From 4ba56f953b24aeb4b90fa84c06f2192da25d9de4 Mon Sep 17 00:00:00 2001 From: mazze Date: Sun, 1 Dec 2013 22:08:26 +0000 Subject: [PATCH] Initial import of Scalos. To decrease size I have removed the website and some 68k and ppc specific includes and libraries. git-svn-id: https://svn.aros.org/svn/aros/trunk/contrib@48481 fb15a70f-31f2-0310-bbcc-cdcc74a49acc --- scalos/BuildArchive | 17 + scalos/CatComp_h.sd | 167 + scalos/Default_Theme/About/Backfill | Bin 0 -> 2196 bytes scalos/Default_Theme/About/ButtonFlushDisabled | Bin 0 -> 4249 bytes scalos/Default_Theme/About/ButtonFlushNormal | Bin 0 -> 4215 bytes scalos/Default_Theme/About/ButtonFlushSelected | Bin 0 -> 4517 bytes scalos/Default_Theme/About/ButtonInfoDisabled | Bin 0 -> 4124 bytes scalos/Default_Theme/About/ButtonInfoNormal | Bin 0 -> 4235 bytes scalos/Default_Theme/About/ButtonInfoSelected | Bin 0 -> 4487 bytes scalos/Default_Theme/About/ButtonOkDisabled | Bin 0 -> 3921 bytes scalos/Default_Theme/About/ButtonOkNormal | Bin 0 -> 3884 bytes scalos/Default_Theme/About/ButtonOkSelected | Bin 0 -> 4230 bytes scalos/Default_Theme/About/ButtonRebootDisabled | Bin 0 -> 4417 bytes scalos/Default_Theme/About/ButtonRebootNormal | Bin 0 -> 4522 bytes scalos/Default_Theme/About/ButtonRebootSelected | Bin 0 -> 4806 bytes scalos/Default_Theme/About/ButtonStopDisabled | Bin 0 -> 4205 bytes scalos/Default_Theme/About/ButtonStopNormal | Bin 0 -> 4218 bytes scalos/Default_Theme/About/ButtonStopSelected | Bin 0 -> 4505 bytes scalos/Default_Theme/AboutBackground | Bin 0 -> 3218 bytes scalos/Default_Theme/AboutBackground.info | Bin 0 -> 1953 bytes scalos/Default_Theme/Desktop.info | Bin 0 -> 1695 bytes scalos/Default_Theme/Desktop/Background | Bin 0 -> 134359 bytes scalos/Default_Theme/FileTrans/Backfill | Bin 0 -> 3218 bytes scalos/Default_Theme/FileTrans/ButtonCancelNormal | Bin 0 -> 4218 bytes .../Default_Theme/FileTrans/ButtonCancelSelected | Bin 0 -> 4505 bytes scalos/Default_Theme/FileTypes/Browse | Bin 0 -> 1108 bytes scalos/Default_Theme/FileTypes/Close | Bin 0 -> 1554 bytes scalos/Default_Theme/FileTypes/CreateThumbnail | Bin 0 -> 1628 bytes scalos/Default_Theme/FileTypes/Delete | Bin 0 -> 1556 bytes scalos/Default_Theme/FileTypes/Edit | Bin 0 -> 1554 bytes scalos/Default_Theme/FileTypes/EditCopy | Bin 0 -> 1558 bytes scalos/Default_Theme/FileTypes/EditCut | Bin 0 -> 1620 bytes scalos/Default_Theme/FileTypes/EditPaste | Bin 0 -> 1622 bytes scalos/Default_Theme/FileTypes/Find | Bin 0 -> 1554 bytes scalos/Default_Theme/FileTypes/Information | Bin 0 -> 1560 bytes scalos/Default_Theme/FileTypes/NewDir | Bin 0 -> 1620 bytes scalos/Default_Theme/FileTypes/Open | Bin 0 -> 1636 bytes scalos/Default_Theme/FileTypes/Properties | Bin 0 -> 1592 bytes scalos/Default_Theme/FileTypes/Rename | Bin 0 -> 1492 bytes scalos/Default_Theme/FileTypes/Update | Bin 0 -> 1556 bytes scalos/Default_Theme/Icons/Overlay/LeftOut | Bin 0 -> 1938 bytes scalos/Default_Theme/Icons/Overlay/ReadOnly | Bin 0 -> 1548 bytes scalos/Default_Theme/Icons/Overlay/Thumbnail | Bin 0 -> 1508 bytes scalos/Default_Theme/Menu.info | Bin 0 -> 1695 bytes scalos/Default_Theme/Menu/DropMenu/Abort | Bin 0 -> 1554 bytes scalos/Default_Theme/Menu/DropMenu/Copy | Bin 0 -> 1554 bytes scalos/Default_Theme/Menu/DropMenu/Move | Bin 0 -> 1554 bytes scalos/Default_Theme/Modules.info | Bin 0 -> 6123 bytes scalos/Default_Theme/Modules/delete.module/delete | Bin 0 -> 1852 bytes .../Modules/delete.module/delete.info | Bin 0 -> 3183 bytes .../Modules/empty_trashcan.module/empty_trashcan | Bin 0 -> 1884 bytes .../empty_trashcan.module/empty_trashcan.info | Bin 0 -> 3183 bytes .../Modules/execute_command.module/execute_command | Bin 0 -> 2308 bytes .../execute_command.module/execute_command.info | Bin 0 -> 505 bytes .../Modules/format_disk.module/format_disk | Bin 0 -> 2208 bytes .../Modules/iconproperties.module/iconproperties | Bin 0 -> 1772 bytes .../Modules/information.module/Information.info | Bin 0 -> 3183 bytes .../Modules/information.module/information | Bin 0 -> 1820 bytes .../Modules/newdrawer.module/Newdrawer | Bin 0 -> 2116 bytes .../Modules/newdrawer.module/newdrawer.info | Bin 0 -> 3183 bytes scalos/Default_Theme/Modules/reboot.module/reboot | Bin 0 -> 2212 bytes scalos/Default_Theme/Modules/rename.module/rename | Bin 0 -> 1900 bytes .../Modules/rename.module/rename.info | Bin 0 -> 3177 bytes .../Modules/systeminfo.module/SystemInfo | Bin 0 -> 2140 bytes .../Modules/systeminfo.module/Systeminfo.info | Bin 0 -> 3183 bytes .../windowproperties.module/windowproperties | Bin 0 -> 2236 bytes scalos/Default_Theme/PointerIcons.info | Bin 0 -> 1695 bytes scalos/Default_Theme/PointerIcons/copying.info | Bin 0 -> 433 bytes scalos/Default_Theme/PointerIcons/forbidden.info | Bin 0 -> 555 bytes scalos/Default_Theme/PointerIcons/makelink.info | Bin 0 -> 387 bytes scalos/Default_Theme/PointerIcons/moving.info | Bin 0 -> 1474 bytes scalos/Default_Theme/Pointers.info | Bin 0 -> 1695 bytes scalos/Default_Theme/Prefs/Modules/delete | Bin 0 -> 1852 bytes scalos/Default_Theme/Prefs/Modules/empty_trashcan | Bin 0 -> 1884 bytes scalos/Default_Theme/Prefs/Modules/execute_command | Bin 0 -> 2308 bytes scalos/Default_Theme/Prefs/Modules/iconproperties | Bin 0 -> 1772 bytes scalos/Default_Theme/Prefs/Modules/information | Bin 0 -> 1820 bytes scalos/Default_Theme/Prefs/Modules/newdrawer | Bin 0 -> 2116 bytes scalos/Default_Theme/Prefs/Modules/reboot | Bin 0 -> 2212 bytes scalos/Default_Theme/Prefs/Modules/rename | Bin 0 -> 1900 bytes scalos/Default_Theme/Prefs/Modules/systeminfo | Bin 0 -> 2140 bytes .../Default_Theme/Prefs/Modules/windowproperties | Bin 0 -> 2236 bytes scalos/Default_Theme/Prefs/Pages/about | Bin 0 -> 1548 bytes scalos/Default_Theme/Prefs/Pages/desktop | Bin 0 -> 1676 bytes scalos/Default_Theme/Prefs/Pages/dragndrop | Bin 0 -> 1628 bytes scalos/Default_Theme/Prefs/Pages/filedisplay | Bin 0 -> 1676 bytes scalos/Default_Theme/Prefs/Pages/icons | Bin 0 -> 1676 bytes scalos/Default_Theme/Prefs/Pages/misc | Bin 0 -> 1564 bytes scalos/Default_Theme/Prefs/Pages/modules | Bin 0 -> 1660 bytes scalos/Default_Theme/Prefs/Pages/paths | Bin 0 -> 1676 bytes scalos/Default_Theme/Prefs/Pages/plugins | Bin 0 -> 1676 bytes scalos/Default_Theme/Prefs/Pages/startup | Bin 0 -> 1676 bytes scalos/Default_Theme/Prefs/Pages/textwindows | Bin 0 -> 1644 bytes scalos/Default_Theme/Prefs/Pages/truetypefonts | Bin 0 -> 1692 bytes scalos/Default_Theme/Prefs/Pages/windows | Bin 0 -> 1676 bytes scalos/Default_Theme/Prefs/Plugins/PopupMenu | Bin 0 -> 1588 bytes scalos/Default_Theme/Prefs/Plugins/filetypes | Bin 0 -> 1756 bytes scalos/Default_Theme/Prefs/Plugins/menu | Bin 0 -> 1804 bytes scalos/Default_Theme/Prefs/Plugins/palette | Bin 0 -> 1756 bytes scalos/Default_Theme/Prefs/Plugins/pattern | Bin 0 -> 1724 bytes scalos/Default_Theme/Prefs/icon128 | Bin 0 -> 6696 bytes scalos/Default_Theme/Prefs/icon16 | Bin 0 -> 376 bytes scalos/Default_Theme/Prefs/icon24 | Bin 0 -> 668 bytes scalos/Default_Theme/Prefs/icon32 | Bin 0 -> 826 bytes scalos/Default_Theme/Prefs/icon48 | Bin 0 -> 1486 bytes scalos/Default_Theme/Prefs/icon64 | Bin 0 -> 2248 bytes scalos/Default_Theme/Prefs/icon96 | Bin 0 -> 4378 bytes scalos/Default_Theme/ScalosAboutLogo | Bin 0 -> 13762 bytes scalos/Default_Theme/ScalosLogo | Bin 0 -> 15176 bytes scalos/Default_Theme/ScalosSplashLogo | Bin 0 -> 15526 bytes scalos/Default_Theme/Sound.info | Bin 0 -> 1695 bytes scalos/Default_Theme/SplashBackground | Bin 0 -> 3218 bytes scalos/Default_Theme/SplashBackground.info | Bin 0 -> 5991 bytes scalos/Default_Theme/ToolTipBackground | Bin 0 -> 3983 bytes scalos/Default_Theme/Window.info | Bin 0 -> 1695 bytes scalos/Default_Theme/Window/Background | Bin 0 -> 149852 bytes scalos/Default_Theme/Window/ControlBar/Background | Bin 0 -> 2030 bytes .../Default_Theme/Window/ControlBar/BrowseDisabled | Bin 0 -> 860 bytes .../Default_Theme/Window/ControlBar/BrowseNormal | Bin 0 -> 858 bytes .../Default_Theme/Window/ControlBar/BrowseSelected | Bin 0 -> 860 bytes .../Window/ControlBar/ButtonAboutDisabled | Bin 0 -> 864 bytes .../Window/ControlBar/ButtonAboutNormal | Bin 0 -> 862 bytes .../Window/ControlBar/ButtonAboutSelected | Bin 0 -> 864 bytes .../Window/ControlBar/ButtonBackDisabled | Bin 0 -> 864 bytes .../Window/ControlBar/ButtonBackNormal | Bin 0 -> 862 bytes .../Window/ControlBar/ButtonBackSelected | Bin 0 -> 864 bytes .../Window/ControlBar/ButtonForwardDisabled | Bin 0 -> 866 bytes .../Window/ControlBar/ButtonForwardNormal | Bin 0 -> 864 bytes .../Window/ControlBar/ButtonForwardSelected | Bin 0 -> 866 bytes .../Window/ControlBar/ButtonInfoDisabled | Bin 0 -> 864 bytes .../Window/ControlBar/ButtonInfoNormal | Bin 0 -> 862 bytes .../Window/ControlBar/ButtonInfoSelected | Bin 0 -> 864 bytes .../Window/ControlBar/ButtonPropertiesDisabled | Bin 0 -> 870 bytes .../Window/ControlBar/ButtonPropertiesNormal | Bin 0 -> 868 bytes .../Window/ControlBar/ButtonPropertiesSelected | Bin 0 -> 870 bytes .../Window/ControlBar/ButtonUpDisabled | Bin 0 -> 862 bytes .../Default_Theme/Window/ControlBar/ButtonUpNormal | Bin 0 -> 860 bytes .../Window/ControlBar/ButtonUpSelected | Bin 0 -> 862 bytes .../Window/ControlBar/CycleBackground | Bin 0 -> 197 bytes scalos/Default_Theme/Window/ControlBar/CycleNormal | Bin 0 -> 2158 bytes .../Window/ControlBar/CyclePopupBackground | Bin 0 -> 450 bytes .../Default_Theme/Window/ControlBar/CycleSelected | Bin 0 -> 2158 bytes .../Default_Theme/Window/ControlBar/HistoryNormal | Bin 0 -> 858 bytes .../Window/ControlBar/HistoryPopupBackground | Bin 0 -> 816 bytes .../Window/ControlBar/HistorySelected | Bin 0 -> 860 bytes .../Window/ControlBar/ShowModeCycleFrame | Bin 0 -> 2375 bytes .../Window/ControlBar/ViewByCycleFrame | Bin 0 -> 2080 bytes scalos/Default_Theme/Window/SortAscending | Bin 0 -> 3216 bytes scalos/Default_Theme/Window/SortDescending | Bin 0 -> 1114 bytes scalos/Default_Theme/Window/StatusBar.info | Bin 0 -> 1695 bytes scalos/Default_Theme/Window/StatusBar/Background | Bin 0 -> 110290 bytes scalos/Default_Theme/Window/StatusBar/PadLock | Bin 0 -> 1508 bytes scalos/Default_Theme/Window/StatusBar/Reading | Bin 0 -> 1532 bytes scalos/Default_Theme/Window/StatusBar/ShowAll | Bin 0 -> 1500 bytes .../Window/StatusBar/ThumbnailsAlways | Bin 0 -> 1516 bytes .../Window/StatusBar/ThumbnailsAsDefault | Bin 0 -> 1508 bytes .../Window/StatusBar/ThumbnailsGenerate | Bin 0 -> 1508 bytes scalos/Default_Theme/Window/StatusBar/Typing | Bin 0 -> 1596 bytes scalos/Default_Theme/Window/TextBackground | Bin 0 -> 62494 bytes scalos/Default_Theme/Window/def_iconify.info | Bin 0 -> 1186 bytes scalos/DevPack | 106 + scalos/ExcludeList | 12 + scalos/Extras/CreateDefaultIcon | Bin 0 -> 2176 bytes scalos/Extras/CreateTrash | Bin 0 -> 11579 bytes scalos/Extras/CreateTrash.68k | Bin 0 -> 20424 bytes scalos/Extras/CreateTrash.68k.info | Bin 0 -> 8314 bytes scalos/Extras/CreateTrash.info | Bin 0 -> 1911 bytes scalos/Extras/CreateTrash.mos | Bin 0 -> 25284 bytes scalos/Extras/CreateTrash.mos.info | Bin 0 -> 8455 bytes scalos/Extras/DoCommand | Bin 0 -> 4144 bytes scalos/Extras/NewIconUtil | Bin 0 -> 2348 bytes scalos/Extras/OpenLocation_CA | Bin 0 -> 8724 bytes scalos/Extras/OpenLocation_CA.info | Bin 0 -> 1348 bytes scalos/Extras/OpenLocation_CA.readme | 8 + scalos/Extras/OpenLocation_CA.readme.info | Bin 0 -> 1696 bytes scalos/Extras/OpenLocation_MUI | Bin 0 -> 3520 bytes scalos/Extras/OpenLocation_MUI.info | Bin 0 -> 1348 bytes scalos/Extras/OpenShell | 8 + scalos/Extras/PictIcon | Bin 0 -> 43355 bytes scalos/Extras/Quit.rexx | 54 + .../Fran\303\247ais/Scalos/Scalos_Comment.catalog" | Bin 0 -> 2244 bytes .../Fran\303\247ais/Scalos/Scalos_Comment.ct" | 305 + .../Scalos_Comment/Catalogs/Scalos_Comment.cd | 297 + scalos/Extras/Scalos_Comment/Comment.module.68k | Bin 0 -> 64348 bytes .../Extras/Scalos_Comment/Comment.module.68k.info | Bin 0 -> 10288 bytes scalos/Extras/Scalos_Comment/Comment.module.mos | Bin 0 -> 82368 bytes .../Extras/Scalos_Comment/Comment.module.mos.info | Bin 0 -> 9104 bytes .../Extras/Scalos_GetHidden/catalogs/GetHidden.cd | 128 + .../catalogs/deutsch/scalos/GetHidden.ct | 157 + .../fran\303\247ais/scalos/GetHidden.catalog" | Bin 0 -> 1170 bytes .../catalogs/fran\303\247ais/scalos/GetHidden.ct" | 128 + scalos/Extras/Scalos_GetHidden/gethidden.68k | Bin 0 -> 69860 bytes scalos/Extras/Scalos_GetHidden/gethidden.68k.info | Bin 0 -> 8280 bytes scalos/Extras/Scalos_GetHidden/gethidden.mos | Bin 0 -> 87516 bytes scalos/Extras/Scalos_GetHidden/gethidden.mos.info | Bin 0 -> 8455 bytes scalos/Extras/browse.script | 12 + scalos/Extras/open_volume.rexx | 14 + scalos/Extras/opendrawer.68k | Bin 0 -> 6648 bytes scalos/Extras/opendrawer.68k.info | Bin 0 -> 10288 bytes scalos/Extras/opendrawer.mos | Bin 0 -> 8908 bytes scalos/Extras/opendrawer_ppc | Bin 0 -> 6264 bytes scalos/Extras/run.script | 12 + scalos/GPLsrc | 53 + scalos/History | 2911 +++++++ scalos/InstallAROS/InstallAROS | 101 + scalos/InstallAROS/InstallAROS.info | Bin 0 -> 4024 bytes scalos/Installer/GFX/MVGA.png | Bin 0 -> 124268 bytes scalos/Installer/GFX/Pointericons.iff | Bin 0 -> 10170 bytes scalos/Installer/GFX/SVGA.png | Bin 0 -> 122872 bytes scalos/Installer/GFX/StatusBar.iff | Bin 0 -> 8378 bytes scalos/Installer/GFX/VGA.png | Bin 0 -> 47261 bytes scalos/Installer/GFX/def_Iconify.iff | Bin 0 -> 6754 bytes scalos/Installer/Install3.5_ScalosBeta | 3106 ++++++++ scalos/Installer/Install3.5_ScalosBeta.info | Bin 0 -> 3457 bytes scalos/Installer/Matrix_Copyright.txt | 15 + scalos/LEGAL | 205 + scalos/Modules/Delete.Gadtools/Copy_of_delete.c | 1357 ++++ scalos/Modules/Delete.Gadtools/Delete.c | 1210 +++ scalos/Modules/Delete.Gadtools/makefile | 80 + scalos/Modules/Delete.MUI/COPYING | 341 + scalos/Modules/Delete.MUI/Release | 51 + scalos/Modules/Delete.MUI/Source.info | Bin 0 -> 1636 bytes .../Source/Catalogs/deutsch/Scalos/Delete.ct | 443 ++ .../Source/Catalogs/deutsch/Scalos/config.mk | 41 + .../Source/Catalogs/deutsch/Scalos/makefile | 14 + .../Source/Catalogs/deutsch/Scalos/makefile-new | 31 + .../Catalogs/fran\303\247ais/Scalos/Delete.ct" | 427 + .../Catalogs/fran\303\247ais/Scalos/config.mk" | 40 + .../Catalogs/fran\303\247ais/Scalos/makefile" | 14 + .../Catalogs/fran\303\247ais/Scalos/makefile-new" | 30 + .../Source/Catalogs/sample/Scalos/Delete.ct | 323 + scalos/Modules/Delete.MUI/Source/Delete.cd | 312 + scalos/Modules/Delete.MUI/Source/Delete.module.c | 928 +++ scalos/Modules/Delete.MUI/Source/Delete.module.h | 216 + .../Delete.MUI/Source/Delete.module_files.c | 1493 ++++ .../Modules/Delete.MUI/Source/Delete.module_rev.h | 18 + .../Delete.MUI/Source/Delete.module_rev.log | 74 + .../Delete.MUI/Source/Delete.module_rev.rev | 3 + .../Delete.MUI/Source/Delete.module_strings.h | 275 + scalos/Modules/Delete.MUI/Source/config.mk | 59 + scalos/Modules/Delete.MUI/Source/makefile | 109 + scalos/Modules/Delete.MUI/Source/makefile-new | 97 + scalos/Modules/Delete.MUI/config.mk | 43 + scalos/Modules/Delete.MUI/makefile | 33 + scalos/Modules/Delete.MUI/makefile-new | 23 + .../Empty_Trashcan.Gadtools/Empty_Trashcan.c | 1153 +++ scalos/Modules/Empty_Trashcan.Gadtools/debug.h | 19 + scalos/Modules/Empty_Trashcan.Gadtools/makefile | 82 + .../Catalogs/deutsch/Scalos/Empty_Trashcan.ct | 234 + .../Catalogs/deutsch/Scalos/config.mk | 41 + .../Catalogs/deutsch/Scalos/makefile | 14 + .../Catalogs/deutsch/Scalos/makefile-new | 30 + .../fran\303\247ais/Scalos/Empty_Trashcan.ct" | 196 + .../Catalogs/fran\303\247ais/Scalos/config.mk" | 40 + .../Catalogs/fran\303\247ais/Scalos/makefile" | 14 + .../Catalogs/fran\303\247ais/Scalos/makefile-new" | 30 + .../Catalogs/sample/Scalos/Empty_Trashcan.ct | 233 + scalos/Modules/Empty_Trashcan.MUI/Empty_Trashcan.c | 1448 ++++ .../Modules/Empty_Trashcan.MUI/Empty_Trashcan.cd | 180 + scalos/Modules/Empty_Trashcan.MUI/Empty_Trashcan.h | 26 + scalos/Modules/Empty_Trashcan.MUI/config.mk | 58 + scalos/Modules/Empty_Trashcan.MUI/makefile | 124 + scalos/Modules/Empty_Trashcan.MUI/makefile-new | 96 + .../Catalogs/deutsch/Scalos/Exchange.ct | 175 + .../Exchange.MUI/Catalogs/deutsch/Scalos/config.mk | 41 + .../Exchange.MUI/Catalogs/deutsch/Scalos/makefile | 13 + .../Catalogs/deutsch/Scalos/makefile-new | 30 + .../Catalogs/fran\303\247ais/Scalos/Exchange.ct" | 153 + .../Catalogs/fran\303\247ais/Scalos/config.mk" | 40 + .../Catalogs/fran\303\247ais/Scalos/makefile" | 13 + .../Catalogs/fran\303\247ais/Scalos/makefile-new" | 30 + .../Catalogs/sample/Scalos/Exchange.ct | 174 + scalos/Modules/Exchange.MUI/Exchange.c | 1043 +++ scalos/Modules/Exchange.MUI/Exchange.cd | 138 + scalos/Modules/Exchange.MUI/Exchange.h | 85 + scalos/Modules/Exchange.MUI/config.mk | 61 + scalos/Modules/Exchange.MUI/cx_private.h | 34 + scalos/Modules/Exchange.MUI/cx_private_ppcinline.h | 29 + scalos/Modules/Exchange.MUI/cx_private_pragmas.h | 24 + scalos/Modules/Exchange.MUI/cx_private_protos.h | 50 + scalos/Modules/Exchange.MUI/debug.h | 28 + scalos/Modules/Exchange.MUI/makefile | 134 + scalos/Modules/Exchange.MUI/makefile-new | 100 + .../Execute_Command.Gadtools/execute_command.c | 779 ++ scalos/Modules/Execute_Command.Gadtools/makefile | 82 + .../Catalogs/deutsch/Scalos/Execute_Command.ct | 223 + .../Catalogs/deutsch/Scalos/config.mk | 41 + .../Catalogs/deutsch/Scalos/makefile | 14 + .../Catalogs/deutsch/Scalos/makefile-new | 30 + .../fran\303\247ais/Scalos/Execute_Command.ct" | 233 + .../Catalogs/fran\303\247ais/Scalos/config.mk" | 41 + .../Catalogs/fran\303\247ais/Scalos/makefile" | 14 + .../Catalogs/fran\303\247ais/Scalos/makefile-new" | 30 + .../Catalogs/sample/Scalos/Execute_Command.ct | 173 + .../Modules/Execute_Command.MUI/Execute_Command.c | 1226 +++ .../Modules/Execute_Command.MUI/Execute_Command.cd | 177 + .../Modules/Execute_Command.MUI/Execute_Command.h | 23 + scalos/Modules/Execute_Command.MUI/config.mk | 58 + scalos/Modules/Execute_Command.MUI/makefile | 122 + scalos/Modules/Execute_Command.MUI/makefile-new | 95 + .../Find.MUI/Catalogs/deutsch/Scalos/Find.ct | 309 + .../Find.MUI/Catalogs/deutsch/Scalos/config.mk | 41 + .../Find.MUI/Catalogs/deutsch/Scalos/makefile | 13 + .../Find.MUI/Catalogs/deutsch/Scalos/makefile-new | 30 + .../Catalogs/fran\303\247ais/Scalos/Find.ct" | 273 + .../Catalogs/fran\303\247ais/Scalos/config.mk" | 40 + .../Catalogs/fran\303\247ais/Scalos/makefile" | 13 + .../Catalogs/fran\303\247ais/Scalos/makefile-new" | 30 + .../Find.MUI/Catalogs/sample/Scalos/Find.ct | 314 + scalos/Modules/Find.MUI/DefIcons.c | 1024 +++ scalos/Modules/Find.MUI/Find.c | 3054 ++++++++ scalos/Modules/Find.MUI/Find.cd | 247 + scalos/Modules/Find.MUI/Find.h | 65 + scalos/Modules/Find.MUI/config.mk | 61 + scalos/Modules/Find.MUI/debug.h | 28 + scalos/Modules/Find.MUI/makefile | 132 + scalos/Modules/Find.MUI/makefile-new | 101 + .../Catalogs/Fran\303\247ais/Scalos/FormatDisk.ct" | 340 + .../Catalogs/Fran\303\247ais/Scalos/config.mk" | 40 + .../Catalogs/Fran\303\247ais/Scalos/makefile" | 15 + .../Catalogs/Fran\303\247ais/Scalos/makefile-new" | 30 + .../Catalogs/deutsch/Scalos/FormatDisk.ct | 354 + .../Catalogs/deutsch/Scalos/config.mk | 41 + .../Catalogs/deutsch/Scalos/makefile | 15 + .../Catalogs/deutsch/Scalos/makefile-new | 30 + .../Catalogs/sample/Scalos/FormatDisk.ct | 359 + .../Modules/FormatDisk.Gadtools/Device_Handler.c | 285 + scalos/Modules/FormatDisk.Gadtools/Format.c | 1533 ++++ scalos/Modules/FormatDisk.Gadtools/Format.h | 133 + scalos/Modules/FormatDisk.Gadtools/FormatDisk.cd | 270 + scalos/Modules/FormatDisk.Gadtools/FormatVolume.c | 323 + .../Modules/FormatDisk.Gadtools/Format_disk_rev.h | 22 + scalos/Modules/FormatDisk.Gadtools/FullFormat.c | 300 + scalos/Modules/FormatDisk.Gadtools/GUI.c | 983 +++ scalos/Modules/FormatDisk.Gadtools/GUI.h | 91 + .../FormatDisk.Gadtools/GetInputFromWindow.c | 243 + scalos/Modules/FormatDisk.Gadtools/NSD_64bit.c | 46 + scalos/Modules/FormatDisk.Gadtools/NoDebug | 3 + scalos/Modules/FormatDisk.Gadtools/ParseArgs.c | 77 + scalos/Modules/FormatDisk.Gadtools/config.mk | 51 + scalos/Modules/FormatDisk.Gadtools/makefile | 160 + scalos/Modules/FormatDisk.Gadtools/makefile-new | 103 + .../Catalogs/deutsch/Scalos/FormatDiskMUI.ct | 203 + .../Catalogs/deutsch/Scalos/config.mk | 41 + .../Catalogs/deutsch/Scalos/makefile | 14 + .../Catalogs/deutsch/Scalos/makefile-new | 31 + .../fran\303\247ais/Scalos/FormatDiskMUI.ct" | 209 + .../Catalogs/fran\303\247ais/Scalos/config.mk" | 40 + .../Catalogs/fran\303\247ais/Scalos/makefile" | 14 + .../Catalogs/fran\303\247ais/Scalos/makefile-new" | 30 + .../Catalogs/sample/Scalos/FormatDisk.ct | 171 + scalos/Modules/FormatDisk.MUI/FormatDisk.c | 1237 +++ scalos/Modules/FormatDisk.MUI/FormatDisk.h | 191 + scalos/Modules/FormatDisk.MUI/FormatDiskMUI.cd | 237 + scalos/Modules/FormatDisk.MUI/config.mk | 60 + scalos/Modules/FormatDisk.MUI/makefile | 118 + scalos/Modules/FormatDisk.MUI/makefile-new | 95 + .../Catalogs/deutsch/Scalos/IconProperties.ct | 161 + .../Catalogs/deutsch/Scalos/config.mk | 41 + .../Catalogs/deutsch/Scalos/makefile | 13 + .../Catalogs/deutsch/Scalos/makefile-new | 30 + .../fran\303\247ais/Scalos/IconProperties.ct" | 156 + .../Catalogs/fran\303\247ais/Scalos/config.mk" | 40 + .../Catalogs/fran\303\247ais/Scalos/makefile" | 13 + .../Catalogs/fran\303\247ais/Scalos/makefile-new" | 30 + .../Catalogs/sample/Scalos/IconProperties.ct | 128 + scalos/Modules/IconProperties.MUI/IconProperties.c | 1484 ++++ .../Modules/IconProperties.MUI/IconProperties.cd | 122 + scalos/Modules/IconProperties.MUI/IconProperties.h | 14 + scalos/Modules/IconProperties.MUI/NoDebug | 3 + scalos/Modules/IconProperties.MUI/ToolTypes.c | 328 + scalos/Modules/IconProperties.MUI/ToolTypes.h | 18 + scalos/Modules/IconProperties.MUI/config.mk | 59 + scalos/Modules/IconProperties.MUI/debug.h | 19 + scalos/Modules/IconProperties.MUI/makefile | 142 + scalos/Modules/IconProperties.MUI/makefile-new | 102 + .../Catalogs/deutsch/Scalos/Information.ct | 734 ++ .../Catalogs/deutsch/Scalos/config.mk | 41 + .../Catalogs/deutsch/Scalos/makefile | 14 + .../Catalogs/deutsch/Scalos/makefile-new | 30 + .../fran\303\247ais/Scalos/Information.ct" | 723 ++ .../Catalogs/fran\303\247ais/Scalos/config.mk" | 40 + .../Catalogs/fran\303\247ais/Scalos/makefile" | 14 + .../Catalogs/fran\303\247ais/Scalos/makefile-new" | 30 + .../Catalogs/sample/Scalos/Information.ct | 741 ++ scalos/Modules/Information.MUI/Information.c | 5529 +++++++++++++ scalos/Modules/Information.MUI/Information.cd | 583 ++ scalos/Modules/Information.MUI/Information.h | 51 + scalos/Modules/Information.MUI/config.mk | 74 + scalos/Modules/Information.MUI/debug.h | 19 + scalos/Modules/Information.MUI/makefile | 173 + scalos/Modules/Information.MUI/makefile-new | 93 + scalos/Modules/NewDrawer.Gadtools/makefile | 79 + scalos/Modules/NewDrawer.Gadtools/newdrawer.c | 665 ++ .../Catalogs/deutsch/Scalos/NewDrawer.ct | 203 + .../Catalogs/deutsch/Scalos/config.mk | 41 + .../NewDrawer.MUI/Catalogs/deutsch/Scalos/makefile | 14 + .../Catalogs/deutsch/Scalos/makefile-new | 30 + .../Catalogs/fran\303\247ais/Scalos/NewDrawer.ct" | 210 + .../Catalogs/fran\303\247ais/Scalos/config.mk" | 40 + .../Catalogs/fran\303\247ais/Scalos/makefile" | 14 + .../Catalogs/fran\303\247ais/Scalos/makefile-new" | 30 + .../Catalogs/sample/Scalos/NewDrawer.ct | 171 + scalos/Modules/NewDrawer.MUI/NewDrawer.c | 1019 +++ scalos/Modules/NewDrawer.MUI/NewDrawer.cd | 159 + scalos/Modules/NewDrawer.MUI/NewDrawer.h | 35 + scalos/Modules/NewDrawer.MUI/config.mk | 60 + scalos/Modules/NewDrawer.MUI/makefile | 121 + scalos/Modules/NewDrawer.MUI/makefile-new | 95 + scalos/Modules/NewDrawer.Reaction/NDStrings.asm | 11 + scalos/Modules/NewDrawer.Reaction/NewDrawer.c | 474 ++ scalos/Modules/NewDrawer.Reaction/NewDrawerGUI.cd | 32 + scalos/Modules/NewDrawer.Reaction/NewDrawerGUI.h | 11 + scalos/Modules/NewDrawer.Reaction/NewDrawerGUI.res | Bin 0 -> 3030 bytes scalos/Modules/NewDrawer.Reaction/makefile | 106 + scalos/Modules/Rename.Gadtools/Rename.c | 825 ++ scalos/Modules/Rename.Gadtools/makefile | 89 + .../Rename.MUI/Catalogs/deutsch/Scalos/Rename.ct | 205 + .../Rename.MUI/Catalogs/deutsch/Scalos/config.mk | 41 + .../Rename.MUI/Catalogs/deutsch/Scalos/makefile | 14 + .../Catalogs/deutsch/Scalos/makefile-new | 30 + .../Catalogs/fran\303\247ais/Scalos/Rename.ct" | 216 + .../Catalogs/fran\303\247ais/Scalos/config.mk" | 40 + .../Catalogs/fran\303\247ais/Scalos/makefile" | 14 + .../Catalogs/fran\303\247ais/Scalos/makefile-new" | 30 + .../Rename.MUI/Catalogs/sample/Scalos/Rename.ct | 178 + scalos/Modules/Rename.MUI/Rename.c | 1330 ++++ scalos/Modules/Rename.MUI/Rename.cd | 161 + scalos/Modules/Rename.MUI/Rename.h | 32 + scalos/Modules/Rename.MUI/config.mk | 60 + scalos/Modules/Rename.MUI/makefile | 123 + scalos/Modules/Rename.MUI/makefile-new | 95 + scalos/Modules/Rename.Reaction/RENStrings.asm | 11 + scalos/Modules/Rename.Reaction/Rename.c | 497 ++ scalos/Modules/Rename.Reaction/RenameGUI.cd | 35 + scalos/Modules/Rename.Reaction/RenameGUI.h | 12 + scalos/Modules/Rename.Reaction/RenameGUI.res | Bin 0 -> 3026 bytes scalos/Modules/Rename.Reaction/RenameStrings.h | 144 + scalos/Modules/Rename.Reaction/RenameStrings.i | 175 + scalos/Modules/Rename.Reaction/makefile | 106 + scalos/Modules/SCOPTIONS | 19 + .../Updater.MUI/Catalogs/deutsch/Scalos/Updater.ct | 612 ++ .../Updater.MUI/Catalogs/deutsch/Scalos/config.mk | 41 + .../Updater.MUI/Catalogs/deutsch/Scalos/makefile | 13 + .../Catalogs/deutsch/Scalos/makefile-new | 30 + .../Catalogs/fran\303\247ais/Scalos/Updater.ct" | 549 ++ .../Catalogs/fran\303\247ais/Scalos/config.mk" | 40 + .../Catalogs/fran\303\247ais/Scalos/makefile" | 13 + .../Catalogs/fran\303\247ais/Scalos/makefile-new" | 30 + .../Updater.MUI/Catalogs/sample/Scalos/Updater.ct | 616 ++ scalos/Modules/Updater.MUI/Updater.c | 3463 ++++++++ scalos/Modules/Updater.MUI/Updater.cd | 480 ++ scalos/Modules/Updater.MUI/Updater.h | 34 + scalos/Modules/Updater.MUI/config.mk | 85 + scalos/Modules/Updater.MUI/debug.h | 28 + scalos/Modules/Updater.MUI/makefile | 10 + scalos/Modules/Updater.MUI/makefile-new | 101 + .../Catalogs/deutsch/Scalos/WindowProperties.ct | 464 ++ .../Catalogs/deutsch/Scalos/config.mk | 41 + .../Catalogs/deutsch/Scalos/makefile | 13 + .../Catalogs/deutsch/Scalos/makefile-new | 30 + .../fran\303\247ais/Scalos/WindowProperties.ct" | 423 + .../Catalogs/fran\303\247ais/Scalos/config.mk" | 40 + .../Catalogs/fran\303\247ais/Scalos/makefile" | 13 + .../Catalogs/fran\303\247ais/Scalos/makefile-new" | 30 + .../Catalogs/sample/Scalos/WindowProperties.ct | 429 + scalos/Modules/WindowProperties.MUI/NoDebug | 3 + .../WindowProperties.MUI/WindowProperties.c | 3382 ++++++++ .../WindowProperties.MUI/WindowProperties.cd | 354 + .../WindowProperties.MUI/WindowProperties.h | 63 + scalos/Modules/WindowProperties.MUI/config.mk | 62 + scalos/Modules/WindowProperties.MUI/debug.h | 19 + scalos/Modules/WindowProperties.MUI/makefile | 181 + scalos/Modules/WindowProperties.MUI/makefile-new | 94 + scalos/Modules/config.mk | 35 + scalos/Modules/makefile | 60 + scalos/Modules/makefile-new | 47 + .../deutsch/Scalos/DrawerContentsPlugin.ct | 23 + .../Catalogs/deutsch/Scalos/config.mk | 41 + .../Catalogs/deutsch/Scalos/makefile | 13 + .../Catalogs/deutsch/Scalos/makefile-new | 33 + .../Scalos/DrawerContentsPlugin.ct" | 23 + .../Catalogs/fran\303\247ais/Scalos/config.mk" | 40 + .../Catalogs/fran\303\247ais/Scalos/makefile" | 13 + .../Catalogs/fran\303\247ais/Scalos/makefile-new" | 33 + .../Catalogs/sample/Scalos/DrawerContentsPlugin.ct | 23 + .../FileTypes/DrawerContents/DrawerContents.c | 420 + .../FileTypes/DrawerContents/DrawerContents.h | 35 + .../DrawerContents/DrawerContentsPlugin.cd | 20 + .../FileTypes/DrawerContents/DrawerContents_base.h | 21 + scalos/Plugins/FileTypes/DrawerContents/config.mk | 75 + scalos/Plugins/FileTypes/DrawerContents/makefile | 128 + .../Plugins/FileTypes/DrawerContents/makefile-new | 98 + .../Plugins/FileTypes/DrawerContents/plugin_data.h | 34 + .../Catalogs/deutsch/Scalos/ExifPicturePlugin.ct | 249 + .../ExifPicture/Catalogs/deutsch/Scalos/config.mk | 41 + .../ExifPicture/Catalogs/deutsch/Scalos/makefile | 13 + .../Catalogs/deutsch/Scalos/makefile-new | 32 + .../fran\303\247ais/Scalos/ExifPicturePlugin.ct" | 248 + .../Catalogs/fran\303\247ais/Scalos/config.mk" | 40 + .../Catalogs/fran\303\247ais/Scalos/makefile" | 14 + .../Catalogs/fran\303\247ais/Scalos/makefile-new" | 32 + .../Catalogs/sample/Scalos/ExifPicturePlugin.ct | 248 + scalos/Plugins/FileTypes/ExifPicture/ExPicDefs.h | 97 + scalos/Plugins/FileTypes/ExifPicture/ExifPicture.c | 2617 +++++++ scalos/Plugins/FileTypes/ExifPicture/ExifPicture.h | 37 + .../FileTypes/ExifPicture/ExifPicturePlugin.cd | 241 + .../FileTypes/ExifPicture/ExifPicture_base.h | 21 + scalos/Plugins/FileTypes/ExifPicture/config.mk | 75 + scalos/Plugins/FileTypes/ExifPicture/makefile | 139 + scalos/Plugins/FileTypes/ExifPicture/makefile-new | 97 + scalos/Plugins/FileTypes/ExifPicture/plugin_data.h | 34 + .../deutsch/Scalos/PictureDimensionsPlugin.ct | 13 + .../Catalogs/deutsch/Scalos/config.mk | 41 + .../Catalogs/deutsch/Scalos/makefile | 13 + .../Catalogs/deutsch/Scalos/makefile-new | 33 + .../Scalos/PictureDimensionsPlugin.ct" | 13 + .../Catalogs/fran\303\247ais/Scalos/config.mk" | 40 + .../Catalogs/fran\303\247ais/Scalos/makefile" | 13 + .../Catalogs/fran\303\247ais/Scalos/makefile-new" | 33 + .../sample/Scalos/PictureDimensionsPlugin.ct | 13 + .../Picture_Dimensions/PictureDimensions.c | 312 + .../Picture_Dimensions/PictureDimensions.h | 37 + .../Picture_Dimensions/PictureDimensionsPlugin.cd | 12 + .../Plugins/FileTypes/Picture_Dimensions/config.mk | 82 + .../Plugins/FileTypes/Picture_Dimensions/makefile | 128 + .../FileTypes/Picture_Dimensions/makefile-new | 95 + .../Picture_Dimensions/picturedimensions_base.h | 21 + .../FileTypes/Picture_Dimensions/plugin_data.h | 34 + scalos/Plugins/FileTypes/config.mk | 36 + scalos/Plugins/FileTypes/makefile | 44 + scalos/Plugins/FileTypes/makefile-new | 28 + scalos/Plugins/Menu/Sorted_Cleanup/makefile | 77 + scalos/Plugins/Menu/Sorted_Cleanup/scalos_macros.i | 213 + .../Plugins/Menu/Sorted_Cleanup/sorted_cleanup.s | 368 + scalos/Plugins/Menu/makefile | 42 + scalos/Plugins/OOP/DeviceFilter/config.mk | 69 + scalos/Plugins/OOP/DeviceFilter/devicefilter.c | 867 ++ scalos/Plugins/OOP/DeviceFilter/devicefilter.h | 58 + scalos/Plugins/OOP/DeviceFilter/makefile | 106 + scalos/Plugins/OOP/DeviceFilter/makefile-new | 69 + scalos/Plugins/OOP/DeviceFilter/plugin_data.h | 39 + scalos/Plugins/OOP/TitleClock/config.mk | 67 + scalos/Plugins/OOP/TitleClock/libbase.h | 44 + scalos/Plugins/OOP/TitleClock/libfuncs.c | 342 + scalos/Plugins/OOP/TitleClock/libfuncs.h | 34 + scalos/Plugins/OOP/TitleClock/makefile | 107 + scalos/Plugins/OOP/TitleClock/makefile-new | 78 + scalos/Plugins/OOP/TitleClock/plugin_data.h | 42 + scalos/Plugins/OOP/TitleClock/prefs/cc_locale.h | 164 + scalos/Plugins/OOP/TitleClock/prefs/config.mk | 53 + scalos/Plugins/OOP/TitleClock/prefs/force | Bin 0 -> 4044 bytes scalos/Plugins/OOP/TitleClock/prefs/force.c | 20 + scalos/Plugins/OOP/TitleClock/prefs/interface.c | 885 +++ scalos/Plugins/OOP/TitleClock/prefs/interface.h | 23 + scalos/Plugins/OOP/TitleClock/prefs/makefile | 32 + scalos/Plugins/OOP/TitleClock/prefs/makefile-new | 69 + scalos/Plugins/OOP/TitleClock/prefs/misc.c | 99 + scalos/Plugins/OOP/TitleClock/prefs/misc.h | 24 + scalos/Plugins/OOP/TitleClock/prefs/prefs_file.c | 194 + scalos/Plugins/OOP/TitleClock/prefs/prefs_file.h | 31 + scalos/Plugins/OOP/TitleClock/prefs/requesters.c | 173 + scalos/Plugins/OOP/TitleClock/prefs/requesters.h | 28 + scalos/Plugins/OOP/TitleClock/prefs/saveicon.c | 51 + scalos/Plugins/OOP/TitleClock/prefs/saveicon.h | 19 + scalos/Plugins/OOP/TitleClock/prefs/screen.c | 104 + scalos/Plugins/OOP/TitleClock/prefs/screen.h | 28 + scalos/Plugins/OOP/TitleClock/prefs/tcp_locale.c | 51 + scalos/Plugins/OOP/TitleClock/prefs/tcp_locale.h | 27 + scalos/Plugins/OOP/TitleClock/prefs/title_clock.cd | 98 + scalos/Plugins/OOP/TitleClock/prefs/title_clock.ct | 123 + .../OOP/TitleClock/prefs/title_clock_prefs.c | 267 + .../OOP/TitleClock/prefs/title_clock_prefs.h | 30 + .../OOP/TitleClock/prefs/title_clock_prefs.info | Bin 0 -> 2464 bytes scalos/Plugins/OOP/TitleClock/readme.1st | 54 + scalos/Plugins/OOP/XTWindows/AutoMsg.h | 38 + scalos/Plugins/OOP/XTWindows/XTWindows.c | 312 + scalos/Plugins/OOP/XTWindows/XTWindows.h | 48 + scalos/Plugins/OOP/XTWindows/config.mk | 71 + scalos/Plugins/OOP/XTWindows/makefile | 98 + scalos/Plugins/OOP/XTWindows/makefile-new | 69 + scalos/Plugins/OOP/XTWindows/plugin_data.h | 38 + scalos/Plugins/OOP/XTWindows/xtwindows.doc | 26 + scalos/Plugins/OOP/config.mk | 35 + scalos/Plugins/OOP/makefile | 48 + scalos/Plugins/OOP/makefile-new | 32 + scalos/Plugins/OOP/title_envvar/config.mk | 64 + scalos/Plugins/OOP/title_envvar/libfuncs.c | 217 + scalos/Plugins/OOP/title_envvar/makefile | 86 + scalos/Plugins/OOP/title_envvar/makefile-new | 69 + scalos/Plugins/OOP/title_envvar/plugin_data.h | 43 + scalos/Plugins/OOP/title_freepens/config.mk | 69 + scalos/Plugins/OOP/title_freepens/libfuncs.c | 198 + scalos/Plugins/OOP/title_freepens/makefile | 86 + scalos/Plugins/OOP/title_freepens/makefile-new | 69 + scalos/Plugins/OOP/title_freepens/plugin_data.h | 43 + scalos/Plugins/OOP/title_test/makefile | 81 + scalos/Plugins/OOP/title_test/scalos_macros.i | 213 + scalos/Plugins/OOP/title_test/title_test.s | 320 + scalos/Plugins/OOP/wb39_plugin/AppIcons.c | 225 + scalos/Plugins/OOP/wb39_plugin/AppWindow.c | 927 +++ scalos/Plugins/OOP/wb39_plugin/DefIcons.c | 356 + scalos/Plugins/OOP/wb39_plugin/NoDebug | 3 + scalos/Plugins/OOP/wb39_plugin/Scalos_Helper.c | 1073 +++ scalos/Plugins/OOP/wb39_plugin/Scalos_Helper.h | 43 + scalos/Plugins/OOP/wb39_plugin/WorkbenchControl.c | 1211 +++ scalos/Plugins/OOP/wb39_plugin/config.mk | 78 + scalos/Plugins/OOP/wb39_plugin/deficons_library.c | 194 + scalos/Plugins/OOP/wb39_plugin/deficons_plugin.asm | 198 + scalos/Plugins/OOP/wb39_plugin/makefile | 166 + scalos/Plugins/OOP/wb39_plugin/makefile-new | 98 + scalos/Plugins/OOP/wb39_plugin/persist/Persist.h | 54 + scalos/Plugins/OOP/wb39_plugin/persist/config.mk | 72 + scalos/Plugins/OOP/wb39_plugin/persist/makefile | 110 + .../Plugins/OOP/wb39_plugin/persist/makefile-new | 68 + scalos/Plugins/OOP/wb39_plugin/persist/persist.c | 1643 ++++ .../Plugins/OOP/wb39_plugin/persist/plugin_data.h | 36 + scalos/Plugins/OOP/wb39_plugin/plugin_data.h | 36 + scalos/Plugins/OOP/wb39_plugin/test.c | 305 + .../OOP/wb39_plugin/volumegauge/VolumeGauge.c | 474 ++ .../Plugins/OOP/wb39_plugin/volumegauge/config.mk | 71 + .../Plugins/OOP/wb39_plugin/volumegauge/makefile | 112 + .../OOP/wb39_plugin/volumegauge/makefile-new | 70 + .../OOP/wb39_plugin/volumegauge/plugin_data.h | 36 + .../OOP/wb39_plugin/volumegauge/vg_plugin.c | 469 ++ .../OOP/wb39_plugin/volumegauge/volumegauge.h | 65 + scalos/Plugins/OOP/wb39_plugin/wb39.c | 1745 +++++ scalos/Plugins/OOP/wb39_plugin/wb39.h | 113 + scalos/Plugins/OOP/wb39_plugin/wb39proto.h | 107 + .../Plugins/OOP/wb39_plugin/wbrexx/MenuTest.rexx | 11 + scalos/Plugins/OOP/wb39_plugin/wbrexx/RexxCmd.c | 2768 +++++++ .../Plugins/OOP/wb39_plugin/wbrexx/RexxGetAttrs.c | 2567 ++++++ scalos/Plugins/OOP/wb39_plugin/wbrexx/RexxIcon.c | 442 ++ scalos/Plugins/OOP/wb39_plugin/wbrexx/WBRexx.c | 2067 +++++ scalos/Plugins/OOP/wb39_plugin/wbrexx/WBRexx.doc | 1930 +++++ scalos/Plugins/OOP/wb39_plugin/wbrexx/WBRexxMain.c | 519 ++ scalos/Plugins/OOP/wb39_plugin/wbrexx/config.mk | 72 + scalos/Plugins/OOP/wb39_plugin/wbrexx/makefile | 129 + scalos/Plugins/OOP/wb39_plugin/wbrexx/makefile-new | 73 + .../Plugins/OOP/wb39_plugin/wbrexx/plugin_data.h | 36 + scalos/Plugins/OOP/wb39_plugin/wbrexx/rxtest.rexx | 246 + scalos/Plugins/OOP/wb39_plugin/wbrexx/rxtest2.rexx | 17 + scalos/Plugins/OOP/wb39_plugin/wbrexx/rxtest3.rexx | 27 + scalos/Plugins/OOP/wb39_plugin/wbrexx/rxtest4.rexx | 18 + scalos/Plugins/OOP/wb39_plugin/wbrexx/wbrexx.h | 248 + scalos/Plugins/Prefs/FileTypes/DefIcons.c | 739 ++ scalos/Plugins/Prefs/FileTypes/DefIconsPrefs.c | 2010 +++++ .../Plugins/Prefs/FileTypes/DefaultDefIconsPrefs.c | 255 + scalos/Plugins/Prefs/FileTypes/FileTypesPrefs.c | 7887 +++++++++++++++++++ scalos/Plugins/Prefs/FileTypes/FileTypesPrefs.h | 549 ++ .../Plugins/Prefs/FileTypes/FileTypesPrefsImage.h | 55 + .../Plugins/Prefs/FileTypes/FileTypesPrefs_proto.h | 105 + scalos/Plugins/Prefs/FileTypes/NoDebug | 3 + scalos/Plugins/Prefs/FileTypes/ReadFtPrefs.c | 1343 ++++ scalos/Plugins/Prefs/FileTypes/WriteFtPrefs.c | 513 ++ scalos/Plugins/Prefs/FileTypes/config.mk | 88 + scalos/Plugins/Prefs/FileTypes/debug.h | 19 + scalos/Plugins/Prefs/FileTypes/makefile | 184 + scalos/Plugins/Prefs/FileTypes/makefile-new | 111 + scalos/Plugins/Prefs/FileTypes/plugin_data.h | 27 + scalos/Plugins/Prefs/Menu/DefaultMenu.c | 646 ++ scalos/Plugins/Prefs/Menu/MenuPrefs.c | 5886 ++++++++++++++ scalos/Plugins/Prefs/Menu/MenuPrefs.h | 216 + scalos/Plugins/Prefs/Menu/MenuPrefsImage.h | 56 + scalos/Plugins/Prefs/Menu/NoDebug | 3 + scalos/Plugins/Prefs/Menu/config.mk | 78 + scalos/Plugins/Prefs/Menu/makefile | 152 + scalos/Plugins/Prefs/Menu/makefile-new | 100 + scalos/Plugins/Prefs/Menu/plugin_data.h | 27 + scalos/Plugins/Prefs/Palette/NoDebug | 3 + scalos/Plugins/Prefs/Palette/PalettePrefs.c | 3208 ++++++++ scalos/Plugins/Prefs/Palette/PalettePrefs.h | 110 + scalos/Plugins/Prefs/Palette/PalettePrefsImage.h | 55 + scalos/Plugins/Prefs/Palette/config.mk | 76 + scalos/Plugins/Prefs/Palette/makefile | 144 + scalos/Plugins/Prefs/Palette/makefile-new | 97 + scalos/Plugins/Prefs/Palette/plugin_data.h | 27 + scalos/Plugins/Prefs/Pattern/DoLoadDT.c | 234 + scalos/Plugins/Prefs/Pattern/LoadDT.h | 21 + scalos/Plugins/Prefs/Pattern/NoDebug | 3 + scalos/Plugins/Prefs/Pattern/PatternPrefs.c | 4409 +++++++++++ scalos/Plugins/Prefs/Pattern/PatternPrefs.h | 154 + scalos/Plugins/Prefs/Pattern/PatternPrefsImage.h | 53 + scalos/Plugins/Prefs/Pattern/config.mk | 81 + scalos/Plugins/Prefs/Pattern/debug.h | 19 + scalos/Plugins/Prefs/Pattern/makefile | 188 + scalos/Plugins/Prefs/Pattern/makefile-new | 94 + scalos/Plugins/Prefs/Pattern/plugin_data.h | 27 + .../Catalogs/deutsch/Scalos/ScalosPopupMenu.ct | 625 ++ .../Popupmenu/Catalogs/deutsch/Scalos/config.mk | 41 + .../Popupmenu/Catalogs/deutsch/Scalos/makefile | 13 + .../Popupmenu/Catalogs/deutsch/Scalos/makefile-new | 32 + .../fran\303\247ais/Scalos/ScalosPopupMenu.ct" | 619 ++ .../Catalogs/fran\303\247ais/Scalos/config.mk" | 40 + .../Catalogs/fran\303\247ais/Scalos/makefile" | 13 + .../Catalogs/fran\303\247ais/Scalos/makefile-new" | 32 + .../Catalogs/sample/Scalos/ScalosPopupMenu.ct | 626 ++ scalos/Plugins/Prefs/Popupmenu/FrameButtonMCC.c | 393 + scalos/Plugins/Prefs/Popupmenu/FrameButtonMCC.h | 49 + scalos/Plugins/Prefs/Popupmenu/PopupMenuPrefs.c | 2487 ++++++ scalos/Plugins/Prefs/Popupmenu/PopupMenuPrefs.h | 174 + .../Plugins/Prefs/Popupmenu/PopupMenuPrefsImage.h | 1049 +++ scalos/Plugins/Prefs/Popupmenu/ScalosPopupMenu.cd | 483 ++ scalos/Plugins/Prefs/Popupmenu/config.mk | 77 + scalos/Plugins/Prefs/Popupmenu/images/Horizontal | Bin 0 -> 2886 bytes .../Prefs/Popupmenu/images/Horizontal Space | Bin 0 -> 3008 bytes .../Prefs/Popupmenu/images/Horizontal Space.c | 156 + scalos/Plugins/Prefs/Popupmenu/images/Horizontal.c | 148 + .../Prefs/Popupmenu/images/Intermediate Spacing | Bin 0 -> 3170 bytes .../Prefs/Popupmenu/images/Intermediate Spacing.c | 165 + .../Plugins/Prefs/Popupmenu/images/NewStyle.brush | Bin 0 -> 582 bytes scalos/Plugins/Prefs/Popupmenu/images/NewStyle.c | 41 + .../Plugins/Prefs/Popupmenu/images/OldStyle.brush | Bin 0 -> 544 bytes scalos/Plugins/Prefs/Popupmenu/images/OldStyle.c | 41 + scalos/Plugins/Prefs/Popupmenu/images/PopupMenu | Bin 0 -> 1588 bytes scalos/Plugins/Prefs/Popupmenu/images/PopupMenu.c | 48 + .../Prefs/Popupmenu/images/Text Displacement | Bin 0 -> 2988 bytes .../Prefs/Popupmenu/images/Text Displacement.c | 159 + .../Plugins/Prefs/Popupmenu/images/Vertical Offset | Bin 0 -> 2374 bytes .../Prefs/Popupmenu/images/Vertical Offset.c | 130 + .../Plugins/Prefs/Popupmenu/images/Vertical Space | Bin 0 -> 2918 bytes .../Prefs/Popupmenu/images/Vertical Space.c | 148 + scalos/Plugins/Prefs/Popupmenu/makefile | 140 + scalos/Plugins/Prefs/Popupmenu/makefile-new | 109 + scalos/Plugins/Prefs/Popupmenu/plugin_data.h | 27 + scalos/Plugins/Prefs/config.mk | 34 + scalos/Plugins/Prefs/makefile | 46 + scalos/Plugins/Prefs/makefile-new | 33 + scalos/Plugins/Preview/DefPicture/DefPicture.c | 878 +++ scalos/Plugins/Preview/DefPicture/DefPicture.h | 26 + scalos/Plugins/Preview/DefPicture/config.mk | 68 + scalos/Plugins/Preview/DefPicture/makefile | 125 + scalos/Plugins/Preview/DefPicture/makefile-new | 73 + scalos/Plugins/Preview/DefPicture/plugin_data.h | 27 + scalos/Plugins/Preview/JpegPicture/JpegPicture.c | 1001 +++ scalos/Plugins/Preview/JpegPicture/JpegPicture.h | 35 + scalos/Plugins/Preview/JpegPicture/config.mk | 75 + scalos/Plugins/Preview/JpegPicture/makefile | 131 + scalos/Plugins/Preview/JpegPicture/makefile-new | 73 + scalos/Plugins/Preview/JpegPicture/plugin_data.h | 27 + scalos/Plugins/Preview/PNGPicture/PNGPicture.c | 785 ++ scalos/Plugins/Preview/PNGPicture/PNGPicture.h | 40 + scalos/Plugins/Preview/PNGPicture/config.mk | 83 + scalos/Plugins/Preview/PNGPicture/makefile | 134 + scalos/Plugins/Preview/PNGPicture/makefile-new | 74 + scalos/Plugins/Preview/PNGPicture/plugin_data.h | 27 + scalos/Plugins/Preview/Video/COPYING | 15 + scalos/Plugins/Preview/Video/Video.c | 1286 +++ scalos/Plugins/Preview/Video/Video.h | 44 + scalos/Plugins/Preview/Video/compat_68k.c | 845 ++ scalos/Plugins/Preview/Video/compat_mos.c | 559 ++ scalos/Plugins/Preview/Video/compat_os4.c | 96 + scalos/Plugins/Preview/Video/config.mk | 101 + scalos/Plugins/Preview/Video/makefile | 8 + scalos/Plugins/Preview/Video/makefile-new | 75 + scalos/Plugins/Preview/Video/plugin_data.h | 27 + scalos/Plugins/Preview/config.mk | 35 + scalos/Plugins/Preview/makefile | 45 + scalos/Plugins/Preview/makefile-new | 30 + scalos/Plugins/config.mk | 35 + scalos/Plugins/makefile | 46 + scalos/Plugins/makefile-new | 30 + .../Catalogs/deutsch/Scalos/ScalosFileTypes.ct | 1435 ++++ .../FileTypes/Catalogs/deutsch/Scalos/config.mk | 41 + .../FileTypes/Catalogs/deutsch/Scalos/makefile | 13 + .../FileTypes/Catalogs/deutsch/Scalos/makefile-new | 30 + .../fran\303\247ais/Scalos/ScalosFileTypes.ct" | 1421 ++++ .../Catalogs/fran\303\247ais/Scalos/config.mk" | 40 + .../Catalogs/fran\303\247ais/Scalos/makefile" | 13 + .../Catalogs/fran\303\247ais/Scalos/makefile-new" | 30 + .../Catalogs/sample/Scalos/ScalosFileTypes.ct | 1438 ++++ scalos/Prefs/FileTypes/FileTypes.c | 934 +++ scalos/Prefs/FileTypes/ScalosFileTypes.cd | 1164 +++ scalos/Prefs/FileTypes/Scalos_FileTypes.info | Bin 0 -> 2577 bytes scalos/Prefs/FileTypes/config.mk | 55 + scalos/Prefs/FileTypes/makefile | 132 + scalos/Prefs/FileTypes/makefile-new | 96 + .../MainPrefs/Catalogs/deutsch/Scalos/Makefile | 13 + .../Catalogs/deutsch/Scalos/Scalos_Prefs.ct | 4212 ++++++++++ .../MainPrefs/Catalogs/deutsch/Scalos/config.mk | 41 + .../MainPrefs/Catalogs/deutsch/Scalos/makefile-new | 30 + .../Catalogs/fran\303\247ais/Scalos/Makefile" | 13 + .../fran\303\247ais/Scalos/Scalos_Prefs.ct" | 3677 +++++++++ .../Catalogs/fran\303\247ais/Scalos/config.mk" | 41 + .../Catalogs/fran\303\247ais/Scalos/makefile-new" | 32 + .../Catalogs/sample/Scalos/Scalos_Prefs.ct | 4172 ++++++++++ scalos/Prefs/MainPrefs/General.h | 18 + scalos/Prefs/MainPrefs/HiddenDevices.c | 785 ++ scalos/Prefs/MainPrefs/HiddenDevices.h | 29 + scalos/Prefs/MainPrefs/Hooks.c | 1529 ++++ scalos/Prefs/MainPrefs/Hooks.h | 50 + scalos/Prefs/MainPrefs/Images.c | 2987 +++++++ scalos/Prefs/MainPrefs/Images.h | 9 + scalos/Prefs/MainPrefs/Images/FileTypesPrefs.brush | Bin 0 -> 1756 bytes scalos/Prefs/MainPrefs/Images/FileTypesPrefs.c | 59 + scalos/Prefs/MainPrefs/Images/IconProperties.brush | Bin 0 -> 1772 bytes scalos/Prefs/MainPrefs/Images/IconProperties.c | 60 + scalos/Prefs/MainPrefs/Images/Information.brush | Bin 0 -> 1820 bytes scalos/Prefs/MainPrefs/Images/Information.c | 63 + scalos/Prefs/MainPrefs/Images/MenuPrefs.brush | Bin 0 -> 1804 bytes scalos/Prefs/MainPrefs/Images/NewDrawer.brush | Bin 0 -> 2116 bytes scalos/Prefs/MainPrefs/Images/NewDrawer.c | 83 + scalos/Prefs/MainPrefs/Images/Palette.brush | Bin 0 -> 1756 bytes scalos/Prefs/MainPrefs/Images/Palette.c | 59 + scalos/Prefs/MainPrefs/Images/PatternPrefs.brush | Bin 0 -> 1724 bytes scalos/Prefs/MainPrefs/Images/PatternPrefs.c | 57 + scalos/Prefs/MainPrefs/Images/Reboot.brush | Bin 0 -> 2212 bytes scalos/Prefs/MainPrefs/Images/Reboot.c | 89 + scalos/Prefs/MainPrefs/Images/TrueTypeFonts.brush | Bin 0 -> 1692 bytes scalos/Prefs/MainPrefs/Images/TrueTypeFonts.c | 55 + .../Prefs/MainPrefs/Images/WindowProperties.brush | Bin 0 -> 2236 bytes scalos/Prefs/MainPrefs/Images/WindowProperties.c | 91 + scalos/Prefs/MainPrefs/Images/about.brush | Bin 0 -> 1548 bytes scalos/Prefs/MainPrefs/Images/about.c | 45 + scalos/Prefs/MainPrefs/Images/delete.brush | Bin 0 -> 1852 bytes scalos/Prefs/MainPrefs/Images/delete.c | 65 + scalos/Prefs/MainPrefs/Images/desktop.brush | Bin 0 -> 1676 bytes scalos/Prefs/MainPrefs/Images/desktop.c | 54 + scalos/Prefs/MainPrefs/Images/dragndrop.brush | Bin 0 -> 1628 bytes scalos/Prefs/MainPrefs/Images/dragndrop.c | 50 + scalos/Prefs/MainPrefs/Images/empty_trashcan.brush | Bin 0 -> 1884 bytes scalos/Prefs/MainPrefs/Images/empty_trashcan.c | 67 + .../Prefs/MainPrefs/Images/execute_command.brush | Bin 0 -> 2308 bytes scalos/Prefs/MainPrefs/Images/execute_command.c | 96 + scalos/Prefs/MainPrefs/Images/filedisplay.brush | Bin 0 -> 1676 bytes scalos/Prefs/MainPrefs/Images/filedisplay.c | 54 + scalos/Prefs/MainPrefs/Images/format_disk.brush | Bin 0 -> 2208 bytes scalos/Prefs/MainPrefs/Images/format_disk.c | 81 + scalos/Prefs/MainPrefs/Images/icon-128x128.iff | Bin 0 -> 6696 bytes scalos/Prefs/MainPrefs/Images/icon-16x16.iff | Bin 0 -> 376 bytes scalos/Prefs/MainPrefs/Images/icon-24x24.iff | Bin 0 -> 668 bytes scalos/Prefs/MainPrefs/Images/icon-32x32.iff | Bin 0 -> 826 bytes scalos/Prefs/MainPrefs/Images/icon-48x48.iff | Bin 0 -> 1486 bytes scalos/Prefs/MainPrefs/Images/icon-64x64.iff | Bin 0 -> 2248 bytes scalos/Prefs/MainPrefs/Images/icon-96x96.iff | Bin 0 -> 4378 bytes scalos/Prefs/MainPrefs/Images/icon128.c | 489 ++ scalos/Prefs/MainPrefs/Images/icon16.c | 67 + scalos/Prefs/MainPrefs/Images/icon24.c | 87 + scalos/Prefs/MainPrefs/Images/icon32.c | 97 + scalos/Prefs/MainPrefs/Images/icon48.c | 141 + scalos/Prefs/MainPrefs/Images/icon64.c | 192 + scalos/Prefs/MainPrefs/Images/icon96.c | 334 + scalos/Prefs/MainPrefs/Images/icons.brush | Bin 0 -> 1676 bytes scalos/Prefs/MainPrefs/Images/icons.c | 54 + scalos/Prefs/MainPrefs/Images/img1 | Bin 0 -> 14554 bytes scalos/Prefs/MainPrefs/Images/img2 | Bin 0 -> 15690 bytes scalos/Prefs/MainPrefs/Images/img3 | Bin 0 -> 12628 bytes scalos/Prefs/MainPrefs/Images/misc.brush | Bin 0 -> 1564 bytes scalos/Prefs/MainPrefs/Images/misc.c | 46 + scalos/Prefs/MainPrefs/Images/modules.brush | Bin 0 -> 1660 bytes scalos/Prefs/MainPrefs/Images/modules.c | 53 + scalos/Prefs/MainPrefs/Images/paths.brush | Bin 0 -> 1676 bytes scalos/Prefs/MainPrefs/Images/paths.c | 54 + scalos/Prefs/MainPrefs/Images/plugins.brush | Bin 0 -> 1676 bytes scalos/Prefs/MainPrefs/Images/plugins.c | 54 + scalos/Prefs/MainPrefs/Images/rename.brush | Bin 0 -> 1900 bytes scalos/Prefs/MainPrefs/Images/rename.c | 69 + scalos/Prefs/MainPrefs/Images/startup.brush | Bin 0 -> 1676 bytes scalos/Prefs/MainPrefs/Images/startup.c | 54 + scalos/Prefs/MainPrefs/Images/systeminfo.brush | Bin 0 -> 2140 bytes scalos/Prefs/MainPrefs/Images/systeminfo.c | 85 + scalos/Prefs/MainPrefs/Images/textwindows.brush | Bin 0 -> 1644 bytes scalos/Prefs/MainPrefs/Images/textwindows.c | 51 + scalos/Prefs/MainPrefs/Images/windows.brush | Bin 0 -> 1676 bytes scalos/Prefs/MainPrefs/Images/windows.c | 54 + scalos/Prefs/MainPrefs/MCC_GFXListview.c | 40 + scalos/Prefs/MainPrefs/MCPFrame_mcc.h | 43 + scalos/Prefs/MainPrefs/Makefile | 204 + scalos/Prefs/MainPrefs/McpFrameMCC.c | 335 + scalos/Prefs/MainPrefs/McpFrameMCC.h | 25 + scalos/Prefs/MainPrefs/NoDebug | 3 + scalos/Prefs/MainPrefs/PrefsPlugins.c | 508 ++ scalos/Prefs/MainPrefs/PrefsPlugins.h | 27 + scalos/Prefs/MainPrefs/PrefsVersion.c | 31 + scalos/Prefs/MainPrefs/ReadWritePrefs.c | 3236 ++++++++ scalos/Prefs/MainPrefs/ReadWritePrefs.h | 34 + scalos/Prefs/MainPrefs/Scalos.c | 8090 +++++++++++++++++++ scalos/Prefs/MainPrefs/ScalosPrefs.h | 627 ++ scalos/Prefs/MainPrefs/Scalos_Prefs.cd | 3157 ++++++++ scalos/Prefs/MainPrefs/Scalos_Prefs.info | Bin 0 -> 2401 bytes scalos/Prefs/MainPrefs/SelectMarkSampleClass.c | 450 ++ scalos/Prefs/MainPrefs/SelectMarkSampleClass.h | 33 + scalos/Prefs/MainPrefs/UrlSubject.h | 9 + scalos/Prefs/MainPrefs/config.mk | 68 + scalos/Prefs/MainPrefs/locale.h | 22 + scalos/Prefs/MainPrefs/makefile-new | 116 + .../Prefs/Menu/Catalogs/dansk/Scalos/ScalosMenu.ct | 1934 +++++ scalos/Prefs/Menu/Catalogs/dansk/Scalos/config.mk | 41 + scalos/Prefs/Menu/Catalogs/dansk/Scalos/makefile | 13 + .../Prefs/Menu/Catalogs/dansk/Scalos/makefile-new | 32 + .../Menu/Catalogs/deutsch/Scalos/ScalosMenu.ct | 1975 +++++ .../Prefs/Menu/Catalogs/deutsch/Scalos/config.mk | 41 + scalos/Prefs/Menu/Catalogs/deutsch/Scalos/makefile | 13 + .../Menu/Catalogs/deutsch/Scalos/makefile-new | 32 + .../Catalogs/espa\303\261ol/scalos/ScalosMenu.ct" | 1989 +++++ .../Menu/Catalogs/espa\303\261ol/scalos/config.mk" | 41 + .../Menu/Catalogs/espa\303\261ol/scalos/makefile" | 12 + .../Catalogs/espa\303\261ol/scalos/makefile-new" | 32 + .../Catalogs/fran\303\247ais/Scalos/ScalosMenu.ct" | 1877 +++++ .../Catalogs/fran\303\247ais/Scalos/config.mk" | 40 + .../Menu/Catalogs/fran\303\247ais/Scalos/makefile" | 13 + .../Catalogs/fran\303\247ais/Scalos/makefile-new" | 32 + .../Menu/Catalogs/italiano/Scalos/ScalosMenu.ct | 1936 +++++ .../Prefs/Menu/Catalogs/italiano/Scalos/config.mk | 41 + .../Prefs/Menu/Catalogs/italiano/Scalos/makefile | 13 + .../Menu/Catalogs/italiano/Scalos/makefile-new | 32 + .../Menu/Catalogs/sample/Scalos/ScalosMenu.ct | 1944 +++++ .../Menu/Catalogs/svenska/Scalos/ScalosMenu.ct | 1935 +++++ .../Prefs/Menu/Catalogs/svenska/Scalos/config.mk | 41 + scalos/Prefs/Menu/Catalogs/svenska/Scalos/makefile | 13 + .../Menu/Catalogs/svenska/Scalos/makefile-new | 32 + .../\303\203e\303\223tina/Scalos/ScalosMenu.ct" | 1934 +++++ .../\303\203e\303\223tina/Scalos/config.mk" | 41 + .../\303\203e\303\223tina/Scalos/makefile" | 12 + .../\303\203e\303\223tina/Scalos/makefile-new" | 32 + scalos/Prefs/Menu/Menu.c | 970 +++ scalos/Prefs/Menu/ParM.cfg | 294 + scalos/Prefs/Menu/ScalosMenu.cd | 1684 ++++ scalos/Prefs/Menu/Scalos_Menu.info | Bin 0 -> 1809 bytes scalos/Prefs/Menu/ToolsDaemon.menu | 12 + scalos/Prefs/Menu/config.mk | 60 + scalos/Prefs/Menu/makefile | 137 + scalos/Prefs/Menu/makefile-new | 97 + .../Palette/Catalogs/dansk/Scalos/ScalosPalette.ct | 435 + .../Prefs/Palette/Catalogs/dansk/Scalos/config.mk | 41 + .../Prefs/Palette/Catalogs/dansk/Scalos/makefile | 13 + .../Palette/Catalogs/dansk/Scalos/makefile-new | 32 + .../Catalogs/deutsch/Scalos/ScalosPalette.ct | 462 ++ .../Palette/Catalogs/deutsch/Scalos/config.mk | 41 + .../Prefs/Palette/Catalogs/deutsch/Scalos/makefile | 13 + .../Palette/Catalogs/deutsch/Scalos/makefile-new | 32 + .../espa\303\261ol/scalos/ScalosPalette.ct" | 434 + .../Catalogs/espa\303\261ol/scalos/config.mk" | 41 + .../Catalogs/espa\303\261ol/scalos/makefile" | 12 + .../Catalogs/espa\303\261ol/scalos/makefile-new" | 32 + .../fran\303\247ais/Scalos/ScalosPalette.ct" | 537 ++ .../Catalogs/fran\303\247ais/Scalos/config.mk" | 40 + .../Catalogs/fran\303\247ais/Scalos/makefile" | 13 + .../Catalogs/fran\303\247ais/Scalos/makefile-new" | 32 + .../Catalogs/italiano/Scalos/ScalosPalette.ct | 434 + .../Palette/Catalogs/italiano/Scalos/config.mk | 41 + .../Palette/Catalogs/italiano/Scalos/makefile | 13 + .../Palette/Catalogs/italiano/Scalos/makefile-new | 33 + .../Catalogs/sample/Scalos/ScalosPalette.ct | 435 + .../Catalogs/svenska/Scalos/ScalosPalette.ct | 435 + .../Palette/Catalogs/svenska/Scalos/config.mk | 41 + .../Prefs/Palette/Catalogs/svenska/Scalos/makefile | 13 + .../Palette/Catalogs/svenska/Scalos/makefile-new | 32 + .../\303\203e\303\223tina/Scalos/ScalosPalette.ct" | 435 + .../\303\203e\303\223tina/Scalos/config.mk" | 41 + .../\303\203e\303\223tina/Scalos/makefile" | 12 + .../\303\203e\303\223tina/Scalos/makefile-new" | 32 + scalos/Prefs/Palette/Palette.c | 878 +++ scalos/Prefs/Palette/ScalosPalette.cd | 418 + scalos/Prefs/Palette/Scalos_Palette.info | Bin 0 -> 2399 bytes scalos/Prefs/Palette/config.mk | 56 + scalos/Prefs/Palette/makefile | 138 + scalos/Prefs/Palette/makefile-new | 97 + .../Pattern/Catalogs/dansk/Scalos/ScalosPattern.ct | 698 ++ .../Prefs/Pattern/Catalogs/dansk/Scalos/config.mk | 41 + .../Prefs/Pattern/Catalogs/dansk/Scalos/makefile | 13 + .../Pattern/Catalogs/dansk/Scalos/makefile-new | 32 + .../Catalogs/deutsch/Scalos/ScalosPattern.ct | 718 ++ .../Pattern/Catalogs/deutsch/Scalos/config.mk | 41 + .../Prefs/Pattern/Catalogs/deutsch/Scalos/makefile | 13 + .../Pattern/Catalogs/deutsch/Scalos/makefile-new | 32 + .../espa\303\261ol/scalos/ScalosPattern.ct" | 647 ++ .../Catalogs/espa\303\261ol/scalos/config.mk" | 41 + .../Catalogs/espa\303\261ol/scalos/makefile" | 12 + .../Catalogs/espa\303\261ol/scalos/makefile-new" | 32 + .../fran\303\247ais/Scalos/ScalosPattern.ct" | 846 ++ .../Catalogs/fran\303\247ais/Scalos/config.mk" | 40 + .../Catalogs/fran\303\247ais/Scalos/makefile" | 13 + .../Catalogs/fran\303\247ais/Scalos/makefile-new" | 32 + .../Catalogs/italiano/Scalos/ScalosPattern.ct | 684 ++ .../Pattern/Catalogs/italiano/Scalos/config.mk | 41 + .../Pattern/Catalogs/italiano/Scalos/makefile | 13 + .../Pattern/Catalogs/italiano/Scalos/makefile-new | 32 + .../Catalogs/sample/Scalos/ScalosPattern.ct | 696 ++ .../Catalogs/svenska/Scalos/ScalosPattern.ct | 659 ++ .../Pattern/Catalogs/svenska/Scalos/config.mk | 41 + .../Prefs/Pattern/Catalogs/svenska/Scalos/makefile | 13 + .../Pattern/Catalogs/svenska/Scalos/makefile-new | 32 + .../\303\203e\303\223tina/Scalos/ScalosPattern.ct" | 696 ++ .../\303\203e\303\223tina/Scalos/config.mk" | 41 + .../\303\203e\303\223tina/Scalos/makefile" | 12 + .../\303\203e\303\223tina/Scalos/makefile-new" | 32 + scalos/Prefs/Pattern/Pattern.c | 923 +++ scalos/Prefs/Pattern/Pattern.h | 25 + scalos/Prefs/Pattern/ScalosPattern.cd | 648 ++ scalos/Prefs/Pattern/Scalos_Pattern.info | Bin 0 -> 2833 bytes scalos/Prefs/Pattern/config.mk | 56 + scalos/Prefs/Pattern/makefile | 137 + scalos/Prefs/Pattern/makefile-new | 97 + scalos/Prefs/config.mk | 39 + scalos/Prefs/makefile | 46 + scalos/Prefs/makefile-new | 31 + scalos/Release | 286 + scalos/ReleaseAROS | 131 + scalos/ScalosBeta.info | Bin 0 -> 1912 bytes scalos/common/BackfillMCC/Backfill.c | 395 + scalos/common/BackfillMCC/Backfill.h | 47 + scalos/common/BitMapMCC/BitMapMCC.c | 456 ++ scalos/common/BitMapMCC/BitMapMCC.h | 41 + scalos/common/DataTypesMCC/DataTypesMCC.c | 659 ++ scalos/common/DataTypesMCC/DataTypesMCC.h | 47 + scalos/common/FontSampleMCC/FontSampleMCC.c | 593 ++ scalos/common/FontSampleMCC/FontSampleMCC.h | 63 + scalos/common/Fs/FsAbstraction.c | 588 ++ scalos/common/Fs/FsAbstraction.h | 54 + scalos/common/IconobjectMCC/IconobjectMCC.c | 315 + scalos/common/IconobjectMCC/IconobjectMCC.h | 28 + scalos/common/Int64/Dos64.c | 38 + scalos/common/Int64/int64.c | 489 ++ scalos/common/Int64/int64.h | 42 + scalos/common/McpGfx/ScalosMcpGfx.c | 427 + scalos/common/McpGfx/ScalosMcpGfx.h | 21 + scalos/common/Plugin/config.mk | 31 + scalos/common/Plugin/plugin-aos4-68kstubs.c | 18 + scalos/common/Plugin/plugin-aos4.c | 277 + scalos/common/Plugin/plugin-aros.c | 255 + scalos/common/Plugin/plugin-classic.c | 221 + scalos/common/Plugin/plugin-common.c | 106 + scalos/common/Plugin/plugin.h | 77 + .../Plugin/scalosfiletypeplugin-aos4-68kstubs.c | 79 + scalos/common/Plugin/scalosplugin-aos4-68kstubs.c | 77 + .../Plugin/scalosprefsplugin-aos4-68kstubs.c | 78 + .../Plugin/scalospreviewplugin-aos4-68kstubs.c | 81 + scalos/common/malloc/malloc.c | 6321 +++++++++++++++ scalos/common/saslib/config.mk | 41 + scalos/common/saslib/makefile-new | 155 + scalos/common/saslib/saslib.c | 44 + scalos/common/saslib/saslib.h | 15 + scalos/config.mk | 280 + .../AmigaIconObj3.5/AmigaIconObj35-aos4.c | 191 + .../AmigaIconObj3.5/AmigaIconObj35-aros.c | 212 + .../AmigaIconObj3.5/AmigaIconObj35-classic.c | 172 + scalos/datatypes/AmigaIconObj3.5/AmigaIconObj35.c | 1868 +++++ scalos/datatypes/AmigaIconObj3.5/AmigaIconObj35.h | 143 + scalos/datatypes/AmigaIconObj3.5/config.mk | 51 + scalos/datatypes/AmigaIconObj3.5/makefile | 104 + scalos/datatypes/AmigaIconObj3.5/makefile-new | 74 + .../AmigaIconObject/AmigaIconObject-aos4.c | 190 + .../AmigaIconObject/AmigaIconObject-aros.c | 214 + .../AmigaIconObject/AmigaIconObject-classic.c | 181 + scalos/datatypes/AmigaIconObject/AmigaIconObject.c | 1025 +++ scalos/datatypes/AmigaIconObject/AmigaIconObject.h | 140 + .../datatypes/AmigaIconObject/amigaiconobject.dt | 6 + scalos/datatypes/AmigaIconObject/config.mk | 51 + scalos/datatypes/AmigaIconObject/makefile | 100 + scalos/datatypes/AmigaIconObject/makefile-new | 73 + .../datatypes/GlowIconObject/GlowIconObject-aos4.c | 191 + .../datatypes/GlowIconObject/GlowIconObject-aros.c | 212 + .../GlowIconObject/GlowIconObject-classic.c | 172 + scalos/datatypes/GlowIconObject/GlowIconObject.c | 4040 ++++++++++ scalos/datatypes/GlowIconObject/GlowIconObject.h | 270 + scalos/datatypes/GlowIconObject/config.mk | 54 + scalos/datatypes/GlowIconObject/makefile | 112 + scalos/datatypes/GlowIconObject/makefile-new | 73 + scalos/datatypes/IconObject/argb.c | 435 + scalos/datatypes/IconObject/config.mk | 59 + scalos/datatypes/IconObject/iconobj-aos4.c | 192 + scalos/datatypes/IconObject/iconobj-aros.c | 199 + scalos/datatypes/IconObject/iconobj-classic.c | 174 + scalos/datatypes/IconObject/iconobj.c | 3949 ++++++++++ scalos/datatypes/IconObject/iconobj.h | 319 + scalos/datatypes/IconObject/makefile | 113 + scalos/datatypes/IconObject/makefile-new | 85 + scalos/datatypes/New Icon Format Mail | 223 + scalos/datatypes/NewIcons/NewIconDt.c | 1484 ++++ scalos/datatypes/NewIcons/NewIconDt.h | 84 + scalos/datatypes/NewIcons/config.mk | 33 + scalos/datatypes/NewIcons/makefile | 97 + scalos/datatypes/NewIcons/makefile-new | 66 + scalos/datatypes/NewIcons/newiconobject.dt | 6 + scalos/datatypes/PNGIcons/GetPNGPicture.c | 227 + scalos/datatypes/PNGIcons/LoadPngIcon.c | 500 ++ scalos/datatypes/PNGIcons/PNGIconDt-aos4.c | 191 + scalos/datatypes/PNGIcons/PNGIconDt-aros.c | 225 + scalos/datatypes/PNGIcons/PNGIconDt-classic.c | 189 + scalos/datatypes/PNGIcons/PNGIconDt.c | 1263 +++ scalos/datatypes/PNGIcons/PNGIconDt.h | 260 + scalos/datatypes/PNGIcons/PNGIconProto.h | 64 + scalos/datatypes/PNGIcons/SavePngIcon.c | 547 ++ scalos/datatypes/PNGIcons/config.mk | 64 + scalos/datatypes/PNGIcons/makefile | 123 + scalos/datatypes/PNGIcons/makefile-new | 78 + scalos/datatypes/config.mk | 39 + scalos/datatypes/makefile | 47 + scalos/datatypes/makefile-new | 38 + scalos/gpl-3.0.txt | 674 ++ scalos/include/DefIcons.h | 75 + scalos/include/MUIundoc.h | 263 + scalos/include/Year.h | 11 + scalos/include/clib/cybergraphics_protos.h | 78 + scalos/include/clib/dtlib_protos.h | 29 + scalos/include/clib/guigfx_protos.h | 70 + scalos/include/clib/iconobject_protos.h | 39 + scalos/include/clib/mcpgfx_protos.h | 46 + scalos/include/clib/newicon_protos.h | 37 + scalos/include/clib/openurl_protos.h | 64 + scalos/include/clib/pm_protos.h | 54 + scalos/include/clib/preferences_protos.h | 38 + scalos/include/clib/scalos_protos.h | 83 + scalos/include/clib/scalosfiletypeplugin_protos.h | 26 + scalos/include/clib/scalosgfx_protos.h | 93 + scalos/include/clib/scalosmenuplugin_protos.h | 26 + scalos/include/clib/scalosplugin_protos.h | 18 + scalos/include/clib/scalosprefsplugin_protos.h | 23 + scalos/include/clib/scalospreviewplugin_protos.h | 30 + scalos/include/clib/sqlite3_protos.h | 138 + scalos/include/clib/titlebarimage_protos.h | 15 + scalos/include/clib/ttengine_protos.h | 56 + scalos/include/curl/curl.h | 2125 +++++ scalos/include/curl/curlbuild.h | 191 + scalos/include/curl/curlrules.h | 252 + scalos/include/curl/curlver.h | 69 + scalos/include/curl/easy.h | 102 + scalos/include/curl/multi.h | 345 + scalos/include/cybergraphx/cybergraphics.h | 300 + scalos/include/datatypes/animationclassext.h | 70 + scalos/include/datatypes/iconobject.h | 533 ++ scalos/include/defines/dtlib.h | 20 + scalos/include/defines/guigfx.h | 342 + scalos/include/defines/iconobject.h | 85 + scalos/include/defines/mcpgfx.h | 84 + scalos/include/defines/newicon.h | 71 + scalos/include/defines/preferences.h | 99 + scalos/include/defines/scalos.h | 348 + scalos/include/defines/scalosfiletypeplugin.h | 21 + scalos/include/defines/scalosgfx.h | 327 + scalos/include/defines/scalosmenuplugin.h | 21 + scalos/include/defines/scalosplugin.h | 19 + scalos/include/defines/scalosprefsplugin.h | 20 + scalos/include/defines/scalospreviewplugin.h | 29 + scalos/include/defines/sqlite3.h | 736 ++ scalos/include/defines/ttengine.h | 172 + scalos/include/defs.h | 2872 +++++++ scalos/include/ffmpeg/avformat.h | 1157 +++ scalos/include/ffmpeg/avio.h | 370 + scalos/include/ffmpeg/common.h | 408 + scalos/include/ffmpeg/integer.h | 84 + scalos/include/ffmpeg/intfloat_readwrite.h | 40 + scalos/include/ffmpeg/libavcodec/avcodec.h | 3036 +++++++ scalos/include/ffmpeg/libavcodec/imgconvert.h | 39 + scalos/include/ffmpeg/libavutil/avutil.h | 147 + scalos/include/ffmpeg/log.h | 129 + scalos/include/ffmpeg/mathematics.h | 69 + scalos/include/ffmpeg/mem.h | 119 + scalos/include/ffmpeg/rational.h | 129 + scalos/include/ffmpeg/rtp.h | 92 + scalos/include/ffmpeg/rtsp.h | 99 + scalos/include/ffmpeg/rtspcodes.h | 40 + scalos/include/ffmpeg/swscale.h | 152 + scalos/include/images/titlebar.h | 44 + scalos/include/inline/cybergraphics.h | 172 + scalos/include/inline/dtlib.h | 27 + scalos/include/inline/guigfx.h | 224 + scalos/include/inline/iconobject.h | 71 + scalos/include/inline/mcpgfx.h | 71 + scalos/include/inline/newicon.h | 59 + scalos/include/inline/openurl.h | 89 + scalos/include/inline/pm.h | 146 + scalos/include/inline/preferences.h | 63 + scalos/include/inline/scalos.h | 224 + scalos/include/inline/scalosfiletypeplugin.h | 29 + scalos/include/inline/scalosgfx.h | 176 + scalos/include/inline/scalosmenuplugin.h | 24 + scalos/include/inline/scalosplugin.h | 22 + scalos/include/inline/scalosprefsplugin.h | 22 + scalos/include/inline/scalospreviewplugin.h | 32 + scalos/include/inline/sqlite3.h | 425 + scalos/include/inline/ttengine.h | 127 + scalos/include/inline4/cybergraphics.h | 98 + scalos/include/inline4/guigfx.h | 153 + scalos/include/inline4/iconobject.h | 60 + scalos/include/inline4/openurl.h | 57 + scalos/include/inline4/pm.h | 99 + scalos/include/inline4/preferences.h | 40 + scalos/include/inline4/scalos.h | 128 + scalos/include/inline4/scalosfiletypeplugin.h | 31 + scalos/include/inline4/scalosgfx.h | 102 + scalos/include/inline4/scalosmenuplugin.h | 31 + scalos/include/inline4/scalosplugin.h | 28 + scalos/include/inline4/scalosprefsplugin.h | 28 + scalos/include/inline4/scalospreviewplugin.h | 39 + scalos/include/inline4/sqlite3.h | 138 + scalos/include/inline4/ttengine.h | 82 + scalos/include/interfaces/cybergraphics.h | 80 + scalos/include/interfaces/guigfx.h | 91 + scalos/include/interfaces/iconobject.h | 47 + scalos/include/interfaces/openurl.h | 48 + scalos/include/interfaces/openurl.i | 36 + scalos/include/interfaces/pm.h | 64 + scalos/include/interfaces/preferences.h | 43 + scalos/include/interfaces/scalos.h | 87 + scalos/include/interfaces/scalosfiletypeplugin.h | 34 + scalos/include/interfaces/scalosgfx.h | 77 + scalos/include/interfaces/scalosmenuplugin.h | 41 + scalos/include/interfaces/scalosplugin.h | 45 + scalos/include/interfaces/scalosprefsplugin.h | 31 + scalos/include/interfaces/scalospreviewplugin.h | 38 + scalos/include/interfaces/sqlite3.h | 133 + scalos/include/interfaces/ttengine.h | 62 + scalos/include/intuition/newmouse.h | 31 + scalos/include/jconfig.h | 46 + scalos/include/jerror.h | 304 + scalos/include/jmorecfg.h | 389 + scalos/include/jpeglib.h | 1173 +++ scalos/include/libraries/mcpgfx.h | 88 + scalos/include/libraries/openurl.h | 227 + scalos/include/libraries/pm.h | 311 + scalos/include/libraries/ttengine.h | 149 + scalos/include/png.h | 3319 ++++++++ scalos/include/pngconf.h | 632 ++ scalos/include/pnglibconf.h | 209 + scalos/include/ppcinline/macros.h | 33 + scalos/include/ppcinline/openurl.h | 89 + scalos/include/ppcinline/ttengine.h | 149 + scalos/include/pragmas/alib_stdio_pragmas.h | 30 + scalos/include/pragmas/cybergraphics_pragmas.h | 47 + scalos/include/pragmas/dtlib_pragmas.h | 37 + scalos/include/pragmas/guigfx_pragmas.h | 57 + scalos/include/pragmas/iconobject_pragmas.h | 87 + scalos/include/pragmas/mcpgfx_pragmas.h | 76 + scalos/include/pragmas/newicon_pragmas.h | 61 + scalos/include/pragmas/openurl_pragmas.h | 69 + scalos/include/pragmas/pm_pragmas.h | 173 + scalos/include/pragmas/preferences_pragmas.h | 64 + scalos/include/pragmas/scalos_pragmas.h | 58 + .../include/pragmas/scalosfiletypeplugin_pragmas.h | 37 + scalos/include/pragmas/scalosgfx_pragmas.h | 46 + scalos/include/pragmas/scalosmenuplugin_pragmas.h | 37 + scalos/include/pragmas/scalosplugin_pragmas.h | 10 + scalos/include/pragmas/scalosprefsplugin_pragmas.h | 37 + .../include/pragmas/scalospreviewplugin_pragmas.h | 45 + scalos/include/pragmas/sqlite3_pragmas.h | 111 + scalos/include/pragmas/titlebarimage_pragmas.h | 12 + scalos/include/pragmas/ttengine_pragmas.h | 63 + scalos/include/prefs/popupmenu.h | 125 + scalos/include/proto/alib.h | 3 + scalos/include/proto/cybergraphics.h | 28 + scalos/include/proto/dtlib.h | 21 + scalos/include/proto/guigfx.h | 29 + scalos/include/proto/iconobject.h | 29 + scalos/include/proto/mcpgfx.h | 25 + scalos/include/proto/newicon.h | 30 + scalos/include/proto/openurl.h | 83 + scalos/include/proto/pm.h | 27 + scalos/include/proto/preferences.h | 30 + scalos/include/proto/scalos.h | 31 + scalos/include/proto/scalosfiletypeplugin.h | 29 + scalos/include/proto/scalosgfx.h | 31 + scalos/include/proto/scalosmenuplugin.h | 29 + scalos/include/proto/scalosplugin.h | 29 + scalos/include/proto/scalosprefsplugin.h | 29 + scalos/include/proto/scalospreviewplugin.h | 29 + scalos/include/proto/sqlite3.h | 30 + scalos/include/proto/titlebarimage.h | 7 + scalos/include/proto/ttengine.h | 41 + scalos/include/scalos/GadgetBar.h | 120 + scalos/include/scalos/int64types.h | 42 + scalos/include/scalos/menu.h | 94 + scalos/include/scalos/palette.h | 84 + scalos/include/scalos/pattern.h | 166 + scalos/include/scalos/preferences.h | 176 + scalos/include/scalos/scalos.h | 2813 +++++++ scalos/include/scalos/scalosgfx.h | 190 + scalos/include/scalos/scalosmenuprefsplugin.h | 49 + scalos/include/scalos/scalospatternprefsplugin.h | 46 + scalos/include/scalos/scalosprefs.h | 120 + scalos/include/scalos/scalosprefsplugin.h | 105 + scalos/include/scalos/scalospreviewplugin.h | 71 + scalos/include/scalos/undo.h | 230 + scalos/include/scalosdebug.h | 18 + scalos/include/sqlite3.h | 6949 ++++++++++++++++ scalos/include/zconf.h | 428 + scalos/include/zlib.h | 1613 ++++ scalos/lgpl-3.0.txt | 165 + scalos/libraries/config.mk | 48 + scalos/libraries/iconobject/IconObject-aos4.c | 290 + scalos/libraries/iconobject/IconObject-aros.c | 205 + scalos/libraries/iconobject/IconObject-classic.c | 179 + scalos/libraries/iconobject/IconObject.c | 760 ++ scalos/libraries/iconobject/IconObject.h | 93 + scalos/libraries/iconobject/config.mk | 49 + scalos/libraries/iconobject/iconnode.h | 53 + .../iconobject/iconobject-aos4-68kstubs.c | 161 + scalos/libraries/iconobject/iconobject_base.h | 30 + scalos/libraries/iconobject/makefile | 106 + scalos/libraries/iconobject/makefile-new | 78 + scalos/libraries/iconobject/test.c | 45 + scalos/libraries/makefile | 47 + scalos/libraries/makefile-new | 40 + scalos/libraries/popupmenu/LICENSE | 3 + scalos/libraries/popupmenu/compiler.h | 22 + scalos/libraries/popupmenu/config.mk | 52 + scalos/libraries/popupmenu/iff.c | 225 + scalos/libraries/popupmenu/makefile | 132 + scalos/libraries/popupmenu/makefile-new | 90 + scalos/libraries/popupmenu/pm-aos4-68kstubs.c | 328 + scalos/libraries/popupmenu/pm.c | 1373 ++++ scalos/libraries/popupmenu/pmcreate.c | 294 + scalos/libraries/popupmenu/pmdlist.c | 115 + scalos/libraries/popupmenu/pmdlist.h | 41 + scalos/libraries/popupmenu/pmdrawshadow.c | 182 + scalos/libraries/popupmenu/pmfind.c | 294 + scalos/libraries/popupmenu/pmfind.h | 53 + scalos/libraries/popupmenu/pmgraph.c | 739 ++ scalos/libraries/popupmenu/pmgraph.h | 38 + scalos/libraries/popupmenu/pmimages.c | 144 + scalos/libraries/popupmenu/pmimages.h | 27 + scalos/libraries/popupmenu/pminit.c | 374 + scalos/libraries/popupmenu/pminput.c | 238 + scalos/libraries/popupmenu/pminput.h | 36 + scalos/libraries/popupmenu/pminternals.h | 65 + scalos/libraries/popupmenu/pmlayout.c | 504 ++ scalos/libraries/popupmenu/pmmem.c | 110 + scalos/libraries/popupmenu/pmmem.h | 28 + scalos/libraries/popupmenu/pmprefs.c | 177 + scalos/libraries/popupmenu/pmprefs.h | 75 + scalos/libraries/popupmenu/pmpriv.h | 557 ++ scalos/libraries/popupmenu/pmshadow.c | 271 + scalos/libraries/popupmenu/pmshadow.h | 78 + scalos/libraries/popupmenu/pmtags.c | 441 ++ scalos/libraries/popupmenu/pmtopography.c | 314 + scalos/libraries/popupmenu/pmtopography.h | 56 + scalos/libraries/popupmenu/pmtypes.h | 39 + scalos/libraries/popupmenu/pmversion.c | 34 + scalos/libraries/popupmenu/popupmenu-aos4.c | 445 ++ scalos/libraries/popupmenu/popupmenu-classic.c | 220 + scalos/libraries/popupmenu/popupmenu.h | 313 + scalos/libraries/popupmenu/window.c | 312 + .../preferences/Preferences-aos4-68kstubs.c | 220 + scalos/libraries/preferences/Preferences-aos4.c | 221 + scalos/libraries/preferences/Preferences-aros.c | 225 + scalos/libraries/preferences/Preferences-classic.c | 195 + scalos/libraries/preferences/Preferences.c | 1535 ++++ scalos/libraries/preferences/Preferences.h | 87 + scalos/libraries/preferences/Preferences_base.h | 48 + scalos/libraries/preferences/config.mk | 53 + scalos/libraries/preferences/makefile | 94 + scalos/libraries/preferences/makefile-new | 76 + scalos/libraries/scalosgfx/BitMapScale.c | 799 ++ scalos/libraries/scalosgfx/Dither.c | 1045 +++ scalos/libraries/scalosgfx/Render.c | 1542 ++++ scalos/libraries/scalosgfx/argb.c | 872 +++ scalos/libraries/scalosgfx/blit.c | 4762 +++++++++++ scalos/libraries/scalosgfx/config.mk | 51 + scalos/libraries/scalosgfx/makefile | 102 + scalos/libraries/scalosgfx/makefile-new | 79 + .../libraries/scalosgfx/scalosgfx-aos4-68kstubs.c | 416 + scalos/libraries/scalosgfx/scalosgfx-aos4.c | 422 + scalos/libraries/scalosgfx/scalosgfx-aros.c | 246 + scalos/libraries/scalosgfx/scalosgfx-classic.c | 210 + scalos/libraries/scalosgfx/scalosgfx.c | 921 +++ scalos/libraries/scalosgfx/scalosgfx.h | 458 ++ scalos/libraries/scalosgfx/scalosgfx_base.h | 31 + scalos/libraries/sqlite/LibSQLite3.c | 1932 +++++ scalos/libraries/sqlite/LibSQLite3.h | 502 ++ scalos/libraries/sqlite/Makefile | 8 + scalos/libraries/sqlite/VERSION | 1 + scalos/libraries/sqlite/config.mk | 81 + scalos/libraries/sqlite/keywordhash.h | 270 + scalos/libraries/sqlite/makefile-new | 162 + scalos/libraries/sqlite/opcodes.c | 159 + scalos/libraries/sqlite/opcodes.h | 185 + scalos/libraries/sqlite/parse.c | 3854 +++++++++ scalos/libraries/sqlite/parse.h | 157 + scalos/libraries/sqlite/sqlite3-aos4-68kstubs.c | 1034 +++ scalos/libraries/sqlite/sqlite3-aos4.c | 305 + scalos/libraries/sqlite/sqlite3-aros.c | 330 + scalos/libraries/sqlite/sqlite3-classic.c | 293 + scalos/libraries/sqlite/sqlite3.h | 6949 ++++++++++++++++ scalos/libraries/sqlite/sqlite3_base.h | 50 + scalos/libraries/sqlite/src/alter.c | 826 ++ scalos/libraries/sqlite/src/analyze.c | 1121 +++ scalos/libraries/sqlite/src/attach.c | 557 ++ scalos/libraries/sqlite/src/auth.c | 249 + scalos/libraries/sqlite/src/backup.c | 719 ++ scalos/libraries/sqlite/src/bitvec.c | 408 + scalos/libraries/sqlite/src/btmutex.c | 287 + scalos/libraries/sqlite/src/btree.c | 8277 ++++++++++++++++++++ scalos/libraries/sqlite/src/btree.h | 241 + scalos/libraries/sqlite/src/btreeInt.h | 652 ++ scalos/libraries/sqlite/src/build.c | 3822 +++++++++ scalos/libraries/sqlite/src/callback.c | 457 ++ scalos/libraries/sqlite/src/complete.c | 283 + scalos/libraries/sqlite/src/ctime.c | 399 + scalos/libraries/sqlite/src/date.c | 1128 +++ scalos/libraries/sqlite/src/delete.c | 651 ++ scalos/libraries/sqlite/src/expr.c | 4040 ++++++++++ scalos/libraries/sqlite/src/fault.c | 87 + scalos/libraries/sqlite/src/fkey.c | 1219 +++ scalos/libraries/sqlite/src/func.c | 1605 ++++ scalos/libraries/sqlite/src/global.c | 221 + scalos/libraries/sqlite/src/hash.c | 277 + scalos/libraries/sqlite/src/hash.h | 96 + scalos/libraries/sqlite/src/hwtime.h | 85 + scalos/libraries/sqlite/src/insert.c | 1842 +++++ scalos/libraries/sqlite/src/journal.c | 238 + scalos/libraries/sqlite/src/legacy.c | 145 + scalos/libraries/sqlite/src/lempar.c | 863 ++ scalos/libraries/sqlite/src/loadext.c | 658 ++ scalos/libraries/sqlite/src/main.c | 3070 ++++++++ scalos/libraries/sqlite/src/malloc.c | 778 ++ scalos/libraries/sqlite/src/mem0.c | 59 + scalos/libraries/sqlite/src/mem1.c | 247 + scalos/libraries/sqlite/src/mem2.c | 528 ++ scalos/libraries/sqlite/src/mem3.c | 687 ++ scalos/libraries/sqlite/src/mem5.c | 581 ++ scalos/libraries/sqlite/src/memjournal.c | 259 + scalos/libraries/sqlite/src/mutex.c | 153 + scalos/libraries/sqlite/src/mutex.h | 74 + scalos/libraries/sqlite/src/mutex_noop.c | 206 + scalos/libraries/sqlite/src/mutex_os2.c | 274 + scalos/libraries/sqlite/src/mutex_other.c | 324 + scalos/libraries/sqlite/src/mutex_unix.c | 351 + scalos/libraries/sqlite/src/mutex_w32.c | 332 + scalos/libraries/sqlite/src/notify.c | 332 + scalos/libraries/sqlite/src/os.c | 356 + scalos/libraries/sqlite/src/os.h | 289 + scalos/libraries/sqlite/src/os_common.h | 115 + scalos/libraries/sqlite/src/os_os2.c | 1924 +++++ scalos/libraries/sqlite/src/os_other.c | 2367 ++++++ scalos/libraries/sqlite/src/os_other.h | 42 + scalos/libraries/sqlite/src/os_unix.c | 6833 ++++++++++++++++ scalos/libraries/sqlite/src/os_win.c | 3697 +++++++++ scalos/libraries/sqlite/src/pager.c | 6897 ++++++++++++++++ scalos/libraries/sqlite/src/pager.h | 184 + scalos/libraries/sqlite/src/pcache.c | 619 ++ scalos/libraries/sqlite/src/pcache.h | 159 + scalos/libraries/sqlite/src/pcache1.c | 1019 +++ scalos/libraries/sqlite/src/pragma.c | 1542 ++++ scalos/libraries/sqlite/src/prepare.c | 862 ++ scalos/libraries/sqlite/src/printf.c | 970 +++ scalos/libraries/sqlite/src/random.c | 145 + scalos/libraries/sqlite/src/resolve.c | 1223 +++ scalos/libraries/sqlite/src/rowset.c | 422 + scalos/libraries/sqlite/src/select.c | 4598 +++++++++++ scalos/libraries/sqlite/src/sqlite3ext.h | 447 ++ scalos/libraries/sqlite/src/sqliteInt.h | 3294 ++++++++ scalos/libraries/sqlite/src/sqliteLimit.h | 208 + scalos/libraries/sqlite/src/status.c | 249 + scalos/libraries/sqlite/src/table.c | 197 + scalos/libraries/sqlite/src/tokenize.c | 526 ++ scalos/libraries/sqlite/src/trigger.c | 1124 +++ scalos/libraries/sqlite/src/update.c | 673 ++ scalos/libraries/sqlite/src/utf.c | 560 ++ scalos/libraries/sqlite/src/util.c | 1185 +++ scalos/libraries/sqlite/src/vacuum.c | 343 + scalos/libraries/sqlite/src/vdbe.c | 6172 +++++++++++++++ scalos/libraries/sqlite/src/vdbe.h | 235 + scalos/libraries/sqlite/src/vdbeInt.h | 474 ++ scalos/libraries/sqlite/src/vdbeapi.c | 1314 ++++ scalos/libraries/sqlite/src/vdbeaux.c | 3274 ++++++++ scalos/libraries/sqlite/src/vdbeblob.c | 469 ++ scalos/libraries/sqlite/src/vdbemem.c | 1147 +++ scalos/libraries/sqlite/src/vdbesort.c | 882 +++ scalos/libraries/sqlite/src/vdbetrace.c | 271 + scalos/libraries/sqlite/src/vtab.c | 1066 +++ scalos/libraries/sqlite/src/wal.c | 3071 ++++++++ scalos/libraries/sqlite/src/wal.h | 128 + scalos/libraries/sqlite/src/walker.c | 136 + scalos/libraries/sqlite/src/where.c | 5236 +++++++++++++ scalos/libraries/sqlite/tool/mkkeywordhash.c | 503 ++ scalos/libs/OS4/guigfx.library | Bin 0 -> 109276 bytes scalos/libs/OS4/render.library | Bin 0 -> 86860 bytes scalos/libs/guigfx.library | Bin 0 -> 42040 bytes scalos/libs/guigfx.library.elf | Bin 0 -> 89012 bytes scalos/libs/mcpgfx.library | Bin 0 -> 16044 bytes scalos/libs/render.library | Bin 0 -> 29848 bytes scalos/libs/render.library.elf | Bin 0 -> 59936 bytes scalos/main/AppMenu.c | 528 ++ scalos/main/AutoUpdate.c | 1803 +++++ scalos/main/BTree.c | 389 + scalos/main/BTree.h | 44 + scalos/main/BackFill.c | 338 + scalos/main/Backdrop.c | 1395 ++++ scalos/main/ButtonGadgetClass.c | 327 + scalos/main/CLIStart.c | 194 + scalos/main/ChildProcess.c | 309 + scalos/main/Class.c | 1276 +++ scalos/main/ControlBar.c | 1297 +++ scalos/main/CycleGadgetClass.c | 1645 ++++ scalos/main/CycleGadgetClass.h | 21 + scalos/main/DefIcons.c | 1319 ++++ scalos/main/DevListClass.c | 768 ++ scalos/main/DeviceWindowClass.c | 1829 +++++ scalos/main/DoubleClick.c | 1140 +++ scalos/main/DragDrop.c | 2323 ++++++ scalos/main/DragDropBobs.c | 3314 ++++++++ scalos/main/DrawIcon.c | 1080 +++ scalos/main/DropMarks.c | 547 ++ scalos/main/DtImageClass.c | 308 + scalos/main/DtImageClass.h | 19 + scalos/main/FileCommands.c | 2468 ++++++ scalos/main/FileTransClass.c | 2232 ++++++ scalos/main/FileTransClass.h | 86 + scalos/main/FontUtil.c | 752 ++ scalos/main/FrameImageClass.c | 963 +++ scalos/main/FrameImageClass.h | 19 + scalos/main/Functions.c | 1167 +++ scalos/main/GadgetBarClass.c | 1247 +++ scalos/main/GadgetBarImageClass.c | 473 ++ scalos/main/GadgetBarTextClass.c | 507 ++ scalos/main/GaugeGadgetClass.c | 397 + scalos/main/GaugeGadgetClass.h | 29 + scalos/main/HistoryGadgetClass.c | 1369 ++++ scalos/main/HistoryGadgetClass.h | 17 + scalos/main/IconImageClass.c | 275 + scalos/main/IconImageClass.h | 13 + scalos/main/IconWindowClass.c | 4874 ++++++++++++ scalos/main/IconWindow_MouseMove.c | 879 +++ scalos/main/IconifyClass.c | 223 + scalos/main/InputHandler.c | 395 + scalos/main/Lasso.c | 645 ++ scalos/main/LocaleStrings.c | 59 + scalos/main/MainWait.c | 652 ++ scalos/main/Memory.c | 635 ++ scalos/main/Menu.c | 1817 +++++ scalos/main/MenuCommand.c | 4838 ++++++++++++ scalos/main/Messages.c | 991 +++ scalos/main/MouseIcon.c | 143 + scalos/main/NoDebug | 3 + scalos/main/OpenDrawerByName.c | 198 + scalos/main/Patches-aos4.c | 392 + scalos/main/Patches-aros.c | 271 + scalos/main/Patches-classic.c | 283 + scalos/main/Patches.c | 2303 ++++++ scalos/main/Patches.h | 255 + scalos/main/Pattern.c | 1430 ++++ scalos/main/PenNames.h | 47 + scalos/main/PopOpenWindows.c | 211 + scalos/main/PopupMenus.c | 876 +++ scalos/main/Prefs.c | 2533 ++++++ scalos/main/Prefs.h | 274 + scalos/main/Rename.c | 188 + scalos/main/Request.c | 171 + scalos/main/RootClass.c | 771 ++ scalos/main/ScaLibrary-aos4.c | 426 + scalos/main/ScaLibrary-aros.c | 181 + scalos/main/ScaLibrary-classic.c | 201 + scalos/main/ScaLibrary.c | 2900 +++++++ scalos/main/ScaLibrary.h | 147 + scalos/main/Scalos.c | 1186 +++ scalos/main/Scalos.cd | 1325 ++++ scalos/main/Scalos.info | Bin 0 -> 2255 bytes scalos/main/ScalosInit.c | 1943 +++++ scalos/main/ScalosLocale.c | 126 + scalos/main/ScalosVersion.c | 34 + scalos/main/Scalos_Cx.c | 621 ++ scalos/main/Scalos_rev.h | 21 + scalos/main/ScanDir.c | 2585 ++++++ scalos/main/ScanDirText.c | 978 +++ scalos/main/Semaphores.c | 722 ++ scalos/main/Semaphores.h | 59 + scalos/main/SeparatorGadgetClass.c | 195 + scalos/main/Shortcuts.c | 561 ++ scalos/main/Splash.c | 1007 +++ scalos/main/StatusBar.c | 221 + scalos/main/StringGadgetClass.c | 406 + scalos/main/Subroutines.c | 582 ++ scalos/main/TTLayout.c | 1148 +++ scalos/main/TTLayout.h | 158 + scalos/main/Test/AddMoreMenus.c | 208 + scalos/main/Test/AppIcon | Bin 0 -> 10008 bytes scalos/main/Test/AppIcon.h | 126 + scalos/main/Test/ClockIcon.c | 283 + scalos/main/Test/SizeTest.c | 32 + scalos/main/Test/XADtest | Bin 0 -> 9368 bytes scalos/main/Test/XADtest.c | 84 + scalos/main/Test/icontest.c | 91 + scalos/main/Test/pens.c | 82 + scalos/main/Test/pngdt | Bin 0 -> 9716 bytes scalos/main/Test/pngdt.c | 204 + scalos/main/Test/putmsg.c | 30 + scalos/main/Test/putmsga.asm | 51 + scalos/main/Test/testwbargs.c | 44 + scalos/main/Test/wbmsgtester1.s | 119 + scalos/main/TextIconClass.c | 1282 +++ scalos/main/TextIconHighlightClass.c | 359 + scalos/main/TextIconHighlightClass.h | 19 + scalos/main/TextWindowClass.c | 2085 +++++ scalos/main/ThumbnailCache.c | 1394 ++++ scalos/main/Thumbnails.c | 1341 ++++ scalos/main/TitleClass.c | 1221 +++ scalos/main/ToolTip.c | 2636 +++++++ scalos/main/ToolTypes.c | 322 + scalos/main/Tools/CollectVersions | 432 + .../main/Tools/CreateTrashCan/CreateTrash.68k.info | Bin 0 -> 8314 bytes scalos/main/Tools/CreateTrashCan/CreateTrash.e | 296 + .../main/Tools/CreateTrashCan/CreateTrash.mos.info | Bin 0 -> 9104 bytes scalos/main/Tools/CreateTrashCan/VERSTAG.e | 8 + scalos/main/Tools/CreateTrashCan/makefile | 57 + scalos/main/Tools/CreateTrashCan/makefile-new | 57 + scalos/main/Tools/CreateTrashCan/mod.m | Bin 0 -> 2640 bytes scalos/main/Tools/GenMsgIdNames.c | 156 + scalos/main/Tools/How-To-sign | 11 + scalos/main/Tools/LoadWB.c | 267 + scalos/main/Tools/OpenDrawer/OpenDrawer.c | 155 + scalos/main/Tools/OpenDrawer/config.mk | 58 + scalos/main/Tools/OpenDrawer/makefile | 57 + scalos/main/Tools/OpenDrawer/makefile-new | 95 + scalos/main/Tools/OpenDrawer/opendrawer.68k.info | Bin 0 -> 10288 bytes scalos/main/Tools/OpenDrawer/opendrawer.mos.info | Bin 0 -> 8423 bytes scalos/main/Tools/Protect.MUI/GetIconObject.e | 59 + scalos/main/Tools/Protect.MUI/ProtModule.e | 80 + scalos/main/Tools/Protect.MUI/Protect.module.e | 810 ++ scalos/main/Tools/Protect.MUI/Scalos_Protect.cd | 204 + .../main/Tools/Protect.MUI/Scalos_Protect_Locale.e | 200 + scalos/main/Tools/Protect.MUI/VERSTAG.e | 9 + .../Fran\303\247ais/Scalos/Scalos_Protect.catalog" | Bin 0 -> 1732 bytes .../Fran\303\247ais/Scalos/Scalos_Protect.ct" | 209 + scalos/main/Tools/Protect.MUI/getpath.e | 24 + scalos/main/Tools/Protect.MUI/makefile | 86 + scalos/main/Tools/Protect.MUI/makefile-new | 86 + scalos/main/Tools/Scalos.pem | 33 + scalos/main/Tools/ScalosCtrl.c | 428 + scalos/main/Tools/ScalosPub.pem | 6 + scalos/main/Tools/ScalosSema.c | 348 + scalos/main/Tools/ScalosVersions | 86 + scalos/main/Tools/Scalos_Comment.info | Bin 0 -> 4185 bytes .../Fran\303\247ais/Scalos/Scalos_Comment.catalog" | Bin 0 -> 2244 bytes .../Fran\303\247ais/Scalos/Scalos_Comment.ct" | 305 + .../Tools/Scalos_Comment/Comment.module.68k.info | Bin 0 -> 10320 bytes scalos/main/Tools/Scalos_Comment/Comment.module.e | 1499 ++++ .../Tools/Scalos_Comment/Comment.module.mos.info | Bin 0 -> 9104 bytes scalos/main/Tools/Scalos_Comment/GetIconObject.e | 59 + scalos/main/Tools/Scalos_Comment/Scalos_Comment.cd | 297 + .../Tools/Scalos_Comment/Scalos_Comment_Locale.e | 241 + scalos/main/Tools/Scalos_Comment/VERSTAG.e | 8 + .../main/Tools/Scalos_Comment/comment.module.info | Bin 0 -> 1718 bytes scalos/main/Tools/Scalos_Comment/getpath.e | 25 + scalos/main/Tools/Scalos_Comment/makefile | 79 + scalos/main/Tools/Scalos_Comment/makefile-new | 79 + scalos/main/Tools/Scalos_GetHidden/GetHidden.cd | 128 + scalos/main/Tools/Scalos_GetHidden/GetHidden.e | 1337 ++++ scalos/main/Tools/Scalos_GetHidden/GetIconObject.e | 59 + scalos/main/Tools/Scalos_GetHidden/GetTCP.e | 239 + scalos/main/Tools/Scalos_GetHidden/MyDebugOnOff.e | 7 + scalos/main/Tools/Scalos_GetHidden/OnlineUpdate.e | 180 + .../Scalos_GetHidden/Scalos_GetHidden_Locale.e | 158 + scalos/main/Tools/Scalos_GetHidden/VERSTAGECX.e | 11 + .../catalogs/deutsch/scalos/GetHidden.ct | 157 + .../catalogs/deutsch/scalos/makefile | 13 + .../catalogs/fran\303\247ais/scalos/GetHidden.ct" | 128 + .../catalogs/fran\303\247ais/scalos/makefile" | 13 + .../main/Tools/Scalos_GetHidden/gethidden.68k.info | Bin 0 -> 4346 bytes .../main/Tools/Scalos_GetHidden/gethidden.mos.info | Bin 0 -> 8455 bytes scalos/main/Tools/Scalos_GetHidden/getpath.e | 25 + scalos/main/Tools/Scalos_GetHidden/makefile | 132 + scalos/main/Tools/Scalos_GetHidden/makefile-new | 131 + scalos/main/Tools/config.mk | 70 + scalos/main/Tools/makefile | 141 + scalos/main/Tools/makefile-new | 107 + scalos/main/Undo.c | 4732 +++++++++++ scalos/main/Variables.h | 277 + scalos/main/WBStartup.c | 396 + scalos/main/Window.c | 2584 ++++++ scalos/main/WindowClass.c | 1613 ++++ scalos/main/Wrappers.h | 52 + scalos/main/about.c | 1757 +++++ scalos/main/about.h | 77 + scalos/main/catalogs/Polski/Scalos/Scalos.ct | 1686 ++++ scalos/main/catalogs/Polski/Scalos/config.mk | 41 + scalos/main/catalogs/Polski/Scalos/makefile | 12 + scalos/main/catalogs/Polski/Scalos/makefile-new | 34 + scalos/main/catalogs/dansk/Scalos/Scalos.ct | 1489 ++++ scalos/main/catalogs/dansk/Scalos/config.mk | 41 + scalos/main/catalogs/dansk/Scalos/makefile | 12 + scalos/main/catalogs/dansk/Scalos/makefile-new | 34 + scalos/main/catalogs/deutsch/Scalos/Scalos.ct | 1710 ++++ scalos/main/catalogs/deutsch/Scalos/config.mk | 41 + scalos/main/catalogs/deutsch/Scalos/makefile | 12 + scalos/main/catalogs/deutsch/Scalos/makefile-new | 34 + .../main/catalogs/espa\303\261ol/Scalos/Scalos.ct" | 1488 ++++ .../main/catalogs/espa\303\261ol/Scalos/config.mk" | 41 + .../main/catalogs/espa\303\261ol/Scalos/makefile" | 12 + .../catalogs/espa\303\261ol/Scalos/makefile-new" | 34 + .../catalogs/fran\303\247ais/Scalos/Scalos.ct" | 1461 ++++ .../catalogs/fran\303\247ais/Scalos/config.mk" | 40 + .../main/catalogs/fran\303\247ais/Scalos/makefile" | 12 + .../catalogs/fran\303\247ais/Scalos/makefile-new" | 34 + scalos/main/catalogs/sample/Scalos/Scalos.ct | 1459 ++++ .../\303\203e\303\223tina/Scalos/Scalos.ct" | 1482 ++++ .../\303\203e\303\223tina/Scalos/config.mk" | 41 + .../\303\203e\303\223tina/Scalos/makefile" | 10 + .../\303\203e\303\223tina/Scalos/makefile-new" | 34 + scalos/main/cleanup.c | 1104 +++ scalos/main/config.mk | 96 + scalos/main/crc32.c | 99 + scalos/main/debug.h | 180 + scalos/main/docs/AutoDocs/SCA_DeviceList.doc | 68 + scalos/main/docs/AutoDocs/SCA_DeviceWindow.doc | 65 + scalos/main/docs/AutoDocs/SCA_FileTrans.doc | 468 ++ scalos/main/docs/AutoDocs/SCA_IconWindow.doc | 1523 ++++ scalos/main/docs/AutoDocs/SCA_Root.doc | 228 + scalos/main/docs/AutoDocs/SCA_TextWindow.doc | 115 + scalos/main/docs/AutoDocs/SCA_Title.doc | 154 + scalos/main/docs/AutoDocs/SCA_Window.doc | 327 + scalos/main/docs/AutoDocs/html/SCA_DeviceList.html | 72 + .../main/docs/AutoDocs/html/SCA_DeviceWindow.html | 8 + scalos/main/docs/AutoDocs/html/SCA_FileTrans.html | 8 + scalos/main/docs/AutoDocs/html/SCA_IconWindow.html | 11 + scalos/main/docs/AutoDocs/html/SCA_Root.html | 11 + scalos/main/docs/AutoDocs/html/SCA_TextWindow.html | 11 + scalos/main/docs/AutoDocs/html/SCA_Title.html | 11 + scalos/main/docs/AutoDocs/html/SCA_Window.html | 11 + scalos/main/docs/AutoDocs/html/iconobject.html | 243 + scalos/main/docs/AutoDocs/html/iconobject_dtc.html | 8 + scalos/main/docs/AutoDocs/html/preferences.html | 488 ++ scalos/main/docs/AutoDocs/html/scalos.html | 11 + scalos/main/docs/AutoDocs/html/scalosAPI.html | 11 + scalos/main/docs/AutoDocs/iconobject.doc | 224 + scalos/main/docs/AutoDocs/iconobject_dtc.doc | 279 + scalos/main/docs/AutoDocs/preferences.doc | 455 ++ scalos/main/docs/AutoDocs/scalos.doc | 1434 ++++ scalos/main/docs/AutoDocs/scalosAPI.doc | 826 ++ scalos/main/docs/AutoDocs/scalosgfx.doc | 910 +++ scalos/main/docs/FileTypes_plugins.guide | 94 + scalos/main/docs/Filetypes.guide | 666 ++ scalos/main/docs/Filetypes_Syntax.doc | 290 + scalos/main/docs/HUNGARO.TXT | 47 + scalos/main/docs/Icon datatype priority | 5 + scalos/main/docs/SOSBugs.txt | 141 + scalos/main/docs/SOSfeatures.txt | 148 + scalos/main/docs/Scalos_source_tree.txt | 76 + scalos/main/docs/Tooltip definition | 366 + scalos/main/dtimage.c | 801 ++ scalos/main/envarc/deficons.prefs | Bin 0 -> 3944 bytes .../main/envarc/scalos.68K/Deutsch/FileTypes/ILBM | 5 + .../envarc/scalos.68K/Deutsch/FileTypes/appicon | 16 + .../envarc/scalos.68K/Deutsch/FileTypes/archive | 50 + .../main/envarc/scalos.68K/Deutsch/FileTypes/avi | 6 + .../main/envarc/scalos.68K/Deutsch/FileTypes/brush | 5 + .../main/envarc/scalos.68K/Deutsch/FileTypes/disk | 130 + .../envarc/scalos.68K/Deutsch/FileTypes/drawer | 129 + .../scalos.68K/Deutsch/FileTypes/filearchive | 50 + .../main/envarc/scalos.68K/Deutsch/FileTypes/gif | 4 + .../main/envarc/scalos.68K/Deutsch/FileTypes/jpeg | 6 + .../main/envarc/scalos.68K/Deutsch/FileTypes/mpeg | 6 + .../envarc/scalos.68K/Deutsch/FileTypes/picture | 118 + .../main/envarc/scalos.68K/Deutsch/FileTypes/png | 6 + .../envarc/scalos.68K/Deutsch/FileTypes/project | 78 + .../envarc/scalos.68K/Deutsch/FileTypes/quicktime | 6 + .../main/envarc/scalos.68K/Deutsch/FileTypes/tool | 119 + .../envarc/scalos.68K/Deutsch/FileTypes/trashcan | 88 + .../main/envarc/scalos.68K/Deutsch/FileTypes/video | 6 + .../main/envarc/scalos.68K/Deutsch/FileTypes/wmv | 6 + scalos/main/envarc/scalos.68K/Deutsch/Menu13.prefs | Bin 0 -> 12044 bytes .../main/envarc/scalos.68K/English/FileTypes/ILBM | 5 + .../envarc/scalos.68K/English/FileTypes/appicon | 16 + .../envarc/scalos.68K/English/FileTypes/archive | 50 + .../main/envarc/scalos.68K/English/FileTypes/avi | 6 + .../main/envarc/scalos.68K/English/FileTypes/brush | 5 + .../main/envarc/scalos.68K/English/FileTypes/disk | 133 + .../envarc/scalos.68K/English/FileTypes/drawer | 129 + .../scalos.68K/English/FileTypes/filearchive | 50 + .../main/envarc/scalos.68K/English/FileTypes/gif | 5 + .../main/envarc/scalos.68K/English/FileTypes/jpeg | 6 + .../main/envarc/scalos.68K/English/FileTypes/mpeg | 6 + .../envarc/scalos.68K/English/FileTypes/picture | 118 + .../main/envarc/scalos.68K/English/FileTypes/png | 6 + .../envarc/scalos.68K/English/FileTypes/project | 78 + .../envarc/scalos.68K/English/FileTypes/quicktime | 6 + .../main/envarc/scalos.68K/English/FileTypes/tool | 119 + .../envarc/scalos.68K/English/FileTypes/trashcan | 88 + .../main/envarc/scalos.68K/English/FileTypes/video | 6 + .../main/envarc/scalos.68K/English/FileTypes/wmv | 6 + scalos/main/envarc/scalos.68K/English/Menu13.prefs | Bin 0 -> 11316 bytes .../scalos.68K/Fran\303\247ais/FileTypes/ILBM" | 5 + .../scalos.68K/Fran\303\247ais/FileTypes/appicon" | 16 + .../scalos.68K/Fran\303\247ais/FileTypes/archive" | 50 + .../scalos.68K/Fran\303\247ais/FileTypes/avi" | 6 + .../scalos.68K/Fran\303\247ais/FileTypes/brush" | 5 + .../scalos.68K/Fran\303\247ais/FileTypes/disk" | 126 + .../scalos.68K/Fran\303\247ais/FileTypes/drawer" | 129 + .../Fran\303\247ais/FileTypes/filearchive" | 50 + .../scalos.68K/Fran\303\247ais/FileTypes/gif" | 5 + .../scalos.68K/Fran\303\247ais/FileTypes/jpeg" | 6 + .../scalos.68K/Fran\303\247ais/FileTypes/mpeg" | 6 + .../scalos.68K/Fran\303\247ais/FileTypes/picture" | 118 + .../scalos.68K/Fran\303\247ais/FileTypes/png" | 6 + .../scalos.68K/Fran\303\247ais/FileTypes/project" | 78 + .../Fran\303\247ais/FileTypes/quicktime" | 6 + .../scalos.68K/Fran\303\247ais/FileTypes/tool" | 119 + .../scalos.68K/Fran\303\247ais/FileTypes/trashcan" | 103 + .../scalos.68K/Fran\303\247ais/FileTypes/video" | 6 + .../scalos.68K/Fran\303\247ais/FileTypes/wmv" | 6 + .../scalos.68K/Fran\303\247ais/Menu13.prefs" | Bin 0 -> 11610 bytes scalos/main/envarc/scalos.68K/Palette13.prefs | Bin 0 -> 288 bytes scalos/main/envarc/scalos.68K/Pattern.prefs | Bin 0 -> 10916 bytes scalos/main/envarc/scalos.68K/Persist.prefs | 35 + scalos/main/envarc/scalos.68K/icandy | 1 + scalos/main/envarc/scalos.68K/scalos.prefs | Bin 0 -> 1538 bytes .../main/envarc/scalos.AROS/Deutsch/FileTypes/ILBM | 5 + .../envarc/scalos.AROS/Deutsch/FileTypes/appicon | 16 + .../envarc/scalos.AROS/Deutsch/FileTypes/archive | 50 + .../main/envarc/scalos.AROS/Deutsch/FileTypes/avi | 6 + .../envarc/scalos.AROS/Deutsch/FileTypes/brush | 5 + .../main/envarc/scalos.AROS/Deutsch/FileTypes/disk | 130 + .../envarc/scalos.AROS/Deutsch/FileTypes/drawer | 129 + .../scalos.AROS/Deutsch/FileTypes/filearchive | 50 + .../main/envarc/scalos.AROS/Deutsch/FileTypes/gif | 4 + .../main/envarc/scalos.AROS/Deutsch/FileTypes/jpeg | 6 + .../main/envarc/scalos.AROS/Deutsch/FileTypes/mpeg | 6 + .../envarc/scalos.AROS/Deutsch/FileTypes/picture | 118 + .../main/envarc/scalos.AROS/Deutsch/FileTypes/png | 6 + .../envarc/scalos.AROS/Deutsch/FileTypes/project | 78 + .../envarc/scalos.AROS/Deutsch/FileTypes/quicktime | 6 + .../main/envarc/scalos.AROS/Deutsch/FileTypes/tool | 119 + .../envarc/scalos.AROS/Deutsch/FileTypes/trashcan | 88 + .../envarc/scalos.AROS/Deutsch/FileTypes/video | 6 + .../main/envarc/scalos.AROS/Deutsch/FileTypes/wmv | 6 + .../main/envarc/scalos.AROS/Deutsch/Menu13.prefs | Bin 0 -> 12000 bytes .../main/envarc/scalos.AROS/English/FileTypes/ILBM | 5 + .../envarc/scalos.AROS/English/FileTypes/appicon | 16 + .../envarc/scalos.AROS/English/FileTypes/archive | 50 + .../main/envarc/scalos.AROS/English/FileTypes/avi | 6 + .../envarc/scalos.AROS/English/FileTypes/brush | 5 + .../main/envarc/scalos.AROS/English/FileTypes/disk | 133 + .../envarc/scalos.AROS/English/FileTypes/drawer | 129 + .../scalos.AROS/English/FileTypes/filearchive | 50 + .../main/envarc/scalos.AROS/English/FileTypes/gif | 5 + .../main/envarc/scalos.AROS/English/FileTypes/jpeg | 6 + .../main/envarc/scalos.AROS/English/FileTypes/mpeg | 6 + .../envarc/scalos.AROS/English/FileTypes/picture | 118 + .../main/envarc/scalos.AROS/English/FileTypes/png | 6 + .../envarc/scalos.AROS/English/FileTypes/project | 78 + .../envarc/scalos.AROS/English/FileTypes/quicktime | 6 + .../main/envarc/scalos.AROS/English/FileTypes/tool | 119 + .../envarc/scalos.AROS/English/FileTypes/trashcan | 88 + .../envarc/scalos.AROS/English/FileTypes/video | 6 + .../main/envarc/scalos.AROS/English/FileTypes/wmv | 6 + .../main/envarc/scalos.AROS/English/Menu13.prefs | Bin 0 -> 11270 bytes .../scalos.AROS/Fran\303\247ais/FileTypes/ILBM" | 5 + .../scalos.AROS/Fran\303\247ais/FileTypes/appicon" | 16 + .../scalos.AROS/Fran\303\247ais/FileTypes/archive" | 50 + .../scalos.AROS/Fran\303\247ais/FileTypes/avi" | 6 + .../scalos.AROS/Fran\303\247ais/FileTypes/brush" | 5 + .../scalos.AROS/Fran\303\247ais/FileTypes/disk" | 126 + .../scalos.AROS/Fran\303\247ais/FileTypes/drawer" | 129 + .../Fran\303\247ais/FileTypes/filearchive" | 50 + .../scalos.AROS/Fran\303\247ais/FileTypes/gif" | 5 + .../scalos.AROS/Fran\303\247ais/FileTypes/jpeg" | 6 + .../scalos.AROS/Fran\303\247ais/FileTypes/mpeg" | 6 + .../scalos.AROS/Fran\303\247ais/FileTypes/picture" | 118 + .../scalos.AROS/Fran\303\247ais/FileTypes/png" | 6 + .../scalos.AROS/Fran\303\247ais/FileTypes/project" | 78 + .../Fran\303\247ais/FileTypes/quicktime" | 6 + .../scalos.AROS/Fran\303\247ais/FileTypes/tool" | 119 + .../Fran\303\247ais/FileTypes/trashcan" | 103 + .../scalos.AROS/Fran\303\247ais/FileTypes/video" | 6 + .../scalos.AROS/Fran\303\247ais/FileTypes/wmv" | 6 + .../scalos.AROS/Fran\303\247ais/Menu13.prefs" | Bin 0 -> 11604 bytes scalos/main/envarc/scalos.AROS/Palette13.prefs | Bin 0 -> 300 bytes scalos/main/envarc/scalos.AROS/Pattern.prefs | Bin 0 -> 10916 bytes scalos/main/envarc/scalos.AROS/Persist.prefs | 35 + scalos/main/envarc/scalos.AROS/icandy | 1 + scalos/main/envarc/scalos.AROS/scalos.prefs | Bin 0 -> 1538 bytes .../main/envarc/scalos.MOS/Deutsch/FileTypes/ILBM | 5 + .../envarc/scalos.MOS/Deutsch/FileTypes/appicon | 16 + .../envarc/scalos.MOS/Deutsch/FileTypes/archive | 50 + .../main/envarc/scalos.MOS/Deutsch/FileTypes/avi | 6 + .../main/envarc/scalos.MOS/Deutsch/FileTypes/brush | 5 + .../main/envarc/scalos.MOS/Deutsch/FileTypes/disk | 130 + .../envarc/scalos.MOS/Deutsch/FileTypes/drawer | 129 + .../scalos.MOS/Deutsch/FileTypes/filearchive | 50 + .../main/envarc/scalos.MOS/Deutsch/FileTypes/gif | 5 + .../main/envarc/scalos.MOS/Deutsch/FileTypes/jpeg | 6 + .../main/envarc/scalos.MOS/Deutsch/FileTypes/mpeg | 6 + .../envarc/scalos.MOS/Deutsch/FileTypes/picture | 118 + .../main/envarc/scalos.MOS/Deutsch/FileTypes/png | 6 + .../envarc/scalos.MOS/Deutsch/FileTypes/project | 78 + .../envarc/scalos.MOS/Deutsch/FileTypes/quicktime | 6 + .../main/envarc/scalos.MOS/Deutsch/FileTypes/tool | 119 + .../envarc/scalos.MOS/Deutsch/FileTypes/trashcan | 88 + .../main/envarc/scalos.MOS/Deutsch/FileTypes/video | 6 + .../main/envarc/scalos.MOS/Deutsch/FileTypes/wmv | 6 + scalos/main/envarc/scalos.MOS/Deutsch/Menu13.prefs | Bin 0 -> 12046 bytes .../main/envarc/scalos.MOS/English/FileTypes/ILBM | 5 + .../envarc/scalos.MOS/English/FileTypes/appicon | 16 + .../envarc/scalos.MOS/English/FileTypes/archive | 50 + .../main/envarc/scalos.MOS/English/FileTypes/avi | 6 + .../main/envarc/scalos.MOS/English/FileTypes/brush | 5 + .../main/envarc/scalos.MOS/English/FileTypes/disk | 133 + .../envarc/scalos.MOS/English/FileTypes/drawer | 129 + .../scalos.MOS/English/FileTypes/filearchive | 50 + .../main/envarc/scalos.MOS/English/FileTypes/gif | 5 + .../main/envarc/scalos.MOS/English/FileTypes/jpeg | 6 + .../main/envarc/scalos.MOS/English/FileTypes/mpeg | 6 + .../envarc/scalos.MOS/English/FileTypes/picture | 118 + .../main/envarc/scalos.MOS/English/FileTypes/png | 6 + .../envarc/scalos.MOS/English/FileTypes/project | 78 + .../envarc/scalos.MOS/English/FileTypes/quicktime | 6 + .../main/envarc/scalos.MOS/English/FileTypes/tool | 119 + .../envarc/scalos.MOS/English/FileTypes/trashcan | 88 + .../main/envarc/scalos.MOS/English/FileTypes/video | 6 + .../main/envarc/scalos.MOS/English/FileTypes/wmv | 6 + scalos/main/envarc/scalos.MOS/English/Menu13.prefs | Bin 0 -> 12946 bytes .../scalos.MOS/Fran\303\247ais/FileTypes/ILBM" | 5 + .../scalos.MOS/Fran\303\247ais/FileTypes/appicon" | 16 + .../scalos.MOS/Fran\303\247ais/FileTypes/archive" | 50 + .../scalos.MOS/Fran\303\247ais/FileTypes/avi" | 6 + .../scalos.MOS/Fran\303\247ais/FileTypes/brush" | 5 + .../scalos.MOS/Fran\303\247ais/FileTypes/disk" | 126 + .../scalos.MOS/Fran\303\247ais/FileTypes/drawer" | 129 + .../Fran\303\247ais/FileTypes/filearchive" | 50 + .../scalos.MOS/Fran\303\247ais/FileTypes/gif" | 5 + .../scalos.MOS/Fran\303\247ais/FileTypes/jpeg" | 6 + .../scalos.MOS/Fran\303\247ais/FileTypes/mpeg" | 6 + .../scalos.MOS/Fran\303\247ais/FileTypes/picture" | 118 + .../scalos.MOS/Fran\303\247ais/FileTypes/png" | 6 + .../scalos.MOS/Fran\303\247ais/FileTypes/project" | 78 + .../Fran\303\247ais/FileTypes/quicktime" | 6 + .../scalos.MOS/Fran\303\247ais/FileTypes/tool" | 119 + .../scalos.MOS/Fran\303\247ais/FileTypes/trashcan" | 103 + .../scalos.MOS/Fran\303\247ais/FileTypes/video" | 6 + .../scalos.MOS/Fran\303\247ais/FileTypes/wmv" | 6 + .../scalos.MOS/Fran\303\247ais/Menu13.prefs" | Bin 0 -> 12116 bytes scalos/main/envarc/scalos.MOS/Palette13.prefs | Bin 0 -> 288 bytes scalos/main/envarc/scalos.MOS/Pattern.prefs | Bin 0 -> 10940 bytes scalos/main/envarc/scalos.MOS/Persist.prefs | 34 + scalos/main/envarc/scalos.MOS/icandy | 1 + scalos/main/envarc/scalos.MOS/scalos.prefs | Bin 0 -> 1500 bytes .../main/envarc/scalos.OS4/Deutsch/FileTypes/ILBM | 5 + .../envarc/scalos.OS4/Deutsch/FileTypes/appicon | 16 + .../envarc/scalos.OS4/Deutsch/FileTypes/archive | 50 + .../main/envarc/scalos.OS4/Deutsch/FileTypes/avi | 6 + .../main/envarc/scalos.OS4/Deutsch/FileTypes/brush | 5 + .../main/envarc/scalos.OS4/Deutsch/FileTypes/disk | 130 + .../envarc/scalos.OS4/Deutsch/FileTypes/drawer | 129 + .../scalos.OS4/Deutsch/FileTypes/filearchive | 50 + .../main/envarc/scalos.OS4/Deutsch/FileTypes/gif | 5 + .../main/envarc/scalos.OS4/Deutsch/FileTypes/jpeg | 6 + .../main/envarc/scalos.OS4/Deutsch/FileTypes/mpeg | 6 + .../envarc/scalos.OS4/Deutsch/FileTypes/picture | 118 + .../main/envarc/scalos.OS4/Deutsch/FileTypes/png | 6 + .../envarc/scalos.OS4/Deutsch/FileTypes/project | 78 + .../envarc/scalos.OS4/Deutsch/FileTypes/quicktime | 6 + .../main/envarc/scalos.OS4/Deutsch/FileTypes/tool | 119 + .../envarc/scalos.OS4/Deutsch/FileTypes/trashcan | 88 + .../main/envarc/scalos.OS4/Deutsch/FileTypes/video | 6 + .../main/envarc/scalos.OS4/Deutsch/FileTypes/wmv | 6 + scalos/main/envarc/scalos.OS4/Deutsch/Menu13.prefs | Bin 0 -> 12046 bytes .../main/envarc/scalos.OS4/English/FileTypes/ILBM | 5 + .../envarc/scalos.OS4/English/FileTypes/appicon | 16 + .../envarc/scalos.OS4/English/FileTypes/archive | 50 + .../main/envarc/scalos.OS4/English/FileTypes/avi | 6 + .../main/envarc/scalos.OS4/English/FileTypes/brush | 5 + .../main/envarc/scalos.OS4/English/FileTypes/disk | 133 + .../envarc/scalos.OS4/English/FileTypes/drawer | 129 + .../scalos.OS4/English/FileTypes/filearchive | 50 + .../main/envarc/scalos.OS4/English/FileTypes/gif | 5 + .../main/envarc/scalos.OS4/English/FileTypes/jpeg | 6 + .../main/envarc/scalos.OS4/English/FileTypes/mpeg | 6 + .../envarc/scalos.OS4/English/FileTypes/picture | 118 + .../main/envarc/scalos.OS4/English/FileTypes/png | 6 + .../envarc/scalos.OS4/English/FileTypes/project | 78 + .../envarc/scalos.OS4/English/FileTypes/quicktime | 6 + .../main/envarc/scalos.OS4/English/FileTypes/tool | 119 + .../envarc/scalos.OS4/English/FileTypes/trashcan | 88 + .../main/envarc/scalos.OS4/English/FileTypes/video | 6 + .../main/envarc/scalos.OS4/English/FileTypes/wmv | 6 + scalos/main/envarc/scalos.OS4/English/Menu13.prefs | Bin 0 -> 11316 bytes .../scalos.OS4/Fran\303\247ais/FileTypes/ILBM" | 5 + .../scalos.OS4/Fran\303\247ais/FileTypes/appicon" | 16 + .../scalos.OS4/Fran\303\247ais/FileTypes/archive" | 50 + .../scalos.OS4/Fran\303\247ais/FileTypes/avi" | 6 + .../scalos.OS4/Fran\303\247ais/FileTypes/brush" | 5 + .../scalos.OS4/Fran\303\247ais/FileTypes/disk" | 126 + .../scalos.OS4/Fran\303\247ais/FileTypes/drawer" | 129 + .../Fran\303\247ais/FileTypes/filearchive" | 50 + .../scalos.OS4/Fran\303\247ais/FileTypes/gif" | 5 + .../scalos.OS4/Fran\303\247ais/FileTypes/jpeg" | 6 + .../scalos.OS4/Fran\303\247ais/FileTypes/mpeg" | 6 + .../scalos.OS4/Fran\303\247ais/FileTypes/picture" | 118 + .../scalos.OS4/Fran\303\247ais/FileTypes/png" | 6 + .../scalos.OS4/Fran\303\247ais/FileTypes/project" | 78 + .../Fran\303\247ais/FileTypes/quicktime" | 6 + .../scalos.OS4/Fran\303\247ais/FileTypes/tool" | 119 + .../scalos.OS4/Fran\303\247ais/FileTypes/trashcan" | 103 + .../scalos.OS4/Fran\303\247ais/FileTypes/video" | 6 + .../scalos.OS4/Fran\303\247ais/FileTypes/wmv" | 6 + .../scalos.OS4/Fran\303\247ais/Menu13.prefs" | Bin 0 -> 11610 bytes scalos/main/envarc/scalos.OS4/Palette13.prefs | Bin 0 -> 300 bytes scalos/main/envarc/scalos.OS4/Pattern.prefs | Bin 0 -> 10916 bytes scalos/main/envarc/scalos.OS4/Persist.prefs | 35 + scalos/main/envarc/scalos.OS4/icandy | 1 + scalos/main/envarc/scalos.OS4/scalos.prefs | Bin 0 -> 2234 bytes scalos/main/filetypes.c | 2667 +++++++ scalos/main/functions.h | 1118 +++ scalos/main/idcmp.c | 1817 +++++ scalos/main/locale.h | 22 + scalos/main/makefile | 393 + scalos/main/makefile-new | 218 + scalos/main/scalos-aos4-68kstubs.c | 570 ++ scalos/main/scalos_structures.h | 1548 ++++ scalos/main/std_includes/E/Examples/Bonus/sthex | Bin 0 -> 1840 bytes .../std_includes/E/Examples/Bonus/sthex.readme | 20 + scalos/main/std_includes/E/Examples/LoadExample.e | 55 + .../main/std_includes/E/Examples/LoadSaveExample.e | 62 + .../E/Examples/OneTag/ExampleOneTag.prefs | Bin 0 -> 682 bytes .../std_includes/E/Examples/OneTag/MakePrefsTag.e | 78 + .../std_includes/E/Examples/OneTag/ReadPrefsTag.e | 63 + .../E/Examples/TwoTags/ExampleTags.prefs | Bin 0 -> 610 bytes .../E/Examples/TwoTags/MakePrefsTags.e | 80 + .../E/Examples/TwoTags/ReadPrefsTags.e | 64 + scalos/main/std_includes/E/Examples/example.prefs | Bin 0 -> 234 bytes .../E/Extras/CommentMUI/Comment.module.e | 1465 ++++ .../E/Extras/CommentMUI/Scalos_Comment_Locale.e | 238 + .../std_includes/E/Extras/CommentMUI/commodule.m | Bin 0 -> 3318 bytes .../std_includes/E/Extras/CommentMUI/getpath.m | Bin 0 -> 758 bytes .../E/Extras/CommentMUI/scalos_comment_locale.m | Bin 0 -> 9050 bytes .../std_includes/E/Extras/CommentMUI/verstag.m | Bin 0 -> 394 bytes .../E/Extras/CreateTrash/CreateTrash.e | 301 + .../main/std_includes/E/Extras/CreateTrash/mod.m | Bin 0 -> 2640 bytes .../E/Extras/OpenDrawer/MOS/OpenDrawer_41.5_mos.e | 97 + .../std_includes/E/Extras/OpenDrawer/MOS/VERSTAG.e | 9 + .../std_includes/E/Extras/OpenDrawer/MOS/verstag.m | Bin 0 -> 402 bytes .../std_includes/E/Extras/OpenDrawer/OpenDrawer.e | 136 + .../std_includes/E/Extras/OpenDrawer/VERSTAG.e | 9 + .../std_includes/E/Extras/OpenDrawer/verstag.m | Bin 0 -> 354 bytes .../main/std_includes/E/modules/Scalos/gadgetbar.m | Bin 0 -> 2408 bytes .../std_includes/E/modules/Scalos/iconobject.m | Bin 0 -> 141 bytes scalos/main/std_includes/E/modules/Scalos/mcpgfx.m | Bin 0 -> 128 bytes scalos/main/std_includes/E/modules/Scalos/menu.m | Bin 0 -> 826 bytes .../E/modules/Scalos/preferences_struct.e | 150 + .../E/modules/Scalos/preferences_struct.m | Bin 0 -> 2916 bytes scalos/main/std_includes/E/modules/Scalos/scalos.e | 1881 +++++ scalos/main/std_includes/E/modules/Scalos/scalos.m | Bin 0 -> 28104 bytes .../std_includes/E/modules/Scalos/scalos.m.txt | 1114 +++ .../std_includes/E/modules/Scalos/scalos41.6.e | 1881 +++++ .../std_includes/E/modules/Scalos/scalos41.6.m | Bin 0 -> 28104 bytes .../E/modules/Scalos/scalosfiletypeplugin.m | Bin 0 -> 55 bytes .../E/modules/Scalos/scalosgfx_struct.m | Bin 0 -> 1930 bytes .../E/modules/Scalos/scalosmenuplugin.m | Bin 0 -> 46 bytes .../E/modules/Scalos/scalosmenuprefsplugin.e | 43 + .../E/modules/Scalos/scalosmenuprefsplugin.m | Bin 0 -> 478 bytes .../E/modules/Scalos/scalospatternprefsplugin.m | Bin 0 -> 440 bytes .../std_includes/E/modules/Scalos/scalosplugin.m | Bin 0 -> 41 bytes .../std_includes/E/modules/Scalos/scalosprefs.m | Bin 0 -> 1146 bytes .../E/modules/Scalos/scalosprefsplugin.e | 91 + .../E/modules/Scalos/scalosprefsplugin.m | Bin 0 -> 1334 bytes scalos/main/std_includes/E/modules/cybergraphics.m | Bin 0 -> 483 bytes scalos/main/std_includes/E/modules/guigfx.m | Bin 0 -> 482 bytes .../std_includes/E/modules/jmc/GetIconObject.e | 64 + .../main/std_includes/E/modules/jmc/MyDebugOnOff.e | 7 + .../std_includes/E/modules/jmc/geticonobject.m | Bin 0 -> 1086 bytes .../main/std_includes/E/modules/jmc/mydebugonoff.m | Bin 0 -> 62 bytes scalos/main/std_includes/E/modules/preferences.m | Bin 0 -> 203 bytes scalos/main/std_includes/E/modules/scalos.m | Bin 0 -> 654 bytes scalos/main/std_includes/E/modules/scalosgfx.m | Bin 0 -> 374 bytes scalos/main/std_includes/E/modules/sqlite3.m | Bin 0 -> 737 bytes .../std_includes/asm/CyberGraphX/cybergraphics.i | 189 + scalos/main/std_includes/asm/Scalos/iconobject.i | 479 ++ scalos/main/std_includes/asm/Scalos/palette.i | 66 + scalos/main/std_includes/asm/Scalos/pattern.i | 129 + scalos/main/std_includes/asm/Scalos/preferences.i | 155 + scalos/main/std_includes/asm/Scalos/scalos.i | 1600 ++++ scalos/main/std_includes/asm/Scalos/undo.i | 258 + scalos/main/std_includes/asm/asmsupp.i | 85 + .../main/std_includes/asm/datatypes/pictureclass.i | 259 + scalos/main/std_includes/asm/devices/printer.i | 305 + scalos/main/std_includes/asm/libraries/mcpgfx.i | 77 + .../main/std_includes/asm/libraries/mui_asmone.i | 3098 ++++++++ scalos/main/std_includes/asm/libraries/pm.i | 111 + .../main/std_includes/asm/lvo/cybergraphics_lib.i | 62 + scalos/main/std_includes/asm/lvo/dtlib_lib.i | 7 + scalos/main/std_includes/asm/lvo/guigfx_lib.i | 58 + scalos/main/std_includes/asm/lvo/iconobject_lib.i | 19 + scalos/main/std_includes/asm/lvo/mcpgfx_lib.i | 17 + scalos/main/std_includes/asm/lvo/newicon_lib.i | 23 + scalos/main/std_includes/asm/lvo/openurl_lib.i | 27 + scalos/main/std_includes/asm/lvo/pm_lib.i | 43 + scalos/main/std_includes/asm/lvo/preferences_lib.i | 25 + scalos/main/std_includes/asm/lvo/scalos_lib.i | 78 + .../asm/lvo/scalosfiletypeplugin_lib.i | 7 + scalos/main/std_includes/asm/lvo/scalosgfx_lib.i | 62 + .../std_includes/asm/lvo/scalosmenuplugin_lib.i | 7 + .../main/std_includes/asm/lvo/scalosplugin_lib.i | 8 + .../std_includes/asm/lvo/scalosprefsplugin_lib.i | 7 + .../std_includes/asm/lvo/scalospreviewplugin_lib.i | 7 + scalos/main/std_includes/asm/lvo/sqlite3_lib.i | 202 + scalos/main/std_includes/asm/mui/NList_mcc.i | 586 ++ scalos/main/std_includes/asm/mui/NListview_mcc.i | 59 + scalos/main/std_includes/asm/mui/listtree_mui.i | 352 + scalos/main/std_includes/asm/mui_asmone.i | 3098 ++++++++ scalos/main/std_includes/asm/workbench/workbench.i | 624 ++ scalos/main/std_includes/fd/cybergraphics_lib.fd | 34 + scalos/main/std_includes/fd/guigfx_lib.fd | 32 + scalos/main/std_includes/fd/iconobject_lib.fd | 11 + scalos/main/std_includes/fd/mcpgfx_lib.fd | 10 + scalos/main/std_includes/fd/openurl_lib.fd | 21 + scalos/main/std_includes/fd/pm_lib.fd | 27 + scalos/main/std_includes/fd/preferences_lib.fd | 14 + scalos/main/std_includes/fd/scalos_lib.fd | 43 + .../std_includes/fd/scalosfiletypeplugin_lib.fd | 5 + scalos/main/std_includes/fd/scalosgfx_lib.fd | 19 + .../main/std_includes/fd/scalosmenuplugin_lib.fd | 5 + scalos/main/std_includes/fd/scalosplugin_lib.fd | 5 + .../main/std_includes/fd/scalosprefsplugin_lib.fd | 5 + .../std_includes/fd/scalospreviewplugin_lib.fd | 5 + scalos/main/std_includes/fd/sqlite3_lib.fd | 91 + scalos/main/std_includes/interfaces/config.mk | 20 + .../main/std_includes/interfaces/cybergraphics.xml | 263 + scalos/main/std_includes/interfaces/guigfx.xml | 254 + scalos/main/std_includes/interfaces/iconobject.xml | 56 + scalos/main/std_includes/interfaces/makefile-new | 33 + scalos/main/std_includes/interfaces/pm.xml | 122 + .../main/std_includes/interfaces/preferences.xml | 68 + scalos/main/std_includes/interfaces/rules.mk | 60 + scalos/main/std_includes/interfaces/scalos.xml | 229 + .../interfaces/scalosfiletypeplugin.xml | 16 + scalos/main/std_includes/interfaces/scalosgfx.xml | 246 + .../std_includes/interfaces/scalosmenuplugin.xml | 16 + .../main/std_includes/interfaces/scalosplugin.xml | 13 + .../std_includes/interfaces/scalosprefsplugin.xml | 14 + .../interfaces/scalospreviewplugin.xml | 25 + scalos/main/std_includes/interfaces/sqlite3.xml | 438 ++ .../main/std_includes/sfd/FD/cybergraphics_lib.fd | 48 + scalos/main/std_includes/sfd/FD/dtlib_lib.fd | 5 + scalos/main/std_includes/sfd/FD/guigfx_lib.fd | 32 + scalos/main/std_includes/sfd/FD/iconobject_lib.fd | 11 + scalos/main/std_includes/sfd/FD/mcpgfx_lib.fd | 0 scalos/main/std_includes/sfd/FD/newicon_lib.fd | 0 scalos/main/std_includes/sfd/FD/openurl_lib.fd | 0 scalos/main/std_includes/sfd/FD/pm_lib.fd | 0 scalos/main/std_includes/sfd/FD/preferences_lib.fd | 0 scalos/main/std_includes/sfd/FD/scalos_lib.fd | 0 .../sfd/FD/scalosfiletypeplugin_lib.fd | 5 + scalos/main/std_includes/sfd/FD/scalosgfx_lib.fd | 33 + .../std_includes/sfd/FD/scalosmenuplugin_lib.fd | 5 + .../main/std_includes/sfd/FD/scalosplugin_lib.fd | 5 + .../std_includes/sfd/FD/scalosprefsplugin_lib.fd | 5 + .../std_includes/sfd/FD/scalospreviewplugin_lib.fd | 5 + scalos/main/std_includes/sfd/FD/sqlite3_lib.fd | 0 .../std_includes/sfd/LVO/cybergraphics_lib.asm | 61 + scalos/main/std_includes/sfd/LVO/dtlib_lib.asm | 7 + scalos/main/std_includes/sfd/LVO/guigfx_lib.asm | 57 + .../main/std_includes/sfd/LVO/iconobject_lib.asm | 19 + scalos/main/std_includes/sfd/LVO/mcpgfx_lib.asm | 3 + scalos/main/std_includes/sfd/LVO/newicon_lib.asm | 3 + scalos/main/std_includes/sfd/LVO/openurl_lib.asm | 3 + scalos/main/std_includes/sfd/LVO/pm_lib.asm | 3 + .../main/std_includes/sfd/LVO/preferences_lib.asm | 3 + scalos/main/std_includes/sfd/LVO/scalos_lib.asm | 3 + .../sfd/LVO/scalosfiletypeplugin_lib.asm | 7 + scalos/main/std_includes/sfd/LVO/scalosgfx_lib.asm | 61 + .../std_includes/sfd/LVO/scalosmenuplugin_lib.asm | 7 + .../main/std_includes/sfd/LVO/scalosplugin_lib.asm | 7 + .../std_includes/sfd/LVO/scalosprefsplugin_lib.asm | 7 + .../sfd/LVO/scalospreviewplugin_lib.asm | 7 + scalos/main/std_includes/sfd/LVO/sqlite3_lib.asm | 3 + .../sfd/PRAGMAS/cybergraphics_pragmas.h | 191 + .../main/std_includes/sfd/PRAGMAS/dtlib_pragmas.h | 37 + .../main/std_includes/sfd/PRAGMAS/guigfx_pragmas.h | 273 + .../std_includes/sfd/PRAGMAS/iconobject_pragmas.h | 87 + .../main/std_includes/sfd/PRAGMAS/mcpgfx_pragmas.h | 2 + .../std_includes/sfd/PRAGMAS/newicon_pragmas.h | 2 + .../std_includes/sfd/PRAGMAS/openurl_pragmas.h | 2 + scalos/main/std_includes/sfd/PRAGMAS/pm_pragmas.h | 2 + .../std_includes/sfd/PRAGMAS/preferences_pragmas.h | 2 + .../main/std_includes/sfd/PRAGMAS/scalos_pragmas.h | 2 + .../sfd/PRAGMAS/scalosfiletypeplugin_pragmas.h | 37 + .../std_includes/sfd/PRAGMAS/scalosgfx_pragmas.h | 175 + .../sfd/PRAGMAS/scalosmenuplugin_pragmas.h | 37 + .../sfd/PRAGMAS/scalosplugin_pragmas.h | 37 + .../sfd/PRAGMAS/scalosprefsplugin_pragmas.h | 37 + .../sfd/PRAGMAS/scalospreviewplugin_pragmas.h | 45 + .../std_includes/sfd/PRAGMAS/sqlite3_pragmas.h | 2 + .../std_includes/sfd/PROTOS/cybergraphics_protos.h | 63 + scalos/main/std_includes/sfd/PROTOS/dtlib_protos.h | 29 + .../main/std_includes/sfd/PROTOS/guigfx_protos.h | 71 + .../std_includes/sfd/PROTOS/iconobject_protos.h | 39 + .../main/std_includes/sfd/PROTOS/mcpgfx_protos.h | 2 + .../main/std_includes/sfd/PROTOS/newicon_protos.h | 2 + .../main/std_includes/sfd/PROTOS/openurl_protos.h | 2 + scalos/main/std_includes/sfd/PROTOS/pm_protos.h | 2 + .../std_includes/sfd/PROTOS/preferences_protos.h | 2 + .../main/std_includes/sfd/PROTOS/scalos_protos.h | 2 + .../sfd/PROTOS/scalosfiletypeplugin_protos.h | 26 + .../std_includes/sfd/PROTOS/scalosgfx_protos.h | 70 + .../sfd/PROTOS/scalosmenuplugin_protos.h | 26 + .../std_includes/sfd/PROTOS/scalosplugin_protos.h | 23 + .../sfd/PROTOS/scalosprefsplugin_protos.h | 23 + .../sfd/PROTOS/scalospreviewplugin_protos.h | 30 + .../main/std_includes/sfd/PROTOS/sqlite3_protos.h | 2 + scalos/main/std_includes/sfd/cybergraphics_lib.sfd | 91 + scalos/main/std_includes/sfd/dtlib_lib.sfd | 10 + scalos/main/std_includes/sfd/guigfx_lib.sfd | 79 + scalos/main/std_includes/sfd/iconobject_lib.sfd | 27 + .../sfd/include/inline4/cybergraphics.h | 98 + .../main/std_includes/sfd/include/inline4/guigfx.h | 153 + .../main/std_includes/sfd/include/inline4/scalos.h | 128 + .../std_includes/sfd/include/inline4/scalosgfx.h | 102 + .../sfd/include/inline4/scalosplugin.h | 28 + .../std_includes/sfd/include/inline4/sqlite3.h | 138 + .../sfd/include/interfaces/cybergraphics.h | 80 + .../std_includes/sfd/include/interfaces/guigfx.h | 91 + .../std_includes/sfd/include/interfaces/scalos.h | 87 + .../sfd/include/interfaces/scalosgfx.h | 77 + .../sfd/include/interfaces/scalosplugin.h | 45 + .../std_includes/sfd/include/interfaces/sqlite3.h | 133 + scalos/main/std_includes/sfd/makefile | 94 + scalos/main/std_includes/sfd/mcpgfx_lib.sfd | 29 + scalos/main/std_includes/sfd/newicon_lib.sfd | 18 + scalos/main/std_includes/sfd/openurl_lib.sfd | 31 + scalos/main/std_includes/sfd/pm_lib.sfd | 51 + scalos/main/std_includes/sfd/preferences_lib.sfd | 23 + scalos/main/std_includes/sfd/scalos_lib.sfd | 88 + .../std_includes/sfd/scalosfiletypeplugin_lib.sfd | 9 + scalos/main/std_includes/sfd/scalosgfx_lib.sfd | 82 + .../main/std_includes/sfd/scalosmenuplugin_lib.sfd | 9 + scalos/main/std_includes/sfd/scalosplugin_lib.sfd | 8 + .../std_includes/sfd/scalosprefsplugin_lib.sfd | 8 + .../std_includes/sfd/scalospreviewplugin_lib.sfd | 12 + scalos/main/std_includes/sfd/sqlite3_lib.sfd | 141 + scalos/main/wbl.c | 657 ++ scalos/main/windowtask.c | 679 ++ scalos/makefile | 47 + scalos/makefile-new | 33 + scalos/msgidnames.sd | 32 + scalos/readme.txt | 109 + scalos/rules.mk | 56 + scalos/tools/fixdeps | Bin 0 -> 10828 bytes scalos/translation | 179 + 2228 files changed, 639297 insertions(+) create mode 100755 scalos/BuildArchive create mode 100644 scalos/CatComp_h.sd create mode 100755 scalos/Default_Theme/About/Backfill create mode 100755 scalos/Default_Theme/About/ButtonFlushDisabled create mode 100755 scalos/Default_Theme/About/ButtonFlushNormal create mode 100755 scalos/Default_Theme/About/ButtonFlushSelected create mode 100755 scalos/Default_Theme/About/ButtonInfoDisabled create mode 100755 scalos/Default_Theme/About/ButtonInfoNormal create mode 100755 scalos/Default_Theme/About/ButtonInfoSelected create mode 100755 scalos/Default_Theme/About/ButtonOkDisabled create mode 100755 scalos/Default_Theme/About/ButtonOkNormal create mode 100755 scalos/Default_Theme/About/ButtonOkSelected create mode 100755 scalos/Default_Theme/About/ButtonRebootDisabled create mode 100755 scalos/Default_Theme/About/ButtonRebootNormal create mode 100755 scalos/Default_Theme/About/ButtonRebootSelected create mode 100755 scalos/Default_Theme/About/ButtonStopDisabled create mode 100755 scalos/Default_Theme/About/ButtonStopNormal create mode 100755 scalos/Default_Theme/About/ButtonStopSelected create mode 100755 scalos/Default_Theme/AboutBackground create mode 100755 scalos/Default_Theme/AboutBackground.info create mode 100755 scalos/Default_Theme/Desktop.info create mode 100755 scalos/Default_Theme/Desktop/Background create mode 100755 scalos/Default_Theme/FileTrans/Backfill create mode 100755 scalos/Default_Theme/FileTrans/ButtonCancelNormal create mode 100755 scalos/Default_Theme/FileTrans/ButtonCancelSelected create mode 100755 scalos/Default_Theme/FileTypes/Browse create mode 100755 scalos/Default_Theme/FileTypes/Close create mode 100755 scalos/Default_Theme/FileTypes/CreateThumbnail create mode 100755 scalos/Default_Theme/FileTypes/Delete create mode 100755 scalos/Default_Theme/FileTypes/Edit create mode 100755 scalos/Default_Theme/FileTypes/EditCopy create mode 100755 scalos/Default_Theme/FileTypes/EditCut create mode 100755 scalos/Default_Theme/FileTypes/EditPaste create mode 100755 scalos/Default_Theme/FileTypes/Find create mode 100755 scalos/Default_Theme/FileTypes/Information create mode 100755 scalos/Default_Theme/FileTypes/NewDir create mode 100755 scalos/Default_Theme/FileTypes/Open create mode 100755 scalos/Default_Theme/FileTypes/Properties create mode 100755 scalos/Default_Theme/FileTypes/Rename create mode 100755 scalos/Default_Theme/FileTypes/Update create mode 100755 scalos/Default_Theme/Icons/Overlay/LeftOut create mode 100755 scalos/Default_Theme/Icons/Overlay/ReadOnly create mode 100755 scalos/Default_Theme/Icons/Overlay/Thumbnail create mode 100755 scalos/Default_Theme/Menu.info create mode 100755 scalos/Default_Theme/Menu/DropMenu/Abort create mode 100755 scalos/Default_Theme/Menu/DropMenu/Copy create mode 100755 scalos/Default_Theme/Menu/DropMenu/Move create mode 100755 scalos/Default_Theme/Modules.info create mode 100755 scalos/Default_Theme/Modules/delete.module/delete create mode 100644 scalos/Default_Theme/Modules/delete.module/delete.info create mode 100755 scalos/Default_Theme/Modules/empty_trashcan.module/empty_trashcan create mode 100644 scalos/Default_Theme/Modules/empty_trashcan.module/empty_trashcan.info create mode 100755 scalos/Default_Theme/Modules/execute_command.module/execute_command create mode 100644 scalos/Default_Theme/Modules/execute_command.module/execute_command.info create mode 100644 scalos/Default_Theme/Modules/format_disk.module/format_disk create mode 100755 scalos/Default_Theme/Modules/iconproperties.module/iconproperties create mode 100644 scalos/Default_Theme/Modules/information.module/Information.info create mode 100755 scalos/Default_Theme/Modules/information.module/information create mode 100755 scalos/Default_Theme/Modules/newdrawer.module/Newdrawer create mode 100644 scalos/Default_Theme/Modules/newdrawer.module/newdrawer.info create mode 100755 scalos/Default_Theme/Modules/reboot.module/reboot create mode 100755 scalos/Default_Theme/Modules/rename.module/rename create mode 100644 scalos/Default_Theme/Modules/rename.module/rename.info create mode 100755 scalos/Default_Theme/Modules/systeminfo.module/SystemInfo create mode 100644 scalos/Default_Theme/Modules/systeminfo.module/Systeminfo.info create mode 100755 scalos/Default_Theme/Modules/windowproperties.module/windowproperties create mode 100755 scalos/Default_Theme/PointerIcons.info create mode 100644 scalos/Default_Theme/PointerIcons/copying.info create mode 100644 scalos/Default_Theme/PointerIcons/forbidden.info create mode 100644 scalos/Default_Theme/PointerIcons/makelink.info create mode 100755 scalos/Default_Theme/PointerIcons/moving.info create mode 100755 scalos/Default_Theme/Pointers.info create mode 100755 scalos/Default_Theme/Prefs/Modules/delete create mode 100755 scalos/Default_Theme/Prefs/Modules/empty_trashcan create mode 100755 scalos/Default_Theme/Prefs/Modules/execute_command create mode 100755 scalos/Default_Theme/Prefs/Modules/iconproperties create mode 100755 scalos/Default_Theme/Prefs/Modules/information create mode 100755 scalos/Default_Theme/Prefs/Modules/newdrawer create mode 100755 scalos/Default_Theme/Prefs/Modules/reboot create mode 100755 scalos/Default_Theme/Prefs/Modules/rename create mode 100755 scalos/Default_Theme/Prefs/Modules/systeminfo create mode 100755 scalos/Default_Theme/Prefs/Modules/windowproperties create mode 100755 scalos/Default_Theme/Prefs/Pages/about create mode 100755 scalos/Default_Theme/Prefs/Pages/desktop create mode 100755 scalos/Default_Theme/Prefs/Pages/dragndrop create mode 100755 scalos/Default_Theme/Prefs/Pages/filedisplay create mode 100755 scalos/Default_Theme/Prefs/Pages/icons create mode 100755 scalos/Default_Theme/Prefs/Pages/misc create mode 100755 scalos/Default_Theme/Prefs/Pages/modules create mode 100755 scalos/Default_Theme/Prefs/Pages/paths create mode 100755 scalos/Default_Theme/Prefs/Pages/plugins create mode 100755 scalos/Default_Theme/Prefs/Pages/startup create mode 100644 scalos/Default_Theme/Prefs/Pages/textwindows create mode 100755 scalos/Default_Theme/Prefs/Pages/truetypefonts create mode 100755 scalos/Default_Theme/Prefs/Pages/windows create mode 100755 scalos/Default_Theme/Prefs/Plugins/PopupMenu create mode 100755 scalos/Default_Theme/Prefs/Plugins/filetypes create mode 100755 scalos/Default_Theme/Prefs/Plugins/menu create mode 100755 scalos/Default_Theme/Prefs/Plugins/palette create mode 100755 scalos/Default_Theme/Prefs/Plugins/pattern create mode 100755 scalos/Default_Theme/Prefs/icon128 create mode 100755 scalos/Default_Theme/Prefs/icon16 create mode 100755 scalos/Default_Theme/Prefs/icon24 create mode 100755 scalos/Default_Theme/Prefs/icon32 create mode 100755 scalos/Default_Theme/Prefs/icon48 create mode 100755 scalos/Default_Theme/Prefs/icon64 create mode 100755 scalos/Default_Theme/Prefs/icon96 create mode 100755 scalos/Default_Theme/ScalosAboutLogo create mode 100755 scalos/Default_Theme/ScalosLogo create mode 100755 scalos/Default_Theme/ScalosSplashLogo create mode 100755 scalos/Default_Theme/Sound.info create mode 100755 scalos/Default_Theme/SplashBackground create mode 100755 scalos/Default_Theme/SplashBackground.info create mode 100755 scalos/Default_Theme/ToolTipBackground create mode 100755 scalos/Default_Theme/Window.info create mode 100755 scalos/Default_Theme/Window/Background create mode 100755 scalos/Default_Theme/Window/ControlBar/Background create mode 100644 scalos/Default_Theme/Window/ControlBar/BrowseDisabled create mode 100644 scalos/Default_Theme/Window/ControlBar/BrowseNormal create mode 100644 scalos/Default_Theme/Window/ControlBar/BrowseSelected create mode 100755 scalos/Default_Theme/Window/ControlBar/ButtonAboutDisabled create mode 100755 scalos/Default_Theme/Window/ControlBar/ButtonAboutNormal create mode 100755 scalos/Default_Theme/Window/ControlBar/ButtonAboutSelected create mode 100644 scalos/Default_Theme/Window/ControlBar/ButtonBackDisabled create mode 100755 scalos/Default_Theme/Window/ControlBar/ButtonBackNormal create mode 100755 scalos/Default_Theme/Window/ControlBar/ButtonBackSelected create mode 100644 scalos/Default_Theme/Window/ControlBar/ButtonForwardDisabled create mode 100755 scalos/Default_Theme/Window/ControlBar/ButtonForwardNormal create mode 100755 scalos/Default_Theme/Window/ControlBar/ButtonForwardSelected create mode 100755 scalos/Default_Theme/Window/ControlBar/ButtonInfoDisabled create mode 100755 scalos/Default_Theme/Window/ControlBar/ButtonInfoNormal create mode 100755 scalos/Default_Theme/Window/ControlBar/ButtonInfoSelected create mode 100755 scalos/Default_Theme/Window/ControlBar/ButtonPropertiesDisabled create mode 100755 scalos/Default_Theme/Window/ControlBar/ButtonPropertiesNormal create mode 100755 scalos/Default_Theme/Window/ControlBar/ButtonPropertiesSelected create mode 100644 scalos/Default_Theme/Window/ControlBar/ButtonUpDisabled create mode 100755 scalos/Default_Theme/Window/ControlBar/ButtonUpNormal create mode 100755 scalos/Default_Theme/Window/ControlBar/ButtonUpSelected create mode 100644 scalos/Default_Theme/Window/ControlBar/CycleBackground create mode 100755 scalos/Default_Theme/Window/ControlBar/CycleNormal create mode 100755 scalos/Default_Theme/Window/ControlBar/CyclePopupBackground create mode 100755 scalos/Default_Theme/Window/ControlBar/CycleSelected create mode 100644 scalos/Default_Theme/Window/ControlBar/HistoryNormal create mode 100755 scalos/Default_Theme/Window/ControlBar/HistoryPopupBackground create mode 100644 scalos/Default_Theme/Window/ControlBar/HistorySelected create mode 100755 scalos/Default_Theme/Window/ControlBar/ShowModeCycleFrame create mode 100755 scalos/Default_Theme/Window/ControlBar/ViewByCycleFrame create mode 100755 scalos/Default_Theme/Window/SortAscending create mode 100755 scalos/Default_Theme/Window/SortDescending create mode 100755 scalos/Default_Theme/Window/StatusBar.info create mode 100755 scalos/Default_Theme/Window/StatusBar/Background create mode 100755 scalos/Default_Theme/Window/StatusBar/PadLock create mode 100755 scalos/Default_Theme/Window/StatusBar/Reading create mode 100755 scalos/Default_Theme/Window/StatusBar/ShowAll create mode 100755 scalos/Default_Theme/Window/StatusBar/ThumbnailsAlways create mode 100755 scalos/Default_Theme/Window/StatusBar/ThumbnailsAsDefault create mode 100755 scalos/Default_Theme/Window/StatusBar/ThumbnailsGenerate create mode 100755 scalos/Default_Theme/Window/StatusBar/Typing create mode 100755 scalos/Default_Theme/Window/TextBackground create mode 100755 scalos/Default_Theme/Window/def_iconify.info create mode 100755 scalos/DevPack create mode 100644 scalos/ExcludeList create mode 100755 scalos/Extras/CreateDefaultIcon create mode 100755 scalos/Extras/CreateTrash create mode 100644 scalos/Extras/CreateTrash.68k create mode 100644 scalos/Extras/CreateTrash.68k.info create mode 100644 scalos/Extras/CreateTrash.info create mode 100644 scalos/Extras/CreateTrash.mos create mode 100644 scalos/Extras/CreateTrash.mos.info create mode 100755 scalos/Extras/DoCommand create mode 100755 scalos/Extras/NewIconUtil create mode 100755 scalos/Extras/OpenLocation_CA create mode 100755 scalos/Extras/OpenLocation_CA.info create mode 100644 scalos/Extras/OpenLocation_CA.readme create mode 100755 scalos/Extras/OpenLocation_CA.readme.info create mode 100755 scalos/Extras/OpenLocation_MUI create mode 100755 scalos/Extras/OpenLocation_MUI.info create mode 100755 scalos/Extras/OpenShell create mode 100755 scalos/Extras/PictIcon create mode 100644 scalos/Extras/Quit.rexx create mode 100644 "scalos/Extras/Scalos_Comment/Catalogs/Fran\303\247ais/Scalos/Scalos_Comment.catalog" create mode 100644 "scalos/Extras/Scalos_Comment/Catalogs/Fran\303\247ais/Scalos/Scalos_Comment.ct" create mode 100644 scalos/Extras/Scalos_Comment/Catalogs/Scalos_Comment.cd create mode 100644 scalos/Extras/Scalos_Comment/Comment.module.68k create mode 100644 scalos/Extras/Scalos_Comment/Comment.module.68k.info create mode 100644 scalos/Extras/Scalos_Comment/Comment.module.mos create mode 100644 scalos/Extras/Scalos_Comment/Comment.module.mos.info create mode 100644 scalos/Extras/Scalos_GetHidden/catalogs/GetHidden.cd create mode 100644 scalos/Extras/Scalos_GetHidden/catalogs/deutsch/scalos/GetHidden.ct create mode 100644 "scalos/Extras/Scalos_GetHidden/catalogs/fran\303\247ais/scalos/GetHidden.catalog" create mode 100644 "scalos/Extras/Scalos_GetHidden/catalogs/fran\303\247ais/scalos/GetHidden.ct" create mode 100644 scalos/Extras/Scalos_GetHidden/gethidden.68k create mode 100644 scalos/Extras/Scalos_GetHidden/gethidden.68k.info create mode 100644 scalos/Extras/Scalos_GetHidden/gethidden.mos create mode 100644 scalos/Extras/Scalos_GetHidden/gethidden.mos.info create mode 100755 scalos/Extras/browse.script create mode 100755 scalos/Extras/open_volume.rexx create mode 100644 scalos/Extras/opendrawer.68k create mode 100644 scalos/Extras/opendrawer.68k.info create mode 100644 scalos/Extras/opendrawer.mos create mode 100755 scalos/Extras/opendrawer_ppc create mode 100755 scalos/Extras/run.script create mode 100755 scalos/GPLsrc create mode 100644 scalos/History create mode 100644 scalos/InstallAROS/InstallAROS create mode 100644 scalos/InstallAROS/InstallAROS.info create mode 100755 scalos/Installer/GFX/MVGA.png create mode 100644 scalos/Installer/GFX/Pointericons.iff create mode 100644 scalos/Installer/GFX/SVGA.png create mode 100755 scalos/Installer/GFX/StatusBar.iff create mode 100755 scalos/Installer/GFX/VGA.png create mode 100755 scalos/Installer/GFX/def_Iconify.iff create mode 100755 scalos/Installer/Install3.5_ScalosBeta create mode 100755 scalos/Installer/Install3.5_ScalosBeta.info create mode 100755 scalos/Installer/Matrix_Copyright.txt create mode 100644 scalos/LEGAL create mode 100755 scalos/Modules/Delete.Gadtools/Copy_of_delete.c create mode 100755 scalos/Modules/Delete.Gadtools/Delete.c create mode 100755 scalos/Modules/Delete.Gadtools/makefile create mode 100755 scalos/Modules/Delete.MUI/COPYING create mode 100755 scalos/Modules/Delete.MUI/Release create mode 100644 scalos/Modules/Delete.MUI/Source.info create mode 100755 scalos/Modules/Delete.MUI/Source/Catalogs/deutsch/Scalos/Delete.ct create mode 100755 scalos/Modules/Delete.MUI/Source/Catalogs/deutsch/Scalos/config.mk create mode 100644 scalos/Modules/Delete.MUI/Source/Catalogs/deutsch/Scalos/makefile create mode 100644 scalos/Modules/Delete.MUI/Source/Catalogs/deutsch/Scalos/makefile-new create mode 100755 "scalos/Modules/Delete.MUI/Source/Catalogs/fran\303\247ais/Scalos/Delete.ct" create mode 100755 "scalos/Modules/Delete.MUI/Source/Catalogs/fran\303\247ais/Scalos/config.mk" create mode 100644 "scalos/Modules/Delete.MUI/Source/Catalogs/fran\303\247ais/Scalos/makefile" create mode 100644 "scalos/Modules/Delete.MUI/Source/Catalogs/fran\303\247ais/Scalos/makefile-new" create mode 100755 scalos/Modules/Delete.MUI/Source/Catalogs/sample/Scalos/Delete.ct create mode 100755 scalos/Modules/Delete.MUI/Source/Delete.cd create mode 100755 scalos/Modules/Delete.MUI/Source/Delete.module.c create mode 100755 scalos/Modules/Delete.MUI/Source/Delete.module.h create mode 100644 scalos/Modules/Delete.MUI/Source/Delete.module_files.c create mode 100755 scalos/Modules/Delete.MUI/Source/Delete.module_rev.h create mode 100644 scalos/Modules/Delete.MUI/Source/Delete.module_rev.log create mode 100755 scalos/Modules/Delete.MUI/Source/Delete.module_rev.rev create mode 100755 scalos/Modules/Delete.MUI/Source/Delete.module_strings.h create mode 100755 scalos/Modules/Delete.MUI/Source/config.mk create mode 100644 scalos/Modules/Delete.MUI/Source/makefile create mode 100755 scalos/Modules/Delete.MUI/Source/makefile-new create mode 100755 scalos/Modules/Delete.MUI/config.mk create mode 100644 scalos/Modules/Delete.MUI/makefile create mode 100755 scalos/Modules/Delete.MUI/makefile-new create mode 100755 scalos/Modules/Empty_Trashcan.Gadtools/Empty_Trashcan.c create mode 100644 scalos/Modules/Empty_Trashcan.Gadtools/debug.h create mode 100755 scalos/Modules/Empty_Trashcan.Gadtools/makefile create mode 100644 scalos/Modules/Empty_Trashcan.MUI/Catalogs/deutsch/Scalos/Empty_Trashcan.ct create mode 100755 scalos/Modules/Empty_Trashcan.MUI/Catalogs/deutsch/Scalos/config.mk create mode 100644 scalos/Modules/Empty_Trashcan.MUI/Catalogs/deutsch/Scalos/makefile create mode 100644 scalos/Modules/Empty_Trashcan.MUI/Catalogs/deutsch/Scalos/makefile-new create mode 100755 "scalos/Modules/Empty_Trashcan.MUI/Catalogs/fran\303\247ais/Scalos/Empty_Trashcan.ct" create mode 100755 "scalos/Modules/Empty_Trashcan.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" create mode 100644 "scalos/Modules/Empty_Trashcan.MUI/Catalogs/fran\303\247ais/Scalos/makefile" create mode 100644 "scalos/Modules/Empty_Trashcan.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" create mode 100644 scalos/Modules/Empty_Trashcan.MUI/Catalogs/sample/Scalos/Empty_Trashcan.ct create mode 100755 scalos/Modules/Empty_Trashcan.MUI/Empty_Trashcan.c create mode 100755 scalos/Modules/Empty_Trashcan.MUI/Empty_Trashcan.cd create mode 100644 scalos/Modules/Empty_Trashcan.MUI/Empty_Trashcan.h create mode 100755 scalos/Modules/Empty_Trashcan.MUI/config.mk create mode 100755 scalos/Modules/Empty_Trashcan.MUI/makefile create mode 100755 scalos/Modules/Empty_Trashcan.MUI/makefile-new create mode 100644 scalos/Modules/Exchange.MUI/Catalogs/deutsch/Scalos/Exchange.ct create mode 100755 scalos/Modules/Exchange.MUI/Catalogs/deutsch/Scalos/config.mk create mode 100644 scalos/Modules/Exchange.MUI/Catalogs/deutsch/Scalos/makefile create mode 100644 scalos/Modules/Exchange.MUI/Catalogs/deutsch/Scalos/makefile-new create mode 100755 "scalos/Modules/Exchange.MUI/Catalogs/fran\303\247ais/Scalos/Exchange.ct" create mode 100755 "scalos/Modules/Exchange.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" create mode 100644 "scalos/Modules/Exchange.MUI/Catalogs/fran\303\247ais/Scalos/makefile" create mode 100644 "scalos/Modules/Exchange.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" create mode 100644 scalos/Modules/Exchange.MUI/Catalogs/sample/Scalos/Exchange.ct create mode 100644 scalos/Modules/Exchange.MUI/Exchange.c create mode 100755 scalos/Modules/Exchange.MUI/Exchange.cd create mode 100644 scalos/Modules/Exchange.MUI/Exchange.h create mode 100755 scalos/Modules/Exchange.MUI/config.mk create mode 100644 scalos/Modules/Exchange.MUI/cx_private.h create mode 100644 scalos/Modules/Exchange.MUI/cx_private_ppcinline.h create mode 100644 scalos/Modules/Exchange.MUI/cx_private_pragmas.h create mode 100644 scalos/Modules/Exchange.MUI/cx_private_protos.h create mode 100644 scalos/Modules/Exchange.MUI/debug.h create mode 100644 scalos/Modules/Exchange.MUI/makefile create mode 100755 scalos/Modules/Exchange.MUI/makefile-new create mode 100755 scalos/Modules/Execute_Command.Gadtools/execute_command.c create mode 100755 scalos/Modules/Execute_Command.Gadtools/makefile create mode 100644 scalos/Modules/Execute_Command.MUI/Catalogs/deutsch/Scalos/Execute_Command.ct create mode 100755 scalos/Modules/Execute_Command.MUI/Catalogs/deutsch/Scalos/config.mk create mode 100644 scalos/Modules/Execute_Command.MUI/Catalogs/deutsch/Scalos/makefile create mode 100644 scalos/Modules/Execute_Command.MUI/Catalogs/deutsch/Scalos/makefile-new create mode 100755 "scalos/Modules/Execute_Command.MUI/Catalogs/fran\303\247ais/Scalos/Execute_Command.ct" create mode 100755 "scalos/Modules/Execute_Command.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" create mode 100644 "scalos/Modules/Execute_Command.MUI/Catalogs/fran\303\247ais/Scalos/makefile" create mode 100644 "scalos/Modules/Execute_Command.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" create mode 100644 scalos/Modules/Execute_Command.MUI/Catalogs/sample/Scalos/Execute_Command.ct create mode 100755 scalos/Modules/Execute_Command.MUI/Execute_Command.c create mode 100755 scalos/Modules/Execute_Command.MUI/Execute_Command.cd create mode 100755 scalos/Modules/Execute_Command.MUI/Execute_Command.h create mode 100755 scalos/Modules/Execute_Command.MUI/config.mk create mode 100755 scalos/Modules/Execute_Command.MUI/makefile create mode 100755 scalos/Modules/Execute_Command.MUI/makefile-new create mode 100644 scalos/Modules/Find.MUI/Catalogs/deutsch/Scalos/Find.ct create mode 100755 scalos/Modules/Find.MUI/Catalogs/deutsch/Scalos/config.mk create mode 100644 scalos/Modules/Find.MUI/Catalogs/deutsch/Scalos/makefile create mode 100644 scalos/Modules/Find.MUI/Catalogs/deutsch/Scalos/makefile-new create mode 100755 "scalos/Modules/Find.MUI/Catalogs/fran\303\247ais/Scalos/Find.ct" create mode 100755 "scalos/Modules/Find.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" create mode 100644 "scalos/Modules/Find.MUI/Catalogs/fran\303\247ais/Scalos/makefile" create mode 100644 "scalos/Modules/Find.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" create mode 100644 scalos/Modules/Find.MUI/Catalogs/sample/Scalos/Find.ct create mode 100644 scalos/Modules/Find.MUI/DefIcons.c create mode 100644 scalos/Modules/Find.MUI/Find.c create mode 100755 scalos/Modules/Find.MUI/Find.cd create mode 100644 scalos/Modules/Find.MUI/Find.h create mode 100755 scalos/Modules/Find.MUI/config.mk create mode 100644 scalos/Modules/Find.MUI/debug.h create mode 100644 scalos/Modules/Find.MUI/makefile create mode 100755 scalos/Modules/Find.MUI/makefile-new create mode 100644 "scalos/Modules/FormatDisk.Gadtools/Catalogs/Fran\303\247ais/Scalos/FormatDisk.ct" create mode 100755 "scalos/Modules/FormatDisk.Gadtools/Catalogs/Fran\303\247ais/Scalos/config.mk" create mode 100644 "scalos/Modules/FormatDisk.Gadtools/Catalogs/Fran\303\247ais/Scalos/makefile" create mode 100644 "scalos/Modules/FormatDisk.Gadtools/Catalogs/Fran\303\247ais/Scalos/makefile-new" create mode 100644 scalos/Modules/FormatDisk.Gadtools/Catalogs/deutsch/Scalos/FormatDisk.ct create mode 100755 scalos/Modules/FormatDisk.Gadtools/Catalogs/deutsch/Scalos/config.mk create mode 100644 scalos/Modules/FormatDisk.Gadtools/Catalogs/deutsch/Scalos/makefile create mode 100644 scalos/Modules/FormatDisk.Gadtools/Catalogs/deutsch/Scalos/makefile-new create mode 100644 scalos/Modules/FormatDisk.Gadtools/Catalogs/sample/Scalos/FormatDisk.ct create mode 100644 scalos/Modules/FormatDisk.Gadtools/Device_Handler.c create mode 100644 scalos/Modules/FormatDisk.Gadtools/Format.c create mode 100755 scalos/Modules/FormatDisk.Gadtools/Format.h create mode 100644 scalos/Modules/FormatDisk.Gadtools/FormatDisk.cd create mode 100644 scalos/Modules/FormatDisk.Gadtools/FormatVolume.c create mode 100644 scalos/Modules/FormatDisk.Gadtools/Format_disk_rev.h create mode 100755 scalos/Modules/FormatDisk.Gadtools/FullFormat.c create mode 100644 scalos/Modules/FormatDisk.Gadtools/GUI.c create mode 100755 scalos/Modules/FormatDisk.Gadtools/GUI.h create mode 100644 scalos/Modules/FormatDisk.Gadtools/GetInputFromWindow.c create mode 100755 scalos/Modules/FormatDisk.Gadtools/NSD_64bit.c create mode 100644 scalos/Modules/FormatDisk.Gadtools/NoDebug create mode 100755 scalos/Modules/FormatDisk.Gadtools/ParseArgs.c create mode 100755 scalos/Modules/FormatDisk.Gadtools/config.mk create mode 100755 scalos/Modules/FormatDisk.Gadtools/makefile create mode 100755 scalos/Modules/FormatDisk.Gadtools/makefile-new create mode 100644 scalos/Modules/FormatDisk.MUI/Catalogs/deutsch/Scalos/FormatDiskMUI.ct create mode 100755 scalos/Modules/FormatDisk.MUI/Catalogs/deutsch/Scalos/config.mk create mode 100644 scalos/Modules/FormatDisk.MUI/Catalogs/deutsch/Scalos/makefile create mode 100644 scalos/Modules/FormatDisk.MUI/Catalogs/deutsch/Scalos/makefile-new create mode 100755 "scalos/Modules/FormatDisk.MUI/Catalogs/fran\303\247ais/Scalos/FormatDiskMUI.ct" create mode 100755 "scalos/Modules/FormatDisk.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" create mode 100644 "scalos/Modules/FormatDisk.MUI/Catalogs/fran\303\247ais/Scalos/makefile" create mode 100644 "scalos/Modules/FormatDisk.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" create mode 100644 scalos/Modules/FormatDisk.MUI/Catalogs/sample/Scalos/FormatDisk.ct create mode 100755 scalos/Modules/FormatDisk.MUI/FormatDisk.c create mode 100755 scalos/Modules/FormatDisk.MUI/FormatDisk.h create mode 100755 scalos/Modules/FormatDisk.MUI/FormatDiskMUI.cd create mode 100755 scalos/Modules/FormatDisk.MUI/config.mk create mode 100755 scalos/Modules/FormatDisk.MUI/makefile create mode 100755 scalos/Modules/FormatDisk.MUI/makefile-new create mode 100644 scalos/Modules/IconProperties.MUI/Catalogs/deutsch/Scalos/IconProperties.ct create mode 100755 scalos/Modules/IconProperties.MUI/Catalogs/deutsch/Scalos/config.mk create mode 100644 scalos/Modules/IconProperties.MUI/Catalogs/deutsch/Scalos/makefile create mode 100644 scalos/Modules/IconProperties.MUI/Catalogs/deutsch/Scalos/makefile-new create mode 100755 "scalos/Modules/IconProperties.MUI/Catalogs/fran\303\247ais/Scalos/IconProperties.ct" create mode 100755 "scalos/Modules/IconProperties.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" create mode 100644 "scalos/Modules/IconProperties.MUI/Catalogs/fran\303\247ais/Scalos/makefile" create mode 100644 "scalos/Modules/IconProperties.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" create mode 100644 scalos/Modules/IconProperties.MUI/Catalogs/sample/Scalos/IconProperties.ct create mode 100644 scalos/Modules/IconProperties.MUI/IconProperties.c create mode 100755 scalos/Modules/IconProperties.MUI/IconProperties.cd create mode 100644 scalos/Modules/IconProperties.MUI/IconProperties.h create mode 100755 scalos/Modules/IconProperties.MUI/NoDebug create mode 100755 scalos/Modules/IconProperties.MUI/ToolTypes.c create mode 100755 scalos/Modules/IconProperties.MUI/ToolTypes.h create mode 100755 scalos/Modules/IconProperties.MUI/config.mk create mode 100644 scalos/Modules/IconProperties.MUI/debug.h create mode 100644 scalos/Modules/IconProperties.MUI/makefile create mode 100755 scalos/Modules/IconProperties.MUI/makefile-new create mode 100644 scalos/Modules/Information.MUI/Catalogs/deutsch/Scalos/Information.ct create mode 100755 scalos/Modules/Information.MUI/Catalogs/deutsch/Scalos/config.mk create mode 100644 scalos/Modules/Information.MUI/Catalogs/deutsch/Scalos/makefile create mode 100644 scalos/Modules/Information.MUI/Catalogs/deutsch/Scalos/makefile-new create mode 100755 "scalos/Modules/Information.MUI/Catalogs/fran\303\247ais/Scalos/Information.ct" create mode 100755 "scalos/Modules/Information.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" create mode 100644 "scalos/Modules/Information.MUI/Catalogs/fran\303\247ais/Scalos/makefile" create mode 100644 "scalos/Modules/Information.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" create mode 100644 scalos/Modules/Information.MUI/Catalogs/sample/Scalos/Information.ct create mode 100644 scalos/Modules/Information.MUI/Information.c create mode 100755 scalos/Modules/Information.MUI/Information.cd create mode 100755 scalos/Modules/Information.MUI/Information.h create mode 100755 scalos/Modules/Information.MUI/config.mk create mode 100644 scalos/Modules/Information.MUI/debug.h create mode 100644 scalos/Modules/Information.MUI/makefile create mode 100755 scalos/Modules/Information.MUI/makefile-new create mode 100755 scalos/Modules/NewDrawer.Gadtools/makefile create mode 100755 scalos/Modules/NewDrawer.Gadtools/newdrawer.c create mode 100644 scalos/Modules/NewDrawer.MUI/Catalogs/deutsch/Scalos/NewDrawer.ct create mode 100755 scalos/Modules/NewDrawer.MUI/Catalogs/deutsch/Scalos/config.mk create mode 100644 scalos/Modules/NewDrawer.MUI/Catalogs/deutsch/Scalos/makefile create mode 100644 scalos/Modules/NewDrawer.MUI/Catalogs/deutsch/Scalos/makefile-new create mode 100755 "scalos/Modules/NewDrawer.MUI/Catalogs/fran\303\247ais/Scalos/NewDrawer.ct" create mode 100755 "scalos/Modules/NewDrawer.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" create mode 100644 "scalos/Modules/NewDrawer.MUI/Catalogs/fran\303\247ais/Scalos/makefile" create mode 100644 "scalos/Modules/NewDrawer.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" create mode 100644 scalos/Modules/NewDrawer.MUI/Catalogs/sample/Scalos/NewDrawer.ct create mode 100755 scalos/Modules/NewDrawer.MUI/NewDrawer.c create mode 100755 scalos/Modules/NewDrawer.MUI/NewDrawer.cd create mode 100755 scalos/Modules/NewDrawer.MUI/NewDrawer.h create mode 100755 scalos/Modules/NewDrawer.MUI/config.mk create mode 100755 scalos/Modules/NewDrawer.MUI/makefile create mode 100755 scalos/Modules/NewDrawer.MUI/makefile-new create mode 100644 scalos/Modules/NewDrawer.Reaction/NDStrings.asm create mode 100644 scalos/Modules/NewDrawer.Reaction/NewDrawer.c create mode 100755 scalos/Modules/NewDrawer.Reaction/NewDrawerGUI.cd create mode 100755 scalos/Modules/NewDrawer.Reaction/NewDrawerGUI.h create mode 100755 scalos/Modules/NewDrawer.Reaction/NewDrawerGUI.res create mode 100644 scalos/Modules/NewDrawer.Reaction/makefile create mode 100755 scalos/Modules/Rename.Gadtools/Rename.c create mode 100755 scalos/Modules/Rename.Gadtools/makefile create mode 100644 scalos/Modules/Rename.MUI/Catalogs/deutsch/Scalos/Rename.ct create mode 100755 scalos/Modules/Rename.MUI/Catalogs/deutsch/Scalos/config.mk create mode 100644 scalos/Modules/Rename.MUI/Catalogs/deutsch/Scalos/makefile create mode 100644 scalos/Modules/Rename.MUI/Catalogs/deutsch/Scalos/makefile-new create mode 100755 "scalos/Modules/Rename.MUI/Catalogs/fran\303\247ais/Scalos/Rename.ct" create mode 100755 "scalos/Modules/Rename.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" create mode 100644 "scalos/Modules/Rename.MUI/Catalogs/fran\303\247ais/Scalos/makefile" create mode 100644 "scalos/Modules/Rename.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" create mode 100644 scalos/Modules/Rename.MUI/Catalogs/sample/Scalos/Rename.ct create mode 100755 scalos/Modules/Rename.MUI/Rename.c create mode 100755 scalos/Modules/Rename.MUI/Rename.cd create mode 100755 scalos/Modules/Rename.MUI/Rename.h create mode 100755 scalos/Modules/Rename.MUI/config.mk create mode 100755 scalos/Modules/Rename.MUI/makefile create mode 100755 scalos/Modules/Rename.MUI/makefile-new create mode 100644 scalos/Modules/Rename.Reaction/RENStrings.asm create mode 100644 scalos/Modules/Rename.Reaction/Rename.c create mode 100755 scalos/Modules/Rename.Reaction/RenameGUI.cd create mode 100755 scalos/Modules/Rename.Reaction/RenameGUI.h create mode 100755 scalos/Modules/Rename.Reaction/RenameGUI.res create mode 100755 scalos/Modules/Rename.Reaction/RenameStrings.h create mode 100755 scalos/Modules/Rename.Reaction/RenameStrings.i create mode 100644 scalos/Modules/Rename.Reaction/makefile create mode 100755 scalos/Modules/SCOPTIONS create mode 100644 scalos/Modules/Updater.MUI/Catalogs/deutsch/Scalos/Updater.ct create mode 100755 scalos/Modules/Updater.MUI/Catalogs/deutsch/Scalos/config.mk create mode 100644 scalos/Modules/Updater.MUI/Catalogs/deutsch/Scalos/makefile create mode 100644 scalos/Modules/Updater.MUI/Catalogs/deutsch/Scalos/makefile-new create mode 100755 "scalos/Modules/Updater.MUI/Catalogs/fran\303\247ais/Scalos/Updater.ct" create mode 100755 "scalos/Modules/Updater.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" create mode 100644 "scalos/Modules/Updater.MUI/Catalogs/fran\303\247ais/Scalos/makefile" create mode 100644 "scalos/Modules/Updater.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" create mode 100644 scalos/Modules/Updater.MUI/Catalogs/sample/Scalos/Updater.ct create mode 100644 scalos/Modules/Updater.MUI/Updater.c create mode 100755 scalos/Modules/Updater.MUI/Updater.cd create mode 100644 scalos/Modules/Updater.MUI/Updater.h create mode 100755 scalos/Modules/Updater.MUI/config.mk create mode 100644 scalos/Modules/Updater.MUI/debug.h create mode 100644 scalos/Modules/Updater.MUI/makefile create mode 100755 scalos/Modules/Updater.MUI/makefile-new create mode 100644 scalos/Modules/WindowProperties.MUI/Catalogs/deutsch/Scalos/WindowProperties.ct create mode 100755 scalos/Modules/WindowProperties.MUI/Catalogs/deutsch/Scalos/config.mk create mode 100644 scalos/Modules/WindowProperties.MUI/Catalogs/deutsch/Scalos/makefile create mode 100644 scalos/Modules/WindowProperties.MUI/Catalogs/deutsch/Scalos/makefile-new create mode 100755 "scalos/Modules/WindowProperties.MUI/Catalogs/fran\303\247ais/Scalos/WindowProperties.ct" create mode 100755 "scalos/Modules/WindowProperties.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" create mode 100644 "scalos/Modules/WindowProperties.MUI/Catalogs/fran\303\247ais/Scalos/makefile" create mode 100644 "scalos/Modules/WindowProperties.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" create mode 100644 scalos/Modules/WindowProperties.MUI/Catalogs/sample/Scalos/WindowProperties.ct create mode 100755 scalos/Modules/WindowProperties.MUI/NoDebug create mode 100644 scalos/Modules/WindowProperties.MUI/WindowProperties.c create mode 100755 scalos/Modules/WindowProperties.MUI/WindowProperties.cd create mode 100644 scalos/Modules/WindowProperties.MUI/WindowProperties.h create mode 100755 scalos/Modules/WindowProperties.MUI/config.mk create mode 100644 scalos/Modules/WindowProperties.MUI/debug.h create mode 100644 scalos/Modules/WindowProperties.MUI/makefile create mode 100755 scalos/Modules/WindowProperties.MUI/makefile-new create mode 100755 scalos/Modules/config.mk create mode 100644 scalos/Modules/makefile create mode 100755 scalos/Modules/makefile-new create mode 100644 scalos/Plugins/FileTypes/DrawerContents/Catalogs/deutsch/Scalos/DrawerContentsPlugin.ct create mode 100755 scalos/Plugins/FileTypes/DrawerContents/Catalogs/deutsch/Scalos/config.mk create mode 100644 scalos/Plugins/FileTypes/DrawerContents/Catalogs/deutsch/Scalos/makefile create mode 100755 scalos/Plugins/FileTypes/DrawerContents/Catalogs/deutsch/Scalos/makefile-new create mode 100755 "scalos/Plugins/FileTypes/DrawerContents/Catalogs/fran\303\247ais/Scalos/DrawerContentsPlugin.ct" create mode 100755 "scalos/Plugins/FileTypes/DrawerContents/Catalogs/fran\303\247ais/Scalos/config.mk" create mode 100644 "scalos/Plugins/FileTypes/DrawerContents/Catalogs/fran\303\247ais/Scalos/makefile" create mode 100755 "scalos/Plugins/FileTypes/DrawerContents/Catalogs/fran\303\247ais/Scalos/makefile-new" create mode 100644 scalos/Plugins/FileTypes/DrawerContents/Catalogs/sample/Scalos/DrawerContentsPlugin.ct create mode 100644 scalos/Plugins/FileTypes/DrawerContents/DrawerContents.c create mode 100644 scalos/Plugins/FileTypes/DrawerContents/DrawerContents.h create mode 100644 scalos/Plugins/FileTypes/DrawerContents/DrawerContentsPlugin.cd create mode 100644 scalos/Plugins/FileTypes/DrawerContents/DrawerContents_base.h create mode 100755 scalos/Plugins/FileTypes/DrawerContents/config.mk create mode 100644 scalos/Plugins/FileTypes/DrawerContents/makefile create mode 100755 scalos/Plugins/FileTypes/DrawerContents/makefile-new create mode 100644 scalos/Plugins/FileTypes/DrawerContents/plugin_data.h create mode 100644 scalos/Plugins/FileTypes/ExifPicture/Catalogs/deutsch/Scalos/ExifPicturePlugin.ct create mode 100755 scalos/Plugins/FileTypes/ExifPicture/Catalogs/deutsch/Scalos/config.mk create mode 100755 scalos/Plugins/FileTypes/ExifPicture/Catalogs/deutsch/Scalos/makefile create mode 100755 scalos/Plugins/FileTypes/ExifPicture/Catalogs/deutsch/Scalos/makefile-new create mode 100755 "scalos/Plugins/FileTypes/ExifPicture/Catalogs/fran\303\247ais/Scalos/ExifPicturePlugin.ct" create mode 100755 "scalos/Plugins/FileTypes/ExifPicture/Catalogs/fran\303\247ais/Scalos/config.mk" create mode 100755 "scalos/Plugins/FileTypes/ExifPicture/Catalogs/fran\303\247ais/Scalos/makefile" create mode 100755 "scalos/Plugins/FileTypes/ExifPicture/Catalogs/fran\303\247ais/Scalos/makefile-new" create mode 100755 scalos/Plugins/FileTypes/ExifPicture/Catalogs/sample/Scalos/ExifPicturePlugin.ct create mode 100755 scalos/Plugins/FileTypes/ExifPicture/ExPicDefs.h create mode 100755 scalos/Plugins/FileTypes/ExifPicture/ExifPicture.c create mode 100755 scalos/Plugins/FileTypes/ExifPicture/ExifPicture.h create mode 100755 scalos/Plugins/FileTypes/ExifPicture/ExifPicturePlugin.cd create mode 100755 scalos/Plugins/FileTypes/ExifPicture/ExifPicture_base.h create mode 100755 scalos/Plugins/FileTypes/ExifPicture/config.mk create mode 100755 scalos/Plugins/FileTypes/ExifPicture/makefile create mode 100755 scalos/Plugins/FileTypes/ExifPicture/makefile-new create mode 100644 scalos/Plugins/FileTypes/ExifPicture/plugin_data.h create mode 100644 scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/deutsch/Scalos/PictureDimensionsPlugin.ct create mode 100755 scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/deutsch/Scalos/config.mk create mode 100644 scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/deutsch/Scalos/makefile create mode 100755 scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/deutsch/Scalos/makefile-new create mode 100755 "scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/fran\303\247ais/Scalos/PictureDimensionsPlugin.ct" create mode 100755 "scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/fran\303\247ais/Scalos/config.mk" create mode 100644 "scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/fran\303\247ais/Scalos/makefile" create mode 100755 "scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/fran\303\247ais/Scalos/makefile-new" create mode 100644 scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/sample/Scalos/PictureDimensionsPlugin.ct create mode 100644 scalos/Plugins/FileTypes/Picture_Dimensions/PictureDimensions.c create mode 100644 scalos/Plugins/FileTypes/Picture_Dimensions/PictureDimensions.h create mode 100644 scalos/Plugins/FileTypes/Picture_Dimensions/PictureDimensionsPlugin.cd create mode 100755 scalos/Plugins/FileTypes/Picture_Dimensions/config.mk create mode 100644 scalos/Plugins/FileTypes/Picture_Dimensions/makefile create mode 100755 scalos/Plugins/FileTypes/Picture_Dimensions/makefile-new create mode 100644 scalos/Plugins/FileTypes/Picture_Dimensions/picturedimensions_base.h create mode 100644 scalos/Plugins/FileTypes/Picture_Dimensions/plugin_data.h create mode 100755 scalos/Plugins/FileTypes/config.mk create mode 100644 scalos/Plugins/FileTypes/makefile create mode 100755 scalos/Plugins/FileTypes/makefile-new create mode 100644 scalos/Plugins/Menu/Sorted_Cleanup/makefile create mode 100755 scalos/Plugins/Menu/Sorted_Cleanup/scalos_macros.i create mode 100755 scalos/Plugins/Menu/Sorted_Cleanup/sorted_cleanup.s create mode 100644 scalos/Plugins/Menu/makefile create mode 100755 scalos/Plugins/OOP/DeviceFilter/config.mk create mode 100644 scalos/Plugins/OOP/DeviceFilter/devicefilter.c create mode 100644 scalos/Plugins/OOP/DeviceFilter/devicefilter.h create mode 100755 scalos/Plugins/OOP/DeviceFilter/makefile create mode 100755 scalos/Plugins/OOP/DeviceFilter/makefile-new create mode 100644 scalos/Plugins/OOP/DeviceFilter/plugin_data.h create mode 100755 scalos/Plugins/OOP/TitleClock/config.mk create mode 100755 scalos/Plugins/OOP/TitleClock/libbase.h create mode 100755 scalos/Plugins/OOP/TitleClock/libfuncs.c create mode 100755 scalos/Plugins/OOP/TitleClock/libfuncs.h create mode 100755 scalos/Plugins/OOP/TitleClock/makefile create mode 100755 scalos/Plugins/OOP/TitleClock/makefile-new create mode 100644 scalos/Plugins/OOP/TitleClock/plugin_data.h create mode 100755 scalos/Plugins/OOP/TitleClock/prefs/cc_locale.h create mode 100755 scalos/Plugins/OOP/TitleClock/prefs/config.mk create mode 100755 scalos/Plugins/OOP/TitleClock/prefs/force create mode 100644 scalos/Plugins/OOP/TitleClock/prefs/force.c create mode 100755 scalos/Plugins/OOP/TitleClock/prefs/interface.c create mode 100755 scalos/Plugins/OOP/TitleClock/prefs/interface.h create mode 100755 scalos/Plugins/OOP/TitleClock/prefs/makefile create mode 100755 scalos/Plugins/OOP/TitleClock/prefs/makefile-new create mode 100644 scalos/Plugins/OOP/TitleClock/prefs/misc.c create mode 100644 scalos/Plugins/OOP/TitleClock/prefs/misc.h create mode 100755 scalos/Plugins/OOP/TitleClock/prefs/prefs_file.c create mode 100755 scalos/Plugins/OOP/TitleClock/prefs/prefs_file.h create mode 100644 scalos/Plugins/OOP/TitleClock/prefs/requesters.c create mode 100644 scalos/Plugins/OOP/TitleClock/prefs/requesters.h create mode 100644 scalos/Plugins/OOP/TitleClock/prefs/saveicon.c create mode 100644 scalos/Plugins/OOP/TitleClock/prefs/saveicon.h create mode 100644 scalos/Plugins/OOP/TitleClock/prefs/screen.c create mode 100644 scalos/Plugins/OOP/TitleClock/prefs/screen.h create mode 100644 scalos/Plugins/OOP/TitleClock/prefs/tcp_locale.c create mode 100644 scalos/Plugins/OOP/TitleClock/prefs/tcp_locale.h create mode 100644 scalos/Plugins/OOP/TitleClock/prefs/title_clock.cd create mode 100755 scalos/Plugins/OOP/TitleClock/prefs/title_clock.ct create mode 100755 scalos/Plugins/OOP/TitleClock/prefs/title_clock_prefs.c create mode 100644 scalos/Plugins/OOP/TitleClock/prefs/title_clock_prefs.h create mode 100755 scalos/Plugins/OOP/TitleClock/prefs/title_clock_prefs.info create mode 100755 scalos/Plugins/OOP/TitleClock/readme.1st create mode 100644 scalos/Plugins/OOP/XTWindows/AutoMsg.h create mode 100644 scalos/Plugins/OOP/XTWindows/XTWindows.c create mode 100644 scalos/Plugins/OOP/XTWindows/XTWindows.h create mode 100755 scalos/Plugins/OOP/XTWindows/config.mk create mode 100644 scalos/Plugins/OOP/XTWindows/makefile create mode 100755 scalos/Plugins/OOP/XTWindows/makefile-new create mode 100644 scalos/Plugins/OOP/XTWindows/plugin_data.h create mode 100644 scalos/Plugins/OOP/XTWindows/xtwindows.doc create mode 100755 scalos/Plugins/OOP/config.mk create mode 100644 scalos/Plugins/OOP/makefile create mode 100755 scalos/Plugins/OOP/makefile-new create mode 100755 scalos/Plugins/OOP/title_envvar/config.mk create mode 100755 scalos/Plugins/OOP/title_envvar/libfuncs.c create mode 100644 scalos/Plugins/OOP/title_envvar/makefile create mode 100755 scalos/Plugins/OOP/title_envvar/makefile-new create mode 100644 scalos/Plugins/OOP/title_envvar/plugin_data.h create mode 100755 scalos/Plugins/OOP/title_freepens/config.mk create mode 100755 scalos/Plugins/OOP/title_freepens/libfuncs.c create mode 100755 scalos/Plugins/OOP/title_freepens/makefile create mode 100755 scalos/Plugins/OOP/title_freepens/makefile-new create mode 100644 scalos/Plugins/OOP/title_freepens/plugin_data.h create mode 100644 scalos/Plugins/OOP/title_test/makefile create mode 100755 scalos/Plugins/OOP/title_test/scalos_macros.i create mode 100755 scalos/Plugins/OOP/title_test/title_test.s create mode 100644 scalos/Plugins/OOP/wb39_plugin/AppIcons.c create mode 100644 scalos/Plugins/OOP/wb39_plugin/AppWindow.c create mode 100644 scalos/Plugins/OOP/wb39_plugin/DefIcons.c create mode 100644 scalos/Plugins/OOP/wb39_plugin/NoDebug create mode 100644 scalos/Plugins/OOP/wb39_plugin/Scalos_Helper.c create mode 100644 scalos/Plugins/OOP/wb39_plugin/Scalos_Helper.h create mode 100644 scalos/Plugins/OOP/wb39_plugin/WorkbenchControl.c create mode 100755 scalos/Plugins/OOP/wb39_plugin/config.mk create mode 100644 scalos/Plugins/OOP/wb39_plugin/deficons_library.c create mode 100644 scalos/Plugins/OOP/wb39_plugin/deficons_plugin.asm create mode 100644 scalos/Plugins/OOP/wb39_plugin/makefile create mode 100755 scalos/Plugins/OOP/wb39_plugin/makefile-new create mode 100644 scalos/Plugins/OOP/wb39_plugin/persist/Persist.h create mode 100755 scalos/Plugins/OOP/wb39_plugin/persist/config.mk create mode 100644 scalos/Plugins/OOP/wb39_plugin/persist/makefile create mode 100755 scalos/Plugins/OOP/wb39_plugin/persist/makefile-new create mode 100644 scalos/Plugins/OOP/wb39_plugin/persist/persist.c create mode 100644 scalos/Plugins/OOP/wb39_plugin/persist/plugin_data.h create mode 100644 scalos/Plugins/OOP/wb39_plugin/plugin_data.h create mode 100644 scalos/Plugins/OOP/wb39_plugin/test.c create mode 100644 scalos/Plugins/OOP/wb39_plugin/volumegauge/VolumeGauge.c create mode 100755 scalos/Plugins/OOP/wb39_plugin/volumegauge/config.mk create mode 100644 scalos/Plugins/OOP/wb39_plugin/volumegauge/makefile create mode 100755 scalos/Plugins/OOP/wb39_plugin/volumegauge/makefile-new create mode 100644 scalos/Plugins/OOP/wb39_plugin/volumegauge/plugin_data.h create mode 100644 scalos/Plugins/OOP/wb39_plugin/volumegauge/vg_plugin.c create mode 100644 scalos/Plugins/OOP/wb39_plugin/volumegauge/volumegauge.h create mode 100644 scalos/Plugins/OOP/wb39_plugin/wb39.c create mode 100644 scalos/Plugins/OOP/wb39_plugin/wb39.h create mode 100644 scalos/Plugins/OOP/wb39_plugin/wb39proto.h create mode 100755 scalos/Plugins/OOP/wb39_plugin/wbrexx/MenuTest.rexx create mode 100644 scalos/Plugins/OOP/wb39_plugin/wbrexx/RexxCmd.c create mode 100644 scalos/Plugins/OOP/wb39_plugin/wbrexx/RexxGetAttrs.c create mode 100644 scalos/Plugins/OOP/wb39_plugin/wbrexx/RexxIcon.c create mode 100644 scalos/Plugins/OOP/wb39_plugin/wbrexx/WBRexx.c create mode 100644 scalos/Plugins/OOP/wb39_plugin/wbrexx/WBRexx.doc create mode 100644 scalos/Plugins/OOP/wb39_plugin/wbrexx/WBRexxMain.c create mode 100755 scalos/Plugins/OOP/wb39_plugin/wbrexx/config.mk create mode 100644 scalos/Plugins/OOP/wb39_plugin/wbrexx/makefile create mode 100755 scalos/Plugins/OOP/wb39_plugin/wbrexx/makefile-new create mode 100644 scalos/Plugins/OOP/wb39_plugin/wbrexx/plugin_data.h create mode 100755 scalos/Plugins/OOP/wb39_plugin/wbrexx/rxtest.rexx create mode 100755 scalos/Plugins/OOP/wb39_plugin/wbrexx/rxtest2.rexx create mode 100755 scalos/Plugins/OOP/wb39_plugin/wbrexx/rxtest3.rexx create mode 100755 scalos/Plugins/OOP/wb39_plugin/wbrexx/rxtest4.rexx create mode 100644 scalos/Plugins/OOP/wb39_plugin/wbrexx/wbrexx.h create mode 100644 scalos/Plugins/Prefs/FileTypes/DefIcons.c create mode 100644 scalos/Plugins/Prefs/FileTypes/DefIconsPrefs.c create mode 100644 scalos/Plugins/Prefs/FileTypes/DefaultDefIconsPrefs.c create mode 100644 scalos/Plugins/Prefs/FileTypes/FileTypesPrefs.c create mode 100644 scalos/Plugins/Prefs/FileTypes/FileTypesPrefs.h create mode 100644 scalos/Plugins/Prefs/FileTypes/FileTypesPrefsImage.h create mode 100644 scalos/Plugins/Prefs/FileTypes/FileTypesPrefs_proto.h create mode 100755 scalos/Plugins/Prefs/FileTypes/NoDebug create mode 100644 scalos/Plugins/Prefs/FileTypes/ReadFtPrefs.c create mode 100644 scalos/Plugins/Prefs/FileTypes/WriteFtPrefs.c create mode 100755 scalos/Plugins/Prefs/FileTypes/config.mk create mode 100644 scalos/Plugins/Prefs/FileTypes/debug.h create mode 100644 scalos/Plugins/Prefs/FileTypes/makefile create mode 100755 scalos/Plugins/Prefs/FileTypes/makefile-new create mode 100644 scalos/Plugins/Prefs/FileTypes/plugin_data.h create mode 100644 scalos/Plugins/Prefs/Menu/DefaultMenu.c create mode 100644 scalos/Plugins/Prefs/Menu/MenuPrefs.c create mode 100644 scalos/Plugins/Prefs/Menu/MenuPrefs.h create mode 100644 scalos/Plugins/Prefs/Menu/MenuPrefsImage.h create mode 100755 scalos/Plugins/Prefs/Menu/NoDebug create mode 100755 scalos/Plugins/Prefs/Menu/config.mk create mode 100644 scalos/Plugins/Prefs/Menu/makefile create mode 100755 scalos/Plugins/Prefs/Menu/makefile-new create mode 100644 scalos/Plugins/Prefs/Menu/plugin_data.h create mode 100755 scalos/Plugins/Prefs/Palette/NoDebug create mode 100644 scalos/Plugins/Prefs/Palette/PalettePrefs.c create mode 100644 scalos/Plugins/Prefs/Palette/PalettePrefs.h create mode 100644 scalos/Plugins/Prefs/Palette/PalettePrefsImage.h create mode 100755 scalos/Plugins/Prefs/Palette/config.mk create mode 100644 scalos/Plugins/Prefs/Palette/makefile create mode 100755 scalos/Plugins/Prefs/Palette/makefile-new create mode 100644 scalos/Plugins/Prefs/Palette/plugin_data.h create mode 100755 scalos/Plugins/Prefs/Pattern/DoLoadDT.c create mode 100755 scalos/Plugins/Prefs/Pattern/LoadDT.h create mode 100755 scalos/Plugins/Prefs/Pattern/NoDebug create mode 100644 scalos/Plugins/Prefs/Pattern/PatternPrefs.c create mode 100644 scalos/Plugins/Prefs/Pattern/PatternPrefs.h create mode 100644 scalos/Plugins/Prefs/Pattern/PatternPrefsImage.h create mode 100755 scalos/Plugins/Prefs/Pattern/config.mk create mode 100644 scalos/Plugins/Prefs/Pattern/debug.h create mode 100644 scalos/Plugins/Prefs/Pattern/makefile create mode 100755 scalos/Plugins/Prefs/Pattern/makefile-new create mode 100644 scalos/Plugins/Prefs/Pattern/plugin_data.h create mode 100644 scalos/Plugins/Prefs/Popupmenu/Catalogs/deutsch/Scalos/ScalosPopupMenu.ct create mode 100755 scalos/Plugins/Prefs/Popupmenu/Catalogs/deutsch/Scalos/config.mk create mode 100644 scalos/Plugins/Prefs/Popupmenu/Catalogs/deutsch/Scalos/makefile create mode 100755 scalos/Plugins/Prefs/Popupmenu/Catalogs/deutsch/Scalos/makefile-new create mode 100644 "scalos/Plugins/Prefs/Popupmenu/Catalogs/fran\303\247ais/Scalos/ScalosPopupMenu.ct" create mode 100755 "scalos/Plugins/Prefs/Popupmenu/Catalogs/fran\303\247ais/Scalos/config.mk" create mode 100644 "scalos/Plugins/Prefs/Popupmenu/Catalogs/fran\303\247ais/Scalos/makefile" create mode 100755 "scalos/Plugins/Prefs/Popupmenu/Catalogs/fran\303\247ais/Scalos/makefile-new" create mode 100644 scalos/Plugins/Prefs/Popupmenu/Catalogs/sample/Scalos/ScalosPopupMenu.ct create mode 100644 scalos/Plugins/Prefs/Popupmenu/FrameButtonMCC.c create mode 100644 scalos/Plugins/Prefs/Popupmenu/FrameButtonMCC.h create mode 100644 scalos/Plugins/Prefs/Popupmenu/PopupMenuPrefs.c create mode 100644 scalos/Plugins/Prefs/Popupmenu/PopupMenuPrefs.h create mode 100644 scalos/Plugins/Prefs/Popupmenu/PopupMenuPrefsImage.h create mode 100755 scalos/Plugins/Prefs/Popupmenu/ScalosPopupMenu.cd create mode 100755 scalos/Plugins/Prefs/Popupmenu/config.mk create mode 100755 scalos/Plugins/Prefs/Popupmenu/images/Horizontal create mode 100755 scalos/Plugins/Prefs/Popupmenu/images/Horizontal Space create mode 100755 scalos/Plugins/Prefs/Popupmenu/images/Horizontal Space.c create mode 100755 scalos/Plugins/Prefs/Popupmenu/images/Horizontal.c create mode 100755 scalos/Plugins/Prefs/Popupmenu/images/Intermediate Spacing create mode 100755 scalos/Plugins/Prefs/Popupmenu/images/Intermediate Spacing.c create mode 100755 scalos/Plugins/Prefs/Popupmenu/images/NewStyle.brush create mode 100755 scalos/Plugins/Prefs/Popupmenu/images/NewStyle.c create mode 100755 scalos/Plugins/Prefs/Popupmenu/images/OldStyle.brush create mode 100755 scalos/Plugins/Prefs/Popupmenu/images/OldStyle.c create mode 100755 scalos/Plugins/Prefs/Popupmenu/images/PopupMenu create mode 100755 scalos/Plugins/Prefs/Popupmenu/images/PopupMenu.c create mode 100755 scalos/Plugins/Prefs/Popupmenu/images/Text Displacement create mode 100755 scalos/Plugins/Prefs/Popupmenu/images/Text Displacement.c create mode 100755 scalos/Plugins/Prefs/Popupmenu/images/Vertical Offset create mode 100755 scalos/Plugins/Prefs/Popupmenu/images/Vertical Offset.c create mode 100755 scalos/Plugins/Prefs/Popupmenu/images/Vertical Space create mode 100755 scalos/Plugins/Prefs/Popupmenu/images/Vertical Space.c create mode 100644 scalos/Plugins/Prefs/Popupmenu/makefile create mode 100755 scalos/Plugins/Prefs/Popupmenu/makefile-new create mode 100644 scalos/Plugins/Prefs/Popupmenu/plugin_data.h create mode 100755 scalos/Plugins/Prefs/config.mk create mode 100644 scalos/Plugins/Prefs/makefile create mode 100755 scalos/Plugins/Prefs/makefile-new create mode 100755 scalos/Plugins/Preview/DefPicture/DefPicture.c create mode 100755 scalos/Plugins/Preview/DefPicture/DefPicture.h create mode 100755 scalos/Plugins/Preview/DefPicture/config.mk create mode 100755 scalos/Plugins/Preview/DefPicture/makefile create mode 100755 scalos/Plugins/Preview/DefPicture/makefile-new create mode 100644 scalos/Plugins/Preview/DefPicture/plugin_data.h create mode 100755 scalos/Plugins/Preview/JpegPicture/JpegPicture.c create mode 100755 scalos/Plugins/Preview/JpegPicture/JpegPicture.h create mode 100755 scalos/Plugins/Preview/JpegPicture/config.mk create mode 100755 scalos/Plugins/Preview/JpegPicture/makefile create mode 100755 scalos/Plugins/Preview/JpegPicture/makefile-new create mode 100644 scalos/Plugins/Preview/JpegPicture/plugin_data.h create mode 100755 scalos/Plugins/Preview/PNGPicture/PNGPicture.c create mode 100755 scalos/Plugins/Preview/PNGPicture/PNGPicture.h create mode 100755 scalos/Plugins/Preview/PNGPicture/config.mk create mode 100755 scalos/Plugins/Preview/PNGPicture/makefile create mode 100755 scalos/Plugins/Preview/PNGPicture/makefile-new create mode 100644 scalos/Plugins/Preview/PNGPicture/plugin_data.h create mode 100755 scalos/Plugins/Preview/Video/COPYING create mode 100755 scalos/Plugins/Preview/Video/Video.c create mode 100755 scalos/Plugins/Preview/Video/Video.h create mode 100644 scalos/Plugins/Preview/Video/compat_68k.c create mode 100644 scalos/Plugins/Preview/Video/compat_mos.c create mode 100644 scalos/Plugins/Preview/Video/compat_os4.c create mode 100755 scalos/Plugins/Preview/Video/config.mk create mode 100755 scalos/Plugins/Preview/Video/makefile create mode 100755 scalos/Plugins/Preview/Video/makefile-new create mode 100644 scalos/Plugins/Preview/Video/plugin_data.h create mode 100755 scalos/Plugins/Preview/config.mk create mode 100644 scalos/Plugins/Preview/makefile create mode 100755 scalos/Plugins/Preview/makefile-new create mode 100755 scalos/Plugins/config.mk create mode 100644 scalos/Plugins/makefile create mode 100755 scalos/Plugins/makefile-new create mode 100755 scalos/Prefs/FileTypes/Catalogs/deutsch/Scalos/ScalosFileTypes.ct create mode 100755 scalos/Prefs/FileTypes/Catalogs/deutsch/Scalos/config.mk create mode 100644 scalos/Prefs/FileTypes/Catalogs/deutsch/Scalos/makefile create mode 100644 scalos/Prefs/FileTypes/Catalogs/deutsch/Scalos/makefile-new create mode 100755 "scalos/Prefs/FileTypes/Catalogs/fran\303\247ais/Scalos/ScalosFileTypes.ct" create mode 100755 "scalos/Prefs/FileTypes/Catalogs/fran\303\247ais/Scalos/config.mk" create mode 100644 "scalos/Prefs/FileTypes/Catalogs/fran\303\247ais/Scalos/makefile" create mode 100644 "scalos/Prefs/FileTypes/Catalogs/fran\303\247ais/Scalos/makefile-new" create mode 100755 scalos/Prefs/FileTypes/Catalogs/sample/Scalos/ScalosFileTypes.ct create mode 100644 scalos/Prefs/FileTypes/FileTypes.c create mode 100755 scalos/Prefs/FileTypes/ScalosFileTypes.cd create mode 100755 scalos/Prefs/FileTypes/Scalos_FileTypes.info create mode 100755 scalos/Prefs/FileTypes/config.mk create mode 100644 scalos/Prefs/FileTypes/makefile create mode 100755 scalos/Prefs/FileTypes/makefile-new create mode 100644 scalos/Prefs/MainPrefs/Catalogs/deutsch/Scalos/Makefile create mode 100644 scalos/Prefs/MainPrefs/Catalogs/deutsch/Scalos/Scalos_Prefs.ct create mode 100755 scalos/Prefs/MainPrefs/Catalogs/deutsch/Scalos/config.mk create mode 100755 scalos/Prefs/MainPrefs/Catalogs/deutsch/Scalos/makefile-new create mode 100644 "scalos/Prefs/MainPrefs/Catalogs/fran\303\247ais/Scalos/Makefile" create mode 100755 "scalos/Prefs/MainPrefs/Catalogs/fran\303\247ais/Scalos/Scalos_Prefs.ct" create mode 100755 "scalos/Prefs/MainPrefs/Catalogs/fran\303\247ais/Scalos/config.mk" create mode 100755 "scalos/Prefs/MainPrefs/Catalogs/fran\303\247ais/Scalos/makefile-new" create mode 100644 scalos/Prefs/MainPrefs/Catalogs/sample/Scalos/Scalos_Prefs.ct create mode 100644 scalos/Prefs/MainPrefs/General.h create mode 100644 scalos/Prefs/MainPrefs/HiddenDevices.c create mode 100644 scalos/Prefs/MainPrefs/HiddenDevices.h create mode 100644 scalos/Prefs/MainPrefs/Hooks.c create mode 100644 scalos/Prefs/MainPrefs/Hooks.h create mode 100644 scalos/Prefs/MainPrefs/Images.c create mode 100644 scalos/Prefs/MainPrefs/Images.h create mode 100755 scalos/Prefs/MainPrefs/Images/FileTypesPrefs.brush create mode 100755 scalos/Prefs/MainPrefs/Images/FileTypesPrefs.c create mode 100755 scalos/Prefs/MainPrefs/Images/IconProperties.brush create mode 100755 scalos/Prefs/MainPrefs/Images/IconProperties.c create mode 100755 scalos/Prefs/MainPrefs/Images/Information.brush create mode 100755 scalos/Prefs/MainPrefs/Images/Information.c create mode 100755 scalos/Prefs/MainPrefs/Images/MenuPrefs.brush create mode 100755 scalos/Prefs/MainPrefs/Images/NewDrawer.brush create mode 100755 scalos/Prefs/MainPrefs/Images/NewDrawer.c create mode 100755 scalos/Prefs/MainPrefs/Images/Palette.brush create mode 100755 scalos/Prefs/MainPrefs/Images/Palette.c create mode 100755 scalos/Prefs/MainPrefs/Images/PatternPrefs.brush create mode 100755 scalos/Prefs/MainPrefs/Images/PatternPrefs.c create mode 100755 scalos/Prefs/MainPrefs/Images/Reboot.brush create mode 100755 scalos/Prefs/MainPrefs/Images/Reboot.c create mode 100755 scalos/Prefs/MainPrefs/Images/TrueTypeFonts.brush create mode 100755 scalos/Prefs/MainPrefs/Images/TrueTypeFonts.c create mode 100755 scalos/Prefs/MainPrefs/Images/WindowProperties.brush create mode 100755 scalos/Prefs/MainPrefs/Images/WindowProperties.c create mode 100755 scalos/Prefs/MainPrefs/Images/about.brush create mode 100755 scalos/Prefs/MainPrefs/Images/about.c create mode 100755 scalos/Prefs/MainPrefs/Images/delete.brush create mode 100755 scalos/Prefs/MainPrefs/Images/delete.c create mode 100755 scalos/Prefs/MainPrefs/Images/desktop.brush create mode 100755 scalos/Prefs/MainPrefs/Images/desktop.c create mode 100755 scalos/Prefs/MainPrefs/Images/dragndrop.brush create mode 100755 scalos/Prefs/MainPrefs/Images/dragndrop.c create mode 100755 scalos/Prefs/MainPrefs/Images/empty_trashcan.brush create mode 100755 scalos/Prefs/MainPrefs/Images/empty_trashcan.c create mode 100755 scalos/Prefs/MainPrefs/Images/execute_command.brush create mode 100755 scalos/Prefs/MainPrefs/Images/execute_command.c create mode 100755 scalos/Prefs/MainPrefs/Images/filedisplay.brush create mode 100755 scalos/Prefs/MainPrefs/Images/filedisplay.c create mode 100644 scalos/Prefs/MainPrefs/Images/format_disk.brush create mode 100755 scalos/Prefs/MainPrefs/Images/format_disk.c create mode 100755 scalos/Prefs/MainPrefs/Images/icon-128x128.iff create mode 100755 scalos/Prefs/MainPrefs/Images/icon-16x16.iff create mode 100755 scalos/Prefs/MainPrefs/Images/icon-24x24.iff create mode 100755 scalos/Prefs/MainPrefs/Images/icon-32x32.iff create mode 100755 scalos/Prefs/MainPrefs/Images/icon-48x48.iff create mode 100755 scalos/Prefs/MainPrefs/Images/icon-64x64.iff create mode 100755 scalos/Prefs/MainPrefs/Images/icon-96x96.iff create mode 100755 scalos/Prefs/MainPrefs/Images/icon128.c create mode 100755 scalos/Prefs/MainPrefs/Images/icon16.c create mode 100755 scalos/Prefs/MainPrefs/Images/icon24.c create mode 100755 scalos/Prefs/MainPrefs/Images/icon32.c create mode 100755 scalos/Prefs/MainPrefs/Images/icon48.c create mode 100755 scalos/Prefs/MainPrefs/Images/icon64.c create mode 100755 scalos/Prefs/MainPrefs/Images/icon96.c create mode 100755 scalos/Prefs/MainPrefs/Images/icons.brush create mode 100755 scalos/Prefs/MainPrefs/Images/icons.c create mode 100755 scalos/Prefs/MainPrefs/Images/img1 create mode 100755 scalos/Prefs/MainPrefs/Images/img2 create mode 100755 scalos/Prefs/MainPrefs/Images/img3 create mode 100755 scalos/Prefs/MainPrefs/Images/misc.brush create mode 100755 scalos/Prefs/MainPrefs/Images/misc.c create mode 100755 scalos/Prefs/MainPrefs/Images/modules.brush create mode 100755 scalos/Prefs/MainPrefs/Images/modules.c create mode 100755 scalos/Prefs/MainPrefs/Images/paths.brush create mode 100755 scalos/Prefs/MainPrefs/Images/paths.c create mode 100755 scalos/Prefs/MainPrefs/Images/plugins.brush create mode 100755 scalos/Prefs/MainPrefs/Images/plugins.c create mode 100755 scalos/Prefs/MainPrefs/Images/rename.brush create mode 100755 scalos/Prefs/MainPrefs/Images/rename.c create mode 100755 scalos/Prefs/MainPrefs/Images/startup.brush create mode 100755 scalos/Prefs/MainPrefs/Images/startup.c create mode 100755 scalos/Prefs/MainPrefs/Images/systeminfo.brush create mode 100755 scalos/Prefs/MainPrefs/Images/systeminfo.c create mode 100644 scalos/Prefs/MainPrefs/Images/textwindows.brush create mode 100755 scalos/Prefs/MainPrefs/Images/textwindows.c create mode 100755 scalos/Prefs/MainPrefs/Images/windows.brush create mode 100755 scalos/Prefs/MainPrefs/Images/windows.c create mode 100644 scalos/Prefs/MainPrefs/MCC_GFXListview.c create mode 100644 scalos/Prefs/MainPrefs/MCPFrame_mcc.h create mode 100755 scalos/Prefs/MainPrefs/Makefile create mode 100644 scalos/Prefs/MainPrefs/McpFrameMCC.c create mode 100644 scalos/Prefs/MainPrefs/McpFrameMCC.h create mode 100755 scalos/Prefs/MainPrefs/NoDebug create mode 100644 scalos/Prefs/MainPrefs/PrefsPlugins.c create mode 100644 scalos/Prefs/MainPrefs/PrefsPlugins.h create mode 100644 scalos/Prefs/MainPrefs/PrefsVersion.c create mode 100644 scalos/Prefs/MainPrefs/ReadWritePrefs.c create mode 100644 scalos/Prefs/MainPrefs/ReadWritePrefs.h create mode 100644 scalos/Prefs/MainPrefs/Scalos.c create mode 100644 scalos/Prefs/MainPrefs/ScalosPrefs.h create mode 100644 scalos/Prefs/MainPrefs/Scalos_Prefs.cd create mode 100755 scalos/Prefs/MainPrefs/Scalos_Prefs.info create mode 100644 scalos/Prefs/MainPrefs/SelectMarkSampleClass.c create mode 100644 scalos/Prefs/MainPrefs/SelectMarkSampleClass.h create mode 100644 scalos/Prefs/MainPrefs/UrlSubject.h create mode 100755 scalos/Prefs/MainPrefs/config.mk create mode 100755 scalos/Prefs/MainPrefs/locale.h create mode 100755 scalos/Prefs/MainPrefs/makefile-new create mode 100644 scalos/Prefs/Menu/Catalogs/dansk/Scalos/ScalosMenu.ct create mode 100755 scalos/Prefs/Menu/Catalogs/dansk/Scalos/config.mk create mode 100644 scalos/Prefs/Menu/Catalogs/dansk/Scalos/makefile create mode 100755 scalos/Prefs/Menu/Catalogs/dansk/Scalos/makefile-new create mode 100644 scalos/Prefs/Menu/Catalogs/deutsch/Scalos/ScalosMenu.ct create mode 100755 scalos/Prefs/Menu/Catalogs/deutsch/Scalos/config.mk create mode 100644 scalos/Prefs/Menu/Catalogs/deutsch/Scalos/makefile create mode 100755 scalos/Prefs/Menu/Catalogs/deutsch/Scalos/makefile-new create mode 100644 "scalos/Prefs/Menu/Catalogs/espa\303\261ol/scalos/ScalosMenu.ct" create mode 100755 "scalos/Prefs/Menu/Catalogs/espa\303\261ol/scalos/config.mk" create mode 100644 "scalos/Prefs/Menu/Catalogs/espa\303\261ol/scalos/makefile" create mode 100755 "scalos/Prefs/Menu/Catalogs/espa\303\261ol/scalos/makefile-new" create mode 100755 "scalos/Prefs/Menu/Catalogs/fran\303\247ais/Scalos/ScalosMenu.ct" create mode 100755 "scalos/Prefs/Menu/Catalogs/fran\303\247ais/Scalos/config.mk" create mode 100644 "scalos/Prefs/Menu/Catalogs/fran\303\247ais/Scalos/makefile" create mode 100755 "scalos/Prefs/Menu/Catalogs/fran\303\247ais/Scalos/makefile-new" create mode 100644 scalos/Prefs/Menu/Catalogs/italiano/Scalos/ScalosMenu.ct create mode 100755 scalos/Prefs/Menu/Catalogs/italiano/Scalos/config.mk create mode 100644 scalos/Prefs/Menu/Catalogs/italiano/Scalos/makefile create mode 100755 scalos/Prefs/Menu/Catalogs/italiano/Scalos/makefile-new create mode 100644 scalos/Prefs/Menu/Catalogs/sample/Scalos/ScalosMenu.ct create mode 100644 scalos/Prefs/Menu/Catalogs/svenska/Scalos/ScalosMenu.ct create mode 100755 scalos/Prefs/Menu/Catalogs/svenska/Scalos/config.mk create mode 100644 scalos/Prefs/Menu/Catalogs/svenska/Scalos/makefile create mode 100755 scalos/Prefs/Menu/Catalogs/svenska/Scalos/makefile-new create mode 100644 "scalos/Prefs/Menu/Catalogs/\303\203e\303\223tina/Scalos/ScalosMenu.ct" create mode 100755 "scalos/Prefs/Menu/Catalogs/\303\203e\303\223tina/Scalos/config.mk" create mode 100644 "scalos/Prefs/Menu/Catalogs/\303\203e\303\223tina/Scalos/makefile" create mode 100755 "scalos/Prefs/Menu/Catalogs/\303\203e\303\223tina/Scalos/makefile-new" create mode 100644 scalos/Prefs/Menu/Menu.c create mode 100755 scalos/Prefs/Menu/ParM.cfg create mode 100755 scalos/Prefs/Menu/ScalosMenu.cd create mode 100755 scalos/Prefs/Menu/Scalos_Menu.info create mode 100755 scalos/Prefs/Menu/ToolsDaemon.menu create mode 100755 scalos/Prefs/Menu/config.mk create mode 100644 scalos/Prefs/Menu/makefile create mode 100755 scalos/Prefs/Menu/makefile-new create mode 100644 scalos/Prefs/Palette/Catalogs/dansk/Scalos/ScalosPalette.ct create mode 100755 scalos/Prefs/Palette/Catalogs/dansk/Scalos/config.mk create mode 100644 scalos/Prefs/Palette/Catalogs/dansk/Scalos/makefile create mode 100755 scalos/Prefs/Palette/Catalogs/dansk/Scalos/makefile-new create mode 100644 scalos/Prefs/Palette/Catalogs/deutsch/Scalos/ScalosPalette.ct create mode 100755 scalos/Prefs/Palette/Catalogs/deutsch/Scalos/config.mk create mode 100644 scalos/Prefs/Palette/Catalogs/deutsch/Scalos/makefile create mode 100755 scalos/Prefs/Palette/Catalogs/deutsch/Scalos/makefile-new create mode 100644 "scalos/Prefs/Palette/Catalogs/espa\303\261ol/scalos/ScalosPalette.ct" create mode 100755 "scalos/Prefs/Palette/Catalogs/espa\303\261ol/scalos/config.mk" create mode 100644 "scalos/Prefs/Palette/Catalogs/espa\303\261ol/scalos/makefile" create mode 100755 "scalos/Prefs/Palette/Catalogs/espa\303\261ol/scalos/makefile-new" create mode 100755 "scalos/Prefs/Palette/Catalogs/fran\303\247ais/Scalos/ScalosPalette.ct" create mode 100755 "scalos/Prefs/Palette/Catalogs/fran\303\247ais/Scalos/config.mk" create mode 100644 "scalos/Prefs/Palette/Catalogs/fran\303\247ais/Scalos/makefile" create mode 100755 "scalos/Prefs/Palette/Catalogs/fran\303\247ais/Scalos/makefile-new" create mode 100644 scalos/Prefs/Palette/Catalogs/italiano/Scalos/ScalosPalette.ct create mode 100755 scalos/Prefs/Palette/Catalogs/italiano/Scalos/config.mk create mode 100644 scalos/Prefs/Palette/Catalogs/italiano/Scalos/makefile create mode 100755 scalos/Prefs/Palette/Catalogs/italiano/Scalos/makefile-new create mode 100644 scalos/Prefs/Palette/Catalogs/sample/Scalos/ScalosPalette.ct create mode 100644 scalos/Prefs/Palette/Catalogs/svenska/Scalos/ScalosPalette.ct create mode 100755 scalos/Prefs/Palette/Catalogs/svenska/Scalos/config.mk create mode 100644 scalos/Prefs/Palette/Catalogs/svenska/Scalos/makefile create mode 100755 scalos/Prefs/Palette/Catalogs/svenska/Scalos/makefile-new create mode 100644 "scalos/Prefs/Palette/Catalogs/\303\203e\303\223tina/Scalos/ScalosPalette.ct" create mode 100755 "scalos/Prefs/Palette/Catalogs/\303\203e\303\223tina/Scalos/config.mk" create mode 100644 "scalos/Prefs/Palette/Catalogs/\303\203e\303\223tina/Scalos/makefile" create mode 100755 "scalos/Prefs/Palette/Catalogs/\303\203e\303\223tina/Scalos/makefile-new" create mode 100644 scalos/Prefs/Palette/Palette.c create mode 100755 scalos/Prefs/Palette/ScalosPalette.cd create mode 100755 scalos/Prefs/Palette/Scalos_Palette.info create mode 100755 scalos/Prefs/Palette/config.mk create mode 100644 scalos/Prefs/Palette/makefile create mode 100755 scalos/Prefs/Palette/makefile-new create mode 100644 scalos/Prefs/Pattern/Catalogs/dansk/Scalos/ScalosPattern.ct create mode 100755 scalos/Prefs/Pattern/Catalogs/dansk/Scalos/config.mk create mode 100644 scalos/Prefs/Pattern/Catalogs/dansk/Scalos/makefile create mode 100755 scalos/Prefs/Pattern/Catalogs/dansk/Scalos/makefile-new create mode 100644 scalos/Prefs/Pattern/Catalogs/deutsch/Scalos/ScalosPattern.ct create mode 100755 scalos/Prefs/Pattern/Catalogs/deutsch/Scalos/config.mk create mode 100644 scalos/Prefs/Pattern/Catalogs/deutsch/Scalos/makefile create mode 100755 scalos/Prefs/Pattern/Catalogs/deutsch/Scalos/makefile-new create mode 100644 "scalos/Prefs/Pattern/Catalogs/espa\303\261ol/scalos/ScalosPattern.ct" create mode 100755 "scalos/Prefs/Pattern/Catalogs/espa\303\261ol/scalos/config.mk" create mode 100644 "scalos/Prefs/Pattern/Catalogs/espa\303\261ol/scalos/makefile" create mode 100755 "scalos/Prefs/Pattern/Catalogs/espa\303\261ol/scalos/makefile-new" create mode 100755 "scalos/Prefs/Pattern/Catalogs/fran\303\247ais/Scalos/ScalosPattern.ct" create mode 100755 "scalos/Prefs/Pattern/Catalogs/fran\303\247ais/Scalos/config.mk" create mode 100644 "scalos/Prefs/Pattern/Catalogs/fran\303\247ais/Scalos/makefile" create mode 100755 "scalos/Prefs/Pattern/Catalogs/fran\303\247ais/Scalos/makefile-new" create mode 100644 scalos/Prefs/Pattern/Catalogs/italiano/Scalos/ScalosPattern.ct create mode 100755 scalos/Prefs/Pattern/Catalogs/italiano/Scalos/config.mk create mode 100644 scalos/Prefs/Pattern/Catalogs/italiano/Scalos/makefile create mode 100755 scalos/Prefs/Pattern/Catalogs/italiano/Scalos/makefile-new create mode 100644 scalos/Prefs/Pattern/Catalogs/sample/Scalos/ScalosPattern.ct create mode 100644 scalos/Prefs/Pattern/Catalogs/svenska/Scalos/ScalosPattern.ct create mode 100755 scalos/Prefs/Pattern/Catalogs/svenska/Scalos/config.mk create mode 100644 scalos/Prefs/Pattern/Catalogs/svenska/Scalos/makefile create mode 100755 scalos/Prefs/Pattern/Catalogs/svenska/Scalos/makefile-new create mode 100644 "scalos/Prefs/Pattern/Catalogs/\303\203e\303\223tina/Scalos/ScalosPattern.ct" create mode 100755 "scalos/Prefs/Pattern/Catalogs/\303\203e\303\223tina/Scalos/config.mk" create mode 100644 "scalos/Prefs/Pattern/Catalogs/\303\203e\303\223tina/Scalos/makefile" create mode 100755 "scalos/Prefs/Pattern/Catalogs/\303\203e\303\223tina/Scalos/makefile-new" create mode 100644 scalos/Prefs/Pattern/Pattern.c create mode 100755 scalos/Prefs/Pattern/Pattern.h create mode 100755 scalos/Prefs/Pattern/ScalosPattern.cd create mode 100755 scalos/Prefs/Pattern/Scalos_Pattern.info create mode 100755 scalos/Prefs/Pattern/config.mk create mode 100644 scalos/Prefs/Pattern/makefile create mode 100755 scalos/Prefs/Pattern/makefile-new create mode 100755 scalos/Prefs/config.mk create mode 100644 scalos/Prefs/makefile create mode 100755 scalos/Prefs/makefile-new create mode 100755 scalos/Release create mode 100644 scalos/ReleaseAROS create mode 100755 scalos/ScalosBeta.info create mode 100644 scalos/common/BackfillMCC/Backfill.c create mode 100644 scalos/common/BackfillMCC/Backfill.h create mode 100644 scalos/common/BitMapMCC/BitMapMCC.c create mode 100644 scalos/common/BitMapMCC/BitMapMCC.h create mode 100644 scalos/common/DataTypesMCC/DataTypesMCC.c create mode 100644 scalos/common/DataTypesMCC/DataTypesMCC.h create mode 100755 scalos/common/FontSampleMCC/FontSampleMCC.c create mode 100755 scalos/common/FontSampleMCC/FontSampleMCC.h create mode 100644 scalos/common/Fs/FsAbstraction.c create mode 100755 scalos/common/Fs/FsAbstraction.h create mode 100755 scalos/common/IconobjectMCC/IconobjectMCC.c create mode 100755 scalos/common/IconobjectMCC/IconobjectMCC.h create mode 100644 scalos/common/Int64/Dos64.c create mode 100644 scalos/common/Int64/int64.c create mode 100644 scalos/common/Int64/int64.h create mode 100644 scalos/common/McpGfx/ScalosMcpGfx.c create mode 100644 scalos/common/McpGfx/ScalosMcpGfx.h create mode 100755 scalos/common/Plugin/config.mk create mode 100644 scalos/common/Plugin/plugin-aos4-68kstubs.c create mode 100644 scalos/common/Plugin/plugin-aos4.c create mode 100644 scalos/common/Plugin/plugin-aros.c create mode 100644 scalos/common/Plugin/plugin-classic.c create mode 100644 scalos/common/Plugin/plugin-common.c create mode 100644 scalos/common/Plugin/plugin.h create mode 100644 scalos/common/Plugin/scalosfiletypeplugin-aos4-68kstubs.c create mode 100644 scalos/common/Plugin/scalosplugin-aos4-68kstubs.c create mode 100755 scalos/common/Plugin/scalosprefsplugin-aos4-68kstubs.c create mode 100644 scalos/common/Plugin/scalospreviewplugin-aos4-68kstubs.c create mode 100755 scalos/common/malloc/malloc.c create mode 100755 scalos/common/saslib/config.mk create mode 100755 scalos/common/saslib/makefile-new create mode 100644 scalos/common/saslib/saslib.c create mode 100644 scalos/common/saslib/saslib.h create mode 100755 scalos/config.mk create mode 100644 scalos/datatypes/AmigaIconObj3.5/AmigaIconObj35-aos4.c create mode 100644 scalos/datatypes/AmigaIconObj3.5/AmigaIconObj35-aros.c create mode 100644 scalos/datatypes/AmigaIconObj3.5/AmigaIconObj35-classic.c create mode 100644 scalos/datatypes/AmigaIconObj3.5/AmigaIconObj35.c create mode 100644 scalos/datatypes/AmigaIconObj3.5/AmigaIconObj35.h create mode 100755 scalos/datatypes/AmigaIconObj3.5/config.mk create mode 100644 scalos/datatypes/AmigaIconObj3.5/makefile create mode 100755 scalos/datatypes/AmigaIconObj3.5/makefile-new create mode 100644 scalos/datatypes/AmigaIconObject/AmigaIconObject-aos4.c create mode 100644 scalos/datatypes/AmigaIconObject/AmigaIconObject-aros.c create mode 100644 scalos/datatypes/AmigaIconObject/AmigaIconObject-classic.c create mode 100644 scalos/datatypes/AmigaIconObject/AmigaIconObject.c create mode 100644 scalos/datatypes/AmigaIconObject/AmigaIconObject.h create mode 100644 scalos/datatypes/AmigaIconObject/amigaiconobject.dt create mode 100755 scalos/datatypes/AmigaIconObject/config.mk create mode 100644 scalos/datatypes/AmigaIconObject/makefile create mode 100755 scalos/datatypes/AmigaIconObject/makefile-new create mode 100644 scalos/datatypes/GlowIconObject/GlowIconObject-aos4.c create mode 100644 scalos/datatypes/GlowIconObject/GlowIconObject-aros.c create mode 100644 scalos/datatypes/GlowIconObject/GlowIconObject-classic.c create mode 100644 scalos/datatypes/GlowIconObject/GlowIconObject.c create mode 100644 scalos/datatypes/GlowIconObject/GlowIconObject.h create mode 100755 scalos/datatypes/GlowIconObject/config.mk create mode 100644 scalos/datatypes/GlowIconObject/makefile create mode 100755 scalos/datatypes/GlowIconObject/makefile-new create mode 100644 scalos/datatypes/IconObject/argb.c create mode 100755 scalos/datatypes/IconObject/config.mk create mode 100644 scalos/datatypes/IconObject/iconobj-aos4.c create mode 100644 scalos/datatypes/IconObject/iconobj-aros.c create mode 100644 scalos/datatypes/IconObject/iconobj-classic.c create mode 100644 scalos/datatypes/IconObject/iconobj.c create mode 100644 scalos/datatypes/IconObject/iconobj.h create mode 100644 scalos/datatypes/IconObject/makefile create mode 100755 scalos/datatypes/IconObject/makefile-new create mode 100644 scalos/datatypes/New Icon Format Mail create mode 100644 scalos/datatypes/NewIcons/NewIconDt.c create mode 100644 scalos/datatypes/NewIcons/NewIconDt.h create mode 100755 scalos/datatypes/NewIcons/config.mk create mode 100644 scalos/datatypes/NewIcons/makefile create mode 100755 scalos/datatypes/NewIcons/makefile-new create mode 100644 scalos/datatypes/NewIcons/newiconobject.dt create mode 100644 scalos/datatypes/PNGIcons/GetPNGPicture.c create mode 100644 scalos/datatypes/PNGIcons/LoadPngIcon.c create mode 100644 scalos/datatypes/PNGIcons/PNGIconDt-aos4.c create mode 100644 scalos/datatypes/PNGIcons/PNGIconDt-aros.c create mode 100644 scalos/datatypes/PNGIcons/PNGIconDt-classic.c create mode 100644 scalos/datatypes/PNGIcons/PNGIconDt.c create mode 100644 scalos/datatypes/PNGIcons/PNGIconDt.h create mode 100644 scalos/datatypes/PNGIcons/PNGIconProto.h create mode 100644 scalos/datatypes/PNGIcons/SavePngIcon.c create mode 100755 scalos/datatypes/PNGIcons/config.mk create mode 100755 scalos/datatypes/PNGIcons/makefile create mode 100755 scalos/datatypes/PNGIcons/makefile-new create mode 100755 scalos/datatypes/config.mk create mode 100644 scalos/datatypes/makefile create mode 100755 scalos/datatypes/makefile-new create mode 100755 scalos/gpl-3.0.txt create mode 100755 scalos/include/DefIcons.h create mode 100755 scalos/include/MUIundoc.h create mode 100644 scalos/include/Year.h create mode 100755 scalos/include/clib/cybergraphics_protos.h create mode 100755 scalos/include/clib/dtlib_protos.h create mode 100755 scalos/include/clib/guigfx_protos.h create mode 100755 scalos/include/clib/iconobject_protos.h create mode 100755 scalos/include/clib/mcpgfx_protos.h create mode 100755 scalos/include/clib/newicon_protos.h create mode 100755 scalos/include/clib/openurl_protos.h create mode 100755 scalos/include/clib/pm_protos.h create mode 100755 scalos/include/clib/preferences_protos.h create mode 100755 scalos/include/clib/scalos_protos.h create mode 100755 scalos/include/clib/scalosfiletypeplugin_protos.h create mode 100755 scalos/include/clib/scalosgfx_protos.h create mode 100755 scalos/include/clib/scalosmenuplugin_protos.h create mode 100755 scalos/include/clib/scalosplugin_protos.h create mode 100755 scalos/include/clib/scalosprefsplugin_protos.h create mode 100755 scalos/include/clib/scalospreviewplugin_protos.h create mode 100755 scalos/include/clib/sqlite3_protos.h create mode 100755 scalos/include/clib/titlebarimage_protos.h create mode 100644 scalos/include/clib/ttengine_protos.h create mode 100644 scalos/include/curl/curl.h create mode 100644 scalos/include/curl/curlbuild.h create mode 100644 scalos/include/curl/curlrules.h create mode 100644 scalos/include/curl/curlver.h create mode 100644 scalos/include/curl/easy.h create mode 100644 scalos/include/curl/multi.h create mode 100644 scalos/include/cybergraphx/cybergraphics.h create mode 100755 scalos/include/datatypes/animationclassext.h create mode 100755 scalos/include/datatypes/iconobject.h create mode 100644 scalos/include/defines/dtlib.h create mode 100644 scalos/include/defines/guigfx.h create mode 100644 scalos/include/defines/iconobject.h create mode 100644 scalos/include/defines/mcpgfx.h create mode 100644 scalos/include/defines/newicon.h create mode 100644 scalos/include/defines/preferences.h create mode 100644 scalos/include/defines/scalos.h create mode 100644 scalos/include/defines/scalosfiletypeplugin.h create mode 100644 scalos/include/defines/scalosgfx.h create mode 100644 scalos/include/defines/scalosmenuplugin.h create mode 100644 scalos/include/defines/scalosplugin.h create mode 100644 scalos/include/defines/scalosprefsplugin.h create mode 100644 scalos/include/defines/scalospreviewplugin.h create mode 100644 scalos/include/defines/sqlite3.h create mode 100644 scalos/include/defines/ttengine.h create mode 100755 scalos/include/defs.h create mode 100644 scalos/include/ffmpeg/avformat.h create mode 100644 scalos/include/ffmpeg/avio.h create mode 100644 scalos/include/ffmpeg/common.h create mode 100644 scalos/include/ffmpeg/integer.h create mode 100644 scalos/include/ffmpeg/intfloat_readwrite.h create mode 100644 scalos/include/ffmpeg/libavcodec/avcodec.h create mode 100644 scalos/include/ffmpeg/libavcodec/imgconvert.h create mode 100644 scalos/include/ffmpeg/libavutil/avutil.h create mode 100644 scalos/include/ffmpeg/log.h create mode 100644 scalos/include/ffmpeg/mathematics.h create mode 100644 scalos/include/ffmpeg/mem.h create mode 100644 scalos/include/ffmpeg/rational.h create mode 100644 scalos/include/ffmpeg/rtp.h create mode 100644 scalos/include/ffmpeg/rtsp.h create mode 100644 scalos/include/ffmpeg/rtspcodes.h create mode 100644 scalos/include/ffmpeg/swscale.h create mode 100755 scalos/include/images/titlebar.h create mode 100755 scalos/include/inline/cybergraphics.h create mode 100755 scalos/include/inline/dtlib.h create mode 100755 scalos/include/inline/guigfx.h create mode 100644 scalos/include/inline/iconobject.h create mode 100755 scalos/include/inline/mcpgfx.h create mode 100644 scalos/include/inline/newicon.h create mode 100644 scalos/include/inline/openurl.h create mode 100755 scalos/include/inline/pm.h create mode 100755 scalos/include/inline/preferences.h create mode 100644 scalos/include/inline/scalos.h create mode 100755 scalos/include/inline/scalosfiletypeplugin.h create mode 100755 scalos/include/inline/scalosgfx.h create mode 100644 scalos/include/inline/scalosmenuplugin.h create mode 100644 scalos/include/inline/scalosplugin.h create mode 100755 scalos/include/inline/scalosprefsplugin.h create mode 100755 scalos/include/inline/scalospreviewplugin.h create mode 100755 scalos/include/inline/sqlite3.h create mode 100644 scalos/include/inline/ttengine.h create mode 100755 scalos/include/inline4/cybergraphics.h create mode 100644 scalos/include/inline4/guigfx.h create mode 100755 scalos/include/inline4/iconobject.h create mode 100755 scalos/include/inline4/openurl.h create mode 100644 scalos/include/inline4/pm.h create mode 100644 scalos/include/inline4/preferences.h create mode 100644 scalos/include/inline4/scalos.h create mode 100644 scalos/include/inline4/scalosfiletypeplugin.h create mode 100755 scalos/include/inline4/scalosgfx.h create mode 100644 scalos/include/inline4/scalosmenuplugin.h create mode 100644 scalos/include/inline4/scalosplugin.h create mode 100755 scalos/include/inline4/scalosprefsplugin.h create mode 100644 scalos/include/inline4/scalospreviewplugin.h create mode 100755 scalos/include/inline4/sqlite3.h create mode 100644 scalos/include/inline4/ttengine.h create mode 100755 scalos/include/interfaces/cybergraphics.h create mode 100644 scalos/include/interfaces/guigfx.h create mode 100644 scalos/include/interfaces/iconobject.h create mode 100755 scalos/include/interfaces/openurl.h create mode 100755 scalos/include/interfaces/openurl.i create mode 100644 scalos/include/interfaces/pm.h create mode 100644 scalos/include/interfaces/preferences.h create mode 100755 scalos/include/interfaces/scalos.h create mode 100644 scalos/include/interfaces/scalosfiletypeplugin.h create mode 100755 scalos/include/interfaces/scalosgfx.h create mode 100644 scalos/include/interfaces/scalosmenuplugin.h create mode 100644 scalos/include/interfaces/scalosplugin.h create mode 100755 scalos/include/interfaces/scalosprefsplugin.h create mode 100644 scalos/include/interfaces/scalospreviewplugin.h create mode 100755 scalos/include/interfaces/sqlite3.h create mode 100644 scalos/include/interfaces/ttengine.h create mode 100755 scalos/include/intuition/newmouse.h create mode 100644 scalos/include/jconfig.h create mode 100644 scalos/include/jerror.h create mode 100644 scalos/include/jmorecfg.h create mode 100644 scalos/include/jpeglib.h create mode 100755 scalos/include/libraries/mcpgfx.h create mode 100755 scalos/include/libraries/openurl.h create mode 100755 scalos/include/libraries/pm.h create mode 100755 scalos/include/libraries/ttengine.h create mode 100644 scalos/include/png.h create mode 100644 scalos/include/pngconf.h create mode 100644 scalos/include/pnglibconf.h create mode 100755 scalos/include/ppcinline/macros.h create mode 100755 scalos/include/ppcinline/openurl.h create mode 100644 scalos/include/ppcinline/ttengine.h create mode 100755 scalos/include/pragmas/alib_stdio_pragmas.h create mode 100755 scalos/include/pragmas/cybergraphics_pragmas.h create mode 100755 scalos/include/pragmas/dtlib_pragmas.h create mode 100755 scalos/include/pragmas/guigfx_pragmas.h create mode 100755 scalos/include/pragmas/iconobject_pragmas.h create mode 100755 scalos/include/pragmas/mcpgfx_pragmas.h create mode 100755 scalos/include/pragmas/newicon_pragmas.h create mode 100755 scalos/include/pragmas/openurl_pragmas.h create mode 100755 scalos/include/pragmas/pm_pragmas.h create mode 100755 scalos/include/pragmas/preferences_pragmas.h create mode 100755 scalos/include/pragmas/scalos_pragmas.h create mode 100755 scalos/include/pragmas/scalosfiletypeplugin_pragmas.h create mode 100755 scalos/include/pragmas/scalosgfx_pragmas.h create mode 100755 scalos/include/pragmas/scalosmenuplugin_pragmas.h create mode 100755 scalos/include/pragmas/scalosplugin_pragmas.h create mode 100755 scalos/include/pragmas/scalosprefsplugin_pragmas.h create mode 100755 scalos/include/pragmas/scalospreviewplugin_pragmas.h create mode 100755 scalos/include/pragmas/sqlite3_pragmas.h create mode 100755 scalos/include/pragmas/titlebarimage_pragmas.h create mode 100644 scalos/include/pragmas/ttengine_pragmas.h create mode 100644 scalos/include/prefs/popupmenu.h create mode 100755 scalos/include/proto/alib.h create mode 100644 scalos/include/proto/cybergraphics.h create mode 100755 scalos/include/proto/dtlib.h create mode 100755 scalos/include/proto/guigfx.h create mode 100755 scalos/include/proto/iconobject.h create mode 100755 scalos/include/proto/mcpgfx.h create mode 100644 scalos/include/proto/newicon.h create mode 100755 scalos/include/proto/openurl.h create mode 100755 scalos/include/proto/pm.h create mode 100755 scalos/include/proto/preferences.h create mode 100755 scalos/include/proto/scalos.h create mode 100755 scalos/include/proto/scalosfiletypeplugin.h create mode 100755 scalos/include/proto/scalosgfx.h create mode 100755 scalos/include/proto/scalosmenuplugin.h create mode 100755 scalos/include/proto/scalosplugin.h create mode 100755 scalos/include/proto/scalosprefsplugin.h create mode 100755 scalos/include/proto/scalospreviewplugin.h create mode 100755 scalos/include/proto/sqlite3.h create mode 100755 scalos/include/proto/titlebarimage.h create mode 100644 scalos/include/proto/ttengine.h create mode 100755 scalos/include/scalos/GadgetBar.h create mode 100644 scalos/include/scalos/int64types.h create mode 100755 scalos/include/scalos/menu.h create mode 100755 scalos/include/scalos/palette.h create mode 100755 scalos/include/scalos/pattern.h create mode 100755 scalos/include/scalos/preferences.h create mode 100755 scalos/include/scalos/scalos.h create mode 100755 scalos/include/scalos/scalosgfx.h create mode 100755 scalos/include/scalos/scalosmenuprefsplugin.h create mode 100755 scalos/include/scalos/scalospatternprefsplugin.h create mode 100755 scalos/include/scalos/scalosprefs.h create mode 100755 scalos/include/scalos/scalosprefsplugin.h create mode 100755 scalos/include/scalos/scalospreviewplugin.h create mode 100755 scalos/include/scalos/undo.h create mode 100755 scalos/include/scalosdebug.h create mode 100644 scalos/include/sqlite3.h create mode 100644 scalos/include/zconf.h create mode 100644 scalos/include/zlib.h create mode 100755 scalos/lgpl-3.0.txt create mode 100755 scalos/libraries/config.mk create mode 100644 scalos/libraries/iconobject/IconObject-aos4.c create mode 100644 scalos/libraries/iconobject/IconObject-aros.c create mode 100644 scalos/libraries/iconobject/IconObject-classic.c create mode 100644 scalos/libraries/iconobject/IconObject.c create mode 100644 scalos/libraries/iconobject/IconObject.h create mode 100755 scalos/libraries/iconobject/config.mk create mode 100644 scalos/libraries/iconobject/iconnode.h create mode 100644 scalos/libraries/iconobject/iconobject-aos4-68kstubs.c create mode 100644 scalos/libraries/iconobject/iconobject_base.h create mode 100644 scalos/libraries/iconobject/makefile create mode 100755 scalos/libraries/iconobject/makefile-new create mode 100644 scalos/libraries/iconobject/test.c create mode 100644 scalos/libraries/makefile create mode 100755 scalos/libraries/makefile-new create mode 100644 scalos/libraries/popupmenu/LICENSE create mode 100644 scalos/libraries/popupmenu/compiler.h create mode 100755 scalos/libraries/popupmenu/config.mk create mode 100644 scalos/libraries/popupmenu/iff.c create mode 100644 scalos/libraries/popupmenu/makefile create mode 100755 scalos/libraries/popupmenu/makefile-new create mode 100644 scalos/libraries/popupmenu/pm-aos4-68kstubs.c create mode 100644 scalos/libraries/popupmenu/pm.c create mode 100644 scalos/libraries/popupmenu/pmcreate.c create mode 100644 scalos/libraries/popupmenu/pmdlist.c create mode 100644 scalos/libraries/popupmenu/pmdlist.h create mode 100644 scalos/libraries/popupmenu/pmdrawshadow.c create mode 100644 scalos/libraries/popupmenu/pmfind.c create mode 100644 scalos/libraries/popupmenu/pmfind.h create mode 100644 scalos/libraries/popupmenu/pmgraph.c create mode 100644 scalos/libraries/popupmenu/pmgraph.h create mode 100644 scalos/libraries/popupmenu/pmimages.c create mode 100644 scalos/libraries/popupmenu/pmimages.h create mode 100644 scalos/libraries/popupmenu/pminit.c create mode 100644 scalos/libraries/popupmenu/pminput.c create mode 100644 scalos/libraries/popupmenu/pminput.h create mode 100644 scalos/libraries/popupmenu/pminternals.h create mode 100644 scalos/libraries/popupmenu/pmlayout.c create mode 100644 scalos/libraries/popupmenu/pmmem.c create mode 100644 scalos/libraries/popupmenu/pmmem.h create mode 100644 scalos/libraries/popupmenu/pmprefs.c create mode 100644 scalos/libraries/popupmenu/pmprefs.h create mode 100644 scalos/libraries/popupmenu/pmpriv.h create mode 100644 scalos/libraries/popupmenu/pmshadow.c create mode 100644 scalos/libraries/popupmenu/pmshadow.h create mode 100644 scalos/libraries/popupmenu/pmtags.c create mode 100644 scalos/libraries/popupmenu/pmtopography.c create mode 100644 scalos/libraries/popupmenu/pmtopography.h create mode 100644 scalos/libraries/popupmenu/pmtypes.h create mode 100644 scalos/libraries/popupmenu/pmversion.c create mode 100644 scalos/libraries/popupmenu/popupmenu-aos4.c create mode 100644 scalos/libraries/popupmenu/popupmenu-classic.c create mode 100644 scalos/libraries/popupmenu/popupmenu.h create mode 100644 scalos/libraries/popupmenu/window.c create mode 100644 scalos/libraries/preferences/Preferences-aos4-68kstubs.c create mode 100644 scalos/libraries/preferences/Preferences-aos4.c create mode 100644 scalos/libraries/preferences/Preferences-aros.c create mode 100644 scalos/libraries/preferences/Preferences-classic.c create mode 100644 scalos/libraries/preferences/Preferences.c create mode 100644 scalos/libraries/preferences/Preferences.h create mode 100644 scalos/libraries/preferences/Preferences_base.h create mode 100755 scalos/libraries/preferences/config.mk create mode 100644 scalos/libraries/preferences/makefile create mode 100755 scalos/libraries/preferences/makefile-new create mode 100644 scalos/libraries/scalosgfx/BitMapScale.c create mode 100755 scalos/libraries/scalosgfx/Dither.c create mode 100644 scalos/libraries/scalosgfx/Render.c create mode 100644 scalos/libraries/scalosgfx/argb.c create mode 100644 scalos/libraries/scalosgfx/blit.c create mode 100755 scalos/libraries/scalosgfx/config.mk create mode 100644 scalos/libraries/scalosgfx/makefile create mode 100755 scalos/libraries/scalosgfx/makefile-new create mode 100644 scalos/libraries/scalosgfx/scalosgfx-aos4-68kstubs.c create mode 100644 scalos/libraries/scalosgfx/scalosgfx-aos4.c create mode 100644 scalos/libraries/scalosgfx/scalosgfx-aros.c create mode 100644 scalos/libraries/scalosgfx/scalosgfx-classic.c create mode 100644 scalos/libraries/scalosgfx/scalosgfx.c create mode 100644 scalos/libraries/scalosgfx/scalosgfx.h create mode 100644 scalos/libraries/scalosgfx/scalosgfx_base.h create mode 100644 scalos/libraries/sqlite/LibSQLite3.c create mode 100644 scalos/libraries/sqlite/LibSQLite3.h create mode 100644 scalos/libraries/sqlite/Makefile create mode 100644 scalos/libraries/sqlite/VERSION create mode 100755 scalos/libraries/sqlite/config.mk create mode 100644 scalos/libraries/sqlite/keywordhash.h create mode 100755 scalos/libraries/sqlite/makefile-new create mode 100644 scalos/libraries/sqlite/opcodes.c create mode 100644 scalos/libraries/sqlite/opcodes.h create mode 100644 scalos/libraries/sqlite/parse.c create mode 100644 scalos/libraries/sqlite/parse.h create mode 100644 scalos/libraries/sqlite/sqlite3-aos4-68kstubs.c create mode 100644 scalos/libraries/sqlite/sqlite3-aos4.c create mode 100644 scalos/libraries/sqlite/sqlite3-aros.c create mode 100644 scalos/libraries/sqlite/sqlite3-classic.c create mode 100644 scalos/libraries/sqlite/sqlite3.h create mode 100644 scalos/libraries/sqlite/sqlite3_base.h create mode 100644 scalos/libraries/sqlite/src/alter.c create mode 100644 scalos/libraries/sqlite/src/analyze.c create mode 100644 scalos/libraries/sqlite/src/attach.c create mode 100644 scalos/libraries/sqlite/src/auth.c create mode 100644 scalos/libraries/sqlite/src/backup.c create mode 100644 scalos/libraries/sqlite/src/bitvec.c create mode 100644 scalos/libraries/sqlite/src/btmutex.c create mode 100644 scalos/libraries/sqlite/src/btree.c create mode 100644 scalos/libraries/sqlite/src/btree.h create mode 100644 scalos/libraries/sqlite/src/btreeInt.h create mode 100644 scalos/libraries/sqlite/src/build.c create mode 100644 scalos/libraries/sqlite/src/callback.c create mode 100644 scalos/libraries/sqlite/src/complete.c create mode 100644 scalos/libraries/sqlite/src/ctime.c create mode 100644 scalos/libraries/sqlite/src/date.c create mode 100644 scalos/libraries/sqlite/src/delete.c create mode 100644 scalos/libraries/sqlite/src/expr.c create mode 100644 scalos/libraries/sqlite/src/fault.c create mode 100644 scalos/libraries/sqlite/src/fkey.c create mode 100644 scalos/libraries/sqlite/src/func.c create mode 100644 scalos/libraries/sqlite/src/global.c create mode 100644 scalos/libraries/sqlite/src/hash.c create mode 100644 scalos/libraries/sqlite/src/hash.h create mode 100644 scalos/libraries/sqlite/src/hwtime.h create mode 100644 scalos/libraries/sqlite/src/insert.c create mode 100644 scalos/libraries/sqlite/src/journal.c create mode 100644 scalos/libraries/sqlite/src/legacy.c create mode 100644 scalos/libraries/sqlite/src/lempar.c create mode 100644 scalos/libraries/sqlite/src/loadext.c create mode 100644 scalos/libraries/sqlite/src/main.c create mode 100644 scalos/libraries/sqlite/src/malloc.c create mode 100644 scalos/libraries/sqlite/src/mem0.c create mode 100644 scalos/libraries/sqlite/src/mem1.c create mode 100644 scalos/libraries/sqlite/src/mem2.c create mode 100644 scalos/libraries/sqlite/src/mem3.c create mode 100644 scalos/libraries/sqlite/src/mem5.c create mode 100644 scalos/libraries/sqlite/src/memjournal.c create mode 100644 scalos/libraries/sqlite/src/mutex.c create mode 100644 scalos/libraries/sqlite/src/mutex.h create mode 100644 scalos/libraries/sqlite/src/mutex_noop.c create mode 100644 scalos/libraries/sqlite/src/mutex_os2.c create mode 100644 scalos/libraries/sqlite/src/mutex_other.c create mode 100644 scalos/libraries/sqlite/src/mutex_unix.c create mode 100644 scalos/libraries/sqlite/src/mutex_w32.c create mode 100644 scalos/libraries/sqlite/src/notify.c create mode 100644 scalos/libraries/sqlite/src/os.c create mode 100644 scalos/libraries/sqlite/src/os.h create mode 100644 scalos/libraries/sqlite/src/os_common.h create mode 100644 scalos/libraries/sqlite/src/os_os2.c create mode 100644 scalos/libraries/sqlite/src/os_other.c create mode 100644 scalos/libraries/sqlite/src/os_other.h create mode 100644 scalos/libraries/sqlite/src/os_unix.c create mode 100644 scalos/libraries/sqlite/src/os_win.c create mode 100644 scalos/libraries/sqlite/src/pager.c create mode 100644 scalos/libraries/sqlite/src/pager.h create mode 100644 scalos/libraries/sqlite/src/pcache.c create mode 100644 scalos/libraries/sqlite/src/pcache.h create mode 100644 scalos/libraries/sqlite/src/pcache1.c create mode 100644 scalos/libraries/sqlite/src/pragma.c create mode 100644 scalos/libraries/sqlite/src/prepare.c create mode 100644 scalos/libraries/sqlite/src/printf.c create mode 100644 scalos/libraries/sqlite/src/random.c create mode 100644 scalos/libraries/sqlite/src/resolve.c create mode 100644 scalos/libraries/sqlite/src/rowset.c create mode 100644 scalos/libraries/sqlite/src/select.c create mode 100644 scalos/libraries/sqlite/src/sqlite3ext.h create mode 100644 scalos/libraries/sqlite/src/sqliteInt.h create mode 100644 scalos/libraries/sqlite/src/sqliteLimit.h create mode 100644 scalos/libraries/sqlite/src/status.c create mode 100644 scalos/libraries/sqlite/src/table.c create mode 100644 scalos/libraries/sqlite/src/tokenize.c create mode 100644 scalos/libraries/sqlite/src/trigger.c create mode 100644 scalos/libraries/sqlite/src/update.c create mode 100644 scalos/libraries/sqlite/src/utf.c create mode 100644 scalos/libraries/sqlite/src/util.c create mode 100644 scalos/libraries/sqlite/src/vacuum.c create mode 100644 scalos/libraries/sqlite/src/vdbe.c create mode 100644 scalos/libraries/sqlite/src/vdbe.h create mode 100644 scalos/libraries/sqlite/src/vdbeInt.h create mode 100644 scalos/libraries/sqlite/src/vdbeapi.c create mode 100644 scalos/libraries/sqlite/src/vdbeaux.c create mode 100644 scalos/libraries/sqlite/src/vdbeblob.c create mode 100644 scalos/libraries/sqlite/src/vdbemem.c create mode 100755 scalos/libraries/sqlite/src/vdbesort.c create mode 100644 scalos/libraries/sqlite/src/vdbetrace.c create mode 100644 scalos/libraries/sqlite/src/vtab.c create mode 100644 scalos/libraries/sqlite/src/wal.c create mode 100644 scalos/libraries/sqlite/src/wal.h create mode 100644 scalos/libraries/sqlite/src/walker.c create mode 100644 scalos/libraries/sqlite/src/where.c create mode 100644 scalos/libraries/sqlite/tool/mkkeywordhash.c create mode 100755 scalos/libs/OS4/guigfx.library create mode 100755 scalos/libs/OS4/render.library create mode 100755 scalos/libs/guigfx.library create mode 100755 scalos/libs/guigfx.library.elf create mode 100755 scalos/libs/mcpgfx.library create mode 100755 scalos/libs/render.library create mode 100755 scalos/libs/render.library.elf create mode 100644 scalos/main/AppMenu.c create mode 100644 scalos/main/AutoUpdate.c create mode 100755 scalos/main/BTree.c create mode 100755 scalos/main/BTree.h create mode 100755 scalos/main/BackFill.c create mode 100755 scalos/main/Backdrop.c create mode 100644 scalos/main/ButtonGadgetClass.c create mode 100644 scalos/main/CLIStart.c create mode 100755 scalos/main/ChildProcess.c create mode 100755 scalos/main/Class.c create mode 100755 scalos/main/ControlBar.c create mode 100644 scalos/main/CycleGadgetClass.c create mode 100644 scalos/main/CycleGadgetClass.h create mode 100644 scalos/main/DefIcons.c create mode 100644 scalos/main/DevListClass.c create mode 100755 scalos/main/DeviceWindowClass.c create mode 100755 scalos/main/DoubleClick.c create mode 100755 scalos/main/DragDrop.c create mode 100755 scalos/main/DragDropBobs.c create mode 100644 scalos/main/DrawIcon.c create mode 100755 scalos/main/DropMarks.c create mode 100644 scalos/main/DtImageClass.c create mode 100644 scalos/main/DtImageClass.h create mode 100644 scalos/main/FileCommands.c create mode 100755 scalos/main/FileTransClass.c create mode 100755 scalos/main/FileTransClass.h create mode 100644 scalos/main/FontUtil.c create mode 100644 scalos/main/FrameImageClass.c create mode 100644 scalos/main/FrameImageClass.h create mode 100755 scalos/main/Functions.c create mode 100755 scalos/main/GadgetBarClass.c create mode 100644 scalos/main/GadgetBarImageClass.c create mode 100644 scalos/main/GadgetBarTextClass.c create mode 100644 scalos/main/GaugeGadgetClass.c create mode 100644 scalos/main/GaugeGadgetClass.h create mode 100644 scalos/main/HistoryGadgetClass.c create mode 100644 scalos/main/HistoryGadgetClass.h create mode 100644 scalos/main/IconImageClass.c create mode 100755 scalos/main/IconImageClass.h create mode 100755 scalos/main/IconWindowClass.c create mode 100644 scalos/main/IconWindow_MouseMove.c create mode 100755 scalos/main/IconifyClass.c create mode 100644 scalos/main/InputHandler.c create mode 100644 scalos/main/Lasso.c create mode 100644 scalos/main/LocaleStrings.c create mode 100755 scalos/main/MainWait.c create mode 100644 scalos/main/Memory.c create mode 100644 scalos/main/Menu.c create mode 100644 scalos/main/MenuCommand.c create mode 100755 scalos/main/Messages.c create mode 100755 scalos/main/MouseIcon.c create mode 100755 scalos/main/NoDebug create mode 100644 scalos/main/OpenDrawerByName.c create mode 100755 scalos/main/Patches-aos4.c create mode 100644 scalos/main/Patches-aros.c create mode 100755 scalos/main/Patches-classic.c create mode 100755 scalos/main/Patches.c create mode 100755 scalos/main/Patches.h create mode 100644 scalos/main/Pattern.c create mode 100644 scalos/main/PenNames.h create mode 100755 scalos/main/PopOpenWindows.c create mode 100644 scalos/main/PopupMenus.c create mode 100644 scalos/main/Prefs.c create mode 100755 scalos/main/Prefs.h create mode 100644 scalos/main/Rename.c create mode 100644 scalos/main/Request.c create mode 100755 scalos/main/RootClass.c create mode 100644 scalos/main/ScaLibrary-aos4.c create mode 100644 scalos/main/ScaLibrary-aros.c create mode 100644 scalos/main/ScaLibrary-classic.c create mode 100755 scalos/main/ScaLibrary.c create mode 100644 scalos/main/ScaLibrary.h create mode 100755 scalos/main/Scalos.c create mode 100644 scalos/main/Scalos.cd create mode 100755 scalos/main/Scalos.info create mode 100755 scalos/main/ScalosInit.c create mode 100644 scalos/main/ScalosLocale.c create mode 100644 scalos/main/ScalosVersion.c create mode 100644 scalos/main/Scalos_Cx.c create mode 100644 scalos/main/Scalos_rev.h create mode 100755 scalos/main/ScanDir.c create mode 100755 scalos/main/ScanDirText.c create mode 100644 scalos/main/Semaphores.c create mode 100755 scalos/main/Semaphores.h create mode 100644 scalos/main/SeparatorGadgetClass.c create mode 100644 scalos/main/Shortcuts.c create mode 100755 scalos/main/Splash.c create mode 100755 scalos/main/StatusBar.c create mode 100644 scalos/main/StringGadgetClass.c create mode 100644 scalos/main/Subroutines.c create mode 100644 scalos/main/TTLayout.c create mode 100644 scalos/main/TTLayout.h create mode 100644 scalos/main/Test/AddMoreMenus.c create mode 100755 scalos/main/Test/AppIcon create mode 100644 scalos/main/Test/AppIcon.h create mode 100644 scalos/main/Test/ClockIcon.c create mode 100644 scalos/main/Test/SizeTest.c create mode 100755 scalos/main/Test/XADtest create mode 100755 scalos/main/Test/XADtest.c create mode 100644 scalos/main/Test/icontest.c create mode 100644 scalos/main/Test/pens.c create mode 100755 scalos/main/Test/pngdt create mode 100644 scalos/main/Test/pngdt.c create mode 100644 scalos/main/Test/putmsg.c create mode 100644 scalos/main/Test/putmsga.asm create mode 100644 scalos/main/Test/testwbargs.c create mode 100755 scalos/main/Test/wbmsgtester1.s create mode 100755 scalos/main/TextIconClass.c create mode 100644 scalos/main/TextIconHighlightClass.c create mode 100644 scalos/main/TextIconHighlightClass.h create mode 100755 scalos/main/TextWindowClass.c create mode 100755 scalos/main/ThumbnailCache.c create mode 100755 scalos/main/Thumbnails.c create mode 100755 scalos/main/TitleClass.c create mode 100755 scalos/main/ToolTip.c create mode 100644 scalos/main/ToolTypes.c create mode 100755 scalos/main/Tools/CollectVersions create mode 100644 scalos/main/Tools/CreateTrashCan/CreateTrash.68k.info create mode 100644 scalos/main/Tools/CreateTrashCan/CreateTrash.e create mode 100644 scalos/main/Tools/CreateTrashCan/CreateTrash.mos.info create mode 100644 scalos/main/Tools/CreateTrashCan/VERSTAG.e create mode 100644 scalos/main/Tools/CreateTrashCan/makefile create mode 100644 scalos/main/Tools/CreateTrashCan/makefile-new create mode 100644 scalos/main/Tools/CreateTrashCan/mod.m create mode 100644 scalos/main/Tools/GenMsgIdNames.c create mode 100644 scalos/main/Tools/How-To-sign create mode 100755 scalos/main/Tools/LoadWB.c create mode 100644 scalos/main/Tools/OpenDrawer/OpenDrawer.c create mode 100755 scalos/main/Tools/OpenDrawer/config.mk create mode 100644 scalos/main/Tools/OpenDrawer/makefile create mode 100755 scalos/main/Tools/OpenDrawer/makefile-new create mode 100644 scalos/main/Tools/OpenDrawer/opendrawer.68k.info create mode 100644 scalos/main/Tools/OpenDrawer/opendrawer.mos.info create mode 100644 scalos/main/Tools/Protect.MUI/GetIconObject.e create mode 100644 scalos/main/Tools/Protect.MUI/ProtModule.e create mode 100644 scalos/main/Tools/Protect.MUI/Protect.module.e create mode 100644 scalos/main/Tools/Protect.MUI/Scalos_Protect.cd create mode 100644 scalos/main/Tools/Protect.MUI/Scalos_Protect_Locale.e create mode 100644 scalos/main/Tools/Protect.MUI/VERSTAG.e create mode 100644 "scalos/main/Tools/Protect.MUI/catalogs/Fran\303\247ais/Scalos/Scalos_Protect.catalog" create mode 100644 "scalos/main/Tools/Protect.MUI/catalogs/Fran\303\247ais/Scalos/Scalos_Protect.ct" create mode 100644 scalos/main/Tools/Protect.MUI/getpath.e create mode 100644 scalos/main/Tools/Protect.MUI/makefile create mode 100644 scalos/main/Tools/Protect.MUI/makefile-new create mode 100755 scalos/main/Tools/Scalos.pem create mode 100644 scalos/main/Tools/ScalosCtrl.c create mode 100644 scalos/main/Tools/ScalosPub.pem create mode 100644 scalos/main/Tools/ScalosSema.c create mode 100755 scalos/main/Tools/ScalosVersions create mode 100644 scalos/main/Tools/Scalos_Comment.info create mode 100644 "scalos/main/Tools/Scalos_Comment/Catalogs/Fran\303\247ais/Scalos/Scalos_Comment.catalog" create mode 100644 "scalos/main/Tools/Scalos_Comment/Catalogs/Fran\303\247ais/Scalos/Scalos_Comment.ct" create mode 100644 scalos/main/Tools/Scalos_Comment/Comment.module.68k.info create mode 100644 scalos/main/Tools/Scalos_Comment/Comment.module.e create mode 100644 scalos/main/Tools/Scalos_Comment/Comment.module.mos.info create mode 100644 scalos/main/Tools/Scalos_Comment/GetIconObject.e create mode 100644 scalos/main/Tools/Scalos_Comment/Scalos_Comment.cd create mode 100644 scalos/main/Tools/Scalos_Comment/Scalos_Comment_Locale.e create mode 100644 scalos/main/Tools/Scalos_Comment/VERSTAG.e create mode 100644 scalos/main/Tools/Scalos_Comment/comment.module.info create mode 100644 scalos/main/Tools/Scalos_Comment/getpath.e create mode 100644 scalos/main/Tools/Scalos_Comment/makefile create mode 100644 scalos/main/Tools/Scalos_Comment/makefile-new create mode 100644 scalos/main/Tools/Scalos_GetHidden/GetHidden.cd create mode 100644 scalos/main/Tools/Scalos_GetHidden/GetHidden.e create mode 100644 scalos/main/Tools/Scalos_GetHidden/GetIconObject.e create mode 100644 scalos/main/Tools/Scalos_GetHidden/GetTCP.e create mode 100644 scalos/main/Tools/Scalos_GetHidden/MyDebugOnOff.e create mode 100644 scalos/main/Tools/Scalos_GetHidden/OnlineUpdate.e create mode 100644 scalos/main/Tools/Scalos_GetHidden/Scalos_GetHidden_Locale.e create mode 100644 scalos/main/Tools/Scalos_GetHidden/VERSTAGECX.e create mode 100644 scalos/main/Tools/Scalos_GetHidden/catalogs/deutsch/scalos/GetHidden.ct create mode 100644 scalos/main/Tools/Scalos_GetHidden/catalogs/deutsch/scalos/makefile create mode 100644 "scalos/main/Tools/Scalos_GetHidden/catalogs/fran\303\247ais/scalos/GetHidden.ct" create mode 100644 "scalos/main/Tools/Scalos_GetHidden/catalogs/fran\303\247ais/scalos/makefile" create mode 100644 scalos/main/Tools/Scalos_GetHidden/gethidden.68k.info create mode 100644 scalos/main/Tools/Scalos_GetHidden/gethidden.mos.info create mode 100644 scalos/main/Tools/Scalos_GetHidden/getpath.e create mode 100644 scalos/main/Tools/Scalos_GetHidden/makefile create mode 100644 scalos/main/Tools/Scalos_GetHidden/makefile-new create mode 100755 scalos/main/Tools/config.mk create mode 100755 scalos/main/Tools/makefile create mode 100755 scalos/main/Tools/makefile-new create mode 100644 scalos/main/Undo.c create mode 100644 scalos/main/Variables.h create mode 100644 scalos/main/WBStartup.c create mode 100755 scalos/main/Window.c create mode 100644 scalos/main/WindowClass.c create mode 100644 scalos/main/Wrappers.h create mode 100755 scalos/main/about.c create mode 100755 scalos/main/about.h create mode 100644 scalos/main/catalogs/Polski/Scalos/Scalos.ct create mode 100755 scalos/main/catalogs/Polski/Scalos/config.mk create mode 100755 scalos/main/catalogs/Polski/Scalos/makefile create mode 100755 scalos/main/catalogs/Polski/Scalos/makefile-new create mode 100755 scalos/main/catalogs/dansk/Scalos/Scalos.ct create mode 100755 scalos/main/catalogs/dansk/Scalos/config.mk create mode 100755 scalos/main/catalogs/dansk/Scalos/makefile create mode 100755 scalos/main/catalogs/dansk/Scalos/makefile-new create mode 100755 scalos/main/catalogs/deutsch/Scalos/Scalos.ct create mode 100755 scalos/main/catalogs/deutsch/Scalos/config.mk create mode 100755 scalos/main/catalogs/deutsch/Scalos/makefile create mode 100755 scalos/main/catalogs/deutsch/Scalos/makefile-new create mode 100755 "scalos/main/catalogs/espa\303\261ol/Scalos/Scalos.ct" create mode 100755 "scalos/main/catalogs/espa\303\261ol/Scalos/config.mk" create mode 100755 "scalos/main/catalogs/espa\303\261ol/Scalos/makefile" create mode 100755 "scalos/main/catalogs/espa\303\261ol/Scalos/makefile-new" create mode 100644 "scalos/main/catalogs/fran\303\247ais/Scalos/Scalos.ct" create mode 100755 "scalos/main/catalogs/fran\303\247ais/Scalos/config.mk" create mode 100755 "scalos/main/catalogs/fran\303\247ais/Scalos/makefile" create mode 100755 "scalos/main/catalogs/fran\303\247ais/Scalos/makefile-new" create mode 100644 scalos/main/catalogs/sample/Scalos/Scalos.ct create mode 100755 "scalos/main/catalogs/\303\203e\303\223tina/Scalos/Scalos.ct" create mode 100755 "scalos/main/catalogs/\303\203e\303\223tina/Scalos/config.mk" create mode 100755 "scalos/main/catalogs/\303\203e\303\223tina/Scalos/makefile" create mode 100755 "scalos/main/catalogs/\303\203e\303\223tina/Scalos/makefile-new" create mode 100755 scalos/main/cleanup.c create mode 100755 scalos/main/config.mk create mode 100644 scalos/main/crc32.c create mode 100644 scalos/main/debug.h create mode 100755 scalos/main/docs/AutoDocs/SCA_DeviceList.doc create mode 100755 scalos/main/docs/AutoDocs/SCA_DeviceWindow.doc create mode 100755 scalos/main/docs/AutoDocs/SCA_FileTrans.doc create mode 100755 scalos/main/docs/AutoDocs/SCA_IconWindow.doc create mode 100755 scalos/main/docs/AutoDocs/SCA_Root.doc create mode 100755 scalos/main/docs/AutoDocs/SCA_TextWindow.doc create mode 100755 scalos/main/docs/AutoDocs/SCA_Title.doc create mode 100755 scalos/main/docs/AutoDocs/SCA_Window.doc create mode 100644 scalos/main/docs/AutoDocs/html/SCA_DeviceList.html create mode 100644 scalos/main/docs/AutoDocs/html/SCA_DeviceWindow.html create mode 100644 scalos/main/docs/AutoDocs/html/SCA_FileTrans.html create mode 100644 scalos/main/docs/AutoDocs/html/SCA_IconWindow.html create mode 100644 scalos/main/docs/AutoDocs/html/SCA_Root.html create mode 100644 scalos/main/docs/AutoDocs/html/SCA_TextWindow.html create mode 100644 scalos/main/docs/AutoDocs/html/SCA_Title.html create mode 100644 scalos/main/docs/AutoDocs/html/SCA_Window.html create mode 100644 scalos/main/docs/AutoDocs/html/iconobject.html create mode 100644 scalos/main/docs/AutoDocs/html/iconobject_dtc.html create mode 100644 scalos/main/docs/AutoDocs/html/preferences.html create mode 100644 scalos/main/docs/AutoDocs/html/scalos.html create mode 100644 scalos/main/docs/AutoDocs/html/scalosAPI.html create mode 100755 scalos/main/docs/AutoDocs/iconobject.doc create mode 100755 scalos/main/docs/AutoDocs/iconobject_dtc.doc create mode 100755 scalos/main/docs/AutoDocs/preferences.doc create mode 100755 scalos/main/docs/AutoDocs/scalos.doc create mode 100755 scalos/main/docs/AutoDocs/scalosAPI.doc create mode 100755 scalos/main/docs/AutoDocs/scalosgfx.doc create mode 100755 scalos/main/docs/FileTypes_plugins.guide create mode 100644 scalos/main/docs/Filetypes.guide create mode 100644 scalos/main/docs/Filetypes_Syntax.doc create mode 100755 scalos/main/docs/HUNGARO.TXT create mode 100755 scalos/main/docs/Icon datatype priority create mode 100644 scalos/main/docs/SOSBugs.txt create mode 100644 scalos/main/docs/SOSfeatures.txt create mode 100755 scalos/main/docs/Scalos_source_tree.txt create mode 100644 scalos/main/docs/Tooltip definition create mode 100755 scalos/main/dtimage.c create mode 100755 scalos/main/envarc/deficons.prefs create mode 100755 scalos/main/envarc/scalos.68K/Deutsch/FileTypes/ILBM create mode 100755 scalos/main/envarc/scalos.68K/Deutsch/FileTypes/appicon create mode 100755 scalos/main/envarc/scalos.68K/Deutsch/FileTypes/archive create mode 100755 scalos/main/envarc/scalos.68K/Deutsch/FileTypes/avi create mode 100755 scalos/main/envarc/scalos.68K/Deutsch/FileTypes/brush create mode 100755 scalos/main/envarc/scalos.68K/Deutsch/FileTypes/disk create mode 100755 scalos/main/envarc/scalos.68K/Deutsch/FileTypes/drawer create mode 100755 scalos/main/envarc/scalos.68K/Deutsch/FileTypes/filearchive create mode 100755 scalos/main/envarc/scalos.68K/Deutsch/FileTypes/gif create mode 100755 scalos/main/envarc/scalos.68K/Deutsch/FileTypes/jpeg create mode 100755 scalos/main/envarc/scalos.68K/Deutsch/FileTypes/mpeg create mode 100755 scalos/main/envarc/scalos.68K/Deutsch/FileTypes/picture create mode 100755 scalos/main/envarc/scalos.68K/Deutsch/FileTypes/png create mode 100755 scalos/main/envarc/scalos.68K/Deutsch/FileTypes/project create mode 100755 scalos/main/envarc/scalos.68K/Deutsch/FileTypes/quicktime create mode 100755 scalos/main/envarc/scalos.68K/Deutsch/FileTypes/tool create mode 100755 scalos/main/envarc/scalos.68K/Deutsch/FileTypes/trashcan create mode 100755 scalos/main/envarc/scalos.68K/Deutsch/FileTypes/video create mode 100755 scalos/main/envarc/scalos.68K/Deutsch/FileTypes/wmv create mode 100755 scalos/main/envarc/scalos.68K/Deutsch/Menu13.prefs create mode 100755 scalos/main/envarc/scalos.68K/English/FileTypes/ILBM create mode 100755 scalos/main/envarc/scalos.68K/English/FileTypes/appicon create mode 100755 scalos/main/envarc/scalos.68K/English/FileTypes/archive create mode 100755 scalos/main/envarc/scalos.68K/English/FileTypes/avi create mode 100755 scalos/main/envarc/scalos.68K/English/FileTypes/brush create mode 100755 scalos/main/envarc/scalos.68K/English/FileTypes/disk create mode 100755 scalos/main/envarc/scalos.68K/English/FileTypes/drawer create mode 100755 scalos/main/envarc/scalos.68K/English/FileTypes/filearchive create mode 100755 scalos/main/envarc/scalos.68K/English/FileTypes/gif create mode 100755 scalos/main/envarc/scalos.68K/English/FileTypes/jpeg create mode 100755 scalos/main/envarc/scalos.68K/English/FileTypes/mpeg create mode 100755 scalos/main/envarc/scalos.68K/English/FileTypes/picture create mode 100755 scalos/main/envarc/scalos.68K/English/FileTypes/png create mode 100755 scalos/main/envarc/scalos.68K/English/FileTypes/project create mode 100755 scalos/main/envarc/scalos.68K/English/FileTypes/quicktime create mode 100755 scalos/main/envarc/scalos.68K/English/FileTypes/tool create mode 100755 scalos/main/envarc/scalos.68K/English/FileTypes/trashcan create mode 100755 scalos/main/envarc/scalos.68K/English/FileTypes/video create mode 100755 scalos/main/envarc/scalos.68K/English/FileTypes/wmv create mode 100755 scalos/main/envarc/scalos.68K/English/Menu13.prefs create mode 100644 "scalos/main/envarc/scalos.68K/Fran\303\247ais/FileTypes/ILBM" create mode 100755 "scalos/main/envarc/scalos.68K/Fran\303\247ais/FileTypes/appicon" create mode 100755 "scalos/main/envarc/scalos.68K/Fran\303\247ais/FileTypes/archive" create mode 100755 "scalos/main/envarc/scalos.68K/Fran\303\247ais/FileTypes/avi" create mode 100755 "scalos/main/envarc/scalos.68K/Fran\303\247ais/FileTypes/brush" create mode 100755 "scalos/main/envarc/scalos.68K/Fran\303\247ais/FileTypes/disk" create mode 100755 "scalos/main/envarc/scalos.68K/Fran\303\247ais/FileTypes/drawer" create mode 100755 "scalos/main/envarc/scalos.68K/Fran\303\247ais/FileTypes/filearchive" create mode 100755 "scalos/main/envarc/scalos.68K/Fran\303\247ais/FileTypes/gif" create mode 100644 "scalos/main/envarc/scalos.68K/Fran\303\247ais/FileTypes/jpeg" create mode 100755 "scalos/main/envarc/scalos.68K/Fran\303\247ais/FileTypes/mpeg" create mode 100644 "scalos/main/envarc/scalos.68K/Fran\303\247ais/FileTypes/picture" create mode 100644 "scalos/main/envarc/scalos.68K/Fran\303\247ais/FileTypes/png" create mode 100644 "scalos/main/envarc/scalos.68K/Fran\303\247ais/FileTypes/project" create mode 100755 "scalos/main/envarc/scalos.68K/Fran\303\247ais/FileTypes/quicktime" create mode 100644 "scalos/main/envarc/scalos.68K/Fran\303\247ais/FileTypes/tool" create mode 100644 "scalos/main/envarc/scalos.68K/Fran\303\247ais/FileTypes/trashcan" create mode 100755 "scalos/main/envarc/scalos.68K/Fran\303\247ais/FileTypes/video" create mode 100755 "scalos/main/envarc/scalos.68K/Fran\303\247ais/FileTypes/wmv" create mode 100755 "scalos/main/envarc/scalos.68K/Fran\303\247ais/Menu13.prefs" create mode 100755 scalos/main/envarc/scalos.68K/Palette13.prefs create mode 100755 scalos/main/envarc/scalos.68K/Pattern.prefs create mode 100755 scalos/main/envarc/scalos.68K/Persist.prefs create mode 100755 scalos/main/envarc/scalos.68K/icandy create mode 100755 scalos/main/envarc/scalos.68K/scalos.prefs create mode 100755 scalos/main/envarc/scalos.AROS/Deutsch/FileTypes/ILBM create mode 100755 scalos/main/envarc/scalos.AROS/Deutsch/FileTypes/appicon create mode 100755 scalos/main/envarc/scalos.AROS/Deutsch/FileTypes/archive create mode 100755 scalos/main/envarc/scalos.AROS/Deutsch/FileTypes/avi create mode 100755 scalos/main/envarc/scalos.AROS/Deutsch/FileTypes/brush create mode 100755 scalos/main/envarc/scalos.AROS/Deutsch/FileTypes/disk create mode 100755 scalos/main/envarc/scalos.AROS/Deutsch/FileTypes/drawer create mode 100755 scalos/main/envarc/scalos.AROS/Deutsch/FileTypes/filearchive create mode 100755 scalos/main/envarc/scalos.AROS/Deutsch/FileTypes/gif create mode 100755 scalos/main/envarc/scalos.AROS/Deutsch/FileTypes/jpeg create mode 100755 scalos/main/envarc/scalos.AROS/Deutsch/FileTypes/mpeg create mode 100755 scalos/main/envarc/scalos.AROS/Deutsch/FileTypes/picture create mode 100755 scalos/main/envarc/scalos.AROS/Deutsch/FileTypes/png create mode 100755 scalos/main/envarc/scalos.AROS/Deutsch/FileTypes/project create mode 100755 scalos/main/envarc/scalos.AROS/Deutsch/FileTypes/quicktime create mode 100755 scalos/main/envarc/scalos.AROS/Deutsch/FileTypes/tool create mode 100755 scalos/main/envarc/scalos.AROS/Deutsch/FileTypes/trashcan create mode 100755 scalos/main/envarc/scalos.AROS/Deutsch/FileTypes/video create mode 100755 scalos/main/envarc/scalos.AROS/Deutsch/FileTypes/wmv create mode 100755 scalos/main/envarc/scalos.AROS/Deutsch/Menu13.prefs create mode 100755 scalos/main/envarc/scalos.AROS/English/FileTypes/ILBM create mode 100755 scalos/main/envarc/scalos.AROS/English/FileTypes/appicon create mode 100755 scalos/main/envarc/scalos.AROS/English/FileTypes/archive create mode 100755 scalos/main/envarc/scalos.AROS/English/FileTypes/avi create mode 100755 scalos/main/envarc/scalos.AROS/English/FileTypes/brush create mode 100755 scalos/main/envarc/scalos.AROS/English/FileTypes/disk create mode 100755 scalos/main/envarc/scalos.AROS/English/FileTypes/drawer create mode 100755 scalos/main/envarc/scalos.AROS/English/FileTypes/filearchive create mode 100755 scalos/main/envarc/scalos.AROS/English/FileTypes/gif create mode 100755 scalos/main/envarc/scalos.AROS/English/FileTypes/jpeg create mode 100755 scalos/main/envarc/scalos.AROS/English/FileTypes/mpeg create mode 100755 scalos/main/envarc/scalos.AROS/English/FileTypes/picture create mode 100755 scalos/main/envarc/scalos.AROS/English/FileTypes/png create mode 100755 scalos/main/envarc/scalos.AROS/English/FileTypes/project create mode 100755 scalos/main/envarc/scalos.AROS/English/FileTypes/quicktime create mode 100755 scalos/main/envarc/scalos.AROS/English/FileTypes/tool create mode 100755 scalos/main/envarc/scalos.AROS/English/FileTypes/trashcan create mode 100755 scalos/main/envarc/scalos.AROS/English/FileTypes/video create mode 100755 scalos/main/envarc/scalos.AROS/English/FileTypes/wmv create mode 100755 scalos/main/envarc/scalos.AROS/English/Menu13.prefs create mode 100644 "scalos/main/envarc/scalos.AROS/Fran\303\247ais/FileTypes/ILBM" create mode 100755 "scalos/main/envarc/scalos.AROS/Fran\303\247ais/FileTypes/appicon" create mode 100755 "scalos/main/envarc/scalos.AROS/Fran\303\247ais/FileTypes/archive" create mode 100755 "scalos/main/envarc/scalos.AROS/Fran\303\247ais/FileTypes/avi" create mode 100755 "scalos/main/envarc/scalos.AROS/Fran\303\247ais/FileTypes/brush" create mode 100755 "scalos/main/envarc/scalos.AROS/Fran\303\247ais/FileTypes/disk" create mode 100755 "scalos/main/envarc/scalos.AROS/Fran\303\247ais/FileTypes/drawer" create mode 100755 "scalos/main/envarc/scalos.AROS/Fran\303\247ais/FileTypes/filearchive" create mode 100755 "scalos/main/envarc/scalos.AROS/Fran\303\247ais/FileTypes/gif" create mode 100644 "scalos/main/envarc/scalos.AROS/Fran\303\247ais/FileTypes/jpeg" create mode 100755 "scalos/main/envarc/scalos.AROS/Fran\303\247ais/FileTypes/mpeg" create mode 100644 "scalos/main/envarc/scalos.AROS/Fran\303\247ais/FileTypes/picture" create mode 100644 "scalos/main/envarc/scalos.AROS/Fran\303\247ais/FileTypes/png" create mode 100644 "scalos/main/envarc/scalos.AROS/Fran\303\247ais/FileTypes/project" create mode 100755 "scalos/main/envarc/scalos.AROS/Fran\303\247ais/FileTypes/quicktime" create mode 100644 "scalos/main/envarc/scalos.AROS/Fran\303\247ais/FileTypes/tool" create mode 100644 "scalos/main/envarc/scalos.AROS/Fran\303\247ais/FileTypes/trashcan" create mode 100755 "scalos/main/envarc/scalos.AROS/Fran\303\247ais/FileTypes/video" create mode 100755 "scalos/main/envarc/scalos.AROS/Fran\303\247ais/FileTypes/wmv" create mode 100755 "scalos/main/envarc/scalos.AROS/Fran\303\247ais/Menu13.prefs" create mode 100755 scalos/main/envarc/scalos.AROS/Palette13.prefs create mode 100755 scalos/main/envarc/scalos.AROS/Pattern.prefs create mode 100755 scalos/main/envarc/scalos.AROS/Persist.prefs create mode 100755 scalos/main/envarc/scalos.AROS/icandy create mode 100755 scalos/main/envarc/scalos.AROS/scalos.prefs create mode 100755 scalos/main/envarc/scalos.MOS/Deutsch/FileTypes/ILBM create mode 100755 scalos/main/envarc/scalos.MOS/Deutsch/FileTypes/appicon create mode 100755 scalos/main/envarc/scalos.MOS/Deutsch/FileTypes/archive create mode 100755 scalos/main/envarc/scalos.MOS/Deutsch/FileTypes/avi create mode 100755 scalos/main/envarc/scalos.MOS/Deutsch/FileTypes/brush create mode 100755 scalos/main/envarc/scalos.MOS/Deutsch/FileTypes/disk create mode 100755 scalos/main/envarc/scalos.MOS/Deutsch/FileTypes/drawer create mode 100755 scalos/main/envarc/scalos.MOS/Deutsch/FileTypes/filearchive create mode 100755 scalos/main/envarc/scalos.MOS/Deutsch/FileTypes/gif create mode 100755 scalos/main/envarc/scalos.MOS/Deutsch/FileTypes/jpeg create mode 100755 scalos/main/envarc/scalos.MOS/Deutsch/FileTypes/mpeg create mode 100755 scalos/main/envarc/scalos.MOS/Deutsch/FileTypes/picture create mode 100755 scalos/main/envarc/scalos.MOS/Deutsch/FileTypes/png create mode 100755 scalos/main/envarc/scalos.MOS/Deutsch/FileTypes/project create mode 100755 scalos/main/envarc/scalos.MOS/Deutsch/FileTypes/quicktime create mode 100755 scalos/main/envarc/scalos.MOS/Deutsch/FileTypes/tool create mode 100755 scalos/main/envarc/scalos.MOS/Deutsch/FileTypes/trashcan create mode 100755 scalos/main/envarc/scalos.MOS/Deutsch/FileTypes/video create mode 100755 scalos/main/envarc/scalos.MOS/Deutsch/FileTypes/wmv create mode 100755 scalos/main/envarc/scalos.MOS/Deutsch/Menu13.prefs create mode 100755 scalos/main/envarc/scalos.MOS/English/FileTypes/ILBM create mode 100755 scalos/main/envarc/scalos.MOS/English/FileTypes/appicon create mode 100755 scalos/main/envarc/scalos.MOS/English/FileTypes/archive create mode 100755 scalos/main/envarc/scalos.MOS/English/FileTypes/avi create mode 100755 scalos/main/envarc/scalos.MOS/English/FileTypes/brush create mode 100755 scalos/main/envarc/scalos.MOS/English/FileTypes/disk create mode 100755 scalos/main/envarc/scalos.MOS/English/FileTypes/drawer create mode 100755 scalos/main/envarc/scalos.MOS/English/FileTypes/filearchive create mode 100755 scalos/main/envarc/scalos.MOS/English/FileTypes/gif create mode 100755 scalos/main/envarc/scalos.MOS/English/FileTypes/jpeg create mode 100755 scalos/main/envarc/scalos.MOS/English/FileTypes/mpeg create mode 100755 scalos/main/envarc/scalos.MOS/English/FileTypes/picture create mode 100755 scalos/main/envarc/scalos.MOS/English/FileTypes/png create mode 100755 scalos/main/envarc/scalos.MOS/English/FileTypes/project create mode 100755 scalos/main/envarc/scalos.MOS/English/FileTypes/quicktime create mode 100755 scalos/main/envarc/scalos.MOS/English/FileTypes/tool create mode 100755 scalos/main/envarc/scalos.MOS/English/FileTypes/trashcan create mode 100755 scalos/main/envarc/scalos.MOS/English/FileTypes/video create mode 100755 scalos/main/envarc/scalos.MOS/English/FileTypes/wmv create mode 100755 scalos/main/envarc/scalos.MOS/English/Menu13.prefs create mode 100644 "scalos/main/envarc/scalos.MOS/Fran\303\247ais/FileTypes/ILBM" create mode 100755 "scalos/main/envarc/scalos.MOS/Fran\303\247ais/FileTypes/appicon" create mode 100755 "scalos/main/envarc/scalos.MOS/Fran\303\247ais/FileTypes/archive" create mode 100755 "scalos/main/envarc/scalos.MOS/Fran\303\247ais/FileTypes/avi" create mode 100755 "scalos/main/envarc/scalos.MOS/Fran\303\247ais/FileTypes/brush" create mode 100755 "scalos/main/envarc/scalos.MOS/Fran\303\247ais/FileTypes/disk" create mode 100755 "scalos/main/envarc/scalos.MOS/Fran\303\247ais/FileTypes/drawer" create mode 100755 "scalos/main/envarc/scalos.MOS/Fran\303\247ais/FileTypes/filearchive" create mode 100755 "scalos/main/envarc/scalos.MOS/Fran\303\247ais/FileTypes/gif" create mode 100644 "scalos/main/envarc/scalos.MOS/Fran\303\247ais/FileTypes/jpeg" create mode 100755 "scalos/main/envarc/scalos.MOS/Fran\303\247ais/FileTypes/mpeg" create mode 100644 "scalos/main/envarc/scalos.MOS/Fran\303\247ais/FileTypes/picture" create mode 100644 "scalos/main/envarc/scalos.MOS/Fran\303\247ais/FileTypes/png" create mode 100644 "scalos/main/envarc/scalos.MOS/Fran\303\247ais/FileTypes/project" create mode 100755 "scalos/main/envarc/scalos.MOS/Fran\303\247ais/FileTypes/quicktime" create mode 100644 "scalos/main/envarc/scalos.MOS/Fran\303\247ais/FileTypes/tool" create mode 100644 "scalos/main/envarc/scalos.MOS/Fran\303\247ais/FileTypes/trashcan" create mode 100755 "scalos/main/envarc/scalos.MOS/Fran\303\247ais/FileTypes/video" create mode 100755 "scalos/main/envarc/scalos.MOS/Fran\303\247ais/FileTypes/wmv" create mode 100755 "scalos/main/envarc/scalos.MOS/Fran\303\247ais/Menu13.prefs" create mode 100755 scalos/main/envarc/scalos.MOS/Palette13.prefs create mode 100755 scalos/main/envarc/scalos.MOS/Pattern.prefs create mode 100755 scalos/main/envarc/scalos.MOS/Persist.prefs create mode 100755 scalos/main/envarc/scalos.MOS/icandy create mode 100755 scalos/main/envarc/scalos.MOS/scalos.prefs create mode 100755 scalos/main/envarc/scalos.OS4/Deutsch/FileTypes/ILBM create mode 100755 scalos/main/envarc/scalos.OS4/Deutsch/FileTypes/appicon create mode 100755 scalos/main/envarc/scalos.OS4/Deutsch/FileTypes/archive create mode 100755 scalos/main/envarc/scalos.OS4/Deutsch/FileTypes/avi create mode 100755 scalos/main/envarc/scalos.OS4/Deutsch/FileTypes/brush create mode 100755 scalos/main/envarc/scalos.OS4/Deutsch/FileTypes/disk create mode 100755 scalos/main/envarc/scalos.OS4/Deutsch/FileTypes/drawer create mode 100755 scalos/main/envarc/scalos.OS4/Deutsch/FileTypes/filearchive create mode 100755 scalos/main/envarc/scalos.OS4/Deutsch/FileTypes/gif create mode 100755 scalos/main/envarc/scalos.OS4/Deutsch/FileTypes/jpeg create mode 100755 scalos/main/envarc/scalos.OS4/Deutsch/FileTypes/mpeg create mode 100755 scalos/main/envarc/scalos.OS4/Deutsch/FileTypes/picture create mode 100755 scalos/main/envarc/scalos.OS4/Deutsch/FileTypes/png create mode 100755 scalos/main/envarc/scalos.OS4/Deutsch/FileTypes/project create mode 100755 scalos/main/envarc/scalos.OS4/Deutsch/FileTypes/quicktime create mode 100755 scalos/main/envarc/scalos.OS4/Deutsch/FileTypes/tool create mode 100755 scalos/main/envarc/scalos.OS4/Deutsch/FileTypes/trashcan create mode 100755 scalos/main/envarc/scalos.OS4/Deutsch/FileTypes/video create mode 100755 scalos/main/envarc/scalos.OS4/Deutsch/FileTypes/wmv create mode 100755 scalos/main/envarc/scalos.OS4/Deutsch/Menu13.prefs create mode 100755 scalos/main/envarc/scalos.OS4/English/FileTypes/ILBM create mode 100755 scalos/main/envarc/scalos.OS4/English/FileTypes/appicon create mode 100755 scalos/main/envarc/scalos.OS4/English/FileTypes/archive create mode 100755 scalos/main/envarc/scalos.OS4/English/FileTypes/avi create mode 100755 scalos/main/envarc/scalos.OS4/English/FileTypes/brush create mode 100755 scalos/main/envarc/scalos.OS4/English/FileTypes/disk create mode 100755 scalos/main/envarc/scalos.OS4/English/FileTypes/drawer create mode 100755 scalos/main/envarc/scalos.OS4/English/FileTypes/filearchive create mode 100755 scalos/main/envarc/scalos.OS4/English/FileTypes/gif create mode 100755 scalos/main/envarc/scalos.OS4/English/FileTypes/jpeg create mode 100755 scalos/main/envarc/scalos.OS4/English/FileTypes/mpeg create mode 100755 scalos/main/envarc/scalos.OS4/English/FileTypes/picture create mode 100755 scalos/main/envarc/scalos.OS4/English/FileTypes/png create mode 100755 scalos/main/envarc/scalos.OS4/English/FileTypes/project create mode 100755 scalos/main/envarc/scalos.OS4/English/FileTypes/quicktime create mode 100755 scalos/main/envarc/scalos.OS4/English/FileTypes/tool create mode 100755 scalos/main/envarc/scalos.OS4/English/FileTypes/trashcan create mode 100755 scalos/main/envarc/scalos.OS4/English/FileTypes/video create mode 100755 scalos/main/envarc/scalos.OS4/English/FileTypes/wmv create mode 100755 scalos/main/envarc/scalos.OS4/English/Menu13.prefs create mode 100644 "scalos/main/envarc/scalos.OS4/Fran\303\247ais/FileTypes/ILBM" create mode 100755 "scalos/main/envarc/scalos.OS4/Fran\303\247ais/FileTypes/appicon" create mode 100755 "scalos/main/envarc/scalos.OS4/Fran\303\247ais/FileTypes/archive" create mode 100755 "scalos/main/envarc/scalos.OS4/Fran\303\247ais/FileTypes/avi" create mode 100755 "scalos/main/envarc/scalos.OS4/Fran\303\247ais/FileTypes/brush" create mode 100755 "scalos/main/envarc/scalos.OS4/Fran\303\247ais/FileTypes/disk" create mode 100755 "scalos/main/envarc/scalos.OS4/Fran\303\247ais/FileTypes/drawer" create mode 100755 "scalos/main/envarc/scalos.OS4/Fran\303\247ais/FileTypes/filearchive" create mode 100755 "scalos/main/envarc/scalos.OS4/Fran\303\247ais/FileTypes/gif" create mode 100644 "scalos/main/envarc/scalos.OS4/Fran\303\247ais/FileTypes/jpeg" create mode 100755 "scalos/main/envarc/scalos.OS4/Fran\303\247ais/FileTypes/mpeg" create mode 100644 "scalos/main/envarc/scalos.OS4/Fran\303\247ais/FileTypes/picture" create mode 100644 "scalos/main/envarc/scalos.OS4/Fran\303\247ais/FileTypes/png" create mode 100644 "scalos/main/envarc/scalos.OS4/Fran\303\247ais/FileTypes/project" create mode 100755 "scalos/main/envarc/scalos.OS4/Fran\303\247ais/FileTypes/quicktime" create mode 100644 "scalos/main/envarc/scalos.OS4/Fran\303\247ais/FileTypes/tool" create mode 100644 "scalos/main/envarc/scalos.OS4/Fran\303\247ais/FileTypes/trashcan" create mode 100755 "scalos/main/envarc/scalos.OS4/Fran\303\247ais/FileTypes/video" create mode 100755 "scalos/main/envarc/scalos.OS4/Fran\303\247ais/FileTypes/wmv" create mode 100755 "scalos/main/envarc/scalos.OS4/Fran\303\247ais/Menu13.prefs" create mode 100755 scalos/main/envarc/scalos.OS4/Palette13.prefs create mode 100755 scalos/main/envarc/scalos.OS4/Pattern.prefs create mode 100755 scalos/main/envarc/scalos.OS4/Persist.prefs create mode 100755 scalos/main/envarc/scalos.OS4/icandy create mode 100755 scalos/main/envarc/scalos.OS4/scalos.prefs create mode 100644 scalos/main/filetypes.c create mode 100755 scalos/main/functions.h create mode 100755 scalos/main/idcmp.c create mode 100755 scalos/main/locale.h create mode 100755 scalos/main/makefile create mode 100755 scalos/main/makefile-new create mode 100644 scalos/main/scalos-aos4-68kstubs.c create mode 100755 scalos/main/scalos_structures.h create mode 100755 scalos/main/std_includes/E/Examples/Bonus/sthex create mode 100644 scalos/main/std_includes/E/Examples/Bonus/sthex.readme create mode 100755 scalos/main/std_includes/E/Examples/LoadExample.e create mode 100755 scalos/main/std_includes/E/Examples/LoadSaveExample.e create mode 100755 scalos/main/std_includes/E/Examples/OneTag/ExampleOneTag.prefs create mode 100755 scalos/main/std_includes/E/Examples/OneTag/MakePrefsTag.e create mode 100755 scalos/main/std_includes/E/Examples/OneTag/ReadPrefsTag.e create mode 100755 scalos/main/std_includes/E/Examples/TwoTags/ExampleTags.prefs create mode 100755 scalos/main/std_includes/E/Examples/TwoTags/MakePrefsTags.e create mode 100755 scalos/main/std_includes/E/Examples/TwoTags/ReadPrefsTags.e create mode 100755 scalos/main/std_includes/E/Examples/example.prefs create mode 100644 scalos/main/std_includes/E/Extras/CommentMUI/Comment.module.e create mode 100644 scalos/main/std_includes/E/Extras/CommentMUI/Scalos_Comment_Locale.e create mode 100755 scalos/main/std_includes/E/Extras/CommentMUI/commodule.m create mode 100755 scalos/main/std_includes/E/Extras/CommentMUI/getpath.m create mode 100755 scalos/main/std_includes/E/Extras/CommentMUI/scalos_comment_locale.m create mode 100755 scalos/main/std_includes/E/Extras/CommentMUI/verstag.m create mode 100755 scalos/main/std_includes/E/Extras/CreateTrash/CreateTrash.e create mode 100755 scalos/main/std_includes/E/Extras/CreateTrash/mod.m create mode 100755 scalos/main/std_includes/E/Extras/OpenDrawer/MOS/OpenDrawer_41.5_mos.e create mode 100755 scalos/main/std_includes/E/Extras/OpenDrawer/MOS/VERSTAG.e create mode 100755 scalos/main/std_includes/E/Extras/OpenDrawer/MOS/verstag.m create mode 100755 scalos/main/std_includes/E/Extras/OpenDrawer/OpenDrawer.e create mode 100755 scalos/main/std_includes/E/Extras/OpenDrawer/VERSTAG.e create mode 100755 scalos/main/std_includes/E/Extras/OpenDrawer/verstag.m create mode 100755 scalos/main/std_includes/E/modules/Scalos/gadgetbar.m create mode 100755 scalos/main/std_includes/E/modules/Scalos/iconobject.m create mode 100755 scalos/main/std_includes/E/modules/Scalos/mcpgfx.m create mode 100755 scalos/main/std_includes/E/modules/Scalos/menu.m create mode 100755 scalos/main/std_includes/E/modules/Scalos/preferences_struct.e create mode 100755 scalos/main/std_includes/E/modules/Scalos/preferences_struct.m create mode 100755 scalos/main/std_includes/E/modules/Scalos/scalos.e create mode 100755 scalos/main/std_includes/E/modules/Scalos/scalos.m create mode 100755 scalos/main/std_includes/E/modules/Scalos/scalos.m.txt create mode 100755 scalos/main/std_includes/E/modules/Scalos/scalos41.6.e create mode 100755 scalos/main/std_includes/E/modules/Scalos/scalos41.6.m create mode 100755 scalos/main/std_includes/E/modules/Scalos/scalosfiletypeplugin.m create mode 100755 scalos/main/std_includes/E/modules/Scalos/scalosgfx_struct.m create mode 100755 scalos/main/std_includes/E/modules/Scalos/scalosmenuplugin.m create mode 100755 scalos/main/std_includes/E/modules/Scalos/scalosmenuprefsplugin.e create mode 100755 scalos/main/std_includes/E/modules/Scalos/scalosmenuprefsplugin.m create mode 100755 scalos/main/std_includes/E/modules/Scalos/scalospatternprefsplugin.m create mode 100755 scalos/main/std_includes/E/modules/Scalos/scalosplugin.m create mode 100755 scalos/main/std_includes/E/modules/Scalos/scalosprefs.m create mode 100755 scalos/main/std_includes/E/modules/Scalos/scalosprefsplugin.e create mode 100755 scalos/main/std_includes/E/modules/Scalos/scalosprefsplugin.m create mode 100755 scalos/main/std_includes/E/modules/cybergraphics.m create mode 100755 scalos/main/std_includes/E/modules/guigfx.m create mode 100644 scalos/main/std_includes/E/modules/jmc/GetIconObject.e create mode 100644 scalos/main/std_includes/E/modules/jmc/MyDebugOnOff.e create mode 100755 scalos/main/std_includes/E/modules/jmc/geticonobject.m create mode 100755 scalos/main/std_includes/E/modules/jmc/mydebugonoff.m create mode 100755 scalos/main/std_includes/E/modules/preferences.m create mode 100755 scalos/main/std_includes/E/modules/scalos.m create mode 100755 scalos/main/std_includes/E/modules/scalosgfx.m create mode 100755 scalos/main/std_includes/E/modules/sqlite3.m create mode 100755 scalos/main/std_includes/asm/CyberGraphX/cybergraphics.i create mode 100755 scalos/main/std_includes/asm/Scalos/iconobject.i create mode 100755 scalos/main/std_includes/asm/Scalos/palette.i create mode 100755 scalos/main/std_includes/asm/Scalos/pattern.i create mode 100755 scalos/main/std_includes/asm/Scalos/preferences.i create mode 100755 scalos/main/std_includes/asm/Scalos/scalos.i create mode 100755 scalos/main/std_includes/asm/Scalos/undo.i create mode 100755 scalos/main/std_includes/asm/asmsupp.i create mode 100644 scalos/main/std_includes/asm/datatypes/pictureclass.i create mode 100644 scalos/main/std_includes/asm/devices/printer.i create mode 100644 scalos/main/std_includes/asm/libraries/mcpgfx.i create mode 100755 scalos/main/std_includes/asm/libraries/mui_asmone.i create mode 100755 scalos/main/std_includes/asm/libraries/pm.i create mode 100755 scalos/main/std_includes/asm/lvo/cybergraphics_lib.i create mode 100644 scalos/main/std_includes/asm/lvo/dtlib_lib.i create mode 100755 scalos/main/std_includes/asm/lvo/guigfx_lib.i create mode 100755 scalos/main/std_includes/asm/lvo/iconobject_lib.i create mode 100755 scalos/main/std_includes/asm/lvo/mcpgfx_lib.i create mode 100644 scalos/main/std_includes/asm/lvo/newicon_lib.i create mode 100644 scalos/main/std_includes/asm/lvo/openurl_lib.i create mode 100755 scalos/main/std_includes/asm/lvo/pm_lib.i create mode 100755 scalos/main/std_includes/asm/lvo/preferences_lib.i create mode 100755 scalos/main/std_includes/asm/lvo/scalos_lib.i create mode 100755 scalos/main/std_includes/asm/lvo/scalosfiletypeplugin_lib.i create mode 100755 scalos/main/std_includes/asm/lvo/scalosgfx_lib.i create mode 100755 scalos/main/std_includes/asm/lvo/scalosmenuplugin_lib.i create mode 100755 scalos/main/std_includes/asm/lvo/scalosplugin_lib.i create mode 100755 scalos/main/std_includes/asm/lvo/scalosprefsplugin_lib.i create mode 100644 scalos/main/std_includes/asm/lvo/scalospreviewplugin_lib.i create mode 100755 scalos/main/std_includes/asm/lvo/sqlite3_lib.i create mode 100755 scalos/main/std_includes/asm/mui/NList_mcc.i create mode 100755 scalos/main/std_includes/asm/mui/NListview_mcc.i create mode 100755 scalos/main/std_includes/asm/mui/listtree_mui.i create mode 100755 scalos/main/std_includes/asm/mui_asmone.i create mode 100644 scalos/main/std_includes/asm/workbench/workbench.i create mode 100755 scalos/main/std_includes/fd/cybergraphics_lib.fd create mode 100755 scalos/main/std_includes/fd/guigfx_lib.fd create mode 100755 scalos/main/std_includes/fd/iconobject_lib.fd create mode 100755 scalos/main/std_includes/fd/mcpgfx_lib.fd create mode 100755 scalos/main/std_includes/fd/openurl_lib.fd create mode 100755 scalos/main/std_includes/fd/pm_lib.fd create mode 100755 scalos/main/std_includes/fd/preferences_lib.fd create mode 100755 scalos/main/std_includes/fd/scalos_lib.fd create mode 100755 scalos/main/std_includes/fd/scalosfiletypeplugin_lib.fd create mode 100755 scalos/main/std_includes/fd/scalosgfx_lib.fd create mode 100755 scalos/main/std_includes/fd/scalosmenuplugin_lib.fd create mode 100755 scalos/main/std_includes/fd/scalosplugin_lib.fd create mode 100755 scalos/main/std_includes/fd/scalosprefsplugin_lib.fd create mode 100755 scalos/main/std_includes/fd/scalospreviewplugin_lib.fd create mode 100755 scalos/main/std_includes/fd/sqlite3_lib.fd create mode 100644 scalos/main/std_includes/interfaces/config.mk create mode 100755 scalos/main/std_includes/interfaces/cybergraphics.xml create mode 100644 scalos/main/std_includes/interfaces/guigfx.xml create mode 100644 scalos/main/std_includes/interfaces/iconobject.xml create mode 100644 scalos/main/std_includes/interfaces/makefile-new create mode 100644 scalos/main/std_includes/interfaces/pm.xml create mode 100644 scalos/main/std_includes/interfaces/preferences.xml create mode 100644 scalos/main/std_includes/interfaces/rules.mk create mode 100755 scalos/main/std_includes/interfaces/scalos.xml create mode 100644 scalos/main/std_includes/interfaces/scalosfiletypeplugin.xml create mode 100755 scalos/main/std_includes/interfaces/scalosgfx.xml create mode 100644 scalos/main/std_includes/interfaces/scalosmenuplugin.xml create mode 100644 scalos/main/std_includes/interfaces/scalosplugin.xml create mode 100755 scalos/main/std_includes/interfaces/scalosprefsplugin.xml create mode 100644 scalos/main/std_includes/interfaces/scalospreviewplugin.xml create mode 100644 scalos/main/std_includes/interfaces/sqlite3.xml create mode 100755 scalos/main/std_includes/sfd/FD/cybergraphics_lib.fd create mode 100755 scalos/main/std_includes/sfd/FD/dtlib_lib.fd create mode 100755 scalos/main/std_includes/sfd/FD/guigfx_lib.fd create mode 100755 scalos/main/std_includes/sfd/FD/iconobject_lib.fd create mode 100755 scalos/main/std_includes/sfd/FD/mcpgfx_lib.fd create mode 100755 scalos/main/std_includes/sfd/FD/newicon_lib.fd create mode 100755 scalos/main/std_includes/sfd/FD/openurl_lib.fd create mode 100755 scalos/main/std_includes/sfd/FD/pm_lib.fd create mode 100755 scalos/main/std_includes/sfd/FD/preferences_lib.fd create mode 100755 scalos/main/std_includes/sfd/FD/scalos_lib.fd create mode 100755 scalos/main/std_includes/sfd/FD/scalosfiletypeplugin_lib.fd create mode 100755 scalos/main/std_includes/sfd/FD/scalosgfx_lib.fd create mode 100755 scalos/main/std_includes/sfd/FD/scalosmenuplugin_lib.fd create mode 100755 scalos/main/std_includes/sfd/FD/scalosplugin_lib.fd create mode 100755 scalos/main/std_includes/sfd/FD/scalosprefsplugin_lib.fd create mode 100755 scalos/main/std_includes/sfd/FD/scalospreviewplugin_lib.fd create mode 100755 scalos/main/std_includes/sfd/FD/sqlite3_lib.fd create mode 100644 scalos/main/std_includes/sfd/LVO/cybergraphics_lib.asm create mode 100644 scalos/main/std_includes/sfd/LVO/dtlib_lib.asm create mode 100644 scalos/main/std_includes/sfd/LVO/guigfx_lib.asm create mode 100644 scalos/main/std_includes/sfd/LVO/iconobject_lib.asm create mode 100644 scalos/main/std_includes/sfd/LVO/mcpgfx_lib.asm create mode 100644 scalos/main/std_includes/sfd/LVO/newicon_lib.asm create mode 100644 scalos/main/std_includes/sfd/LVO/openurl_lib.asm create mode 100644 scalos/main/std_includes/sfd/LVO/pm_lib.asm create mode 100644 scalos/main/std_includes/sfd/LVO/preferences_lib.asm create mode 100644 scalos/main/std_includes/sfd/LVO/scalos_lib.asm create mode 100644 scalos/main/std_includes/sfd/LVO/scalosfiletypeplugin_lib.asm create mode 100644 scalos/main/std_includes/sfd/LVO/scalosgfx_lib.asm create mode 100644 scalos/main/std_includes/sfd/LVO/scalosmenuplugin_lib.asm create mode 100644 scalos/main/std_includes/sfd/LVO/scalosplugin_lib.asm create mode 100644 scalos/main/std_includes/sfd/LVO/scalosprefsplugin_lib.asm create mode 100644 scalos/main/std_includes/sfd/LVO/scalospreviewplugin_lib.asm create mode 100644 scalos/main/std_includes/sfd/LVO/sqlite3_lib.asm create mode 100755 scalos/main/std_includes/sfd/PRAGMAS/cybergraphics_pragmas.h create mode 100755 scalos/main/std_includes/sfd/PRAGMAS/dtlib_pragmas.h create mode 100755 scalos/main/std_includes/sfd/PRAGMAS/guigfx_pragmas.h create mode 100755 scalos/main/std_includes/sfd/PRAGMAS/iconobject_pragmas.h create mode 100755 scalos/main/std_includes/sfd/PRAGMAS/mcpgfx_pragmas.h create mode 100755 scalos/main/std_includes/sfd/PRAGMAS/newicon_pragmas.h create mode 100755 scalos/main/std_includes/sfd/PRAGMAS/openurl_pragmas.h create mode 100755 scalos/main/std_includes/sfd/PRAGMAS/pm_pragmas.h create mode 100755 scalos/main/std_includes/sfd/PRAGMAS/preferences_pragmas.h create mode 100755 scalos/main/std_includes/sfd/PRAGMAS/scalos_pragmas.h create mode 100755 scalos/main/std_includes/sfd/PRAGMAS/scalosfiletypeplugin_pragmas.h create mode 100755 scalos/main/std_includes/sfd/PRAGMAS/scalosgfx_pragmas.h create mode 100755 scalos/main/std_includes/sfd/PRAGMAS/scalosmenuplugin_pragmas.h create mode 100755 scalos/main/std_includes/sfd/PRAGMAS/scalosplugin_pragmas.h create mode 100755 scalos/main/std_includes/sfd/PRAGMAS/scalosprefsplugin_pragmas.h create mode 100755 scalos/main/std_includes/sfd/PRAGMAS/scalospreviewplugin_pragmas.h create mode 100755 scalos/main/std_includes/sfd/PRAGMAS/sqlite3_pragmas.h create mode 100755 scalos/main/std_includes/sfd/PROTOS/cybergraphics_protos.h create mode 100755 scalos/main/std_includes/sfd/PROTOS/dtlib_protos.h create mode 100755 scalos/main/std_includes/sfd/PROTOS/guigfx_protos.h create mode 100755 scalos/main/std_includes/sfd/PROTOS/iconobject_protos.h create mode 100755 scalos/main/std_includes/sfd/PROTOS/mcpgfx_protos.h create mode 100755 scalos/main/std_includes/sfd/PROTOS/newicon_protos.h create mode 100755 scalos/main/std_includes/sfd/PROTOS/openurl_protos.h create mode 100755 scalos/main/std_includes/sfd/PROTOS/pm_protos.h create mode 100755 scalos/main/std_includes/sfd/PROTOS/preferences_protos.h create mode 100755 scalos/main/std_includes/sfd/PROTOS/scalos_protos.h create mode 100755 scalos/main/std_includes/sfd/PROTOS/scalosfiletypeplugin_protos.h create mode 100755 scalos/main/std_includes/sfd/PROTOS/scalosgfx_protos.h create mode 100755 scalos/main/std_includes/sfd/PROTOS/scalosmenuplugin_protos.h create mode 100755 scalos/main/std_includes/sfd/PROTOS/scalosplugin_protos.h create mode 100755 scalos/main/std_includes/sfd/PROTOS/scalosprefsplugin_protos.h create mode 100755 scalos/main/std_includes/sfd/PROTOS/scalospreviewplugin_protos.h create mode 100755 scalos/main/std_includes/sfd/PROTOS/sqlite3_protos.h create mode 100644 scalos/main/std_includes/sfd/cybergraphics_lib.sfd create mode 100755 scalos/main/std_includes/sfd/dtlib_lib.sfd create mode 100755 scalos/main/std_includes/sfd/guigfx_lib.sfd create mode 100755 scalos/main/std_includes/sfd/iconobject_lib.sfd create mode 100755 scalos/main/std_includes/sfd/include/inline4/cybergraphics.h create mode 100644 scalos/main/std_includes/sfd/include/inline4/guigfx.h create mode 100755 scalos/main/std_includes/sfd/include/inline4/scalos.h create mode 100755 scalos/main/std_includes/sfd/include/inline4/scalosgfx.h create mode 100644 scalos/main/std_includes/sfd/include/inline4/scalosplugin.h create mode 100755 scalos/main/std_includes/sfd/include/inline4/sqlite3.h create mode 100755 scalos/main/std_includes/sfd/include/interfaces/cybergraphics.h create mode 100644 scalos/main/std_includes/sfd/include/interfaces/guigfx.h create mode 100755 scalos/main/std_includes/sfd/include/interfaces/scalos.h create mode 100755 scalos/main/std_includes/sfd/include/interfaces/scalosgfx.h create mode 100644 scalos/main/std_includes/sfd/include/interfaces/scalosplugin.h create mode 100755 scalos/main/std_includes/sfd/include/interfaces/sqlite3.h create mode 100644 scalos/main/std_includes/sfd/makefile create mode 100644 scalos/main/std_includes/sfd/mcpgfx_lib.sfd create mode 100644 scalos/main/std_includes/sfd/newicon_lib.sfd create mode 100644 scalos/main/std_includes/sfd/openurl_lib.sfd create mode 100755 scalos/main/std_includes/sfd/pm_lib.sfd create mode 100644 scalos/main/std_includes/sfd/preferences_lib.sfd create mode 100755 scalos/main/std_includes/sfd/scalos_lib.sfd create mode 100755 scalos/main/std_includes/sfd/scalosfiletypeplugin_lib.sfd create mode 100644 scalos/main/std_includes/sfd/scalosgfx_lib.sfd create mode 100755 scalos/main/std_includes/sfd/scalosmenuplugin_lib.sfd create mode 100755 scalos/main/std_includes/sfd/scalosplugin_lib.sfd create mode 100755 scalos/main/std_includes/sfd/scalosprefsplugin_lib.sfd create mode 100755 scalos/main/std_includes/sfd/scalospreviewplugin_lib.sfd create mode 100755 scalos/main/std_includes/sfd/sqlite3_lib.sfd create mode 100644 scalos/main/wbl.c create mode 100755 scalos/main/windowtask.c create mode 100644 scalos/makefile create mode 100755 scalos/makefile-new create mode 100644 scalos/msgidnames.sd create mode 100644 scalos/readme.txt create mode 100755 scalos/rules.mk create mode 100755 scalos/tools/fixdeps create mode 100755 scalos/translation diff --git a/scalos/BuildArchive b/scalos/BuildArchive new file mode 100755 index 000000000..9d37b8484 --- /dev/null +++ b/scalos/BuildArchive @@ -0,0 +1,17 @@ +/* BuildArchive */ +/* 02 Jan 2004 12:27:31 */ +/* $Date: 2009-03-12 21:26:11 +0100 (Do, 12. Mär 2009) $ */ +/* $Revision: */ +/* $Id: BuildArchive 93 2009-03-12 20:26:11Z jlachmann $ */ + +LHAName = '../Reserve/Scalos_' + +LHAName = LHAName || date("s") || '.tar.gz' + +say LHAName + +address command + +'tar -cvz -X ExcludeList -f ' || LHAName || ' #?' + +'tar -tzf ' || LHAName || ' #?' diff --git a/scalos/CatComp_h.sd b/scalos/CatComp_h.sd new file mode 100644 index 000000000..ed423f9c6 --- /dev/null +++ b/scalos/CatComp_h.sd @@ -0,0 +1,167 @@ +##rem $Id: CatComp_h.sd 79 2007-01-01 11:45:21Z tactica $ +##stringtype C +##shortstrings + +/**************************************************************** + + This file was created automatically by `%fv' + from "%f0" + + using CatComp.sd 1.2 (24.09.1999) + + Do NOT edit by hand! + +****************************************************************/ + +#ifndef %b_STRINGS_H +#define %b_STRINGS_H + +#ifndef EXEC_TYPES_H +#include +#endif + +#ifdef %b_BASIC_CODE +#undef %b_BASIC +#undef %b_CODE +#define %b_BASIC +#define %b_CODE +#endif + +#ifdef %b_BASIC +#undef %b_ARRAY +#undef %b_BLOCK +#define %b_ARRAY +#define %b_BLOCK +#endif + +#ifdef %b_ARRAY +#undef %b_NUMBERS +#undef %b_STRINGS +#define %b_NUMBERS +#define %b_STRINGS +#endif + +#ifdef %b_BLOCK +#undef %b_STRINGS +#define %b_STRINGS +#endif + + +#ifdef %b_NUMBERS + +#define %i %d + +#endif /* %b_NUMBERS */ + + +/****************************************************************************/ + + +#ifdef %b_STRINGS + +#define %i_STR %s + +#endif /* %b_STRINGS */ + + +/****************************************************************************/ + + +#ifdef %b_ARRAY + +struct %b_ArrayType +{ + LONG cca_ID; + CONST_STRPTR cca_Str; +}; + +static const struct %b_ArrayType %b_Array[] = +{ + { %i, %i_STR }, +}; + + +#endif /* %b_ARRAY */ + + +/****************************************************************************/ + + +#ifdef %b_BLOCK + +static const char %b_Block[] = +{ + + "%4a" "%2t"\n %i_STR "%z" + +}; + +#endif /* %b_BLOCK */ + + +/****************************************************************************/ + + +#ifdef %b_CODE + +#ifndef PROTO_LOCALE_H +#define __NOLIBBASE__ +#define __NOGLOBALIFACE__ +#include +#endif + +#ifndef %b_CODE_EXISTS + #define %b_CODE_EXISTS + +CONST_STRPTR Get%bString(struct %b_LocaleInfo *li, LONG stringNum) +{ +#ifndef __amigaos4__ + struct Library *LocaleBase = li->li_LocaleBase; +#else + struct LocaleIFace *ILocale = li->li_ILocale; +#endif + + CONST_STRPTR builtIn = ""; + ULONG n; + + for (n = 0; n < sizeof(%b_Array) / sizeof(%b_Array[0]); n++) + { + if (%b_Array[n].cca_ID == stringNum) + { + builtIn = %b_Array[n].cca_Str; + break; + } + } + +#ifndef __amigaos4__ + if (LocaleBase) + { + return GetCatalogStr(li->li_Catalog, stringNum, (STRPTR)builtIn); + } +#else + if (ILocale) + { +#ifdef __USE_INLINE__ + return GetCatalogStr(li->li_Catalog, stringNum, (STRPTR)builtIn); +#else + return ILocale->GetCatalogStr(li->li_Catalog, stringNum, (STRPTR)builtIn); +#endif + } +#endif + + return builtIn; +} + +#else + +STRPTR Get%bString(struct %b_LocaleInfo *li, LONG stringNum); + +#endif /* %b_CODE_EXISTS */ + +#endif /* %b_CODE */ + + +/****************************************************************************/ + + +#endif /* %b_STRINGS_H */ diff --git a/scalos/Default_Theme/About/Backfill b/scalos/Default_Theme/About/Backfill new file mode 100755 index 0000000000000000000000000000000000000000..5c3cff20e4432fe077f7074222b4806d6650795a GIT binary patch literal 2196 zcwUuMdpOe#8~%-9%*rM)XKTImI&Mypwbv;`PH#>nzA)t+kwi&fZ#kvR`M7jI6xmx7 z%_cF1M4Ozg=CI4&95zXaz25%#zU%t_`|juYk*BLJ^^yak2xI!Kp+4B z?G_-K0Biw>q@Kz4U71{a3|cwqBuMEaxR ziR5q*aCP=*niGPC{wmc>Q@Q0o>cfR9F3c!o;GWbjj8t!J9vvI+nfkyy4LSv#F}s=I z*yru7k*;F#$>`jZmB(rg?PSxjp|x*x3zY-%(a)v=SeYW=nh^vsJiiqYPojkSMkxR+6l__fLe-=V&(rAY!?)0s2ISpx~Z*zgmh)QlGKyh2g+ZX1XJ`5Dv~@L=i5A6m<0IxSCSi@g3tVb zIqI?E8$f_wQ)@i5-|NN9m&6=cXNVm4^yQj2!yNy$>s~!UD`!N26rR}|>)?K`!(BHk z=I*uUdE%a!k|#>Jwuy<0!X7YEA4ePeSGc3hn7V}$g2$gL9ja&lA=4RtHlafVP^E2C zGMHS->KLzdStf``(&bm?WWxD zF@h4eEF>{M7%HtbGP*30rzBraEDcFcS0eZjRSV6NQW z5nkyyIU6F({^Qs899~+OvN0>W1iQD3(%4uDIC~^B)v!F|PGs!`>%$C@ry4%=S)-T3RwDQsUO&n%G%o+omTVH3yW>4?ikmpGEGOpy4Q_FT_WF&%icbD-Bu_Fq2(4eRwZX$uj-!2#w`p}X7Ni7|Jy`}**oXVA9n?ht4SS2} zlwgX`rtAA?RJ+-pN)g7)i#zEtTWo3WwE(U^Q#{hP|430t+tVvN}JSF@xFz2(D+$FJ=zBv&<`|eOS;eiqXr`jiN>?fl+svBE`+GA=TwMlMeg6Wlz2zQ_lXii$E@#Nav;SMx1WzlG*_P8 zsNW{X&)NZo>5Oep`dTqNm4B%hv17WB#GiEec*kySe{4#Y?fRS1?)!M*s>9NsuW_2? zl)UWsF1J^H?Edz#-dIA-O3D4zcOI)77)FMg}_fj-3dVFp&(2uBj(wn6C zrfhQXig)NB>grC(Wf=M1g{n7keXvdXTb32h{w}fJtVb622AdK^+iwH-k8Q$`-Rp?;<+7?rC&11&d$m2_+h0k=M>gX2gv;Xl-zG)tjQW=vG;nK fQP<$qer4j|5_CqdN!6R6eQ`C0O71hki^l#2O78iH literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/About/ButtonFlushDisabled b/scalos/Default_Theme/About/ButtonFlushDisabled new file mode 100755 index 0000000000000000000000000000000000000000..902bf98cf6f3a860ce09035b455ef591cfdc3e79 GIT binary patch literal 4249 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 literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/About/ButtonFlushNormal b/scalos/Default_Theme/About/ButtonFlushNormal new file mode 100755 index 0000000000000000000000000000000000000000..13bb8bd3867a84a7346fc85dcb0dfdfae33c6ea8 GIT binary patch literal 4215 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 N002ovPDHLkV1gIT){X!G literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/About/ButtonFlushSelected b/scalos/Default_Theme/About/ButtonFlushSelected new file mode 100755 index 0000000000000000000000000000000000000000..ca5de8f0ea55a311cad3f7d192dac0c9a4a34e5c GIT binary patch literal 4517 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 D3;>6! literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/About/ButtonInfoDisabled b/scalos/Default_Theme/About/ButtonInfoDisabled new file mode 100755 index 0000000000000000000000000000000000000000..54c9df181c78aa8c3f81cc1d94b3fc109151e953 GIT binary patch literal 4124 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 literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/About/ButtonOkNormal b/scalos/Default_Theme/About/ButtonOkNormal new file mode 100755 index 0000000000000000000000000000000000000000..99efb68349b2043e64b3509365ad709f78852f82 GIT binary patch literal 3884 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 literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/About/ButtonRebootDisabled b/scalos/Default_Theme/About/ButtonRebootDisabled new file mode 100755 index 0000000000000000000000000000000000000000..c15d8976f605142cc7ee8e7641d27b6f1ebe2f8f GIT binary patch literal 4417 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 IM6N<$g5&Us%m4rY literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/About/ButtonRebootSelected b/scalos/Default_Theme/About/ButtonRebootSelected new file mode 100755 index 0000000000000000000000000000000000000000..f15f515e6b1d07872d8afa8bad25a94a15cdad01 GIT binary patch literal 4806 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 literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/About/ButtonStopNormal b/scalos/Default_Theme/About/ButtonStopNormal new file mode 100755 index 0000000000000000000000000000000000000000..a9b5a6b21398d19561e017c3e776590b6034ff5f GIT binary patch literal 4218 zcwPZ|5QXoFP)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z000H0NklZVnP)RIthI2?HLuAq|14`QthHccK*s!K zh`!Q9<#p@VU(C8!v~psoQrX~~`;?ixm>I?x_|k^Wr(1OptZh8TJL$i zr{{+W0SpZd6@(B+opU>w8HNbP7-+4VAei|<^qqs7929UKgg=D@gw`5bYbd2yDYbjc z)~&}{0vM`P3L*$faBdSbgNUG%f>NphfCz>eHVpt61K{sVmtbqPOg}q>z_c}Mz%yn% z1R(vaG!QZdS}8~=5lacJ)QN4|x9@xyz|hcV0CrerD6Jvm7;zj!O4$U!%&-~Jzt`W7 z-}dgs${@fK833jMcy8lH3~bw$2~wnS0gaS025}rCiXy~Pg0$ZG{_fo;ngA+y?ree( zUt4RTwMHC82*VIj6hTP|N}TtF*2;c5cn~jLyM~v8AUjh4prZqq_U*&{xpT8Y2+>@f zb6{pjDG`Pt!Z3uCl9_qQz5@pag27w23f8&9oaCE~V}xOddcBUQ@#kg@q>DIxRr>nS zF))Dc37q%Q71b)1mdh=lV^jH`UeoDntpyPkVkwURKwzEQz|1fBT#Mtl;dmTFYdyAT zTbPv+mD8uOItVZ`XV-c9$`w4@-=C|s`hA5E5XtX`8Ct2$AMD!I65y>@ zr4)!LSIfL{_AH(s9mPr^P>>P;P>`~D`S0G^q(otO7)#EdN5GuBQ3)X+k`rcTXd*}{ zw+6J*kSV_{Ns>8R(i#aFMQeS)^z3WV=WWDJy2 zT>&M-$`7qPk#8iwMX^%BvLrIx-rkJ-qpTn$c;P~{En0-B#yr;4wqpm}tiTup(i)U< zJ{Qjk0zA{(3r;ze*Ldnwi0*C-c6DK7=FHsAv$YN9eZ~-Rpnc981Ge_Tpvqyid^vva z?nW&g*>R_ku7jp6SO7bJK7O4uCpXda)Fz=7zRBDTNbBn!k!1#)YYvh;CVP8vvrvE; zmqMAJJ31g%tiT_gortGQ$+d^46jDk=2|FMn0O$|2*5B$>=kX_y7X%lJxV3H_Msl8- zSh^H)-aK3@7W3tNk~V%4*XwmiDSdnYE+C>ap7H7A6w-B&C!I`B5B{7!9gpnlvt|KH zmf)B9^I-~wT>8NCpjxelYPE_m3_(P2&an{UOz`T)jTg02-z%k{J@ZTodc1haoW|3q zWAv@JU;v<4%)G>^Rrsf~6N4Fro8E_+p|wU7MW|M*7#$hG=)HT0qR8{HljlmM>umr) zM0<#+kC_WiCxt*E2q1(&kXo}WT)P${H*ey}1q*<-whTVqfuD;-aK;4o0rPZTDuvqp z`xqG=#qjVjYPA}SF>ub+g%BT)q0?WSJozCJ9cj)1ArK@^djKK`nsoPZ3jL94EYSqk zIWH%nq(nUoQLR={tyWR1)u6TZ_qL%mHYH%Zm>I9e{_9Ct zYnv1yB_o>@-Z@tXu*FAyLQ#Kk|Nbti)M2gEW=eEGTF^}98;S8KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z000KWNklO>7j&8HS&#>gnn38P9n9v)E&>!2B$d5q4lAEg%q)_Ou&Cd)Wvj zQZ6V`l;noAn-FDhkyeUU;=lpe8<8Sya@b`9tH_9;Afc?Z66^s*c;Nsn7&|rw|IJMQ zR8YnNDs`q{CtM~h=g|(JdO#wNe{OHl61LL=EAD(&gDUnj*x-Nn5(^)E!3jzwo;y+8J(wTC( z{3-A+AbJr257_yqPd+(x<;s=chhdmcw5D7xGf*zmSuEmt9?Ef$=?sW;;EifR2oM6f zjELv^_`Z))$`lKQKW`fv`YrGP2$vJc06R~gKKhiNx3IVv;>=(Ot@BSt5EszLntpNHiUcC5|&o5l~-SqUd8W|a( zQmN3{*@;pLC1p!_DJ4S6hWh^p@TP$noAxh+z*>v7wk4SF`)7CV+I13`b%5->d-slB zy?XWJQnjk~j*M{Nzyb0d9SA^4iQ~FBDe%?|v{C=t%a=*!=Gv0$6oS&5Z(@tZ7fFvy z6}Kq~tZnoq1X^p9QdDcTpH56nd{r)&&pSZpwQJXY6h%>?x4WC~Rx0E>I*>x(x-OYa z2FGz4F~3IWOy0P`^%E!9FD02a1Y)4)&K+h?o_uNew63kiSc@?Rk&FVl2N=YV@X~ezbAlKx%FDba!`CC=`%Np_IaT1@K9=%GV!# z#2ZplTBpl+*RPZN^2=Aw8Hv`^!;mW^0pO(fdJY|;TB%?iXMOexXst=KMr)0fa;ua=boib}5Cjd? zr9`~~`1uD9czFIiZ%DZUnnh+)w;&UaAs%Mksu64YvMS@Xx(xp>HB^y$mMWdw^bg< z^%5|K(*664r0;3ZYbn20Q}sG}`*!4x9XPexnrp^bOB_W+QPdz|462crs>f(ewN|56uM@>F)>@oQW=0xozxF(@ zF$4caed8TD!sOw@EG$=c)hw)D!~hHpVYhB&W^{CI@Wv2^A=RZN!g?KJ431J{U3W}& zbaedDQHpFf+bEi(Y}6ul-Sa@_d++hUaY$B$P}}RyPQ<=_JgZbl^7)s7x5g01F;Aa8 zV{T!AD2h-@5j0%$b2&0H^7oAE-fGr3)>>?OHfaWIru24)+Ombkci&}poutK{JtRXz z%nlDf*H^0!G6tP4TI->`?R3HLFjM>Y6T*r^j*QwWPL~)D|f?~1A=FOWK92~sb*VlJUDK!n)AHBW3 zXZrj5KM+DZY3_YiZ|WtGpPHI_Yhix=gfXTPh9O~EJef3ozi8n9nMAXENki9Ki{m&1 zK|rBU7~k~TYrpb?;Bxw9!nXS=v3xdysi~>&M`3u>TKl#(W`JeeyjH&0XaZ>^;5g3H rjO+e2o6Y{k^Snz^$|ZQ-BmO-AocC1H;Tj(g00000NkvXXu0mjf_*Il$ literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/AboutBackground b/scalos/Default_Theme/AboutBackground new file mode 100755 index 0000000000000000000000000000000000000000..f918cf86af86f053732cb22001d3801e0d94cf70 GIT binary patch literal 3218 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 T%ixCU55+<9UnVL62UGt7!~d^B literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/AboutBackground.info b/scalos/Default_Theme/AboutBackground.info new file mode 100755 index 0000000000000000000000000000000000000000..bfac00d6dba792928ecf2463bf67d1481a604d58 GIT binary patch literal 1953 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�?0Q99S5+ho#QJl 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 T%ixCU55+<9UnVL62UGt7!~d^B literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/FileTrans/ButtonCancelNormal b/scalos/Default_Theme/FileTrans/ButtonCancelNormal new file mode 100755 index 0000000000000000000000000000000000000000..a9b5a6b21398d19561e017c3e776590b6034ff5f GIT binary patch literal 4218 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 literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/FileTypes/Browse b/scalos/Default_Theme/FileTypes/Browse new file mode 100755 index 0000000000000000000000000000000000000000..bdb4be90f56244e72f025c352f86015f7afe4133 GIT binary patch literal 1108 zcwTe!5AtPTVDa(vaq{(Z^mS!mU|@GD$}cZYWnggf^>6|5MHmEt5C}M!7#bLuxVb@m zXGdRmpb(40Ck6&*U&jCj24;pIe|`Xk{{R2aFbYP&$OBIPE|Cljj0~VWfGUH^mnnGM zkIWYdK;@&$+xA)^>)9I&nG?NoA>%)1h#$-&A zq~+!1#l^+>`T4oIx!Kv-nVFgC>FKGdsmaO7iHV8v@$s>-F~8qGJUl!!G&DFk*x%pZ z*VpIqc-(GxPft&Gcel&s>g??7=;&x~Z*OaBYi(_9X=!mfolQ+mjg5_VyS<^Ip}xMp zuCC5zvsG7DS5;M6ESAd3%8H7L^78Vsva-_B(vp%Av)No+TwGLCWHOlw3JQ!yV}5>q zUS3{qZf;IaPIh*7R#uk5U;qHUUa!;Xv|4RuW@bi4MtXX>Mx#kfOG`;fQLEL0AgENT zq@*OJQmIfV!DycIU_o%tCG%!R;h;~KjZ;ahwcq;Sdbjq~CLDRM4PyRyu>hoeoSf6mpcVrjfGJ6Vp{CnKzZ=s%Q1FC=Rq<+>#^Zy9D z(2E}on`knuW3l>_@80QxWNrxpc?-CexrzekL*0EJ^%tGr&Z{oaSb6x~;>FMls!zqC zUZTEY^A89j$X;9F`0*+pKlEba2!|?>!+kEwgZD&;%YFdT9?f4H!UWoF*aNZsicd(t j!b5N%guz3~?Q;>ARI&T$p!?XM{lB68R{iIF{e}MmN6m7a literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/FileTypes/CreateThumbnail b/scalos/Default_Theme/FileTypes/CreateThumbnail new file mode 100755 index 0000000000000000000000000000000000000000..63cfe9230fb6a61baf9a0f8ad9cc02fc5d3bae24 GIT binary patch literal 1628 zcwXhxeN0nV6aerm1=s=0hU7fs+0m7y1~S79n&Cwrop+f*}fXw z{J@|L@H#X@iOO^!C`fGu3OK%W_?9p*qF9W7pf($G6AHAwJ4F)r|Nh*4Iq%)~e(#*z zcXD4+`iCln+&6AWm8;U?REY>7VZ3_V*1~NY^Y`!mbkEiuyO3O^NPy=eB!&Zqzy-0W z(Zj=eA0MYmhDWZkuMmn?#bqGGL(-k)TS?!}^S|!9IJB+2V{gr14tt^e_R}-1k0bV+ zljMJwe8d#bHizLOk-N{NmG;UD&uuE}`naqs@9e;y3j@1;=s$Ynx00I=g7eEGzHXH4 zzZ`L(Hf(p*dR>e3U_)eKP0F#`3EFzq2~$GR#kAvw%#-ce<()Ydow~Y#GX2oCyXL0* z&w58*^gMjt|JdT;>EXM?H)=!pd&$TrWkF!U!qwXsN>49Zdq@;{Y*9#|cSxZ~{{7Op zlYY_KrSejL-w2_yJa|XFval{k^3jU4Or<0u)Zwt-(%-y)_s%o(h`#a1=DLeF8?NY^ z8tgMu6Te#=cAMdr{`#e=$?=hg((4?(S}FZ8aK=27^Jb*Ecma5ke{}D=R80N=iy}I-ORlEh;KftJMVs1$lXS z7~|aB+$~$SEFx?MB3iJy;1I{Ip`138Vwn|TWJW~Ri-^f@-XDOkq8vR# z@iiMb2LBs;4cHTiN8l^K?@@es0O~IX?+0Hu@1x-UP~SxHc?)DOL8N^g+!w3|!UQe@ ze?@WVAmoRDJHUBhV-ODT1yH{q@|`XOe+0e~tm~~?F%Qcc5at^YVLTB@{+TlL##^7I zv$&mFu`Bc^np#N$;xlxv2Ud>T&A9Cy z1$KK_O^hAjCUBY46?1-|_bQH7)|V({Lf#5U#i6=n;VFs zO+n(~T9_I0yNt&C#J?z@lm)d0#Ci9iOdYUTVPA0!~-V=aQPE@w(PpEFR=Y z%qao+h2=9(kAmyKHGJ;L@~`lv6RYv9U^8h+BIJWfALj0&bVlnA^{0oqqG%)bLJXGr zSCg={hHC=e$-$W4|x6 zu}rk`@;M&#mk0fY{YKzQZ1eqvIR|sjig-?&b7we>{%e0i H{3rhh$;^`_ literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/FileTypes/Delete b/scalos/Default_Theme/FileTypes/Delete new file mode 100755 index 0000000000000000000000000000000000000000..707787299660abdd231fcb93e2d6223e48485f9b GIT binary patch literal 1556 zcwX(&Ur19?90%}o?<`mL@4;DNtpdZBM8pTrV7s(A`=eV)J%l~vQJGMQF9sUc%(~3uLc53~h|Ib0c!+H3f&;9-`+;h)d zyrc$T=brN_h5CYA9RmRHS8CEUw=@7K)aR6>4+KGEkrLA29=I70@Uf4UtIv`nztful zM62cT00@A`<8iy)E|-gCS*O!!x7*j(*Voq8R##V-mzS58mTWeg)oQg^EDH+@^Yim_ zb91w^vokX@)6>&tvw3Q2YI1UNVq#)^e0*$dY;<&VWMpJ`cz9@NXmD_FU|^uXzrU}q z&uBFE^z?Lfb#-=jc64;Kx3{;owY9dkwzRY~H#avmH8nOiHZ(NU*Vot8)z#M4*3{Hg zS65e6RaI72VvH*)D$2{t%gV}1OG`^iN{Wk%i;9X03kwSh3i9*w4F-c=ug}ZN)9G|M zIXRh`nHd=w>FMcdX=$mcsTz$YB_$;}IXNjQDKRlIAt50?K3=6##l^+N#>U3P#3+?Y zg+jqFj7%nzN~IEsBq}N@GBPqEA|gCIJS;3MG&D3MBt$G02L}fS1qF#jqQJmFp-@QE zH2Io5&x8N<&z9n%G64YkInQ(G;|74jJnzNi43eH~kC{AX=J)^E*{8(c6MsT{n0OTN zL&WVqw;CD5WfFf#VediWS82$KILNN}eDRqWy}55f5(25sM9 z(7s3H{l9R_O9pM;`F-B@_%HJ}OlVt6<{N%9pCa?qN&eBV^KV}f&o&`i-%nij^Zc_M z+Ptp)ly`*m;vGM@U7$tIYvg{8Q`q(3F5b05LkHx(y6cJ-Z5cU4yC}T%!i%XmnkWZ7 YpWXACLtH3_s4NO|0mND2{@?z;4;}0y&j0`b literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/FileTypes/Edit b/scalos/Default_Theme/FileTypes/Edit new file mode 100755 index 0000000000000000000000000000000000000000..37ce71825a8dcc66a94f7627aa2c168b1fd1c9e5 GIT binary patch literal 1554 zcwXJo@lTUS7zgm9uqp`Dkx^W-v5H1Fqp)<^ykn$VRJM^7NLA)=)JrjqK$9d!2s5YkD@+_k<-j{YvEqc1N@a!8$(ydkL#8LswR z^n0g*frpR({`04fFY1kD*7o}E+DsO6-TBiedM=$AywW~wG1%JmHAkRl*lg>pxzhgG z#pV;%w$E?;J}x}m0`-uQ8IgJH_m+tXayd$z2%RomNIZfmRRHCJ}ERG$CxqrQ$4 z+y($V*A-TY`L?r!SstZS}6+E7y&c<31)9a3aS-2ELxKb}2p`s8QJ8J)J+ zch^n)9#YGjaayeBYCo;k5broK@`#a7YWYDUKVamaQYBA2I`6xFAoIhQFEqHE1H`}& z8lr+0$%uLM7l$sP9x@wEW>k`Sh)uIx6 zO?loXjl-xql$9EAbb5-C8}m|!4az`Qgwfwydn|@ZrOyrKK8; zrlh2#xVX5mu<+o)gKD+9prAmdQb7p!@87RfD);T%w|DQ}+}zyVyLa!}wJRqlCp$Yk zAt6C16voHLuUxq@Ha0dUCMGg6G9n^^whqT};Quw!vv+&|0MDKVyl`<(7mOY$L4$(} zh_fd$_N_q%fN0EdEEWMF>U!$)kQHgD|3-b0I*)oK_3CFXTAe|Coca~&bJU}#AEF+j4zPgK!aE@|6oj@Q z-%<@?c?!lJ=3zh>bpo(xeImqbGN6DIQh$@y8yI`Ig8|{xL)15DA-mQ91y61xAK8M~ zuyn@0%*23Y)Spn_+z#=kJeab$3HjJR5XUlfr6UV$W`|; z!tsQekrM{w+c9TO!=mdR$S$|R*f1FyjiX*beGTQWJ8o8g3#%8HQnr{~1(5f`N_A3=!xT=F|DrM;U<$UBm zDrIJ>2oqin@FS3hUv=`J`}#EGsb|qF%10BKw*T^N1DJh14KK@2hl>SL2wb!1?uC4G zbG426eK}#GMASF{YUq=>F9Gla_{>YgcoR91b7Q_L>%r`ib%AqamHOrBydXm(t_s2bFq_V!T&T zDiLcsTC^&~{k$~tenEGYeR8e~>^2oz`H=6z^8-1b}=xXWjY`&76Db2sqR9m?)H~I8Q*UG|tke9pr z_K(FEl55JOPud=KG}TNG^+@wBx71fZme&h@NHRR19Mtx9D-|7W&CjRwxtFp|d>Jl9 zc^Wl2KR5eR_QlPcHu?Jaczb#6^7K3$5fOag06#D=B{|u$y4s;s=I7<*iNy@V&@@d^ zl*M9MSy?fg%_fs+d3kwpadBZ`!Duwj&CSiu&d$utOixei_4b{+Pfw3pt?usbR;g5-ot;Xhvc0|i(W6HSg`%~! zRVI@)G&DST@Sv`)uBN7@y1Kfms;aWGvZA7*yuAF*ojYY^Wu>L1w{G3KdGlsTNl9^W z@%8K1i;9Y*QmI5DDJ(23C@2t%#Uha?CnqO6J3A{YD>E}wC={MMcTOM>q~U;5Q&Un> zl9G}V5)$I$yAr*`1P`IlR zYFjB(dEzs~#(!_de+-_qkUAR++40u9u-0uDj{n_&uI-m1Ub_%@?{5a`9lqo&=EfIY zP}dj=&5|_K)ar;nI>rKiC-`8v_-k_1+LxrWHL$ZI8ZN{>t7TKg0ftGmv>IgiN;? pF-4fW8vn~p9LNY*c>gdLSiRam&a3@1VXdrl%>LyW^g0(1^o$5Qnsn;uJNyst{O0|hnY}Ih zb-?Ozdz^Z6tzHixwcdBq?>g&;Q*W%}dNy|QWq^uqXzA%j-BqhM@GVQtcfh6BdVwU+ zm%9|dLth`!+{@_OYq9tJuln(NAo<Oh*L==z5W3gBy5}BT!4uwMF2CTW5_U~)g(70yleOYFn!Hk0pR ztK=-1ywv1#LSQVPBP2CEV-IUIeA_g>S0HqnENoD_K?BC4h4tCniv)HoM-p>hk S+TdU_lFuIghXaQF<$nMe_nL12 literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/FileTypes/EditPaste b/scalos/Default_Theme/FileTypes/EditPaste new file mode 100755 index 0000000000000000000000000000000000000000..5f366d8969d63916625ded33b1616518c45d0119 GIT binary patch literal 1622 zcwW_$`%_a#7=}-xMMtb@kV}=36xxZcMI3Fbr`nQ;2HK$!v?5Iy$c8C0AVnFW+;a}J zLBZQ7A`5h&MT^3W0<8kJ$T<{^Qh}@pg2kFx5R{RtBHrJsf}*G;im#*M1GNX^BPbu`XWPk)BlRX}Bo+%Pmg4N~ZR2fQ zm40Mup?sX8wkfv;Qq%%!%jPXwZA58lSxL#+!s6mzYHIA3*txqqNu?{@-B);ctaNe` zkBu3;yrdROPgYiDX=(A5E7gY&>#f$=UoQqWT-CO>Cf{k*h3ujdzi~YOgS?~d#DjbJ zQV+ZARJV&~)sbIO*~t#xv{(~JDgD-L^m6vzyusJg300mKdx3!jXwEwwd02#%e~yhE0!;7E7KdxbH+Qbb^P}8 z-TDhJ?l(>J7&;rPCd_Sk{K;UJOq^ADVqRHZw8$@jH&5tHf`+EOUBe zslzgRbn#@7K7Ra8ZE6fij}4!AaBJdW%a5mzG+wT-JpJ1;Xi^95RP7F&9)7G#PM97W zWKxr6C!aTQ^=~4E-Wl8C@9F!&p&hKOkQ4IZf@@JoYSmGcqz*meuKW>FMcdX=y1bDapynNl8fw2?_D>@o{l+2M!#Fjg5_oiHVMm zj*5zkh=>Re57%n7VPRpRp`jrmAu5$BI5;>cD9GR6U!hQ}U%%ed(^D#yy1To(xw*Nz zx;i^MJ2*Iq#bTjQC=dupC6Sv_|MTz(*sikugSiq6tP%`nB^b_e^P;f^(_{&nlVFrt z#Q?pT0hqyXW*yN8rY(|J+#FWZ9mJ?njz)0|(4D8g% zK*c@=R&z4QvzX?YSDeEbfdmG88OMNQGYtIh7zfSY6aFox<@OXRVli^XCSWhepqbae zTvi7AIGdkv8HIi)d_Ue#xCC^{*FinuO)`e&G1*@RP%SG#!t_XxvgZWod)Ni*a*VK% zBYfWoEq~vPxYH7}7rTHI-UQnDo3NZR!kaP)@tcUBM;!6Li)(>IJp%Gfk+A!9BYdqWGj8J*`Y8wNmXum*H0y5O@t5;$9?p_?v92sh7j@A}mM>@tC=6^G!>P#K(? z3!obx+4kq>xzHmKP`T^C+-rU?lL~+tQw+`31<=CCDr6-*qbMJ+ha>>6IS=t|2I6rU mjb}*xEMyVpMF_Kt0QpV;vl2*pn`oPC^+kF#&tB<2;r{{#xcHI) literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/FileTypes/Find b/scalos/Default_Theme/FileTypes/Find new file mode 100755 index 0000000000000000000000000000000000000000..02b3af0d40e2ebb7ec82830463d5ab969e8bf500 GIT binary patch literal 1554 zcwXg`>r+!l6u|f1fG~n7($)@+R6EYt#+J7DAR7b{NJ0`M#EMglfZYLRiZ&ud2v2!U z3oRe;!4#Jww!XjzXnhrhg5fCz4O_7&h#2INK@boFM2+|MI{hemWnA?hSjHt6&NRpczq`1+t)+o#1$X2inFT=uAolkU@bmNEw8>8-@)Zi9kB?BT4hs!ct5hK}nOrKBNhE<8 z8JVf6X$C`TN{S&lIc49zWW9c0Qj$I~F=_AK#OUaqTJ4VQ+qF44xq-pTuJPIL^vP}A zcXcg&$sLc1x`#^dTT1^KJw5RB)Wh+*k?Dr9nX|V{S31cf>#I?#&GKS?OXZC%C$B|b zYDHJt;v2ekbzNyKJ(;cd3jQ7{yfaYtV638Vtn8k-y!T19dE)%zrx%ANFFl#O^l+rX zGSmKS?)LP8uUJyw+ODoMh1Pb7zCRR%tE6RTWWSvC|EW|~dRlp`CiYtE?rSaSH*e?t z)mzxvTXd)I%+N&3_{{wmw#&D=9z1(4304FtRe=iSfMtAiX131Qw5|Ha)~YM@mZ=}l z)U;V9@6T8VX6MFjuZCx>>G)`UTYGnZzp1b9;?=7ss;Vy6))o{NR-QjsapL&??ERTp znduqnx;?t6=%`rjs_HWF;e27ksn9`F1Re z57%fkYPEXv=FK4?Au5$hsZ=Tyis0a2xm+%j$)r-LzdtwPO(KyExR|5a12-3*30MJH9<8tIA@kO-R13MrAwu=X$ZKVlv8$@g?t%Rpsi#`AW z$mO62FF&{hTfcn@#~$}XC!;elb6#NgLBP!i36dT0r`IWLEH}aKk2@is0Ah5qlkCa0 zXj{i(v@u(NcYY$kSG@+|g;Wz1A9W_VJS!158xTJ(8-;C%#^1=)xHzd1-jo->m47;r zT*^k)h!RkBM*ylW_rhYcCmwyxz@4uOVCtg(e3oMdg6FrQ>)<2Y*t`ob?;nG4&yPU` z9}qyt}KS4@kW^ap)=>LB)(=Hn*Z4y6>V6GYf_ftJ^Vqa zDIA1}8E%}PB<4066~)tNFQ3Az#wgtF&cN6u49uDbTz@+eo}-bllSW_mQrNkZ!j)bO zd@W?)#@pQcd3NF-Nh9Z48if~AI3bn7^^X|%#{>gK9-OD`WX&2HeQ_Wk38pE$Op}Lg zE)0CUz(CKFxy0;{MR+yM$fG<6x!-KUt~r5tVWAP4-wA*~2#D3$k5EDR$f=_l0ZSg{ znU3Q(EH}Ru#~|S6k~cFeh=g|+AqRKlMty~m6NN9nxd0E?`4Bh)!rDSf9M2tPflibL zn($(t2shckhNs_pkV{zmXC$6#MllqP5GBVt>Lq^3?1pnJ4H1x#Us*R|1PKU$0we=o z*a-IH^{g*^m-7IuBHT)m31C3eAPk)Z(f9|>$FhgvQnnLPz>P3$2Z;v0D2F2gh_E-u k9NP|g>^$cI=dGj>(CBlHFhJo!j&7ELVh%p%pR;!IFMFbGJOBUy literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/FileTypes/Information b/scalos/Default_Theme/FileTypes/Information new file mode 100755 index 0000000000000000000000000000000000000000..fa2933eab35886b5309f2038ae2105e24ba52cdd GIT binary patch literal 1560 zcwX(2Ur5tY6vwZ#Y_-ioB7(@?e3YVsJvecHavS(_(nA!+I`t3*Z6gco&( z1}8$u1fw1X{nIEFmy|1<>!nOe5-U^+|5WPc_Pe)hi{QG4UVHFdz7O|&IOlTi`Bppj zON10{ve%fTTBEd&5Tdoak9!(iN6()0xQR)!S$J+U*}@MGwTfIIJ2aZ*yV)pNd1_77 zcS6jPv5t^J!Wh#xy|-Wgarln1`|6Cfo%Y8QB^M`LPZ-$)g$LWTp69#TSY4Ezy7sUn zLhHMjba%4i()}aP*s<>U##gNUgW~Pz{`8Zch-boG3EwcAqb$k$vL!CE8msXihsj|% zM2M=7F$y^;m=o3WJQsPrtiN1QkaA87R`3EZ(9;yM=VVmYDVRxlMINM(Qd3w=_Ta(* z?{BLV_@bY}tlkR~J)`(VmT{q>RNxa93S$*f_)1(jqcY&2QY`T4S|?1NFNL=|T}T}U zOw%g@PXxR$*L(o7=DirMxr`5zMFQ^$b;7-1B@F5!_{}77-X!p+Egf)6Qx5Oc5gZwi z@OB=b24AS0&-eyMtU3%NU*y&MwsF2Sf-i?9415&pZ?ts&srTcQmGc$-(=ELa3zk7@ zy&vP%`FteggjjPUJl?n#$EsR67w4lJ+%T?oLbh0kpN*{;8xsF78Ky9s65NKx()kvJ}XUPH*3y z%#Rs`YIv1lh$3`MFg75>qn*{~^J+T^8mxuKZF`%$i_Dkzz14HzoxZ0Ix4d}9QGB|; zto4(Z-uqPh!Dk20evaGdE8=xs`^|F8(9sLG^cP*_X7L5_TJbqr(tf@4{7~728!va< zKKP;Q&_}Mr)-Q0^og=m{k9K=1KKAM_dyPF(O^^GHUUzM;+jPY(T=58fp1M9y{Z&uH zRnMFK-bT0wyvGN;CkDJt4ynoEJ?W564ob~~(xJ{9Cmh~WPN~HyF@|bt(4IZ$@#E(L z4+O^UGxmV7`Fn00i^bN~)}qm9BobL&T@8goD=RC@%gakkON)z(!C-KHem)Qg%+1Zs z&d$!v%uG*DPfbltPEJltOpK3@kByCuj*gCujQIWj;o)J6#bP#_wOTEMCI65AVpP^w zwIu%o2m+@}V5Dhb$dj6a=cGs?&G|HkJgF2{0N>CvqTmqS_9M*U5QZGbD`d_a5m{eg zgwJ)-jK7_f|HX+n7Jz5BrMS|7$X|bk2?|N{=>rl~h9n#dhjC;_bBbr4F_3>sH6&wG zq}c@`>u3oGb?ERyT#x!O%l$pG*Ff(0G^Dswq>Zo#74(0pz=nP4{u%6l z-#6cq)~_U*fA$gOLyxe%B#aX|yHeafUPzj9zbB@Elj_QUrTm5u+jm{V3@PRMsFO6+ zb`w)9i|SNWlxG;*xo*t-yj=fm4%vUVoaEgSX-E4SRkAE>M?7W`ncHF_>HE5fs}1Dg+hM|2_$gwgRJnz49H}tdQpxA{yMe5CX$aSqQRd^-sEq7ArB=4#-~1z@k&vdNbH@H>zCsv6bdiq(FZ_~Dm<9-x4?m3 zbXZ$}2JRj^#`;QyDvXA>@?8L>N)ZEK33g%S@0>@6h%yqdc1fynORM$BY^t81cYQA3KU?^*Us1b%aYsN|cW6rf z*}{90($3RS`TnUTo>^*1TJd|upL&+GdzEzv%R9ZVc8Rd}Y(?L@spy{mkw?aLuS+%F z1$Ae#s=ae>i1KcUFW0?)t=sFvR`K;d-^zZ!>d!tqcMS%^&d$#E z_V(7+*5>Bs#>U3_`uf`1+Un}6UawzSSy^6QURqjOTwGjOSeT!mpPQSTnVFfInwp%P zoS2vxA0HnZ8yg)R)#-F2BP0F&{k^@tJv}|0ot+&W9c^uGrKP1A85yy$vEkw2VPRpR zp`jrmAxfoEp-{+VGO1K5kw|=feZ^w2kB^V5tE;oKvy+n(A%xbCVHo&-{6`}wIyi+r z2Mkk3sLKjj(In%m_Tfv;-`tYw@D?Qe*r42&ay_7d$KW6KCSvgjh*kL!f3|n@eI8xQ zV9DTb-@hcs>*@OKfP!W~eF=ls)<;~=p**09SZ34xQkP}=vv3Aj;n@Nbe7qbXi1OeDZsoElD>5nryzoYX4bOP`i|;Lk;Cm$}>q)nvRIv z0l%}#!ZOE9j5NuylB1zqfCG;wNW>6Q$mzaTw6Ckj zR`oR$(A)^j`QhQg&wO&SR!?k3bja&y#r0}0r<&iPCmguO#6MAEsqtbn78Lhml@kH41e|88<}?{lAX z&&|C#Nm?Bb;Inb3CZ11?;}ZeEZ&yjtA!Esr{l>!p@%)bMY;Pq5K_Ht!CISJ@`uQzz zLL8sWwj}CFfCN5n7l0UIV`3vBHid^rB`5DpO4^Z;u_q&AcY1n;M#Cp1CCA0Zt5oW| zJmbW~WPF0=g0*93iY|pux3+gQHCvP$!a0f0l7Qu}Zj20zie3_+kgZ#yn`J$N~K^F`+qgCV!Q-CA2) zW7tcK*%6&*RVR)qZ*=hYY{zN}l^+zXuRf^kK9lur+rgd|)2)joZ^o{+eWLI0JeI!6 zFJrSjeY1S`7DYuSIdve?<+vR|q;C*ec&P7{y1mz14%sZFgO|*|4O*WLes-lUbKrdG z@57fw0KPI=L0%rE)Z_8E-R|k>>Cw^Ap`oFHfq}lhzTV#6n>TOT?e^~O?#q`iTdmgC z)>ezf($v({*x1<6&`?uTQ&m+}Sy?FvLV0=l(W6I8OG}H3i%lj|ety2uXw1#c)$8>- zosQ>ub_@JJ{^N+(Zr=+aa?nvqU@Z`k08$S{I!=-4#aLL=YUT@>k7Dd#T*W*Gi$Sk3 z7MPD?-k0$+#uu0mg~gyv6uoX0;beqxY60g%%;=S>SZxP#tiHD(1ZnCBk?IAqB+Y^I z0Xg{BogCyiJ#vD8-qaAB-8MzU6+nE%{x~0e72R_YC>8BMDfd3k1V^B|*+7N1XLYCkADifo@o(2I*2e)k8}QFY`I@VN(vn$ z|8WosFoJ)&qzIZI(m+7Bzy_jucerZ3`jr0}$@11-+6H z^e!Di&P)(aI?xLtIB$~^&H+SRzYFK?6ye-ApQC7O7&)i-5h-!1C^ literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/FileTypes/Rename b/scalos/Default_Theme/FileTypes/Rename new file mode 100755 index 0000000000000000000000000000000000000000..0f83fb794a59e84229d6ab78eaed2457abacc194 GIT binary patch literal 1492 zcwTe!5AtPTU_ImM)`_Ai+~{za4<16Ffem-gZR#l zzV1LF7Kcv^49>oe0SpYx4FCWC_w@7xiUJu7qhJ(_FyQ3x63M{8)bRiRF9i^0U|_7k zhAEamNkIMyQ2q@b`OiT4-{i}GARzy*m@@ef1mvI5SpK6oQ2sB0@O?r-{Lxq*06k>G A;s5{u literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/FileTypes/Update b/scalos/Default_Theme/FileTypes/Update new file mode 100755 index 0000000000000000000000000000000000000000..39883a953365b8e74b26fd5873fad901f607af16 GIT binary patch literal 1556 zcwX&NT})eL82-L<`nUe91q&TNg|8JHFh=>E2$c4;qXnU(kRVwiI5H4I#$SZwWmw_V zZb}wpc;OBHKnTXGvFKRX1=vDDj5v(RG-{lKO)oIQ%3xWW(H=jxEAPGZJ$ZAU_j%s; zJNeG@I%?}(2uYMxH8$57&Q*aBk~Z|Vw)D3lWOG%XrnMHu(}#wPK_h5Fp*XDVoXbfm zk@XQmb{FSHh(!fowHDrJb=>TA-t03?HRgZOl>hnb4T~4guUtC6>}y;0<$YS;x;)ak z>g!p#Y#MiX*2YUdtTA1&av#-uZ%@qpdM%qTIq5CU9)2aySDx>)n8&M4@0Pv%zJ1~T zl4GLw%Z-JC;gai{^SAz3%zDeT^k*Qe=fs`;JL`Y1uWhYmUO1k9&iHfir+a&MPj#7` z9;^G(t0`4FYk%>^-d%%RXRJHM^`6o@UPvleCv%!)izYr#sXZar1kh=2M43XU60MBr6a6JMdO#rYOLkO86bfugy zK8A=yEx;58AmnTUaU};#*))V$JvksQe7UlvB`rJRAWf?L~eJK}!T)s*REt>3j~Y zH*+zxs3Xuy^{YYJLvd0{l;q?xL{E75(T&0WwFipndjvh#KWJJag?=x|8{wes91q^l z%s{L>SPeXkqyP6m#1N8 z$OT96G-%%2gbmQcqn$U21ph@u>a(C$O+fI;EJ)ZN;D~w`flYc%pioy3H6yEhH{7lLGb)b zzZa(dV;k*x?x`S{sZKG=Q{4mK2dOTm^I{GTQwS|S(~y+vArCxQrMkjP&{4`M==?rC zpFR9{6bB;^BvB$wVTdw?hogBs>~DEMB&GgYFg*1~AbgR|zfI4-fB|RGo#G;ZKc@Hq dLzInxkQ61D?gyft;H#9=(f!omXDK|4z(3%Wv{?WE literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Icons/Overlay/LeftOut b/scalos/Default_Theme/Icons/Overlay/LeftOut new file mode 100755 index 0000000000000000000000000000000000000000..62a66abd3cef462b1f60941842e203757e1258cc GIT binary patch literal 1938 zcwTe!5AtPTVDIwuaq@NY^>ATeU=U$oXW$3Y46IBH4GauAI*bmC49>oe0YIUI{|x`@ z85m}PrJ8l`10Z1hu1Iv ze);s^)Ul5b@7>(8VNX@*lUp|zr6!)9J#zvh<1{6u#ddc8e*F0T>lXvi=>PxSgB+cJ z_OLK8Gq5{5`nrSJOacrco_>)G3~Vk84h$MVbqrVmx;T~9@#9d(4+$6X=2sEtwmFau8->KFdPN}A7J7ihPFDGI6rOF;Yu&)fZFOl@IyTgOO78P`p{iX ztU6e};^#+~f(0~`rnWk?Y=skys>2S3i8?2L7hqk&FwF+c1CcdgmJ6_|kzr5(vUq^d ufPn+Z0`V-svKl}>I?IAV0;(4TCNT&wB1U literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Icons/Overlay/ReadOnly b/scalos/Default_Theme/Icons/Overlay/ReadOnly new file mode 100755 index 0000000000000000000000000000000000000000..37b2ac77731eaa74b9a1e69efbd016d3444e139f GIT binary patch literal 1548 zcwWtv&q~8U5Ql#)wRjMA58kVuJoHfL#bcV5)`GF6c=2RG$aCyPjVE6r=e~q_fV_gQ zAakrBjesDI%)w$<{-D zoY;;c7i$UF-D6cVWvidBtLojiqg(fTUb3{6Csp>O_Ujpir{ey9=Be;G#q)N4Gr!oe zem{H1s@|Urq!+^2pSH)gOv`8^%{IA6PCZDAoO*M!;_&2d9>%~+=amvI8@184aY^>b a=$wzj58<=$lfLL-jZ0e6lP<5f`@aEX_umcx literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Icons/Overlay/Thumbnail b/scalos/Default_Theme/Icons/Overlay/Thumbnail new file mode 100755 index 0000000000000000000000000000000000000000..0ce8f5c5ee12f0bb2a293f59d0a76d042e023dc0 GIT binary patch literal 1508 zcwWVnu};G<6h%*)6p$)m1_ovp7&f? zBi)OlNRmWEa&j4#uaNE|DN^R5gB)I9J|`6@N7FDeTd_%J5XPf=-rnJ2e0HVt`UD*E z(G=BZfJlYXc^cr(Q;AyQm8yp(_^S46ZckwDYPE50mh_{3p4-# literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Menu.info b/scalos/Default_Theme/Menu.info new file mode 100755 index 0000000000000000000000000000000000000000..d82ed8b856bafc74caa8ca748317f471843a28ed GIT binary patch literal 1695 zcwTLjTWk|Y6hLRZHcl|GFRO(QvR-f0mXFBsCPXb%3YK>^LIUhGn?wZ_Q}CmpsbkMF04`m1A^d}BvHj}}FT896icXdpnR+3u#I`hDtt2${{4tElYYItfYT&Jn0N5U{ z_XjqqK0hMTMRj$M1-0up`dUcPx4}{hLaU_?xb{2hbs=|;&KB#g>%#6aIy>+3iQ>5N z-S6f&_6ePxad}10m|kz0q_eZG!=fni&5tI5R~C*~IYZMtqu1LeL96H$jx6EW2BpEh z=>cedNbxLou@#^>XK`+Q0EC;mka1KPEX+&-s_4m5>WJS z=N5z+uy=~MT|xlPPXaG~O>_nmX;+n(5S}sC@8))%^g283S(q`5IH%0LTI=Ic%ANxU z3@gk!Ws&#sjc6dv*kq0?GPQC^nAQX1<+RIA{BUKqmLQF&6%7pJKpSy9w75|wg3y=^ zeU!=piJND-WwIZ#nTTH`nI3gEpjOWiMEI=TK!}8GY;5(Mu%TZGL(MZgoK0MTafY6P zvA1ZJ_DH>JXxz{EKJ*x(mpT=QrCE1$Sm`V4P<|5?@xN-&0E5) zrEQY2O+BIW@LIY4ysV)u1ABvdV#BS~xOrB;oFAj})z{hxa-YuI?p#XUqeu5Ug1Fz& zac=XT-#>W$Gj+vQ83Wvpzra_pjx%@{UXNFSN{3N9!7`)6s5e0EQy{`odI-Y%zzc<& zc;yrpa^>cn&M-AWnql1yN;~O=ngkJ(Mk$7-bx#(;zrbP0NsWO$q%&~MR7E)-3~O2g zcEK#2)jj0aKB+>QrUf!koTjr@f+Gqc9GIip#92B^Ny=>SD*~wT2})*X!Ml>G6@p5; zf#~TuTbBs)bk;5*RVffqjV0p~P%aAzifh8b#&BR9K1WN59ip2p&{>NVxT6OiS0g2w ziY_F&+zp~|h~UN0Oevn%;}hV^5mG`Du4uyJ4up`JiWU=>Yh7XiLMdXTttIn` zwLga*S-V8xtj@SeNF&+KcuEfqQv?L(BywIY^av&k=~;+M>sm~=G_glW(UQf)S}pY5 ze^6_(=gfqK{8YcARcO0G7k#nVj~Dl7TmI}&4E%(Fqp~j*>%D&pZSL$=D@p8bB2I>1 zj>QK1?`Ueb8Z+QlDI7XjmFyY(B{ZzZM=NJrBt?|aFda^&z8P#+qUH30MHUX(xF(Y3 zoDz#Ak6lpXqx$iMe@YQQ=m;mzM|(O-i4S}GNY$)dQ)t)`4#y%&w2+>+8Zx5{^S)?H zMAw}QPre|PT|BNoOrKSu3Sa@c6C@)TOxR!+D$SjPzLUm;^*y# z*HU1vlrB`F#hCZ|jVx@d1*nUe5_ZQiV0AlYzTb zvcn+HOzSQGWMoGBjdCJzP2VDeIt1i=t6M47=5O<(?x)bX4tM0Z%$} zz=j4cKpe*eT5J5{AHNiC;4gv7MQbHq8?a9A_Sd~2FU+3Zl*kgZKf*|)E3@Cvkw`4F z=cy8^ZuXMu>o)WLE$`)BiITa$I8yx$<2~{l^Zx_&Cu6)MXZo9x=gfRE&3o}_zF+ny DHdyhr literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Menu/DropMenu/Copy b/scalos/Default_Theme/Menu/DropMenu/Copy new file mode 100755 index 0000000000000000000000000000000000000000..cb92d5a3f414e41d661cd689b5a9404ce46ec354 GIT binary patch literal 1554 zcwWtt?@v=_6vuC+g2;~*rifF5W|@0JOg5aLfC2@lP6S1qP8YB-@dYmk1XvITQb3u+ z4HXIwY!MVPrr?HyaS)-c6|4P0DVDZE0ijR?K`PSG!oA!*h`!i=u;=ER-1B^%b53&3 zckiJikpyAC`kRAckx}f(uL*)!8J?JwP7q;{`}g2z4dH=5d{(U>xP;2dX(|JX}no<>0I)(L2lAYM|z|+e4bVz z(W|8QO0v4{m8l!~kLs@ViSHO?jm5dC!8?3Q^3xyRtNN|<;%H~8ZGt`(v8<)tEuwqn1k*j~~8zX)3;yfAZTSf?rFt-CfgD zlRp<++_+)GuArd6fPfwT{zqeCA`Tn~W3w~T)5(Peg(KNldxJXeHNs{yP z^ER8!YPHVI%~>p#+1c5dnVG4nsmaO7iHV8v@o|&MG&(wJG#ZD8hlhrS1_uWR1_t{3 z`wa#|Z*Q+&uh;2xTCKLHr$?jFba!{F)oPVWrBo{Aa=A<s6$15r-Dl9B4C@9F!&(F)t%gxQr$;shzxmkF@nVA_G8EI*0DJdz* z$;nAcNr{Px2?+@t4ks=yE;cqcCMG62Iyx#UDk35xEDR5Z9TE}}7#Qg9@4s!^HeWpZ zty_J3e70=a;^pP#>FMd=;o43n?J62rlED=j&_xKuL0?7hrG2T8=zk*Mkv{y$DZ60RM0m;n`saBc_%qRS+DnoXj@eH2{KQLwj* z0og1D2yrbDt|7CKs6$1fx;qr`aK3ve13tyvh~FF5Q6RNsqTC%1kiLV0hLgL2iF}?*Q0?s@dKEdSzvW2fPW;_h-~^2&3%*(b5=39+PeYaU;*=4oS!`oHhwi) z_^b=fnr-mbCI)8kRlI)-&>{*JXh)zqYY;8wAi6jJXt5ZGooXPw{V*5c{l){mPJ`&X zp@`;}0jG7-%su>UaUGT!@d<$M3( RJKDO;mpu1@zxUo!{4d7E94r6; literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Menu/DropMenu/Move b/scalos/Default_Theme/Menu/DropMenu/Move new file mode 100755 index 0000000000000000000000000000000000000000..04858760498e85acb129a283e25b2d0f504b4034 GIT binary patch literal 1554 zcwX(3>rYd67{`C7r#&rTxtE&=Wn6lsR(eAy)b{iOR_p;J-nJJ8k}cW0`D!s)mK3+R zx9;_pWxQDCT-X#u3Mg$U6r?TGu1EzYR0J6cNT*TQ684<-u(5?dVW;`z`#jJ0dCu>0 z()y+r8X+R_q}50_8t6KN5Rd-o;|~xr(iSshnJ5c>@CZ1_hEP%xlba0m2`F)?C_*OM z(2Nkyv}C3UQ-p~SlojS`DkNvj)o1H8%ELv80)DD6NvAw~>bTKZ9^X<;s(;5BHK^_q$XtwLIyFG@=$#d(#|lEOTZtfZhgKU#2=`^LTl9i?>AE=c}43*NF z3W;1I&d<&uiw-Lcw{i9t@-}>gO=Nr*`_kX$R82_%v{msvVKlFJ*b5A<&j(y)d z{8i`Oj$6)dmw#Y1_-1Q+Yx|Eo?ul-f@27kBJGx!B9Nw9Q<+oegJ#K%WC(z@b2+b|7 zu5V7yFO7$07nW9ovyr*QmHDOB-r>nEr+4pZy+VllfhQI8OL0kOK+B3gIdWLmzfx|W1u)o?zkQszMq*d5k%Y6|&bi{U6GNb%x$Io3DBi<|vva>Caod-%`^9ai zV|&N1DB?bNhzI)@w8if)0Z4?ibJ;xzTj6d2+yFJE&MMBHU*LpU_=d1QghQQC=5C0N zxR1g52>=0e$xI!TVCD>QzYNwUfCQKoGwZj<>$}z7!SgU4WD^Z)2y^LV7J literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Modules.info b/scalos/Default_Theme/Modules.info new file mode 100755 index 0000000000000000000000000000000000000000..befa4faa4d0b3ed630580adbdeaf368a6b9edd24 GIT binary patch literal 6123 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 Ki`=N^Xukpa`fXkS literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Modules/delete.module/delete.info b/scalos/Default_Theme/Modules/delete.module/delete.info new file mode 100644 index 0000000000000000000000000000000000000000..339e1dd4561d0ca7af74709bf53f9751ce65a55a GIT binary patch literal 3183 zcwWtv&r=&^9L7WG#a{I8C7U$wzFCk>7UV~=$-*YtO+q${*>_2mkgz~U>ZCBE_@ftx zo0t9(jxsoo<47%2#!~2v9;Eb#OR7$1^x)Ks|APnpzVB{Q=m2_f#ym@Sv)K>N`@HW< zp5I>z^aQBNf$svnf%9+$0zLZEKYk0Gq@MG4^4Fhi%mf?oU=GC2oQzW3PwDo>Ut*4@+Y!pAU#+rBcXEt5eZMyF6?sjFvbsucH2Uqc; zikDX08MnFJcyxFFp{lBJM05b-_>=J1$|wwq`!M6W+i^TU;<`oGr5RRf2C%rdsKyr6 z#zFHY4DQZ`>CSwq#_{6f;FufzdZ>9@+uL#Www9#ZY7IiT_etOMEqPzFWZXidjRQ@Y zyMJ|WApdA$`N3Q3cdA_W(*pbquNO9i%j)O5)5$ltzWqkR{159RowdV;|C;<~Ij!Vm zN6~CPBB$i36umr6(_cd45Gcc^B2g`ymSuSgsHrxWg7@{qq%r9@PA7xo08U6&i^!Cx z*A%m+qdW_yzyWf)dK-zj4aovDPU}N+a~3FF)gRlK1yLK;iwm9lSn6nb}>!q zXMf=1EGY}91D}oRXp%QrU z8A@>+?qtwyq=VnwTz{iJiyLe`ZBqy(^01pI0_O)*zYn$Ao^T-x@w{SNNDS*XmlK_S z#?&7ty=^J6d0}TPlOKivyvU1l4T{WmGW?iiB!dZsVY|z4Fc}kx9{SS}H#iD*9>lT; zflzfi-Oog)GUZ ShGO*QLOxf}^CUGW1^xzYmX(D7 literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Modules/empty_trashcan.module/empty_trashcan b/scalos/Default_Theme/Modules/empty_trashcan.module/empty_trashcan new file mode 100755 index 0000000000000000000000000000000000000000..473a533d9e7e683447656cffa4a1649246db2953 GIT binary patch literal 1884 zcwW6#J!lkB5dQXFlC#+4MNM%?er&`PA#7N*2ut>o93}zJgpeX>6%NZ(Y86kgxXw~j z2q~=6Xk`Micyib+oP}UxBG_mlWN{1eSToLhZxfOeyolhy-0aLZGjDe0-R!mb#WIjz zn!7$#o+{6l0QBJk23Vpahbk~K;uIZBmnRq4)e1 z*Vi{UH+Ob+qA1$k-6bO5_c>r@adJwhLN|J*C(ASDIoFG&xf?4$X9tQH#(yByqQ@=r z&$uTK?XLL^WPDtTH1>=h!blO3wI`&EncTWEer`j{KqS60cI(#$7t{!oRO^jEOQHO_ z475EZGGX-){NSeb1PSXRaH$SRqL8BYxQsmM^00*KDL3SV37;2dIG-nl^p(;QzA||z z(&vJw9O`;Jid@D;ETd4@C1XE(Z)(KtaZnN(ouxjH+hA1VpoPr(Bq@@SX=`K~4d2dz z66;TtXuGa4%Yf71B9m-$bwWNiIUerXGK{NwNd*^(d1R^WxHX^c$u zSa4LB@N7J!jc={59S&u?g;4p%ttCIQcvr>^Vh5H=U3QA&ygazkZXa#s7__=1aT_ zowx1$px3b>WqDdZUj%L`!_LCWZVi3SVf2sR!TC3w zn_fY_uQDHCP;c=2G0#UqG{-T}?BLbTHT`5ey@SkFyu*A3BOGgAHD`v=$GN{)JjWl0 zbeQvGt$4ut+A_rc2GGm6{*na4NAY;bd~e|h2jjWm1sp0`{2A+o1vnYrb-RFk?>0JU n*1$uB2@JhHKw+ZG=u)LzONt)!8=dc)ebpMrh?ZSI+v literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Modules/empty_trashcan.module/empty_trashcan.info b/scalos/Default_Theme/Modules/empty_trashcan.module/empty_trashcan.info new file mode 100644 index 0000000000000000000000000000000000000000..e80532dff99c3980a480b78a0e2677f105d16b8d GIT binary patch literal 3183 zcwWtv&u`mg9LCdi7j}Uo5|=nxUcYfmow%hx5+`n*#7@#U3GwS@P&cXDPIM@1B`803 zLA`;*i5q9AiV#9{Y+A*-b`u;Z-4EOh5E7i=4}tId+R56fEgX=@oWag=<06Sy{RE-qagwZ|;C7a*o+X1wjaA zD`lPpbJ+q3l6)?xRZ68wy-?PJr9wGpa$FD~3a=N8cuLjvP-Jp4#$B?-t*>sBBB4-w zyngHA5O@9X`@754Hg|n8_LwVf7I!v_pP3V_yZf_SuIsj3cXxNYw&}VLw%miOcuB>} ztM07Z+HO9&yZ=yC)i@$LfN}gucw%)N2E~1taoz1WUKn%TqU+KOYcvB`{II0Pmel4! z>jn(&&Su4({ZftNrKRBsH~RHR>$bMHfTWP(bUR=*EjCex$LI}_!-?OYzmjv&v$2%uigCi8wvA2Zj5!;4jcY^@}K3jlha*A zv-yaelB+3td77cWgytbohEGMJS~e}qauuj*hfBfx#$nQ!b{wah!Epd5B&$Va%G0aL ztm!Dvfhq8wsYSB+D0THfz!)RTHZ=u|&2CwwoG+&3blOKLOeGxk;w%#BX3#FCDgERR ze4Hg^0d?TBQ9bQTmOCS*=-dWfI|p+|vtWkl!-*##o7!*;mJoBm4Gm*ZI^E5HGA6yp zKJL-L8yM@{rJ(^Eo?=|nkcEA9C|Hs)4U}D!V&W`)f;6N9&B4p}qGDcnA`u@GUxYWD zE+P)H9LbQLnqs)&FNu1+{7PID*?b}7&5K4+hw=kroCwEbVuDeoPiX|Gl2HOV;Ac_k ziF$0DfNH!&2NJ3fFW`~?2bL5Og3w4JUKbI`Af=2f1Rtr$GwldIgD+WPAU?cc5mZ4H zo)^UoKS?l{mY85_gpgUWZ2i?SM~C+SRcgG#heS-hyuAT0(#*pG@|Pq!}%KZ zb(pD9>P)RE$g+wYE{4M#5eIX#y{BAd)Fvyx`lM`o1Y(SHs)}Xt*2uOp+p{b6Gh&o!FRRDbxfq#mej>3^zhsRt@s z>Ve9ZdZ4nU9;j@o2P#|ok1AXEHua!2G3DmQSyo?oKe|4pV2r) zSyWZw?8=r{WtVwm<-k=d3ujce4go`<#RA*PQ#*T#hizOGVb2+LN^66OWpy*KGxG40 zi<=F!0h-~2LVrroV!u)RnR+2h@~M#+ Qy}6Lj74$qw4NHN)0nY)E_W%F@ literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Modules/execute_command.module/execute_command b/scalos/Default_Theme/Modules/execute_command.module/execute_command new file mode 100755 index 0000000000000000000000000000000000000000..9bfd854a060ee6fe6a679cb1feef2a926cf99c9c GIT binary patch literal 2308 zcwW7gL1-Lh6vy9}S=m~mQ(}W!w6ohqkUDFOK~M>u-6Wa@-Nu$KB1K{jJ@lgSq!+t; z@seYXo=PktgRLkMAyTqUp$DlFCLT+6iuO`wGutd-#q8|od+(dso!wGfM0|($vj5-z z|9#)g&TQVCJyihM*P3~IqA*c7J_P^=;V3+Z6A}YZ1~5&L6EIoGzk||C&2!76qoea@ z=kdc#VWw#>!TcAmon1b+xU#soXxm?{tbG6L>dN(>uP-evHTRm+r}7iD6b!@AWWF%X ze-9jh(=#XD19&6>Id~raw|eFQdNhypVoPGR`ewa5)4z=EY!32dp28WRer)FkT*Z8P zeJl8Vkf-7}nFndb|2eOR`$iK|;km+T_&Vwy7~4A)$eI9|5h)!PU`(CQ*bcdm*&z=v z4?ovZUG7yw-f**&Pmdc8=f@4=x@R%hecy#m%HK4kN%@-(#lbU}gWtHN);ABU^}Ud1 zLM~mWs`A-XH!r+v%!My&*{nzTA;(E|&L=#G_&}A`$;coD-Rnbc$+ia?<%y@I zREP_w%GcjUR5Q^h)qN0j^N5=n=7_d14WuJ_FT(pP3i;bDb7%TO3xtrCmFv1poViVgTLYhrc^e+#uwALP4F-Fr{8SWlEYGCyCj z-j4dyXYPDQo%Bb~$Sn}t7x6b*JaxG_N}cq5mr3_el71imv%IqELhZ=i`WPR4us*yX ziXdK*?QcM=(Z1F^>m`6oAktEvj`X)!KVL7R|4H3O|BpKA#x&{1XZ3+AAYRaeDG)!A zu1%7zoxe-|;m65;h4m@cOLaRSe=!mIlgCL7iaiyb=Op$$!r^4M$7?*-KmpXl|#+tIn_Q-975!4^jkK1i#cmy}N^2IkGbZahpFJf`46q1N1({GXMYp literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Modules/execute_command.module/execute_command.info b/scalos/Default_Theme/Modules/execute_command.module/execute_command.info new file mode 100644 index 0000000000000000000000000000000000000000..52740195ab82a3764bfcfb9ceaa84cfc650c3ad3 GIT binary patch literal 505 zcwT!fz`)1=17-~33@kuCWB3Mn4hF1%g&}-n?U(R{uXZ#5c?~FX0uaiKL5zWkfl=lH zGm1V4;2}sef8hWB07x@&7%<3yX!ZjP%nd*qB%J`I1)wwsL|*;~NWB7sf)Pl+1j7Md zka=v(49p;!i3wspI?enK+1~p9An=C)O#T1Ca5WSJ0tnJqSOXYD!L$PdBZvkW2ct!y zG%Fg-2vINU2&Dr+<^?c>hJff0Mu_>iXo$TH3~<1eTbfgnS(cev4&s5Lfz2%-*wzTd a;|%w73GuKsF#s#{aP@Te2(dLbX8-{6k5@(j literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Modules/format_disk.module/format_disk b/scalos/Default_Theme/Modules/format_disk.module/format_disk new file mode 100644 index 0000000000000000000000000000000000000000..c7ed80eed3ac8ca8c9a71703a9350de580a60b6f GIT binary patch literal 2208 zcwUv2PiRy}9LK+JC+WV1VdtfdO+1Jx^pK#3M;B!eftRe&?26ljP)h$m8!u7g}9Ul+e>N1LZms=la76eY5UsgZ)RT1rH6fQnVp&M z`^@|O<~P5YIWarm0Q~FqQ`JVbQJV%Zgnjg*r@w$EaQLt{>ET#oYL29Z_4V~jU$x$; zp4r$?)ZX6S-rU?=TwHu~ZffiP@%b~~Xsw_9KD2e@2+^yntNTBFx3Y5LgYP~*_vnl9 z@$q`Sz6`W(wAMerb?xZ##@V|M4m~`3=#y($yj%P7Ax_QAPgQATA2T~siYJjGU8peQLOTvhXtnDBdgo+jH&RkMuI=oqNM=yP zb8rwgtf@}2xCkyCr(bb#9*)PltC6NDcN}-)sP&5DdAPFGwRUka+2H!!Jx=w`MLM>+ zg0yiFx^3euX|;AadU9~(koFn5}1Q{iED-oXyG{To}_l6f|Vl>MT^2W7_S$G%siL*sQ0W2SeL&&~`r5K$L@< z;LPeOg5@}4nO!(8O>JCynjaTI*Z5oGN4%E9V_fG9EXmMXIGHGA6B zQfL#Io;jv;LVYHM@tZL^OHF=JerRi-5;Dobk-u~R(x>HwJC(IbTC2mJi->Godgiz} zK4dQRB$>G1&!2K1lKWp%dJ9hTNFJ`rP zJ_5XP9pahgn!`V=R7I;o(-XbpaZ`1<9){%HkskBH_HaIx4d9DJ_4?n_!Gg#uHw HD#hl1%1LLG literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Modules/iconproperties.module/iconproperties b/scalos/Default_Theme/Modules/iconproperties.module/iconproperties new file mode 100755 index 0000000000000000000000000000000000000000..b40d427d237b1bdcb7867df41cb0dc86b3aa385d GIT binary patch literal 1772 zcwWVnKWG#|6vn^1i9+yXgN6k0PyB;m5#``m6kM6yB_syioCF)OiN#fdU3%-qB6Se$ zQfy-(HezwG-4R$T5iBeWq!LfoLUeWfZr((%Pf91Z-z^@u1?^_^2$wM-x%g_4*z+0#^kP4f5bBtSlG|C z`$2ako|(Fj{(;-)#_jW@BzNDMJ~@kL~ikKZ(BlnR=S1xqMb!q<`cKFixMRE-uhN z{1rILKovOu5twE@b@12v><;xi;KXs!XYO-Np7I{+qV*+U<`(PM(qFGpKW06M3FIwk^hxSR)OT5bU~EwH-ZKwb-)69vzC-<-^%L0l){E4ySifYPrhee&<*qIm F-vR6-5f%Ud literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Modules/information.module/Information.info b/scalos/Default_Theme/Modules/information.module/Information.info new file mode 100644 index 0000000000000000000000000000000000000000..8d8208bcc1a0075104ab4de54b9df1f470e68008 GIT binary patch literal 3183 zcwWtvO;aO99LB@47x$ufFPUW1(;1LS2IM7~WMGoaBw><4riZK&k_@mVYh|HI@ntU- zCr^F|ODQbNvSeLqDVGJR^dQT=IAqn@Dm|@Vz`FFx^6d50naaXG1=GV83NGQ}A zt=zsmz}-ChVSj0=#oZi_J?4rV#hs1f=hj$r|6q30b={`x?(S|+Z@BJ*P51CRUR3eY ziaYBzx9gAg4<4$j8b?G2FpfVBkFAWtptuh+uDcz_^CPZXbX}TZm1Y2ody8spQLP^~ zZ^7X1Y?$usS85zDE)I^l(Qk&DceK47XK!msx}#PhgnOU#&D@p`G)u-UG+IB@l*aw* zdjt7L6Uz_YTEAQ2vY!>;XL!A^AzW3z*quqfx%J(*66SwgAL*q1>PJA8d@2&vvT0eCr+}Jjb18UVJ4%)&9mnZpa2&u1$!Zaq^7NWw z)^wETz!Z4T)F#<{l)8E#V2qLFDm4X+&2HPIoG+&3blOKLOeGxm;%pM>WY8|BDgEpZ ze4Hg^0d?TBQ9bQTmfItx=-ef`b`Iu_X2A^8hhxt`Hg(AoDngps^lw#s6eS$Qk1I@w9_o8B6cq|bg5nq8f zoGu~`vK-5ho|s^G$zKxndhPYND6;uN$eR}pqc-IS#5fU-$HWAqET7T{P)5lBIpAkg z>4{2glz^srn+_yo5-;Gf{|A;75rWWAB3=;@$snbSYy=;v$TMvVK7%h=qAxx;Zxdu9 zljlV-!;cdTrUnyCjS#X-yQ;r2;^^=mAaj~m_>hRHm$x_IMLHSAL&UbLuMX)t$8dg{ z`Z~4>358+1%WyCm6Nw)B^D#F#3U(gEvIv1t zH9Fldj^PU;5q7FfVxu-!#nt)~u&D~q3$uNAk!HZSI#;VhQ$6)#NnKFc(*IQ1QWsRV z)CH9-bwOoIT~OIl7gVBbUL+KtXH5dXm(x_sI`*4olKNyn{7`&`-| zyzdEaa`_yz;$~dszn;778qQL2XCP`9m!l`>jtgn4!F-HcOp}AUufb3S-=`@T41)~W}@o%Y{kiz;t^pfJ{7lO zaVvQOy+2>v-vig&`4>+4ZQUPsRe#oTlfe}$@qv5^s1HIDXJSsa2T#whA0^9N%x@j1 z{Ek=!=g>S-Tu6KDI`aLr;@Fc7glNCuNgD2Zu^cP*86FhOe^fL5zt%eJ@(pcBK84&fK1mZjqjlZW5m&_?Ce&o+A9kkhMbu=O1DG2oYXParcgo z;4Fgi-6wypcygjR>8(6Rzzot{`roH12Iq6VWm5j>JpX2nA-KrGIAaK>6Fj;__53{5 zx{1wflXOCw>YD;PM-^1N?`fC`LK@(Q&joC}I;PLti1LdMTLEv_G2XEe@=WznO{#*c F>^CK$`z-(f literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Modules/newdrawer.module/Newdrawer b/scalos/Default_Theme/Modules/newdrawer.module/Newdrawer new file mode 100755 index 0000000000000000000000000000000000000000..563b540b25da9cdfa8c753bc9d1d671003ee6b69 GIT binary patch literal 2116 zcwV(sJxmlq6n-;%9+$Z6tzfYQcndbhfL?-y1>t_!fFztCvCv9maRn8ng)vK{xW>d1 zx+~39mc}z-a>i(JAp}CFVPk2K7^E=9yK&x|J-9nG+>!W-@7w*pH*aR&?99~MLJlA{ zJ~NxmWplSY0JsQ4FsK+J9DIP05te2!naj*8DG7O5EEYY_%jff-%ijL}g+igQwzgI( zmCEIEwOW-@j*X2e#0pTFUdUvz6xd)*W^&W?%x$Uo;wT2rJ|+eW85@R>*CB*fM5b3wfj)U%d-rqj!UthxO|R z<9fUZ$6Mk2rlrT%>iS*S#Ql&W?t{yEy!_IM?}EVng=8<2La}W!+-uma>;H2ADg($9 z+i?D7l0!e1l4*UIg|MJspfpDnU;p1KS9>(la1hJQk#i--q^joSpnpp88L z6EQ+5TG#u1o!VhH=_&kA`1&tjJ*QFV(Ylmsf~ed{H*OJqFx5q+N}F=Apj-e4;3n1U zq5Mc{2P^yVSmpSzMEST->!qs0UAC%nT=t@&bK?#cjYU-rLA^$;e24}YPZ0fC)Ym^^ z<6YGUww%GkyUe0^!LMVw7)~nv>j$+N?CJ`(F7=km#Dv1ygF}VS?HdZ?uTZz?6hD>f q-i1d#qCpFcP}dVOt+F` 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 O&l~xIZjkhl6#5$>9h2Sw literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Modules/systeminfo.module/SystemInfo b/scalos/Default_Theme/Modules/systeminfo.module/SystemInfo new file mode 100755 index 0000000000000000000000000000000000000000..231ac6e92cfcea79c8b957595e8c01e88a51ebbc GIT binary patch literal 2140 zcwV(t&u<$=6#ix%Xe45?E})m2g^BxgfQ|2;l?&KoJMJ zIe;wj7eqodxi;d)1p?9r4!s!RDiRe!sW&aC2O|HRCasTCA(XgPlW*C`Mi)muWY+NFGNea8ZFb~1Cr)Zwhj;m zG~sq|641Ri(!}c|tDj-(@Qz|g9C(-pOyYIoO%9u9do(^QW79VCluXRyC1rX)&$v@( zKH8k#VgI<<^LIi!%70&^n2$IC-S>Ct8`wXfyTnI;_EC5vR9Ep$nfK${wjcl7Z9l$% z%Fpnm%Fh(G%8#tdFE;)lukt%=D1Rfc=YLl;ayb*JiH6z{rd_?cqO13xJnTwdR?0)! zi!Pw>@ACe9zUP&VZ#$; z6q@v4@Kd=*y~4-4Kdut)A?+Zc-@W5t+)WZb`R*p^U-6V)Y_fh~h49n3&3Xx)^tjz| zFo7)L+4m+n{v(U@`N2uj=aa0T2p=c?xt2}wb0b2-lE z)XJ9}=PQTu&t5Y(9L!y1{KYSZS-)H^5dO{0ZNk51Jh5W2e)H`cgkSw^m3zjgo?U1C zZ@2{tn0>&fkQ+^>ZR+*Y>zMek{F8%o zbk|84UT#>(rIs5Byo77?BE2eqZ_tLQArBk;RZ!M3oh-mOEdJxcw%nk zz$Uy!XG$AJNEpvM7SbD^JhTXZL}$v4GC^<^7?Hn9zGZ*-mw>LoaqHu!foJ3gF5jL* fzMB{vVC0?mc^p?lLxmYoW2hf8v=2^m<&3<^^=Y3!D z{Qg3yCqz{VeHZEtorfzF>d~J3p@&XV&-pw0hl4Na;g9rnxLrT?FzgS#aGeYF{P}S& zyZwu)16?rQX|7#)_sZq>=-vD9dhrWTadCAeyl^dSxhpHzKA3!K?d=^9Mb0tXxF87O zyjkH%xR5WBFwqNP)hw6ITCt*q%f(8;;Za#C*zyjp;w1$y zuX?jybGz~A?*2nXQId#g04DJ#(XrK07_#2Ooab#P@xqAbl{}ATSfd%h;`=2fv7|H( znm1tZb~a6K_Ddy+mzD;{y!h8c&D-kUj=OhrS-Pz_5W>4p`ets)`>G}578-3FsM-1Z zSN8_=N0TcL-rTrT1ZzRnBurbnEJ8bx`>3^2nN>6nZ z&+9RHT%I1Mm#-Q6OK2PdWdu|#uI4kcEKdV9-R8#Oef=6$x6OvbBGUe$t z&8+Dt&w(lMzNt;}dYroYAYhD zg8*kqSwIc=d|b-}lI8YDDLS`7*UrJ*@jRGe`f%(i$fh=2gC)cqa07!Fl*x25pqxeT zae(_Y@CL>jcWI!{fu|T(Rb=BpZ3>oTOabMTq=Yz2pCA=!Ky&a4yr`HL9!n)h#Fya> zr-_JzEJreACMOwg1WTe`ufCQPMK)gq`SYS-)TV-f7^kAigqUKK6;LVxs%(@&F8JA0 zTB?>9C7>#A(}6@x;s-qP|G<(WLJ%5CC2JxgIh3s+8^K2k@=e=<&)`dz>PrqT*aVr# z4tX_*P8MhID^?P#x$xEj0%$gJ{NJ|bf3z7|vIz zuggr0a(ikui)_2Z;ZiipA<>uX)*ZI$07MpFg>`dQl+y|YB(lleMjgZVpd3JD@Zxin z;yB#NpxHH&G1E52*eCYPCJ#LKfortZgANs@YsYbo&`o zf1LKWrOf7qov}=Q7y|GjFU~h8GS|uQW15i+CKQJ4uE4?MOeFf~PerT?k2r7oy! zsS7Gw>VnFax}dV9E~sqjKdNlu-&8g)oLJe?iItsQEDC2-Hh2#6*{q%wg)=If=W{BT z%`Pg6aCT)&tgO5I;FM2#I`#b*ctiw z$;C~Oe~btnGd)(`?79DUmT-7VgVT{%?4V2}v>J7qp^s)bq0pZZwAe2cf38-{6McLr QL2oYTg`%dD@j)r{Hz6&OxBvhE literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Modules/windowproperties.module/windowproperties b/scalos/Default_Theme/Modules/windowproperties.module/windowproperties new file mode 100755 index 0000000000000000000000000000000000000000..d5b08477523812de04244458d382530cfbe19fdb GIT binary patch literal 2236 zcwVKHO>7%g5XZ-MQ6d!l1(ybA*KwrMpoVzmL&=A;NotW+!UR>}&0teIs8*@NZZk(o4rAiHU93g~A>#w4KwBBK6-daH_CP6&gZ~Xqh zd9&}$ytgkbp3VaFe|_r3`Rsi5WCj49f&_i29rA+(aO{|G)(0oDb1##WY)2w1E7u`H zE{RksmC0lvSAfD5Sh-#(6yT%FrBdPdhaV!Ylu9K;TsS>9&!Hd!krQ*-1^Mp}!_ujj z&Hy}i2xj3Z{NENpSFDa`hXKs0`gNP`Kn!WDw*tu4bU?!fjhk2%-Q(e60E;x=D1o*X zr|~LQi*Rrr_XiNdGS+wuKI!-6-DXn0cwN0(m+Ne+dv-q_@@$fwl1g{udzN_J<1vqK zd%Ui=Q=Ex2513mL-&xlszO!Lg55k*cn()x=rto&8EWDkr2ygj+68;1l!kZXU92G}H z#fLRD-(6GODXaLc`)YnDI;`R+)brbZwxLe-7S}83*Plx>@6@9sRb|JShl}Gfzn*r4 zM^|?O%%k7$R1Uy{W5Xd{hta}DgBGdPj7E_BwYt&dbqDR+vJb<207>R%4TNJ0IBw{{ zh~&YD+_Qz>vi;2U$d=?SxS5nZ8ntp=;_ujMe$|$|4@3>AQ|f*hIsZeo67ar z`|;q-Ha3`>p_q?&EDhVNYn><6`5CTbi@4!xz+9X0sq-~6E;dMYvYFdK#cjnkTg?yF zQ@GAN>~UCCd~8I;kCt7T-*G+e#SfPi@6i1wouP56BNd0F>ecleD1?JTTcJ)LY z3l^N84PK%DdZVzPJ{w1R-J2ALLhF0m$kV2*N0!vpdC%bWy>wmrv-G|b{ZH_E9d|_^ z5WOw>uIP!2tXF+gTddVZPpyv{nZj&~)_ z5%$Mxtm88h=Ns|AvB3Tt9N#TcuiqP`oSYrGlOuie#v*Y48r_G&$K?M;?mg0{zj!AE z)IX&7hnE&8+VWR_Y*{dMI4ilCq4)t>t#PWt3! zKk3t-@{R`Y@a~pJcR9{UVE=y3K=@jYvhnsAq&yrS1zO?p(Hv!L@KxLbc&l0Jv%pwS zkutTx86FzKUn$PEMfyZFPfGe{)}MCq62N&M>yyCxq+j$4_&KfT66??Rvp%uJdhAP= x{Ff`Di~sZoQpbwxqdXvxJ`GaeidWx0%3D(ETmE}}oxXpryPVj6JwFF&e*whU__zQ7 literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/PointerIcons.info b/scalos/Default_Theme/PointerIcons.info new file mode 100755 index 0000000000000000000000000000000000000000..283d87e820518f604b4cd48a7511fea82fbdb29b GIT binary patch literal 1695 zcwSYLS!@$W7=UMeV242WvfA=M*6WShA~kZnIn+X>V0mXL5@4se)2V5d&mBN%0?1O z2T#GzUm+CvJ;Koy99yT< zxwhN~O%KdGi=1p3Xv&xz+wKG5CKghaWd;c|lfayJrwb)}fhhqGXpZA}V&+N;R^~`T z(YJ$J5N5!>DH3)C0XQE?y!^K$5Y_9G7RR<$^Gc{o}=?(?;TOMYftC^{^QZ3}iqH2|TpCUM7m* zm=%7U$N-6(XS!sv9ar)>s8G;Do+v-`Le{!SS4JhRi$$mJME z@CisdDY?KLHrAK1n;7A7W?x7bwo(5SgZQyE>0Zlh5JUs7^ z5z|XH&^j_j&d!M9a}|YYD^%K_fz%D2NP~=oX&Y2p2PQ${8qW)<7kpwJSzp+93F~j& z5^k+*k&I>HF`cEZ6>HDR8r(XtFM#z;w;E8>EWVf>qq7y)S_pEF&RTC@NZh4I4^#$F zUuD~wj=g_<_{JCNs%Y zP{K{LdI|}dVp9e)OjUqpSXZ6WN_wG6Cu-6t`QS8mrzz?wI6`q!y?-z13{*8$HqHk^ znpTILRGLm>H@UUX>`>D*e~J>P>9mF5&yUxLRgA%toolGj)DPuLo?PBBMOQrIY4 zi)Zz9mxB*2ouY6WGcJ{kmuq~f{cECmbeHe(S15$Gw};i(0I3z%azcQd!rD`D z{~dF@%^>@yv6GrMHoW#!@{TDU95F!BzygDfu3WHu9!WmJWzs$Nj2<&u^Z3h&Xm?Mq zEHYKsd85nw636vCVtkzA$4fR?7J`bNwI1sjzfg_Vw Qp1Cz-(sq~Tt`DWaf9!gZGXMYp literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/PointerIcons/copying.info b/scalos/Default_Theme/PointerIcons/copying.info new file mode 100644 index 0000000000000000000000000000000000000000..8a90f8197a00cc05149a1b01220a10a501fc2c46 GIT binary patch literal 433 zcwT!fz`)1=1I!F8K*-3zSZ=pv2?I93$ih%|zB&VlUo-%@4JeWd5Q-THnSdtDUVeVSTYS_&@ye(E6#t}dP-3Lze@3U2;BKK|jJe(nlB zo_?;uii!$AMIgoEp1y{*PR90%s#~(o*k&kNT(&=O;^ZZeR02rq|C422Ko|-nmae&Q z;lg>}3+Li5m|Zx(;X-!&1^)}%He6V7;qU>Vl2hTkmwBCCbKx{LH5Y(tfW#@VIbahV PE<&w0!fm|~O|1t2sduLI literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/PointerIcons/forbidden.info b/scalos/Default_Theme/PointerIcons/forbidden.info new file mode 100644 index 0000000000000000000000000000000000000000..c601c51e2faf757eb6b8d2b6c6254c1d551fba1a GIT binary patch literal 555 zcwT!fz`)1=1I!F8K*-3zSZ=pv2?I93$ih%|X0t)rCF2PVKyCwyqymIu20|vF2{V|% z-2Y$zSH$I8np2WlmYG@(;;8^J6Ih?7mX?-+i@%?Gh=Qw&XNW?GhpU2{zmJc9xTl}H zf{&-4Yp|lC0#Ff1v7o1~p{BH^Sz2qe0+yBYbWL0CsJ; A^8f$< literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/PointerIcons/makelink.info b/scalos/Default_Theme/PointerIcons/makelink.info new file mode 100644 index 0000000000000000000000000000000000000000..be6557f1955534de14935cac64fa433c57191a3c GIT binary patch literal 387 zcwT!fz`)1=1I!F8K*-3zSZ=pv2?I93$ih%|zC5DreD#Y4Ah!WUQUO9S10fU8gc;0W z?td_VE8_Ak%_+$&%SGD7{;G>X4Of`*(AZJc1K*uF74tWgv4F*Pa4^VTV8k9&5rJ}7GW$nq1d5= zQFILE)Tx8FI&>H#uu}v=)NMhiONWI>jLn(e_gh;vf;t$z?EdC^-|z49Ju~Y;5Pn7{ zy3oiu9f+*-^8Ye^4GP>gPOdse^U)ETQ+rRRReQ)P8Un$mI`%cl78-vT6;y0jY_^4m z62cZo7*_2*hYyIjYWvdGeV3Ovh2^+!gM6O}CXbl&Jysg`zXNXA-vk`fF9XZOWmMEg zn~JsezQwj)C8beab&KNhkW_5N#SrVIrbQWK+M?Ga(Yr)%9AJeWCO|HAJJ8*7C)e%G zb=FI6&XuKaF*7|m)*G+rJog2f)Rrx3|ARn6-DJj~3=ktJ7gSe9v50zXdmdWYXU}V4 zs8_V+thJ}7mbLHVZqGxGup(1culSl-?s;kRq*8H@FKdDgq?-{ZOS zpTu+B{jKK(T7s(7qwcvmkewdPUzsgT&7{wqj!8*A&5o{A_S%K1nHy8Z(OiDonw+)H z6>m=Gt%+w2biDMtVcHXe-uGoqM8L;Web6eap0RJ^GQ; zlo6Sj+!>wH7sj_h8@wVfKcltFV_xe@-beU>wve>F=iYS>p6@;K-WeZok$;0%2eExh NwulIFO8nPT;s^BF`Ah%+ literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Pointers.info b/scalos/Default_Theme/Pointers.info new file mode 100755 index 0000000000000000000000000000000000000000..d82ed8b856bafc74caa8ca748317f471843a28ed GIT binary patch literal 1695 zcwTLjTWk|Y6hLRZHcl|GFRO(QvR-f0mXFBsCPXb%3YK>^LIUhGn?wZ_Q}CmpsbkMF04`m1A^d}BvHj}}FT896icXdpnR+3u#I`hDtt2${{4tElYYItfYT&Jn0N5U{ z_XjqqK0hMTMRj$M1-0up`dUcPx4}{hLaU_?xb{2hbs=|;&KB#g>%#6aIy>+3iQ>5N z-S6f&_6ePxad}10m|kz0q_eZG!=fni&5tI5R~C*~IYZMtqu1LeL96H$jx6EW2BpEh z=>cedNbxLou@#^>XK`+Q0EC;mka1KPEX+&-s_4m5>WJS z=N5z+uy=~MT|xlPPXaG~O>_nmX;+n(5S}sC@8))%^g283S(q`5IH%0LTI=Ic%ANxU z3@gk!Ws&#sjc6dv*kq0?GPQC^nAQX1<+RIA{BUKqmLQF&6%7pJKpSy9w75|wg3y=^ zeU!=piJND-WwIZ#nTTH`nI3gEpjOWiMEI=TK!}8GY;5(Mu%TZGL(MZgoK0MTafY6P zvA1ZJ_DH>JXxz{EKJ*x(mpT=QrCE1$Sm`V4P<|5?@xN-&0E5) zrEQY2O+BIW@LIY4ysV)u1ABvdV#BS~xOrB;oFAj})z{hxa-YuI?p#XUqeu5Ug1Fz& zac=XT-#>W$Gj+vQ83Wvpzra_pjx%@{UXNFSN{3N9!7`)6s5e0EQy{`odI-Y%zzc<& zc;yrpa^>cn&M-AWnql1yN;~O=ngkJ(Mk$7-bx#(;zrbP0NsWO$q%&~MR7E)-3~O2g zcEK#2)jj0aKB+>QrUf!koTjr@f+Gqc9GIip#92B^Ny=>SD*~wT2})*X!Ml>G6@p5; zf#~TuTbBs)bk;5*RVffqjV0p~P%aAzifh8b#&BR9K1WN59ip2p&{>NVxT6OiS0g2w ziY_F&+zp~|h~UN0Oevn%;}hV^5mG`Du4uyJ4up`JiWU=>Yh7XiLMdXTttIn` zwLga*S-V8xtj@SeNF&+KcuEfqQv?L(BywIY^av&k=~;+M>sm~=G_glW(UQf)S}pY5 ze^6_(=gfqK{8YcARcO0G7k#nVj~Dl7TmI}&4E%(Fqp~j*>%D&pZSL$=D@p8bB2I>1 zj>QK1?`Ueb8Z+QlDI7XjmFyY(B{ZzZM=NJrBt?|aFda^&z8P#+qUH30MHUX(xF(Y3 zoDz#Ak6lpXqx$iMe@YQQ=m;mzM|(O-i4S}GNY$)dQ)t)`4#y%&w2+>+8Zx5{^S)?H zMAw}QPre|PT|BNoOrKSu3Sa@c6C@)TOxR!+D$SjPzLUm;^*y# z*HU1vlrB`F#hCZ|jVx@d1*nUe5_ZQiV0AlYzTb zvcn+HOzSQGWMoGBjd>Yi^jaU&iCDM^Ay70%};se{V@CH8MU4oW)8al?Rs@ zVm$~BoFRkMGLFnFkpYL?MMy*}5!o&hvyghv`;~yCvqc|X)j)M+j6F;)&)8`%0OY=jNTA4^bvpAu|5rkb#*;nEcUNG~v(LVG=~=mzH`?`WLu#&tfbUVoWxdf0txl{NGxAyTP^4 z+n+WM9~JPb#sluuhB(?o;ln9#bPvU6z-@fNbsA!pKMOo-&U=HqbdEV(;Ueo}$v?-U zi9iKQtOqlhP9+}e66~XV^_1~nC~JOBY587p$cD_@hJNvai-0)0k6UL2F5SGBb2ig= ze&e=;dwNZ*ph(}0?wep&nB%9#eJ=jlGV@p*Z&`o+1md^{UKF1Gr-+uv{&>fIZ)c2y zaX;FJM>UIoV!gTp&*8Jrt0>6$wo%7B1_6y6W Ki`=N^Xukpa`fXkS literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Prefs/Modules/empty_trashcan b/scalos/Default_Theme/Prefs/Modules/empty_trashcan new file mode 100755 index 0000000000000000000000000000000000000000..473a533d9e7e683447656cffa4a1649246db2953 GIT binary patch literal 1884 zcwW6#J!lkB5dQXFlC#+4MNM%?er&`PA#7N*2ut>o93}zJgpeX>6%NZ(Y86kgxXw~j z2q~=6Xk`Micyib+oP}UxBG_mlWN{1eSToLhZxfOeyolhy-0aLZGjDe0-R!mb#WIjz zn!7$#o+{6l0QBJk23Vpahbk~K;uIZBmnRq4)e1 z*Vi{UH+Ob+qA1$k-6bO5_c>r@adJwhLN|J*C(ASDIoFG&xf?4$X9tQH#(yByqQ@=r z&$uTK?XLL^WPDtTH1>=h!blO3wI`&EncTWEer`j{KqS60cI(#$7t{!oRO^jEOQHO_ z475EZGGX-){NSeb1PSXRaH$SRqL8BYxQsmM^00*KDL3SV37;2dIG-nl^p(;QzA||z z(&vJw9O`;Jid@D;ETd4@C1XE(Z)(KtaZnN(ouxjH+hA1VpoPr(Bq@@SX=`K~4d2dz z66;TtXuGa4%Yf71B9m-$bwWNiIUerXGK{NwNd*^(d1R^WxHX^c$u zSa4LB@N7J!jc={59S&u?g;4p%ttCIQcvr>^Vh5H=U3QA&ygazkZXa#s7__=1aT_ zowx1$px3b>WqDdZUj%L`!_LCWZVi3SVf2sR!TC3w zn_fY_uQDHCP;c=2G0#UqG{-T}?BLbTHT`5ey@SkFyu*A3BOGgAHD`v=$GN{)JjWl0 zbeQvGt$4ut+A_rc2GGm6{*na4NAY;bd~e|h2jjWm1sp0`{2A+o1vnYrb-RFk?>0JU n*1$uB2@JhHKw+ZG=u)LzONt)!8=dc)ebpMrh?ZSI+v literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Prefs/Modules/execute_command b/scalos/Default_Theme/Prefs/Modules/execute_command new file mode 100755 index 0000000000000000000000000000000000000000..9bfd854a060ee6fe6a679cb1feef2a926cf99c9c GIT binary patch literal 2308 zcwW7gL1-Lh6vy9}S=m~mQ(}W!w6ohqkUDFOK~M>u-6Wa@-Nu$KB1K{jJ@lgSq!+t; z@seYXo=PktgRLkMAyTqUp$DlFCLT+6iuO`wGutd-#q8|od+(dso!wGfM0|($vj5-z z|9#)g&TQVCJyihM*P3~IqA*c7J_P^=;V3+Z6A}YZ1~5&L6EIoGzk||C&2!76qoea@ z=kdc#VWw#>!TcAmon1b+xU#soXxm?{tbG6L>dN(>uP-evHTRm+r}7iD6b!@AWWF%X ze-9jh(=#XD19&6>Id~raw|eFQdNhypVoPGR`ewa5)4z=EY!32dp28WRer)FkT*Z8P zeJl8Vkf-7}nFndb|2eOR`$iK|;km+T_&Vwy7~4A)$eI9|5h)!PU`(CQ*bcdm*&z=v z4?ovZUG7yw-f**&Pmdc8=f@4=x@R%hecy#m%HK4kN%@-(#lbU}gWtHN);ABU^}Ud1 zLM~mWs`A-XH!r+v%!My&*{nzTA;(E|&L=#G_&}A`$;coD-Rnbc$+ia?<%y@I zREP_w%GcjUR5Q^h)qN0j^N5=n=7_d14WuJ_FT(pP3i;bDb7%TO3xtrCmFv1poViVgTLYhrc^e+#uwALP4F-Fr{8SWlEYGCyCj z-j4dyXYPDQo%Bb~$Sn}t7x6b*JaxG_N}cq5mr3_el71imv%IqELhZ=i`WPR4us*yX ziXdK*?QcM=(Z1F^>m`6oAktEvj`X)!KVL7R|4H3O|BpKA#x&{1XZ3+AAYRaeDG)!A zu1%7zoxe-|;m65;h4m@cOLaRSe=!mIlgCL7iaiyb=Op$$!r^4M$7?*-KmpXl|#+tIn_Q-975!4^jkK1i#cmy}N^2IkGbZahpFJf`46q1N1({GXMYp literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Prefs/Modules/iconproperties b/scalos/Default_Theme/Prefs/Modules/iconproperties new file mode 100755 index 0000000000000000000000000000000000000000..b40d427d237b1bdcb7867df41cb0dc86b3aa385d GIT binary patch literal 1772 zcwWVnKWG#|6vn^1i9+yXgN6k0PyB;m5#``m6kM6yB_syioCF)OiN#fdU3%-qB6Se$ zQfy-(HezwG-4R$T5iBeWq!LfoLUeWfZr((%Pf91Z-z^@u1?^_^2$wM-x%g_4*z+0#^kP4f5bBtSlG|C z`$2ako|(Fj{(;-)#_jW@BzNDMJ~@kL~ikKZ(BlnR=S1xqMb!q<`cKFixMRE-uhN z{1rILKovOu5twE@b@12v><;xi;KXs!XYO-Np7I{+qV*+U<`(PM(qFGpKW06M3FIwk^hxSR)OT5bU~EwH-ZKwb-)69vzC-<-^%L0l){E4ySifYPrhee&<*qIm F-vR6-5f%Ud literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Prefs/Modules/information b/scalos/Default_Theme/Prefs/Modules/information new file mode 100755 index 0000000000000000000000000000000000000000..3fbbaab9ea414c7d76883862c7fb80577b878d44 GIT binary patch literal 1820 zcwViQ&ubG=5XZlpO$^1w4H5+}CFCTfhlK?}*s|F)Sc}F=?V+9&gy1nJuUl_9^x!qO z93}rkE(^IXBbUL+KtXH5dXm(x_sI`*4olKNyn{7`&`-| zyzdEaa`_yz;$~dszn;778qQL2XCP`9m!l`>jtgn4!F-HcOp}AUufb3S-=`@T41)~W}@o%Y{kiz;t^pfJ{7lO zaVvQOy+2>v-vig&`4>+4ZQUPsRe#oTlfe}$@qv5^s1HIDXJSsa2T#whA0^9N%x@j1 z{Ek=!=g>S-Tu6KDI`aLr;@Fc7glNCuNgD2Zu^cP*86FhOe^fL5zt%eJ@(pcBK84&fK1mZjqjlZW5m&_?Ce&o+A9kkhMbu=O1DG2oYXParcgo z;4Fgi-6wypcygjR>8(6Rzzot{`roH12Iq6VWm5j>JpX2nA-KrGIAaK>6Fj;__53{5 zx{1wflXOCw>YD;PM-^1N?`fC`LK@(Q&joC}I;PLti1LdMTLEv_G2XEe@=WznO{#*c F>^CK$`z-(f literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Prefs/Modules/newdrawer b/scalos/Default_Theme/Prefs/Modules/newdrawer new file mode 100755 index 0000000000000000000000000000000000000000..563b540b25da9cdfa8c753bc9d1d671003ee6b69 GIT binary patch literal 2116 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 literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Prefs/Pages/about b/scalos/Default_Theme/Prefs/Pages/about new file mode 100755 index 0000000000000000000000000000000000000000..8fca9a4732fb0fde3bf2b1e503e0e6499718fc5a GIT binary patch literal 1548 zcwW7fu};G<5QhI&g#{#MU_?#W7&;)agOgU2N)1I73mX%!kd1ikD|E~3r{DoP@B&DA zf+|nIaZa3)grQMe@N&NUF880$k?&^n5IF8lra>5l_agvjIEBL&y)G0m7<6O@!_a@^ z&=mnml3Yic9leOO)})t26h+Y*OIia9;1gJ_@XEP*Jof`r3MUXlKOE=#u7jt^!!vNy zgTy8NZ4uR60c35spdyW}^^3eLPdNa$I@I83$+79P-fsqR7+&bHELG=a_HB3>C)>aA z%bbI7tF-$L`&mdhNYQU2QXuABC1dra pVvb8|`3ufVl?JNY|j7y literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Prefs/Pages/desktop b/scalos/Default_Theme/Prefs/Pages/desktop new file mode 100755 index 0000000000000000000000000000000000000000..c1a05edb5867d632d05db816aaf785eddc51e9b2 GIT binary patch literal 1676 zcwW7gF>ljQ5Xb+{ODQTA?m!`^NQpWjRH>G{Mrx8;w3RTe0t`%*7&5RhW^4zBe1%F3 z9vCW%p?elfT{2k8!UyP>F%lgRGCBV5J-1yD1jXWpyu16|yYpTAo}V9dBjC=*{TH36 z6YYfn9-xL*uBcXU0&H$NEeAVM`;abQlG8Yj!!Ydidi{PMz0;tdgo8nnB*Wp55h8*O zItJ(oknDEb9i0k~;O(@dU87f4@p}K|TVSb*7M|jN37>6RsILCmzP10zJ^AKyQRB?| zwVvAeyacZN!YAT;RvoARz!3xmcO^5LD>i?MGC1oi!>5va7K^Qqxj1~7v}!E=*cK9K zoH72ro;jY9`G4ov zCGn2KU-Lj8?Q`*=-oV&PhqSk1 zV2k{OoGG8od{l%Sm#D4)>sRM+>=NY366+9$S2wxv_~fXeewlsZ@PGvoT2^$_)5BR_6o=HS$|A8!x?n1 J$2Wt#m0!_}u&n?9 literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Prefs/Pages/dragndrop b/scalos/Default_Theme/Prefs/Pages/dragndrop new file mode 100755 index 0000000000000000000000000000000000000000..da91be5f5e84fa585cf390f6a2db0c0ec0a2260e GIT binary patch literal 1628 zcwTe!5AtPTU<>i|aq@NY^>ATeU=U%DWZ(tT3@l6x4GauAI*bmC49>oe0YD*xsZ*x{ zssI1~Tc5aQ_<$-uzM!r;K5!7vIa1AiD8_z%!dp7}q+0s9ZQ)ln+XZ-3y= z=RaU|JYaRymIo%+{}6cw+Q=XH^B=GMl*u#yKR_USDU&A@{}juQ0=&S<-vw9}GF%{} u4ju3@SfKFbIciYE%=_*!$TQWz`S$<+F~~C@@%#Rv$jf)2>PI)9Q~&_gUX`T) literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Prefs/Pages/filedisplay b/scalos/Default_Theme/Prefs/Pages/filedisplay new file mode 100755 index 0000000000000000000000000000000000000000..d5f8e23e3b4689841ba3cb0f306230905e093ec9 GIT binary patch literal 1676 zcwW7f&uY|A6vn?ys<;T;4k)-$+$q>aAPYBvGc%3-1IB7?7lI2x7(rdRa9l_-P^I$< zBEqa)_y88hKyhW@BDmHE5QacDBB94~b6c$b*~o0#s%9X9v3`lFwYY#q6l;-VVMPR2pYM$Ue-#PDd$7!Wzn|TCZ|BW!Wn-%b9KN+) zE!WDmvjKqPIEey}$Ys$6mX|Xt8LZYyn`}AM@Ai7Vpxz~*FEJbrH3O|R5jC65eRT0w zG_J@kYg?tVEQMn@vRbOGnR&K=^Xum>0Eco|!6_VYaA6e1f0@otpTgNZv|K3hEP}(n zPcDtbXG{Erxk})%k32b!C!C@rmgf|dnuGfk8%`7(&Nmn?>;DHHC7u?ZCrS-Zrd*Aj zd3fkXsb}6hGF&!Rc%-NK7vzzzA}5yon*3Di=NFRvA)I-5sKV4|?L{HQtSyg7`lKyb zl4D_x7@pb7REzH>iJS1|YNeFv|4hz>^7^iuxKh93k4@@NT-P=AFUm)W&4@j>8( ztfda}RAlO(!HN6L%Nj0yk^aZ#T=SlXi*r6#l*Ut@{?aDYY%XD8>Zb>z7m4yl!2iO` zKR(g(=`6?dFWA{EA`=H_U3$bn<{~<;8?ZiA(E2*TPSM7lw1IqDL6auTZM?YJfd9RM zo2)wzZQR~%ptW1!x+fSgf3{SG|8yJ8md4$jjn4fWxc1;BPEdfynE~42W!N7ATpYi_ z6T66ZyNddF8>jmk literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Prefs/Pages/misc b/scalos/Default_Theme/Prefs/Pages/misc new file mode 100755 index 0000000000000000000000000000000000000000..8cdddc19a5f52aef295ee2a84fbbb59d4dda21f1 GIT binary patch literal 1564 zcwX(4ziPuU5Qo1QwNPS6hd_5v9WofQcrf@+Ow&Nsl+dM+*-sISM~_{zdG;%0$phpS z`U=4h5KtwzA)$nBjS2Kl(&=~K=@ub9OlK0V`;(_w#_}-%`rL7&Bf=tw!Jrd%7|G~G zr(Bg%mZgGKwN!d2l@_ZlOU+bOs4W!m0h*Mlu1S&g!Q;E{eRgJdzOy?wI$Lev%=Tuh z+OD>nbpWd3)hW-3@XTdTAi$#r%KcQ$X{1M)d|xQ726mNQjbJAqLV`~yK6yc{A5 zSzT$xuDMSkPKK1NMCWl!2*=Fi$dM&kWhg9}%s-M*D%{e-GMncLp_yAeLK)zaR*Q4T zjtOP%lLIY{EehH!)QO40`P{s;Wqct?S{Q$6rjmH%!kkpB%pQ^wq!VLkrm*8E1&+WL zrt6f=N+DGgO%;x&`CK7@`3^`)-a^w4wB$b9B%)C|JecxWn|)BDh!QRWx4bwHtROKX z;-|)OvOY!0`fO$Dx!j&|A{j?huK)5V1#Y}BA!pqD$&~cc;fqGKQ|Ge~>U6)vxzPk4 z$3T|#{<-&fvi<<>c@Oz@55?6c8gF*-a^)GaZ$F@TeFdF|7xBD!0okWNP#fprdnYIb z-;o>t#?{_sNdGGe#OaTrzm%Xaov?A7;xp9#5`NttqdVlx{Y237ptoP3``Sk<^O5Tw u^xijg-w|4cM|jl(j{IYEKM}g_G4{Epy+d@5OnnHS-`nRJ8*CQWr{fQhP3%tq literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Prefs/Pages/paths b/scalos/Default_Theme/Prefs/Pages/paths new file mode 100755 index 0000000000000000000000000000000000000000..e3b0b94a120192595c7470cbe0a21f164f7ac485 GIT binary patch literal 1676 zcwV)Yu}Z^G6o&t_RSE_gL~zwjq(h*SAf}B)Ef_1+#TW1uqEJ-C!NC`B>m1*}K>`I` z0tI)aI5;?HKwUI&{coDsQY$UC9=JXCKi}>7Z|@E1O1WYI<0qwc(=x5KB7iAOLt{oN zfg>QBRq_g!t->Ztx_CydR?FFr0362=&bbi6w(Vz}3+GgRiywD@=V4baS*;XI*$NX# zFBh!UaGubxUE0_I#!|>*4*wo%5-w9F5Qf{K2j-MMAR7FwzLc*)m`BES8j_1l-DlmX z$NLzNbN;FVz9B@gNG`p+5psn0Nq=r%a^^jZE?Me>!aWG66qq>&*R~ut(DXy-nQCWBY*1PY4Z0D4kXy`fclv8D#sH4 VFr>cXJkK#h-i)%#dh>hqiZ3(xue|^O literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Prefs/Pages/plugins b/scalos/Default_Theme/Prefs/Pages/plugins new file mode 100755 index 0000000000000000000000000000000000000000..3b2aaee33de57c5792b24ec18af2c5fa52171e95 GIT binary patch literal 1676 zcwW7gO=#3m5Xb-d=(=DaL4;mJf+vxJk=!IS*=^Zc=(@6W4_+3%c#wj}AVOV=hk{to zz3Adea#|2X5j3z+L;~?v4@x~Pc#&WZiadDEWY-Uj%2n-`V=9LGE?($H1(fQ1DmP_WdjT_Tr*59s&%ZWu`*+72U@7c$zFQifsp8N1l# zN0B7B#vv>1TAfqjD5^`f=1O6!7S>lUUIylL1UQZVAzx0??@T*{-zX) zS#ZyQR&WC*DOX58XFjB`GMtv}GI!yn1y7+dkHyfL0ry3cB*lD922~r+y_Bw7hR5tP zxD4HsnbM2T^JB^+NyYTsq*LR`*QgJUoy3{Kb=?x2J1x{9`RSjQPbc-(GJOk`zYzVG z#g(pa0cW;!+&*}Ro^7M{Mg?|&tKS74oO_BuJr4v`+<4;Qp|OYcw<^@0g`4{uxOa90 zD>wx`uyAXC4R`$!?AI#nD;72nHn1~4LN)#Zo#I>H1O`VcsMyD#+YY*4-{blHJ?Kgs zbCm(QgA;i6se#St5%AcCLcPgOgMJn&f=+-}H1vM-5{ozqCF%p@TkLdc5g&gq?N56m FKLEc)ly3k4 literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Prefs/Pages/startup b/scalos/Default_Theme/Prefs/Pages/startup new file mode 100755 index 0000000000000000000000000000000000000000..5a6dd01f88efa6cfc2222de2b5a5ddec51ef2adc GIT binary patch literal 1676 zcwW7fziZn-6vw~kbCN;@$`I&kGKDsjgIi5yE5A#XgpfFN^VEOATM(f`$5OgvvW5)7 z0Vhi!#EU@df&PMq4&4gHkfkjm*LNos+!Cn3q7Og5_ul99?)lle^_{%{n0>qT$`AZt za}~e>o?xC7^%_E8d6~5sR)Y2}r35}9iXzz?Xkb7#QlpX5gA=WFuh;vA6TCBzLMgm4 zTQ>IEzA1&rc(l?EHtf1KkNvIf*T762EiB=`nc%s)*`N9^?x;djngCgr#x_nwTnWz* zJGolpIvbCTf{UyK=W)(?io|ettTS_t1MO766RpRNV?wxQTa$Jwk>~G9@R)Lm?H^L+ z+~qk}ssgTPgE=1(+=y_LHs`0YY~GdOu;0~~{r!cMO-=Jnsk*L)b8q6GCT!QlrS!a# z91~{hTdtHgIxVL;CX>8rKQ>>A$3=Zt>)5C$I0ar690iwB+PBA1N)?)x;cn6A-}XB{ zEuYr>omILE*~73+{-W@wR*1|K1LJ_Qr!f87S>+CWkMlwQ4G;Q$B;V`b(Jf=>5HmqxftkihzSBW_?b={=>T(43x($Ky0jN23walPJ#zM@MG21%t*rdkD`* z@9CT8NDXkhwcqPoS6IRFW-r+)=SxjI+unTv+;S1)KK^ra(B%k2IK~(V{S%l>gR6x( zL#7L+z#&XgSngOs`)6HfUCW^(%`)=CxiQh4&j4;_B6DuUjl)p#?zH4KGs`if{1)as zQV!M6s8}W{UZ^TQRZ!0nDTKC9e9DEgT>lXdt^czADf>$tbADa?oANsU*XGB<%0Dmr zr*+kTVQl{w=NhVvuXz?)ZZzdVoEsI^a`Fal-#KUWf~)(rRnTiRnsgnv>!JRkEvbyU zVATBFBK%)le{Vql!bY=hU-Ok4x6K`8=X~Nwe{wFv!;cF09JDW)Vh0aoAik1bf%x)P zv6rg|#A}821mg3BbcU_if4D~a1My2>=t{q{A>mcp9kyi9S-YZL(i^|%t9&&MI`lTZ uoOB`GgJl_XAH`^&NpbNl_EaPT|B&KIy4R@+{2e<=o4@zzjr>iirF{o~X0&_& literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Prefs/Pages/windows b/scalos/Default_Theme/Prefs/Pages/windows new file mode 100755 index 0000000000000000000000000000000000000000..bfb9248cf6c42c5c2dc6bdac85fa0e5616144853 GIT binary patch literal 1676 zcwV)Yv1-Cl6o&s88wwTbP$=C?>EICPDwss66`ES4i!abu$ktlu(6MVa=R8DJTm|P+ z`U(>0;t;$&=Xy07u?8A{4JY6I;yniv;&rp-0>*3O)^Q#8rUu{yrzlcIK8FraDruI6 zs%ziVk|`$WcDq+zAOPR@gCG!rFNE+sZvvlx^#*(cqY)nIlAzwQ9o`B@IIP-kU7qKP zcxc?UfrC6OTw>1=oc?A_>xb%)>tW0ky$Ih!by(|LWE*ng<@&&Y4-uhZR2B*B%Q4~B> z5bOhp)VzR>vztw!sWk~rHvGH!W@jfe+1+b*d|zc?i< z$!{9R%JoU#Kg+nu>I$6Z_~QSY#%1G?)PDK;DVz-dC%zP(k{_?#kh2hjIQPuT&U>&r zu=+TT^xmqv(W-3C`6rrp?S4NOp5R_NlP`S2QFpIrI6+yRzud~%URLh7JvYy;H?=xp QRn+=%5slw2BaQ8T0n#|$7ytkO literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Prefs/Plugins/filetypes b/scalos/Default_Theme/Prefs/Plugins/filetypes new file mode 100755 index 0000000000000000000000000000000000000000..1b4efb56cadc3540b5093ab4dc37721396cfe8b6 GIT binary patch literal 1756 zcwVKHzfTlF6vw~EoRE-_!9=Wx3y1O}xr5b>i3v+~IW8gz2ZTsrgV<1CC4~)*@k(17 zJX;$7fGgbO8jFobj4fgP3*2NYiQ5PEsEUgPsP_Y%F2T=cZU&eSt1`hCNDMrjz&SRu|+C)G;-Z@6vS#>aLM9*dZ3 z<@y|{PL*=o>xV^n5;C0)xJXe{#VS-cw5J(dQsj+J2*XTu5Bz%(>vQ5a(%X z`b)CDVrEpNMsqk->#O&}V#7(zxfU`h!c`l(AL5Boy*~tErvT3z_00y|g{7^ld7rLd z70C2C-4@<2U$aSiejqxqW+&)E1;)f7maG;QPFvd7EE~0v7G^%SFp53g9ofUsQVjMz z#={#C*ir;9f}nZc~&?5pKPTaPY~;iw$}ogTM^w%z1#Rw*kr&Lllc2 z0?bj+g@8#b!2E82=?(G?AJgkTs_q1;3msspgF7!fsJ#Pb7b2P;q4qw){m*Z3&x%o^ yaLy@Wh^(=O_6Q`8V#L;B(SguUV1!ukRH+OmKgN`zvE!j>J#y zIXHhLJ^}E+^@8)|M}AMB)ARcniFZIwi+&CxrhmfA{2xwWev5GcGS4yl{=@iQntAJ2 zd?Gu(C&A}s^x;ScV$C?`Z~4DoLa7s`(=cH4w<_;l%q`OXgJXo+(67(lPV}BV z0Td2IO#R^4RF0|$U*-Dh3+Z<#c1?B_n1x=z4C%9^&$|9A&$Pt3pPmY4kV?UxAeC;k@cGo;UL3Ug!0sdEckpX{c-q5uE@ literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Prefs/Plugins/palette b/scalos/Default_Theme/Prefs/Plugins/palette new file mode 100755 index 0000000000000000000000000000000000000000..6d79f7457c668ae2b37ed3d456e809caec01cc68 GIT binary patch literal 1756 zcwWVozi-n(6vw~Ll>}85R|E_dsHrjlLkCOVs3j+9M5%;nRmi~Bss8{2t0h3n*tHUW zLH+@TEGK0}%F>ZY<;MVvWhpGcq2t}XxJoBGLWmbVfBoL)<<9rR=ZE`;2~a=Vd)!UB z$)g^Co47?kvXvTAU~9{3d)P@j2b2n0{nl_e?DzYv)+vrnI0$>Eg8?wY%V`)+kHb-K zG#&P`>^fCvS+;xF>Ds2Siq)M?vg__^Yk0QzhP5k{Mr$rF{;w4CnEN%efO%Mv=iEQ!dwZpEk6C?QpEB+vVlDDo zu?ka(3n5ueFz3Ni+@}?@Dvf(SXr4dXe@0c|P=Om@Y`8tB5FC&5N_@-%6o%)MVyE=_ z=t|t}VV9Xt^u?7Y?1~dZ?ik|Q#9Yf`6d+$ zYGdOU<;d^epDd)yeJsSMnzHb%Xpn-GAY@ww^-#q;XLDvY7&}6&iL2ya5_N6mW6` YZ$|l(6yEtcflX?F^7PRFj!OV literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Prefs/Plugins/pattern b/scalos/Default_Theme/Prefs/Plugins/pattern new file mode 100755 index 0000000000000000000000000000000000000000..568adec790755f5c388cac89cd37919caa4ee903 GIT binary patch literal 1724 zcwWtvzl#$=6vw}tNiJ}%jPYk78b~2mgkxa^5mqKY7SDr=k;4>rsSZmkt;8)X?hg=- z{0pfBEi6O_0%8$ZOD)8-Hep~vQv}AhGaCph?jC~pVEDc_pSN#j-p=mL{(cYGc)7dR z>2-RyLI7uR9%o2VE+GP%O{e9c+iTyUDev=vKN^i{1HTc5gTcTLNB$_RO&j6(QRDD% zJRTp6roJCe$07Oi`Fv-;-APN~98P!Jy&dD1PT}tE?R!9_j25==znkwWX;cJ8r&_2~ zg|=}X*Rkb{CtfN`t(PVii7LRERy+;iF`WvZ2+M<57vWqlC#D>O;V#uT&oQQD0nThS z+Kvhgm)y*7k!0)tnL{gSKy1>$J+0G)SZwohxsaaSm`z{_B}j6n%H-v8PDe~**w=xC z8kBlLrhm)R78s3fBZO!3xyK4}+juzObD5|bp+=|3zzi_&SQx>eZ}QEaQ(>)8*e4VSD;2WW}A*%t4FBMfD7+{EiuEjFB1Iy z5GSbaRchx&nyWrlC_M)*^%vNT6@C8;;68BjXn_qHaA>>%s@(-xn|vrZFM!gXG6NWb sT_O2I3w<1#Jv;P#^@wtwWrz4cuWy^?SAYE$`RQ$VwRX_7^aJGD4|Q8S)c^nh literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Prefs/icon128 b/scalos/Default_Theme/Prefs/icon128 new file mode 100755 index 0000000000000000000000000000000000000000..b0543b366249deca7db142f1b65096f2a7035a99 GIT binary patch literal 6696 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 literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Prefs/icon16 b/scalos/Default_Theme/Prefs/icon16 new file mode 100755 index 0000000000000000000000000000000000000000..d3d0ebb46131c904b44fe17f2cff35cc28990069 GIT binary patch literal 376 zcwR-1JxD@f6o$Vyjh4!WpdiE1p_;NG5H6aDm14BDNEVF|(h?C^SE4D9h897KpgH=X zA<#>PnPp&TqKOIx8ix1gZK%M$J|XZN&d&oc=f`ZHu@Qph39Hd&v{_7qkZ#h&oLMUY z%Rqz2Y=&tDb1W#O^JeRwFY61OuWnsTId>vS@hq6Q%hqn6DzWr?Bvpx~-eT!WB43L? zSEH#?BqLotzTOw)crx=TSw5<}FQ+39C!XB8;mEsvIXUF(?8xed*<_>LG|P4rSld{{ zGJczFJp|c;Vo| hkD@pZ@CZ7wVnrwn`4H`D$P`L~Z;Coa3u!(@{s0o%r>g(} literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Prefs/icon24 b/scalos/Default_Theme/Prefs/icon24 new file mode 100755 index 0000000000000000000000000000000000000000..4bec17ea437fd0044fe7787768c23bee13305197 GIT binary patch literal 668 zcwT*xT}V@57{{NpXKFCS%svJQ+l3e9MVkhFV06|LGw874O?2hC^l}&8M37Pu2fB&q zLLw3&WO!p2L3kmXG(UpLCY{+4Mzdr|x!g)^LTB&k|AImn;dwbPzvukk=i}w{M*1}( z*RvZp!&+GD>mj1!p0G0?wfYv)Qj=rJ!5A6!`9Q$SDJo* zapgxgUruE{zhC*DUM($H<)!@3%%|<;FV*;)chhsGY2|Yt=XQS?m9Hl^($}-I@zqh) zywx@J_`&m*=3L+$Du*LIw=s{qM#3Sg?XUkcQ;3M2w+;vcGxbTsN(?NPD3Uh;#M2Nb~Xv1DfWuZa{KSE_~|Hx@6Htht?*$}Oq zJP;{}jU8k(?SQOV literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Prefs/icon32 b/scalos/Default_Theme/Prefs/icon32 new file mode 100755 index 0000000000000000000000000000000000000000..71576170169fe02911925e39a2a84e765f7677f6 GIT binary patch literal 826 zcwU8)PfQa*6vn6f7223hw-FDGMz+!Di3my*6Twy>MiUy;gMZ?|UQ9fRo+Ku^gJSSP z#Kd?}6T(4{8lxACX^EhqNI^g}A+V+VQG#p>)ogX!@eLll=}z{```&Nny_wlP*mx|$ z7vh2)F673U1!AcR(ddXH)Gq?fm;#XJ#4%OpuENy-vpxeGUHi?V`=^z4dqUhIFr=dH(C~YWX zqDrJ0DqFG)qirh!Wmik1C>P02=z{eCF(s~BG*7gWuqf?{x#7olFRY&}2J~D^r7H<%QI(@F==P*9V0r%J zX}D8+&q0~-bRdw7t3ber<9kMb48`jYLis}C)2v}AX^kUUXBzORK8B(Ol8sL;c7lbe TUZF|I+h2=a9qd2<+u!IndqGPW literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Prefs/icon48 b/scalos/Default_Theme/Prefs/icon48 new file mode 100755 index 0000000000000000000000000000000000000000..913ed7377f790755e69bbf7e880cc01a3401b7eb GIT binary patch literal 1486 zcwUv1e`s4(6vxlY%gIZc^oO-9U0X^1&@BjC#!$N{E@?O26ibH~@E5e`KpEIoaBQr9 zBds(dNzIY_wni9 zuFbFhIJ>;1^`+E|p1A(YUH#D7>Y41sma$~t^ob`XAKTvN@o?nU_B}6f=7)<=B)-en z|9rCnI83k+t(o-KyY(#cioh#4JdqJ4;?X^FR5n`Po|xtBo3p$J{P4GtBiKy2BZrS# zL~gGn6z8C|O-GJegjW(;{G22TvBxFh2)9Z?OPsSpg=Bp2Mmhu|2HY2Aq(-=eG)D7M zl&CI|WAWh_BPYQ&$H)P&``Oq-MK*#;>k@e*5=kxOo9KwiC}m=qF0EJP>)VhLHwPPcae(c%6;BIXX+iA{B@aF=G0_%ZO4&lz$@r zNO(XZv0d+3h!Q9xg)(wluD!zAd0(!l-%4a3C@1PJBTgB`u5i_*Q^mU{tSA*jYzz@S z4`^d#6HC83owh&fP;gg$y)kLNHISNYypnZ5$tp{9&o#Bxv+R04JScytpL=($K zfv(^SJFW>ETcS01&pGffgPGiouxTLiq9eH+5KnMK)wis|>MNnBTEyYy1E?ai^KMpi=Qx`X`OmWo1{_PDmg415;`Si%*{nw$CBNW0&`_@%zEiFa4-Jcy=4t30j>C z1(x)l{H-XDnp|sa+_B^Wfoclu@^9Zfpz)VLss8oN{CPXO c&m>LA(@23zLkg`L*2$%S%lOZS+`qlSpIFIO!T_4A*d4FIJOrZ0W+K+shP9zQ+5ZUGG<^h3mBzy9^w ztIPK7yS{bn?%ki9S=-Y6{2L$sc=Bw|DK~NK^zpu{KlR@_+}%_4%<|9ocb>VBx_;5T zab?bJ_svY|<80>0!0+D;bkz4IwjcbU`E2v78IMe8EiCMN;xSULZ2*6I1BMPEo;Q6a)PVa{!gvxulJ65Xfo3(ZGcSPlu)Y z*zsLcsq7TA&v8E&MAIwI_tEWW$U5%`cVZE@vObVLX-d#tN|Nu{=!0Sxv^J&{PqoYvT1jHRjKva~4Ww=lt2Tj1YBq?9 zSznWza+%G=VxJQ0r-)WHvPaT{xAYte%wePO)WHMo6f)jY;G4p_esYnVfRZd-ghC%{ zfj=;M^kf!2(`wr{Efg?`Tsv%HCeu`t4TGL|3>Psd^@B)Ceg@(EU*co&ug zD~9tM&AdE@v$@#LqdJ5@N@+Ns;Lts=UtV4o(7Aa~T+F$Z7cdth7#6M=N@IlhU2XKEqZW> zl^0S)*D|~aH)0FJCc%2;#|S6T*hcUa^+MpOB?SLX6?vps}<6Hi074}=k7lnh{l7emC|70ag&!>zA3Gn_O%k?sR&(6&=D zO;u-ugyqVM;|lgr3_}Y4C{&kG=Czikg*pN48cG!fJ{d+@q<|}|Ss83!6(7qiVrzWHYLqhBfM%wd z+ApzgAU!u{1( zY3aA2YeDU1hOzFQ=;n}Sg6chI7#3?BPLE(x&a(>+bp(sUa?ncEd7+|^EJ7R#q3N)Z zbwD}Nrwt#&=4v-o9+p|l-Ov##Pw=7*Q6P>iA;t!Dc=gEOnB8Bp$=c2~Ib==}9nsEy zna8l|itwzgEuxV-Fe$^9#`DMGW~Ic@y8;){46^GcqDgzv!khG`Mv`Pu3y4VHsrdQU z+FfnZn;Qv?RJ-ERpe++uyKLTYLlLpgHXwvU8ipvoUo_${?at4@R}wuOm%e`VOx2Z? zzBszoBAS%cV+VDD@Hkd1+`HbExB%{Z=+YXC&)nX@OLJ@qJ^0172Yw(!VjH(HI;mds z*s>Eeu7tXW%lZiRyqfMZgP3z(NgtYI_&v~v1WKU2g4&71?_p;$yp)dhqL!la@GInc zxn*VrupwH)BEijR%uth{Rxa^ebAw0GQQO;5Z6No6^3of68jKmM=QKc;u7=Kufz literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Prefs/icon96 b/scalos/Default_Theme/Prefs/icon96 new file mode 100755 index 0000000000000000000000000000000000000000..3104210df0d77cb5248b898f1b2db71ba074625e GIT binary patch literal 4378 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 literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/ScalosAboutLogo b/scalos/Default_Theme/ScalosAboutLogo new file mode 100755 index 0000000000000000000000000000000000000000..cd14e947f4a1227c9462c962581a9a988f981705 GIT binary patch literal 13762 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 K(m2=v$^Qe!fAF3F literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/ScalosSplashLogo b/scalos/Default_Theme/ScalosSplashLogo new file mode 100755 index 0000000000000000000000000000000000000000..4b160274807c81646adc9f490baeeb7768a0629d GIT binary patch literal 15526 zcwW7FRZt#Xu$mJ4bUndr~P;QBwO~cBU5ACZBnrEM-@Xga>SajRzAHHIb#u z+7xSlfSjTNb_7*3A2l8@3_?X08VvpouZD?*mMN(^5HJrfne}@+_iKxpaQJVn2vr@f zbCT7PMsJUcv$L1QmyUzXgV!ndX%s&+^e=Jy`IZ2;QZOIS5=o4_qlA;DG%+110+K)<g19B^b$QdAes=)j-n^+{k{W_rlmuQVx6d?n^FHMAQ0wCoA2SkZ6CLu^=Aaa>z zyEjYq?Soq+!GNCeq{);Yv#gjcNq_NOuP-;Z$+r8fYefukXi!bzcF8kSGAJ-44e7x}fb44Hy(1DF5 zcUzTe10XfPeB()%bpr$l@eJ~Cw!fg9+K=D2t?E4l?GqcTBt3!tsex(uC zqChS??B1#rCq_1!w2gk`%W_4M{05iciUd@I$oI%K!8DFr_xPNHfkz-~%(?(VJ~#A{ z_y}%L`vU+ZbU(!i(SiY!DTO-#&~b>X^CuBUW(XDl#B%+=)d<5N_F`7_AZPXx zb@bqX8$yc-AyW46p^8B7`VqqC;U){?sr2wHK{nPv;OC;HZ=p8yGIJpvY@+M`KP33!L%EJKPHZT;e#!Y(Gx!a} z{C-XOB{M$`ot*&h@MvSd8D?bD$Yn#F$k6WwVH)^fhOv$JG}zT**o}!aI9;#^da?~K zU@5^P{4h>o^@33QtOH_WB{XC-ME_8oQZ%5q!K%Xr1~K<(Nr^lfzbgk%Mit8Jv^l26h>nTo2Ts^GkP8G=f=DoVMYns>3dYQ4fvDcnEo^7&FC)%H@3swpK`r5J^2 zMg4*<{kMQ;W2Cx}VDa1#$pRJQ<{`W&GVCE1lPe98gv**;4si!SSq$A;&@8Lo|^O|dPwZN+)|SYXch#Qg~FZtM>EXl+K~&gQn@ z4(Iq{;bMk_lZg$MBNoq^nalWcBG&lOD%GN8<}zsO58AkSTik$o!HiS^b<3CYP_rF& zHyi=e3Ohoh3bu8VRVzM2BMX+5!hyoU-7cERM5}buwwZ=Gr-_LXy48xMiqX?(?)gls zY{RbQj+NJ_;G*xDgVGTk5yQ!#WUq0kWZC40ic~cLHFvc;wZ#gl1)USR6PpEfYXt)J z48#ncjPa&Fl^K--E*Ul(nA?~!G_y2!%C;cp)7Mk@)AUp5GwyrCd#Zbz`)Q&HLUf`9 zUMF6!Urx>wF4p!PCxu&V{iOq?{YUC%1ZH`TSvTxB#Xn-l(NkPfaFlII!b@y(JjRpu z@Xy<38|Ur{GTJj%E0=BltxfO`dY8Y*GGq{p>h|+r2;W{lXly%7>|~W>l=R)i9x&>; z=xOS`bP~(gXMV|EV6qum8PMMB9QQQf5#Tp@o;rdM7!m-_@yH47D()iR;P0aFS@22o zfqBh-;e8%|i+Swca=*sDl7lh;>jm2b>-5L>uZOULAc0JSEP`Q&ih^o~W<(Ug5b?XBjw;_M$yjc2>^ zX|ij^dT|A(qNmge?gf&HC@|v6@0Hlf5@B2iWdzHA@5+zLSFCMrk>-ov&r(ae=UU_S z7JW7kkr#I!Vuh1eqIHkMi*Kd4kyR60Sg)8~c37t8PRvZqEKowSNN%8AWNQA}EN@Cn zn}D?IzHc)|kPtfduuJjec(a0K9V|0b(4bVMfQ&7}_=na_8&}({MY2;;>mTce>HF~$ z1wsI}S7&UELQ75kQj44B)h2oO_jYWG2xS~s24-EQwx4bmm$TmE=HqqAZwlKQN~+hE z?yJ|)N`bRQMWVC;>TF4+iKFATRkvEL##n|)KUFU*Q|7hRe81r&=~viS{Hc1Z5pUVw zR+rPC_qubp0fE+~o5#*hBu@%YY%3l#yQ`%;ErsX*hFl_55?n>?5$M}UuRG;=Sl&fX zHcXC9La-aMpJ`7tRjgd+aTMHpWclijtG!j0H+L<60WEZ|xq99p2NGfNu3sdcb~Mtu zsath^_r9~8Jr7um!8amk>)!WSYmso3AIy&NEb@f8|9){|>11cUTHW1U2WO+i5k)M? zW51W-X9vnSOLuLw*ZPLsC%o57y;1DtxubBHH`Tw|Ke>_S+k6LmBI!;$%hT;#L0@2# z%b(YIaTr;UMWjb0(bfFnbHTi0>^#gKqn@3c^_BnXX*VEYr{rfzc9xtV|G%_V_XnBR zG%H<2-A*&n>1;t9r*oNR{fE(;^@AAQ%MSZn@&}_8s^%Y+{8juCKK5^0lGWOFCngW$ zXX<=aPPeiryfYVbzR#9D^Nx#;iwwFs?wuDyrv%NmU)Bg)sM_uxUGC3tT;b1UR&_mM z+^S!@KySw|&nU;f4ezxkJvN(<20aGT{hBBj$Z(;0ASA?W6XYBq=UbGHd; zCM+uq0JYIxFNz7DKB=*!k}LptPyv8nAOJjle2zx|;LHR7#|8kvlL`PhcJcay;s5{v zD9EUM|M>X41^D=X=AlZ?L4`tv$H7D*&HF`HoX$a!HAsg$)l4GCQMLHDT|;(QZ+*e^ zNax!6;_;{JW|C&E?W3+}Bq1STC_t>o$D++6q0XtT!fyYW_?^y^m9JLOm~YKuEckquIUA)>!3ysZ?R4j+sZ6Er6!Bo!_MIwII7 zw(9EYhN8%p42#Y<@!n91A@Bbpm4zu~>Artr%!-2K3fwtz?TE8~LX(n`a?umW^I(~Y zqxvW#BpX0g+5p|%-CZ?loq3KO2{P?LU)r4id)d?7MbJpqaAinCoNm4gdyE$1!NI}K z%+N-A(MnO!Qnc|uH<7Vx^HacOrP2##-znYAw_}5hJix(#E<$ZYXJCEun+*q1AsmN*nM_Q2oQeQ zP+?@S@pK63oJa*Cs11K(BYFpWus!+{6BB;hdD@l>dK3{Vy1hGRx5g01VVpV!|qJpwmvP1`~B> z;zw`Cv-*q502k||!nTJ62u;$$X0ld3JPyOY@r+OY0F$KJ*BWeWU{pL$-1`PsFUJDw&Q)e{)dLu zS?9EOA~8pNnGQk7vGX~%XSLlVclXmI_u|$hmoI+=BX2k4!4W*+UM?-owe9yVGt@S`T7w!`YUWnNuxIv)5XTc%h*9ssoJqTUt2pv}3*}W9I z^tzs+vfmePUC++Wq92b*X)?XU;`M$$E3(%S&kKeo1p;;ziPvv4gsbekaPMCJ)Xoi} zjy?iOK%m--h9W5-;XLXee1L~5-Y6xDMO5{f*r5M1Y3qnj0dxMdG4{i!s%;lgX;r5X z$ukPFUkJ@Tu7Egjag!a*LRxDDPDKD@y2*L_wm}UjWJO^fJ3;wo{dS_M;&1^MW5_*7 z7elZfDqO=9jBxnff0nVUP74yb$JQ)aE18Y?Ot%#EK0g`2P1~_+fN}|#8U)jRP<2q}94?Z$bYUv)PzgW~T#Z9-HCPuwy!(djq6#Le;=h3CJN!y$uxJJ+ppVep zKH(+yQ2P<;z2trf+oOeqU1J57oFlUNk119W+V7L3xxGaN&EG;8As;i}gxawI*Y5y= z9~km!0C^8?;nvp1Gh8MHxcprO%t1f+&p<9hG>+_NseW?4)A;h*-stbSsng&tkkYb* zE&hIfBxTIcpE~F&5H>R~Tn$=^w7j{(EZO7L`4f@cs+ZEvBnNH`9zqqp)+hz_D%Ech0YoC$Yc&0Rxis013d>2+-e zXG%+7o&QH|>sk>{WVg*0(Nx9^E-e?BQ~^jM29+4h3HAH7Y}!;0EGjwKCdxyY8MnxM zJ!ZzY$hU^8FWl~qXB2XyYe$K5-^`hYssbVZ*za+!VYp+6D7OOJDeq4Nlp?5u^|*Q6 z(q4Kty^-Xor>ye+0%s*x_g^)!@;NEmrF@S1T_T#4<}I4J$O#Nol#PTiTu5Y&4iGM# zfp!#2*Wc@i_+E_L!r-K&0pvgDs`1vGvB_^!h7MrT7$~IBm z``H=RV7wtL#`UnK-k=?n7BH?B-l6Yw=XGBNAp`U~zB^GxLNd!-w4N|3s;tS!zdFO^ zl5QRy9(ag6o-*T~O&ql}&W{18!oT>?{O&W>kb4>j`NX3LBA%lTZj3)ROFm+>*>Ojh z+XAiEUzAWe4Z*k?jB`U)y%hlEe^;=;Zw*MG52y6u4GnJ0vW2p6aY0^|c};#NG=D-T zJ=}rsPvoyR{HOa1HnEtPY3JU)ovzU2yEOEt}s6Cq-` z;R+9JT?b8)Ckx80hvG zui_Ad8lb7hrIIXXp;$0>_acv!vxua$Yd7f!hxX;qK;bV%OIIc__&Q*@EvhYNXoV7q z4mrgX?tyFDkhC{Y82+id;^27!s~f_uLf$)^GI#oQQTCLz{LBA^s!&35EG5xI*|1pBZCnVbq@T{5wz7IG+_z5Hq#3Y++XJ%n<3b|rm^(k%7I z+c|i_)xxINPTo1U5A_CyE+1K?dg@?i66eP^6!6E!EW4Ku* zB_Xlt_e6!VEcpJ6h0^i&DmSM3Tl3X^Gk;py!`sD_h3<3&Jf%G(DicK|Aw+VmH;*}& zN#PUB<2|kbYQT#{wtY~Y(1ho30s{Hmem?2nngiE@hBzoyvtPCrzAS4xX3|D>X&RB= zPG~Cok2)8-PytH*Q}m5ViGjcr*p2~`yhm7vOLtU1BEdS7!EPc!TWsjN(rHTWe``=r zZg}k|0hKUVRHQutfg_)mz_#ONpu}YgxRJ$ptnV&o(OfuVt$!B+>uK!9!Q%w}fFd=juS}jM zXVAE?$rDK^9NRk7SsWnkb*FM?Bcc{;w^}vkRvR5b=^n*ZB7|8B)QDaYswD!tk<@J; zI|pJD3Xz>a~jJ9dH5=m}*&nN6!n* z`+~_t49vtvz)-y2x+CF;w%S1OW;9EQEnO`;Xq!g7d^-;2N%K*hIZ?tM|AFiO$#*`3 zqGn7IyoNC7r`?t@AOxSR?d}-lHG+tQ-&&pCUf{9$%apl&jYB@D6|86gMBw%(@Mt0}}3+^j! zvck7+GO9b!n&qH#v~*PwVrJy=>-MXg4n$5`Fcar+S}&;vyE9L8v843mQ4$sjas6w9 z#aq1VxJI5X{124+MGpMdCEOf?u|z@EA`X7LQ7@mNWE9k(UbxLWl%^FnO%zH3#0p#@ z&sRejFoTm*YYk0JXV!X7E$3%Jsq9UMha6q4GUO7KmVwmQ(zD4Dq0;RSz0D}j$&Eks zL4ISQ0$uQscl$0Yd{s{!ye35w#>UE%4#|}4cF3Qf1}<3;o~0Bkgm^0#JBy?MkHhYv zVl-EMCmmtZvI?kzn^{U;S)tS#;$F$7&NFc-DjmE`Sh=C zs}Op!68}K?L-p(RUxN#T{nN>8AYr9n}YckH)&Z#5B1vC=IlO`jg9r zEC6H0{q}Ki*vs=;WTMr=!N$gNHW(6h(PwJ$B3t%SG2`yGo*VxhY=2RDk(`QANGbYH zimwzHLU5tGwmG^rItz`R{*}z>K@F^^l^JbxU3pi*58vf44_7!N~7(PgTr=LOa zvkM_hH{aRxsEQ%!;M*gWXL{URfAGtnbZ7DaU^~J{&yR@TyM4q+sJSw)mrXV=?>(G; zHZ@@pZg7w`%MK#Q6Gj|L!MG2nv`=Pg(}>0TX}oyY6!3@+l3parH8KOKITHnl$J5K0 zYB(PYB*3Do#Rg)9eN_Bd-6`!Bsws@x!o!_f*1P->1_obs?Y$moDn@UxG{*{#$d21! zDh`?>v7PtTf4m;~GHBC3j2yd3olSJf1>LT$f!R}PcX~5M;Q9)q%^Yqx!C1WTlL^{> z<6w~E(IsFSEOhXoN(C!qgI&+?ucTC%htciX_=VKZoe^sTOc@UJY4U&6>e zH4R)C{0KL4d>*dXLrjJ}SBerJkK4h&ZuRV01&4ApPUekZgAu0lhm`R+OH7sXx4kqv zr(j#LB&0OX25ZGNb&O=d-+x$?S$^Y2y!wuMm+Xt5gX>-Y^PboGG?A?gj?SyA5;{@V znzH**+Nw;|PbUpTyb3iVewU08W8@N+n9BqJtvVv+;R?xfb4q#WS7pNi3%^dIo-)ij zwB>Y_vNDZp#&;8boCJHrX+9wM`9Y+Vb4l;}o^;aoC_UbKC}cf5kz}je*9neQehjr=`!W&R!qK746N_uU6T-itqf?7bMLd6#Pf>s zXqV!ZQ%*eG<^5MI3KcE0F{h@WN3^d)cOYH*?XIyp1*ay0x7C>9Xf6PoNj=o?bxkaQ zm2WY$iLQ;|ARjCU?6H3e`Gu{j6|w!W%0k@pvbQc~p}*eDK(W*ZUQCAIGKy>r7;OEVqhlj)jQHc#Os$4=QFwvF z?fJP12R9Uz7o;B}x5cBnVHB86-^Muz2gE*#JxAjejF+6Q8(|`cq0+{Y4`+YcU6&Hq zG*hNRH%o#tIpcm3AywBCSc+b|)TX*O4I_Nse#0_RkODMT#kyUxz+e9XQ`@{M-+<}7 zJJ^PX#@vMNLF}$kmKgo`11f?|gB;_PbIKO6N$`&Uf*C|00mtnOpUDAmv+FJ{+<4JyO^enl4ez2&Fi9h`SWVV5Cxc8)Ba@w8d%U z)mQ@}!5`l0s!gd0Ff8jHZ`XB4M_TdJKbKysP;31J-alSPV_Y76=1(CMu>8IhF^;EZ zc|fv)`H{@uE7?so)<7dt+JL}Z!Q`X{JNFJt5$GQwCH`>u!zY(m zvYTH5ot1~Cgd3LnL+m6ee}w>-F&i{qOI|FPrD*uA)75-CgZZVs5EcUm
Mg>vU!eoFZimq|q!F@QhsRCSRmxV_<15%nDpoeUHjwDo*zS)NI1xu@B z&b6EiSD@Z&tgYB13a&_+79Uq_J5Ll*E~|!V(O1;MeDC#6g;{^Sf}A2FOwYiF2zAl8 zwYtsQpsU)yXw!LbueQ0VuBh3aZ8LcjBJNB;T^c*F@YQ*aofp-7Jx<#F0&)gOo0Yyp zFx~kk<2Fa8(XSSN+!5>2d*{6BFLh_%e?WbB{)9FQ=F~G1WZ!fe?PMd$U}&J!PmY?Q z0Y8^zLRdd$zHIvDSr_0#HtQztRaF^oMR!Nh#1pWzpKC)?Yu{e?PNyRWxdln9?pSm^ z)_Er|f#9)1@_vTg%he1yI77d9`wxi~Xd$K%MZFQk{zzyubJN;V{WC4Wpa{@h`D&DHJp2QkYSw(+c=+TJjytu1xdT$v z>e|PgSBwd5Yd*Yzie6eLa{p>9GTIUeC_c?hj)ed|CD$HW60KcL2L13$~MK9$li=EtLD==XD7pEoC^{YQ=9qju`rHftbh zSruQGjeR2prFL6}AcP|YE5wTTYO#f3r~(9{Cm{+g8ft1 z6Ko>hem<=cQ@;u7zzk6rU$c|g3dE*pGufFw{Okip;yZBwLJs-+KOfC&ivy!pO$h!z z>&^4!{AD|EgHj;~+=8y>^e0fVkXk0A)sfMBBTvo=8@E#*|tAeBshM%Ov29N8}Pn~ z_0inZox?UYdk-^4WJ)%FICBS++!U*nPq5Wh?!YKCy#;fE+2{QD^F30;UyCC6QR((d zsJbn4{kDlqU&+oN-ddzW{Bkp;+zcQQ3y@U0z)Vi=xJ&GeA1<&u#*)09kf?Oaty0g- z!s;?Oa*BMZhPM07sraf@P>WnfY~{Hzx`|-h&)vJEKZ;M=>(}ird5_ z=G!dEiR(iDQ^{!XZ9uXfaD7m#5g%{9QHm7m5PRs;NlpxDr0K!;x<|}q7{R$i0uNbI z%GFHRg=>+G*ZHVbFja`f6WOC(fJE6~>dfVY%0~g;Ub%zTT8X~A5C|b27d|2uUzE=b zD{;utx*3g0a1{$<(qzCSLqw|rhl_6#iU-|%dni7Ks=wBpO0MOi4=-@e;NOsayY(U6zqT$Sju5w zr%TZBivR-30P5inb=f_F_lF)vy--?Na5ZY?zQtf!Sa$hd=eNHwU-+hI7bJ60JJe@k z&*Cw_R}NX1Z&NJ59TPDD61!3CL2@~)FbWKTABXf{eV^DoqV>=ygjwfLS?q6k_0#<( z{w0xKJSr*}vkq$f_^}ryDo&Hu$y)|*s)~`pQXT2?9*EAA57x3zj8R0;IOS)pdtadU zkA{_xs(f^}qe!+WajrFSwvfyKNZ}?$S|!$HD3AvC1|_$k6C5n+%%dVa`DURFsv$&Nf4(caXqdyJrmN$9-}G^jrKz z%&i6j^;%2DEv5TAc>)TX0wdmbONa_k>3V2y=4kP?tlx)&I6Q4`Y%22?kroE)>6E{| zRQz4gg7ZfyV9&{xS?WGB5=Y%CXS88XLCs-f4Xp)Xw-cmSwUg6J6hVVT#bAkY z&JXG`4-Ym^o3BFEuYd2JnF87V9Om5{zGa$5UTqSD;I;=?#fZqC;@oA7dbY_Dqjc}f zN4y z_IWJgGKqw!mIw!7$QJDyVgT2u%rLY}*jJ18MtK+_WoPS2r(EYnvZ;$vajiq73f%dI zLgeG)cvrD;Z-(+3<=ZU5Xa`=qq(`JWW=XNY1I3p%p&yK-d3q_XWh)o87Y71yr}^>+ z>kBS{&bGJL&JCRji*up$42&cKUc2@XQ4(airN!UMB?>}#y-Hyt7xO9huOCrh94@D- zUmrbNtW6T|SB|1HhkgL*TgP9)FN>RlI-|jWo0~A8L}J$TX*xT19V3yZHQAxLlf}l& z^$3>o`K&zmIQ)UTAGPnBw~o7gw@#MwiSnvmT|wiuICFmNX@Czu*loW2V&%v$itp)k ziP*#*1wV-*elFrAHZNQwYW99lKdgupm}(&E5!iGE!CEzN!E>e&@+IO{X_6AYjdn$5 zwhxnDc!s#FL!kX(rI92ybo?;Y6<-o4@USU7Tlnd^$WPUHMo_EZom9-U=Kxs)Cr*i0 zC3wQWd^8`{aXJ%12LTD;&mR+qLS1S*>-E>}pXjh*UH+b?->K61>>d1FG5??C@F2F3 z{2@x(xcUJlPOK!KWvoqXiBSKnu94tdf731YZgp~pJgKyo@tqdTy!qsmdI&mA)dtXxP>Z&QRgglhg+Z064pa>JDzh6bir^~C5wRkT@9}f_ zN(j2?ltvLdI|=yB%}tSW*BKysbkql#Ky$H6RA4Abdl(rC&Za&S5C;)8ypwP-??y;9 zzm6XMi(bqwlO52vJg}wf*stLni#oLAH3Jd%+OFo(JN_2(Cb@JxXXcn}(KHjncwE&~ z?F9)0x-jLlC)wU7bZXnK?EJE?D1p&``z9*JZVgR__{}k;{nT&}W`TL6X(_w)$HhHp z^-C;il{coIHFYh`U7&m!$KB9)`}&PuU}?@*sjVK~NE;Z0NezMOFi z`L(-}H$3CxB6!-mTF?^i+8B}H&ZsC10#~g9k@jC(q9DlqB%Gv%-#sw1F`S!{w}eJ8 za1k9+%RDU@MyS8bH-bcHlp6n0q?d9I4=tG2QGlqV#HB^AarGb#9Q+alJ;&SG*tN1N z+Z+{t9cuWw+1r*5_tT*cc*kef(q_~Vsh}?Z00R-i^@3dXDUoc~ePuUY^(1Bx&#ROc zEtdnHhyOGvM-SrR8<;|0`Y1I~aZs>&K>Si*C&mvAJ_ZO;eC>Fz7HN~KX((>-Qp2{h z0kYPnAo*nrVh<#d1VK%W-v@Yq?ptcJ^;f9At5V`6$-#gjhtLp1_$;txrfVM;Td#c4 zQqVaDXQW?R$G{O5`;%UXf&O+jSDsy$BSyIv&e=t9jkK9|YX|AW$o?E;$@E8LgY1?- zDs1##AHT8;`Ysoq)S+=Xd5q#1#2)!e)fx3QYO)0{I%MZcX$xUp%B3))$cC>oz_%c1m(`CmxbI+x~sp@-hyQ4wD;%*Dg6B zFLRm8e$L2xvhHshRUw4l`)nuB9=Rgacy>wQv`run=qWFm72i$O-CkeNSa54YY_rO0 zPM3)`;JS&Vmgw-D$WIHOh^Z$rqwa^9#;A3bJnC zw`W$?!;wZ!LXmS>y6oKPxipsO=+1(ygmcLQu?+i{i0eWsQ)ohvAsupn)fi(>J5lk@ zN;p&bLXuzBqWUj_MgD!9Wzieo+h&>|rsNc|R=rTOVFj&5^hPv5!i43)VLy=SgR%OU zldbV;*TNHAgePBGi`Qh$Ra|C*XZzLAVld3U7r8QE-1Pvr7=BjU_iJ)2X`54nNG{E~l2PZa_oNTgCqkW*#efJv@#5QCx3*Dxs*MZ(`vya*$1SC~4D@aY|8v}Zl!c2GAfQ!H(%uE^oY>`N-i%+^7=6J0N zOX6;kXJH{&^`I7Blh`Wjru@EKf>~gfDFmyZ8ZP^}+Uz1MAm?stT`R)+)bb;4HcxCa z+YlwFGxzSarcn@m(Y}8|O2Ljz2HWh~7K#_&TmlbR^d6U=^o%@lgna+IQKJ+S)9KQq z_q9Nw^K@gMFqJ={dtsu&yHw&~Ep^(&k+pttapypHV!Cl^iMp0d>YU$V-MZP;bTEvq zzr2d$>8*Cu%*#c0$$JZ}#|d!9>dSp!gd^cc7WfLJt&tx+HYM~xrNL|jpGRiA``XjH z&jQ^&bfb)^by%+`3_+>TujIZ)UAuJV@-I{?#wC6P_7=Y&Lczdse7lrcC|VD+7rZox zGaTj~3n4|i7#fr)zu@1$utz+1yL0{vSnXT0jngy!emtFGZhG(0b&AWdeV|1{Ro~+E z(y~s%K7ddbx}TI_%A~Pbt|ue);C|}y+}1VfQoV>ZTJ9&T`e8H|$L1i|+(PMH#;^m?Q)_%mY2}RG1@#2o&{^`9MLt3z&Fgz7;}>W4b4RN$W-RZis|JCktWBFPV2UHe7(%->4sW!>kIrA0%{X`fjPngk%!xl|gU;pm3shEHl zj`2fEw_k3unUZxm!!OZuXWv%sOqu1fXVg>|h_8P#*>F5{Px;KQv#^51VpHt}6Hex| zqD#ngAx%X#-XrTglRYNc>E(2}%ngtKdT7J`u8louS%>O)Zat&ZgdgU2_#=U-_fE^d zvqLFPBw+I+e3mEZ^jK;Y-Ffv_M3w%?r9yPm^&#_qUboZ7Xiy&`vHXU;mmphoZK#|9 z0Hz0(9$cz_&1E}el{Wq5@#ju6yKugv;K>$^bnL;s4C>$`h%3(^F`; zC;wiuPtqH*ix1q(rub6`%L+DUH55EQWMqe)$fC;*ko;ME6-kGp1snoS_HM+&(}_E+ zNQA?6$RIl}#K1<3CpbBow4Qg%XK71(XEIDX)}8GFP?!u~h=g{B?&r9h@;eeq&O<wnGro9+aNmSS}vdaNv6#7Lh9rjFdXmry#o!xR(Tzb$e`I2{AR1!=)u z)faFzG3!EW!jQKJ2 zv@NaDFkTJvjX=||OS~`nD9RUBijkCsEsEV!L4Cc^XbtR-RXe>Or`@qu9)x2~hak$L zh{43wc7xSc)V*pX$pgqycFlQ7D63%ozl;J}G{@goQ4ka5SHb*|iER|B1#i5(eZ`Dt z->h$q8lg^X9~xgXmj1+9PKG;C3?1{XM4n@+ez zef*JMi2lIA-&UD+ET<;dt8P^T2YKH~+xn-(g*vTUz718_>>6Z|-xJ6;a;nzVPoUwc zW-0>nD`s-Ps@+5S<=LYBIrP|Cgvqa6&#cn~vDP~+&J-Hs;l6IB6*T;_a7g42GxA5Y0mg(Xz__l|~V7|-U z=omp!E+2FPwZxzC?o6!hX+McIb0jmUHH{K&!p!}w7iS}X=e!SSLdRgS zpi{AGHRMkEG^3{Rs@wIg*2s!fJp~MnoIRbfeCJ{JL@Cilo+uOJ`T3`^ zxnVBRb~zj{quL58?vH~kG7R-vAunY}{}JEBC6c@B7ev*sI8OK|Ay{Nnh;u&@l0O^= zJ#lz)r7Uuevt)}0E%lcu(>ciPC?ju~+GWF#*Q&=r+tfppzB?6jy*7{~PC0!0o;J*{ z@VMGbUFkLGg^gC~J!|~$VF_&Fh4pZ4f#y5L=-JL`iX#}w*7@RI;9~hKNai$&m^~r2 zr5CS0vIHY`p?eKxe}S2A=cxdu0F3F6*izRE`KLtV6ZnkPz832dJOlmNd&5#U=W&`IBf&Xvmt2 z)HGqm6-j|eGZ@atlc*Tj=36LD&lqM@*&*oEP(j|7UVW<3S&AyJ;Rli7H2!ob^S>Y~E=nhAl_AEhUEjr<4Et+x76l>)oyX#|Kcsk!~u5 SQd19nn$&kWu__URfd2!S#d_TU literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Sound.info b/scalos/Default_Theme/Sound.info new file mode 100755 index 0000000000000000000000000000000000000000..d82ed8b856bafc74caa8ca748317f471843a28ed GIT binary patch literal 1695 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 T%ixCU55+<9UnVL62UGt7!~d^B literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/SplashBackground.info b/scalos/Default_Theme/SplashBackground.info new file mode 100755 index 0000000000000000000000000000000000000000..3d00bb5d9120fc15f9f7f7533375969d74bc3ebc GIT binary patch literal 5991 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 literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/ToolTipBackground b/scalos/Default_Theme/ToolTipBackground new file mode 100755 index 0000000000000000000000000000000000000000..4635ad0b7afefe3076d5f212b46382ad5f4cda40 GIT binary patch literal 3983 zcwVhmdpuO@8eVfBlX4rEs689Wtw|TA+GGkNCcr`@QRX7t{fL0OaY` zw$=awi2!Wi4S>cFwT`~Q$AZIsgF}AaxON?|*}~QyH4H2u65d<>7zY5zDdaZjEA$nG zMKS;YqlcOY{-0R)_mf2pV~ei*;?ofT;;-W(H@V2+|2|$9W+_32uvBgt3^}<)?$3j)ob3MqR1YZNfpv&AD1-ulR6w8<5YSUZE-Vm- zSOD-R&=?dFivVzV8Nw0-EF1NA77oCwv5TZUfP_UM(MT)~1sh~I0*O*U0~k%k_1m4W zN(Z$<fZ+@p9(%s9g0Xy&#!81`!s#{_}ME3)z97y{@Ao*_mLCl zt`^obwGW9l+wAd;OuELcecthTMt_U#UcZy)uNU2W(K$S8@C)6|KZ=#XtNX2ML=3+; z5>|`;zr%nZf2@qiC?8_ZvvdqhZYofrz z7;Bwh3Gu;xmV9tHArYgxV#!_kE_MtA6f5Vs93R;sVm1iV4QCG0$z)Ebq>bKv>Y5g^gxmaYN=UAmp>#GSd*af1af-5|ueWxj zw@|vqj&askN%A9J8l^kksG-@@3HAm!^$#Z|W3bhh{DSnc3C%`7TFE=kRH~d8zg?N< zGui1{f>F>-pYf=(hFk?)ZGP3s|@FoqS*?P&^*0LR7lW42#8ZFXnu_>f`F5b zr<;BJn5(dbB8BE@NjK=!KtI1PWZNBu)}DPgm}2)8it z=-Hbw2naCo;^EGhiFcB&IYEGi7tam@_M9<44G!LsVI0zkKXzhl90FcPGMm39f!)*E z4^^cBjg*|{{BOUf%}@s);0?%Xq-s9(92_Q|^GS{}^VDvFeV4teVIBaEp7>?zkzPL5 zwYR@oWV|bTJW_>2Z>lv4*!4jSPI?&9?VEU2`PM?TDfrkcx%rKYAgrpl^u>ZK?umTr zgG#ROK=vflfIv*&s@@U3WP!M^ch_z7-D~^To1LXPtPUryfSR`Fvjx2=>a?zvUz($g z&A&)O2`(!#f`?9A8Coi)_?dHZp4L1;aE9#1NWK_+z@k>f<$ug-1Vr(S+NY30mr z<;smakAmIlTd8%8woZOOOTD5WYD+@21Q|B^ZBh#bNl0$<*eaKfs?#wgo&#|%doQJ% zh#Oi0?@v@tvD{(h(JahU=eKpIr1WXMYTMGdx@YhvhL#iX4j-Tnzq-ndk#C(qa zwoqu*EbFQqNjENepVYt6R9j&TNIa|56cOc{OQxB3qn)&L_d=1lfIbFo*gE9JyjlRJ^#aiQsq0sO6)y_L-&` z&Av1MYvQD4*YKNOMpR1Pi*~6h!RUou_a@J`W4mIb zvOD8~Y`Wq3NGtm4Gdy!}AO6HWU2h+UHx8rq$()Q~e9sHH zNv(lQjzHyXAtjR4FSW>m%s9; zXAN?Wc7RP!hd$;&fUFEdEJOx`Zdn<35q!Owr@1zHhuEqOS)~sFl)fq&xsNn4VdBtb zeiIznkI&n4pNM?&e*|WDbTqEw;^G|A;o8ciKc|G00^xBW& zhcP>(Mg3g%oyLZ-hlcH-xG;GG2(|tgdAYXt!Rq_XhJ)dzwBlD$6{qGEz3ocm&qi|# zrL@pgmUN1@Twvv(X%$KcuE1jnP%`qTnSf~h~5zSKhdd-6op zp1QcDQjztxFLTw8{j5sne!7};`>D0C&md{%;3}}-=fYXsX%%ke15PTf{cVGW4W3gM z{_f+-A2Z7gl2kXWdOAbp}v?t+_R(7M%e#Xa1o z;L}i7rC^GrxWAM-u%F3_-?y_?H%YXYI(ShAD5`o8d$gx}6@0(-_IgznCk}p}fq=n_ zOpbb|Xl4LaF6pCw4_0^8MzKZy1n}8*2-q-@fA^d(=|LJh?J``|i5pRJLW@)CFKXs5 zH|+GsE~jQ~z&X8u+rg#CT!EVk1hATFbm2uSQkj-}u-hCaGS>0nwKD9M(=NVJ3<-^LIUhGn?wZ_Q}CmpsbkMF04`m1A^d}BvHj}}FT896icXdpnR+3u#I`hDtt2${{4tElYYItfYT&Jn0N5U{ z_XjqqK0hMTMRj$M1-0up`dUcPx4}{hLaU_?xb{2hbs=|;&KB#g>%#6aIy>+3iQ>5N z-S6f&_6ePxad}10m|kz0q_eZG!=fni&5tI5R~C*~IYZMtqu1LeL96H$jx6EW2BpEh z=>cedNbxLou@#^>XK`+Q0EC;mka1KPEX+&-s_4m5>WJS z=N5z+uy=~MT|xlPPXaG~O>_nmX;+n(5S}sC@8))%^g283S(q`5IH%0LTI=Ic%ANxU z3@gk!Ws&#sjc6dv*kq0?GPQC^nAQX1<+RIA{BUKqmLQF&6%7pJKpSy9w75|wg3y=^ zeU!=piJND-WwIZ#nTTH`nI3gEpjOWiMEI=TK!}8GY;5(Mu%TZGL(MZgoK0MTafY6P zvA1ZJ_DH>JXxz{EKJ*x(mpT=QrCE1$Sm`V4P<|5?@xN-&0E5) zrEQY2O+BIW@LIY4ysV)u1ABvdV#BS~xOrB;oFAj})z{hxa-YuI?p#XUqeu5Ug1Fz& zac=XT-#>W$Gj+vQ83Wvpzra_pjx%@{UXNFSN{3N9!7`)6s5e0EQy{`odI-Y%zzc<& zc;yrpa^>cn&M-AWnql1yN;~O=ngkJ(Mk$7-bx#(;zrbP0NsWO$q%&~MR7E)-3~O2g zcEK#2)jj0aKB+>QrUf!koTjr@f+Gqc9GIip#92B^Ny=>SD*~wT2})*X!Ml>G6@p5; zf#~TuTbBs)bk;5*RVffqjV0p~P%aAzifh8b#&BR9K1WN59ip2p&{>NVxT6OiS0g2w ziY_F&+zp~|h~UN0Oevn%;}hV^5mG`Du4uyJ4up`JiWU=>Yh7XiLMdXTttIn` zwLga*S-V8xtj@SeNF&+KcuEfqQv?L(BywIY^av&k=~;+M>sm~=G_glW(UQf)S}pY5 ze^6_(=gfqK{8YcARcO0G7k#nVj~Dl7TmI}&4E%(Fqp~j*>%D&pZSL$=D@p8bB2I>1 zj>QK1?`Ueb8Z+QlDI7XjmFyY(B{ZzZM=NJrBt?|aFda^&z8P#+qUH30MHUX(xF(Y3 zoDz#Ak6lpXqx$iMe@YQQ=m;mzM|(O-i4S}GNY$)dQ)t)`4#y%&w2+>+8Zx5{^S)?H zMAw}QPre|PT|BNoOrKSu3Sa@c6C@)TOxR!+D$SjPzLUm;^*y# z*HU1vlrB`F#hCZ|jVx@d1*nUe5_ZQiV0AlYzTb zvcn+HOzSQGWMoGBjdSQLton~#?Ve9Z*ChkxN83q&vo5d{0Wo3F<&@OLdJ6x;KL z)m)$ZRU4%aWxY$o^xTl3T2!KSvVYkFgtSRyNYFc^@YmFc$77_@7KBI*d`hi-pB8#( z>^4>9ojX-n;nnT#U97QgEQ}t1o#|X&OW~+pBk=E)-K7(&DhAyfp75;ztFY3!`QA-I z53HhMw)K8$<+JcU-smJQ8}ZPd@`tcQNkY8imS;9%ZBjH*XWEXreB`7?2HldRQbbh4 zD`&{QNME3>#-F|)n!gicjT-AT$*QU#GS+BhY7Iu3*BFx>d)=_=?&EI_CQ;8)uQtdBTTX2hY z;|PEufQhgyFB)&Ej2xz^;=8EVCRC}hNLc``^{i{%wmwg-e*Mek{KM53Tsjm=4A7bO zU~XKI6GBB~x7;=uPm4hS<6B@^&G$n+cFJ5d7`v#Og4<-RO|n+}gJthy)F~1E8nCqC z)wZ#`AXWdwik_1mdPux&SchA8Dh7S=(z?m9E=7#L$+9pO0;{r8rP5SkOsqZH3Mx7N zp)vxM?n0vxiSW9IKNML?ATn_|Ccdv8WQ!stUSPk&yLVH{kaGQa(^1Z%At+->=aQN8hnyXy zOX#2&i54wHD1=0W1_>As5=c#midZ`){B%R*T*+YzN7;h}*M7IEehGT!{A_125&m37 zssHHuU~$1cExW6|FE)QlDPH!b>R0_|!w+n~I_6THhFU*vf$jcr;(2~UR&I)S@paa9 zK*I9QC2l>ORkwNy%*mLu37-0hKgW$2%OJk?E%xH#Zo-Jh-~PUIL_l;FCIqYZzyy%;&(1DbqxtxLg^KKna$}<|_HG?=#+Z;qR@-P9`wuqi*4lY?MB5 zVUHcJ=V(1qkvL#n8%@O00&K^PUjJ`teUZJ1ZQwKko3X3q{#gZ=pLJ-Qx*sy;&=+XR zmJ#aLSo5}>CRZzf7AXf>^a!BYp`tOK;}Ur+jgSrv6HSwfN5?Qgld!ShV)Lvr#j$2X znxGwdeMflBZjVg{SOIOQ;KL-Bz&2VHOM9XT!c~9Km}9#qZkY38;ZsRi$JD1cqjt80 zihoTT`1IG>6M>fQ+Q>CTOu{NeA~oz-BvP`!BWkhPHk+t54OT8nUV=KR@Agx(hJCMz zt~`9`NK1X61JvS*85dXXo}T7*o%1!47;cs+&(#^_#P0J3rKGRroIdl&hL$50mF@6Z?ks=9O3WYS%hD|^i;}NNE z)zMhvqQnY}zhR|y&lzRPpFt;N#Q3%mhKdCuhr3c z^+30S1>)@w6q=-jNYQAi5ksV9256H&>)TltVPnxv$y@)jOJ62^R>$wJg06Qt81G-- zbsx~&&M)8FumdZ0om(3-bMvjMm0k z_feRI{{8DwWpz8~x&9-~gp{u6kZv;QJuhy-3dikEf??keML+4nzV<#qd-N?| zrfS%a@vb~|)UfT%EAo{!EDe&XkYlDJAt887m-}eBqrU%j=K#qY9YMN@*RRrS{`KiV z`@R?CTc27m6ZQuhn5BeENr+uUWI=2mM{DSGym8Qb{CSbG7Ow(Y9#*?>v{s;{-~DZW zmyJPzv-*eKi^+ew%YD*b*HTyV^K$F!ziki4$bhzm_X%Z+L}G*lC{C(`y{tpsjX34C zyWqHDWyw~%*$+uiuT9emn+owCn@*iuN|jPUXO=8~JShF>(3;f7Xpb%-7p{904l7ho z*pxPK$^1*ysax?@({FV0nk5Z;Y_a#?pcS)syOtobx_`&Z@#mHqp*VUV=>|dVEuKP9 z(fSannq7!AgdS#yBjwj|0miEy;Vu}r;5DhOung6hke9Na1pOU$;%R~1S{62U+T>9fQK;^>>D0ibR2)@x#wp;jOO^sy-=inl%(`%WT48=6{&Q3Mxh3;kfpv8_ z%UUQ6dup-w$e@P5u^N|A=vL7PUNMPESr)?+dCrisZ*2$~k9a1-DBREGvc_4Bhp{eM z6TY~gU4l3jwwta7XcE{0)PI1msbSO!%n>`7+iZ*xy z4gU_WJ$y9KTI<$6ksnt?vl)BXZC3NmX@#mnTn`CdCTpc~PN+}v>OncrESyFyE0=i8@n2fXLtdTl%}25@sX0HsfO-Xu#I6G zEe>ddozLvrm03BasQZVlU#FhdJMns&T{kcHcWFe_g2~5bsKtae95XyGb>%>@*%-Rt#qgL)C;$ zZM;t%uY8<$=}EB7WV&iCHG~mXn8&Pj^Xl{A=scrb=fj7dL0sNDX?<2gwThx3E(}I? zs9bWEKt1^kAp#cs$LAqpDDRaER%)3OP45uY+cbO>En*0+a|711S)Msq|wDJnXK&^oG^9PR8i z3Edl%rsdx;V|>Y^OPwntAc=sdntA#Z*=ZO(ttD4>O+T1lP`8ZL-S7olnqOe*~2h#1DwUI8r?8(^>RxTGaA zNQqOGFsa}N7_*Df0%*SjjnNL<@@DKo-AtefS=yd|NAr4^<7cY zvIb}eSem?@HcfSUk6w<^MX^hlX`4^{_WJyXr^QQVk^B4}m+A(S0dsBr%pT)I)0@sG> zyPaqHFVXci?^Ynb*zBI;5RtZ|iHbVZdrwv$BTIMZx8;c^ep8(n?fLZk3i?t&fSGmN zPHI1i#3cI2cMLI)@k3IHJ`725Qoa=NauIJl^-7IlT!FbVwJBPTt8g7w%VbsX2YeUf zuPkip>5Y0hl4By5E>@d+F#x+?JbgN8<@aDf@MaUrH4P+mGxFXUx9`y}rON+FZ^ zC=CVJqBt#z%y3=d=La+fX!m7&SMy$`7A(zvOj@`Dr4jllny2zz8=8R@ea}E)o+sB~ zY0(jB4Xy1o<96D~ztIMAw1cPvi9VV14Kcs$$Mgo8nAvW}PeZ(Ih&O?H^(%f0yGo%> zZ5kn$-2+;KY;h$H#`p`ypMTI!0IfIBx}%qaf6z)z{{_vB@A~$aU-)!fqR6)Mn(>0^ z=4Z{dH(qc*zQ8N(drwMp#0NJ|)f%sCzB_ZK1_Mnl?^xJek`uiqtwBRY@p^B}>Lt;3 z?fEt-u{&xWEZX*I-4c3ufQN~7+;-~uL9|Clr^cl3YM^DGG(L&;#O`2elTV|B$!#<> z(0&72rBqHD_ z!Y)9^dUg?-N8k3{-lCgAZxf%|yLjE^-s?JIw_YEQ7?cMsjao~!j<~f_DgCmeNq_jM z8_W7-OUu^dL+hKm`Id}~oX|pzrHzNsPeZhSeYUdq0NtXc<06C5$0pO=Att-GWXGFi z!l>L?kSwf*g-0hj!bV6#88EZcJSfLJu~NpaHVv#gl?Ds%a)+>B4R?S>Y`-BU`koSv zA;ad}y8;^T3HMe7qVr3&0yzyy@rnp-^pp^VB#}}>-CU&4>wsu`m>MJ&sHcE3jlMl@ zd#+vzBE`uYXM&93VK==GM+}NaE*-y?(u}yZN;&WI{-y)NPgTl5c5^>Ibhx>j@1H@D zvLCYP+EM>gMr9QdgFEj?)@P(bL?=OP`XG8ELJTL<5;nSMuHnTRurzD1*caCU$y$kJ ztgPvWOiYG#8-HaSCtKkKG9k#a{)NnJ#H~@=9duKqMxx}si+P)+G1{2y@}a9i`M9M~ z5fqNTEmO990oe$U{gK`KW-5MtqWLH%(@Y2&*QCFqWDb(5-7*Hs>;#oJV6FQ;`dNgJsnfniy~j>{tW#TOw79IHv1PpA-* zP=$i?wjXrqeuHwDX%{X%a4laqX-AG^V5dW`-cO$Vo>B`gn1s*u9iC^S6bkfSR&37q zu3Bg}sMDdBs^C-KDR(63x@WfjDAApjQ=3%I854(J91~k7vhg6TGT-qif*}kAOSX#2 zBnFI78(HZh!U1MX=ouwQBr(&-Gzy$riZ$l#>daUslBB2URVW0_`;pR&um~KWMEg=QF>uw1%HF z9z!^_(-O&K6WwV*E9&1)Gcs$HY3{bulsLLZbqHuKH`{5S|4u6vI(=C7pES3Bq+Jr6 zC%LR0W=yjB7ma5iYkg2#)+W56u;9YLc3MzDK|{qepeg#d)0C7e5(qh3=}O}d%etQt z0F8XvMtg-=TE8tTw(67}FnC;e!Nh7BGIl6tX<8;|obg|@hNirlmH$aou{1$0F~B4J zO46#bgmeQPliVPuhx9Dj*Mz0nGqZ}0vYjHYZ4nZF5@;2P7Q}<$Swz*}J$Ln}Uym7y zgC1whJ~?&q;l|T0mrM*JHZ&Ve`rt>k_-cxe`wv~bdC=-k)n{({rr+r726ls{u#b(%?vNt{c!bMk(0soGps?XIudCBKVO5 zHG?dOLJ~G(Nvv#siX|g)b9zpDia?g}S$kbP8(Y^(*AOz6UTZeSQOY0uJ2QJ9#6C6~ zJ*{~xBiI9p4jd59{03qPWaPW(~7;J z6A&L7Lz;n_hr;kiyKKGb$FOSOc zK>PKCo}UuG4_FXA;o?&tkCVY^FOccF5A#CzW>6)aTi)TR<((jA9?{b;9z8Be>vS(^ z#t4C@!R!f0OM?tO8L#e)MK^nzl#s}#FX}8|7a@&ABGjb8h8Ll#V?|SyT&+-JAXUK! z9(+mJE; z&8|E`UHb{Uok#TkpRiE?OS0&eN%JK_WV5s#=88nx9PB)MxKcC)%T)@8={R2k-1I!*^NLTRK>z#$$h-IGweRREpH**ES~U6f8yCkQ==aPW&ofyHV19L&RDHf^c}p|3p-98%k%&oR2I zpAcm&LoO^#=t_EZG;Mgw$eD?=T)(U@agS`P*_t?0}S0@ppP{(WO+jef(9NxE6 zV&m{=y1wlSU)5Kr<#ZDggtLo~Y-R^$sf4Oj|E@jP?#4Qe(a_oZx6CAhe$~#oSCMHw zOSK_mtsZqhDl&6Ors6z)bLoZi-1)?m={bsT&%+MXJ;}`NvV`i+WS@2WZNPj2U(GDv zp47U2c%!7V=vw*#TPN$)3n=!Tln{o{4a6mdhp=I<(mh2qLVR0f6HcnIoV|Xh!Mc&M zRM=fuy&6|3;cL9-ShE#8He}o+@OUE2E9pktwrkRp+CAiQU)3v0k0~M`Jv?MYN^9dp zh~J5AI~am*%i~8_QTNpow7W}zMh+dhMGt5`+BxMF_MN6TZ%E@))SprLnX9uE7x4E> z8t0EdTau%wfBqr0p)&JK)O4VI{=aE!DLz9JKr=>Ud{T8N#MW=8*>y(5TB=?K4EAcJ zdbP}2rNpW_j)rm7Gptz$G%4xvlScleP3CBo|4fUTAcCyLXe5JY>us1xOc~E+&E9%e zWn#uO0+OoA0$M(9EYuWynNI{owbN8tXQHBD&|h!{Xmbg5X(pYN)EeW+(nh5pARVoL z3E^V<34mr4pIiHejeV8wB`PBLT|4tZ{!J$PNi+CKbKz(&SejD5zvulK{OBf+vXs|P z6_soBJb#(>_0DW`hWTK*j6EQ;=dne+SXdjdG>qVLi5l^Ake!GU*4<2UYFal@*#B&@ zLF-1l7}3+&J2p9Lzr7NWY_y#^Uw3m)_x&}S@cBF~tF98e_1_L0xoCK5x7uB1dgL>8 zPAD0dG&5Awyt(K==gOKuyAK|Z`+U0DC_0mtnH)}?hpMZ~w-7h+VnZZ6HnbgV0R|a~ zb%dc|Xp{yU!6IzXYE@%JD>P1DR8Tem%lnQicLA)f4K|{Q_DZRHI;(PxsosP4?v}^f`b~b`4Y@>~7 z(uxfsc@SG1iliNYrmqw45rJIWXlJ#WqF}h31;~6{^_HW_R0)64hH^CjHd<&qt@}UH zP+Qgvg^mM~spZHnMzUx2_82Z}hPH83A<%}XYpU?2yj|9sJ$CC`Uc8g<==}8izMNG^R zaW3;Jdqd1bS70p#)+(i{rMd2T#WDG_Xr>PL&fi>L_@toR4Oo{rRz`}Z(;HyDZDZ;E zU{S+=u&nvOG67ak_U$BeX#pXzFfRGQs%9^l*KjNq=Cx=P?|-;N%x2aVnldL@Hpae! zUZ(5s@UL8MY`RJ-XT(%L@wAQcie@fzuEGtw{oHySp`tk#ZfREjx2wW^n1;$_UE;Jv zjm4Xkkn^*W-2*a1c?9J@bOh78)Q@uso#J*kS(n;gc<}&Y_vY*BB4h7Bh;2b}t~;tZ ztZUWF`50H$sg(8X$&PlKZroV)!j9BJyXFC5vsz6K`U)E&Op??aj$Afzz9mrs3?Vm! za!Gbt5hG*|^$=QZKJ_SaySV(f@|`NH$^?h?>zs27`tN!>ifmf-$+ooLd`cC$olJUj z^J!)1ja_So9Qrl4nM_bECd0?~o>$VZhU$q%H~Dn5^p-}LMpSF~GkiVPN~}=9h9jk} z)*f;Cu!{oU{;rp!;DtLl6t%m`zgB|l>8^PNhoW+u9TV^zV1J!)?We0F=c?sg(Gn{W z>lzI%SSeBw8PeTbI+Q@=7sJ@iB{7ozaGBP#ojh**qiVf|mBA{kQ~bBAm$4qm?7}8C z{Utl-`fp@^vMGr#+E&TG!OEO-FE}Q!8Cy1w%NS-8`nB?fYHj7NHLOfMa2H<8%I2{$ zdo;RM&sf_Fh43TFTR=ufAU0zMJzRgt+~y4fnIWnz4C7*(*`wcjmv0b2Y*r>$z5&@+ zY<>BM3_i$y&;t54=%rG(>XL6sp3j~9VAk*+CqD$w@SVy`-J0E~PqH^T&{7h?dnRQ^ zX2fqq)Y;>uYa{yHAF^3Ez^B8Za|8DMzH!O;Bl{jD?mHRYWJxs~zb&qpep+S_)K3wA zC$saOn-3wVpX=Y?02EoNx+4 zk_2th%Y1wu8oR8Qd2dITpIbK0!;$OQ;#ayeb$UMt(c6)Rh*|^gWg{1 zYF%=fq++gT`K+EcCo_LxJ-=-2`HubO%SFD9VkV4_20L{!;Y;+Tv=EIFF=CV{VPT?h zyH`VW^#}NfV^0rA`Te)?083)5j)a$UuxM3}r^~iZ>ZjPL$nJOGX89_BDHB_>>mpfL z4}c9GQ*z-4Ea*RBh$KAhy@&`t$`0&cg)H=iZdxpijA0y+8fFwt{-Zoif(lPK`c{SC z*EP$VU=gaLWp~?TXZ7|`SC@e7%4pA`cG=je%=oRk|3Y?Uctp?p{d9#+KIFO#n|51t7@ToKbTCVc^y#*wCG5(x7jyZUd3zW3a$mFEuu1Fm)#}|ZFMnIqibxYARUuNs zp2|jy24OyCPaW!>4m4VSNHqQfKF*8${`G#udf%b$7Cy_|#2x$Tt*5r1ejF>fHmrxu zPCUVD_O_>&cFdozb->5TVD``v2FcWUpY?T3;mfAnog0w*$KD0@qa+!I)3h9mKV;4F zoWZA{8Pr7qggvZy4+t${B~mdAbTxI8eyg7SoGm=sK*S%%B+~> zL`2zKzDK`pYgt(Z$i__c{vos21a)I4$QG_+Wnbm1u^Ru74eDe0@ak5it}eFzr3ddwW-|T3GNjOBGc;I;yiOXnz((@+=?T z*~H&clw{@Q3de(`*69I4T2`1C%D1yMvgFPY#fCCMhCm^s4awW(;QNb{ZrU@htCq#qu|hNhV&d zQ@4x#&C~rjS_t1xirCm%S2u;mT}`s2r>|x+2C?G_@xaYoY@ju*UapFCkty3~uW>y` zt8b_EpnC=t&NVn~EwPm>{cZlK%aeA=rSU0?Ee6KN|6ZWs?#0$)Xg<+?VOh!!(R>km zy9o6>ulVHjT8a0}y!+>`2M3HpS$#jR>n95AdL<%%?L6v%{C=9}fh3=5#dF2(CEI-m zWrc)St)8>({dL)p#r~AGmz9CtBF4C*#9@-(Zy~45g%1nY7OQLS2@|dw55@=+mV8kN zV!Q-|iIgF_BatICt0Z*8G*6E7(+bE9k|7I{I+iY4}}>E?7~9OIxm6<5Ho}}5?dfK$aICpyunl>q^xom#%twRlhc4T8mxYg8-P~d?A&_o zZ?t_9J4xR-jWGroIYgHuBZp-pzYbfMprOnr8j8h~%CrRR1+Jl{Ii`1|0kqI8g5|(Db z(E_y$19}%h(mGs1V(}Q3X8aeeRj$_LRB*IwKx_C(dy#Kt+%G8m>$t>DE4$3@PJPpT zxyI(o=nw0=pxMKo!fK?|$dnxriV%BUjjfS(w8(<}3N^s9=H%uhTZhyt)t19GvtQXw zANj%3*>F|gE5qv&2T@rbufN<%pRg-;)!Pk^cRzgPQ{QR*fuZLnulyw2eYF?0&)AA5 z?bLeGmFe`L%bYaPvfs+)9ldhB+IxW8f+-y+C={+Vf#TUn#Sq&|A`#GJS6X*y3^ez= zRTvj)FtHj$hAyxY^Vkaz>PlRHO@o`+6WTZOtqcKnRbSL;rJ$=e)nfH>pv{$qEUat4 z$CL>naznz+_O6VTQ&A8V_hMwFf_*{fa+bSY|O; zV&1oC_`Sq#RF-GWiCagjfTrI4O#blI!up`YsV;e|R=$^Axa!Q(-2YCCJW#gi=#?+k z-p(9tA42Xxga3`tE83AgZ#tT0S7YB8T3^hYiSZ>3HXC0E#nD=Rm%WOf2aA!V$?F&MKZ7wg&TyKMf{mTA{X5&$lz4=IjVeYDCZL5nTU+FFxnPxd; zz@WaDhbJ>#r~=O#1<>S>)ZMMPk)?g%XbM^L9TzIm$cm75`VML7P%7xmh^8JWvpstG zOPaTno36iz+DC}oX|2sC+1T$Oc9_I(p{rK65M7s;5d99+ObxySZ9ULb3hVs4I2GeR zpg79wOEjr`TZwI<3{xHcHyRk4@(W!ApuGv`-q5dk_a*uiMt_7kq6R8<*>JmS&|!& zqCCPwffRG5^OK#tV(ZiVJ?nwgi6xB!lK%otCmG?9;7&l$7u|a0ZViFhi8M@Mb4~fguc%sJ%WL5t2Qc$2xQ}bC6$#LNzyQ;TRhmQC zTE)`du(V4+i_y_HY@-Rg^ZzZ)DCahx9GSyU9`7A)QWKZXJJbEePV&ao)8ro02usR3 z=k_?DjrdcxK%-H8KJ8F<_AwPc^cqO2Mq(HspettY8=dqm2F+HmKvCDW&8T-AiwkE9Cf=j_|=)n~G_ukV89Cow6b_a9vl)xFPv zfiLi<>^syF@!;?!RcFExA?e{Jj_cBC;Un{1Psat6I3n@-O#Ni`Vr;Cy51|bX9=d57 zq$4bqh?69eA;dPmNdGHl@5*k;!B|rvR|adaPP1ImfE9{snkbdB4K}|G=5(HgopB4A z{C8Lfdnq!MB7$Hq6(OS#zlq47rjt0C3CQB&kXTFFcckY9kh$kd?ZY%S0=ql7U3Te= zm&+r^kp1#p85Om9@rrW~HSMy9HksiM*|&3}mA`*qn_o4_O`NWMgCZ zGiN_!3t8Dzb-V0m&R7||bVCPLX618j!md5~ChlC$D9D+;W2`B_H}n_@GNX`56_P3C zen~%NmLS^-3$k7IQKdL5&sqFKw(tD|?;ZPHFFyS3@&V?xlfjglmG^Yfy4fwOgo|U(2q&KL z`%KNT=#f8fX1<{NvS`o6W;=B4jb|%dvh%JepS(CTzL0t_t6nr=zo%ck+shGgA4ZnQ zlaS$Rvw2E9qJ#h-EC6becx(PZ(E&{#u#;^Vf^x7-_&7D2+cm$ zXyVqvTZqgE8qoj~{b4_YgH3IReHtK~8Gi<~!{+DDo6o^K+F@9hEx)X+`Y%|WOFPUI zV58b#h_6Pvgr^@OU0sr2uEpqsGFt0!C=Uo(Zcj`pXH%rz9$wsY@-((Nxrq#}y zpx0|!$_}bZlHMU~rA+VWlxevea`rx=QWlOlqIR1lHt?`<>~cT-2nRiSJy_0`H@Ml(naAE5&4|RY;Rv1nwLdWl z`X|5bM4#nhetIabjU)-1&5~|K#pKj#UH<0c9~Kigh9~+#+7q&tB?YAw6dp}bzfyet zc;;JIndeWE{vM9>yuV>PY4yr>lB9bZ31X)`7aPJ#(MYtBwa}YCW?LMRN*=bcwqhJ? zi@&nPUZIVvoBzOh>c}6oK5aB2HUMa1J(@803*PbXXp?{j+0r{Y##_4M(IDJf$jF{rgd zMcoquC-Iv+-3YfC6wq#n#4PRf^AU#av0YX!2=HZT6wp?*(R^&HfL5hY%*RE~fB#84 zJ7%lHhlEGV`Ubm9IuWAO4Kp`UkU4Hg-J6K?;dfd<)`ZwQZ%7GGq(an~28S!=(OKTt z(>$}hQszU0u^1$t#G(oSO zC?~g@Lq8@B&8U7^Be!C2K$gJCDh6$*??G)nv)!+^&+#Ndc|*spK!2ym=wbDVVV0uG}89dksB z5fa7}u}|FSvX3J2Q4eJ3z7b$)B9a9P^4$UKHkF~hEr1Ko=IGj_hqHM!{-TwT|TXw7rA9VIiT#sFiq_HIx0o3 zvP%u0dONz8!`Ex^QnxM9^9e=85Z8j~U)^v8n~{N4CYmBC zf(;9@{)rKLIhp$ryHD#DMQYC%_VPM0lOE$E*H$y z6yt_=S@us^?;Rl1>}!`%Y@b>|kX#%*c4c*+Tr!vW&#=KW=k5+iB;vVbT2c^HF#DMCTu} zGpTFv7fuE#-5MRaMe)e_dO_q58Dq|*Ax`F}Yua;1T*mgML_!jeEG_g|*)~GwGbc+K ztd-fx1Y)OJWzrDaLfR&4sBe=!(oAkvu(F!T_^86=JzEA%eP^8QH#8!y^j`6YLdTq= zIo5rs_84(SMLpfC}YvCk|~O=*|*m0opG&DVF4k4|+B^m;=i z+D~!}n0`*(VUQj5DR*Dkty1&IVZEKr-4%X;Q>t(8j%e+_zW9OsVOKlK+$^NQk{ryG zzbyW6(UI!xBD}+!aO~RD{9|rbreiD0rB6*#J$Qq2GTj#4& zxo79K6^~S_)Ol(b?h$%`4CpsBoL_pcDC8%k`(4`+04b|9lpyJL1W}>K%oO<%h}%~r zdTjHFE;B^bhqQf(rKJX{9{Mh+u6OA`x|$Ks1s-=y%Lq{{qHZayrjBXJNBiBO@)L>5J|Cg(M>}$|gCppFC%a@-dbLkv4}E9z(OX^HWC4zGApzvUjSUoEM$cxX^)a#7SR`_ROdk?$TF{Oy6EMmmsmnc zkj**7JI}=yhZ9K5ZWh&@q0Uek8zr(#W!a7&AkgNi>O(rA#zs@GPm?Y1k8_8lw^U-NMyp$ zf;d-5ALbt1Al|_cX`qHJwpfX4)VM|_Z;@#HRm^NF4_ZJCssIr%N=x6$9qq) zc9-uIgZP#)CTfcL4ciNGG9w$1 zNstj#dZt`ZN+36+CBy7xb5>^bMFTQOm>R#9^=Wa@K%M7kCA~u1X>=Rye(s!TW5 zb*SlO#d;xaNu#SFX+XQr^e@p_xR;>>EUhcV-tC868UHS}t`1LBF72;Hu)-rb3GV;aDD^L0s$tF2H@mLXEz1%*hXWos%iRND|xeVhcxjMWn#L2oEZUc3j6^IdZk7~KiCdXd zSIIwEl>da1j{|6jY9fP0-B#NI>aILSt?5_KqHuu9vO!&_a{Br|Q78HgSKhc(!J#^i z1{B1Gp3S0-WiQf_)*%}{#}YIGtJ$TMb7`=+O4(FpfU8tLVSWDw-UKVf++>=D4^V{6nLOt;EzRYT!wX|Xb0 zED8-2SzhcmP}-wOv(thR7|+05ONbd5OafbxfX_Z6C4uGl(AGS!jP5;lxaE|mGw+=| z@lH^6b3(Z=UiolN%jZO@URs$bc8!-gi>A~n_a4c4=lS^h)G94{?loD<=lxWds?tG^ zQti*U?}~BIU1TxEu&J9+q|@|pr(vSNa20?=7->WEf%t+XLDg+>A)v-2Nj`A1{uQPofZWmq(#C} zKmLG(1>Kig$9l0Kiz($ZlTRLgCwOvw!UHX4`c)33wEeSSBMZ`=(xR+937{7@r&bC_ z;z#YETL8-ZPmn?L!vpOg3tcgd?9-5h1!?=S*XcoY8MTSD>eX`mC>SeRu}%*6{A;ZS zx{JS51O8GW%Zs-CS(Wa;Q9ZOZJ}aW*#}3!#(gdof*C9>9g%8_RRq`9ICuPo-KU7sW zAx&3*s)`1fr!r^U6F8N>VUsN%(lkkzQ?a34Aaois+FWQ*T|40TL*?>Abrjr&jOdWjC%Nov4cNv^+qjf+-0AHMI(Bh9QD8`H*aGm^(f%XMK0fy~Ii=X}usNzrWcHb2{Osgva>#X<-Hh22;=&|I zQ7ju&OdxHf%N)*z(9r+2wqhYvZk3vSUY^w8Mh)gq{S#(K&TMIwD8W09~6@-k#mHj7vk-Iu8sWtwuR@nl7 zd(8+1zzVx$Sn{h99?V_&@^I=U{>Qt zp$IYTso_?{^Rh!8z=E<4x*pduIscw_4;n{kn2#GH3|52<`(#e_ zkmL^^M zL*dcABi5(ChPZZ2f9^QXXT0qs9%`iBolj^LCmKU!Aslqs)0?fBmtV=IOZ%Y;3dO2c z88?PJyXjGs=r{#L>j$jesMrpo1XeV3sKCSQBPH4xm*B-XkOaTTv?;?o6sq_Us1gzS zwPgA$g5pUo>aV(X*t3jT6chA7}F$Bau8JE`{dq-==G%hyKWOtg3AvUZ- zjs^u?-ZG(5&eDDbT8?^hYcR#qmVXzuL?82rsr&vGd3@X$+wt&)g#0~A!>w{fsv0-; zR7?xviy6KiynA91dz(Ld9|2-0ofGf9E=-m$wm?Dxsl{ZDL_gRsa_WwpbX?QnB)@@bVbZ~8>E3t2MPJ%L>fOt z3@+{Wdg&AM7l}~t@?jmESXTr+XFc;eYzf~ATql%nPaer-okV+Z{=;b2wXAf>hQ@DY z%Fu_L%eURNfhoJmy0#XWtzBctx~f^1K?vvaB++I;8s{0oX{`UC41K}D-29IrfH4~obD75_OacirjCCuireMMQM#MsF z9>l(7z`}F@7G-#pA94c{#;e^WgB=AjS--l!WWlN`PL|%?WhJ%LiCO<5w%hu0-G>w0 z&rVH_cIoga-E#AUkL_n+5KO~Z${vyhQY3JLQmEhYUbk)QU!=BJIxkzLBOhpJ`SW>jvkAp@sbIHj%E z#P*3R-+gtN`;P0ziyVVioZ25Z^&UkRiBhD9fY@{_KUtd2z{;1Bv`zR%3StZ8Sot2a z_W>Ep)vCo+!7{dKf+N>f+3NzX9=^00;RhxJCav{JJ$L@;3Z|u;={Mt#6s>L8TY@AE zV?jf2A)OK9hDJ+tk%gU9aFvds^gCSc6TALS>KY;{9B5&>g=6fzw=hW}j~Pqe2&te) zj}7l{sd8x<;v59DO($B%ehFH~Je$_2%FEtG)%F@PqK#GzvXTLSQXNb47j#=Ox1GLZ?r!ustpsFV>K$Eu&iHeTa z)YqKQ0BtKrQ+@`T-CzmOqykN>PF&K3__e|&_GdM+v@mXior$}k2;*q9 zujqJe|v#cmUAwRcpL!r=|gD%1A{e z&?3KJj#dS<%(!HOu%0WSG)SV3&+IN@aKa#&)#?gW`C*-O;j`otHIdHUy(e*8gXOEuV)+>?@oOXBl3`di_$kcO6 z)Gs5cLla5l$Y*Dhwlgy9(0~&D^r zh*3Ar8;`UaB&Cp}2TUSTgd~VzoRB-(h)|pe*$rkZBI4t_`M9wK^JEGvXMY?n#@E;% z*vL7&{(M?9?UCDUJq8@NSjUEThvlJ(6mse+&0zc=6R@KWdhqyCDKbXdd@+*nJfOTM zW{Dy9KjqW~p8m zZn}8xB8PJN3w7`ZN}ENEn#Q7>LZ$GkQjmlO6puw2wWBQZoMin?E;EV$-TKbE#iRm0Nq-?230x~_R`Fni+z@&72h7icKA{sH{^nHgi;XWT-b zJT8@_QmJ$`q|%i-DwQI-=&n-8Wgd5xN=cj|qjWz-SCts4&<&>>6{ed*i78?*X7+#Y zp>xjr{{O$#`(N)m?`f^GR$m|A{p|hS&$BNKuSBn@c9Whe^Tl*AQqtB?7wK))gg&1> zv4c5-IuG<>)L6qEP;3fy@8!QMX$qMLdLx<`9{`1ElAd1L`EwharrVo)t>1Y6@@su| z`q`-JOZ$wQqg7pt6e{HqsB(c3U{fHf2e1h|Eb^@6fXPFpCpm2g-S5-$yHQ6B9K8ji z*8x?bSDyLl4!4oE4v+n7B)QNdN9KriCl1wt! zjh^mcPHu3y&s(BDXu#RH-%su{m6zzu;s0RGQv(bhFa`r0K$HSyjYSB73gCT0tx}E0 zHNw+<32cB}r7&C$Rq^@E3MhGtH)XU)q)OKAjbEJYt-RKMxu5mBK05=khG(cXM>9D^ z3axSym~)w4Tvdt@$3nsJfqw_1c=omoRX#696UhQ;gKJ23*kIy{H5Xp{EDo`#^c}^p z{?R&|_%ISK>>p+L?rlkaYOr40{UGglSxMhBcxksy&QU;S@!v{hH=M8w#HnMIA|YoHr%^_149qR~Gm( z)UDgE3|B!}S-2yr-;cMY`KhTmr%KxM?X6QHprV%sbfXv!6uF`JJ}}}AGP92R-7-=0 z^?fZ(ejo?YEP2f3Tr&q{Y!4Ps$ViFe{jk+loyj|FifDBb#YxzSX)T2^8T3Z9md9`9 z^1PNU$^oolHJ($AALD&Lb3x-rer`y{0#2f4*DvfE!02Og82Yi&t3W8r_fs zV|RM05O;_!D$_aK>43{|V5sGS(Le~~&@e}U=ftQxR20B1UFZ*`u)`ZZQT+4})pp6q z6S4Ip_Auq<$P=~AD#>#U1pR$La1qm;FjqH=T*-<}ilS-W5H7Gx(i3vINR^P*GI-w{ zeSP!DJw~*hWPA_9qxkEBnUU37R9%tkOIlpR{`7v*{NuAjUdguxbZ$X?a^MGunxR*mXa1%s*Ykczm^a^@sWr@2N*b(tPbVU=+_>`}fFbc9$XkVuef zh2V)8_OcePCDQDoKdX5JZ7tpqhgjj5MPt^$U$e^6;?5*$8W@t(ex9H>F8%*Ti&Dd;&=g;#Y9*n z8J+HnJ@p%5ZesRe_4Iv7C3KSUcwM!tNu!0iTnPJ%VZ5kk1Qgdx9qVo>5N!*ld0`rU zxn^?ykIFlD{ur6`Db+}?1}?fLL^Y}s|dQD+A3-W9)LP%>G+uq|im?BB`-W^)=o8M!4*+HK^k zmSpd-58iJb+mBqP@u}?euxpnOpB@PMNejYf&%e0#`QFh(*^%2bD!(F-kj5W6xhhtG z!!y-QFy{c3Z>wl_EI&yN^@IJTi6vL+M>)A0wtN=JUcS! z{t+X+AGYMo#g8)D_T?Z@aC%WA$x#PBw^^+B|$2i0gybM$UQPt@Bt5PtPL(5`p}6KCrtv9(JtX(?VYU_M*G?MGoX=VNeD@ec3piZ)6~)H1IKVxH zXvudX_N=@JRJzv+5$$(1nv}vm+A>U=y0=}i0MTkOZHRcI>X7Dk!$xvP%+R{QE(Z zhe4Ot=*ySqHnoR+3nMiY)6X?b^*L%e!oTT{{p0<8(icnCf6k6hp52{v;4ryU_3|Ly zYi6!??y34q+TxNYOtW^do8<>C23O+oytvdp035-jx3h5!d$O0kcGhqxeCzFj8D1i zvR;f4%9hSYW#-EzH3NmJ8w30iX(u9WiDGW?m-vvkzIi4rzT~Taowz)^olEPJvlS(X z6!6A!#IB}0dyLgAYJ()3KYtY;YU=KRJ^w+fm7bRET8K!KmxPVDrh`a~B4CGN>lgud zz;YfZY<-RTL(UIg)Ic;Ob5IKe6{r;aCWSdrCMxsRI-`JUQjHeD8`%ACTEeCpI-YCb zJY948C`@Anx?W>dc>WKx5=8SaW{z0jWY00?IH#d(5!nlqntpgyh9O!9q6yyMWcFm< z>e_{Aa=G|w6YQl$A{xh)%Z=xfAK2=?`iM3J1ZrQ?tnkJ(Wo%Cz`_(w1?CpGttJ%J! z4#oZ&+}KO&*C-X|NMw#>-kJ@CC~F$0gWkZN-lbb(UYy7(Cp8Q_E554bwS<`OKlrum zuhNype`vC0ZJ+RVV})|vf;MUpJW#~t0D=ct=6uv2PGLSBF!IBXE&Sd^9wC#mLr<^LY-xb<8{%w_?c}Jx61QW0Uoscd@kklh-E+-|yFF z7?>W|sB-2KF=XEF{$;);tBe0Ije0Iavn^nUVzc>NjyoU@g8Sn++@Z!m#hi~jWz-)U zR-j=EJz3HmsMri08>FzK1$Nh=nx0Vfx-77Z=UMSWZFF%6fm{#&nz1s=R+A-b%VyYv zB=l=z=>sqcWIGb?_0#;FwimDZSj1wu3;CqFlJ?`$NxPw~Pi*71an~^Qxi^olNWK@! zVl5*TN?PmfJcq>{>yqQm=5~Y%HtdoW=v8%jT>MF6BU%`yty}TC|HEx1t3Uot%f&Po zF2^6l7JyHPW@AjNI2Td)nh4Y%x?!43B29(6oS_+_Nm~Tn1&(+vgXlkKWopSqh!*+B z!}}^LBmXzr6y{uR+#4?=x7$j3zj2V zXtxX|SIImsE<-d5XN_liz*QxhCe-HbwtmQGt&X%crJu`aGO(BC!R3U3QzD{%a$4|) z(Bjn}i>w&#S^uW(g>U$X)*zBTncSW6H?7r4P&Q^bgOOEyQMh6L`c^8{&dkO^9Jx|B z$ol>S)Eeqb z;FIT#N|}TOVck4|q**jBKUoxkTHX~N2d{g=f%mur7Y3!R+@&jqGBI9HI9DNuDsogz z$pvx<#0d1vN&GixJ#YOe>M#OPM`rkVMj;d^+m4nM3_oy@IJ!rp#Iqlu%!yT&v})w>gZtcn+g8R)#e z8rqIvIT*%L!YcbxXP4t?ql)jdB%wjMUQbfIL2k%j!AxA(qcpTPGFmxqf#besJ%R5nTqYjqs$HqLqIll+AFP%CFBWNl7hZDJG?lDREb!7b z$tVhFTJ*A1zu;#|B5lJmGYE%^1P$S^t@dvj_a7PUbZER;uS^4E5}Wo~|5E0gGs${H zk^MH5Fz*#=hr*~x3l{Id`wS#2zjug)qQXl#ufij+OwjzSr~SQ!SN;Jx?2{#h4vs%O zxOfAS0jER3rtSgt#T(~nfMoNP7dYW0IrI~Xt+pAkU8(n<^wVFu=Azi7uM?n->N}`@ z=#wd+uDH$&3VLZDGYavFeoQl=w%8orY5^Ks1)Y0gphd*;%~~gq40f6mHDGd*8+x25 z+yQngm(Hl@qV`7_kq>9?ShT99c0xas$f}@djfK-rdw#q4zO&GY?3(3%iTqw`_haRy zTE~7`hgAdlduy}K+jo1ds}>!c-0*1KO>#=^rW3K-smQYJWcA+1fz~@UH)?!Lvvhi7 zG2m>54yn%;nyXXbKEMMCpQeSJQyhGz@hCoBZR@~xV;^sQ6@*@|Y^ zg-Aa^<`%5R)`-poLEwq*C2O=!7^*sXMQI}tsR>pySg0xkx`)Fr7`e<)3%?#0KbM*k!6xjxVSwsUX&5Il!O%WD+LokS|qNJh3>wQtq zk>9pGmnsBe)Wd)NDRZ+)GRLWk2u3oC+kLV*QS32EGkzs|ICJ45pG2HAdT}6AV`1b8 z_iul!tVT(D@9ciMSEj(Sl&YY6du!`2g>}n6cOn^l6jF#}b5BHC;-r~+Cd>}BzQS3h z@xh3RlExNhsFJ4adQ0s9lr%$wO6EP9{-oK=xr}7n_yag&2arurES4R>N&6x|G{Lbx zS~Gkv72`v?1|Rc_G0=|MH#()OaplwbnfQQ_Rf&;q1O0b zGQ8KA;F62iH4XjxJ)-&vYj|Fm<*U|b_S3%%atjqt(D>`p)zxIps`Svt@8N+p{?q#% zzjE5A-g@5N1uns>s%QUzCk15uF+UFjHsj)`AC1CywOf-XzC5?%Vm>qfWMKdK#vD=; zwLnxLvAODeJQ)EhsOz7Pe!niX5m&{8A(ctwP)jC3tq`9G(k+!r6w0sv4HCE(n^L#O z@cK+nPv>iy-Mh8w?5*fy1TxL!kUCo1@%H@$)c**53HL*WrXXOT2J@INPzSsu($jwr zl7+cH0qlNLEaF;=CQaYNo*v?|OXJg}EA?d6YKUZlo|=uD^J=bk_(-XFP21*%!nD~P zSau+D``@w;Nak4EEBlCL36RsD4cL7$3z~C?Fy(L;GE~4CB-1~NU*j61Tq$X_0=P-> zQ7Y+{LzsbR5=^r^Vu8~YJ38ghGN&i=_mTH*xtzTj{X1dLrSIBAtnSnO0U zi&yVnP}3h-%n7YELbMaBN%1Ba`n8XyxZ2Swoiwj$r&}oOMzpJtj6Pz4X{Sd0D58sM zwnk3Adv4*mo6K90fyVPWICc=CG52$|{e`}fo`?FGasqZ}s2*EGn{W+|GTJ&W$)RDJ z1g45>BVcpSM`;C`&&e}jy`%-pVg@f=5WwfoaacS1@WKe!pv;eXdH%F|SC_h?eTY6Q z0Tmf&y2`?n0=gX#v@dz3TKB!1s3o{`|8=wJdnHS36JLKW705=68>7MT`kfTLR=Icp zw&a#3bZoGRJd<$3bhB%`pnW=fOuNmiCNjqS>Iyy|%yC#V)qeR3*R7eYd3nJ={qsn5 z#YY=`avzZmXg(1QxXyeb;L^ol5a8lZhebaq+E?YO!drRjJ*NP_e;0(q*K)`fL8u`X zWGFGSbnSXENjoAqH;(z8!IK*Op*kl>F!biiRD_|2ItJGcp)T9q)@qzk~ktj_G z+sJLz-1ilt7Q51fYi^9lhM880o-^YGZG*>-QR8@EnCe9x*wR_LUpjH~-kh}arV`|a z^Hj%3ZR(oH`v_Ll3kwWi;rjjGu=9rGT;dwPs2Ao!19ztqdMv>O?3H#!JroE)FgKB- z5|)p8`N9yvLj*fs0hy?SL@?G*nBT0Tg%O;w$NWx@L$FE=8}duosA@)*4$jz~YqO{C z%`vjpEL(>%##SA}RQ=Dm{Fm(n4IZ5cNP+SJKNmifs60Kt=9_j+Qhi2z(u`u8dt7<^gFE?=mUD@l8kg2j zKDI1swfUn@g1texg5%> z;2Q|zC8BXi6>Wi3$FYh)s+prX2ZJx1-Z(z1|B3rx7LOc1Ee`LJVSs7bv?iG8HKl^zc9jGhToS%!(y&2jEo$wezZEeEoZ)<{-yJ~V6L?f5Or zZo4@`$?cZ0-p#jqR-UPy_NbjjYWyubgJcga=SJSbGSRZAO(P$DRd;Y9Xnqlvol*cD zia!nHvVPbw%=lp27?&?9rMHpH5y_Uyp|^3=3MEn{yEp3j?1ap+K>7Em2vli{U(!ySrb+FO(bS-#15|H7w2=*Sspb`dK z^1Pe#djt)&b7k$eB$J_%G(8HzdYIF0<`)ql(m~^r|FGRAQ7ef@_fhP4dTJ5D_L+7H z#a@SEU)K3yGr@5x9nlL56BIfspuS?MKn6Q9t|)1evO*YLp`;nz^g6a<=w0I8oRG4+ z^RN1Z^4lhzru=69aKGhd@waV&--9to?8Zm5k5FTZO@#!WqGwdci@h)GvV91YLAWgZr3KHDlzzo9X>-tPy^HEC)}N%%n#+a+AC@N zEH{%+DuF<+h!83W{h1E@SRz+Aoo~s>!mBlm#zz2s^01ONA;O+{X%YLptz(Qx>k&~! zBbryzU0pItNploT?tbN%d_kP~3=V(xOe@RZo5KnOt8wZM7ZC zKX&l3oeM`#Se~%y%82tDf5cmOX5ao~JBD0k6oq0F46uqJoD0HeK9|tfoMjP3S=Gz} zqsUBLAmYg~lzX?rWPwPcXlfJ5!{OV(1rQ(0xJ@-86w&B?$0odRI6LWV2>CT?xW_BT zY=dJRLn%_7ITe)w9Myrl?cVEHZv`qRm{X|SSQ-d@<51FeQv~Zk$PvNTgvgxlw1%c)VP;oh@Z!(XM+t($s(bF-sq$s}1&8MyEmhKHU|Kw)wL4A- z$FxF3JK>q#{THHbG>VKtG*$Dj4D%UaF70xKIZ5-2WfYa&;|j)-sZbG$Xq{pxuj_SDy=xCyssJ^XU7!m{uk}o(s*Lxg9`- z$xu`7Q76}osMd`Yy1BdA_B7{QoL<%D#fkCx7Py}|aQD|x4jK5>b?k$0UUla+72f8} zLk-I2*d}b>{&;}Kn0avmW76b#p8u`|S9RKbnODmBtG_sMcg#Js?}pH8Pw9r3%cL~5*LxaoV^0_R15=~3qqA}#Vn{tIA-iZvQU*$g}QoI@f&o7gh zXEtHaDL=xZ2pnv*J^4KJxb}pVJ&yv^Vp>Ucy(AVs9&sTBg!_R@@o3~@Momrv+(>`a z;jgjvM6|i?vow32j<`6z-*ZG;`EA;M=9t}|Fild1Xx?=>whBR3^U#-#h_-Ee_W+H7 z^Y-`BHvTs)`G831byP{~&*h@>m)QR;2}BLhoy+LY1)4lsHHpK$8-Qr_5{VeobRZ1> z4sXjpNnqPoLFX2!WJ+c)jnPZX@*|=U&0kYVv-uxstA>{u;;d=d_B_qH$XHl3heP{p z^Ven$C`T;KXs=xy2JPEy@wof-$Y7m!<(>Euw|rSJE2)p@sOWo26;z zt}7h8Aav}qSLroZu1}b`Yhb}2;+CSjJ0Kt^eE$iX4-!y=;Nbp|VB?cr2?mB>rMLclb0EDyNNqz#e?pb?jY4E3KfVd`}t7` zAc5v^qW}T4X~3bF1Vu5JQn45fU54L9@*un|UJ{NP<#z#;isg#l-tb<&LwMxPnzG>o&cmtXG^hT{EBvT{G0T?>7&Rk$%MJ00_6)ZB#@gdC8nB7H zotbr(hK&W#>gC0lbmKu3BBjTjTgyWv&P;GZ-Rt|ngJXR* z`~YdBdLo6MC62}}HvQLaT0IGWFtkkCqYliE3X#mE49h6rVE42y7DS(n{bqBS_F;7- zb9;bg*1@XFmzbuN_Q{U8uc|H7zVI)Z;6iEJ`F~{UJ{TSIyD6K;+(eP{Zw<&6fwiX{@TLgEsH{m0Nyb6Bg)iF&Y5!2NAMJ$7%-|x%F;A4Js>s?}C zV^FHLlezR7>1q)--TmxXO@>Oo$CxdH-Wz6fKTky=H{441bgD31L~-%5JZnOO%eOd4 z5ex?L~#hj~g)b{FuZYQT< zP6%y4`+v9fQj6EoXBeV65!)8%?A7PFvy|JDR6)N4{^fK4mXcYKgKv&l?CKI+lQ_8A z-D?7Jv7!VY1c%vwn%}S{+fQco2&D6Tf}i!<-n26KEpn}jg>q??Xs)^R205qKWy{b) zF2R4h$OV)kc4-niX)dGwv@*voHjN%La43qX;pT`xV^Yn-)x~0RKO&z0_iVMLQK~j#4&@A6&^E{gCgu6sL?9)CavtooRl9 z(r-U`2Gdpr*JTFDwuZ?tEgnrQszkNs(n4|$MI+iM4ucrwK5&c0T}W+?XYD58#=Q;TV`=kVK_ziFL<<{&8E02StlR$7&x zQ)ap?DApwK56b@C0=m)E?G?+Q$ngTL$+!ls0bd4KEHpz=?*{nY4saq3`1W4?KE_=P zIr(`;qm$XWaI=s6fz4k83m2})lMf=_a9sk%eN3zluHQSgc5CKELBEelLq30T?h^0)-eA7 zO+*+-uzgu}>I$IA0elt;tURxFHL1_Hckfj_oLb$h0t1yl_KK@=OY$w(B@C-V>MzV_ z?p0L|QKIW0ocAx)Hmi~Ut(r`>1P34$a|e^n$10$_SLP>cr2#Mg0IDeDdtjFcvy_)m z$ogc*k*qj%?*$~=7Heex2luB8C}kW*(ywHwSoG}oG3IPY*0~unc2t6VLxSC$PYJ(bMIKe0R-R9iic(IIIqeWN*RY?L`s4KY3C#%>*{oM3l?#j(n2AGxIXSA*UzhM< z0K!x)Cf2ek7paU~xCi+QCd(2=W|0TK8P6D7KxaBE%UIwrN_TBW|0WJkZjj$Cdw=~7kg+bQJ&azNGpg@WB%vq-yYYYPryftwp> zki)P;?arE_B4^rCRPIPxrD8-?trR_0`lUYv&_iAUAsSC$L>?52-OBNHAy;;swUS1u z4~b3Klwcw3r8%2i3<1QiXpt0e+PGSjuc_$^3b-Mq8T~hK7xtfY+PV6i=6-K7?|X>U zQI2SW%vY#wNNc@i7t4N0LU+PhAlPBSm%cDkj zJWqXJ_jXR-|Ld!8@a5IeC8>M7vfLTAXA#3G;YudW$?5OGdqfG7u5TgLvEQUUh6C(tS zNHkKtW8wP?Cr9$5nXm$eDxkIuHYubsZ{>$QnMkI9EHqk)!V!p@J`aOjjEh%KuJ>`a9xN-e zppeWEb@Imh=w2B^h9>JA@F`%=bYq$yKIRu)omD6}SXit&M%6HbgseW2QDk3usX5sVyBB@R(QR9!si z*e3HX>`Pg@MD|m*$@OXm-`ynd+7q)40;BkB!BukTGV8xQCLa27F9fgg!b32H59vUy zkWZlhqX_a)|MYFw6%AgTWgk+?yJ09j?L(bU$Mqg1*z3Xhf&clcQ z3Vut^`S9Xhsp+`~n>@m9JSFFHa?@wcS07W_XyUiRI6ixZ8ZmS#HGTT%co7rBZ=k`5)rGJ_9{u3k$d zHwZN2Vi3e~ne}M|DZUpnkp!GdE^tS6tv`d9N5-RB0Z``?&U|i^HSixz9@4AvMWQ*J z-##3sTSG!=mk%{mspnajjgzQ2nta~hb{i6T&hFotQrDt*OV9oA>Rriz&o3n&VG4*u z-~JJieIoNdQK*hn_BT{LGg!dK1aNr--ZspM;Y~xTb*@}ZokFMsVUAn|GwY$G1;4;n zmqJB8qNR!?(tp!p$PJ;K*uQB*xyARE4EZIkzvi~t&7f0fZ6F z0@DC{9bV|*st$^L3}kY%URSvYDjHC2dmDD8cA>6aB!!Ndh;}%>kLG_gh|N{E3PLoi zZxg&noxIEcHO)O2^k$6Bq#f$L-m=vlE;D%d3u9w`jGm&3XeThO;AP&7gf1u-?{{;^ z>qZHE`a&U6tR=4PA|oEO=Jcu9;6QwceRAE!(DRFvy!QXWk=uBlp18-$*;>eOlIFtft$T#Woh@ z2VZD6js-{lyy@U!u%E-agF4tApy~>^e1c#lD1Zh{*!d8HJsAWSa0#)Z2dYZ(CN+f& zjZ!KKR56M3wKzu6A=>_zX!@kmM%Gol0xr6S17FW&ox- zuaX7qi0r$xosqse8bL_C)Mr&yN|d$7ai-O6j5@0|z35ygH-763((=WEH)4dcSUO^7 z#@y@cnhUCiFh&F>@YX4q|Y1iIIj`K9s-~!YCqpSdoKiczxFjn;C=etA3rk$%^L};yx|0g*|@oUq@K;?{4z2C@Ue9YyP?2fI)Cj z5s1%G*QGhY6p&|{b2}$C>J=V*+n64&-7!J$^Ym)H(Xep!LQu0ipFCI9SvRp$@9Lqq zU(zp$@`HF?<<(<`$Z`rt4S|m1QPf$3Y2t~ND$rXwBzKzDJlzCpkS=Tf!-j#DU!q8k zE}xCMKjrspYo3}5o?F>+0C7mT$HEk-N}EM^*PTKRc~vbP`FLveHV-N`c}r`X@Px#x z*W~mcrWn@zq+wnbH6LJ-Ub0{htHw23E$rTfjjMpc-JZ-L0 zwv;vhb;B@AMHH#tE7ST9*-}88^V7}@wA=|u?FoFm0!jQ zPyjBM0e}$zYA*n1lT(ZlXvOLRo zDz-c{*os&S&PEhPrVSlft4-DxH>_8(6pEdNnLnq+B=6Omt=KCgH~lJmr95)YL==ekfpr7%H}lMTc$#<;iv; zn#B<76eZ0P)5gqF(sU7Rb=e#6=PzkxrLOpAFY|2KS$LpbKcuAe!XmpBG4$b~17EXI zLZ$1m9Mcp~em%Ud;lkpsh&s7Ae-q3>WhOO}Vj$Y!kwIL`j@9DNmiFfMFbLN#?4 z%Na`A2^9Mqij8PmwbYzVZt1SSu0@CzR<-^wEmH?D z$anPhhs})S(|5)@1)V);Ry*y@hRCJ(R&0C{1MUY=f!hOA7{CXxSY+zzmqe@Nfnaw{ zi~qQOwTkV|4T`t}u(-bPH`6!k$meH8Wb4OL*d=@4twQUF+Uc!0ylpGW-p zRxGAS@Ujh!z!kOlb}>(}B8OEX8NSjq_?gXLTKW!Pti|Y*hmDNL(|3%Wf~X|3 zYNdzNpT_6lE8w_%3yM$yhb(|OpPg`!QOerJiJ3#j4}7WC+Jsq8{KxjIjhOHJS0R01 zOVQxl=K3oJlFu7O2CWU4)v|P)iTrEm>?%cEKSlAoLhqV4pD`-}vv&R$OFS*&am*9a zC3d|g_E5gS4)ue&9DI3N89}K6YvdyHccrx9S7qW1G~sW>Cl{a^BS--|f71N>XoD<9 zVj2;5$B5WLam~`Eo%f5>{S__RCxvKjK(zF)uH$rTH~!{aQW&EeQ7kO9)PG}6Ry9Mi zRf1@+W!E?}xgvD7R1ud6iyI0BHFeFTPnpe5O%}?SC6)Y;V?nUhj0jsh9DDdZnkGFS zAR3Bo=WAg{Xn{jEoRNI(vV#_-tX;0zbI1#Qw2BNlrfm{S%SG~_2zV2o$&+10w2RYc z?t1P0PF=cigI7$&nHz@U{)2+~&guHAuWl#mm<&{bp(!vSlmjMe=4g7VLIW;(%t-tE z(?14fA8%LxlF5h7igmHV>?P5nf(wo*OWChxk_&Ei#10agNjc|Jl0)r0-I`W?dL0i7 z25(66j8P0GS2^Q>^0-XI2dD}K?*;A^~#d3u_%qVdUK?1aNAy6V86)V+23@F3xUcFy_3MWNYV zGb5?&*N8TBM3O6}1?G3u56aGzBDo$6>E0sw^l1sAoe51@ifL<{-M9A9sxWP54WIs- z)`DnwGcEq|uKNwdu-NJ@0Mq8gsI%0;JVX;odTF{kFjUqh&xe@S77AfIyo_kO|EBqx z#>_f-W0d!@)4jB;|AEHMzfs?twIcxfcdyH$K4IF)i7BqESLWo-{EqfM+H)vZU>eR^ zjv!@eoMH>fcXnUdOLOiQ<9TAxHZLXZaOG-Yn)PXN5W^kEW}w*LQ0zg&?<=$RL z&f*WaEF>sK4**u(s6}$+_=Z^27)dLUfBunEiuIi-H*Ve@N&QE+sM zHmN7wxcAB>IJCR!TgyDn;}edKFxiya@lZMb_T2P%0}EI?fB?VGiaf668RO)h{gDj=K^>P?`Xhl zX_V(_7@H3=@T-&BkeiB&WeeCNq}viB&3Q~3HW{obqOejy>hAKpH!KVMF1+9GGTUnp%IaBu&q6Pn&#?AA;aN~?JYcVy}x4Rn= z?YF|GcPDxUGgCClad2aPA5DR25dG&WMYC9dX$Q#P_$jOUXl_@=S`}?m(zqquPpbA` z{v^k7SU9#5!{1sTvQIwc?*NwO$%}vO49cA&NgDnYU85b!vHj+6CsF z7J~4(5EpP>Lb!#el>Io{SoT7YdQo|1H6c``w*>KF5&yNzdaBFK_ETj#7@*yG3hst|jG99YOzO#-vFtaZiMEMUs5pbc!seIFmqEDavFTGe+HB849Ulc?LDWJ=Gg%5|214yY7 zx*l8$dNiSt2Suo-_r?o^98nj724@cX^93jtd{rP+z|?sNb+Q-54mi<_QLce!-?=`B>F3Kct z56?_Z&6Tr@ED>$pxK`TZr}tGM2nv-v2vppR>h8CGwO`J}=w*xhTqm)s5xMe}u6Lh) zgkAdawrUu2CMdE-(}rFbO&FmnSj|otsq1CLa2-8_c>_A4azjlCL%m^x9Hq-!AUO$P z-q%-H=7ePDqm{BfG42*mk<7p~Fs;b-(~Z=~U&-Pon_JCjtx;xd!RvAt50o*Je(QNm zwINZQ1!Sq{`%f7Rl1XZJVp-mo9fF*RkCzEZ|GO(f&t8gFW{fR#w|s(R9{g1=_`^RP zsv^jl%pz+Pn_}p)IxM4BDr4sg-;WAQ8})efFzyYxqZBH{N*O9U*P;qvP2epMM++o3 zzCJ^=R}C8;?6WNTe*5H;XRkJHti6-JC@A~g)Hl;j{TJlSkpd>cQZ_=C45*+MITUq= zj;8x6foq@mKO_eO%P9FI*u}Fn^_gjwYlW(s!`PVkyTChD^$UM5rRCB>~S4j7#&|D8y z*?`a_Xb#8KmPVs8{(uKIs8m7$5aSPasHc!YfkLYJ94ZH8ZwQZc=O9io;v`xYy}y0( z>7o~3H_p9t0db0^K4P2thvc}BhG+;Rn0$8*F*l|pk^e$yfc|ERIQmH+Or(v-$wo0Y z+y9(0fbTgf(ndG=3e$Z^LVw3QV_rul$MGkU7t#wSY)lpPwE6PSRL<~j+ zC}}ER43kfvbV5lpE66cUNxsOpBt?j}{kb3l(Jo3d-zqMIBbul{RQoa&z6>R4L}M`{ z-=U-hK3i?QukjqB(ab%Rsph&deDX+)4VTd22cX!ArHQUJjgx8cNr+!;l*8;cABkH>2BRG=k29YCDCKwpKzJwyy}UM*(TwdhY62KCI|2} zJ5a&FKs_PQR{*@;gEVM6{o942Q1>BSuZ*C(NR+S4`epOrBZ)L>VemnbW5Vft~|lwJ8yboW7aI( z%=!JEF|U#1X$uVT`wW&44KS-2_-Jm5ZNOu)q5y-r7>e4uArL4aBU6q#dejZJppiLT z`8wmoPmDIgSY(}WR_CuO^3e&W);!$vP>a-LxOf44uG(2Hh#Jc;X1hD1_HJfMTLE<@ zk0igJU|uNlcc;ETG!DyHVN_5rLaa(gdD5s=W51D?WraaGr84(nOJ4u3xG|k89(aF)J}ebGB)K%9vsZt!_*@&Oj$Z1TKHR$nOsTx>x-ZZ z1}U$v-hZPzqje+yC`{b>@fhsc>>&8@eN9>7sbTfy6J9zI%45}yy3jwUC&WiIP-N$$ z{v}$XNs}Bxqz~!~F0`p+-PR_8zE$j!%}>#&Be%{}@zqK$SPiyE4%obaJ@?y1*lZiK`TpVQ^`L;)U=f}PBvzxiYF0Z^_6n)CJzGYO34f+okH z7)>lqQ5it9;`mk+0TrE)Q7;uKAQO$o9~DqVAPa#qd>TXCjc(&UhTpN4AKDJyFTSry z(8LUzmjsy*Z4v`)fsq4e=j+IVv%bJQ7Z~yB*t75XT*8M8b|p%*k|$YlLn05a;%T(0 z2yL|0g1*gqX2MHRuOq)dHuKdI6@)v4O5K{jo=kqQ`E zU|;LRtUWN%%JmtOxZewoN}qRI+?6OAJrzt1(fgV=EZ6p zC%Yb-{nf`3H_I=yJvf)Ioe|Vl(G8_3I&~!L+N2?f^|(jd%6IQ7p*C0Z;L7_nGu!sl zC5se_+^vkwK(Qm|k%NhB{=fY3w=x>Vp#xZh0wmeag#WSiU3D81n|bsrEC><#K@$2kbmeZ%g2*Q3gN_ z^|`97C>;yD)msOji3Gcrp)NtuA#Q?-ZpaSrlIK9>sdsdyDzxcE-qKx&g{urC8w_O?|Hy78 z^46c4_Q>cTSu&FGe*4>@;hz^Gs*=@5^5cmp?V0tc=Z$ z()og9xw?HaksNlP_HLT+x9mESx#4$eTRZO2Z>p!(b%*?ZDb@PuM?d}FT6L|SsYUpy zS+q+5ht0MVq8kW|@yCVu!?o7{6CrghT-x4%$zBBpm_dyFk z-D_TN`Xx-OSw8uO+L0Ad{BPDW?Mv%lM@0T)4Mi-{$R|yeW;|rDRpQ(^9DBqXhgl5Q zL>t7?ZO9b#2;}4BU9c-hDitHwW0WMhwC!cDjKZ=?Pp22%4oX>8udL{Qlf@tBC2Xo6 z^aroV&T8TPyJvxE8BW-+8^mFpFtOtId?;xtbiDh0=kl)~n|Gxvu*|Vgs}Rcocjsl@ zN>8r+n<*OX)3aXN5&+AJi1kb?^9)Ffryo6J40s?#u>%u#(&N4XFhy4>d#QT{%i71u zzr&kK*>0t*`ES{-22uQ9=VURacjrg1nJ|2z=64Uvo6fn9bsP2jJ0&Q979X%sT}uH9 zje`t}9yA?MZgV0J^!HCU*6UyYaUuJyqWN=A+%6i$!Gm88ti4SP@w}?%HJUBT6%v>a z>y-uIu1^@%229^8QS&voV$|iw42P+kVK*el7SP4$9v9?}hLF4abyhFM%ECSGE zY=6F|v7x5qqdwa+?ZMqYux!Rf4ohy(n2ltTw8r!$dU{(Wg5jv5>FUBVH<5Ro3us@TDbm7xex zQBhe%MF9(91v?hZ&;+pnift_f6uSaeR4}n)1v}PIR8)k3C;>t;@7@G=-T(i+w|n;N zS$FpwKYo69?)~n}EwCyR0IoBQWQ3~#$!L?zbx78@1Qtt3*8B=qxI8tZP#~IEM`L|D zRt2oH#$&T@SkX@RuNVm%~)Yo{W;SLZ+-b3YlLW4L@i3%DpIlc^V=yM zY?*eN`sY?1jd=-aN^-uW0E8c_5?DKYVL6!&^`3-*gL$S;0su-HAm_&){XmVd-O8Uw z9|?DNnT%*W+~SPsP0lnSO+wlbsj6y8qm&6Ly2E^agVHH&J0(Qa~rNs}%q?=wPI z*@TabK6T|~fo0i2qtKSEyRFO?u>eNE!jH#;6H^*awy8FNQRr16O|ETD3OVxjywkEn zo{cdfSx(L_RIQWsp2y)0KkQt>$sx^0D(hN@&6``ewPMfCqzP;nzb{>a8~5&9Hd|a5 zPg2?{C(r{K8 zo-TmXDlzj;d9jgcVZ?HE?bSAhTcnOuGu3MJ-7bL>Y-Qq*@>*-6qId6kSzuaraBS$F ztyWfMdN4MzAO8M?mC)1l!#w+eGqqc*MP8wF8UP<4EZ*<%+x||o5Xv*;$;2!DQC%YI~N?vk1z^N(IP}s%a5$;;^J2eX>Xbu ze~9a~G!OPa9iDo9|m6w_Qh5 ztwgjcd5ijQ+E2zfrk!?SNB1#C{Vzs0N89PUq?KHG^J#C`(9mhg29^$&tY-2lU;*c# z=vEUzMQH%b5uhHCE#RSb)nwnrUBQQ9(R~Af{7jcf`zDi)b34U*j9aF77UlbCKk51P z<+g@8Q4%*%lRsCS=P&Fy`@oINL&_gt-mX;2$pHy9KDJJMBZ`acM!O6CygWXxbC`eV zG}@qlmjb~|Qbcz+1Dw$Y0-;a6fabx_34oR)2zbe^CSGPz@s}9p6}sb2F3nYlm2aR- z!*Ik3rMRT72qi6j;5aCYs*e`xN2EPGc26stnv7Wc|`&IOn<;4 zfN(VEY%S5zT=Q zNb8h8)onT&a~skYB3iVLHb+N0f@o_Jy5&I{pO4%5qzU3W^#>TFWhHdt@gR-dvi7GK z(i$6?_fmx-=HoqW(lp|aO6C`Bz(YuLMKoU8L%qLfrvHV8&F@FUti`hg@6T`}g+4%= zwXw@SmewQMvN~oPq?H)&U?A;`#;xPr12?1!C8MJebkj{p6UvH&qpbwHd6YJ5Q)$et zo#t_daE7r>?R@J6ahGB21R$wN=xlvdNBg0Mw6lnos)!l!7p<|K<~I4_`9X_UMfMKO zPn&W<|Gw3ht=AWAGp_Nwz5h|h2o~()^;PJIBtWsvm4HPHV5d0tXu+X7FRM$Zl&5@L zTy$Mhy>vk8w$&!j8*EFRRKrQdNfC8BKY4d)%KACZBX6!$E{z(tZC=@cf8$QErgI?lPi{}JIy z(jf0N<~x_t3zgBLAKVO7OalRS&6AU6o|XV%E|S|XV@rc%DIdd&WWwsD{fxKGGx?)| zr0le?=Gk}h>vlgrzJ5-xk+++aOIH?cTU~acV91Y{f53hwi+=oHV4=rBI40u#k(VMn zhhS{@pm&|+NjL{(B#;ocg4v_FsFaQqOGiVP_MJx4zN;$Lkp*jYG`B%66Cf>LFy4y? zX(>9|P4Yj{3WRskucwWdq|6B)DT6udvt`?AK}H@K;Iv>cqJ6ldRFu8?s`+QeQ|V~xwK|&pHNJPjuw{*l1v$YdDDmE$1vADh ze6S-M*p@{0iG{NifOg5CQCZLeaDBEHI*|d8nZtVT8nGey^7sL-3kk(r$Eg{nXSVk} zzvj}H9)e;G`EGdM!jISY@zNDD4i-w|W>3wKT-@Hb+dHOQQd+W}#941=74&dD>zkfP zHdEs3Sqn5{{9#a{^TW@Uv=Ielyll#xphX1!8J*;AfWg_zs6;Q2MzPRsJB%_!TBBhI z71KeXRx|pou%BO3#E7MBs7@4K160AFb`n_DPRgM14tFB^U`AdT-vIa!XD9(}O$7vN z05F9^e`XgiJwCu-K{He<fKj__^bv};n_|(NBBt?2$dz_kZi7ztBS@-T zC2bS`Eql6H-~?rT+hz2Blm3{KNiovb01)0#<2gfs5;Q-*h(F4EnaqXqsbo>$4?*v9+=bvY-T;&jB-_%nZup zN4)g*L77pzOwKTCp)6k~EB{+YCDYRmFCG}v8B?0|it z6`=wI?xkH@qu(2S!UO1ZONtan9Z9~Q{{CUDkt8er{m;D04b$n26@Hg$b1Zz!j+4@L z;&W4W6mR<=9vPDQC@QTo$*uQ}uuTn%BEVR|Vv;hH4Zgr1Fx?=mrodXTC6Yg{j%H=N z_22e>Ahpg{f0#q7Gq73toWC#^&hf#TA9qi%9;Mv_Y z@=#V+iP6CXnv57m(FkP$jH*g0Ze*02A%DpnkW2_=d)I1> zXuJ4F4Nx{6WGwN{UnDW11l>qx9aH#b$9s9L_zRPYQkoQ#yJJO3OKq*iShG437|Qw# z;MeYj$jGPRZUfn>gG2DsT2H*{U#HHA=%J1Mm%@2oc$wK5UPJ@n=Dj-JusI5p^qX~c$5$5 z)1kc~O<-w;&x(%-9V*EoOgF-xy<^S+pfMaE7(rEBh*{(-@1+aobE;8%0Y|)@JM( zo1>TlY=yCxD!lE}i~UHY#rw=Nvo_VLnDSpVb!N7-sOm;;OYK||H%>m;EO0UDjI!oG z$#sJ3b%9;>PF^SXSv-9SS;`^r-X08j__X*K! zU+tkACp9;1Ry|&RvbX;SmjRbjombRc5HILTmKqm_&B~t8C%bfQN@7Zi$g;8Hxsjh5 zM&9Fx#u1ol09qj;0lY08mq+P2Q9NyIt`JbXSQy(h7bc1cVU%mDH=*yZuxb=*7_OX= zD#eWUaD3~YeW7a#@k}rhxjL7gP4T|#MLm{T7t?7kNEue_2>|ZS;SC40ehO^ldoqA; z6xsv=_>fk**+@(4wSia~&=1m9>>EHD_425)jERJ_r$nTd)>Lexe4{zp)Bl^x098r& zikc?ztiNf8%f#)pJ?*seI6g*}f?`O+-8XeyiD)7mm}CG#$Q#AOQ0(5!KuA;HiK*U* zXcyH?-2z5cqCBre``7+K^MtgGIvNH3BhBG40kd}K8sSXCtQ8*W%Kye2FvTdmf7Oea zSuW(+r<)<|aN}vsBSibw+h1KcfRQg2Lt124GQgOEv;h22=@Ljw=9xDp3rCh`dCDLS zKpKh-X{jC8M{VqVPxLGHDBiVy(qbV^t)sQ1{!Lpj_loV2%YhSYOe%ms>sIGwwC&xG zPv=JuHZ*#iRnrFNE4Yy0qvN}H1nL&iWsR6GATx+Lo~s>??SF7^nCfi9h5F4LS7)mg z=Q=!8u8-VpPG;=BSsrxj#Fmd&XQ(dL5BacJTyddOk9XW#-|Kr#%^<;r6GIN32#B(U zQTeP}0`I8lrGAg+NAcKOA19n30gtAE3>P{Edl3X*j{thHu>Fsu(J>dkG{cyS8O8(M zFJ1&k>n0T(!(bb{*v4R Go`+rxhbdfAv2z&Ss*i8uIOK7YdcNGTDgfK&MEzD|O8er>D8?;xT zFdAER2~)Kn!oJsNVb!}7Osi75x}9c&Xq^Ptfj^FD#&D@6NPvHIhQ{k5>$y4WE7p{2#BVM;ZTuMut2;OtESp`BrDK7I{& zM~x}jfTny%$f6nX);I9{fFU)@1L^!ZU7Ez>1zBsY-M{J)FEM0RuZG2_W@D z*3BwyD$Gl^$@qRCVzl9j)Lw7Br1}b`Oa0`)D00-Sp?=o}7N(`zKUj4j=DFdCeMbwI z$rnA6<|e;Rjw1gkq$K2BFNewNqBn=8{~0G(<`+6BbgmsGTe4+cBAl>b1e_IN4wCt7 zz%fT3v$b6z;OX;@0wC3BZ&By8$#=o3x2BcB(Lx&~Hkr{n;tD+UyvI%q8wnk*(D6sR zV^L3oR1#QILV*m<%B@{v0Wbo9#X;-3?I>O}`v+u=Ugs^-v6gCCTf6P^%H%zgc1fG? z46?*S=RVf4lv-Bi$+l%oq=L!)Ea(0ISgW_RC7Mz^PXfCJ>>LW$K$Z>q^w!QY<+TAL zDeU1j!x?$ojU>pb&@Fz2Jv^gSC|Um>nh6y!#^pcILWa&N9Z;B-j3>a1dBTkKKp87x zx)e_Uh_-I-V`X7p>hQOaCWo}s?X+h3TSNmAQqPMuIWz*&(jaXFqG6P5WU@;lNm+Y3 zn&@bWS{iEujBO8NuQB|8(HJ?KQI>qy((XKcVw0I)8S}E*Fji2QIfU0xv8Tha1v56h z*|JWdVgZ5BRSj^Sl`9&KThIl00JTTb-DLV>FqTaFo^{8s&T#6j#-6qZD(BwYGACz8 zN)SQ14>x2aW68>{!IdkSYhgE){Nc`@CuPL0c67a-N045POKl`367kb>-D|XN(B5 z+iiO(q({Py#F3wunE@N&a2Wuhdcm$dL7W}TmoQYL-Jm?vQv!?_wfr&c2s4`wmM{wO zdx&aZ^CiC;qBT8<>jh1Vp5Ng^Q{pevqz!MnERUYoUyJ54#R2q)pS&)Mxb8zt|h&r?8o{ z+%##-IrX8C)x%z8<+~iWd^`CG3l4yo8gK+cAq|9is4>E6G#@RDCh-CF>pf=2Nm5?v z859M3jRyGZR@sJU@1IX=>CoDP#Qin&yxDOD!iqhca-*F`;}hsO*}xfNpHKfX`gBin z(02po1urJ#a;N3XO*h;Uc+{_tc567A4^k}GO}YU`U_J&XNEWWbJlacm4gftNft%m} z=Yt3iAYkvOfxRN9L|!6R%SUU_iO@`)_Pxh0?V1O5o}Rl5vOaPqEyt4#A|9QB zin&h+&=-g;VFUQnT}TTY>ove&O*EkCG+-p?Hv!T(^}dLv-vVjTh_*Xh#tD4?e0)oX zW=LD7DL^#IHAo9awCk<1i|@xi5BVo;Fr*#+jkZ-sGvND8g0#WzdGrL~4@h%>Rmq z2-XEcTAQ-q7^L00QzEXF8)z7VJCMdiGK?brL_5v(pET|~E$tAenEmgxe)X4y+*Y6&qG>5G>}$rkS~L@Jbd|b zd_y9nIY&U69Z29r5Rf*6FGjS>h~|iBYu4fEacQ`bVBI7wE$^SSB!!mtQxSg*(Y}Oz z`euK3Ox?<9CpPmtF8kSRm3|O^GBdt*YuTINSp?t!+^P*087vCG+Ki&K#}308wIdBk z%dQqCAD#0^?{7v0Mc0RR!r7-+-mJZ<$$wr?IqV}XQ>JuyKH!YWpmRQb8|(ZHxE~h> zt9$QXXS&)^a&R9RRx#E`xErrqGwoio(a@;pKhx-Lov+)+f7$x%Hh_^WDUKC{U3Ykt2Y7mun>lGG5ezvKOkDOwB-(@J*@t?{G!sh4i&L2BZRzB7T?8ZMuPm}@9Q0mstQo!r%WydPkPuKup z?14TU6#IKnr~CehHdAIVybfcZdxb zJh46loNAFx`QG-`tcXGTl;KpF10P&CIHT7&6t@*EHV5P*4)|m`vzK4lnXjfV z{EwO~J}+%P)VJ=++(oQKpE2^$qQK_MOM7`=H=VZO`;DhmxWvdkch4P3UYrh=Zd#hDe6 zkYxnR4Wg4IPvB@+4mfsml7x1jY0pp)4JUw*_O;KZYfQ*M52kY2Juta}?4BLz-i1HKJ|!own=`eMB=9 z=0n;{NDEEEB=pT#i4ewy9mwehL{rKiK^h5ZnbAy$*h3Q{Px=SV9?^!FeT(l-0GG{E zsE*tI6O91nC~McZ-7|e5;+f4qe<1ph>DVD%3|VYMiwxAjtogk@quSY2QU_@a)6`g} zs;+fdglHS52~gJTV`HBYo47}}+Yw+*v53OxZvw8Egft^q%M-Se{C2@jau@S>r#tfl;dIdv}*` zVhu?<A=T>&=@Py>V%eX19R%kTis z)V2-d@B40CHr_t{`1%+Yuonfu;s*}z0-meWV~pVOM!9Ff*mj@-#Nmuu+QwMaG76>q zbuUJxWQtzGA|zAJ*lJgIKvlQ1Sx{x%WrCBdtEsid@>yx)>~*k(1P_IY{xc$lE>WUm#rKUrXJHj~K!1(@<=x|mSd6rj z&(89HE$)3hto&1J`GIfMQx+|azS}r#)8$9uv5MbeAzeJib7nwT4TLR0Ff|D(MQ}I< z_=GeoJ=flkF~Cb6ZFP`GMcH8$fJH)>3Vo2RRa7_0OMAh7L|mwBQ%Y0i8rxq9>vqS%R38u8y~?}S5MayAqgD2_kqY;e= z+C0s@3dXjJtpce!+FC|atGJ`1RqJS5f6RnWJE@xFKtn?EZO& zSTHJ>7^Q|`%NYe6tf6Ua!FHW#Br*+wrrizDWDQL?H2EI!_CW=ypdu7LSjoUp@_5p` z6kq~r<={Cs97VJQNb}nYX&9t^pp4)U?SW_(FDD}!to9XGS1Vza z4{5gTv~AP+LE1^)BY5G-SU>}?s~gqv}V~#|Jn-DulmMp zlr{G+p-YH_&9rge%lGq+Vge_kBP0-exOZ48s3ZS(>m#zCjM;^h1f2aOy92Tr;g z^l>fjGfH-=(`=I~U*0{a{bt|4*o2H73dd(X^-(j6%&|3N;eN2A)SEe|8WOEgiOEr(VG1 zMQ2S--u=8NV$FX~Tf^>_FfI>`02I&5VlbO)9X2MRoEG+{S#WA{P#?-BoC(UAh!bA4 zOg~I;;%J&blmU?mS(D{p31uq_JC&?G%PcN=*>CpCi?805LD{e}D0`Pt_?t{@yPo@- z%#a(BEJ89?xr8;F@$$(=Gkbpe`iE@Pk+W-3lh>|lm( zK)0II%&W|6xT74?agT*cHTp{oImKkm%rU{~%;BM<%&&f*8eY*HFKHRJt>e$*9&FKA zvi|g%E!$!X4^HXxbEi*5zOAij`COx!Ck}rde{<@^vm`6PhteKu<0@E)Z6LI75_x$P ze4xQO0dA5c%Hpe z__QNwyz`4-Xv`&{7`Zumxs~FG5Q#9Z z6|e%>j`K2%>{Vbjc%e^Y-+@|I)QxLBS?9KdgIM@Dp1|BH&&ziLT3KSYywr}@WCq)w zlwn#m45o%Oel^2fI)$z=SExKRI@*@)XNdMcdo-FQn$A9C>s^)-hlP{5< z!Xx)ZEuJ=|BI@Cl)>+5*J7@-NOB%L3ysF{Itv$QR*fiFW`zE_Ln;PA)zIL*r_1Og3 zVUg#%G;71sUSpjs1;8A3jKpYH04J5WCE$&BiwF7kFm~@-$vDH9qjL^XS14Y)UJYTn zbur8%IeNd?x(YQ%y^aZ5SdY{*bi!`$(2Rf=b?)BBAPfxXHk*V`Zx=W~(tQw(gL^## zj~%I~V*VDgf4F42i<+|8g&`#sdIyq8srw0hHs*lopzK8s@GE!QU%$eG+IC*nkk@tVmaoxXna^a zm5;upiXT2;S)kzy(P|m7YJCeV@pCmX(no5BmHNFeOc|rsIl=y)vfGc`y}NFNvi|=n zW5PQx9E_4y5yd|^*i(PR#goP6N&a2KtD1qGSpoT}Nhhm9vbo3QN=?g!J26P6RLC!p zv4ES6WUfedw5mB{f@}lNGlsS{q@DB~NkN+VTp1wl_d!YHSbDu3-*AL#I00je6^|T9 zCX#9Wr>t(e^pP00#?%HxBl{E|aN!cXPHQLa7~036bkf$ai$HjG?Pymw$lHbpp9)oIvjcP9j*zP#0KoQESR^?Gyl{F z2kwqz-Oao1BHv2qqJ$}35KN3GRFMcfbo0
+newshell window=CON:20/20/400/150/Scalos_Cli/close/wait diff --git a/scalos/Extras/PictIcon b/scalos/Extras/PictIcon new file mode 100755 index 0000000000000000000000000000000000000000..650778789af67123a4fcbc7f831e493ad42dd1ec GIT binary patch literal 43355 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 AyZ`_I literal 0 HcwPel00001 diff --git a/scalos/Extras/Quit.rexx b/scalos/Extras/Quit.rexx new file mode 100644 index 000000000..02f021060 --- /dev/null +++ b/scalos/Extras/Quit.rexx @@ -0,0 +1,54 @@ +/* Quit.rexx */ + +options results; +address command; + +selection = Request("Quit Scalos", "What would you like to do now?", "Quit|Reboot|Shutdown|Cancel") + +select + when selection = '1' then do + /* say "Quit" */ + address workbench 'menu invoke "WORKBENCH.QUIT"'; + end; + when selection = '2' then do + doReboot = Request("Reboot Machine", "Are you sure you want to reboot now?", "Reboot|Cancel") + /* say "Reboot" doReboot */ + if doReboot = '1' then do + /* say "Reboot now!" */ + address command "c:reboot" + end; + end; + when selection = '3' then do + doShutdown = Request("Shutdown Machine", "Are you sure you want to shutdown now?", "Shutdown|Cancel") + /* say "Shutdown" doShutdown */ + if doShutdown = '1' then do + /* say "Shutdown now!" */ + address command "c:shutdown" + end; + end; + otherwise do + say "Cancel" + end; +end + +exit; + + +Request : procedure +do + parse arg title, body, gadgets + + tmpfname = "t:xyzzy" + + /* say "title=" title */ + address command; + + 'requestchoice > ' tmpfname 'title "' title '" body "' body '" gadgets "' gadgets '"'; + + rc = open( 'tmpfile', tmpfname, 'R' ) + instring = readln( 'tmpfile' ) + rc = close( 'tmpfile' ) + + return instring; +end; + diff --git "a/scalos/Extras/Scalos_Comment/Catalogs/Fran\303\247ais/Scalos/Scalos_Comment.catalog" "b/scalos/Extras/Scalos_Comment/Catalogs/Fran\303\247ais/Scalos/Scalos_Comment.catalog" new file mode 100644 index 0000000000000000000000000000000000000000..a828ab251ec564a9f9abd3d18ebb7bff78df5a8f GIT binary patch literal 2244 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 literal 0 HcwPel00001 diff --git a/scalos/Extras/Scalos_Comment/Comment.module.mos b/scalos/Extras/Scalos_Comment/Comment.module.mos new file mode 100644 index 0000000000000000000000000000000000000000..cdd1ad334c49656e5af24f70adb73fa0cc9147e3 GIT binary patch literal 82368 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 literal 0 HcwPel00001 diff --git a/scalos/Extras/Scalos_GetHidden/catalogs/GetHidden.cd b/scalos/Extras/Scalos_GetHidden/catalogs/GetHidden.cd new file mode 100644 index 000000000..ccde3b3d5 --- /dev/null +++ b/scalos/Extras/Scalos_GetHidden/catalogs/GetHidden.cd @@ -0,0 +1,128 @@ +; GetHidden.cd +; version $VER: GetHidden.catalog 1.0 (26.05.09) +; codeset 0s +; language english +; +;#arrayopts static __far +; +; +MSGID_SEARCHING (//) +Please wait, searching hidden protection... +; +; +MSGID_REMOVEHIDDEN (//) +Remove hidden protection... +; +; +MSGID_ABORT (//) +Abort +; +; +MSGID_DIRS (//) +Dirs: +; +; +MSGID_FILES (//) +Files: +; +; +MSGID_TOTAL (//) +Total: +; +; +MSGID_NUMBERDIRS (//) +Number of dirs found. +; +; +MSGID_NUMBERFILES (//) +Number of files found. +; +; +MSGID_NUMBERTOTAL (//) +Total number of objects found. +; +; +MSGID_ANYHIDDENFOUND (//) +Any hidden protection bit found! +; +; +MSGID_USERABORTED (//) +Aborted by user! +; +; +MSGID_COMPLETED (//) +Completed! +; +; +MSGID_WAITHIDDENREMOVED (//) +Please wait, remove hidden protection... +; +; +MSGID_HIDDENREMOVED (//) +Hidden protection bit removed! +; +; +MSGID_SCALOSFAILED (//) +Can't open %s.%s +; +; +MSGID_ERRORMUIMASTER (//) +Can't open %s! +; +; +MSGID_ERRORICONLIB (//) +Can't open icon.library! +; +; +MSGID_ERRORAPP (//) +Can't create application! +; +; +MSGID_IOERRORFILE (//) +*** WARNING ***\n\ +%s\n\ +\tErrorCode: %ld - %s\n***************\n +; +; +MSGID_IOERRORFULLPATH (//) +*** WARNING ***\n\ +%s\n\ +\tErrorCode: %ld - %s\n***************\n +; +; +MSGID_TITLENAME (//) +Name +; +; +MSGID_TITLEPROTECT (//) +Protection +; +; +MSGID_TITLESISE (//) +Size +; +; +MSGID_TITLEDATE (//) +Date +; +; +MSGID_TITLETIME (//) +Time +; +; +MSGID_TITLEPATH (//) +Path +; +; +MSGID_MENUOPENDIR (//) +Open parent dir +; +; +MSGID_ARGNOFOUND (//) +Argument no found! +; +; +MSGID_ENTRYNAME (//) +** Entry name: +; +; diff --git a/scalos/Extras/Scalos_GetHidden/catalogs/deutsch/scalos/GetHidden.ct b/scalos/Extras/Scalos_GetHidden/catalogs/deutsch/scalos/GetHidden.ct new file mode 100644 index 000000000..9760f8f3c --- /dev/null +++ b/scalos/Extras/Scalos_GetHidden/catalogs/deutsch/scalos/GetHidden.ct @@ -0,0 +1,157 @@ +## version $VER: GetHidden.catalog 1.0 (26.05.09) +## codeset 0s +## language deutsch +; +; +++translateme+++ +MSGID_SEARCHING +Please wait, searching hidden protection... +; Please wait, searching hidden protection... +; +; +++translateme+++ +MSGID_REMOVEHIDDEN +Remove hidden protection... +; Remove hidden protection... +; +; +++translateme+++ +MSGID_ABORT +Abort +; Abort +; +; +++translateme+++ +MSGID_DIRS +Dirs: +; Dirs: +; +; +++translateme+++ +MSGID_FILES +Fichiers : +; Files: +; +; +++translateme+++ +MSGID_TOTAL +Total : +; Total: +; +; +++translateme+++ +MSGID_NUMBERDIRS +Number of dirs found. +; Number of dirs found. +; +; +++translateme+++ +MSGID_NUMBERFILES +Number of files found. +; Number of files found. +; +; +++translateme+++ +MSGID_NUMBERTOTAL +Total number of objects found. +; Total number of objects found. +; +; +++translateme+++ +MSGID_ANYHIDDENFOUND +Any hidden protection bit found! +; Any hidden protection bit found! +; +; +++translateme+++ +MSGID_USERABORTED +Aborted by user! +; Aborted by user! +; +; +++translateme+++ +MSGID_COMPLETED +Completed! +; Completed! +; +; +++translateme+++ +MSGID_WAITHIDDENREMOVED +Please wait, remove hidden protection... +; Please wait, remove hidden protection... +; +; +++translateme+++ +MSGID_HIDDENREMOVED +Hidden protection bit removed! +; Hidden protection bit removed! +; +; +++translateme+++ +MSGID_SCALOSFAILED +Can't open %s.%s +; Can't open %s.%s +; +; +++translateme+++ +MSGID_ERRORMUIMASTER +Can't open %s! +; Can't open %s! +; +; +++translateme+++ +MSGID_ERRORICONLIB +Can't open icon.library! +; Can't open icon.library! +; +; +++translateme+++ +MSGID_ERRORAPP +Can't create application! +; Can't create application! +; +; +++translateme+++ +MSGID_IOERRORFILE + *** WARNING ***\n\ +%s\n\ +\tErrorCode: %ld - %s\n***************\n +; *** WARNING ***\n\ +;%s\n\ +;\tErrorCode: %ld - %s\n***************\n +; +; +++translateme+++ +MSGID_IOERRORFULLPATH + *** WARNING ***\n\ +%s\n\ +\tErrorCode: %ld - %s\n***************\n +; *** WARNING ***\n\ +; %s\n\ +; %tErrorCode: %ld - %s\n***************\n +; +; +++translateme+++ +MSGID_TITLENAME +Name +; Name +; +; +++translateme+++ +MSGID_TITLEPROTECT +Protection +; Protection +; +; +++translateme+++ +MSGID_TITLESISE +Size +; Size +; +; +++translateme+++ +MSGID_TITLEDATE +Date +; Date +; +; +++translateme+++ +MSGID_TITLETIME +Time +; Time +; +; +++translateme+++ +MSGID_TITLEPATH +Path +; Path +; +; +++translateme+++ +MSGID_MENUOPENDIR +Open parent dir +; Open parent dir +; +; +++translateme+++ +MSGID_ARGNOFOUND +Argument no found! +; Argument no found! +; +; +++translateme+++ +MSGID_ENTRYNAME +** Entry name: +; ** Entry name: +; diff --git "a/scalos/Extras/Scalos_GetHidden/catalogs/fran\303\247ais/scalos/GetHidden.catalog" "b/scalos/Extras/Scalos_GetHidden/catalogs/fran\303\247ais/scalos/GetHidden.catalog" new file mode 100644 index 0000000000000000000000000000000000000000..9c260cd0adea35d8ad5cd7c11a094fccda279a1d GIT binary patch literal 1170 zcwVhj+iuf95MAhv2Fm@`7Nn^}WEz19NK_&(C`4&m5t1skc;BqI%}N`uHM_0^pTLhI zzwiyrdXtn&Excgq$e!6VGiPSj`@_)}#+H9{l74UhYj?yLi(b&X1wH8wRGP{x7Tj@d zPT_6bgqQF3;^zCf`C*r_etXa({`v{>>?c>2vCeTfArG*BJjcoCn5sUUnV*liQ!;b% zJJ?8RI5UNXT=QS<6=)79#Y7?jQfZ;o<&?M<1Q(Oig0v1~2Er6*<2d&Dt`X`Z=@d!? zEn%!2g+h+TN#T^qLhOvq*mc5MJIe|!(c4RejZv9PbcS+RXa(Lfp|-EYL`j@GSA1+@ zXhOlUN_ajn(=mFvfQu~P&=hB-oz+|;Y@hQ^=2`z_-5~7DIIb#@MvL|@reo`bxLt@M zyQ*EtA`Yc1XOXZ|#nlK~RqrL_oW>OuPHAPilLgK=H$AUorn&av!FP+W_m{n)bjX7c zTH(2t`Or6fZ=bGEihg(VN{rq1vpSsS##%L|eWnpLfC`~*4Ig31Z32!dr zkV37-q!*P0B}ipu;O5aq(^IR(t95h%lF-0jCweAx>HX03RCrNjZ z91aISR;_Mp>m8H&+7i)^xCM2c!fVo5Yg~N%YS@GSl*j*TOLUj~_ankeTL@``*2jd^ zge$FOWk2=j2b46JY}222CUUB>%HHxhhGBG;x<9|VC%lr(ZYE&R0&<9X)e QsU?yVMoA|~v#Wlf-vkdTfdBvi literal 0 HcwPel00001 diff --git "a/scalos/Extras/Scalos_GetHidden/catalogs/fran\303\247ais/scalos/GetHidden.ct" "b/scalos/Extras/Scalos_GetHidden/catalogs/fran\303\247ais/scalos/GetHidden.ct" new file mode 100644 index 000000000..0d37cc405 --- /dev/null +++ "b/scalos/Extras/Scalos_GetHidden/catalogs/fran\303\247ais/scalos/GetHidden.ct" @@ -0,0 +1,128 @@ +## version $VER: GetHidden.catalog 1.0 (26.05.09) +## codeset 0s +## language français +; +MSGID_SEARCHING +Patientez s'il vous plaît, la recherche des éléments cachés est en cours... +; Please wait, searching hidden protection... +; +MSGID_REMOVEHIDDEN +Retirer le bit de protection caché... +; Remove hidden protection... +; +MSGID_ABORT +Annuler +; Abort +; +MSGID_DIRS +Répertoires : +; Dirs: +; +MSGID_FILES +Fichiers : +; Files: +; +MSGID_TOTAL +Total : +; Total: +; +MSGID_NUMBERDIRS +Nombre de répertoire trouvés. +; Number of dirs found. +; +MSGID_NUMBERFILES +Nombre de fichiers trouvés. +; Number of files found. +; +MSGID_NUMBERTOTAL +Nombre total d'éléments trouvés. +; Total number of objects found. +; +MSGID_ANYHIDDENFOUND +Aucun bit de protection caché n'a été trouvé ! +; Any hidden protection bit found! +; +MSGID_USERABORTED +Annulé par l'utilisateur ! +; Aborted by user! +; +MSGID_COMPLETED +Complété ! +; Completed! +; +MSGID_WAITHIDDENREMOVED +Patientez s'il vous plaît, retrait de la protection... +; Please wait, remove hidden protection... +; +MSGID_HIDDENREMOVED +Bit de protection caché retiré ! +; Hidden protection bit removed! +; +MSGID_SCALOSFAILED +Impossible d'ouvrir %s.%s ! +; Can't open %s.%s +; +MSGID_ERRORMUIMASTER +Impossible d'ouvrir %s ! +; Can't open %s! +; +MSGID_ERRORICONLIB +Impossible d'ouvrir la librairie icon.library ! +; Can't open icon.library! +; +MSGID_ERRORAPP +La création de l'application a échouée ! +; Can't create application! +; +MSGID_IOERRORFILE +*** ATTENTION ***\n\ +%s\n\ +\tCode d'erreur : %ld - %s\n***************\n +; *** WARNING ***\n\ +;%s\n\ +;\tErrorCode: %ld - %s\n***************\n +; +MSGID_IOERRORFULLPATH +*** ATTENTION ***\n\ +%s\n\ +\tCode d'erreur : %ld - %s\n***************\n +; *** WARNING ***\n\ +; %s\n\ +; \tErrorCode: %ld - %s\n***************\n +; +MSGID_TITLENAME +Nom +; Name +; +MSGID_TITLEPROTECT +Acces +; Protection +; +MSGID_TITLESISE +Taille +; Size +; +MSGID_TITLEDATE +Date +; Date +; +MSGID_TITLETIME +Heure +; Time +; +MSGID_TITLEPATH +Chemin +; Path +; +MSGID_MENUOPENDIR +Ouvrir son répertoire +; Open parent dir +; +MSGID_ARGNOFOUND +Pas trouvé d'argument ! +; Argument no found! +; +MSGID_ENTRYNAME +** Nom de l'entrée : +; ** Entry name: +; diff --git a/scalos/Extras/Scalos_GetHidden/gethidden.68k b/scalos/Extras/Scalos_GetHidden/gethidden.68k new file mode 100644 index 0000000000000000000000000000000000000000..07e69ea6f9bdbceda8909b2e358391c8f271fc8d GIT binary patch literal 69860 zcwWrC4}4VBnKyp!%m9-=;)oF=1h|ZoA%Tzy5E0X$`3oUph$LX_qRE6zCV~8OGU1OR z4Tu;K1r-q~T54Ti-)?lNYg_HIEmGD}n{}h5%Gy*@%eJhIZMK`*6eIKdKIfb}_uk1| zw7<{ieLpXHbMBmb&U2pg{P~{eoO|xQjM@K(iGK=<{+s(IWA^`|wBoM12xAqmR;*#H z>~{)NTbWDEV9soQ=5A$9Pb*9IF0XhTIg?g?$hs@;sOX~7zWL0BBUzo#oIX}~fhDTW zI>ubgj;8EdOS5a4!^ixLRj>LZOV;Y5PO^{wx{|x8)Y=ne-DM}-Or3RNM|pP;1*rAH zeif9d4IEBCi>xCWXv5LLzBDBd?@<#=9Y<~Qcxqe%D8XxH)0u;)CZq4mLBknKdzC>RF=q6X}Cps%X+%^V2 zI47(A7#XEr`3eku94BY}AITX9LwQG5OQe70hjv!+(&t;Wo_!&`R5qcz==#4hlbvw7 z$vB+x=w@wU4z-;*-R;nEV(A5ziYuRbYH{!hdTb z!#;b_i;-b3abfqv2AAd6?DMfrO#E7&Te)vuL1fIwM2Srikze`_NlI7gsAv4!|xk5EtC)bb9kW!_S*FUd;>FQ!VVUEx>^xEOG7k&~67ww;&&)|I|AL#Q1(pLG4kx^*l zG17)IqHCkrBeWqb7pNewo3%hx$=A8Hbc?Iv+UF+(|HV`yL6nHCKlX?yBU&u%)vUhg zk;;84u4uNJ-suYl!nL<-EotuDxT=0bV0}0v)3>5{RfSqncuT3eZ1t*J)Z&#Z^3?Rs zM7BH-Ua`KtO_a+He7V}U6^Y8tsF~f;Tp#j>wwiroY+f0+ILLK&0a*)1m_izdqEeP6 z%6l1uM7_`mWC`np6$=}M#)jOr>MX9$SE1uXFVIq*#~gLcL}?V1AoUIgkK>XDP6!zd z08b0DU^z3BXIC&*(?e~N&fLhm_Md$TSxu3#tTv!O?3XN>JOq52sT_<;1-L}saqTyJ ziLq43C&@QVR4U_Au}NN@vgE~SqLLVwie2*ZxFs*iMk)oT;!<%)UiMn@;xbX$9+%1l z$;3K^^mrI_k{Vd-^X`Lk{m*nYgOP&f$l%`lx zx13!Y~G+LEUhBc&V8SyD=qJiTMdQ-_Jt zVM|IgBu{;oJcUh^;*S5k#7xQ4zgqIN#YAbMC8b%Cryp7Jw9QCq$#F|cs^sZ4OP;z- zltPx2W=o!|aeSAFQidfZx8&(XOP+d+l&=54lG3%3r@y!4X|IXW0ZU3A$&{wInk#vlW69GCCQ6T3Qko}uO19*w*F>qrl2Vr7NsU#K=M>>$?;MCnFLN{b{8y#;R7*!lF|*5rvsKeoikC2JOAY+@+40WS@Lw=NGazJmXy9CdAiw>ry&!i=PW7ZOP)$B zc^WoR`l=t`WLj&=e#VkgvEXUu+m<|;)|;}cEh&{q zp1yC%lWENgNuD0IRE=!)$Oq8-L zDV0f{Hdykc8dgL{P>)uRMM+k1P|adPKIYD1tbE69udjGLdjD}l`HRenG}V*eoxmLP ziuipvC#_}IG3E>@^9m!QUb-X4?{&<))#p@cMLzs?ALnPq>=n%6nGX(%n3GnaXBVKX zlh$rMweDKJcDsSrW#g{=4x!~KV&#`=@X`Zf9ak%lzO$Ky_~T@3(pene!|x2n6c46g z@8HPACHH!N*x%9~tgTv)q_cK;AY9hm&=6>2jq7W}TRQ?Q&=zcI?rdVBfG=7gTh?UL zTiny@(>tfPxmiWKdRvj|4+Xng18w0>wXwactzmW|E39wt3adKplJ?DQE$#jW)nDHp z3I`h0`mJhLXCO427S+SeZ9z4?Q_VGic5?QK#jYdV4Lm5I$q$CYO#!t9&3A@1`KWpGGa0qs)*cq7LYzh! z2e1Bme(vyD1xDRyr$vV}B<`5^#sdA#6 zCbb_Hd~&j&I#<1|aCOCsisdTKVX}z{+*yj-8v=Q1dV@NjZdlDV|4U@W{TG$Xop>?cJ+nCVJyHDwrw3>i8myLSltd-Q`@>)>!JMiMzx*a$&*-?%_^c78ewp8 zvLX0rE~k~p0San_%JEk?)#^*IZ|Y}ffO|CHYCP94(mX?zv;KnNxN*66n(U&aTBfgxoNKt?H}miyEBf8ahTf6c&TPzRrj$M zBS%}Avf4X8a)j^INai~oj>WU+WR)*b>+PIJ=$c!`1|Eg) zz|hK-8_G3`{S`i2dG~E6R-B-n7UerJhF6O6K6xK|Foj#k!+qKKY9vV(z{=D+Yb6(o3BwF>*eR%v%5qInPo%+M#&b-@M zv(L+5Gxq)+tGo3*H||e4z2m%|OW&6=`vB+YMZU)%ms-1iOzyon@C&kr6wE-F2X)em zn1kZ9^aAD-J1~BkQn^po^w8dk>whQrPCWM>YDSLFK~1q^;{A_#$x}gQds9Y#8_3SD z|ApMgk~GfNN97)lBHdnDzS&-V?Dl;gL8Y8Ax|hr)mn?Se(7AVFjVST2qEDah`b8fi z#^=z7WX|zx={K_!e)crZ()iiKI1~NZh_fty_Enr=*2vFSiC%tM{azo=;%XroGe>Xj z9EwYmct1-;4Et&B+kHN#TjV6TNmgS&@AFU(6MTs%yMYbsee~8+JbP^cT1enjz9J*x zUPQuDD!xRunT_amLE=UI+%-i6FJv55}$9<6V{K&3ri_nh*vdQ;6w1X}30(mK}4{^)bMV29~ z`#ndctnbb5F4}Wc+ZTo_VI9|m{xxr!xlF&pf8TA~_cklUeXv*7BrRn6lA<2EO+!TV zE=@x>+D{Or-Xk%rmt!u!&Z*2XP+6>7|BP29H@&jl3}4di`+UW^ugnY)MNv9oT@7(} zOnP(%)mVH%Sjk_K-y`Yu&M5-A7HIpR-b>*U5`4_ZxXEeG*j=-aBah^I#ydLl(r@Po zZ|4=U3(V*>&iDD1S2au_n_qlR*!*8o-zH3Xg?7sLoYeZe2X*uzk6Qfi!lVA8a!tPq zO*5hCcUw50#|0iQKJ80f^+(KAAqP(}d^%C^mG%~}qSlvK)$O4@lMA&ylWY0-iBHDmXFt(b!rD67bbHIn&U~t$dJf+_=zXcSHx$ruOcA!(Jmg-q&>k@yQz;yGO6$8?FGxxgiUOzbMNe`4Hs#=W>-+W9g$P7+TX z{}g7%KaTN4sYvH(`f;5n6=R{4z)oW?4N;C`{HQSwwF?Z?@6@SJd_?at*Th3o6HB-z zj_8^=Gh*A;NDJ3?M3JnrYu@>cq_ zUh>)lS|0b8TLnrRckxB~h4ph?{9&9f&PZLX6;w2-L%UDU6QCbNb!%4dF-;>tP?va;!+-omE4Rvj>p4p7Tp8tHCSSDtR?a~uhi_*DNJ}w z+Yy;ItmShp6zV&B)1DJCB#&m+Me&k6-VleS_KuHFrwwxc&Pw}E(>?t7FKNdoSw#PN zxv#j_(E1`n>s}FYqV2G$?a79=bIb^BU(IoNz(CRCb7JH$cu6Y7_AbfURHNr{3Tyce z*;KVPas;@T!Gwi5!wM|md>vD!sie8?wR{J%*ioLA;hyDFNKUuOUC2H~B?}OxW}WQj zyOQ7cIih-$d$n4y&L)cGT-F&++)vhzWTYo#tbt^_yTyXLmv)AcWkc~efV43;oP0!t@WE*fL9;j z(w&Hz(P$m}>`Z1YX5+P(gV*x-&$;!gxb#i>v(U4Sn6-&||}sC|7!7pCP~qXQ-jJqHOdDmnomt#CsOz zGFWa-nDMeULuuNpDB?Q)OpMn?zf}7bJDp5_I^&iVx0I^YTRQ^kQoc04s-n8IqI!Py z?Uki@(O)Y|E0$N6<*~~WX(4@iAiOXm(^pwoRkbir-5hET2Qr%5Xelhqo!;rrOk~ST zt7-MVth&0=w;(%bT(t#xYG*iv7OA}PV%(K^mflJK8HzQ~3i49EiC)ia?C^)i=Y~6x zm7m^uqdH&h41_iXLb6DBeMeq;r*BCP^RcFIxFgT!V|NBG1&ZRkdmDQ`&>Q(B>RTay#(pws!Gg%C6=CGpD(n?mbYB?QiR)@oy$pU-?aAl$qB2q$KtSY?NP2N(wgHy;U^c*kbl#|X@#GB-lv~`a*EDf zIH$3D`A1*8mUx9X&RU`t?U~mSwOp~52=AfiCq&fdW*+?Z%oWcPiBWv#PFco@JW*=a z&Td&Q*{8T|Vg=BvxMz9nqO>OicwnHw#{!DXoN|q%H(q3xG7S+}zWEs$7vtE<_faT@ zwbske^ZawvnwvlSL|F8@U+Q!GpYZ1oiBEMdOX2a8hk7qpqFyjZ!c-1(ffPwEl}9@s z1INeA98yJx9IEG;$8rTf2Ks$*>E}{CHIpq7{21u>$ECkS$|s-m zQ(X+NqbH{fdOkCL_R4)QNNZm4a%(189^Jz1KTEp_e~<3OVggwlRC&1+`6iz7ia0^ zlk>#$qKG|+vuc`Kdxcde#g}T*VL3Y))8^F6Z<2HB>i1~oK02pBn^T{v;PdBEDI1lZ zaxLG1*!)ISwBh7wzCclJUFARdsus=8s2>y`>e2t@`)edci`9<-IpZ$TO zc-f!GVrUJIekFwD3eq{*!bINcx#(O}!e8bGE;{>NMB-S4=n|Mds1Ygx(K1JHZI=;>_OzSMLjdS`6=gEb9zsvdP zJj<*xr$J-FM>3fjtFeU1y2dWs#8<0`gB-G|Wgp1Z&8D}BgQ3}=A^pKMyFi=oz1~~7 zPa>y_&nk!XS;A%f8D+joKp3`Nvw7lg*-zy9T=?f?^JlLu(AMW(|7ztv@>;hTgXc02 z{tC2A0$L6jQHo9mb@CpshCZuC5GA*8&G-xWHm-xWG>Mnn)8 z?|~ioo8hy0H7+)e=R)F4Tuia22`-dxi@9|pQ;x=!#V)>9c~)PmJOTfYBA-4248@M5 zG(VEM;d3OUS@aG7(iKwLi8K^D8=5qQxRRq7B(32!jcJf&CYNYttVC^i=weKnfR z(G&0(^B{kHoEwN8=d?&rdy>}JAElf6qy0(@)$pgMjk9LRZh+qvog(neFnh-w8u`!4 zkry)5MlJ(4XJfgc^?hlxPFjIQx`gJlZp_SmG0(S7Xajet@GD*S1F^c7K2DaG8Ebir z+rQKju0V_L7fu=*A`7&-*4VpM-)&yS-K{>JFOFIkr zDj=srYYTGkU+TD)&s(&dik3&TJILJr_xlp9?jTDKDl+hwA8RQhJ_D69J$i7wsYg$f zPSwb}1@gW*<73f~Hu`z_Dx#)GHY)Df(wc#L7QgTLF6qd;es$^fCeobI3dT=e`IfXU zzDo)-)lGRz4U<(jU8L27==Ig5RclsO)BL@q!H~VGGhE!-k(by`lY3Q6?=fZ9r}|vZ_TP5Qz>bdeyDWir0+j#V4@3fHb|4{G!3ymZ2K2MqTQuAKG<+OaI&2uma6Vx@;^Bn zlaqm(7&V7GA{AXI-DNK4DGRZM8IiG>qI^#@OnD0|nO= zMJ}p|6!~Vu%Dk$^QryV zcC1^8@|XPcKXM*jU%syD!+5#b=`2Rg(hIDJ-h$(8iJb5x(R*^-Me;g&jaER>ik90} z_BzpxS@CM9D`@qCoX^tt~f4qO4J&~dTftcfM3puq)nF%e+f6`J9zTlv&7hg zGOrgMa-&>Xq58V&6mk@t2x=5tD9VP_YrAa)_OakhZ$aVEMfUd3R97&?U7$YdPCB=u zYDbv4Pu}`dUMDMZBskff^muRN(8h^B?~NQm9^~zE`dyg?kt3PgXpJIrsP5g$ZVz+k z)0>6_SCKsML>%?470Be#lip&lv+BMq{{E3jziRg;2`Lv|U~}D056x%( zAg_J|o<=h14JF-;M>Ax#f5WlHhKEJ-bQ zO+(4N4HNMHeTY zEme1w?+)5Zy4?<7^A_@g5EEC5_KTd=d(?8TGsMEol?uL=Zzv(|Haa<{Idvab^<+4| z*AsjL$IK4QGm&4oA=`m6$wf>JvdByS`NBKhH9PA*P?fsf{Ob4W-bCu(cnW`m8-7^# zJpI}*5p}MwdlP?et2-6b>Vn`XwHo}BY>h=~@HbVqmlL#2cwM$uuzF|RIkdzgX;G|k zzWqn$a9uMcH8|~M);Q`Z^RAdOJvi~@X^lg{PdSq8M9(7sm!Ks|TPx1Gj4a49_ zy`mrzsr#*(K>D3d`c275%=WR=Z7hFoWNcs$+0G{AyKe;3+><jcW2- zmIxd?*TJgxxD!+0?T_tJOBNJHE<(O%E4r%obbvC+U3kdFx12!cpsR!Y23|xt8iq#w z_98q6=U>iW$VdLOhpQfR!jw^go`ao|s3l_LpMt&r6aZJ4& z94SHDnq8~@QpP-&(5to`9JN5h@3bh#N>Z+ zwoTsXl4Hal`1qg*9WZvqD?mh;@Vz)3M>yuKiJTH|5#uYxDSU_OV8vbY$|C)AS5J#@ zD!(o6@KWqk@dB=%MTG3~6y(ljDP<>Lrr2~MW^{Wnww?7*RF9|@9-|;mX^jks$ma8E zey3Ed;!x>zG{^K5U^eOK-$ARZV$QA>RP5*P@j91T7%9^zW)?*X)Z~dYV?4{}v;&f} zR6gS#MA>Z=Yw`9dE_#2Sc=Oa*%>A5}{0!^-C^Y9C1}dFE{wX(Nc+|z*?VX*p?-Fys z(}+I%N$aGbU?LIF9^&S~zQj1@uSOC52 znNY112Z{!TWKFjiYKfgZN@_L`N@l%BH^88Jl zKS%Xee`5{3qi`FHy=bBm(z&8g10eVg+9P+ny zMuTAEm3qIP9}M|Bnwr<^8O?3su4aB;P0ML$?=;5J5u0KI4sElVbJjnbY2Hmgf@7%g zlSnteTiqb;T7BbQv6>w-ryG{umP~t`{Op3KhR@%=vGEJ{5hwFIJM6E2k~Qv(dsl2E zO5e^)pOU33;+7thv|YT+e4i6F9+Nd@e!*Qg_GkX|`z;rK+8e#&rp->xcigmGe#Z^7 zMUPnT-*bW5>wTW*sUmOx9-j9Y&r1_|j~(E7+j(B9$UBh6^EU9j6p{Bt56@f6^IRhD z!9ku^#Pj6ycn3G|yzENR&k3|f$yhlgwNBe_&PH~N-Rt7riO-DD?jc!Pn`g8C8KKpu z!lA$HccYKdox}&scWU@fVp z=X;oqc_>*z9;U5aKl3JExfU8(L3@vp_d}fNE7$B#^nThDe&r?N@WKG^(bLzKBU0ow zahAgKd^k(vXR~m|cS=6}dz@uOYvlS81ZE5ScyTdCdFm5-%v-$7XNQ~)&>fF-TA58W z?i}YOOT@nQrw2)f7Y9S)x@`Vhpk}cW(IbvW5qV4$_sNZ`poLTUnl;frCweljhh^fq0=;@FfwdgX21rUpnIWWz4e$+!w0F^A`UM`An1(^vNPqW7nuj3k5~c zg35bx)Ve1I4WEW)74p5m9yi&$D~`R#^U7rDzcIYK1@8&b^O>+KiEofhnprY}_nUST z@7z+3jJF_<^f-guN1}2+Z<2e;|53TC@#KEvn^C#}{U72y!hww-bZ%a|k74 zp3p%%yHIwexh!&fqVWqKWB=PxLnHStpS^hKvs_OW>ygjDu;)CL@=EE@XVvg?dfFy= z`4Brm&q4VTQNqSc>?d#fYzxM$9vZU>Q9>Y(pM7hPm#8Kke0GGW&nD`K4!-pUzf#8A zJx^TRS!CbVp^eUtkXMDQ-w6sVBe8 z^;bZ-L-pusf#i~b-Y$AyFGs-?@XPPvKW)bu-5D8yOkJ5b)4M9Wi;jNHXZI=Sc_rUX z&`;9jv%64vFRKjF7HUuxTu@mtf_;nb8YQE|mLPLfixSI+#vG7OH(H_l$L!e?mHVKR zZPELp$sv|m$hOom`$c}2azZ1sHK1;dpguYv;yrl}B*%OY1eV609i>*om_4%ts3-4o z&#mKHrn}_%Pv6RFHAy|o?_&rZMrFvkfA*NXGETbB9^`kAve+r@J}L_vXs?V?Xpge+!vQ7-~EZXZ(qz+y0gW;Ii~4- z(q8`euqXwotB`t!CiQQYYt##e#;SsBk=e&%ZS?_df_rAe%%DdYIYK+tGH~8*nSlSlY zU$@+iLt5$9W{Q~0pR8k_y&zXOw0Da?Z@Pon%j7x*ahj#?Wbb9eGJn{3M-lmBGJh;4 ze?;bw#N@}{3E#^yXbnPGk@lAS{Ez5K1K58CAuIQrX_a+QP_xqH4i1sD#9e-n^KBxUHf2!R?v6@rd!ztQ9G2g&#K`ghz zN`6~bxz9wy#c3?#H0X|2zJaTfSgs@uhnYrRpV)N~yTgF*uqUKh%RP;wCOgGZ zqA)Lo{wi6p@aMRNZ{YM3HQPS-7$5EG#GL=gNt*M+(w~by0mshSxV*F2Q60nZtB$T6 znJIm#PPdA@VeWgXxrQp@GvN5wKc+hHq!;*ZidcSZoS$_u{Jfy^^P7<5=ZJ})b#(3P zk4S#j8ThG-@^d6EKVPLf#&;s|wfIr~cA@9^*#Cl#7VdA?h$nPL2{ZVc6-HYbdtTGR zSQ)KM%CT!i8@mo;>~y!nllX2FKl^AZ?Ix+#-WBKOii% zlu2}-mY;q2zI;-f%VO{yD_MM~#d>|>*&0YPC3zWQ=*X5hptP@>BDupoIcc^ zejMYP?$ctv4|oiteW?YS^pui3r;IcKAE&QJ)Ozis9T7tCC zkN=8`r5mVq_RK zZX~`b7BX@!uutPw@An6*iGE5K-VTd6Iw?WpzX`IB?}u$Smuu5qV&JP1$kujoe7cWJ6JqkX{`e&JzU2w zz5;K^F~r3!v2n5R`(M3J&#J=z&+<7z8Y16@c{fK!$WEiEbQ0SkRgb?V@xUMfW!$=xkifuMA%PFy74o0-MpS$FW$%!=$D*-4wOAlpeChIN zi`uu?(qgXiHXgrGV(7S8#N*uld32C#h#iJ`>@ebuGkbsRPm$uCo6K z5z<%h&}ND6H;LytMqW2HR`GQmyJ7nNg?4V_j^7S8B(lG31OZiTEin=3Wxa*tZ zjqbH|e!!#NxrUrRq0I>&>3Q~gnfI39NcS;OM#J))IvNfBQl?p&usg)dIkE9F<}Eov zrc9+Zh3H%&EuQut^{%p53wV^j#|V`6Qe5U|Bh__c9%_(@LHnNZt3~_Yj6<8Zx}UHA zc!;~5lDj2lyYT2UjEvYB2I_Z6ThH}ctzKot;U`bCv2nICb)4moTG-->Dm|14QyQNM?taN(u1lK8l zcOJ%-Q(DaPH|tnR)#fmaggfU&zk)Vi@BGal-?O-SAa>PHd_~R03}eoDi?@l?3!2m$ z8j*@A<6gJ5enB7+0JWZ+$*0^Bc!YSw4Z{ zrda&Az?mYk10~-390zcmE&L>Mn(s_W;PLtiZ6-zeT6_eZCI~e7xmd@LX!Fh%eXjZQ zP@LyA*gI1$G47s`-ap;7KtnUCmGAo6Wd6uWw~Rj8x|a>??2G3 zxBnGwM~~5Z|GoMW*4rm!6UTb{%lW%n94~Y0?Hgyk{oHzAmDc;Ju-^V~Tl1xZpKy+|S@Ma# zs82Y?*(~`)U(_dTaeYGPUm5Qc%Sqo!nmu{7Hxn7{`@F%*Vc8PPv$;*r*S>t4{1IP+ z>f_kjui3%Bt>jTq3-ZOARM@|5uZjO%;k+P4Kw>S4W|lAcoZ6FXo?IDA^XAg!J$3c4fxfph; zCd?MG=fLbj{#@Upo}E|$AKipYIdh|FV-`E++o?9qz$)5$G+ zKJ!HHs=M`aM;_6AV0Mm_>`cS;y@u<2Rh6E>jLs{Kl=kQ))!$y4lFFZzr>8ihb3h}d z9z)3^UqES_>|JWS-aT`{P;&JbP+BN^m%?|kxGhR0$Dy)Yzdmb7_RPh1=UPyi^+p^j zyA0Q#m%S2i&$FV^9f!(J!}U7ZBj=@hG%GI-m2SiJnD=6Re(KA`u0`^Fx4wA2Dk}%5my+ob?~VM|E!O=svUYQlmTJ zrzgWQHa#mb*D5w0p!#ZtWo$Y~^*wVfW7Bg~-<@F@o1WMDWD%PVnfMtT&qO`n zqj7_=!XTj;h<`k@4s`RczGI}1dZml-o$uHvkayz;qP|b>B^;rZ5vEd{N6+9y+i{`f z2;V{Lk~Gh8pCC*gsoWuHofrG;iB3(oq%kCRqf!0powDw*UUxOG8+T0L*2^1i5ZDHaH7Nj!n-Ekv5 zbv}PD$+YyafwK8m?AxQl7TbTD$)~uL!@_zo_?UWcw>Ba(v!_9#d!sco^KmL zK4ArY*~z6+oL3;@JnjL-Lu0R8OK~25Z_CyO9?KabwA2&Yo1CIKFKO|f?vY=({w#NG z7~UeuP8_rJmy_0Om2yq%h}XQ5mCdn{@v(t_`8WE;I`(=+bhg1)6|}1{vtI7o5?Q$A z{HRYN<%l)*T>Y#j9lb=I*v-|i;fkcT-Ha@zJwm)(ygfn&366?=0<_N{xx2gQ^2xBk zCc^jSWg51Xeu7eoW(s;9_xQ%x-#VVqeSZxJBazKtMGXHAA0=lBB=Q>G8A>HK@tq<@ z{s<{G9!Xd30=geQ5AzH@T22JVr%bzGJ+Rw8y5kCrNum3*eE$ZYBeUoDy8eDY8yNPp z-|zNn`%+IC_N5XRFB^8I_8WGlj>+9UROXQ{xi>YI2ermfuaQNz)bZV3MjfKnL0aXf z*%jXpKTL9s95!ffkV}TgkW`Y7)bAL^$x8D$>1pNrwV7dme6@LJCJ-w5TC``l`%n|} zYynDe|JUzSuQT7L^`Zpr*Eh6M7q=Ccp_PWXt)$d3N0GK0h;v`a-wxzRr?&%TFeg&F zM)}F~Of*s#?RQBht!r{h_GQJ0?(@Bxu|V_RmM;NOL-R%@MuUZ5V~bHD~l%gS>V&dM!D6txR4!6TRk&Udxi# z`l8pOJBa?-C9e(2QSV3M86H3T0l$ZDcsqNBDCHCTi1<0`r_fG-H9P4J1Lx0W7(wrm zZ;E3-qE#7skISG&FG$Y^i;}v0_r~rk7Cio-MVAR50XJ#m;}1_sy63cAN;+MGX7-QU zc_8Sf=yJg?zHdkC*AMdbFZuA?(>&K3lRLn3T`{?5DfhJtF}Y`W?m1Jg*vZabdn+b) zi08fTWT=$@IAJkG)x zqQ_aUF=?N@`h2ID>Lf_|G4p(q7LV!WTff0&sumaXF)?2s6P0&FDdS$p?~jTde#RPz zMaKxU#STCDZaNJaFp^yURS`=VXgN5oUfRV$-_(jj%^}{%C-*fv^tU=*o@}P(p*OO@ zQ@?*Fc`beMDh@T;t>^S4ew{2>>1Zj8kyPmHeI5hDSTI=*3T5ZpO?K$)X2(X-)k=3wj884 zSc;HHgjO}(ez)J;XJbv$7>{FRO`$zs*>~4nf>&1zuP)9j*Uxu7m*h1ihSwC%E7!#g zacDJO>z8x0ejIP|8g@gC@gBrpdq&oH2FD>@!(phA9IcTYtq(P&z$G2Y(UYff3iX^vTq^9Ua4z*^@O!Y2yE&R0*NwkMK}2~9=r1cm2l z->KNMNq$E2ZgUxV-5I^^jC(yfdObPrbyxJdEAI7_==Buyb-jn5t+d_`T=>b@F8%zo zO6?pYN-o)!{V?A%xYs*=hag6h4gE5*h~4`|*Iv=Fs&MFY`8}--DSUQvL?4;7r+E2Q zEh;=}alKAn@3pvIz+*Xqn|!6L6n#S(tRJglLgeCd2GiW z+S`n2CKUZb4F6K)ZdxJH_CkMFDef90<#&x=zH$7z@^ZSGBvxRAofyhb9={)FIW(cY zW&6lK@ON2=_(P8B-{rwD9kI0UNZX6cSEEX3^{N!S^KXqA=V)0mQEq{8RqGh-V@)x)tkLCdZxU?} zJX85%WLP{Aa4b@W{+)B3JQpQCwgZ@-&%MD%-ZGXC( zuF%uCUb(}ERmRzaSt-{udjzHE)4N28?|`HyM54I7*lV?y(Xazj?qwtjZMqkg4t*}a ziP`v;agPxnwMiF?=}iouZ=<)YihG$X4Rik#@h!+BS@bOa=P91~ER~+mMyZr*c@)c^ zmrkQMr6QldSK~+uy;lQ#r(VmS7C^~DmJhE`QKAI-X~*9RP(G&9( z#u$#DzMga3OZO}#$0~75_X}t9h?=Dm6}nf4{4BcLhWuQ*UxxgAy5oiXl6b9n)|Rf$ z(?4piF37$?&B$4ty~Rn?DQWn?G+< ztD6F<_}IEy9q_lR^VMazwAmjD;IwLUb9jA|+TPfxy2S^9-G(m$cV?pqef^k!3mZk7 z^3;sd;u4%7iXKA1Dp9T`a%o6<}|%iyhWA1XWp!x zXgTSf`X9D9Z{b4vvzV2zQg$0#jp;-co6pMVwW%xqjxOI3Jzb2`MVve^4-_g3tIGf# zoY3?|EWM?He|nuhNp0$rN9 zTEkao{_irczXi9oy`ifmFz!P)g{{p&|Ej92#Y=9M@8rED(AL!)4z%*i^doxG84fiI zP2I|tvs+l9)EFvRDJ}Nhx%$WB`RB;H!p$ws;jP+bbvBF1Va5-e$N4HxCznk0C%wl} zb@BH(I@Nz<4tj?ff1jg#)2O%D{LaKpY;i{9qV_)8$L@Rk$Ksu|xh$AE{!OxHis@al z-XwaHEMvxZMrv;={moHv9-PVFAFI9pb&7cZYw^%UdVlVt?w*RSTYHL!B17&gf>S*! z+=btHy>WyhbgnbFh$G3xjlN#ZYZb7^fLWd zcTsNx|K+6f;a~Cd20B0fOZ|MI$XDq6M^{DZO)%1V^suRoq&RIP(D~ax5qaL<>S+vr zlZ=>(+e=K&q%Tn`!JI=<(%RHZ=sHUMp-5l4T%`6Z`PGSf zi+b6kzY(dyPE7V`$k!!eqOi7Aq@x30`nri*Y2|i{vIcJG*=DmfRc#bkHBMtVHu3R& z$GGdU8vQafZ6dX?|EFqjj2M}!OVU{8Qc{U?{W7cTUqIJ{6GnWwrEo^zr zv}Tz|yZ>G9n*n#OGSd57ap$_9iFEaUi1hy_4mmB$aw$K&+mvT0Z9uJfCBGQoCd5*F z_H}h^#e)kL7^%Ltk$zEbZ0T#(d|_$cTK}K*5>MaC!bV>3d#m-;?xJ^QT(a&x@>kT$ zsLuA=b>uSD-bBA3_KRP1{Y!91(ybDBhcsEH*XVxF%Xb(k-EE+Kjm|Z$)C>FRZIHjq z#qWK;k-uwXS}D`dWO}PiSIe|Y)FTvE$Okb7hainQnGKsRi)5ziarg53)^nnA1DW_k{VJR}_3~HsCa?Xy+8Hnbz z$(%vtbnu)lGUq&Uw$XPH=vx^u%OR+Wzw?)|HQ=!Nc^p5$@fMDcaD0mVnT%E4iDMUI z>)%28GJ?l!q~~yb3Xa7%N>C0GUGr7O)`I43UdHN18S_^ouM)?rjD4*FDeA0s;mF5P zj-v(#xLu33wxONfPMo7ne+V>C?zS`>sCQcq^1z=TeB73Y1MS^*1P6F&r82)o?9t8G z?da6)^*A~h`|30t89319-yKDn5tLbm;}OQb?m&t@*Q~~I7{@vs&oS0gz*rb-o1peL+IZ&@P04k zy!!*j9#CZWk-;d*c$k~GfGX2^C9QfUh^8CYM(CgRG@2|ar;{x)~ z*Y4eDAMHNkW^5n&c<2qr4x=B3LGLi+dnqV>hBNH*Ug#{x3z@rI5=~@Rk2P)bGb} z9OvNSM#y*R3ykH#=9WOFOZMUbwk&{*a!%kVVk{eFv!VBFI)}dJqpj>F#)OKuT88RLE*7{9`KQF%>*s1zBGO9bW~#r@+TjpsN(fDFwE4CFFZ0{QFAy z))d(N6yU%V*yI$*;tJ^T3fSlsxs16W3m5e0f(%{g*X1X109!5x9!!QTC&QN}SJD>- z>1%>G;K!FiC&|!7GVC!Kwwg=>3v`kM8%l!RB|;~OkU=7BEdg>&c$L0bhy%XmgdCh` z&k0;f1J7yTISo9gf#>Pqc{+HW4xXoh=V{=18hD-tp05GV*MR41z;h~iP6drr@Jt`r zxEefP4W6$C&r`wkRPa0%JWmDBSAplN(Dqf}IR!kYfaetOoI(Q|c)k)mUkRS4fafXT zc?x*G0={$w^n3+;>GJGo;*pdW)NrG)80Y8%x>6?)_;4_J^jRf>30re7qQwflR6YV)+-%jX! z0(4HFRGIJ?4z%L{Rym-52RdLsEpXoc-v~d(R+bbkXY>d!Dr!qyt?iw8!9Z9nTlsKC zUyI5PP$djawlI}N+D!^X3Yn5JZIBDQ3@PlA!H(^)QFb}fazWn?pJ7+fTR2FFNU0w2 z1G%uPz#Dv*K{gKPj$MruvSR3$W1IWC@1c%kx8xNz%n~hmrDdu1`VE2gVZkxy*>Onl z=r}5Pa-0^tIG{fUJ8^s@c$(l4JWX&5o+gwDUM7SDFB7_vUV{|&$EG7aCis~EeX?0d zVJmDly^{jzwMc=N4E{I)w!zY&6O4y!4pNd0j)~9}n@1B~q_D$@&=FgJl-h&-C&I27 zYKm+*2 zfIpK?AiW1E$?9IDz+?tnnnW_Y4=ME#{5hdB_8?M{*+WR-uWTPu@Xx@v6F$ZsMGEX< zu*U?F@#9FzF5p)Q)VC*)zKaximI&WrPa>s0KyQg8>!*;y?-_hFsQ~HM>HSPdfsIMP zGxjvPOLhTYNhTS711T_%9YsoU=r`&6qDY^mFP0+x7E)j&dye*dApLu!z)lA2m<-%u z{|jaUOl25%E(gA{|BV#9G4kO-r2hbuCLMw|7x}}BNU47>!K~mL>>rT=vl-z5cx2x} z3Jhc5X$pLo{S#8im_gQ4fcNaXFh9~EVGG&9_mP5E241ct8v-7sK=15dkai^qh8^KUfiK>9XP@@HVqHDoV8M+(el(8VTi&eef=lKM6xH?`3(30gDhqM zPZ@B22DO7e&LF%1zRn14wyQj9}{Bk5!V@T+u^A@C%fbP9X*k}UvFyrd(@)k}Q`u6W6Y zGm&D9VDph;Y$9Col1yQDUg8h;K&@Zi8ZKt6zOe93D0gvO1AfRfGQfS zA?LXm4_PfzYS)jH+Fg&7>cNiY5}ig4X$WSKQaiAdc^GrqMx-Q{R;0iYnw`ue--bQR zBijPzWs!|Se_4cc=tCCy_GWa2y-U z_GXhDfD_roAFwH#Z1rKJL>IEjCR_$q`Ct!(RX(yo*sTxaEn$-neIab}k^JEQKB@<7 z@{t}6(JQGK$EF-=7ub|TJ_u~eA=`t_bI1pPO*zyquqlTy2iTNDJ_eo^P`kjU1!UvU z^#bZ2uxSC=G_Yv_$ro6(0JI5<77*?Oix!Z)fJF<*cYs9;2|FOmg>{T$&_eP7V9-Ls zUdVDGVj#krg(P2K%|aS;fi(+h%m&shBrE~eEF}HCh7@rJ`vEr*#{L;8Vj{wzMPvuS zphfTx!k|Se;~2Dvu>J&6j75Y&i^zU~L5oP=z@SB>FJRCj;tLqGi1ZKaSwvWjwiiLx zgf)wfGLAKi2!nw!i-;d!%OdzYVM;FP`8|4B5#tz=OZEks=8`?aM{)^se}$Cn8d#D` z{U1b1egHhlB|Re6%SB%ZTXIRCzr)aq_>G~@*AW)}7gFNy_eg1sfe&0qa{2@*`os{g zEhg-Qzc2PkjG!^XA|`2XYiVu^h}*APNJ4d&5DvnwmyoZ)*O!pYVNW*@p2Np)Ae(?s z-$1;=r*9x%gk$BA4&d8)gzG+}EsXng9$^d=mPg|qVui0zefaiQ$d(Wre1&lQEBK%2 zEk#Q7Zo(Xk##_iQpKP`mDbayE^2x?Zk+zle7>#&oX$QGKBl1_jTH<7QPjhm=E z?52Qp4}UJGV;l<#XgtOkT0ph}EGQuP!OjZ_8-dw{JMdV}9dolSYFr%1k39>6D+khPvlT8CNipiD{#}t!o0V7JNU0_2A zVIAzOgyadCl#mSp6H2Imz=9IOHef*s#$dvL60&h%KncY+@cB~0Si~cx)Gp$YQj#-# zzm)ick1r$N1C3>bQQx62|1$2|%erTuf2fDPfGcd$Mjw+)upGCz>0MwH~7vv zih&WA+(CW;-Q7W$fNOV9ePGBP6sG_??jZXIcH9A(5_a4{V-M=yL4E*VzmxQh@%YXx zE)I4l>_P#)-ibabh>Pz8?+S46PUu0IgcLeaFmB%oY)}%A_KUdU&W}Z0QR@(KMJ@ED zfcM%g5nt58-WABQ7Wz{VE7THQ%spzmk;3uX5_RB7fe+V#rh=HF4w$0gsDqy>h$-se2MX||4)RcdFLm%)1+haN>{tPg z)m`pI8=|gO#v_UBv0T^J+%w`si(NC5GnjwDWb26Aq5WAWBgIj zRz2|n9I7X|LU!w6KML%7J!GJuPwT0Fz^C=ZS2U92a4A_iKIu|`?TO_wQ%g&IhY@Wlr3robN>$S&Xy4b%?WXdwRK z3k}3S{GkCpuhb!>I1_zsfc-1*hX&x70=sV@Il}H6NN%vr0CcV(HVROGfaL)dDf}P+ z9VqaHKmntdu(AMXD!_sOa7DQbDR4(Y%oIS3p>!gJzbf#X0Lcw8Q-JIdeGX86w$heg zq`=EYvJcGb8et0xXf+aj_*o;_2XxX%{ktD2`mCUDjp&;Kd~5`73hBt5|f z8sX;(aI%s52bl)p0}5iSAZ$_rk3rzPg85&N>>s=a$u5DLLBt9Qa56~kBZdl+UqE(2 z>L+YJNcM?XDF_)TN0Fj!1-c3XM-|{>kmLsz>K|gDCZdPfr-|fqac=PqJI7> zhc2d|@6CwsmD5OJ`wH->88TMDLo?9>PBnvug1XHokOHTg$xmR@8^~Y5;|9|IyYvxs zq`3VdfH$s0Jg5k8_Imf1-D@kgYv83i`7k?i=tk&^$zHe2Ak%KspRBPf_pwLl*> z0AmaEK{pLr(5?->(E_}(0Uul7KQ>@d3t}W2@UaClumKlaK+gu7XhB?JyPQKjvjO*7 zft@zsUMujy1{t)19~*G5746x89j!zcvTX$}*CbY2K;IxK7n6tgGhm2ZNwMirgowS9k!#44fxd# zIoTkCcKE0bvTKK}+n|$n*qjY3Ba?bIIdr~~$B10HptFE-#&2mH|n9d`i7Y`~)q#1}STOb77|U+jQBZ5Wq3 zU{^NSKnJx49O{5>Z5WsDg5TIM4&O!n2j1L8`hhI(f?e34ySv~+HW=+)#4q}E7wp0Y z+_?*L5gU{ef~;-8nGj@P1I~nicQ)Wm2z{{uKSIC(8*n28OtV3@A(XM9jS#g1+z1h$ z7^g$j4rCsJuiAhkA(A(2D+JrN0Y^Gv=Qi-vN$o(Uog`=AMko4i18#HzXKcWWPSP9j zqLccI`9UYfSsUW4PO>M&Sz(eFa3c&^*$`ia!GjI95{AFoP$x|70YAbQ7+<68B6~xe z)rGOx2JGsh`j~5VWgrEwUBD+BaHR|QWP^^ofJZjWy}Fi7WFt_Rge%LUF>VnVOP-YXg51-jY zdI!F2B0U0MHj(}@N7@A0*nlgW$nJnAo5;U_ADa+Q*)TWSO#Oh(Z6*aCd9p^YtM_rQlO zq*q|+7V6)hkrMxq?N*}m8B((2&ykY+B1oZEJMdyF9ay*(ZP)koIi!pEvIDatj@d?h0S~spKJ1uRZG$h_fd|_lFFWvH8}WtsW*gB( z%(D%0wF>@y@;QaXW0_UX1B>_}slDC&=(#s*iZ) zUg8h7crS3(4*a;6_ym63OL9bBl#nKxDRoF z9mjn{4}QIiZlVi(*iCW(KI|rcKs>RV>FfdM*#W%h0Zu!B7d_z5feSsrB?sb*9@wA* zy6k~G9f&V_(0>QY_CWRy#2G#C3kPhy2QqK~XL`Vs12)@$`Vh$h`0x-g)&ZY?2zKT`9PtpY(Y?2a;JXgs#Y6CC2ikrJHtoQ? z<{{XU12+B;Y{r2&;~}C8n|X-nBHq}GalipQ*$W*wFyG%x^kK7m5uZ5_XY3_815fr+ zJBT;-0y`Yg>0bDS198V**slZe#$MQ~1HQPIP-$^A+CA~WOn5%wP~Pkn9~c zdywQlNMEN$3Y4lE4gyOYu$d>RpTMOjNuI!? zCt=eL$off)Z4S(Lo+Q43PfwCwA)_aWZ{XCEz$piC>Pg}c@y#K!U-<4JvLDQU4iOFk zzYbxnasa;$5kIi~L%?$f+CD^ng81htvIE3FPkH(6RQ43?Y65WWDU9Ti>{ICX1o-4rkpBeW*i&d{0(|Hx*y)5Mq>$eP==v$x%mm=rQ_#T##7R#9-zFeF zI!ttdYln#rZ2mCDwF$tV!{B`aaOLah|Ac&c-i+~ogw2!l*NSy(w97YQ5Topi?*Gr9 zKcC58Y<*WK6le=KG>6zG@%Rx72Rg&7qrH=LhC{5iy&1ku_p~^;1Id*Mkuj$I^O*8S zqxl)8{E=vWmMMQYnxCxaV~lW$bJ;h@knVZ$GS+>I*)O2=G1MMx^S1`*y!Mu@CC!~1 zSMfru0fkvZeUJs#ZxK)Kbmlb#>brv3t!!gusJSh?j5V?b*1~u$-Cf^^nA}fCC`i%y z=K9XCKNRljU=1KE+D2w;ptI8-4Djb_>iwMowA9Jdz?Q&ze)46?FurClWx^ny z8H=ln6{dV$7Z^+UzL41RYxVqyRvuW)>P-1UcNiDw{-l<#>xl7t9(sA9CB8VYMP6ri zN5l~s;HN}?r=AZQBT+gJ>G_Hyaz^__Yx9Quv*KLZ23n&vM%t%hWgFJ}B*;b@*Vl%( zc5wS3b6+0{(9?Cz4cz$G`@^UktQAj()#}gOwRR#i;18{DYHkbiU#rpTrhwscVSRfj z%+E@iL!JC&89lki&#K!&n4eX2wblnh(IVofUQqnjix;+S6>ThQ?`mt{S!+52A>LR( z{HEs%TLRjz+x*RvX~Ch$9iJn*C>|c;8Kt36d*~MJaWFk=1x$8jbG@EX*wMj%{D1A8 ze~ctYb;oOa=EfmGj*%V7kV9IqkwCeebH`7GBzSl4&b#*R-evdpj1ls=GlkjRc=WQ;L#0s>g^9hl>CuDJksuVeWv6 zGo1&^X%T#V1kE9-lc_q@iN)5rEk$Y4lNFVmt(I?MS0{k-awoadILI6hj;87$@{^kh}oOICtzM9KM>O@Eb|PDJrm=N4}sEF+%NCk-T`6RJ&!X zp*5oR^k>gyX_?0Tv~Zf3F8z3%$+HaGH>uw>pyZ7bc4K+ij|+0r zG&B=~{hZkCY5H-tI)?iwl782e@hTh={i(Ksl1(dNx^|ka%AQsE*w45_!?7gdSMwIO z`_@m8ZAa`_f6VgGf7Jg;aq%}S=P{AxaAjC=E6|L?#E4&;<~{&rI4ja%JAzLn~o{Zb*(%f7Rb=a z7pTa*Gxcf#&tATAu(vBLN9mwFGKEDWI$*02(@8UGv=|~N|K>j zCDTbV7FQN1ZX^A5xdvS_7$p@wq8QhZ8L=mHl5WW+;|zQI)x2d!Nipu1W;D(+*oPt| z?XUCpbQ6=GBP~#f)=q}l-5m}i**DE8(j}Scbg$U%e=EW88Xm0wu`ylHcfr583%{Va z^l8rj_skJvzDxMO2-kAHueg`_Jia#m*q~hNY{vpMm5PqBD zUlqQp_<7-Lia#oRsQ4qoHx)l8{G*CLB>WD=9}xcMihoAy((>>XFCx1d(2;BKX z!_VOzCw5Wzx0M{%KKtlc}!e>amNvr%=HyO?@RUd@GYeIHG?d?@X|Uv)ur97NEG#F_0XYW`(T zzX~4)5;^?ex_2sQl-zFOtXQWj;AmvEip5)q&#eQ60_LkXgisvHmquTkvh0hK&kF;m z-JGWYln<aDcRuj&cC#Q1gyr1W%;j;_VCPxhq9C%IdO8*D`Gx=2{?C`l* zTQxC>zQtoudF0TcPj3E%KH`fKIMAFy-zt7azDng<|*LbSMFEbkMXM&_hWoT z@vDV@Nb&u`Z&iF!IN4;ZliH!5wU7t(#~hKhITU-m;>Y-zkiYDG)1AV#{EsQ_^?$G8 zUjN?qlKh`u5dMJ5@7v`Iiu-nXSaI?76JJ*R1>s*&d`tLw#l_c8{FUP3>#sh zmm6h!$yPJR`o@VTJXbdPZ$ci}@W3W3Tdi%fx79yT+_&RT71y@6taM1LcOjA83(f=$du@cK(!U=UGWN;bcFPKG_~Rir2;k8Io?g(Su1} zC{~Y+vo`J!no~ob1A?)kBg2C#s^6@Zg!#BxLr1RiYYhMj5u8$Db$SV?yCdcgr}ggaoO&{ zIVPCtq>Dk_+I^F@`*Bg2GjwIpp?hF~2NgrZlkubj{5?#q+wP@wE*X956z~+?w8cIK zcbP5D?BCgCx||Dw+T@H&G-)gNy5Oee9jgXAs1R~NeAZ70rLuEL`^O^AJPBv^~^j4;17KR|~&SDvw z{WDFm4cmaEWrX_-**4+^Gby!HGlCe2q|NnK(-{@ChkYc$G1A@v9aYrEt8{>twqs^> z)Z}5-r!K^grAT7gT*+q94^j3k_0+0x6ty@WSVdL|euB~7T*kZ#sUCxh@|JCG3uMBp z?Xp#wS*a#k+yo29+cffAiB$F!PYT(oAyl9$9EY~#N+T3pcKCN!DAk7oQ$&|ACLK~> zr{rUX&Z1DIf)UlWrjp}MO7_@Va=oDuIw<3`-)Dpl#&(?tAzI%K)ZHg`Y|y>egFhW~ zR`2F}l@ONxx>xaq&kA4ry!LtR^V;YC+s8lU(eqQkuDHK<^-o*$z3b(Q`+4LyC@%M| zc>hGe<=&O&%RHYHE;*QAEBtN7zNcb){eMkyU;p1#+}Hn&iu?K>R@~SBy^8z#|B>R8 z!WRwi`Ly@6ugExJJN$_eD7K0n??&VPEoqn@6N9PC@X|L#3`dQgU&Mk_2Ib*|n#EiB7@;ooPL%7!GU5fkby<2gAz4s|D z<1xBlaT$-%rxlm+7=2c88IRZ(7Vs^{;YR{4bEeog7I2v}#s0B?%N!;4j|E)jG`Srs zeyMss%I$bQ%pdfhzonnA?ZUsUxNn#5DDK<$dy31rh@Mki;)Li0#U)ONex&%M@SiI# zaSrx@1^n%f<4S6~jk^PiOFzNBu!_U}KPCCcA@^|z`eALiaeANPs$T_M^{arZeid-l zuL8d1IQmtQ@0*{VL$9Upc-!b=`v0`zUjLs}-0T1Iii`ePpPqaDKcx7U@Ux10{XeX@*Z)D!FID=7K5K6a^9TC; zeZzYKt=?X_Abdu+(i`^e1>EcHpyw{W<#Lz8{6V=b`Z=|W{58e3{8PKgzg^{*cELV9 z&x3N2|IZ}9FSn(*AHQpgE5GJ==-0Sh$sd&a7xZ%vb9Fybdr-KKbI@ncD$ez(q0P^G zUPpbZI0yUp9N(b_DL1&^A^(WIeHHiD`z_&GKhJm`#(TBzhWUed5AvVgL;kaS$bWXH zeC$7~@86lfex2eXzy5B|Fq;u^n=5QQXV9RdH!|?E9)X?9ZLT3!mThhx$hi z@5>70NW0fRq4Hb%fO>w)<=|(Q)<05gSpU4@R|x-#;#Ua|)|U{!TKGRIzF)Xl7Uq+} zf2R1g!e8-xqVE0Uz6r$-2>(sRe^0o~OE7+=W9NZP(RmH&FlzohsP z;kPM1E4-)pyzqhICxjP@pA`P5ihoe}Cl&v&@SuH(-zNM^ig$#|og{Oq^}fdy?+Xw5 z1M#8oZz^627thLkL%4Wu=6@nwJqtH?3J>}f@wf#lJU}6_?g-+^YD~!u7b2UeM6vLgKx~8O0?&Y22Z>^p3_o zif;**mS!%!qw%2P5??iByqJ2phNJPA$}ej^8h`CMv7Zb7J1 z>NO&bA1eNm@LxF2^%Q+xCYZ}*eO^Z1@G|M2oL@@Arv`8HhMoUK?eM|FlW$+hN5kIn z9%)DcADOpYNXwCjRtZn}b>>vw+{f^w)5@Q~G$))E{nJK#m)6{~6BTc)X)zr7G z|2Sp$&2HmndBN`2bzC0#9<%#_eSY`k*X~a?kz3qh_cP1+)$`z`IlB+s)MQBpf3RoV z?Ax&@V<9I?de0Vp*VtqAg|YkQO-B`y|Z19m^v4gLhcia(sTgpTyL+FLAK%TQQMa<6z&*Vj{cN0Ux}7#?-=< z4fY*6sIy(dVBaNVBDa*mzKhA!^-2YN@UAFRS1T0QCgL4c759r3jD4q7#e-D~_8nN& zwX4+&e9rasYXa*S?7Ou{mwr8ivG4P$&ecm8=!18Vp}(e?nLn^pz5B1$;Z0!F=E;0) z%njV9t2M3^_rDKniri{ZW3Iv4`l#CYm{jk7j(CXx{jJ{D8`&*L_~3oJVgAd|{!z7m za9PVeu*l$*7$; zyokm@;WfXF=6B8+eor8^7ZrxJAXDbehzt?U*XYWJq_O!lLmkc`qKKBOB@o8UVeYdw zMH-vQhuq4P2T@aW9BhDqW$`1Z`~q*kUPL+3vA8G~lXW`05fN?;>8c!@&tnx!(B{fy zU}KvF*obH;#+FK)x9|+tBVkqUqk6zIPb~KkIGuy7j&S}wH~j*U*0svlpuLRHuXT&z`T+ zmFj2jbZJsMIiy)`hnYUPixsrP*>gx!_nXf%Y&$rMJ{DC8()n3LZ4*aQblaO?N1~gt QwCfnky73=uoom1NZ*=JuUjP6A literal 0 HcwPel00001 diff --git a/scalos/Extras/Scalos_GetHidden/gethidden.68k.info b/scalos/Extras/Scalos_GetHidden/gethidden.68k.info new file mode 100644 index 0000000000000000000000000000000000000000..c17f15272f71452f29bf28f7b880b9100e11701f GIT binary patch literal 8280 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 lqJ(r){$Y`!Y{uiqxIo1FG literal 0 HcwPel00001 diff --git a/scalos/Extras/Scalos_GetHidden/gethidden.mos b/scalos/Extras/Scalos_GetHidden/gethidden.mos new file mode 100644 index 0000000000000000000000000000000000000000..23ec98566dc05d4efbe35c15cc323b0593e2a934 GIT binary patch literal 87516 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 z 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 E1BLPV1ONa4 literal 0 HcwPel00001 diff --git a/scalos/Extras/browse.script b/scalos/Extras/browse.script new file mode 100755 index 000000000..82fbc8eb8 --- /dev/null +++ b/scalos/Extras/browse.script @@ -0,0 +1,12 @@ +.key browse +.bra { +.ket } + +c:requestfile "{browse}" title "What drawer should open?" drawersonly noicons >env:browse +IF WARN + delete env:browse >nil: + QUIT +ELSE + scalos:tools/opendrawer $browse +ENDIF +delete env:browse >nil: diff --git a/scalos/Extras/open_volume.rexx b/scalos/Extras/open_volume.rexx new file mode 100755 index 000000000..6263b968e --- /dev/null +++ b/scalos/Extras/open_volume.rexx @@ -0,0 +1,14 @@ +/* Open Volume */ + +addlib('rexxreqtools.library',0,-30) + +viewmode=2 + +Parse Arg name + +directory=rtfilerequest(,,'Select Volume To Open',,'rtfi_volumerequest=0',) +If directory ~= "" Then + address command "scalos:tools/opendrawer " directory 'VM=' || viewmode + + + diff --git a/scalos/Extras/opendrawer.68k b/scalos/Extras/opendrawer.68k new file mode 100644 index 0000000000000000000000000000000000000000..3d958c870a409c5ee0b71ec4e346ade18361e6cf GIT binary patch literal 6648 zcwX&UdrVu`8UOr%T#TE#8Evz)DkqlX;$VD%rfJGT>jzFS1)IbqA$<%CT)>N8@dMI_ zHegj2byLZ-s+yu|+8ZhaPXABV;KIAZXvR?+G+j)wNEJ=bjNk-A+ zzeU@F7jJ)N>kH4G~zq+uJ*h@eRhg+@LO4>&Rkr@7YZ??N{HL zN)lD}ll~PJmltexM55llAG6Sj24`HpVXbAg@S_JBZrZ40YFOodmNkIeZQV`Axk=C# z?G5rx(ZJlnv%S;S26@rpk=qLz9bVbZ%*F}WuM-KJH&oBIUh3w&H^KYT7-{zUf*03+ z4~=;nm)=dn9sOA;`J=lIe^wlB`7-dcR#1zS&P?gZFd5-b@p7i#k!js?3Kc?K;+Ht+g5MnRHkb z{$Gg#_l+LbJg?=eb$bDl^9udvccjlL^z(P5Uw6jj`QSx)7X3A?{~r2pDsr#hQSO>T z&)$(f>j=qtN0&Uo`3yG9cL~v0uzIZyGS5#UDob{6@O$7~bj9TS?wCAbcgk($kwLz! zlyc*Cumf2>Lb@8}l$R0hRg70hh#Kv2dDU7^gov;4*jjza0Hdfcc_h2Au4|yL_P^IL zBcFlPHds4TX3dN7wX#ecz<9QN3^{Ji1^lXL;8~+&E>_H5%X0-*-dAZHr;Kl4Jikfj z+@|sMO*U@8#tx2w{7azUD5IaYIpsyH+_JjoN-GmQi9A}i*9M;p=7{2v>}XVyq)aq1 zl1)bv8CNVikdCCE-#{6Nl<*_zNNO}XSVBY-*<3UmO(u$%p=61QPuBA~l%H?^b1jKZ z`4ZaOXcrLmOHM>wIPD0^ZzKK}P@D2-YiO%z%bt((i{7(4_d@}pzrg!cNyPKyZi^`J z`e3@yJ1r`ht-sbVulG*d3DGpnO;+-HvLq5;e@?63+Rf`+o@=uUh(DM6rC4=n+RAg& zA$o|im7T5G4KIwn=Cm_Uyz_7MHfwr!6!j9K zyRNRNwzp==cKpjC`9EG?vYR$=oMR2^%N-Ljq8`Mhd>^_XyC(8%Tjcq{>XS6<~>rGLbh9Q=5?5-c-BGsFyEDT^@~F2 z6M31b^6lzQ#tG=gN~pL1?mA8~WAB-5PU!QJMbTWNX}%AdAH?C$1z+zhWc5VJk?bYJ^bhnEDVQ+9S;jOU;Z zG$Z0^Mht*EhP})X-Ps9cY~?&D9jX}d*qbLg4{n)47B@kn6lo`v?Wq573k#*BL|ZyC zE~VL?Cf8n8*R;>o_&EL?tf{Hxk>-}hee6f9xv{ai0Y8tk4k?mo=!&GH67z*TJ#2qu zBod27BZ)!DJ)D*#*Kqm?*1&p3B^Dlx#F817l_GKGiAP5wp|ErBKBPIB9(blHel#kL zcO{1;_P{fZ@pvwiWdjoavg4AJ0Pd0IIOl3q$dSYl<0A$An1W)`sX-}~WriVvKg1D=lPVRMtn$(cv0?2MQ%8$qDG}ysjo$J_h|JV!cvS{s?j z0=`hNwF#Y|r_0~kj7~W4w7>NcblN;U{?x}o zQ(2m{hCQ8~EiBv~I#zCkk3+%E>?dfS3JWFwRj|&1`%FX;mY>&y8 zZPonEY;~fZc{{cblbrwVRlCnFguki1TjrR-ULDNccR85z+`@Sx*ia)4f7PfT;H|OB zUpXBU!*8T&_{)REetPg_+d3C^lzM%ikW^&fIt{UBYYWLiza)Ulfm2`}~~>?la7dk)Yg`EqeUo zBq8m;F6_6~DtE(e;JM=cz7>4!9(IKZd=7R#-)d0pzQ4$;_7hldz7m3>HwL};Xj=C6 zlf0m;kCDN5GWMQP|0$y?mY)byB_9ErHTY!>ZdExwOM0qn_bgG37x!BL^;1R%g0FMG*1MCIldLmfg7XSzNYY%V`kjr5`g;_w%uIeE` z_)-O({P9wi1{?*v2p9$Y2=Hq-mCb#RE_z) zXk6|~obtbj{otrHcmk&h;VCW=??|VlLFGrmK%oM;E*i)U_j%GI89dF0lQbNSNxU-< zOAekO{?pg3oQZ{gc9c^5CzDNU2OHryj-=C(=P5lD;fe+#LuqL&s?g9cumMNtlX}VF z77+E84aV_%)?_KN>6HbrmEOM$~{-SHNp}__w!+ zC%IyMNx^*uEwF)qt;m051AeuL?g(5y#(qpWUSIDU0Pf@x4RKRl-D=lOY3lM1KwQ3|Df0dUY;pxx=`W=&Qiqxti&%H<@w_1{tftr za-3lWKihoCcnY;{h>b_Hqs;H?WzDW8S2L^YN~Tkzc-D1y`yA}BG!o5Zr8M}m$<0?& z7wL(gEByb@7>YIbAB*eSIigqUtNfv?ox}PQ-RWo|dw@G3sN-BVoaILsSvBAO{!g>^ BrXv6V literal 0 HcwPel00001 diff --git a/scalos/Extras/opendrawer.68k.info b/scalos/Extras/opendrawer.68k.info new file mode 100644 index 0000000000000000000000000000000000000000..8209ff1d7767c12129244acb5c404f409b29d205 GIT binary patch literal 10288 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 literal 0 HcwPel00001 diff --git a/scalos/Extras/opendrawer.mos b/scalos/Extras/opendrawer.mos new file mode 100644 index 0000000000000000000000000000000000000000..7b1ea2c1b70789b221d12fff4ee8d1fdb3d790e2 GIT binary patch literal 8908 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 p4^@%+GyBXZX0Hrenv:runit +IF WARN + delete env:runit >nil: + QUIT +ELSE + c:wbrun $runit +ENDIF +delete env:runit >nil: diff --git a/scalos/GPLsrc b/scalos/GPLsrc new file mode 100755 index 000000000..f8b999913 --- /dev/null +++ b/scalos/GPLsrc @@ -0,0 +1,53 @@ +/* GPLsrc */ +/* $Date: 2008-06-01 10:01:35 +0200 (So, 01 Jun 2008) $ */ +/* $Revision: 2829 $ */ +/* $Id: GPLsrc 2829 2008-06-01 09:01:35Z juergen $ */ + +LHAName1 = 'RAM:VideoPlugin-src' +LHAName2 = 'RAM:DeleteModule-src' + +address command + +"makedir RAM:Video.Plugin" +"makedir RAM:Delete.Module" +"makedir RAM:Delete.Module/" +"makedir RAM:Delete.Module/Catalogs" +"makedir RAM:Delete.Module/Catalogs/deutsch" +"makedir RAM:Delete.Module/Catalogs/sample" +"makedir RAM:Delete.Module/Catalogs/français" +"makedir RAM:Delete.Module/Catalogs/deutsch/Scalos" +"makedir RAM:Delete.Module/Catalogs/sample/Scalos" +"makedir RAM:Delete.Module/Catalogs/français/Scalos" + +say "Copying Video.Plugin..." + +'copy Plugins/Preview/Video/#?.(c|h) "RAM:Video.Plugin" clone quiet' +'copy Plugins/Preview/Video/makefile-new "RAM:Video.Plugin/makefile" clone quiet' +'copy Plugins/Preview/Video/config.mk "RAM:Video.Plugin" clone quiet' +'copy gpl-3.0.txt "RAM:Video.Plugin" clone quiet' +'copy lgpl-3.0.txt "RAM:Video.Plugin" clone quiet' +'copy Plugins/Preview/Video/COPYING "RAM:Video.Plugin" clone quiet' + +say "Copying Delete.Module..." + +'copy Modules/Delete.MUI/Source/#?.(c|h) "RAM:Delete.Module" clone quiet' +'copy Modules/Delete.MUI/Source/Delete.Module_rev#? "RAM:Delete.Module" clone quiet' +'copy Modules/Delete.MUI/Source/makefile-new "RAM:Delete.Module/makefile" clone quiet' +'copy Modules/Delete.MUI/Source/config.mk "RAM:Delete.Module" clone quiet' +'copy Modules/Delete.MUI/Source/#?.cd "RAM:Delete.Module" clone quiet' +'copy gpl-3.0.txt "RAM:Delete.Module/COPYING" clone quiet' + +'copy Modules/Delete.MUI/Source/Catalogs/sample/Scalos/#?.ct "RAM:Delete.Module/Catalogs/sample/Scalos" clone quiet' +'copy Modules/Delete.MUI/Source/Catalogs/deutsch/Scalos/#?.ct "RAM:Delete.Module/Catalogs/deutsch/Scalos" clone quiet' +'copy Modules/Delete.MUI/Source/Catalogs/deutsch/Scalos/makefile-new "RAM:Delete.Module/Catalogs/deutsch/Scalos/makefile" clone quiet' +'copy Modules/Delete.MUI/Source/Catalogs/français/Scalos/#?.ct "RAM:Delete.Module/Catalogs/français/Scalos" clone quiet' +'copy Modules/Delete.MUI/Source/Catalogs/français/Scalos/makefile-new "RAM:Delete.Module/Catalogs/français/Scalos/makefile" clone quiet' + + +say "Creating archives..." + +'lha -r -e -x a ' || LHAName1 || ' RAM:Video.Plugin ' +'lha -r -e -x a ' || LHAName2 || ' RAM:Delete.Module ' + +lha t LHAName1 +lha t LHAName2 diff --git a/scalos/History b/scalos/History new file mode 100644 index 000000000..7c67473dc --- /dev/null +++ b/scalos/History @@ -0,0 +1,2911 @@ + +**************************************************************************** + +--------------------Main Scalos--------------------------------------------- + +NEXT VERSION TO RELEASE 41.8 + + +Additions/changes: + +41.8 20121117 jmc - Improvement: Upgraded libpng to 1.5.13 and zlib to 1.2.7. + 20120825 jl - Bugfix: release creation script failed to copy icon datatypes. + 20120312 jl - Improvement: Updated sqlite3.library to SQLite3 V3.7.10. + 20120311 jl - Improvement: Upgraded libpng to 1.5.9. + 20120121 jl - Bugfix: resolved NULL pointer dereferencing w/ crash in persist plugin (only occurs with iconified windows). + 20111204 jl - Improvement: Updated sqlite3.library to SQLite3 V3.7.9. + 20111020 jl - Improvement: File transfer class duration estimate now also displays hours. + - Improvement: Updated memory allocator to dlmalloc 2.8.5. + - Improvement: Updated sqlite3.library to SQLite3 V3.7.8. + 20110605 jl - Improvement: Updated sqlite3.library to SQLite3 V3.7.6.3. + 20110511 jl - Improvement: Updated sqlite3.library to SQLite3 V3.7.6.2. + 20110220 jl - Improvement: added new menu command to open disks or drawers in a new browser window. + - Bugfix: corrected multiple issues with default icons for unreadable files. + 20110205 jl - Improvement: Upgraded libpng to 1.5.1. + 20110202 jl - Improvement: Updated sqlite3.library to SQLite3 V3.7.5. + 20110116 jl - Improvement: Upgraded libpng to 1.5.0. + 20110109 jl - Bugfix: if new directory couldn't be locked upon creation ("Object in use"), Scalos + failed to show drawer icon. + 20110108 jl - Improvement: if project icon has invalid tool, the pop-up requester now has an option to + use the "default tool", ie. the default tool of the corresponding default icon, + as stored in ENV:Sys. + 20110107 jl - Improvement: If no default tool is present in a project icon, try to get a + default icon and if present, use default tool from the default icon. + 20110104 jl - Improvement: updated libZ to version 1.2.5 + 20110102 jl - Improvement: updated libcurl (used by updater.module) to version 7.21.3 + 20110101 jl - Bugfix: on MorphOS, most WMV video thumbnails contained garbage. + 20101231 jl - Bugfix: corrected various issues with soft links, e.g. after creating a new soft link + to an image, it didn't show up correctly inside icon window. Icon windows failed to + display underlined soft link names if no icon was present (i.e. for default icons). + - Bugfix: under certain circumstances, glowiconobject set wrong icon size (too small) + which caused iconobject.datatype to overwrite allocated memory. + 20101227 jl - Improvement: Upgraded libpng to 1.4.5. + 20101226 jl - Improvement: abborting long directory reads via "parent", "forward", "backward", + etc. buttons now works as expected. + 20101212 jl - Improvement: Updated sqlite3.library to SQLite3 V3.7.4. + 20101123 jl - Bugfix: when icon was dragged over drawer in same window, pop-open window function was broken. + 20101108 jl - Bugfix: information.module: corrected overflow on device usage percentage calculation. + - Bugfix: disabled thumbnail generation in popup windows during drag&drop. + 20101010 jl - Improvement: Updated sqlite3.library to SQLite3 V3.7.3. + 20100828 jl - Improvement: Updated sqlite3.library to SQLite3 V3.7.2. + 20100821 jl - Bugfix: the Rename patch caused attempts to lock an invalid path containing gargabe characters. + 20100820 jl - Bugfix: with AsyncWB installed, Scalos failed to copy associated icons when copying objects. + 20100914 jl - Improvement: Updated sqlite3.library to SQLite3 V3.7.0.1. + - Improvement: Added support for SQLite3 WAL. + 20100910 jl - Improvement: Updated sqlite3.library to SQLite3 V3.7.0. + 20100629 jl - Upgraded libpng to 1.4.3. + 20100605 jl - Bugfix: window history entries are now adjusted correctly when a listed directory is renamed. + 20100604 jl - Improvement: jpegpicture.pvplugin : now JPG pictures are read in one big chunk. + This method uses more memory, but greatly speeds up reading images + on some file systems (e.g. USB ptp). + 20100603 jl - Bugfix: finally implemented complete support for backdrop icons + created by MorphOS Ambient (shortcuts.prefs). + - Bugfix: enabled workbench.library WBInfo path for all systems. With this fix, + AmigaOS4.x Workbenchstart "Information" button works again with Scalos. + 20100509 jl - Bugfix: for file copying and link creation, detection of already existing icons didn't work. + 20100505 jl - Improvement: allow individual icon size constraints and icon scale factor per window. + - Bugfix: Windowproperties.module: fixed enforcer hit/crash when saving changes. + 20100501 jl - Improvement: arbitrary scaling of icons is now possible. + 20100418 jl - Bugfix: scaling of newicons always displayed garbage. + - Improvement: updated libcurl (used by updater.module) to version 7.20.1 + 20100411 jl - Bugfix: corrected recognition of active 3D-Layers ("Enhanced Display") with MorphOS 2.x + - Bugfix: do not check RAM disk for sucfficient space (when copying files) when it + returns 0 blocks free (AmigaOS3.x RAM disk always returns 0 free blocks). + 20100328 jl - Improvement: added option to select whether drawers in text windows are + displayed before files, after files, or with files. + 20100324 jl - Improvement: Updater.module: added signature check for downloaded versions.txt file. + 20100322 jl - Bugfix: corrected line height calculation for text windows. + - Bugfix: minimum window size is now adjusted, taking control bar and status bar into account. + +41.7 20100312 jmc - Improvement: Updated libjpeg to libjpeg V8 for Morphos. + 20100310 jl - Improvement: Updated sqlite3.library to SQLite3 V3.6.23. + 20100309 jl - Bugfix: added Workaround against "menu-open-lockup" with MorphOS. + 20100228 jl - Improvement: added check for sufficient space on copy/move operations. + - Bugfix: corrected handling of copy/move progress without valid totals count. + 20100219 jl - Improvement: touching pattern.prefs trigger selection + of new random background patterns, even when prefs have not changed. + 20100216 jl - Bugfix: Reboot button in about window didn't work with MorphOS 1.x. + 20100213 jl - Bugfix: screen backdrop pattern didn't work. + 20100202 jl - Bugfix: links to volumes could not be created. + - Bugfix: drop menu didnt work when dragging volumes into icon windows. + 20100201 jl - Bugfix: Undo/Redo function was unable to remove copied (non-empty) directories. + 20100130 jl - Improvement: added capability to undo/redo closing windows. + - Bugfix: sqlite3.library reported read-only state for "RAM:t". + - Bugfix: scalos crashed when drag-copying a disk into an icon window. + 20100128 jl - Bugfix: thumbnail cache database sometimes was left open if ThumbnailCacheOpen() failed. + 20100117 jl - Improvement: added user configuration for SQLite3 thumbnail + database temporary files directory. + - Improvement: implemented large file (4 >GBytes) support for AmigaOS4. + - Improvement: added new popup menu for desktop. + 20100107 jl - Improvement: Updated sqlite3.library to SQLite3 V3.6.22. + 20100105 jl - Bugfix: fixed GR with AmigaOS4 when user attempted to run a second Scalos instance. + 20100104 jl - Bugfix: improved DosList locking fixed occasional crash when volumes/devices go away. + - Improvement: requester informs user if Scalos is run a second time. + - Improvement: requesters informs user if menu preferences cannot be read. + 20091229 jl - Bugfix: corrected problems with text window striping and + window resizing under MorphOS. + 20091218 jl - Bugfix: with "apply to all selected icons" enabled, popup menu selection + always was applied to one icon less than selected. + 20091214 jl - Improvement: information.module: added Undo/Redo support for object renaming. + - Bugfix: information.module: for text windows, icons are not displayed correctly. + 20091211 jl - Improvement: Updated sqlite3.library to SQLite3 V3.6.21. + 20090609 jl - Upgraded libpng to 1.2.41 (68k). + 20091207 jl - Bugfix: worked around a possible GCC bug that caused filetypes prefs to crash + on AmigaOS4 when trying to edit an attribute. + 20091129 jl - Bugfix: In pattern preferences, separate preview right of listview was broken. + 20091128 jl - Improvement: eliminated separate Rename.module for rename-in-place. + Now there is only one Rename.module, rename-in-place can be activated + by setting an environment variable "Scalos/RENAMEINPLACE" to any + value (e.g. "setenv save Scalos/RENAMEINPLACE 1"). + 20091107 jl - Improvement: Updated sqlite3.library to SQLite3 V3.6.20. + 20091101 jl - Bugfix: Highlighting window gadgets when mouse pointer was moved over + them didn't work with AmigaOS4. + 20091031 jl - Bugfix: On MorphOS 2.x, main menu entries were never disabled. + 20091026 jl - Bugfix: suppress system requester when relabelling a volume. + - Bugfix: corrected location of rename gadget for RenameInPlace. + 20091016 jl - Improvement: Updated sqlite3.library to SQLite3 V3.6.19. + 20091011 jl - Improvement: Add support for control bar also for standard (non-browser) windows. + - Improvement: Windowproperties.module: control bar can be switched off + for individual windows. + 20091005 jl - Bugfix: with AmigaOS4, centered window background images sometimes did not display. + 20090918 jmc - Improvement: Upgraded libpng 1.2.39 to 1.2.40 (68k and MOS). + 20090915 jl - Improvement: added new sophisticated text window selection marker. + - Improvement: Moved main preferences text window settings to separate page, + and added configuration for new selection marker. + 20090911 jl - Bugfix: popupmenu.library: zoom effect didn't work correctly on + MorphOS if "Enhanced Display" was enabled. + jl - Improvement: Updated sqlite3.library to SQLite3 V3.6.18. + 20090823 jl - Improvement: added new FileTrans subdirectory to default theme. + 20090812 jmc - Upgraded libpng 1.2.37 to 1.2.39 (SAS/C and MOS). + 20090811 jl - Improvement: Updated sqlite3.library to SQLite3 V3.6.17. + 20090810 jl - Improvement: enhancements for popup window feature: now works with single-window. + Added preferences options to enable/disable popup window feature + and to adjust popup delay. + - Bugfix: information.module: icon drop zone drop marks were not displayed + correctly under MorphOS 2.3. + 20090809 jl - Improvement: data transfer speed in copy/move progress window is now + rounded to two decimals. + - Improvement: added support for dynamic window resizing with + MorphOS 2.3 Advanced Display Engine. + - Improvement: added experimental new feature: drawers and volumes pop up when + mouse pointer stays longer than 3 seconds over them during Drag&Drop. All + popped up windows automatically close when D&D is finished. + 20090729 jl - Improvement: added more details to copy/move progress window. Cancel + button now had themed image. Copy/move progress window is now sizeable. + - Improvement: Copy/move recognizes if destination file system does not support + links, and asks the user whether to skip the link(s), copy the link contents, + or abort the entire operation. + 20090726 jl - Bugfix: information.module:crash when trying to replace icon image by + dropping another icon on the image. + - Bugfix: information.module:drop mark wasn't displayed correctly + with MorphOS 2.x and 3D layers enabled. + 20090719 jl - Bugfix: Under rare circumstances, on startup some left-out icons erroneously + appeared inside their directory windows instead of the desktop window. + 20090629 jl - Improvement: Updated sqlite3.library to SQLite3 3.6.16. + 20090628 jl - Bugfix: updating left-out icons left the Scalos main window task + with an invalid current directory handle. + 20090618 jl - Improvement: Updated sqlite3.library to SQLite3 V3.6.15. + 20090609 jmc - Upgraded libpng 1.2.36 to 1.2.37 (68k and MOS). + 20090528 jmc - Upgraded libpng 1.2.35 to 1.2.36 (68k and MOS). + 20090526 jl - Improvement: Updated sqlite3.library to SQLite3 3.6.14.2. + 20090523 jl - Improvement: Updated sqlite3.library to SQLite3 3.6.14.1. + - Improvement: icons can now be selected incrementally via keyboard input. + 20090517 jl - Bugfix: when switching to non-backdrop desktop window, the window was + created with 100% transparency (invisible). + 20090511 jl - Improvement: added filetype for FLV video. + 20090507 jl - Improvement: Updated sqlite3.library to SQLite3 V3.6.14. + 20090430 jmc - Bugfix: Extras comment.module didn't increment files via + asl requester using ASLFR_DOMULTISELECT tag. + 20090413 jl - Bugfix: about window gadget tooltips kept appearing over and over. + 20090412 jl - Improvement: gadget help tooltips in about window no longer pop up + immediately when mouse is moved over gadget, but with a short delay. + 20090410 jl - Improvement: added smooth fade-in and fade-out for Splash and About + windows (MorphOS2.x and AmigaOS4.x only). + 20090402 jl - Improvement: Updated sqlite3.library to SQLite3 V3.6.12. + 20090327 jl - Bugfix: in default menu preferences, prefs drawer didn't open due to wrong path. + 20090322 jl - Bugfix: information.module:wrong icon was displayed for all entries inside a + drawer if at least one icon was left-out from this drawer to the desktop. + +41.6 20090304 jl - Improvement: added support for alpha transparency on AmigaOS4 with defpicture.pvplugin. + 20090301 jl - Improvement: Added general support for persistent storing of sorting + direction with new ddFlags values introduced by AmigaOS4. + 20090128 jl - Improvement: Updated sqlite3.library to SQLite3 V3.6.11. + jl - Improvement: Added support for AmigaOS4 CPU information in title bar. + 20090227 jl - Bugfix: introduced support for alpha transparency with AmigaOS4 datatypes. + 20090226 jmc - Upgraded libpng for AmigaOS/68k and MorphOS - lipng version 1.2.35 - February 14, 2009 + 20090225 jl - Bugfix: Popup menu for AppIcons didn't work correctly + if "apply to all selected icons" was enabled. + 20090221 jl - Bugfix: Occasional hit with AmigaOS4 moving the mouse over the About window gadgets. + 20090220 jl - Improvement. informationmodule: now displays name of + recognized filetype and icon position. + 20090216 jl - Improvement: lots of changes to allow build with latest AmigaOS4.1 SDK. + 20090124 jl - Improvement: find.module result list can now be copied to clipboard. + 20090117 jl - Improvement: Updated sqlite3.library to SQLite3 V3.6.10. + 20090113 jl - Improvement: Updated sqlite3.library to SQLite3 V3.6.8. + 20090112 jl - Improvement: added different degrees of transparency for active and inactive Scalos windows. + - Improvement: Window transparency can be individually configured for each window. + 20090109 jl - Improvement: added support for transparent Scalos windows - MorphOS 2.x only. + 20090105 jl - Improvement: replaced the ugly GadTools buttons in About window by themed + image buttons. Fallback to simple rctangular buttons is provided. + - Improvement: "Reboot" dialog from About window now also supports + shutdown (Currently only with MorphOS 2.x). + 20090103 jl - Improvement: added option to highlight text of selected icons + by a surrounding rectangle with rounded corners, with + user-configurable color, borders and corner radius. + 20081224 jl - Improvement: added new Commodities Exchange module. + - Bugfix: finally managed to make dropmarks work again properly + with MorphOS 2.x and 3D layers. + 20081223 jl - Bugfix: after changing standard (non-TT) icon font, icon font + always was reset to Topaz/8 + 20081219 jl - Improvement: tooltips now smoothly fade in and out - MorphOS 2.x only. + - Improvement: Cycle and History gadget popup windows now may have configurable + background patterns "THEME:Window/ControlBar/CyclePopupBackground" + and "THEME:Window/ControlBar/HistoryPopupBackground". + - Bugfix: Fixed major memory leak in video.pvplugin. + - Bugfix: Incorrect image reading algorithm in video.pvplugin caused endless + loop with certain video format files. + 20081218 jl - Improvement: find.module history for pattern and contents is now stored + persistently. Added Popup menus for history lists. + 20081217 jl - Improvement: Updated sqlite3.library to SQLite3 V3.6.7. + 20081216 jl - Improvement: Updated video.pvplugin to use latest libavcodec library + (MorphOS only). Now supports more video formats, including + several real video format variants. + 20081128 jl - Improvement: Updated sqlite3.library to SQLite3 V3.6.6.2. + - Bugfix: informationmodule: directory size calculation didn't + work with large files >2GBytes. + 20081123 jl - Improvement: Updated sqlite3.library to SQLite3 V3.6.6.1. + 20081122 jl - Improvement: Updated sqlite3.library to SQLite3 V3.6.6. + 20081119 jl - Improvement Information.module: Add support for large files (64 bit file size). + 20081112 jl - Improvement: Updated sqlite3.library to SQLite3 V3.6.5. + 20081018 jl - Improvement: Updated sqlite3.library to SQLite3 V3.6.4. + 20081009 jl - Bugfix: automatic icon positioning didn't work correctly in small + windows with lots of icons. + 20081003 jl - Improvement: file copy buffer size is now configurable via Scalos Prefs. + 20080923 jl - Improvement: Updated sqlite3.library to SQLite3 V3.6.3. + 20080907 jl - Bugfix: Added BMF_MINPLANES flag at save BitMap allocations. + This solves problem with garbage visible after removing + dropmarks with MorphOS 2.x. + - Bugfix: Added BMF_MINPLANES flag at FrameImageClass. BitMap allocation. + This resolves visual garbage on cycle gadget backgrounds with MorphOS 2.x. + 20080901 jl - Improvement: Added new find.module. + 20080831 jl - Improvement: Updated sqlite3.library to SQLite3 V3.6.2. + 20080830 jl - Bugfix.in SCA_OpenIconWindow() and SCA_OpenDrawerByName() library functions, + SCA_ShowAllMode and SCA_ShowAllFiles tags explicitly given + now take precedence over any window or icon settings. + 20080824 jl - Improvement: added new internal command "find", to be used + with upcoming "find.module". + 20080817 jl - Bugfix: scalosgfx.library function ScalosGfxFillARGBFromBitMap() didn't + set Alpha values correctly for ARGB/RGBA/BGRA input BitMap types. + - Improvement: defpicture.pvplugin now supports Alpha transparency for + thumbnails (if source image type contains Alpha information). + - Improvement: Trying to quit Scalos in workbench replacement + mode now gives a reasonable error message. + - Bugfix: USB device with MSD* file system type were not recognized properly. + - Improvement: Made several new sqlite3 functions accessible + via library calls. + 20080806 jl - Improvement: Updated sqlite3.library to SQLite3 V3.6.1. + 20080727 jl - Improvement: Control bar gadgets are now updated on-the-fly, i.e. no + more reason to close and re-open a window after changes in + control bar gadget preferences. + - Bugfix: switching control bar cycle gadgets with mouse wheel didn't work. + 20080726 jl - Improvement: Added bicubic scaler for improved quality of scaled + pictures, e.g. thumbnails. + - Bugfix: solved various problems when preferences are reloaded after + change, i.e. there should be no more problems saving changed preferences. + 20080723 jl - Bugfix: plugged several holes in CloneDefIconObject() that could cause + crashes, e.g. when desktop was rebuilt after preferences change. + 20080716 jl - Improvement: Added configurable (both global and per window) checking + for overlapping icons. + jl - Improvement: Updated sqlite3.library to SQLite3 V3.6.0. + 20080702 jl - Bugfix: control bar cycle bar gadget height calculation had a bug which + sometimes caused control bar to become way to tall. + 20080527 jl - Improvement: Added user-configurable images for text window sort + order indicators ("THEME:Window/SortAscending" + and "THEME:Window/SortDescending"). + 20080526 jl - Improvement: while dragging icons, window contents can be scrolled to + reveal invisible contents by holding the mouse pointer over the window borders. + 20080518 jl - Improvement: extended DefIcons functionality to cover classification + of WBDISK objects, i.e. USB disks, DVDs or SMB network volumes are now + recognized automatically. + 20080517 jl - Improvement: sorting of text windows can now toggled between ascending + and descending order by clicking on the column headers. + 20080514 jl - Improvement: Updated sqlite3.library to SQLite3 V3.5.9. + 20080509 jl - Bugfix: Icons without object were handled differently on original + directory read than on window update. + - Improvement: Added support for shadowed/outline text window icons. + Used for highlighing cut icons, and for mouse-over effect. + 20080417 jl - Improvement: Updated sqlite3.library to SQLite3 V3.5.8. + 20080403 jl - Improvement: Worked around a certain type of semaphore deadlock with + icon lists. This resolves locked desktop after dragging around + some animated icons. + 20080318 jl - Improvement: Updated sqlite3.library to SQLite3 V3.5.7. + 20080302 jl - Bugfix: browser window didn't correctly set non-zero window + offsets from drawer icon. + 20080301 jl - Bugfix: control bar gadgets which are hidden due to lack of space were + erroneously drawn when corresponding attribute was changed, e.g. when + window view mode was switched. + - Improvement: sped up text window redraw. + - Improvement: added support for text icon highlighted and shadowed state. + - Bugfix: Added safeguard against possible division by 0 in popupmenu.library. + - Improvement: blurred transparent area now look nicer due to + switching from 3x3 to 5x5 blur matrix. + 20080224 jl - Improvement: for text icons and TTLayout engine, SetSoftStyle() and SetFont() + is now only called if really required. + 20080221 jl - Bugfix: default Pattern wasn't set correctly according to icon's view + mode in SCA_OpenIconWindow(). + 20080217 jl - Bugfix: SCA_OpenDrawerByNameTags() failed to open drawers with no associated icon. + - Bugfix: text windows were not updated correctly when files or drawers were + added while window was iconified. + 20080207 jl - Bugfix: window close gadget had to be clicked twice during thumbnail creation. + - Improvement: Updated sqlite3.library to SQLite3 V3.5.6. + 20080205 jl - Improvement: Added caching for default icons, to speed up opening + drawer windows with many default icons. + - Bugfix: For drag-drop label ("334 files, 12 drawers"), detection of + singular/plural message for files ("file" vs "files") was wrong. + - Bugfix: At end of drag&drop, icons in text windows were not + deselected correctly. + - Bugfix: At end of drag&drop, selected icon count in status bar + wasn't updated immediately. + 20080109 jl - Improvement: Added two new scalos.library + functions SCA_LockDrag() and SCA_UnlockDrag(). + - Improvement: Icons no longer stay selected after being dragged. + - Improvement Information.module: Highlighting of icon drop zones + when icons are dragged over them now also works with MUI 4.0 + 20080101 jl - Improvement Window Properties Module: Selection of window background + now has a drop-down list with preview thumbnails. + 20071223 jl - Improvement: popup menus now have smooth dropshadows. + 20071219 jl - Improvement: Updated sqlite3.library to SQLite3 V3.5.4. + 20071216 jl - Bugfix: Status bar never showed "View all" icon when a window was opened. + - Bugfix: enforcer hits if "Mark icon under mouse" enabled. + 20071206 jl - Improvement: updated to libpng 1.2.23. + 20071202 jl - Improvement Information.module(MUI): Changes volume file system field + to float text, in order to prevent window to become extremely wide. + 20071128 jl - Improvement: Updated sqlite3.library to SQLite3 V3.5.3. + 20071127 jl - Bugfix: When screen fotn was changed, status bar font wasn't + updated for existing windows. + 20071126 jl - Improvement: background of transparent tooltips is now drawn blurred. + - Improvement: added configurable blurring of transparent popup menu background. + 20071125 jl - Bugfix: Auto-update caused unnecessary icon refresh if date or protection + differed between icon and object. + - Improvement: Updated sqlite3.library to SQLite3 V3.5.2. + 20071105 jl - Bugfix: browser text window column width was not adjusted when + switching between different directories. + 20071104 jl - Bugfix: control bar gadget enable status wasn't updated if selected + icon(s) were disabled by clicking into different Scalos window. + - Bugfix: control window gadgets were not disabled correctly when + icon in different window got disabled with double-click. + 20071103 staf - Improvement: everything now uses newlib.library as C run time on OS4 + 20071102 staf - Improvement: Modules and Prefs are now also buit with newlib.library + 20071101 staf - Improvement: All Plugins, libraries and datatypes are built now + with newlib.library for OS4. + 20071029 staf - Bugfix: fixed OS4 initialization code that could lead to recoverable + alerts when quiting scalos or crashes when expunging scalosgfx + 20071006 jl - Improvement: show-all, view mode, and window x/y offset are now + remembered for each directory inside browser window. + - Improvement: Icon lists are cached for all directories in + browser windows (still experimental). + - Improvement: Updated sqlite3.library to SQLite3 V3.5.1 (still experimental). + 20070916 jl - Bugfix: EXALL packet was issued once more + after ERROR_NO_MORE_ENTRIES had been returned. + 20070902 jl - Improvement: thumbnail cache cleanup no longer removes entries on + volumes that are (currently) not mounted. + 20070901 jl - Bugfix Information.module(MUI): Window no longer expands + vertically when switching icon type. + 20070822 jl - Bugfix: drawing selected icons in highlighted state erroneously + used the unselected Alpha channel. + - Bugfix: type of PNG icons is no longer incorrectly set due to + unreasonable icon hunk attributes (e.g. drawer x/y position + for "tool" icon). + - Bugfix: for dual PNG icons, only first icon hunk will be loaded, + any further icon hunks are ignored. + 20070812 jl - Improvement: about window scrolling can now be toggled by clicking + anywhere inside window. + - Bugfix: double-clicking icons didn't wiork while thumbnail generation + was in progress. + +41.5 20070726 jl - Bugfix: Information.module(MUI): garbage was displayed instead + of device handler ID string. + 20070715 jl - Improvement: Thumbnail cache cleanup now always removes + entries for non-existing files. + - Improvement: Added menu command to manually initiate + thumbnail cache cleanup. + 20070626 jmc - Information.module(MUI): + Added new menu option to get size of drawers always or not at startup. + A new "InfoAuGetSize" variable will be created into "env:scalos/" and + "envarc:scalos/" to always or never get size at startup. + Replaced "information.prefs" by "InfoShowiconPath" variable to show/hide + icon path at startup. + 20070624 - Information.module(MUI): + Added new menu option to show or hide the icon path gadget. + A new "information.prefs" file will be created into "env:scalos/" and + "envarc:scalos/" to always or never show icon path gadget after startup. + Removed icon object's selecting codes which allowed the similar + "hide/show" function. + 20070610 jl - Improvement: Added support for centered and unscaled + background images, and for scaled images with correct aspect. + - Improvement: Added support for single-colour or + gradient backfill. + 20070603 jl - Improvement: path for internal datatypes image cache (previously + fixed "t:") is now user-configurable. On startup, all old Scalos + files are removed from that location. + 20070526 jl - Improvement: About window no longer starts with empty area. + - Improvement: Added button to temporaily stop scrolling of about window. + 20070523 sv - Improvement: amigaiconobj35.datatype can now retrieve ARGB icons if + icon.library does support ICONCTRLA_GetARGBImageData[12]. + 20070503 jl - Bugfix: Color palette wasn't loaded correctly on Scalos startup. + 20070430 jl - Improvement: Added build number to Scalos version information (Splash + about). + 20070426 jl - Bugfix: Delete.module crashed with file names longer than 39 characters. + 20070422 jmc - Improvement: (IconProperties module) Added SCALOS_BROWSERMODE + tooltype support. + 20070401 jl - Improvement: "view by type" now finally works. + - Improvement: "type" column in text windows is now functional. + 20070326 jl - Bugfix: installer script failed if languaga setting was different + from "English", "Francais", or "Deutsch". + 20070323 jl - Improvement: optimized text window refresh. Now windows is only + redrawn if really required. + 20070319 jl - Bugfix: Moving files didn't correctly update "Show All Files" windows + 20070315 jl - Bugfix: Changing truetype icons font didn't have immediate + effect (required restart). + 20070313 jl - Improvement: devicefilter.plugin no longer requires Workbench V44+, + i.e. filtering of device no also works with OS3.0 and 3.1. + 20070220 jl - Improvement: icons won't stay selected after double-click anymore. + 20061126 jl - Bugfix: added work-around in defpicture.pvplugin to circumvent a + problem with some MorphOS datatypes (e.g. GIF and BMP) that cause + the last byte of sac_BitMap to be decremented by 1 when the + datatypes object is disposed. + 20061119 jl - Bugfix: never try to open SQlite3 thumbnail database if + user-configured thumbnail cache database name is empty. + - Bugfix: Added safeguard to avoid crash when OpenDrawerByName() was + called with a device name before desktop window was completely + initialized. This could happen if initial delay for persistent window + plugin was set too short. + 20061029 jl - Improvement: font preferences about draw mode and background color + for icon text are now taken into account. + jl - Bugfix: incorrect parsing of Workbench font preferences caused + wrong background pen and draw mode to be used. + jl - Bugfix: added a workaround to defpicture.pvplugin that permits + thumbnails to be generated under OS3.0/3.1 and Picasso96. + jl - Bugfix: Information.module failed to close opened libraries on + abort due to missing MCC modules. + 20061028 jl - Bugfix: defpicture.pvplugin opened scalosgfx.library twice. + 20061023 jl - Bugfix: Dropmenu did ask separately for each one if multiple + icons were dropped. + 20061022 jl - Bugfix: it was not possible to turn off thumbnails. + +41.4 20061003 jl - Improvement: Added optional drop menu to allow comfortable selection + between copy, move, or create-link operation. + - Improvement: Added optional icon images for popup menus. + 20061001 jl - Bugfix: errors on link creation were never reported. + - Improvement: In German translation, replaced all "link" by "Verknüpfung". + 20060912 jl - Improvement: Added single-window lasso mode, with scrolling window contents. + This mode is invoked by dragging mouse with configurable qualifier key. + 20060829 jl - Bugfix: Text icon selection was drawn incorrectly if "Name column selects + text icons" was on and window was scrolled horizontally. + - Bugfix: Text icon lasso selection used to ignore "Name column selects + text icons" flag. + 20060816 jl - Improvement: Added support for backfilled thumbnail icons, with + selectable color and transparency. + 20060723 jl - Improvement: lifetime of cached thumbnail icons is now configurable for + each drawer. Lifetime may now be set to "forever". + - Improvement: Added option to always generate square thumbnail icons. + 20060610 jl - Improvement: Added ability to scale background images without guigfx.library. + 20060528 jl - Improvement: Added new parameter options for menu CLI commands. + "%w" inserts path name of current window, + "%d" inserts device name of argument icons (useful for "eject" tool). + 20060516 jl - Bugfix: Corrected naming of Scalos main process "Workbench" - should + fix all remaining path inheritance problems. + 20060503 jl - Improvement: Added filetype-specific preview (=thumbnail) generation + plugin system. Standard defpicture.pvplugin behaves exactly like + previous build-in thumbnail generation. + - Improvement: Added jpegpicture.pvplugin thumbnail generator for JPEG + images. Thumbnails are generated 2 to 3 times faster than with + default thumbnail generator. + 20060425 jl - Improvement: Windows are now updated immediately when drag-drop + copying icons, moving icons, or creating links. + 20060423 jl - Improvement: Borders around tooltip bubbles are now drawn with + antialiasing (GFX card required). + 20060419 jl - Bugfix: Applying popup menus to all selected icons didn't work + with a single icon under the mouse pointer that + hasn't been selected before clicking RMB. + 20060418 jl - Improvement: Added new user setting to always apply popup menus to + every selected icon, regardless of qualifier. + 20060401 jl - Improvement: Added selectable transparency for tooltip bubbles. + 20060327 jl - Improvement: Clicking into startup splash window causes it to + close immediately. + 20060327 jmc - Added setting: Switch on/off the displaying of image thumbnails + to be shown if they have no icons. + 20060324 jl - Improvement: SQL tables are initialized each time the database is + opened, so the thumbnail database can be safely renamed or + deleted anytime, and Scalos creates new database next time a + drawer is opened. + 20060322 jl - Moved image scaling and dithering code to shared library scalosgfx.library. + +41.3 20060208 JMC - Little feature added from File Transfer Class about copy of volumes: + If a "disk" icon is located from the volume to copy and only if this icon type + is "WBDISK", the destination drawer icon's image to create will be exactly + the same, instead to use the "def_drawer" icon's image. + 20060203 JMC - Improvement: Objects without icons aren't removed automatically from + desktop until Scalos main window is updated or until all + is updated("UpdateAll" command). + 20060202 jl - Bugfix: A race condition sometimes crashed Scalos when one of the + filetype descriptions was updated. + 20060128 jl - Improvement: Added new internal command "createthumbnail". This + command manually creates an icon thumbnail for any image and saves it. + 20060125 jl - Bugfix: Due to race condition between SetMenuStrip/ClearMenuStrip + and OnMenu/OffMenu, enforcer hits could occur on startup. + Added MenuSema protection for menu of/off. + - Improvement: (information.module) Added new settings "Start + priority", "Wait until finished", and wait time (only for tools + located in SYS:WBStartup or any subdirectory). + 20060121 jl - Improvement: Prefs flag "auto-leaveout" now also has "auto-putaway" + functionality, i.e. dragging a left-icon back into its native window + automatically issues a "put away" command. + 20060119 jl - Bugfix: Text window auto-update failed to recognize changed entries if + time difference was less than one minute (ds_ticks was not checked!). + 20060117 jl - Bugfix: In striped text windows, background color of selected + entries was incorrect. + - Bugfix: changing view mode (show all vs. show only icons) + during reading of icons sometimes caused incomplete display of icons. + 20060115 jl - Improvement: Added user-selectable layout direction for each icon + type, separate for desktop and standard icon windows. + 20060106 jl - Bugfix: window area offsets wt_XOffset and wt_YOffset are cleared + if window is opened in backdrop mode or is switched to backdrop mode. + 20060101 jl - Bugfix: long-standing bug - under certain circumstances, window + refresh while icon update was in progress could cause + input.device to block, and entire machine to hang. + - Bugfix: removed potential input.device semaphore deadlock while + moving window scrollers. + 20051225 jl - Improvement: For MorphOS, added patch for WBInfo workbench library + function, which doesn't work otherwise. + 20051223 jl - Bugfix information.module IsDevice() didn't work on MorphOS + with USB memory stick, causing "information" to fail. + 20051215 jl - Bugfix: Redesigned recognition of modified preferences files. + Fixes all problems recognizing unchanged prefs, and should resolve + lockup problems when changed prefs are applied. + 20051207 jl - Improvement: Added support for global trashcan to + Empty_Trashcan.module, as defined and selected in delete.module. + 20051206 jl - Improvement: Initial version of MUI-based Empty_Trashcan.module. + 20051203 jl - Bugfix: In text windows, name field width calculation + didn't take left window border into account. + 20051202 jl - Bugfix: inherited path of parent process was not used under MOS. + The code tried to find the Scalos initial process named "Workbench", + and that didn't work with MorphOS. + jl - Bugfix: pressing RMB while moving around windows caused MorphOS version + to stay in "window move" mode until reboot. + 20051121 JMC - Bugfix from "prefs.c": Use of screen title mode "Permanently hidden" + option didn'twork correctly and was disabled by MCP screen menu. + - Bugfix from "prefs.c": Use of "Mark Icon Under Mouse" option didn't + work, was only availlable after a reboot. + 20051119 JMC - Bugfix from "IconWindowClass.c": After change of new icon window + font (non TrueType),icons's labels on desktop(devices, left-out icons) + weren't updated. + +41.2 20051015 JL - Eliminated artificial "MaxWBArgs" (= 64) limit for WBArgs[]. + Now number of selected icons is actually counted, and count + is used to allocate WBArgs arrays. + 20051014 JL - Bugfix: striped text windows wre not refreshed correctly + beyond rightmost text icon column. + 20050909 JL - Improvement: mcpgfx.library is no longer required. + 20050903 JL - Bugfix: File operations with multiple selected sources displayed + incorrect remaining time. + - Bugfix. (Rename.module) could not rename orphaned + icons (icons w/o object). + 20050902 JL - Bugfix: FileTransClass returned wrong error code when an error + was encountered while copying objects, and "replace all" has + been selected. + 20050901 JMC - BugFix: (Rename.module) Under "Viewbyicons" view mode, + icons name without objects weren't returned. A error DOS was occurred. + 20050828 JL - Bugfix: incorrect first WBstart parameter wa_Lock for project + icons caused dnetc client to start in command line window. + - Improvement: Thumbnails are now generated in 256 (or less) colors + for icons that don't support true color, e.g. glowicons or newicons. + - Bugfix: double-clicking icons during thumbnail generation + now works. + - Improvement: Scalos now tries to always generated thumbnails + for visible icons first. + - Bumped revision to 41.2. + JMC - News "Copyto" and "MoveTo" menu commands added. + +41.1 20050729 JMC - Execute_Command.c: Bugfix, a wrong path was returned to the path + string buffer. + Fixed window width according to 30% from screen width. + - Rename.c: Improved, string gadget is now activated when applying + or skiping the renaming command. + Fixed window width according to 30% from screen width. + - NewDrawer.c: Fixed window width to 30% from screen width. + 20050717 JMC - Bugfix: Copying a icon image, IconProperties module didn't copy + ToolTypes from old icon to the new icon. + 20050701 JL - Improvement: Scalos now can generate thumbnail views of + any image in a drawer. For PNG icons, thumbnails can even be + saved. Thumbnails currently only work with a Gfx card on a + Workbench screen of 65535 or more colors. We hope to get + thumbnails working for standard screens, too, in the near future. + 20050629 JMC - Information.c: Removed "SetAttrs" WBPROJECT's type for iconobj + when ".info" was stripped from its name(e.g. from Textwindows). + Function wasn't appropriated for all others icons type. + 20050627 JL - Improvement: Newdrawer.MUI module 40.4 - Module now uses + iconobject system for new default drawer icon, thus + PNG icons can be used on AmigaOS3.x. + 20050626 JL - Improvement: Added two new Scalos library functions. Therefore, + Scalos version was bumped to 41.1. + 20050618 JL - Bugfix: Added workaround for MorphOS EndNotify problem - after + "use" or "save" of Scalos prefs, some window patterns + were not refreshed. + - Added two new scalos.library functions, SCA_GetDefIconObject + and SCA_OpenDrawerByName. + + +40.34 20050611 JL - Bugfix: drag-copying a folder onto another folder of same + name on desktop, but located on another volume wasn't possible. + 20050521 JL - Improvement: Added new menu commands "showdefault" + and "viewbydefault". + 20050515 JMC - Updated: Installer script according to news default prefs "Pages" and + "Modules" themes used by "Scalos Prefs"(since version 40.16). + 20050511 JMC - Added: MUIA_ExportID for NewDrawer and Execute_Command modules, + loading/saving from/to "ENV:MUI" string content(Execute_Command.c only) + and CheckMark objects's states. + - Added: "MUIA_Window_Width, MUIV_Window_Width_Screen(45)", + for "NewDrawer.module" decreasing window width at startup. + 20050503 JMC - Added: Functions to Iconproperties.module replacing + icon by Drag & Drop and replacing icon image by the + default icon image. Same functions than + Information.module. + - Bugfix: Installer scipt didn't isntall window, desktop + background images and "def_Iconify.info" icon with + "expert mode" user level. + 20050502 JL - Bugfix: name of device icons wasn't updated after + formatting the drive. + 20050502 JMC - Improvement: Made localizable string for "NDOS" disks. + 20050501 JMC - Added: OpenURL support for Execute_Command.module. + 20050430 JMC - Bugfix: Installer script installed German default preferences + for all but French country setting. + 20050428 JL - Bumped revision to 41.1. + +40.33 20050423 JL - Improvement: Scalos window popup menu is suppressed over + depth-arrange gadgets. This allows MorphOS popup menu + to work again. + 20050422 JL - Bugfix: changing selected icon with cursor up/down keys in + text windows caused window contents to shift to rightmost position. + 20050418 JMC - Improvement: Heavily improved installer script. Now all + required components are installed, and first-time installation + works as expected. + JL - Bugfix: Under rare circumstances, icons were positioned + incorrectly on desktop. + - Bugfix: resizing simple-refresh windows during automatic icon + update caused icons to be drawn outside window interior, + trashing window borders and causing crashes. + 20050417 JL - Bugfix: Added workaround for WinUAE - Scalos crashed + on startup as WB-replacement. + 20050411 JL - Bugfix: disk icons were saved with incorrect name. + - Bugfix: "unsnapshoticon" didn't work with device icons. + 20050409 JL - Bugfix: Internal command "cleanup" was broken due to recent + cleanup redrawing optimization. + 20050406 JL - Bugfix: Unsnapshotting multiple icons caused semaphore deadlock. + 20050402 JL - Bugfix: PNG images with transparent background were not + displayed correctly as splash and about logo. + 20050402 JL - Bugfix: Added checking for mupltiple instances of left-out icons. + - Bugfix: Installer script erroneously installed German default + preferences for all languages other than German or French. + - Bumped revision to 40.33. + + 40.32 20053027 JMC - Added: New window title bar's refreshing setting. Screen + and window title bars are refreshed separately. + 20050326 JL - Fixed: OpenDrawerByName.c. OpenDrawerByName failed to open + drawers without icons. + - WindowClass.c: prefAutoCleanupOnResize now is only honored + for "view-by-icon" windows. + - WorkbenchControl.c, wb39.c, wb39.h: Added check for + NULL ws_Lock in CloseWorkbenchObjectA(). + Fixed leak in IsOpen() which could leave Scalos window list + locked on exit. + - Added more safeguards against use of invalid ws_Window pointer: + (1) In WindowClass.c, ws_Window is cleared just BEFORE the window + is really closed (just like wt_Window). + (2) In Window.c, LockedSetWindowTitles() checks if its "win" + parameter is one of Intuition's windows on the Scalos screen. + 20050325 JMC - IconProperties.c: Inserted path name gadget inside + ScrollGroupObject(). + - WindowProperties.c: Inserted path name gadget inside a + ScrollGroupObject(). + JL - Added Files: guigfx.library.elf mcpgfx.library popupmenu.library + preferences.library render.library.elf. + Added new directory with binary-only libraries + (required or recommended for Scalos operation). + 20050321 JL - Class.c: Added locking of WindowSemaphore to CheckUpdate functions, + in order to window from being closed until update finished. + 20050319 JL - InputHandler.c: Added missing check for NULL iwtUnderPointer. + Added: new modules "InputHandler.c". + Redesign of popup menu trigger mechanism - used to work with + IDCMP_MENUVERIFY, but that didn't work reliably under MorphOS. + Now a Scalos InputHandler is installed which watches all input + events, and causes popup menus to show up. + - Scalos.h: Added: new message type SM_DoPopupMenu. + 20050318 JMC - Information.c: Added method "MUIM_WriteLong"returning + "RESULT_HALT" when "CancelButton" is pressed. Now size + calcutation is aborted and application can quit, so like + closing the window. + 20050317 JMC - Information.c: Added hook function to abort size calculation. +  Added "MUIM_WriteLong" method, closing the window a + "MUIM_WriteLong" method set "Result = RESULT_HALT" + to abort size calculation before to quit application. +  - Fixed: Added "const char versTag" variable, "TextVersion" was + sometimes buffer. + 20050313 JL - MenuCommand.c, WindowClass.c, idcmp.c: Added updating of + icon list at end of IDCMP_CHANGEWINDOW handler. + "resize to fit" failed to update the icons when increasing + window size. + - Information.c + Bugfix: Icon position was lost when image + was replaced. + Bugfix: PNG icons lost DrawerData information when + image was replaced. + 20050312 JL - MenuCommand.c: After "unsnapshot" menu command, icon is + automatically repositioned (just like "cleanup"). + - IconobjectMCC.c: Added capability to replace iconobject via + SET method. + - Information.c: Added drop-replacement of icon images. + Added menu item "default", to replace icon image by default icon. + Added recursive directory scanning for devices. + Added button to count files/drawers/bytes for devices. + - IconobjectMCC.c: Added capability to replace iconobject via + SET method. + - MenuCommand.c: After "unsnapshot" menu command, icon is + automatically repositioned (just like "cleanup"). + 20050309 JL - Activated "auto-leavout" feature. Corrected handling of + "INF_SupportsSnapshot" and "INF_SupportsUnSnapshot" flags + on automatic icon update. + - iconobj.c: Adapted IconProperties.module and + WindowProperties.module for MorphOS/PPC. + 20050305 JL - Added new feature "Highlight icon under pointer". + 20050227 JL - Information.c: Improved handling of icons without associated + files/drawers. + 20050209 JL - Adapted IconProperties.module and WindowProperties.module + for MorphOS/PPC. + - TitleClass.c: Added PPC CPU types for MorphOS. + - DeviceWindowClass.c: Added correct setting of in_SupportFlags + for Ambient shortcut icons. + 20050202 JMC - TextWindow: Files were not updated after change of date and + time. "Class.c" updated. + 20050130 - TextWindow: Files were not updated after change of protection + bits. "Class.c" updated. + 20050122 JL - Bugfix: After change of Scalos prefs, text window font (non + TrueType) was no longer recognized, and screen font + was used instead. + 20050110 JL - After unsuccessful try to quit Scalos (because some + application still has scalos.library open), creation of + new Scalos subprocesses didn't work anymore, e.g. it was + not possible to open the "about" window. + 20050105 JL - Improved Drag&Drop : Transparency with icon alpha channel + is now also fully supported when multiple icons are dragged. + 20050102 JL - Finally found and fixed long-standing bug that caused + Scalos to crash on exit (scalos.library expunge function + was called twice, and tried to FreeMem() incorrect pointer). + 20041202 JMC - Added variable for support hidden files(via FIBF_HIDDEN) + in "DeviceWindowClass.c","Class.c","ScanDir.c". Now this + support is switchable from "Scalos Prefs". + 20041128 JMC - Added support for hidden files(via FIBF_HIDDEN). + 20041126 JMC - Added WBGARBAGE diskobject for "AsyncPasteProg()" function, + in "MenuCommand.c". Now objects can be copied into traschcans + via popupmenu command "paste", before objects were copied into + parent of trashcans. + 20040917 JL - Bugfix: simple-refresh window redraw failed when + issueing some menu commands, e.g. "open parent". + 20040908 JL - Bugfix: renaming left-out icons sometimes caused random + memory to be trashed. fixed. + - Bugfix: renaming left-out icons caused Scalos processes + to hang due to semaphore deadlocks. + - Bugfix: cured semaphore deadlock that sometimes occured + when automatic window update collided with some user + action, e.g. opening a popup menu. + 20040828 JL - Bugfix: with TrueType fonts, having one softlink in a + text window caused all entries to be displayed underlined. + - Added new internal commands "iconproperties" and + "windowproperties" (Requires iconproperties.module + and windowproperties.nodule). + - Bugfix: drag&drop left garbage on screen if custom bob + routines were used and "special" bob (e.g. "forbidden" + or "copying") was visible and was larger than main bob. + 20040716 JL - Added new qualifier during D&D to force moving of + file system objects (instead of copying). + - Implemented the long-planned "Create link" on D&D feature. + - Bugfix: default icons were not shown transparent if + D&D "real transparency" wasn't turned on. + 20040625 JL - When copying icons, the "replace all", "skip all", + and "abort" buttons of the overwrite request didn't work. + 20040612 JL - Automatic update of windows caused enforcer hit and + crashes if the modified files containes special + pattern-matching characters in their names (e.g. "()[]#?|"). + 20040602 JL - Fixed long-standing bug that caused Scalos to lockup + when an icon was selected while a new window was + initially reading its icons. + - About dialog sometimes opened with maximum screen width, + but without any contents in the scrolling field. Fixed. + 20040527 JL - Closing an icon window while it was initially reading + its directory caused Enforcer hits and crashed + Scalos. Fixed. + 20040523 JL - Added TrueType font support. TT Fonts can be used for + icons, text windows, tooltips, and the "About" window. + 20040519 JL - Menu selection "leave out" (not from popup menu) + caused enforcer hits when issued from "View all" + text window. Fixed. + 20040425 JL - Added CRC checks over prefs files. Now writing + a prefs file only causes re-reading of prefs and + reinitialization if file contents has actually changed. + 20040424 JL - Disk Read-Only status display is now updated when + disk is inserted. + 20040419 JL - Icons without associated object were displayed + incorrectly after window update. Fixed. + - Bumped revision to 40.32. + + 40.31 20040322 JL - Default icons were not recognized on main window. This + bug could show up after dragging default icons from + some drawer window onto the desktop. + 20040221 JL - Improved caching of filetype descriptors. With "env-handler", + all filetypes were flushed from cache whenever a new + filetype was loaded from ENVARC: to ENV:. + 20040216 JL - Internal command "reset" didn't work correctly. Fixed. + 20040214 JL - Icons were not updated correctly after change of file + comment of rename with change of case + only (e.g. "amiga" to "Amiga"). + 20040211 JL - Icon selection marks for popup menu could be drawn in + incorrect window when "Apply to every selected icon" + is enabled. + - Fixed various problems with left-out icons (different + icons with same name were not handled correctly, + left-out icons were not updated as intended). + 20040210 JL - "Mac-like selection" was broken. Fixed. + 20040206 JL - "Snapshot window" didn't work if there was no + icon present for window. + 20040126 JL - Main window didn't allow multiple icons with same + name (e.g. left-out icons from different paths). Fixed. + - Bumped revision to 40.31. + + 40.30 20040123 JL - In "view all" text windows, "Leave out" icon "xxx" now + removes both "xxx" and "xxx.info" from text window, and + "Put away" causes both entries to reappear. + - Now text window SCCM_IconWin_ReadIcon method correctly + handles increase in column width. + - All "cleanup**" menu commands are now disabled + in text windows. + - Fixed enable/disable state of "leave out" and "put away" + menu commands for "view all" text windows. + - "selectall" menu command is now disabled if + all icons are selected. + - "clearselection" menu command is now disabled if no + icon is selected. + 20040122 JL - Text windows now automatically update object associated + entries if an icon is removed or added. + 20040118 JL - Fixed internal locking during reading and parsing + of Scalos filetypes descriptions. + - AppIcons no longer can get "Default Icon" attribute. + 20040111 JL - Default icons may be drawn with adjustable + degree of transparency. + - Added support for MorphOS-style iconify gadgets. This + fixed any visual distortion of iconify Gadgets under MorphOS. + 20040109 JL - When loading default icons, Scalos now adds information + about the original object (Path+Name) for usage by + the iconobject datatypes. + 20040105 JL - Made icon dd_Flags handling more flexible, so OS3.9 CD + drawers open with correct viewmodes (WB handles + invalid values of "3" like DDFLAGS_SHOWALL). + - Scalos didn't handle default icons from icon drawer + (e.g. def_drawer.info) correctly. Without separate + DefIcons installed, only the icon.library built-in + icons were used. + 20040104 JL - Added "skip all" gadget to standard copy/move + "replace" dialog. + - Fixed enforcer hits/crashes when starting Scalos + while Scalos is already running. + - Added new ScalosControlA() tags + SCALOSCTRLA_GetCopyBuffSize and + SCALOSCTRLA_SetCopyBuffSize. + 20040101 JL - Added preferences item to set default stack size. + - FileTypes code assumed that popupmenu.library was open, + leading to crashes on machines where that library was + not installed. + - Bumped revision to 40.30. + + 40.29 20031230 JL - Added full support for alpha channel icon drawing, + including drag&drop ("Custom" bob routines only). + - Memory for default action in filetype descriptions was + freed while not in use. Fixed. + - Filetype descriptions are now cached, in order to + improve performance. + - Starting WB programs left 2 locks dangling. Fixed. + 20031226 JL - updated "%os" title function to recognize OS 3.5 + and OS 3.9. + - Made localizable string for "BUSY" disks. + - Popupmenu items now show default action (the action + that is taken upon double-click) in bold text. + 20031222 JL - Optimization of Drag-and-Drop bobs was broken, leading + to very sluggish drawing of bobs when dragging + multiple icons. + 20031208 JL - Changed directory for Scalos filetype descriptors + from "Scalos:FileTypes/" to "ENV:Scalos/FileTypes/". For + compatibility, Scalos still looks in the old place if the + new directory cannot be found. + 20031202 JL - In Text window, icon update erroneously changed type + from "WBGARBAGE" to "WBDRAWER". + 20031117 JL - Fixed incorrect update of icons in text windows + in "view all" mode. + 20030727 JL - To provide a visual hint that popup menu commands only + apply to the icon under the pointer, all other selected + icons are temporarily deselected while the popup menu + is open. + - Added keyboard qualifier to apply popup menu commands to + every selected icon, instead of only the icon under + the mouse pointer. + 20030711 JL - Fixed long delay upon startup when splash window was + turned off. + - Bugfix: selecting an icon in one window, then changing + to another window, and hitting "enter" caused Scalos + to crash with "invalid semaphore state" errors. + 20030628 JL - Fixed several memory leaks associated with + filetype-dependent popup menus and tooltips. + 20030618 JL - In Window popup menus, "view by text/name" never + displayed a checkmark. + 20030616 JL - Drawers opened from text view windows did not correctly + inherit the "view all" attribute. + - Corrected minor typo in About window "100%" was lacking + the percent sign. + 20030615 JL - Bumped revision to 40.29. + + + 40.28 20030612 JL - Major improvement in text view window update - now works + the same way as icon window update, only the changed + items are redrawn. + 20030531 JL - Bugfix; In text view windows, it was erronously + possible to "snapshot" and "unsnapshot" icons. + 20030529 JL - Bugfix: In text view windows, no file comments + were displayed. + 20030525 JL - In text view windows, Scalos had problems recognizing + default tool entries for project icons. Fixed. + 20030517 JL - Text icon IDTA_Type returned wrong icon type + for WBGARBAGE (Trashcan) icons. + 20030502 JL - Major improvements to SCA_OpenIconWindow(). Now Scalos + tries hard to find the appropriate icon for the window + to be opened. If an icon is to be found, the window + settings are taken from the icon. + 20030423 JL - Text windows didn't recognize window resize events + during reading of icons. Fixed. + 20030421 JL - Rewrote context-sensitive disabling of menu items. + 20030420 JL - Added requester to ask user what to do when a project + icon without default tool is encountered. + - Added Polish catalog to developer archive, translation + by Paweî Szczodry. + 20030418 JL - Fixed file count routine in filetransclass. The bug + caused incorrect calculation of total byte/item count + and lead to display of more than 100% completion with + nonsense values for "remaining time". + - Removed display of every single item copied in + filetrans copy/move requester. This optimization greatly + improved copying speed. + 20030327 JL - Added new method "SCCM_FileTrans_OverwriteRequest" + for FileTrans.sca class. + 20030301 JL - Bugfix: Filetype wasn't set correctly for trashcan. + - Bugfix: AsyncWB hook wasn't called correctly + for "Empty Trashcan". + 20030218 JL - Bugfix: Program name wasn't handed over to + execute_command.module on icon double-click. + 20030216 JL - Bugfix: Improved window clipping, now application-drawn + AppIcons no longer draw across non-backdrop Workbench + window border. + 20030211 JL - Bugfix: When a drawer window was created in iconified + state, it could not be uniconified by double-clicking + its parent drawer. + 20030208 JL - Bugfix: In 40.27, WBStartup execution of ARexx type + icons was broken. Fixed. + - Feature: Added display of estimated remaining + time to file copy/move progress dialog. + - Bumped revision to 40.28. + + 40.27 20030130 JL - Bugfix: Window backfill pattern re-layout didn't occur + when "backdrop" was turned on and off. + 20030129 JL - Bugfix: fixed enforcer hits/crashes during window + zoom/resize when "always relayout" was enabled (code + tried to use ptn_bitmap after FreeBitMap()). + 20030126 JL - Bugfix: added locking mechanism for asynchronous + backfill to avoid crashes when windows are closed while + async backfill process hasn't finished. + 20030118 JL - Bugfix: fixed enforcer hits when CLI project icon + contained no default tool. + - Improvement: Program list now contains full path for + each program started instead of only program name. + - New feature: Added SCA_ScalosControl() subcommand to + get/free list of menu commands. + 20030111 JL - Bugfix: Cut+Paste didn't work when AsyncWB was + installed. Fixed. + - New features: Added new FONT and VALIGN attributes + to TOOLTIP STRING. + - Bumped revision to 40.27. + + 40.26 20030104 JL - Bugfix: "about" produced 2 enforcer hits when no + Scalos logo found. + - Bugfix: Splash resizing / text positioning was broken + when no Scalos logo was found. + - Bugfix: window process hung when one of the standard + modules could not be started. + 20030103 JL - Bugfix: Snapshotting a window which had no icon created + an ".info" instead of an icon with the drawer's name. + - Bugfix: Windows with virtual width or height > 32768 + could produce problems from graphical screen + corruption to system crash. + 20030102 JL - New feature: Icon tooltips can now be user-defined in + the file type description files. Scalos now supports + file type information plugins, e.g. to display size + information about image files. + 20021221 JL - Bugfix: During file copy operations, icons could be + overwritten without warning. + 20021209 JL - Bugfix: TextInputHook wasn't used to run program + without icon - instead always execute_command.module + was called. + - Bugfix: automatic disabling didn't work for some + main menu items (e.g. "sizetofit" didn't get disabled + in backdrop root window). + - Bumped revision to 40.26. + + + 40.25 20021206 JL - Added "viewbytype", "cleanupbyname", "cleanupbydate", + "cleanupbysize", and "cleanupbytype" menu commands. + 20021205 JL - Fixed Enforcer hits which occured when an ARexx program + ended that had been started from an icon window, and + the icon window had been closed. + 20021130 JL - Added support for cyling through icons in window + via TAB key. + - Rebuilt about window code to make use of the + TT layout engine. + - Fixed bug in SCA_SortNode() - lists with less than + 3 entries were not sorted. + 20021116 JL - Fixed broken close-window abort recognition during + GenerateIcons() icon drawing in window. + 20021019 JL - The user-defined path for default icons was never + used for iconified Scalos window icons. Now it is taken + as fall-back if there are no theme-specific icons. + 20021018 JL - Changed sizing method for splash window. + 20021014 JL - Added new methods SCCM_AddToClipboard and + SCCM_ClearClipboard to root class. + 20021013 JL - Copy/paste didn't work for volumes/disks. Fixed. + - Fixed another source for erroneous error messages + during SCCM_FileTrans_Copy and SCCM_FileTrans_Move + operations. + 20021009 JL - Changes in icon font were not recognized in desktop + window. Fixed. + - The menu "copy" and "paste" commands trashed the + destination file name. Fixed. + 20021008 JL - Fixed some enforcer hits and crashed when selecting + some device icons, and then pressing "enter" twice. + 20021006 JL - Changed location of icons for iconified Scalos window + from "ENV:Sys/def_iconify" to "THEME:window/def_iconify". + - LoadWB.scalos now waits until Scalos opens its first + window on the Workbench screen before exiting. + - Now Scalos first tries to load deficons from + "THEME:DefIcons/". If that fails, the standard + path "ENV:Sys/" is used. + 20021003 JL - Now uses "titlebarimageclass" for iconify + image if available. + - changed all makefiles to work with GNU make. + - Bumped revision to 40.25. + + + 40.24 20021003 JL - Fixed broken ARexx menu command support. + 20021003 JL - Major improvement of Tooltip layout engine. + - Added tooltips for several Scalos gadgets, including + the status bar images. + 20020929 JL - Fixed menu bug where every menu item got a hotkey + mark. Now only the menu items which have got hotkeys + are shown with hotkey marks. + - Icon positions were messed up during "cut", "copy" + and "paste" operations. Fixed. + - Changed file name for default device icons from + ".info" to "def_.info" in + order to match OS3.9 behaviour. + - Changed file name for default volume icons from + ".info" to "def_.info" in + order to match OS3.9 behaviour. + - Added missing SHADOWPEN vertical line to the left + of the window iconify image. + - The assign "THEME:" isn't touched any more if + it exists prior to Scalos startup. + - The assign "Scalos:" is created (pointing to PROGDIR:) + on startup if it doesn't exist. + - Tooltips are no longer displayed if ICandy == 0. + - Bumped revision to 40.24. + + + 40.23 20020928 JL - Improved handling of "cut" icons (shadowed display got + corrupted). Needs iconobject.datatype 40.7 . + 20020926 JL - Fixed bug that caused Scalos to crash when an icon + was removed during Drag&Drop (e.g. an AppIcon was + removed by its application). + 20020923 JL - Changed default setting for icon frame type from + MF_FRAME_BUTTON to MF_FRAME_NONE. + 20020921 JL - Moved special pointer icons ("forbidden", "copying", + "makelink") from ENV:Scalos/ to THEME:PointerIcons/. + 20020915 JL - Environment variable "scalos/icandy" is recognized + if set before Scalos startup. ATM, icandy < 2 turns + off splash screen and window status bars. + If not set, "Scalos/icandy" gets set with a default + value of "2". + 20020914 JL - Changing "Fullbench" and "Poptitle" now works + on-the-fly and doesn't require rebooting anymore. + - Locale (language) preferences can now be changed + on-the-fly, no reboot required anymore. + 20020913 JL - Fixed erronous message "This drawer cannot be opened" + when trying to open a drawer which is already open. + 20020831 JL - Icon position now always is set to NO_ICON_POSITION + for default icons loaded via DefIcons. + 20020825 JL - Changed default for Workbench "backdrop" to TRUE. + - Changed tool tip placement - now tool tips are displayed + below mouse pointer if space allows. + 20020822 JL - Added optional process priority field for filetype + specific popup menu commands. + 20020817 JL - Bugfix in FileCommands.c: since ExNext() result + ERROR_NO_MORE_ENTRIES was erronously remembered as + error, an incorrect error reason could be displayed + when a "real" error occured. + - Bumped revision to 40.23. + + + 40.22 20020812 JL - Bugfix with "Show All" windows: icon list was read + before window was opened, leading to problems with + icon layout (invisible icons). + 20020803 JL - Fixed problems with file type-specific popup menus + and STACK parameter. + 20020801 JL - Finished conversion of Scalos Pattern Prefs + from ASM to C. + 20020720 JL - First implementation of new filetype-specific popup + menu system. + - Removed obsoleted scalos.library + function SCA_RemapBitmap(). + 20020711 JL - CheckMouseIcon() didn't take window borders into + account, i.e. clicking on window border could cause + icon to be selected. + 20020703 JL - Text icon font changes now take effect immediately, + Reboot is not required anymore. + 20020624 JL - Fixed problem in wbl.c - spawned processes incorrectly + inherited the ConsoleTask pointer. + 20020623 JL - Now SCCM_IconWin_Redraw also refreshes window frame + and status bar. + 20020622 JL - Added image "THEME:Window/StatusBar/ShowAll" to status + bar, which visualises the "Show All Files" window + setting. + 20020612 JL - Fixed bug introduced by optimized pen allocation. + 20020601 JL - Improved pen allocation in LockScalosPens() - pens + which are members of dri_Pens are no longer allocated + a second time. + - Upon startup, Scalos should give a warning Requester + if not all defined pens could be allocated. + 20020529 dm - Finished converting cleanup code to C. + 20020526 JL - Fixed bug in the scalos.library expunge code which was + trying to FreeMem() an incorrect library base pointer + when quitting Scalos. + - When "quit Scalos" is requested, memory is flushed + before checking scalos.library open count, so unused + libraries still resident in memory no longer prevent + Scalos from closing. + - Added optional background image for tooltips + "THEME:TooltipBackground". + - Added optional background image for window status bar + "THEME:Window/StatusBar/Background". + - Added forgotten "PDTA_DestMode, PMODE_V43" in about.c + and GadgetBarImageClass.c. Now the entries for the + Scalos processes in "PicTD" prefs are no longer required. + 20020525 JL - Fixed a serious bug in the new C SCA_MoveNode() function + which caused Scalos to crash when trying to "cleanup" a + window which had already been cleaned up. + 20020513 JL - Fixed an icon drag bug: When an icon was clicked with LMB + and the mouse button held for several seconds without + moving the icon, a DisplayBeep() was triggered when the + mouse button was released. + 20020504 JL - Many minor changes to allow Scalos to cpiled with GCC. + - Replaced handmade CLI startup detaching code by standard + cback.o and detach.o mdoules. + 20020414 JL - Corrected error in scalos_lib.sfd - order of parameters + for SCA_WBStartTags() was incorrect. + 20020412 JL - When icons were selected purely via keyboard, the + "IconActive" variable was not updated and selected + icons could not be opened by pressing "return". + - When trying to open an disk/drawer icon via wb39/ARexx, + under certain circumstances the Scalos main task could + hang, waiting for a message reply. Fixed. + 20020405 JL - When prefEnableSplash was turned off after splash window + has opened, the splash window never closed. Fixed. + - After removing an entry from the hidden device list, + that device used to appear multiple times on the Scalos + screen. Fixed. + 20020404 JL - When AppIcon was replaced via AppChange, Scalos tried + to free invalid memory while removing AppIcon. Fixed. + 20020403 JL - ScalosMain() was called with seglist in d1 instead of + d0, leading to enforcer hits or crash on exit when + started from workbench via icon double-click. + - Bumped revision to 40.22. + + + 40.21 20020402 JL - Fixed lockup problem when a window opened or closed + during drag/drop operations. + 20020329 JL - Fixed problem in scalos library code - Expunge() never + got called. + - Fixed init problem with prefTextModeTextAttr.ta_Name, + after unsuccessful startup, Scalos tried to + FreeVecPooled() static string. + - Added safeguard to AllocVecPooled() and FreeVecPooled() + against being called with MemPool of NULL. + 20020309 JL - SCCM_DeviceList_Generate now works fully asynchronous way, + avoiding most sources of hangs connected to weird + file systems. + 20020212 JL - Finished converting Scalos startup and shutdown code to C. + 20020209 JL - DefIcons support now integrated into Scalos, including + automatic reload of DefIcons.prefs after + external changes. Filetypes.plugin and Deficons.plugin + are now obsolete. + 20020204 JL - Programs started by Scalos were never removed from the + internal program list. Fixed. + 20020203 JL - Now displays message on screen title when user tries to + double-click a drawer icon without associated directory. + 20020202 JL - ToolTip sometimes didn't show used/total/percent + correctly for disk icons. Fixed. + - Bumped revision to 40.21. + + + 40.20 20020201 JL - Dragged icons were corrupted on screens with + interleaved bitmaps. Fixed. + - Dragging icons with text didn't always work, depending + on icon text colour settings. Fixed. + 20020127 JL - UnSnapshot function was thoroughly broken - Should now + again work as expected. + 20020126 JL - Now supports adding submenus and new menus + via SCA_NewAddAppMenuItem(). + - The Rename() patch now tries to update (i.e. remove) + the old object's icon. + - CopyCommand() now quietly returns OK if source of copy + operation cannot be found, so copying of orphan icons + (icons w/o associated objects) should work now. + 20020125 JL - Plugged memory leak when reloading menu prefs. + - Bumped revision to 40.20. + + + 40.19 20020121 JL - Snapshot/Unsnapshot didn't free Lock on icons. Fixed. + - Unsnapshot failed to move icon to wt_LateIconList. Fixed. + 20020119 JL - ReLayoutIcons() forgot to update IDTA_TextPenShadow and + IDTA_TextPenOutline pens. Fixed. + - SCA_ScreenTitleMsg() was broken and couldn't display + the last message. Fixed. + 20020115 JL - Fixed problem in DragDropBobs.c : newiconobject.library + didn't return image mask for special icons because + IDTM_Layout was only called for normal image and + IDTM_Mask_Selected was requested. Fixed. + 20020114 JL - Fixed problem with MOS and SameLock() NULL Locks in + Functions.c. Now it should be possible to open SYS: + volume. + - Bumped revision to 40.19. + + + 40.18 20020113 JL - Undid most changes in DragDropBobs.c from 40.17. Now + frames around icons work in a more compatible way, + together with 40.2 icon datatypes. + 20020109 JL - Commands "rename", "execute", "newdrawer" now support + global TextInputHook. + 20020107 JL - Built .sfd files for all Scalos components. All pragma + and proto includes and .fd files are now created + from those .sfd files. + 20020106 JL - Several window backfill functions didn't check properly + for non-existing background images (FileTransfer, + Splash). Fixed. + - INF_File was not set for text icons when file system + returned non-standard fib_DirEntryType. Now INF_File is + always set if fib_DirEntryType < 0. + - The PenArray delivered by the workbench OpenScreen patch + always contained -1 in the first entry, rendering it + pretty useless. Fixed. + - Adapted to now (NDK3.9) officially supported Workbench + hooks (CopyHook, DeleteHook, SetupCleanupHook). + - Now requires includes Release 45.1 to compile. + - "Empty Trash" menu command now uses DeleteHook + if available. + - The PenArray delivered by the workbench OpenScreen patch + always contained -1 in the first entry, rendering it + pretty useless. Fixed. + 20020105 JL - When changing icon attributes (e.g. border), AppIcons + didn't get refreshed properly. Fixed. + 20020104 JL - Automatic icon update on file system notification didn't + work properly for left-out icons. Fixed. + - Bumped revision to 40.18. + + + 40.17 20020101 JL - Added separate pens for selected icon text, icon text + outline, and icon text shadow. + 20011231 JL - Several changes in DragDropBobs.c to enable frames + around masked icons. Requires latest icon datatypes!!! + 20011229 JL - Device icons got a name of "" (empty string) when tool + type SCALOS_NOTEXT was found, whereas other + icons got NULL. Fixed. + 20011228 JL - When Scalos tries to quit and there were still foreign + windows on WB screen, a retry requester occurs. After + clicking "Retry", Scalos tried to free PenShareMap more + than once. Fixed. + 20011225 JL - Non-DOS disk icons are now ghosted (just like WB3.9). + - Many menu items (e.g. "Open", "Information") are now + disabled for non-DOS disks. + - Unreadable disks are now labeled as "DF0:Unreadable" + instead of "DF0:????". + 20011221 JL - OpenWorkBench() return ULONG instead of Workbench screen + address in case of success. Fixed. + - Window status bar text now always uses text window font. + 20011215 JL - Many changes and fixes in FileCommand.c (File + moving/copying code). Moving objects to a different + volume (copy-and-delete) now works. + 20011214 JL - Added timeout (default=10s) to file transfer counting. + - Added Win***s-like "Copy", "Cut", "Paste" menu commands + to transfer files. + 20011213 JL - Added workaround kludge for broken "delete.module" + implementations that rely on wa_Name being empty + for directories. + - Fixed a memory trashing bug in CLIStart(). Only occured + when file name was longer than default tool name. + 20011212 JL - LeaveOutIcon() trashed the CurrentDir of the Scalos + window task. Fixed. + - Scalos window tasks now have their directory namess + appended to the task name, + e.g. "Scalos_Window_Task ". + - (old) SCA_RemoveAppObject() failed to remove icons in + wt_LateIconList, leading to crashes with MUI + applications on CloseWorkBench()/OpenWorkBench(). Fixed. + - Added new pen for status bar text. + 20011208 JL - Popup menus now can also be opened by keyboard + (Right Alt +Right Amiga). + - SCCM_IconWin_CheckUpdate did not recognize changes + between default icon and non-default icon (e.g. an icon + associated to an object was deleted - display didn't + change). Fixed. + - Added optional THEME:FileTransBackground background + image to copy/move progress window. + - Display of window drop marks is now settable into 3 + modes - none, non-backdrop windows only, always. + - Added GBTDTA_SoftStyle to set text style + for GadgetBarTextClass gadgets. + - Bumped revision to 40.17. + + + 40.16 20011207 JL - Scalos.c/RefreshTextWindow didn't check if window + exists. Fixed. + - Scalos.c/ReportError didn't propagate RESULT_UserAborted + if the user clicked the "Abort" button. Should + be fixed now. + - Major rewrite of FileTransfer class. Redesigned + copy/move progress window with progress gauge and + cancel button. + 20011205 JL - Fixed another bug in window backfilling - filled area + was exactly 1 pixel too small in x- and y-direction. + - With window scrollbar arrows, the detection of shift + key was reversed. Fixed. + - Changed scrolling step for window scrollbar arrows + to 10 pixel. + 20011204 JL - Added SCCM_IconWin_AddToStatusBar, + SCCM_IconWin_RemFromStatusBar, and + SCCM_IconWin_UpdateStatusBar methods to make status bar + interfacing easier. + - More changes in OpenWorkBench() / CloseWorkBench(). Now + also uses icon.library V44+ ICONCTRLA_SetGlobalScreen + tag. Closing/reopening Scalos (e.g. via screen mode + change) should now work. + 20011203 JL - Rewrote OpenWorkBench() / CloseWorkBench() patches in C. + Problems with wrong colors after OpenWorkBench() should + now be fixed. + 20011202 JL - Added support for WB3.9-compatible (undocumented) + CloseWB hook. Now e.g. AmiDock iconifies automagically + on CloseWorkbench() and uniconifies afer OpenWorkBench(). + - With status bar enabled, Scalos window heights grew + each time a window was iconified and re-opened. Fixed. + 20011201 JL - Fixed broken FreePatternNode() - now reloading pattern + prefs should work again. + - Finally fixed long-standing bug in icon update code + that sometimes lead to duplicate icons. + 20011130 JL - Disk without icons now get default icon of type WBDISK + instead of WBKICK. + - Fixed problem with removed nodes in + SCCM_DeviceList_Generate, leading to corrupted device + icon list. + 20011129 JL - Added file version information to tooltips. + 20011128 JL - Implemented global copy and delete hooks for + compatibility with AsyncWB. + - Fixed inverted NoRemap checking in backfill functions. + 20011127 JL - Finished converting all menu functions to C. + 20011124 JL - Fixed wrong SCA_FreeNode() parameter + in DevListClass_Generate(). + - LockScalosPens() produces lots of enforcer hits when + no palette prefs could be found. Fixed. + 20011123 JL - Finished converting all IDCMP handlers to C. + 20011120 JL - Completed converting window background rendering + code to C. + 20011117 JL - Menu command "backdrop" didn't work. Fixed. + 20011116 JL - Fixed missing Argument for WaitReply() in A5. This + resulted in crashes when running modules with simple + refresh windows. + - Bumped revision to 40.16. + + + 40.15 20011113 JL - INF_File was not set for backdrop icons. Fixed. + - Devices are now counted and displayed separately + during D&D. + 20011112 JL - Changed screen pop-title algorithm so it should always + get switched on if necessary. + - Changed rendering of Logo in splash window back from + DTM_DRAW to blitting functions. + - Fixed error in DevListClass_Filter() - missing + parentheses lead to wrong exception calculation. + - Bumped revision to 40.15. + + + 40.15 20011112 JL - Changed path for status bar images + to "THEME:Window/StatusBar/". + 20011111 JL - Added SCA_NoStatusBar attribute to SCA_OpenWindow() + library function and SCALOS_NOSTATUSBAR tooltype to + suppress status bar display on a single window. + 20011110 JL - Fixed most serious error : failed to reserve memory for + IconWindowClass instance data. + 20011108 JL - Fixed wrong position for "iconify" gadget (overlapped + zip gadget). + - Horizontal scroller height was too small. Fixed. + - Added special detection of Screen titlebar to circumvent + problem with MagicMenu which lead to screen bar staying + visible in spite of cleared SHOWTITLE flag. + 20011107 JL - Added "Typing" symbol to status bar. + - Icon selection by typing icon name didn't work for + AppIcons and device icons. Fixed. + - Removed LockIBase() in Window.c/QueryObjectUnderPointer(), + hopefully avoiding window lockups. + - Converted automatic Screen bar switching code to C (see + Scalos_Cx.c). Added additional checks for locked Layers + to avoid deadlocks. + 20011106 DM - Added two new preference variables, prefWindowHScroll and + prefWindowVScroll for the default distances of scrolling + icon windows by the keyboard (main_prefs.s, variables.h, + imports.i, exports.i). + - Added parts of cleanup code converted to C to the source files + (cleanup.c, main_subroutines.s) + - Added two missing includes to scalos_structures.h file + (graphics/gels.h and workbench/startup.h) + - Can use shift+cursor keys in icon windows to scroll by a whole + page (well, inner height and width of icon window - IconWindowClass.c) + - Can also use Return to open active icon in icon windows + (IconWindowClass.c) + - Fixed problem with reading Workbench preferences and then showing + Scalos main window in wrong mode/sizes (WindowClass.c) + 20011104 JL - Icon menu didn't get enabled when icon was selected via + keyboard input (first letter(s) of icon name). Fixed. + 20011102 JL - Replaced blitting function in Splash.c by DTM_DRAW. + - Fixed old problems with pen allocations - ObtainPen() + didn't check for success. + 20011101 JL - Bumped revision to 40.14. + + + 40.13 20011020 JL - During D&D, window dropmarks are no longer erased when + mouse is over icon, but remain visible until mouse + leaves window. + - Added SCALOSCTRLA_GetEmulationMode tag + for ScalosControl(). + 20011013 JL - Now MenuItems get disabled if they have SubItems and + every SubItem is disabled. + - Since redrawing of partially overlapped icons seems to + work well, I disabled the strict icon overlap checking + while D&D. + 20011012 JL - Added support for AppIcons sending select/unselect + notification messages and + WBAPPICONA_NotifySelectState tag. + - CLIStart() didn't work with WBPROJECT icons. Fixed. + 20011011 JL - Icon window crashed after D&D when redrawing previously + obscured icons - Fixed. + - Sometimes IDCMP_INTUITICKS messages were not + replied. Fixed. + - Automatic change of default window patterns failed when + switching between icon and text mode. Pattern numbers + sometimes were treated as unsigned instead of signed + numbers. Fixed. + 20011010 JL - Added new Tags SCALOSCTRLA_GetTypeRestartTime and + SCALOSCTRLA_SetTypeRestartTime for ScalosControl(). + 20011008 JL - Menu commands "snapshotwindow" and "snapshotall" stayed + disabled forever. Fixed name compare error + in Prefs.c/CompareCommand(). + - Replaced remaining 64bit integer arithmetic code + by C version. + 20011007 JL - Finished converting "Title.sca" to C. + - Updated SCA_Title" autodocs for "Title.sca" class. + 20011006 JL - Finished converting "FileTransfer.sca" to C. + 20011005 JL - Replaced fixed version/revision strings in about window + by text macros "%v" and "%r". + - Added feature: Icons may now be selected by typing the + first character(s) of their names, just as in WB 3.9. + - Added feature: Cursors key can be used to select icon + right/left/below/above the currently selected one. + - Finished converting "DeviceList.SCA" to C. + 20011005 JL - Bumped revision to 40.13. + + + 40.12 20011004 JL - When converting WindowClass to C, I somehow dropped one + line of code and forgot to clear a window's UserPort + before closing the window. So it could happen that + IntuiMessages in the wt_IconPort already had got freed + by Intuition on closing the corresponding window, + leading to corrupted messages. + 20011001 JL - SCA_WBStart() didn't work for icons with "CLI" or + "REXX" tooltypes. Fixed. + 20010930 JL - Wbstartup sometimes skiped icons with free + positions (Unshapshot). Fixed. + 20010929 JL - Finished converting Root class to C. + 20010928 JL - Now all window, menu and wbl processes inherit the + original workbench path. + 20010926 JL - Added support for WBAPPMENUA_CommandKeyString (OS3.9) + and separator bars to SCA_NewAddAppMenuItem(). + 20010924 JL - Finished converting TextWindow class to C. + 20010922 JL - Finished converting IconWindow class to C. + 20010916 JL - Finally fixed long-standing problems with simultaneous + multiple window updates (Enforcer hits, icons + appearing twice, etc.). + 20010910 JL - Fixed problem reading large directories containing icons with + both fixed and free positions. Icons with "free" + positions were placed at the end of each block read, and + could be overlapped by an icon read later with a fixed position. + 20010908 JL - Bumped revision to 40.12. + + 40.11 20010907 JL - In Icon windows, icons without associated objects were not + displayed with "Show all files" setting. Fixed. + 20010906 JL - Text windows now show "Trashcan" in size column for + trashcan drawers. + - Icons of type WBDISK are hidden in text windows with + "Show only icons". + 20010904 JL - Major changes in text window directory scanning. Now + icons without associated object are displayed in text + windows with "Show only icons". + 20010903 JL - Text windows now show "Drawer" in the size column for drawers. + 20010902 JL - Changed number format for file sizes to "%lU", using localized + display format. + - Finished converting window class to C. + - Finished converting text icon class to C. + 20010901 JL - Deleting left-out object now always updates ".backdrop" files. + - Left-out icons got the "put away" menu item disabled when + updated (e.g. by adding tooltypes). Fixed. + 20010831 JL - Windows can now be scrolled with the arrow keys (only if no + icons are selected in window). + 20010830 JL - Did some changes to the asm class macros to make the class + engine more "C-friendly". + 20010828 JL - Moved Scalos .catalog files in archive from catalogs// + to catalogs//Scalos/. + - Now .catalog files are ignored if their version is <40, avoiding + trouble with wrong messages. + 20010819 JL - Added distinct pens for the dragging info text. + - Additional checks on plugin initialization - Now erroneously + added menu plugins should no longer cause Scalos to crash on startup. + - CloseWorkBench() from VisualPrefs Task didn't work. Fixed. + - CloseWorkBench() will not close Scalos while there are + active "Scalos_Async_Backfill" processes. + - Bumped revision to 40.11. + + 40.10 20010817 JL - Repaired bug in updateicon which sometimes caused icons to + appear in incorrect windows. + 20010815 JL - Duplicating/cloning items now pops up the file copying progress + window. + - Dragging multiple icons now shows one or two text lines under pointer + telling how many files and drawers are being dragged. + - Fixed severe bug in wbl.c : WBNode's were allocated with AllocVecPooled() + and freed with FreeVec(). + 20010814 JL - Added a varargs version of SCA_ScreenTitleMsg(). + - Added flag to switch between Flag: old dragging (all + icons visible) and new "icon stack". + - Added new SCA_ScalosControl() tags + SCALOSCTRLA_GetOldDragIconMode + and SCALOSCTRLA_SetOldDragIconMode. + - IconWinCheckUpdate() now correctly updates INF_DefaultIcon + flag and INF_SupportsLeaveOut attribute. + 20010811 JL - Missed a CurrentDir() when renaming objects, leading + to a directory lock getting never UnLock()ed. + - When D&D copying or moving icons, "Replace All" and + "Abort" now should work correctly. + - Message strings "xxx already exists" are now different + when moving and copying objects. + - When moving icons inside window and new position overlaps + other icon, the moved icons now jump back to their + original positions. + - Bumped revision to 40.10. + + 40.9 20010811 JL - THEME:SplashBackground was never freed, leaving a + Lock on it. Fixed. + - CLI and ARexx default tools icons didn't work + in text windows. fixed. + 20010809 JL - Enabled deadlock detection for lasso operations. + 20010808 JL - Additional check for NULL wt_LateIconList in cleanup(). + - Text windows now again display "#?.info" files (icons). + - Forbid drag-copying or -moving icon into own sibling + window or on sibling icon to avoid move errors + or endless recursion. + 20010807 JL - Fixed multiple problems with text window updates. + 20010806 JL - Added semaphore locking to protect from two or more Scalos + tasks opening or closing windows at the same time. + - Fixed broken "copy by dragging on drawer icon". + - Added additional checking to prefs file notification. + - Bumped revision to 40.9. + + 40.8 20010804 JL - Worked around semaphore deadlock in SetIconMenuOnOff(). This + one occured when copying multiple directories between + text windows. + 20010803 JL - Copying/moving of (left-out) drawers, tools, or projects + from main window to any drawer window didn't work. Fixed. + - Dragging a device icon into an icon window (copying device + into directory) no longer results in requester "DEVICE: + already exists ....". + - Bug #29 : Dragging a device icon into an icon window where + a drawer with the name of the device (w/o ":") already + existed: Nothing happened. Fixed. + - left-out icons no longer show up in text icon windows. + - "leave out" and "put away" now correctly update text windows. + - Increased size of text window + tooltip date and time fields + from 16 to 80 bytes. + - Added date/time string length checking to ScaFormatDate(). + 20010802 JL - Fixed a race condition between DrawDrag() and DragEnter() that + could block window when trying to auto-remove icons. + - Finally fixed icon masking problem with PAL Hires-Laced screen. When + "Auto Remove Icons" was turned on, dragged icons left garbage at their + original position until finally dropped. + Problem finally solved without setting friend BitMap to NULL. + 20010731 JL - Added preferences selectable pens for ToolTip text and background. + - Due to an incompatibility in Palette.prefs, I renamed it to + "Palette13.prefs" . Scalos uses old "Palette.prefs" if + no "Palette13.prefs" found. To create new prefs file, either + copy old "Palette.prefs" to new "Palette13.prefs" or load + Palette prefs editor and use "Save" button to generate + new "Palette13.prefs". + 20010729 JL - Added check for deleting files of an undefined DirEntryType. + - For SoftLinks, ToolTips showed name of link target + instead of link name. Fixed. + - Bumped revision to 40.8. + + 40.7 20010729 JL - Dropped Popupmenu.library for icon ToolTip display and added + own layouting and rendering code. + 20010728 DM + Added check for copying files of a non-specific DirEntryType. + Copies files correctly across Samba network, deleting files + seems to work OK with the current code. + 20010728 JL - Moved ToolTip display to separate task. + 20010727 DM + Fixed corrupt logo and text in about and splash windows by setting + all allocated bitmaps to have no friend bitmap + 20010726 JL - Added AttempLockLayerRom() around icon ToolTip display routine in + order to avoid deadlocks. + 20010724 JL - Due to Mike's request, increased minimum window width by 20. + 20010723 JL - Added "scalos/icandy" environment variable on startup and set contents to "2". + - Changed every copyright string to "© 1999-2001 The Scalos Team". + - Added "About" function to Menu and Palette preferences. + 20010722 JL - Changing palette prefs now closes and reopens Scalos, no matter if + the "DisableCloseWorkbench" flag is set. + 20010721 JL - "put away" command didn't work with icons without associated objects. Fixed. + - "Scalos Menu" : added new menu commands "viewbysize" and "viewbydate". + - "Disk.info" icons of type WBDISK will no longer appear inside drawer windows. + - Switching window view mode while window is reading icons no + longer causes window to close. + - SCCM_IconWin_RemIcon now updates window's virtual size and adjusts sliders. + 20010720 JL - Bumped revision to 40.7. + + 40.6 20010718 JL - Double-clicking tool icons in text windows didn't start execute command. + Recognition of default icons in text windows didn't work when + starting programs. Fixed. + 20010717 JL - Found a icon masking problem with PAL Hires-Laced screen. When + "auto remove icons" was turned on, dragged icons left garbage at their + original position until finally dropped. + Problem (mask BitMap and icon BitMap having different format, + recognizable by different "BytesPerRow" values for equeal width) at + least partially solved by setting friend BitMap to NULL if (Depth <= 8). + 20010716 JL - Empty lines in ".backdrop" files should be ignored now. + - CloseWorkBench() from IPrefs Task didn't work. Fixed. + 20010715 JL - Text windows sometimes swallowed first character of file comment. Fixed. + 20010713 JL - "Replace All" now works when drag-copying multiple objects. + 20010712 JL - "select contents" now deselects all icons in non-selected windows. + - "clear selection" now deselects all icons in all windows. + 20010711 JL - Plugin libraries are now flushed on scalos exit. + - Fixed possible problem with missing ScaWindowTask parameter on FreeIconList(). + - Bumped revision to 40.6. + + 40.5 20010708 JL - CheckMouseIcon() didn't work with negative coordinates. Fixed. + - text windows initially opened with do_CurrentX < 0 in icon displayed + icon text at incorrect position. Fixed. + 20010707 JL - When reading a directory, icons are no longer checked if they overlap each other. + - converted SCA_OpenIconWindow() to C. + - Bumped revision to 40.5. + + 40.4 20010706 JL - Enabled "snapshot window" and "snapshot all" for root window again. + 20010705 JL - Changed locking in DrawDrag() - first call. When "Auto remove icons" was enabled, + Icons sometimes didn't get ghosted properly due to DRAGFLAGF_WindowLocked set. + - Changed initial value for unused oldDir Locks from NULL to $ffffffff, to avoid + trouble with pr_CurrentDir = NULL (at the end of functions, CurrentDir() never + got reset to initial value when that value was NULL). + - AmigaDos menu commands failed to skip trailing '"' if command name is surrounded + by '"', e.g. "SYS:xyz" executed with '"' as first argument. + 20010704 JL - AmigaDos menu commands now inherit the workbench path. + - Bumped revision to 40.4. + + 40.3 20010704 JL - ReadIcon() didn't respect the "show only icons" setting for text windows, so + all files appeared after automatic window update. + 20010703 JL - changed detection for WMFLAG_IsVirtualSize (sizetofit menu command enabling), + now also enabled if window is larger than necessary to hold icons. + 20010702 JL - Screen menu items are now enabled/disabled each time + SCCM_IconWin_SetVirtSize is applied (i.e. after any change in window size). + 20010630 JL - Forgot to set Flag in ReadTextWindowIconList(), + so all text icons were treated as if on a write-protected disk. + - Bumped revision to 40.3. + + 40.2 20010629 JL - Fixed more problems run AmigaDOS menu commands without path. + 20010628 JL - SnapshotWindow() sometimes wrote icon to wrong directory. Fixed. + - Added wt_UpdateSemaphore locking for "update" command. + - Bumped revision to 40.2. + + 40.1 20010627 JL - BltMaskBitMapRastPort() used incorrect MinTerm so Masking didn't work + correctly. (e.g. logos in splash and about window on non-cybergraphics screen). + 20010626 JL - CheckMouseIcon() didn't work when "Non-masked click area" was checked. Fixed. + - Splash window didn't adjust logo when window was resized due to long message. Fixed. + - ReadDatatypesImage() returned the original BitMap (PDTA_BitMap) instead of + the remapped one (PDTA_DestBitMap). + 20010624 JL - Due to extended library functions, bumped version to 40.1. + +39.234 20010623 JL - Added SCA_ScalosControl() call to scalos.library. Only 3 tags supported + yet, documentation still missing. + 20010620 JL - About and Splash window can may load different logo images + "THEME:ScalosSplashLogo" and "THEME:ScalosAboutLogo". If those + files are not found, both windows fall back to "THEME:ScalosLogo". + 20010617 JL - Due to an incompatibility in menu.prefs, I renamed it to + "menu13.prefs" . Scalos uses old "menu.prefs" if no "menu13.prefs" found. + To create new prefs file, either copy old "menu.prefs" to new + "menu13.prefs" or load old "menu.prefs" in menu prefs editor + and use "Save" button to generate new "menu13.prefs". + 20010616 JL - Added new popup menu class for AppIcons. + - "System Info" button in About window is disabled if sysinfo module cannot + be found. + - Opening new icon windows in iconified state could lead to each icon + appearing twice after uniconifying window - Fixed. Now wt_LateIconList is + cleared at the beginning of ReadIconList(). + 20010615 JL - Fixed enforcer hits in about window when no scalos logo could be loaded. + - RunMenuCommand() didn't work with CLI (=AmigaDos) commands without + path, i.e. only filename specified. Fixed. + - Icon tooltips no longer pop up when non-Scalos window is active. + - Icon position for iconified Scalos windows can be specified in + window icon with SCALOS_ICONIFIED_XPOS and SCALOS_ICONIFIED_YPOS. + - Bumped revision to 39.234. + +39.233 20010614 JL - AppIcon menu commands now support all WB3.5+ AMCLASSICON_... + AppMessage class codes (e.g. Benchtrash information/snapshot/unsnapshot works). + 20010613 JL - Due to common request, Bob functions now don't use chip memory + if port "FBlit" is available. + 20010610 JL - AppIcons always got IDTV_TextMode_Normal (no outline, no shadow). Fixed. + 20010609 JL - ARexx menu commands now may have selected items as arguments. + - Bumped revision to 39.233. + +39.232 20010608 JL - Enabling/disabling popup menus now works correctly with nested sub-menus. + 20010607 JL - Scalos now does a "Update all" instead of "Redraw" when + detecting changed main prefs. + 20010606 JL - Softlink sometimes could not be copied due to incorrect parent directory - Fixed. + 20010605 JL - Fixed nasty bug in AllocVecPooled()/FreeVecPooled() : a6 was overwritten. + - In text windows with "Show only Icons", non-existing objects (i.e. icons + without corresponding objects) are no longer displayed (e.g. "disk"). + - Disabled "Leave Out" for default icons. + - Changed locking in TestPopup() to prevent deadlocks. + 20010603 JL - Bug #4. Fixed crash when executing ARexx menu command. + 20010602 JL - No tooltips are displayed for icon after clicking or double-clicking it. + - Menu command "sizetofit" now also shrinks windows if appropriate. + - Bumped revision to 39.232. + +39.231 20010601 JL - Text windows with "Show only Icons" displayed data for icons + instead of objects. Fixed. + - Bug #13. Drawers inside of text windows no longer open always + in text mode, but use the drawer icon settings instead. + 20010530 JL - checkmouseicon() and QueryObjectUnderPointer() now take + "Non-masked click area" setting into account. + 20010529 JL - Fixed possible race condition with QueryObjectUnderPointer() by + extending window list and wt_IconSemaphore locking. + 20010526 JL - AppIcons now have popup menus (currently the same as tool icons) + if is not 0. + - Tooltips now recognize iconified scalos windows. + 20010525 JL - Iconified window appIcons get the "WBAPPICONA_SupportsOpen, TRUE" Attribute. + - Fixed error in SCA_NewAddAppIcon() - WBAPPICONA_Supports... tags didn't work. + - Bumped revision to 39.231. + +39.230 20010524 JL - No icon tool tips are displayed if icon has tooltype "SCALOS_NOTOOLTIPS". + - Added new menu commands "sizetofit" and "clearselection". + 20010523 JL - Scalos now passes a copy of the window lock as wa_Lock and wa_Name=NULL + when no icons are selected (now OS3.9 Find work just as with Workbench). + - Fixed a couple of problems with the new tooltip function. + 20010519 JL - Bumped revision to 39.230. + +39.229 20010519 JL - Fixed bug in QueryObjectUnderPointer() - did not work correctly if Workbench + screen wasn't frontmost screen. + 20010517 JL - Added check for ST_LINKFILE, ST_LINKDIR, ST_SOFTLINK before calling isLink(). + - (OLD) After updating left-out (backdrop) icon, updating the associated disk icon + created a new backdrop icon instead of refreshing the old one. Fixed. + 20010515 JL - Replaced IDCMP_VANILLAKEY handling by IDCMP_RAWKEY in order to + receive "key up" events. + - Drag&Drag indicators (copy etc.) are now updated immediately when + pressing or releasing qualifier key. + 20010512 JL - About window now supports optional background image "THEME:AboutBackground". + 20010510 JL - Added support for wheel mouse (icon/text window scrolling). + 20010509 JL - Text windows didn't get refreshed properly after deleting icons. Fixed. + 20010508 JL - Icon tooltypes sometimes were not recognized correctly. Fixed. + - Bumped revision to 39.229. + +39.228 20010507 JL - Changed method of soft link detection to a more system-friendly one. + - Bumped revision to 39.228. + +39.227 20010506 JL - Scalos no longer tries to load appchange'd AppIcons when their + name contains invalid characters, i.e. ":/". + - Scalos now uses AddPart() to add the name of the AppIcon to the "Default icons" + path, to make sure there is always a "/" between path and file name. + - Converted WBLtask to C. The "unable to load your tool ..." Request now offers + to select a different tool via ASL requester. + 20010504 JL - "Leave Out" didn't work for icons without associated files or drawers. Fixed. + 20010501 JL - Icon menu items weren't enabled correctly in text windows. Fixed. + - "View All" wasn't recognized when initially opening text windows. Fixed. + 20010430 JL - Softlinks are now displayed with underlined names. This feature + work only with iconobject.datatype 39.33 and later. + (I saw that feature at Workbench 3.9 (with BoingBag 1) and immediately liked it). + 20010429 JL - Text windows now distinguish between "Show All Files" and "Show Only Icons". + - Bumped revision to 39.227. + +39.226 20010428 JL - Splash window : added 10" timeout when waiting for update message reply. + 20010427 JL - AppIcons now support the WBAPPICONA_Supports... tags. + - Icon menu items are now enabled/disabled according to the icons properties, + e.g. for icons on read-only media "delete" and "rename" is disabled. + - Splash window now supports optional background image "THEME:SplashBackground". + 20010424 JL - Fixed Enforcer hit in file/directory copying code when + FileTransClassInstance was NULL. + - CopyCommand didn't work with DestName != NULL (to perform + "Copy As" function). Fixed. + - Objects can now get duplicated (cloned) via D&D into same window + with Control key held down. + 20010422 JL - Window.c/QueryObjectUnderPointer() could crash if PtrLayer->Window was + empty (NULL). Fixed. + - Path Assign "THEME:" is set on program start to "Scalos:themes/default". + - Bumped revision to 39.226. + +39.225 20010421 JL - Fixed enforcer hits/crash opening window popup menu with empty (NULL) ws_Name. + - MoveCommand() no longer complains when trying to move non-existing object. + - Bumped revision to 39.225. + +39.224 20010420 JL - Dropped drop zone rendering in separate layers and returned to complement + drawing due to lack of performance. + 20010417 JL - Logo gets loaded by datatypes.library from THEME:ScalosLogo + - Defined C names for all library bases. + 20010415 JL - Region didn't get freed in class.c/SameWindow() if no icon was moved. Fixed. + - Additional check for NULL window pointer in Scalos.c/LassoInit(). + - moving icons in same window with "AutoRemove Icons = Off" didn't work properly + because registers were trashed in main_subroutines.s/checkposition. Fixed. + - Bumped revision to 39.224. + +39.223 20010415 JL - Due to Mike's request, bumped revision to 39.223. + +222x26 - Removed locking with DragDropSemaphore due to deadlock problems. + - Changed rendering of window/icon drop zones from complement drawing + to separate layers (in Requesters), hopefully eliminating all problems + with garbage left in windows. + 20010414 JL - Changed to utilize CatComp and its automatically generated locale header files. + All localized string are now in "Scalos.cd". Tested with CatComp 44.6. + 20010413 JL - Bumped version to 222x26. + +222x25 20010413 JL - Fixed crash when icon window was closed or iconified while reading icons + and drawer contained more than 20 icons. + 20010412 JL - (OLD) Fixed another icon window cleanup bug - icons were incorrectly + positioned under certain conditions so that icon text could overlap + other icons. + 20010411 JL - Lasso selection didn't respect window limits when selecting icons. Fixed. + 20010410 JL - CLIStart() crashed with type WBTOOL icons. Fixed. + - (OLD) SCA_OpenIconWindow() didn't work with SCA_Iconify tag. Fixed. + 20010409 JL - Lasso didn't correctly calculate window left and top offsets. Fixed. + - Popup menus now have two title lines, with the type of object in the + first line and the name of the object in the second one. + 20010407 JL - File move and copy routiones rewritten from scratch. Extensive error checking + when moving/copying objects. Requester when trying to overwrite existing + objects while moving/copying. + - Created locking mechanism (via DragDropSemaphore) to prevent window updates + during D&D. + 20010404 JL - Renaming left-out icons will no longer lose their position. + 20010403 JL - Changed window refresh after file system notify : icon update is held back until + 2s after last update request. Fixes lengthy repeated icon window updates after + changing many items (e.g. "Select All", then "UnShapshot"). + - Implemented drag threshold, i.e. icons have to be moved more than 4 pixels until + drop zone indicator is drawn. + THE AMOUNT OF 4 PIXELS SHOULD BE MADE USER SELECTABLE IN PREFERENCES. + 20010402 JL - When modifying icons, Icons used to disappear if no associated file existed. Fixed. + 20010401 JL - Icon just left out did not disappear from desktop when volume (disk) was removed. Fixed. + - Icons could be "left out" multiple times, leaving several lines in ".backdrop". Fixed. + 20010331 JL - Fixed bug #25 - D&D didn't copy to drawer icon left out on the desktop. + 20010330 JL - Bumped version to 222x25. + +222x24 20010329 JL - (OLD) ".backdrop" files are now updated when renaming objects. Fixed bug #22. + 20010328 JL - Fixed OLD bug in root_handlemessages - stack could be corrupted if message without + handler routine was encountered. Possibly also fixes long-standing bug #21. + 20010327 JL - Text mode windows used to show "#?.info" files when UseExAll was off. Fixed. + 20010325 JL - (OLD) Fixed enforcer hits/Alerts with "leave out" and "put away". + - (OLD) Leave out didn't work if .backdrop had a length of 0 bytes. Fixed. + 20010325 JL - Bumped version to 222x24. + +222x23 20010324 JL - Rename.module, newdrawer.module and delete.module now trigger + window updates on completion. + - On completion of rename.module, objects are checked if they have been renamed + and window names are adjusted if necessary (bug #16 finally wiped out). + 20010323 JL - Lasso selection now only affects visible icons (same behaviour as Scalos 2.1d) + 20010321 JL - Hopefully fixed multiple text window refresh problems. + - Removed forced D&D source update. + 20010320 JL - Window drop box was drawn incorrectly for text windows. Fixed. + - Added new text window methods : SCCM_TextWin_BeginUpdate, SCCM_TextWin_EndUpdate. + - Changed text window method SCCM_IconWin_RemIcon from no-op to working icon removal. + 20010319 JL - Fixed serious bug in GetTextIcon_Fib() : Drop on text window icon caused + many enforcer hits. + - D&D onto text icon drawers didn't work. Fixed. + - IconWinCheckUpdate() now also works work text windows. + 20010318 JL - Converted text window icon reading code to C. + - Text windows displayed date+time incorrectly : last digit was shown twice. Fixed. + - Text window columns now always are wide enough to show column title + (e.g. empty drawer in text mode only used to show the last column spanning all window width) + - IconActive flag didn't get updated corrected when lasso-selecting icons. Fixed. + - Left mousebutton click toggles icon selection state when shift pressed. + 20010317 JL - Bumped version to 222x23. + +222x22 20010317 JL - Text mode windows used incorrect font. Inserted missing SetFont() in DrawTextGadgets(). + Special indicator bobs were broken with system bob routines. Fixed. + 20010317 JL - Bumped version to 222x22. + +222x21 20010317 JL - ReadIconList() failed when called from different WindowTask (e.g. activate + Window #1, RMB click Window #2, select "Update" via popup menu). Fixed. + - Icons in backdrop windows could be dragged to overlap each other. Fixed. + - At D&D operations, the first argument (file/drawer) didnþt get freed. Fixed. + 20010316 JL - Prefs option "Hide hidden files" now hides files starting with "." + (only in functions converted to C yet). + - Drag/Drop copy/move forces check for update on source. + - Changed D&D special indicator handling: + * special bobs initially added to separate list instead of adding to srgh_boblist + and then moved to special bob list. + * drgh_boblist protected by semaphore to prevent DrawDrag() until InitDrag() finishes. + 20010315 JL - Icon drop marks during menu popup didn't get erased properly + in simple-refresh windows. fixed. + 20010314 JL - Fixed directory-reading bug with empty file names or files ".info". + - special D&D indicators are now always drawn solid. + 20010313 JL - Fixed (self-introduced) Bug in DragDropBobs.c : BlitTrans() + handled masks incorrectly when width was a multiple of 16. + - Bob functions now don't use chip memory if CyberGfxBase is available. + 20010312 JL - Squished Bug #17 : Text window column headers no longer flicker + when MMB is held down and mouse is moved. + 20010310 JL - Removed layout bug in iconwindow cleanup (icons did overlap). + 20010305 JL - Lasso() now always uses Screen->MouseX/MouseY coordinates. + No more offsets between mouse position and lasso corner ! +222x20 20010303 JL - PopupMenu now visually indicates selected icon. + - Popup menus work without selecting window now (if any Scalos window is selected) + 20010227 JL - finished converting main_dragdropbobs.s to C. + - During D&D, special indicators show if icon may not be dropped + or icons are going to be copied. + - During D&D, holding CTRL key forces copy (instead of move). + 20010221 JL - During D&D, Icons leave a "shadow" at their original position if + "Auto remove icons" is enabled. This Shadow is truly transparent + if possible (CyberGfx + Screen depth > 8) and enabled + in preferences, else it is drawn "ghosted". + 20010220 JL - Removed old bug in copyfiles - after a read error, Scalos didn't stop, + but tried to write 0xffffffff bytes to the destination. +222x17 20010217 JL - ported all xxxDrop() stuff to C. + Changed ScaBob and ScaBob2 member names to avoid conflicts with Gels Bobs. + 20010216 JL - Fixed old bug in execomprog, formatdiskprog, shutdownprog, renameprog, + newdrawerprog, deleteprog, emptytrashprog : TagList for SBA_WBStart() wasn't set, + a1 contained garbage. + 20010211 JL - Bug #30: Removed GM_HITTEST from TextIconClass. Now TextIcons can be selected + Bug #19: Text window cleanup now works. + - by clicking anywhere in the line, not only the name field. + 20010209 JL - Fixed bug Scalos crashing on quit with drawer windows open + 20010207 JL - Pulled nasty bug introduced by early plugin init in ReadDiskPlugin1 + 20010129 JL - Added new IconWindow methods SCCM_IconWin_DragEnter, SCCM_IconWin_DragLeave, + SCCM_IconWin_DragQuery. + - Added Qualifier to SCCM_IconWin_DragDrop. + - Added global Variable "Default_StackSize". + - Added Support for ToolType "DONOTPROMPT" in conjunction with old ToolType "CLI". + - Moved all datat structure definitions to file "scalos_structures.i". + - Created C header file "scalos_structures.h". + - Actual Plugin Data (e.g. instance size) is read before MakeClass() + - Changed view of dragging selected icons to dragging a "stack" of max. 3 icons + - When dragging, icons/windows indicate where things may be dropped. + - Lasso activates icons on the fly now. + - Popup menu titles reflect icon names. + 20010113 JL - Ported to assemble with PhxAss. PhxAss doesn't like constructs like "iconnode\.node" + so I put a prefix on all structure members e.g. "in_node". +39.220 20010111 DM - Converted Juergen's fixes to values instead of constants, AsmOne seems to not like some of the included OS files - in various files + 20001231 MC0002 - Added includes for various lvo/#?.i + 20001230 MC0001 - Added exec/libraries.i for LIB_VERSION() macro + and OS3.5 asm includes for workbench.library, imageclass.i + 20001217 DM000A - Removed include file main_about.s - all code now in C! + 20001212 DM0009 - Added some code for calling debug startup/shutdown C functions + 20001122 DM0007 - Removed about_pattern from main_tables.s and put into about.c (the only place that was using it) + All logo stuff moved from main_scalos.s to main_about.s (only place it is used) + 2000 DM0006 + 2000 DM0005 + 20001114 DM0004 - started converting the about requester and related code to C as a test of how painful this is going to be :) + 20001107 DM0003 - added the includes imports.i and exports.i. used for when combining with C code. Also added workaround for symbol export bug in AsmXXX + 20000903 DM0002 - Bumped version and date to 39.220 (1.2c) and 3/9/00 + - Fixed enforcer hit when there is no main menu prefs file on startup + - Noticed that main menu prefs aren't read in with prefslib! + +39.219 20000726 DM0001 - Altered some lines in readmainprefs routine so that scratch registers are reloaded before use + 19991130 CDH0001 - Added code for new "formatdisk" command from Menu Prefs + 19991204 CDH0002 - Added code for "SystemInfo.module" from About requester + 19991205 CDH0003 - Added code for new "shutdown" command from Menu Prefs + +---------------------------------------------------------------------------- + +**************************************************************************** + +--------------------Scalos main Preferences--------------------------------- + + 40.28 20100901 jl - Improvement: added icon sample for thumbnail size selection and icon min/max size selection. + - Improvement: moved all icon size related settings to separate page. + 20100606 jl - Improvement: added "About MorphOS" menu item (MorphOS version only). + 20100501 jl - Improvement: rearranged values in minimum icon size cycle gadget. + - Improvement: added slider to select nominal icon size between 25% and 400%. + 20100328 jl - Improvement: added option to select whether drawers in text windows are + displayed before files, after files, or with files. + - Improvement: prefs pages are now virtual. + + 40.27 20100321 jl - Bugfix: when saving preferences, Workbench preferences was overwritten, silently removing + all chunks Scalos isn't aware of. Now all unknown chunks are written back 1:1. + + 40.26 20100216 jl - Bugfix: control bar gadget image previews were not updated correctly when image was changed. + 20091230 jl - Improvement: Add configuration for drag&drop pop-open windows open delay. + 20091011 jl - Improvement: Add support for control bar also for standard (non-browser) windows, + standard and browser-mode control bars can be configured independently. + + 40.25 20090829 jl - Improvement: allow TrueType font selection for text windows on windows/text windows page. + 40.24 20090413 jl - Bugfix: resolved NULL pointer hit when adding normal image to user-defined control bar button. + + 40.23 20090109 jl - Improvement: added support for transparent Scalos windows - MorphOS 2.x only. + 20090103 jl - Improvement: added configuration options option for highlighting + of selected icon text by a surrounding rectangle. + + 40.22 20071202 jl - Improvement: Allow only one instance of Scalos Prefs. + 20071101 jl - Improvement: Added page for user-configurable browser window control bars. + 20071003 jl - Improvement: Automatically use Zune instead of MUI if present. + Fixes crashes with prefs pugins with AFA OS installed. + 20070916 jl - Improvement: When adding plugins, file requester only + shows plugins that have not been added yet. + - Improvement: By selecting more than one entry in file + requester, multiple plugins can be added. + + 40.21 20070315 jl - Improvement: Simplified changing of icon font by adding a copy + of truetype font settings to icons/labels page. + + 40.20 20061001 jl - Improvement: In German translation, replaced all "link" by "Verknüpfung". + 20060912 jl - Improvement: Added configuration for single-window lasso mode qualifier key. + 20060815 jl - Improvement: Added new settings for user-definable thumbnail + backfill, frames around thumbnails, and thumbnail background + transparency. + 20060418 jl - Improvement: Added new user setting to always apply popup menus to + every selected icon, regardless of qualifier. + 20060401 jl - Improvement: Moved all thumbnail-related settings to separate page. + - Improvement: Added selectable transparency for tooltip bubbles. + 20060327 jmc - Improvement: New setting Added - Switch on/off the displaying of + image thumbnails to be shown if they have no icons (available + with "THUMBNAILS_AsDefault" option). + + 40.19 20060207 jmc - Added cache size limit "user-configurable" option. + 20060115 jl - Improvement: Added user-selectable layout direction for each icon + type, separate for desktop and standard icon windows. + 20051216 jl - Bugfix: Under OS3.1, Scalos Prefs failed to start + if THEME: images were not present. + - Bugfix: All requesters for unavailable volumes are + now suppressed. + 20051215 jl - Improvement: Added new tooltype "NOPREFSPLUGINS", + causes prefs plugins to be ignored, as name suggests. + 20051211 jl - Improvement: the list of hidden device can be + changed (stored in workbench.prefs). + 20051202 jl - Bugfix: icon borders changed if preferences were + reloaded after start. + 40.18 20051001 jl - Improvement: sorting of plugin list is now selectable. + 40.17 20050909 jl - Improvement: Selecting new icon frames now automatically + adjusts icon borders. + - Improvement: mcpgfx.library and MCPFrame.mcc are no + longer required. + 40.16 20050701 jl - Improvement: Added selection for thumbnail display mode + and size of thumbnails. + 20050611 jl - Improvement: Icon font is now selectable via Scalos prefs + if no "font preferences" is available. + - Improvement: popup font selection for icon and text + window font is disabled if corresponding TrueType + font is enabled. + 20050604 jl - Improvement: Added selectable minimum and + maximum sizes for icons. + 20050521 jl - Improvement: Added selectable behaviour for default + "show" and "view by" to "windows" Scalos Prefs page. + 20050513 jl - Improvement: Scalos prefs tries to load page list and + modules images from "THEME:Prefs/pages" and + "THEME:Prefs/modules". If images are not found, old + built-in images are used. + 20050508 jl - Improvement: Scalos plugins that refuse to load are no longer + suppressed in plugin list, but rather displayed in italic. + 20050507 jl - Improvement: About page uses new revision string in scalos + library base instead of hard-coded "1.4" string. + 20050506 jl - Improvement: Rearranged window related items, now text + windows is a register page in "windows" section. + 20050424 jl - Improvement: Added new tooltype "NOSPLASHWINDOW". When + set, no splash windows are displayed on loading and saving + prefs. This applies to prefs modules, too. + - Bugfix: Corrected border types around MUI checkboxes. + + 40.15 20050402 jl - Changed background of prefs pages to MUII_PageBack. + + 40.14 20050329 jl - Renamed prefs page "File display" to "Text windows". + Moved "Text windows" prefs page directly after + "Windows" page. + 20053027 +JMC+ - Added: New window title bar's refreshing setting into + section "Windows". Screen and window title bars are + refreshed separately. + 20050119 jl - Improvement: Added new settings "antialiasing" and + "gamma correction" on "TrueType Fonts" page. + 40.13 20041202 +JMC+ - In the "File Display" section, added new checkmark + for support hidden files(via FIBF_HIDDEN). + jl - Exchanged "Borders" and "Attributes" register + paqes in "Icons" section. + 20040827 jl - Added passing of tooltypes on to prefs plugins. + 40.12 20040718 jl - Added font preview for icon font, and text window font. + - In the "drag and drop" section, added new qualifier + input field for "Create links" and "Force move". + - On the "Miscellaneous" page, added a cycle gadget to + select the type of links Scalos generates. + 40.11 20040516 jl - Added new prefs page for TrueType font settings. TT Font + selection is available for icons, text windows and + tooltips and the "About" window ("Screen font"). + - Added checking for custom MUI MCCs and MCC versions. + - Enabled "Multiple Lines" switch for icon text. + 40.10 jl - Rearranged prefs pages - created new prefs + group "Drag and Drop". + 40.9 + 40.8 20040111 jl - Added slider for degree of default icon + drawing transparency. + - Transparency settings and "Custom" bob routines + are now disabled when noo CyberGfx library found + or when Workbench screen has no more than 256 colours. + 40.7 20040107 jl - Several Datatypes images were no longer + visible after iconify/uniconify. Fixed. + - Added icon for iconified state. + 40.6 20040101 jl - Added gadget to adjust Scalos default stack size. + 40.5 20031227 jl - Replaced MUI NFloattext class by Floattext. + 40.4 20031218 jl - Updated Scalos URL to "scalos.noname.fr". + 40.3 20031216 jl - Added missing load/save functions for + Tooltip delay + 40.2 20031117 jl - "Add plugin" command erroneously cleared + internal plugin list. + - Changed module image display from + TransferAnimObject to DataTypesMCCObject. + 40.1 20030104 jl - Rewritten from scratch, based on code by Budda. + 20030710 jl - Initial release 40.1 + +---------------------------------------------------------------------------- + +**************************************************************************** + +--------------------Scalos FileTypes Preferences---------------------------- + + 40.24 20110220 jl - Bugfix: pasting unselected or selected icon attribute failed to update icon preview. + 20100516 jl - Bugfix: new filetype recognition methods are now insert below selected method. + 20100411 jl - Improvement: number of find hits is now displayed. + In filetypes listtree, string matches are now marked with fill pen. + Drawback: DOS-style patterns are no longer supported to find filetypes. + 20100404 jl - Improvement: added preview of menu icon images to listview. + 40.23 (internal version only) + 40.22 20090511 jl - Bugfix: icon is updated correctly when filetypes recognition + list is sorted via drag-drop. + - Improvement: Search panel can now be unhidden via popup menu. + - Improvement: In filetype search panel, forward and backwards + buttons allow jumping to next and previous match. + 40.21 20081217 jl - Improvement: Replaced "search" entries in popup menu by + MUI group. Filetype search work works incrementally. + 40.20 20080831 jl - Bugfix: search filetypes list with "Find next" didn't work. + 40.18 20080518 jl - Bugfix: Adding new methods for filetypes' recognition was broken. + jl - Improvement: extended DefIcons functionality to cover classification + of WBDISK objects, i.e. USB disks, DVDs or SMB network volumes are now + recognized automatically. + 40.17 20071003 jl - Improvement: Automatically use Zune instead of MUI if present. + Fixes crashes with prefs pugins with AFA OS installed. + 20070930 jl - Improvement: added capability to search for filetype by name. + 40.16 20070918 jl - Improvement: thumbnail menu image is now optionally + loaded from "THEME:prefs/plugins/filetypes". + 40.15 20070815 jl - Bugfix: enforcer hit creating a new filetype. + 40.14 20070715 jl - Improvement: Added menu command to manually initiate + thumbnail cache cleanup. + 20061224 jl - Improvement: Selecting an entry on the "Recognition" page + automatically selects matching entry on the "Actions" page. + 40.13 20061003 jl - Improvement: Added user-selectable icon images + for filetype-specific popup menus. + 20060503 jl - Improvement: Added new attribute PREVIEWPLUGIN for + filetype-specific thumbnail generators. + 40.12 20060128 jl - Improvement: Added new internal command "createthumbnail". + 20051225 jl - Improvement: Added functionality to create new + filetype-specific icons, and edit them via information.module. + 40.11 20051026 jl - Improvement "Open" and "save" requester are only allocated + once. This way, directory and file name for "open" and + "save as" are remembered until preferences are closed. + 20050930 jl - Improvement: Added editor for deficons prefs. Filetype + recognition is now fully configurable. + 40.10 20050917 jl - Bugfix: dropping below other entries wasn't possible + at the correct locations. + 40.9 20050521 jl - Improvement: Added support for new menu commands + "showdefault" and "viewbydefault" + 40.8 20050408 jl - Added checking of MUI MCCs required by prefs plugins. + 40.7 20050402 jl - Changed background of prefs page to MUII_PageBack. + 40.6 20041111 jl - Replaced Assembler library startup code by C. + No functional changes. + 40.5 20040828 jl - Added menu option and tooltype to hide all + empty filetype entries. + 40.4 20040703 jl - Added font preview to TTTFONT editing window. + 40.3 20040222 jl - Changing the "create icons" menu item had no effect. + - Added TrueType font support for ToolTips (new TTFONT + attribute for STRING). + 40.2 20040108 jl - Added icon for iconified state. + - Bugfix: Fixed handling of internal "modified" flag. + - Added lamp indicator for "modified" flags. + 40.1 20031211 jl - Initial release 40.1 + +---------------------------------------------------------------------------- + +**************************************************************************** + +--------------------Scalos Menu Preferences--------------------------------- + + 40.20 20120108 jl - Bugfix: "Reset to default" didn't generate submenus in + window menu, e.g. "window/show" or "window/View by". + 20100404 jl - Improvement: added preview of menu icon images to listview. + 40.19 20100131 jl - Improvement: redesigned layout for better overview. + - Improvement: added Workbench popup menu to + default menu preferences. + - Improvement: added copy/cut/paste functionality + for easier menu configuration. + - Improvement: "Save As" dialog uses path of "Open" + dialog as default. + 40.18 20100125 jl - (internal version only) + 40.17 20100119 jl - Bugfix: With Scalos menu preferences, it was not possible to + add menu items to an empty popup menu + 20071003 jl - Improvement: Automatically use Zune instead of MUI if present. + Fixes crashes with prefs pugins with AFA OS installed. + 20070918 jl - Improvement: thumbnail menu image is now optionally + loaded from "THEME:prefs/plugins/menu". + 40.16 20070715 jl - Improvement: Added menu command to manually initiate + thumbnail cache cleanup. + 20061003 jl - Improvement: Added user-selectable icon images + for popup menus. + 20060805 jl - Improvement: popup menus that are nowadays configurable + via filetypes prefs are now hidden by default, to + avoid confusion. + 20060505 jl - Bugfix: Selecting a new "internal command" from list + didn't update string gadget. + 40.15 20060128 jl - Improvement: Added new internal command "createthumbnail". + 20051101 jl - Improvement: "reset to defaults" now generates a complete, + localized menu, instead of an empty one. + 20051026 jl - Improvement "Open" and "save" requester are only allocated + once. This way, directory and file name for "open" and + "save as" are remembered until preferences are closed. + 20050521 jl - Improvement: Added support for new menu commands + "showdefault" and "viewbydefault" + 40.14 20050408 jl - Added checking of MUI MCCs required by prefs plugins. + 40.13 20050402 jl - Changed background of prefs page to MUII_PageBack. + 40.12 20041111 jl - Replaced Assembler library startup code by C. + No functional changes. + 40.10 20040424 jl - Bugfix: Fixed handling of internal "modified" flag. + - Added lamp indicator for "modified" flags. + - Menu command "Merge" erroneously cleared the existing + entries before importing the new ones. Fixed. + 40.9 20040222 jl - Changing the "create icons" menu item had no effect. + 40.8 20040108 jl - Added icon for iconified state. + 40.7 20030831 jl - Moved core functionaility to "MenuPrefs.prefsplugin". + 40.6 20030712 JL - Bugfix: Removed memory leak in CLI startup code. + 40.5 20030531 JL - Bugfix: Popup button for IconWindow command entries now + only accepts directories. + - Bugfix: Closing command popup ASL requester with "Ok" + button failed to enter filename into Listview element. + - Improvement: command popup ASL requester now defaults to + "Scalos:Plugins/Menu/" directory for menu plugins. + 40.4 20030424 JL - Several bugfixes that affect renaming of menu items. + - for Workbench commands, stack size and priority are taken + from icon, if available. + 40.2 20030223 JL - Added checking of menu level and number of menu items. It + is no longer possible to add a new menu to a SubMenu, or + to add more than 64 MenuItems to a menu, or to add more + than 32 Entries to a sub menu. + 40.1 20021226 JL - Rewritten from scratch in C. + +---------------------------------------------------------------------------- + +**************************************************************************** + +--------------------Scalos Palette Preferences------------------------------ + + 40.11 20071003 jl - Improvement: Automatically use Zune instead of MUI if present. + Fixes crashes with prefs pugins with AFA OS installed. + - Bugfix: new allocated pens are now correctly added + at bottom of list. + 20070918 jl - Improvement: thumbnail menu image is now optionally + loaded from "THEME:prefs/plugins/palette". + 40.10 20060815 jl - Improvement: Added two new pens for filling of + thumbnail backgrounds. + 20060319 jl - Improvement: Moved color wheel from separate register + page to new pane in main page. + - Bugfix: Context menu only worked over listviews. + - Improvement: All listviews are now user-sortable via + mouse-click on column title. + 40.9 20051026 jl - Improvement "Open" and "save" requester are only allocated + once. This way, directory and file name for "open" and + "save as" are remembered until preferences are closed. + 20050408 jl - Added checking of MUI MCCs required by prefs plugins. + 40.8 20050402 jl - Changed background of prefs page to MUII_PageBack. + 40.7 20041111 jl - Replaced Assembler library startup code by C. + No functional changes. + 40.6 20040424 jl - Bugfix: Fixed handling of internal "modified" flag. + - Added lamp indicator for "modified" flags. + - Changing the "create icons" menu item had no effect. + 40.5 20040121 jl - Number of allocatable pens was too small by 1. Fixed. + 40.4 20040108 jl - Added icon for iconified state. + 40.3 20030831 JL - Moved core functionaility to "PalettePrefs.prefsplugin". + 40.2 20030712 JL - Bugfix: Removed memory leak in CLI startup code. + 40.1 20020601 JL - Added display for number of currently allocated and + available pens. + 20011225 JL - Rewritten from scratch in C. + - Added separate pens for selected icon text, icon text + outline, and icon text shadow. +---------------------------------------------------------------------------- + +**************************************************************************** + +--------------------Scalos Pattern Preferences------------------------------ + + 40.19 20071231 jl - Improvement: when thumbnails are loaded, progress window is + only opened if loading takes more than 100ms. Addtionally, + for increased performance, gadgets are updates only every 100ms. + 40.18 20071130 jl - Bugfix: Enforcer hits on exit after inserting new entries. + - Bugfix: dragging images into listview didn't work when started + from stand-alone "Pattern Prefs". + - Improvement: Thumbnail is automatically created when an image + is dropped onto the listview. + 40.17 20071003 jl - Improvement: Automatically use Zune instead of MUI if present. + Fixes crashes with prefs pugins with AFA OS installed. + 20070918 jl - Improvement: thumbnail menu image is now optionally + loaded from "THEME:prefs/plugins/pattern". + 40.16 20070610 jl - Improvement: Added support for centered, unscaled + background images. + - Improvement: Added support for single-colour or + gradient backfill. + + 40.15 20061101 jl - Bugfix: added workaround to get thumbnails generation + working with OS3.0/3.1 and Picasso96. + + 40.14 20051216 jl - Bugfix: All requesters for unavailable volumes are + now suppressed. + + 40.13 20051030 jl - Improvement: "Reset to defaults" now creates reasonable + default pattern settings (same as pattern.prefs + in release archive). + 20051026 jl - Improvement "Open" and "save" requester are only allocated + once. This way, directory and file name for "open" and + "save as" are remembered until preferences are closed. + 20051001 jl - Improvement: Sorting of pattern list is now selectable. + + 40.12 20050516 jl - Improvement: Added column in pattern list to show which + default patterns has been selected for desktop, screen, + icon windows, and text windows. + - Improvement: On "Defaults" page, added preview images + for selected default patterns. + - Improvement: If guigfx.library is not available, all + guigfx-specific settings are hidden. + 20050505 jl - Improvement: background images are checked on startup, + and thumbnails are removed for non-existing images. + 40.11 20050424 jl - Bugfix: Corrected border types around MUI checkboxes. + 40.10 20050408 jl - Added checking of MUI MCCs required by prefs plugins. + 40.9 20050402 jl - Changed background of prefs page to MUII_PageBack. + 40.8 20041111 jl - Replaced Assembler library startup code by C. + - Improvement: Added option to show thumbnail preview + of patterns in listview. + 40.6 20040426 jl - Bugfix: Fixed handling of internal "modified" flag. + - Added lamp indicator for "modified" flags. + - Changing the "create icons" menu item had no effect. + 40.5 20040108 jl - Added icon for iconified state. + 40.4 20030831 jl - Moved core functionality to "PatternPrefs.prefsplugin". + 40.3 20030712 jl - Bugfix: Removed memory leak in CLI startup code. + 40.2 20030129 jl - Bugfix: Bubble for preview gadget was broken. + - Bugfix: switching between "tiled" and "fit size" didn't work. + - Rewritten from scratch in C. + +---------------------------------------------------------------------------- + +**************************************************************************** + +--------------------Scalos LoadWB------------------------------------------- + + 1.6 20050417 jl - Bugfix: Startup crashes under MorphOS should now be fixed. + 1.4 20040108 jl - The functionality to wait until Scalos opens its first + Window on the workbench screen can now be + suppressed with NOWAIT. + 1.3 20021005 JL - LoadWB now waits until Scalos opened its first Window on + the workbench screen. This is to avoid problems with + Birdie. +**************************************************************************** + +--------------------exifpicture.plugin-------------------------------------- + + 40.0 20050917 jmc/jl - Initial release + +---------------------------------------------------------------------------- + +**************************************************************************** + +--------------------picturedimensions.plugin-------------------------------- + + 40.3 20040117 jl - Added localization for message strings. + 40.2 20030628 jl - Fixed several memory leaks. + 40.1 20021231 jl - Initial release + +--------------------------------------------------------------- + +**************************************************************************** + +--------------------drawercontents.plugin----------------------------------- + + 40.3 20040117 jl - Added localization for message strings. + 40.2 20030628 jl - Fixed several memory leaks. + 40.1 20030104 jl - Initial release + +---------------------------------------------------------------------------- + +**************************************************************************** + +--------------------amigaiconobj35.datatype--------------------------------- + + 40.18 20080403 jl - Improvement: drawing area for AppIcons with render hook is now + clipped to actual icon area. This avoids black left-over + lines when moving some animated icons. + 20080211 jl - Bugfix: do not skip layout even if RenderHook if present. + Otherwise, garbage will be drawn when icon is dragged around. + 20080205 jl - Improvement: Added support for cloning of existing icons + 40.17 20060505 jl - Bugfix: dtNewImage didn't handle color index #0 + correctly (was handled as transparent). + 40.15 20060222 jl - Improvement: replace GetDTAttrs() call by series of + GetAttr(). Now datatypes.library is no longer used. + 40.14 20060120 jl - Bugfix: CoerceMethod() in OM_NEW could lead to + enforcer hits if object could not be created. + 40.13 20060115 jl - Bugfix: Thumbnail images were not saved correctly. + 40.11 20050812 jl - Bugfix: Added size checking for icon BitMaps, to fix a major + memory trashing bug triggered by thumbnailed icons. + 20050604 jl - Improvement: icons can now be scaled. + 40.10 20050427 jl - Bugfix: saving of interior window offsets + (dd_CurrentX/dd_CurrentY) didn't work. + 40.9 20041229 jl - Finished conversion from ASM to C. + 40.7 20031220 jl - changed library from "struct Library" to "struct ClassLibrary" + 40.6 20030420 jl - Added support for "borderless" flag. + 40.5 20021201 jl - Enhanced cleanup - now does RemLibrary() on iconobject.datatype. + 40.4 20020815 jl - Fixed possible enforcer hits in Expunge() + 40.3 20020131 jl - Object pointer in A2 might have been set incorrectly under + certain circumstances in OM_NEW/SetSuperImgBorders. + 40.2 20020112 jl - Always sets IDTA_InnerLeft, IDTA_InnerTop, IDTA_InnerRight + and IDTA_InnerBottom to 0 if icon has a RenderHook. + 40.1 20020101 jl - Removed IDTA_InnerLeft and IDTA_InnerTop checks to + enable frames around masked icons + - Added support for IDTA_SupportedIconTypes tag. + 39.31 20010627 jl - Fixed wrong register for GetCyberMapAttr() Attribute parameter. + 39.30 20010508 jl - some instance data is now longword aligned + 39.29 20010207 jl - fixed 2 byte memory overwrite error in ClearMemory + 39.28 20010128 jl - Added Semaphore protection for memory pools + 39.27 20010117 jl - Begin revision history + +---------------------------------------------------------------------------- + +**************************************************************************** + +--------------------amigaiconobject.datatype-------------------------------- + + 40.10 20060222 jl - Improvement: replace GetDTAttrs() call by series of + GetAttr(). Now datatypes.library is no longer used. + 40.9 20060120 jl - Bugfix: CoerceMethod() in OM_NEW could lead to + enforcer hits if object could not be created. + 40.8 20050604 jl - Improvement: icons can now be scaled. + 40.7 20050427 jl - Bugfix: saving of interior window offsets + (dd_CurrentX/dd_CurrentY) didn't work. + 40.6 20041229 jl - Finished conversion from ASM to C, compiles with bith SAS/C and GCC. + 40.5 20031220 jl - changed library from "struct Library" to "struct ClassLibrary" + 40.4 20021201 jl - Enhanced cleanup - now does RemLibrary() on iconobject.datatype. + 40.3 20020815 jl - Fixed possible enforcer hits in Expunge() + 40.2 20020113 jl - More changes for enhanced compatibility for icons with borders. + 40.1 20020101 jl - Removed IDTA_InnerLeft and IDTA_InnerTop checks to + enable frames around masked icons + 39.24 20010514 jl - fixed mean bug in clLayout - somehow two lines had disappeared. + 39.23 20010511 jl - fixed serious bug in clWrite. + 39.22 20010508 jl - some instance data is now longword aligned + 39.21 20010128 jl - Added Semaphore protection for memory pools + 39.20 20010117 jl - All memory allocations are now being done via memory pools. + +---------------------------------------------------------------------------- + +**************************************************************************** + +--------------------glowiconobject.datatype--------------------------------- + + 40.14 20080205 jl - Improvement: Added support for cloning of existing icons + 40.13 20071228 jl - Improvement: accelerated icon reading by using buffered I/O. + 40.11 20070426 jl - Bugfix: Fixed handling of 32bit glowicons with only one image. + 40.10 20070117 jl - Improvement: Added support for 32bit glowicons + 40.8 20060819 jl - Bugfix: fixed support for transparent colors with non-zero index. + 40.7 20060222 jl - Improvement: replace GetDTAttrs() call by series of + GetAttr(). Now datatypes.library is no longer used. + 40.6 20060120 jl - Bugfix: CoerceMethod() in OM_NEW could lead to + enforcer hits if object could not be created. + 40.5 20050821 jl - Improvement: Reworked icon saving code, now it is possible to + correctly save a modified icon image. + 40.4 20050812 jl - Bugfix: Added size checking for icon BitMaps, to fix a major + memory trashing bug triggered by thumbnailed icons. + 20050604 jl - Improvement: icons can now be scaled. + 40.3 20050427 jl - Bugfix: saving of interior window offsets + (dd_CurrentX/dd_CurrentY) didn't work. + 40.1 20050312 jl - GlowIconObject.c, GlowIconObject.h: datatype now calls + "UpdateWorkbench" function after saving glowicon data. + 20050210 jl - GlowIconObject.c: Relaxed strict image size checking - some + icons could not be read. + 20041231 jl - Initial version. This datatype supports OS3.5- GlowIcons + even under OS3.1. + +---------------------------------------------------------------------------- + +**************************************************************************** + +--------------------iconobject.datatype------------------------------------- + + 40.27 20100501 jl - Improvement: arbitrary scaling of icons is now possible. + 40.26 20081216 jl - Improvement: improved multi-line icon text division algorithm. + 40.25 20080205 jl - Improvement: Added support for cloning of existing icons + 40.24 20070310 jl - Improvement: faster drawing of true-color icons by avoiding + multiple coping of image data. + 20070116 jl - Improvement: added support for selected state ARGB icon images. + 40.23 20061029 jl - Improvement: draw mode and background color for standard icon + text (no outline, no shadow) are now selectable. + 40.22 20060820 jl - Bugfix: incorrect check for allocation success in SetTags(). + 40.21 20060616 jmc - Improvement: Once CyberGfxbase found, chip memory was always used + if Fblit port wasn't found. + 40.20 20060322 jl - Use common code for image scaling and dithering from scalosgfx.library. + 40.19 20060222 jl - Improvement: replace GetDTAttrs() call by series of + GetAttr(). Now datatypes.library is no longer used. + 40.18 20060120 jl - Bugfix: CoerceMethod() in OM_NEW could lead to + enforcer hits if object could not be created. + 40.17 20050909 jl - Improvement: mcpgfx.library is no longer required. + 40.16 20050815 jl - Bugfix: scaling non-PNG icons caused enforcer hits and trashed + display, due to a NULL ColorMap. + - Bugfix: ScaleBitMap() didn't work with P96 - as a workaround, + we now always use graphics.library function BitMapScale(). + - Bugfix: Once again switched to own bitmap scaling, to overcome + remaining P96-related problems. Redesigned + WriteARGBToBitMap() for LUT BitMaps. + 40.15 20050604 jl - Improvement: icons can now be scaled. + 40.14 20050414 jl - Bugfix: Attributes IDTA_Mask_Normal and IDTA_Mask_Selected + didn't return correct values. + 40.13 20041227 jl - Finished conversion from ASM to C, compiles with bith SAS/C and GCC. + - Corrected minor miscalculation of icon bounding box, leading to + some pixels on right border of icon text not getting erased. + 40.12 20040814 jl - Added support for new IODRAWF_NoEraseBg flag. + 40.11 20040524 jl - Added functionality to support TrueType fonts for icon text + 20040611 jl - Added support for splitting of icon text into multiple lines + 20040611 jl - Added support for transparent rendering of icon label shadow + and outline (TrueType fonts only). + 40.10 20031220 jl - changed library from "struct Library" to "struct ClassLibrary" + 40.9 20030420 jl - Added support for per-icon "borderless" flag + 40.7 20020928 jl - Added IDTA_UserFlags get/set tag. + 40.6 20020815 jl - Fixed possible enforcer hits in Expunge() + 40.5 20020321 dm - Fixed crash when GM_HITTEST was invoked with icon mask of NULL. + 40.4 20020320 jl - GM_HITTEST was broken when icon borders were > 0. + 40.3 20020201 jl - Added attribute tags IDTA_MaskBM_Normal and IDTA_MaskBM_Selected. + 40.2 20020113 jl - More changes for enhanced compatibility for icons with borders. + 40.1 20020101 jl - Added separate pens for selected icon text, icon text + outline, and icon text shadow. + 39.38 20011230 jl - Major changes to support borders around os3.5 icons and NewIcons. + 39.37 20010818 jl - Added IDTA_Font attribute + 39.36 20010617 jl - SetAttr(IDTA_ToolTypes) now stores a COPY of the + provided tooltype array. Copy gets freed on Dispose. + 39.35 20010613 jl - checks for "FBlit" on OpenLibrary and doesn't use + any chip memory if found. + 39.34 20010508 jl - longword-aligned structure IconObjectInst. + 39.33 20010429 jl - Displays underlined text if IDTA_isLink is TRUE. + 39.32 20010311 jl - Uses no chip mem if cybergraphics is found. + 39.31 20010209 jl - Added missing "ret" in LibClose ... + fixes crash on Scalos closing. + 39.30 20010128 jl - Added Semaphore protection for memory pools + 39.29 20010117 jl - All memory allocations are now being done via memory pools. + 39.28 20010114 jl - fixed memory leak with iobj_name + +---------------------------------------------------------------------------- + +**************************************************************************** + +--------------------newiconobject.datatype---------------------------------- + + 40.11 20070121 jl - Bugfix: generating thumbnails for newicons caused invalid memory accesses. + 40.10 20060819 jl - Improvement: added suport for transparent colors with non-zero index. + 40.8 20060120 jl - Bugfix: CoerceMethod() in OM_NEW could lead to + enforcer hits if object could not be created. + 40.7 20050812 jl - Bugfix: Added size checking for icon BitMaps, to fix a major + memory trashing bug triggered by thumbnailed icons. + 20050604 jl - Improvement: icons can now be scaled. + 40.6 20041225 jl - Finished conversion from ASM to C, compiles with both SAS/C and GCC. + 40.5 20031220 jl - changed library from "struct Library" to "struct ClassLibrary" + 40.4 20021201 jl - Enhanced cleanup - now does RemLibrary() on iconobject.datatype. + 40.3 20020815 jl - Fixed possible enforcer hits in Expunge() + 40.2 20020113 jl - More changes for enhanced compatibility for icons with borders. + 40.1 20020101 jl - Removed IDTA_InnerLeft and IDTA_InnerTop checks to + enable frames around masked icons + 39.24 20011206 jl - Fixed reversed check for IOFREELAYOUTB_ScreenAvailable + in idtm_freelayout. + 39.23 20010714 jl - Fixed bug in DTM_Write with IDTA_ToolTypes. + 39.22 20010627 jl - Fixed wrong register for GetCyberMapAttr() Attribute parameter. + 39.21 20010508 jl - some instance data is now longword aligned + 39.20 20010128 jl - Added Semaphore protection for memory pools + 39.19 20010120 jl - All memory allocations are now being done via memory pools. + +---------------------------------------------------------------------------- + +**************************************************************************** + +--------------------pngiconobject.datatype---------------------------------- + + 40.21 20080205 jl - Improvement: Added support for cloning of existing icons + 40.20 20071228 jl - Improvement: accelerated icon reading by using buffered I/O. + 40.19 20071206 jl - Improvement: updated to libpng 1.2.23. + 40.18 20070118 jl - Improvement: added support for second (selected + state) PNG image in icon. + - Improvement: updated to libpng 1.2.15. + 40.17 20060630 jl - Improvement: updated to libpng 1.2.10. + 40.16 20060222 jl - Improvement: replace GetDTAttrs() call by series of + GetAttr(). Now datatypes.library is no longer used. + 40.15 20060128 jl - Improvement: Added support for "ICONA_NoPosition" + tag in IDTM_Write method. + 20060120 jl - Bugfix: CoerceMethod() in OM_NEW could lead to + enforcer hits if object could not be created. + 40.14 20050704 jl - Improvement: replaced handcrafted code to read PNG images + by libpng. As a bonus, the datatype now can write any PNG image. + 20050604 jl - Improvement: icons can now be scaled. + 40.13 20050518 jl - Added support for PNG_COLOR_TYPE_GRAY_ALPHA type PNG icons. + 40.12 20041111 jl - Replaced Assembler library startup code by C. Now + completely coded in C, compiles with both SAS/C + and GCC (No functional changes). + 40.11 20040915 jl - Bugfix: icon mask generation clipped some pixels + at right border. Fixed. + 40.10 20040801 jl - Default icons were not saved to the correct path. + 40.9 20040523 jl - Fixed severe memory trashing. Datatype used to overwrite + random memory with some icons. + 40.8 20040429 jl - Datatype now correctly recognizes and renders + AppIcons generated by PowerIcons. + 40.7 20040226 jl - Plugged several memory holes. + 40.6 20040111 jl - Added support for default icons via IDTA_DefType tag. + 40.5 20040109 jl - Now supports extra information about original + object (Path- Name) for the determination + of icon type. + 40.4 20040105 jl - Iconobjects now use DrawerData defaults from + icon.library default icon of the same type. + 40.3 20040104 jl - Fixed severe bug that trashed random memory. + Only occured with icons without fixed position. + 40.2 20040102 jl - Added optimization in alpha-blending routines. + - Fixed trashing of icon image data + during IDTM_Write. + - Disk icons (WBDISK) were not recognized properly. + 40.1 20011221 jl - Initial version + +---------------------------------------------------------------------------- + +**************************************************************************** + +-------------------iconobject.library--------------------------------------- + + 40.6 20071228 jl - Improvement: accelerated icon reading by using + common file handle and buffered I/O. + 40.4 20041110 jl - Removed Assembler library startup code. Now + completely coded in C, compiles with both SAS/C + and GCC (No functional changes). + 40.3 20021201 jl - Improved cleanup code: FreeClassList() now calls + RemLibrary() for each datatype. + - Added capability to copy/cut/paste attributes. + 40.2 20020815 jl - Fixed possible Enforcer hit in Expunge() + 40.1 20020101 jl - Added new library function Convert2IconObjectA() + +---------------------------------------------------------------------------- + +**************************************************************************** + +-------------------wbrexx.plugin-------------------------------------------- + + 39.22 20091220 jl - Bugfix: in non-emulation mode, an allocated + signal was never freed. + 39.21 20091101 jl - Improvement: Added support for "HELP PROMPT". + 39.20 20081219 jl - Bugfix: "menu invoke" always required a window, even + for menu commands that do not work on + windows, like "WORKBENCH.ABOUT". + 39.19 20050618 jl - Replaced dedicated code by new SCA_OpenDrawerByName + library function (requires Scalos V41.x). + 39.18 20041113 jl - Replaced Assembler library startup functions + by C code. No functional changes. + 39.17 20031222 JL - Changed "OpenDrawerByName()" to make use of the + Scalos iconobject datatypes. + 39.16 20030112 JL - Removed some dependencies on undocumented internal + Scalos data structures. + 39.15 20021206 JL - Added "MENU INVOKE WINDOW.CLEANUPBY.NAME/DATE" + "/SIZE/TYPE" functions. + - Added "ICON MOVE IN/OUT" functions. + - Added "MENU INVOKE WINDOW.RESIZETOFIT" function. + 39.14 20021130 JL - Added "ICON ACTIVATE UP/DOWN/LEFT/RIGHT" functions. + - Fixed order of which icons get select with + "ICON CYCLE NEXT/PREV" function. + 39.13 20020927 JL - Fixed bug in AddMenuItem() and AddKeyboardCommand() + which could lead to crashed when trying to add items + with already exiting names. + 39.12 20020131 JL - Now supports adding menu subitems and new menus. Using + this new features requires Scalos V40.20. + 39.11 20011030 JL - Fixed serious initialisation problem in Scalos + preview mode, leading to crash on any keyboard input. + 39.10 20011020 JL - No longer initializes if Scalos is running in + preview mode. + 39.9 20011008 JL - Changed priority to -79 in order to make it work + for text windows. + - "ICON MAKEVISIBLE" didn't always work correctly for + text windows. Fixed. + 39.8 20010927 JL - Added missing MENU and KEYBOARD functions. + - Fixed several bugs GETATTR function. + 39.7 20010719 JL - Forgot to UnLock() lock in FindWindowByName(). Fixed. + 39.6 20010718 JL - Changed matching algorithm in FindWindowByName(), + important for all WINDOW commands. + +---------------------------------------------------------------------------- + +**************************************************************************** + +-------------------wb39.plugin---------------------------------------------- + + 45.34 20080211 jl - Bugfix: WorkbenchControl() WBCTRLA_RedrawAppIcon tag now + verifies if given icon is member of desktop window icon list. + This stops animated icons leaving garbage images when + dragged around on desktop. + 45.33 20080110 jl - Improvement: Added two new scalos.library functions for + (temporary) unlocking and relocking of screen layers during + drag operation. + - Improvement: Added support for browser mode windows. + 45.32 20061224 jl - Improvement: width of volume gauge is now adjusted to + - match width of window close gadget. + 45.31 20060112 jl - Bugfix: Removed some possible sources for semaphore deadlocks. + 20051202 jl - Bugfix: WBCTRLA_DuplicateSearchPath failed to return + inherited path of parent process under MOS. + The code tried to find the Scalos initial process + named "Workbench", and that didn't work with MorphOS. + 45.30 20050618 jl - Replaced dedicated code by new SCA_OpenDrawerByName + library function (requires Scalos V41.x). + 45.29 20050427 jl - Bugfix: Replaced LockIBase()/UnlockIBase() by + Forbid()/Permit(), to avoid deadlocks while layers + are locked (Lasso, drag&drop). + 45.28 20041113 jl - Replaced Assembler library startup functions + by C code. No functional changes. + 45.27 20040612 JL - Fixed enforcer hits when text window icons were + renamed with AsyncWB (Added translation of text icon + types in ChangeWorkbenchSelectionA() ). + 45.26 20040103 JL - Added several undocumented WorkbenchControl() tags, + WBCtrl doesn't fail, however, not all values are used. + - MaxCopyMem can now be changed via + WorkbenchControlA() calls. + 45.25 20031222 JL - Changed "OpenDrawerByName()" to make use of the + Scalos iconobject datatypes. + 45.24 20030112 JL - Removed some dependencies on undocumented internal + Scalos data structures. + 45.23 20020914 JL - Added support for V45 WBOPENA_Show and WBOPENA_ViewBy + tags to OpenWorkbenchObjectA emulation. + 45.22 20020110 JL - The AMTYPE_APPWINDOW AppMessages generated in + AppWindow.c had wrong mn_Replyport. Fixed. + 45.21 20011231 JL - Added support for "No Color Icons" and "No NewIcons" + workbench prefs settings. + 45.20 20011223 JL - Avoid excessive Scalos root window updates + with AddHiddenDevice/RemHiddenDevice. + 45.19 20011204 JL - Added support for (undocumented) CloseWB/OpenWB hook list. + - Added Support for (undocumented) set/clear icon.library + global screen. + 45.18 20011129 JL - Added support for getting and setting delete, copy, + and text input hooks (undocumented). + 45.17 20011116 JL - fVolumeGauge was not longer checked. Fixed. + - WB prefs are now checked each time a new device + window is opened. + 45.16 20011020 JL - No longer installs patches if Scalos is running in + preview mode. + 45.15 20011010 JL - Added proper handling for WorkbenchControl() tags + WBCTRLA_SetTypeRestartTime and WBCTRLA_GetTypeRestartTime. + 20011008 JL - Changed priority to -89. + 45.14 20010714 JL - After WBCTRLA_AddHiddenDeviceName and + WBCTRLA_RemoveHiddenDeviceName, now does + SCCM_IconWin_Update on root window. + 45.13 20010708 JL - When opening drawer windows, DDVM_BYICON now gets + translated into IDTV_ViewModes_Icon. + 20010623 JL - Added full Support for WBCTRLA_GetDefaultStackSize and + WBCTRLA_GetProgramList, using new SCA_ScalosControl() call. + 20010524 JL - HiddenDeviceList entries now get ln_Type=0x67 so + Workbench prefs/IPrefs correctly removes old entries from list. + 20010523 JL - Added additional argument checking to myWorkbenchControlA() + - Added Semaphore protection for HiddenDeviceList + 20010520 DM - Some other small fixes + 20010518 DM - Hidden device list completely supported (needs devicefilter.plugin + to actually hide devices). + - Hidden devices read from workbench prefs file (scalos_helper.c) + 20010124 JL - Fixed Malfunction of AddAppWindowDropZoneA() with WBDZA_Box + +---------------------------------------------------------------------------- + +**************************************************************************** + +--------------------persist.plugin------------------------------------------ + + 39.26 20101228 jl - Bugfix: failed to save window state if Persistant_Windows + initially wasn't present. + 20101224 jl - Bugfix: updating saved window state failed if + file "Persistant_Windows-old" was present. + 39.25 20091229 jl - Improvement: changed saving of current state to make it bullet + proof. Now new file is written under name Persistant_Windows-new, + then existing file is renamed to Persistant_Windows-old, and + if everything worked, new file is renamed to Persistant_Windows + and old file Persistant_Windows-old is deleted. + 39.24 20090712 jl - Improvement: plugin now automatically recognizes when Scalos has + finished starting up, and will start re-opening windows. + Preferences variable "StartDelay_Seconds" is no longer used. + 39.23 20090107 jl - Improvement: Plugin is now able to store size and + position of Scalos windows. + 39.22 20080106 jl - Improvement: Added support for browser mode windows. + 39.21 20061230 jl - Improvement: persist now skips opening any Scalos + window if shift key is pressed. + 39.20 20050618 jl - Replaced dedicated code by new SCA_OpenDrawerByName + library function (requires Scalos V41.x). + 39.19 20041113 jl - Replaced Assembler library startup functions + by C code. No functional changes. + 39.18 20031222 JL - Changed "OpenDrawerByName()" to make use of the + Scalos iconobject datatypes. + 39.17 20020501 JL - "Persistant_Windows" file no longer is deleted during + initialization. The advantage is, if Scalos crashed before + the first window gets re-opened, the Persistant_Windows + file is untouched. As soon as the first window opens, + the Persistant_Windows file is rewritten. + - The re-opened windows won't get activated (works with + Scalos V40.22+). + 39.16 20011228 JL - Disabled some Printf() calls. + 39.15 20010803 JL - Reversed order in which windows are reopened. + 39.14 20010730 JL - Changed name of prefs file from "ENVARC:Scalos/Persist.config" + to "ENV:Scalos/Persist.prefs". + - "Use_SCA_Iconify" now default to "1" if scalos.library + version is at least 40. + 39.13 JL - Name of persistant windows status file is now configurable + in "ENVARC:Scalos/Persist.config". + 39.12 JL - When re-opening drawer windows, + DDVM_BYICON now gets translated into IDTV_ViewModes_Icon. + 39.11 JL - when re-opening window in iconified state, now immediately adds + entry in persist file (no SCCM_Window_Open will occur, so otherwise + no entry would be generated at all). + 39.10 JL - prefs file may contain comment lines beginning with "#". + empty lines in prefs file will be ignored. + iconified windows are remembered and re-iconified on startup. + +---------------------------------------------------------------------------- + +**************************************************************************** + +-------------------volumegauge.plugin--------------------------------------- + + 39.8 20061224 jl - Improvement: width of volume gauge is now adjusted to + - match width of window close gadget. + 39.7 20050618 jl - Replaced dedicated code by new SCA_OpenDrawerByName + library function (requires Scalos V41.x). + 39.6 20041113 jl - Replaced Assembler library startup functions + by C code. No functional changes. + 39.5 20030112 JL - Removed some dependencies on undocumented internal + Scalos data structures. + 39.4 20011110 - some changes for compatibility with Scalos 40.14. + +---------------------------------------------------------------------------- + +**************************************************************************** + +-------------------deficons.plugin------------------------------------------ + + ./. 20031231 JL - Depracated since functionality has been integrated + into Scalos main program. + 45.6 20011230 JL - OpenLibraries was called twice. Fixed. + - Added support for individually enabled/disabled icon types. + +---------------------------------------------------------------------------- + +**************************************************************************** + +-------------------xtwindows.plugin----------------------------------------- + + 40.6 20050325 JL - Adapted XTWindows.plugin for PPC/MorphOS. + 40.5 20040102 JL - Adapted to changed OpenDrawerByName() function, now + uses iconobject.library instead of icon.library. + +-------------------- sorted_cleanup.plugin --------------------------------- + + 39.4 20050320 JL - sorted_cleanup.s: New attempt to fix refresh + problems with sort_cleanup. + +**************************************************************************** + +-------------------ScalosCtrl----------------------------------------------- + + 40.16 20040104 JL - Added new CBS=COPYBUFFSIZE parameter. + 20040102 - Added "QUERY" command line switch. + +---------------------------------------------------------------------------- + +**************************************************************************** diff --git a/scalos/InstallAROS/InstallAROS b/scalos/InstallAROS/InstallAROS new file mode 100644 index 000000000..4fbb1cc16 --- /dev/null +++ b/scalos/InstallAROS/InstallAROS @@ -0,0 +1,101 @@ +; AROS-DOS script for installing Scalos on AROS + +; $VER: InstallAROS 1.0 (26.12.2011) + +Set target="" +Set subdir="Scalos" +Set target=`RequestFile DRAWER Extras: TITLE "Choose directory for Scalos" SAVEMODE DRAWERSONLY` +IF "$target" EQ "" + RequestChoice "Information" "Script cancelled" "OK" + Quit +EndIf + +Set target="$target$subdir" + +If Exists "$target" + Set result=`RequestChoice "Warning" "Directory $target already exists.*NIt will be deleted if you continue!" "Continue|Cancel"` + If $result EQ 0 + RequestChoice "Information" "Script cancelled" "OK" >NIL: + Quit + Else + Delete "$target" ALL + EndIf +EndIf + + +MakeDir "$target" ALL +Copy Scalos Scalos.info History readme.txt LEGAL "$target" +Copy IconDatatypes "$target/IconDatatypes" ALL +Copy Libs "$target/Libs" ALL +Copy Modules "$target/Modules" ALL +Copy Plugins "$target/Plugins" ALL +Copy Prefs "$target/Prefs" ALL +Copy S "$target/S" ALL +Copy Themes "$target/Themes" ALL +Copy Tools "$target/Tools" ALL + + +; Copy icons +Copy Envarc:SYS/def_Drawer.info "$target//Scalos.info" + +Copy Envarc:SYS/def_Drawer.info "$target/Modules.info" +Copy Envarc:SYS/def_Drawer.info "$target/Prefs.info" +Copy Envarc:SYS/def_Drawer.info "$target/Tools.info" + +Copy Envarc:SYS/def_Tool.info "$target/Modules/Delete.module.info" +Copy Envarc:SYS/def_Tool.info "$target/Modules/Empty_Trashcan.module.info" +Copy Envarc:SYS/def_Tool.info "$target/Modules/Exchange.module.info" +Copy Envarc:SYS/def_Tool.info "$target/Modules/Execute_Command.module.info" +Copy Envarc:SYS/def_Tool.info "$target/Modules/Find.module.info" +Copy Envarc:SYS/def_Tool.info "$target/Modules/Format_Disk.module.info" +Copy Envarc:SYS/def_Tool.info "$target/Modules/IconProperties.module.info" +Copy Envarc:SYS/def_Tool.info "$target/Modules/Information.module.info" +Copy Envarc:SYS/def_Tool.info "$target/Modules/NewDrawer.module.info" +Copy Envarc:SYS/def_Tool.info "$target/Modules/Rename.module.info" +Copy Envarc:SYS/def_Tool.info "$target/Modules/Updater.module.info" +Copy Envarc:SYS/def_Tool.info "$target/Modules/WindowProperties.module.info" + +Copy Envarc:SYS/def_Tool.info "$target/Prefs/Scalos_FileTypes.info" +Copy Envarc:SYS/def_Tool.info "$target/Prefs/Scalos_Menu.info" +Copy Envarc:SYS/def_Tool.info "$target/Prefs/Scalos_Palette.info" +Copy Envarc:SYS/def_Tool.info "$target/Prefs/Scalos_Pattern.info" +Copy Envarc:SYS/def_Tool.info "$target/Prefs/Scalos_Prefs.info" + + +; Copy catalogs +Set result=`RequestChoice "Request" "Do you want to copy the catalogs?" "Yes|No"` +If $result NOT EQ 0 + Copy Catalogs Locale:Catalogs ALL +EndIf + + +; Copy Env +If Not Exists ENVARC:Scalos + MakeDir ENVARC:Scalos +EndIf + +Copy Env-Archive/deficons.prefs ENVARC: +Copy Env-Archive/Scalos/icandy ENVARC:Scalos +Copy Env-Archive/Scalos/Palette13.prefs ENVARC:Scalos +Copy Env-Archive/Scalos/Pattern.prefs ENVARC:Scalos +Copy Env-Archive/Scalos/Persist.prefs ENVARC:Scalos +Copy Env-Archive/Scalos/scalos.prefs ENVARC:Scalos + +Set result=`RequestChoice "Request" "In what language do you want to install the environment?" "German|French|English"` +If $result EQ 1 + Copy Env-Archive/Scalos/Deutsch/#? ENVARC:Scalos ALL +Else + If $result EQ 2 + Copy Env-Archive/Scalos/Français/#? ENVARC:Scalos ALL + Else + Copy Env-Archive/Scalos/English/#? ENVARC:Scalos ALL + Endif +EndIf + + +; Create package variable +Echo "$target" >ENVARC:SYS/Packages/Scalos + + +RequestChoice "Information" "Done. After a reset you should be able to start Scalos." "OK" >NIL: + diff --git a/scalos/InstallAROS/InstallAROS.info b/scalos/InstallAROS/InstallAROS.info new file mode 100644 index 0000000000000000000000000000000000000000..f7eda7f59655261eaaf9b450cfbd4c674929f6e3 GIT binary patch literal 4024 zcwV)Y30PBC7RPU1@&rr)D^oUEtXe1qWr?65i|7Dl8l*xMqwLU7P!ZH1ib@dBTG6!N z2#G93BrFOph$w>WvW1`mvWN%*ks`8`B|wswd0B94=lkl+*YkaOznt?w_uPBW&3)-# z0x)2~Oo1i9p+4p-)WDw^1_u^2s`T^LmPjC~0*SJ);A0FU6d3?mF{wa?iUwuMfr40+ z67+&k{x-@`!^OmwkBf;Z@0GAmLeO6>;UrbUNGWZkb*!b-`oLe%BcZk|lMq`W znFmYlm98g5Ohpj>m)8Grl=QV1$cTt72QuQmm%r&h5CH-Iw_)Bq{)>s`;REogbUyL# z09hg>_}|F?Q`#_R7&$9pnYV-pRl*)1^`$J6 zGEz#eBo9H)7bSPDPfV45^n69EqKe5CoiEBM(fNufX$NLN$`~neAH#*~yky}vzA;(x zb2*TtZv+td%O>k*5$LxsI2_nJyEp-WKjFC9d5gX6W;;|{v~~mfG<0;bbpQZo1r)Iu zj4TcY22p?sFc930!@$rCz`*z}3cL&xQYXw+q6+ALCC#Kmoy`TN0JQ0)^SPx{OGNU>wYq zYCLJ~9E3} z%X2@_#05nk0W|ZjG=@q%EQA)FdN(|ZRuiDrpx-};itCL3F?IaIqI@)O;?EcHVOYFw z^zq(YlHDTWA(QV4d`Q$b$wn2>?qL^HxrJkZ&_hCCQCYtDxv;Z^LqLDQd{N)A^YB~o zO>G3?i%X;3#ZJF3qN91@inHR3nLnt{-;D?$2!0!a#gn7cf;S<_diZ~T1d>E>P^Z)b z5Q6E1MRya=1CqPh4FkMrFb}=p_$R0U&5OQuh`!ANbSwC7(Or)M*#JpK03w7eEZPwY zQmxQ_o$|^zS&5=cu>it$CBy<>t)#1a-NJ$*Y^Ue~TNj5-=%4-y^o@eP#$;3g2v2^^ z_=fmhfa*zGd3<7Z_K3$VC&yfmZ!ZSNRbT#eZ}H>X#>~QwohnX_#IqOUeev=+`15Om za#y+RA$eEk?abd#w_Wqqfq*2n;1gUPTyi{x>wLf8+~%bQJCjgM9XPxG0GV@a_CB|) zsebvTIJ?zBTlG||B4*->@7>F}bm>GxLxbnCZQHj$?(JP(8a`2}?0oE)RUWC}q=|`% z=dL`DdlxLVXkVmOolELjyo@;7PkLS+fgE_x5O!OQD#Wu3g)q z9JJS=u(0q&!8y$h_73MX(l?({*cuq9_nC@H3nJj^HpR!mXPA8br?UGa;N ze?xP#TYg?n&gU6v{)Tv~NW^_$^tYC*P0p#7>9sWNmhNtiCN}$Vh68P=uj+EstmLrk%5b+c=2PKuJ9Z=*dNJeUm&WRC z*sv=x(A#_CU1m;>W1o-Ez$l00ueHv=gru#qg&wC$QR#TfLe|SYk!W5F2*D&oR7%}zt(JCT# zM0m>|?W=?sS9m1YVpkG*T{4=ce+CTX&z1{p_s0CZV1l@jJ;ru~j~`#Qnj&O2qB8oFCjbx$=*3q(?Q|4HHX5gEB9Be3Rr|B)w7R~xz1YhEl<-@(|anmdT0@p zWheJ8UlLLsQ(%6#wpX#RpaBwesy=LLxsCN;7C!RxnG+m$Ag!*ozL*R5;%2+fvXIysH8>PVhbLKW3 zeFv;}zCeh!j1Ekv6d0a=IMto%Len7(nIBgu?PyiISzTGl=+aZ-=#7|Ow+_(J(q}y( zFjBu^=OO;h_4LkEjg_+u#j@AG4*ft(6qn`CO`b~%$&Vu(a_ z{@O+1C?Y#}Jk0)Xeo4^7TV|~OlX3xd=u%G~$ShixD%8g^(6j?uJ*nX$OVMgAL zNZK(w+9IdK-ZjWFN_eFH>$o?1lt(L)0+E#~jT@dn%`YJbgcj*F*46#^^DZ3o#g&{x{uB}gYATj+Gwjq12J*|`mD>N#coj~?0*rqHSp_@fqf9Pid*2WS+uNQh}liSRFDz!Y=pBy!E%|$Cgv70`> zp&Zg!Z5pMmC3Hzqvr<-mlCdS}IyZrU)n=U^W~okW91n_>dzr^S8W51x;aW$pcsY5P zA|C8Rd)m`uy^rlg_SI6dPDrykGL`L(z7(`AnOW#`mF76k7NfSdHofDC2BZ@a<{aZb z9y2*vBebdE-}*HjD*{f^yU8a@t5(kRS*JOVOkO{ws;<6tw>ImFYC#{?5Bi;oU=%Ok zr+sN?=*-!AC!}ntSJ9E_pwKa`p0v_SqvJK69WoI<+T&D>Dw!B$Y+;e80XWE)~$w(MT003mFDvG)Q!2U@BfFSsH zdtv?S_J4-9y1vps^S>bkfc*yyAOY+@V1N=JkO&whfKkE#3Lq#EFcg5HU;qseC>R2T zfS~~l4FgO7i9#aKFa#O_V*)TH7{CA|8i`>rf>MkN7C00onT0a<{Mgu!G1r5Gi^0fa1!QW62f0iXzw zvPc9DMkz}PQ~*K|hEPPnQ~)K8@*gN10;mJjKmE`7pFja^fKZ3Qv;j;TMyW!HR7apx zkO*zqKTs-^lj@W z6X<_nEYO^0oEQrX#u|nBXIf*>&S*}1G>+?_BR}-ED0)sPFv6+5MY!ba#aBH|Mn3 zwC>sNwXJ1DQo#WD7qhC0^7_8hTMxACXZtcJq{nqWrVh-KMw%rnR5YeNwLnjwOuW6u zZ2i#lnP245nD~+9Shyx!{+Y^Gw)g47trf!R-p9kTkL7# zNw>dn-aUSG>LzkAsms)f8tk~GQ?l`H_iTLkY~!7lgzNcSuv^>5`I)d6#SsZMth$Io zFS1L$R}@Yn;g*88IMS#)R{O@eVYe*xxPE!B>h0@n>V!Y2U{ zZ_7cPYRRsn2Nj?6rFm(`y;p@~L)a%SU0AU{;neIuM34cKSg*#zYRpwRN#7ko*wfrZ zRX^sPFYyfETi}G7!&mkUr2>*x!OotEGme+9ZP8~@ksk_Q#Hx?YrCa@b=+Sg3vsYS> zPlMb#IqCkV!S7Burz08Z56}ex*=x614T~yx2fmkeC@gw~;U(USORlLBcqO|;Lk@L# zy7f%+S@{Xu%SuwT{GB*&mog4cXK-ujb7^-_SwJ!RPqv8xTrY%C&yCV$z>0N>T+Ahg zHkQ{jcdIh{UB!sF{k%uo^&6J;nI(;ulVaTn6Usk2-yHLq|1#TF2##~yoO#S7A1ftl zSCwH>{phQzNZF*Lzf?|mV+Xrb#Z-v(a5`l}ORyWPu(WO@KjQ51vdrnLh<6)}ehZT2 zh69hu#m6B4ro&V_^kS0`R9*gEwaFD8|8py{`U%q$_sqllZ4>Tk<5)XK{$h)2=EvF{ zGuD0A2j7n6OeLYl#omp#41K6T+%$b|yz+^!v7mVK_50M1=#A5s5aToJL-90<*SFN4 zil1`P{yvS&s`T9QxvJe{{+O|n;RWkc{vlPRL0L_lp&!kG6KiLtI(o70uR2_$&JVEE8acT~dtoaZ0pDGV(erxbpP70zz-It$@kOpIXk<3MIt*&IBv?ibl-8+Nz$$2-s z%zS7Tp`e&BdSRcvskwP@u6cip&m>ORCd)P*-@yo{M3>vnW+)0S^O^PSOk2gI`T)gUP`T^QQe@23)%B)u z>|I*AE5s{Yz3qxuHAjtEPo=O!l8E=rtW7BOmA%J=rR3fXQrc$24^~o}b|Lp({v>3O z{o#;bN|HDP!%v5Eh7vuR3O^-OT|G!={b>f&epZ z_pc0^`sARvrs`2`-0(02@F{==oh&Bf@oQzwpnXJxZ+|945$px~`UR($o0-2Az8d?H z3cjq!MN9SvE2Wm)A-#ddb75TS9|`5tne0F@{WeE6!x9N6-9^_b>1+*@3ly@lQ;EPD zGy+2S>JrO*glza3&(mN7*tffVh5$o5{jv1yP4%ddpiZR5>E`oLJKkW8Ti7Oc!q)`gh<^v=~aalDv}jMke2i(G<@NHPHM+R8j?g?%q|DHnGpYV?33Ov+ek&C^565dn&# zJLbYa(?W0}4;7QNsc*V_{td~>k|lV;zBN+u6uM^k#pkGf+Qd|e^dS@{=S0cx#-P}N zCM~y`$Guj(sDWsZ=U)gk}&%$ zIQ2IK96t5DSwEcu7XJ3X1h_TA_#C^t;#d)HJ^=2kYF1Z^kte$Tf#f#6RslR+^oIK7 zG|^>tyZ7HNaX`Trn7spCqaisMe;Y1@R}pcC#9ewl)y{6TY|uI7OBC*d;J=WZDL0@0 zP2CcpQ4*MO1eoQrj(+6SlSNSJ(qJXI$pjc&U|{mso0+WEsaKIOAgmqXjf$kp^KKjQoUg?`*MXwYanNdA6$)?`6?vqoTF^3+HB`SgGc(62OkN0= zQvv6X=aMAZk>Xti>MXC{I)~i9o89c~^(5u;WC`x|XQ|h%&FV$WopPRyjtCmO!KCFA zh~IVm3^i!>QU&ceLI2}3QLDt`c$lu(ls<=SDl5R-7El8<53fu!Yb^@9?%x2kf4iZL z0PRt(+|)i^5XI%0`yLSWm7euXF*j;Z%n9H7ymh|C0KxRzW!vQU@Q?#_BBL{l2`Rv& z2HN%T#<4C&QsD3_1n@+T%da~e9YRWozsZ<=)O_*tsRR^Misilyt-hHQ7j6ahc@^u)*c`pp6D#p$G?rdilW9QP z^#hED63q|rM7a8VS_r`1Pq5DtA_fbp9m@1i-V%U9vcwkY-~Q0}YjxWro?@x>ArOd|qu1DFQ_D^GNNXC470fH#WD%fkGZPcrS~OALdIR zFQtd{Z1;CBw+Fr`GF!5%Uv`zpGw8D;7M9^;Zli#d3;%tA{v0hR$a}^a7Xz6JTN>0Z z$W<3{+U7dA@pg#}X}g$c=;96;+q#cZY$q{C=H0m3wZB+hO|>gQ69)1Sb}MqlQ4~?o z)hXX*Ikl6xCS588&V4GieMe5;qi z6Li_Vsnoe!>EcrVFEwqsz4F3n)+o!w`HOmKvW-X5d@3?tKC?upNriMP=Kf2Rys~e0 zejDvPEH3{rGGw{{JluDvmtEiIeAu)EF(xhzY&@;IXF7YkwjC&Z)nb`m?hf-{XD3QD z@l)@1Isihrly??eA4io8qkGPm$KPEgsVsGBdF>_=&D?UK@w~Lb$ z!1$Ds??Pfz!qPH@>T1$7Rx_&)Vh5@x?cR^wFK4*co&E8e%59JGYnHguk8RKLHIhJFYkS&l-S`e$3#<#DRfDT4&Dwz_*${5n;rB)dn}AAx*XlJpU$s%Y&@>WR0JizUl;|*|t?!OVh zT~05mSibLvx9fpe$X3U2Xy{6=PA);E1QIR<0H|P=!aVAEp8}J5{r;CfuZ32u%pGVFM-JQ zyld+S06tiMNB1x_f;}}IE&zxsUvoLXy-i>}Kn647uIV_TC4&I1z4wGbVr>D1QB}lv zGXQYa2U$4vn7l#CgEGI{IHVM1@u!0qC?|Q?K;gDOXifrF5-HGw{UZ)^evpB1698IP zjpK+fDnZU{EhU-NS{Vg^jflzn!5>PO>%ZF~e9UQFQ)|$iMs~KoIWS4(8gw*`YuLaW z%89OI{Rj^&y2QSf|6OxR2HLy2LI(&ln%s!i*JpF+l)JKbd~mIjS5|-9v6U;5N98kP zKNn@6(@@<_jK4@ah6ArFqm%M!rmLrSgEP}tuv!n^05IR>`<@&aBAN^ikwJsQayspB z`@2E(3x_h{=93o=cmBjtRM*`|Y+jRJi-ZG8rI9_^XZ<~MmtjqFqByy>n+grznq(ec zBv@0eo;7IVNf#pfUR$T6bF@GW<{huIds!+xZku|QU2?`e*<q!5fCR z4a)Z@4~8EHUY@qi8oraNC&xW$J^ZI&OZhE2;lEMvV(xE}t?G4|(!e%?a@Hh&~&4@l6v)N-CDQpP`jwBF5iXS;XdeB1ul zvQ1aSSBWdK%tP$3(y~(0(d;a@d>-8~D5Th)XvY4aB zuk8Q$#^Q)>BLvw#5nILjJR?eHka3*WTAt-E)m30hk~UH4FBzfLu9--G0<*=Cdc$Xt zxFh_0wcpE%C7aw2#z_J3Ij5F`>E5-8yah|j2;kCNI>#n;Ujzc_VRV%!#P_3!VF#fw<{DwkCH0dhGr~$Iek=2y6fnu?qgm!xb{Q=!5snt$oAPV5 zwT+VEXGy~DX1ryz$M{A{nakU~5*^ZVZc84(UDU0TxcOdNBeXo~T>oY5p`J4t#6PAJ z`lIHHqEKE1D^nQ*dG@zw$b0H_I%OR?sgs&!&4RW5CjL z_olRA3za`1CFkTrdGGCm7LN$6oiNYiLzNV|)5b%j3N4DbY2K9govQK7jOf5S`+$KhvAdG*%0lY)YyxaN)Q^uC+_c<+ zsuu*v3yOEOL}_bar)=M-4eeF25e)+I^Uts)tjh42uXK!BLDN6s7+L|G)tXl#dx~c) zo^L8vy5o9Doeg^WGn{K&msE^z8rEVI^xHr>p7VT;#I$dP#LayHcqOYaU_GR3Pr7gqTL>2VLX!$28VWZ_s#eZ}0MLG0Rp7Jh5;^_K+~O zn=N*smc=D0ypvjm)s&Z)?*EZu%?9^IOBt=%ehE4+lX#RG@JJ<&2;%eC&Vqf2f!|&=Dveha+F&JE=d(x}?8q2H5G?OH+pI4sdg?pDIl*~6!C+bIn)t)dI z2wOF_82mC%L)>nnenR!)-z2zH+mOWP=RO3S?Z!y7Qm* z&HA2k&)(M~|e52Ak&F>Yf^eo;?lQJTw{d zicKK|ev3ape4&REFpEy5i|1)o#E+++FTp_A>-#P{WO+;chVYchjvGq6Jn#AT3apoJ z_|BD;uZQ>ig&mA(KPxMJFerED$mrvr_OJGxiK z6YSNReql+a@pM9+E(Qs~Ec^LmOR6ZXkuDA0T&2~$RJJ@yv;M+I@1nQ;BZ4D^|L4m?zZq(U8(tc(>=Zxt{!ZC)U~~9< zWWD1H<@08SJwbJJb|OFIoZ5is{bto@5Ly0xBq(MuCyEQhTq_74Yu2tzr6)PcoTR6L z0F^k30pHtiOl}DWGW}v@NtCc4n5qrg7;Xth0*qBt+sWUaXFUD>J9~{n9kGlTr9&43 zxB2hGKT#x})Khnc2(vl>(6_08G0}K0LDck%fa2e|U3pW+MR&fZbh-!9?t_E;D@@&= zMX15>%S{#G00?Y-95S3Bdy&_^Y7A{S@@$F?cEm^@kBYy>sF+$u7&A?AD>KHtizU0qTRy3ZOh)v)#9~L4cFLPj{~(fp$Zk z76BMg4{UmV{BBxvb-vYq|7tn=w)4zX$|o`df$?qeF&ebG0=>g{Juwu?S)gYjOItJT z@JR*V7kKCG2f{K0nk6c^a;~LgfRHbRqT321JNSrYhw+iFGXs>A@O$S1dEK;5$FZT)Yz z=wR1YFU@BtIx%W;U%5I?Q$)A{mEd0s3;V+|GF;fO)U8i89~QEc7WdA4HmUJyf6@=w zqhUYruEpsGnKd_A8actNoIQPd^v2F4C#d-0l)?$DeHB1TSQrUp@01P(khi=am+AI$ zsm#Y8k$vsK6HABcF)lqzT1>LcP;d(=Y**l4dpeYBHNiHo)VwNDpq}6{i6>=)SR};KS^;y7QXu= z5+{tsY8=9G9HU@4gV=xMy)}8qL?~j6e1LVmZ-R8o4rJ^i&%V)bZ+S;d=rh1`cXxvK-VI>y?6Dq?@ z&f%J#Z5C`?JN_u|$xE{=WwsI5+m|P7dIPkAou^sAYdrI|t8PsR5D??#*9B(&cdU2w z9Z+Y2jY^50L_YSiE9wFgI9a73d$Bl4)Ai@-B~q?f!dN$d>T}ebgg6IqEFY8d_;Ry65c{E#s8XFei<>osO3uG<`YrtI zC?M`qr_62HwAT8i4>BrAYpScjaECeKcaJGK;29cnHPI^BhWu37eF<`9jDC&P2;*(g z_q;s~GwcZjW0PO}v9@`G{w94bqSc0F*?dzGv}^II5V6x^PER^`?gA4UdH{7laDdbV zi_zkr%3r5~LAyt*V9!jj(xppc_n$l`y^zae9*WACZ!k@-e<^ z<{`WfW)TKYh3>^)&z(>Oot%DG3TbB6P>Z3LombngpC7xqTQ>3da9vFY=(d8jpboI= z4#9w!(!W2Kw@eq!j$*^`217M4&>bMe{?;)Zwy<@~@mNi?WJs9>mw+rP0`Dw32o~eZ z`6+OUDs3WyJ9K~c6QFws4;Pq@Nsr{$p*3n$_;fw|FPMctiMHbC#Xe^;6c;N(3w))| ztoh9m;^neO3Qg|(%_qjXCikm9C-`=EMj#bd3WYv}wW-4Kr2L+I078tj`y<6>1;QMp zqzJQ!;BLz(9NxRDdNPN8R@JF;HScj0d}p2YDJh1FzCDeJNlS3@pr`9<5lIy7kVLF5 zl$C}IA64ItEzK3b2ci7wW6D=Kp)fDcBvt-uq-?^35^qMTw|{WCKMCuSlBg()_vnG(NIiXH8?EhWPDj^odbpffgj#Q^DVK%ho;^Ur&UeQ|VC{k4kt>2i11XK-_eidy zUT{MDS8}Z_-~2_UFJDj1P6QD&kc4N_8L}^_w8SUj3E3t=lkA=ysq25m8mv?3`hMui zCZ&~C4JD)SrdA!}c44EMGea40+#_>&ei3RQmx4V+^vC^$eu*U2ehKj5>lz;3EJ8`d zDr0>#%rh#WLKWsQ`XyO?N8f@^GLpu5+JT|Mck?6{X->xw?u$UJ3W|>UhCL4%CEe>m z7LPML?Qasv5OQi1Ot45YAt)bTqS4+P%`YcwK9rBHxfYkiCA)P=|BD27CK(Hfa9~eB zK<`Fh`kK2=rn@|Tf}7+>`h{D6`9dDUoU`ymvno{2@n4jFEQC5Wx~q;ttZt>_^&m9v zTT5shlb?dvXuS}jHZ@A0jep29{bwcqY-^>Y{S}`JH%rj)V}hL{&lHowQr7QCq;ymw zZ`uz7rO^QLp!!=6whvQ&`NoY4$pgOQ>EU~m>*A!a_TNdI3^)*(y{@&9B6E36zpZr- z`!PP@cx=}e?OWxqeE4Z|a<+(nOq?BXa{`@{m7Byk5putNXs%e(bE43D$J@t+E$_t| z#b=@OKgHlNFbqlfv@XhIW`qIWb_Hk9Z}*Ls+bnxZBJcu@LX==hA5mMf(F7N(ucsgAo- z`lKcMysXT^SGGZ5K>dZ7mmo4=Y%>rGnpuNpcidr(kIT^cTpww5S_B;>C& zk6^+WeVC+a%p>;nmeOgnm&7lrEA-3#$g(ik!}wAqZ^Q-g>b>7j|G6?leNXdKZ`@>v ziJ*J_bVa-f{O!muGlNo!*GH_$0A9i~WE;OVIgE0e&%faJkO`d2X(m+iK#8mXS^~yWb?(w$;(K75;h9_N(g?mlm$n z@;n(~DGGM|R|3}oZDHMv_f#zXkL*9wR+!6gBw}|Rrs{&cn3D~IKD%4j-JdqDQsj6) ztl|Fue*xyKewFM~UOjmPu^JBS%(rSaYhl0!1-a5061;SMrg>|y@s60T+B8bvd-A{* za3fy!{A8=^9YWwe<_lVkGFv~#G^Fh*|<-q5jX55vP^3=tZdXouJMx=7MH<&U$DV@i-L>vr|xNgaT%~# zdCx%7SZllYn@@j%y2NDjp_C1chVaiDyO(rpt9;eBjdi{S9Di11cIBN!>vD?!nI05U zxte=J`;JFVb$#&_zxhZw_rtAo$7i|U9~f4|b#CvZ%axS&&?Kol{%LIEox)ri*4F3E z5-yq68~k7?51!dJZlO+HFO#~ZoE{bC_$Nh`PTp^M2flW+@jmeEVOjOYwr*TLeX!`CXrbvyPY{Cm25v|V7+>%O!B+n zqix>Q$6yD+*jsH&nB(U!I6~JgXS0VtXIH;I$4HSU_16EHemd+@*w#T2Zc%&>IvV%m$#pqBiABT}Hc z!?{?q;Z*Rm$4F`3n$~twh3m|%2lK{GNrb<+-fAoP?PboR;2Fcj z*e2H}8xPUCdmkS*mpteQBi-r$6`aTk*gq6E`41>OK6I9LeeCaRAetVfn1I6N#dI@U zGzDSF?-SbE9|m2X%lv4q#Co}eZ$9L-t=%bRvsDU;Nj!c#|M2zK$^iJ@3HgJeo0F!2-`AP8JiVQ|c<+ zR@1dY`kx0X=#ZjSv!{!XrFd-|hY;{`5%Nn5+Q@%(;bpR6vA70aj$nRc*)^5c;5NgT z&nxXgCJ&?C-q)SUzEMSMz;pAyQ3!kr#047u@HZ$QY8dgg@IE4eSse4^kuE^`b6%0) ze_EL+KH@A0IGT$|{U9R@9DfkQe_Q86wRJYl&wt0ka!YH2hWp(=N}tg{DDjNn2w*u$ z+@SWB!j3!*lYXJX7#o@!l8c*7bH;K4Hm8xlPuka{n(pZn@MmE=c4MfqzJjHbz7im<2RTw@C?OY7f$X(|%&p>GZbxHXuIgcUvJekt> zThKvbaGA}y%18%9j(t7uLvb?DW*(MD%dg67))kY#RuUxp3k9a61EmANR3*ClYz7q5K{C z1qE#<9JD!F@dzz7;XVNno(Exke9Ad1LKI2sefP(o%#(#-^BNqN*UW1P>9kQu`-hS~ zV{MKZ;%4{*1le^>^6r{4eW%)6(=6$4G%^W(mLn3z8RtjqsP;zjFW9N^p)EpO(am4+ zq8zD5yd)~u#rTfmj=uFg^i=FZQd=biUOE1&&JA0u8rk3r3<4+DJw%r%b12RP{{D5A ztaOcobMvDz?;zC88YxCiIUS)q7l|+nI4fR&oZ|2#`bm8C{Oc8}(67TdPLS`*2h?XN zTnt>_P&~N@!LosH>gc=tjo=L>e!s1O?XDbougCJHgJPW>MN}v2K&+7ldiy!|YCdWt zLXIRDMvu>lPcM09oiQTD`YO$HDn){V*~N5?AE%WA!`oJTH;)B8OH1>6(5+i$5k}P8 zNwPe}c^!p>U-o7FuC^{V#BL;I_$ zxw={QNnj$*FnWtZlA&p;vXiYU75DudA!6LWCcY*1r9Sx5s*y0N0<>Q~hy>?iqN}VX z)?YvU+n=@l4CL$3+1xp6KLwB5jDF9KRV|U&Q4Nt@5~v7`qUgVt)}F2x-*10}!nvpw zJeJ(95a8`y)RmlZq0zk#$1x35^uTey6Pr(FIY>|L1)~d_o$K72zZqhgZ9OWo$DQu= z!E=Sr*YBE;v?dkh$4q~D*zEt*y>;>~zo0>goR{C7JgRttRH@iSnekroR48zdMSh}Io6F(RB)P5AJz&Uq)*M8$Dga0gv9l_(jzPt(% zz(|CbxVuogQ_-0PL0xZ~0S=j>_j11#MI(Y$GWXSl@akR-mXz9S_9;X-j!mNa+Xx)$ z)pfAp6>6joiVgfN2ws`jqd+k_LSeX>8cySA+YABN$Q4$37c)je5? z(0dyKE9aHL2la0!#7Ccrv-K8?ne_4kx_h_J<;|NfiYZ?!W#(W1Z5DfcIKj$|e}KvkDYBrM+6p zRKRpEPW!@PP2-ccOUP3pUR_`qN0tO4M%5otm)jU0eUI0%cdKH;vxqkUpX)%dN=rdI zVAX%dz|84S!w4)_=o3B3CoD?ou-uz5ougRA%s139yn4;pqz*Oq$lG=4IZ51Y55F~4 zc&pRxplH3&yHPrQM2ASiyF?B87K9t*Eo*F}-0=*QV4tpws^z%zw2b`$sH7|;-SZE* zIs7bd+;o|S+GEe$2>rFEH zWj$c9H93DiD!}aZ+4p5kWRB}>cE&O(w1~GsDkCBDjbRie+sisjSGyFr(cT8VJ4B@; z;Y|3(vV#*A2Ko7lCREW;)RrdW-SX{+BK;RwQ9G_klZ<-m`gh#Xh8Fv*nwp-sC2noK z$YU$7Ta?8&QGw^I8icX7D{Ee^Ni=trg@?5E3v{v53RHhsH9Sqft;*hlxBK4OvQzhz zqB+y5Ywg3XI&^=0FHBo=xOC-Q&P%%XhS^+QC`WziT-K9V3W{yR&{TS>NzYK|T-S+& zbHsRZn%vR?TniJdcJ1Y+8I-{2W?Z^N5xsWk?fm!%tYse0rb4cYTq+U2gN<4e9}Mpo z?I0Grp+y+1K6yLVP^V2g#n9$`gyJ;9=vgmL=#Lj5x0;$5_gZ-_ zdoqn^f)={9g`$dHiT$pas}EpMqZERW;OEM*i!-9c5VG${-0rBgqi1;k5)8ubMJt>8{|CVJisIs z-WJH@<>cc5f0Z%N@K})}WZmpi^hZ_P^Jb!VH36DT@qUyqL-b!O*1n3G54?LIxJ^EL zo^f~eJL>Skq+fGwz+mr^U`Dg=fcYJOs+EUYl=nmH-EvjCy)Gnwgz+~`MwqzLZ{cd? zR_h?E(|k$*=6r47WZ+!Go2|i*NXASH%Sci-J@BtI3(lfN*p}eKJkh?&#LpvR)aZyR zM{-POZCYGR#3EN#JrzRDwhW~h!>z$E34W>+>gFkgFAeCByv8EeNW+d(x-KKc{8tK+ z`yh9Y&(YgP$f}0GO4<_7fspJKyV~blX>J(o`YuoDuAwVnFDkm(dtR!YNiul-ueVsI zGU>3laqTY=?Es^ZtE<%Z^8NM8meoI_40y4Ht0|dq%HAP?cnRtC;-6+7SC~U3@3nVA zwr_Y5LK`c2(G+|SJymbOe;uJJ?#ZkjhJMr)oaru$u@0knCy#vLqmr!ToFu1Sjp;0P zpkr`J8?u}vDtveIX2tYzt5%iGedDTusvo2rDww!?DRM!lA-gTRE%T=KGtajUCR+O2 zv39-72RIx^I3X7Oke$NXIdH!y34Z-02fvzHjocVgv-0K|p%a88`s>42q8|TFFJ*CJv`I6+4rs4oT&l& zPQCY}3Vx_$N!;{PKEfj_xXKx`hWpx_e72HU%HJ zmGURb8KtWgYH@8`_HazM*e8p)F|KrfyZ=^344bLh@kmzBvf$qJTK9N6LcL{spO&S2 z(HW-vVX`vz2pGZN?N32f>?*wZ49^NzQYhMRUytlvK1XP< z%0}#qzDZQ?x^rS>lr`e}Dc;Fai|l-RlE%?nkAmutf4t1S zPWdfb+KH>UIxsbyHS;S7Wnx5*{1T?P)#9l#5SY*L;W`XzVeI*B^U=i>47N(=VZxL2 zz_54b5t)~ihrr4`;hg%Xfih0nb8o}g0whJaQ`0o0J}u=n8{P|Kbm{#=L~wUr>*i>C zgh8?8%_Yuj&vIG{T%1SSX#eV^O11)G{Pt_(CTLa)}=9f^wj6$+)yK<>cp95 zYOrD7&#zdSZwjA)?fti>`xf;+Wxr#D={sUPIz0t@NZTE8hH`jPtqAGmlHNrdD;>({ zBW63>fC)qLXSfjZFjxNyQmYP2<_MXOhaQ2quTCy6gj)tC@7=Ld{QkUhY!NM^QT!C1 z;Eox!^$}f^msf@$t`&^+Jp>7UQP+Nk+KDOC{AQ8*Thuda{ytHNQ4}Q{V|H}Gqj-B6FrwGv+`IPmjTuM_&F#c)8 zmebqs0lx`X6&dcf4Qg-aTMK>~jpAlJk`YszXfy@d51>a+W@IHECLiY^28gUtBKVod(@4?=q!4LmWHk7AlJV*gBFM=v z+cmF@+UrbIB~zV*k3InR5GZ`%*KHqdfP*k(I*@bXn^waXAJv%Ds`2ht$2yY2+hJFB zoItUn=4yRr^}S__h#p^=l5WdhRK=TAmLBryB*TTKx4Tc)RF#;B@w;IcS0wNSTreh3 zJsq@DOp}rVDWiOV&>g}Bru_6ZhGO{KGwDrq)E`v00SNYwGA{)rVcFy3}s*tRS+ct7bN@Ig!S^V|N)F*D$sKm~8V!ApW)H6CgqBL)*tUr1pQ zKgN=>_5~C#-}r>X(){vwPpkw){W7^ukA3v?@(Y8KdZN^PPPfKmh=rlpX%d3Dr`Z+- z2-6ix-ShWUsdgye6GU%&#Zol@2UkNBmn%>`B=8+wweNz}|u0 z>}PTrAdX-wO8g=nxLPo2dp!RJ?7eFwl_J~K{>a)KGQwra31GyU7PJL>pX5*wT&Kf= z1(L_xcF|nN;GP?@(+qFnOY5^{bTm!gibca7EvylV{*_YO)Dj9)31XeNL12#lJ^GB^ ztkt8^JBil7dAQ!k_?FD>309E&q)M6^%-{44w|JAwCNlZWVH?-41Y(No9Spfk*2=^g z;Q(HK`nqdz@01X=u;PDm8InDHp@A19;VS8e=jQ8uW{**#1pi{~_ouE?IIiTo`BZ7S zA|P*VkA6R2L@Pyy4}S|`4b6s=%W2Ty9dDzLtROsf%#%t}QLN^zp??jZ(i_Z*IH$H< zOf`+#?{G*QGHyvPjV4{35#w}B;-Ls?8bHrhQ1a^SLj0sXsf>MrOJ*490>yjB1_aJI zuV@v5sqW}}b8I}yCHwHs6C5x<54|y?8*WS8k&B)_8@=@yf)hOc>DVHu3EOb|D<=D@ zvT;!Po#+eVwFjS|;5h%mkLU5&!&H@IzX(5CI(iV9{YmuIpD8#FA~~n8$>a9f;^uvJ z@Jh7qSNQW+Mu3u(6?UrtSM(?Qrx5NV6LCArbM8*;9RaMC2>Pbmt(a-@-%;Mekdybd zHr5CR@$5Z+6Xn}l-C2z3X`VaKK5Juj*L`2hcd1keW_2f}MX*sQJWP4viqAJl@YF{-9bV!o&z?6tSUPf~Suamu6F zaS%LdJ0n>nS{oX=0wME)>{yQe+Z3jcaDR!FAk~LrY7bs|WF2w!DS1I^%sM5Z>r>`f z{ITc*pyzNhV-*cn;lzN@-GRMn(uv#uoUQ)&1;YiJl{kDOCam$#b?2vf z1l%4;urZYjeS#EI`#sa5QsUIjho% z{}L8i4^5nWblZn67%+8c5HDw*y9)?&TDdr<2;TVKd6DV{?Jef5{_!>FM`a7EKjKSm z#!Z{IA?&QVqzS12LqwCK6A5xvJ_=GuT=+2&!0;cve6k0FJhA<~f+O-^RvzsEsgx3p zPhKn&o;x+?rneREC4He6zssP2gkGL6)k?UM8CFc2flm5)A#Si`odJhpNxtQQJxcKm zQ$|v#2mjc^;`EhsXnRV)^MIYC{{E-XJ=s@ZVuacwz^v6UY5oIzd-XL@3Yifro(6g! z4s&hLj+!w}1s2pp2loeMGkB#v9}SO&w0yn?mX#S9PekG_byl2gu4Pcum{g{+$dV8C zxH??>Gazy{vHA=Rrp{Vivo2c-Lq`T#1&8F5wb~ko3Y)v&fac&#;tjn|{>#^aPk(d@ zMM+%ttbgSasUy%5BV?;5>)W3gg-cFbym4352u^FOl6~YB@II>HYBW-q0&9tE*U*Ax zpg_(hHAm4vB1q1ZUpQ*LqO$bhv5*}=!hod*sl*9&;tQ|(w?cwpwrRz-#gU>dXZgIJ zZy4x30)G*JXYs=#UShXilluYa?o=HRGo{`6Oq@5pmWwe>c~mPBa|70ol?TBCAs>os znbc*zye`#&Ptnyn*Kk9zJ1M<2(Sq2TA=~RiDea0hl=zTZnBu)L`XC+F2&vu|X9k+;TvXY&Xv3S_r0do0q- z7w|R+zPuw3E|ZI4G!0;?!cF-HGtB1w`dP(67e(B6N49bO_7@P=f8iA_C|eMATDZ8z zz4`bP%+Z2Cl%h$Cb;#c>gcRz&9v~dj{y!SdGAIitTI2h|ONVqLAtl`*T_PRQEueIV zfW%9ufP{c_NVjyz3rKf&NOyO6|M$+^Py1v2N~2pUf&5*RP9WB&XKw zw3j=bnv+bpebE@T78{=gcbjws0+w~_Ily)eN>K2-e=*a4tjREPj~(y`12;DG|Hb`_ z(3*LyneAo3x6r(aFrXD|ih0k!+=28*Cfnk5k&obTdaMnkYJqd%<{#FGAr2_p*EM|q z4I<7A)e8bL5pKWm1H`gA(?kVVz#xk0e}AhUWSSCnEGTKx7XK%0_$=imf`SELXc1gOV`T(r)X!WB?>c|I1 zZyiTkT;?MVEZu`I!!l+ur#MPIw2xfr+}OocF@b(mXp5vLem+^ixCqPTfo7AZo4d!BH4R=xFPl==cIjgT*p|$t6N{ zzbQK#O`qa*>@dU+O`k>XlSj~}Rm@}F4?Wg31}D;-rnqzC?n^8EHT%qJZ$4f{vijW9 zWHaf=m=J85XEMg~wpYc}wk9Jr$>2BfNCq_xr}zG$68Mw7X2n2b`rDU-`W>(T>=oy` zkaM(5T?t2{q1F`F`oXQ>Xx`@kp9L7BKukeMO*Va9W_4%A-f3*yx8%imOQ0(sce9BC z#ky*Ham)7*_acG=WfH3UA#=wc1uyzl;nvxvu!BLuoy_NppW<+7y4`>Mcf1)mdU+X! z9I8X1{GD~gsOkmC!i?c!^)W&stjsR#U(((s5Z9cL7R+wq0e_Ur^4eO=4kQupV8&70 z<=cPj5)O%;wt9p+sjvx3HMNl(g-g%KIHOfSN<==aE@Wp{7PL*gsGkMUG0|HH4)70&E=jggW>-N@JkKg-rTcQdt z^9H^2^$xmBUuB&Y#Q6?mb*`wMwEfPkA=r)>+kT0JOxZB0@=jq&mMm(6EDuUA$?QAN zZBVQ2P4{VDd@;-K4If)P6oC6(+Kh?%68qD_V!H#+L?ey*bmyCeLMvhzCA5pJIYm`dVt69{EU ze&AhqDS+*_l2V3kk~<7J9t8gKCOqBV5HF?p&aMnmbNzyonINSEljsB2(Pj_!jIm)QNtR z#Z1=9Z9J$3>#yU1enL`39^3gAz{&rXQRtjj-wI#!?X6OVDd~q?To((Xie(ARw(0M) z#7J{SPt5DIVwqn%ax$jO3nA??CuDfr&2i z%(7wwdeV6#Nw_~9@tvGm{^2E`c*{v$G6A5YxJykmS1RaqH1fVb?%Ndk!%8%h?=58g zagmqx2*YupZkIm|q{x2sw45HkLW;Y==9@IY#SOngs?u}NaxsXZF!)Pdej~yYF*`&v1`@Xs~{HpMakXwAMLl`-8I)=$?G+!eg`}K z=EMV*+7<07j8fzYE-G&L34EfxcC(iJlSx{XllVrne8Sb>P{4Qfq2o%r^h!pl4qeqI zhOdC)uN?C~riuUbV8P(MhMe+>^Uyc!9z0OAl0vD$udu?~;6ULEWMqxlgp|afg2A}S zkwe3;LP*(C-!P9KqC?T&_7FuHBUz^wRN78sp~2oUtJ+LmOP7egE?*;qTlX&cjE1H1 z;sN!XkyE2kkeJ!H_SnQ>?QRjmjS%N=toUE;=jYyucLjs+fn@$5`BiD)h69tdbQF~U zlAYgB_C#kV9zPb(d|vu{rR?PE>U(wV6NxABdq z_~2Pee^Moh?q@i>c|BUFqs#``r7n}3$*MZ_mWdgK2(>`q)pB(+Z~n)Z16-~?-j4>~ z!0Gw+u3z(DYTr93_xw{+*$l|Z%l1;ixy%3uTjKLF>*(rwO|PZmbZx6z+dw{o`H|x) zVuC*=(wnx^P``!mm~V~UD7;3^Z>hMP+twUo+7R}tug{mOjG{hs^=O*j__4!(&K4|? z4RPh}uh3I@ohE-xwT`L=RT~S!Ex(8)G)SddvR+6T(CyD+yNG@8cw-79cSE*G@8#^o zuul)idV!h|*zxgp|K?XHE)?Xj4H4DvO45N9>gS>+s%fIZ-caJlk4j^DJ&RJ(=s|?m z2-y@<6wl@V6`~pZ{7{&Z^P6bi+wanW>RpoBSPUfwM`YjVjApU^y!?%w<-eFi=*5Eo zV+k9D!nv}xSV5o^>AymAL26KkOR#&|DF;cpv(+V;csmuwLn3mrYu=Df!K-|V*;7Xr zZ|E+K18Zv(ST<(>D!rV_zP8_5XcVwMd<=N;eCQ3Oe(6<~Xg6xto@0DDj?{>Zv35W3 zxb6U9;(~Dgt-$iNE-KbFB}_&}n#I}BuFr}1MWk(kU`!WC!kI%`a~DZb@;hu`>!10Fx71?ax!e1~H#5~7zW!sI8bY`F z#72QMeYXXsZ&CDS4HuN)F*9>vUr{p9gPkued+k#DvE6rV_Q%41ws4EQaby3KGxzfc zYuW1`AFvn2G(YPnoE<;^zELQN&tR4>j!z8m9m~m^i{F2`TRAzo!J>OorIKtpSr@OgM$Q6M33aq z0A!SCd@NQK7fQemH{rHwuhUPZxL4wIo2U(vNiYOiEm_-o$|6a{5Uy`))AXP(em(I| z`8da`xyQ_qT8s&|+#8)%-jP4l>NtrK=wu0F!FSdYS~V15#k|xIfL#Oy#{>xAs82SL z2$&+(_DV#Oz2!oC%|zhmKa|J^;6UV|7R%mW2vCzsAc5#S`3a=cgL#z8@p*f6Q~v8W z4NhGN{zCkBAsAK3yf!|O!;0+iPCYC%KwWT+QRuVn4q5qq&qapi^%6u+!u)A4!yn67 z;RTIGp*u(1!ID#0lNU%J?(RDVKlPgkHAT0@NQ$v9N%s>K>+6ORqw@pC{OarC} zb&|Ht;JxHO-*~-W?u}(S$FIywsX*#wfejJEhz>2GL^Y7 zB?3&~FNZ(}p+mA=WzfsJ9TH${Ngs907e{s0X8f99A*;>=1rNv^De!~7n796d5!>NK zUY%v-pFTnKo!7k5ZwiyIhp4?-jDOVrlM?C1$|O8O3b!74^7-Ma+#n>S<$&ilQEvv; zX5-RWkiq7tCwuO~f3HHA9JKttIS4jwNsD@WjJ%!9+dBXSzLS1@ zVSR8@Pre2_GNkQ2*_P)}xIE z=0hZ;z7snyX`o6%-G$A-_qDAXQJ&bQ@}q|c%iLGUPV^D(8FumH1Z2*u$LOlc8FLS3 zimwIU`g;@U$u9p$37;9Y6w*$0x}}*;L;!w#&CK-3fOpaMD`YLL9twLiuX~Nd-tnJT zj^<&{;YvTA_ywehVaLyVB(Rb$q!c7@CEDy8C!{R9Mfen_ax<20krCHJM@)?bnDK^I zjiq9IayD@xu(d2a5NFV>O$2J;k=tRfUL3J|Z6cMiL)QFPKOz98+Lr9G<7CO4@~WMf zlQ%?I+y#w1R$Fz{6i%zwS`6#}B5}&+$=CFLSjg_}>R*-0Wh=XGRqQXTXY0ut3^t6H z=VJaVJAa`7@nGGoJ^m>JE+M^5)fjZ#Ej;bwyF2UoK}Fwn#W82*B@JZXOXRW~QLE$C z?B1z?+b|XiN}W4^4S0BG+Kyl7#hAN${6{yzV0&?lKo3TTDu@rn)W7Z^PPx8#)|Szg zJ_z<2++xz3h|wNAn`t;W6Hz;TbJvv=;(Rnf!5x+qH<61y&QbdWsexq2ua9w)cA|a4Ew$ z!buYwUCJ!O9r!lL1SMN7_qT_e@95#e2yHaPjDJ%X=3QDa{K5eg}3}W$-lH4&oi zzs16ZyOoDBnB0pz*$#+CDNS_()7rkRwcn0Mj$0ivgD!i8w~bG_>S^1u1V#aAQ+p)c zzASY$tMu<%7Q>0XU!JPvNkpF1hhP7<(?MF1V8};-(LE z912EuIxU<0_s{u zz>5qLUD?n>wOlxK@ByxcAhkxP(CGYlcUL@6*LI==)CI>BNQUU7sQ1G-yfnX zwd^dtiBnT-&Lc5G)ha!{u3FL}4oVg=wOBTlv8`(MEe{v7YPG$KkkxQJ$v#tyEU zs~1xJC$a|HKgM2eJCA(R82mYA?3pyF&EC@PD`SowpElr_ximvrB=Y-Wf>D8VM~ePm zu6pU#tUOD}HO!BhFqxXAyxP&Dg%PWqwYkq)V{G_Ug0+$W*+c9}Wh`O%cRRi0pb~pN zr5_z{6`&G7lkXpXk$g$a%VV?%BNN7Q<#CYL;ip;|*kC3rS8aC|ue0Dg^V%Ly2yuth zHbqn^lHb(FZr{Z-Pl~Pf328*?Kd`+dQ!TGJdfDH&dH(WX1h3dm?oKfirp|ed*%k}MXm_-;yyA};$vH_8SMPYXmp*7}AD=eb;MW}0Wd#$C_%u=6 zpQjC1GxpnO#w>8a>Px#9Zq(n8Jf&@AT;HfQ*iu1W7gcba)g~5`=RAx5bQzh}THhQq zF6VpcFtlzjvY%-}A(p})+rOXon#t+pOk8AshPPbfPUMb{t6()^nM1Zx1((8tBvU;!&O~3frS4aX zbMMzY9mjtJJt$@KZ;Gx4&uja>^4jp3V}A<}66nrryViB$v-JArEAqv=7n;TwwP3C( zzTdp!;Lo)ssARAgx9_bna8)_`f#!oIamzmSN{tSlBy?cds5jkaPD5a!V7{U0i(Q82wrG1jK9bDd`ZG12 z{jNDp%J3nC#BX}v0`%Q#FyjXl2nMoGt?21^N!6%I_go4ql76!(4_4Fv>#!#>^$5Ol z^#9&aXt2#one-`})86*JHt#yCC)g1a0`p|m#Sf#XKiMs1>(4K(4{m;Si4ZME8lp60 zHxb?y z_bJcIua!{fNaaMuUN%W$D2wkG46yCm>ha<~&=cs49s34E=Jqx8v|&ZsxKX~N^5pRD z`H_D}kS7XzYfs==Uc(_?9@xp;i`Y~)ZT*v_c(-5lRL7^n;;nJ?ck7U#u0NYP^Xxy2 zRW+h=_Jo(k7D#$*ItD~94$CHU$Au2~nK81N394T#pSu5QR$!fBma}~5j=E`RscjeS zJ=+z}FN=IhT5sM%$K}Pl5G>p{)d^S8s?J7qbL(FApr-U~O{4u!{oo%?RMZ>tym6YZ{%%_xeb>5<yi7AR+nw2NII3$wmT^I8!4%@T|knNi(uNGTf@w^QIQro&&T38hw(Y?`5}P9xd=V)-$u+l93X zlg0c>6?Gfy{mcG`uRfX}L+J$qJhm6Z|3B`L5W$-O4wa`5#bF45f|~`|3#i%Z|9kAM ztjzsp=a^*cA_3qi%L_YqU@hcTvGACgDb(glbZjeZcJ|RpgWJ1Z@><}8l4xox5<*RF z@Ng~%BEIxT7s|P-84W+kk%pOnr1C8K-ASVZRQ%^xk;cC<-_H8@4okF9 z_CB9;>mz`wg~KFZ=FnzNg}u&kEd85fW1cWaoYGVvjto9;Fm6Lo zLmqVwcolpjBkaP(A%OtH;X+i|t`o?+oZUg|kUvC#RpnW=i_O2KT>MU#hXxG4=F;p& z23|oVu2St^1bqY`^}QQ$EF?R_=84X~FE8(r_Mli`fzw*fzlHR#!{;rZZg%)I=S+sV zo#N8dceI09d|X=q-eo8mjLpwXds#xrHR2{ZsSF^DYo6`)scwG>uK$@y4Kk6%cWXA5 z$_Q@K2-aSZxY5}r7#27Q?#)@aiy?raaIV_XrbdW9z7Y&3ORhpmg28+JRm1(*o4H90 z1pQfT|7X7VSL7gnNl5>~OyE6k7ROXSx@u`OB>HVQL}?5!(bTm4ac{cW5GIJsDTSGB z2j-6DAdF*q(zc7siKnQ#c9P-Gv@FyuCsL6%Y)>!% zd{-a9sD+FG$VMkX1=%+u`u%36?MHPc$z#^YY$gd#B4ml*-ZPYr{b?h9!>Ifn5wJ}L z4r%eyf)rl6YQ*QkVQMO%Sp!hP+u!ELWadUNG$8m10Zey^#a7&%*x2OkcpcwP$RhL! zFKaUZ3W{3qN?(T~RS0}kokV|Ig^Opi1L6kZ{GiRkKh8@zz)2$BrvF~JsuTM@X3SiI zD0@>17ABhYB?bzbQ}M#GW~jjF!pQE3rf$N>I{l7CGHNr$*0mY$6c?aQBe|u(UctD) z_t<^=;lB`&05!#vn>=}NB{txFTFYJzy6o{&r;_++@bwoD3mqu>j>AXHyReC!vFin> z^KR>F2N(b#&VFCHBez8lpejqRv?&cJ01S;y(CH}7*qc0^=nZAy2Img|M(sF=Y?P&% zdeafW9JWJ;L)+~H#)Lb#^jcK{rlLo1Q|Nj;X4~T%SQrDX8y>(($=Wknu4+;t=jY@zG`oJ14E?jWzY;%Z*tgOub=&1T^EJB)X3AHYcMe{tLx z{Oz`k=69rmMs~kSL5KSP2^iYY($r;jlN`I-j@^izc54L0UfcpTLGKMi&8<1F>5u`= z&-3S642dt-Yg+N2txOrfAtDlO-g-@G%AW{%X5n8b_uBoKNa*cjXx!W~KX^_zS#^0yD_z z#+c+$XQ#Yz0C3Bp0eK=*Nl=s(MFJoG+Nbwp&;+xosonqejREP$6z?lNq2^E7uTiZ} zJNhN-#U+6R!x0JSY5n>GLj0ea>eWVY(P=nWmcK%%aRB_UXTBj!dlo%ZyTLS3bNL7} zpN!P2S>@(QPMN0}k#Wr=kZg*wcI^lC@Mi4uy-w3knHi`$fzGP0UA_nK63?|PKg_%X z_#56C2v{KUlB0&2po6&ONxM3fbg-6P(i;<-OWIQbVE-OR_6|QmK=gf1*B#tP|G(qw zNCI8FHyR9^0XB5W@ZJPSxIH1adlIs3B1m-7op!aiT`0x{W}e)i=&PJg5IvN0TpRrT zEV8M+%8CM@!rlU^oZ6(5R*2xaSPTLhK@$LY#Ol>B@^7v7XrM970R=+8c$cjuh-N}* z2~o3*Q`dp-I~xT~$s%&l)!^vFGr!5&_Q}kHY1)%0$#>8qQ||*)caIqwtm}y8uiZF> zR<8$ShKdrzg%DgHgZp%deDQ$=%P2aKFpPB-_JCM%h4!0;cfPK}LxISm_sfo>2g35+ zX;ZNgK+8TGk>KXNt4c1T#-MiFfwh{oXCz9Xv+OnwP(vfUE)f@XXgJDAjrxQjYxMvL{%^#qP2;i~@lEr~zBLnVvoduh?k0Tf)%R#p{qKSn6O*DSlE zy${%&kjL}%pj@;g)I3SE2W+1n6&gV87aVE;YA0@>*I-;R0K zRJFOfQNCEJ5Baxi$u%+n5>5|0l!cR!POC@)O-waVWiokhSM;^)D#o&`7CF>V|Jc}9 znaa^H?P{xkZ(^GYKpXhuCp~Y5_Du1z^{MK%?sN(AydeGZ{7^_Ujq&@5D>sewLH-Zj zx)n^Ic5IMoex*Y8)pxSyo-I%e4ZIQqAU&pB>PkSA`>a_tif8*^`i)oA|zKcuBv*`Fv=YYtFqHq}_3-ZdDBdvF52qYJ~-8EWK=Mss$VgN(`gS9|5%YP|QaG0LM0x|>iq z)%lGA2}@`3jZn8ALAJxxkaq9aXS>WL`k(qeo}LP6ln-o)2;th!KQ8v?F|kAL4iY{XOACB#&eF%M&78<|Y#6s)9$6?~NhDZ#4sZD9HD9xflbpWFt z>VoU25l}jutUv;PNOO6tGgu>%lx(SyIX^(B+4_yG7mIl9N#`#@WUcB>EorAcEV<~u zLW_`UZ%<-N0=tja8jVfVc7ypHcgrIQNw{E_ezsJ}X9aO-EFTz)%jO$Qwe%i@D3eOi zrH@({x$$g>%cVjcWY{~R&z}rh=_BKgCH^_La|L|9+Ff7Irx-R&x}u2r9%93All1A5 zwe+HP-j4r|)p4K6;e@HpnPW~-k4m1Uks*Z&`Y}Ngr3V`?v%#`^9b%qN^Z0=f@peo- zg*NBM$@QSnAJ@l5=YK|2gpF9jnhewh8pyG_;QD{kWW83+P+z`|!%)_ca}gUv;!AME$Ld3W&3jR6{avi?MUN`lPAb?njy z>kM*N7(;{M(K+|~h5Ehgm|10l2eFm6U&}MXRSdX8j(J~Yy2AwOp!2H@@V%M*Q`M!lfMN58X|NnlmI)RgAnQKEkyEf%<*u?d?6nb}Ub*;D0 z-5eFktzl(0_T~|2;P>{VB-u?uh>Q*Kd_%9C>}Xi}@86BT-~Cz=Pz!MMKDZuy>vtUT zw^WuA(G1~TmxrkggO1b1uV8sC7PQ{x=H-g<^gX-?1A8NrVU3iMl4HEVeK*#q$B*9H zsj5^nSB@{EpJj~4mp}KmKR2$vG(uz;AurJ!7NXuxIOwKAX3ti+J}{rbq1v0eO0i8I znFsjwRPHLtBSo|(oP%Cgt82O>Sd8`86qZs0-TO$sDm&g&?fJbAY{KJ7Td1(I z8^KzXsJ#*urrtlE0JlWB+dErvJhypb-iRKuJ!bM-{hYlPcrGR5qh+y zqyG2+O=N7ROAexIY9w()))1nC{UD4+`8>HDpWDgsvmiB*Uc5H+M?!Lz`OlS&npm<* zgw7X=>w>4J7aB}VfddGRuhn6&7X&Cj>1ld-wAu&l1&NcBvrv-zg@xPkFK7xY*(-8< zuk|;+1ZIzc#nj<2b8K+F?KAs${{4kTl&Pb`s&OC8=nQf`ydEyF!jqi%CX~>N2fve{ zBo&+WHQTL`csm;YTZ0gGaQ!dL3!k=;<{*PfX5wj)6TNWV_%a6Tfmu2^#V2hd-FDQk zy^+G_-pv_TI71(s#K^LLhZ!nSOv?Jl0UmhnBx&P7KIiOhN_Gb`UBQ3{-kdqV`~CXn z6+Br2Yh8Ja>yW1h5fh>1L;NX2_eV5|mV;~3nD3Sjv1K~#SA1^{OF-GN8jd7UFb|SM zeDD7XhI1bAL4;yPL!R#@D+mpOv-yK6YgHdWtLvqit~Rn&iPe*k5O8GVhaT1yF<|** zyfCDfT(R1Jd*w?R$|k!SXk5rKegP&RO(4{K$lnWp@+9dVPqbB#Q}4hqGUNEj|8C*= zZfk4p@Nk{>!xz2suri0>ogii?wJl0aBnd7BO7Ky8;wENfEivFg=5o`Jhj3D|gVvU@ z4Vn-$>X9cV8P?l)sOciz1NOC80t-LuW#gjkckleL{)*yn1BE~ zw&iZD15RZx=TGv!)Q30Q;Q%5RCBj~=q?S91nt|&3vUo0Smo6D*&a~lDZC*V1^|#!< z_mIA`mhoYBdj2pA*4d5frvI|p`GARlbL9%r zK9%T^mQ$#(r{-=TgRBKf(#F8nll(~t;X2opj@C4=PZ#4xsUSs*SOG0^I#v?UHadNZ zjpjmex!+%puUug4Vix0GO~>@^nY(qKYm)#D%fG+6l0SQRhU>z|42@(oi13w`sN7Ir z_oqz?nU$Xe_ggorOR`lNGTwH@tZ#O4Aeowqu!7lFDvz}v)9`)PZ_OhgQW?NiJ+X5y zwp2sh-R0;DIfT=17!oY_u%6H304l+DXBTcWDm#^j_58%e`Pz3@NdB=zx?7lp2B}Wg{E5pA<5jI8ElS%ID@A`b1G-UN`|DodU_v zkr5x}zV6Iz-e4g38Jk$gwzg3MjH&~NIy;#rqFcP~2Y;df0s>cItMC9(EqyWFE{;oB3}d1S{Tn{d@lbH7;UK4TLYpj&eU= z^FrW9DX!$W>w&?U(>b8^0Sjp@NeB~S#tuGKzTJQ&z|^RqrV1#`sKC%Mg`LwWzlW3n z&2g6PH7I@;7M6aJMuu(bbXO0n? zl;LzL_6klD!x{(W1-U+H*ct_rDXmj@BUs{(it*vsy$re-Gkhn6gPk)MmNptb&n%bL zL5m-gCKXtr)lJb7ie^mnd!?ODwl|kzh^*J&zn_Mgb|-lIcG-UgRp{^24z9N-9Yu{{ zm=J8!8#UXS5EamlXh2X4lu%TpVbV_CetSCz)B_AxlO*MCy5Sp(r-7tW+|tQmBqnK% z@P{voCxH0B)epddGh_+u~jawOsT24QC;729CSQo9l*rOpe2t?)2H3W7R zViDZEzMpQ5-Y$Mk%M2F(tj7#eP&090Q61e|vYllMo~UEYzBR9BTp+0No+V%kt8w#Y zynl^J$pxZzO>G0GU}F<)(^<$@2Y+Rl!Jb`Q*l-2apN`Vw8mNTsJl%4I{YIbiAn&Dj zcLZwA%mo*UlQTC1*hEqcQ<*|XS{qo854%PSyCw|`8k8E2Ag~C z<|Uh+l4KP%EiWNbwnbk~ye9C*%*|(p!Yqf+TD_YGMHJFsGMc_}FvWzVbK=8H7pB6* zk3x!pligw?SUaFC@S+4#ACPypHmWgQ$efN%d6j|YSH@HoWJXV>DfOa&pTr69x|YMP^Y*W~KL4rnqfhwwZ)H)t~!odjr|Xo#>GzW2n5#D2Z-?3RC~N| zh15Qym3Rl+t=2j7Wd{7O;n^G#Q+LSvkb+7B&j-Am(EpsnDd!IiSUsmm6x}PDVz)pv z^Pl;h6d?FN^T}b-uDqtc+;pdc9$!IDIatsd-_NsO40LZRXHUi)9hTEI)_IIX(K(zT z2&+d^cj?tser=77(Sg+g)h=2H)Z(8>-+BaO z#|9BDpw8~Yr-5U==tXWn&hv=s{@oMJWZ04_9-zd-KO#doXQuc41JqnqIgxPM9e>9g8lme%2wn7C%3XRY$K~K*S1eWS-}H zj%o4(nvMhZ91!AS9J=V%&S)WDU%#q0z(x&s2kLl}FJ~Ykw%RV}Fa$V8K*1JxX;F8i zoBnram`#rZ(j3N1+{2IR=u~C#t{=)hDS~p6-&IGRx#{lwUW#5-^z8@x0vUeH7%gdkMuP!eS z>GH036+ArLb@!|0os`yDr_fz{?+vTlr7UmUlK7`O&KB?+N9JlCR71^zKWN3YI#Ad0 zoE95HcnolK>RD%het(9UOw2Y8<(Utqu&V>8JTip(<`rn(%6zfr&UM@F_o??@JDDS$ zI%Orr`C=XKW3B3!Au&^GvOkD6(Zk@qhn16y!^skNeuuVs&IDe`)m@ddBv5+ASz=54@Xyd@>LjeLY z?7r>LyHVPIZEyM6FS9W#NXY+Uz4KU>{{xkn<*}gi8}py=y>y|SJ+_1&xkHMOlm_+p zM9ko{s@$4>r&B&M)$FR&#iTJg2H8_T?YQq^9^((MfqqN!iRs$bZ&M$3_)!zHf<5A+ z`9R(mS~^NO1k;9##+b(|2}E82@7@}uC{Liv1VG7%S4#Exh=ho3vSyWe%z zTqdFKkPSi4BS=@gq-?i_Ge7Srl*lt#-QN*P-Vw&#c(rzhn6=!|5nFV!rG_vsZQOKa z=uGto)p?~{2(VWiv}-nE+bgd&FV@`6b_Xg_l$z`*Wb9Zsy$XwSrP;ZEMCv;K^WaNR zX%d^g#>BE0&!8n_ORD1(-kj+RVo z6#j7^D~F6{Rm*3msyAI!#Io|`(UaKiHVl_||K1w4o$E~JERL5W5i7^*Xg>?qq&n!? z`^w%6e0kOxZ%?+w)&HDD-Xr6~YmIrE5cYyzR*UfyCaQ_=L$b0_e11|AhhxiI8RvjW z^gnXSgEh@WZ;rKsn^;V`*vf~H;B;&LLu06ft_<5fgx`KcCViB1+OGmRIV~+VPnR05 z^0`?Xx!+qkOO$!k?KZrbt5Le$<@xy`=56DkduPfoUZ&lerD-jE9-r9AFOb?y;)S*d z%)NZBIP2dT+{0TD-62g*vRuRB%ibtP7Mwj1zaF(@Z)jr3UVV~PQzL-I5dX70%Zh%l z%*e<;N`Vge%>rgwUcMW|Ppge5a!18zXpLj)ZaS_d%I8WAg}((2@$vSXwqN=$)>*&GKEXd5 z&E6O-4z%e?uG9qi+J4^LS}F21nzanDC8P^Ps-7v3>?;vO!uePy+1j{RM0kgvYuM$n zeTMI>Uh#h6)w84`+et*9XUSedCb>l$2wZZ>?eIF^dkp?>!=P9H)$;h`N(rS=_+}#I zzTVpy{qMFY>^0dw_df16nhdk<=d|w{L8CRgdZKnCmley;)j@;A>feKbeLts)UcZ8z zlD-lpgZkO}l}d_K%f8;LIhmR6rhxXnQ5GcR{qzw@0!PaQ#%a8Iq`iswF3ng9QGUGxx}G$!6W2gmP8yZv2gxw}?=|ukvXQ3}|+>^uPOa`dpf<@~Fw=n5~}v*9Ue2 zidw~}HGX3+;0>xPO=3@e-u)Q2XyLt>R$@3b{nQxAqLD*1 zh#n`X*7*~v!wwdkeAh0XPlGnMxdd+cdxodti$% zpRhAVNbR1)tH#2nDkB8Q`NdduE)Vt`Y(VoSc5u;qVR^~l>&OccobY<6!QYh$DC~>H zx5XJ|Vj%hJ$xVsCsx3`OyBL@XJK@?h{AX@5aNkgVCC?M!4SkIfIO9rLnv4O*vBu1b zO$f+EO^>-tfc*$nQ?o-kUbK+ZbxIW&xn%BJ4th9e@2^@LEh#q0k^>eYb20eHK5O>u zfJ{*hp!=1T)fqu!=z}1raNcCY89_Pmx3sFox8zXZ{2G@S=(@5@cBw>N4CP{$20`4(P4`R}KUXihqiZHO0*BNBE#VHyYQ2jr_UmQ=V^VU=Tk2_S9kR9cuBg`uX!u zSA+c1jQ8)I(BvBe(}S2cOmQ|nvtEiBln)^~MG7;^qKUMM3d2(DS{SxBTJ;YtOo`E9 zW|w2}lIM3KhsQ$%u<&t>5Iky7mDDO4*p@L&1E|bT2T*4+r@UEF<7$ZL3r{+-?2=p{ zP<3m(Aub7^_Pz(Yb|E(e34Z8_he~K0l&c89zwZnnNziiynmfphogH3C0@Iw|k0CS; zHYI?%@Skj4D~1}-$GVH;vQqpOKA4h*4*xB>sT#fpfdRSz#hD$k=5IE0S(xH1Z&X&= zAsF^i7~hP$u;Pg`6rgKbe_sEl2Gb!xykeMj*5SvWo8IQF37qUa>yQ_844sH5PhXm~ zSb?AgHLDKOw@?svvay-L69(2agLvh`BDBOP0$w1SItcZ~3D|u^h$F1nl!sds(}2Si zK?>C4p-)>V5SI&5?Lh_`Y9e=Q6whteG+-tMdNyB3H(~~FS)~Y9@WeKCda0U)0i#tA#Yqn?u<0g|s$TmaeR0MFTRPZ?4ETRQ;-R@uiMOf3{f&#+`>S$yxsdsw>=Sb*4 zQOs8X2|kPj57g~OqZxYr8uZy?(i&eo4@JLa0M|kq7brpa{_-IbE?v2Px4(j5+OZ@y z(?%VEnmnu?j|&W<3c`@dk%% zf=uU6#|eB;d4A0}(u04aD|f;CF*8rd9-jPOM;S9s%cu0axdz5E7UXq-cLq%U>Uv zv!(_rB>o>9=g?3&s$a;djkO}c^d#oseCgq}xz*zT5D;)ys0cLqLcP#bsB^bNbW9Wm zu4&8&Wjj5+c3mF#*zV08Se}xY8JWOe8Gx67o3_g}DY9#@v7P-66|WePfdkZ8VQsd zz5Nc)ypK4i9SVWnIXDZ_mgEU=sON3mAaJlKsH(OWYY)>A0WQ*qu6{s_2wnTNZ$&B} z+qiS8{mO6H-rVm*pH>Pi_>l-cOlu)o(CN89#)-3aA_0ge1_JOpiLS)Z0b0tof7>5z#1(#q#*I{EFxmTLqe4Iw z(&4nv7q_4fNOrR7iTlAAC9Q%|cJ-@M$MS%g8muL^iuM{;rMT*}fZeT&U3#KnLy)0DvcUO9zoVacYsB&FQ&#)O7soptBrwOc0->@4ep^K@w=8om zwe@xu2G_u$?hyLp4R*H41g@A=I5PVE%oJgyo17n_sIyTQ&Q^D6Yy7klHr)Pp*`>Ri1(A-WQyQcjq`SMNge9bh zoD{HU+wJJ73Ncc*A&%rO-(H_TB2+8W~SiZ>|6l>5ieGMZZiEnJI^n1i1E% zkdu}qRP`iuyaoI>r{GS*nGLD4TC~4EAX`tvWf8K(ol3c-uwEexfaMx=8h`K}^6Z904b8`66()7+NZ#8#q zBm2?&vDZv1hu50Y4SJb&B&oexuwk7wQWNRBdxhDI~iC-w8L9EO|ap2Ev*crjXu5XuZ<)y&xe%9 zp41H(%0EWxhaIJFRvEHy(2RW5=KLOx<-dCFxnRmp7Wst)lK)N(M#$HE5|tPs<8I%V zSMI{~(9OakqaHuNzZw`>yZ+NqBSEmHKOjZ|iesh#cJ12QjWFNTA(t(T85iLS@9*5y zt(IYRc412)xY8WPTITug>-W}T(WbM|(J2aPakYJ3@+Yyx!AX>u_!jkr^1e^+ZHaJv zZoqGWIRRtyMv00Yu5tznKYi=fvYEnCw`yo)|5IT*CgvaTm`7>phZ_bf)E$PB*cI4dAhx5wWEU(_r~awGkuCpm zDF6Sr0K2&WHri?&8aKNW1)ZMZNGci#DMMgz-epZAzG{?1CPj&3`o(4IE@tA@{^D%I z<%;lo&M$xkm`TPM9^`8`Dq;2Yy@Ps7M@{aRhl1$P)%=XVs$Yj9nS1h6H=Dw2wq@oS zwajuWT;J+=$5s8Iwa#4{MDI)XrVrA0{)Jv&pCsV80$EchKNKn4w!o#G+E)OL2kY0i zkC3b@QDXN=UF(VnVInhuH?j&k2-f+56JqkTxm&-f`2R&9WC&MjLjvwv(8R-bauu>-waK3Jcdvp{^4{CF0KA%%aXKy2E6 z13kJ9Y!Pf;ZkWAbctH^3lpRYMbtU&sY4p9kcQ)~9TVq1A;-e}d)HmRO9Tr*`z=xr5A%fRmWcYoRrp79Shup->3>TGv zyAlh)7Dvy+rD_*8;9Qn`WfjP}9rUO+K~YlW_g z(jWsE!Od+%3Ly7SrO(F%^LMmV8L=7c?o6n7J#3#0$-9mWYP?CyB8%N}9w-M~8TVp> z){vCdr!&bZv^QNVBc4cns2Q<;oz^o-Fd;h`4B$?x-ytMw2qM@bRphH-!o!=xSAR$W ziW~+`pKzZ&^y9A#zJ8O&0-rbuek0dOc|>vno)>4=+dTg3d+SRs>~CUC0ZZ-N7i7aE zRTDIsR77uhdGFx7h?GTiXUp_%~r?4%ewvFU{f#d61dxWs!USH98P zPe}dlcWDT=Teqn;V;&A1a2YOa173jI@HrMJa?DD^$==T&SGL<67jU~?~M07p{OrfbRU zJRE-uZyw;!m49JQWp_IUIhUKaBB|7qOjHGX`EYTS^k{26rK#b1HDk>WT0p%t>A=bX zC;p67+lpaK8`H)MgJt%PQhl63vyE#0(%f~Qzn>^ErJj0#H831khCJZ+sd#HUp9)~a z0_5Xf*J$neKvnI8)&IypvfOOlycd-PKKmwOD@}oN>Q&6yDMGu3)n#Xc6z|*hLXUR(E3=jy6jF6DI z`xw=M4bsFGZtYgrp;^7dlYAHR7~On zI_LmVJ_R!=4k~Dse(10H1VwWXPwR9`P~r%mA`#$HfKhquRtJ7tHPZY zBAeU58Ii^%Fdl>QNTl+LCI#K>xjp$jk2X|_5 z>bui5J?jlHI>-RP@LP)$IJTr~nlk(VD2^2fJ5BbE%=r8hQZ(_h1|ipluk)MbH1g0( z<8U#h_;moM5Bi7^+Du}=wlE1|arKvrp#8323iPQAORD|PRq4ocjSMC}V&VDm``ji> z9$+jH^j|xtr%0Mod;a&Y+4VkbcnLey?r1yZZ&zb8FRaRC|wU3(Z#A`h2Ty@eZDW2iQD#a>UH zK-5DfxPFACD}1*hG##-h`)l zOA&a2JMUW0Pwt1xwz8&JF#n2pVJsjEAmM}K<+IMro;cC1z-`EkFzU(5{RKH<>LuUF zYaW~cZ*;@H->F?(z}&&Ywxqe)Rj;VvLgjCt+>&L@%=&}V%)S9*#B?AGvjZ>$uSLHA z-8|kPQqlvLaegeGWTI}_3*TVz+z6wyc~sQHF$ss`s^h-Or|G&`k()FZ``_NMM34=-)c4b9E~JpDYx>QLxoo1F zF9sr4)0#k3L{d~lmhU2JNs%o73!QCqVZthxVsFQi6&;#n&41A?+j&|=)mt-Mi9E?kAI}F(kiLnNjw5nUv2uyP2f4_Ri`X? zQs_vHam}CIxb{_z1e@fAs=u(1g?hy9uIS+r^57v@gLp&?2&h8Jq5Rp2Iid0&psY zunJO-+EH0mNWbpy!p1X3NcrX4QuymzO-3}U03Y?%lN?UU{2F7XHQ%@+LMISXtu<}d zn!*|!!Sd=B=ga0=pWN-~E|`jzI%2?+2!Uo3c+wV4TfzjlQ#VTC{FnCei@4`zDR*di zOH?!3yXkn|x2FVl4VPS)H3C^1sdJur>NuoJh_ zx7~8riU(3d-@CjcjurgnmhF1UW~=rw(TQlhBz233pJ7$2UOy5-wDPIpO+tIp$nL{- z-r%BHU#qaTC~>-Y9o)|FU~MgTl#z&{s_4Ayy>8lhnszz4e8ed=?c3FdhULY);n9~u ze`G+Kno9E@SA^XEEVk#znlGK#`*fqhmu3xv-1+w1(9+-JORScE(AcheLt3reu`b3G zSrZ9mNcmuoruqe0npq&hxh5vmqRcK~fG(e+zk8-S^3QLqr6Q+udF&nU%wOA_EtSX< z$(znVH>*y9WuZ51r$Y}!XF?ZN=si(jPTWS)sPY^6jlO5e-rOvr7rDDmZzh9(h76+s zkS(`f`?)mP@11s@=7ygDMTa4k^M|G~S5>5w&RksX5}DM4<<;<)F-a+xL!GDe7x6yAUWr`*iIt2uH!RH9!ww&^%Ma14t`<4IrRF+9${}#;#|f#>sn@cGcpCWLw5`;_zd0JR*xTD+i0&&C+|y z&s6Jkg`v?0+{|PNFI{%XmYTqjM%-7->)*+?2U;BSmP%~({15JZ_iDTTA1>){+$om| zS6PnKqdsre;KUi+yjfVTCIQ?&kny+Bku`sI-hkqNz+|gGjL{$eu4NpM);@9C4DUO$ z$a|V)FECD?DG@%n%OF}2T-0qOugy&)>u_yhS;dB0Wb3zut0D~mxi~}m*6Udh*iFH8Bg&cU=`LuY8CeO?*3}Th4&2 zZBU9|<2>!*Fg2tCO;J+M{%SEV9H`^yB1d25q-@J(I_&!%U58Mr#6qHrydp)APal}e z@|TMC(lJ7%9ED@h2drQ{2383rtpgz%Qqph2A*H&u0tYc)X;JiC6PbG8YeK#ulwH`)H6e)NHF+J80w7fIBc*4fi9o@_T3;wRRzoCD zMCW5fC5QnuPSxm)Q7iCT=+3R>+N9Qq_Tcxb*;~obQ_;Q4$HbKT`!VQjcu=wIJecot^!jf^!p^p{66FFCcE<3mLf_}XHF=Pf1`Wo0nBhyxb1$bqQJzl>&d2FAH z@|r{cF&X=#Jdn07%b$L<#8Ye)eVHRTWJ9(k58h zCMdb}zMFaQm4pN;2t5&3S+e6NB|4&C3Ba!;goA)If75ZygP-`;wfxdm9~GSDE?lT; zce)d-X-xo(R-Qw#lbYN^uv~;UmvgEBqhMmavF;H0Xw4ll-TNEt6z$S~*j#J+Oz>D> zaYutA38;bT60s8-RFXb{*Ip~N3PdK>Deh9xbbZ5(V_Q1+#S!VYs@Kb5$c^sAY6C8) zAr`@dnko0N5QIW7IS1j4&cCM4>Xc@!tTmw2$9Eo%tF!o014DsdZ^*BjDf7 z1lF@F|3?6w!2lR>0YINv;_-oQ9Bp6B$^TUEdkwIOd$kjit=%xjnJ>$OEm|=Ik1ZF) zncF!NV0Vw>K3S2G<0cRVOFxw3eG{^xA$b5_w!q*$1-O3NdO}kxC1rXG*VyosUWgft zj~siT;7G6~MEDAYIW>Nu!@69=W^*-n|J&8G={ z`+mBh4Onhg0__Z+cCL%TK{}ul&XSS;NDiv?ah71M@wcNR#kiFCEIu;wAo>C#UzzX~ zA@M%IY`|;vX8)=H`1kH8aB{%U%T3EYngZl(b8F zDx<{Xm>}%eb*M;DVu%DjesfMsTOA(%!m|Nbj%kv&wxhFpk#6T}%_{HK-<+;?-W z2EQ?|HF#72BM)XldBI>dprl5h&|`m8MTMIkcogysR;aS)(qh1;EU_HP{TF5NpfB+?k=*RFwnJV9VO=g$TWhP_Qf4t5-?%fC8_1$MSPpp(ZQ*>0`?Z3+ya1JD6m zT>L?R5pSG+q@pt(hjSAv2;&!jaUc6nZc1F}T2jZjG|*pPdqw~Z{tJ+%hR<3lq|;6x za-i?j&#Rs&CPAbc>Ud=;>U>_|fEz2oZc}rO5xi^QbTRhA`hb=NM4VS_L7MHs=XR2mfe?}#s|cOowmEz7(;br!PE zVSo_)SDzY$%t9H!eToV5UCueQBkqT_onVm%&5|+ziV_-7i-=)XDf|wTbavK?owf!I zFUp}r!Z1-9q1`9Z0+a{31KqVDb~U0fYE+WTCX`7f?4m9pcqma|TG`Suu71*%8uDq` z|5g3?0V$ujNQ5y-?T6d{!kPMt5#SU}E+8q9bGvxZ!k#wK%CjeSRlaN0+6Y&!)l%gm+A1 z%I@`Eyc&KO5br>-w#tDf9oUHmo9EOG(;iNZf?gBNT(aJ$H-9HZz?>$ya@p$k2Xa-O z2@Cx20dG-no#7)({U%-&7L8z++eAk}e%CAmQpfRkagYXe4i8=Gw%65FUNQ$I0iPlu7bw@>l-ce%sK;Hi|PA29U2o+w`ye(Dh-MQoC)l+e6he z!supny_VDT^&PxJis}%gy<;e0s8`eHhzwF6$}wIHDI+WdX^tm63u2%Jiua;US+*p7 z@oPDt3MmBNW~Mll1!?;J>!nk@Do1MTB&ZAoPY{0(mBXKUqepC;HeRK1rWaq|=cV!K z_{>uTjx~8WFKpV@wXcxhZ}kAl3aGuIgO;_VbRI;7GH-U;+NX4z&VRP#0q&>ZQ5j=~ z&Cs>XFqlA2U@_o<);fl|i`+A9yjrUfBNs0^Uk53Q8DOVBMPLAFR+5$Y5a=44S0H#= zyb)OYr(x~0#DoRG!wv_1Se+1;jE~Y-3y4{+^AziRBn)S)hrx$;iZ^Jh3jYw{4 z37dTA$dmdA-guOIr?Kr@Gc5tN%JPMM-w)k;mo<>t$+hV(E`q;kzV~CQX-Sg}^G*!d z*Ve74w2ir45 zTj-mycox^W`clK*E-a*9q>(&DFYmy6gZxjQ93U3&?PT1T9!4f$cOR*1`PG-tKmUa^ zJo;EC8X%*G+9>fuxp`{NM6Ye&+uzcs>r~~)yAdW;b*iG1^O>|gTr4A2+9I?fisCO1 z(gv!Doc6+NdFRojv?{p5Ua*-ND6p`g7w~NR*%Ix6Ws8{LyAOX(T4mI+#xsb|L)_a1 zq|E*}6N!ZEsc+3Q698H=kWc)6c8n=xx#_;-1~N8{=w=%4d=uHVvh8Z)ToTS7B^Amu z^lry0Bb_&lx0Ep#9=?kSiV%@@?*3Ku*c)PsIUCSOHTSdkYWkW7h7bRMS3PzFkNYg9 zkk}@IJ?ukI0?mP2{rs?_@ze~`1ZeM4aQpJV&xbS|zw)HeKLtI<8JB*#?dE1|_tPBK z2`^b>9s*1%v(Y@N-PBXHU*N^jM&OJ;RD1e;A0jFn8Esw2R6&tDC~$eZm2n^5%@E7; zZV)!oiXLoU3SOras`x&R&sEDp^lr!CuTXf^+>$X3lF+lqYy9wNw>m&YR)=VSlzap1v{w5`1i>;{WUh1(4rhu9=ek}Tg%e5LQdmiMuAF0{K-3%bjN~qK)$#b-b`1trfqNQ0`aT-c- zI@{pc?!M5eangpTx}5yA9!Cd%IZ69z|P83go4S4d#xT-n~4 zVV2gCwC8zdAN~;H7#I;la#k7tJ$^N$vn}E7FmA*YxN;!xzKF;c4I1bp)BA__XB!Lg zOSu0Xqd!#=q)0taSmIkM@**r{-sJ91zE$m)`kGO`E3z|<0#0_@lrQ-sLafDF_v z(e7Avltwdce`v#5q(LT`*5p4eTnG~-lZmJZc6TuroD&#oeSVkI)&ECfKG8b4V1iJ1 znGtPQ#W$!6=(K$31MzxzylN>!d)rD4+@9Ow)BdjnyS-RDv8vaOPCsKI}hST z^te8I5X#ePWin#I=5e3*&(8i0MEBXM2K}xEebYk`TwgDY5GK#q#ylIcgvXpiEn=W} z){-PZAN(EvT{lmHvN!uIZf^JI7kj1MyeLx7f`Evx!$6vD&@ zTKdi=wHyd3(%IH>_=lJ6a#YG+dVugC^Eoj1fv-bxa*W8wDU+_CfPor1?(=vBhPmHt zlfeLHdl>L#IpgDz^6abCW52%cBv<&KMyQnbWdYvSiw>Y2T<=R>0uVzm8~a-R{}v#l zTwvw2YQgn$4!Ec_Q0u}uZdeJ5;8n!Vba{K>1+K4n`#9aoT?lkpgX@Qvxl;5oeshsN zKU`M+_2U>>eoc=lb%h8A;A|eP&H=8R@A>)whU{;=YKKpXfD985B20>yKy6FpKl>%O zYUBh0vSzN$U+;j^i2><4MEldx#K#+P+=96PbR_#wn zs)7q8PVc*0$Ql_j;tlF?&td}4WK6_yNVW$kkN^{r-c<6%vae5O-`}CwR{^OoxF#P9 z$XSDug;G@MLEmMfF05t3I)aNOn?!GQzp?EQXg%M9e?JAjno&NkSDhTTD6*h4YYPlXVpI&3iWlo z^RKvk#{ShGr#uW7@|!n3KES&Po-%T4NVHVf z3G?Jt#Y6j2ij%f|vdBe_g{)tU39CYhCvQ4y&;*{mwG53|30O8fvC%uRxc-FDnF6@) zwg*4Yw-`9XhtGen2zUyDgo8k&$Zxk3U|7uo{>*`&v^oA=o$b4J6UmFdhl&Dg!E?ee z$QD>GC_@Gd&>$&^HMnTTXrLZ?vP9#XW%$TJR&_YVa%IqKU7LUbJ2c=&*8vqJmamwz zfyhk|z!cZD4iJF#QFU$qi{u9=U`Gfht1op17busLv$#u)Xz6Kot$|;i-8!-4&XUOqhEh- z9Gur5et+Q8%QtpMSqN6eM0S@IvZEtwB4^|PQhvTvr+fEx{Co8*bxg}GTXG+<#re2s zV2!%@WHDh=rz(I8L3W$p0F?0{;9{uB;!Vp2;RPSDnGV|$sFX1O69-`hvhV=qexw!@ zg=RZoGq7VbLolVrgiw{#LG?T(?fkJ)R<(|y2&I7+sUpbwO@UNu6s!0g{#sq#DJTm* z;^Qae4x!b*NsmSzRAgWxr1BJw3cmo8PX_vd5bcJ>$xwJ1_?!SR(T@dO&RJ{-7|Sig zJ!L3!GwlhLI!P~UE&n~A5U*wDgQ@K#;Hfo7VZaWRNCJ(ath$(Z;E$B5%?_ZI2rh5HBl8&G;YsoH z$pm771zr0VpC(-9mRpfK2w*}il6*R!y};^-G?_d3_nsH;mKzgCUU)iy zImmZ12-2zM$DOLx>R#{cVqy+5m0-v3ilTZ z?vm4yBw4&tCJQR)GZh`f?HGY zN8u<}#TjJs_7`Vbbxb|)=kl~>15Uu%wNt#dFMF2q;^FM9ODKuK;ouOz{68!#*?wRK zHqI^CqYfoal^_%(R3!qnT~o00F`(|YIdUR5Ry*_abGXUoLbUc0bS*Hi*Rv!EWdx*0 zv9$9z$(A)gKY<`c^rRtUULWQz=mHmd+qz=7xKZ7oZE5#3!ny-ZV)9-EO!gdOg8#QKV71%@%2=mbg*!sAx1YEEt&8HO?9Njo>(@AY8IpvAwm8Iq&Ot6^uMT#=vmgW8 zvCrDBB3Xc1>%aK;o3norD`UgqrNBm%F@(bL#mR^dRr@Bofhl=!)45IGOm`udv+fasr_|bv(@Zw>oc_UlDJ|lW{H$4mu(5Km{O$1HdMFr=WQu6Xj-HD56 zgB39`3JzWJDdiWJ<%`4Um|xA|5w}dNj8jNz29*k=$&l4MBk?FT?cWFzZ@!0{;elUz z{rD})?B*OvMawalA_jtNy`P zFie?u_djO~^Y9M*+SJ=C=^4XN=UCSCQIZaB5DCk5wAz3g&U}4*q;d6nNbT!tIC5EP zFA8U=)o*4ijH(GAya~_a4)G%($$6!(<>uMfdiQA6@uJi7mNfoBuoo?gxSjqOfj3Tt z^{aqN1s(cLtdNh`$BA+&UFrSux-Z8~aB*$n+RM|(!8pQg_WO_0)vIpU@nsNF>iMK` zlHcsg*H5e6b(476)vdyMpy5FSlBUOryw;~o)ab(UZ|<8VBE_He^isTHZ_p>Ql0QBx zO)PNJ9y_zAUUX)d5b1}UI6Q~+UHv}Ft&OVCtKK7FrxAmC!0Rjw7Unl>o1V#dB=IV? zUjL@=F16ER+rg?|J)#lNuatl;r!r}X?bhpl>CyXV_3azi7S+*q;txp4{>istEJZNp z&{b5bb9nrlobkdzKU<`Pd==%;KwgsT&fp`%b&wOe{9*l8u|t6R56q!lk!)FbO<+?? z9vAY#ugxc9ZwNlZGP3F~?UBA3D5~^;fm^7m&*;w> z%zCjUMIedWpur}`?jD5en9aaRB@h;dMzL#yULCIgaSKX?#HDBaCXc0$vhzT#+(q&S zl7%%p9xep+_r*ea#Qr~zpZMx|46QB^+%2D;c#D#+PQeSiBt`@;vulo^g3t~I{6oB z$^d|@UfNVF$-EZL9`Fdg>)JD(Q)7cxRJwlzY}V7}zzD#fHZy>86s2#Fw9r&L?37q4 zaqxEv-cq@EcUhfeyPJW+JLd?nTEfHkH!CJi3hLGG7RVTC!)(>Rtihzpf1Cmo2i!yI zt0v!1kosDK7I|6Pe)VB+N4_65js85UaC%{xq44#`)c(z$tS%0cRHpNA{BzZQa&I+< zAiFjy>fzBkK_22}u``q(r)Ig0dSJvl3b&BQ&r_`r^kzhEhQ%T^SAU&v(vNf7_lqQU z`o2bz?btU125o$dc^dc)g36Hq@_w?{Kzd?LInzaXz4^IT+F#Xl7)Zo$&SN zv__N0HUf5=bqFI)*M9-FOqJHhArHKsbtMGI>CD0Gji=M1lhL#?x%s?ybh{R8f#m93 zO(7j3tl}Ebr?`jH`-h)3y8}*X`$Mc#SO3mm`Y(y%AdXHC0zUI?4`1?Z&+rUzjHBzk zNhey}#6N<{cP(m^SnznwN%TgK%pwO^ z940cvqGo6q_P(-qwGD&bul{01r?m$>+BLg|@7WMF9G$F^yA+KmkqCutkY{m_>Jqp1fb-hhgg<8YM{kmn6CH zJ`1x!hR7rwWfK6!1VO+`hIm0XGYL&~5Vzl|+7BY_!s0-$X>`emdJo1&Z}0^J=fP|x zOE>u4Vt3~sTj~BWat!iWGFfExRrU*GWY^^D>qdt6=gVbdAxaFfx#T@|b(nx^wYqT0 zr6;bgn{k@X<`lBDkO2RJA|?>xHL2ty9;VdhJYe)){Zz%_A6Z_V5(rsD%A2#$mrId3 zjx+p0@XU-@FA|o__@Dh`=sJ`D7WPFfEY5uCf~B5W=zy=yrQxqy#|j75*&!;4FGCQ1 zR&=Rg-qRL!VB=8rNln6qL~F3h!zzI@NQ2ldo!iMWSq!Yi4iPHP?*^ppd`KdBjdOH zXt+~hO6+>0T(Ep-2*0$OBvm?TRt*eD4`B7xzjB$7t~H>KyEfM+?>5oV0^mE&zAY?7 z7J?F`U-1w%ILK3t)Od}OPg5xDebm&?8}4M&v5~J}#KdnpA<#7OnlsAU-gcG$q>~|o zDS#Ho>D7$<8&5W?54bKFDoJo`?iMd)@ew5wy+$)A+qVCSY)oSl%JQ=!bcWRh3u;|< z9VJZ}ovjc~L%d?DbxErZAM_I%B?OUY;m6=(Vlv^}?3^g};Q#ls%9yFtx~P^FUXrch z5xWnh=)1d2-z{7eyco7mPfU`zLc3wTxGZ2W>-PgEGOrXSuZy%eh zyT=QI`As^5=TE4`by5*6D1^&X~T2nDa2-(WPd{|Ii>i0^3!5m->QgI<3tFf9`eQGsh zJ;ZWG>z)GOd#5KQt>s`LA)-d<(WAq?q@4gODE&_B>{M+iNS0PAkj-O>R{VT2?}u&e zDO=jUU1<{r7jo6bT4$3o6`gpD+guOmfp{6coJg5;_#y}N->hpeKQJoJdx79YHj`%q ztTp^Ym|||MPTs48(>V{s&2B$jky6Smoo~OTxM%R9N(1VsFTq8hnBHyH=Kv#CBpKur zJ;aFX<7~a%?o=k4hU;EAt9o}AH4)_I4Wp%~1Ph>*j)k=BWB2B*+XXH@#l!#M?dB9sliUP^XwBO??_D8aY6| zQ&jxTlb8aM9yZJ(V%*e@!6PdEoneoR4!S>~Uf^s)V)5%Dt3dS)rYtsI^LHqW^tmBY z`m}3(3!JQ9ZMzaS*}!bt+ylfwD}U@Ri7$j;F(6(@(iJ9PWHaU1fKOU>)L1A$x|qn` z%0g{M)`xf01>@jLOk7;Ee-}T+2SzuezcVeUrD2#Na4@Bw#Dg8}m-U#k%q6{Pp~xW9 zSuWh#uPm<{G2Od+Sv!;dj{Zsw#2<%A1{$e~Fu(u_8S$4scDk9>C=zY>oBCbKqIJZ? z9;KR7{5kQwIYk*1m}V1Dhs8gPYW#PP7pTu?q{#1I>%oVf8vn}Aj=ITF&@qX^>V+(5 zQSbv8re3mS+pT=jy%%`>*^PLjx|b1`Gv5Tt^B*z9L?bty{*apO$gWcNh~puKtkCCA z=4F@+hYf!{Mo{{ea!X2EEF+idjYSn4GVr?T4@v)+yc@D;4MNbulA>pLYJ4-ox-mv6PjZxvQLi^v0HL2+i=Brz5uFY^0 zfy(zQeY0+bQ23X%m8K9ryxcJ97%Zl-;v%+puR8f#qh|d=Z#O!gtS_Rn(dv0XZBOE@ z=ARYp!82DYV)VwlbC)Dk21E6&evW{}sNz%A zjD9&P7Q6`hgJnI+gz(JiYWZ6nnW_-rD%EV;`NBPuNzhe;Az4Jm<*kH-wv3W-uCs7} zG9t}DG`3I%{7J$XPVv9aoJswB@RP`OWz=_tkE_kB9`qqA z6z4B%aXsjzOf$nA=1?Vcc7IgY8ufp8jj9qP|7k~mYvq$4AJ@w^(C_t(B#`_sCU@(V z$`CrqH^XQluUS4#rgUfuH%1mcN7oj6|B3X%!2FT)z7KkGu7YNBIO;1a#d_=7SUd!) z0yZXfZZ$#(HolfP4YIgRR69|W)cR5-gqPr&b4yle9pQ?wPi|}Kzi<2W_HDtdhph6B zug4tL@2YMF$v~)NoKiFS_-}#c6;Jb(+p5FJUsU}yiqx7~0{aB=cy{+=E*PS~U zsN}F#$a4w{je0WhUm`2IWX?1<@+p0jYw|{58xhOmb1g_*qGwYW@qW9C5GqU_x0@c? z>OOmaIp@W~tmG}`_SQY9O{R}DM!b5G&G=hA0P#6_YBW_s$kZoYoWUT;I<>lwoGb9a#JlS!|S z^W@3c(Lbx(B1PhcIji1jM4Kyox+`J>?g91 z;opL0B)^GJ!D?b$RWkP%%83Hs-9uGc2pZ%Y<_(z3by>#D>KIri-w5AoUg~LHM4IqT z_l?z98c!u8uBe+LI6qoDl$&GJSi4@tWKz$tmU-WZJ7arYJ}b$co6JuZ$UCQEbj#j; z|IkAfnKj2xr~9*^V3r-IanJP;=8$O8){WeeP&Pk|Q zz1xVDKc|{{8({SoKt6%HSt)Of#3ewmE*Q=lBfs?IW&;Ke~2D?$U z5OJ{Fgn}gltgGrp)3NZYb2cIK!)wp^i4Xxa+)lHGx<7VejSrI>MnoCV%Nox1R)lgIkRrwBFCPaX)0E5HP$tzp>_Z4q>owEE*5s(*XhKVMG zeHPHB<%urW|M!YwwVMr(HE#H2Wd z6R1Kg;T)fJVYQWECx$0{uS~WFGrqE1Si-Xi&_auauy}c*A0TNqsdyH@U**fbDhY(#U^ey5Q^H@DN`EOgBS1JTnswfT z9o;nn;@bP!{@fAkWv7)dU2YgMVd2u((rN_I?n#-&8piQgT?W6eOqQoqbcw}oTXi-4riIm_!`ww<_j%<+NL;+oF|ezTGR@R~~2 z?{h2$`6I4_aTEC47ke#e=)gDz9GLoZWf(hGLIDG8b(z0CQLy`_#!osZbIeAJKL)!- zvqqkIM>Y@0r?2P9K=0LscgIsfuBW@u zn80WH16m;sE(0Vvd=!E#_-G`ccz2Xha$SOEkK*yqPmaOK^9gf#>)5<_i$A^g+ozBl|6CYlmx; z!LW)^{y53d#P`QMO^N_GQf`QBN6Ske2IPXwnG?Ze*l`|K6Oc7H3BoBX$O^;rA1^I^ z!)USZ?!~b=U=duRh$*$!6wSKiY>tVHeElA5(eAH0C>{5WoWw# zzvM@cL{lve%2T9d2k;^Ry%LO%X%+!ki14+&*2e)SUqKb8 z_n@)tLBoWHA9nmUYy+x|o5|bcAGk23(6Q=FfQpw)IJBjCFX>j*Z7@Q$umRekLZ(W0 zX5Jz#aulgC&pa$7wpVTkz%5DwUF(^!)#JegDx`9ZH^9Nccnokud>~t}@;HU?zd^*r zpS2MKWabMmAz!oTbM2`Tzg~-wyEY9alS`2+J@2N={Upo3b}e{{wSY)ZpQ^!5<=Sn2hk4T_5DPg`&ZACN_y{MturdG zwTY+>8n8t^0?7MTmImi$n8wdFt|9kd2WZm;#)2sy%jqI&g+(x?H95xEXL6*{ zh=_~ICc`T1!H5qp?Z8q#KA@g2ZjEVmYOFC&>A#}$IYpqz7ym{6t{dugzd}p|Hh8Q; z<9z@?9udCe>6MAFdYgOqz=XC30>ejFEw{jtIaoz0>V@wskL&MGI%@lP|0}m^`0EYW zU?#FcD`KF#11Q1*TAY2!q^6f%es3;&i_&Ifu~_{0%IGzaj2^i7w;dpEjg|$Wmuk!6 z(sL~e58^Sqjq<>@Xb}HH(^&?^*)(nY+QlUVcMb0Dwz#_{xI=Ka0E%R|6e)hv=P~X)ZgytGA5!kS-o1@fAvo0Jt}LT@A1XELHmCu&3Q3 zUK1u8**_lrxuOK7OI%dAj#!}1>Gx4lrGcmkx7mard6Cm-_>m-FwS&JVF;Lf|KJ!q> z<-5obenW~p>ac5^mj#^%P@I~qQtAd`QH`Jr4re3%!3n9?n9jz%#J)O*ot*dRF+L_K z60*DqBw+kg26#HzKrk32XW)qQHVyeh0 z`2pSa4Ap7nSz-aUHlStFYEbpF_iwl!H?_u-r~};0Pe@of!UDTODs^-I=+-l@vLOHy zXGGA2Sw1c4`n$&ewB3`DAxodJmeyx1s9>6VHSDu2Gvf5gCLH=g(kC)_$}z*(A3+SY zcI=8?%F02or~(*S2?L41i7Z0yCGGBWpes2v9t^NS?njJ~!GR`fbH+%Z`^G|NtoQJR zw;nsRAbj(ky-Ti9mJ@u#rZdLu@A9ve>1tgvvhAtP9wrvdHKQF+Ij1zlVk-wBhGFh* zR}53#>1`EHq$VOc_gOOEx#jXN-Qr8OY_mTb$L8qu^s8k0m=OR(7)4e3D&4_37n8|4 zOh+?u^@mg2e&HwzRub(}jyqD1Q*pV0=v| z$YE2N1o~(kdRK@}Pq5H=g_WYDt%`2k;qsrYz%dJDhD|#3J?EzzAAGufaub16j{oZg zh+L}NeJK;k`zpC;=p2pna-;9fXPg(*d&)n*iv{hk{D#*sh58vkTX=Vo>(Bd3nZQ@*;aBTw zgTXMrhuAI~Khv$Rl;FL&Z5H9nX=Nr z6d$}0>nrQO{#BK`?>ubcCu%6GK&_*Qbi!ErLdI;D#KY8jn#k6Jc02jz4g>mHs0v9c zDocP7zdD@L_mw(S?BjAg1{FnA`o+;u`_Hds*tnvIn#CF81Mmn#@5$>e_GG>Z0UK{<{684IgUtIhsIAjH`RB> zop=6)ptieyABEZ?7B)7_f6q+a8O6R#*C$W!nI2oZSr!73ROJ zQ{wy84y%5LYdS%^x|~)ZmAuZkTp>A8sqzx~(fDU)r>+WCKfUiZM`g)(rMy%6`dix8 zCaaIx7#TYuhEyIWydA$+c*N`->%a-&{_l4#GB;WaOEXHeLoXwrSXW=&eYb3tEwT#x zyv$PM-K^(F&jg(a3ip3Ve&%&qE>fx(@ISiSYkguidD-^E>6-4{>UB7~y6X22+rJUg zV3G= zmDTUECXYQS4v#P1f6xlw6EkfXrHMH*3JdE}TR>d#Tq)8@tEOuE0d)+Ib`-i_k4|;_G7}rWZF3Je zfD}!dvH*A1I^0aIV7GK0vY%3aPBU~JN~u)oRFF6g$J$Kpl`Lb|!FFd%tir z(Yt+UWK-%UeZ}yKu?mO}uiXrCH#YULWtQ{rO|(_q@#8U26J* z(te(r~K;P9(9s(a%7*>nC*ll=H^ekMSLHzZ^f#o_`Xwk-1Wwuyr*+J`Nq}Qw!gbg zV{MGBZ;CJi7N?5co;uK%&DTjp0VH>GDe{2*a4-;I?l;A+8{UGefJ9*W8-GECq$(e9 zShSJlW8s-zs&8r_nI%T&sa}MW%IVKv{MQ&Xv$eRfLlmr?BeOd6B_5Jc zfu`OoA{LvQzAMF#11;TPE*am6^;)8OUpJ%71}rh5XDV`3AW)7wC4C!OPLBz0eP#gI z!15!gFp>Pc|AeVK%RTzj?VdGZr}V%FWT?HCko&sOPnLcn#Wz;w366nP-xW{lF4>>i zvp>FS_z$@DI_IENLK+nc3#Hsu#^78EcLav3BtbxV;tG@NPL%rvJ2LRj+;X-TV^)su z#7kzbL| zIH5>Rs>bQO+7Liq_KV8u3NxKF0mh6enk3OV#%tPF-FqH_ULNm{kFRfz7M~U>knO*H zl6w?#2%twP3o2DF8MF@MUjo0inM&;Wztdf(-BNV`%?W zolbS7ox12aq4SZ1`?9if5eHQ-gMS`8f6z?~x@u9&3Zp^>YzHa&_rL(txDm84024@! zgWqJs4w>P>pOyWJuo<+wm-}5Am;sS{jB&I&QRDKCAeaViIF6r!U6`4Ak^9SSwmwLm zS3OCzVhV;B{EPyvj+81y!Q+tP2csoi#F&lsiKto0{1!W?C~^yz%I#<^$EUNoGqYMd?vsJ2P%yNz{l5YYw+l0T ze~5>L5s+n%PA7>Bs0HLNnF2@+B8;SQ4sRoN$3TqF5YN!FfVrZ1n=< zMPq!{8OEC|&EDNl?+}37tTp;N=hKk2-Ed=j+>L|?Z#<~5KNaR zB!U1yBU4 zv~dty;Sd_61g!DY)m4wjEP(ukXQHjSZSc#936^Eb*|ojx zzD=y-k#i~#6$nZaZ01eQu2_X|0=X1a!NBG?OyPk})-jToHnT20m9~*6Gmm z?d;o{`c%2b!Vo2`D~#cQ)mPe~%%`S0^OJoerxWc!@jo;a_(IouFm8QjQ51rUPlU5o z2hq~^&Wk=2H%)VK;I+tPek99k*o4W40;cvgGhj;IZch#kd$Eb{+eoUBe3>dP@ofXK zb%k?Xf+C{D^T>dgbMK*0#L{W>UV(|{C@QQ{8Bm`VUfFuGXyd^#o!zOxhhBvJ?M)7k zR$=*?rE4)`KcLco_s(;ye|TtIr(^zql8^zj)ZA>iHK>GVLRBlZ-{$PYi&t`zE1#pQDOM4i;k!byg8NdeQMraF@kB8zDu+aIYJ^?)dH^1DoX0F zYT9`esHA*(%s*I-DP4pnZV2twztcCou3Z)m5eZWm6V5NCg+Z34jzjh4T zBt}6Uw@?^-J@dh?Qq~6Csvm6!)bo0J5^4KffYX~3Q9B9wHyY=<91o5o5lTZGZ~e4B zIZ03oOExu_riw2Q)Ki1^v6ViX8Sh>=!pyy`WK=!GRl9ktJ=QD)zq$2Bd_2%-zNri&5|Ob{v&-YSs37? z8lh$<%`H|87!s# zKqg>MHrC70!R>gD3#amN3Z*$-uHl+MXWZ>aRRtvyaLH~ULlmV7j3ICU>Jp_~*Gd&TnLeND zC&zco0unMIm4b=llgh(}f3nMO0wb5dr1ZO#N_J7OLU2OX2{>7#g-+^*SEGjKTE%pdeftjWkNe8H!g6f3S? zH3I3154}aZx3upKJdAYSwBwZ?)kvO~PJ1&4?YIT?C=8^$2V*!SFs~bH-}HRxOc&rV zhsO&o22LWYe4~8?##$G?n7zwws2*UMET;bQo!DS}_s3Mz0OVEDw>-LZ-0LTGTWv>! z*-3`V=;uCapXc=d)BjjvU(^6fXyq zD@@G6ZGVEHDGD5D2R`NXe#mCv%G(&{ULq&fPH2Nkv;am&^a;~?MF&K*-PK((_|m9h zs+XY+iZEzh=Q7{#Sz?V8fxiB%A8MNAth5b=jzK1GLiR;6bvIn4cH5k)HQcDmRT>1C zC=Zn>kfm1o>#K;VzNW(cwCnZluBmsz`*&#S=k=rEX2wV&WhL;LulU0U2J2H9ED^+s z;H_u6f@z5f42&2Az(IHn-ugS>=GRpwaOnT47@D6i$o(F$n0+KxvuNkcDX~`n_DzM_ zCJni0mDi%`4+o(%1i^UJ%)IA33MnSYRCcKl0W}0_7xer(G{0Zv&U79`O-|5SSp1_3 zmi{HjnfCR|KxBfDDq@ojAJ4yEC;*bJnTpH4H#`^`y(n6!i%|du*K7v^O9tVwUp}6g zav{acQa6BOXc6HzDOLV*N==~z0}isT&wW=6R^JF=-@xZDhv9>gH^_e(Kh>+CDJ<|* zw$5AgD*{8PFW&fF&v*zB^0r&Dxf=zr`bO{{q$;Cc^1ZW|eS30b=nAo<|I`PV^f}Fd zkOby|&{&qv-bpb$)Ha(z<^8$S6*lw}bJ!ou05$%jov$d6gzu>4J1rv5ZTdih-P8uF zFLFFy0UI*3z20yKVd#*rxN1*M4n+WLT?+{TT-@NR5g3l6^5#ruqrYboit(KdnS-Ko zO&qEu8xY-|vxu1au2lJr!j?C(+)OpODg00C2~dzBUCTFQ;@K>~XPny2j_c~&Zg!4b zft)f?bOxrOxjqut{nE3uePptL*Hbs})Hza1vh;zeDj3>$%HeJyTTRMHjvpIo*+@vj z8O3#zFoKKFpz$loZXYaNV||8i`h_HCFR#rKteyp-zgkeg$KX$mAz&!WltENoGcXVQL64J2=l=7U26Rv;Q+o zB)2yR_7|K`ALSo~c1gyI>9)cs!#HZcJo|I1wuJclzNf=lCE}D3qx4 z$K_Rl3_@{EK5*RbH2K_-RUHD}JXdYLs(Jex{X$u|eb(+(?%HS_CJp;sV$9&Mk&-z^ zu9-O!266)l>;|vI-;qC)QgH>+0ZSOFHKwNV66Gokz`2!VR(Kgy(vvw7ddbcF>l+HX z9LLQT#i7kaLzs9&MV zQ0`{I&UqRvIP~Ve!i}1nM5)I3m;8>F3&+7)M;Fi(njPvECfCOUj)AbglBy{N9O!@1 zcaWt{EZ$vDqz}X#5F@)41PCnPGPP-+)G7y9=%5}ytp$f#ZbUfr+Q&1e$zs#|TVzaN zysVA_EU|r^-_!vZ0_^W2uc}ma=oZ^BVz{0AJxOHy%00Dj56VRzu6~ckieKv-KBAXF!_ z^xG~q(e8=DNA911^e&h_2YRcpM};*4Z4wq32zb|m5bI{VmxlOYo1mmjDjZC}FDV4L zwhnEwyb~v$%CdFGQ3cb^AIjDA7{PeW@CjSue9JjBFgdncc6|Y#9bB40qSfqHTU=9O zhQ5p5bnHPxU`O_B&_V>f#LNh!`Gl?6zW8#2hVd}K)+D@bjBD>MY6T^E;FcNS#^FJx zq3AOtauR0d7|2s42lSD1X-T%f+uxzBc=u(Eegh$Bo36*9CL%~=b9iUBy2QC^`sB*NC^4pVs{)OYnVpXAp;_a6AU$ zYg=?Bj0?2+*9a4Ob{nrYF_YTq_75nMC~JJP7pY#4BXn7oU__e^Zw&!MUs}z|{b-KO z8x^xLbt8|F;wIFZ3qVuVm)5UE{gqMr?# zd|S`X>GE&2Pl|3>UGq3zN1MWOmX&{N7=-A&apN1}e z&Uvn(^PY{zUhPF|MIm%^t_9cP5wmzUQ)K@Hzcp@ezYXFDHTI64S^Sp`!F1J$ANieN@U^v7Hf-{TzfAf7I93;`sVTFS25A>2gk-?;Cd$QeJnDJ#a> zW+R$oQAR6ked)gI+}Jo9ZCkJns1c!Xzj*Y�l(FMpPS#+Hw4}Zc5qyb(NO)vsKpJ zjyJ}#FtY;Q6$D@JD}(Q}@kUiLu6A-q9LNxs-P@PV87c|&)o*B+6uG4PDhYUiOX48D zf>0Iau(9Lv)Q#aK9Oz{NH4{Kdd9gY}u+j9mt#$dUg7-7Rx+F}EUE8@&3oI})BQPMT`Xp^4 zlh|VKw(f*ayD5WtZ+)QP>)8D7p_l(%r%M!M-eU(io$Ttogk7u|2NNB>^V7r%bKTs1 z@V>)fgvXqGeI_8d>hD@QJ3Lna39=Xn1-HL(gmC+lFSWADfkil0w%M zfQ0PbZ~(&QHhK&9HWOD{?LB63rN+50T)w}hm;cJ2OR0!P0 zRpK{!Fk-0IDDgYVTu3KlCj+{RX!BR&cb@ePQN7NOAp)f$7uBD-XaIS3C4qhwx`Z5j zatil`pGUQx*~aoxIbJ(>MFGGi>I$tCw84rIhuUahl*(d%`$c=(czp(pk3c_CA)CKS z_Axili@i-;JnibW-%u5G#qLAl-+xNq%f`SD!D3xY4Ay%op8C#$PPAsra_aS;=p7+{ zGzaKaTeO*!M;`D})42W)NB@cg7cl*!gHmLc6*Om^@8wQg@o^}9gIghLo}2mHK;gfx zB~O;%dQmywfKr@hd)`A&u>hlqHrPWMBcFIOwyqKU<*?nuX_VP&UtXG-Nuu1|rv3O6 zDVNOMJ(JDiYF3T87S-x%np(?%+RaqQ$|qRQPt?=i@qWgR8w1BLHwVw1&w>kQit z|DrKmSjw=2Gu&uGh3}+E{>eA^#QsvZze}HjV4})uPmxEp_y>Ctsaq+LX1Bb>;gOU? z)~Z~+yY$EC4Ss3}c&jh5Q46uhsrn$n$#H}@DbP0n)&YBN`nGgG{^&rWwDqMcYpjTqe_@Vgh3R3xBK+KWV7hTR$CFte7uK ze6mVFOLL??+>zv7gL!&#BY+}WAN)O;ToSMh4|ogvV$GAs|Ebtb^#yr7H~c9owYb6E z=IC75mg&0^m{6zX5CeGe4sNwW{XKfMWp~jV>+H1<&h^S$1?PgL%!usqzzlvi$c^iF zkF87JswOwHY-ZblvC@2AlEr&#V(OrvPpt-8`x+PMu59h^gu>YOtmql?g=;4F@*?CubfwAYeLK3`ivG(CmvN&%#k7<73Cg%V zRb~8LL;$zy;d__Z6UEho_%pf~)MmC~2Of4c82R zSwWvaM_#0hC(URGhJV3zMuVOi4@8d`B;u_NM6VFf%%wBJ94dj1pXCBMyjkexx*6H|o$-HZn*dJVSGe*I3iR}_w za6p!)Q7+B@^#VL9wgQyBDk#Ul-H)sp-+57z*wfUf>N&NkxPiA`xoKAS@~3svc^42E z0>f>uvHB|qSAPCL;*AxZ7@!Ki5s^RcV=4fY`LS2uKOIScE*4qDk)5oQnJ=EtY?x(**my1kL2yGUE8`kdqwAPc%2AaXyUSG5O)#D1Irv+N~R z@(U7ZpaL=PGqht=2y^3x$qM8~53=R_<$^Y&`J)+%j@#^J7Yx|Ei0Pa!*I2E77bwxo zyw-g0IxA)oz5*cUcfBanev7FdjSX~+fP4gHg+?yB>Z)Q-*syO9gM!2&9U7omv$*kd zyA@}@{P0F143082M?o`0hLGqo=P*6yKiGcpI;UVSybrRp$ya3K5xV2hulp`oVtoDh zFK-eF*TGj61z1W-GVOhziU{EMPh#z=6_xfYPD_^nn{CF@6T{=%^#kA6&hF#@ml=jZ zWcXbKEF;6HRebp-&o5rGY@3)kZT`M;C2cE+07SwR5m49Oj_SVZ{Ng5&OwO#pHiR+; zK-PG2zk3r6M4vr++3Oi$0>sZ7ZRS^Veg0@Hjh{n$XR}_Fv#t8?&4E%Ej2Ez6T-3^K#qiGOsj8MU;=zxYKFvZ?q z-cAYt?BZlI<0QGU9X|5jR)A^pP)?>Fg-zQ2THG}!ML#oK?gie zz`Ys{D0df+ zke8Z>QJ)HX*GB5ry^em!NR0_VB5bLEyjE)N-vGd+?F4SQzO;ZT+U z;H#5NEJR*-?r4EKEc}6qK1Bt;B%=m35xR1**=#B7x|jsc*2I*0(<yYf1&RQ&gk**g=?+MG*x-^su{yLL zWQryt->^I^{^JG&j5qZEYd6`*M|JVj388wA(|(dEVZ4I|M9Bi1!i<1GALZJM072F* z`O9oR^^N_#h6OwzXH04Yf;a{OOQJ<`iXVDNM!^7HY@3<2VdTJ95ab627HvBiU~s6ek02sU~fq&PJr44u6- z99eSHn#3Qp{U!;Z09Wz9xDJwFaE8W(_>VxySc`5ADka(Z7j~6o#>>B%zyIo%89RsB zVFQq!WO3{&^)dR7!Dt^n(s83$7Z4KaVLcB@+Pvy6mPcM)9ak{&}kI~%y zef(2N>XqeMB%8(!w8Uoi#eO*T!@k_jH#zgmior0BJqhgGAkL-k^b4JNZUFf1w;3l1 zl~AM!siC-=ZNgOk08gkDW~2jB1Vbl8%OXy$9%m-ZJ;2`p)5d$iHh7{N&c^rrSQ0!cYRoD@B`y#~;PTopgN@g^)7V)OwVn|4SD+(Z%gU5@-F>1^T^%{$4ppac z%{$aN;#*Ro{lXmAE88S%Ah>JIW9hwqk(>27ae#0rz{n-x0MwvjLlH z%_b@Uw18+J2OjF&jmU0`0jPT@zY4St;erm!*dQyx82ZxIQu&66fCedodc+uhWGr)+ zPaH-gziSyL6aen%iazCNR~O9F0Mg9JzyiUZ>*Z&4hNy5hA_E%LVc9RA3L#*K88%0! zxV&GR49~J(_Ek^-%I?8)m-#!g#k?CY5$zl|yMgJni!EopNPru%t-_abzutSY3=jMz z1a23lNwueq%I04#`{9AS_Z^HNO7xDLbTr@x?1Bm9KN8o=R;v5h!hZk~JSsz(d$DLh ziTb+nKQt8}V4zG(qp8fQ=MD~lRs8-60$3rVDD`Wab5SN|(K{xJKSB!7<;%~g;gR1e zqcj+-b_7|?r`L9WnB(h&ucm~=|Fxfzpt2AVh!9LNOgSm=kzV16nPwdDFcfj<-ow)) z+Pz<}+aeK!`Zy8?C;8bBcKJstE|%h`2TzUsF{LzmhK)*C(3TH>fcN2U-~vj;CBE&( zbjQJm&Z~S>!=A#tC0C%=_KzY3*oeSm@qbtl_NheE&Qli3hLM38CfHXHv^OIF3rTE) z8`YP@9v;Z<`~kR7_%oqA0?-NLzb`6I{(R0m>`}v_6l8_2J9};W-HAQ2gkK(5FNs|! zoL`f#+ob^@s_qw@y!j`UPlc*6?27-YSNoxbZ;^+AwLfIAgRx5>}2jX-ih;Ezw=JPROijtm?RY-zs|@`h2ec+@RK z;!G`3Jl}Hzn|p7EHm8JSi!M{N$w5`>g$^U~>#989Vug=MVKgd*h7LOG=vzXrh=BL$ z7W~h*RQF$2)*#JKE|-Ia|G*GKnbbe5hC6lUIlZq^7X*}m%g8r1$q^;KhlkTKjQx)+ zZP?e%nlFvKzNs-iB!V7T$#sJ#Kn^t4O^)`urES0of9sdqYb4O zF1!=$X*mApWqtTgX?dtfSGfQALzwQSKC`sAAVSHO7LjieID%}gbn(5~;SJZg=l0eocM^}X&J{2j5n`1{lNs~nVQvI$WxQ9mO_8aY0RtCuN-*TD;wmx znkLWZcs%P>hj=00)D16EQ*^m6p9($nnL4ynIsSGZt4+;wTn>7N-R&;GHgCTo_bv1` zz(z#B%DTbqu6gvrpYcloXdD9cs7li~g)b0~E1-M@365ZE_BlUvJv!JxkqJeW)VpYheo>SU2jpp!L*V%O9 zM^{*X!+S9-O(Lzb=Q3CQ(}Xd`W)gwrh-xLkPE zm>>K(lRbB?Wco`Q>e@)@Uo^&Mc;Hu4AdqLfbb7}AM|r#8{e0{&p~iHq=&0CgW(uNG zwPH>ZCd9z&OH-W--0f}l$FWTcjPB*S&YTD2F_i11yA5eiLC*gjQF{b%{B$+rEQv+q z34YT3Sl8`#RLB;PS-F2YDAGkeAB?7->9rZCR@*RPhm)%y$Ya!8AwK3ZY|q_XIdE7R z$=w~Vv|*{YNMW!bhtOReXlu0n`km8(_v9}n!U@^_|GsLf6Wa^IzfyBpZjC)s6*^kW zG(G6wkP{>h*s>mHYQUF3>BvM4WqA+B#8Wkr>eziG(}jcFooi6WjlP}c-G0L7k)y~+ z0s>ZZ>@u2+68_T5efJj3EPkxD^YV|M69iy(>2%E}hP9mM>dQ?QYSzIz)=h%W89JrD zARy~!iLdF3+|dk5k?o2a+2q~YX^!zo%XuQJfq=FBxWm;;eq!J zQw`LYD~-b{*T2PX{kIa*_&iF|dkMh67kj^TrvMcI z(izY6?$^;tw&p>9kYmd)LbmH$LnA^CW*~-1S z*!MceZvemzUyHP;uIH|6wWtIG$c2#0`~as)g({+=ynIU?lF{Z#3&ZWEZgsxbB6cPI zCj~`p&;FI@^*4bW;ws6I>C(}A^HbWyKDj!H3s&Ob6sZ}Lvj2=Zd6{#%W`& zWj3&$h+K5MmBsgt9S#`t2x0It#6l43CIaUC<4XEvo~fP1*4f;?6MBcbEUkC_#1}FU zWmkq@?t~Mro>;LJ#H{>@M+66*_DjJ?)d2%Ys)TaiD5Qhi*~T^<;@@=OtGnQU(kl`I zL`|#hZe;U|EHwZ^iXgFhD`#8aDD)v}Sx%3o{Ff79yS0{&Q#1yiPV=-H%?A$cr7wc@ z#L2{Zjf)fxm`n5oKOFOeJS?ikk%imNw`f${4SxlMoLp{x_>L~>>q}Y2l#3nWQXX}J zq)-AuuQ)N6%}WvS=zT`fZU8@7nw;y&0eN#zAM&O0Gk9luIB?lJSFYa(fTqg5)6JMG z0aE_Y;}(XOR?~0WiDrBlETTM*-#ze6(E&mvLXV1CF3cqg14}{o>vXkcq>m)>E{PPQ zScYsr$jjzhoKOG`G2!F6E0F2$8RFE>HnQ}l$TllSjZR}A26Pg>lqA!Jo$!50K8U<# z1vesaZt9-qvf!Q-hQ-W5wA6PY9*w2pf(HPIS`Psk_K9$&Hxodg5I+D3{!i;;V(iq! zr?&0H4u6EMYvA@BrT zNC_tczOhFW*~{PIp}`b!Ac&R0H=jh03I#-_@RPsT)Pe`4iz=i%4gh{{mIdWal2X+_TSk96B0JOO5M$A@L`)X zgupIml`>HjU`iMd+Wck>r7Yquo=w3P`$3ScOGLBnFhZA`M2NJ$$(2Sn01t$|ZgHu* zgCNBNIybZVnu#66xVoT{kDvBZwG#RuHk(6USNDiBn46KQm@mjSVCedxZ&>leHxe;P zTUtlSNd%wk0z=a4EY* z;$f&+jtSaGurn1n2)>$F;*KX}=D8MQWDPvyegr9;5(uKG!rnt$J=5|lNZ|UjrM*Xz z-11h-k3|FkQ}xz*tgYFaTtr3(!y{f!76ag!WFYq^d%Hv{Ewlz8mH(n*ro_kk{5?mD zQs1?p8XAux04vEfS1*MZa=4GJKzQhFuYHk2T8A3DvgZ8!wI>KTB1#etJ6o3XL)rd8 z1w6bH|3W|;Y;V((Ey)JE0yLKs0n=kw@mLuflVplNPIpFitc#wUiXt{K<8qnLYE84= z3|zr%zgzD1b?@{&2RuoDnpyJ7@9E|1JTkK)-guNMt0e^#zP`kdFJ$TP9UV!0xW6qA7RwS-hX*R*q{|rO0H9lR0t;+c0?LCX)cqy z9929hX}T|i0YJJO7CM~`s1DQg*sLh1Ti!DDqigxa%{{tegTn6vX=7Cj)&DGEUJ8Kn zqQ)%P8Y0O57tThz8t`Z~qGAoH?q-A0>YX~@m36FbJu86fe7ZwM_w^KTIWMBj7%#)H zXT%HO_=xxeb%K3j+DDT`gln*Q!e{S*XhDu}2gCo6IxoUWL?+{aZ>(UfEQO6B@7{RZ0jfyPUnoca|f? zk*>_deF#UT|MT2?i7mLV9i2FE&cOYVXclisRhURBbcJ{p!&t9S-ZZxI7dRAsTq+t7 zL51^Li#?UEI@Gg9k>?s-R@k9oGT8e0+SGK?yZF&PRhw3?wWO(>-D7Hit?X3v?*9*a zxC;PSyWh5k8{8`~fhpu6xflp45B{s=O-;Wj?t@^?9-&o{lo|%vM5|{WV|W-PJYY67 z%q)!>81#i3Iu=H(voACeo_wV(&wi}B_oC)X>NgPUaABG)gA%hBjwNrCluU^rSwdpD zPj*(&`f<1=iM~DPh4AO9tE|r>-VK6EK`ozt(^?b3Oc=%o;dHx7{#E<*wyuxGWDv8J z>X)51eSY(GfHL;zGx@*`rj+mLUi7j#V0#=l!=v^vyb;ojCA0XgG>#(ZgA{RvO4Kv+ zNHK{O(ylkXX$YIbDk`vlLw+Clq|W-^gKg5onY~9!GkakuflE3*f&*s+g)~t66s(!j z`bf~;)SS%j1h;mYpo(O>21_?8<-cSznAV$T_DUx_koKJSz)FM1&7> za-Z*ddD?bu4d259(UdG~_DJ~umL&#eghU+zLq#1=L+BBWKlPX>=Iu$aLju6mn9om6 z4|ONa2YB)4FsX8VLg^ZCWQcha5+EhrQ@`-pA!>a=sI%`D{G{^gLIC+~0}lkY|L3rp z`4tdDmR#c_7f%r1mkjCQbuv4lCP(beOtoLEL>4Q7m*Tqxs~5h+i&7oy%cI^qRep|z zQ*l53;NJ_tRa+e|Fng#g{%@q!%^+%ATwG(py3*9u+_ON&@1b#0a)c(`L(OW(DLDQM zSYuqAG@{!q zOy(#P%qm{5Q%qEP2N@O8CWx3;ayImv3WnYtLsZ7__xG(p_{{x@Ckz_yl};Nc`xf(K#>C)`c1JAQeyxa^|0bAAs6nUI* z?b18`1p-sua=N~_0bIJK92m)b`~e@uzOa!>SlEX(qS2Zbli<1?>Q@JI6fJS|p-Z&= zYbT@Hv$^p^+ClWE`{XavV^y5gRnv?UB0K%XP?fk*Nxhh(hKJ!t8hw(4c7{M@%8DiM%Lj6)-m*)08DtDsk3fsnKHfUwe$Y_ zSDdiFl)hu1uY)kPA~digR*Bebsxitk7Ir(QmyO~WAPbdO+j@v`?oR?H4qR0hPg%O% zb63d}XNaUHBoft}+uyw?=Q5qEd>7Clw>`d#g%rNuEG+w>*MC3Ni;u6LUTZ)$){RsD ztb73hG!3TgTce18hh!n8uJ!}&;%6Rov~cAE$GO+08DsV4Z!hH3rJ5ZUd8(^UazCxY zP?*SQvl%);!2Mux1GK`Gya2zuWzoPG&hfsyYcN=9h~U|6QzZK3_7z=gM8EGOvDBmj znN^?-bdb=*^<%=JcDMz0jpVoR!gY5^BTgP#-@#OF))3xF>&p)HOG%w6DP0>OEVIpM z{`NFGHeO~hm+(WJ+W$zJKIX%|`ul9L@rODPWUVN@tK;j;xyl7;f!l;9dr)+tS27{u z7vRIC1h;%`DqZ<*y8vp)Z$=A*DuWO+F09HX)sOO2<#A5v+$?l4_?#tqY02&Yhnms! zsWKtt%+D~>OtCSdf4lT3IK;90-0+U63K0ld{_eiv4nzGUzuY^Qf%lse1hqG452u_%0)h*@ zDvO+2tvzrO#t3i-~4)Pz;Wg!?@M?M7vq?~fQ68d zbikmZv!VwmfgW{8wN0T}t9ND@36N*;m{gj}BNTg2u0rIFGP`oE+KHhJ29$iVKiuq$ zdl)eT5X=x*HgZY=(q%pXL=za)1W_t5@2A@;a&I#^A)L52Tu}j2w}#Ct&bi6Nj+2cm zqQKD1JP}}Nc>@4anU^{w?`p-?R@d=Cllx-m?ip9K^@vtD#>9`fVlR~f@I!9E6kjPk zzyY|nrnpeexoT4ERZ}YhQj?yK(S}2k_S>$@QY zB`tO&Ojw44{V)508OC{5eq}$>5$6Bu5(!#B-VI0~QI*Ap&yJAvql-pKPLWsN-3`>s zfdgi2fP_fxYiglL7A+RB{?xsWNgYvMVCYxwib2+&m4y!_k#^U3GYi;1Lh4kQ+Y~s( zIvc-A0uSN;kTs{$D4bPa-qqny{ziB&_!+D9_r%@y^9?l8EUSc{|A1Z3Qj+~^Mnp0( z@ed~f0JhGo#Pm^rGv4XIikwt}UHKv0C#OPkFh&&z422@qgJABFQ?HApKnu6@=PLv_ zNE|@94+o^_BLlXTe!wO!YlK7Nm*oS~{W0f%G6b?s?|<%^Z%PDt3F;127ZZmf{3)u~h;tmo0L{^w%R?KrFv> zumj?c*H-bHFDU904&a%61X@a08?%#P#_9iJsAzPq;mX5^`p|^N|Y^^ zMxA4o!_HZH1Rxq41H|4DD5oF{F+$wI5}O&KWZIyrt=lDUtCAxhI;2<#mY9VfKE%<4 z3V!?S;!p|ZBpU5kud;|?0~&5*fIVYsS=}2do#pM~PMIu!WZp zBre2ZO-fh2uWcmxUHA%FjJ5gCKduQ00K{@vrLtIc%ur6F7Do4tX^X74b>B9i`FB#Z z@J1g~5b3z&EvuoYG*S|`WK_-n*!EW%N0R}jr(^56KOpdTq7KqV=0DxwQ-4PfK)6qg zPF)2onyw_S5(2uol3;l9{GtbYh+xVkXho&_uC{XLI}ow-Ioc_^nMsIe_*nB0T`|js^?uhgMzBLGmb6St?>2 zhicR)-mm1-IZ2y04M&xNQwDI>4Tj3j?7jn!D#6$6Iw1>2WTjtJMu7fj@jDR{o6psrjC-> z_Ux*iT%Lv}M;ZYG)U8zjJpQUb-ZZE|^zIybPTIx*K3pNZc>w-SVJ;0{JZ;^p3yx0S z$nN5Wc7jG*dih#)B1aN`TO#fwx{s|rC;9S684BgGjjtb6(kp6^z>u~0k-tjSPPmXu z4?b{NdIjVJjX-bAx4lKX+jlNjgZz^APR?XkJWK4!8n1y*w=e*Xhp9R-F}AF>7R1)h z0GK(m5e&?#UP&j7!?!(bB|xJ|)ql+sErbaH*EM$CK+X9TU`K?QxT0wR_>Ls0hb{{? z!~1ds!XJAZ@GOB5DRW<2hEtNRG2KsOv#(SoKX{p}T|F_F=xX(%=T&Q~Ba5Jivu0-P zdocJGFhIn7snsT?S>@c3OMB~hS&tmW&_=YN@RT*`UwzetV3Nt+lH5F<7%1UnWeP%L zXL8ww3vDk0L~-?4u8I@+e!NB0u}qLpY$@db8rvGteetM^IsI3ku~eGJ(jedcT{&jC zfc{GJVX=JE&4h-rtlU|aGUJ|6ewc2#1Ud6n4I$HaWIzDJXSv@se$6)fo!mW@7Xkko zib3xl#_2h<4y^+THV7|4Y@I~oAK23KVQYLP-Qv%z6H*x~XLQ)!HKH{#%oVsO3jVnUAJG(p-DF*V>XE_*ZR zILO9|oq=~!eD3QU`klwqDChBg=5g!Ic-*z0tRXo_bR*%?Ink_V_goCo65Bj-CRDA& zu@%GDF)1l>cCJaHO`hy>ks8mKHxy6xdE;*&t;2rnu(VFVBW=IYvwCB-zkq2hfHe-i zTwniKNIfd#Lr=GJ5@=Gk)elcr+s~&)SgEY2RwGRm)8Q+Y#k|v@Ro;7vrcmliF)ft& zAXX?5GH>kIYy;t(=;`~N=>OBrX@?ggRG$y;hdA?^v{BgdV~gVH@&BcqxNUS zhtb~kY;-M`#B^?o+|UHYI(p$u?%B}M1gYx6F`>cGFuRW@=ZX6!O{8Brz9xqz;}&9Z z!0=gvY9Oy#l5Ri~61#HxZG^lwi=QnI zGuB45Mm}`XP944=}zz%8N@k=D~ z&xU_;=CO4?9}LzklsL1BerY8uv!qB>47T;h63y|*g=fq_`=71k(TtP-lO%Zt+s&v2 zcCNVbzXT&nvn{R#brLAO-^X%3bG$t_jKmemfq@s-0(tT7W`=B++?J-!2i8|e8P5|X zBiFeW@;`k#>f0C#JFi-VdTS_}AHriaHiTNFl_?JGtkXp`Gl(f8)J8Xy z3V89Ho_>B5V+^>^f2i|s06$3RnW`IK8wJdj9x_s7u$|!eYWvrTUw3Ia2437K7x8&H ztV!B2?L?1h3!#t@;EAa7oOget+-WZmC{5;k9WaKftncKEr7EjeoMbvhQocsaiXi=9 zVB|`A`^?gBvUCT38A~z1HumF^LW$qYSWpFSyh#&(^Y3PaSYDiMH;28OJ?;*-lmv90 zp#Xso2GJ%g^@N13Xa53IzxU{~jY{rm0=OwF6jyn#6%A4t6!q~k(a@Krt?Tax(XYo# z>BrJNi}{!UFYdwEqr!DVT^AXII_#zd>^3rJ<)lCgw;3xQuE9RDb zm2X3PDfyLMdYf9R5FL}NZL@=H&VN9}x>0pj_wt(C*25SEy;;PYeQ}HG8#s;M8tL>6 zOm(YF7j_#)u<2^F8n?s1->RDAJSvWJqvUr+GPb`BEt}8rph_@!brH5vaZ#|F+G)eV zU(|_;%fj`loFlUNx{W(NJ`Xw&d9-k&T)=v)iYn!P>d;n3S>}!4m0V7 zcTd;P5jXJ4P#erPOi{QXgXEY`cI-?uX*gL_Ko5uIrjH?3d}*Zt3bNZf%i>&rxaR24 zta7^5^xbJexcsTbw)KAGZq*?08NKw>`yKK!7F??@B^z8KMCNE|vh^-17M zJFUB6fvCQBVgTrD>g&i4(+_tT1r$V7s6PH1E_t&{iUoSduC+~6zLe#4BAE8VtT*NSzdJY`N^Upj&y zGJVWr#scY8{?2B+IDjCglp{(2dWFlNU?|(n{ejwhL|Z`Qm7CJcN>z#x4=E_`bY#Q$ zL`0LawV}1(*m(^9b+Jq6^T-Z?!f#{%NU%l(o*Ux2^@pb`D|B2d)PlNqr;KK2?Hs$yjVAni|2Vz7`06wpdOz_lZ%dbAM zA`0M?BYqH?NP9677%&~1Zp7KVIunrZ>_P@_IX7Suq&RVh-Ismm%Mz}|3YxWT?(tL} z(J>^4eXZu^bL(9{>JydQ9sIqp0oEW%PcboJH$ar|Y1<~cWX$<1ZlsZW@ZEO? zI~Jd_$>5Mya$=cwdU+@V8`ZXB0>KvyKqq3NL;8mnz?o0mXiUA(*#$uz1rYo0kOlzf zS5E;fpim1RG75`10^lWpx4b!Gd3@w8Ldt#Qs3In2@kww+nK4!IxLtpPUEGxscyuRg z>!80!9(?0vD&%aN0>34B+?M(8Kfe_Y%5(c_a14V0!phf6I6q<~@sN;yli)CSSpLwT zBEfirkeE9hcaj0b%-P=XH{S#BQ=EkNd2oF`d??Ps_EXB$=ark8Yxn@+?PeA0Fr0y? zq1=!_{*QQ?uE~H};y%rA2OnV`)XsiHVaJO@ebd&12=l$o$5O*?7|&tg96(LWmHFlh$Ok3Ro?__M9w_jt^c0RV_jWit?lis6x> zAE!%QX*offR=nK=0M%&e_bC1`$XDt0F+_69j1l7O|KW!wnAB~eUzJs>_;W_V9W`Nu zi8mEyLhY^YyP(Cy2nF}rv1oRzy8%13V*Rtx53=d-s4g-}d!?L;EQB$f?R{cM~aJx}Kc zYK=pQ)n`|K)K)D&95C)uNdEf;|G5iAb0Dd>3hn*mILquPLW_LW@=SKjBIR%INd6y* zJ_{kTpO^LtrFxsj7qG4CC&FR_uVY)>YT$B~RM(fC`tqFOcl?9XHF8}&O+o3MGJT`5 zd~|v57#8VD`e00PC=i|O*VPDZ3b?yt)%G`n4^-eL|8oEIn`B7}3)YJ12af>xA=Z-K zxsdM5>GdmFE1$XZ$NaQr6ybf@x6w>)_P@GjOv4JAjPHiT{AJVNJAdTL8IBx-Ng-gg z&PQC3{R%25Bplqb31{&64ma?xDP~ujuYajV0OfC#6YoPh`f0q9ABA^*yBPH!bKlsg z*{EJmAC}A+Na~eqGXwa=ysQoim%%Cf88)34wh2lE9!sJ?Wmufwo2m6XA>rgd?!u(ChxLtd>A+eL1`A1Q5at>Dr$ z=@sH;yG3jtQ<4rHDLy?}5+4eqqC1ygS6_5U#twyZZacA+6cP+?Un^IZYi|1dDkRa` zUn-lc=FJ%t?%W&j9XMC-Cj91vL_qF$Pf0o)K_`Gm>>5FiF9H?KRncd zEK`=j@9m>>A{T-6DAk9(mj@A2(2sJy~tRBYVuRIfS>t*={G72uTwXy9QYAUcCY9c!S&?-m zsPFgUs4C;*PetWeb-j(9L% ztFe(EHCs>hQO?uLlc0EKgUpNo+#96qb6^h23d_|IwRa1xSIxUiChIwaR9aE2<3>?06iQXm ztb_l!Si7G~=X)4888o@Kbsls@Uo+T}5O*hhq_#Ha-%5*~ul%yea+ne-9ie|WYmLsv zJhpsK;W*A5JXJ9MB`J48Fc_U;w3$E1c|@*IOY6AI)rk!!_^>6IPEL3_StKtrG0^DE zt({ZzuKH&Tu7LKV85>PW5%71^A=vT4azuy%!Z;~_X;iDXz=rnZfHiTey^DUBdE9(K zf#Y`=cv|?wdX%^pfNjeUKkbPT!REbsFM$?vdW0aEARoHC;dchHdRE92{>@7rXQb$u zO7miTk$L_^i2@%aJh~DOqiC~B>dQNBOU?xvVxLy@Y8ZeM7t_WOJ|$vJ$WHu)lETuX z-Ay$bp^qu_Hal!g(wtZZu^*a@Q!UigoD-%goGI{lGUkORgeTE+B|T;GznFW=VwZ|I zA)m=~G?26Sm7kJ%^9tBo{TF@Pz|Y$viPko{~1Q&7zG(c?f4C&e}B z7or&%`+@*FY$8TcD7L$=)PEZsz5Y!`{NY<-dpl$3gkoif!Jdg~XU*NtHYKabZE z1^pkW@ali|^%Uqx$_)DLY$G)MMZTLI69?!y{s%>1dMcvSh3#a-F5vo2-<|=8MO%uS zU;DCB5>}XrTa&fN>{nnDh0IhXiqJ1LsgLm9t}|LF!D0o zedG#|zswjAvgexK-<+YPynxyud4*sM^_y?-<2^l7W4U?+X)W0Ufb-+U!Y?}Kh8Yv1 zMSIzTH=++e$=CQ&+=C*L#1rBMUxKdXkF0cFIRiyL1-0MrP1)jzvW5(c>rjoX<`AQ# zL=lHMZOGYIBTP_prMobu(Kny2xHUr4&Wv-krpuz&QF(^5jW?wuHWANYT|EJWg#kxp z3}*u+zZ^i+hF;jPTHO_y{QEC6X%H&&JWn1C)bd1DTqDKu;>~+QDbCtG%(@aigPA%) z(y2A+UkPL?ax|CwoyCh?1?u1vju$UfXY9wv5_;1)9)zhOw|y(j2C!r^<^`MUAW`02R+ za^uEEaA73}8BhmKIg>I$LDyvG^nI@!*Zr6K164%?`0M2mvv{`@I2d{2tu+ZoHvSpW zOvG~IzStdw1_3VbPQP}^@=b2pXu4=3Zp`dNqgy3OR((!H>QW-<%ok;XQQ`1M1Z=vR z28EQ#Z@=$f_z3Dmi}T_i7P4_YNv4IVOQpB){NJ?DqX7W#Q!SxQlkIywBOJk2vk&Tm zkHWTi0YHzdvhx3(3H;ceuS*oBni6)1tg~N`DGM4XP8edv-)+@-*~3=JSE2wFU7r)j?|>_ zFTSKNkbu{ljnaWF& z_O09WIzGKE`-rjN;sIGeH*AV|aBz9e7w*HLFoW(ZpT-a3`AM?XLtm`D*v1UCzqVgw z-LnW=8~q_mM3$m&@^~qE)&A6Xybb|TDYo%ZEOO$yn2^mtb|OlO`(ZL5)1wIBP)PVO z-TUQ{b}&_pu}@-}6VFC~Vvj%L(WN&Pirn5kVAo7py3zeRL)Ue)e&Ip@)eTN;n);|X zH2H-f(@3^ZMR=U+HagBbQJ{}?hJVQ+L zN%1GWp+z=RoI+H=hMh!4n*Jc$k z@`6j|iZh{XNpIhwm|H;Qz6OtG&5qTxNzWf@1&DsKR2NkDzPY!re-M55OxYU80erOA zl};inGt>``w4=b(yJ3dZ6WqA&1Or$+&Dd>OHDUCi;(+`5G_umP3I`|A=u4(9o??^xL!I3XDXn@k4d zX-qfGv0egcO|y4M0L+$#*c4#3f29Rfo)8+a#|zm!&fupYUWmTQ*DGvWa&0y|dkKYi zmB@|oh*Mxa$Ft|tG{;c?r1qh?|=ow7D&uAa3Grk5zobqkFH=z>mF$V5}v#p z@Iw!ANAqTvGq(*(Z**L{!aTp+Fsjiw)-RC97YTmY@B3D8Q@)FZ04_pPL>{wN1y}O|2;jJDF#hh4eb|No znx-!J88NmI;6Y+}8^Jl@;!L8?Ux>XnVs4y?tsd^!Kc3nsv@8G2QM@RQ)wbuxZw_!7 zi&(%kjFR#cd43foh4LREzo-$_u|U8`WICQjg(|~Z1UN0zU1#36T|nH>BQ=6%v^&SK zW=*souL1ai{!4dWEVhqQRP0{8g9=}KKF@x(8BaOizPqdOfAO?iQai{BHZ6P1_$tm@(9V(z_d^9#VJ;R;;RB)p~c7NrX_yypA@Ux@JV%$&HNxA30 zHOTlq7_i}Hj?HXtRXrz48OVfP@%mVBHVqUhFV{Fr_lrWRdX~8&3Gw2Tdo0Gtz!&*Q z=ZyiXnCJUHO0=dh0dX6R72IVjveXrkZAl-0EC8+!A_CwIgux7XdwW2%21HN zH>z6FLN1DP$aiIvkE|vE;2Zb5fDHm6bk zI$G1FsO7KvQPxBo}KiAj@eFh>3IRourH=sAg+>!ZN5P;^6okgiZv5E8x)J8q&w z#ZzTog|(Cg{_HZ7A9<_}5XH~&DiZ2?l5m+|+R7jkM;G~Zj}m`tQzAqI0cjzAz6y16 znpl0V_!RbpTlIYbrV(fZ{^o$4_s>HEfP0QHwIZBEU01|@O^Ae!q5#F@+zIhmDU^Je zjQH0Uq7xJ!Tb3wju?-R-BS*xhCgGFGX0UmuZ58beq8kJ_(hwYGb9Pf9<8-`{6w&vi ziD`c2yOj+yPeMtb9#^A|=J9c8*kDxw$4Jo$vDyJqP2I)D?y;0UBXrgjY?sa?VUcui zbu2Gng72l-T%EeS*%Bzyo2WBA(n$NtTkF3u(s1PA2PIEEmy-M95+ZU#VT)1VuX|+6^Ch!eBlLuoZn4zZ z@LOuQ)kUv-pib?g^1ljQGaSaI!JW866o`u+<%N(8uVf@$luM$Ob*Ekk9gBQw!VSe? zUOw4MwOXH{u!Wg-0}MmrW1Z_P5gwH8tw5=|$a$av(x}B4L*aF<)8;`ua?gJFhtD>G z9}3cVxcN$qZC9+cP0rcT_v`IC2PY=SXOIm06N^f9jD2ivq(qB7;tyn#kL?7D1ZVy~ z3n2YpD@ zaKeewt3Rzf6nnR?DZM^?<%Y=hf?3Uv`ZY?@gGNj|S9soiXoOv$S*MJMTe3PWy4Egr zp0?A5(B!rKwFOsGs`z2B=(o6Stl#1dTJkX+Du7-zNNVa<+v*|TE6hS&bgIe>`K=!ivi!WDWms6LB%0w z)rw^0dWbM{GcTj!TYgn!__BIL^`Yfw_E^R{)$f+b-VqK3{zWXxDm4?R_ zf!F=5JQKcY)xMp&yRJoYYsKi^BlNJYgXP&^;{n=&GZf~iVt0EhqSAxgw9uct#P>w> zo7V5*znFD4HK)6|@XM0oB2nYJ5;YlpdmWbfyZ~57&~kY{mv4PuZ6hxIR-F|v!+TAI z*Ivjwpt`b`8vWtx*Yx=WofV;M6dewfZ|~AOR(TIH(KZ;m4Aq&|@)sKo(_~|kLR&V? z)oDCi()!-vRYbDwiaGA5k zop@CKoxL)%c0G!pfkX+(8jHI%8V@i30P#Gmw-KA}wf(%1jKFi34Cic%>ev^@*72OK zs{@*uD(*pa=iFdzKel@A@61wQELnHZNAlN(V<$4@d6A#2CK9%@|1SX`mZCWFQqgXT z-i*ldf#~j~dIw)+f&8bM_uO@R2Ni5`XaaopWi^3D48~lIHcj&Q(+YIxPTigxOp#rSnF&o8 zFA=d-ihc9U^>17o-S%6Os}|Ebm*JKJ@2T?}!4u*~3cqkYi@G8W(|@Oj0BDeYp%*yH zuf`Nb-y+Pc{Ijv?ntP?I`iY3xhTt{g{8fXS|27N-?PK5W`)O@^**8ls4z4<-RSgc` ziaw5f3rY%jCR?|@N%|N1baZ}kCm_EO95ty^Jr594s!emu5Eo(%WcUf{SUy5y33ifm z2o$RZjUEv7Lq2Tq_AN7$=zjBXm`v{mKJK}b*wn}v41K0`a}f9|c~j=)IT_8!f3zz4 z-khbRH>dtps_6?aJTya%xnAe}uquqcNujFcxMy%y_YK~wh*bfw zwaFJRF>z~n#Dbqt+S+}Hy|{q@0-ihZe?IgnnlG)v=*D@dkW?#c_+;V(nCsRk02T7Z zhR@C52@aS;vr%Qdv-*is@qIdO zdk(bWed%lOj~O+UjF9P4mC zl$RRtR}Pem6h7jqJwjr3^#%?vuafCKa%&Uz9TgL zXO|?M2z%1I%$;b;Lex4;YXdPa!I!91SRw0r0;>?vl^UdmWPV9R?B>a2daYKer_-<& z1hZh>zZlk1Q;VN*Lwv(B^onrn?-P;qwXvBidbz^0Z@@!nz{fiJk!OaHfFY@lE>m%) zs3dvFCM%UsR&IU`moiH4Bn_}_<0T}-n|Y+;zN(4p z2Sk$%NY{%!FZWM+;PcbivZGr=TF*Wt{LpN{!X`sTb zGF9LVZqfiRa0Myt*;ZU>fTnZ)F9I1N{hk`2QH*+Gb8q^+K?vp(p_?jraM2$)@D2fw zqPk_t#lL@>8*~|uK*T0SBzF~k-Md226hS_d++ZtTqX;?GWB}81(7J4K*KkTj^5(fv z<+2nx*jAPGEGoPOiw>6Ey2|+xag&6|aTvCZ1SO<}o^CO;B8EmEeN1}=p{nBK7ggPs zC9v85eL~FSXG{nJAw%*f*InBV3(%UG!yFBOH2mKMFrZKsVOGFt+Q;c$>^ph)PvQ0! z8JfreA-}1$gsOebcxN12SYpsU9Q!g@Zc05n5OrSMB&=QVT8jn1LuWP-GW8}AsVpF3 z&vO+pv6ud24YaHD$(J_;cx`|nfd#eqe1BC%9|P|v?WI^Vcm8W!`i`u$U6}koqUns= zJ<`oOQO%bKz1OrFZpl(FL$W{T^`t>h6K+Y`irK`H(R+(4dNshz#nFv)?7FYwYhZAn z^hRG>Hy&bL2p#2Pw6pGKIuBW#%2bqwvdhhyBtX0~kDy#Rm(yRn6Rp+r{iUFr=0hdG z$50!!w?ATuAp7&|XtZCu0gqriI)G$WrWi$>Z;)R8i z9ChM)t=sD9`bR$HcZ--^#)n&F7|UPClheF52ljJ5K_O~(9i*j`U+FZtN}RdSR3Q!- z{M@K1eGVaRo4Y;FJdNPVUIbDeqXa@5xxR>jA;iLvn@i8!$PJH-NaSMu4^+L#JuBp4 z2jw(?2VLyh_|aVP!b;Jj^HF3OB*}O7ht-xZFHihxw9coTx#yhw?^y}qsi(TVCix%z zTyb2;S$nU_5vNpmH_ZoQs}gS4QlL|^-sNbBrqsUFl?L`384p4LB2Ndd7xZu6;K8^<{4jc>=g<-1 z@8I;fa5cIo`tiYb^u+wJH^6`uyqJ|HUx!_zsLIzs6d*3J$aXaZ+h+Kz=W$S{7bhC2Yp4j3%aDn9eX* z_v~7q?4;hW352j!^%y_^MwDjco%4R8sY+ z<|PO4EkT6jW7$UbfTBOk7pUUQe{(1o)yu4cE%1aPMIlg_1UV9_o8!w|O~tjxnZjz>@%#Yvf-Kv6LRR zlCSblv=7`~kjfWuQf~48(xciT2R?LjIc{?M{APP{GbLAr)SZM5dO77xbC84Be&Yg3 z9=cs&`kwb$gihNtK>B)g=FR&FOH>)s@A=FqM1*gkzkH`8N6Od&?C=R#xpS^>e1nK6 zO0A)%jd<|(bD%Q&{jZs3g&0U2IdH>X|7eG4werjBW*k8!uM|2Ni#S<#EFSN8;%ND` z_2>DwFpht3o?pcVwa>&}2teybTef>cMw$NP3}AZWwgGt??blUpzSinBgH#~jdTrQf z0Wse!aWmmz5`x3}1h&0;zYXGay zQ0uu}!oim_BtH#5@gDk_AE>4f2EIA!ovvy|$1qo&=mfxUO@yp!YKzh4MgL~C3r^KAN2Y8tKNQk@+? z#4OB1tXZg02yI0wDMz&<8D6_&ZaE{tPX zbH8HMswkTMv}-Rp;PFrXqt3OE{^mkXDK4hb*Pppl>J~3$4CmWY7_yEcjo(UrY#A() zB4Z>(1MOvdUb`y`^f(SevFo{8C7c2Q>?ay^Sf8p%>ay3us||jA$Zu;DI;8X(&UesB z&6?sg@7ow`F~lA~YW<_nJBV~2LThu+gt`3cpddFcPr`+t`wcNhLT*zBzJ+8Fu3?VOm~k5GK-3t);t1(Q0t<>F(f|O@zT8w_ugR{SeR7(-W~|^1(d~_u?sL zX>E&W<8x6cJCKz zA+(m*V(kN|ox?#LG-9XxN$@{H+;LFBZP$zjdJ?}TQrg3QlLYYr778p?`} z$K5G3ck1>URNH=&pL+Xjj4mhflEW8DysOur-nTZ(xZ8VP&L%0>F@?9cb_!lVZA7?8 zymhMFe=cR{4_!s1bT%{Pvu^~LFXYs6Gn)ywP3&8*WoF+S-+x1Yy{)6Pj;!@PaAX$^ zTCli>-dje3ONq4exA`)o)!@%DsI&{wW2>%GA}@b|YFB(K#3K%|=cXmAuS{6Q^JPQlA7qtiI#?8z_cm zvYjX&<3defsQeX;e`i?ee4MlC11>7v?0mtJ9@R)H6ka-?6VO)t1xjvT{7Cu}+PIbGN!c@DeHr2;D}OONS>}pI&P6Da;}W~`2BN1j zadrx}Z{F=FR*5w!OQ{eFVHdo@c&;I)D`1GfHk@CGh+*I_y1ZazjBlS|7VTe1(jjr( zEv_~~!t*GKqZU17JD+@*Gb7`eR(R20tk`k;gq*r{n1g%S@0=uvO;Pan7q84eD9wDp^i`RS`kZSL#)Ew^3}gA)$k5ONZbU`dP_Rt9vuPj~MnykEDg; z>-I9x*kLwGk zRCUKzqRU!keiUu429MFlSy^&S%QA0Lr78MpD|y0IpFbz)sVgADpOh|E*@Y~MS$xTK zc;()sz&nF=Eis{ZsRJA14Tl8xR#JcdiMTx7Bj=%#Gky7`)Z`x&RYqYoKF>9q#`|2t z9m6l~PNB~sj;cvLnNstN0H6XMfki>)I#}G*g$jy`swMOPjWNfcv z#-K_C)Z?=$B!4h(r?z;(p3eU3Y{u;FmKj}ZvF5qQ$D09y#zvTr9xj6QSDxhUczrvU z7`RNw=fI&sT|F9KbkcXddfn;6uEx&Cmjq1|#V)?^bQrk}pgR916Cy_T;k~6zCxx4` zHJQKVJ*$d5Y`Utri53eA*&>(H2*lRZ4>|E@bJJQ;mGWucwI}hpICpIgmn-KIvAhlKga# zn%--3NHG3_EmqM7@HYJZG~}DxscaD;;?*X^_kQZAhvNevQvP#h0WyDv( zp&)UXjMmybE4V8C&#k=QfELJj{2=%aV;cdl%Lh_k<2!x0ReS&26g<0$K&G;db7w|F z;g(RBL6Y@{3uqxX^YUdr<#b)3rhzu*8)jJ8djW{vM*Z{I1OJFPg=4A#77`(uUvZsZ zJgi)`--{&kI%W-4(?e~#6v0v1ZBI+RLon>R8C8vshblIR^qLQ4i|?kebKaxYBQOWH zdAzgZ+YEIH)oAarWgfiKUA(3S;y5K{JcIL?5J+!As69&Wsjrq}tGkP7rxRYp6-CB# zGX6MJ?5{;4DjeF+tE@UjXqpUw;zzDvvu}t*Xkc?WEMC2{XvD5JgcRl_4Lw~GM}~^A zDh7U$NYTcHiuK?eS7?AarS835>lbj(7_B+fR|fhzw&8ix`+Ml@abOR-WBuPh4tVgh zF^Pp%wpBq1KG%O8vvn8&2SIG(#yc!X;k7(8kuN@@6OeuH-*)TX7J#w`P@uw+#;#&f!h2kC z03N;tRLzi97F+a{yK^!qLr>=78`_X6qocWktQr;TY@V-EZqMa!3 zreOtzg){)evm@tz&j?rZ8N39PWuUYf z2%x_0{oX=^LBUVD{*=LDCwEuL<0=^37yMhEC3T7YU73lX0I9CApYfMmv@nkmZH|7Z7~fR| z3=oJ-5q{Qxugz4sPM}2I;*L^YOd`0p$&9K8{?1-DUy6o^yu2?CtP0gpAvF#VcnNRM zR-xZMoqg*uZT(uXS+XE3in{DrA7;9S_5rH4;BA-zJ?(dQ4MePR-GDUAY(i5#okzSk zQ?^uI;IiX_sfYez@{S(tsuwuXsT>{&3I}&wK;|2lfJF>a88lY=HAF1emKC!1<3y%l zbm(?b`h;G9$WJzGM*z`=onY11A?~4!t(_(H+(sfjDr+*0h#D-{!q9#rub~Zqq50yJlpOf0dFF|lm9+m^Uf^9~Ykx!ew zBm>_<_!Am(3WDAeon~cS`;(+f8X8FCex?Bvmw(8-kt59zQyyHS(F<)maJ&?tVj`vx z{7l5XT;VVQfP}6Aw(A8+j_Dd55+x|83RCKR2M!eH zNpa9;NNc>BPO#tzjD)}fx(lTWeqkI!Sr(|@q!=cy<3X>AI>w>EevTaU?@AE{jt9f4 zMR&^6$+O^DfL)qUO^si($_86R08tMP*vCMbon%j+Ed8Knzy&4>pgMO|!*En@?x^pF zp8ghGe3v5u_7>hkZd!{MOjpU5Od&px-;Q&np;PF|jll{Kmuqyy!svx|6`Z2^cNM@P z(+j7Kd_RxTuF8MOmGBifxC?TDP=e>~+a70TKZPVzCMxjH4YfCNuf29Je+W_SLrN8| zPg?lXo-E>IKNJTW5#9xz-TA94yuxF<1qX?BA42L{&TorI{J)9ZQMy6L{C@c+EHofI z(E8$*_0_57DCqE`0^Z^z=;kM7GGbKiHZ6~H*E2?`~C$D*30w) zZly#3JwEno2YZ6h{mt=Jv-xFgmk}yN(;l_Ng)tR~93;rK3J%?82Gbg-VtI5!1qtFv zl)FzUz6@CLwpK-))<5@oGvN?X)vJb^F5r`p7Cve)vTw4n2`? zGGTVMu3WfH;i}z*Og6p`&*=@c*%zab?*&S`MBt#SFNVv}r*uS!quG3j}N=u6^9{9h;q3n zCM9JdMyDjhu?P(%l+-8UyeQ2%GRz}h})hC zSFneqU8Y!=34y^Z1O}(mEmE%xa6)!!?VPuBL|q|h50;0zWJ`I7`{M>zJWUVOe42Ja zgcb(;jwrJB?lj7{DCI2!Q4ie6Ub}3LSk5B3#voB3$0AxxTD%v3fPQfJx!zlZ+R5CI zg0-nbk)_f19-W$W{*|G#9WGjE%yK*ZGJ0BTcUEF(Wt*}kF82BuqN=BK!~T0GDxoeS z?)NC4eQTVgzEyvN`xH(!(sN;3oiC&BBnZ?d^Z!w3urzF7G0gWWUnr)Yx14YOJAIPx ze!{EoYWSXp}M?rxBlZWNI2?k=T6mXdCy zyOr(~mhO_2Tm%IK1f)UWxxYU=f5FU|nQP|#I@g>715}OLgg#Rm5Xoz(mQ(l2jqW6Q zY$7jEEq*^}*uZnoDe?PB+XD?c@X@6ss7Al`lf_7{8@yV1r9)_on>3>Y2IBA?f^{C- zXFbX!7$Zq|0ONLf8BXVzWnT_*{V{=2cZnLvDv8u@CfuBHU z9U2uK0ospQkF*a#kO2WtGE!Ul?!SjlVMMtuIA*dX(TPf7hpL2+I0g%s>kQTgh6qKE z)>E`XNz1G@W*3@w{9??LPJ4gFB7sB)x)WUCE;`ickRc++;!}R1Gy|*_3U$ezTGRd9Ll5`lJW-WD%4+j)9z$1fG9< z9jC65_`ZYXrK>X~+u^32qoS}WfoWFUg-_Hzh8TLW)58xfF|8&;DVU{2A;aU3lFeT) zIBesVVk#Vei_b8FK&&)hjG`{m@{iZ7b`5>I8VpJTzZe;9f+unkz(v9n&iKIVI$a$# z2~O9khd%F{VmC`#G-rq7pIgqzB#Y19zaoIc?Wlj4!rwn!0zco#p_aTzYDPqVks=BG zY<-aprY#TkQ!X!Q%XPAuidgRb3A0_zJE`xlj1^hZ`COyw*=;(XaK>jW?v}&4VjytK z1l9a;KuLo9DnY^e|GNMz{62>Y_B03-L7-|K*905-=uVBCk-`X-97?d_O-< zsjK!ViIj<#Wj$jm{WI@L4OEav_3rieGC6Pmrocx74Hp_87gFmwCLwknTVff zZ7gR`K%ct9$F-(zWh?9EzCtUz3#vP~j*RAMiX6}D1&kd{hQU0Yi_MMRE6dnjjPupt z`GUW7bS4|>cD$I6HlkI< z0yo->U0+)eUx`D*FiPUZ*AJqx)YX`6xcIrp%|kAx>w=m|7og{CI}D#v2`D6O96KGU z9xS}-`Krq>r!CjE3nLCDTXZ^=gfW_O?wVACok0VpUFebWpD)WvvrV#Ax=Ca1lbjEU z#P)5J<5ZtgmDnAr$I4zYc(us7Z$wauJFpdJ3JIecBs#^KA!TI1D17Bb*Ao}PotP+G!w?O_|H9)LG z$+jmVDszFPg5@}j_y<;6Ag=e!RlvzpO?QffZmqa@fm$5PrB1sz3ITstV}Y`h_U>Pj zB4Bl__`92M-&Tzxu`D2>y;M=hVy<1%*0>2CzfJz)xPP`ck4j)i&%8TBdjF)c;9V!I zn<`K@SRsik90x{-eOa5kO7k;#lfND$3#hI)dU?BZy@jI=x*z-&VmtoOZGMuJq_eiH z<2Td({;Q_g6mLLS=9FE9GfU%$=mS_|xFO#vU@uypYA?0zmp58L9Avaqd$N5*d9mc@ z{WS@!4HHghmb*-u9{1Hz{N! z^)491+<-KmKw02tfk=~Pb`gW1#w;Yh?-?1rN7JPDf*G%WmCkAizS$a(g}>$Jz*8>a zTWZPWUy;_L9pc@v@EN}zm~A+vZ<@^gRNY5PM9Ps{gBL9{RkhJ?6or=C_ddj9Z9wr? zp=75-g-Zs2*fYR7S}K&FrdrnJ;loZW-?y=7OjIVu5*JH>qNar|{+hQb(+q9ofReA| zB@%1vAkUt9`IoKAVq+BBwvXx<@SwyR5$XrE^d-Q?DUVdvaf$4tYmn##mGw6{3Dv*2 zb@zF#6NcGvTHsHdN`m8tAi?1pW>0ggk~inE-IdZO-M&|TCvE%BHrD<-j=vZ+%k9>Q z+o^m4(k0R=OPNd0!uot&O9of&kYneq$a18N zKMHGIG^A#h*r}637=fph=u>_sVZs?RjU5Pjt-Ubn>%){OevnOK7v%GM+YdutIPa@C zmAWQfbTYw!*^f$DljB97h!+|V?0)Y>QA*Va7tWI#SsF$}@k7s^;zh%O;51##T6EX` zZ-0MFZ6f%aCcQ}p!>qX@IW&HU$*Wn{PrOMU5Wb|J_-QVMY>*1ZknHiManZ4-#Yscq z=t@)mNB5?6-;zr?zyteYxJzQ;g)gV!3_Hwod^~F;%sN%n@8mxd3x-quY@B|i;COVP zI1B3KSZ{`rL*8U5jzYe2iW3@BEi#}xzhWT^q=)f@orwRZ3J4Hii%``k2(v( z&Y*+WB>mM--N5|G`?UUFo3)GNs2}Q2!>DXNkC*5m4FG!BNxwsnbJzf(&%D-B=MyE? zRu32i{qS%Wto@x9bdZHCe`rhbqjUUZC@GY$EM+C;kjtyx2r!!1d>OF0RHB?^WA``_ z3(bA>OJKx&uh=+GNaV+{2kLpv2{XVvqp3IhdOhC}`zvfqiiF{D^h(VAXD@)31I-?= zDhjZgEnAC#jq_ieW8nyn{_*a_ep+FYe8Qrohr%he)F3TPQGf@J->JVWaO{7G#5_14 zf(rDsyPMlVf$#GI3E{x1zT`*F?6*qg#gktwqH|`uh4c}Q#rdhd%OXhraJ!e`SyO$c|!t}q-Xzpx}V$*OA1|JC&%!5rZo0P zD({>aHd2zJA}Fw69(#dy!6I5Q1+n(-zfe%BDSi6`d1c%KI;`}X;ItJa5n$v#A<*c~ zfQo3n{UVW)#h^UjUoT}BeK}y@(Vy3iznOlV;_zd>nKqKgtRc=zCBL=Rx=u!P1Fi-)Lzn>sLkAR2n+5OdMd~2{LJ1;fLTL0|h5F6lD|7WMJ z>EZbNmz`opq5OZ`CkNaXzVL;Nubf0e8lVHoRK?c$<2pbVz zvLyMNEvn6T1HHh!7v7h(rzOlYbJNnnm&Tp1eRYm8u?E2?;#$n87OdL#8=&?a3bQuP z+M@WtYYR9-Bx{82^;d(r=`LeDC7NDK(zfq01tcKQfdL3AeKRgYy$h+Yjg(M9$!(>k z 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

THELvMsO`-sc*vgnIbl& z(Rc-)={xg&;plZQmbi+rIJ| zP1Pw}K~a1$8SxlLGEV`2}X)5%@ zy8^b=asA91!2x0EwVTdl%;k$Hdtsh!qt}*11$5d7HM-g_6Q0!FEtyk(EEE9?LCfN6 z+r)=%NvB$g!>8?hCG5U8XwNlvR=ezHwDAL`%E-H2rQU5$4Cv418i@}8pDmyMfhM^E z0|1X_lxEWWtC4f$PmTVAR*uN>xRhXEeoP}8nV$g# zh8qI~)%H&0Np&WJ{rFI?rsQ2L%<`PP59JUzt!ejEgd9V61~q%z$#)}TiLGSG6R97b zwzI_n8)u|b@Co<7Wo5ERzVxtp7MFQuQXXp#J{vv=sKg;~`XcuLVe8_RMXvZUHU_!V zr=q7{nfc)BeB3ONeA6pg&wx!h_^2{HK;!dEdKP-u-E*2ahqkZWL9?3f@}_{s?)-al+LZg@N{;ML5cE!Cq; z+a|$HP|4Z|fZKUzhB`g9YXc{!Fq!Cs!Hm0`l54l=1{#HlWPcDf-FeDUuj3}sr?DbZ z7!+3IwD@L@YGqIU3EQ!*^XbS@P`<(AhaVt1OO=f|YHVp#I(l_B*%nI7CEbf>UgD-13T(;ne~2nNPn9-qdqF);tn}%#i6evXy%w?D?Pt)!Uw#d2iymS< znL)PUehW1NZ7y{;5%l$tvveLf+I+k*o^sdI!Lp9{P^@AF!?z=Gcuz}ZBV7hRX6l`e ztIhU|Vn}M|!qHy2`(JFId!&vGX+TzTv^>$FCtY~C-?w0$7dhkyIF?wc&QBXxIcAy1 z-PD@*=JpT^BNa-@O5X?SC5?Wg;S3|w>j_UD8+!-6yG+c+)p_hXJG4#iZ8l9J?5inO zV0_**%wMS%h(i`dqsZe?O;=cbWPs-^|5=SY;t_E{EN$_30D=yitQ@~2H)FO*)3N*+dv-^W(K9iv z$hVz!@E6`UMfc17B&7ZhZ-&jlC~~n+Ug=A~l~c?q9uyt=>bld3{aUL2_Rtxxl<0ZG zx4<#8pdL&dSk$V@u3v%ZOxIPV80n$%@GZOq0Vmj!)!$K7`{IR}%Ca zw&Z!7YqS7HbN6c_bdwE(@lToIZhS(3+K!Mm{3y3)S}!L`b%9N#o(U>9#VWrnx|mGO zHR*m3Z{b%RD$u~KFlQzCxa`AgKc$Z)aSbYK4sSVe>>H2Rz}><{2|fq*k2Z1qu7mR3 z?19ZGE&+-WylEN|YKE7n6y;=*j;0b*5=h2m+`SWGk5t9(vOdOW{ufMa06ay8A=-Xn(g|<^6Xm8QNie$OXc}g(G2O>@ylLY-C7!W2V zOja*ZBvwqIfy-OIQFIS>L)|X_vBHUohLuX9i>7caVIlG``D@3{bP$#`VaI(m^a1b* z`V~d_yDH@~@|#_3@fhE6D-A$3|8$R#Q|}pgi6^>UsX-}M{d+`K&&(~{WjiGr%2Gc{ ztpyVOAgT0cB{~)hG?8th?3J-HjQ0pq-^V8W`Oy6hH=M${C8B~`2=qLIiKPli3lmm2hzEM096an?2Mu#C-tzW%&T;@WGy12+qSL8$934efqI0a7 zbC8Jsv?-5O9U1Nr({$c8cfqvN1uL6=DfHf7f|ddP z4*)Q-?L?6*r$Eq|P#-HoJdCAuMfRhN%BQa89K;YNy{xx`)^cm33g)EAla9pOsKBx@3~e|O zg8nZn7WQF!d8mf{jsnvq4^H9XN1Iwj2$)v%@tjt%8%~Z@J$R|pwFK81 zpUv_mH++-%*WsS|hmb!jU8YBTVnIQf%cfgtJt{If&C|4?;_23`m6=1MuO zeYqP+q{lV$P}L7gAmUlWeeW>=jDUN7fHVQ|(JPyp%q)w4=YBbQ3Pf1OQVe6cTxv7~ zaqo*FrLkN%{!NaRSrM_SHD+$|Ngkc^5i>jYk0R0^-ZFo9Z?(a)3trIaVdRGoME2W! z_xapxlT-R-z*o!8AD{MAa~XmaG(P3tdX=|qMB=4M z{KuaglGYa!cu0c}T-gO7X3}jaFn;{B4#$Wa!h{Al;;4tu;8@al0nCJbK|!LtwJs~b zR2v%!=F4Lg9~>h9vh(tPb58sX(gL zZZG!L^R5S_Lj7TFA>vTci+dtFn-77*YbHP#)8>Id zw}OCg5Q@}0BgSu;n7koP;PWkB#UWL&Koz{e5B;l^z)vf`3w5cA@MYM$Q(0=VPKUz0 z)q5hoAAU7u>DF~2iYrz&XZ!SyjQve7;=y$G=gyCkW2;&WlVZzRpV`7jv603!zhswB zOq0>>24y_UG)XpfYA>%Njex1@+NDQ#G<1JQ;knn-8mIsz9XPh7gci^I%i;4>XRg6ELfb zME8%E1%!W9OEhPvvl@hc2~dN`RS3}BgYnU_Eww9;zi2Da+3UgJW5<3sy4@$m%DU%p zl4^&WE#R@ug_$mMaFIEi8R=6B5#q==z6JWN^YUo*zsXR(nN@+Z^a4{7!w`eqouN4@ zp0L`FyoPidjef@_7h98U>jvubh)rI?qBBycPih;R;rkV78aGY>Eo-oPOgueeM|J4Bv0eHO01PQwc(1U z3iYkz?{u`?b^f!B%)s-cV>QDpsmgtGh-J~JN%P6`x0E1?{ytgH9}@fuPu<3Il?x+* zM=k_%lo8eA$NwnuwjUS5p<2ciFh0z22*XsHLt153YhF*1ot-Uzwq*w-3mtr}cs48f zy7`FTj~u^Pj1$Jnk5Vyh_c{2S%he@A+AfQpKO6W%#+W1S>^L{gY!8!|5EBvq~Bo)Hk(CBJkoRRe{!e7ksFYlBrPZ!|x_J zCXHGbBz=0kt_(CvCVHI~s_!UM7@hT{0P{xorcE4bIq}bcFumu+pVX&ptk~nuTyo?3(%ae+cM8|<`B4oZm>9cV>e2LN@0@w9D0q1x$Ca($RT8rUdR`f~ z@ys%BWEVV1L6zb|v6X4_nam%Ey}!tW;t$nuHk#%Vo4fx!oLO~H`P5YRtm6&RtbxIB z#J=ldyD!+{k@4(=XRU4!t5S)9)M2Spk4l%LPc@o z)m1)!`fv`W*50IZ)>}Z0EFBwe;HQhVfeG&`m4Ei;JlOEy`g3ag5J%nm>(T# zXK!z{aq)Z@cQS3j(O}eRsx2q#$I!zn=T3LejPJ@$q}Hb~ih&_Ev4ttUI|P*rq-|M! zHm@vNntPe~b`@%*`q=JYP6jTX9;%$iX>YL>Ku3Z;%$H;dj9r&Lx;R~8yL%o1P%avS z<7~^J?!gs3tK&`M`z^-1@grQThxXO5?hLtTAH4*Q7KIb&+tC_i$!l3;4Q-j`bQPTM0o%laj zalGin-s)vI94fzV)_fFY#r5K)6@&xPN7)50)@t#xpnprFVY>l0Lp@n+oA@y4L~%U4 zvIKc=RVjQo(`am!tKw;)3ijMd2e22F96twq&GSOqd+ezWlO@0W<*LipnyRTJC~n1n z)XsahG4NS%X=mIk-_;)%jz5J*rY0x#Qmk3BN#z;_PNPZg+`(`+OJSTWzLq|bLV&OQ zb-Y++%YJXYrY%(!`+N<`Gk!0xp{bhN_%}b9Bpb(#82?&_PAl*W%65@DT47VJT$AI+?^QYAyPMUe;(wS(SNl@sd^}hFY)5gu^uvb z^39jIX=*Es1Esr~`V}8bE@y+vO`F;5(@bE-t)3$&z?~5#fJo{miQar zcEwG=M0hI$600eztEU9eVdP{TWioq`-Vt^vS6V?@Gyho*0b&;<*b;ED=U=YF2}+3l z?>;k_cPpeHkT|-a=?I8>I$}S0D5(>&_3|8#ihp5+6^)tA{mDhRCd9lR-bnXx<@kc1 z3XHosx-SXlLWXGI*l)JNzzoJWt22v0?`i0pmHaHKX96!WkHo#tc8Pz#9z}uqsr%4) zvrhSwJfFwn8ua~bX#0FP1?(iA4C4C!O7wjf-QW`$TAoT&%c$HdcPiLB;`O=1(KGa) z{L$F)GcvPI1P=Wb&dn`=*JO0UNAIzX_3KDtoY($w5^vVLN#VrNQaye@iqhy4r63&) ze`}|9D+j*(t1i=ho_MWvX&Vtq5J-h5V5EZasHgL8@}hb_Aibs$rX`eB|n z7x!INKz>c#L^ zg)ZEA+)$-BJCv5g@)t-lDA>P^!NZag!#d=wOBI&>=q}ff z&{OBoN}f3?vtLlxOLqnyl){sQevO3Yw^*vcbDlKk*9~xfw4=`QQV@+bl&RFP_6}IX z7j2IW5y>DWMZ=f4K^a8#Cl=xQm5ZlxbIe|v8{M9PhbD;^lwk(no1-8BSL}u~h1Q~Y zLSY0NeOXgmMExgrN^>6_I)9X3A}1R09wZ2fD~#n@4teJcC-9R%L>~ynFh605e{Sl? zC-1l;J};r_W>h&fgCW3n{xw=Y7TmIqMkUS)dHfUMJ;vbRmcpSo3aXB~dg>$;YT>XMD)t@;y%c|(9jfHI2VA`!fA)lI?C-#u=x@!$n_ zTp^3k48&dAHgP1W!l=pO(hGTwy$JQSfKKfs(b6H02MYXyxv`9Oc7?TpPmr9Y`*NS=3Mk&!&zv8 zn17kuvgY1PS0nK%Gxgqp$Ym($VW5mDpjar1Tj7T$o$@2GjJ>Zk7{4cV6QwX}w%YTC zBT6%I8P*}GcYyp)J*|r}pGZn^c+p74e+Vqf2g_ao~_WedvHB` z`QLdsMyx@XLwhH47a6~DdL}kLyJ1;!;dLaM#PlL^L)L4Dc({?2PMZX10_ed7CmDP8 z)fUerG*elNxKcmir6GXRO1{~o^aTLo@xNJs54~pkKVY&vZG=TiCIP%L&;2X8n4K|A zdBX@WSKbe6l14-j0W`RX6P2!B^Ly3^eJ)?W>Dog9ADxD#y(3}QdC40k-8@n_Xi;Du zCtZ%~X2+!pzK9ZFjxjIX^K~2ej$)0vzt1utlzA-1d9ake2|LY_cGj5npcB$sFYA*i z)MIf%MMtYUg6TzN!^JEzW5Ohjl^zWzG0xctoZ{2c5PolIs4)+J@R7ZT;H`hzB3g(= zi9aL5{8G5F}~ch%)VDG)`Qt1q_naT5lxE1Me=?o3?~Bl<`1kY8SWlXQeH9W z6}oTJa|!bb$-PC;xSBBcPMPjY%zlEut$m2UcVJ}2%$Ywa`CSgTQ4!s(H1zgV zdBNrd8NOIetk6={m%g@eNwYtT#?7+=2EkN@-u2RM<^nU=s CC(Kp= literal 0 HcwPel00001 diff --git a/scalos/Installer/GFX/Pointericons.iff b/scalos/Installer/GFX/Pointericons.iff new file mode 100644 index 0000000000000000000000000000000000000000..37af181d7d65deefc458cfc4e8aaf8da8bdcfeae GIT binary patch literal 10170 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®_x{Cj6sD)}hl-cG~KOFyWHp~1+O-z@W; zdg7Z!^9!ZE^Su(x?9xnC*n_TfbSm^F!aB&pLO+w@vC&cF|6LR=3e&|~KA(pq|9&#EOx$N?zgI|LnV510pQA4Rk*IY#1g8d#sB`5P+0aFiJq zBZe0HY{fvtHOBoUait63%YIDfz}Gu55M>6$h@r(?0)1KM?5lM1oMF((myg9gSL!( zCOM)5VL?!sCvKGrV#Ls573n8NV|e>*l5{QOIOy{eWG2eY>siNBcd$McLxa&TXpYBm z)mKE%X+Q&uJvTPF;@?U8HGd$**zUo ze4KeBw>KDApNgTynhtqxVc_U5N#+D=92m3eD09K?UbE!U-k?~jMT{6)?9z#Fuqv=~ zJsF>&H`pMRo;^eJcbBNl3B7-t%KMZJE#_L?UGH=Mft78_QXa0>z z@y66?V#Ls5pU(B3F8ZW0g*;W9{lFW~+2^v+?s`*ZDyA4QwAcs9DOD+}WntIU*J#M? zHfr4ccAQ_bS5|R{C%|%Nx2^a6;@|fs%95=)q1D!_`-uFizRkN_)@KdbW%ZETBfZV@ zVyXDl87|5?VKnpx9>*P=#0*h+M9NHs9eqGnVQt5cBssHq|BcExj>v!264{$=854Me zORjV$1ye$|b7)&J=F-e6Szpzej5c|kfyf*J${YfbIWT2pU*PYH4{hS2YGYje0`e*3 zD}ChiKJt}5_>)|iI{d2*5?4^u#(*xVoy(@IHJ4B2ziR3Khhlo_Jw-9Sr_}gAoNZ36 zePn1z5lS!0LTNXxH-+CgTfAs27e^DJBHPq$>w^#6*ysz`nI@`B1Y<>Zx2=7Z<--&I zn!$9?oV07YIz#uZg|S!mZ~B;PpZ&pR?0%M2qy7UPZkW&X&Vg7Dn`!o;cjI(*i{hp% z2m915O2$a%Vs(1X}n%k)lq|Buhv++*gK z?)ezZ;Cg2n7*24#Glb1i=D@$futzsz4-r<=pI&sdAJHHIBKLUj;S z`?W|xxnD~c?ToVHWVWS?;hk+)>fk8XK+7zc#Wm34Iz=2P7GAd?`x=Uc6(;th1-qTI z%RQ~&WfI&xzYgqN2&MFjVQF&bmPqHSIAM~th1hgOo9N;IIUev}mzPVUu|VMZW|=QU zUK-=_sk83r;E6JI`6m?DTD7*mVs#lmq$bBRprqxu!OlhO0RSn{8o$kbRIN~;?ig=Tu4h7Ig=hgYH7dO zO24#N!`a?ws9BKfqBHSvJ=aBJp=L#TT?}PQ68(B9+bKZ|YbmkMma&B>o0;Td>&M}* zmvB+EEarRPk&GCjsw;-E=_ybj2DK z+D)1f(R4(wSYpJ`U_`R-EgLG!nhB3wTwqM&RY63R8C03UD3h7w&2it+C(|<OUwl%31tJ=6!nFF>| zE>$iJK73YTP8u+53ujImFnf!_RIrcXOjp&zXUfUsi`hxGVj!w{&-Kgjh-w3(Pb2>}UptWPFGB3>87h@rulH2LE(2bU%XfB_QtF`z4QMCekE z2wjmQ0=1YTnUbX_lK0=s6-jyP+ph!)HTS7TjRs?)ZIuZ HN(BE26`CSQ literal 0 HcwPel00001 diff --git a/scalos/Installer/GFX/SVGA.png b/scalos/Installer/GFX/SVGA.png new file mode 100644 index 0000000000000000000000000000000000000000..51a1b0be8e4208250f0a56eef55b88ce03dc124f GIT binary patch literal 122872 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

0o^h6V|2Wr1UdFteAJ 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®XPAH$aA=hB+8llR)hCI= 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 Ty`)qD!2YDg<;BWG4E+8-F3*5Q literal 0 HcwPel00001 diff --git a/scalos/Installer/GFX/def_Iconify.iff b/scalos/Installer/GFX/def_Iconify.iff new file mode 100755 index 0000000000000000000000000000000000000000..57a4530c4de16cd96de158fc086f1accf4688957 GIT binary patch literal 6754 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 literal 0 HcwPel00001 diff --git a/scalos/Installer/Install3.5_ScalosBeta b/scalos/Installer/Install3.5_ScalosBeta new file mode 100755 index 000000000..342c951ae --- /dev/null +++ b/scalos/Installer/Install3.5_ScalosBeta @@ -0,0 +1,3106 @@ +; // $Date: 2008-01-19 19:30:12 +0200 (Sa, 19 Jan 2008) $ +; // $Revision: 2765 $ +; +; $VER: Scalos Beta Installation Script 4.3 (06.04.2010) (c)2005-2010 THE SALOS TEAM +; Scalos Beta Installation Script written by: +; Name : Jean-Marie COAT +; Name : Jürgen Lachmann +; +; @user-level: 0 novice, 1 average et 2 expert +; + + +(set #installer-version (/ @installer-version 65536)) + +;----------------------------- +(set #Smdmatrix ("SVGA.png")) +(set #Hmdmatrix ("MVGA.png")) +(set #Lmdmatrix ("VGA.png")) +(set #Deficonify ("def_iconify.iff")) +(set #PointerIcons ("PointerIcons.iff")) +(set #StatusBar ("StatusBar.iff")) + +(set #licencetext 'History') + +(if (>= #installer-version 44) + ( + (effect "center" "radial" $000000 $039A00) ;$000000 + + (set #w (querydisplay "screen" "width")) + (set #h (querydisplay "screen" "height")) + (set #d (querydisplay "screen" "depth")) + (set #c (querydisplay "screen" "colors")) + ) +) + +;===================================================== + +(set @language (getenv "Language" )) + + +(set @applicationdate (cat "(06.04.2010)" )) + +(set #scalosresident 0) +(set #scalosresident (getversion "scalos.library" (resident))) +(set #scalosresidentVer (/ #scalosresident 65536)) +(set #scalosresidentRev (- #scalosresident (* #scalosresidentVer 65536) )) + +(set #tranceversion 0) +(set #tranceversion (/ (getversion "trance.library" (resident)) 65536)) +(set #newlibversion 0) +(set #newlibversion (/ (getversion "newlib.library" (resident)) 65536)) + +(set #wbversion 0) +(set #MOS 0) +(set #OS4 0) +(if (> #tranceversion 40) + ( + (set #MOS 1) + (set #wbversion 50) + (set cpuadd-1 ".060") + ) + ( + (set #MOS 0) + (if (>= #newlibversion 52) + (set #OS4 1) + (set #OS4 0) + ) + (set #wbversion (/ (getversion "Libs:version.library") 65536)) + ) +) + +(set #scaversion (getversion "scalos" )) +(set #scaver (/ #scaversion 65536) ) +(set #scarev (- #scaversion (* #scaver 65536) )) + +;(message "trance.library version " #tranceversion) +;(message "newlib.library version " #newlibversion) +;(message "wb version " #wbversion) + +(set #cat-app-name + (cat + "Scalos Beta "#scaver"."#scarev"" + ) +) +(set @app-name #cat-app-name) + +(set foundthemes 0) + +;===================== VERSION ICONOBJECT DATATYPES ================================= +;= PNG = +(set #dtversionpng (getversion "Scalos:Icondatatypes/datatypes/pngiconobject.datatype" )) +(set #dtverpng (/ #dtversionpng 65536) ) +(set #dtrevpng (- #dtversionpng (* #dtverpng 65536) )) + +;============================== AMIGAICONOBJ35 ====================================== + +(set #dtversion_aiconobj35 (getversion "Scalos:Icondatatypes/datatypes/amigaiconobj35.datatype" )) +(set #dtver_aiconobj35 (/ #dtversion_aiconobj35 65536) ) +(set #dtrev_aiconobj35 (- #dtversion_aiconobj35 (* #dtver_aiconobj35 65536) )) + +;============================= AMIGAICONOBJECT ====================================== + +(set #dtversion_aiconobject (getversion "Scalos:Icondatatypes/datatypes/amigaiconobject.datatype" )) +(set #dtver_aiconobject (/ #dtversion_aiconobject 65536) ) +(set #dtrev_aiconobject (- #dtversion_aiconobject (* #dtver_aiconobject 65536) )) + +;=============================== ICONOBJECT ========================================= + +(set #dtversion_iconobject (getversion "Scalos:Icondatatypes/datatypes/iconobject.datatype" )) +(set #dtver_iconobject (/ #dtversion_iconobject 65536) ) +(set #dtrev_iconobject (- #dtversion_iconobject (* #dtver_iconobject 65536) )) + +;============================== NEWICONOBJECT ======================================= + +(if (= #OS4 0) + ( + (set #dtversion_niconobject (getversion "Scalos:Icondatatypes/datatypes/newiconobject.datatype" )) + (set #dtver_niconobject (/ #dtversion_niconobject 65536) ) + (set #dtrev_niconobject (- #dtversion_niconobject (* #dtver_niconobject 65536) )) + ) +) + +;============================== GLOWICONOBJECT ======================================= + +(set #dtversion_glowiconobject (getversion "Scalos:Icondatatypes/datatypes/glowiconobject.datatype" )) +(set #dtver_glowiconobject (/ #dtversion_glowiconobject 65536) ) +(set #dtrev_glowiconobject (- #dtversion_glowiconobject (* #dtver_glowiconobject 65536) )) + + +;=========================== DIRECTORY Classes ====================================== + +(set #defclasses "Scalos:Icondatatypes/Datatypes") + +;==================================================================================== + +(set #catctrl + (cat + "Installing useful tools ?\n" + ) +) + +(set #install-exit2 + (cat + "\nThank you for installing Scalos\n" + "and have fun with it!" + ) +) + +(set #makedir-scalos "Creating Scalos-Destination...") + +(set #makedir-Prefs-scalos "Creating Prefs-Destination...") + +(set #CatMOsLibs (cat "Installing MorphOS library:\n")) +(set #CatOsLibs (cat "Installing library:\n")) + +;------------------------------------------------------------ +;--- CHECK BEST IMAGE SIZE -------------------------------- +;------------------------------------------------------------ + +(if (>= #installer-version 44) + ( + (set #hires 0) + + (if (> #c 32) + ( + (if (> #h 590) + ( + (set #hires 2) + ) + ( + (set #hires 1) + ) + ) + (if (> #h 800) + ( + (set #hires 3) + ) + ) + ) + ) + + (if (<= #c 32) + ( + (if (> #h 590) + ( + (set #hires 2) + ) + ( + (set #hires 1) + ) + ) + ) + ) + + + (if #hires + ( + (if (= #hires 1) + ( + (set #mdmatrix #Lmdmatrix) + ) + ) + (if (= #hires 2) + ( + (set #mdmatrix #Hmdmatrix) + ) + ) + (if (= #hires 3) + ( + (set #mdmatrix #Smdmatrix) + ) + ) + (showmedia "mdmatrix" (tackon "GFX" #mdmatrix) 'center' 'none' 0) + ) + ) + ) +) +;---------------------------------------------------------------------------- +;== PROCEDURE ASKABOUTCPU ================================================= +;---------------------------------------------------------------------------- + +(procedure askaboutcpu + + (set cpu (database "cpu")) + (if (= cpu 68020) + (set cpuadd-1 ".020") + ) + (if (= cpu 68030) + (set cpuadd-1 ".020") + ) + (if (= cpu 68040) + (set cpuadd-1 ".040") + ) + (if (= cpu 68060) + (set cpuadd-1 ".060") + ) +) + +;---------------------------------------------------------------------------- +;== PROCEDURE CLOSEMEDIA ================================================= +;---------------------------------------------------------------------------- + +(procedure P_closemedia #media + (if (>= #installer-version 44) + (closemedia #media) + ) +) + +;---------------------------------------------------------------------------- +;== PROCEDURE REBOOT ===================================================== +;---------------------------------------------------------------------------- + +(procedure P_EndInstall #boot + (if #boot + ( + (message #install-exit2) + (P_closemedia mdmatrix) + (if (= #OS4 0) + (reboot) + ;else + (run C:reboot) + ) + ) + ( + (P_closemedia mdmatrix) + (exit #install-exit2) ; (quiet)) + ) + ) +) + +;---------------------------------------------------------------------------- +;== PROCEDURE REPLACE ===================================================== +;---------------------------------------------------------------------------- + +(procedure P_Replace #nwb #owb + (set #sverwb + (cat + "File to copy:\n" + ""#nwb" replacement.\n" + "Old version will be replaced:\n" + ""#owb".\n" + ) + ) +) + +;---------------------------------------------------------------------------- +;== PROCEDURE SIMPLE COPY ================================================= +;---------------------------------------------------------------------------- + +(procedure P_SimpleCopy #text #src #dest #helptxt + (copyfiles + (prompt #text) + (source #src) + (dest #dest) + (help #helptxt) + (files) + ) +) + +;---------------------------------------------------------------------------- +;== PROCEDURE SIMPLE COPY WITH ICON ======================================= +;---------------------------------------------------------------------------- + +(procedure P_SimpleCopyInfo #text #src #dest #helptxt + (copyfiles + (prompt #text) + (source #src) + (dest #dest) + (help #helptxt) + (files) + (infos) + ) +) + +;---------------------------------------------------------------------------- +;== PROCEDURE SIMPLE AVERAGE / EXPERT ===================================== +;---------------------------------------------------------------------------- + +(procedure P_SimpleCopyAvExp #text #src #dest #helptxt + (copyfiles + (prompt #text) + (source #src) + (dest #dest) + (help #helptxt) + (confirm "average") + (files) + ) +) + +;---------------------------------------------------------------------------- +;== PROCEDURE SIMPLE COPY FOR NOVICE ====================================== +;---------------------------------------------------------------------------- + +(procedure P_SimpleCopyNovice #ntext #nsrc #ndest #nhelptxt + (copyfiles + (prompt #ntext) + (source #nsrc) + (dest #ndest) + (help #nhelptxt) + (confirm 0) + (files) + ) +) + +;---------------------------------------------------------------------------- +;== PROCEDURE P_VERIFYTHEMES ===================================== +;---------------------------------------------------------------------------- + +(procedure P_VerifyThemes + + (set ReplaceWinStatusBar 0) + (set foundstatusbar 0) + + (set #b 0) + (while + (set brush + (select #b + "Themes/default/AboutBackground" + "Themes/default/ScalosAboutLogo" + "Themes/default/FileTransBackground" + "Themes/default/ScalosSplashLogo" + "Themes/default/ScalosLogo" + "Themes/default/SplashBackground" + "Themes/default/ToolTipBackground" + "Themes/default/About/Backfill" + "Themes/default/About/ButtonFlushSelected" + "Themes/default/About/ButtonFlushNormal" + "Themes/default/About/ButtonFlushDisabled" + "Themes/default/About/ButtonInfoSelected" + "Themes/default/About/ButtonInfoNormal" + "Themes/default/About/ButtonInfoDisabled" + "Themes/default/About/ButtonStopSelected" + "Themes/default/About/ButtonStopNormal" + "Themes/default/About/ButtonStopDisabled" + "Themes/default/About/ButtonOkSelected" + "Themes/default/About/ButtonOkNormal" + "Themes/default/About/ButtonOkDisabled" + "Themes/default/About/ButtonRebootSelected" + "Themes/default/About/ButtonRebootNormal" + "Themes/default/About/ButtonRebootDisabled" + "Themes/default/Desktop/Background" + "Themes/default/FileTypes/archiveextract" + "Themes/default/FileTypes/Browse" + "Themes/default/FileTypes/Close" + "Themes/default/FileTypes/CreateThumbnail" + "Themes/default/FileTypes/Delete" + "Themes/default/FileTypes/Edit" + "Themes/default/FileTypes/EditCopy" + "Themes/default/FileTypes/EditCut" + "Themes/default/FileTypes/EditPaste" + "Themes/default/FileTypes/Find" + "Themes/default/FileTypes/Information" + "Themes/default/FileTypes/NewDir" + "Themes/default/FileTypes/Open" + "Themes/default/FileTypes/Properties" + "Themes/default/FileTypes/Rename" + "Themes/default/FileTypes/SizeToFit" + "Themes/default/FileTypes/Update" + "Themes/default/Window/Background" + "Themes/default/Window/SortDescending" + "Themes/default/Window/SortAscending" + "Themes/default/Window/Textbackground" + "Themes/default/Window/def_iconify.info" + "Themes/default/window/ControlBar/Background" + "Themes/default/window/ControlBar/BrowseDisabled" + "Themes/default/window/ControlBar/BrowseNormal" + "Themes/default/window/ControlBar/BrowseSelected" + "Themes/default/window/ControlBar/ButtonAboutDisabled" + "Themes/default/window/ControlBar/ButtonAboutNormal" + "Themes/default/window/ControlBar/ButtonAboutSelected" + "Themes/default/window/ControlBar/ButtonBackDisabled" + "Themes/default/window/ControlBar/ButtonBackNormal" + "Themes/default/window/ControlBar/ButtonBackSelected" + "Themes/default/window/ControlBar/ButtonForwardDisabled" + "Themes/default/window/ControlBar/ButtonForwardNormal" + "Themes/default/window/ControlBar/ButtonForwardSelected" + "Themes/default/window/ControlBar/ButtonInfoDisabled" + "Themes/default/window/ControlBar/ButtonInfoNormal" + "Themes/default/window/ControlBar/ButtonInfoSelected" + "Themes/default/window/ControlBar/ButtonPropertiesDisabled" + "Themes/default/window/ControlBar/ButtonPropertiesNormal" + "Themes/default/window/ControlBar/ButtonPropertiesSelected" + "Themes/default/window/ControlBar/ButtonUpDisabled" + "Themes/default/window/ControlBar/ButtonUpNormal" + "Themes/default/window/ControlBar/ButtonUpSelected" + "Themes/default/window/ControlBar/CycleBackground" + "Themes/default/window/ControlBar/CycleNormal" + "Themes/default/window/ControlBar/CycleSelected" + "Themes/default/window/ControlBar/CyclePopupBackground" + "Themes/default/window/ControlBar/HistoryNormal" + "Themes/default/window/ControlBar/HistorySelected" + "Themes/default/window/ControlBar/HistoryPopupBackground" + "Themes/default/window/ControlBar/ShowModeCycleFrame" + "Themes/default/window/ControlBar/ViewByCycleFrame" + "Themes/default/window/StatusBar/Background" + "Themes/default/window/StatusBar/PadLock" + "Themes/default/window/StatusBar/Reading" + "Themes/default/window/StatusBar/ShowAll" + "Themes/default/window/StatusBar/ThumbnailsAlways" + "Themes/default/window/StatusBar/ThumbnailsAsDefault" + "Themes/default/window/StatusBar/ThumbnailsGenerate" + "Themes/default/window/StatusBar/Typing" + "Themes/default/Menu/DropMenu/Abort" + "Themes/default/Menu/DropMenu/Copy" + "Themes/default/Menu/DropMenu/Move" + "Themes/default/PointerIcons/copying.info" + "Themes/default/PointerIcons/forbidden.info" + "Themes/default/PointerIcons/makelink.info" + "Themes/default/PointerIcons/moving.info" + "Themes/default/Prefs/Modules/delete" + "Themes/default/Prefs/Modules/empty_trashcan" + "Themes/default/Prefs/Modules/execute_command" + "Themes/default/Prefs/Modules/iconproperties" + "Themes/default/Prefs/Modules/information" + "Themes/default/Prefs/Modules/newdrawer" + "Themes/default/Prefs/Modules/reboot" + "Themes/default/Prefs/Modules/rename" + "Themes/default/Prefs/Modules/systeminfo" + "Themes/default/Prefs/Modules/windowproperties" + "Themes/default/Prefs/Pages/about" + "Themes/default/Prefs/Pages/desktop" + "Themes/default/Prefs/Pages/dragndrop" + "Themes/default/Prefs/Pages/filedisplay" + "Themes/default/Prefs/Pages/icons" + "Themes/default/Prefs/Pages/misc" + "Themes/default/Prefs/Pages/modules" + "Themes/default/Prefs/Pages/paths" + "Themes/default/Prefs/Pages/plugins" + "Themes/default/Prefs/Pages/startup" + "Themes/default/Prefs/Pages/truetypefonts" + "Themes/default/Prefs/Pages/windows" + "Themes/default/Icons/Overlay/LeftOut" + "Themes/default/Icons/Overlay/ReadOnly" + "Themes/default/Icons/Overlay/Thumbnail" + "" + ) + ) + ( + (set #Theme-WinStatusBar-Installed (tackon "Scalos:" brush)) + (if (exists #Theme-WinStatusBar-Installed (NOREQ)) + ( + (set ReplaceWinStatusBar 1) + ;(message "Number: " #b "\nBrush: " #Theme-WinStatusBar-Installed) + ) + ) + (set #b (+ #b 1)) + ) + ) + + (if ReplaceWinStatusBar + ( + (set #ask-replace-winstatusbar + (cat + "Installer found themes installed.\n" + "Do you want to replace them?\n" + "A backup copy will be created in 'Sys:Storage/Scalos'\n\n" + "NOTE: If an old backup copy already exists, it will be replaced!" + ) + ) + (set foundstatusbar + (askbool + (prompt #ask-replace-winstatusbar) + (help #help-themes-statusbar) + (default 0) + ) + ) + ) + ) + + (set #b 0) + (while + (set brush + (select #b + "Themes/default/AboutBackground" + "Themes/default/ScalosAboutLogo" + "Themes/default/FileTransBackground" + "Themes/default/ScalosSplashLogo" + "Themes/default/ScalosLogo" + "Themes/default/SplashBackground" + "Themes/default/ToolTipBackground" + "Themes/default/About/Backfill" + "Themes/default/About/ButtonFlushSelected" + "Themes/default/About/ButtonFlushNormal" + "Themes/default/About/ButtonFlushDisabled" + "Themes/default/About/ButtonInfoSelected" + "Themes/default/About/ButtonInfoNormal" + "Themes/default/About/ButtonInfoDisabled" + "Themes/default/About/ButtonStopSelected" + "Themes/default/About/ButtonStopNormal" + "Themes/default/About/ButtonStopDisabled" + "Themes/default/About/ButtonOkSelected" + "Themes/default/About/ButtonOkNormal" + "Themes/default/About/ButtonOkDisabled" + "Themes/default/About/ButtonRebootSelected" + "Themes/default/About/ButtonRebootNormal" + "Themes/default/About/ButtonRebootDisabled" + "Themes/default/Desktop/Background" + "Themes/default/FileTypes/archiveextract" + "Themes/default/FileTypes/Browse" + "Themes/default/FileTypes/Close" + "Themes/default/FileTypes/CreateThumbnail" + "Themes/default/FileTypes/Delete" + "Themes/default/FileTypes/Edit" + "Themes/default/FileTypes/EditCopy" + "Themes/default/FileTypes/EditCut" + "Themes/default/FileTypes/EditPaste" + "Themes/default/FileTypes/Find" + "Themes/default/FileTypes/Information" + "Themes/default/FileTypes/NewDir" + "Themes/default/FileTypes/Open" + "Themes/default/FileTypes/Properties" + "Themes/default/FileTypes/Rename" + "Themes/default/FileTypes/SizeToFit" + "Themes/default/FileTypes/Update" + "Themes/default/Window/Background" + "Themes/default/Window/SortDescending" + "Themes/default/Window/SortAscending" + "Themes/default/Window/Textbackground" + "Themes/default/Window/def_iconify.info" + "Themes/default/window/ControlBar/Background" + "Themes/default/window/ControlBar/BrowseDisabled" + "Themes/default/window/ControlBar/BrowseNormal" + "Themes/default/window/ControlBar/BrowseSelected" + "Themes/default/window/ControlBar/ButtonAboutDisabled" + "Themes/default/window/ControlBar/ButtonAboutNormal" + "Themes/default/window/ControlBar/ButtonAboutSelected" + "Themes/default/window/ControlBar/ButtonBackDisabled" + "Themes/default/window/ControlBar/ButtonBackNormal" + "Themes/default/window/ControlBar/ButtonBackSelected" + "Themes/default/window/ControlBar/ButtonForwardDisabled" + "Themes/default/window/ControlBar/ButtonForwardNormal" + "Themes/default/window/ControlBar/ButtonForwardSelected" + "Themes/default/window/ControlBar/ButtonInfoDisabled" + "Themes/default/window/ControlBar/ButtonInfoNormal" + "Themes/default/window/ControlBar/ButtonInfoSelected" + "Themes/default/window/ControlBar/ButtonPropertiesDisabled" + "Themes/default/window/ControlBar/ButtonPropertiesNormal" + "Themes/default/window/ControlBar/ButtonPropertiesSelected" + "Themes/default/window/ControlBar/ButtonUpDisabled" + "Themes/default/window/ControlBar/ButtonUpNormal" + "Themes/default/window/ControlBar/ButtonUpSelected" + "Themes/default/window/ControlBar/CycleBackground" + "Themes/default/window/ControlBar/CycleNormal" + "Themes/default/window/ControlBar/CycleSelected" + "Themes/default/window/ControlBar/CyclePopupBackground" + "Themes/default/window/ControlBar/HistoryNormal" + "Themes/default/window/ControlBar/HistorySelected" + "Themes/default/window/ControlBar/HistoryPopupBackground" + "Themes/default/window/ControlBar/ShowModeCycleFrame" + "Themes/default/window/ControlBar/ViewByCycleFrame" + "Themes/default/window/StatusBar/Background" + "Themes/default/window/StatusBar/PadLock" + "Themes/default/window/StatusBar/Reading" + "Themes/default/window/StatusBar/ShowAll" + "Themes/default/window/StatusBar/ThumbnailsAlways" + "Themes/default/window/StatusBar/ThumbnailsAsDefault" + "Themes/default/window/StatusBar/ThumbnailsGenerate" + "Themes/default/window/StatusBar/Typing" + "Themes/default/Menu/DropMenu/Abort" + "Themes/default/Menu/DropMenu/Copy" + "Themes/default/Menu/DropMenu/Move" + "Themes/default/PointerIcons/copying.info" + "Themes/default/PointerIcons/forbidden.info" + "Themes/default/PointerIcons/makelink.info" + "Themes/default/PointerIcons/moving.info" + "Themes/default/Prefs/Modules/delete" + "Themes/default/Prefs/Modules/empty_trashcan" + "Themes/default/Prefs/Modules/execute_command" + "Themes/default/Prefs/Modules/iconproperties" + "Themes/default/Prefs/Modules/information" + "Themes/default/Prefs/Modules/newdrawer" + "Themes/default/Prefs/Modules/reboot" + "Themes/default/Prefs/Modules/rename" + "Themes/default/Prefs/Modules/systeminfo" + "Themes/default/Prefs/Modules/windowproperties" + "Themes/default/Prefs/Pages/about" + "Themes/default/Prefs/Pages/desktop" + "Themes/default/Prefs/Pages/dragndrop" + "Themes/default/Prefs/Pages/filedisplay" + "Themes/default/Prefs/Pages/icons" + "Themes/default/Prefs/Pages/misc" + "Themes/default/Prefs/Pages/modules" + "Themes/default/Prefs/Pages/paths" + "Themes/default/Prefs/Pages/plugins" + "Themes/default/Prefs/Pages/startup" + "Themes/default/Prefs/Pages/truetypefonts" + "Themes/default/Prefs/Pages/windows" + "Themes/default/Icons/Overlay/LeftOut" + "Themes/default/Icons/Overlay/ReadOnly" + "Themes/default/Icons/Overlay/Thumbnail" + "" + ) + ) + ( + (set #Theme-WinStatusBar-Installed (tackon "Scalos:" brush)) + (if ReplaceWinStatusBar + ( + ;(message "Number: " #b "\nInstall: " brush "\nTo: " (tackon "Scalos:" (pathonly(brush)))) + (if foundstatusbar + ( + + (if (exists #Theme-WinStatusBar-Installed (NOREQ)) + (P_BackupThemes #Theme-WinStatusBar-Installed brush) + ) + (trap 4 + (P_SimpleCopy ("Copying: " (fileonly (brush)) "...") brush (tackon "Scalos:" (pathonly(brush))) " Theme.") + ) + ) + ) + ) + ( + (trap 4 + (P_SimpleCopy ("Copying: " (fileonly (brush)) "...") brush (tackon "Scalos:" (pathonly(brush))) " Theme.") + ) + ) + ) + + (if (= @ioerr 202) + ( + (message "ErrorCode: " @ioerr "\nTheme: '" (fileonly(brush)) "'\n" + "This theme hasn't been installed to: '" (pathonly(#Theme-WinStatusBar-Installed)) "'!\n" + "Installer's going to try to install it again." + ) + + (trap 4 + (P_SimpleCopy ("Copying: " (fileonly (brush)) "...") brush (tackon "Scalos:" (pathonly(brush))) " Theme.") + ) + + (if (= @ioerr 202) + ( + (message "ErrorCode: " @ioerr "\nTheme: '" (fileonly(brush)) "'\n" + "Sorry! This theme hasn't been installed to: '" (pathonly(#Theme-WinStatusBar-Installed)) "'.\n" + ) + ) + ) + + ) + + ) + (set @ioerr 0) + (set #b (+ #b 1)) + ) + ) +) + +;---------------------------------------------------------------------------- +;== PROCEDURE P_RemoveObsolete ======================================== +;---------------------------------------------------------------------------- + +(procedure P_RemoveObsolete + (set #b 0) + (while + (set fname + (select #b + "SYS:Classes/datatypes/amigaiconobj35.datatype" + "SYS:Classes/datatypes/amigaiconobject.datatype" + "SYS:Classes/datatypes/glowiconobject.datatype" + "SYS:Classes/datatypes/iconobject.datatype" + "SYS:Classes/datatypes/newiconobject.datatype" + "SYS:Classes/datatypes/pngiconobject.datatype" + "Devs:Datatypes/AmigaIconObj35" + "Devs:Datatypes/AmigaIconObj35.info" + "Devs:Datatypes/AmigaIconObject" + "Devs:Datatypes/AmigaIconObject.info" + "Devs:Datatypes/GlowIconObject" + "Devs:Datatypes/GlowIconObject.info" + "Devs:Datatypes/NewIconObject" + "Devs:Datatypes/NewIconObject.info" + "Devs:Datatypes/PNGIconObject" + "Devs:Datatypes/PNGIconObject.info" + "" + ) + ) + ( + (if (exists fname (NOREQ)) + ( + (delete fname force) + ) + ) + (set #b (+ #b 1)) + ) + ) +) + +;---------------------------------------------------------------------------- +;== PROCEDURE P_BACKUPTHEMES ======================================== +;---------------------------------------------------------------------------- + +(procedure P_BackupThemes #picture #pathpic + + (set #BackupThemes (tackon #storage-scalos "Themes")) + + (if (not (exists #BackupThemes (NOREQ))) + ( + (makedir #BackupThemes + (prompt "Create dir: " #BackupThemes) + (help @makedir-help) + ) + ) + ) + + + (set #BackupDefaultThemes (tackon #BackupThemes "default")) + + (if (not (exists #BackupDefaultThemes (NOREQ))) + ( + (makedir #BackupDefaultThemes + (prompt "Create dir: " #BackupDefaultThemes) + (help @makedir-help) + ) + ) + ) + + (set #BackupThemePointers (tackon #BackupDefaultThemes "Pointers")) + + (if (not (exists #BackupThemePointers (NOREQ))) + ( + (makedir #BackupThemePointers + (prompt "Create dir: " #BackupThemePointers) + (help @makedir-help) + ) + ) + ) + + (set #BackupThemeDesktop (tackon #BackupDefaultThemes "Desktop")) + + (if (not (exists #BackupThemeDesktop (NOREQ))) + ( + (makedir #BackupThemeDesktop + (prompt "Create dir: " #BackupThemeDesktop) + (help @makedir-help) + ) + ) + ) + + (set #BackupThemeMenu (tackon #BackupDefaultThemes "Menu")) + + (if (not (exists #BackupThemeMenu (NOREQ))) + ( + (makedir #BackupThemeMenu + (prompt "Create dir: " #BackupThemeMenu) + (help @makedir-help) + ) + ) + ) + + (set #BackupThemeDropMenu (tackon #BackupThemeMenu "DropMenu")) + + (if (not (exists #BackupThemeDropMenu (NOREQ))) + ( + (makedir #BackupThemeDropMenu + (prompt "Create dir: " #BackupThemeDropMenu) + (help @makedir-help) + ) + ) + ) + + (set #BackupThemesWin (tackon #BackupDefaultThemes "Window")) + + (if (not (exists #BackupThemesWin (NOREQ))) + ( + (makedir #BackupThemesWin + (prompt "Create dir: " #BackupThemesWin) + (help @makedir-help) + ) + ) + ) + + (set #BackupThemesWinStatusBar (tackon #BackupThemesWin "StatusBar")) + + (if (not (exists #BackupThemesWinStatusBar (NOREQ))) + ( + (makedir #BackupThemesWinStatusBar + (prompt "Create dir: " #BackupThemesWinStatusBar) + (help @makedir-help) + ) + ) + ) + + (set #BackupThemesPrefs (tackon #BackupDefaultThemes "Prefs")) + + (if (not (exists #BackupThemesPrefs (NOREQ))) + ( + (makedir #BackupThemesPrefs + (prompt "Create dir: " #BackupThemesPrefs) + (help @makedir-help) + ) + ) + ) + + (set #BackupThemesPrefsPages (tackon #BackupThemesPrefs "Pages")) + + (if (not (exists #BackupThemesPrefsPages (NOREQ))) + ( + (makedir #BackupThemesPrefsPages + (prompt "Create dir: " #BackupThemesPrefsPages) + (help @makedir-help) + ) + ) + ) + + (set #BackupThemesPrefsModules (tackon #BackupThemesPrefs "Modules")) + + (if (not (exists #BackupThemesPrefsModules (NOREQ))) + ( + (makedir #BackupThemesPrefsModules + (prompt "Create dir: " #BackupThemesPrefsModules) + (help @makedir-help) + ) + ) + ) + + + (set #BackupThemesIcons (tackon #BackupDefaultThemes "Icons")) + + (if (not (exists #BackupThemesIcons (NOREQ))) + ( + (makedir #BackupThemesIcons + (prompt "Create dir: " #BackupThemesIcons) + (help @makedir-help) + ) + ) + ) + + (set #BackupThemesIconsOverlay (tackon #BackupThemesIcons "Overlay")) + + (if (not (exists #BackupThemesIconsOverlay (NOREQ))) + ( + (makedir #BackupThemesIconsOverlay + (prompt "Create dir: " #BackupThemesIconsOverlay) + (help @makedir-help) + ) + ) + ) + + ; (message "Copy: \n" #picture "\nTo: \n" (tackon #storage-scalos (pathonly(#pathpic)))) + (trap 4 + (P_SimpleCopy ("Copy backup: " (fileonly (#picture)) "...") #picture (tackon #storage-scalos (pathonly(#pathpic))) " Theme.") + ) + (if (> @ioerr 0 ) + ( + (message "ErrorCode: " @ioerr "\nTheme: '" (fileonly(brush)) "'! :(\n" + "Sorry! This theme hasn't been copied to: '" (tackon #storage-scalos (pathonly(#pathpic))) "'.\n" + ) + ) + ) + (set foundthemes 1) + (set @ioerr 0) +) + +;---------------------------------------------------------------------------- +;== PROCEDURE ENVARC AVERAGE =============================================== +;---------------------------------------------------------------------------- + +(procedure P_VerifyEnvarcAverage #ehelptext + + (set ReplaceEnvarc 0) + (set FoundEnvarc 0) + + (set #num 0) + (while + (set #deftype + (select #num + "deficons.prefs" + "icandy" + "Palette13.prefs" + "Pattern.prefs" + "Persist.prefs" + "scalos.prefs" + "Menu13.prefs" + "appicon" + "archive" + "brush" + "disk" + "drawer" + "filearchive" + "gif" + "ILBM" + "jpeg" + "picture" + "project" + "tool" + "trashcan" + "" + ) + ) + ( + (if (= #num 0) + ( + (set #ftypes-installed (cat "" (tackon #env #deftype))) + (set #ftypes-to-install #deficons) + (set #destbackup "Sys:Storage/Envarc") + ) + ) + + (if (and (> #num 0) (<= #num 5)) + ( + (set #ftypes-installed (cat "" (tackon #env-scalos #deftype))) + (set #ftypes-to-install (cat "" (tackon #envarc-common #deftype))) + (set #destbackup (tackon #storage-scalos "Envarc")) + ) + ) + + (if (= #num 6) + ( + (set #ftypes-installed (cat "" (tackon #env-scalos #deftype))) + (set #ftypes-to-install #menu13) + (set #destbackup (tackon #storage-scalos "Envarc")) + ) + ) + + (if (and (> #num 6) (<= #num 19)) + ( + (set #ftypes-installed (cat "" (tackon (tackon #env-scalos "Filetypes") #deftype))) + (set #ftypes-to-install (cat "" (tackon #envarcftypes #deftype))) + (set #destbackup (tackon #storage-scalos "Envarc/Filetypes")) + ) + ) + + (if (exists #ftypes-installed (NOREQ)) + ( + (set ReplaceEnvarc 1) + ;(message "Number: " #num "\nInstalled: " #ftypes-installed "\nTo install: " #ftypes-to-install "\n\nBackup of: " #ftypes-installed "\nto: " #destbackup) + ) + ) + (set #num(+ #num 1)) + ) + ) + (if ReplaceEnvarc + ( + (set #ask-replace-Envarc + (cat + "Installer found some default preferences installed.\n" + "Do you want to replace them?\n\n" + "Files to install:\n" + "deficons.prefs, icandy, Palette13.prefs, Pattern.prefs\n" + "Menu13.prefs, Persist.prefs, scalos.prefs\n\n" + "appicon, archive, brush, disk, drawer, filearchive\n" + "gif, ILBM, jpeg, picture, project, tool, trashcan\n\n" + "A backup copy will be created in 'Sys:Storage/Scalos'\n\n" + "NOTE: If a old backup copy already exists, it will be replaced!" + ) + ) + (set FoundEnvarc + (askbool + (prompt #ask-replace-Envarc) + (help #help-themes-statusbar) + (default 0) + ) + ) + ) + ) + (set #num 0) + (while + (set #deftype + (select #num + "deficons.prefs" + "icandy" + "Palette13.prefs" + "Pattern.prefs" + "Persist.prefs" + "scalos.prefs" + "Menu13.prefs" + "appicon" + "archive" + "brush" + "disk" + "drawer" + "filearchive" + "gif" + "ILBM" + "jpeg" + "picture" + "project" + "tool" + "trashcan" + "" + ) + ) + ( + + (if (= #num 0) + ( + (set #ftypes-installed (cat "" (tackon #env #deftype))) + (set #ftypes-to-install #deficons) + (set #destbackup "Sys:Storage/Envarc") + ) + ) + + (if (and (> #num 0) (<= #num 5)) + ( + (set #ftypes-installed (cat "" (tackon #env-scalos #deftype))) + (set #ftypes-to-install (cat "" (tackon #envarc-common #deftype))) + (set #destbackup (tackon #storage-scalos "Envarc")) + ) + ) + + (if (= #num 6) + ( + (set #ftypes-installed (cat "" (tackon #env-scalos #deftype))) + (set #ftypes-to-install #menu13) + (set #destbackup (tackon #storage-scalos "Envarc")) + ) + ) + + (if (and (> #num 6) (<= #num 19)) + ( + (set #ftypes-installed (cat "" (tackon (tackon #env-scalos "Filetypes") #deftype))) + (set #ftypes-to-install (cat "" (tackon #envarcftypes #deftype))) + (set #destbackup (tackon #storage-scalos "Envarc/Filetypes")) + ) + ) + + + (if ReplaceEnvarc + ( + (if FoundEnvarc + ( + (if (exists #ftypes-installed (NOREQ)) + ( + (P_BackupEnvarc #ftypes-installed #destbackup) + ) + ) + (P_SimpleCopy ("Copying: " (fileonly (#deftype)) "...") #ftypes-to-install (pathonly(#ftypes-installed)) " default prefs.") + ) + ) + ) + ( + (P_SimpleCopy ("Copying: " (fileonly (#deftype)) "...") #ftypes-to-install (pathonly(#ftypes-installed)) " default prefs.") + ) + ) + (set #num (+ #num 1)) + ) + ) +) + +;---------------------------------------------------------------------------- +;== PROCEDURE P_BACKUPENVARC ============================================= +;---------------------------------------------------------------------------- + +(procedure P_BackupEnvarc #file #destpath + + (if (not (exists #destpath (NOREQ))) + ( + (makedir #destpath + (prompt "Create dir: " #destpath) + (help @makedir-help) + ) + ) + ) + (P_SimpleCopy ("Copy backup: " (fileonly (#file)) "...") #file #destpath " default prefs.") +) + +;---------------------------------------------------------------------------- +;== PROCEDURE ENVARC EXPERT ============================================ +;---------------------------------------------------------------------------- + +(procedure P_VerifyEnvarcForExpert #esrc #edest #ehelptext + + (set #flag-icandy 1) + (set #flag-Palette 2) + (set #flag-Pattern 4) + (set #flag-Persist 8) + (set #flag-scalosprefs 16) + + (set #install-default (BITOR #install-default #flag-icandy)) + (set #install-default (BITOR #install-default #flag-Palette)) + (set #install-default (BITOR #install-default #flag-Pattern)) + (set #install-default (BITOR #install-default #flag-Persist)) + (set #install-default (BITOR #install-default #flag-scalosprefs)) + + + (set ftypes-files + (askoptions + (prompt #prompt-default-prefs) + (help #fhelptext @askoptions-help) + (choices + "icandy" + "Palette13.prefs" + "Pattern.prefs" + "Persist.prefs" + "scalos.prefs" + ) + (default #install-default) + ) + ) + (set #num 0) + (while + (set #deftype + (select #num + "icandy" + "Palette13.prefs" + "Pattern.prefs" + "Persist.prefs" + "scalos.prefs" + "" + ) + ) + ( + (set #ftypes-installed + (cat "" (tackon #edest #deftype) + ) + ) + + ( + (set #ftypes-to-install + (cat "" (tackon #esrc #deftype) + ) + ) + + (if (IN ftypes-files #num) + ( + (P_SimpleCopy "Copy Filetypes: " #ftypes-to-install #edest #ehelptxt) + ) + ) + (set #num(+ #num 1)) + ) + ) + + ) +) + + +;---------------------------------------------------------------------------- +;== PROCEDURE ENVARC FILETYPES NOVICE ====================================== +;---------------------------------------------------------------------------- + +(procedure P_VerifyEnvarcFTypesForNovice #fsrc #fdest #fhelptext + + (set #flag-appicon 1) + (set #flag-archive 2) + (set #flag-brush 4) + (set #flag-disk 8) + (set #flag-drawer 16) + (set #flag-filearchive 32) + (set #flag-gif 64) + (set #flag-ILBM 128) + (set #flag-jpeg 256) + (set #flag-picture 1024) + (set #flag-project 2048) + (set #flag-tool 4096) + (set #flag-trashcan 8192) + + (set #install-default (BITOR #install-default #flag-appicon)) + (set #install-default (BITOR #install-default #flag-archive)) + (set #install-default (BITOR #install-default #flag-brush)) + (set #install-default (BITOR #install-default #flag-disk)) + (set #install-default (BITOR #install-default #flag-drawer)) + (set #install-default (BITOR #install-default #flag-filearchive)) + (set #install-default (BITOR #install-default #flag-gif)) + (set #install-default (BITOR #install-default #flag-ILBM)) + (set #install-default (BITOR #install-default #flag-jpeg)) + (set #install-default (BITOR #install-default #flag-picture)) + (set #install-default (BITOR #install-default #flag-project)) + (set #install-default (BITOR #install-default #flag-tool)) + (set #install-default (BITOR #install-default #flag-trashcan)) + + + (set ftypes-files + (askoptions + (prompt #prompt-default-prefs) + (help #fhelptext @askoptions-help) + (choices + "appicon" + "archive" + "brush" + "disk" + "drawer" + "filearchive" + "gif" + "ILBM" + "jpeg" + "picture" + "project" + "tool" + "trashcan" + ) + (default #install-default) + ) + ) + (set #num 0) + (while + (set #deftype + (select #num + "appicon" + "archive" + "brush" + "disk" + "drawer" + "filearchive" + "gif" + "ILBM" + "jpeg" + "picture" + "project" + "tool" + "trashcan" + "" + ) + ) + ( + (set #ftypes-installed + (cat "" (tackon #fdest #deftype) + ) + ) + + ( + (set #ftypes-to-install + (cat "" (tackon #fsrc #deftype) + ) + ) + + (if (IN ftypes-files #num) + (if (not (exists #ftypes-installed (NOREQ))) + ( + (P_SimpleCopy "Copy Filetypes: " #ftypes-to-install #fdest #fhelptxt) + ) + ) + ) + (set #num(+ #num 1)) + ) + ) + ) +) + +;---------------------------------------------------------------------------- +;== PROCEDURE ENVARC NOVICE ================================================ +;---------------------------------------------------------------------------- + +(procedure P_VerifyEnvarcForNovice #esrc #edest #ehelptext + + (set #flag-icandy 1) + (set #flag-Palette 2) + (set #flag-Pattern 4) + (set #flag-Persist 8) + (set #flag-scalosprefs 16) + + (set #install-default (BITOR #install-default #flag-icandy)) + (set #install-default (BITOR #install-default #flag-Palette)) + (set #install-default (BITOR #install-default #flag-Pattern)) + (set #install-default (BITOR #install-default #flag-Persist)) + (set #install-default (BITOR #install-default #flag-scalosprefs)) + + + (set ftypes-files + (askoptions + (prompt "Do you want to install Scalos default preferences?\n") + (help #fhelptext @askoptions-help) + (choices + "icandy" + "Palette13.prefs" + "Pattern.prefs" + "Persist.prefs" + "scalos.prefs" + ) + (default #install-default) + ) + ) + (set #num 0) + (while + (set #deftype + (select #num + "icandy" + "Palette13.prefs" + "Pattern.prefs" + "Persist.prefs" + "scalos.prefs" + "" + ) + ) + ( + (set #ftypes-installed + (cat "" (tackon #edest #deftype) + ) + ) + + ( + (set #ftypes-to-install + (cat "" (tackon #esrc #deftype) + ) + ) + + (if (IN ftypes-files #num) + (if (not (exists #ftypes-installed (NOREQ))) + ( + ;(set #deftext + ; (cat "Really overwrite: " #ftypes-installed "?" + ; ) + ;) + ;(P_SimpleCopyNovice #deftext #ftypes-to-install #edest #helptext) + ;) + ;( + (set #deftext + (cat "Copying: " #deftype " to:" #ftypes-installed + ) + ) + (P_SimpleCopy #deftext #ftypes-to-install #edest #helptext) + ) + ) + ) + (set #num(+ #num 1)) + ) + ) + + ) +) + +;---------------------------------------------------------------------------- +;== PROCEDURE P_VERIFYIFEXISTSFORNOVICE =================================== +;---------------------------------------------------------------------------- + +(procedure P_VeriFyIfExistsForNovice #srcdir #object #destdir #help + + (if (not (exists (tackon #destdir #object) (NOREQ))) + ( + (set #deftext + (cat "Copying: " #object " to: " #destdir + ) + ) + (P_SimpleCopy #deftext (tackon #srcdir #object) #destdir #help) + ) + ) +) + +;---------------------------------------------------------------------------- +;== PROCEDURE P_VERIFYIFEXISTSFORAVEXP =================================== +;---------------------------------------------------------------------------- + +(procedure P_VeriFyIfExistsForAvExp #srcdir #object #destdir #help + + (if (not (exists (tackon #destdir #object) (NOREQ))) + ( + (set #deftext + (cat "Copying: " #object " to: " #destdir + ) + ) + (P_SimpleCopy #deftext (tackon #srcdir #object) #destdir #help) + ) + ( + (set #deftext + (cat "Do you want to replace: " #object " from: " #destdir + ) + ) + (P_SimpleCopyAvExp #deftext (tackon #srcdir #object) #destdir #help) + ) + ) +) + +;---------------------------------------------------------------------------- +;== PROCEDURE COPYLIB ===================================================== +;---------------------------------------------------------------------------- + +(procedure P_Copylib #ptext #srclib #destlib + (copylib + (prompt #ptext) + (source #srclib) + (dest #destlib) + (help @copylib-help) + (confirm) + ) +) + +;---------------------------------------------------------------------------- +;== PROCEDURE COPYLIBCPU ================================================== +;---------------------------------------------------------------------------- + +(procedure P_CopylibCPU #ptext #srclib #destlib #new + (askaboutcpu) + (if (exists (cat #srclib cpuadd-1) ) + ( + (copylib + (prompt #ptext) + (source (cat #srclib cpuadd-1)) + (dest #destlib) + (newname #new) + (help @copylib-help) + (confirm) + ;(optional "nofail") + ) + ) + ) +) + +;---------------------------------------------------------------------------- +;========================= KICKSTART ======================================== +;---------------------------------------------------------------------------- + +(set #msg-badkick +(cat "You must be using Kickstart v3.1 and AmigaOS 3.5 " + "to run install script for " @app-name "!" + )) + +;================== +; Have the KS3.1 +(if (< #wbversion 40) +( (exit #msg-badkick (quiet)) + )) + +(set guides-default 1) + +(set #bad-kick "You must be using Kickstart 3.0+ to install Scalos") +(set #bad-cpu "You require at least a 68020 or higher processor to run Scalos") + +(if (= #MOS 1) + ( + (set #machine "MorphOS/PPC") + ) + ( + (if (= #OS4 1) + (set #machine "AmigaOS4/PPC") + (set #machine "AmigaOS/68K") + ) + ) +) + +(set #install-start + (cat + "\n\n" @app-name "\n" + #machine "\n" + @applicationdate"\n" + "Copyright © 2000-2010 THE SCALOS TEAM\n\n\n" + "E-mail: info@scalos.noname.fr\n" + "Web: http://scalos.noname.fr\n\n" + "\nThis script will install "@app-name" \n" + "on your disk...\n") +) + +(set #warning-start + (cat + "\n\n Scalos (Version: " #scalosresidentVer "." #scalosresidentRev ") is currently running, please, close all windows\n" + " before to continue the installation. As Scalos use some pictures\n" + " for windows status bar and if some windows are opened without\n" + " Status Bar hidden, the installation will break returning a DOS ERROR.\n") +) + +;-------------------------------------------------------------------- +;--- SCALOS MESSAGES --------------------------------------------- +;-------------------------------------------------------------------- + +(set #cat-where-scalos + (cat + "Where would you like to install "#cat-app-name"?\n" + "(A directory named Scalos will be created)." + ) +) +(set #where-scalos #cat-where-scalos) + +(set #where-scalos-help + (cat + "Scalos will be installed directly into the" + " desired directory. An assign Scalos: is made" + " right after the creation of the directory" + ) +) + +(set #startup-scalos "Scalos: assign is about add to you user-startup") + +(set #startup-scalos-help + (cat + "An Assign Scalos: will be added to your user-startup" + ) +) + +(set #startsca-select "Do you want to install Scalos as Workbench replacement?") + +(set #startsca-select-help + (cat + "If you select YES this installscript will rename the current" + " LoadWB to LoadWB.orig and install a tiny replacement to load" + " Scalos intead of the original Workbench" + ) +) +(set #startsca-select-scaloadwbhelp + (cat + "If you select YES this installscript will copy" + " LoadWB.scalos to c: and not as LoadWB replacement." + ) +) + +;-------------------------------------------------------------------- +;--- SCALOS PREFS MESSAGES ---------------------------------------- +;-------------------------------------------------------------------- + +(set #where-scalosprefs "Where is the place for the preferences editors?") + +(set #where-scalosprefs-help + (cat + "This is the destination directory of all Scalos preferences" + " editors!\n\n Normally ALL Scalos preferences editors are in Scalos:Prefs !" + ) +) + +(set #prompt-default-prefs "Do you want to install Scalos default preferences?") + +;-------------------------------------------------------------------- +;--- PLUGINS MESSAGES --------------------------------------------- +;-------------------------------------------------------------------- + +(set #plugin-select "Do you want to install some useful plugins for Scalos") + +(set #plugin-select-help + (cat + "One plugin for example might be useful for you if you want" + " a sorted cleanup of the icons..." + ) +) + +;-------------------------------------------------------------------- +;--- COPIES MESSAGES ---------------------------------------------- +;-------------------------------------------------------------------- + +(set #copy-scalos "Installing Scalos (Mainprogram)...") +(set #copy-scalosprefs "Installing Scalos Preferences...") +(set #copy-libs1 "Installing Library: iconobject.library ...") +(set #copy-libs4 "Installing Datatype: amigaiconob35.datatype ...") +(set #copy-libs4.1 "Installing Datatype: amigaiconobject.datatype ...") +(set #copy-libs5 "Installing Datatype: iconobject.datatype ...") +(set #copy-libs6 "Installing Datatype: newiconobject.datatype ...") +(set #copy-libs7 "Installing Datatype: pngiconobject.datatype ...") +(set #copy-libs8 "Installing Datatype: glowiconobject.datatype ...") +(set #copy-libs9 "Installing Library: sqlite3.library ...") + +(set #CatMOsGuiLib "Installing MorphOS library: guigfx.library.elf...") +(set #CatMOsRenderLib "Installing MorphOS library: render.library.elf...") +(set #CatOS4GuiLib "Installing library: guigfx.library.os4...") +(set #CatOS4RenderLib "Installing library: render.library.os4...") +(set #CatGuiLib "Installing library: guigfx.library...") +(set #CatRenderLib "Installing library: render.library...") + +(set #CatPopLib "Installing Library: popupmenu.library...") +(set #CatPrefLib "Installing Library: preferences.library...") +(set #CatScaGfxLib "Installing Library: scalosgfx.library...") + +(set #copy-classes "Installing required datatypes (Classes)...") +(set #copy-datatypes "Installing required datatypes (Devs)...") +(set #copy-catalog "Installing desired catalogs...") +(set #copy-presets "Installing Presets...") +(set #copy-filetypes-presets "Installing Filetypes preferences...") +(set #copy-plugins-filetypes "Installing FileTypes Plugins...") +(set #copy-plugins-menu "Installing Menu Plugins...") +(set #copy-plugins-oop "Installing OOP Plugins...") +(set #copy-plugins-preview "Installing Preview Plugins...") +(set #copy-tools "Installing Tools...") +(set #copy-loadwb "Installing LoadWB replacement...") + +;-------------------------------------------------------------------- +;--- DIALOGUES RENAME --------------------------------------------- +;-------------------------------------------------------------------- + +(set #rename-loadwborg "Renaming of original LoadWB...") +(set #rename-loadwbscalos "Renaming/Installing Scalos-LoadWB...") + +;-------------------------------------------------------------------- +;--- MESSAGE: SCALOS NO FOUND [UNUSED] ----------------------------- +;-------------------------------------------------------------------- + +(set #cat-scalos-nofound + (cat + "\n\n\nSorry ! Assign SCALOS: no found,\n" + " ScalosBeta V"#scaver"."#scarev"\n" + "can't be installed.\n" + ) +) +;---------------------------------------------------------------------------- +;=========================== PROGRAM-START ================================== +;---------------------------------------------------------------------------- + +(set @default-dest "") + +;Check Kickstart (>= v3.0) Version. + +(if (< (/ (getversion) 65536) 39) + (abort #bad-kick) +) +(set processor (database "cpu")) +(if (< processor "68020") + (abort #bad-cpu) +) + +(set #envarc-scalos-request 0) + +(set #scalos-default-dest "SYS:") +(set #env "Envarc:") +(set #env-scalos ("Envarc:Scalos")) + +;(set #scalos-default-dest "RAM:t") +;(set #env "Env:") +;(set #env-scalos ("Env:Scalos")) + +(if (exists #env-scalos (NOREQ)) + (set #envarc-scalos-request 1) +) + + +(set #storage-scalos ("Sys:Storage/Scalos")) + +(set #backupinfo + (cat + "\n\nInstaller has found Scalos preferences in '" #env-scalos "'.\n" + " You will be prompted if you want anything to be overwritten, and\n" + " a backup copy will be created in '" #storage-scalos "'\n" + ) +) + +(complete 0) + +;---------------------------------------------------------------------------- +;=========================== START REQUEST ================================= +;---------------------------------------------------------------------------- + +(message #install-start) + +;---------------------------------------------------------------------------- +;============================================================================ +;=== If Scalos is running, check its version and revison, if version >= 40 +;=== OR version = 41 AND revision <= 2 then open request asking user to +;=== close all windows(datatypes images locked). +;============================================================================ +(set #residentmore40 0) + +(if (> #scalosresident 0) + ( + (if (and (> #scalosresident 0) (>= #scalosresidentVer 40)) + ( + (set #residentmore40 1) + ) + ) + (if #residentmore40) + ( + (if (OR (< #scalosresidentVer 41) (and (= #scalosresidentVer 41) (<= #scalosresidentRev 2)) ) + ( + (message #warning-start) + ) + ) + ) + ) +) +;=========================================================================== +;--------------------------------------------------------------------------- + +(welcome) + +;=== DETECT USER-LEVEL SELECTED BY USER ===================================== + +(set #level @user-level) + +;============================================================================ + +(if (and (> #envarc-scalos-request 0) (> #level 0)) + ( + (message #backupinfo) + ) +) + +;===[ SELECT SCALOS DESTINATION ]============================================ + + +(if (and (>= #installer-version 44) (> #level 0)) + ( + (showmedia "mediatext" #licencetext 'lower_left' 'small' 1 'wordwrap') + ) +) + +(set #oldlevel #level) + +(if (exists "Scalos:" (NOREQ)) + ( + (set firstinstall 0) + (set #scalos-dest "Scalos:") + ;=== + (if (exists "Scalos:Scalos" (NOREQ)) + ( + (if (> #level 0) + ( + (set #oldversion-select-help + (cat + "\n\n Script found ASSIGN Scalos: and\n" + "compare Scalos version already installed\n" + "with the new version to install.\n" + ) + ) + + (set #oldscaversion (getversion "Scalos:scalos" )) + (set #oldscaver (/ #oldscaversion 65536) ) + (set #oldscarev (- #oldscaversion (* #oldscaver 65536) )) + (set #catoldversion + (cat + "\n\n Scalos version already installed:\n" + "Scalos V"#oldscaver"."#oldscarev"\n\n" + " Scalos to install:\n" + " ScalosBeta V"#scaver"."#scarev" ") + ) + + ;=== + (set #instnew + (askbool + (prompt #catoldversion) + (help #oldversion-select-help) + (default 1) + ) + ) + ) + ) + ) + ) + ) + ;== ELSE ==[ ASSIGN SCALOS: NO FOUND ]=============================== + + ( + (set firstinstall 1) + (if (= #level 0) + ( + (set #scalos-dest #scalos-default-dest) + ) + (set #scalos-dest + (askdir + (prompt #where-scalos) + (help #where-scalos-help "\n\n" @askdir-help) + (default #scalos-default-dest) + (newpath) + ) + ) + ) + + ) + ) + +(complete 2) + +;===[ BACKUP ENV:SCALOS ]================================================== + +(set #envarc-backup-prompt + (cat + "Installer found Scalos preferences!\n" + "If you want, a backup copy of '" #env-scalos "'\n" + " will be created in '" #storage-scalos "'" + ) +) + +(if #envarc-scalos-request + ( + (if (not (exists #storage-scalos (NOREQ))) + ( + (set #create-env-sca + (cat "Create 'Scalos' directory:\n" #storage-scalos) + ) + (makedir #storage-scalos + (prompt #create-env-sca) + (help @makedir-help) + ) + ) + ) + + ;(copyfiles + ; (prompt #envarc-backup-prompt) + ; (source #env-scalos) + ; (dest #storage-scalos) + ; (help @askfile-help) + ; (confirm "average") + ; (infos) + ; (all) + ;) + ) +) + +;========================[ INFOS SCALOS/DATATYPES ]========================== + +(set #catinfo + (if (= #OS4 0) + (cat + "\n\nScalosBeta V"#scaver"."#scarev" will be installed to : "#scalos-dest"\n\n" + "Datatypes versions to install:\n\n" + "- pngiconobject.datatype V"#dtverpng"."#dtrevpng"\n" + "- amigaiconobj35.datatype V"#dtver_aiconobj35"."#dtrev_aiconobj35"\n" + "- amigaiconobject.datatype V"#dtver_aiconobject"."#dtrev_aiconobject"\n" + "- iconobject.datatype V"#dtver_iconobject"."#dtrev_iconobject"\n" + "- newiconobject.datatype V"#dtver_niconobject"."#dtrev_niconobject"\n" + "- glowiconobject.datatype V"#dtver_glowiconobject"."#dtrev_glowiconobject"\n" + ) + ;else + (cat + "\n\nScalosBeta V"#scaver"."#scarev" will be installed to : "#scalos-dest"\n\n" + "Datatypes versions to install:\n\n" + "- pngiconobject.datatype V"#dtverpng"."#dtrevpng"\n" + "- amigaiconobj35.datatype V"#dtver_aiconobj35"."#dtrev_aiconobj35"\n" + "- amigaiconobject.datatype V"#dtver_aiconobject"."#dtrev_aiconobject"\n" + "- iconobject.datatype V"#dtver_iconobject"."#dtrev_iconobject"\n" + "- glowiconobject.datatype V"#dtver_glowiconobject"."#dtrev_glowiconobject"\n" + ) + ) +) + +(if (= #level 2) + ( + (message #catinfo) + ) +) + +(P_closemedia mediatext) + +;===================[ CREATE AND ASSIGN SCALOS DIR ]========================= + +(if firstinstall + ( + (set #userdir + (cat "" (tackon #scalos-dest "Scalos")) + ) + + (if (not (exists #userdir (NOREQ))) + ( + (makedir #userdir + (prompt #makedir-scalos) + (help @makedir-help) + (infos) + ) + + ) + + ) + (makeassign "Scalos" (tackon #scalos-dest "Scalos")) + ) + +) + +(set #scalos-dest "Scalos:") + +;---------------------------------------------------------------------------- +;------------------ IF USER-LEVEL = EXPERT (2) ------------------------------ +;---------------------------------------------------------------------------- +(if (= #level 2) + ( + (set scalosprefs-dest + (askdir + (prompt #where-scalosprefs) + (help #where-scalosprefs-help "\n\n" @askdir-help) + (default (tackon "Scalos:" "Prefs")) + (newpath) + ) + ) + ) + ( + (set scalosprefs-dest (tackon "Scalos:" "Prefs")) + ) +) + +(complete 6) + +;============================================================================ +;==================== VERIFING DIRECTORY TREE THEMES ======================== +;============================================================================ + +(set #copy-themes-help + (cat + "Installing different brushes for:\n" + " statusbar,pointer,tooltip backdrops" + ) +) + +(set #copy-themes-logos + (cat + "Installing Themes:\n " logos "..." + ) +) +(set #copy-themes + (cat + "Do you want to install themes?\n\n" + "Brushes or images will be used:\n" + " - As background for:\n" + " FileTransfer Request, Tooltips bubble.\n\n" + " - As background and informations for:\n" + " Windows Statusbar.\n\n" + " - By 'Scalos Prefs':\n" + " Delete, Empty_Traschcan, Execute_Command, Information,\n" + " NewDrawer, Reboot, Rename, SystemInfo.\n" + ) +) + +(complete 8) + +(if (< #level 2) + ( + (set askthemes 1) + ) + ( + (set askthemes + (askbool + (prompt #copy-themes) + (help #copy-themes-help) + (default 1) + ) + ) + ) +) + +(if askthemes + ( + (set themes "Scalos:Themes") + (set themes-defaut "Scalos:Themes/default") + + (set themes-menu "Scalos:Themes/default/Menu") + (set themes-modules "Scalos:Themes/default/Modules") + + (set themes-module-delete "Scalos:Themes/default/Modules/delete.module") + (set themes-module-etrasch "Scalos:Themes/default/Modules/empty_trashcan.module") + (set themes-module-ecommand "Scalos:Themes/default/Modules/execute_command.module") + (set themes-module-info "Scalos:Themes/default/Modules/information.module") + (set themes-module-ndrawer "Scalos:Themes/default/Modules/newdrawer.module") + (set themes-module-reboot "Scalos:Themes/default/Modules/reboot.module") + (set themes-module-rename "Scalos:Themes/default/Modules/rename.module") + (set themes-module-sysinfo "Scalos:Themes/default/Modules/systeminfo.module") + + (set themes-pointers "Scalos:Themes/default/PointerIcons") + (set themes-sound "Scalos:Themes/default/Sound") + (set themes-desktop "Scalos:Themes/default/Desktop") + (set themes-window "Scalos:Themes/default/Window") + (set themes-controlbar "Scalos:Themes/default/Window/ControlBar") + (set themes-statusbar "Scalos:Themes/default/Window/StatusBar") + + (set themes-prefs "Scalos:Themes/default/Prefs") + (set themes-prefs-pages "Scalos:Themes/default/Prefs/Pages") + (set themes-prefs-modules "Scalos:Themes/default/Prefs/Modules") + + (set themes-icons "Scalos:Themes/default/Icons") + (set themes-icons-overlay "Scalos:Themes/default/Icons/Overlay") + + (set #makedir-themes "Creating Themes-Destination...") + + (if (not (exists themes (NOREQ))) + ( + (makedir themes + (prompt #makedir-themes) + (help @makedir-help) + ) + ) + ) (if (not (exists themes-defaut (NOREQ))) + ( + (makedir themes-defaut + (prompt #makedir-themes) + (help @makedir-help) + ) + ) + ) (if (not (exists themes-desktop (NOREQ))) + ( + (makedir themes-desktop + (prompt #makedir-themes) + (help @makedir-help) + ) + ) + ) (if (not (exists themes-menu (NOREQ))) + ( + (makedir themes-menu + (prompt #makedir-themes) + (help @makedir-help) + ) + ) + ) (if (not (exists themes-modules (NOREQ))) + ( + (makedir themes-modules + (prompt #makedir-themes) + (help @makedir-help) + ) + ) + ) (if (not (exists themes-module-delete (NOREQ))) + ( + (makedir themes-module-delete + (prompt #makedir-themes) + (help @makedir-help) + ) + ) + ) (if (not (exists themes-module-etrasch (NOREQ))) + ( + (makedir themes-module-etrasch + (prompt #makedir-themes) + (help @makedir-help) + ) + ) + ) (if (not (exists themes-module-ecommand (NOREQ))) + ( + (makedir themes-module-ecommand + (prompt #makedir-themes) + (help @makedir-help) + ) + ) + ) (if (not (exists themes-module-info (NOREQ))) + ( + (makedir themes-module-info + (prompt #makedir-themes) + (help @makedir-help) + ) + ) + ) (if (not (exists themes-module-ndrawer (NOREQ))) + ( + (makedir themes-module-ndrawer + (prompt #makedir-themes) + (help @makedir-help) + ) + ) + ) (if (not (exists themes-module-reboot (NOREQ))) + ( + (makedir themes-module-reboot + (prompt #makedir-themes) + (help @makedir-help) + ) + ) + ) (if (not (exists themes-module-rename (NOREQ))) + ( + (makedir themes-module-rename + (prompt #makedir-themes) + (help @makedir-help) + ) + ) + ) (if (not (exists themes-module-sysinfo (NOREQ))) + ( + (makedir themes-module-sysinfo + (prompt #makedir-themes) + (help @makedir-help) + ) + ) + ) (if (not (exists themes-pointers (NOREQ))) + ( + (makedir themes-pointers + (prompt #makedir-themes) + (help @makedir-help) + ) + ) + ) (if (not (exists themes-sound (NOREQ))) + ( + (makedir themes-sound + (prompt #makedir-themes) + (help @makedir-help) + ) + ) + ) (if (not (exists themes-window (NOREQ))) + ( + (makedir themes-window + (prompt #makedir-themes) + (help @makedir-help) + ) + ) + ) (if (not (exists themes-statusbar (NOREQ))) + ( + (makedir themes-statusbar + (prompt #makedir-themes) + (help @makedir-help) + ) + ) + ) (if (not (exists themes-controlbar (NOREQ))) + ( + (makedir themes-controlbar + (prompt #makedir-themes) + (help @makedir-help) + ) + ) + ) + + ;================================= Default themes prefs ================================== + + (if (not (exists themes-prefs (NOREQ))) + ( + (makedir themes-prefs + (prompt #makedir-themes) + (help @makedir-help) + ) + ) + ) + (if (not (exists themes-prefs-pages (NOREQ))) + ( + (makedir themes-prefs-pages + (prompt #makedir-themes) + (help @makedir-help) + ) + ) + ) + (if (not (exists themes-prefs-modules (NOREQ))) + ( + (makedir themes-prefs-modules + (prompt #makedir-themes) + (help @makedir-help) + ) + ) + ) + + ;================================= Default themes icons ================================== + + (if (not (exists themes-icons (NOREQ))) + ( + (makedir themes-icons + (prompt #makedir-themes) + (help @makedir-help) + ) + ) + ) + (if (not (exists themes-icons-overlay (NOREQ))) + ( + (makedir themes-icons-overlay + (prompt #makedir-themes) + (help @makedir-help) + ) + ) + ) + + ;======================================== HELP THEMES ==================================== + + (set #help-themes-default + (cat + "\nBackgrounds and Scalos Logo brushes.\n\n" + " AboutBackground: About window background\n" + " FileTransBackground: Request transferfiles window background\n" + " ScalosAboutLogo: About window logo\n" + " ScalosLogo: About page of 'Scalos Prefs'\n" + " ScalosSplashLogo: Splash window logo\n" + " SplashBackground: Splash window background\n" + " ToolTipBackground: Tooltip bubble background\n\n" + ) + ) + + (set #help-themes-module-delete + (cat + "\nInstalling theme Delete.module file." + ) + ) + + (set #help-themes-module-etrasch + (cat + "\nInstalling theme Empty_TraschCan.module file." + ) + ) + + (set #help-themes-module-ecommand + (cat + "\nInstalling theme Execute_Command.module file." + ) + ) + + (set #help-themes-module-info + (cat + "\nInstalling theme Information.module file." + ) + ) + + (set #help-themes-module-ndrawer + (cat + "\nInstalling theme NewDrawer.module file." + ) + ) + + (set #help-themes-module-reboot + (cat + "\nInstalling theme Reboot.module file." + ) + ) + + (set #help-themes-module-rename + (cat + "\nInstalling theme Rename.module file." + ) + ) + + (set #help-themes-module-sysinfo + (cat + "\nInstalling theme Systeminfo.module file." + ) + ) + + (set #help-themes-PointerIcons + (cat + "\n Theme PointerIcons files.\n" + "They are used for all files to manipulate.\n" + "e.g. Icon 'copying.info' is used when\n" + "some objects must be copied, moved or cloned." + ) + ) + + (set #help-themes-desktop + (cat + "\n Used as default Desktop background." + ) + ) + + + (set #help-themes-window + (cat + "\n Icon 'def_iconify.info' is used for all\n" + "Scalos windows iconified on desktop.\n" + "Background: default picture used with mode view by icon.\n" + "TextBackground: default picture used with mode view by text." + ) + ) + + (set #help-themes-statusbar + (cat + "\n Theme for Window's status bar.\n\n" + "Reading:\n" + " Indicates that the window is currently reading the disk directory.\n" + "Tipyng:\n" + " Indicates that the keyboard icon selection is active.\n" + "By typing any letter, you may select the first icon starting with that letter.\n" + "PadLock:\n" + " Indicates that the contents of the window cannot be changed.\n" + "e.g. might be located on a read-only medium.\n" + "ShowAll:\n" + " This symbol shows that the window is in 'Show all files' mode.\n" + "Background:\n" + " This brush is used for the gadget status bar background." + ) + ) + + (set #help-themes-prefs + (cat + "\n Used by "Scalos Prefs":\n" + " - Pages.\n" + " - Modules.\n" + ) + ) + + (set #help-icons-overlay + (cat + "\n Used for "icons overlay":\n" + " - LeftOut.\n" + " - ReadOnly.\n" + " - Thumbnail.\n" + ) + ) + + ;===[ COPY MODULES-THEMES ]================================== + + (set themes-delete-int "Scalos:Themes/default/Modules/delete.module/delete") + (if (exists themes-delete-int (NOREQ)) + ( + (set foundthemes 1) + + ;(debug "foundthemes = " foundthemes "\nlogos = " themes-delete-int "\n") + + (set themes-delete-new (cat "" themes-delete-int ".old")) + (rename themes-delete-int themes-delete-new + (prompt "Rename old theme: delete") + ) + ) + ) + (P_SimpleCopy "Installing theme: Delete..." "Themes/default/Modules/delete.module/delete" themes-module-delete #help-themes-module-delete) + + ;------------------------------------------------------------ + + (set themes-etrash-int "Scalos:Themes/default/Modules/empty_trashcan.module/empty_trashcan") + (if (exists themes-etrash-int (NOREQ)) + ( + (set foundthemes 1) + + ;(debug "foundthemes = " foundthemes "\nlogos = " themes-etrash-int "\n") + + (set themes-etrash-new (cat "" themes-etrash-int ".old")) + (rename themes-etrash-int themes-etrash-new + (prompt "Rename old theme: empty_trashcan") + ) + ) + ) + (P_SimpleCopy "Installing theme: Empty_Trashcan..." "Themes/default/Modules/empty_trashcan.module/empty_trashcan" themes-module-etrasch #help-themes-module-etrasch) + + ;------------------------------------------------------------ + + (set themes-exec-int "Scalos:Themes/default/Modules/execute_command.module/execute_command") + (if (exists themes-exec-int (NOREQ)) + ( + (set foundthemes 1) + + ;(debug "foundthemes = " foundthemes "\nlogos = " themes-exec-int "\n") + + (set themes-exec-new (cat "" themes-exec-int ".old")) + (rename themes-exec-int themes-exec-new + (prompt "Rename old theme: execute_command") + ) + ) + ) + (P_SimpleCopy "Installing theme: Execute_Command..." "Themes/default/Modules/execute_command.module/execute_command" themes-module-ecommand #help-themes-module-ecommand) + + ;------------------------------------------------------------ + + (set themes-info-int "Scalos:Themes/default/Modules/information.module/information") + (if (exists themes-info-int (NOREQ)) + ( + (set foundthemes 1) + + ;(debug "foundthemes = " foundthemes "\nlogos = " themes-info-int "\n") + + (set themes-info-new (cat "" themes-info-int ".old")) + (rename themes-info-int themes-info-new + (prompt "Rename old theme: information") + ) + ) + ) + (P_SimpleCopy "Installing theme: Information..." "Themes/default/Modules/information.module/information" themes-module-info #help-themes-module-info) + + ;------------------------------------------------------------ + + (set themes-drawer-int "Scalos:Themes/default/Modules/Newdrawer.module/Newdrawer") + (if (exists themes-drawer-int (NOREQ)) + ( + (set foundthemes 1) + + ;(debug "foundthemes = " foundthemes "\nlogos = " themes-drawer-int "\n") + + (set themes-drawer-new (cat "" themes-drawer-int ".old")) + (rename themes-drawer-int themes-drawer-new + (prompt "Rename old theme: newdrawer") + ) + ) + ) + (P_SimpleCopy "Installing theme: NewDrawer..." "Themes/default/Modules/newdrawer.module/Newdrawer" themes-module-ndrawer #help-themes-module-ndrawer) + + ;------------------------------------------------------------ + + (set themes-reboot-int "Scalos:Themes/default/Modules/Reboot.module/Reboot") + (if (exists themes-reboot-int (NOREQ)) + ( + (set foundthemes 1) + + ;(debug "foundthemes = " foundthemes "\nlogos = " themes-reboot-int "\n") + + (set themes-reboot-new (cat "" themes-reboot-int ".old")) + (rename themes-reboot-int themes-reboot-new + (prompt "Rename old theme: reboot") + ) + ) + ) + (P_SimpleCopy "Installing theme: Reboot..." "Themes/default/Modules/reboot.module/reboot" themes-module-reboot #help-themes-module-reboot) + + ;------------------------------------------------------------ + + (set themes-rename-int "Scalos:Themes/default/Modules/Rename.module/Rename") + (if (exists themes-rename-int (NOREQ)) + ( + (set foundthemes 1) + + ;(debug "foundthemes = " foundthemes "\nlogos = " themes-rename-int "\n") + + (set themes-rename-new (cat "" themes-rename-int ".old")) + (rename themes-rename-int themes-rename-new + (prompt "Rename old theme: rename") + ) + ) + ) + (P_SimpleCopy "Installing theme: Rename..." "Themes/default/Modules/rename.module/rename" themes-module-rename #help-themes-module-rename) + + ;------------------------------------------------------------ + + (set themes-sysinfo-int "Scalos:Themes/default/Modules/SystemInfo.module/SystemInfo") + (if (exists themes-sysinfo-int (NOREQ)) + ( + (set foundthemes 1) + + ;(debug "foundthemes = " foundthemes "\nlogos = " themes-sysinfo-int "\n") + + (set themes-sysinfo-new (cat "" themes-sysinfo-int ".old")) + (rename themes-sysinfo-int themes-sysinfo-new + (prompt "Rename old theme: systeminfo") + ) + ) + ) + (P_SimpleCopy "Installing theme: SystemInfo..." "Themes/default/Modules/systeminfo.module/SystemInfo" themes-module-sysinfo #help-themes-module-sysinfo) + + ;===[ VERIFY DESKTOP/WINDOW/POINTERICONS THEMES ]========================== + + (if (and (>= #installer-version 44) (> #level 0)) + ( + (showmedia "StatusBar" (tackon "GFX" #StatusBar) 'lower_left' 'none' 0) + (showmedia "Deficonify" (tackon "GFX" #Deficonify) 'center_left' 'none' 0) + (showmedia "PointerIcons" (tackon "GFX" #PointerIcons) 'upper_left' 'none' 0) + ) + ) + + (if (= #level 2) + ( + ;--- EXPERT ---[ Themes/default/PointerIcons ]------------------------------------------------------ + (copyfiles + (prompt "Do you want to install theme: PointerIcons?") + (source "Themes/default/PointerIcons") + (dest themes-pointers) + (help #help-themes-PointerIcons) + (files) + (infos) + (all) + (confirm "expert") + ) + ) + ) + + (if (= #level 2) + ( + ;--- EXPERT ---[ Themes/default ]------------------------------------------------------------------- + (copyfiles + (prompt "Do you want to install themes for:\nScalos logos, windows and Tooltip backgrounds") + (source "Themes/default") + (dest themes-defaut) + (help #help-themes-default) + (files) + (confirm "expert") + (all) + ) + + ;--- EXPERT ---[ Themes/default/window/ControlBar ]-------------------------------------------------- + (copyfiles + (prompt "Do you want to install theme for\nwindows Control Bar and examples?\n") + (source "Themes/default/window/ControlBar") + (dest themes-controlbar) + (help #help-themes-controlbar) + (files) + (confirm "expert") + (all) + ) + + ;--- EXPERT ---[ Themes/default/window/statusbar ]-------------------------------------------------- + (copyfiles + (prompt "Do you want to install theme for\nwindows statusbar and examples?\n") + (source "Themes/default/window/statusbar") + (dest themes-statusbar) + (help #help-themes-statusbar) + (files) + (confirm "expert") + (all) + ) + + ;--- EXPERT ---[ Themes/default/window ]------------------------------------------------------------ + (copyfiles + (prompt "Do you want to install theme for windows?\n") + (source "Themes/default/window") + (dest themes-window) + (help #help-themes-window) + (files) + (confirm "expert") + (all) + ) + ;--- EXPERT ---[ Themes/default/Desktop ]----------------------------------------------------------- + (copyfiles + (prompt "Do you want to install theme for desktop?\n") + (source "Themes/default/Desktop") + (dest themes-desktop) + (help #help-themes-desktop) + (files) + (confirm "expert") + (all) + ) + ;--- EXPERT ---[ Themes/default/Prefs/Pages ]------------------------------------------------------- + (copyfiles + (prompt "Do you want to install pages themes used by scalos prefs?\n") + (source "Themes/default/Prefs/Pages") + (dest themes-prefs-pages) + (help #help-themes-prefs) + (files) + (confirm "expert") + (all) + ) + ;--- EXPERT ---[ Themes/default/Prefs/modules ]----------------------------------------------------- + (copyfiles + (prompt "Do you want to install modules themes used by scalos prefs?\n") + (source "Themes/default/Prefs/Modules") + (dest themes-prefs-modules) + (help #help-themes-prefs) + (files) + (confirm "expert") + (all) + ) + ;--- EXPERT ---[ Themes/default/Prefs/icons/Overlay ]----------------------------------------------- + (copyfiles + (prompt "Do you want to install themes used for icons overlay?\n") + (source "Themes/default/Icons/Overlay") + (dest themes-icons-overlay) + (help #help-icons-overlay) + (files) + (confirm "expert") + (all) + ) + + ) + ( + (P_VerifyThemes) + ) + ) + + (if (> #level 0) + ( + (P_closemedia Statusbar) + (P_closemedia Deficonify) + (P_closemedia PointerIcons) + ) + ) + ) +) + + +;===[ START MODULES ]======================================================== + +(set modules (tackon #scalos-dest "Modules")) + +(set #help-module-iconproper + (cat + "\nInstalling IconProperties.module." + ) +) +(set #help-module-winproper + (cat + "\nInstalling WindowProperties.module." + ) +) +(set #help-module-information + (cat + "\nInstalling Information.module." + ) +) +(set #help-module-delete + (cat + "\nInstalling Delete.module." + ) +) +(set #help-module-emptytrashcan + (cat + "\nInstalling Empty_Trashcan.module." + ) +) +(set #help-module-executecommand + (cat + "\nInstalling Execute_Command.module." + ) +) +(set #help-module-newdrawer + (cat + "\nInstalling NewDrawer.module." + ) +) +(set #help-module-rename + (cat + "\nInstalling Rename.module." + ) +) + +(set #makedir-modules "Create modules directory...") +(if (not (exists modules (NOREQ))) + ( + (makedir modules + (prompt #makedir-modules) + (help @makedir-help) + ) + ) +) + +(complete 20) + +(if (> #level 0) + ( + (copyfiles + (prompt "Select modules to install, please...") + (source "Modules/") + (dest modules) + (help @askfile-help) + (infos) + (confirm "expert") + (all) + ) + ) + ( + (P_VeriFyIfExistsForNovice "Modules" "IconProperties.module" modules #help-module-iconproper) + (P_VeriFyIfExistsForNovice "Modules" "WindowProperties.module" modules #help-module-winproper) + (P_VeriFyIfExistsForNovice "Modules" "Information.module" modules #help-module-information) + (P_VeriFyIfExistsForNovice "Modules" "Delete.module" modules #help-module-delete) + (P_VeriFyIfExistsForNovice "Modules" "Empty_Trashcan.module" modules #help-module-emptytrashcan) + (P_VeriFyIfExistsForNovice "Modules" "Execute_Command.module" modules #help-module-executecommand) + (P_VeriFyIfExistsForNovice "Modules" "NewDrawer.module" modules #help-module-newdrawer) + (P_VeriFyIfExistsForNovice "Modules" "Rename.module" modules #help-module-rename) + ) +) + +;===[ END MODULES ]=========================================================== + + +(complete 40) + +;===[ COPY SCALOS-MAINFILE ]================================================== + +(set #help-scamain + (cat + "\nInstalling Scalos main executable." + ) +) +(P_SimpleCopyinfo "Installing Scalos ..." "Scalos" #scalos-dest #help-scamain) + + +;==================[ COPY PREFS ]============================================ + +(if (not (exists "Scalos:Prefs" (NOREQ))) + ( + (makedir scalosprefs-dest + (prompt #makedir-prefs) + (help @makedir-help) + ) + (set scalosprefs-dest "Scalos:Prefs") + ) +) + +(copyfiles + (prompt #copy-scalosprefs) + (source "Prefs/") + (dest scalosprefs-dest) + (help @askfile-help) + (infos) + (confirm) + (all) +) + +(complete 50) + +;==================[ COPY LIBRARIES ]======================================== + +(P_Copylib #copy-libs1 "Libs/iconobject.library" "Libs:") +(P_Copylib #copy-libs4 "Icondatatypes/Datatypes/amigaiconobject.datatype" #defclasses) +(P_Copylib #copy-libs4.1 "Icondatatypes/Datatypes/amigaiconobj35.datatype" #defclasses) +(P_Copylib #copy-libs5 "Icondatatypes/Datatypes/iconobject.datatype" #defclasses) +(if (= #OS4 0) + (P_Copylib #copy-libs6 "Icondatatypes/Datatypes/newiconobject.datatype" #defclasses) +) +(P_Copylib #copy-libs7 "Icondatatypes/Datatypes/pngiconobject.datatype" #defclasses) +(P_Copylib #copy-libs8 "Icondatatypes/Datatypes/glowiconobject.datatype" #defclasses) +(P_Copylib #copy-libs9 "Libs/sqlite3.library" "Libs:") + +(if (= #OS4 0) + (P_Copylib #CatPopLib "Libs/popupmenu.library" "Libs:") +) +(P_Copylib #CatPrefLib "Libs/preferences.library" "Libs:") +(P_Copylib #CatScaGfxLib "Libs/scalosgfx.library" "Libs:") + +(if (= #MOS 1) + ( + (P_Copylib #CatMOsGuiLib "Libs/guigfx.library.elf" "Libs:") + (P_Copylib #CatMOsRenderLib "Libs/render.library.elf" "Libs:") + ) + (if (= #OS4 1) + ( + (P_Copylib #CatOS4GuiLib "Libs/OS4/guigfx.library" "Libs:") + (P_Copylib #CatOS4RenderLib "Libs/OS4/render.library" "Libs:") + ) + ( + (P_Copylib #CatGuiLib "Libs/guigfx.library" "Libs:") + (P_Copylib #CatRenderLib "Libs/render.library" "Libs:") + ) + ) +) + +;==================[ COPY MUI CLASSES ]======================================== + +(if (= #MOS 1) + ( + (set #mui-classes "SYS:classes/mui") + ) + ( + (set #mui-classes "MUI:libs/mui") + ) +) + +;===========[ COPY CATALOG FILES ]=========================================== + +(set catalogs + (tackon "Catalogs" (tackon @language "Scalos")) +) + +(set destination + (tackon "Locale:Catalogs" (tackon @language "Scalos")) +) + +(if (exists (catalogs)) + (copyfiles + (prompt #copy-catalog) + (source catalogs) + (dest destination) + (help @askfile-help) + (confirm) + (all) + ) +) + +;===========[ COPY ENV-ARCHIVE ]============================================= + +(set #deficons "env-archive/deficons.prefs") + +; select source directory for localized preferences +(if (= #MOS 1) + ( + ; MorphOS + (set #envarc-common "env-archive/scalos.MOS") + ) + (if (= #OS4 1) + ( + ; OS4 + (set #envarc-common "env-archive/scalos.OS4") + ) + ( + ; 68K + (set #envarc-common "env-archive/scalos.68k") + ) + ) +) + +; default for unknown language is "English" +(set #envarc-locale (tackon #envarc-common "English")) + +(if (= @language "français") + ( + (set #envarc-locale (tackon #envarc-common "Français")) + ) +) +(if (= @language "deutsch") + ( + (set #envarc-locale (tackon #envarc-common "Deutsch")) + ) +) + +(set #menu13 (tackon #envarc-locale "Menu13.prefs")) +(set #envarcftypes (tackon #envarc-locale "FileTypes")) + +(complete 75) + +(if (= #level 0) + ( + (P_VerifyEnvarcForNovice #envarc-common #env-scalos #copy-filetypes-presets) + (P_VerifyEnvarcFTypesForNovice #envarcftypes (tackon #env-scalos "Filetypes") #copy-filetypes-presets) + (if (not (exists (tackon #env-scalos "Menu13.prefs") (NOREQ))) + ( + (set #deftext + (cat "Copying: " #menu13 " to: " #env-scalos + ) + ) + (P_SimpleCopy #deftext #menu13 #env-scalos #helptext) + ) + ) + + (if (not (exists (tackon #env "deficons.prefs") (NOREQ))) + ( + (set #deftext + (cat "Copying: " #deficons " to: " #env + ) + ) + (P_SimpleCopy #deftext #deficons #env #helptext) + ) + ) + ) + ( + ;===[ Average and expert mode ]=== + (if (= #level 1) + ( + (P_VerifyEnvarcAverage #copy-filetypes-presets) + ) + ) + + (if (= #level 2) + ( + (P_VerifyEnvarcForExpert #envarc-common #env-scalos #copy-filetypes-presets) + + ;=========[ COPY ENV-ARCHIVE FILETYPES ]===================================== + + (copyfiles + (prompt #copy-filetypes-presets) + (source #envarcftypes) + (dest (tackon #env-scalos "Filetypes")) + (help @askfile-help) + (confirm "expert") + (all) + ) + (copyfiles + (prompt #copy-presets) + (source #envarc-locale) + (dest #env-scalos) + (help @askfile-help) + (confirm "expert") + (files) + (all) + ) + (copyfiles + (prompt "Do you want to install: \n" #deficons " to: "#env " ?") + (source #deficons) + (dest #env) + (help @askfile-help) + (confirm "expert") + (files) + ) + ) + ) + ) +) + +;=========[ HISTORY ]========================================================= + +(P_SimpleCopy "Installing History..." #licencetext #scalos-dest @askfile-help) + +;=========[ README ]=========================================================== + +(P_SimpleCopy "Installing Readme..." "Readme.txt" #scalos-dest @askfile-help) + +(complete 85) + +;=========[ ASK COPY PLUGINS ================================================ + +(if (= #level 2) + ( + (set plugin + (askbool + (prompt #plugin-select) + (help #plugin-select-help) + (default 1) + ) + ) + ) + ( + (set plugin 1) + ) +) + +(if plugin + ( + (set #plugins-dest "Scalos:Plugins") + (set #plugins-dest-types "Scalos:Plugins/FileTypes") + (set #plugins-dest-menu "Scalos:Plugins/Menu") + (set #plugins-dest-oop "Scalos:Plugins/OOP") + (set #plugins-dest-preview "Scalos:Plugins/Preview") + + (set #makedir-plug "Creating Plugin-Destination...") + (set #makedir-plug-types "Creating FileTypes Plugins-Destination...") + (set #makedir-plug-menu "Creating Menu Plugins-Destination...") + (set #makedir-plug-oop "Creating OOP Plugin-Destination...") + (set #makedir-plug-preview "Creating Preview Plugin-Destination...") + +;---------------------------------------------------------------------------- +;------------------[ VERIFY DIRECTORY TREE PLUGINS ]------------------------- +;---------------------------------------------------------------------------- + + (if (not (exists #plugins-dest (NOREQ))) + ( + (makedir #plugins-dest + (prompt #makedir-plug) + (help @makedir-help) + ) + ) + ) + + (if (not (exists #plugins-dest-types (NOREQ))) + ( + (makedir #plugins-dest-types + (prompt #makedir-plug-types) + (help @makedir-help) + ) + ) + ) + + (if (not (exists #plugins-dest-menu (NOREQ))) + ( + (makedir #plugins-dest-menu + (prompt #makedir-plug-menu) + (help @makedir-help) + ) + ) + ) + (if (not (exists #plugins-dest-oop (NOREQ))) + ( + (makedir #plugins-dest-oop + (prompt #makedir-plug-oop) + (help @makedir-help) + ) + ) + ) + + (if (not (exists #plugins-dest-preview (NOREQ))) + ( + (makedir #plugins-dest-preview + (prompt #makedir-plug-preview) + (help @makedir-help) + ) + ) + ) + +(complete 88) + +;=========[ COPY PLUGINS ]=================================================== + + (copyfiles + (prompt #copy-plugins-filetypes) + (source "PlugIns/Filetypes") + (dest (tackon #scalos-dest "Plugins/Filetypes")) + (help @askfile-help) + (confirm) + (all) + ) + + (copyfiles + (prompt #copy-plugins-menu) + (source "Plugins/Menu") + (dest (tackon #scalos-dest "Plugins/Menu")) + (help @askfile-help) + (confirm) + (all) + ) + + (copyfiles + (prompt #copy-plugins-preview) + (source "Plugins/Preview") + (dest (tackon #scalos-dest "Plugins/Preview")) + (help @askfile-help) + (confirm) + (all) + ) + +;=========[ COPY OOP PLUGINS WITH VERSIONS CHECKED - AUTO COMPLETE ]========= + + (set p 0) + (while (set oopplug (select p "devicefilter.plugin" "persist.plugin" "title_clock.plugin" "title_freepens.plugin" "volumegauge.plugin" "wb39.plugin" "wbrexx.plugin" "xtwindows.plugin" "")) + ( + (set p(+ p 1)) + (P_Copylib (cat "" #copy-plugins-oop "\n" oopplug "") (tackon "Plugins/OOP" oopplug) (tackon #scalos-dest "Plugins/OOP")) + ) + ) + + ) +) + +(complete 94) + +;=========[ Remove icon datatypes from old locations ]======================= + +(P_RemoveObsolete) + +(complete 95) + +;=========[ COPY SCALOS TOOLS ]============================================== + +(copyfiles + (prompt #catctrl) + (source "Tools") + (dest "Scalos:Tools") + (help @askfile-help) + (confirm) + (files) + (infos) + (all) +) + +;=========[ LOADWB (VERSION CHECKED) ]======================================= + +(complete 98) + +(if (= #MOS 1) + ( + (set #loadwb "MOSSYS:c/LoadWB") + ) + ( + (set #loadwb "c:LoadWB") + ) +) +(set #loadwb-backup (cat #loadwb ".orig")) +(set #loadwbsca (cat #loadwb ".scalos")) + +;=========[ WORKBENCH REPLACEMENT // SET USER LEVEL 1 ]====================== + +(user 1) + +(set #startsca 0) + +(set #startsca + (askbool + (prompt #startsca-select) + (help #startsca-select-help) + (default 1) + ) + ) + + +(P_Replace 'C/LoadWB' #loadwb) + +(user #oldlevel) + +(if #startsca + ( + (if (NOT (exists #loadwb-backup (NOREQ))) + ( + (rename #loadwb #loadwb-backup + (prompt #rename-loadwborg) + ) + ) + ) + (copyfiles + (prompt #sverwb) + (source "c/LoadWB") + (dest (pathonly #loadwb)) + (help @askfile-help) + (confirm "expert") + ) + (startup @app-name + (prompt #startup-scalos) + (help #startup-scalos-help "\n\n" @startup-help) + (command 'Assign Scalos: \"' (expandpath (#scalos-dest)) '\"\n') + ) + ) +) + +;=========[ ASK REBOOT ]===================================================== + +(set #final-exit + (cat + "\n\nThe installation of " @app-name " is now complete.\n\n" + "To enable Scalos Beta, you need to your Amiga.\n\n" + "Select the \"Yes\" gadget to reboot your Amiga." + ) +) + +(set #reboot-help + (cat + " New Scalos Beta will be running only after the next startup.\n" + "If you choose not to reboot you will continue to use the old version of " + "Scalos currently resident in memory." + ) +) + +(if (> #level 0) + ( + (if foundthemes + ( + (set #install-exit + (cat + "\n\n Script found some Themes files already presents\n" + "in 'Scalos:Themes/modules' directory, and backed them up \n" + "with a '.old' suffix.\n" + "\n\n The installation of " @app-name " is now complete.\n\n" + "To enable Scalos Beta, you need to reboot your Amiga.\n\n" + "Select the \"Yes\" gadget to reboot your Amiga." + ) + ) + ) + ( + (set #install-exit #final-exit) + ) + ) + ) + ( + (set #install-exit #final-exit) + ) +) + +(user 1) + +(set @default-dest (expandpath("Scalos:"))) +(complete 100) + +(if #startsca + ( + (set #preboot + (askbool + (prompt #install-exit) + (help #reboot-help) + (default 0) + ) + ) + (P_EndInstall #preboot) + ) + ( + (P_closemedia mdmatrix) + (exit #install-exit2) + ) +) + + +;=========[ END INSTALLATION ]=============================================== + diff --git a/scalos/Installer/Install3.5_ScalosBeta.info b/scalos/Installer/Install3.5_ScalosBeta.info new file mode 100755 index 0000000000000000000000000000000000000000..cb63e19afc076f873b79263bbabc0a3cc97e1f6d GIT binary patch literal 3457 zcwXIAZERCj7=F)f_W>(unK9r;*3JdcVPGuAEJU&v+@Q+F7=ukv5EL`bHZ}om4A_>K zuniI_zuFnIjZEE&xSFUSOm6XqE-ps?kU$_(>Y zSqpbtu|srxl`P1f`no;kHk;Ea+@`w6U=x}X7cX$2$B92c%ZIj2Y%W(y=S#WVCN^$E zPZ`?N7~jhQbqP?Z{#GB_vMK@1+H@J$$v=7%3-U4r-{I|>Ec?M*GlTi5_qf=9}CP&D>8HzNU`XK;iyIfzgTpe;dUCwJ*nu*mCpO- zPHgKQ!t7C8<}YsN)N=y(bYh#ph42>9tdH9_677PE=FpDuZOs#l6(}8#yi;wRr&Eo_N>O89TarA`4Jvi{PDB9(WFKcH!$ExxC z9I;^PWJp{r7~?l>8tX&P0ks;Bs{U3l+OkS~fIPaQg2x`5n8S`CUjQ!Z#UpnD%%$Z~ z!Q*nu{chNf{^fMdK7d!?tzm#Fs6l@PZASk}oFTCjv;klDJVfR)b`jR%{w#DhR*gI2 zJW|2bL<|~jULA<)=mV+)Q5_}PRqP~imH{7=m^6QxfFF0hzNVH-T({^mz z%k9)%_2I!Y|2Ba>?{O20Zi9NXbA=}^(A>;%dM)C|mMw@O;GR&#%T#Ds%0G>=xRuvs z5j={M1_iR}kS$T8B6e%h_sp?X;BLax6<{oe(R8J8QK>~#IzCran#z|TR)+Ur8lw=$ z8a1$BjW~hV=vS~t_M@5CcrM2Gf6gKh1S%Y3W?tj92)9Q?^qPp?QQkvT%>rY*MpZ;r z5!Dn~MAsqG8o{GQRI2MxwNKZf2ete4>0Ubn4O#_vwdxR}jqq#JZ(4$E*JXc%_K*p` z)T|bWq7KPWj@)Yedo}0~WatnWbOd*vHgAPH44uL_3;6K{K^2oIc3|htScm%jsp_%u=z;Aac{FGhk$H8J zouM$8t(pSS+%HrN=dVcOt#tg5MD3|)snd4AUb(oO#Pqw0`|*z>*C7x(q!|4|hd}5M z2pytAhd}5M2ps~UL-+olOx*DQWH;|qHFB*QuaWBwHE5NNBy}~oR?(C#l{5Sv&34ow z$Q?u-0--}x=nx1U0--}G?MWd`+c8mNN_$2HUK7zfAQVVPp+h37il_#%@T^0mX&xuL zTQ+Z5-_*46T|SzQ&m*pynrc^7#ex-YtZ&-1dEv$_>v_mp<*r`2qM~*|^|Dp&MHSp- zd$FQYxLm6$YF&$k&r(zCuC7~9=~}u%j0sdOtF1z&zjH5IR$b{5GqY#RK%D8WaxKP; zOJFq-VkY0f%p2gBB#E4d4cMIrl5mg<8F<;+n_W~?G`IIEDJ;@k;T0hNl#nqXH%iDT z9D9zpd4EE$=r7_tC$37UlZ;wJV7~zN&^4H(v=+J&UIhkAp!;XCQ}vOA&)u>ACQQ;= z8$F(#313G?NASpP2))14OO3hBRQRi_O}PMKyD)Ncz5Si`AE*L zS>Jj(FlBWp+#SxBM-Fx_{@kN4(VIs{JUiPx=_Rt|GY9vaG7ofhUxw~5IjlrJRY&rE z{d*ZZ{_2rDd5E03e3qIb5jFDU(IzIx(flI0?gn0OzPJ z;hfj8=alrN9MJDTUNSm6JWg!e5+t^L|IpCTk+6~3lWZ_)9vS&. +  +All rights reserved. +  +Permission to use, copy, modify, and distribute this software for any purpose +with or without fee is hereby granted, provided that the above copyright +notice and this permission notice appear in all copies. +  +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN +NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. +  +Except as contained in this notice, the name of a copyright holder shall not +be used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization of the copyright holder. +------------------------------------------------------------------------------- +Updater.module uses AmiSSL. + + +AmiSSL v1 copyright (c) 1999-2006 Andrija Antonijevic. +AmiSSL v2/v3 copyright (c) 2002-2006 Andrija Antonijevic and Stefan Burstroem. +AmiSSL is based on OpenSSL which is in turn based on SSLeay. AmiSSL is freeware. + +AmiSSL IS PROVIDED "AS IS" AND ANY WARRANTIES, EXPRESSED OR IMPLIED, INCLUDING, BUT +NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AmiSSL AUTHORS OR ITS CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +This product includes cryptographic software written by Eric Young (eay@cryptsoft.com). +This product includes software written by Tim Hudson (tjh@cryptsoft.com). + +Here are the licences for OpenSSL and SSLeay: + + +OpenSSL license +--------------- + +Copyright (c) 1998-1999 The OpenSSL Project. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + +3. All advertising materials mentioning features or use of this + software must display the following acknowledgment: + "This product includes software developed by the OpenSSL Project + for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + +4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + endorse or promote products derived from this software without + prior written permission. For written permission, please contact + openssl-core@openssl.org. + +5. Products derived from this software may not be called "OpenSSL" + nor may "OpenSSL" appear in their names without prior written + permission of the OpenSSL Project. + +6. Redistributions of any form whatsoever must retain the following + acknowledgment: + "This product includes software developed by the OpenSSL Project + for use in the OpenSSL Toolkit (http://www.openssl.org/)" + +THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +OF THE POSSIBILITY OF SUCH DAMAGE. + +This product includes cryptographic software written by Eric Young +(eay@cryptsoft.com). This product includes software written by Tim +Hudson (tjh@cryptsoft.com). + +Original SSLeay License +----------------------- + +Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) +All rights reserved. + +This package is an SSL implementation written +by Eric Young (eay@cryptsoft.com). +The implementation was written so as to conform with Netscapes SSL. + +This library is free for commercial and non-commercial use as long as +the following conditions are aheared to. The following conditions +apply to all code found in this distribution, be it the RC4, RSA, +lhash, DES, etc., code; not just the SSL code. The SSL documentation +included with this distribution is covered by the same copyright terms +except that the holder is Tim Hudson (tjh@cryptsoft.com). + +Copyright remains Eric Young's, and as such any Copyright notices in +the code are not to be removed. +If this package is used in a product, Eric Young should be given attribution +as the author of the parts of the library used. +This can be in the form of a textual message at program startup or +in documentation (online or textual) provided with the package. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. All advertising materials mentioning features or use of this software + must display the following acknowledgement: + "This product includes cryptographic software written by + Eric Young (eay@cryptsoft.com)" + The word 'cryptographic' can be left out if the rouines from the library + being used are not cryptographic related :-). +4. If you include any Windows specific code (or a derivative thereof) from + the apps directory (application code) you must include an acknowledgement: + "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + +THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +The licence and distribution terms for any publically available version or +derivative of this code cannot be changed. i.e. this code cannot simply be +copied and put under another distribution licence +[including the GNU Public Licence.] diff --git a/scalos/Modules/Delete.Gadtools/Copy_of_delete.c b/scalos/Modules/Delete.Gadtools/Copy_of_delete.c new file mode 100755 index 000000000..97b34d1a2 --- /dev/null +++ b/scalos/Modules/Delete.Gadtools/Copy_of_delete.c @@ -0,0 +1,1357 @@ +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +__stdargs void NewList( struct List *list ); + +IMPORT struct Library *GadToolsBase; +IMPORT struct Library *IntuitionBase; +IMPORT struct Library *SysBase; +IMPORT struct Library *GfxBase; +IMPORT struct Library *DOSBase; +IMPORT struct Library *UtilityBase; + +struct Library *IconBase; +struct Library *CTRequestBase; + +struct Screen *scr; +struct DrawInfo *drinfo; +APTR visualinfo; +ULONG offx,offy,fonty,sizeheight; +ULONG wndwidth,wndheight,drawerwidth; + +struct Window *wnd; +struct Gadget *glist; +BOOL glistAttached; +BOOL fromWB; + +const STATIC STRPTR engLocText[] = +{ + "Warning! You cannot get back what you delete!\nOK to delete:", + "_OK", + "_Cancel", + "Delete", + "file(s) and", + "drawer(s) (and there contents)?", + "Delete|Abort", + "Deleting...", + "Path", + "Abort", + "Building Filelist...", + "Not Enough Memory", + "Error", + "couldn't be deleted", + "Skip it|Abort", + "is protected against deletion.\n\nDelete anywhy?", + "Delete|Skip it" +}; + +UWORD abort_key; + +STRPTR locText[18]; + +static const STRPTR VerString = "$VER: delete.module 1.0 "__AMIGADATE__; + +STATIC BOOL CreateGadgets(void); + +//------------------------------------- +// Requester Support + +#ifdef __SASC + +STATIC VOID SR_LenFunc(VOID) +{ + __emit(0x5293); // ADDQ.L #1,(A3) +} + +STATIC VOID SR_CopyFunc(VOID) +{ + __emit(0x16c0); // MOVE.B D0,(A3)+ +} + +STATIC VOID SR_CopyFuncNoUnderscore(VOID) +{ + __emit(0xb03c); __emit(0x005f); // CMP.B #'_',D0 + __emit(0x6702); // BEQ.B .end(RTS) + __emit(0x16c0); // MOVE.B D0,(A3)+ +} + +STATIC VOID SR_Dummy(VOID) +{ +} + +#else + +VOID SR_LenFunc(VOID); +VOID SR_CopyFunc(VOID); +VOID SR_CopyFuncNoUnderscore(VOID); +VOID SR_Dummy(VOID); + +#endif + +//------------------------------------- +LONG SimpleRequestArgs( struct Window *wnd, struct EasyStruct *easy, ULONG *idcmp, STRPTR reqType, STRPTR fallBackType, APTR argList ) +{ + struct EasyCTRStruct *ctr; + + // if ctrrequest.library isn't available call the + // intuituin function instead + if( !CTRequestBase ) + { + STRPTR gadgetText = (STRPTR)easy->es_GadgetFormat; + STRPTR newGadgetText; + ULONG len; + APTR nd; + + if( !gadgetText ) + { + DisplayBeep(NULL); + return 0; + } + + // Skip the text format + if( easy->es_TextFormat ) nd = RawDoFmt(easy->es_TextFormat,argList,(void(*)())SR_Dummy,NULL); + else nd = argList; + + // Calculate the length of the formatted GadgetText + len = 0; + RawDoFmt(easy->es_GadgetFormat,nd,(void(*)())SR_LenFunc,&len); + + newGadgetText = (STRPTR)AllocVec( len+2, 0 ); + if( !newGadgetText ) return EasyRequestArgs(wnd,easy,idcmp,argList); + else + { + LONG val; + struct EasyStruct es; + + // Format the gadgettext without underscores + RawDoFmt(easy->es_GadgetFormat,nd,(void(*)())SR_CopyFuncNoUnderscore,newGadgetText); + + es.es_StructSize = sizeof(struct EasyStruct); + es.es_Flags = easy->es_Flags; + es.es_Title = easy->es_Title; + es.es_TextFormat = easy->es_TextFormat; + es.es_GadgetFormat = newGadgetText; + + val = EasyRequestArgs(wnd,&es,idcmp,argList); + FreeVec( newGadgetText ); + return val; + } + } + + // Alloc an EasyCTRStruct + ctr = (struct EasyCTRStruct*)AllocVec( sizeof(struct EasyCTRStruct),MEMF_CLEAR); + if(ctr) + { + LONG val; + + // Fill in special things + ctr->ectr_Title = easy->es_Title; + ctr->ectr_RequesterType = reqType; + ctr->ectr_RequesterType_FB =fallBackType; + ctr->ectr_TimeOutmodes = NULL;//timeOutmodes; + ctr->ectr_Screen = wnd?wnd->WScreen:NULL; + + // Is any additional Arg given? + if( !argList ) + { + // No - take the Body and Gadget strings like they are + ctr->ectr_Body = easy->es_TextFormat; + ctr->ectr_Gadgets = easy->es_GadgetFormat; + } else + { + // Yes + ULONG len=0; + + // Calculate the length of the formatted body string + APTR nd = RawDoFmt(easy->es_TextFormat,argList,(void(*)())SR_LenFunc,&len); + if( len ) + { + STRPTR body = (STRPTR)AllocVec( len+2, 0 ); + + // Perform final text formatting + if( body ) RawDoFmt(easy->es_TextFormat,argList,(void(*)())SR_CopyFunc,body); + ctr->ectr_Body = body; + } + + len=0; + + // Calculate the length of the formatted gadget string + RawDoFmt(easy->es_GadgetFormat,nd,(void(*)())SR_LenFunc,&len); + if( len ) + { + STRPTR gadget = (STRPTR)AllocVec( len+2, 0 ); + + // Perform final gadget formatting + if( gadget ) RawDoFmt(easy->es_GadgetFormat,nd,(void(*)())SR_CopyFunc,gadget); + ctr->ectr_Gadgets = gadget; + } + } + + // Check for IDCMPs + if( idcmp ) + { + if( *idcmp & IDCMP_DISKINSERTED ) ctr->ectr_MonitorDiskInserted = TRUE; + if( *idcmp & IDCMP_DISKREMOVED ) ctr->ectr_MonitorDiskRemoved = TRUE; + + // Clear the *idcmp variable + *idcmp = 0; + } + + // And now the nice requester + val = EasyCTRequest(ctr); + if( val < -1 ) + { + DisplayBeep(NULL); + val = 0; + } else + { + if( val == -1 && idcmp ) + { + if( ctr->ectr_MonitorDiskInserted ) *idcmp |= IDCMP_DISKINSERTED; + if( ctr->ectr_MonitorDiskRemoved ) *idcmp |= IDCMP_DISKREMOVED; + } + } + + // ArgList given? + if( argList ) + { + // Yes - free the allocated memory + if( ctr->ectr_Gadgets ) FreeVec(ctr->ectr_Gadgets); + if( ctr->ectr_Body ) FreeVec(ctr->ectr_Body); + } + + // Free the EasyCTRStruct + FreeVec(ctr); + return val; + } +} + +//------------------------------------- +LONG SimpleRequest( struct Window *wnd, struct EasyStruct *easy, ULONG *idcmp, STRPTR reqType, STRPTR fallBackType, APTR args,... ) +{ + return SimpleRequestArgs( wnd, easy, idcmp, reqType, fallBackType, &args ); +} +//------------------------------------- + +//------------------------------------- +VOID sprintf( STRPTR buf, const STRPTR fmt,...) +{ + RawDoFmt((const STRPTR)fmt,(const STRPTR*)&fmt+1,(void(*)())SR_CopyFunc,buf); +} + +//------------------------------------- +ULONG StrLen( const STRPTR str ) +{ + if( !str) return 0; + return strlen(str); +} +//------------------------------------- +STRPTR StrCopy( const STRPTR str ) +{ + STRPTR dst; + if( !str ) return NULL; + if( !*str) return NULL; + + dst = (STRPTR)AllocVec(strlen(str)+1,0); + if(dst) strcpy(dst,str); + return dst; +} +//------------------------------------- +STRPTR NameOfLock( BPTR lock ) +{ + STRPTR n; + BOOL again; + ULONG bufSize = 127; + if( !lock ) return NULL; + + do + { + again = FALSE; + if((n = (STRPTR)AllocVec(bufSize, 0x10000 ))) + { + if( NameFromLock( lock, n, bufSize-1 ) == DOSFALSE ) + { + if( IoErr() == ERROR_LINE_TOO_LONG ) + { + bufSize += 127; + again = TRUE; + } + FreeVec(n); + n = NULL; + } + } + } while(again); + + return n; +} +//------------------------------------- +STRPTR WBArg2String( struct WBArg *arg, LONG numArgs ) +{ + struct WBArgNode + { + struct MinNode node; + STRPTR dirname; + STRPTR filename; + }; + + struct MinList list; + ULONG len=0; + STRPTR buf; + UWORD i; + + NewList((struct List*)&list ); + + for( i=0; idirname = n; + node->filename = arg[i].wa_Name; + + len += StrLen( n )+StrLen(arg[i].wa_Name)+8; + AddTail((struct List*)&list, (struct Node*)node ); + } + } + + buf = (STRPTR)AllocVec(len+2,0x10000); + if(buf) + { + struct WBArgNode *node; + STRPTR bufPtr = buf; + + while(( node = (struct WBArgNode*)RemHead((struct List*)&list))) + { + STRPTR n = node->dirname; + if( !n ) continue; + + if( n[0] ) strcpy(bufPtr,n ); + AddPart(bufPtr,node->filename,len-(bufPtr-buf)); + + bufPtr+=strlen(bufPtr); + if(list.mlh_Head->mln_Succ) + *bufPtr++=' '; + + FreeVec(n); + FreeVec(node); + } + *bufPtr = 0; + } + return buf; +} +//------------------------------------- +STRPTR GetFullPath( const STRPTR drw, const STRPTR file ) +{ + ULONG length = StrLen(drw)+StrLen(file)+4; + STRPTR fp = (STRPTR)AllocVec( length+1,0 ); + if( fp ) + { + strcpy( fp, drw ); + + if( AddPart( fp, file, length )) return fp; + FreeVec( fp ); + } + return NULL; +} +//------------------------------------- +STRPTR BuildIconName( const STRPTR name ) +{ + ULONG namelen=strlen(name); + STRPTR infoname = AllocVec(namelen+8,0); + if(infoname) + { + strcpy(infoname,name); + strcpy(infoname+namelen,".info"); + } + return infoname; +} +//------------------------------------- + +ULONG deleteAllProt; + +STRPTR delprot_body = "is protected against deletion.\n\nDelete anyway?"; +STRPTR couldnt_body = "couldn't be deleted:"; + +//------------------------------------- +// Readsupport +struct DirList +{ + struct MinList list; + BPTR lock; + ULONG read; +}; + +struct DirNode +{ + struct MinNode node; + STRPTR name; + struct DirList list; + struct DirList *parentList; + ULONG icon; +}; + +struct FileNode +{ + struct MinNode node; + STRPTR name; + ULONG nameLen; + ULONG icon; +}; + +//------------------------------------- +ULONG PrintError( const ULONG ioerr, const STRPTR name, const STRPTR button ) +{ + struct EasyStruct easy; + char buffer[80]; + + easy.es_StructSize = sizeof(struct EasyStruct); + easy.es_Flags = 0; + easy.es_Title = "Scalos"; + easy.es_TextFormat = "%s %s\n%s"; + easy.es_GadgetFormat = "%s"; + + Fault( ioerr, NULL, buffer,80); + + return (ULONG)SimpleRequest( NULL, &easy, NULL, ECTR_TYPE_WARNING, NULL, name, couldnt_body, buffer,button); +} +//------------------------------------- +BOOL IsDeletable( const STRPTR name, ULONG prot) +{ + if(( prot & FIBF_DELETE )) + { + BOOL del=deleteAllProt; + if( !deleteAllProt) + { + struct EasyStruct easy; + easy.es_StructSize = sizeof(struct EasyStruct); + easy.es_Flags = 0; + easy.es_Title = "Scalos"; + easy.es_TextFormat = "%s\n%s"; + easy.es_GadgetFormat = "%s"; + + switch( SimpleRequest( NULL, &easy, NULL, ECTR_TYPE_WARNING, NULL, name, delprot_body, "Delete|DeleteAllProtect|Skip")) + { + case 0: + break; + + case 1: + del=TRUE; + break; + + case 2: + del=deleteAllProt=TRUE; + break; + } + } + return del; + } + return TRUE; +} + +//------------------------------------- +ULONG Unprotect( const STRPTR name, const ULONG icon, ULONG prot) +{ + if(( prot & FIBF_DELETE )) + { + BOOL ok; + if(SetProtection(name,NULL) != DOSFALSE ) ok=TRUE; + else + { + LONG ioerr = IoErr(); + if( ioerr == ERROR_OBJECT_NOT_FOUND ) ok = TRUE; + else + { + ok = FALSE; + return PrintError(ioerr,name,"Skip|Abort"); + } + } + + if(ok && icon ) + { + if( icon ) + { + STRPTR infoname = BuildIconName(name); + if(infoname) + { + if(SetProtection(infoname,NULL)== DOSFALSE ) + { + LONG ioerr = IoErr(); + if( ioerr == ERROR_OBJECT_NOT_FOUND ) ok = TRUE; + else return PrintError(ioerr,name,"Skip|Abort"); + } + + FreeVec(infoname); + } + } + } + } + return 2; +} +//------------------------------------- +BOOL DeleteTheFile( const STRPTR name, const ULONG icon ) +{ + BOOL goon = TRUE; + struct TextExtent te; + ULONG len = strlen(name); + ULONG nc; + LONG ioerr; + BOOL onlyicon = FALSE; + + struct IntuiMessage *imsg; + + Move(wnd->RPort,offx+2,offy+drinfo->dri_Font->tf_Baseline+2+fonty+1); + nc = TextFit(wnd->RPort,(const STRPTR)name+len,len,&te,NULL,-1,wndwidth-2*offx-4,fonty); + Text(wnd->RPort,(const STRPTR)name+len-nc,nc); + + if( te.te_Width < drawerwidth ) + { + EraseRect(wnd->RPort,wnd->RPort->cp_x,offy+3+fonty,offx+2+drawerwidth,offy+2+2*fonty); + } + + if(wnd) + { + while((imsg = (struct IntuiMessage*)GT_GetIMsg(wnd->UserPort))) + { + ULONG cl = imsg->Class; + + if( cl == IDCMP_SIZEVERIFY ) + { + if(glistAttached) RemoveGList( wnd, glist, -1 ); + glistAttached = FALSE; + GT_ReplyIMsg(imsg); + continue; + } + + GT_ReplyIMsg(imsg); + + switch(cl) + { + case IDCMP_GADGETUP: + case IDCMP_CLOSEWINDOW: + return FALSE; + break; + + case IDCMP_NEWSIZE: + if(glistAttached) RemoveGList( wnd, glist, -1 ); + wndwidth = wnd->Width; + wndheight = wnd->Height; + EraseRect( wnd->RPort, wnd->BorderLeft, wnd->BorderTop+fonty+3, + wnd->Width-wnd->BorderRight-1, wnd->Height-wnd->BorderBottom-1 ); + if(CreateGadgets()) + { + AddGList( wnd, glist, -1,-1, NULL ); + RefreshGList( glist, wnd, NULL, -1 ); + glistAttached = TRUE; + SetFont(wnd->RPort,drinfo->dri_Font); + } + break; + } + } + } + + drawerwidth = te.te_Width; + + if(DeleteFile(name)==DOSFALSE) + { + ioerr = IoErr(); + if( ioerr == ERROR_OBJECT_NOT_FOUND) + { + if(!DeleteDiskObject(name)) + { + ioerr=IoErr(); + if(ioerr==ERROR_OBJECT_NOT_FOUND) ioerr=0; + } + else ioerr=0; + onlyicon=TRUE; + } + } else ioerr=0; + + if( ioerr ) + { + switch( ioerr) + { + case ERROR_DELETE_PROTECTED: + { + BOOL del=deleteAllProt; + if( !deleteAllProt) + { + struct EasyStruct easy; + + easy.es_StructSize = sizeof(struct EasyStruct); + easy.es_Flags = 0; + easy.es_Title = "Scalos"; + easy.es_TextFormat = "%s\n%s"; + easy.es_GadgetFormat = "%s"; + + switch( SimpleRequest( NULL, &easy, NULL, ECTR_TYPE_WARNING, NULL, name, delprot_body, "Delete|DeleteAllProtect|Skip")) + { + case 0: + del=FALSE; + break; + + case 1: + del=TRUE; + break; + + case 2: + del=deleteAllProt=TRUE; + break; + } + + } + if(del) + { + BOOL ok = onlyicon; + if( !ok ) if(SetProtection(name,NULL) != DOSFALSE ) ok=TRUE; + + if(ok)//nlyicon || SetProtection(name,NULL) != DOSFALSE ) + { + BOOL error; + + if( icon || onlyicon ) + { + ULONG namelen=strlen(name); + STRPTR infoname = AllocVec(namelen+8,0); + error = TRUE; + if(infoname) + { + strcpy(infoname,name); + strcpy(infoname+namelen,".info"); + + if(SetProtection(infoname,NULL) != DOSFALSE ) + error = FALSE; + + FreeVec(infoname); + } else SetIoErr(103); + } else error=FALSE; + + if( !error ) + { + if( onlyicon ) + { + if(DeleteDiskObject(name)) return TRUE; + } else + { + if(DeleteFile(name) != DOSFALSE ) + { + if(icon) + { + if(DeleteDiskObject(name)) return TRUE; + } else return TRUE; + } + } + } + } + ioerr = IoErr(); + } else break; + } + + default: +/* { + struct EasyStruct easy; + char buffer[80]; + + easy.es_StructSize = sizeof(struct EasyStruct); + easy.es_Flags = 0; + easy.es_Title = "Scalos"; + easy.es_TextFormat = "%s %s\n%s"; + easy.es_GadgetFormat = "%s"; + + Fault( ioerr, NULL, buffer,80); + + return (BOOL)SimpleRequest( NULL, &easy, NULL, ECTR_TYPE_WARNING, NULL, name, couldnt_body, buffer,"Skip|Abort"); + }*/ + return (BOOL)PrintError(ioerr,name,"Skip|Abort"); + break; + } + } else + { + if( icon ) + { + DeleteDiskObject(name); + } + } + + return goon; +} +//------------------------------------- +BOOL ReadInDir( struct DirList *list, APTR dirPool ) +{ + BOOL retval = TRUE; + STRPTR lockName; + + if( !list->lock ) + { + Printf("No Lock!\n"); + return FALSE; + } + + if( list->read ) + { + PutStr("Already read!\n"); + return TRUE; + } + + lockName = NameOfLock(list->lock); + if( lockName ) + { + ULONG lockSize = strlen(lockName); + APTR filePool = CreatePool( 0,4096,4096); + if( filePool ) + { + struct ExAllControl *eac; + eac = (struct ExAllControl*)AllocDosObject(DOS_EXALLCONTROL,NULL); + if( eac ) + { + struct ExAllData *ead; + ead = (struct ExAllData*)AllocVec( 1032, 0x10000 ); + if(ead) + { + LONG more; + struct MinList fileList; + NewList((struct List*)&fileList); + + eac->eac_LastKey = 0; + eac->eac_MatchString = NULL; + + list->read = TRUE; + + do + { + struct ExAllData *ed = ead; + more = ExAll( list->lock, ed, 1024, ED_TYPE, eac ); + if((!more) && (IoErr() != ERROR_NO_MORE_ENTRIES )) + { + retval = FALSE; + break; + } + + if( eac->eac_Entries ) + { + do + { + ULONG nlen = strlen(ed->ed_Name); + ULONG len = nlen+8+lockSize; + if( ed->ed_Type > 0 ) + { + struct DirNode *dir = (struct DirNode*)AllocPooled(dirPool,sizeof(struct DirNode)); + if( dir ) + { + STRPTR name = (STRPTR)AllocPooled(dirPool,len); + if(name) + { + strcpy(name,lockName); + AddPart(name,ed->ed_Name,len); + + dir->name = name; + dir->list.lock = Lock( name, ACCESS_READ); + dir->list.read = FALSE; + dir->parentList = list; + dir->icon = FALSE; + NewList((struct List*)&dir->list); + + AddTail((struct List*)list, (struct Node*)dir); + } + } + } else + { + struct FileNode *file = (struct FileNode*)AllocPooled(filePool,sizeof(struct FileNode)); + if( file ) + { + STRPTR name = (STRPTR)AllocPooled(filePool,len); + if( name ) + { + strcpy(name,lockName); + AddPart(name,ed->ed_Name,len); + + file->name = name; + file->nameLen = strlen(name); + file->icon = FALSE; + AddTail((struct List*)&fileList, (struct Node*)file); + } + } + } + ed = ed->ed_Next; + } while(ed); + } + } while(more); + + FreeVec(ead); + + // Icons aussortieren + if( !IsListEmpty((struct List*)&fileList)) + { + struct FileNode *node; + node = (struct FileNode*)fileList.mlh_Head; + while(node->node.mln_Succ && retval) + { + if( node->nameLen > 4 ) + { + if( !Stricmp(".info",node->name+node->nameLen-5)) + { + struct FileNode *fnode = (struct FileNode*)fileList.mlh_Head; + BOOL iconfound=FALSE; + node->name[node->nameLen-5]=0; + while(fnode->node.mln_Succ) + { + if( fnode != node ) + { + if( !Stricmp(node->name,fnode->name)) + { + fnode->icon = iconfound = TRUE; + break; + } + } + fnode = (struct FileNode*)fnode->node.mln_Succ; + } + + if( !iconfound ) + { + struct DirNode *dnode = (struct DirNode*)list->list.mlh_Head; + while(dnode->node.mln_Succ) + { + if( !Stricmp(node->name,dnode->name)) + { + dnode->icon = iconfound = TRUE; + break; + } + + dnode = (struct DirNode*)dnode->node.mln_Succ; + } + } + + if( iconfound ) + { + struct FileNode *tfn = node; + node = (struct FileNode*)node->node.mln_Succ; + Remove((struct Node*)tfn); + continue; + } + } + } + node = (struct FileNode*)node->node.mln_Succ; + } + + node = (struct FileNode*)fileList.mlh_Head; + while(node->node.mln_Succ && retval) + { + retval = DeleteTheFile(node->name,node->icon); + node = (struct FileNode*)node->node.mln_Succ; + } + } + } + + FreeDosObject(DOS_EXALLCONTROL,eac); + } + DeletePool(filePool); + } + FreeVec(lockName); + } + return retval; +} +//------------------------------------- +BOOL DeleteDir( struct DirList *root, APTR dirPool ) +{ + struct DirList *cl = root; + BOOL goon = TRUE; + while(cl) + { +// Printf("Readdir: %s 0x%lx\n",NameOfLock(cl->lock),cl); + if(goon) + { + if(!ReadInDir(cl,dirPool)) goon=FALSE; + } + + if( !IsListEmpty((struct List*)cl)) + { + struct DirNode *cn = (struct DirNode*)cl->list.mlh_Head; + cl = (struct DirList*)&cn->list; + } else + { + if(cl != root ) + { + struct DirNode *cn = (struct DirNode*)(((ULONG*)cl)-3); + struct DirNode *ncn = (struct DirNode*)cn->node.mln_Succ; + + if( !ncn->node.mln_Succ ) + { + do + { + if( cl == root ) return TRUE; + + cl = cn->parentList; + if( !cl ) + { + PutStr("Ready...\n"); + return TRUE; + } + + if( IsListEmpty((struct List*)cl)) + { + PutStr("Error!!\n"); + return FALSE; + } + + ncn = (struct DirNode*)RemHead((struct List*)cl); + cn = (struct DirNode*)(((ULONG*)cl)-3); + + UnLock(ncn->list.lock); + ncn->list.lock = NULL; + if( goon ) + { + goon = DeleteTheFile(ncn->name,ncn->icon); +/* { + cl = NULL; + break; + }*/ + } + } while( IsListEmpty((struct List*)cl)); + if( !cl ) break; + + ncn = (struct DirNode*)cl->list.mlh_Head; + } else + { + Remove((struct Node*)cn); + UnLock(cn->list.lock); + + if( goon ) goon=DeleteTheFile(cn->name,cn->icon);// break; + } + + cl = (struct DirList*)&ncn->list; + } else return FALSE; + } + } + return FALSE; +} +//------------------------------------- + +//------------------------------------- +STATIC BOOL SetupScreen(void) +{ + if((scr = LockPubScreen(NULL))) + { + if((drinfo = GetScreenDrawInfo(scr))) + { + if((visualinfo = GetVisualInfoA(scr,NULL))) + { + Object *o = (Object*)NewObject( NULL, SYSICLASS, + SYSIA_DrawInfo,drinfo, + SYSIA_Which, SIZEIMAGE, + TAG_DONE); + if(o) + { + if(!GetAttr( IA_Height,o,&sizeheight)) sizeheight = 11; + DisposeObject(o); + } else sizeheight = 11; + return TRUE; + } + } + } + return FALSE; +} +//------------------------------------- +STATIC VOID FreeScreen(void) +{ + if( visualinfo ) FreeVisualInfo(visualinfo); + if( drinfo ) FreeScreenDrawInfo(scr,drinfo); + if( scr ) UnlockPubScreen(NULL,scr); +} +//------------------------------------- +STATIC VOID Render(void) +{ + Move(wnd->RPort,offx+2,offy+drinfo->dri_Font->tf_Baseline+2); + SetABPenDrMd(wnd->RPort,drinfo->dri_Pens[TEXTPEN],drinfo->dri_Pens[BACKGROUNDPEN],JAM2); + Text(wnd->RPort,"Deleting...",11); +} +//------------------------------------- +STATIC BOOL CreateGadgets(void) +{ + struct Gadget *g; + + if(glist) + { + FreeGadgets(glist); + glist = NULL; + } + + g = CreateContext( &glist ); + if( g ) + { + struct NewGadget ng; + + ng.ng_VisualInfo = visualinfo; + ng.ng_TextAttr = NULL; + ng.ng_GadgetText = "_Abort"; + ng.ng_GadgetID = 1; + ng.ng_Flags = PLACETEXT_IN; + ng.ng_UserData = NULL; + ng.ng_LeftEdge = offx+2; + ng.ng_TopEdge = offy+2*fonty+4; + ng.ng_Width = wndwidth-2*ng.ng_LeftEdge; + ng.ng_Height = fonty+6; + + g = CreateGadget( BUTTON_KIND, g, &ng, + GT_Underscore,'_', + TAG_DONE); + if(g) return TRUE; + + FreeGadgets(glist); + glist=NULL; + } + return FALSE; +} +//------------------------------------- +STATIC VOID FreeGUI(void) +{ + if(wnd) CloseWindow(wnd); + if(glist) FreeGadgets(glist); +} +//------------------------------------- +STATIC BOOL SetupGUI(void) +{ + fonty = drinfo->dri_Font->tf_YSize; + offx = scr->WBorLeft; + offy = scr->WBorTop + fonty + 1; + + wndwidth = 300; + wndheight = offy + 2*fonty + sizeheight + 20; + + if( CreateGadgets()) + { + wnd = OpenWindowTags( NULL, + WA_Left,(scr->Width-wndwidth)/2, + WA_Top,(scr->Height-wndheight)/2, + WA_Width, wndwidth, + WA_Height, wndheight, + WA_IDCMP, IDCMP_CLOSEWINDOW|IDCMP_NEWSIZE|BUTTONIDCMP|IDCMP_SIZEVERIFY|IDCMP_VANILLAKEY, + WA_DragBar,TRUE, + WA_SizeGadget, TRUE, + WA_DepthGadget,TRUE, + WA_CloseGadget, TRUE, + WA_Title,"Delete", + WA_RMBTrap, TRUE, + WA_Gadgets, glist, + WA_SizeBBottom,TRUE, + WA_MaxWidth,-1, + WA_Activate, TRUE, + WA_PubScreen,scr, + WA_NoCareRefresh,TRUE, + TAG_DONE ); + if( wnd ) + { + glistAttached = TRUE; + SetFont(wnd->RPort,drinfo->dri_Font); + Render(); + return TRUE; + } + glistAttached = FALSE; + } + FreeGUI(); + return FALSE; +} +//------------------------------------- +/*STATIC BOOL HandleWnd(void) +{ + struct IntuiMessage *imsg; + BOOL retVal = FALSE; + + while((imsg = GT_GetIMsg(wnd->UserPort))) + { + ULONG cl = imsg->Class; + UWORD code = imsg->Code; + APTR iaddress = imsg->IAddress; + + if( cl == IDCMP_SIZEVERIFY ) + { + if(glistAttached) RemoveGList( wnd, glist, -1 ); + glistAttached = FALSE; + GT_ReplyIMsg(imsg); + continue; + } + + GT_ReplyIMsg(imsg); + + switch( cl ) + { + case IDCMP_CLOSEWINDOW: + retVal = TRUE; + break; + + case IDCMP_VANILLAKEY: + if( code == 10 ) retVal = TRUE; + else if( code == 27 ) + { + retVal = TRUE; + } + break; + + case IDCMP_NEWSIZE: + if(glistAttached) RemoveGList( wnd, glist, -1 ); + wndwidth = wnd->Width; + wndheight = wnd->Height; + EraseRect( wnd->RPort, wnd->BorderLeft, wnd->BorderTop+fonty+3, + wnd->Width-wnd->BorderRight-1, wnd->Height-wnd->BorderBottom-1 ); + if(CreateGadgets()) + { + AddGList( wnd, glist, -1,-1, NULL ); + RefreshGList( glist, wnd, NULL, -1 ); + glistAttached = TRUE; + SetFont(wnd->RPort,drinfo->dri_Font); + } else + { + glistAttached = FALSE; + retVal = TRUE; + } + break; + + case IDCMP_GADGETUP: + switch( ((struct Gadget*)iaddress)->GadgetID ) + { + default: + break; + } + break; + } + } + return retVal; +} +//------------------------------------- +*/ +STRPTR warning_body = "Warning! You cannot get back what you delete!\nOK to delete:"; +STRPTR files_body = "file(s) and"; +STRPTR drawers_body = "drawer(s) (and there contents)?"; + +//------------------------------------- +void main(void) +{ +/* if(SetupScreen()) + { + if( SetupGUI()) + { + BOOL ready = FALSE; + ULONG wndsig = 1UL<UserPort->mp_SigBit; + ULONG appsig; + + if( appMsgPort ) appsig = 1UL<mp_SigBit; + else appsig = 0UL; + + ActivateGadget(commandString,wnd,NULL); + + while( ready == FALSE ) + { + ULONG signal = Wait(wndsig|appsig|4096); + + if( signal & 4096 ) ready = TRUE; + if( signal & wndsig ) ready = HandleWnd(); + if( signal & appsig ) HandleApp(); + } + FreeGUI(); + + if( commandStr ) + { + STRPTR conName = BuildConName("Scalos Output Window",scr); + if( conName ) + { + SystemTags( commandStr, + SYS_Asynch, TRUE, + SYS_Output, Open(conName,MODE_OLDFILE), + SYS_Input, NULL, + SYS_UserShell, TRUE, + stackNum>=4096?NP_StackSize:TAG_IGNORE,stackNum, + TAG_DONE); + + FreeVec(conName); + } + SetVar("Scalos_last_cmd",commandStr,strlen(commandStr),GVF_GLOBAL_ONLY); + FreeVec(commandStr); + commandStr = NULL; + } + } + FreeScreen(); + } + + if(WorkbenchBase)CloseLibrary(WorkbenchBase);*/ +} +//------------------------------------- +void wbmain(struct WBStartup *wbs ) +{ + BOOL replied=FALSE; + if( wbs->sm_NumArgs > 1 ) + { + if((IconBase = OpenLibrary("icon.library",37))) + { + LONG numArgs=wbs->sm_NumArgs; + struct WBArg *wbarg; + + main(); + + wbarg = (struct WBArg*)AllocVec((numArgs+2)*sizeof(struct WBArg),0x10000); + if( wbarg ) + { + ULONG num_files=0; + ULONG num_drws=0; + ULONG i; + BOOL error=FALSE; + + for( i=1; ism_ArgList[i].wa_Lock))) + { + error = TRUE; + break; + } else + { + if(wbs->sm_ArgList[i].wa_Name) + { + if(*wbs->sm_ArgList[i].wa_Name) + { + if(!(wbarg[i-1].wa_Name = StrCopy(wbs->sm_ArgList[i].wa_Name))) + { + error = TRUE; + break; + } + num_files++; + } + else num_drws++; + } + else num_drws++; + } + } + + if( !error ) + { + ReplyMsg((struct Message*)wbs); + wbs=NULL; + replied=TRUE; + numArgs--; + + if( SetupScreen()) + { + struct EasyStruct easy; + + easy.es_StructSize = sizeof(struct EasyStruct); + easy.es_Flags = 0; + easy.es_Title = "Scalos"; + easy.es_TextFormat = "%s\n%ld %s %ld %s"; + easy.es_GadgetFormat = "%s"; + + if( SimpleRequest( NULL, &easy, NULL, ECTR_TYPE_WARNING, NULL, warning_body, num_files, files_body, num_drws, drawers_body, "OK|Cancel")) + { + if(SetupGUI()) + { + BOOL ready = FALSE; + for( i=0; ifib_Protection)) + { + NewList((struct List*)&list); + + list.lock = wbarg[i].wa_Lock;//Lock("RAM:",ACCESS_READ); + list.read = FALSE; + + DeleteDir(&list,dirPool); + + UnLock(wbarg[i].wa_Lock); + wbarg[i].wa_Lock=NULL; + + switch(Unprotect(name,TRUE,fib->fib_Protection)) + { + case 0: ready=TRUE;break; + case 2: if(!DeleteTheFile(name,TRUE))ready=TRUE; + } + } + } else PrintError(IoErr(),name,"OK"); + } + FreeVec(name); + } + DeletePool(dirPool); + } + } else + { + STRPTR dname=NameOfLock(wbarg[i].wa_Lock); + if(dname) + { + ULONG len=strlen(dname)+8+strlen(wbarg[i].wa_Name); + STRPTR name = (STRPTR)AllocVec(len,0); + if(name) + { + strcpy(name,dname); + AddPart(name,wbarg[i].wa_Name,len); + if(!DeleteTheFile(name,TRUE)) + { + ready=TRUE; + } + } + } + } + } + FreeGUI(); + } + } + + FreeScreen(); + } + } + + for( i=0; i +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +//#include + +#include +#include +#include +#include +#include +#include +#include +#include +//#include + +__stdargs void NewList( struct List *list ); + +const STRPTR VerString = "$VER: delete.module 1.0 "__AMIGADATE__; + +#define ECTR_TYPE_WARNING 0 + +IMPORT struct Library *GadToolsBase; +IMPORT struct Library *IntuitionBase; +IMPORT struct Library *SysBase; +IMPORT struct Library *GfxBase; +IMPORT struct Library *DOSBase; +IMPORT struct Library *UtilityBase; +IMPORT struct Library *LocaleBase; + +struct Library *IconBase; +//struct Library *ScalosBase; + +struct Catalog *Cat; + +struct Screen *scr; +struct DrawInfo *drinfo; +APTR visualinfo; +ULONG offx,offy,fonty,sizeheight; +ULONG wndwidth,wndheight,drawerwidth; + +struct Window *wnd; +struct Gadget *glist; + +BOOL glistAttached; +BOOL sizeVerify; +BOOL fromWB; + +const STATIC STRPTR engLocText[] = +{ + "Warning! You cannot get back what you delete!\nOK to delete:", + "_OK", + "_Cancel", + "Delete", + "file(s) and", + "drawer(s) (and there contents)?", + "Delete|Abort", + "Deleting...", + "Path", + "_Abort", + "Building Filelist...", + "Not Enough Memory", + "Error", + "couldn't be deleted", + "Skip it|Abort", + "is protected against deletion.\n\nDelete anywhy?", + "Delete|Skip it", + "Delete|DeleteAllProtect|Skip" +}; + +UWORD abort_key; + +STRPTR locText[18]; + +static void wbmain(struct WBStartup *wbs ); +STATIC BOOL CreateGadgets(void); + +//------------------------------------- +// Requester Support + +#ifdef __SASC + +STATIC VOID SR_LenFunc(VOID) +{ + __emit(0x5293); // ADDQ.L #1,(A3) +} + +STATIC VOID SR_CopyFunc(VOID) +{ + __emit(0x16c0); // MOVE.B D0,(A3)+ +} + +STATIC VOID SR_CopyFuncNoUnderscore(VOID) +{ + __emit(0xb03c); __emit(0x005f); // CMP.B #'_',D0 + __emit(0x6702); // BEQ.B .end(RTS) + __emit(0x16c0); // MOVE.B D0,(A3)+ +} + +STATIC VOID SR_Dummy(VOID) +{ +} + +#else + +VOID SR_LenFunc(VOID); +VOID SR_CopyFunc(VOID); +VOID SR_CopyFuncNoUnderscore(VOID); +VOID SR_Dummy(VOID); + +#endif + +//------------------------------------- +LONG SimpleRequestArgs( struct Window *wnd, struct EasyStruct *easy, ULONG *idcmp, STRPTR reqType, STRPTR fallBackType, APTR argList ) +{ + STRPTR gadgetText = (STRPTR)easy->es_GadgetFormat; + STRPTR newGadgetText; + ULONG len; + APTR nd; + + if( !gadgetText ) + { + DisplayBeep(NULL); + return 0; + } + + // Skip the text format + if( easy->es_TextFormat ) nd = RawDoFmt(easy->es_TextFormat,argList,(void(*)())SR_Dummy,NULL); + else nd = argList; + + // Calculate the length of the formatted GadgetText + len = 0; + RawDoFmt(easy->es_GadgetFormat,nd,(void(*)())SR_LenFunc,&len); + + newGadgetText = (STRPTR)AllocVec( len+2, 0 ); + if( !newGadgetText ) return EasyRequestArgs(wnd,easy,idcmp,argList); + else + { + LONG val; + struct EasyStruct es; + + // Format the gadgettext without underscores + RawDoFmt(easy->es_GadgetFormat,nd,(void(*)())SR_CopyFuncNoUnderscore,newGadgetText); + + es.es_StructSize = sizeof(struct EasyStruct); + es.es_Flags = easy->es_Flags; + es.es_Title = easy->es_Title; + es.es_TextFormat = easy->es_TextFormat; + es.es_GadgetFormat = newGadgetText; + + val = EasyRequestArgs(wnd,&es,idcmp,argList); + FreeVec( newGadgetText ); + return val; + } +} + +//------------------------------------- +LONG SimpleRequest( struct Window *wnd, struct EasyStruct *easy, ULONG *idcmp, STRPTR reqType, STRPTR fallBackType, APTR args,... ) +{ + return SimpleRequestArgs( wnd, easy, idcmp, reqType, fallBackType, &args ); +} +//------------------------------------- + +//------------------------------------- +VOID sprintf( STRPTR buf, STRPTR fmt,...) +{ + RawDoFmt(fmt,(&fmt+1),(void(*)())SR_CopyFunc,buf); +} + +//------------------------------------- +ULONG StrLen( const STRPTR str ) +{ + if( !str) return 0; + return strlen(str); +} +//------------------------------------- +STRPTR StrCopy( const STRPTR str ) +{ + STRPTR dst; + if( !str ) return NULL; + if( !*str) return NULL; + + dst = (STRPTR)AllocVec(strlen(str)+1,0); + if(dst) strcpy(dst,str); + return dst; +} +//------------------------------------- +STRPTR NameOfLock( BPTR lock ) +{ + STRPTR n; + BOOL again; + ULONG bufSize = 127; + if( !lock ) return NULL; + + do + { + again = FALSE; + if((n = (STRPTR)AllocVec(bufSize, 0x10000 ))) + { + if( NameFromLock( lock, n, bufSize-1 ) == DOSFALSE ) + { + if( IoErr() == ERROR_LINE_TOO_LONG ) + { + bufSize += 127; + again = TRUE; + } + FreeVec(n); + n = NULL; + } + } + } while(again); + + return n; +} +//------------------------------------- +STRPTR WBArg2String( struct WBArg *arg, LONG numArgs ) +{ + struct WBArgNode + { + struct MinNode node; + STRPTR dirname; + STRPTR filename; + }; + + struct MinList list; + ULONG len=0; + STRPTR buf; + UWORD i; + + NewList((struct List*)&list ); + + for( i=0; idirname = n; + node->filename = arg[i].wa_Name; + + len += StrLen( n )+StrLen(arg[i].wa_Name)+8; + AddTail((struct List*)&list, (struct Node*)node ); + } + } + + buf = (STRPTR)AllocVec(len+2,0x10000); + if(buf) + { + struct WBArgNode *node; + STRPTR bufPtr = buf; + + while(( node = (struct WBArgNode*)RemHead((struct List*)&list))) + { + STRPTR n = node->dirname; + if( !n ) continue; + + if( n[0] ) strcpy(bufPtr,n ); + AddPart(bufPtr,node->filename,len-(bufPtr-buf)); + + bufPtr+=strlen(bufPtr); + if(list.mlh_Head->mln_Succ) + *bufPtr++=' '; + + FreeVec(n); + FreeVec(node); + } + *bufPtr = 0; + } + return buf; +} +//------------------------------------- +STRPTR GetFullPath( const STRPTR drw, const STRPTR file ) +{ + ULONG length = StrLen(drw)+StrLen(file)+4; + STRPTR fp = (STRPTR)AllocVec( length+1,0 ); + if( fp ) + { + strcpy( fp, drw ); + + if( AddPart( fp, file, length )) return fp; + FreeVec( fp ); + } + return NULL; +} +//------------------------------------- +STRPTR BuildIconName( const STRPTR name ) +{ + ULONG namelen=strlen(name); + STRPTR infoname = AllocVec(namelen+8,0); + if(infoname) + { + strcpy(infoname,name); + strcpy(infoname+namelen,".info"); + } + return infoname; +} +//------------------------------------- +ULONG FindUnderscoredToLower(STRPTR text) +{ + ULONG c; + while(( c = *text++)) + { + if( c == '_' ) return ToLower(*text); + } + return 0; +} +//------------------------------------- + +ULONG deleteAllProt; + +//------------------------------------- +STATIC VOID InitStrings(void) +{ + ULONG i; + + if( LocaleBase ) + { + for(i=0; i<18; i++) + { + locText[i] = GetCatalogStr( Cat, i, engLocText[i]); + } + } else + { + for(i=0; i<18; i++) + { + locText[i] = engLocText[i]; + } + } + + abort_key = FindUnderscoredToLower(locText[9]); +} +//------------------------------------- + +//------------------------------------- +// Readsupport +struct DirList +{ + struct MinList list; + BPTR lock; + ULONG read; +}; + +struct DirNode +{ + struct MinNode node; + STRPTR name; + struct DirList list; + struct DirList *parentList; + ULONG icon; + ULONG prot; +}; + +struct FileNode +{ + struct MinNode node; + STRPTR name; + ULONG nameLen; + ULONG icon; +}; + +//------------------------------------- +STATIC ULONG PrintError( const ULONG ioerr, const STRPTR name, const STRPTR button ) +{ + struct EasyStruct easy; + char buffer[80]; + + easy.es_StructSize = sizeof(struct EasyStruct); + easy.es_Flags = 0; + easy.es_Title = (STRPTR) "Scalos"; + easy.es_TextFormat = (STRPTR) "%s %s\n%s"; + easy.es_GadgetFormat = (STRPTR) "%s"; + + Fault( ioerr, NULL, buffer,80); + + return (ULONG)SimpleRequest( NULL, &easy, NULL, ECTR_TYPE_WARNING, NULL, name, locText[13], buffer,button); +} +//------------------------------------- +STATIC BOOL IsDeletable( const STRPTR name, ULONG prot) +{ + if(( prot & FIBF_DELETE )) + { + BOOL del=deleteAllProt; + if( !deleteAllProt) + { + struct EasyStruct easy; + easy.es_StructSize = sizeof(struct EasyStruct); + easy.es_Flags = 0; + easy.es_Title = (STRPTR) "Scalos"; + easy.es_TextFormat = (STRPTR) "%s\n%s"; + easy.es_GadgetFormat = (STRPTR) "%s"; + + switch( SimpleRequest( NULL, &easy, NULL, ECTR_TYPE_WARNING, NULL, name, locText[15], locText[17])) + { + case 0: + break; + + case 1: + del=TRUE; + break; + + case 2: + del=deleteAllProt=TRUE; + break; + } + } + return del; + } + return TRUE; +} + +//------------------------------------- +STATIC ULONG Unprotect( const STRPTR name, const ULONG icon, ULONG prot) +{ + if(( prot & FIBF_DELETE )) + { + BOOL ok; + if(SetProtection(name,NULL) != DOSFALSE ) ok=TRUE; + else + { + LONG ioerr = IoErr(); + if( ioerr == ERROR_OBJECT_NOT_FOUND ) ok = TRUE; + else + { +// ok = FALSE; + return PrintError(ioerr,name, locText[14]); + } + } + + if(ok && icon ) + { + if( icon ) + { + STRPTR infoname = BuildIconName(name); + if(infoname) + { + if(SetProtection(infoname,NULL)== DOSFALSE ) + { + LONG ioerr = IoErr(); + if( ioerr == ERROR_OBJECT_NOT_FOUND ) /* ok = TRUE */; + else return PrintError(ioerr,name, locText[14]); + } + + FreeVec(infoname); + } + } + } + } + return 2; +} +//------------------------------------- +STATIC BOOL DeleteIcon(const STRPTR name, const ULONG update ) +{ + if(update) return DeleteDiskObject(name); + else + { + STRPTR iname = BuildIconName(name); + if(iname) + { + if(DeleteFile(iname)==DOSFALSE) return FALSE; + else return TRUE; + + FreeVec(iname); + } + } +} +//------------------------------------- +STATIC BOOL DeleteTheFile( const STRPTR name, const ULONG icon, const ULONG update ) +{ + BOOL goon = TRUE; + struct TextExtent te; + ULONG len = strlen(name); + ULONG nc; + LONG ioerr; + BOOL onlyicon = FALSE; + + struct IntuiMessage *imsg; + + Move(wnd->RPort,offx+2,offy+drinfo->dri_Font->tf_Baseline+2+fonty+1); + nc = TextFit(wnd->RPort,(const STRPTR)name+len,len,&te,NULL,-1,wndwidth-2*offx-4,fonty); + Text(wnd->RPort,(const STRPTR)name+len-nc,nc); + + if( te.te_Width < drawerwidth ) + { + EraseRect(wnd->RPort,wnd->RPort->cp_x,offy+3+fonty,offx+2+drawerwidth,offy+2+2*fonty); + } + + if(wnd) + { + while((imsg = (struct IntuiMessage*)GT_GetIMsg(wnd->UserPort))) + { + ULONG cl = imsg->Class; + + if( cl == IDCMP_SIZEVERIFY ) + { + if(glistAttached) RemoveGList( wnd, glist, -1 ); + glistAttached = FALSE; + GT_ReplyIMsg(imsg); + continue; + } + + GT_ReplyIMsg(imsg); + + switch(cl) + { + case IDCMP_GADGETUP: + case IDCMP_CLOSEWINDOW: + return FALSE; + break; + + case IDCMP_NEWSIZE: + if( !sizeVerify && glistAttached) + { + if( wndwidth == wnd->Width || wndheight != wnd->Height ) break; + } + + if(glistAttached) RemoveGList( wnd, glist, -1 ); + + if( wnd->Width < wndwidth ) RefreshWindowFrame(wnd); + + wndwidth = wnd->Width; + wndheight = wnd->Height; + EraseRect( wnd->RPort, wnd->BorderLeft, wnd->BorderTop+fonty+3, + wnd->Width-wnd->BorderRight-1, wnd->Height-wnd->BorderBottom-1 ); + if(CreateGadgets()) + { + AddGList( wnd, glist, -1,-1, NULL ); + RefreshGList( glist, wnd, NULL, -1 ); + glistAttached = TRUE; + SetFont(wnd->RPort,drinfo->dri_Font); + } + break; + } + } + } + + drawerwidth = te.te_Width; + + if(DeleteFile(name)==DOSFALSE) + { + ioerr = IoErr(); + if( ioerr == ERROR_OBJECT_NOT_FOUND) + { + if(!DeleteIcon(name,update)) + { + ioerr=IoErr(); + if(ioerr==ERROR_OBJECT_NOT_FOUND) ioerr=0; + } + else ioerr=0; + onlyicon=TRUE; + } else + { + if( ioerr == ERROR_OBJECT_IN_USE ) + { + if(DeleteFile(name)==DOSFALSE) ioerr = IoErr(); + else ioerr = 0; + } + } + } else ioerr=0; + + if( ioerr ) + { + switch( ioerr) + { + case ERROR_DELETE_PROTECTED: + { + BOOL del=deleteAllProt; + if( !deleteAllProt) + { + struct EasyStruct easy; + + easy.es_StructSize = sizeof(struct EasyStruct); + easy.es_Flags = 0; + easy.es_Title = (STRPTR) "Scalos"; + easy.es_TextFormat = (STRPTR) "%s\n%s"; + easy.es_GadgetFormat = (STRPTR) "%s"; + + switch( SimpleRequest( NULL, &easy, NULL, ECTR_TYPE_WARNING, NULL, name, locText[15], locText[17])) + { + case 0: + del=FALSE; + break; + + case 1: + del=TRUE; + break; + + case 2: + del=deleteAllProt=TRUE; + break; + } + + } + if(del) + { + BOOL ok = onlyicon; + if( !ok ) if(SetProtection(name,NULL) != DOSFALSE ) ok=TRUE; + + if(ok)//nlyicon || SetProtection(name,NULL) != DOSFALSE ) + { + BOOL error; + + if( icon || onlyicon ) + { + ULONG namelen=strlen(name); + STRPTR infoname = AllocVec(namelen+8,0); + error = TRUE; + if(infoname) + { + strcpy(infoname,name); + strcpy(infoname+namelen,".info"); + + if(SetProtection(infoname,NULL) != DOSFALSE ) + error = FALSE; + + FreeVec(infoname); + } else SetIoErr(103); + } else error=FALSE; + + if( !error ) + { + if( onlyicon ) + { + if(DeleteIcon(name,update)) return TRUE; + } else + { + if(DeleteFile(name) != DOSFALSE ) + { + if(icon) + { + if(DeleteIcon(name,update)) return TRUE; + } else return TRUE; + } + } + } + } + ioerr = IoErr(); + } else break; + } + + default: + return (BOOL)PrintError(ioerr,name, locText[14]); + break; + } + } else + { + if( icon ) + { + DeleteIcon(name,update); + } + } + + return goon; +} +//------------------------------------- +STATIC BOOL ReadInDir( struct DirList *list, APTR dirPool ) +{ + BOOL retval = TRUE; + STRPTR lockName; + + if( !list->lock ) + { +// Printf("No Lock!\n"); + return FALSE; + } + + if( list->read ) + { +// PutStr("Already read!\n"); + return TRUE; + } + + lockName = NameOfLock(list->lock); + if( lockName ) + { + ULONG lockSize = strlen(lockName); + APTR filePool = CreatePool( 0,4096,4096); + if( filePool ) + { + struct ExAllControl *eac; + eac = (struct ExAllControl*)AllocDosObject(DOS_EXALLCONTROL,NULL); + if( eac ) + { + struct ExAllData *ead; + ead = (struct ExAllData*)AllocVec( 1032, 0x10000 ); + if(ead) + { + LONG more; + struct MinList fileList; + NewList((struct List*)&fileList); + + eac->eac_LastKey = 0; + eac->eac_MatchString = NULL; + + list->read = TRUE; + + do + { + struct ExAllData *ed = ead; + more = ExAll( list->lock, ed, 1024, ED_PROTECTION, eac ); + if((!more) && (IoErr() != ERROR_NO_MORE_ENTRIES )) + { + retval = FALSE; + break; + } + + if( eac->eac_Entries ) + { + do + { + ULONG nlen = strlen(ed->ed_Name); + ULONG len = nlen+8+lockSize; + if( ed->ed_Type > 0 ) + { + STRPTR name = (STRPTR)AllocPooled(dirPool,len); + if(name) + { + struct DirNode *dir = (struct DirNode*)AllocPooled(dirPool,sizeof(struct DirNode)); + if( dir ) + { + strcpy(name,lockName); + AddPart(name,ed->ed_Name,len); + + dir->name = name; + dir->list.lock = Lock( name, ACCESS_READ); + dir->list.read = FALSE; + dir->parentList = list; + dir->icon = FALSE; + dir->prot = ed->ed_Prot; + NewList((struct List*)&dir->list); + + AddTail((struct List*)list, (struct Node*)dir); + } + } + } else + { + struct FileNode *file = (struct FileNode*)AllocPooled(filePool,sizeof(struct FileNode)); + if( file ) + { + STRPTR name = (STRPTR)AllocPooled(filePool,len); + if( name ) + { + strcpy(name,lockName); + AddPart(name,ed->ed_Name,len); + + file->name = name; + file->nameLen = strlen(name); + file->icon = FALSE; + AddTail((struct List*)&fileList, (struct Node*)file); + } + } + } + ed = ed->ed_Next; + } while(ed); + } + } while(more); + + ExAllEnd( list->lock, ead, 1024, ED_PROTECTION, eac ); + FreeVec(ead); + + if( !IsListEmpty((struct List*)&fileList)) + { + struct FileNode *node; + struct DirNode *dnode; + + node = (struct FileNode*)fileList.mlh_Head; + while(node->node.mln_Succ && retval) + { + // Icons aussortieren + if( node->nameLen > 4 ) + { + if( !Stricmp(".info",node->name+node->nameLen-5)) + { + struct FileNode *fnode = (struct FileNode*)fileList.mlh_Head; + BOOL iconfound=FALSE; + node->name[node->nameLen-5]=0; + while(fnode->node.mln_Succ) + { + if( fnode != node ) + { + if( !Stricmp(node->name,fnode->name)) + { + fnode->icon = iconfound = TRUE; + break; + } + } + fnode = (struct FileNode*)fnode->node.mln_Succ; + } + + if( !iconfound ) + { + dnode = (struct DirNode*)list->list.mlh_Head; + while(dnode->node.mln_Succ) + { + if( !Stricmp(node->name,dnode->name)) + { + dnode->icon = iconfound = TRUE; + break; + } + + dnode = (struct DirNode*)dnode->node.mln_Succ; + } + } + + if( iconfound ) + { + struct FileNode *tfn = node; + node = (struct FileNode*)node->node.mln_Succ; + Remove((struct Node*)tfn); + continue; + } + } + } + node = (struct FileNode*)node->node.mln_Succ; + } + + node = (struct FileNode*)fileList.mlh_Head; + while(node->node.mln_Succ && retval) + { + retval = DeleteTheFile(node->name,node->icon,FALSE); + node = (struct FileNode*)node->node.mln_Succ; + } + + dnode = (struct DirNode*)list->list.mlh_Head; + while(dnode->node.mln_Succ) + { + struct DirNode *help = dnode; + dnode = (struct DirNode*)dnode->node.mln_Succ; + if( !IsDeletable(help->name,help->prot)) + { + UnLock(help->list.lock); + Remove((struct Node*)help); + } + } + } + } + + FreeDosObject(DOS_EXALLCONTROL,eac); + } + DeletePool(filePool); + } + FreeVec(lockName); + } + return retval; +} +//------------------------------------- +STATIC BOOL DeleteDir( struct DirList *root, APTR dirPool ) +{ + struct DirList *cl = root; + BOOL goon = TRUE; + while(cl) + { + if(goon) + { + if(!ReadInDir(cl,dirPool)) goon=FALSE; + } + + if( !IsListEmpty((struct List*)cl)) + { + struct DirNode *cn = (struct DirNode*)cl->list.mlh_Head; + cl = (struct DirList*)&cn->list; + } else + { + if(cl != root ) + { + struct DirNode *cn = (struct DirNode*)(((ULONG*)cl)-3); + struct DirNode *ncn = (struct DirNode*)cn->node.mln_Succ; + + if( !ncn->node.mln_Succ ) + { + do + { + if( cl == root ) return TRUE; + + cl = cn->parentList; + if( !cl ) + { +// PutStr("Ready...\n"); + return TRUE; + } + + if( IsListEmpty((struct List*)cl)) + { + return FALSE; + } + + ncn = (struct DirNode*)RemHead((struct List*)cl); + cn = (struct DirNode*)(((ULONG*)cl)-3); + + if(ncn->list.lock) + { + UnLock(ncn->list.lock); + ncn->list.lock = NULL; + } + + if( goon ) + { + Unprotect(ncn->name,ncn->icon,ncn->prot); + goon = DeleteTheFile(ncn->name,ncn->icon,FALSE); + } + } while( IsListEmpty((struct List*)cl)); + if( !cl ) break; + + ncn = (struct DirNode*)cl->list.mlh_Head; + } else + { + Remove((struct Node*)cn); + + if(cn->list.lock) + { + UnLock(cn->list.lock); + cn->list.lock = NULL; + } + + if( goon ) + { + Unprotect(cn->name,cn->icon,cn->prot); + goon=DeleteTheFile(cn->name,cn->icon,FALSE); + } + } + + cl = (struct DirList*)&ncn->list; + } else return FALSE; + } + } + return FALSE; +} +//------------------------------------- + +//------------------------------------- +STATIC BOOL SetupScreen(void) +{ + if((scr = LockPubScreen(NULL))) + { + if((drinfo = GetScreenDrawInfo(scr))) + { + if((visualinfo = GetVisualInfoA(scr,NULL))) + { + Object *o = (Object*)NewObject( NULL, SYSICLASS, + SYSIA_DrawInfo,drinfo, + SYSIA_Which, SIZEIMAGE, + TAG_DONE); + if(o) + { + if(!GetAttr( IA_Height,o,&sizeheight)) sizeheight = 11; + DisposeObject(o); + } else sizeheight = 11; + return TRUE; + } + } + } + return FALSE; +} +//------------------------------------- +STATIC VOID FreeScreen(void) +{ + if( visualinfo ) FreeVisualInfo(visualinfo); + if( drinfo ) FreeScreenDrawInfo(scr,drinfo); + if( scr ) UnlockPubScreen(NULL,scr); +} +//------------------------------------- +STATIC VOID Render(void) +{ + Move(wnd->RPort,offx+2,offy+drinfo->dri_Font->tf_Baseline+2); + SetABPenDrMd(wnd->RPort,drinfo->dri_Pens[TEXTPEN],drinfo->dri_Pens[BACKGROUNDPEN],JAM2); + Text(wnd->RPort,locText[7],strlen(locText[7])); +} +//------------------------------------- +STATIC BOOL CreateGadgets(void) +{ + struct Gadget *g; + + if(glist) + { + FreeGadgets(glist); + glist = NULL; + } + + g = CreateContext( &glist ); + if( g ) + { + struct NewGadget ng; + + ng.ng_VisualInfo = visualinfo; + ng.ng_TextAttr = NULL; + ng.ng_GadgetText = locText[9]; + ng.ng_GadgetID = 1; + ng.ng_Flags = PLACETEXT_IN; + ng.ng_UserData = NULL; + ng.ng_LeftEdge = offx+2; + ng.ng_TopEdge = offy+2*fonty+4; + ng.ng_Width = wndwidth-2*ng.ng_LeftEdge; + ng.ng_Height = fonty+6; + + g = CreateGadget( BUTTON_KIND, g, &ng, + GT_Underscore,'_', + TAG_DONE); + if(g) return TRUE; + + FreeGadgets(glist); + glist=NULL; + } + return FALSE; +} +//------------------------------------- +STATIC VOID FreeGUI(void) +{ + if(wnd) CloseWindow(wnd); + if(glist) FreeGadgets(glist); +} +//------------------------------------- +STATIC BOOL SetupGUI(void) +{ + fonty = drinfo->dri_Font->tf_YSize; + offx = scr->WBorLeft; + offy = scr->WBorTop + fonty + 1; + + wndwidth = 300; + wndheight = offy + 3*fonty + sizeheight + 12; + + if( CreateGadgets()) + { + ULONG idcmp = IDCMP_CLOSEWINDOW|IDCMP_NEWSIZE|BUTTONIDCMP|IDCMP_VANILLAKEY; + if( sizeVerify ) idcmp |= IDCMP_SIZEVERIFY; + + wnd = OpenWindowTags( NULL, + WA_Left,(scr->Width-wndwidth)/2, + WA_Top,(scr->Height-wndheight)/2, + WA_Width, wndwidth, + WA_Height, wndheight, + WA_IDCMP, idcmp, + WA_DragBar,TRUE, + WA_SizeGadget, TRUE, + WA_DepthGadget,TRUE, + WA_CloseGadget, TRUE, + WA_Title,locText[3], + WA_RMBTrap, TRUE, + WA_Gadgets, glist, + WA_SizeBBottom,TRUE, + WA_MaxWidth,-1, + WA_Activate, TRUE, + WA_PubScreen,scr, + WA_NoCareRefresh,TRUE, + TAG_DONE ); + if( wnd ) + { + glistAttached = TRUE; + SetFont(wnd->RPort,drinfo->dri_Font); + Render(); + return TRUE; + } + glistAttached = FALSE; + } + FreeGUI(); + return FALSE; +} +//------------------------------------- + +//------------------------------------- +void main(void) +{ + wbmain(WBenchMsg); +} +//------------------------------------- +static void wbmain(struct WBStartup *wbs ) +{ + if( wbs->sm_NumArgs > 1 ) + { + if((IconBase = OpenLibrary("icon.library",37))) + { + LONG numArgs=wbs->sm_NumArgs-1; + struct WBArg *wbarg = wbs->sm_ArgList+1; + BPTR lock; + +// ScalosBase = OpenLibrary("scalos.library",0); + + lock = Lock("ENV:Scalos/NoSizeVerify",ACCESS_READ); + if(lock) + { + sizeVerify = FALSE; + UnLock(lock); +// lock = NULL; + } else sizeVerify = TRUE; + + + if(LocaleBase) Cat = OpenCatalogA( NULL, (STRPTR) "Scalos/Scalos_Delete.catalog",NULL); + InitStrings(); + + if( SetupScreen()) + { + struct EasyStruct easy; + + ULONG num_files=0; + ULONG num_drws=0; + ULONG i; + + for( i=0; ifib_Protection)) + { + NewList((struct List*)&list); + + list.lock = wbarg[i].wa_Lock;//Lock("RAM:",ACCESS_READ); + list.read = FALSE; + + DeleteDir(&list,dirPool); + + UnLock(wbarg[i].wa_Lock); + wbarg[i].wa_Lock=NULL; + + switch(Unprotect(name,TRUE,fib->fib_Protection)) + { + case 0: ready=TRUE;break; + case 2: if(!DeleteTheFile(name,TRUE,TRUE))ready=TRUE; + } + } + } else PrintError(IoErr(),name, (STRPTR) "OK"); + } + FreeVec(name); + } + DeletePool(dirPool); + } + } else + { + STRPTR dname=NameOfLock(wbarg[i].wa_Lock); + if(dname) + { + ULONG len=strlen(dname)+8+strlen(wbarg[i].wa_Name); + STRPTR name = (STRPTR)AllocVec(len,0); + if(name) + { + strcpy(name,dname); + AddPart(name,wbarg[i].wa_Name,len); + if(!DeleteTheFile(name,TRUE,TRUE)) + { + ready=TRUE; + } + } + } + } + } + FreeGUI(); + } + } + + FreeScreen(); + } + if( Cat ) CloseCatalog( Cat ); +// if( ScalosBase ) CloseLibrary(ScalosBase); + CloseLibrary(IconBase); + } + } +} +//------------------------------------- diff --git a/scalos/Modules/Delete.Gadtools/makefile b/scalos/Modules/Delete.Gadtools/makefile new file mode 100755 index 000000000..693e0a41d --- /dev/null +++ b/scalos/Modules/Delete.Gadtools/makefile @@ -0,0 +1,80 @@ +# Makefile for Delete.module (Gadtools) +# using GNU make and SAS/C +# $Date$ + +##################################################################### + +CHEADERS = +CC = sc +CFLAGS = optimize nostackcheck nochkabort strcons debug=s \ + idlen=128 strmer nover streq idir=sc:include/ idir=include: idir=//include +AS = phxass +AFLAGS = QUIET m=68020 linedebug opt=NRQB i=include: +LD = slink +LNFLAGS = quiet batch noicons stripdebug +LNDBFLAGS = quiet batch noicons addsym +LIBS = LIB:sc.lib LIB:debug.lib LIB:amiga.lib +CSTARTUP = LIB:c.o +OBJDIR = .sasobj + +.SUFFIXES: .asm + +############################################################# + +NAME = delete.module +DBGNAME = $(NAME).debug + +############################################################# + +all: $(NAME) $(DBGNAME) +# install +# clean + +##################################################################### + +CSRCS = Delete.c \ + + +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(CSRCS:%.c=$(OBJDIR)/%.o) + +##################################################################### + +$(NAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNFLAGS) + +$(DBGNAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNDBFLAGS) + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +############################################################# + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $< objectname $@ + +##################################################################### + +$(NAME) $(DBGNAME) : $(OBJS) + +##################################################################### + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(NAME)\033[0m\n' + @copy $(NAME) Scalos:modules/ + +##################################################################### + +# A little something to clean it all up +clean: + @printf '\033[32mCleanup: \033[31m\033[1m\n' + -@delete $(OBJS) $(NAME) $(DBGNAME) + @printf '\033[0m' + +##################################################################### + diff --git a/scalos/Modules/Delete.MUI/COPYING b/scalos/Modules/Delete.MUI/COPYING new file mode 100755 index 000000000..e23804491 --- /dev/null +++ b/scalos/Modules/Delete.MUI/COPYING @@ -0,0 +1,341 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/scalos/Modules/Delete.MUI/Release b/scalos/Modules/Delete.MUI/Release new file mode 100755 index 000000000..c3ccb0cf1 --- /dev/null +++ b/scalos/Modules/Delete.MUI/Release @@ -0,0 +1,51 @@ +/* Release */ +/* 24 Apr 2005 21:37:16 */ + +/* Generate an archive with full delete.module source code, + according to GPL. */ + +DirName = 'RAM:DeleteModule' +LHAName = 'RAM:Scalos-Module_Delete_Src' + +address command + +"version" + +say "Deleting old directory tree..." +"delete RAM:DeleteModule all QUIET" +say "Deleting old archive..." +"delete " || LHAName || ".lha quiet" + +"makedir RAM:DeleteModule" + +"makedir RAM:DeleteModule/source" +"mkdir -p RAM:DeleteModule/source/catalogs/Deutsch/Scalos" +"mkdir -p RAM:DeleteModule/source/catalogs/français/Scalos" + + +"copy #? RAM:DeleteModule/ all clone quiet" + +say "Removing CVS directories..." + +TempName = 't:xx123' +'list dir "RAM:DeleteModule/" all pat "CVS" nohead lformat "delete *"%f%n*" all quiet" to ' || TempName +'execute ' || TempName +'delete ' || TempName || ' quiet' + +say "Removing .obj directories..." + +TempName = 't:xx123' +'list dir "RAM:DeleteModule/" all pat ".objs" nohead lformat "delete *"%f%n*" all quiet" to ' || TempName +'execute ' || TempName +'delete ' || TempName || ' quiet' + +say "Removing .obj directories..." + +TempName = 't:xx123' +'list dir "RAM:DeleteModule/" all pat ".sasobj" nohead lformat "delete *"%f%n*" all quiet" to ' || TempName +'execute ' || TempName +'delete ' || TempName || ' quiet' + +'lha -r -e -x a ' || LHAName || ' RAM:DeleteModule/' + +lha t LHAName diff --git a/scalos/Modules/Delete.MUI/Source.info b/scalos/Modules/Delete.MUI/Source.info new file mode 100644 index 0000000000000000000000000000000000000000..3e6947e94e6ca4e8ec13e78d1b3d800d0e1a96bb GIT binary patch literal 1636 zcwWs_NpI6Y7nE z2E-x(DyA)>5*K=Gio+_lg2V~V+{!l-Cnc4TIB;M_*37*5zIku_JEa_UolJ^MfTcVE-g^S-aFkE0cg(F{=ev3Gh_$ItvU1ifgVe6%S`}}S;@0YG_ z>&8@su~lfCd1Dvd1bu^$xN@Lh=xsl{eO>Ehoa_H%To1Mnp1vfTNwO>_t%>o0QZi@R zrDUm?OXep=M<s7-U*0qrrZl9cSo)mDQ_igq$FMsH*{XvPQ$Dxhiw#6Ba<(cqY(h0V zwZHeH_8<6B``3QVn(O>X_xJh{-tfZm?j~CEqc+?rDIH!|oV@20o3X+4b~s>Grraf( z4JR3Px01D*F;`W2%rP*eVa9Z){6&Tx2T$ttX4_!F0>@O3`Cn~TdNtha#Ph4he4TiH z+nCRJu&^j8?F)DLye9+kodIhi?%sx*jjv5D^95liS_EhElpDB(nJU8lc$U|K@64eV zK_R%ffhBN%6}LpwwZO% \n +;\n\33b\33c\0338ScalosDelete\0330\33n\n\ +; Copyright 1999 Chris Page, \n\ +; The World Foundry LLC \n\n\ +; Contact: \33ichris \n +; +MSG_ABOUT_BODY +\n\33cDieses Program is Freie Software; you can\n\ + redistribute it and/or modify it under the \n\ +terms of the GNU General Public License as\n\ +published by the Free Software Foundation;\n\ +either version 2 of the License, or (at\n\ +your option) any later version.\n\n\ +This program is distributed in the hope\n\ +that it will be useful,but WITHOUT ANY\n\ +WARRANTY; without even the implied\n\ + warranty of MERCHANTABILITY or FITNESS FOR \n\ +A PARTICULAR PURPOSE. See the GNU General\n\ +Public License for more details.\n\n\ +You should have received a copy of the GNU\n\ +General Public License along with this\n\ +program; if not, write to\n\n\ +Free Software Foundation, Inc.,\n\ +59 Temple Place,\n\ +Suite 330,\n\ +Boston, MA\n\ +02111-1307\n\ +USA\n\n\ +Or email the original author +;\n\33cThis program is free software; you can\n\ +; redistribute it and/or modify it under the \n\ +;terms of the GNU General Public License as\n\ +;published by the Free Software Foundation;\n\ +;either version 2 of the License, or (at\n\ +;your option) any later version.\n\n\ +;This program is distributed in the hope\n\ +;that it will be useful,but WITHOUT ANY\n\ +;WARRANTY; without even the implied\n\ +; warranty of MERCHANTABILITY or FITNESS FOR \n\ +;A PARTICULAR PURPOSE. See the GNU General\n\ +;Public License for more details.\n\n\ +;You should have received a copy of the GNU\n\ +;General Public License along with this\n\ +;program; if not, write to\n\n\ +;Free Software Foundation, Inc.,\n\ +;59 Temple Place,\n\ +;Suite 330,\n\ +;Boston, MA\n\ +;02111-1307\n\ +;USA\n\n\ +;Or email the original author +; +; +MSGID_UNDO_OK +Kann Rückgängig gemacht werden, da \033bPapierkorb benutzen\033n eingeschaltet +;Undo possible since \033bUse trashcan\033n is enabled +; +; +MSGID_UNDO_NOT_POSSIBLE +Rückgängigmachen \033inicht\033n möglich solange \033bPapierkorb benutzen\033n ausgeschaltet +;Undo \033inot\033n possible unless \033bUse trashcan\033n is enabled +; +; +MSG_GAD_OK_ABORT +*_Ok|Abbrechen +;*_Ok|Abort +; +;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Projekt +;Project +; +; +MSGID_MENU_PROJECT_ABOUT +Über... +;About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Über MUI... +;About MUI... +; +; +MSGID_MENU_PROJECT_QUIT +Beenden +;Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Delete.module kann nicht gestartet werden +;Delete.module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Wiederholen|Beenden +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\ +Die Klasse ist nicht installiert. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Sie haben momentan Version v%lu.%lu installiert und\n\ +sollten die Klasse daher aktualisieren! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Version %lu.%lu wird momentan von einer anderen Anwendung\n\ +verwendet. Wenn sie die benötigte Version installiert haben,\n\ +schließen sie alle MUI Programme und probieren es erneut. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; diff --git a/scalos/Modules/Delete.MUI/Source/Catalogs/deutsch/Scalos/config.mk b/scalos/Modules/Delete.MUI/Source/Catalogs/deutsch/Scalos/config.mk new file mode 100755 index 000000000..b60748fa3 --- /dev/null +++ b/scalos/Modules/Delete.MUI/Source/Catalogs/deutsch/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = deutsch + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = german + +else + +############################################################################### +# AmigaOS and AROS + +LANG = deutsch + +endif +endif diff --git a/scalos/Modules/Delete.MUI/Source/Catalogs/deutsch/Scalos/makefile b/scalos/Modules/Delete.MUI/Source/Catalogs/deutsch/Scalos/makefile new file mode 100644 index 000000000..4b1f87f13 --- /dev/null +++ b/scalos/Modules/Delete.MUI/Source/Catalogs/deutsch/Scalos/makefile @@ -0,0 +1,14 @@ +# makefile for Delete.module (translated Texts : deutsch) +# $Date$ +# $Revision$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mdeutsch\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +Delete.catalog : Delete.ct ../../../Delete.cd + +All: Delete.catalog diff --git a/scalos/Modules/Delete.MUI/Source/Catalogs/deutsch/Scalos/makefile-new b/scalos/Modules/Delete.MUI/Source/Catalogs/deutsch/Scalos/makefile-new new file mode 100644 index 000000000..71ac39988 --- /dev/null +++ b/scalos/Modules/Delete.MUI/Source/Catalogs/deutsch/Scalos/makefile-new @@ -0,0 +1,31 @@ +# makefile for Delete.module (translated Texts : deutsch) +# $Date: 2011-07-24 10:11:00 +0200 (So, 24. Jul 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = Delete + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + + +all: $(CATNAME).catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git "a/scalos/Modules/Delete.MUI/Source/Catalogs/fran\303\247ais/Scalos/Delete.ct" "b/scalos/Modules/Delete.MUI/Source/Catalogs/fran\303\247ais/Scalos/Delete.ct" new file mode 100755 index 000000000..d6b769037 --- /dev/null +++ "b/scalos/Modules/Delete.MUI/Source/Catalogs/fran\303\247ais/Scalos/Delete.ct" @@ -0,0 +1,427 @@ +; Delete.ct +; $Date$ +; $Revision$ +; $Id$ +## version $VER: Delete.catalog 1.0 (27.11.06) +## codeset 0 +## language français +; +;#arrayopts static __far +; +MSG_APP_TITLE +Delete.module +;Delete.module +; +MSG_APP_DESC +Module Delete.module pour Scalos +;Replacement for Scalos Delete.module +; +MSG_WIN_TITLE +Effacer +;Delete +; +MSG_ASL_TITLE +Choix de l'emplacement de la corbeille +;Select Trashcan directory +; +MSG_PAGES_FILES +Fichiers +;Files +; +MSG_PAGES_PREFS +Préferences +;Preferences +; +MSG_LABEL_TRASH +Utiliser la corbeille ? +;Use trashcan? +; +MSG_LABEL_DIRS +Confirmer l'éffacement des répertoires ? +;Confirm dir delete? +; +MSG_LABEL_FILES +Confirmer l'éffacement des fichiers ? +;Confirm file delete? +; +MSG_LABEL_QUIET +Lancement rapide +;Quiet start +; +MSG_LABEL_TLOC +Emplacement de la corbeille +;Trashcan Location +; +MSG_LABEL_INFO +%ld%% fait +;Done %ld%% +; +MSG_LABEL_PROG +Sélectionnés : %ld fichiers [%ld bytes], %ld répertoires +;Selected: %ld files [%ld bytes], %ld directories +; +MSG_LABEL_VERS +Version : +;Version: +; +MSG_LABEL_COMP +Compilé : +;Compiled: +; +MSG_BUTTON_FULL +Détail +;Details +; +MSG_BUTTON_DEL +Effacer +;Delete +; +MSG_BUTTON_ABT +A propos... +;About... +; +MSG_BUTTON_CAN +Annuler +;Cancel +; +MSG_BUTTON_STOP +Interrompre ! +;STOP! +; +MSG_BUTTON_AMUI +A propos de MUI... +;About MUI... +; +MSG_BUTTON_SAVE +Sauver +;Save +; +MSG_BUTTON_USE +Utiliser +;Use +; +MSG_BUTTON_REST +Restaurer +;Restore +; +MSG_KEY_DETAILS +d +;e +; +MSG_KEY_TRASH +c +;t +; +MSG_KEY_DIRS +r +;o +; +MSG_KEY_FILES +f +;n +; +MSG_KEY_QUIET +q +;q +; +MSG_KEY_TLOC +| +;l +; +MSG_KEY_SAVE +s +;v +; +MSG_KEY_USE +u +;u +; +MSG_KEY_REST +t +;r +; +MSG_KEY_DELETE +e +;d +; +MSG_KEY_ABOUT +o +;a +; +MSG_KEY_CANCEL +a +;c +; +MSG_KEY_STOP +i +;s +; +MSG_KEY_AMUI +m +;m +; +MSG_HELP_TRASH +\33cFichiers sont déplaçès vers\nSYS:Trashcan\nplutôt que d'être\ncompletement supprimés +;\33cFiles are moved to\nSYS:Trashcan\nrather than being\nremoved completely +; +MSG_HELP_DIRS +\33cSi sélectionné, vous devez confirmer\nl'éffacement d'un répertoire +;\33cIf set, you must confirm that\na directory should be deleted +; +MSG_HELP_FILES +\33cSi sélectionné, vous devez confirmer\nà chaque fois l'éffacement d'un fichier +;\33cIf set, you must confirm every\nfile delete operation +; +MSG_HELP_QUIET +\33cSi sélectionné, la fenêtre d'information du programme\nne s'ouvrira pas au démarrage +;\33cIf set, the about window is not\nshown when the program starts +; +MSG_HELP_TLOC +\33cEmplacement de la corbeille à utiliser\nsi l'option \"Utilser la corbeille\" est sélectionnée +;\33cLocation of the trashcan used\nif \"Use Trashcan\" is set +; +MSG_LVT_NAME +\33bNom\33n +;\33bName\33n +; +MSG_LVT_SIZE +Taille +;Size +; +MSG_LVT_DATE +Date +;Date +; +MSG_LVT_TIME +Heure +;Time +; +MSG_ERROR_TITLE +Delete.module: Erreur +;Delete module error +; +MSG_WARN_TITLE +Delete.module: Alerte +;Delete module warning +; +MSG_REQ_TITLE +Requête de delete.module +;Delete module request +; +MSG_GAD_OK +*_D'accord +;*_Ok +; +MSG_GAD_NOYES +_Oui|*_Non +;_Yes|*_No +; +MSG_GAD_PROTECT +_Oui|_Tous les fichiers|*_non +;_Yes|_All files|*_No +; +MSG_BODY_NOFILES +\33cAucun fichier n'a été sélectionner !\n\nOpération annulée +;\33cNo files have been selected!\n\nOperation aborted +; +MSG_BODY_NOLIST +\33cLa création des listes internes a échouée\n\nOpération annulée +;\33cUnable to create internal lists\n\nOperation aborted +; +MSG_BODY_VOLUME +\33cDetection d'une tentative d'éffacement du volume\n\33b%s\33n\nEtes-vous \33bsûr\33n de vouloir faire çà ?!? +;\33cDetected an attempt to delete volume\n\33b%s\33n\nAre you \33bsure\33n you want to do this?!? +; +MSG_BODY_CFILE +\33cEtes-vous sûr de voulir éffacer le fichier\n%s +;\33cAre you sure you want to delete file\n%s +; +MSG_BODY_BUFERR +\33cImpossible de copier\n%s\nvers la corbeille\nPas assez d'espace libre.\nContinuer à éffacer le fichier ? +;\33cUnable to copy\n%s\nto trashcan\nOut of buffer space.\nContinue to delete the file? +; +MSG_BODY_COPYFAIL +\33cImpossible de copier\n%s\nvers la corbeille\nErreur survennue lors de l'écriture vers la corbeille\nContinuer à éffacer le fichier ? +;\33cUnable to copy\n%s\nto trashcan\nError writing to trashcan\nContinue to delete the file? +; +MSG_BODY_NOICON +\33cImposible déffacer l'icône\n%s +;\33cUnable to delete icon\n%s +; +MSG_BODY_CDIR +\33cEtes-vous sûr de vouloir éffacer le répertoire\n%s +;\33cAre you sure you want to delete directory\n%s +; +MSG_BODY_BADTD +\33cImpossible de créer le répertoire\ndans la corbeille.\nContinuer ? +;\33cUnable to create directory\nin Trashcan.\nContinue? +; +MSG_BODY_NOSCAN +\33cImpossible d'analyser le contenu du répertoire\nOpération sur répertoire annulée +;\33cUnable to scan directory\nDirectory aborted +; +MSG_BODY_PROTECT +\33c%s\nest protégé contre l'éffacement\nRetirer la protection ? +;\33c%s\nis protected from deletion\nRemove the protection? +; +MSG_BODY_NODEL +\33c%s\nn'a pas été supprimé +;\33c%s\nnot deleted +; +MSG_BODY_COPYING +Copie de %s vers la corbeille +;Copying %s to trashcan +; +MSG_BODY_REMOVE +Suppresion de %s +;Removing %s +; +MSG_BODY_SCAN +Analyse de %s +;Scanning %s +; +MSG_BODY_DETAIL +\33c\0338ATTENTION\0330\nCette opération peut prendre beaucoup de temps\net ne peut être annulée. Continuer ? +;\33c\0338WARNING\0330\nThis operation may take a long time\nto complete and may not be\naborted. Continue? +; +MSG_ABOUT_HEAD +\n\33b\33c\0338ScalosDelete\0330\33n\n\ + Tout droit réservé 1999 Chris Page, \n\ + The World Foundry LLC \n\n\ + Contact : \33ichris \n +; +;\n\33b\33c\0338ScalosDelete\0330\33n\n\ +; Copyright 1999 Chris Page, \n\ +; The World Foundry LLC \n\n\ +; Contact: \33ichris \n +; +MSG_ABOUT_BODY +\n\33cThis program is free software; you can\n\ + redistribute it and/or modify it under the \n\ +terms of the GNU General Public License as\n\ +published by the Free Software Foundation;\n\ +either version 2 of the License, or (at\n\ +your option) any later version.\n\n\ +This program is distributed in the hope\n\ +that it will be useful,but WITHOUT ANY\n\ +WARRANTY; without even the implied\n\ + warranty of MERCHANTABILITY or FITNESS FOR \n\ +A PARTICULAR PURPOSE. See the GNU General\n\ +Public License for more details.\n\n\ +You should have received a copy of the GNU\n\ +General Public License along with this\n\ +program; if not, write to\n\n\ +Free Software Foundation, Inc.,\n\ +59 Temple Place,\n\ +Suite 330,\n\ +Boston, MA\n\ +02111-1307\n\ +USA\n\n\ +Or email the original author +; +;\n\33cThis program is free software; you can\n\ +; redistribute it and/or modify it under the \n\ +;terms of the GNU General Public License as\n\ +;published by the Free Software Foundation;\n\ +;either version 2 of the License, or (at\n\ +;your option) any later version.\n\n\ +;This program is distributed in the hope\n\ +;that it will be useful,but WITHOUT ANY\n\ +;WARRANTY; without even the implied\n\ +; warranty of MERCHANTABILITY or FITNESS FOR \n\ +;A PARTICULAR PURPOSE. See the GNU General\n\ +;Public License for more details.\n\n\ +;You should have received a copy of the GNU\n\ +;General Public License along with this\n\ +;program; if not, write to\n\n\ +;Free Software Foundation, Inc.,\n\ +;59 Temple Place,\n\ +;Suite 330,\n\ +;Boston, MA\n\ +;02111-1307\n\ +;USA\n\n\ +;Or email the original author +; +;+++translateme+++ +MSGID_UNDO_OK +Undo possible since \033bUtiliser la corbeille\033n is enabled +;Undo possible since \033bUse trashcan\033n is enabled +; +;+++translateme+++ +MSGID_UNDO_NOT_POSSIBLE +Undo \033inot\033n possible unless \033bUtiliser la corbeille\033n is enabled +;Undo \033inot\033n possible unless \033bUse trashcan\033n is enabled +; +;+++translateme+++ +MSG_GAD_OK_ABORT +*_Ok|Abort +;*_Ok|Abort +; +;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Projet +; Project +; +; +MSGID_MENU_PROJECT_ABOUT +About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI +A propos de MUI... +; About MUI... +; +; +MSGID_MENU_PROJECT_QUIT +Quitter +; Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; Q +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Le lancement de Delete.module a échoué +;Delete.module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Recommençer | Quitter +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +Celle-ci n'est pas installée. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +\n\ +La version installée est V%lu.%lu, installez-en une plus récente s'il vous plaît ! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +%lu.%lu est actuellement utilisée par d'autres applications.\n\ +\n\ +Une fois la version requise installée,\n\ +fermez tous les programmes MUI, soyez sûr que l'ancienne classe\n\ +ne soit plus présente dans la mémoire puis, essayez de nouveau. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; diff --git "a/scalos/Modules/Delete.MUI/Source/Catalogs/fran\303\247ais/Scalos/config.mk" "b/scalos/Modules/Delete.MUI/Source/Catalogs/fran\303\247ais/Scalos/config.mk" new file mode 100755 index 000000000..1b4cabf68 --- /dev/null +++ "b/scalos/Modules/Delete.MUI/Source/Catalogs/fran\303\247ais/Scalos/config.mk" @@ -0,0 +1,40 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = français + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = french + +else + +############################################################################### +# AmigaOS and AROS + +LANG = français + +endif +endif diff --git "a/scalos/Modules/Delete.MUI/Source/Catalogs/fran\303\247ais/Scalos/makefile" "b/scalos/Modules/Delete.MUI/Source/Catalogs/fran\303\247ais/Scalos/makefile" new file mode 100644 index 000000000..837bc05ff --- /dev/null +++ "b/scalos/Modules/Delete.MUI/Source/Catalogs/fran\303\247ais/Scalos/makefile" @@ -0,0 +1,14 @@ +# makefile for Delete.module (translated Texts : français) +# $Date$ +# $Revision$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mfrançais\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +Delete.catalog : Delete.ct ../../../Delete.cd + +All: Delete.catalog diff --git "a/scalos/Modules/Delete.MUI/Source/Catalogs/fran\303\247ais/Scalos/makefile-new" "b/scalos/Modules/Delete.MUI/Source/Catalogs/fran\303\247ais/Scalos/makefile-new" new file mode 100644 index 000000000..992967b43 --- /dev/null +++ "b/scalos/Modules/Delete.MUI/Source/Catalogs/fran\303\247ais/Scalos/makefile-new" @@ -0,0 +1,30 @@ +# makefile for Delete.module (translated Texts : français) +# $Date: 2011-07-24 10:11:00 +0200 (So, 24. Jul 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = Delete + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Modules/Delete.MUI/Source/Catalogs/sample/Scalos/Delete.ct b/scalos/Modules/Delete.MUI/Source/Catalogs/sample/Scalos/Delete.ct new file mode 100755 index 000000000..8fc7bc150 --- /dev/null +++ b/scalos/Modules/Delete.MUI/Source/Catalogs/sample/Scalos/Delete.ct @@ -0,0 +1,323 @@ +## version $VER: Delete.catalog 1.RR (DD.MM.1998) +## codeset 0s +## language english +; +;#arrayopts static __far +; +MSG_APP_TITLE +Delete.module +; +MSG_APP_DESC +Replacement for Scalos Delete.module +; +MSG_WIN_TITLE +Delete +; +MSG_ASL_TITLE +Select Trashcan directory +; +MSG_PAGES_FILES +Files +; +MSG_PAGES_PREFS +Preferences +; +MSG_LABEL_TRASH +Use trashcan? +; +MSG_LABEL_DIRS +Confirm dir delete? +; +MSG_LABEL_FILES +Confirm file delete? +; +MSG_LABEL_QUIET +Quiet start +; +MSG_LABEL_TLOC +Trashcan Location +; +MSG_LABEL_INFO +Done %ld%% +; +MSG_LABEL_PROG +Selected: %ld files [%ld bytes], %ld directories +; +MSG_LABEL_VERS +Version: +; +MSG_LABEL_COMP +Compiled: +; +MSG_BUTTON_FULL +Details +; +MSG_BUTTON_DEL +Delete +; +MSG_BUTTON_ABT +About +; +MSG_BUTTON_CAN +Cancel +; +MSG_BUTTON_STOP +STOP! +; +MSG_BUTTON_AMUI +About MUI +; +MSG_BUTTON_SAVE +Save +; +MSG_BUTTON_USE +Use +; +MSG_BUTTON_REST +Restore +; +MSG_KEY_DETAILS +e +; +MSG_KEY_TRASH +t +; +MSG_KEY_DIRS +o +; +MSG_KEY_FILES +n +; +MSG_KEY_QUIET +q +; +MSG_KEY_TLOC +l +; +MSG_KEY_SAVE +v +; +MSG_KEY_USE +u +; +MSG_KEY_REST +r +; +MSG_KEY_DELETE +d +; +MSG_KEY_ABOUT +a +; +MSG_KEY_CANCEL +c +; +MSG_KEY_STOP +s +; +MSG_KEY_AMUI +m +; +MSG_HELP_TRASH +\33cFiles are moved to\nSYS:Trashcan\nrather than being\nremoved completely +; +MSG_HELP_DIRS +\33cIf set, you must confirm that\na directory should be deleted +; +MSG_HELP_FILES +\33cIf set, you must confirm every\nfile delete operation +; +MSG_HELP_QUIET +\33cIf set, the about window is not\nshown when the program starts +; +MSG_HELP_TLOC +\33cLocation of the trashcan used\nif \"Use Trashcan\" is set +; +MSG_LVT_NAME +\33bName\33n +; +MSG_LVT_SIZE +Size +; +MSG_LVT_DATE +Date +; +MSG_LVT_TIME +Time +; +MSG_ERROR_TITLE +Delete module error +; +MSG_WARN_TITLE +Delete module warning +; +MSG_REQ_TITLE +Delete module request +; +MSG_GAD_OK +*_Ok +; +MSG_GAD_NOYES +_Yes|*_No +; +MSG_GAD_PROTECT +_Yes|_All files|*_No +; +MSG_BODY_NOFILES +\33cNo files have been selected!\n\nOperation aborted +; +MSG_BODY_NOLIST +\33cUnable to create internal lists\n\nOperation aborted +; +MSG_BODY_VOLUME +\33cDetected an attempt to delete volume\n\33b%s\33n\nAre you \33bsure\33n you want to do this?!? +; +MSG_BODY_CFILE +\33cAre you sure you want to delete file\n%s +; +MSG_BODY_BUFERR +\33cUnable to copy\n%s\nto trashcan\nOut of buffer space.\nContinue to delete the file? +; +MSG_BODY_COPYFAIL +\33cUnable to copy\n%s\nto trashcan\nError writing to trashcan\nContinue to delete the file? +; +MSG_BODY_NOICON +\33cUnable to delete icon\n%s +; +MSG_BODY_CDIR +\33cAre you sure you want to delete directory\n%s +; +MSG_BODY_BADTD +\33cUnable to create directory\nin Trashcan.\nContinue? +; +MSG_BODY_NOSCAN +\33cUnable to scan directory\nDirectory aborted +; +MSG_BODY_PROTECT +\33c%s\nis protected from deletion\nRemove the protection? +; +MSG_BODY_NODEL +\33c%s\nnot deleted +; +MSG_BODY_COPYING +Copying %s to trashcan +; +MSG_BODY_REMOVE +Removing %s +; +MSG_BODY_SCAN +Scanning %s +; +MSG_BODY_DETAIL +\33c\0338WARNING\0330\nThis operation may take a long time\nto complete and may not be\naborted. Continue? +; +MSG_ABOUT_HEAD +\n\33b\33c\0338ScalosDelete\0330\33n\n\ + Copyright 1999 Chris Page, \n\ + The World Foundry LLC \n\n\ + Contact: \33ichris \n +; +MSG_ABOUT_BODY +\n\33cThis program is free software; you can\n\ + redistribute it and/or modify it under the \n\ +terms of the GNU General Public License as\n\ +published by the Free Software Foundation;\n\ +either version 2 of the License, or (at\n\ +your option) any later version.\n\n\ +This program is distributed in the hope\n\ +that it will be useful,but WITHOUT ANY\n\ +WARRANTY; without even the implied\n\ + warranty of MERCHANTABILITY or FITNESS FOR \n\ +A PARTICULAR PURPOSE. See the GNU General\n\ +Public License for more details.\n\n\ +You should have received a copy of the GNU\n\ +General Public License along with this\n\ +program; if not, write to\n\n\ +Free Software Foundation, Inc.,\n\ +59 Temple Place,\n\ +Suite 330,\n\ +Boston, MA\n\ +02111-1307\n\ +USA\n\n\ +Or email the original author +; +;+++translateme+++ +MSGID_UNDO_OK +Undo possible since \033bUse trashcan\033n is enabled +;Undo possible since \033bUse trashcan\033n is enabled +; +;+++translateme+++ +MSGID_UNDO_NOT_POSSIBLE +Undo \033inot\033n possible unless \033bUse trashcan\033n is enabled +;Undo \033inot\033n possible unless \033bUse trashcan\033n is enabled +; +;+++translateme+++ +MSG_GAD_OK_ABORT +*_Ok|Abort +;*_Ok|Abort +; +;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Project +; +; +MSGID_MENU_PROJECT_ABOUT +About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI +About MUI... +; +; +MSGID_MENU_PROJECT_QUIT +Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Delete.module Prefs startup failed +;Delete.module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Try again|Quit +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; diff --git a/scalos/Modules/Delete.MUI/Source/Delete.cd b/scalos/Modules/Delete.MUI/Source/Delete.cd new file mode 100755 index 000000000..62c14cb54 --- /dev/null +++ b/scalos/Modules/Delete.MUI/Source/Delete.cd @@ -0,0 +1,312 @@ +; Delete.cd +; $Date$ +; $Revision$ +; +; version $VER: Information.catalog 40.1 (20 Feb 2005 21:03:45) +; codeset 0s +; language english +; +;#arrayopts static __far +; +; +MSG_APP_TITLE (1//) +Delete.module +; +MSG_APP_DESC (//) +Replacement for Scalos Delete.module +; +MSG_WIN_TITLE (//) +Delete +; +MSG_ASL_TITLE (//) +Select Trashcan directory +; +MSG_PAGES_FILES (//) +Files +; +MSG_PAGES_PREFS (//) +Preferences +; +MSG_LABEL_TRASH (//) +Use trashcan? +; +MSG_LABEL_DIRS (//) +Confirm dir delete? +; +MSG_LABEL_FILES (//) +Confirm file delete? +; +MSG_LABEL_QUIET (//) +Quiet start +; +MSG_LABEL_TLOC (//) +Trashcan Location +; +MSG_LABEL_INFO (//) +Done %ld%% +; +MSG_LABEL_PROG (//) +Selected: %ld files [%ld bytes], %ld directories +; +MSG_LABEL_VERS (//) +Version: +; +MSG_LABEL_COMP (//) +Compiled: +; +MSG_BUTTON_FULL (//) +Details +; +MSG_BUTTON_DEL (//) +Delete +; +MSG_BUTTON_ABT (//) +About... +; +MSG_BUTTON_CAN (//) +Cancel +; +MSG_BUTTON_STOP (//) +STOP! +; +MSG_BUTTON_AMUI (//) +About MUI... +; +MSG_BUTTON_SAVE (//) +Save +; +MSG_BUTTON_USE (//) +Use +; +MSG_BUTTON_REST (//) +Restore +; +MSG_KEY_DETAILS (//) +e +; +MSG_KEY_TRASH (//) +t +; +MSG_KEY_DIRS (//) +o +; +MSG_KEY_FILES (//) +n +; +MSG_KEY_QUIET (//) +q +; +MSG_KEY_TLOC (//) +l +; +MSG_KEY_SAVE (//) +v +; +MSG_KEY_USE (//) +u +; +MSG_KEY_REST (//) +r +; +MSG_KEY_DELETE (//) +d +; +MSG_KEY_ABOUT (//) +a +; +MSG_KEY_CANCEL (//) +c +; +MSG_KEY_STOP (//) +s +; +MSG_KEY_AMUI (//) +m +; +MSG_HELP_TRASH (//) +\33cFiles are moved to\nSYS:Trashcan\nrather than being\nremoved completely +; +MSG_HELP_DIRS (//) +\33cIf set, you must confirm that\na directory should be deleted +; +MSG_HELP_FILES (//) +\33cIf set, you must confirm every\nfile delete operation +; +MSG_HELP_QUIET (//) +\33cIf set, the about window is not\nshown when the program starts +; +MSG_HELP_TLOC (//) +\33cLocation of the trashcan used\nif \"Use Trashcan\" is set +; +MSG_LVT_NAME (//) +\33bName\33n +; +MSG_LVT_SIZE (//) +Size +; +MSG_LVT_DATE (//) +Date +; +MSG_LVT_TIME (//) +Time +; +MSG_ERROR_TITLE (//) +Delete module error +; +MSG_WARN_TITLE (//) +Delete module warning +; +MSG_REQ_TITLE (//) +Delete module request +; +MSG_GAD_OK (//) +*_Ok +; +MSG_GAD_NOYES (//) +_Yes|*_No +; +MSG_GAD_PROTECT (//) +_Yes|_All files|*_No +; +MSG_BODY_NOFILES (//) +\33cNo files have been selected!\n\nOperation aborted +; +MSG_BODY_NOLIST (//) +\33cUnable to create internal lists\n\nOperation aborted +; +MSG_BODY_VOLUME (//) +\33cDetected an attempt to delete volume\n\33b%s\33n\nAre you \33bsure\33n you want to do this?!? +; +MSG_BODY_CFILE (//) +\33cAre you sure you want to delete file\n%s +; +MSG_BODY_BUFERR (//) +\33cUnable to copy\n%s\nto trashcan\nOut of buffer space.\nContinue to delete the file? +; +MSG_BODY_COPYFAIL (//) +\33cUnable to copy\n%s\nto trashcan\nError writing to trashcan\nContinue to delete the file? +; +MSG_BODY_NOICON (//) +\33cUnable to delete icon\n%s +; +MSG_BODY_CDIR (//) +\33cAre you sure you want to delete directory\n%s +; +MSG_BODY_BADTD (//) +\33cUnable to create directory\nin Trashcan.\nContinue? +; +MSG_BODY_NOSCAN (//) +\33cUnable to scan directory\nDirectory aborted +; +MSG_BODY_PROTECT (//) +\33c%s\nis protected from deletion\nRemove the protection? +; +MSG_BODY_NODEL (//) +\33c%s\nnot deleted +; +MSG_BODY_COPYING (//) +Copying %s to trashcan +; +MSG_BODY_REMOVE (//) +Removing %s +; +MSG_BODY_SCAN (//) +Scanning %s +; +MSG_BODY_DETAIL (//) +\33c\0338WARNING\0330\nThis operation may take a long time\nto complete and may not be\naborted. Continue? +; +MSG_ABOUT_HEAD (//) +\n\33b\33c\0338ScalosDelete\0330\33n\n\ + Copyright 1999 Chris Page, \n\ + The World Foundry LLC \n\n\ + Contact: \33ichris \n +; +MSG_ABOUT_BODY (//) +\n\33cThis program is free software; you can\n\ + redistribute it and/or modify it under the \n\ +terms of the GNU General Public License as\n\ +published by the Free Software Foundation;\n\ +either version 2 of the License, or (at\n\ +your option) any later version.\n\n\ +This program is distributed in the hope\n\ +that it will be useful,but WITHOUT ANY\n\ +WARRANTY; without even the implied\n\ + warranty of MERCHANTABILITY or FITNESS FOR \n\ +A PARTICULAR PURPOSE. See the GNU General\n\ +Public License for more details.\n\n\ +You should have received a copy of the GNU\n\ +General Public License along with this\n\ +program; if not, write to\n\n\ +Free Software Foundation, Inc.,\n\ +59 Temple Place,\n\ +Suite 330,\n\ +Boston, MA\n\ +02111-1307\n\ +USA\n\n\ +Or email the original author +; +; +MSGID_UNDO_OK (//) +Undo possible since \033bUse trashcan\033n is enabled +; +; +MSGID_UNDO_NOT_POSSIBLE (//) +Undo \033inot\033n possible unless \033bUse trashcan\033n is enabled +; +; +MSG_GAD_OK_ABORT (//) +*_Ok|Abort +; +;----------------------------------------------------------- +; +MSGID_MENU_PROJECT (2000//) +Project +; +; +MSGID_MENU_PROJECT_ABOUT (//) +About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI (//) +About MUI... +; +; +MSGID_MENU_PROJECT_QUIT (//) +Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT (//) +Q +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE (5000//) +Delete.module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD (//) +Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +; +;----------------------------------------------------------- +; diff --git a/scalos/Modules/Delete.MUI/Source/Delete.module.c b/scalos/Modules/Delete.MUI/Source/Delete.module.c new file mode 100755 index 000000000..c07cab797 --- /dev/null +++ b/scalos/Modules/Delete.MUI/Source/Delete.module.c @@ -0,0 +1,928 @@ +// Delete.module.c +// $Date$ +// $Revision$ +// $Id$ + +// ___ ___ +// _/ /_______\ \_ ___ ___ __ _ _ __ ___ ___. +//__// / _______ \ \\___/ \___ +//_/ | ' \__ __/ ` | \_/ © Copyright 1999, Christopher Page \__ +// \ | | | |__ | | / \ Released as Free Software under the GNU GPL /. +// >| . | _/ . |< >--- --- -- - - -- --- ---<. +// / \ \ | | / / \ / This file is part of the ScalosDelete code \. +// \ \ \_/ \_/ / / \ and it is released under the GNU GPL. Please /. +// \ \ / / \ read the "COPYING" file which should have /. +// //\ \_________/ /\\ //\ been included in the distribution arc. /. +//- --\ _______ /-- - --\ for full details of the license /----- +//-----\_/ \_/---------\ ___________________________________ /------ +// \_/ \_/. +// +// Description: +// +// Interface setup and entrypoints for ScalosDelete +// +// Functions: +// +// int wbmain (WBStartup *); +// int main (int , char **); +// void ExitMUI (APTR, STRPTR); +// void InitMUI (void); +// void SetupInterface(void); +// +// Detail: +// +// This file contains the setup/ shutdown, interface creation and entrypoint +// functions for ScalosDelete. It is written for StormC so some modification +// will be required to recompile under other systems. Note that StormC uses +// wbmain() as the entrypoint for workbench launched programs, you can probably +// remove this if you recompile under SAS/C or similar (DiceC uses the same +// mechanism). +// +// Modification History: +// +// [02 June 1999, Chris ] +// +// Converted header notice to GNU GPL version, checked and recommented where +// required. +// +// Fold Markers: +// +// Start: /*GFS*/ +// End: /*GFE*/ + +#define Delete_CODE +#define Delete_ARRAY +#include"Delete.module.h" + +//---------------------------------------------------------------------------- + +/*GFE*/ +// Prototypes +int wbmain (struct WBStartup *); +int main (int, char **); +void ExitMUI (APTR, STRPTR); +void InitMUI (void); +void SetupInterface (void); + +static SAVEDS(APTR) INTERRUPT OpenAboutMUIHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT EnableTrashcanHookFunc(struct Hook *hook, Object *o, Msg msg); +static BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev); + +//---------------------------------------------------------------------------- + +const char Version[] = VERSTAG; + +// Library bases and classes. Only hand-open the ones we really need a specific +// version of.. +extern struct ExecBase *SysBase; +struct Library *MUIMasterBase = NULL; +struct Library *AslBase = NULL; +#ifndef __amigaos4__ +T_UTILITYBASE UtilityBase = NULL; +#endif +struct ScalosBase *ScalosBase = NULL; +T_LOCALEBASE LocaleBase = NULL; +struct Catalog *WordsCat = NULL; +static struct Locale *DeleteLocale = NULL; + +#ifdef __amigaos4__ +struct IntuitionBase *IntuitionBase = NULL; + +struct MUIMasterIFace *IMUIMaster = NULL; +struct AslIFace *IAsl = NULL; +struct ScalosIFace *IScalos = NULL; +struct LocaleIFace *ILocale = NULL; +struct IntuitionIFace *IIntuition = NULL; +#endif + +// MUI globals +/*GFS*/ +Object *MUI_App = NULL; +Object *WI_Delete = NULL; + +Object *LV_Files = NULL; +Object *BT_Details = NULL; +Object *TX_ReadOut = NULL; + +Object *BT_Delete = NULL; +Object *BT_About = NULL; +Object *BT_Cancel = NULL; + +Object *GP_Progress = NULL; +Object *TX_Progress = NULL; +Object *GA_Progress = NULL; +Object *BT_STOP = NULL; + +Object *ST_TrashDir = NULL; +Object *CM_TrashCan = NULL; +Object *CM_DirConf = NULL; +Object *CM_FileConf = NULL; +Object *CM_Quiet = NULL; +Object *BT_Save = NULL; +Object *BT_Use = NULL; +Object *BT_Restore = NULL; + +CONST_STRPTR Pages[ 3] = { NULL }; +CONST_STRPTR Keys [14] = { NULL }; + +static Object *LampUndoPossible; +static Object *TextUndoPossible; + +Object *WI_About = NULL; +Object *BT_About_MUI = NULL; +static Object *MenuAbout; +static Object *MenuAboutMUI; +static Object *MenuQuit; +static Object *WIN_AboutMUI; + +static struct Hook AboutMUIHook = { { NULL, NULL }, HOOKFUNC_DEF(OpenAboutMUIHookFunc), NULL }; +static struct Hook EnableTrashcanHook = { { NULL, NULL }, HOOKFUNC_DEF(EnableTrashcanHookFunc), NULL }; + +//---------------------------------------------------------------------------- + +/* void ExitMUI(APTR, STRPTR) */ +/* -=-=-=-=-=-=-=-=-=-=-=-=-= */ +/* If an error occurs, or when the window is closed, this routine is called */ +/* to clean up all the resources, display an error message if required and */ +/* then exit(). */ +/* */ +/* Parameters: */ +/* errApp Pointer to the MUI Application object to close. */ +/* errString String to display in an EasyRequest. If this is */ +/* NULL then nothing is displayed */ + +/*GFS*/ void ExitMUI(APTR errApp, STRPTR errString) +{ +// LONG EntryNum = 0; + + struct EasyStruct ErrorDisplay = + { + sizeof(struct EasyStruct), + 0, + "Delete.module Error", // Not localised (may not have Locale y'see..) + "%s", + "Ok", + }; + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + // Show the error + if(errString) + EasyRequest(NULL, &ErrorDisplay, NULL, errString, 0); + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + if(errApp) + MUI_DisposeObject(errApp); + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + // Clean up + if(FileBuffer) + free(FileBuffer); + if(PathBuffer) + free(PathBuffer); + if(DirBuffer) + free(DirBuffer); + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + if(WordsCat) + CloseCatalog(WordsCat ); + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + if (DeleteLocale) + CloseLocale(DeleteLocale); + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + +#ifdef __amigaos4__ + if (IIntuition ) + DropInterface((struct Interface *)IIntuition ); +#endif + if (IntuitionBase) + CloseLibrary((struct Library *) IntuitionBase); +#ifdef __amigaos4__ + if(IMUIMaster ) + DropInterface((struct Interface *)IMUIMaster ); +#endif + if(MUIMasterBase) + CloseLibrary(MUIMasterBase); +#ifdef __amigaos4__ + if(IAsl ) + DropInterface((struct Interface *)IAsl ); +#endif + if(AslBase ) + CloseLibrary(AslBase ); +#ifndef __amigaos4__ + if(UtilityBase ) + CloseLibrary((struct Library *) UtilityBase ); +#endif +#ifdef __amigaos4__ + if(IScalos ) + DropInterface((struct Interface *)IScalos ); +#endif + if(ScalosBase ) + CloseLibrary(&ScalosBase->scb_LibNode); + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); +#ifdef __amigaos4__ + if(ILocale ) + DropInterface((struct Interface *)ILocale ); +#endif + if(LocaleBase ) + CloseLibrary((struct Library *) LocaleBase ); + + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); + + exit(0); +}/*GFE*/ + + +/* void InitMUI(void) */ +/* -=-=-=-=-=-=-=-=-= */ +/* This routine opens the libraries and locale catalog. If an error occurs */ +/* (ie: library will not open, memory allocation fails etc) then ExitMUI() */ +/* is called with an error. Note that the error messages are not localised as*/ +/* locale.library may not be available when the error is encountered.. */ + +/*GFS*/ void InitMUI(void) +{ + if(!(MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN))) + { + ExitMUI(NULL, "Unable to open "MUIMASTER_NAME"."); + } +#ifdef __amigaos4__ + else + { + IMUIMaster = (struct MUIMasterIFace *)GetInterface((struct Library *)MUIMasterBase, "main", 1, NULL); + } +#endif + + if(!(AslBase = OpenLibrary(AslName , 39))) + { + ExitMUI(NULL, "Unable to open "AslName"."); + } +#ifdef __amigaos4__ + else + { + IAsl = (struct AslIFace *)GetInterface((struct Library *)AslBase, "main", 1, NULL); + } +#endif + if(!(IntuitionBase = (struct IntuitionBase *) OpenLibrary(IntuitionName , 39))) + { + ExitMUI(NULL, "Unable to open " IntuitionName "."); + } +#ifdef __amigaos4__ + else + { + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + } +#endif +#ifndef __amigaos4__ + if(!(UtilityBase = (T_UTILITYBASE) OpenLibrary(UTILITYNAME, 39))) + { + ExitMUI(NULL, "Unable to open "UTILITYNAME"."); + } +#endif + + if(!(ScalosBase = (struct ScalosBase *) OpenLibrary("scalos.library", 39))) + { + ExitMUI(NULL, "Unable to open scalos.library."); + } +#ifdef __amigaos4__ + else + { + IScalos = (struct ScalosIFace *)GetInterface((struct Library *)ScalosBase, "main", 1, NULL); + } +#endif + + if(!(LocaleBase = (T_LOCALEBASE)OpenLibrary("locale.library", 37))) + { + ExitMUI(NULL, "Unable to open locale.library v39+"); + } +#ifdef __amigaos4__ + else + { + ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL); + } +#endif + + DeleteLocale = OpenLocale(NULL); + if (DeleteLocale) + WordsCat = OpenCatalogA(DeleteLocale, "Scalos/Delete.catalog", NULL); + + if(!(FileBuffer = malloc(MAX_FILENAME_LEN))) + { + ExitMUI(NULL, "Unable to allocate file buffer"); + } + + if(!(PathBuffer = malloc(MAX_FILENAME_LEN))) + { + ExitMUI(NULL, "Unable to allocate path buffer"); + } + + if(!(DirBuffer = malloc(MAX_FILENAME_LEN))) + { + ExitMUI(NULL, "Unable to allocate directory buffer"); + } +}/*GFE*/ + +#if 0 +/* int wbmain(WBStartup *) */ +/* -=-=-=-=-=-=-=-=-=-=-=- */ +/* Entry point for WB started programs. Required by StormC and DiceC but can */ +/* probably be removed for other system. It just calls main() with argc set */ +/* to 0 and argv pointing to the WBStartup message. */ + +/*GFS*/ int wbmain(struct WBStartup *wb_Startup) +{ + return (main(0, (char **)wb_Startup)); +}/*GFE*/ +#endif + +/* int main(int char **) */ +/* -=-=-=-=-=-=-=-=-=-=- */ +/* Eh? You want COMMENTS?? For *MAIN*??? Oh, all right then main routine.. */ +/* there that's all your getting. Comments indeed.. */ + +/*GFS*/ int main(int argc, char **argv) +{ + BOOL Running = TRUE; + ULONG Sig = 0; + ULONG Source = 0; + + // Wake up MUI... + InitMUI(); + + if (!CheckMCCVersion(MUIC_NList, 20, 121) || + !CheckMCCVersion(MUIC_NListview, 19, 66) || + !CheckMCCVersion(MUIC_Lamp, 11, 1) ) + return 10; + + SetupInterface(); + + // Bomb if the user has started the program from shell (daft user...) otherwise + // read the filelist... + if(argc != 0) + { + ExitMUI(MUI_App, "Delete.module may not be started from shell"); + } + + // Bomb out if something has gone clogs-skyward + if(!MUI_App) + { + ExitMUI(MUI_App, "Unable to create application"); + } + + CallHookPkt(&EnableTrashcanHook, MUI_App, NULL); + + // Some domethods to make processing easier. + DoMethod(WI_Delete , MUIM_Notify, MUIA_Window_CloseRequest, TRUE , MUI_App , 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + DoMethod(BT_Cancel , MUIM_Notify, MUIA_Pressed , FALSE , MUI_App , 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + DoMethod(BT_Delete , MUIM_Notify, MUIA_Pressed , FALSE , MUI_App , 2, MUIM_Application_ReturnID, DELETE_IT); + DoMethod(BT_Details , MUIM_Notify, MUIA_Pressed , FALSE , MUI_App , 2, MUIM_Application_ReturnID, DETAIL_IT); + DoMethod(BT_STOP , MUIM_Notify, MUIA_Pressed , FALSE , MUI_App , 2, MUIM_Application_ReturnID, STOP_IT ); + + DoMethod(BT_Save , MUIM_Notify, MUIA_Pressed , FALSE , MUI_App , 2, MUIM_Application_ReturnID, PREFSSAVE); + DoMethod(BT_Use , MUIM_Notify, MUIA_Pressed , FALSE , MUI_App , 2, MUIM_Application_ReturnID, PREFSUSE ); + DoMethod(BT_Restore , MUIM_Notify, MUIA_Pressed , FALSE , MUI_App , 2, MUIM_Application_ReturnID, PREFSLOAD); + + DoMethod(CM_TrashCan , MUIM_Notify, MUIA_Selected , MUIV_EveryTime, + MUI_App, 2, MUIM_CallHook, &EnableTrashcanHook); + + // About handling... + DoMethod(WI_About , MUIM_Notify, MUIA_Window_CloseRequest, TRUE , WI_About, 3, MUIM_Set, MUIA_Window_Open, FALSE ); + DoMethod(BT_About , MUIM_Notify, MUIA_Pressed , FALSE, WI_About, 3, MUIM_Set, MUIA_Window_Open, TRUE ); + DoMethod(BT_About_MUI, MUIM_Notify, MUIA_Pressed , FALSE, MUI_App , 2, MUIM_Application_AboutMUI , WI_About); + + // Menu handling + DoMethod(MenuAbout, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + WI_About, 3, MUIM_Set, MUIA_Window_Open, TRUE); + DoMethod(MenuAboutMUI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + MUI_App, 2, MUIM_CallHook, &AboutMUIHook); + DoMethod(MenuQuit, MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime, + MUI_App, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + // Read in the settings + DoMethod(MUI_App, MUIM_Application_Load, MUIV_Application_Load_ENV); + + // Get the show on the road... + set(WI_Delete, MUIA_Window_Open, TRUE); + + // +jmc+ : Activate delete button gadget + set(WI_Delete, MUIA_Window_ActiveObject, BT_Delete); + + // Open the about window & GNU GPL details.... + get(CM_Quiet , MUIA_Selected , &Source); + if(Source == 0) + set(WI_About, MUIA_Window_Open, TRUE); + + if(!ListFiles((struct WBStartup *)argv)) + ExitMUI(MUI_App, NULL); + + // Main loop: Block on the MUI Notify... + while (Running) + { + Source = DoMethod(MUI_App, MUIM_Application_NewInput, &Sig); + switch(Source) + { + case MUIV_Application_ReturnID_Quit: + Running = FALSE; + break; + case PREFSSAVE: + DoMethod(MUI_App, MUIM_Application_Save, MUIV_Application_Save_ENVARC); + case PREFSUSE : + DoMethod(MUI_App, MUIM_Application_Save, MUIV_Application_Save_ENV); + break; + case PREFSLOAD: + DoMethod(MUI_App, MUIM_Application_Load, MUIV_Application_Load_ENV); + break; + case DETAIL_IT: + GetDetails((struct WBStartup *)argv); + break; + case DELETE_IT: + set(BT_Details, MUIA_Disabled, TRUE); + set(BT_Delete, MUIA_Disabled, TRUE); + set(BT_About, MUIA_Disabled, TRUE); + set(BT_Cancel, MUIA_Disabled, TRUE); + KillFiles((struct WBStartup *)argv); + Running = FALSE; + break; + } + if(Running && Sig) + Wait(Sig); + } + + // Clean up and begone. + ExitMUI(MUI_App, NULL); + + return 0; +}/*GFE*/ + + +/* void SetupInterface(void) */ +/* -=-=-=-=-=-=-=-=-=-=-=-=- */ +/* Sets up the interface all in one compound command. Much easier to read */ +/* than lots of small functions adding bits here and there IMO... */ + +/*GFS*/ void SetupInterface(void) +{ + char VersionBuffer[64]; + char DateBuffer [64]; + + // Set up the compiled and version info... + sprintf(VersionBuffer, "%d.%d", VERSION, REVISION); + sprintf(DateBuffer , "%s %s" , __TIME__, __DATE__); + + // Localise the page names + Pages[0] = GetLocString(MSG_PAGES_FILES); + Pages[1] = GetLocString(MSG_PAGES_PREFS); + + // and the key shortcuts. Bit of a hack this really.... + Keys[ 0] = GetLocString(MSG_KEY_DETAILS); + Keys[ 1] = GetLocString(MSG_KEY_TRASH ); + Keys[ 2] = GetLocString(MSG_KEY_DIRS ); + Keys[ 3] = GetLocString(MSG_KEY_FILES ); + Keys[ 4] = GetLocString(MSG_KEY_QUIET ); + Keys[ 5] = GetLocString(MSG_KEY_TLOC ); + Keys[ 6] = GetLocString(MSG_KEY_SAVE ); + Keys[ 7] = GetLocString(MSG_KEY_USE ); + Keys[ 8] = GetLocString(MSG_KEY_REST ); + Keys[ 9] = GetLocString(MSG_KEY_DELETE ); + Keys[10] = GetLocString(MSG_KEY_ABOUT ); + Keys[11] = GetLocString(MSG_KEY_CANCEL ); + Keys[12] = GetLocString(MSG_KEY_STOP ); + Keys[13] = GetLocString(MSG_KEY_AMUI ); + + MUI_App = ApplicationObject, + MUIA_Application_Title , GetLocString(MSG_APP_TITLE), + MUIA_Application_Version , &Version[1], + MUIA_Application_Copyright , "(C)1999 Chris Page, The World Foundry", + MUIA_Application_Author , "Chris Page, The World Foundry", + MUIA_Application_Description, GetLocString(MSG_APP_DESC), + MUIA_Application_Base , BASENAME, + MUIA_Application_SingleTask , TRUE, +/*GFS*/ SubWindow, WI_Delete = WindowObject, + MUIA_Window_Title , GetLocString(MSG_WIN_TITLE), + MUIA_Window_ID , MAKE_ID('M','A','I','N'), + MUIA_Window_ScreenTitle, VSTR, + WindowContents, VGroup, + Child, RegisterGroup(Pages), + MUIA_CycleChain, TRUE, + MUIA_Background, MUII_RegisterBack, + Child, VGroup, + Child, HGroup, + GroupFrame, + MUIA_Background, MUII_GroupBack, + Child, LampUndoPossible = LampObject, + MUIA_Lamp_Type, MUIV_Lamp_Type_Huge, + MUIA_Lamp_Color, MUIV_Lamp_Color_Off, + End, //LampObject + Child, TextUndoPossible = TextObject, + MUIA_Text_Contents, GetLocString(MSGID_UNDO_NOT_POSSIBLE), + End, //TextObject + End, //HGroup + + Child, VGroup, + MUIA_Group_Spacing, 0, + Child, LV_Files = NListviewObject, + MUIA_CycleChain, 1, + MUIA_NListview_Vert_ScrollBar, TRUE, + MUIA_NListview_NList , NListObject, + MUIA_CycleChain, 1, + MUIA_NList_Input , FALSE, + MUIA_NList_DragSortable , FALSE, + MUIA_NList_Title , TRUE, + MUIA_NList_Format , "BAR,BAR,BAR,", + MUIA_NList_ConstructHook , &ConList, + MUIA_NList_DestructHook , &DesList, + MUIA_NList_DisplayHook , &DisList, + MUIA_NList_CompareHook , &CmpList, + End, //NListObject + End, //NListviewObject + Child, BT_Details = KeyButtonChain(GetLocString(MSG_BUTTON_FULL), Keys[0][0], 1), + End, //VGroup + + Child, TX_ReadOut = TextObject, + TextFrame, + MUIA_Background, MUII_TextBack, + MUIA_Weight , 800, + MUIA_Text_PreParse, "\33c", + MUIA_FixHeightTxt , " ", + End, //TextObject + + End, //VGroup + + Child, VGroup, + Child, ColGroup(4), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + Child, KeyLabel1(GetLocString(MSG_LABEL_TRASH), Keys[1][0]), + Child, CM_TrashCan = KeyCheckMarkHelpID(TRUE, Keys[1][0], 1, MAKE_ID('C', 'M', 'T', 'C'), GetLocString(MSG_HELP_TRASH)), + Child, HVSpace, + + Child, HVSpace, + Child, KeyLabel1(GetLocString(MSG_LABEL_DIRS) , Keys[2][0]), + Child, CM_DirConf = KeyCheckMarkHelpID(FALSE, Keys[2][0], 1, MAKE_ID('C', 'M', 'D', 'C'), GetLocString(MSG_HELP_DIRS )), + Child, HVSpace, + + Child, HVSpace, + Child, KeyLabel1(GetLocString(MSG_LABEL_FILES), Keys[3][0]), + Child, CM_FileConf = KeyCheckMarkHelpID(FALSE, Keys[3][0], 1, MAKE_ID('C', 'M', 'F', 'C'), GetLocString(MSG_HELP_FILES)), + Child, HVSpace, + + Child, HVSpace, + Child, KeyLabel1(GetLocString(MSG_LABEL_QUIET), Keys[4][0]), + Child, CM_Quiet = KeyCheckMarkHelpID(TRUE, Keys[4][0], 1, MAKE_ID('C', 'M', 'Q', 'I'), GetLocString(MSG_HELP_QUIET)), + Child, HVSpace, + + End, //ColGroup + + Child, HVSpace, + + Child, HGroup, + GroupFrameT(GetLocString(MSG_LABEL_TLOC)), + + Child, ST_TrashDir = PopaslObject, + MUIA_Popstring_String, StringObject, + StringFrame, + MUIA_String_MaxLen , 128, + MUIA_CycleChain , 1, + MUIA_ControlChar , Keys[5][0], + MUIA_ShortHelp , GetLocString(MSG_HELP_TLOC), + MUIA_ExportID , MAKE_ID('S', 'T', 'T', 'C'), + End, //StringObject + MUIA_Popstring_Button, PopButton(MUII_PopDrawer), + MUIA_CycleChain , 1, + ASLFR_TitleText , GetLocString(MSG_ASL_TITLE), + ASLFR_RejectIcons , TRUE, + ASLFR_DrawersOnly , TRUE, + End, //PopaslObject + End, //HGroup + Child, VSpace(0), + Child, HGroup, + MUIA_Group_SameSize, TRUE, + Child, BT_Save = KeyButtonChain(GetLocString(MSG_BUTTON_SAVE), Keys[6][0], 1), + Child, BT_Use = KeyButtonChain(GetLocString(MSG_BUTTON_USE ), Keys[7][0], 1), + Child, BT_Restore = KeyButtonChain(GetLocString(MSG_BUTTON_REST), Keys[8][0], 1), + End, //HGroup + End, //VGroup + End, //RegisterGroup + + Child, HGroup, + MUIA_Group_SameSize, TRUE, + Child, BT_Delete = KeyButtonChain(GetLocString(MSG_BUTTON_DEL), Keys[ 9][0], 1), + Child, BT_About = KeyButtonChain(GetLocString(MSG_BUTTON_ABT), Keys[10][0], 1), + Child, BT_Cancel = KeyButtonChain(GetLocString(MSG_BUTTON_CAN), Keys[11][0], 1), + End, //HGroup + + Child, GP_Progress = VGroup, + GroupFrame, + MUIA_Background, MUII_GroupBack, + MUIA_ShowMe, FALSE, + Child, HGroup, + Child, TX_Progress = TextObject, + MUIA_Background, MUII_TextBack, + TextFrame, + MUIA_Weight , 800, + MUIA_Background, MUII_TextBack, + MUIA_Text_PreParse, "\33c", + MUIA_FixHeightTxt , " ", + End, //TextObject + Child, BT_STOP = KeyButtonChain(GetLocString(MSG_BUTTON_STOP), Keys[12][0], 1), + End, //HGroup + Child, VGroup, + Child, GA_Progress = GaugeObject, + GaugeFrame, + MUIA_Gauge_Current , 0, + MUIA_Gauge_Max , 100, + MUIA_Gauge_Horiz , TRUE, + MUIA_FixHeightTxt , " ", + MUIA_Gauge_InfoText, GetLocString(MSG_LABEL_INFO), + End, //GaugeObject + Child, ScaleObject, + MUIA_Scale_Horiz , TRUE, + End, //ScaleObject + End, //VGroup + End, //VGroup + End, //VGroup +/*GFE*/ End, //WindowObject + +/*GFS*/ SubWindow, WI_About = WindowObject, + MUIA_Window_Title , GetLocString(MSG_BUTTON_ABT), + MUIA_Window_ID , MAKE_ID('A','B','O','T'), + MUIA_Window_ScreenTitle, VSTR, + WindowContents, VGroup, + Child, TextObject, + TextFrame, + MUIA_Background, MUII_TextBack, + MUIA_Text_Contents, GetLocString(MSG_ABOUT_HEAD), + End, //TextObject + Child, ColGroup(7), + Child, HSpace(0), + Child, TextObject, + MUIA_Text_Contents, GetLocString(MSG_LABEL_VERS), + MUIA_Text_PreParse, "\33r", + End, //TextObject + Child, TextObject, + MUIA_Text_Contents, VersionBuffer, + End, //TextObject + Child, HSpace(0), + Child, TextObject, + MUIA_Text_Contents, GetLocString(MSG_LABEL_COMP), + MUIA_Text_PreParse, "\33r", + End, //TextObject + Child, TextObject, + MUIA_Text_Contents, DateBuffer, + End, //TextObject + Child, HSpace(0), + End, //ColGroup + Child, ScrollgroupObject, + MUIA_Scrollgroup_Contents, VGroupV, + VirtualFrame , + Child, TextObject, + MUIA_Background, MUII_TextBack, + MUIA_Text_Contents, GetLocString(MSG_ABOUT_BODY), + End, //TextObject + End, //VGroupV + End, //ScrollgroupObject + + Child, BT_About_MUI = KeyButtonChain(GetLocString(MSG_BUTTON_AMUI), Keys[13][0], 1), + End, //VGroup +/*GFE*/ End, //WindowObject + + MUIA_Application_Menustrip, MenustripObject, + Child, MenuObjectT(GetLocString(MSGID_MENU_PROJECT)), + + Child, MenuAbout = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUT), + End, + Child, MenuAboutMUI = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUTMUI), + End, + Child, MenuitemObject, + MUIA_Menuitem_Title, -1, + End, + Child, MenuQuit = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_QUIT), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_PROJECT_QUIT_SHORT), + End, + + End, //MenuObjectT + End, //MenuStripObject + End; //ApplicationObject +}/*GFE*/ + +//---------------------------------------------------------------------------- + +CONST_STRPTR GetLocString(ULONG MsgId) +{ + struct Delete_LocaleInfo li; + + li.li_Catalog = WordsCat; +#ifndef __amigaos4__ + li.li_LocaleBase = LocaleBase; +#else + li.li_ILocale = ILocale; +#endif + +// KPrintF(__FILE__ "%s/%ld: Catalog=%08lx LocaleBase=%08lx\n", +// __FUNC__, __LINE__, li.li_Catalog, li.li_LocaleBase); + + return (CONST_STRPTR) GetDeleteString(&li, MsgId); +} + +//---------------------------------------------------------------------------- + +STRPTR safe_strcat(STRPTR dest, CONST_STRPTR src, size_t DestLen) +{ + STRPTR dst; + size_t Len = strlen(dest); + + if (DestLen < Len) + return dest; + + DestLen -= Len; + dst = dest + Len; + + while (DestLen > 1 && *src) + { + *dst++ = *src++; + DestLen--; + } + *dst = '\0'; + + return dest; +} + +//---------------------------------------------------------------------------- + +#if !defined(__SASC) &&!defined(__MORPHOS__) +// Replacement for SAS/C library functions + +size_t stccpy(char *dest, const char *src, size_t MaxLen) +{ + size_t Count = 0; + + while (*src && MaxLen > 1) + { + *dest++ = *src++; + MaxLen--; + Count++; + } + *dest = '\0'; + Count++; + + return Count; +} + +#endif /* __SASC */ + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT OpenAboutMUIHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + if (NULL == WIN_AboutMUI) + { + WIN_AboutMUI = MUI_NewObject(MUIC_Aboutmui, + MUIA_Window_RefWindow, WI_Delete, + MUIA_Aboutmui_Application, MUI_App, + End; + } + + if (WIN_AboutMUI) + set(WIN_AboutMUI, MUIA_Window_Open, TRUE); + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT EnableTrashcanHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + ULONG UseTrashcan = 0; + + get(CM_TrashCan, MUIA_Selected, &UseTrashcan); + + set(ST_TrashDir, MUIA_Disabled, UseTrashcan); + set(LampUndoPossible, MUIA_Lamp_Color, UseTrashcan ? MUIV_Lamp_Color_Ok : MUIV_Lamp_Color_Error); + set(TextUndoPossible, MUIA_Text_Contents, GetLocString(UseTrashcan ? MSGID_UNDO_OK : MSGID_UNDO_NOT_POSSIBLE)); +} + +//---------------------------------------------------------------------------- + +// Checks if a certain version of a MCC is available +static BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev) +{ + BOOL flush = TRUE; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: %s ", name, __LINE__);) + + while (1) + { + ULONG ver = 0; + ULONG rev = 0; + struct Library *base; + char libname[256]; + + // First we attempt to acquire the version and revision through MUI + Object *obj = MUI_NewObject((STRPTR) name, TAG_DONE); + if (obj) + { + get(obj, MUIA_Version, &ver); + get(obj, MUIA_Revision, &rev); + + MUI_DisposeObject(obj); + + if(ver > minver || (ver == minver && rev >= minrev)) + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: v%ld.%ld found through MUIA_Version/Revision\n", __LINE__, ver, rev);) + return TRUE; + } + } + + // If we did't get the version we wanted, let's try to open the + // libraries ourselves and see what happens... + stccpy(libname, "PROGDIR:mui", sizeof(libname)); + AddPart(libname, name, sizeof(libname)); + + if ((base = OpenLibrary(&libname[8], 0)) || (base = OpenLibrary(&libname[0], 0))) + { + UWORD OpenCnt = base->lib_OpenCnt; + + ver = base->lib_Version; + rev = base->lib_Revision; + + CloseLibrary(base); + + // we add some additional check here so that eventual broken .mcc also have + // a chance to pass this test (i.e. Toolbar.mcc is broken) + if (ver > minver || (ver == minver && rev >= minrev)) + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: v%ld.%ld found through OpenLibrary()\n", __LINE__, ver, rev);) + return TRUE; + } + + if (OpenCnt > 1) + { + if (MUI_Request(NULL, NULL, 0L, + (STRPTR) GetLocString(MSGID_STARTUP_FAILURE), + (STRPTR) GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), + (STRPTR) GetLocString(MSGID_STARTUP_MCC_IN_USE), + name, minver, minrev, ver, rev)) + { + flush = TRUE; + } + else + break; + } + + // Attempt to flush the library if open count is 0 or because the + // user wants to retry (meaning there's a chance that it's 0 now) + + if (flush) + { + struct Library *result; + + Forbid(); + if ((result = (struct Library *) FindName(&((struct ExecBase *)SysBase)->LibList, name))) + RemLibrary(result); + Permit(); + flush = FALSE; + } + else + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: couldn`t find minimum required version.\n", __LINE__);) + + // We're out of luck - open count is 0, we've tried to flush + // and still haven't got the version we want + if (MUI_Request(NULL, NULL, 0L, + (STRPTR) GetLocString(MSGID_STARTUP_FAILURE), + (STRPTR) GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), + (STRPTR) GetLocString(MSGID_STARTUP_OLD_MCC), + name, minver, minrev, ver, rev)) + { + flush = TRUE; + } + else + break; + } + } + else + { + // No MCC at all - no need to attempt flush + flush = FALSE; + if (!MUI_Request(NULL, NULL, 0L, + (STRPTR) GetLocString(MSGID_STARTUP_FAILURE), + (STRPTR) GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), + (STRPTR) GetLocString(MSGID_STARTUP_MCC_NOT_FOUND), + name, minver, minrev)) + { + break; + } + } + } + + return FALSE; +} + +//---------------------------------------------------------------------------- + diff --git a/scalos/Modules/Delete.MUI/Source/Delete.module.h b/scalos/Modules/Delete.MUI/Source/Delete.module.h new file mode 100755 index 000000000..f6f320a81 --- /dev/null +++ b/scalos/Modules/Delete.MUI/Source/Delete.module.h @@ -0,0 +1,216 @@ +// Delete.module.h +// $Date$ +// $Revision$ + +// ___ ___ +// _/ /_______\ \_ ___ ___ __ _ _ __ ___ ___ +//__// / _______ \ \\___/ \___ +//_/ | ' \__ __/ ` | \_/ © Copyright 1999, Christopher Page \__ +// \ | | | |__ | | / \ Released as Free Software under the GNU GPL /. +// >| . | _/ . |< >--- --- -- - - -- --- ---<. +// / \ \ | | / / \ / This file is part of the ScalosDelete code \. +// \ \ \_/ \_/ / / \ and it is released under the GNU GPL. Please /. +// \ \ / / \ read the "COPYING" file which should have /. +// //\ \_________/ /\\ //\ been included in the distribution arc. /. +//- --\ _______ /-- - --\ for full details of the license /----- +//-----\_/ \_/---------\ ___________________________________ /------ +// \_/ \_/. +// +// Description: +// +// Includes and shared stuff for the various source files for ScalosDelete. +// +// Yeah, I know I overdo the #include stuff, so kill me... + + +// MUI +#include +#include +#include +#include + +// System +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Prototypes +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// ANSI C +#include +#include +#include + +#include + +// Revision stuff +#include "Delete.module_rev.h" + + +#define DEBUG_CURRENTDIR {\ + char xxName[200];\ + BPTR oldDir = CurrentDir(NULL);\ + strcpy(xxName, "");\ + NameFromLock(oldDir, xxName, sizeof(xxName));\ + KPrintF("%s/%s/%ld: CurrentDir=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, oldDir, xxName);\ + CurrentDir(oldDir);\ + } + +struct Delete_LocaleInfo +{ + APTR li_LocaleBase; + APTR li_Catalog; + struct LocaleIFace *li_ILocale; +}; + +#define Delete_NUMBERS +#include STR(SCALOSLOCALE) + + +// Couple of macros to make the code more readable. + +// Need MAKE_ID for the windows, so best to be sure... +#ifndef MAKE_ID +#define MAKE_ID(a,b,c,d) ((ULONG) (a)<<24 | (ULONG) (b)<<16 | (ULONG) (c)<<8 | (ULONG) (d)) +#endif + +#ifndef __AROS__ +#define BNULL ((BPTR) NULL) +#endif + +// Some macros to make the MUI code a bit easier to read. +#define KeyCheckMarkHelpID(selected, control, cyclechain, ident, help)\ + ImageObject,\ + ImageButtonFrame,\ + MUIA_InputMode , MUIV_InputMode_Toggle,\ + MUIA_Image_Spec , MUII_CheckMark,\ + MUIA_Image_FreeVert , TRUE,\ + MUIA_Selected , selected,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShowSelState , FALSE,\ + MUIA_ControlChar , control,\ + MUIA_CycleChain , cyclechain,\ + MUIA_ShortHelp , help,\ + MUIA_ExportID , ident,\ + End + +#define KeyButtonChain(name, key, cyclechain)\ + TextObject,\ + ButtonFrame,\ + MUIA_Text_Contents, name,\ + MUIA_Text_PreParse, "\33c",\ + MUIA_Text_HiChar , key,\ + MUIA_ControlChar , key,\ + MUIA_InputMode , MUIV_InputMode_RelVerify,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_CycleChain , cyclechain,\ + End + + +// Events generated by the interface. +#define DELETE_IT 1 +#define DETAIL_IT 2 +#define STOP_IT 3 + +#define PREFSSAVE 10 +#define PREFSUSE 11 +#define PREFSLOAD 12 + +// Results generated by the delete functions. +#define RESULT_OK 0 +#define RESULT_FAIL 1 +#define RESULT_CANCEL 2 +#define RESULT_HALT 3 + +#define MAX_FILENAME_LEN 512 + +#define IntuitionName "intuition.library" + +// «««««««««««««««««««««««««««« ---------------- »»»»»»»»»»»»»»»»»»»»»»»»»»» +// ««««««««««««««««««««««««««« In Delete.module.c »»»»»»»»»»»»»»»»»»»»»»»»»» +// «««««««««««««««««««««««««««« ---------------- »»»»»»»»»»»»»»»»»»»»»»»»»»» + +// Globals... +extern struct Library *AslBase; +extern T_UTILITYBASE UtilityBase ; +extern struct ScalosBase *ScalosBase ; +extern T_LOCALEBASE LocaleBase ; +extern struct Library *MUIMasterBase; +extern struct Catalog *WordsCat ; + +extern Object *MUI_App ; +extern Object *WI_Delete ; +extern Object *LV_Files ; +extern Object *BT_Details ; +extern Object *TX_ReadOut ; +extern Object *BT_Delete ; +extern Object *BT_Cancel ; +extern Object *GP_Progress ; +extern Object *TX_Progress ; +extern Object *GA_Progress ; +extern Object *BT_STOP ; +extern Object *ST_TrashDir ; +extern Object *CM_TrashCan ; +extern Object *CM_DirConf ; +extern Object *CM_FileConf ; + +CONST_STRPTR GetLocString(ULONG MsgId); +STRPTR safe_strcat(STRPTR dest, CONST_STRPTR src, size_t DestLen); + +#if !defined(__SASC) && !defined(__MORPHOS__) && !defined(__amigaos4__) +size_t stccpy(char *dest, const char *src, size_t MaxLen); +#endif /* __SASC */ + +#if defined(__SASC) +int snprintf(char *, size_t, const char *, /*args*/ ...); +#endif /* __SASC */ + + +// ««««««««««««««««««««««««« ---------------------- »»»»»»»»»»»»»»»»»»»»»»»» +// «««««««««««««««««««««««« In Delete.module_hooks.c »»»»»»»»»»»»»»»»»»»»»»» +// ««««««««««««««««««««««««« ---------------------- »»»»»»»»»»»»»»»»»»»»»»»» + +extern STRPTR FileBuffer; +extern STRPTR PathBuffer; +extern STRPTR DirBuffer ; +extern char TextBuffer[80 + 1]; +extern struct Hook ConList ; +extern struct Hook DesList ; +extern struct Hook DisList ; +extern struct Hook CmpList ; + +extern BOOL ListFiles (struct WBStartup *); +extern BOOL GetDetails(struct WBStartup *); +extern void KillFiles (struct WBStartup *); + + +// Make debugging a bit easier to activate/ deactivate.... +extern void kprintf(UBYTE *fmt, ...); +extern void KPrintF(UBYTE *fmt, ...); + +#ifdef __AROS__ +#define KPrintF kprintf +#endif + +#define d1(x) ; +#define d2(x) x; diff --git a/scalos/Modules/Delete.MUI/Source/Delete.module_files.c b/scalos/Modules/Delete.MUI/Source/Delete.module_files.c new file mode 100644 index 000000000..3f7be22cb --- /dev/null +++ b/scalos/Modules/Delete.MUI/Source/Delete.module_files.c @@ -0,0 +1,1493 @@ +// Delete.module_files.c +// $Date$ +// $Revision$ + + +// ___ ___. +// _/ /_______\ \_ ___ ___ __ _ _ __ ___ ___. +//__// / _______ \ \\___/ \___. +//_/ | ' \__ __/ ` | \_/ © Copyright 1999, Christopher Page \__. +// \ | | | |__ | | / \ Released as Free Software under the GNU GPL /. +// >| . | _/ . |< >--- --- -- - - -- --- ---<. +// / \ \ | | / / \ / This file is part of the ScalosDelete code \. +// \ \ \_/ \_/ / / \ and it is released under the GNU GPL. Please /. +// \ \ / / \ read the "COPYING" file which should have /. +// //\ \_________/ /\\ //\ been included in the distribution arc. /. +//- --\ _______ /-- - --\ for full details of the license /----- +//-----\_/ \_/---------\ ___________________________________ /------ +// \_/ \_/. +// +// Description: +// +// Filesystem functions and listview hook functions +// +// Functions: +// +// int estrlen (STRPTR) +// APTR ConstructList(APTR, FileInfoBlock *) +// void DestructList (APTR, FileInfoBlock *) +// LONG DisplayList (char **, FileInfoBlock *) +// LONG CompareList (FileInfoBlock *, FileInfoBlock *) +// BOOL ListFiles (WBStartup *) +// LONG CopyFile (STRPTR, STRPTR, ULONG) +// void UpdateDrawer (STRPTR) +// LONG FileDelete (STRPTR, BOOL, APTR) +// LONG DeleteIcon (STRPTR, BOOL, APTR) +// LONG DirDelete (STRPTR, BOOL, APTR) +// void KillFiles (WBStartup *) +// void DirCount (STRPTR, DetailStats *) +// BOOL GetDetails (WBStartup *) +// +// Detail: +// +// This file contains the routines that do the real work. The xxxxList() +// functions are hook functions used in the main list in the interface, +// the remainder of the functions either count the selected files and +// directories or do the actual file/ directory deletion. Several of the +// routines contain a large numbr of debugging commands, if you don't +// define NDEBUG somewhere (either in your preprocessor options or in +// the header) then you'll need to link debug.lib and have something +// watching the serial port... if you have defined NDEBUG then the +// preprocessor removes all the debugging commands... +// +// Modification History: +// +// [02 June 1999, Chris ] +// +// Converted header notice to GNU GPL version, checked and recommented where +// required. +// +// Fold Markers: +// +// Start: /*GFS*/. +// End: /*GFE*/ . + +#include"Delete.module.h" + +struct DetailStats +{ + ULONG ds_Files; + ULONG ds_Bytes; + ULONG ds_Dirs ; +}; + +// These make life easier later, they are allocated/ freed in InitMUI()/ ExitMUI().... +STRPTR FileBuffer = NULL; +STRPTR PathBuffer = NULL; +STRPTR DirBuffer = NULL; +char TextBuffer[80 + 1]; + +struct FileInfoBlock *GlobalFIB = NULL; // This makes some of the routines easier to follow.. +BOOL Unprotect = FALSE; // If TRUE all files are automagically unprotected + +ULONG SizeCount = 0 ; // Number of bytes being deleted in total +BOOL GotDetails = FALSE; // If TRUE then Sizecount is the size of all files and subdirectories +ULONG DoneSize = 0; // Number of bytes we've deleted already + +//---------------------------------------------------------------------------- + +static struct ScaWindowStruct *FindScalosWindow(BPTR dirLock); + +//---------------------------------------------------------------------------- + +/* int estrlen(STRPTR) */ +/* -=-=-=-=-=-=-=-=-=- */ +/* This routine does exactly the same thing as ANSI strlen() except that if */ +/* it recieves a NULL pointer, it returns 0 rather than causing enforcer hits*/ + +size_t estrlen(CONST_STRPTR strdat) +{ +/// + if(strdat) + return strlen(strdat); + + return(0); +/// +} + + +/* APTR ConstructList(APTR, FileInfoBlock *) */ +/* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */ +/* This simply creates a copy of the provided FIB. No processing or messing */ +/* around, just a straight allocate + copy... */ + +SAVEDS(APTR) ConstructList(struct Hook *hook, APTR MemPool, const struct FileInfoBlock *AddFib) +{ +/// + struct FileInfoBlock *NewFib = NULL; + + (void) hook; + + // Allocate a new FIB. + if(NewFib = AllocPooled(MemPool, sizeof(struct FileInfoBlock))) + { + *NewFib = *AddFib; + } + + return(NewFib); +/// +} + + +/* void DestructList(APTR, FileInfoBlock *) */ +/* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ +/* Destruct hook function used by the main list, this frees the provided FIB */ +/* from the memory pool (so it damn well better have been allocated in it!!) */ + +SAVEDS(void) DestructList(struct Hook *hook, APTR MemPool, struct FileInfoBlock *OldFib) +{ +/// + (void) hook; + FreePooled(MemPool, OldFib, sizeof(struct FileInfoBlock)); +/// +} + + +/* LONG DisplayList(char **, FileInfoBlock *) */ +/* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */ +/* Main list display hook, some messing around has to be done to make sure */ +/* that directories are highlighted, but nothing too complex... */ + +SAVEDS(LONG) DisplayList(struct Hook *hook, char **Array, struct FileInfoBlock *ShowFib) +{ +/// + static char NameBuffer[1+108], SizeBuffer[20], DateBuffer[24], TimeBuffer[12]; + static struct DateTime Date; + + (void) hook; + + if(ShowFib) + { + Date.dat_Stamp = ShowFib->fib_Date; + Date.dat_Format = FORMAT_DOS; + Date.dat_Flags = DTF_SUBST; + Date.dat_StrDay = NULL; + Date.dat_StrDate= DateBuffer; + Date.dat_StrTime= TimeBuffer; + DateToStr(&Date); + + if(ShowFib->fib_DirEntryType < 0) + { + stccpy(NameBuffer, ShowFib->fib_FileName, sizeof(NameBuffer)); + snprintf(SizeBuffer, sizeof(SizeBuffer), "\33r%lu", (unsigned long) ShowFib->fib_Size); + } + else + { + stccpy(NameBuffer, "\0333", sizeof(NameBuffer)); + safe_strcat(NameBuffer, ShowFib->fib_FileName, sizeof(NameBuffer)); + stccpy(SizeBuffer, "\33r\33I[6.22]", sizeof(SizeBuffer)); + } + *Array++ = NameBuffer; + *Array++ = SizeBuffer; + *Array++ = DateBuffer; + *Array = TimeBuffer; + } + else + { + *Array++ = (char *) GetLocString(MSG_LVT_NAME); + *Array++ = (char *) GetLocString(MSG_LVT_SIZE); + *Array++ = (char *) GetLocString(MSG_LVT_DATE); + *Array = (char *) GetLocString(MSG_LVT_TIME); + } + + return(0); +/// +} + + +/* LONG CompareList(FileInfoBlick *, FileInfoBlock *) */ +/* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ +/* Compare hook function wich takes two FIBs and returns <0 if Fib1 < Fib2, */ +/* 0 if they are equal or >0 if Fib1 > Fib2. Directories automagically go */ +/* before files regardless of alphabetical ordering... */ + +SAVEDS(LONG) CompareList(struct Hook *hook, + struct FileInfoBlock *Fib1, struct FileInfoBlock *Fib2) +{ +/// + (void) hook; + + if(Fib1->fib_DirEntryType == Fib2->fib_DirEntryType) + { + return(Stricmp(Fib1->fib_FileName, Fib2->fib_FileName)); + } + else + { + if(Fib1->fib_DirEntryType < 0) + return(1); + else + return(-1); + } +/// +} + +struct Hook ConList = {{NULL, NULL}, HOOKFUNC_DEF(ConstructList), NULL}; +struct Hook DesList = {{NULL, NULL}, HOOKFUNC_DEF(DestructList ), NULL}; +struct Hook DisList = {{NULL, NULL}, HOOKFUNC_DEF(DisplayList ), NULL}; +struct Hook CmpList = {{NULL, NULL}, HOOKFUNC_DEF(CompareList ), NULL}; + +/* BOOL ListFiles(struct WBStartup *) */ +/* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ +/* Before the main GUI is opened, this routine constructs a list of all the */ +/* files / directories to be deleted (on the first level, not recursively!) */ +/* It detects an attempt to delete a volume, and allows the user to cancel */ +/* the whole operation immediately. The main file list is a list of FIBs so */ +/* the display routine can do nice things like sorting directories and files */ +/* seperately and displaying sizes etc. If anything goes wrong, or the user */ +/* cancels the operation, then this routine returns FALSE, otherwise TRUE. */ + +BOOL ListFiles(struct WBStartup *WBStart) +{ +/// + struct WBArg *lf_Args = WBStart->sm_ArgList; + struct FileInfoBlock *lf_Fib = NULL; + LONG lf_Num = 0; + BPTR lf_File = (BPTR)NULL; + + ULONG lf_FileCount = 0; + ULONG lf_DirCount = 0; + + d1(kprintf("ListFiles(): Started\n");) + + if(WBStart->sm_NumArgs <= 1) + { + MUI_Request(MUI_App, WI_Delete, 0, + (char *) GetLocString(MSG_ERROR_TITLE), + (char *) GetLocString(MSG_GAD_OK), + (char *) GetLocString(MSG_BODY_NOFILES)); + return(FALSE); + } + + d1(kprintf("ListFiles(): Passed arglist check\n");) + + if(!(lf_Fib = AllocDosObject(DOS_FIB, NULL))) + { + MUI_Request(MUI_App, WI_Delete, 0, + (char *) GetLocString(MSG_ERROR_TITLE), + (char *) GetLocString(MSG_GAD_OK), + (char *) GetLocString(MSG_BODY_NOLIST )); + return(FALSE); + } + + d1(kprintf("ListFiles(): Obtained FileInfoblock\n");) + + for(lf_Num = 1; lf_Num < WBStart->sm_NumArgs; lf_Num ++) + { + d1(KPrintF("ListFiles(): Checking entry %ld. Lock 0x%08lX Name <%s>\n", \ + lf_Num, lf_Args[lf_Num].wa_Lock, lf_Args[lf_Num].wa_Name);) + + // If got a lock, change to it + if(lf_Args[lf_Num].wa_Lock) + { + BPTR lf_Old; + + lf_Old = CurrentDir(lf_Args[lf_Num].wa_Lock); + + // Got a filename? + if(estrlen(lf_Args[lf_Num].wa_Name)) + { + d1(KPrintF("ListFiles(): Got filename\n");) + + // Lock it... + if(lf_File = Lock(lf_Args[lf_Num].wa_Name, ACCESS_READ)) + { + // Grab the FIB and bung it in the files list. + Examine(lf_File, lf_Fib); + DoMethod(LV_Files, MUIM_NList_InsertSingle, lf_Fib, MUIV_NList_Insert_Sorted); + if(lf_Fib->fib_DirEntryType < 0) + { + d1(KPrintF("ListFiles(): Entry is a file\n");) + lf_FileCount ++; + SizeCount += lf_Fib->fib_Size; + } + else + { + d1(KPrintF("ListFiles(): Entry is a directory?\n");) + lf_DirCount ++; + } + UnLock(lf_File); + } + + // Try for the icon too... + stccpy(FileBuffer, lf_Args[lf_Num].wa_Name, MAX_FILENAME_LEN); + safe_strcat(FileBuffer, ".info", MAX_FILENAME_LEN); + + if(lf_File = Lock(FileBuffer, ACCESS_READ)) + { + d1(KPrintF("ListFiles(): Obtained icon for file\n");) + + // Grab the FIB and bung it in the files list. + Examine(lf_File, lf_Fib); + DoMethod(LV_Files, MUIM_NList_InsertSingle, lf_Fib, MUIV_NList_Insert_Sorted); + if(lf_Fib->fib_DirEntryType < 0) + { + lf_FileCount ++; + SizeCount += lf_Fib->fib_Size; + } + UnLock(lf_File); + } + + } + else + { + d1(KPrintF("ListFiles(): No filename avilable\n");) + + // Resolve a name... + NameFromLock(lf_Args[lf_Num].wa_Lock, FileBuffer, MAX_FILENAME_LEN); + + // Got a name? + if(strlen(FileBuffer)) + { + // Is it a volume? + if(FileBuffer[strlen(FileBuffer) -1] == ':') + { + d1(KPrintF("ListFiles(): WARNING. Filename contains volume name\n");) + + // AGH!! VOLUME DELETE ENCOUNTERED! PANIC!!!!!! + if(!MUI_Request(MUI_App, WI_Delete, 0, + (char *) GetLocString(MSG_WARN_TITLE), + (char *) GetLocString(MSG_GAD_NOYES), + (char *) GetLocString(MSG_BODY_VOLUME), + FileBuffer)) + { + FreeDosObject(DOS_FIB, lf_Fib); + CurrentDir(lf_Old); + return(FALSE); + } + } + } + + // Well, either this was a directory, or Joe Sixpack out there is deleting a volume. + Examine (lf_Args[lf_Num].wa_Lock, lf_Fib); + if(lf_Fib->fib_DirEntryType >= 0) + { + lf_DirCount ++; + } + DoMethod(LV_Files, MUIM_NList_InsertSingle, lf_Fib, MUIV_NList_Insert_Sorted); + + // Try for the icon again... + safe_strcat(FileBuffer, ".info", MAX_FILENAME_LEN); + if(lf_File = Lock(FileBuffer, ACCESS_READ)) + { + d1(kprintf("ListFiles(): Obtained icon for file\n");) + + // Grab the FIB and bung it in the files list. + Examine(lf_File, lf_Fib); + if(lf_Fib->fib_DirEntryType < 0) + { + lf_FileCount ++; + SizeCount += lf_Fib->fib_Size; + } + DoMethod(LV_Files, MUIM_NList_InsertSingle, lf_Fib, MUIV_NList_Insert_Sorted); + UnLock(lf_File); + } + } + + // Better get back to home. + CurrentDir(lf_Old); + } + } + + // better not forget this.... + FreeDosObject(DOS_FIB, lf_Fib); + + d1(kprintf("ListFiles(): Compiling stats display\n");) + + snprintf(TextBuffer, sizeof(TextBuffer), + GetLocString(MSG_LABEL_PROG), + lf_FileCount, + SizeCount, + lf_DirCount); + set(TX_ReadOut, MUIA_Text_Contents, TextBuffer); + + // Small cheat to avoid divide-by-zero errors... + SizeCount++; + + // Disable the details option if there are no directories... + set(BT_Details, MUIA_Disabled, (lf_DirCount == 0)); + + d1(kprintf("ListFiles(): All done\n");) + + return(TRUE); +/// +} + + +/* ULONG CopyFile(STRPTR, STRPTR, ULONG) */ +/* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */ +/* You'd think that a common operation like a copy would at least be */ +/* supported in dos.library.... ho hum. This function copies one file */ +/* to a destination (doesn't check if it exists though) though a buffer */ +/* */ +/* Parameters: */ +/* SourceName File to copy. (including path) */ +/* DestName filename of the copy (+ path) */ + +LONG CopyFile(STRPTR SourceName, STRPTR DestName, ULONG BufferSize) +{ +/// + char *Buffer = NULL; + BPTR Source = (BPTR)NULL; + BPTR Dest = (BPTR)NULL; + LONG ReadLen = 0; + + // Stats for readout.. + ULONG FileSize= 0; + ULONG Written = 0; + + LONG Result = RESULT_OK; + LONG TempSig = 0; + + d1(KPrintF("CopyFile(): Copying %s to %s, %ldk buffer specified\n", SourceName, DestName, BufferSize);) + + snprintf(TextBuffer, sizeof(TextBuffer), + GetLocString(MSG_BODY_COPYING), FilePart(SourceName)); + set(TX_Progress, MUIA_Text_Contents, TextBuffer); + set(GA_Progress, MUIA_Gauge_Current, 0); + + if(Buffer = malloc(BufferSize * 1024)) + { + d1(kprintf("CopyFile(): Buffer allocated at 0x%08lX\n", Buffer);) + + if(Source = Open(SourceName, MODE_OLDFILE)) + { + Seek(Source, 0, OFFSET_END); + FileSize = Seek(Source, 0, OFFSET_BEGINNING); + + d1(kprintf("CopyFile(): Source file opened, size is %ld bytes\n", FileSize);) + + if(Dest = Open(DestName, MODE_NEWFILE)) + { + d1(KPrintF("CopyFile(): Destination opened, doing copy\n");) + + do { + DoMethod(MUI_App, MUIM_Application_InputBuffered); + + ReadLen = Read(Source, Buffer, (BufferSize * 1024)); + if(ReadLen) + { + if(Write(Dest, Buffer, ReadLen) != ReadLen) + { + Result = RESULT_FAIL; + } + } + Written += ReadLen; + + if(FileSize > 0) + { + set(GA_Progress, MUIA_Gauge_Current, (Written * 100)/FileSize); + } + else + { + set(GA_Progress, MUIA_Gauge_Current, 100); + } + + if(DoMethod(MUI_App, MUIM_Application_NewInput, &TempSig) == STOP_IT) + Result = RESULT_HALT; + } while((ReadLen == (BufferSize * 1024)) && (Result == RESULT_OK)); + Close(Dest); + + d1(KPrintF("CopyFile(): Copy finished, copy was%s successful\n", (Result != RESULT_OK) ? " not":"");) + + if(Result != RESULT_OK) + DeleteFile(DestName); + } + else + { + Result = RESULT_FAIL; + } + Close(Source); + } + else + { + Result = RESULT_FAIL; + } + free(Buffer); + } + else + { + Result = RESULT_FAIL; + } + + d1(kprintf("CopyFile(): Copy complete\n");) + + set(TX_Progress, MUIA_Text_Contents, NULL); + set(GA_Progress, MUIA_Gauge_Current, 0); + + return(Result); +/// +} + + +/* LONG UpdateDrawer(STRPTR) */ +/* -=-=-=-=-=-=-=-=-=-=-=-=- */ +/* This calls the Scalos update routine to redraw the directory. I suppose I */ +/* could have got it to do this once all the files have been deleted, for */ +/* speed if nothing else, but that'd probably need another file list and.. */ +/* probably more trouble than it's worth IMO. */ + +void UpdateDrawer(STRPTR Name) +{ +/// + struct ScaUpdateIcon_IW Update ; + STRPTR TempPos = NULL; + + TempPos = FilePart(Name); + stccpy(FileBuffer, TempPos, MAX_FILENAME_LEN); + TempPos[0] = '\0'; + + if(Update.ui_iw_Lock = Lock(Name, SHARED_LOCK)) + { + Update.ui_iw_Name = FileBuffer; + SCA_UpdateIcon(WSV_Type_IconWindow, &Update, sizeof(struct ScaUpdateIcon_IW)); + + safe_strcat(FileBuffer, ".info", MAX_FILENAME_LEN); + SCA_UpdateIcon(WSV_Type_IconWindow, &Update, sizeof(struct ScaUpdateIcon_IW)); + + UnLock(Update.ui_iw_Lock); + } +/// +} + + +/* LONG FileDelete(STRPTR, BOOL) */ +/* -=-=-=-=-=-=-=-=-=-=-=-=-=-=- */ +/* This routine is mainly here to allow the user to confirm file deletion and*/ +/* copy the file to trash if required by the settings. If neither a confirm */ +/* or trashcan copy are required then this is a bit of a waste of space I */ +/* suppose... but it's only just over 20k anyway... */ + +LONG FileDelete(STRPTR FileName, BOOL Trash, APTR UndoStep) +{ +/// + LONG CurrentPos = 0; + IPTR Confirm = 0; + BPTR FileLk = (BPTR)NULL; + + LONG Result = 0; + LONG TempSig = 0; + + d1(KPrintF("%s/%s/%ld: processing <%s>\n", __FILE__, __FUNC__, __LINE__, FileName)); + + snprintf(TextBuffer, sizeof(TextBuffer), + GetLocString(MSG_BODY_REMOVE), FilePart(FileName)); + set(TX_Progress, MUIA_Text_Contents, TextBuffer); + + // Ask the user to confirm? + get(CM_FileConf, MUIA_Selected, &Confirm); + if(Confirm) + { + if(!MUI_Request(MUI_App, WI_Delete, 0, + (char *) GetLocString(MSG_REQ_TITLE), + (char *) GetLocString(MSG_GAD_NOYES), + (char *) GetLocString(MSG_BODY_CFILE), + FileName)) + { + return(RESULT_CANCEL); + } + } + + d1(KPrintF("%s/%s/%ld: Confirm stage passed\n", __FILE__, __FUNC__, __LINE__)); + + // Copy the file to the trashcan if required. + if(Trash) + { + d1(KPrintF("%s/%s/%ld: Attempting to copy to trashcan\n", __FILE__, __FUNC__, __LINE__)); + d1(KPrintF("%s/%s/%ld: FileBuffer=<%s> FileName=<%s>\n", __FILE__, __FUNC__, __LINE__, FileBuffer, FileName)); + + CurrentPos = strlen(FileBuffer); + if(!AddPart(FileBuffer, FilePart(FileName), MAX_FILENAME_LEN)) + { + // Unable to create filename. Bomb. + if(!MUI_Request(MUI_App, WI_Delete, 0, + (char *) GetLocString(MSG_ERROR_TITLE), + (char *) GetLocString(MSG_GAD_NOYES), + (char *) GetLocString(MSG_BODY_BUFERR), + FileName)) + { + return(RESULT_FAIL); + } + } + else + { + // got filename, copy the file. + Result = CopyFile(FileName, FileBuffer, 8); + + // Problem? + if(Result == RESULT_FAIL) + { + if(!MUI_Request(MUI_App, WI_Delete, 0, + (char *) GetLocString(MSG_ERROR_TITLE), + (char *) GetLocString(MSG_GAD_NOYES), + (char *) GetLocString(MSG_BODY_COPYFAIL), + FileName)) + { + FileBuffer[CurrentPos] = '\0'; + return(RESULT_FAIL); + } + // Stopped it completely? + } + else if(Result == RESULT_HALT) + { + FileBuffer[CurrentPos] = '\0'; + return(RESULT_HALT); + } + } + FileBuffer[CurrentPos] = '\0'; + } + + d1(KPrintF("%s/%s/%ld: Trash copy stage passed, checking for protection\n", __FILE__, __FUNC__, __LINE__)); + + // Check for protected status... + if(FileLk = Lock(FileName, SHARED_LOCK)) + { + d1(KPrintF("%s/%s/%ld: Locked file, examining\n", __FILE__, __FUNC__, __LINE__)); + + if(Examine(FileLk, GlobalFIB)) + { + d1(KPrintF("%s/%s/%ld: examined\n", __FILE__, __FUNC__, __LINE__)); + + // protected? + if(GlobalFIB->fib_Protection & FIBF_DELETE) + { + d1(KPrintF("%s/%s/%ld: File is protected, asking user to verify\n", __FILE__, __FUNC__, __LINE__)); + if(!Unprotect) + { + Result = MUI_Request(MUI_App, WI_Delete, 0, + (char *) GetLocString(MSG_REQ_TITLE), + (char *) GetLocString(MSG_GAD_PROTECT), + (char *) GetLocString(MSG_BODY_PROTECT), + FilePart(FileName)); + + if(Result == 2) + Unprotect = TRUE; + } + + d1(KPrintF("%s/%s/%ld: User replied with response %ld, Unprotect set to %s\n", \ + __FILE__, __FUNC__, __LINE__, Result, Unprotect ? "TRUE" : "FALSE")); + + if(Unprotect || (Result == 1)) + { + d1(KPrintF("%s/%s/%ld: Changing protection to 0x%08lX\n", __FILE__, __FUNC__, __LINE__, GlobalFIB->fib_Protection & ~FIBB_DELETE)); + SetProtection(FileName, GlobalFIB->fib_Protection & ~FIBF_DELETE); + } + } + + // Add to the size... + } + UnLock(FileLk); + } + else + { + d1(KPrintF("%s/%s/%ld: Lock(%s) failed, IoErr=%ld\n", __FILE__, __FUNC__, __LINE__, FileName, IoErr())); + } + + d1(KPrintF("%s/%s/%ld: protection stage passed, checking for abort and exiting\n", __FILE__, __FUNC__, __LINE__)); + + if(DoMethod(MUI_App, MUIM_Application_NewInput, &TempSig) == STOP_IT) + return(RESULT_HALT); + + return(RESULT_OK); +/// +} + + +/* LONG DeleteIcon(STRPTR, BOOL) */ +/* -=-=-=-=-=-=-=-=-=-=-=-=-=-=- */ +/* This attempts to lock the specified filename and, if the lock was obtained*/ +/* delete it. It's just a fast'n'simple way to remove the icons for files and*/ +/* directories. */ + +LONG DeleteIcon(STRPTR FileName, BOOL Trash, APTR UndoStep) +{ +/// + BPTR IconLock = (BPTR)NULL; + LONG Result = RESULT_OK; + + d1(KPrintF("%s/%s/%ld: Deleting icon <%s>\n", __FILE__, __FUNC__, __LINE__, FileName)); + + // Attempt to lock it... + if(IconLock = Lock(FileName, SHARED_LOCK)) + { + Examine(IconLock, GlobalFIB); + UnLock(IconLock); + + Result = FileDelete(FileName, Trash, UndoStep); + + if(Result == RESULT_OK) + { + if(!DeleteFile(FileName)) + { + Fault(IoErr(), (char *) GetLocString(MSG_BODY_NOICON), TextBuffer, sizeof(TextBuffer) - 1); + if ( !MUI_Request(MUI_App, WI_Delete, 0, + (char *) GetLocString(MSG_ERROR_TITLE), + (char *) GetLocString(MSG_GAD_OK_ABORT), + TextBuffer, + FileName)) + { + Result = RESULT_HALT; + } + } + } + DoneSize += GlobalFIB->fib_Size; + } + + return(Result); +/// +} + + +/* LONG DirDelete(STRPTR, BOOL) */ +/* -=-=-=-=-=-=-=-=-=-=-=-=-=-= */ +/* This is a recursive routine which attempts to remove all files and sub- */ +/* directories from the named directory before deleting it. It deleted the */ +/* sub-directories by calling itself with the new directory name. If Trash */ +/* is TRUE then the directory, and all it's contents, are copied to the */ +/* global trashcan before deleting (if one has been specified) */ + +LONG DirDelete(STRPTR DirName, BOOL Trash, APTR UndoStep) +{ +/// + struct ScaUpdateIcon_IW Update ; + struct FileInfoBlock *ExFIB = NULL; + struct FileInfoBlock OldFIB ; + ULONG Position = 0; + LONG ExNextRtn = 0; + LONG Result = 0; + LONG TempSig = 0; + BPTR TrashLock = (BPTR)NULL; + BPTR DirLock = (BPTR)NULL; + IPTR Confirm = 0; + + d1(kprintf("%s()/%ld: Trying to delete %s\n", __FUNCTION__, __LINE__, DirName);) + + DEBUG_CURRENTDIR; + + snprintf(TextBuffer, sizeof(TextBuffer), + GetLocString(MSG_BODY_REMOVE), FilePart(DirName)); + set(TX_Progress, MUIA_Text_Contents, TextBuffer); + + get(CM_DirConf, MUIA_Selected, &Confirm); + if(Confirm) + { + if(!MUI_Request(MUI_App, WI_Delete, 0, + (char *) GetLocString(MSG_REQ_TITLE), + (char *) GetLocString(MSG_GAD_NOYES), + (char *) GetLocString(MSG_BODY_CDIR), + DirName)) + { + return(RESULT_CANCEL); + } + } + + d1(kprintf("%s()/%ld: Confirm stage passed\n", __FUNCTION__, __LINE__);) + + if(Trash) + { + Position = strlen(FileBuffer); + AddPart(FileBuffer, FilePart(DirName), MAX_FILENAME_LEN); + + // Does the directory already exist? + if(!(TrashLock = Lock(FileBuffer, SHARED_LOCK))) + { + // No, try to create it. + if(!(TrashLock = CreateDir(FileBuffer))) + { + // Create failed. Moan at user. + if(!MUI_Request(MUI_App, WI_Delete, 0, + (char *) GetLocString(MSG_ERROR_TITLE), + (char *) GetLocString(MSG_GAD_NOYES), + (char *) GetLocString(MSG_BODY_BADTD))) + { + FileBuffer[Position] = '\0'; + return(RESULT_CANCEL); + } + } + } + if(TrashLock) + UnLock(TrashLock); + } + + d1(kprintf("%s()/%ld: Trashcan stage passed\n", __FUNCTION__, __LINE__);) + + if(!(ExFIB = AllocDosObject(DOS_FIB, NULL))) + { + MUI_Request(MUI_App, WI_Delete, 0, + (char *) GetLocString(MSG_ERROR_TITLE), + (char *) GetLocString(MSG_GAD_OK), + (char *) GetLocString(MSG_BODY_NOSCAN)); + if(Trash) + FileBuffer[Position] = '\0'; + return(RESULT_FAIL); + } + + d1(kprintf("%s()/%ld: Obtained FIB, locking and examining, DirName=<%s>\n", __FUNCTION__, __LINE__, DirName);) + + if(DirLock = Lock(DirName, SHARED_LOCK)) + { + BPTR OldDir; + + OldDir = CurrentDir(DirLock); + + DEBUG_CURRENTDIR; + + if(Examine(DirLock, ExFIB)) + { + d1(kprintf("%s()/%ld: Examined, checking protection\n", __FUNCTION__, __LINE__);) + + // protected? + if(ExFIB->fib_Protection & FIBF_DELETE) + { + if(!Unprotect) + { + Result = MUI_Request(MUI_App, WI_Delete, 0, + (char *) GetLocString(MSG_REQ_TITLE), + (char *) GetLocString(MSG_GAD_PROTECT), + (char *) GetLocString(MSG_BODY_PROTECT), + FilePart(DirName)); + + if(Result == 2) + Unprotect = TRUE; + } + + if(Unprotect || (Result == 1)) + { + SetProtection(DirName, ExFIB->fib_Protection - FIBB_DELETE); + } + } + + d1(kprintf("%s()/%ld: Protection stage complete, checking contents\n", __FUNCTION__, __LINE__);) + + DEBUG_CURRENTDIR; + + if(ExNext(DirLock, ExFIB)) + { + do { + DEBUG_CURRENTDIR; + + DoMethod(MUI_App, MUIM_Application_InputBuffered); + + // Copy and jump to next entry (allows delete). + OldFIB = *ExFIB; + ExNextRtn = ExNext(DirLock, ExFIB); + + DEBUG_CURRENTDIR; + d1(kprintf("%s()/%ld: fib_DirEntryType=%ld\n", __FUNCTION__, __LINE__, OldFIB.fib_DirEntryType);) + + if (ST_SOFTLINK == OldFIB.fib_DirEntryType) + { + // It's a softlink! + d1(kprintf("%s()/%ld: <%s> is a softlink, removing it\n", __FUNCTION__, __LINE__, OldFIB.fib_FileName);) + + Result = FileDelete(OldFIB.fib_FileName, Trash, UndoStep); + d1(kprintf("%s()/%ld: FileDelete() returned %ld\n", __FUNCTION__, __LINE__, Result);) + if(Result == RESULT_OK) + { + d1(kprintf("%s()/%ld: calling DeleteFile(%s)\n", __FUNCTION__, __LINE__, OldFIB.fib_FileName);) + if(!DeleteFile(OldFIB.fib_FileName)) + { + Fault(IoErr(), (char *) GetLocString(MSG_BODY_NODEL), TextBuffer, sizeof(TextBuffer) - 1); + if (!MUI_Request(MUI_App, WI_Delete, 0, + (char *) GetLocString(MSG_ERROR_TITLE), + (char *) GetLocString(MSG_GAD_OK_ABORT), + TextBuffer, + OldFIB.fib_FileName)) + { + CurrentDir(OldDir); + UnLock(DirLock); + return RESULT_HALT; + } + } + } + + DoneSize += OldFIB.fib_Size; + } + else if(OldFIB.fib_DirEntryType < 0) + { + // It's a file! + d1(kprintf("%s()/%ld: <%s> is a file, removing it\n", __FUNCTION__, __LINE__, OldFIB.fib_FileName);) + + { + BPTR fLock = Lock(OldFIB.fib_FileName, ACCESS_READ); + if (fLock) + UnLock(fLock); + else + d1(KPrintF("%s/%s/%ld: Lock(%s) failed, IoErr=%ld\n", __FILE__, __FUNC__, __LINE__, OldFIB.fib_FileName, IoErr())); + } + + Result = FileDelete(OldFIB.fib_FileName, Trash, UndoStep); + d1(kprintf("%s()/%ld: FileDelete() returned %ld\n", __FUNCTION__, __LINE__, Result);) + if(Result == RESULT_OK) + { + d1(kprintf("%s()/%ld: calling DeleteFile(%s)\n", __FUNCTION__, __LINE__, OldFIB.fib_FileName);) + if(!DeleteFile(OldFIB.fib_FileName)) + { + Fault(IoErr(), (char *) GetLocString(MSG_BODY_NODEL), TextBuffer, sizeof(TextBuffer) - 1); + if (!MUI_Request(MUI_App, WI_Delete, 0, + (char *) GetLocString(MSG_ERROR_TITLE), + (char *) GetLocString(MSG_GAD_OK_ABORT), + TextBuffer, + OldFIB.fib_FileName)) + { + CurrentDir(OldDir); + UnLock(DirLock); + return RESULT_HALT; + } + } + } + + DoneSize += OldFIB.fib_Size; + } + else + { + d1(kprintf("%s()/%ld: %s is a directory, removing it\n", __FUNCTION__, __LINE__, OldFIB.fib_FileName);) + + Result = DirDelete(OldFIB.fib_FileName, Trash, UndoStep); + if(Result == RESULT_OK) + { + if(!DeleteFile(OldFIB.fib_FileName)) + { + Fault(IoErr(), (char *) GetLocString(MSG_BODY_NODEL), TextBuffer, sizeof(TextBuffer) - 1); + if (!MUI_Request(MUI_App, WI_Delete, 0, + (char *) GetLocString(MSG_ERROR_TITLE), + (char *) GetLocString(MSG_GAD_OK_ABORT), + TextBuffer, + OldFIB.fib_FileName)) + { + CurrentDir(OldDir); + UnLock(DirLock); + return RESULT_HALT; + } + + } + } + } + + d1(kprintf("%s()/%ld: Updating directory window\n", __FUNCTION__, __LINE__);) + + // Update the window. This must be done as the window for the + // directory could, in theory, be opened already... + Update.ui_iw_Lock = DirLock; + Update.ui_iw_Name = OldFIB.fib_FileName; + SCA_UpdateIcon(WSV_Type_IconWindow, &Update, sizeof(struct ScaUpdateIcon_IW)); + + if(DoMethod(MUI_App, MUIM_Application_NewInput, &TempSig) == STOP_IT) + Result = RESULT_HALT; + + // Only bother to update the GUI if the details have been obtained.. + if(GotDetails) + set(GA_Progress, MUIA_Gauge_Current, (DoneSize * 100) / SizeCount); + } while(ExNextRtn && (Result != RESULT_HALT)); + } + } + CurrentDir(OldDir); + UnLock(DirLock); + } + + d1(kprintf("%s()/%ld: Finished working\n", __FUNCTION__, __LINE__);) + + FreeDosObject(DOS_FIB, ExFIB); + if(Trash) + FileBuffer[Position] = '\0'; + + DEBUG_CURRENTDIR; + + if(Result == RESULT_HALT) + return(RESULT_HALT); + else + return(RESULT_OK); +/// +} + + +/* void KillFiles(WBStartup *) */ +/* -=-=-=-=-=-=-=-=-=-=-=-=-=- */ +/* This is the routine which attempts to delete the files the user selected */ +/* on the Scalos screen. Files are simply deleted (along with their icons) */ +/* but directories are deleted by the DirDelete() routine. */ + +void KillFiles(struct WBStartup *WBStart) +{ +/// + struct ScaUpdateIcon_IW kf_Update ; + struct WBArg *kf_Args = WBStart->sm_ArgList; + struct FileInfoBlock *kf_Fib = NULL; + LONG kf_Num = 0; + BPTR kf_File = (BPTR)NULL; + LONG kf_Result = 0; + IPTR Trash = FALSE; + STRPTR TrashDir = NULL; + APTR UndoStep = NULL; + struct ScaWindowStruct *ws = NULL; + struct ScaWindowList *wl; + + d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__)); + + get(CM_TrashCan, MUIA_Selected, &Trash); + + wl = SCA_LockWindowList(SCA_LockWindowList_Shared); + if (wl) + { + struct ScaWindowStruct *ws = wl->wl_WindowStruct; + + UndoStep = (APTR) DoMethod(ws->ws_WindowTask->mt_MainObject, + SCCM_IconWin_BeginUndoStep); + + SCA_UnLockWindowList(); + } + + if(Trash) + { + get(ST_TrashDir, MUIA_String_Contents, &TrashDir); + } + + if(!(kf_Fib = AllocDosObject(DOS_FIB, NULL))) + { + MUI_Request(MUI_App, WI_Delete, 0, + (char *) GetLocString(MSG_ERROR_TITLE), + (char *) GetLocString(MSG_GAD_OK), + (char *) GetLocString(MSG_BODY_NOLIST)); + return; + } + + if(!(GlobalFIB = AllocDosObject(DOS_FIB, NULL))) + { + MUI_Request(MUI_App, WI_Delete, 0, + (char *) GetLocString(MSG_ERROR_TITLE), + (char *) GetLocString(MSG_GAD_OK), + (char *) GetLocString(MSG_BODY_NOLIST)); + return; + } + + set(GP_Progress, MUIA_ShowMe, TRUE); + + for(kf_Num = 1; ((kf_Num < WBStart->sm_NumArgs) && (kf_Result != RESULT_HALT)); kf_Num ++) + { + DoMethod(MUI_App, MUIM_Application_InputBuffered); + + if(Trash) + { + struct ScaWindowStruct *wsFile; + + if(estrlen(TrashDir)) + { + stccpy(FileBuffer, TrashDir, MAX_FILENAME_LEN); + } + else + { + stccpy(FileBuffer, "SYS:TrashCan/", MAX_FILENAME_LEN); + } + + wsFile = FindScalosWindow(kf_Args[kf_Num].wa_Lock); + if (wsFile) + { + DoMethod(wsFile->ws_WindowTask->mt_MainObject, + SCCM_IconWin_AddUndoEvent, + UNDO_Delete, + UNDOTAG_CopySrcDirLock, kf_Args[kf_Num].wa_Lock, + UNDOTAG_CopySrcName, kf_Args[kf_Num].wa_Name, + UNDOTAG_CopyDestName, FileBuffer, + TAG_END + ); + + SCA_UnLockWindowList(); + } + } + + d1(KPrintF("%s/%s/%ld: Processing %ld\n", __FILE__, __FUNC__, __LINE__, kf_Num)); + + // If got a lock, change to it + if(kf_Args[kf_Num].wa_Lock) + { + BPTR kf_Old; + + kf_Old = CurrentDir(kf_Args[kf_Num].wa_Lock); + + d1(KPrintF("%s/%s/%ld: Filename: %s Lock: 0x%08lX\n", __FILE__, __FUNC__, __LINE__, kf_Args[kf_Num].wa_Name, kf_Args[kf_Num].wa_Lock)); + + // Got a filename? + if(estrlen(kf_Args[kf_Num].wa_Name)) + { + d1(KPrintF("%s/%s/%ld: Passed estrlen()\n", __FILE__, __FUNC__, __LINE__)); + + // Lock it... + if(kf_File = Lock(kf_Args[kf_Num].wa_Name, ACCESS_READ)) + { + d1(KPrintF("%s/%s/%ld: Passed Lock()\n", __FILE__, __FUNC__, __LINE__)); + + // Grab the FIB and bung it in the files list. + Examine(kf_File, kf_Fib); + UnLock(kf_File); + + if (kf_Fib->fib_DirEntryType < 0) + { + kf_Result = FileDelete(kf_Fib->fib_FileName, Trash, UndoStep); + if(kf_Result == RESULT_OK) + { + if(!DeleteFile(kf_Fib->fib_FileName)) + { + Fault(IoErr(), (char *) GetLocString(MSG_BODY_NODEL), TextBuffer, sizeof(TextBuffer) - 1); + MUI_Request(MUI_App, WI_Delete, 0, + (char *) GetLocString(MSG_ERROR_TITLE), + (char *) GetLocString(MSG_GAD_OK), + TextBuffer, + kf_Fib->fib_FileName); + } + + stccpy(PathBuffer, kf_Fib->fib_FileName, MAX_FILENAME_LEN); + safe_strcat(PathBuffer, ".info", MAX_FILENAME_LEN); + + kf_Result = DeleteIcon(PathBuffer, Trash, UndoStep); + } + } + else + { + kf_Result = DirDelete(DirBuffer, Trash, UndoStep); + if(kf_Result == RESULT_OK) + { + UnLock(kf_Args[kf_Num].wa_Lock); + kf_Args[kf_Num].wa_Lock = (BPTR)NULL; + + if(!DeleteFile(DirBuffer)) + { + Fault(IoErr(), (char *) GetLocString(MSG_BODY_NODEL), TextBuffer, sizeof(TextBuffer) - 1); + MUI_Request(MUI_App, WI_Delete, 0, + (char *) GetLocString(MSG_ERROR_TITLE), + (char *) GetLocString(MSG_GAD_OK), + TextBuffer, + DirBuffer); + } + + safe_strcat(DirBuffer, ".info", MAX_FILENAME_LEN); + kf_Result = DeleteIcon(DirBuffer, Trash, UndoStep); + + DirBuffer[strlen(DirBuffer) - 5] = '\0'; + UpdateDrawer(DirBuffer); + } + } + DoneSize += kf_Fib->fib_Size; + } + else + { + d1(KPrintF("%s/%s/%ld: Failed Lock()\n", __FILE__, __FUNC__, __LINE__)); + + stccpy(PathBuffer, kf_Args[kf_Num].wa_Name, MAX_FILENAME_LEN); + safe_strcat(PathBuffer, ".info", MAX_FILENAME_LEN); + + kf_Result = DeleteIcon(PathBuffer, Trash, UndoStep); + } + + // Better get back to home. + CurrentDir(kf_Old); + + d1(KPrintF("%s/%s/%ld: Updating\n", __FILE__, __FUNC__, __LINE__)); + + kf_Update.ui_iw_Lock = kf_Args[kf_Num].wa_Lock; + kf_Update.ui_iw_Name = kf_Args[kf_Num].wa_Name; + SCA_UpdateIcon(WSV_Type_IconWindow, &kf_Update, sizeof(struct ScaUpdateIcon_IW)); + + kf_Update.ui_iw_Lock = kf_Args[kf_Num].wa_Lock; + kf_Update.ui_iw_Name = PathBuffer; + SCA_UpdateIcon(WSV_Type_IconWindow, &kf_Update, sizeof(struct ScaUpdateIcon_IW)); + + // No name. Must be a directory :/ + } + else + { + CurrentDir(kf_Old); + + // Resolve a name... + NameFromLock(kf_Args[kf_Num].wa_Lock, DirBuffer, 256); + + if(!strcmp(DirBuffer, FileBuffer)) + { + MUI_Request(MUI_App, WI_Delete, 0, + (char *) GetLocString(MSG_ERROR_TITLE), + (char *) GetLocString(MSG_GAD_OK), + "\33c%s\nis the trashcan!\nUse the \"Empty Trashcan\"\nto clear it"); + } + else + { + kf_Result = DirDelete(DirBuffer, Trash, UndoStep); + if(kf_Result == RESULT_OK) + { + UnLock(kf_Args[kf_Num].wa_Lock); + kf_Args[kf_Num].wa_Lock = (BPTR)NULL; + + if(!DeleteFile(DirBuffer)) + { + Fault(IoErr(), (char *) GetLocString(MSG_BODY_NODEL), TextBuffer, sizeof(TextBuffer) - 1); + MUI_Request(MUI_App, WI_Delete, 0, + (char *) GetLocString(MSG_ERROR_TITLE), + (char *) GetLocString(MSG_GAD_OK), + TextBuffer, + DirBuffer); + } + + safe_strcat(DirBuffer, ".info", MAX_FILENAME_LEN); + kf_Result = DeleteIcon(DirBuffer, Trash, UndoStep); + + DirBuffer[strlen(DirBuffer) - 5] = '\0'; + UpdateDrawer(DirBuffer); + } + } + } + } + d1(KPrintF("%s/%s/%ld: Processing complete\n", __FILE__, __FUNC__, __LINE__)); + + set(GA_Progress, MUIA_Gauge_Current, (DoneSize * 100) / SizeCount); + } + + // Release the fibs... + FreeDosObject(DOS_FIB, kf_Fib ); + FreeDosObject(DOS_FIB, GlobalFIB); + + if (ws) + { + if (UndoStep) + { + DoMethod(ws->ws_WindowTask->mt_MainObject, + SCCM_IconWin_EndUndoStep, + UndoStep); + } + SCA_UnLockWindowList(); + } + + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); +/// +} + + +/* void DirCount(STRPTR, DetailStats *) */ +/* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ +/* Resursive directory & file count routine. If the user has selected one or */ +/* more directories then this handles counting the number of files and sub- */ +/* directories within the selected directories. It calls itself to compile */ +/* the information on any directories it encountered. */ + +void DirCount(STRPTR DirName, struct DetailStats *Stats) +{ +/// + struct FileInfoBlock *ExFIB = NULL; + struct FileInfoBlock OldFIB ; + LONG ExNextRtn = 0; + BPTR DirLock = (BPTR)NULL; + + snprintf(TextBuffer, sizeof(TextBuffer), + GetLocString(MSG_BODY_SCAN), FilePart(DirName)); + set(TX_Progress, MUIA_Text_Contents, TextBuffer); + + // Allocate some room for the FIB.. + if(!(ExFIB = AllocDosObject(DOS_FIB, NULL))) + { + MUI_Request(MUI_App, WI_Delete, 0, + (char *) GetLocString(MSG_ERROR_TITLE), + (char *) GetLocString(MSG_GAD_OK), + (char *) GetLocString(MSG_BODY_NOSCAN)); + return; + } + + // Lock and change to the directory.... + if(DirLock = Lock(DirName, SHARED_LOCK)) + { + BPTR OldDir; + + OldDir = CurrentDir(DirLock); + + if(Examine(DirLock, ExFIB)) + { + if(ExNext(DirLock, ExFIB)) + { + do { + DoMethod(MUI_App, MUIM_Application_InputBuffered); + + // Copy and jump to next entry (allows delete). + CopyMem(ExFIB, &OldFIB, sizeof(struct FileInfoBlock)); + ExNextRtn = ExNext(DirLock, ExFIB); + + if(OldFIB.fib_DirEntryType < 0) + { + // It's a file! + Stats->ds_Files ++; + Stats->ds_Bytes += OldFIB.fib_Size; + } + else + { + // It's a directory. Recurse down a level.. + Stats->ds_Dirs ++; + DirCount(OldFIB.fib_FileName, Stats); + } + + } while(ExNextRtn); + } + } + CurrentDir(OldDir); + UnLock(DirLock); + } + + FreeDosObject(DOS_FIB, ExFIB); +/// +} + + +/* BOOL GetDetails(WBStartup *) */ +/* -=-=-=-=-=-=-=-=-=-=-=-=-=-= */ +/* Very similar to ListFiles() except this obtains the statistics for the */ +/* whole tree of selected directories (ie: it gives a much better picture of */ +/* exactly how much really needs to be deleted). This uses DirCount() to */ +/* obtain the info on directories and devices and it will, almost certainly, */ +/* take a fair amount of time to complete (not to mention eat stack space...)*/ + +BOOL GetDetails(struct WBStartup *WBStart) +{ +/// + struct WBArg *gd_Args = WBStart->sm_ArgList; + struct FileInfoBlock *gd_Fib = NULL; + struct DetailStats gd_Details = { 0, 0, 0 }; + LONG gd_Num = 0; + BPTR gd_File = (BPTR)NULL; + + + if(MUI_Request(MUI_App, WI_Delete, 0, + (char *) GetLocString(MSG_WARN_TITLE), + (char *) GetLocString(MSG_GAD_NOYES), + (char *) GetLocString(MSG_BODY_DETAIL))) + { + if(!(gd_Fib = AllocDosObject(DOS_FIB, NULL))) + { + MUI_Request(MUI_App, WI_Delete, 0, + (char *) GetLocString(MSG_ERROR_TITLE), + (char *) GetLocString(MSG_GAD_OK), + (char *) GetLocString(MSG_BODY_NOLIST )); + return(FALSE); + } + + set(MUI_App, MUIA_Application_Sleep, TRUE); + + for(gd_Num = 1; gd_Num < WBStart->sm_NumArgs; gd_Num ++) + { + // If got a lock, change to it + if(gd_Args[gd_Num].wa_Lock) + { + BPTR gd_Old; + + gd_Old = CurrentDir(gd_Args[gd_Num].wa_Lock); + + // Got a filename? + if(estrlen(gd_Args[gd_Num].wa_Name)) + { + // Lock it... + if(gd_File = Lock(gd_Args[gd_Num].wa_Name, ACCESS_READ)) + { + Examine(gd_File, gd_Fib); + if(gd_Fib->fib_DirEntryType < 0) + { + // File, add to the file stuff.... + gd_Details.ds_Files ++; + gd_Details.ds_Bytes += gd_Fib->fib_Size; + } + UnLock(gd_File); + } + + // Try for the icon too... + stccpy(FileBuffer, gd_Args[gd_Num].wa_Name, MAX_FILENAME_LEN); + safe_strcat(FileBuffer, ".info", MAX_FILENAME_LEN); + + if(gd_File = Lock(FileBuffer, ACCESS_READ)) + { + // Grab the FIB and bung it in the files list. + Examine(gd_File, gd_Fib); + if(gd_Fib->fib_DirEntryType < 0) + { + gd_Details.ds_Files ++; + gd_Details.ds_Bytes += gd_Fib->fib_Size; + } + UnLock(gd_File); + } + + // No filename, must be a directory + } + else + { + // Resolve a name... + NameFromLock(gd_Args[gd_Num].wa_Lock, FileBuffer, MAX_FILENAME_LEN); + + // Directory or volume, ours is not to reason why.... + Examine (gd_Args[gd_Num].wa_Lock, gd_Fib); + gd_Details.ds_Dirs ++; + DirCount(FileBuffer, &gd_Details); + + // Try for the icon again... + safe_strcat(FileBuffer, ".info", MAX_FILENAME_LEN); + + if(gd_File = Lock(FileBuffer, ACCESS_READ)) + { + // Grab the FIB and bung it in the files list. + Examine(gd_File, gd_Fib); + if(gd_Fib->fib_DirEntryType < 0) + { + gd_Details.ds_Files ++; + gd_Details.ds_Bytes += gd_Fib->fib_Size; + } + UnLock(gd_File); + } + } + + // Better get back to home. + CurrentDir(gd_Old); + } + } + + // better not forget this.... + FreeDosObject(DOS_FIB, gd_Fib); + + snprintf(TextBuffer, sizeof(TextBuffer), + GetLocString(MSG_LABEL_PROG), + gd_Details.ds_Files, + gd_Details.ds_Bytes, + gd_Details.ds_Dirs); + set(TX_ReadOut, MUIA_Text_Contents, TextBuffer); + + SizeCount = gd_Details.ds_Bytes + 1; + GotDetails = TRUE; + + set(TX_Progress, MUIA_Text_Contents, NULL); + set(MUI_App, MUIA_Application_Sleep, FALSE); + } + + return(TRUE); +/// +} + +//---------------------------------------------------------------------------- + +/// +static struct ScaWindowStruct *FindScalosWindow(BPTR dirLock) +{ + struct ScaWindowList *wl; + BOOL Found = FALSE; + + d1(KPrintF(__FILE__ "/%s/%ld: START \n", __FUNC__, __LINE__)); + + wl = SCA_LockWindowList(SCA_LockWindowList_Shared); + + if (wl) + { + struct ScaWindowStruct *ws; + + for (ws = wl->wl_WindowStruct; !Found && ws; ws = (struct ScaWindowStruct *) ws->ws_Node.mln_Succ) + { + if ((BNULL == dirLock && BNULL == ws->ws_Lock) || (LOCK_SAME == SameLock(dirLock, ws->ws_Lock))) + { + return ws; + } + } + SCA_UnLockWindowList(); + } + + return NULL; +} +/// + +//---------------------------------------------------------------------------- + diff --git a/scalos/Modules/Delete.MUI/Source/Delete.module_rev.h b/scalos/Modules/Delete.MUI/Source/Delete.module_rev.h new file mode 100755 index 000000000..7b4a50972 --- /dev/null +++ b/scalos/Modules/Delete.MUI/Source/Delete.module_rev.h @@ -0,0 +1,18 @@ +// Delete.module.h +// $Date$ +// $Revision$ + +#define VERSION 1 +#define REVISION 13 +#define DATE "10.01.2010" +#define VERS "Delete.module " STR(VERSION) "." STR(REVISION) +#define VSTRING "Delete.module " STR(VERSION) "." STR(REVISION) " " DATE "\r\n" +#define VERSTAG "\0$VER: Delete.module V" STR(VERSION) "." STR(REVISION) " " DATE COMPILER_STRING +#define VSTR "Delete.module " STR(VERSION) "." STR(REVISION) " " DATE +#define USER "worldfoundry" +#define HOST "worldfoundry.demon.co.uk" +#define TIME "13:37:18" +#define PRGNAME "Delete.module" +#define BASENAME "DELETE.MODULE" +#define _CREATIONDATE_ "12.11.1998" +#define _COPYRIGHTYEARS_ "1998-2010" diff --git a/scalos/Modules/Delete.MUI/Source/Delete.module_rev.log b/scalos/Modules/Delete.MUI/Source/Delete.module_rev.log new file mode 100644 index 000000000..ae6bcd3b0 --- /dev/null +++ b/scalos/Modules/Delete.MUI/Source/Delete.module_rev.log @@ -0,0 +1,74 @@ + +Delete.module 0.1 (12.11.1998) 14:07:38 by chris@worldfoundry.demon.co.uk + +Started, shouldn't take long (he says hopefully...) + + +Delete.module 0.2 (13.11.1998) 14:38:49 by chris@worldfoundry.demon.co.uk + +interface complete, selection listing working. Tested as real scalos module +sucessfully. Adding delete code presently + + +Delete.module 0.3 (14.11.1998) 11:33:10 by chris@worldfoundry.demon.co.uk + +Almost everything working. Only major problems so far caused by some +incorrect directory scanning. + + +Delete.module 1.0 (14.11.1998) 17:46:09 by chris@worldfoundry.demon.co.uk + +Finally got everything working. Some of the more fun bugs include the rather stupid attempt to +delete icons twice in a recursive directory delete (once implicitly and once explicitly) and +fun with Storm's optimister (program crashes on 9, set back to 1 and compiler, runs, set back +to 9, compile, runs again... don'tcha love it..) +Anyway, 'tis done. Enjoy + + +Delete.module 1.1 (24.11.1998) 21:14:51 by worldfoundry@worldfoundry.demon.co.uk + +Added automatic update of icons (after remaking half the Scalos include files to work in Storm!) + + +Delete.module 1.2 (26.11.1998) 14:26:50 by worldfoundry@worldfoundry.demon.co.uk + +Fixed non-update of "drawerless" drawer icons. + + +Delete.module 1.3 (28.11.1998) 16:42:58 by worldfoundry@worldfoundry.demon.co.uk + +Found the cause of the lockups on some people's systems - I'd not removed some of the +debug code (DOH!). Fixed in this version, as well as a slight optimisation of the +directory delete code. + + +Delete.module 1.4 (18.12.1998) 19:53:17 by worldfoundry@worldfoundry.demon.co.uk + +BUGGER!!! I didn't take files with 0 length into account in the progress display. This would cause +divide by 0 errors. This version has some extra checks to deal with the problem. + + +Delete.module 1.5 (1.7.1999) 18:10:07 by worldfoundry@worldfoundry.demon.co.uk + +Added "remove protection" option, localised code. Started converting to GNU GPL license & +ensuring code comments are up to scratch.... + + +Delete.module 1.6 (2.7.1999) 14:02:40 by worldfoundry@worldfoundry.demon.co.uk + +Added details scanning routine. + + +Delete.module 1.7 (3.7.1999) 15:11:56 by worldfoundry@worldfoundry.demon.co.uk + +Removed automatic save of preferences settings, added gadgets to do the work (pointless saving +every time the program is used! :/) + + +Delete.module 1.8 (5.7.1999) 18:57:18 by worldfoundry@worldfoundry.demon.co.uk + +Volume delete warning should now open in the correct place, About window title is localised (I +always have to miss one of the buggers), fixed a problem with the version string in Exchange - +RevUp's VERSTAG isn't really suitable for the MUI version data..... + + diff --git a/scalos/Modules/Delete.MUI/Source/Delete.module_rev.rev b/scalos/Modules/Delete.MUI/Source/Delete.module_rev.rev new file mode 100755 index 000000000..d41150b8a --- /dev/null +++ b/scalos/Modules/Delete.MUI/Source/Delete.module_rev.rev @@ -0,0 +1,3 @@ +8 +0 +12.11.1998 diff --git a/scalos/Modules/Delete.MUI/Source/Delete.module_strings.h b/scalos/Modules/Delete.MUI/Source/Delete.module_strings.h new file mode 100755 index 000000000..4f0bfaf77 --- /dev/null +++ b/scalos/Modules/Delete.MUI/Source/Delete.module_strings.h @@ -0,0 +1,275 @@ +// Delete.module_strings.h +// $Date$ +// $Revision$ + +// ___ ___ +// _/ /_______\ \_ ___ ___ __ _ _ __ ___ ___ +//__// / _______ \ \\___/ \___ +//_/ | ' \__ __/ ` | \_/ © Copyright 1999, Christopher Page \__ +// \ | | | |__ | | / \ Released as Free Software under the GNU GPL / +// >| . | _/ . |< >--- --- -- - - -- --- ---< +// / \ \ | | / / \ / This file is part of the ScalosDelete code \ +// \ \ \_/ \_/ / / \ and it is released under the GNU GPL. Please / +// \ \ / / \ read the "COPYING" file which should have / +// //\ \_________/ /\\ //\ been included in the distribution arc. / +//- --\ _______ /-- - --\ for full details of the license /----- +//-----\_/ \_/---------\ ___________________________________ /------ +// \_/ \_/ +// +// Description: +// +// Default locale strings (English) +// +// Modification History: +// +// [02 June 1999, Chris ] +// +// Converted to GNU GPL license, finally used the correct numbers for the +// ID_s! +// +// + +#define ID_APP_TITLE 1 +#define MSG_APP_TITLE "Delete.module" + +#define ID_APP_DESC 2 +#define MSG_APP_DESC "Replacement for Scalos Delete.module" + +#define ID_WIN_TITLE 3 +#define MSG_WIN_TITLE "Delete" + +#define ID_ASL_TITLE 4 +#define MSG_ASL_TITLE "Select Trashcan directory" + +#define ID_PAGES_FILES 5 +#define MSG_PAGES_FILES "Files" + +#define ID_PAGES_PREFS 6 +#define MSG_PAGES_PREFS "Preferences" + +#define ID_LABEL_TRASH 7 +#define MSG_LABEL_TRASH "Use trashcan?" + +#define ID_LABEL_DIRS 8 +#define MSG_LABEL_DIRS "Confirm dir delete?" + +#define ID_LABEL_FILES 9 +#define MSG_LABEL_FILES "Confirm file delete?" + +#define ID_LABEL_QUIET 10 +#define MSG_LABEL_QUIET "Quiet start" + +#define ID_LABEL_TLOC 11 +#define MSG_LABEL_TLOC "Trashcan Location" + +#define ID_LABEL_INFO 12 +#define MSG_LABEL_INFO "Done %ld%%" + +#define ID_LABEL_PROG 13 +#define MSG_LABEL_PROG "Selected: %ld files [%ld bytes], %ld directories" + +#define ID_LABEL_VERS 14 +#define MSG_LABEL_VERS "Version:" + +#define ID_LABEL_COMP 15 +#define MSG_LABEL_COMP "Compiled:" + +#define ID_BUTTON_FULL 16 +#define MSG_BUTTON_FULL "Details" + +#define ID_BUTTON_DEL 17 +#define MSG_BUTTON_DEL "Delete" + +#define ID_BUTTON_ABT 18 +#define MSG_BUTTON_ABT "About" + +#define ID_BUTTON_CAN 19 +#define MSG_BUTTON_CAN "Cancel" + +#define ID_BUTTON_STOP 20 +#define MSG_BUTTON_STOP "STOP!" + +#define ID_BUTTON_AMUI 21 +#define MSG_BUTTON_AMUI "About MUI" + +#define ID_BUTTON_SAVE 22 +#define MSG_BUTTON_SAVE "Save" + +#define ID_BUTTON_USE 23 +#define MSG_BUTTON_USE "Use" + +#define ID_BUTTON_REST 24 +#define MSG_BUTTON_REST "Restore" + +#define ID_KEY_DETAILS 25 +#define MSG_KEY_DETAILS "e" + +#define ID_KEY_TRASH 26 +#define MSG_KEY_TRASH "t" + +#define ID_KEY_DIRS 27 +#define MSG_KEY_DIRS "o" + +#define ID_KEY_FILES 28 +#define MSG_KEY_FILES "n" + +#define ID_KEY_QUIET 29 +#define MSG_KEY_QUIET "q" + +#define ID_KEY_TLOC 30 +#define MSG_KEY_TLOC "l" + +#define ID_KEY_SAVE 31 +#define MSG_KEY_SAVE "v" + +#define ID_KEY_USE 32 +#define MSG_KEY_USE "u" + +#define ID_KEY_REST 33 +#define MSG_KEY_REST "r" + +#define ID_KEY_DELETE 34 +#define MSG_KEY_DELETE "d" + +#define ID_KEY_ABOUT 35 +#define MSG_KEY_ABOUT "a" + +#define ID_KEY_CANCEL 36 +#define MSG_KEY_CANCEL "c" + +#define ID_KEY_STOP 37 +#define MSG_KEY_STOP "s" + +#define ID_KEY_AMUI 38 +#define MSG_KEY_AMUI "m" + +#define ID_HELP_TRASH 39 +#define MSG_HELP_TRASH "\33cFiles are moved to\nSYS:Trashcan\nrather than being\nremoved completely" + +#define ID_HELP_DIRS 40 +#define MSG_HELP_DIRS "\33cIf set, you must confirm that\na directory should be deleted" + +#define ID_HELP_FILES 41 +#define MSG_HELP_FILES "\33cIf set, you must confirm every\nfile delete operation" + +#define ID_HELP_QUIET 42 +#define MSG_HELP_QUIET "\33cIf set, the about window is not\nshown when the program starts" + +#define ID_HELP_TLOC 43 +#define MSG_HELP_TLOC "\33cLocation of the trashcan used\nif \"Use Trashcan\" is set" + +#define ID_LVT_NAME 44 +#define MSG_LVT_NAME "\33bName\33n" + +#define ID_LVT_SIZE 45 +#define MSG_LVT_SIZE "Size" + +#define ID_LVT_DATE 46 +#define MSG_LVT_DATE "Date" + +#define ID_LVT_TIME 47 +#define MSG_LVT_TIME "Time" + +#define ID_ERROR_TITLE 48 +#define MSG_ERROR_TITLE "Delete module error" + +#define ID_WARN_TITLE 49 +#define MSG_WARN_TITLE "Delete module warning" + +#define ID_REQ_TITLE 50 +#define MSG_REQ_TITLE "Delete module request" + +#define ID_GAD_OK 51 +#define MSG_GAD_OK "*_Ok" + +#define ID_GAD_NOYES 52 +#define MSG_GAD_NOYES "_Yes|*_No" + +#define ID_GAD_PROTECT 53 +#define MSG_GAD_PROTECT "_Yes|_All files|*_No" + +#define ID_BODY_NOFILES 54 +#define MSG_BODY_NOFILES "\33cNo files have been selected!\n\nOperation aborted" + +#define ID_BODY_NOLIST 55 +#define MSG_BODY_NOLIST "\33cUnable to create internal lists\n\nOperation aborted" + +#define ID_BODY_VOLUME 56 +#define MSG_BODY_VOLUME "\33cDetected an attempt to delete volume\n\33b%s\33n\nAre you \33bsure\33n you want to do this?!?" + +#define ID_BODY_CFILE 57 +#define MSG_BODY_CFILE "\33cAre you sure you want to delete file\n%s" + +#define ID_BODY_BUFERR 58 +#define MSG_BODY_BUFERR "\33cUnable to copy\n%s\nto trashcan\nOut of buffer space.\nContinue to delete the file?" + +#define ID_BODY_COPYFAIL 59 +#define MSG_BODY_COPYFAIL "\33cUnable to copy\n%s\nto trashcan\nError writing to trashcan\nContinue to delete the file?" + +#define ID_BODY_NOICON 60 +#define MSG_BODY_NOICON "\33cUnable to delete icon\n%s" + +#define ID_BODY_CDIR 61 +#define MSG_BODY_CDIR "\33cAre you sure you want to delete directory\n%s" + +#define ID_BODY_BADTD 62 +#define MSG_BODY_BADTD "\33cUnable to create directory\nin Trashcan.\nContinue?" + +#define ID_BODY_NOSCAN 63 +#define MSG_BODY_NOSCAN "\33cUnable to scan directory\nDirectory aborted" + +#define ID_BODY_PROTECT 64 +#define MSG_BODY_PROTECT "\33c%s\nis protected from deletion\nRemove the protection?" + +#define ID_BODY_NODEL 65 +#define MSG_BODY_NODEL "\33c%s\nnot deleted" + +#define ID_BODY_COPYING 66 +#define MSG_BODY_COPYING "Copying %s to trashcan" + +#define ID_BODY_REMOVE 67 +#define MSG_BODY_REMOVE "Removing %s" + +#define ID_BODY_SCAN 68 +#define MSG_BODY_SCAN "Scanning %s" + +#define ID_BODY_DETAIL 69 +#define MSG_BODY_DETAIL "\33c\0338WARNING\0330\nThis operation may take a long time\nto complete and may not be\naborted. Continue?" + + +// The following lines *MAY NOT* be modified. They are the copyright notice +// and GNU GPL notice. Removing these violates the GNU GPL agreemenT! +#define ID_ABOUT_HEAD 70 +#define MSG_ABOUT_HEAD "\n\33b\33c\0338ScalosDelete\0330\33n\n"\ +" Copyright 1999 Chris Page, \n"\ +" The World Foundry LLC \n\n"\ +" Contact: \33ichris \n" + +#define ID_ABOUT_BODY 71 +#define MSG_ABOUT_BODY "\n\33cThis program is free software; you can\n"\ +" redistribute it and/or modify it under the \n"\ +"terms of the GNU General Public License as\n"\ +"published by the Free Software Foundation;\n"\ +"either version 2 of the License, or at\n"\ +"your option) any later version.\n\n"\ +"This program is distributed in the hope\n"\ +"that it will be useful,but WITHOUT ANY\n"\ +"WARRANTY; without even the implied\n"\ +" warranty of MERCHANTABILITY or FITNESS FOR \n"\ +"A PARTICULAR PURPOSE. See the GNU General\n"\ +"Public License for more details.\n\n"\ +"You should have received a copy of the GNU\n"\ +"General Public License along with this\n"\ +"program; if not, write to\n\n"\ +"Free Software Foundation, Inc.,\n"\ +"59 Temple Place,\n"\ +"Suite 330,\n"\ +"Boston, MA\n"\ +"02111-1307\n"\ +"USA\n\n"\ +"Or email the original author" + +//#define ID_ 72 +//#define MSG_ + + diff --git a/scalos/Modules/Delete.MUI/Source/config.mk b/scalos/Modules/Delete.MUI/Source/config.mk new file mode 100755 index 000000000..8c038bd0d --- /dev/null +++ b/scalos/Modules/Delete.MUI/Source/config.mk @@ -0,0 +1,59 @@ +# $Date: 2011-07-16 19:39:22 +0200 (Sa, 16. Jul 2011) $ +# $Revision: 787 $ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +SCALOS_LOCALE = $(OBJDIR)/Delete_Locale.h + +CFLAGS += -D SCALOSLOCALE=$(SCALOS_LOCALE) + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +INCLUDES += # + +LFLAGS += # + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +INCLUDES += # + +LFLAGS += # + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +INCLUDES += -DMUI_OBSOLETE + +LFLAGS += -lmui -larossupport -lintuition + +else + +############################################################################### +# AmigaOS + +INCLUDES += # + +LFLAGS += -lauto + +endif +endif +endif diff --git a/scalos/Modules/Delete.MUI/Source/makefile b/scalos/Modules/Delete.MUI/Source/makefile new file mode 100644 index 000000000..f7df029cc --- /dev/null +++ b/scalos/Modules/Delete.MUI/Source/makefile @@ -0,0 +1,109 @@ +# makefile for Scalos Delete.MUI module +# $Date$ +# $Revision$ +# $Id$ + +############################################################# + +CSRCS = Delete.module.c \ + Delete.module_files.c + +############################################################# + +CC = sc +LINK = slink +LIBS = \ + ///SAS-lib/snprintf.lib \ + LIB:sc.lib \ + LIB:debug.lib \ + LIB:amiga.lib + +# Optimizer Flags +# Ignore Note 306: local function inlined: "InsertMH" +# Ignore Note 308: inline function does not use formal parameter ... +OPT_FLG = OPTIMIZE OPTINLOCAL OPTTIME OPTSCHED IGNORE=306 IGNORE=308 IGNORE=304 +COPTS = NOWVRET NOVERSION nostackcheck \ + define SCALOSLOCALE=$(SCALOS_LOCALE) \ + idlen=128 \ + idir=///include +OPTIONS = $(OPT_FLG) DATA=FAR DEBUG=L $(COPTS) def=NDEBUG +DBFLAG = nodebug +CSTARTUP = LIB:c.o +TOPLEVEL = // +CATCOMP = catcomp +FLEXCAT = FlexCat +OBJDIR = .sasobj +SUBDIRMAKE = $(MAKE) -s -C + +SCALOS_LOCALE = $(OBJDIR)/Delete_Locale.h + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +OBJS = $(CSRCS:%.c=$(OBJDIR)/%.o) + +############################################################# + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(OPTIONS) $*.c objectname $@ + +############################################################# + +NAME = .bin_os3/Delete.module +NAMEDBG = $(NAME).debug +CAT_FILE = Scalos/Delete.catalog +DESTCAT = Locale:Catalogs +CATS = deutsch \ + français + +ALLCATS = $(foreach cat,$(CATS),Catalogs/$(cat)/$(CAT_FILE)) +CATCOMPH = $(SCALOS_LOCALE) + +############################################################# + +All: $(NAME) \ + allcatalogs + +############################################################# + +$(NAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LINK) FROM $(CSTARTUP) $(OBJS) TO $@ lib $(LIBS) noicons batch quiet + +$(OBJDIR)/Delete.module.o: Delete.module.c Delete.module.h $(CATCOMPH) + +$(OBJDIR)/Delete.module_files.o: Delete.module_files.c Delete.module.h $(CATCOMPH) + +##################################################################### + +$(CATCOMPH) : Delete.cd + @printf '\033[32mMake CatComp header: \033[31m\033[1m$(CATCOMPH) \033[32mfrom \033[31m$<\033[0m\n' + @$(FLEXCAT) $< $@=$(TOPLEVEL)/CatComp_h.sd + +############################################################# + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(NAME)\033[0m\n' + @copy $(NAME) Scalos:Modules/ + @$(foreach cat,$(CATS),printf "\033[32mInstall catalog: \033[31m\033[1mcatalogs/$(cat)/$(CAT_FILE)\033[0m to \033[31m\033[1m$(DESTCAT)/$(cat)/Scalos\033[0m\n";) + -@$(foreach cat,$(CATS),copy "catalogs/$(cat)/$(CAT_FILE)" "$(DESTCAT)/$(cat)/Scalos" clone;) + +############################################################# + +# make all Scalos .catalogs +allcatalogs: + -@$(foreach cat,$(CATS),$(SUBDIRMAKE) Catalogs/$(cat)/Scalos;) + +############################################################# + +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + -@delete $(NAME) $(OBJS) + -@delete $(OBJS) $(NAME) $(NAMEDBG) $(CATCOMPH) $(ALLCATS) + @printf '\033[0m' + +############################################################# + diff --git a/scalos/Modules/Delete.MUI/Source/makefile-new b/scalos/Modules/Delete.MUI/Source/makefile-new new file mode 100755 index 000000000..bbece5af4 --- /dev/null +++ b/scalos/Modules/Delete.MUI/Source/makefile-new @@ -0,0 +1,97 @@ +# $Date: 2011-07-12 02:18:25 +0200 (Di, 12. Jul 2011) $ +# $Revision: 773 $ +############################################################# +TOPLEVEL = $(shell pwd)/../../.. + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + SDPATH=// +else + SDPATH=../../.. +endif + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(OBJDIR)/Delete.module.o \ + $(OBJDIR)/Delete.module_files.o + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Subdirs +# + +SUBDIRS = $(filter-out Catalogs/sample/Scalos, $(wildcard Catalogs/*/Scalos)) + +############################################################################## +# +# Targets +# + +NAME = Delete.module +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) \ + all_subdirs + +############################################################################## + +$(OBJDIR)/%.o: $(TOOLTYPE_DIR)/%.c + $(run-cc) + +$(OBJDIR)/%.o: $(ICONOBJMCC_DIR)/%.c + $(run-cc) + +$(OBJDIR)/Delete.module.o $(OBJDIR)/Delete.module.d \ +$(OBJDIR)/Delete.module_files.o $(OBJDIR)/Delete.module_files.d : $(OBJDIR)/Delete_Locale.h + +$(OBJDIR)/Delete_Locale.h : Delete.cd + @$(ECHO) "FlexCat $@" + $(FLEXCAT) $< $@=$(SDPATH)/CatComp_h.sd + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + @$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) +ifneq ($(MACHINE), ppc-amigaos) + -@chmod u+x $@ +endif + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) Scalos:modules/ clone + +install: install_subdirs + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* \ + $(OBJDIR)/Delete_Locale.h + +clean: clean_subdirs + +############################################################################## + diff --git a/scalos/Modules/Delete.MUI/config.mk b/scalos/Modules/Delete.MUI/config.mk new file mode 100755 index 000000000..6624ed324 --- /dev/null +++ b/scalos/Modules/Delete.MUI/config.mk @@ -0,0 +1,43 @@ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += # + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += # + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +LFLAGS += # + + +else +############################################################################### +# AmigaOS + +LFLAGS += # + +endif +endif +endif diff --git a/scalos/Modules/Delete.MUI/makefile b/scalos/Modules/Delete.MUI/makefile new file mode 100644 index 000000000..856435f56 --- /dev/null +++ b/scalos/Modules/Delete.MUI/makefile @@ -0,0 +1,33 @@ +# makefile for Scalos delete.MUI module +# $Date$ + +############################################################# + +SUBDIRS = Source \ + +############################################################# + +.PHONY: All install clean + +############################################################# + +All: + @for name in $(SUBDIRS) ; do \ + $(MAKE) -s --directory=$$name; \ + done + +############################################################# + +install: + @for name in $(SUBDIRS) ; do \ + $(MAKE) -s install --directory=$$name; \ + done + +############################################################# + +clean: + @for name in $(SUBDIRS) ; do \ + $(MAKE) -s clean --directory=$$name; \ + done + +############################################################# diff --git a/scalos/Modules/Delete.MUI/makefile-new b/scalos/Modules/Delete.MUI/makefile-new new file mode 100755 index 000000000..f8c66c175 --- /dev/null +++ b/scalos/Modules/Delete.MUI/makefile-new @@ -0,0 +1,23 @@ +# $Date: 2009-02-17 21:22:13 +0100 (Di, 17. Feb 2009) $ +# $Revision: 5 $ +############################################################# +TOPLEVEL = $(shell pwd)/../.. + +include config.mk + +############################################################################## +# +# Project subdirectories +# + +SUBDIRS = Source \ + +############################################################################## + +.PHONY: all install clean + +all: all_subdirs + +clean: clean_subdirs + +install: install_subdirs diff --git a/scalos/Modules/Empty_Trashcan.Gadtools/Empty_Trashcan.c b/scalos/Modules/Empty_Trashcan.Gadtools/Empty_Trashcan.c new file mode 100755 index 000000000..abf465409 --- /dev/null +++ b/scalos/Modules/Empty_Trashcan.Gadtools/Empty_Trashcan.c @@ -0,0 +1,1153 @@ +// Empty_Trashcan.c +// $Date$ +// $Revision$ + + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "debug.h" + +//------------------------------------- +// Readsupport +struct DirList +{ + struct MinList list; + BPTR lock; + ULONG read; +}; + +struct DirNode +{ + struct MinNode node; + STRPTR name; + struct DirList list; + struct DirList *parentList; + ULONG icon; + ULONG prot; +}; + +struct FileNode +{ + struct MinNode node; + STRPTR name; + ULONG nameLen; + ULONG icon; +}; + +//------------------------------------- + +const STRPTR VerString = "$VER: Empty_Trashcan.module 40.1 "__AMIGADATE__ " " COMPILER_STRING; + +#define ECTR_TYPE_WARNING 0 + +IMPORT struct Library *GadToolsBase; +IMPORT struct Library *SysBase; +IMPORT struct Library *UtilityBase; + +struct Library *IconBase; + +struct Catalog *Cat; + +struct Screen *scr; +struct DrawInfo *drinfo; +APTR visualinfo; +ULONG offx,offy,fonty,sizeheight; +ULONG wndwidth,wndheight,drawerwidth; + +struct Window *wnd; +struct Gadget *glist; + +BOOL glistAttached; +BOOL sizeVerify; +BOOL fromWB; + +const STATIC STRPTR engLocText[] = +{ + "Warning! You cannot get back what you delete!\nOK to empty the trashcan?", + "_OK", + "_Cancel", + "Empty Trashcan", + "Delete|Abort", + "Emptying Trashcan...", + "Path", + "_Abort", + "Building Filelist...", + "Not Enough Memory", + "Error", + "couldn't be deleted", + "Skip it|Abort", + "is protected against deletion.\n\nDelete anywhy?", + "Delete|Skip it", + "Delete|DeleteAllProtect|Skip" +}; + +UWORD abort_key; + +STRPTR locText[16]; + +STATIC BOOL CreateGadgets(void); + +//---------------------------------------------------------------------------- + +extern struct WBStartup *_WBenchMsg; + +//------------------------------------- +// Requester Support + +#ifdef __SASC + +STATIC VOID SR_LenFunc(VOID) +{ + __emit(0x5293); // ADDQ.L #1,(A3) +} + +//STATIC VOID SR_CopyFunc(VOID) +//{ +// __emit(0x16c0); // MOVE.B D0,(A3)+ +//} + +STATIC VOID SR_CopyFuncNoUnderscore(VOID) +{ + __emit(0xb03c); __emit(0x005f); // CMP.B #'_',D0 + __emit(0x6702); // BEQ.B .end(RTS) + __emit(0x16c0); // MOVE.B D0,(A3)+ +} + +STATIC VOID SR_Dummy(VOID) +{ +} + +#else + +VOID SR_LenFunc(VOID); +VOID SR_CopyFunc(VOID); +VOID SR_CopyFuncNoUnderscore(VOID); +VOID SR_Dummy(VOID); + +#endif + +//------------------------------------- +LONG SimpleRequestArgs( struct Window *wnd, struct EasyStruct *easy, ULONG *idcmp, STRPTR reqType, STRPTR fallBackType, APTR argList ) +{ + STRPTR gadgetText = (STRPTR)easy->es_GadgetFormat; + STRPTR newGadgetText; + ULONG len; + APTR nd; + + if( !gadgetText ) + { + DisplayBeep(NULL); + return 0; + } + + // Skip the text format + if( easy->es_TextFormat ) + nd = RawDoFmt(easy->es_TextFormat,argList,(void(*)())SR_Dummy,NULL); + else + nd = argList; + + // Calculate the length of the formatted GadgetText + len = 0; + RawDoFmt(easy->es_GadgetFormat,nd,(void(*)())SR_LenFunc,&len); + + newGadgetText = (STRPTR) calloc(len+2, 1); + if( !newGadgetText ) + return EasyRequestArgs(wnd,easy,idcmp,argList); + else + { + LONG val; + struct EasyStruct es; + + // Format the gadgettext without underscores + RawDoFmt(easy->es_GadgetFormat,nd,(void(*)())SR_CopyFuncNoUnderscore,newGadgetText); + + es.es_StructSize = sizeof(struct EasyStruct); + es.es_Flags = easy->es_Flags; + es.es_Title = easy->es_Title; + es.es_TextFormat = easy->es_TextFormat; + es.es_GadgetFormat = newGadgetText; + + val = EasyRequestArgs(wnd,&es,idcmp,argList); + free( newGadgetText ); + return val; + } +} + +//------------------------------------- +LONG SimpleRequest( struct Window *wnd, struct EasyStruct *easy, ULONG *idcmp, STRPTR reqType, STRPTR fallBackType, APTR args,... ) +{ + return SimpleRequestArgs( wnd, easy, idcmp, reqType, fallBackType, &args ); +} +//------------------------------------- + +STATIC STRPTR NameOfLock( BPTR lock ) +{ + STRPTR n; + BOOL again; + ULONG bufSize = 127; + if( !lock ) + return NULL; + + do + { + again = FALSE; + if((n = malloc(bufSize))) + { + if( NameFromLock( lock, n, bufSize-1 ) == DOSFALSE ) + { + if( IoErr() == ERROR_LINE_TOO_LONG ) + { + bufSize += 127; + again = TRUE; + } + free(n); + n = NULL; + } + } + } while(again); + + return n; +} +//------------------------------------- +STATIC STRPTR BuildIconName( const STRPTR name ) +{ + ULONG namelen=strlen(name); + STRPTR infoname = malloc(namelen+8); + if(infoname) + { + strcpy(infoname,name); + strcat(infoname,".info"); + } + return infoname; +} +//------------------------------------- +STATIC ULONG FindUnderscoredToLower(STRPTR text) +{ + ULONG c; + while(( c = *text++)) + { + if( c == '_' ) + return ToLower(*text); + } + return 0; +} +//------------------------------------- + +ULONG deleteAllProt; + +//------------------------------------- +STATIC VOID InitStrings(void) +{ + ULONG i; + + if( LocaleBase ) + { + for(i=0; i<16; i++) + { + locText[i] = GetCatalogStr( Cat, i, engLocText[i]); + } + } + else + { + for(i=0; i<16; i++) + { + locText[i] = engLocText[i]; + } + } + + abort_key = FindUnderscoredToLower(locText[7]); +} +//------------------------------------- + +STATIC ULONG PrintError( const ULONG ioerr, const STRPTR name, const STRPTR button ) +{ + struct EasyStruct easy; + char buffer[80]; + + easy.es_StructSize = sizeof(struct EasyStruct); + easy.es_Flags = 0; + easy.es_Title = "Scalos"; + easy.es_TextFormat = "%s %s\n%s"; + easy.es_GadgetFormat = "%s"; + + Fault( ioerr, NULL, buffer,80); + + return (ULONG)SimpleRequest( NULL, &easy, NULL, ECTR_TYPE_WARNING, NULL, name, locText[11], buffer,button); +} +//------------------------------------- +STATIC BOOL IsDeletable( const STRPTR name, ULONG prot) +{ + if(( prot & FIBF_DELETE )) + { + BOOL del=deleteAllProt; + if( !deleteAllProt) + { + struct EasyStruct easy; + easy.es_StructSize = sizeof(struct EasyStruct); + easy.es_Flags = 0; + easy.es_Title = "Scalos"; + easy.es_TextFormat = "%s\n%s"; + easy.es_GadgetFormat = "%s"; + + switch( SimpleRequest( NULL, &easy, NULL, ECTR_TYPE_WARNING, NULL, name, locText[13], locText[15])) + { + case 0: + break; + + case 1: + del=TRUE; + break; + + case 2: + del=deleteAllProt=TRUE; + break; + } + } + return del; + } + return TRUE; +} + +//------------------------------------- +STATIC ULONG Unprotect( const STRPTR name, const ULONG icon, ULONG prot) +{ + if(( prot & FIBF_DELETE )) + { + BOOL ok; + if(SetProtection(name,NULL) != DOSFALSE ) + ok=TRUE; + else + { + LONG ioerr = IoErr(); + if( ioerr == ERROR_OBJECT_NOT_FOUND ) + ok = TRUE; + else + { +// ok = FALSE; + return PrintError(ioerr,name, locText[12]); + } + } + + if(ok && icon ) + { + if( icon ) + { + STRPTR infoname = BuildIconName(name); + if(infoname) + { + if(SetProtection(infoname,NULL)== DOSFALSE ) + { + LONG ioerr = IoErr(); + if( ioerr == ERROR_OBJECT_NOT_FOUND ) + /* ok = TRUE */; + else + return PrintError(ioerr,name, locText[12]); + } + + free(infoname); + } + } + } + } + return 2; +} +//------------------------------------- +STATIC BOOL DeleteIcon(const STRPTR name, const ULONG update ) +{ + if(update) + return DeleteDiskObject(name); + else + { + STRPTR iname = BuildIconName(name); + if(iname) + { + if(DeleteFile(iname)==DOSFALSE) + return FALSE; + else return TRUE; + + free(iname); + } + } +} +//------------------------------------- +STATIC BOOL DeleteTheFile( const STRPTR name, const ULONG icon, const ULONG update ) +{ + BOOL goon = TRUE; + struct TextExtent te; + ULONG len = strlen(name); + ULONG nc; + LONG ioerr; + BOOL onlyicon = FALSE; + + struct IntuiMessage *imsg; + + Move(wnd->RPort,offx+2,offy+drinfo->dri_Font->tf_Baseline+2+fonty+1); + nc = TextFit(wnd->RPort,(const STRPTR)name+len,len,&te,NULL,-1,wndwidth-2*offx-4,fonty); + Text(wnd->RPort,(const STRPTR)name+len-nc,nc); + + if( te.te_Width < drawerwidth ) + { + EraseRect(wnd->RPort,wnd->RPort->cp_x,offy+3+fonty,offx+2+drawerwidth,offy+2+2*fonty); + } + + if(wnd) + { + while((imsg = (struct IntuiMessage*)GT_GetIMsg(wnd->UserPort))) + { + ULONG cl = imsg->Class; + + if( cl == IDCMP_SIZEVERIFY ) + { + if(glistAttached) + RemoveGList( wnd, glist, -1 ); + glistAttached = FALSE; + GT_ReplyIMsg(imsg); + continue; + } + + GT_ReplyIMsg(imsg); + + switch(cl) + { + case IDCMP_GADGETUP: + case IDCMP_CLOSEWINDOW: + return FALSE; + break; + + case IDCMP_NEWSIZE: + if( !sizeVerify && glistAttached) + { + if( wndwidth == wnd->Width || wndheight != wnd->Height ) + break; + } + if(glistAttached) + RemoveGList( wnd, glist, -1 ); + + if( wnd->Width < wndwidth ) + RefreshWindowFrame(wnd); + + wndwidth = wnd->Width; + wndheight = wnd->Height; + EraseRect( wnd->RPort, wnd->BorderLeft, wnd->BorderTop+fonty+3, + wnd->Width-wnd->BorderRight-1, wnd->Height-wnd->BorderBottom-1 ); + if(CreateGadgets()) + { + AddGList( wnd, glist, -1,-1, NULL ); + RefreshGList( glist, wnd, NULL, -1 ); + glistAttached = TRUE; + SetFont(wnd->RPort,drinfo->dri_Font); + } + break; + } + } + } + + drawerwidth = te.te_Width; + + if(DeleteFile(name)==DOSFALSE) + { + ioerr = IoErr(); + if( ioerr == ERROR_OBJECT_NOT_FOUND) + { + if(!DeleteIcon(name,update)) + { + ioerr=IoErr(); + if(ioerr==ERROR_OBJECT_NOT_FOUND) + ioerr=0; + } + else + ioerr=0; + onlyicon=TRUE; + } + else + { + if( ioerr == ERROR_OBJECT_IN_USE ) + { + if(DeleteFile(name)==DOSFALSE) + ioerr = IoErr(); + else + ioerr = 0; + } + } + } + else + ioerr=0; + + if( ioerr ) + { + switch( ioerr) + { + case ERROR_DELETE_PROTECTED: + { + BOOL del=deleteAllProt; + if( !deleteAllProt) + { + struct EasyStruct easy; + + easy.es_StructSize = sizeof(struct EasyStruct); + easy.es_Flags = 0; + easy.es_Title = "Scalos"; + easy.es_TextFormat = "%s\n%s"; + easy.es_GadgetFormat = "%s"; + + switch( SimpleRequest( NULL, &easy, NULL, ECTR_TYPE_WARNING, NULL, name, locText[13], locText[15])) + { + case 0: + del=FALSE; + break; + + case 1: + del=TRUE; + break; + + case 2: + del=deleteAllProt=TRUE; + break; + } + + } + if(del) + { + BOOL ok = onlyicon; + if( !ok ) + if(SetProtection(name,NULL) != DOSFALSE ) + ok=TRUE; + + if(ok)//nlyicon || SetProtection(name,NULL) != DOSFALSE ) + { + BOOL error; + + if( icon || onlyicon ) + { + ULONG namelen=strlen(name); + STRPTR infoname = malloc(namelen+8); + error = TRUE; + if(infoname) + { + strcpy(infoname,name); + strcpy(infoname+namelen,".info"); + + if(SetProtection(infoname,NULL) != DOSFALSE ) + error = FALSE; + + free(infoname); + } + else + SetIoErr(ERROR_NO_FREE_STORE); + } + else + error=FALSE; + + if( !error ) + { + if( onlyicon ) + { + if(DeleteIcon(name,update)) + return TRUE; + } + else + { + if(DeleteFile(name) != DOSFALSE ) + { + if(icon) + { + if(DeleteIcon(name,update)) + return TRUE; + } + else + return TRUE; + } + } + } + } + ioerr = IoErr(); + } + else + break; + } + + default: + return (BOOL)PrintError(ioerr,name, locText[12]); + break; + } + } + else + { + if( icon ) + { + DeleteIcon(name,update); + } + } + + return goon; +} +//------------------------------------- +STATIC BOOL ReadInDir( struct DirList *list, APTR dirPool ) +{ + BOOL retval = TRUE; + STRPTR lockName; + + if( !list->lock ) + { +// Printf("No Lock!\n"); + return FALSE; + } + + if( list->read ) + { +// PutStr("Already read!\n"); + return TRUE; + } + + lockName = NameOfLock(list->lock); + if( lockName ) + { + ULONG lockSize = strlen(lockName); + APTR filePool = CreatePool( 0,4096,4096); + if( filePool ) + { + struct ExAllControl *eac; + eac = (struct ExAllControl*)AllocDosObject(DOS_EXALLCONTROL,NULL); + if( eac ) + { + struct ExAllData *ead; + ead = (struct ExAllData*) malloc(1032); + if(ead) + { + LONG more; + struct MinList fileList; + NewList((struct List*)&fileList); + + eac->eac_LastKey = 0; + eac->eac_MatchString = NULL; + + list->read = TRUE; + + do + { + struct ExAllData *ed = ead; + more = ExAll( list->lock, ed, 1024, ED_PROTECTION, eac ); + if((!more) && (IoErr() != ERROR_NO_MORE_ENTRIES )) + { + retval = FALSE; + break; + } + + if( eac->eac_Entries ) + { + do + { + ULONG nlen = strlen(ed->ed_Name); + ULONG len = nlen+8+lockSize; + if( ed->ed_Type > 0 ) + { + STRPTR name = (STRPTR)AllocPooled(dirPool,len); + if(name) + { + struct DirNode *dir = (struct DirNode*)AllocPooled(dirPool,sizeof(struct DirNode)); + if( dir ) + { + strcpy(name,lockName); + AddPart(name,ed->ed_Name,len); + + dir->name = name; + dir->list.lock = Lock( name, ACCESS_READ); + dir->list.read = FALSE; + dir->parentList = list; + dir->icon = FALSE; + dir->prot = ed->ed_Prot; + NewList((struct List*)&dir->list); + + AddTail((struct List*)list, (struct Node*)dir); + } + } + } + else + { + struct FileNode *file = (struct FileNode*)AllocPooled(filePool,sizeof(struct FileNode)); + if( file ) + { + STRPTR name = (STRPTR)AllocPooled(filePool,len); + if( name ) + { + strcpy(name,lockName); + AddPart(name,ed->ed_Name,len); + + file->name = name; + file->nameLen = strlen(name); + file->icon = FALSE; + AddTail((struct List*)&fileList, (struct Node*)file); + } + } + } + ed = ed->ed_Next; + } while(ed); + } + } while(more); + + ExAllEnd( list->lock, ead, 1024, ED_PROTECTION, eac ); + free(ead); + + if( !IsListEmpty((struct List*)&fileList)) + { + struct FileNode *node; + struct DirNode *dnode; + + node = (struct FileNode*)fileList.mlh_Head; + while(node->node.mln_Succ && retval) + { + // Icons aussortieren + if( node->nameLen > 4 ) + { + if( !Stricmp(".info",node->name+node->nameLen-5)) + { + struct FileNode *fnode = (struct FileNode*)fileList.mlh_Head; + BOOL iconfound=FALSE; + node->name[node->nameLen-5]=0; + while(fnode->node.mln_Succ) + { + if( fnode != node ) + { + if( !Stricmp(node->name,fnode->name)) + { + fnode->icon = iconfound = TRUE; + break; + } + } + fnode = (struct FileNode*)fnode->node.mln_Succ; + } + + if( !iconfound ) + { + dnode = (struct DirNode*)list->list.mlh_Head; + while(dnode->node.mln_Succ) + { + if( !Stricmp(node->name,dnode->name)) + { + dnode->icon = iconfound = TRUE; + break; + } + + dnode = (struct DirNode*)dnode->node.mln_Succ; + } + } + + if( iconfound ) + { + struct FileNode *tfn = node; + node = (struct FileNode*)node->node.mln_Succ; + Remove((struct Node*)tfn); + continue; + } + } + } + node = (struct FileNode*)node->node.mln_Succ; + } + + node = (struct FileNode*)fileList.mlh_Head; + while(node->node.mln_Succ && retval) + { + retval = DeleteTheFile(node->name,node->icon,FALSE); + node = (struct FileNode*)node->node.mln_Succ; + } + + dnode = (struct DirNode*)list->list.mlh_Head; + while(dnode->node.mln_Succ) + { + struct DirNode *help = dnode; + dnode = (struct DirNode*)dnode->node.mln_Succ; + if( !IsDeletable(help->name,help->prot)) + { + UnLock(help->list.lock); + Remove((struct Node*)help); + } + } + } + } + + FreeDosObject(DOS_EXALLCONTROL,eac); + } + DeletePool(filePool); + } + free(lockName); + } + return retval; +} +//------------------------------------- +STATIC BOOL DeleteDir( struct DirList *root, APTR dirPool ) +{ + struct DirList *cl = root; + BOOL goon = TRUE; + + d1(kprintf(__FUNC__ "/%ld: root=%08lx dirPool=%08lx\n", __LINE__, root, dirPool)); + + while(cl) + { + if(goon) + { + if(!ReadInDir(cl,dirPool)) + goon=FALSE; + } + + if( !IsListEmpty((struct List*)cl)) + { + struct DirNode *cn = (struct DirNode*)cl->list.mlh_Head; + cl = (struct DirList*)&cn->list; + } + else + { + if(cl != root ) + { + struct DirNode *cn = (struct DirNode*)(((ULONG*)cl)-3); + struct DirNode *ncn = (struct DirNode*)cn->node.mln_Succ; + + if( !ncn->node.mln_Succ ) + { + do + { + if( cl == root ) + return TRUE; + + cl = cn->parentList; + if( !cl ) + { +// PutStr("Ready...\n"); + return TRUE; + } + + if( IsListEmpty((struct List*)cl)) + { + return FALSE; + } + + ncn = (struct DirNode*)RemHead((struct List*)cl); + cn = (struct DirNode*)(((ULONG*)cl)-3); + + if(ncn->list.lock) + { + UnLock(ncn->list.lock); + ncn->list.lock = NULL; + } + + if( goon ) + { + Unprotect(ncn->name,ncn->icon,ncn->prot); + goon = DeleteTheFile(ncn->name,ncn->icon,FALSE); + } + } while( IsListEmpty((struct List*)cl)); + if( !cl ) + break; + + ncn = (struct DirNode*)cl->list.mlh_Head; + } + else + { + Remove((struct Node*)cn); + + if(cn->list.lock) + { + UnLock(cn->list.lock); + cn->list.lock = NULL; + } + + if( goon ) + { + Unprotect(cn->name,cn->icon,cn->prot); + goon=DeleteTheFile(cn->name,cn->icon,FALSE); + } + } + + cl = (struct DirList*)&ncn->list; + } + else + return FALSE; + } + } + + return FALSE; +} + +//------------------------------------- +STATIC BOOL SetupScreen(void) +{ + if((scr = LockPubScreen(NULL))) + { + if((drinfo = GetScreenDrawInfo(scr))) + { + if((visualinfo = GetVisualInfoA(scr,NULL))) + { + Object *o = (Object*)NewObject( NULL, SYSICLASS, + SYSIA_DrawInfo,drinfo, + SYSIA_Which, SIZEIMAGE, + TAG_DONE); + if(o) + { + if(!GetAttr( IA_Height,o,&sizeheight)) + sizeheight = 11; + DisposeObject(o); + } + else + sizeheight = 11; + return TRUE; + } + } + } + return FALSE; +} +//------------------------------------- +STATIC VOID FreeScreen(void) +{ + if( visualinfo ) + FreeVisualInfo(visualinfo); + if( drinfo ) + FreeScreenDrawInfo(scr,drinfo); + if( scr ) + UnlockPubScreen(NULL,scr); +} +//------------------------------------- +STATIC VOID Render(void) +{ + Move(wnd->RPort,offx+2,offy+drinfo->dri_Font->tf_Baseline+2); + SetABPenDrMd(wnd->RPort,drinfo->dri_Pens[TEXTPEN],drinfo->dri_Pens[BACKGROUNDPEN],JAM2); + Text(wnd->RPort,locText[5],strlen(locText[5])); +} +//------------------------------------- +STATIC BOOL CreateGadgets(void) +{ + struct Gadget *g; + + if(glist) + { + FreeGadgets(glist); + glist = NULL; + } + + g = CreateContext( &glist ); + if( g ) + { + struct NewGadget ng; + + ng.ng_VisualInfo = visualinfo; + ng.ng_TextAttr = NULL; + ng.ng_GadgetText = locText[7]; + ng.ng_GadgetID = 1; + ng.ng_Flags = PLACETEXT_IN; + ng.ng_UserData = NULL; + ng.ng_LeftEdge = offx+2; + ng.ng_TopEdge = offy+2*fonty+4; + ng.ng_Width = wndwidth-2*ng.ng_LeftEdge; + ng.ng_Height = fonty+6; + + g = CreateGadget( BUTTON_KIND, g, &ng, + GT_Underscore,'_', + TAG_DONE); + if(g) + return TRUE; + + FreeGadgets(glist); + glist=NULL; + } + return FALSE; +} +//------------------------------------- +STATIC VOID FreeGUI(void) +{ + if(wnd) + CloseWindow(wnd); + if(glist) + FreeGadgets(glist); +} +//------------------------------------- +STATIC BOOL SetupGUI(void) +{ + fonty = drinfo->dri_Font->tf_YSize; + offx = scr->WBorLeft; + offy = scr->WBorTop + fonty + 1; + + wndwidth = 300; + wndheight = offy + 3*fonty + sizeheight + 12; + + if( CreateGadgets()) + { + ULONG idcmp = IDCMP_CLOSEWINDOW|IDCMP_NEWSIZE|BUTTONIDCMP|IDCMP_VANILLAKEY; + if( sizeVerify ) + idcmp |= IDCMP_SIZEVERIFY; + + wnd = OpenWindowTags( NULL, + WA_Left,(scr->Width-wndwidth)/2, + WA_Top,(scr->Height-wndheight)/2, + WA_Width, wndwidth, + WA_Height, wndheight, + WA_IDCMP, idcmp, + WA_DragBar,TRUE, + WA_SizeGadget, TRUE, + WA_DepthGadget,TRUE, + WA_CloseGadget, TRUE, + WA_Title,locText[3], + WA_RMBTrap, TRUE, + WA_Gadgets, glist, + WA_SizeBBottom,TRUE, + WA_MaxWidth,-1, + WA_Activate, TRUE, + WA_PubScreen,scr, + WA_NoCareRefresh,TRUE, + TAG_DONE ); + if( wnd ) + { + glistAttached = TRUE; + SetFont(wnd->RPort,drinfo->dri_Font); + Render(); + return TRUE; + } + glistAttached = FALSE; + } + FreeGUI(); + return FALSE; +} +//------------------------------------- + +int main(int argc, char *argv[]) +{ + BPTR OldDir = NULL; + BPTR fLock = NULL; + struct FileInfoBlock *fib = NULL; + APTR dirPool = NULL; + STRPTR name = NULL; + + do { + struct EasyStruct easy; + struct WBArg *wbarg; + struct DirList list; + + if(NULL == _WBenchMsg) + break; + + if (_WBenchMsg->sm_NumArgs <= 1 ) + break; + + IconBase = OpenLibrary("icon.library",37); + if (NULL == IconBase) + break; + + wbarg = _WBenchMsg->sm_ArgList+1; + + fLock = Lock("ENV:Scalos/NoSizeVerify",ACCESS_READ); + if(fLock) + { + sizeVerify = FALSE; + UnLock(fLock); + } + else + sizeVerify = TRUE; + + + if(LocaleBase) + Cat = OpenCatalogA( NULL, "Scalos/Scalos_ETrashcan.catalog",NULL); + InitStrings(); + + if( !SetupScreen()) + break; + + easy.es_StructSize = sizeof(struct EasyStruct); + easy.es_Flags = 0; + easy.es_Title = "Scalos"; + easy.es_TextFormat = "%s"; + easy.es_GadgetFormat = "%s|%s"; + + if( !SimpleRequest( NULL, &easy, NULL, ECTR_TYPE_WARNING, NULL, locText[0], locText[1], locText[2])) + break; + + d1(kprintf(__FUNC__ "/%ld: \n", __LINE__)); + + if(!SetupGUI()) + break; + + d1(kprintf(__FUNC__ "/%ld: \n", __LINE__)); + + OldDir = CurrentDir(wbarg->wa_Lock); + + if(wbarg->wa_Name) + { + d1(kprintf(__FUNC__ "/%ld: wa_Name=<%s>\n", __LINE__, wbarg->wa_Name)); + fLock = Lock(wbarg->wa_Name, ACCESS_READ); + } + else + { + fLock = Lock("", ACCESS_READ); + } + + if (NULL == fLock) + break; + + fib = AllocDosObject(DOS_FIB, NULL); + if (NULL == fib) + break; + + if (!Examine(fLock, fib)) + break; + + if (fib->fib_DirEntryType < 0) + break; + + dirPool = CreatePool(NULL,4096,4096); + if (NULL == dirPool) + break; + + d1(kprintf(__FUNC__ "/%ld: dirPool=%08lx\n", __LINE__, dirPool)); + + name = NameOfLock(wbarg->wa_Lock); + d1(kprintf(__FUNC__ "/%ld: name=%08lx\n", __LINE__, name)); + if (NULL == name) + break; + + NewList((struct List*)&list); + + list.lock = fLock; + list.read = FALSE; + + DeleteDir(&list, dirPool); + } while (0); + + if (name) + free(name); + if (dirPool) + DeletePool(dirPool); + if (fib) + FreeDosObject(DOS_FIB, fib); + if (fLock) + UnLock(fLock); + if (OldDir) + CurrentDir(OldDir); + + FreeGUI(); + FreeScreen(); + if( Cat ) + CloseCatalog( Cat ); + if (IconBase) + CloseLibrary(IconBase); +} +//------------------------------------- diff --git a/scalos/Modules/Empty_Trashcan.Gadtools/debug.h b/scalos/Modules/Empty_Trashcan.Gadtools/debug.h new file mode 100644 index 000000000..aea559dac --- /dev/null +++ b/scalos/Modules/Empty_Trashcan.Gadtools/debug.h @@ -0,0 +1,19 @@ +// debug.h +// $Date$ +// $Revision$ + +#ifndef DEBUG_H +#define DEBUG_H + +//---------------------------------------------------------------------------- + +#define d1(x) ; +#define d2(x) x; + +// from debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +//---------------------------------------------------------------------------- + +#endif /* DEBUG_H */ diff --git a/scalos/Modules/Empty_Trashcan.Gadtools/makefile b/scalos/Modules/Empty_Trashcan.Gadtools/makefile new file mode 100755 index 000000000..15a59b59a --- /dev/null +++ b/scalos/Modules/Empty_Trashcan.Gadtools/makefile @@ -0,0 +1,82 @@ +# Makefile for Empty_Trashcan.module (MUI) +# using GNU make and SAS/C +# $Date$ + +##################################################################### + +CHEADERS = +CC = sc +CFLAGS = optimize nostackcheck nochkabort debug=s \ + idlen=128 strmer nover streq idir=sc:include/ idir=include: idir=//include +AS = phxass +AFLAGS = QUIET m=68020 linedebug opt=NRQB i=include: +LD = slink +LNFLAGS = quiet batch noicons stripdebug +LNDBFLAGS = quiet batch noicons addsym +LIBS = LIB:sc.lib LIB:debug.lib LIB:amiga.lib +CSTARTUP = LIB:c.o +OBJDIR = .sasobj + +.SUFFIXES: .asm + +##################################################################### + +NAME = Empty_Trashcan.module +DBGNAME = $(NAME).debug + +##################################################################### + +all: $(NAME) $(DBGNAME) +# install +# clean + +##################################################################### + +CSRCS = Empty_Trashcan.c + + +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(CSRCS:%.c=$(OBJDIR)/%.o) + +##################################################################### + +$(NAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNFLAGS) + +$(DBGNAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNDBFLAGS) + +##################################################################### + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +##################################################################### + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $< objectname $@ + +##################################################################### + +Empty_Trashcan.o : Empty_Trashcan.c debug.h + +$(NAME) $(DBGNAME) : $(OBJS) + +##################################################################### + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(NAME) \033[0mto \033[31m\033[1mScalos:modules/ \033[0m\n' + copy $(NAME) Scalos:modules/ + +##################################################################### + +# A little something to clean it all up +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + -@delete $(OBJS) $(NAME) $(DBGNAME) + @printf '\033[0m' + +##################################################################### + diff --git a/scalos/Modules/Empty_Trashcan.MUI/Catalogs/deutsch/Scalos/Empty_Trashcan.ct b/scalos/Modules/Empty_Trashcan.MUI/Catalogs/deutsch/Scalos/Empty_Trashcan.ct new file mode 100644 index 000000000..3fcad8d66 --- /dev/null +++ b/scalos/Modules/Empty_Trashcan.MUI/Catalogs/deutsch/Scalos/Empty_Trashcan.ct @@ -0,0 +1,234 @@ +; Empty_Trashcan.ct +## version $VER: Empty_Trashcan.catalog 40.1 (04 Dec 2005 23:01:34) +## codeset 0 +## language deutsch +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Papierkorb leeren +;Scalos Empty_Trashcan +; +; +MSGID_OKBUTTON +Start +;Ok +; +; +MSGID_OKBUTTON_SHORT +S +;O +; +; +MSGID_SHORTHELP_OKBUTTON +Beginnt die Leerung des Papierkorbs.\n\ +Der gesamte Inhalt wird unwiederruflich gelöscht! +;Start emptying trashcan.\n\ +;All contents is deleted irrevocably! +; +; +MSGID_CANCELBUTTON +Abbruch +;Cancel +; +; +MSGID_CANCELBUTTON_SHORT +a +;c +; +; +MSGID_SHORTHELP_CANCELBUTTON +Papierkorb unberührt lassen und Programm beenden. +;Leave trashcan untouched and quit +; +; +MSGID_ABORTBUTTON +Abbruch +;Abort +; +; +MSGID_ABORTBUTTON_SHORT +a +;a +; +; +MSGID_SHORTHELP_ABORTBUTTON +Leere des Papierkorbs abbrechen\n\ +und Programm beenden. +;Immediately abort emptying\n\ +;of trashcan and quit. +; +; +MSGID_CREATE_APPLICATION_FAILED +Fehler beim Erzeugen der Anwendung.\n +;Failed to create Application.\n +; +; +MSGID_CREATE_MAINWINDOW_FAILED +Fehler beim Öffnen des Hauptfensters !\n +;Failed to open main window !\n +; +; +MSGID_OPEN_LIBRARY_FAILED +Fehler beiom Öffnen von \"%s\" !\n +;Failed to open \"%s\" !\n +; +;;----------------------------------------------------------- +; +; +MSGID_MENU_PROJECT +Projekt +;Project +; +; +MSGID_MENU_PROJECT_ABOUT +Über... +;About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Über MUI... +;About MUI... +; +; +MSGID_MENU_PROJECT_QUIT +Beenden +;Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +;Q +; +;----------------------------------------------------------- +; +; +MSGID_ABOUTREQOK +OK +;OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Empty_Trashcan.module V%ld.%ld\033n\n\ +%s\n\ +© 2005%s Das Scalos-Team +;\33c\033bScalos Empty_Trashcan.module V%ld.%ld\033n\n\ +;%s\n\ +;© 2005%s The Scalos Team +; +;----------------------------------------------------------- +; +; +MSGID_WARNING_EMPTY_TRASHCAN +Vorsicht!\n\ +Gelöschte Inhalte können nicht wiederhergestellt werden!\n\ +Soll der Papierkorb jetzt geleert werden? +;Warning! You cannot get back what you delete!\n\ +;OK to empty the trashcan? +; +; +MSGID_GADGETS_EMPTY_ABORT +Leeren|Abbruch +;Empty|Abort +; +; +MSGID_GADGETTEXT_OK +OK +;OK +; +; +MSGID_GADGETTEXT_CANCEL +Abbruch +;Cancel +; +; +MSGID_EMPTY_TRASHCAN +Papierkorb leeren +;Empty Trashcan +; +; +MSGID_GADGETS_DELETE_ABORT +Löschen|Abbruch +;Delete|Abort +; +; +MSGID_EMPTYING_TRASHCAN +Papierkorb wird geleert... +;Emptying Trashcan... +; +; +MSGID_PATH +Pfad +;Path +; +; +MSGID_GADGET_ABORT +Abbruch +;Abort +; +; +MSGID_BUILD_FILELIST +Dateiliste bilden... +;Building Filelist... +; +; +MSGID_OUT_OF_MEMORY +Nicht genug Speicher +;Not Enough Memory +; +; +MSGID_ERROR +Fehler +;Error +; +; +MSGID_FAILED_TO_DELETE +%s\n\ +konnte nicht gelöscht werden:\n\ +%s +;%s\n\ +;couldn't be deleted:\n\ +;%s +; +; +MSGID_GADGETS_SKIP_ABORT +Überspringen|Abbruch +;Skip it|Abort +; +; +MSGID_DELETE_PROTECTED +%s ist gegen Löschen geschützt.\n\ +Trotzdem löschen? +;%s is protected against deletion.\n\ +;Delete anyway? +; +; +MSGID_GADGETS_DELETE_SKIP +Löschen|Überspringen +;Delete|Skip it +; +; +MSGID_GADGETS_DELETE_DELETEALL_PROTECT_SKIP +Löschen|Alles Löschen|Überspringen +;Delete|DeleteAllProtect|Skip +; +; +MSGID_TEXT_CURRENTITEM +Beim Löschen von: +;Currently removing: +; +; +MSGID_TEXT_CURRENTITEM_SHORTHELP +Dies ist der Name des Elements\n\ +der gerade gelöscht wird. +;This is the name if the item currently\n\ +;being deleted from trashcan. +; +; +MSGID_GLOBAL_TRASHCAN +\nDieser globale Papierkorb wird ebenfalls geleert: +;\nThis global trashcan will be emptied, too: +; +;----------------------------------------------------------- +; diff --git a/scalos/Modules/Empty_Trashcan.MUI/Catalogs/deutsch/Scalos/config.mk b/scalos/Modules/Empty_Trashcan.MUI/Catalogs/deutsch/Scalos/config.mk new file mode 100755 index 000000000..8631b0623 --- /dev/null +++ b/scalos/Modules/Empty_Trashcan.MUI/Catalogs/deutsch/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = deutsch + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = german + +else + +############################################################################### +# AmigaOS and AROS + +LANG = deutsch + +endif +endif diff --git a/scalos/Modules/Empty_Trashcan.MUI/Catalogs/deutsch/Scalos/makefile b/scalos/Modules/Empty_Trashcan.MUI/Catalogs/deutsch/Scalos/makefile new file mode 100644 index 000000000..22f73f4c2 --- /dev/null +++ b/scalos/Modules/Empty_Trashcan.MUI/Catalogs/deutsch/Scalos/makefile @@ -0,0 +1,14 @@ +# makefile for Empty_Trashcan.module (translated Texts : deutsch) +# $Date$ +# $Revision$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mdeutsch\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +Empty_Trashcan.catalog : Empty_Trashcan.ct ../../../Empty_Trashcan.cd + +All: Empty_Trashcan.catalog diff --git a/scalos/Modules/Empty_Trashcan.MUI/Catalogs/deutsch/Scalos/makefile-new b/scalos/Modules/Empty_Trashcan.MUI/Catalogs/deutsch/Scalos/makefile-new new file mode 100644 index 000000000..f710b2760 --- /dev/null +++ b/scalos/Modules/Empty_Trashcan.MUI/Catalogs/deutsch/Scalos/makefile-new @@ -0,0 +1,30 @@ +# makefile for Empty_Trashcan.module (translated Texts : deutsch) +# $Date: 2011-07-24 10:11:00 +0200 (So, 24. Jul 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = Empty_Trashcan + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git "a/scalos/Modules/Empty_Trashcan.MUI/Catalogs/fran\303\247ais/Scalos/Empty_Trashcan.ct" "b/scalos/Modules/Empty_Trashcan.MUI/Catalogs/fran\303\247ais/Scalos/Empty_Trashcan.ct" new file mode 100755 index 000000000..90b78bc62 --- /dev/null +++ "b/scalos/Modules/Empty_Trashcan.MUI/Catalogs/fran\303\247ais/Scalos/Empty_Trashcan.ct" @@ -0,0 +1,196 @@ +; Empty_Trashcan.ct +## version $VER: Empty_Trashcan.catalog 40.1 (04 Dec 2005 23:01:34) +## codeset 0 +## language français +; +;#arrayopts static __far +; +MSGID_TITLENAME +Scalos Empty_Trashcan +;Scalos Empty_Trashcan +; +MSGID_OKBUTTON +D'accord +;Ok +; +MSGID_OKBUTTON_SHORT +O +;O +; +MSGID_SHORTHELP_OKBUTTON +Vider la corbeille.\n\ +Le contenu est \033birrévocablement éffaçé\033n ! +;Start emptying trashcan.\n\ +;All contents is deleted irrevocably! +; +MSGID_CANCELBUTTON +Annuler +;Cancel +; +MSGID_CANCELBUTTON_SHORT +A +;c +; +MSGID_SHORTHELP_CANCELBUTTON +Ne pas vider la corbeille et quitter. +;Leave trashcan untouched and quit +; +MSGID_ABORTBUTTON +Interrompre +;Abort +; +MSGID_ABORTBUTTON_SHORT +i +;a +; +; +MSGID_SHORTHELP_ABORTBUTTON +Interrompre immèdiatement la\n\ +vidange de la corbeille et quitter. +;Immediately abort emptying\n\ +;of trashcan and quit. +; +; +MSGID_CREATE_APPLICATION_FAILED +La création de l'application a échouée.\n +;Failed to create Application.\n +; +MSGID_CREATE_MAINWINDOW_FAILED +Impoosible d'ouvrir la fenêtre principale !\n +;Failed to open main window !\n +; +MSGID_OPEN_LIBRARY_FAILED +L'ouverture de \"%s\" a échouée !\n +;Failed to open \"%s\" !\n +; +;;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Projet +;Project +; +MSGID_MENU_PROJECT_ABOUT +A propos... +;About... +; +MSGID_MENU_PROJECT_ABOUTMUI +A propos de MUI... +;About MUI... +; +MSGID_MENU_PROJECT_QUIT +Quitter +;Quit +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +;Q +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +_D'accord +;_OK +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Empty_Trashcan.module V\0333%ld\0332.\0333%ld\0332\033n\n\ +%s\n\ +© 2005%s The Scalos Team +;\33c\033bScalos Empty_Trashcan.module V%ld.%ld\033n\n\ +;%s\n\ +;© 2005%s The Scalos Team +; +;----------------------------------------------------------- +; +MSGID_WARNING_EMPTY_TRASHCAN +\033c\033bAttention !\033n\n\ +Vous ne pouvez pas récupèrer ce que vous éffacez !\n\ +OK pour vider la corbeille ? +;Warning! You cannot get back what you delete!\n\ +;OK to empty the trashcan? +; +MSGID_GADGETS_EMPTY_ABORT +Vider|Interrompre +;Empty|Abort +; +MSGID_GADGETTEXT_OK +OK +;OK +; +MSGID_GADGETTEXT_CANCEL +Annuler +;Cancel +; +MSGID_EMPTY_TRASHCAN +Empty Trashcan +;Empty Trashcan +; +MSGID_GADGETS_DELETE_ABORT +Efacer|Interrompre +;Delete|Abort +; +MSGID_EMPTYING_TRASHCAN +Vidange de la corbeille... +;Emptying Trashcan... +; +MSGID_PATH +Chemin +;Path +; +MSGID_GADGET_ABORT +Interrompre +;Abort +; +MSGID_BUILD_FILELIST +Création de la liste des fichiers... +;Building Filelist... +; +MSGID_OUT_OF_MEMORY +Plus assez de mémoire +;Not Enough Memory +; +MSGID_ERROR +Erreur +;Error +; +MSGID_FAILED_TO_DELETE +%s\n\ +n'a put être supprimé :\n\ +%s +;%s\n\ +;couldn't be deleted:\n\ +;%s +; +MSGID_GADGETS_SKIP_ABORT +Le laisser|Interrompre +;Skip it|Abort +; +MSGID_DELETE_PROTECTED +%s est protégé contre l'éffacement.\n\ +L'éffacer quand même ? +;%s is protected against deletion.\n\ +;Delete anyway? +; +MSGID_GADGETS_DELETE_SKIP +Effacer|Le laisser +;Delete|Skip it +; +MSGID_GADGETS_DELETE_DELETEALL_PROTECT_SKIP +Effacer|Effacer toute protection|Laisser +;Delete|DeleteAllProtect|Skip +; +MSGID_TEXT_CURRENTITEM +Effacement de : +;Currently removing: +; +MSGID_TEXT_CURRENTITEM_SHORTHELP +Nom de l'object en train d'être\n\ +supprimer de la corbeille. +;This is the name if the item currently\n\ +;being deleted from trashcan. +; +MSGID_GLOBAL_TRASHCAN +\nCette corbeille globale sera vidée, aussi : +;\nThis global trashcan will be emptied, too: +; +;----------------------------------------------------------- +; diff --git "a/scalos/Modules/Empty_Trashcan.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" "b/scalos/Modules/Empty_Trashcan.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" new file mode 100755 index 000000000..8b7056423 --- /dev/null +++ "b/scalos/Modules/Empty_Trashcan.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" @@ -0,0 +1,40 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = français + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = french + +else + +############################################################################### +# AmigaOS and AROS + +LANG = français + +endif +endif diff --git "a/scalos/Modules/Empty_Trashcan.MUI/Catalogs/fran\303\247ais/Scalos/makefile" "b/scalos/Modules/Empty_Trashcan.MUI/Catalogs/fran\303\247ais/Scalos/makefile" new file mode 100644 index 000000000..3de0c453a --- /dev/null +++ "b/scalos/Modules/Empty_Trashcan.MUI/Catalogs/fran\303\247ais/Scalos/makefile" @@ -0,0 +1,14 @@ +# makefile for Empty_Trashcan.module (translated Texts : français) +# $Date$ +# $Revision$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mfrançais\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +Empty_Trashcan.catalog : Empty_Trashcan.ct ../../../Empty_Trashcan.cd + +All: Empty_Trashcan.catalog diff --git "a/scalos/Modules/Empty_Trashcan.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" "b/scalos/Modules/Empty_Trashcan.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" new file mode 100644 index 000000000..bd70f6165 --- /dev/null +++ "b/scalos/Modules/Empty_Trashcan.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" @@ -0,0 +1,30 @@ +# makefile for Empty_Trashcan.module (translated Texts : français) +# $Date: 2011-07-24 10:11:00 +0200 (So, 24. Jul 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = Empty_Trashcan + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Modules/Empty_Trashcan.MUI/Catalogs/sample/Scalos/Empty_Trashcan.ct b/scalos/Modules/Empty_Trashcan.MUI/Catalogs/sample/Scalos/Empty_Trashcan.ct new file mode 100644 index 000000000..f17601301 --- /dev/null +++ b/scalos/Modules/Empty_Trashcan.MUI/Catalogs/sample/Scalos/Empty_Trashcan.ct @@ -0,0 +1,233 @@ +; Empty_Trashcan.ct +## version $VER: Empty_Trashcan.catalog 40.1 (04 Dec 2005 23:01:34) +## codeset 0s +## language xxxxxx +; +;#arrayopts static __far +; +;+++translateme+++ +MSGID_TITLENAME +Scalos Empty_Trashcan +;Scalos Empty_Trashcan +; +;+++translateme+++ +MSGID_OKBUTTON +Ok +;Ok +; +;+++translateme+++ +MSGID_OKBUTTON_SHORT +O +;O +; +;+++translateme+++ +MSGID_SHORTHELP_OKBUTTON +Start emptying trashcan.\n\ +All contents is deleted irrevocably! +;Start emptying trashcan.\n\ +;All contents is deleted irrevocably! +; +;+++translateme+++ +MSGID_CANCELBUTTON +Cancel +;Cancel +; +;+++translateme+++ +MSGID_CANCELBUTTON_SHORT +c +;c +; +;+++translateme+++ +MSGID_SHORTHELP_CANCELBUTTON +Leave trashcan untouched and quit +;Leave trashcan untouched and quit +; +;+++translateme+++ +MSGID_ABORTBUTTON +Abort +;Abort +; +;+++translateme+++ +MSGID_ABORTBUTTON_SHORT +a +;a +; +;+++translateme+++ +MSGID_SHORTHELP_ABORTBUTTON +Immediately abort emptying\n\ +of trashcan and quit. +;Immediately abort emptying\n\ +;of trashcan and quit. +; +;+++translateme+++ +MSGID_CREATE_APPLICATION_FAILED +Failed to create Application.\n +;Failed to create Application.\n +; +;+++translateme+++ +MSGID_CREATE_MAINWINDOW_FAILED +Failed to open main window !\n +;Failed to open main window !\n +; +;+++translateme+++ +MSGID_OPEN_LIBRARY_FAILED +Failed to open \"%s\" !\n +;Failed to open \"%s\" !\n +; +;;----------------------------------------------------------- +; +;+++translateme+++ +MSGID_MENU_PROJECT +Project +;Project +; +;+++translateme+++ +MSGID_MENU_PROJECT_ABOUT +About... +;About... +; +;+++translateme+++ +MSGID_MENU_PROJECT_ABOUTMUI +About MUI... +;About MUI... +; +;+++translateme+++ +MSGID_MENU_PROJECT_QUIT +Quit +;Quit +; +;+++translateme+++ +MSGID_MENU_PROJECT_QUIT_SHORT +Q +;Q +; +;----------------------------------------------------------- +; +;+++translateme+++ +MSGID_ABOUTREQOK +_OK +;_OK +; +;+++translateme+++ +MSGID_ABOUTREQFORMAT +\33c\033bScalos Empty_Trashcan.module V%ld.%ld\033n\n\ +%s\n\ +© 2005%s The Scalos Team +;\33c\033bScalos Empty_Trashcan.module V%ld.%ld\033n\n\ +;%s\n\ +;© 2005%s The Scalos Team +; +;----------------------------------------------------------- +; +;+++translateme+++ +MSGID_WARNING_EMPTY_TRASHCAN +Warning! You cannot get back what you delete!\n\ +OK to empty the trashcan? +;Warning! You cannot get back what you delete!\n\ +;OK to empty the trashcan? +; +;+++translateme+++ +MSGID_GADGETS_EMPTY_ABORT +Empty|Abort +;Empty|Abort +; +;+++translateme+++ +MSGID_GADGETTEXT_OK +OK +;OK +; +;+++translateme+++ +MSGID_GADGETTEXT_CANCEL +Cancel +;Cancel +; +;+++translateme+++ +MSGID_EMPTY_TRASHCAN +Empty Trashcan +;Empty Trashcan +; +;+++translateme+++ +MSGID_GADGETS_DELETE_ABORT +Delete|Abort +;Delete|Abort +; +;+++translateme+++ +MSGID_EMPTYING_TRASHCAN +Emptying Trashcan... +;Emptying Trashcan... +; +;+++translateme+++ +MSGID_PATH +Path +;Path +; +;+++translateme+++ +MSGID_GADGET_ABORT +Abort +;Abort +; +;+++translateme+++ +MSGID_BUILD_FILELIST +Building Filelist... +;Building Filelist... +; +;+++translateme+++ +MSGID_OUT_OF_MEMORY +Not Enough Memory +;Not Enough Memory +; +; +MSGID_ERROR +Error +;Error +; +; +MSGID_FAILED_TO_DELETE +%s\n\ +couldn't be deleted:\n\ +%s +;%s\n\ +;couldn't be deleted:\n\ +;%s +; +; +MSGID_GADGETS_SKIP_ABORT +Skip it|Abort +;Skip it|Abort +; +; +MSGID_DELETE_PROTECTED +%s is protected against deletion.\n\ +Delete anyway? +;%s is protected against deletion.\n\ +;Delete anyway? +; +; +MSGID_GADGETS_DELETE_SKIP +Delete|Skip it +;Delete|Skip it +; +; +MSGID_GADGETS_DELETE_DELETEALL_PROTECT_SKIP +Delete|DeleteAllProtect|Skip +;Delete|DeleteAllProtect|Skip +; +; +MSGID_TEXT_CURRENTITEM +Currently removing: +;Currently removing: +; +; +MSGID_TEXT_CURRENTITEM_SHORTHELP +This is the name if the item currently\n\ +being deleted from trashcan. +;This is the name if the item currently\n\ +;being deleted from trashcan. +; +; +MSGID_GLOBAL_TRASHCAN +\nThis global trashcan will be emptied, too: +;\nThis global trashcan will be emptied, too: +; +;----------------------------------------------------------- +; diff --git a/scalos/Modules/Empty_Trashcan.MUI/Empty_Trashcan.c b/scalos/Modules/Empty_Trashcan.MUI/Empty_Trashcan.c new file mode 100755 index 000000000..5a2c27947 --- /dev/null +++ b/scalos/Modules/Empty_Trashcan.MUI/Empty_Trashcan.c @@ -0,0 +1,1448 @@ +// Empty_Trashcan.c +// $Date$ +// $Revision$ + + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include // +jmc+ + +#include "Empty_Trashcan.h" + +#define Empty_Trashcan_NUMBERS +#define Empty_Trashcan_ARRAY +#define Empty_Trashcan_CODE +#include STR(SCALOSLOCALE) + +//---------------------------------------------------------------------------- + +#define VERSION_MAJOR 40 +#define VERSION_MINOR 1 + +//---------------------------------------------------------------------------- + +#define ID_MUIO MAKE_ID('M','U','I','O') +#define ID_CMTC MAKE_ID('C','M','T','C') +#define ID_STTC MAKE_ID('S','T','T','C') + +//---------------------------------------------------------------------------- + +#define Application_Return_Ok 1001 + +//---------------------------------------------------------------------------- + +#define KeyButtonHelp(name,key,HelpText)\ + TextObject,\ + ButtonFrame,\ + MUIA_Font, MUIV_Font_Button,\ + MUIA_Text_Contents, name,\ + MUIA_Text_PreParse, "\33c",\ + MUIA_Text_HiChar , key,\ + MUIA_ControlChar , key,\ + MUIA_InputMode , MUIV_InputMode_RelVerify,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShortHelp , HelpText,\ + MUIA_CycleChain , TRUE,\ + End + +#define CheckMarkHelp(InputMode, Selected, Image,HelpTextID, NumID)\ + ImageObject,\ + ImageButtonFrame,\ + MUIA_InputMode , InputMode,\ + MUIA_Image_Spec , Image,\ + MUIA_Image_FreeVert , TRUE,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShowSelState , Selected,\ + MUIA_CycleChain , TRUE,\ + MUIA_ShortHelp , GetLocString(HelpTextID), \ + MUIA_ExportID , NumID, \ + End + +//---------------------------------------------------------------------------- + +// Read support + +struct DirList +{ + struct MinList list; + BPTR lock; + ULONG read; +}; + +struct DirNode +{ + struct MinNode node; + STRPTR name; + struct DirList list; + struct DirList *parentList; + ULONG icon; + ULONG prot; +}; + +struct FileNode +{ + struct MinNode node; + STRPTR name; + ULONG nameLen; + ULONG icon; +}; + +//---------------------------------------------------------------------------- + +#if !defined(__AROS__) && !defined(__amigaos4__) +#include + +long _stack = 16384; // minimum stack size, used by SAS/C startup code +#endif + +//---------------------------------------------------------------------------- + +CONST_STRPTR VerString = "$VER: Empty_Trashcan.module 40.1 "__DATE__ " " COMPILER_STRING; + +//---------------------------------------------------------------------------- + +static STRPTR NameOfLock( BPTR lock ); +static STRPTR BuildIconName( CONST_STRPTR name ); +static BOOL IsDeletable( CONST_STRPTR name, ULONG prot); +static long Unprotect( CONST_STRPTR name, const ULONG icon, ULONG prot); +static BOOL DeleteIcon(CONST_STRPTR name, const ULONG update ); +static BOOL DeleteTheFile( CONST_STRPTR name, const ULONG icon, const ULONG update ); +static BOOL ReadInDir( struct DirList *list, APTR dirPool ); +static BOOL DeleteDir( struct DirList *root, APTR dirPool ); +static BOOL OpenLibraries(void); +static void CloseLibraries(void); +static LONG ReportError(LONG Result, CONST_STRPTR Filename, ULONG GadgetMsgId); +static STRPTR GetLocString(ULONG MsgId); +//static void TranslateStringArray(STRPTR *stringArray); +static SAVEDS(APTR) INTERRUPT OpenAboutMUIHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT OpenAboutHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT EmptyTrashcanHookFunc(struct Hook *hook, Object *o, Msg msg); +static void DoEmptyTrashcan(struct WBArg *wbarg); +static ULONG ReadDeleteModulePrefs(void); + +//---------------------------------------------------------------------------- + +extern struct ExecBase *SysBase; +struct IntuitionBase *IntuitionBase = NULL; +T_LOCALEBASE LocaleBase = NULL; +#ifndef __amigaos4__ +T_UTILITYBASE UtilityBase = NULL; +#endif +struct Library *MUIMasterBase = NULL; +struct Library *IconBase = NULL; +struct Library *IFFParseBase = NULL; + +#ifdef __amigaos4__ +struct IntuitionIFace * IIntuition = NULL; +struct LocaleIFace *ILocale = NULL; +struct MUIMasterIFace *IMUIMaster = NULL; +struct IconIFace *IIcon = NULL; +struct IFFParseIFace *IIFFParse = NULL; +#endif + +static struct Catalog *Cat; + + +static ULONG DeleteModuleUseTrashcan = FALSE; +static char DeleteModuleGlobalTrashcan[512] = ""; + +static BOOL deleteAllProt; + +static struct Hook AboutHook = { { NULL, NULL }, HOOKFUNC_DEF(OpenAboutHookFunc), NULL }; +static struct Hook AboutMUIHook = { { NULL, NULL }, HOOKFUNC_DEF(OpenAboutMUIHookFunc), NULL }; +static struct Hook EmptyTrashcanHook = { { NULL, NULL }, HOOKFUNC_DEF(EmptyTrashcanHookFunc), NULL }; + +static struct WBArg *wbarg1 = NULL; + +//---------------------------------------------------------------------------- + +static Object *APP_Main; +static Object *WIN_Main, *WIN_AboutMUI, *WIN_Progress; +static Object *OkButton, *CancelButton; +static Object *AbortButton; +static Object *TextCurrentItem; +static Object *MenuAbout, *MenuAboutMUI, *MenuQuit; + +//---------------------------------------------------------------------------- + +static STRPTR NameOfLock( BPTR lock ) +{ + STRPTR n; + BOOL again; + ULONG bufSize = 127; + if ( !lock ) + return NULL; + + do + { + again = FALSE; + if ((n = malloc(bufSize))) + { + if ( NameFromLock( lock, n, bufSize-1 ) == DOSFALSE ) + { + if ( IoErr() == ERROR_LINE_TOO_LONG ) + { + bufSize += 127; + again = TRUE; + } + free(n); + n = NULL; + } + } + } while(again); + + return n; +} + +//------------------------------------- + +static STRPTR BuildIconName( CONST_STRPTR name ) +{ + ULONG namelen = strlen(name); + STRPTR infoname = malloc(namelen+8); + if (infoname) + { + strcpy(infoname,name); + strcat(infoname,".info"); + } + return infoname; +} + +//------------------------------------- + +static BOOL IsDeletable( CONST_STRPTR name, ULONG prot) +{ + if (( prot & FIBF_DELETE )) + { + BOOL del = deleteAllProt; + + if ( !deleteAllProt) + { + LONG Result; + + //MUI_RequestA( + Result = MUI_Request(APP_Main, WIN_Main, 0, + GetLocString(MSGID_EMPTY_TRASHCAN), + GetLocString(MSGID_GADGETS_DELETE_DELETEALL_PROTECT_SKIP), + GetLocString(MSGID_DELETE_PROTECTED), + name); + + switch (Result) + { + case 0: + break; + case 1: + del = TRUE; + break; + case 2: + del = deleteAllProt = TRUE; + break; + } + } + return del; + } + return TRUE; +} + +//------------------------------------- + +static long Unprotect( CONST_STRPTR name, const ULONG icon, ULONG prot) +{ + if (( prot & FIBF_DELETE )) + { + BOOL ok; + if (SetProtection(name,0) != DOSFALSE ) + ok = TRUE; + else + { + LONG ioerr = IoErr(); + if ( ioerr == ERROR_OBJECT_NOT_FOUND ) + ok = TRUE; + else + { +// ok = FALSE; + return ReportError(ioerr, name, MSGID_GADGETTEXT_CANCEL); + } + } + + if (ok && icon ) + { + if ( icon ) + { + STRPTR infoname = BuildIconName(name); + if (infoname) + { + if (SetProtection(infoname,0) == DOSFALSE ) + { + LONG ioerr = IoErr(); + if ( ioerr == ERROR_OBJECT_NOT_FOUND ) + /* ok = TRUE */; + else + return ReportError(ioerr, name, MSGID_GADGETS_SKIP_ABORT); + } + + free(infoname); + } + } + } + } + return 2; +} + +//------------------------------------- + +static BOOL DeleteIcon(CONST_STRPTR name, const ULONG update ) +{ + if (update) + return DeleteDiskObject((STRPTR) name); + else + { + STRPTR iname = BuildIconName(name); + if (iname) + { + BOOL Result; + + Result = DeleteFile(iname); + + free(iname); + + return Result; + } + } + + return FALSE; +} + +//------------------------------------- + +static BOOL DeleteTheFile( CONST_STRPTR name, const ULONG icon, const ULONG update ) +{ + BOOL goon = TRUE; + LONG ioerr; + BOOL onlyicon = FALSE; + + + set(TextCurrentItem, MUIA_Text_Contents, name); + + DoMethod(APP_Main, MUIM_Application_InputBuffered); + + if (DeleteFile(name) == DOSFALSE) + { + ioerr = IoErr(); + if ( ioerr == ERROR_OBJECT_NOT_FOUND) + { + if (!DeleteIcon(name,update)) + { + ioerr = IoErr(); + if (ioerr == ERROR_OBJECT_NOT_FOUND) + ioerr = 0; + } + else + ioerr = 0; + onlyicon = TRUE; + } + else + { + if ( ioerr == ERROR_OBJECT_IN_USE ) + { + if (DeleteFile(name) == DOSFALSE) + ioerr = IoErr(); + else + ioerr = 0; + } + } + } + else + ioerr = 0; + + if ( ioerr ) + { + switch( ioerr) + { + case ERROR_DELETE_PROTECTED: + { + BOOL del = deleteAllProt; + if ( !deleteAllProt) + { + LONG Result; + + //MUI_RequestA( + Result = MUI_Request(APP_Main, WIN_Main, 0, + GetLocString(MSGID_EMPTY_TRASHCAN), + GetLocString(MSGID_GADGETS_DELETE_DELETEALL_PROTECT_SKIP), + GetLocString(MSGID_DELETE_PROTECTED), + name); + + switch (Result) + { + case 0: + del = FALSE; + break; + case 1: + del = TRUE; + break; + case 2: + del = deleteAllProt = TRUE; + break; + } + + } + if (del) + { + BOOL ok = onlyicon; + if ( !ok ) + if (SetProtection(name,0) != DOSFALSE ) + ok = TRUE; + + if (ok)//nlyicon || SetProtection(name,NULL) != DOSFALSE ) + { + BOOL error; + + if ( icon || onlyicon ) + { + ULONG namelen = strlen(name); + STRPTR infoname = malloc(namelen+8); + error = TRUE; + if (infoname) + { + strcpy(infoname,name); + strcpy(infoname+namelen,".info"); + + if (SetProtection(infoname,0) != DOSFALSE ) + error = FALSE; + + free(infoname); + } + else + SetIoErr(ERROR_NO_FREE_STORE); + } + else + error = FALSE; + + if ( !error ) + { + if ( onlyicon ) + { + if (DeleteIcon(name,update)) + return TRUE; + } + else + { + if (DeleteFile(name) != DOSFALSE ) + { + if (icon) + { + if (DeleteIcon(name,update)) + return TRUE; + } + else + return TRUE; + } + } + } + } + ioerr = IoErr(); + } + else + break; + } + + default: + return (BOOL) ReportError(ioerr, name, MSGID_GADGETS_SKIP_ABORT); + break; + } + } + else + { + if ( icon ) + { + DeleteIcon(name,update); + } + } + + return goon; +} + +//------------------------------------- + +static BOOL ReadInDir( struct DirList *list, APTR dirPool ) +{ + BOOL retval = TRUE; + STRPTR lockName; + + if ( !list->lock ) + { + d1(KPrintF(__FILE__ "/%s/%ld: No Lock\n", __FUNC__, __LINE__)); + return FALSE; + } + + if ( list->read ) + { + d1(KPrintF(__FILE__ "/%s/%ld: Already read", __FUNC__, __LINE__)); + return TRUE; + } + + lockName = NameOfLock(list->lock); + if ( lockName ) + { + ULONG lockSize = strlen(lockName); + APTR filePool = CreatePool( 0,4096,4096); + if ( filePool ) + { + struct ExAllControl *eac; + eac = (struct ExAllControl*)AllocDosObject(DOS_EXALLCONTROL,NULL); + if ( eac ) + { + struct ExAllData *ead; + ead = (struct ExAllData*) malloc(1032); + if (ead) + { + LONG more; + struct MinList fileList; + NewList((struct List*)&fileList); + + eac->eac_LastKey = 0; + eac->eac_MatchString = NULL; + + list->read = TRUE; + + do + { + struct ExAllData *ed = ead; + more = ExAll( list->lock, ed, 1024, ED_PROTECTION, eac ); + if ((!more) && (IoErr() != ERROR_NO_MORE_ENTRIES )) + { + retval = FALSE; + break; + } + + if ( eac->eac_Entries ) + { + do + { + ULONG nlen = strlen(ed->ed_Name); + ULONG len = nlen+8+lockSize; + if ( ed->ed_Type > 0 ) + { + STRPTR name = (STRPTR)AllocPooled(dirPool,len); + if (name) + { + struct DirNode *dir = (struct DirNode*)AllocPooled(dirPool,sizeof(struct DirNode)); + if ( dir ) + { + strcpy(name,lockName); + AddPart(name,ed->ed_Name,len); + + dir->name = name; + dir->list.lock = Lock( name, ACCESS_READ); + dir->list.read = FALSE; + dir->parentList = list; + dir->icon = FALSE; + dir->prot = ed->ed_Prot; + NewList((struct List*)&dir->list); + + AddTail((struct List*)list, (struct Node*)dir); + } + } + } + else + { + struct FileNode *file = (struct FileNode*)AllocPooled(filePool,sizeof(struct FileNode)); + if ( file ) + { + STRPTR name = (STRPTR)AllocPooled(filePool,len); + if ( name ) + { + strcpy(name,lockName); + AddPart(name,ed->ed_Name,len); + + file->name = name; + file->nameLen = strlen(name); + file->icon = FALSE; + AddTail((struct List*)&fileList, (struct Node*)file); + } + } + } + ed = ed->ed_Next; + } while(ed); + } + } while(more); + + ExAllEnd( list->lock, ead, 1024, ED_PROTECTION, eac ); + free(ead); + + if ( !IsListEmpty((struct List*)&fileList)) + { + struct FileNode *node; + struct DirNode *dnode; + + node = (struct FileNode*)fileList.mlh_Head; + while(node->node.mln_Succ && retval) + { + // Icons aussortieren + if ( node->nameLen > 4 ) + { + if ( !Stricmp(".info",node->name+node->nameLen-5)) + { + struct FileNode *fnode = (struct FileNode*)fileList.mlh_Head; + BOOL iconfound = FALSE; + node->name[node->nameLen-5] = 0; + while(fnode->node.mln_Succ) + { + if ( fnode != node ) + { + if ( !Stricmp(node->name,fnode->name)) + { + fnode->icon = iconfound = TRUE; + break; + } + } + fnode = (struct FileNode*)fnode->node.mln_Succ; + } + + if ( !iconfound ) + { + dnode = (struct DirNode*)list->list.mlh_Head; + while(dnode->node.mln_Succ) + { + if ( !Stricmp(node->name,dnode->name)) + { + dnode->icon = iconfound = TRUE; + break; + } + + dnode = (struct DirNode*)dnode->node.mln_Succ; + } + } + + if ( iconfound ) + { + struct FileNode *tfn = node; + node = (struct FileNode*)node->node.mln_Succ; + Remove((struct Node*)tfn); + continue; + } + } + } + node = (struct FileNode*)node->node.mln_Succ; + } + + node = (struct FileNode*)fileList.mlh_Head; + while(node->node.mln_Succ && retval) + { + retval = DeleteTheFile(node->name,node->icon,FALSE); + node = (struct FileNode*)node->node.mln_Succ; + } + + dnode = (struct DirNode*)list->list.mlh_Head; + while(dnode->node.mln_Succ) + { + struct DirNode *help = dnode; + dnode = (struct DirNode*)dnode->node.mln_Succ; + if ( !IsDeletable(help->name,help->prot)) + { + UnLock(help->list.lock); + Remove((struct Node*)help); + } + } + } + } + + FreeDosObject(DOS_EXALLCONTROL,eac); + } + DeletePool(filePool); + } + free(lockName); + } + return retval; +} + +//------------------------------------- + +static BOOL DeleteDir( struct DirList *root, APTR dirPool ) +{ + struct DirList *cl = root; + BOOL goon = TRUE; + + d1(kprintf(__FUNC__ "/%ld: root = %08lx dirPool = %08lx\n", __LINE__, root, dirPool)); + + while(cl) + { + if (goon) + { + if (!ReadInDir(cl,dirPool)) + goon = FALSE; + } + + if ( !IsListEmpty((struct List*)cl)) + { + struct DirNode *cn = (struct DirNode*)cl->list.mlh_Head; + cl = (struct DirList*)&cn->list; + } + else + { + if (cl != root ) + { + struct DirNode *cn = (struct DirNode*)(((ULONG*)cl)-3); + struct DirNode *ncn = (struct DirNode*)cn->node.mln_Succ; + + if ( !ncn->node.mln_Succ ) + { + do + { + if ( cl == root ) + return TRUE; + + cl = cn->parentList; + if ( !cl ) + { + d1(KPrintF(__FILE__ "/%s/%ld: Ready...", __FUNC__, __LINE__)); + return TRUE; + } + + if ( IsListEmpty((struct List*)cl)) + { + return FALSE; + } + + ncn = (struct DirNode*)RemHead((struct List*)cl); + cn = (struct DirNode*)(((ULONG*)cl)-3); + + if (ncn->list.lock) + { + UnLock(ncn->list.lock); + ncn->list.lock = (BPTR)NULL; + } + + if ( goon ) + { + Unprotect(ncn->name,ncn->icon,ncn->prot); + goon = DeleteTheFile(ncn->name,ncn->icon,FALSE); + } + } while( IsListEmpty((struct List*)cl)); + if ( !cl ) + break; + + ncn = (struct DirNode*)cl->list.mlh_Head; + } + else + { + Remove((struct Node*)cn); + + if (cn->list.lock) + { + UnLock(cn->list.lock); + cn->list.lock = (BPTR)NULL; + } + + if ( goon ) + { + Unprotect(cn->name,cn->icon,cn->prot); + goon = DeleteTheFile(cn->name,cn->icon,FALSE); + } + } + + cl = (struct DirList*)&ncn->list; + } + else + return FALSE; + } + } + + return FALSE; +} + +//------------------------------------- + +int main(int argc, char *argv[]) +{ + struct WBStartup *WBenchMsg = + (argc == 0) ? (struct WBStartup *)argv : NULL; + + if (NULL == WBenchMsg) + { + return 5; + } + if (WBenchMsg->sm_NumArgs < 2) + { + return 5; + } + + wbarg1 = &WBenchMsg->sm_ArgList[1]; + do { + LONG win_opened = FALSE; + BOOL Run = TRUE; + + if (!OpenLibraries()) + break; + + if (LocaleBase) + Cat = OpenCatalogA( NULL, "Scalos/Empty_Trashcan.catalog", NULL); + + ReadDeleteModulePrefs(); + + APP_Main = ApplicationObject, + MUIA_Application_Title, GetLocString(MSGID_TITLENAME), + MUIA_Application_Version, "$VER: Scalos Empty_Trashcan.module V40.2 (" __DATE__ ") " COMPILER_STRING, + MUIA_Application_Copyright, "© The Scalos Team, 2005" CURRENTYEAR, + MUIA_Application_Author, "The Scalos Team", + MUIA_Application_Description, "Scalos Empty_Trashcan module", + MUIA_Application_Base, "SCALOS_EMPTY_TRASH", + + SubWindow, WIN_Main = WindowObject, + MUIA_Window_Title, GetLocString(MSGID_TITLENAME), +// MUIA_Window_ID, MAKE_ID('M','A','I','N'), + MUIA_Window_AppWindow, FALSE, + + MUIA_Window_TopEdge, MUIV_Window_TopEdge_Moused, + MUIA_Window_LeftEdge, MUIV_Window_LeftEdge_Moused, + + MUIA_Window_Width, MUIV_Window_Width_Screen(30), //+jmc+ + + WindowContents, VGroup, + Child, TextObject, + MUIA_Text_PreParse, MUIX_C, + MUIA_Text_Contents, GetLocString(MSGID_WARNING_EMPTY_TRASHCAN), + End, //TextObject + + Child, VGroup, + MUIA_ShowMe, strlen(DeleteModuleGlobalTrashcan) > 0 && DeleteModuleUseTrashcan, + + Child, TextObject, + MUIA_Text_PreParse, MUIX_C, + MUIA_Text_Contents, GetLocString(MSGID_GLOBAL_TRASHCAN), + End, //TextObject + Child, TextObject, + MUIA_Text_PreParse, MUIX_C, + MUIA_Text_Contents, DeleteModuleGlobalTrashcan, + End, //TextObject + End, //VGroup + + Child, HGroup, + MUIA_Group_SameWidth, TRUE, + Child, OkButton = KeyButtonHelp(GetLocString(MSGID_OKBUTTON), + *GetLocString(MSGID_OKBUTTON_SHORT), + GetLocString(MSGID_SHORTHELP_OKBUTTON)), + Child, CancelButton = KeyButtonHelp(GetLocString(MSGID_CANCELBUTTON), + *GetLocString(MSGID_CANCELBUTTON_SHORT), + GetLocString(MSGID_SHORTHELP_CANCELBUTTON)), + End, //HGroup + End, //VGroup + + End, //WindowObject + + SubWindow, WIN_Progress = WindowObject, + MUIA_Window_Title, GetLocString(MSGID_TITLENAME), +// MUIA_Window_ID, MAKE_ID('M','A','I','N'), + MUIA_Window_AppWindow, FALSE, + + MUIA_Window_TopEdge, MUIV_Window_TopEdge_Moused, + MUIA_Window_LeftEdge, MUIV_Window_LeftEdge_Moused, + + MUIA_Window_Width, MUIV_Window_Width_Screen(30), //+jmc+ + + WindowContents, VGroup, + Child, TextObject, + MUIA_Text_PreParse, MUIX_C, + MUIA_Text_Contents, GetLocString(MSGID_TEXT_CURRENTITEM), + MUIA_ShortHelp, GetLocString(MSGID_TEXT_CURRENTITEM_SHORTHELP), + End, //TextObject + + Child, TextCurrentItem = TextObject, + MUIA_Text_PreParse, MUIX_C, + MUIA_Text_Contents, "", + End, //TextObject + + Child, HGroup, + MUIA_Group_SameWidth, TRUE, + Child, AbortButton = KeyButtonHelp(GetLocString(MSGID_ABORTBUTTON), + *GetLocString(MSGID_ABORTBUTTON_SHORT), GetLocString(MSGID_SHORTHELP_ABORTBUTTON)), + End, //HGroup + End, //VGroup + + End, //WindowObject + + MUIA_Application_Menustrip, MenustripObject, + Child, MenuObjectT(GetLocString(MSGID_MENU_PROJECT)), + + Child, MenuAbout = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUT), + End, + Child, MenuAboutMUI = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUTMUI), + End, + Child, MenuitemObject, + MUIA_Menuitem_Title, -1, + End, + Child, MenuQuit = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_QUIT), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_PROJECT_QUIT_SHORT), + End, + + End, //MenuObjectT + End, //MenuStripObject + + End; //ApplicationObject + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: \n", __LINE__)); + + if (NULL == APP_Main) + { + printf(GetLocString(MSGID_CREATE_APPLICATION_FAILED)); + break; + } + + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + WIN_Main, 3, MUIM_Set, MUIA_Window_Open, FALSE); + + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + // If cancel button is pressed, quit + DoMethod(CancelButton, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + // Ok button is pressed, start emptying the trashcan + DoMethod(OkButton, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_CallHook, &EmptyTrashcanHook); + + DoMethod(AbortButton, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + DoMethod(MenuAbout, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &AboutHook); + + DoMethod(MenuAboutMUI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &AboutMUIHook); + + DoMethod(MenuQuit, MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + set(WIN_Main, MUIA_Window_Open, TRUE); + get(WIN_Main, MUIA_Window_Open, &win_opened); + + if (!win_opened) + { + printf(GetLocString(MSGID_CREATE_MAINWINDOW_FAILED)); + break; + } + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: \n", __LINE__)); + + while (Run) + { + LONG sigs; + ULONG Action = DoMethod(APP_Main, MUIM_Application_NewInput, &sigs); + + switch (Action) + { + case Application_Return_Ok: + Run = FALSE; + break; + case MUIV_Application_ReturnID_Quit: + Run = FALSE; + break; + } + } + } while (0); + + set(WIN_Main, MUIA_Window_Open, FALSE); + + if (APP_Main) + MUI_DisposeObject(APP_Main); + if (Cat) + CloseCatalog(Cat); + + CloseLibraries(); + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT EmptyTrashcanHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + BPTR ParentLock = (BPTR)NULL; + BPTR DirLock = (BPTR)NULL; + + (void) hook, + (void) o; + (void) msg; + + // Empty selected trashcan + DoEmptyTrashcan(wbarg1); + + // Now try to empty global trashcan, if defined + do { + struct WBArg globalTrashcanWBArg; + + if (strlen(DeleteModuleGlobalTrashcan) < 1) + break; + if (!DeleteModuleUseTrashcan) + break; + + globalTrashcanWBArg.wa_Name = FilePart(DeleteModuleGlobalTrashcan); + if (NULL == globalTrashcanWBArg.wa_Name) + break; + + DirLock = Lock(DeleteModuleGlobalTrashcan, ACCESS_READ); + if ((BPTR)NULL == DirLock) + break; + + ParentLock = globalTrashcanWBArg.wa_Lock = ParentDir(DirLock); + // NULL is valid for ParentLock + + // Now empty global trashcan + DoEmptyTrashcan(&globalTrashcanWBArg); + } while (0); + + if (ParentLock) + UnLock(ParentLock); + if (DirLock) + UnLock(DirLock); +} + +//---------------------------------------------------------------------------- + +static void DoEmptyTrashcan(struct WBArg *wbarg) +{ + BPTR OldDir = (BPTR)NULL; + BPTR fLock = (BPTR)NULL; + struct FileInfoBlock *fib = NULL; + APTR dirPool = NULL; + STRPTR name = NULL; + LONG win_opened = FALSE; + + do { + struct DirList list; + + // Close initial window + set(WIN_Main, MUIA_Window_Open, FALSE); + + // Open progress display window + set(WIN_Progress, MUIA_Window_Open, TRUE); + get(WIN_Progress, MUIA_Window_Open, &win_opened); + + if (!win_opened) + { + printf(GetLocString(MSGID_CREATE_MAINWINDOW_FAILED)); + break; + } + + d1(kprintf(__FUNC__ "/%ld: \n", __LINE__)); + + OldDir = CurrentDir(wbarg->wa_Lock); + + if (wbarg->wa_Name) + { + d1(kprintf(__FUNC__ "/%ld: wa_Name = <%s>\n", __LINE__, wbarg->wa_Name)); + fLock = Lock(wbarg->wa_Name, ACCESS_READ); + } + else + { + fLock = Lock("", ACCESS_READ); + } + + if ((BPTR)NULL == fLock) + break; + + fib = AllocDosObject(DOS_FIB, NULL); + if (NULL == fib) + break; + + if (!Examine(fLock, fib)) + break; + + if (fib->fib_DirEntryType < 0) + break; + + dirPool = CreatePool(MEMF_PUBLIC, 4096, 4096); + if (NULL == dirPool) + break; + + d1(kprintf(__FUNC__ "/%ld: dirPool = %08lx\n", __LINE__, dirPool)); + + name = NameOfLock(wbarg->wa_Lock); + d1(kprintf(__FUNC__ "/%ld: name = %08lx\n", __LINE__, name)); + if (NULL == name) + break; + + NewList((struct List*)&list); + + list.lock = fLock; + list.read = FALSE; + + DeleteDir(&list, dirPool); + + // Close progress window + set(WIN_Progress, MUIA_Window_Open, FALSE); + } while (0); + + if (name) + free(name); + if (dirPool) + DeletePool(dirPool); + if (fib) + FreeDosObject(DOS_FIB, fib); + if (fLock) + UnLock(fLock); + if (OldDir) + CurrentDir(OldDir); + + if (Cat) + CloseCatalog( Cat ); + + DoMethod(APP_Main, MUIM_Application_ReturnID, Application_Return_Ok); +} + +//------------------------------------- + +static BOOL OpenLibraries(void) +{ + MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN-1); + if (NULL == MUIMasterBase) + return FALSE; +#ifdef __amigaos4__ + IMUIMaster = (struct MUIMasterIFace *)GetInterface((struct Library *)MUIMasterBase, "Main", 1, NULL); + if (NULL == IMUIMaster) + return FALSE; +#endif + + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + if (NULL == IntuitionBase) + return FALSE; +#ifdef __amigaos4__ + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "Main", 1, NULL); + if (NULL == IIntuition) + return FALSE; +#endif + + LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 38); + if (NULL == LocaleBase) + return FALSE; +#ifdef __amigaos4__ + ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "Main", 1, NULL); + if (NULL == ILocale) + return FALSE; +#endif + +#ifndef __amigaos4__ + UtilityBase = (T_UTILITYBASE) OpenLibrary("utility.library", 39); + if (NULL == UtilityBase) + return FALSE; +#endif + + IconBase = OpenLibrary("icon.library", 37); + if (NULL == IconBase) + return FALSE; +#ifdef __amigaos4__ + IIcon = (struct IconIFace *)GetInterface((struct Library *)IconBase, "Main", 1, NULL); + if (NULL == IIcon) + return FALSE; +#endif + + IFFParseBase = OpenLibrary("iffparse.library", 37); + if (NULL == IFFParseBase) + return FALSE; +#ifdef __amigaos4__ + IIFFParse = (struct IFFParseIFace *)GetInterface((struct Library *)IFFParseBase, "Main", 1, NULL); + if (NULL == IIFFParse) + return FALSE; +#endif + + return TRUE; +} + +//---------------------------------------------------------------------------- + +static void CloseLibraries(void) +{ +#ifdef __amigaos4__ + if (IIFFParse) + { + DropInterface((struct Interface *)IIFFParse); + IIFFParse = NULL; + } +#endif + if (IFFParseBase) + { + CloseLibrary(IFFParseBase); + IFFParseBase = NULL; + } +#ifdef __amigaos4__ + if (IIcon) + { + DropInterface((struct Interface *)IIcon); + IIcon = NULL; + } +#endif + if (IconBase) + { + CloseLibrary(IconBase); + IconBase = NULL; + } +#ifndef __amigaos4__ + if (UtilityBase) + { + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } +#endif +#ifdef __amigaos4__ + if (ILocale) + { + DropInterface((struct Interface *)ILocale); + ILocale = NULL; + } +#endif + if (LocaleBase) + { + CloseLibrary((struct Library *)LocaleBase); + LocaleBase = NULL; + } +#ifdef __amigaos4__ + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } +#endif + if (IntuitionBase) + { + CloseLibrary((struct Library *)IntuitionBase); + IntuitionBase = NULL; + } +#ifdef __amigaos4__ + if (IMUIMaster) + { + DropInterface((struct Interface *)IMUIMaster); + IMUIMaster = NULL; + } +#endif + if (MUIMasterBase) + { + CloseLibrary(MUIMasterBase); + MUIMasterBase = NULL; + } +} + +//---------------------------------------------------------------------------- + +static LONG ReportError(LONG IoResult, CONST_STRPTR Filename, ULONG GadgetMsgId) +{ + char FaultText[256]; + LONG Result; + + Fault(IoResult, "", FaultText, sizeof(FaultText)); + + Result = MUI_Request(APP_Main, WIN_Main, 0, + GetLocString(MSGID_EMPTY_TRASHCAN), + GetLocString(GadgetMsgId), + GetLocString(MSGID_FAILED_TO_DELETE), + Filename, FaultText); + + return Result; +} + +//---------------------------------------------------------------------------- + +static STRPTR GetLocString(ULONG MsgId) +{ + struct Empty_Trashcan_LocaleInfo li; + + li.li_Catalog = Cat; +#ifndef __amigaos4__ + li.li_LocaleBase = LocaleBase; +#else + li.li_ILocale = ILocale; +#endif + + return (STRPTR)GetEmpty_TrashcanString(&li, MsgId); +} + +/* +static void TranslateStringArray(STRPTR *stringArray) +{ + while (*stringArray) + { + *stringArray = GetLocString((ULONG) *stringArray); + stringArray++; + } +} +*/ +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT OpenAboutMUIHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + if (NULL == WIN_AboutMUI) + { + WIN_AboutMUI = MUI_NewObject(MUIC_Aboutmui, + MUIA_Window_RefWindow, WIN_Main, + MUIA_Aboutmui_Application, APP_Main, + End; + } + + if (WIN_AboutMUI) + set(WIN_AboutMUI, MUIA_Window_Open, TRUE); + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT OpenAboutHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + MUI_Request(APP_Main, WIN_Main, 0, + GetLocString(MSGID_EMPTY_TRASHCAN), + GetLocString(MSGID_ABOUTREQOK), + GetLocString(MSGID_ABOUTREQFORMAT), + VERSION_MAJOR, VERSION_MINOR, COMPILER_STRING, CURRENTYEAR); +} + +//---------------------------------------------------------------------------- + +static ULONG ReadDeleteModulePrefs(void) +{ + LONG Result; + struct IFFHandle *iff; + BOOL iffOpened = FALSE; + ULONG *MuioChunk = NULL; + + do { + iff = AllocIFF(); + if (NULL == iff) + { + Result = IoErr(); + break; + } + + InitIFFasDOS(iff); + + iff->iff_Stream = (IPTR)Open("ENV:mui/DELETE.MODULE.cfg", MODE_OLDFILE); + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: iff_Stream=%08lx\n", __LINE__, iff->iff_Stream)); + + if (0 == iff->iff_Stream) + { + Result = IoErr(); + break; + } + + Result = OpenIFF(iff, IFFF_READ); + if (RETURN_OK != Result) + break; + + iffOpened = TRUE; + + Result = StopChunk(iff, ID_PREF, ID_MUIO); + if (RETURN_OK != Result) + break; + + while (RETURN_OK == Result) + { + struct ContextNode *cn; + + Result = ParseIFF(iff, IFFPARSE_SCAN); + if (RETURN_OK != Result) + break; + + cn = CurrentChunk(iff); + if (NULL == cn) + continue; + + if (ID_MUIO == cn->cn_ID) + { + LONG Actual; + LONG len = cn->cn_Size; + const ULONG *lptr; + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: iff_Stream=%08lx\n", __LINE__, cn->cn_ID, cn->cn_Size)); + + MuioChunk = malloc(cn->cn_Size); + if (NULL == MuioChunk) + break; + + Actual = ReadChunkBytes(iff, MuioChunk, cn->cn_Size); + if (Actual < 0) + break; + + lptr = MuioChunk; + while (len > 0) + { + size_t EntryLen = lptr[1]; + size_t slen; + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: len=%ld ID=%08lx EntryLen=%lu\n", __LINE__, len, lptr[0], EntryLen)); + + switch (lptr[0]) + { + case ID_CMTC: // Use Trashcan + DeleteModuleUseTrashcan = lptr[2]; + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: DeleteModuleUseTrashcan=%ld\n", __LINE__, DeleteModuleUseTrashcan)); + break; + case ID_STTC: // Global trashcan location + slen = EntryLen; + if (slen >= sizeof(DeleteModuleGlobalTrashcan)) + slen = sizeof(DeleteModuleGlobalTrashcan) - 1; + memcpy(DeleteModuleGlobalTrashcan, (char *) &lptr[2], slen); + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: DeleteModuleGlobalTrashcan=<%s>\n", __LINE__, DeleteModuleGlobalTrashcan)); + break; + default: + break; + } + + len -= 2 * sizeof(ULONG) + EntryLen; + lptr = (ULONG *) (((UBYTE *) &lptr[2]) + EntryLen); + } + + + } + } + } while (0); + + if (iff) + { + if (iffOpened) + CloseIFF(iff); + + if (iff->iff_Stream) + Close((BPTR)iff->iff_Stream); + + FreeIFF(iff); + } + if (MuioChunk) + free(MuioChunk); + + return (ULONG) Result; +} + +//---------------------------------------------------------------------------- + + diff --git a/scalos/Modules/Empty_Trashcan.MUI/Empty_Trashcan.cd b/scalos/Modules/Empty_Trashcan.MUI/Empty_Trashcan.cd new file mode 100755 index 000000000..99af3530c --- /dev/null +++ b/scalos/Modules/Empty_Trashcan.MUI/Empty_Trashcan.cd @@ -0,0 +1,180 @@ +; Empty_Trashcan.cd +; version $VER: Empty_Trashcan.catalog 40.1 (04 Dec 2005 23:10:45) +; codeset 0s +; language english +; +;#arrayopts static __far +; +; +MSGID_TITLENAME (//) +Scalos Empty_Trashcan +; +; +MSGID_OKBUTTON (//) +Ok +; +; +MSGID_OKBUTTON_SHORT (/1/1) +O +; +; +MSGID_SHORTHELP_OKBUTTON (//) +Start emptying trashcan.\n\ +All contents is deleted irrevocably! +; +; +MSGID_CANCELBUTTON (//) +Cancel +; +; +MSGID_CANCELBUTTON_SHORT (/1/1) +c +; +; +MSGID_SHORTHELP_CANCELBUTTON (//) +Leave trashcan untouched and quit +; +; +MSGID_ABORTBUTTON (//) +Abort +; +; +MSGID_ABORTBUTTON_SHORT (/1/1) +a +; +; +MSGID_SHORTHELP_ABORTBUTTON (//) +Immediately abort emptying\n\ +of trashcan and quit. +; +; +MSGID_CREATE_APPLICATION_FAILED (//) +Failed to create Application.\n +; +; +MSGID_CREATE_MAINWINDOW_FAILED (//) +Failed to open main window !\n +; +; +MSGID_OPEN_LIBRARY_FAILED (//) +Failed to open \"%s\" !\n +; +;;----------------------------------------------------------- +; +MSGID_MENU_PROJECT (2000//) +Project +; +; +MSGID_MENU_PROJECT_ABOUT (//) +About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI (//) +About MUI... +; +; +MSGID_MENU_PROJECT_QUIT (//) +Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT (//) +Q +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK (3000//) +OK +; +; +MSGID_ABOUTREQFORMAT (//) +\33c\033bScalos Empty_Trashcan.module V%ld.%ld\033n\n\ +%s\n\ +© 2005%s The Scalos Team +; +;----------------------------------------------------------- +; +MSGID_WARNING_EMPTY_TRASHCAN (//4000) +Warning! You cannot get back what you delete!\n\ +OK to empty the trashcan? +; +; +MSGID_GADGETS_EMPTY_ABORT (//) +Empty|Abort +; +; +MSGID_GADGETTEXT_OK (//) +OK +; +; +MSGID_GADGETTEXT_CANCEL (//) +Cancel +; +; +MSGID_EMPTY_TRASHCAN (//) +Empty Trashcan +; +; +MSGID_GADGETS_DELETE_ABORT (//) +Delete|Abort +; +; +MSGID_EMPTYING_TRASHCAN (//) +Emptying Trashcan... +; +; +MSGID_PATH (//) +Path +; +; +MSGID_GADGET_ABORT (//) +Abort +; +; +MSGID_BUILD_FILELIST (//) +Building Filelist... +; +; +MSGID_OUT_OF_MEMORY (//) +Not Enough Memory +; +; +MSGID_ERROR (//) +Error +; +; +MSGID_FAILED_TO_DELETE (//) +%s\n\ +couldn't be deleted:\n\ +%s +; +; +MSGID_GADGETS_SKIP_ABORT (//) +Skip it|Abort +; +; +MSGID_DELETE_PROTECTED (//) +%s is protected against deletion.\n\ +Delete anyway? +; +; +MSGID_GADGETS_DELETE_SKIP (//) +Delete|Skip it +; +; +MSGID_GADGETS_DELETE_DELETEALL_PROTECT_SKIP (//) +Delete|DeleteAllProtect|Skip +; +; +MSGID_TEXT_CURRENTITEM (//) +Currently removing: +; +; +MSGID_TEXT_CURRENTITEM_SHORTHELP (//) +This is the name if the item currently\n\ +being deleted from trashcan. +; +; +MSGID_GLOBAL_TRASHCAN (//) +\nThis global trashcan will be emptied, too: +; +;----------------------------------------------------------- diff --git a/scalos/Modules/Empty_Trashcan.MUI/Empty_Trashcan.h b/scalos/Modules/Empty_Trashcan.MUI/Empty_Trashcan.h new file mode 100644 index 000000000..ec84964c2 --- /dev/null +++ b/scalos/Modules/Empty_Trashcan.MUI/Empty_Trashcan.h @@ -0,0 +1,26 @@ +// debug.h +// $Date$ +// $Revision$ + +#ifndef DEBUG_H +#define DEBUG_H + +//---------------------------------------------------------------------------- + +#define d1(x) ; +#define d2(x) x; + +// from debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +//---------------------------------------------------------------------------- + +struct Empty_Trashcan_LocaleInfo +{ + APTR li_LocaleBase; + APTR li_Catalog; + struct LocaleIFace *li_ILocale; +}; + +#endif /* DEBUG_H */ diff --git a/scalos/Modules/Empty_Trashcan.MUI/config.mk b/scalos/Modules/Empty_Trashcan.MUI/config.mk new file mode 100755 index 000000000..2448ae6bf --- /dev/null +++ b/scalos/Modules/Empty_Trashcan.MUI/config.mk @@ -0,0 +1,58 @@ +# $Date: 2011-07-10 21:18:38 +0200 (So, 10. Jul 2011) $ +# $Revision: 766 $ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +SCALOS_LOCALE = $(OBJDIR)/Empty_Trashcan_Locale.h + +CFLAGS += -D SCALOSLOCALE=$(SCALOS_LOCALE) + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +INCLUDES += # + +LFLAGS += # + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +INCLUDES += # + +LFLAGS += + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +INCLUDES += # + +LFLAGS += -lmui + +else + +############################################################################### +# AmigaOS + +INCLUDES += # + +LFLAGS += # + +endif +endif +endif diff --git a/scalos/Modules/Empty_Trashcan.MUI/makefile b/scalos/Modules/Empty_Trashcan.MUI/makefile new file mode 100755 index 000000000..88b3b2341 --- /dev/null +++ b/scalos/Modules/Empty_Trashcan.MUI/makefile @@ -0,0 +1,124 @@ +# Makefile for Empty_Trashcan.module (MUI) +# using GNU make and SAS/C +# $Date$ +# $Revision$ + +##################################################################### + +TOPLEVEL = / +SUBDIRMAKE = $(MAKE) -s -C +CHEADERS = +CC = sc +CFLAGS = optimize nostackcheck nochkabort debug=s \ + idlen=128 strmer nover streq data=far \ + define SCALOSLOCALE=$(SCALOS_LOCALE) \ + ignore=217 idir=sc:include/ \ + idir=include: idir=//include +AS = phxass +AFLAGS = QUIET m=68020 linedebug opt=NRQB i=include: +LD = slink +LNFLAGS = quiet batch noicons stripdebug +LNDBFLAGS = quiet batch noicons addsym +LIBS = LIB:sc.lib LIB:debug.lib LIB:amiga.lib +CATCOMP = catcomp +FLEXCAT = FlexCat +CSTARTUP = LIB:c.o +OBJDIR = .sasobj + +SCALOS_LOCALE = $(OBJDIR)/Empty_Trashcan_Locale.h + +##################################################################### + +.SUFFIXES: .asm + +##################################################################### + +NAME = .bin_os3/Empty_Trashcan.module +DBGNAME = $(NAME).debug +CATCOMPH = $(SCALOS_LOCALE) +CAT_FILE = Scalos/Empty_Trashcan.catalog +DESTCAT = Locale:Catalogs +ALLCATS = Catalogs/deutsch/$(CAT_FILE) \ + Catalogs/français/$(CAT_FILE) + +##################################################################### + +all: $(NAME) \ + $(DBGNAME) \ + allcatalogs +# install +# clean + +##################################################################### + +# make all Scalos .catalogs +allcatalogs: + @$(SUBDIRMAKE) Catalogs/deutsch/Scalos + @$(SUBDIRMAKE) Catalogs/français/Scalos + +##################################################################### + +CSRCS = Empty_Trashcan.c + +##################################################################### + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +##################################################################### + +XOBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(CSRCS:%.c=$(OBJDIR)/%.o) +OBJS = $(XOBJS) + +##################################################################### + +$(NAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNFLAGS) + +$(DBGNAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNDBFLAGS) + +##################################################################### + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $< objectname $@ + +$(OBJDIR)/%.o : %.asm + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +##################################################################### + +$(CATCOMPH) : Empty_Trashcan.cd + @printf '\033[32mMake CatComp header: \033[31m\033[1m$(CATCOMPH) \033[32mfrom \033[31m$<\033[0m\n' + @$(FLEXCAT) $< $@=$(TOPLEVEL)/CatComp_h.sd + +$(OBJDIR)/Empty_Trashcan.o : Empty_Trashcan.c Empty_Trashcan.h $(CATCOMPH) + +##################################################################### + +$(NAME) $(DBGNAME) : $(OBJS) + +##################################################################### + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(NAME) \033[0mto \033[31m\033[1mScalos:modules/ \033[0m\n' + @copy $(NAME) Scalos:modules/ + @avail flush + @printf '\033[32mInstall: \033[31m\033[1m$(CAT_FILE)\033[0m\n' + -@copy "catalogs/deutsch/$(CAT_FILE)" "$(DESTCAT)/Deutsch/Scalos/" clone + -@copy "catalogs/français/$(CAT_FILE)" "$(DESTCAT)/français/Scalos/" clone + +##################################################################### + +# A little something to clean it all up +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + @delete $(XOBJS) $(NAME) $(DBGNAME) \ + $(CATCOMPH) + @printf '\033[0m' + +##################################################################### diff --git a/scalos/Modules/Empty_Trashcan.MUI/makefile-new b/scalos/Modules/Empty_Trashcan.MUI/makefile-new new file mode 100755 index 000000000..65f22f081 --- /dev/null +++ b/scalos/Modules/Empty_Trashcan.MUI/makefile-new @@ -0,0 +1,96 @@ +# $Date: 2011-07-12 02:18:25 +0200 (Di, 12. Jul 2011) $ +# $Revision: 773 $ +############################################################################## + +TOPLEVEL = $(shell pwd)/../.. + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + SDPATH=/ +else + SDPATH=../.. +endif + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(OBJDIR)/Empty_Trashcan.o \ + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Subdirs +# + +SUBDIRS = $(filter-out Catalogs/sample/Scalos, $(wildcard Catalogs/*/Scalos)) + +############################################################################## +# +# Targets +# + +NAME = Empty_Trashcan.module +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) \ + all_subdirs + +############################################################################## + +$(OBJDIR)/%.o: $(TOOLTYPE_DIR)/%.c + @$(run-cc) + +$(OBJDIR)/%.o: $(ICONOBJMCC_DIR)/%.c + @$(run-cc) + +Empty_Trashcan.c : $(OBJDIR)/Empty_Trashcan_Locale.h + +$(OBJDIR)/Empty_Trashcan_Locale.h : Empty_Trashcan.cd + @$(ECHO) "FlexCat $@" + $(FLEXCAT) $< $@=$(SDPATH)/CatComp_h.sd + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + @$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) +ifneq ($(MACHINE), ppc-amigaos) + -@chmod u+x $@ +endif + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) Scalos:modules/ clone + +install: install_subdirs + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* \ + $(OBJDIR)/Empty_Trashcan_Locale.h + +clean: clean_subdirs + +############################################################################## + diff --git a/scalos/Modules/Exchange.MUI/Catalogs/deutsch/Scalos/Exchange.ct b/scalos/Modules/Exchange.MUI/Catalogs/deutsch/Scalos/Exchange.ct new file mode 100644 index 000000000..81c5af229 --- /dev/null +++ b/scalos/Modules/Exchange.MUI/Catalogs/deutsch/Scalos/Exchange.ct @@ -0,0 +1,175 @@ +; Exchange.ct +; $Date$ +; $Revision$ +## version $VER: Exchange.catalog 40.1 (23 Dec 2008 18:50:08) +## codeset 0 +## language deutsch +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Exchange +;Scalos Exchange +; +;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Projekt +;Project +; +; +MSGID_MENU_PROJECT_ABOUT +Über... +;About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Über MUI... +;About MUI... +; +; +MSGID_MENU_PROJECT_QUIT +Beenden +;Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +;Q +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +_OK +;_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Exchange.module V%ld.%ld\033n\n\ +%s\n\ +© 2008%s Das Scalos Team +;\33c\033bScalos Exchange.module V%ld.%ld\033n\n\ +;%s\n\ +;© 2008%s The Scalos Team +; +;----------------------------------------------------------- +; +MSGID_BUTTON_SHOW +Oberfläche zeigen +;Show +; +; +MSGID_BUTTON_SHOW_KEY +Z +;S +; +; +MSGID_BUTTON_SHOW_SHORTHELP +Öffnet das Fenster des\n\ +ausgewählten Commodities. +;Show Commodity window. +; +; +MSGID_BUTTON_HIDE +Oberfläche verbergen +;Hide +; +; +MSGID_BUTTON_HIDE_KEY +V +;H +; +; +MSGID_BUTTON_HIDE_SHORTHELP +Schließt das Fenster des\n\ +ausgewählten Commodities. +;Hide Commodity window. +; +; +MSGID_BUTTON_REMOVE +Entfernen +;Remove +; +; +MSGID_BUTTON_REMOVE_KEY +E +;R +; +; +MSGID_BUTTON_REMOVE_SHORTHELP +Versucht das ausgewählte Commodity zu beenden. +;Remove selected Commodity. +; +; +MSGID_CXLIST_NAME +Name +;Name +; +; +MSGID_CXLIST_STATE +Zustand +;State +; +; +MSGID_CXLIST_TITLE +Titel +;Title +; +; +MSGID_CXLIST_PRIORITY +Priorität +;Priority +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Exchange.module kann nicht gestartet werden +;Exchange Module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Wiederholen|Beenden +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\ +Die Klasse ist nicht installiert. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Sie haben momentan Version v%lu.%lu installiert und\n\ +sollten die Klasse daher aktualisieren! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Version %lu.%lu wird momentan von einer anderen Anwendung\n\ +verwendet. Wenn sie die benötigte Version installiert haben,\n\ +schließen sie alle MUI Programme und probieren es erneut. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_CYCLE_ACTIVE_ACTIVE +Aktiv +;Active +; +; +MSGID_CYCLE_ACTIVE_INACTIVE +Inaktiv +;Inactive +; +;----------------------------------------------------------- diff --git a/scalos/Modules/Exchange.MUI/Catalogs/deutsch/Scalos/config.mk b/scalos/Modules/Exchange.MUI/Catalogs/deutsch/Scalos/config.mk new file mode 100755 index 000000000..8631b0623 --- /dev/null +++ b/scalos/Modules/Exchange.MUI/Catalogs/deutsch/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = deutsch + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = german + +else + +############################################################################### +# AmigaOS and AROS + +LANG = deutsch + +endif +endif diff --git a/scalos/Modules/Exchange.MUI/Catalogs/deutsch/Scalos/makefile b/scalos/Modules/Exchange.MUI/Catalogs/deutsch/Scalos/makefile new file mode 100644 index 000000000..923637190 --- /dev/null +++ b/scalos/Modules/Exchange.MUI/Catalogs/deutsch/Scalos/makefile @@ -0,0 +1,13 @@ +# makefile for Exchange.module (translated Texts : deutsch) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mdeutsch\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +Exchange.catalog : Exchange.ct ../../../Exchange.cd + +All: Exchange.catalog diff --git a/scalos/Modules/Exchange.MUI/Catalogs/deutsch/Scalos/makefile-new b/scalos/Modules/Exchange.MUI/Catalogs/deutsch/Scalos/makefile-new new file mode 100644 index 000000000..473cffecd --- /dev/null +++ b/scalos/Modules/Exchange.MUI/Catalogs/deutsch/Scalos/makefile-new @@ -0,0 +1,30 @@ +# makefile for Exchange.module (translated Texts : deutsch) +# $Date: 2011-07-24 10:11:00 +0200 (So, 24. Jul 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = Exchange + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git "a/scalos/Modules/Exchange.MUI/Catalogs/fran\303\247ais/Scalos/Exchange.ct" "b/scalos/Modules/Exchange.MUI/Catalogs/fran\303\247ais/Scalos/Exchange.ct" new file mode 100755 index 000000000..fa6c1bd82 --- /dev/null +++ "b/scalos/Modules/Exchange.MUI/Catalogs/fran\303\247ais/Scalos/Exchange.ct" @@ -0,0 +1,153 @@ +; Exchange.ct +; $Date$ +; $Revision$ +## version $VER: Exchange.catalog 40.1 (23 Dec 2008 18:50:08) +## codeset 0 +## language français +; +;#arrayopts static __far +; +MSGID_TITLENAME +Scalos Exchange +;Scalos Exchange +; +;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Projet +;Project +; +MSGID_MENU_PROJECT_ABOUT +A propos... +;About... +; +MSGID_MENU_PROJECT_ABOUTMUI +A propos de MUI... +;About MUI... +; +MSGID_MENU_PROJECT_QUIT +Quitter +;Quit +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +;Q +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +_OKay +;_OK +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Exchange.module V%ld.%ld\033n\n\ +%s\n\ +© 2008%s The Scalos Team +;\33c\033bScalos Exchange.module V%ld.%ld\033n\n\ +;%s\n\ +;© 2008%s The Scalos Team +; +;----------------------------------------------------------- +; +MSGID_BUTTON_SHOW +Voir +;Show +; +MSGID_BUTTON_SHOW_KEY +S +;S +; +MSGID_BUTTON_SHOW_SHORTHELP +Voir la fenêtre des commoditées. +;Show Commodity window. +; +MSGID_BUTTON_HIDE +Cacher +;Hide +; +MSGID_BUTTON_HIDE_KEY +H +;H +; +MSGID_BUTTON_HIDE_SHORTHELP +Cacher la fenêtre des commoditées. +;Hide Commodity window. +; +MSGID_BUTTON_REMOVE +Supprimer +;Remove +; +MSGID_BUTTON_REMOVE_KEY +R +;R +; +MSGID_BUTTON_REMOVE_SHORTHELP +Supprimer la commodité sélectionnée. +;Remove selected Commodity. +; +MSGID_CXLIST_NAME +Nom +;Name +; +MSGID_CXLIST_STATE +Etat +;State +; +MSGID_CXLIST_TITLE +Titre +;Title +; +MSGID_CXLIST_PRIORITY +Priorité +;Priority +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Le démarrage du module de recherche a échoué. +;Exchange Module startup failed +; +MSGID_STARTUP_RETRY_QUIT_GAD +Essayer de nouveau | Quitter +;Try again|Quit +; +MSGID_STARTUP_MCC_NOT_FOUND +Ouverture impossible de la classe MUI '%s' V%lu.%lu.\n\ +La classe n'est pas installée. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +MSGID_STARTUP_OLD_MCC +Ouverture impossible de la classe MUI '%s' V%lu.%lu.\n\ +\n\ +Actuellement installée : V%lu.%lu, \n\ +installez une version supérieure S.V.P ! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +MSGID_STARTUP_MCC_IN_USE +Ouverture impossible de la classe MUI '%s' V%lu.%lu.\n\ +%lu.%lu est actuellement utilisé par d'autres applications.\n\ +\n\ +Une fois que vous vaez installé la version requise,\n\ +fermez tous les programmes MUI, soyez sure que l'ancienne classe\n\ +ne soit plus en mémoire et essayez de nouveau. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_CYCLE_ACTIVE_ACTIVE +Actif +;Active +; +MSGID_CYCLE_ACTIVE_INACTIVE +Inactif +;Inactive +; +;----------------------------------------------------------- diff --git "a/scalos/Modules/Exchange.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" "b/scalos/Modules/Exchange.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" new file mode 100755 index 000000000..8b7056423 --- /dev/null +++ "b/scalos/Modules/Exchange.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" @@ -0,0 +1,40 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = français + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = french + +else + +############################################################################### +# AmigaOS and AROS + +LANG = français + +endif +endif diff --git "a/scalos/Modules/Exchange.MUI/Catalogs/fran\303\247ais/Scalos/makefile" "b/scalos/Modules/Exchange.MUI/Catalogs/fran\303\247ais/Scalos/makefile" new file mode 100644 index 000000000..eee568271 --- /dev/null +++ "b/scalos/Modules/Exchange.MUI/Catalogs/fran\303\247ais/Scalos/makefile" @@ -0,0 +1,13 @@ +# makefile for Exchange.module (translated Texts : français) +# $Date: 17 Aug 2004 20:12:47 + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mfrançais\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +Exchange.catalog : Exchange.ct ../../../Exchange.cd + +All: Exchange.catalog diff --git "a/scalos/Modules/Exchange.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" "b/scalos/Modules/Exchange.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" new file mode 100644 index 000000000..c048974c1 --- /dev/null +++ "b/scalos/Modules/Exchange.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" @@ -0,0 +1,30 @@ +# makefile for Exchange.module (translated Texts : français) +# $Date: 2011-07-24 10:11:00 +0200 (So, 24. Jul 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = Exchange + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Modules/Exchange.MUI/Catalogs/sample/Scalos/Exchange.ct b/scalos/Modules/Exchange.MUI/Catalogs/sample/Scalos/Exchange.ct new file mode 100644 index 000000000..febe104fb --- /dev/null +++ b/scalos/Modules/Exchange.MUI/Catalogs/sample/Scalos/Exchange.ct @@ -0,0 +1,174 @@ +; Exchange.ct +; $Date$ +; $Revision$ +## version $VER: Exchange.catalog 40.1 (23 Dec 2008 18:50:08) +## codeset 0s +## language xxxxxx +; +;#arrayopts static __far +; +;+++translateme+++ +SGID_TITLENAME +Scalos Exchange +;Scalos Exchange +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_MENU_PROJECT +Project +;Project +; +;+++translateme+++ +MSGID_MENU_PROJECT_ABOUT +About... +;About... +; +;+++translateme+++ +MSGID_MENU_PROJECT_ABOUTMUI +About MUI... +;About MUI... +; +;+++translateme+++ +MSGID_MENU_PROJECT_QUIT +Quit +;Quit +; +;+++translateme+++ +MSGID_MENU_PROJECT_QUIT_SHORT +Q +;Q +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_ABOUTREQOK +_OK +;_OK +; +;+++translateme+++ +MSGID_ABOUTREQFORMAT +\33c\033bScalos Exchange.module V%ld.%ld\033n\n\ +%s\n\ +© 2008%s The Scalos Team +;\33c\033bScalos Exchange.module V%ld.%ld\033n\n\ +;%s\n\ +;© 2008%s The Scalos Team +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_BUTTON_SHOW +Show +;Show +; +;+++translateme+++ +MSGID_BUTTON_SHOW_KEY +S +;S +; +;+++translateme+++ +MSGID_BUTTON_SHOW_SHORTHELP +Show Commodity window. +;Show Commodity window. +; +;+++translateme+++ +MSGID_BUTTON_HIDE +Hide +;Hide +; +;+++translateme+++ +MSGID_BUTTON_HIDE_KEY +H +;H +; +;+++translateme+++ +MSGID_BUTTON_HIDE_SHORTHELP +Hide Commodity window. +;Hide Commodity window. +; +;+++translateme+++ +MSGID_BUTTON_REMOVE +Remove +;Remove +; +;+++translateme+++ +MSGID_BUTTON_REMOVE_KEY +R +;R +; +;+++translateme+++ +MSGID_BUTTON_REMOVE_SHORTHELP +Remove selected Commodity. +;Remove selected Commodity. +; +;+++translateme+++ +MSGID_CXLIST_NAME +Name +;Name +; +;+++translateme+++ +MSGID_CXLIST_STATE +State +;State +; +;+++translateme+++ +MSGID_CXLIST_TITLE +Title +;Title +; +;+++translateme+++ +MSGID_CXLIST_PRIORITY +Priority +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_STARTUP_FAILURE +Exchange Module startup failed +;Exchange Module startup failed +; +;+++translateme+++ +MSGID_STARTUP_RETRY_QUIT_GAD +Try again|Quit +;Try again|Quit +; +;+++translateme+++ +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +;+++translateme+++ +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +;+++translateme+++ +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_CYCLE_ACTIVE_ACTIVE +Active +;Active +; +;+++translateme+++ +MSGID_CYCLE_ACTIVE_INACTIVE +Inactive +;Inactive +; +;----------------------------------------------------------- diff --git a/scalos/Modules/Exchange.MUI/Exchange.c b/scalos/Modules/Exchange.MUI/Exchange.c new file mode 100644 index 000000000..9910fb301 --- /dev/null +++ b/scalos/Modules/Exchange.MUI/Exchange.c @@ -0,0 +1,1043 @@ +// Exchange.c +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // MAKE_ID() +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include // +jmc+ + +#include "Exchange.h" +#include "cx_private.h" +#include "debug.h" + +#define Exchange_NUMBERS +#define Exchange_ARRAY +#define Exchange_CODE +#include STR(SCALOSLOCALE) + +//---------------------------------------------------------------------------- + +#if !defined(__amigaos4__) && !defined(__AROS__) +#include + +long _stack = 16384; // minimum stack size, used by SAS/C startup code +#endif + +//---------------------------------------------------------------------------- + +// local data structures + +#define KeyButtonHelp(name,key,HelpText)\ + TextObject,\ + ButtonFrame,\ + MUIA_CycleChain, TRUE, \ + MUIA_Font, MUIV_Font_Button,\ + MUIA_Text_Contents, name,\ + MUIA_Text_PreParse, "\33c",\ + MUIA_Text_HiChar , key,\ + MUIA_ControlChar , key,\ + MUIA_InputMode , MUIV_InputMode_RelVerify,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShortHelp, HelpText,\ + End + +struct CxListEntry +{ + STRPTR xle_Name; + STRPTR xle_Title; + STRPTR xle_Description; + struct Task *xle_Task; + APTR xle_Addr; + LONG xle_Pri; + UWORD xle_Flags; + char xle_PriString[10]; +}; + +//---------------------------------------------------------------------------- + +// local functions + +static void init(void); +static void fail(APTR APP_Main, CONST_STRPTR str); +static BOOL OpenLibraries(void); +static void CloseLibraries(void); +static SAVEDS(APTR) INTERRUPT OpenAboutMUIFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT OpenAboutFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT CxListConstructHookFunc(struct Hook *hook, APTR unused, struct NList_ConstructMessage *nlcm); +static SAVEDS(void) INTERRUPT CxListDestructHookFunc(struct Hook *hook, APTR unused, struct NList_DestructMessage *nldm); +static SAVEDS(ULONG) INTERRUPT CxListDisplayHookFunc(struct Hook *hook, APTR unused, struct NList_DisplayMessage *nldm); +static SAVEDS(LONG) INTERRUPT CxListCompareHookFunc(struct Hook *hook, Object *obj, struct NList_CompareMessage *ncm); +static SAVEDS(void) INTERRUPT RescanHookFunc(struct Hook *hook, Object *obj, Msg *msg); +static SAVEDS(void) INTERRUPT SelectCxHookFunc(struct Hook *hook, Object *obj, Msg *msg); +static SAVEDS(void) INTERRUPT CxCommandHookFunc(struct Hook *hook, Object *obj, LONG *cmd); +static SAVEDS(void) INTERRUPT BrokerHookFunc(struct Hook *hook, Object *obj, CxMsg *msg); + +static STRPTR GetLocString(ULONG MsgId); +static void TranslateStringArray(STRPTR *stringArray); +#if 0 +static void TranslateNewMenu(struct NewMenu *nm); +#endif + +BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev); + +//---------------------------------------------------------------------------- + +static struct Hook AboutHook = {{ NULL, NULL }, HOOKFUNC_DEF(OpenAboutFunc), NULL }; +static struct Hook AboutMUIHook = {{ NULL, NULL }, HOOKFUNC_DEF(OpenAboutMUIFunc), NULL }; + +static struct Hook CxListConstructHook = {{ NULL, NULL }, HOOKFUNC_DEF(CxListConstructHookFunc), NULL }; +static struct Hook CxListDestructHook = {{ NULL, NULL }, HOOKFUNC_DEF(CxListDestructHookFunc), NULL }; +static struct Hook CxListDisplayHook = {{ NULL, NULL }, HOOKFUNC_DEF(CxListDisplayHookFunc), NULL }; +static struct Hook CxListCompareHook = {{ NULL, NULL }, HOOKFUNC_DEF(CxListCompareHookFunc), NULL }; +static struct Hook RescanHook = {{ NULL, NULL }, HOOKFUNC_DEF(RescanHookFunc), NULL }; +static struct Hook SelectCxHook = {{ NULL, NULL }, HOOKFUNC_DEF(SelectCxHookFunc), NULL }; +static struct Hook CxCommandHook = {{ NULL, NULL }, HOOKFUNC_DEF(CxCommandHookFunc), NULL }; +static struct Hook BrokerHook = {{ NULL, NULL }, HOOKFUNC_DEF(BrokerHookFunc), NULL }; + +//---------------------------------------------------------------------------- + +static STRPTR CycleActiveEntries[] = + { + (STRPTR) MSGID_CYCLE_ACTIVE_ACTIVE, + (STRPTR) MSGID_CYCLE_ACTIVE_INACTIVE, + NULL + }; + +//---------------------------------------------------------------------------- + +// local data items + +static struct List BrokerCopyList; + +struct IntuitionBase *IntuitionBase = NULL; +struct Library *MUIMasterBase = NULL; +struct Library *CxBase = NULL; +T_LOCALEBASE LocaleBase = NULL; + +#ifdef __amigaos4__ +struct IntuitionIFace *IIntuition = NULL; +struct MUIMasterIFace *IMUIMaster = NULL; +struct CxIFace *ICx = NULL; +struct LocaleIFace *ILocale = NULL; +#endif + +static struct Catalog *ExchangeCatalog; + +static Object *APP_Main; +static Object *WIN_Main; +static Object *WIN_AboutMUI; +static Object *ButtonShow, *ButtonHide, *ButtonRemove; +static Object *CycleActive; +static Object *NListCxList; +static Object *FloattextDescription; +static Object *MenuAbout, *MenuAboutMUI, *MenuQuit; + +//---------------------------------------------------------------------------- + +int main(int argc, char *argv[]) +{ + LONG win_opened = 0; + + init(); + + if (!CheckMCCVersion(MUIC_NListview, 19, 66) ) + { + d1(KPrintF(__FILE__ "/%s/%ld: CheckMCCVersion failed\n", __FUNC__, __LINE__)); + return 10; + } + + APP_Main = ApplicationObject, + MUIA_Application_Title, GetLocString(MSGID_TITLENAME), + MUIA_Application_Version, "$VER: Scalos Exchange.module V" VERS_MAJOR "." VERS_MINOR " (" __DATE__ ") " COMPILER_STRING, + MUIA_Application_Copyright, "© The Scalos Team, 2008" CURRENTYEAR, + MUIA_Application_Author, "The Scalos Team", + MUIA_Application_Description, "Scalos Exchange module", + MUIA_Application_Base, "SCALOS_EXCHANGE_MODULE", + MUIA_Application_BrokerHook, &BrokerHook, + + SubWindow, WIN_Main = WindowObject, + MUIA_Window_Title, GetLocString(MSGID_TITLENAME), + MUIA_Window_ID, MAKE_ID('M','A','I','N'), + MUIA_Window_AppWindow, TRUE, + + WindowContents, VGroup, + Child, NListviewObject, + MUIA_Weight, 200, + MUIA_CycleChain, TRUE, + MUIA_NListview_NList, NListCxList = NListObject, + MUIA_NList_Title, TRUE, + MUIA_NList_TitleSeparator, TRUE, + MUIA_NList_TitleMark, MUIV_NList_TitleMark_Down | 0, + MUIA_NList_SortType, 0, + MUIA_NList_Format, "BAR,BAR,BAR,BAR", + MUIA_NList_DisplayHook2, &CxListDisplayHook, + MUIA_NList_ConstructHook2, &CxListConstructHook, + MUIA_NList_DestructHook2, &CxListDestructHook, + MUIA_NList_CompareHook2, &CxListCompareHook, + End, //NListObject + End, //NListviewObject + + Child, VGroup, + Child, FloattextDescription = FloattextObject, + TextFrame, + MUIA_VertWeight, 0, + End, //FloattextObject + + Child, ColGroup(2), + Child, ButtonShow = KeyButtonHelp(GetLocString(MSGID_BUTTON_SHOW), + *GetLocString(MSGID_BUTTON_SHOW_KEY), + GetLocString(MSGID_BUTTON_SHOW_SHORTHELP)), + Child, ButtonHide = KeyButtonHelp(GetLocString(MSGID_BUTTON_HIDE), + *GetLocString(MSGID_BUTTON_HIDE_KEY), + GetLocString(MSGID_BUTTON_HIDE_SHORTHELP)), + + Child, CycleActive = CycleObject, + MUIA_CycleChain, TRUE, + MUIA_Cycle_Entries, CycleActiveEntries, + End, //CycleObject + + Child, ButtonRemove = KeyButtonHelp(GetLocString(MSGID_BUTTON_REMOVE), + *GetLocString(MSGID_BUTTON_REMOVE_KEY), + GetLocString(MSGID_BUTTON_REMOVE_SHORTHELP)), + End, //ColGroup + End, //VGroup + End, //VGroup + End, //WindowObject + + MUIA_Application_Menustrip, MenustripObject, + Child, MenuObjectT(GetLocString(MSGID_MENU_PROJECT)), + + Child, MenuAbout = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUT), + End, + Child, MenuAboutMUI = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUTMUI), + End, + Child, MenuitemObject, + MUIA_Menuitem_Title, -1, + End, + Child, MenuQuit = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_QUIT), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_PROJECT_QUIT_SHORT), + End, + + End, //MenuObjectT + + End, //MenuStripObject + + End; //ApplicationObject + + if (NULL == APP_Main) + { + fail(APP_Main, "Failed to create Application."); + } + + DoMethod(APP_Main, MUIM_Application_Load, MUIV_Application_Load_ENV); + + d1(KPrintF("%s/%s/%ld: before MUIM_CallHook APP_Main=%08lx\n", __FILE__, __FUNC__, __LINE__, APP_Main)); + + DoMethod(APP_Main, MUIM_CallHook, &RescanHook, 0); + d1(KPrintF("%s/%s/%ld: after MUIM_CallHook APP_Main=%08lx\n", __FILE__, __FUNC__, __LINE__, APP_Main)); + + //--------------------------------------------------------------------------// + + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + WIN_Main, 3, MUIM_Set, MUIA_Window_Open, FALSE); + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + // Call hook whenever an entry is selected + DoMethod(NListCxList, MUIM_Notify, MUIA_NList_SelectChange, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &SelectCxHook); + + // Show Cx Application Window whenever "Show" button is pressed + DoMethod(ButtonShow, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 3, MUIM_CallHook, &CxCommandHook, CXCMD_APPEAR); + + // Show Cx Application Window whenever list entry is double-clicked + DoMethod(NListCxList, MUIM_Notify, MUIA_Listview_DoubleClick, TRUE, + APP_Main, 3, MUIM_CallHook, &CxCommandHook, CXCMD_APPEAR); + + // Hide Cx Application Window whenever "Hide" button is pressed + DoMethod(ButtonHide, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 3, MUIM_CallHook, &CxCommandHook, CXCMD_DISAPPEAR); + + // Activate Cx Application when cycle "active" is selected + DoMethod(CycleActive, MUIM_Notify, MUIA_Cycle_Active, 0, + APP_Main, 3, MUIM_CallHook, &CxCommandHook, CXCMD_ENABLE); + + // Deactivate Cx Application when cycle "inactive" is selected + DoMethod(CycleActive, MUIM_Notify, MUIA_Cycle_Active, 1, + APP_Main, 3, MUIM_CallHook, &CxCommandHook, CXCMD_DISABLE); + + // Remove Cx Application whenever "Remove" button is pressed + DoMethod(ButtonRemove, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 3, MUIM_CallHook, &CxCommandHook, CXCMD_KILL); + + // setup sorting hooks for Cx list + DoMethod(NListCxList, MUIM_Notify, MUIA_NList_TitleClick, MUIV_EveryTime, + NListCxList, 4, MUIM_NList_Sort3, MUIV_TriggerValue, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_Both); + DoMethod(NListCxList, MUIM_Notify, MUIA_NList_TitleClick2, MUIV_EveryTime, + NListCxList, 4, MUIM_NList_Sort3, MUIV_TriggerValue, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_2); + DoMethod(NListCxList, MUIM_Notify, MUIA_NList_SortType, MUIV_EveryTime, + NListCxList, 3, MUIM_Set, MUIA_NList_TitleMark, MUIV_TriggerValue); + DoMethod(NListCxList, MUIM_Notify, MUIA_NList_SortType2, MUIV_EveryTime, + NListCxList, 3, MUIM_Set, MUIA_NList_TitleMark2, MUIV_TriggerValue); + + DoMethod(MenuAbout, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &AboutHook); + DoMethod(MenuAboutMUI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &AboutMUIHook); + DoMethod(MenuQuit, MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + set(WIN_Main, MUIA_Window_Open, TRUE); + get(WIN_Main, MUIA_Window_Open, &win_opened); + + if (win_opened) + { + ULONG sigs = 0; + BOOL Run = TRUE; + + while (Run) + { + ULONG Action = DoMethod(APP_Main, MUIM_Application_NewInput, &sigs); + + switch (Action) + { + case MUIV_Application_ReturnID_Quit: + Run = FALSE; + break; + default: + break; + } + + if (Run && sigs) + { + sigs = Wait(sigs | SIGBREAKF_CTRL_C); + + if (sigs & SIGBREAKF_CTRL_C) + { + Run = FALSE; + } + } + } + } + else + { + printf("failed to open main window !\n"); + } + + set(WIN_Main, MUIA_Window_Open, FALSE); + + DoMethod(APP_Main, MUIM_Application_Save, MUIV_Application_Save_ENV); + DoMethod(APP_Main, MUIM_Application_Save, MUIV_Application_Save_ENVARC); + + fail(APP_Main, NULL); + + return 0; +} + +//---------------------------------------------------------------------------- + +static VOID fail(APTR APP_Main, CONST_STRPTR str) +{ + CxFreeBrokerList(&BrokerCopyList); + + if (APP_Main) + { + MUI_DisposeObject(APP_Main); + } + if (ExchangeCatalog) + { + CloseCatalog(ExchangeCatalog); + ExchangeCatalog = NULL; + } + + CloseLibraries(); + + if (str) + { + puts(str); + exit(20); + } + + exit(0); +} + +//---------------------------------------------------------------------------- + +static void init(void) +{ + NewList(&BrokerCopyList); + + if (!OpenLibraries()) + fail(NULL, "Failed to open "MUIMASTER_NAME"."); + + if (LocaleBase) + ExchangeCatalog = OpenCatalogA(NULL, "Scalos/Exchange.catalog", NULL); + +// TranslateNewMenu(NewContextMenuHistoryPopup); + TranslateStringArray(CycleActiveEntries); +} + +//---------------------------------------------------------------------------- + +static BOOL OpenLibraries(void) +{ + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + if (NULL == IntuitionBase) + return FALSE; +#ifdef __amigaos4__ + else + { + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + return FALSE; + } +#endif + + MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN-1); + if (NULL == MUIMasterBase) + return FALSE; +#ifdef __amigaos4__ + else + { + IMUIMaster = (struct MUIMasterIFace *)GetInterface((struct Library *)MUIMasterBase, "main", 1, NULL); + if (NULL == IMUIMaster) + return FALSE; + } +#endif + + CxBase = OpenLibrary("commodities.library", 40); + if (NULL == CxBase) + return FALSE; +#ifdef __amigaos4__ + else + { + ICx = (struct CxIFace *)GetInterface((struct Library *)CxBase, "main", 1, NULL); + if (NULL == ICx) + return FALSE; + } +#endif + + LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 39); +#ifdef __amigaos4__ + if (NULL != LocaleBase) + { + ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL); + if (NULL == ILocale) + return FALSE; + } +#endif + + return TRUE; +} + +//---------------------------------------------------------------------------- + +static void CloseLibraries(void) +{ + if (LocaleBase) + { + if (ExchangeCatalog) + { + CloseCatalog(ExchangeCatalog); + ExchangeCatalog = NULL; + } +#ifdef __amigaos4__ + if (ILocale) + { + DropInterface((struct Interface *)ILocale); + ILocale = NULL; + } +#endif + CloseLibrary((struct Library *) LocaleBase); + LocaleBase = NULL; + } +#ifdef __amigaos4__ + if (ICx) + { + DropInterface((struct Interface *)ICx); + ICx = NULL; + } +#endif + if (CxBase) + { + CloseLibrary((struct Library *) CxBase); + CxBase = NULL; + } +#ifdef __amigaos4__ + if (IMUIMaster) + { + DropInterface((struct Interface *) IMUIMaster); + IMUIMaster = NULL; + } +#endif + if (MUIMasterBase) + { + CloseLibrary(MUIMasterBase); + MUIMasterBase = NULL; + } +#ifdef __amigaos4__ + if (IIntuition) + { + DropInterface((struct Interface *) IIntuition); + IIntuition = NULL; + } +#endif + if (IntuitionBase) + { + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } +} + +//---------------------------------------------------------------------------- + +static STRPTR GetLocString(ULONG MsgId) +{ + struct Exchange_LocaleInfo li; + + li.li_Catalog = ExchangeCatalog; +#ifndef __amigaos4__ + li.li_LocaleBase = LocaleBase; +#else + li.li_ILocale = ILocale; +#endif + + return (STRPTR)GetExchangeString(&li, MsgId); +} + +//---------------------------------------------------------------------------- + +static void TranslateStringArray(STRPTR *stringArray) +{ + while (*stringArray) + { + *stringArray = GetLocString((ULONG) *stringArray); + stringArray++; + } +} + +//---------------------------------------------------------------------------- +#if 0 +static void TranslateNewMenu(struct NewMenu *nm) +{ + while (nm && NM_END != nm->nm_Type) + { + if (NM_BARLABEL != nm->nm_Label) + nm->nm_Label = GetLocString((ULONG) nm->nm_Label); + + if (nm->nm_CommKey) + nm->nm_CommKey = GetLocString((ULONG) nm->nm_CommKey); + + nm++; + } +} +#endif +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT OpenAboutMUIFunc(struct Hook *hook, Object *o, Msg msg) +{ + if (NULL == WIN_AboutMUI) + { + WIN_AboutMUI = MUI_NewObject(MUIC_Aboutmui, + MUIA_Window_RefWindow, WIN_Main, + MUIA_Aboutmui_Application, APP_Main, + End; + } + + if (WIN_AboutMUI) + set(WIN_AboutMUI, MUIA_Window_Open, TRUE); + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT OpenAboutFunc(struct Hook *hook, Object *o, Msg msg) +{ + MUI_Request(APP_Main, WIN_Main, 0, NULL, + GetLocString(MSGID_ABOUTREQOK), + GetLocString(MSGID_ABOUTREQFORMAT), + VERSION_MAJOR, VERSION_MINOR, COMPILER_STRING, CURRENTYEAR); +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT CxListConstructHookFunc(struct Hook *hook, APTR unused, struct NList_ConstructMessage *nlcm) +{ + struct CxListEntry *xle = AllocPooled(nlcm->pool, sizeof(struct CxListEntry)); + BOOL Success = FALSE; + + (void) unused; + + do { + struct BrokerCopy *bc = nlcm->entry; + + d1(KPrintF("%s/%s/%ld: bc=%08lx\n", __FILE__, __FUNC__, __LINE__, bc)); + d1(KPrintF("%s/%s/%ld: bc_Name=<%s>\n", __FILE__, __FUNC__, __LINE__, bc->bc_Name)); + d1(KPrintF("%s/%s/%ld: bc_Title=<%s>\n", __FILE__, __FUNC__, __LINE__, bc->bc_Title)); + d1(KPrintF("%s/%s/%ld: bc_Descr=<%s>\n", __FILE__, __FUNC__, __LINE__, bc->bc_Descr)); + + if (NULL == xle) + break; + + xle->xle_Name = strdup(bc->bc_Name); + if (NULL == xle->xle_Name) + break; + + xle->xle_Title = strdup(bc->bc_Title); + if (NULL == xle->xle_Title) + break; + + xle->xle_Description = strdup(bc->bc_Descr); + if (NULL == xle->xle_Description) + break; + + xle->xle_Task = bc->bc_Task; + xle->xle_Pri = bc->bc_Node.ln_Pri; + xle->xle_Flags = bc->bc_Flags; +#ifdef __AROS__ + xle->xle_Addr = bc->bc_Port; +#else + xle->xle_Addr = bc->bc_Addr; +#endif + + Success = TRUE; + } while (0); + + if (!Success) + { + if (xle) + { + if (xle->xle_Name) + free(xle->xle_Name); + if (xle->xle_Title) + free(xle->xle_Title); + if (xle->xle_Description) + free(xle->xle_Description); + + FreePooled(nlcm->pool, xle, sizeof(struct CxListEntry)); + xle = NULL; + } + } + + d1(KPrintF("%s/%s/%ld: END xle=%08lx\n", __FILE__, __FUNC__, __LINE__, xle)); + + return (APTR) xle; +} + + +static SAVEDS(void) INTERRUPT CxListDestructHookFunc(struct Hook *hook, APTR unused, struct NList_DestructMessage *nldm) +{ + struct CxListEntry *xle = (struct CxListEntry *) nldm->entry; + + d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__)); + + (void) unused; + + if (xle) + { + if (xle->xle_Name) + free(xle->xle_Name); + if (xle->xle_Title) + free(xle->xle_Title); + if (xle->xle_Description) + free(xle->xle_Description); + + FreePooled(nldm->pool, xle, sizeof(struct CxListEntry)); + } + + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); +} + + +static SAVEDS(ULONG) INTERRUPT CxListDisplayHookFunc(struct Hook *hook, APTR unused, struct NList_DisplayMessage *nldm) +{ + (void) unused; + + d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__)); + + if (nldm->entry) + { + struct CxListEntry *xle = (struct CxListEntry *) nldm->entry; + + d1(KPrintF("%s/%s/%ld: xle=%08lx\n", __FILE__, __FUNC__, __LINE__, xle)); + d1(KPrintF("%s/%s/%ld: xle_Name=<%s>\n", __FILE__, __FUNC__, __LINE__, xle->xle_Name)); + + sprintf(xle->xle_PriString, "%ld", (long int)xle->xle_Pri); + + nldm->strings[0] = xle->xle_Name; + nldm->strings[1] = xle->xle_Title; + nldm->strings[2] = CycleActiveEntries[(xle->xle_Flags & COF_ACTIVE) ? 0 : 1]; + nldm->strings[3] = xle->xle_PriString; + } + else + { + // display titles + nldm->strings[0] = GetLocString(MSGID_CXLIST_NAME); + nldm->strings[1] = GetLocString(MSGID_CXLIST_TITLE); + nldm->strings[2] = GetLocString(MSGID_CXLIST_STATE); + nldm->strings[3] = GetLocString(MSGID_CXLIST_PRIORITY); + } + + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); + + return 0; +} + + +static SAVEDS(LONG) INTERRUPT CxListCompareHookFunc(struct Hook *hook, Object *obj, struct NList_CompareMessage *ncm) +{ + const struct CxListEntry *xle1 = (const struct CxListEntry *) ncm->entry1; + const struct CxListEntry *xle2 = (const struct CxListEntry *) ncm->entry2; + LONG col1 = ncm->sort_type & MUIV_NList_TitleMark_ColMask; + LONG col2 = ncm->sort_type2 & MUIV_NList_TitleMark2_ColMask; + LONG Result = 0; + + d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__)); + + if (ncm->sort_type != MUIV_NList_SortType_None) + { + // primary sorting + switch (col1) + { + case 0: // sort by name + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = Stricmp(xle2->xle_Name, xle1->xle_Name); + else + Result = Stricmp(xle1->xle_Name, xle2->xle_Name); + break; + case 1: // sort by title + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = Stricmp(xle2->xle_Title, xle1->xle_Title); + else + Result = Stricmp(xle1->xle_Title, xle2->xle_Title); + break; + case 2: // sort by state + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = (xle2->xle_Flags & COF_ACTIVE) - (xle1->xle_Flags & COF_ACTIVE); + else + Result = (xle1->xle_Flags & COF_ACTIVE) - (xle2->xle_Flags & COF_ACTIVE); + break; + case 3: // sort by priority + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = xle2->xle_Pri - xle1->xle_Pri; + else + Result = xle1->xle_Pri - xle2->xle_Pri; + break; + default: + break; + } + + if (0 == Result && col1 != col2) + { + // Secondary sorting + switch (col2) + { + case 0: // sort by name + if (ncm->sort_type2 & MUIV_NList_TitleMark2_TypeMask) + Result = Stricmp(xle2->xle_Name, xle1->xle_Name); + else + Result = Stricmp(xle1->xle_Name, xle2->xle_Name); + break; + case 1: // sort by title + if (ncm->sort_type2 & MUIV_NList_TitleMark2_TypeMask) + Result = Stricmp(xle2->xle_Title, xle1->xle_Title); + else + Result = Stricmp(xle1->xle_Title, xle2->xle_Title); + break; + case 2: // sort by state + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = (xle2->xle_Flags & COF_ACTIVE) - (xle1->xle_Flags & COF_ACTIVE); + else + Result = (xle1->xle_Flags & COF_ACTIVE) - (xle2->xle_Flags & COF_ACTIVE); + break; + case 3: // sort by priority + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = xle2->xle_Pri - xle1->xle_Pri; + else + Result = xle1->xle_Pri - xle2->xle_Pri; + break; + default: + break; + } + } + } + + d1(KPrintF("%s/%s/%ld: END Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + + return Result; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT RescanHookFunc(struct Hook *hook, Object *obj, Msg *msg) +{ + d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__)); + + do { + struct BrokerCopy *bc; + LONG res; + + CxFreeBrokerList(&BrokerCopyList); + + set(NListCxList, MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + DoMethod(NListCxList, MUIM_NList_Clear); + + res = CxCopyBrokerList(&BrokerCopyList); + d1(KPrintF("%s/%s/%ld: CxCopyBrokerList returned %ld\n", __FILE__, __FUNC__, __LINE__, res)); + + for (bc = (struct BrokerCopy *) BrokerCopyList.lh_Head; + bc != (struct BrokerCopy *) &BrokerCopyList.lh_Tail; + bc = (struct BrokerCopy *) bc->bc_Node.ln_Succ) + { + d1(KPrintF("%s/%s/%ld: bc=%08lx\n", __FILE__, __FUNC__, __LINE__, bc)); + d1(KPrintF("%s/%s/%ld: bc_Name=<%s> bc_Title=<%s> bc_Descr=<%s>\n", \ + __FILE__, __FUNC__, __LINE__, bc->bc_Name, bc->bc_Title, bc->bc_Descr)); + d1(KPrintF("%s/%s/%ld: bc_Addr=%08lx bc_Dummy2=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, bc->bc_Addr, bc->bc_Dummy2)); + + DoMethod(NListCxList, + MUIM_NList_InsertSingle, + bc, + MUIV_NList_Insert_Sorted); + } + + set(NListCxList, MUIA_NList_Quiet, MUIV_NList_Quiet_None); + } while (0); + + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT SelectCxHookFunc(struct Hook *hook, Object *obj, Msg *msg) +{ + const struct CxListEntry *xle = NULL; + + DoMethod(NListCxList, + MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, + &xle); + + if (xle) + { + STRPTR Description; + + Description = malloc(3 + strlen(xle->xle_Title) + strlen(xle->xle_Description)); + if (Description) + { + sprintf(Description, "%s\n%s", xle->xle_Title, xle->xle_Description); + set(FloattextDescription, MUIA_Floattext_Text, Description); + free(Description); + } + + set(ButtonShow, MUIA_Disabled, !(xle->xle_Flags & COF_SHOW_HIDE)); + set(ButtonHide, MUIA_Disabled, !(xle->xle_Flags & COF_SHOW_HIDE)); + set(ButtonRemove, MUIA_Disabled, FALSE); + set(CycleActive, MUIA_Disabled, FALSE); + setcycle(CycleActive, (xle->xle_Flags & COF_ACTIVE) ? 0 : 1); + } + else + { + set(FloattextDescription, MUIA_Floattext_Text, ""); + set(ButtonShow, MUIA_Disabled, TRUE); + set(ButtonHide, MUIA_Disabled, TRUE); + set(ButtonRemove, MUIA_Disabled, TRUE); + set(CycleActive, MUIA_Disabled, TRUE); + } +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT CxCommandHookFunc(struct Hook *hook, Object *obj, LONG *cmd) +{ + struct CxListEntry *xle = NULL; + + DoMethod(NListCxList, + MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, + &xle); + + if (xle) + { + (void) CxBrokerCommand(xle->xle_Name, *cmd); + } +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT BrokerHookFunc(struct Hook *hook, Object *obj, CxMsg *msg) +{ + if (CXM_COMMAND == CxMsgType(msg)) + { + switch (CxMsgID(msg)) + { + case CXCMD_APPEAR: + set(WIN_Main, MUIA_Window_Open, TRUE); + break; + case CXCMD_LIST_CHG: + DoMethod(APP_Main, MUIM_CallHook, &RescanHook); + break; + default: + break; + } + } +} + +//---------------------------------------------------------------------------- + +// Checks if a certain version of a MCC is available +BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev) +{ + BOOL flush = TRUE; + + d1(KPrintF("%s/%s/%ld: %s ", __FILE__, __FUNC__, __LINE__, name);) + + while (1) + { + ULONG ver = 0; + ULONG rev = 0; + struct Library *base; + char libname[256]; + + // First we attempt to acquire the version and revision through MUI + Object *obj = MUI_NewObject((STRPTR) name, TAG_DONE); + if (obj) + { + get(obj, MUIA_Version, &ver); + get(obj, MUIA_Revision, &rev); + + MUI_DisposeObject(obj); + + if(ver > minver || (ver == minver && rev >= minrev)) + { + d1(kprintf("%s/%s/%ld: v%ld.%ld found through MUIA_Version/Revision\n", __FILE__, __FUNC__, __LINE__, ver, rev);) + return TRUE; + } + } + + // If we did't get the version we wanted, let's try to open the + // libraries ourselves and see what happens... + stccpy(libname, "PROGDIR:mui", sizeof(libname)); + AddPart(libname, name, sizeof(libname)); + + if ((base = OpenLibrary(&libname[8], 0)) || (base = OpenLibrary(&libname[0], 0))) + { + UWORD OpenCnt = base->lib_OpenCnt; + + ver = base->lib_Version; + rev = base->lib_Revision; + + CloseLibrary(base); + + // we add some additional check here so that eventual broken .mcc also have + // a chance to pass this test (i.e. Toolbar.mcc is broken) + if (ver > minver || (ver == minver && rev >= minrev)) + { + d1(kprintf("%s/%s/%ld: v%ld.%ld found through OpenLibrary()\n", __FILE__, __FUNC__, __LINE__, ver, rev);) + return TRUE; + } + + if (OpenCnt > 1) + { + if (MUI_Request(NULL, NULL, 0L, + (STRPTR) GetLocString(MSGID_STARTUP_FAILURE), + (STRPTR) GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), + (STRPTR) GetLocString(MSGID_STARTUP_MCC_IN_USE), + name, minver, minrev, ver, rev)) + { + flush = TRUE; + } + else + break; + } + + // Attempt to flush the library if open count is 0 or because the + // user wants to retry (meaning there's a chance that it's 0 now) + + if (flush) + { + struct Library *result; + extern struct ExecBase *SysBase; + + Forbid(); + if ((result = (struct Library *) FindName(&SysBase->LibList, name))) + RemLibrary(result); + Permit(); + flush = FALSE; + } + else + { + d1(kprintf("%s/%s/%ld: couldn`t Exchange minimum required version.\n", __LINE__);) + + // We're out of luck - open count is 0, we've tried to flush + // and still haven't got the version we want + if (MUI_Request(NULL, NULL, 0L, + (STRPTR) GetLocString(MSGID_STARTUP_FAILURE), + (STRPTR) GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), + (STRPTR) GetLocString(MSGID_STARTUP_OLD_MCC), + name, minver, minrev, ver, rev)) + { + flush = TRUE; + } + else + break; + } + } + else + { + // No MCC at all - no need to attempt flush + flush = FALSE; + if (!MUI_Request(NULL, NULL, 0L, + (STRPTR) GetLocString(MSGID_STARTUP_FAILURE), + (STRPTR) GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), + (STRPTR) GetLocString(MSGID_STARTUP_MCC_NOT_FOUND), + name, minver, minrev)) + { + break; + } + } + } + + return FALSE; +} + +//---------------------------------------------------------------------------- + + diff --git a/scalos/Modules/Exchange.MUI/Exchange.cd b/scalos/Modules/Exchange.MUI/Exchange.cd new file mode 100755 index 000000000..0e6710453 --- /dev/null +++ b/scalos/Modules/Exchange.MUI/Exchange.cd @@ -0,0 +1,138 @@ +; Exchange.cd +; $Date$ +; $Revision$ +; version $VER: Exchange.catalog 40.1 (23 Dec 2008 18:50:08) +; codeset 0s +; language english +; +;#arrayopts static __far +; +; +MSGID_TITLENAME (//) +Scalos Exchange +; +;----------------------------------------------------------- +; +MSGID_MENU_PROJECT (1000//) +Project +; +; +MSGID_MENU_PROJECT_ABOUT (//) +About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI (//) +About MUI... +; +; +MSGID_MENU_PROJECT_QUIT (//) +Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT (/1/1) +Q +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK (2000//) +_OK +; +; +MSGID_ABOUTREQFORMAT (//) +\33c\033bScalos Exchange.module V%ld.%ld\033n\n\ +%s\n\ +© 2008%s The Scalos Team +; +;----------------------------------------------------------- +; +MSGID_BUTTON_SHOW (3000//) +Show +; +; +MSGID_BUTTON_SHOW_KEY (/1/1) +S +; +; +MSGID_BUTTON_SHOW_SHORTHELP (//) +Show Commodity window. +; +; +MSGID_BUTTON_HIDE (//) +Hide +; +; +MSGID_BUTTON_HIDE_KEY (/1/1) +H +; +; +MSGID_BUTTON_HIDE_SHORTHELP (//) +Hide Commodity window. +; +; +MSGID_BUTTON_REMOVE (//) +Remove +; +; +MSGID_BUTTON_REMOVE_KEY (/1/1) +R +; +; +MSGID_BUTTON_REMOVE_SHORTHELP (//) +Remove selected Commodity. +; +; +MSGID_CXLIST_NAME (//) +Name +; +; +MSGID_CXLIST_STATE (//) +State +; +; +MSGID_CXLIST_TITLE (//) +Title +; +; +MSGID_CXLIST_PRIORITY (//) +Priority +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE (4000//) +Exchange Module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD (//) +Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_CYCLE_ACTIVE_ACTIVE (5000//) +Active +; +; +MSGID_CYCLE_ACTIVE_INACTIVE (//) +Inactive +; +;----------------------------------------------------------- +; diff --git a/scalos/Modules/Exchange.MUI/Exchange.h b/scalos/Modules/Exchange.MUI/Exchange.h new file mode 100644 index 000000000..573d33f10 --- /dev/null +++ b/scalos/Modules/Exchange.MUI/Exchange.h @@ -0,0 +1,85 @@ +// Exchange.h +// $Date$ +// $Revision$ + +#ifndef EXCHANGE_MODULE_H +#define EXCHANGE_MODULE_H + +//---------------------------------------------------------------------------- + +#include + +//---------------------------------------------------------------------------- + +#define VERSION_MAJOR 40 +#define VERSION_MINOR 2 + +#define VERS_MAJOR STR(VERSION_MAJOR) +#define VERS_MINOR STR(VERSION_MINOR) + +//---------------------------------------------------------------------------- + +#if 0 +struct PrivateCxObj +{ + struct Node pco_Node; + UBYTE pco_Flags; + UBYTE pco_dummy1; + struct MinList pco_SubList; + APTR pco_dummy2; + TEXT pco_Name[CBD_NAMELEN]; + TEXT pco_Title[CBD_TITLELEN]; + TEXT pco_Descr[CBD_DESCRLEN]; + struct Task * pco_Task; + struct MsgPort *pco_Port; + ULONG pco_dummy3; + WORD pco_dummy4; +}; +#endif + +// Special Value in pco_Flags +#ifndef COF_ACTIVE +#define COF_ACTIVE 0x02 +#endif + +#if !defined(__AROS__) + +#ifdef __PPC__ +#pragma pack(2) +#endif + +struct BrokerCopy +{ + struct Node bc_Node; + char bc_Name[CBD_NAMELEN]; + char bc_Title[CBD_TITLELEN]; + char bc_Descr[CBD_DESCRLEN]; + struct Task *bc_Task; + APTR bc_Addr; + LONG bc_Dummy2; + UWORD bc_Flags; +}; + +#ifdef __PPC__ +#pragma pack() +#endif + +#endif // !__AROS__ + +//---------------------------------------------------------------------------- + +#if defined(__SASC) +int snprintf(char *, size_t, const char *, /*args*/ ...); +int vsnprintf(char *, size_t, const char *, va_list ap); +#endif /* __SASC */ + +//---------------------------------------------------------------------------- + +struct Exchange_LocaleInfo +{ + APTR li_LocaleBase; + APTR li_Catalog; + struct LocaleIFace *li_ILocale; +}; + +#endif /* EXCHANGE_MODULE_H */ diff --git a/scalos/Modules/Exchange.MUI/config.mk b/scalos/Modules/Exchange.MUI/config.mk new file mode 100755 index 000000000..0914889ab --- /dev/null +++ b/scalos/Modules/Exchange.MUI/config.mk @@ -0,0 +1,61 @@ +# $Date: 2011-07-16 19:39:22 +0200 (Sa, 16. Jul 2011) $ +# $Revision: 787 $ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +ICONOBJMCC_DIR = $(TOPLEVEL)/common/IconobjectMCC + +SCALOS_LOCALE = $(OBJDIR)/Exchange_Locale.h + +CFLAGS += -D SCALOSLOCALE=$(SCALOS_LOCALE) + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +INCLUDES += -I$(ICONOBJMCC_DIR) \ + +LFLAGS += # + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +INCLUDES += -I$(ICONOBJMCC_DIR) \ + +LFLAGS += -lauto + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +INCLUDES += -I$(ICONOBJMCC_DIR) \ + +LFLAGS += -lmui -lutility + + +else + + +############################################################################### +# AmigaOS + +LFLAGS += # + +endif +endif +endif diff --git a/scalos/Modules/Exchange.MUI/cx_private.h b/scalos/Modules/Exchange.MUI/cx_private.h new file mode 100644 index 000000000..6884bf46c --- /dev/null +++ b/scalos/Modules/Exchange.MUI/cx_private.h @@ -0,0 +1,34 @@ +// cx_private.h +// $Date$ +// $Revision$ + +#ifndef PROTO_COMMODITIES_PRIVATE_H +#define PROTO_COMMODITIES_PRIVATE_H + +#include + +#if defined(__amigaos4__) || defined(__AROS__) + +#define CxCopyBrokerList CopyBrokerList +#define CxFreeBrokerList FreeBrokerList +#define CxBrokerCommand BrokerCommand + +#else //!defined(__amigaos4__) + +#ifdef __GNUC__ +#ifdef __PPC__ +#ifndef _NO_PPCINLINE +#include "cx_private_ppcinline.h" +#endif /* _NO_PPCINLINE */ +#else +#ifndef _NO_INLINE +#include "cx_private_inline.h" +#endif /* _NO_INLINE */ +#endif /* __PPC__ */ +#else +#include "cx_private_pragmas.h" +#endif /* __GNUC__ */ +#endif //!defined(__amigaos4__) + +#endif /* !PROTO_COMMODITIES_PRIVATE_H */ + diff --git a/scalos/Modules/Exchange.MUI/cx_private_ppcinline.h b/scalos/Modules/Exchange.MUI/cx_private_ppcinline.h new file mode 100644 index 000000000..14acc045a --- /dev/null +++ b/scalos/Modules/Exchange.MUI/cx_private_ppcinline.h @@ -0,0 +1,29 @@ +// cx_private.h +// $Date$ +// $Revision$ + +#ifndef _PPCINLINE_COMMODITIES_PRIVATE_H +#define _PPCINLINE_COMMODITIES_PRIVATE_H + +#ifndef __PPCINLINE_MACROS_H +#include +#endif /* !__PPCINLINE_MACROS_H */ + +#ifndef COMMODITIES_BASE_NAME +#define COMMODITIES_BASE_NAME CxBase +#endif /* !COMMODITIES_BASE_NAME */ + +#define CxCopyBrokerList(list) \ + LP1(186, LONG, CopyBrokerList, struct List *, list, a0, \ + , CxBase, 0, 0, 0, 0, 0, 0) + +#define CxFreeBrokerList(list) \ + LP1(192, LONG, FreeBrokerList, struct List *, list, a0, \ + , CxBase, 0, 0, 0, 0, 0, 0) + +#define CxBrokerCommand(name,cmd) \ + LP2(198, LONG, BrokerCommand, BYTE *, name, a0, LONG, cmd, d0, \ + , CxBase, 0, 0, 0, 0, 0, 0) + +#endif /* !_PPCINLINE_COMMODITIES_PRIVATE_H */ + diff --git a/scalos/Modules/Exchange.MUI/cx_private_pragmas.h b/scalos/Modules/Exchange.MUI/cx_private_pragmas.h new file mode 100644 index 000000000..6efe04bed --- /dev/null +++ b/scalos/Modules/Exchange.MUI/cx_private_pragmas.h @@ -0,0 +1,24 @@ +// cx_private_pragmas.h +// $Date$ +// $Revision$ + +#ifndef _INCLUDE_PRAGMA_COMMODITIES_PRIVATE_LIB_H +#define _INCLUDE_PRAGMA_COMMODITIES_PRIVATE_LIB_H + +#if defined(AZTEC_C) || defined(__MAXON__) || defined(__STORM__) +#pragma amicall(CxBase,0x0ba,CxCopyBrokerList(a0)) +#pragma amicall(CxBase,0x0c0,CxFreeBrokerList(a0)) +#pragma amicall(CxBase,0x0c6,CxBrokerCommand(a0,d0)) +#endif +#if defined(_DCC) || defined(__SASC) +#pragma libcall CxBase CxCopyBrokerList 0ba 801 +#pragma libcall CxBase CxFreeBrokerList 0c0 801 +#pragma libcall CxBase CxBrokerCommand 0c6 0802 +#endif + +#ifndef CLIB_COMMODITIES_PRIVATE_PROTOS_H +#include "cx_private_protos.h" +#endif + +#endif /* _INCLUDE_PRAGMA_COMMODITIES_PRIVATE_LIB_H */ + diff --git a/scalos/Modules/Exchange.MUI/cx_private_protos.h b/scalos/Modules/Exchange.MUI/cx_private_protos.h new file mode 100644 index 000000000..d42b1e6dc --- /dev/null +++ b/scalos/Modules/Exchange.MUI/cx_private_protos.h @@ -0,0 +1,50 @@ +// cx_private_protos.h +// $Date$ +// $Revision$ + +#ifndef CLIB_COMMODITIES_PRIVATE_PROTOS_H +#define CLIB_COMMODITIES_PRIVATE_PROTOS_H + +/* + commodities.library private C prototypes +*/ + +#ifndef EXEC_TYPES_H +# include +#endif + +#ifndef EXEC_TASKS_H +# include +#endif + +#ifndef EXEC_NODES_H +# include +#endif + +#ifndef LIBRARIES_COMMODITIES_H +# include +#endif + +#ifndef DEVICES_INPUTEVENT_H +# include +#endif + +#ifndef DEVICES_KEYMAP_H +# include +#endif + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +LONG CxCopyBrokerList(struct List *brokerList); +LONG CxFreeBrokerList(struct List *brokerList); +LONG CxBrokerCommand(CONST_STRPTR name, LONG cmd); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* CLIB_COMMODITIES_PROTOS_H */ diff --git a/scalos/Modules/Exchange.MUI/debug.h b/scalos/Modules/Exchange.MUI/debug.h new file mode 100644 index 000000000..b5839f9cd --- /dev/null +++ b/scalos/Modules/Exchange.MUI/debug.h @@ -0,0 +1,28 @@ +// debug.h +// $Date$ +// $Revision$ + +#ifndef DEBUG_H +#define DEBUG_H + +//---------------------------------------------------------------------------- + +#define d1(x) ; +#define d2(x) x; + +#define debugLock_d1(LockName) ; +#define debugLock_d2(LockName) \ + {\ + char xxName[200];\ + strcpy(xxName, "");\ + NameFromLock((LockName), xxName, sizeof(xxName));\ + KPrintF("%s/%s/%ld: " #LockName "=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, LockName, xxName);\ + } + +// from debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +//---------------------------------------------------------------------------- + +#endif /* DEBUG_H */ diff --git a/scalos/Modules/Exchange.MUI/makefile b/scalos/Modules/Exchange.MUI/makefile new file mode 100644 index 000000000..9a9486333 --- /dev/null +++ b/scalos/Modules/Exchange.MUI/makefile @@ -0,0 +1,134 @@ +# MakeFile für Exchange MUI module +# $Date$ + +##################################################################### + +TOPLEVEL = / +SUBDIRMAKE = $(MAKE) -s -C +CATCOMP = CatComp +FLEXCAT = FlexCat +CHEADERS = +CC = sc +CFLAGS = optimize nostackcheck nochkabort debug=s NOWVRET \ + strmer nover streq idlen=128 IGNORE=217 \ + idir=sc:include/ \ + define SCALOSLOCALE=$(SCALOS_LOCALE) \ + idir=include: idir=//include +AFLAGS = QUIET m=68020 linedebug opt=NRQB i=include: +LD = slink +LNFLAGS = quiet batch noicons stripdebug +LNDBFLAGS = quiet batch noicons addsym +LIBS = LIB:sc.lib \ + //SAS-lib/snprintf.lib \ + LIB:mempools.lib \ + LIB:debug.lib \ + LIB:amiga.lib +CSTARTUP = LIB:c.o +OBJDIR = .sasobj + +SCALOS_LOCALE = $(OBJDIR)/Exchange_Locale.h + +.SUFFIXES: .cd + +############################################################# + +NAME = .bin_os3/Exchange.module +DBGNAME = $(NAME).debug +CATCOMPHEADER = $(SCALOS_LOCALE) +DESTTOOL = Scalos:modules/ +CAT_FILE = Scalos/Exchange.catalog +DESTCAT = Locale:Catalogs +ALLCATS = Catalogs/deutsch/$(CAT_FILE) \ + Catalogs/français/$(CAT_FILE) + +############################################################# + +all: $(NAME) \ + $(DBGNAME) \ + allcatalogs +# install +# clean + +##################################################################### + +# make all Scalos .catalogs +allcatalogs: + @$(SUBDIRMAKE) Catalogs/deutsch/Scalos + @$(SUBDIRMAKE) Catalogs/français/Scalos + +##################################################################### + +CSRCS = Exchange.c \ + +##################################################################### + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +############################################################# + +XSRCS = $(notdir $(CSRCS)) +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(XSRCS:%.c=$(OBJDIR)/$(notdir %).o) + +##################################################################### + +$(CATCOMPHEADER) : Exchange.cd + @printf '\033[32mMake Catcomp header: \033[31m\033[1m$@ \033[32mfrom \033[31m$<\033[0m\n' + @$(FLEXCAT) $< $@=$(TOPLEVEL)/CatComp_h.sd + +##################################################################### + +$(OBJDIR)/Exchange.o : Exchange.c Exchange.h \ + $(SCALOS_LOCALE) \ + cx_private.h \ + cx_private_protos.h \ + cx_private_pragmas.h \ + debug.h + +##################################################################### + +$(NAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNFLAGS) + +$(DBGNAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNDBFLAGS) + +############################################################# + +# commands generated a catalog (.catalog) from a catalog translation (.ct) file. +.ct.catalog: + $(CATCOMP) $*.cd $< CATALOG $*.catalog VB=1 + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $< objectname $@ + +$(OBJDIR)/%.o : %.s + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +$(OBJDIR)/%.o : %.asm + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +############################################################# + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(NAME) \033[0mto \033[1m$(DESTTOOL) \033[0m\n' + @copy $(NAME) $(DESTTOOL) clone + @printf '\033[32mFlushing memory\033[0m\n' + @avail flush + @printf '\033[32mInstall: \033[31m\033[1m$(CAT_FILE)\033[0m\n' + -@copy 'catalogs/deutsch/$(CAT_FILE)' '$(DESTCAT)/Deutsch/Scalos/' clone + -@copy 'catalogs/français/$(CAT_FILE)' '$(DESTCAT)/français/Scalos/' clone + +############################################################# + +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + -@delete $(OBJS) $(NAME) $(DBGNAME) $(ALLCATS) $(CATCOMPHEADER) + @printf '\033[0m' + +############################################################# diff --git a/scalos/Modules/Exchange.MUI/makefile-new b/scalos/Modules/Exchange.MUI/makefile-new new file mode 100755 index 000000000..9ff32708c --- /dev/null +++ b/scalos/Modules/Exchange.MUI/makefile-new @@ -0,0 +1,100 @@ +# $Date: 2011-07-12 02:18:25 +0200 (Di, 12. Jul 2011) $ +# $Revision: 773 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL = $(shell pwd)/../.. +endif + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + SDPATH=/ +else + SDPATH=../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(OBJDIR)/Exchange.o \ + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Subdirs +# + +SUBDIRS = $(filter-out Catalogs/sample/Scalos, $(wildcard Catalogs/*/Scalos)) + +############################################################################## +# +# Targets +# + +NAME = Exchange.module +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) \ + all_subdirs + +############################################################################## + +$(OBJDIR)/%.o: $(TOOLTYPE_DIR)/%.c + @$(run-cc) + +$(OBJDIR)/%.o: $(ICONOBJMCC_DIR)/%.c + @$(run-cc) + +Exchange.c : $(OBJDIR)/Exchange_Locale.h + +$(OBJDIR)/Exchange_Locale.h : Exchange.cd + @$(ECHO) "FlexCat $@" + $(FLEXCAT) $< $@=$(SDPATH)/CatComp_h.sd + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + @$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) +ifneq ($(MACHINE), ppc-amigaos) + -@chmod u+x $@ +endif + +############################################################################## + +install: install_subdirs + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) Scalos:modules/ clone + +clean: clean_subdirs + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* \ + $(OBJDIR)/Exchange_Locale.h + +############################################################################## + diff --git a/scalos/Modules/Execute_Command.Gadtools/execute_command.c b/scalos/Modules/Execute_Command.Gadtools/execute_command.c new file mode 100755 index 000000000..730cfb04b --- /dev/null +++ b/scalos/Modules/Execute_Command.Gadtools/execute_command.c @@ -0,0 +1,779 @@ +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +__stdargs void NewList( struct List *list ); +static void ecmain(void); +static void wbmain(struct WBStartup *wbs ); + +IMPORT struct Library *GadToolsBase; +IMPORT struct Library *IntuitionBase; +IMPORT struct Library *SysBase; +IMPORT struct Library *GfxBase; +IMPORT struct Library *DOSBase; +IMPORT struct Library *LocaleBase; +IMPORT struct Library *UtilityBase; + +struct Library *WorkbenchBase; + +struct Catalog *Cat; + +struct Screen *scr; +struct DrawInfo *drinfo; +APTR visualinfo; +ULONG offx,offy,fonty,sizeheight,uwidth; +ULONG wndwidth,wndheight; + +struct Window *wnd; +struct MsgPort *appMsgPort; +struct AppWindow *appWnd; +struct Gadget *glist; +struct Gadget *commandString; +struct Gadget *stackInteger; +STRPTR commandStr; +ULONG stackNum; + +BOOL glistAttached; +BOOL sizeVerify; +BOOL fromWB; + +const STATIC STRPTR engLocText[] = +{ + "Enter command and its Arguments", + "_Command", + "_OK", + "_Cancel", + "Execute a file", + "_Stack", + "Choose a command", + "Scalos Output Window" +}; + +UWORD ok_key, cancel_key, stack_key, command_key, commandbut_key; + +STRPTR locText[8]; + +const STRPTR VerString = "$VER: execute_command.module 1.0 "__AMIGADATE__; + +#define WND_COMMAND_STRING 1 +#define WND_COMMAND_BUTTON 2 +#define WND_OK_BUTTON 3 +#define WND_STACK_INTEGER 4 +#define WND_CANCEL_BUTTON 5 + +//------------------------------------- +STATIC VOID SR_CopyFunc(VOID) +{ + __emit(0x16c0); // MOVE.B D0,(A3)+ +} +//------------------------------------- +VOID sprintf( STRPTR buf, const STRPTR fmt,...) +{ + RawDoFmt((const STRPTR)fmt,(STRPTR*)&fmt+1,(void(*)())SR_CopyFunc,buf); +} + +//------------------------------------- +ULONG StrLen( const STRPTR str ) +{ + if( !str) return 0; + return strlen(str); +} +//------------------------------------- +STRPTR StrCopy( const STRPTR str ) +{ + STRPTR dst; + if( !str ) return NULL; + if( !*str) return NULL; + + dst = (STRPTR)AllocVec(strlen(str)+1,0); + if(dst) strcpy(dst,str); + return dst; +} +//------------------------------------- +STRPTR BuildConName( STRPTR wtitle, struct Screen *scr ) +{ + const STATIC STRPTR fmt = "CON:/%ld//%ld/%s/AUTO/CLOSE/WAIT"; + + STRPTR buf = (STRPTR)AllocVec( strlen(fmt)+strlen(wtitle)+30,0 ); + if( buf ) + { + LONG height=280; + LONG top=13; + if( scr ) + { + struct Rectangle rect; + if(QueryOverscan( GetVPModeID( &scr->ViewPort ), &rect, OSCAN_TEXT )) + { + height = rect.MaxY - rect.MinY + 1; + } else height = scr->Height; + + height = height*2/3; + top = -scr->TopEdge; + if( top <= scr->BarHeight ) top = scr->BarHeight + 1; + } + sprintf( buf, fmt, top, height, wtitle ); + } + return buf; +} +//------------------------------------- +STRPTR NameOfLock( BPTR lock ) +{ + STRPTR n; + BOOL again; + ULONG bufSize = 127; + if( !lock ) return NULL; + + do + { + again = FALSE; + if((n = (STRPTR)AllocVec(bufSize, 0x10000 ))) + { + if( NameFromLock( lock, n, bufSize-1 ) == DOSFALSE ) + { + if( IoErr() == ERROR_LINE_TOO_LONG ) + { + bufSize += 127; + again = TRUE; + } + FreeVec(n); + n = NULL; + } + } + } while(again); + + return n; +} +//------------------------------------- +STRPTR WBArg2String( struct WBArg *arg, LONG numArgs ) +{ + struct WBArgNode + { + struct MinNode node; + STRPTR dirname; + STRPTR filename; + }; + + struct MinList list; + ULONG len=0; + STRPTR buf; + UWORD i; + + NewList((struct List*)&list ); + + for( i=0; idirname = n; + node->filename = arg[i].wa_Name; + + len += StrLen( n )+StrLen(arg[i].wa_Name)+8; + AddTail((struct List*)&list, (struct Node*)node ); + } + } + + buf = (STRPTR)AllocVec(len+2,0x10000); + if(buf) + { + struct WBArgNode *node; + STRPTR bufPtr = buf; + + while(( node = (struct WBArgNode*)RemHead((struct List*)&list))) + { + STRPTR n = node->dirname; + if( !n ) continue; + + if( n[0] ) strcpy(bufPtr,n ); + AddPart(bufPtr,node->filename,len-(bufPtr-buf)); + + bufPtr+=strlen(bufPtr); + if(list.mlh_Head->mln_Succ) + *bufPtr++=' '; + + FreeVec(n); + FreeVec(node); + } + *bufPtr = 0; + } + return buf; +} +//------------------------------------- +STRPTR GetFullPath( const STRPTR drw, const STRPTR file ) +{ + ULONG length = StrLen(drw)+StrLen(file)+4; + STRPTR fp = (STRPTR)AllocVec( length+1,0 ); + if( fp ) + { + strcpy( fp, drw ); + + if( AddPart( fp, file, length )) return fp; + FreeVec( fp ); + } + return NULL; +} +//------------------------------------- +STRPTR RequestAFile(void) +{ + STRPTR file_name = NULL; + struct Library *AslBase; + + AslBase = OpenLibrary("asl.library",39); + if( AslBase ) + { + struct FileRequester *file_req; + + file_req = (struct FileRequester*)AllocAslRequestTags(ASL_FileRequest, + ASLFR_RejectIcons, TRUE, + ASLFR_Window,wnd, + ASLFR_SleepWindow,TRUE, + ASLFR_TitleText,locText[6], + TAG_DONE); + if( file_req ) + { + if(AslRequest(file_req, NULL)) + { + file_name = GetFullPath( file_req->fr_Drawer, file_req->fr_File ); + } + FreeAslRequest(file_req); + } + CloseLibrary(AslBase); + } + return file_name; +} +//------------------------------------- +ULONG FindUnderscoredToLower(STRPTR text) +{ + ULONG c; + while(( c = *text++)) + { + if( c == '_' ) return ToLower(*text); + } + return 0; +} +//------------------------------------- + +//------------------------------------- +STATIC VOID InitStrings(void) +{ + ULONG i; + for(i=0; i<8; i++) + { + locText[i] = GetCatalogStr( Cat, i, engLocText[i]); + } + + command_key = FindUnderscoredToLower(locText[1]); + commandbut_key = ToUpper(command_key); + ok_key = FindUnderscoredToLower(locText[2]); + cancel_key = FindUnderscoredToLower(locText[3]); + stack_key = FindUnderscoredToLower(locText[5]); +} +//------------------------------------- + +//------------------------------------- +STATIC VOID GetCommand(void) +{ + STRPTR cmdStr; + + if(GT_GetGadgetAttrs(commandString,wnd,NULL, + GTST_String, &cmdStr, + TAG_DONE )) + { + if( commandStr ) FreeVec(commandStr); + commandStr=StrCopy(cmdStr); + } +} +//------------------------------------- +STATIC VOID GetStack(void) +{ + GT_GetGadgetAttrs(stackInteger,wnd,NULL, + GTIN_Number,&stackNum, + TAG_DONE ); + + if( stackNum < 4096 ) + { + stackNum = 4096; + GT_SetGadgetAttrs(stackInteger,wnd,NULL, + GTIN_Number,stackNum, + TAG_DONE ); + + } +} +//------------------------------------- +STATIC VOID SetCommand(void) +{ + GT_SetGadgetAttrs(commandString,wnd,NULL, + GTST_String, commandStr?commandStr:(STRPTR)"", + TAG_DONE ); +} +//------------------------------------- + +//------------------------------------- +STATIC VOID CommandButton(void) +{ + STRPTR cstr = RequestAFile(); + if( cstr ) + { + if(commandStr)FreeVec(commandStr); + commandStr = cstr; + SetCommand(); + ((struct StringInfo*)(commandString->SpecialInfo))->BufferPos = strlen(cstr); + ActivateGadget(commandString, wnd, NULL ); + } +} +//------------------------------------- + +//------------------------------------- +STATIC BOOL SetupScreen(void) +{ + if((scr = LockPubScreen(NULL))) + { + if((drinfo = GetScreenDrawInfo(scr))) + { + if((visualinfo = GetVisualInfoA(scr,NULL))) + { + Object *o = (Object*)NewObject( NULL, SYSICLASS, + SYSIA_DrawInfo,drinfo, + SYSIA_Which, SIZEIMAGE, + TAG_DONE); + if(o) + { + if(!GetAttr( IA_Height,o,&sizeheight)) sizeheight = 11; + DisposeObject(o); + } else sizeheight = 11; + uwidth = TextLength(&scr->RastPort,"_",1); + return TRUE; + } + } + } + return FALSE; +} +//------------------------------------- +STATIC VOID FreeScreen(void) +{ + if( visualinfo ) FreeVisualInfo(visualinfo); + if( drinfo ) FreeScreenDrawInfo(scr,drinfo); + if( scr ) UnlockPubScreen(NULL,scr); +} +//------------------------------------- +STATIC VOID Render(void) +{ + Move(wnd->RPort,offx+4,offy+drinfo->dri_Font->tf_Baseline+4); + SetABPenDrMd(wnd->RPort,drinfo->dri_Pens[TEXTPEN],0,JAM1); + Text(wnd->RPort,locText[0],strlen(locText[0])); +} +//------------------------------------- +STATIC BOOL CreateGadgets(void) +{ + struct Gadget *g; + + if(glist) + { + FreeGadgets(glist); + glist = NULL; + } + + g = CreateContext( &glist ); + if( g ) + { + struct NewGadget ng; + WORD commandButtonWidth = TextLength(&scr->RastPort,"«",1)+6; + WORD usableWidth = wndwidth-2*offx-24-TextLength(&scr->RastPort,locText[5],strlen(locText[5]))-uwidth-10; + BOOL setCursor; + UWORD cancelLeft; + + ng.ng_VisualInfo = visualinfo; + ng.ng_TextAttr = NULL; + ng.ng_GadgetText = locText[1]; + ng.ng_GadgetID = WND_COMMAND_STRING; + ng.ng_Flags = NULL; + ng.ng_UserData = NULL; + ng.ng_LeftEdge = offx+13+TextLength(&scr->RastPort,ng.ng_GadgetText,strlen(ng.ng_GadgetText))-uwidth; + ng.ng_TopEdge = offy+fonty+7; + ng.ng_Width = wndwidth-ng.ng_LeftEdge-offx-4-commandButtonWidth; + ng.ng_Height = fonty+6; + + if( !commandString && commandStr ) setCursor = TRUE; + else setCursor = FALSE; + + g = commandString = CreateGadget( STRING_KIND, g, &ng, + GTST_String, commandStr?commandStr:(STRPTR)"", + GT_Underscore,'_', + TAG_DONE); + + if( setCursor ) + ((struct StringInfo*)(commandString->SpecialInfo))->BufferPos = strlen(commandStr); + + + ng.ng_LeftEdge += ng.ng_Width; + ng.ng_Width = commandButtonWidth; + ng.ng_GadgetID = WND_COMMAND_BUTTON; + ng.ng_GadgetText = "«"; + + g = CreateGadgetA( BUTTON_KIND, g, &ng, NULL ); + + ng.ng_TopEdge += ng.ng_Height+4; + ng.ng_Width = usableWidth/3; + ng.ng_GadgetText = locText[2]; + ng.ng_LeftEdge = offx+4; + ng.ng_GadgetID = WND_OK_BUTTON; + + g = CreateGadget( BUTTON_KIND, g, &ng, + GT_Underscore,'_', + TAG_DONE); + + cancelLeft = wndwidth-offx-4-ng.ng_Width; + + ng.ng_LeftEdge += ng.ng_Width + TextLength(&scr->RastPort,locText[5],5)-uwidth+20; + ng.ng_Width = cancelLeft - ng.ng_LeftEdge - 10; + ng.ng_GadgetText = locText[5]; + ng.ng_GadgetID = WND_STACK_INTEGER; + + stackInteger = g = CreateGadget( INTEGER_KIND, g, &ng, + GT_Underscore,'_', + GTIN_Number, stackNum, + TAG_DONE); + + ng.ng_GadgetText = locText[3]; + ng.ng_LeftEdge = cancelLeft; + ng.ng_GadgetID = WND_CANCEL_BUTTON; + ng.ng_Width = usableWidth/3; + + g = CreateGadget( BUTTON_KIND, g, &ng, + GT_Underscore,'_', + TAG_DONE); + + if(g) return TRUE; + + FreeGadgets(glist); + glist=NULL; + } + return FALSE; +} +//------------------------------------- +STATIC VOID FreeGUI(void) +{ + if(appWnd) RemoveAppWindow(appWnd); + if(appMsgPort) DeleteMsgPort(appMsgPort); + if(wnd) CloseWindow(wnd); + if(glist) FreeGadgets(glist); +} +//------------------------------------- +STATIC BOOL SetupGUI(void) +{ + fonty = drinfo->dri_Font->tf_YSize; + offx = scr->WBorLeft; + offy = scr->WBorTop + fonty + 1; + + wndwidth = TextLength(&scr->RastPort,locText[0],strlen(locText[0]))+TextLength(&scr->RastPort,locText[1],strlen(locText[1]))+TextLength(&scr->RastPort,"«",1)+6; + wndheight = offy + 3*fonty + sizeheight + 26; + + if( CreateGadgets()) + { + ULONG idcmp = IDCMP_CLOSEWINDOW|IDCMP_NEWSIZE|BUTTONIDCMP|IDCMP_VANILLAKEY|STRINGIDCMP; + if( sizeVerify ) idcmp |= IDCMP_SIZEVERIFY; + + wnd = OpenWindowTags( NULL, + WA_Left,0, + WA_Top,offy, + WA_Width, wndwidth, + WA_Height, wndheight, + WA_IDCMP, idcmp, + WA_DragBar,TRUE, + WA_SizeGadget, TRUE, + WA_DepthGadget,TRUE, + WA_CloseGadget, TRUE, + WA_Title,locText[4], + WA_RMBTrap, TRUE, + WA_Gadgets, glist, + WA_SizeBBottom,TRUE, + WA_MaxWidth,-1, + WA_Activate, TRUE, + WA_PubScreen,scr, + WA_NoCareRefresh,TRUE, +// WA_MaxHeight,-1, + TAG_DONE ); + if( wnd ) + { + glistAttached = TRUE; + if( WorkbenchBase ) + { + if((appMsgPort = CreateMsgPort())) + { + appWnd = AddAppWindowA(1,NULL,wnd,appMsgPort,NULL); + } + } + + SetFont(wnd->RPort,drinfo->dri_Font); + Render(); + return TRUE; + } + glistAttached = FALSE; + } + FreeGUI(); + return FALSE; +} +//------------------------------------- +STATIC BOOL HandleWnd(void) +{ + struct IntuiMessage *imsg; + BOOL retVal = FALSE; + + while((imsg = GT_GetIMsg(wnd->UserPort))) + { + ULONG cl = imsg->Class; + UWORD code = imsg->Code; + APTR iaddress = imsg->IAddress; + + if( cl == IDCMP_SIZEVERIFY ) + { + if(glistAttached) RemoveGList( wnd, glist, -1 ); + glistAttached = FALSE; + GT_ReplyIMsg(imsg); + continue; + } + + GT_ReplyIMsg(imsg); + + switch( cl ) + { + case IDCMP_CLOSEWINDOW: + retVal = TRUE; + if( commandStr ) FreeVec(commandStr); + commandStr = NULL; + break; + + case IDCMP_VANILLAKEY: + if( code == 10 || code == ok_key) retVal = TRUE; + else if( code == 27 || code == cancel_key) + { + retVal = TRUE; + if( commandStr ) FreeVec(commandStr); + commandStr = NULL; + } + else if( code == command_key ) ActivateGadget(commandString,wnd,NULL); + else if( code == stack_key ) ActivateGadget(stackInteger,wnd,NULL); + else if( code == commandbut_key ) CommandButton(); + break; + + case IDCMP_NEWSIZE: + if( !sizeVerify && glistAttached) + { + if( wndwidth == wnd->Width || wndheight != wnd->Height ) break; + } + if(glistAttached) RemoveGList( wnd, glist, -1 ); + if( wnd->Width < wndwidth ) RefreshWindowFrame(wnd); + wndwidth = wnd->Width; + wndheight = wnd->Height; + EraseRect( wnd->RPort, wnd->BorderLeft, wnd->BorderTop+fonty+6, + wnd->Width-wnd->BorderRight-1, wnd->Height-wnd->BorderBottom-1 ); + if(CreateGadgets()) + { + AddGList( wnd, glist, -1,-1, NULL ); + RefreshGList( glist, wnd, NULL, -1 ); + glistAttached = TRUE; + ActivateGadget( commandString, wnd, NULL); + } else + { + glistAttached = FALSE; + retVal = TRUE; + } + break; + + case IDCMP_GADGETUP: + switch( ((struct Gadget*)iaddress)->GadgetID ) + { + case WND_COMMAND_STRING: + retVal = TRUE; + GetCommand(); + break; + + case WND_COMMAND_BUTTON: + CommandButton(); + break; + + case WND_CANCEL_BUTTON: + retVal = TRUE; + if( commandStr ) FreeVec(commandStr); + commandStr = NULL; + break; + + case WND_OK_BUTTON: + retVal = TRUE; + GetCommand(); + break; + + case WND_STACK_INTEGER: + GetStack(); + break; + + default: + break; + } + break; + } + } + return retVal; +} +//------------------------------------- +STATIC VOID HandleApp(void) +{ + struct AppMessage *amsg; + BOOL commandSet = FALSE; + while(( amsg = (struct AppMessage*)GetMsg(appMsgPort))) + { + if( amsg->am_Type == AMTYPE_APPWINDOW ) + { + STRPTR str = WBArg2String(amsg->am_ArgList, amsg->am_NumArgs ); + if( str ) + { + if(commandStr) FreeVec(commandStr); + commandStr = str; + SetCommand(); + ((struct StringInfo*)(commandString->SpecialInfo))->BufferPos = strlen(str); + commandSet = TRUE; + } + } + ReplyMsg((struct Message*)amsg); + } + if(commandSet) + { + ActivateWindow(wnd); + ActivateGadget(commandString,wnd,NULL); + } +} +//------------------------------------- + +//------------------------------------- +static void ecmain(void) +{ + BPTR lock; + WorkbenchBase = OpenLibrary("workbench.library",37); + if(LocaleBase)Cat = OpenCatalogA( NULL, "Scalos/Scalos_ECommand.catalog",NULL); + + lock = Lock("ENV:Scalos/NoSizeVerify",ACCESS_READ); + if(lock) + { + sizeVerify = FALSE; + UnLock(lock); +// lock = NULL; + } else sizeVerify = TRUE; + + InitStrings(); + + if(SetupScreen()) + { + stackNum = 4096; + if(!commandStr) + { + STRPTR buffer = (STRPTR)AllocVec(516,0); + if(buffer) + { + if(GetVar("Scalos_last_cmd",buffer,512,GVF_GLOBAL_ONLY)!=-1) + { + commandStr = StrCopy(buffer); + } + FreeVec(buffer); + } + } + + if( SetupGUI()) + { + BOOL ready = FALSE; + ULONG wndsig = 1UL<UserPort->mp_SigBit; + ULONG appsig; + + if( appMsgPort ) appsig = 1UL<mp_SigBit; + else appsig = 0UL; + + ActivateGadget(commandString,wnd,NULL); + + while( ready == FALSE ) + { + ULONG signal = Wait(wndsig|appsig|4096); + + if( signal & 4096 ) ready = TRUE; + if( signal & wndsig ) ready = HandleWnd(); + if( signal & appsig ) HandleApp(); + } + FreeGUI(); + + if( commandStr ) + { + STRPTR conName = BuildConName(locText[7],scr); + if( conName ) + { + SystemTags( commandStr, + SYS_Asynch, TRUE, + SYS_Output, Open(conName,MODE_OLDFILE), + SYS_Input, NULL, + SYS_UserShell, TRUE, + stackNum>=4096?NP_StackSize:TAG_IGNORE,stackNum, + TAG_DONE); + + FreeVec(conName); + } + SetVar("Scalos_last_cmd",commandStr,strlen(commandStr),GVF_GLOBAL_ONLY); + FreeVec(commandStr); + commandStr = NULL; + } + } + FreeScreen(); + } + + if(Cat) CloseCatalog(Cat); + if(WorkbenchBase)CloseLibrary(WorkbenchBase); +} +//------------------------------------- +main() +{ + wbmain(WBenchMsg); +} +//------------------------------------- +static void wbmain(struct WBStartup *wbs ) +{ + BPTR olddir; + BPTR lock; + + if( wbs->sm_NumArgs > 1 ) + { + lock = NULL; + commandStr = StrCopy(wbs->sm_ArgList[1].wa_Name); + olddir = CurrentDir(wbs->sm_ArgList[1].wa_Lock); + } else + { + lock = Lock("RAM:",ACCESS_READ); + olddir = CurrentDir(lock); + } + ecmain(); + CurrentDir(olddir); + + if(lock) UnLock(lock); +} +//------------------------------------- diff --git a/scalos/Modules/Execute_Command.Gadtools/makefile b/scalos/Modules/Execute_Command.Gadtools/makefile new file mode 100755 index 000000000..d65b37259 --- /dev/null +++ b/scalos/Modules/Execute_Command.Gadtools/makefile @@ -0,0 +1,82 @@ +# Makefile for Execute_Command.module (MUI) +# using GNU make and SAS/C +# $Date$ + +##################################################################### + +CHEADERS = +CC = sc +CFLAGS = optimize nostackcheck nochkabort debug=s \ + strmer nover streq idir=sc:include/ idir=include: idir=//include +AS = phxass +AFLAGS = QUIET m=68020 linedebug opt=NRQB i=include: +LD = slink +LNFLAGS = quiet batch noicons stripdebug +LNDBFLAGS = quiet batch noicons addsym +LIBS = LIB:sc.lib LIB:debug.lib LIB:amiga.lib +CSTARTUP = LIB:c.o +OBJDIR = .sasobj + +##################################################################### + +.SUFFIXES: .asm + +##################################################################### + +NAME = Execute_Command.module +DBGNAME = $(NAME).debug + +##################################################################### + +all: $(NAME) $(DBGNAME) +# install +# clean + +##################################################################### + +CSRCS = execute_command.c \ + + +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(CSRCS:%.c=$(OBJDIR)/%.o) + +##################################################################### + +$(NAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNFLAGS) + +$(DBGNAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNDBFLAGS) + +##################################################################### + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +##################################################################### + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $< objectname $@ + +##################################################################### + +$(NAME) $(DBGNAME) : $(OBJS) + +##################################################################### + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(NAME) \033[0mto \033[31m\033[1mScalos:modules/ \033[0m\n' + copy $(NAME) Scalos:modules/ + +##################################################################### + +# A little something to clean it all up +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + -@delete $(OBJS) $(NAME) $(DBGNAME) + @printf '\033[0m' + +##################################################################### + diff --git a/scalos/Modules/Execute_Command.MUI/Catalogs/deutsch/Scalos/Execute_Command.ct b/scalos/Modules/Execute_Command.MUI/Catalogs/deutsch/Scalos/Execute_Command.ct new file mode 100644 index 000000000..1baca2e4a --- /dev/null +++ b/scalos/Modules/Execute_Command.MUI/Catalogs/deutsch/Scalos/Execute_Command.ct @@ -0,0 +1,223 @@ +; Execute_Command.ct +## version $VER: Execute_Command.catalog 40.1 (20 Feb 2005 22:02:39) +## codeset 0 +## language deutsch +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Execute_Command +; +; +MSGID_OKBUTTON +Ausführen +;Execute +; +; +MSGID_OKBUTTON_SHORT +r +; +; +MSGID_SHORTHELP_OKBUTTON +Save the changed icon.\n\ +If necessary, a new icon will be\n\ +created from a the default icon. +; +; +MSGID_CANCELBUTTON +Abbrechen +;Cancel +; +; +MSGID_CANCELBUTTON_SHORT +a +;c +; +; +MSGID_SHORTHELP_CANCELBUTTON +Änderungen verwerfen und\n\ +keinen Befehl ausführen. +;Discard all changes and\n\ +;do not execute any command. +; +; +MSGID_CREATE_APPLICATION_FAILED +Fehler beim Erzeugen der Anwendung.\n +;Failed to create Application.\n +; +; +MSGID_CREATE_MAINWINDOW_FAILED +Fehler beim Öffnen des Hauptfensters!\n +;Failed to open main window !\n +; +; +MSGID_OPEN_LIBRARY_FAILED +Fehler beim Öffnen von \"%s\" !\n +;Failed to open \"%s\" !\n +; +;-------------------------------- +; +MSGID_MENU_PROJECT +Projekt +;Project +; +; +MSGID_MENU_PROJECT_ABOUT +Über... +;About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Über MUI... +;About MUI... +; +; +MSGID_MENU_PROJECT_QUIT +Beenden +;Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Execute_Command.module V%ld.%ld\033n\n\ +%s\n\ +© 2004%s Das Scalos-Team +;\33c\033bScalos Execute_Command.module V%ld.%ld\033n\n\ +;%s\n\ +;© 2004%s The Scalos Team +; +;----------------------------------------------------------- +; +; +MSGID_TEXT_ENTER_COMMAND +Befehl und Parameter: +;Enter command and its arguments: +; +; +MSGID_LABEL_COMMAND +Befehl: +;Command: +; +; +MSGID_TITLE_ERRORREQ +Eceute_Command Fehler +;Execute_Command Error +; +; +MSGID_CURRENTDIR +Aktuelles Verzeichnis: "%s" +; Current dir: "%s" +; +; +MSGID_CURRENTDIR_SHORTHELP +Aktuelles Verzeichnis.\n\ +Bei langen Verzeichnisnamen kann der ganze Inhalt mit\n\ +dem Rollbalken am unteren Fensterrand angezeigt werden. +;Current dir.\n\n\ +;It's possible to show all content of this gadget using\n\ +;the scroller located at the bottom of the window.\n\ +;Can be usefull for large path lenght. +; +; +MSGID_ERRORREQ_BODYTEXT +Konnte Befehl\n\ +\"%s\" nicht ausführen\n\ +%s +;Could not execute command\n\ +;\"%s\"\n\ +;%s +; +; +MSGID_REQ_OK +Ok +; +; +MSGID_ASL_REQUESTER_SHORTHELP +Öffnet einen Dateiauswahldialog, in dem das\n\ +auszuführende Programm ausgewählt werden kann. +;Open a ASL file requeter\n\ +;and choose a file to execute.\n\ +; +; +MSGID_COMMAND_ASLTITLE +Auszuführenden Befehl wählen +;Select file to execute +; +; +MSGID_LABEL_STACK +Stackgröße: +;Stack: +; +; +MSGID_GET_DEFSTACK_SHORTHELP +Standardgröße für Stack benutzen. +;Use default stack size +; +; +MSGID_LABEL_CHECKQUIT +Dialogfenster geöffnet lassen +;Stay opened +; +; +MSGID_CHECKQUIT_SHORTHELP +When diese Option eingeschaltet ist, bleibt das\n\ +Fenster vom Execute_Command.module auch nach\n\ +dem Start einer Anwendung offen. +;If selected, Execute_Command.module\n\ +;stay opened after execution. +; +; +MSGID_CONSOLE_NAME +Scalos Execute_Command Ausgabefenster +;Scalos Execute_Command Output Window +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Execute_Command.module kann nicht gestartet werden +;Execute_Command.module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Wiederholen|Beenden +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\ +Die Klasse ist nicht installiert. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Sie haben momentan Version v%lu.%lu installiert und\n\ +sollten die Klasse daher aktualisieren! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Version %lu.%lu wird momentan von einer anderen Anwendung\n\ +verwendet. Wenn sie die benötigte Version installiert haben,\n\ +schließen sie alle MUI Programme und probieren es erneut. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- diff --git a/scalos/Modules/Execute_Command.MUI/Catalogs/deutsch/Scalos/config.mk b/scalos/Modules/Execute_Command.MUI/Catalogs/deutsch/Scalos/config.mk new file mode 100755 index 000000000..8631b0623 --- /dev/null +++ b/scalos/Modules/Execute_Command.MUI/Catalogs/deutsch/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = deutsch + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = german + +else + +############################################################################### +# AmigaOS and AROS + +LANG = deutsch + +endif +endif diff --git a/scalos/Modules/Execute_Command.MUI/Catalogs/deutsch/Scalos/makefile b/scalos/Modules/Execute_Command.MUI/Catalogs/deutsch/Scalos/makefile new file mode 100644 index 000000000..9d6a70194 --- /dev/null +++ b/scalos/Modules/Execute_Command.MUI/Catalogs/deutsch/Scalos/makefile @@ -0,0 +1,14 @@ +# makefile for Execute_Command.module (translated Texts : deutsch) +# $Date$ +# $Revision$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mdeutsch\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +Execute_Command.catalog : Execute_Command.ct ../../../Execute_Command.cd + +All: Execute_Command.catalog diff --git a/scalos/Modules/Execute_Command.MUI/Catalogs/deutsch/Scalos/makefile-new b/scalos/Modules/Execute_Command.MUI/Catalogs/deutsch/Scalos/makefile-new new file mode 100644 index 000000000..1d698fdca --- /dev/null +++ b/scalos/Modules/Execute_Command.MUI/Catalogs/deutsch/Scalos/makefile-new @@ -0,0 +1,30 @@ +# makefile for Execute_Command.module (translated Texts : deutsch) +# $Date: 2011-07-24 10:11:00 +0200 (So, 24. Jul 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = Execute_Command + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git "a/scalos/Modules/Execute_Command.MUI/Catalogs/fran\303\247ais/Scalos/Execute_Command.ct" "b/scalos/Modules/Execute_Command.MUI/Catalogs/fran\303\247ais/Scalos/Execute_Command.ct" new file mode 100755 index 000000000..8e8f735e5 --- /dev/null +++ "b/scalos/Modules/Execute_Command.MUI/Catalogs/fran\303\247ais/Scalos/Execute_Command.ct" @@ -0,0 +1,233 @@ +; Execute_Command.ct +; $Date$ +; $Revision$ +; +## version $VER: Execute_Command.catalog 40.1 (20 Feb 2005 20:27:40) +## codeset 0 +## language français +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Executer une commande +; Scalos Execute command +; +; +MSGID_OKBUTTON +Executer +; Execute +; +; +MSGID_OKBUTTON_SHORT +e +; r +; +; +MSGID_SHORTHELP_OKBUTTON +Execute l'objet d'après\n\ +le contenu du champ de texte. +; Execute_Command the object as\n\ +; the string gadget's content. +; +; +MSGID_CANCELBUTTON +Annuler +; Cancel +; +; +MSGID_CANCELBUTTON_SHORT +a +; c +; +; +MSGID_SHORTHELP_CANCELBUTTON +Oublier tout changement en cours et\n\ +n'executer aucune commande. +; Discard all changes and\n\ +; do not execute any command. +; +; +MSGID_CREATE_APPLICATION_FAILED +La création de l'application a échouée.\n +; Failed to create Application.\n +; +; +MSGID_CREATE_MAINWINDOW_FAILED +Impossible d'ouvrir la fenêtre !\n +; Failed to open main window !\n +; +; +MSGID_OPEN_LIBRARY_FAILED +Impossible d'ouvrir "%s" !\n +; Failed to open "%s" !\n +; +;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Projet +; Project +; +; +MSGID_MENU_PROJECT_ABOUT +A propos... +; About... +; +MSGID_MENU_PROJECT_ABOUTMUI +A propos de MUI... +; About MUI... +; +; +MSGID_MENU_PROJECT_QUIT +Quitter +; Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; Q +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +D'acc_ord +; _OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Execute_Command.module V\0333%ld\0332.\0333%ld\0332\033n\n\ +Compilé sous : \0333%s\0332\n\ +© 2004%s The Scalos Team +; \33c\033bScalos Execute_Command.module V%ld.%ld\033n\n\ +; %s\n\ +; © 2004%s The Scalos Team +; +;----------------------------------------------------------- +; +; +MSGID_TEXT_ENTER_COMMAND +Entrez une commande et ses arguments\033n +; Enter command and its arguments: +; +; +MSGID_LABEL_COMMAND +\033bCommande \033n: +; Command: +; +; +MSGID_TITLE_ERRORREQ +Execute_Command Erreur +; Execute_Command Error +; +; +MSGID_CURRENTDIR +\033bRépertoire courant\033n : "%s" +; Current dir: \"%s\" +; +; +MSGID_CURRENTDIR_SHORTHELP +Chemin d'accès de l'élément.\n\n\ +Si besoin, vous avez la possibilité d'utiliser\n\ +l'ascenseur siué au bas de la fenêtre\n\ +afin de visionner le chemin d'accès\n\ +complet de l'élément.\n\ +Peut s'avèrer utile pour de longs chemins d'accès. +; Current dir.\n\n\ +; It's possible to show all content of this gadget using\n\ +; the scroller located at the bottom of the window.\n\ +; Can be usefull for large path lenght. +; +; +MSGID_ERRORREQ_BODYTEXT +Impossible d'executer la commande\n\ +"%s"\n\ +%s +; Could not execute command\n\ +; "%s"\n\ +; %s +; +MSGID_REQ_OK +D'acc_ord +; _Ok +; +MSGID_ASL_REQUESTER_SHORTHELP +executer un fichier à l'aide\n\ +de la requête de fichiers ASL. +; Open a ASL file requeter\n\ +; and choose a file to execute.\n\ +; +; +MSGID_COMMAND_ASLTITLE +Seléction d'un fichier à executer... +; Select file to execute +; +; +MSGID_LABEL_STACK +\033bPile\033n : +; Stack: +; +; +MSGID_GET_DEFSTACK_SHORTHELP +Utiliser la taille de la pile\n\ +fixée par défaut. +; +; +MSGID_LABEL_CHECKQUIT +\033bNe pas quitter\033n +; Stay opened +; +; +MSGID_CHECKQUIT_SHORTHELP +Sélectionné, Execute Command restera ouvert\n\ +aprés la fin de l'execution d'une commande. +; If selected, Execute_Command.module\n\ +; stay opened after execution. +; +; +MSGID_CONSOLE_NAME +Scalos - Executer une commande - Fenêtre de sortie +; Scalos Execute_Command Output Window +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Le lancement de Execute_Command.module a échoué +;Execute_Command.module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Recommençer | Quitter +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +Celle-ci n'est pas installée. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +\n\ +La version installée est V%lu.%lu, installez-en une plus récente s'il vous plaît ! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +%lu.%lu est actuellement utilisée par d'autres applications.\n\ +\n\ +Une fois la version requise installée,\n\ +fermez tous les programmes MUI, soyez sûr que l'ancienne classe\n\ +ne soit plus présente dans la mémoire puis, essayez de nouveau. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; diff --git "a/scalos/Modules/Execute_Command.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" "b/scalos/Modules/Execute_Command.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" new file mode 100755 index 000000000..d7f9d6869 --- /dev/null +++ "b/scalos/Modules/Execute_Command.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = français + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = french + +else + +############################################################################### +# AmigaOS and AROS + +LANG = français + +endif +endif diff --git "a/scalos/Modules/Execute_Command.MUI/Catalogs/fran\303\247ais/Scalos/makefile" "b/scalos/Modules/Execute_Command.MUI/Catalogs/fran\303\247ais/Scalos/makefile" new file mode 100644 index 000000000..53672d0ba --- /dev/null +++ "b/scalos/Modules/Execute_Command.MUI/Catalogs/fran\303\247ais/Scalos/makefile" @@ -0,0 +1,14 @@ +# makefile for Execute_Command.module (translated Texts : français) +# $Date$ +# $Revision$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mfrançais\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +Execute_Command.catalog : Execute_Command.ct ../../../Execute_Command.cd + +All: Execute_Command.catalog diff --git "a/scalos/Modules/Execute_Command.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" "b/scalos/Modules/Execute_Command.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" new file mode 100644 index 000000000..9032a0041 --- /dev/null +++ "b/scalos/Modules/Execute_Command.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" @@ -0,0 +1,30 @@ +# makefile for Execute_Command.module (translated Texts : français) +# $Date: 2011-07-24 10:11:00 +0200 (So, 24. Jul 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = Execute_Command + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Modules/Execute_Command.MUI/Catalogs/sample/Scalos/Execute_Command.ct b/scalos/Modules/Execute_Command.MUI/Catalogs/sample/Scalos/Execute_Command.ct new file mode 100644 index 000000000..8a546a119 --- /dev/null +++ b/scalos/Modules/Execute_Command.MUI/Catalogs/sample/Scalos/Execute_Command.ct @@ -0,0 +1,173 @@ +; Execute_Command.ct +## version $VER: Execute_Command.catalog 40.1 (26 Feb 2005 22:01:34) +## codeset 0s +## language xxxxxx +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Execute_Command +; +; +MSGID_OKBUTTON +Execute +; +; +MSGID_OKBUTTON_SHORT +r +; +; +MSGID_SHORTHELP_OKBUTTON +Execute command as stated in \n\ +the string gadget's content. +; +; +MSGID_CANCELBUTTON +Cancel +; +; +MSGID_CANCELBUTTON_SHORT +c +; +; +MSGID_SHORTHELP_CANCELBUTTON +Discard all changes and\n\ +do not execute any command. +; +; +MSGID_CREATE_APPLICATION_FAILED +Failed to create Application.\n +; +; +MSGID_CREATE_MAINWINDOW_FAILED +Failed to open main window !\n +; +; +MSGID_OPEN_LIBRARY_FAILED +Failed to open \"%s\" !\n +; +;;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Project +; +; +MSGID_MENU_PROJECT_ABOUT +About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI +About MUI... +; +; +MSGID_MENU_PROJECT_QUIT +Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Execute_Command.module V%ld.%ld\033n\n\ +%s\n\ +© 2004%s The Scalos Team +; +;----------------------------------------------------------- +; +; +MSGID_TEXT_ENTER_COMMAND +Enter command and its arguments: +; +; +MSGID_LABEL_COMMAND +Command: +; +; +MSGID_TITLE_ERRORREQ +Execute_Command Error +; +; +MSGID_CURRENTDIR +Current dir: "%s" +; +; +MSGID_CURRENTDIR_SHORTHELP +Current dir.\n\n\ +It's possible to show all content of this gadget using\n\ +the scroller located at the bottom of the window.\n\ +Can be usefull for large path lenght. +; +; +MSGID_ERRORREQ_BODYTEXT +Could not execute command\n\ +\"%s\"\n\ +%s +; +; +MSGID_REQ_OK + _Ok +; +; +MSGID_ASL_REQUESTER_SHORTHELP +Open a ASL file requeter\n\ +and choose a file to execute.\n\ +; +; +MSGID_COMMAND_ASLTITLE +Select file to execute +; +; +MSGID_LABEL_STACK +Stack: +; +; +MSGID_GET_DEFSTACK_SHORTHELP +Use default stack size +; +; +MSGID_LABEL_CHECKQUIT +Stay opened +; +; +MSGID_CHECKQUIT_SHORTHELP +If selected, Execute_Command.module\n\ +stay opened after execution. +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Execute_Command.module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +; +;----------------------------------------------------------- +; diff --git a/scalos/Modules/Execute_Command.MUI/Execute_Command.c b/scalos/Modules/Execute_Command.MUI/Execute_Command.c new file mode 100755 index 000000000..f57b8ff2d --- /dev/null +++ b/scalos/Modules/Execute_Command.MUI/Execute_Command.c @@ -0,0 +1,1226 @@ +// Execute_Command.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // +jmc+ +#include +#include // +jmc+ + +#include +#include //+jmc+ + +#include +#include +#include +#include +#include // +jmc+ +#include // +jmc+ +#include // +jmc+ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include // +jmc+ + +#include "Execute_Command.h" + +#define Execute_Command_NUMBERS +#define Execute_Command_ARRAY +#define Execute_Command_CODE +#include STR(SCALOSLOCALE) + +//---------------------------------------------------------------------------- + +#define VERSION_MAJOR 40 +#define VERSION_MINOR 4 + +//---------------------------------------------------------------------------- + +#define Application_Return_Ok 1001 +#define Application_Return_OpenAsl 1002 +#define Application_Return_GetDefStack 1003 + +//---------------------------------------------------------------------------- + +#define KeyButtonHelp(name,key,HelpText)\ + TextObject,\ + ButtonFrame,\ + MUIA_Font, MUIV_Font_Button,\ + MUIA_Text_Contents, name,\ + MUIA_Text_PreParse, "\33c",\ + MUIA_Text_HiChar , key,\ + MUIA_ControlChar , key,\ + MUIA_InputMode , MUIV_InputMode_RelVerify,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShortHelp , HelpText,\ + MUIA_CycleChain , TRUE,\ + End + +#define CheckMarkHelp(InputMode, Selected, Image,HelpTextID, NumID)\ + ImageObject,\ + ImageButtonFrame,\ + MUIA_InputMode , InputMode,\ + MUIA_Image_Spec , Image,\ + MUIA_Image_FreeVert , TRUE,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShowSelState , Selected,\ + MUIA_CycleChain , TRUE,\ + MUIA_ShortHelp , GetLocString(HelpTextID), \ + MUIA_ExportID , NumID, \ + End + +//---------------------------------------------------------------------------- + +static BOOL OpenLibraries(void); +static void CloseLibraries(void); +static void ReportError(LONG Result, CONST_STRPTR CmdString); + +static LONG ExecuteCommand(struct WBArg *arg); + +static void InitCurrent(struct WBArg *arg); //+jmc+ +static void WBLRequestFile(struct WBArg *arg); //+jmc+ + +static SAVEDS(APTR) INTERRUPT OpenAboutMUIHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT OpenAboutHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT StringMUIHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT IntegerMUIHookFunc(struct Hook *hook, Object *o, Msg msg); + +static STRPTR GetLocString(ULONG MsgId); +static BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev); +static STRPTR BuildConsole(STRPTR wtitle, struct Screen *scr); //+jmc+ +static void MakeAPPSleep(BOOL etat); //+jmc+ +static BOOL TrackSpace(STRPTR Buffer); //+jmc+ +static BOOL FindURL(STRPTR StringExec); //+jmc+ +static void GetDefStack(void); //+jmc+ +BPTR DupWBPathList(void); //+jmc+ +static void SaveToEnv(void); //+jmc+ + +//---------------------------------------------------------------------------- + +#if !defined(__AROS__) && !defined(__amigaos4__) +#include + +long _stack = 16384; // minimum stack size, used by SAS/C startup code +#endif + +//---------------------------------------------------------------------------- + +extern struct ExecBase *SysBase; +struct IntuitionBase *IntuitionBase = NULL; +T_LOCALEBASE LocaleBase = NULL; +#ifndef __amigaos4__ +T_UTILITYBASE UtilityBase = NULL; +#endif +struct Library *MUIMasterBase = NULL; +struct ScalosBase *ScalosBase = NULL; //+jmc+ + +#ifdef __amigaos4__ +struct IntuitionIFace *IIntuition = NULL; +struct LocaleIFace *ILocale = NULL; +struct MUIMasterIFace *IMUIMaster = NULL; +struct ScalosIFace *IScalos = NULL; +#endif + +static struct Catalog *gb_Catalog; + +static struct Hook AboutHook = { { NULL, NULL }, HOOKFUNC_DEF(OpenAboutHookFunc), NULL }; +static struct Hook AboutMUIHook = { { NULL, NULL }, HOOKFUNC_DEF(OpenAboutMUIHookFunc), NULL }; +static struct Hook StringMUIHook = { { NULL, NULL }, HOOKFUNC_DEF(StringMUIHookFunc), NULL }; //+jmc+ +static struct Hook IntegerMUIHook = { { NULL, NULL }, HOOKFUNC_DEF(IntegerMUIHookFunc), NULL }; //+jmc+ + +static struct Screen *scr; //+jmc+ + +//---------------------------------------------------------------------------- + +static Object *Group_Buttons2; +static Object *APP_Main; +static Object *WIN_Main; +static Object *WIN_AboutMUI; +static Object *OkButton, *CancelButton; +static Object *MenuAbout, *MenuAboutMUI, *MenuQuit; +static Object *TextEnterCommand; +static Object *PopAslCommand; +static Object *StringName; // +jmc+ String gadget replacing PopaslObject. +static Object *TextEnterName; // +jmc+ TextObject for Current dir. +static Object *CheckQuit; // +jmc+ CheckMark to quit or notafter execute command finished. +static Object *Group_Virtual; //+jmc+ To switch 0/1 "MUIA_ShowMe" the ScroolGroupObject group. +static Object *StringStack; //+jmc+ Stack integer +static Object *GetStack; //+jmc+ Get default stack button +static BOOL Run = TRUE; +static BOOL Success = FALSE; +static ULONG stackNum; //+jmc+ +static ULONG oldstackNum=0; //+jmc+ +static ULONG PrevInteger; //+jmc+ + +//---------------------------------------------------------------------------- + +int main(int argc, char *argv[]) +{ + LONG win_opened = 0; + struct WBStartup *WBenchMsg = + (argc == 0) ? (struct WBStartup *)argv : NULL; + +#if 0 + if (WBenchMsg) + { + LONG n; + + // kprintf("NumArgs=%ld\n", WBenchMsg->sm_NumArgs); + + for (n=0; nsm_NumArgs; n++) + { + char xName[512]; + + NameFromLock(WBenchMsg->sm_ArgList[n].wa_Lock, xName, sizeof(xName)); + + // kprintf("%ld. Lock=<%s> Name=<%s>\n", n, xName, WBenchMsg->sm_ArgList[n].wa_Name); + } + } +#endif + + if (NULL == WBenchMsg) + { + return 5; + } + + if (WBenchMsg->sm_NumArgs < 2) + { + return 5; + } + + do { + ULONG sigs = 0; + ULONG QuitSelected = 0; + ULONG StackSelected = 0; + + struct WBArg *arg = &WBenchMsg->sm_ArgList[1]; + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + if (!OpenLibraries()) + break; + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + if (!CheckMCCVersion(MUIC_BetterString, 11, 0)) + break; + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + GetDefStack(); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + gb_Catalog = OpenCatalogA(NULL, "Scalos/Execute_Command.catalog",NULL); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + APP_Main = ApplicationObject, + MUIA_Application_Title, GetLocString(MSGID_TITLENAME), + MUIA_Application_Version, "$VER: Scalos Execute_Command.module V40.5 (" __DATE__ ") " COMPILER_STRING, + MUIA_Application_Copyright, "© The Scalos Team, 2004" CURRENTYEAR, + MUIA_Application_Author, "The Scalos Team", + MUIA_Application_Description, "Scalos Execute_Command module", + MUIA_Application_Base, "SCALOS_EXECUTE_COMMAND", + + SubWindow, WIN_Main = WindowObject, + MUIA_Window_Title, GetLocString(MSGID_TITLENAME), +// MUIA_Window_ID, MAKE_ID('M','A','I','N'), + MUIA_Window_AppWindow, TRUE, + MUIA_Window_UseBottomBorderScroller, TRUE, // +jmc+ + + MUIA_Window_TopEdge, MUIV_Window_TopEdge_Moused, + MUIA_Window_LeftEdge, MUIV_Window_LeftEdge_Moused, + + MUIA_Window_Width, MUIV_Window_Width_Screen(30), //+jmc+ + + WindowContents, VGroup, + Child, GroupObject, // +jmc+ + Child, Group_Virtual = ScrollgroupObject, + MUIA_Scrollgroup_VertBar, NULL, + MUIA_Scrollgroup_HorizBar, NULL, + MUIA_Scrollgroup_FreeHoriz, TRUE, + MUIA_Scrollgroup_FreeVert, FALSE, + MUIA_Scrollgroup_UseWinBorder, TRUE, + MUIA_Scrollgroup_Contents, + VirtgroupObject, + Child, TextEnterName = TextObject, + MUIA_Text_PreParse, MUIX_C, + MUIA_ShortHelp, GetLocString(MSGID_CURRENTDIR_SHORTHELP), + End, //TextObject + End, //VirtgroupObject + End, //ScrollgroupObject + End, //GroupObject + + Child, VGroup, + Child, TextEnterCommand = TextObject, + MUIA_Text_PreParse, MUIX_C, + MUIA_Text_Contents, GetLocString(MSGID_TEXT_ENTER_COMMAND), + End, //TextObject + + Child, VSpace(1), + + Child, HGroup, MUIA_Group_Spacing, 0, + Child, Label1(GetLocString(MSGID_LABEL_COMMAND)), + Child, StringName = BetterStringObject, + StringFrame, + MUIA_String_Contents, "", + MUIA_CycleChain, TRUE, + MUIA_ExportID, 1, + End, //BetterStringObject + Child, PopAslCommand = CheckMarkHelp(MUIV_InputMode_RelVerify, TRUE,\ + MUII_PopFile,\ + MSGID_ASL_REQUESTER_SHORTHELP, NULL), + End, //HGroup + End, //VGroup + + Child, HGroup, + Child, RectangleObject, + End, + Child, Label1(GetLocString(MSGID_LABEL_STACK)), + Child, HGroup, MUIA_Group_Spacing, 0, + Child, StringStack = BetterStringObject, StringFrame, + MUIA_String_Integer, stackNum, + MUIA_String_Accept , "0123456789", + MUIA_String_Format, MUIV_String_Format_Center, + MUIA_CycleChain, TRUE, + End, // BetterStringObject + Child, GetStack = CheckMarkHelp(MUIV_InputMode_Toggle, FALSE,\ + MUII_CheckMark,\ + MSGID_GET_DEFSTACK_SHORTHELP, NULL), + End, //HGroup + + Child, HGroup, + Child, Label1(GetLocString(MSGID_LABEL_CHECKQUIT)), + Child, CheckQuit = CheckMarkHelp(MUIV_InputMode_Toggle, FALSE,\ + MUII_CheckMark,\ + MSGID_CHECKQUIT_SHORTHELP,2), + + End, // HGroup + Child, RectangleObject, + End, + End, // HGroup + + Child, Group_Buttons2 = HGroup, + MUIA_Group_SameWidth, TRUE, + Child, OkButton = KeyButtonHelp(GetLocString(MSGID_OKBUTTON), + *GetLocString(MSGID_OKBUTTON_SHORT), GetLocString(MSGID_SHORTHELP_OKBUTTON)), + Child, CancelButton = KeyButtonHelp(GetLocString(MSGID_CANCELBUTTON), + *GetLocString(MSGID_CANCELBUTTON_SHORT), GetLocString(MSGID_SHORTHELP_CANCELBUTTON)), + End, //HGroup + End, //VGroup + + End, //WindowObject + + MUIA_Application_Menustrip, MenustripObject, + Child, MenuObjectT(GetLocString(MSGID_MENU_PROJECT)), + + Child, MenuAbout = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUT), + End, + Child, MenuAboutMUI = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUTMUI), + End, + Child, MenuitemObject, + MUIA_Menuitem_Title, -1, + End, + Child, MenuQuit = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_QUIT), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_PROJECT_QUIT_SHORT), + End, + + End, //MenuObjectT + End, //MenuStripObject + + End; //ApplicationObject + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + if (NULL == APP_Main) + { + printf(GetLocString(MSGID_CREATE_APPLICATION_FAILED)); + break; + } + + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + WIN_Main, 3, MUIM_Set, MUIA_Window_Open, FALSE); + + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + + DoMethod(CancelButton, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + DoMethod(OkButton, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_Application_ReturnID, Application_Return_Ok); + + DoMethod(PopAslCommand, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_Application_ReturnID, Application_Return_OpenAsl); + + + DoMethod(StringName, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, + APP_Main, 2, MUIM_Application_ReturnID, Application_Return_Ok); + + DoMethod(StringStack, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, + APP_Main, 2, MUIM_Application_ReturnID, Application_Return_GetDefStack); + + + DoMethod(CheckQuit, MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + WIN_Main, 3, MUIM_Set, MUIA_Window_ActiveObject, StringName); + + DoMethod(GetStack, MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + APP_Main, 3, MUIM_Application_ReturnID, Application_Return_GetDefStack); + + + DoMethod(StringName, MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + StringName, 3, MUIM_CallHook, &StringMUIHook); + + DoMethod(StringStack, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, + StringStack, 2, MUIM_CallHook, &IntegerMUIHook); + + DoMethod(MenuAbout, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &AboutHook); + + DoMethod(MenuAboutMUI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &AboutMUIHook); + + DoMethod(MenuQuit, MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + + set(WIN_Main, MUIA_Window_ActiveObject, StringName); + + set(GetStack, MUIA_Selected, TRUE); + + // Loading of MUI objects ID settings. + DoMethod(APP_Main, MUIM_Application_Load,MUIV_Application_Load_ENV); + + InitCurrent(arg); + + set(WIN_Main, MUIA_Window_Open, TRUE); + get(WIN_Main, MUIA_Window_Open, &win_opened); + + if (!win_opened) + { + printf(GetLocString(MSGID_CREATE_MAINWINDOW_FAILED)); + break; + } + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: \n", __LINE__)); + + while (Run) + { + ULONG Action = DoMethod(APP_Main, MUIM_Application_NewInput, &sigs); + + switch (Action) + { + case Application_Return_Ok: + ExecuteCommand(&WBenchMsg->sm_ArgList[1]); + SaveToEnv(); + get(CheckQuit, MUIA_Selected, &QuitSelected); + if (!QuitSelected) + Run = FALSE; + break; + case Application_Return_OpenAsl: + set(Group_Virtual, MUIA_ShowMe, 0); + WBLRequestFile(arg); + set(Group_Virtual, MUIA_ShowMe, 1); + if (Success) + { + SaveToEnv(); + get(CheckQuit, MUIA_Selected, &QuitSelected); + // kprintf("QuitSelected= [%ld] Success=[%ld]\n", QuitSelected, Success); + if (!QuitSelected) + Run = FALSE; + } + break; + case Application_Return_GetDefStack: + GetDefStack(); + // kprintf("Selected: oldstackNum =[ %ld ] stackNum=[ %ld ]\n", oldstackNum, stackNum); + get(GetStack, MUIA_Selected, &StackSelected); + if(oldstackNum>=stackNum) + { + if(StackSelected) + { + set(StringStack, MUIA_String_Integer, stackNum); + set(StringStack, MUIA_Disabled, TRUE); + } + else + { + set(StringStack, MUIA_Disabled, FALSE); + set(StringStack, MUIA_String_Integer, oldstackNum); + set(WIN_Main, MUIA_Window_ActiveObject, StringStack); + } + } + else + { + set(StringStack, MUIA_String_Integer, stackNum); + set(StringStack, MUIA_Disabled, TRUE); + oldstackNum=stackNum; + } + // kprintf("oldstackNum =[ %ld ] stackNum=[ %ld ]\n", oldstackNum, stackNum); + break; + case MUIV_Application_ReturnID_Quit: + Run = FALSE; + break; + } + + if (Run && sigs) + { + sigs = Wait(sigs | SIGBREAKF_CTRL_C); + + if (sigs & SIGBREAKF_CTRL_C) + { + Run = FALSE; + } + } + } + } while (0); + + set(WIN_Main, MUIA_Window_Open, FALSE); + + if (APP_Main) + MUI_DisposeObject(APP_Main); + if(gb_Catalog) + CloseCatalog(gb_Catalog); + + CloseLibraries(); + + return 0; +} + +//---------------------------------------------------------------------------- +// +jmc+ +// Export all IDs of MUI objects to ENV:MUI. +// Availlable for "Application_Return_Ok" and "Application_Return_OpenAsl", + +static void SaveToEnv(void) +{ + DoMethod(APP_Main, MUIM_Application_Save,MUIV_Application_Save_ENV); +} + +//---------------------------------------------------------------------------- + +static BOOL OpenLibraries(void) +{ + ScalosBase = (struct ScalosBase *) OpenLibrary("scalos.library", 40); + if (NULL == ScalosBase) + return FALSE; +#ifdef __amigaos4__ + IScalos = (struct ScalosIFace *)GetInterface((struct Library *)ScalosBase, "main", 1, NULL); + if (NULL == IScalos) + return FALSE; +#endif + + MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN-1); + if (NULL == MUIMasterBase) + return FALSE; +#ifdef __amigaos4__ + IMUIMaster = (struct MUIMasterIFace *)GetInterface((struct Library *)MUIMasterBase, "main", 1, NULL); + kprintf("MUIMasterBase = %lx, IMUIMaster = %lx\n", MUIMasterBase, IMUIMaster); + if (NULL == IMUIMaster) + return FALSE; + +#endif + + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + if (NULL == IntuitionBase) + return FALSE; +#ifdef __amigaos4__ + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + return FALSE; +#endif + + LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 38); + if (NULL == LocaleBase) + return FALSE; +#ifdef __amigaos4__ + ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL); + if (NULL == ILocale) + return FALSE; +#endif + +#ifndef __amigaos4__ + UtilityBase = (T_UTILITYBASE) OpenLibrary("utility.library", 39); + if (NULL == UtilityBase) + return FALSE; +#endif + + return TRUE; +} + +//---------------------------------------------------------------------------- + +static void CloseLibraries(void) +{ +#ifndef __amigaos4__ + if (UtilityBase) + { + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } +#endif +#ifdef __amigaos4__ + if (ILocale) + { + DropInterface((struct Interface *)ILocale); + ILocale = NULL; + } +#endif + if (LocaleBase) + { + CloseLibrary((struct Library *) LocaleBase); + LocaleBase = NULL; + } +#ifdef __amigaos4__ + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } +#endif + if (IntuitionBase) + { + CloseLibrary((struct Library *)IntuitionBase); + IntuitionBase = NULL; + } +#ifdef __amigaos4__ + if (IMUIMaster) + { + DropInterface((struct Interface *)IMUIMaster); + IMUIMaster = NULL; + } +#endif + if (MUIMasterBase) + { + CloseLibrary(MUIMasterBase); + MUIMasterBase = NULL; + } +#ifdef __amigaos4__ + if (IScalos) + { + DropInterface((struct Interface *)IScalos); + IScalos = NULL; + } +#endif + if (ScalosBase) + { + CloseLibrary(&ScalosBase->scb_LibNode); + ScalosBase = NULL; + } +} + +//---------------------------------------------------------------------------- + +static void ReportError(LONG Result, CONST_STRPTR CmdString) +{ + char FaultText[256]; + + Fault(Result, "", FaultText, sizeof(FaultText)); + + MUI_Request(APP_Main, WIN_Main, 0, NULL, + GetLocString(MSGID_REQ_OK), + GetLocString(MSGID_ERRORREQ_BODYTEXT), + CmdString, FaultText); +} + +//---------------------------------------------------------------------------- +// +jmc+ +static void MakeAPPSleep(BOOL etat) +{ + set(APP_Main, MUIA_Application_Sleep, etat); +} + + +//---------------------------------------------------------------------------- +// +jmc+ +static void GetDefStack(void) +{ + SCA_ScalosControl(NULL, + SCALOSCTRLA_GetDefaultStackSize, (ULONG) &stackNum, + TAG_END); +} + +//---------------------------------------------------------------------------- +// +jmc+ +static void InitCurrent(struct WBArg *arg) +{ + char xName[512]; + char LabelText[512]; + char SpaceName[256]; + STRPTR LastContent = NULL; + + NameFromLock(arg->wa_Lock, xName, sizeof(xName)); + sprintf(LabelText, GetLocString(MSGID_CURRENTDIR), xName); + + set(TextEnterName, MUIA_Text_Contents, LabelText); + + if (arg->wa_Name && strlen(arg->wa_Name) > 0) + { + BOOL Space; + + if ( Space = TrackSpace(arg->wa_Name) ) + sprintf(SpaceName, "\"%s\"", arg->wa_Name); + else + stccpy(SpaceName, arg->wa_Name, sizeof(SpaceName)); + + set(StringName, MUIA_String_Contents, SpaceName); + set(StringName, MUIA_String_BufferPos, 0); + } + else + { + get(StringName, MUIA_String_Contents, &LastContent); + // stccpy(SpaceName, LastContent, sizeof(SpaceName)); + // if(strlen(SpaceName) == 0) + if(strlen(LastContent) == 0) + set(OkButton, MUIA_Disabled, TRUE); + } + +} + +//---------------------------------------------------------------------------- + +static LONG ExecuteCommand(struct WBArg *arg) +{ + STRPTR CommandString = NULL; + STRPTR StackDisabled = NULL; + BPTR oldDir; + LONG Result = RETURN_OK; + STRPTR conDef = "CON:////Execute_Command/AUTO/CLOSE/WAIT"; + BOOL GetUrl; + + GetDefStack(); + + get(StringStack, MUIA_Disabled, &StackDisabled); + if (!StackDisabled) + set(StringStack, MUIA_String_Acknowledge, TRUE); + else + { + PrevInteger = oldstackNum; + oldstackNum = stackNum; + } + + if(oldstackNum>stackNum) + stackNum = oldstackNum; + + get(StringName, MUIA_String_Contents, &CommandString); + + if ( GetUrl = FindURL(CommandString) ) + { + struct Library *OpenURLBase; +#ifdef __amigaos4__ + struct OpenURLIFace *IOpenURL; +#endif + + OpenURLBase = OpenLibrary(OPENURLNAME, 3); +#ifdef __amigaos4__ + IOpenURL = (struct OpenURLIFace *)GetInterface(OpenURLBase, "main", 1, NULL); + if (NULL == IOpenURL) + { + CloseLibrary(OpenURLBase); + OpenURLBase = NULL; + } +#endif + if (NULL != OpenURLBase) + { + URL_Open(CommandString, + URL_Launch, TRUE, + URL_Show, TRUE, + TAG_DONE); + +#ifdef __amigaos4__ + DropInterface((struct Interface *)IOpenURL); +#endif + CloseLibrary(OpenURLBase); + } + else + printf(GetLocString(MSGID_OPEN_LIBRARY_FAILED), OPENURLNAME); + } + else + { + oldDir = CurrentDir(arg->wa_Lock); + + if(scr = LockPubScreen(NULL)) + { + STRPTR conName; + BOOL ConBuilt = TRUE; + + conName = BuildConsole(GetLocString(MSGID_CONSOLE_NAME),scr); + if(!conName) + { + ConBuilt = FALSE; + conName = conDef; + } + + //SystemTagList() + Result = SystemTags(CommandString, + SYS_Asynch, TRUE, + SYS_Output, NULL, + SYS_Input, Open(conName,MODE_OLDFILE), + SYS_UserShell, TRUE, + NP_StackSize, stackNum, + NP_Path, DupWBPathList(), + TAG_DONE); + + if (ConBuilt) + FreeVec(conName); + + // kprintf("ConBuilt=[ %ld ] - stackNum=[ %ld ] oldstackNum=[ %ld ]\n", ConBuilt, stackNum, oldstackNum); + + if (RETURN_OK != Result) + ReportError(Result, CommandString); + + CurrentDir(oldDir); + + UnlockPubScreen(NULL,scr); + + oldstackNum = PrevInteger; + } + } + return Result; +} + +//---------------------------------------------------------------------------- +// +jmc+ +static BOOL FindURL(STRPTR StringExec) +{ + BOOL URLFound = FALSE; + + if ( (strnicmp("HTTP://",StringExec,7) == 0) || (strnicmp("FILE://",StringExec,7) == 0) + || (strnicmp("FTP://",StringExec,6) == 0) || (strnicmp("MAILTO:",StringExec,7) == 0) ) + URLFound = TRUE; + + return URLFound; +} + +//---------------------------------------------------------------------------- +// +jmc+ +static STRPTR BuildConsole(STRPTR wtitle, struct Screen *scr) +{ + const STATIC STRPTR fmt = "CON:%ld/%ld/%ld/%ld/%s/AUTO/CLOSE/WAIT"; + + STRPTR buf = (STRPTR)AllocVec( strlen(fmt)+strlen(wtitle)+40,0 ); + if(buf) + { + LONG height=280; + LONG width =120; + LONG top=8; + LONG left=8*2; + + if(scr) + { + struct Rectangle rect; + if(QueryOverscan(GetVPModeID( &scr->ViewPort), &rect, OSCAN_TEXT)) + { + height = rect.MaxY - rect.MinY + 1; + width = rect.MaxX - rect.MinX + 1; + } + else + { + height = scr->Height; + width = scr->Width; + } + height = height*25/100; + + width = (width*75/100)-((scr->BarHeight*2)*75/100); + + left = (scr->Width/2)-(width/2)-scr->BarHeight; + + top = -scr->TopEdge; + + if( top <= scr->BarHeight ) + top = scr->BarHeight + 1; + } + + sprintf(buf, fmt, left, top, width, height, wtitle); + // kprintf("buf=<%s>\nLeft=<%ld>\nTop=<%ld>\nWidth=<%ld>\nHeight=<%ld>\nWtitle=<%s>\n\n", buf, left, top, width, height, wtitle); + } + return buf; +} + +//---------------------------------------------------------------------------- + +static STRPTR GetLocString(ULONG MsgId) +{ + struct Execute_Command_LocaleInfo li; + + li.li_Catalog = gb_Catalog; +#ifndef __amigaos4__ + li.li_LocaleBase = LocaleBase; +#else + li.li_ILocale = ILocale; +#endif + + return (STRPTR)GetExecute_CommandString(&li, MsgId); +} + +/* +static void TranslateStringArray(STRPTR *stringArray) +{ + while (*stringArray) + { + *stringArray = GetLocString((ULONG) *stringArray); + stringArray++; + } +} +*/ +//---------------------------------------------------------------------------- +// +jmc+ +static void WBLRequestFile(struct WBArg *arg) +{ + char Path[1024]; + char SpacePath[1024]; + struct FileRequester *fileReq = NULL; + + do { + STRPTR FileName; + Success = FALSE; + + if (!NameFromLock(arg->wa_Lock, Path, sizeof(Path))) + break; + + if (arg->wa_Name && strlen(arg->wa_Name) > 0) + FileName = arg->wa_Name; + else + FileName = ""; + + // AllocAslRequest() + fileReq = AllocAslRequestTags(ASL_FileRequest, + ASLFR_TitleText, (ULONG) GetLocString(MSGID_COMMAND_ASLTITLE), + ASLFR_DoSaveMode, FALSE, + ASLFR_RejectIcons, FALSE, + TAG_END); + + if (NULL == fileReq) + break; + + MakeAPPSleep(TRUE); // APP_Main Sleep + + // AslRequest() + if (AslRequestTags(fileReq, + ASLFR_InitialFile, (ULONG) FileName, + ASLFR_InitialDrawer, (ULONG) Path, + TAG_END)) + Success = TRUE; + else + Success = FALSE; + + MakeAPPSleep(FALSE); // APP_Main Sleep + + if (Success) + { + BPTR dirLock; + char xName[512]; + char LabelText[512]; + BOOL Space; + + dirLock = Lock(fileReq->fr_Drawer, ACCESS_READ); + if ((BPTR)NULL == dirLock) + { + break; + } + + NameFromLock(dirLock, Path, sizeof(Path)); + sprintf(LabelText, GetLocString(MSGID_CURRENTDIR), Path); + stccpy(xName, fileReq->fr_File, sizeof(xName)); + + if (strlen(xName) > 0) + { + AddPart(Path, xName, sizeof(xName)); + } + + set(TextEnterName, MUIA_Text_Contents, LabelText); + + if ( Space = TrackSpace(Path) ) + { + sprintf(SpacePath, "\"%s\"", Path); + set(StringName, MUIA_String_Contents, SpacePath); + // kprintf("Space [%ld] - SpacePath=<%s>\n", Space, SpacePath); + } + else + { + set(StringName, MUIA_String_Contents, Path); + } + + UnLock(arg->wa_Lock); + arg->wa_Lock = dirLock; + arg->wa_Name = NULL; + + ExecuteCommand(arg); + } + } while (0); + + if (fileReq) + FreeAslRequest(fileReq); + +} + +//---------------------------------------------------------------------- +// +jmc+ +static BOOL TrackSpace(STRPTR Buffer) +{ + BOOL FindSpace = FALSE; + LONG i=0; + + while (Buffer[i]) + { + if (Buffer[i] == ' ') + { + FindSpace = TRUE; + break; + } + i++; + } + // kprintf("Lenght = [%ld] - Find Space = [%ld]\n", i, FindSpace); + return FindSpace; +} + +//-------- DupWBPathList() - From in CliStart.c -------------------------- +// +jmc+ +BPTR DupWBPathList(void) +{ + struct Process *wbProc; + struct CommandLineInterface *cli; + struct AssignList *aList, *StartList = NULL, **nList = NULL; + + Forbid(); + wbProc = (struct Process *) FindTask("Workbench"); + Permit(); + + if (NULL == wbProc) + return (BPTR)NULL; + if (NT_PROCESS != wbProc->pr_Task.tc_Node.ln_Type) + return (BPTR)NULL; + + cli = BADDR(wbProc->pr_CLI); + if (NULL == cli) + return (BPTR)NULL; + + aList = BADDR(cli->cli_CommandDir); + if (NULL == aList) + return (BPTR)NULL; + + while (aList) + { + struct AssignList *nNode = AllocVec(sizeof(struct AssignList), MEMF_PUBLIC); + + if (NULL == nNode) + break; + if (NULL == nList) + StartList = nNode; + else + *nList = (struct AssignList *) MKBADDR(nNode); + + nNode->al_Next = NULL; + nNode->al_Lock = DupLock(aList->al_Lock); + nList = &nNode->al_Next; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: aList=%08lx Next=%08lx Lock=%08lx\n", __LINE__, \ + aList, aList->al_Next, aList->al_Lock)); + + aList = BADDR(aList->al_Next); + } + + return MKBADDR(StartList); +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT OpenAboutMUIHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + if (NULL == WIN_AboutMUI) + { + WIN_AboutMUI = MUI_NewObject(MUIC_Aboutmui, + MUIA_Window_RefWindow, WIN_Main, + MUIA_Aboutmui_Application, APP_Main, + End; + } + + if (WIN_AboutMUI) + set(WIN_AboutMUI, MUIA_Window_Open, TRUE); + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT OpenAboutHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + MUI_Request(APP_Main, WIN_Main, 0, NULL, + GetLocString(MSGID_ABOUTREQOK), + GetLocString(MSGID_ABOUTREQFORMAT), + VERSION_MAJOR, VERSION_MINOR, COMPILER_STRING, CURRENTYEAR); +} + +//---------------------------------------------------------------------------- +// +jmc+ +static SAVEDS(void) INTERRUPT StringMUIHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + STRPTR defstring = NULL; + + get(StringName, MUIA_String_Contents, &defstring); + if(defstring && strlen(defstring) > 0) + set(OkButton, MUIA_Disabled, FALSE); + else + set(OkButton, MUIA_Disabled, TRUE); +} + +//---------------------------------------------------------------------------- +// +jmc+ +static SAVEDS(void) INTERRUPT IntegerMUIHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + get(StringStack, MUIA_String_Integer, &PrevInteger); + if(PrevInteger minver || (ver == minver && rev >= minrev)) + { + d1(kprintf(__FILE__ "/%s/%ld: v%ld.%ld found through MUIA_Version/Revision\n", __FUNC__, __LINE__, ver, rev);) + return TRUE; + } + } + + // If we did't get the version we wanted, let's try to open the + // libraries ourselves and see what happens... + stccpy(libname, "PROGDIR:mui", sizeof(libname)); + AddPart(libname, name, sizeof(libname)); + + d1(kprintf(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__);) + + if ((base = OpenLibrary(&libname[8], 0)) || (base = OpenLibrary(&libname[0], 0))) + { + UWORD OpenCnt = base->lib_OpenCnt; + + d1(kprintf(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__);) + + ver = base->lib_Version; + rev = base->lib_Revision; + + CloseLibrary(base); + + // we add some additional check here so that eventual broken .mcc also have + // a chance to pass this test (i.e. Toolbar.mcc is broken) + if (ver > minver || (ver == minver && rev >= minrev)) + { + d1(kprintf(__FILE__ "/%s/%ld: v%ld.%ld found through OpenLibrary()\n", __FUNC__, __LINE__, ver, rev);) + return TRUE; + } + + if (OpenCnt > 1) + { + if (MUI_Request(NULL, NULL, 0L, GetLocString(MSGID_STARTUP_FAILURE), + GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), GetLocString(MSGID_STARTUP_MCC_IN_USE), + name, minver, minrev, ver, rev)) + { + flush = TRUE; + } + else + break; + } + + // Attempt to flush the library if open count is 0 or because the + // user wants to retry (meaning there's a chance that it's 0 now) + + if (flush) + { + struct Library *result; + + Forbid(); + if ((result = (struct Library *) FindName(&((struct ExecBase *)SysBase)->LibList, name))) + RemLibrary(result); + Permit(); + flush = FALSE; + } + else + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: couldn`t find minimum required version.\n", __LINE__);) + + // We're out of luck - open count is 0, we've tried to flush + // and still haven't got the version we want + if (MUI_Request(NULL, NULL, 0L, GetLocString(MSGID_STARTUP_FAILURE), + GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), GetLocString(MSGID_STARTUP_OLD_MCC), + name, minver, minrev, ver, rev)) + { + flush = TRUE; + } + else + break; + } + } + else + { + d1(kprintf(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__);) + + // No MCC at all - no need to attempt flush + flush = FALSE; + if (!MUI_Request(NULL, NULL, 0L, GetLocString(MSGID_STARTUP_FAILURE), + GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), GetLocString(MSGID_STARTUP_MCC_NOT_FOUND), + name, minver, minrev)) + { + break; + } + } + } + + return FALSE; +} + +//---------------------------------------------------------------------------- + diff --git a/scalos/Modules/Execute_Command.MUI/Execute_Command.cd b/scalos/Modules/Execute_Command.MUI/Execute_Command.cd new file mode 100755 index 000000000..78f07fb11 --- /dev/null +++ b/scalos/Modules/Execute_Command.MUI/Execute_Command.cd @@ -0,0 +1,177 @@ +; Execute_Command.cd +; version $VER: Execute_Command.catalog 40.1 (26 Feb 2005 21:03:45) +; codeset 0s +; language english +; +;#arrayopts static __far +; +; +MSGID_TITLENAME (//) +Scalos Execute_Command +; +; +MSGID_OKBUTTON (//) +Execute +; +; +MSGID_OKBUTTON_SHORT (/1/1) +r +; +; +MSGID_SHORTHELP_OKBUTTON (//) +Execute command as stated in \n\ +the string gadget's content. +; +; +MSGID_CANCELBUTTON (//) +Cancel +; +; +MSGID_CANCELBUTTON_SHORT (/1/1) +c +; +; +MSGID_SHORTHELP_CANCELBUTTON (//) +Discard all changes and\n\ +do not execute any command. +; +; +MSGID_CREATE_APPLICATION_FAILED (//) +Failed to create Application.\n +; +; +MSGID_CREATE_MAINWINDOW_FAILED (//) +Failed to open main window !\n +; +; +MSGID_OPEN_LIBRARY_FAILED (//) +Failed to open \"%s\" !\n +; +;;----------------------------------------------------------- +; +MSGID_MENU_PROJECT (2000//) +Project +; +; +MSGID_MENU_PROJECT_ABOUT (//) +About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI (//) +About MUI... +; +; +MSGID_MENU_PROJECT_QUIT (//) +Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT (//) +Q +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK (3000//) +_OK +; +; +MSGID_ABOUTREQFORMAT (//) +\33c\033bScalos Execute_Command.module V%ld.%ld\033n\n\ +%s\n\ +© 2004%s The Scalos Team +; +;----------------------------------------------------------- +; +; +MSGID_TEXT_ENTER_COMMAND (4000//) +Enter command and its arguments: +; +; +MSGID_LABEL_COMMAND (//) +Command: +; +; +MSGID_TITLE_ERRORREQ (//) +Execute_Command Error +; +; +MSGID_CURRENTDIR (//) +Current dir: \"%s\" +; +; +MSGID_CURRENTDIR_SHORTHELP (//) +Current dir.\n\n\ +It's possible to show all content of this gadget using\n\ +the scroller located at the bottom of the window.\n\ +Can be usefull for large path lenght. +; +; +MSGID_ERRORREQ_BODYTEXT (//) +Could not execute command\n\ +\"%s\"\n\ +%s +; +; +MSGID_REQ_OK (//) + _Ok +; +; +MSGID_ASL_REQUESTER_SHORTHELP (//) +Open a ASL file requeter\n\ +and choose a file to execute.\n\ +; +; +MSGID_COMMAND_ASLTITLE (//) +Select file to execute +; +; +MSGID_LABEL_STACK (//) +Stack: +; +; +MSGID_GET_DEFSTACK_SHORTHELP (//) +Use default stack size +; +; +MSGID_LABEL_CHECKQUIT (//) +Stay opened +; +; +MSGID_CHECKQUIT_SHORTHELP (//) +If selected, Execute_Command.module\n\ +stay opened after execution. +; +; +MSGID_CONSOLE_NAME (//) +Scalos Execute_Command Output Window +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE (5000//) +Execute_Command.module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD (//) +Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +; +;----------------------------------------------------------- +; diff --git a/scalos/Modules/Execute_Command.MUI/Execute_Command.h b/scalos/Modules/Execute_Command.MUI/Execute_Command.h new file mode 100755 index 000000000..ff9771ac3 --- /dev/null +++ b/scalos/Modules/Execute_Command.MUI/Execute_Command.h @@ -0,0 +1,23 @@ +// Execute_Command.h +// $Date$ +// $Revision$ + + +#ifndef EXECUTE_COMMAND_H +#define EXECUTE_COMMAND_H + +#define d1(x) ; +#define d2(x) x; + + +extern int kprintf(CONST_STRPTR, ...); +extern int KPrintF(CONST_STRPTR, ...); + +struct Execute_Command_LocaleInfo +{ + APTR li_LocaleBase; + APTR li_Catalog; + struct LocaleIFace *li_ILocale; +}; + +#endif /* EXECUTE_COMMAND_H */ diff --git a/scalos/Modules/Execute_Command.MUI/config.mk b/scalos/Modules/Execute_Command.MUI/config.mk new file mode 100755 index 000000000..fc91e622e --- /dev/null +++ b/scalos/Modules/Execute_Command.MUI/config.mk @@ -0,0 +1,58 @@ +# $Date: 2011-07-16 19:39:22 +0200 (Sa, 16. Jul 2011) $ +# $Revision: 787 $ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +SCALOS_LOCALE = $(OBJDIR)/Execute_Command_Locale.h + +CFLAGS += -D SCALOSLOCALE=$(SCALOS_LOCALE) + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +INCLUDES += # + +LFLAGS += # + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +INCLUDES += # + +LFLAGS += -lauto + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +INCLUDES += -DMUI_OBSOLETE + +LFLAGS += -lmui -larossupport -lasl -lgraphics + +else + +############################################################################### +# AmigaOS + +INCLUDES += # + +LFLAGS += # + +endif +endif +endif diff --git a/scalos/Modules/Execute_Command.MUI/makefile b/scalos/Modules/Execute_Command.MUI/makefile new file mode 100755 index 000000000..a953af5d9 --- /dev/null +++ b/scalos/Modules/Execute_Command.MUI/makefile @@ -0,0 +1,122 @@ +# Makefile for Execute_Command.module (MUI) +# using GNU make and SAS/C +# $Date$ + +##################################################################### + +TOPLEVEL = / +SUBDIRMAKE = $(MAKE) -s -C +CHEADERS = +CC = sc +CFLAGS = optimize nostackcheck nochkabort debug=s \ + idlen=128 strmer nover streq data=far \ + ignore=217 idir=sc:include/ \ + define SCALOSLOCALE=$(SCALOS_LOCALE) \ + idir=include: idir=//include +AS = phxass +AFLAGS = QUIET m=68020 linedebug opt=NRQB i=include: +LD = slink +LNFLAGS = quiet batch noicons stripdebug +LNDBFLAGS = quiet batch noicons addsym +LIBS = LIB:sc.lib LIB:debug.lib LIB:amiga.lib +CATCOMP = catcomp +FLEXCAT = FlexCat +CSTARTUP = LIB:c.o +OBJDIR = .sasobj + +SCALOS_LOCALE = $(OBJDIR)/Execute_Command_Locale.h + +##################################################################### + +.SUFFIXES: .asm + +##################################################################### + +NAME = .bin_os3/Execute_Command.module +DBGNAME = $(NAME).debug +CATCOMPH = $(SCALOS_LOCALE) +CAT_FILE = Scalos/Execute_Command.catalog +DESTCAT = Locale:Catalogs +ALLCATS = Catalogs/deutsch/$(CAT_FILE) \ + Catalogs/français/$(CAT_FILE) + +##################################################################### + +all: $(NAME) \ + $(DBGNAME) \ + allcatalogs +# install +# clean + +##################################################################### + +# make all Scalos .catalogs +allcatalogs: + @$(SUBDIRMAKE) Catalogs/deutsch/Scalos + @$(SUBDIRMAKE) Catalogs/français/Scalos + +##################################################################### + +CSRCS = Execute_Command.c + +##################################################################### + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +##################################################################### + +XOBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(CSRCS:%.c=$(OBJDIR)/%.o) +OBJS = $(XOBJS) + +##################################################################### + +$(NAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNFLAGS) + +$(DBGNAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNDBFLAGS) + +##################################################################### + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $< objectname $@ + +$(OBJDIR)/%.o : %.asm + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +##################################################################### + +$(CATCOMPH) : Execute_Command.cd + @printf '\033[32mMake CatComp header: \033[31m\033[1m$(CATCOMPH) \033[32mfrom \033[31m$<\033[0m\n' + @$(FLEXCAT) $< $@=$(TOPLEVEL)/CatComp_h.sd + +$(OBJDIR)/Execute_Command.o : Execute_Command.c Execute_Command.h $(CATCOMPH) + +##################################################################### + +$(NAME) $(DBGNAME) : $(OBJS) + +##################################################################### + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(NAME) \033[0mto \033[31m\033[1mScalos:modules/ \033[0m\n' + @copy $(NAME) Scalos:modules/ + @avail flush + @printf '\033[32mInstall: \033[31m\033[1m$(CAT_FILE)\033[0m\n' + -@copy "catalogs/deutsch/$(CAT_FILE)" "$(DESTCAT)/Deutsch/Scalos/" clone + -@copy "catalogs/français/$(CAT_FILE)" "$(DESTCAT)/français/Scalos/" clone + +##################################################################### + +# A little something to clean it all up +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + -@delete $(XOBJS) $(NAME) $(DBGNAME) $(CATCOMPH) + @printf '\033[0m' + +##################################################################### diff --git a/scalos/Modules/Execute_Command.MUI/makefile-new b/scalos/Modules/Execute_Command.MUI/makefile-new new file mode 100755 index 000000000..19063fac2 --- /dev/null +++ b/scalos/Modules/Execute_Command.MUI/makefile-new @@ -0,0 +1,95 @@ +# $Date: 2011-07-12 02:18:25 +0200 (Di, 12. Jul 2011) $ +# $Revision: 773 $ +############################################################# +TOPLEVEL = $(shell pwd)/../.. + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + SDPATH=/ +else + SDPATH=../.. +endif + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(OBJDIR)/Execute_Command.o \ + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Subdirs +# + +SUBDIRS = $(filter-out Catalogs/sample/Scalos, $(wildcard Catalogs/*/Scalos)) + +############################################################################## +# +# Targets +# + +NAME = Execute_Command.module +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) \ + all_subdirs + +############################################################################## + +$(OBJDIR)/%.o: $(TOOLTYPE_DIR)/%.c + @$(run-cc) + +$(OBJDIR)/%.o: $(ICONOBJMCC_DIR)/%.c + @$(run-cc) + +Execute_Command.c : $(OBJDIR)/Execute_Command_Locale.h + +$(OBJDIR)/Execute_Command_Locale.h : Execute_Command.cd + @$(ECHO) "FlexCat $@" + $(FLEXCAT) $< $@=$(SDPATH)/CatComp_h.sd + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + @$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) +ifneq ($(MACHINE), ppc-amigaos) + -@chmod u+x $@ +endif + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) Scalos:modules/ clone + +install: install_subdirs + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* \ + $(OBJDIR)/Execute_Command_Locale.h + +clean: clean_subdirs + +############################################################################## + diff --git a/scalos/Modules/Find.MUI/Catalogs/deutsch/Scalos/Find.ct b/scalos/Modules/Find.MUI/Catalogs/deutsch/Scalos/Find.ct new file mode 100644 index 000000000..65f38dd25 --- /dev/null +++ b/scalos/Modules/Find.MUI/Catalogs/deutsch/Scalos/Find.ct @@ -0,0 +1,309 @@ +; Find.ct +## version $VER: Find.catalog 40.1 (23 Aug 2008 18:50:08) +## codeset 0 +## language deutsch +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Dateisuche +;Scalos Find +; +; +MSGID_SEARCH_FINISHED +Fertig. +;Finished. +; +; +MSGID_SEARCH_ABORTED +Abgebrochen. +;Aborted. +; +;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Projekt +;Project +; +; +MSGID_MENU_PROJECT_ABOUT +Über... +;About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Über MUI... +;About MUI... +; +; +MSGID_MENU_PROJECT_QUIT +Beenden +;Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +;Q +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +_OK +;_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Find.module V%ld.%ld\033n\n\ +%s\n\ +© 2008%s Das Scalos Team +;\33c\033bScalos Find.module V%ld.%ld\033n\n\ +;%s\n\ +;© 2008%s The Scalos Team +; +;----------------------------------------------------------- +; +MSGID_POPSTRING_NAME +Dateiname: +;Name: +; +; +MSGID_POPSTRING_NAME_SHORTHELP +Suchmuster für den Dateinamen.\n\ +Alle DOS Jokerzeichen wie \"#?\" können verwendet werden. +;Pattern for file names to look for.\n\ +;You can use all DOS wildcards like \"#?\" +; +; +MSGID_POPSTRING_TEXT +Inhalt: +;Text: +; +; +MSGID_POPSTRING_TEXT_SHORTHELP +Nach diesem Text wird im Inhalt aller Dateien gesucht,\n\ +deren Namen auf das Dateiname-Muster paßt.\n\ +Hier können keine Jokerzeichen verwendet werden. +;String that is search inside all files\n\ +;matching the file name pattern.\n\ +;No wildcards are allowed here. +; +; +MSGID_POPSTRING_TYPE +Dateityp: +;Type: +; +; +MSGID_POPSTRING_TYPE_SHORTHELP +Name des Dateityps, den alle gefundenen Dateien haben müssen. +;Name of Filetype all found entries must have. +; +; +MSGID_SHORTHELP_LISTVIEW_FILETYPES +Dateityp aus dieser Liste durch Doppelklick auswählen. +;Select any filetype from this list by double-licking it. +; +; +MSGID_GROUP_SOURCES +Suchpfade +;Sources +; +; +MSGID_GROUP_SOURCES_ASLTITLE +Neuen Suchpfad eintragen: +;Enter find source path: +; +; +MSGID_GROUP_RESULTS +Suchergebnisse +;Results +; +; +MSGID_BUTTON_ADD +Hinzufügen \033I[6:20] +;Add \033I[6:20] +; +; +MSGID_BUTTON_ADD_KEY +Z +;A +; +; +MSGID_BUTTON_ADD_SHORTHELP +Neuen Pfad zu der Liste der Suchpfade hinzufügen. +;Add another path to search for desired file(s). +; +; +MSGID_BUTTON_REMOVE +Entfernen +;Remove +; +; +MSGID_BUTTON_REMOVE_KEY +F +;R +; +; +MSGID_BUTTON_REMOVE_SHORTHELP +Ausgewählten Pfad aus der Liste der Suchpfade entfernen. +;Remove selected entry from the list of\n\ +;paths to search for desired file(s). +; +; +MSGID_BUTTON_SEARCH +Suchen +;Search +; +; +MSGID_BUTTON_SEARCH_KEY +S +;S +; +; +MSGID_BUTTON_SEARCH_SHORTHELP +Dateisuche starten. +;Start searching for desired file(s). +; +; +MSGID_BUTTON_STOP +Anhalten +;Stop +; +; +MSGID_BUTTON_STOP_KEY +H +;p +; +; +MSGID_BUTTON_STOP_SHORTHELP +Laufende Suche sofort abbrechen. +;Immediately stop search in progress. +; +; +MSGID_RESULTLIST_NAME +Name +;Name +; +; +MSGID_RESULTLIST_LOCATION +Verzeichnis +;Location +; +; +MSGID_BUTTON_FIND_NEXT +Nächster +;Next +; +; +MSGID_BUTTON_FIND_NEXT_KEY +N +;N +; +; +MSGID_BUTTON_FIND_NEXT_SHORTHELP +Nächsten Dateityp suchen, der zum angegebenen Suchtext paßt. +;Find next filetype that matches the given search string. +; +; +MSGID_BUTTON_FIND_HIDE_SHORTHELP +Schaltflächen zur Suche nach Dateityp ausblenden. +;Hide Find Filetype Dialog. +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Find.module kann nicht gestartet werden +;Find Module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Wiederholen|Beenden +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\ +Die Klasse ist nicht installiert. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Sie haben momentan Version v%lu.%lu installiert und\n\ +sollten die Klasse daher aktualisieren! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Version %lu.%lu wird momentan von einer anderen Anwendung\n\ +verwendet. Wenn sie die benötigte Version installiert haben,\n\ +schließen sie alle MUI Programme und probieren es erneut. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_MENU_RESULTS_TITLE +Suchergebnisse +;Find Results +; +; +MSGID_MENU_RESULTS_OPEN +Öffnen mit MultiView... +;Open with MultiView... +; +; +MSGID_MENU_RESULTS_OPENDRAWER +Verzeichnisfenster öffnen... +;Open Drawer... +; +; +MSGID_MENU_RESULTS_FIND +Im Ergebnisverzeichnis suchen... +;Find in Result... +; +; +MSGID_MENU_RESULTS_COPYTOCLIP +Kopieren in Zwischenablage +;Copy to Clipboard +; +;----------------------------------------------------------- +; +MSGID_MENU_FILETYPES_TITLE +Dateitypen +;File Types +; +; +MSGID_MENU_EDIT_COLLAPSE +Auswahl zuklappen +;Collapse Selected +; +; +MSGID_MENU_EDIT_EXPAND +Auswahl aufklappen +;Expand Selected +; +; +MSGID_MENU_EDIT_COLLAPSEALL +Alles zuklappen +;Collapse All +; +; +MSGID_MENU_EDIT_EXPANDALL +Alles aufklappen +;Expand All +; +; +MSGID_MENU_CLEARHISTORY +Verlauf löschen +;Clear History +; +;----------------------------------------------------------- diff --git a/scalos/Modules/Find.MUI/Catalogs/deutsch/Scalos/config.mk b/scalos/Modules/Find.MUI/Catalogs/deutsch/Scalos/config.mk new file mode 100755 index 000000000..8631b0623 --- /dev/null +++ b/scalos/Modules/Find.MUI/Catalogs/deutsch/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = deutsch + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = german + +else + +############################################################################### +# AmigaOS and AROS + +LANG = deutsch + +endif +endif diff --git a/scalos/Modules/Find.MUI/Catalogs/deutsch/Scalos/makefile b/scalos/Modules/Find.MUI/Catalogs/deutsch/Scalos/makefile new file mode 100644 index 000000000..c95cb96ce --- /dev/null +++ b/scalos/Modules/Find.MUI/Catalogs/deutsch/Scalos/makefile @@ -0,0 +1,13 @@ +# makefile for Find.module (translated Texts : deutsch) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mdeutsch\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +Find.catalog : Find.ct ../../../Find.cd + +All: Find.catalog diff --git a/scalos/Modules/Find.MUI/Catalogs/deutsch/Scalos/makefile-new b/scalos/Modules/Find.MUI/Catalogs/deutsch/Scalos/makefile-new new file mode 100644 index 000000000..5d801c11c --- /dev/null +++ b/scalos/Modules/Find.MUI/Catalogs/deutsch/Scalos/makefile-new @@ -0,0 +1,30 @@ +# makefile for Find.module (translated Texts : deutsch) +# $Date: 2011-07-24 10:11:00 +0200 (So, 24. Jul 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = Find + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git "a/scalos/Modules/Find.MUI/Catalogs/fran\303\247ais/Scalos/Find.ct" "b/scalos/Modules/Find.MUI/Catalogs/fran\303\247ais/Scalos/Find.ct" new file mode 100755 index 000000000..fe498cbc3 --- /dev/null +++ "b/scalos/Modules/Find.MUI/Catalogs/fran\303\247ais/Scalos/Find.ct" @@ -0,0 +1,273 @@ +; Find.ct +; $Date$ +; $Revision$ +## version $VER: Find.catalog 40.1 (23 Aug 2008 18:50:08) +## codeset 0 +## language français +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos : Rechercher +;Scalos Find +; +MSGID_SEARCH_FINISHED +Terminé. +;Finished. +; +MSGID_SEARCH_ABORTED +Annulé. +;Aborted. +; +;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Projet +;Project +; +MSGID_MENU_PROJECT_ABOUT +A propos... +;About... +; +MSGID_MENU_PROJECT_ABOUTMUI +A propos de MUI... +;About MUI... +; +MSGID_MENU_PROJECT_QUIT +Quitter +;Quit +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +;Q +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +_OKay +;_OK +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Find.module V%ld.%ld\033n\n\ +%s\n\ +© 2008%s The Scalos Team +;\33c\033bScalos Find.module V%ld.%ld\033n\n\ +;%s\n\ +;© 2008%s The Scalos Team +; +;----------------------------------------------------------- +; +MSGID_POPSTRING_NAME +Nom : +;Name: +; +MSGID_POPSTRING_NAME_SHORTHELP +Motif pour les noms de fichiers à rechercher.\n\ +Vous pouvez utiliser toutes les syntaxes DOS comme \"#?\" +;Pattern for file names to look for.\n\ +;You can use all DOS wildcards like \"#?\" +; +MSGID_POPSTRING_TEXT +Texte : +;Text: +; +MSGID_POPSTRING_TEXT_SHORTHELP +Texte à rechercher dans tous les fichiers\n\ +correspondant au motif du nom du fichier.\n\ +Aucune syntaxe n'est allouée ici. +;String that is search inside all files\n\ +;matching the file name pattern.\n\ +;No wildcards are allowed here. +; +MSGID_POPSTRING_TYPE +Type : +;Type: +; +MSGID_POPSTRING_TYPE_SHORTHELP +Nom du type de fichier que toutes\n\ +les entrées doivent avoir. +;Name of Filetype all found entries must have. +; +MSGID_SHORTHELP_LISTVIEW_FILETYPES +Selectionnez un type de fichier depuis cette liste par Double-Click. +;Select any filetype from this list by double-licking it. +; +MSGID_GROUP_SOURCES +Sources +;Sources +; +MSGID_GROUP_SOURCES_ASLTITLE +Entrer un chemin de recherche : +;Enter find source path: +; +MSGID_GROUP_RESULTS +Résultats +;Results +; +MSGID_BUTTON_ADD +Ajouter \033I[6:20] +;Add \033I[6:20] +; +MSGID_BUTTON_ADD_KEY +A +;A +; +MSGID_BUTTON_ADD_SHORTHELP +Ajouter un autre chemin de recherche\n\ +pour le ou les fichiers désirés. +;Add another path to search for desired file(s). +; +MSGID_BUTTON_REMOVE +Retirer +;Remove +; +MSGID_BUTTON_REMOVE_KEY +R +;R +; +MSGID_BUTTON_REMOVE_SHORTHELP +Supprimer l'entrée sélectionnée, depuis la liste, des\n\ +chemins de recherches pour le ou les fichiers désirés. +;Remove selected entry from the list of\n\ +;paths to search for desired file(s). +; +MSGID_BUTTON_SEARCH +Chercher +;Search +; +MSGID_BUTTON_SEARCH_KEY +S +;S +; +MSGID_BUTTON_SEARCH_SHORTHELP +Débuter la recherche pour le\n\ +ou les fichiers désirés. +;Start searching for desried file(s). +; +MSGID_BUTTON_STOP +Interrompre +;Stop +; +MSGID_BUTTON_STOP_KEY +I +;p +; +MSGID_BUTTON_STOP_SHORTHELP +Interrompre immédiatement\n\ +le processus de recherche. +;Immediately stop search in progress. +; +MSGID_RESULTLIST_NAME +Nom +;Name +; +MSGID_RESULTLIST_LOCATION +Emplacement +;Location +; +MSGID_BUTTON_FIND_NEXT +Prochain +;Next +; +MSGID_BUTTON_FIND_NEXT_KEY +P +;N +; +MSGID_BUTTON_FIND_NEXT_SHORTHELP +Trouver le prochain type de fichier \n\ +correspondant à la recherche donnée. +;Find next filetype that matches the given search string. +; +MSGID_BUTTON_FIND_HIDE_SHORTHELP +Cacher le dialogue avec les types de fichiers. +;Hide Find Filetype Dialog. +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Le démarrage du module de recherche a échoué. +;Find Module startup failed +; +MSGID_STARTUP_RETRY_QUIT_GAD +Essayer de nouveau | Quitter +;Try again|Quit +; +MSGID_STARTUP_MCC_NOT_FOUND +Ouverture impossible de la classe MUI '%s' V%lu.%lu.\n\ +La classe n'est pas installée. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +MSGID_STARTUP_OLD_MCC +Ouverture impossible de la classe MUI '%s' V%lu.%lu.\n\ +\n\ +Actuellement installée : V%lu.%lu, \n\ +installez une version supérieure S.V.P ! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +MSGID_STARTUP_MCC_IN_USE +Ouverture impossible de la classe MUI '%s' V%lu.%lu.\n\ +%lu.%lu est actuellement utilisé par d'autres applications.\n\ +\n\ +Une fois que vous vaez installé la version requise,\n\ +fermez tous les programmes MUI, soyez sure que l'ancienne classe\n\ +ne soit plus en mémoire et essayez de nouveau. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_MENU_RESULTS_TITLE +Résultats de recherche +;Find Results +; +MSGID_MENU_RESULTS_OPEN +Ouvrir avec MultiView... +;Open with MultiView... +; +MSGID_MENU_RESULTS_OPENDRAWER +Ouvrir le répertoire... +;Open Drawer... +; +MSGID_MENU_RESULTS_FIND +Trouver dans le résultat... +;Find in Result... +; +MSGID_MENU_RESULTS_COPYTOCLIP +Copier vers le presse-papier +;Copy to Clipboard +; +;----------------------------------------------------------- +; +MSGID_MENU_FILETYPES_TITLE +Type de fichier +;File Types +; +MSGID_MENU_EDIT_COLLAPSE +Plier l'entrée sélectionée +;Collapse Selected +; +MSGID_MENU_EDIT_EXPAND +Déplier l'entrée sélectionnée +;Expand Selected +; +MSGID_MENU_EDIT_COLLAPSEALL +Tout plier +;Collapse All +; +MSGID_MENU_EDIT_EXPANDALL +Tout déplier +;Expand All +; +MSGID_MENU_CLEARHISTORY +Nettoyer l'historique +;Clear History +; +;----------------------------------------------------------- diff --git "a/scalos/Modules/Find.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" "b/scalos/Modules/Find.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" new file mode 100755 index 000000000..8b7056423 --- /dev/null +++ "b/scalos/Modules/Find.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" @@ -0,0 +1,40 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = français + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = french + +else + +############################################################################### +# AmigaOS and AROS + +LANG = français + +endif +endif diff --git "a/scalos/Modules/Find.MUI/Catalogs/fran\303\247ais/Scalos/makefile" "b/scalos/Modules/Find.MUI/Catalogs/fran\303\247ais/Scalos/makefile" new file mode 100644 index 000000000..54b59d066 --- /dev/null +++ "b/scalos/Modules/Find.MUI/Catalogs/fran\303\247ais/Scalos/makefile" @@ -0,0 +1,13 @@ +# makefile for Find.module (translated Texts : français) +# $Date: 17 Aug 2004 20:12:47 + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mfrançais\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +Find.catalog : Find.ct ../../../Find.cd + +All: Find.catalog diff --git "a/scalos/Modules/Find.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" "b/scalos/Modules/Find.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" new file mode 100644 index 000000000..d0617f796 --- /dev/null +++ "b/scalos/Modules/Find.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" @@ -0,0 +1,30 @@ +# makefile for Find.module (translated Texts : français) +# $Date: 2011-07-24 10:11:00 +0200 (So, 24. Jul 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = Find + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Modules/Find.MUI/Catalogs/sample/Scalos/Find.ct b/scalos/Modules/Find.MUI/Catalogs/sample/Scalos/Find.ct new file mode 100644 index 000000000..7ed7e9009 --- /dev/null +++ b/scalos/Modules/Find.MUI/Catalogs/sample/Scalos/Find.ct @@ -0,0 +1,314 @@ +; Find.ct +; version $VER: Find.catalog 40.1 (23. Aug 2008 18:50:08) +; $Date$ +; $Revision$ +; codeset 0s +; language xxxxxx +; +;#arrayopts static __far +; +;+++translateme+++ +MSGID_TITLENAME +Scalos Find +;Scalos Find +; +;+++translateme+++ +MSGID_SEARCH_FINISHED +Finished. +;Finished. +; +;+++translateme+++ +MSGID_SEARCH_ABORTED +Aborted. +;Aborted. +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_MENU_PROJECT +Project +;Project +; +;+++translateme+++ +MSGID_MENU_PROJECT_ABOUT +About... +;About... +; +;+++translateme+++ +MSGID_MENU_PROJECT_ABOUTMUI +About MUI... +;About MUI... +; +;+++translateme+++ +MSGID_MENU_PROJECT_QUIT +Quit +;Quit +; +;+++translateme+++ +MSGID_MENU_PROJECT_QUIT_SHORT +Q +;Q +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_ABOUTREQOK +_OK +;_OK +; +;+++translateme+++ +MSGID_ABOUTREQFORMAT +\33c\033bScalos Find.module V%ld.%ld\033n\n\ +%s\n\ +© 2008%s The Scalos Team +;\33c\033bScalos Find.module V%ld.%ld\033n\n\ +;%s\n\ +;© 2008%s The Scalos Team +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_POPSTRING_NAME +Name: +;Name: +; +;+++translateme+++ +MSGID_POPSTRING_NAME_SHORTHELP +Pattern for file names to look for.\n\ +You can use all DOS wildcards like \"#?\" +;Pattern for file names to look for.\n\ +;You can use all DOS wildcards like \"#?\" +; +;+++translateme+++ +MSGID_POPSTRING_TEXT +Text: +;Text: +; +;+++translateme+++ +MSGID_POPSTRING_TEXT_SHORTHELP +String that is search inside all files\n\ +matching the file name pattern.\n\ +No wildcards are allowed here. +;String that is search inside all files\n\ +;matching the file name pattern.\n\ +;No wildcards are allowed here. +; +;+++translateme+++ +MSGID_POPSTRING_TYPE +Type: +;Type: +; +;+++translateme+++ +MSGID_POPSTRING_TYPE_SHORTHELP +Name of Filetype all found entries must have. +;Name of Filetype all found entries must have. +; +;+++translateme+++ +MSGID_SHORTHELP_LISTVIEW_FILETYPES +Select any filetype from this list by double-licking it. +;Select any filetype from this list by double-licking it. +; +;+++translateme+++ +MSGID_GROUP_SOURCES +Sources +;Sources +; +;+++translateme+++ +MSGID_GROUP_SOURCES_ASLTITLE +Enter find source path: +;Enter find source path: +; +;+++translateme+++ +MSGID_GROUP_RESULTS +Results +;Results +; +;+++translateme+++ +MSGID_BUTTON_ADD +Add \033I[6:20] +;Add \033I[6:20] +; +;+++translateme+++ +MSGID_BUTTON_ADD_KEY (/1/1) +A +;A +; +;+++translateme+++ +MSGID_BUTTON_ADD_SHORTHELP +Add another path to search for desired file(s). +;Add another path to search for desired file(s). +; +;+++translateme+++ +MSGID_BUTTON_REMOVE +Remove +;Remove +; +;+++translateme+++ +MSGID_BUTTON_REMOVE_KEY (/1/1) +R +;R +; +;+++translateme+++ +MSGID_BUTTON_REMOVE_SHORTHELP +Remove selected entry from the list of\n\ +paths to search for desired file(s). +;Remove selected entry from the list of\n\ +;paths to search for desired file(s). +; +;+++translateme+++ +MSGID_BUTTON_SEARCH +Search +;Search +; +;+++translateme+++ +MSGID_BUTTON_SEARCH_KEY (/1/1) +S +;S +; +;+++translateme+++ +MSGID_BUTTON_SEARCH_SHORTHELP +Start searching for desried file(s). +;Start searching for desried file(s). +; +;+++translateme+++ +MSGID_BUTTON_STOP +Stop +;Stop +; +;+++translateme+++ +MSGID_BUTTON_STOP_KEY +p +;p +; +;+++translateme+++ +MSGID_BUTTON_STOP_SHORTHELP +Immediately stop search in progress. +;Immediately stop search in progress. +; +;+++translateme+++ +MSGID_RESULTLIST_NAME +Name +;Name +; +;+++translateme+++ +MSGID_RESULTLIST_LOCATION +Location +;Location +; +;+++translateme+++ +MSGID_BUTTON_FIND_NEXT +Next +;Next +; +;+++translateme+++ +MSGID_BUTTON_FIND_NEXT_KEY (/1/1) +N +;N +; +;+++translateme+++ +MSGID_BUTTON_FIND_NEXT_SHORTHELP +Find next filetype that matches the given search string. +;Find next filetype that matches the given search string. +; +;+++translateme+++ +MSGID_BUTTON_FIND_HIDE_SHORTHELP +Hide Find Filetype Dialog. +;Hide Find Filetype Dialog. +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_STARTUP_FAILURE +Find Module startup failed +;Find Module startup failed +; +;+++translateme+++ +MSGID_STARTUP_RETRY_QUIT_GAD +Try again|Quit +;Try again|Quit +; +;+++translateme+++ +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +;+++translateme+++ +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +;+++translateme+++ +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_MENU_RESULTS_TITLE +Find Results +;Find Results +; +;+++translateme+++ +MSGID_MENU_RESULTS_OPEN +Open with MultiView... +;Open with MultiView... +; +;+++translateme+++ +MSGID_MENU_RESULTS_OPENDRAWER +Open Drawer... +;Open Drawer... +; +;+++translateme+++ +MSGID_MENU_RESULTS_FIND +Find in Result... +;Find in Result... +; +;+++translateme+++ +MSGID_MENU_RESULTS_COPYTOCLIP +Copy to Clipboard +;Copy to Clipboard +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_MENU_FILETYPES_TITLE +File Types +;File Types +; +;+++translateme+++ +MSGID_MENU_EDIT_COLLAPSE +Collapse Selected +;Collapse Selected +; +;+++translateme+++ +MSGID_MENU_EDIT_EXPAND +Expand Selected +;Expand Selected +; +;+++translateme+++ +MSGID_MENU_EDIT_COLLAPSEALL +Collapse All +;Collapse All +; +;+++translateme+++ +MSGID_MENU_EDIT_EXPANDALL +Expand All +;Expand All +; +;+++translateme+++ +MSGID_MENU_CLEARHISTORY +Clear History +;Clear History +; +;----------------------------------------------------------- diff --git a/scalos/Modules/Find.MUI/DefIcons.c b/scalos/Modules/Find.MUI/DefIcons.c new file mode 100644 index 000000000..e7997d2f8 --- /dev/null +++ b/scalos/Modules/Find.MUI/DefIcons.c @@ -0,0 +1,1024 @@ +// DefIcons.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef __amigaos4__ +#define USE_OLD_ANCHORPATH +#include +#endif +#include +#include +#include +#include +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#define NO_INLINE_STDARG +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#include "debug.h" +#include "Find.h" + +//---------------------------------------------------------------------------- + +// local data structures + +#define IOBUFFERLEN 480 +#define NO_TYPE_NODE ((struct TypeNode *) -1) + +#ifndef __AROS__ +#define BNULL ((BPTR) 0) +#endif + +//---------------------------------------------------------------------------- + +// local functions + +static void ReloadDefIcons(struct FileTypesPrefsInst *inst, CONST_STRPTR DefIconPrefsName); +static VOID InitTypeTree(struct FileTypesPrefsInst *inst, + struct TypeNode *parentnode, const UBYTE **desclist); +static struct TypeNode *AllocTypeNode(const UBYTE **description); +static VOID AddSon(struct TypeNode *parent,struct TypeNode *son); +static void DeleteTypeNode(struct TypeNode *tn); +static void AddFileTypesToList(struct FileTypesPrefsInst *inst); +static void AddTypeNodeToFileTypesList(struct FileTypesPrefsInst *inst, struct TypeNode *tn, + struct MUI_NListtree_TreeNode *parentNode); +static void AddRootTypeNodeToList(struct FileTypesPrefsInst *inst, CONST_STRPTR Name); +static struct TypeNode *DefIconsIdentifyDisk(BPTR lock); +static struct TypeNode *DefIconsIdentifyProject(CONST_STRPTR Name, struct FileInfoBlock *fib); +static STRPTR DefIconsGetDeviceName(CONST_STRPTR DosDevice, ULONG *DosType); +static LONG match(CONST_STRPTR a, CONST_STRPTR b, size_t len); + +//---------------------------------------------------------------------------- + +/* A table of clearly invalid ASCII characters (8 bits). */ +static const UBYTE InvalidTab[256] = +{ + 1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, + 1,0,1,0,1,1,1,1,1,1,1,0,1,1,1,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,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,0,1,1,1,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; + +//---------------------------------------------------------------------------- + +static struct FileTypesPrefsInst PrefsInst; + +LONG InitDefIcons(void) +{ + CONST_STRPTR DefIconPrefsName = "ENV:deficons.prefs"; + + CleanupDefIcons(); + + PrefsInst.fpb_DefIconsInit = TRUE; + + d1(KPrintF(__FILE__ "/%s/%ld: DefIconPrefsName=<%s>\n", __FUNC__, __LINE__, DefIconPrefsName)); + + ReloadDefIcons(&PrefsInst, DefIconPrefsName); + + AddFileTypesToList(&PrefsInst); + + return RETURN_OK; +} + + +static void ReloadDefIcons(struct FileTypesPrefsInst *inst, CONST_STRPTR DefIconPrefsName) +{ + if (DefIconPrefsName) + { + inst->fpb_DefIconsSegList = LoadSeg(DefIconPrefsName); + + d1(KPrintF(__FILE__ "/%s/%ld: SegList=%08lx\n", __FUNC__, __LINE__, inst->fpb_DefIconsSegList)); + + if (inst->fpb_DefIconsSegList) + { + const UBYTE *inittable; + + inittable = ((UBYTE *)BADDR(inst->fpb_DefIconsSegList))+4; + InitTypeTree(inst, NO_TYPE_NODE, &inittable); + + d1(KPrintF(__FILE__ "/%s/%ld: RootType=%08lx\n", __FUNC__, __LINE__, inst->fpb_RootType)); + } + } +} + + +void CleanupDefIcons(void) +{ + if (PrefsInst.fpb_DefIconsInit) + { + if (PrefsInst.fpb_RootType) + { + DeleteTypeNode(PrefsInst.fpb_RootType); + PrefsInst.fpb_RootType = NULL; + } + + if (PrefsInst.fpb_DefIconsSegList) + { + UnLoadSeg(PrefsInst.fpb_DefIconsSegList); + PrefsInst.fpb_DefIconsSegList = (BPTR)NULL; + } + } +} + + +static VOID InitTypeTree(struct FileTypesPrefsInst *inst, + struct TypeNode *parentnode, const UBYTE **desclist) +{ + struct TypeNode *newTn = NULL; + + while (1) + { + switch(**desclist) + { + case TYPE_DOWN_LEVEL: + (*desclist)++; + InitTypeTree(inst, newTn, desclist); + break; + + case TYPE_UP_LEVEL: + (*desclist)++; + /* fall thru next case */ + case TYPE_END: + return; + break; + + default: + if ((newTn = AllocTypeNode(desclist))) /* desclist will be incremented by */ + /* AllocTypeNode */ + { + if (parentnode != NO_TYPE_NODE) + { + AddSon(parentnode, newTn); + } + else + { + if (inst->fpb_RootType) + inst->fpb_RootType->tn_RightBrother = newTn; + else + inst->fpb_RootType = newTn; + } + } + break; + } + } +} + + +static struct TypeNode *AllocTypeNode(const UBYTE **description) +{ + struct TypeNode *nd; + ULONG j; + const UBYTE *arg; + const UBYTE *name; + + j = 0; + name = *description; + arg = name + strlen((char *)name) + 1; + d1(KPrintF(__FILE__ "/%s/%ld: name=<%s>\n", __FUNC__, __LINE__, name)); + while (*arg != ACT_END) + { + j++; + switch(*(arg++)) + { + case ACT_MATCH: + arg = arg + 3 + abs((BYTE)arg[2]); + break; + case ACT_SEARCH: + case ACT_SEARCHSKIPSPACES: + arg = arg + 1 + abs((BYTE)arg[0]); + break; + case ACT_PROTECTION: + arg += 8; + break; + case ACT_FILESIZE: + case ACT_MINSIZEMB: + arg += 4; + break; + case ACT_NAMEPATTERN: + case ACT_DOSDEVICE: + case ACT_DEVICENAME: + case ACT_CONTENTS: + arg = arg + strlen((char *)arg) + 1; + break; + case ACT_DOSTYPE: + arg = arg + 1 + arg[0]; + break; + } + } + + if ((nd = calloc(sizeof(struct TypeNode) + j * sizeof(struct Magic), 1))) + { + nd->tn_Name = (STRPTR) name; + + j = 0; + arg = name + strlen((char *)name) + 1; + while (*arg != ACT_END) + { + switch(nd->tn_Description[j].action = *(arg++)) + { + case ACT_MATCH: + nd->tn_Description[j].arg1 = *(arg++); + nd->tn_Description[j].arg1 <<= 8; + nd->tn_Description[j].arg1 |= *(arg++); + nd->tn_Description[j].arg2 = (BYTE)*(arg++); + nd->tn_Description[j].str = (STRPTR) arg; + arg += abs(nd->tn_Description[j].arg2); + break; + case ACT_SEARCH: + case ACT_SEARCHSKIPSPACES: + nd->tn_Description[j].arg2 = (BYTE)*(arg++); + nd->tn_Description[j].str = (STRPTR) arg; + arg += abs(nd->tn_Description[j].arg2); + break; + case ACT_FILESIZE: + case ACT_MINSIZEMB: + nd->tn_Description[j].arg2 = *(arg++); + nd->tn_Description[j].arg2 <<= 8; + nd->tn_Description[j].arg2 |= *(arg++); + nd->tn_Description[j].arg2 <<= 8; + nd->tn_Description[j].arg2 |= *(arg++); + nd->tn_Description[j].arg2 <<= 8; + nd->tn_Description[j].arg2 |= *(arg++); + break; + case ACT_DOSTYPE: + nd->tn_Description[j].arg2 = (BYTE)*(arg++); + nd->tn_Description[j].str = (STRPTR) arg; + arg += nd->tn_Description[j].arg2; + d1(KPrintF(__FILE__ "/%s/%ld: arg2=%ld str=<%s>\n", __FUNC__, __LINE__, nd->tn_Description[j].arg2, nd->tn_Description[j].str)); + break; + case ACT_NAMEPATTERN: + case ACT_DOSDEVICE: + case ACT_DEVICENAME: + case ACT_CONTENTS: + nd->tn_Description[j].str = (STRPTR) arg; + arg += strlen((char *)arg) + 1; + break; + case ACT_PROTECTION: + nd->tn_Description[j].arg1 = *(arg++); + nd->tn_Description[j].arg1 <<= 8; + nd->tn_Description[j].arg1 |= *(arg++); + nd->tn_Description[j].arg1 <<= 8; + nd->tn_Description[j].arg1 |= *(arg++); + nd->tn_Description[j].arg1 <<= 8; + nd->tn_Description[j].arg1 |= *(arg++); + nd->tn_Description[j].arg2 = *(arg++); + nd->tn_Description[j].arg2 <<= 8; + nd->tn_Description[j].arg2 |= *(arg++); + nd->tn_Description[j].arg2 <<= 8; + nd->tn_Description[j].arg2 |= *(arg++); + nd->tn_Description[j].arg2 <<= 8; + nd->tn_Description[j].arg2 |= *(arg++); + break; + } + + j++; + } + nd->tn_Description[j].action = ACT_END; + } + + *description = arg+1; /* increment *description for recursion */ + + return(nd); +} + + + +static VOID AddSon(struct TypeNode *parent,struct TypeNode *son) +{ + struct TypeNode *nd; + + if (!parent || !son) + return; + + if ((nd = parent->tn_FirstSon)) + { + while (nd->tn_RightBrother) + nd = nd->tn_RightBrother; + + nd->tn_RightBrother = son; + } + else + parent->tn_FirstSon = son; + + son->tn_Parent = parent; +} + + +static void DeleteTypeNode(struct TypeNode *tn) +{ + while (tn) + { + struct TypeNode *tnNext = tn->tn_RightBrother; + + DeleteTypeNode(tn->tn_FirstSon); + + free(tn); + + tn = tnNext; + } +} + + +static void AddFileTypesToList(struct FileTypesPrefsInst *inst) +{ + DoMethod(ListtreeFileTypes, + MUIM_NListtree_Clear, NULL, 0); + + set(ListtreeFileTypes, MUIA_NListtree_Quiet, TRUE); + + AddTypeNodeToFileTypesList(inst, inst->fpb_RootType, + (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_ListNode_Root); + + // Make sure required root entries are present + AddRootTypeNodeToList(inst, "Project"); + AddRootTypeNodeToList(inst, "Disk"); + + set(ListtreeFileTypes, MUIA_NListtree_Quiet, FALSE); + + // Activate first entry (which should be "project" + set(ListtreeFileTypes, + MUIA_NListtree_Active, MUIV_NListtree_Active_First); + // For some obscure reason, the MUIA_NListtree_Active scrolls the list + // so the first (active) entry is not visible. + set(ListtreeFileTypes, + MUIA_NList_First, MUIV_NList_First_Top); +} + + +static void AddTypeNodeToFileTypesList(struct FileTypesPrefsInst *inst, struct TypeNode *tn, + struct MUI_NListtree_TreeNode *parentNode) +{ + while (tn) + { + struct MUI_NListtree_TreeNode *lnNew; + + d1(KPrintF(__FILE__ "/%s/%ld: tn=%08lx <%s> Next=%08lx Son=%08lx\n", \ + __FUNC__, __LINE__, tn, tn->tn_Name, tn->tn_RightBrother, tn->tn_FirstSon)); + + lnNew = (struct MUI_NListtree_TreeNode *) DoMethod(ListtreeFileTypes, + MUIM_NListtree_Insert, + tn->tn_Name, + tn, + parentNode, + MUIV_NListtree_Insert_PrevNode_Tail, + TNF_LIST | TNF_OPEN); + + d1(KPrintF(__FILE__ "/%s/%ld: parentNode=%08lx lnNew=%08lx\n", __FUNC__, __LINE__, parentNode, lnNew)); + + if (tn->tn_FirstSon) + AddTypeNodeToFileTypesList(inst, tn->tn_FirstSon, lnNew); + + tn = tn->tn_RightBrother; + } +} + +//---------------------------------------------------------------------------- + +static void AddRootTypeNodeToList(struct FileTypesPrefsInst *inst, CONST_STRPTR Name) +{ + d1(KPrintF(__FILE__ "/%s/%ld: Name=<%s>\n", __FUNC__, __LINE__, Name)); + + if (0 == DoMethod(ListtreeFileTypes, + MUIM_NListtree_FindName, + MUIV_NListtree_FindName_ListNode_Root, + Name, + MUIV_NListtree_FindName_Flag_SameLevel)) + { + struct TypeNode tn; + + d1(KPrintF(__FILE__ "/%s/%ld: Name=<%s> not found, creating new\n", __FUNC__, __LINE__, Name)); + + tn.tn_RightBrother = tn.tn_FirstSon = tn.tn_Parent = NULL; + tn.tn_IconObject = NULL; + tn.tn_Name = (STRPTR) Name; + tn.tn_Description[0].action = ACT_END; + + AddTypeNodeToFileTypesList(inst, &tn, + (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_ListNode_Root); + } +} + +//---------------------------------------------------------------------------- + +/* DefIconsIdentify(BPTR dirLock, CONST_STRPTR *Name): + * + * Heuristically identify the type of a file. + +* IMPORTANT: this function usually returns a TypeNode *, but may also return +* one of the special values WBDISK and WBDRAWER +it returns NULL for failure + */ + +struct TypeNode *DefIconsIdentify(BPTR dirLock, CONST_STRPTR Name) +{ + struct TypeNode *type = NULL; + struct FileInfoBlock *fib = NULL; + BPTR lock; + BPTR oldDirLock; + + debugLock_d1(dirLock); + d1(KPrintF("%s/%s/%ld: Name=<%s>\n", __FILE__, __FUNC__, __LINE__, Name)); + + oldDirLock = CurrentDir(dirLock); + + if ((lock = Lock((STRPTR) Name, ACCESS_READ)) && (fib = AllocDosObject(DOS_FIB, NULL)) && + Examine(lock, fib)) + { + debugLock_d1(lock); + + if (fib->fib_DirEntryType > 0) + { + BPTR dirlock; + + if ((dirlock = ParentDir(lock))) + { +// Object *IconObj; + + type = (struct TypeNode *) WBDRAWER; + UnLock(dirlock); + +/* // extra check for WBGARBAGE + IconObj = NewIconObjectTags(Name, + TAG_END); + if (IconObj) + { + GetAttr(IDTA_Type, IconObj, (APTR) &type); + DisposeIconObject(IconObj); + } +*/ + } + else + { + type = DefIconsIdentifyDisk(lock); + } + } + else + { + type = DefIconsIdentifyProject(Name, fib); + } + } + else + { + if (!stricmp(Name, "disk")) + { + BPTR curdir; + + curdir = CurrentDir((BPTR)NULL); + CurrentDir(curdir); + + if ((lock = ParentDir(curdir))) + UnLock(lock); + else + type = (struct TypeNode *)WBDISK; + } + } + + if (fib) + FreeDosObject(DOS_FIB,fib); + if (lock) + UnLock(lock); + + CurrentDir(oldDirLock); + + d1(KPrintF("%s/%s/%ld: type=%08lx\n", __FILE__, __FUNC__, __LINE__, type)); + + return(type); +} + +//---------------------------------------------------------------------------- + +static struct TypeNode *DefIconsIdentifyDisk(BPTR lock) +{ + struct InfoData *infoData = NULL; + struct TypeNode *type = (struct TypeNode *) WBDISK; + STRPTR AllocatedDevName = NULL; + + debugLock_d1(lock); + + do { + struct TypeNode *candidate; + struct TypeNode *tn; + const struct DosList *VolumeNode; + CONST_STRPTR DosDevice = ""; + CONST_STRPTR DeviceName = ""; + ULONG DosType = MAKE_ID('D','O','S',0); + + tn = PrefsInst.fpb_RootType; + while (tn && 0 != Stricmp(tn->tn_Name, "disk")) + tn = tn->tn_RightBrother; + + if (NULL == tn) + break; + + infoData = malloc(sizeof(struct InfoData)); + if (NULL == infoData) + break; + + if (!Info(lock, infoData)) + break; + + type = tn; + d1(KPrintF("%s/%s/%ld: type=<%s>\n", __FILE__, __FUNC__, __LINE__, type->tn_Name)); + d1(KPrintF("%s/%s/%ld: id_NumBlocks=%lu id_DiskType=%08lx id_VolumeNode=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, \ + infoData->id_NumBlocks, infoData->id_DiskType, infoData->id_VolumeNode)); + + VolumeNode = BADDR(infoData->id_VolumeNode); + if (TypeOfMem((APTR) VolumeNode) & MEMF_PUBLIC) + { + d1(KPrintF("%s/%s/%ld: dol_Type=%ld dol_Name=%08lx dol_Task=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, VolumeNode->dol_Type, VolumeNode->dol_Name, VolumeNode->dol_Task)); + + if (VolumeNode->dol_Task && (TypeOfMem(VolumeNode->dol_Task) & MEMF_PUBLIC)) + { + struct Task *DevTask = VolumeNode->dol_Task->mp_SigTask; + + d1(KPrintF("%s/%s/%ld: dol_DiskType=%08lx\n", __FILE__, __FUNC__, __LINE__, VolumeNode->dol_misc.dol_volume.dol_DiskType)); + + DosDevice = DevTask->tc_Node.ln_Name; + d1(KPrintF("%s/%s/%ld: DevTask=<%s>\n", __FILE__, __FUNC__, __LINE__, DosDevice)); + + AllocatedDevName = DefIconsGetDeviceName(DosDevice, &DosType); + if (AllocatedDevName) + DeviceName = AllocatedDevName; + d1(KPrintF("%s/%s/%ld: DeviceName=<%s>\n", __FILE__, __FUNC__, __LINE__, DeviceName)); + } + } +loop: + candidate = type->tn_FirstSon; +loop1: + while (candidate) + { + struct Magic *curr; + BOOL matching = 1; + + + curr = candidate->tn_Description; + + do + { + switch (curr->action) + { + case ACT_END: + if (matching) + { + type = candidate; + goto loop; /* ////// */ + } + break; + + case ACT_OR: + if (matching) + { + type = candidate; + goto loop; /* ////// */ + } + else + { + matching = 1; + } + break; + + case ACT_MATCH: + case ACT_SEARCH: + case ACT_SEARCHSKIPSPACES: + case ACT_FILESIZE: + case ACT_NAMEPATTERN: + case ACT_PROTECTION: + case ACT_ISASCII: + matching = 0; + break; + + case ACT_MINSIZEMB: + if (matching) + { + ULONG BlocksPerMByte = (1024 * 1024) / infoData->id_BytesPerBlock; + + d1(KPrintF("%s/%s/%ld: BlocksPerMByte=%lu id_NumBlocks=%lu\n", __FILE__, __FUNC__, __LINE__, BlocksPerMByte, infoData->id_NumBlocks)); + + if ((infoData->id_NumBlocks / BlocksPerMByte) < curr->arg2) + matching = 0; + } + break; + + case ACT_DOSDEVICE: + if (matching) + { + UBYTE buf[50]; + + matching = 0; + if (ParsePatternNoCase(curr->str, (STRPTR) buf, sizeof(buf)) >= 0 && + MatchPatternNoCase((STRPTR) buf, (STRPTR) DosDevice)) + matching = 1; + } + break; + + case ACT_DEVICENAME: + if (matching) + { + UBYTE buf[50]; + + matching = 0; + if (ParsePatternNoCase(curr->str, (STRPTR) buf, sizeof(buf)) >= 0 && + MatchPatternNoCase((STRPTR) buf, (STRPTR) DeviceName)) + matching = 1; + } + break; + + case ACT_DOSTYPE: + if (matching) + { + UBYTE DosTypeString[5]; + + memcpy(DosTypeString, &DosType, sizeof(DosType)); + DosTypeString[4] = '\0'; + + d1(KPrintF("%s/%s/%ld: arg2=%ld DosType=<%s> str=<%s>\n", __FILE__, __FUNC__, __LINE__, curr->arg2, DosTypeString, curr->str)); + + if (abs(curr->arg2) > sizeof(ULONG) || + match((CONST_STRPTR)DosTypeString, curr->str, curr->arg2)) + { + matching = 0; + } + break; + } + break; + + case ACT_CONTENTS: + if (matching) + { + LONG result; + struct AnchorPath ap; + BPTR OldDir = CurrentDir(lock); + + matching = 0; + + memset(&ap, 0, sizeof(ap)); + ap.ap_Flags |= APF_DOWILD; + + result = MatchFirst(curr->str, &ap); + if (RETURN_OK == result) + matching = 1; + + d1(KPrintF("%s/%s/%ld: str=<%s> result=%ld\n", __FILE__, __FUNC__, __LINE__, curr->str, result)); + + MatchEnd(&ap); + + CurrentDir(OldDir); + } + break; + } + } while ((curr++)->action != ACT_END); + + candidate = candidate->tn_RightBrother; + } + + /* don't consider valid a macroclass alone */ + if (type->tn_Description->action == ACT_MACROCLASS) + { + candidate = type->tn_RightBrother; + type = type->tn_Parent; + goto loop1; /* ////// */ + } + } while (0); + + if (AllocatedDevName) + free(AllocatedDevName); + if (infoData) + free(infoData); + + return type; +} + +//---------------------------------------------------------------------------- + +static struct TypeNode *DefIconsIdentifyProject(CONST_STRPTR Name, struct FileInfoBlock *fib) +{ + UBYTE *Buffer = NULL; + BPTR File = (BPTR) NULL; + struct TypeNode *type = (struct TypeNode *) WBPROJECT; + struct TypeNode *tn; + + tn = PrefsInst.fpb_RootType; + while (tn && 0 != Stricmp(tn->tn_Name, "project")) + tn = tn->tn_RightBrother; + + if (tn && (Buffer = malloc(IOBUFFERLEN)) && (File = Open((STRPTR) Name,MODE_OLDFILE))) + { + WORD Size; + + type = tn; + + d1(KPrintF("%s/%s/%ld: fib_FileName=<%s> type=<%s>\n", __FILE__, __FUNC__, __LINE__, fib->fib_FileName, type->tn_Name)); + + /* Read the first IOBUFFERLEN bytes. */ + if ((Size = Read(File,Buffer,IOBUFFERLEN)) >= 0) + { + struct TypeNode *candidate; + const UBYTE *buf; + +loop: + candidate = type->tn_FirstSon; +loop1: + while (candidate) + { + struct Magic *curr; + BOOL matching = 1; + + + curr = candidate->tn_Description; + buf = Buffer; + + do + { + switch (curr->action) + { + case ACT_END: + if (matching) + { + type = candidate; + goto loop; /* ////// */ + } + break; + + case ACT_OR: + if (matching) + { + type = candidate; + goto loop; /* ////// */ + } + else + { + matching = 1; + buf = Buffer; + } + break; + + case ACT_MATCH: + if (matching) + { + if (Size - (buf - Buffer) < curr->arg1 + abs(curr->arg2) || + match((STRPTR)&buf[curr->arg1],curr->str,abs(curr->arg2))) + matching = 0; + } + break; + + case ACT_SEARCH: + case ACT_SEARCHSKIPSPACES: + if (matching) + { + WORD loop; + + + loop = Size - (buf - Buffer) - abs(curr->arg2); + + while (loop >= 0) + { + if (!match((STRPTR)buf,curr->str,curr->arg2)) + break; + + if (curr->action == ACT_SEARCHSKIPSPACES && !isspace(*buf)) + loop = -1; + else + { + loop--; + buf++; + } + } + + if (loop < 0) matching = 0; + } + break; + + case ACT_FILESIZE: + if (matching) + { + if (fib->fib_Size != curr->arg2) + matching = 0; + } + break; + + case ACT_NAMEPATTERN: + if (matching) + { + UBYTE buf[50]; + + matching = 0; + if (ParsePatternNoCase(curr->str,(STRPTR)buf,sizeof(buf)) >= 0 && + MatchPatternNoCase((STRPTR)buf,fib->fib_FileName)) + matching = 1; + } + break; + + case ACT_PROTECTION: + if (matching) + { + if ((fib->fib_Protection & curr->arg1) != curr->arg2) + matching = 0; + } + break; + + case ACT_ISASCII: + if (matching) + { + matching = 0; + if (Size) + { + buf = &Buffer[Size]; + + while (buf > Buffer && !InvalidTab[*(--buf)]); + + if (buf == Buffer) matching = 1; + } + } + break; + + case ACT_MINSIZEMB: + case ACT_DOSDEVICE: + case ACT_DEVICENAME: + case ACT_CONTENTS: + matching = 0; + break; + } + } while ((curr++)->action != ACT_END); + + candidate = candidate->tn_RightBrother; + } + + /* don't consider valid a macroclass alone */ + if (type->tn_Description->action == ACT_MACROCLASS) + { + candidate = type->tn_RightBrother; + type = type->tn_Parent; + goto loop1; /* ////// */ + } + + if (!stricmp(type->tn_Name,"iff")) + { + struct TypeNode *new; + UBYTE *desc; + + if ((desc = malloc(14))) + { + const UBYTE *descp = desc; + + strncpy((char *)desc,(char *)&Buffer[8],4); + desc[4] = 0; + desc[5] = ACT_MATCH; + desc[6] = 0; + desc[7] = 8; + desc[8] = 4; + strncpy((char *)&desc[9],(char *)&Buffer[8],4); + desc[13] = ACT_END; + + if ((new = AllocTypeNode(&descp))) + { + AddSon(type,new); + + type = new; + } + else + free(desc); + } + } + } + } + + if (File) + Close(File); + if (Buffer) + free(Buffer); + return type; +} + +//---------------------------------------------------------------------------- + +// DosDevice : DOS device name ("DH0"), without trailing ":" +static STRPTR DefIconsGetDeviceName(CONST_STRPTR DosDevice, ULONG *DosType) +{ + STRPTR DevName = NULL; + + do { + struct DosList *dl; + struct FileSysStartupMsg *fssm; + struct DosEnvec *env; + CONST_STRPTR BDevName; + size_t Length; + + dl = LockDosList(LDF_DEVICES | LDF_READ); + + dl = FindDosEntry(dl, DosDevice, LDF_DEVICES); + if (NULL == dl) + break; + + if (BNULL == dl->dol_misc.dol_handler.dol_Startup) + break; + + fssm = BADDR(dl->dol_misc.dol_handler.dol_Startup); + if (!(TypeOfMem(fssm) & MEMF_PUBLIC)) + break; + + if (BNULL == fssm->fssm_Device) + break; + + BDevName = BADDR(fssm->fssm_Device); + if (!(TypeOfMem((APTR) BDevName) & MEMF_PUBLIC)) + break; + + Length = BDevName[0]; + DevName = malloc(1 + Length); + if (NULL == DevName) + break; + + memcpy(DevName, BDevName + 1, Length); + DevName[Length] = '\0'; + + env = BADDR(fssm->fssm_Environ); + if (NULL == env) + break; + if (!(TypeOfMem((APTR) env) & MEMF_PUBLIC)) + break; + + *DosType = env->de_DosType; + } while (0); + + UnLockDosList(LDF_DEVICES | LDF_READ); + + return DevName; +} + +//---------------------------------------------------------------------------- + +/* compare two buffers of length 'len'. These functions cannot be replaced */ +/* with strn(i)cmp() because the buffers may contain NULLs */ +static LONG match(CONST_STRPTR a, CONST_STRPTR b, size_t len) +{ + if (len > 0) /* case sensitive */ + { + while (*a == *b) + { + if (!(--len)) + return(0); + + a++; + b++; + } + } + else /* ignore case */ + { + while (toupper(*a) == toupper(*b)) + { + if (!(++len)) return(0); + + a++; + b++; + } + } + + return(*a - *b); +} + +//---------------------------------------------------------------------------- + + diff --git a/scalos/Modules/Find.MUI/Find.c b/scalos/Modules/Find.MUI/Find.c new file mode 100644 index 000000000..d6384c09a --- /dev/null +++ b/scalos/Modules/Find.MUI/Find.c @@ -0,0 +1,3054 @@ +// Find.c +// $Date$ +// $Revision$ + +#ifdef __AROS__ +#define MUIMASTER_YES_INLINE_STDARG +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include // +jmc+ + +#include "Find.h" +#include "debug.h" + +#define Find_NUMBERS +#define Find_ARRAY +#define Find_CODE +#define Find_NUMBERS +#define Find_ARRAY +#define Find_CODE +#include STR(SCALOSLOCALE) + +//---------------------------------------------------------------------------- + +#if !defined(__amigaos4__) && !defined(__AROS__) +#include + +long _stack = 16384; // minimum stack size, used by SAS/C startup code +#endif + +//---------------------------------------------------------------------------- + +// local data structures + +#define SEARCH_PATTERN_DEFAULT "#?" +#define SEARCH_CONTENTS_DEFAULT "" +#define SEARCH_FILETYPE_DEFAULT "" + +#define BUFFERSIZE (4096*10) /* XXX: perhaps should be 8192 ? test.. */ + +#define USE_EXALL 1 + +// maximum number of popup nlist entries that will be saved persistently +#define MAX_SAVED_NLIST_ENTRIES 10 + +#define KeyButtonHelp(name,key,HelpText)\ + TextObject,\ + ButtonFrame,\ + MUIA_CycleChain, TRUE, \ + MUIA_Font, MUIV_Font_Button,\ + MUIA_Text_Contents, name,\ + MUIA_Text_PreParse, "\33c",\ + MUIA_Text_HiChar , key,\ + MUIA_ControlChar , key,\ + MUIA_InputMode , MUIV_InputMode_RelVerify,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShortHelp, HelpText,\ + End + +struct ResultsListEntry + { + STRPTR rle_Name; + STRPTR rle_Path; + STRPTR rle_CopyString; + }; + +struct FindResult + { + BPTR fr_Lock; // Lock to parent directory + STRPTR fr_Name; // File name + }; + +struct MyNListExport + { + ULONG nle_Size; // Total Size + char nle_Data[0]; // Contents + }; + +//---------------------------------------------------------------------------- + +// local functions + +static void init(void); +static void fail(APTR APP_Main, CONST_STRPTR str); +static BOOL OpenLibraries(void); +static void CloseLibraries(void); +static SAVEDS(APTR) INTERRUPT OpenAboutMUIFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT OpenAboutFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT AppMessageHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT IntuiMessageHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT SelectSourceHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT RemoveSourceHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT AddSourceHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT ResultsConstructHookFunc(struct Hook *hook, APTR unused, struct NList_ConstructMessage *nlcm); +static SAVEDS(void) INTERRUPT ResultsDestructHookFunc(struct Hook *hook, APTR unused, struct NList_DestructMessage *nldm); +static SAVEDS(ULONG) INTERRUPT ResultsDisplayHookFunc(struct Hook *hook, APTR unused, struct NList_DisplayMessage *nldm); +static SAVEDS(LONG) INTERRUPT ResultsCompareHookFunc(struct Hook *hook, Object *obj, struct NList_CompareMessage *ncm); +static SAVEDS(LONG) INTERRUPT ResultsCopyEntryToClipHookFunc(struct Hook *hook, Object *obj, struct NList_CopyEntryToClipMessage *ncm); +static SAVEDS(LONG) INTERRUPT StartSearchHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(LONG) INTERRUPT StopSearchHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(VOID) INTERRUPT OpenResultHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(VOID) INTERRUPT CopyResultsToClipHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(VOID) INTERRUPT OpenResultWithFindHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(VOID) INTERRUPT OpenResultWithMultiviewHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT FileTypesConstructHookFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_ConstructMessage *ltcm); +static SAVEDS(void) INTERRUPT FileTypesDestructHookFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_DestructMessage *ltdm); +static SAVEDS(ULONG) INTERRUPT FileTypesDisplayHookFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_DisplayMessage *ltdm); +static SAVEDS(LONG) INTERRUPT HideFindHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(LONG) INTERRUPT PatternHistoryHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(LONG) INTERRUPT ContentsHistoryHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(LONG) INTERRUPT FiletypeSelectHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(LONG) INTERRUPT CheckEmptyStringsHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(LONG) INTERRUPT FindFileTypeHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(LONG) INTERRUPT FindNextFileTypeHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT CollapseFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT ExpandFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT CollapseAllFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT ExpandAllFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT SelectFileTypesEntryHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(VOID) INTERRUPT FileTypesPopupWindowHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(VOID) INTERRUPT ClearHistoryHookFunc(struct Hook *hook, Object *o, Msg msg); + +static void StartSearch(void); +static void DoSearchPath(CONST_STRPTR Path, CONST_STRPTR Pattern, + CONST_STRPTR Contents, CONST_STRPTR Filetype); +static void DoSearchDir(BPTR DirLock, CONST_STRPTR Pattern, + CONST_STRPTR Contents, CONST_STRPTR Filetype); +static void SearchEntry(BPTR DirLock, CONST_STRPTR Name, LONG DirEntryType, + CONST_STRPTR Pattern, CONST_STRPTR Contents, CONST_STRPTR Filetype); +static void SearchFile(CONST_STRPTR FileName, CONST_STRPTR Pattern, + CONST_STRPTR Contents, CONST_STRPTR Filetype); +static void preQsBc(const UBYTE *x, LONG m, LONG qsBc[]); +static BOOL SearchTypeNodeTree(const struct TypeNode *tn, CONST_STRPTR Name); +static LONG QuickSearch(const UBYTE *x, LONG m, UBYTE *y, LONG n); +static BOOL MatchFileContents(BPTR fh, CONST_STRPTR Contents); + +static STRPTR GetLocString(ULONG MsgId); +//static void TranslateStringArray(STRPTR *stringArray); +static void TranslateNewMenu(struct NewMenu *nm); + +static void FillSourcesList(struct WBStartup *WBenchMsg); +static Object *MyPopButton(ULONG img); +BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev); +static BOOL SearchFileType(CONST_STRPTR SearchString, BOOL SearchNext); +static LONG GetElapsedTime(T_TIMEVAL *tv); +static struct MUI_NListtree_TreeNode *FindPatternInListtree(Object *lt, + struct MUI_NListtree_TreeNode *list, CONST_STRPTR pattern, + struct MUI_NListtree_TreeNode *startnode, ULONG *dosearch); +static void AddSourcesLine(CONST_STRPTR NewSourcePath); +static void PushEntry(Object *NList, CONST_STRPTR Contents, LONG Position); +static void ExportNList(Class *cl, Object *obj, struct MUIP_Export *msg); +static void ImportNList(Class *cl, Object *obj, struct MUIP_Import *msg); + +//---------------------------------------------------------------------------- + +static struct Hook AboutHook = {{ NULL, NULL }, HOOKFUNC_DEF(OpenAboutFunc), NULL }; +static struct Hook AboutMUIHook = {{ NULL, NULL }, HOOKFUNC_DEF(OpenAboutMUIFunc), NULL }; +static struct Hook AppMessageHook = {{ NULL, NULL }, HOOKFUNC_DEF(AppMessageHookFunc), NULL }; +static struct Hook SelectSourceHook = {{ NULL, NULL }, HOOKFUNC_DEF(SelectSourceHookFunc), NULL }; +static struct Hook RemoveSourceHook = {{ NULL, NULL }, HOOKFUNC_DEF(RemoveSourceHookFunc), NULL }; +static struct Hook AddSourceHook = {{ NULL, NULL }, HOOKFUNC_DEF(AddSourceHookFunc), NULL }; +static struct Hook ResultsConstructHook = {{ NULL, NULL }, HOOKFUNC_DEF(ResultsConstructHookFunc), NULL }; +static struct Hook ResultsDestructHook = {{ NULL, NULL }, HOOKFUNC_DEF(ResultsDestructHookFunc), NULL }; +static struct Hook ResultsDisplayHook = {{ NULL, NULL }, HOOKFUNC_DEF(ResultsDisplayHookFunc), NULL }; +static struct Hook ResultsCompareHook = {{ NULL, NULL }, HOOKFUNC_DEF(ResultsCompareHookFunc), NULL }; +static struct Hook ResultsCopyEntryToClipHook = {{ NULL, NULL }, HOOKFUNC_DEF(ResultsCopyEntryToClipHookFunc), NULL }; +static struct Hook StartSearchHook = {{ NULL, NULL }, HOOKFUNC_DEF(StartSearchHookFunc), NULL }; +static struct Hook StopSearchHook = {{ NULL, NULL }, HOOKFUNC_DEF(StopSearchHookFunc), NULL }; +static struct Hook IntuiMessageHook = {{ NULL, NULL }, HOOKFUNC_DEF(IntuiMessageHookFunc), NULL }; +static struct Hook OpenResultHook = {{ NULL, NULL }, HOOKFUNC_DEF(OpenResultHookFunc), NULL }; +static struct Hook CopyResultsToClipHook = {{ NULL, NULL }, HOOKFUNC_DEF(CopyResultsToClipHookFunc), NULL }; +static struct Hook FileTypesConstructHook = {{ NULL, NULL }, HOOKFUNC_DEF(FileTypesConstructHookFunc), NULL }; +static struct Hook FileTypesDestructHook = {{ NULL, NULL }, HOOKFUNC_DEF(FileTypesDestructHookFunc), NULL }; +static struct Hook FileTypesDisplayHook = {{ NULL, NULL }, HOOKFUNC_DEF(FileTypesDisplayHookFunc), NULL }; +static struct Hook HideFindHook = {{ NULL, NULL }, HOOKFUNC_DEF(HideFindHookFunc), NULL }; +static struct Hook PatternHistoryHook = {{ NULL, NULL }, HOOKFUNC_DEF(PatternHistoryHookFunc), NULL }; +static struct Hook ContentsHistoryHook = {{ NULL, NULL }, HOOKFUNC_DEF(ContentsHistoryHookFunc), NULL }; +static struct Hook FiletypeSelectHook = {{ NULL, NULL }, HOOKFUNC_DEF(FiletypeSelectHookFunc), NULL }; +static struct Hook CheckEmptyStringsHook = {{ NULL, NULL }, HOOKFUNC_DEF(CheckEmptyStringsHookFunc), NULL }; +static struct Hook FindFileTypeHook = {{ NULL, NULL }, HOOKFUNC_DEF(FindFileTypeHookFunc), NULL }; +static struct Hook FindNextFileTypeHook = {{ NULL, NULL }, HOOKFUNC_DEF(FindNextFileTypeHookFunc), NULL }; +static struct Hook CollapseFileTypesHook = {{ NULL, NULL }, HOOKFUNC_DEF(CollapseFileTypesHookFunc), NULL }; +static struct Hook ExpandFileTypesHook = {{ NULL, NULL }, HOOKFUNC_DEF(ExpandFileTypesHookFunc), NULL }; +static struct Hook CollapseAllFileTypesHook = {{ NULL, NULL }, HOOKFUNC_DEF(CollapseAllFileTypesHookFunc), NULL }; +static struct Hook ExpandAllFileTypesHook = {{ NULL, NULL }, HOOKFUNC_DEF(ExpandAllFileTypesHookFunc), NULL }; +static struct Hook ClearHistoryHook = {{ NULL, NULL }, HOOKFUNC_DEF(ClearHistoryHookFunc), NULL }; +static struct Hook SelectFileTypesEntryHook = {{ NULL, NULL }, HOOKFUNC_DEF(SelectFileTypesEntryHookFunc), NULL }; +static struct Hook FileTypesPopupWindowHook = {{ NULL, NULL }, HOOKFUNC_DEF(FileTypesPopupWindowHookFunc), NULL }; +static struct Hook OpenResultWithFindHook = {{ NULL, NULL }, HOOKFUNC_DEF(OpenResultWithFindHookFunc), NULL }; +static struct Hook OpenResultWithMultiviewHook = {{ NULL, NULL }, HOOKFUNC_DEF(OpenResultWithMultiviewHookFunc), NULL }; + +//---------------------------------------------------------------------------- + +// Context menu in "results" list +static struct NewMenu NewContextMenuResults[] = + { + { NM_TITLE, (STRPTR) MSGID_MENU_RESULTS_TITLE, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_RESULTS_OPEN, NULL, 0, 0, &OpenResultWithMultiviewHook }, + { NM_ITEM, (STRPTR) MSGID_MENU_RESULTS_OPENDRAWER, NULL, 0, 0, &OpenResultHook }, + { NM_ITEM, (STRPTR) MSGID_MENU_RESULTS_COPYTOCLIP, NULL, 0, 0, &CopyResultsToClipHook }, + { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_RESULTS_FIND, NULL, 0, 0, &OpenResultWithFindHook }, + { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_ABOUT, NULL, 0, 0, (APTR) &AboutHook }, + + { NM_END, NULL, NULL, 0, 0, 0,}, + }; + +// Context menu in "filetypes" list +static struct NewMenu NewContextMenuFileTypes[] = + { + { NM_TITLE, (STRPTR) MSGID_MENU_FILETYPES_TITLE, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_EDIT_COLLAPSE, NULL, NM_ITEMDISABLED, 0, (APTR) &CollapseFileTypesHook }, + { NM_ITEM, (STRPTR) MSGID_MENU_EDIT_EXPAND, NULL, NM_ITEMDISABLED, 0, (APTR) &ExpandFileTypesHook }, + { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_EDIT_COLLAPSEALL, NULL, 0, 0, (APTR) &CollapseAllFileTypesHook }, + { NM_ITEM, (STRPTR) MSGID_MENU_EDIT_EXPANDALL, NULL, 0, 0, (APTR) &ExpandAllFileTypesHook }, + { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_ABOUT, NULL, 0, 0, (APTR) &AboutHook }, + + { NM_END, NULL, NULL, 0, 0, 0,}, + }; + +// Context menu in "pattern" and "contents" history popup list +static struct NewMenu NewContextMenuHistoryPopup[] = + { + { NM_TITLE, (STRPTR) MSGID_MENU_FILETYPES_TITLE, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_CLEARHISTORY, NULL, 0, 0, (APTR) &ClearHistoryHook }, + { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_ABOUT, NULL, 0, 0, (APTR) &AboutHook }, + + { NM_END, NULL, NULL, 0, 0, 0,}, + }; + +//---------------------------------------------------------------------------- + +// local data items + +struct IntuitionBase *IntuitionBase = NULL; +struct Library *MUIMasterBase = NULL; +struct ScalosBase *ScalosBase = NULL; +T_LOCALEBASE LocaleBase = NULL; +T_TIMERBASE TimerBase; + +#ifdef __amigaos4__ +struct IntuitionIFace *IIntuition = NULL; +struct MUIMasterIFace *IMUIMaster = NULL; +struct ScalosIFace *IScalos = NULL; +struct LocaleIFace *ILocale = NULL; +struct TimerIFace *ITimer; +#endif + +static struct Catalog *FindCatalog; + +static BOOL StopSearch = FALSE; + +static Object *APP_Main; +static Object *WIN_Main; +static Object *WIN_AboutMUI; +static Object *NListviewSources, *NListSources; +static Object *StringNewSource; +static Object *NListResults; +static Object *StringFilePattern, *StringFileContents, *StringFileType; +static Object *TextCurrentFile; +static Object *GroupFindFiletype; +static Object *ButtonHideFind; +static Object *PopObjectPattern, *PopObjectContents, *PopObjectFiletypes; +static Object *NListPatternHistory, *NListContentsHistory; +static Object *ButtonSearch, *ButtonStop; +static Object *StringFindFileType; +static Object *ButtonFindNextFileType; +static Object *ButtonAddSource, *ButtonRemoveSource; +static Object *PopAslNewSource; +static Object *MenuAbout, *MenuAboutMUI, *MenuQuit; +static Object *MenuExpandFileTypes, *MenuCollapseFileTypes; +static Object *ContextMenuResults; +static Object *ContextMenuFileTypes; +static Object *ContextMenuPatternPopup, *ContextMenuContentsPopup; + +Object *ListtreeFileTypes; + +struct WBStartup *WBenchMsg; + +static char CurrentPath[1024]; + +static T_TIMEREQUEST *TimerIO; +static struct MsgPort *TimerPort; +static T_TIMEVAL LastUpdate; + +DISPATCHER_PROTO(myFindResultsNList); +DISPATCHER_PROTO(myFileTypesNListTree); +DISPATCHER_PROTO(myPersistentNList); +DISPATCHER_PROTO(myPopObject); + +static struct MUI_CustomClass *myFindResultsNListClass; +static struct MUI_CustomClass *myFileTypesNListTreeClass; +static struct MUI_CustomClass *myPersistentNListClass; +static struct MUI_CustomClass *myPopObjectClass; + + +#if defined(__AROS__) +#define FindResultsNListObject BOOPSIOBJMACRO_START(myFindResultsNListClass->mcc_Class) +#define FileTypesNListTreeObject BOOPSIOBJMACRO_START(myFileTypesNListTreeClass->mcc_Class) +#define PersistentNListObject BOOPSIOBJMACRO_START(myPersistentNListClass->mcc_Class) +#define PopObject BOOPSIOBJMACRO_START(myPopObjectClass->mcc_Class) +#else +#define FindResultsNListObject NewObject(myFindResultsNListClass->mcc_Class, NULL +#define FileTypesNListTreeObject NewObject(myFileTypesNListTreeClass->mcc_Class, NULL +#define PersistentNListObject NewObject(myPersistentNListClass->mcc_Class, NULL +#define PopObject NewObject(myPopObjectClass->mcc_Class, NULL +#endif + +//---------------------------------------------------------------------------- + +int main(int argc, char *argv[]) +{ + LONG win_opened; + + WBenchMsg = (argc == 0) ? (struct WBStartup *)argv : NULL; + + init(); + + if (!CheckMCCVersion(MUIC_NListview, 19, 66) + || !CheckMCCVersion(MUIC_NListtree, 18, 18)) + { + d1(KPrintF(__FILE__ "/%s/%ld: CheckMCCVersion failed\n", __FUNC__, __LINE__)); + return 10; + } + + ContextMenuResults = MUI_MakeObject(MUIO_MenustripNM, NewContextMenuResults, 0); + if (NULL == ContextMenuResults) + { + fail(APP_Main, "Failed to create Results Context Menu."); + } + + ContextMenuFileTypes = MUI_MakeObject(MUIO_MenustripNM, NewContextMenuFileTypes, 0); + if (NULL == ContextMenuFileTypes) + { + fail(APP_Main, "Failed to create Filetypes Context Menu."); + } + + ContextMenuPatternPopup = MUI_MakeObject(MUIO_MenustripNM, NewContextMenuHistoryPopup, 0); + if (NULL == ContextMenuPatternPopup) + { + fail(APP_Main, "Failed to create Pattern Popup Context Menu."); + } + + ContextMenuContentsPopup = MUI_MakeObject(MUIO_MenustripNM, NewContextMenuHistoryPopup, 0); + if (NULL == ContextMenuContentsPopup) + { + fail(APP_Main, "Failed to create Contents Popup Context Menu."); + } + + APP_Main = ApplicationObject, + MUIA_Application_Title, GetLocString(MSGID_TITLENAME), + MUIA_Application_Version, "$VER: Scalos Find.module V" VERS_MAJOR "." VERS_MINOR " (" __DATE__ ") " COMPILER_STRING, + MUIA_Application_Copyright, "© The Scalos Team, 2008" CURRENTYEAR, + MUIA_Application_Author, "The Scalos Team", + MUIA_Application_Description, "Scalos Find module", + MUIA_Application_Base, "SCALOS_FIND_MODULE", + + SubWindow, WIN_Main = WindowObject, + MUIA_Window_Title, GetLocString(MSGID_TITLENAME), + MUIA_Window_ID, MAKE_ID('M','A','I','N'), + MUIA_Window_AppWindow, TRUE, + + WindowContents, VGroup, + + Child, HGroup, + Child, VGroup, + Child, ColGroup(2), + Child, Label1(GetLocString(MSGID_POPSTRING_NAME)), + Child, PopObjectPattern = PopObject, + MUIA_Popstring_Button, MyPopButton(MUII_PopUp), + MUIA_Popstring_String, StringFilePattern = StringObject, + StringFrame, + MUIA_CycleChain, TRUE, + MUIA_String_Contents, SEARCH_PATTERN_DEFAULT, + End, //StringObject + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_POPSTRING_NAME_SHORTHELP), + MUIA_Popobject_Object, VGroup, + Child, NListviewObject, + MUIA_NListview_NList, NListPatternHistory = PersistentNListObject, + MUIA_ObjectID, OBJID_NLIST_NAME, + MUIA_ContextMenu, ContextMenuPatternPopup, + MUIA_NList_Exports, MUIV_NList_Exports_All, + MUIA_NList_Imports, MUIV_NList_Imports_All, + MUIA_NList_ConstructHook, MUIV_NList_ConstructHook_String, + MUIA_NList_DestructHook, MUIV_NList_DestructHook_String, + End, //NListObject + End, //NListviewObject + End, //VGroup + End, //PopobjectObject + + Child, Label1(GetLocString(MSGID_POPSTRING_TEXT)), + Child, PopObjectContents = PopObject, + MUIA_Popstring_Button, MyPopButton(MUII_PopUp), + MUIA_Popstring_String, StringFileContents = StringObject, + StringFrame, + MUIA_CycleChain, TRUE, + MUIA_String_Contents, SEARCH_CONTENTS_DEFAULT, + End, //StringObject + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_POPSTRING_TEXT_SHORTHELP), + MUIA_Popobject_Object, VGroup, + Child, NListviewObject, + MUIA_NListview_NList, NListContentsHistory = PersistentNListObject, + MUIA_ObjectID, OBJID_NLIST_TEXT, + MUIA_ContextMenu, ContextMenuContentsPopup, + MUIA_NList_Exports, MUIV_NList_Exports_All, + MUIA_NList_Imports, MUIV_NList_Imports_All, + MUIA_NList_ConstructHook, MUIV_NList_ConstructHook_String, + MUIA_NList_DestructHook, MUIV_NList_DestructHook_String, + End, //NListObject + End, //NListviewObject + End, //VGroup + End, //PopobjectObject + + Child, Label1(GetLocString(MSGID_POPSTRING_TYPE)), + Child, PopObjectFiletypes = PopObject, + MUIA_Popstring_Button, MyPopButton(MUII_PopUp), + MUIA_Popstring_String, StringFileType = StringObject, + StringFrame, + MUIA_CycleChain, TRUE, + MUIA_String_Contents, SEARCH_FILETYPE_DEFAULT, + End, //StringObject + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_POPSTRING_TYPE_SHORTHELP), + MUIA_Popobject_WindowHook, &FileTypesPopupWindowHook, + MUIA_Popobject_Object, VGroup, + Child, NListviewObject, + MUIA_CycleChain, TRUE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_SHORTHELP_LISTVIEW_FILETYPES), + MUIA_NListview_NList, ListtreeFileTypes = FileTypesNListTreeObject, + MUIA_Background, MUII_ListBack, + MUIA_NListtree_DisplayHook, &FileTypesDisplayHook, + MUIA_NListtree_ConstructHook, &FileTypesConstructHook, + MUIA_NListtree_DestructHook, &FileTypesDestructHook, + MUIA_NListtree_FindNameHook, MUIV_NListtree_FindNameHook_PartCaseInsensitive, + MUIA_NListtree_EmptyNodes, TRUE, + MUIA_NListtree_AutoVisible, MUIV_NListtree_AutoVisible_Expand, + MUIA_ContextMenu, ContextMenuFileTypes, + End, //myFileTypesNListTreeClass + End, //NListviewObject + Child, GroupFindFiletype = HGroup, + GroupFrame, + Child, ButtonHideFind = TextObject, + MUIA_Weight, 10, + ButtonFrame, + MUIA_CycleChain, TRUE, +#if defined(MUII_Close) + MUIA_Text_Contents, MUIX_C "\33I[6:" STR(MUII_Close) "]", +#else + MUIA_Text_Contents, MUIX_C "\33I[6:" STR(MUII_TapeStop) "]", +#endif + MUIA_InputMode, MUIV_InputMode_RelVerify, + MUIA_Background, MUII_ButtonBack, + MUIA_ShortHelp, GetLocString(MSGID_BUTTON_FIND_HIDE_SHORTHELP), + End, + + Child, StringFindFileType = StringObject, + MUIA_CycleChain, TRUE, + StringFrame, + End, //StringObject + Child, ButtonFindNextFileType = KeyButtonHelp(GetLocString(MSGID_BUTTON_FIND_NEXT), + *GetLocString(MSGID_BUTTON_FIND_NEXT_KEY), + GetLocString(MSGID_BUTTON_FIND_NEXT_SHORTHELP)), + End, //HGroup + End, //VGroup + End, //PopobjectObject + + End, //ColGroup + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_GROUP_SOURCES), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, NListviewSources = NListviewObject, + MUIA_NListview_NList, NListSources = NListObject, + MUIA_CycleChain, TRUE, + MUIA_NList_ConstructHook, MUIV_NList_ConstructHook_String, + MUIA_NList_DestructHook, MUIV_NList_DestructHook_String, + End, //NListObject + End, //NListviewObject + + Child, HGroup, + Child, PopAslNewSource = PopaslObject, + MUIA_CycleChain, TRUE, + MUIA_Popasl_Type, ASL_FileRequest, + MUIA_Popstring_Button, MyPopButton(MUII_PopDrawer), + MUIA_Popstring_String, StringNewSource = StringObject, + StringFrame, + MUIA_CycleChain, TRUE, + End, //StringObject + + ASLFR_TitleText, (ULONG) GetLocString(MSGID_GROUP_SOURCES_ASLTITLE), + ASLFR_DrawersOnly, TRUE, + ASLFR_IntuiMsgFunc, &IntuiMessageHook, + End, //PopaslObject + + Child, ButtonAddSource = KeyButtonHelp(GetLocString(MSGID_BUTTON_ADD), + *GetLocString(MSGID_BUTTON_ADD_KEY), + GetLocString(MSGID_BUTTON_ADD_SHORTHELP)), + Child, ButtonRemoveSource = KeyButtonHelp(GetLocString(MSGID_BUTTON_REMOVE), + *GetLocString(MSGID_BUTTON_REMOVE_KEY), + GetLocString(MSGID_BUTTON_REMOVE_SHORTHELP)), + End, //HGroup + End, //VGroup + End, //VGroup + + Child, BalanceObject, + End, // BalanceObject + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_GROUP_RESULTS), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, NListviewObject, + //MUIA_CycleChain, TRUE, + MUIA_NListview_Horiz_ScrollBar, MUIV_NListview_HSB_FullAuto, + MUIA_NListview_NList, NListResults = FindResultsNListObject, + MUIA_CycleChain, TRUE, + MUIA_NList_Format, "BAR,BAR,", + MUIA_NList_ConstructHook2, &ResultsConstructHook, + MUIA_NList_DestructHook2, &ResultsDestructHook, + MUIA_NList_DisplayHook2, &ResultsDisplayHook, + MUIA_NList_CompareHook2, &ResultsCompareHook, + MUIA_NList_CopyEntryToClipHook2, &ResultsCopyEntryToClipHook, + MUIA_NList_TitleSeparator, TRUE, + MUIA_NList_Title, TRUE, + MUIA_NList_SortType, 0, + MUIA_ContextMenu, ContextMenuResults, + MUIA_NList_TitleMark, MUIV_NList_TitleMark_Down | 0, + End, //NListObject + End, //NListviewObject + + End, //VGroup + + End, // HGroup + + Child, TextCurrentFile = TextObject, + MUIA_Text_Contents, "", + End, //TextObject + + Child, ColGroup(2), + Child, ButtonSearch = KeyButtonHelp(GetLocString(MSGID_BUTTON_SEARCH), + *GetLocString(MSGID_BUTTON_SEARCH_KEY), + GetLocString(MSGID_BUTTON_SEARCH_SHORTHELP)), + Child, ButtonStop = KeyButtonHelp(GetLocString(MSGID_BUTTON_STOP), + *GetLocString(MSGID_BUTTON_STOP_KEY), + GetLocString(MSGID_BUTTON_STOP_SHORTHELP)), + End, //ColGroup + End, //VGroup + End, //WindowObject + + MUIA_Application_Menustrip, MenustripObject, + Child, MenuObjectT(GetLocString(MSGID_MENU_PROJECT)), + + Child, MenuAbout = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUT), + End, + Child, MenuAboutMUI = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUTMUI), + End, + Child, MenuitemObject, + MUIA_Menuitem_Title, -1, + End, + Child, MenuQuit = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_QUIT), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_PROJECT_QUIT_SHORT), + End, + + End, //MenuObjectT + + End, //MenuStripObject + + End; //ApplicationObject + + if (NULL == APP_Main) + { + fail(APP_Main, "Failed to create Application."); + } + + InitDefIcons(); + + DoMethod(APP_Main, MUIM_Application_Load, MUIV_Application_Load_ENV); + + //--------------------------------------------------------------------------// + + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + WIN_Main, 3, MUIM_Set, MUIA_Window_Open, FALSE); + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + DoMethod(ButtonStop, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_CallHook, &StopSearchHook); + DoMethod(ButtonSearch, MUIM_Notify,MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_CallHook, &StartSearchHook); + + //--------------------------------------------------------------------------// + + // Find selected entries from context menus + MenuExpandFileTypes = (Object *) DoMethod(ContextMenuFileTypes, + MUIM_FindUData, &ExpandFileTypesHook); + MenuCollapseFileTypes = (Object *) DoMethod(ContextMenuFileTypes, + MUIM_FindUData, &CollapseFileTypesHook); + + // activate StringFilePattern on startup + set(WIN_Main, MUIA_Window_ActiveObject, StringFilePattern); + + set(ButtonStop, MUIA_Disabled, TRUE); + set(ButtonRemoveSource, MUIA_Disabled, TRUE); + + // Call hook whenever an entry in sources list is selected + DoMethod(NListSources, MUIM_Notify, MUIA_NList_SelectChange, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &SelectSourceHook); + // Call hook whenever "remove source" button is clicked + DoMethod(ButtonRemoveSource, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_CallHook, &RemoveSourceHook); + // Call hook whenever "add source" button is clicked + DoMethod(ButtonAddSource, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_CallHook, &AddSourceHook); + + // Call Add Source hook whenever return is hit in source string gadget + DoMethod(StringNewSource, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &AddSourceHook); + + // Start Search whenever return it hit in "name" string gadget + DoMethod(StringFilePattern, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &StartSearchHook); + + // Start Search whenever return it hit in "text" string gadget + DoMethod(StringFileContents, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &StartSearchHook); + + // Call the AppMsgHook when an icon is dropped on sources listview + DoMethod(NListviewSources, MUIM_Notify, MUIA_AppMessage, MUIV_EveryTime, + NListviewSources, 3, MUIM_CallHook, &AppMessageHook, MUIV_TriggerValue); + + // Call OpenResultHook when an result entry is double-clicked + DoMethod(NListResults, MUIM_Notify, MUIA_NList_DoubleClick, MUIV_EveryTime, + APP_Main, 3, MUIM_CallHook, &OpenResultHook, MUIV_TriggerValue); + + // Call HideFindHook when Find Filetype Hide button is clicked + DoMethod(ButtonHideFind, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_CallHook, &HideFindHook); + + // Call PatternHistoryHook when an entry in pattern history is double-clicked + DoMethod(NListPatternHistory, MUIM_Notify, MUIA_NList_DoubleClick, MUIV_EveryTime, + APP_Main, 3, MUIM_CallHook, &PatternHistoryHook, MUIV_TriggerValue); + + // Call ContentsHistoryHook when an entry in contents history is double-clicked + DoMethod(NListContentsHistory, MUIM_Notify, MUIA_NList_DoubleClick, MUIV_EveryTime, + APP_Main, 3, MUIM_CallHook, &ContentsHistoryHook, MUIV_TriggerValue); + + // Call FiletypeSelectHook when a filetype is double-clicked + DoMethod(ListtreeFileTypes, MUIM_Notify, MUIA_NListtree_DoubleClick, MUIV_EveryTime, + APP_Main, 3, MUIM_CallHook, &FiletypeSelectHook, MUIV_TriggerValue); + + // on every contents change, check all 3 search string gadgets, + // and disable "start search" button if all strings are empty + DoMethod(StringFilePattern, MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &CheckEmptyStringsHook); + DoMethod(StringFileContents, MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &CheckEmptyStringsHook); + DoMethod(StringFileType, MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &CheckEmptyStringsHook); + + // Call FindFileTypeHook everytime the contents of StringFindFileType changes + DoMethod(StringFindFileType, MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &FindFileTypeHook); + + // Call FindNextFileTypeHook when "Next" button is clicked + DoMethod(ButtonFindNextFileType, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_CallHook, &FindNextFileTypeHook); + + // call hook everytime a new filetype is selected + DoMethod(ListtreeFileTypes, MUIM_Notify, MUIA_NListtree_Active, MUIV_EveryTime, + ListtreeFileTypes, 3, MUIM_CallHook, &SelectFileTypesEntryHook, MUIV_TriggerValue ); + + // setup sorting hooks for plugin list + DoMethod(NListResults, MUIM_Notify, MUIA_NList_TitleClick, MUIV_EveryTime, + NListResults, 4, MUIM_NList_Sort3, MUIV_TriggerValue, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_Both); + DoMethod(NListResults, MUIM_Notify, MUIA_NList_TitleClick2, MUIV_EveryTime, + NListResults, 4, MUIM_NList_Sort3, MUIV_TriggerValue, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_2); + DoMethod(NListResults, MUIM_Notify, MUIA_NList_SortType, MUIV_EveryTime, + NListResults, 3, MUIM_Set, MUIA_NList_TitleMark, MUIV_TriggerValue); + DoMethod(NListResults, MUIM_Notify, MUIA_NList_SortType2, MUIV_EveryTime, + NListResults, 3, MUIM_Set, MUIA_NList_TitleMark2, MUIV_TriggerValue); + + //--------------------------------------------------------------------------// + + DoMethod(MenuAbout, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &AboutHook); + DoMethod(MenuAboutMUI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &AboutMUIHook); + DoMethod(MenuQuit, MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + FillSourcesList(WBenchMsg); + + set(WIN_Main, MUIA_Window_Open, TRUE); + get(WIN_Main, MUIA_Window_Open, &win_opened); + + if (win_opened) + { + ULONG sigs = 0; + BOOL Run = TRUE; + + while (Run) + { + ULONG Action = DoMethod(APP_Main, MUIM_Application_NewInput, &sigs); + + switch (Action) + { + case MUIV_Application_ReturnID_Quit: + Run = FALSE; + break; + default: + break; + } + + if (Run && sigs) + { + sigs = Wait(sigs | SIGBREAKF_CTRL_C); + + if (sigs & SIGBREAKF_CTRL_C) + { + Run = FALSE; + } + } + } + } + else + { + printf("failed to open main window !\n"); + } + + set(WIN_Main, MUIA_Window_Open, FALSE); + + DoMethod(APP_Main, MUIM_Application_Save, MUIV_Application_Save_ENV); + DoMethod(APP_Main, MUIM_Application_Save, MUIV_Application_Save_ENVARC); + + fail(APP_Main, NULL); + + return 0; +} + +//---------------------------------------------------------------------------- + +static VOID fail(APTR APP_Main, CONST_STRPTR str) +{ + CleanupDefIcons(); + + if (APP_Main) + { + MUI_DisposeObject(APP_Main); + } + if (ContextMenuFileTypes) + { + MUI_DisposeObject(ContextMenuFileTypes); + ContextMenuFileTypes = NULL; + } + if (ContextMenuPatternPopup) + { + MUI_DisposeObject(ContextMenuPatternPopup); + ContextMenuPatternPopup = NULL; + } + if (ContextMenuContentsPopup) + { + MUI_DisposeObject(ContextMenuContentsPopup); + ContextMenuContentsPopup = NULL; + } + if (ContextMenuResults) + { + MUI_DisposeObject(ContextMenuResults); + ContextMenuResults = NULL; + } + if (FindCatalog) + { + CloseCatalog(FindCatalog); + FindCatalog = NULL; + } + if (myPopObjectClass) + { + MUI_DeleteCustomClass(myPopObjectClass); + myPopObjectClass = 0; + } + if (myPersistentNListClass) + { + MUI_DeleteCustomClass(myPersistentNListClass); + myPersistentNListClass = NULL; + } + if (myFindResultsNListClass) + { + MUI_DeleteCustomClass(myFindResultsNListClass); + myFindResultsNListClass = NULL; + } + if (myFileTypesNListTreeClass) + { + MUI_DeleteCustomClass(myFileTypesNListTreeClass); + myFileTypesNListTreeClass = NULL; + } + + CloseLibraries(); + + if (str) + { + puts(str); + exit(20); + } + + exit(0); +} + +//---------------------------------------------------------------------------- + +DISPATCHER(myPopObject) +{ + ULONG Result; + Object *opop = NULL; + + d1(kprintf(__FILE__ "/%s/%ld: MethodID=%08lx\n", __FUNC__, __LINE__, msg->MethodID)); + + switch(msg->MethodID) + { + case MUIM_Export: + d1(KPrintF("%s/%ld: MUIM_Export\n", __FUNC__, __LINE__)); + + get(obj, MUIA_Popobject_Object, &opop); + if (opop) + DoMethodA(opop, msg); + + Result = DoSuperMethodA(cl, obj, msg); + break; + + case MUIM_Import: + d1(KPrintF("%s/%ld: MUIM_Import\n", __FUNC__, __LINE__)); + + get(obj, MUIA_Popobject_Object, &opop); + if (opop) + DoMethodA(opop, msg); + + Result = DoSuperMethodA(cl, obj, msg); + break; + + default: + Result = DoSuperMethodA(cl, obj, msg); + } + + return Result; +} +DISPATCHER_END + +//---------------------------------------------------------------------------- + +DISPATCHER(myPersistentNList) +{ + ULONG Result; + + d1(KPrintF(__FILE__ "/%s/%ld: MethodID=%08lx\n", __FUNC__, __LINE__, msg->MethodID)); + + switch(msg->MethodID) + { + case MUIM_Export: + d1(KPrintF("%s/%ld: MUIM_Export id=%08lx\n", __FUNC__, __LINE__, muiNotifyData(obj)->mnd_ObjectID)); + Result = DoSuperMethodA(cl, obj, msg); + ExportNList(cl, obj, (struct MUIP_Export *) msg); + d1(KPrintF(__FILE__ "/%s/%ld: Result=%ld\n", __FUNC__, __LINE__, Result)); + break; + + case MUIM_Import: + d1(KPrintF("%s/%ld: MUIM_Import id=%08lx\n", __FUNC__, __LINE__, muiNotifyData(obj)->mnd_ObjectID)); + //Result = DoSuperMethodA(cl, obj, msg); + ImportNList(cl, obj, (struct MUIP_Import *) msg); + Result = 0; + d1(KPrintF(__FILE__ "/%s/%ld: Result=%ld\n", __FUNC__, __LINE__, Result)); + break; + + case MUIM_ContextMenuChoice: + { + struct MUIP_ContextMenuChoice *cmc = (struct MUIP_ContextMenuChoice *) msg; + Object *MenuObj; + struct Hook *MenuHook = NULL; + + d1(kprintf("%s/%ld: MUIM_ContextMenuChoice item=%08lx\n", __FUNC__, __LINE__, cmc->item)); + + MenuObj = cmc->item; + + d1(kprintf("%s/%ld: MenuObj=%08lx\n", __FUNC__, __LINE__, MenuObj)); + d1(kprintf("%s/%ld: msg=%08lx *msg=%08lx\n", __FUNC__, __LINE__, msg, *((ULONG *) msg))); + + get(MenuObj, MUIA_UserData, &MenuHook); + + d1(kprintf("%s/%ld: MenuHook=%08lx\n", __FUNC__, __LINE__, MenuHook)); + if (MenuHook) + DoMethod(obj, MUIM_CallHook, MenuHook, 0); + + Result = 0; + } + break; + + default: + Result = DoSuperMethodA(cl, obj, msg); + } + + d1(KPrintF(__FILE__ "/%s/%ld: MethodID=%08lx Result=%ld\n", __FUNC__, __LINE__, msg->MethodID, Result)); + + return Result; +} +DISPATCHER_END + +//---------------------------------------------------------------------------- + +DISPATCHER(myFindResultsNList) +{ + ULONG Result; + + d1(kprintf(__FILE__ "/%s/%ld: MethodID=%08lx\n", __FUNC__, __LINE__, msg->MethodID)); + + switch(msg->MethodID) + { + case MUIM_Export: + d1(KPrintF("%s/%ld: MUIM_Export\n", __FUNC__, __LINE__)); + Result = DoSuperMethodA(cl, obj, msg); + break; + case MUIM_Import: + d1(KPrintF("%s/%ld: MUIM_Import\n", __FUNC__, __LINE__)); + Result = DoSuperMethodA(cl, obj, msg); + break; + case MUIM_ContextMenuChoice: + { + struct MUIP_ContextMenuChoice *cmc = (struct MUIP_ContextMenuChoice *) msg; + Object *MenuObj; + struct Hook *MenuHook = NULL; + + d1(KPrintF("%s/%ld: MUIM_ContextMenuChoice item=%08lx\n", __FUNC__, __LINE__, cmc->item)); + + MenuObj = cmc->item; + + d1(KPrintF("%s/%ld: MenuObj=%08lx\n", __FUNC__, __LINE__, MenuObj)); + d1(KPrintF("%s/%ld: msg=%08lx *msg=%08lx\n", __FUNC__, __LINE__, msg, *((ULONG *) msg))); + + get(MenuObj, MUIA_UserData, &MenuHook); + + d1(KPrintF("%s/%ld: MenuHook=%08lx\n", __FUNC__, __LINE__, MenuHook)); + if (MenuHook) + DoMethod(APP_Main, MUIM_CallHook, MenuHook, MenuObj); + + Result = 0; + } + break; + + default: + Result = DoSuperMethodA(cl, obj, msg); + } + + return Result; +} +DISPATCHER_END + +//---------------------------------------------------------------------------- + +DISPATCHER(myFileTypesNListTree) +{ + ULONG Result; + + d1(kprintf(__FILE__ "/%s/%ld: MethodID=%08lx\n", __FUNC__, __LINE__, msg->MethodID)); + + switch(msg->MethodID) + { + case MUIM_Export: + d1(KPrintF("%s/%ld: MUIM_Export\n", __FUNC__, __LINE__)); + Result = DoSuperMethodA(cl, obj, msg); + break; + case MUIM_Import: + d1(KPrintF("%s/%ld: MUIM_Import\n", __FUNC__, __LINE__)); + Result = DoSuperMethodA(cl, obj, msg); + break; + case MUIM_ContextMenuChoice: + { + struct MUIP_ContextMenuChoice *cmc = (struct MUIP_ContextMenuChoice *) msg; + Object *MenuObj; + struct Hook *MenuHook = NULL; + + d1(kprintf("%s/%ld: MUIM_ContextMenuChoice item=%08lx\n", __FUNC__, __LINE__, cmc->item)); + + MenuObj = cmc->item; + + d1(kprintf("%s/%ld: MenuObj=%08lx\n", __FUNC__, __LINE__, MenuObj)); + d1(kprintf("%s/%ld: msg=%08lx *msg=%08lx\n", __FUNC__, __LINE__, msg, *((ULONG *) msg))); + + get(MenuObj, MUIA_UserData, &MenuHook); + + + d1(kprintf("%s/%ld: MenuHook=%08lx\n", __FUNC__, __LINE__, MenuHook)); + if (MenuHook) + DoMethod(APP_Main, MUIM_CallHook, MenuHook, 0); + + Result = 0; + } + break; + + default: + Result = DoSuperMethodA(cl, obj, msg); + } + + return Result; +} +DISPATCHER_END + +//---------------------------------------------------------------------------- + +static void init(void) +{ + if (!OpenLibraries()) + fail(NULL, "Failed to call OpenLibraries"); + + if (LocaleBase) + FindCatalog = OpenCatalogA(NULL, "Scalos/Find.catalog", NULL); + + TranslateNewMenu(NewContextMenuResults); + TranslateNewMenu(NewContextMenuFileTypes); + TranslateNewMenu(NewContextMenuHistoryPopup); + + myFindResultsNListClass = MUI_CreateCustomClass(NULL, MUIC_NList, + NULL, 0, DISPATCHER_REF(myFindResultsNList)); + + myFileTypesNListTreeClass = MUI_CreateCustomClass(NULL, MUIC_NListtree, + NULL, 0, DISPATCHER_REF(myFileTypesNListTree)); + + myPersistentNListClass = MUI_CreateCustomClass(NULL, MUIC_NList, + NULL, 0, DISPATCHER_REF(myPersistentNList)); + + myPopObjectClass = MUI_CreateCustomClass(NULL, MUIC_Popobject, + NULL, 0, DISPATCHER_REF(myPopObject)); +} + +//---------------------------------------------------------------------------- + +static BOOL OpenLibraries(void) +{ + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + if (NULL == IntuitionBase) + fail(NULL, "Failed to open intuition.library."); +#ifdef __amigaos4__ + else + { + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + fail(NULL, "Failed to open intuition interface."); + } +#endif + + MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN-1); + if (NULL == MUIMasterBase) + fail(NULL, "Failed to open muimaster.library."); +#ifdef __amigaos4__ + else + { + IMUIMaster = (struct MUIMasterIFace *)GetInterface((struct Library *)MUIMasterBase, "main", 1, NULL); + if (NULL == IMUIMaster) + fail(NULL, "Failed to open muimaster interface."); + } +#endif + + ScalosBase = (struct ScalosBase *) OpenLibrary("scalos.library", 40); + if (NULL == ScalosBase) + fail(NULL, "Failed to open scalos.library."); +#ifdef __amigaos4__ + else + { + IScalos = (struct ScalosIFace *)GetInterface((struct Library *)ScalosBase, "main", 1, NULL); + if (NULL == IScalos) + fail(NULL, "Failed to open scalos interface."); + } +#endif + + LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 39); +#ifdef __amigaos4__ + if (NULL != LocaleBase) + { + ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL); + if (NULL == ILocale) + fail(NULL, "Failed to open locale interface."); + } +#endif + + TimerPort = CreateMsgPort(); + TimerIO = (T_TIMEREQUEST *)CreateIORequest(TimerPort, sizeof(T_TIMEREQUEST)); + if (NULL == TimerIO) + fail(NULL, "Failed to call CreateIORequest."); + + OpenDevice("timer.device", UNIT_VBLANK, &TimerIO->tr_node, 0); + TimerBase = (T_TIMERBASE) TimerIO->tr_node.io_Device; + if (NULL == TimerBase) + fail(NULL, "Failed to open timer.device."); +#ifdef __amigaos4__ + ITimer = (struct TimerIFace *)GetInterface((struct Library *)TimerBase, "main", 1, NULL); + if (NULL == ITimer) + fail(NULL, "Failed to open timer interface."); +#endif + + return TRUE; +} + +//---------------------------------------------------------------------------- + +static void CloseLibraries(void) +{ + if (TimerIO) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)ITimer); +#endif + CloseDevice(&TimerIO->tr_node); + DeleteIORequest(&TimerIO->tr_node); + + TimerIO = NULL; + TimerBase = NULL; + } + if (TimerPort) + { + DeleteMsgPort(TimerPort); + TimerPort = NULL; + } + if (LocaleBase) + { + if (FindCatalog) + { + CloseCatalog(FindCatalog); + FindCatalog = NULL; + } +#ifdef __amigaos4__ + if (ILocale) + { + DropInterface((struct Interface *)ILocale); + ILocale = NULL; + } +#endif + CloseLibrary((struct Library *) LocaleBase); + LocaleBase = NULL; + } +#ifdef __amigaos4__ + if (IScalos) + { + DropInterface((struct Interface *)IScalos); + IScalos = NULL; + } +#endif + if (ScalosBase) + { + CloseLibrary((struct Library *) ScalosBase); + ScalosBase = NULL; + } +#ifdef __amigaos4__ + if (IMUIMaster) + { + DropInterface((struct Interface *)IMUIMaster); + IMUIMaster = NULL; + } +#endif + if (MUIMasterBase) + { + CloseLibrary(MUIMasterBase); + MUIMasterBase = NULL; + } +#ifdef __amigaos4__ + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } +#endif + if (IntuitionBase) + { + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } +} + +//---------------------------------------------------------------------------- + +static STRPTR GetLocString(ULONG MsgId) +{ + struct Find_LocaleInfo li; + + li.li_Catalog = FindCatalog; +#ifndef __amigaos4__ + li.li_LocaleBase = LocaleBase; +#else + li.li_ILocale = ILocale; +#endif + + return (STRPTR)GetFindString(&li, MsgId); +} + +//---------------------------------------------------------------------------- + +#if 0 +static void TranslateStringArray(STRPTR *stringArray) +{ + while (*stringArray) + { + *stringArray = GetLocString((ULONG) *stringArray); + stringArray++; + } +} +#endif + +//---------------------------------------------------------------------------- + +static void TranslateNewMenu(struct NewMenu *nm) +{ + while (nm && NM_END != nm->nm_Type) + { + if (NM_BARLABEL != nm->nm_Label) + nm->nm_Label = GetLocString((ULONG) nm->nm_Label); + + if (nm->nm_CommKey) + nm->nm_CommKey = GetLocString((ULONG) nm->nm_CommKey); + + nm++; + } +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT OpenAboutMUIFunc(struct Hook *hook, Object *o, Msg msg) +{ + if (NULL == WIN_AboutMUI) + { + WIN_AboutMUI = MUI_NewObject(MUIC_Aboutmui, + MUIA_Window_RefWindow, WIN_Main, + MUIA_Aboutmui_Application, APP_Main, + TAG_DONE); + } + + if (WIN_AboutMUI) + set(WIN_AboutMUI, MUIA_Window_Open, TRUE); + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT OpenAboutFunc(struct Hook *hook, Object *o, Msg msg) +{ + MUI_Request(APP_Main, WIN_Main, 0, NULL, + GetLocString(MSGID_ABOUTREQOK), + GetLocString(MSGID_ABOUTREQFORMAT), + VERSION_MAJOR, VERSION_MINOR, COMPILER_STRING, CURRENTYEAR); +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT IntuiMessageHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct IntuiMessage *imsg = (struct IntuiMessage *) msg; + + if (IDCMP_REFRESHWINDOW == imsg->Class) + DoMethod(APP_Main, MUIM_Application_CheckRefresh); +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT AppMessageHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct AppMessage *AppMsg = *(struct AppMessage **) msg; + ULONG n; + + d1(KPrintF("%s/%s/%ld: AppMsg=%08lx am_NumArgs=%ld\n", __FILE__, __FUNC__,, __LINE__, AppMsg, AppMsg->am_NumArgs)); + + for (n = 0; n < AppMsg->am_NumArgs; n++) + { + struct WBArg *arg = &AppMsg->am_ArgList[n]; + char Path[512]; + + NameFromLock(arg->wa_Lock, Path, sizeof(Path)); + AddPart(Path, arg->wa_Name, sizeof(Path)); + + d1(KPrintF("%s/%s/%ld: wa_Lock=%08lx\n", __FILE__, __FUNC__,, __LINE__, arg->wa_Lock)); + + AddSourcesLine(Path); + } +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT SelectSourceHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + STRPTR SourceEntry = NULL; + + DoMethod(NListSources, MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, + &SourceEntry); + + // Enable "remove" button only if any entry is selected + set(ButtonRemoveSource, MUIA_Disabled, NULL == SourceEntry); +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT RemoveSourceHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + LONG pos; + + get(NListSources, MUIA_NList_Active, &pos); + + d1(KPrintF( "%s/%s/%ld: pos=%ld\n", __FILE__, __FUNC__, __LINE__, pos)); + if (MUIV_NList_Active_Off != pos) + { + DoMethod(NListSources, MUIM_NList_Remove, pos); + + set(NListSources, MUIA_NList_Active, MUIV_NList_Active_Off); + set(ButtonRemoveSource, MUIA_Disabled, TRUE); + } +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT AddSourceHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + STRPTR NewSource = NULL; + + get(StringNewSource, MUIA_String_Contents, &NewSource); + if (NewSource && strlen(NewSource) > 0) + { + AddSourcesLine(NewSource); + setstring(StringNewSource, ""); + } + else + { + DoMethod(PopAslNewSource, MUIM_Popstring_Open); + } +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT ResultsConstructHookFunc(struct Hook *hook, APTR unused, struct NList_ConstructMessage *nlcm) +{ + struct ResultsListEntry *rle = AllocPooled(nlcm->pool, sizeof(struct ResultsListEntry)); + BOOL Success = FALSE; + + (void) unused; + + do { + struct FindResult *newFr = (struct FindResult *) nlcm->entry; + STRPTR Path; + size_t Length = 1024; + + if (NULL == rle) + break; + + rle->rle_CopyString = NULL; + + rle->rle_Name = strdup(newFr->fr_Name); + if (NULL == rle->rle_Name) + break; + + Path = malloc(Length); + if (NULL == Path) + break; + + if (!NameFromLock(newFr->fr_Lock, Path, Length)) + break; + + rle->rle_Path = strdup(Path); + if (NULL == rle->rle_Path) + break; + + Success = TRUE; + } while (0); + + if (!Success) + { + if (rle) + { + if (rle->rle_Name) + free(rle->rle_Name); + if (rle->rle_Path) + free(rle->rle_Path); + if (rle->rle_CopyString) + free(rle->rle_CopyString); + FreePooled(nlcm->pool, rle, sizeof(struct ResultsListEntry)); + rle = NULL; + } + } + + return (APTR) rle; +} + + +static SAVEDS(void) INTERRUPT ResultsDestructHookFunc(struct Hook *hook, APTR unused, struct NList_DestructMessage *nldm) +{ + struct ResultsListEntry *rle = (struct ResultsListEntry *) nldm->entry; + + (void) unused; + + if (rle->rle_Name) + free(rle->rle_Name); + if (rle->rle_Path) + free(rle->rle_Path); + if (rle->rle_CopyString) + free(rle->rle_CopyString); + + FreePooled(nldm->pool, rle, sizeof(struct ResultsListEntry)); +} + + +static SAVEDS(ULONG) INTERRUPT ResultsDisplayHookFunc(struct Hook *hook, APTR unused, struct NList_DisplayMessage *nldm) +{ + (void) unused; + + if (nldm->entry) + { + struct ResultsListEntry *rle = (struct ResultsListEntry *) nldm->entry; + + nldm->strings[0] = rle->rle_Name; + nldm->strings[1] = rle->rle_Path; + } + else + { + // display titles + nldm->strings[0] = GetLocString(MSGID_RESULTLIST_NAME); + nldm->strings[1] = GetLocString(MSGID_RESULTLIST_LOCATION); + } + + return 0; +} + + +static SAVEDS(LONG) INTERRUPT ResultsCompareHookFunc(struct Hook *hook, Object *obj, struct NList_CompareMessage *ncm) +{ + const struct ResultsListEntry *rle1 = (const struct ResultsListEntry *) ncm->entry1; + const struct ResultsListEntry *rle2 = (const struct ResultsListEntry *) ncm->entry2; + LONG col1 = ncm->sort_type & MUIV_NList_TitleMark_ColMask; + LONG col2 = ncm->sort_type2 & MUIV_NList_TitleMark2_ColMask; + LONG Result = 0; + + if (ncm->sort_type != MUIV_NList_SortType_None) + { + // primary sorting + switch (col1) + { + case 0: // sort by name + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = Stricmp(rle2->rle_Name, rle1->rle_Name); + else + Result = Stricmp(rle1->rle_Name, rle2->rle_Name); + break; + case 1: // sort by path + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = Stricmp(rle2->rle_Path, rle1->rle_Path); + else + Result = Stricmp(rle1->rle_Path, rle2->rle_Path); + break; + default: + break; + } + + if (0 == Result && col1 != col2) + { + // Secondary sorting + switch (col2) + { + case 0: // sort by name + if (ncm->sort_type2 & MUIV_NList_TitleMark2_TypeMask) + Result = Stricmp(rle2->rle_Name, rle1->rle_Name); + else + Result = Stricmp(rle1->rle_Name, rle2->rle_Name); + break; + case 1: // sort by path + if (ncm->sort_type2 & MUIV_NList_TitleMark2_TypeMask) + Result = Stricmp(rle2->rle_Path, rle1->rle_Path); + else + Result = Stricmp(rle1->rle_Path, rle2->rle_Path); + break; + default: + break; + } + } + } + + return Result; +} + + +static SAVEDS(LONG) INTERRUPT ResultsCopyEntryToClipHookFunc(struct Hook *hook, Object *obj, struct NList_CopyEntryToClipMessage *ncc) +{ + struct ResultsListEntry *rle = (struct ResultsListEntry *) ncc->entry; + LONG Result = 0; + size_t len; + + len = strlen(rle->rle_Path) + + 1 // room for separator + + strlen(rle->rle_Name) + + 2; // room for "\n" and trailing 0. + + rle->rle_CopyString = realloc(rle->rle_CopyString, len); + if (rle->rle_CopyString) + { + strcpy(rle->rle_CopyString, rle->rle_Name); + strcat(rle->rle_CopyString, "\t"); + strcat(rle->rle_CopyString, rle->rle_Path); + strcat(rle->rle_CopyString, "\n"); + + ncc->str_result = rle->rle_CopyString; + } + + return Result; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(LONG) INTERRUPT StartSearchHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + (void) hook; + (void) o; + (void) msg; + + StartSearch(); + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(LONG) INTERRUPT StopSearchHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + (void) hook; + (void) o; + (void) msg; + + StopSearch = TRUE; + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(VOID) INTERRUPT OpenResultHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + (void) hook; + (void) o; + (void) msg; + + do { + struct ResultsListEntry *rle = NULL; + + DoMethod(NListResults, MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, &rle); + + if (NULL == rle) + break; + + // Open result drawer in Scalos + SCA_OpenDrawerByNameTags(rle->rle_Path, + SCA_ShowAllMode, DDFLAGS_SHOWALL, + TAG_END); + } while (0); +} + + +static SAVEDS(VOID) INTERRUPT CopyResultsToClipHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + (void) hook; + (void) o; + (void) msg; + + DoMethod(NListResults, MUIM_NList_CopyToClip, + MUIV_NList_CopyToClip_All, + 0, // clipboard number to copy to + NULL, + NULL ); +} + + +static SAVEDS(VOID) INTERRUPT OpenResultWithFindHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct WBArg wbArg[2] = { { (BPTR)NULL }, { (BPTR)NULL } }; + BOOL Success = FALSE; + + (void) hook; + (void) o; + (void) msg; + + do { + struct ResultsListEntry *rle = NULL; + + if (NULL == WBenchMsg) + break; + + DoMethod(NListResults, MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, &rle); + + if (NULL == rle) + break; + + wbArg[1].wa_Name = rle->rle_Name; + wbArg[1].wa_Lock = Lock(rle->rle_Path, ACCESS_READ); + if ((BPTR)NULL == wbArg[1].wa_Lock) + break;; + + wbArg[0].wa_Name = WBenchMsg->sm_ArgList[0].wa_Name; + wbArg[0].wa_Lock = DupLock(WBenchMsg->sm_ArgList[0].wa_Lock); + if ((BPTR) NULL == wbArg[0].wa_Lock) + break; + + // SCA_WBStart() + Success = SCA_WBStartTags(wbArg, 2, + SCA_Flags, SCAF_WBStart_Wait, + SCA_WaitTimeout, 0, + TAG_END); + } while (0); + + if (!Success) + { + if (wbArg[0].wa_Lock) + UnLock(wbArg[0].wa_Lock); + if (wbArg[1].wa_Lock) + UnLock(wbArg[1].wa_Lock); + } +} + +//---------------------------------------------------------------------------- + +static SAVEDS(VOID) INTERRUPT OpenResultWithMultiviewHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct WBArg wbArg[2] = { { (BPTR)NULL }, { (BPTR)NULL } }; + BOOL Success = FALSE; + + (void) hook; + (void) o; + (void) msg; + + do { + struct ResultsListEntry *rle = NULL; + + DoMethod(NListResults, MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, &rle); + + if (NULL == rle) + break; + + wbArg[1].wa_Name = rle->rle_Name; + wbArg[1].wa_Lock = Lock(rle->rle_Path, ACCESS_READ); + if ((BPTR)NULL == wbArg[1].wa_Lock) + break;; + + wbArg[0].wa_Name = (STRPTR) "Multiview"; + wbArg[0].wa_Lock = Lock("SYS:Utilities", ACCESS_READ); + if ((BPTR) NULL == wbArg[0].wa_Lock) + break; + + // SCA_WBStart() + Success = SCA_WBStartTags(wbArg, 2, + SCA_Flags, SCAF_WBStart_Wait, + SCA_WaitTimeout, 0, + TAG_END); + } while (0); + + if (!Success) + { + if (wbArg[0].wa_Lock) + UnLock(wbArg[0].wa_Lock); + if (wbArg[1].wa_Lock) + UnLock(wbArg[1].wa_Lock); + } +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT FileTypesConstructHookFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_ConstructMessage *ltcm) +{ + struct FileTypesEntry *fte; + BOOL Success = FALSE; + + d1(kprintf(__FILE__ "/%s/%ld: obj=%08lx ltcm=%08lx memPool=%08lx UserData=%08lx\n", \ + __FUNC__, __LINE__, obj, ltcm, ltcm->MemPool, ltcm->UserData)); + + do { + const struct TypeNode *TnOrig = ltcm->UserData; + + fte = AllocPooled(ltcm->MemPool, sizeof(struct FileTypesEntry)); + d1(KPrintF(__FILE__ "/%s/%ld: fte=%08lx\n", __FUNC__, __LINE__, fte)); + if (NULL == fte) + break; + + NewList(&fte->fte_MagicList); + fte->fte_TypeNode = *TnOrig; + + fte->fte_AllocatedName = fte->fte_TypeNode.tn_Name = strdup(TnOrig->tn_Name); + if (NULL == fte->fte_AllocatedName) + break; + + Success = TRUE; + } while (0); + + if (!Success && fte) + { + if (fte->fte_AllocatedName) + { + free(fte->fte_AllocatedName); + fte->fte_AllocatedName = NULL; + } + FreePooled(ltcm->MemPool, fte, sizeof(struct FileTypesEntry)); + fte = NULL; + } + + return fte; +} + +static SAVEDS(void) INTERRUPT FileTypesDestructHookFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_DestructMessage *ltdm) +{ + struct FileTypesEntry *fte = (struct FileTypesEntry *) ltdm->UserData; + + d1(KPrintF(__FILE__ "/%s/%ld: fte=%08lx\n", __FUNC__, __LINE__, fte)); + + if (fte->fte_AllocatedName) + free(fte->fte_AllocatedName); + + FreePooled(ltdm->MemPool, fte, sizeof(struct FileTypesEntry)); + ltdm->UserData = NULL; +} + +static SAVEDS(ULONG) INTERRUPT FileTypesDisplayHookFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_DisplayMessage *ltdm) +{ + struct FileTypesEntry *fte = (struct FileTypesEntry *) ltdm->TreeNode->tn_User; + + d1(KPrintF(__FILE__ "/%s/%ld: fte=%08lx\n", __FUNC__, __LINE__, fte)); + + if (fte) + { + ltdm->Array[0] = fte->fte_TypeNode.tn_Name; + } + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(LONG) INTERRUPT HideFindHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + LONG isVisible; + + (void) hook; + (void) o; + (void) msg; + + get(GroupFindFiletype, MUIA_ShowMe, &isVisible); + set(GroupFindFiletype, MUIA_ShowMe, !isVisible); + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(LONG) INTERRUPT PatternHistoryHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + LONG *pPos = (LONG *) msg; + + (void) hook; + (void) o; + + if (*pPos >= 0) + { + STRPTR entry; + + DoMethod(NListPatternHistory, MUIM_NList_GetEntry, *pPos, &entry); + d1(KPrintF(__FILE__ "/%s/%ld: *pPos=%ld entry=%08lx\n", __FUNC__, __LINE__, *pPos, entry)); + if (entry) + setstring(StringFilePattern, entry); + + DoMethod(PopObjectPattern, MUIM_Popstring_Close, 1); + } + + return 0; +} +//---------------------------------------------------------------------------- + +static SAVEDS(LONG) INTERRUPT ContentsHistoryHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + LONG *pPos = (LONG *) msg; + + (void) hook; + (void) o; + + if (*pPos >= 0) + { + STRPTR entry; + + DoMethod(NListContentsHistory, MUIM_NList_GetEntry, *pPos, &entry); + d1(KPrintF(__FILE__ "/%s/%ld: *pPos=%ld entry=%08lx\n", __FUNC__, __LINE__, *pPos, entry)); + if (entry) + setstring(StringFileContents, entry); + + DoMethod(PopObjectContents, MUIM_Popstring_Close, 1); + } + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(LONG) INTERRUPT FiletypeSelectHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MUI_NListtree_TreeNode **tn = (struct MUI_NListtree_TreeNode **) msg; + + (void) hook; + (void) o; + + d1(KPrintF(__FILE__ "/%s/%ld: tn=%08lx\n", __FUNC__, __LINE__, *tn)); + d1(KPrintF(__FILE__ "/%s/%ld: tn_Name=<%s>\n", __FUNC__, __LINE__, (*tn)->tn_Name)); + + setstring(StringFileType, (*tn)->tn_Name); + + DoMethod(PopObjectFiletypes, MUIM_Popstring_Close, 1); + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(LONG) INTERRUPT CheckEmptyStringsHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + CONST_STRPTR FilePattern = NULL; + CONST_STRPTR FileContents = NULL; + CONST_STRPTR FileType = NULL; + size_t TotalLength = 0; + + (void) hook; + (void) o; + (void) msg; + + get(StringFilePattern, MUIA_String_Contents, &FilePattern); + get(StringFileContents, MUIA_String_Contents, &FileContents); + get(StringFileType, MUIA_String_Contents, &FileType); + + if (FilePattern) + TotalLength += strlen(FilePattern); + if (FileContents) + TotalLength += strlen(FileContents); + if (FileType) + TotalLength += strlen(FileType); + + set(ButtonSearch, MUIA_Disabled, 0 == TotalLength); + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(LONG) INTERRUPT FindFileTypeHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + CONST_STRPTR FindString = NULL; + + (void) hook; + (void) o; + (void) msg; + + get(StringFindFileType, MUIA_String_Contents, &FindString); + + if (FindString && strlen(FindString) > 0) + { +#if 1 + SearchFileType(FindString, FALSE); +#else + DoMethod(ListtreeFileTypes, MUIM_NListtree_FindName, + MUIV_NListtree_FindName_ListNode_Root, + FindString, MUIV_NListtree_FindName_Flag_Activate); +#endif + } + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(LONG) INTERRUPT FindNextFileTypeHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + CONST_STRPTR FindString = NULL; + + (void) hook; + (void) o; + (void) msg; + + get(StringFindFileType, MUIA_String_Contents, &FindString); + + if (FindString && strlen(FindString) > 0) + { +#if 1 + SearchFileType(FindString, TRUE); +#else + struct MUI_NListtree_TreeNode *tn = NULL; + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(ListtreeFileTypes, + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, + 0); + d1(KPrintF("%s/%ld: active tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) "")); + + if (tn) + { + tn = (struct MUI_NListtree_TreeNode *) DoMethod(ListtreeFileTypes, + MUIM_NListtree_GetEntry, + tn, + MUIV_NListtree_GetEntry_Position_Next, + 0); + d1(KPrintF("%s/%ld: active tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) "")); + } + if (NULL == tn) + tn = (struct MUI_NListtree_TreeNode *) MUIV_NListtree_FindName_ListNode_Root; + + DoMethod(ListtreeFileTypes, + MUIM_NListtree_FindName, + MUIV_NListtree_FindName_ListNode_Active, + FindString, + MUIV_NListtree_FindName_Flag_StartNode | MUIV_NListtree_FindName_Flag_Activate); +#endif + } + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT CollapseFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + (void) hook; + (void) o; + (void) msg; + + DoMethod(ListtreeFileTypes, + MUIM_NListtree_Close, + MUIV_NListtree_Close_ListNode_Active, + MUIV_NListtree_Close_TreeNode_All, + 0); + + return NULL; +} + +static SAVEDS(APTR) INTERRUPT ExpandFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MUI_NListtree_TreeNode *tn; + + (void) hook; + (void) o; + (void) msg; + + set(ListtreeFileTypes, MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(ListtreeFileTypes, + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, + 0); + d1(kprintf("%s/%ld: active tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) "")); + + DoMethod(ListtreeFileTypes, + MUIM_NListtree_Open, + MUIV_NListtree_Open_ListNode_Active, + MUIV_NListtree_Open_TreeNode_Active, + 0); + + if (tn) + { + struct MUI_NListtree_TreeNode *tnChild; + + tnChild = (struct MUI_NListtree_TreeNode *) DoMethod(ListtreeFileTypes, + MUIM_NListtree_GetEntry, + tn, + MUIV_NListtree_GetEntry_Position_Head, + 0); + d1(kprintf("%s/%ld: Head tn=%08lx <%s>\n", __FUNC__, __LINE__, tnChild, tnChild ? tnChild->tn_Name : (STRPTR) "")); + + if (tnChild) + { + set(ListtreeFileTypes, MUIA_NListtree_Active, (ULONG) tnChild); + + DoMethod(ListtreeFileTypes, + MUIM_NListtree_Open, + MUIV_NListtree_Open_ListNode_Active, + MUIV_NListtree_Open_TreeNode_All, + 0); + } + + set(ListtreeFileTypes, MUIA_NListtree_Active, (ULONG) tn); + } + + set(ListtreeFileTypes, MUIA_NList_Quiet, MUIV_NList_Quiet_None); + + return NULL; +} + +static SAVEDS(APTR) INTERRUPT CollapseAllFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + (void) hook; + (void) o; + (void) msg; + + + DoMethod(ListtreeFileTypes, MUIM_NListtree_Close, + MUIV_NListtree_Close_ListNode_Root, + MUIV_NListtree_Close_TreeNode_All, + 0); + + return NULL; +} + +static SAVEDS(APTR) INTERRUPT ExpandAllFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + (void) hook; + (void) o; + (void) msg; + + + DoMethod(ListtreeFileTypes, MUIM_NListtree_Open, + MUIV_NListtree_Open_ListNode_Root, + MUIV_NListtree_Open_TreeNode_All, + 0); + + return NULL; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT SelectFileTypesEntryHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MUI_NListtree_TreeNode **tn = (struct MUI_NListtree_TreeNode **) msg; + + if (*tn) + { + set(MenuExpandFileTypes, MUIA_Menuitem_Enabled, TRUE); + set(MenuCollapseFileTypes, MUIA_Menuitem_Enabled, TRUE); + } + else + { + set(MenuExpandFileTypes, MUIA_Menuitem_Enabled, FALSE); + set(MenuCollapseFileTypes, MUIA_Menuitem_Enabled, FALSE); + } + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(VOID) INTERRUPT FileTypesPopupWindowHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + Object *PopWindow = (Object *) msg; + + set(PopWindow, MUIA_Window_ActiveObject, StringFindFileType); +} + +//---------------------------------------------------------------------------- + +static SAVEDS(VOID) INTERRUPT ClearHistoryHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + DoMethod(o, MUIM_NList_Clear, 0); +} + +//---------------------------------------------------------------------------- + +static void StartSearch(void) +{ + static ULONG Searching = 0; + ULONG Entries, n; + CONST_STRPTR FilePattern = NULL; + CONST_STRPTR FileContents = NULL; + CONST_STRPTR FileType = NULL; + STRPTR PatternBuf = NULL; + STRPTR ContentsBuf = NULL; + STRPTR FiletypeBuf = NULL; + + d1(KPrintF("%s/%s/%ld: START Searching=%lu\n", __FILE__, __FUNC__, __LINE__, Searching)); + + do { + if (++Searching > 1) + break; + + set(ButtonSearch, MUIA_Disabled, TRUE); + set(ButtonStop, MUIA_Disabled, FALSE); + set(StringFilePattern, MUIA_Disabled, TRUE); + set(StringFileContents, MUIA_Disabled, TRUE); + set(StringFileType, MUIA_Disabled, TRUE); + + // Clear search results + DoMethod(NListResults, MUIM_NList_Clear); + + get(StringFilePattern, MUIA_String_Contents, &FilePattern); + get(StringFileContents, MUIA_String_Contents, &FileContents); + get(StringFileType, MUIA_String_Contents, &FileType); + + if (FilePattern && strlen(FilePattern) > 0) + { + // Need to match file name + size_t len = 2 * strlen(FilePattern) + 10; + + PushEntry(NListPatternHistory, FilePattern, MUIV_NList_Insert_Top); + + PatternBuf = malloc(len); + if (NULL == PatternBuf) + break; + + if (ParsePatternNoCase(FilePattern, PatternBuf, len) < 0) + break; + } + if (FileContents && strlen(FileContents) > 0) + { + // Need to match contents + PushEntry(NListContentsHistory, FileContents, MUIV_NList_Insert_Top); + + ContentsBuf = strdup(FileContents); + if (NULL == ContentsBuf) + break; + + strlwr(ContentsBuf); + } + if (FileType && strlen(FileType) > 0) + { + FiletypeBuf = strdup(FileType); + if (NULL == FiletypeBuf) + break; + } + + get(NListSources, MUIA_NList_Entries, &Entries); + + for (n = 0; !StopSearch && n < Entries; n++) + { + STRPTR SearchPath; + + DoMethod(NListSources, MUIM_NList_GetEntry, + n, &SearchPath); + + DoSearchPath(SearchPath, PatternBuf, ContentsBuf, FiletypeBuf); + + DoMethod(APP_Main, MUIM_Application_InputBuffered); + } + } while (0); + + if (PatternBuf) + free(PatternBuf); + if (ContentsBuf) + free(ContentsBuf); + if (FiletypeBuf) + free(FiletypeBuf); + + if (0 == --Searching) + { + setstring(StringFilePattern, SEARCH_PATTERN_DEFAULT); + setstring(StringFileContents, SEARCH_CONTENTS_DEFAULT); + setstring(StringFileType, SEARCH_FILETYPE_DEFAULT); + + set(TextCurrentFile, MUIA_Text_Contents, + GetLocString(StopSearch ? MSGID_SEARCH_ABORTED : MSGID_SEARCH_FINISHED)); + set(ButtonStop, MUIA_Disabled, TRUE); + set(StringFilePattern, MUIA_Disabled, FALSE); + set(StringFileContents, MUIA_Disabled, FALSE); + set(StringFileType, MUIA_Disabled, FALSE); + + StopSearch = FALSE; + } + + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); +} + +//---------------------------------------------------------------------------- + +static void DoSearchPath(CONST_STRPTR Path, CONST_STRPTR Pattern, + CONST_STRPTR Contents, CONST_STRPTR Filetype) +{ + BPTR DirLock; + size_t PathLength = strlen(CurrentPath); + + d1(KPrintF("%s/%s/%ld: START Path=<%s>\n", __FILE__, __FUNC__, __LINE__, Path)); + + if (Pattern) + { + // Match file name pattern + if (NULL == Contents && NULL == Filetype + && MatchPatternNoCase(Pattern, (STRPTR) Path)) + { + struct FindResult fr; + + d1(KPrintF("%s/%s/%ld: Path=<%s>\n", __FILE__, __FUNC__, __LINE__, Path)); + + fr.fr_Lock = CurrentDir((BPTR)NULL); + CurrentDir(fr.fr_Lock); + fr.fr_Name = (STRPTR) Path; + + DoMethod(NListResults, MUIM_NList_InsertSingle, + &fr, MUIV_NList_Insert_Sorted); + } + } + + d1(KPrintF("%s/%s/%ld: PathLength=%lu CurrentPath=<%s> Path=<%s>\n", \ + __FILE__, __FUNC__, __LINE__, PathLength, CurrentPath, Path)); + + if (PathLength) + AddPart(CurrentPath, Path, sizeof(CurrentPath)); + else + strcpy(CurrentPath, Path); + + d1(KPrintF("%s/%s/%ld: CurrentPath=<%s>\n", __FILE__, __FUNC__, __LINE__, CurrentPath)); + + DirLock = Lock(Path, ACCESS_READ); + if (DirLock) + { + DoSearchDir(DirLock, Pattern, Contents, Filetype); + + UnLock(DirLock); + } + + CurrentPath[PathLength] = '\0'; + + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); +} + +//---------------------------------------------------------------------------- + +static void DoSearchDir(BPTR DirLock, CONST_STRPTR Pattern, + CONST_STRPTR Contents, CONST_STRPTR Filetype) +{ + BPTR OldCurrentDir = CurrentDir(DirLock); +#if USE_EXALL + const size_t eadSize = 32768; + struct ExAllControl *eac = NULL; + struct ExAllData *EAData; + BOOL More = FALSE; +#else /* USE_EXALL */ + struct FileInfoBlock *fib = NULL; +#endif /* USE_EXALL */ + + d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__)); + + do { +#if USE_EXALL + EAData = malloc(eadSize); + if (NULL == EAData) + break; + + eac = AllocDosObject(DOS_EXALLCONTROL, NULL); + if (NULL == eac) + break; + + eac->eac_MatchString = NULL; + eac->eac_MatchFunc = NULL; + eac->eac_LastKey = 0; + More = TRUE; + + while (!StopSearch && More) + { + struct ExAllData *ead; + + DoMethod(APP_Main, MUIM_Application_InputBuffered); + + More = ExAll(DirLock, EAData, eadSize, ED_TYPE, eac); + if (!More && (IoErr() != ERROR_NO_MORE_ENTRIES)) + break; + + if (0 == eac->eac_Entries) + continue; + + for (ead = EAData; ead; ead = ead->ed_Next) + { + if (GetElapsedTime(&LastUpdate) > 100) + { + // Update at most every 100ms + char FullName[512]; + + strcpy(FullName, CurrentPath); + AddPart(FullName, ead->ed_Name, sizeof(FullName)); + set(TextCurrentFile, MUIA_Text_Contents, FullName); + + GetSysTime(&LastUpdate); + } + + SearchEntry(DirLock, ead->ed_Name, ead->ed_Type, Pattern, Contents, Filetype); + + DoMethod(APP_Main, MUIM_Application_InputBuffered); + } + } +#else /* USE_EXALL */ + fib = AllocDosObject(DOS_FIB, NULL); + if (NULL == fib) + break; + + if (!Examine(DirLock, fib)) + break; + + d1(KPrintF("%s/%s/%ld: fib_fileName=<%s>\n", __FILE__, __FUNC__, __LINE__, fib->fib_FileName)); + + while (!StopSearch) + { + if (GetElapsedTime(&LastUpdate) > 100) + { + // Update at most every 100ms + char FullName[512]; + + strcpy(FullName, Path); + AddPart(FullName, fib->fib_FileName, sizeof(FullName)); + set(TextCurrentFile, MUIA_Text_Contents, FullName); + + GetSysTime(&LastUpdate); + } + + if (!ExNext(DirLock, fib)) + break; + + SearchEntry(DirLock, fib->fib_FileName, fib->fib_DirEntryType, Pattern, Contents, Filetype); + + d1(KPrintF("%s/%s/%ld: fib_fileName=<%s>\n", __FILE__, __FUNC__, __LINE__, fib->fib_FileName)); + + DoMethod(APP_Main, MUIM_Application_InputBuffered); + } +#endif /* USE_EXALL */ + } while (0); + +#if USE_EXALL + if (eac) + { + if (More) + ExAllEnd(DirLock, EAData, eadSize, ED_TYPE, eac); + + FreeDosObject(DOS_EXALLCONTROL, eac); + } + if (EAData) + free(EAData); +#else /* USE_EXALL */ + if (fib) + FreeDosObject(DOS_FIB, fib); +#endif /* USE_EXALL */ + + CurrentDir(OldCurrentDir); + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); +} + +//---------------------------------------------------------------------------- + +static void SearchEntry(BPTR DirLock, CONST_STRPTR Name, LONG DirEntryType, + CONST_STRPTR Pattern, CONST_STRPTR Contents, CONST_STRPTR Filetype) +{ + d1(KPrintF("%s/%s/%ld: Name=<%s> DirEntryType=%ld\n", __FILE__, __FUNC__, __LINE__, Name, DirEntryType)); + debugLock_d1(DirLock); + + switch (DirEntryType) + { + case ST_ROOT: + case ST_USERDIR: + case ST_LINKDIR: + DoSearchPath(Name, Pattern, Contents, Filetype); + break; + + case ST_SOFTLINK: + case ST_FILE: + case ST_LINKFILE: + case ST_PIPEFILE: + SearchFile(Name, Pattern, Contents, Filetype); + break; + + default: + if (DirEntryType > 0) + DoSearchPath(Name, Pattern, Contents, Filetype); + else if (DirEntryType < 0) + SearchFile(Name, Pattern, Contents, Filetype); + break; + } +} + +//---------------------------------------------------------------------------- + +static void SearchFile(CONST_STRPTR FileName, CONST_STRPTR Pattern, + CONST_STRPTR Contents, CONST_STRPTR Filetype) +{ + do { + struct FindResult fr; + + if (Pattern) + { + // Match file name pattern + if (!MatchPatternNoCase(Pattern, (STRPTR) FileName)) + break; + } + if (Contents) + { + // Match file contents + BPTR fh; + BOOL Match; + + fh = Open(FileName, MODE_OLDFILE); + d1(KPrintF("%s/%s/%ld: FileName=<%s> fh=%08lx\n", __FILE__, __FUNC__, __LINE__, FileName, fh)); + if (0 == fh) + break; + + Match = MatchFileContents(fh, Contents); + + Close(fh); + + if (!Match) + break; + } + if (Filetype) + { + const struct TypeNode *tn; + BPTR dirLock; + + dirLock = CurrentDir((BPTR)NULL); + CurrentDir(dirLock); + + tn = DefIconsIdentify(dirLock, FileName); + if (tn && IS_TYPENODE(tn)) + { + d1(KPrintF("%s/%s/%ld: identify: tn_Name=<%s> Name=<%s>\n", __FILE__, __FUNC__, __LINE__, tn->tn_Name, FileName)); + if (!SearchTypeNodeTree(tn, Filetype)) + break; + } + else + { + break; + } + } + + fr.fr_Lock = CurrentDir((BPTR)NULL); + CurrentDir(fr.fr_Lock); + fr.fr_Name = (STRPTR) FileName; + + DoMethod(NListResults, MUIM_NList_InsertSingle, + &fr, MUIV_NList_Insert_Sorted); + } while (0); +} + +//---------------------------------------------------------------------------- + +static BOOL SearchTypeNodeTree(const struct TypeNode *tn, CONST_STRPTR Name) +{ + if (0 == Stricmp(tn->tn_Name, Name)) + { + d1(KPrintF("%s/%s/%ld: match: tn_Name=<%s> Name=<%s>\n", __FILE__, __FUNC__, __LINE__, tn->tn_Name, Name)); + return TRUE; + } + + for (tn = tn->tn_Parent; tn; tn = tn->tn_Parent) + { + if (0 == Stricmp(tn->tn_Name, Name)) + { + d1(KPrintF("%s/%s/%ld: match: tn_Name=<%s> Name=<%s>\n", __FILE__, __FUNC__, __LINE__, tn->tn_Name, Name)); + return TRUE; + } + } + + return FALSE; // not found +} + +//---------------------------------------------------------------------------- + +/* + * QuickSearch algoritm (Modified Bayer-Moore). + * http://www-igm.univ-mlv.fr/~lecroq/string/index.html + */ + +#define ASIZE 256 /* alphabet size */ + +static void preQsBc(const UBYTE *x, LONG m, LONG qsBc[]) +{ + LONG i; + + for (i = 0; i < ASIZE; ++i) + qsBc[i] = m + 1; + for (i = 0; i < m; ++i) + qsBc[x[i]] = m - i; +} + + +static LONG QuickSearch(const UBYTE *x, LONG m, UBYTE *y, LONG n) +{ + LONG j, qsBc[ASIZE]; + + // Initialize qsBc[] + preQsBc(x, m, qsBc); + + /* Searching */ + j = 0; + while (j <= n - m) + { + if (memcmp(x, y + j, m) == 0) + return j; + j += qsBc[y[j + m]]; /* shift */ + } + + return -1; +} + + +static BOOL MatchFileContents(BPTR fh, CONST_STRPTR Contents) +{ + UBYTE *ReadBuffer; + BOOL Match = FALSE; + + do { + size_t ContentsLen = strlen(Contents); + LONG offset = 0; + + ReadBuffer = malloc(1 + BUFFERSIZE); + if (NULL == ReadBuffer) + break; + + while (!StopSearch) + { + LONG BytesRead; + ULONG n; + + BytesRead = FRead(fh, ReadBuffer + offset, 1, BUFFERSIZE - offset); + if (0 == BytesRead) + break; + + ReadBuffer[BytesRead + offset] = 0; + + for(n = 0; n < BytesRead + offset; n++) + { + ReadBuffer[n] = ToLower(ReadBuffer[n]); + } + + if (-1 != QuickSearch((const UBYTE *)Contents, ContentsLen, ReadBuffer, BytesRead + offset)) + { + d1(KPrintF("%s/%s/%ld: Contents=<%s> ContentsLen=%lu\n", __FILE__, __FUNC__, __LINE__, Contents, ContentsLen)); + Match = TRUE; + break; + } + + // Copy end of buffer to the begining. + if (BytesRead == BUFFERSIZE - offset) + { + memcpy(ReadBuffer, ReadBuffer + BUFFERSIZE - 1 - ContentsLen, ContentsLen); + offset = ContentsLen; + } + else + { + break; + } + + DoMethod(APP_Main, MUIM_Application_InputBuffered); + } + } while (0); + + if (ReadBuffer) + free(ReadBuffer); + + return Match; +} + +//---------------------------------------------------------------------------- + +static void FillSourcesList(struct WBStartup *WBenchMsg) +{ + if (WBenchMsg && WBenchMsg->sm_ArgList) + { + ULONG n; + + for (n = 1; n < WBenchMsg->sm_NumArgs; n++) + { + struct WBArg *arg = &WBenchMsg->sm_ArgList[n]; + char Path[512]; + + NameFromLock(arg->wa_Lock, Path, sizeof(Path)); + AddPart(Path, arg->wa_Name, sizeof(Path)); + + d1(KPrintF("%s/%s/%ld: wa_Lock=%08lx\n", __FILE__, __FUNC__,, __LINE__, arg->wa_Lock)); + + AddSourcesLine(Path); + } + } +} + +//---------------------------------------------------------------------------- + +static Object *MyPopButton(ULONG img) +{ + Object *obj; + + obj = MUI_MakeObject(MUIO_PopButton, img); + + if (obj) + { + set(obj, MUIA_CycleChain, TRUE); + } + + return obj; +} + +//---------------------------------------------------------------------------- + +// Checks if a certain version of a MCC is available +BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev) +{ + BOOL flush = TRUE; + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: %s ", __LINE__, name);) + + while (1) + { + ULONG ver; + ULONG rev; + struct Library *base; + char libname[256]; + + // First we attempt to acquire the version and revision through MUI + Object *obj = MUI_NewObject((STRPTR) name, TAG_DONE); + if (obj) + { + get(obj, MUIA_Version, &ver); + get(obj, MUIA_Revision, &rev); + + MUI_DisposeObject(obj); + + if(ver > minver || (ver == minver && rev >= minrev)) + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: v%ld.%ld found through MUIA_Version/Revision\n", __LINE__, ver, rev);) + return TRUE; + } + } + + // If we did't get the version we wanted, let's try to open the + // libraries ourselves and see what happens... + stccpy(libname, "PROGDIR:mui", sizeof(libname)); + AddPart(libname, name, sizeof(libname)); + + if ((base = OpenLibrary(&libname[8], 0)) || (base = OpenLibrary(&libname[0], 0))) + { + UWORD OpenCnt = base->lib_OpenCnt; + + ver = base->lib_Version; + rev = base->lib_Revision; + + CloseLibrary(base); + + // we add some additional check here so that eventual broken .mcc also have + // a chance to pass this test (i.e. Toolbar.mcc is broken) + if (ver > minver || (ver == minver && rev >= minrev)) + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: v%ld.%ld found through OpenLibrary()\n", __LINE__, ver, rev);) + return TRUE; + } + + if (OpenCnt > 1) + { + if (MUI_Request(NULL, NULL, 0L, + (STRPTR) GetLocString(MSGID_STARTUP_FAILURE), + (STRPTR) GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), + (STRPTR) GetLocString(MSGID_STARTUP_MCC_IN_USE), + name, minver, minrev, ver, rev)) + { + flush = TRUE; + } + else + break; + } + + // Attempt to flush the library if open count is 0 or because the + // user wants to retry (meaning there's a chance that it's 0 now) + + if (flush) + { + struct Library *result; + extern struct ExecBase *SysBase; + + Forbid(); + if ((result = (struct Library *) FindName(&SysBase->LibList, name))) + RemLibrary(result); + Permit(); + flush = FALSE; + } + else + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: couldn`t find minimum required version.\n", __LINE__);) + + // We're out of luck - open count is 0, we've tried to flush + // and still haven't got the version we want + if (MUI_Request(NULL, NULL, 0L, + (STRPTR) GetLocString(MSGID_STARTUP_FAILURE), + (STRPTR) GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), + (STRPTR) GetLocString(MSGID_STARTUP_OLD_MCC), + name, minver, minrev, ver, rev)) + { + flush = TRUE; + } + else + break; + } + } + else + { + // No MCC at all - no need to attempt flush + flush = FALSE; + if (!MUI_Request(NULL, NULL, 0L, + (STRPTR) GetLocString(MSGID_STARTUP_FAILURE), + (STRPTR) GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), + (STRPTR) GetLocString(MSGID_STARTUP_MCC_NOT_FOUND), + name, minver, minrev)) + { + break; + } + } + } + + return FALSE; +} + +//---------------------------------------------------------------------------- + +// Get elapsed time since time in milliseconds. +static LONG GetElapsedTime(T_TIMEVAL *tv) +{ + T_TIMEVAL Now; + LONG Diff; + + GetSysTime(&Now); + SubTime(&Now, tv); + + Diff = 1000 * Now.tv_secs + Now.tv_micro / 1000; + + d1(kprintf("%s/%s/%ld: Now s=%ld ms=%ld Start s=%ld ms=%ld Diff=%ld\n", \ + __LINE__, Now.tv_secs, Now.tv_micro, \ + tv->tv_secs, tv->tv_micro, Diff)); + + return Diff; +} + +//---------------------------------------------------------------------------- + +static BOOL SearchFileType(CONST_STRPTR SearchString, BOOL SearchNext) +{ + BOOL Found = FALSE; + STRPTR SearchPattern = NULL; + STRPTR PatternBuffer = NULL; + + do { + struct MUI_NListtree_TreeNode *tn = NULL; + size_t SearchPatternLength; + size_t PatternBufLength; + ULONG dosearch; + + if (SearchString == NULL || strlen(SearchString) < 1) + break; + + /* + * Search for pattern in mimetype name and description. + */ + SearchPatternLength = strlen(SearchString) + 2 + 2 + 1; + + SearchPattern = malloc(SearchPatternLength); + if (NULL == SearchPattern) + break; + + snprintf(SearchPattern, SearchPatternLength, "#?%s#?", SearchString); + + PatternBufLength = 2 * strlen(SearchPattern) + 2; + + PatternBuffer = malloc(PatternBufLength); + if (NULL == PatternBuffer) + break; + + if (ParsePatternNoCase(SearchPattern, PatternBuffer, PatternBufLength) < 0) + break; + + /* + * When searching for next one, fetch selected one first. + */ + + if (SearchNext) + { + tn = (struct MUI_NListtree_TreeNode *) DoMethod(ListtreeFileTypes, + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, + 0); + } + + dosearch = NULL == tn; + + tn = FindPatternInListtree(ListtreeFileTypes, + MUIV_NListtree_GetEntry_ListNode_Root, PatternBuffer, tn, &dosearch); + + if (NULL == tn) + break; + + Found = TRUE; + /* + * Open node if needed and select. + */ + DoMethod(ListtreeFileTypes, + MUIM_NListtree_Open, + MUIV_NListtree_Open_ListNode_Parent, + tn, + 0); + set(ListtreeFileTypes, MUIA_NListtree_Active, tn); + + } while (0); + + if (SearchPattern) + free(SearchPattern); + if (PatternBuffer) + free(PatternBuffer); + + return Found; +} + +//---------------------------------------------------------------------------- + +static struct MUI_NListtree_TreeNode *FindPatternInListtree(Object *ListTree, + struct MUI_NListtree_TreeNode *list, CONST_STRPTR pattern, + struct MUI_NListtree_TreeNode *startnode, ULONG *dosearch) +{ + struct MUI_NListtree_TreeNode *tn; + ULONG pos; + + for (pos = 0; ; pos++) + { + tn = (struct MUI_NListtree_TreeNode *) DoMethod(ListTree, + MUIM_NListtree_GetEntry, + list, + pos, + MUIV_NListtree_GetEntry_Flag_SameLevel); + + if (NULL == tn) + break; + + if (tn->tn_Flags & TNF_LIST) + { + struct MUI_NListtree_TreeNode *tnChild; + + tnChild = FindPatternInListtree(ListTree, tn, pattern, startnode, dosearch); + + if (tnChild) + return tnChild; + + if (*dosearch) + { + if (MatchPatternNoCase(pattern, tn->tn_Name)) + return tn; + } + } + + if ( tn == startnode ) + *dosearch = TRUE; + } + + return NULL; +} + +//---------------------------------------------------------------------------- + +static void AddSourcesLine(CONST_STRPTR NewSourcePath) +{ + PushEntry(NListSources, NewSourcePath, MUIV_NList_Insert_Bottom); +} + +//---------------------------------------------------------------------------- + +static void PushEntry(Object *NList, CONST_STRPTR Contents, LONG Position) +{ + ULONG entries = 0; + ULONG n; + + get(NList, MUIA_NList_Entries, &entries); + + for (n = 0; n < entries; n++) + { + STRPTR entry = NULL; + + DoMethod(NList, MUIM_NList_GetEntry, + n, + &entry); + if (entry && 0 == Stricmp(entry, Contents)) + { + DoMethod(NList, + MUIM_NList_Remove, + n); + get(NList, MUIA_NList_Entries, &entries); + n--; + } + } + + DoMethod(NList, MUIM_NList_InsertSingle, + Contents, + MUIV_NList_Insert_Top); +} + +//---------------------------------------------------------------------------- + +static void ExportNList(Class *cl, Object *obj, struct MUIP_Export *msg) +{ + ULONG id = muiNotifyData(obj)->mnd_ObjectID; + + d1(KPrintF("%s/%ld: START id=%08lx\n", __FUNC__, __LINE__, id)); + if (0 != id) + { + size_t TotalLength = 0; + ULONG entries = 0; + ULONG n; + + get(obj, MUIA_NList_Entries, &entries); + + if (entries > MAX_SAVED_NLIST_ENTRIES) + entries = MAX_SAVED_NLIST_ENTRIES; + + for (n = 0; n < entries; n++) + { + STRPTR entry = NULL; + + DoMethod(obj, MUIM_NList_GetEntry, + n, + &entry); + + if (entry) + TotalLength += 1 + strlen(entry); + } + + if (TotalLength) + { + struct MyNListExport *nle; + + TotalLength += sizeof(struct MyNListExport); + + nle = malloc(TotalLength); + + if (nle) + { + STRPTR bp = nle->nle_Data; + + nle->nle_Size = TotalLength; + d1(KPrintF("%s/%ld: entries=%lu nle_Size=%lu\n", __FUNC__, __LINE__, entries, nle->nle_Size)); + + for (n = 0; n < entries; n++) + { + STRPTR entry = NULL; + + DoMethod(obj, MUIM_NList_GetEntry, + n, + &entry); + + if (entry) + { + d1(KPrintF("%s/%ld: entry=<%s>\n", __FUNC__, __LINE__, entry)); + strcpy(bp, entry); + bp += 1 + strlen(bp); + } + } + + DoMethod(msg->dataspace, + MUIM_Dataspace_Add, + nle, + TotalLength, + id); + + free(nle); + } + } + else + { + DoMethod(msg->dataspace, MUIM_Dataspace_Remove, id); + } + } +} + +//---------------------------------------------------------------------------- + +static void ImportNList(Class *cl, Object *obj, struct MUIP_Import *msg) +{ + ULONG id = muiNotifyData(obj)->mnd_ObjectID; + + d1(KPrintF("%s/%ld: START id=%08lx\n", __FUNC__, __LINE__, id)); + if (0 != id) + { + struct MyNListExport *nle; + + nle = (struct MyNListExport *) DoMethod(msg->dataspace, MUIM_Dataspace_Find, id); + + d1(KPrintF("%s/%ld: nle=%08lx\n", __FUNC__, __LINE__, nle)); + + if (nle) + { + d1(KPrintF("%s/%ld: nle_Size=%lu\n", __FUNC__, __LINE__, nle->nle_Size)); + + if (nle->nle_Size >= sizeof(struct MyNListExport)) + { + size_t TotalSize = nle->nle_Size - sizeof(struct MyNListExport); + STRPTR entry = nle->nle_Data; + + while (TotalSize) + { + size_t len = 1 + strlen(entry); + + d1(KPrintF("%s/%ld: TotalSize=%lu entry=<%s>\n", __FUNC__, __LINE__, TotalSize, entry)); + + DoMethod(obj, MUIM_NList_InsertSingle, + entry, + MUIV_NList_Insert_Bottom); + + entry += len; + if (TotalSize > len) + TotalSize -= len; + else + TotalSize = 0; + } + } + } + } +} + +//---------------------------------------------------------------------------- + + diff --git a/scalos/Modules/Find.MUI/Find.cd b/scalos/Modules/Find.MUI/Find.cd new file mode 100755 index 000000000..81ff8412e --- /dev/null +++ b/scalos/Modules/Find.MUI/Find.cd @@ -0,0 +1,247 @@ +; Find.cd +; $Date$ +; $Revision$ +; version $VER: Find.catalog 40.1 (23. Aug 2008 18:50:08) +; codeset 0s +; language english +; +;#arrayopts static __far +; +; +MSGID_TITLENAME (//) +Scalos Find +; +; +MSGID_SEARCH_FINISHED (//) +Finished. +; +; +MSGID_SEARCH_ABORTED (//) +Aborted. +; +;----------------------------------------------------------- +; +MSGID_MENU_PROJECT (1000//) +Project +; +; +MSGID_MENU_PROJECT_ABOUT (//) +About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI (//) +About MUI... +; +; +MSGID_MENU_PROJECT_QUIT (//) +Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT (//) +Q +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK (2000//) +_OK +; +; +MSGID_ABOUTREQFORMAT (//) +\33c\033bScalos Find.module V%ld.%ld\033n\n\ +%s\n\ +© 2008%s The Scalos Team +; +;----------------------------------------------------------- +; +MSGID_POPSTRING_NAME (3000//) +Name: +; +; +MSGID_POPSTRING_NAME_SHORTHELP (//) +Pattern for file names to look for.\n\ +You can use all DOS wildcards like \"#?\" +; +; +MSGID_POPSTRING_TEXT (//) +Text: +; +; +MSGID_POPSTRING_TEXT_SHORTHELP (//) +String that is search inside all files\n\ +matching the file name pattern.\n\ +No wildcards are allowed here. +; +; +MSGID_POPSTRING_TYPE (//) +Type: +; +; +MSGID_POPSTRING_TYPE_SHORTHELP (//) +Name of Filetype all found entries must have. +; +; +MSGID_SHORTHELP_LISTVIEW_FILETYPES (//) +Select any filetype from this list by double-licking it. +; +; +MSGID_GROUP_SOURCES (//) +Sources +; +; +MSGID_GROUP_SOURCES_ASLTITLE (//) +Enter find source path: +; +; +MSGID_GROUP_RESULTS (//) +Results +; +; +MSGID_BUTTON_ADD (//) +Add \033I[6:20] +; +; +MSGID_BUTTON_ADD_KEY (/1/1) +A +; +; +MSGID_BUTTON_ADD_SHORTHELP (//) +Add another path to search for desired file(s). +; +; +MSGID_BUTTON_REMOVE (//) +Remove +; +; +MSGID_BUTTON_REMOVE_KEY (/1/1) +R +; +; +MSGID_BUTTON_REMOVE_SHORTHELP (//) +Remove selected entry from the list of\n\ +paths to search for desired file(s). +; +; +MSGID_BUTTON_SEARCH (//) +Search +; +; +MSGID_BUTTON_SEARCH_KEY (/1/1) +S +; +; +MSGID_BUTTON_SEARCH_SHORTHELP (//) +Start searching for desired file(s). +; +; +MSGID_BUTTON_STOP (//) +Stop +; +; +MSGID_BUTTON_STOP_KEY (//) +p +; +; +MSGID_BUTTON_STOP_SHORTHELP (//) +Immediately stop search in progress. +; +; +MSGID_RESULTLIST_NAME (//) +Name +; +; +MSGID_RESULTLIST_LOCATION (//) +Location +; +; +MSGID_BUTTON_FIND_NEXT (//) +Next +; +; +MSGID_BUTTON_FIND_NEXT_KEY (/1/1) +N +; +; +MSGID_BUTTON_FIND_NEXT_SHORTHELP (//) +Find next filetype that matches the given search string. +; +; +MSGID_BUTTON_FIND_HIDE_SHORTHELP (//) +Hide Find Filetype Dialog. +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE (6000//) +Find Module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD (//) +Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_MENU_RESULTS_TITLE (7000//) +Find Results +; +; +MSGID_MENU_RESULTS_OPEN (//) +Open with MultiView... +; +; +MSGID_MENU_RESULTS_OPENDRAWER (//) +Open Drawer... +; +; +MSGID_MENU_RESULTS_FIND (//) +Find in Result... +; +; +MSGID_MENU_RESULTS_COPYTOCLIP (//) +Copy to Clipboard +; +;----------------------------------------------------------- +; +MSGID_MENU_FILETYPES_TITLE (7100//) +File Types +; +; +MSGID_MENU_EDIT_COLLAPSE (//) +Collapse Selected +; +; +MSGID_MENU_EDIT_EXPAND (//) +Expand Selected +; +; +MSGID_MENU_EDIT_COLLAPSEALL (//) +Collapse All +; +; +MSGID_MENU_EDIT_EXPANDALL (//) +Expand All +; +; +MSGID_MENU_CLEARHISTORY (//) +Clear History +; +;----------------------------------------------------------- +; diff --git a/scalos/Modules/Find.MUI/Find.h b/scalos/Modules/Find.MUI/Find.h new file mode 100644 index 000000000..c157fbd7b --- /dev/null +++ b/scalos/Modules/Find.MUI/Find.h @@ -0,0 +1,65 @@ +// Find.h +// $Date$ +// $Revision$ + +#ifndef FIND_MODULE_H +#define FIND_MODULE_H + +//---------------------------------------------------------------------------- + +#define VERSION_MAJOR 40 +#define VERSION_MINOR 3 + +#define VERS_MAJOR STR(VERSION_MAJOR) +#define VERS_MINOR STR(VERSION_MINOR) + +//---------------------------------------------------------------------------- + +#define OBJID_NLIST_NAME 4913001 +#define OBJID_NLIST_TEXT 4913002 + +struct FileTypesEntry + { + STRPTR fte_AllocatedName; // allocated space for tn_Name + struct TypeNode fte_TypeNode; + + struct List fte_MagicList; // List of FileTypesActionListEntry + }; + +struct FileTypesPrefsInst +{ + BPTR fpb_DefIconsSegList; + struct TypeNode *fpb_RootType; + BOOL fpb_DefIconsInit; +}; + +//---------------------------------------------------------------------------- + +extern Object *ListtreeFileTypes; + +//---------------------------------------------------------------------------- + +// Functions in DefIcons.c +LONG InitDefIcons(void); +void CleanupDefIcons(void); +struct TypeNode *DefIconsIdentify(BPTR dirLock, CONST_STRPTR Name); + +//---------------------------------------------------------------------------- + +#if defined(__SASC) +int snprintf(char *, size_t, const char *, /*args*/ ...); +int vsnprintf(char *, size_t, const char *, va_list ap); +#endif /* __SASC */ + +//---------------------------------------------------------------------------- + +struct Find_LocaleInfo +{ + APTR li_LocaleBase; + APTR li_Catalog; + struct LocaleIFace *li_ILocale; +}; + +//---------------------------------------------------------------------------- + +#endif /* FIND_MODULE_H */ diff --git a/scalos/Modules/Find.MUI/config.mk b/scalos/Modules/Find.MUI/config.mk new file mode 100755 index 000000000..fad67ecbc --- /dev/null +++ b/scalos/Modules/Find.MUI/config.mk @@ -0,0 +1,61 @@ +# $Date: 2011-07-16 16:53:37 +0200 (Sa, 16. Jul 2011) $ +# $Revision: 782 $ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +SCALOS_LOCALE = $(OBJDIR)/Find_Locale.h + +CFLAGS += -D SCALOSLOCALE=$(SCALOS_LOCALE) + +ICONOBJMCC_DIR = $(TOPLEVEL)/common/IconobjectMCC + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +INCLUDES += -I$(ICONOBJMCC_DIR) \ + +LFLAGS += # + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +INCLUDES += -I$(ICONOBJMCC_DIR) \ + +LFLAGS += -lauto + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +INCLUDES += -I$(ICONOBJMCC_DIR) \ + +LFLAGS += -lmui -lutility + + +else + + +############################################################################### +# AmigaOS + +LFLAGS += # + +endif +endif +endif diff --git a/scalos/Modules/Find.MUI/debug.h b/scalos/Modules/Find.MUI/debug.h new file mode 100644 index 000000000..b5839f9cd --- /dev/null +++ b/scalos/Modules/Find.MUI/debug.h @@ -0,0 +1,28 @@ +// debug.h +// $Date$ +// $Revision$ + +#ifndef DEBUG_H +#define DEBUG_H + +//---------------------------------------------------------------------------- + +#define d1(x) ; +#define d2(x) x; + +#define debugLock_d1(LockName) ; +#define debugLock_d2(LockName) \ + {\ + char xxName[200];\ + strcpy(xxName, "");\ + NameFromLock((LockName), xxName, sizeof(xxName));\ + KPrintF("%s/%s/%ld: " #LockName "=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, LockName, xxName);\ + } + +// from debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +//---------------------------------------------------------------------------- + +#endif /* DEBUG_H */ diff --git a/scalos/Modules/Find.MUI/makefile b/scalos/Modules/Find.MUI/makefile new file mode 100644 index 000000000..378ed4fae --- /dev/null +++ b/scalos/Modules/Find.MUI/makefile @@ -0,0 +1,132 @@ +# MakeFile für Find MUI module +# $Date$ + +##################################################################### + +TOPLEVEL = / +SUBDIRMAKE = $(MAKE) -s -C +CATCOMP = CatComp +FLEXCAT = FlexCat +CHEADERS = +CC = sc +CFLAGS = optimize nostackcheck nochkabort debug=s NOWVRET \ + strmer nover streq idlen=128 IGNORE=217 \ + define SCALOSLOCALE=$(SCALOS_LOCALE) \ + idir=sc:include/ \ + idir=include: idir=//include +AFLAGS = QUIET m=68020 linedebug opt=NRQB i=include: +LD = slink +LNFLAGS = quiet batch noicons stripdebug +LNDBFLAGS = quiet batch noicons addsym +LIBS = LIB:sc.lib \ + //SAS-lib/snprintf.lib \ + LIB:mempools.lib \ + LIB:debug.lib \ + LIB:amiga.lib +CSTARTUP = LIB:c.o +OBJDIR = .sasobj + +SCALOS_LOCALE = $(OBJDIR)/Find_Locale.h + +.SUFFIXES: .cd + +############################################################# + +NAME = .bin_os3/Find.module +DBGNAME = $(NAME).debug +CATCOMPHEADER = $(SCALOS_LOCALE) +DESTTOOL = Scalos:modules/ +CAT_FILE = Scalos/Find.catalog +DESTCAT = Locale:Catalogs +ALLCATS = Catalogs/deutsch/$(CAT_FILE) \ + Catalogs/français/$(CAT_FILE) + +############################################################# + +all: $(NAME) \ + $(DBGNAME) \ + allcatalogs +# install +# clean + +##################################################################### + +# make all Scalos .catalogs +allcatalogs: + @$(SUBDIRMAKE) Catalogs/deutsch/Scalos + @$(SUBDIRMAKE) Catalogs/français/Scalos + +##################################################################### + +CSRCS = Find.c \ + DefIcons.c \ + +##################################################################### + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +############################################################# + +XSRCS = $(notdir $(CSRCS)) +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(XSRCS:%.c=$(OBJDIR)/$(notdir %).o) + +##################################################################### + +$(CATCOMPHEADER) : Find.cd + @printf '\033[32mMake Catcomp header: \033[31m\033[1m$@ \033[32mfrom \033[31m$<\033[0m\n' + @$(FLEXCAT) $< $@=$(TOPLEVEL)/CatComp_h.sd + +##################################################################### + +$(OBJDIR)/Find.o : Find.c Find.h \ + $(SCALOS_LOCALE) \ + debug.h + +##################################################################### + +$(NAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNFLAGS) + +$(DBGNAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNDBFLAGS) + +############################################################# + +# commands generated a catalog (.catalog) from a catalog translation (.ct) file. +.ct.catalog: + $(CATCOMP) $*.cd $< CATALOG $*.catalog VB=1 + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $< objectname $@ + +$(OBJDIR)/%.o : %.s + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +$(OBJDIR)/%.o : %.asm + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +############################################################# + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(NAME) \033[0mto \033[1m$(DESTTOOL) \033[0m\n' + @copy $(NAME) $(DESTTOOL) clone + @printf '\033[32mFlushing memory\033[0m\n' + @avail flush + @printf '\033[32mInstall: \033[31m\033[1m$(CAT_FILE)\033[0m\n' + -@copy 'catalogs/deutsch/$(CAT_FILE)' '$(DESTCAT)/Deutsch/Scalos/' clone + -@copy 'catalogs/français/$(CAT_FILE)' '$(DESTCAT)/français/Scalos/' clone + +############################################################# + +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + -@delete $(OBJS) $(NAME) $(DBGNAME) $(ALLCATS) $(CATCOMPHEADER) + @printf '\033[0m' + +############################################################# diff --git a/scalos/Modules/Find.MUI/makefile-new b/scalos/Modules/Find.MUI/makefile-new new file mode 100755 index 000000000..781dcca51 --- /dev/null +++ b/scalos/Modules/Find.MUI/makefile-new @@ -0,0 +1,101 @@ +# $Date: 2011-07-16 16:53:37 +0200 (Sa, 16. Jul 2011) $ +# $Revision: 782 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL = $(shell pwd)/../.. +endif + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + SDPATH=/ +else + SDPATH=../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(OBJDIR)/Find.o \ + $(OBJDIR)/DefIcons.o \ + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Subdirs +# + +SUBDIRS = $(filter-out Catalogs/sample/Scalos, $(wildcard Catalogs/*/Scalos)) + +############################################################################## +# +# Targets +# + +NAME = Find.module +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) \ + all_subdirs + +############################################################################## + +$(OBJDIR)/%.o: $(TOOLTYPE_DIR)/%.c + @$(run-cc) + +$(OBJDIR)/%.o: $(ICONOBJMCC_DIR)/%.c + @$(run-cc) + +Find.c : $(OBJDIR)/Find_Locale.h + +$(OBJDIR)/Find_Locale.h : Find.cd + @$(ECHO) "FlexCat $@" + $(FLEXCAT) $< $@=$(SDPATH)/CatComp_h.sd + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + @$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) +ifneq ($(MACHINE), ppc-amigaos) + -@chmod u+x $@ +endif + +############################################################################## + +install: install_subdirs + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) Scalos:modules/ clone + +clean: clean_subdirs + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* \ + $(OBJDIR)/Find_Locale.h + +############################################################################## + diff --git "a/scalos/Modules/FormatDisk.Gadtools/Catalogs/Fran\303\247ais/Scalos/FormatDisk.ct" "b/scalos/Modules/FormatDisk.Gadtools/Catalogs/Fran\303\247ais/Scalos/FormatDisk.ct" new file mode 100644 index 000000000..a0c370f4a --- /dev/null +++ "b/scalos/Modules/FormatDisk.Gadtools/Catalogs/Fran\303\247ais/Scalos/FormatDisk.ct" @@ -0,0 +1,340 @@ +; FormatDisk.ct +; $Date$ +; $Revision$ +; $Id$ +; +## version $VER: FormatDisk.catalog 1.05 (08.12.2006) +## codeset 0 +## language français +; +;#arrayopts static __far +; +; +MSGID_DEVICE_SPACE_USED +Utilisé : +;Used: +; +; +MSGID_DEVICE_SPACE_FREE +Libre: +;Free: +; +; +MSGID_DEVICE_SIZE +Taille : +;Size: +; +; +MSGID_DEVICE_BLOCK_SIZE +Taille des blocs : +;Block size: +; +; +MSGID_DEVICE_BLOCKS_PERCENT_USED +Utilisé : %s (%lD Blocks, %lD%%) +;Used: %s (%lD Blocks, %lD%%) +; +; +MSGID_DEVICE_BLOCKS_PERCENT_FREE +Libre: %s (%lD Blocks, %lD%%) +;Free: %s (%lD Blocks, %lD%%) +; +; +;Size: +MSGID_DEVICE_BLOCKS +Taille : %s (%lD Blocks) +;%s (%lD Blocks) +; +; +MSGID_DEVICE_SHORTSIZE +Taille : %ld +;Size : %ld +; +; +; Block size: +MSGID_DEVICE_BLOCKSIZE_BYTES +Taille des blocs : %lD +;Block size: %lD bytes +; +; +; +MSGID_REQ_SURE_TITLE +Format_Disk.module : Requête... +;Format_Disk.module: Request... +; +; +MSGID_REQ_SURE_BODY +Etes-vous certain de vouloir formater le volume :\n\ +%s\n\ +\n\ +%s\n\ +\n\ +(Le contenu de ce disque sera détruit) ? +;Are you sure you want to format volume\n\ +;%s\n\ +;\n\ +;%s\n\ +;\n\ +;(the contents of the disk will be destroyed)? +; +; +; +MSGID_REQ_SURE_GADGETS +Oui|Non +;Yes|No +; +; +MSGID_VOLUME_PROTECTED +Le Volume\n%s\nest protégé en écriture +;Volume\n%s\nis write protected +; +; +MSGID_REQ_RETRY_CANCEL +Recommencer|Annuler +;Retry|Cancel +; +; +MSGID_GADGET_OK +D'accord +;OK +; +;--------------------------------------------------------------------------- +; +MSGID_GADGET_DEVNAME +_Nom du volume : +;_Name: +; +; +MSGID_GADGET_VOLUME +Volume : +;Volume: +; +MSGID_GADGET_DEVICE +Unité : +;Device: +; +; +MSGID_GADGET_FFS +_FFS +;_Fast File System +; +; +MSGID_GADGET_INTL +Mode _International +;_International +; +; +MSGID_GADGET_VERIFY +_Vérification +;_Verify Format +; +; +MSGID_GADGET_TRASHCAN +Avec cor_beille +;With t_rashcan +; +; +MSGID_GADGET_DIRCACHE +_Répertoire cache +;_Dircache +; +; +MSGID_GADGET_TRASHCAN_NAME +_Corbeille : +;_Trash: +; +; +MSGID_GADGET_GUI_FORMAT +_D'accord +;_Format +; +; +MSGID_GADGET_QUICK_FORMAT +For_mat. rapide +;_Quick Format +; +; +MSGID_GADGET_GUI_CANCEL +_Annuler +;_Cancel +; +; +MSGID_DRIVE_NOFOUND +L'unité est introuvable ! +; +; +MSGID_VOLUME_SELECTED +Volume sélectionné : +;Volume selected: +; +; +MSGID_OBJECT +L'objet : +;Object: +; +; +MSGID_IS_WRONG_TYPE +est de type incorrect ! +;is a wrong type! +; +; +;-------------------------------------------------------- +; +; +MSGID_CLI_SUPPORT_64CMD +*** L'unité %s supporte les commandes 64bit ! Capacité de formattage illimité !\n +;*** Device %s supports 64bit commands! No size limit!!\n +; +; +MSGID_CLI_NO_SUPPORT_64CMD +*** L'unité %s ne supporte pas les commandes 64bit. Le formattage est limité à une capacité de 4GB !\n +;*** Device %s does NOT support 64bit commands. 4GB limit activated!!\n +; +; +MSGID_CLI_INSERT_DISK +Insèrez le disque à formatter dans le lecteur +;Insert the disk to be formatted in drive +; +; +MSGID_CLI_PRESS_RETURN + et pressez la touche RETURN +; and press RETURN +; +; +MSGID_INITIALIZING_DISK +Initialisation du disque... +;Initializing disk... +; +; +MSGID_INITIALIZING_DISK_SUCCESS +Initialisation réussie. +;Initialized successfully. +; +; +MSGID_INITIALIZING_DISK_FAILED +L'initialisation du disque a échouée. +;Initialization failed. +; +; +MSGID_SECOND_INITIALIZING_DISK +Seconde initialisation... +;Second Initialization... +; +; +MSGID_CLI_BREAK +***Interruption\n +;***Break\n +; +; +MSGID_FORMAT_DISK_FAILED +Impossible de formatter le volume +;Cannot format volume +; +; +MSGID_FORMAT_DISK_WRITEPROTECTED +parce que le disque est protégé en écriture +;because the disk is write protected +; +; +MSGID_DEVICE_NOT_ACCESS +Impossible d'accèder à l'unité ! +;Couldn't access the device +; +; +MSGID_CREATING_TRASHCAN_USER +Création de la corbeille, nommée : \"%s\" +;Creating Trashcan, named: \"%s\" +; +; +MSGID_CREATING_TRASHCAN_DEFAULT +Création de la corbeille, nommée : \"Trashcan\" +;Creating Trashcan, named: \"Trashcan\" +; +; +MSGID_CREATING_TRASHCAN_ERROR +Une erreur est survenue lors de la création de la corbeille. +;There was an error while creating the trashcan +; +; +MSGID_CREATING_TRASHCAN_DIR_ERROR +Une erreur est survenue lors de la création du répertoire de la corbeille. +;There was an error while creating the trashcan directory +; +;---------------------------------------------------------- +; +MSGID_GUI_FORMATTING_CYLINDER +Formatage du cylindre %ld/%ld, %ld restant(s) +;Formatting cylinder %ld/%ld, %ld to go +; +; +MSGID_FORMATTING_ERROR +Une erreur est survenue pendant le formatage ! +;A formatting error occured +; +; +MSGID_GUI_FORMATTING_ABORTED +Opération de formatage annulée ! +;Formatting operation aborted! +; +; +MSGID_GUI_VERIFYING_CYLINDER +Vérification du cylindre %ld/%ld, %ld restant(s) +;Verifying cylinder %ld/%ld, %ld to go +; +; +MSGID_VERIFYING_ERROR +Une erreur est survenue pendant la vérification ! +;A verify error occurred +; +; +MSGID_GUI_VERIFYING_ABORTED +Opération de vérification annulée ! +;Verifying operation aborted! +; +; +MSGID_WARNING_FORMAT_DEVICE_NO64BIT +Vous tentez de formater au-delà des 4GB néanmoins\n\ +votre unité ne supporte pas les commandes 64 bit. De ce fait,\n\ +l'opération de formatage est annulée afin de préserver votre disque. +;You are trying to format beyond 4GB border although\n\ +;your device does not support 64 bit commands. Due to this\n\ +;fact, format operation is aborted in order to save your drive. +; +; +;-------------------------------------------------------- +; +MSGID_GUI_PREPWINDOW_TITLE +Format_Disk.module +;Format_Disk.module +; +; +MSGID_GUI_STATUSWINDOW_TITLE +Format_Disk.module: Statut +;Format_Disk.module: Status +; +; +MSGID_GUI_STATUSWINDOW_FORMATTING_DRIVE +Formatage de \"%s\" nommé \"%s\" - [%s] ... +;Formatting drive \"%s\" as \"%s\" [%s] ... +; +; +MSGID_GUI_STATUSWINDOW_DEVICE_64BIT +Unité statut : \"%s\" [ Support NSD : OUI ]. +;Status Device: \"%s\" [ NSD Support: YES ]. +; +; +MSGID_GUI_STATUSWINDOW_DEVICE_NO64BIT +Unité statut : \"%s\" [ Support NSD : N/D ]. +;Status Device: \"%s\" [ NSD Support: N/A. ] +; +; +MSGID_GUI_STATUSWINDOW_ABORT +_Interrompre +;_Stop +; +; +MSGID_GUI_ON_DRIVE +Sur périphèrique : +;On drive +; +; diff --git "a/scalos/Modules/FormatDisk.Gadtools/Catalogs/Fran\303\247ais/Scalos/config.mk" "b/scalos/Modules/FormatDisk.Gadtools/Catalogs/Fran\303\247ais/Scalos/config.mk" new file mode 100755 index 000000000..8b7056423 --- /dev/null +++ "b/scalos/Modules/FormatDisk.Gadtools/Catalogs/Fran\303\247ais/Scalos/config.mk" @@ -0,0 +1,40 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = français + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = french + +else + +############################################################################### +# AmigaOS and AROS + +LANG = français + +endif +endif diff --git "a/scalos/Modules/FormatDisk.Gadtools/Catalogs/Fran\303\247ais/Scalos/makefile" "b/scalos/Modules/FormatDisk.Gadtools/Catalogs/Fran\303\247ais/Scalos/makefile" new file mode 100644 index 000000000..c96adbf0c --- /dev/null +++ "b/scalos/Modules/FormatDisk.Gadtools/Catalogs/Fran\303\247ais/Scalos/makefile" @@ -0,0 +1,15 @@ +# makefile for FormatDisk.ct (translated Texts : français) +# $Date$ +# $Revision$ +# $Id$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mfrançais\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +FormatDisk.catalog : FormatDisk.ct ../../../FormatDisk.cd + +All: FormatDisk.catalog diff --git "a/scalos/Modules/FormatDisk.Gadtools/Catalogs/Fran\303\247ais/Scalos/makefile-new" "b/scalos/Modules/FormatDisk.Gadtools/Catalogs/Fran\303\247ais/Scalos/makefile-new" new file mode 100644 index 000000000..5546da025 --- /dev/null +++ "b/scalos/Modules/FormatDisk.Gadtools/Catalogs/Fran\303\247ais/Scalos/makefile-new" @@ -0,0 +1,30 @@ +# makefile for FormatDisk.module (translated Texts : français) +# $Date: 2011-08-10 14:03:16 +0200 (Mi, 10. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = FormatDisk + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Modules/FormatDisk.Gadtools/Catalogs/deutsch/Scalos/FormatDisk.ct b/scalos/Modules/FormatDisk.Gadtools/Catalogs/deutsch/Scalos/FormatDisk.ct new file mode 100644 index 000000000..43f3b68df --- /dev/null +++ b/scalos/Modules/FormatDisk.Gadtools/Catalogs/deutsch/Scalos/FormatDisk.ct @@ -0,0 +1,354 @@ +; FormatDisk.ct +; $Date$ +; $Revision$ +; $Id$ +; +## version $VER: FormatDisk.catalog 1.05 (08.12.2006) +## codeset 0 +## language deutsch +; +;#arrayopts static __far +; +; +; +; +MSGID_DEVICE_SPACE_USED +Belegt: +;Used: +; +; +; +MSGID_DEVICE_SPACE_FREE +Frei: +;Free: +; +; +; +MSGID_DEVICE_SIZE +Größe: +;Size: +; +; +; +MSGID_DEVICE_BLOCK_SIZE +Blockgröße: +;Block size: +; +; +; +MSGID_DEVICE_BLOCKS_PERCENT_USED +Belegt: %s (%lD Blöcke, %lD%%) +;Used: %s (%lD Blocks, %lD%%) +; +; +; +MSGID_DEVICE_BLOCKS_PERCENT_FREE +Frei: %s (%lD Blöcke, %lD%%) +;Free: %s (%lD Blocks, %lD%%) +; +; +; +MSGID_DEVICE_BLOCKS +Größe: %s (%lD Blöcke) +;Size: %s (%lD Blocks) +; +; +; +MSGID_DEVICE_SHORTSIZE +Größe: %ld +;Size : %ld +; +; +; +MSGID_DEVICE_BLOCKSIZE_BYTES +Blockgröße: %lD bytes +;Block size:%lD bytes +; +; +; +MSGID_REQ_SURE_TITLE +Format_Disk.module : Anfrage... +;Format_Disk.module: Request... +; +; +; +MSGID_REQ_SURE_BODY +Sind Sie sicher, daß Sie den Datenträger\n\ +%s\n\ +\n\ +%s\n\ +formatieren möchten??\n\ +(Der Inhalt des Datenträgers wird komplett gelöscht!)? +;Are you sure you want to format volume\n\ +;%s\n\ +;\n\ +;%s\n\ +;\n\ +;(the contents of the disk will be destroyed)? +; +; +; +MSGID_REQ_SURE_GADGETS +Ja|Nein +;Yes|No +; +; +; +MSGID_VOLUME_PROTECTED +Datenträger\n%s\nist schreibgeschützt +;Volume\n%s\nis write protected +; +; +; +MSGID_REQ_RETRY_CANCEL +Wiederholen|Abbrechen +;Retry|Cancel +; +; +; +MSGID_GADGET_OK +OK +;Ok +; +;--------------------------------------------------------------------------- +; +MSGID_GADGET_DEVNAME +_Name: +;_Name: +; +; +MSGID_GADGET_VOLUME +Datenträger: +;Volume: +; +; +MSGID_GADGET_DEVICE +Gerät: +;Device: +; +; +MSGID_GADGET_FFS +_Fastfilesystem: +;_Fast File System +; +; +MSGID_GADGET_INTL +_Internationaler Modus: +;_International +; +; +MSGID_GADGET_VERIFY +Format _Überprüfen +;_Verify Format +; +; +MSGID_GADGET_TRASHCAN +Mit _Papierkorb +;With t_rashcan +; +; +MSGID_GADGET_DIRCACHE +_Verzeichnis-Cache: +;_Dircache +; +; +MSGID_GADGET_TRASHCAN_NAME +Papier_korb: +;_Trash: +; +; +MSGID_GADGET_GUI_FORMAT +_Formatieren +;_Format +; +; +MSGID_GADGET_QUICK_FORMAT +_Schnellformatierung +;_Quick Format +; +; +MSGID_GADGET_GUI_CANCEL +_Abbruch +;_Cancel +; +; +MSGID_DRIVE_NOFOUND +Kann Laufwerk nicht finden! +; +; +MSGID_VOLUME_SELECTED +Ausgewählter Datenträger: +;Volume selected: +; +; +MSGID_OBJECT +Objekt: +;Object: +; +; +MSGID_IS_WRONG_TYPE +hat falschen typ! +;is a wrong type! +; +;-------------------------------------------------------- +; +; +MSGID_CLI_SUPPORT_64CMD +*** Gerät %s unterstützt 64-Bit Befehle! Keine Größenbegrenzung!\n +;*** Device %s supports 64bit commands! No size limit!!\n +; +; +MSGID_CLI_NO_SUPPORT_64CMD +*** Gerät %s unterstützt KEINE 64-Bit Befehle! Größe wird auf 4GB begrenzt!!\n +;*** Device %s does NOT support 64bit commands. 4GB limit activated!!\n +; +; +MSGID_CLI_INSERT_DISK +Bitte zu formatierenden Datenträger ins Laufwerk einlegen +;Insert the disk to be formatted in drive +; +; +MSGID_CLI_PRESS_RETURN + und die Enter-Taste drücken +; and press RETURN +; +; +MSGID_INITIALIZING_DISK +Disk wird initialisiert... +;Initializing disk... +; +; +MSGID_INITIALIZING_DISK_SUCCESS +Initialisierung erfolgreich. +;Initialized successfully. +; +; +MSGID_INITIALIZING_DISK_FAILED +Fehler bei der Initialisierung. +;Initialization failed. +; +; +++ translateme +++ +MSGID_SECOND_INITIALIZING_DISK +Second Initialization... +;Second Initialization... +; +; +MSGID_CLI_BREAK +***Abbruch\n +;***Break\n +; +; +MSGID_FORMAT_DISK_FAILED +Kann Datenträger nicht formatieren +;Cannot format volume +; +; +MSGID_FORMAT_DISK_WRITEPROTECTED +Weil er schreibgeschützt ist +;because the disk is write protected +; +; +MSGID_DEVICE_NOT_ACCESS +Konnte nicht auf das Gerät zugreifen +;Couldn't access the device +; +; +MSGID_CREATING_TRASHCAN_USER +Papierkorb wird angelegt als \"%s\". +;Creating Trashcan, named: \"%s\" +; +; +MSGID_CREATING_TRASHCAN_DEFAULT +Papierkorb wird angelegt als \"Trashcan\". +;Creating Trashcan, named: \"Trashcan\" +; +; +MSGID_CREATING_TRASHCAN_ERROR +Fehler beim Anlegen des Papierkorbs +;There was an error while creating the trashcan +; +; +MSGID_CREATING_TRASHCAN_DIR_ERROR +Fehler beim Erzeugen der Papierkorb-Schublade +;There was an error while creating the trashcan directory +; +;---------------------------------------------------------- +; +; +MSGID_GUI_FORMATTING_CYLINDER +Formatieren von Zylinder %ld/%ld, noch %ld übrig +;Formatting cylinder %ld/%ld, %ld to go +; +; +MSGID_FORMATTING_ERROR +Fehler beim Formatieren +;A formatting error occured +; +; +MSGID_GUI_FORMATTING_ABORTED +Formatierung abgebrochen! +;Formatting operation aborted! +; +; +MSGID_GUI_VERIFYING_CYLINDER +Überprüfen von Zylinder %ld/%ld, noch %ld übrig +;Verifying cylinder %ld/%ld, %ld to go +; +; +MSGID_VERIFYING_ERROR +Fehler beim Überprüfen +;A verify error occurred +; +; +MSGID_GUI_VERIFYING_ABORTED +Überprüfung abgebrochen +;Verifying operation aborted! +; +; +MSGID_WARNING_FORMAT_DEVICE_NO64BIT +Sie veruschen ein Laufwerk jenseits der 4GB-Grenze zu\n\ +formatieren, obwohl das Gerät keine 64-Befehle unterstützt.\n\ +Daher wird die Formatierung abgebrochen, um Zerstörung von\n\ +Laufwerksinhalten zu vermeiden. +;You are trying to format beyond 4GB border although\n\ +;your device does not support 64 bit commands. Due to this\n\ +;fact, format operation is aborted in order to save your drive. +; +;-------------------------------------------------------- +; +; +MSGID_GUI_PREPWINDOW_TITLE +Format_Disk.module +;Format_Disk.module +; +; +MSGID_GUI_STATUSWINDOW_TITLE +Format_Disk.module: Status +;Format_Disk.module: Status +; +; +MSGID_GUI_STATUSWINDOW_FORMATTING_DRIVE +Formatiere Laufwerk \"%s\" als \"%s\" [%s] ... +;Formatting drive \"%s\" as \"%s\" [%s] ... +; +; +MSGID_GUI_STATUSWINDOW_DEVICE_64BIT +Gerätestatus: \"%s\" [ NSD-Unterstützung: Ja ]. +;Status Device: \"%s\" [ NSD Support: YES ]. +; +; +MSGID_GUI_STATUSWINDOW_DEVICE_NO64BIT +Gerätestatus: \"%s\" [ NSD-Unterstützung: Nein. ] +;Status Device: \"%s\" [ NSD Support: N/A. ] +; +; +MSGID_GUI_STATUSWINDOW_ABORT +_Abbrechen +;_Stop +; +; +MSGID_GUI_ON_DRIVE +Auf Laufwerk +;On drive +; +; diff --git a/scalos/Modules/FormatDisk.Gadtools/Catalogs/deutsch/Scalos/config.mk b/scalos/Modules/FormatDisk.Gadtools/Catalogs/deutsch/Scalos/config.mk new file mode 100755 index 000000000..8631b0623 --- /dev/null +++ b/scalos/Modules/FormatDisk.Gadtools/Catalogs/deutsch/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = deutsch + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = german + +else + +############################################################################### +# AmigaOS and AROS + +LANG = deutsch + +endif +endif diff --git a/scalos/Modules/FormatDisk.Gadtools/Catalogs/deutsch/Scalos/makefile b/scalos/Modules/FormatDisk.Gadtools/Catalogs/deutsch/Scalos/makefile new file mode 100644 index 000000000..9c1fbeac1 --- /dev/null +++ b/scalos/Modules/FormatDisk.Gadtools/Catalogs/deutsch/Scalos/makefile @@ -0,0 +1,15 @@ +# makefile for FormatDisk.ct (translated Texts : deutsch) +# $Date: 2$ +# $Revision$ +# $Id$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mdeutsch\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +FormatDisk.catalog : FormatDisk.ct ../../../FormatDisk.cd + +All: FormatDisk.catalog diff --git a/scalos/Modules/FormatDisk.Gadtools/Catalogs/deutsch/Scalos/makefile-new b/scalos/Modules/FormatDisk.Gadtools/Catalogs/deutsch/Scalos/makefile-new new file mode 100644 index 000000000..f086dc78a --- /dev/null +++ b/scalos/Modules/FormatDisk.Gadtools/Catalogs/deutsch/Scalos/makefile-new @@ -0,0 +1,30 @@ +# makefile for FormatDisk.module (translated Texts : deutsch) +# $Date: 2011-08-10 14:03:16 +0200 (Mi, 10. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = FormatDisk + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Modules/FormatDisk.Gadtools/Catalogs/sample/Scalos/FormatDisk.ct b/scalos/Modules/FormatDisk.Gadtools/Catalogs/sample/Scalos/FormatDisk.ct new file mode 100644 index 000000000..d00a76bb3 --- /dev/null +++ b/scalos/Modules/FormatDisk.Gadtools/Catalogs/sample/Scalos/FormatDisk.ct @@ -0,0 +1,359 @@ +; FormatDisk.ct +; $Date$ +; $Revision$ +; $Id$ +; +## version $VER: FormatDisk.catalog 1.05 (08.12.2006) +## codeset 0s +## language xxxxxx +; +;#arrayopts static __far +; +; +; +; +++ translateme +++ +MSGID_DEVICE_SPACE_USED +Used: +;Used: +; +; +; +++ translateme +++ +MSGID_DEVICE_SPACE_FREE +Free: +;Free: +; +; +; +++ translateme +++ +MSGID_DEVICE_SIZE +Size: +;Size: +; +; +; +++ translateme +++ +MSGID_DEVICE_BLOCK_SIZE +Block size: +;Block size: +; +; +; +++ translateme +++ +MSGID_DEVICE_BLOCKS_PERCENT_USED +Used: %s (%lD Blocks, %lD%%) +;Used: %s (%lD Blocks, %lD%%) +; +; +; +++ translateme +++ +MSGID_DEVICE_BLOCKS_PERCENT_FREE +Free: %s (%lD Blocks, %lD%%) +;Free: %s (%lD Blocks, %lD%%) +; +; +; +++ translateme +++ +MSGID_DEVICE_BLOCKS +Size: %s (%lD Blocks) +;Size: %s (%lD Blocks) +; +; +; +++ translateme +++ +MSGID_DEVICE_SHORTSIZE +Taille : %ld +;Size : %ld +; +; +; +++ translateme +++ +MSGID_DEVICE_BLOCKSIZE_BYTES +Block size: %lD bytes +;Block size:%lD bytes +; +; +; +++ translateme +++ +MSGID_REQ_SURE_TITLE +Format_Disk.module : Request... +;Format_Disk.module: Request... +; +; +; +++ translateme +++ +MSGID_REQ_SURE_BODY +Are you sure you want to format volume\n\ +%s\n\ +\n\ +%s\n\ +%s\n\ +%s\ +\n\ +\n\ +(the contents of the disk will be destroyed)? +;Are you sure you want to format volume\n\ +;%s\n\ +;\n\ +;%s\n\ +;%s\n\ +;%s\ +;\n\ +;\n\ +;(the contents of the disk will be destroyed)? +; +; +; +++ translateme +++ +MSGID_REQ_SURE_GADGETS +Yes|No +;Yes|No +; +; +; +++ translateme +++ +MSGID_VOLUME_PROTECTED +Volume\n%s\nis write protected +;Volume\n%s\nis write protected +; +; +; +++ translateme +++ +MSGID_REQ_RETRY_CANCEL +Retry|Cancel +;Retry|Cancel +; +; +; +++ translateme +++ +MSGID_GADGET_OK +OK +;Ok +; +;--------------------------------------------------------------------------- +; +; +++ translateme +++ +MSGID_GADGET_DEVNAME +_Name: +;_Name: +; +; +++ translateme +++ +MSGID_GADGET_VOLUME +Volume: +;Volume: +; +; +++ translateme +++ +MSGID_GADGET_DEVICE +Device: +;Device: +; +; +++ translateme +++ +MSGID_GADGET_FFS +_Fast File System +;_Fast File System +; +; +++ translateme +++ +MSGID_GADGET_INTL +_International +;_International +; +; +++ translateme +++ +MSGID_GADGET_VERIFY +_Verify Format +;_Verify Format +; +; +++ translateme +++ +MSGID_GADGET_TRASHCAN +With t_rashcan +;With t_rashcan +; +; +++ translateme +++ +MSGID_GADGET_DIRCACHE +_Dircache +;_Dircache +; +; +++ translateme +++ +MSGID_GADGET_TRASHCAN_NAME +_Trash: +;_Trash: +; +; +++ translateme +++ +MSGID_GADGET_GUI_FORMAT +_Format +;_Format +; +; +++ translateme +++ +MSGID_GADGET_QUICK_FORMAT +_Quick Format +;_Quick Format +; +; +++ translateme +++ +MSGID_GADGET_GUI_CANCEL +_Cancel +;_Cancel +; +; +++ translateme +++ +MSGID_DRIVE_NOFOUND +Can't find its drive! +; +; +++ translateme +++ +MSGID_VOLUME_SELECTED +Volume selected: +;Volume selected: +; +; +++ translateme +++ +MSGID_OBJECT +Object: +;Object: +; +; +++ translateme +++ +MSGID_IS_WRONG_TYPE +is a wrong type! +;is a wrong type! +; +;-------------------------------------------------------- +; +++ translateme +++ +MSGID_CLI_SUPPORT_64CMD +*** Device %s supports 64bit commands! No size limit!!\n +;*** Device %s supports 64bit commands! No size limit!!\n +; +; +++ translateme +++ +MSGID_CLI_NO_SUPPORT_64CMD +*** Device %s does NOT support 64bit commands. 4GB limit activated!!\n +;*** Device %s does NOT support 64bit commands. 4GB limit activated!!\n +; +; +++ translateme +++ +MSGID_CLI_INSERT_DISK +Insert the disk to be formatted in drive +;Insert the disk to be formatted in drive +; +; +++ translateme +++ +MSGID_CLI_PRESS_RETURN + and press RETURN +; and press RETURN +; +; +++ translateme +++ +MSGID_INITIALIZING_DISK +Initializing disk... +;Initializing disk... +; +; +++ translateme +++ +MSGID_INITIALIZING_DISK_SUCCESS +Initialized successfully. +;Initialized successfully. +; +; +++ translateme +++ +MSGID_INITIALIZING_DISK_FAILED +Initialization failed. +;Initialization failed. +; +; +++ translateme +++ +MSGID_SECOND_INITIALIZING_DISK +Second Initialization... +;Second Initialization... +; +; +++ translateme +++ +MSGID_CLI_BREAK +***Break\n +;***Break\n +; +; +++ translateme +++ +MSGID_FORMAT_DISK_FAILED +Cannot format volume +;Cannot format volume +; +; +++ translateme +++ +MSGID_FORMAT_DISK_WRITEPROTECTED +because the disk is write protected +;because the disk is write protected +; +; +++ translateme +++ +MSGID_DEVICE_NOT_ACCESS +Couldn't access the device +;Couldn't access the device +; +; +++ translateme +++ +MSGID_CREATING_TRASHCAN_USER +Creating Trashcan, named: \"%s\" +;Creating Trashcan, named: \"%s\" +; +; +++ translateme +++ +MSGID_CREATING_TRASHCAN_DEFAULT +Creating Trashcan, named: \"Trashcan\" +;Creating Trashcan, named: \"Trashcan\" +; +; +++ translateme +++ +MSGID_CREATING_TRASHCAN_ERROR +There was an error while creating the trashcan +;There was an error while creating the trashcan +; +; +++ translateme +++ +MSGID_CREATING_TRASHCAN_DIR_ERROR +There was an error while creating the trashcan directory +;There was an error while creating the trashcan directory +; +;---------------------------------------------------------- +; +; +++ translateme +++ +MSGID_GUI_FORMATTING_CYLINDER +Formatting cylinder %ld/%ld, %ld to go +;Formatting cylinder %ld/%ld, %ld to go +; +; +++ translateme +++ +MSGID_FORMATTING_ERROR +A formatting error occured +;A formatting error occured +; +; +++ translateme +++ +MSGID_GUI_FORMATTING_ABORTED +Formatting operation aborted! +;Formatting operation aborted! +; +; +++ translateme +++ +MSGID_GUI_VERIFYING_CYLINDER +Verifying cylinder %ld/%ld, %ld to go +;Verifying cylinder %ld/%ld, %ld to go +; +; +++ translateme +++ +MSGID_VERIFYING_ERROR +A verify error occurred +;A verify error occurred +; +; +++ translateme +++ +MSGID_GUI_VERIFYING_ABORTED +Verifying operation aborted! +;Verifying operation aborted! +; +; +++ translateme +++ +MSGID_WARNING_FORMAT_DEVICE_NO64BIT +You are trying to format beyond 4GB border although\n\ +your device does not support 64 bit commands. Due to this\n\ +fact, format operation is aborted in order to save your drive. +;You are trying to format beyond 4GB border although\n\ +;your device does not support 64 bit commands. Due to this\n\ +;fact, format operation is aborted in order to save your drive. +; +;-------------------------------------------------------- +; +; +++ translateme +++ +MSGID_GUI_PREPWINDOW_TITLE +Format_Disk.module +;Format_Disk.module +; +; +++ translateme +++ +MSGID_GUI_STATUSWINDOW_TITLE +Format_Disk.module: Status +;Format_Disk.module: Status +; +; +++ translateme +++ +MSGID_GUI_STATUSWINDOW_FORMATTING_DRIVE +Formatting drive \"%s\" as \"%s\" [%s] ... +;Formatting drive \"%s\" as \"%s\" [%s] ... +; +; +++ translateme +++ +MSGID_GUI_STATUSWINDOW_DEVICE_64BIT +Status Device: \"%s\" [ NSD Support: YES ]. +;Status Device: \"%s\" [ NSD Support: YES ]. +; +; +++ translateme +++ +MSGID_GUI_STATUSWINDOW_DEVICE_NO64BIT +Status Device: \"%s\" [ NSD Support: N/A. ] +;Status Device: \"%s\" [ NSD Support: N/A. ] +; +; +++ translateme +++ +MSGID_GUI_STATUSWINDOW_ABORT +_Stop +;_Stop +; +; +++ translateme +++ +MSGID_GUI_ON_DRIVE +On drive +;On drive +; +; diff --git a/scalos/Modules/FormatDisk.Gadtools/Device_Handler.c b/scalos/Modules/FormatDisk.Gadtools/Device_Handler.c new file mode 100644 index 000000000..711f3829b --- /dev/null +++ b/scalos/Modules/FormatDisk.Gadtools/Device_Handler.c @@ -0,0 +1,285 @@ +// Device_Handler.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "Format.h" + +//----------------------------------------------------------------------------- + +STRPTR NameOfDevice = ""; // +jmc+ : driver name copied here, problems found after twice analyzes for a same drive. + +LONG TextHighCyl=0; +LONG TextLayoutBPT=0; + +//----------------------------------------------------------------------------- + +// Convert a volume name to a device name, and get information +// on the layout of the disk +// +BOOL volumeToDevName(BPTR volumeLock, char *dev, DriveLayout *layout) + { + struct DosList *dosList; + char name[36]; + struct Process *process; + APTR oldWdw; + BOOL Found = FALSE; + + + d1(KPrintF("%s/%s/%ld: START dev=<%s>\n", __FILE__, __FUNC__, __LINE__, dev)); + debugLock_d1(volumeLock); + + // Disable requestors during the execution of this function + process = (struct Process *) FindTask(NULL); + oldWdw = process->pr_WindowPtr; + process->pr_WindowPtr = (APTR)(-1); + + // Get the DOS device list + dosList = LockDosList(LDF_DEVICES|LDF_READ); + + // Go through each entry + while (!Found && dosList != NULL) + { + dosList = NextDosEntry(dosList, LDF_DEVICES|LDF_READ); + if (dosList == NULL) + break; + + d1(KPrintF("%s/%s/%ld: dol_Startup=%08lx dol_Handler=%08lx Type=%ld Task=%08lx Lock=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, dosList->dol_misc.dol_handler.dol_Startup, + dosList->dol_misc.dol_handler.dol_Handler, dosList->dol_Type, dosList->dol_Task, dosList->dol_Lock)); + + // If the node in the list is a volume + if (dosList->dol_misc.dol_handler.dol_Startup > (BPTR) 1000 && + (dosList->dol_Task /* || dosList->dol_misc.dol_handler.dol_Handler */ || dosList->dol_misc.dol_handler.dol_SegList)) + { + BOOL stat = FALSE; + + // Get the name of the device + BtoCString(dosList->dol_Name, name, sizeof(name) - 1); + strcat(name, ":"); + + /*Get the information on the device*/ + /* driveEnv = (struct DosEnvec *) + BADDR(((struct FileSysStartupMsg *) + BADDR(dosList->dol_misc.dol_handler.dol_Startup))->fssm_Environ);*/ + + d1(KPrintF("%s/%s/%ld: dol_Name=<%s>\n", __FILE__, __FUNC__, __LINE__, name)); + + // If the volume lock is NULL, the 'dev' is assumed to be the + // name of a device holding an unformatted disk, so compare the + // name to the name of the current node + + if (volumeLock == (BPTR)NULL) + { + stat = (Stricmp(dev, name) == 0); + d1(KPrintF("%s/%s/%ld: stat=%ld dev=%s name=%s\n", __FILE__, __FUNC__, __LINE__, stat, dev,name)); + } + else + { + // Otherwise, since 'dev' could hold a volume rather than + // device name, get a lock on it and compare it to the lock + // on the device that was given; if they're the same, we've + // found the drive + BPTR tempLock; + + tempLock = Lock(name, ACCESS_READ); + debugLock_d1(tempLock); + if (tempLock) + { + ULONG same; + + same = SameLock(tempLock,volumeLock); + d1(KPrintF("%s/%s/%ld: same=%ld\n", __FILE__, __FUNC__, __LINE__, same)); + stat = LOCK_SAME == same || LOCK_SAME_VOLUME == same; + UnLock(tempLock); + } + } + + /*If weve found the drive, get the information on it*/ + if (stat) + { + // Get a pointer to the structure that holds the needed info + struct FileSysStartupMsg *startup; + struct DosEnvec *driveEnv; + + startup = (struct FileSysStartupMsg *) BADDR(dosList->dol_misc.dol_handler.dol_Startup); + driveEnv = (struct DosEnvec *) BADDR(startup->fssm_Environ); + + // Get the information + layout->unit = startup->fssm_Unit; + + // Copy the device name to layout->devName + BtoCString(startup->fssm_Device, layout->devName, sizeof(layout->devName) - 1); + d1(KPrintF("%s/%s/%ld: layout->devName=%s\n", __FILE__, __FUNC__, __LINE__, layout->devName)); + + if (strlen(NameOfDevice) > 0) + { + d1(KPrintF("%s/%s/%ld: ** OK ** NameOfDevice lenght > 0 Len=[%ld]\n", __FILE__, __FUNC__, __LINE__, strlen(NameOfDevice))); + + strcpy(layout->devName, NameOfDevice); + + d1(KPrintF("%s/%s/%ld: ** SO ** layout.devName = NameofDevice=<%s>\n", __FILE__, __FUNC__, __LINE__, layout->devName)); + } + else + NameOfDevice = layout->devName; + + d1(KPrintF("%s/%s/%ld: NameOfDevice=<%s> layout->devName=<%s>\n", __FILE__, __FUNC__, __LINE__, NameOfDevice, layout->devName)); + + + layout->flags = startup->fssm_Flags; + layout->memType = driveEnv->de_BufMemType; + layout->lowCyl = driveEnv->de_LowCyl; + layout->highCyl = driveEnv->de_HighCyl; + layout->surfaces = driveEnv->de_Surfaces; + layout->BPT = driveEnv->de_BlocksPerTrack; + layout->blockSize = driveEnv->de_SizeBlock; + +//--------------------------------------------------------------------------------------------------------------------------------- + TextHighCyl = layout->highCyl; + TextLayoutBPT = layout->BPT; + + + // Copy the device name back to 'dev' + strcpy(dev,name); + + d1(KPrintF("%s/%s/%ld: FOUBND dev=<%s> name=<%s> flags=%lx memType=%lx lowCyl=%ld highCyl=%ld surfaces=%ld BlocksPerTrack=%ld blockSize=%ld TAILLE: [ %ld ]\n", + __FILE__, __FUNC__, __LINE__, dev, name, layout->flags, layout->memType, layout->lowCyl, layout->highCyl, + layout->surfaces, layout->BPT, layout->blockSize, ((layout->highCyl + 1) * layout->BPT) )); + +//-------------------------------------------------------------------------------------------------------------------------------------- + + Found = TRUE; + } + } + } + + d1(KPrintF("%s/%s/%ld: Found=%ld\n", __FILE__, __FUNC__, __LINE__, Found)); + + // We didnt find the drive in the list, so unlock the list + UnLockDosList(LDF_DEVICES|LDF_READ); + + // Restore the requester pointer + process->pr_WindowPtr = oldWdw; + + // And return + return Found; + } + +//----------------------------------------------------------------------------- + +// Create a communications port linking this process to the drive +struct IOExtTD *OpenDrive(char *driveDevName,ULONG unit,ULONG flags) + { + struct MsgPort *diskPort; + struct IOExtTD *diskRequest; + + // Create the message port + if ((diskPort = CreateMsgPort()) != NULL) + { + // Create the IORequest + diskRequest = (struct IOExtTD *) + CreateIORequest(diskPort,sizeof(struct IOExtTD)); + if(diskRequest != NULL) + { + // Open the device, and return the IORequest if the device + // opened successfully + + d1(KPrintF("%s/%s/%ld: driveDevName=<%s> unit=[%ld]\n", __FILE__, __FUNC__, __LINE__, driveDevName, unit)); + + if(!OpenDevice(driveDevName,unit,(struct IORequest *)diskRequest,flags)) + return(diskRequest); + + // The device didnt open, so clean up + DeleteIORequest((struct IORequest *)diskRequest); + } + + DeleteMsgPort(diskPort); + } + + // Return NULL to indicate that an error occurred + return(NULL); + } + +//----------------------------------------------------------------------------- + +// Close an open device and delete the accompanying port, etc. +void CloseDrive(struct IOExtTD *diskRequest) + { + CloseDevice((struct IORequest *)diskRequest); + DeleteMsgPort(diskRequest->iotd_Req.io_Message.mn_ReplyPort); + DeleteIORequest((struct IORequest *)diskRequest); + } + +//----------------------------------------------------------------------------- + +// Convert a CSTR to a BSTR +BSTR makeBSTR(CONST_STRPTR in, char *out) +{ + int c; + + out[0] = strlen(in); + for(c = 0; c < out[0]; c++) + out[c+1] = in[c]; + + return MKBADDR(out); +} + + +//----------------------------------------------------------------------------- + +// Convert a BSTR to a CSTR + +STRPTR BtoCString(BPTR bString, STRPTR Buffer, size_t MaxLen) +{ +#ifdef __AROS__ + // AROS needs special handling because it uses NULL-terminated + // strings on some platforms. + size_t Len = AROS_BSTR_strlen(bString); + if (Len >= MaxLen) + Len = MaxLen - 1; + strncpy(Buffer, AROS_BSTR_ADDR(bString), Len); + Buffer[Len] = '\0'; + + return Buffer; +#else + UBYTE *bStringAddr = BADDR(bString); + size_t Length = bStringAddr[0]; + + if (Length >= MaxLen) + Length = MaxLen - 1; + + memcpy(Buffer, bStringAddr + 1, Length); + Buffer[Length] = '\0'; + + return Buffer; +#endif +} + +//----------------------------------------------------------------------------- + diff --git a/scalos/Modules/FormatDisk.Gadtools/Format.c b/scalos/Modules/FormatDisk.Gadtools/Format.c new file mode 100644 index 000000000..e8d9f5645 --- /dev/null +++ b/scalos/Modules/FormatDisk.Gadtools/Format.c @@ -0,0 +1,1533 @@ +// Format.c +// $Date$ +// $Revision$ + + +/************************************************************************************************/ +/* Format64 */ +/* Version 1.05 */ +/* */ +/* This is a replacement for the AmigaDOS "Format" command. It sports */ +/* (for the Workbench user) more friendly user-interface, although it is */ +/* virtually identical to the standard Format command where the CLI */ +/* interface is concerned. */ +/* */ +/* NewFormat v1.00 is Copyright 1992 by Dave Schreiber, All Rights Reserved. */ +/* Format64 v1.00 is Copyright 1998 by Jarkko Vatjus-Anttila */ +/* This program may not be sold for more than a small copying and shipping */ +/* and handling fee, except by written permission of Dave Schreiber. */ +/* */ +/* Version list: */ +/* 1.00 - First release (August 31, 1992) */ +/* 1.00 - Update to 64 bit command set. Support for disks >4GB */ +/* 1.01 - Small bug fixes. Made the program to use ANSI C functions. */ +/* */ +/* 1.05 (jmc) */ +/* - Bug fix: Some drives weren't initialized. */ +/* - Bug fix: Some devices weren't open. */ +/* - GUI.c Improvemnts : Added "DirCache", "Trashcan" */ +/* field gadgets, replaced, "Quick Format" chekbox */ +/* gadget by a button gadget. */ +/* Added messages string informations about Drive, Volume, */ +/* if drive support NSD or not. */ +/* - Added: "FindFileSysResEntry()" from information.module. */ +/* */ +/************************************************************************************************/ + + +//------------------------------------------- +//--------------- MEMO ------------- +//------------------------------------------- +// UNREADABLE_DISK 42414400 BAD\0 +// DOS_DISK 444F5300 DOS\0 +// FFS_DISK 444F5301 DOS\1 +// INTER_DOS_DISK 444F5302 DOS\2 +// INTER_FFS_DISK 444F5303 DOS\3 +// FASTDIR_DOS_DISK 444F5304 DOS\4 +// FASTDIR_FFS_DISK 444F5305 DOS\5 +// NOT_REALLY_DOS 4E444F53 NDOS +// KICKSTART_DISK 4B49434B KICK +// MSDOS_DISK 4d534400 MSD\0 +//------------------------------------------- +//------------------------------------------- + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include // +jmc+ + +#include "Format.h" +#include "GUI.h" + +#include +#include +#include "Format_disk_rev.h" + + + +#include +#define FormatDisk_NUMBERS +#define FormatDisk_ARRAY +#define FormatDisk_CODE +#include STR(SCALOSLOCALE) + +#include +#include +//----------------------------------------------------------------------------- + +BOOL QuickFmt=FALSE; +BOOL Verify=TRUE; +BOOL Icon=FALSE; +BOOL FFS; +BOOL intl; +BOOL DirCache; // +jmc+ +BPTR StdErr = (BPTR)NULL; +BOOL fromcli; + +//----------------------------------------------------------------------------- + +LONG args[7] = { 0,0,0,0,0,0,0 }; + +extern Rect box; + +//----------------------------------------------------------------------------- + +char *Version = VERSTAG COPYRIGHT; +char temp[32]; +char volumeName[256]; +extern char deviceName[64]; +extern char NewVolumeName[]; +char DosTypeString[16]; +STRPTR ShortDostype=""; + +//----------------------------------------------------------------------------- + +static void BtoCstring(BSTR bstr, STRPTR Buffer, size_t BuffLen); +static UBYTE MakePrintable(UBYTE ch); +static void GetDeviceName(BPTR dLock, STRPTR DeviceName, size_t MaxLen); +static const struct FileSysEntry *FindFileSysResEntry(ULONG DosType); +static CONST_STRPTR FindVersionString(const UBYTE *block, size_t BlockLen); + +const char versTag[] = VERSTAG; // $VER version string + +static char TextDeviceName[128]; +static char TextDeviceOnDev[64]; +static char TextDeviceHandler[128]; + +static ULONG TypeNewDostype; +BOOL FastFSType; + +//----------------------------------------------------------------------------- + +#if !defined(__amigaos4__) && !defined(__AROS__) +#include + +long _stack = 16384; // stack size. +#endif + +struct IntuitionBase *IntuitionBase; +struct GfxBase *GfxBase; +struct Library *GadToolsBase, *IconBase, *DiskfontBase; +#ifndef __amigaos4__ +T_UTILITYBASE UtilityBase; +#endif +T_LOCALEBASE LocaleBase = NULL; + +#ifdef __amigaos4__ +struct IntuitionIFace *IIntuition; +struct GraphicsIFace *IGraphics; +struct GadToolsIFace *IGadTools; +struct IconIFace *IIcon; +struct LocaleIFace *ILocale; +struct DiskfontIFace *IDiskfont; +#endif + +//----------------------------------------------------------------------------- + +static struct Locale *FormatDiskLocale; +static struct Catalog *FormatDiskCatalog; + +struct FormatDateHookData + { + STRPTR fdhd_Buffer; // buffer to write characters to + size_t fdhd_Length; // length of buffer + }; + +static STRPTR ScaFormatString(CONST_STRPTR FormatString, STRPTR Buffer, size_t MaxLen, LONG NumArgs, ...); + +static M68KFUNC_P3_PROTO(void, FormatDateHookFunc, + A0, struct Hook *, theHook, + A2, struct Locale *, locale, + A1, char, ch); + +static void ByteCount(STRPTR Buffer, size_t BuffLen, LONG NumBlocks, LONG BytesPerBlock); +static char TextDeviceUsed[128]; +static char TextDeviceFree[128]; +static char TextDeviceSize[128]; +static char DeviceBlockSize[128]; + +static char BufferRequest[512]=""; + +//static char DeviceState[128]; + +extern LONG TextHighCyl; +extern LONG TextLayoutBPT; +LONG TestCapacity = 0; + +//----------------------------------------------------------------------------- + +BOOL checkfor64bitcommandset(struct IOStdReq *io); + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + + +int main(int argc, char *argv[]) +{ + UWORD disk; + ULONG i; + char statusString[80], driveName[64]; + char newName[108]; + char TrashName[108] = ""; + BPTR driveLock; + struct Process *process; + APTR oldWdw; + DriveLayout junk; + prepResult stat=eCancel; // +jmc+ + int SetFFS; + int SetIntl; + int SetDirCache; // +jmc + struct FormatSettings Parms; + struct WBStartup *WBenchMsg = (struct WBStartup *)argv; + + + memset(&Parms, 0, sizeof(Parms)); + Parms.newName = newName; + Parms.TrashName = TrashName; + Parms.ffs = ID_DOS_DISK; + + // Open the various shared libraries that are needed + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",39); + GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 39); + IconBase = (struct Library *) OpenLibrary("icon.library", 39); + GadToolsBase = (struct Library *) OpenLibrary("gadtools.library",39); +#ifndef __amigaos4__ + UtilityBase = (T_UTILITYBASE) OpenLibrary("utility.library", 39); +#endif + DiskfontBase = (struct Library *) OpenLibrary("diskfont.library", 39); + + LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 39); + + if (IntuitionBase==NULL || GfxBase==NULL || IconBase==NULL || GadToolsBase==NULL + || DiskfontBase==NULL +#ifndef __amigaos4__ + || UtilityBase==NULL +#endif + ) + cleanup(100); + +#ifdef __amigaos4__ + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + IGraphics = (struct GraphicsIFace *)GetInterface((struct Library *)GfxBase, "main", 1, NULL); + IIcon = (struct IconIFace *)GetInterface((struct Library *)IconBase, "main", 1, NULL); + IGadTools = (struct GadToolsIFace *)GetInterface((struct Library *)GadToolsBase, "main", 1, NULL); + IDiskfont = (struct DiskfontIFace *)GetInterface((struct Library *)DiskfontBase, "main", 1, NULL); + if (LocaleBase) + ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL); + + if (IIntuition==NULL || IGraphics==NULL || IIcon==NULL || IGadTools==NULL + || IDiskfont==NULL + ) + cleanup(100); +#endif + + if (LocaleBase) + { + FormatDiskLocale = OpenLocale(NULL); + FormatDiskCatalog = OpenCatalogA(NULL, "Scalos/FormatDisk.catalog", NULL); + } + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + fromcli = argc != 0; + + if (!fromcli) + { + if (WBenchMsg->sm_NumArgs==1) + { + printError("Please select a drive to format and try again!",NULL,NULL); + cleanup(100); + } + + TypeNewDostype = 0UL; + FastFSType = TRUE; + strcpy(TextDeviceSize,""); + + // From GUI.c + SetupScreen(); + + for (disk = 1; disk < WBenchMsg->sm_NumArgs && stat != eQuit; disk++) + { + STRPTR LockStr; + + // Get the volume/device name of the disk to format + getVolumeName(volumeName,WBenchMsg->sm_ArgList,disk); + + // If there is no lock to the volume, that means it is + // unformatted, so just use the name given to us by Workbench + if (WBenchMsg->sm_ArgList[disk].wa_Lock==(BPTR)NULL) + { + strcpy(volumeName,WBenchMsg->sm_ArgList[disk].wa_Name); + + d1(KPrintF("%s/%s/%ld: * GET *** volumeToDevName(%lx,%s,%lx)\n", __FILE__, __FUNC__, __LINE__, WBenchMsg->sm_ArgList[disk].wa_Lock,volumeName,&junk)); + + volumeToDevName(WBenchMsg->sm_ArgList[disk].wa_Lock, volumeName, &junk); + + d1(KPrintF("%s/%s/%ld: LOCK=NULL volumeName: Device Name=<%s>\n", __FILE__, __FUNC__, __LINE__, volumeName)); + d1(KPrintF("%s/%s/%ld: LOCK=NULL volumeName:junk.devName=<%s> junk.unit=[%ld]\n", __FILE__, __FUNC__, __LINE__, junk.devName, junk.unit)); + + } + else + { + if ((LockStr = (STRPTR)AllocVec(256,0)) != NULL) + { + size_t len; + + NameFromLock(WBenchMsg->sm_ArgList[disk].wa_Lock, (STRPTR)LockStr, 256); + + if (WBenchMsg->sm_ArgList[disk].wa_Name && strlen(WBenchMsg->sm_ArgList[disk].wa_Name) > 0) + AddPart(LockStr, WBenchMsg->sm_ArgList[disk].wa_Name, 256); + + len=strlen(LockStr); + + if(len) + { + if(LockStr[len-1] != ':') + { + d1(KPrintF("%s/%s/%ld: Wrong type!!! len = %ld= %s\n", __FILE__, __FUNC__, __LINE__, len, LockStr)); + + printError((STRPTR) GetLocString(MSGID_OBJECT), FilePart(LockStr), (STRPTR) GetLocString(MSGID_IS_WRONG_TYPE)); + return ERROR_OBJECT_WRONG_TYPE; + } + else + { + if (!volumeToDevName(WBenchMsg->sm_ArgList[disk].wa_Lock,deviceName,&junk)) + { + printError((STRPTR) GetLocString(MSGID_DRIVE_NOFOUND),(STRPTR) GetLocString(MSGID_VOLUME_SELECTED), LockStr); + d1(KPrintF("%s/%s/%ld: Can't find the drive for %s\n", __FILE__, __FUNC__, __LINE__, LockStr)); + return RETURN_WARN; + } + } + } + FreeVec(LockStr); + } + + d1(KPrintF("%s/%s/%ld: LOCK=OK BUFFER deviceName: Device Name=<%s>\n", __FILE__, __FUNC__, __LINE__, deviceName)); + d1(KPrintF("%s/%s/%ld: LOCK=OK BUFFER deviceName:junk.devName=<%s> junk.unit=[%ld]\n", __FILE__, __FUNC__, __LINE__, junk.devName, junk.unit)); + + } + + GetDeviceName(WBenchMsg->sm_ArgList[disk].wa_Lock, deviceName, strlen(deviceName)); // +jmc+ + + d1(KPrintF("%s/%s/%ld: ** FIRST CHECK DOS TYPE TO USE: TypeNewDostype=[%lx] **\n", __FILE__, __FUNC__, __LINE__, TypeNewDostype)); + +//----------------------------------------------------------------------------- + + if ((TypeNewDostype == ID_FFS_DISK) || (TypeNewDostype == ID_FASTDIR_FFS_DISK)) // 444F5301 [DOS\1] or 444F5305 [DOS\5] or 444F5300 [DOS\0]. + { + FFS = TRUE; + SetFFS = 1; + } + else + { + FFS = FALSE; + SetFFS = 0; + } + + if ((TypeNewDostype == ID_INTER_FFS_DISK) || (TypeNewDostype == ID_INTER_DOS_DISK)) // 444F5303 [DOS\3] or 444F5302 [DOS\2]. + { + intl = TRUE; + SetIntl = 1; + } + else + { + intl = FALSE; + SetIntl = 0; + } + + + if ((TypeNewDostype == ID_FASTDIR_FFS_DISK) || (TypeNewDostype == ID_FASTDIR_DOS_DISK)) // 444F5305 [DOS\5] or 444F5304 [DOS\4]. + { + DirCache = TRUE; + SetDirCache = 1; + } + else + { + DirCache = FALSE; + SetDirCache = 0; + } + + d1(KPrintF("%s/%s/%ld: ** FIRST CHECK FFS: FFS=[%ld] **\n", __FILE__, __FUNC__, __LINE__, FFS)); + + if (FFS == TRUE) + { + if (DirCache == TRUE) + Parms.ffs = ID_FASTDIR_FFS_DISK; + else if (intl == TRUE) + Parms.ffs = ID_INTER_FFS_DISK; + else + Parms.ffs = ID_FFS_DISK; + } + else + { + if (DirCache == TRUE) + Parms.ffs = ID_FASTDIR_DOS_DISK; + else if (intl == TRUE) + Parms.ffs = ID_INTER_DOS_DISK; + else + Parms.ffs = ID_DOS_DISK; + SetFFS = 1; // Here: Force enabling of FFS gadget in all case. + } + + + if ( (strlen(NameOfDevice) > 0) && (0 == (stricmp(NameOfDevice, "mfm.device"))) ) + { + TypeNewDostype = ID_MSDOS_DISK; + d1(KPrintF("%s/%s/%ld: FOUND MSDOS drive Dostype = ««%lx»»\n", __FILE__, __FUNC__, __LINE__, TypeNewDostype)); + } + + + d1(KPrintF("%s/%s/%ld: ** SECOND CHECK FFS: FFS=[%ld] INTL = %ld DIRCACHE = %ld Parms.ffs=$%lx\n", __FILE__, __FUNC__, __LINE__, FFS, intl, DirCache, Parms.ffs)); + + if ( (0UL != TypeNewDostype) && (Parms.ffs != TypeNewDostype) ) + { + FFS = FALSE; + Parms.ffs = TypeNewDostype; + FastFSType = FALSE; + SetFFS = 0; // [ FFS = FALSE ] and [ Parms.ffs = TypeNewDostype ] SO Disable FFS gadget. + } + +//---------------------------------------------------------------------------- + + sprintf(DosTypeString, "%c%c%c%c", + MakePrintable((Parms.ffs >> 24) & 0xff), + MakePrintable((Parms.ffs >> 16) & 0xff), + MakePrintable((Parms.ffs >> 8) & 0xff), + MakePrintable(Parms.ffs & 0xff)); + + ShortDostype = DosTypeString; + + d1(KPrintF("%s/%s/%ld: ** THIRD CHECK FFS: FFS=[%ld] INTL = %ld DIRCACHE = %ld Parms.ffs=$%lx ShortDostype=[%s]\n", __FILE__, __FUNC__, __LINE__, FFS, intl, DirCache, Parms.ffs, ShortDostype)); + +//----------------------------------------------------------------------------- + + + // Open the options window: from GUI.c + if ((stat=OpenPrepWindow(volumeName, SetFFS, SetIntl, SetDirCache))==0) + { + if (SetFFS) + FFS = TRUE; // NOTE: Initialize FFS value for message class according to SetFFS value, before getPrepInput() call. + + // Get the users input: from GetInputFromWindow.c + stat=getPrepInput(); + + Parms.icon = Icon; + + d1(KPrintF("%s/%s/%ld: [] PASS1: RETURNED FROM GUI: FFS = %ld INTL = %ld DIRCACHE = %ld Parms.ffs=««%lx»»\n", __FILE__, __FUNC__, __LINE__, FFS, intl, DirCache, Parms.ffs)); + + d1(KPrintF("%s/%s/%ld: Parms.ffs= ««%lx»» FastFSType=%ld\n", __FILE__, __FUNC__, __LINE__, Parms.ffs, FastFSType)); + + if (FastFSType) + { + if (FFS == TRUE) + { + if (DirCache == TRUE) + Parms.ffs = ID_FASTDIR_FFS_DISK; + else if (intl == TRUE) + Parms.ffs = ID_INTER_FFS_DISK; + else + Parms.ffs = ID_FFS_DISK; + } + else + { + if (DirCache == TRUE) + Parms.ffs = ID_FASTDIR_DOS_DISK; + else if (intl == TRUE) + Parms.ffs = ID_INTER_DOS_DISK; + else + Parms.ffs = ID_DOS_DISK; + } + } + + d1(KPrintF("%s/%s/%ld: [] PASS2: RETURNED FROM GUI: FFS = %ld INTL = %ld DIRCACHE = %ld Parms.ffs=««%lx»»\n", __FILE__, __FUNC__, __LINE__, FFS, intl, DirCache, Parms.ffs)); + + + sprintf(DosTypeString, "%c%c%c%c", + MakePrintable((Parms.ffs >> 24) & 0xff), + MakePrintable((Parms.ffs >> 16) & 0xff), + MakePrintable((Parms.ffs >> 8) & 0xff), + MakePrintable(Parms.ffs & 0xff)); + + ShortDostype = DosTypeString; + + d1(KPrintF("%s/%s/%ld: [] PASS2: ShortDostype = %s Parms.ffs=««%lx»»\n", __FILE__, __FUNC__, __LINE__, ShortDostype, Parms.ffs)); + + + // And close the window: from GUI.c + ClosePrepWindow(); + + if (stat == eQuick) + { + Parms.quick = TRUE; + Parms.verify = FALSE; + } + + // If the user selected 'OK' + // +jmc+: "eQuick" added to "enum prepResult" in Format.h, + // this is the QuickFormat option replacement pessing a button (GD_QuickFmtGadget) from GUI.c. + // "eQuick" class mesage type is checked from GetInputFromWindow.c with all other gadgets. + if ((stat == eOK) || (stat == eQuick)) + { + // Get the new name of the disk + strcpy(newName,((struct StringInfo *) + (PrepGadgets[GD_NameGadget]->SpecialInfo))->Buffer); + + // Get the name of trashcan. + if (Parms.icon) + { + strcpy(TrashName, ((struct StringInfo *) + (PrepGadgets[GD_TrashCanNameGadget]->SpecialInfo))->Buffer); + } + + d1(KPrintF("%s/%s/%ld: get from string gadget: newName=<%s>\n", __FILE__, __FUNC__, __LINE__, newName)); + + strcpy(NewVolumeName,newName); + strcpy(deviceName,volumeName); + +//----------------------------------------------------------------------------------------------- + + if (strlen(BufferRequest) == 0) + { + TestCapacity = (TextHighCyl + 1) * TextLayoutBPT; + + if (TestCapacity > 2 * 1000000) + { + sprintf(BufferRequest, GetLocString(MSGID_DEVICE_SHORTSIZE), ((TestCapacity/1000)/1000)); + strcat(BufferRequest, " Gb"); + } + else + { + sprintf(BufferRequest, GetLocString(MSGID_DEVICE_SHORTSIZE), TestCapacity); + strcat(BufferRequest, " Kb"); + } + } + +//----------------------------------------------------------------------------------------------- + + // Ask the user for verification + if (askAreYouSure(volumeName, (WBenchMsg->sm_ArgList[disk].wa_Lock!=(BPTR)NULL), BufferRequest)) + { + struct IOExtTD *io1; + DriveLayout layout; + struct MsgPort *devPort; + BOOL writeProtCont=TRUE; + + + // If the volume lock is NULL, assume that the volumeName string holds + // a valid device pointer + if (WBenchMsg->sm_ArgList[disk].wa_Lock==(BPTR)NULL) + { + strcpy(deviceName,volumeName); + d1(KPrintF("%s/%s/%ld: deviceName=<%s>\n", __FILE__, __FUNC__, __LINE__, deviceName)); + } + + // Get the drive name (if possible) + d1(KPrintF("%s/%s/%ld: * GET *** volumeToDevName(%lx,%s,%lx)\n", __FILE__, __FUNC__, __LINE__, WBenchMsg->sm_ArgList[disk].wa_Lock,volumeName,&layout)); + + if (!volumeToDevName(WBenchMsg->sm_ArgList[disk].wa_Lock,deviceName,&layout)) + { + printError((STRPTR) GetLocString(MSGID_DRIVE_NOFOUND), (STRPTR) GetLocString(MSGID_VOLUME_SELECTED), deviceName); + d1(KPrintF("%s/%s/%ld: Can't find the drive for %s\n", __FILE__, __FUNC__, __LINE__, deviceName)); + return RETURN_WARN; + } + + d1(KPrintF("%s/%s/%ld: DriveName=<%s>\n", __FILE__, __FUNC__, __LINE__, deviceName)); + + // This port will be used to communicate with the filesystem + devPort=DeviceProc(deviceName); + if (devPort==NULL) + { + printError((STRPTR) GetLocString(MSGID_DRIVE_NOFOUND), (STRPTR) GetLocString(MSGID_VOLUME_SELECTED), deviceName); + d1(KPrintF("%s/%s/%ld: Can't find the drive for %s\n", __FILE__, __FUNC__, __LINE__, deviceName)); + return RETURN_WARN; + } + + // Open the disk device + d1(KPrintF("%s/%s/%ld: * CALL *** OpenDrive(%s,%ld,%lx)\n", __FILE__, __FUNC__, __LINE__, layout.devName,layout.unit,layout.flags)); + + if ((io1=OpenDrive(layout.devName,layout.unit,layout.flags))!=NULL) + { + // Determine the write protect status + io1->iotd_Req.io_Data=NULL; + io1->iotd_Req.io_Length=0; + io1->iotd_Req.io_Command=TD_PROTSTATUS; + DoIO((struct IORequest *)io1); + + d1(KPrintF("%s/%s/%ld: layout.devName=<%s> layout.unit=[%ld]\n", __FILE__, __FUNC__, __LINE__, layout.devName, layout.unit)); + + // Loop while the disk stays protected and user keeps pressing Retry + while (io1->iotd_Req.io_Actual!=0 && (writeProtCont=alertIsWriteProtected(volumeName))) + DoIO((struct IORequest *)io1); + + // If the disk is not write-protected + if (writeProtCont) + { + // Do a full format if the user did not select the Quick option, + // checkfor64bitcommandset(): from NSD_64bit.c + if (checkfor64bitcommandset((struct IOStdReq *)io1) == TRUE) + { + // BOOL NsdSupport used for "StatusIText" message (yes or not drive support NSD 64bit support), + // result inserted to "StatusTextNSDSupport" string buffer. + // See StatusRender() from GUI.c + NsdSupport=TRUE; + if (WBenchMsg == NULL) + printf("***Device %s supports 64bit commands! No size limit!!\n", deviceName); + } + else + { + if (WBenchMsg == NULL) + printf("***Device %s does NOT support 64bit commands. 4GB limit activated!!\n", deviceName); + } + } + CloseDrive(io1); + } + // Disk device closed + + d1(KPrintF("%s/%s/%ld: FROM WB FIRST CHECK: TypeNewDostype ?? = $%lx \n", __FILE__, __FUNC__, __LINE__, ffs)); + + // If everythings OK, open the status window + if ((stat=OpenStatusWindow(statusString))==0) + { + + d1(KPrintF("%s/%s/%ld: FROM WB PASS2: FFS=%ld INTL=%ld Dostype to use: ffs=$%lx QuickFormat=%ld Parms.verify=%ld CreateIcon=%ld\n", \ + __FILE__, __FUNC__, __LINE__, FFS, intl, ffs, Parms.quick, Parms.verify, Parms.icon)); + + // And format the disk + formatVolume(&(WBenchMsg->sm_ArgList[disk].wa_Lock), volumeName, &Parms, statusString); + + // Were done, so close the status window + CloseStatusWindow(); + } + } + } + } + } + // Free the visual info, etc. + CloseDownScreen(); + } + + else // Weve been run from the CLI -- UNFINISHED !!! + + { + // Open a 'stderr' I/O channel to the shell + // (the normal stderr was not opened since we used _main() ) + StdErr=Open("CONSOLE:",MODE_OLDFILE); + + // Make sure requestors dont open + process=(struct Process *)FindTask(0L); + oldWdw=process->pr_WindowPtr; + process->pr_WindowPtr=(APTR)(-1); + + // Get the command-line arguments + parseArgs(driveName,volumeName, &FFS, &intl, &Parms.icon, TrashName, &Parms.quick, &Parms.verify); + + for (i=0; ipr_WindowPtr = oldWdw; + + Write(Output(),"\n",1); + } + + cleanup(0); + + return(0); +} + +//---------------------------------------------------------------------------- + +CONST_STRPTR GetLocString(ULONG MsgId) +{ + struct FormatDisk_LocaleInfo li; + + li.li_Catalog = FormatDiskCatalog; +#ifndef __amigaos4__ + li.li_LocaleBase = LocaleBase; +#else + li.li_ILocale = ILocale; +#endif + + return GetFormatDiskString(&li, MsgId); +} + +//----------------------------------------------------------------------------- +// Ask the user if she really wants to format the disk +BOOL askAreYouSure(char *volumeName,BOOL truncColon, char *DeviceSize) +{ + char name[36]; + APTR args[3]; + UBYTE result; + struct EasyStruct ez; + + // Get the device name + strcpy(name,volumeName); + + // Truncate the trailing colon if so specified + if (truncColon) + name[strlen(name)-1]='\0'; + + // Setup the device name as the argument to the requestor + args[0]=name; + args[1]=DeviceSize; + args[2]=NULL; + + + ez.es_StructSize = sizeof(ez); + ez.es_Flags = 0; + ez.es_Title = (STRPTR) GetLocString(MSGID_REQ_SURE_TITLE); + ez.es_TextFormat = (STRPTR) GetLocString(MSGID_REQ_SURE_BODY); + ez.es_GadgetFormat = (STRPTR) GetLocString(MSGID_REQ_SURE_GADGETS); + + // (+jmc+) Open the request + result=EasyRequestArgs(NULL, &ez, NULL, args); + + // return(result==1); // + return(result); // +jmc+ +} + +//----------------------------------------------------------------------------- +// Print one, two, or three lines of error messages in an EasyRequestor +// or to 'StdErr' +void printError(CONST_STRPTR first, CONST_STRPTR second, CONST_STRPTR third) +{ + static const char *oneLine="%s"; + static const char *twoLine="%s\n%s"; + static const char *threeLine="%s\n%s\n%s"; + struct EasyStruct errorReq; + APTR args[4]; + args[0] = args[3] = NULL; + + errorReq.es_StructSize = sizeof(errorReq); + errorReq.es_Flags = 0; + errorReq.es_Title = (STRPTR) GetLocString(MSGID_REQ_SURE_TITLE); + errorReq.es_TextFormat = NULL; + errorReq.es_GadgetFormat = (STRPTR) GetLocString(MSGID_GADGET_OK); + + // If we're running from the CLI + if (fromcli) + { + // And a StdErr handle was opened successfully + if (StdErr!=(BPTR)NULL) + { + char LF=0x0A; + + // Print the first line + if (first != NULL) + { + Write(StdErr, (STRPTR) first, strlen(first)); + Write(StdErr," ",1); + } + + // Print the second line + if (second != NULL) + { + Write(StdErr, (STRPTR) second, strlen(second)); + Write(StdErr," ",1); + } + + // Print the third line + if (third != NULL) + { + Write(StdErr, (STRPTR) third, strlen(third)); + Write(StdErr, " ", 1); + } + + // Print the terminating carriage return + Write(StdErr,&LF,1); + } + } + else // Otherwise, we're running from Workbench, so put up the requestor + { + // Three lines + if (third != NULL) + { + args[2] = (APTR) third; + args[1] = (APTR) second; + args[0] = (APTR) first; + errorReq.es_TextFormat = (STRPTR) threeLine; + } + else if (second != NULL) // Two lines + { + args[1] = (APTR) second; + args[0] = (APTR) first; + errorReq.es_TextFormat = (STRPTR) twoLine; + } + else if (first != NULL) // One line + { + args[0] = (APTR) first; + errorReq.es_TextFormat = (STRPTR) oneLine; + } + // Put up the requestor + EasyRequestArgs(NULL,&errorReq,NULL,args); + } + return; +} + +//----------------------------------------------------------------------------- +// Get the name of a volume, given a lock to that volume +void getVolumeName(char *name,struct WBArg *argList,UWORD disk) +{ + // Get the name + if (NameFromLock(argList[disk].wa_Lock,name,256) == DOSFALSE) + // Or return if the name couldn't be determined + strcpy(name,""); + return; +} + +//----------------------------------------------------------------------------- +// Alert the user to the fact that the disk is write protected, and give +// the user a chance to unprotect the disk +BOOL alertIsWriteProtected(CONST_STRPTR devName) +{ + struct EasyStruct writeProtected; + APTR args[2]; + BYTE result; + + // Setup the device name as the argument to the requestor + args[0] = (APTR) devName; + args[1] = NULL; + + writeProtected.es_StructSize = sizeof(writeProtected); + writeProtected.es_Flags = 0; + writeProtected.es_Title = (STRPTR) GetLocString(MSGID_REQ_SURE_TITLE); + writeProtected.es_TextFormat = (STRPTR) GetLocString(MSGID_VOLUME_PROTECTED); + writeProtected.es_GadgetFormat = (STRPTR) GetLocString(MSGID_REQ_RETRY_CANCEL); + + // (+jmc+) Open the request + result=EasyRequestArgs(NULL, &writeProtected, NULL, args); + + // return(result==1); // + return(result); // +jmc+ +} + +//----------------------------------------------------------------------------- +// Exit from the program, closing any open libraries +void cleanup(ULONG err) +{ +#ifdef __amigaos4__ + if (IDiskfont) + DropInterface((struct Interface *)IDiskfont); +#endif + if (DiskfontBase) + CloseLibrary((struct Library *) DiskfontBase); + +#ifndef __amigaos4__ + if (UtilityBase) + CloseLibrary((struct Library *) UtilityBase); +#endif + +#ifdef __amigaos4__ + if (IIntuition) + DropInterface((struct Interface *)IIntuition); +#endif + if (IntuitionBase!=NULL) + CloseLibrary((struct Library *)IntuitionBase); + +#ifdef __amigaos4__ + if (IGraphics) + DropInterface((struct Interface *)IGraphics); +#endif + if (GfxBase!=NULL) + CloseLibrary((struct Library *)GfxBase); + +#ifdef __amigaos4__ + if (IGadTools) + DropInterface((struct Interface *)IGadTools); +#endif + if (GadToolsBase!=NULL) + CloseLibrary(GadToolsBase); + +#ifdef __amigaos4__ + if (IIcon) + DropInterface((struct Interface *)IIcon); +#endif + if (IconBase!=NULL) + CloseLibrary(IconBase); + + if (LocaleBase!=NULL) + { + if (FormatDiskLocale) + { + CloseLocale(FormatDiskLocale); + FormatDiskLocale = NULL; + } + if (FormatDiskCatalog) + { + CloseCatalog(FormatDiskCatalog); + FormatDiskCatalog = NULL; + } +#ifdef __amigaos4__ + if (ILocale) + DropInterface((struct Interface *)ILocale); +#endif + CloseLibrary((struct Library *) LocaleBase); + LocaleBase = NULL; + } + + + exit(err); +} + +//----------------------------------------------------------------------------- +// Update the status window (from Workbench), or CLI output (from the CLI) +// If running from the CLI, this also checks to see if the user has pressed +// control-C +BOOL updateStatWindow(char *string,UWORD percent) +{ + UWORD width; + ULONG class1; + UWORD code; + struct TagItem tags[3]; + static char msg[80]; + char CR = 0x0d; + UWORD AbortButton_key; + + struct IntuiMessage *mesg; + + AbortButton_key = FindUnderscoredToLower((STRPTR) GetLocString(MSGID_GUI_STATUSWINDOW_ABORT)); + + // If this is NULL, were running from the CLI + if (fromcli) + { + // Write the string to the CLI, followed by a carriage return (but not a line feed) + Write(Output(),string,strlen(string)); + Write(Output(),&CR,1); + + // Check to see if the user pressed Control-C + if ( (SetSignal(0,0) & SIGBREAKF_CTRL_C) == SIGBREAKF_CTRL_C) + { + // If he did, print "***Break" and return TRUE, to signal that + // the user aborted the formatting process + Write(Output(),"\n***Break\n",10); + return(TRUE); + } + // Otherwise, continue + return(FALSE); + } + + // This code is used to update the status window that is displayed when + // the user runs NewFormat from the Workbench. + // This puts the message into the text-display gadget. + // This copy is so that the caller can change the contents of 'string' + // upon return (which can't be done without the copy, since GadTools + // wont copy the contents of string to an internal buffer). + + strcpy(msg,string); + tags[0].ti_Tag=GTTX_Text; + tags[0].ti_Data=(ULONG)msg; + + tags[1].ti_Tag=TAG_DONE; + tags[1].ti_Data=0UL; + + GT_SetGadgetAttrsA(StatusGadgets[GD_StatusGadget], StatusWnd,NULL, tags); + + // Fill the status box with the current percentage of completion + SetAPen(StatusWnd->RPort,3); + width=box.left+((box.width-3)*percent)/1000; + RectFill(StatusWnd->RPort,box.left+2,box.top+1,width,box.top+box.height-2); + + // Check user input + mesg=GT_GetIMsg(StatusWnd->UserPort); + + // Loop while there are messages + while (mesg!=NULL) + { + class1 = mesg->Class; + code = mesg->Code; + GT_ReplyIMsg(mesg); + + switch(class1) + { + // Return TRUE (user abort) if the user pressed Abort button gadget. + case IDCMP_VANILLAKEY: + if (code == AbortButton_key) return(TRUE); + break; + + // Or if the user pressed the 'Stop' gadget + case IDCMP_GADGETUP: + return(TRUE); + } + // Get the next message + mesg=GT_GetIMsg(StatusWnd->UserPort); + } + return(FALSE); + } + +//----------------------------------------------------------------------------- +//------------------- From information.module --------------------------------- +//----------------------------------------------------------------------------- + +static void BtoCstring(BSTR bstr, STRPTR Buffer, size_t BuffLen) +{ + size_t Len; + +#ifdef __AROS__ + // AROS needs special handling because it uses NULL-terminated + // strings on some platforms. + Len = AROS_BSTR_strlen(bstr); + if (Len >= BuffLen) + Len = BuffLen - 2; + strncpy(Buffer, AROS_BSTR_ADDR(bstr), Len); +#else + const char *bString = BADDR(bstr); + + *Buffer = '\0'; + + Len = *bString; + if (Len >= BuffLen) + Len = BuffLen - 2; + + strncpy(Buffer, bString + 1, Len); +#endif + Buffer[Len] = '\0'; +} + +//----------------------------------------------------------------------------- + +static UBYTE MakePrintable(UBYTE ch) +{ + if (ch < ' ') + ch += '0'; + + return ch; +} +//----------------------------------------------------------------------------- + +static void ByteCount(STRPTR Buffer, size_t BuffLen, LONG NumBlocks, LONG BytesPerBlock) +{ + CONST_STRPTR Decimal; + + if (FormatDiskLocale) + Decimal = FormatDiskLocale->loc_DecimalPoint; + else + Decimal = "."; + + // Normalize block size to KBytes + while (BytesPerBlock > 1024) + { + BytesPerBlock >>= 1; + NumBlocks <<= 1; + } + while (BytesPerBlock < 1024) + { + BytesPerBlock <<= 1; + NumBlocks >>= 1; + } + + d1(KPrintF(__FILE__ "/%s/%ld: NumBlocks=%lu\n", __FUNC__, __FILE__, __FUNC__, __LINE__, NumBlocks)); + + if (NumBlocks > 2 * 1024 * 1024) + { + // > 2 GB + ULONG GBytes = NumBlocks / (1024 * 1024); + ULONG MBytes = NumBlocks / 1024 - GBytes * 1024; + + d1(KPrintF(__FILE__ "/%s/%ld: GBytes=%lu MBytes=%lu\n", __FUNC__, __FILE__, __FUNC__, __LINE__, GBytes, MBytes)); + + if (GBytes > 200) + ScaFormatString("%lDG", Buffer, BuffLen, 1, GBytes); + else if (GBytes > 20) + ScaFormatString("%lD%s%1ldG", Buffer, BuffLen, 3, GBytes, Decimal, MBytes / 100); + else + ScaFormatString("%lD%s%-02ldG", Buffer, BuffLen, 3, GBytes, Decimal, MBytes / 10); + } + else if (NumBlocks > 2 * 1024) + { + // > 2 MB + ULONG MBytes = NumBlocks / 1024; + ULONG KBytes = NumBlocks % 1024; + + if (MBytes > 200) + ScaFormatString("%lDM", Buffer, BuffLen, 1, MBytes); + else if (MBytes > 20) + ScaFormatString("%lD%s%1ldM", Buffer, BuffLen, 3, MBytes, Decimal, KBytes / 100); + else + ScaFormatString("%lD%s%-02ldK", Buffer, BuffLen, 3, MBytes, Decimal, KBytes / 10); + } + else + { + ScaFormatString("%lDK", Buffer, BuffLen, 1, NumBlocks); + } + +} + +//----------------------------------------------------------------------------- + +static STRPTR ScaFormatString(CONST_STRPTR formatString, STRPTR Buffer, size_t MaxLen, LONG NumArgs, ...) +{ + va_list args; + + va_start(args, NumArgs); + + if (FormatDiskLocale) + { + ULONG *ArgArray; + + ArgArray = malloc(sizeof(ULONG) * NumArgs); + if (ArgArray) + { + struct FormatDateHookData fd; + struct Hook fmtHook; + ULONG n; + STATIC_PATCHFUNC(FormatDateHookFunc) + + for (n = 0; n < NumArgs; n++) + ArgArray[n] = va_arg(args, LONG); + + fmtHook.h_Entry = (HOOKFUNC) PATCH_NEWFUNC(FormatDateHookFunc); + fmtHook.h_Data = &fd; + + fd.fdhd_Buffer = Buffer; + fd.fdhd_Length = MaxLen; + + FormatString(FormatDiskLocale, (STRPTR) formatString, ArgArray, &fmtHook); + + free(ArgArray); + } + } + else + { + vsprintf(Buffer, formatString, args); + } + + va_end(args); + + return Buffer; +} + +//----------------------------------------------------------------------------- + +static M68KFUNC_P3(void, FormatDateHookFunc, + A0, struct Hook *, theHook, + A2, struct Locale *, locale, + A1, char, ch) +{ + struct FormatDateHookData *fd = (struct FormatDateHookData *) theHook->h_Data; + + (void) locale; + + if (fd->fdhd_Length >= 1) + { + *(fd->fdhd_Buffer)++ = ch; + fd->fdhd_Length--; + } +} +M68KFUNC_END + +//----------------------------------------------------------------------------- + +static void GetDeviceName(BPTR dLock, STRPTR DeviceName, size_t MaxLen) +{ + struct InfoData *info = malloc(sizeof(struct InfoData)); + + strcpy(DeviceName, ""); + if (info) + { + struct DosList *VolumeNode; + ULONG UsedPercent; + char ByteCountText[16]; + + Info(dLock, info); + + + d1(kprintf(__FILE__ "/%s/%ld: DiskType=%ld DiskState=%ld\n", __FUNC__, __FILE__, __FUNC__, __LINE__, info->id_DiskType, info->id_DiskState)); + + + + VolumeNode = (struct DosList *) BADDR(info->id_VolumeNode); + + d1(KPrintF("%s/%s/%ld: VolumeNode=%08lx Type=%08lx\n", __FILE__, __FUNC__, __LINE__, VolumeNode, VolumeNode->dol_Type)); + + if (VolumeNode) + { + //char DosTypeString[16]; + const struct FileSysEntry *fse; + char FseHandler[] = ""; + LONG FseVersion; + LONG FseRevision; + + d1(KPrintF("%s/%s/%ld: *** dol_DiskType = %lx OR VolumeNode->dol_misc.dol_volume.dol_DiskType=%lx ?? ***\n", \ + __FILE__, __FUNC__, __LINE__, VolumeNode->dol_Type, VolumeNode->dol_misc.dol_volume.dol_DiskType)); + + d1(KPrintF("%s/%s/%ld: *** GO SEARCH: FindFileSysResEntry(%lx) ***\n", \ + __FILE__, __FUNC__, __LINE__, VolumeNode->dol_misc.dol_volume.dol_DiskType)); + + fse = FindFileSysResEntry(VolumeNode->dol_misc.dol_volume.dol_DiskType); + if (fse) + { + LONG *seg; + + d1(KPrintF(__FILE__ "/%s/%ld: *** fse OK! =%08lx ***\n", __FUNC__, __FILE__, __FUNC__, __LINE__, fse)); + + if (fse->fse_Node.ln_Name) + stccpy(FseHandler, fse->fse_Node.ln_Name, sizeof(FseHandler)); + + if (fse->fse_DosType) + TypeNewDostype = fse->fse_DosType; + + d1(KPrintF("%s/%s/%ld: fse->fse_DosType=TypeNewDostype=<%lx> fse->fse_Node.ln_Name=<%s>\n", \ + __FILE__, __FUNC__, __LINE__, TypeNewDostype, fse->fse_Node.ln_Name)); + + FseVersion = fse->fse_Version >> 16; + FseRevision = fse->fse_Version & 0xffff; + + sprintf(TextDeviceHandler, "%s %ld.%ld", + FseHandler, + (long)FseVersion, (long)FseRevision); + + d1(KPrintF("%s/%s/%ld: FseHandler=%s FseVersion/FseRevision=%ld.%ld\n", __FILE__, __FUNC__, __LINE__, FseHandler, FseVersion, FseRevision)); + + seg = (LONG *) BADDR(fse->fse_SegList); + + d1(KPrintF("%s/%s/%ld: seg=%08lx\n", __FILE__, __FUNC__, __LINE__, seg)); + + while (seg) + { + CONST_STRPTR VersionString; + size_t SegLength = sizeof(LONG) * seg[-1]; + + d1(KPrintF("%s/%s/%ld: seg=%08lx len=%lu\n", __FILE__, __FUNC__, __LINE__, seg, SegLength)); + + VersionString = FindVersionString((UBYTE *) seg, SegLength); + if (VersionString) + { + strcpy(TextDeviceHandler, VersionString); + + d1(KPrintF("%s/%s/%ld: VersionString=%s\n", __FILE__, __FUNC__, __LINE__, VersionString)); + break; + } + + seg = (LONG *) BADDR(*seg); + } + } + + d1(KPrintF("%s/%s/%ld: dol_DiskType ?? = %lx\n", __FILE__, __FUNC__, __LINE__, VolumeNode->dol_misc.dol_volume.dol_DiskType)); + + sprintf(DosTypeString, "%c%c%c%c", + MakePrintable((VolumeNode->dol_misc.dol_volume.dol_DiskType >> 24) & 0xff), + MakePrintable((VolumeNode->dol_misc.dol_volume.dol_DiskType >> 16) & 0xff), + MakePrintable((VolumeNode->dol_misc.dol_volume.dol_DiskType >> 8) & 0xff), + MakePrintable(VolumeNode->dol_misc.dol_volume.dol_DiskType & 0xff)); + + if (VolumeNode->dol_Task && VolumeNode->dol_Task->mp_SigTask) + { + struct DosList *dl; + + stccpy(DeviceName, ((struct Task *) VolumeNode->dol_Task->mp_SigTask)->tc_Node.ln_Name, MaxLen); + + sprintf(TextDeviceOnDev, "on %s", DeviceName); + + + d1(KPrintF("%s/%s/%ld: ** TextDeviceOnDev=<%s> **\n", __FILE__, __FUNC__, __LINE__, TextDeviceOnDev)); + + dl = LockDosList(LDF_DEVICES | LDF_READ); + + dl = FindDosEntry(dl, DeviceName, LDF_DEVICES); + d1(KPrintF(__FILE__ "/%s/%ld: dl=%08lx\n", __FUNC__, __FILE__, __FUNC__, __LINE__, dl)); + d1(KPrintF("%s/%s/%ld: FindDosEntry(%08lx, %s, LDF_DEVICES)\n", __FILE__, __FUNC__, __LINE__, dl, DeviceName)); + + if (dl) + { + struct FileSysStartupMsg *fsm; + + d1(KPrintF("%s/%s/%ld: *** dl OK! =%08lx ***\n", __FILE__, __FUNC__, __LINE__, dl)); + + d1(KPrintF(__FILE__ "/%s/%ld: dl=%08lx Type=%08lx\n", __FUNC__, __FILE__, __FUNC__, __LINE__, dl, dl->dol_Type)); + d1(KPrintF(__FILE__ "/%s/%ld: dl=%08lx dol_handler=%08lx\n", __FUNC__, __FILE__, __FUNC__, __LINE__, dl, dl->dol_misc.dol_handler.dol_Handler)); + + if (dl->dol_misc.dol_handler.dol_Handler) + { + char Handler[128]; + + BtoCstring(dl->dol_misc.dol_handler.dol_Handler, Handler, sizeof(Handler)); + + d1(KPrintF(__FILE__ "/%s/%ld: ** Handler=<%s> **\n", __FUNC__, __FILE__, __FUNC__, __LINE__, Handler)); + + sprintf(TextDeviceHandler, "%s", Handler); + } + + fsm = BADDR(dl->dol_misc.dol_handler.dol_Startup); + + d1(KPrintF("%s/%s/%ld: *** fsm=%08lx ***\n", __FILE__, __FUNC__, __LINE__, fsm)); + + if (fsm) + { + char DevName[128]; + struct DosEnvec *env; + + d1(KPrintF(__FILE__ "/%s/%ld: *** fms OK! =%08lx ***\n", __FUNC__, __FILE__, __FUNC__, __LINE__, fsm)); + + BtoCstring(fsm->fssm_Device, DevName, sizeof(DevName)); + sprintf(TextDeviceName, "%s, %ld", DevName, fsm->fssm_Unit); + + d1(KPrintF("%s/%s/%ld: DevName=<%s> fsm->fssm_Unit=%ld\n", __FILE__, __FUNC__, __LINE__, DevName, fsm->fssm_Unit)); + + env = BADDR(fsm->fssm_Environ); + + if (env && env->de_TableSize >= DE_DOSTYPE) + { + d1(KPrintF("%s/%s/%ld: env->de_DosType=$%lx [%c%c%c%c]\n", \ + __FILE__, __FUNC__, __LINE__, env->de_DosType, ((env->de_DosType >> 24) & 0xff), + ((env->de_DosType >> 16) & 0xff), + ((env->de_DosType >> 8) & 0xff), + (env->de_DosType & 0xff))); + + TypeNewDostype = env->de_DosType; + + sprintf(DosTypeString, "%c%c%c%c", + MakePrintable((env->de_DosType >> 24) & 0xff), + MakePrintable((env->de_DosType >> 16) & 0xff), + MakePrintable((env->de_DosType >> 8) & 0xff), + MakePrintable(env->de_DosType & 0xff)); + + d1(KPrintF("%s/%s/%ld: DosTypeStrin[env->de_DosType Made printable]=%s\n", __FILE__, __FUNC__, __LINE__, DosTypeString)); + } + +//------------------------------------------------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------------------------------------------------------- + d1(KPrintF("%s/%s/%ld: Info Type=%08lx id_NumBlocks=%ld id_BytesPerBlock=%ld id_BytesPerBlock=%ld id_NumBlocksUsed=%ld\n", \ + __FILE__, __FUNC__, __LINE__, info->id_DiskType, info->id_NumBlocks, info->id_BytesPerBlock, info->id_BytesPerBlock, info->id_NumBlocksUsed)); + + + UsedPercent = (100 * info->id_NumBlocksUsed) / info->id_NumBlocks; + + ByteCount(ByteCountText, sizeof(ByteCountText), info->id_NumBlocksUsed, info->id_BytesPerBlock); + ScaFormatString(GetLocString(MSGID_DEVICE_BLOCKS_PERCENT_USED), + TextDeviceUsed, sizeof(TextDeviceUsed), + 3, ByteCountText, info->id_NumBlocksUsed, UsedPercent); + + d1(kprintf("%s/%s/%ld: ByteCountText=%s TextDeviceUsed=%s\n", __FILE__, __FUNC__, __LINE__, ByteCountText,TextDeviceUsed)); + + + ByteCount(ByteCountText, sizeof(ByteCountText),info->id_NumBlocks - info->id_NumBlocksUsed, info->id_BytesPerBlock); + ScaFormatString(GetLocString(MSGID_DEVICE_BLOCKS_PERCENT_FREE), + TextDeviceFree, sizeof(TextDeviceFree), + 3, ByteCountText, info->id_NumBlocks - info->id_NumBlocksUsed, 100 - UsedPercent); + + d1(kprintf("%s/%s/%ld: ByteCountText=%s TextDeviceFree=%s\n", __FILE__, __FUNC__, __LINE__, ByteCountText, TextDeviceFree)); + + + ByteCount(ByteCountText, sizeof(ByteCountText), info->id_NumBlocks, info->id_BytesPerBlock); + ScaFormatString(GetLocString(MSGID_DEVICE_BLOCKS), + TextDeviceSize, sizeof(TextDeviceSize), 2, ByteCountText, info->id_NumBlocks); + + d1(kprintf("%s/%s/%ld: ByteCountText=%s TextDeviceSize=%s\n", __FILE__, __FUNC__, __LINE__, ByteCountText, TextDeviceSize)); + + + ScaFormatString("Block size: %lD bytes", DeviceBlockSize, sizeof(DeviceBlockSize), 1, info->id_BytesPerBlock); + d1(kprintf("%s/%s/%ld: DeviceBlockSize=%s\n", __FILE__, __FUNC__, __LINE__, DeviceBlockSize)); + + + sprintf(BufferRequest, "%s\n%s\n%s",TextDeviceUsed, TextDeviceFree, TextDeviceSize); + + // ScaFormatString("Capacity: %lD", TextDeviceSize, sizeof(TextDeviceSize), 1, ((TextHighCyl + 1 ) * TextLayoutBPT); + + + d1(KPrintF("%s/%s/%ld: %s\n", __FILE__, __FUNC__, __LINE__, ByteCountText)); +//------------------------------------------------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------------------------------------------------------- + + } + } + + UnLockDosList(LDF_DEVICES | LDF_READ); + } + } + + d1(kprintf(__FILE__ "/%s/%ld: DeviceName=<%s>\n", __FUNC__, __FILE__, __FUNC__, __LINE__, DeviceName)); + + free(info); + } +} + +//----------------------------------------------------------------------------- + +static const struct FileSysEntry *FindFileSysResEntry(ULONG DosType) +{ + struct FileSysResource *FileSysRes; + + FileSysRes = OpenResource(FSRNAME); + if (FileSysRes) + { + const struct FileSysEntry *fse; + char Buffer_Dostype[8]; + char Buffer_FseNodeType[8]; + + sprintf(Buffer_Dostype, "%c%c%c%c", + MakePrintable((DosType >> 24) & 0xff), + MakePrintable((DosType >> 16) & 0xff), + MakePrintable((DosType >> 8) & 0xff), + MakePrintable(DosType & 0xff)); + + for (fse = (const struct FileSysEntry *) FileSysRes->fsr_FileSysEntries.lh_Head; + fse != (const struct FileSysEntry *) &FileSysRes->fsr_FileSysEntries.lh_Tail; + fse = (const struct FileSysEntry *) fse->fse_Node.ln_Succ) + { + + sprintf(Buffer_FseNodeType, "%c%c%c%c", + MakePrintable((fse->fse_DosType >> 24) & 0xff), + MakePrintable((fse->fse_DosType >> 16) & 0xff), + MakePrintable((fse->fse_DosType >> 8) & 0xff), + MakePrintable(fse->fse_DosType & 0xff)); + + d1(KPrintF("%s/%s/%ld: COMPARE: fse->fse_DosType =%lx [%s] WITH DosType =%lx [%s]\n", \ + __FILE__, __FUNC__, __LINE__, fse->fse_DosType, Buffer_FseNodeType, DosType, Buffer_Dostype)); + + if (fse->fse_DosType == DosType) + return fse; + } + } + + return NULL; +} +//---------------------------------------------------------------------------- + + +static CONST_STRPTR FindVersionString(const UBYTE *block, size_t BlockLen) +{ + static char VersMask[10] = "$"; + + // do not use statically initalized "$VER" variable here + // since it might confuse the "version" command. + strcat(VersMask, "VER: "); + + while (BlockLen--) + { + if (0 == memcmp(VersMask, block, strlen(VersMask))) + return (CONST_STRPTR)(block + strlen(VersMask)); + + block++; + } + + return NULL; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + diff --git a/scalos/Modules/FormatDisk.Gadtools/Format.h b/scalos/Modules/FormatDisk.Gadtools/Format.h new file mode 100755 index 000000000..991fa17ac --- /dev/null +++ b/scalos/Modules/FormatDisk.Gadtools/Format.h @@ -0,0 +1,133 @@ +/* + * Format.h + * + * $Date$ + * $Revision$ + * + */ + +#ifndef FORMAT_H +#define FORMAT_H + +#ifndef EXEC_TYPES_H +#include +#endif + +#include +#include + +typedef struct DriveLayout +{ + ULONG lowCyl,highCyl; + ULONG surfaces; + ULONG BPT; + ULONG blockSize; + ULONG unit; + ULONG flags; + ULONG memType; + char devName[256]; +} DriveLayout; + +struct FormatSettings + { + CONST_STRPTR newName; + CONST_STRPTR TrashName; + ULONG ffs; + BOOL quick; + BOOL verify; + BOOL icon; + }; + +//----------------------------------------------------------------------------- + +typedef enum prepResult {eOK,eCancel,eQuit, eQuick} prepResult; + +// int main(void); + +//----------------------------------------------------------------------------- + +void formatVolume(BPTR *volumeLock, + CONST_STRPTR volumeName, + const struct FormatSettings *Parms, + char *statString); + +BOOL doFullFormat(DriveLayout *layout, + char *statString, + struct IOExtTD *io1); + +// BOOL askAreYouSure(char *volumeName, BOOL truncColon); +BOOL askAreYouSure(char *volumeName, BOOL truncColon, char *DeviceSize); +// BOOL askAreYouSure(char *volumeName, BOOL truncColon, char *BodyText); + +BOOL alertIsWriteProtected(CONST_STRPTR devName); + +void printError(CONST_STRPTR first, CONST_STRPTR second, CONST_STRPTR third); + +void getVolumeName(char *name, struct WBArg *argList, UWORD disk); + +void cleanup(ULONG err); + +prepResult getPrepInput(void); + +BOOL volumeToDevName(BPTR volumeLock, char *dev, DriveLayout *layout); + +struct IOExtTD *OpenDrive(char *driveDevName, ULONG unit, ULONG flags); + +void CloseDrive(struct IOExtTD *diskRequest); + +BSTR makeBSTR(CONST_STRPTR in, char *out); +STRPTR BtoCString(BPTR bString, STRPTR Buffer, size_t MaxLen); + +void parseArgs(char *drive, + char *newName, + BOOL *ffs, + BOOL *intl, + BOOL *icons, + char *TrashName, + BOOL *quick, + BOOL *verify); + +//----------------------------------------------------------------------------- + +BOOL updateStatWindow(char *string, UWORD percent); +CONST_STRPTR GetLocString(ULONG MsgId); + +//----------------------------------------------------------------------------- + +extern STRPTR NameOfDevice; +extern STRPTR ShortDostype; + +extern BOOL fromcli; + +// Debug swithes +#define d1(x) ; +#define d2(x) x; + +#define debugLock_d1(LockName) ; +#define debugLock_d2(LockName) \ + {\ + char xxName[200];\ + strcpy(xxName, "");\ + NameFromLock((LockName), xxName, sizeof(xxName));\ + kprintf(__FILE__ "/%s/%ld: " #LockName "=%08lx <%s>\n", __FUNC__, __LINE__, LockName, xxName);\ + } + + +// From debug lib +extern int kprintf(CONST_STRPTR, ...); +extern int KPrintF(CONST_STRPTR, ...); + +//---------------------------------------------------------------------------- + +struct FormatDisk_LocaleInfo +{ + APTR li_LocaleBase; + APTR li_Catalog; + struct LocaleIFace *li_ILocale; +}; + +//----------------------------------------------------------------------------- + +#endif /* FORMAT_H */ + + diff --git a/scalos/Modules/FormatDisk.Gadtools/FormatDisk.cd b/scalos/Modules/FormatDisk.Gadtools/FormatDisk.cd new file mode 100644 index 000000000..a89d29368 --- /dev/null +++ b/scalos/Modules/FormatDisk.Gadtools/FormatDisk.cd @@ -0,0 +1,270 @@ +; FormatDisk.cd +; $Date$ +; $Revision$ +; $Id$ +; version $VER: FormatDisk.catalog 1.05 (08.12.2006) +; codeset 0s +; language english +; +;#arrayopts static __far +; +; +MSGID_DEVICE_SPACE_USED (//) +Used: +; +; +MSGID_DEVICE_SPACE_FREE (//) +Free: +; +; +MSGID_DEVICE_SIZE (//) +Size: +; +; +MSGID_DEVICE_BLOCK_SIZE (//) +Block size: +; +; +; +MSGID_DEVICE_BLOCKS_PERCENT_USED (//) +Used: %s (%lD Blocks, %lD%%) +; +; +MSGID_DEVICE_BLOCKS_PERCENT_FREE (//) +Free: %s (%lD Blocks, %lD%%) +; +; +;Size: +MSGID_DEVICE_BLOCKS (//) +Size: %s (%lD Blocks) +; +; +MSGID_DEVICE_SHORTSIZE (//) +Size: %ld +; +; +; Block size: +MSGID_DEVICE_BLOCKSIZE_BYTES (//) +Block size: %lD bytes +; +; +MSGID_REQ_SURE_TITLE (//) +Format_Disk.module: Request... +; +; +MSGID_REQ_SURE_BODY (//) +Are you sure you want to format volume\n\ +%s\n\ +\n\ +%s\n\ +\n\ +(the contents of the disk will be destroyed)? +; +; +MSGID_REQ_SURE_GADGETS (//) +Yes|No +; +; +MSGID_VOLUME_PROTECTED (//) +Volume\n%s\nis write protected +; +; +MSGID_REQ_RETRY_CANCEL (//) +Retry|Cancel +; +; +MSGID_GADGET_OK (//) +OK +; +; +;--------------------------------------------------------------------------- +; +MSGID_GADGET_DEVNAME (2000//) +_Name: +; +; +MSGID_GADGET_VOLUME (//) +Volume: +; +; +MSGID_GADGET_DEVICE (//) +Device: +; +; +MSGID_GADGET_FFS (//) +_Fast File System +; +; +MSGID_GADGET_INTL (//) +_International +; +; +MSGID_GADGET_VERIFY (//) +_Verify Format +; +; +MSGID_GADGET_TRASHCAN (//) +With t_rashcan +; +; +MSGID_GADGET_DIRCACHE (//) +_Dircache +; +; +MSGID_GADGET_TRASHCAN_NAME (//) +_Trash: +; +; +MSGID_GADGET_GUI_FORMAT (//) +_Format +; +; +MSGID_GADGET_QUICK_FORMAT (//) +_Quick Format +; +; +MSGID_GADGET_GUI_CANCEL (//) +_Cancel +; +; +MSGID_DRIVE_NOFOUND (//) +Can't find its drive! +; +; +MSGID_VOLUME_SELECTED (//) +Volume selected: +; +; +MSGID_OBJECT (//) +Object: +; +; +MSGID_IS_WRONG_TYPE (//) +is a wrong type! +; +;-------------------------------------------------------- +; +MSGID_CLI_SUPPORT_64CMD (//) +*** Device %s supports 64bit commands! No size limit!!\n +; +; +MSGID_CLI_NO_SUPPORT_64CMD (//) +*** Device %s does NOT support 64bit commands. 4GB limit activated!!\n +; +; +MSGID_CLI_INSERT_DISK (//) +Insert the disk to be formatted in drive +; +; +MSGID_CLI_PRESS_RETURN (//) + and press RETURN +; +; +MSGID_INITIALIZING_DISK (//) +Initializing disk... +; +; +MSGID_INITIALIZING_DISK_SUCCESS (//) +Initialized successfully. +; +; +MSGID_INITIALIZING_DISK_FAILED (//) +Initialization failed. +; +; +MSGID_SECOND_INITIALIZING_DISK (//) +Second Initialization... +; +; +MSGID_CLI_BREAK (//) +***Break\n +; +; +MSGID_FORMAT_DISK_FAILED (//) +Cannot format volume +; +; +MSGID_FORMAT_DISK_WRITEPROTECTED (//) +because the disk is write protected +; +; +MSGID_DEVICE_NOT_ACCESS (//) +Couldn't access the device +; +; +MSGID_CREATING_TRASHCAN_USER (//) +Creating Trashcan, named: \"%s\" +; +; +MSGID_CREATING_TRASHCAN_DEFAULT (//) +Creating Trashcan, named: \"Trashcan\" +; +; +MSGID_CREATING_TRASHCAN_ERROR (//) +There was an error while creating the trashcan +; +; +MSGID_CREATING_TRASHCAN_DIR_ERROR (//) +There was an error while creating the trashcan directory +; +;---------------------------------------------------------- +; +MSGID_GUI_FORMATTING_CYLINDER (//) +Formatting cylinder %ld/%ld, %ld to go +; +; +MSGID_FORMATTING_ERROR (//) +A formatting error occured +; +; +MSGID_GUI_FORMATTING_ABORTED (//) +Formatting operation aborted! +; +; +MSGID_GUI_VERIFYING_CYLINDER (//) +Verifying cylinder %ld/%ld, %ld to go +; +; +MSGID_VERIFYING_ERROR (//) +A verify error occurred +; +; +MSGID_GUI_VERIFYING_ABORTED (//) +Verifying operation aborted! +; +; +MSGID_WARNING_FORMAT_DEVICE_NO64BIT (//) +You are trying to format beyond 4GB border although\n\ +your device does not support 64 bit commands. Due to this\n\ +fact, format operation is aborted in order to save your drive. +; +;-------------------------------------------------------- +; +MSGID_GUI_PREPWINDOW_TITLE (//) +Format_Disk.module +; +; +MSGID_GUI_STATUSWINDOW_TITLE (//) +Format_Disk.module: Status +; +; +MSGID_GUI_STATUSWINDOW_FORMATTING_DRIVE (//) +Formatting drive \"%s\" as \"%s\" [%s] ... +; +; +MSGID_GUI_STATUSWINDOW_DEVICE_64BIT (//) +Status Device: \"%s\" [ NSD Support: YES ]. +; +; +MSGID_GUI_STATUSWINDOW_DEVICE_NO64BIT (//) +Status Device: \"%s\" [ NSD Support: N/A. ] +; +; +MSGID_GUI_STATUSWINDOW_ABORT (//) +_Stop +; +; +MSGID_GUI_ON_DRIVE (//) +On drive +; +; diff --git a/scalos/Modules/FormatDisk.Gadtools/FormatVolume.c b/scalos/Modules/FormatDisk.Gadtools/FormatVolume.c new file mode 100644 index 000000000..016c1386b --- /dev/null +++ b/scalos/Modules/FormatDisk.Gadtools/FormatVolume.c @@ -0,0 +1,323 @@ +// FormatVolume.c +// $Date$ +// $Revision$ +// $Id$ + + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "Format.h" +#define FormatDisk_NUMBERS +#include STR(SCALOSLOCALE) + +//---- +extern ULONG FFS; +extern BOOL QuickFmt; +extern BOOL Verify; +extern BOOL Icon; + +extern char temp[]; + +char TheDeviceName[64]; +BOOL NsdSupport = FALSE; +char deviceName[64]; + +UBYTE MakePrintable(UBYTE ch); + +BOOL checkfor64bitcommandset(struct IOStdReq *io); + +//----------------------------------------------------------------------------- + +// This functions handles the low-level format, the high-level format, the +// creation of icons, etc. +void formatVolume(BPTR *volumeLock, CONST_STRPTR volumeName, + const struct FormatSettings *Parms, char *statString) +{ + struct IOExtTD *io1; + BOOL fmtResult = TRUE; + int result = 0; + char temp2[4]; + DriveLayout layout; + struct MsgPort *devPort; + BOOL writeProtCont = TRUE; + char typeDOS[8]; + + // If the volume lock is NULL, assume that the volumeName string holds + // a valid device pointer. + if (*volumeLock == (BPTR)NULL) + { + strcpy(deviceName,volumeName); + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: deviceName=<%s>\n", __LINE__, deviceName)); + } + + // Get the drive name (if possible) + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: * GET *** volumeToDevName(%08lx,%s,%lx) * BUT WHY ??\n", __LINE__, *volumeLock,deviceName,&layout)); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: ** CHECK ** NameOfDevice=<%s> Len=<%ld>\n", __LINE__, NameOfDevice, strlen(NameOfDevice))); + + + if (!volumeToDevName(*volumeLock,deviceName,&layout)) + { + printError((STRPTR) GetLocString(MSGID_DRIVE_NOFOUND),NULL,NULL); + return; + } + + strcpy(TheDeviceName, deviceName); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: * CHECK DEVICENAME: deviceName=<%s> TheDeviceName=<%s>\n", __LINE__, deviceName, TheDeviceName)); + + // This port will be used to communicate with the filesystem + devPort = DeviceProc(deviceName); + if (devPort == NULL) + { + printError((STRPTR) GetLocString(MSGID_DRIVE_NOFOUND),NULL,NULL); + return; + } + + // Inhibit the drive + DoPkt1(devPort,ACTION_INHIBIT,DOSTRUE); + + // If we got a lock to the volume that we're going to format it, destroy + // it, since the volume that it points to is about to be erased anyway. + if (*volumeLock != (BPTR)NULL) + { + UnLock(*volumeLock); + *volumeLock = (BPTR)NULL; + } + + // Open the disk device. + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: * CALL *** OpenDrive(%s,%ld,%lx)\n", \ + __LINE__, layout.devName, layout.unit, layout.flags)); + + if ((io1 = OpenDrive(layout.devName, layout.unit, layout.flags)) != NULL) + { + // Determine the write protect status. + io1->iotd_Req.io_Data = NULL; + io1->iotd_Req.io_Length = 0; + io1->iotd_Req.io_Command = TD_PROTSTATUS; + DoIO((struct IORequest *)io1); + + // Loop while the disk stays protected and user keeps pressing Retry. + while (io1->iotd_Req.io_Actual != 0 && (writeProtCont = alertIsWriteProtected(volumeName))) + DoIO((struct IORequest *)io1); + + // If the disk is not write-protected. + if (writeProtCont) + { + // Do a full format if the user didnt select the Quick option. + if (checkfor64bitcommandset((struct IOStdReq *)io1) == TRUE) + { + NsdSupport = TRUE; + if (fromcli) + printf((STRPTR) GetLocString(MSGID_CLI_SUPPORT_64CMD), deviceName); + } + else + { + if (fromcli) + printf((STRPTR) GetLocString(MSGID_CLI_NO_SUPPORT_64CMD), deviceName); + } + + if (fromcli) + { + Write(Output(),(STRPTR) GetLocString(MSGID_CLI_INSERT_DISK), strlen((STRPTR) GetLocString(MSGID_CLI_INSERT_DISK))); // 41 + Write(Output(),temp,strlen(temp)); + Write(Output(),(STRPTR) GetLocString(MSGID_CLI_PRESS_RETURN), strlen((STRPTR) GetLocString(MSGID_CLI_PRESS_RETURN))); // 18 + Read(Input(),temp2,1); + } + + if ( (SetSignal(0,0) & SIGBREAKF_CTRL_C) != SIGBREAKF_CTRL_C) + { + if (!Parms->quick) + fmtResult = doFullFormat(&layout, statString, io1); + if (fmtResult == TRUE) + { + // Write an extra carriage return, if run from the CLI. + if (fromcli) + Write(Output(),"\n",1); + + // Tell the user that were doing the high-level format. + fmtResult = !updateStatWindow((STRPTR) GetLocString(MSGID_INITIALIZING_DISK),1000); + + // If the user hasnt clicked on Stop, do the high-level format. + if (fmtResult) + { + // Volume name buffer to use with MKBADDR() below. + char mybuf[128]; + + strcpy(mybuf, " "); + strcat(mybuf, Parms->newName); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: mybuf=<%s>\n", __LINE__, mybuf)); + + // result = Format(deviceName,newName, ffs ? ID_FFS_DISK : ID_DOS_DISK); + + // First disk initializing test. If trouble DO: "ACTION_FORMAT" via Dopkt2() below ??. + result = Format(deviceName, Parms->newName, Parms->ffs); + + if (result) + updateStatWindow((STRPTR) GetLocString(MSGID_INITIALIZING_DISK_SUCCESS),1000); + else + { + updateStatWindow((STRPTR) GetLocString(MSGID_INITIALIZING_DISK_FAILED),1000); + + + // Something failed try "ACTION_FORMAT" via Dopkt2() ?? + result = DoPkt2(devPort, ACTION_FORMAT, (IPTR)MKBADDR(mybuf), Parms->ffs); + + updateStatWindow((STRPTR) GetLocString(MSGID_SECOND_INITIALIZING_DISK),1000); + if (result) + updateStatWindow((STRPTR) GetLocString(MSGID_INITIALIZING_DISK_SUCCESS),1000); // Comment "on PASS 2" will be removed after severals tests. + else + updateStatWindow((STRPTR) GetLocString(MSGID_INITIALIZING_DISK_FAILED),1000); + } + + sprintf(typeDOS, "%c%c%c%c", + MakePrintable((Parms->ffs >> 24) & 0xff), + MakePrintable((Parms->ffs >> 16) & 0xff), + MakePrintable((Parms->ffs >> 8) & 0xff), + MakePrintable(Parms->ffs & 0xff)); + + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: FORMATTED: DRIVE deviceName<%s> AS newName=<%s> DOSTYPE: ffs=«$%lx» [%s]\n", \ + __LINE__, deviceName, newName, ffs, typeDOS)); + } + } + } + else + { + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: [SIGBREAKF_CTRL_C]\n", __LINE__)); + Write(Output(),(STRPTR) GetLocString(MSGID_CLI_BREAK), strlen((STRPTR) GetLocString(MSGID_CLI_BREAK))); // 9 + } + } + else + printError("Cannot format volume", volumeName, "because the disk is write protected"); + + // Close the disk device. + CloseDrive(io1); + } + else + { + printError((STRPTR) GetLocString(MSGID_DEVICE_NOT_ACCESS),NULL,NULL); + + if (devPort) + DoPkt1(devPort,ACTION_INHIBIT,DOSFALSE); // ADDED: If error occurred, drives were always inhibited. + return; + } + + // Uninhibit the drive + DoPkt1(devPort,ACTION_INHIBIT,DOSFALSE); + + + // Wait for the drive to come on line, but a better way could be apply here! + Delay(50); + + // If the disk was never unprotected, return. + if (!writeProtCont) + { + return; + } + + // If the format was successful and the user wants icons created. + if (Parms->icon && result == DOSTRUE) + { + struct DiskObject *trashIcon; + BPTR trashLock; + size_t TrashLen; + + + TrashLen = strlen(Parms->TrashName); + + // User can choose its own Trashcan name. + if (TrashLen > 0) + sprintf(statString, (STRPTR) GetLocString(MSGID_CREATING_TRASHCAN_USER), Parms->TrashName); + else + strcpy(statString, (STRPTR) GetLocString(MSGID_CREATING_TRASHCAN_DEFAULT)); + + // Update the user + fmtResult = !updateStatWindow(statString ,1000); + + // If she didnt press Stop. + if (fmtResult) + { + // Create the trashcan name (:Trashcan). + Delay(120); // Wait a little, drive can be yet inhibited. + + strcpy(deviceName, Parms->newName); + strcat(deviceName,":"); + + if (TrashLen > 0) + strcat(deviceName, Parms->TrashName); + else + strcat(deviceName, "Trashcan"); + + // Create the trashcan directory. + trashLock = CreateDir(deviceName); + + // If it was successfully created. + if (trashLock != (BPTR)NULL) + { + UnLock(trashLock); + // Get the trashcan icon. + trashIcon = GetDefDiskObject(WBGARBAGE); + + // If there wasnt an error. + if (trashIcon != NULL) + { + // Write the icon to disk. + if (!PutDiskObject(deviceName,trashIcon)) + printError((STRPTR) GetLocString(MSGID_CREATING_TRASHCAN_ERROR), NULL,NULL); + + // and free it. + FreeDiskObject(trashIcon); + } + else + { + // printf("ERROR NUMBER = %ld\n", IoErr()); + printError((STRPTR) GetLocString(MSGID_CREATING_TRASHCAN_ERROR), NULL,NULL); + } + } + else + { + // printf("ERROR NUMBER = %ld\n", IoErr()); + printError((STRPTR) GetLocString(MSGID_CREATING_TRASHCAN_DIR_ERROR), NULL,NULL); + } + } + } + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: NsdSupport=%ld deviceName=<%s>\n", __LINE__, NsdSupport, deviceName)); + + return; +} + +//---------------------------------------------- + +UBYTE MakePrintable(UBYTE ch) +{ + if (ch < ' ') + ch += '0'; + + return ch; +} + diff --git a/scalos/Modules/FormatDisk.Gadtools/Format_disk_rev.h b/scalos/Modules/FormatDisk.Gadtools/Format_disk_rev.h new file mode 100644 index 000000000..6043187de --- /dev/null +++ b/scalos/Modules/FormatDisk.Gadtools/Format_disk_rev.h @@ -0,0 +1,22 @@ +// Format_disk_rev.h +// $Date$ +// $Revision$ +// $Id$ + +#ifndef FORMAT_DISK_REV_H +#define FORMAT_DISK_REV_H + + +#include + +#define VERSION 1 +#define REVISION 05 +#define VERS_REV_STR "1.05" +#define DATE "06.12.2006" +#define NAME "Format_Disk.module" +#define TITLE_NAME NAME VERS_REV_STR " (" DATE ") NSD 64Bit Support" COMPILER_STRING COPYRIGHT +#define VERSTAG "\00$VER: " NAME " " VERS_REV_STR " (" DATE ") NSD 64Bit Support" COMPILER_STRING +#define COPYRIGHT " © 2006" CURRENTYEAR " The Scalos Team" + +#endif /* FORMAT_DISK_REV_H */ + diff --git a/scalos/Modules/FormatDisk.Gadtools/FullFormat.c b/scalos/Modules/FormatDisk.Gadtools/FullFormat.c new file mode 100755 index 000000000..83af6c1e7 --- /dev/null +++ b/scalos/Modules/FormatDisk.Gadtools/FullFormat.c @@ -0,0 +1,300 @@ +// DoFullFormat.c +// $Date$ +// $Revision$ + + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "Format.h" +#define FormatDisk_NUMBERS +#include STR(SCALOSLOCALE) + +//----------------------------------------------------------------------------- + +#ifdef __GNUC__ + +typedef unsigned long long ULONG64; + +// Macros to acccess one of the longs of an ULONG64 +#define ULONG64_LOW(long64) ((ULONG) ((long64) & 0xffffffff)) +#define ULONG64_HIGH(long64) ((ULONG) (((long64) >> 32) & 0xffffffff)) + +#else /* __GNUC__ */ + +typedef struct { ULONG High, Low; } ULONG64; + + +// Macros to acccess one of the longs of an ULONG64 +#define ULONG64_LOW(long64) ((long64).Low) +#define ULONG64_HIGH(long64) ((long64).High) + +#endif /* __GNUC__ */ + +//----------------------------------------------------------------------------- + +//--- External symbols +extern BOOL FFS; +extern BOOL QuickFm; +extern BOOL Verify; +extern BOOL Icon; + +static ULONG64 Make64( ULONG n ); +static ULONG64 Incr64(ULONG64 x, ULONG n ); + +//--- NSD Functions +BOOL checkfor64bitcommandset(struct IOStdReq *io); + +//----------------------------------------------------------------------------- + +// This function does a full (low-level) format of a disk +BOOL doFullFormat(DriveLayout *layout, char *statString, struct IOExtTD *io1) +{ + ULONG64 nsdbuffer, nsdbuffer2; + ULONG trackSize, numTracks, i, track; + UWORD formatcommand = TD_FORMAT; + UWORD verifycommand = CMD_READ; + int c; + UBYTE error = 2, *write; // +jmc+ not = NULL + BOOL errorB = FALSE, command64; // +jmc+ not = FALSE; + + + // Get the size of a track (#surfaces*#blocks*#longwordsPerTrack*4) + trackSize = layout->surfaces*layout->blockSize*4*layout->BPT; + + command64 = checkfor64bitcommandset((struct IOStdReq *)io1); + if (command64 == TRUE) + { + formatcommand = NSCMD_TD_FORMAT64; + verifycommand = NSCMD_TD_READ64; + } + + nsdbuffer = Make64(0); + + // Allocate enough memory for one track + write = (UBYTE*)AllocMem(trackSize, layout->memType|MEMF_CLEAR); + if (write != NULL) + { + // Initialize the IORequest*/ +// io1->iotd_Req.io_Data = write; +// io1->iotd_Req.io_Length = trackSize; + + + // Get the starting byte position in the volume + for (i = 0; ilowCyl; i++) + nsdbuffer = Incr64(nsdbuffer, trackSize); + + nsdbuffer2 = nsdbuffer; + + for (i = layout->lowCyl; ihighCyl; i++) + nsdbuffer2 = Incr64(nsdbuffer2, trackSize); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: start: nsdbuffer[0]=%u nsdbuffer[1]=%u end: nsdbuffer2[0]=%u nsdbuffer2[1]=%u\n", \ + __LINE__, ULONG64_HIGH(nsdbuffer), ULONG64_LOW(nsdbuffer), ULONG64_HIGH(nsdbuffer2), ULONG64_LOW(nsdbuffer2))); + + if (ULONG64_HIGH(nsdbuffer2) != 0) + { + if (command64 == FALSE) + { + printError((STRPTR) GetLocString(MSGID_WARNING_FORMAT_DEVICE_NO64BIT), NULL, NULL); + FreeMem(write, trackSize); + return(FALSE); + } + else + { + formatcommand = NSCMD_TD_FORMAT64; + verifycommand = NSCMD_TD_READ64; + } + } + + numTracks = layout->highCyl-layout->lowCyl+1; + + // Clear the status window + error = (updateStatWindow(" ",0)) ? 0 : error; + + // For each track + for (track = 0;track < numTracks && error != 0;track++) + { + // Setup to format the disk + io1->iotd_Req.io_Data = write; + io1->iotd_Req.io_Length = trackSize; + io1->iotd_Req.io_Command = formatcommand; + io1->iotd_Req.io_Actual = ULONG64_HIGH(nsdbuffer); + io1->iotd_Req.io_Offset = ULONG64_LOW(nsdbuffer); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: iotd_Req.io_Data=<%u> iotd_Req.io_Length=<%u> command=$%lx iotd_Req.io_Actual=<%u> iotd_Req.io_Offset=<%u> write=%08lx\n", \ + __LINE__, io1->iotd_Req.io_Data, io1->iotd_Req.io_Length, io1->iotd_Req.io_Command, io1->iotd_Req.io_Actual, io1->iotd_Req.io_Offset, write)); + + // Update the status window + sprintf(statString, (STRPTR) GetLocString(MSGID_GUI_FORMATTING_CYLINDER), + track+layout->lowCyl, numTracks, numTracks-track-1); + + error = (updateStatWindow(statString,track*1000/numTracks)) ? 0 :error; + + // If the user did not press Stop + if (error != 0) + { + error = (DoIO((struct IORequest *)io1)) ? 0 : error; + if (error == 0) + { + printError((STRPTR) GetLocString(MSGID_FORMATTING_ERROR),NULL,NULL); + errorB = TRUE; + } + } + else + { + updateStatWindow((STRPTR) GetLocString(MSGID_GUI_FORMATTING_ABORTED),1000); + } + + // If we're suppossed to verify, and the user didn't press 'Stop' + if (Verify == TRUE && error != 0) + { + // Setup the same IORequest to do a read + io1->iotd_Req.io_Data = write; + io1->iotd_Req.io_Length = trackSize; + io1->iotd_Req.io_Command = verifycommand; + io1->iotd_Req.io_Actual = ULONG64_HIGH(nsdbuffer); + io1->iotd_Req.io_Offset = ULONG64_LOW(nsdbuffer); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: iotd_Req.io_Data=<%u> iotd_Req.io_Length=<%u> command=$%lx iotd_Req.io_Actual=<%u> iotd_Req.io_Offset=<%u>\n", \ + __LINE__, io1->iotd_Req.io_Data, io1->iotd_Req.io_Length, io1->iotd_Req.io_Command, io1->iotd_Req.io_Actual, io1->iotd_Req.io_Offset)); + + // Update the status + sprintf(statString, (STRPTR) GetLocString(MSGID_GUI_VERIFYING_CYLINDER), + track+layout->lowCyl, numTracks, numTracks-track-1); + + error = (updateStatWindow(statString, ( (1+(track*2))*1000)/(2*numTracks) )) ? 0 : error; + + // If the user hasnt pressed Stop + if (error != 0) + { + error = (DoIO((struct IORequest *)io1)) ? 0 : error; + if (error == 0) + { + printError((STRPTR) GetLocString(MSGID_VERIFYING_ERROR),NULL,NULL); + errorB = TRUE; + } + } + else + { + updateStatWindow((STRPTR) GetLocString(MSGID_GUI_VERIFYING_ABORTED),1000); + } + + // Check the data that was read back. + if (error != 0) + if (errorB == FALSE) + for (c=0; c +#include +#include +#include +// #include +#include + +#include + +#include +#include +#include +#include +#include + + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "Format.h" +#define FormatDisk_NUMBERS +#include STR(SCALOSLOCALE) + +#include "GUI.h" +#include "Format_disk_rev.h" +#include + +//----------------------------------------------------------------------------- + +struct Window *PrepWnd = NULL; +struct Window *StatusWnd = NULL; +struct Gadget *PrepGadgets[11]; // Number of gadgets +struct Gadget *StatusGadgets[2]; + +char NewVolumeName[64]; + +Rect box; + +//----------------------------------------------------------------------------- + +extern struct GfxBase *GfxBase; + +extern char volumeName[]; +extern char deviceName[]; + +extern STRPTR ShortDostype; + +//----------------------------------------------------------------------------- + +static struct Screen *Scr = NULL; +static APTR VisualInfo = NULL; +static struct Gadget *PrepGList = NULL; +static struct Gadget *StatusGList = NULL; +static UWORD PrepLeft = 0; +static UWORD PrepTop = 23; +static UWORD PrepWidth = 332; +static UWORD PrepHeight = 90; +static UWORD StatusLeft = 0; +static UWORD StatusTop = 23; +static UWORD StatusWidth = 480; +static UWORD StatusHeight = 69; +static STRPTR PrepWdt; +static STRPTR StatusWdt; + +static struct TextAttr *Font, Attr; + +static UWORD FontX, FontY; +static UWORD OffX, OffY; +static UWORD ScreenBarH; + +static char StatusTextDrive[128]; +static char StatusTextNSDSupport[256]; + +static BOOL DefaultFont=FALSE; + +static UWORD SpaceChar; +static UWORD CheckBoxPixel; +static BOOL ForceFontTopaz8 = FALSE; +static UWORD gd_StatusGadgetWidth; + +//----------------------------------------------------------------------------- + +static LONG GetLenForText(LONG LMsgig, LONG Current, struct TextFont *tf); // Used with LONG +static LONG GetLenForText2(STRPTR LString, LONG Current, struct TextFont *tf); // Used with STRPTR + +static void InitScreenFont( void ); + +//----------------------------------------------------------------------------- + +static struct IntuiText StatusIText[] = + { + {1, 0, JAM1,3, 2, NULL, StatusTextDrive, &StatusIText[1] }, + {1, 0, JAM1,3, 12, NULL, StatusTextNSDSupport }, + {0} + }; + +//----------------------------------------------------------------------------- + +static UWORD ComputeX( UWORD value ) +{ + return(( UWORD )(( FontX * value) / 8)); // / 8 +} + +//----------------------------------------------------------------------------- + +static UWORD ComputeY( UWORD value ) +{ + return(( UWORD )(( FontY * value ) / 8)); // 8 +} + +//----------------------------------------------------------------------------- +static void InitScreenFont( void ) +{ + struct TextFont *tf; + Font = &Attr; + + Font->ta_Name = Scr->Font->ta_Name; + tf = OpenDiskFont(Scr->Font); // OpenDiskFont + ScreenBarH = tf->tf_YSize + Scr->WBorTop + 1; + OffY = ScreenBarH; + CheckBoxPixel = OffY; + CloseFont(tf); + + if (DefaultFont) + { + // Default font. + Font->ta_Name = GfxBase->DefaultFont->tf_Message.mn_Node.ln_Name; + Font->ta_YSize = FontY = GfxBase->DefaultFont->tf_YSize; + FontX = GfxBase->DefaultFont->tf_XSize; + CheckBoxPixel = OffY; + } + else + { + // Screen font. + tf = OpenDiskFont(Scr->Font); + Font->ta_YSize = FontY = tf->tf_YSize; + FontX = tf->tf_XSize; + Font = Scr->Font; + CloseFont(tf); + } + + if (OffX > OffY) + CheckBoxPixel = OffX; + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: Font Name = <%s> X=%ld / Y=%ld ScreenBarH = %ld CheckBoxPixel= %ld \n", \ + __LINE__, Font->ta_Name, (LONG) FontX, (LONG) FontY, (LONG) OffY, (LONG) CheckBoxPixel)); + + OffX = Scr->WBorLeft; +} + +//----------------------------------------------------------------------------- + +static BOOL ComputeFont( UWORD width, UWORD height ) +{ + if ( width && height ) + { + if (( width + OffX + Scr->WBorRight ) > Scr->Width ) + return TRUE; + // goto UseTopaz; + if (( height + OffY + Scr->WBorBottom ) > Scr->Height ) + return TRUE; + // goto UseTopaz; + } + return FALSE; +} + +//----------------------------------------------------------------------------- + +int SetupScreen( void ) +{ + if ( ! ( Scr = LockPubScreen( NULL ))) + return( 1L ); + + ComputeFont( 0L, 0L ); + + if ( ! ( VisualInfo = GetVisualInfo( Scr, TAG_DONE ))) + return( 2L ); + + if(Scr) + { + PrepTop = (Scr->Height/2) - (PrepHeight/2) - (Scr->BarHeight*2); + PrepLeft = (Scr->Width/2) - (PrepWidth/2) + (((Scr->WBorLeft+4)*2)+1); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: PrepLeft =%ld\n", __LINE__, PrepLeft)); + + StatusTop = (Scr->Height/2) - (StatusHeight/2) - (Scr->BarHeight*2); + StatusLeft = (Scr->Width/2) - (StatusWidth/2) + ((Scr->WBorLeft+4)*2); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: StatusLeft =%ld\n", __LINE__, StatusLeft)); + } + + return( 0L ); +} + +//----------------------------------------------------------------------------- + +void CloseDownScreen( void ) +{ + if (VisualInfo) + { + FreeVisualInfo( VisualInfo ); + VisualInfo = NULL; + } + + if (Scr) + { + UnlockPubScreen( NULL, Scr ); + Scr = NULL; + } +} + +//----------------------------------------------------------------------------- + +int OpenPrepWindow( char *volumeName , BOOL GetFFS, BOOL GetINTL, BOOL GetDirCache) +{ + struct TextFont *tf; + struct NewGadget ng; + struct Gadget *g; + UWORD wleft, wtop, ww, wh; + UWORD BtWidth; + char StripVolumeName[64]; + char OnDeviceName[256]; + CONST_STRPTR gd_DeviceGad_Text; + size_t volumeNamelen; + size_t deviceNamelen; + UWORD WestNameOrDevice; // +jmc+ + UWORD Row1; // +jmc+ + UWORD Row2; // +jmc+ + UWORD Row3; // +jmc+ + UWORD Row4; // +jmc+ + UWORD Row5; // +jmc+ + UWORD Row6; // +jmc+ + UWORD West; // +jmc+ + UWORD TrashCanFieldPosition; // +jmc+ + UWORD WestOnDrive; // +jmc+ + BOOL AddOnDrive = FALSE; + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: deviceName=<%s>\n", __LINE__, deviceName)); + + PrepWdt = (STRPTR) GetLocString(MSGID_GUI_PREPWINDOW_TITLE); + + volumeNamelen=strlen(volumeName); + deviceNamelen=strlen(deviceName); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: volumeNamelen=<%ld> - deviceNamelen=<%ld>\n", __LINE__, volumeNamelen, deviceNamelen)); + + stccpy(StripVolumeName, volumeName, volumeNamelen); + + InitScreenFont(); + + tf = OpenDiskFont(Font); + + //================================================================================================================================ + + if ( ! ( g = CreateContext( &PrepGList ))) + return( 1L ); + + if (deviceNamelen == 0) + { + strcpy(OnDeviceName, volumeName); + gd_DeviceGad_Text = GetLocString(MSGID_GADGET_DEVICE); + Row1 = GetLenForText(MSGID_GADGET_DEVICE, 0, tf); + } + else + { + sprintf(OnDeviceName, "%s (%s \"%s:\")", volumeName, GetLocString(MSGID_GUI_ON_DRIVE), deviceName); + gd_DeviceGad_Text = GetLocString(MSGID_GADGET_VOLUME); + Row1 = GetLenForText(MSGID_GADGET_VOLUME, 0, tf); + AddOnDrive = TRUE; + } + + SpaceChar = FontX; + + West = Row1; + WestNameOrDevice = Row1; + + Row2 = GetLenForText(MSGID_GADGET_DEVNAME, 0, tf); + if (Row2 > West) + { + West = Row2; + WestNameOrDevice = Row2; + } + + WestNameOrDevice = WestNameOrDevice + SpaceChar + (Scr->WBorLeft + Scr->WBorRight); + + Row3 = GetLenForText(MSGID_GADGET_FFS, 0, tf); + Row3 += GetLenForText(MSGID_GADGET_INTL, Row3, tf); + if (Row3 > West) + West = Row3; + + Row4 = GetLenForText(MSGID_GADGET_VERIFY, 0, tf); + Row4 += GetLenForText(MSGID_GADGET_TRASHCAN, Row4, tf); + if (Row4 > West) + West = Row4; + + Row5 = GetLenForText(MSGID_GADGET_DIRCACHE, 0, tf); + Row5 += GetLenForText(MSGID_GADGET_TRASHCAN_NAME, Row5, tf); + if (Row5 > West) + West = Row5; + + Row6 = GetLenForText(MSGID_GADGET_GUI_FORMAT, 0, tf) + (SpaceChar * 2); + Row6 += GetLenForText(MSGID_GADGET_QUICK_FORMAT, Row6, tf) + (SpaceChar * 2); + Row6 += GetLenForText(MSGID_GADGET_GUI_CANCEL, Row6, tf) + (SpaceChar * 2); + if (Row6 > West) + West = Row6; + + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld:\nForceFontTopaz8 = [%ld]\nRow1 = %ld \nRow2 = %ld\nRow3 = %ld\nRow4 = %ld\nRow5 = %ld\nRow6 = %ld\n=> West = %ld\n", \ + __LINE__, ForceFontTopaz8, Row1, Row2, Row3, Row4, Row5, Row6, West)); + + + TrashCanFieldPosition = (West/2) + GetLenForText(MSGID_GADGET_TRASHCAN_NAME, 0, tf); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: West = [%ld]\n", __LINE__, West)); + + if (AddOnDrive == TRUE) + { + WestOnDrive = GetLenForText2((STRPTR) OnDeviceName, 0,tf) + WestNameOrDevice; + if (WestOnDrive > West) + { + West = WestOnDrive; + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: Change Widest: West = [%ld]\n", __LINE__, West)); + } + } + + ww = West + (SpaceChar * 3); + + CloseFont(tf); + +//---------------------------------- Check Window size according to Screen width and height ---------------------------------------------------------- + + ForceFontTopaz8 = ComputeFont( ww, PrepHeight ); + +//---------------------------------- Window width size initialization once again ---------------------------------------------------------------------- + + if (ForceFontTopaz8) + { + Font->ta_Name = (STRPTR)"topaz.font"; + FontX = FontY = Font->ta_YSize = 8; + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: ForceFontTopaz8=[%ld] Font Name = <%s> X=%ld / Y=%ld ScreenBarH = %ld\n", \ + __LINE__, ForceFontTopaz8, Font->ta_Name, (LONG) FontX, (LONG) FontY, (LONG) OffY)); + + tf = OpenDiskFont(Font); + + // wh = ComputeY( PrepHeight ); + + if (deviceNamelen == 0) + { + strcpy(OnDeviceName, volumeName); + gd_DeviceGad_Text = GetLocString(MSGID_GADGET_DEVICE); + Row1 = GetLenForText(MSGID_GADGET_DEVICE, 0, tf); + } + else + { + sprintf(OnDeviceName, "%s (On drive \"%s:\")", volumeName, deviceName); + gd_DeviceGad_Text = GetLocString(MSGID_GADGET_VOLUME); + Row1 = GetLenForText(MSGID_GADGET_VOLUME, 0, tf); + } + + SpaceChar = FontX; + + West = Row1; + WestNameOrDevice = Row1; + + Row2 = GetLenForText(MSGID_GADGET_DEVNAME, 0, tf); + if (Row2 > West) + { + West = Row2; + WestNameOrDevice = Row2; + } + + WestNameOrDevice = WestNameOrDevice + SpaceChar + (Scr->WBorLeft + Scr->WBorRight); + + Row3 = GetLenForText(MSGID_GADGET_FFS, 0, tf); + Row3 += GetLenForText(MSGID_GADGET_INTL, Row3, tf); + if (Row3 > West) + West = Row3; + + Row4 = GetLenForText(MSGID_GADGET_VERIFY, 0, tf); + Row4 += GetLenForText(MSGID_GADGET_TRASHCAN, Row4, tf); + if (Row4 > West) + West = Row4; + + Row5 = GetLenForText(MSGID_GADGET_DIRCACHE, 0, tf); + Row5 += GetLenForText(MSGID_GADGET_TRASHCAN_NAME, Row5, tf); + if (Row5 > West) + West = Row5; + + Row6 = GetLenForText(MSGID_GADGET_GUI_FORMAT, 0, tf) + (SpaceChar * 2); + Row6 += GetLenForText(MSGID_GADGET_QUICK_FORMAT, Row6, tf) + (SpaceChar * 2); + Row6 += GetLenForText(MSGID_GADGET_GUI_CANCEL, Row6, tf) + (SpaceChar * 2); + if (Row6 > West) + West = Row6; + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld:\nForceFontTopaz8 = [%ld]\nRow1 = %ld \nRow2 = %ld\nRow3 = %ld\nRow4 = %ld\nRow5 = %ld\nRow6 = %ld\n=> West = %ld\n", \ + __LINE__, ForceFontTopaz8, Row1, Row2, Row3, Row4, Row5, Row6, West)); + + + TrashCanFieldPosition = (West/2) + GetLenForText(MSGID_GADGET_TRASHCAN_NAME, 0, tf); + + if (AddOnDrive == TRUE) + { + WestOnDrive = GetLenForText2((STRPTR) OnDeviceName, 0,tf) + WestNameOrDevice; + if (WestOnDrive > West) + { + West = WestOnDrive; + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: Change Widest: West = [%ld]\n", __LINE__, West)); + } + } + + ww = West + (SpaceChar * 2); + + CloseFont(tf); + } + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: AddOnDrive = [%ld] - West = [%ld] Window width = [%ld] \n", __LINE__, AddOnDrive, West, ww)); + + wh = ComputeY( PrepHeight ); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: wh = [%ld] OffY = %ld ScreenBarH = %ld\n", __LINE__, wh, OffY, ScreenBarH)); + +//- ROW 1 ---------------------------------------------------------------------------------------------------------------------------------------------- + + ng.ng_LeftEdge = OffX + WestNameOrDevice; + ng.ng_TopEdge = ScreenBarH + ComputeY( 4 ); + ng.ng_Width = ww - ((OffX*2) + WestNameOrDevice) - Scr->WBorLeft - Scr->WBorRight; + ng.ng_Height = ComputeY( 13 ); + ng.ng_TextAttr = Font; + ng.ng_GadgetText = (STRPTR) gd_DeviceGad_Text; // TEXT Gadget: "Volume:" or "Device:" + ng.ng_GadgetID = GD_DeviceGad; + ng.ng_Flags = PLACETEXT_LEFT; + ng.ng_VisualInfo = VisualInfo; + + g = CreateGadget( TEXT_KIND, + g, &ng, + GTTX_Text, OnDeviceName, + GTTX_Border, TRUE, + TAG_DONE ); + + PrepGadgets[ GDX_DeviceGad ] = g; + + //--------------------------------------------------------------------- + +//- ROW 2 ---------------------------------------------------------------------------------------------------------------------------------------------- + + //--------------------------------------------------------------------- + + ng.ng_LeftEdge = OffX + WestNameOrDevice; + ng.ng_TopEdge = ScreenBarH + ComputeY( 18 ); + ng.ng_Width = ww - ((OffX*2) + WestNameOrDevice) - Scr->WBorLeft - Scr->WBorRight; + ng.ng_GadgetText = (STRPTR) GetLocString(MSGID_GADGET_DEVNAME); // STRING Gadget: "Name" + ng.ng_GadgetID = GD_NameGadget; + ng.ng_Flags = PLACETEXT_LEFT; + + g = CreateGadget( STRING_KIND, g, &ng, GTST_String, StripVolumeName, + GTST_MaxChars, 30, + GT_Underscore, '_', + STRINGA_Justification, GACT_STRINGCENTER, + TAG_DONE ); + + PrepGadgets[ GDX_NameGadget ] = g; + + //--------------------------------------------------------------------- + +//- ROW 3 ---------------------------------------------------------------------------------------------------------------------------------------------- + + //--------------------------------------------------------------------- + + ng.ng_LeftEdge = OffX + ComputeX( 5 ); + ng.ng_TopEdge = ScreenBarH + ComputeY( 33 ); + ng.ng_Width = CheckBoxPixel; + ng.ng_Height = CheckBoxPixel; + ng.ng_GadgetText = (STRPTR) GetLocString(MSGID_GADGET_FFS); // CHECKBOX Gadget: "Fast File System" + ng.ng_GadgetID = GD_FFSGadget; + ng.ng_Flags = PLACETEXT_RIGHT; + + g = CreateGadget( CHECKBOX_KIND, + g, &ng, + GTCB_Checked, GetFFS, + GT_Underscore, '_', + GA_Disabled, !GetFFS, + TAG_DONE ); + + PrepGadgets[ GDX_FFSGadget ] = g; + + //--------------------------------------------------------------------- + + ng.ng_LeftEdge = ww/2; + ng.ng_GadgetText = (STRPTR) GetLocString(MSGID_GADGET_INTL); // CHECKBOX Gadget: "INTL" (Internationnal) + ng.ng_GadgetID = GD_IntlGadget; + + g = CreateGadget( CHECKBOX_KIND, + g, &ng, + GTCB_Checked, GetINTL, + GT_Underscore, '_', + TAG_DONE ); + + PrepGadgets[ GDX_IntlGadget ] = g; + + //--------------------------------------------------------------------- + +//- ROW 4 ---------------------------------------------------------------------------------------------------------------------------------------------- + + //--------------------------------------------------------------------- + + ng.ng_LeftEdge = OffX + ComputeX( 5 ); + ng.ng_TopEdge = ScreenBarH + ComputeY( 46 ); + ng.ng_GadgetText = (STRPTR) GetLocString(MSGID_GADGET_VERIFY); // CHECKBOX Gadget: "Verify Format". + ng.ng_GadgetID = GD_VerifyGadget; + + g = CreateGadget( CHECKBOX_KIND, g, &ng, GTCB_Checked, Verify, GT_Underscore, '_', TAG_DONE ); + + PrepGadgets[ GDX_VerifyGadget ] = g; + + //--------------------------------------------------------------------- + + ng.ng_LeftEdge = ww/2; + ng.ng_GadgetText = (STRPTR) GetLocString(MSGID_GADGET_TRASHCAN); // CHECKBOX Gadget: "With Traschcan". + ng.ng_GadgetID = GD_IconGadget; + ng.ng_Flags = PLACETEXT_RIGHT; + + g = CreateGadget( CHECKBOX_KIND, + g, &ng, + GTCB_Checked, Icon, + GT_Underscore, '_', + TAG_DONE ); + + PrepGadgets[ GDX_IconGadget ] = g; + + + //--------------------------------------------------------------------- + +//- ROW 5 ---------------------------------------------------------------------------------------------------------------------------------------------- + + //--------------------------------------------------------------------- + + ng.ng_LeftEdge = OffX + ComputeX( 5 ); + ng.ng_TopEdge = ScreenBarH + ComputeY( 60 ); + ng.ng_GadgetText = (STRPTR) GetLocString(MSGID_GADGET_DIRCACHE); // CHECKBOX Gadget "DirCache". + ng.ng_GadgetID = GD_DirCacheGadget; + ng.ng_Flags = PLACETEXT_RIGHT; + + g = CreateGadget( CHECKBOX_KIND, + g, &ng, + GTCB_Checked, GetDirCache, + GT_Underscore, '_', + TAG_DONE ); + + PrepGadgets[ GDX_DirCacheGadget ] = g; + + //--------------------------------------------------------------------- + + ng.ng_LeftEdge = TrashCanFieldPosition; + ng.ng_TopEdge -= ComputeY( 2 ); + ng.ng_Width = ww - TrashCanFieldPosition - Scr->WBorLeft - Scr->WBorRight - 3; + ng.ng_Height = ComputeY( 13 ); + ng.ng_GadgetText = (STRPTR) GetLocString(MSGID_GADGET_TRASHCAN_NAME); // STRING Gadget "Trashcan Name". + ng.ng_GadgetID = GD_TrashCanNameGadget; + ng.ng_Flags = PLACETEXT_LEFT; + + g = CreateGadget( STRING_KIND, + g, &ng, + GTST_String, "Trashcan", + GTST_MaxChars, 25, + GT_Underscore, '_', + GA_Disabled, !Icon, + TAG_DONE ); + + PrepGadgets[ GDX_TrashCanNameGadget ] = g; + + //--------------------------------------------------------------------- + +//- ROW 6 ---------------------------------------------------------------------------------------------------------------------------------------------- + + //--------------------------------------------------------------------- + + + BtWidth = ( (ww - Scr->WBorRight - Scr->WBorLeft - (FontX+4)) / 3 ); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: Bouton Width = %ld ww = %ld\n", __LINE__, BtWidth, ww)); + + ng.ng_LeftEdge = OffX + ComputeX( 4 ); + ng.ng_TopEdge = OffY + ComputeY( 76 ); + ng.ng_Width = BtWidth; + ng.ng_Height = ComputeY( 12 ); + ng.ng_GadgetText = (STRPTR) GetLocString(MSGID_GADGET_GUI_FORMAT); // BUTTON Gadget: "OK". + ng.ng_GadgetID = GD_OKGadget; + ng.ng_Flags = PLACETEXT_IN; + + g = CreateGadget( BUTTON_KIND, + g, &ng, + GT_Underscore, '_', + TAG_DONE ); + + PrepGadgets[ GDX_OKGadget ] = g; + + //--------------------------------------------------------------------- + + ng.ng_LeftEdge = OffX + ComputeX( 4 ) + (BtWidth + 2) ; + ng.ng_Width = BtWidth; + ng.ng_Height = ComputeY( 12 ); + ng.ng_GadgetText = (STRPTR) GetLocString(MSGID_GADGET_QUICK_FORMAT); // BUTTON Gadget: "Quick Format". + ng.ng_GadgetID = GD_QuickFmtGadget; + ng.ng_Flags = PLACETEXT_IN; + + g = CreateGadget( BUTTON_KIND, + g, &ng, + GT_Underscore, '_', + TAG_DONE ); + + PrepGadgets[ GDX_QuickFmtGadget ] = g; + + //--------------------------------------------------------------------- + + ng.ng_LeftEdge = OffX + ComputeX( 4 ) + (BtWidth * 2) + 4; + ng.ng_Width = BtWidth; + ng.ng_Height = ComputeY( 12 ); + ng.ng_GadgetText = (STRPTR) GetLocString(MSGID_GADGET_GUI_CANCEL); // BUTTON Gadget: "Cancel". + ng.ng_GadgetID = GD_CancelGadget; + ng.ng_Flags = PLACETEXT_IN; + + g = CreateGadget( BUTTON_KIND, + g, &ng, + GT_Underscore, '_', + TAG_DONE ); + + PrepGadgets[ GDX_CancelGadget ] = g; + + + //--------------------------------------------------------------------- + + if ( ! g ) + return( 2L ); + + + wleft = ((Scr->Width/2) - ((ww + Scr->WBorRight + Scr->WBorLeft)/2)); + wtop = ((Scr->Height/2) - ((wh + Scr->BarHeight + Scr->WBorTop + Scr->WBorBottom)/2)); + + if ( ! ( PrepWnd = OpenWindowTags( NULL, + WA_Left, wleft, + WA_Top, wtop, + WA_Width, ww, + WA_Height, wh + OffY + Scr->WBorBottom, + WA_IDCMP, IDCMP_VANILLAKEY|IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW|BUTTONIDCMP|CHECKBOXIDCMP, + WA_Flags, WFLG_ACTIVATE|WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_CLOSEGADGET|WFLG_SMART_REFRESH|WFLG_RMBTRAP, + WA_Gadgets, PrepGList, + WA_Title, PrepWdt, + WA_ScreenTitle, TITLE_NAME, + WA_PubScreen, Scr, + TAG_DONE ))) + + return( 4L ); + + GT_RefreshWindow( PrepWnd, NULL ); + + return( 0L ); +} + +//----------------------------------------------------------------------------- + +void ClosePrepWindow( void ) +{ + if ( PrepWnd ) + { + CloseWindow( PrepWnd ); + PrepWnd = NULL; + } + + if ( PrepGList ) + { + FreeGadgets( PrepGList ); + PrepGList = NULL; + } +} + +//----------------------------------------------------------------------------- + +void StatusRender( void ) +{ + ULONG leftEdge[2],topEdge[2]; + ComputeFont( StatusWidth, StatusHeight ); + + leftEdge[0] = StatusIText[0].LeftEdge; + leftEdge[1] = StatusIText[1].LeftEdge; + + topEdge[0] = StatusIText[0].TopEdge; + topEdge[1] = StatusIText[1].TopEdge; + + + StatusIText[0].LeftEdge = ComputeX(StatusIText[0].LeftEdge); + StatusIText[0].TopEdge = ComputeY(StatusIText[0].TopEdge); + StatusIText[1].LeftEdge = ComputeX(StatusIText[1].LeftEdge); + StatusIText[1].TopEdge = ComputeY(StatusIText[1].TopEdge); + + PrintIText(StatusWnd->RPort,StatusIText,OffX,OffY); + + StatusIText[0].LeftEdge = leftEdge[0]; + StatusIText[0].TopEdge = topEdge[0]; + StatusIText[1].LeftEdge = leftEdge[1]; + StatusIText[1].TopEdge = topEdge[1]; + + DrawBevelBox( StatusWnd->RPort, OffX + ComputeX( 3 ), + OffY + ComputeY( 38 ), + gd_StatusGadgetWidth - (ComputeX( 3 ) * 2), + ComputeY( 13 ), + GT_VisualInfo, VisualInfo, GTBB_Recessed, TRUE, + TAG_DONE ); + + box.left = OffX+ComputeX(3); + box.top = OffY+ComputeY(38); + box.width = gd_StatusGadgetWidth - (ComputeX( 3 ) * 2); + box.height = ComputeY(13); + box.center = box.left+box.width/2; +} + +//----------------------------------------------------------------------------- + +int OpenStatusWindow(char *bufPointer) +{ + struct NewGadget ng; + struct Gadget *g; + UWORD wleft, wtop, ww, wh; + struct TextFont *tf; + UWORD Row1; // +jmc+ + UWORD Row2; // +jmc+ + UWORD Row3; // +jmc+ + UWORD Row3b; // +jmc+ + UWORD Row4; // +jmc+ + UWORD West; // +jmc+ + + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: Volume=<%s>\n", __LINE__, volumeName)); + + tf = OpenDiskFont(Font); + + if ( ! ( g = CreateContext( &StatusGList ))) + return( 1L ); + + StatusWdt = (STRPTR) GetLocString(MSGID_GUI_STATUSWINDOW_TITLE); + + sprintf(StatusTextDrive, GetLocString(MSGID_GUI_STATUSWINDOW_FORMATTING_DRIVE), volumeName, NewVolumeName, ShortDostype); + Row1 = GetLenForText2((STRPTR) StatusTextDrive, 0,tf); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: LENGHT: Row1=[%ld] \n", __LINE__, Row1)); + + SpaceChar = FontX; + + West = Row1; + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: --> \"%s\" as \"%s\"...\n", __LINE__, volumeName, NewVolumeName)); + + + if (NsdSupport==TRUE) + sprintf(StatusTextNSDSupport, GetLocString(MSGID_GUI_STATUSWINDOW_DEVICE_64BIT), deviceName); + else + sprintf(StatusTextNSDSupport, GetLocString(MSGID_GUI_STATUSWINDOW_DEVICE_NO64BIT), deviceName); + + Row2 = GetLenForText2((STRPTR) StatusTextNSDSupport, 0,tf); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: LENGHT: Row2=[%ld]\n", __LINE__, Row2)); + + if (Row2 > West) + West = Row2; + +//------ Get string lenght of "Formatting" and "Verifying" strings ------------------- + + Row3 = GetLenForText(MSGID_GUI_FORMATTING_CYLINDER, 0, tf) + (SpaceChar * 4); + if (Row3 > West) + West = Row3; + + Row3b = GetLenForText(MSGID_GUI_VERIFYING_CYLINDER, 0, tf) + (SpaceChar * 4); + if (Row3b > West) + West = Row3b; + +//------------------------------------------------------------------------------------- + + Row4 = GetLenForText(MSGID_GUI_STATUSWINDOW_ABORT, 0, tf) + (SpaceChar * 2); + + if (Row4 > West) + West = Row4; + + ww = West + SpaceChar + Scr->WBorRight + Scr->WBorLeft; + + CloseFont(tf); + +//---------------------------------- Check Window size according to Screen width and height ---------------------------------------------------------- + + ForceFontTopaz8 = ComputeFont( ww, StatusHeight ); + +//---------------------------------- Window width size initialization once again ---------------------------------------------------------------------- + + if (ForceFontTopaz8) + { + Font->ta_Name = (STRPTR)"topaz.font"; + FontX = FontY = Font->ta_YSize = 8; + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: ForceFontTopaz8=[%ld] Font Name = <%s> X=%ld / Y=%ld ScreenBarH = %ld\n", \ + __LINE__, ForceFontTopaz8, Font->ta_Name, (LONG) FontX, (LONG) FontY, (LONG) OffY)); + + tf = OpenDiskFont(Font); + + StatusWdt = (STRPTR) GetLocString(MSGID_GUI_STATUSWINDOW_TITLE); + + sprintf(StatusTextDrive, GetLocString(MSGID_GUI_STATUSWINDOW_FORMATTING_DRIVE), volumeName, NewVolumeName, ShortDostype); + Row1 = GetLenForText2((STRPTR) StatusTextDrive, 0,tf); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: LENGHT: Row1=[%ld] \n", __LINE__, Row1)); + + SpaceChar = FontX; + + West = Row1; + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: --> \"%s\" as \"%s\"...\n", __LINE__, volumeName, NewVolumeName)); + + if (NsdSupport==TRUE) + sprintf(StatusTextNSDSupport, GetLocString(MSGID_GUI_STATUSWINDOW_DEVICE_64BIT), deviceName); + else + sprintf(StatusTextNSDSupport, GetLocString(MSGID_GUI_STATUSWINDOW_DEVICE_NO64BIT), deviceName); + + Row2 = GetLenForText2((STRPTR) StatusTextNSDSupport, 0,tf); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: LENGHT: Row2=[%ld]\n", __LINE__, Row2)); + + if (Row2 > West) + West = Row2; + + //------ Get string lenght of "Formatting" and "Verifying" strings ------------------- + + Row3 = GetLenForText(MSGID_GUI_FORMATTING_CYLINDER, 0, tf) + (SpaceChar * 6); + if (Row3 > West) + West = Row3; + + Row3b = GetLenForText(MSGID_GUI_VERIFYING_CYLINDER, 0, tf) + (SpaceChar * 6); + if (Row3b > West) + West = Row3b; + + //------------------------------------------------------------------------------------- + + Row4 = GetLenForText(MSGID_GUI_STATUSWINDOW_ABORT, 0, tf) + (SpaceChar * 2); + + if (Row4 > West) + West = Row4; + + ww = West + SpaceChar + Scr->WBorRight + Scr->WBorLeft; + + CloseFont(tf); + } + + wh = ComputeY( StatusHeight ); + + StatusWidth = ww; + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: NsdSupport=%ld TextNSDSupport=<%s>\n", __LINE__, NsdSupport, StatusTextNSDSupport)); + +//- ROW3 - Status gadget - (Formatting / Verifying) ---------------------------------------------------------------------------------------------------- + + gd_StatusGadgetWidth = ww - Scr->WBorRight - Scr->WBorLeft; + + ng.ng_LeftEdge = OffX + ComputeX( 3 ); + ng.ng_TopEdge = OffY + ComputeY( 22 ); + ng.ng_Width = gd_StatusGadgetWidth - (ComputeX( 3 ) * 2); + ng.ng_Height = ComputeY( 13 ); + ng.ng_GadgetText = NULL; + ng.ng_TextAttr = Font; + ng.ng_GadgetID = GD_StatusGadget; + ng.ng_Flags = 0; + ng.ng_VisualInfo = VisualInfo; + + g = CreateGadget( TEXT_KIND, g, &ng, GTTX_Border, TRUE, TAG_DONE ); + + StatusGadgets[ 0 ] = g; + +//- ROW 4 - "_Stop" button gadget ----------------------------------------------------------------------------------------------------------------------- + + ng.ng_LeftEdge = (ww/2) - (Row4/2); + ng.ng_TopEdge = OffY + ComputeY( 54 ); + ng.ng_Width = Row4; + ng.ng_GadgetText = (STRPTR) GetLocString(MSGID_GUI_STATUSWINDOW_ABORT); + ng.ng_GadgetID = GD_StopGadget; + ng.ng_Flags = PLACETEXT_IN; + + g = CreateGadget( BUTTON_KIND, g, &ng, GT_Underscore, '_', TAG_DONE ); + + StatusGadgets[ 1 ] = g; + + if ( ! g ) + return( 2L ); + + wleft = ((Scr->Width/2) - ((ww + Scr->WBorRight + Scr->WBorLeft)/2)); + wtop = ((Scr->Height/2) - ((wh + Scr->BarHeight + Scr->WBorTop + Scr->WBorBottom)/2)); + + if ( ! ( StatusWnd = OpenWindowTags( NULL, + WA_Left, wleft, + WA_Top, wtop, + WA_Width, ww, + WA_Height, wh + OffY + Scr->WBorBottom, + WA_IDCMP, IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW|IDCMP_VANILLAKEY|BUTTONIDCMP, + WA_Flags, WFLG_ACTIVATE|WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_SMART_REFRESH, + WA_Gadgets, StatusGList, + WA_Title, StatusWdt, + WA_ScreenTitle, TITLE_NAME, + WA_PubScreen, Scr, + TAG_DONE ))) + return( 4L ); + + GT_RefreshWindow( StatusWnd, NULL ); + + tf = OpenDiskFont(Font); // +jmc+ + SetFont(StatusWnd->RPort, tf); // +jmc+ + StatusRender(); + CloseFont(tf); // +jmc+ + + return( 0L ); +} + +//----------------------------------------------------------------------------- + +void CloseStatusWindow( void ) +{ + if ( StatusWnd ) + { + CloseWindow( StatusWnd ); + StatusWnd = NULL; + } + + if ( StatusGList ) + { + FreeGadgets( StatusGList ); + StatusGList = NULL; + } +} + +//----------------------------------------------------------------------------- + +static LONG GetLenForText(LONG LMsgid, LONG Current, struct TextFont *tf) +{ + CONST_STRPTR pString; /* pointer to the string retrieved from the locale table */ + LONG lPixlen; /* The pixel length of the string */ + struct RastPort rast; + + InitRastPort(&rast); + SetFont(&rast, tf); + + + pString = GetLocString(LMsgid); + + lPixlen = TextLength(&rast, (STRPTR) pString, strlen(pString)); + + if (lPixlen > Current) + Current = lPixlen; + + return Current; +} + +static LONG GetLenForText2(STRPTR LString, LONG Current, struct TextFont *tf) +{ + LONG lPixlen; /* The pixel length of the string */ + struct RastPort rast; + + InitRastPort(&rast); + SetFont(&rast, tf); + + + lPixlen = TextLength(&rast, LString, strlen(LString)); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: Current=[%ld] LString len=[%ld] lPixlen=[%ld]\n", __LINE__, Current, strlen(LString), lPixlen)); + + if (lPixlen > Current) + Current = lPixlen; + + return Current; +} + diff --git a/scalos/Modules/FormatDisk.Gadtools/GUI.h b/scalos/Modules/FormatDisk.Gadtools/GUI.h new file mode 100755 index 000000000..56003fe2c --- /dev/null +++ b/scalos/Modules/FormatDisk.Gadtools/GUI.h @@ -0,0 +1,91 @@ +// Gui.h +// $Date$ +// $Revision$ + +/* + * Source generated with GadToolsBox V1.3 + * which is (c) Copyright 1991,92 Jaba Development + */ + +#ifndef GUI_H +#define GUI_H + +#include + +// #define max(a,b) ((a) > (b) ? (a) : (b)) + +#define GD_DeviceGad 0 +#define GD_NameGadget 1 +#define GD_FFSGadget 2 +#define GD_IntlGadget 3 +#define GD_VerifyGadget 4 +#define GD_IconGadget 5 +#define GD_DirCacheGadget 6 // +jmc+ +#define GD_TrashCanNameGadget 7 // +jmc+ +#define GD_OKGadget 8 +#define GD_QuickFmtGadget 9 // +jmc+ +#define GD_CancelGadget 10 + +#define GDX_DeviceGad 0 +#define GDX_NameGadget 1 +#define GDX_FFSGadget 2 +#define GDX_IntlGadget 3 +#define GDX_VerifyGadget 4 +#define GDX_IconGadget 5 +#define GDX_DirCacheGadget 6 // +jmc+ +#define GDX_TrashCanNameGadget 7 // +jmc+ +#define GDX_OKGadget 8 +#define GDX_QuickFmtGadget 9 // +jmc+ +#define GDX_CancelGadget 10 + + +#define GD_StatusGadget 0 +#define GD_StopGadget 1 + +#define GDX_StatusGadget 0 +#define GDX_StopGadget 1 + +//----------------------------------------------------------------------------- + +typedef struct Rect +{ + UWORD left,top,width,height; + UWORD center; +} Rect; + +//----------------------------------------------------------------------------- + +extern struct Window *PrepWnd; +extern struct Window *StatusWnd; +extern struct Gadget *PrepGadgets[11]; // Number gadgets. +extern struct Gadget *StatusGadgets[2]; + +extern int SetupScreen( void ); +extern void CloseDownScreen( void ); +extern int OpenPrepWindow( char *, BOOL, BOOL, BOOL); +extern void ClosePrepWindow( void ); +extern void StatusRender( void ); +extern int OpenStatusWindow(char *bufPointer); +extern void CloseStatusWindow( void ); + +extern BOOL NsdSupport; +extern BOOL QuickFmt; +extern BOOL Verify; +extern BOOL Icon; + +extern char NewVolumeName[64]; + +extern Rect box; + +extern ULONG FindUnderscoredToLower(STRPTR text); + +//----------------------------------------------------------------------------- + +#define d1(x) ; +#define d2(x) x; + +extern int kprintf(CONST_STRPTR, ...); +extern int KPrintF(CONST_STRPTR, ...); + + +#endif /* GUI_H */ diff --git a/scalos/Modules/FormatDisk.Gadtools/GetInputFromWindow.c b/scalos/Modules/FormatDisk.Gadtools/GetInputFromWindow.c new file mode 100644 index 000000000..79d7e47e2 --- /dev/null +++ b/scalos/Modules/FormatDisk.Gadtools/GetInputFromWindow.c @@ -0,0 +1,243 @@ +// GetInputFromWindow.c +// $Date$ +// $Revision$ + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "Format.h" +#define FormatDisk_NUMBERS +#include STR(SCALOSLOCALE) + +#include "GUI.h" + +//----------------------------------------------------------------------------- + +extern BOOL FFS; +extern BOOL intl; +extern BOOL DirCache; + +//----------------------------------------------------------------------------- +static void GetMsgidUnderScore(void); +//static ULONG FindUnderscoredToLower(STRPTR text); + +static UWORD Name_key, FFS_key, INTL_key, Verify_key, WithTrash_key; +static UWORD Dircache_key, Trash_key, Format_key, QuickFormat_key, Cancel_key; + + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ + +static void GetMsgidUnderScore(void) +{ + Name_key = FindUnderscoredToLower( (STRPTR) GetLocString(MSGID_GADGET_DEVNAME)); + + FFS_key = FindUnderscoredToLower( (STRPTR) GetLocString(MSGID_GADGET_FFS)); + + INTL_key = FindUnderscoredToLower( (STRPTR) GetLocString(MSGID_GADGET_INTL)); + + Verify_key = FindUnderscoredToLower( (STRPTR) GetLocString(MSGID_GADGET_VERIFY)); + + WithTrash_key = FindUnderscoredToLower( (STRPTR) GetLocString(MSGID_GADGET_TRASHCAN)); + + Dircache_key = FindUnderscoredToLower( (STRPTR) GetLocString(MSGID_GADGET_DIRCACHE)); + + Trash_key = FindUnderscoredToLower( (STRPTR) GetLocString(MSGID_GADGET_TRASHCAN_NAME)); + + Format_key = FindUnderscoredToLower( (STRPTR) GetLocString(MSGID_GADGET_GUI_FORMAT)); + + QuickFormat_key = FindUnderscoredToLower( (STRPTR) GetLocString(MSGID_GADGET_QUICK_FORMAT)); + + Cancel_key = FindUnderscoredToLower( (STRPTR) GetLocString(MSGID_GADGET_GUI_CANCEL)); +} + +//----------------------------------------------------------------------------- + +ULONG FindUnderscoredToLower(STRPTR text) +{ + ULONG c; + while(( c = *text++)) + { + if( c == '_' ) return ToLower(*text); + } + return 0; +} +//----------------------------------------------------------------------------- + +// Get input from the original window +prepResult getPrepInput(void) +{ + struct IntuiMessage *mesg; + ULONG class; + ULONG code; + struct Gadget *gadget; + struct TagItem tags[2]; + + GetMsgidUnderScore(); + + // Setup tags that will be used to toggle the states of checkbox gadgets + tags[0].ti_Tag = GTCB_Checked; + tags[1].ti_Tag = TAG_DONE; + tags[1].ti_Data = 0UL; + + // Loop until the user presses 'OK' or 'Cancel' + for(;;) + { + // Wait for input + Wait(1<UserPort->mp_SigBit); + + // Get the input + mesg = GT_GetIMsg(PrepWnd->UserPort); + + // Loop while there are messages to be processed + while (mesg != NULL) + { + // Get the message type, etc. + class = mesg->Class; + code = mesg->Code; + gadget = (struct Gadget *)mesg->IAddress; + + // Reply to the message + GT_ReplyIMsg(mesg); + + // Act on the message + switch(class) + { + // User clicked on close gadget. Treat it as a click on 'Cancel' + case IDCMP_CLOSEWINDOW: + return(eQuit); + + // User pressed a gadget + case IDCMP_GADGETUP: + switch(gadget->GadgetID) + { + // Checkbox gadgets + // (each toggles the appropriate status flag) + + // FastfileSystem + case GD_FFSGadget: + FFS = !FFS; + break; + + // Withe Trashcan + case GD_IconGadget: + Icon = !Icon; + break; + + // Verify + case GD_VerifyGadget: + Verify = !Verify; + break; + + // International + case GD_IntlGadget: + intl = !intl; + break; + + // DirCache + case GD_DirCacheGadget: + DirCache = !DirCache; + break; + + // OK + case GD_OKGadget: + return(eOK); + + // Quick format + case GD_QuickFmtGadget: + return(eQuick); + + // Cancel + case GD_CancelGadget: + return(eCancel); + } + break; + + // Keypress (gadget equivalents) + case IDCMP_VANILLAKEY: + if (code == Name_key) + ActivateGadget(PrepGadgets[GD_NameGadget], PrepWnd,NULL); + else if( code == FFS_key ) + { + // Toggle the checkmark state of the gadget + tags[0].ti_Data = (FFS = !FFS); + GT_SetGadgetAttrsA(PrepGadgets[GD_FFSGadget], PrepWnd,NULL, tags); + } + else if( code == INTL_key ) + { + if (!DirCache) + { + tags[0].ti_Data = (intl = !intl); + GT_SetGadgetAttrsA(PrepGadgets[GD_IntlGadget], PrepWnd,NULL, tags); + } + } + else if( code == Verify_key ) + { + tags[0].ti_Data = (Verify = !Verify); + GT_SetGadgetAttrsA(PrepGadgets[GD_VerifyGadget], PrepWnd,NULL, tags); + } + else if( code == WithTrash_key ) + { + tags[0].ti_Data = (Icon = !Icon); + GT_SetGadgetAttrsA(PrepGadgets[GD_IconGadget], PrepWnd,NULL, tags); + } + else if( code == Dircache_key ) + { + tags[0].ti_Data = (DirCache = !DirCache); + GT_SetGadgetAttrsA(PrepGadgets[GD_DirCacheGadget], PrepWnd,NULL, tags); + } + else if( code == Trash_key ) + { + if (Icon) + { + ActivateGadget(PrepGadgets[GD_TrashCanNameGadget], PrepWnd,NULL); + } + } + else if( code == Format_key ) + return(eOK); + else if( code == QuickFormat_key ) + return(eQuick); + else if( code == Cancel_key ) + return(eCancel); + + break; + } + + // Get the next message + mesg = GT_GetIMsg(PrepWnd->UserPort); + } + + // Update state of some gadgets. + GT_SetGadgetAttrs(PrepGadgets[GD_IntlGadget], PrepWnd, NULL, GA_Disabled, DirCache, TAG_DONE); + + GT_SetGadgetAttrs(PrepGadgets[GD_TrashCanNameGadget], PrepWnd, NULL, GA_Disabled, !Icon, TAG_DONE); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: SELECTED FROM GUI: FFS = %ld INTL = %ld DIRCACHE = %ld ICON = %ld VERIFY = %ld\n", + __LINE__, FFS, intl, DirCache, Icon, Verify)); + } + + return(FALSE); +} + diff --git a/scalos/Modules/FormatDisk.Gadtools/NSD_64bit.c b/scalos/Modules/FormatDisk.Gadtools/NSD_64bit.c new file mode 100755 index 000000000..c16bfb5e8 --- /dev/null +++ b/scalos/Modules/FormatDisk.Gadtools/NSD_64bit.c @@ -0,0 +1,46 @@ +// NSD_64bit.c +// $Date$ +// $Revision$ +// $Id$ + + +#include +#include +#include + +BOOL checkfor64bitcommandset(struct IOStdReq *io) +{ + // struct IOStdReq io = { }; + + struct NSDeviceQueryResult nsdqr; // +jmc+ { } ??; + LONG error; // +jmc+ = 0 + // BOOL newstyle = FALSE; + BOOL does64bit = FALSE; + UWORD *cmdcheck; + + // newstyle = FALSE; + nsdqr.SizeAvailable = 0; + nsdqr.DevQueryFormat = 0; + + io->io_Command = NSCMD_DEVICEQUERY; + io->io_Length = sizeof(nsdqr); + io->io_Data = (APTR)&nsdqr; + error = DoIO((struct IORequest *)io); + if ((!error) && (io->io_Actual >= 16) && + (nsdqr.SizeAvailable == io->io_Actual) && + (nsdqr.DeviceType == NSDEVTYPE_TRACKDISK)) + { + // Ok, this must be a new style trackdisk device + // newstyle = TRUE; + + // Is it safe to use 64 bits with this driver? We can reject + // bad mounts pretty easily via this check! + + for(cmdcheck = nsdqr.SupportedCommands; *cmdcheck; cmdcheck++) + if(*cmdcheck == NSCMD_TD_READ64) + does64bit = TRUE; + // This trackdisk style device supports the complete + // 64 bit command set without returning IOERR_NOCMD! + } + return(does64bit); +} diff --git a/scalos/Modules/FormatDisk.Gadtools/NoDebug b/scalos/Modules/FormatDisk.Gadtools/NoDebug new file mode 100644 index 000000000..49ed68d29 --- /dev/null +++ b/scalos/Modules/FormatDisk.Gadtools/NoDebug @@ -0,0 +1,3 @@ +; NoDebug +; 23 Dec 2001 16:17:11 +splat -s -o "d2(" "d1(" #?.c diff --git a/scalos/Modules/FormatDisk.Gadtools/ParseArgs.c b/scalos/Modules/FormatDisk.Gadtools/ParseArgs.c new file mode 100755 index 000000000..acfcedb9f --- /dev/null +++ b/scalos/Modules/FormatDisk.Gadtools/ParseArgs.c @@ -0,0 +1,77 @@ +// ParseArgs.c +// $Date$ +// $Revision$ +// $Id$ + + +#include +#include + +#include +#include +// #include +// #include +// #include +// #include +// #include +#include + +// Prototypes for system functions +#include +#include + +// Other headers +#include "Format.h" +#include "GUI.h" +#include + +extern SIPTR args[]; + +// Get the command-line arguments given by the user, by using ReadArgs() +void parseArgs(char *drive,char *newName,BOOL *ffs,BOOL *intl, BOOL *icons, char *TrashName, BOOL *quick, BOOL *verify) +{ + APTR r; + + // Get the arguments + r=ReadArgs("DRIVE/K/A,NAME/K/A,FFS/S,INTL=INTERNATIONAL/S,NOICONS/S,QUICK/S,NOVERIFY/S/TRASCHCAN/N",args, NULL); + + // If the user didnt specify a drive name, print an error + if(args[0] == 0L) + { + printError("You need to specify a drive to format",NULL,NULL); + if(r != NULL) + FreeArgs(r); + cleanup(200); + } + else + strcpy(drive,(char *)args[0]); + + // Likewise for a name for the newly formatted volume + if(args[1]==0L) + { + printError("You need to specify a name for the volume",NULL,NULL); + cleanup(200); + } + else + strcpy(newName,(char *)args[1]); + + // Get the four togglable settings + *ffs=(args[2]!=0); + *intl=(args[3]!=0); + *icons=(args[4]==0); + + if(args[5]==0L) + strcpy(TrashName, "Trashcan"); + else + strcpy(TrashName,(char *)args[5]); + + *quick=(args[6]!=0); + *verify=(args[7]==0); + + // Were done, so free the ReadArgs result + FreeArgs(r); + + // And return + return; +} + diff --git a/scalos/Modules/FormatDisk.Gadtools/config.mk b/scalos/Modules/FormatDisk.Gadtools/config.mk new file mode 100755 index 000000000..ed09ec8a9 --- /dev/null +++ b/scalos/Modules/FormatDisk.Gadtools/config.mk @@ -0,0 +1,51 @@ +# $Date: 2010-05-14 21:40:32 +0200 (Fr, 14. Mai 2010) $ +# $Revision: 612 $ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +SCALOS_LOCALE = $(OBJDIR)/FormatDisk_Locale.h + +CFLAGS += -D SCALOSLOCALE=$(SCALOS_LOCALE) +DEFINES += -DSCALOSLOCALE=$(SCALOS_LOCALE) + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +INCLUDES += # + +LFLAGS += # + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +INCLUDES += # + +LFLAGS += # + +DEFINES += -DINTUITION_PRE_V36_NAMES + +else + +############################################################################### +# AmigaOS + +INCLUDES += # + +LFLAGS += # + +endif +endif + diff --git a/scalos/Modules/FormatDisk.Gadtools/makefile b/scalos/Modules/FormatDisk.Gadtools/makefile new file mode 100755 index 000000000..2e85cfa8c --- /dev/null +++ b/scalos/Modules/FormatDisk.Gadtools/makefile @@ -0,0 +1,160 @@ +# MakeFile for Format_Disk.module (Gadtools) module. +# $Date$ +# $Revision$ +############################################################# + +.PHONY: dirs clean install nodebug + +############################################################# + +TOPLEVEL = / +SUBDIRMAKE = $(MAKE) -s -C +CATCOMP = CatComp +FLEXCAT = FlexCat +CC = sc +SPLAT = sc:c/splat + +CFLAGS = optimize nostackcheck nochkabort debug=s idlen=128 \ + define SCALOSLOCALE=$(SCALOS_LOCALE) \ + strmer nover streq \ + idir=sc:include/ \ + idir=include: \ + idir=//include + +LIBS = lib:sc.lib LIB:debug.lib lib:amiga.lib +CSTARTUP = LIB:c.o + +LINK = SLINK +LFLAGS = SC SD +LNFLAGS = quiet batch noicons stripdebug +LNDBFLAGS = quiet batch noicons addsym + +OBJDIR = .sasobj +MKDIR = mkdir -p +DESTTOOL = Scalos:modules/ + +SCALOS_LOCALE = $(OBJDIR)/FormatDisk_Locale.h + +############################################################# + +.SUFFIXES: .asm .cd + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +############################################################# + +NAME = .bin_os3/Format_Disk.module +DBGNAME = $(NAME).debug +CATCOMPHEADER = $(SCALOS_LOCALE) +CAT_FILE = Scalos/FormatDisk.catalog +DESTCAT = Locale:Catalogs +ALLCATS = Catalogs/français/$(CAT_FILE) \ + Catalogs/deutsch/$(CAT_FILE) + + +############################################################# + +all: dirs \ + $(NAME) \ + $(DBGNAME) \ + allcatalogs + +############################################################# + +# make all Scalos .catalogs +allcatalogs: + @$(SUBDIRMAKE) Catalogs/français/Scalos + @$(SUBDIRMAKE) Catalogs/deutsch/Scalos + +############################################################# + +SRCS = NSD_64bit.c \ + Device_Handler.c \ + FullFormat.c \ + FormatVolume.c \ + ParseArgs.c \ + Format.c \ + GetInputFromWindow.c \ + GUI.c \ + +############################################################# + +define SRCS_LIST_TO_OBJS + $(addprefix $(OBJDIR)/, $(addsuffix .o, $(foreach file, $(SRCS), \ + $(basename $(notdir $(file)))))) +endef +OBJS = $(SRCS_LIST_TO_OBJS) + +############################################################# + +$(CATCOMPHEADER) : FormatDisk.cd + @printf '\033[32mMake Catcomp header: \033[31m\033[1m$@ \033[32mfrom \033[31m$<\033[0m\n' + @$(FLEXCAT) $< $@=$(TOPLEVEL)/CatComp_h.sd + +############################################################# + +$(NAME) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LINK) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNFLAGS) + +$(DBGNAME) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LINK) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNDBFLAGS) + +############################################################# + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $*.c objectname $@ + +############################################################# + +# commands generated a catalog (.catalog) from a catalog translation (.ct) file. +.ct.catalog: + $(CATCOMP) $*.cd $< CATALOG $*.catalog VB=1 + +############################################################# + +$(OBJDIR)/NSD_64bit.o : NSD_64bit.c +$(OBJDIR)/Device_Handler.o : Device_Handler.c Format.h +$(OBJDIR)/FullFormat.o : FullFormat.c Format.h $(SCALOS_LOCALE) +$(OBJDIR)/FormatVolume.o : FormatVolume.c Format.h $(SCALOS_LOCALE) +$(OBJDIR)/ParseArgs.o : ParseArgs.c Format.h GUI.h +$(OBJDIR)/Format.o : Format.c Format.h $(SCALOS_LOCALE) GUI.h +$(OBJDIR)/GetInputFromWindow.o : GetInputFromWindow.c Format.h GUI.h +$(OBJDIR)/GUI.o : GUI.c $(SCALOS_LOCALE) Format.h GUI.h + +############################################################# + + +dirs: + @$(MKDIR) $(OBJDIR) + +############################################################# + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(NAME) \033[32mto \033[31m\033[1m$(DESTTOOL) \033[0m\n' + @copy $(NAME) $(DESTTOOL) clone + @copy $(NAME).info $(DESTTOOL) clone + @printf '\033[32mFlushing memory\033[0m\n' + @avail flush + @printf '\033[32mInstall: \033[31m\033[1m$(CAT_FILE)\033[0m\n' + -@copy 'catalogs/deutsch/$(CAT_FILE)' '$(DESTCAT)/Deutsch/Scalos/' clone + -@copy 'catalogs/français/$(CAT_FILE)' '$(DESTCAT)/français/Scalos/' clone + +############################################################# + +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + -@delete $(OBJS) $(CATCOMPHEADER) $(NAME) $(DBGNAME) + @printf '\033[0m' + +############################################################# + +nodebug: + -@$(SPLAT) -s -o "d2(" "d1(" "#?.c" + +############################################################# diff --git a/scalos/Modules/FormatDisk.Gadtools/makefile-new b/scalos/Modules/FormatDisk.Gadtools/makefile-new new file mode 100755 index 000000000..618e6e9be --- /dev/null +++ b/scalos/Modules/FormatDisk.Gadtools/makefile-new @@ -0,0 +1,103 @@ +# $Date: 2011-08-10 18:36:43 +0200 (Mi, 10. Aug 2011) $ +# $Revision: 836 $ +############################################################################## + +TOPLEVEL = $(shell pwd)/../.. + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + SDPATH=/ +else + SDPATH=../.. +endif + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(OBJDIR)/NSD_64bit.o \ + $(OBJDIR)/Device_Handler.o \ + $(OBJDIR)/FullFormat.o \ + $(OBJDIR)/FormatVolume.o \ + $(OBJDIR)/ParseArgs.o \ + $(OBJDIR)/Format.o \ + $(OBJDIR)/GetInputFromWindow.o \ + $(OBJDIR)/GUI.o \ + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Subdirs +# + +SUBDIRS = $(filter-out Catalogs/sample/Scalos, $(wildcard Catalogs/*/Scalos)) + +############################################################################## +# +# Targets +# + +NAME = Format_Disk.module +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) \ + all_subdirs + +############################################################################## + +$(OBJDIR)/%.o: $(TOOLTYPE_DIR)/%.c + $(run-cc) + +$(OBJDIR)/%.o: $(ICONOBJMCC_DIR)/%.c + $(run-cc) + +Format.c : $(OBJDIR)/FormatDisk_Locale.h + +$(OBJDIR)/FormatDisk_Locale.h : FormatDisk.cd + @$(ECHO) "FlexCat $@" + $(FLEXCAT) $< $@=$(SDPATH)/CatComp_h.sd + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + @$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) +ifneq ($(MACHINE), ppc-amigaos) + @chmod u+x $@ +endif + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) Scalos:modules/ clone + +install: install_subdirs + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* \ + $(OBJDIR)/FormatDisk_Locale.h + +clean: clean_subdirs + +############################################################################## + diff --git a/scalos/Modules/FormatDisk.MUI/Catalogs/deutsch/Scalos/FormatDiskMUI.ct b/scalos/Modules/FormatDisk.MUI/Catalogs/deutsch/Scalos/FormatDiskMUI.ct new file mode 100644 index 000000000..f04f1fefc --- /dev/null +++ b/scalos/Modules/FormatDisk.MUI/Catalogs/deutsch/Scalos/FormatDiskMUI.ct @@ -0,0 +1,203 @@ +; Rename.ct +## version $VER: FormatDiskMUI.catalog 40.1 (20 Feb 2005 22:02:39) +## codeset 0s +## language deutsch +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Neue Schublade +;Scalos NewDrawer +; +; +MSGID_OKBUTTON +Anlegen +;NewDrawer +; +; +MSGID_OKBUTTON_SHORT +n +;r +; +; +MSGID_SHORTHELP_OKBUTTON +Legt eine neue, leere Schublade\n\ +mit dem angegebenen Namen an. +;Create new drawer. +; +; +MSGID_CANCELBUTTON +Abbrechen +;Cancel +; +; +MSGID_CANCELBUTTON_SHORT +a +;c +; +; +MSGID_SHORTHELP_CANCELBUTTON +Abbrechen ohne Anlegen\n\ +einer neuer Schublade. +;Discard all changes and\n\ +;do not create anything. +; +; +MSGID_CREATE_APPLICATION_FAILED +Fehler beim Erzeugen der Anwendung.\n +;Failed to create Application.\n +; +; +MSGID_CREATE_MAINWINDOW_FAILED +Fehler beim Öffnen des Hauptfensters !\n +;Failed to open main window !\n +; +; +MSGID_OPEN_LIBRARY_FAILED +Fehler beim Öffnen von \"%s\" !\n +;Failed to open \"%s\" !\n +; +;;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Projekt +;Project +; +; +MSGID_MENU_PROJECT_ABOUT +Über... +;About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Über MUI... +;About MUI... +; +; +MSGID_MENU_PROJECT_QUIT +Beenden +;Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +Ok +;_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Rename.module V%ld.%ld\033n\n\ +%s\n\ +© 2004%s Das Scalos-Team +;\33c\033bScalos Rename.module V%ld.%ld\033n\n\ +;%s\n\ +;© 2004%s The Scalos Team +; +;----------------------------------------------------------- +; +MSGID_NEWNAME_DEFAULT +Bitte_umbenennen +;New_Drawer_Name +; +; +MSGID_TEXT_ENTERNAME +Name der neuen Schublade in \"%s\": +;Enter name for a new drawer in \"%s\" +; +; +MSGID_LABEL_ENTERNAME +Name der Schublade: +;New Drawer +; +; +MSGID_LABEL_CREATE_ICON +Piktogramm +;Create Icon +; +; +MSGID_CHECKMARK_CREATEICON_SHORTHELP +Ist dieser Schalter eingeschaltet, wird für\n\ +die neue Schublade ein Piktogramm mit erzeugt. +;If this checkbox is checked, an icon\n\ +;will be created for the new drawer. +; +; +MSGID_TITLE_ERRORREQ +Fehler bei neuer Schublade +;NewDrawer Error +; +; +MSGID_ERRORREQ_BODYTEXT +Konnte \"%s" nicht anlegen:\n\ +%s +;Could not create '%s'\n%s +; +; +MSGID_REQ_OK + _Ok +; +; +MSGID_TEXT_ENTERNAME_SHORTHELP +Pfad der neuen Schublade.\n\ +Mit dem Rollbalken am unteren Fensterrand kann\n\ +der Inhalt des Pfades hin- und hergeschoben werden,\n\ +um auch lange Pfadnamen lesen zu können. +;Path to create a new drawer.\n\n\ +;It's possible to show all content of this gadget using\n\ +;the scroller located at the bottom of the window.\n\ +;Can be usefull for large path lenght. +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +NewDrawer.module kann nicht gestartet werden +;NewDrawer.module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Wiederholen|Beenden +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\ +Die Klasse ist nicht installiert. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Sie haben momentan Version v%lu.%lu installiert und\n\ +sollten die Klasse daher aktualisieren! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Version %lu.%lu wird momentan von einer anderen Anwendung\n\ +verwendet. Wenn sie die benötigte Version installiert haben,\n\ +schließen sie alle MUI Programme und probieren es erneut. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +;+++ translateme +++ +MSGID_OPEN_PREFS_LIBRARY_FAILED +Failed to open \"%s\" !\n\ +Loading and saving of settings aren't availlables.\n +; +;----------------------------------------------------------- +; diff --git a/scalos/Modules/FormatDisk.MUI/Catalogs/deutsch/Scalos/config.mk b/scalos/Modules/FormatDisk.MUI/Catalogs/deutsch/Scalos/config.mk new file mode 100755 index 000000000..8631b0623 --- /dev/null +++ b/scalos/Modules/FormatDisk.MUI/Catalogs/deutsch/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = deutsch + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = german + +else + +############################################################################### +# AmigaOS and AROS + +LANG = deutsch + +endif +endif diff --git a/scalos/Modules/FormatDisk.MUI/Catalogs/deutsch/Scalos/makefile b/scalos/Modules/FormatDisk.MUI/Catalogs/deutsch/Scalos/makefile new file mode 100644 index 000000000..190ba9365 --- /dev/null +++ b/scalos/Modules/FormatDisk.MUI/Catalogs/deutsch/Scalos/makefile @@ -0,0 +1,14 @@ +# makefile for FormatDisk.module (translated Texts : deutsch) +# $Date$ +# $Revision$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mdeutsch\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +FormatDiskMUI.catalog : FormatDiskMUI.ct ../../../FormatDisk.cd + +All: FormatDiskMUI.catalog diff --git a/scalos/Modules/FormatDisk.MUI/Catalogs/deutsch/Scalos/makefile-new b/scalos/Modules/FormatDisk.MUI/Catalogs/deutsch/Scalos/makefile-new new file mode 100644 index 000000000..1c1c63188 --- /dev/null +++ b/scalos/Modules/FormatDisk.MUI/Catalogs/deutsch/Scalos/makefile-new @@ -0,0 +1,31 @@ +# makefile for FormatDisk.module (translated Texts : deutsch) +# $Date: 2011-07-24 10:11:00 +0200 (So, 24. Jul 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = FormatDiskMUI + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + + +$(CATNAME)MUI.catalog : $(CATNAME).ct ../../../$(CATNAME).cd + +clean: + $(RM) -f $(CATNAME)MUI.catalog + +install: + -copy $(CATNAME)MUI.catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git "a/scalos/Modules/FormatDisk.MUI/Catalogs/fran\303\247ais/Scalos/FormatDiskMUI.ct" "b/scalos/Modules/FormatDisk.MUI/Catalogs/fran\303\247ais/Scalos/FormatDiskMUI.ct" new file mode 100755 index 000000000..402b92b79 --- /dev/null +++ "b/scalos/Modules/FormatDisk.MUI/Catalogs/fran\303\247ais/Scalos/FormatDiskMUI.ct" @@ -0,0 +1,209 @@ +; $Date$ +; $Revision$ +; +## version $VER: FormatDiskMUI.catalog 40.1 (20 Feb 2005 20:27:40) +## codeset 0s +## language français +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Nouveau répertoire +; Scalos NewDrawer +; +; +MSGID_OKBUTTON +Nouveau répertoire +; NewDrawer +; +; +MSGID_OKBUTTON_SHORT +n +; r +; +; +MSGID_SHORTHELP_OKBUTTON +Création d'un\n\ +nouveau répertoire. +; Create new drawer. +; +; +MSGID_CANCELBUTTON +Annuler +; Cancel +; +; +MSGID_CANCELBUTTON_SHORT +a +; c +; +; +MSGID_SHORTHELP_CANCELBUTTON +Oublier tout changement\n\ +et ne rien créer. +; Discard all changes and\n\ +; do not create anything. +; +; +MSGID_CREATE_APPLICATION_FAILED +La création de l'application a échouée.\n +; Failed to create Application.\n +; +; +MSGID_CREATE_MAINWINDOW_FAILED +Impossible d'ouvrir la fenêtre !\n +; Failed to open main window !\n +; +; +MSGID_OPEN_LIBRARY_FAILED +Impossible d'ouvrir "%s" ! +; Failed to open \"%s\" ! +; +;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Projet +; Project +; +; +MSGID_MENU_PROJECT_ABOUT +A propos... +; About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI +A propos de MUI... +; About MUI... +; +; +MSGID_MENU_PROJECT_QUIT +Quitter +; Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; Q +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +D'acc_ord +; _OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos NewDrawer.module V\0333%ld\0332.\0333%ld\0332\033n\n\ +Compilé sous : \0333%s\0332\n\ +© 2004%s The Scalos Team +; \33c\033bScalos NewDrawer.module V%ld.%ld\033n\n\ +; %s\n\ +; © 2004%s The Scalos Team +; +;----------------------------------------------------------- +; +MSGID_NEWNAME_DEFAULT +Nouveau_Répertoire +; New_Drawer_Name +; +; +MSGID_TEXT_ENTERNAME +\033bEntrez un nom pour le nouveau répertoire dans :\033n "%s" +; Enter name for a new drawer in: \"%s\" +; +; +MSGID_LABEL_ENTERNAME +\033bNouveau répertoire\033n +; New Drawer +; +; +MSGID_LABEL_CREATE_ICON +Création d'une icône +; Create Icon +; +; +MSGID_CHECKMARK_CREATEICON_SHORTHELP +Si ce bouton est coché, une icône\n\ +sera créée pour le nouveau répertoire. +; If this checkbox is checked, an icon\n\ +; will be created for the new drawer. +; +; +MSGID_TITLE_ERRORREQ +Nouveau répertoire Erreur +; NewDrawer Error +; +; +MSGID_ERRORREQ_BODYTEXT +Impossible de créer '\033b%s\033n'\n\ +dans '\033b%s\033n' ! +; Could not create '%s' +; +; +MSGID_REQ_OK +D'acc_ord +; _Ok +; +; +MSGID_TEXT_ENTERNAME_SHORTHELP +Lieu de création du répertoire.\n\n\ +Si besoin, vous avez la possibilité d'utiliser\n\ +l'ascenseur siué au bas de la fenêtre afin\n\ +de mieux visionner le chemin d'accès.\n\ +Peut s'avèrer utile pour de longs\n\ +chemins d'accès. +; Path to create a new drawer\n\n\ +; It's possible to show all content of this gadget using\n\ +; the scroller located at the bottom of the window.\n\ +; Can be usefull for large path lenght. +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Le lancement de NewDrawer.module a échoué +;NewDrawer.module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Recommencer | Quitter +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +Celle-ci n'est pas installée. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +\n\ +La version installée est V%lu.%lu, installez-en une plus récente s'il vous plaît ! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +%lu.%lu est actuellement utilisée par d'autres applications.\n\ +\n\ +Une fois la version requise installée,\n\ +fermez tous les programmes MUI, soyez sûr que l'ancienne classe\n\ +ne soit plus présente dans la mémoire puis, essayez de nouveau. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_OPEN_PREFS_LIBRARY_FAILED +Le chargement de \"%s\" a échoué !\n\ +Le chargement et la sauvegarde des options ne sont pas disponibles.\n +; +;----------------------------------------------------------- +; diff --git "a/scalos/Modules/FormatDisk.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" "b/scalos/Modules/FormatDisk.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" new file mode 100755 index 000000000..8b7056423 --- /dev/null +++ "b/scalos/Modules/FormatDisk.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" @@ -0,0 +1,40 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = français + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = french + +else + +############################################################################### +# AmigaOS and AROS + +LANG = français + +endif +endif diff --git "a/scalos/Modules/FormatDisk.MUI/Catalogs/fran\303\247ais/Scalos/makefile" "b/scalos/Modules/FormatDisk.MUI/Catalogs/fran\303\247ais/Scalos/makefile" new file mode 100644 index 000000000..70b2e54e7 --- /dev/null +++ "b/scalos/Modules/FormatDisk.MUI/Catalogs/fran\303\247ais/Scalos/makefile" @@ -0,0 +1,14 @@ +# makefile for FormatDisk.module (translated Texts : français) +# $Date$ +# $Revision$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mfrançais\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +FormatDiskMUI.catalog : FormatDiskMUI.ct ../../../FormatDisk.cd + +All: FormatDiskMUI.catalog diff --git "a/scalos/Modules/FormatDisk.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" "b/scalos/Modules/FormatDisk.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" new file mode 100644 index 000000000..19f59371a --- /dev/null +++ "b/scalos/Modules/FormatDisk.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" @@ -0,0 +1,30 @@ +# makefile for FormatDisk.module (translated Texts : français) +# $Date: 2008-10-03 13:54:39 +0200 (Fr, 03 Okt 2008) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = FormatDiskMUI + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Modules/FormatDisk.MUI/Catalogs/sample/Scalos/FormatDisk.ct b/scalos/Modules/FormatDisk.MUI/Catalogs/sample/Scalos/FormatDisk.ct new file mode 100644 index 000000000..14eba8918 --- /dev/null +++ b/scalos/Modules/FormatDisk.MUI/Catalogs/sample/Scalos/FormatDisk.ct @@ -0,0 +1,171 @@ +; Rename.ct +## version $VER: FormatDiskMUI.catalog 40.1 (26 Feb 2005 22:01:34) +## codeset 0s +## language xxxxxx +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos NewDrawer +; +; +MSGID_OKBUTTON +NewDrawer +; +; +MSGID_OKBUTTON_SHORT +r +; +; +MSGID_SHORTHELP_OKBUTTON +Create new drawer. +; +; +MSGID_CANCELBUTTON +Cancel +; +; +MSGID_CANCELBUTTON_SHORT +c +; +; +MSGID_SHORTHELP_CANCELBUTTON +Discard all changes and\n\ +do not create anything. +; +; +MSGID_CREATE_APPLICATION_FAILED +Failed to create Application.\n +; +; +MSGID_CREATE_MAINWINDOW_FAILED +Failed to open main window !\n +; +; +MSGID_OPEN_LIBRARY_FAILED +Failed to open \"%s\" !\n +; +;;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Project +; +; +MSGID_MENU_PROJECT_ABOUT +About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI +About MUI... +; +; +MSGID_MENU_PROJECT_QUIT +Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Rename.module V%ld.%ld\033n\n\ +%s\n\ +© 2004%s The Scalos Team +; +;----------------------------------------------------------- +; +MSGID_NEWNAME_DEFAULT +New_Drawer_Name +; +; +MSGID_TEXT_ENTERNAME +Enter name for a new drawer in \"%s\" +; +; +MSGID_LABEL_ENTERNAME +New Drawer +; +; +MSGID_LABEL_CREATE_ICON +Create Icon +; +; +MSGID_CHECKMARK_CREATEICON_SHORTHELP +If this checkbox is checked, an icon\n\ +will be created for the new drawer. +; +; +MSGID_TITLE_ERRORREQ +NewDrawer Error +; +; +MSGID_ERRORREQ_BODYTEXT +Could not create '%s'\n%s +; +; +MSGID_REQ_OK + _Ok +; +; +MSGID_TEXT_ENTERNAME_SHORTHELP +Path to create a new drawer.\n\n\ +It's possible to show all content of this gadget using\n\ +the scroller located at the bottom of the window.\n\ +Can be usefull for large path lenght. +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +NewDrawer.module Prefs startup failed +;NewDrawer.module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Try again|Quit +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_OPEN_PREFS_LIBRARY_FAILED +Failed to open \"%s\" !\n\ +Loading and saving of settings aren't availlables.\n +; +;----------------------------------------------------------- +; diff --git a/scalos/Modules/FormatDisk.MUI/FormatDisk.c b/scalos/Modules/FormatDisk.MUI/FormatDisk.c new file mode 100755 index 000000000..407975c17 --- /dev/null +++ b/scalos/Modules/FormatDisk.MUI/FormatDisk.c @@ -0,0 +1,1237 @@ +// FormatDisk.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include // +jmc+ + +#include "FormatDisk.h" + +#define FormatDiskMUI_NUMBERS +#define FormatDiskMUI_ARRAY +#define FormatDiskMUI_CODE +#include STR(SCALOSLOCALE) + +//---------------------------------------------------------------------------- + +#define VERSION_MAJOR 40 +#define VERSION_MINOR 1 + +//---------------------------------------------------------------------------- + +#define MAX_DEV_NAME 128 + +struct FileSystemName + { + ULONG fsn_DosType; // DosType + CONST_STRPTR fsn_Name; + }; + +#define KeyButtonHelp(name,key,HelpText)\ + TextObject,\ + ButtonFrame,\ + MUIA_Font , MUIV_Font_Button,\ + MUIA_Text_Contents, name,\ + MUIA_Text_PreParse, "\33c",\ + MUIA_Text_HiChar , key,\ + MUIA_ControlChar , key,\ + MUIA_InputMode , MUIV_InputMode_RelVerify,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShortHelp , HelpText,\ + MUIA_CycleChain , TRUE,\ + End + +#define CheckMarkHelp(selected, HelpTextID)\ + ImageObject,\ + ImageButtonFrame,\ + MUIA_InputMode , MUIV_InputMode_Toggle,\ + MUIA_Image_Spec , MUII_CheckMark,\ + MUIA_Image_FreeVert , TRUE,\ + MUIA_Selected , selected,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShowSelState , FALSE,\ + MUIA_CycleChain , TRUE,\ + MUIA_ShortHelp , GetLocString(HelpTextID), \ + End + +#if defined(MUII_StringBack) + #define StringBack MUIA_Background, MUII_StringBack +#else /* MUII_StringBack */ + #define StringBack MUIA_Background, MUII_TextBack +#endif /* MUII_StringBack */ + +//---------------------------------------------------------------------------- + +static BOOL OpenLibraries(void); +static void CloseLibraries(void); +static SAVEDS(APTR) INTERRUPT OpenAboutMUIHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT OpenAboutHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT SelectDeviceHookFunc(struct Hook *hook, Object *o, Msg msg); +static STRPTR GetLocString(ULONG MsgId); +static BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev); +static void FillDeviceList(void); +static void BToCString(BSTR BName, STRPTR CName, size_t Length); +static BOOL IsFssmValid(struct FileSysStartupMsg *fssm); +static void SelectDevice(CONST_STRPTR DevName); +static BOOL IsDiskFormatted(CONST_STRPTR DevName); +static void StripTrailingChar(STRPTR String, char CharToRemove); +static ULONG GetDosType(CONST_STRPTR DevName, STRPTR ExecDevName, size_t MaxLength, ULONG *UnitNumber); +static CONST_STRPTR GetFileSystemName(ULONG DosType, STRPTR Buffer, size_t MaxLength); +static STRPTR GetDosTypePrintableString(UBYTE dosType, STRPTR Buffer, size_t MaxLength); +static void GetCapacityString(STRPTR Buffer, size_t MaxLength, const struct InfoData *id); + +//---------------------------------------------------------------------------- + +#if !defined(__amigaos4__) && !defined(__AROS__) +#include + +long _stack = 16384; // minimum stack size, used by SAS/C startup code +#endif + +//---------------------------------------------------------------------------- + +extern struct ExecBase *SysBase; +struct IntuitionBase *IntuitionBase = NULL; +T_LOCALEBASE LocaleBase = NULL; +#ifndef __amigaos4__ +T_UTILITYBASE UtilityBase = NULL; +#endif +struct Library *MUIMasterBase = NULL; +struct Library *IconBase = NULL; +struct Library *IconobjectBase = NULL; + +#ifdef __amigaos4__ +struct IntuitionIFace *IIntuition = NULL; +struct LocaleIFace *ILocale = NULL; +struct MUIMasterIFace *IMUIMaster = NULL; +struct IconIFace *IIcon = NULL; +struct IconobjectIFace *IIconobject = NULL; +#endif + +static struct Catalog *gb_Catalog; + +static struct Hook AboutHook = { { NULL, NULL }, HOOKFUNC_DEF(OpenAboutHookFunc), NULL }; +static struct Hook AboutMUIHook = { { NULL, NULL }, HOOKFUNC_DEF(OpenAboutMUIHookFunc), NULL }; +static struct Hook SelectDeviceHook = { { NULL, NULL }, HOOKFUNC_DEF(SelectDeviceHookFunc), NULL }; + +//---------------------------------------------------------------------------- + +static const struct FileSystemName FsList[] = +{ + /* BSD disklabel in MSDOS partitions */ + {FS_BSD_DISKLABEL_MSDOS_SWAP , "BSD swap"}, /* "BSD\1" */ + {FS_BSD_DISKLABEL_MSDOS_V6 , "BSD version 6"}, /* "BSD\2" */ + {FS_BSD_DISKLABEL_MSDOS_V7 , "BSD version 7"}, /* "BSD\3" */ + {FS_BSD_DISKLABEL_MSDOS_SYSV , "BSD System V"}, /* "BSD\4" */ + {FS_BSD_DISKLABEL_MSDOS_41 , "4.1 BSD"}, /* "BSD\5" */ + {FS_BSD_DISKLABEL_MSDOS_8TH , "8th edition BSD"}, /* "BSD\6" */ + {FS_BSD_DISKLABEL_MSDOS_42 , "4.2 BSD"}, /* "BSD\7" */ + {FS_BSD_DISKLABEL_MSDOS_MSDOS , "BSD MSDOS"}, /* "BSD\8" */ + {FS_BSD_DISKLABEL_MSDOS_44LFS , "4.4 BSD LFS"}, /* "BSD\9" */ + {FS_BSD_DISKLABEL_MSDOS_UNKNOWN, "BSD unknown"}, /* "BSD\a" */ + {FS_BSD_DISKLABEL_MSDOS_HPFS , "BSD OS/2 HPFS"}, /* "BSD\b" */ + {FS_BSD_DISKLABEL_MSDOS_ISO9660, "BSD ISO9660"}, /* "BSD\c" */ + {FS_BSD_DISKLABEL_MSDOS_BOOT , "BSD boot"}, /* "BSD\d" */ + {FS_BSD_DISKLABEL_MSDOS_AFFS , "BSD Amiga AFFS"}, /* "BSD\e" */ + {FS_BSD_DISKLABEL_MSDOS_HFS , "BSD Apple HFS"}, /* "BSD\f" */ + + /* OSF (alpha) */ + {FS_OFS_LINUX_SWAP , "OSF BSD/Linux swap"}, /* "OFS\1" */ + {FS_OFS_BSD_V6 , "OSF BSD version 6"}, /* "OFS\2" */ + {FS_OFS_BSD_V7 , "OSF BSD version 7"}, /* "OFS\3" */ + {FS_OFS_BSD_SYSV , "OSF BSD System V"}, /* "OFS\4" */ + {FS_OFS_BSD_41 , "OSF 4.1 BSD"}, /* "OFS\5" */ + {FS_OFS_BSD_8TH , "OSF 8th edition BSD"}, /* "OFS\6" */ + {FS_OFS_BSD_42 , "OSF 4.2 BSD"}, /* "OFS\7" */ + {FS_OFS_LINUX_NATIVE, "OSF Linux native"}, /* "OFS\8" */ + {FS_OFS_BSD_44LFS , "OSF 4.4 BSD LFS"}, /* "OFS\9" */ + {FS_OFS_UNKNOWN , "OSF unknown"}, /* "OFS\a" */ + {FS_OFS_HPFS , "OSF OS/2 HPFS"}, /* "OFS\b" */ + {FS_OFS_ISO9660 , "OSF ISO9660"}, /* "OFS\c" */ + {FS_OFS_BOOT , "OSF boot"}, /* "OFS\d" */ + {FS_OFS_AFFS , "OSF Amiga AFFS"}, /* "OFS\e" */ + {FS_OFS_HFS , "OSF Apple HFS"}, /* "OFS\f" */ + {FS_OFS_ADVFS , "OSF Digital AdvFS"}, /* "OFS\1\0" */ + + /* SUN */ + {FS_SUN_EMPTY , "Sun empty"}, /* "SUN\0" */ + {FS_SUN_BOOT , "Sun boot"}, /* "SUN\1" */ + {FS_SUN_SUNOS_ROOT , "SunOS root"}, /* "SUN\2" */ + {FS_SUN_SUNOS_SWAP , "SunOS swap"}, /* "SUN\3" */ + {FS_SUN_SUNOS_USR , "SunOS usr"}, /* "SUN\4" */ + {FS_SUN_WHOLE , "Sun whole disk"}, /* "SUN\5" */ + {FS_SUN_SUNOS_STAND , "SunOS stand"}, /* "SUN\6" */ + {FS_SUN_SUNOS_VAR , "SunOS var"}, /* "SUN\7" */ + {FS_SUN_SUNOS_HOME , "SunOS home"}, /* "SUN\8" */ + {FS_SUN_LINUX_MINIX , "Sun Linux minix"}, /* "SUN\8\1" */ + {FS_SUN_LINUX_SWAP , "Sun Linux swap"}, /* "SUN\8\2" */ + {FS_SUN_LINUX_NATIVE, "Sun Linux native"}, /* "SUN\8\3" */ + + /* Amiga */ + {FS_AMIGA_GENERIC_BOOT , "Amiga generic boot"}, /* "BOOU" */ + {FS_AMIGA_OFS , "OFS"}, /* "DOS\0" */ + {FS_AMIGA_FFS , "FFS"}, /* "DOS\1" */ + {FS_AMIGA_OFS_INTL , "OFS Intl."}, /* "DOS\2" */ + {FS_AMIGA_FFS_INTL , "FFS Intl."}, /* "DOS\3" */ + {FS_AMIGA_OFS_DC_INTL , "OFS DC Intl."}, /* "DOS\4" */ + {FS_AMIGA_FFS_DC_INTL , "FFS DC Intl."}, /* "DOS\5" */ + {FS_AMIGA_OFS_LNFS , "OFS LNFS"}, /* "DOS\6" */ + {FS_AMIGA_FFS_LNFS , "FFS LNFS"}, /* "DOS\7" */ + {FS_AMIGA_MUFS_FFS_INTL , "muFS FFS Intl."}, /* "muFS" */ + {FS_AMIGA_MUFS_OFS , "muFS OFS"}, /* "muF\0" */ + {FS_AMIGA_MUFS_FFS , "muFS FFS"}, /* "muF\1" */ + {FS_AMIGA_MUFS_OFS_INTL , "muFS OFS Intl"}, /* "muF\2" */ + {FS_AMIGA_MUFS_FFS_INTL2, "muFS FFS Intl."}, /* "muF\3", same as muFS */ + {FS_AMIGA_MUFS_OFS_DC , "muFS OFS DC"}, /* "muF\4" */ + {FS_AMIGA_MUFS_FFS_DC , "muFS FFS DC"}, /* "muF\5" */ + {FS_AMIGA_LINUX_NATIVE , "Amiga Linux native"}, /* "LNX\0" */ + {FS_AMIGA_LINUX_EXT2 , "Amiga Linux ext2"}, /* "EXT2" */ + {FS_AMIGA_LINUX_SWAP , "Amiga Linux swap"}, /* "SWAP" */ + {FS_AMIGA_LINUX_SWAP2 , "Amiga Linux swap"}, /* "SWP\0", same as SWAP */ + {FS_AMIGA_LINUX_MINIX , "Amiga Linux minix"}, /* "MNX\0" */ + {FS_AMIGA_AMIX_0 , "Amix 0"}, /* "UNI\0" */ + {FS_AMIGA_AMIX_1 , "Amix 1"}, /* "UNI\1" */ + {FS_AMIGA_NETBSD_ROOT , "Amiga NetBSD root"}, /* "NBR\7" */ + {FS_AMIGA_NETBSD_SWAP , "Amiga NetBSD swap"}, /* "NBS\1" */ + {FS_AMIGA_NETBSD_OTHER , "Amiga NetBSD other"}, /* "NBU\7" */ + {FS_AMIGA_PFS0 , "PFS 0"}, /* "PFS\0" */ /* XXX: not sure about the PFS ones.. ask.. */ + {FS_AMIGA_PFS1 , "PFS 1"}, /* "PFS\1" */ /* XXX: not sure about the PFS ones.. ask.. */ + {FS_AMIGA_PFS2 , "PFS 2"}, /* "PFS\2" */ + {FS_AMIGA_PDS2 , "PFS 2 SCSIdirect"}, /* "PDS\0" */ + {FS_AMIGA_PFS3 , "PFS 3"}, /* "PFS\3" */ + {FS_AMIGA_PDS3 , "PFS 3 SCSIdirect"}, /* "PDS\3" */ + {FS_AMIGA_MUPFS , "PFS Multiuser"}, /* "muPF" */ + {FS_AMIGA_AFS , "AFS"}, /* "AFS\0" */ + {FS_AMIGA_AFS_EXP , "AFS (experimental)"}, /* "AFS\1" */ + {FS_AMIGA_CDISO , "CDROM ISO"}, /* "CD01" can be AmiCDFS, CBM's FS or CDrive in ISO mode */ + {FS_AMIGA_CDHSF , "CDROM HSF"}, /* "CD00" HighSierra */ + {FS_AMIGA_CDDA , "CDROM CDDA"}, /* "CDDA" audio CD */ + {FS_AMIGA_CDRIVE , "CDrive or AmiCDFS"}, /* "CDFS" used by AmiCDFS and CDrive, CDrive changes the dostype to ISO, HighSierra or CDDA then */ + {FS_AMIGA_ASIMCDFS , "AsimCDFS"}, /* */ + {FS_AMIGA_HFS , "Macintosh HFS"}, /* "MAC\0" */ + {FS_AMIGA_MSDOS , "MSDOS disk"}, /* "MSD\0" */ + {FS_AMIGA_MSDOS_HF , "MSDOS PC-Task hardfile"}, /* "MSH\0" */ + {FS_AMIGA_BFFS , "BFFS"}, /* "BFFS" */ + {FS_AMIGA_SFS , "SFS"}, /* "SFS\0 */ + + /* Those are special amiga stuff */ + {FS_AMIGA_BAD , "Unreadable disk"}, /* "BAD\0" */ + {FS_AMIGA_NDOS, "Not really dos"}, /* "NDOS" */ + {FS_AMIGA_KICK, "Kickstart disk"}, /* "KICK" */ + + /* Atari */ + {FS_ATARI_GEMDOS , "Atari GEMDOS (<32MB)"}, /* "AGEM" */ + {FS_ATARI_GEMDOSBIG , "Atari GEMDOS (>32MB)"}, /* "ABGM" */ + {FS_ATARI_LINUX , "Atari Linux"}, /* LNX */ + {FS_ATARI_LINUX_SWAP , "Atari Linux swap"}, /* SWP */ + {FS_ATARI_LINUX_MINIX , "Atari Linux minix"}, /* MIX */ + {FS_ATARI_LINUX_MINIX2, "Atari Linux minix"}, /* MNX */ + {FS_ATARI_HFS , "Atari HFS"}, /* MAC */ + {FS_ATARI_SYSV_UNIX , "Atari SysV unix"}, /* UNX */ + {FS_ATARI_RAW , "Atari raw"}, /* RAW */ + {FS_ATARI_EXTENDED , "Atari extended"}, /* XGM */ + + /* Macintosh */ + {FS_MAC_PARTITION_MAP , "Mac partition map"}, /* "MAC\0" */ + {FS_MAC_MACOS_DRIVER , "MacOS driver"}, /* "MAC\1" */ + {FS_MAC_MACOS_DRIVER_43 , "MacOS driver 4.3"}, /* "MAC\2" */ + {FS_MAC_MACOS_HFS , "MacOS HFS"}, /* "MAC\4" */ + {FS_MAC_MACOS_MFS , "MacOS MFS"}, /* "MAC\5" */ + {FS_MAC_SCRATCH , "Mac scratch"}, /* "MAC\6" */ + {FS_MAC_PRODOS , "Mac ProDOS"}, /* "MAC\7" */ + {FS_MAC_FREE , "Mac free"}, /* "MAC\8" */ + {FS_MAC_LINUX_SWAP , "Mac Linux swap"}, /* "MAC\9" */ + {FS_MAC_AUX , "Mac A/UX"}, /* "MAC\a" */ + {FS_MAC_MSDOS , "Mac MSDOS"}, /* "MAC\b" */ + {FS_MAC_MINIX , "Mac minix"}, /* "MAC\c" */ + {FS_MAC_AFFS , "Mac Amiga AFFS"}, /* "MAC\d" */ + {FS_MAC_LINUX_NATIVE , "Mac Linux native"}, /* "MAC\e" */ + {FS_MAC_NEWWORLD , "Mac NewWorld bootblock"}, /* "MAC\f" */ + {FS_MAC_MACOS_ATA , "MacOS ATA driver"}, /* "MAC\1\0" */ + {FS_MAC_MACOS_FW_DRIVER , "MacOS FW driver"}, /* "MAC\1\1" */ + {FS_MAC_MACOS_IOKIT , "MacOS IOKit"}, /* "MAC\1\2" */ + {FS_MAC_MACOS_PATCHES , "MacOS patches"}, /* "MAC\1\3" */ + {FS_MAC_MACOSX_BOOT , "MacOSX bootloader"}, /* "MAC\1\4" */ + {FS_MAC_MACOSX_LOADER , "MacOSX loader"}, /* "MAC\1\5" */ + {FS_MAC_UFS , "Mac UFS"}, /* "MAC\1\6" */ + + /* Acorn */ + {FS_ACORN_ADFS , "Acorn ADFS"}, /* "ARM\1" */ + {FS_ACORN_LINUX_MAP , "Acorn Linux partitionmap"}, /* "ARM\2" */ + {FS_ACORN_LINUX_EXT2 , "Acorn Linux ext2"}, /* "ARM\3" */ + {FS_ACORN_LINUX_SWAP , "Acorn Linux swap"}, /* "ARM\4" */ + {FS_ACORN_ADFS_ICS , "Acorn ADFS (ICS/APDL)"}, /* "ARM\5" */ + {FS_ACORN_LINUX_EXT2_ICS, "Acorn Linux ext2 (ICS/APDL)"}, /* "ARM\6" */ + {FS_ACORN_LINUX_SWAP_ICS, "Acorn Linux swap (ICS/APDL)"}, /* "ARM\7" */ + + /* Sinclair QL */ + {FS_SINCLAIR_QL5A, "Sinclair QL 720k"}, /* "QL5A" */ + {FS_SINCLAIR_QL5B, "Sinclair QL 1440k"}, /* "QL5B" */ + + /* Spectrum */ + {FS_SPECTRUM_DISCIPLE, "Spectrum Disciple"}, /* "ZXS\0" */ + {FS_SPECTRUM_UNIDOS , "Spectrum UniDos"}, /* "ZXS\1" */ + {FS_SPECTRUM_SAMDOS , "Spectrum SamDos"}, /* "ZXS\2" */ + {FS_SPECTRUM_OPUS , "Spectrum Opus (180k)"}, /* "ZXS\3" */ + + /* Archimedes */ + {FS_ARCHIMEDES_D, "Archimedes (D)"}, /* "ARMD" */ + {FS_ARCHIMEDES_E, "Archimedes (E)"}, /* "ARME" */ + + /* CP/M */ + {FS_CPM, "CP/M"}, /* "CPM\2" */ + + /* C64 */ + {FS_C64, "C64"}, /* "1541" */ + + {0, NULL}, +}; + +//---------------------------------------------------------------------------- + +static Object *APP_Main; +static Object *WIN_Main; +static Object *WIN_AboutMUI; +static Object *NListDosDevices; +static Object *StringLabel; +static Object *TextFormatted; +static Object *TextDosType; +static Object *TextDeviceName; +static Object *CancelButton; +static Object *ButtonQuickFormat, *ButtonFormat, *ButtonFormatVerify; +static Object *MenuAbout, *MenuAboutMUI, *MenuQuit; + +//---------------------------------------------------------------------------- + + +int main(int argc, char *argv[]) +{ + LONG win_opened; +#if 0 + struct WBStartup *WBenchMsg = + (argc == 0) ? (struct WBStartup *)argv : NULL; + + if (NULL == WBenchMsg) + { + return 5; + } + if (WBenchMsg->sm_NumArgs < 2) + { + return 5; + } +#endif + + do { + ULONG sigs = 0; + BOOL Run = TRUE; + + if (!OpenLibraries()) + break; + + if (!CheckMCCVersion(MUIC_NListview, 19, 66) ) + break; + + gb_Catalog = OpenCatalogA(NULL, "Scalos/FormatDiskMUI.catalog",NULL); + + APP_Main = ApplicationObject, + MUIA_Application_Title, GetLocString(MSGID_TITLENAME), + MUIA_Application_Version, "$VER: Scalos FormatDisk.module V40.1 (" __DATE__ ") " COMPILER_STRING, + MUIA_Application_Copyright, "© The Scalos Team, 2008" CURRENTYEAR, + MUIA_Application_Author, "The Scalos Team", + MUIA_Application_Description, "Scalos FormatDisk module", + MUIA_Application_Base, "SCALOS_FORMATDISK", + + SubWindow, WIN_Main = WindowObject, + MUIA_Window_Title, GetLocString(MSGID_TITLENAME), + MUIA_Window_ID, MAKE_ID('M','A','I','N'), + MUIA_Window_AppWindow, TRUE, + MUIA_Window_UseBottomBorderScroller, TRUE, // +jmc+ + + WindowContents, VGroup, + Child, HGroup, + Child, NListviewObject, + MUIA_Weight, 10, + MUIA_NListview_NList, NListDosDevices = NListObject, + MUIA_NList_ConstructHook, MUIV_NList_ConstructHook_String, + MUIA_NList_DestructHook, MUIV_NList_DestructHook_String, + End, //NListObject + End, //NListviewObject + + Child, VGroup, + GroupFrame, + Child, ColGroup(2), + Child, Label1(GetLocString(MSGID_STRING_LABEL)), + Child, StringLabel = StringObject, + StringFrame, + StringBack, + End, //StringObject + + Child, Label1(GetLocString(MSGID_TEXT_FILESYSTEM)), + Child, TextDosType = TextObject, + MUIA_Background, MUII_TextBack, + TextFrame, + End, //TextObject + + Child, Label1(GetLocString(MSGID_TEXT_STATUS)), + Child, TextFormatted = TextObject, + TextFrame, + MUIA_Background, MUII_TextBack, + End, //TextObject + End, //ColGroup + + Child, HVSpace, + + Child, HGroup, + Child, VGroup, + GroupFrame, + MUIA_Background, MUII_GroupBack, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_GROUP_COMMON), + + Child, ColGroup(2), + Child, Label1(GetLocString(MSGID_CHECK_CREATEICONS)), + Child, CheckMarkHelp(FALSE, MSGID_CHECK_CREATEICONS_SHORTHELP), + End, //ColGroup + End, //VGroup + + Child, HVSpace, + + Child, VGroup, + GroupFrame, + MUIA_Background, MUII_GroupBack, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_GROUP_SPECIFIC), + + Child, ColGroup(2), + Child, Label1(GetLocString(MSGID_CHECK_CASE_SENSITIVE)), + Child, CheckMarkHelp(FALSE, MSGID_CHECK_CASE_SENSITIVE_SHORTHELP), + + Child, Label1(GetLocString(MSGID_CHECK_CREATE_RECYCLE)), + Child, CheckMarkHelp(FALSE, MSGID_CHECK_CREATE_RECYCLE_SHORTHELP), + + Child, Label1(GetLocString(MSGID_CHECK_RECYCLE_VISIBLE)), + Child, CheckMarkHelp(FALSE, MSGID_CHECK_RECYCLE_VISIBLE_SHORTHELP), + End, //ColGroup + End, //VGroup + + End, //HGroup + + Child, HVSpace, + + Child, TextDeviceName = TextObject, + TextFrame, + MUIA_Background, MUII_TextBack, + MUIA_Text_PreParse, "\33c", + End, //TextObject + End, //VGroup + End, //HGroup + + Child, VSpace(1), + + Child, ColGroup(4), + Child, ButtonQuickFormat = KeyButtonHelp(GetLocString(MSGID_BUTTON_QUICKFORMAT), + *GetLocString(MSGID_BUTTON_QUICKFORMAT_SHORT), GetLocString(MSGID_BUTTON_QUICKFORMAT_SHORTHELP)), + Child, ButtonFormat = KeyButtonHelp(GetLocString(MSGID_BUTTON_FORMAT), + *GetLocString(MSGID_BUTTON_FORMAT_SHORT), GetLocString(MSGID_BUTTON_FORMAT_SHORTHELP)), + Child, ButtonFormatVerify = KeyButtonHelp(GetLocString(MSGID_BUTTON_FORMAT_VERIFY), + *GetLocString(MSGID_BUTTON_FORMAT_VERIFY_SHORT), GetLocString(MSGID_BUTTON_FORMAT_VERIFY_SHORTHELP)), + Child, CancelButton = KeyButtonHelp(GetLocString(MSGID_CANCELBUTTON), + *GetLocString(MSGID_CANCELBUTTON_SHORT), GetLocString(MSGID_SHORTHELP_CANCELBUTTON)), + End, //HGroup + End, //VGroup + End, //WindowObject + + MUIA_Application_Menustrip, MenustripObject, + Child, MenuObjectT(GetLocString(MSGID_MENU_PROJECT)), + + Child, MenuAbout = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUT), + End, + Child, MenuAboutMUI = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUTMUI), + End, + Child, MenuitemObject, + MUIA_Menuitem_Title, -1, + End, + Child, MenuQuit = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_QUIT), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_PROJECT_QUIT_SHORT), + End, + + End, //MenuObjectT + End, //MenuStripObject + + End; //ApplicationObject + + d1(KPrintF( "%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + if (NULL == APP_Main) + { + printf(GetLocString(MSGID_CREATE_APPLICATION_FAILED)); + break; + } + + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + WIN_Main, 3, MUIM_Set, MUIA_Window_Open, FALSE); + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + DoMethod(MenuAbout, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &AboutHook); + DoMethod(MenuAboutMUI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &AboutMUIHook); + DoMethod(MenuQuit, MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + // Call hook everytime a device is selected + DoMethod(NListDosDevices, MUIM_Notify, MUIA_NList_Active, MUIV_EveryTime, + APP_Main, 3, MUIM_CallHook, &SelectDeviceHook, MUIV_TriggerValue); + + // Quit when "Cancel" button is clicked + DoMethod(CancelButton, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + set(ButtonQuickFormat, MUIA_Disabled, TRUE); + set(ButtonFormat, MUIA_Disabled, TRUE); + set(ButtonFormatVerify, MUIA_Disabled, TRUE); + + FillDeviceList(); + + set(WIN_Main, MUIA_Window_Open, TRUE); + get(WIN_Main, MUIA_Window_Open, &win_opened); + + if (!win_opened) + { + printf(GetLocString(MSGID_CREATE_MAINWINDOW_FAILED)); + break; + } + + d1(KPrintF( "%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + while (Run) + { + ULONG Action = DoMethod(APP_Main, MUIM_Application_NewInput, &sigs); + + switch (Action) + { + case MUIV_Application_ReturnID_Quit: + Run = FALSE; + break; + } + + if (Run && sigs) + { + sigs = Wait(sigs | SIGBREAKF_CTRL_C); + + if (sigs & SIGBREAKF_CTRL_C) + { + Run = FALSE; + } + } + } + + set(WIN_Main, MUIA_Window_Open, FALSE); + } while (0); + + if (APP_Main) + MUI_DisposeObject(APP_Main); + if(gb_Catalog) + CloseCatalog(gb_Catalog); + + CloseLibraries(); + + return 0; +} + +//---------------------------------------------------------------------------- + +static BOOL OpenLibraries(void) +{ + MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN-1); + if (NULL == MUIMasterBase) + return FALSE; +#ifdef __amigaos4__ + else + { + IMUIMaster = (struct MUIMasterIFace *)GetInterface((struct Library *)MUIMasterBase, "main", 1, NULL); + if (NULL == IMUIMaster) + return FALSE; + } +#endif + + + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + if (NULL == IntuitionBase) + return FALSE; +#ifdef __amigaos4__ + else + { + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + return FALSE; + } +#endif + + LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 38); +#ifdef __amigaos4__ + if (NULL != LocaleBase) + ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL); +#endif + + IconBase = OpenLibrary("icon.library", 39); + if (NULL == IconBase) + return FALSE; +#ifdef __amigaos4__ + else + { + IIcon = (struct IconIFace *)GetInterface((struct Library *)IconBase, "main", 1, NULL); + if (NULL == IIcon) + return FALSE; + } +#endif + +#ifndef __amigaos4__ + UtilityBase = (T_UTILITYBASE) OpenLibrary("utility.library", 39); + if (NULL == UtilityBase) + return FALSE; +#endif + + return TRUE; +} + +//---------------------------------------------------------------------------- + +static void CloseLibraries(void) +{ +#ifndef __amigaos4__ + if (UtilityBase) + { + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } +#endif +#ifdef __amigaos4__ + if (ILocale) + { + DropInterface((struct Interface *)ILocale); + ILocale = NULL; + } +#endif + if (LocaleBase) + { + CloseLibrary((struct Library *)LocaleBase); + LocaleBase = NULL; + } +#ifdef __amigaos4__ + if (IIcon) + { + DropInterface((struct Interface *)IIcon); + IIcon = NULL; + } +#endif + if (IconBase) + { + CloseLibrary(IconBase); + IconBase = NULL; + } +#ifdef __amigaos4__ + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } +#endif + if (IntuitionBase) + { + CloseLibrary((struct Library *)IntuitionBase); + IntuitionBase = NULL; + } +#ifdef __amigaos4__ + if (IMUIMaster) + { + DropInterface((struct Interface *)IMUIMaster); + IMUIMaster = NULL; + } +#endif + if (MUIMasterBase) + { + CloseLibrary(MUIMasterBase); + MUIMasterBase = NULL; + } +} + +//---------------------------------------------------------------------------- + +static STRPTR GetLocString(ULONG MsgId) +{ + struct FormatDiskMUI_LocaleInfo li; + + li.li_Catalog = gb_Catalog; +#ifndef __amigaos4__ + li.li_LocaleBase = LocaleBase; +#else + li.li_ILocale = ILocale; +#endif + + return (STRPTR)GetFormatDiskMUIString(&li, MsgId); +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT OpenAboutMUIHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + if (NULL == WIN_AboutMUI) + { + WIN_AboutMUI = MUI_NewObject(MUIC_Aboutmui, + MUIA_Window_RefWindow, WIN_Main, + MUIA_Aboutmui_Application, APP_Main, + End; + } + + if (WIN_AboutMUI) + set(WIN_AboutMUI, MUIA_Window_Open, TRUE); + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT OpenAboutHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + MUI_Request(APP_Main, WIN_Main, 0, NULL, + GetLocString(MSGID_ABOUTREQOK), + GetLocString(MSGID_ABOUTREQFORMAT), + VERSION_MAJOR, VERSION_MINOR, COMPILER_STRING, CURRENTYEAR); +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT SelectDeviceHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + LONG *pPos = (LONG *) msg; + + (void) hook; + (void) o; + + if (*pPos >= 0) + { + STRPTR entry; + + DoMethod(NListDosDevices, MUIM_NList_GetEntry, *pPos, &entry); + d2(KPrintF(__FILE__ "/%s/%ld: *pPos=%ld entry=<%s>\n", __FUNC__, __LINE__, *pPos, entry)); + + if (entry) + SelectDevice(entry); + } + +} + +//---------------------------------------------------------------------------- + +IPTR mui_getv(APTR obj, ULONG attr) +{ + IPTR v; + GetAttr(attr, obj, &v); + return (v); +} + +//---------------------------------------------------------------------------- + +// Checks if a certain version of a MCC is available +static BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev) +{ + BOOL flush = TRUE; + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: %s ", __LINE__, name);) + + while (1) + { + ULONG ver; + ULONG rev; + struct Library *base; + char libname[256]; + + // First we attempt to acquire the version and revision through MUI + Object *obj = MUI_NewObject((STRPTR) name, TAG_DONE); + if (obj) + { + get(obj, MUIA_Version, &ver); + get(obj, MUIA_Revision, &rev); + + MUI_DisposeObject(obj); + + if(ver > minver || (ver == minver && rev >= minrev)) + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: v%ld.%ld found through MUIA_Version/Revision\n", __LINE__, ver, rev);) + return TRUE; + } + } + + // If we did't get the version we wanted, let's try to open the + // libraries ourselves and see what happens... + stccpy(libname, "PROGDIR:mui", sizeof(libname)); + AddPart(libname, name, sizeof(libname)); + + if ((base = OpenLibrary(&libname[8], 0)) || (base = OpenLibrary(&libname[0], 0))) + { + UWORD OpenCnt = base->lib_OpenCnt; + + ver = base->lib_Version; + rev = base->lib_Revision; + + CloseLibrary(base); + + // we add some additional check here so that eventual broken .mcc also have + // a chance to pass this test (i.e. Toolbar.mcc is broken) + if (ver > minver || (ver == minver && rev >= minrev)) + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: v%ld.%ld found through OpenLibrary()\n", __LINE__, ver, rev);) + return TRUE; + } + + if (OpenCnt > 1) + { + if (MUI_Request(NULL, NULL, 0L, + (STRPTR) GetLocString(MSGID_STARTUP_FAILURE), + (STRPTR) GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), + (STRPTR) GetLocString(MSGID_STARTUP_MCC_IN_USE), + name, minver, minrev, ver, rev)) + { + flush = TRUE; + } + else + break; + } + + // Attempt to flush the library if open count is 0 or because the + // user wants to retry (meaning there's a chance that it's 0 now) + + if (flush) + { + struct Library *result; + extern struct ExecBase *SysBase; + + Forbid(); + if ((result = (struct Library *) FindName(&SysBase->LibList, name))) + RemLibrary(result); + Permit(); + flush = FALSE; + } + else + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: couldn`t find minimum required version.\n", __LINE__);) + + // We're out of luck - open count is 0, we've tried to flush + // and still haven't got the version we want + if (MUI_Request(NULL, NULL, 0L, + (STRPTR) GetLocString(MSGID_STARTUP_FAILURE), + (STRPTR) GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), + (STRPTR) GetLocString(MSGID_STARTUP_OLD_MCC), + name, minver, minrev, ver, rev)) + { + flush = TRUE; + } + else + break; + } + } + else + { + // No MCC at all - no need to attempt flush + flush = FALSE; + if (!MUI_Request(NULL, NULL, 0L, + (STRPTR) GetLocString(MSGID_STARTUP_FAILURE), + (STRPTR) GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), + (STRPTR) GetLocString(MSGID_STARTUP_MCC_NOT_FOUND), + name, minver, minrev)) + { + break; + } + } + } + + return FALSE; +} + +//---------------------------------------------------------------------------- + +static void FillDeviceList(void) +{ + ULONG DosListFlags = LDF_DEVICES | LDF_READ; + struct DosList *dl; + + dl = LockDosList(DosListFlags); + + while ((dl = NextDosEntry(dl, DosListFlags))) + { + struct FileSysStartupMsg *fssm = BADDR(dl->dol_misc.dol_handler.dol_Startup); + + if (dl->dol_Task && IsFssmValid(fssm)) + { + char DeviceName[MAX_DEV_NAME]; + + BToCString(dl->dol_Name, DeviceName, sizeof(DeviceName) - 1); + strcat(DeviceName, ":"); + + d1(KPrintF( "%s/%s/%ld: dl=%08lx dol_Name=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, dl, dl->dol_Name, DeviceName)); + + if (IsFileSystem(DeviceName)) + { + DoMethod(NListDosDevices, + MUIM_NList_InsertSingle, + DeviceName, + MUIV_NList_Insert_Sorted); + } + } + } + + UnLockDosList(DosListFlags); +} + +//---------------------------------------------------------------------------- + +static void BToCString(BSTR BName, STRPTR CName, size_t Length) +{ + const UBYTE *bName = BADDR((const UBYTE *) BName); + size_t BLength = bName[0]; + + bName++; // skip length + + while (Length > 1 && BLength) + { + *CName++ = *bName++; + Length--; + BLength--; + } + *CName = '\0'; +} + +//---------------------------------------------------------------------------- + +/* + * Checks if a device has a valid fssm. + */ +static BOOL IsFssmValid(struct FileSysStartupMsg *fssm) +{ + const struct DosEnvec *env; + + if (!(TypeOfMem(fssm) & MEMF_PUBLIC)) + return FALSE; + + if (!(TypeOfMem(BADDR(fssm->fssm_Device)) & MEMF_PUBLIC)) + return FALSE; + + env = BADDR(fssm->fssm_Environ); + if (!(TypeOfMem((APTR) env) & MEMF_PUBLIC)) + return FALSE; + + if (env->de_TableSize > 2 * sizeof(struct DosEnvec)) + return FALSE; +#if 0 + if (!((UBYTE *)myfssm)[0] || !((UBYTE *)devname)[0]) + { + return (TRUE); + } +#endif + + return TRUE; +} + +//---------------------------------------------------------------------------- + +static void SelectDevice(CONST_STRPTR DevName) +{ + struct FileInfoBlock *fib = NULL; + struct InfoData *id = NULL; + BPTR dLock = 0; + struct Process *myProc = (struct Process *) FindTask(NULL); + APTR oldWindowPtr = myProc->pr_WindowPtr; + + myProc->pr_WindowPtr = (APTR) ~0; + + do { + char FsName[MAX_DEV_NAME]; + char ExecDevName[108]; + char DevInfoString[128]; + char CapacityString[40]; + ULONG UnitNumber = 0; + ULONG DosType; + + fib = AllocDosObject(DOS_FIB, NULL); + d2(KPrintF( "%s/%s/%ld: fib=%08lx\n", __FILE__, __FUNC__, __LINE__, fib)); + if (NULL == fib) + break; + + id = malloc(sizeof(struct InfoData)); + d2(KPrintF( "%s/%s/%ld: id=%08lx\n", __FILE__, __FUNC__, __LINE__, id)); + if (NULL == id) + break; + + dLock = Lock(DevName, ACCESS_READ); + d2(KPrintF( "%s/%s/%ld: dLock=%08lx\n", __FILE__, __FUNC__, __LINE__, dLock)); + if (0 == dLock) + break; + + if (!Info(dLock, id)) + break; + + d2(KPrintF( "%s/%s/%ld: Info() Ok, id_DiskType=%08lx\n", __FILE__, __FUNC__, __LINE__, id->id_DiskType)); + + if (ID_NO_DISK_PRESENT == id->id_DiskType) + break; + + if (Examine(dLock, fib)) + { + d2(KPrintF( "%s/%s/%ld: Examine() OK <%s>\n", __FILE__, __FUNC__, __LINE__, fib->fib_FileName)); + setstring(StringLabel, fib->fib_FileName); + } + else + { + d2(KPrintF( "%s/%s/%ld: Examine() failed <%s>\n", __FILE__, __FUNC__, __LINE__, fib->fib_FileName)); + setstring(StringLabel, GetLocString(MSGID_LABEL_RELABEL_ME)); + } + + set(TextFormatted, MUIA_Text_Contents, + GetLocString(IsDiskFormatted(DevName) ? MSGID_DISK_FORMATTED : MSGID_DISK_UNFORMATTED)); + + DosType = GetDosType(DevName, ExecDevName, sizeof(ExecDevName), &UnitNumber); + d2(KPrintF( "%s/%s/%ld: DosType=%08lx\n", __FILE__, __FUNC__, __LINE__, DosType)); + + set(TextDosType, MUIA_Text_Contents, GetFileSystemName(DosType, FsName, sizeof(FsName))); + + GetCapacityString(CapacityString, sizeof(CapacityString), id); + + snprintf(DevInfoString, sizeof(DevInfoString), + GetLocString(MSGID_TEXT_DEVICENAME), ExecDevName, UnitNumber, CapacityString); + + set(TextDeviceName, MUIA_Text_Contents, DevInfoString); + + if (ID_WRITE_PROTECTED == id->id_DiskState) + { + set(ButtonQuickFormat, MUIA_Disabled, TRUE); + set(ButtonFormat, MUIA_Disabled, TRUE); + set(ButtonFormatVerify, MUIA_Disabled, TRUE); + } + else + { + set(ButtonQuickFormat, MUIA_Disabled, FALSE); + set(ButtonFormat, MUIA_Disabled, FALSE); + set(ButtonFormatVerify, MUIA_Disabled, FALSE); + } + } while (0); + + if (dLock) + UnLock(dLock); + if (id) + free(id); + if (fib) + FreeDosObject(DOS_FIB, fib); + + myProc->pr_WindowPtr = oldWindowPtr; +} + +//---------------------------------------------------------------------------- + +static BOOL IsDiskFormatted(CONST_STRPTR DevName) +{ + char ClonedDeviceName[MAX_DEV_NAME]; + ULONG DosListFlags = LDF_DEVICES | LDF_READ; + struct DosList *dl; + struct MsgPort *mp = NULL; + BOOL IsFormatted = FALSE; + + stccpy(ClonedDeviceName, DevName, sizeof(ClonedDeviceName)); + StripTrailingChar(ClonedDeviceName, ':'); + + d2(KPrintF( "%s/%s/%ld: ClonedDeviceName=<%s>\n", __FILE__, __FUNC__, __LINE__, ClonedDeviceName)); + + dl = LockDosList(DosListFlags); + if ((dl = FindDosEntry(dl, ClonedDeviceName, LDF_DEVICES))) + { + mp = dl->dol_Task; + d2(KPrintF( "%s/%s/%ld: dl=%08lx mp=%08lx dol_Task=%08lx\n", __FILE__, __FUNC__, __LINE__, dl, mp)); + } + UnLockDosList(DosListFlags); + + if (mp) + { + DosListFlags = LDF_VOLUMES | LDF_READ; + + dl = LockDosList(DosListFlags); + while ((dl = NextDosEntry(dl, LDF_VOLUMES))) + { + d2(KPrintF( "%s/%s/%ld: dl=%08lx mp=%08lx dol_Task=%08lx\n", __FILE__, __FUNC__, __LINE__, dl, mp, dl->dol_Task)); + if (mp == dl->dol_Task) + { + IsFormatted = TRUE; + break; + } + } + UnLockDosList(DosListFlags); + } + + return IsFormatted; +} + +//---------------------------------------------------------------------------- + +static void StripTrailingChar(STRPTR String, char CharToRemove) +{ + size_t Len = strlen(String); + + if (Len > 0 && CharToRemove == String[Len - 1]) + String[Len - 1] = '\0'; +} + +//---------------------------------------------------------------------------- + +static ULONG GetDosType(CONST_STRPTR DevName, STRPTR ExecDevName, size_t MaxLength, ULONG *UnitNumber) +{ + char ClonedDeviceName[MAX_DEV_NAME]; + ULONG DosListFlags = LDF_DEVICES | LDF_READ; + struct DosList *dl; + ULONG DosType = 0; + + stccpy(ClonedDeviceName, DevName, sizeof(ClonedDeviceName)); + StripTrailingChar(ClonedDeviceName, ':'); + + d2(KPrintF( "%s/%s/%ld: ClonedDeviceName=<%s>\n", __FILE__, __FUNC__, __LINE__, ClonedDeviceName)); + + dl = LockDosList(DosListFlags); + if ((dl = FindDosEntry(dl, ClonedDeviceName, LDF_DEVICES))) + { + struct FileSysStartupMsg *fssm = BADDR(dl->dol_misc.dol_handler.dol_Startup); + + d2(KPrintF( "%s/%s/%ld: dl=%08lx fssm=%08lx\n", __FILE__, __FUNC__, __LINE__, dl, fssm)); + + if (dl->dol_Task && IsFssmValid(fssm)) + { + struct DosEnvec *env = BADDR(fssm->fssm_Environ); + + DosType = env->de_DosType; + + BToCString(fssm->fssm_Device, ExecDevName, MaxLength); + *UnitNumber = fssm->fssm_Unit; + } + } + UnLockDosList(DosListFlags); + + return DosType; +} + +//---------------------------------------------------------------------------- + +static CONST_STRPTR GetFileSystemName(ULONG DosType, STRPTR Buffer, size_t MaxLength) +{ + const struct FileSystemName *fsn; + CONST_STRPTR FsName = NULL; + + for (fsn = FsList; fsn->fsn_Name; fsn++) + { + if (fsn->fsn_DosType == DosType) + { + stccpy(Buffer, fsn->fsn_Name, MaxLength); + FsName = Buffer; + break; + } + } + + if (NULL == FsName) + { + char DosListString[4][10]; + + snprintf(Buffer, MaxLength, + GetLocString(MSGID_FSNAME_UNKNOWN), + GetDosTypePrintableString((UBYTE) (DosType >> 24), DosListString[0], sizeof(DosListString[0])), + GetDosTypePrintableString((UBYTE) ((DosType >> 16) & 0xff), DosListString[1], sizeof(DosListString[1])), + GetDosTypePrintableString((UBYTE) ((DosType >> 8) & 0xff), DosListString[2], sizeof(DosListString[2])), + GetDosTypePrintableString((UBYTE) (DosType & 0xff), DosListString[3], sizeof(DosListString[3])) + ); + } + + return Buffer; +} + +//---------------------------------------------------------------------------- + +static STRPTR GetDosTypePrintableString(UBYTE dosType, STRPTR Buffer, size_t MaxLength) +{ + if (isprint(dosType)) + snprintf(Buffer, MaxLength, "%c", dosType); + else + snprintf(Buffer, MaxLength, "\\%x", (unsigned int) dosType); + + return Buffer; +} + +//---------------------------------------------------------------------------- + +static void GetCapacityString(STRPTR Buffer, size_t MaxLength, const struct InfoData *id) +{ + ULONG BlocksPerKByte = 1024 / id->id_BytesPerBlock; + ULONG KBytes, MBytes, GBytes; + + if (BlocksPerKByte) + { + // Block size <= 1024 + KBytes = id->id_NumBlocks / BlocksPerKByte; + } + else + { + // Block size > 1024 + ULONG KBytesPerBlock = id->id_BytesPerBlock / 1024; + + KBytes = id->id_NumBlocks * KBytesPerBlock; + } + + MBytes = KBytes / 1024; + GBytes = MBytes / 1024; + + if (GBytes > 2) + { + if (GBytes > 20) + snprintf(Buffer, MaxLength, "%lu %s", (unsigned long)GBytes, GetLocString(MSGID_GBYTENAME)); + else + snprintf(Buffer, MaxLength, "%lu.%lu %s", (unsigned long)GBytes, (unsigned long)((MBytes / 100) % 10), GetLocString(MSGID_GBYTENAME)); + } + else if (MBytes > 2) + { + if (MBytes > 20) + snprintf(Buffer, MaxLength, "%lu %s", (unsigned long)MBytes, GetLocString(MSGID_MBYTENAME)); + else + snprintf(Buffer, MaxLength, "%lu.%lu %s", (unsigned long)MBytes, (unsigned long)((KBytes / 100) % 10), GetLocString(MSGID_MBYTENAME)); + } + else + snprintf(Buffer, MaxLength, "%lu %s", (unsigned long)KBytes, GetLocString(MSGID_KBYTENAME)); +} + +//---------------------------------------------------------------------------- + + diff --git a/scalos/Modules/FormatDisk.MUI/FormatDisk.h b/scalos/Modules/FormatDisk.MUI/FormatDisk.h new file mode 100755 index 000000000..1fe55a149 --- /dev/null +++ b/scalos/Modules/FormatDisk.MUI/FormatDisk.h @@ -0,0 +1,191 @@ +// FormatDisk.h +// $Date$ +// $Revision$ + + +#ifndef FORMATDISK_H +#define FORMATDISK_H + +#define NDP_IconCreation 0x80000001 + +#define d1(x) ; +#define d2(x) x; + +//---------------------------------------------------------------------------- + +/// IDs of various file systems + +#define FS_BSD_DISKLABEL_MSDOS_SWAP 0x42534401 +#define FS_BSD_DISKLABEL_MSDOS_V6 0x42534402 +#define FS_BSD_DISKLABEL_MSDOS_V7 0x42534403 +#define FS_BSD_DISKLABEL_MSDOS_SYSV 0x42534404 +#define FS_BSD_DISKLABEL_MSDOS_41 0x42534405 +#define FS_BSD_DISKLABEL_MSDOS_8TH 0x42534406 +#define FS_BSD_DISKLABEL_MSDOS_42 0x42534407 +#define FS_BSD_DISKLABEL_MSDOS_MSDOS 0x42534408 +#define FS_BSD_DISKLABEL_MSDOS_44LFS 0x42534409 +#define FS_BSD_DISKLABEL_MSDOS_UNKNOWN 0x4253440a +#define FS_BSD_DISKLABEL_MSDOS_HPFS 0x4253440b +#define FS_BSD_DISKLABEL_MSDOS_ISO9660 0x4253440c +#define FS_BSD_DISKLABEL_MSDOS_BOOT 0x4253440d +#define FS_BSD_DISKLABEL_MSDOS_AFFS 0x4253440e +#define FS_BSD_DISKLABEL_MSDOS_HFS 0x4253440f + +#define FS_OFS_LINUX_SWAP 0x4f534601 +#define FS_OFS_BSD_V6 0x4f534602 +#define FS_OFS_BSD_V7 0x4f534603 +#define FS_OFS_BSD_SYSV 0x4f534604 +#define FS_OFS_BSD_41 0x4f534605 +#define FS_OFS_BSD_8TH 0x4f534606 +#define FS_OFS_BSD_42 0x4f534607 +#define FS_OFS_LINUX_NATIVE 0x4f534608 +#define FS_OFS_BSD_44LFS 0x4f534609 +#define FS_OFS_UNKNOWN 0x4f53460a +#define FS_OFS_HPFS 0x4f53460b +#define FS_OFS_ISO9660 0x4f53460c +#define FS_OFS_BOOT 0x4f53460d +#define FS_OFS_AFFS 0x4f53460e +#define FS_OFS_HFS 0x4f53460f +#define FS_OFS_ADVFS 0x4f534610 + +#define FS_SUN_EMPTY 0x53554e00 +#define FS_SUN_BOOT 0x53554e01 +#define FS_SUN_SUNOS_ROOT 0x53554e02 +#define FS_SUN_SUNOS_SWAP 0x53554e03 +#define FS_SUN_SUNOS_USR 0x53554e04 +#define FS_SUN_WHOLE 0x53554e05 +#define FS_SUN_SUNOS_STAND 0x53554e06 +#define FS_SUN_SUNOS_VAR 0x53554e07 +#define FS_SUN_SUNOS_HOME 0x53554e08 +#define FS_SUN_LINUX_MINIX 0x53554e81 +#define FS_SUN_LINUX_SWAP 0x53554e82 +#define FS_SUN_LINUX_NATIVE 0x53554e83 + +#define FS_AMIGA_GENERIC_BOOT 0x424f4f55 +#define FS_AMIGA_OFS 0x444f5300 +#define FS_AMIGA_FFS 0x444f5301 +#define FS_AMIGA_OFS_INTL 0x444f5302 +#define FS_AMIGA_FFS_INTL 0x444f5303 +#define FS_AMIGA_OFS_DC_INTL 0x444f5304 +#define FS_AMIGA_FFS_DC_INTL 0x444f5405 +#define FS_AMIGA_OFS_LNFS 0x444f5406 +#define FS_AMIGA_FFS_LNFS 0x444f5407 +#define FS_AMIGA_MUFS_FFS_INTL 0x6d754653 +#define FS_AMIGA_MUFS_OFS 0x6d754600 +#define FS_AMIGA_MUFS_FFS 0x6d754601 +#define FS_AMIGA_MUFS_OFS_INTL 0x6d754602 +#define FS_AMIGA_MUFS_FFS_INTL2 0x6d754603 +#define FS_AMIGA_MUFS_OFS_DC 0x6d754604 +#define FS_AMIGA_MUFS_FFS_DC 0x6d754605 +#define FS_AMIGA_LINUX_NATIVE 0x4c4e5800 +#define FS_AMIGA_LINUX_EXT2 0x45585432 +#define FS_AMIGA_LINUX_SWAP 0x53574150 +#define FS_AMIGA_LINUX_SWAP2 0x53575000 +#define FS_AMIGA_LINUX_MINIX 0x4d4e5800 +#define FS_AMIGA_AMIX_0 0x554e4900 +#define FS_AMIGA_AMIX_1 0x554e4901 +#define FS_AMIGA_NETBSD_ROOT 0x4e425207 +#define FS_AMIGA_NETBSD_SWAP 0x4e425301 +#define FS_AMIGA_NETBSD_OTHER 0x4e425507 +#define FS_AMIGA_PFS0 0x50465300 +#define FS_AMIGA_PFS1 0x50465301 +#define FS_AMIGA_PFS2 0x50465302 +#define FS_AMIGA_PFS3 0x50465303 +#define FS_AMIGA_PDS2 0x50445300 +#define FS_AMIGA_PDS3 0x50445303 +#define FS_AMIGA_MUPFS 0x6d755046 +#define FS_AMIGA_AFS 0x41465300 +#define FS_AMIGA_AFS_EXP 0x41465301 +#define FS_AMIGA_CDISO 0x43443031 +#define FS_AMIGA_CDHSF 0x43443030 +#define FS_AMIGA_CDDA 0x43444441 +#define FS_AMIGA_CDRIVE 0x43444653 +#define FS_AMIGA_ASIMCDFS 0x662dabac +#define FS_AMIGA_HFS 0x4d414300 +#define FS_AMIGA_MSDOS 0x4d534400 +#define FS_AMIGA_MSDOS_HF 0x4d534800 +#define FS_AMIGA_BFFS 0x42464653 +#define FS_AMIGA_SFS 0x53465300 + +#define FS_AMIGA_BAD 0x42414400 +#define FS_AMIGA_NDOS 0x4e444f53 +#define FS_AMIGA_KICK 0x4b49434b + +#define FS_ATARI_GEMDOS 0x4147454d +#define FS_ATARI_GEMDOSBIG 0x4142474d +#define FS_ATARI_LINUX 0x414c4e58 +#define FS_ATARI_LINUX_SWAP 0x41535750 +#define FS_ATARI_LINUX_MINIX 0x414d4958 +#define FS_ATARI_LINUX_MINIX2 0x414d4e58 +#define FS_ATARI_HFS 0x414d4143 +#define FS_ATARI_SYSV_UNIX 0x41554e58 +#define FS_ATARI_RAW 0x41524157 +#define FS_ATARI_EXTENDED 0x4158474d + +#define FS_MAC_PARTITION_MAP 0x4d414301 +#define FS_MAC_MACOS_DRIVER 0x4d414302 +#define FS_MAC_MACOS_DRIVER_43 0x4d414303 +#define FS_MAC_MACOS_HFS 0x4d414304 +#define FS_MAC_MACOS_MFS 0x4d414305 +#define FS_MAC_SCRATCH 0x4d414306 +#define FS_MAC_PRODOS 0x4d414307 +#define FS_MAC_FREE 0x4d414308 +#define FS_MAC_LINUX_SWAP 0x4d414309 +#define FS_MAC_AUX 0x4d41430a +#define FS_MAC_MSDOS 0x4d41430b +#define FS_MAC_MINIX 0x4d41430c +#define FS_MAC_AFFS 0x4d41430d +#define FS_MAC_LINUX_NATIVE 0x4d41430e +#define FS_MAC_NEWWORLD 0x4d41430f +#define FS_MAC_MACOS_ATA 0x4d414310 +#define FS_MAC_MACOS_FW_DRIVER 0x4d414311 +#define FS_MAC_MACOS_IOKIT 0x4d414312 +#define FS_MAC_MACOS_PATCHES 0x4d414313 +#define FS_MAC_MACOSX_BOOT 0x4d414314 +#define FS_MAC_MACOSX_LOADER 0x4d414315 +#define FS_MAC_UFS 0x4d414316 + +#define FS_ACORN_ADFS 0x41524d01 +#define FS_ACORN_LINUX_MAP 0x41524d02 +#define FS_ACORN_LINUX_EXT2 0x41524d03 +#define FS_ACORN_LINUX_SWAP 0x41524d04 +#define FS_ACORN_ADFS_ICS 0x41524d05 +#define FS_ACORN_LINUX_EXT2_ICS 0x41524d06 +#define FS_ACORN_LINUX_SWAP_ICS 0x41524d07 + +#define FS_SINCLAIR_QL5A 0x514c3541 +#define FS_SINCLAIR_QL5B 0x514c3542 + +#define FS_SPECTRUM_DISCIPLE 0x5a585300 +#define FS_SPECTRUM_UNIDOS 0x5a585301 +#define FS_SPECTRUM_SAMDOS 0x5a585302 +#define FS_SPECTRUM_OPUS 0x5a585303 + +#define FS_ARCHIMEDES_D 0x41524d44 +#define FS_ARCHIMEDES_E 0x41524d45 + +#define FS_CPM 0x43504d02 + +#define FS_C64 0x31353431 + +//---------------------------------------------------------------------------- + +#ifdef __AROS__ +#define KPrintF kprintf +#endif + +extern int kprintf(CONST_STRPTR, ...); +extern int KPrintF(CONST_STRPTR, ...); + +IPTR mui_getv(APTR, ULONG ); + +struct FormatDiskMUI_LocaleInfo +{ + APTR li_LocaleBase; + APTR li_Catalog; + struct LocaleIFace *li_ILocale; +}; + +//---------------------------------------------------------------------------- + +#endif /* FORMATDISK_H */ diff --git a/scalos/Modules/FormatDisk.MUI/FormatDiskMUI.cd b/scalos/Modules/FormatDisk.MUI/FormatDiskMUI.cd new file mode 100755 index 000000000..df8d37bcf --- /dev/null +++ b/scalos/Modules/FormatDisk.MUI/FormatDiskMUI.cd @@ -0,0 +1,237 @@ +; FormatDisk.cd +; version $VER: FormatDiskMUI.catalog 40.1 (26 Feb 2005 21:03:45) +; codeset 0 +; language english +; +;#arrayopts static __far +; +; +MSGID_TITLENAME (//) +Scalos FormatDisk +; +; +MSGID_OKBUTTON (//) +New Drawer +; +; +MSGID_OKBUTTON_SHORT (/1/1) +n +; +; +MSGID_SHORTHELP_OKBUTTON (//) +Create new drawer. +; +; +MSGID_CANCELBUTTON (//) +Cancel +; +; +MSGID_CANCELBUTTON_SHORT (/1/1) +c +; +; +MSGID_SHORTHELP_CANCELBUTTON (//) +Discard all changes and\n\ +do not create anything. +; +; +MSGID_CREATE_APPLICATION_FAILED (//) +Failed to create Application.\n +; +; +MSGID_CREATE_MAINWINDOW_FAILED (//) +Failed to open main window !\n +; +; +MSGID_OPEN_LIBRARY_FAILED (//) +Failed to open \"%s\" !\n +; +;;----------------------------------------------------------- +; +MSGID_MENU_PROJECT (2000//) +Project +; +; +MSGID_MENU_PROJECT_ABOUT (//) +About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI (//) +About MUI... +; +; +MSGID_MENU_PROJECT_QUIT (//) +Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT (//) +Q +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK (3000//) +_OK +; +; +MSGID_ABOUTREQFORMAT (//) +\33c\033bScalos FormatDisk.module V%ld.%ld\033n\n\ +%s\n\ +© 2004%s The Scalos Team +; +;----------------------------------------------------------- +; +MSGID_STRING_LABEL (4000//) +Label: +; +; +MSGID_TEXT_FILESYSTEM (//) +File System: +; +; +MSGID_TEXT_STATUS (//) +Status: +; +; +MSGID_GROUP_COMMON (//) +Common +; +; +MSGID_CHECK_CREATEICONS (//) +Create Icons? +; +; +MSGID_CHECK_CREATEICONS_SHORTHELP (//) +...create icons.. +; +; +MSGID_GROUP_SPECIFIC (//) +Specific +; +; +MSGID_CHECK_CASE_SENSITIVE (//) +Case Sensitive? +; +; +MSGID_CHECK_CASE_SENSITIVE_SHORTHELP (//) +...Case Sensitive... +; +; +MSGID_CHECK_CREATE_RECYCLE (//) +Create Recyle Directory? +; +; +MSGID_CHECK_CREATE_RECYCLE_SHORTHELP (//) +...Create Recyle Directory... +; +; +MSGID_CHECK_RECYCLE_VISIBLE (//) +Recycle Directory Visible? +; +; +MSGID_CHECK_RECYCLE_VISIBLE_SHORTHELP (//) +...Recycle Directory Visible... +; +; +MSGID_DISK_FORMATTED (//) +Formatted +; +; +MSGID_DISK_UNFORMATTED (//) +Unformatted +; +; +MSGID_FSNAME_UNKNOWN (//) +Unknown (%s%s%s%s) +; +; +MSGID_TEXT_DEVICENAME (//) +%s, Unit %ld. %s +; +; +MSGID_KBYTENAME (//) +KB +; +; +MSGID_MBYTENAME (//) +MBytes +; +; +MSGID_GBYTENAME (//) +GBytes +; +; +MSGID_HBYTENAME (//) +HBytes +; +; +MSGID_LABEL_RELABEL_ME (//) +Relabel me! +; +; +MSGID_BUTTON_QUICKFORMAT (//) +Quick Format... +; +; +MSGID_BUTTON_QUICKFORMAT_SHORT (/1/1) +Q +; +; +MSGID_BUTTON_QUICKFORMAT_SHORTHELP (//) +...quick format... +; +; +MSGID_BUTTON_FORMAT (//) +Format... +; +; +MSGID_BUTTON_FORMAT_SHORT (/1/1) +F +; +; +MSGID_BUTTON_FORMAT_SHORTHELP (//) +...Format... +; +; +MSGID_BUTTON_FORMAT_VERIFY (//) +Format and Verify... +; +; +MSGID_BUTTON_FORMAT_VERIFY_SHORT (/1/1) +V +; +; +MSGID_BUTTON_FORMAT_VERIFY_SHORTHELP (//) +...Format and Verify... +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE (5000//) +FormatDisk.module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD (//) +Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +; +;----------------------------------------------------------- +; +; diff --git a/scalos/Modules/FormatDisk.MUI/config.mk b/scalos/Modules/FormatDisk.MUI/config.mk new file mode 100755 index 000000000..9961f3635 --- /dev/null +++ b/scalos/Modules/FormatDisk.MUI/config.mk @@ -0,0 +1,60 @@ +# $Date: 2011-07-12 00:57:51 +0200 (Di, 12. Jul 2011) $ +# $Revision: 771 $ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +SCALOS_LOCALE = $(OBJDIR)/FormatDisk_Locale.h + +CFLAGS += -D SCALOSLOCALE=$(SCALOS_LOCALE) + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +INCLUDES += # + +LFLAGS += # + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +INCLUDES += # + +LFLAGS += # + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +INCLUDES += # + +LFLAGS += -lmui -larossupport + + +else + +############################################################################### +# AmigaOS + +INCLUDES += # + +LFLAGS += # + +endif +endif +endif diff --git a/scalos/Modules/FormatDisk.MUI/makefile b/scalos/Modules/FormatDisk.MUI/makefile new file mode 100755 index 000000000..2a14dc486 --- /dev/null +++ b/scalos/Modules/FormatDisk.MUI/makefile @@ -0,0 +1,118 @@ +# Makefile for FormatDisk.module (MUI) +# using GNU make and SAS/C +# $Date$ + +##################################################################### + +TOPLEVEL = / +SUBDIRMAKE = $(MAKE) -s -C +CHEADERS = +CC = sc +CFLAGS = optimize nostackcheck nochkabort debug=s \ + idlen=128 strmer nover streq data=far \ + ignore=217 idir=sc:include/ \ + idir=include: idir=//include +AS = phxass +AFLAGS = QUIET m=68020 linedebug opt=NRQB i=include: +LD = slink +LNFLAGS = quiet batch noicons stripdebug +LNDBFLAGS = quiet batch noicons addsym +LIBS = LIB:sc.lib LIB:debug.lib LIB:amiga.lib +CATCOMP = catcomp +FLEXCAT = FlexCat +CSTARTUP = LIB:c.o +OBJDIR = .sasobj + +##################################################################### + +.SUFFIXES: .asm + +##################################################################### + +NAME = FormatDisk.module +DBGNAME = $(NAME).debug +CATCOMPH = FormatDisk_Locale.h +CAT_FILE = Scalos/FormatDisk.catalog +DESTCAT = Locale:Catalogs +ALLCATS = Catalogs/deutsch/$(CAT_FILE) \ + Catalogs/français/$(CAT_FILE) + +##################################################################### + +all: $(NAME) \ + $(DBGNAME) \ + allcatalogs \ + +##################################################################### + +# make all Scalos .catalogs +allcatalogs: + @$(SUBDIRMAKE) Catalogs/deutsch/Scalos + @$(SUBDIRMAKE) Catalogs/français/Scalos + +##################################################################### + +CSRCS = FormatDisk.c + +##################################################################### + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +##################################################################### + +XOBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(CSRCS:%.c=$(OBJDIR)/%.o) +OBJS = $(XOBJS) + +##################################################################### + +$(NAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNFLAGS) + +$(DBGNAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNDBFLAGS) + +##################################################################### + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $< objectname $@ + +$(OBJDIR)/%.o : %.asm + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +##################################################################### + +$(CATCOMPH) : FormatDiskMUI.cd + @printf '\033[32mMake CatComp header: \033[31m\033[1m$(CATCOMPH) \033[32mfrom \033[31m$<\033[0m\n' + @$(FLEXCAT) $< $@=$(TOPLEVEL)/CatComp_h.sd + +$(OBJDIR)/FormatDisk.o : FormatDisk.c FormatDisk.h $(CATCOMPH) + +##################################################################### + +$(NAME) $(DBGNAME) : $(OBJS) + +##################################################################### + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(NAME) \033[0mto \033[31m\033[1mScalos:modules/ \033[0m\n' + @copy $(NAME) Scalos:modules/ + @avail flush + @printf '\033[32mInstall: \033[31m\033[1m$(CAT_FILE)\033[0m\n' + -@copy "catalogs/deutsch/$(CAT_FILE)" "$(DESTCAT)/Deutsch/Scalos/" clone + -@copy "catalogs/français/$(CAT_FILE)" "$(DESTCAT)/français/Scalos/" clone + +##################################################################### + +# A little something to clean it all up +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + -@delete $(XOBJS) $(NAME) $(DBGNAME) \ + $(CATCOMPH) + @printf '\033[0m' + +##################################################################### diff --git a/scalos/Modules/FormatDisk.MUI/makefile-new b/scalos/Modules/FormatDisk.MUI/makefile-new new file mode 100755 index 000000000..91d3eae47 --- /dev/null +++ b/scalos/Modules/FormatDisk.MUI/makefile-new @@ -0,0 +1,95 @@ +# $Date: 2011-07-12 02:18:25 +0200 (Di, 12. Jul 2011) $ +# $Revision: 773 $ +############################################################# +TOPLEVEL = $(shell pwd)/../.. + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + SDPATH=/ +else + SDPATH=../.. +endif + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(OBJDIR)/FormatDisk.o \ + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Subdirs +# + +SUBDIRS = $(filter-out Catalogs/sample/Scalos, $(wildcard Catalogs/*/Scalos)) + +############################################################################## +# +# Targets +# + +NAME = FormatDisk.module +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) \ + all_subdirs + +############################################################################## + +$(OBJDIR)/%.o: $(TOOLTYPE_DIR)/%.c + @$(run-cc) + +$(OBJDIR)/%.o: $(ICONOBJMCC_DIR)/%.c + @$(run-cc) + +FormatDisk.c : $(OBJDIR)/FormatDisk_Locale.h + +$(OBJDIR)/FormatDisk_Locale.h : FormatDiskMUI.cd + @$(ECHO) "FlexCat $@" + $(FLEXCAT) $< $@=$(SDPATH)/CatComp_h.sd + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + @$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) +ifneq ($(MACHINE), ppc-amigaos) + -@chmod u+x $@ +endif + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) Scalos:modules/ clone + +install: install_subdirs + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* \ + $(OBJDIR)/FormatDisk_Locale.h + +clean: clean_subdirs + +############################################################################## + diff --git a/scalos/Modules/IconProperties.MUI/Catalogs/deutsch/Scalos/IconProperties.ct b/scalos/Modules/IconProperties.MUI/Catalogs/deutsch/Scalos/IconProperties.ct new file mode 100644 index 000000000..9a72c364b --- /dev/null +++ b/scalos/Modules/IconProperties.MUI/Catalogs/deutsch/Scalos/IconProperties.ct @@ -0,0 +1,161 @@ +; IconProperties.ct +## version $VER: IconProperties.catalog 40.6 (05. Oct 2005 18:50:08) +## codeset 0 +## language deutsch +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Piktogramm-Eigenschaften +; +; +MSGID_OKBUTTON +Speichern +; Ok +; +MSGID_SHORTHELP_OKBUTTON +Alle Änderungen in den Merkmalen\n\ +des Piktogramms speichern.\n\ +Gegebenenfalls wird ein neues Piktogramm\n\ +aus dem Standardpiktogramm erzeugt. +;Save the changes in the icon's tooltypes.\n\ +;If necessary, a new icon will be created\n\ +;from a the default icon. +; +; +MSGID_CANCELBUTTON +Abbruch +;Cancel +; +; +MSGID_SHORTHELP_CANCELBUTTON +Alle Änderungen verwerfen und\n\ +Piktogramm unverändert belassen. +;Discard all changes and\n\ +;leave the icon unchanged. +; +; +MSGID_CHECKMARK_NOTEXT +Piktogrammtext unterdrücken +;Hide Icon Text +; +; +MSGID_CHECKMARK_NOTEXT_SHORTHELP +Wenn dieser Schalter eingeschaltet ist, wird\n\ +zu diesem Piktogramm kein Text angezeigt. +;Suppress display of the icon's name. +; +; +MSGID_CHECKMARK_NODRAG +Piktogramm nicht verschiebbar +;Icon cannot be moved +; +; +MSGID_CHECKMARK_NODRAG_SHORTHELP +Wenn dieser Schalter eingeschaltet ist, kann\n\ +dieses Piktogramm nicht mehr innerhalb seines\n\ +Fensters verschoben werden.\n\ +Kopieren ist auch dann jederzeit möglich. +;The icon cannot be moved inside its window.\n\ +;Copying is still possible, however. +; +; +MSGID_READ_ONLY +(Schreibgeschützt) +;(Read-Only) +; +; +MSGID_TEXT_ICONNAME_SHORTHELP +Piktogramm-Name +; Icon name +; +; +MSGID_TEXT_ICONPATH_SHORTHELP +Piktogramm-Pfad +;Icon path +; +; +MSGID_CHECKMARK_NOTOOLTIPS +Keine Tooltips zeigen +;Suppress Tooltips +; +; +MSGID_CHECKMARK_NOTOOLTIPS_SHORTHELP +Wenn dieser Schalter eingeschaltet ist, werden\n\ +keine Tooltips angezeigt, wenn der Mauszeiger\n\ +über dem Piktrogramm bleibt. +;No tooltips are displayed when the\n\ +;mouse pointer is held over this icon. +; +; +; +MSGID_CHECKMARK_BROWSERMODE +Einzelfenster-Modus +;Browser mode +; +; +MSGID_CHECKMARK_BROWSERMODE_SHORTHELP +In dieser Betriebsart werden für Verzeichnisse\n\ +und Datenträger keine neuen Fenster geöffnet,\n\ +sondern ihr Inhalt erscheint im aktuellen Fenster.\n\ +Verfügbar bei Datenträgern, Paperkörben und Verzeichnissen. +;Activate the browser mode.\n\ +;Availlable for disks, trashcans and drawers. +; +;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Projekt +;Project +; +; +MSGID_MENU_PROJECT_ABOUT +Über... +;About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Über MUI... +;About MUI... +; +; +MSGID_MENU_PROJECT_QUIT +Beenden +;Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +;Q +; +; +MSGID_MENU_IMAGE +Piktogramm-Bild +;Icon Image +; +; +MSGID_MENU_IMAGE_DEFAULT +Standardbild +;Default +; +; +MSGID_MENU_IMAGE_DEFAULT_SHORT +D +;D +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +_OK +;_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos IconProperties.module V%ld.%ld\033n\n\ +%s\n\ +© 2004%s Das Scalos-Team +;\33c\033bScalos IconProperties.module V%ld.%ld\033n\n\ +;© 2004%s The Scalos Team +; +;----------------------------------------------------------- diff --git a/scalos/Modules/IconProperties.MUI/Catalogs/deutsch/Scalos/config.mk b/scalos/Modules/IconProperties.MUI/Catalogs/deutsch/Scalos/config.mk new file mode 100755 index 000000000..8631b0623 --- /dev/null +++ b/scalos/Modules/IconProperties.MUI/Catalogs/deutsch/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = deutsch + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = german + +else + +############################################################################### +# AmigaOS and AROS + +LANG = deutsch + +endif +endif diff --git a/scalos/Modules/IconProperties.MUI/Catalogs/deutsch/Scalos/makefile b/scalos/Modules/IconProperties.MUI/Catalogs/deutsch/Scalos/makefile new file mode 100644 index 000000000..1e4275b5d --- /dev/null +++ b/scalos/Modules/IconProperties.MUI/Catalogs/deutsch/Scalos/makefile @@ -0,0 +1,13 @@ +# makefile for IconProperties.module (translated Texts : deutsch) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mdeutsch\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +IconProperties.catalog : IconProperties.ct ../../../IconProperties.cd + +All: IconProperties.catalog diff --git a/scalos/Modules/IconProperties.MUI/Catalogs/deutsch/Scalos/makefile-new b/scalos/Modules/IconProperties.MUI/Catalogs/deutsch/Scalos/makefile-new new file mode 100644 index 000000000..d1345a264 --- /dev/null +++ b/scalos/Modules/IconProperties.MUI/Catalogs/deutsch/Scalos/makefile-new @@ -0,0 +1,30 @@ +# makefile for IconProperties.module (translated Texts : deutsch) +# $Date: 2011-07-24 10:11:00 +0200 (So, 24. Jul 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = IconProperties + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git "a/scalos/Modules/IconProperties.MUI/Catalogs/fran\303\247ais/Scalos/IconProperties.ct" "b/scalos/Modules/IconProperties.MUI/Catalogs/fran\303\247ais/Scalos/IconProperties.ct" new file mode 100755 index 000000000..90a37dcc7 --- /dev/null +++ "b/scalos/Modules/IconProperties.MUI/Catalogs/fran\303\247ais/Scalos/IconProperties.ct" @@ -0,0 +1,156 @@ +; IconProperties.ct +; $Date$ +; $Revision$ +## version $VER: IconProperties.catalog 40.6 (05. Oct 2005 18:50:08) +## codeset 0 +## language français +; +;#arrayopts static __far +; +MSGID_TITLENAME +Scalos Propriétés d'icônes +; Scalos Icon Properties +; +; +MSGID_OKBUTTON +Sauver +; Ok +; +; +MSGID_SHORTHELP_OKBUTTON +Enregistre les changements dans les types\n\ +d'outils de l'icône.\n\ +Si nécessaire, une nouvelle icône sera\n\ +créée d'après le type d'icône par défaut. +; Save the changes in the icon's tooltypes.\n\ +; If necessary, a new icon will be\n\ +; created from a the default icon. +; +; +MSGID_CANCELBUTTON +Annuler +; Cancel +; +; +MSGID_SHORTHELP_CANCELBUTTON +Oublier tout changement en cours.\n\ +L'icône ne sera pas modifiée. +; Discard all changes and\n\ +; leave the icon unchanged. +; +; +MSGID_CHECKMARK_NOTEXT +Caher le texte de l'icône +; Hide Icon Text +; +; +MSGID_CHECKMARK_NOTEXT_SHORTHELP +Supprime l'affichage du texte de l'icône. +; Suppress display of the icon's name. +; +; +MSGID_CHECKMARK_NODRAG +Figer la position de l'icône +; Icon cannot be moved +; +; +MSGID_CHECKMARK_NODRAG_SHORTHELP +L'icône ne pourra être déplacer dans sa fenêtre.\n\ +Toutefois, la copie reste toujours possible. +; The icon cannot be moved inside its window.\n\ +; Copying is still possible, however. +; +; +MSGID_READ_ONLY +(Protégé en écriture) +; (Read-Only) +; +; +MSGID_TEXT_ICONNAME_SHORTHELP +Nom de l'icône +; Icon name +; +; +MSGID_TEXT_ICONPATH_SHORTHELP +Chemin d'accès de l'icône +; Icon path +; +; +MSGID_CHECKMARK_NOTOOLTIPS +Désactiver la bulle d'informations +;Suppress Tooltips +; +; +MSGID_CHECKMARK_NOTOOLTIPS_SHORTHELP +Aucune information ne sera affichée lorsque le\n\ +curseur de la souris se trouvera au dessus de cette icône. +;No tooltips are displayed when the\n\ +;mouse pointer is held over this icon. +; +; +MSGID_CHECKMARK_BROWSERMODE +Mode navigateur +;Browser mode +; +; +MSGID_CHECKMARK_BROWSERMODE_SHORTHELP +Activater le mode navigateur.\n\ +Option disponible pour les volumes, corbeilles et répertoires. +;Activate the browser mode.\n\ +;Availlable for disks, trashcans and drawers. +; +;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Projet +; Project +; +; +MSGID_MENU_PROJECT_ABOUT +A propos... +; About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI +A propos de MUI... +; About MUI... +; +; +MSGID_MENU_PROJECT_QUIT +Quitter +; Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +;Q +; +MSGID_MENU_IMAGE +Image de l'icône +;Icon Image +; +; +MSGID_MENU_IMAGE_DEFAULT +Image par défaut +;Default +; +; +MSGID_MENU_IMAGE_DEFAULT_SHORT +D +;D +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +D'_accord +; _OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Main IconProperties.module V\0333%ld\0332.\0333%ld\0332\033n\n\ +Compilé sous : \0333%s\0332\n\ +© 2004%s The Scalos Team +; \33c\033bScalos Main IconProperties.module V%ld.%ld\033n\n\ +; © 2004 The Scalos Team +; +;----------------------------------------------------------- diff --git "a/scalos/Modules/IconProperties.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" "b/scalos/Modules/IconProperties.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" new file mode 100755 index 000000000..8b7056423 --- /dev/null +++ "b/scalos/Modules/IconProperties.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" @@ -0,0 +1,40 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = français + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = french + +else + +############################################################################### +# AmigaOS and AROS + +LANG = français + +endif +endif diff --git "a/scalos/Modules/IconProperties.MUI/Catalogs/fran\303\247ais/Scalos/makefile" "b/scalos/Modules/IconProperties.MUI/Catalogs/fran\303\247ais/Scalos/makefile" new file mode 100644 index 000000000..3f1151a45 --- /dev/null +++ "b/scalos/Modules/IconProperties.MUI/Catalogs/fran\303\247ais/Scalos/makefile" @@ -0,0 +1,13 @@ +# makefile for IconProperties.module (translated Texts : français) +# $Date: 17 Aug 2004 20:12:47 + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mfrançais\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +IconProperties.catalog : IconProperties.ct ../../../IconProperties.cd + +All: IconProperties.catalog diff --git "a/scalos/Modules/IconProperties.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" "b/scalos/Modules/IconProperties.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" new file mode 100644 index 000000000..53b67af86 --- /dev/null +++ "b/scalos/Modules/IconProperties.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" @@ -0,0 +1,30 @@ +# makefile for IconProperties.module (translated Texts : français) +# $Date: 2011-07-24 10:11:00 +0200 (So, 24. Jul 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = IconProperties + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Modules/IconProperties.MUI/Catalogs/sample/Scalos/IconProperties.ct b/scalos/Modules/IconProperties.MUI/Catalogs/sample/Scalos/IconProperties.ct new file mode 100644 index 000000000..821f46875 --- /dev/null +++ b/scalos/Modules/IconProperties.MUI/Catalogs/sample/Scalos/IconProperties.ct @@ -0,0 +1,128 @@ +; IconProperties.ct +## version $VER: IconProperties.catalog 40.6 (05. Oct 2005 18:50:08) +## codeset 0s +## language xxxxxx +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Icon Properties +; +; +MSGID_OKBUTTON +Save +; +; +MSGID_SHORTHELP_OKBUTTON +Save the changes in the icon's tooltypes.\n\ +If necessary, a new icon will be created\n\ +from a the default icon. +; +; +MSGID_CANCELBUTTON +Cancel +; +; +MSGID_SHORTHELP_CANCELBUTTON +Discard all changes and\n\ +leave the icon unchanged. +; +; +MSGID_CHECKMARK_NOTEXT +Hide Icon Text +; +; +MSGID_CHECKMARK_NOTEXT_SHORTHELP +Suppress display of the icon's name. +; +; +MSGID_CHECKMARK_NODRAG +Icon cannot be moved +; +; +MSGID_CHECKMARK_NODRAG_SHORTHELP +The icon cannot be moved inside its window.\n\ +Copying is still possible, however. +; +; +MSGID_READ_ONLY +(Read-Only) +; +; +MSGID_TEXT_ICONNAME_SHORTHELP +Icon name +; +; +MSGID_TEXT_ICONPATH_SHORTHELP +Icon path +; +;+++translateme+++ +MSGID_CHECKMARK_NOTOOLTIPS +Suppress Tooltips +;Suppress Tooltips +; +;+++translateme+++ +MSGID_CHECKMARK_NOTOOLTIPS_SHORTHELP +No tooltips are displayed when the\n\ +mouse pointer is held over this icon. +;No tooltips are displayed when the\n\ +;mouse pointer is held over this icon. +; +; +;+++translateme+++ +MSGID_CHECKMARK_BROWSERMODE +Browser mode +;Browser mode +; +;+++translateme+++ +MSGID_CHECKMARK_BROWSERMODE_SHORTHELP +Activate the browser mode.\n\ +Availlable for disks, trashcans and drawers. +;Activate the browser mode.\n\ +;Availlable for disks, trashcans and drawers. +; +;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Project +; +; +MSGID_MENU_PROJECT_ABOUT +About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI +About MUI... +; +; +MSGID_MENU_PROJECT_QUIT +Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +; +MSGID_MENU_IMAGE +Icon Image +; +; +MSGID_MENU_IMAGE_DEFAULT +Default +; +; +MSGID_MENU_IMAGE_DEFAULT_SHORT +D +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Main IconProperties.module V%ld.%ld\033n\n\ +© 2004 The Scalos Team +; +;----------------------------------------------------------- diff --git a/scalos/Modules/IconProperties.MUI/IconProperties.c b/scalos/Modules/IconProperties.MUI/IconProperties.c new file mode 100644 index 000000000..34818080d --- /dev/null +++ b/scalos/Modules/IconProperties.MUI/IconProperties.c @@ -0,0 +1,1484 @@ +// IconProperties.c +// $Date$ +// $Revision$ +// $Id$ + +// NOTE: Replaced "VSpace(0)" by "RectangleObject" before +// "IconobjectMCCObject" and after "CheckMarkNoDrag ImageObject" and, +// removed VSpace(0) between groupframe and "Group_Buttons2 = HGroup", +// to show entirely the window's title. + +#ifdef __AROS__ +#define MUIMASTER_YES_INLINE_STDARG +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include // +jmc+ + +#include "IconProperties.h" +#include "IconobjectMCC.h" +#include "ToolTypes.h" +#include "debug.h" + +#define IconProperties_NUMBERS +#define IconProperties_ARRAY +#define IconProperties_CODE +#include STR(SCALOSLOCALE) + +//---------------------------------------------------------------------------- + +#define VERSION_MAJOR 40 +#define VERSION_MINOR 8 + +#define VERS_MAJOR STR(VERSION_MAJOR) +#define VERS_MINOR STR(VERSION_MINOR) +//---------------------------------------------------------------------------- + +#define ID_MAIN MAKE_ID('M','A','I','N') +#define PS_DATA(prefsstruct) ((STRPTR) (prefsstruct)) + sizeof((prefsstruct)->ps_Size) + +//---------------------------------------------------------------------------- + +#if !defined(__amigaos4__) && !defined(__AROS__) +#include + +long _stack = 16384; // minimum stack size, used by SAS/C startup code +#endif + +//---------------------------------------------------------------------------- + +// local data structures + +#define KeyButtonHelp(name,key,HelpText)\ + TextObject,\ + ButtonFrame,\ + MUIA_Font, MUIV_Font_Button,\ + MUIA_Text_Contents, name,\ + MUIA_Text_PreParse, "\33c",\ + MUIA_Text_HiChar , key,\ + MUIA_ControlChar , key,\ + MUIA_InputMode , MUIV_InputMode_RelVerify,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_CycleChain, TRUE, \ + MUIA_ShortHelp, HelpText,\ + End + + +#define Application_Return_Ok 1001 +#define Application_Return_Path 1002 + +//---------------------------------------------------------------------------- + +// local functions + +static void init(void); +static void fail(APTR APP_Main, CONST_STRPTR str); +static BOOL OpenLibraries(void); +static void CloseLibraries(void); +static SAVEDS(APTR) INTERRUPT OpenAboutMUIFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT OpenAboutFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT AppMessageHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT DefaultIconHookFunc(struct Hook *hook, Object *o, Msg msg); + +static STRPTR GetLocString(ULONG MsgId); +//static void TranslateStringArray(STRPTR *stringArray); +static void SaveSettings(Object *IconObj, CONST_STRPTR IconName); +static Object *GetIconObject(CONST_STRPTR IconName, BPTR DirLock); +static Object *GetDeviceIconObject(CONST_STRPTR IconName, CONST_STRPTR VolumeName, CONST_STRPTR DeviceName); +static BOOL isDiskWritable(BPTR dLock); +static ULONG CheckInfoData(const struct InfoData *info); +static BOOL IsDevice(struct WBArg *arg); +static void GetDeviceName(BPTR dLock, STRPTR DeviceName, size_t MaxLen); +static BOOL ReadScalosPrefs(void); +static CONST_STRPTR GetPrefsConfigString(APTR prefsHandle, ULONG Id, CONST_STRPTR DefaultString); +static void StripTrailingChar(STRPTR String, char CharToRemove); +static void BuildDefVolumeNameNoSpace(STRPTR Buffer, CONST_STRPTR VolumeName, size_t MaxLength); +static void ReplaceIcon(Object *NewIconObj, Object **OldIconObj); +static struct ScaWindowStruct *FindScalosWindow(BPTR dirLock); + + +static struct Hook AppMessageHook = {{ NULL, NULL }, HOOKFUNC_DEF(AppMessageHookFunc), NULL }; +static struct Hook DefaultIconHook = {{ NULL, NULL }, HOOKFUNC_DEF(DefaultIconHookFunc), NULL }; + +//---------------------------------------------------------------------------- + +// local data items + +static UBYTE prefDefIconsFirst = TRUE; // Flag: try Def-Diskicons first +static CONST_STRPTR prefDefIconPath = "ENV:sys"; + +struct IntuitionBase *IntuitionBase = NULL; +struct Library *MUIMasterBase = NULL; +struct Library *IconBase = NULL; +struct Library *IconobjectBase = NULL; +struct ScalosBase *ScalosBase = NULL; +struct Library *PreferencesBase = NULL; +T_LOCALEBASE LocaleBase = NULL; + +#ifdef __amigaos4__ +struct IntuitionIFace *IIntuition = NULL; +struct MUIMasterIFace *IMUIMaster = NULL; +struct IconIFace *IIcon = NULL; +struct IconobjectIFace *IIconobject = NULL; +struct ScalosIFace *IScalos = NULL; +struct PreferencesIFace *IPreferences = NULL; +struct LocaleIFace *ILocale = NULL; +#endif + +static struct Catalog *IconPropertiesCatalog; + +static struct Hook AboutHook = + { + { NULL, NULL }, + HOOKFUNC_DEF(OpenAboutFunc), + NULL + }; +static struct Hook AboutMUIHook = + { + { NULL, NULL }, + HOOKFUNC_DEF(OpenAboutMUIFunc), + NULL + }; + +static APTR Group_Buttons2; +static APTR APP_Main; +static APTR WIN_Main; +static APTR WIN_AboutMUI; +static APTR OkButton, CancelButton; +static Object *CheckMarkNoText, *CheckMarkNoDrag; +static Object *CheckMarkNoToolTips; +static Object *MenuAbout, *MenuAboutMUI, *MenuQuit, *Path, *IconImage, *GroupMccIconObj; +static Object *Group_Virtual; //+jmc+ To switch 0/1 "MUIA_ShowMe" the ScroolGroupObject group. +static Object *CheckMarkBrowserMode; //+jmc+ BrowserMode tooltype. +static Object *MenuImageDefault; + +static struct MUI_CustomClass *IconobjectClass; + +//---------------------------------------------------------------------------- + +int main(int argc, char *argv[]) +{ + LONG win_opened; + BPTR oldDir = (BPTR)NULL; + CONST_STRPTR IconName = ""; + Object *iconObj = NULL; + BOOL IsWriteable = TRUE; + static char PathName[512]; + LONG selected; + struct WBStartup *WBenchMsg = + (argc == 0) ? (struct WBStartup *)argv : NULL; + + init(); + + if (WBenchMsg && WBenchMsg->sm_ArgList) + { + struct WBArg *arg; + + if (WBenchMsg->sm_NumArgs > 1) + { + arg = &WBenchMsg->sm_ArgList[1]; + + IconName = arg->wa_Name; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: wa_Lock=%08lx\n", __LINE__, arg->wa_Lock)); + + oldDir = CurrentDir(arg->wa_Lock); + + if (IsDevice(arg)) + { + static char VolumeName[256]; + char DeviceName[256]; + + NameFromLock(arg->wa_Lock, VolumeName, sizeof(VolumeName)); + GetDeviceName(arg->wa_Lock, DeviceName, sizeof(DeviceName)); + + StripTrailingChar(VolumeName, ':'); + StripTrailingChar(DeviceName, ':'); + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: VolumeName=<%s>\n", __LINE__, VolumeName)); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: DeviceName=<%s>\n", __LINE__, DeviceName)); + + iconObj = GetDeviceIconObject(IconName, VolumeName, DeviceName); + + IconName = VolumeName; + } + else + { + ULONG Pos; + char xName[256]; + + stccpy(xName, arg->wa_Name, sizeof(xName)); + Pos = IsIconName(xName); + + if (Pos && ~0 != Pos) + *((char *) Pos) = '\0'; + + iconObj = GetIconObject(xName, arg->wa_Lock); + + NameFromLock(arg->wa_Lock,PathName,sizeof(PathName)); + } + IsWriteable = isDiskWritable(arg->wa_Lock); + } + } + + DefaultIconHook.h_Data = &iconObj; + AppMessageHook.h_Data = &iconObj; + + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: IconObj=%08lx\n", __LINE__, iconObj)); + + if ((strlen(IconName) > 0 && iconObj)) + { + ULONG NoText = FALSE; + ULONG NoDrag = FALSE; + ULONG NoToolTip = FALSE; + ULONG BrowserMode = FALSE; + BOOL BrowserSupported = FALSE; + ULONG IconType; + STRPTR tt; + + GetAttr(IDTA_Type, iconObj, (IPTR *)&IconType); + + if ((WBDISK == IconType) || (WBDRAWER == IconType) || (WBGARBAGE == IconType)) + BrowserSupported = TRUE; + + tt = NULL; + if (DoMethod(iconObj, IDTM_FindToolType, "SCALOS_NOTEXT", &tt)) + NoText = TRUE; + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: tt=%08lx\n", __LINE__, tt)); + + tt = NULL; + if (DoMethod(iconObj, IDTM_FindToolType, "SCALOS_NODRAG", &tt)) + NoDrag = TRUE; + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: tt=%08lx\n", __LINE__, tt)); + + tt = NULL; + if (DoMethod(iconObj, IDTM_FindToolType, "SCALOS_NOTOOLTIPS", &tt)) + NoToolTip = TRUE; + + tt = NULL; + if (DoMethod(iconObj, IDTM_FindToolType, "SCALOS_BROWSERMODE", &tt)) + BrowserMode = TRUE; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: tt=%08lx\n", __LINE__, tt)); + + + APP_Main = ApplicationObject, + MUIA_Application_Title, GetLocString(MSGID_TITLENAME), + MUIA_Application_Version, "$VER: Scalos IconProperties.module V" VERS_MAJOR "." VERS_MINOR " (" __DATE__ ") " COMPILER_STRING, + MUIA_Application_Copyright, "© The Scalos Team, 2004" CURRENTYEAR, + MUIA_Application_Author, "The Scalos Team", + MUIA_Application_Description, "Scalos Icon Properties module", + MUIA_Application_Base, "SCALOS_ICON_PROPERTIES", + + SubWindow, WIN_Main = WindowObject, + MUIA_Window_Title, GetLocString(MSGID_TITLENAME), +// MUIA_Window_ID, MAKE_ID('M','A','I','N'), + MUIA_Window_AppWindow, TRUE, + + MUIA_Window_TopEdge, MUIV_Window_TopEdge_Moused, + MUIA_Window_LeftEdge, MUIV_Window_LeftEdge_Moused, + + MUIA_Window_Width, MUIV_Window_Width_MinMax(0), + MUIA_Window_Height, MUIV_Window_Height_MinMax(0), + + WindowContents, VGroup, + Child, VGroup, + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, TextObject, + MUIA_Text_PreParse, MUIX_C MUIX_B, + MUIA_Text_Contents, IconName, + TextFrame, + MUIA_Background, MUII_TextBack, + MUIA_ShortHelp, GetLocString(MSGID_TEXT_ICONNAME_SHORTHELP), + End, //TextObject + + Child, TextObject, + MUIA_ShowMe, !IsWriteable, + MUIA_Text_PreParse, MUIX_C, + MUIA_Text_Contents, GetLocString(MSGID_READ_ONLY), + End, //TextObject + + // Child, VSpace(0), + + Child, HGroup, + Child, GroupMccIconObj = HGroup, + Child, RectangleObject, End, //--- Instead: Child, VSpace(0) + + Child, IconImage = IconobjectMCCObject, + MUIA_Iconobj_Object, iconObj, + MUIA_InputMode, MUIV_InputMode_Toggle, + MUIA_ShowSelState, FALSE, + End, //IconobjectMCCObject + End, //VGroup + + Child, VSpace(0), + + Child, ColGroup(2), + Child, Label1(GetLocString(MSGID_CHECKMARK_NOTEXT)), + Child, CheckMarkNoText = ImageObject, + ImageButtonFrame, + MUIA_CycleChain, TRUE, + MUIA_InputMode, MUIV_InputMode_Toggle, + MUIA_Image_Spec, MUII_CheckMark, + MUIA_Image_FreeVert, TRUE, + MUIA_Selected, NoText, + MUIA_Disabled, !IsWriteable, + MUIA_Background, MUII_ButtonBack, + MUIA_ShowSelState, FALSE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_CHECKMARK_NOTEXT_SHORTHELP), + End, //Image + + Child, Label1(GetLocString(MSGID_CHECKMARK_NODRAG)), + Child, CheckMarkNoDrag = ImageObject, + ImageButtonFrame, + MUIA_CycleChain, TRUE, + MUIA_InputMode, MUIV_InputMode_Toggle, + MUIA_Image_Spec, MUII_CheckMark, + MUIA_Image_FreeVert, TRUE, + MUIA_Selected, NoDrag, + MUIA_Disabled, !IsWriteable, + MUIA_Background, MUII_ButtonBack, + MUIA_ShowSelState, FALSE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_CHECKMARK_NODRAG_SHORTHELP), + End, //Image + + Child, Label1(GetLocString(MSGID_CHECKMARK_NOTOOLTIPS)), + Child, CheckMarkNoToolTips = ImageObject, + ImageButtonFrame, + MUIA_CycleChain, TRUE, + MUIA_InputMode, MUIV_InputMode_Toggle, + MUIA_Image_Spec, MUII_CheckMark, + MUIA_Image_FreeVert, TRUE, + MUIA_Selected, NoToolTip, + MUIA_Disabled, !IsWriteable, + MUIA_Background, MUII_ButtonBack, + MUIA_ShowSelState, FALSE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_CHECKMARK_NOTOOLTIPS_SHORTHELP), + End, //Image + + Child, Label1(GetLocString(MSGID_CHECKMARK_BROWSERMODE)), + Child, CheckMarkBrowserMode = ImageObject, + ImageButtonFrame, + MUIA_CycleChain, TRUE, + MUIA_InputMode, MUIV_InputMode_Toggle, + MUIA_Image_Spec, MUII_CheckMark, + MUIA_Image_FreeVert, TRUE, + MUIA_Selected, BrowserMode, + MUIA_Disabled, (!IsWriteable || !BrowserSupported), + MUIA_Background, MUII_ButtonBack, + MUIA_ShowSelState, FALSE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_CHECKMARK_BROWSERMODE_SHORTHELP), + End, //Image + + End, //ColGroup + + Child, RectangleObject, End, //--- Instead: Child, VSpace(0) + + End, //HGroup + + Child, Group_Virtual = ScrollgroupObject, // +jmc+ + MUIA_CycleChain, TRUE, + MUIA_Scrollgroup_VertBar, NULL, + MUIA_Scrollgroup_HorizBar, NULL, + MUIA_Scrollgroup_FreeHoriz, TRUE, + MUIA_Scrollgroup_FreeVert, FALSE, + MUIA_Scrollgroup_Contents, + VirtgroupObject, + Child, Path = TextObject, TextFrame, + MUIA_Background, MUII_TextBack, + MUIA_Text_PreParse, MUIX_C, + MUIA_Text_Contents, PathName, + MUIA_ShortHelp, GetLocString(MSGID_TEXT_ICONPATH_SHORTHELP), + End, //TextObject + End, //VirtgroupObject + End, //ScrollgroupObject + + End, //VGroup, + + // Child, VSpace(0), //--- Removed + + Child, Group_Buttons2 = HGroup, + MUIA_Group_SameWidth, TRUE, + Child, OkButton = KeyButtonHelp(GetLocString(MSGID_OKBUTTON), + 'o', GetLocString(MSGID_SHORTHELP_OKBUTTON)), + Child, CancelButton = KeyButtonHelp(GetLocString(MSGID_CANCELBUTTON), + 'c', GetLocString(MSGID_SHORTHELP_CANCELBUTTON)), + End, //HGroup + End, //VGroup + End, //WindowObject + + MUIA_Application_Menustrip, MenustripObject, + Child, MenuObjectT(GetLocString(MSGID_MENU_PROJECT)), + + Child, MenuAbout = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUT), + End, + Child, MenuAboutMUI = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUTMUI), + End, + Child, MenuitemObject, + MUIA_Menuitem_Title, -1, + End, + Child, MenuQuit = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_QUIT), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_PROJECT_QUIT_SHORT), + End, + + End, //MenuObjectT + + Child, MenuObjectT(GetLocString(MSGID_MENU_IMAGE)), + Child, MenuImageDefault = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_IMAGE_DEFAULT), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_IMAGE_DEFAULT_SHORT), + End, + End, //MenuObjectT + + End, //MenuStripObject + + End; //ApplicationObject + + if (NULL == APP_Main) + { + fail(APP_Main, "Failed to create Application."); + } + + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + WIN_Main, 3, MUIM_Set, MUIA_Window_Open, FALSE); + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + DoMethod(CancelButton, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + DoMethod(OkButton, MUIM_Notify,MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_Application_ReturnID, Application_Return_Ok); + + //--------------------------------------------------------------------------// + + // call hook when menu command "icon image/default" is issued + DoMethod(MenuImageDefault, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &DefaultIconHook); + + // setup notification when an icon is dropped onto the icon image + DoMethod(GroupMccIconObj, MUIM_Notify, MUIA_AppMessage, MUIV_EveryTime, + GroupMccIconObj, 3, MUIM_CallHook, &AppMessageHook, MUIV_TriggerValue); + + //--------------------------------------------------------------------------// + + DoMethod(MenuAbout, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &AboutHook); + DoMethod(MenuAboutMUI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &AboutMUIHook); + DoMethod(MenuQuit, MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + DoMethod(IconImage, MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + APP_Main, 3, MUIM_Application_ReturnID, Application_Return_Path); + + DoMethod(IconImage, MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + APP_Main, 3, MUIM_WriteLong, MUIV_TriggerValue, &selected); + + // disable Ok button for read-only icons + set(OkButton, MUIA_Disabled, !IsWriteable); + set(Group_Virtual, MUIA_ShowMe, 0); + + set(WIN_Main, MUIA_Window_Open, TRUE); + get(WIN_Main, MUIA_Window_Open, &win_opened); + + if (win_opened) + { + ULONG sigs = 0; + BOOL Run = TRUE; + + while (Run) + { + ULONG Action = DoMethod(APP_Main, MUIM_Application_NewInput, &sigs); + + switch (Action) + { + case Application_Return_Ok: + SaveSettings(iconObj, IconName); + Run = FALSE; + break; + case Application_Return_Path: + if(strlen(PathName) > 0) + set(Group_Virtual, MUIA_ShowMe, selected); + break; + case MUIV_Application_ReturnID_Quit: + Run = FALSE; + break; + } + + if (Run && sigs) + { + sigs = Wait(sigs | SIGBREAKF_CTRL_C); + + if (sigs & SIGBREAKF_CTRL_C) + { + Run = FALSE; + } + } + } + } + else + { + printf("failed to open main window !\n"); + } + + set(WIN_Main, MUIA_Window_Open, FALSE); + } + + if (iconObj) + DisposeIconObject(iconObj); + if (oldDir) + CurrentDir(oldDir); + + fail(APP_Main, NULL); + + return 0; +} + + +static VOID fail(APTR APP_Main, CONST_STRPTR str) +{ + if (APP_Main) + { + MUI_DisposeObject(APP_Main); + } + if (IconobjectClass) + { + CleanupIconobjectClass(IconobjectClass); + IconobjectClass = NULL; + } + if (IconPropertiesCatalog) + { + CloseCatalog(IconPropertiesCatalog); + IconPropertiesCatalog = NULL; + } + + CloseLibraries(); + + if (str) + { + puts(str); + exit(20); + } + + exit(0); +} + + +static void init(void) +{ + if (!OpenLibraries()) + fail(NULL, "Failed to call OpenLibraries()"); + + if (LocaleBase) + IconPropertiesCatalog = OpenCatalogA(NULL, "Scalos/IconProperties.catalog", NULL); + + IconobjectClass = InitIconobjectClass(); + + ReadScalosPrefs(); +} + + +static BOOL OpenLibraries(void) +{ + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + if (NULL == IntuitionBase) + fail(NULL, "Failed to open intuition.library."); +#ifdef __amigaos4__ + else + { + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + fail(NULL, "Failed to open intuition interface."); + } +#endif + + MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN-1); + if (NULL == MUIMasterBase) + fail(NULL, "Failed to open "MUIMASTER_NAME"."); +#ifdef __amigaos4__ + else + { + IMUIMaster = (struct MUIMasterIFace *)GetInterface((struct Library *)MUIMasterBase, "main", 1, NULL); + if (NULL == IMUIMaster) + fail(NULL, "Failed to open muimaster interface."); + } +#endif + + IconBase = OpenLibrary("icon.library", 0); + if (NULL == IconBase) + fail(NULL, "Failed to open icon.library"); +#ifdef __amigaos4__ + else + { + IIcon = (struct IconIFace *)GetInterface((struct Library *)IconBase, "main", 1, NULL); + if (NULL == IIcon) + fail(NULL, "Failed to open icon interface."); + } +#endif + + ScalosBase = (struct ScalosBase *) OpenLibrary("scalos.library", 40); + if (NULL == ScalosBase) + fail(NULL, "Failed to open scalos.library"); +#ifdef __amigaos4__ + else + { + IScalos = (struct ScalosIFace *)GetInterface((struct Library *)ScalosBase, "main", 1, NULL); + if (NULL == IScalos) + fail(NULL, "Failed to open scalos interface."); + } +#endif + + PreferencesBase = OpenLibrary("preferences.library", 39); + if (NULL == PreferencesBase) + fail(NULL, "Failed to open preferences.library."); +#ifdef __amigaos4__ + else + { + IPreferences = (struct PreferencesIFace *)GetInterface((struct Library *)PreferencesBase, "main", 1, NULL); + if (NULL == IPreferences) + fail(NULL, "Failed to open preferences interface."); + } +#endif + + IconobjectBase = OpenLibrary("iconobject.library", 0); + if (NULL == IconobjectBase) + fail(NULL, "Failed to open iconobject.library."); +#ifdef __amigaos4__ + else + { + IIconobject = (struct IconobjectIFace *)GetInterface((struct Library *)IconobjectBase, "main", 1, NULL); + if (NULL == IIconobject) + fail(NULL, "Failed to open iconobject interface."); + } +#endif + + LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 39); +#ifdef __amigaos4__ + if (NULL != LocaleBase) + { + ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL); + if (NULL == ILocale) + fail(NULL, "Failed to open locale interface"); + } +#endif + + return TRUE; +} + + +static void CloseLibraries(void) +{ + if (LocaleBase) + { + if (IconPropertiesCatalog) + { + CloseCatalog(IconPropertiesCatalog); + IconPropertiesCatalog = NULL; + } +#ifdef __amigaos4__ + if (ILocale) + { + DropInterface((struct Interface *)ILocale); + ILocale = NULL; + } +#endif + CloseLibrary((struct Library *) LocaleBase); + LocaleBase = NULL; + } +#ifdef __amigaos4__ + if (IIconobject) + { + DropInterface((struct Interface *)IIconobject); + IIconobject = NULL; + } +#endif + if (IconobjectBase) + { + CloseLibrary(IconobjectBase); + IconobjectBase = NULL; + } +#ifdef __amigaos4__ + if (IPreferences) + { + DropInterface((struct Interface *)IPreferences); + IPreferences = NULL; + } +#endif + if (PreferencesBase) + { + CloseLibrary(PreferencesBase); + PreferencesBase = NULL; + } +#ifdef __amigaos4__ + if (IScalos) + { + DropInterface((struct Interface *)IScalos); + IScalos = NULL; + } +#endif + if (ScalosBase) + { + CloseLibrary((struct Library *) ScalosBase); + ScalosBase = NULL; + } +#ifdef __amigaos4__ + if (IIcon) + { + DropInterface((struct Interface *)IIcon); + IIcon = NULL; + } +#endif + if (IconBase) + { + CloseLibrary(IconBase); + IconBase = NULL; + } +#ifdef __amigaos4__ + if (IMUIMaster) + { + DropInterface((struct Interface *)IMUIMaster); + IMUIMaster = NULL; + } +#endif + if (MUIMasterBase) + { + CloseLibrary(MUIMasterBase); + MUIMasterBase = NULL; + } +#ifdef __amigaos4__ + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } +#endif + if (IntuitionBase) + { + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } +} + +//---------------------------------------------------------------------------- + +static STRPTR GetLocString(ULONG MsgId) +{ + struct IconProperties_LocaleInfo li; + + li.li_Catalog = IconPropertiesCatalog; +#ifndef __amigaos4__ + li.li_LocaleBase = LocaleBase; +#else + li.li_ILocale = ILocale; +#endif + + return (STRPTR)GetIconPropertiesString(&li, MsgId); +} + +#if 0 +static void TranslateStringArray(STRPTR *stringArray) +{ + while (*stringArray) + { + *stringArray = GetLocString((ULONG) *stringArray); + stringArray++; + } +} +#endif + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT OpenAboutMUIFunc(struct Hook *hook, Object *o, Msg msg) +{ + if (NULL == WIN_AboutMUI) + { + WIN_AboutMUI = MUI_NewObject(MUIC_Aboutmui, + MUIA_Window_RefWindow, WIN_Main, + MUIA_Aboutmui_Application, APP_Main, + TAG_END); + } + + if (WIN_AboutMUI) + set(WIN_AboutMUI, MUIA_Window_Open, TRUE); + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT OpenAboutFunc(struct Hook *hook, Object *o, Msg msg) +{ + MUI_Request(APP_Main, WIN_Main, 0, NULL, + GetLocString(MSGID_ABOUTREQOK), + GetLocString(MSGID_ABOUTREQFORMAT), + VERSION_MAJOR, VERSION_MINOR, COMPILER_STRING, CURRENTYEAR); +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT DefaultIconHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + Object **OldIconObj = (Object **) hook->h_Data; + Object *NewIconObj; + IPTR IconType; + + GetAttr(IDTA_Type, *OldIconObj, &IconType); + NewIconObj = GetDefIconObject(IconType, NULL); + if (NewIconObj) + ReplaceIcon(NewIconObj, OldIconObj); +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT AppMessageHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct AppMessage *AppMsg = *(struct AppMessage **) msg; + Object **OldIconObj = (Object **) hook->h_Data; + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: AppMsg=%08lx am_NumArgs=%ld\n", __LINE__, AppMsg, AppMsg->am_NumArgs)); + + if (AppMsg->am_NumArgs >= 1) + { + struct WBArg *arg = &AppMsg->am_ArgList[0]; + BPTR OldDir; + Object *NewIconObj; + ULONG Pos; + char xName[256]; + STRPTR NewIconName; + + OldDir = CurrentDir(arg->wa_Lock); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: wa_Lock=%08lx wa_Name=<%s>\n", __LINE__, arg->wa_Lock, arg->wa_Name)); + + if (IsDevice(arg)) + { + static char VolumeName[256]; + char DeviceName[256]; + + NewIconName = "disk"; + + NameFromLock(arg->wa_Lock, VolumeName, sizeof(VolumeName)); + GetDeviceName(arg->wa_Lock, DeviceName, sizeof(DeviceName)); + + StripTrailingChar(VolumeName, ':'); + StripTrailingChar(DeviceName, ':'); + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: VolumeName=<%s>\n", __LINE__, VolumeName)); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: DeviceName=<%s>\n", __LINE__, DeviceName)); + + NewIconObj = GetDeviceIconObject(NewIconName, VolumeName, DeviceName); + + if (NewIconObj) + { + SetAttrs(NewIconObj, + IDTA_Type, WBDISK, + TAG_END); + } + } + else + { + if (strlen(arg->wa_Name) > 0) + { + stccpy(xName, arg->wa_Name, sizeof(xName)); + Pos = IsIconName(xName); + if (Pos && ~0 != Pos) + *((char *) Pos) = '\0'; + NewIconObj = GetIconObject(xName, arg->wa_Lock); + } + else + { + NameFromLock(arg->wa_Lock, xName, sizeof(xName)); + NewIconObj = GetIconObject(xName, arg->wa_Lock); // ParentDir(arg->wa_Lock) + } + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: xName=<%s>\n", __LINE__, xName)); + } + + if (NewIconObj) + ReplaceIcon(NewIconObj, OldIconObj); + + CurrentDir(OldDir); + } +} + +//---------------------------------------------------------------------------- + +static void ReplaceIcon(Object *NewIconObj, Object **OldIconObj) +{ + STRPTR str; + struct IBox *WinRect; + struct ExtGadget *ggOld = (struct ExtGadget *) *OldIconObj; + struct ExtGadget *ggNew = (struct ExtGadget *) NewIconObj; + IPTR ul; + IPTR IconType; + IPTR TheName; + STRPTR *ToolTypesArray = NULL; + + GetAttr(IDTA_Type, *OldIconObj, &IconType); + set(NewIconObj, IDTA_Type, IconType); + + GetAttr(DTA_Name, *OldIconObj, &TheName); + set(NewIconObj, DTA_Name, TheName); + + ggNew->BoundsLeftEdge = ggOld->LeftEdge + (ggNew->LeftEdge - ggNew->BoundsLeftEdge); + ggNew->BoundsTopEdge = ggOld->TopEdge + (ggNew->TopEdge - ggNew->BoundsTopEdge); + ggNew->LeftEdge = ggOld->LeftEdge; + ggNew->TopEdge = ggNew->TopEdge; + + + GetAttr(IDTA_ToolTypes, *OldIconObj, (APTR) &ToolTypesArray); + set(NewIconObj, IDTA_ToolTypes, (ULONG) ToolTypesArray); + + GetAttr(IDTA_DefaultTool, *OldIconObj, (APTR) &str); + set(NewIconObj, IDTA_DefaultTool, (ULONG) str); + + GetAttr(IDTA_WindowRect, *OldIconObj, (APTR) &WinRect); + set(NewIconObj, IDTA_WindowRect, (ULONG) WinRect); + + GetAttr(IDTA_WinCurrentX, *OldIconObj, &ul); + set(NewIconObj, IDTA_WinCurrentX, ul); + GetAttr(IDTA_WinCurrentY, *OldIconObj, &ul); + set(NewIconObj, IDTA_WinCurrentY, ul); + + GetAttr(IDTA_Flags, *OldIconObj, &ul); + set(NewIconObj, IDTA_Flags, ul); + + GetAttr(IDTA_ViewModes, *OldIconObj, &ul); + set(NewIconObj, IDTA_ViewModes, ul); + + set(IconImage, MUIA_Iconobj_Object, NewIconObj); + DisposeIconObject(*OldIconObj); + *OldIconObj = NewIconObj; +} + +//---------------------------------------------------------------------------- + +static void SaveSettings(Object *IconObj, CONST_STRPTR IconName) +{ + if (IconObj) + { + IPTR IconType; + ULONG Checked = 0; + char CheckName[256]; + ULONG Pos; + APTR UndoStep = NULL; + struct ScaWindowStruct *ws; + CONST_STRPTR *ToolTypesArray; + STRPTR *OldToolTypesArray; + BPTR dirLock = CurrentDir((BPTR) NULL); + + CurrentDir(dirLock); + ws = FindScalosWindow(dirLock); + + if (ws) + { + UndoStep = (APTR) DoMethod(ws->ws_WindowTask->mt_MainObject, SCCM_IconWin_BeginUndoStep); + } + + stccpy(CheckName, IconName, sizeof(CheckName)); + Pos = IsIconName(CheckName); + + if (Pos && ~0 != Pos) + { + // strip ".info" from name + *((char *) Pos) = '\0'; + IconName = CheckName; + IconObj = NewIconObject(IconName, NULL); + } + + GetAttr(IDTA_ToolTypes, IconObj, (APTR) &ToolTypesArray); + OldToolTypesArray = CloneToolTypeArray(ToolTypesArray, 0); + + GetAttr(IDTA_Type, IconObj, &IconType); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: IconType=%ld\n", __LINE__, IconType)); + if (WBDISK == IconType) + { + IconName = "disk"; + SetAttrs(IconObj, + DTA_Name, IconName, + TAG_END); + } + + get(CheckMarkNoText, MUIA_Selected, &Checked); + if (Checked) + SetToolType(IconObj, "SCALOS_NOTEXT", ""); + else + RemoveToolType(IconObj, "SCALOS_NOTEXT"); + + get(CheckMarkNoDrag, MUIA_Selected, &Checked); + if (Checked) + SetToolType(IconObj, "SCALOS_NODRAG", ""); + else + RemoveToolType(IconObj, "SCALOS_NODRAG"); + + get(CheckMarkNoToolTips, MUIA_Selected, &Checked); + if (Checked) + SetToolType(IconObj, "SCALOS_NOTOOLTIPS", ""); + else + RemoveToolType(IconObj, "SCALOS_NOTOOLTIPS"); + + get(CheckMarkBrowserMode, MUIA_Selected, &Checked); + if (Checked) + SetToolType(IconObj, "SCALOS_BROWSERMODE", ""); + else + RemoveToolType(IconObj, "SCALOS_BROWSERMODE"); + + if (ws) + { + CONST_STRPTR *NewToolTypeArray = NULL; + + GetAttr(IDTA_ToolTypes, IconObj, (APTR) &NewToolTypeArray); + + DoMethod(ws->ws_WindowTask->mt_MainObject, + SCCM_IconWin_AddUndoEvent, + UNDO_SetToolTypes, + UNDOTAG_IconDirLock, dirLock, + UNDOTAG_IconName, (ULONG) IconName, + UNDOTAG_OldToolTypes, (ULONG) OldToolTypesArray, + UNDOTAG_NewToolTypes, (ULONG) NewToolTypeArray, + TAG_END + ); + } + + PutIconObjectTags(IconObj, IconName, + ICONA_NoNewImage, TRUE, + TAG_END); + + if (ws) + { + DoMethod(ws->ws_WindowTask->mt_MainObject, SCCM_IconWin_EndUndoStep, UndoStep); + SCA_UnLockWindowList(); + } + if (OldToolTypesArray) + { + free(OldToolTypesArray); + } + } +} + +//---------------------------------------------------------------------------- + +static Object *GetIconObject(CONST_STRPTR IconName, BPTR DirLock) +{ + Object *IconObj; + struct ScaWindowList *WinList = NULL; + struct FileInfoBlock *fib = NULL; + BPTR fLock = (BPTR)NULL; + + do { + struct ScaWindowStruct *ws; + + IconObj = NewIconObject(IconName, NULL); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: IconName=<%s> IconObj=%08lx\n", __LINE__, IconName, IconObj)); + if (IconObj) + break; + + fLock = Lock(IconName, ACCESS_READ); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: fLock=%08lx IconName=<%s>\n", __LINE__, fLock, IconName)); + if ((BPTR)NULL == fLock) + break; + + fib = AllocDosObject(DOS_FIB, TAG_END); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: fib=%08lx\n", __LINE__, fib)); + if (NULL == fib) + break; + + if (!Examine(fLock, fib)) + break; + + WinList = SCA_LockWindowList(SCA_LockWindowList_Shared); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: WinList=%08lx\n", __LINE__, WinList)); + if (NULL == WinList) + break; + + + for (ws = WinList->wl_WindowStruct; ws; ws = (struct ScaWindowStruct *) ws->ws_Node.mln_Succ) + { + if (LOCK_SAME == SameLock(ws->ws_Lock, DirLock)) + { + IconObj = (Object *) DoMethod(ws->ws_WindowTask->mt_MainObject, + SCCM_IconWin_GetDefIcon, IconName, + fib->fib_DirEntryType, fib->fib_Protection); + } + } + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: IconObj=%08lx\n", __LINE__, IconObj)); + } while (0); + + if (fLock) + UnLock(fLock); + if (fib) + FreeDosObject(DOS_FIB, fib); + if (WinList) + SCA_UnLockWindowList(); + + return IconObj; +} + +//---------------------------------------------------------------------------- + +static Object *GetDeviceIconObject(CONST_STRPTR IconName, CONST_STRPTR VolumeName, CONST_STRPTR DeviceName) +{ + Object *IconObj = NULL; + BPTR OldDir = (BPTR)NULL; + BPTR dLock = (BPTR)NULL; + + do { + char DefIconName[256]; + + if (prefDefIconsFirst) + { + dLock = Lock(prefDefIconPath, ACCESS_READ); + if ((BPTR)NULL == dLock) + break; + + OldDir = CurrentDir(dLock); + + strcpy(DefIconName, "def_"); + strcat(DefIconName, VolumeName); + + IconObj = NewIconObject(DefIconName, NULL); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: IconObj=%08lx <%s>\n", __LINE__, IconObj, DefIconName)); + if (IconObj) + break; + + BuildDefVolumeNameNoSpace(DefIconName, VolumeName, sizeof(DefIconName)); + + IconObj = NewIconObject(DefIconName, NULL); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: IconObj=%08lx <%s>\n", __LINE__, IconObj, DefIconName)); + if (IconObj) + break; + + strcpy(DefIconName, "def_"); + strcat(DefIconName, DeviceName); + + IconObj = NewIconObject(DefIconName, NULL); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: IconObj=%08lx <%s>\n", __LINE__, IconObj, DefIconName)); + if (IconObj) + break; + + CurrentDir(OldDir); + OldDir = (BPTR)NULL; + + IconObj = NewIconObject(IconName, NULL); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: IconObj=%08lx <%s>\n", __LINE__, IconObj, IconName)); + if (IconObj) + break; + + } + else + { + IconObj = NewIconObject(IconName, NULL); + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: IconObj=%08lx <%s>\n", __LINE__, IconObj, IconName)); + if (IconObj) + break; + + dLock = Lock(prefDefIconPath, ACCESS_READ); + if ((BPTR)NULL == dLock) + break; + + OldDir = CurrentDir(dLock); + + strcpy(DefIconName, "def_"); + strcat(DefIconName, VolumeName); + + IconObj = NewIconObject(DefIconName, NULL); + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: IconObj=%08lx <%s>\n", __LINE__, IconObj, DefIconName)); + if (IconObj) + break; + + BuildDefVolumeNameNoSpace(DefIconName, VolumeName, sizeof(DefIconName)); + + IconObj = NewIconObject(DefIconName, NULL); + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: IconObj=%08lx <%s>\n", __LINE__, IconObj, DefIconName)); + if (IconObj) + break; + + strcpy(DefIconName, "def_"); + strcat(DefIconName, DeviceName); + + IconObj = NewIconObject(DefIconName, NULL); + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: IconObj=%08lx <%s>\n", __LINE__, IconObj, DefIconName)); + if (IconObj) + break; + } + + IconObj = GetDefIconObject(WBDISK, NULL); + } while (0); + + if (IconObj) + { + SetAttrs(IconObj, + IDTA_Type, WBDISK, + TAG_END); + } + + if (OldDir) + CurrentDir(OldDir); + if (dLock) + UnLock(dLock); + + return IconObj; +} + +//---------------------------------------------------------------------------- + +static BOOL isDiskWritable(BPTR dLock) +{ + struct InfoData *info = malloc(sizeof(struct InfoData)); + BOOL Result = TRUE; + + if (info) + { + Info(dLock, info); + + if (!CheckInfoData(info)) + Result = FALSE; + + free(info); + } + + return Result; +} + + +// return TRUE if Disk is writable +static ULONG CheckInfoData(const struct InfoData *info) +{ + ULONG Result = TRUE; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: DiskType=%ld DiskState=%ld\n", __LINE__, info->id_DiskType, info->id_DiskState)); + + switch (info->id_DiskType) + { + case ID_NO_DISK_PRESENT: + case ID_UNREADABLE_DISK: + Result = FALSE; + break; + } + + if (ID_WRITE_PROTECTED == info->id_DiskState) + Result = FALSE; + + return Result; +} + +//---------------------------------------------------------------------------- + +static BOOL IsDevice(struct WBArg *arg) +{ + BOOL isDevice = FALSE; + BPTR OldDir; + BPTR fLock = (BPTR)NULL; + + do { + char VolumeName[256]; + size_t Len; + + OldDir = CurrentDir(arg->wa_Lock); + + if (arg->wa_Name && strlen(arg->wa_Name) > 0) + { + fLock = Lock(arg->wa_Name, ACCESS_READ); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: fLock=%08lx Name=<%s>\n", __LINE__, fLock, arg->wa_Name)); + if ((BPTR)NULL == fLock) + { + if (0 == stricmp(arg->wa_Name, "disk")) + { + struct WBArg ArgCopy = *arg; + + ArgCopy.wa_Name = ""; + isDevice = IsDevice(&ArgCopy); + } + break; + } + + NameFromLock(fLock, VolumeName, sizeof(VolumeName)); + } + else + { + NameFromLock(arg->wa_Lock, VolumeName, sizeof(VolumeName)); + } + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: VolumeName=<%s>\n", __LINE__, VolumeName)); + + Len = strlen(VolumeName); + isDevice = Len > 0 && ':' == VolumeName[Len - 1]; + } while (0); + + if (fLock) + UnLock(fLock); + CurrentDir(OldDir); + + return isDevice; +} + +//---------------------------------------------------------------------------- + +static void GetDeviceName(BPTR dLock, STRPTR DeviceName, size_t MaxLen) +{ + struct InfoData *info = malloc(sizeof(struct InfoData)); + + strcpy(DeviceName, ""); + if (info) + { + struct DosList *VolumeNode; + + Info(dLock, info); + + VolumeNode = (struct DosList *) BADDR(info->id_VolumeNode); + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: VolumeNode=%08lx\n", __LINE__, VolumeNode)); + + if (VolumeNode && VolumeNode->dol_Task && VolumeNode->dol_Task->mp_SigTask) + stccpy(DeviceName, ((struct Task *) VolumeNode->dol_Task->mp_SigTask)->tc_Node.ln_Name, MaxLen); + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: DeviceName=<%s>\n", __LINE__, DeviceName)); + + free(info); + } +} + +//---------------------------------------------------------------------------- + +static BOOL ReadScalosPrefs(void) +{ + CONST_STRPTR MainPrefsFileName = "ENV:Scalos/Scalos.prefs"; + APTR MainPrefsHandle; + + MainPrefsHandle = AllocPrefsHandle((STRPTR) "Scalos"); + if (NULL == MainPrefsHandle) + return FALSE; + + ReadPrefsHandle(MainPrefsHandle, (STRPTR) MainPrefsFileName); + + GetPreferences(MainPrefsHandle, ID_MAIN, SCP_LoadDefIconsFirst, &prefDefIconsFirst, sizeof(prefDefIconsFirst)); + // UBYTE, no endiannes handling needed + + prefDefIconPath = GetPrefsConfigString(MainPrefsHandle, SCP_PathsDefIcons, prefDefIconPath); + + if (prefDefIconPath) + prefDefIconPath = strdup(prefDefIconPath); + + FreePrefsHandle(MainPrefsHandle); + + return TRUE; +} + +static CONST_STRPTR GetPrefsConfigString(APTR prefsHandle, ULONG Id, CONST_STRPTR DefaultString) +{ + struct PrefsStruct *ps = FindPreferences(prefsHandle, ID_MAIN, Id); + + if (ps) + return (CONST_STRPTR) PS_DATA(ps); + + return DefaultString; +} + +//---------------------------------------------------------------------------- + +static void StripTrailingChar(STRPTR String, char CharToRemove) +{ + size_t Len = strlen(String); + + if (Len > 0 && CharToRemove == String[Len - 1]) + String[Len - 1] = '\0'; +} + +//---------------------------------------------------------------------------- + +static void BuildDefVolumeNameNoSpace(STRPTR Buffer, CONST_STRPTR VolumeName, size_t MaxLength) +{ + STRPTR dlp; + size_t Len; + + strcpy(Buffer, "def_"); + + Len = MaxLength - 1 - strlen(Buffer); + + dlp = Buffer + strlen(Buffer); + while (Len && *VolumeName) + { + if (' ' != *VolumeName) + { + *dlp++ = *VolumeName; + Len--; + } + VolumeName++; + } + *dlp = '\0'; +} + +// ---------------------------------------------------------- + +static struct ScaWindowStruct *FindScalosWindow(BPTR dirLock) +{ + struct ScaWindowList *wl; + BOOL Found = FALSE; + + d1(KPrintF(__FILE__ "/%s/%ld: START \n", __FUNC__, __LINE__)); + + wl = SCA_LockWindowList(SCA_LockWindowList_Shared); + + if (wl) + { + struct ScaWindowStruct *ws; + + for (ws = wl->wl_WindowStruct; !Found && ws; ws = (struct ScaWindowStruct *) ws->ws_Node.mln_Succ) + { + if (((BPTR) NULL == dirLock && (BPTR) NULL == ws->ws_Lock) || (LOCK_SAME == SameLock(dirLock, ws->ws_Lock))) + { + return ws; + } + } + SCA_UnLockWindowList(); + } + + return NULL; +} + +//---------------------------------------------------------------------------- + diff --git a/scalos/Modules/IconProperties.MUI/IconProperties.cd b/scalos/Modules/IconProperties.MUI/IconProperties.cd new file mode 100755 index 000000000..3fddace3f --- /dev/null +++ b/scalos/Modules/IconProperties.MUI/IconProperties.cd @@ -0,0 +1,122 @@ +; IconProperties.cd +; version $VER: IconProperties.catalog 40.6 (05. Oct 2005 18:50:08) +; codeset 0 +; language english +; +;#arrayopts static __far +; +; +MSGID_TITLENAME (//) +Scalos Icon Properties +; +; +MSGID_OKBUTTON (//) +Save +; +; +MSGID_SHORTHELP_OKBUTTON (//) +Save the changes in the icon's tooltypes.\n\ +If necessary, a new icon will be created\n\ +from a the default icon. +; +; +MSGID_CANCELBUTTON (//) +Cancel +; +; +MSGID_SHORTHELP_CANCELBUTTON (//) +Discard all changes and\n\ +leave the icon unchanged. +; +; +MSGID_CHECKMARK_NOTEXT (//) +Hide Icon Text +; +; +MSGID_CHECKMARK_NOTEXT_SHORTHELP (//) +Suppress display of the icon's name. +; +; +MSGID_CHECKMARK_NODRAG (//) +Icon cannot be moved +; +; +MSGID_CHECKMARK_NODRAG_SHORTHELP (//) +The icon cannot be moved inside its window.\n\ +Copying is still possible, however. +; +; +MSGID_READ_ONLY (//) +(Read-Only) +; +; +MSGID_TEXT_ICONNAME_SHORTHELP (//) +Icon name +; +; +MSGID_TEXT_ICONPATH_SHORTHELP (//) +Icon path +; +; +MSGID_CHECKMARK_NOTOOLTIPS (//) +Suppress Tooltips +; +; +MSGID_CHECKMARK_NOTOOLTIPS_SHORTHELP (//) +No tooltips are displayed when the\n\ +mouse pointer is held over this icon. +; +; +MSGID_CHECKMARK_BROWSERMODE (//) +Browser mode +; +; +MSGID_CHECKMARK_BROWSERMODE_SHORTHELP (//) +Activate the browser mode.\n\ +Availlable for disks, trashcans and drawers. +; +;----------------------------------------------------------- +; +MSGID_MENU_PROJECT (2000//) +Project +; +; +MSGID_MENU_PROJECT_ABOUT (//) +About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI (//) +About MUI... +; +; +MSGID_MENU_PROJECT_QUIT (//) +Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT (//) +Q +; +; +MSGID_MENU_IMAGE (//) +Icon Image +; +; +MSGID_MENU_IMAGE_DEFAULT (//) +Default +; +; +MSGID_MENU_IMAGE_DEFAULT_SHORT (/1/1) +D +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK (3000//) +_OK +; +; +MSGID_ABOUTREQFORMAT (//) +\33c\033bScalos IconProperties.module V%ld.%ld\033n\n\ +%s\n\ +© 2004%s The Scalos Team +; +;----------------------------------------------------------- diff --git a/scalos/Modules/IconProperties.MUI/IconProperties.h b/scalos/Modules/IconProperties.MUI/IconProperties.h new file mode 100644 index 000000000..9ba682a87 --- /dev/null +++ b/scalos/Modules/IconProperties.MUI/IconProperties.h @@ -0,0 +1,14 @@ +// IconProperties.h +// 11 Aug 2004 20:42:01 + +#ifndef ICONPROPERTIES_H +#define ICONPROPERTIES_H + +struct IconProperties_LocaleInfo +{ + APTR li_LocaleBase; + APTR li_Catalog; + struct LocaleIFace *li_ILocale; +}; + +#endif /* ICONPROPERTIES_H */ diff --git a/scalos/Modules/IconProperties.MUI/NoDebug b/scalos/Modules/IconProperties.MUI/NoDebug new file mode 100755 index 000000000..49ed68d29 --- /dev/null +++ b/scalos/Modules/IconProperties.MUI/NoDebug @@ -0,0 +1,3 @@ +; NoDebug +; 23 Dec 2001 16:17:11 +splat -s -o "d2(" "d1(" #?.c diff --git a/scalos/Modules/IconProperties.MUI/ToolTypes.c b/scalos/Modules/IconProperties.MUI/ToolTypes.c new file mode 100755 index 000000000..e3f2e8b8f --- /dev/null +++ b/scalos/Modules/IconProperties.MUI/ToolTypes.c @@ -0,0 +1,328 @@ +// ToolTypes.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include +#include + +#include + +#include "defs.h" +#include +#include + +#include +#include +#include + +#include "debug.h" +#include "ToolTypes.h" + +//---------------------------------------------------------------------------- + +// local data structures + +//---------------------------------------------------------------------------- + +// local functions + +static size_t CountToolTypeEntries(CONST_STRPTR *ToolTypeArray); +static size_t GetToolTypeLength(CONST_STRPTR *ToolTypeArray); +STRPTR *CloneToolTypeArray(CONST_STRPTR *ToolTypeArray, ULONG AdditionalEntries); +static STRPTR *scaFindToolType(STRPTR *ToolTypeArray, CONST_STRPTR typeName); + +//---------------------------------------------------------------------------- + +LONG SetToolType(Object *iconObj, CONST_STRPTR ToolTypeName, CONST_STRPTR ToolTypeValue) +{ + LONG Result = RETURN_OK; + STRPTR newTT = NULL; + STRPTR *ttClone = NULL; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: iconObj=%08lx ttName=<%s> ttValue=<%s>\n", \ + __LINE__, iconObj, ToolTypeName, ToolTypeValue)); + + do { + STRPTR *ToolTypeArray = NULL; + STRPTR *ptt; + STRPTR iconName = NULL; + + if (NULL == iconObj) + break; + + //GetAttr(IDTA_ToolTypes, iconObj, (ULONG *) &ToolTypeArray); + //GetAttr(DTA_Name, iconObj, (ULONG *) &iconName); + get(iconObj, IDTA_ToolTypes, &ToolTypeArray); + get(iconObj, DTA_Name, &iconName); + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: ToolTypeArray=%08lx iconName=<%s>\n", \ + __LINE__, ToolTypeArray, iconName)); + + d1(for (ptt=ToolTypeArray; *ptt; ptt++)\ + kprintf(__FILE__ "/" __FUNC__ "/%ld: old ToolType=<%s>\n", __LINE__, *ptt)); + + newTT = (STRPTR) malloc(1 + strlen(ToolTypeName) + 1 + strlen(ToolTypeValue)); + if (NULL == newTT) + break; + + if (strlen(ToolTypeValue) > 0) + sprintf(newTT, "%s=%s", ToolTypeName, ToolTypeValue); + else + strcpy(newTT, ToolTypeName); + + ttClone = CloneToolTypeArray((CONST_STRPTR *) ToolTypeArray, 1); + if (NULL == ttClone) + break; + + ptt = scaFindToolType(ttClone, ToolTypeName); + if (ptt) + { + // overwrite old tooltype + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: ToolType=<%s>\n", __LINE__, *ptt)); + *ptt = newTT; + } + else + { + // append new tooltype + for (ptt=ttClone; *ptt; ptt++) + ; + + *ptt = newTT; + } + + for (ptt=ttClone; *ptt; ptt++) + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: new ToolType=<%s>\n", __LINE__, *ptt)); + + SetAttrs(iconObj, + IDTA_ToolTypes, ttClone, + TAG_END); + + PutIconObjectTags(iconObj, iconName, + ICONA_NoNewImage, TRUE, + TAG_END); + } while (0); + + if (newTT) + free(newTT); + if (ttClone) + free(ttClone); + + return Result; +} + +//---------------------------------------------------------------------------- + +LONG RemoveToolType(Object *iconObj, CONST_STRPTR ToolTypeName) +{ + LONG Result = RETURN_OK; + STRPTR *ttClone = NULL; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: iconObj=%08lx ttName=<%s> ttValue=<%s>\n", \ + __LINE__, iconObj, ToolTypeName, ToolTypeValue)); + + do { + STRPTR *ToolTypeArray = NULL; + STRPTR *ptt; + STRPTR iconName; + + if (NULL == iconObj) + break; + + GetAttr(IDTA_ToolTypes, iconObj, (APTR) &ToolTypeArray); + GetAttr(DTA_Name, iconObj, (APTR) &iconName); + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: ToolTypeArray=%08lx iconName=<%s>\n", \ + __LINE__, ToolTypeArray, iconName)); + + if (NULL == ToolTypeArray) + break; + + d1(for (ptt=ToolTypeArray; ptt && *ptt; ptt++)\ + kprintf(__FILE__ "/" __FUNC__ "/%ld: old ToolType=<%s>\n", __LINE__, *ptt)); + + ttClone = CloneToolTypeArray((CONST_STRPTR *) ToolTypeArray, 0); + if (NULL == ttClone) + break; + + ptt = scaFindToolType(ttClone, ToolTypeName); + if (ptt) + { + // old tooltype found - remove it + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: ToolType=<%s>\n", __LINE__, *ptt)); + while (*ptt) + { + *ptt = ptt[1]; + if (NULL == *ptt) + break; + ptt++; + } + + d1(for (ptt=ttClone; *ptt; ptt++) \ + kprintf(__FILE__ "/" __FUNC__ "/%ld: new ToolType=<%s>\n", __LINE__, *ptt)); + + SetAttrs(iconObj, + IDTA_ToolTypes, ttClone, + TAG_END); + + PutIconObjectTags(iconObj, iconName, + ICONA_NoNewImage, TRUE, + TAG_END); + } + } while (0); + + if (ttClone) + free(ttClone); + + return Result; +} + +//---------------------------------------------------------------------------- + +static size_t CountToolTypeEntries(CONST_STRPTR *ToolTypeArray) +{ + size_t ttCount; + + for (ttCount=0; ToolTypeArray && ToolTypeArray[ttCount]; ttCount++); + + return ttCount; +} + +//---------------------------------------------------------------------------- + +static size_t GetToolTypeLength(CONST_STRPTR *ToolTypeArray) +{ + size_t Length = sizeof(STRPTR); + + while (ToolTypeArray && *ToolTypeArray) + { + Length += sizeof(STRPTR) + strlen(*ToolTypeArray) + 1; + ToolTypeArray++; + } + + return Length; +} + +//---------------------------------------------------------------------------- + +STRPTR *CloneToolTypeArray(CONST_STRPTR *ToolTypeArray, ULONG AdditionalEntries) +{ + size_t ttLength; + STRPTR *newTT, *newTTalloc; + STRPTR stringSpace; + ULONG ttCount; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: AdditionalEntries=%ld\n", __LINE__, AdditionalEntries)); + + ttLength = GetToolTypeLength(ToolTypeArray) + AdditionalEntries * sizeof(STRPTR); + ttCount = CountToolTypeEntries(ToolTypeArray); + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: ttLength=%ld ttCount=%ld\n", __LINE__, ttLength, ttCount)); + + newTT = newTTalloc = malloc(ttLength); + if (NULL == newTT) + return NULL; + + stringSpace = (STRPTR) &newTT[1 + ttCount + AdditionalEntries]; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: newTT=%08lx stringSpace=%08lx\n", __LINE__, newTT, stringSpace)); + + while (ToolTypeArray && *ToolTypeArray) + { + *newTT = stringSpace; + + strcpy(stringSpace, *ToolTypeArray); + stringSpace += strlen(stringSpace) + 1; + + newTT++; + ToolTypeArray++; + } + + while (AdditionalEntries--) + *newTT++ = NULL; + + *newTT = NULL; + + return newTTalloc; +} + +//---------------------------------------------------------------------------- + +static STRPTR *scaFindToolType(STRPTR *ToolTypeArray, CONST_STRPTR typeName) +{ + if (NULL == ToolTypeArray) + return NULL; + + while (*ToolTypeArray) + { + STRPTR lp = strchr(*ToolTypeArray, '='); + STRPTR CompEnd; + size_t CompLen; + + if (lp) + { + CompEnd = lp; + + if (CompEnd != *ToolTypeArray) + CompEnd--; // skip "=" + while (CompEnd != *ToolTypeArray && ' ' == *CompEnd) + CompEnd--; // skip all " " before "=" + +// lp = stpblk(++lp); // skip "=" and trailing blanks + + CompLen = CompEnd - *ToolTypeArray; + } + else + { + CompLen = strlen(*ToolTypeArray); +// lp = (STRPTR) ""; + } + + if (0 == Strnicmp(*ToolTypeArray, typeName, CompLen)) + { + return ToolTypeArray; + } + + ToolTypeArray++; + } + + return NULL; +} + +//---------------------------------------------------------------------------- + +LONG CmpToolTypeArrays(CONST_STRPTR *ToolTypeArray1, CONST_STRPTR *ToolTypeArray2) +{ + while (*ToolTypeArray1 && *ToolTypeArray2) + { + int rc = strcmp(*ToolTypeArray1, *ToolTypeArray2); + + if (0 != rc) + return (LONG) rc; + + ToolTypeArray1++; + ToolTypeArray2++; + } + + if (*ToolTypeArray1) + return 1; + else if (*ToolTypeArray2) + return -1; + + return 0; +} + +//---------------------------------------------------------------------------- + diff --git a/scalos/Modules/IconProperties.MUI/ToolTypes.h b/scalos/Modules/IconProperties.MUI/ToolTypes.h new file mode 100755 index 000000000..ada049fe3 --- /dev/null +++ b/scalos/Modules/IconProperties.MUI/ToolTypes.h @@ -0,0 +1,18 @@ +// ToolTypes.h +// $Date$ +// $Revision$ + + +#ifndef TOOLTYPES_H +#define TOOLTYPES_H + +//---------------------------------------------------------------------------- + +LONG SetToolType(Object *iconObj, CONST_STRPTR ToolTypeName, CONST_STRPTR ToolTypeValue); +LONG RemoveToolType(Object *iconObj, CONST_STRPTR ToolTypeName); +STRPTR *CloneToolTypeArray(CONST_STRPTR *ToolTypeArray, ULONG AdditionalEntries); +LONG CmpToolTypeArrays(CONST_STRPTR *ToolTypeArray1, CONST_STRPTR *ToolTypeArray2); + +//---------------------------------------------------------------------------- + +#endif /* TOOLTYPES_H */ diff --git a/scalos/Modules/IconProperties.MUI/config.mk b/scalos/Modules/IconProperties.MUI/config.mk new file mode 100755 index 000000000..170ae4b24 --- /dev/null +++ b/scalos/Modules/IconProperties.MUI/config.mk @@ -0,0 +1,59 @@ +# $Date: 2011-07-16 19:39:22 +0200 (Sa, 16. Jul 2011) $ +# $Revision: 787 $ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +ICONOBJMCC_DIR = $(TOPLEVEL)/common/IconobjectMCC + +SCALOS_LOCALE = $(OBJDIR)/IconProperties_Locale.h + +CFLAGS += -D SCALOSLOCALE=$(SCALOS_LOCALE) + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +INCLUDES += -I$(ICONOBJMCC_DIR) \ + +LFLAGS += # + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +INCLUDES += -I$(ICONOBJMCC_DIR) \ + +LFLAGS += -lauto + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +INCLUDES += -I$(ICONOBJMCC_DIR) \ + +LFLAGS += -mui -lutility + +else + +############################################################################### +# AmigaOS + +LFLAGS += # + +endif +endif +endif diff --git a/scalos/Modules/IconProperties.MUI/debug.h b/scalos/Modules/IconProperties.MUI/debug.h new file mode 100644 index 000000000..aea559dac --- /dev/null +++ b/scalos/Modules/IconProperties.MUI/debug.h @@ -0,0 +1,19 @@ +// debug.h +// $Date$ +// $Revision$ + +#ifndef DEBUG_H +#define DEBUG_H + +//---------------------------------------------------------------------------- + +#define d1(x) ; +#define d2(x) x; + +// from debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +//---------------------------------------------------------------------------- + +#endif /* DEBUG_H */ diff --git a/scalos/Modules/IconProperties.MUI/makefile b/scalos/Modules/IconProperties.MUI/makefile new file mode 100644 index 000000000..f465d005c --- /dev/null +++ b/scalos/Modules/IconProperties.MUI/makefile @@ -0,0 +1,142 @@ +# MakeFile für IconProperties MUI module +# $Date$ +# $Revision$ +##################################################################### + +TOPLEVEL = / +SUBDIRMAKE = $(MAKE) -s -C +CATCOMP = CatComp +FLEXCAT = FlexCat +CHEADERS = +CC = sc +CFLAGS = optimize nostackcheck nochkabort debug=s NOWVRET \ + strmer nover streq idlen=128 idir=sc:include/ \ + define SCALOSLOCALE=$(SCALOS_LOCALE) \ + idir=include: idir=//include \ + idir=$(subst ../,/,$(ICONOBJMCC_DIR)) +AS = phxass +AFLAGS = QUIET m=68020 linedebug opt=NRQB i=include: +LD = slink +LNFLAGS = quiet batch noicons stripdebug +LNDBFLAGS = quiet batch noicons addsym +LIBS = LIB:sc.lib LIB:mempools.lib LIB:debug.lib LIB:amiga.lib +CSTARTUP = LIB:c.o +OBJDIR = .sasobj + +SCALOS_LOCALE = $(OBJDIR)/IconProperties_Locale.h + +.SUFFIXES: .asm .cd + +############################################################# + +NAME = .bin_os3/IconProperties.module +DBGNAME = $(NAME).debug +CATCOMPHEADER = $(SCALOS_LOCALE) +DESTTOOL = Scalos:modules/ +CAT_FILE = Scalos/IconProperties.catalog +DESTCAT = Locale:Catalogs +ALLCATS = Catalogs/deutsch/$(CAT_FILE) \ + Catalogs/français/$(CAT_FILE) +ICONOBJMCC_DIR = ../../common/IconobjectMCC + +############################################################# + +all: $(NAME) \ + $(DBGNAME) \ + allcatalogs +# install +# clean + +##################################################################### + +# make all Scalos .catalogs +allcatalogs: + @$(SUBDIRMAKE) Catalogs/deutsch/Scalos + @$(SUBDIRMAKE) Catalogs/français/Scalos + +##################################################################### + +CSRCS = IconProperties.c \ + $(ICONOBJMCC_DIR)/IconobjectMCC.c \ + ToolTypes.c + +##################################################################### + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +############################################################# + +XSRCS = $(notdir $(CSRCS)) +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(XSRCS:%.c=$(OBJDIR)/$(notdir %).o) + +##################################################################### + +$(OBJDIR)/IconobjectMCC.o : $(ICONOBJMCC_DIR)/IconobjectMCC.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(CATCOMPHEADER) : IconProperties.cd + @printf '\033[32mMake Catcomp header: \033[31m\033[1m$@ \033[32mfrom \033[31m$<\033[0m\n' + @$(FLEXCAT) $< $@=$(TOPLEVEL)/CatComp_h.sd + +##################################################################### + +$(OBJDIR)/IconProperties.o : IconProperties.c IconProperties.h \ + $(SCALOS_LOCALE) $(ICONOBJMCC_DIR)/IconobjectMCC.h \ + ToolTypes.h debug.h + +$(OBJDIR)/IconobjectMCC.o : $(ICONOBJMCC_DIR)/IconobjectMCC.h debug.h + +$(OBJDIR)/ToolTypes.o : ToolTypes.c ToolTypes.h debug.h + +$(OBJDIR)/IconobjectMCC.o : $(ICONOBJMCC_DIR)/IconobjectMCC.c \ + $(ICONOBJMCC_DIR)/IconobjectMCC.h debug.h + +##################################################################### + +$(NAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNFLAGS) + +$(DBGNAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNDBFLAGS) + +############################################################# + +# commands generated a catalog (.catalog) from a catalog translation (.ct) file. +.ct.catalog: + $(CATCOMP) $*.cd $< CATALOG $*.catalog VB=1 + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $< objectname $@ + +$(OBJDIR)/%.o : %.s + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +$(OBJDIR)/%.o : %.asm + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +############################################################# + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(NAME) \033[0mto \033[1m$(DESTTOOL) \033[0m\n' + @copy $(NAME) $(DESTTOOL) clone + @printf '\033[32mFlushing memory\033[0m\n' + @avail flush + @printf '\033[32mInstall: \033[31m\033[1m$(CAT_FILE)\033[0m\n' + -@copy 'catalogs/deutsch/$(CAT_FILE)' '$(DESTCAT)/Deutsch/Scalos/' clone + -@copy 'catalogs/français/$(CAT_FILE)' '$(DESTCAT)/français/Scalos/' clone + +############################################################# + +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + -@delete $(OBJS) $(NAME) $(DBGNAME) $(ALLCATS) $(CATCOMPHEADER) + @printf '\033[0m' + +############################################################# diff --git a/scalos/Modules/IconProperties.MUI/makefile-new b/scalos/Modules/IconProperties.MUI/makefile-new new file mode 100755 index 000000000..73642511d --- /dev/null +++ b/scalos/Modules/IconProperties.MUI/makefile-new @@ -0,0 +1,102 @@ +# $Date: 2011-07-12 02:12:04 +0200 (Di, 12. Jul 2011) $ +# $Revision: 772 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL = $(shell pwd)/../.. +endif + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + SDPATH=/ +else + SDPATH=../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(OBJDIR)/IconProperties.o \ + $(OBJDIR)/IconobjectMCC.o \ + $(OBJDIR)/ToolTypes.o \ + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Subdirs +# + +SUBDIRS = $(filter-out Catalogs/sample/Scalos, $(wildcard Catalogs/*/Scalos)) + +############################################################################## +# +# Targets +# + +NAME = IconProperties.module +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) \ + all_subdirs + +############################################################################## + +$(OBJDIR)/%.o: $(TOOLTYPE_DIR)/%.c + @$(run-cc) + +$(OBJDIR)/%.o: $(ICONOBJMCC_DIR)/%.c + @$(run-cc) + +IconProperties.c : $(OBJDIR)/IconProperties_Locale.h + +$(OBJDIR)/IconProperties_Locale.h : IconProperties.cd + @$(ECHO) "FlexCat $@" + $(FLEXCAT) $< $@=$(SDPATH)/CatComp_h.sd + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + $(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) +ifneq ($(MACHINE), ppc-amigaos) + -@chmod u+x $@ +endif + +############################################################################## + +install: install_subdirs + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) Scalos:modules/ clone + +clean: clean_subdirs + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* \ + $(OBJDIR)/IconProperties_Locale.h + +############################################################################## + diff --git a/scalos/Modules/Information.MUI/Catalogs/deutsch/Scalos/Information.ct b/scalos/Modules/Information.MUI/Catalogs/deutsch/Scalos/Information.ct new file mode 100644 index 000000000..914c10bd6 --- /dev/null +++ b/scalos/Modules/Information.MUI/Catalogs/deutsch/Scalos/Information.ct @@ -0,0 +1,734 @@ +; Information.ct +; $Date$ +; $Revision$ +; +## version $VER: Information.catalog 40.5 (25 Jan 2006 22:02:39) +## codeset 0 +## language deutsch +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Information +;Scalos Information +; +; +MSGID_OKBUTTON +Speichern +;Save +; +; +MSGID_SHORTHELP_OKBUTTON +Speichert die Änderungen am Piktogramm.\n\ +Ein neues Piktogramm wird erzeugt,\n\ +wenn bisher keines existierte. +;Save the changed icon.\n\ +;If necessary, a new icon will be\n\ +;created from a the default icon. +; +; +MSGID_CANCELBUTTON +Abbrechen +;Cancel +; +; +MSGID_SHORTHELP_CANCELBUTTON +Alle Änderungen verwerfen und das\n\ +Piktogramm im originalen Zustand lassen. +;Discard all changes and\n\ +;leave the icon unchanged. +; +; +MSGID_CREATE_APPLICATION_FAILED +Fehler beim Erzeugen der Anwendung.\n +;Failed to create Application.\n +; +; +MSGID_CREATE_MAINWINDOW_FAILED +Fehler beim Öffnen des Hauptfensters !\n +;Failed to open main window !\n +; +; +MSGID_OPEN_LIBRARY_FAILED +Fehler beim Öffnen von \"%s\" !\n +;Failed to open \"%s\" !\n +; +;;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Projekt +;Project +; +; +MSGID_MENU_PROJECT_ABOUT +Über... +;About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Über MUI... +;About MUI... +; +; +MSGID_MENU_PROJECT_QUIT +Beenden +;Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +;Q +; +; +MSGID_MENU_TYPE +Typ +;Type +; +; +MSGID_MENU_TYPE_DISK +Datenträger +;Disk +; +; +MSGID_MENU_TYPE_DRAWER +Verzeichnis +;Drawer +; +; +MSGID_MENU_TYPE_PROJECT +Projekt +;Project +; +; +MSGID_MENU_TYPE_TOOL +Programm +;Tool +; +; +MSGID_MENU_TYPE_TRASHCAN +Papierkorb +;Trashcan +; +; +MSGID_MENU_IMAGE +Piktogramm-Bild +;Icon Image +; +; +MSGID_MENU_IMAGE_DEFAULT +Standardbild +;Default +; +; +MSGID_MENU_IMAGE_DEFAULT_SHORT +D +;D +; +; +MSGID_MENU_OPTIONS +Optionen +; Options +; +; +MSGID_MENU_ALWAYS_ICONPATH +Piktogrammpfad sofort anzeigen? +; Always display icon path +; +; +MSGID_MENU_ALWAYS_ICONPATH_SHORT +P +; P +; +; +MSGID_MENU_ALWAYS_GETSIZE +Verzeichnisgröße sofort bestimmen? +; Always get size +; +; +MSGID_MENU_ALWAYS_GETSIZE_SHORT +G +; G +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +Ok +;_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Information.module V%ld.%ld\033n\n\ +%s\n\ +© 2004%s DasScalos-Team +;\33c\033bScalos Information.module V%ld.%ld\033n\n\ +;%s\n\ +;© 2004%s The Scalos Team +; +;----------------------------------------------------------- +; +MSGID_DEVICE_DEVICE +Gerät: +;Device +; +; +MSGID_DEVICE_HANDLER +Dateisystem: +;Handler +; +; +MSGID_DEVICE_CREATED_ON +Erstellt am: +;Created on +; +; +MSGID_DEVICE_SPACE_USED +Belegt: +;Used +; +; +MSGID_DEVICE_SPACE_FREE +Frei: +;Free +; +; +MSGID_DEVICE_SIZE +Größe: +;Size +; +; +MSGID_DEVICE_BLOCK_SIZE +Blockgröße: +;Block size +; +; +MSGID_DEVICE_STATE +Status: +;State +; +; +MSGID_DEVICE_BLOCKS_PERCENT +%s (%lD Blöcke, %lD%%) +;%s (%lD Blocks, %lD%%) +; +; +MSGID_DEVICE_BLOCKS +%s (%lD Blöcke) +;%s (%lD Blocks) +; +; +MSGID_DEVICE_DISKSTATE_READONLY +nur lesbar +;read-only +; +; +MSGID_DEVICE_DISKSTATE_VALIDATING +Beim Validieren +;validating +; +; +MSGID_DEVICE_DISKSTATE_READ_WRITE +schreib-/lesbar +;read-/writable +; +; +MSGID_DEVICE_DISKSTATE_UNKNOWN +??unbekannt?? +;??unknown?? +; +; +MSGID_DEVICE_BLOCKSIZE_BYTES +%lD Bytes +;%lD bytes +; +; +MSGID_DEVICE_HANDLER_DISKID +%s %ld.%ld +;%s %ld.%ld +; +; +MSGID_DEVICE_ON_DEVNAME +auf %s +;on %s +; +; +MSGID_DEVICE_DEVICE_UNIT +%s, %ld +;%s, %ld +; +;----------------------------------------------------------- +; +MSGID_LASTCHANGE +Letzte Änderung: +;Last change +; +; +MSGID_SIZE +Größe: +;Size +; +; +MSGID_SIZE_FORMAT +%s Bytes +;%s bytes +; +; +MSGID_PROTECTION +Schutz: +;Protection +; +; +MSGID_PROTECTION_READ +Lesbar +;Read +; +; +MSGID_PROTECTION_WRITE +Schreibbar +;Write +; +; +MSGID_PROTECTION_ARCHIVE +Archiv +;Archive +; +; +MSGID_PROTECTION_DELETE +Löschbar +;Delete +; +; +MSGID_PROTECTION_EXECUTE +Ausführbar +;Execute +; +; +MSGID_PROTECTION_SCRIPT +Skript +;Script +; +; +MSGID_PROTECTION_READ_SHORTHELP +Dieses Dateisystem-Attribute erlaubt das Lesen aus der Datei. +;Read??? +; +; +MSGID_PROTECTION_WRITE_SHORTHELP +Dieses Dateisystem-Attribute erlaubt das Beschreiben der Datei. +;Write??? +; +; +MSGID_PROTECTION_ARCHIVE_SHORTHELP +Dieses Dateisystem-Attribute kennzeichnet die Datei als archiviert.\n\ +Es wird automatisch beim ersten Schreibzugriff gelöscht. +;Archive??? +; +; +MSGID_PROTECTION_DELETE_SHORTHELP +Dieses Dateisystem-Attribute erlaubt das Löschen der Datei. +;Delete??? +; +; +MSGID_PROTECTION_EXECUTE_SHORTHELP +Dieses Dateisystem-Attribute kennzeichnet die Datei als ausführbar. +;Execute??? +; +; +MSGID_PROTECTION_SCRIPT_SHORTHELP +Dieses Dateisystem-Attribute kennzeichnet die Datei als\n\ +ausführbares Skript (Shell- oder ARexx-Skript). +;Script??? +; +; +MSGID_COMMENT +Kommentar: +;Comment +; +; +MSGID_TOOLTYPES +Merkmale: +;Tooltypes +; +; +MSGID_VERSION +Version: +;Version +; +; +MSGID_DEFAULTTOOL +Standardprogramm: +;Default tool +; +; +MSGID_STACKSIZE +Stapelgröße: +;Stack size +; +; +MSGID_TOOL_PRIORITY +Priorität: +;Priority +; +; +MSGID_START_FROM +Start durch: +;Start from +; +; +MSGID_PROMPT_FOR_INPUT +Auf Eingabe warten: +;Prompt for input +; +; +MSGID_VERSION_NOT_AVAILABLE +nicht verfügbar +;not available +; +; +MSGID_DRAWER_SIZE_SHORTHELP +Klicken Sie auf diesen Knopf, um die\n\ +tatsächliche Größe des Schubladeninhalts\n\ +zu bestimmen.\n\ +Abhängig von Inhalt der Schublade kann die\n\ +Größenbestimmung unter Umständen einige Zeit dauern! +;Press this button to calculate the actual\n\ +;size of the drawer contents.\n\ +;This operation may takt some time,\n\ +;depending on the drawer contents. +; +; +MSGID_INITIAL_DRAWER_SIZE +1 Block +;1 block +; +; +MSGID_DRAWER_SIZE +%s Bytes in %lD Dateien, %lD Verzeichnissen (%lD Blöcke) +;%s bytes in %lD files, %lD drawers (%lD blocks) +; +; +MSGID_STARTPRI +Startpriorität: +;Start priority: +; +; +MSGID_WAITUNTILFINISHED +Auf Beendigung warten: +;Wait until finished: +; +; +MSGID_WAITUNTILFINISHED_SHORTHELP +Bei WBStartup Programmen legt diese Einstellung fest,\n\ +ob Scalos wartet, bis das Programm fertig ist, oder\n\ +einfach mit dem nächsten Programm aus WBStartup weitermacht. +;For WBStartup programs, selects if Scalos will wait\n\ +;until program is finished holding WBStartup processsing,\n\ +;or if processing will continue asynchronously. +; +; +MSGID_TOOL_SECONDS +Sekunden +;seconds +; +; +MSGID_ICONPOS_X +X: +; +; +MSGID_ICONPOS_Y +Y: +; +; +MSGID_ICONPOS_NONE +- +; +;----------------------------------------------------------- +; +MSGID_START_FROM_WORKBENCH +Workbench +;Workbench +; +; +MSGID_START_FROM_CLI +Shell +;Shell +; +; +MSGID_START_FROM_AREXX +ARexx +;ARexx +; +;----------------------------------------------------------- +; +MSGID_DEVICE_REGISTER_DEVICE +Datenträger +;Device +; +; +MSGID_DEVICE_REGISTER_ICON +Piktogramm +;Icon +; +;----------------------------------------------------------- +; +MSGID_DRAWER_REGISTER_DRAWER +Verzeichnis +;Drawer +; +; +MSGID_DRAWER_REGISTER_ICON +Piktogramm +;Icon +; +;----------------------------------------------------------- +; +MSGID_PROJECT_REGISTER_PROJECT +Projekt +;Project +; +; +MSGID_PROJECT_REGISTER_ICON +Piktogramm +;Icon +; +;----------------------------------------------------------- +; +MSGID_TOOL_REGISTER_TOOL +Programm +;Tool +; +; +MSGID_TOOL_REGISTER_ICON +Piktogramm +;Icon +; +;----------------------------------------------------------- +; +MSGID_ICONTYPE_DISK +(Datenträger) +;(Disk) +; +; +MSGID_ICONTYPE_DRAWER +(Verzeichnis) +;(Drawer) +; +; +MSGID_ICONTYPE_TOOL +(Programm) +;(Tool) +; +; +MSGID_ICONTYPE_PROJECT +(Projekt) +;(Project) +; +; +MSGID_ICONTYPE_TRASHCAN +(Papierkorb) +;(Trashcan) +; +; +MSGID_ICONTYPE_DEVICE +(Gerät) +;(Device) +; +; +MSGID_ICONTYPE_KICKSTART +(Kickstart) +;(Kickstart) +; +; +MSGID_ICONTYPE_APPICON +(AppIcon) +;(AppIcon) +; +; +MSGID_ICONTYPE_UNKNOWN +(??unbekannt??) +;(??unknown??) +; +;----------------------------------------------------------- +; +MSGID_BYTES_GB +%lDG +;%lDG +; +; +MSGID_BYTES_GB_2 +%lD%s%-02ldG +; +; +MSGID_BYTES_GB_1 +%lD%s%1ldG +; +; +MSGID_BYTES_MB +%lDM +;%lDM +; +; +MSGID_BYTES_MB_2 +%lD%s%-02ldM +; +; +MSGID_BYTES_MB_1 +%lD%s%1ldM +; +; +MSGID_BYTES_KB +%lDK +;%lDK +; +; +MSGID_BYTES_KB_2 +%lD%s%-02ldK +; +; +MSGID_BYTES_KB_1 +%lD%s%1ldK +; +;----------------------------------------------------------- +; +MSGID_ERROR_SETCOMMENT +Fehler beim Ändern des Kommentars\n\ +%s. +;Error setting comment\n\ +;%s. +; +; +MSGID_ERROR_SETPROTECTION +Fehler beim Ändern des Schutzes\n\ +%s. +;Error setting protection\n\ +;%s. +; +; +MSGID_ERROR_RELABEL +Fehler beim Umbenennen eines Datenträgers\n\ +%s. +;Error relabelling disk\n\ +;%s. +; +; +MSGID_ERROR_RENAME +Fehler beim Umbenennen\n\ +%s. +;Error renaming\n\ +;%s. +; +; +MSGID_ERROR_REQ_OK +Ok +;_OK +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Information.module kann nicht gestartet werden +;Information.module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Wiederholen|Beenden +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\ +Die Klasse ist nicht installiert. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Sie haben momentan Version v%lu.%lu installiert und\n\ +sollten die Klasse daher aktualisieren! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Version %lu.%lu wird momentan von einer anderen Anwendung\n\ +verwendet. Wenn sie die benötigte Version installiert haben,\n\ +schließen sie alle MUI Programme und probieren es erneut. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_DEVICE_DOSTYPE +Dateisystemkennung: +;Identifier: +; +; +MSGID_DEVICE_DOSTYPESTRING +(\033b%c%c%c%c\033n) +;(\033b%c%c%c%c\033n) +; +;----------------------------------------------------------- +; +; +MSGID_PROTECTION_HIDDEN +Versteckt +;Hidden +; +; +MSGID_PROTECTION_HIDDEN_SHORTHELP +Dieses Dateisystem-Attribut kennzeichnet die Datei als versteckt. +;Hidden??? +; +; +MSGID_PROTECTION_PURE +Resident-Fähig +;Pure +; +; +MSGID_PROTECTION_PURE_SHORTHELP +Dieses Dateisystem-Attribut kennzeichnet die Datei als geeignet für Residenten Betrieb. +;Pure??? +; +;------------------------------------------------------------ +; +MSGID_TEXT_ICONPATH_SHORTHELP +Piktogrammpfad +;Icon path +; +; +MSGID_FILETYPE_DRAWER +Schublade +;Drawer +; +; +MSGID_FILETYPE_GARBAGE +Mülleimer +;Trashcan +; +; +MSGID_FILETYPE_DISK +Datenträger +;Disk +; +; +MSGID_FILETYPE_TOOL +Werkzeug +;Tool +; +; +MSGID_FILETYPE_PROJECT +Projekt +;Project +; +; +MSGID_FILETYPE_APPICON +Anwendungspiktogramm +;Appicon +; +;------------------------------------------------------------ +; diff --git a/scalos/Modules/Information.MUI/Catalogs/deutsch/Scalos/config.mk b/scalos/Modules/Information.MUI/Catalogs/deutsch/Scalos/config.mk new file mode 100755 index 000000000..7a0fa6265 --- /dev/null +++ b/scalos/Modules/Information.MUI/Catalogs/deutsch/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2011-07-12 03:13:22 +0200 (Di, 12. Jul 2011) $ +# $Revision: 775 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = deutsch + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = german + +else + +############################################################################### +# AmigaOS and AROS + +LANG = deutsch + +endif +endif diff --git a/scalos/Modules/Information.MUI/Catalogs/deutsch/Scalos/makefile b/scalos/Modules/Information.MUI/Catalogs/deutsch/Scalos/makefile new file mode 100644 index 000000000..be3e04357 --- /dev/null +++ b/scalos/Modules/Information.MUI/Catalogs/deutsch/Scalos/makefile @@ -0,0 +1,14 @@ +# makefile for Information.module (translated Texts : deutsch) +# $Date$ +# $Revision$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mdeutsch\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +Information.catalog : Information.ct ../../../Information.cd + +All: Information.catalog diff --git a/scalos/Modules/Information.MUI/Catalogs/deutsch/Scalos/makefile-new b/scalos/Modules/Information.MUI/Catalogs/deutsch/Scalos/makefile-new new file mode 100644 index 000000000..315cac59b --- /dev/null +++ b/scalos/Modules/Information.MUI/Catalogs/deutsch/Scalos/makefile-new @@ -0,0 +1,30 @@ +# makefile for Information.module (translated Texts : deutsch) +# $Date: 2011-07-24 10:11:00 +0200 (So, 24. Jul 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = Information + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git "a/scalos/Modules/Information.MUI/Catalogs/fran\303\247ais/Scalos/Information.ct" "b/scalos/Modules/Information.MUI/Catalogs/fran\303\247ais/Scalos/Information.ct" new file mode 100755 index 000000000..e8884deab --- /dev/null +++ "b/scalos/Modules/Information.MUI/Catalogs/fran\303\247ais/Scalos/Information.ct" @@ -0,0 +1,723 @@ +; Information.ct +; $Date$ +; $Revision$ +; +## version $VER: Information.catalog 40.5 (20 Oct 2006) +## codeset 0 +## language français +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Information +;Scalos Information +; +; +MSGID_OKBUTTON +Sauver +;Save +; +; +MSGID_SHORTHELP_OKBUTTON +Enregistre l'icône modifiée.\n\ +Si nécessaire, une nouvelle icône sera\n\ +créée d'après le type d'icône par défaut. +;Save the changed icon.\n\ +;If necessary, a new icon will be\n\ +;created from a the default icon. +; +; +MSGID_CANCELBUTTON +Annuler +;Cancel +; +; +MSGID_SHORTHELP_CANCELBUTTON +Oublier tout changement en cours.\n\ +L'icône ne sera pas modifiée. +;Discard all changes and\n\ +;leave the icon unchanged. +; +; +MSGID_CREATE_APPLICATION_FAILED +La création de l'application a échouée.\n +;Failed to create Application.\n +; +; +MSGID_CREATE_MAINWINDOW_FAILED +L'ouverture de la fenêtre n'a pu être éffectuée !\n +;Failed to open main window !\n +; +; +MSGID_OPEN_LIBRARY_FAILED +Impossible d'ouvrir "%s" !\n +;Failed to open "%s" !\n +; +;;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Projet +;Project +; +; +MSGID_MENU_PROJECT_ABOUT +A propos... +;About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI +A propos de MUI... +;About MUI... +; +; +MSGID_MENU_PROJECT_QUIT +Quitter +;Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +;Q +; +; +MSGID_MENU_TYPE +Type +;Type +; +; +MSGID_MENU_TYPE_DISK +Volume +;Disk +; +; +MSGID_MENU_TYPE_DRAWER +Répertore +;Drawer +; +; +MSGID_MENU_TYPE_PROJECT +Projet +;Project +; +; +MSGID_MENU_TYPE_TOOL +Outil +;Tool +; +; +MSGID_MENU_TYPE_TRASHCAN +Corbeille +;Trashcan +; +; +MSGID_MENU_IMAGE +Image de l'icône +;Icon Image +; +; +MSGID_MENU_IMAGE_DEFAULT +Image par défaut +;Default +; +; +MSGID_MENU_IMAGE_DEFAULT_SHORT +D +;D +; +; +MSGID_MENU_OPTIONS +Options +; Options +; +; +MSGID_MENU_ALWAYS_ICONPATH +Afficher le chemin de l'icône +; Always display icon path +; +; +MSGID_MENU_ALWAYS_ICONPATH_SHORT +P +; P +; +; +MSGID_MENU_ALWAYS_GETSIZE +Toujours saisir la taille +; Always get size +; +; +MSGID_MENU_ALWAYS_GETSIZE_SHORT +G +; G +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +_D'accord +;_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Information.module V\0333%ld\0332.\0333%ld\0332\033n\n\ +Compilé sous: \033b%s\033n\n\ +© 2004%s The Scalos Team +;\33c\033bScalos Information.module V%ld.%ld\033n\n\ +;%s\n\ +;© 2004%s The Scalos Team +; +;----------------------------------------------------------- +; +MSGID_DEVICE_DEVICE +\0333Périphérique : +;Device +; +; +MSGID_DEVICE_HANDLER +\0333Gestionnaire : +;Handler +; +; +MSGID_DEVICE_CREATED_ON +\0333Créé le : +;Created on +; +; +MSGID_DEVICE_SPACE_USED +\0333Utilisé : +;Used +; +; +MSGID_DEVICE_SPACE_FREE +\0333Libre : +;Free +; +; +MSGID_DEVICE_SIZE +\0333Taille : +;Size +; +; +MSGID_DEVICE_BLOCK_SIZE +\0333Octets par bloc : +;Block size +; +; +MSGID_DEVICE_STATE +\0333Statut : +;State +; +; +MSGID_DEVICE_BLOCKS_PERCENT +%s (%lD Blocs, %lD%%) +;%s (%lD Blocks, %lD%%) +; +; +MSGID_DEVICE_BLOCKS +%s (%lD Blocs) +;%s (%lD Blocks) +; +; +MSGID_DEVICE_DISKSTATE_READONLY +Seulement lisible +;read-only +; +; +MSGID_DEVICE_DISKSTATE_VALIDATING +validation +;validating +; +; +MSGID_DEVICE_DISKSTATE_READ_WRITE +Lisible/Modifiable +;read-/writable +; +; +MSGID_DEVICE_DISKSTATE_UNKNOWN +?? Inconnu ?? +;??unknown?? +; +; +MSGID_DEVICE_BLOCKSIZE_BYTES +%lD Octets +;%lD bytes +; +; +MSGID_DEVICE_HANDLER_DISKID +%s %ld.%ld +;%s %ld.%ld +; +; +MSGID_DEVICE_ON_DEVNAME +\0333sur\0332 \033b%s\033n +;on %s +; +; +MSGID_DEVICE_DEVICE_UNIT +%s, %ld +;%s, %ld +; +;----------------------------------------------------------- +; +MSGID_LASTCHANGE +\0333Modifié le : +;Last change +; +; +MSGID_SIZE +\0333Taille : +;Size +; +; +MSGID_SIZE_FORMAT +%s Octets +;%s bytes +; +; +MSGID_PROTECTION +\0333Protection : +;Protection +; +; +MSGID_PROTECTION_READ +Lisible +;Read +; +; +MSGID_PROTECTION_WRITE +Modifiable +;Write +; +; +MSGID_PROTECTION_ARCHIVE +Archivable +;Archive +; +; +MSGID_PROTECTION_DELETE +Effaçable +;Delete +; +; +MSGID_PROTECTION_EXECUTE +Executable +;Execute +; +; +MSGID_PROTECTION_SCRIPT +Script +;Script +; +; +MSGID_PROTECTION_READ_SHORTHELP +Lisible ??? +;Read??? +; +; +MSGID_PROTECTION_WRITE_SHORTHELP +Modifiable ??? +;Write??? +; +; +MSGID_PROTECTION_ARCHIVE_SHORTHELP +Archivable ??? +;Archive??? +; +; +MSGID_PROTECTION_DELETE_SHORTHELP +Effaçable ??? +;Delete??? +; +; +MSGID_PROTECTION_EXECUTE_SHORTHELP +Executable ??? +;Execute??? +; +; +MSGID_PROTECTION_SCRIPT_SHORTHELP +Script ??? +;Script??? +; +; +MSGID_COMMENT +\0333Commentaire : +;Comment +; +; +MSGID_TOOLTYPES +\0333Types d'outils : +;Tooltypes +; +; +MSGID_VERSION +\0333Version : +;Version +; +; +MSGID_DEFAULTTOOL +\0333Outil par défaut : +;Default tool +; +; +MSGID_STACKSIZE +\0333Taille de la pile : +;Stack size +; +; +MSGID_TOOL_PRIORITY +\0333 Priorité : +;Priority +; +; +MSGID_START_FROM +\0333Démarrage : +;Start from +; +; +MSGID_PROMPT_FOR_INPUT +\0333Invité de commande : +;Prompt for input +; +; +MSGID_VERSION_NOT_AVAILABLE +\033bnon disponible +;not available +; +; +MSGID_DRAWER_SIZE_SHORTHELP +Pressez ce bouton afin de calculer la\n\ +taille du contenu du répertoire/Volume.\n\ +Cette opération peut prendre un certain temps,\n\ +tout dépend du contenu du répertoire/Volume. +;Press this button to calculate the actual\n\ +;size of the drawer contents.\n\ +;This operation may takt some time,\n\ +;depending on the drawer contents. +; +; +MSGID_INITIAL_DRAWER_SIZE +1 Bloc +;1 block +; +; +MSGID_DRAWER_SIZE +%s Octects dans %lD fichiers, %lD répertoires (%lD blocs) +;%s bytes in %lD files, %lD drawers (%lD blocks) +; +MSGID_STARTPRI +Pri. au lancement : +;Start priority: +; +MSGID_WAITUNTILFINISHED +Attendre pendant : +;Wait until finished: +; +MSGID_WAITUNTILFINISHED_SHORTHELP +Pour les programmes du WBStartup, choisissez si Scalos devra attendre\n\ +que le programme ai fini son processus de démarrage,\n\ +ou si le processus continura en asynchrone. +;For WBStartup programs, selects if Scalos will wait\n\ +;until program is finished holding WBStartup processsing,\n\ +;or if processing will continue asynchronously. +; +MSGID_TOOL_SECONDS +secondes +;seconds +; +MSGID_ICONPOS_X +X : +; +MSGID_ICONPOS_Y +Y : +; +MSGID_ICONPOS_NONE +- +; +;----------------------------------------------------------- +; +MSGID_START_FROM_WORKBENCH +Workbench +;Workbench +; +; +MSGID_START_FROM_CLI +Shell +;Shell +; +; +MSGID_START_FROM_AREXX +ARexx +;ARexx +; +;----------------------------------------------------------- +; +MSGID_DEVICE_REGISTER_DEVICE +\033bDispositif +;Device +; +; +MSGID_DEVICE_REGISTER_ICON +\033bIcône +;Icon +; +;----------------------------------------------------------- +; +MSGID_DRAWER_REGISTER_DRAWER +\033bRépertoire +;Drawer +; +; +MSGID_DRAWER_REGISTER_ICON +\033bIcône +;Icon +; +;----------------------------------------------------------- +; +MSGID_PROJECT_REGISTER_PROJECT +\033bProjet +;Project +; +; +MSGID_PROJECT_REGISTER_ICON +\033bIcône +;Icon +; +;----------------------------------------------------------- +; +MSGID_TOOL_REGISTER_TOOL +\033bOutil +;Tool +; +; +MSGID_TOOL_REGISTER_ICON +\033bIcône +;Icon +; +;----------------------------------------------------------- +; +MSGID_ICONTYPE_DISK +(Volume) +;(Disk) +; +; +MSGID_ICONTYPE_DRAWER +(Répertoire) +;(Drawer) +; +; +MSGID_ICONTYPE_TOOL +(Outil) +;(Tool) +; +; +MSGID_ICONTYPE_PROJECT +(Projet) +;(Project) +; +; +MSGID_ICONTYPE_TRASHCAN +(Corbeille) +;(Trashcan) +; +; +MSGID_ICONTYPE_DEVICE +(Périphérique) +;(Device) +; +; +MSGID_ICONTYPE_KICKSTART +(Kickstart) +;(Kickstart) +; +; +MSGID_ICONTYPE_APPICON +(AppIcon) +;(AppIcon) +; +; +MSGID_ICONTYPE_UNKNOWN +(?? Inconnu ??) +;(??unknown??) +; +;----------------------------------------------------------- +; +MSGID_BYTES_GB +%lD Go +;%lDG +; +; +MSGID_BYTES_GB_2 +%lD%s%-02ld Go +;%lD%s%-02ldG +; +; +MSGID_BYTES_GB_1 +%lD%s%1ld Go +;%lD%s%1ldG +; +; +MSGID_BYTES_MB +%lD Mo +;%lDM +; +; +MSGID_BYTES_MB_2 +%lD%s%-02ld Mo +;%lD%s%-02ldM +; +; +MSGID_BYTES_MB_1 +%lD%s%1ld Mo +;%lD%s%1ldM +; +; +MSGID_BYTES_KB +%lD Ko +;%lDK +; +; +MSGID_BYTES_KB_2 +%lD%s%-02ld Ko +;%lD%s%-02ldK +; +; +MSGID_BYTES_KB_1 +%lD%s%1ld Ko +;%lD%s%1ldK +; +;----------------------------------------------------------- +; +MSGID_ERROR_SETCOMMENT +Erreur: Commentant\n\ +%s. +;Error setting comment\n\ +;%s. +; +; +MSGID_ERROR_SETPROTECTION +Erreur: Modifiant la protection de\n\ +%s. +;Error setting protection\n\ +;%s. +; +; +MSGID_ERROR_RELABEL +Erreur: Renommant le volume\n\ +%s. +;Error relabelling disk\n\ +;%s. +; +; +MSGID_ERROR_RENAME +Erreur: Renommant\n\ +%s. +;Error renaming\n\ +;%s. +; +; +MSGID_ERROR_REQ_OK +D'acc_ord +;_OK +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Le lancement de Information.module a échoué +;Information.module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Recommençer | Quitter +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +Celle-ci n'est pas installée. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +\n\ +La version installée est V%lu.%lu, installez-en une plus récente s'il vous plaît ! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +%lu.%lu est actuellement utilisée par d'autres applications.\n\ +\n\ +Une fois la version requise installée,\n\ +fermez tous les programmes MUI, soyez sûr que l'ancienne classe\n\ +ne soit plus présente dans la mémoire puis, essayez de nouveau. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_DEVICE_DOSTYPE +\0333Identificateur : +;Identifier: +; +; +MSGID_DEVICE_DOSTYPESTRING +(\033b%c%c%c%c\033n) +;(\033b%c%c%c%c\033n) +; +;----------------------------------------------------------- +; +MSGID_PROTECTION_HIDDEN +Caché +; Hidden +; +MSGID_PROTECTION_HIDDEN_SHORTHELP +Caché ??? +; Hidden??? +; +MSGID_PROTECTION_PURE +Pure +; Pure +; +MSGID_PROTECTION_PURE_SHORTHELP +Pure ??? +;Pure??? +; +;------------------------------------------------------------ +; +MSGID_TEXT_ICONPATH_SHORTHELP +Chemin d'accès de l'icône. +;Icon path +; +MSGID_FILETYPE_DRAWER +Répertoire +;Drawer +; +MSGID_FILETYPE_GARBAGE +Corbeille +;Trashcan +; +MSGID_FILETYPE_DISK +Volume +;Disk +; +MSGID_FILETYPE_TOOL +Outil +;Tool +; +MSGID_FILETYPE_PROJECT +Projet +;Project +; +MSGID_FILETYPE_APPICON +Icône app +;Appicon +; +;------------------------------------------------------------ +; diff --git "a/scalos/Modules/Information.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" "b/scalos/Modules/Information.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" new file mode 100755 index 000000000..a37de524f --- /dev/null +++ "b/scalos/Modules/Information.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" @@ -0,0 +1,40 @@ +# $Date: 2009-02-17 21:22:13 +0100 (Di, 17. Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = français + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = french + +else + +############################################################################### +# AmigaOS + +LANG = français + +endif +endif diff --git "a/scalos/Modules/Information.MUI/Catalogs/fran\303\247ais/Scalos/makefile" "b/scalos/Modules/Information.MUI/Catalogs/fran\303\247ais/Scalos/makefile" new file mode 100644 index 000000000..56f33f08d --- /dev/null +++ "b/scalos/Modules/Information.MUI/Catalogs/fran\303\247ais/Scalos/makefile" @@ -0,0 +1,14 @@ +# makefile for IconProperties.module (translated Texts : français) +# $Date$ +# $Revision$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mfrançais\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +Information.catalog : Information.ct ../../../Information.cd + +All: Information.catalog diff --git "a/scalos/Modules/Information.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" "b/scalos/Modules/Information.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" new file mode 100644 index 000000000..4c6408ab2 --- /dev/null +++ "b/scalos/Modules/Information.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" @@ -0,0 +1,30 @@ +# makefile for Information.module (translated Texts : français) +# $Date: 2011-07-24 10:11:00 +0200 (So, 24. Jul 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = Information + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Modules/Information.MUI/Catalogs/sample/Scalos/Information.ct b/scalos/Modules/Information.MUI/Catalogs/sample/Scalos/Information.ct new file mode 100644 index 000000000..c64c8564a --- /dev/null +++ b/scalos/Modules/Information.MUI/Catalogs/sample/Scalos/Information.ct @@ -0,0 +1,741 @@ +; Information.ct +## version $VER: Information.catalog 40.1 (20 Feb 2005 22:01:34) +## codeset 0s +## language xxxxxx +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Information +;Scalos Information +; +; +MSGID_OKBUTTON +Save +;Save +; +; +MSGID_SHORTHELP_OKBUTTON +Save the changed icon.\n\ +If necessary, a new icon will be\n\ +created from a the default icon. +;Save the changed icon.\n\ +;If necessary, a new icon will be\n\ +;created from a the default icon. +; +; +MSGID_CANCELBUTTON +Cancel +;Cancel +; +; +MSGID_SHORTHELP_CANCELBUTTON +Discard all changes and\n\ +leave the icon unchanged. +;Discard all changes and\n\ +;leave the icon unchanged. +; +; +MSGID_CREATE_APPLICATION_FAILED +Failed to create Application.\n +;Failed to create Application.\n +; +; +MSGID_CREATE_MAINWINDOW_FAILED +Failed to open main window !\n +;Failed to open main window !\n +; +; +MSGID_OPEN_LIBRARY_FAILED +Failed to open \"%s\" !\n +;Failed to open \"%s\" !\n +; +;;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Project +;Project +; +; +MSGID_MENU_PROJECT_ABOUT +About... +;About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI +About MUI... +;About MUI... +; +; +MSGID_MENU_PROJECT_QUIT +Quit +;Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +;Q +; +; +MSGID_MENU_TYPE +Type +;Type +; +; +MSGID_MENU_TYPE_DISK +Disk +;Disk +; +; +MSGID_MENU_TYPE_DRAWER +Drawer +;Drawer +; +; +MSGID_MENU_TYPE_PROJECT +Project +;Project +; +; +MSGID_MENU_TYPE_TOOL +Tool +;Tool +; +; +MSGID_MENU_TYPE_TRASHCAN +Trashcan +;Trashcan +; +; +MSGID_MENU_IMAGE +Icon Image +;Icon Image +; +; +MSGID_MENU_IMAGE_DEFAULT +Default +;Default +; +; +MSGID_MENU_IMAGE_DEFAULT_SHORT +D +;D +; +;+++ translateme +++ +MSGID_MENU_OPTIONS +Options +; Options +; +;+++ translateme +++ +MSGID_MENU_ALWAYS_ICONPATH +Always display icon path +; Always display icon path +; +;+++ translateme +++ +MSGID_MENU_ALWAYS_ICONPATH_SHORT +P +; P +; +; +++ translateme +++ +MSGID_MENU_ALWAYS_GETSIZE +Always get size +; Always get size +; +; +++ translateme +++ +MSGID_MENU_ALWAYS_GETSIZE_SHORT +G +; G +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +_OK +;_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Information.module V%ld.%ld\033n\n\ +%s\n\ +© 2004%s The Scalos Team +;\33c\033bScalos Information.module V%ld.%ld\033n\n\ +;%s\n\ +;© 2004%s The Scalos Team +; +;----------------------------------------------------------- +; +MSGID_DEVICE_DEVICE +Device +;Device +; +; +MSGID_DEVICE_HANDLER +Handler +;Handler +; +; +MSGID_DEVICE_CREATED_ON +Created on +;Created on +; +; +MSGID_DEVICE_SPACE_USED +Used +;Used +; +; +MSGID_DEVICE_SPACE_FREE +Free +;Free +; +; +MSGID_DEVICE_SIZE +Size +;Size +; +; +MSGID_DEVICE_BLOCK_SIZE +Block size +;Block size +; +; +MSGID_DEVICE_STATE +State +;State +; +; +MSGID_DEVICE_BLOCKS_PERCENT +%s (%lD Blocks, %lD%%) +;%s (%lD Blocks, %lD%%) +; +; +MSGID_DEVICE_BLOCKS +%s (%lD Blocks) +;%s (%lD Blocks) +; +; +MSGID_DEVICE_DISKSTATE_READONLY +read-only +;read-only +; +; +MSGID_DEVICE_DISKSTATE_VALIDATING +validating +;validating +; +; +MSGID_DEVICE_DISKSTATE_READ_WRITE +read-/writable +;read-/writable +; +; +MSGID_DEVICE_DISKSTATE_UNKNOWN +??unknown?? +??unknown?? +; +; +MSGID_DEVICE_BLOCKSIZE_BYTES +%lD bytes +;%lD bytes +; +; +MSGID_DEVICE_HANDLER_DISKID +%s %ld.%ld +;%s %ld.%ld +; +; +MSGID_DEVICE_ON_DEVNAME +on %s +;on %s +; +; +MSGID_DEVICE_DEVICE_UNIT +%s, %ld +;%s, %ld +; +;----------------------------------------------------------- +; +MSGID_LASTCHANGE +Last change +;Last change +; +; +MSGID_SIZE +Size +;Size +; +; +MSGID_SIZE_FORMAT +%s bytes +;%s bytes +; +; +MSGID_PROTECTION +Protection +;Protection +; +; +MSGID_PROTECTION_READ +Read +;Read +; +; +MSGID_PROTECTION_WRITE +Write +;Write +; +; +MSGID_PROTECTION_ARCHIVE +Archive +;Archive +; +; +MSGID_PROTECTION_DELETE +Delete +;Delete +; +; +MSGID_PROTECTION_EXECUTE +Execute +;Execute +; +; +MSGID_PROTECTION_SCRIPT +Script +;Script +; +; +MSGID_PROTECTION_READ_SHORTHELP +Read??? +;Read??? +; +; +MSGID_PROTECTION_WRITE_SHORTHELP +Write??? +;Write??? +; +; +MSGID_PROTECTION_ARCHIVE_SHORTHELP +Archive??? +;Archive??? +; +; +MSGID_PROTECTION_DELETE_SHORTHELP +Delete??? +;Delete??? +; +; +MSGID_PROTECTION_EXECUTE_SHORTHELP +Execute??? +;Execute??? +; +; +MSGID_PROTECTION_SCRIPT_SHORTHELP +Script??? +;Script??? +; +; +MSGID_COMMENT +Comment +;Comment +; +; +MSGID_TOOLTYPES +Tooltypes +;Tooltypes +; +; +MSGID_VERSION +Version +;Version +; +; +MSGID_DEFAULTTOOL +Default tool +;Default tool +; +; +MSGID_STACKSIZE +Stack size +;Stack size +; +; +MSGID_TOOL_PRIORITY +Priority +;Priority +; +; +MSGID_START_FROM +Start from +;Start from +; +; +MSGID_PROMPT_FOR_INPUT +Prompt for input +;Prompt for input +; +; +MSGID_VERSION_NOT_AVAILABLE +not available +;not available +; +; +MSGID_DRAWER_SIZE_SHORTHELP +Press this button to calculate the actual\n\ +size of the drawer contents.\n\ +This operation may takt some time,\n\ +depending on the drawer contents. +;Press this button to calculate the actual\n\ +;size of the drawer contents.\n\ +;This operation may takt some time,\n\ +;depending on the drawer contents. +; +; +MSGID_INITIAL_DRAWER_SIZE +1 block +;1 block +; +; +MSGID_DRAWER_SIZE +%s bytes in %lD files, %lD drawers (%lD blocks) +;%s bytes in %lD files, %lD drawers (%lD blocks) +; +; +MSGID_BUTTON_ABORT_SIZE +Abort ! +; Abort ! +; +; +MSGID_ABORT_SIZE_CALCULATION +Abort the size's calculation +; Abort the size's calculation +; +;+++translateme+++ +MSGID_STARTPRI +Start priority: +;Start priority: +; +;+++translateme+++ +MSGID_WAITUNTILFINISHED +Wait until finished: +;Wait until finished: +; +;+++translateme+++ +MSGID_WAITUNTILFINISHED_SHORTHELP +For WBStartup programs, selects if Scalos will wait\n\ +until program is finished holding WBStartup processsing,\n\ +or if processing will continue asynchronously. +;For WBStartup programs, selects if Scalos will wait\n\ +;until program is finished holding WBStartup processsing,\n\ +;or if processing will continue asynchronously. +; +;+++translateme+++ +MSGID_TOOL_SECONDS +seconds +;seconds +; +;+++translateme+++ +MSGID_ICONPOS_X +X: +; +;+++translateme+++ +MSGID_ICONPOS_Y +Y: +; +;+++translateme+++ +MSGID_ICONPOS_NONE +- +; +;----------------------------------------------------------- +; +MSGID_START_FROM_WORKBENCH +Workbench +;Workbench +; +; +MSGID_START_FROM_CLI +Shell +;Shell +; +; +MSGID_START_FROM_AREXX +ARexx +;ARexx +; +;----------------------------------------------------------- +; +MSGID_DEVICE_REGISTER_DEVICE +Device +;Device +; +; +MSGID_DEVICE_REGISTER_ICON +Icon +;Icon +; +;----------------------------------------------------------- +; +MSGID_DRAWER_REGISTER_DRAWER +Drawer +;Drawer +; +; +MSGID_DRAWER_REGISTER_ICON +Icon +;Icon +; +;----------------------------------------------------------- +; +MSGID_PROJECT_REGISTER_PROJECT +Project +;Project +; +; +MSGID_PROJECT_REGISTER_ICON +Icon +;Icon +; +;----------------------------------------------------------- +; +MSGID_TOOL_REGISTER_TOOL +Tool +;Tool +; +; +MSGID_TOOL_REGISTER_ICON +Icon +;Icon +; +;----------------------------------------------------------- +; +MSGID_ICONTYPE_DISK +(Disk) +;(Disk) +; +; +MSGID_ICONTYPE_DRAWER +(Drawer) +;(Drawer) +; +; +MSGID_ICONTYPE_TOOL +(Tool) +;(Tool) +; +; +MSGID_ICONTYPE_PROJECT +(Project) +;(Project) +; +; +MSGID_ICONTYPE_TRASHCAN +(Trashcan) +;(Trashcan) +; +; +MSGID_ICONTYPE_DEVICE +(Device) +;(Device) +; +; +MSGID_ICONTYPE_KICKSTART +(Kickstart) +;(Kickstart) +; +; +MSGID_ICONTYPE_APPICON +(AppIcon) +;(AppIcon) +; +; +MSGID_ICONTYPE_UNKNOWN +(??unknown??) +;(??unknown??) +; +;----------------------------------------------------------- +; +MSGID_BYTES_GB +%lDG +;%lDG +; +; +MSGID_BYTES_GB_2 +%lD%s%-02ldG +;%lD%s%-02ldG +; +; +MSGID_BYTES_GB_1 +%lD%s%1ldG +;%lD%s%1ldG +; +; +MSGID_BYTES_MB +%lDM +;%lDM +; +; +MSGID_BYTES_MB_2 +%lD%s%-02ldM +;%lD%s%-02ldM +; +; +MSGID_BYTES_MB_1 +%lD%s%1ldM +;%lD%s%1ldM +; +; +MSGID_BYTES_KB +%lDK +;%lDK +; +; +MSGID_BYTES_KB_2 +%lD%s%-02ldK +;%lD%s%-02ldK +; +; +MSGID_BYTES_KB_1 +%lD%s%1ldK +;%lD%s%1ldK +; +;----------------------------------------------------------- +; +MSGID_ERROR_SETCOMMENT +Error setting comment\n\ +%s. +;Error setting comment\n\ +;%s. +; +; +MSGID_ERROR_SETPROTECTION +Error setting protection\n\ +%s. +;Error setting protection\n\ +;%s. +; +; +MSGID_ERROR_RELABEL +Error relabelling disk\n\ +%s. +;Error relabelling disk\n\ +;%s. +; +; +MSGID_ERROR_RENAME +Error renaming\n\ +%s. +;Error renaming\n\ +;%s. +; +; +MSGID_ERROR_REQ_OK +_OK +;_OK +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Information.module startup failed +;Information.module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Try again|Quit +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_DEVICE_DOSTYPE +Identifier: +;Identifier: +; +MSGID_DEVICE_DOSTYPESTRING +(\033b%c%c%c%c\033n) +;(\033b%c%c%c%c\033n) +; +;-------------------------------------------------------------- +; +MSGID_PROTECTION_HIDDEN +Hidden +;Hidden +; +MSGID_PROTECTION_HIDDEN_SHORTHELP +Hidden??? +;Hidden??? +; +MSGID_PROTECTION_PURE +Pure +;Pure +; +MSGID_PROTECTION_PURE_SHORTHELP +Pure??? +;Pure??? +; +;------------------------------------------------------------ +; +MSGID_TEXT_ICONPATH_SHORTHELP +Icon path +;Icon path +; +;+++translateme+++ +MSGID_FILETYPE_DRAWER +Drawer +;Drawer +; +;+++translateme+++ +MSGID_FILETYPE_GARBAGE +Trashcan +;Trashcan +; +;+++translateme+++ +MSGID_FILETYPE_DISK +Disk +;Disk +; +;+++translateme+++ +MSGID_FILETYPE_TOOL +Tool +;Tool +; +;+++translateme+++ +MSGID_FILETYPE_PROJECT +Project +;Project +; +;+++translateme+++ +MSGID_FILETYPE_APPICON +Appicon +;Appicon +; +;------------------------------------------------------------ +; diff --git a/scalos/Modules/Information.MUI/Information.c b/scalos/Modules/Information.MUI/Information.c new file mode 100644 index 000000000..8f4bab580 --- /dev/null +++ b/scalos/Modules/Information.MUI/Information.c @@ -0,0 +1,5529 @@ +// Information.c +// $Date$ +// $Revision$ + +#ifdef __AROS__ +#define MUIMASTER_YES_INLINE_STDARG +#endif + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include // +jmc+ +#include + +#if !defined(MUIA_Application_UsedClasses) +#include +#endif /* MUIA_Application_UsedClasses */ + +#include "Information.h" +#include "IconobjectMCC.h" +#include "ToolTypes.h" +#include "FsAbstraction.h" +#include "debug.h" + +#define Information_NUMBERS +#define Information_ARRAY +#define Information_CODE +#include STR(SCALOSLOCALE) + +//---------------------------------------------------------------------------- + +#define VERSION_MAJOR 40 +#define VERSION_MINOR 13 + + +#define VERS_MAJOR STR(VERSION_MAJOR) +#define VERS_MINOR STR(VERSION_MINOR) + + +//---------------------------------------------------------------------------- + +#define ID_MAIN MAKE_ID('M','A','I','N') +#define PS_DATA(prefsstruct) ((STRPTR) (prefsstruct)) + sizeof((prefsstruct)->ps_Size) + +#if !defined(MADF_OBJECTVISIBLE) +#define MADF_OBJECTVISIBLE (1<<14) // The object is visible +#endif /* MADF_OBJECTVISIBLE */ + +//---------------------------------------------------------------------------- + +// local macros + +#define Label1S(name) \ + VGroup, \ + Child, VSpace(0), \ + Child, HGroup, \ + Child, HSpace(0), \ + Child, Label1(name), \ + End, \ + Child, VSpace(0), \ + End //VGroup + +#define ConstantText(contents) \ + TextObject, \ + TextFrame, \ + MUIA_Background, MUII_TextBack, \ + MUIA_Text_Contents, (contents), \ + End //Textobject + +#define ConstantFloatText(contents) \ + FloattextObject, \ + TextFrame, \ + MUIA_Weight, 0, \ + MUIA_Background, MUII_TextBack, \ + MUIA_Floattext_Text, (contents), \ + End //Textobject + +#define KeyButtonHelp(name,key,HelpText)\ + TextObject,\ + ButtonFrame,\ + MUIA_Font, MUIV_Font_Button,\ + MUIA_Text_Contents, name,\ + MUIA_Text_PreParse, "\33c",\ + MUIA_Text_HiChar , key,\ + MUIA_ControlChar , key,\ + MUIA_InputMode , MUIV_InputMode_RelVerify,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShortHelp , HelpText,\ + MUIA_CycleChain , TRUE,\ + End + +#define ButtonHelp(name,HelpText,InputMode)\ + TextObject,\ + ButtonFrame,\ + MUIA_Font, MUIV_Font_Button,\ + MUIA_Text_Contents, name,\ + MUIA_Text_PreParse, "\33c",\ + MUIA_InputMode , InputMode,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShortHelp , HelpText,\ + MUIA_CycleChain , TRUE,\ + End + +#define CheckMarkHelp(selected, HelpTextID)\ + ImageObject,\ + ImageButtonFrame,\ + MUIA_InputMode , MUIV_InputMode_Toggle,\ + MUIA_Image_Spec , MUII_CheckMark,\ + MUIA_Image_FreeVert , TRUE,\ + MUIA_Selected , selected,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShowSelState , FALSE,\ + MUIA_CycleChain , TRUE,\ + MUIA_ShortHelp , GetLocString(HelpTextID), \ + End + +#define UpArrowObject \ + ImageObject, \ + ImageButtonFrame, \ + MUIA_InputMode, MUIV_InputMode_RelVerify, \ + MUIA_Image_Spec, MUII_TapeUp, \ + MUIA_Background, MUII_ButtonBack, \ + MUIA_CycleChain, TRUE, \ + MUIA_ShowSelState, TRUE, \ + End + +#define DownArrowObject \ + ImageObject, \ + ImageButtonFrame, \ + MUIA_InputMode, MUIV_InputMode_RelVerify, \ + MUIA_Image_Spec, MUII_TapeDown, \ + MUIA_Background, MUII_ButtonBack, \ + MUIA_CycleChain, TRUE, \ + MUIA_ShowSelState, TRUE, \ + End + +#if defined(MUII_StringBack) + #define StringBack MUIA_Background, MUII_StringBack +#else /* MUII_StringBack */ + #define StringBack TAG_IGNORE, 0 +#endif /* MUII_StringBack */ + +//----------------------------------------------------------------------------------------------- + +#define GroupStackSize(stringobj, iconObj, uparrow, downarrow, name, slidobj, privalue) \ + HGroup, \ + Child, HGroup, MUIA_Group_HorizSpacing, 0, \ + Child, stringobj = StringObject, \ + StringFrame, \ + MUIA_String_Integer, GetStackSize(iconObj), \ + MUIA_String_Accept, "0123456789", \ + MUIA_CycleChain, TRUE, \ + End, \ + End, \ + \ + Child, slidobj = SliderObject, \ + MUIA_CycleChain, TRUE, \ + MUIA_Slider_Horiz, TRUE, \ + MUIA_Numeric_Min, -128, \ + MUIA_Numeric_Max, 127, \ + MUIA_Numeric_Value, privalue, \ + End, \ + End + +//------------------------------------------------------------------------------------------------------------------ + +#define MAX_PATH_SIZE 512 + +#define Application_Return_Ok 1001 +#define Application_Return_Path 1002 + +#define RESULT_HALT 1 + +#define FIBF_HIDDEN (1<<7) // 25.11.2004 Define Hidden protection bit + +#define CR '\x0d' +#define LF '\n' + +//---------------------------------------------------------------------------- + +// local data structures + +typedef void (*DropZoneHandler)(struct WBArg *, Object *, struct DefIconInfo *); + +struct FormatDateHookData + { + STRPTR fdhd_Buffer; // buffer to write characters to + size_t fdhd_Length; // length of buffer + }; + +struct DropZone + { + struct Node dz_Node; + Object *dz_Object; + struct IBox dz_Box; + struct AppWindowDropZone *dz_DropZone; + DropZoneHandler dz_Handler; + }; + +//---------------------------------------------------------------------------- + +// local functions + +static void init(void); +static void fail(APTR APP_Main, CONST_STRPTR str); +static void Cleanup(void); +static BOOL OpenLibraries(STRPTR *LibName); +static void CloseLibraries(void); +static SAVEDS(APTR) INTERRUPT OpenAboutMUIHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT OpenAboutHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT DrawerSizeHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT DefaultIconHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(ULONG) INTERRUPT AppWindowDropZoneHookFunc(struct Hook *hook, APTR Reserved, struct AppWindowDropZoneMsg *adzm); +static SAVEDS(void) INTERRUPT ChangeIconTypeHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT StartFromCycleHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(LONG) INTERRUPT SelectFromButtonHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT IconifyHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT StringIntegerIncrementHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT StringIntegerDecrementHookFunc(struct Hook *hook, Object *o, Msg msg); + +static void DropZoneMsgHandler(struct DropZoneMsg *dzm); +static void HandleAppMessage(struct AppMessage *AppMsg, struct DefIconInfo *dii); +static void ReplaceIcon(Object *NewIconObj, Object **OldIconObj); +static void UpdateDrawerSize(Object *ButtonSize, ULONG *FileCount, + ULONG *DrawersCount, ULONG *BlocksCount, ULONG64 *ByteCount); +static LONG ExamineDrawer(Object *ButtonSize, CONST_STRPTR Name, ULONG *FileCount, + ULONG *DrawersCount, ULONG *BlocksCount, ULONG64 *ByteCount, T_TIMEVAL *lastUpdateTime); +static LONG GetElapsedTime(T_TIMEVAL *tv); +static CONST_STRPTR GetLocString(ULONG MsgId); +static void TranslateStringArray(STRPTR *stringArray); +static void SaveSettings(Object *IconObj, Object *originalIconObj, CONST_STRPTR IconName); +static void GetIconObject(struct DefIconInfo *dii, CONST_STRPTR IconName, BPTR DirLock, + STRPTR FileTypeName, size_t FileTypeNameSize); +static void GetDeviceIconObject(struct DefIconInfo *dii, CONST_STRPTR IconName, + CONST_STRPTR VolumeName, CONST_STRPTR DeviceName, + STRPTR FileTypeName, size_t FileTypeNameSize); +static BOOL isDiskWritable(BPTR dLock); +static ULONG CheckInfoData(const struct InfoData *info); +static BOOL IsDevice(struct WBArg *arg); +static void GetDeviceName(BPTR dLock, CONST_STRPTR VolumeName, STRPTR DeviceName, size_t MaxLen); +static BOOL ReadScalosPrefs(void); +static CONST_STRPTR GetPrefsConfigString(APTR prefsHandle, ULONG Id, CONST_STRPTR DefaultString); +static void StripTrailingChar(STRPTR String, char CharToRemove); +static void BuildDefVolumeNameNoSpace(STRPTR Buffer, CONST_STRPTR VolumeName, size_t MaxLength); +static STRPTR ScaFormatString(CONST_STRPTR FormatString, STRPTR Buffer, size_t MaxLen, LONG NumArgs, ...); +static void ScaFormatDate(struct DateTime *dt, ULONG DayMaxLen, ULONG DateMaxLen, ULONG TimeMaxLen); +static M68KFUNC_P3_PROTO(void, FormatDateHookFunc, + A0, struct Hook *, theHook, + A2, struct Locale *, locale, + A1, char, ch); +static void BtoCstring(BSTR bstr, STRPTR Buffer, size_t BuffLen); +static void ByteCount(STRPTR Buffer, size_t BuffLen, LONG NumBlocks, LONG BytesPerBlock); +static UBYTE MakePrintable(UBYTE ch); +static CONST_STRPTR GetIconTypeName(Object *IconObj); +static const struct FileSysEntry *FindFileSysResEntry(ULONG DosType); +static STRPTR GetChangeDate(BOOL Valid, struct DateStamp *ChangeDate); +static ULONG GetStackSize(Object *IconObj); +static STRPTR GetDefaultTool(Object *IconObj); +static STRPTR GetVersionString(CONST_STRPTR IconName); +static void SetGuiFromIconType(Object *IconObj); +static CONST_STRPTR FindVersionString(const UBYTE *block, size_t BlockLen); +const struct Resident *SearchResident(const UWORD *block, size_t BlockLen); +static void ReportError(ULONG MsgId); +static BOOL RenameDevice(CONST_STRPTR OldName, CONST_STRPTR NewName); +static BOOL RenameObject(CONST_STRPTR OldName, CONST_STRPTR NewName); +static void SetupToolTypes(Object *IconObject, Object *TextEditor); +static void SetChangedToolTypes(Object *IconObj, Object *TextEditor); +static STRPTR GetSizeString(void); +static BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev); +static BOOL ToolTypeNameCmp(CONST_STRPTR ToolTypeName, CONST_STRPTR ToolTypeContents); +static void GetIconObjectFromWBArg(struct DefIconInfo *dii, struct WBArg *arg, + STRPTR FileTypeName, size_t FileTypeNameSize); +static BOOL RemoveDropZoneForObject(Object *o); +static void AddDropZoneForObject(Object *o, DropZoneHandler Handler); +static void AdjustDropZones(void); +static void HandleDropOnIcon(struct WBArg *arg, Object *o, struct DefIconInfo *dii); +static void HandleDropOnString(struct WBArg *arg, Object *o, struct DefIconInfo *dii); +static void HandleDropOnName(struct WBArg *arg, Object *o, struct DefIconInfo *dii); +static void HandleDropOnToolTypes(struct WBArg *arg, Object *o, struct DefIconInfo *dii); +static BOOL CheckIsWBStartup(BPTR DirLock); +static Object *GetIconObjectFromScalos(BPTR DirLock, CONST_STRPTR IconName, + STRPTR FileTypeName, size_t FileTypeNameSize); +#if 0 +static Object *GetDeviceIconObjectFromScalos(BPTR dLock, + STRPTR FileTypeName, size_t FileTypeNameSize); +#endif +static void GetIconFileType(struct ScaWindowTask *wt, struct ScaIconNode *in, + STRPTR FileTypeName, size_t FileTypeNameSize); +static struct InfoData *AllocInfoData(void); +static void FreeInfoData(struct InfoData *pId); +static struct ScaWindowStruct *FindScalosWindow(BPTR dirLock); + +//---------------------------------------------------------------------------- + +// local data items + +static UBYTE prefDefIconsFirst = TRUE; // Flag: try Def-Diskicons first +static CONST_STRPTR prefDefIconPath = "ENV:Sys"; + +extern struct ExecBase *SysBase; +struct IntuitionBase *IntuitionBase = NULL; +struct Library *IconBase = NULL; +struct Library *MUIMasterBase = NULL; +struct Library *WorkbenchBase = NULL; +struct Library *IconobjectBase = NULL; +struct ScalosBase *ScalosBase = NULL; +struct Library *PreferencesBase = NULL; +T_LOCALEBASE LocaleBase = NULL; +T_TIMERBASE TimerBase; + +#ifdef __amigaos4__ +struct IntuitionIFace *IIntuition = NULL; +struct IconIFace *IIcon = NULL; +struct MUIMasterIFace *IMUIMaster = NULL; +struct WorkbenchIFace *IWorkbench = NULL; +struct IconobjectIFace *IIconobject = NULL; +struct ScalosIFace *IScalos = NULL; +struct PreferencesIFace *IPreferences = NULL; +struct LocaleIFace *ILocale = NULL; +struct TimerIFace *ITimer; +#endif + +static struct Catalog *InformationCatalog; +static struct Locale *InformationLocale; + +static struct MsgPort *TimerPort; +static T_TIMEREQUEST *TimerIO; + +static STRPTR DeviceRegisterTitleStrings[] = + { + (STRPTR) MSGID_DEVICE_REGISTER_DEVICE, + (STRPTR) MSGID_DEVICE_REGISTER_ICON, + NULL + }; + +static STRPTR DrawerRegisterTitleStrings[] = + { + (STRPTR) MSGID_DRAWER_REGISTER_DRAWER, + (STRPTR) MSGID_DRAWER_REGISTER_ICON, + NULL + }; + +static STRPTR ProjectRegisterTitleStrings[] = + { + (STRPTR) MSGID_PROJECT_REGISTER_PROJECT, + (STRPTR) MSGID_TOOL_REGISTER_ICON, + NULL + }; + +static STRPTR ToolRegisterTitleStrings[] = + { + (STRPTR) MSGID_TOOL_REGISTER_TOOL, + (STRPTR) MSGID_TOOL_REGISTER_ICON, + NULL + }; + +static STRPTR StartFromCycleChoices[] = + { + (STRPTR) MSGID_START_FROM_WORKBENCH, + (STRPTR) MSGID_START_FROM_CLI, + (STRPTR) MSGID_START_FROM_AREXX, + NULL + }; + +static struct Hook AboutHook = { { NULL, NULL }, HOOKFUNC_DEF(OpenAboutHookFunc), NULL }; +static struct Hook AboutMUIHook = { { NULL, NULL }, HOOKFUNC_DEF(OpenAboutMUIHookFunc), NULL }; +static struct Hook ChangeIconTypeHook = { { NULL, NULL }, HOOKFUNC_DEF(ChangeIconTypeHookFunc), NULL }; +static struct Hook StartFromCycleHook = { { NULL, NULL }, HOOKFUNC_DEF(StartFromCycleHookFunc), NULL }; +static struct Hook DrawerSizeHook = { { NULL, NULL }, HOOKFUNC_DEF(DrawerSizeHookFunc), NULL }; +static struct Hook DefaultIconHook = {{ NULL, NULL }, HOOKFUNC_DEF(DefaultIconHookFunc), NULL }; +static struct Hook AppWindowDropZoneHook = {{ NULL, NULL }, HOOKFUNC_DEF(AppWindowDropZoneHookFunc), NULL }; +static struct Hook SelectFromButtonHook = {{ NULL, NULL }, HOOKFUNC_DEF(SelectFromButtonHookFunc), NULL }; // +jmc+ +static struct Hook IconifyHook = {{ NULL, NULL }, HOOKFUNC_DEF(&IconifyHookFunc), NULL }; // +jmc+ +static struct Hook StringIntegerIncrementHook = {{ NULL, NULL }, HOOKFUNC_DEF(&StringIntegerIncrementHookFunc), NULL }; +static struct Hook StringIntegerDecrementHook = {{ NULL, NULL }, HOOKFUNC_DEF(&StringIntegerDecrementHookFunc), NULL }; + +//---------------------------------------------------------------------------- + +static char TextDeviceName[128]; +static char TextDeviceOnDev[64]; +static char TextDeviceHandler[128]; +static char TextDeviceCreateDate[128]; +static char TextDeviceUsed[128]; +static char TextDeviceFree[128]; +static char TextDeviceSize[128]; +static char TextPosXString[64]; +static char TextPosYString[64]; +static char TextFileTypeName[108]; +static char DeviceBlockSize[128]; +static char DeviceState[128]; +static char TextLastChange[128]; +static char TextSize[64]; +static char TextVersion[512]; +static char InitButtonSize[128]; // +jmc+ : Initial ButtonSize(ButtonDiskSize or ButtonDrawerSize) gadget's contents. + // When size calculation is aborted, itinial text is inserted. + +//---------------------------------------------------------------------------- + +static Object *Group_Buttons2; +static Object *APP_Main; +static Object *WIN_Main; +static Object *WIN_AboutMUI; +static Object *OkButton, *CancelButton; +static Object *MenuAbout, *MenuAboutMUI, *MenuQuit; +static Object *MenuTypeDisk, *MenuTypeDrawer, *MenuTypeProject; +static Object *MenuTypeTool, *MenuTypeTrashcan; +static Object *MenuImageDefault; +static Object *MenuIconPath, *MenuGetSize; // +jmc+ : Variables options. +static Object *GroupDisk, *GroupDrawer; +static Object *GroupProject, *GroupTool; +static Object *TextTypeName, *TextOnDev; +static Object *StringStackSizeProject, *StringStackSizeTool; +static Object *PopAslDefaultTool; +static Object *SliderToolPriProject, *SliderToolPriTool; +static Object *CycleStartFromProject, *CycleStartFromTool; +static Object *ButtonPromptForInputProject, *ButtonPromptForInputTool; +static Object *StringCommentDrawer, *StringCommentProject, *StringCommentTool; +static Object *StringCommentDevice; +static Object *TextEditorToolTypesDrawer, *TextEditorToolTypesProject; +static Object *TextEditorToolTypesDevice, *TextEditorToolTypesTool; +static Object *ScrollBarToolTypesDrawer, *ScrollBarToolTypesProject; +static Object *ScrollBarToolTypesDevice, *ScrollBarToolTypesTool; +static Object *StringName; +static Object *ButtonDrawerSize, *ButtonDiskSize; +static Object *TextPosX, *TextPosY; + +static Object *CheckMarkProtectionReadDrawer, *CheckMarkProtectionWriteDrawer; +static Object *CheckMarkProtectionArchiveDrawer, *CheckMarkProtectionDeleteDrawer; +static Object *CheckMarkProtectionExecuteDrawer, *CheckMarkProtectionScriptDrawer; + + +static Object *CheckMarkProtectionHideProject, *CheckMarkProtectionPureProject; +static Object *CheckMarkProtectionReadProject, *CheckMarkProtectionWriteProject; +static Object *CheckMarkProtectionArchiveProject, *CheckMarkProtectionDeleteProject; +static Object *CheckMarkProtectionExecuteProject, *CheckMarkProtectionScriptProject; + +static Object *CheckMarkProtectionHideTool, *CheckMarkProtectionPureTool; +static Object *CheckMarkProtectionReadTool, *CheckMarkProtectionWriteTool; +static Object *CheckMarkProtectionArchiveTool, *CheckMarkProtectionDeleteTool; +static Object *CheckMarkProtectionExecuteTool, *CheckMarkProtectionScriptTool; + +static Object *SliderStartPriTool, *CheckMarkWaitUntilFinishedTool, *StringWaitTimeTool; +static Object *LabelStartPriTool, *LabelWaitUntilFinishedTool; +static Object *GroupWaitUntilFinished, *GroupIconTool, *GroupWaitTimeTool; +static Object *UpArrowStackSizeProject, *DownArrowStackSizeProject; +static Object *UpArrowStackSizeTool, *DownArrowStackSizeTool; +static Object *UpArrowWaitTimeTool, *DownArrowWaitTimeTool; +static Object *MccIconObj; +static Object *GroupMccIconObj, *Path, *Group_Virtual; //+jmc+ To switch 0/1 "MUIA_ShowMe" the ScroolGroupObject group. + +static Object *SliderStartPriTool2, *CheckMarkWaitUntilFinishedTool2, *StringWaitTimeTool2; +static Object *LabelStartPriTool2, *LabelWaitUntilFinishedTool2; +static Object *GroupWaitUntilFinished2, *GroupIconProject, *GroupWaitTimeTool2, *UpArrowWaitTimeTool2, *DownArrowWaitTimeTool2; + +//---------------------------------------------------------------------------- + +static struct MUI_CustomClass *IconobjectClass; + +static T_ExamineData *fib = NULL; +static BOOL FibValid = FALSE; +static LONG Result; + +static struct AppWindow *myAppWindow; +static struct MsgPort *AppMsgPort; +static struct MsgPort *DropZoneMsgPort; + +static struct Task *myTask; + +static struct List DropZoneList; + +static BOOL FoundDeviceHandler = FALSE; +static BOOL FoundDeviceDosType = FALSE; +static BOOL FoundDeviceFromArg = FALSE; +static char PathName[512]; + +//---------------------------------------------------------------------------- + +static void ScaFormatStringMaxLength(char *Buffer, size_t BuffLen, const char *Format, ...); +static void ScaFormatStringArgs(char *Buffer, size_t BuffLength, const char *Format, APTR Args); +static STRPTR AllocCopyString(CONST_STRPTR clp); +static void FreeCopyString(STRPTR lp); + +//---------------------------------------------------------------------------- + +const char versTag[] = "\0$VER: Scalos Information.module V" VERS_MAJOR "." VERS_MINOR " (" __DATE__ ") " COMPILER_STRING; + +#if !defined(__amigaos4__) && !defined(__AROS__) +#include + +long _stack = 32768; // minimum stack size, used by SAS/C startup code +#endif + + +//---------------------------------------------------------------------------- + +int main(int argc, char *argv[]) +{ + LONG win_opened = 0; + BPTR oldDir = (BPTR)NULL; + CONST_STRPTR IconName = ""; + Object *iconObjFromScalos = NULL; + Object *iconObjFromDisk = NULL; + Object *backupIconObjFromDisk = NULL; + BOOL IsWriteable = TRUE; + BOOL IsWBStartup = FALSE; + char VolumeName[128]; + LONG ShowIconPath; + LONG AutoGetSize; + char Buffer[25]; + struct DefIconInfo dii; + struct WBStartup *WBenchMsg = + (argc == 0) ? (struct WBStartup *)argv : NULL; + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + dii.dii_IconObjectFromDisk = &iconObjFromDisk; + dii.dii_IconObjectFromScalos = &iconObjFromScalos; + dii.dii_BackupIconObjectFromDisk = &backupIconObjFromDisk; + + ChangeIconTypeHook.h_Data = DefaultIconHook.h_Data = &dii; + + init(); + + myTask = FindTask(NULL); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + if (!CheckMCCVersion(MUIC_NListview, 19, 66) + || !CheckMCCVersion(MUIC_TextEditor, 15, 28)) + { + Cleanup(); + return 10; + } + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + DropZoneMsgPort = CreateMsgPort(); + if (NULL == DropZoneMsgPort) + { + Cleanup(); + return 10; + } + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + //--- +jmc+ -------------------------------------------------------------------------------------------------- + + //--- InfoShowIconPath variable --- + if (GetVar(INFO_ICONPATH_ENV, Buffer, sizeof(Buffer), GVF_GLOBAL_ONLY) <= 0) + { + d1(KPrintF("%s/%s/%ld: %s NOT FOUND\n", __FILE__, __FUNC__, __LINE__, INFO_ICONPATH_ENV)); + + ShowIconPath = 1; + ScaFormatStringMaxLength(Buffer, strlen(Buffer), "%lu", ShowIconPath); + + SetVar(INFO_ICONPATH_ENV, Buffer, -1, GVF_GLOBAL_ONLY); + } + else + { + unsigned long ulong1; + d1(KPrintF("%s/%s/%ld: INFO_ICONPATH_ENV=<%s>\n", __FILE__, __FUNC__, __LINE__, Buffer)); + sscanf(Buffer, "%lu", &ulong1); + ShowIconPath = ulong1; + } + + //--- InfoAutoGetSize variable ---- + if (GetVar(INFO_AUTOGETSIZE_ENV, Buffer, sizeof(Buffer), GVF_GLOBAL_ONLY) <= 0) + { + d1(KPrintF("%s/%s/%ld: %s NOT FOUND\n", __FILE__, __FUNC__, __LINE__, INFO_AUTOGETSIZE_ENV)); + + AutoGetSize = 0; + ScaFormatStringMaxLength(Buffer, strlen(Buffer), "%lu", ShowIconPath); + + SetVar(INFO_AUTOGETSIZE_ENV, Buffer, -1, GVF_GLOBAL_ONLY); + } + else + { + unsigned long long1; + d1(KPrintF("%s/%s/%ld: INFO_AUTOGETSIZE_ENV=<%s>\n", __FILE__, __FUNC__, __LINE__, Buffer)); + sscanf(Buffer, "%lu", &long1); + AutoGetSize = long1; + } + + //------------------------------------------------------------------------------------------------------------ + + TranslateStringArray(StartFromCycleChoices); + TranslateStringArray(DeviceRegisterTitleStrings); + TranslateStringArray(DrawerRegisterTitleStrings); + TranslateStringArray(ProjectRegisterTitleStrings); + TranslateStringArray(ToolRegisterTitleStrings); + + d1(KPrintF(__FILE__ "/%s/%ld: WBenchMsg=%08lx\n", __FUNC__, __LINE__, WBenchMsg)); + + if (WBenchMsg && WBenchMsg->sm_ArgList) + { + struct WBArg *arg; + + d1(KPrintF(__FILE__ "/%s/%ld: NumArgs=%lu\n", __FUNC__, __LINE__, WBenchMsg->sm_NumArgs)); + + if (WBenchMsg->sm_NumArgs > 1) + { + BPTR fLock; + + arg = &WBenchMsg->sm_ArgList[1]; + + DrawerSizeHook.h_Data = arg; + + IsWBStartup = CheckIsWBStartup(arg->wa_Lock); + + IconName = arg->wa_Name; + + d1(kprintf(__FILE__ "/%s/%ld: wa_Lock=%08lx\n", __FUNC__, __LINE__, arg->wa_Lock)); + + oldDir = CurrentDir(arg->wa_Lock); + + fLock = Lock(arg->wa_Name, ACCESS_READ); + if (fLock) + { + if (ScalosExamineLock(fLock, &fib)) + FibValid = TRUE; + UnLock(fLock); + } + + GetIconObjectFromWBArg(&dii, arg, TextFileTypeName, sizeof(TextFileTypeName)); + + dii.dii_DirLock = arg->wa_Lock; + dii.dii_IconName = arg->wa_Name; + + if (IsDevice(arg)) + { + NameFromLock(arg->wa_Lock, VolumeName, sizeof(VolumeName)); + fLock = Lock(VolumeName, ACCESS_READ); + if (fLock) + { + if (ScalosExamineLock(fLock, &fib)) // +jmc+ - fib->fib_Comment for WBDISK(Supported by some FileSystems - Not for PFS). + FibValid = TRUE; + UnLock(fLock); + } + + StripTrailingChar(VolumeName, ':'); + + d1(kprintf(__FILE__ "/%s/%ld: VolumeName=<%s>\n", __FUNC__, __LINE__, VolumeName)); + + IconName = VolumeName; + } + + IsWriteable = isDiskWritable(arg->wa_Lock); + } + } + + d1(KPrintF(__FILE__ "/%s/%ld: iconObjFromDisk=%08lx iconObjFromScalos=%08lx\n", \ + __FUNC__, __LINE__, iconObjFromDisk, iconObjFromScalos)); + + if (iconObjFromDisk) + { + const struct ExtGadget *gg = (const struct ExtGadget *) iconObjFromDisk; + STRPTR *ToolTypesArray = NULL; + ULONG IconType; + enum StartFromType StartFrom = STARTFROM_Workbench; + BOOL PromptForInput = FALSE; + BOOL WaitUntilFinished = TRUE; + LONG ToolPri = 0; + LONG StartPri = 0; + LONG WaitTime = 0; + ULONG Protection = FibValid ? ScalosExamineGetProtection(fib) : 0; + CONST_STRPTR Comment = FibValid ? ScalosExamineGetComment(fib) : (CONST_STRPTR) ""; + + d1(kprintf(__FILE__ "/%s/%ld: FibValid=%ld fib=%08lx\n", __FUNC__, __LINE__, FibValid, fib)); + + GetAttr(IDTA_ToolTypes, iconObjFromDisk, (APTR)&ToolTypesArray); + GetAttr(IDTA_Type, iconObjFromDisk, &IconType); + + if ((0 == gg->LeftEdge && 0 == gg->TopEdge) + || NO_ICON_POSITION_SHORT == (UWORD) gg->LeftEdge || NO_ICON_POSITION_SHORT == (UWORD) gg->TopEdge) + { + stccpy(TextPosXString, GetLocString(MSGID_ICONPOS_NONE), sizeof(TextPosXString)); + stccpy(TextPosYString, GetLocString(MSGID_ICONPOS_NONE), sizeof(TextPosYString)); + } + else + { + snprintf(TextPosXString, sizeof(TextPosXString), "%d", gg->LeftEdge); + snprintf(TextPosYString, sizeof(TextPosYString), "%d", gg->TopEdge); + } + + d1(KPrintF(__FILE__ "/%s/%ld: LeftEdge=%lx TopEdge=%lx\n", __FUNC__, __LINE__, gg->LeftEdge, gg->TopEdge)); + + if (ToolTypesArray) + { + STRPTR ToolPriString; + long long1; + + if (FindToolType(ToolTypesArray, "DONOTWAIT")) + WaitUntilFinished = FALSE; + else + WaitUntilFinished = TRUE; + + ToolPriString = FindToolType(ToolTypesArray, "WAIT"); + if (ToolPriString) + { + sscanf(ToolPriString, "%ld", &long1); + WaitTime = long1; + } + ToolPriString = FindToolType(ToolTypesArray, "STARTPRI"); + if (ToolPriString) + { + sscanf(ToolPriString, "%ld", &long1); + StartPri = long1; + } + if (FindToolType(ToolTypesArray, "CLI")) + StartFrom = STARTFROM_CLI; + else if (FindToolType(ToolTypesArray, "REXX")) + StartFrom = STARTFROM_Arexx; + + if (STARTFROM_CLI == StartFrom || STARTFROM_Arexx == StartFrom) + { + PromptForInput = NULL == FindToolType(ToolTypesArray, "DONOTPROMPT"); + } + + ToolPriString = FindToolType(ToolTypesArray, "TOOLPRI"); + if (ToolPriString) + sscanf(ToolPriString, "%ld", &ToolPri); + } + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + APP_Main = ApplicationObject, + MUIA_Application_Title, GetLocString(MSGID_TITLENAME), + MUIA_Application_Version, versTag + 1, + MUIA_Application_Copyright, "© The Scalos Team, 2004" CURRENTYEAR, + MUIA_Application_Author, "The Scalos Team", + MUIA_Application_Description, "Scalos Information module", + MUIA_Application_Base, "SCALOS_INFORMATION", + + SubWindow, WIN_Main = WindowObject, + MUIA_Window_Title, GetLocString(MSGID_TITLENAME), +// MUIA_Window_ID, MAKE_ID('M','A','I','N'), + MUIA_Window_AppWindow, FALSE, + + MUIA_Window_TopEdge, MUIV_Window_TopEdge_Moused, + MUIA_Window_LeftEdge, MUIV_Window_LeftEdge_Moused, + + MUIA_Window_Width, MUIV_Window_Width_MinMax(0), + MUIA_Window_Height, MUIV_Window_Height_MinMax(0), + + WindowContents, VGroup, + + Child, HGroup, + Child, StringName = StringObject, + MUIA_Text_PreParse, MUIX_C MUIX_B, + MUIA_String_Contents, IconName, + MUIA_String_MaxLen, 108, + StringFrame, + StringBack, + MUIA_String_Format, MUIV_String_Format_Center, + MUIA_Weight, 100, + MUIA_CycleChain, TRUE, + End, //StringObject + Child, TextOnDev = TextObject, + MUIA_ShowMe, strlen(TextDeviceOnDev) > 0, + MUIA_Text_Contents, TextDeviceOnDev, + MUIA_Weight, 0, + End, //TextObject + Child, TextTypeName = TextObject, + MUIA_Text_Contents, GetIconTypeName(iconObjFromDisk), + MUIA_Weight, 0, + End, //TextObject + End, //HGroup + +//---- +jmc+ ----------------------------------------------------------------------------------------------------------------------------------- + + Child, Group_Virtual = ScrollgroupObject, + MUIA_ShowMe, strlen(PathName) > 0 ? ShowIconPath : FALSE, + MUIA_CycleChain, TRUE, + MUIA_Scrollgroup_FreeHoriz, TRUE, + MUIA_Scrollgroup_FreeVert, FALSE, + MUIA_Scrollgroup_Contents, + VirtgroupObject, + Child, Path = TextObject, TextFrame, + MUIA_Background, MUII_TextBack, + MUIA_Text_PreParse, MUIX_C, + MUIA_Text_Contents, PathName, + MUIA_ShortHelp, GetLocString(MSGID_TEXT_ICONPATH_SHORTHELP), + End, //TextObject + End, //VirtgroupObject + End, //ScrollgroupObject + +//---------------------------------------------------------------------------------------------------------------------------------------------- + Child, HGroup, + Child, GroupMccIconObj = VGroup, + Child, VSpace(0), + + Child, TextObject, + MUIA_Text_PreParse, MUIX_C, + MUIA_Text_Contents, TextFileTypeName, + End, //TextObject + + Child, VSpace(1), + + Child, MccIconObj = IconobjectMCCObject, + MUIA_Iconobj_Object, iconObjFromScalos ? iconObjFromScalos : iconObjFromDisk, + MUIA_InputMode, MUIV_InputMode_Toggle, + MUIA_ShowSelState, FALSE, + MUIA_Dropable, TRUE, + End, //IconobjectMCCObject + + Child, VSpace(1), + + Child, ColGroup(4), + Child, HSpace(0), + + Child, TextObject, + MUIA_Text_Contents, GetLocString(MSGID_ICONPOS_X), + End, //TextObject + Child, TextPosX = TextObject, + MUIA_Text_PreParse, MUIX_R, + MUIA_Text_Contents, TextPosXString, + End, //TextObject + + Child, HSpace(0), + Child, HSpace(0), + + Child, TextObject, + MUIA_Text_Contents, GetLocString(MSGID_ICONPOS_Y), + End, //TextObject + Child, TextPosY = TextObject, + MUIA_Text_PreParse, MUIX_R, + MUIA_Text_Contents, TextPosYString, + End, //TextObject + + Child, HSpace(0), + End, //ColGroup(2) + + Child, VSpace(0), + End, //VGroup + + Child, VGroup, + MUIA_Background, MUII_GroupBack, + + Child, GroupDisk = RegisterObject, + MUIA_Register_Titles, DeviceRegisterTitleStrings, + MUIA_CycleChain, TRUE, + MUIA_ShowMe, (WBDISK == IconType), + + Child, VGroup, + GroupFrame, + Child, ColGroup(2), + strlen(TextDeviceName) > 0 ? Child : TAG_IGNORE, Label1(GetLocString(MSGID_DEVICE_DEVICE)), + strlen(TextDeviceName) > 0 ? Child : TAG_IGNORE, ConstantText(TextDeviceName), + + // strlen(TextDeviceHandler) > 0 ? Child : TAG_IGNORE, Label1(GetLocString(MSGID_DEVICE_HANDLER)), + FoundDeviceHandler ? Child : TAG_IGNORE, Label1(GetLocString(MSGID_DEVICE_HANDLER)), + (!FoundDeviceHandler && FoundDeviceDosType) ? Child : TAG_IGNORE, Label1(GetLocString(MSGID_DEVICE_DOSTYPE)), + + strlen(TextDeviceHandler) > 0 ? Child : TAG_IGNORE, ConstantFloatText(TextDeviceHandler), + + Child, Label1(GetLocString(MSGID_DEVICE_CREATED_ON)), + Child, ConstantText(TextDeviceCreateDate), + + Child, Label1(GetLocString(MSGID_DEVICE_SPACE_USED)), + Child, ButtonDiskSize = ButtonHelp(TextDeviceUsed, GetLocString(MSGID_DRAWER_SIZE_SHORTHELP), MUIV_InputMode_Toggle), + + Child, Label1(GetLocString(MSGID_DEVICE_SPACE_FREE)), + Child, ConstantText(TextDeviceFree), + + Child, Label1(GetLocString(MSGID_DEVICE_SIZE)), + Child, ConstantText(TextDeviceSize), + + Child, Label1(GetLocString(MSGID_DEVICE_BLOCK_SIZE)), + Child, ConstantText(DeviceBlockSize), + + Child, Label1(GetLocString(MSGID_DEVICE_STATE)), + Child, ConstantText(DeviceState), + + Child, Label1S(GetLocString(MSGID_COMMENT)), + Child, StringCommentDevice = StringObject, + StringFrame, + StringBack, + MUIA_String_Contents, (ULONG) Comment, + MUIA_CycleChain, TRUE, + MUIA_Dropable, TRUE, + End, //StringObject + End, //ColGroup + End, //VGroup + + Child, VGroup, + GroupFrame, + + Child, ColGroup(2), + Child, VGroup, + Child, VSpace(0), + Child, Label1(GetLocString(MSGID_TOOLTYPES)), + Child, VSpace(0), + End, //VGroup + Child, HGroup, + Child, TextEditorToolTypesDevice = TextEditorObject, + TextFrame, + MUIA_Background, MUII_TextBack, + MUIA_CycleChain, TRUE, + //MUIA_Textinput_Multiline, TRUE, + MUIA_Dropable, TRUE, + End, //TextEditorObject + Child, ScrollBarToolTypesDevice = ScrollbarObject, + MUIA_Background, MUII_PropBack, + SliderFrame, + End, //ScrollbarObject + End, //HGroup + End, //ColGroup + End, //VGroup + End, //RegisterObject + + Child, GroupDrawer = RegisterObject, + MUIA_Register_Titles, DrawerRegisterTitleStrings, + MUIA_CycleChain, TRUE, + MUIA_ShowMe, (WBDRAWER == IconType) || (WBGARBAGE == IconType), + + Child, VGroup, + GroupFrame, + Child, ColGroup(2), + Child, Label1S(GetLocString(MSGID_LASTCHANGE)), + Child, ConstantText(GetChangeDate(FibValid, ScalosExamineGetDate(fib))), + Child, Label1S(GetLocString(MSGID_SIZE)), + Child, ButtonDrawerSize = ButtonHelp(GetLocString(MSGID_INITIAL_DRAWER_SIZE), GetLocString(MSGID_DRAWER_SIZE_SHORTHELP), MUIV_InputMode_Toggle), + Child, Label1S(GetLocString(MSGID_PROTECTION)), + Child, VGroup, + Child, VSpace(0), + Child, HGroup, + GroupFrame, + Child, HSpace(0), + Child, ColGroup(2 * 3), + MUIA_Disabled, !FibValid || !IsWriteable, + + Child, Label1(GetLocString(MSGID_PROTECTION_READ)), + Child, CheckMarkProtectionReadDrawer = CheckMarkHelp(!(Protection & FIBF_READ), MSGID_PROTECTION_READ_SHORTHELP), + + Child, Label1(GetLocString(MSGID_PROTECTION_WRITE)), + Child, CheckMarkProtectionWriteDrawer = CheckMarkHelp(!(Protection & FIBF_WRITE), MSGID_PROTECTION_WRITE_SHORTHELP), + + Child, Label1(GetLocString(MSGID_PROTECTION_ARCHIVE)), + Child, CheckMarkProtectionArchiveDrawer = CheckMarkHelp(Protection & FIBF_ARCHIVE, MSGID_PROTECTION_ARCHIVE_SHORTHELP), + + Child, Label1(GetLocString(MSGID_PROTECTION_DELETE)), + Child, CheckMarkProtectionDeleteDrawer = CheckMarkHelp(!(Protection & FIBF_DELETE), MSGID_PROTECTION_DELETE_SHORTHELP), + + Child, Label1(GetLocString(MSGID_PROTECTION_EXECUTE)), + Child, CheckMarkProtectionExecuteDrawer = CheckMarkHelp(!(Protection & FIBF_EXECUTE), MSGID_PROTECTION_EXECUTE_SHORTHELP), + + Child, Label1(GetLocString(MSGID_PROTECTION_SCRIPT)), + Child, CheckMarkProtectionScriptDrawer = CheckMarkHelp(Protection & FIBF_SCRIPT, MSGID_PROTECTION_SCRIPT_SHORTHELP), + End, //ColGroup + Child, HSpace(0), + End, //HGroup + Child, VSpace(0), + End, //VGroup + Child, Label1S(GetLocString(MSGID_COMMENT)), + Child, StringCommentDrawer = StringObject, + StringFrame, + StringBack, + MUIA_String_Contents, Comment, + MUIA_CycleChain, TRUE, + MUIA_Dropable, TRUE, + End, //StringObject + End, //ColGroup + End, //VGroup + + Child, VGroup, + GroupFrame, + + Child, ColGroup(2), + Child, VGroup, + Child, VSpace(0), + Child, Label1(GetLocString(MSGID_TOOLTYPES)), + Child, VSpace(0), + End, //VGroup + Child, HGroup, + Child, TextEditorToolTypesDrawer = TextEditorObject, + TextFrame, + MUIA_Background, MUII_TextBack, + MUIA_CycleChain, TRUE, + //MUIA_Textinput_Multiline, TRUE, + MUIA_Dropable, TRUE, + End, //TextEditorObject + Child, ScrollBarToolTypesDrawer = ScrollbarObject, + MUIA_Background, MUII_PropBack, + SliderFrame, + End, //ScrollbarObject + End, //HGroup + End, //ColGroup + End, //VGroup + + End, //RegisterObject + + Child, GroupProject = RegisterObject, + MUIA_Register_Titles, ProjectRegisterTitleStrings, + MUIA_CycleChain, TRUE, + MUIA_ShowMe, WBPROJECT == IconType, + + Child, VGroup, + GroupFrame, + Child, ColGroup(2), + Child, Label1S(GetLocString(MSGID_VERSION)), + Child, ConstantFloatText(GetVersionString(IconName)), + + Child, Label1S(GetLocString(MSGID_LASTCHANGE)), + Child, ConstantText(GetChangeDate(FibValid, ScalosExamineGetDate(fib))), + + Child, Label1S(GetLocString(MSGID_SIZE)), + Child, ConstantText(GetSizeString()), + + Child, Label1S(GetLocString(MSGID_PROTECTION)), + Child, VGroup, + Child, VSpace(0), + Child, HGroup, + GroupFrame, + Child, HSpace(0), + + Child, ColGroup(2 * 4), + MUIA_Disabled, !FibValid || !IsWriteable, + + Child, Label1(GetLocString(MSGID_PROTECTION_HIDDEN)), + Child, CheckMarkProtectionHideProject = CheckMarkHelp((Protection & FIBF_HIDDEN), MSGID_PROTECTION_HIDDEN_SHORTHELP), + + + Child, Label1(GetLocString(MSGID_PROTECTION_READ)), + Child, CheckMarkProtectionReadProject = CheckMarkHelp(!(Protection & FIBF_READ), MSGID_PROTECTION_READ_SHORTHELP), + + Child, Label1(GetLocString(MSGID_PROTECTION_WRITE)), + Child, CheckMarkProtectionWriteProject = CheckMarkHelp(!(Protection & FIBF_WRITE), MSGID_PROTECTION_WRITE_SHORTHELP), + + Child, Label1(GetLocString(MSGID_PROTECTION_ARCHIVE)), + Child, CheckMarkProtectionArchiveProject = CheckMarkHelp(Protection & FIBF_ARCHIVE, MSGID_PROTECTION_ARCHIVE_SHORTHELP), + + + Child, Label1(GetLocString(MSGID_PROTECTION_DELETE)), + Child, CheckMarkProtectionDeleteProject = CheckMarkHelp(!(Protection & FIBF_DELETE), MSGID_PROTECTION_DELETE_SHORTHELP), + + + Child, Label1(GetLocString(MSGID_PROTECTION_PURE)), + Child, CheckMarkProtectionPureProject = CheckMarkHelp((Protection & FIBF_PURE), MSGID_PROTECTION_PURE_SHORTHELP), + + + Child, Label1(GetLocString(MSGID_PROTECTION_EXECUTE)), + Child, CheckMarkProtectionExecuteProject = CheckMarkHelp(!(Protection & FIBF_EXECUTE), MSGID_PROTECTION_EXECUTE_SHORTHELP), + + Child, Label1(GetLocString(MSGID_PROTECTION_SCRIPT)), + Child, CheckMarkProtectionScriptProject = CheckMarkHelp(Protection & FIBF_SCRIPT, MSGID_PROTECTION_SCRIPT_SHORTHELP), + End, //ColGroup + + Child, HSpace(0), + End, //HGroup + Child, VSpace(0), + End, //VGroup + + Child, Label1S(GetLocString(MSGID_COMMENT)), + Child, StringCommentProject = StringObject, + StringFrame, + StringBack, + MUIA_String_Contents, (ULONG) Comment, + MUIA_CycleChain, TRUE, + MUIA_Dropable, TRUE, + End, //TextObject + End, //ColGroup + End, //VGroup + + Child, VGroup, + GroupFrame, + + Child, GroupIconProject = ColGroup(2), + Child, Label1(GetLocString(MSGID_DEFAULTTOOL)), + Child, PopAslDefaultTool = PopaslObject, + MUIA_Popstring_Button, PopButton(MUII_PopDrawer), + MUIA_Dropable, TRUE, + MUIA_Popstring_String, StringObject, + StringFrame, + StringBack, + MUIA_String_Contents, GetDefaultTool(iconObjFromDisk), + MUIA_CycleChain, TRUE, + End, //StringObject +// ASLFR_TitleText, (ULONG) GetLocString(MSGID_PATHSPAGE_SCALOS_HOME_ASLTITLE), +// MUIA_ShortHelp, (ULONG) GetLocString(MSGID_PATHSPAGE_SCALOS_HOME_SHORTHELP), + End, //PopaslObject + + + Child, Label1(GetLocString(MSGID_STACKSIZE)), + Child, HGroup, + Child, HGroup, + MUIA_Group_HorizSpacing, 0, + Child, StringStackSizeProject = StringObject, + StringFrame, + StringBack, + MUIA_String_Integer, GetStackSize(iconObjFromDisk), + MUIA_String_Accept, "0123456789", + MUIA_CycleChain, TRUE, + End, //StringObject + Child, VGroup, + MUIA_Group_VertSpacing, 0, + Child, UpArrowStackSizeProject = UpArrowObject, + Child, DownArrowStackSizeProject = DownArrowObject, + End, //VGroup + End, //HGroup + + Child, Label1(GetLocString(MSGID_TOOL_PRIORITY)), + Child, SliderToolPriProject = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Min, -128, + MUIA_Numeric_Max, 127, + MUIA_Numeric_Value, ToolPri, + End, //SliderObject + End, //HGroup + + Child, Label1(GetLocString(MSGID_START_FROM)), + Child, HGroup, + Child, CycleStartFromProject = CycleObject, + MUIA_CycleChain, TRUE, + MUIA_Cycle_Entries, StartFromCycleChoices, + MUIA_Cycle_Active, StartFrom, + End, //CycleObject + + Child, Label1(GetLocString(MSGID_PROMPT_FOR_INPUT)), + Child, ButtonPromptForInputProject = ImageObject, + ButtonFrame, + MUIA_InputMode, MUIV_InputMode_Toggle, + MUIA_Image_Spec, MUII_CheckMark, + MUIA_Selected, PromptForInput, + MUIA_Background, MUII_ButtonBack, + MUIA_ShowSelState, FALSE, + End, //Image + End, //HGroup + + Child, VGroup, + Child, VSpace(0), + Child, Label1(GetLocString(MSGID_TOOLTYPES)), + Child, VSpace(0), + End, //VGroup + + Child, HGroup, + Child, TextEditorToolTypesProject = TextEditorObject, + TextFrame, + MUIA_Background, MUII_TextBack, + MUIA_CycleChain, TRUE, + //MUIA_Textinput_Multiline, TRUE, + MUIA_Dropable, TRUE, + End, //TextEditorObject + Child, ScrollBarToolTypesProject = ScrollbarObject, + MUIA_Background, MUII_PropBack, + SliderFrame, + End, //ScrollbarObject + End, //HGroup + +//************************************************************* WBStartup members **************************************************************** + + // the following members are only used for icons located in WBStartup + // for all other directories, those members will be removed later + Child, LabelStartPriTool2 = Label1S(GetLocString(MSGID_STARTPRI)), + Child, SliderStartPriTool2 = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Min, -128, + MUIA_Numeric_Max, 127, + MUIA_Numeric_Value, StartPri, + End, //SliderObject + + Child, LabelWaitUntilFinishedTool2 = Label1S(GetLocString(MSGID_WAITUNTILFINISHED)), + Child, GroupWaitUntilFinished2 = HGroup, + Child, CheckMarkWaitUntilFinishedTool2 = CheckMarkHelp(WaitUntilFinished, MSGID_WAITUNTILFINISHED_SHORTHELP), + + Child, GroupWaitTimeTool2 = HGroup, + MUIA_Group_HorizSpacing, 0, + MUIA_Disabled, !WaitUntilFinished, + + Child, StringWaitTimeTool2 = StringObject, + StringFrame, + StringBack, + MUIA_String_Integer, WaitTime, + MUIA_String_Accept, "0123456789", + MUIA_CycleChain, TRUE, + End, //StringObject + Child, VGroup, + MUIA_Group_VertSpacing, 0, + Child, UpArrowWaitTimeTool2 = UpArrowObject, + Child, DownArrowWaitTimeTool2 = DownArrowObject, + End, //VGroup + End, //HGroup + + Child, Label1(GetLocString(MSGID_TOOL_SECONDS)), + End, //HGroup + +//************************************************************************************************************************************************* + + End, //ColGroup + End, //VGroup + + End, //RegisterObject + + Child, GroupTool = RegisterObject, + MUIA_Register_Titles, ToolRegisterTitleStrings, + MUIA_CycleChain, TRUE, + MUIA_ShowMe, WBTOOL == IconType, + + Child, VGroup, + GroupFrame, + Child, ColGroup(2), + Child, Label1S(GetLocString(MSGID_VERSION)), + Child, ConstantFloatText(GetVersionString(IconName)), + + Child, Label1S(GetLocString(MSGID_LASTCHANGE)), + Child, ConstantText(GetChangeDate(FibValid, ScalosExamineGetDate(fib))), + + Child, Label1S(GetLocString(MSGID_SIZE)), + Child, ConstantText(GetSizeString()), + + Child, Label1S(GetLocString(MSGID_PROTECTION)), + Child, VGroup, + Child, VSpace(0), + Child, HGroup, + GroupFrame, + Child, HSpace(0), + + Child, ColGroup(2 * 4), + MUIA_Disabled, !FibValid || !IsWriteable, + + Child, Label1(GetLocString(MSGID_PROTECTION_HIDDEN)), + Child, CheckMarkProtectionHideTool = CheckMarkHelp((Protection & FIBF_HIDDEN), MSGID_PROTECTION_HIDDEN_SHORTHELP), + + + Child, Label1(GetLocString(MSGID_PROTECTION_READ)), + Child, CheckMarkProtectionReadTool = CheckMarkHelp(!(Protection & FIBF_READ), MSGID_PROTECTION_READ_SHORTHELP), + + Child, Label1(GetLocString(MSGID_PROTECTION_WRITE)), + Child, CheckMarkProtectionWriteTool = CheckMarkHelp(!(Protection & FIBF_WRITE), MSGID_PROTECTION_WRITE_SHORTHELP), + + Child, Label1(GetLocString(MSGID_PROTECTION_ARCHIVE)), + Child, CheckMarkProtectionArchiveTool = CheckMarkHelp(Protection & FIBF_ARCHIVE, MSGID_PROTECTION_ARCHIVE_SHORTHELP), + + Child, Label1(GetLocString(MSGID_PROTECTION_DELETE)), + Child, CheckMarkProtectionDeleteTool = CheckMarkHelp(!(Protection & FIBF_DELETE), MSGID_PROTECTION_DELETE_SHORTHELP), + + Child, Label1(GetLocString(MSGID_PROTECTION_PURE)), + Child, CheckMarkProtectionPureTool = CheckMarkHelp((Protection & FIBF_PURE), MSGID_PROTECTION_PURE_SHORTHELP), + + + Child, Label1(GetLocString(MSGID_PROTECTION_EXECUTE)), + Child, CheckMarkProtectionExecuteTool = CheckMarkHelp(!(Protection & FIBF_EXECUTE), MSGID_PROTECTION_EXECUTE_SHORTHELP), + + Child, Label1(GetLocString(MSGID_PROTECTION_SCRIPT)), + Child, CheckMarkProtectionScriptTool = CheckMarkHelp(Protection & FIBF_SCRIPT, MSGID_PROTECTION_SCRIPT_SHORTHELP), + End, //ColGroup + + Child, HSpace(0), + End, //HGroup + Child, VSpace(0), + End, //VGroup + + Child, Label1S(GetLocString(MSGID_COMMENT)), + Child, StringCommentTool = StringObject, + StringFrame, + StringBack, + MUIA_String_Contents, (ULONG) Comment, + MUIA_CycleChain, TRUE, + MUIA_Dropable, TRUE, + End, //TextObject + End, //ColGroup + End, //VGroup + + Child, VGroup, + GroupFrame, + + Child, GroupIconTool = ColGroup(2), + + + Child, Label1S(GetLocString(MSGID_STACKSIZE)), + Child, HGroup, + Child, HGroup, + MUIA_Group_HorizSpacing, 0, + Child, StringStackSizeTool = StringObject, + StringFrame, + StringBack, + MUIA_String_Integer, GetStackSize(iconObjFromDisk), + MUIA_String_Accept, "0123456789", + MUIA_CycleChain, TRUE, + End, //StringObject + Child, VGroup, + MUIA_Group_VertSpacing, 0, + Child, UpArrowStackSizeTool = UpArrowObject, + Child, DownArrowStackSizeTool = DownArrowObject, + End, //VGroup + End, //HGroup + + Child, Label1(GetLocString(MSGID_TOOL_PRIORITY)), + Child, SliderToolPriTool = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Min, -128, + MUIA_Numeric_Max, 127, + MUIA_Numeric_Value, ToolPri, + End, //SliderObject + End, //HGroup + + Child, Label1S(GetLocString(MSGID_START_FROM)), + Child, HGroup, + Child, CycleStartFromTool = CycleObject, + MUIA_Cycle_Entries, StartFromCycleChoices, + MUIA_Cycle_Active, StartFrom, + MUIA_CycleChain, TRUE, + End, //CycleObject + + Child, Label1(GetLocString(MSGID_PROMPT_FOR_INPUT)), + Child, ButtonPromptForInputTool = ImageObject, + ButtonFrame, + MUIA_InputMode, MUIV_InputMode_Toggle, + MUIA_Image_Spec, MUII_CheckMark, + MUIA_Selected, PromptForInput, + MUIA_Background, MUII_ButtonBack, + MUIA_ShowSelState, FALSE, + End, //Image + End, //HGroup + + Child, VGroup, + Child, VSpace(0), + Child, Label1(GetLocString(MSGID_TOOLTYPES)), + Child, VSpace(0), + End, //VGroup + + Child, HGroup, + Child, TextEditorToolTypesTool = TextEditorObject, + TextFrame, + MUIA_Background, MUII_TextBack, + MUIA_CycleChain, TRUE, + //MUIA_Textinput_Multiline, TRUE, + MUIA_Dropable, TRUE, + End, //TextEditorObject + Child, ScrollBarToolTypesTool = ScrollbarObject, + MUIA_Background, MUII_PropBack, + SliderFrame, + End, //ScrollbarObject + End, //HGroup + + // the following members are only used for icons located in WBStartup + // for all other directories, those members will be removed later + Child, LabelStartPriTool = Label1S(GetLocString(MSGID_STARTPRI)), + Child, SliderStartPriTool = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Min, -128, + MUIA_Numeric_Max, 127, + MUIA_Numeric_Value, StartPri, + End, //SliderObject + + Child, LabelWaitUntilFinishedTool = Label1S(GetLocString(MSGID_WAITUNTILFINISHED)), + Child, GroupWaitUntilFinished = HGroup, + Child, CheckMarkWaitUntilFinishedTool = CheckMarkHelp(WaitUntilFinished, MSGID_WAITUNTILFINISHED_SHORTHELP), + + Child, GroupWaitTimeTool = HGroup, + MUIA_Group_HorizSpacing, 0, + MUIA_Disabled, !WaitUntilFinished, + + Child, StringWaitTimeTool = StringObject, + StringFrame, + StringBack, + MUIA_String_Integer, WaitTime, + MUIA_String_Accept, "0123456789", + MUIA_CycleChain, TRUE, + End, //StringObject + Child, VGroup, + MUIA_Group_VertSpacing, 0, + Child, UpArrowWaitTimeTool = UpArrowObject, + Child, DownArrowWaitTimeTool = DownArrowObject, + End, //VGroup + End, //HGroup + + Child, Label1(GetLocString(MSGID_TOOL_SECONDS)), + End, //HGroup + End, //ColGroup + End, //VGroup + + End, //RegisterObject + End, //VGroup + End, //HGroup + +// + Child, VSpace(0), + + Child, Group_Buttons2 = HGroup, + MUIA_Group_SameWidth, TRUE, + Child, OkButton = KeyButtonHelp(GetLocString(MSGID_OKBUTTON), + 'o', GetLocString(MSGID_SHORTHELP_OKBUTTON)), + Child, CancelButton = KeyButtonHelp(GetLocString(MSGID_CANCELBUTTON), + 'c', GetLocString(MSGID_SHORTHELP_CANCELBUTTON)), + End, //HGroup + End, //VGroup + End, //WindowObject + + MUIA_Application_Menustrip, MenustripObject, + Child, MenuObjectT(GetLocString(MSGID_MENU_PROJECT)), + + Child, MenuAbout = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUT), + End, + Child, MenuAboutMUI = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUTMUI), + End, + Child, MenuitemObject, + MUIA_Menuitem_Title, -1, + End, + Child, MenuQuit = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_QUIT), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_PROJECT_QUIT_SHORT), + End, + + End, //MenuObjectT + + Child, MenuObjectT(GetLocString(MSGID_MENU_TYPE)), + + Child, MenuTypeDisk = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_TYPE_DISK), + MUIA_Menuitem_Shortcut, "1", + MUIA_Menuitem_Checkit, TRUE, + MUIA_Menuitem_Exclude, 0x1e, + End, + Child, MenuTypeDrawer = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_TYPE_DRAWER), + MUIA_Menuitem_Shortcut, "2", + MUIA_Menuitem_Checkit, TRUE, + MUIA_Menuitem_Exclude, 0x1d, + End, + Child, MenuTypeProject = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_TYPE_PROJECT), + MUIA_Menuitem_Shortcut, "3", + MUIA_Menuitem_Checkit, TRUE, + MUIA_Menuitem_Exclude, 0x1b, + End, + Child, MenuTypeTool = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_TYPE_TOOL), + MUIA_Menuitem_Shortcut, "4", + MUIA_Menuitem_Checkit, TRUE, + MUIA_Menuitem_Exclude, 0x17, + End, + Child, MenuTypeTrashcan = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_TYPE_TRASHCAN), + MUIA_Menuitem_Shortcut, "5", + MUIA_Menuitem_Checkit, TRUE, + MUIA_Menuitem_Exclude, 0x0f, + End, + End, //MenuObjectT + + Child, MenuObjectT(GetLocString(MSGID_MENU_IMAGE)), + + Child, MenuImageDefault = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_IMAGE_DEFAULT), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_IMAGE_DEFAULT_SHORT), + End, + End, //MenuObjectT + +//--- +jmc+ -------------------------------------------------------------------------------------------------------------- + + Child, MenuObjectT(GetLocString(MSGID_MENU_OPTIONS)), + Child, MenuIconPath = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_ALWAYS_ICONPATH), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_ALWAYS_ICONPATH_SHORT), + MUIA_Menuitem_Checkit, TRUE, + MUIA_Menuitem_Toggle, TRUE, + // MUIA_Menuitem_Enabled, (WBDISK != IconType), + End, + Child, MenuGetSize = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_ALWAYS_GETSIZE), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_ALWAYS_GETSIZE_SHORT), + MUIA_Menuitem_Checkit, TRUE, + MUIA_Menuitem_Toggle, TRUE, + MUIA_Menuitem_Enabled, (WBDRAWER == IconType) || (WBGARBAGE == IconType), + End, + End, //MenuObjectT + +//------------------------------------------------------------------------------------------------------------------------ + + End, //MenuStripObject + + End; //ApplicationObject + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + if (NULL == APP_Main) + { + fail(APP_Main, GetLocString(MSGID_CREATE_APPLICATION_FAILED)); + } + + SetGuiFromIconType(iconObjFromDisk); + + //--------------------------------------------------------------------------// + + // Connect TextEditor objects with their scrollbars + + set(TextEditorToolTypesProject, MUIA_TextEditor_Slider, ScrollBarToolTypesProject); + set(TextEditorToolTypesTool, MUIA_TextEditor_Slider, ScrollBarToolTypesTool); + set(TextEditorToolTypesDrawer, MUIA_TextEditor_Slider, ScrollBarToolTypesDrawer); + set(TextEditorToolTypesDevice, MUIA_TextEditor_Slider, ScrollBarToolTypesDevice); + + //--------------------------------------------------------------------------// + + // connect UpArrow and DownArrow with the corresponding string Gadgets + + DoMethod(UpArrowWaitTimeTool, MUIM_Notify, MUIA_Timer, MUIV_EveryTime, + StringWaitTimeTool, 2, MUIM_CallHook, &StringIntegerIncrementHook); + DoMethod(DownArrowWaitTimeTool, MUIM_Notify, MUIA_Timer, MUIV_EveryTime, + StringWaitTimeTool, 2, MUIM_CallHook, &StringIntegerDecrementHook); + + DoMethod(UpArrowWaitTimeTool2, MUIM_Notify, MUIA_Timer, MUIV_EveryTime, + StringWaitTimeTool2, 2, MUIM_CallHook, &StringIntegerIncrementHook); + DoMethod(DownArrowWaitTimeTool2, MUIM_Notify, MUIA_Timer, MUIV_EveryTime, + StringWaitTimeTool2, 2, MUIM_CallHook, &StringIntegerDecrementHook); + + DoMethod(UpArrowStackSizeProject, MUIM_Notify, MUIA_Timer, MUIV_EveryTime, + StringStackSizeProject, 2, MUIM_CallHook, &StringIntegerIncrementHook); + DoMethod(DownArrowStackSizeProject, MUIM_Notify, MUIA_Timer, MUIV_EveryTime, + StringStackSizeProject, 2, MUIM_CallHook, &StringIntegerDecrementHook); + + DoMethod(UpArrowStackSizeTool, MUIM_Notify, MUIA_Timer, MUIV_EveryTime, + StringStackSizeTool, 2, MUIM_CallHook, &StringIntegerIncrementHook); + DoMethod(DownArrowStackSizeTool, MUIM_Notify, MUIA_Timer, MUIV_EveryTime, + StringStackSizeTool, 2, MUIM_CallHook, &StringIntegerDecrementHook); + + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + WIN_Main, 3, MUIM_Set, MUIA_Window_Open, FALSE); + + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + WIN_Main, 3 , MUIM_WriteLong, RESULT_HALT, &Result); + + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + DoMethod(CancelButton, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 3 , MUIM_WriteLong, RESULT_HALT, &Result); + + DoMethod(CancelButton, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + DoMethod(OkButton, MUIM_Notify,MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_Application_ReturnID, Application_Return_Ok); + + DoMethod(MenuAbout, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &AboutHook); + DoMethod(MenuAboutMUI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &AboutMUIHook); + DoMethod(MenuQuit, MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + // Call IconifyHook every time we get iconified or uniconified + DoMethod(APP_Main, MUIM_Notify, MUIA_Application_Iconified, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &IconifyHook); + + // Get drawer or disk size. + // Call getsize's hook when buttons are selected. + DoMethod(ButtonDrawerSize, MUIM_Notify, MUIA_Selected, TRUE, + APP_Main, 2, MUIM_CallHook, &DrawerSizeHook); + + DoMethod(ButtonDiskSize, MUIM_Notify, MUIA_Selected, TRUE, + APP_Main, 2, MUIM_CallHook, &DrawerSizeHook); + + // +jmc+ -------------------------------------------------------------------// + + // Set up a notification checking buttons state everytime. + // Unselected = RESULT_HALT / Selected = RETURN_OK. + DoMethod(ButtonDiskSize, MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + ButtonDiskSize, 3, MUIM_CallHook, &SelectFromButtonHook); + + DoMethod(ButtonDrawerSize, MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + ButtonDrawerSize, 3, MUIM_CallHook, &SelectFromButtonHook); + + //--- +jmc+ : variables menu's options ----------------------------------- + // Menu options methods - Icon path. + DoMethod(MenuIconPath, MUIM_Notify, MUIA_Menuitem_Checked, MUIV_EveryTime, + APP_Main, 3, MUIM_WriteLong, MUIV_TriggerValue, &ShowIconPath); + + DoMethod(MenuIconPath, MUIM_Notify, MUIA_Menuitem_Checked, MUIV_EveryTime, + APP_Main, 2, MUIM_Application_ReturnID, Application_Return_Path); + + // Menu options methods - Auto GetSize. + DoMethod(MenuGetSize, MUIM_Notify, MUIA_Menuitem_Checked, MUIV_EveryTime, + APP_Main, 3, MUIM_WriteLong, MUIV_TriggerValue, &AutoGetSize); + + //--------------------------------------------------------------------------// + + // Setup notification when icon type is changed via menu + DoMethod(MenuTypeDisk, MUIM_Notify, MUIA_Menuitem_Checked, TRUE, + APP_Main, 3, MUIM_CallHook, &ChangeIconTypeHook, WBDISK); + DoMethod(MenuTypeDrawer, MUIM_Notify, MUIA_Menuitem_Checked, TRUE, + APP_Main, 3, MUIM_CallHook, &ChangeIconTypeHook, WBDRAWER); + DoMethod(MenuTypeProject, MUIM_Notify, MUIA_Menuitem_Checked, TRUE, + APP_Main, 3, MUIM_CallHook, &ChangeIconTypeHook, WBPROJECT); + DoMethod(MenuTypeTool, MUIM_Notify, MUIA_Menuitem_Checked, TRUE, + APP_Main, 3, MUIM_CallHook, &ChangeIconTypeHook, WBTOOL); + DoMethod(MenuTypeTrashcan, MUIM_Notify, MUIA_Menuitem_Checked, TRUE, + APP_Main, 3, MUIM_CallHook, &ChangeIconTypeHook, WBGARBAGE); + + // call hook when menu command "icon image/default" is issued + DoMethod(MenuImageDefault, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &DefaultIconHook); + + // enable/disable the ButtonPromptForInput****, + // according to state of CycleStartFrom**** + DoMethod(CycleStartFromProject, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, + CycleStartFromProject, 2, MUIM_CallHook, &StartFromCycleHook); + DoMethod(CycleStartFromTool, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, + CycleStartFromTool, 2, MUIM_CallHook, &StartFromCycleHook); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + // disable Ok button for read-only icons + set(OkButton, MUIA_Disabled, !IsWriteable); + + //-- +jmc+ : Variables options ---------------------------------------------------- + + // Check on or off Menuitem to always display icon path gadget. + set(MenuIconPath,MUIA_Menuitem_Checked, ShowIconPath); + + // Check on or off Menuitem to always display icon path gadget. + set(MenuGetSize, MUIA_Menuitem_Checked, AutoGetSize); + + //------------------------------------------------------------------------ + + d1(KPrintF(__FILE__ "/%s/%ld: PathName lenght = %ld\n", __FUNC__, __LINE__, strlen(PathName))); + + // disable all input gadgets for read-only icons + set(StringCommentDevice, MUIA_Disabled, !IsWriteable); + set(StringCommentDrawer, MUIA_Disabled, !IsWriteable); + set(StringCommentProject, MUIA_Disabled, !IsWriteable); + set(StringCommentTool, MUIA_Disabled, !IsWriteable); + set(StringName, MUIA_Disabled, !IsWriteable); + set(TextEditorToolTypesDevice, MUIA_Disabled, !IsWriteable); + set(TextEditorToolTypesDrawer, MUIA_Disabled, !IsWriteable); + set(TextEditorToolTypesProject, MUIA_Disabled, !IsWriteable); + set(TextEditorToolTypesTool, MUIA_Disabled, !IsWriteable); + set(StringStackSizeProject, MUIA_Disabled, !IsWriteable); + set(StringStackSizeTool, MUIA_Disabled, !IsWriteable); + set(PopAslDefaultTool, MUIA_Disabled, !IsWriteable); + set(SliderToolPriProject, MUIA_Disabled, !IsWriteable); + set(SliderToolPriTool, MUIA_Disabled, !IsWriteable); + set(CycleStartFromProject, MUIA_Disabled, !IsWriteable); + set(CycleStartFromTool, MUIA_Disabled, !IsWriteable); + set(ButtonPromptForInputProject, MUIA_Disabled, + !IsWriteable || (STARTFROM_CLI != StartFrom && STARTFROM_Arexx != StartFrom)); + set(ButtonPromptForInputTool, MUIA_Disabled, + !IsWriteable || (STARTFROM_CLI != StartFrom && STARTFROM_Arexx != StartFrom)); + + //--------------------------------------------------------------------------// + + if (IsWBStartup) + { + // disable GroupWaitTimeTool if "Wait until finished" is turned off + DoMethod(CheckMarkWaitUntilFinishedTool, MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + GroupWaitTimeTool, 3, MUIM_Set, MUIA_Disabled, MUIV_NotTriggerValue); + + DoMethod(CheckMarkWaitUntilFinishedTool2, MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + GroupWaitTimeTool2, 3, MUIM_Set, MUIA_Disabled, MUIV_NotTriggerValue); + + } + else + { + // show WBStartup parameters only for objects located in WBStartup + // for some reason, MUIA_ShowMe doesn't work in column groups, + // so I choose to remove the objects instead. + + DoMethod(GroupIconTool, MUIM_Group_InitChange); + DoMethod(GroupIconTool, OM_REMMEMBER, LabelStartPriTool); + DoMethod(GroupIconTool, OM_REMMEMBER, SliderStartPriTool); + DoMethod(GroupIconTool, OM_REMMEMBER, LabelWaitUntilFinishedTool); + DoMethod(GroupIconTool, OM_REMMEMBER, GroupWaitUntilFinished); + DoMethod(GroupIconTool, MUIM_Group_ExitChange); + + DoMethod(GroupIconProject, MUIM_Group_InitChange); + DoMethod(GroupIconProject, OM_REMMEMBER, LabelStartPriTool2); + DoMethod(GroupIconProject, OM_REMMEMBER, SliderStartPriTool2); + DoMethod(GroupIconProject, OM_REMMEMBER, LabelWaitUntilFinishedTool2); + DoMethod(GroupIconProject, OM_REMMEMBER, GroupWaitUntilFinished2); + DoMethod(GroupIconProject, MUIM_Group_ExitChange); + + // since those objects are no longer childs of anything, + // we need to dispose of them ourselves + MUI_DisposeObject(LabelStartPriTool); + MUI_DisposeObject(LabelStartPriTool2); + + MUI_DisposeObject(SliderStartPriTool); + MUI_DisposeObject(SliderStartPriTool2); + + MUI_DisposeObject(LabelWaitUntilFinishedTool); + MUI_DisposeObject(LabelWaitUntilFinishedTool2); + + MUI_DisposeObject(GroupWaitUntilFinished); + MUI_DisposeObject(GroupWaitUntilFinished2); + + LabelStartPriTool = NULL; + LabelStartPriTool2 = NULL; + + SliderStartPriTool = NULL; + SliderStartPriTool2 = NULL; + + LabelWaitUntilFinishedTool = NULL; + LabelWaitUntilFinishedTool2 = NULL; + + GroupWaitUntilFinished = NULL; + GroupWaitUntilFinished2 = NULL; + + CheckMarkWaitUntilFinishedTool = NULL; + CheckMarkWaitUntilFinishedTool2 = NULL; + + StringWaitTimeTool = NULL; + StringWaitTimeTool2 = NULL; + + GroupWaitTimeTool = NULL; + GroupWaitTimeTool2 = NULL; + } + + //--------------------------------------------------------------------------// + + set(WIN_Main, MUIA_Window_Open, TRUE); + get(WIN_Main, MUIA_Window_Open, &win_opened); + + if (win_opened) + { + ULONG sigs = 0; + BOOL Run = TRUE; + struct Window *MainWin = NULL; + ULONG AppMsgSignal; + ULONG DropZoneMsgSignal; + char VarBuffer[3]; + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + //-- +jmc+ ------------------------------------------------------------------------------------ + // Only start size calculation at startup if the icon isn't WBDISK type, because getsize gadget + // is used for drawers and disks(ButtonSize = ButtonDrawerSize or ButtonSize = ButtonDiskSize) + // from DrawerSizeHookFunc() hook. + + if ((WBDRAWER == IconType) || (WBGARBAGE == IconType)) + set(ButtonDrawerSize, MUIA_Selected, AutoGetSize); + + //--------------------------------------------------------------------------------------------- + + get(WIN_Main, MUIA_Window_Window, &MainWin); + + myAppWindow = AddAppWindowA(0, 0, + MainWin, AppMsgPort, NULL); + + AppMsgSignal = 1 << AppMsgPort->mp_SigBit; + DropZoneMsgSignal = 1 << DropZoneMsgPort->mp_SigBit; + + AddDropZoneForObject(MccIconObj, HandleDropOnIcon); + AddDropZoneForObject(StringName, HandleDropOnName); + AddDropZoneForObject(PopAslDefaultTool, HandleDropOnString); + AddDropZoneForObject(StringCommentDrawer, HandleDropOnString); + AddDropZoneForObject(StringCommentProject, HandleDropOnString); + AddDropZoneForObject(StringCommentTool, HandleDropOnString); + AddDropZoneForObject(StringCommentDevice, HandleDropOnString); + AddDropZoneForObject(TextEditorToolTypesDrawer, HandleDropOnToolTypes); + AddDropZoneForObject(TextEditorToolTypesProject, HandleDropOnToolTypes); + AddDropZoneForObject(TextEditorToolTypesDevice, HandleDropOnToolTypes); + AddDropZoneForObject(TextEditorToolTypesTool, HandleDropOnToolTypes); + + d1(KPrintF(__FILE__ "/%s/%ld: Application_Return_Ok(%ld) MUIV_Application_ReturnID_Quit(%ld)\n", + __FUNC__, __LINE__, Application_Return_Ok, MUIV_Application_ReturnID_Quit)); + + + while (Run) + { + ULONG Action = DoMethod(APP_Main, MUIM_Application_NewInput, &sigs); + + d1(KPrintF(__FILE__ "/%s/%ld: Action=%ld\n", __FUNC__, __LINE__, Action)); + + switch (Action) + { + case Application_Return_Ok: + SaveSettings(iconObjFromDisk, backupIconObjFromDisk, IconName); + Run = FALSE; + break; + + case Application_Return_Path: + if(strlen(PathName) > 0) + set(Group_Virtual, MUIA_ShowMe, ShowIconPath); + d1(KPrintF(__FILE__ "/%s/%ld: strlen(PathName)=%ld ShowIconPath=%ld\n", __FUNC__, __LINE__, strlen(PathName), ShowIconPath)); + break; + + case MUIV_Application_ReturnID_Quit: + //---- Show icon path gadget -------------------------------------------------------------------------------------- + get(MenuIconPath, MUIA_Menuitem_Checked, &ShowIconPath); + sprintf(VarBuffer, "%ld", (long) ShowIconPath); + SetVar(INFO_ICONPATH_ENV, VarBuffer, -1, GVF_GLOBAL_ONLY); + SetVar(INFO_ICONPATH_ENVARC, VarBuffer, -1, GVF_GLOBAL_ONLY); + + d1(KPrintF(__FILE__ "/%s/%ld: ShowIconPath=%ld VarBuffer=<%s>\nINFO_ICONPATH_ENV=<%s>\nINFO_ICONPATH_ENVARC=<%s>\n", + __FUNC__, __LINE__, ShowIconPath, VarBuffer, INFO_ICONPATH_ENV, INFO_ICONPATH_ENVARC)); + + //---- Auto GetSize calculation at startup ------------------------------------------------------------------------- + + get(MenuGetSize, MUIA_Menuitem_Checked, &AutoGetSize); + sprintf(VarBuffer, "%ld", (long) AutoGetSize); + SetVar(INFO_AUTOGETSIZE_ENV, VarBuffer, -1, GVF_GLOBAL_ONLY); + SetVar(INFO_AUTOGETSIZE_ENVARC, VarBuffer, -1, GVF_GLOBAL_ONLY); + + d1(KPrintF(__FILE__ "/%s/%ld: AutoGetSize=%ld VarBuffer=<%s>\nINFO_AUTOGETSIZE_ENV=<%s>\nINFO_AUTOGETSIZE_ENVARC=<%s>\n", + __FUNC__, __LINE__, AutoGetSize, VarBuffer, INFO_AUTOGETSIZE_ENV, INFO_AUTOGETSIZE_ENVARC)); + + Run = FALSE; + break; + } + + if (Run && sigs) + { + AdjustDropZones(); + + sigs = Wait(sigs | AppMsgSignal | DropZoneMsgSignal | SIGBREAKF_CTRL_C); + + if (sigs & SIGBREAKF_CTRL_C) + { + Run = FALSE; + } + if (sigs & AppMsgSignal) + { + struct AppMessage *AppMsg; + + while ((AppMsg = (struct AppMessage *) GetMsg(AppMsgPort))) + { + HandleAppMessage(AppMsg, &dii); + ReplyMsg(&AppMsg->am_Message); + } + } + if (sigs & DropZoneMsgSignal) + { + struct DropZoneMsg *dzm; + + d1(KPrintF(__FILE__ "/%s/%ld: sigs=%08lx\n", __FUNC__, __LINE__, sigs)); + + while ((dzm = (struct DropZoneMsg *) GetMsg(DropZoneMsgPort))) + { + d1(KPrintF(__FILE__ "/%s/%ld: dzm=%08lx\n", __FUNC__, __LINE__, dzm)); + DropZoneMsgHandler(dzm); + d1(KPrintF(__FILE__ "/%s/%ld: dzm=%08lx\n", __FUNC__, __LINE__, dzm)); + //free(dzm); + ReplyMsg(&dzm->dzm_Msg); + } + } + } + } + } + else + { + printf(GetLocString(MSGID_CREATE_MAINWINDOW_FAILED)); + } + + if (myAppWindow) + { + RemoveAppWindow(myAppWindow); + myAppWindow = NULL; + } + set(WIN_Main, MUIA_Window_Open, FALSE); + } + + if (backupIconObjFromDisk) + DisposeIconObject(backupIconObjFromDisk); + if (iconObjFromDisk) + DisposeIconObject(iconObjFromDisk); + if (iconObjFromScalos) + DisposeIconObject(iconObjFromScalos); + if (oldDir) + CurrentDir(oldDir); + + fail(APP_Main, NULL); + + return 0; +} + + +static VOID fail(APTR APP_Main, CONST_STRPTR str) +{ + Cleanup(); + + if (str) + { + puts(str); + exit(20); + } + + exit(0); +} + + +static void init(void) +{ + STRPTR LibName; + + NewList(&DropZoneList); + + if (!OpenLibraries(&LibName)) + { + char FailText[256]; + + sprintf(FailText, GetLocString(MSGID_OPEN_LIBRARY_FAILED), LibName); + fail(NULL, FailText); + } + + if (LocaleBase) + { + InformationLocale = OpenLocale(NULL); + InformationCatalog = OpenCatalogA(NULL, "Scalos/Information.catalog", NULL); + } + + AppMsgPort = CreateMsgPort(); + if (NULL == AppMsgPort) + { + fail(NULL, ""); + } + + IconobjectClass = InitIconobjectClass(); + + ReadScalosPrefs(); +} + + +static void Cleanup(void) +{ + if (APP_Main) + { + MUI_DisposeObject(APP_Main); + } + if (IconobjectClass) + { + CleanupIconobjectClass(IconobjectClass); + IconobjectClass = NULL; + } + if (InformationCatalog) + { + CloseCatalog(InformationCatalog); + InformationCatalog = NULL; + } + + if (AppMsgPort) + { + struct Message *msg; + + Forbid(); + while ((msg = GetMsg(AppMsgPort))) + ReplyMsg(msg); + + DeleteMsgPort(AppMsgPort); + Permit(); + + AppMsgPort = NULL; + } + if (DropZoneMsgPort) + { + struct Message *msg; + + Forbid(); + while ((msg = GetMsg(DropZoneMsgPort))) + free(msg); + + DeleteMsgPort(DropZoneMsgPort); + Permit(); + + AppMsgPort = NULL; + } + + CloseLibraries(); +} + + +static BOOL OpenLibraries(STRPTR *LibName) +{ + *LibName = "intuition.library"; + IntuitionBase = (struct IntuitionBase *) OpenLibrary(*LibName, 39); + if (NULL == IntuitionBase) + return FALSE; +#ifdef __amigaos4__ + else + { + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + return FALSE; + } +#endif + + *LibName = MUIMASTER_NAME; + MUIMasterBase = OpenLibrary(*LibName, MUIMASTER_VMIN-1); + if (NULL == MUIMasterBase) + return FALSE; +#ifdef __amigaos4__ + else + { + IMUIMaster = (struct MUIMasterIFace *)GetInterface((struct Library *)MUIMasterBase, "main", 1, NULL); + if (NULL == IMUIMaster) + return FALSE; + } +#endif + + + *LibName = "icon.library"; + IconBase = OpenLibrary(*LibName, 0); + if (NULL == IconBase) + return FALSE; +#ifdef __amigaos4__ + else + { + IIcon = (struct IconIFace *)GetInterface((struct Library *)IconBase, "main", 1, NULL); + if (NULL == IIcon) + return FALSE; + } +#endif + + + *LibName = "scalos.library"; + ScalosBase = (struct ScalosBase *) OpenLibrary(*LibName, 40); + if (NULL == ScalosBase) + return FALSE; +#ifdef __amigaos4__ + else + { + IScalos = (struct ScalosIFace *)GetInterface((struct Library *)ScalosBase, "main", 1, NULL); + if (NULL == IScalos) + return FALSE; + } +#endif + + + *LibName = "preferences.library"; + PreferencesBase = OpenLibrary(*LibName, 39); + if (NULL == PreferencesBase) + return FALSE; +#ifdef __amigaos4__ + else + { + IPreferences = (struct PreferencesIFace *)GetInterface((struct Library *)PreferencesBase, "main", 1, NULL); + if (NULL == IPreferences) + return FALSE; + } +#endif + + + *LibName = "iconobject.library"; + IconobjectBase = OpenLibrary(*LibName, 0); + if (NULL == IconobjectBase) + return FALSE; +#ifdef __amigaos4__ + else + { + IIconobject = (struct IconobjectIFace *)GetInterface((struct Library *)IconobjectBase, "main", 1, NULL); + if (NULL == IIconobject) + return FALSE; + } +#endif + + + *LibName = "workbench.library"; + WorkbenchBase = OpenLibrary(*LibName, 39); + if (NULL == WorkbenchBase) + return FALSE; +#ifdef __amigaos4__ + else + { + IWorkbench = (struct WorkbenchIFace *)GetInterface((struct Library *)WorkbenchBase, "main", 1, NULL); + if (NULL == IWorkbench) + return FALSE; + } +#endif + + + LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 39); +#ifdef __amigaos4__ + if (NULL != LocaleBase) + ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL); +#endif + + *LibName = "timer.device"; + TimerPort = CreateMsgPort(); + if (NULL == TimerPort) + return FALSE; + TimerIO = (T_TIMEREQUEST *)CreateIORequest(TimerPort, sizeof(T_TIMEREQUEST)); + if (NULL == TimerIO) + return FALSE; + if (0 != OpenDevice("timer.device", UNIT_VBLANK, &TimerIO->tr_node, 0)) + return FALSE; + TimerBase = (T_TIMERBASE) TimerIO->tr_node.io_Device; + if (NULL == TimerBase) + return FALSE; +#ifdef __amigaos4__ + ITimer = (struct TimerIFace *)GetInterface((struct Library *)TimerBase, "main", 1, NULL); + if (NULL == ITimer) + return FALSE; +#endif + + if (!ScalosExamineBegin(&fib)) + return FALSE; + + return TRUE; +} + + +static void CloseLibraries(void) +{ +#ifdef __amigaos4__ + if (ITimer) + { + DropInterface((struct Interface *)ITimer); + ITimer = NULL; + } +#endif + if (TimerIO) + { + CloseDevice(&TimerIO->tr_node); + DeleteIORequest(&TimerIO->tr_node); + TimerIO = NULL; + } + if (TimerPort) + { + DeleteMsgPort(TimerPort); + TimerPort = NULL; + } + + ScalosExamineEnd(&fib); + if (LocaleBase) + { + if (InformationLocale) + { + CloseLocale(InformationLocale); + InformationLocale = NULL; + } + if (InformationCatalog) + { + CloseCatalog(InformationCatalog); + InformationCatalog = NULL; + } +#ifdef __amigaos4__ + if (ILocale) + { + DropInterface((struct Interface *)ILocale); + ILocale = NULL; + } +#endif + CloseLibrary((struct Library *) LocaleBase); + LocaleBase = NULL; + } +#ifdef __amigaos4__ + if (IIconobject) + { + DropInterface((struct Interface *)IIconobject); + IIconobject = NULL; + } +#endif + if (IconobjectBase) + { + CloseLibrary(IconobjectBase); + IconobjectBase = NULL; + } +#ifdef __amigaos4__ + if (IPreferences) + { + DropInterface((struct Interface *)IPreferences); + IPreferences = NULL; + } +#endif + if (PreferencesBase) + { + CloseLibrary(PreferencesBase); + PreferencesBase = NULL; + } +#ifdef __amigaos4__ + if (IScalos) + { + DropInterface((struct Interface *)IScalos); + IScalos = NULL; + } +#endif + if (ScalosBase) + { + CloseLibrary((struct Library *) ScalosBase); + ScalosBase = NULL; + } +#ifdef __amigaos4__ + if (IWorkbench) + { + DropInterface((struct Interface *)IWorkbench); + IWorkbench = NULL; + } +#endif + if (WorkbenchBase) + { + CloseLibrary(WorkbenchBase); + WorkbenchBase = NULL; + } +#ifdef __amigaos4__ + if (IIcon) + { + DropInterface((struct Interface *)IIcon); + IIcon = NULL; + } +#endif + if (IconBase) + { + CloseLibrary(IconBase); + IconBase = NULL; + } +#ifdef __amigaos4__ + if (IMUIMaster) + { + DropInterface((struct Interface *)IMUIMaster); + IMUIMaster = NULL; + } +#endif + if (MUIMasterBase) + { + CloseLibrary(MUIMasterBase); + MUIMasterBase = NULL; + } +#ifdef __amigaos4__ + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } +#endif + if (IntuitionBase) + { + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } +} + +//---------------------------------------------------------------------------- + +static CONST_STRPTR GetLocString(ULONG MsgId) +{ + struct Information_LocaleInfo li; + + li.li_Catalog = InformationCatalog; +#ifndef __amigaos4__ + li.li_LocaleBase = LocaleBase; +#else + li.li_ILocale = ILocale; +#endif + + return GetInformationString(&li, MsgId); +} + +static void TranslateStringArray(STRPTR *stringArray) +{ + while (*stringArray) + { + *stringArray = (STRPTR)GetLocString((ULONG) *stringArray); + stringArray++; + } +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT OpenAboutMUIHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + if (NULL == WIN_AboutMUI) + { + WIN_AboutMUI = MUI_NewObject(MUIC_Aboutmui, + MUIA_Window_RefWindow, WIN_Main, + MUIA_Aboutmui_Application, APP_Main, + TAG_END); + } + + if (WIN_AboutMUI) + set(WIN_AboutMUI, MUIA_Window_Open, TRUE); + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT OpenAboutHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + MUI_Request(APP_Main, WIN_Main, 0, NULL, + (STRPTR)GetLocString(MSGID_ABOUTREQOK), + (STRPTR)GetLocString(MSGID_ABOUTREQFORMAT), + VERSION_MAJOR, VERSION_MINOR, COMPILER_STRING, CURRENTYEAR); +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT DrawerSizeHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + ULONG FileCount, DrawersCount, BlocksCount; + ULONG64 ByteCount; + struct WBArg *arg = (struct WBArg *) hook->h_Data; + BPTR OldDir; + Object *ButtonSize; + T_TIMEVAL lastUpdateTime; + + FileCount = DrawersCount = 0; + ByteCount = MakeU64(0); + BlocksCount = 1; + Result = RETURN_OK; + + d1(KPrintF(__FILE__ "/%s/%ld: arg=%08lx wa_Lock=%08lx wa_Name=<%s>\n", __FUNC__, __LINE__, arg, arg->wa_Lock, arg->wa_Name)); + + GetSysTime(&lastUpdateTime); + + OldDir = CurrentDir(arg->wa_Lock); + + if (IsDevice(arg)) + { + ButtonSize = ButtonDiskSize; + stccpy(InitButtonSize, TextDeviceUsed, sizeof(InitButtonSize)); // +jmc+ + + d1(KPrintF(__FILE__ "/%s/%ld: ButtonDiskSize=<%s>\n", __FUNC__, __LINE__, InitButtonSize)); + + ExamineDrawer(ButtonSize, ":", &FileCount, &DrawersCount, &BlocksCount, &ByteCount, &lastUpdateTime); + } + else + { + ButtonSize = ButtonDrawerSize; + stccpy(InitButtonSize, GetLocString(MSGID_INITIAL_DRAWER_SIZE), sizeof(InitButtonSize)); // +jmc+ + + d1(KPrintF(__FILE__ "/%s/%ld: ButtonDiskSize=<%s>\n", __FUNC__, __LINE__, InitButtonSize)); + + ExamineDrawer(ButtonSize, arg->wa_Name, &FileCount, &DrawersCount, &BlocksCount, &ByteCount, &lastUpdateTime); + } + + CurrentDir(OldDir); + + if (RESULT_HALT == Result) // +jmc+ + { + set(ButtonSize, MUIA_Text_Contents, (ULONG) InitButtonSize); // +jmc+ + } + else + { + UpdateDrawerSize(ButtonSize, &FileCount, &DrawersCount, &BlocksCount, &ByteCount); + set(ButtonSize, MUIA_Selected, FALSE); // +jmc+ + } + + d1(KPrintF(__FILE__ "/%s/%ld: RESULT = [%ld] InitButtonSize <%s>\n", __FUNC__, __LINE__, Result, InitButtonSize)); +} + +//---------------------------------------------------------------------------- + +static void UpdateDrawerSize(Object *ButtonSize, ULONG *FileCount, + ULONG *DrawersCount, ULONG *BlocksCount, ULONG64 *ByteCount) +{ + char ByteCountText[40]; + char SizeText[256]; + + Convert64(InformationLocale, *ByteCount, ByteCountText, sizeof(ByteCountText)); + + ScaFormatString(GetLocString(MSGID_DRAWER_SIZE), + SizeText, sizeof(SizeText), 4, + ByteCountText, *FileCount, *DrawersCount, *BlocksCount); + set(ButtonSize, MUIA_Text_Contents, SizeText); +} + +//---------------------------------------------------------------------------- + +static LONG ExamineDrawer(Object *ButtonSize, CONST_STRPTR Name, ULONG *FileCount, + ULONG *DrawersCount, ULONG *BlocksCount, ULONG64 *ByteCount, T_TIMEVAL *lastUpdateTime) +{ + T_ExamineDirHandle edh; + BPTR dLock = (BPTR)NULL; + + DoMethod(APP_Main, MUIM_Application_InputBuffered); + + // do not update more often than every 100ms + if (GetElapsedTime(lastUpdateTime) > 100) + { + GetSysTime(lastUpdateTime); + UpdateDrawerSize(ButtonSize, FileCount, DrawersCount, BlocksCount, ByteCount); + } + + DoMethod(APP_Main, MUIM_Application_InputBuffered); + + do { + dLock = Lock(Name, ACCESS_READ); + if ((BPTR)NULL == dLock) + { + Result = IoErr(); + d1(KPrintF(__FILE__ "/%s/%ld: Result=%ld\n", __FUNC__, __LINE__, Result)); + break; + } + if (!ScalosExamineDirBegin(dLock, &edh)) + { + Result = IoErr(); + d1(KPrintF(__FILE__ "/%s/%ld: Result=%ld\n", __FUNC__, __LINE__, Result)); + break; + } + + do { + T_ExamineData *exd; + + DoMethod(APP_Main, MUIM_Application_InputBuffered); + + if (!ScalosExamineDir(dLock, &edh, &exd)) + { + Result = IoErr(); + d1(KPrintF(__FILE__ "/%s/%ld: Result=%ld\n", __FUNC__, __LINE__, Result)); + break; + } + + d1(KPrintF(__FILE__ "/%s/%ld: ScalosExamineDir() success - Name=<%s> DirEntryType=%ld\n", __FUNC__, __LINE__, \ + ScalosExamineGetName(exd), ScalosExamineGetDirEntryType(exd))); + + (*BlocksCount) += ScalosExamineGetBlockCount(exd); + + if (ScalosExamineIsDrawer(exd)) + { + BPTR OldDir = CurrentDir(dLock); + + (*DrawersCount)++; + d1(KPrintF(__FILE__ "/%s/%ld: Name=<%s>\n", __FUNC__, __LINE__, ScalosExamineGetName(exd))); + + Result = ExamineDrawer(ButtonSize, ScalosExamineGetName(exd), + FileCount, DrawersCount, BlocksCount, ByteCount, lastUpdateTime); + + CurrentDir(OldDir); + } + else + { + (*FileCount)++; + *ByteCount = Add64(*ByteCount, ScalosExamineGetSize(exd) ); + } + DoMethod(APP_Main, MUIM_Application_InputBuffered); + + // do not update more often than every 100ms + if (GetElapsedTime(lastUpdateTime) > 100) + { + GetSysTime(lastUpdateTime); + UpdateDrawerSize(ButtonSize, FileCount, + DrawersCount, BlocksCount, ByteCount); + } + + DoMethod(APP_Main, MUIM_Application_InputBuffered); + + } while (RETURN_OK == Result); + } while (0); + + if (ERROR_NO_MORE_ENTRIES == Result) + Result = RETURN_OK; + + ScalosExamineDirEnd(&edh); + if (dLock) + UnLock(dLock); + + d1(KPrintF(__FILE__ "/%s/%ld: Result=%ld InitButtonSize <%s>\n", __FUNC__, __LINE__, Result, InitButtonSize)); + + return Result; +} + +//---------------------------------------------------------------------------- + +// Get elapsed time since time in milliseconds. +static LONG GetElapsedTime(T_TIMEVAL *tv) +{ + T_TIMEVAL Now; + LONG Diff; + + GetSysTime(&Now); + SubTime(&Now, tv); + + Diff = 1000 * Now.tv_secs + Now.tv_micro / 1000; + + d1(kprintf("%s/%s/%ld: Now s=%ld ms=%ld Start s=%ld ms=%ld Diff=%ld\n", \ + __FILE__, __FUNC__, __LINE__, \ + Now.tv_secs, Now.tv_micro, \ + tv->tv_secs, tv->tv_micro, Diff)); + + return Diff; +} + +// +jmc+ ----------------------------------------------------------------------// + +static SAVEDS(LONG) INTERRUPT SelectFromButtonHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + LONG Sel = 0; + + get(o, MUIA_Selected, &Sel); + if(!Sel) + Result = RESULT_HALT; + else + Result = RETURN_OK; + + d1(KPrintF(__FILE__ "/%s/%ld: Result=[%ld] Sel=[%ld]\n", __FUNC__, __LINE__, Result, Sel)); + + return Result; +} + +//----------------------------------------------------------------------------// + +static SAVEDS(void) INTERRUPT IconifyHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + ULONG Iconified = 0, attr = 0; + struct DropZone *dz; + struct Window *MainWin = NULL; + + get(APP_Main, MUIA_Application_Iconified, &Iconified); + get(WIN_Main, MUIA_Window, &attr); + + d1(KPrintF("%s/%ld: Iconified=%ld MainWin=%08lx myAppWindow=%08lx\n", __FUNC__, __LINE__, Iconified, MainWin, myAppWindow)); + + if (!Iconified && MainWin && NULL == myAppWindow) + { + myAppWindow = AddAppWindowA(0, 0, MainWin, AppMsgPort, NULL); + } + + for (dz = (struct DropZone *) DropZoneList.lh_Head; + dz != (struct DropZone *) &DropZoneList.lh_Tail; + dz = (struct DropZone *) dz->dz_Node.ln_Succ) + { + if (Iconified) + { + d1(KPrintF("%s/%ld: dz_DropZone=%08lx\n", __FUNC__, __LINE__, dz->dz_DropZone)); + if (dz->dz_DropZone) + RemoveAppWindowDropZone(myAppWindow, dz->dz_DropZone); + } + else + { + struct MUI_AreaData *mad; + + mad = muiAreaData(dz->dz_Object); + + if (mad) + { + d1(KPrintF("%s/%ld: dz=%08lx Left=%ld Top=%ld Width=%ld Height=%ld\n", __FUNC__, __LINE__, dz, mad->mad_Box.Left, mad->mad_Box.Top, mad->mad_Box.Width, mad->mad_Box.Height)); + + dz->dz_Box = mad->mad_Box; + + if (mad->mad_Flags & MADF_OBJECTVISIBLE) + { + dz->dz_DropZone = AddAppWindowDropZone(myAppWindow, 0, + (ULONG) dz, + WBDZA_Hook, (ULONG) &AppWindowDropZoneHook, + WBDZA_Box, (ULONG) &dz->dz_Box, + TAG_END); + } + } + } + + } + + if (Iconified && myAppWindow) + { + RemoveAppWindow(myAppWindow); + myAppWindow = NULL; + } +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT DefaultIconHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct DefIconInfo *dii = (struct DefIconInfo *) hook->h_Data; + Object *NewIconObj; + + NewIconObj = SCA_GetDefIconObject(dii->dii_DirLock, dii->dii_IconName); + + if (NULL == NewIconObj) + { + IPTR IconType; + + GetAttr(IDTA_Type, *dii->dii_IconObjectFromDisk, &IconType); + NewIconObj = GetDefIconObject(IconType, NULL); + } + if (NewIconObj) + ReplaceIcon(NewIconObj, dii->dii_IconObjectFromDisk); +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT StringIntegerIncrementHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + LONG Value = 0; + + get(o, MUIA_String_Integer, &Value); + set(o, MUIA_String_Integer, Value + 1); +} + + +static SAVEDS(void) INTERRUPT StringIntegerDecrementHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + LONG Value = 0; + + get(o, MUIA_String_Integer, &Value); + set(o, MUIA_String_Integer, Value - 1); +} + +//---------------------------------------------------------------------------- + +static void HandleAppMessage(struct AppMessage *AppMsg, struct DefIconInfo *dii) +{ + struct DropZone *dz = (struct DropZone *) AppMsg->am_UserData; + ULONG Disabled = 0; + + d1(KPrintF(__FILE__ "/%s/%ld: AppMsg=%08lx am_NumArgs=%ld am_Type=%ld\n", __FUNC__, __LINE__, AppMsg, AppMsg->am_NumArgs, AppMsg->am_Type)); + + switch (AppMsg->am_Type) + { + case AMTYPE_APPWINDOW: + d1(KPrintF("%s/%ld: AMTYPE_APPWINDOW\n", __FUNC__, __LINE__)); + if (IsListEmpty(&DropZoneList)) + { + if (AppMsg->am_NumArgs >= 1) + HandleDropOnIcon(&AppMsg->am_ArgList[0], MccIconObj, dii); + } + break; + + case AMTYPE_APPWINDOWZONE: + d1(KPrintF("%s/%ld: AMTYPE_APPWINDOWZONE\n", __FUNC__, __LINE__)); + get(dz->dz_Object, MUIA_Disabled, &Disabled); + DoMethod(dz->dz_Object, MUIM_DragFinish, NULL); + + if (!Disabled && AppMsg->am_NumArgs >= 1 && dz->dz_Handler) + { + dz->dz_Handler(&AppMsg->am_ArgList[0], dz->dz_Object, dii); + } + break; + } +} + +//---------------------------------------------------------------------------- + +static SAVEDS(ULONG) INTERRUPT AppWindowDropZoneHookFunc(struct Hook *hook, + APTR Reserved, struct AppWindowDropZoneMsg *adzm) +{ + struct DropZoneMsg *dzm; + + d1(KPrintF("%s/%ld: adzm_Action=%ld\n", __FUNC__, __LINE__, adzm->adzm_Action)); + d1(KPrintF("%s/%ld: Task=<%s>\n", __FUNC__, __LINE__, FindTask(NULL)->tc_Node.ln_Name)); + + do { + struct MsgPort *ReplyPort; + + ReplyPort = CreateMsgPort(); + if (NULL == ReplyPort) + break; + + dzm = malloc(sizeof(struct DropZoneMsg)); + if (NULL == dzm) + break; + + dzm->dzm_adzm = *adzm; + dzm->dzm_Msg.mn_Length = sizeof(struct DropZoneMsg); + dzm->dzm_Msg.mn_ReplyPort = ReplyPort; + d1(KPrintF("%s/%ld: dzm=%08lx \n", __FUNC__, __LINE__, dzm)); + PutMsg(DropZoneMsgPort, &dzm->dzm_Msg); + + d1(KPrintF("%s/%ld:\n", __FUNC__, __LINE__)); + WaitPort(ReplyPort); + + while ((dzm = (struct DropZoneMsg *) GetMsg(ReplyPort))) + { + d1(KPrintF(__FILE__ "/%s/%ld: dzm=%08lx\n", __FUNC__, __LINE__, dzm)); + free(dzm); + } + d1(KPrintF("%s/%ld:\n", __FUNC__, __LINE__)); + DeleteMsgPort(ReplyPort); + } while (0); + + return 0; +} + +//---------------------------------------------------------------------------- + +static void DropZoneMsgHandler(struct DropZoneMsg *dzm) +{ + struct DropZone *dz = (struct DropZone *) dzm->dzm_adzm.adzm_UserData; + ULONG Disabled = 0; + + d1(KPrintF("%s/%ld: START dz=%08lx o=%08lx adzm_Action=%ld\n", __FUNC__, __LINE__, dz, dz->dz_Object, dzm->dzm_adzm.adzm_Action)); + d1(KPrintF("%s/%ld: Task=<%s>\n", __FUNC__, __LINE__, FindTask(NULL)->tc_Node.ln_Name)); + + switch (dzm->dzm_adzm.adzm_Action) + { + case ADZMACTION_Enter: + d1(KPrintF("%s/%ld: ADZMACTION_Enter\n", __FUNC__, __LINE__)); + get(dz->dz_Object, MUIA_Disabled, &Disabled); + if (!Disabled) + { + DoMethod(dz->dz_Object, MUIM_DragBegin, NULL); +#if defined(__MORPHOS__) + if (DOSBase->dl_lib.lib_Version >= 51) + { + Delay(1); + WaitTOF(); + } +#endif //defined(__MORPHOS__) + } + break; + case ADZMACTION_Leave: + d1(KPrintF("%s/%ld: ADZMACTION_Leave\n", __FUNC__, __LINE__)); + DoMethod(dz->dz_Object, MUIM_DragFinish, NULL, FALSE); +#if defined(__MORPHOS__) + if (DOSBase->dl_lib.lib_Version >= 51) + { + Delay(1); + WaitTOF(); + } +#endif //defined(__MORPHOS__) + break; + } + d1(KPrintF("%s/%ld: END\n", __FUNC__, __LINE__)); +} + +//---------------------------------------------------------------------------- + +static void ReplaceIcon(Object *NewIconObj, Object **OldIconObj) +{ + //STRPTR str; + //struct IBox *WinRect; + struct ExtGadget *ggOld = (struct ExtGadget *) *OldIconObj; + struct ExtGadget *ggNew = (struct ExtGadget *) NewIconObj; + IPTR ul; + IPTR IconType; + + d1(KPrintF("%s/%ld: START NewIconObj=%08lx OldIconObj=%08lx\n", __FUNC__, __LINE__, NewIconObj, OldIconObj)); + + d1(KPrintF("%s/%ld: *OldIconObj=%08lx\n", __FUNC__, __LINE__, *OldIconObj)); + GetAttr(IDTA_Type, *OldIconObj, &IconType); + d1(KPrintF("%s/%ld: \n", __FUNC__, __LINE__)); + set(NewIconObj, IDTA_Type, IconType); + + d1(KPrintF("%s/%ld: \n", __FUNC__, __LINE__)); + + ggNew->BoundsLeftEdge = ggOld->LeftEdge + (ggNew->LeftEdge - ggNew->BoundsLeftEdge); + ggNew->BoundsTopEdge = ggOld->TopEdge + (ggNew->TopEdge - ggNew->BoundsTopEdge); + ggNew->LeftEdge = ggOld->LeftEdge; + ggNew->TopEdge = ggNew->TopEdge; + + d1(KPrintF("%s/%ld: \n", __FUNC__, __LINE__)); + + GetAttr(IDTA_DefaultTool, *OldIconObj, &ul); + set(NewIconObj, IDTA_DefaultTool, ul); + + d1(KPrintF("%s/%ld: \n", __FUNC__, __LINE__)); + + GetAttr(IDTA_WindowRect, *OldIconObj, &ul); + set(NewIconObj, IDTA_WindowRect, ul); + + GetAttr(IDTA_WinCurrentX, *OldIconObj, &ul); + set(NewIconObj, IDTA_WinCurrentX, ul); + GetAttr(IDTA_WinCurrentY, *OldIconObj, &ul); + set(NewIconObj, IDTA_WinCurrentY, ul); + + GetAttr(IDTA_Flags, *OldIconObj, &ul); + set(NewIconObj, IDTA_Flags, ul); + + d1(KPrintF("%s/%ld: \n", __FUNC__, __LINE__)); + + GetAttr(IDTA_ViewModes, *OldIconObj, &ul); + set(NewIconObj, IDTA_ViewModes, ul); + + d1(KPrintF("%s/%ld: \n", __FUNC__, __LINE__)); + + set(MccIconObj, MUIA_Iconobj_Object, NewIconObj); + + d1(KPrintF("%s/%ld: \n", __FUNC__, __LINE__)); + + DisposeIconObject(*OldIconObj); + *OldIconObj = NewIconObj; + + d1(KPrintF("%s/%ld: END\n", __FUNC__, __LINE__)); +} + +//---------------------------------------------------------------------------- + +static void SaveSettings(Object *IconObj, Object *originalIconObj, CONST_STRPTR IconName) +{ + d1(KPrintF(__FILE__ "/%s/%ld: IconObj=%08lx IconName=<%s>\n", __FUNC__, __LINE__, IconObj, IconName)); + + if (IconObj) + { + IPTR IconType; + IPTR ToolPri; + char ToolPriString[15]; + struct ScaWindowStruct *ws; + CONST_STRPTR *ToolTypesArray; + STRPTR *OldToolTypesArray; + enum StartFromType StartFrom = STARTFROM_Workbench; + APTR UndoStep = NULL; + STRPTR Comment = ""; + STRPTR DefaultTool = ""; + IPTR Selected; + ULONG Protection = 0; + IPTR StackSize; + CONST_STRPTR NewName = ScalosExamineGetName(fib); + char GetName[128]; + char VolumeName[128]; + ULONG Pos2; + BPTR dirLock = CurrentDir((BPTR) NULL); + + CurrentDir(dirLock); + ws = FindScalosWindow(dirLock); + + if (ws) + { + UndoStep = (APTR) DoMethod(ws->ws_WindowTask->mt_MainObject, SCCM_IconWin_BeginUndoStep); + } + + GetAttr(IDTA_Type, IconObj, &IconType); + GetAttr(MUIA_String_Contents, StringName, (APTR)&NewName); + + GetAttr(IDTA_ToolTypes, IconObj, (APTR) &ToolTypesArray); + OldToolTypesArray = CloneToolTypeArray(ToolTypesArray, 0); + + Protection = ScalosExamineGetProtection(fib) & ~(FIBF_READ | FIBF_WRITE | FIBF_ARCHIVE | FIBF_DELETE | FIBF_EXECUTE | FIBF_SCRIPT); + + switch (IconType) + { + case WBDISK: + GetAttr(MUIA_String_Contents, StringCommentDevice, (APTR)&Comment); + SetChangedToolTypes(IconObj, TextEditorToolTypesDevice); + break; + case WBDRAWER: + SetChangedToolTypes(IconObj, TextEditorToolTypesDrawer); + + GetAttr(MUIA_String_Contents, StringCommentDrawer, (APTR)&Comment); + + GetAttr(MUIA_Selected, CheckMarkProtectionReadDrawer, &Selected); + if (!Selected) + Protection |= FIBF_READ; + GetAttr(MUIA_Selected, CheckMarkProtectionWriteDrawer, &Selected); + if (!Selected) + Protection |= FIBF_WRITE; + GetAttr(MUIA_Selected, CheckMarkProtectionArchiveDrawer, &Selected); + if (Selected) + Protection |= FIBF_ARCHIVE; + GetAttr(MUIA_Selected, CheckMarkProtectionDeleteDrawer, &Selected); + if (!Selected) + Protection |= FIBF_DELETE; + GetAttr(MUIA_Selected, CheckMarkProtectionExecuteDrawer, &Selected); + if (!Selected) + Protection |= FIBF_EXECUTE; + GetAttr(MUIA_Selected, CheckMarkProtectionScriptDrawer, &Selected); + if (Selected) + Protection |= FIBF_SCRIPT; + break; + + case WBGARBAGE: + SetChangedToolTypes(IconObj, TextEditorToolTypesDrawer); + + GetAttr(MUIA_String_Contents, StringCommentDrawer, (APTR)&Comment); + + GetAttr(MUIA_Selected, CheckMarkProtectionReadDrawer, &Selected); + if (!Selected) + Protection |= FIBF_READ; + GetAttr(MUIA_Selected, CheckMarkProtectionWriteDrawer, &Selected); + if (!Selected) + Protection |= FIBF_WRITE; + GetAttr(MUIA_Selected, CheckMarkProtectionArchiveDrawer, &Selected); + if (Selected) + Protection |= FIBF_ARCHIVE; + GetAttr(MUIA_Selected, CheckMarkProtectionDeleteDrawer, &Selected); + if (!Selected) + Protection |= FIBF_DELETE; + GetAttr(MUIA_Selected, CheckMarkProtectionExecuteDrawer, &Selected); + if (!Selected) + Protection |= FIBF_EXECUTE; + GetAttr(MUIA_Selected, CheckMarkProtectionScriptDrawer, &Selected); + if (Selected) + Protection |= FIBF_SCRIPT; + break; + + case WBTOOL: + SetChangedToolTypes(IconObj, TextEditorToolTypesTool); + + GetAttr(MUIA_String_Contents, StringCommentTool, (APTR)&Comment); + GetAttr(MUIA_Cycle_Active, CycleStartFromTool, (APTR)&StartFrom); + GetAttr(MUIA_String_Integer, StringStackSizeTool, &StackSize); + + SetAttrs(IconObj, + IDTA_Stacksize, StackSize, + TAG_END); + + switch (StartFrom) + { + case STARTFROM_CLI: + SetToolType(IconObj, "CLI", ""); + RemoveToolType(IconObj, "REXX"); + break; + case STARTFROM_Arexx: + SetToolType(IconObj, "REXX", ""); + RemoveToolType(IconObj, "CLI"); + break; + case STARTFROM_Workbench: + default: + RemoveToolType(IconObj, "CLI"); + RemoveToolType(IconObj, "REXX"); + break; + } + + + if (SliderStartPriTool) + { + IPTR StartPri; + + GetAttr(MUIA_Numeric_Value, SliderStartPriTool, &StartPri); + if (0 != StartPri) + { + sprintf(ToolPriString, "%ld", StartPri); + SetToolType(IconObj, "STARTPRI", ToolPriString); + } + else + RemoveToolType(IconObj, "STARTPRI"); + } + + if (StringWaitTimeTool) + { + IPTR WaitTime; + + GetAttr(MUIA_String_Integer, StringWaitTimeTool, &WaitTime); + if (0 != WaitTime) + { + sprintf(ToolPriString, "%ld", (long) WaitTime); + SetToolType(IconObj, "WAIT", ToolPriString); + } + else + RemoveToolType(IconObj, "WAIT"); + } + + if (CheckMarkWaitUntilFinishedTool) + { + IPTR WaitUntilFinished; + + GetAttr(MUIA_Selected, CheckMarkWaitUntilFinishedTool, &WaitUntilFinished); + if (WaitUntilFinished) + RemoveToolType(IconObj, "DONOTWAIT"); + else + SetToolType(IconObj, "DONOTWAIT", ""); + } + + if (STARTFROM_CLI == StartFrom || STARTFROM_Arexx == StartFrom) + { + IPTR PromptForInput; + + GetAttr(MUIA_Selected, ButtonPromptForInputTool, &PromptForInput); + + if (PromptForInput) + RemoveToolType(IconObj, "DONOTPROMPT"); + else + SetToolType(IconObj, "DONOTPROMPT", ""); + } + + GetAttr(MUIA_Numeric_Value, SliderToolPriTool, &ToolPri); + if (ToolPri) + { + sprintf(ToolPriString, "%ld", (long) ToolPri); + SetToolType(IconObj, "TOOLPRI", ToolPriString); + } + else + RemoveToolType(IconObj, "TOOLPRI"); + + GetAttr(MUIA_Selected, CheckMarkProtectionHideTool, &Selected); + if (Selected) + Protection |= FIBF_HIDDEN; + + GetAttr(MUIA_Selected, CheckMarkProtectionReadTool, &Selected); + if (!Selected) + Protection |= FIBF_READ; + GetAttr(MUIA_Selected, CheckMarkProtectionWriteTool, &Selected); + if (!Selected) + Protection |= FIBF_WRITE; + GetAttr(MUIA_Selected, CheckMarkProtectionArchiveTool, &Selected); + if (Selected) + Protection |= FIBF_ARCHIVE; + GetAttr(MUIA_Selected, CheckMarkProtectionDeleteTool, &Selected); + if (!Selected) + Protection |= FIBF_DELETE; + + + GetAttr(MUIA_Selected, CheckMarkProtectionPureTool, &Selected); + if (Selected) + Protection |= FIBF_PURE; + + GetAttr(MUIA_Selected, CheckMarkProtectionExecuteTool, &Selected); + if (!Selected) + Protection |= FIBF_EXECUTE; + GetAttr(MUIA_Selected, CheckMarkProtectionScriptTool, &Selected); + if (Selected) + Protection |= FIBF_SCRIPT; + break; + + case WBPROJECT: + SetChangedToolTypes(IconObj, TextEditorToolTypesProject); + + GetAttr(MUIA_String_Contents, StringCommentProject, (APTR)&Comment); + GetAttr(MUIA_Cycle_Active, CycleStartFromProject, (APTR)&StartFrom); + GetAttr(MUIA_String_Integer, StringStackSizeProject, &StackSize); + GetAttr(MUIA_String_Contents, PopAslDefaultTool, (APTR)&DefaultTool); + + SetAttrs(IconObj, + IDTA_Stacksize, StackSize, + IDTA_DefaultTool, DefaultTool, + TAG_END); + + switch (StartFrom) + { + case STARTFROM_CLI: + SetToolType(IconObj, "CLI", ""); + RemoveToolType(IconObj, "REXX"); + break; + case STARTFROM_Arexx: + SetToolType(IconObj, "REXX", ""); + RemoveToolType(IconObj, "CLI"); + break; + case STARTFROM_Workbench: + default: + RemoveToolType(IconObj, "CLI"); + RemoveToolType(IconObj, "REXX"); + break; + } +//----------------------------------------------------------------------------------------------- + + if (SliderStartPriTool2) + { + IPTR StartPri; + + GetAttr(MUIA_Numeric_Value, SliderStartPriTool2, &StartPri); + if (0 != StartPri) + { + sprintf(ToolPriString, "%ld", StartPri); + SetToolType(IconObj, "STARTPRI", ToolPriString); + } + else + RemoveToolType(IconObj, "STARTPRI"); + } + + if (StringWaitTimeTool2) + { + IPTR WaitTime; + + GetAttr(MUIA_String_Integer, StringWaitTimeTool2, &WaitTime); + if (0 != WaitTime) + { + sprintf(ToolPriString, "%ld", (long) WaitTime); + SetToolType(IconObj, "WAIT", ToolPriString); + } + else + RemoveToolType(IconObj, "WAIT"); + } + + if (CheckMarkWaitUntilFinishedTool2) + { + IPTR WaitUntilFinished; + + GetAttr(MUIA_Selected, CheckMarkWaitUntilFinishedTool2, &WaitUntilFinished); + if (WaitUntilFinished) + RemoveToolType(IconObj, "DONOTWAIT"); + else + SetToolType(IconObj, "DONOTWAIT", ""); + } +//-------------------------------------------------------------------------------------------- + + if (STARTFROM_CLI == StartFrom || STARTFROM_Arexx == StartFrom) + { + IPTR PromptForInput; + + GetAttr(MUIA_Selected, ButtonPromptForInputProject, &PromptForInput); + + if (PromptForInput) + RemoveToolType(IconObj, "DONOTPROMPT"); + else + SetToolType(IconObj, "DONOTPROMPT", ""); + } + + GetAttr(MUIA_Numeric_Value, SliderToolPriProject, (IPTR *) &ToolPri); + if (ToolPri) + { + sprintf(ToolPriString, "%ld", (long) ToolPri); + SetToolType(IconObj, "TOOLPRI", ToolPriString); + } + else + RemoveToolType(IconObj, "TOOLPRI"); + + GetAttr(MUIA_Selected, CheckMarkProtectionHideProject, &Selected); + if (Selected) + Protection |= FIBF_HIDDEN; + + GetAttr(MUIA_Selected, CheckMarkProtectionReadProject, &Selected); + if (!Selected) + Protection |= FIBF_READ; + GetAttr(MUIA_Selected, CheckMarkProtectionWriteProject, &Selected); + if (!Selected) + Protection |= FIBF_WRITE; + GetAttr(MUIA_Selected, CheckMarkProtectionArchiveProject, &Selected); + if (Selected) + Protection |= FIBF_ARCHIVE; + GetAttr(MUIA_Selected, CheckMarkProtectionDeleteProject, &Selected); + if (!Selected) + Protection |= FIBF_DELETE; + GetAttr(MUIA_Selected, CheckMarkProtectionExecuteProject, &Selected); + if (!Selected) + Protection |= FIBF_EXECUTE; + + GetAttr(MUIA_Selected, CheckMarkProtectionPureProject, &Selected); + if (Selected) + Protection |= FIBF_PURE; + + GetAttr(MUIA_Selected, CheckMarkProtectionScriptProject, &Selected); + if (Selected) + Protection |= FIBF_SCRIPT; + break; + + default: + break; + } + + d1(KPrintF(__FILE__ "/%s/%ld: IconObj=%08lx IconName=<%s>\n", __FUNC__, __LINE__, IconObj, IconName)); + + // +jmc+ Check WBDISK, PutIconObjectTags() with strip ".info" from name if needed. + // If ".info" exists, icon will be overwritten instead to create + // a icon from the complete name with ".info"(i.e. "name.info.info"). + + if (WBDISK == IconType && FoundDeviceFromArg) + { + IconName = "disk"; + d1(KPrintF(__FILE__ "/%s/%ld: IconObj=%08lx IconName=<%s>\n", __FUNC__, __LINE__, IconObj, IconName)); + } + + stccpy(GetName, IconName, sizeof(GetName)); + Pos2 = IsIconName(GetName); + + if (Pos2 && ~0 != Pos2) + { + // strip ".info" from name + *((char *) Pos2) = '\0'; + } + + d1(KPrintF(__FILE__ "/%s/%ld: IconObj=%08lx IconName=<%s>\n", __FUNC__, __LINE__, IconObj, IconName)); + + if (ws) + { + DoMethod(ws->ws_WindowTask->mt_MainObject, + SCCM_IconWin_AddUndoEvent, + UNDO_ChangeIconObject, + UNDOTAG_UndoMultiStep, UndoStep, + UNDOTAG_IconDirLock, dirLock, + UNDOTAG_IconName, (ULONG) ScalosExamineGetName(fib), + UNDOTAG_OldIconObject, (ULONG) originalIconObj, + UNDOTAG_NewIconObject, (ULONG) IconObj, + TAG_END + ); + } + + PutIconObjectTags(IconObj, GetName, + ICONA_NoNewImage, TRUE, + TAG_END); + + d1(KPrintF(__FILE__ "/%s/%ld: IconObj=%08lx IconName=<%s>\n", __FUNC__, __LINE__, IconObj, IconName)); + + + if (WBDISK != IconType) + { + if (FibValid && Protection != ScalosExamineGetProtection(fib)) + { + // Protection has changed + if (ws) + { + DoMethod(ws->ws_WindowTask->mt_MainObject, + SCCM_IconWin_AddUndoEvent, + UNDO_SetProtection, + UNDOTAG_UndoMultiStep, UndoStep, + UNDOTAG_IconDirLock, dirLock, + UNDOTAG_IconName, (ULONG) ScalosExamineGetName(fib), + UNDOTAG_OldProtection, ScalosExamineGetProtection(fib), + UNDOTAG_NewProtection, Protection, + TAG_END + ); + } + if (!SetProtection(IconName, Protection)) + ReportError(MSGID_ERROR_SETPROTECTION); + } + } + + if (FibValid && 0 != strcmp(NewName, ScalosExamineGetName(fib))) + { + // Name has changed + if (WBDISK == IconType) + { + if (ws) + { + DoMethod(ws->ws_WindowTask->mt_MainObject, + SCCM_IconWin_AddUndoEvent, + UNDO_Relabel, + UNDOTAG_UndoMultiStep, UndoStep, + UNDOTAG_CopySrcDirLock, dirLock, + UNDOTAG_CopySrcName, (ULONG) ScalosExamineGetName(fib), + UNDOTAG_CopyDestName, NewName, + TAG_END + ); + } + RenameDevice(ScalosExamineGetName(fib), NewName); + } + else + { + if (ws) + { + DoMethod(ws->ws_WindowTask->mt_MainObject, + SCCM_IconWin_AddUndoEvent, + UNDO_Rename, + UNDOTAG_UndoMultiStep, UndoStep, + UNDOTAG_CopySrcDirLock, dirLock, + UNDOTAG_CopySrcName, (ULONG) ScalosExamineGetName(fib), + UNDOTAG_CopyDestName, (ULONG) NewName, + TAG_END + ); + } + RenameObject(ScalosExamineGetName(fib), NewName); + } + + if (ws) + SCA_UnLockWindowList(); + } + + if (FibValid && 0 != strcmp(Comment, ScalosExamineGetComment(fib))) + { + // Comment has changed + if (WBDISK == IconType && FoundDeviceFromArg) // +jmc+ - Add ":" to volume name for SetComment(). + { + stccpy(VolumeName, NewName, sizeof(VolumeName)); + strcat(VolumeName,":"); + IconName = VolumeName; + } + if (ws) + { + DoMethod(ws->ws_WindowTask->mt_MainObject, + SCCM_IconWin_AddUndoEvent, + UNDO_SetComment, + UNDOTAG_UndoMultiStep, UndoStep, + UNDOTAG_IconDirLock, dirLock, + UNDOTAG_IconName, (ULONG) ScalosExamineGetName(fib), + UNDOTAG_OldComment, (ULONG) ScalosExamineGetComment(fib), + UNDOTAG_NewComment, (ULONG) Comment, + TAG_END + ); + } + if (!SetComment(IconName, Comment)) + ReportError(MSGID_ERROR_SETCOMMENT); + } + + if (ws) + { + DoMethod(ws->ws_WindowTask->mt_MainObject, SCCM_IconWin_EndUndoStep, UndoStep); + SCA_UnLockWindowList(); + } + if (OldToolTypesArray) + { + free(OldToolTypesArray); + } + } + + d1(KPrintF(__FILE__ "/%s/%ld: IconObj=%08lx IconName=<%s>\n", __FUNC__, __LINE__, IconObj, IconName)); +} + +//---------------------------------------------------------------------------- + +static void GetIconObject(struct DefIconInfo *dii, CONST_STRPTR IconName, BPTR DirLock, + STRPTR FileTypeName, size_t FileTypeNameSize) +{ + char IconPath[MAX_PATH_SIZE]; + + do { + strcpy(FileTypeName, ""); + + if (NULL == IconName || strlen(IconName) < 1) + { + if (!NameFromLock(DirLock, IconPath, sizeof(IconPath))) + break; + IconName = IconPath; + } + + *dii->dii_IconObjectFromScalos = GetIconObjectFromScalos(DirLock, IconName, FileTypeName, FileTypeNameSize); + + *dii->dii_IconObjectFromDisk = NewIconObject(IconName, NULL); + d1(KPrintF(__FILE__ "/%s/%ld: IconName=<%s> dii_IconObjectFromDisk=%08lx\n", __FUNC__, __LINE__, IconName, *dii->dii_IconObjectFromDisk)); + if (*dii->dii_IconObjectFromDisk) + { + if (NULL == *dii->dii_BackupIconObjectFromDisk) + *dii->dii_BackupIconObjectFromDisk = NewIconObject(IconName, NULL); + break; + } + + *dii->dii_IconObjectFromDisk = SCA_GetDefIconObjectTags(DirLock, IconName, + TAG_END); + if (*dii->dii_IconObjectFromDisk) + { + if (NULL == *dii->dii_BackupIconObjectFromDisk) + { + *dii->dii_BackupIconObjectFromDisk = SCA_GetDefIconObjectTags(DirLock, IconName, + TAG_END); + } + } + + d1(KPrintF(__FILE__ "/%s/%ld: dii_IconObjectFromDisk=%08lx\n", __FUNC__, __LINE__, *dii->dii_IconObjectFromDisk)); + } while (0); +} + +//---------------------------------------------------------------------------- + +static void GetDeviceIconObject(struct DefIconInfo *dii, CONST_STRPTR IconName, + CONST_STRPTR VolumeName, CONST_STRPTR DeviceName, + STRPTR FileTypeName, size_t FileTypeNameSize) +{ + BPTR OldDir = (BPTR)NULL; + BPTR dLock = (BPTR)NULL; + BPTR DiskLock = (BPTR) NULL; + + do { + char DefIconName[128]; + + strcpy(DefIconName, VolumeName); + strcat(DefIconName, ":"); + + DiskLock = Lock(DefIconName, ACCESS_READ); + + if (prefDefIconsFirst) + { + dLock = Lock(prefDefIconPath, ACCESS_READ); + if ((BPTR)NULL == dLock) + break; + +// *dii->dii_IconObjectFromScalos = GetDeviceIconObjectFromScalos(dLock, FileTypeName, FileTypeNameSize); + + OldDir = CurrentDir(dLock); + + strcpy(DefIconName, "def_"); + strcat(DefIconName, VolumeName); + + *dii->dii_IconObjectFromDisk = NewIconObject(DefIconName, NULL); + d1(KPrintF(__FILE__ "/%s/%ld: dii_IconObjectFromDisk=%08lx <%s>\n", __FUNC__, __LINE__, *dii->dii_IconObjectFromDisk, DefIconName)); + if (*dii->dii_IconObjectFromDisk) + break; + + BuildDefVolumeNameNoSpace(DefIconName, VolumeName, sizeof(DefIconName)); + + *dii->dii_IconObjectFromDisk = NewIconObject(DefIconName, NULL); + d1(KPrintF(__FILE__ "/%s/%ld: dii_IconObjectFromDisk=%08lx DefIconName=<%s> VolumeName=<%s>\n", __FUNC__, __LINE__, *dii->dii_IconObjectFromDisk, DefIconName, VolumeName)); + if (*dii->dii_IconObjectFromDisk) + break; + + strcpy(DefIconName, "def_"); + strcat(DefIconName, DeviceName); + + *dii->dii_IconObjectFromDisk = NewIconObject(DefIconName, NULL); + d1(KPrintF(__FILE__ "/%s/%ld: dii_IconObjectFromDisk=%08lx <%s>\n", __FUNC__, __LINE__, *dii->dii_IconObjectFromDisk, DefIconName)); + if (*dii->dii_IconObjectFromDisk) + break; + + CurrentDir(OldDir); + OldDir = (BPTR)NULL; + + *dii->dii_IconObjectFromDisk = NewIconObject(IconName, NULL); + d1(KPrintF(__FILE__ "/%s/%ld: dii_IconObjectFromDisk=%08lx <%s>\n", __FUNC__, __LINE__, *dii->dii_IconObjectFromDisk, IconName)); + if (*dii->dii_IconObjectFromDisk) + break; + + OldDir = CurrentDir(DiskLock); + + *dii->dii_IconObjectFromDisk = NewIconObject("disk", NULL); + d1(KPrintF(__FILE__ "/%s/%ld: dii_IconObjectFromDisk=%08lx IconName=<%s>\n", __FUNC__, __LINE__, *dii->dii_IconObjectFromDisk, IconName)); + if (*dii->dii_IconObjectFromDisk) + break; + } + else + { + dLock = Lock(prefDefIconPath, ACCESS_READ); + if ((BPTR)NULL == dLock) + break; + +// *dii->dii_IconObjectFromScalos = GetDeviceIconObjectFromScalos(dLock, FileTypeName, FileTypeNameSize); + + if (IconName && strlen(IconName)) + { + *dii->dii_IconObjectFromDisk = NewIconObject(IconName, NULL); + d1(KPrintF(__FILE__ "/%s/%ld: dii_IconObjectFromDisk=%08lx IconName=<%s>\n", __FUNC__, __LINE__, *dii->dii_IconObjectFromDisk, IconName)); + if (*dii->dii_IconObjectFromDisk) + break; + } + + OldDir = CurrentDir(DiskLock); + + *dii->dii_IconObjectFromDisk = NewIconObject("disk", NULL); + d1(KPrintF(__FILE__ "/%s/%ld: dii_IconObjectFromDisk=%08lx IconName=<%s>\n", __FUNC__, __LINE__, *dii->dii_IconObjectFromDisk, IconName)); + if (*dii->dii_IconObjectFromDisk) + break; + + (void) CurrentDir(dLock); + + strcpy(DefIconName, "def_"); + strcat(DefIconName, VolumeName); + + *dii->dii_IconObjectFromDisk = NewIconObject(DefIconName, NULL); + d1(KPrintF(__FILE__ "/%s/%ld: *dii->dii_IconObjectFromDisk=%08lx <%s> VolumeName=<%s>\n", __FUNC__, __LINE__, *dii->dii_IconObjectFromDisk, DefIconName, VolumeName)); + if (*dii->dii_IconObjectFromDisk) + break; + + BuildDefVolumeNameNoSpace(DefIconName, VolumeName, sizeof(DefIconName)); + + *dii->dii_IconObjectFromDisk = NewIconObject(DefIconName, NULL); + d1(KPrintF(__FILE__ "/%s/%ld: dii_IconObjectFromDisk=%08lx DefIconName=<%s> VolumeName=<%s>\n", __FUNC__, __LINE__, *dii->dii_IconObjectFromDisk, DefIconName, VolumeName)); + if (*dii->dii_IconObjectFromDisk) + break; + + strcpy(DefIconName, "def_"); + strcat(DefIconName, DeviceName); + + *dii->dii_IconObjectFromDisk = NewIconObject(DefIconName, NULL); + d1(KPrintF(__FILE__ "/%s/%ld: dii_IconObjectFromDisk=%08lx <%s>\n", __FUNC__, __LINE__, *dii->dii_IconObjectFromDisk, DefIconName)); + if (*dii->dii_IconObjectFromDisk) + break; + } + + if (DiskLock) + { + *dii->dii_IconObjectFromDisk = SCA_GetDefIconObjectTags(DiskLock, "", + TAG_END); + d1(KPrintF(__FILE__ "/%s/%ld: dii_IconObjectFromDisk=%08lx <%s>\n", __FUNC__, __LINE__, *dii->dii_IconObjectFromDisk, DefIconName)); + } + } while (0); + + if (OldDir) + CurrentDir(OldDir); + if (dLock) + UnLock(dLock); + if (DiskLock) + UnLock(DiskLock); +} + +//---------------------------------------------------------------------------- + +static BOOL isDiskWritable(BPTR dLock) +{ + struct InfoData *info = AllocInfoData(); + BOOL Result = TRUE; + + if (info) + { + Info(dLock, info); + + if (!CheckInfoData(info)) + Result = FALSE; + + FreeInfoData(info); + } + + return Result; +} + +//---------------------------------------------------------------------------- + +// return TRUE if Disk is writable +static ULONG CheckInfoData(const struct InfoData *info) +{ + ULONG Result = TRUE; + ULONG64 UsedPercent64; + ULONG UsedPercent; + char ByteCountText[16]; + + d1(kprintf(__FILE__ "/%s/%ld: DiskType=%ld DiskState=%ld\n", __FUNC__, __LINE__, info->id_DiskType, info->id_DiskState)); + + UsedPercent64 = Div64(Mul64(MakeU64(100), MakeU64(info->id_NumBlocksUsed), NULL), MakeU64(info->id_NumBlocks), NULL); + UsedPercent = ULONG64_LOW(UsedPercent64); + + ByteCount(ByteCountText, sizeof(ByteCountText), info->id_NumBlocksUsed, info->id_BytesPerBlock); + ScaFormatString(GetLocString(MSGID_DEVICE_BLOCKS_PERCENT), + TextDeviceUsed, sizeof(TextDeviceUsed), + 3, ByteCountText, info->id_NumBlocksUsed, UsedPercent); + + ByteCount(ByteCountText, sizeof(ByteCountText), + info->id_NumBlocks - info->id_NumBlocksUsed, info->id_BytesPerBlock); + ScaFormatString(GetLocString(MSGID_DEVICE_BLOCKS_PERCENT), + TextDeviceFree, sizeof(TextDeviceFree), + 3, ByteCountText, + info->id_NumBlocks - info->id_NumBlocksUsed, + 100 - UsedPercent); + + ByteCount(ByteCountText, sizeof(ByteCountText), info->id_NumBlocks, info->id_BytesPerBlock); + ScaFormatString(GetLocString(MSGID_DEVICE_BLOCKS), + TextDeviceSize, sizeof(TextDeviceSize), + 2, ByteCountText, info->id_NumBlocks); + + + switch (info->id_DiskState) + { + case ID_WRITE_PROTECTED: + stccpy(DeviceState, GetLocString(MSGID_DEVICE_DISKSTATE_READONLY), sizeof(DeviceState)); + break; + case ID_VALIDATING: + stccpy(DeviceState, GetLocString(MSGID_DEVICE_DISKSTATE_VALIDATING), sizeof(DeviceState)); + break; + case ID_VALIDATED: + stccpy(DeviceState, GetLocString(MSGID_DEVICE_DISKSTATE_READ_WRITE), sizeof(DeviceState)); + break; + default: + stccpy(DeviceState, GetLocString(MSGID_DEVICE_DISKSTATE_UNKNOWN), sizeof(DeviceState)); + break; + } + + ScaFormatString(GetLocString(MSGID_DEVICE_BLOCKSIZE_BYTES), + DeviceBlockSize, sizeof(DeviceBlockSize), + 1, info->id_BytesPerBlock); + + switch (info->id_DiskType) + { + case ID_NO_DISK_PRESENT: + case ID_UNREADABLE_DISK: + Result = FALSE; + break; + } + + if (ID_WRITE_PROTECTED == info->id_DiskState) + Result = FALSE; + + return Result; +} + +//---------------------------------------------------------------------------- + +static BOOL IsDevice(struct WBArg *arg) +{ + BOOL isDevice = FALSE; + BPTR OldDir; + BPTR fLock = (BPTR)NULL; + + d1(KPrintF(__FILE__ "/%s/%ld: START\n", __FUNC__, __LINE__)); + + do { + char VolumeName[128]; + size_t Len; + + OldDir = CurrentDir(arg->wa_Lock); + + if (arg->wa_Name && strlen(arg->wa_Name) > 0) + { + fLock = Lock(arg->wa_Name, ACCESS_READ); + d1(kprintf(__FILE__ "/%s/%ld: fLock=%08lx Name=<%s>\n", __FUNC__, __LINE__, fLock, arg->wa_Name)); + if ((BPTR)NULL == fLock) + { + if (0 == stricmp(arg->wa_Name, "disk")) + { + struct WBArg ArgCopy = *arg; + + ArgCopy.wa_Name = ""; + isDevice = IsDevice(&ArgCopy); + } + break; + } + + NameFromLock(fLock, VolumeName, sizeof(VolumeName)); + + d1(KPrintF(__FILE__ "/%s/%ld: VolumeName=<%s>\n", __FUNC__, __LINE__, VolumeName)); + + Len = strlen(VolumeName); + isDevice = Len > 0 && ':' == VolumeName[Len - 1]; + } + else + { + T_ExamineData *fib; + + if (ScalosExamineBegin(&fib)) + { + BPTR parentDir; + + if (ScalosExamineLock(arg->wa_Lock, &fib)) + { + d1(KPrintF(__FILE__ "/%s/%ld: fib_DirEntryType=%ld <%s>\n", __FUNC__, __LINE__, \ + ScalosExamineGetDirEntryType(fib), ScalosExamineGetName(fib))); + isDevice = ST_ROOT == ScalosExamineGetDirEntryType(fib); + } + + parentDir = ParentDir(arg->wa_Lock); + d1(KPrintF(__FILE__ "/%s/%ld: parentDir=%08lx\n", __FUNC__, __LINE__, parentDir)); + if (parentDir) + UnLock(parentDir); + else + { + // ParentDir() of root directory returns NULL + isDevice = TRUE; + } + + ScalosExamineEnd(&fib); + } + } + } while (0); + + if (fLock) + UnLock(fLock); + CurrentDir(OldDir); + + d1(KPrintF(__FILE__ "/%s/%ld: END isDevice=%ld\n", __FUNC__, __LINE__, isDevice)); + + return isDevice; +} + +//---------------------------------------------------------------------------- + +static void GetDeviceName(BPTR dLock, CONST_STRPTR VolumeName, STRPTR DeviceName, size_t MaxLen) +{ + struct InfoData *info = AllocInfoData(); + + strcpy(DeviceName, ""); + if (info) + { + struct DosList *VolumeNode; + + Info(dLock, info); + + VolumeNode = (struct DosList *) BADDR(info->id_VolumeNode); + + d1(KPrintF(__FILE__ "/%s/%ld: VolumeNode=%08lx Type=%08lx\n", __FUNC__, __LINE__, VolumeNode, VolumeNode->dol_Type)); + + if (VolumeNode) + { + char DosTypeString[16]; + const struct FileSysEntry *fse; + char FseHandler[80] = ""; + LONG FseVersion; + LONG FseRevision; + + if (DLT_VOLUME == VolumeNode->dol_Type) + { + d1(KPrintF(__FILE__ "/%s/%ld: DiskType=%08lx\n", __FUNC__, __LINE__, VolumeNode->dol_misc.dol_volume.dol_DiskType)); + + stccpy(TextDeviceCreateDate, + GetChangeDate(TRUE, &VolumeNode->dol_misc.dol_volume.dol_VolumeDate), + sizeof(TextDeviceCreateDate)); + } + + fse = FindFileSysResEntry(VolumeNode->dol_misc.dol_volume.dol_DiskType); + if (fse) + { + LONG *seg; + + d1(KPrintF(__FILE__ "/%s/%ld: fse=%08lx ln_Name=%08lx\n", __FUNC__, __LINE__, fse, fse->fse_Node.ln_Name)); + + if (fse->fse_Node.ln_Name) + stccpy(FseHandler, fse->fse_Node.ln_Name, sizeof(FseHandler)); + + FseVersion = fse->fse_Version >> 16; + FseRevision = fse->fse_Version & 0xffff; + + sprintf(TextDeviceHandler, GetLocString(MSGID_DEVICE_HANDLER_DISKID), + FseHandler, + FseVersion, FseRevision); + + + seg = (LONG *) BADDR(fse->fse_SegList); + d1(KPrintF(__FILE__ "/%s/%ld: seg=%08lx\n", __FUNC__, __LINE__, seg)); + while (seg) + { + const struct Resident *rt; + CONST_STRPTR VersionString; + size_t SegLength = /* sizeof(LONG) * */ seg[-1]; + + d1(KPrintF(__FILE__ "/%s/%ld: seg=%08lx len=%lu\n", __FUNC__, __LINE__, seg, SegLength)); + + rt = SearchResident((UWORD *) (seg + 1), SegLength - 8); + d1(KPrintF(__FILE__ "/%s/%ld: rt=%08lx\n", __FUNC__, __LINE__, rt)); + if (rt && rt->rt_IdString) + { + strcpy(TextDeviceHandler, rt->rt_IdString); + d1(KPrintF(__FILE__ "/%s/%ld: rt->rt_IdString: TextDeviceHandler=%s\n", __FUNC__, __LINE__, TextDeviceHandler)); + break; + } + + VersionString = FindVersionString((UBYTE *) (seg + 1), SegLength - 8); + d1(KPrintF(__FILE__ "/%s/%ld: VersionString=%08lx\n", __FUNC__, __LINE__, VersionString)); + if (VersionString) + { + strcpy(TextDeviceHandler, VersionString); + break; + } + + seg = (LONG *) BADDR(*seg); + } + } + + sprintf(DosTypeString, GetLocString(MSGID_DEVICE_DOSTYPESTRING), + MakePrintable((VolumeNode->dol_misc.dol_volume.dol_DiskType >> 24) & 0xff), + MakePrintable((VolumeNode->dol_misc.dol_volume.dol_DiskType >> 16) & 0xff), + MakePrintable((VolumeNode->dol_misc.dol_volume.dol_DiskType >> 8) & 0xff), + MakePrintable(VolumeNode->dol_misc.dol_volume.dol_DiskType & 0xff)); + + if (VolumeNode->dol_Task && VolumeNode->dol_Task->mp_SigTask) + { + struct DosList *dl; + +#if defined(__amigaos4__) + { + struct FileSystemData *fsd; + + fsd = GetDiskFileSystemData(VolumeName); + d1(kprintf(__FILE__ "/%s/%ld: fsd=%08lx\n", __FUNC__, __LINE__, fsd)); + if (fsd) + { + d1(kprintf(__FILE__ "/%s/%ld: fsd_FileSystemName=%08lx\n", __FUNC__, __LINE__, fsd->fsd_FileSystemName)); + d1(kprintf(__FILE__ "/%s/%ld: fsd_FileSystemName=<%s>\n", __FUNC__, __LINE__, fsd->fsd_FileSystemName)); + stccpy(DeviceName, fsd->fsd_FileSystemName, sizeof(DeviceName)); + FreeDiskFileSystemData(fsd); + } + else + { + stccpy(DeviceName, ((struct Task *) VolumeNode->dol_Task->mp_SigTask)->tc_Node.ln_Name, MaxLen); + } + } +#else //defined(__amigaos4__) + stccpy(DeviceName, ((struct Task *) VolumeNode->dol_Task->mp_SigTask)->tc_Node.ln_Name, MaxLen); +#endif //defined(__amigaos4__) + + sprintf(TextDeviceOnDev, GetLocString(MSGID_DEVICE_ON_DEVNAME), DeviceName); + + d1(KPrintF(__FILE__ "/%s/%ld: DeviceName=<%s>\n", __FUNC__, __LINE__, DeviceName)); + + dl = LockDosList(LDF_DEVICES | LDF_READ); + + dl = FindDosEntry(dl, DeviceName, LDF_DEVICES); + d1(KPrintF(__FILE__ "/%s/%ld: dl=%08lx\n", __FUNC__, __LINE__, dl)); + if (dl) + { + struct FileSysStartupMsg *fsm; + + d1(KPrintF(__FILE__ "/%s/%ld: dl=%08lx Type=%08lx\n", __FUNC__, __LINE__, dl, dl->dol_Type)); + d1(KPrintF(__FILE__ "/%s/%ld: dl=%08lx dol_handler=%08lx\n", __FUNC__, __LINE__, dl, dl->dol_misc.dol_handler.dol_Handler)); + + if (dl->dol_misc.dol_handler.dol_Handler) + { + char Handler[128]; + + BtoCstring(dl->dol_misc.dol_handler.dol_Handler, Handler, sizeof(Handler)); + d1(KPrintF(__FILE__ "/%s/%ld: Handler=<%s>\n", __FUNC__, __LINE__, Handler)); + sprintf(TextDeviceHandler, "%s", Handler); + } + + fsm = BADDR(dl->dol_misc.dol_handler.dol_Startup); + d1(KPrintF(__FILE__ "/%s/%ld: fsm=%08lx\n", __FUNC__, __LINE__, fsm)); + if (fsm) + { + char DevName[128]; + struct DosEnvec *env; + + d1(KPrintF(__FILE__ "/%s/%ld: fssm_Device=%08lx\n", __FUNC__, __LINE__, fsm->fssm_Device)); + + BtoCstring(fsm->fssm_Device, DevName, sizeof(DevName)); + sprintf(TextDeviceName, GetLocString(MSGID_DEVICE_DEVICE_UNIT), DevName, fsm->fssm_Unit); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + env = BADDR(fsm->fssm_Environ); + + d1(KPrintF(__FILE__ "/%s/%ld: env=%08lx\n", __FUNC__, __LINE__, env)); + + if ( 0 == (((ULONG) fsm->fssm_Environ) & 0xc0000000) + && env + && 0 != TypeOfMem((APTR) env) + && env->de_TableSize >= DE_DOSTYPE) + { + sprintf(DosTypeString, GetLocString(MSGID_DEVICE_DOSTYPESTRING), + MakePrintable((env->de_DosType >> 24) & 0xff), + MakePrintable((env->de_DosType >> 16) & 0xff), + MakePrintable((env->de_DosType >> 8) & 0xff), + MakePrintable(env->de_DosType & 0xff)); + } + } + d1(KPrintF(__FILE__ "/%s/%ld: fsm=%08lx\n", __FUNC__, __LINE__, fsm)); + } + + UnLockDosList(LDF_DEVICES | LDF_READ); + } + + if (CR == TextDeviceHandler[strlen(TextDeviceHandler) - 2]) + { + TextDeviceHandler[strlen(TextDeviceHandler) - 2] = '\0'; + strcat(TextDeviceHandler, "\n"); + d1(KPrintF(__FILE__ "/%s/%ld: rt->rt_IdString: TextDeviceHandler - CR =%s\n", __FUNC__, __LINE__, TextDeviceHandler)); + } + + if (strlen(TextDeviceHandler) > 0 && strlen(DosTypeString) > 0) + { + if (LF != TextDeviceHandler[strlen(TextDeviceHandler) - 1]) + strcat(TextDeviceHandler, " "); + strcat(TextDeviceHandler, DosTypeString); + FoundDeviceHandler = TRUE; + } + else if (strlen(TextDeviceHandler) == 0 && strlen(DosTypeString) > 0) // +jmc+ + { + stccpy(TextDeviceHandler, DosTypeString, sizeof(TextDeviceHandler)); + FoundDeviceDosType = TRUE; + d1(KPrintF(__FILE__ "/%s/%ld: TextDeviceHandler: DosTypeString only=<%s>\n", __FUNC__, __LINE__, TextDeviceHandler)); + } + } + + d1(kprintf(__FILE__ "/%s/%ld: DeviceName=<%s>\n", __FUNC__, __LINE__, DeviceName)); + + FreeInfoData(info); + } +} + +//---------------------------------------------------------------------------- + +static BOOL ReadScalosPrefs(void) +{ + CONST_STRPTR MainPrefsFileName = "ENV:Scalos/Scalos.prefs"; + APTR MainPrefsHandle; + + MainPrefsHandle = AllocPrefsHandle((STRPTR) "Scalos"); + if (NULL == MainPrefsHandle) + return FALSE; + + ReadPrefsHandle(MainPrefsHandle, (STRPTR) MainPrefsFileName); + + GetPreferences(MainPrefsHandle, ID_MAIN, SCP_LoadDefIconsFirst, &prefDefIconsFirst, sizeof(prefDefIconsFirst)); + prefDefIconPath = GetPrefsConfigString(MainPrefsHandle, SCP_PathsDefIcons, prefDefIconPath); + + if (prefDefIconPath) + prefDefIconPath = strdup(prefDefIconPath); + + FreePrefsHandle(MainPrefsHandle); + + return TRUE; +} + +static CONST_STRPTR GetPrefsConfigString(APTR prefsHandle, ULONG Id, CONST_STRPTR DefaultString) +{ + struct PrefsStruct *ps = FindPreferences(prefsHandle, ID_MAIN, Id); + + if (ps) + return (CONST_STRPTR) PS_DATA(ps); + + return DefaultString; +} + +//---------------------------------------------------------------------------- + +static void StripTrailingChar(STRPTR String, char CharToRemove) +{ + size_t Len = strlen(String); + + if (Len > 0 && CharToRemove == String[Len - 1]) + String[Len - 1] = '\0'; +} + +//---------------------------------------------------------------------------- + +static void BuildDefVolumeNameNoSpace(STRPTR Buffer, CONST_STRPTR VolumeName, size_t MaxLength) +{ + STRPTR dlp; + size_t Len; + + strcpy(Buffer, "def_"); + + Len = MaxLength - 1 - strlen(Buffer); + + dlp = Buffer + strlen(Buffer); + while (Len && *VolumeName) + { + if (' ' != *VolumeName) + { + *dlp++ = *VolumeName; + Len--; + } + VolumeName++; + } + *dlp = '\0'; +} + +//---------------------------------------------------------------------------- + +static STRPTR ScaFormatString(CONST_STRPTR formatString, STRPTR Buffer, size_t MaxLen, LONG NumArgs, ...) +{ + va_list args; + + va_start(args, NumArgs); + + if (InformationLocale) + { + ULONG *ArgArray; + + ArgArray = malloc(sizeof(ULONG) * NumArgs); + if (ArgArray) + { + struct FormatDateHookData fd; + struct Hook fmtHook; + ULONG n; + STATIC_PATCHFUNC(FormatDateHookFunc) + + for (n = 0; n < NumArgs; n++) + ArgArray[n] = va_arg(args, LONG); + + fmtHook.h_Entry = (HOOKFUNC) PATCH_NEWFUNC(FormatDateHookFunc); + fmtHook.h_Data = &fd; + + fd.fdhd_Buffer = Buffer; + fd.fdhd_Length = MaxLen; + + FormatString(InformationLocale, (STRPTR) formatString, ArgArray, &fmtHook); + + free(ArgArray); + } + } + else + { + vsprintf(Buffer, formatString, args); + } + + va_end(args); + + return Buffer; +} + +//---------------------------------------------------------------------------- + +static void ScaFormatDate(struct DateTime *dt, ULONG DayMaxLen, ULONG DateMaxLen, ULONG TimeMaxLen) +{ + if (InformationLocale) + { + struct FormatDateHookData fd; + struct Hook fmtHook; + STATIC_PATCHFUNC(FormatDateHookFunc) + + d1(kprintf(__FILE__ "/%s/%ld: DateBuff=%08lx Len=%ld TimeBuff=%08lx Len=%ld\n", \ + __FUNC__, __LINE__, dt->dat_StrDate, DateMaxLen, dt->dat_StrTime, DateMaxLen)); + + fmtHook.h_Entry = (HOOKFUNC) PATCH_NEWFUNC(FormatDateHookFunc); + fmtHook.h_Data = &fd; + + if (dt->dat_StrDay) + { + fd.fdhd_Buffer = dt->dat_StrDay; + fd.fdhd_Length = DayMaxLen; + + FormatDate(InformationLocale, "%A", + &dt->dat_Stamp, &fmtHook); + } + + if (dt->dat_StrDate) + { + fd.fdhd_Buffer = dt->dat_StrDate; + fd.fdhd_Length = DateMaxLen; + + FormatDate(InformationLocale, InformationLocale->loc_ShortDateFormat, + &dt->dat_Stamp, &fmtHook); + } + + if (dt->dat_StrTime) + { + fd.fdhd_Buffer = dt->dat_StrTime; + fd.fdhd_Length = TimeMaxLen; + + FormatDate(InformationLocale, InformationLocale->loc_ShortTimeFormat, + &dt->dat_Stamp, &fmtHook); + } + } + else + { + DateToStr(dt); // no size checking possible here :( + } +} + +//---------------------------------------------------------------------------- + +static M68KFUNC_P3(void, FormatDateHookFunc, + A0, struct Hook *, theHook, + A2, struct Locale *, locale, + A1, char, ch) +{ + struct FormatDateHookData *fd = (struct FormatDateHookData *) theHook->h_Data; + + (void) locale; + + if (fd->fdhd_Length >= 1) + { + *(fd->fdhd_Buffer)++ = ch; + fd->fdhd_Length--; + } +} +M68KFUNC_END + +//---------------------------------------------------------------------------- + +static void BtoCstring(BSTR bstr, STRPTR Buffer, size_t BuffLen) +{ +#ifdef __AROS__ + // AROS needs special handling because it uses NULL-terminated + // strings on some platforms. + size_t Len = AROS_BSTR_strlen(bstr); + if (Len >= BuffLen) + Len = BuffLen - 2; + strncpy(Buffer, AROS_BSTR_ADDR(bstr), Len); + Buffer[Len] = '\0'; +#else + const char *bString = BADDR(bstr); + + *Buffer = '\0'; + + if ( 0 == (((ULONG) bstr) & 0xc0000000) && bString && 0 != TypeOfMem((APTR) bString) ) + { + size_t Len = *bString; + + if (Len >= BuffLen) + Len = BuffLen - 2; + + strncpy(Buffer, bString + 1, Len); + Buffer[Len] = '\0'; + } +#endif +} + +//---------------------------------------------------------------------------- + +static void ByteCount(STRPTR Buffer, size_t BuffLen, LONG NumBlocks, LONG BytesPerBlock) +{ + CONST_STRPTR Decimal; + + if (InformationLocale) + Decimal = InformationLocale->loc_DecimalPoint; + else + Decimal = "."; + + // Normalize block size to KBytes + while (BytesPerBlock > 1024) + { + BytesPerBlock >>= 1; + NumBlocks <<= 1; + } + while (BytesPerBlock < 1024) + { + BytesPerBlock <<= 1; + NumBlocks >>= 1; + } + + d1(KPrintF(__FILE__ "/%s/%ld: NumBlocks=%lu\n", __FUNC__, __LINE__, NumBlocks)); + + if (NumBlocks > 2 * 1024 * 1024) + { + // > 2 GB + ULONG GBytes = NumBlocks / (1024 * 1024); + ULONG MBytes = NumBlocks / 1024 - GBytes * 1024; + + d1(KPrintF(__FILE__ "/%s/%ld: GBytes=%lu MBytes=%lu\n", __FUNC__, __LINE__, GBytes, MBytes)); + + if (GBytes > 200) + ScaFormatString(GetLocString(MSGID_BYTES_GB), Buffer, BuffLen, 1, GBytes); + else if (GBytes > 20) + ScaFormatString(GetLocString(MSGID_BYTES_GB_1), Buffer, BuffLen, 3, GBytes, Decimal, MBytes / 100); + else + ScaFormatString(GetLocString(MSGID_BYTES_GB_2), Buffer, BuffLen, 3, GBytes, Decimal, MBytes / 10); + } + else if (NumBlocks > 2 * 1024) + { + // > 2 MB + ULONG MBytes = NumBlocks / 1024; + ULONG KBytes = NumBlocks % 1024; + + if (MBytes > 200) + ScaFormatString(GetLocString(MSGID_BYTES_MB), Buffer, BuffLen, 1, MBytes); + else if (MBytes > 20) + ScaFormatString(GetLocString(MSGID_BYTES_MB_1), Buffer, BuffLen, 3, MBytes, Decimal, KBytes / 100); + else + ScaFormatString(GetLocString(MSGID_BYTES_MB_2), Buffer, BuffLen, 3, MBytes, Decimal, KBytes / 10); + } + else + { + ScaFormatString(GetLocString(MSGID_BYTES_KB), Buffer, BuffLen, 1, NumBlocks); + } + +} + +//---------------------------------------------------------------------------- + +static UBYTE MakePrintable(UBYTE ch) +{ + if (ch < ' ') + ch += '0'; + + return ch; +} + +//---------------------------------------------------------------------------- + +static CONST_STRPTR GetIconTypeName(Object *IconObj) +{ + IPTR IconType; + CONST_STRPTR TypeName; + + GetAttr(IDTA_Type, IconObj, &IconType); + + switch (IconType) + { + case WBDISK: + TypeName = GetLocString(MSGID_ICONTYPE_DISK); + break; + case WBDRAWER: + TypeName = GetLocString(MSGID_ICONTYPE_DRAWER); + break; + case WBTOOL: + TypeName = GetLocString(MSGID_ICONTYPE_TOOL); + break; + case WBPROJECT: + TypeName = GetLocString(MSGID_ICONTYPE_PROJECT); + break; + case WBGARBAGE: + TypeName = GetLocString(MSGID_ICONTYPE_TRASHCAN); + break; + case WBDEVICE: + TypeName = GetLocString(MSGID_ICONTYPE_DEVICE); + break; + case WBKICK: + TypeName = GetLocString(MSGID_ICONTYPE_KICKSTART); + break; + case WBAPPICON: + TypeName = GetLocString(MSGID_ICONTYPE_APPICON); + break; + default: + TypeName = GetLocString(MSGID_ICONTYPE_UNKNOWN); + break; + } + + return TypeName; +} + +//---------------------------------------------------------------------------- + +static const struct FileSysEntry *FindFileSysResEntry(ULONG DosType) +{ + struct FileSysResource *FileSysRes; + + FileSysRes = OpenResource(FSRNAME); + if (FileSysRes) + { + const struct FileSysEntry *fse; + + for (fse = (const struct FileSysEntry *) FileSysRes->fsr_FileSysEntries.lh_Head; + fse != (const struct FileSysEntry *) &FileSysRes->fsr_FileSysEntries.lh_Tail; + fse = (const struct FileSysEntry *) fse->fse_Node.ln_Succ) + { + if (fse->fse_DosType == DosType) + return fse; + } + } + + return NULL; +} + +//---------------------------------------------------------------------------- + +static STRPTR GetChangeDate(BOOL Valid, struct DateStamp *ChangeDate) +{ + if (Valid) + { + char DayBuffer[64], DateBuffer[64], TimeBuffer[64]; + struct DateTime dt; + + memset(&dt, 0, sizeof(dt)); + + dt.dat_Stamp = *ChangeDate; + dt.dat_StrDay = DayBuffer; + dt.dat_StrDate = DateBuffer; + dt.dat_StrTime = TimeBuffer; + + ScaFormatDate(&dt, sizeof(DayBuffer), sizeof(DateBuffer), sizeof(TimeBuffer)); + + sprintf(TextLastChange, "%s, %s %s", DayBuffer, DateBuffer, TimeBuffer); + } + else + { + strcpy(TextLastChange, GetLocString(MSGID_VERSION_NOT_AVAILABLE)); + } + + return TextLastChange; +} + +//---------------------------------------------------------------------------- + +static ULONG GetStackSize(Object *IconObj) +{ + IPTR StackSize = 16384; + + GetAttr(IDTA_Stacksize, IconObj, &StackSize); + + return StackSize; +} + +//---------------------------------------------------------------------------- + +static STRPTR GetDefaultTool(Object *IconObj) +{ + STRPTR DefaultTool = ""; + + GetAttr(IDTA_DefaultTool, IconObj, (APTR)&DefaultTool); + + return DefaultTool ? DefaultTool : (STRPTR) ""; +} + +//---------------------------------------------------------------------------- + +static STRPTR GetVersionString(CONST_STRPTR IconName) +{ +/// + char VersMask[10]; + BPTR fh = (BPTR)NULL; + UBYTE *Buffer; + const size_t BuffLength = 1024; + T_TIMEVAL StartTime, currentTime; + STRPTR VersionString = TextVersion; + size_t MaxLen = sizeof(TextVersion); + + stccpy(VersionString, GetLocString(MSGID_VERSION_NOT_AVAILABLE), MaxLen); + + // do not use statically initalized "$VER" variable here + // since it might confuse the "version" command. + // strcat(VersMask, "VER: "); + stccpy(VersMask, versTag + 1, 6 + 1); + + switch (ScalosExamineGetDirEntryType(fib)) + { + case ST_FILE: + case ST_LINKFILE: + case ST_PIPEFILE: + break; + default: + return TextVersion; + break; + } + + do { + ULONG TotalLen = 0; + LONG ActLen; + ULONG MaskNdx = 0; + BOOL Finished = FALSE; + BOOL Found = FALSE; + + Buffer = malloc(BuffLength); + if (NULL == Buffer) + break; + + CurrentTime((ULONG *)&StartTime.tv_secs, (ULONG *)&StartTime.tv_micro); + + fh = Open(IconName, MODE_OLDFILE); + if ((BPTR)NULL == fh) + break; + + do { + ActLen = Read(fh, Buffer, BuffLength); + + if (ActLen > 0) + { + ULONG n; + UBYTE *BufPtr = Buffer; + + TotalLen += ActLen; + + for (n=0; !Finished && n 1 && *BufPtr && *BufPtr >= ' ' && *BufPtr <= 0x7f) + { + *VersionString++ = *BufPtr++; + MaxLen--; + } + else + Finished = TRUE; + } + else + { + if (*BufPtr++ == VersMask[MaskNdx]) + { + MaskNdx++; + + if (MaskNdx >= strlen(VersMask)) + { + Found = TRUE; + } + } + else + { + MaskNdx = 0; + } + } + } + } + + CurrentTime((ULONG *)¤tTime.tv_secs, (ULONG *)¤tTime.tv_micro); + if ((currentTime.tv_secs - StartTime.tv_secs) > 2) + break; + } while (ActLen > 0 && TotalLen < 0x100000 && !Finished); + } while (0); + + *VersionString = '\0'; + + if (Buffer) + free(Buffer); + if (fh) + Close(fh); + + return TextVersion; +/// +} + +//---------------------------------------------------------------------------- + +static CONST_STRPTR FindVersionString(const UBYTE *block, size_t BlockLen) +{ + static char VersMask[10] = "$"; + + // do not use statically initalized "$VER" variable here + // since it might confuse the "version" command. + strcat(VersMask, "VER: "); + + while (BlockLen--) + { + if (0 == memcmp(VersMask, block, strlen(VersMask))) + return (CONST_STRPTR)(block + strlen(VersMask)); + + block++; + } + + return NULL; +} + +//---------------------------------------------------------------------------- + +const struct Resident *SearchResident(const UWORD *block, size_t BlockLen) +{ + while (BlockLen -= sizeof(UWORD)) + { + const struct Resident *res = (struct Resident *) block; + + if (RTC_MATCHWORD == res->rt_MatchWord && res->rt_MatchTag == res) + return res; + + block++; + } + + return NULL; +} + +//---------------------------------------------------------------------------- + +static void SetGuiFromIconType(Object *IconObj) +{ + IPTR IconType; + + GetAttr(IDTA_Type, IconObj, &IconType); + + SetAttrs(TextTypeName, + MUIA_Text_Contents, GetIconTypeName(IconObj), + TAG_END); + + // Attention: + // Always make sure the "MUIA_ShowMe, FALSE" lines are grouped BEFORE the "MUIA_ShowMe, TRUE" ones. + // Otherwise, the information window will grow substantially in vertical direction. + + switch (IconType) + { + case WBDISK: + SetAttrs(GroupDrawer, MUIA_ShowMe, FALSE, TAG_END); + SetAttrs(GroupProject, MUIA_ShowMe, FALSE, TAG_END); + SetAttrs(GroupTool, MUIA_ShowMe, FALSE, TAG_END); + SetAttrs(GroupDisk, MUIA_ShowMe, TRUE, TAG_END); + SetAttrs(MenuTypeDisk, MUIA_Menuitem_Checked, TRUE, TAG_END); + SetupToolTypes(IconObj, TextEditorToolTypesDevice); + break; + case WBDRAWER: + SetAttrs(GroupDisk, MUIA_ShowMe, FALSE, TAG_END); + SetAttrs(GroupProject, MUIA_ShowMe, FALSE, TAG_END); + SetAttrs(GroupTool, MUIA_ShowMe, FALSE, TAG_END); + SetAttrs(GroupDrawer, MUIA_ShowMe, TRUE, TAG_END); + SetAttrs(MenuTypeDrawer, MUIA_Menuitem_Checked, TRUE, TAG_END); + SetupToolTypes(IconObj, TextEditorToolTypesDrawer); + break; + case WBGARBAGE: + SetAttrs(GroupDisk, MUIA_ShowMe, FALSE, TAG_END); + SetAttrs(GroupProject, MUIA_ShowMe, FALSE, TAG_END); + SetAttrs(GroupTool, MUIA_ShowMe, FALSE, TAG_END); + SetAttrs(GroupDrawer, MUIA_ShowMe, TRUE, TAG_END); + SetAttrs(MenuTypeTrashcan, MUIA_Menuitem_Checked, TRUE, TAG_END); + SetupToolTypes(IconObj, TextEditorToolTypesDrawer); + break; + case WBTOOL: + SetAttrs(GroupDisk, MUIA_ShowMe, FALSE, TAG_END); + SetAttrs(GroupDrawer, MUIA_ShowMe, FALSE, TAG_END); + SetAttrs(GroupProject, MUIA_ShowMe, FALSE, TAG_END); + SetAttrs(GroupTool, MUIA_ShowMe, TRUE, TAG_END); + SetAttrs(MenuTypeTool, MUIA_Menuitem_Checked, TRUE, TAG_END); + SetupToolTypes(IconObj, TextEditorToolTypesTool); + break; + case WBPROJECT: + SetAttrs(GroupDisk, MUIA_ShowMe, FALSE, TAG_END); + SetAttrs(GroupDrawer, MUIA_ShowMe, FALSE, TAG_END); + SetAttrs(GroupTool, MUIA_ShowMe, FALSE, TAG_END); + SetAttrs(GroupProject, MUIA_ShowMe, TRUE, TAG_END); + SetAttrs(MenuTypeProject, MUIA_Menuitem_Checked, TRUE, TAG_END); + SetupToolTypes(IconObj, TextEditorToolTypesProject); + break; + default: + SetAttrs(GroupDisk, MUIA_ShowMe, FALSE, TAG_END); + SetAttrs(GroupDrawer, MUIA_ShowMe, FALSE, TAG_END); + SetAttrs(GroupProject, MUIA_ShowMe, FALSE, TAG_END); + SetAttrs(GroupTool, MUIA_ShowMe, FALSE, TAG_END); + SetAttrs(MenuTypeDisk, MUIA_Menuitem_Checked, TRUE, TAG_END); + break; + } +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT ChangeIconTypeHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct DefIconInfo *dii = (struct DefIconInfo *) hook->h_Data; + ULONG *pNewType = (ULONG *) msg; + + d1(KPrintF(__FILE__ "/%s/%ld: o=%08lx msg=%08lx NewType=%08lx\n", __FUNC__, __LINE__, o, msg, *pNewType)); + + SetAttrs(*dii->dii_IconObjectFromDisk, + IDTA_Type, *pNewType, + TAG_END); + + SetGuiFromIconType(*dii->dii_IconObjectFromDisk); +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT StartFromCycleHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + IPTR StartFrom; + + GetAttr(MUIA_Cycle_Active, o, &StartFrom); + + SetAttrs(ButtonPromptForInputProject, + MUIA_Disabled, (STARTFROM_CLI != StartFrom && STARTFROM_Arexx != StartFrom), + TAG_END); + SetAttrs(ButtonPromptForInputTool, + MUIA_Disabled, (STARTFROM_CLI != StartFrom && STARTFROM_Arexx != StartFrom), + TAG_END); +} + +//---------------------------------------------------------------------------- + +static void ReportError(ULONG MsgId) +{ + LONG ErrorCode; + char Buffer[256]; + + ErrorCode = IoErr(); + Fault(ErrorCode, "", Buffer, sizeof(Buffer)); + + MUI_Request(APP_Main, WIN_Main, 0, NULL, + (STRPTR)GetLocString(MSGID_ERROR_REQ_OK), + (STRPTR)GetLocString(MsgId), + Buffer); +} + +//---------------------------------------------------------------------------- + +static BOOL RenameDevice(CONST_STRPTR OldName, CONST_STRPTR NewName) +{ + STRPTR VolumeName; + BOOL Success = FALSE; + + do { + VolumeName = malloc(1 + 1 + strlen(OldName)); + if (NULL == VolumeName) + break; + + strcpy(VolumeName, OldName); + strcat(VolumeName, ":"); + + if (!Relabel(VolumeName, NewName)) + { + ReportError(MSGID_ERROR_RELABEL); + break; + } + + Success = TRUE; + } while (0); + + if (VolumeName) + free(VolumeName); + + return Success; +} + +//---------------------------------------------------------------------------- + +static BOOL RenameObject(CONST_STRPTR OldName, CONST_STRPTR NewName) +{ + STRPTR OldIconName; + STRPTR NewIconName = NULL; + BOOL Success = FALSE; + + do { + OldIconName = malloc(1 + 5 + strlen(OldName)); + if (NULL == OldIconName) + break; + + NewIconName = malloc(1 + 5 + strlen(NewName)); + if (NULL == NewIconName) + break; + + if (!Rename(OldName, NewName)) + { + ReportError(MSGID_ERROR_RENAME); + break; + } + + strcpy(OldIconName, OldName); + strcat(OldIconName, ".info"); + + strcpy(NewIconName, NewName); + strcat(NewIconName, ".info"); + + if (!Rename(OldIconName, NewIconName)) + { + ReportError(MSGID_ERROR_RENAME); + break; + } + + Success = TRUE; + } while (0); + + if (OldIconName) + free(OldIconName); + if (NewIconName) + free(NewIconName); + + return Success; +} + +//---------------------------------------------------------------------------- + +static void SetupToolTypes(Object *IconObj, Object *TextEditor) +{ + STRPTR *ToolTypesArray = NULL; + STRPTR *TTPtr; + BOOL IsNewIcon = FALSE; + + GetAttr(IDTA_ToolTypes, IconObj, (APTR)&ToolTypesArray); + + for (TTPtr = ToolTypesArray; TTPtr && *TTPtr; TTPtr++) + { + if (ToolTypeNameCmp("*** DON'T EDIT THE FOLLOWING LINES!! ***", *TTPtr) ) + { + IsNewIcon = TRUE; + continue; + } + if (IsNewIcon && ToolTypeNameCmp("IM1", *TTPtr)) + continue; + if (IsNewIcon && ToolTypeNameCmp("IM2", *TTPtr)) + continue; + + if (!ToolTypeNameCmp("CLI", *TTPtr) + && !ToolTypeNameCmp("REXX", *TTPtr) + && !ToolTypeNameCmp("TOOLPRI", *TTPtr) + && !ToolTypeNameCmp("WAIT", *TTPtr) + && !ToolTypeNameCmp("STARTPRI", *TTPtr) + && !ToolTypeNameCmp("DONOTWAIT", *TTPtr) + && !ToolTypeNameCmp("DONOTPROMPT", *TTPtr)) + { + DoMethod(TextEditor, MUIM_TextEditor_InsertText, + *TTPtr, + MUIV_TextEditor_InsertText_Bottom); + DoMethod(TextEditor, MUIM_TextEditor_InsertText, + "\n", + MUIV_TextEditor_InsertText_Bottom); + } + } +} + +//---------------------------------------------------------------------------- + +static void SetChangedToolTypes(Object *IconObj, Object *TextEditor) +{ + IPTR Changed = FALSE; + ULONG ToolTypesCount = 0; + STRPTR Contents = NULL; + STRPTR *ToolTypeArray = NULL; + + do { + CONST_STRPTR lp; + ULONG n; + + GetAttr(MUIA_TextEditor_HasChanged, TextEditor, &Changed); + if (!Changed) + break; + + Contents = (STRPTR) DoMethod(TextEditor, MUIM_TextEditor_ExportText); + if (NULL == Contents) + break; + + get(TextEditor, MUIA_TextEditor_Prop_Entries, &ToolTypesCount); + + ToolTypeArray = calloc(sizeof(STRPTR), 1 + ToolTypesCount); + if (NULL == ToolTypeArray) + break; + + lp = Contents; + n = 0; + while (*lp) + { + CONST_STRPTR Line = lp; + size_t LineLength = 0; + + while (*lp && '\n' != *lp) + { + LineLength++; + lp++; + } + if (*lp) + lp++; // skip LF + + ToolTypeArray[n] = malloc(1 + LineLength); + if (NULL == ToolTypeArray[n]) + break; + + memcpy(ToolTypeArray[n], Line, LineLength); + ToolTypeArray[n][LineLength] = '\0'; + + if (++n >= ToolTypesCount) + break; + } + + SetAttrs(IconObj, + IDTA_ToolTypes, ToolTypeArray, + TAG_END); + + set(TextEditor, MUIA_TextEditor_HasChanged, FALSE); + } while (0); + + if (Contents) + { + FreeVec(Contents); + } + if (ToolTypeArray) + { + STRPTR *lp = ToolTypeArray; + + while (*lp) + { + free(*lp); + *lp = NULL; + lp++; + } + + free(ToolTypeArray); + } +} + +//---------------------------------------------------------------------------- + +static STRPTR GetSizeString(void) +{ + STRPTR SizeString; + + if (FibValid) + { + char ByteCountText[40]; + + Convert64(InformationLocale, ScalosExamineGetSize(fib), ByteCountText, sizeof(ByteCountText)); + + SizeString = ScaFormatString(GetLocString(MSGID_SIZE_FORMAT), TextSize, sizeof(TextSize), + 1, ByteCountText); + } + else + SizeString = (STRPTR)GetLocString(MSGID_VERSION_NOT_AVAILABLE); + + return SizeString; +} + +//---------------------------------------------------------------------------- + +// Checks if a certain version of a MCC is available +static BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev) +{ +/// + BOOL flush = TRUE; + + d1(kprintf("%s/%s/%ld: %s ", __FILE__, __FUNC__, __LINE__, name)); + + while (1) + { + ULONG ver = 0; + ULONG rev = 0; + struct Library *base; + char libname[256]; + + // First we attempt to acquire the version and revision through MUI + Object *obj = MUI_NewObject((STRPTR) name, TAG_DONE); + if (obj) + { + get(obj, MUIA_Version, &ver); + get(obj, MUIA_Revision, &rev); + + MUI_DisposeObject(obj); + + if(ver > minver || (ver == minver && rev >= minrev)) + { + d1(kprintf("%s/%s/%ld: v%ld.%ld found through MUIA_Version/Revision\n", __FILE__, __FUNC__, __LINE__, ver, rev)); + return TRUE; + } + } + + // If we did't get the version we wanted, let's try to open the + // libraries ourselves and see what happens... + stccpy(libname, "PROGDIR:mui", sizeof(libname)); + AddPart(libname, name, sizeof(libname)); + + if ((base = OpenLibrary(&libname[8], 0)) || (base = OpenLibrary(&libname[0], 0))) + { + UWORD OpenCnt = base->lib_OpenCnt; + + ver = base->lib_Version; + rev = base->lib_Revision; + + CloseLibrary(base); + + // we add some additional check here so that eventual broken .mcc also have + // a chance to pass this test (i.e. Toolbar.mcc is broken) + if (ver > minver || (ver == minver && rev >= minrev)) + { + d1(kprintf("%s/%s/%ld: v%ld.%ld found through OpenLibrary()\n", __FILE__, __FUNC__, __LINE__, ver, rev)); + return TRUE; + } + + if (OpenCnt > 1) + { + if (MUI_Request(NULL, NULL, 0L, (STRPTR)GetLocString(MSGID_STARTUP_FAILURE), + (STRPTR)GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), (STRPTR)GetLocString(MSGID_STARTUP_MCC_IN_USE), + name, minver, minrev, ver, rev)) + { + flush = TRUE; + } + else + break; + } + + // Attempt to flush the library if open count is 0 or because the + // user wants to retry (meaning there's a chance that it's 0 now) + + if (flush) + { + struct Library *result; + + Forbid(); + if ((result = (struct Library *) FindName(&((struct ExecBase *)SysBase)->LibList, name))) + RemLibrary(result); + Permit(); + flush = FALSE; + } + else + { + d1(kprintf("%s/%s/%ld: couldn`t find minimum required version.\n", __FILE__, __FUNC__, __LINE__)); + + // We're out of luck - open count is 0, we've tried to flush + // and still haven't got the version we want + if (MUI_Request(NULL, NULL, 0L, (STRPTR)GetLocString(MSGID_STARTUP_FAILURE), + (STRPTR)GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), (STRPTR)GetLocString(MSGID_STARTUP_OLD_MCC), + name, minver, minrev, ver, rev)) + { + flush = TRUE; + } + else + break; + } + } + else + { + // No MCC at all - no need to attempt flush + flush = FALSE; + if (!MUI_Request(NULL, NULL, 0L, (STRPTR)GetLocString(MSGID_STARTUP_FAILURE), + (STRPTR)GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), (STRPTR)GetLocString(MSGID_STARTUP_MCC_NOT_FOUND), + name, minver, minrev)) + { + break; + } + } + } + + return FALSE; +/// +} + +//---------------------------------------------------------------------------- + +static BOOL ToolTypeNameCmp(CONST_STRPTR ToolTypeName, CONST_STRPTR ToolTypeContents) +{ + while (*ToolTypeName && *ToolTypeContents) + { + UBYTE ch1; // Work-around for GCC compiler bug + + if ('=' == *ToolTypeContents) + break; + ch1 = ToLower(*ToolTypeName); + if (ch1 != ToLower(*ToolTypeContents)) + break; + + ToolTypeName++; + ToolTypeContents++; + } + + return (BOOL) ('\0' == *ToolTypeName && ('\0' == *ToolTypeContents || '=' == *ToolTypeContents)); +} + +//---------------------------------------------------------------------------- + +static void GetIconObjectFromWBArg(struct DefIconInfo *dii, struct WBArg *arg, + STRPTR FileTypeName, size_t FileTypeNameSize) +{ + ULONG Pos; + STRPTR NewIconName; + + d1(KPrintF(__FILE__ "/%s/%ld: wa_Lock=%08lx wa_Name=<%s>\n", __FUNC__, __LINE__, arg->wa_Lock, arg->wa_Name)); + + if (*dii->dii_IconObjectFromDisk) + { + DisposeIconObject(*dii->dii_IconObjectFromDisk); + *dii->dii_IconObjectFromDisk = NULL; + } + if (*dii->dii_IconObjectFromScalos) + { + DisposeIconObject(*dii->dii_IconObjectFromScalos); + *dii->dii_IconObjectFromScalos = NULL; + } + + if (IsDevice(arg)) + { + static char VolumeName[128]; + char DeviceName[128]; + + d1(KPrintF(__FILE__ "/%s/%ld:\n", __FUNC__, __LINE__)); + + NewIconName = "disk"; + + NameFromLock(arg->wa_Lock, VolumeName, sizeof(VolumeName)); + GetDeviceName(arg->wa_Lock, VolumeName, DeviceName, sizeof(DeviceName)); + + d1(kprintf(__FILE__ "/%s/%ld: VolumeName=<%s>\n", __FUNC__, __LINE__, VolumeName)); + + StripTrailingChar(VolumeName, ':'); + StripTrailingChar(DeviceName, ':'); + + d1(kprintf(__FILE__ "/%s/%ld: VolumeName=<%s>\n", __FUNC__, __LINE__, VolumeName)); + d1(kprintf(__FILE__ "/%s/%ld: DeviceName=<%s>\n", __FUNC__, __LINE__, DeviceName)); + + GetDeviceIconObject(dii, NewIconName, VolumeName, DeviceName, FileTypeName, FileTypeNameSize); + + if (*dii->dii_IconObjectFromDisk) + { + SetAttrs(*dii->dii_IconObjectFromDisk, + IDTA_Type, WBDISK, + TAG_END); + + FoundDeviceFromArg = TRUE; + } + } + else + { + char xName[128]; + + d1(KPrintF(__FILE__ "/%s/%ld:\n", __FUNC__, __LINE__)); + + stccpy(xName, arg->wa_Name, sizeof(xName)); + Pos = IsIconName(xName); + + if (Pos && ~0 != Pos) + { + // strip ".info" from name + *((char *) Pos) = '\0'; + } + + GetIconObject(dii, xName, arg->wa_Lock, FileTypeName, FileTypeNameSize); + + NameFromLock(arg->wa_Lock,PathName,sizeof(PathName)); + } +} + +//---------------------------------------------------------------------------- + +static BOOL RemoveDropZoneForObject(Object *o) +{ + struct DropZone *dz; + + for (dz = (struct DropZone *) DropZoneList.lh_Head; + dz != (struct DropZone *) &DropZoneList.lh_Tail; + dz = (struct DropZone *) dz->dz_Node.ln_Succ) + { + if (dz->dz_Object == o) + { + Remove(&dz->dz_Node); + + if (myAppWindow && dz->dz_DropZone) + RemoveAppWindowDropZone(myAppWindow, dz->dz_DropZone); + + free(dz); + + return TRUE; // found + } + } + + return FALSE; // not found +} + +//---------------------------------------------------------------------------- + +static void AddDropZoneForObject(Object *o, DropZoneHandler Handler) +{ + struct DropZone *dz; + + d1(KPrintF("%s/%ld: o=%08lx\n", __FUNC__, __LINE__, o)); + + if (WorkbenchBase->lib_Version < 44) + return; + + // if a dropzone already exists for this object, remove it + RemoveDropZoneForObject(o); + + // Now create new dropzone for this object + do { + ULONG Left = 0, Top = 0, Width = 0, Height = 0; + + dz = malloc(sizeof(struct DropZone)); + if (NULL == dz) + break; + + dz->dz_Object = o; + dz->dz_Handler = Handler; + + get(o, MUIA_LeftEdge, &Left); + get(o, MUIA_TopEdge, &Top); + get(o, MUIA_Width, &Width); + get(o, MUIA_Height, &Height); + + d1(KPrintF("%s/%ld: o=%08lx Left=%ld Top=%ld Width=%ld Height=%ld\n", __FUNC__, __LINE__, o, Left, Top, Width, Height)); + + dz->dz_Box.Left = Left; + dz->dz_Box.Top = Top; + dz->dz_Box.Width = Width; + dz->dz_Box.Height = Height; + + if (myAppWindow && Width && Height) + { + // AddAppWindowDropZoneA() + dz->dz_DropZone = AddAppWindowDropZone(myAppWindow, 0, + (ULONG) dz, + WBDZA_Hook, (ULONG) &AppWindowDropZoneHook, + WBDZA_Box, (ULONG) &dz->dz_Box, + TAG_END); + + d1(KPrintF("%s/%ld: dz_DropZone=%08lx\n", __FUNC__, __LINE__, dz->dz_DropZone)); + if (NULL == dz->dz_DropZone) + break; + } + + AddTail(&DropZoneList, &dz->dz_Node); + dz = NULL; + } while (0); + + // If we did not succeed, free allocated DropZone + if (dz) + free(dz); +} + +//---------------------------------------------------------------------------- + +static void AdjustDropZones(void) +{ + struct DropZone *dz; + + for (dz = (struct DropZone *) DropZoneList.lh_Head; + dz != (struct DropZone *) &DropZoneList.lh_Tail; + dz = (struct DropZone *) dz->dz_Node.ln_Succ) + { + struct MUI_AreaData *mad; + + mad = muiAreaData(dz->dz_Object); + + if (mad) + { + if (((mad->mad_Flags & MADF_OBJECTVISIBLE) && NULL == dz->dz_DropZone) + || (!(mad->mad_Flags & MADF_OBJECTVISIBLE) && dz->dz_DropZone) + || mad->mad_Box.Left != dz->dz_Box.Left + || mad->mad_Box.Top != dz->dz_Box.Top + || mad->mad_Box.Width != dz->dz_Box.Width + || mad->mad_Box.Height != dz->dz_Box.Height) + { + d1(KPrintF("%s/%ld: myAppWindow=%08lx Left=%ld Top=%ld Width=%ld Height=%ld\n", __FUNC__, __LINE__, myAppWindow, mad->mad_Box.Left, mad->mad_Box.Top, mad->mad_Box.Width, mad->mad_Box.Height)); + + dz->dz_Box = mad->mad_Box; + + if (dz->dz_DropZone) + RemoveAppWindowDropZone(myAppWindow, dz->dz_DropZone); + + if (mad->mad_Flags & MADF_OBJECTVISIBLE) + { + dz->dz_DropZone = AddAppWindowDropZone(myAppWindow, 0, + (ULONG) dz, + WBDZA_Hook, (ULONG) &AppWindowDropZoneHook, + WBDZA_Box, (ULONG) &dz->dz_Box, + TAG_END); + } + else + { + dz->dz_DropZone = NULL; + } + } + } + } +} + +//---------------------------------------------------------------------------- + +static void HandleDropOnIcon(struct WBArg *arg, Object *o, struct DefIconInfo *dii) +{ + BPTR OldDir; + Object *OldIconObj = *dii->dii_IconObjectFromDisk; + + (void) o; + + *dii->dii_IconObjectFromDisk = NULL; + + OldDir = CurrentDir(arg->wa_Lock); + + d1(KPrintF(__FILE__ "/%s/%ld: wa_Lock=%08lx wa_Name=<%s>\n", __FUNC__, __LINE__, arg->wa_Lock, arg->wa_Name)); + + GetIconObjectFromWBArg(dii, arg, TextFileTypeName, sizeof(TextFileTypeName)); + + if (*dii->dii_IconObjectFromDisk) + ReplaceIcon(*dii->dii_IconObjectFromDisk, &OldIconObj); + else + DisposeIconObject(OldIconObj); + + CurrentDir(OldDir); +} + +//---------------------------------------------------------------------------- + +static void HandleDropOnString(struct WBArg *arg, Object *o, struct DefIconInfo *dii) +{ + d1(KPrintF(__FILE__ "/%s/%ld: wa_Lock=%08lx wa_Name=<%s>\n", __FUNC__, __LINE__, arg->wa_Lock, arg->wa_Name)); + + (void) dii; + + do { + char Path[MAX_PATH_SIZE]; + struct MUI_AreaData *mad; + + if (!NameFromLock(arg->wa_Lock, Path, sizeof(Path))) + break; + + if (!AddPart(Path, arg->wa_Name, sizeof(Path))) + break; + + mad = muiAreaData(o); + if (NULL == mad) + break; + d1(KPrintF(__FILE__ "/%s/%ld: mad=%08lx mad_Flags=%08lx\n", __FUNC__, __LINE__, mad, mad->mad_Flags)); + if (!(mad->mad_Flags & MADF_OBJECTVISIBLE)) + break; + + set(o, MUIA_String_Contents, Path); + } while (0); +} + +//---------------------------------------------------------------------------- + +static void HandleDropOnName(struct WBArg *arg, Object *o, struct DefIconInfo *dii) +{ + d1(KPrintF(__FILE__ "/%s/%ld: wa_Lock=%08lx wa_Name=<%s>\n", __FUNC__, __LINE__, arg->wa_Lock, arg->wa_Name)); + + (void) dii; + + do { + struct MUI_AreaData *mad; + char Path[MAX_PATH_SIZE]; + STRPTR Name = arg->wa_Name; + + if (NULL == arg->wa_Name || strlen(arg->wa_Name) < 1) + { + if (!NameFromLock(arg->wa_Lock, Path, sizeof(Path))) + break; + Name = FilePart(Path); + } + if (NULL == Name) + break; + + mad = muiAreaData(o); + if (NULL == mad) + break; + d1(KPrintF(__FILE__ "/%s/%ld: mad=%08lx mad_Flags=%08lx\n", __FUNC__, __LINE__, mad, mad->mad_Flags)); + if (!(mad->mad_Flags & MADF_OBJECTVISIBLE)) + break; + + set(o, MUIA_String_Contents, Name); + } while (0); +} + +//---------------------------------------------------------------------------- + +static void HandleDropOnToolTypes(struct WBArg *arg, Object *o, struct DefIconInfo *dii) +{ + BPTR OldDir; + + OldDir = CurrentDir(arg->wa_Lock); + + d1(KPrintF(__FILE__ "/%s/%ld: wa_Lock=%08lx wa_Name=<%s>\n", __FUNC__, __LINE__, arg->wa_Lock, arg->wa_Name)); + + GetIconObjectFromWBArg(dii, arg, TextFileTypeName, sizeof(TextFileTypeName)); + + if (*dii->dii_IconObjectFromDisk) + { + DoMethod(o, MUIM_TextEditor_ClearText); + SetupToolTypes(*dii->dii_IconObjectFromDisk, o); + } + + CurrentDir(OldDir); +} + +//---------------------------------------------------------------------------- + +static BOOL CheckIsWBStartup(BPTR DirLock) +{ + BPTR WbStartupLock; + BPTR ParentLock; + BPTR NewDirLock = (BPTR)NULL; + BOOL IsWBStartup = FALSE; + + do { + WbStartupLock = Lock("SYS:WBStartup", ACCESS_READ); + if ((BPTR)NULL == WbStartupLock) + break; + + while (1) + { + if (LOCK_SAME == SameLock(DirLock, WbStartupLock)) + { + IsWBStartup = TRUE; + break; + } + + ParentLock = ParentDir(DirLock); + if ((BPTR)NULL == ParentLock) + break; // we have reached root + + if (NewDirLock) + UnLock(NewDirLock); + NewDirLock = ParentLock; + + DirLock = ParentLock; + } + } while (0); + + if (NewDirLock) + UnLock(NewDirLock); + if (WbStartupLock) + UnLock(WbStartupLock); + + return IsWBStartup; +} + +//---------------------------------------------------------------------------- + +static void ScaFormatStringMaxLength(char *Buffer, size_t BuffLen, const char *Format, ...) +{ + va_list Args; + + va_start(Args, Format); + + ScaFormatStringArgs(Buffer, BuffLen, Format, Args); + + va_end(Args); +} + +//----------------------------------------------------------------------------------- + +static void ScaFormatStringArgs(char *Buffer, size_t BuffLength, const char *Format, APTR Args) +{ + // here converting %lU und %lD format strings to lower case + // because sprintf doesn't recognize them + char *FormatCopy; + + FormatCopy = AllocCopyString(Format); + d1(kprintf("%s/%s/%ld: ALLOC FormatCopy=%08lx\n", __FILE__, __FUNC__, __LINE__, FormatCopy)); + if (FormatCopy) + { + char *p; + + p = strstr(Format, "%lU"); + if (p) + p[2] = 'u'; + + p = strstr(Format, "%lD"); + if (p) + p[2] = 'd'; + + vsprintf(Buffer, Format, Args); + d1(kprintf("%s/%s/%ld: FREE FormatCopy=%08lx\n", __FILE__, __FUNC__, __LINE__, FormatCopy)); + FreeCopyString(FormatCopy); + } +} + +//---------------------------------------------------------- + +static STRPTR AllocCopyString(CONST_STRPTR clp) +{ + STRPTR lp; + + if (NULL == clp) + clp = ""; + + lp = AllocVec(1 + strlen(clp), MEMF_PUBLIC); + if (lp) + strcpy(lp, clp); + + d1(KPrintF("%s/%s/%ld: kp=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, lp, clp)); + + return lp; +} + + +static void FreeCopyString(STRPTR lp) +{ + d1(KPrintF("%s/%s/%ld: lp=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, lp, lp)); + if (lp) + FreeVec(lp); +} + +//---------------------------------------------------------- + +static Object *GetIconObjectFromScalos(BPTR DirLock, CONST_STRPTR IconName, + STRPTR FileTypeName, size_t FileTypeNameSize) +{ + struct ScaWindowList *WinList = NULL; + Object *IconObj = NULL; + + d1(KPrintF(__FILE__ "/%s/%ld: IconName=<%s>\n", __FUNC__, __LINE__, IconName)); + + WinList = SCA_LockWindowList(SCA_LockWindowList_Shared); + d1(KPrintF(__FILE__ "/%s/%ld: WinList=%08lx\n", __FUNC__, __LINE__, WinList)); + if (WinList) + { + struct ScaWindowStruct *ws; + + for (ws = WinList->wl_WindowStruct; (NULL == IconObj) && ws; ws = (struct ScaWindowStruct *) ws->ws_Node.mln_Succ) + { + if ((BPTR) NULL == ws->ws_Lock + || LOCK_SAME == SameLock(ws->ws_Lock, DirLock)) + { + struct ScaWindowTask *wt = ws->ws_WindowTask; + struct ScaIconNode *in; + + ObtainSemaphoreShared(wt->wt_IconSemaphore); + + for (in = wt->wt_IconList; (NULL == IconObj) && in; in = (struct ScaIconNode *) in->in_Node.mln_Succ) + { + CONST_STRPTR Name = NULL; + + GetAttr(IDTA_Text, in->in_Icon, (APTR) &Name); + + if ( (((BPTR) NULL == ws->ws_Lock && in->in_Lock && LOCK_SAME == SameLock(in->in_Lock, DirLock)) + || (LOCK_SAME == SameLock(ws->ws_Lock, DirLock))) + && (Name && 0 == Stricmp(IconName, Name)) ) + { + struct TagItem CloneTags[1]; + + GetIconFileType(wt, in, FileTypeName, FileTypeNameSize); + + CloneTags[0].ti_Tag = TAG_END; + + if (SCAV_ViewModes_Icon != ws->ws_Viewmodes) + { + //GetAttr(TIDTA_IconObject, in->in_Icon, (ULONG *) &IconObj); + IconObj = NULL; + } + else + { + IconObj = (Object *) DoMethod(in->in_Icon, + IDTM_CloneIconObject, CloneTags); + } + + d1(KPrintF(__FILE__ "/%s/%ld: IconObj=%08lx\n", __FUNC__, __LINE__, IconObj)); + + if (IconObj) + { + SetAttrs(IconObj, + IDTA_InnerTop, 0, + IDTA_InnerLeft, 0, + IDTA_InnerBottom, 0, + IDTA_InnerRight, 0, + IDTA_FrameType, MF_FRAME_NONE, + IDTA_FrameTypeSel, MF_FRAME_NONE, + TAG_END); + } + } + } + + ReleaseSemaphore(wt->wt_IconSemaphore); + } + } + + SCA_UnLockWindowList(); + } + + d1(KPrintF(__FILE__ "/%s/%ld: IconObj=%08lx\n", __FUNC__, __LINE__, IconObj)); + + return IconObj; +} + +//---------------------------------------------------------- +#if 0 +static Object *GetDeviceIconObjectFromScalos(BPTR dLock, + STRPTR FileTypeName, size_t FileTypeNameSize) +{ + struct ScaWindowList *WinList = NULL; + Object *IconObj = NULL; + + d1(KPrintF(__FILE__ "/%s/%ld: dLock=%08lx\n", __FUNC__, __LINE__, dLock)); + + WinList = SCA_LockWindowList(SCA_LockWindowList_Shared); + d1(KPrintF(__FILE__ "/%s/%ld: WinList=%08lx\n", __FUNC__, __LINE__, WinList)); + if (WinList) + { + struct ScaWindowStruct *ws; + + for (ws = WinList->wl_WindowStruct; (NULL == IconObj) && ws; ws = (struct ScaWindowStruct *) ws->ws_Node.mln_Succ) + { + if ((BPTR) NULL == ws->ws_Lock) + { + // This is the desktop window + struct ScaWindowTask *wt = ws->ws_WindowTask; + struct ScaIconNode *in; + struct FileLock *fl = (struct FileLock *) BADDR(dLock); + + ObtainSemaphoreShared(wt->wt_IconSemaphore); + + for (in = wt->wt_IconList; (NULL == IconObj) && in; in = (struct ScaIconNode *) in->in_Node.mln_Succ) + { + d1(KPrintF(__FILE__ "/%s/%ld: in=%08lx <%s>\n", __FUNC__, __LINE__, in, in->in_Name)); + if (in->in_DeviceIcon) + { + const struct ScaDeviceIcon *di = in->in_DeviceIcon; + + if ( fl->fl_Task == di->di_Handler ) + { + struct TagItem CloneTags[1]; + + GetIconFileType(wt, in, FileTypeName, FileTypeNameSize); + + CloneTags[0].ti_Tag = TAG_END; + + IconObj = (Object *) DoMethod(in->in_Icon, + IDTM_CloneIconObject, CloneTags); + d1(KPrintF(__FILE__ "/%s/%ld: IconObj=%08lx\n", __FUNC__, __LINE__, IconObj)); + + if (IconObj && (SCAV_ViewModes_Icon != ws->ws_Viewmodes)) + { + GetAttr(TIDTA_IconObject, IconObj, (ULONG *) &IconObj); + } + + if (IconObj) + { + SetAttrs(IconObj, + IDTA_InnerTop, 0, + IDTA_InnerLeft, 0, + IDTA_InnerBottom, 0, + IDTA_InnerRight, 0, + IDTA_FrameType, MF_FRAME_NONE, + IDTA_FrameTypeSel, MF_FRAME_NONE, + TAG_END); + } + } + } + } + + ReleaseSemaphore(wt->wt_IconSemaphore); + break; + } + } + + SCA_UnLockWindowList(); + } + + d1(KPrintF(__FILE__ "/%s/%ld: IconObj=%08lx\n", __FUNC__, __LINE__, IconObj)); + + return IconObj; +} +#endif +//---------------------------------------------------------- + +static void GetIconFileType(struct ScaWindowTask *wt, struct ScaIconNode *in, + STRPTR FileTypeName, size_t FileTypeNameSize) +{ + DoMethod(wt->mt_MainObject, SCCM_IconWin_GetIconFileType, in); + + d1(KPrintF(__FILE__ "/%s/%ld: in=%08lx <%s> in_FileType=%08lx\n", __FUNC__, __LINE__, in, in->in_Name, in->in_FileType)); + + switch ((ULONG) in->in_FileType) + { + case WBDRAWER: + case WB_TEXTICON_DRAWER: + stccpy(FileTypeName, GetLocString(MSGID_FILETYPE_DRAWER), FileTypeNameSize); + break; + + case WBGARBAGE: + stccpy(FileTypeName, GetLocString(MSGID_FILETYPE_GARBAGE), FileTypeNameSize); + break; + + case WBDISK: + stccpy(FileTypeName, GetLocString(MSGID_FILETYPE_DISK), FileTypeNameSize); + break; + + case WBTOOL: + case WB_TEXTICON_TOOL: // Text Tool + stccpy(FileTypeName, GetLocString(MSGID_FILETYPE_TOOL), FileTypeNameSize); + break; + + case WBPROJECT: + stccpy(FileTypeName, GetLocString(MSGID_FILETYPE_PROJECT), FileTypeNameSize); + break; + + case WBAPPICON: + stccpy(FileTypeName, GetLocString(MSGID_FILETYPE_APPICON), FileTypeNameSize); + break; + + default: + if ( 0 != TypeOfMem((APTR) in->in_FileType) ) + { + const struct TypeNode *tn = (const struct TypeNode *) in->in_FileType; + + stccpy(FileTypeName, tn->tn_Name, FileTypeNameSize); + } + break; + } +} + +//---------------------------------------------------------- + +static struct InfoData *AllocInfoData(void) +{ +#ifdef __amigaos4__ + return (struct InfoData *) AllocDosObject(DOS_INFODATA, NULL); +#else // __amigaos4__ + return (struct InfoData *) malloc(sizeof(struct InfoData)); +#endif //__amigaos4__ +} + +// ---------------------------------------------------------- + +static void FreeInfoData(struct InfoData *pId) +{ + if (pId) + { +#ifdef __amigaos4__ + FreeDosObject(DOS_INFODATA, pId); +#else // __amigaos4__ + free(pId); +#endif //__amigaos4__ + } +} + +// ---------------------------------------------------------- + +static struct ScaWindowStruct *FindScalosWindow(BPTR dirLock) +{ + struct ScaWindowList *wl; + BOOL Found = FALSE; + + d1(KPrintF(__FILE__ "/%s/%ld: START \n", __FUNC__, __LINE__)); + + wl = SCA_LockWindowList(SCA_LockWindowList_Shared); + + if (wl) + { + struct ScaWindowStruct *ws; + + for (ws = wl->wl_WindowStruct; !Found && ws; ws = (struct ScaWindowStruct *) ws->ws_Node.mln_Succ) + { + if (((BPTR) NULL == dirLock && (BPTR) NULL == ws->ws_Lock) || (LOCK_SAME == SameLock(dirLock, ws->ws_Lock))) + { + return ws; + } + } + SCA_UnLockWindowList(); + } + + return NULL; +} + +//---------------------------------------------------------------------------- + diff --git a/scalos/Modules/Information.MUI/Information.cd b/scalos/Modules/Information.MUI/Information.cd new file mode 100755 index 000000000..d16fea1a2 --- /dev/null +++ b/scalos/Modules/Information.MUI/Information.cd @@ -0,0 +1,583 @@ +; Information.cd +; version $VER: Information.catalog 40.1 (20 Feb 2005 21:03:45) +; codeset 0s +; language english +; +;#arrayopts static __far +; +; +MSGID_TITLENAME (//) +Scalos Information +; +; +MSGID_OKBUTTON (//) +Save +; +; +MSGID_SHORTHELP_OKBUTTON (//) +Save the changed icon.\n\ +If necessary, a new icon will be\n\ +created from a the default icon. +; +; +MSGID_CANCELBUTTON (//) +Cancel +; +; +MSGID_SHORTHELP_CANCELBUTTON (//) +Discard all changes and\n\ +leave the icon unchanged. +; +; +MSGID_CREATE_APPLICATION_FAILED (//) +Failed to create Application.\n +; +; +MSGID_CREATE_MAINWINDOW_FAILED (//) +Failed to open main window !\n +; +; +MSGID_OPEN_LIBRARY_FAILED (//) +Failed to open \"%s\" !\n +; +;;----------------------------------------------------------- +; +MSGID_MENU_PROJECT (2000//) +Project +; +; +MSGID_MENU_PROJECT_ABOUT (//) +About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI (//) +About MUI... +; +; +MSGID_MENU_PROJECT_QUIT (//) +Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT (//) +Q +; +; +MSGID_MENU_TYPE (//) +Type +; +; +MSGID_MENU_TYPE_DISK (//) +Disk +; +; +MSGID_MENU_TYPE_DRAWER (//) +Drawer +; +; +MSGID_MENU_TYPE_PROJECT (//) +Project +; +; +MSGID_MENU_TYPE_TOOL (//) +Tool +; +; +MSGID_MENU_TYPE_TRASHCAN (//) +Trashcan +; +; +MSGID_MENU_IMAGE (//) +Icon Image +; +; +MSGID_MENU_IMAGE_DEFAULT (//) +Default +; +; +MSGID_MENU_IMAGE_DEFAULT_SHORT (/1/1) +D +; +; +MSGID_MENU_OPTIONS (//) +Options +; +; +MSGID_MENU_ALWAYS_ICONPATH (//) +Always display icon path +; +; +MSGID_MENU_ALWAYS_ICONPATH_SHORT (/1/1) +P +; +; +MSGID_MENU_ALWAYS_GETSIZE (//) +Always get size +; +; +MSGID_MENU_ALWAYS_GETSIZE_SHORT (/1/1) +G +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK (3000//) +_OK +; +; +MSGID_ABOUTREQFORMAT (//) +\33c\033bScalos Information.module V%ld.%ld\033n\n\ +%s\n\ +© 2004%s The Scalos Team +; +;----------------------------------------------------------- +; +MSGID_DEVICE_DEVICE (4000//) +Device: +; +; +MSGID_DEVICE_HANDLER (//) +Handler: +; +; +MSGID_DEVICE_CREATED_ON (//) +Created on: +; +; +MSGID_DEVICE_SPACE_USED (//) +Used: +; +; +MSGID_DEVICE_SPACE_FREE (//) +Free: +; +; +MSGID_DEVICE_SIZE (//) +Size: +; +; +MSGID_DEVICE_BLOCK_SIZE (//) +Block size: +; +; +MSGID_DEVICE_STATE (//) +State: +; +; +MSGID_DEVICE_BLOCKS_PERCENT (//) +%s (%lD Blocks, %lD%%) +; +; +MSGID_DEVICE_BLOCKS (//) +%s (%lD Blocks) +; +; +MSGID_DEVICE_DISKSTATE_READONLY (//) +read-only +; +; +MSGID_DEVICE_DISKSTATE_VALIDATING (//) +validating +; +; +MSGID_DEVICE_DISKSTATE_READ_WRITE (//) +read-/writable +; +; +MSGID_DEVICE_DISKSTATE_UNKNOWN (//) +??unknown?? +; +; +MSGID_DEVICE_BLOCKSIZE_BYTES (//) +%lD bytes +; +; +MSGID_DEVICE_HANDLER_DISKID (//) +%s %ld.%ld +; +; +MSGID_DEVICE_ON_DEVNAME (//) +on %s +; +; +MSGID_DEVICE_DEVICE_UNIT (//) +%s, %ld +; +;----------------------------------------------------------- +; +MSGID_LASTCHANGE (5000//) +Last change: +; +; +MSGID_SIZE (//) +Size: +; +; +MSGID_SIZE_FORMAT (//) +%s bytes +; +; +MSGID_PROTECTION (//) +Protection: +; +; +MSGID_PROTECTION_READ (//) +Read +; +; +MSGID_PROTECTION_WRITE (//) +Write +; +; +MSGID_PROTECTION_ARCHIVE (//) +Archive +; +; +MSGID_PROTECTION_DELETE (//) +Delete +; +; +MSGID_PROTECTION_EXECUTE (//) +Execute +; +; +MSGID_PROTECTION_SCRIPT (//) +Script +; +; +MSGID_PROTECTION_READ_SHORTHELP (//) +Read??? +; +; +MSGID_PROTECTION_WRITE_SHORTHELP (//) +Write??? +; +; +MSGID_PROTECTION_ARCHIVE_SHORTHELP (//) +Archive??? +; +; +MSGID_PROTECTION_DELETE_SHORTHELP (//) +Delete??? +; +; +MSGID_PROTECTION_EXECUTE_SHORTHELP (//) +Execute??? +; +; +MSGID_PROTECTION_SCRIPT_SHORTHELP (//) +Script??? +; +; +MSGID_COMMENT (//) +Comment: +; +; +MSGID_TOOLTYPES (//) +Tooltypes: +; +; +MSGID_VERSION (//) +Version: +; +; +MSGID_DEFAULTTOOL (//) +Default tool: +; +; +MSGID_STACKSIZE (//) +Stack size: +; +; +MSGID_TOOL_PRIORITY (//) +Priority: +; +; +MSGID_START_FROM (//) +Start from: +; +; +MSGID_PROMPT_FOR_INPUT (//) +Prompt for input: +; +; +MSGID_VERSION_NOT_AVAILABLE (//) +not available +; +; +MSGID_DRAWER_SIZE_SHORTHELP (//) +Press this button to calculate the actual\n\ +size of the drawer contents.\n\ +This operation may takt some time,\n\ +depending on the drawer contents. +; +; +MSGID_INITIAL_DRAWER_SIZE (//) +1 block +; +; +MSGID_DRAWER_SIZE (//) +%s bytes in %lD files, %lD drawers (%lD blocks) +; +; +MSGID_STARTPRI (//) +Start priority: +; +; +MSGID_WAITUNTILFINISHED (//) +Wait until finished: +; +; +MSGID_WAITUNTILFINISHED_SHORTHELP (//) +For WBStartup programs, selects if Scalos will wait\n\ +until program is finished holding WBStartup processsing,\n\ +or if processing will continue asynchronously. +; +; +MSGID_TOOL_SECONDS (//) +seconds +; +; +MSGID_ICONPOS_X (//) +X: +; +; +MSGID_ICONPOS_Y (//) +Y: +; +; +MSGID_ICONPOS_NONE (//) +- +; +;----------------------------------------------------------- +; +MSGID_START_FROM_WORKBENCH (5500//) +Workbench +; +; +MSGID_START_FROM_CLI (//) +Shell +; +; +MSGID_START_FROM_AREXX (//) +ARexx +; +;----------------------------------------------------------- +; +MSGID_DEVICE_REGISTER_DEVICE (5550//) +Device +; +; +MSGID_DEVICE_REGISTER_ICON (//) +Icon +; +;----------------------------------------------------------- +; +MSGID_DRAWER_REGISTER_DRAWER (5600//) +Drawer +; +; +MSGID_DRAWER_REGISTER_ICON (//) +Icon +; +;----------------------------------------------------------- +; +MSGID_PROJECT_REGISTER_PROJECT (5700//) +Project +; +; +MSGID_PROJECT_REGISTER_ICON (//) +Icon +; +;----------------------------------------------------------- +; +MSGID_TOOL_REGISTER_TOOL (5800//) +Tool +; +; +MSGID_TOOL_REGISTER_ICON (//) +Icon +; +;----------------------------------------------------------- +; +MSGID_ICONTYPE_DISK (5900//) +(Disk) +; +; +MSGID_ICONTYPE_DRAWER (//) +(Drawer) +; +; +MSGID_ICONTYPE_TOOL (//) +(Tool) +; +; +MSGID_ICONTYPE_PROJECT (//) +(Project) +; +; +MSGID_ICONTYPE_TRASHCAN (//) +(Trashcan) +; +; +MSGID_ICONTYPE_DEVICE (//) +(Device) +; +; +MSGID_ICONTYPE_KICKSTART (//) +(Kickstart) +; +; +MSGID_ICONTYPE_APPICON (//) +(AppIcon) +; +; +MSGID_ICONTYPE_UNKNOWN (//) +(?unknown?) +; +;----------------------------------------------------------- +; +MSGID_BYTES_GB (6000//) +%lDG +; +; +MSGID_BYTES_GB_2 (//) +%lD%s%-02ldG +; +; +MSGID_BYTES_GB_1 (//) +%lD%s%1ldG +; +; +MSGID_BYTES_MB (//) +%lDM +; +; +MSGID_BYTES_MB_2 (//) +%lD%s%-02ldM +; +; +MSGID_BYTES_MB_1 (//) +%lD%s%1ldM +; +; +MSGID_BYTES_KB (//) +%lDK +; +; +MSGID_BYTES_KB_2 (//) +%lD%s%-02ldK +; +; +MSGID_BYTES_KB_1 (//) +%lD%s%1ldK +; +;----------------------------------------------------------- +; +MSGID_ERROR_SETCOMMENT (6100//) +Error setting comment\n\ +%s. +; +; +MSGID_ERROR_SETPROTECTION (//) +Error setting protection\n\ +%s. +; +; +MSGID_ERROR_RELABEL (//) +Error relabelling disk\n\ +%s. +; +; +MSGID_ERROR_RENAME (//) +Error renaming\n\ +%s. +; +; +MSGID_ERROR_REQ_OK (//) +_OK +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE (6200//) +Information.module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD (//) +Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_DEVICE_DOSTYPE (//) +Identifier: +; +; +MSGID_DEVICE_DOSTYPESTRING (//) +(\033b%c%c%c%c\033n) +; +;----------------------------------------------------------- +; +MSGID_PROTECTION_HIDDEN (//) +Hidden +; +; +MSGID_PROTECTION_HIDDEN_SHORTHELP (//) +Hidden??? +; +; +MSGID_PROTECTION_PURE (//) +Pure +; +; +MSGID_PROTECTION_PURE_SHORTHELP (//) +Pure??? +; +;------------------------------------------------------------ +; +MSGID_TEXT_ICONPATH_SHORTHELP (6300//) +Icon path +; +; +MSGID_FILETYPE_DRAWER (//) +Drawer +; +; +MSGID_FILETYPE_GARBAGE (//) +Trashcan +; +; +MSGID_FILETYPE_DISK (//) +Disk +; +; +MSGID_FILETYPE_TOOL (//) +Tool +; +; +MSGID_FILETYPE_PROJECT (//) +Project +; +; +MSGID_FILETYPE_APPICON (//) +Appicon +; +;------------------------------------------------------------ +; diff --git a/scalos/Modules/Information.MUI/Information.h b/scalos/Modules/Information.MUI/Information.h new file mode 100755 index 000000000..4852e76e2 --- /dev/null +++ b/scalos/Modules/Information.MUI/Information.h @@ -0,0 +1,51 @@ +// Information.h +// $Date$ +// $Revision$ + + +#ifndef INFORMATION_H +#define INFORMATION_H + +#define NO_ICON_POSITION_SHORT ((UWORD) 0x8000) + +#define INFO_ICONPATH_ENV "ENV:Scalos/InfoShowIconPath" +#define INFO_ICONPATH_ENVARC "ENVARC:Scalos/InfoShowIconPath" + +#define INFO_AUTOGETSIZE_ENV "ENV:Scalos/InfoAutoGetSize" +#define INFO_AUTOGETSIZE_ENVARC "ENVARC:Scalos/InfoAutoGetSize" + +enum StartFromType + { + STARTFROM_Workbench, + STARTFROM_CLI, + STARTFROM_Arexx, + }; + +struct DropZoneMsg + { + struct Message dzm_Msg; + struct AppWindowDropZoneMsg dzm_adzm; + }; + +struct DefIconInfo + { + BPTR dii_DirLock; + CONST_STRPTR dii_IconName; + Object **dii_IconObjectFromDisk; + Object **dii_IconObjectFromScalos; + Object **dii_BackupIconObjectFromDisk; // 2nd copy of dii_IconObjectFromDisk, for Undo + }; + +#if defined(__SASC) +int snprintf(char *, size_t, const char *, /*args*/ ...); +int vsnprintf(char *, size_t, const char *, va_list ap); +#endif /* __SASC */ + +struct Information_LocaleInfo +{ + APTR li_LocaleBase; + APTR li_Catalog; + struct LocaleIFace *li_ILocale; +}; + +#endif /* INFORMATION_H */ diff --git a/scalos/Modules/Information.MUI/config.mk b/scalos/Modules/Information.MUI/config.mk new file mode 100755 index 000000000..53786a761 --- /dev/null +++ b/scalos/Modules/Information.MUI/config.mk @@ -0,0 +1,74 @@ +# $Date: 2011-07-16 19:39:22 +0200 (Sa, 16. Jul 2011) $ +# $Revision: 787 $ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +TOOLTYPE_DIR = ../IconProperties.MUI +ICONOBJMCC_DIR = $(TOPLEVEL)/common/IconobjectMCC +INT64_DIR = $(TOPLEVEL)/common/Int64 +FS_DIR = $(TOPLEVEL)/common/Fs + +vpath %.c $(TOOLTYPE_DIR) $(ICONOBJMCC_DIR) $(INT64_DIR) $(FS_DIR) + +SCALOS_LOCALE = $(OBJDIR)/Information_Locale.h + +CFLAGS += -D SCALOSLOCALE=$(SCALOS_LOCALE) + +############################################################################## + +INCLUDES += -I$(TOOLTYPE_DIR) \ + -I$(ICONOBJMCC_DIR) \ + -I$(INT64_DIR) \ + -I$(FS_DIR) \ + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +INCLUDES += + +LFLAGS += # + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +INCLUDES += + +LFLAGS += # + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +INCLUDES += + +LFLAGS += -lmui -lutility + + +else + +############################################################################### +# AmigaOS + +INCLUDES += + +LFLAGS += # + +endif +endif +endif diff --git a/scalos/Modules/Information.MUI/debug.h b/scalos/Modules/Information.MUI/debug.h new file mode 100644 index 000000000..aea559dac --- /dev/null +++ b/scalos/Modules/Information.MUI/debug.h @@ -0,0 +1,19 @@ +// debug.h +// $Date$ +// $Revision$ + +#ifndef DEBUG_H +#define DEBUG_H + +//---------------------------------------------------------------------------- + +#define d1(x) ; +#define d2(x) x; + +// from debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +//---------------------------------------------------------------------------- + +#endif /* DEBUG_H */ diff --git a/scalos/Modules/Information.MUI/makefile b/scalos/Modules/Information.MUI/makefile new file mode 100644 index 000000000..64f40f275 --- /dev/null +++ b/scalos/Modules/Information.MUI/makefile @@ -0,0 +1,173 @@ +# MakeFile für Information MUI module +# $Date$ +# $Revision$ +############################################################# + +TOPLEVEL = / +SUBDIRMAKE = $(MAKE) -s -C +CATCOMP = CatComp +FLEXCAT = FlexCat +CHEADERS = +CC = sc +CFLAGS = nostackcheck nochkabort debug=s data=far code=far \ + strmer nover streq stringsection=far idlen=64 idir=sc:include/ \ + define SCALOSLOCALE=$(SCALOS_LOCALE) \ + idir=include: \ + idir=//include \ + idir=$(subst ../,/,$(TOOLTYPE_DIR)) \ + idir=$(subst ../,/,$(ICONOBJMCC_DIR)) \ + idir=$(subst ../,/,$(INT64_DIR)) \ + idir=$(subst ../,/,$(FS_DIR)) +SPLAT = sc:c/splat +AS = phxass +AFLAGS = QUIET m=68020 linedebug opt=NRQB i=include: +LD = slink +LNFLAGS = quiet batch noicons stripdebug +LNDBFLAGS = quiet batch noicons addsym +LIBS = LIB:sc.lib \ + //SAS-lib/snprintf.lib \ + LIB:mempools.lib \ + LIB:debug.lib \ + LIB:amiga.lib \ + +CSTARTUP = LIB:c.o +OBJDIR = .sasobj +TOOLTYPE_DIR = ../IconProperties.MUI +ICONOBJMCC_DIR = ../../common/IconobjectMCC +INT64_DIR = ../../common/Int64 +FS_DIR = ../../common/Fs + +SCALOS_LOCALE = $(OBJDIR)/Information_Locale.h + +.SUFFIXES: .asm .cd + +############################################################# + +NAME = .bin_os3/Information.module +DBGNAME = $(NAME).debug +CATCOMPHEADER = $(SCALOS_LOCALE) +DESTTOOL = Scalos:modules/ +CAT_FILE = Scalos/Information.catalog +DESTCAT = Locale:Catalogs +ALLCATS = Catalogs/deutsch/$(CAT_FILE) \ + Catalogs/français/$(CAT_FILE) + +############################################################# + +all: $(NAME) \ + $(DBGNAME) \ + allcatalogs +# install +# clean + +############################################################# + +# make all Scalos .catalogs +allcatalogs: + @$(SUBDIRMAKE) Catalogs/deutsch/Scalos + @$(SUBDIRMAKE) Catalogs/français/Scalos + +############################################################# + +CSRCS = Information.c \ + $(ICONOBJMCC_DIR)/IconobjectMCC.c \ + $(TOOLTYPE_DIR)/ToolTypes.c \ + $(FS_DIR)/FsAbstraction.c \ + $(INT64_DIR)/int64.c \ + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +############################################################# + +XSRCS = $(notdir $(CSRCS)) +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(XSRCS:%.c=$(OBJDIR)/$(notdir %).o) + +############################################################# + +$(CATCOMPHEADER) : Information.cd + @printf '\033[32mMake Catcomp header: \033[31m\033[1m$@ \033[32mfrom \033[31m$<\033[0m\n' + @$(FLEXCAT) $< $@=$(TOPLEVEL)/CatComp_h.sd + +############################################################# + +$(OBJDIR)/Information.o : Information.c Information.h \ + $(SCALOS_LOCALE) $(ICONOBJMCC_DIR)/IconobjectMCC.h \ + $(TOOLTYPE_DIR)/ToolTypes.h $(INT64_DIR)/int64.h $(FS_DIR)/FsAbstraction.h debug.h + +$(OBJDIR)/IconobjectMCC.o : $(ICONOBJMCC_DIR)/IconobjectMCC.c \ + $(ICONOBJMCC_DIR)/IconobjectMCC.h debug.h + +$(OBJDIR)/ToolTypes.o : $(TOOLTYPE_DIR)/ToolTypes.c \ + $(TOOLTYPE_DIR)/ToolTypes.h debug.h + +############################################################# + +$(NAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNFLAGS) + +$(DBGNAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNDBFLAGS) + +############################################################# + +# commands generated a catalog (.catalog) from a catalog translation (.ct) file. +.ct.catalog: + $(CATCOMP) $*.cd $< CATALOG $*.catalog VB=1 + +$(OBJDIR)/IconobjectMCC.o : $(ICONOBJMCC_DIR)/IconobjectMCC.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/ToolTypes.o : $(TOOLTYPE_DIR)/ToolTypes.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/FsAbstraction.o : $(FS_DIR)/FsAbstraction.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/int64.o : $(INT64_DIR)/int64.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $< objectname $@ + +$(OBJDIR)/%.o : %.s + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +$(OBJDIR)/%.o : %.asm + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +############################################################# + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(NAME) \033[0mto \033[1m$(DESTTOOL) \033[0m\n' + @copy $(NAME) $(DESTTOOL) clone + @printf '\033[32mFlushing memory\033[0m\n' + @avail flush + @printf '\033[32mInstall: \033[31m\033[1m$(CAT_FILE)\033[0m\n' + -@copy 'catalogs/deutsch/$(CAT_FILE)' '$(DESTCAT)/Deutsch/Scalos/' clone + -@copy 'catalogs/français/$(CAT_FILE)' '$(DESTCAT)/français/Scalos/' clone + +############################################################# + +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + -@delete $(OBJS) $(NAME) $(DBGNAME) $(ALLCATS) $(CATCOMPHEADER) + @printf '\033[0m' + +############################################################# + +nodebug: + -@$(SPLAT) -s -o "d2(" "d1(" "#?.c" + +############################################################# diff --git a/scalos/Modules/Information.MUI/makefile-new b/scalos/Modules/Information.MUI/makefile-new new file mode 100755 index 000000000..eb14708dc --- /dev/null +++ b/scalos/Modules/Information.MUI/makefile-new @@ -0,0 +1,93 @@ +# $Date: 2011-07-12 03:13:22 +0200 (Di, 12. Jul 2011) $ +# $Revision: 775 $ +############################################################# +TOPLEVEL = $(shell pwd)/../.. + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + SDPATH=/ +else + SDPATH=../.. +endif + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(OBJDIR)/Information.o \ + $(OBJDIR)/IconobjectMCC.o \ + $(OBJDIR)/ToolTypes.o \ + $(OBJDIR)/int64.o \ + $(OBJDIR)/FsAbstraction.o \ + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Subdirs +# + +SUBDIRS = $(filter-out Catalogs/sample/Scalos, $(wildcard Catalogs/*/Scalos)) + +############################################################################## +# +# Targets +# + +NAME = Information.module +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) \ + all_subdirs + +############################################################################## + +Information.c : $(OBJDIR)/Information_Locale.h + +$(OBJDIR)/Information_Locale.h : Information.cd + @$(ECHO) "FlexCat $@" + $(FLEXCAT) $< $@=$(SDPATH)/CatComp_h.sd + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + @$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) +ifneq ($(MACHINE), ppc-amigaos) + -@chmod u+x $@ +endif + +############################################################################## + +install: install_subdirs + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) Scalos:modules/ clone + +clean: clean_subdirs + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* \ + $(OBJDIR)/Information_Locale.h + +############################################################################## + diff --git a/scalos/Modules/NewDrawer.Gadtools/makefile b/scalos/Modules/NewDrawer.Gadtools/makefile new file mode 100755 index 000000000..962a37880 --- /dev/null +++ b/scalos/Modules/NewDrawer.Gadtools/makefile @@ -0,0 +1,79 @@ +# Makefile for NewDrawer.module (MUI) +# using GNU make and SAS/C +# $Date$ + +##################################################################### + +CHEADERS = +CC = sc +CFLAGS = optimize nostackcheck nochkabort debug=s \ + strmer nover streq idir=sc:include/ idir=include: idir=//include +AS = phxass +AFLAGS = QUIET m=68020 linedebug opt=NRQB i=include: +LD = slink +LNFLAGS = quiet batch noicons stripdebug +LNDBFLAGS = quiet batch noicons addsym +LIBS = LIB:sc.lib LIB:debug.lib LIB:amiga.lib +CSTARTUP = LIB:c.o +OBJDIR = .sasobj + +.SUFFIXES: .asm + +############################################################# + +NAME = NewDrawer.module +DBGNAME = $(NAME).debug + +############################################################# + +all: $(NAME) $(DBGNAME) +# install clean + +##################################################################### + +CSRCS = newdrawer.c \ + + +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(CSRCS:%.c=$(OBJDIR)/%.o) + +##################################################################### + +$(NAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNFLAGS) + +$(DBGNAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNDBFLAGS) + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +############################################################# + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $< objectname $@ + +##################################################################### + +$(DTNAME) $(DTDBGNAME) : $(OBJS) + +##################################################################### + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(NAME)\033[0m\n' + copy $(NAME) Scalos:modules/ + +##################################################################### + +# A little something to clean it all up +clean: + @printf '\033[32mCleanup: \033[31m\033[1m\n' + -@delete $(OBJS) $(NAME) $(DBGNAME) + @printf '\033[0m\n' + +##################################################################### + diff --git a/scalos/Modules/NewDrawer.Gadtools/newdrawer.c b/scalos/Modules/NewDrawer.Gadtools/newdrawer.c new file mode 100755 index 000000000..0e03ceb19 --- /dev/null +++ b/scalos/Modules/NewDrawer.Gadtools/newdrawer.c @@ -0,0 +1,665 @@ +// newdrawer.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include // +jmc+ + + +#define d1(x) ; +#define d2(x) x; + +#ifndef TOGGLE_BOOL +#define TOGGLE_BOOL( x ) ( (x) ? FALSE : TRUE ) +#endif + +// from debug.lib +extern int kprintf(const char *fmt, ...); + +__stdargs void NewList( struct List *list ); +static void ndmain(void); +static void wbmain(struct WBStartup *wbs ); + +IMPORT T_LOCALEBASE LocaleBase; +IMPORT T_UTILITYBASE UtilityBase; +struct Library *IconobjectBase = NULL; + +struct Catalog *Cat; + +struct Screen *scr; +struct DrawInfo *drinfo; +BOOL one2two; +APTR visualinfo; +ULONG offx,offy,fonty,sizeheight,uwidth; +ULONG wndwidth,wndheight; + +struct Window *wnd; +struct Gadget *glist; +struct Gadget *drawerString; +struct Gadget *iconCheckbox; + +STRPTR drawerStr; +ULONG iconChecked; + +STRPTR parentStr; +STRPTR topStr; + +BOOL glistAttached; +BOOL sizeVerify; +BOOL fromWB; + +const STATIC STRPTR engLocText[] = +{ + "Enter Name for a a new Drawer in:", + "New _Drawer:", + "_OK", + "_Cancel", + "Add a new Drawer", + "Unnamed", + "Path:", + "Create _Icon", + "Can't create drawer" +}; + +UWORD ok_key, cancel_key, drawer_key, icon_key; + +STRPTR locText[9]; + +const STRPTR VerString = "$VER: newdrawer.module 1.1 "__AMIGADATE__; + +#define WND_DRAWER_STRING 1 +#define WND_ICON_CHECKBOX 2 +#define WND_OK_BUTTON 3 +#define WND_CANCEL_BUTTON 4 + +//------------------------------------- +ULONG StrLen( const STRPTR str ) +{ + if( !str) + return 0; + return strlen(str); +} +//------------------------------------- +STRPTR NameOfLock( BPTR lock ) +{ + STRPTR n; + BOOL again; + ULONG bufSize = 127; + if( !lock ) return NULL; + + do + { + again = FALSE; + if((n = (STRPTR) calloc(bufSize, 1))) + { + if( NameFromLock( lock, n, bufSize-1 ) == DOSFALSE ) + { + if( IoErr() == ERROR_LINE_TOO_LONG ) + { + bufSize += 127; + again = TRUE; + } + free(n); + n = NULL; + } + } + } while(again); + + return n; +} +//------------------------------------- +STRPTR GetFullPath( const STRPTR drw, const STRPTR file ) +{ + ULONG length = StrLen(drw)+StrLen(file)+4; + STRPTR fp = (STRPTR) malloc( length+1 ); + if( fp ) + { + strcpy( fp, drw ); + + if( AddPart( fp, file, length )) return fp; + free( fp ); + } + return NULL; +} +//------------------------------------- +ULONG GetTextLength( const STRPTR str ) +{ + return TextLength(&scr->RastPort,str,strlen(str)); +} +//------------------------------------- +ULONG FindUnderscoredToLower(STRPTR text) +{ + ULONG c; + while(( c = *text++)) + { + if( c == '_' ) return ToLower(*text); + } + return 0; +} +//------------------------------------- +BOOL ToggleCheckbox( struct Window *wnd, struct Gadget *g, BOOL oldState ) +{ + BOOL newState = TOGGLE_BOOL(oldState); + GT_SetGadgetAttrs( g, wnd, NULL, + GTCB_Checked, newState, + TAG_DONE ); + return newState; +} +//------------------------------------- + +//------------------------------------- +STATIC VOID InitStrings(void) +{ + ULONG i; + for(i=0; i<9; i++) + { + locText[i] = GetCatalogStr( Cat, i, engLocText[i]); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: locText[%ld]=<%s>\n", __LINE__, i, locText[i])); + } + + drawer_key = FindUnderscoredToLower(locText[1]); + ok_key = FindUnderscoredToLower(locText[2]); + cancel_key = FindUnderscoredToLower(locText[3]); + icon_key = FindUnderscoredToLower(locText[7]); +} +//------------------------------------- + +//------------------------------------- +STATIC VOID GetDefaultDrawer(void) +{ + ULONG num = 1; + STRPTR buf; + drawerStr = (STRPTR) calloc(strlen(locText[5])+20, 1); + if(drawerStr) + { + strcpy(drawerStr,locText[5]); + buf = drawerStr+strlen(locText[5]); + while(num<1000000) + { + BPTR lock; + sprintf(buf,"%ld",num); + if(( lock = Lock(drawerStr,ACCESS_READ))) + { + UnLock(lock); + } else return; + num++; + } + free(drawerStr); + drawerStr=NULL; + } +} +//------------------------------------- +STATIC VOID GetDrawer(void) +{ + STRPTR drwStr; + + if(GT_GetGadgetAttrs(drawerString,wnd,NULL, + GTST_String, &drwStr, + TAG_DONE )) + { + if( drawerStr ) + free(drawerStr); + drawerStr=strdup(drwStr); + } +} +//------------------------------------- +STATIC VOID GetIcon(void) +{ + ULONG ichk=0; + if(GT_GetGadgetAttrs(iconCheckbox,wnd,NULL, + GTCB_Checked, &ichk, + TAG_DONE )) + { + iconChecked=ichk; + } +} +//------------------------------------- +STATIC BOOL SetupScreen(void) +{ + if((scr = LockPubScreen(NULL))) + { + if((drinfo = GetScreenDrawInfo(scr))) + { + if((visualinfo = GetVisualInfoA(scr,NULL))) + { + UWORD x,y; + Object *o = (Object*)NewObject( NULL, SYSICLASS, + SYSIA_DrawInfo,drinfo, + SYSIA_Which, SIZEIMAGE, + TAG_DONE); + if(o) + { + if(!GetAttr( IA_Height,o,&sizeheight)) + sizeheight = 11; + DisposeObject(o); + } + else + sizeheight = 11; + uwidth = TextLength(&scr->RastPort,"_",1); + + x = drinfo->dri_Resolution.X; + y = drinfo->dri_Resolution.Y; + if( y/x >= 2 ) + { + one2two = TRUE; + } else one2two = FALSE; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: parentStr=%08lx\n", __LINE__, parentStr)); + if(parentStr) + { + topStr = (STRPTR) malloc( strlen(parentStr)+strlen(locText[0])+8 ); + if(topStr) + { + sprintf(topStr,"%s \'%s\'",locText[0],parentStr); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: locText[0]=<%s>\n", __LINE__, locText[0])); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: parentStr=<%s>\n", __LINE__, parentStr)); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: topStr=<%s>\n", __LINE__, topStr)); + } + } + + return TRUE; + } + } + } + return FALSE; +} +//------------------------------------- +STATIC VOID FreeScreen(void) +{ + if( visualinfo ) + FreeVisualInfo(visualinfo); + if( drinfo ) + FreeScreenDrawInfo(scr,drinfo); + if( scr ) + UnlockPubScreen(NULL,scr); +} +//------------------------------------- +STATIC VOID Render(void) +{ + Move(wnd->RPort,offx+4,offy+drinfo->dri_Font->tf_Baseline+4); + SetABPenDrMd(wnd->RPort,drinfo->dri_Pens[TEXTPEN],0,JAM1); + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: topStr=%08lx\n", __LINE__, topStr)); + + if( topStr ) + Text(wnd->RPort,topStr,strlen(topStr)); + else + Text(wnd->RPort,locText[0],strlen(locText[0])); +} +//------------------------------------- +STATIC BOOL CreateGadgets(void) +{ + struct Gadget *g; + + if(glist) + { + FreeGadgets(glist); + glist = NULL; + } + + g = CreateContext( &glist ); + if( g ) + { + struct NewGadget ng; + WORD createIconWidth = TextLength(&scr->RastPort,locText[7],strlen(locText[7]))-uwidth; + WORD usableWidth = wndwidth - 2*offx-8; + WORD cbw = (fonty+6)*13*(one2two+1)/11; + WORD createIconLeft = wndwidth-offx-4-cbw-createIconWidth-8; + BOOL setCursor; + + ng.ng_VisualInfo = visualinfo; + ng.ng_TextAttr = NULL; + ng.ng_GadgetText = locText[1]; + ng.ng_GadgetID = WND_DRAWER_STRING; + ng.ng_Flags = NULL; + ng.ng_UserData = NULL; + ng.ng_LeftEdge = offx+13+TextLength(&scr->RastPort,ng.ng_GadgetText,strlen(ng.ng_GadgetText))-uwidth; + ng.ng_TopEdge = offy+fonty+7; + ng.ng_Width = createIconLeft - ng.ng_LeftEdge-6; + ng.ng_Height = fonty+6; + + if( !drawerString && drawerStr ) setCursor = TRUE; + else setCursor = FALSE; + + g = drawerString = CreateGadget( STRING_KIND, g, &ng, + GTST_String, drawerStr?drawerStr:(STRPTR)"", + GT_Underscore,'_', + TAG_DONE); + + if( setCursor ) + ((struct StringInfo*)(drawerString->SpecialInfo))->BufferPos = strlen(drawerStr); + + + ng.ng_LeftEdge = wndwidth - cbw-4-offx; + ng.ng_Width = cbw; + ng.ng_GadgetID = WND_ICON_CHECKBOX; + ng.ng_GadgetText = locText[7]; + + g = iconCheckbox = CreateGadget( CHECKBOX_KIND, g, &ng, + GTCB_Scaled, TRUE, + GTCB_Checked, iconChecked, + GT_Underscore,'_', + TAG_DONE ); + + ng.ng_TopEdge += ng.ng_Height+4; + ng.ng_Width = usableWidth/2-3; + ng.ng_GadgetText = locText[2]; + ng.ng_LeftEdge = offx+4; + ng.ng_GadgetID = WND_OK_BUTTON; + + g = CreateGadget( BUTTON_KIND, g, &ng, + GT_Underscore,'_', + TAG_DONE); + + ng.ng_GadgetText = locText[3]; + ng.ng_LeftEdge = wndwidth - ng.ng_Width-4-offx; + ng.ng_GadgetID = WND_CANCEL_BUTTON; + + g = CreateGadget( BUTTON_KIND, g, &ng, + GT_Underscore,'_', + TAG_DONE); + + if(g) return TRUE; + + FreeGadgets(glist); + glist=NULL; + } + return FALSE; +} +//------------------------------------- +STATIC VOID FreeGUI(void) +{ + if(wnd) CloseWindow(wnd); + if(glist) FreeGadgets(glist); + if(topStr) + { + free(topStr); + topStr = NULL; + } +} +//------------------------------------- +STATIC BOOL SetupGUI(void) +{ + WORD cbw;// = (fonty+6)*13*(one2two+1)/11; + ULONG newwndwidth;// = GetTextLength(locText[1])+GetTextLength(locText[7])+cbw+GetTextLength(locText[5])+2*offx+46; + + fonty = drinfo->dri_Font->tf_YSize; + offx = scr->WBorLeft; + offy = scr->WBorTop + fonty + 1; + + cbw = (fonty+6)*13*(one2two+1)/11; + newwndwidth = GetTextLength(locText[1])+GetTextLength(locText[7])+cbw+GetTextLength(locText[5])+2*offx+46; + + wndwidth = GetTextLength(topStr); + if(newwndwidth>wndwidth)wndwidth=newwndwidth; + if(wndwidth > scr->Width) wndwidth=scr->Width; + + wndheight = offy + 3*fonty + sizeheight + 26; + + GetDefaultDrawer(); + + if( CreateGadgets()) + { + ULONG idcmp = IDCMP_CLOSEWINDOW|IDCMP_NEWSIZE|BUTTONIDCMP|IDCMP_VANILLAKEY|STRINGIDCMP; + if( sizeVerify ) idcmp |= IDCMP_SIZEVERIFY; + + wnd = OpenWindowTags( NULL, + WA_Left,0, + WA_Top,offy, + WA_Width, wndwidth, + WA_Height, wndheight, + WA_IDCMP, idcmp, + WA_DragBar,TRUE, + WA_SizeGadget, TRUE, + WA_DepthGadget,TRUE, + WA_CloseGadget, TRUE, + WA_Title,locText[4], + WA_RMBTrap, TRUE, + WA_Gadgets, glist, + WA_SizeBBottom,TRUE, + WA_MaxWidth,-1, + WA_Activate, TRUE, + WA_PubScreen,scr, + WA_NoCareRefresh,TRUE, +// WA_MaxHeight,-1, + TAG_DONE ); + if( wnd ) + { + glistAttached = TRUE; + SetFont(wnd->RPort,drinfo->dri_Font); + Render(); + return TRUE; + } + glistAttached = FALSE; + } + + FreeGUI(); + return FALSE; +} +//------------------------------------- +STATIC BOOL HandleWnd(void) +{ + struct IntuiMessage *imsg; + BOOL retVal = FALSE; + + while((imsg = GT_GetIMsg(wnd->UserPort))) + { + ULONG cl = imsg->Class; + UWORD code = imsg->Code; + APTR iaddress = imsg->IAddress; + + if( cl == IDCMP_SIZEVERIFY ) + { + if(glistAttached) RemoveGList( wnd, glist, -1 ); + glistAttached = FALSE; + GT_ReplyIMsg(imsg); + continue; + } + + GT_ReplyIMsg(imsg); + + switch( cl ) + { + case IDCMP_CLOSEWINDOW: + retVal = TRUE; + if( drawerStr ) + free(drawerStr); + drawerStr = NULL; + break; + + case IDCMP_VANILLAKEY: + if( code == 10 || code == ok_key) retVal = TRUE; + else if( code == 27 || code == cancel_key ) + { + if( drawerStr ) + free(drawerStr); + drawerStr = NULL; + retVal = TRUE; + } + else if( code == drawer_key ) ActivateGadget(drawerString,wnd,NULL); + else if( code == icon_key ) iconChecked = ToggleCheckbox(wnd,iconCheckbox,iconChecked); + break; + + case IDCMP_NEWSIZE: + if( !sizeVerify && glistAttached) + { + if( wndwidth == wnd->Width || wndheight != wnd->Height ) break; + } + + if(glistAttached) RemoveGList( wnd, glist, -1 ); + + if( wnd->Width < wndwidth ) RefreshWindowFrame(wnd); + + wndwidth = wnd->Width; + wndheight = wnd->Height; + EraseRect( wnd->RPort, wnd->BorderLeft, wnd->BorderTop+fonty+6, + wnd->Width-wnd->BorderRight-1, wnd->Height-wnd->BorderBottom-1 ); + if(CreateGadgets()) + { + AddGList( wnd, glist, -1,-1, NULL ); + RefreshGList( glist, wnd, NULL, -1 ); + glistAttached = TRUE; + ActivateGadget( drawerString, wnd, NULL); + } else + { + glistAttached = FALSE; + retVal = TRUE; + } + break; + + case IDCMP_GADGETUP: + switch( ((struct Gadget*)iaddress)->GadgetID ) + { + case WND_DRAWER_STRING: + retVal = TRUE; + GetDrawer(); + break; + + case WND_ICON_CHECKBOX: + GetIcon(); + break; + + case WND_CANCEL_BUTTON: + retVal = TRUE; + if( drawerStr ) + free(drawerStr); + drawerStr = NULL; + break; + + case WND_OK_BUTTON: + retVal = TRUE; + GetDrawer(); + break; + + default: + break; + } + break; + } + } + return retVal; +} +//------------------------------------- + +//------------------------------------- +static void ndmain(void) +{ + if(LocaleBase) Cat = OpenCatalogA( NULL, "Scalos/Scalos_NewDrawer.catalog",NULL); + + if ((IconobjectBase = OpenLibrary(ICONOBJECTNAME, 39))) + { + BPTR lock = Lock("ENV:Scalos/NoSizeVerify",ACCESS_READ); + if(lock) + { + sizeVerify = FALSE; + UnLock(lock); + } else sizeVerify = TRUE; + + InitStrings(); + + iconChecked = TRUE; + + if(SetupScreen()) + { + if( SetupGUI()) + { + BOOL ready = FALSE; + ULONG wndsig = 1UL<UserPort->mp_SigBit; + + ActivateGadget(drawerString,wnd,NULL); + + while( ready == FALSE ) + { + ULONG signal = Wait(wndsig|4096); + + if( signal & 4096 ) ready = TRUE; + if( signal & wndsig ) ready = HandleWnd(); + } + FreeGUI(); + + if( drawerStr ) + { + BPTR lock = CreateDir(drawerStr); + if( lock ) + { + if( iconChecked ) + { + Object *IconObj; + + IconObj = GetDefIconObject(WBDRAWER, NULL); + if (IconObj) + { + PutIconObjectTags(IconObj, drawerStr, + TAG_END); + DisposeIconObject(IconObj); + } + } + UnLock(lock); + } + free(drawerStr); + drawerStr = NULL; + } + } + FreeScreen(); + } + CloseLibrary(IconobjectBase); + } + if(Cat) CloseCatalog(Cat); +} +//------------------------------------- +main() +{ + if (WBenchMsg) + wbmain(WBenchMsg); +} +//------------------------------------- +static void wbmain(struct WBStartup *wbs ) +{ +// BPTR olddir; +// BPTR lock; + + if( wbs->sm_NumArgs > 1 ) + { + if((parentStr = NameOfLock(wbs->sm_ArgList[1].wa_Lock))) + { + BPTR olddir = CurrentDir(wbs->sm_ArgList[1].wa_Lock); + ndmain(); + free(parentStr); + CurrentDir(olddir); + } +/* lock = NULL; + commandStr = strdup(wbs->sm_ArgList[1].wa_Name); + olddir = CurrentDir(wbs->sm_ArgList[1].wa_Lock); + } else + { + lock = Lock("RAM:",ACCESS_READ); + olddir = CurrentDir(lock);*/ + } +// main(); +// CurrentDir(olddir); + +// if(lock) UnLock(lock); +} +//------------------------------------- diff --git a/scalos/Modules/NewDrawer.MUI/Catalogs/deutsch/Scalos/NewDrawer.ct b/scalos/Modules/NewDrawer.MUI/Catalogs/deutsch/Scalos/NewDrawer.ct new file mode 100644 index 000000000..51dab82b3 --- /dev/null +++ b/scalos/Modules/NewDrawer.MUI/Catalogs/deutsch/Scalos/NewDrawer.ct @@ -0,0 +1,203 @@ +; Rename.ct +## version $VER: Rename.catalog 40.1 (20 Feb 2005 22:02:39) +## codeset 0 +## language deutsch +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Neue Schublade +;Scalos NewDrawer +; +; +MSGID_OKBUTTON +Anlegen +;NewDrawer +; +; +MSGID_OKBUTTON_SHORT +n +;r +; +; +MSGID_SHORTHELP_OKBUTTON +Legt eine neue, leere Schublade\n\ +mit dem angegebenen Namen an. +;Create new drawer. +; +; +MSGID_CANCELBUTTON +Abbrechen +;Cancel +; +; +MSGID_CANCELBUTTON_SHORT +a +;c +; +; +MSGID_SHORTHELP_CANCELBUTTON +Abbrechen ohne Anlegen\n\ +einer neuer Schublade. +;Discard all changes and\n\ +;do not create anything. +; +; +MSGID_CREATE_APPLICATION_FAILED +Fehler beim Erzeugen der Anwendung.\n +;Failed to create Application.\n +; +; +MSGID_CREATE_MAINWINDOW_FAILED +Fehler beim Öffnen des Hauptfensters !\n +;Failed to open main window !\n +; +; +MSGID_OPEN_LIBRARY_FAILED +Fehler beim Öffnen von \"%s\" !\n +;Failed to open \"%s\" !\n +; +;;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Projekt +;Project +; +; +MSGID_MENU_PROJECT_ABOUT +Über... +;About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Über MUI... +;About MUI... +; +; +MSGID_MENU_PROJECT_QUIT +Beenden +;Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +Ok +;_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Rename.module V%ld.%ld\033n\n\ +%s\n\ +© 2004%s Das Scalos-Team +;\33c\033bScalos Rename.module V%ld.%ld\033n\n\ +;%s\n\ +;© 2004%s The Scalos Team +; +;----------------------------------------------------------- +; +MSGID_NEWNAME_DEFAULT +Bitte_umbenennen +;New_Drawer_Name +; +; +MSGID_TEXT_ENTERNAME +Name der neuen Schublade in \"%s\": +;Enter name for a new drawer in \"%s\" +; +; +MSGID_LABEL_ENTERNAME +Name der Schublade: +;New Drawer +; +; +MSGID_LABEL_CREATE_ICON +Piktogramm +;Create Icon +; +; +MSGID_CHECKMARK_CREATEICON_SHORTHELP +Ist dieser Schalter eingeschaltet, wird für\n\ +die neue Schublade ein Piktogramm mit erzeugt. +;If this checkbox is checked, an icon\n\ +;will be created for the new drawer. +; +; +MSGID_TITLE_ERRORREQ +Fehler bei neuer Schublade +;NewDrawer Error +; +; +MSGID_ERRORREQ_BODYTEXT +Konnte \"%s" nicht anlegen:\n\ +%s +;Could not create '%s'\n%s +; +; +MSGID_REQ_OK + _Ok +; +; +MSGID_TEXT_ENTERNAME_SHORTHELP +Pfad der neuen Schublade.\n\ +Mit dem Rollbalken am unteren Fensterrand kann\n\ +der Inhalt des Pfades hin- und hergeschoben werden,\n\ +um auch lange Pfadnamen lesen zu können. +;Path to create a new drawer.\n\n\ +;It's possible to show all content of this gadget using\n\ +;the scroller located at the bottom of the window.\n\ +;Can be usefull for large path lenght. +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +NewDrawer.module kann nicht gestartet werden +;NewDrawer.module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Wiederholen|Beenden +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\ +Die Klasse ist nicht installiert. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Sie haben momentan Version v%lu.%lu installiert und\n\ +sollten die Klasse daher aktualisieren! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Version %lu.%lu wird momentan von einer anderen Anwendung\n\ +verwendet. Wenn sie die benötigte Version installiert haben,\n\ +schließen sie alle MUI Programme und probieren es erneut. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +;+++ translateme +++ +MSGID_OPEN_PREFS_LIBRARY_FAILED +Failed to open \"%s\" !\n\ +Loading and saving of settings aren't availlables.\n +; +;----------------------------------------------------------- +; diff --git a/scalos/Modules/NewDrawer.MUI/Catalogs/deutsch/Scalos/config.mk b/scalos/Modules/NewDrawer.MUI/Catalogs/deutsch/Scalos/config.mk new file mode 100755 index 000000000..8631b0623 --- /dev/null +++ b/scalos/Modules/NewDrawer.MUI/Catalogs/deutsch/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = deutsch + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = german + +else + +############################################################################### +# AmigaOS and AROS + +LANG = deutsch + +endif +endif diff --git a/scalos/Modules/NewDrawer.MUI/Catalogs/deutsch/Scalos/makefile b/scalos/Modules/NewDrawer.MUI/Catalogs/deutsch/Scalos/makefile new file mode 100644 index 000000000..d60c91636 --- /dev/null +++ b/scalos/Modules/NewDrawer.MUI/Catalogs/deutsch/Scalos/makefile @@ -0,0 +1,14 @@ +# makefile for NewDrawer.module (translated Texts : deutsch) +# $Date$ +# $Revision$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mdeutsch\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +NewDrawer.catalog : NewDrawer.ct ../../../NewDrawer.cd + +All: NewDrawer.catalog diff --git a/scalos/Modules/NewDrawer.MUI/Catalogs/deutsch/Scalos/makefile-new b/scalos/Modules/NewDrawer.MUI/Catalogs/deutsch/Scalos/makefile-new new file mode 100644 index 000000000..466f37dc1 --- /dev/null +++ b/scalos/Modules/NewDrawer.MUI/Catalogs/deutsch/Scalos/makefile-new @@ -0,0 +1,30 @@ +# makefile for NewDrawer.module (translated Texts : deutsch) +# $Date: 2011-07-24 10:11:00 +0200 (So, 24. Jul 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = NewDrawer + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git "a/scalos/Modules/NewDrawer.MUI/Catalogs/fran\303\247ais/Scalos/NewDrawer.ct" "b/scalos/Modules/NewDrawer.MUI/Catalogs/fran\303\247ais/Scalos/NewDrawer.ct" new file mode 100755 index 000000000..b937cea12 --- /dev/null +++ "b/scalos/Modules/NewDrawer.MUI/Catalogs/fran\303\247ais/Scalos/NewDrawer.ct" @@ -0,0 +1,210 @@ +; Rename.ct +; $Date$ +; $Revision$ +; +## version $VER: Rename.catalog 40.1 (20 Feb 2005 20:27:40) +## codeset 0 +## language français +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Nouveau répertoire +; Scalos NewDrawer +; +; +MSGID_OKBUTTON +Nouveau répertoire +; NewDrawer +; +; +MSGID_OKBUTTON_SHORT +n +; r +; +; +MSGID_SHORTHELP_OKBUTTON +Création d'un\n\ +nouveau répertoire. +; Create new drawer. +; +; +MSGID_CANCELBUTTON +Annuler +; Cancel +; +; +MSGID_CANCELBUTTON_SHORT +a +; c +; +; +MSGID_SHORTHELP_CANCELBUTTON +Oublier tout changement\n\ +et ne rien créer. +; Discard all changes and\n\ +; do not create anything. +; +; +MSGID_CREATE_APPLICATION_FAILED +La création de l'application a échouée.\n +; Failed to create Application.\n +; +; +MSGID_CREATE_MAINWINDOW_FAILED +Impossible d'ouvrir la fenêtre !\n +; Failed to open main window !\n +; +; +MSGID_OPEN_LIBRARY_FAILED +Impossible d'ouvrir "%s" ! +; Failed to open \"%s\" ! +; +;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Projet +; Project +; +; +MSGID_MENU_PROJECT_ABOUT +A propos... +; About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI +A propos de MUI... +; About MUI... +; +; +MSGID_MENU_PROJECT_QUIT +Quitter +; Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; Q +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +D'acc_ord +; _OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos NewDrawer.module V\0333%ld\0332.\0333%ld\0332\033n\n\ +Compilé sous : \0333%s\0332\n\ +© 2004%s The Scalos Team +; \33c\033bScalos NewDrawer.module V%ld.%ld\033n\n\ +; %s\n\ +; © 2004%s The Scalos Team +; +;----------------------------------------------------------- +; +MSGID_NEWNAME_DEFAULT +Nouveau_Répertoire +; New_Drawer_Name +; +; +MSGID_TEXT_ENTERNAME +\033bEntrez un nom pour le nouveau répertoire dans :\033n "%s" +; Enter name for a new drawer in: \"%s\" +; +; +MSGID_LABEL_ENTERNAME +\033bNouveau répertoire\033n +; New Drawer +; +; +MSGID_LABEL_CREATE_ICON +Création d'une icône +; Create Icon +; +; +MSGID_CHECKMARK_CREATEICON_SHORTHELP +Si ce bouton est coché, une icône\n\ +sera créée pour le nouveau répertoire. +; If this checkbox is checked, an icon\n\ +; will be created for the new drawer. +; +; +MSGID_TITLE_ERRORREQ +Nouveau répertoire Erreur +; NewDrawer Error +; +; +MSGID_ERRORREQ_BODYTEXT +Impossible de créer '\033b%s\033n'\n\ +dans '\033b%s\033n' ! +; Could not create '%s' +; +; +MSGID_REQ_OK +D'acc_ord +; _Ok +; +; +MSGID_TEXT_ENTERNAME_SHORTHELP +Lieu de création du répertoire.\n\n\ +Si besoin, vous avez la possibilité d'utiliser\n\ +l'ascenseur siué au bas de la fenêtre afin\n\ +de mieux visionner le chemin d'accès.\n\ +Peut s'avèrer utile pour de longs\n\ +chemins d'accès. +; Path to create a new drawer\n\n\ +; It's possible to show all content of this gadget using\n\ +; the scroller located at the bottom of the window.\n\ +; Can be usefull for large path lenght. +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Le lancement de NewDrawer.module a échoué +;NewDrawer.module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Recommencer | Quitter +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +Celle-ci n'est pas installée. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +\n\ +La version installée est V%lu.%lu, installez-en une plus récente s'il vous plaît ! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +%lu.%lu est actuellement utilisée par d'autres applications.\n\ +\n\ +Une fois la version requise installée,\n\ +fermez tous les programmes MUI, soyez sûr que l'ancienne classe\n\ +ne soit plus présente dans la mémoire puis, essayez de nouveau. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_OPEN_PREFS_LIBRARY_FAILED +Le chargement de \"%s\" a échoué !\n\ +Le chargement et la sauvegarde des options ne sont pas disponibles.\n +; +;----------------------------------------------------------- +; diff --git "a/scalos/Modules/NewDrawer.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" "b/scalos/Modules/NewDrawer.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" new file mode 100755 index 000000000..8b7056423 --- /dev/null +++ "b/scalos/Modules/NewDrawer.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" @@ -0,0 +1,40 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = français + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = french + +else + +############################################################################### +# AmigaOS and AROS + +LANG = français + +endif +endif diff --git "a/scalos/Modules/NewDrawer.MUI/Catalogs/fran\303\247ais/Scalos/makefile" "b/scalos/Modules/NewDrawer.MUI/Catalogs/fran\303\247ais/Scalos/makefile" new file mode 100644 index 000000000..20db3dbca --- /dev/null +++ "b/scalos/Modules/NewDrawer.MUI/Catalogs/fran\303\247ais/Scalos/makefile" @@ -0,0 +1,14 @@ +# makefile for NewDrawer.module (translated Texts : français) +# $Date$ +# $Revision$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mfrançais\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +NewDrawer.catalog : NewDrawer.ct ../../../NewDrawer.cd + +All: NewDrawer.catalog diff --git "a/scalos/Modules/NewDrawer.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" "b/scalos/Modules/NewDrawer.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" new file mode 100644 index 000000000..dd8f4aa14 --- /dev/null +++ "b/scalos/Modules/NewDrawer.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" @@ -0,0 +1,30 @@ +# makefile for NewDrawer.module (translated Texts : français) +# $Date: 2011-07-24 10:11:00 +0200 (So, 24. Jul 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = NewDrawer + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Modules/NewDrawer.MUI/Catalogs/sample/Scalos/NewDrawer.ct b/scalos/Modules/NewDrawer.MUI/Catalogs/sample/Scalos/NewDrawer.ct new file mode 100644 index 000000000..125156520 --- /dev/null +++ b/scalos/Modules/NewDrawer.MUI/Catalogs/sample/Scalos/NewDrawer.ct @@ -0,0 +1,171 @@ +; Rename.ct +## version $VER: Rename.catalog 40.1 (26 Feb 2005 22:01:34) +## codeset 0s +## language xxxxxx +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos NewDrawer +; +; +MSGID_OKBUTTON +NewDrawer +; +; +MSGID_OKBUTTON_SHORT +r +; +; +MSGID_SHORTHELP_OKBUTTON +Create new drawer. +; +; +MSGID_CANCELBUTTON +Cancel +; +; +MSGID_CANCELBUTTON_SHORT +c +; +; +MSGID_SHORTHELP_CANCELBUTTON +Discard all changes and\n\ +do not create anything. +; +; +MSGID_CREATE_APPLICATION_FAILED +Failed to create Application.\n +; +; +MSGID_CREATE_MAINWINDOW_FAILED +Failed to open main window !\n +; +; +MSGID_OPEN_LIBRARY_FAILED +Failed to open \"%s\" !\n +; +;;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Project +; +; +MSGID_MENU_PROJECT_ABOUT +About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI +About MUI... +; +; +MSGID_MENU_PROJECT_QUIT +Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Rename.module V%ld.%ld\033n\n\ +%s\n\ +© 2004%s The Scalos Team +; +;----------------------------------------------------------- +; +MSGID_NEWNAME_DEFAULT +New_Drawer_Name +; +; +MSGID_TEXT_ENTERNAME +Enter name for a new drawer in \"%s\" +; +; +MSGID_LABEL_ENTERNAME +New Drawer +; +; +MSGID_LABEL_CREATE_ICON +Create Icon +; +; +MSGID_CHECKMARK_CREATEICON_SHORTHELP +If this checkbox is checked, an icon\n\ +will be created for the new drawer. +; +; +MSGID_TITLE_ERRORREQ +NewDrawer Error +; +; +MSGID_ERRORREQ_BODYTEXT +Could not create '%s'\n%s +; +; +MSGID_REQ_OK + _Ok +; +; +MSGID_TEXT_ENTERNAME_SHORTHELP +Path to create a new drawer.\n\n\ +It's possible to show all content of this gadget using\n\ +the scroller located at the bottom of the window.\n\ +Can be usefull for large path lenght. +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +NewDrawer.module Prefs startup failed +;NewDrawer.module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Try again|Quit +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_OPEN_PREFS_LIBRARY_FAILED +Failed to open \"%s\" !\n\ +Loading and saving of settings aren't availlables.\n +; +;----------------------------------------------------------- +; diff --git a/scalos/Modules/NewDrawer.MUI/NewDrawer.c b/scalos/Modules/NewDrawer.MUI/NewDrawer.c new file mode 100755 index 000000000..5af990bc8 --- /dev/null +++ b/scalos/Modules/NewDrawer.MUI/NewDrawer.c @@ -0,0 +1,1019 @@ +// NewDrawer.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* For the MAKE_ID macro */ +#include + +/* For the PrefsStruct structure */ +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include // +jmc+ + +#include "NewDrawer.h" + +#define NewDrawer_NUMBERS +#define NewDrawer_ARRAY +#define NewDrawer_CODE +#include STR(SCALOSLOCALE) + +//---------------------------------------------------------------------------- + +#define VERSION_MAJOR 40 +#define VERSION_MINOR 4 + +//---------------------------------------------------------------------------- + +#define Application_Return_Ok 1001 +#define Application_Return_Skip 1002 + +//---------------------------------------------------------------------------- + +#define PREFSENV "Env:Scalos/NewDrawer.prefs" +#define PREFSENVARC "Envarc:Scalos/NewDrawer.prefs" + +//---------------------------------------------------------------------------- + +#define KeyButtonHelp(name,key,HelpText)\ + TextObject,\ + ButtonFrame,\ + MUIA_Font , MUIV_Font_Button,\ + MUIA_Text_Contents, name,\ + MUIA_Text_PreParse, "\33c",\ + MUIA_Text_HiChar , key,\ + MUIA_ControlChar , key,\ + MUIA_InputMode , MUIV_InputMode_RelVerify,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShortHelp , HelpText,\ + MUIA_CycleChain , TRUE,\ + End + +#define CheckMarkHelp(selected, HelpTextID)\ + ImageObject,\ + ImageButtonFrame,\ + MUIA_InputMode , MUIV_InputMode_Toggle,\ + MUIA_Image_Spec , MUII_CheckMark,\ + MUIA_Image_FreeVert , TRUE,\ + MUIA_Selected , selected,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShowSelState , FALSE,\ + MUIA_CycleChain , TRUE,\ + MUIA_ShortHelp , GetLocString(HelpTextID), \ + End + +//---------------------------------------------------------------------------- + +static BOOL OpenLibraries(void); +static void CloseLibraries(void); +static void UpdateGadgets(struct WBStartup *wbMsg); +static void ReportError(LONG Result, CONST_STRPTR NewObjName); +static LONG MakeNewDrawer(struct WBStartup *wbMsg); +static SAVEDS(APTR) INTERRUPT OpenAboutMUIHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT OpenAboutHookFunc(struct Hook *hook, Object *o, Msg msg); +static STRPTR GetLocString(ULONG MsgId); +static BOOL CheckInfoData(const struct InfoData *info); +static BOOL isDiskWritable(BPTR dLock); +static BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev); +static void ReadPrefs(STRPTR PrefsFile); // +jmc+ - Load Prefs. +static void WritePrefs(STRPTR PrefsFile); // +jmc+ - Save pres. +static struct ScaWindowStruct *FindScalosWindow(BPTR dirLock); + +//---------------------------------------------------------------------------- + +#if !defined(__amigaos4__) && !defined(__AROS__) +#include + +long _stack = 16384; // minimum stack size, used by SAS/C startup code +#endif + +//---------------------------------------------------------------------------- + +extern struct ExecBase *SysBase; +struct IntuitionBase *IntuitionBase = NULL; +T_LOCALEBASE LocaleBase = NULL; +#ifndef __amigaos4__ +T_UTILITYBASE UtilityBase = NULL; +#endif +struct Library *MUIMasterBase = NULL; +struct Library *IconBase = NULL; +struct Library *IconobjectBase = NULL; +struct Library *PreferencesBase = NULL; +struct ScalosBase *ScalosBase = NULL; + +#ifdef __amigaos4__ +struct IntuitionIFace *IIntuition = NULL; +struct LocaleIFace *ILocale = NULL; +struct MUIMasterIFace *IMUIMaster = NULL; +struct IconIFace *IIcon = NULL; +struct IconobjectIFace *IIconobject = NULL; +struct PreferencesIFace *IPreferences = NULL; +struct ScalosIFace *IScalos = NULL; +#endif + +static BYTE gd_Selected = 1; // +jmc+ - CreateIcon gadget state. + +static struct Catalog *gb_Catalog; + +static struct Hook AboutHook = { { NULL, NULL }, HOOKFUNC_DEF(OpenAboutHookFunc), NULL }; +static struct Hook AboutMUIHook = { { NULL, NULL }, HOOKFUNC_DEF(OpenAboutMUIHookFunc), NULL }; + +//---------------------------------------------------------------------------- + +static Object *Group_Buttons2; +static Object *APP_Main; +static Object *WIN_Main; +static Object *WIN_AboutMUI; +static Object *OkButton, *CancelButton; +static Object *MenuAbout, *MenuAboutMUI, *MenuQuit; +static Object *TextEnterName; +static Object *StringNewName; +static Object *CheckmarkCreateIcon; + +//---------------------------------------------------------------------------- + + +int main(int argc, char *argv[]) +{ + LONG win_opened = 0; + struct WBStartup *WBenchMsg = + (argc == 0) ? (struct WBStartup *)argv : NULL; + +#if 0 + if (WBenchMsg) + { + LONG n; + + kprintf("NumArgs=%ld\n", WBenchMsg->sm_NumArgs); + + for (n=0; nsm_NumArgs; n++) + { + char xName[512]; + + NameFromLock(WBenchMsg->sm_ArgList[n].wa_Lock, xName, sizeof(xName)); + + kprintf("%ld. Lock=<%s> Name=<%s>\n", n, xName, WBenchMsg->sm_ArgList[n].wa_Name); + } + } +#endif + + if (NULL == WBenchMsg) + { + return 5; + } + if (WBenchMsg->sm_NumArgs < 2) + { + return 5; + } + + do { + ULONG sigs = 0; + BOOL Run = TRUE; + + if (!OpenLibraries()) + break; + + if (!CheckMCCVersion(MUIC_BetterString, 11, 0)) + break; + + gb_Catalog = OpenCatalogA(NULL, "Scalos/NewDrawer.catalog",NULL); + + ReadPrefs(PREFSENV); // load Newdrawer.prefs + + APP_Main = ApplicationObject, + MUIA_Application_Title, GetLocString(MSGID_TITLENAME), + MUIA_Application_Version, "$VER: Scalos NewDrawer.module V40.6 (" __DATE__ ") " COMPILER_STRING, + MUIA_Application_Copyright, "© The Scalos Team, 2004" CURRENTYEAR, + MUIA_Application_Author, "The Scalos Team", + MUIA_Application_Description, "Scalos NewDrawer module", + MUIA_Application_Base, "SCALOS_NEWDRAWER", + + SubWindow, WIN_Main = WindowObject, + MUIA_Window_Title, GetLocString(MSGID_TITLENAME), +// MUIA_Window_ID, MAKE_ID('M','A','I','N'), + MUIA_Window_AppWindow, TRUE, + MUIA_Window_UseBottomBorderScroller, TRUE, // +jmc+ + + MUIA_Window_TopEdge, MUIV_Window_TopEdge_Moused, + MUIA_Window_LeftEdge, MUIV_Window_LeftEdge_Moused, + + MUIA_Window_Width, MUIV_Window_Width_Screen(30), // +jmc+ + + WindowContents, VGroup, + Child, GroupObject, // +jmc+ + Child, ScrollgroupObject, + MUIA_Scrollgroup_VertBar, NULL, + MUIA_Scrollgroup_HorizBar, NULL, + MUIA_Scrollgroup_FreeHoriz, TRUE, + MUIA_Scrollgroup_FreeVert, FALSE, + MUIA_Scrollgroup_UseWinBorder, TRUE, + MUIA_Scrollgroup_Contents, + VirtgroupObject, + Child, TextEnterName = TextObject, + MUIA_Text_PreParse, MUIX_C, + MUIA_ShortHelp, GetLocString(MSGID_TEXT_ENTERNAME_SHORTHELP), + End, //TextObject + End, //VirtgroupObject + End, //ScrollgroupObject + End, //GroupObject + + Child, VSpace(1), + + Child, HGroup, + Child, Label1(GetLocString(MSGID_LABEL_ENTERNAME)), + Child, StringNewName = BetterStringObject, + StringFrame, + MUIA_String_Contents, GetLocString(MSGID_NEWNAME_DEFAULT), + MUIA_String_Reject, ":", + MUIA_Background, MUII_TextBack, + MUIA_String_MaxLen, 108, + MUIA_CycleChain, TRUE, + MUIA_BetterString_SelectSize, -strlen(GetLocString(MSGID_NEWNAME_DEFAULT)), + End, //StringObject + End, //HGroup + + Child, HGroup, + Child, RectangleObject, + End, + Child, Label1(GetLocString(MSGID_LABEL_CREATE_ICON)), + Child, CheckmarkCreateIcon = CheckMarkHelp(gd_Selected, MSGID_CHECKMARK_CREATEICON_SHORTHELP), + Child, RectangleObject, + End, + End, //HGroup + + Child, VSpace(1), + + Child, Group_Buttons2 = HGroup, + MUIA_Group_SameWidth, TRUE, + Child, OkButton = KeyButtonHelp(GetLocString(MSGID_OKBUTTON), + *GetLocString(MSGID_OKBUTTON_SHORT), GetLocString(MSGID_SHORTHELP_OKBUTTON)), + Child, CancelButton = KeyButtonHelp(GetLocString(MSGID_CANCELBUTTON), + *GetLocString(MSGID_CANCELBUTTON_SHORT), GetLocString(MSGID_SHORTHELP_CANCELBUTTON)), + End, //HGroup + End, //VGroup + End, //WindowObject + + MUIA_Application_Menustrip, MenustripObject, + Child, MenuObjectT(GetLocString(MSGID_MENU_PROJECT)), + + Child, MenuAbout = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUT), + End, + Child, MenuAboutMUI = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUTMUI), + End, + Child, MenuitemObject, + MUIA_Menuitem_Title, -1, + End, + Child, MenuQuit = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_QUIT), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_PROJECT_QUIT_SHORT), + End, + + End, //MenuObjectT + End, //MenuStripObject + + End; //ApplicationObject + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: \n", __LINE__)); + + if (NULL == APP_Main) + { + printf(GetLocString(MSGID_CREATE_APPLICATION_FAILED)); + break; + } + + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + WIN_Main, 3, MUIM_Set, MUIA_Window_Open, FALSE); + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + DoMethod(CancelButton, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + DoMethod(OkButton, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_Application_ReturnID, Application_Return_Ok); + + DoMethod(StringNewName, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, + APP_Main, 2, MUIM_Application_ReturnID, Application_Return_Ok); + + DoMethod(MenuAbout, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &AboutHook); + DoMethod(MenuAboutMUI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &AboutMUIHook); + DoMethod(MenuQuit, MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + // Loading of MUI objects ID settings. + // DoMethod(APP_Main, MUIM_Application_Load,MUIV_Application_Load_ENV); + + UpdateGadgets(WBenchMsg); + + set(WIN_Main, MUIA_Window_ActiveObject, StringNewName); + + set(WIN_Main, MUIA_Window_Open, TRUE); + get(WIN_Main, MUIA_Window_Open, &win_opened); + + if (!win_opened) + { + printf(GetLocString(MSGID_CREATE_MAINWINDOW_FAILED)); + break; + } + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: \n", __LINE__)); + + while (Run) + { + ULONG Action = DoMethod(APP_Main, MUIM_Application_NewInput, &sigs); + + switch (Action) + { + case Application_Return_Ok: + MakeNewDrawer(WBenchMsg); + WritePrefs(PREFSENV); + Run = FALSE; + break; + case MUIV_Application_ReturnID_Quit: + WritePrefs(PREFSENV); + Run = FALSE; + break; + } + + if (Run && sigs) + { + sigs = Wait(sigs | SIGBREAKF_CTRL_C); + + if (sigs & SIGBREAKF_CTRL_C) + { + Run = FALSE; + } + } + } + + set(WIN_Main, MUIA_Window_Open, FALSE); + } while (0); + + if (APP_Main) + MUI_DisposeObject(APP_Main); + if(gb_Catalog) + CloseCatalog(gb_Catalog); + + CloseLibraries(); + + return 0; +} + +//---------------------------------------------------------------------------- + +static BOOL OpenLibraries(void) +{ + MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN-1); + if (NULL == MUIMasterBase) + return FALSE; +#ifdef __amigaos4__ + else + { + IMUIMaster = (struct MUIMasterIFace *)GetInterface((struct Library *)MUIMasterBase, "main", 1, NULL); + if (NULL == IMUIMaster) + return FALSE; + } +#endif + + + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + if (NULL == IntuitionBase) + return FALSE; +#ifdef __amigaos4__ + else + { + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + return FALSE; + } +#endif + + LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 38); +#ifdef __amigaos4__ + if (NULL != LocaleBase) + ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL); +#endif + + IconBase = OpenLibrary("icon.library", 39); + if (NULL == IconBase) + return FALSE; +#ifdef __amigaos4__ + else + { + IIcon = (struct IconIFace *)GetInterface((struct Library *)IconBase, "main", 1, NULL); + if (NULL == IIcon) + return FALSE; + } +#endif + +#ifndef __amigaos4__ + UtilityBase = (T_UTILITYBASE) OpenLibrary("utility.library", 39); + if (NULL == UtilityBase) + return FALSE; +#endif + + IconobjectBase = OpenLibrary(ICONOBJECTNAME, 39); + if (NULL == IconobjectBase) + return FALSE; +#ifdef __amigaos4__ + else + { + IIconobject = (struct IconobjectIFace *)GetInterface((struct Library *)IconobjectBase, "main", 1, NULL); + if (NULL == IIconobject) + return FALSE; + } +#endif + + PreferencesBase = OpenLibrary("preferences.library", 0); + if (NULL == PreferencesBase) + { + printf(GetLocString(MSGID_OPEN_PREFS_LIBRARY_FAILED), "preferences.library"); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: PreferencesBase = NULL\n", __LINE__)); + } +#ifdef __amigaos4__ + else + { + IPreferences = (struct PreferencesIFace *)GetInterface((struct Library *)PreferencesBase, "main", 1, NULL); + if (NULL == IPreferences) + return FALSE; + } +#endif + + ScalosBase = (struct ScalosBase *) OpenLibrary(SCALOSNAME, 40); + if (NULL == ScalosBase) + return FALSE; +#ifdef __amigaos4__ + else + { + IScalos = (struct ScalosIFace *)GetInterface((struct Library *)ScalosBase, "main", 1, NULL); + if (NULL == IScalos) + return FALSE; + } +#endif //__amigaos4__ + + return TRUE; +} + +//---------------------------------------------------------------------------- + +static void CloseLibraries(void) +{ +#ifdef __amigaos4__ + if (IScalos) + { + DropInterface((struct Interface *)IScalos); + IScalos = NULL; + } +#endif + if (ScalosBase) + { + CloseLibrary((struct Library *) ScalosBase); + ScalosBase = NULL; + } +#ifdef __amigaos4__ + if (IPreferences) + { + DropInterface((struct Interface *)IPreferences); + IPreferences = NULL; + } +#endif + if (PreferencesBase) + { + CloseLibrary(PreferencesBase); + PreferencesBase = NULL; + } +#ifdef __amigaos4__ + if (IIconobject) + { + DropInterface((struct Interface *)IIconobject); + IIconobject = NULL; + } +#endif + if (IconobjectBase) + { + CloseLibrary(IconobjectBase); + IconobjectBase = NULL; + } +#ifndef __amigaos4__ + if (UtilityBase) + { + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } +#endif +#ifdef __amigaos4__ + if (ILocale) + { + DropInterface((struct Interface *)ILocale); + ILocale = NULL; + } +#endif + if (LocaleBase) + { + CloseLibrary((struct Library *)LocaleBase); + LocaleBase = NULL; + } +#ifdef __amigaos4__ + if (IIcon) + { + DropInterface((struct Interface *)IIcon); + IIcon = NULL; + } +#endif + if (IconBase) + { + CloseLibrary(IconBase); + IconBase = NULL; + } +#ifdef __amigaos4__ + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } +#endif + if (IntuitionBase) + { + CloseLibrary((struct Library *)IntuitionBase); + IntuitionBase = NULL; + } +#ifdef __amigaos4__ + if (IMUIMaster) + { + DropInterface((struct Interface *)IMUIMaster); + IMUIMaster = NULL; + } +#endif + if (MUIMasterBase) + { + CloseLibrary(MUIMasterBase); + MUIMasterBase = NULL; + } +} + +//---------------------------------------------------------------------------- + +static void UpdateGadgets(struct WBStartup *wbMsg) +{ + char xName[512]; + char LabelText[512]; + BOOL IsWriteable = isDiskWritable(wbMsg->sm_ArgList[1].wa_Lock); + + NameFromLock(wbMsg->sm_ArgList[1].wa_Lock, xName, sizeof(xName)); + + sprintf(LabelText, GetLocString(MSGID_TEXT_ENTERNAME), xName); + + SetAttrs(TextEnterName, + MUIA_Text_Contents, LabelText, + TAG_END); + + set(OkButton, MUIA_Disabled, !IsWriteable); + set(StringNewName, MUIA_Disabled, !IsWriteable); + set(CheckmarkCreateIcon, MUIA_Disabled, !IsWriteable); +} + +//---------------------------------------------------------------------------- + +static void ReportError(LONG Result, CONST_STRPTR NewObjName) +{ + char FaultText[256]; + + Fault(Result, "", FaultText, sizeof(FaultText)); + + MUI_Request(APP_Main, WIN_Main, 0, NULL, + GetLocString(MSGID_REQ_OK), + GetLocString(MSGID_ERRORREQ_BODYTEXT), + NewObjName, FaultText); +} + +//---------------------------------------------------------------------------- + +static LONG MakeNewDrawer(struct WBStartup *wbMsg) +{ + BPTR oldDir = CurrentDir(wbMsg->sm_ArgList[1].wa_Lock); + LONG Result = RETURN_OK; + STRPTR NewObjName = NULL; + struct ScaWindowStruct *ws; + APTR UndoStep = NULL; + BPTR newDirLock; + IPTR CreateIcon = FALSE; + + d1(kprintf(__FILE__ "/%s/%ld:\n", __FUNC__, __LINE__)); + + GetAttr(MUIA_String_Contents, StringNewName, (APTR) &NewObjName); + + ws = FindScalosWindow(wbMsg->sm_ArgList[1].wa_Lock); + + if ('/' == NewObjName[strlen(NewObjName) - 1]) // +jmc+ + { + NewObjName[strlen(NewObjName) - 1] = '\0'; + set(StringNewName, MUIA_String_Contents, NewObjName); + } + + d1(kprintf(__FILE__ "/%s/%ld:\n", __FUNC__, __LINE__)); + + GetAttr(MUIA_Selected, CheckmarkCreateIcon, &CreateIcon); + + if (ws) + { + UndoStep = (APTR) DoMethod(ws->ws_WindowTask->mt_MainObject, SCCM_IconWin_BeginUndoStep); + } + + if (NewObjName && strlen(NewObjName) > 0) + { + if (ws) + { + DoMethod(ws->ws_WindowTask->mt_MainObject, + SCCM_IconWin_AddUndoEvent, + UNDO_NewDrawer, + UNDOTAG_UndoMultiStep, UndoStep, + UNDOTAG_IconDirLock, wbMsg->sm_ArgList[1].wa_Lock, + UNDOTAG_IconName, NewObjName, + UNDOTAG_CreateIcon, CreateIcon, + TAG_END + ); + } + + newDirLock = CreateDir(NewObjName); + + d1(kprintf(__FILE__ "/%s/%ld:\n", __FUNC__, __LINE__)); + + if (newDirLock) + { + if (CreateIcon) + { + Object *IconObj; + + d1(kprintf(__FILE__ "/%s/%ld:\n", __FUNC__, __LINE__)); + + IconObj = GetDefIconObject(WBDRAWER, NULL); + + d1(kprintf(__FILE__ "/%s/%ld:\n", __FUNC__, __LINE__)); + + if (IconObj) + { + PutIconObjectTags(IconObj, NewObjName, + TAG_END); + DisposeIconObject(IconObj); + } + else + Result = IoErr(); + } + + UnLock(newDirLock); + } + else + { + Result = IoErr(); + } + } + + d1(kprintf(__FILE__ "/%s/%ld:\n", __FUNC__, __LINE__)); + + CurrentDir(oldDir); + + if (ws) + { + DoMethod(ws->ws_WindowTask->mt_MainObject, SCCM_IconWin_EndUndoStep, UndoStep); + SCA_UnLockWindowList(); + } + if (Result) + ReportError(Result, NewObjName); + + return Result; +} + + +//---------------------------------------------------------------------------- + +static STRPTR GetLocString(ULONG MsgId) +{ + struct NewDrawer_LocaleInfo li; + + li.li_Catalog = gb_Catalog; +#ifndef __amigaos4__ + li.li_LocaleBase = LocaleBase; +#else + li.li_ILocale = ILocale; +#endif + + return (STRPTR)GetNewDrawerString(&li, MsgId); +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT OpenAboutMUIHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + if (NULL == WIN_AboutMUI) + { + WIN_AboutMUI = MUI_NewObject(MUIC_Aboutmui, + MUIA_Window_RefWindow, WIN_Main, + MUIA_Aboutmui_Application, APP_Main, + End; + } + + if (WIN_AboutMUI) + set(WIN_AboutMUI, MUIA_Window_Open, TRUE); + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT OpenAboutHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + MUI_Request(APP_Main, WIN_Main, 0, NULL, + GetLocString(MSGID_ABOUTREQOK), + GetLocString(MSGID_ABOUTREQFORMAT), + VERSION_MAJOR, VERSION_MINOR, COMPILER_STRING, CURRENTYEAR); +} + +//---------------------------------------------------------------------------- + +// return TRUE if Disk is writable +static BOOL CheckInfoData(const struct InfoData *info) +{ + BOOL Result = TRUE; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: DiskType=%ld DiskState=%ld\n", __LINE__, info->id_DiskType, info->id_DiskState)); + + switch (info->id_DiskType) + { + case ID_NO_DISK_PRESENT: + case ID_UNREADABLE_DISK: + Result = FALSE; + break; + } + + if (ID_WRITE_PROTECTED == info->id_DiskState) + Result = FALSE; + + return Result; +} + +//---------------------------------------------------------------------------- + +static BOOL isDiskWritable(BPTR dLock) +{ + struct InfoData *info = malloc(sizeof(struct InfoData)); + BOOL Result = TRUE; + + if (info) + { + Info(dLock, info); + + if (!CheckInfoData(info)) + Result = FALSE; + + free(info); + } + + return Result; +} + +//---------------------------------------------------------------------------- + +// Checks if a certain version of a MCC is available +static BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev) +{ + BOOL flush = TRUE; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: %s ", name, __LINE__);) + + while (1) + { + ULONG ver = 0; + ULONG rev = 0; + struct Library *base; + char libname[256]; + + // First we attempt to acquire the version and revision through MUI + Object *obj = MUI_NewObject((STRPTR) name, TAG_DONE); + if (obj) + { + get(obj, MUIA_Version, &ver); + get(obj, MUIA_Revision, &rev); + + MUI_DisposeObject(obj); + + if(ver > minver || (ver == minver && rev >= minrev)) + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: v%ld.%ld found through MUIA_Version/Revision\n", __LINE__, ver, rev);) + return TRUE; + } + } + + // If we did't get the version we wanted, let's try to open the + // libraries ourselves and see what happens... + stccpy(libname, "PROGDIR:mui", sizeof(libname)); + AddPart(libname, name, sizeof(libname)); + + if ((base = OpenLibrary(&libname[8], 0)) || (base = OpenLibrary(&libname[0], 0))) + { + UWORD OpenCnt = base->lib_OpenCnt; + + ver = base->lib_Version; + rev = base->lib_Revision; + + CloseLibrary(base); + + // we add some additional check here so that eventual broken .mcc also have + // a chance to pass this test (i.e. Toolbar.mcc is broken) + if (ver > minver || (ver == minver && rev >= minrev)) + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: v%ld.%ld found through OpenLibrary()\n", __LINE__, ver, rev);) + return TRUE; + } + + if (OpenCnt > 1) + { + if (MUI_Request(NULL, NULL, 0L, GetLocString(MSGID_STARTUP_FAILURE), + GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), GetLocString(MSGID_STARTUP_MCC_IN_USE), + name, minver, minrev, ver, rev)) + { + flush = TRUE; + } + else + break; + } + + // Attempt to flush the library if open count is 0 or because the + // user wants to retry (meaning there's a chance that it's 0 now) + + if (flush) + { + struct Library *result; + + Forbid(); + if ((result = (struct Library *) FindName(&((struct ExecBase *)SysBase)->LibList, name))) + RemLibrary(result); + Permit(); + flush = FALSE; + } + else + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: couldn`t find minimum required version.\n", __LINE__);) + + // We're out of luck - open count is 0, we've tried to flush + // and still haven't got the version we want + if (MUI_Request(NULL, NULL, 0L, GetLocString(MSGID_STARTUP_FAILURE), + GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), GetLocString(MSGID_STARTUP_OLD_MCC), + name, minver, minrev, ver, rev)) + { + flush = TRUE; + } + else + break; + } + } + else + { + // No MCC at all - no need to attempt flush + flush = FALSE; + if (!MUI_Request(NULL, NULL, 0L, GetLocString(MSGID_STARTUP_FAILURE), + GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), GetLocString(MSGID_STARTUP_MCC_NOT_FOUND), + name, minver, minrev)) + { + break; + } + } + } + + return FALSE; +} + +//---------------------------------------------------------------------------- +// +jmc+ +static void ReadPrefs(STRPTR PrefsFile) +{ + struct PrefsHandle *Nd_prefhandle; + LONG ID_GAD; + struct PrefsStruct *prefstruct; + BPTR EnvLock; + + if (PreferencesBase) + { + Nd_prefhandle = AllocPrefsHandle("NDrawer"); + ID_GAD = MAKE_ID('M','A','I','N'); + if(Nd_prefhandle) + { + if(EnvLock = Lock(PrefsFile, ACCESS_READ)) + { + ReadPrefsHandle(Nd_prefhandle, PrefsFile); + if(NULL != (prefstruct = FindPreferences(Nd_prefhandle, ID_GAD, NDP_IconCreation)) ) + GetPreferences(Nd_prefhandle, ID_GAD, NDP_IconCreation, &gd_Selected, sizeof(gd_Selected) ); + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: ID_GAD=%08lx NDP_IconCreation=%08lx gd_Selected = %ld\n", __LINE__, ID_GAD, NDP_IconCreation, gd_Selected)); + + UnLock(EnvLock); + } + + FreePrefsHandle(Nd_prefhandle); + } + } +} + +//---------------------------------------------------------------------------- +// +jmc+ +static void WritePrefs(STRPTR PrefsFile) +{ + APTR Nd_prefhandle; + LONG ID_GAD; + + if (PreferencesBase) + { + Nd_prefhandle = AllocPrefsHandle("NDrawer"); + ID_GAD = MAKE_ID('M','A','I','N'); + if(Nd_prefhandle) + { + gd_Selected = mui_getv(CheckmarkCreateIcon, MUIA_Selected); + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: gd_Selected = %ld\n", __LINE__, gd_Selected)); + + SetPreferences(Nd_prefhandle, ID_GAD, NDP_IconCreation, &gd_Selected, sizeof(gd_Selected) ); + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: ID_GAD=%08lx NDP_IconCreation=%08lx gd_Selected = %ld\n", __LINE__, ID_GAD, NDP_IconCreation, gd_Selected)); + + WritePrefsHandle(Nd_prefhandle, PrefsFile); + + FreePrefsHandle(Nd_prefhandle); + } + } +} + +//---------------------------------------------------------------------------- + +IPTR mui_getv(APTR obj, ULONG attr) +{ + IPTR v; + GetAttr(attr, obj, &v); + return (v); +} + +//---------------------------------------------------------------------------- + +static struct ScaWindowStruct *FindScalosWindow(BPTR dirLock) +{ + struct ScaWindowList *wl; + BOOL Found = FALSE; + + d1(KPrintF(__FILE__ "/%s/%ld: START \n", __FUNC__, __LINE__)); + debugLock_d1(dirLock); + + wl = SCA_LockWindowList(SCA_LockWindowList_Shared); + + if (wl) + { + struct ScaWindowStruct *ws; + + for (ws = wl->wl_WindowStruct; !Found && ws; ws = (struct ScaWindowStruct *) ws->ws_Node.mln_Succ) + { + if (((BPTR)NULL == dirLock && (BPTR)NULL == ws->ws_Lock) || (LOCK_SAME == SameLock(dirLock, ws->ws_Lock))) + { + d1(KPrintF(__FILE__ "/%s/%ld: END ws=%08lx\n", __FUNC__, __LINE__, ws)); + return ws; + } + } + SCA_UnLockWindowList(); + } + + d1(KPrintF(__FILE__ "/%s/%ld: END (not found)\n", __FUNC__, __LINE__)); + return NULL; +} + +//---------------------------------------------------------------------------- diff --git a/scalos/Modules/NewDrawer.MUI/NewDrawer.cd b/scalos/Modules/NewDrawer.MUI/NewDrawer.cd new file mode 100755 index 000000000..e52b207a7 --- /dev/null +++ b/scalos/Modules/NewDrawer.MUI/NewDrawer.cd @@ -0,0 +1,159 @@ +; NewDrawer.cd +; version $VER: NewDrawer.catalog 40.1 (26 Feb 2005 21:03:45) +; codeset 0s +; language english +; +;#arrayopts static __far +; +; +MSGID_TITLENAME (//) +Scalos NewDrawer +; +; +MSGID_OKBUTTON (//) +New Drawer +; +; +MSGID_OKBUTTON_SHORT (/1/1) +n +; +; +MSGID_SHORTHELP_OKBUTTON (//) +Create new drawer. +; +; +MSGID_CANCELBUTTON (//) +Cancel +; +; +MSGID_CANCELBUTTON_SHORT (/1/1) +c +; +; +MSGID_SHORTHELP_CANCELBUTTON (//) +Discard all changes and\n\ +do not create anything. +; +; +MSGID_CREATE_APPLICATION_FAILED (//) +Failed to create Application.\n +; +; +MSGID_CREATE_MAINWINDOW_FAILED (//) +Failed to open main window !\n +; +; +MSGID_OPEN_LIBRARY_FAILED (//) +Failed to open \"%s\" !\n +; +;;----------------------------------------------------------- +; +MSGID_MENU_PROJECT (2000//) +Project +; +; +MSGID_MENU_PROJECT_ABOUT (//) +About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI (//) +About MUI... +; +; +MSGID_MENU_PROJECT_QUIT (//) +Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT (//) +Q +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK (3000//) +_OK +; +; +MSGID_ABOUTREQFORMAT (//) +\33c\033bScalos NewDrawer.module V%ld.%ld\033n\n\ +%s\n\ +© 2004%s The Scalos Team +; +;----------------------------------------------------------- +; +MSGID_NEWNAME_DEFAULT (4001//) +New_Drawer_Name +; +; +MSGID_TEXT_ENTERNAME (//) +Enter name for a new drawer in \"%s\" +; +; +MSGID_LABEL_ENTERNAME (//) +New Drawer +; +; +MSGID_LABEL_CREATE_ICON (//) +Create Icon +; +; +MSGID_CHECKMARK_CREATEICON_SHORTHELP (//) +If this checkbox is checked, an icon\n\ +will be created for the new drawer. +; +; +MSGID_TITLE_ERRORREQ (//) +NewDrawer Error +; +; +MSGID_ERRORREQ_BODYTEXT (//) +Could not create '%s'\n%s +; +; +MSGID_REQ_OK (//) + _Ok +; +; +MSGID_TEXT_ENTERNAME_SHORTHELP (//) +Path to create a new drawer.\n\n\ +It's possible to show all content of this gadget using\n\ +the scroller located at the bottom of the window.\n\ +Can be usefull for large path lenght. +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE (5000//) +NewDrawer.module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD (//) +Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_OPEN_PREFS_LIBRARY_FAILED (//) +Failed to open \"%s\" !\n\ +Loading and saving of settings aren't availlables.\n +; +;----------------------------------------------------------- +; +; diff --git a/scalos/Modules/NewDrawer.MUI/NewDrawer.h b/scalos/Modules/NewDrawer.MUI/NewDrawer.h new file mode 100755 index 000000000..eb81e998d --- /dev/null +++ b/scalos/Modules/NewDrawer.MUI/NewDrawer.h @@ -0,0 +1,35 @@ +// NewDrawer.h +// $Date$ +// $Revision$ + + +#ifndef NEWDRAWER_H +#define NEWDRAWER_H + +#define NDP_IconCreation 0x80000001 + +#define d1(x) ; +#define d2(x) x; + +#define debugLock_d1(LockName) ; +#define debugLock_d2(LockName) \ + {\ + char xxName[200];\ + strcpy(xxName, "");\ + NameFromLock((LockName), xxName, sizeof(xxName));\ + KPrintF("%s/%s/%ld: " #LockName "=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, LockName, xxName);\ + } + +extern int kprintf(CONST_STRPTR, ...); +extern int KPrintF(CONST_STRPTR, ...); + +IPTR mui_getv(APTR, ULONG ); + +struct NewDrawer_LocaleInfo +{ + APTR li_LocaleBase; + APTR li_Catalog; + struct LocaleIFace *li_ILocale; +}; + +#endif /* NEWDRAWER_H */ diff --git a/scalos/Modules/NewDrawer.MUI/config.mk b/scalos/Modules/NewDrawer.MUI/config.mk new file mode 100755 index 000000000..039e61586 --- /dev/null +++ b/scalos/Modules/NewDrawer.MUI/config.mk @@ -0,0 +1,60 @@ +# $Date: 2011-07-12 03:41:40 +0200 (Di, 12. Jul 2011) $ +# $Revision: 777 $ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +SCALOS_LOCALE = $(OBJDIR)/NewDrawer_Locale.h + +CFLAGS += -D SCALOSLOCALE=$(SCALOS_LOCALE) + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +INCLUDES += # + +LFLAGS += # + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +INCLUDES += # + +LFLAGS += # + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +INCLUDES += # + +LFLAGS += -lmui + + +else + +############################################################################### +# AmigaOS + +INCLUDES += # + +LFLAGS += # + +endif +endif +endif diff --git a/scalos/Modules/NewDrawer.MUI/makefile b/scalos/Modules/NewDrawer.MUI/makefile new file mode 100755 index 000000000..0a2ecb885 --- /dev/null +++ b/scalos/Modules/NewDrawer.MUI/makefile @@ -0,0 +1,121 @@ +# Makefile for NewDrawer.module (MUI) +# using GNU make and SAS/C +# $Date$ +# $Revision$ +##################################################################### + +TOPLEVEL = / +SUBDIRMAKE = $(MAKE) -s -C +CHEADERS = +CC = sc +CFLAGS = optimize nostackcheck nochkabort debug=s \ + define SCALOSLOCALE=$(SCALOS_LOCALE) \ + idlen=128 strmer nover streq data=far \ + ignore=217 idir=sc:include/ \ + idir=include: idir=//include +AS = phxass +AFLAGS = QUIET m=68020 linedebug opt=NRQB i=include: +LD = slink +LNFLAGS = quiet batch noicons stripdebug +LNDBFLAGS = quiet batch noicons addsym +LIBS = LIB:sc.lib LIB:debug.lib LIB:amiga.lib +CATCOMP = catcomp +CSTARTUP = LIB:c.o +OBJDIR = .sasobj + +SCALOS_LOCALE = $(OBJDIR)/NewDrawer_Locale.h + +##################################################################### + +.SUFFIXES: .asm + +##################################################################### + +NAME = .bin_os3/NewDrawer.module +DBGNAME = $(NAME).debug +CATCOMPH = $(SCALOS_LOCALE) +FLEXCAT = FlexCat +CAT_FILE = Scalos/NewDrawer.catalog +DESTCAT = Locale:Catalogs +ALLCATS = Catalogs/deutsch/$(CAT_FILE) \ + Catalogs/français/$(CAT_FILE) + +##################################################################### + +all: $(NAME) \ + $(DBGNAME) \ + allcatalogs \ + +##################################################################### + +# make all Scalos .catalogs +allcatalogs: + @$(SUBDIRMAKE) Catalogs/deutsch/Scalos + @$(SUBDIRMAKE) Catalogs/français/Scalos + +##################################################################### + +CSRCS = NewDrawer.c + +##################################################################### + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +##################################################################### + +XOBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(CSRCS:%.c=$(OBJDIR)/%.o) +OBJS = $(XOBJS) + +##################################################################### + +$(NAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNFLAGS) + +$(DBGNAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNDBFLAGS) + +##################################################################### + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $< objectname $@ + +$(OBJDIR)/%.o : %.asm + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +##################################################################### + +$(CATCOMPH) : NewDrawer.cd + @printf '\033[32mMake CatComp header: \033[31m\033[1m$(CATCOMPH) \033[32mfrom \033[31m$<\033[0m\n' + @$(FLEXCAT) $< $@=$(TOPLEVEL)/CatComp_h.sd + +$(OBJDIR)/NewDrawer.o : NewDrawer.c NewDrawer.h $(CATCOMPH) + +##################################################################### + +$(NAME) $(DBGNAME) : $(OBJS) + +##################################################################### + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(NAME) \033[0mto \033[31m\033[1mScalos:modules/ \033[0m\n' + @copy $(NAME) Scalos:modules/ + @avail flush + @printf '\033[32mInstall: \033[31m\033[1m$(CAT_FILE)\033[0m\n' + -@copy "catalogs/deutsch/$(CAT_FILE)" "$(DESTCAT)/Deutsch/Scalos/" clone + -@copy "catalogs/français/$(CAT_FILE)" "$(DESTCAT)/français/Scalos/" clone + +##################################################################### + +# A little something to clean it all up +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + -@delete $(XOBJS) $(NAME) $(DBGNAME) \ + $(CATCOMPH) + @printf '\033[0m' + +##################################################################### diff --git a/scalos/Modules/NewDrawer.MUI/makefile-new b/scalos/Modules/NewDrawer.MUI/makefile-new new file mode 100755 index 000000000..8af3a2bd5 --- /dev/null +++ b/scalos/Modules/NewDrawer.MUI/makefile-new @@ -0,0 +1,95 @@ +# $Date: 2011-07-12 03:41:40 +0200 (Di, 12. Jul 2011) $ +# $Revision: 777 $ +############################################################# +TOPLEVEL = $(shell pwd)/../.. + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + SDPATH=/ +else + SDPATH=../.. +endif + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(OBJDIR)/NewDrawer.o \ + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Subdirs +# + +SUBDIRS = $(filter-out Catalogs/sample/Scalos, $(wildcard Catalogs/*/Scalos)) + +############################################################################## +# +# Targets +# + +NAME = NewDrawer.module +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) \ + all_subdirs + +############################################################################## + +$(OBJDIR)/%.o: $(TOOLTYPE_DIR)/%.c + @$(run-cc) + +$(OBJDIR)/%.o: $(ICONOBJMCC_DIR)/%.c + @$(run-cc) + +NewDrawer.c : $(OBJDIR)/NewDrawer_Locale.h + +$(OBJDIR)/NewDrawer_Locale.h : NewDrawer.cd + @$(ECHO) "FlexCat $@" + $(FLEXCAT) $< $@=$(SDPATH)/CatComp_h.sd + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + @$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) +ifneq ($(MACHINE), ppc-amigaos) + -@chmod u+x $@ +endif + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) Scalos:modules/ clone + +install: install_subdirs + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* \ + $(OBJDIR)/NewDrawer_Locale.h + +clean: clean_subdirs + +############################################################################## + diff --git a/scalos/Modules/NewDrawer.Reaction/NDStrings.asm b/scalos/Modules/NewDrawer.Reaction/NDStrings.asm new file mode 100644 index 000000000..1dbed85f1 --- /dev/null +++ b/scalos/Modules/NewDrawer.Reaction/NDStrings.asm @@ -0,0 +1,11 @@ +; NDStrings.asm +; 10 Aug 2001 18:58:56 + +CATCOMP_NUMBERS: equ 1 +CATCOMP_STRINGS: equ 1 + + section tpStrings,DATA + + include "NewDrawerStrings.i" + + end diff --git a/scalos/Modules/NewDrawer.Reaction/NewDrawer.c b/scalos/Modules/NewDrawer.Reaction/NewDrawer.c new file mode 100644 index 000000000..958fc8fa3 --- /dev/null +++ b/scalos/Modules/NewDrawer.Reaction/NewDrawer.c @@ -0,0 +1,474 @@ +// NewDrawer.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include // +jmc+ + +#include "NewDrawerGUI.h" + +#define CATCOMP_NUMBERS +#define CATCOMP_STRINGS +#include "NewDrawerStrings.h" + + +#define d1(x) ; +#define d2(x) x; + +#define CATSTR(id) GetCatalogStr(gb_Catalog, id, (STRPTR) id ## _STR) +#define CATSTRSTR(id,str) GetCatalogStr(gb_Catalog, id, (STRPTR) str) + + +extern int kprintf(CONST_STRPTR, ...); + +static BOOL OpenLibraries(void); +static void CloseLibraries(void); +static ULONG MessageLoop(void); +static void UpdateGadgets(struct WBStartup *WBenchMsg); +static LONG MakeNewDrawer(void); +static void ReportError(LONG Result, CONST_STRPTR NewObjName); +static struct ScaWindowStruct *FindScalosWindow(BPTR dirLock); + + +#define PROGNAME "NewDrawer.module" +#define VERSIONR "1.1" +#define PROGDATE "29 Jun 2005 18:18:23" +#define COPYRIGT "© The Scalos Team, 2004" CURRENTYEAR + +const char *version = "\0$VER: " PROGNAME " " VERSIONR " (" PROGDATE ") - " COPYRIGT "\n"; + + +struct Library *ResourceBase; +struct IntuitionBase *IntuitionBase; +struct Library *GadToolsBase; +T_LOCALEBASE LocaleBase; +struct Library *IconBase; +struct Library *IconobjectBase = NULL; +struct ScalosBase *ScalosBase = NULL; +T_UTILITYBASE UtilityBase; + +static struct Screen *gb_Screen; +static struct Window *gb_Window; +static struct Gadget **gb_Gadgets; +static struct Catalog *gb_Catalog; +static struct MsgPort *gb_IDCMPort; +static struct MsgPort *gb_AppPort; +static Object *gb_WindowObj; +RESOURCEFILE gb_Resource; + +static char LabelText[1024]; + + +main() +{ +#if 0 + if (WBenchMsg) + { + LONG n; + + kprintf("NumArgs=%ld\n", WBenchMsg->sm_NumArgs); + + for (n=0; nsm_NumArgs; n++) + { + char xName[512]; + + NameFromLock(WBenchMsg->sm_ArgList[n].wa_Lock, xName, sizeof(xName)); + + kprintf("%ld. Lock=<%s> Name=<%s>\n", n, xName, WBenchMsg->sm_ArgList[n].wa_Name); + } + } +#endif + + if (NULL == WBenchMsg) + { + return 5; + } + if (WBenchMsg->sm_NumArgs < 2) + { + return 5; + } + + do { + if (!OpenLibraries()) + break; + + gb_Catalog = OpenCatalogA(NULL, PROGNAME ".catalog",NULL); + + gb_Screen = LockPubScreen(NULL); + if (NULL == gb_Screen) + break; + + gb_IDCMPort = CreateMsgPort(); + if (NULL == gb_IDCMPort) + break; + + gb_AppPort = CreateMsgPort(); + if (NULL == gb_AppPort) + break; + + gb_Resource = RL_OpenResource(RCTResource, gb_Screen, gb_Catalog); + + gb_WindowObj = RL_NewObject(gb_Resource, WIN_NewDrawer_ID, + WINDOW_SharedPort, gb_IDCMPort, + WINDOW_AppPort, gb_AppPort, + TAG_DONE); + if (NULL == gb_WindowObj) + break; + + gb_Gadgets = (struct Gadget **) RL_GetObjectArray(gb_Resource, gb_WindowObj, GROUP_NewDrawer_ID); + if (NULL == gb_Gadgets) + break; + + UpdateGadgets(WBenchMsg); + + gb_Window = RA_OpenWindow(gb_WindowObj); + if (NULL == gb_Window) + break; + + MessageLoop(); + } while (0); + + if (gb_WindowObj) + DoMethod(gb_WindowObj, WM_CLOSE); + if (gb_Resource) + RL_CloseResource(gb_Resource); + if(gb_Catalog) + CloseCatalog(gb_Catalog); + if (gb_AppPort) + DeleteMsgPort(gb_AppPort); + if (gb_IDCMPort) + DeleteMsgPort(gb_IDCMPort); + if (gb_Screen) + UnlockPubScreen(NULL, gb_Screen); + + CloseLibraries(); +} + + +static BOOL OpenLibraries(void) +{ + ResourceBase = OpenLibrary("resource.library", 44); + if (NULL == ResourceBase) + return FALSE; + + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + if (NULL == IntuitionBase) + return FALSE; + + GadToolsBase = OpenLibrary("gadtools.library", 38); + if (NULL == GadToolsBase) + return FALSE; + + LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 38); + if (NULL == LocaleBase) + return FALSE; + + IconBase = OpenLibrary("icon.library", 39); + if (NULL == IconBase) + return FALSE; + + UtilityBase = (T_UTILITYBASE) OpenLibrary("utility.library", 39); + if (NULL == UtilityBase) + return FALSE; + + IconobjectBase = OpenLibrary(ICONOBJECTNAME, 39); + if (NULL == IconobjectBase) + return FALSE; + + ScalosBase = (struct ScalosBase *) OpenLibrary(SCALOSNAME, 40); + if (NULL == ScalosBase) + return FALSE; + + return TRUE; +} + + +static void CloseLibraries(void) +{ + if (ScalosBase) + { + CloseLibrary((struct Library *) ScalosBase); + ScalosBase = NULL; + } + if (IconobjectBase) + { + CloseLibrary(IconobjectBase); + IconobjectBase = NULL; + } + if (UtilityBase) + { + CloseLibrary(UtilityBase); + UtilityBase = NULL; + } + if (IconBase) + { + CloseLibrary(IconBase); + IconBase = NULL; + } + if (LocaleBase) + { + CloseLibrary(LocaleBase); + LocaleBase = NULL; + } + if (GadToolsBase) + { + CloseLibrary(GadToolsBase); + GadToolsBase = NULL; + } + if (IntuitionBase) + { + CloseLibrary((struct Library *)IntuitionBase); + IntuitionBase = NULL; + } + if (ResourceBase) + { + CloseLibrary(ResourceBase); + ResourceBase = NULL; + } +} + + +static ULONG MessageLoop(void) +{ + ULONG res = RETURN_FAIL; + ULONG windowsignal, signals; + + GetAttr(WINDOW_SigMask, gb_WindowObj, &windowsignal); + + while (res == RETURN_FAIL) + { + ActivateGadget(gb_Gadgets[String_NewDrawer], gb_Window, NULL); + + signals = Wait(windowsignal); + + if (signals & windowsignal) + { + ULONG result; + WORD code; + + while ((result = RA_HandleInput(gb_WindowObj, &code)) != WMHI_LASTMSG) + { + d1(kprintf("result=%08lx code=%04lx\n", result, code)); + + switch (result & WMHI_CLASSMASK) + { + case WMHI_CLOSEWINDOW: + res = RETURN_OK; + break; + + case WMHI_GADGETUP: + { +// const UWORD groupid = RL_GROUPID(result); + const UWORD gadid = RL_GADGETID(result); + + switch (gadid) + { + case String_NewDrawer: + d1(kprintf("WMHI_GADGETUP code=%04lx\n", code)); + if (0 == code) + MakeNewDrawer(); + res = RETURN_OK; + break; + + case OkButton: + MakeNewDrawer(); + res = RETURN_OK; + break; + + case Cancelbutton: + res = RETURN_OK; + break; + + default: + break; + } + } + break; + } + } + } + } + + return( res ); +} + + +static void UpdateGadgets(struct WBStartup *WBenchMsg) +{ + char xName[512]; + STRPTR NewObjName = ""; + ULONG Mark; + + NameFromLock(WBenchMsg->sm_ArgList[1].wa_Lock, xName, sizeof(xName)); + + sprintf(LabelText, CATSTR(MSGID_LABEL_ENTERNAME), xName); + + SetAttrs(gb_Gadgets[TextLine_EnterName], + GA_Text, LabelText, + TAG_END); + + GetAttr(STRINGA_TextVal, gb_Gadgets[String_NewDrawer], (ULONG *) &NewObjName); + + Mark = (0 << 16) + strlen(NewObjName); + SetAttrs(gb_Gadgets[String_NewDrawer], + STRINGA_Mark, Mark, + TAG_END); +} + + +static LONG MakeNewDrawer(void) +{ + BPTR oldDir = CurrentDir(WBenchMsg->sm_ArgList[1].wa_Lock); + LONG Result = RETURN_OK; + STRPTR NewObjName = NULL; + struct ScaWindowStruct *ws; + APTR UndoStep = NULL; + BPTR newDirLock; + ULONG CreateIcon = FALSE; + + ws = FindScalosWindow(WBenchMsg->sm_ArgList[1].wa_Lock); + + GetAttr(STRINGA_TextVal, gb_Gadgets[String_NewDrawer], (ULONG *) &NewObjName); + GetAttr(GA_Selected, gb_Gadgets[CheckBox_CreateIcon], &CreateIcon); + + if (ws) + { + UndoStep = (APTR) DoMethod(ws->ws_WindowTask->mt_MainObject, SCCM_IconWin_BeginUndoStep); + } + + if (NewObjName && strlen(NewObjName) > 0) + { + if (ws) + { + DoMethod(ws->ws_WindowTask->mt_MainObject, + SCCM_IconWin_AddUndoEvent, + UNDO_NewDrawer, + UNDOTAG_UndoMultiStep, UndoStep, + UNDOTAG_IconDirLock, WBenchMsg->sm_ArgList[1].wa_Lock, + UNDOTAG_IconName, NewObjName, + UNDOTAG_CreateIcon, CreateIcon, + TAG_END + ); + } + newDirLock = CreateDir(NewObjName); + if (newDirLock) + { + if (CreateIcon) + { + Object *IconObj; + + IconObj = GetDefIconObject(WBDRAWER, NULL); + if (IconObj) + { + PutIconObjectTags(IconObj, NewObjName, + TAG_END); + DisposeIconObject(IconObj); + } + else + Result = IoErr(); + } + + UnLock(newDirLock); + } + else + { + Result = IoErr(); + } + } + + if (ws) + { + DoMethod(ws->ws_WindowTask->mt_MainObject, SCCM_IconWin_EndUndoStep, UndoStep); + SCA_UnLockWindowList(); + } + + CurrentDir(oldDir); + + if (Result) + ReportError(Result, NewObjName); + + return Result; +} + + +static void ReportError(LONG Result, CONST_STRPTR NewObjName) +{ + char FaultText[256]; + struct EasyStruct ezStruct; + + Fault(Result, "", FaultText, sizeof(FaultText)); + + ezStruct.es_StructSize = sizeof(struct EasyStruct); + ezStruct.es_Flags = 0; + ezStruct.es_Title = CATSTR(MSGID_TITLE_ERRORREQ); + ezStruct.es_TextFormat = CATSTR(MSGID_ERRORREQ_BODYTEXT); + ezStruct.es_GadgetFormat = CATSTR(MSGID_REQ_OK); + + EasyRequest(gb_Window, &ezStruct, NULL, + NewObjName, FaultText); +} + +//---------------------------------------------------------------------------- + +static struct ScaWindowStruct *FindScalosWindow(BPTR dirLock) +{ + struct ScaWindowList *wl; + BOOL Found = FALSE; + + d1(KPrintF(__FILE__ "/%s/%ld: START \n", __FUNC__, __LINE__)); + + wl = SCA_LockWindowList(SCA_LockWindowList_Shared); + + if (wl) + { + struct ScaWindowStruct *ws; + + for (ws = wl->wl_WindowStruct; !Found && ws; ws = (struct ScaWindowStruct *) ws->ws_Node.mln_Succ) + { + if (((BPTR)NULL == dirLock && (BPTR)NULL == ws->ws_Lock) || (LOCK_SAME == SameLock(dirLock, ws->ws_Lock))) + { + return ws; + } + } + SCA_UnLockWindowList(); + } + + return NULL; +} + +//---------------------------------------------------------------------------- diff --git a/scalos/Modules/NewDrawer.Reaction/NewDrawerGUI.cd b/scalos/Modules/NewDrawer.Reaction/NewDrawerGUI.cd new file mode 100755 index 000000000..ab3382a95 --- /dev/null +++ b/scalos/Modules/NewDrawer.Reaction/NewDrawerGUI.cd @@ -0,0 +1,32 @@ +; *** catalog description file of "NewDrawerGUI.res" +; +MSGID_WINTITLE_NEWDRAWER (256//) +Add a new drawer +; +MSGID_LABEL_ENTERNAME (257//) +Enter Name for a new Drawer in '%s' +; +MSGID_NEWNAME_DEFAULT (258//) +New_Drawer_Name +; +MSGID_LABEL_NEWDRAWER (259//) +New Drawer +; +MSGID_GADGETTEXT_CREATEICON (260//) +Create _Icon +; +MSGID_BUTTON_OK (261//) +_Ok +; +MSGID_BUTTON_CANCEL (262//) +_Cancel +; +MSGID_TITLE_ERRORREQ (263//) +NewDrawer Error +; +MSGID_ERRORREQ_BODYTEXT (264//) +Could not create new drawer\n'%s'\n%s +; +MSGID_REQ_OK (265//) + _Ok +; diff --git a/scalos/Modules/NewDrawer.Reaction/NewDrawerGUI.h b/scalos/Modules/NewDrawer.Reaction/NewDrawerGUI.h new file mode 100755 index 000000000..54a5870e9 --- /dev/null +++ b/scalos/Modules/NewDrawer.Reaction/NewDrawerGUI.h @@ -0,0 +1,11 @@ +/* header file of "NewDrawerGUI.res" */ +extern char RCTResource[]; +#define WIN_NewDrawer_ID 1 +#define GROUP_NewDrawer_ID 2 +#define TextLine_EnterName 15 +#define String_NewDrawer 11 +#define Label_NewDrawer 10 +#define CheckBox_CreateIcon 13 +#define OkButton 5 +#define Cancelbutton 6 +#define REQ_ReportError_ID 3 diff --git a/scalos/Modules/NewDrawer.Reaction/NewDrawerGUI.res b/scalos/Modules/NewDrawer.Reaction/NewDrawerGUI.res new file mode 100755 index 0000000000000000000000000000000000000000..22dc468371eadd307775b1b2f685f21e20335440 GIT binary patch literal 3030 zcwW6$TaVjB6rMQAUc8}Mc6(EKu~e3-QngZ1h2Q~!V^7nliM?^WN-I@zon+XCP3^7Y zZMJ<{peuxg#0x)#pTQ$Pg?E@U7kgqh$Q2T!MCZ)Rxu0*w<6+xE2vz7$r?ftF>>-~c zP48d(nbPfH#|a#=u#<2>lAvRYefU=eZ7inIBwp-~XW@JfYv%|>plePhMrcH2VN94h zUAx&Ev^#b{t@<6mivtG_ZO-}4Avz>2ihW0g^vC%f|w$x*C2<@~z_wb-tAq{pwitZjr4f_9J7QTs3 z)BW*_>1;Ab)}ty;K+MrOe5pY-uw>eUgNmznl0Q7u;XLTF?$#c348CTM@nnitofeV zX54bdpZzMX@@Q6iUIoHrl>FGI8 z-N_(~3dmKiQ&g#DTD2^y;wX)hul^7ko9KT-i3#R*trui`+=|ZvD>AvW5eQcw@d`t1*!S@hKd?M(`nY4c4ycJc;i9r#&oiO6 zc9oi!sen2P=&}A3>sJc4wnpUj5?U@Q3?u6z3W*)*p)9K9DB@$6-@2<%^6;wAtF7?2 z3MDWD9W9%!m#!W}zLv>xdI_2y0o`zqTPy?0*Nc`f{h|OOs)2h9^Cm|^>(KXICvYEw zNImQKzave?C%s)-NtE{?A9+6t89jc00Igv(CbN;uYOUaBbyn*ESB16RrOYhTv2Yhe z*Ggumo+BCaf5~)d(6caL)bbhiaDO1AHNAHaFtl}3Ttsp1ka102>2-tq>o3s{GCS2i;#c&RnBo7`Yt!OB&x!JoI-^IVTAQ /dev/null 2>&1 + +##################################################################### + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $< objectname $@ + +$(OBJDIR)/%.o : %.asm + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +##################################################################### + +$(CATCOMPH) $(CATCOMPI) : NewDrawerGUI.cd + @printf '\033[32mMake CatComp header: \033[31m\033[1m$(CATCOMPH) $@ \033[32mfrom \033[31m$<\033[0m\n' + @$(CATCOMP) $< cfile=$(CATCOMPH) asmfile=$(CATCOMPI) NOCODE XDEF + +$(OBJDIR)/NDStrings.o : NewDrawerStrings.i + +$(OBJDIR)/NewDrawer.o : NewDrawer.c NewDrawerGUI.h NewDrawerStrings.h + +##################################################################### + +$(NAME) $(DBGNAME) : $(OBJS) + +##################################################################### + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(NAME) \033[0mto \033[31m\033[1mScalos:modules/ \033[0m\n' + @copy $(NAME) Scalos:modules/ + +##################################################################### + +# A little something to clean it all up +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + @delete $(XOBJS) $(NAME) $(DBGNAME) \ + $(CATCOMPH) $(CATCOMPI) + @printf '\033[0m' + +##################################################################### diff --git a/scalos/Modules/Rename.Gadtools/Rename.c b/scalos/Modules/Rename.Gadtools/Rename.c new file mode 100755 index 000000000..9645d68af --- /dev/null +++ b/scalos/Modules/Rename.Gadtools/Rename.c @@ -0,0 +1,825 @@ +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +__stdargs void NewList( struct List *list ); +static void renmain(void); +static void wbmain(struct WBStartup *wbs ); +STATIC VOID Render(void); + +IMPORT struct Library *GadToolsBase; +IMPORT struct Library *IntuitionBase; +IMPORT struct Library *SysBase; +IMPORT struct Library *GfxBase; +IMPORT struct Library *DOSBase; +IMPORT struct Library *LocaleBase; +IMPORT struct Library *UtilityBase; + +struct Library *IconBase; +struct Library *ScalosBase; + +struct Catalog *Cat; + +struct Screen *scr; +struct DrawInfo *drinfo; +BOOL one2two; +APTR visualinfo; +ULONG offx,offy,fonty,sizeheight,uwidth; +ULONG wndwidth,wndheight; + +struct Hook editHook; +struct Window *wnd; +struct Gadget *glist; +struct Gadget *nameString; +//struct Gadget *skipButton; + +STRPTR nameStr; +STRPTR orgNameStr; + +STRPTR parentStr; +BPTR parent; + +STRPTR topStr; +STRPTR top2Str; + +struct WBArg *wbarg; +ULONG wbarg_act,wbarg_num; +BOOL relabel; + +BOOL glistAttached; +BOOL sizeVerify; +BOOL fromWB; + +const STATIC STRPTR engLocText[] = +{ + "Enter a new Name for", + "New _Name:", + "_OK", + "_Cancel", + "_Skip", + "Rename", + "Path", + NULL, + "Cannot rename because" +}; + +UWORD ok_key,cancel_key,skip_key,name_key; + +STRPTR locText[9]; + +const STRPTR VerString = "$VER: rename.module 1.0 "__AMIGADATE__; + +#define WND_NAME_STRING 1 +#define WND_OK_BUTTON 2 +#define WND_SKIP_BUTTON 3 +#define WND_CANCEL_BUTTON 4 + +//------------------------------------- +STATIC VOID SR_CopyFunc(VOID) +{ + __emit(0x16c0); // MOVE.B D0,(A3)+ +} +//------------------------------------- +VOID sprintf( STRPTR buf, const STRPTR fmt,...) +{ + RawDoFmt((const STRPTR)fmt,(STRPTR*)&fmt+1,(void(*)())SR_CopyFunc,buf); +} + +//------------------------------------- +ULONG StrLen( const STRPTR str ) +{ + if( !str) return 0; + return strlen(str); +} +//------------------------------------- +STRPTR StrCopy( const STRPTR str ) +{ + STRPTR dst; + if( !str ) return NULL; + if( !*str) return NULL; + + dst = (STRPTR)AllocVec(strlen(str)+1,0); + if(dst) strcpy(dst,str); + return dst; +} +//------------------------------------- +STRPTR NameOfLock( BPTR lock ) +{ + STRPTR n; + BOOL again; + ULONG bufSize = 127; + if( !lock ) return NULL; + + do + { + again = FALSE; + if((n = (STRPTR)AllocVec(bufSize, 0x10000 ))) + { + if( NameFromLock( lock, n, bufSize-1 ) == DOSFALSE ) + { + if( IoErr() == ERROR_LINE_TOO_LONG ) + { + bufSize += 127; + again = TRUE; + } + FreeVec(n); + n = NULL; + } + } + } while(again); + + return n; +} +//------------------------------------- +ULONG GetTextLength( const STRPTR str ) +{ + return TextLength(&scr->RastPort,str,strlen(str)); +} +//------------------------------------- +ULONG FindUnderscoredToLower(STRPTR text) +{ + ULONG c; + while(( c = *text++)) + { + if( c == '_' ) return ToLower(*text); + } + return 0; +} +//------------------------------------- +__asm __saveds ULONG StringFunc( register __a0 struct Hook stringHook, register __a1 ULONG *Msg, register __a2 struct SGWork *SGW ) +{ +// struct StringInfo *sinfo = SGW->StringInfo; + if( *Msg != SGH_KEY ) return 0; + + SGW->Actions |= SGA_USE; + + switch( SGW->EditOp ) + { + case EO_INSERTCHAR: + { + switch(SGW->Code) + { + case '/': + case ':': + SGW->Actions |= SGA_BEEP; + SGW->Actions ^= SGA_USE; + break; + } + } + break; + } + return 1L; +} +//------------------------------------- + +//------------------------------------- +STATIC ULONG CalcWidth(void) +{ + ULONG wndwidth; + ULONG newwndwidth = GetTextLength(locText[3])+GetTextLength(locText[4])+GetTextLength(locText[5])+2*offx+50; + wndwidth = GetTextLength(topStr)+2*offx+8; + if(newwndwidth>wndwidth)wndwidth=newwndwidth; + + newwndwidth = GetTextLength(top2Str)+2*offx+8; + if(newwndwidth>wndwidth)wndwidth=newwndwidth; + + if(wndwidth > scr->Width) wndwidth=scr->Width; + return wndwidth; +} +//------------------------------------- +STATIC VOID RenameTheFile(void) +{ + if(nameStr) + { + if( relabel ) + { + Relabel(parentStr,nameStr); + } else + { + ULONG len1 = strlen(orgNameStr); + ULONG len2 = strlen(nameStr); + STRPTR infoname1 = AllocVec(len1+8,0); + if(infoname1) + { + STRPTR infoname2 = AllocVec(len2+8,0); + if(infoname2) + { + BPTR olddir = CurrentDir(parent); + struct ScaUpdateIcon_IW updateIcon; + + strcpy(infoname1,orgNameStr); + strcpy(&infoname1[len1],".info"); + strcpy(infoname2,nameStr); + strcpy(&infoname2[len2],".info"); + + Rename(infoname1,infoname2); + Rename(orgNameStr,nameStr); + CurrentDir(olddir); + FreeVec(infoname2); + + updateIcon.ui_iw_Lock = parent; + updateIcon.ui_iw_Name = orgNameStr; + SCA_UpdateIcon( WSV_Type_IconWindow, &updateIcon, sizeof(struct ScaUpdateIcon_IW)); + + updateIcon.ui_iw_Name = nameStr; + SCA_UpdateIcon( WSV_Type_IconWindow, &updateIcon, sizeof(struct ScaUpdateIcon_IW)); + } + FreeVec(infoname1); + } + } + } +} +//------------------------------------- +STATIC VOID CleanRename(void) +{ + if(parent) + { + UnLock(parent); + parent = NULL; + } + + if(nameStr) + { + FreeVec(nameStr); + nameStr = NULL; + } + + if(orgNameStr) + { + FreeVec(orgNameStr); + orgNameStr = NULL; + } + + if(parentStr) + { + FreeVec(parentStr); + parentStr = NULL; + } + + if( topStr ) + { + FreeVec(topStr); + topStr=NULL; + } + + if( top2Str ) + { + FreeVec(top2Str); + top2Str=NULL; + } +} +//------------------------------------- +STATIC BOOL PrepareRename(void) +{ + BOOL retval = FALSE; + if(wbarg_act < wbarg_num ) + { + CleanRename(); + relabel = FALSE; + if((parentStr = NameOfLock(wbarg[wbarg_act].wa_Lock))) + { + BOOL drawer; + if(wbarg[wbarg_act].wa_Name) + { + if(*wbarg[wbarg_act].wa_Name) drawer = FALSE; + else drawer=TRUE; + } else drawer=TRUE; + + if( drawer ) + { + if((parent = ParentDir(wbarg[wbarg_act].wa_Lock))) + { + STRPTR drwName = FilePart(parentStr); + STRPTR parentName = PathPart(parentStr); + if((nameStr = StrCopy(drwName))) + { + if((orgNameStr = StrCopy(drwName))) + { + *parentName = 0; + wbarg_act++; + retval = TRUE; + } + } + } else + { + LONG len=strlen(parentStr); + if(len) + { + if(parentStr[len-1] == ':') + { + relabel = TRUE; + parent=NULL; + nameStr=StrCopy(parentStr); + nameStr[len-1]=0; + orgNameStr=StrCopy(nameStr); + wbarg_act++; + retval = TRUE; + } + } + } + } else + { + if((nameStr = StrCopy(wbarg[wbarg_act].wa_Name))) + { + if((orgNameStr = StrCopy(nameStr))) + { + if((parent = DupLock(wbarg[wbarg_act].wa_Lock))) + { + wbarg_act++; + retval = TRUE; + } + } + } + } + } + } + + if( retval && parentStr ) + { + topStr = (STRPTR)AllocVec( strlen(nameStr)+strlen(locText[0])+8,0); + if(topStr) + { + sprintf(topStr,"%s '%s'",locText[0],nameStr); + } else retval = FALSE; + top2Str = (STRPTR)AllocVec( strlen(parentStr)+strlen(locText[6])+8,0); + if(top2Str) + { + sprintf(top2Str,"%s '%s'",locText[6],parentStr); + + if( wnd ) + { + ULONG newwidth = CalcWidth(); + if(newwidth>wnd->Width) + { + ChangeWindowBox(wnd,wnd->LeftEdge,wnd->TopEdge,newwidth,wnd->Height); + Delay(6); + WindowLimits(wnd,newwidth,0,~0,wnd->Height); + wndwidth=wnd->Width; + } else + { + if( nameString ) + { + GT_SetGadgetAttrs(nameString,wnd,NULL, + GTST_String,nameStr, + TAG_DONE); + + ((struct StringInfo*)(nameString->SpecialInfo))->BufferPos = strlen(nameStr); + + ActivateGadget(nameString,wnd,NULL); + } + } + Render(); + } + + } else retval = FALSE; + } + + return retval; +} +//------------------------------------- + +//------------------------------------- +STATIC VOID InitStrings(void) +{ + ULONG i; + for(i=0; i<9; i++) + { + locText[i] = GetCatalogStr( Cat, i, engLocText[i]); + } + + name_key = FindUnderscoredToLower(locText[1]); + ok_key = FindUnderscoredToLower(locText[2]); + cancel_key = FindUnderscoredToLower(locText[3]); + skip_key = FindUnderscoredToLower(locText[4]); +} +//------------------------------------- + +//------------------------------------- +STATIC VOID GetName(void) +{ + STRPTR nmeStr; + + if(GT_GetGadgetAttrs(nameString,wnd,NULL, + GTST_String, &nmeStr, + TAG_DONE )) + { + if( nameStr ) FreeVec(nameStr); + nameStr=StrCopy(nmeStr); + } +} +//------------------------------------- +//STATIC void SetName(void) +//{ +// GT_SetGadgetAttrs(nameString,wnd,NULL, +// GTST_String, nameStr?nameStr:(STRPTR)"", +// TAG_DONE ); +//} +//------------------------------------- +STATIC BOOL SetupScreen(void) +{ + if((scr = LockPubScreen(NULL))) + { + if((drinfo = GetScreenDrawInfo(scr))) + { + if((visualinfo = GetVisualInfoA(scr,NULL))) + { + UWORD x,y; + Object *o = (Object*)NewObject( NULL, SYSICLASS, + SYSIA_DrawInfo,drinfo, + SYSIA_Which, SIZEIMAGE, + TAG_DONE); + if(o) + { + if(!GetAttr( IA_Height,o,&sizeheight)) sizeheight = 11; + DisposeObject(o); + } else sizeheight = 11; + uwidth = TextLength(&scr->RastPort,"_",1); + + x = drinfo->dri_Resolution.X; + y = drinfo->dri_Resolution.Y; + if( y/x >= 2 ) + { + one2two = TRUE; + } else one2two = FALSE; + + return TRUE; + } + } + } + return FALSE; +} +//------------------------------------- +STATIC VOID FreeScreen(void) +{ + if( visualinfo ) FreeVisualInfo(visualinfo); + if( drinfo ) FreeScreenDrawInfo(scr,drinfo); + if( scr ) UnlockPubScreen(NULL,scr); +} +//------------------------------------- +STATIC VOID Render(void) +{ + UWORD x1,x2; + Move(wnd->RPort,offx+4,offy+drinfo->dri_Font->tf_Baseline+4); + SetABPenDrMd(wnd->RPort,drinfo->dri_Pens[TEXTPEN],drinfo->dri_Pens[BACKGROUNDPEN],JAM2); + Text(wnd->RPort,topStr,strlen(topStr)); + + x1=wnd->RPort->cp_x; + x2=wnd->Width-wnd->BorderRight-1; + if( x1 <= x2 ) + { + EraseRect(wnd->RPort,x1,offy+4,x2,offy+4+fonty); + } + + Move(wnd->RPort,offx+4,offy+drinfo->dri_Font->tf_Baseline+8+fonty); + + x1=wnd->RPort->cp_x; + if( x1 <= x2 ) + { + EraseRect(wnd->RPort,x1,offy+8+fonty,x2,offy+8+2*fonty); + } + + Text(wnd->RPort,top2Str,strlen(top2Str)); + +} +//------------------------------------- +STATIC BOOL CreateGadgets(void) +{ + struct Gadget *g; + + if(glist) + { + FreeGadgets(glist); + glist = NULL; + } + + g = CreateContext( &glist ); + if( g ) + { + struct NewGadget ng; + ULONG usableWidth = wndwidth - 2*offx-8; + ULONG cancelLeft; + BOOL setCursor; + + ng.ng_VisualInfo = visualinfo; + ng.ng_TextAttr = NULL; + ng.ng_GadgetText = locText[1]; + ng.ng_GadgetID = WND_NAME_STRING; + ng.ng_Flags = NULL; + ng.ng_UserData = NULL; + ng.ng_LeftEdge = offx+13+TextLength(&scr->RastPort,ng.ng_GadgetText,strlen(ng.ng_GadgetText))-uwidth; + ng.ng_TopEdge = offy+2*fonty+10; + ng.ng_Width = wndwidth-ng.ng_LeftEdge-offx-4; + ng.ng_Height = fonty+6; + + if( !nameString && nameStr ) setCursor = TRUE; + else setCursor = FALSE; + + g = nameString = CreateGadget( STRING_KIND, g, &ng, + GTST_String, nameStr?nameStr:(STRPTR)"", + GTST_EditHook, &editHook, + GT_Underscore,'_', + TAG_DONE); + + if( setCursor ) + ((struct StringInfo*)(nameString->SpecialInfo))->BufferPos = strlen(nameStr); + + ng.ng_TopEdge += ng.ng_Height+4; + ng.ng_Width = usableWidth/3-2; + ng.ng_GadgetText = locText[2]; + ng.ng_LeftEdge = offx+4; + ng.ng_GadgetID = WND_OK_BUTTON; + + g = CreateGadget( BUTTON_KIND, g, &ng, + GT_Underscore,'_', + TAG_DONE); + + cancelLeft = wndwidth - ng.ng_Width-4-offx; + + if(wbarg_num>1) + { + ng.ng_GadgetText = locText[4]; + ng.ng_LeftEdge += ng.ng_Width+2; + ng.ng_Width = cancelLeft - 2 - ng.ng_LeftEdge; + ng.ng_GadgetID = WND_SKIP_BUTTON; + + g = CreateGadget( BUTTON_KIND, g, &ng, + GT_Underscore,'_', + TAG_DONE); + } + + ng.ng_GadgetText = locText[3]; + ng.ng_LeftEdge = cancelLeft; + ng.ng_GadgetID = WND_CANCEL_BUTTON; + ng.ng_Width = usableWidth/3-2; + + g = CreateGadget( BUTTON_KIND, g, &ng, + GT_Underscore,'_', + TAG_DONE); + + if(g) return TRUE; + + FreeGadgets(glist); + glist=NULL; + } + return FALSE; +} +//------------------------------------- +STATIC VOID FreeGUI(void) +{ + if(wnd) CloseWindow(wnd); + if(glist) FreeGadgets(glist); +} +//------------------------------------- +STATIC BOOL SetupGUI(void) +{ +// WORD cbw = (fonty+6)*13*(one2two+1)/11; + + fonty = drinfo->dri_Font->tf_YSize; + offx = scr->WBorLeft; + offy = scr->WBorTop + fonty + 1; + + wndwidth = CalcWidth(); + wndheight = offy + 4*fonty + sizeheight + 29; + + editHook.h_Entry = (HOOKFUNC)StringFunc; + + if( CreateGadgets()) + { + ULONG idcmp = IDCMP_CLOSEWINDOW|IDCMP_NEWSIZE|BUTTONIDCMP|IDCMP_VANILLAKEY|STRINGIDCMP; + if( sizeVerify ) idcmp |= IDCMP_SIZEVERIFY; + + wnd = OpenWindowTags( NULL, + WA_Left,0, + WA_Top,offy, + WA_Width, wndwidth, + WA_Height, wndheight, + WA_IDCMP, idcmp, + WA_DragBar,TRUE, + WA_SizeGadget, TRUE, + WA_DepthGadget,TRUE, + WA_CloseGadget, TRUE, + WA_Title,locText[5], + WA_RMBTrap, TRUE, + WA_Gadgets, glist, + WA_SizeBBottom,TRUE, + WA_MaxWidth,-1, + WA_Activate, TRUE, + WA_PubScreen,scr, + WA_NoCareRefresh,TRUE, +// WA_MaxHeight,-1, + TAG_DONE ); + if( wnd ) + { + glistAttached = TRUE; + SetFont(wnd->RPort,drinfo->dri_Font); + Render(); + return TRUE; + } + glistAttached = FALSE; + } + + FreeGUI(); + return FALSE; +} +//------------------------------------- +STATIC BOOL HandleWnd(void) +{ + struct IntuiMessage *imsg; + BOOL retVal = FALSE; + + while((imsg = GT_GetIMsg(wnd->UserPort))) + { + ULONG cl = imsg->Class; + UWORD code = imsg->Code; + APTR iaddress = imsg->IAddress; + + if( cl == IDCMP_SIZEVERIFY ) + { + if(glistAttached) RemoveGList( wnd, glist, -1 ); + glistAttached = FALSE; + GT_ReplyIMsg(imsg); + continue; + } + + GT_ReplyIMsg(imsg); + + switch( cl ) + { + case IDCMP_CLOSEWINDOW: + retVal = TRUE; + if( nameStr ) FreeVec(nameStr); + nameStr = NULL; + break; + + case IDCMP_VANILLAKEY: + if( code == 10 || code == ok_key ) + { + GetName(); + RenameTheFile(); + if(!PrepareRename()) retVal = TRUE; + } + else if( code == 27 || code == cancel_key) + { + if( nameStr ) FreeVec(nameStr); + nameStr = NULL; + retVal = TRUE; + } + else if( code == skip_key ) + { + if(!PrepareRename()) retVal = TRUE; + } + else if( code == name_key ) ActivateGadget(nameString,wnd,NULL); + break; + + case IDCMP_NEWSIZE: + if( !sizeVerify && glistAttached) + { + if( wndwidth == wnd->Width || wndheight != wnd->Height ) break; + } + + if(glistAttached) RemoveGList( wnd, glist, -1 ); + + if( wnd->Width < wndwidth ) RefreshWindowFrame(wnd); + + wndwidth = wnd->Width; + wndheight = wnd->Height; + EraseRect( wnd->RPort, wnd->BorderLeft, wnd->BorderTop+2*fonty+9, + wnd->Width-wnd->BorderRight-1, wnd->Height-wnd->BorderBottom-1 ); + if(CreateGadgets()) + { + AddGList( wnd, glist, -1,-1, NULL ); + RefreshGList( glist, wnd, NULL, -1 ); + glistAttached = TRUE; + ActivateGadget( nameString, wnd, NULL); + } else + { + glistAttached = FALSE; + retVal = TRUE; + } + break; + + case IDCMP_GADGETUP: + switch( ((struct Gadget*)iaddress)->GadgetID ) + { + case WND_NAME_STRING: + GetName(); + RenameTheFile(); + if(!PrepareRename()) retVal = TRUE; + break; + + case WND_CANCEL_BUTTON: + retVal = TRUE; + if( nameStr ) FreeVec(nameStr); + nameStr = NULL; + break; + + case WND_SKIP_BUTTON: + if(!PrepareRename()) retVal = TRUE; + break; + + case WND_OK_BUTTON: + GetName(); + RenameTheFile(); + if(!PrepareRename()) retVal = TRUE; + break; + + default: + break; + } + break; + } + } + return retVal; +} +//------------------------------------- + +//------------------------------------- +static void renmain(void) +{ + if(LocaleBase) Cat = OpenCatalogA( NULL, "Scalos/Scalos_Rename.catalog",NULL); + + if((IconBase = OpenLibrary("icon.library",37))) + { + BPTR lock = Lock("ENV:Scalos/NoSizeVerify",ACCESS_READ); + ScalosBase = OpenLibrary("scalos.library",0); + if(lock) + { + sizeVerify = FALSE; + UnLock(lock); + } else sizeVerify = TRUE; + + InitStrings(); + + if(PrepareRename()) + { + if(SetupScreen()) + { + if( SetupGUI()) + { + BOOL ready = FALSE; + ULONG wndsig = 1UL<UserPort->mp_SigBit; + + ActivateGadget(nameString,wnd,NULL); + + while( ready == FALSE ) + { + ULONG signal = Wait(wndsig|4096); + + if( signal & 4096 ) ready = TRUE; + if( signal & wndsig ) ready = HandleWnd(); + } + FreeGUI(); + } + FreeScreen(); + } + } + if(ScalosBase) CloseLibrary(ScalosBase); + CloseLibrary(IconBase); + } + if(Cat) CloseCatalog(Cat); +} +//------------------------------------- +main() +{ + wbmain(WBenchMsg); +} +//------------------------------------- +static void wbmain(struct WBStartup *wbs ) +{ + if( wbs->sm_NumArgs > 1 ) + { + wbarg_num = wbs->sm_NumArgs-1; + wbarg = wbs->sm_ArgList+1; + + renmain(); + + CleanRename(); + } +} +//------------------------------------- diff --git a/scalos/Modules/Rename.Gadtools/makefile b/scalos/Modules/Rename.Gadtools/makefile new file mode 100755 index 000000000..03ca43792 --- /dev/null +++ b/scalos/Modules/Rename.Gadtools/makefile @@ -0,0 +1,89 @@ +# Makefile for Rename.module (MUI) +# using GNU make and SAS/C +# $Date$ + +##################################################################### + +CSRCS = Rename.c + +##################################################################### + +CC = sc +CFLAGS = optimize nostackcheck nochkabort debug=s \ + idlen=128 strmer nover streq idir=sc:include/ idir=include: idir=//include +AS = phxass +AFLAGS = QUIET m=68020 linedebug opt=NRQB i=include: +LD = slink +LNFLAGS = quiet batch noicons stripdebug +LNDBFLAGS = quiet batch noicons addsym +LIBS = //SAS-lib/z.lib LIB:sc.lib LIB:debug.lib LIB:amiga.lib +CSTARTUP = LIB:c.o +OBJDIR = .sasobj + +##################################################################### + +.SUFFIXES: .asm + +##################################################################### + +NAME = Rename.module +DBGNAME = $(NAME).debug + +##################################################################### + +all: $(NAME) $(DBGNAME) +# install clean + +##################################################################### + +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(CSRCS:%.c=$(OBJDIR)/%.o) + +##################################################################### + +$(NAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNFLAGS) + +$(DBGNAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNDBFLAGS) + +##################################################################### + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +##################################################################### + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $< objectname $@ + +$(OBJDIR)/%.o : %.s + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +$(OBJDIR)/%.o : %.asm + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +##################################################################### + +$(NAME) $(DBGNAME) : $(OBJS) + +##################################################################### + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(NAME) \033[0mto \033[31m\033[1mScalos:modules/ \033[0m\n' + copy $(NAME) Scalos:modules/ + +##################################################################### + +# A little something to clean it all up +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + @delete $(OBJS) $(NAME) $(DBGNAME) + @printf '\033[0m' + +##################################################################### + diff --git a/scalos/Modules/Rename.MUI/Catalogs/deutsch/Scalos/Rename.ct b/scalos/Modules/Rename.MUI/Catalogs/deutsch/Scalos/Rename.ct new file mode 100644 index 000000000..3bd3b9f0c --- /dev/null +++ b/scalos/Modules/Rename.MUI/Catalogs/deutsch/Scalos/Rename.ct @@ -0,0 +1,205 @@ +; Rename.ct +## version $VER: Rename.catalog 40.1 (20 Feb 2005 22:02:39) +## codeset 0 +## language deutsch +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Umbenennen +;Scalos Rename +; +; +MSGID_OKBUTTON +Umbenennen +;Rename +; +; +MSGID_OKBUTTON_SHORT +u +;r +; +; +MSGID_SHORTHELP_OKBUTTON +Namen des ausgählten Objects ändern. +;Save the changed icon.\n\ +;If necessary, a new icon will be\n\ +;created from a the default icon. +; +; +MSGID_SKIPBUTTON +Überspringen +;Skip +; +; +MSGID_SKIPBUTTON_SHORT +ü +;s +; +; +MSGID_SHORTHELP_SKIPBUTTON +...SkipButton... +; +; +MSGID_CANCELBUTTON +Abbrechen +;Cancel +; +; +MSGID_CANCELBUTTON_SHORT +a +;c +; +; +MSGID_SHORTHELP_CANCELBUTTON +Änderungen verwerfen und den\n\ +originalen Namen beibehalten. +;Discard all changes and\n\ +;leave keep the original name. +; +; +MSGID_CREATE_APPLICATION_FAILED +Fehler beim Erzeugen der Anwendung.\n +;Failed to create Application.\n +; +; +MSGID_CREATE_MAINWINDOW_FAILED +Fehler beim Öffnen des Hauptfensters!\n +;Failed to open main window !\n +; +; +MSGID_OPEN_LIBRARY_FAILED +Fehler beim Öffnen von \"%s\" !\n +;Failed to open \"%s\" !\n +; +;;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Projekt +;Project +; +; +MSGID_MENU_PROJECT_ABOUT +Über... +;About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Über MUI... +;About MUI... +; +; +MSGID_MENU_PROJECT_QUIT +Beenden +;Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +Ok +;_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Rename.module V%ld.%ld\033n\n\ +%s\n\ +© 2004%s Das Scalos-Team +;\33c\033bScalos Rename.module V%ld.%ld\033n\n\ +;%s\n\ +;© 2004%s The Scalos Team +; +;----------------------------------------------------------- +; +; +MSGID_TEXTLINE_ENTERNEWNAME +Neuen Namen for \"%s\" angeben +;Enter a new Name for \"%s\" +; +; +MSGID_LABEL_NEWNAME +Neuer Name +;New Name +; +; +MSGID_TITLE_ERRORREQ +Fehler beim Umbenennen +;Rename Error +; +; +MSGID_ERRORREQ_BODYTEXT +Fehler beim Umbennenen\n\ +von \"%s" nach \"%s\"\n%s. +;Could not rename\n'%s' to '%s'\n%s +; +; +MSGID_REQ_OK +Ok +; _Ok +; +; +MSGID_TEXTLINE_PATH +Pfad: \"%s\" +;Path: \"%s\" +; +; +MSGID_BUTTON_SKIP +Überspringen +;_Skip +; +; +MSGID_PATHOF_NAME +Pfad des Objects.\n\ +Mit dem Rollbalken am unteren Fensterrand kann\n\ +der Inhalt des Pfades hin- und hergeschoben werden,\n\ +um auch lange Pfadnamen lesen zu können. +;Path of object.\n\n\ +;It's possible to show all content of this gadget using\n\ +;the scroller located at the bottom of the window.\n\ +;Can be usefull for large path lenght. +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Rename.module kann nicht gestartet werden +;Rename.module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Wiederholen|Beenden +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\ +Die Klasse ist nicht installiert. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Sie haben momentan Version v%lu.%lu installiert und\n\ +sollten die Klasse daher aktualisieren! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Version %lu.%lu wird momentan von einer anderen Anwendung\n\ +verwendet. Wenn sie die benötigte Version installiert haben,\n\ +schließen sie alle MUI Programme und probieren es erneut. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- diff --git a/scalos/Modules/Rename.MUI/Catalogs/deutsch/Scalos/config.mk b/scalos/Modules/Rename.MUI/Catalogs/deutsch/Scalos/config.mk new file mode 100755 index 000000000..8631b0623 --- /dev/null +++ b/scalos/Modules/Rename.MUI/Catalogs/deutsch/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = deutsch + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = german + +else + +############################################################################### +# AmigaOS and AROS + +LANG = deutsch + +endif +endif diff --git a/scalos/Modules/Rename.MUI/Catalogs/deutsch/Scalos/makefile b/scalos/Modules/Rename.MUI/Catalogs/deutsch/Scalos/makefile new file mode 100644 index 000000000..1367ca0a4 --- /dev/null +++ b/scalos/Modules/Rename.MUI/Catalogs/deutsch/Scalos/makefile @@ -0,0 +1,14 @@ +# makefile for Rename.module (translated Texts : deutsch) +# $Date$ +# $Revision$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mdeutsch\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +Rename.catalog : Rename.ct ../../../Rename.cd + +All: Rename.catalog diff --git a/scalos/Modules/Rename.MUI/Catalogs/deutsch/Scalos/makefile-new b/scalos/Modules/Rename.MUI/Catalogs/deutsch/Scalos/makefile-new new file mode 100644 index 000000000..6422d5a40 --- /dev/null +++ b/scalos/Modules/Rename.MUI/Catalogs/deutsch/Scalos/makefile-new @@ -0,0 +1,30 @@ +# makefile for Rename.module (translated Texts : deutsch) +# $Date: 2011-07-24 10:11:00 +0200 (So, 24. Jul 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = Rename + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git "a/scalos/Modules/Rename.MUI/Catalogs/fran\303\247ais/Scalos/Rename.ct" "b/scalos/Modules/Rename.MUI/Catalogs/fran\303\247ais/Scalos/Rename.ct" new file mode 100755 index 000000000..474c58537 --- /dev/null +++ "b/scalos/Modules/Rename.MUI/Catalogs/fran\303\247ais/Scalos/Rename.ct" @@ -0,0 +1,216 @@ +; Rename.ct +; $Date$ +; $Revision$ +; +## version $VER: Rename.catalog 40.1 (20 Feb 2005 20:27:40) +## codeset 0 +## language français +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Renommer +; Scalos Rename +; +; +MSGID_OKBUTTON +Renommer +; Rename +; +; +MSGID_OKBUTTON_SHORT +r +; r +; +; +MSGID_SHORTHELP_OKBUTTON +Renommer l'objet d'après\n\ +le contenu du champ de texte. +; Rename the object as\n\ +; the string gadget's content. +; +; +MSGID_SKIPBUTTON +Passer +; Skip +; +; +MSGID_SKIPBUTTON_SHORT +p +; s +; +; +MSGID_SHORTHELP_SKIPBUTTON +Ignorer l'objet à renommer\n\ +et passer au suivant. +; ...SkipButton... +; +; +MSGID_CANCELBUTTON +Annuler +; Cancel +; +; +MSGID_CANCELBUTTON_SHORT +a +; c +; +; +MSGID_SHORTHELP_CANCELBUTTON +Oublier tout changement en cours et\n\ +conserver le nom d'origine. +; Discard all changes and\n\ +; leave keep the original name. +; +; +MSGID_CREATE_APPLICATION_FAILED +La création de l'application a échouée.\n +; Failed to create Application.\n +; +; +MSGID_CREATE_MAINWINDOW_FAILED +Impossible d'ouvrir la fenêtre !\n +; Failed to open main window !\n +; +; +MSGID_OPEN_LIBRARY_FAILED +Impossible d'ouvrir "%s" !\n +; Failed to open "%s" !\n +; +;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Projet +; Project +; +; +MSGID_MENU_PROJECT_ABOUT +About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI +A propos de MUI... +; About MUI... +; +; +MSGID_MENU_PROJECT_QUIT +Quitter +; Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; Q +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +D'acc_ord +; _OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Rename.module V\0333%ld\0332.\0333%ld\0332\033n\n\ +Compilé sous : \0333%s\0332\n\ +© 2004%s The Scalos Team +; \33c\033bScalos Rename.module V%ld.%ld\033n\n\ +; %s\n\ +; © 2004%s The Scalos Team +; +;----------------------------------------------------------- +; +; +MSGID_TEXTLINE_ENTERNEWNAME +\033bEntrez un nouveau nom pour\033n "%s" +; Enter a new Name for \"%s\" +; +; +MSGID_LABEL_NEWNAME +Nouveau nom +; New Name +; +; +MSGID_TITLE_ERRORREQ +Renomination erreur +; Rename Error +; +; +MSGID_ERRORREQ_BODYTEXT +Impossible de renommer\n\ +'\033b%s\033n' en '\033b%s\033n'\n\ +%s +; Could not rename\n\ +; '%s' to '%s'\n%s +; +; +MSGID_REQ_OK +D'acc_ord +; _Ok +; +; +MSGID_TEXTLINE_PATH +\033bChemin :\033n "%s" +; Path: \"%s\" +; +; +MSGID_BUTTON_SKIP +_Passer +; _Skip +; +; +MSGID_PATHOF_NAME +Chemin d'accès de l'élément.\n\n\ +Si besoin, vous avez la possibilité d'utiliser\n\ +l'ascenseur siué au bas de la fenêtre\n\ +afin de visionner le chemin d'accès\n\ +complet de l'élément.\n\ +Peut s'avèrer utile pour de longs chemins d'accès. +; Path of object\n\n\ +; It's possible to show all content of this gadget using\n\ +; the scroller located at the bottom of the window.\n\ +; Can be usefull for large path lenght. +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Le lancement de Rename.module a échoué +;Rename.module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Recommençer | Quitter +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +Celle-ci n'est pas installée. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +\n\ +La version installée est V%lu.%lu, installez-en une plus récente s'il vous plaît ! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +%lu.%lu est actuellement utilisée par d'autres applications.\n\ +\n\ +Une fois la version requise installée,\n\ +fermez tous les programmes MUI, soyez sûr que l'ancienne classe\n\ +ne soit plus présente dans la mémoire puis, essayez de nouveau. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; diff --git "a/scalos/Modules/Rename.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" "b/scalos/Modules/Rename.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" new file mode 100755 index 000000000..8b7056423 --- /dev/null +++ "b/scalos/Modules/Rename.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" @@ -0,0 +1,40 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = français + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = french + +else + +############################################################################### +# AmigaOS and AROS + +LANG = français + +endif +endif diff --git "a/scalos/Modules/Rename.MUI/Catalogs/fran\303\247ais/Scalos/makefile" "b/scalos/Modules/Rename.MUI/Catalogs/fran\303\247ais/Scalos/makefile" new file mode 100644 index 000000000..97d60c21f --- /dev/null +++ "b/scalos/Modules/Rename.MUI/Catalogs/fran\303\247ais/Scalos/makefile" @@ -0,0 +1,14 @@ +# makefile for Rename.module (translated Texts : français) +# $Date$ +# $Revision$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mfrançais\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +Rename.catalog : Rename.ct ../../../Rename.cd + +All: Rename.catalog diff --git "a/scalos/Modules/Rename.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" "b/scalos/Modules/Rename.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" new file mode 100644 index 000000000..57686d0e0 --- /dev/null +++ "b/scalos/Modules/Rename.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" @@ -0,0 +1,30 @@ +# makefile for Rename.module (translated Texts : français) +# $Date: 2011-07-24 10:11:00 +0200 (So, 24. Jul 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = Rename + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Modules/Rename.MUI/Catalogs/sample/Scalos/Rename.ct b/scalos/Modules/Rename.MUI/Catalogs/sample/Scalos/Rename.ct new file mode 100644 index 000000000..cde39543e --- /dev/null +++ b/scalos/Modules/Rename.MUI/Catalogs/sample/Scalos/Rename.ct @@ -0,0 +1,178 @@ +; Rename.ct +## version $VER: Rename.catalog 40.1 (26 Feb 2005 22:01:34) +## codeset 0s +## language xxxxxx +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Rename +; +; +MSGID_OKBUTTON +Rename +; +; +MSGID_OKBUTTON_SHORT +r +; +; +MSGID_SHORTHELP_OKBUTTON +Save the changed icon.\n\ +If necessary, a new icon will be\n\ +created from a the default icon. +; +; +MSGID_SKIPBUTTON +Skip +; +; +MSGID_SKIPBUTTON_SHORT +s +; +; +MSGID_SHORTHELP_SKIPBUTTON +...SkipButton... +; +; +MSGID_CANCELBUTTON +Cancel +; +; +MSGID_CANCELBUTTON_SHORT +c +; +; +MSGID_SHORTHELP_CANCELBUTTON +Discard all changes and\n\ +leave keep the original name. +; +; +MSGID_CREATE_APPLICATION_FAILED +Failed to create Application.\n +; +; +MSGID_CREATE_MAINWINDOW_FAILED +Failed to open main window !\n +; +; +MSGID_OPEN_LIBRARY_FAILED +Failed to open \"%s\" !\n +; +;;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Project +; +; +MSGID_MENU_PROJECT_ABOUT +About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI +About MUI... +; +; +MSGID_MENU_PROJECT_QUIT +Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Rename.module V%ld.%ld\033n\n\ +%s\n\ +© 2004%s The Scalos Team +; +;----------------------------------------------------------- +; +; +MSGID_TEXTLINE_ENTERNEWNAME +Enter a new Name for \"%s\" +; +; +MSGID_LABEL_NEWNAME +New Name +; +; +MSGID_TITLE_ERRORREQ +Rename Error +; +; +MSGID_ERRORREQ_BODYTEXT +Could not rename\n'%s' to '%s'\n%s +; +; +MSGID_REQ_OK + _Ok +; +; +MSGID_TEXTLINE_PATH +Path: \"%s\" +; +; +MSGID_BUTTON_SKIP +_Skip +; +; +MSGID_PATHOF_NAME +Path of object.\n\n\ +It's possible to show all content of this gadget using\n\ +the scroller located at the bottom of the window.\n\ +Can be usefull for large path lenght. +; Path of object.\n\\n\ +; It's possible to show me completly using\n\ +; the scroller located at bottom of the window.\n\ +; Can be usefull for large path lenght. +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Rename.module Prefs startup failed +;Rename.module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Try again|Quit +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; diff --git a/scalos/Modules/Rename.MUI/Rename.c b/scalos/Modules/Rename.MUI/Rename.c new file mode 100755 index 000000000..e2bb659ea --- /dev/null +++ b/scalos/Modules/Rename.MUI/Rename.c @@ -0,0 +1,1330 @@ +// Rename.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include // +jmc+ + +#include "Rename.h" + +#define Rename_NUMBERS +#define Rename_ARRAY +#define Rename_CODE +#include STR(SCALOSLOCALE) + +//---------------------------------------------------------------------------- + +#define VERSION_MAJOR 41 +#define VERSION_MINOR 2 + +//---------------------------------------------------------------------------- + +#define Application_Return_Ok 1001 +#define Application_Return_Skip 1002 + +#ifndef __AROS__ +#define BNULL ((BPTR) NULL) +#endif + +//---------------------------------------------------------------------------- + +#define KeyButtonHelp(name,key,HelpText)\ + TextObject,\ + ButtonFrame,\ + MUIA_Font, MUIV_Font_Button,\ + MUIA_Text_Contents, name,\ + MUIA_Text_PreParse, "\33c",\ + MUIA_Text_HiChar , key,\ + MUIA_ControlChar , key,\ + MUIA_InputMode , MUIV_InputMode_RelVerify,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShortHelp , HelpText,\ + MUIA_CycleChain , TRUE,\ + End + +//---------------------------------------------------------------------------- + +static BOOL OpenLibraries(void); +static void CloseLibraries(void); +static void UpdateGadgets(struct WBArg *arg); +static void ReportError(LONG Result, CONST_STRPTR OldObjName, CONST_STRPTR NewObjName); +static LONG RenameObject(struct WBArg *arg, APTR UndoStep); +void StripTrailingColon(STRPTR Line); +static SAVEDS(APTR) INTERRUPT OpenAboutMUIHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT OpenAboutHookFunc(struct Hook *hook, Object *o, Msg msg); +static STRPTR GetLocString(ULONG MsgId); +static BOOL CheckInfoData(const struct InfoData *info); +static BOOL isDiskWritable(BPTR dLock); +static BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev); +static BOOL IfLocateName(STRPTR FileName); +static BOOL FindScalosIcon(struct Rectangle *IconNameRect, struct WBArg *Icon); +static BOOL FindScalosDeviceIcon(struct Rectangle *IconNameRect, + BPTR DeviceLock, struct ScaWindowStruct *ws); +static struct ScaWindowStruct *FindScalosWindow(BPTR dirLock); + +//---------------------------------------------------------------------------- + +#if !defined(__amigaos4__) && !defined(__AROS__) +#include + +long _stack = 16384; // minimum stack size, used by SAS/C startup code +#endif + +//---------------------------------------------------------------------------- + +extern struct ExecBase *SysBase; +struct IntuitionBase *IntuitionBase = NULL; +T_LOCALEBASE LocaleBase = NULL; +struct ScalosBase *ScalosBase = NULL; +#ifndef __amigaos4__ +T_UTILITYBASE UtilityBase = NULL; +#endif +struct Library *MUIMasterBase = NULL; + +#ifdef __amigaos4__ +struct IntuitionIFace *IIntuition = NULL; +struct LocaleIFace *ILocale = NULL; +struct MUIMasterIFace *IMUIMaster = NULL; +struct ScalosIFace *IScalos = NULL; +#endif + +static struct Catalog *gb_Catalog; + +static BOOL RenameInPlace = FALSE; +static BOOL RenameVolume = FALSE; + +static struct Hook AboutHook = { { NULL, NULL }, HOOKFUNC_DEF(OpenAboutHookFunc), NULL }; +static struct Hook AboutMUIHook = { { NULL, NULL }, HOOKFUNC_DEF(OpenAboutMUIHookFunc), NULL }; + +//---------------------------------------------------------------------------- + +static Object *Group_Buttons2; +static Object *APP_Main; +static Object *WIN_Main; +static Object *WIN_AboutMUI; +static Object *OkButton, *SkipButton, *CancelButton; +static Object *MenuAbout, *MenuAboutMUI, *MenuQuit; +static Object *TextEnterName; +static Object *TextPath; +static Object *StringNewName; +static Object *TextinputNewName; + +//---------------------------------------------------------------------------- + +int main(int argc, char *argv[]) +{ + struct ScaWindowList *wl = NULL; + APTR UndoStep = NULL; + LONG win_opened = 0; + ULONG n; + struct WBStartup *WBenchMsg = + (argc == 0) ? (struct WBStartup *)argv : NULL; + + if (NULL == WBenchMsg) + { + return 5; + } + if (WBenchMsg->sm_NumArgs < 2) + { + return 5; + } + + do { + char EnvBuff[100]; + + if (!OpenLibraries()) + break; + + if (!CheckMCCVersion(MUIC_BetterString, 11, 0)) + break; + + gb_Catalog = OpenCatalogA(NULL, "Scalos/Rename.catalog",NULL); + + if ((GetVar("Scalos/RENAMEINPLACE", EnvBuff, sizeof(EnvBuff), 0) >= 0) && + (CheckMCCVersion(MUIC_Textinput, MCC_Textinput_Version, MCC_Textinput_Revision))) + { + RenameInPlace = TRUE; + } + + wl = SCA_LockWindowList(SCA_LockWindowList_Shared); + if (wl) + { + struct ScaWindowStruct *ws = wl->wl_WindowStruct; + + UndoStep = (APTR) DoMethod(ws->ws_WindowTask->mt_MainObject, + SCCM_IconWin_BeginUndoStep); + } + + if (RenameInPlace) + { + struct Rectangle IconRect; + + if (!FindScalosIcon(&IconRect, &WBenchMsg->sm_ArgList[1])) + break; + + d1(KPrintF(__FILE__ "/%s/%ld: MinX=%ld MinY=%ld MaxX=%ld MaxY=%ld\n", \ + __FUNC__, __LINE__, IconRect.MinX, IconRect.MinY, IconRect.MaxX, IconRect.MaxY)); + + WIN_Main = WindowObject, + MUIA_Window_AppWindow, FALSE, + MUIA_Window_CloseGadget, FALSE, + MUIA_Window_DepthGadget, FALSE, + MUIA_Window_DragBar, FALSE, + MUIA_Window_SizeGadget, FALSE, + MUIA_Window_Borderless, TRUE, + + MUIA_Window_LeftEdge, IconRect.MinX, + MUIA_Window_TopEdge, IconRect.MinY, + MUIA_Window_Width, 1 + IconRect.MaxX - IconRect.MinX, + MUIA_Window_Height, 1 + IconRect.MaxY - IconRect.MinY, + + WindowContents, VGroup, + MUIA_InnerRight, 0, + MUIA_InnerLeft, 0, + MUIA_InnerTop, 0, + MUIA_InnerBottom, 0, + + Child, TextinputNewName = TextinputObject, + MUIA_InnerRight, 0, + MUIA_InnerLeft, 0, + MUIA_InnerTop, 0, + MUIA_InnerBottom, 0, + StringFrame, + MUIA_Textinput_RejectChars, "/:", + MUIA_Background, MUII_TextBack, + MUIA_CycleChain, TRUE, +// MUIA_Textinput_Multiline, TRUE, + MUIA_Textinput_MaxLen, 108, + MUIA_Textinput_MaxLines, 2, + MUIA_Textinput_SetVMin, TRUE, + MUIA_Textinput_NoExtraSpacing, TRUE, + MUIA_Textinput_ProhibitParse, TRUE, + MUIA_Textinput_Styles, MUIV_Textinput_Styles_None, + MUIA_Textinput_ResetMarkOnCursor, TRUE, + End, //TextinputObject + End, //VGroup + End; //WindowObject + } + else + { + WIN_Main = WindowObject, + MUIA_Window_Title, GetLocString(MSGID_TITLENAME), +// MUIA_Window_ID, MAKE_ID('M','A','I','N'), + MUIA_Window_AppWindow, TRUE, + MUIA_Window_UseBottomBorderScroller, TRUE, // +jmc+ + + MUIA_Window_TopEdge, MUIV_Window_TopEdge_Moused, + MUIA_Window_LeftEdge, MUIV_Window_LeftEdge_Moused, + + MUIA_Window_Width, MUIV_Window_Width_Screen(30), // +jmc+ + + WindowContents, VGroup, + Child, VGroup, + Child, TextEnterName = TextObject, + MUIA_Text_PreParse, MUIX_C, + End, //TextObject + + Child, GroupObject, // +jmc+ + Child, ScrollgroupObject, + MUIA_Scrollgroup_VertBar, NULL, + MUIA_Scrollgroup_HorizBar, NULL, + MUIA_Scrollgroup_FreeHoriz, TRUE, + MUIA_Scrollgroup_FreeVert, FALSE, + MUIA_Scrollgroup_UseWinBorder, TRUE, + MUIA_Scrollgroup_Contents, + VirtgroupObject, + Child, TextPath = TextObject, + MUIA_Text_PreParse, MUIX_C, + MUIA_ShortHelp, GetLocString(MSGID_PATHOF_NAME), + End, //TextObject + End, //VirtgroupObject + End, //ScrollgroupObject + End, //GroupObject + + Child, VSpace(1), + + Child, HGroup, + Child, Label1(GetLocString(MSGID_LABEL_NEWNAME)), + Child, StringNewName = BetterStringObject, + StringFrame, + MUIA_String_Reject, "/:", + MUIA_Background, MUII_TextBack, + MUIA_String_MaxLen, 108, + MUIA_CycleChain, TRUE, + End, //StringObject + End, //HGroup + End, //VGroup + + Child, Group_Buttons2 = HGroup, + MUIA_Group_SameWidth, TRUE, + Child, OkButton = KeyButtonHelp(GetLocString(MSGID_OKBUTTON), + *GetLocString(MSGID_OKBUTTON_SHORT), GetLocString(MSGID_SHORTHELP_OKBUTTON)), + Child, SkipButton = KeyButtonHelp(GetLocString(MSGID_SKIPBUTTON), + *GetLocString(MSGID_SKIPBUTTON_SHORT), GetLocString(MSGID_SHORTHELP_SKIPBUTTON)), + Child, CancelButton = KeyButtonHelp(GetLocString(MSGID_CANCELBUTTON), + *GetLocString(MSGID_CANCELBUTTON_SHORT), GetLocString(MSGID_SHORTHELP_CANCELBUTTON)), + End, //HGroup + End, //VGroup + End; //WindowObject + } + + APP_Main = ApplicationObject, + MUIA_Application_Title, GetLocString(MSGID_TITLENAME), + MUIA_Application_Version, "$VER: Scalos Rename.module V" + STR(VERSION_MAJOR) "." STR(VERSION_MINOR) " (" __DATE__ ") " COMPILER_STRING, + MUIA_Application_Copyright, "© The Scalos Team, 2004" CURRENTYEAR, + MUIA_Application_Author, "The Scalos Team", + MUIA_Application_Description, "Scalos Rename module", + MUIA_Application_Base, "SCALOS_RENAME", + + SubWindow, WIN_Main, + + MUIA_Application_Menustrip, MenustripObject, + Child, MenuObjectT(GetLocString(MSGID_MENU_PROJECT)), + + Child, MenuAbout = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUT), + End, + Child, MenuAboutMUI = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUTMUI), + End, + Child, MenuitemObject, + MUIA_Menuitem_Title, -1, + End, + Child, MenuQuit = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_QUIT), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_PROJECT_QUIT_SHORT), + End, + + End, //MenuObjectT + End, //MenuStripObject + + End; //ApplicationObject + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: \n", __LINE__)); + + if (NULL == APP_Main) + { + printf(GetLocString(MSGID_CREATE_APPLICATION_FAILED)); + break; + } + + if (RenameInPlace) + { + DoMethod(TextinputNewName, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, + APP_Main, 2, MUIM_Application_ReturnID, Application_Return_Ok); + + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_Activate, FALSE, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + } + else + { + DoMethod(CancelButton, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + DoMethod(OkButton, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_Application_ReturnID, Application_Return_Ok); + DoMethod(SkipButton, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_Application_ReturnID, Application_Return_Skip); + + DoMethod(StringNewName, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, + APP_Main, 2, MUIM_Application_ReturnID, Application_Return_Ok); + } + + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + WIN_Main, 3, MUIM_Set, MUIA_Window_Open, FALSE); + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + DoMethod(MenuAbout, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &AboutHook); + DoMethod(MenuAboutMUI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &AboutMUIHook); + DoMethod(MenuQuit, MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + for (n = 1; n < WBenchMsg->sm_NumArgs; n++) + { + struct WBArg *arg = &WBenchMsg->sm_ArgList[n]; + ULONG sigs = 0; + BOOL Run = TRUE; + BOOL IsWriteable = isDiskWritable(arg->wa_Lock); + + if (RenameInPlace) + { + struct Rectangle IconRect; + + if (FindScalosIcon(&IconRect, arg)) + { + set(TextinputNewName, MUIA_Disabled, !IsWriteable); + + SetAttrs(WIN_Main, + MUIA_Window_LeftEdge, IconRect.MinX, + MUIA_Window_TopEdge, IconRect.MinY, + MUIA_Window_Width, 1 + IconRect.MaxX - IconRect.MinX, + MUIA_Window_Height, 1 + IconRect.MaxY - IconRect.MinY, + TAG_END); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + } + } + else + { + set(OkButton, MUIA_Disabled, !IsWriteable); + set(StringNewName, MUIA_Disabled, !IsWriteable); + } + + UpdateGadgets(arg); + + set(WIN_Main, MUIA_Window_Open, TRUE); + get(WIN_Main, MUIA_Window_Open, &win_opened); + + if (!win_opened) + { + printf(GetLocString(MSGID_CREATE_MAINWINDOW_FAILED)); + break; + } + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: \n", __LINE__)); + + set(WIN_Main, MUIA_Window_ActiveObject, RenameInPlace ? TextinputNewName : StringNewName); + + while (Run) + { + ULONG Action = DoMethod(APP_Main, MUIM_Application_NewInput, &sigs); + + switch (Action) + { + case Application_Return_Ok: + RenameObject(arg, UndoStep); + Run = FALSE; + break; + case Application_Return_Skip: + Run = FALSE; + break; + case MUIV_Application_ReturnID_Quit: + n = WBenchMsg->sm_NumArgs; + Run = FALSE; + break; + } + + if (Run && sigs) + { + sigs = Wait(sigs | SIGBREAKF_CTRL_C); + + if (sigs & SIGBREAKF_CTRL_C) + { + Run = FALSE; + } + } + } + } + + set(WIN_Main, MUIA_Window_Open, FALSE); + } while (0); + + if (wl) + { + if (UndoStep) + { + struct ScaWindowStruct *ws = wl->wl_WindowStruct; + + DoMethod(ws->ws_WindowTask->mt_MainObject, + SCCM_IconWin_EndUndoStep, + UndoStep); + } + SCA_UnLockWindowList(); + } + + if (APP_Main) + MUI_DisposeObject(APP_Main); + if(gb_Catalog) + CloseCatalog(gb_Catalog); + + CloseLibraries(); + + return 0; +} + +//---------------------------------------------------------------------------- + +static BOOL OpenLibraries(void) +{ + MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN-1); + if (NULL == MUIMasterBase) + { + puts("Can't open muimaster.library."); + return FALSE; + } +#ifdef __amigaos4__ + else + { + IMUIMaster = (struct MUIMasterIFace *)GetInterface((struct Library *)MUIMasterBase, "main", 1, NULL); + if (NULL == IMUIMaster) + { + puts("Can't open muimaster interface"); + return FALSE; + } + } +#endif //__amigaos4__ + + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + if (NULL == IntuitionBase) + { + puts("Can't open intuition.library."); + return FALSE; + } +#ifdef __amigaos4__ + else + { + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + { + puts("Can't open intuition interface."); + return FALSE; + } + } +#endif //__amigaos4__ + + LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 38); + if (NULL == LocaleBase) + { + puts("Can't open locale.library."); + return FALSE; + } +#ifdef __amigaos4__ + else + { + ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL); + if (NULL == ILocale) + { + puts("Can't open locale interface."); + return FALSE; + } + } +#endif //__amigaos4__ + +#ifndef __amigaos4__ + UtilityBase = (T_UTILITYBASE) OpenLibrary("utility.library", 39); + if (NULL == UtilityBase) + { + puts("Can't open utility.library."); + return FALSE; + } +#endif //__amigaos4__ + + ScalosBase = (struct ScalosBase *) OpenLibrary(SCALOSNAME, 40); + if (NULL == ScalosBase) + { + puts("Can't open scalos.library."); + return FALSE; + } +#ifdef __amigaos4__ + else + { + IScalos = (struct ScalosIFace *)GetInterface((struct Library *)ScalosBase, "main", 1, NULL); + if (NULL == IScalos) + { + puts("Can't open scalos interface."); + return FALSE; + } + } +#endif //__amigaos4__ + + return TRUE; +} + +//---------------------------------------------------------------------------- + +static void CloseLibraries(void) +{ +#ifdef __amigaos4__ + if (IScalos) + { + DropInterface((struct Interface *)IScalos); + IScalos = NULL; + } +#endif + if (ScalosBase) + { + CloseLibrary((struct Library *) ScalosBase); + ScalosBase = NULL; + } +#ifndef __amigaos4__ + if (UtilityBase) + { + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } +#endif //__amigaos4__ +#ifdef __amigaos4__ + if (ILocale) + { + DropInterface((struct Interface *)ILocale); + IIntuition = NULL; + } +#endif //__amigaos4__ + if (LocaleBase) + { + CloseLibrary((struct Library *)LocaleBase); + LocaleBase = NULL; + } +#ifdef __amigaos4__ + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } +#endif //__amigaos4__ + if (IntuitionBase) + { + CloseLibrary((struct Library *)IntuitionBase); + IntuitionBase = NULL; + } +#ifdef __amigaos4__ + if (IMUIMaster) + { + DropInterface((struct Interface *)IMUIMaster); + IMUIMaster = NULL; + } +#endif //__amigaos4__ + if (MUIMasterBase) + { + CloseLibrary(MUIMasterBase); + MUIMasterBase = NULL; + } +} + +//---------------------------------------------------------------------------- + +static void UpdateGadgets(struct WBArg *arg) +{ + static char LabelText[1024]; + static char PathText[1024]; + STRPTR FileName; + char xName[512]; + BPTR NLock; + BPTR oldDir = (BPTR)NULL; + + NameFromLock(arg->wa_Lock, xName, sizeof(xName)); + + if (arg->wa_Name && strlen(arg->wa_Name) > 0) + FileName = arg->wa_Name; + else + FileName = FilePart(xName); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: FileName =<%s> xName=<%s> wa_Name=%08lx <%s>\n", __LINE__, FileName, xName, arg->wa_Name, arg->wa_Name ? arg->wa_Name : "")); + + if (':' == xName[strlen(xName)-1] && strlen(arg->wa_Name) < 1) + { + sprintf(PathText, GetLocString(MSGID_TEXTLINE_PATH), xName); + + StripTrailingColon(xName); + + FileName = xName; + + RenameVolume = TRUE; + } + else + { + NLock = DupLock(arg->wa_Lock); + if (NLock) + { + BOOL IfName; + char xIconOnly[512]; + + oldDir = CurrentDir(NLock); + stccpy(xIconOnly, (STRPTR) FileName, sizeof(xIconOnly)); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: AddPart(): FileName=<%s> xIconOnly =<%s>\n", __LINE__, FileName, xIconOnly)); + + IfName = IfLocateName(xIconOnly); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: IfLocateName(%s) FileName = <%s> IfName = %ld\n", __LINE__, xIconOnly, FileName, IfName)); + + if (!IfName) + { + BOOL IfNewName; + + strcat(xIconOnly,".info"); + IfNewName = IfLocateName(xIconOnly); + + if (IfNewName) + FileName = xIconOnly; + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: FileName = <%s> IfNewName = %ld xIconOnly =<%s>\n", __LINE__, FileName, IfNewName, xIconOnly)); + } + } + + if (NLock) + { + CurrentDir(oldDir); + UnLock(NLock); + } + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: xname=<%s> FileName=<%s>\n", __LINE__, xName, FileName)); + + sprintf(PathText, GetLocString(MSGID_TEXTLINE_PATH), xName); + d1(KPrintF("FileName =<%s> xName=<%s> wa_Name=%08lx <%s>\n", FileName, xName, arg->wa_Name, arg->wa_Name ? arg->wa_Name : "")); + } + + + if (RenameInPlace) + { + SetAttrs(TextinputNewName, + MUIA_Textinput_Contents, FileName, + MUIA_Textinput_MarkStart, 0, + MUIA_Textinput_MarkEnd, strlen(FileName), + MUIA_Textinput_CursorPos, strlen(FileName), + TAG_END); + } + else + { + sprintf(LabelText, GetLocString(MSGID_TEXTLINE_ENTERNEWNAME), FileName); + + SetAttrs(StringNewName, + MUIA_String_Contents, FileName, + MUIA_BetterString_SelectSize, -strlen(FileName), + TAG_END); + + SetAttrs(TextEnterName, + MUIA_Text_Contents, LabelText, + TAG_END); + SetAttrs(TextPath, + MUIA_Text_Contents, PathText, + TAG_END); + } +} + +//---------------------------------------------------------------------------- + +static BOOL IfLocateName(STRPTR FileName) +{ + BPTR FLock; + + FLock = Lock(FileName, ACCESS_READ); + if ((BPTR)NULL == FLock) + return FALSE; + + if (FLock) + UnLock(FLock); + + return TRUE; +} + +//---------------------------------------------------------------------------- + +static void ReportError(LONG Result, CONST_STRPTR OldObjName, CONST_STRPTR NewObjName) +{ + char FaultText[256]; + + Fault(Result, "", FaultText, sizeof(FaultText)); + + MUI_Request(APP_Main, WIN_Main, 0, NULL, + GetLocString(MSGID_REQ_OK), + GetLocString(MSGID_ERRORREQ_BODYTEXT), + OldObjName, NewObjName, FaultText); +} + +//---------------------------------------------------------------------------- + +static LONG RenameObject(struct WBArg *arg, APTR UndoStep) +{ + BPTR dirLock; + LONG Result = RETURN_OK; + STRPTR NewObjName = NULL; + STRPTR OldObjName; + char ObjName[512]; + BPTR oldDir = (BPTR)NULL; + struct ScaWindowStruct *ws; + BOOL IsWriteable = isDiskWritable(arg->wa_Lock); + + if (!IsWriteable) + return ERROR_WRITE_PROTECTED; + + NameFromLock(arg->wa_Lock, ObjName, sizeof(ObjName)); + + if (RenameInPlace) + GetAttr(MUIA_Textinput_Contents, TextinputNewName, (APTR) &NewObjName); + else + GetAttr(MUIA_String_Contents, StringNewName, (APTR) &NewObjName); + + if (arg->wa_Name && strlen(arg->wa_Name) > 0) + { + OldObjName = arg->wa_Name; + dirLock = DupLock(arg->wa_Lock); + } + else + { + OldObjName = FilePart(ObjName); + dirLock = ParentDir(arg->wa_Lock); + } + + ws = FindScalosWindow(dirLock); + + if (dirLock) + oldDir = CurrentDir(dirLock); + + d1(KPrintF("dirLock=%08lx\n", dirLock)); + + if (NewObjName && strlen(NewObjName) > 0) + { + BOOL IfName; + char xIconOnly[512]; + + if (RenameVolume) + { + StripTrailingColon(NewObjName); + + d1(KPrintF("OldName=<%s> NewName=<%s>\n", ObjName, NewObjName)); + + if (ws) + { + DoMethod(ws->ws_WindowTask->mt_MainObject, + SCCM_IconWin_AddUndoEvent, + UNDO_Relabel, + UNDOTAG_CopySrcDirLock, dirLock, + UNDOTAG_CopySrcName, ObjName, + UNDOTAG_CopyDestName, NewObjName, + TAG_END + ); + } + + if (!Relabel(ObjName, NewObjName)) + { + Result = IoErr(); + OldObjName = ObjName; + } + } + else + { + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: OldName=<%s> NewName=<%s>\n", __LINE__, OldObjName, NewObjName)); + + stccpy(xIconOnly, OldObjName, sizeof(xIconOnly)); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: stccpy(): OldObjName=<%s> xIconOnly =<%s>\n", __LINE__, OldObjName, xIconOnly)); + + IfName = IfLocateName(xIconOnly); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: IfLocateName(%s) OldObjName = <%s> IfName = %ld\n", __LINE__, xIconOnly, OldObjName, IfName)); + + if (!IfName) + { + BOOL IfNewName; + + strcat(xIconOnly,".info"); + IfNewName = IfLocateName(xIconOnly); + + if (IfNewName) + { + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: IfLocateName(%s) OldObjName = <%s> IfNewName = %ld\n", __LINE__, xIconOnly, OldObjName, IfNewName)); + OldObjName = xIconOnly; + } + } + + if (ws) + { + DoMethod(ws->ws_WindowTask->mt_MainObject, + SCCM_IconWin_AddUndoEvent, + UNDO_Rename, + UNDOTAG_CopySrcDirLock, dirLock, + UNDOTAG_CopySrcName, OldObjName, + UNDOTAG_CopyDestName, NewObjName, + TAG_END + ); + } + + if (!Rename(OldObjName, NewObjName)) + Result = IoErr(); + + // handle orphaned icons here (icons w/o object) + if (ERROR_OBJECT_NOT_FOUND == Result) + Result = RETURN_OK; + } + + if (RETURN_OK != Result) + ReportError(Result, OldObjName, NewObjName); + else + { + // try to rename associated icon + char OldIconName[512]; + char NewIconName[512]; + + stccpy(OldIconName, OldObjName, sizeof(OldIconName) - 5); + strcat(OldIconName, ".info"); + + stccpy(NewIconName, NewObjName, sizeof(NewIconName) - 5); + strcat(NewIconName, ".info"); + + if (!Rename(OldIconName, NewIconName)) + Result = IoErr(); + + if (ERROR_OBJECT_NOT_FOUND == Result) + Result = RETURN_OK; + + if (RETURN_OK != Result) + ReportError(Result, OldIconName, NewIconName); + } + } + + if (ws) + SCA_UnLockWindowList(); + + if (dirLock) + { + CurrentDir(oldDir); + UnLock(dirLock); + } + + return Result; +} + +//---------------------------------------------------------------------------- + +void StripTrailingColon(STRPTR Line) +{ + size_t Len = strlen(Line); + + Line += Len - 1; + + if (':' == *Line) + *Line = '\0'; +} + +//---------------------------------------------------------------------------- + +static STRPTR GetLocString(ULONG MsgId) +{ + struct Rename_LocaleInfo li; + + li.li_Catalog = gb_Catalog; +#ifndef __amigaos4__ + li.li_LocaleBase = LocaleBase; +#else + li.li_ILocale = ILocale; +#endif + + return (STRPTR)GetRenameString(&li, MsgId); +} + +/* +static void TranslateStringArray(STRPTR *stringArray) +{ + while (*stringArray) + { + *stringArray = GetLocString((ULONG) *stringArray); + stringArray++; + } +} +*/ + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT OpenAboutMUIHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + if (NULL == WIN_AboutMUI) + { + WIN_AboutMUI = MUI_NewObject(MUIC_Aboutmui, + MUIA_Window_RefWindow, WIN_Main, + MUIA_Aboutmui_Application, APP_Main, + End; + } + + if (WIN_AboutMUI) + set(WIN_AboutMUI, MUIA_Window_Open, TRUE); + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT OpenAboutHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + MUI_Request(APP_Main, WIN_Main, 0, NULL, + GetLocString(MSGID_ABOUTREQOK), + GetLocString(MSGID_ABOUTREQFORMAT), + VERSION_MAJOR, VERSION_MINOR, COMPILER_STRING, CURRENTYEAR); +} + +//---------------------------------------------------------------------------- + +// return TRUE if Disk is writable +static BOOL CheckInfoData(const struct InfoData *info) +{ + BOOL Result = TRUE; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: DiskType=%ld DiskState=%ld\n", __LINE__, info->id_DiskType, info->id_DiskState)); + + switch (info->id_DiskType) + { + case ID_NO_DISK_PRESENT: + case ID_UNREADABLE_DISK: + Result = FALSE; + break; + } + + if (ID_WRITE_PROTECTED == info->id_DiskState) + Result = FALSE; + + return Result; +} + + +static BOOL isDiskWritable(BPTR dLock) +{ + struct InfoData *info = malloc(sizeof(struct InfoData)); + BOOL Result = TRUE; + + if (info) + { + Info(dLock, info); + + if (!CheckInfoData(info)) + Result = FALSE; + + free(info); + } + + return Result; +} + +//---------------------------------------------------------------------------- + +// Checks if a certain version of a MCC is available +static BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev) +{ + BOOL flush = TRUE; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: %s ", name, __LINE__);) + + while (1) + { + ULONG ver = 0; + ULONG rev = 0; + struct Library *base; + char libname[256]; + + // First we attempt to acquire the version and revision through MUI + Object *obj = MUI_NewObject((STRPTR) name, TAG_DONE); + if (obj) + { + get(obj, MUIA_Version, &ver); + get(obj, MUIA_Revision, &rev); + + MUI_DisposeObject(obj); + + if(ver > minver || (ver == minver && rev >= minrev)) + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: v%ld.%ld found through MUIA_Version/Revision\n", __LINE__, ver, rev);) + return TRUE; + } + } + + // If we did't get the version we wanted, let's try to open the + // libraries ourselves and see what happens... + stccpy(libname, "PROGDIR:mui", sizeof(libname)); + AddPart(libname, name, sizeof(libname)); + + if ((base = OpenLibrary(&libname[8], 0)) || (base = OpenLibrary(&libname[0], 0))) + { + UWORD OpenCnt = base->lib_OpenCnt; + + ver = base->lib_Version; + rev = base->lib_Revision; + + CloseLibrary(base); + + // we add some additional check here so that eventual broken .mcc also have + // a chance to pass this test (i.e. Toolbar.mcc is broken) + if (ver > minver || (ver == minver && rev >= minrev)) + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: v%ld.%ld found through OpenLibrary()\n", __LINE__, ver, rev);) + return TRUE; + } + + if (OpenCnt > 1) + { + if (MUI_Request(NULL, NULL, 0L, GetLocString(MSGID_STARTUP_FAILURE), + GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), GetLocString(MSGID_STARTUP_MCC_IN_USE), + name, minver, minrev, ver, rev)) + { + flush = TRUE; + } + else + break; + } + + // Attempt to flush the library if open count is 0 or because the + // user wants to retry (meaning there's a chance that it's 0 now) + + if (flush) + { + struct Library *result; + + Forbid(); + if ((result = (struct Library *) FindName(&((struct ExecBase *)SysBase)->LibList, name))) + RemLibrary(result); + Permit(); + flush = FALSE; + } + else + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: couldn`t find minimum required version.\n", __LINE__);) + + // We're out of luck - open count is 0, we've tried to flush + // and still haven't got the version we want + if (MUI_Request(NULL, NULL, 0L, GetLocString(MSGID_STARTUP_FAILURE), + GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), GetLocString(MSGID_STARTUP_OLD_MCC), + name, minver, minrev, ver, rev)) + { + flush = TRUE; + } + else + break; + } + } + else + { + // No MCC at all - no need to attempt flush + flush = FALSE; + if (!MUI_Request(NULL, NULL, 0L, GetLocString(MSGID_STARTUP_FAILURE), + GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), GetLocString(MSGID_STARTUP_MCC_NOT_FOUND), + name, minver, minrev)) + { + break; + } + } + } + + return FALSE; +} + +//---------------------------------------------------------------------------- + +static BOOL FindScalosIcon(struct Rectangle *IconNameRect, struct WBArg *Icon) +{ + struct ScaWindowList *wl; + BOOL Found = FALSE; + + d1(KPrintF(__FILE__ "/%s/%ld: START wa_Name=<%s>\n", __FUNC__, __LINE__, Icon->wa_Name);) + debugLock_d1(Icon->wa_Lock); + + wl = SCA_LockWindowList(SCA_LockWindowList_Shared); + d1(KPrintF(__FILE__ "/%s/%ld: wl=%08lx\n", __FUNC__, __LINE__, wl);) + if (wl) + { + if (NULL == Icon->wa_Name || strlen(Icon->wa_Name) < 1) + { + Found = FindScalosDeviceIcon(IconNameRect, Icon->wa_Lock, wl->wl_WindowStruct); + } + else + { + struct ScaWindowStruct *ws; + + for (ws = wl->wl_WindowStruct; !Found && ws; ws = (struct ScaWindowStruct *) ws->ws_Node.mln_Succ) + { + struct ScaWindowTask *wt = ws->ws_WindowTask; + const struct ScaIconNode *in; + + if (ws->ws_Lock) + { + if (LOCK_SAME == SameLock(Icon->wa_Lock, ws->ws_Lock)) + { + IPTR Left = 0, Top = 0; + + GetAttr(SCCA_IconWin_InnerLeft, ws->ws_WindowTask->mt_MainObject, &Left); + GetAttr(SCCA_IconWin_InnerTop, ws->ws_WindowTask->mt_MainObject, &Top); + + IconNameRect->MinX = ws->ws_Window->LeftEdge + Left; + IconNameRect->MinY = ws->ws_Window->TopEdge + Top; + + d1(KPrintF(__FILE__ "/%s/%ld: MinX=%ld MinY=%ld\n", __FUNC__, __LINE__, IconNameRect->MinX, IconNameRect->MinY);) + + ObtainSemaphoreShared(wt->wt_IconSemaphore); + + for (in = wt->wt_IconList; in; in = (const struct ScaIconNode *) in->in_Node.mln_Succ) + { + if (0 == Stricmp(in->in_Name, Icon->wa_Name)) + { + const struct ExtGadget *gg = (const struct ExtGadget *) in->in_Icon; + + IconNameRect->MinX += gg->BoundsLeftEdge - wt->wt_XOffset; + IconNameRect->MinY += gg->TopEdge + gg->Height - wt->wt_YOffset; + IconNameRect->MaxX = IconNameRect->MinX + gg->BoundsWidth - 1; + IconNameRect->MaxY = IconNameRect->MinY + gg->BoundsHeight - 1; + + Found = TRUE; + break; + } + } + + ReleaseSemaphore(wt->wt_IconSemaphore); + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__);) + + break; + } + } + else + { + // Desktop window + // Search through backdrop icons + + IconNameRect->MinX = 0; + IconNameRect->MinY = 0; + + ObtainSemaphoreShared(wt->wt_IconSemaphore); + + for (in = wt->wt_IconList; in; in = (const struct ScaIconNode *) in->in_Node.mln_Succ) + { + if (in->in_Lock + && LOCK_SAME == SameLock(Icon->wa_Lock, in->in_Lock) + && 0 == Stricmp(in->in_Name, Icon->wa_Name)) + { + const struct ExtGadget *gg = (const struct ExtGadget *) in->in_Icon; + + d1(KPrintF(__FILE__ "/%s/%ld: FOUND, in=%08lx <%s>\n", __FUNC__, __LINE__, in, GetIconName(in));) + + IconNameRect->MinX += gg->BoundsLeftEdge - wt->wt_XOffset; + IconNameRect->MinY += gg->TopEdge + gg->Height - wt->wt_YOffset; + IconNameRect->MaxX = IconNameRect->MinX + gg->BoundsWidth - 1; + IconNameRect->MaxY = IconNameRect->MinY + gg->BoundsHeight - 1; + + Found = TRUE; + break; + } + } + ReleaseSemaphore(wt->wt_IconSemaphore); + } + } + } + + SCA_UnLockWindowList(); + } + + d1(KPrintF(__FILE__ "/%s/%ld: END\n", __FUNC__, __LINE__);) + + return Found; +} + +//---------------------------------------------------------------------------- + +static BOOL FindScalosDeviceIcon(struct Rectangle *IconNameRect, + BPTR DeviceLock, struct ScaWindowStruct *ws) +{ + BOOL Found = FALSE; + + for (; !Found && ws; ws = (struct ScaWindowStruct *) ws->ws_Node.mln_Succ) + { + if ((BPTR)NULL == ws->ws_Lock) + { + // This is the desktop window + struct ScaWindowTask *wt = ws->ws_WindowTask; + const struct ScaIconNode *in; + + ObtainSemaphoreShared(wt->wt_IconSemaphore); + + for (in = wt->wt_IconList; !Found && in; in = (const struct ScaIconNode *) in->in_Node.mln_Succ) + { + if (in->in_DeviceIcon && in->in_DeviceIcon->di_Volume) + { + STRPTR DevName; + + DevName = malloc(2 + strlen(in->in_DeviceIcon->di_Volume)); + if (DevName) + { + BPTR dLock; + + strcpy(DevName, in->in_DeviceIcon->di_Volume); + strcat(DevName, ":"); + + IconNameRect->MinX = IconNameRect->MinY = 0; + + dLock = Lock(DevName, ACCESS_READ); + if (dLock) + { + if (LOCK_SAME == SameLock(dLock, DeviceLock)) + { + const struct ExtGadget *gg = (const struct ExtGadget *) in->in_Icon; + + IconNameRect->MinX += gg->BoundsLeftEdge - wt->wt_XOffset; + IconNameRect->MinY += gg->TopEdge + gg->Height - wt->wt_YOffset; + IconNameRect->MaxX = IconNameRect->MinX + gg->BoundsWidth - 1; + IconNameRect->MaxY = IconNameRect->MinY + gg->BoundsHeight - 1; + + Found = TRUE; + } + UnLock(dLock); + } + free(DevName); + } + } + } + + ReleaseSemaphore(wt->wt_IconSemaphore); + break; + } + } + + return Found; +} + +//---------------------------------------------------------------------------- + +static struct ScaWindowStruct *FindScalosWindow(BPTR dirLock) +{ + struct ScaWindowList *wl; + BOOL Found = FALSE; + + d1(KPrintF(__FILE__ "/%s/%ld: START \n", __FUNC__, __LINE__)); + + wl = SCA_LockWindowList(SCA_LockWindowList_Shared); + + if (wl) + { + struct ScaWindowStruct *ws; + + for (ws = wl->wl_WindowStruct; !Found && ws; ws = (struct ScaWindowStruct *) ws->ws_Node.mln_Succ) + { + if ((BNULL == dirLock && BNULL == ws->ws_Lock) || (LOCK_SAME == SameLock(dirLock, ws->ws_Lock))) + { + return ws; + } + } + SCA_UnLockWindowList(); + } + + return NULL; +} + +//---------------------------------------------------------------------------- + diff --git a/scalos/Modules/Rename.MUI/Rename.cd b/scalos/Modules/Rename.MUI/Rename.cd new file mode 100755 index 000000000..780232fc4 --- /dev/null +++ b/scalos/Modules/Rename.MUI/Rename.cd @@ -0,0 +1,161 @@ +; Rename.cd +; version $VER: Rename.catalog 40.1 (26 Feb 2005 21:03:45) +; codeset 0s +; language english +; +;#arrayopts static __far +; +; +MSGID_TITLENAME (//) +Scalos Rename +; +; +MSGID_OKBUTTON (//) +Rename +; +; +MSGID_OKBUTTON_SHORT (/1/1) +r +; +; +MSGID_SHORTHELP_OKBUTTON (//) +Rename the object as\n\ +the string gadget's content. +; +; +MSGID_SKIPBUTTON (//) +Skip +; +; +MSGID_SKIPBUTTON_SHORT (/1/1) +s +; +; +MSGID_SHORTHELP_SKIPBUTTON (//) +..SkipButton.. +; +; +MSGID_CANCELBUTTON (//) +Cancel +; +; +MSGID_CANCELBUTTON_SHORT (/1/1) +c +; +; +MSGID_SHORTHELP_CANCELBUTTON (//) +Discard all changes and\n\ +leave keep the original name. +; +; +MSGID_CREATE_APPLICATION_FAILED (//) +Failed to create Application.\n +; +; +MSGID_CREATE_MAINWINDOW_FAILED (//) +Failed to open main window !\n +; +; +MSGID_OPEN_LIBRARY_FAILED (//) +Failed to open \"%s\" !\n +; +;;----------------------------------------------------------- +; +MSGID_MENU_PROJECT (2000//) +Project +; +; +MSGID_MENU_PROJECT_ABOUT (//) +About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI (//) +About MUI... +; +; +MSGID_MENU_PROJECT_QUIT (//) +Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT (//) +Q +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK (3000//) +_OK +; +; +MSGID_ABOUTREQFORMAT (//) +\33c\033bScalos Rename.module V%ld.%ld\033n\n\ +%s\n\ +© 2004%s The Scalos Team +; +;----------------------------------------------------------- +; +; +MSGID_TEXTLINE_ENTERNEWNAME (4000//) +Enter a new Name for \"%s\" +; +; +MSGID_LABEL_NEWNAME (//) +New Name +; +; +MSGID_TITLE_ERRORREQ (//) +Rename Error +; +; +MSGID_ERRORREQ_BODYTEXT (//) +Could not rename\n'%s' to '%s'\n%s +; +; +MSGID_REQ_OK (//) + _Ok +; +; +MSGID_TEXTLINE_PATH (//) +Path: \"%s\" +; +; +MSGID_BUTTON_SKIP (//) +_Skip +; +; +MSGID_PATHOF_NAME (//) +Path of object.\n\n\ +It's possible to show all content of this gadget using\n\ +the scroller located at the bottom of the window.\n\ +Can be usefull for large path lenght. +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE (5000//) +Rename.module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD (//) +Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +; +;----------------------------------------------------------- +; diff --git a/scalos/Modules/Rename.MUI/Rename.h b/scalos/Modules/Rename.MUI/Rename.h new file mode 100755 index 000000000..4094cee5b --- /dev/null +++ b/scalos/Modules/Rename.MUI/Rename.h @@ -0,0 +1,32 @@ +// Rename.h +// $Date$ +// $Revision$ + + +#ifndef RENAME_H +#define RENAME_H + +#define d1(x) ; +#define d2(x) x; + +#define debugLock_d1(LockName) ; +#define debugLock_d2(LockName) \ + {\ + char xxName[200];\ + strcpy(xxName, "");\ + NameFromLock((LockName), xxName, sizeof(xxName));\ + kprintf(__FILE__ "/%s/%ld: " #LockName "=%08lx <%s>\n", __FUNC__, __LINE__, LockName, xxName);\ + } + + +extern int kprintf(CONST_STRPTR, ...); +extern int KPrintF(CONST_STRPTR, ...); + +struct Rename_LocaleInfo +{ + APTR li_LocaleBase; + APTR li_Catalog; + struct LocaleIFace *li_ILocale; +}; + +#endif /* RENAME_H */ diff --git a/scalos/Modules/Rename.MUI/config.mk b/scalos/Modules/Rename.MUI/config.mk new file mode 100755 index 000000000..28403155a --- /dev/null +++ b/scalos/Modules/Rename.MUI/config.mk @@ -0,0 +1,60 @@ +# $Date: 2011-07-16 19:22:18 +0200 (Sa, 16. Jul 2011) $ +# $Revision: 786 $ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +SCALOS_LOCALE = $(OBJDIR)/Rename_Locale.h + +CFLAGS += -D SCALOSLOCALE=$(SCALOS_LOCALE) + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +INCLUDES += # + +LFLAGS += # + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +INCLUDES += # + +LFLAGS += # + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +INCLUDES += # + +LFLAGS += -lmui + + +else + +############################################################################### +# AmigaOS + +INCLUDES += # + +LFLAGS += # + +endif +endif +endif diff --git a/scalos/Modules/Rename.MUI/makefile b/scalos/Modules/Rename.MUI/makefile new file mode 100755 index 000000000..d476581b6 --- /dev/null +++ b/scalos/Modules/Rename.MUI/makefile @@ -0,0 +1,123 @@ +# Makefile for Rename.module (MUI) +# using GNU make and SAS/C +# $Date$ +# $Revision$ +##################################################################### + +TOPLEVEL = / +SUBDIRMAKE = $(MAKE) -s -C +CHEADERS = +CC = sc +CFLAGS = optimize nostackcheck nochkabort debug=s \ + idlen=128 strmer nover streq data=far \ + define SCALOSLOCALE=$(SCALOS_LOCALE) \ + ignore=217 idir=sc:include/ \ + idir=include: idir=//include +AS = phxass +AFLAGS = QUIET m=68020 linedebug opt=NRQB i=include: +LD = slink +LNFLAGS = quiet batch noicons stripdebug +LNDBFLAGS = quiet batch noicons addsym +LIBS = LIB:sc.lib LIB:debug.lib LIB:amiga.lib +CATCOMP = catcomp +FLEXCAT = FlexCat +CSTARTUP = LIB:c.o +OBJDIR = .sasobj + +SCALOS_LOCALE = $(OBJDIR)/Rename_Locale.h + +##################################################################### + +.SUFFIXES: .asm + +##################################################################### + +NAME = .bin_os3/Rename.module +DBGNAME = $(NAME).debug +CATCOMPH = $(SCALOS_LOCALE) +CAT_FILE = Scalos/Rename.catalog +DESTCAT = Locale:Catalogs +ALLCATS = Catalogs/deutsch/$(CAT_FILE) \ + Catalogs/français/$(CAT_FILE) + +##################################################################### + +all: $(NAME) \ + $(DBGNAME) \ + allcatalogs +# install +# clean + +##################################################################### + +# make all Scalos .catalogs +allcatalogs: + @$(SUBDIRMAKE) Catalogs/deutsch/Scalos + @$(SUBDIRMAKE) Catalogs/français/Scalos + +##################################################################### + +CSRCS = Rename.c + +##################################################################### + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +##################################################################### + +XOBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(CSRCS:%.c=$(OBJDIR)/%.o) +OBJS = $(XOBJS) + +##################################################################### + +$(NAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNFLAGS) + +$(DBGNAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNDBFLAGS) + +##################################################################### + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $< objectname $@ + +$(OBJDIR)/%.o : %.asm + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +##################################################################### + +$(CATCOMPH) : Rename.cd + @printf '\033[32mMake CatComp header: \033[31m\033[1m$(CATCOMPH) \033[32mfrom \033[31m$<\033[0m\n' + @$(FLEXCAT) $< $@=$(TOPLEVEL)/CatComp_h.sd + +$(OBJDIR)/Rename.o : Rename.c Rename.h $(CATCOMPH) + +##################################################################### + +$(NAME) $(DBGNAME) : $(OBJS) + +##################################################################### + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(NAME) \033[0mto \033[31m\033[1mScalos:modules/ \033[0m\n' + @copy $(NAME) Scalos:modules/ + @avail flush + @printf '\033[32mInstall: \033[31m\033[1m$(CAT_FILE)\033[0m\n' + -@copy "catalogs/deutsch/$(CAT_FILE)" "$(DESTCAT)/Deutsch/Scalos/" clone + -@copy "catalogs/français/$(CAT_FILE)" "$(DESTCAT)/français/Scalos/" clone + +##################################################################### + +# A little something to clean it all up +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + -@delete $(XOBJS) $(NAME) $(DBGNAME) \ + $(CATCOMPH) + @printf '\033[0m' + +##################################################################### diff --git a/scalos/Modules/Rename.MUI/makefile-new b/scalos/Modules/Rename.MUI/makefile-new new file mode 100755 index 000000000..35e03a473 --- /dev/null +++ b/scalos/Modules/Rename.MUI/makefile-new @@ -0,0 +1,95 @@ +# $Date: 2011-07-16 19:22:18 +0200 (Sa, 16. Jul 2011) $ +# $Revision: 786 $ +############################################################# +TOPLEVEL = $(shell pwd)/../.. + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + SDPATH=/ +else + SDPATH=../.. +endif + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(OBJDIR)/Rename.o \ + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Subdirs +# + +SUBDIRS = $(filter-out Catalogs/sample/Scalos, $(wildcard Catalogs/*/Scalos)) + +############################################################################## +# +# Targets +# + +NAME = Rename.module +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) \ + all_subdirs + +############################################################################## + +$(OBJDIR)/%.o: $(TOOLTYPE_DIR)/%.c + $(run-cc) + +$(OBJDIR)/%.o: $(ICONOBJMCC_DIR)/%.c + $(run-cc) + +Rename.c : $(OBJDIR)/Rename_Locale.h + +$(OBJDIR)/Rename_Locale.h : Rename.cd + @$(ECHO) "FlexCat $@" + $(FLEXCAT) $< $@=$(SDPATH)/CatComp_h.sd + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + @$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) +ifneq ($(MACHINE), ppc-amigaos) + @-chmod u+x $@ +endif + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) Scalos:modules/ clone + +install: install_subdirs + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* \ + $(OBJDIR)/Rename_Locale.h + +clean: clean_subdirs + +############################################################################## + diff --git a/scalos/Modules/Rename.Reaction/RENStrings.asm b/scalos/Modules/Rename.Reaction/RENStrings.asm new file mode 100644 index 000000000..1bb1f2692 --- /dev/null +++ b/scalos/Modules/Rename.Reaction/RENStrings.asm @@ -0,0 +1,11 @@ +; RENStrings.asm +; 10 Aug 2001 18:58:56 + +CATCOMP_NUMBERS: equ 1 +CATCOMP_STRINGS: equ 1 + + section tpStrings,DATA + + include "RenameStrings.i" + + end diff --git a/scalos/Modules/Rename.Reaction/Rename.c b/scalos/Modules/Rename.Reaction/Rename.c new file mode 100644 index 000000000..2b511200e --- /dev/null +++ b/scalos/Modules/Rename.Reaction/Rename.c @@ -0,0 +1,497 @@ +// Rename.c +// 09 Jan 2002 16:56:12 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "RenameGUI.h" + +#define CATCOMP_NUMBERS +#define CATCOMP_STRINGS +#include "RenameStrings.h" + + +#define d1(x) ; +#define d2(x) x; + +#define CATSTR(id) GetCatalogStr(gb_Catalog, id, (STRPTR) id ## _STR) +#define CATSTRSTR(id,str) GetCatalogStr(gb_Catalog, id, (STRPTR) str) + + +extern int kprintf(CONST_STRPTR, ...); + +static BOOL OpenLibraries(void); +static void CloseLibraries(void); +static ULONG MessageLoop(struct WBArg *ArgList, LONG *n); +static void UpdateGadgets(struct WBArg *arg); +static void ReportError(LONG Result, CONST_STRPTR OldObjName, CONST_STRPTR NewObjName); +static LONG RenameObject(struct WBArg *arg); +ULONG RefreshSetGadgetAttrsA(struct Gadget *g, struct Window *w, struct Requester *r, struct TagItem *tags); +ULONG RefreshSetGadgetAttrs(struct Gadget *g, struct Window *w, struct Requester *r, Tag tag1, ...); +void StripTrailingColon(STRPTR Line); + + +#define PROGNAME "Rename.module" +#define VERSIONR "1.3" +#define PROGDATE "09 Jan 2002 16:56:28" +#define COPYRIGT "Copyright © Jürgen Lachmann" + +CONST_STRPTR version = "\0$VER: " PROGNAME " " VERSIONR " (" PROGDATE ") - " COPYRIGT "\n"; + + +struct Library *ResourceBase; +struct IntuitionBase *IntuitionBase; +struct Library *GadToolsBase; +struct Library *LocaleBase; +struct Library *UtilityBase; + +static struct Screen *gb_Screen; +static struct Window *gb_Window; +static struct Gadget **gb_Gadgets; +static struct Catalog *gb_Catalog; +static struct MsgPort *gb_IDCMPort; +static struct MsgPort *gb_AppPort; +static Object *gb_WindowObj; +RESOURCEFILE gb_Resource; + + +static BOOL RenameVolume = FALSE; + + +main() +{ +#if 0 + if (WBenchMsg) + { + LONG n; + + kprintf("NumArgs=%ld\n", WBenchMsg->sm_NumArgs); + + for (n=0; nsm_NumArgs; n++) + { + char xName[512]; + + NameFromLock(WBenchMsg->sm_ArgList[n].wa_Lock, xName, sizeof(xName)); + + kprintf("%ld. Lock=<%s> Name=<%s>\n", n, xName, WBenchMsg->sm_ArgList[n].wa_Name); + } + } +#endif + + if (NULL == WBenchMsg) + { + return 5; + } + if (WBenchMsg->sm_NumArgs < 2) + { + return 5; + } + + do { + LONG Result; + LONG n; + + if (!OpenLibraries()) + break; + + gb_Catalog = OpenCatalogA(NULL, PROGNAME ".catalog",NULL); + + gb_Screen = LockPubScreen(NULL); + if (NULL == gb_Screen) + break; + + gb_IDCMPort = CreateMsgPort(); + if (NULL == gb_IDCMPort) + break; + + gb_AppPort = CreateMsgPort(); + if (NULL == gb_AppPort) + break; + + gb_Resource = RL_OpenResource(RCTResource, gb_Screen, gb_Catalog); + + gb_WindowObj = RL_NewObject(gb_Resource, WIN_Rename_ID, + WINDOW_SharedPort, gb_IDCMPort, + WINDOW_AppPort, gb_AppPort, + TAG_DONE); + if (NULL == gb_WindowObj) + break; + + gb_Gadgets = (struct Gadget **) RL_GetObjectArray(gb_Resource, gb_WindowObj, GROUP_Rename_ID); + if (NULL == gb_Gadgets) + break; + + UpdateGadgets(&WBenchMsg->sm_ArgList[1]); + + gb_Window = RA_OpenWindow(gb_WindowObj); + if (NULL == gb_Window) + break; + + n = 1; + do { + Result = MessageLoop(WBenchMsg->sm_ArgList, &n); + } while (n < WBenchMsg->sm_NumArgs && RETURN_OK == Result); + } while (0); + + if (gb_WindowObj) + DoMethod(gb_WindowObj, WM_CLOSE); + if (gb_Resource) + RL_CloseResource(gb_Resource); + if(gb_Catalog) + CloseCatalog(gb_Catalog); + if (gb_AppPort) + DeleteMsgPort(gb_AppPort); + if (gb_IDCMPort) + DeleteMsgPort(gb_IDCMPort); + if (gb_Screen) + UnlockPubScreen(NULL, gb_Screen); + + CloseLibraries(); +} + + +static BOOL OpenLibraries(void) +{ + ResourceBase = OpenLibrary("resource.library", 44); + if (NULL == ResourceBase) + return FALSE; + + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + if (NULL == IntuitionBase) + return FALSE; + + GadToolsBase = OpenLibrary("gadtools.library", 38); + if (NULL == GadToolsBase) + return FALSE; + + LocaleBase = OpenLibrary("locale.library", 38); + if (NULL == LocaleBase) + return FALSE; + + UtilityBase = OpenLibrary("utility.library", 39); + if (NULL == UtilityBase) + return FALSE; + + return TRUE; +} + + +static void CloseLibraries(void) +{ + if (UtilityBase) + { + CloseLibrary(UtilityBase); + UtilityBase = NULL; + } + if (LocaleBase) + { + CloseLibrary(LocaleBase); + LocaleBase = NULL; + } + if (GadToolsBase) + { + CloseLibrary(GadToolsBase); + GadToolsBase = NULL; + } + if (IntuitionBase) + { + CloseLibrary((struct Library *)IntuitionBase); + IntuitionBase = NULL; + } + if (ResourceBase) + { + CloseLibrary(ResourceBase); + ResourceBase = NULL; + } +} + + +static ULONG MessageLoop(struct WBArg *ArgList, LONG *n) +{ + ULONG res = RETURN_FAIL; + ULONG windowsignal, signals; + + UpdateGadgets(&ArgList[*n]); + + GetAttr(WINDOW_SigMask, gb_WindowObj, &windowsignal); + + while (res == RETURN_FAIL) + { + ActivateGadget(gb_Gadgets[String_NewName], gb_Window, NULL); + + signals = Wait(windowsignal); + + if (signals & windowsignal) + { + ULONG result; + WORD code; + + while ((result = RA_HandleInput(gb_WindowObj, &code)) != WMHI_LASTMSG) + { + d1(kprintf("result=%08lx code=%04lx\n", result, code)); + + switch (result & WMHI_CLASSMASK) + { + case WMHI_CLOSEWINDOW: + res = RETURN_OK; + break; + + case WMHI_GADGETUP: + { +// const UWORD groupid = RL_GROUPID(result); + const UWORD gadid = RL_GADGETID(result); + + switch (gadid) + { + case String_NewName: + d1(kprintf("WMHI_GADGETUP code=%04lx\n", code)); + if (0 == code) + RenameObject(&ArgList[*n]); + res = RETURN_OK; + (*n)++; + break; + + case OkButton: + RenameObject(&ArgList[*n]); + res = RETURN_OK; + (*n)++; + break; + + case SkipButton: + (*n)++; + res = RETURN_OK; + break; + + case Cancelbutton: + res = RETURN_ERROR; + break; + + default: + break; + } + } + break; + } + } + } + } + + return( res ); +} + + +static void UpdateGadgets(struct WBArg *arg) +{ + static char LabelText[1024]; + static char PathText[1024]; + STRPTR FileName; + ULONG Mark; + char xName[512]; + + NameFromLock(arg->wa_Lock, xName, sizeof(xName)); + + if (arg->wa_Name && strlen(arg->wa_Name) > 0) + FileName = arg->wa_Name; + else + FileName = FilePart(xName); + + d1(kprintf("xName=<%s> wa_Name=%08lx <%s>\n", xName, arg->wa_Name, arg->wa_Name ? arg->wa_Name : "")); + + if (':' == xName[strlen(xName)-1]) + { + sprintf(PathText, CATSTR(MSGID_TEXTLINE_PATH), xName); + + StripTrailingColon(xName); + + FileName = xName; + + RenameVolume = TRUE; + } + else + { + STRPTR lp = PathPart(xName); + if (lp) + *lp = '\0'; + + sprintf(PathText, CATSTR(MSGID_TEXTLINE_PATH), xName); + } + + + sprintf(LabelText, CATSTR(MSGID_TEXTLINE_ENTERNEWNAME), FileName); + + Mark = (0 << 16) + strlen(FileName); + + RefreshSetGadgetAttrs(gb_Gadgets[String_NewName], gb_Window, NULL, + STRINGA_TextVal, FileName, + TAG_END); + + RefreshSetGadgetAttrs(gb_Gadgets[String_NewName], gb_Window, NULL, + STRINGA_Mark, Mark, + TAG_END); + + RefreshSetGadgetAttrs(gb_Gadgets[TextLine_EnterName], gb_Window, NULL, + GA_Text, LabelText, + TAG_END); + RefreshSetGadgetAttrs(gb_Gadgets[TextLine_Path], gb_Window, NULL, + GA_Text, PathText, + TAG_END); +} + + +static void ReportError(LONG Result, CONST_STRPTR OldObjName, CONST_STRPTR NewObjName) +{ + char FaultText[256]; + struct EasyStruct ezStruct; + + Fault(Result, "", FaultText, sizeof(FaultText)); + + ezStruct.es_StructSize = sizeof(struct EasyStruct); + ezStruct.es_Flags = 0; + ezStruct.es_Title = CATSTR(MSGID_TITLE_ERRORREQ); + ezStruct.es_TextFormat = CATSTR(MSGID_ERRORREQ_BODYTEXT); + ezStruct.es_GadgetFormat = CATSTR(MSGID_REQ_OK); + + EasyRequest(gb_Window, &ezStruct, NULL, + OldObjName, NewObjName, FaultText); +} + + +static LONG RenameObject(struct WBArg *arg) +{ + BPTR dirLock; + LONG Result = RETURN_OK; + STRPTR NewObjName = NULL; + STRPTR OldObjName; + char ObjName[512]; + BPTR oldDir; + + NameFromLock(arg->wa_Lock, ObjName, sizeof(ObjName)); + + GetAttr(STRINGA_TextVal, gb_Gadgets[String_NewName], (ULONG *) &NewObjName); + + if (arg->wa_Name && strlen(arg->wa_Name) > 0) + { + OldObjName = arg->wa_Name; + dirLock = DupLock(arg->wa_Lock); + } + else + { + OldObjName = FilePart(ObjName); + dirLock = ParentDir(arg->wa_Lock); + } + + oldDir = CurrentDir(dirLock); + + if (dirLock && NewObjName && strlen(NewObjName) > 0) + { + if (RenameVolume) + { + StripTrailingColon(OldObjName); + StripTrailingColon(NewObjName); + + if (!Relabel(OldObjName, NewObjName)) + Result = IoErr(); + } + else + { + if (!Rename(OldObjName, NewObjName)) + Result = IoErr(); + } + + if (RETURN_OK != Result) + ReportError(Result, OldObjName, NewObjName); + else + { + // try to rename associated icon + char OldIconName[512]; + char NewIconName[512]; + + stccpy(OldIconName, OldObjName, sizeof(OldIconName) - 5); + strcat(OldIconName, ".info"); + + stccpy(NewIconName, NewObjName, sizeof(NewIconName) - 5); + strcat(NewIconName, ".info"); + + if (!Rename(OldIconName, NewIconName)) + Result = IoErr(); + + if (ERROR_OBJECT_NOT_FOUND == Result) + Result = RETURN_OK; + + if (RETURN_OK != Result) + ReportError(Result, OldIconName, NewIconName); + } + } + + CurrentDir(oldDir); + + UnLock(dirLock); + + return Result; +} + + +ULONG RefreshSetGadgetAttrsA(struct Gadget *g, struct Window *w, struct Requester *r, struct TagItem *tags) +{ + ULONG retval; + BOOL changedisabled = FALSE; + BOOL disabled = FALSE; + + if (w) + { + if (FindTagItem(GA_Disabled,tags)) + { + changedisabled = TRUE; + disabled = g->Flags & GFLG_DISABLED; + } + } + retval = SetGadgetAttrsA(g,w,r,tags); + if (w && (retval || (changedisabled && disabled != (g->Flags & GFLG_DISABLED)))) + { + RefreshGList(g,w,r,1); + retval = 1; + } + return retval; +} + + +ULONG RefreshSetGadgetAttrs(struct Gadget *g, struct Window *w, struct Requester *r, Tag tag1, ...) +{ + return RefreshSetGadgetAttrsA(g,w,r,(struct TagItem *) &tag1); +} + + +void StripTrailingColon(STRPTR Line) +{ + size_t Len = strlen(Line); + + Line += Len - 1; + + if (':' == *Line) + *Line = '\0'; +} + + diff --git a/scalos/Modules/Rename.Reaction/RenameGUI.cd b/scalos/Modules/Rename.Reaction/RenameGUI.cd new file mode 100755 index 000000000..c9ed9c9e6 --- /dev/null +++ b/scalos/Modules/Rename.Reaction/RenameGUI.cd @@ -0,0 +1,35 @@ +; *** catalog description file of "RenameGUI.res" +; +MSGID_WINTITLE_RENAME (256//) +Rename +; +MSGID_TEXTLINE_ENTERNEWNAME (257//) +Enter a new Name for '%s' +; +MSGID_NEWNAME_DEFAULT (258//) +New_Object_Name +; +MSGID_LABEL_NEWNAME (259//) +New Name +; +MSGID_BUTTON_OK (261//) +_Ok +; +MSGID_BUTTON_CANCEL (262//) +_Cancel +; +MSGID_TITLE_ERRORREQ (263//) +Rename Error +; +MSGID_ERRORREQ_BODYTEXT (264//) +Could not rename\n'%s' to '%s'\n%s +; +MSGID_REQ_OK (265//) + _Ok +; +MSGID_TEXTLINE_PATH (266//) +Path: '%s' +; +MSGID_BUTTON_SKIP (267//) +_Skip +; diff --git a/scalos/Modules/Rename.Reaction/RenameGUI.h b/scalos/Modules/Rename.Reaction/RenameGUI.h new file mode 100755 index 000000000..6eed923bf --- /dev/null +++ b/scalos/Modules/Rename.Reaction/RenameGUI.h @@ -0,0 +1,12 @@ +/* header file of "RenameGUI.res" */ +extern char RCTResource[]; +#define WIN_Rename_ID 1 +#define GROUP_Rename_ID 2 +#define TextLine_EnterName 15 +#define TextLine_Path 18 +#define String_NewName 11 +#define Label_NewName 10 +#define OkButton 5 +#define SkipButton 19 +#define Cancelbutton 6 +#define REQ_ReportError_ID 3 diff --git a/scalos/Modules/Rename.Reaction/RenameGUI.res b/scalos/Modules/Rename.Reaction/RenameGUI.res new file mode 100755 index 0000000000000000000000000000000000000000..ec607e5842b7aa2f31b241f2c8497793cef1b318 GIT binary patch literal 3026 zcwV(uy>Ht_6hD30mMmMbmDc^pz@bi%4E_Ux43WjFESMq{iiX>Xp(MtUt&lQB*X`z{ z35rf#I(EsP(L)oUDB7VYf&c}Ijv4bOWN+U)-ci)qL=>bsNO3+I|0vsD#@OT8hl!mv z5j$x7kXSDiTaT~BJNtPhdy~!BXw=k(&|`9hR2rtS)1J;r7XBAe2KL%Q9{x*1=Ntbh z-00mM4EtkJ-_lSVa{F_cJIIphYzmD%r@!ZhgvCfkk-ZF`tta@)3H}q#i@|qhjp^wn zt|wxdH71fG&pk-dKt?A%pS=XSYPnyB+Q4&d>VSV2q59Y0X6tdFmt#-~vwTJ#G`YwFadxX5wBbU(*&=Nu!QvA84*H84hum0+!i@37h8Xv zCbZdlv(->1=wTmhX-?N2Ccu-Dzmfox9lla6fOj#P22I)$xX)9X}2(YYB<4SCU< zh?w66>C}Kb-eI(EF>2CV9WI?MYNr_JDy%_YHu8gz27w<$&6(WIR08+#$Q?tM5Vx!l z1!b>AB!M%$UwI`e<#Lo4w2oz*DaKORy_KU*P+=}%evyBPS*uG;(=b61#OGrzj6|vX yN5j72`Joap{Sto2mC$D&^wK(pwH8?tHtbD9{SrU$Xl7xOr&hCrT|A+xQU4EPn!@V< literal 0 HcwPel00001 diff --git a/scalos/Modules/Rename.Reaction/RenameStrings.h b/scalos/Modules/Rename.Reaction/RenameStrings.h new file mode 100755 index 000000000..be5af3241 --- /dev/null +++ b/scalos/Modules/Rename.Reaction/RenameStrings.h @@ -0,0 +1,144 @@ +#ifndef RENAMESTRINGS_H +#define RENAMESTRINGS_H + + +/****************************************************************************/ + + +/* This file was created automatically by CatComp. + * Do NOT edit by hand! + */ + + +#ifndef EXEC_TYPES_H +#include +#endif + +#ifdef CATCOMP_ARRAY +#undef CATCOMP_NUMBERS +#undef CATCOMP_STRINGS +#define CATCOMP_NUMBERS +#define CATCOMP_STRINGS +#endif + +#ifdef CATCOMP_BLOCK +#undef CATCOMP_STRINGS +#define CATCOMP_STRINGS +#endif + + +/****************************************************************************/ + + +#ifdef CATCOMP_NUMBERS + +#define MSGID_WINTITLE_RENAME 256 +#define MSGID_TEXTLINE_ENTERNEWNAME 257 +#define MSGID_NEWNAME_DEFAULT 258 +#define MSGID_LABEL_NEWNAME 259 +#define MSGID_BUTTON_OK 261 +#define MSGID_BUTTON_CANCEL 262 +#define MSGID_TITLE_ERRORREQ 263 +#define MSGID_ERRORREQ_BODYTEXT 264 +#define MSGID_REQ_OK 265 +#define MSGID_TEXTLINE_PATH 266 +#define MSGID_BUTTON_SKIP 267 + +#endif /* CATCOMP_NUMBERS */ + + +/****************************************************************************/ + + +#ifdef CATCOMP_STRINGS + +#define MSGID_WINTITLE_RENAME_STR "Rename" +#define MSGID_TEXTLINE_ENTERNEWNAME_STR "Enter a new Name for '%s'" +#define MSGID_NEWNAME_DEFAULT_STR "New_Object_Name" +#define MSGID_LABEL_NEWNAME_STR "New Name" +#define MSGID_BUTTON_OK_STR "_Ok" +#define MSGID_BUTTON_CANCEL_STR "_Cancel" +#define MSGID_TITLE_ERRORREQ_STR "Rename Error" +#define MSGID_ERRORREQ_BODYTEXT_STR "Could not rename\n'%s' to '%s'\n%s" +#define MSGID_REQ_OK_STR " _Ok" +#define MSGID_TEXTLINE_PATH_STR "Path: '%s'" +#define MSGID_BUTTON_SKIP_STR "_Skip" + +#endif /* CATCOMP_STRINGS */ + + +/****************************************************************************/ + + +#ifdef CATCOMP_ARRAY + +struct CatCompArrayType +{ + LONG cca_ID; + STRPTR cca_Str; +}; + +static const struct CatCompArrayType CatCompArray[] = +{ + {MSGID_WINTITLE_RENAME,(STRPTR)MSGID_WINTITLE_RENAME_STR}, + {MSGID_TEXTLINE_ENTERNEWNAME,(STRPTR)MSGID_TEXTLINE_ENTERNEWNAME_STR}, + {MSGID_NEWNAME_DEFAULT,(STRPTR)MSGID_NEWNAME_DEFAULT_STR}, + {MSGID_LABEL_NEWNAME,(STRPTR)MSGID_LABEL_NEWNAME_STR}, + {MSGID_BUTTON_OK,(STRPTR)MSGID_BUTTON_OK_STR}, + {MSGID_BUTTON_CANCEL,(STRPTR)MSGID_BUTTON_CANCEL_STR}, + {MSGID_TITLE_ERRORREQ,(STRPTR)MSGID_TITLE_ERRORREQ_STR}, + {MSGID_ERRORREQ_BODYTEXT,(STRPTR)MSGID_ERRORREQ_BODYTEXT_STR}, + {MSGID_REQ_OK,(STRPTR)MSGID_REQ_OK_STR}, + {MSGID_TEXTLINE_PATH,(STRPTR)MSGID_TEXTLINE_PATH_STR}, + {MSGID_BUTTON_SKIP,(STRPTR)MSGID_BUTTON_SKIP_STR}, +}; + +#endif /* CATCOMP_ARRAY */ + + +/****************************************************************************/ + + +#ifdef CATCOMP_BLOCK + +static const char CatCompBlock[] = +{ + "\x00\x00\x01\x00\x00\x08" + MSGID_WINTITLE_RENAME_STR "\x00\x00" + "\x00\x00\x01\x01\x00\x1A" + MSGID_TEXTLINE_ENTERNEWNAME_STR "\x00" + "\x00\x00\x01\x02\x00\x10" + MSGID_NEWNAME_DEFAULT_STR "\x00" + "\x00\x00\x01\x03\x00\x0A" + MSGID_LABEL_NEWNAME_STR "\x00\x00" + "\x00\x00\x01\x05\x00\x04" + MSGID_BUTTON_OK_STR "\x00" + "\x00\x00\x01\x06\x00\x08" + MSGID_BUTTON_CANCEL_STR "\x00" + "\x00\x00\x01\x07\x00\x0E" + MSGID_TITLE_ERRORREQ_STR "\x00\x00" + "\x00\x00\x01\x08\x00\x22" + MSGID_ERRORREQ_BODYTEXT_STR "\x00\x00" + "\x00\x00\x01\x09\x00\x06" + MSGID_REQ_OK_STR "\x00\x00" + "\x00\x00\x01\x0A\x00\x0C" + MSGID_TEXTLINE_PATH_STR "\x00\x00" + "\x00\x00\x01\x0B\x00\x06" + MSGID_BUTTON_SKIP_STR "\x00" +}; + +#endif /* CATCOMP_BLOCK */ + + +/****************************************************************************/ + + +struct LocaleInfo +{ + APTR li_LocaleBase; + APTR li_Catalog; +}; + + + +#endif /* RENAMESTRINGS_H */ diff --git a/scalos/Modules/Rename.Reaction/RenameStrings.i b/scalos/Modules/Rename.Reaction/RenameStrings.i new file mode 100755 index 000000000..ba1b9d462 --- /dev/null +++ b/scalos/Modules/Rename.Reaction/RenameStrings.i @@ -0,0 +1,175 @@ + IFND RENAMESTRINGS_I +RENAMESTRINGS_I SET 1 + + +;----------------------------------------------------------------------------- + + +* This file was created automatically by CatComp. +* Do NOT edit by hand! +* + + + IFND EXEC_TYPES_I + INCLUDE 'exec/types.i' + ENDC + + IFD CATCOMP_ARRAY +CATCOMP_NUMBERS SET 1 +CATCOMP_STRINGS SET 1 + ENDC + + IFD CATCOMP_CODE +CATCOMP_BLOCK SET 1 + ENDC + + +;----------------------------------------------------------------------------- + + + IFD CATCOMP_NUMBERS + + XDEF MSGID_WINTITLE_RENAME +MSGID_WINTITLE_RENAME EQU 256 + XDEF MSGID_TEXTLINE_ENTERNEWNAME +MSGID_TEXTLINE_ENTERNEWNAME EQU 257 + XDEF MSGID_NEWNAME_DEFAULT +MSGID_NEWNAME_DEFAULT EQU 258 + XDEF MSGID_LABEL_NEWNAME +MSGID_LABEL_NEWNAME EQU 259 + XDEF MSGID_BUTTON_OK +MSGID_BUTTON_OK EQU 261 + XDEF MSGID_BUTTON_CANCEL +MSGID_BUTTON_CANCEL EQU 262 + XDEF MSGID_TITLE_ERRORREQ +MSGID_TITLE_ERRORREQ EQU 263 + XDEF MSGID_ERRORREQ_BODYTEXT +MSGID_ERRORREQ_BODYTEXT EQU 264 + XDEF MSGID_REQ_OK +MSGID_REQ_OK EQU 265 + XDEF MSGID_TEXTLINE_PATH +MSGID_TEXTLINE_PATH EQU 266 + XDEF MSGID_BUTTON_SKIP +MSGID_BUTTON_SKIP EQU 267 + + ENDC ; CATCOMP_NUMBERS + + +;----------------------------------------------------------------------------- + + + IFD CATCOMP_STRINGS + + XDEF MSGID_WINTITLE_RENAME_STR +MSGID_WINTITLE_RENAME_STR: DC.B 'Rename',$00 + XDEF MSGID_TEXTLINE_ENTERNEWNAME_STR +MSGID_TEXTLINE_ENTERNEWNAME_STR: DC.B 'Enter a new Name for ',39,'%s',39,$00 + XDEF MSGID_NEWNAME_DEFAULT_STR +MSGID_NEWNAME_DEFAULT_STR: DC.B 'New_Object_Name',$00 + XDEF MSGID_LABEL_NEWNAME_STR +MSGID_LABEL_NEWNAME_STR: DC.B 'New Name',$00 + XDEF MSGID_BUTTON_OK_STR +MSGID_BUTTON_OK_STR: DC.B '_Ok',$00 + XDEF MSGID_BUTTON_CANCEL_STR +MSGID_BUTTON_CANCEL_STR: DC.B '_Cancel',$00 + XDEF MSGID_TITLE_ERRORREQ_STR +MSGID_TITLE_ERRORREQ_STR: DC.B 'Rename Error',$00 + XDEF MSGID_ERRORREQ_BODYTEXT_STR +MSGID_ERRORREQ_BODYTEXT_STR: DC.B 'Could not rename',10,39,'%s',39,' to ',39,'%s',39,10,'%s',$00 + XDEF MSGID_REQ_OK_STR +MSGID_REQ_OK_STR: DC.B ' _Ok',$00 + XDEF MSGID_TEXTLINE_PATH_STR +MSGID_TEXTLINE_PATH_STR: DC.B 'Path: ',39,'%s',39,$00 + XDEF MSGID_BUTTON_SKIP_STR +MSGID_BUTTON_SKIP_STR: DC.B '_Skip',$00 + + ENDC ; CATCOMP_STRINGS + + +;----------------------------------------------------------------------------- + + + IFD CATCOMP_ARRAY + + STRUCTURE CatCompArrayType,0 + LONG cca_ID + APTR cca_Str + LABEL CatCompArrayType_SIZEOF + + CNOP 0,4 + + XDEF CatCompArray +CatCompArray: + XDEF _CatCompArray +_CatCompArray: +AS0: DC.L MSGID_WINTITLE_RENAME,MSGID_WINTITLE_RENAME_STR +AS1: DC.L MSGID_TEXTLINE_ENTERNEWNAME,MSGID_TEXTLINE_ENTERNEWNAME_STR +AS2: DC.L MSGID_NEWNAME_DEFAULT,MSGID_NEWNAME_DEFAULT_STR +AS3: DC.L MSGID_LABEL_NEWNAME,MSGID_LABEL_NEWNAME_STR +AS4: DC.L MSGID_BUTTON_OK,MSGID_BUTTON_OK_STR +AS5: DC.L MSGID_BUTTON_CANCEL,MSGID_BUTTON_CANCEL_STR +AS6: DC.L MSGID_TITLE_ERRORREQ,MSGID_TITLE_ERRORREQ_STR +AS7: DC.L MSGID_ERRORREQ_BODYTEXT,MSGID_ERRORREQ_BODYTEXT_STR +AS8: DC.L MSGID_REQ_OK,MSGID_REQ_OK_STR +AS9: DC.L MSGID_TEXTLINE_PATH,MSGID_TEXTLINE_PATH_STR +AS10: DC.L MSGID_BUTTON_SKIP,MSGID_BUTTON_SKIP_STR + + ENDC ; CATCOMP_ARRAY + + +;----------------------------------------------------------------------------- + + + IFD CATCOMP_BLOCK + + XDEF CatCompBlock +CatCompBlock: + XDEF _CatCompBlock +_CatCompBlock: + DC.L $100 + DC.W $8 + DC.B 'Rename',$00,$00 + DC.L $101 + DC.W $1A + DC.B 'Enter a new Name for ',39,'%s',39,$00 + DC.L $102 + DC.W $10 + DC.B 'New_Object_Name',$00 + DC.L $103 + DC.W $A + DC.B 'New Name',$00,$00 + DC.L $105 + DC.W $4 + DC.B '_Ok',$00 + DC.L $106 + DC.W $8 + DC.B '_Cancel',$00 + DC.L $107 + DC.W $E + DC.B 'Rename Error',$00,$00 + DC.L $108 + DC.W $22 + DC.B 'Could not rename',10,39,'%s',39,' to ',39,'%s',39,10,'%s',$00,$00 + DC.L $109 + DC.W $6 + DC.B ' _Ok',$00,$00 + DC.L $10A + DC.W $C + DC.B 'Path: ',39,'%s',39,$00,$00 + DC.L $10B + DC.W $6 + DC.B '_Skip',$00 + + ENDC ; CATCOMP_BLOCK + + +;----------------------------------------------------------------------------- + + + STRUCTURE LocaleInfo,0 + APTR li_LocaleBase + APTR li_Catalog + LABEL LocaleInfo_SIZEOF + + + ENDC ; RENAMESTRINGS_I diff --git a/scalos/Modules/Rename.Reaction/makefile b/scalos/Modules/Rename.Reaction/makefile new file mode 100644 index 000000000..715416da8 --- /dev/null +++ b/scalos/Modules/Rename.Reaction/makefile @@ -0,0 +1,106 @@ +# Makefile for Rename.module (Reaction) +# using GNU make and SAS/C +# $Date$ + +##################################################################### + +CHEADERS = +CC = sc +CFLAGS = optimize nostackcheck nochkabort debug=s \ + idlen=128 strmer nover streq data=far \ + idir=sc:include/ \ + idir=include: idir=//include +AS = phxass +AFLAGS = QUIET m=68020 linedebug opt=NRQB i=include: +LD = slink +LNFLAGS = quiet batch noicons stripdebug +LNDBFLAGS = quiet batch noicons addsym +LIBS = LIB:sc.lib LIB:debug.lib LIB:amiga.lib \ + LIB:reaction.lib +CATCOMP = catcomp +CSTARTUP = +OBJDIR = .sasobj + +##################################################################### + +.SUFFIXES: .asm + +##################################################################### + +NAME = Rename.module +DBGNAME = $(NAME).debug +CATCOMPI = RenameStrings.i +CATCOMPH = RenameStrings.h + +##################################################################### + +all: $(NAME) \ + $(DBGNAME) +# install +# clean + +##################################################################### + +ASRCS = RENStrings.asm +CSRCS = Rename.c + +##################################################################### + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +##################################################################### + +XOBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(CSRCS:%.c=$(OBJDIR)/%.o) +OBJS = $(XOBJS) RenameGUI.o + +##################################################################### + +$(NAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(OBJS) TO $@ LIB $(LIBS) $(LNFLAGS) + +$(DBGNAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(OBJS) TO $@ LIB $(LIBS) $(LNDBFLAGS) + +##################################################################### + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $< objectname $@ + +$(OBJDIR)/%.o : %.asm + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +##################################################################### + +$(CATCOMPH) $(CATCOMPI) : RenameGUI.cd + @printf '\033[32mMake CatComp header: \033[31m\033[1m$(CATCOMPH) $@ \033[32mfrom \033[31m$<\033[0m\n' + @$(CATCOMP) $< cfile=$(CATCOMPH) asmfile=$@ NOCODE XDEF + +$(OBJDIR)/RENStrings.o : RenameStrings.i + +$(OBJDIR)/Rename.o : Rename.c RenameGUI.h RenameStrings.h + +##################################################################### + +$(NAME) $(DBGNAME) : $(OBJS) + +##################################################################### + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(NAME) \033[0mto \033[31m\033[1mScalos:modules/ \033[0m\n' + @copy $(NAME) Scalos:modules/ + +##################################################################### + +# A little something to clean it all up +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + @delete $(XOBJS) $(NAME) $(DBGNAME) \ + $(CATCOMPH) $(CATCOMPI) + @printf '\033[0m' + +##################################################################### diff --git a/scalos/Modules/SCOPTIONS b/scalos/Modules/SCOPTIONS new file mode 100755 index 000000000..fa820fb2e --- /dev/null +++ b/scalos/Modules/SCOPTIONS @@ -0,0 +1,19 @@ +PARAMETERS=REGISTERS +NOSTACKCHECK +STRINGMERGE +NOCHECKABORT +OPTIMIZE +OPTIMIZERINLINELOCAL +SMALLCODE +SMALLDATA +STRIPDEBUG +OPTIMIZERSCHEDULER +UTILITYLIBRARY +OPTIMIZERTIME +INCLUDEDIR=include: +INCLUDEDIR=MDEV:amiga/c-inc +INCLUDEDIR=MDEV:amiga/cgfx +GENPROTOFILE=cpublit_prototypes.h +LIBRARYFDFILE=cpublit_lib.fd +LIBRARYVERSION=1 +LIBRARYREVISION=0 diff --git a/scalos/Modules/Updater.MUI/Catalogs/deutsch/Scalos/Updater.ct b/scalos/Modules/Updater.MUI/Catalogs/deutsch/Scalos/Updater.ct new file mode 100644 index 000000000..8e3cd6eb7 --- /dev/null +++ b/scalos/Modules/Updater.MUI/Catalogs/deutsch/Scalos/Updater.ct @@ -0,0 +1,612 @@ +; Updater.ct +## version $VER: Updater.catalog 40.1 (05 Nov 20098 18:50:08) +## codeset 0 +## language deutsch +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Aktualisierer +;Scalos Updater +; +;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Projekt +;Project +; +; +MSGID_MENU_PROJECT_ABOUT +Über... +;About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Über MUI... +;About MUI... +; +; +MSGID_MENU_PROJECT_QUIT +Beenden +;Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +;Q +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +_OK +;_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Updater.module V%ld.%ld\033n\n\ +%s\n\ +© 2009%s Das Scalos Team +;\33c\033bScalos Updater.module V%ld.%ld\033n\n\ +;%s\n\ +;© 2009%s The Scalos Team +; +;----------------------------------------------------------- +; +MSGID_COMPONENTLIST_DIRECTORY +Verzeichnis +;Directory +; +; +MSGID_COMPONENTLIST_FILE +Dateiname +;Filename +; +; +MSGID_COMPONENTLIST_LATEST_VERSION +Neueste +;Latest +; +; +MSGID_COMPONENTLIST_INSTALLED_VERSION +Installiert +;Installed +; +; +MSGID_COMPONENTLIST_UPDATE +Akt. +;Update +; +;----------------------------------------------------------- +; +; +MSGID_BUTTON_CHECKFORUPDATES +Nach Updates suchen +;Check For Updates +; +; +MSGID_BUTTON_CHECKFORUPDATES_SHORT +U +;C +; +;+++translateme+++ +MSGID_BUTTON_CHECKFORUPDATES_HELP +...TBD... +;...TBD... +; +; +MSGID_BUTTON_STARTUPDATE +Update starten +;Begin Update +; +; +MSGID_BUTTON_STARTUPDATE_SHORT +S +;B +; +; +MSGID_BUTTON_STARTUPDATE_HELP +...TBD... +;...TBD... +; +; +MSGID_BUTTON_SELECT_ALL +Alles auswählen +;Select All +; +;+++translateme+++ +MSGID_BUTTON_SELECT_ALL_SHORT +A +;A +; +;+++translateme+++ +MSGID_BUTTON_SELECT_ALL_HELP +...TBD... +;...TBD... +; +; +MSGID_BUTTON_DESELECT_ALL +Alles abwählen +;Deselect All +; +; +MSGID_BUTTON_DESELECT_ALL_SHORT +W +;D +; +;+++translateme+++ +MSGID_BUTTON_DESELECT_ALL_HELP +...TBD... +;...TBD... +; +; +MSGID_TEXT_SELECTED_COUNT +%ld ausgewählt +;%ld Selected +; +; +MSGID_REGISTER_MAIN +Komponenten +;Main +; +; +MSGID_REGISTER_LOG +Protokoll +;Log +; +MSGID_REGISTER_CONFIGURATION +Einstellungen +;Configuration +; +; +MSGID_GROUP_PROXY +Proxy-Einstellungen +;Proxy Settings +; +; +MSGID_CHECK_USE_PROXY +Proxy verwenden? +;Use Proxy? +; +;+++translateme+++ +MSGID_CHECK_USE_PROXY_SHORTHELP +...TBD... +;...TBD... +; +; +MSGID_STRING_PROXY_ADDR +Adresse: +;Address: +; +;+++translateme+++ +MSGID_STRING_PROXY_ADDR_SHORTHELP +...TBD... +;...TBD... +; +; +MSGID_STRING_PROXY_PORT +Port: +;Port: +; +;+++translateme+++ +MSGID_STRING_PROXY_PORT_SHORTHELP +...TBD... +;...TBD... +; +; +MSGID_CHECK_USE_PROXYAUTH +Proxy braucht Benutzer und Passwort? +;Proxy requires authentication? +; +;+++translateme+++ +MSGID_CHECK_USE_PROXYAUTH_SHORTHELP +...TBD... +;...TBD... +; +; +MSGID_STRING_PROXY_USERNAME +Benutzername: +;User Name: +; +;+++translateme+++ +MSGID_STRING_PROXY_USERNAME_SHORTHELP +...TBD... +;...TBD... +; +; +MSGID_STRING_PROXY_PASSWD +Passwort: +;Password: +; +;+++translateme+++ +MSGID_STRING_PROXY_PASSWD_SHORTHELP +...TBD... +;...TBD... +; +; +MSGID_REQFORMAT_OPENSSL_ERROR +In der Funktion \033b%s\033n ist\n\ +der OpenSSL-Aufruf \033b%s\033n fehlgeschlagen:\n\ +%s +;In function \033b%s\033n,\n\ +;OpenSSL call \033b%s\033n failed:\n\ +;%s +; +; +MSGID_REQFORMAT_NO_UPDATES_FOUND +Keine Aktualisierungen für %s gefunden.\n\ +Sie haben bereits die aktuellsten\n\ +Scalos-Komponenten installiert. +;No Updates found for %s.\n\ +;You already have the most recent\n\ +;Scalos components installed. +; +; +MSGID_CHECK_SHOW_ALL_COMPONENTS +Auch aktuelle Komponenten zeigen? +;Show up-to-date components? +; +;+++translateme+++ +MSGID_CHECK_SHOW_ALL_COMPONENTS_SHORTHELP +...TBD... +;...TBD... +; +; +MSGID_CHECK_ASK_EVERY_UPDATE +Bei Aktualisierung jeder Komponente nachfragen? +;Ask about every component update? +; +;+++translateme+++ +MSGID_CHECK_ASK_EVERY_UPDATE_SHORTHELP +...TBD... +;...TBD... +; +; +MSGID_ABOUTREQ_YES_NO_ABORT +_Ja|_Nein|_Abbruch +;_Yes|_No|_Abort +; +; +MSGID_REQFORMAT_ASK_UPDATE +Möchten Sie wirklch die Scalos-Komponente \"%s\"\n\ +auf die Version %ld.%ld aktualisieren?\n\ +(Derzeit installiert: V%ld.%ld) +;Are you sure you want to update\n\ +;\"%s\" to version %ld.%ld\n\ +;(Installed Version: %ld.%ld) ? +; +; +MSGID_ERROR_DOWNLOADING_UPDATE +Fehler beim Herunterladen der Komponente \"%s\":\n\ +%s +;Error downloading update package \"%s\"\n\ +;%s +; +; +MSGID_REQ_CONTINUE_ABORT +_Weiter|_Abbruch +;_Continue|_Abort +; +; +MSGID_ERROR_LHA1 +Fehler beim AUspacken von \"%s\" mit LHA. +;Error: LHA failed to unpack \"%s\". +; +; +MSGID_ERROR_LHA2 +Fehler beim AUspacken der\n\ +Sprachkataloge für \"%s\". +;Error: LHA failed to unpack\n\ +;catalog files for \"%s\". +; +; +MSGID_ERROR_OPEN_LHAFILE +Fehler beim Anlegen des temporären\n\ +Archivs \"%s\" zur\n\ +Aktualisierung von \"%s\". +;Error: failed to open temporary\n\ +;archive \"%s\" for updating \"%s\". +; +; +MSGID_STRING_SCALOS_SERVER +Scalos Aktualisierungs-Server +;Scalos Update Server +; +;+++translateme+++ +MSGID_STRING_SCALOS_SERVER_SHORTHELP +...TBD... +;...TBD... +; +; +MSGID_REQ_INSTALL_UPDATES_GADGETS +_Aktualisieren|_Stop +;_Update|_Abort +; +; +MSGID_REQ_INSTALL_UPDATES +Sind Sie sicher, daß Sie jetzt %ld \n\ +Aktualisierungen für Scalos durchführen möchten? +;%ld Scalos updates now? +;Are you sure you want to install\n\ +;%ld Scalos updates now? +; +; +MSGID_GROUP_LOG +Aktualisierungsprotokoll +;Update Log +; +; +MSGID_POPASL_TEMPPATH +Pfad für temporäre Dateien +;Path for Temporary Files +; +; +MSGID_GROUP_MISCELLANEOUS +Verschiedenes +;Miscellaneous +; +; +MSGID_BUTTON_CLEAR_LOG +Protokoll löschen +;Clear Log +; +; +MSGID_BUTTON_CLEAR_LOG_SHORT +L +;C +; +;+++translateme+++ +MSGID_BUTTON_CLEAR_LOG_SHORTHELP +...TBD.. +;...TBD.. +; +; +MSGID_BUTTON_SAVE_LOG +Protokoll speichern... +;Save Log... +; +; +MSGID_BUTTON_SAVE_LOG_SHORT +S +;S +; +;+++translateme+++ +MSGID_BUTTON_SAVE_LOG_SHORTHELP +...TBD.. +;...TBD.. +; +; +MSGID_SAVE_LOG_ASLTITLE +Aktualisierungsprotokoll speichern... +;Save Update Log... +; +;----------------------------------------------------------- +; +; +MSG_PROGRESS_RESOLVING_NAME +Namen %s auflösen... +;Resolving name %s... +; +; +MSG_PROGRESS_CONNECTING +Verbinden mit %s... +;Connecting to %s... +; +; +MSG_PROGRESS_SEND_HTTP_REQUEST +HTTP-Anfrage senden... +;Sending HTTP Request... +; +; +MSG_PROGRESS_PROCESS_HTTP_RESPONSE +HTTP-Antwort verarbeiten... +;Processing HTTP Response... +; +; +MSG_PROGRESS_DONE +Fertig! +;Finished! +; +; +MSG_PROGRESS_FAILURE +Keine Verbindung zu %s : %s +;Failed to connect to %s : %s +; +; +MSG_PROGRESS_START_UPDATE +Aktualisierung beginnt... +;Starting Update... +; +; +MSG_PROGRESS_DOWNLOAD_UPDATE +Herunterladen von Update %s... +;Downloading update %s... +; +; +MSG_PROGRESS_FAILED +Fehlgeschlagen. +;Failed. +; +; +MSG_PROGRESS_VERIFY_SIGNATURE +Signatur wird geprüft... +;Verifying signature... +; +;----------------------------------------------------------- +; +; +MSGID_MENU_COMPONENTS_TITLE +Komponenten +;Components +; +; +MSGID_MENU_COMPONENTS_SELECT_ALL +Alles auswählen +;Select All +; +; +MSGID_MENU_COMPONENTS_SELECT_NONE +Alles abwählen +;Deselect All +; +;----------------------------------------------------------- +; +;+++translateme+++ +MSGID_LOG_READ_VERSIONINFO +Reading version information from Scalos update server %s.\n +;Reading version information from Scalos update server %s.\n +; +;+++translateme+++ +MSGID_LOG_ERROR_READ_VERSIONINFO +Failed to get version information from Scalos update server %s : %s.\n +;Failed to get version information from Scalos update server %s : %s.\n +; +;+++translateme+++ +MSGID_LOG_CHECKING_VERSIONS +Processing information about available updates.\n +;Processing information about available updates.\n +; +;+++translateme+++ +MSGID_LOG_UPDATES_FOUND +Found %ld components to update.\n +;Found %ld components to update.\n +; +;+++translateme+++ +MSGID_LOG_UPDATING +Updating component %ld of %ld.\n +;Updating component %ld of %ld.\n +; +;+++translateme+++ +MSGID_LOG_DOWNLOAD_PACKAGE +Downloading update package for %s\n. +;Downloading update package for %s\n. +; +;+++translateme+++ +MSGID_LOG_VERIFY_SIGNATURE +Verifying signature of %s update package\n. +;Verifying signature of %s update package\n. +; +;+++translateme+++ +MSGID_LOG_VERIFY_FAIL_SIGNATURE +Failed to update %s - invalid signature!\n +;Failed to update %s - invalid signature!\n +; +;+++translateme+++ +MSGID_LOG_DOWNLOAD_FAILED_PACKAGE +Failed to download update package for %s - %s.\n +;Failed to download update package for %s - %s.\n +; +;+++translateme+++ +MSGID_LOG_SKIP_PACKAGE +Skipping update of %s, due to user's request.\n +;Skipping update of %s, due to user's request.\n +; +;+++translateme+++ +MSGID_LOG_UNPACK_PACKAGE +Unpacking update package for %s.\n +;Unpacking update package for %s.\n +; +;+++translateme+++ +MSGID_LOG_UNPACK_FAIL_PACKAGE +Failed to unpack update for %s.\n +;Failed to unpack update for %s.\n +; +;+++translateme+++ +MSGID_LOG_UNPACK_CATALOGS_FAIL_PACKAGE +Failed to unpack language catalogs for %s.\n +;Failed to unpack language catalogs for %s.\n +; +;+++translateme+++ +MSGID_LOG_ERROR_OPEN_LHAFILE +Error: failed to open temporary archive \"%s\" for updating \"%s\".\n +; +;+++translateme+++ +MSGID_LOG_ERROR_OPEN_INPUTFD +Error: failed to open input file handle for lha: %s\n +;Error: failed to open input file handle for lha: %s\n +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Updater.module kann nicht gestartet werden +;Updater Module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Wiederholen|Beenden +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\ +Die Klasse ist nicht installiert. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Sie haben momentan Version v%lu.%lu installiert und\n\ +sollten die Klasse daher aktualisieren! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Version %lu.%lu wird momentan von einer anderen Anwendung\n\ +verwendet. Wenn sie die benötigte Version installiert haben,\n\ +schließen sie alle MUI Programme und probieren es erneut. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_AMISSL_LIBOPEN_FAIL_AMISSLMASTER +Konnte amisslmaster.library nicht öffnen +;Failed to open amisslmaster.library +; +; +MSGID_AMISSL_FAIL_INITAMISSLMASTER +InitAmiSSLMaster klappt nicht, eventuell ist Ihre AmiSSL-Installation zu alt +;InitAmiSSLMaster failed, probably your AmiSSL installation is too old +; +; +MSGID_AMISSL_FAIL_OPENAMISSL +OpenAmiSSL klappt nicht +;OpenAmiSSL failed +; +; +MSGID_AMISSL_FAIL_AMISSL_INTERFACE +Konnte kein Interface für AmiSSL bekommen +;Couldn't get AmiSSL interface +; +; +MSGID_AMISSL_FAIL_AMISSLMASTER_INTERFACE +Konnte kein Interface für AmiSSLMaster bekommen +;Couldn't get AmiSSLMaster interface +; +; +MSGID_AMISSL_FAIL_INITAMISSL +InitAmiSSL klappt nicht +;InitAmiSSL failed +; +; +MSGID_AMISSL_FAIL_REQ_FORMAT +Konnte AmiSSL nicht initialisieren:\n\ +%s\n\ +Leider benötigt der Aktualisierer eine funktionierende AmiSSL V3 Installation\n\ +(http://www.heightanxiety.com/AmiSSL)/\n\ +zur Prüfung der Signaturen der heruntergeladenen Dateien. +;Could not initialize AmiSSL:\n\ +;%s\n\ +;Sorry, but Updater needs a working AmiSSL V3 installation\n\ +;(http://www.heightanxiety.com/AmiSSL)/\n\ +;to verify the signatures of the downloaded files. +; +;----------------------------------------------------------- diff --git a/scalos/Modules/Updater.MUI/Catalogs/deutsch/Scalos/config.mk b/scalos/Modules/Updater.MUI/Catalogs/deutsch/Scalos/config.mk new file mode 100755 index 000000000..8631b0623 --- /dev/null +++ b/scalos/Modules/Updater.MUI/Catalogs/deutsch/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = deutsch + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = german + +else + +############################################################################### +# AmigaOS and AROS + +LANG = deutsch + +endif +endif diff --git a/scalos/Modules/Updater.MUI/Catalogs/deutsch/Scalos/makefile b/scalos/Modules/Updater.MUI/Catalogs/deutsch/Scalos/makefile new file mode 100644 index 000000000..8b4897e3e --- /dev/null +++ b/scalos/Modules/Updater.MUI/Catalogs/deutsch/Scalos/makefile @@ -0,0 +1,13 @@ +# makefile for Updater.module (translated Texts : deutsch) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mdeutsch\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +Updater.catalog : Updater.ct ../../../Updater.cd + +All: Updater.catalog diff --git a/scalos/Modules/Updater.MUI/Catalogs/deutsch/Scalos/makefile-new b/scalos/Modules/Updater.MUI/Catalogs/deutsch/Scalos/makefile-new new file mode 100644 index 000000000..f9dd6ad6c --- /dev/null +++ b/scalos/Modules/Updater.MUI/Catalogs/deutsch/Scalos/makefile-new @@ -0,0 +1,30 @@ +# makefile for Updater.module (translated Texts : deutsch) +# $Date: 2011-08-10 15:09:09 +0200 (Mi, 10. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = Updater + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git "a/scalos/Modules/Updater.MUI/Catalogs/fran\303\247ais/Scalos/Updater.ct" "b/scalos/Modules/Updater.MUI/Catalogs/fran\303\247ais/Scalos/Updater.ct" new file mode 100755 index 000000000..1659249ab --- /dev/null +++ "b/scalos/Modules/Updater.MUI/Catalogs/fran\303\247ais/Scalos/Updater.ct" @@ -0,0 +1,549 @@ +; Updater.ct +; $Date$ +; $Revision$ +; $Id$ +## version $VER: Updater.catalog 40.1 (05 Nov 2009 18:50:08) +## codeset 0 +## language français +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos : mise à jour +;Scalos Updater +; +;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Projet +;Project +; +MSGID_MENU_PROJECT_ABOUT +A propos... +;About... +; +MSGID_MENU_PROJECT_ABOUTMUI +A propos de MUI... +;About MUI... +; +MSGID_MENU_PROJECT_QUIT +Quitter +;Quit +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +;Q +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +_OKay +;_OK +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Updater.module V%ld.%ld\033n\n\ +%s\n\ +© 2009%s The Scalos Team +;\33c\033bScalos Updater.module V%ld.%ld\033n\n\ +;%s\n\ +;© 2009%s The Scalos Team +; +;----------------------------------------------------------- +; +MSGID_COMPONENTLIST_DIRECTORY +Répertoire +;Directory +; +MSGID_COMPONENTLIST_FILE +Fichier +;Filename +; +MSGID_COMPONENTLIST_LATEST_VERSION +Dernier +;Latest +; +MSGID_COMPONENTLIST_INSTALLED_VERSION +Installé +;Installed +; +MSGID_COMPONENTLIST_UPDATE +Mise à jour +;Update +; +;----------------------------------------------------------- +; +MSGID_BUTTON_CHECKFORUPDATES +Chercher les mises à jour +;Check For Updates +; +MSGID_BUTTON_CHECKFORUPDATES_SHORT +C +;C +; +MSGID_BUTTON_CHECKFORUPDATES_HELP +...TBD... +;...TBD... +; +MSGID_BUTTON_STARTUPDATE +Commencer la mise à jour +;Begin Update +; +MSGID_BUTTON_STARTUPDATE_SHORT +J +;B +; +MSGID_BUTTON_STARTUPDATE_HELP +...TBD... +;...TBD... +; +MSGID_BUTTON_SELECT_ALL +Tout sélectionner +;Select All +; +MSGID_BUTTON_SELECT_ALL_SHORT +T +;A +; +;+++translateme+++ +MSGID_BUTTON_SELECT_ALL_HELP +...TBD... +;...TBD... +; +MSGID_BUTTON_DESELECT_ALL +Tout déselectionner +;Deselect All +; +MSGID_BUTTON_DESELECT_ALL_SHORT +D +;D +; +;+++translateme+++ +MSGID_BUTTON_DESELECT_ALL_HELP +...TBD... +;...TBD... +; +MSGID_TEXT_SELECTED_COUNT +%ld Sélectionné(s) +;%ld Selected +; +MSGID_REGISTER_MAIN +Principal +;Main +; +MSGID_REGISTER_LOG +Compte rendu +;Log +; +MSGID_REGISTER_CONFIGURATION +Configuration +;Configuration +; +MSGID_GROUP_PROXY +Options du Proxy +;Proxy Settings +; +MSGID_CHECK_USE_PROXY +Utiliser un Proxy ? +;Use Proxy? +; +;+++translateme+++ +MSGID_CHECK_USE_PROXY_SHORTHELP +...TBD... +;...TBD... +; +MSGID_STRING_PROXY_ADDR +Adresse: +;Address: +; +;+++translateme+++ +MSGID_STRING_PROXY_ADDR_SHORTHELP +...TBD... +;...TBD... +; +MSGID_STRING_PROXY_PORT +Port: +;Port: +; +;+++translateme+++ +MSGID_STRING_PROXY_PORT_SHORTHELP +...TBD... +;...TBD... +; +MSGID_CHECK_USE_PROXYAUTH +Le Proxy néccessite une authentification ? +;Proxy requires authentication? +; +;+++translateme+++ +MSGID_CHECK_USE_PROXYAUTH_SHORTHELP +...TBD... +;...TBD... +; +MSGID_STRING_PROXY_USERNAME +Nom d'utilisateur: +;User Name: +; +;+++translateme+++ +MSGID_STRING_PROXY_USERNAME_SHORTHELP +...TBD... +;...TBD... +; +MSGID_STRING_PROXY_PASSWD +Mot de passe: +;Password: +; +;+++translateme+++ +MSGID_STRING_PROXY_PASSWD_SHORTHELP +...TBD... +;...TBD... +; +MSGID_REQFORMAT_OPENSSL_ERROR +Dans la fonction \033b%s\033n,\n\ +OpenSSL appelant \033b%s\033n a échoué :\n\ +%s +;In function \033b%s\033n,\n\ +;OpenSSL call \033b%s\033n failed:\n\ +;%s +; +MSGID_REQFORMAT_NO_UPDATES_FOUND +Pas de mise à jour pour %s.\n\ +Vous possédez déjà les composants\n\ +les plus récents de Scalos. +;No Updates found for %s.\n\ +;You already have the most recent\n\ +;Scalos components installed. +; +MSGID_CHECK_SHOW_ALL_COMPONENTS +Voir les vieux composants ? +;Show up-to-date components? +; +;+++translateme+++ +MSGID_CHECK_SHOW_ALL_COMPONENTS_SHORTHELP +...TBD... +;...TBD... +; +MSGID_CHECK_ASK_EVERY_UPDATE +Demander pour chaque mise à jour des composants ? +;Ask about every component update? +; +;+++translateme+++ +MSGID_CHECK_ASK_EVERY_UPDATE_SHORTHELP +...TBD... +;...TBD... +; +MSGID_ABOUTREQ_YES_NO_ABORT +_Oui|_Non|_Annuler +;_Yes|_No|_Abort +; +; +MSGID_REQFORMAT_ASK_UPDATE +Etes-vous certain de vouloir mettre à jour\n\ +\"%s\" en version %ld.%ld\n\ +(Version installée : %ld.%ld) ? +;Are you sure you want to update\n\ +;\"%s\" to version %ld.%ld\n\ +;(Installed Version: %ld.%ld) ? +; +MSGID_ERROR_DOWNLOADING_UPDATE +Erreur pendant le téléchargement du pack \"%s\"\n\ +%s +;Error downloading update package \"%s\"\n\ +;%s +; +MSGID_REQ_CONTINUE_ABORT +_Continuer|_Annuler +;_Continue|_Abort +; +MSGID_ERROR_LHA1 +Erreur : LHA n'a pas réussit à désarchiver \"%s\". +;Error: LHA failed to unpack \"%s\". +; +MSGID_ERROR_LHA2 +Erreur : LHA n'a pas réussit à désarchiver\n\ +les catalogues pour \"%s\". +;Error: LHA failed to unpack\n\ +;catalog files for \"%s\". +; +; +MSGID_ERROR_OPEN_LHAFILE +Erreur : Impossible d'ouvrir l'archive\n\ +temporaire \"%s\" pour mettre à jour \"%s\". +;Error: failed to open temporary\n\ +;archive \"%s\" for updating \"%s\". +; +MSGID_STRING_SCALOS_SERVER +Scalos : Serveur de mise à jour +;Scalos Update Server +; +;+++translateme+++ +MSGID_STRING_SCALOS_SERVER_SHORTHELP +...TBD... +;...TBD... +; +MSGID_REQ_INSTALL_UPDATES_GADGETS +_Mettre à jour|_Annuler +;_Update|_Abort +; +MSGID_REQ_INSTALL_UPDATES +Etes-vous certain de vouloir instajjer\n\ +%ld les mises à jour de Scalos maintenant ? +;Are you sure you want to install\n\ +;%ld Scalos updates now? +; +MSGID_GROUP_LOG +Mise à jour du compte rendu +;Update Log +; +MSGID_POPASL_TEMPPATH +Chemin pour les fichiers temporarires +;Path for Temporary Files +; +MSGID_GROUP_MISCELLANEOUS +Divers +;Miscellaneous +; +MSGID_BUTTON_CLEAR_LOG +Vider le compte rendu +;Clear Log +; +MSGID_BUTTON_CLEAR_LOG_SHORT +V +;C +; +;+++translateme+++ +MSGID_BUTTON_CLEAR_LOG_SHORTHELP +...TBD.. +;...TBD.. +; +MSGID_BUTTON_SAVE_LOG +Sauver le compte rendu... +;Save Log... +; +;+++translateme+++ +MSGID_BUTTON_SAVE_LOG_SHORT +S +;S +; +;+++translateme+++ +MSGID_BUTTON_SAVE_LOG_SHORTHELP +...TBD.. +;...TBD.. +; +MSGID_SAVE_LOG_ASLTITLE +Sauver la mise à jour du compte rendu... +;Save Update Log... +; +;----------------------------------------------------------- +; +MSG_PROGRESS_RESOLVING_NAME +Résolution du nom %s... +;Resolving name %s... +; +MSG_PROGRESS_CONNECTING +Connection à %s... +;Connecting to %s... +; +MSG_PROGRESS_SEND_HTTP_REQUEST +Envoi de la requête HTTP... +;Sending HTTP Request... +; +MSG_PROGRESS_PROCESS_HTTP_RESPONSE +Processus de réponse HTTP... +;Processing HTTP Response... +; +MSG_PROGRESS_DONE +Terminé ! +;Finished! +; +MSG_PROGRESS_FAILURE +Impossible de se connecter à %s : %s +;Failed to connect to %s : %s +; +MSG_PROGRESS_START_UPDATE +Démarrage de la mise à jour... +;Starting Update... +; +MSG_PROGRESS_DOWNLOAD_UPDATE +Téléchargement de la mise à jour %s... +;Downloading update %s... +; +MSG_PROGRESS_FAILED +Echoué. +;Failed. +; +MSG_PROGRESS_VERIFY_SIGNATURE +Vérification de la signature... +;Verifying signature... +; +;----------------------------------------------------------- +; +MSGID_MENU_COMPONENTS_TITLE +Composants +;Components +; +MSGID_MENU_COMPONENTS_SELECT_ALL +Tout sélectionner +;Select All +; +MSGID_MENU_COMPONENTS_SELECT_NONE +Tout déselectionner +;Deselect All +; +;----------------------------------------------------------- +; +MSGID_LOG_READ_VERSIONINFO +Lecture d'information de la version depuis le serveur de mise à jour de Scalos %s.\n +;Reading version information from Scalos update server %s.\n +; +MSGID_LOG_ERROR_READ_VERSIONINFO +La recherche de l'information de la version a échouée depuis le serveur de mise à jour de Scalos %s : %s.\n +;Failed to get version information from Scalos update server %s : %s.\n +; +;+++translateme+++ +MSGID_LOG_CHECKING_VERSIONS +Processing information about available updates.\n +;Processing information about available updates.\n +; +;+++translateme+++ +MSGID_LOG_UPDATES_FOUND +Found %ld components to update.\n +;Found %ld components to update.\n +; +;+++translateme+++ +MSGID_LOG_UPDATING +Updating component %ld of %ld.\n +;Updating component %ld of %ld.\n +; +;+++translateme+++ +MSGID_LOG_DOWNLOAD_PACKAGE +Downloading update package for %s\n. +;Downloading update package for %s\n. +; +;+++translateme+++ +MSGID_LOG_VERIFY_SIGNATURE +Verifying signature of %s update package\n. +;Verifying signature of %s update package\n. +; +;+++translateme+++ +MSGID_LOG_VERIFY_FAIL_SIGNATURE +Failed to update %s - invalid signature!\n +;Failed to update %s - invalid signature!\n +; +;+++translateme+++ +MSGID_LOG_DOWNLOAD_FAILED_PACKAGE +Failed to download update package for %s - %s.\n +;Failed to download update package for %s - %s.\n +; +;+++translateme+++ +MSGID_LOG_SKIP_PACKAGE +Skipping update of %s, due to user's request.\n +;Skipping update of %s, due to user's request.\n +; +;+++translateme+++ +MSGID_LOG_UNPACK_PACKAGE +Unpacking update package for %s.\n +;Unpacking update package for %s.\n +; +;+++translateme+++ +MSGID_LOG_UNPACK_FAIL_PACKAGE +Failed to unpack update for %s.\n +;Failed to unpack update for %s.\n +; +;+++translateme+++ +MSGID_LOG_UNPACK_CATALOGS_FAIL_PACKAGE +Failed to unpack language catalogs for %s.\n +;Failed to unpack language catalogs for %s.\n +; +;+++translateme+++ +MSGID_LOG_ERROR_OPEN_LHAFILE +Error: failed to open temporary archive \"%s\" for updating \"%s\".\n +; +;+++translateme+++ +MSGID_LOG_ERROR_OPEN_INPUTFD +Error: failed to open input file handle for lha: %s\n +;Error: failed to open input file handle for lha: %s\n +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Le démarrage du module de recherche a échoué. +;Updater Module startup failed +; +MSGID_STARTUP_RETRY_QUIT_GAD +Essayer de nouveau | Quitter +;Try again|Quit +; +MSGID_STARTUP_MCC_NOT_FOUND +Ouverture impossible de la classe MUI '%s' V%lu.%lu.\n\ +La classe n'est pas installée. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +MSGID_STARTUP_OLD_MCC +Ouverture impossible de la classe MUI '%s' V%lu.%lu.\n\ +\n\ +Actuellement installée : V%lu.%lu, \n\ +installez une version supérieure S.V.P ! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +MSGID_STARTUP_MCC_IN_USE +Ouverture impossible de la classe MUI '%s' V%lu.%lu.\n\ +%lu.%lu est actuellement utilisé par d'autres applications.\n\ +\n\ +Une fois que vous vaez installé la version requise,\n\ +fermez tous les programmes MUI, soyez sure que l'ancienne classe\n\ +ne soit plus en mémoire et essayez de nouveau. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_AMISSL_LIBOPEN_FAIL_AMISSLMASTER +Failed to open amisslmaster.library +;Failed to open amisslmaster.library +; +;+++translateme+++ +MSGID_AMISSL_FAIL_INITAMISSLMASTER +InitAmiSSLMaster failed, probably your AmiSSL installation is too old +;InitAmiSSLMaster failed, probably your AmiSSL installation is too old +; +;+++translateme+++ +MSGID_AMISSL_FAIL_OPENAMISSL +OpenAmiSSL failed +;OpenAmiSSL failed +; +;+++translateme+++ +MSGID_AMISSL_FAIL_AMISSL_INTERFACE +Couldn't get AmiSSL interface +;Couldn't get AmiSSL interface +; +;+++translateme+++ +MSGID_AMISSL_FAIL_AMISSLMASTER_INTERFACE +Couldn't get AmiSSLMaster interface +;Couldn't get AmiSSLMaster interface +; +;+++translateme+++ +MSGID_AMISSL_FAIL_INITAMISSL +InitAmiSSL failed +;InitAmiSSL failed +; +;+++translateme+++ +MSGID_AMISSL_FAIL_REQ_FORMAT +Could not initialize AmiSSL:\n\ +%s\n\ +Sorry, but Updater needs a working AmiSSL V3 installation\n\ +(http://www.heightanxiety.com/AmiSSL)/\n\ +to verify the signatures of the downloaded files. +;Could not initialize AmiSSL:\n\ +;%s\n\ +;Sorry, but Updater needs a working AmiSSL V3 installation\n\ +;(http://www.heightanxiety.com/AmiSSL)/\n\ +;to verify the signatures of the downloaded files. +; +;----------------------------------------------------------- diff --git "a/scalos/Modules/Updater.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" "b/scalos/Modules/Updater.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" new file mode 100755 index 000000000..8b7056423 --- /dev/null +++ "b/scalos/Modules/Updater.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" @@ -0,0 +1,40 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = français + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = french + +else + +############################################################################### +# AmigaOS and AROS + +LANG = français + +endif +endif diff --git "a/scalos/Modules/Updater.MUI/Catalogs/fran\303\247ais/Scalos/makefile" "b/scalos/Modules/Updater.MUI/Catalogs/fran\303\247ais/Scalos/makefile" new file mode 100644 index 000000000..6860cdb61 --- /dev/null +++ "b/scalos/Modules/Updater.MUI/Catalogs/fran\303\247ais/Scalos/makefile" @@ -0,0 +1,13 @@ +# makefile for Updater.module (translated Texts : français) +# $Date: 17 Aug 2004 20:12:47 + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mfrançais\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +Updater.catalog : Updater.ct ../../../Updater.cd + +All: Updater.catalog diff --git "a/scalos/Modules/Updater.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" "b/scalos/Modules/Updater.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" new file mode 100644 index 000000000..0ba5fa5af --- /dev/null +++ "b/scalos/Modules/Updater.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" @@ -0,0 +1,30 @@ +# makefile for Updater.module (translated Texts : français) +# $Date: 2011-08-10 15:09:09 +0200 (Mi, 10. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = Updater + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Modules/Updater.MUI/Catalogs/sample/Scalos/Updater.ct b/scalos/Modules/Updater.MUI/Catalogs/sample/Scalos/Updater.ct new file mode 100644 index 000000000..100e6dcdc --- /dev/null +++ b/scalos/Modules/Updater.MUI/Catalogs/sample/Scalos/Updater.ct @@ -0,0 +1,616 @@ +; Updater.ct +; version $VER: Updater.catalog 40.1 (23. Aug 2008 18:50:08) +; $Date$ +; $Revision$ +; codeset 0s +; language xxxxxx +; +;#arrayopts static __far +; +;+++translateme+++ +MSGID_TITLENAME +Scalos Updater +;Scalos Updater +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_MENU_PROJECT +Project +;Project +; +;+++translateme+++ +MSGID_MENU_PROJECT_ABOUT +About... +;About... +; +;+++translateme+++ +MSGID_MENU_PROJECT_ABOUTMUI +About MUI... +;About MUI... +; +;+++translateme+++ +MSGID_MENU_PROJECT_QUIT +Quit +;Quit +; +;+++translateme+++ +MSGID_MENU_PROJECT_QUIT_SHORT +Q +;Q +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_ABOUTREQOK +_OK +;_OK +; +;+++translateme+++ +MSGID_ABOUTREQFORMAT +\33c\033bScalos Updater.module V%ld.%ld\033n\n\ +%s\n\ +© 2009%s The Scalos Team +;\33c\033bScalos Updater.module V%ld.%ld\033n\n\ +;%s\n\ +;© 2009%s The Scalos Team +; +;----------------------------------------------------------- +; +;+++translateme+++ +MSGID_COMPONENTLIST_DIRECTORY +Directory +;Directory +; +;+++translateme+++ +MSGID_COMPONENTLIST_FILE +Filename +;Filename +; +;+++translateme+++ +MSGID_COMPONENTLIST_LATEST_VERSION +Latest +;Latest +; +;+++translateme+++ +MSGID_COMPONENTLIST_INSTALLED_VERSION +Installed +;Installed +; +;+++translateme+++ +MSGID_COMPONENTLIST_UPDATE +Update +;Update +; +;----------------------------------------------------------- +; +;+++translateme+++ +MSGID_BUTTON_CHECKFORUPDATES +Check For Updates +;Check For Updates +; +;+++translateme+++ +MSGID_BUTTON_CHECKFORUPDATES_SHORT +C +;C +; +;+++translateme+++ +MSGID_BUTTON_CHECKFORUPDATES_HELP +...TBD... +;...TBD... +; +;+++translateme+++ +MSGID_BUTTON_STARTUPDATE +Begin Update +;Begin Update +; +;+++translateme+++ +MSGID_BUTTON_STARTUPDATE_SHORT +B +;B +; +;+++translateme+++ +MSGID_BUTTON_STARTUPDATE_HELP +...TBD... +;...TBD... +; +;+++translateme+++ +MSGID_BUTTON_SELECT_ALL +Select All +;Select All +; +;+++translateme+++ +MSGID_BUTTON_SELECT_ALL_SHORT +A +;A +; +;+++translateme+++ +MSGID_BUTTON_SELECT_ALL_HELP +...TBD... +;...TBD... +; +;+++translateme+++ +MSGID_BUTTON_DESELECT_ALL +Deselect All +;Deselect All +; +;+++translateme+++ +MSGID_BUTTON_DESELECT_ALL_SHORT +D +;D +; +;+++translateme+++ +MSGID_BUTTON_DESELECT_ALL_HELP +...TBD... +;...TBD... +; +;+++translateme+++ +MSGID_TEXT_SELECTED_COUNT +%ld Selected +;%ld Selected +; +;+++translateme+++ +MSGID_REGISTER_MAIN +Main +;Main +; +;+++translateme+++ +MSGID_REGISTER_LOG +Log +;Log +; +;+++translateme+++ +MSGID_REGISTER_CONFIGURATION +Configuration +;Configuration +; +;+++translateme+++ +MSGID_GROUP_PROXY +Proxy Settings +;Proxy Settings +; +;+++translateme+++ +MSGID_CHECK_USE_PROXY +Use Proxy? +;Use Proxy? +; +;+++translateme+++ +MSGID_CHECK_USE_PROXY_SHORTHELP +...TBD... +;...TBD... +; +;+++translateme+++ +MSGID_STRING_PROXY_ADDR +Address: +;Address: +; +;+++translateme+++ +MSGID_STRING_PROXY_ADDR_SHORTHELP +...TBD... +;...TBD... +; +;+++translateme+++ +MSGID_STRING_PROXY_PORT +Port: +;Port: +; +;+++translateme+++ +MSGID_STRING_PROXY_PORT_SHORTHELP +...TBD... +;...TBD... +; +;+++translateme+++ +MSGID_CHECK_USE_PROXYAUTH +Proxy requires authentication? +;Proxy requires authentication? +; +;+++translateme+++ +MSGID_CHECK_USE_PROXYAUTH_SHORTHELP +...TBD... +;...TBD... +; +;+++translateme+++ +MSGID_STRING_PROXY_USERNAME +User Name: +;User Name: +; +;+++translateme+++ +MSGID_STRING_PROXY_USERNAME_SHORTHELP +...TBD... +;...TBD... +; +;+++translateme+++ +MSGID_STRING_PROXY_PASSWD +Password: +;Password: +; +;+++translateme+++ +MSGID_STRING_PROXY_PASSWD_SHORTHELP +...TBD... +;...TBD... +; +;+++translateme+++ +MSGID_REQFORMAT_OPENSSL_ERROR +In function \033b%s\033n,\n\ +OpenSSL call \033b%s\033n failed:\n\ +%s +;In function \033b%s\033n,\n\ +;OpenSSL call \033b%s\033n failed:\n\ +;%s +; +;+++translateme+++ +MSGID_REQFORMAT_NO_UPDATES_FOUND +No Updates found for %s.\n\ +You already have the most recent\n\ +Scalos components installed. +;No Updates found for %s.\n\ +;You already have the most recent\n\ +;Scalos components installed. +; +;+++translateme+++ +MSGID_CHECK_SHOW_ALL_COMPONENTS +Show up-to-date components? +;Show up-to-date components? +; +;+++translateme+++ +MSGID_CHECK_SHOW_ALL_COMPONENTS_SHORTHELP +...TBD... +;...TBD... +; +;+++translateme+++ +MSGID_CHECK_ASK_EVERY_UPDATE +Ask about every component update? +;Ask about every component update? +; +;+++translateme+++ +MSGID_CHECK_ASK_EVERY_UPDATE_SHORTHELP +...TBD... +;...TBD... +; +;+++translateme+++ +MSGID_ABOUTREQ_YES_NO_ABORT +_Yes|_No|_Abort +;_Yes|_No|_Abort +; +;+++translateme+++ +MSGID_REQFORMAT_ASK_UPDATE +Are you sure you want to update\n\ +\"%s\" to version %ld.%ld\n\ +(Installed Version: %ld.%ld) ? +;Are you sure you want to update\n\ +;\"%s\" to version %ld.%ld\n\ +;(Installed Version: %ld.%ld) ? +; +;+++translateme+++ +MSGID_ERROR_DOWNLOADING_UPDATE +Error downloading update package \"%s\"\n\ +%s +;Error downloading update package \"%s\"\n\ +;%s +; +;+++translateme+++ +MSGID_REQ_CONTINUE_ABORT +_Continue|_Abort +;_Continue|_Abort +; +;+++translateme+++ +MSGID_ERROR_LHA1 +Error: LHA failed to unpack \"%s\". +;Error: LHA failed to unpack \"%s\". +; +;+++translateme+++ +MSGID_ERROR_LHA2 +Error: LHA failed to unpack\n\ +catalog files for \"%s\". +;Error: LHA failed to unpack\n\ +;catalog files for \"%s\". +; +;+++translateme+++ +MSGID_ERROR_OPEN_LHAFILE +Error: failed to open temporary\n\ +archive \"%s\" for updating \"%s\". +;Error: failed to open temporary\n\ +;archive \"%s\" for updating \"%s\". +; +;+++translateme+++ +MSGID_STRING_SCALOS_SERVER +Scalos Update Server +;Scalos Update Server +; +;+++translateme+++ +MSGID_STRING_SCALOS_SERVER_SHORTHELP +...TBD... +;...TBD... +; +;+++translateme+++ +MSGID_REQ_INSTALL_UPDATES_GADGETS +_Update|_Abort +;_Update|_Abort +; +;+++translateme+++ +MSGID_REQ_INSTALL_UPDATES +Are you sure you want to install\n\ +%ld Scalos updates now? +;Are you sure you want to install\n\ +;%ld Scalos updates now? +; +;+++translateme+++ +MSGID_GROUP_LOG +Update Log +;Update Log +; +;+++translateme+++ +MSGID_POPASL_TEMPPATH +Path for Temporary Files +;Path for Temporary Files +; +;+++translateme+++ +MSGID_GROUP_MISCELLANEOUS +Miscellaneous +;Miscellaneous +; +;+++translateme+++ +MSGID_BUTTON_CLEAR_LOG +Clear Log +;Clear Log +; +;+++translateme+++ +MSGID_BUTTON_CLEAR_LOG_SHORT +C +;C +; +;+++translateme+++ +MSGID_BUTTON_CLEAR_LOG_SHORTHELP +...TBD.. +;...TBD.. +; +;+++translateme+++ +MSGID_BUTTON_SAVE_LOG +Save Log... +;Save Log... +; +;+++translateme+++ +MSGID_BUTTON_SAVE_LOG_SHORT +S +;S +; +;+++translateme+++ +MSGID_BUTTON_SAVE_LOG_SHORTHELP +...TBD.. +;...TBD.. +; +;+++translateme+++ +MSGID_SAVE_LOG_ASLTITLE +Save Update Log... +;Save Update Log... +; +;----------------------------------------------------------- +; +;+++translateme+++ +MSG_PROGRESS_RESOLVING_NAME +Resolving name %s... +;Resolving name %s... +; +;+++translateme+++ +MSG_PROGRESS_CONNECTING +Connecting to %s... +;Connecting to %s... +; +;+++translateme+++ +MSG_PROGRESS_SEND_HTTP_REQUEST +Sending HTTP Request... +;Sending HTTP Request... +; +;+++translateme+++ +MSG_PROGRESS_PROCESS_HTTP_RESPONSE +Processing HTTP Response... +;Processing HTTP Response... +; +;+++translateme+++ +MSG_PROGRESS_DONE +Finished! +;Finished! +; +;+++translateme+++ +MSG_PROGRESS_FAILURE +Failed to connect to %s : %s +;Failed to connect to %s : %s +; +;+++translateme+++ +MSG_PROGRESS_START_UPDATE +Starting Update... +;Starting Update... +; +;+++translateme+++ +MSG_PROGRESS_DOWNLOAD_UPDATE +Downloading update %s... +;Downloading update %s... +; +;+++translateme+++ +MSG_PROGRESS_FAILED +Failed. +;Failed. +; +;+++translateme+++ +MSG_PROGRESS_VERIFY_SIGNATURE +Verifying signature... +;Verifying signature... +; +;----------------------------------------------------------- +; +;+++translateme+++ +MSGID_MENU_COMPONENTS_TITLE +Components +;Components +; +;+++translateme+++ +MSGID_MENU_COMPONENTS_SELECT_ALL +Select All +;Select All +; +;+++translateme+++ +MSGID_MENU_COMPONENTS_SELECT_NONE +Deselect All +;Deselect All +; +;----------------------------------------------------------- +; +;+++translateme+++ +MSGID_LOG_READ_VERSIONINFO +Reading version information from Scalos update server %s.\n +;Reading version information from Scalos update server %s.\n +; +;+++translateme+++ +MSGID_LOG_ERROR_READ_VERSIONINFO +Failed to get version information from Scalos update server %s : %s.\n +;Failed to get version information from Scalos update server %s : %s.\n +; +;+++translateme+++ +MSGID_LOG_CHECKING_VERSIONS +Processing information about available updates.\n +;Processing information about available updates.\n +; +;+++translateme+++ +MSGID_LOG_UPDATES_FOUND +Found %ld components to update.\n +;Found %ld components to update.\n +; +;+++translateme+++ +MSGID_LOG_UPDATING +Updating component %ld of %ld.\n +;Updating component %ld of %ld.\n +; +;+++translateme+++ +MSGID_LOG_DOWNLOAD_PACKAGE +Downloading update package for %s\n. +;Downloading update package for %s\n. +; +;+++translateme+++ +MSGID_LOG_VERIFY_SIGNATURE +Verifying signature of %s update package\n. +;Verifying signature of %s update package\n. +; +;+++translateme+++ +MSGID_LOG_VERIFY_FAIL_SIGNATURE +Failed to update %s - invalid signature!\n +;Failed to update %s - invalid signature!\n +; +;+++translateme+++ +MSGID_LOG_DOWNLOAD_FAILED_PACKAGE +Failed to download update package for %s - %s.\n +;Failed to download update package for %s - %s.\n +; +;+++translateme+++ +MSGID_LOG_SKIP_PACKAGE +Skipping update of %s, due to user's request.\n +;Skipping update of %s, due to user's request.\n +; +;+++translateme+++ +MSGID_LOG_UNPACK_PACKAGE +Unpacking update package for %s.\n +;Unpacking update package for %s.\n +; +;+++translateme+++ +MSGID_LOG_UNPACK_FAIL_PACKAGE +Failed to unpack update for %s.\n +;Failed to unpack update for %s.\n +; +;+++translateme+++ +MSGID_LOG_UNPACK_CATALOGS_FAIL_PACKAGE +Failed to unpack language catalogs for %s.\n +;Failed to unpack language catalogs for %s.\n +; +;+++translateme+++ +MSGID_LOG_ERROR_OPEN_LHAFILE +Error: failed to open temporary archive \"%s\" for updating \"%s\".\n +; +;+++translateme+++ +MSGID_LOG_ERROR_OPEN_INPUTFD +Error: failed to open input file handle for lha: %s\n +;Error: failed to open input file handle for lha: %s\n +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_STARTUP_FAILURE +Updater Module startup failed +;Updater Module startup failed +; +;+++translateme+++ +MSGID_STARTUP_RETRY_QUIT_GAD +Try again|Quit +;Try again|Quit +; +;+++translateme+++ +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +;+++translateme+++ +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +;+++translateme+++ +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_AMISSL_LIBOPEN_FAIL_AMISSLMASTER +Failed to open amisslmaster.library +;Failed to open amisslmaster.library +; +;+++translateme+++ +MSGID_AMISSL_FAIL_INITAMISSLMASTER +InitAmiSSLMaster failed, probably your AmiSSL installation is too old +;InitAmiSSLMaster failed, probably your AmiSSL installation is too old +; +;+++translateme+++ +MSGID_AMISSL_FAIL_OPENAMISSL +OpenAmiSSL failed +;OpenAmiSSL failed +; +;+++translateme+++ +MSGID_AMISSL_FAIL_AMISSL_INTERFACE +Couldn't get AmiSSL interface +;Couldn't get AmiSSL interface +; +;+++translateme+++ +MSGID_AMISSL_FAIL_AMISSLMASTER_INTERFACE +Couldn't get AmiSSLMaster interface +;Couldn't get AmiSSLMaster interface +; +;+++translateme+++ +MSGID_AMISSL_FAIL_INITAMISSL +InitAmiSSL failed +;InitAmiSSL failed +; +;+++translateme+++ +MSGID_AMISSL_FAIL_REQ_FORMAT +Could not initialize AmiSSL:\n\ +%s\n\ +Sorry, but Updater needs a working AmiSSL V3 installation\n\ +(http://www.heightanxiety.com/AmiSSL)/\n\ +to verify the signatures of the downloaded files. +;Could not initialize AmiSSL:\n\ +;%s\n\ +;Sorry, but Updater needs a working AmiSSL V3 installation\n\ +;(http://www.heightanxiety.com/AmiSSL)/\n\ +;to verify the signatures of the downloaded files. +; +;----------------------------------------------------------- diff --git a/scalos/Modules/Updater.MUI/Updater.c b/scalos/Modules/Updater.MUI/Updater.c new file mode 100644 index 000000000..7d219a3ae --- /dev/null +++ b/scalos/Modules/Updater.MUI/Updater.c @@ -0,0 +1,3463 @@ +// Updater.c +// $Date$ +// $Revision$ + +#ifdef __AROS__ +#define MUIMASTER_YES_INLINE_STDARG +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef STATIC_SSL +#include +#include +#endif + +#include +#include + +#define CURL_DISABLE_TYPECHECK +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef STATIC_SSL +#include +#else +#include +#include +#endif + +#include +#include +#include // +jmc+ + +#include "Updater.h" +#include "debug.h" + +#define Updater_NUMBERS +#define Updater_ARRAY +#define Updater_CODE +#include STR(SCALOSLOCALE) + +//---------------------------------------------------------------------------- + +#if !defined(__amigaos4__) && !defined(__AROS__) +#include + +long _stack = 16384; // minimum stack size, used by SAS/C startup code +#endif + +//---------------------------------------------------------------------------- + +// local data structures + +#define KeyButtonHelp(name,key,HelpText)\ + TextObject,\ + ButtonFrame,\ + MUIA_CycleChain, TRUE, \ + MUIA_Font, MUIV_Font_Button,\ + MUIA_Text_Contents, name,\ + MUIA_Text_PreParse, "\33c",\ + MUIA_Text_HiChar , key,\ + MUIA_ControlChar , key,\ + MUIA_InputMode , MUIV_InputMode_RelVerify,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShortHelp, HelpText,\ + End + +struct VersionFileHandle + { + STRPTR vfh_AllocatedBuffer; + STRPTR vfh_BuffPtr; + size_t vfh_AllocatedLength; + size_t vfh_TotalLength; + size_t vfh_CurrentLength; + }; + +struct ComponentListEntry + { + STRPTR cle_Dir; + STRPTR cle_File; + STRPTR cle_Package; + STRPTR cle_Hash; + + ULONG cle_RemoteVersion; + ULONG cle_RemoteRevision; + ULONG cle_RemotePatchLevel; + + Object *cle_LampObject; + ULONG cle_LampImageNr; + + Object *cle_CheckboxObject; + ULONG cle_CheckboxImageNr; + + ULONG cle_Selected; + + ULONG cle_LocalVersion; + ULONG cle_LocalRevision; + ULONG cle_LocalPatchLevel; + + char cle_LocalVersionString[10]; + char cle_RemoteVersionString[10]; + char cle_CheckboxImageNrString[20]; + char cle_LampImageNrString[20]; + }; + +struct ProgressData + { + ULONG pgd_Min; + ULONG pgd_Max; + }; + +struct MUIP_ScalosPrefs_MCCList + { + CONST_STRPTR MccName; + ULONG MccMinVersion; + ULONG MccMinRevision; + }; + +//---------------------------------------------------------------------------- + +// local functions + +static BOOL init(void); +static BOOL MyInitAmiSSL(void); +static void fail(APTR APP_Main, CONST_STRPTR str, int rc); +static BOOL OpenLibraries(CONST_STRPTR LibName); +static void CloseLibraries(void); +static SAVEDS(APTR) INTERRUPT OpenAboutMUIFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT OpenAboutFunc(struct Hook *hook, Object *o, Msg msg); + +static void TranslateStringArray(CONST_STRPTR *stringArray); +static void TranslateNewMenu(struct NewMenu *nm); +static STRPTR GetLocString(ULONG MsgId); +BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev); +static BOOL ProcessVersionFile(CONST_STRPTR text, size_t len); +static size_t VersionFileWrite( void *ptr, size_t size, size_t nmemb, void *stream); +static APTR ComponentsConstructHookFunc(struct Hook *hook, Object *obj, struct NList_ConstructMessage *msg); +static void ComponentsDestructHookFunc(struct Hook *hook, Object *obj, struct NList_DestructMessage *msg); +static ULONG ComponentsDisplayHookFunc(struct Hook *hook, Object *obj, struct NList_DisplayMessage *msg); +static LONG ComponentsCompareHookFunc(struct Hook *hook, Object *obj, struct NList_CompareMessage *msg); +static void ComponentToggleUpdateHookFunc(struct Hook *hook, Object *obj, Msg *msg); +static void ToggleShowAllHookFunc(struct Hook *hook, Object *obj, Msg *msg); +static STRPTR GetAssignListVersionString(CONST_STRPTR Dir, CONST_STRPTR Filename, STRPTR VersionString, size_t MaxLen); +static STRPTR GetFileVersionString(CONST_STRPTR Dir, CONST_STRPTR Filename, STRPTR VersionString, size_t MaxLen); +static void ExtractVersionNumberFromVersionString(CONST_STRPTR VersionString, ULONG *Version, ULONG *Revision, ULONG *PatchLevel); +static void CheckForUpdatesHookFunc(struct Hook *hook, Object *obj, Msg *msg); +static void StartUpdateUpdateHookFunc(struct Hook *hook, Object *obj, Msg *msg); +static void SelectAllComponentsHookFunc(struct Hook *hook, Object *obj, Msg *msg); +static void DeselectAllComponentsHookFunc(struct Hook *hook, Object *obj, Msg *msg); +static void SaveLogHookFunc(struct Hook *hook, Object *obj, Msg *msg); +static void AslIntuiMsgHookFunc(struct Hook *hook, Object *o, Msg msg); +static void UpdateSelectedCount(void); +static int CheckForUpdatesProgressFunc(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow); +static int PerformUpdateProgressFunc(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow); +static BOOL CalculateFileHash(CONST_STRPTR Filename, unsigned char *digest); +static RSA* GetScalosPublicKey(void); +static BOOL VerifyFileSignature(CONST_STRPTR FileName, CONST_STRPTR SignatureString); +static BOOL VerifyVersionsFileSignature(const struct VersionFileHandle *vfhFile, const struct VersionFileHandle *vfhSig); +static void decodeblock(const unsigned char in[4], unsigned char out[3]); +static BOOL Base64Decode(CONST_STRPTR Base64String, unsigned char *outbuf, size_t BuffLength); +//static BOOL HexStringDecode(CONST_STRPTR HexString, unsigned char *outbuf, size_t BuffLength); +//static UBYTE HexDigit(char ch); +//static void ByteDump(unsigned char *Data, size_t Length); +static STRPTR EscapeHttpName(CONST_STRPTR name); +static BOOL SetProxyOptions(CURL *curl); +static void OpenSSLError(CONST_STRPTR Function, CONST_STRPTR Operation); +static BOOL ErrorMsg(ULONG MsgId, ...); +static void AddLogMsg(ULONG MsgId, ...); +static void ParseArguments(void); +static CURLcode DownloadFile(struct VersionFileHandle *vfh, CONST_STRPTR Filename, ULONG ProgressMin, ULONG ProgressMax); +#if !defined(__SASC) &&!defined(__MORPHOS__) +size_t stccpy(char *dest, const char *src, size_t MaxLen); +#endif //!defined(__SASC) &&!defined(__MORPHOS__) + +//---------------------------------------------------------------------------- + +// local data items + +struct DosLibrary *DOSBase; +struct IntuitionBase *IntuitionBase = NULL; +struct Library *MUIMasterBase = NULL; +struct ScalosBase *ScalosBase = NULL; +extern struct Library *SocketBase; +T_LOCALEBASE LocaleBase = NULL; +T_TIMERBASE TimerBase; +struct Library *IconBase = NULL; + +#ifndef STATIC_SSL +struct Library *AmiSSLMasterBase; +struct Library *AmiSSLBase; +#endif + +#if defined(__GNUC__) && defined(M68K) +extern T_UTILITYBASE __UtilityBase; +#else /* defined(__GNUC__) && defined(M68K) */ +T_UTILITYBASE UtilityBase; +#endif /* defined(__GNUC__) && defined(M68K) */ + +#ifdef __amigaos4__ +struct DOSIFace *IDOS; +struct IntuitionIFace *IIntuition = NULL; +struct MUIMasterIFace *IMUIMaster = NULL; +struct ScalosIFace *IScalos = NULL; +struct SocketIFace *ISocket = NULL; +struct LocaleIFace *ILocale = NULL; +struct TimerIFace *ITimer; +struct UtilityIFace *IUtility; +struct IconIFace *IIcon = NULL; +struct AmiSSLMasterIFace *IAmiSSLMaster; +struct AmiSSLIFace *IAmiSSL; +#endif + +static struct Catalog *FindCatalog; + +static Object *APP_Main; +static Object *WIN_Main; +static Object *WIN_AboutMUI; +static Object *MenuAbout, *MenuAboutMUI, *MenuQuit; +static Object *GaugeProgress; +static Object *NListComponents; +static Object *NListHiddenComponents; +static Object *SelectedCountMsg; +static Object *ButtonCheckForUpdates, *ButtonStartUpdate; +static Object *ButtonSelectAll, *ButtonDeselectAll; +static Object *ContextMenuComponents; +static Object *CheckUseProxy, *CheckUseProxyAuth; +static Object *StringProxyAddr, *StringProxyPort; +static Object *StringProxyUser, *StringProxyPwd; +static Object *CheckShowAllComponents; +static Object *StringScalosWebSite; +static Object *CheckAskEveryUpdate; +static Object *GroupSelection, *GroupActionButtons; +static Object *TextEditorLog; +static Object *ScrollBarLog; +static Object *PopAslTempPath; +static Object *ButtonClearLog, *ButtonSaveLog; + +static struct FileRequester *SaveLogAslRequest = NULL; + +struct WBStartup *WBenchMsg; + +static char TextProgressBuffer[256]; + +static T_TIMEREQUEST *TimerIO; +static struct MsgPort *TimerPort; + +static ULONG globalImageNr = 0; + +static ULONG SelectedCount = 0; + +#if defined(__amigaos4__) +static CONST_STRPTR OsName = "AmigaOS4"; +#elif defined(__MORPHOS__) +static CONST_STRPTR OsName = "MorphOS"; +#else +static CONST_STRPTR OsName = "AmigaOS3"; +#endif + +static struct Hook AboutHook = {{ NULL, NULL }, HOOKFUNC_DEF(OpenAboutFunc), NULL }; +static struct Hook AboutMUIHook = {{ NULL, NULL }, HOOKFUNC_DEF(OpenAboutMUIFunc), NULL }; +static struct Hook ComponentsConstructHook = {{ NULL, NULL }, HOOKFUNC_DEF(ComponentsConstructHookFunc), NULL }; +static struct Hook ComponentsDestructHook = {{ NULL, NULL }, HOOKFUNC_DEF(ComponentsDestructHookFunc), NULL }; +static struct Hook ComponentsDisplayHook = {{ NULL, NULL }, HOOKFUNC_DEF(ComponentsDisplayHookFunc), NULL }; +static struct Hook ComponentsCompareHook = {{ NULL, NULL }, HOOKFUNC_DEF(ComponentsCompareHookFunc), NULL }; +static struct Hook ComponentToggleUpdateHook = {{ NULL, NULL }, HOOKFUNC_DEF(ComponentToggleUpdateHookFunc), NULL }; +static struct Hook ToggleShowAllHook = {{ NULL, NULL }, HOOKFUNC_DEF(ToggleShowAllHookFunc), NULL }; +static struct Hook CheckForUpdatesHook = {{ NULL, NULL }, HOOKFUNC_DEF(CheckForUpdatesHookFunc), NULL }; +static struct Hook StartUpdateUpdateHook = {{ NULL, NULL }, HOOKFUNC_DEF(StartUpdateUpdateHookFunc), NULL }; +static struct Hook SelectAllComponentsHook = {{ NULL, NULL }, HOOKFUNC_DEF(SelectAllComponentsHookFunc), NULL }; +static struct Hook DeselectAllComponentsHook = {{ NULL, NULL }, HOOKFUNC_DEF(DeselectAllComponentsHookFunc), NULL }; +static struct Hook SaveLogHook = {{ NULL, NULL }, HOOKFUNC_DEF(SaveLogHookFunc), NULL }; +static struct Hook AslIntuiMsgHook = {{ NULL, NULL }, HOOKFUNC_DEF(AslIntuiMsgHookFunc), NULL }; + +static CONST_STRPTR TempFilePath = "ram:"; +static CONST_STRPTR ScalosHttpAddr = "scalos.noname.fr"; + +static ULONG fAuto = FALSE; // Flag: Check for updates immediately on startup + // After completed Check for updates, start update automatically +static ULONG fUseProxy = FALSE; // Flag: use HTTP Proxy +static ULONG fUseProxyAuth = FALSE; // Flag: use username/password for proxy authentication +static ULONG fShowAllComponents = FALSE; // Flag: show all components +static ULONG fAskEveryUpdate = FALSE; // Flag: ask user for every updated component +static ULONG fQuiet = FALSE; // FLag: skip requester telling there are no updates +static CONST_STRPTR ProxyAddr = "proxy-host.com"; +static UWORD ProxyPort = 8080; +static CONST_STRPTR ProxyUser = "user"; +static CONST_STRPTR ProxyPasswd = "password"; + +static CONST_STRPTR VersTag = "\0$VER: Scalos Updater.module V" VERS_MAJOR "." VERS_MINOR " (" __DATE__ ") " COMPILER_STRING; + +DISPATCHER_PROTO(myComponentsNList); + +static struct MUI_CustomClass *myComponentsNListClass; + +#ifdef __AROS__ +#define myComponentsNListObject BOOPSIOBJMACRO_START(myComponentsNListClass->mcc_Class) +#else +#define myComponentsNListObject NewObject(myComponentsNListClass->mcc_Class, 0 +#endif + +static RSA *ScalosPubKeyRSA; // Scalos Public key for signature verification + +//---------------------------------------------------------------------------- + +static const struct MUIP_ScalosPrefs_MCCList RequiredMccList[] = + { + { MUIC_Lamp, 11, 1 }, + { MUIC_NListview, 18, 0 }, + { MUIC_TextEditor, 15, 28 }, + { NULL, 0, 0 } + }; + +static CONST_STRPTR RegisterTitles[] = + { + (CONST_STRPTR) MSGID_REGISTER_MAIN, + (CONST_STRPTR) MSGID_REGISTER_LOG, + (CONST_STRPTR) MSGID_REGISTER_CONFIGURATION, + NULL + }; + +// Context menu in components list +static struct NewMenu NewContextMenuComponents[] = + { + { NM_TITLE, (STRPTR) MSGID_MENU_COMPONENTS_TITLE, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_COMPONENTS_SELECT_ALL, NULL, 0, 0, (APTR) &SelectAllComponentsHook }, + { NM_ITEM, (STRPTR) MSGID_MENU_COMPONENTS_SELECT_NONE, NULL, 0, 0, (APTR) &DeselectAllComponentsHook }, + { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_ABOUT, NULL, 0, 0, (APTR) &AboutHook }, + + { NM_END, NULL, NULL, 0, 0, 0,}, + }; + +//---------------------------------------------------------------------------- + +int main(int argc, char *argv[]) +{ + const struct MUIP_ScalosPrefs_MCCList *mcc; + LONG win_opened = 0; + + WBenchMsg = (argc == 0) ? (struct WBStartup *)argv : NULL; + + if (!init()) + { + return 20; + } + + for (mcc = RequiredMccList; mcc->MccName; mcc++) + { + if (!CheckMCCVersion(mcc->MccName, mcc->MccMinVersion, mcc->MccMinRevision)) + { + d1(KPrintF(__FILE__ "/%s/%ld: CheckMCCVersion(%s) failed\n", __FUNC__, __LINE__, mcc->MccName)); + return 10; + } + } + + TranslateStringArray(RegisterTitles); + + ContextMenuComponents = MUI_MakeObject(MUIO_MenustripNM, (ULONG) NewContextMenuComponents, 0); + if (NULL == ContextMenuComponents) + { + fail(APP_Main, "Failed to create Collections Context Menu.", 20); + } +#if defined(M68K) && defined(__GNUC__) +#undef NewObject +#endif //defined(M68K) && defined(__GNUC__) + APP_Main = ApplicationObject, + MUIA_Application_Title, GetLocString(MSGID_TITLENAME), + MUIA_Application_Version, 1 + VersTag, + MUIA_Application_Copyright, "© The Scalos Team, 2009" CURRENTYEAR, + MUIA_Application_Author, "The Scalos Team", + MUIA_Application_Description, "Scalos Updater module", + MUIA_Application_Base, "SCALOS_UPDATER_MODULE", + + SubWindow, WIN_Main = WindowObject, + MUIA_Window_Title, GetLocString(MSGID_TITLENAME), + MUIA_Window_ID, MAKE_ID('M','A','I','N'), + MUIA_Window_AppWindow, TRUE, + + WindowContents, VGroup, + + Child, RegisterGroup(RegisterTitles), + + //------- Main page ---------------- + Child, VGroup, + MUIA_Background, MUII_RegisterBack, + + Child, NListviewObject, + MUIA_NListview_NList, NListComponents = myComponentsNListObject, + MUIA_NList_Format, ",BAR,BAR,BAR,BAR,BAR", + MUIA_Background, MUII_ListBack, + MUIA_NList_ConstructHook2, &ComponentsConstructHook, + MUIA_NList_DestructHook2, &ComponentsDestructHook, + MUIA_NList_DisplayHook2, &ComponentsDisplayHook, + MUIA_NList_CompareHook2, &ComponentsCompareHook, + MUIA_NList_AdjustWidth, TRUE, + MUIA_NList_Title, TRUE, + MUIA_NList_TitleSeparator, TRUE, + MUIA_NList_SortType, 1, + MUIA_NList_TitleMark, MUIV_NList_TitleMark_Down | 3, + MUIA_ContextMenu, ContextMenuComponents, + End, //NListObject + End, //NListviewObject + + Child, NListviewObject, + MUIA_ShowMe, FALSE, + MUIA_NListview_NList, NListHiddenComponents = myComponentsNListObject, + MUIA_NList_Format, ",BAR,BAR,BAR,BAR,BAR", + MUIA_Background, MUII_ListBack, + MUIA_NList_ConstructHook2, &ComponentsConstructHook, + MUIA_NList_DestructHook2, &ComponentsDestructHook, + MUIA_NList_DisplayHook2, &ComponentsDisplayHook, + MUIA_NList_CompareHook2, &ComponentsCompareHook, + MUIA_NList_AdjustWidth, TRUE, + MUIA_NList_Title, TRUE, + MUIA_NList_TitleSeparator, TRUE, + MUIA_NList_SortType, 1, + MUIA_NList_TitleMark, MUIV_NList_TitleMark_Down | 3, + MUIA_ContextMenu, ContextMenuComponents, + End, //NListObject + End, //NListviewObject + + Child, GroupSelection = HGroup, + Child, ColGroup(2), + Child, ButtonSelectAll = KeyButtonHelp(GetLocString(MSGID_BUTTON_SELECT_ALL), + GetLocString(MSGID_BUTTON_SELECT_ALL_SHORT), + GetLocString(MSGID_BUTTON_SELECT_ALL_HELP)), + Child, ButtonDeselectAll = KeyButtonHelp(GetLocString(MSGID_BUTTON_DESELECT_ALL), + GetLocString(MSGID_BUTTON_DESELECT_ALL_SHORT), + GetLocString(MSGID_BUTTON_DESELECT_ALL_HELP)), + End, //ColGroup + + Child, SelectedCountMsg = TextObject, + MUIA_Text_Contents, "", + MUIA_Text_PreParse, MUIX_C, + End, //TextObject + End, //HGroup + + Child, HGroup, + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, GaugeProgress = GaugeObject, + GaugeFrame, + MUIA_InputMode, MUIV_InputMode_None, + MUIA_ShowSelState, FALSE, + MUIA_Gauge_InfoText, "", + MUIA_Gauge_Horiz, TRUE, + MUIA_Gauge_Max, 100, + End, //GaugeObject + End, //HGroup + + + Child, GroupActionButtons = ColGroup(2), + Child, ButtonCheckForUpdates = KeyButtonHelp(GetLocString(MSGID_BUTTON_CHECKFORUPDATES), + GetLocString(MSGID_BUTTON_CHECKFORUPDATES_SHORT), + GetLocString(MSGID_BUTTON_CHECKFORUPDATES_HELP)), + Child, ButtonStartUpdate = KeyButtonHelp(GetLocString(MSGID_BUTTON_STARTUPDATE), + GetLocString(MSGID_BUTTON_STARTUPDATE_SHORT), + GetLocString(MSGID_BUTTON_STARTUPDATE_HELP)), + End, //HGroup + + End, //VGroup + + //------- Log page ---------------- + Child, VGroup, + MUIA_Background, MUII_RegisterBack, + + Child, HGroup, + GroupFrame, + MUIA_Background, MUII_GroupBack, + MUIA_FrameTitle, GetLocString(MSGID_GROUP_LOG), + Child, TextEditorLog = TextEditorObject, + TextFrame, + MUIA_Background, MUII_TextBack, + MUIA_TextEditor_ReadOnly, TRUE, + End, //TextEditorObject + Child, ScrollBarLog = ScrollbarObject, + MUIA_Background, MUII_PropBack, + SliderFrame, + End, //ScrollbarObject + End, //HGroup + + Child, ColGroup(2), + Child, ButtonClearLog = KeyButtonHelp(GetLocString(MSGID_BUTTON_CLEAR_LOG), + GetLocString(MSGID_BUTTON_CLEAR_LOG_SHORT), + GetLocString(MSGID_BUTTON_CLEAR_LOG_SHORTHELP)), + Child, ButtonSaveLog = KeyButtonHelp(GetLocString(MSGID_BUTTON_SAVE_LOG), + GetLocString(MSGID_BUTTON_SAVE_LOG_SHORT), + GetLocString(MSGID_BUTTON_SAVE_LOG_SHORTHELP)), + End, //HGroup + + + End, //VGroup + + //------- Configuration page ---------------- + Child, VGroup, + MUIA_Background, MUII_RegisterBack, + + Child, VGroup, + GroupFrame, + MUIA_Background, MUII_GroupBack, + MUIA_FrameTitle, GetLocString(MSGID_GROUP_PROXY), + Child, HGroup, + Child, Label1((ULONG) GetLocString(MSGID_CHECK_USE_PROXY)), + Child, HGroup, + Child, CheckUseProxy = CheckMark(fUseProxy), + Child, HVSpace, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_CHECK_USE_PROXY_SHORTHELP), + End, //HGroup + End, //HGroup, + Child, HGroup, + Child, Label2((ULONG) GetLocString(MSGID_STRING_PROXY_ADDR)), + Child, StringProxyAddr = StringObject, + StringFrame, + MUIA_Disabled, !fUseProxy, + MUIA_CycleChain, TRUE, + MUIA_String_Contents, ProxyAddr, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_STRING_PROXY_ADDR_SHORTHELP), + End, //StringObject + Child, Label2((ULONG) GetLocString(MSGID_STRING_PROXY_PORT)), + Child, StringProxyPort = StringObject, + MUIA_Weight, 25, + StringFrame, + MUIA_Disabled, !fUseProxy, + MUIA_CycleChain, TRUE, + MUIA_String_Integer, ProxyPort, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_STRING_PROXY_PORT_SHORTHELP), + End, //StringObject + End, //HGroup + + Child, HGroup, + Child, Label1((ULONG) GetLocString(MSGID_CHECK_USE_PROXYAUTH)), + Child, HGroup, + Child, CheckUseProxyAuth = ImageObject, + ImageButtonFrame, + MUIA_InputMode, MUIV_InputMode_Toggle, + MUIA_Image_Spec, MUII_CheckMark, + MUIA_Image_FreeVert, TRUE, + MUIA_Selected, fUseProxyAuth, + MUIA_Background, MUII_ButtonBack, + MUIA_ShowSelState, FALSE, + MUIA_Disabled, !fUseProxy, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_CHECK_USE_PROXYAUTH_SHORTHELP), + End, //Checkmark() + + Child, HVSpace, + End, //HGroup + End, //HGroup, + Child, HGroup, + Child, Label2((ULONG) GetLocString(MSGID_STRING_PROXY_USERNAME)), + Child, StringProxyUser = StringObject, + StringFrame, + MUIA_Disabled, !(fUseProxy && fUseProxyAuth), + MUIA_CycleChain, TRUE, + MUIA_String_Contents, ProxyUser, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_STRING_PROXY_USERNAME_SHORTHELP), + End, //StringObject + Child, Label2((ULONG) GetLocString(MSGID_STRING_PROXY_PASSWD)), + Child, StringProxyPwd = StringObject, + StringFrame, + MUIA_Disabled, !(fUseProxy && fUseProxyAuth), + MUIA_CycleChain, TRUE, + MUIA_String_Contents, ProxyPasswd, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_STRING_PROXY_PASSWD_SHORTHELP), + End, //StringObject + End, //HGroup + + End, //VGroup + + Child, HGroup, + GroupFrame, + MUIA_Background, MUII_GroupBack, + MUIA_FrameTitle, GetLocString(MSGID_STRING_SCALOS_SERVER), + + Child, StringScalosWebSite = StringObject, + StringFrame, + MUIA_CycleChain, TRUE, + MUIA_String_Contents, ScalosHttpAddr, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_STRING_SCALOS_SERVER_SHORTHELP), + End, //StringObject + End, //HGroup + + Child, HGroup, + GroupFrame, + MUIA_Background, MUII_GroupBack, + MUIA_FrameTitle, GetLocString(MSGID_POPASL_TEMPPATH), + + Child, PopAslTempPath = PopaslObject, + MUIA_Popstring_Button, PopButton(MUII_PopDrawer), + MUIA_Dropable, TRUE, + MUIA_Popstring_String, StringObject, + StringFrame, + MUIA_Background, MUII_TextBack, + MUIA_String_Contents, TempFilePath, + MUIA_CycleChain, TRUE, + End, //StringObject +// ASLFR_TitleText, (ULONG) GetLocString(MSGID_PATHSPAGE_SCALOS_HOME_ASLTITLE), +// MUIA_ShortHelp, (ULONG) GetLocString(MSGID_PATHSPAGE_SCALOS_HOME_SHORTHELP), + End, //PopaslObject + End, //HGroup + + Child, ColGroup(2), + GroupFrame, + MUIA_Background, MUII_GroupBack, + MUIA_FrameTitle, GetLocString(MSGID_GROUP_MISCELLANEOUS), + + Child, Label1((ULONG) GetLocString(MSGID_CHECK_SHOW_ALL_COMPONENTS)), + Child, HGroup, + Child, CheckShowAllComponents = CheckMark(fShowAllComponents), + Child, HVSpace, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_CHECK_SHOW_ALL_COMPONENTS_SHORTHELP), + End, //HGroup + + Child, Label1((ULONG) GetLocString(MSGID_CHECK_ASK_EVERY_UPDATE)), + Child, HGroup, + Child, CheckAskEveryUpdate = CheckMark(fAskEveryUpdate), + Child, HVSpace, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_CHECK_ASK_EVERY_UPDATE_SHORTHELP), + End, //HGroup + End, //ColGroup, + + End, //VGroup + //------------------------------------------- + + End, //RegisterGroup + + End, //VGroup + + End, //WindowObject + + MUIA_Application_Menustrip, MenustripObject, + Child, MenuObjectT(GetLocString(MSGID_MENU_PROJECT)), + + Child, MenuAbout = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUT), + End, + Child, MenuAboutMUI = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUTMUI), + End, + Child, MenuitemObject, + MUIA_Menuitem_Title, -1, + End, + Child, MenuQuit = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_QUIT), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_PROJECT_QUIT_SHORT), + End, + + End, //MenuObjectT + + End, //MenuStripObject + + End; //ApplicationObject + + if (NULL == APP_Main) + { + fail(APP_Main, "Failed to create Application.", 20); + } + + DoMethod(APP_Main, MUIM_Application_Load, MUIV_Application_Load_ENV); + + ParseArguments(); + + //--------------------------------------------------------------------------// + + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + WIN_Main, 3, MUIM_Set, MUIA_Window_Open, FALSE); + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + //--------------------------------------------------------------------------// + + DoMethod(MenuAbout, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &AboutHook); + DoMethod(MenuAboutMUI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &AboutMUIHook); + DoMethod(MenuQuit, MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + //--------------------------------------------------------------------------// + + // setup sorting hooks for NListComponents list + DoMethod(NListComponents, MUIM_Notify, MUIA_NList_TitleClick, MUIV_EveryTime, + NListComponents, 4, MUIM_NList_Sort3, MUIV_TriggerValue, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_Both); + DoMethod(NListComponents, MUIM_Notify, MUIA_NList_TitleClick2, MUIV_EveryTime, + NListComponents, 4, MUIM_NList_Sort3, MUIV_TriggerValue, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_2); + DoMethod(NListComponents, MUIM_Notify, MUIA_NList_SortType, MUIV_EveryTime, + NListComponents, 3, MUIM_Set, MUIA_NList_TitleMark, MUIV_TriggerValue); + DoMethod(NListComponents, MUIM_Notify, MUIA_NList_SortType2, MUIV_EveryTime, + NListComponents, 3, MUIM_Set, MUIA_NList_TitleMark2, MUIV_TriggerValue); + + //--------------------------------------------------------------------------// + + // toggle update selection buttons on click + DoMethod(NListComponents, MUIM_Notify, MUIA_NList_ButtonClick, MUIV_EveryTime, + NListComponents, 2, MUIM_CallHook, &ComponentToggleUpdateHook); + + // Enable proxy configuration if "Use Proxy" is selected + DoMethod(CheckUseProxy, MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + StringProxyAddr, 3, MUIM_Set, MUIA_Disabled, MUIV_NotTriggerValue); + DoMethod(CheckUseProxy, MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + StringProxyPort, 3, MUIM_Set, MUIA_Disabled, MUIV_NotTriggerValue); + DoMethod(CheckUseProxy, MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + CheckUseProxyAuth, 3, MUIM_Set, MUIA_Disabled, MUIV_NotTriggerValue); + + DoMethod(CheckUseProxyAuth, MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + StringProxyUser, 3, MUIM_Set, MUIA_Disabled, MUIV_NotTriggerValue); + DoMethod(CheckUseProxyAuth, MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + StringProxyPwd, 3, MUIM_Set, MUIA_Disabled, MUIV_NotTriggerValue); + + DoMethod(CheckShowAllComponents, MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + CheckShowAllComponents, 2, MUIM_CallHook, &ToggleShowAllHook); + + DoMethod(ButtonStartUpdate, MUIM_Notify, MUIA_Pressed, FALSE, + ButtonStartUpdate, 2, MUIM_CallHook, &StartUpdateUpdateHook); + DoMethod(ButtonCheckForUpdates, MUIM_Notify, MUIA_Pressed, FALSE, + ButtonCheckForUpdates, 2, MUIM_CallHook, &CheckForUpdatesHook); + + // Connect TextEditor object with its scrollbar + set(TextEditorLog, MUIA_TextEditor_Slider, (ULONG) ScrollBarLog); + + // Setup callback hooks for "Select All" and "Deselect All" buttons + DoMethod(ButtonSelectAll, MUIM_Notify, MUIA_Pressed, FALSE, + ButtonSelectAll, 2, MUIM_CallHook, &SelectAllComponentsHook); + DoMethod(ButtonDeselectAll, MUIM_Notify, MUIA_Pressed, FALSE, + ButtonDeselectAll, 2, MUIM_CallHook, &DeselectAllComponentsHook); + + // Clear log when button "Clear Log" is pressed + DoMethod(ButtonClearLog, MUIM_Notify, MUIA_Pressed, FALSE, + TextEditorLog, 1, MUIM_TextEditor_ClearText); + + // Call hook when button "Save Log" is pressed + DoMethod(ButtonSaveLog, MUIM_Notify, MUIA_Pressed, FALSE, + TextEditorLog, 2, MUIM_CallHook, &SaveLogHook); + + set(GroupSelection, MUIA_ShowMe, !fAuto); + set(GroupActionButtons, MUIA_ShowMe, !fAuto); + + UpdateSelectedCount(); + + if (!fAuto) + { + set(WIN_Main, MUIA_Window_Open, TRUE); + get(WIN_Main, MUIA_Window_Open, &win_opened); + } + + if (fAuto || win_opened) + { + ULONG sigs = 0; + BOOL Run = TRUE; + + if (fAuto) + { + CallHookPkt(&CheckForUpdatesHook, ButtonCheckForUpdates, NULL); + if (SelectedCount > 0) + { + LONG res; + + set(WIN_Main, MUIA_Window_Open, TRUE); + get(WIN_Main, MUIA_Window_Open, &win_opened); + + res = MUI_Request(APP_Main, WIN_Main, 0, NULL, + GetLocString(MSGID_REQ_INSTALL_UPDATES_GADGETS), + GetLocString(MSGID_REQ_INSTALL_UPDATES), + SelectedCount); + + if (1 == res) + CallHookPkt(&StartUpdateUpdateHook, ButtonStartUpdate, NULL); + } + + DoMethod(APP_Main, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + } + + while (Run && win_opened) + { + ULONG Action = DoMethod(APP_Main, MUIM_Application_NewInput, &sigs); + + switch (Action) + { + case MUIV_Application_ReturnID_Quit: + Run = FALSE; + break; + default: + break; + } + + if (Run && sigs) + { + sigs = Wait(sigs | SIGBREAKF_CTRL_C); + + if (sigs & SIGBREAKF_CTRL_C) + { + Run = FALSE; + } + } + } + } + else + { + printf("failed to open main window !\n"); + } + + set(WIN_Main, MUIA_Window_Open, FALSE); + + DoMethod(APP_Main, MUIM_Application_Save, MUIV_Application_Save_ENV); + DoMethod(APP_Main, MUIM_Application_Save, MUIV_Application_Save_ENVARC); + + fail(APP_Main, NULL, 0); + + return 0; +} + +//---------------------------------------------------------------------------- + +static VOID fail(APTR APP_Main, CONST_STRPTR str, int rc) +{ + if (SaveLogAslRequest) + { + MUI_FreeAslRequest(SaveLogAslRequest); + SaveLogAslRequest = NULL; + } + if (ScalosPubKeyRSA) + { + RSA_free(ScalosPubKeyRSA); + ScalosPubKeyRSA = NULL; + } + if (ContextMenuComponents) + { + MUI_DisposeObject(ContextMenuComponents); + ContextMenuComponents = NULL; + } + if (APP_Main) + { + MUI_DisposeObject(APP_Main); + } + if (FindCatalog) + { + CloseCatalog(FindCatalog); + FindCatalog = NULL; + } + if (myComponentsNListClass) + { + MUI_DeleteCustomClass(myComponentsNListClass); + myComponentsNListClass = NULL; + } + + if (str) + { + puts(str); + rc = 20; + } + + CloseLibraries(); + + exit(rc); +} + +//---------------------------------------------------------------------------- + +DISPATCHER(myComponentsNList) +{ + ULONG Result; + + d1(KPrintF(__FILE__ "/%s/%ld: MethodID=%08lx\n", __FUNC__, __LINE__, msg->MethodID)); + + switch(msg->MethodID) + { + case MUIM_ContextMenuChoice: + { + struct MUIP_ContextMenuChoice *cmc = (struct MUIP_ContextMenuChoice *) msg; + Object *MenuObj; + struct Hook *MenuHook = NULL; + + d1(kprintf("%s/%ld: MUIM_ContextMenuChoice item=%08lx\n", __FUNC__, __LINE__, cmc->item)); + + MenuObj = cmc->item; + + d1(kprintf("%s/%ld: MenuObj=%08lx\n", __FUNC__, __LINE__, MenuObj)); + d1(kprintf("%s/%ld: msg=%08lx *msg=%08lx\n", __FUNC__, __LINE__, msg, *((ULONG *) msg))); + + get(MenuObj, MUIA_UserData, &MenuHook); + + d1(kprintf("%s/%ld: MenuHook=%08lx\n", __FUNC__, __LINE__, MenuHook)); + if (MenuHook) + DoMethod(obj, MUIM_CallHook, MenuHook, 0); + + Result = 0; + } + break; + + default: + Result = DoSuperMethodA(cl, obj, msg); + } + + d1(KPrintF(__FILE__ "/%s/%ld: MethodID=%08lx Result=%ld\n", __FUNC__, __LINE__, msg->MethodID, Result)); + + return Result; +} +DISPATCHER_END + +//---------------------------------------------------------------------------- + +static BOOL init(void) +{ + CONST_STRPTR LibName = ""; + + if (!OpenLibraries(LibName)) + { + char ErrorString[100]; + + snprintf(ErrorString, sizeof(ErrorString), "Failed to open \"%s\".", LibName); + fail(NULL, ErrorString, 20); + } + + if (LocaleBase) + FindCatalog = OpenCatalogA(NULL, "Scalos/Updater.catalog", NULL); + + myComponentsNListClass = MUI_CreateCustomClass(NULL, MUIC_NList, + NULL, 0, DISPATCHER_REF(myComponentsNList)); + + TranslateNewMenu(NewContextMenuComponents); + + if (!MyInitAmiSSL()) + { + fail(NULL, "No AmiSSL", 20); + } + + ScalosPubKeyRSA = GetScalosPublicKey(); + if (NULL == ScalosPubKeyRSA) + { + fail(NULL, "Couldn't get Scalos Public Key!", 20); + } + + return TRUE; +} + +//---------------------------------------------------------------------------- + +static BOOL MyInitAmiSSL(void) +{ + BOOL Success = FALSE; + ULONG ErrMsgID; + + do { +#ifndef STATIC_SSL + AmiSSLMasterBase = OpenLibrary("amisslmaster.library", AMISSLMASTER_MIN_VERSION); + if (NULL == AmiSSLMasterBase) + { + ErrMsgID = MSGID_AMISSL_LIBOPEN_FAIL_AMISSLMASTER; + break; + } +#endif + +#ifdef __amigaos4__ + IAmiSSLMaster = (struct AmiSSLMasterIFace *)GetInterface(AmiSSLMasterBase, "main", 1, NULL); + if (NULL == IAmiSSLMaster) + { + ErrMsgID = MSGID_AMISSL_FAIL_AMISSLMASTER_INTERFACE; + break; + } +#endif //__amigaos4__ + +#ifndef STATIC_SSL + if (!InitAmiSSLMaster(AMISSL_CURRENT_VERSION, TRUE)) + { + ErrMsgID = MSGID_AMISSL_FAIL_INITAMISSLMASTER; + break; + } + + AmiSSLBase = OpenAmiSSL(); + if (NULL == AmiSSLBase) + { + ErrMsgID = MSGID_AMISSL_FAIL_OPENAMISSL; + break; + } +#endif + +#ifdef __amigaos4__ + IAmiSSL = (struct AmiSSLIFace *)GetInterface(AmiSSLBase, "main", 1, NULL); + if (NULL == IAmiSSL) + { + ErrMsgID = MSGID_AMISSL_FAIL_AMISSL_INTERFACE; + break; + } +#endif //__amigaos4__ + +#ifndef STATIC_SSL + if (0 != InitAmiSSL(AmiSSL_ErrNoPtr, (ULONG) &errno, + TAG_END)) + { + ErrMsgID = MSGID_AMISSL_FAIL_INITAMISSL; + break; + } +#endif + + Success = TRUE; + } while (0); + + if (!Success) + { + MUI_Request(APP_Main, WIN_Main, 0, NULL, + GetLocString(MSGID_ABOUTREQOK), + GetLocString(MSGID_AMISSL_FAIL_REQ_FORMAT), + (ULONG) GetLocString(ErrMsgID)); + } + + return Success; +} + +//---------------------------------------------------------------------------- + +static BOOL OpenLibraries(CONST_STRPTR LibName) +{ + LibName = DOSNAME; + DOSBase = (struct DosLibrary *) OpenLibrary(LibName, 39); + if (NULL == DOSBase) + return FALSE; +#ifdef __amigaos4__ + IDOS = (struct DOSIFace *)GetInterface((struct Library *)DOSBase, "main", 1, NULL); + if (NULL == IDOS) + return FALSE; +#endif //__amigaos4__ + + LibName = "utility.library"; + UtilityBase = (APTR) OpenLibrary(LibName, 39 ); + if (NULL == UtilityBase) + return FALSE; +#ifdef __amigaos4__ + IUtility = (APTR) GetInterface((struct Library *)UtilityBase, "main", 1, NULL); + if (NULL == IUtility) + return FALSE; +#endif /* __amigaos4__ */ + + LibName = "intuition.library"; + IntuitionBase = (struct IntuitionBase *) OpenLibrary(LibName, 39); + if (NULL == IntuitionBase) + return FALSE; +#ifdef __amigaos4__ + else + { + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + return FALSE; + } +#endif //__amigaos4__ + + LibName = MUIMASTER_NAME; + MUIMasterBase = OpenLibrary(LibName, MUIMASTER_VMIN-1); + if (NULL == MUIMasterBase) + return FALSE; +#ifdef __amigaos4__ + else + { + IMUIMaster = (struct MUIMasterIFace *)GetInterface((struct Library *)MUIMasterBase, "main", 1, NULL); + if (NULL == IMUIMaster) + return FALSE; + } +#endif //__amigaos4__ + + LibName = "bsdsocket.library"; + SocketBase = OpenLibrary(LibName, 0); + if (NULL == SocketBase) + return FALSE; +#ifdef __amigaos4__ + else + { + ISocket = (struct SocketIFace *)GetInterface(SocketBase, "main", 1, NULL); + if (NULL == ISocket) + return FALSE; + } +#endif //__amigaos4__ + + + LibName = "scalos.library"; + ScalosBase = (struct ScalosBase *) OpenLibrary(LibName, 40); + if (NULL == ScalosBase) + return FALSE; +#ifdef __amigaos4__ + else + { + IScalos = (struct ScalosIFace *)GetInterface((struct Library *)ScalosBase, "main", 1, NULL); + if (NULL == IScalos) + return FALSE; + } +#endif //__amigaos4__ + + LibName = "locale.library"; + LocaleBase = (T_LOCALEBASE) OpenLibrary(LibName, 39); +#ifdef __amigaos4__ + if (NULL != LocaleBase) + { + ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL); + if (NULL == ILocale) + return FALSE; + } +#endif //__amigaos4__ + + TimerPort = CreateMsgPort(); + TimerIO = (T_TIMEREQUEST *)CreateIORequest(TimerPort, sizeof(T_TIMEREQUEST)); + if (NULL == TimerIO) + return FALSE; + + LibName = "timer.device"; + OpenDevice(LibName, UNIT_VBLANK, &TimerIO->tr_node, 0); + TimerBase = (T_TIMERBASE) TimerIO->tr_node.io_Device; + if (NULL == TimerBase) + return FALSE; +#ifdef __amigaos4__ + ITimer = (struct TimerIFace *)GetInterface((struct Library *)TimerBase, "main", 1, NULL); + if (NULL == ITimer) + return FALSE; +#endif //__amigaos4__ + + LibName = "icon.library"; + IconBase = OpenLibrary(LibName, 39); + if (NULL == IconBase) + return FALSE; +#ifdef __amigaos4__ + IIcon = (struct IconIFace *)GetInterface(IconBase, "main", 1, NULL); + if (NULL == IIcon) + return FALSE; +#endif //__amigaos4__ + + return TRUE; +} + +//---------------------------------------------------------------------------- + +static void CloseLibraries(void) +{ +#ifdef __amigaos4__ + if (IIcon) + { + DropInterface((struct Interface *)IIcon); + IIcon = NULL; + } +#endif + if (IconBase) + { + CloseLibrary(IconBase); + IconBase = NULL; + } + +#ifndef STATIC_SSL + if (AmiSSLBase) + { +#ifdef __amigaos4__ + if (IAmiSSL) + { + CleanupAmiSSL(TAG_DONE); + DropInterface((struct Interface *)IAmiSSL); + IAmiSSL = NULL; + } +#else //__amigaos4__ + CleanupAmiSSL(TAG_END); +#endif //__amigaos4__ + + CloseAmiSSL(); + AmiSSLBase = NULL; + } + +#ifdef __amigaos4__ + DropInterface((struct Interface *)IAmiSSLMaster); + IAmiSSLMaster = NULL; +#endif //__amigaos4__ + + CloseLibrary(AmiSSLMasterBase); + AmiSSLMasterBase = NULL; +#endif //STATIC_SSL + + if (TimerIO) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)ITimer); +#endif + CloseDevice(&TimerIO->tr_node); + DeleteIORequest(&TimerIO->tr_node); + + TimerIO = NULL; + TimerBase = NULL; + } + if (TimerPort) + { + DeleteMsgPort(TimerPort); + TimerPort = NULL; + } +#ifdef __amigaos4__ + if (IDOS) + { + DropInterface((struct Interface *)IDOS); + IDOS = NULL; + } +#endif //__amigaos4__ + if (DOSBase) + { + CloseLibrary((struct Library *) DOSBase); + //DOSBase = NULL; // do NOT clear DOSBase - it is still required for AmigaOS3/GCC + } + if (LocaleBase) + { + if (FindCatalog) + { + CloseCatalog(FindCatalog); + FindCatalog = NULL; + } +#ifdef __amigaos4__ + if (ILocale) + { + DropInterface((struct Interface *)ILocale); + ILocale = NULL; + } +#endif + CloseLibrary((struct Library *) LocaleBase); + LocaleBase = NULL; + } + +#ifdef __amigaos4__ + if (ISocket) + { + DropInterface((struct Interface *)ISocket); + ISocket = NULL; + } +#endif + if (SocketBase) + { + CloseLibrary((struct Library *) SocketBase); + SocketBase = NULL; + } + +#ifdef __amigaos4__ + if (IScalos) + { + DropInterface((struct Interface *)IScalos); + IScalos = NULL; + } +#endif + if (ScalosBase) + { + CloseLibrary((struct Library *) ScalosBase); + ScalosBase = NULL; + } +#ifdef __amigaos4__ + if (IMUIMaster) + { + DropInterface((struct Interface *)IMUIMaster); + IMUIMaster = NULL; + } +#endif + if (MUIMasterBase) + { + CloseLibrary(MUIMasterBase); + MUIMasterBase = NULL; + } +#ifdef __amigaos4__ + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } +#endif + if (IntuitionBase) + { + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } +#ifdef __amigaos4__ + if (IUtility) + { + DropInterface((struct Interface *)IUtility); + IUtility = NULL; + } +#endif /* __amigaos4__ */ + if (UtilityBase) + { + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } +} + +//---------------------------------------------------------------------------- + +static STRPTR GetLocString(ULONG MsgId) +{ + struct Updater_LocaleInfo li; + + li.li_Catalog = FindCatalog; +#ifndef __amigaos4__ + li.li_LocaleBase = LocaleBase; +#else + li.li_ILocale = ILocale; +#endif + + return (STRPTR)GetUpdaterString(&li, MsgId); +} + +//---------------------------------------------------------------------------- + +static void TranslateStringArray(CONST_STRPTR *stringArray) +{ + while (*stringArray) + { + *stringArray = GetLocString((ULONG) *stringArray); + stringArray++; + } +} + +//---------------------------------------------------------------------------- + +static void TranslateNewMenu(struct NewMenu *nm) +{ + while (nm && NM_END != nm->nm_Type) + { + if (NM_BARLABEL != nm->nm_Label) + nm->nm_Label = GetLocString((ULONG) nm->nm_Label); + + if (nm->nm_CommKey) + nm->nm_CommKey = GetLocString((ULONG) nm->nm_CommKey); + + nm++; + } +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT OpenAboutMUIFunc(struct Hook *hook, Object *o, Msg msg) +{ + if (NULL == WIN_AboutMUI) + { + WIN_AboutMUI = MUI_NewObject(MUIC_Aboutmui, + MUIA_Window_RefWindow, WIN_Main, + MUIA_Aboutmui_Application, APP_Main, + TAG_END); + } + + if (WIN_AboutMUI) + set(WIN_AboutMUI, MUIA_Window_Open, TRUE); + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT OpenAboutFunc(struct Hook *hook, Object *o, Msg msg) +{ + MUI_Request(APP_Main, WIN_Main, 0, NULL, + GetLocString(MSGID_ABOUTREQOK), + GetLocString(MSGID_ABOUTREQFORMAT), + VERSION_MAJOR, VERSION_MINOR, (ULONG) COMPILER_STRING, (ULONG) CURRENTYEAR); +} + +//---------------------------------------------------------------------------- + +// Checks if a certain version of a MCC is available +BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev) +{ + BOOL flush = TRUE; + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: %s ", __LINE__, name);) + + while (1) + { + ULONG ver = 0; + ULONG rev = 0; + struct Library *base; + char libname[256]; + + // First we attempt to acquire the version and revision through MUI + Object *obj = MUI_NewObject((STRPTR) name, TAG_DONE); + if (obj) + { + get(obj, MUIA_Version, &ver); + get(obj, MUIA_Revision, &rev); + + MUI_DisposeObject(obj); + + if(ver > minver || (ver == minver && rev >= minrev)) + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: v%ld.%ld found through MUIA_Version/Revision\n", __LINE__, ver, rev);) + return TRUE; + } + } + + // If we did't get the version we wanted, let's try to open the + // libraries ourselves and see what happens... + stccpy(libname, "PROGDIR:mui", sizeof(libname)); + AddPart(libname, name, sizeof(libname)); + + if ((base = OpenLibrary(&libname[8], 0)) || (base = OpenLibrary(&libname[0], 0))) + { + UWORD OpenCnt = base->lib_OpenCnt; + + ver = base->lib_Version; + rev = base->lib_Revision; + + CloseLibrary(base); + + // we add some additional check here so that eventual broken .mcc also have + // a chance to pass this test (i.e. Toolbar.mcc is broken) + if (ver > minver || (ver == minver && rev >= minrev)) + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: v%ld.%ld found through OpenLibrary()\n", __LINE__, ver, rev);) + return TRUE; + } + + if (OpenCnt > 1) + { + if (MUI_Request(NULL, NULL, 0L, + (STRPTR) GetLocString(MSGID_STARTUP_FAILURE), + (STRPTR) GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), + (STRPTR) GetLocString(MSGID_STARTUP_MCC_IN_USE), + (ULONG) name, minver, minrev, ver, rev)) + { + flush = TRUE; + } + else + break; + } + + // Attempt to flush the library if open count is 0 or because the + // user wants to retry (meaning there's a chance that it's 0 now) + + if (flush) + { + struct Library *result; + extern struct ExecBase *SysBase; + + Forbid(); + if ((result = (struct Library *) FindName(&SysBase->LibList, name))) + RemLibrary(result); + Permit(); + flush = FALSE; + } + else + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: couldn`t find minimum required version.\n", __LINE__);) + + // We're out of luck - open count is 0, we've tried to flush + // and still haven't got the version we want + if (MUI_Request(NULL, NULL, 0L, + (STRPTR) GetLocString(MSGID_STARTUP_FAILURE), + (STRPTR) GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), + (STRPTR) GetLocString(MSGID_STARTUP_OLD_MCC), + (ULONG) name, minver, minrev, ver, rev)) + { + flush = TRUE; + } + else + break; + } + } + else + { + // No MCC at all - no need to attempt flush + flush = FALSE; + if (!MUI_Request(NULL, NULL, 0L, + (STRPTR) GetLocString(MSGID_STARTUP_FAILURE), + (STRPTR) GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), + (STRPTR) GetLocString(MSGID_STARTUP_MCC_NOT_FOUND), + (ULONG) name, minver, minrev)) + { + break; + } + } + } + + return FALSE; +} + +//---------------------------------------------------------------------------- + +static BOOL ProcessVersionFile(CONST_STRPTR text, size_t len) +{ + BOOL Success = FALSE; + ULONG ShowAllComponents = 0; + size_t TotalLen = len; + + d1(KPrintF("%s/%s/%ld: Received data\n", __FILE__, __FUNC__, __LINE__)); + d1(KPrintF("%s/%s/%ld: =======================\n", __FILE__, __FUNC__, __LINE__)); + + get(CheckShowAllComponents, MUIA_Selected, &ShowAllComponents); + + while (len) + { + size_t LineLen = 0; + + while (len && '\n' != text[LineLen]) + { + LineLen++; + len--; + } + + set(GaugeProgress, MUIA_Gauge_Current, 100 - (50 * len) / TotalLen); + + // Skip empty lines, and comment lines. + if (LineLen && ';' != *text && '#' != *text) + { + enum { ARG_DIR, ARG_FILE, ARG_VERSION, ARG_PKG, ARG_OS, ARG_HASH }; + static CONST_STRPTR Template = "DIR/A/K,FILE/A/K,VERSION/A/K,PKG/K,OS/A/K,HASH/K"; + struct RDArgs *ReadArgs; + SIPTR Args[6]; + + memset(Args, 0, sizeof(Args)); + + ReadArgs = AllocDosObject(DOS_RDARGS, NULL); + if (ReadArgs) + { + ReadArgs->RDA_Source.CS_Buffer = (STRPTR) text; + ReadArgs->RDA_Source.CS_Length = LineLen; + ReadArgs->RDA_Source.CS_CurChr = 0; + ReadArgs->RDA_Flags |= RDAF_NOPROMPT; + + if (ReadArgs(Template, Args, ReadArgs)) + { + struct ComponentListEntry cle; + + Success = TRUE; + + cle.cle_Dir = (STRPTR) Args[ARG_DIR]; + cle.cle_File = (STRPTR) Args[ARG_FILE]; + cle.cle_Package = (STRPTR) Args[ARG_PKG]; + cle.cle_Hash = (STRPTR) Args[ARG_HASH]; + cle.cle_Selected = FALSE; + + d1(KPrintF("%s/%s/%ld: DIR=<%s> FILE=<%s> VERSION=<%s> PKG=<%s> OS=<%s>\n", __FILE__, __FUNC__, __LINE__, \ + Args[ARG_DIR], Args[ARG_FILE], Args[ARG_VERSION], Args[ARG_PKG], Args[ARG_OS])); + + if (0 == strcmp(OsName, (STRPTR) Args[ARG_OS])) + { + unsigned long ulong1, ulong2, ulong3; + cle.cle_RemoteVersion = cle.cle_RemoteRevision = cle.cle_RemotePatchLevel = 0; + + if (sscanf((STRPTR) Args[ARG_VERSION], "%lu.%lu.%lu", &ulong1, &ulong2, &ulong3) >= 2) + { + char VersionString[80]; + + cle.cle_RemoteVersion = ulong1; + cle.cle_RemoteRevision = ulong2; + cle.cle_RemotePatchLevel = ulong3; + + if (':' == cle.cle_Dir[strlen(cle.cle_Dir) - 1]) + GetAssignListVersionString(cle.cle_Dir, cle.cle_File, VersionString, sizeof(VersionString)); + else + GetFileVersionString(cle.cle_Dir, cle.cle_File, VersionString, sizeof(VersionString)); + + d1(KPrintF("%s/%s/%ld: VersionString=<%s>\n", __FILE__, __FUNC__, __LINE__, VersionString)); + + ExtractVersionNumberFromVersionString(VersionString, + &cle.cle_LocalVersion, &cle.cle_LocalRevision, &cle.cle_LocalPatchLevel); + + d1(KPrintF("%s/%s/%ld: cle_LocalVersion=%lu cle_LocalRevision=%lu cle_LocalPatchLevel=%lu\n", __FILE__, __FUNC__, __LINE__, cle.cle_LocalVersion, cle.cle_LocalRevision, cle.cle_LocalPatchLevel)); + + cle.cle_Selected = (cle.cle_LocalVersion < cle.cle_RemoteVersion) + || ((cle.cle_LocalVersion == cle.cle_RemoteVersion) + && (cle.cle_LocalRevision < cle.cle_RemoteRevision)) + || ((cle.cle_LocalVersion == cle.cle_RemoteVersion) + && (cle.cle_LocalRevision == cle.cle_RemoteRevision) + && (cle.cle_LocalPatchLevel < cle.cle_RemotePatchLevel) ); + + if (cle.cle_Selected) + SelectedCount++; + + if (cle.cle_Selected || ShowAllComponents) + { + DoMethod(NListComponents, MUIM_NList_InsertSingle, + &cle, MUIV_NList_Insert_Sorted); + } + else + { + DoMethod(NListHiddenComponents, MUIM_NList_InsertSingle, + &cle, MUIV_NList_Insert_Sorted); + } + } + } + + FreeArgs(ReadArgs); + } + else + { + d1(KPrintF("%s/%s/%ld: ReadArgs failed IoErr=%ld\n", __FILE__, __FUNC__, __LINE__, IoErr())); + d1(KPrintF("%s/%s/%ld: text=<%s>\n", __FILE__, __FUNC__, __LINE__, text)); + } + + FreeDosObject(DOS_RDARGS, ReadArgs); + } + } + + text += LineLen; + + // Skip '\n' + len--; + text++; + } + + d1(KPrintF("%s/%s/%ld: =======================\n", __FILE__, __FUNC__, __LINE__)); + + return Success; +} + +//---------------------------------------------------------------------------- + +static size_t VersionFileWrite( void *ptr, size_t size, size_t nmemb, void *stream) +{ + struct VersionFileHandle *vfh = (struct VersionFileHandle *) stream; + size_t BytesWritten = 0; + + if (vfh) + { + size_t DataLength = size * nmemb; + + if ((vfh->vfh_CurrentLength + DataLength) > vfh->vfh_AllocatedLength) + { + size_t NewSize = vfh->vfh_AllocatedLength + DataLength + 32768; + + vfh->vfh_AllocatedBuffer = realloc(vfh->vfh_AllocatedBuffer, NewSize); + vfh->vfh_AllocatedLength = NewSize; + vfh->vfh_BuffPtr = vfh->vfh_AllocatedBuffer + vfh->vfh_CurrentLength; + } + if (vfh->vfh_AllocatedBuffer) + { + memcpy(vfh->vfh_BuffPtr, ptr, DataLength); + vfh->vfh_BuffPtr += DataLength; + vfh->vfh_CurrentLength += DataLength; + vfh->vfh_TotalLength = vfh->vfh_CurrentLength; + BytesWritten = DataLength; + } + } + + return BytesWritten; +} + +//---------------------------------------------------------------------------- + +static APTR ComponentsConstructHookFunc(struct Hook *hook, Object *obj, struct NList_ConstructMessage *msg) +{ + struct ComponentListEntry *cle = AllocPooled(msg->pool, sizeof(struct ComponentListEntry)); + + if (cle) + { + const struct ComponentListEntry *cleIn = (struct ComponentListEntry *) msg->entry; + + cle->cle_Dir = strdup(cleIn->cle_Dir); + cle->cle_File = strdup(cleIn->cle_File); + cle->cle_Package = strdup(cleIn->cle_Package); + cle->cle_Hash = strdup(cleIn->cle_Hash); + + cle->cle_RemoteVersion = cleIn->cle_RemoteVersion; + cle->cle_RemoteRevision = cleIn->cle_RemoteRevision; + cle->cle_RemotePatchLevel = cleIn->cle_RemotePatchLevel; + cle->cle_LocalVersion = cleIn->cle_LocalVersion; + cle->cle_LocalRevision = cleIn->cle_LocalRevision; + cle->cle_LocalPatchLevel = cleIn->cle_LocalPatchLevel; + cle->cle_Selected = cleIn->cle_Selected; + cle->cle_CheckboxImageNr = ++globalImageNr; + cle->cle_LampImageNr = ++globalImageNr; + + cle->cle_LampObject = LampObject, + MUIA_Lamp_Type, MUIV_Lamp_Type_Huge, + MUIA_Lamp_Color, cle->cle_Selected ? MUIV_Lamp_Color_LoadingData : MUIV_Lamp_Color_Off, + End; + + cle->cle_CheckboxObject = ImageObject, + MUIA_Image_Spec, MUII_CheckMark, + ImageButtonFrame, + MUIA_CycleChain, TRUE, + MUIA_InputMode, MUIV_InputMode_Toggle, + MUIA_Selected, cle->cle_Selected, + MUIA_Background, MUII_ButtonBack, + MUIA_ShowSelState, FALSE, + End; + + DoMethod(obj, MUIM_NList_UseImage, cle->cle_LampObject, cle->cle_LampImageNr, 0); + DoMethod(obj, MUIM_NList_UseImage, cle->cle_CheckboxObject, cle->cle_CheckboxImageNr, 0); + + if (cle->cle_LocalPatchLevel) + snprintf(cle->cle_LocalVersionString, sizeof(cle->cle_LocalVersionString), "%lu.%lu.%lu", (unsigned long) cle->cle_LocalVersion, (unsigned long) cle->cle_LocalRevision, (unsigned long) cle->cle_LocalPatchLevel); + else + snprintf(cle->cle_LocalVersionString, sizeof(cle->cle_LocalVersionString), "%lu.%lu", (unsigned long) cle->cle_LocalVersion, (unsigned long) cle->cle_LocalRevision); + if (cle->cle_RemotePatchLevel) + snprintf(cle->cle_RemoteVersionString, sizeof(cle->cle_RemoteVersionString), "%lu.%lu.%lu", (unsigned long) cle->cle_RemoteVersion, (unsigned long) cle->cle_RemoteRevision, (unsigned long) cle->cle_RemotePatchLevel); + else + snprintf(cle->cle_RemoteVersionString, sizeof(cle->cle_RemoteVersionString), "%lu.%lu", (unsigned long) cle->cle_RemoteVersion, (unsigned long) cle->cle_RemoteRevision); + + snprintf(cle->cle_CheckboxImageNrString, sizeof(cle->cle_CheckboxImageNrString), "\33o[%ld@%ld|0]", (long) cle->cle_CheckboxImageNr, (long) cle->cle_CheckboxImageNr); + snprintf(cle->cle_LampImageNrString, sizeof(cle->cle_LampImageNrString), "\33o[%ld]", (long) cle->cle_LampImageNr); + } + + return cle; +} + +static void ComponentsDestructHookFunc(struct Hook *hook, Object *obj, struct NList_DestructMessage *msg) +{ + if (msg->entry) + { + struct ComponentListEntry *cle = (struct ComponentListEntry *) msg->entry; + + if (cle->cle_Hash) + free(cle->cle_Hash); + if (cle->cle_Package) + free(cle->cle_Package); + if (cle->cle_Dir) + free(cle->cle_Dir); + if (cle->cle_File) + free(cle->cle_File); + + if (cle->cle_CheckboxObject) + { + DoMethod(obj, MUIM_NList_UseImage, NULL, cle->cle_CheckboxImageNr, 0); + MUI_DisposeObject(cle->cle_CheckboxObject); + cle->cle_CheckboxObject = NULL; + } + if (cle->cle_LampObject) + { + DoMethod(obj, MUIM_NList_UseImage, NULL, cle->cle_LampImageNr, 0); + MUI_DisposeObject(cle->cle_LampObject); + cle->cle_LampObject = NULL; + } + FreePooled(msg->pool, msg->entry, sizeof(struct ComponentListEntry)); + } +} + +static ULONG ComponentsDisplayHookFunc(struct Hook *hook, Object *obj, struct NList_DisplayMessage *msg) +{ + if (msg->entry) + { + struct ComponentListEntry *cle = (struct ComponentListEntry *) msg->entry; + + msg->strings[0] = cle->cle_LampImageNrString; + msg->strings[1] = cle->cle_CheckboxImageNrString; + msg->strings[2] = cle->cle_Dir; + msg->strings[3] = cle->cle_File; + msg->strings[4] = cle->cle_RemoteVersionString; + msg->strings[5] = cle->cle_LocalVersionString; + + msg->preparses[0] = MUIX_C; + + if (0 == cle->cle_LocalVersion) + { + // local version not available + msg->preparses[2] = msg->preparses[3] = + msg->preparses[4] = msg->preparses[5] = MUIX_I; + } + else if ( (cle->cle_LocalVersion < cle->cle_RemoteVersion) || + (cle->cle_LocalVersion == cle->cle_RemoteVersion && cle->cle_LocalRevision < cle->cle_RemoteRevision) ) + { + // needs to be updated + msg->preparses[2] = msg->preparses[3] = + msg->preparses[4] = msg->preparses[5] = MUIX_B; + } + else if ( (cle->cle_LocalVersion == cle->cle_RemoteVersion) && (cle->cle_LocalRevision == cle->cle_RemoteRevision) ) + { + // versions match + msg->preparses[2] = msg->preparses[3] = + msg->preparses[4] = msg->preparses[5] = MUIX_N; + } + else + { + // Huh? + // Local version newer than remote version + msg->preparses[2] = msg->preparses[3] = + msg->preparses[4] = msg->preparses[5] = MUIX_PH; + } + } + else + { + // display titles + msg->strings[0] = " "; + msg->strings[1] = GetLocString(MSGID_COMPONENTLIST_UPDATE); ; + msg->strings[2] = GetLocString(MSGID_COMPONENTLIST_DIRECTORY); + msg->strings[3] = GetLocString(MSGID_COMPONENTLIST_FILE); + msg->strings[4] = GetLocString(MSGID_COMPONENTLIST_LATEST_VERSION); + msg->strings[5] = GetLocString(MSGID_COMPONENTLIST_INSTALLED_VERSION); + } + + return 0; +} + +static LONG ComponentsCompareHookFunc(struct Hook *hook, Object *obj, struct NList_CompareMessage *ncm) +{ + const struct ComponentListEntry *cle1 = (const struct ComponentListEntry *) ncm->entry1; + const struct ComponentListEntry *cle2 = (const struct ComponentListEntry *) ncm->entry2; + LONG col1 = ncm->sort_type & MUIV_NList_TitleMark_ColMask; + LONG col2 = ncm->sort_type2 & MUIV_NList_TitleMark2_ColMask; + LONG Result = 0; + + if (ncm->sort_type != MUIV_NList_SortType_None) + { + // primary sorting + switch (col1) + { + case 2: // sort by directory + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = Stricmp(cle2->cle_Dir, cle1->cle_Dir); + else + Result = Stricmp(cle1->cle_Dir, cle2->cle_Dir); + break; + case 3: // sort by filename + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = Stricmp(cle2->cle_File, cle1->cle_File); + else + Result = Stricmp(cle1->cle_File, cle2->cle_File); + break; + case 4: // sort by version + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = cle2->cle_RemoteVersion - cle1->cle_RemoteVersion; + else + Result = cle1->cle_RemoteVersion - cle2->cle_RemoteVersion; + break; + case 5: // sort by revision + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = cle2->cle_RemoteRevision - cle1->cle_RemoteRevision; + else + Result = cle1->cle_RemoteRevision - cle2->cle_RemoteRevision; + break; + default: + break; + } + + if (0 == Result && col1 != col2) + { + // Secondary sorting + switch (col2) + { + case 2: // sort by directory + if (ncm->sort_type2 & MUIV_NList_TitleMark2_TypeMask) + Result = Stricmp(cle2->cle_Dir, cle1->cle_Dir); + else + Result = Stricmp(cle1->cle_Dir, cle2->cle_Dir); + break; + case 3: // sort by filename + if (ncm->sort_type2 & MUIV_NList_TitleMark2_TypeMask) + Result = Stricmp(cle2->cle_File, cle1->cle_File); + else + Result = Stricmp(cle1->cle_File, cle2->cle_File); + break; + case 4: // sort by version + if (ncm->sort_type2 & MUIV_NList_TitleMark2_TypeMask) + Result = cle2->cle_RemoteVersion - cle1->cle_RemoteVersion; + else + Result = cle1->cle_RemoteVersion - cle2->cle_RemoteVersion; + break; + case 5: // sort by revision + if (ncm->sort_type2 & MUIV_NList_TitleMark2_TypeMask) + Result = cle2->cle_RemoteRevision - cle1->cle_RemoteRevision; + else + Result = cle1->cle_RemoteRevision - cle2->cle_RemoteRevision; + break; + default: + break; + } + } + } + + return Result; +} + +//---------------------------------------------------------------------------- + +static void ComponentToggleUpdateHookFunc(struct Hook *hook, Object *obj, Msg *msg) +{ + ULONG ButtonNr = 0; + ULONG Entries = 0; + ULONG n; + + get(NListComponents, MUIA_NList_ButtonClick, &ButtonNr); + + d1(KPrintF("%s/%s/%ld: Button clicked, n=%ld\n", __FILE__, __FUNC__, __LINE__, ButtonNr)); + + get(NListComponents, MUIA_NList_Entries, &Entries); + + for (n = 0; n < Entries; n++) + { + struct ComponentListEntry *cle = NULL; + + DoMethod(NListComponents, MUIM_NList_GetEntry, + n, &cle); + if (cle && cle->cle_CheckboxImageNr == ButtonNr) + { + cle->cle_Selected = !cle->cle_Selected; + set(cle->cle_CheckboxObject, MUIA_Selected, cle->cle_Selected); + set(cle->cle_LampObject, MUIA_Lamp_Color, cle->cle_Selected ? MUIV_Lamp_Color_LoadingData : MUIV_Lamp_Color_Off); + + if (cle->cle_Selected) + SelectedCount++; + else + SelectedCount--; + + d1(KPrintF("%s/%s/%ld: Selected=%ld\n", __FILE__, __FUNC__, __LINE__, cle->cle_Selected)); + DoMethod(NListComponents, MUIM_NList_RedrawEntry, cle); + + UpdateSelectedCount(); + } + } +} + +//---------------------------------------------------------------------------- + +static void ToggleShowAllHookFunc(struct Hook *hook, Object *obj, Msg *msg) +{ + ULONG ShowAll = 0; + ULONG Entries = 0; + + set(NListComponents, MUIA_NList_Quiet, TRUE); + set(NListHiddenComponents, MUIA_NList_Quiet, TRUE); + + get(CheckShowAllComponents, MUIA_Selected, &ShowAll); + + d1(KPrintF("%s/%s/%ld: Button clicked, n=%ld\n", __FILE__, __FUNC__, __LINE__, ButtonNr)); + + if (ShowAll) + { + // Move all entries from NListHiddenComponents to NListComponents + get(NListHiddenComponents, MUIA_NList_Entries, &Entries); + + while (Entries--) + { + struct ComponentListEntry *cle = NULL; + + DoMethod(NListHiddenComponents, MUIM_NList_GetEntry, 0, &cle); + + if (cle) + { + cle->cle_Selected = FALSE; + + DoMethod(NListComponents, MUIM_NList_InsertSingle, + cle, MUIV_NList_Insert_Sorted); + + DoMethod(NListHiddenComponents, MUIM_NList_Remove, 0); + } + } + DoMethod(NListComponents, MUIM_NList_ColWidth, MUIV_NList_ColWidth_All, MUIV_NList_ColWidth_Default); + } + else + { + // Move all entries from NListComponents to NListHiddenComponents + get(NListComponents, MUIA_NList_Entries, &Entries); + + while (Entries--) + { + struct ComponentListEntry *cle = NULL; + + DoMethod(NListComponents, MUIM_NList_GetEntry, 0, &cle); + + if (cle) + { + cle->cle_Selected = FALSE; + + DoMethod(NListHiddenComponents, MUIM_NList_InsertSingle, + cle, MUIV_NList_Insert_Sorted); + + DoMethod(NListComponents, MUIM_NList_Remove, 0); + } + } + } + + set(NListComponents, MUIA_NList_Quiet, FALSE); + set(NListHiddenComponents, MUIA_NList_Quiet, FALSE); + + SelectedCount = 0; + UpdateSelectedCount(); +} + +//---------------------------------------------------------------------------- + +static STRPTR GetAssignListVersionString(CONST_STRPTR Dir, CONST_STRPTR Filename, STRPTR VersionString, size_t MaxLen) +{ + STRPTR NameCopy = NULL; + + d1(KPrintF("%s/%s/%ld: Dir=<%s> Filename=<%s>\n", __FILE__, __FUNC__, __LINE__, Dir, Filename)); + + *VersionString = '\0'; + + do { + struct DosList *dl; + + GetFileVersionString(Dir, Filename, VersionString, MaxLen); + if (strlen(VersionString) > 0) + break; // found! + + NameCopy = strdup(Dir); + if (NULL == NameCopy) + break; + + NameCopy[strlen(NameCopy) - 1] = '\0'; // strip trailing ":" + + dl = LockDosList(LDF_ASSIGNS | LDF_READ); + + if (dl = FindDosEntry(dl, NameCopy, LDF_ASSIGNS)) + { + struct AssignList *asl; + + d1(KPrintF("%s/%s/%ld: dl=%08lx\n", __FILE__, __FUNC__, __LINE__, dl, dl->dol_misc.dol_assign.dol_AssignName)); + asl = dl->dol_misc.dol_assign.dol_List; + + while (asl) + { + char AssignDirName[300]; + + debugLock_d1(asl->al_Lock); + + if (NameFromLock(asl->al_Lock, AssignDirName, sizeof(AssignDirName))) + { + GetFileVersionString(AssignDirName, Filename, VersionString, MaxLen); + if (strlen(VersionString) > 0) + break; // found! + } + + asl = asl->al_Next; + } + } + + UnLockDosList(LDF_ASSIGNS | LDF_READ); + } while (0); + + if (NameCopy) + free(NameCopy); + + return VersionString; +} + +//---------------------------------------------------------------------------- + +static STRPTR GetFileVersionString(CONST_STRPTR Dir, CONST_STRPTR Filename, STRPTR VersionString, size_t MaxLen) +{ + char VersMask[10]; + BPTR fh = (BPTR)NULL; + UBYTE *Buffer; + const size_t BuffLength = 1024; + T_TIMEVAL StartTime, currentTime; + STRPTR OrigVersionString = VersionString; + BPTR DirLock = (BPTR)NULL; + + // do not use statically initalized "$VER" variable here + // since it might confuse the "version" command. + // skip the leading "\0" in versTag + stccpy(VersMask, VersTag + 1, 6 + 1); + + d1(KPrintF("%s/%s/%ld: Dir=<%s> Filename=<%s>\n", __FILE__, __FUNC__, __LINE__, Dir, Filename)); + + do { + ULONG TotalLen = 0; + LONG ActLen; + ULONG MaskNdx = 0; + BOOL Finished = FALSE; + BOOL Found = FALSE; + BPTR OldDir; + + Buffer = malloc(BuffLength); + if (NULL == Buffer) + break; + + GetSysTime(&StartTime); + + DirLock = Lock(Dir, ACCESS_READ); + if ((BPTR)NULL == DirLock) + { + d1(KPrintF("%s/%s/%ld: failed to lock dir=<%s>\n", __FILE__, __FUNC__, __LINE__, Dir)); + break; + } + + OldDir = CurrentDir(DirLock); + fh = Open(Filename, MODE_OLDFILE); + CurrentDir(OldDir); + + if ((BPTR)NULL == fh) + { + d1(KPrintF("%s/%s/%ld: failed to open Filename=<%s>\n", __FILE__, __FUNC__, __LINE__, Filename)); + break; + } + + do { + ActLen = Read(fh, Buffer, BuffLength); + + if (ActLen > 0) + { + ULONG n; + UBYTE *BufPtr = Buffer; + + TotalLen += ActLen; + + for (n=0; !Finished && n 1 && *BufPtr && *BufPtr >= ' ' && *BufPtr <= 0x7f) + { + *VersionString++ = *BufPtr++; + MaxLen--; + } + else + Finished = TRUE; + } + else + { + if (*BufPtr++ == VersMask[MaskNdx]) + { + MaskNdx++; + + if (MaskNdx >= strlen(VersMask)) + { + Found = TRUE; + } + } + else + { + MaskNdx = 0; + } + } + } + } + + GetSysTime(¤tTime); + if ((currentTime.tv_secs - StartTime.tv_secs) > 2) + { + d1(KPrintF("%s/%s/%ld: timeout\n", __FILE__, __FUNC__, __LINE__)); + break; + } + } while (ActLen > 0 && !Finished); + } while (0); + + *VersionString = '\0'; + + if (Buffer) + free(Buffer); + if (fh) + Close(fh); + + if (DirLock) + UnLock(DirLock); + + d1(KPrintF("%s/%s/%ld: OrigVersionString=<%s>\n", __FILE__, __FUNC__, __LINE__, OrigVersionString )); + + return OrigVersionString; +} + +//---------------------------------------------------------------------------- + +static void ExtractVersionNumberFromVersionString(CONST_STRPTR VersionString, ULONG *Version, ULONG *Revision, ULONG *PatchLevel) +{ + unsigned long ulong1, ulong2, ulong3; + + *Version = *Revision = *PatchLevel = 0; + + d1(KPrintF("%s/%s/%ld: VersionString=<%s>\n", __FILE__, __FUNC__, __LINE__, VersionString )); + + do { + while (*VersionString && !isspace(*VersionString)) + VersionString++; + + while (*VersionString && isspace(*VersionString)) + VersionString++; + } while (*VersionString && !isdigit(*VersionString) && 'v' != ToLower(*VersionString)); + + if ('v' == ToLower(*VersionString)) + VersionString++; + + sscanf(VersionString, "%lu.%lu.%lu", &ulong1, &ulong2, &ulong3); + *Version = ulong1; + *Revision = ulong2; + *PatchLevel = ulong3; + + d1(KPrintF("%s/%s/%ld: Version=%lu Revision=%lu PatchLevel=%lu\n", __FILE__, __FUNC__, __LINE__, *Version, *Revision, *PatchLevel)); +} + +//---------------------------------------------------------------------------- + +static void CheckForUpdatesHookFunc(struct Hook *hook, Object *obj, Msg *msg) +{ + BOOL Success = FALSE; + struct VersionFileHandle vfhVersions; + struct VersionFileHandle vfhSig; + + memset(&vfhVersions, 0, sizeof(vfhVersions)); + memset(&vfhSig, 0, sizeof(vfhSig)); + + do { + CURLcode res; + + set(GaugeProgress, MUIA_Gauge_Current, 0); + DoMethod(NListComponents, MUIM_NList_Clear); + DoMethod(NListHiddenComponents, MUIM_NList_Clear); + + res = DownloadFile(&vfhVersions, "/versions.txt", 0, 40); + if (0 != res) + break; + + res = DownloadFile(&vfhSig, "/versions.txt.sig", 40, 50); + if (0 != res) + break; + + if (!VerifyVersionsFileSignature(&vfhVersions, &vfhSig)) + { + break; + } + + AddLogMsg(MSGID_LOG_CHECKING_VERSIONS); + + set(GaugeProgress, MUIA_Gauge_InfoText, (ULONG) GetLocString(MSG_PROGRESS_PROCESS_HTTP_RESPONSE)); + Success = ProcessVersionFile(vfhVersions.vfh_AllocatedBuffer, vfhVersions.vfh_TotalLength); + + AddLogMsg(MSGID_LOG_UPDATES_FOUND, SelectedCount); + + if (0 == SelectedCount && fAuto && !fQuiet) + { + MUI_Request(APP_Main, WIN_Main, 0, NULL, + GetLocString(MSGID_ABOUTREQOK), + GetLocString(MSGID_REQFORMAT_NO_UPDATES_FOUND), + (ULONG) OsName); + } + + } while (0); + + free(vfhVersions.vfh_AllocatedBuffer); + free(vfhSig.vfh_AllocatedBuffer); + + set(GaugeProgress, MUIA_Gauge_Current, 100); + set(GaugeProgress, MUIA_Gauge_InfoText, (ULONG) GetLocString(Success ? MSG_PROGRESS_DONE : MSG_PROGRESS_FAILED)); + + UpdateSelectedCount(); +} + +//---------------------------------------------------------------------------- + +static void StartUpdateUpdateHookFunc(struct Hook *hook, Object *obj, Msg *msg) +{ + ULONG AskEveryUpdate = 0; + STRPTR ScalosWebSite = ""; + CURL *curl; + + set(GaugeProgress, MUIA_Gauge_InfoText, (ULONG) GetLocString(MSG_PROGRESS_START_UPDATE)); + set(GaugeProgress, MUIA_Gauge_Current, 0); + d1(KPrintF("%s/%s/%ld: MUIA_Gauge_Current=%ld\n", __FILE__, __FUNC__, __LINE__, 0)); + + get(CheckAskEveryUpdate, MUIA_Selected, &AskEveryUpdate); + get(StringScalosWebSite, MUIA_String_Contents, &ScalosWebSite); + + curl = curl_easy_init(); + if (curl) + { + BPTR inputFd = 0; + ULONG TotalUpdateCount = SelectedCount; + BOOL AbortUpdate = FALSE; + ULONG Count = 0; + ULONG Entries = 0; + ULONG n; + + get(NListComponents, MUIA_NList_Entries, &Entries); + + for (n = 0; !AbortUpdate && n < Entries; n++) + { + FILE *fh = NULL; + struct ComponentListEntry *cle = NULL; + STRPTR LhaName = NULL; + STRPTR HttpAddr = NULL; + STRPTR EscapedPackageName = NULL; + STRPTR LhaCmdLine = NULL; + BOOL Success = FALSE; + + AddLogMsg(MSGID_LOG_UPDATING, Count, SelectedCount); + + DoMethod(NListComponents, MUIM_NList_GetEntry, + n, &cle); + + do { + struct ProgressData pgd; + size_t len; + LONG rc; + BOOL SkipFile = FALSE; + CURLcode res; + CONST_STRPTR TempFilePath = ""; + + if (!cle->cle_Selected) + break; + + GetAttr(MUIA_String_Contents, PopAslTempPath, (APTR) &TempFilePath); + + set(cle->cle_LampObject, MUIA_Lamp_Color, MUIV_Lamp_Color_ReceivingData); + DoMethod(NListComponents, MUIM_NList_RedrawEntry, cle); + + pgd.pgd_Min = (100 * Count) / TotalUpdateCount; + pgd.pgd_Max = (100 * (1 + Count)) / TotalUpdateCount; + d1(KPrintF("%s/%s/%ld: pgd_Min=%ld pgd_Max=%ld\n", __FILE__, __FUNC__, __LINE__, pgd.pgd_Min, pgd.pgd_Max)); + + set(GaugeProgress, MUIA_Gauge_Current, pgd.pgd_Min); + d1(KPrintF("%s/%s/%ld: MUIA_Gauge_Current=%ld\n", __FILE__, __FUNC__, __LINE__, pgd.pgd_Min)); + + len = 1 + strlen(TempFilePath) + strlen(FilePart(cle->cle_Package)); + + LhaName = malloc(len); + if (NULL == LhaName) + break; + + strcpy(LhaName, TempFilePath); + AddPart(LhaName, FilePart(cle->cle_Package), len); + + snprintf(TextProgressBuffer, sizeof(TextProgressBuffer), + GetLocString(MSG_PROGRESS_DOWNLOAD_UPDATE), cle->cle_Package); + set(GaugeProgress, MUIA_Gauge_InfoText, (ULONG) TextProgressBuffer); + + EscapedPackageName = EscapeHttpName(cle->cle_Package); + d1(KPrintF("%s/%s/%ld: EscapedPackageName=%08lx\n", __FILE__, __FUNC__, __LINE__, EscapedPackageName)); + if (NULL == EscapedPackageName) + break; + + len = 1 + strlen(ScalosWebSite) + strlen(EscapedPackageName); + HttpAddr = malloc(len); + if (NULL == HttpAddr) + break; + + snprintf(HttpAddr, len, "%s%s", ScalosWebSite, EscapedPackageName); + + d1(KPrintF("%s/%s/%ld: HttpAddr=<%s>\n", __FILE__, __FUNC__, __LINE__, HttpAddr)); + + fh = fopen(LhaName, "wb"); + if (NULL == fh) + { + AddLogMsg(MSGID_LOG_ERROR_OPEN_LHAFILE, LhaName, cle->cle_File); + AbortUpdate = ErrorMsg(MSGID_ERROR_OPEN_LHAFILE, LhaName, cle->cle_File); + break; + } + + AddLogMsg(MSGID_LOG_DOWNLOAD_PACKAGE, cle->cle_Package); + + if (!SetProxyOptions(curl)) + break; + + curl_easy_setopt(curl, CURLOPT_URL, HttpAddr); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, fh); + curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, PerformUpdateProgressFunc); + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &pgd); + + d1(KPrintF("%s/%s/%ld: cle_Dir=<%s> cle_File=<%s> cle_Package=<%s>\n", \ + __FILE__, __FUNC__, __LINE__, cle->cle_Dir, cle->cle_File, cle->cle_Package)); + + res = curl_easy_perform(curl); + if (0 != res) + { + CONST_STRPTR ErrorBuffer; + + ErrorBuffer = curl_easy_strerror(res); + + d1(KPrintF("%s/%s/%ld: <%s>\n", __FILE__, __FUNC__, __LINE__, ErrorBuffer)); + + AbortUpdate = ErrorMsg(MSGID_ERROR_DOWNLOADING_UPDATE, cle->cle_File, ErrorMsg); + AddLogMsg(MSGID_LOG_DOWNLOAD_FAILED_PACKAGE, cle->cle_Package, ErrorMsg); + break; + } + + fclose(fh); + fh = NULL; + + set(GaugeProgress, MUIA_Gauge_InfoText, (ULONG) GetLocString(MSG_PROGRESS_VERIFY_SIGNATURE)); + + AddLogMsg(MSGID_LOG_VERIFY_SIGNATURE, cle->cle_Package); + + if (!VerifyFileSignature(LhaName, cle->cle_Hash)) + { + d1(KPrintF("%s/%s/%ld: File signature mismatch\n", __FILE__, __FUNC__, __LINE__)); + AddLogMsg(MSGID_LOG_VERIFY_FAIL_SIGNATURE, cle->cle_Package); + break; + } + + if (AskEveryUpdate) + { + LONG ReqRes; + + ReqRes = MUI_Request(APP_Main, WIN_Main, 0, NULL, + GetLocString(MSGID_ABOUTREQ_YES_NO_ABORT), + GetLocString(MSGID_REQFORMAT_ASK_UPDATE), + (ULONG) cle->cle_File, + cle->cle_RemoteVersion, + cle->cle_RemoteRevision, + cle->cle_LocalVersion, + cle->cle_LocalRevision); + + d1(KPrintF("%s/%s/%ld: ReqRes=%ld\n", __FILE__, __FUNC__, __LINE__, ReqRes)); + if (1 == ReqRes) + SkipFile = FALSE; // "Yes" + else if (2 == ReqRes) + SkipFile = TRUE; // "No" + else + { + AbortUpdate = TRUE; + break; // "Abort" selected + } + } + + if (SkipFile) + { + AddLogMsg(MSGID_LOG_SKIP_PACKAGE, cle->cle_Package); + } + else + { + size_t LhaCmdLineLen; + char ch = cle->cle_Dir[strlen(cle->cle_Dir) - 1]; + + if (0 == inputFd) + inputFd = Open("NIL:", MODE_OLDFILE); + if (0 == inputFd) + { + char buffer[120]; + + (void) Fault(IoErr(), "", buffer, sizeof(buffer)); + AddLogMsg(MSGID_LOG_ERROR_OPEN_INPUTFD, buffer); + AbortUpdate = ErrorMsg(MSGID_LOG_ERROR_OPEN_INPUTFD, buffer); + break; + } + + LhaCmdLineLen = 1 + strlen(LhaName) + 2 * strlen(cle->cle_File) + strlen(cle->cle_Dir) + 80; + LhaCmdLine = malloc(LhaCmdLineLen); + if (NULL == LhaCmdLine) + break; + + // lha -qI e Delete.module.lha Delete.module Delete.module.info Scalos:modules + if ('/' == ch || ':' == ch) + { + snprintf(LhaCmdLine, LhaCmdLineLen, "lha -qI e \"%s\" \"%s\" \"%s.info\" \"%s\"", + LhaName, cle->cle_File, cle->cle_File, cle->cle_Dir); + } + else + { + snprintf(LhaCmdLine, LhaCmdLineLen, "lha -qI e \"%s\" \"%s\" \"%s.info\" \"%s/\"", + LhaName, cle->cle_File, cle->cle_File, cle->cle_Dir); + } + + d1(KPrintF("%s/%s/%ld: LhaCmdLine=<%s>\n", __FILE__, __FUNC__, __LINE__, LhaCmdLine)); + AddLogMsg(MSGID_LOG_UNPACK_PACKAGE, cle->cle_Package); + + // SystemTagList() + rc = SystemTags(LhaCmdLine, + SYS_Input, inputFd, + NP_Output, 0, + TAG_END); + d1(KPrintF("%s/%s/%ld: Lha returned rc=%ld\n", __FILE__, __FUNC__, __LINE__, rc)); + if (RETURN_OK != rc) + { + AbortUpdate = ErrorMsg(MSGID_ERROR_LHA1, cle->cle_File); + AddLogMsg(MSGID_LOG_UNPACK_FAIL_PACKAGE, cle->cle_Package); + break; + } + + free(LhaCmdLine); + LhaCmdLineLen = 1 + strlen(LhaName) + 80; + LhaCmdLine = malloc(LhaCmdLineLen); + if (NULL == LhaCmdLine) + break; + + // lha -qI x Delete.module.lha #?.catalog locale: + snprintf(LhaCmdLine, LhaCmdLineLen, "lha -qI x \"%s\" #?.catalog locale:", + LhaName); + + d1(KPrintF("%s/%s/%ld: LhaCmdLine=<%s>\n", __FILE__, __FUNC__, __LINE__, LhaCmdLine)); + + // SystemTagList() + rc = SystemTags(LhaCmdLine, + SYS_Input, inputFd, + SYS_Output, 0, + TAG_END); + d1(KPrintF("%s/%s/%ld: Lha returned rc=%ld\n", __FILE__, __FUNC__, __LINE__, rc)); + if (RETURN_OK != rc) + { + AbortUpdate = ErrorMsg(MSGID_ERROR_LHA2, cle->cle_File); + AddLogMsg(MSGID_LOG_UNPACK_CATALOGS_FAIL_PACKAGE, cle->cle_Package); + break; + } + + Success = TRUE; + } + + set(GaugeProgress, MUIA_Gauge_Current, pgd.pgd_Max); + d1(KPrintF("%s/%s/%ld: MUIA_Gauge_Current=%ld\n", __FILE__, __FUNC__, __LINE__, pgd.pgd_Max)); + + Count++; + } while (0); + + if (fh) + fclose(fh); + if (LhaName) + { + DeleteFile(LhaName); + free(LhaName); + } + if (HttpAddr) + free(HttpAddr); + if (EscapedPackageName) + free(EscapedPackageName); + if (LhaCmdLine) + free(LhaCmdLine); + + if (cle->cle_Selected) + { + set(cle->cle_LampObject, MUIA_Lamp_Color, Success ? MUIV_Lamp_Color_Ok : MUIV_Lamp_Color_FatalError); + + if (Success) + { + SelectedCount--; + cle->cle_Selected = FALSE; + set(cle->cle_CheckboxObject, MUIA_Selected, cle->cle_Selected); + UpdateSelectedCount(); + } + } + DoMethod(NListComponents, MUIM_NList_RedrawEntry, cle); + } + + if (inputFd) + Close(inputFd); + + curl_easy_cleanup(curl); + } + + set(GaugeProgress, MUIA_Gauge_Current, 100); + set(GaugeProgress, MUIA_Gauge_InfoText, (ULONG) GetLocString(MSG_PROGRESS_DONE)); + d1(KPrintF("%s/%s/%ld: MUIA_Gauge_Current=%ld\n", __FILE__, __FUNC__, __LINE__, 100)); +} + +//---------------------------------------------------------------------------- + +static void SelectAllComponentsHookFunc(struct Hook *hook, Object *obj, Msg *msg) +{ + ULONG Entries = 0; + ULONG n; + + get(NListComponents, MUIA_NList_Entries, &Entries); + + set(NListComponents, MUIA_NList_Quiet, TRUE); + + for (n = 0; n < Entries; n++) + { + struct ComponentListEntry *cle = NULL; + + DoMethod(NListComponents, MUIM_NList_GetEntry, + n, &cle); + + if (!cle->cle_Selected) + { + cle->cle_Selected = TRUE; + set(cle->cle_CheckboxObject, MUIA_Selected, cle->cle_Selected); + set(cle->cle_LampObject, MUIA_Lamp_Color, cle->cle_Selected ? MUIV_Lamp_Color_LoadingData : MUIV_Lamp_Color_Off); + + if (cle->cle_Selected) + SelectedCount++; + else + SelectedCount--; + + DoMethod(NListComponents, MUIM_NList_RedrawEntry, cle); + } + } + set(NListComponents, MUIA_NList_Quiet, FALSE); + UpdateSelectedCount(); +} + +//---------------------------------------------------------------------------- + +static void DeselectAllComponentsHookFunc(struct Hook *hook, Object *obj, Msg *msg) +{ + ULONG Entries = 0; + ULONG n; + + get(NListComponents, MUIA_NList_Entries, &Entries); + set(NListComponents, MUIA_NList_Quiet, TRUE); + + for (n = 0; n < Entries; n++) + { + struct ComponentListEntry *cle = NULL; + + DoMethod(NListComponents, MUIM_NList_GetEntry, + n, &cle); + + if (cle->cle_Selected) + { + cle->cle_Selected = FALSE; + set(cle->cle_CheckboxObject, MUIA_Selected, cle->cle_Selected); + set(cle->cle_LampObject, MUIA_Lamp_Color, cle->cle_Selected ? MUIV_Lamp_Color_LoadingData : MUIV_Lamp_Color_Off); + + if (cle->cle_Selected) + SelectedCount++; + else + SelectedCount--; + + DoMethod(NListComponents, MUIM_NList_RedrawEntry, cle); + } + } + + set(NListComponents, MUIA_NList_Quiet, FALSE); + UpdateSelectedCount(); +} + +//---------------------------------------------------------------------------- + +static void SaveLogHookFunc(struct Hook *hook, Object *obj, Msg *msg) +{ + if (NULL == SaveLogAslRequest) + { + //MUI_AllocAslRequest + SaveLogAslRequest = MUI_AllocAslRequestTags(ASL_FileRequest, + ASLFR_InitialFile, (ULONG) "UpdateLog.txt", + ASLFR_DoSaveMode, TRUE, + ASLFR_InitialDrawer, (ULONG) "SYS:", + ASLFR_IntuiMsgFunc, (ULONG) &AslIntuiMsgHook, + TAG_END); + } + if (SaveLogAslRequest) + { + BOOL Result; + struct Window *win = NULL; + + get(WIN_Main, MUIA_Window_Window, &win); + + //MUI_AslRequest( + Result = MUI_AslRequestTags(SaveLogAslRequest, + ASLFR_TitleText, (ULONG) GetLocString(MSGID_SAVE_LOG_ASLTITLE), + ASLFR_Window, (ULONG) win, + ASLFR_SleepWindow, TRUE, + TAG_END); + + if (Result) + { + BPTR dirLock; + BPTR oldDir = 0; + BPTR fh = 0; + STRPTR Contents = NULL; + + do { + dirLock = Lock(SaveLogAslRequest->fr_Drawer, ACCESS_READ); + if (0 == dirLock) + break; + + oldDir = CurrentDir(dirLock); + + Contents = (STRPTR) DoMethod(TextEditorLog, MUIM_TextEditor_ExportText); + if (NULL == Contents) + break; + + fh = Open(SaveLogAslRequest->fr_File, MODE_NEWFILE); + if (0 == fh) + break; + + Write(fh, Contents, strlen(Contents)); + } while (0); + if (fh) + Close(fh); + if (Contents) + FreeVec(Contents); + if (oldDir) + CurrentDir(oldDir); + if (dirLock) + UnLock(dirLock); + } + } +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT AslIntuiMsgHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct IntuiMessage *iMsg = (struct IntuiMessage *) msg; + + if (IDCMP_REFRESHWINDOW == iMsg->Class) + { + DoMethod(APP_Main, MUIM_Application_CheckRefresh); + } +} + +//---------------------------------------------------------------------------- + +static void UpdateSelectedCount(void) +{ + static char SelectedCountBuffer[60]; + + snprintf(SelectedCountBuffer, sizeof(SelectedCountBuffer), + GetLocString(MSGID_TEXT_SELECTED_COUNT), SelectedCount); + set(SelectedCountMsg, MUIA_Text_Contents, (ULONG) SelectedCountBuffer); + + set(ButtonStartUpdate, MUIA_Disabled, 0 == SelectedCount); + set(ButtonDeselectAll, MUIA_Disabled, 0 == SelectedCount); +} + +//---------------------------------------------------------------------------- + +#if !defined(__amigaos4__) && !defined(__AROS__) +int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, + struct timeval *timeout) +{ + return (int) WaitSelect(nfds, readfds, writefds, exceptfds, timeout, NULL); +} +#endif + +//---------------------------------------------------------------------------- + +#if !defined(__amigaos4__) +int ioctl(int s, int cmd, char *arg) +{ + return IoctlSocket(s, cmd, arg); +} +#endif + +//---------------------------------------------------------------------------- + +static int CheckForUpdatesProgressFunc(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) +{ + const struct ProgressData *pgd = (const struct ProgressData *) clientp; + LONG dlLevel; + + dlLevel = pgd->pgd_Min + (LONG) (((pgd->pgd_Max - pgd->pgd_Min) * dlnow) / dltotal); + + d1(kprintf("%s/%ld: dlLevel=%ld\n", __FUNC__, __LINE__, dlLevel)); + set(GaugeProgress, MUIA_Gauge_Current, dlLevel); + + return 0; +} + +//---------------------------------------------------------------------------- + +static int PerformUpdateProgressFunc(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) +{ + const struct ProgressData *pgd = (const struct ProgressData *) clientp; + LONG dlLevel; + + dlLevel = pgd->pgd_Min + (LONG) (((pgd->pgd_Max - pgd->pgd_Min) * dlnow) / dltotal); + + if (dlLevel < 0) + dlLevel = 0; + else if (dlLevel > 100) + dlLevel = 100; + + d1(KPrintF("%s/%s/%ld: MUIA_Gauge_Current=%ld\n", __FILE__, __FUNC__, __LINE__, dlLevel)); + set(GaugeProgress, MUIA_Gauge_Current, dlLevel); + + return 0; +} + +//---------------------------------------------------------------------------- + +static BOOL CalculateFileHash(CONST_STRPTR Filename, unsigned char *digest) +{ + FILE *fh = NULL; + UBYTE *Buffer = NULL; + BOOL Success = FALSE; + + d1(KPrintF("%s/%s/%ld: START Filename=<%s>\n", __FILE__, __FUNC__, __LINE__, Filename)); + + do { + size_t nBytes; + size_t BuffSize = 4096; + SHA_CTX ctx; + + memset(&ctx, 0, sizeof(ctx)); + SHA1_Init(&ctx); + + Buffer = malloc(BuffSize); + if (NULL == Buffer) + break; + + fh = fopen(Filename, "rb"); + if (NULL == fh) + break; + + while ((nBytes = fread(Buffer, 1, BuffSize, fh)) > 0) + { + d1(KPrintF("%s/%s/%ld: nBytes=%ld\n", __FILE__, __FUNC__, __LINE__, nBytes)); + SHA1_Update(&ctx, Buffer, nBytes); + } + + SHA1_Final(digest, &ctx); + + Success = TRUE; + } while (0); + + if (fh) + fclose(fh); + if (Buffer) + free(Buffer); + + d1(KPrintF("%s/%s/%ld: END Success=%ld\n", __FILE__, __FUNC__, __LINE__, Success)); + + return Success; +} + +//---------------------------------------------------------------------------- + +static RSA *GetScalosPublicKey(void) +{ + static CONST_STRPTR ScalosPubKey = + "-----BEGIN PUBLIC KEY-----\n" + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDER/rCy5ESeTLgUXDl7xbTmXR7\n" + "OySYhzMk3pD3E9hS293vkU3rUCxbGVdI/ywg8Hw3UgrrYwg+7vxeShV4A1zzl8rm\n" + "mWE5ZmV1mYH4UxU95zZfCgLDAiQDVp/dMHR5YBcb9MUMWYZGewiQo29yNUbSd+hQ\n" + "W595xYqTCIN3lAfezwIDAQAB\n" + "-----END PUBLIC KEY-----"; + RSA *rsa = NULL; + BIO *bp; + + d1(KPrintF("%s/%s/%ld: START \n", __FILE__, __FUNC__, __LINE__)); + + bp = BIO_new_mem_buf((void *) ScalosPubKey, strlen(ScalosPubKey)); + d1(KPrintF("%s/%s/%ld: bp=%08lx\n", __FILE__, __FUNC__, __LINE__, bp)); + if (bp) + { + rsa = PEM_read_bio_RSA_PUBKEY(bp, NULL, NULL, NULL); + + if (NULL == rsa) + { + OpenSSLError(__FUNCTION__, "PEM_read_bio_RSA_PUBKEY"); + } + BIO_free(bp); + } + else + { + OpenSSLError(__FUNCTION__, "BIO_new_mem_buf"); + } + + d1(KPrintF("%s/%s/%ld: END rsa=%08lx\n", __FILE__, __FUNC__, __LINE__, rsa)); + + return rsa; +} + +//---------------------------------------------------------------------------- + +static BOOL VerifyFileSignature(CONST_STRPTR FileName, CONST_STRPTR SignatureString) +{ + BOOL Success = FALSE; + + d1(KPrintF("%s/%s/%ld: START Filename=<%s>\n", __FILE__, __FUNC__, __LINE__, FileName)); + d1(KPrintF("%s/%s/%ld: SignatureString=<%s>\n", __FILE__, __FUNC__, __LINE__, SignatureString)); + + do { + unsigned char signature[128]; + unsigned char digest[SHA_DIGEST_LENGTH]; + int rc; + + if (RSA_size(ScalosPubKeyRSA) != sizeof(signature)) + break; + + if (!Base64Decode(SignatureString, signature, sizeof(signature))) +// if (!HexStringDecode(SignatureString, signature, sizeof(signature))) + { + d1(KPrintF("%s/%s/%ld: Base64Decode(%s) failed.\n", __FILE__, __FUNC__, __LINE__, SignatureString)); + break; + } + + d1(KPrintF("%s/%s/%ld: signature=%08lx\n", __FILE__, __FUNC__, __LINE__, signature)); + //ByteDump(signature, sizeof(signature)); + d1(KPrintF("%s/%s/%ld: digest=%08lx\n", __FILE__, __FUNC__, __LINE__, digest)); + //ByteDump(digest, sizeof(digest)); + + if (!CalculateFileHash(FileName, digest)) + { + d1(KPrintF("%s/%s/%ld: CalculateFileHash(%s) failed.\n", __FILE__, __FUNC__, __LINE__, FileName)); + break; + } + + d1(KPrintF("%s/%s/%ld: RSA_size=%ld.\n", __FILE__, __FUNC__, __LINE__, RSA_size(ScalosPubKeyRSA))); + + rc = RSA_verify(NID_sha1, digest, sizeof(digest), + signature, sizeof(signature), ScalosPubKeyRSA); + + d1(KPrintF("%s/%s/%ld: RSA_verify returned %ld.\n", __FILE__, __FUNC__, __LINE__, rc)); + + if (1 == rc) + { + Success = TRUE; + } + else + { + OpenSSLError(__FUNCTION__, "RSA_verify"); + } + } while (0); + + return Success; +} + +//---------------------------------------------------------------------------- + +static BOOL VerifyVersionsFileSignature(const struct VersionFileHandle *vfhFile, const struct VersionFileHandle *vfhSig) +{ + BOOL Success = FALSE; + + do { + unsigned char signature[128]; + unsigned char digest[SHA_DIGEST_LENGTH]; + SHA_CTX ctx; + int rc; + + if (RSA_size(ScalosPubKeyRSA) != sizeof(signature)) + break; + + if (!Base64Decode(vfhSig->vfh_AllocatedBuffer, signature, sizeof(signature))) + { + d1(KPrintF("%s/%s/%ld: Base64Decode(versions.txt.sig) failed.\n", __FILE__, __FUNC__, __LINE__)); + break; + } + + d1(KPrintF("%s/%s/%ld: signature=%08lx\n", __FILE__, __FUNC__, __LINE__, signature)); + //ByteDump(signature, sizeof(signature)); + d1(KPrintF("%s/%s/%ld: digest=%08lx\n", __FILE__, __FUNC__, __LINE__, digest)); + //ByteDump(digest, sizeof(digest)); + + // calculate digest from versions file contents in vfhFile + memset(&ctx, 0, sizeof(ctx)); + SHA1_Init(&ctx); + + d1(KPrintF("%s/%s/%ld: nBytes=%ld\n", __FILE__, __FUNC__, __LINE__, vfhSig->vfh_TotalLength)); + SHA1_Update(&ctx, vfhFile->vfh_AllocatedBuffer, vfhFile->vfh_TotalLength); + + SHA1_Final(digest, &ctx); + + d1(KPrintF("%s/%s/%ld: RSA_size=%ld.\n", __FILE__, __FUNC__, __LINE__, RSA_size(ScalosPubKeyRSA))); + + rc = RSA_verify(NID_sha1, digest, sizeof(digest), + signature, sizeof(signature), ScalosPubKeyRSA); + + d1(KPrintF("%s/%s/%ld: RSA_verify returned %ld.\n", __FILE__, __FUNC__, __LINE__, rc)); + + if (1 == rc) + { + Success = TRUE; + } + else + { + OpenSSLError(__FUNCTION__, "RSA_verify"); + } + } while (0); + + return Success; +} + +//---------------------------------------------------------------------------- + +/* +** decodeblock +** +** decode 4 '6-bit' characters into 3 8-bit binary bytes +*/ +static void decodeblock( const unsigned char in[4], unsigned char out[3] ) +{ + out[0] = (unsigned char ) (in[0] << 2 | in[1] >> 4); + out[1] = (unsigned char ) (in[1] << 4 | in[2] >> 2); + out[2] = (unsigned char ) (((in[2] << 6) & 0xc0) | in[3]); +} + +/* +** decode +** +** decode a base64 encoded stream discarding padding, line breaks and noise +*/ +static BOOL Base64Decode(CONST_STRPTR Base64String, unsigned char *outbuf, size_t BuffLength) +{ + while ( *Base64String && BuffLength) + { + size_t len; + unsigned char in[4], v; + int i; + + for ( len = 0, i = 0; i < 4 && *Base64String; i++ ) + { + v = 0; + while ( *Base64String && v == 0 ) + { + static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq"; + + v = (unsigned char) *Base64String++; + v = (unsigned char) ((v < 43 || v > 122) ? 0 : cd64[ v - 43 ]); + if ( v ) + { + v = (unsigned char) ((v == '$') ? 0 : v - 61); + } + } + if ( *Base64String ) + { + len++; + if( v ) + { + in[i] = (unsigned char) (v - 1); + } + } + else + { + in[i] = 0; + } + } + if (len) + { + unsigned char out[3]; + + decodeblock( in, out ); + for( i = 0; i < len - 1 && BuffLength; i++ ) + { + *outbuf++ = out[i]; + BuffLength--; + } + } + } + + return TRUE; +} + +//---------------------------------------------------------------------------- +#if 0 +static BOOL HexStringDecode(CONST_STRPTR HexString, unsigned char *outbuf, size_t BuffLength) +{ + while (strlen(HexString) >= 2 && BuffLength) + { + if (!isxdigit(HexString[0]) || !isxdigit(HexString[1])) + break; + + *outbuf++ = (HexDigit(HexString[0]) << 4) + HexDigit(HexString[1]); + + BuffLength--; + HexString += 2; + } + + return (0 == BuffLength) && (0 == strlen(HexString)); +} + +//---------------------------------------------------------------------------- + +static UBYTE HexDigit(char ch) +{ + UBYTE val = 0; + + if (isxdigit(ch)) + { + if (ch >= 'a') + val = ch - 'a' + 10; + else if (ch >= 'A') + val = ch - 'A' + 10; + else + val = ch - '0'; + } + + return val; +} +#endif +//---------------------------------------------------------------------------- + +#if 0 +static void ByteDump(unsigned char *Data, size_t Length) +{ + unsigned long count; + unsigned char Line[80], *lp; + + lp = Line; + for (count=0; count\n", __FILE__, __FUNC__, __LINE__, ErrorBuffer)); + + MUI_Request(APP_Main, WIN_Main, 0, NULL, + GetLocString(MSGID_ABOUTREQOK), + GetLocString(MSGID_REQFORMAT_OPENSSL_ERROR), + (ULONG) Function, (ULONG) Operation, (ULONG) ErrorBuffer); + + AddLogMsg(MSGID_REQFORMAT_OPENSSL_ERROR, Function, Operation, ErrorBuffer); + + ERR_free_strings(); +} + +//---------------------------------------------------------------------------- + +static BOOL ErrorMsg(ULONG MsgId, ...) +{ + char Buffer[200]; + LONG res; + va_list args; + + va_start(args, MsgId); + + vsnprintf(Buffer, sizeof(Buffer), GetLocString(MsgId), args); + + res = MUI_Request(APP_Main, WIN_Main, 0, NULL, + GetLocString(MSGID_REQ_CONTINUE_ABORT), + Buffer); + + va_end(args); + + return (BOOL) (1 != res); +} + +//---------------------------------------------------------------------------- + +static void AddLogMsg(ULONG MsgId, ...) +{ + char Buffer[200]; + va_list args; + + va_start(args, MsgId); + + vsnprintf(Buffer, sizeof(Buffer), GetLocString(MsgId), args); + + DoMethod(TextEditorLog, MUIM_TextEditor_InsertText, + Buffer, + MUIV_TextEditor_InsertText_Bottom); + + va_end(args); +} + +//---------------------------------------------------------------------------- + +static void ParseArguments(void) +{ + if (WBenchMsg) + { + // Called from Workbench, check ToolTypes + BPTR oldDir; + struct DiskObject *icon; + + oldDir = CurrentDir(WBenchMsg->sm_ArgList[0].wa_Lock); + + d1(kprintf("%s/%ld: Called from Workbench\n", __FUNC__, __LINE__)); + + icon = GetDiskObject(WBenchMsg->sm_ArgList[0].wa_Name); + if (icon) + { + STRPTR tt; + + tt = FindToolType(icon->do_ToolTypes, "QUIET"); + fQuiet = (NULL != tt); + + tt = FindToolType(icon->do_ToolTypes, "AUTO"); + fAuto = (NULL != tt); + + tt = FindToolType(icon->do_ToolTypes, "USEPROXY"); + fUseProxy = (NULL != tt); + + tt = FindToolType(icon->do_ToolTypes, "PROXYAUTH"); + fUseProxyAuth = (NULL != tt); + + tt = FindToolType(icon->do_ToolTypes, "SHOWALL"); + fShowAllComponents = (NULL != tt); + + tt = FindToolType(icon->do_ToolTypes, "ASK"); + fAskEveryUpdate = (NULL != tt); + + tt = FindToolType(icon->do_ToolTypes, "PROXYUSER"); + if (tt) + setstring(StringProxyUser, (ULONG) tt); + + tt = FindToolType(icon->do_ToolTypes, "PROXY"); + if (tt) + setstring(StringProxyAddr, (ULONG) tt); + + tt = FindToolType(icon->do_ToolTypes, "PROXYPASSWORD"); + if (tt) + setstring(StringProxyPwd, (ULONG) tt); + + tt = FindToolType(icon->do_ToolTypes, "SCALOSHTTP"); + if (tt) + setstring(StringScalosWebSite, (ULONG) tt); + + tt = FindToolType(icon->do_ToolTypes, "TEMPFILEPATH"); + if (tt) + setstring(PopAslTempPath, (ULONG) tt); + + //TODO:PROXYPORT + + FreeDiskObject(icon); + } + + CurrentDir(oldDir); + } + else + { + // Called from command line + enum { ARG_USEPROXY, ARG_PROXYAUTH, ARG_SHOWALL, ARG_ASKUPDATES, + ARG_AUTO, ARG_PROXY, ARG_PROXYPORT, ARG_PROXYUSER, + ARG_PROXYPASSWORD, ARG_TEMPFILEPATH, ARG_SCALOSHTTP, + ARG_QUIET, + ARG_LAST }; + static CONST_STRPTR Template = "USEPROXY/S,PROXYAUTH/S,SHOWALL/S,ASK/S," + "AUTO/S,PROXY/K,PROXYPORT/N,PROXYUSER/K,PROXYPASSWORD/K," + "TEMPFILEPATH/K,SCALOSHTTP/K,QUIET/S"; + struct RDArgs *ReadArgs; + IPTR Args[ARG_LAST]; + + memset(Args, 0, sizeof(Args)); + + ReadArgs = ReadArgs(Template, Args, NULL); + d1(kprintf("%s/%ld: ReadArgs=%08lx\n", __FUNC__, __LINE__, ReadArgs)); + if (ReadArgs) + { + fAuto = Args[ARG_AUTO]; + fUseProxy = Args[ARG_USEPROXY]; + fUseProxyAuth = Args[ARG_PROXYAUTH]; + fShowAllComponents = Args[ARG_SHOWALL]; + fAskEveryUpdate = Args[ARG_ASKUPDATES]; + fQuiet = Args[ARG_QUIET]; + + if (Args[ARG_PROXYUSER]) + setstring(StringProxyUser, Args[ARG_PROXYUSER]); + if (Args[ARG_PROXY]) + setstring(StringProxyAddr, Args[ARG_PROXY]); + if (Args[ARG_PROXYPASSWORD]) + setstring(StringProxyPwd, Args[ARG_PROXYPASSWORD]); + if (Args[ARG_SCALOSHTTP]) + setstring(StringScalosWebSite, Args[ARG_SCALOSHTTP]); + if (Args[ARG_TEMPFILEPATH]) + setstring(PopAslTempPath, Args[ARG_TEMPFILEPATH]); + + //TODO:PROXYPORT + + FreeArgs(ReadArgs); + } + } +} + +//---------------------------------------------------------------------------- + +static CURLcode DownloadFile(struct VersionFileHandle *vfh, CONST_STRPTR Filename, ULONG ProgressMin, ULONG ProgressMax) +{ + CURLcode res = CURLE_FAILED_INIT; + CURL *curl; + + curl = curl_easy_init(); + if (curl) + { + char addr[255]; + struct ProgressData pgd; + STRPTR ScalosWebSite = ""; + + pgd.pgd_Min = ProgressMin; + pgd.pgd_Max = ProgressMax; + + get(StringScalosWebSite, MUIA_String_Contents, &ScalosWebSite); + + snprintf(addr, sizeof(addr), "%s%s", ScalosWebSite, Filename); + + snprintf(TextProgressBuffer, sizeof(TextProgressBuffer), + GetLocString(MSG_PROGRESS_CONNECTING), ScalosWebSite); + set(GaugeProgress, MUIA_Gauge_InfoText, (ULONG) TextProgressBuffer); + + if (SetProxyOptions(curl)) + { + curl_easy_setopt(curl, CURLOPT_URL, addr); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, VersionFileWrite); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, vfh); + curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, CheckForUpdatesProgressFunc); + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &pgd); + + AddLogMsg(MSGID_LOG_READ_VERSIONINFO, ScalosWebSite); + + res = curl_easy_perform(curl); + + d1(KPrintF("%s/%s/%ld: res=%ld\n", __FILE__, __FUNC__, __LINE__, res)); + + if (0 == res) + { + d1(KPrintF("%s/%s/%ld: <%s>: vfh->vfh_TotalLength=%ld\n", __FILE__, __FUNC__, __LINE__, Filename, vfh->vfh_TotalLength)); + } + else + { + snprintf(TextProgressBuffer, sizeof(TextProgressBuffer), + GetLocString(MSG_PROGRESS_FAILURE), ScalosWebSite, curl_easy_strerror(res)); + + set(GaugeProgress, MUIA_Gauge_InfoText, (ULONG) TextProgressBuffer); + + ErrorMsg(MSG_PROGRESS_FAILURE, ScalosWebSite, curl_easy_strerror(res)); + AddLogMsg(MSGID_LOG_ERROR_READ_VERSIONINFO, ScalosWebSite, curl_easy_strerror(res)); + } + + /* always cleanup */ + curl_easy_cleanup(curl); + } + } + + return res; +} + +//---------------------------------------------------------------------------- + +#if !defined(__SASC) &&!defined(__MORPHOS__) +// Replacement for SAS/C library functions + +size_t stccpy(char *dest, const char *src, size_t MaxLen) +{ + size_t Count = 0; + + while (*src && MaxLen > 1) + { + *dest++ = *src++; + MaxLen--; + Count++; + } + *dest = '\0'; + Count++; + + return Count; +} + +#endif //!defined(__SASC) &&!defined(__MORPHOS__) + +//---------------------------------------------------------------------------- diff --git a/scalos/Modules/Updater.MUI/Updater.cd b/scalos/Modules/Updater.MUI/Updater.cd new file mode 100755 index 000000000..b07882b84 --- /dev/null +++ b/scalos/Modules/Updater.MUI/Updater.cd @@ -0,0 +1,480 @@ +; Updater.cd +; $Date$ +; $Revision$ +; version $VER: Updater.catalog 40.1 (23. Aug 2008 18:50:08) +; codeset 0s +; language english +; +;#arrayopts static __far +; +; +MSGID_TITLENAME (//) +Scalos Updater +; +;----------------------------------------------------------- +; +MSGID_MENU_PROJECT (1000//) +Project +; +; +MSGID_MENU_PROJECT_ABOUT (//) +About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI (//) +About MUI... +; +; +MSGID_MENU_PROJECT_QUIT (//) +Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT (//) +Q +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK (2000//) +_OK +; +; +MSGID_ABOUTREQFORMAT (//) +\33c\033bScalos Updater.module V%ld.%ld\033n\n\ +%s\n\ +© 2009%s The Scalos Team +; +;----------------------------------------------------------- +; +MSGID_COMPONENTLIST_DIRECTORY (3000//) +Directory +; +; +MSGID_COMPONENTLIST_FILE (//) +Filename +; +; +MSGID_COMPONENTLIST_LATEST_VERSION (//) +Latest +; +; +MSGID_COMPONENTLIST_INSTALLED_VERSION (//) +Installed +; +; +MSGID_COMPONENTLIST_UPDATE (//) +Update +; +;----------------------------------------------------------- +; +MSGID_BUTTON_CHECKFORUPDATES (3500//) +Check For Updates +; +; +MSGID_BUTTON_CHECKFORUPDATES_SHORT (/1/1) +C +; +; +MSGID_BUTTON_CHECKFORUPDATES_HELP (//) +...TBD... +; +; +MSGID_BUTTON_STARTUPDATE (//) +Begin Update +; +; +MSGID_BUTTON_STARTUPDATE_SHORT (/1/1) +B +; +; +MSGID_BUTTON_STARTUPDATE_HELP (//) +...TBD... +; +; +MSGID_BUTTON_SELECT_ALL (//) +Select All +; +; +MSGID_BUTTON_SELECT_ALL_SHORT (/1/1) +A +; +; +MSGID_BUTTON_SELECT_ALL_HELP (//) +...TBD... +; +; +MSGID_BUTTON_DESELECT_ALL (//) +Deselect All +; +; +MSGID_BUTTON_DESELECT_ALL_SHORT (/1/1) +D +; +; +MSGID_BUTTON_DESELECT_ALL_HELP (//) +...TBD... +; +; +MSGID_TEXT_SELECTED_COUNT (//) +%ld Selected +; +; +MSGID_REGISTER_MAIN (//) +Main +; +; +MSGID_REGISTER_CONFIGURATION (//) +Configuration +; +; +MSGID_REGISTER_LOG (//) +Log +; +; +MSGID_GROUP_PROXY (//) +Proxy Settings +; +; +MSGID_CHECK_USE_PROXY (//) +Use Proxy? +; +; +MSGID_CHECK_USE_PROXY_SHORTHELP (//) +...TBD... +; +; +MSGID_STRING_PROXY_ADDR (//) +Address: +; +; +MSGID_STRING_PROXY_ADDR_SHORTHELP (//) +...TBD... +; +; +MSGID_STRING_PROXY_PORT (//) +Port: +; +; +MSGID_STRING_PROXY_PORT_SHORTHELP (//) +...TBD... +; +; +MSGID_CHECK_USE_PROXYAUTH (//) +Proxy requires authentication? +; +; +MSGID_CHECK_USE_PROXYAUTH_SHORTHELP (//) +...TBD... +; +; +MSGID_STRING_PROXY_USERNAME (//) +User Name: +; +; +MSGID_STRING_PROXY_USERNAME_SHORTHELP (//) +...TBD... +; +; +MSGID_STRING_PROXY_PASSWD (//) +Password: +; +; +MSGID_STRING_PROXY_PASSWD_SHORTHELP (//) +...TBD... +; +; +MSGID_REQFORMAT_OPENSSL_ERROR (//) +In function \033b%s\033n,\n\ +OpenSSL call \033b%s\033n failed:\n\ +%s +; +; +MSGID_REQFORMAT_NO_UPDATES_FOUND (//) +No Updates found for %s.\n\ +You already have the most recent\n\ +Scalos components installed. +; +; +MSGID_CHECK_SHOW_ALL_COMPONENTS (//) +Show up-to-date components? +; +; +MSGID_CHECK_SHOW_ALL_COMPONENTS_SHORTHELP (//) +...TBD... +; +; +MSGID_CHECK_ASK_EVERY_UPDATE (//) +Ask about every component update? +; +; +MSGID_CHECK_ASK_EVERY_UPDATE_SHORTHELP (//) +...TBD... +; +; +MSGID_ABOUTREQ_YES_NO_ABORT (//) +_Yes|_No|_Abort +; +; +MSGID_REQFORMAT_ASK_UPDATE (//) +Are you sure you want to update\n\ +\"%s\" to version %ld.%ld\n\ +(Installed Version: %ld.%ld) ? +; +; +MSGID_ERROR_DOWNLOADING_UPDATE (//) +Error downloading update package \"%s\"\n\ +%s +; +; +MSGID_REQ_CONTINUE_ABORT (//) +_Continue|_Abort +; +; +MSGID_ERROR_LHA1 (//) +Error: LHA failed to unpack \"%s\". +; +; +MSGID_ERROR_LHA2 (//) +Error: LHA failed to unpack\n\ +catalog files for \"%s\". +; +; +MSGID_ERROR_OPEN_LHAFILE (//) +Error: failed to open temporary\n\ +archive \"%s\" for updating \"%s\". +; +; +MSGID_STRING_SCALOS_SERVER (//) +Scalos Update Server +; +; +MSGID_STRING_SCALOS_SERVER_SHORTHELP (//) +...TBD... +; +; +MSGID_REQ_INSTALL_UPDATES_GADGETS (//) +_Update|_Abort +; +; +MSGID_REQ_INSTALL_UPDATES (//) +Are you sure you want to install\n\ +%ld Scalos updates now? +; +; +MSGID_GROUP_LOG (//) +Update Log +; +; +MSGID_POPASL_TEMPPATH (//) +Path for Temporary Files: +; +; +MSGID_GROUP_MISCELLANEOUS (//) +Miscellaneous +; +; +MSGID_BUTTON_CLEAR_LOG (//) +Clear Log +; +; +MSGID_BUTTON_CLEAR_LOG_SHORT (/1/1) +C +; +; +MSGID_BUTTON_CLEAR_LOG_SHORTHELP (//) +...TBD.. +; +; +MSGID_BUTTON_SAVE_LOG (//) +Save Log... +; +; +MSGID_BUTTON_SAVE_LOG_SHORT (/1/1) +S +; +; +MSGID_BUTTON_SAVE_LOG_SHORTHELP (//) +...TBD.. +; +; +MSGID_SAVE_LOG_ASLTITLE (//) +Save Update Log... +; +;----------------------------------------------------------- +; +MSG_PROGRESS_RESOLVING_NAME (4000//) +Resolving name %s... +; +; +MSG_PROGRESS_CONNECTING (//) +Connecting to %s... +; +; +MSG_PROGRESS_SEND_HTTP_REQUEST (//) +Sending HTTP Request... +; +; +MSG_PROGRESS_PROCESS_HTTP_RESPONSE (//) +Processing HTTP Response... +; +; +MSG_PROGRESS_DONE (//) +Finished! +; +; +MSG_PROGRESS_FAILURE (//) +Failed to connect to %s : %s +; +; +MSG_PROGRESS_START_UPDATE (//) +Starting Update... +; +; +MSG_PROGRESS_DOWNLOAD_UPDATE (//) +Downloading update %s... +; +; +MSG_PROGRESS_FAILED (//) +Failed. +; +; +MSG_PROGRESS_VERIFY_SIGNATURE (//) +Verifying signature... +; +;----------------------------------------------------------- +; +MSGID_MENU_COMPONENTS_TITLE (5000//) +Components +; +; +MSGID_MENU_COMPONENTS_SELECT_ALL (//) +Select All +; +; +MSGID_MENU_COMPONENTS_SELECT_NONE (//) +Deselect All +; +;----------------------------------------------------------- +; +MSGID_LOG_READ_VERSIONINFO (5500//) +Reading version information from Scalos update server %s.\n +; +; +MSGID_LOG_ERROR_READ_VERSIONINFO (//) +Failed to get version information from Scalos update server %s : %s.\n +; +; +MSGID_LOG_CHECKING_VERSIONS (//) +Processing information about available updates.\n +; +; +MSGID_LOG_UPDATES_FOUND (//) +Found %ld components to update.\n +; +; +MSGID_LOG_UPDATING (//) +Updating component %ld of %ld.\n +; +; +MSGID_LOG_DOWNLOAD_PACKAGE (//) +Downloading update package for %s\n. +; +; +MSGID_LOG_VERIFY_SIGNATURE (//) +Verifying signature of %s update package\n. +; +; +MSGID_LOG_VERIFY_FAIL_SIGNATURE (//) +Failed to update %s - invalid signature!\n +; +; +MSGID_LOG_DOWNLOAD_FAILED_PACKAGE (//) +Failed to download update package for %s - %s.\n +; +; +MSGID_LOG_SKIP_PACKAGE (//) +Skipping update of %s, due to user's request.\n +; +; +MSGID_LOG_UNPACK_PACKAGE (//) +Unpacking update package for %s.\n +; +; +MSGID_LOG_UNPACK_FAIL_PACKAGE (//) +Failed to unpack update for %s.\n +; +; +MSGID_LOG_UNPACK_CATALOGS_FAIL_PACKAGE (//) +Failed to unpack language catalogs for %s.\n +; +; +MSGID_LOG_ERROR_OPEN_LHAFILE (//) +Error: failed to open temporary archive \"%s\" for updating \"%s\".\n +; +; +MSGID_LOG_ERROR_OPEN_INPUTFD (//) +Error: failed to open input file handle for lha: %s\n +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE (6000//) +Updater Module startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD (//) +Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_AMISSL_LIBOPEN_FAIL_AMISSLMASTER (6100//) +Failed to open amisslmaster.library +; +; +MSGID_AMISSL_FAIL_INITAMISSLMASTER (//) +InitAmiSSLMaster failed, probably your AmiSSL installation is too old +; +; +MSGID_AMISSL_FAIL_OPENAMISSL (//) +OpenAmiSSL failed +; +; +MSGID_AMISSL_FAIL_AMISSL_INTERFACE (//) +Couldn't get AmiSSL interface +; +; +MSGID_AMISSL_FAIL_AMISSLMASTER_INTERFACE (//) +Couldn't get AmiSSLMaster interface +; +; +MSGID_AMISSL_FAIL_INITAMISSL (//) +InitAmiSSL failed +; +; +MSGID_AMISSL_FAIL_REQ_FORMAT (//) +Could not initialize AmiSSL:\n\ +%s\n\ +Sorry, but Updater needs a working AmiSSL V3 installation\n\ +(http://www.heightanxiety.com/AmiSSL)/\n\ +to verify the signatures of the downloaded files. +; +;----------------------------------------------------------- +; diff --git a/scalos/Modules/Updater.MUI/Updater.h b/scalos/Modules/Updater.MUI/Updater.h new file mode 100644 index 000000000..a87922134 --- /dev/null +++ b/scalos/Modules/Updater.MUI/Updater.h @@ -0,0 +1,34 @@ +// Updater.h +// $Date$ +// $Revision$ + +#ifndef UPDATER_MODULE_H +#define UPDATER_MODULE_H + +//---------------------------------------------------------------------------- + +#define VERSION_MAJOR 40 +#define VERSION_MINOR 3 + +#define VERS_MAJOR STR(VERSION_MAJOR) +#define VERS_MINOR STR(VERSION_MINOR) + +//---------------------------------------------------------------------------- + +#if defined(__SASC) +int snprintf(char *, size_t, const char *, /*args*/ ...); +int vsnprintf(char *, size_t, const char *, va_list ap); +#endif /* __SASC */ + +//---------------------------------------------------------------------------- + +struct Updater_LocaleInfo +{ + APTR li_LocaleBase; + APTR li_Catalog; + struct LocaleIFace *li_ILocale; +}; + +//---------------------------------------------------------------------------- + +#endif /* UPDATER_MODULE_H */ diff --git a/scalos/Modules/Updater.MUI/config.mk b/scalos/Modules/Updater.MUI/config.mk new file mode 100755 index 000000000..943cb1718 --- /dev/null +++ b/scalos/Modules/Updater.MUI/config.mk @@ -0,0 +1,85 @@ +# $Date: 2011-08-10 15:09:09 +0200 (Mi, 10. Aug 2011) $ +# $Revision: 833 $ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +ICONOBJMCC_DIR = $(TOPLEVEL)/common/IconobjectMCC +AMISSL_INC_DIR = /gg/amissl-v3-sdk/include/include_h + +SCALOS_LOCALE = $(OBJDIR)/Updater_Locale.h + +CFLAGS += -D SCALOSLOCALE=$(SCALOS_LOCALE) + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +INCLUDES += -I$(ICONOBJMCC_DIR) \ + -I$(AMISSL_INC_DIR)\ + +LFLAGS += \ + -lcurl \ + -lz \ + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +INCLUDES += -I$(ICONOBJMCC_DIR) \ + +LFLAGS += -lauto \ + -lcurl \ + -lamisslauto \ + -lz \ + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +INCLUDES += -I$(ICONOBJMCC_DIR) \ + +DEFINES += -DSTATIC_SSL -D__BSD_VISIBLE -DMUI_OBSOLETE + +LFLAGS += \ + -lcurl \ + -lssl \ + -lcrypto \ + -lz \ + +else + +############################################################################### +# AmigaOS + +INCLUDES += -I$(AMISSL_INC_DIR)\ + +LFLAGS += -nodefaultlibs \ + -lcurl \ + -lamissl \ + -lz \ + -lm2 \ + -lgcc \ + -lc \ + -ldebug \ + -lamiga \ + -lstubs \ + +CFLAGS += -Dfd_set=APTR + + +endif +endif +endif diff --git a/scalos/Modules/Updater.MUI/debug.h b/scalos/Modules/Updater.MUI/debug.h new file mode 100644 index 000000000..b5839f9cd --- /dev/null +++ b/scalos/Modules/Updater.MUI/debug.h @@ -0,0 +1,28 @@ +// debug.h +// $Date$ +// $Revision$ + +#ifndef DEBUG_H +#define DEBUG_H + +//---------------------------------------------------------------------------- + +#define d1(x) ; +#define d2(x) x; + +#define debugLock_d1(LockName) ; +#define debugLock_d2(LockName) \ + {\ + char xxName[200];\ + strcpy(xxName, "");\ + NameFromLock((LockName), xxName, sizeof(xxName));\ + KPrintF("%s/%s/%ld: " #LockName "=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, LockName, xxName);\ + } + +// from debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +//---------------------------------------------------------------------------- + +#endif /* DEBUG_H */ diff --git a/scalos/Modules/Updater.MUI/makefile b/scalos/Modules/Updater.MUI/makefile new file mode 100644 index 000000000..8a0059d09 --- /dev/null +++ b/scalos/Modules/Updater.MUI/makefile @@ -0,0 +1,10 @@ +# MakeFile für Updater MUI module +# $Date$ +# $Revision$ + +##################################################################### + +# Updater.module cannot be built with SAS/C + +include makefile-new + diff --git a/scalos/Modules/Updater.MUI/makefile-new b/scalos/Modules/Updater.MUI/makefile-new new file mode 100755 index 000000000..388aca6ea --- /dev/null +++ b/scalos/Modules/Updater.MUI/makefile-new @@ -0,0 +1,101 @@ +# $Date: 2011-08-10 15:09:09 +0200 (Mi, 10. Aug 2011) $ +# $Revision: 833 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL = $(shell pwd)/../.. +endif + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + SDPATH=/ +else + SDPATH=../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(OBJDIR)/Updater.o \ + + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Subdirs +# + +SUBDIRS = $(filter-out Catalogs/sample/Scalos, $(wildcard Catalogs/*/Scalos)) + +############################################################################## +# +# Targets +# + +NAME = Updater.module +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) \ + all_subdirs + +############################################################################## + +$(OBJDIR)/%.o: $(TOOLTYPE_DIR)/%.c + @$(run-cc) + +$(OBJDIR)/%.o: $(ICONOBJMCC_DIR)/%.c + @$(run-cc) + +Updater.c : $(OBJDIR)/Updater_Locale.h + +$(OBJDIR)/Updater_Locale.h : Updater.cd + @$(ECHO) "FlexCat $@" + $(FLEXCAT) $< $@=$(SDPATH)/CatComp_h.sd + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + @$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) +ifneq ($(MACHINE), ppc-amigaos) + -@chmod u+x $@ +endif + +############################################################################## + +install: install_subdirs + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) Scalos:modules/ clone + +clean: clean_subdirs + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* \ + $(OBJDIR)/Updater_Locale.h + +############################################################################## + diff --git a/scalos/Modules/WindowProperties.MUI/Catalogs/deutsch/Scalos/WindowProperties.ct b/scalos/Modules/WindowProperties.MUI/Catalogs/deutsch/Scalos/WindowProperties.ct new file mode 100644 index 000000000..45509711c --- /dev/null +++ b/scalos/Modules/WindowProperties.MUI/Catalogs/deutsch/Scalos/WindowProperties.ct @@ -0,0 +1,464 @@ +; WindowProperties.ct +; $Date$ +; $Revision$ +## version $VER: WindowProperties.catalog 40.6 (11.01.2009 19:01:45) +## codeset 0 +## language deutsch +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Fenstereigenschaften +; +; +MSGID_OKBUTTON +Speichern +; +; +MSGID_SHORTHELP_OKBUTTON +Alle Änderungen in den Merkmalen\n\ +des Schubladen-Piktogramms speichern.\n\ +Gegebenenfalls wird ein neues Piktogramm\n\ +aus dem Standardpiktogramm für Schubladen erzeugt. +;Save the changes in the icon's tooltypes.\n\ +;If necessary, a new icon will be\n\ +;created from a the default icon. +; +; +MSGID_CANCELBUTTON +Abbruch +; +; +MSGID_SHORTHELP_CANCELBUTTON +Alle Änderungen verwerfen und Piktogramm\n\ +der Schublade unverändert belassen. +;Discard all changes and\n\ +;leave the icon unchanged. +; +; +MSGID_CYCLE_NOSTATUSBAR +Statusbalken unterdrücken: +;Hide Status Bar: +; +; +MSGID_CYCLE_NOSTATUSBAR_SHORTHELP +Mit diesem Schalter kann der Statusbalken für dieses\n\ +Fenster abgeschaltet werden, unabhängig von der\n\ +globalen Einstellung. +;This switch can be used to turn off the status bar\n\ +;for this window, independent of the global setting. +; +; +MSGID_POPUP_PATTERNNUMBER +Hintergrundbild: +;Pattern number: +; +; +MSGID_READ_ONLY +(Schreibgeschützt) +;(Read-Only) +; +; +MSGID_TEXT_WINDOWNAME_SHORTHELP +Fenstername +; Window name +; +; +MSGID_TEXT_PARENTDIR_SHORTHELP +Pfad des Ordnerfensters +; Drawer window path +; +; +MSGID_SHOWTHUMBNAILS_NOTSET +(Standard verwenden) +;Never +; +; +MSGID_SHOWTHUMBNAILS_NEVER +Niemals +;Never +; +; +MSGID_SHOWTHUMBNAILS_AS_DEFAULT +Für Standardpiktogr. +;As default +; +; +MSGID_SHOWTHUMBNAILS_ALWAYS +Immer +;Always +; +; +MSGID_CYCLE_THUMBNAILS +Miniaturbilder zeigen: +;Show Thumbnails: +; +; +MSGID_CYCLE_THUMBNAILS_SHORTHELP +Ordnerspezifische Vorgabe für die Anzeige von\n\ +Miniaturbildern für Bilder.\n\ +Ist die Vorgabe nicht gesetzt, wird die\n\ +globale Einstellung verwendet. +;Individual drawer-specific setting for thumbnail display.\n\ +;If not set, the default setting from Scalos prefs is used. +; +; +MSGID_CHECKOVERLAP_NO +Nein +;No +; +; +MSGID_CHECKOVERLAP_YES +Ja +;Yes +; +; +MSGID_CHECKOVERLAP_NOTSET +(Standard verwenden) +;(not set) +; +; +MSGID_CYCLE_CHECKOVERLAP +Piktogrammüberlappung prüfen: +;Check Overlapping Icons: +; +; +MSGID_CYCLE_CHECKOVERLAP_SHORTHELP +Ordnerspezifische Vorgabe für die Prüfung auf überlappende Piktogramme.\n\ +Ist die Prüfung eingeschaltet, werden alle Piktogramme verschoben, die\n\ +andere Piktogramme überlappen könnten. +;Individual drawer-specific setting for overlapping icons check.\n\ +;If set icons that overlap any other icon will be repositioned. +; +; +MSGID_HIDESTATUSBAR_NOTSET +(Standard verwenden) +;(not set) +; +; +MSGID_HIDESTATUSBAR_HIDE +unterdrücken +;Hidden +; +; +MSGID_TRANSPARENCY_ACTIVEWINDOW +Fenster aktiv +;Active window state +; +; +MSGID_TRANSPARENCY_INACTIVEWINDOW +Fenster inaktiv +;Inactive window state +; +; +MSGID_TRANSPARENCY_ACTIVEWINDOW_SHORTHELP +Hier wird der Grad der Durchsichtigkeit für\n\ +das aktive Scalos-Fenster eingestellt.\n\ +Die Arbeitsfläche wird nur transparent,\n\ +wenn sie kein Hintergundfenster ist. +;Here you can select the degree of transparency\n\ +;for the active Scalos desktop, icon, or text window.\n\ +;The desktop will only get transparent if it is not a backdrop window. +; +; +MSGID_TRANSPARENCY_INACTIVEWINDOW_SHORTHELP +Hier wird der Grad der Durchsichtigkeit für alle\n\ +inaktiven Scalos-Fenster eingestellt.\n\ +Die Arbeitsfläche wird nur transparent,\n\ +wenn sie kein Hintergundfenster ist. +;Here you can select the degree of transparency\n\ +;for all inactive Scalos desktop, icon, or text windows.\n\ +;The desktop will only get transparent if it is not a backdrop window. +; +; +MSGID_TRANSPARENCY_OPAQUE +Undurchsichtig +;opaque +; +; +MSGID_TRANSPARENCY_TRANSPARENT +Transparent +;transparent +; +; +MSGID_CHECKBOX_TRANSPARENCY_USEDEFAULT +Standard verwenden: +;Use default: +; +; +MSGID_CHECKBOX_TRANSPARENCY_USEDEFAULT_SHORTHELP +Standard verwenden: +;Use default: +; +; +MSGID_CYCLE_NOCONTROLBAR +Steuerleiste unterdrücken: +;Hide Control Bar: +; +; +MSGID_CYCLE_NOCONTROLBAR_SHORTHELP +Mit diesem Schalter kann die Steuerleiste für dieses\n\ +Fenster abgeschaltet werden, unabhängig von der\n\ +globalen Einstellung. +;This switch can be used to turn off the control bar\n\ +;for this window, independent of the global setting. +; +; +MSGID_HIDECONTROLBAR_NOTSET +(Standard verwenden) +;(not set) +; +; +MSGID_HIDECONTROLBAR_HIDE +unterdrücken +;Hidden +; +; +MSGID_GROUP_ICONSCALING +Piktogrammskalierung +;Icon Scaling +; +; +MSGID_ICONSCALING_NOMINALSIZE_SHORTHELP +Dies ist die Standardskalierung für alle Piktogramme in diesem Fenster. +;Standard size adjustment applied to all icons. +; +; +MSGID_ICONSCALING_NOMINALSIZE +Standardgröße: +;Nominal Size: +; +; +MSGID_ICONSCALING_PERCENT +% +; +; +MSGID_ICONSCALING_MINSIZE +Minimalgröße: +;Minimum Size: +; +; +MSGID_ICONSCALING_MINSIZE_SHORTHELP +Minimale Größe für alle Piktogramme in diesem Fenster.\n\ +Kleinere Piktogramme werden auf die Mindestgröße skaliert. +;Minimum size for displayed icons.\n\ +;Smaller icons will be scaled to\n\ +;the specified minimum size. +; +; +MSGID_ICONSCALING_MAXSIZE +Maximalgröße: +;Maximum Size: +; +; +MSGID_ICONSCALING_MAXSIZE_SHORTHELP +Maximale Größe für alle Piktogramme in diesem Fenster.\n\ +Größere Piktogramme werden auf die Maximalgröße skaliert. +;Maximum size for displayed icons.\n\ +;Larger icons will be scaled to\n\ +;the specified maximum size. +; +; +MSGID_CHECKBOX_ICONSCALING_NOMINALSIZE +Standard verwenden: +;Use default: +; +; +MSGID_CHECKBOX_ICONSCALING_NOMINALSIZE_SHORTHELP +Dieser Schalter legt fest, ob der globale Wert für die\n\ +Piktogrammskalierung aus dem Scalos Voreinsteller verwendet wird.\n\ +Wenn ausgeschaltet, wird in diesem Fenster ein\n\ +individueller Wert für die Piktogrammskalierung benutzt. +;If this checkbox is checked, global icon scaling from Scalos Preferences is used.\n\ +;Turn off this checkbox to specify individual icon scaling for this window. +; +; +MSGID_CHECKBOX_ICONSIZECONSTRAINTS_USEDEFAULT +Standard verwenden: +;Use default: +; +; +MSGID_CHECKBOX_ICONSIZECONSTRAINTS_USEDEFAULT_SHORTHELP +Dieser Schalter legt fest, ob die globale Werte für die\n\ +Piktogrammgrößenbegrenzung aus dem Scalos Voreinsteller verwendet werden.\n\ +Wenn ausgeschaltet, werden in diesem Fenster\n\ +individuelle Werte für die Piktogrammgrößenbegrenzung benutzt. +;If this checkbox is checked, global icon size\n\ +;constraints from Scalos Preferences are used.\n\ +;Turn off this checkbox to specify individual\n\ +;icon size constraints for this window. +; +;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Projekt +;Project +; +; +MSGID_MENU_PROJECT_ABOUT +Über... +;About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Über MUI... +;About MUI... +; +; +MSGID_MENU_PROJECT_QUIT +Beenden +;Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +;Q +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +_OK +;_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos WindowProperties.module V%ld.%ld\033n\n\ +%s\n\ +© 2004%s Das Scalos Team +;\33c\033bScalos WindowProperties.module V%ld.%ld\033n\n\ +;© 2004%s The Scalos Team +; +;----------------------------------------------------------- +; +MSGID_THUMBNAILS_LIFETIME_FOREVER +niemals +;never +; +; +MSGID_THUMBNAILS_LIFETIME_NOTSET +(Standard verwenden) +;(Default) +; +; +MSGID_ICONSPAGE_THUMBNAILS_MAXAGE +Vorschaubilder aufräumen nach: +;Cleanup thumbnails after: +; +; +MSGID_ICONSPAGE_THUMBNAILS_MAXAGE_SHORTHELP +Um die Größe der Zwischenspeicherdatei in Grenzen\n\ +zu halten, werden die zwischengespeicherten Vorschaubilder\n\ +gelöscht, wenn sie länger als die eingestellte Anzahl\n\ +Tage nicht benutzt wurden.\n\ +Mit der Einstellung \033b(Standard verwenden)\033n wird die\n\ +systemweite Einstellung benutzt. +;Cached thumbnail images will be removed from the cache\n\ +;if they have not been accessed for more than the\n\ +;specified number of days, in order to keep cache\n\ +;size as small as possible. +;If \033b(Default)\033n is selected, the global setting is used. +; +; +MSGID_ICONSPAGE_THUMBNAILS_MAXAGE_DAYS +Tagen +;days +; +;----------------------------------------------------------- +; +MSGID_COLUMNTITLE_1 +\33bNr. +;\33bNr. +; +; +MSGID_COLUMNTITLE_3 +\33bVorschau +;\33bPreview +; +; +MSGID_REQTITLE_READERROR +Fehler beim Lesen der Hintergrundbilder-Einstellungs-\n\ +Datei \"%s\"\n\ +%s +;Error reading pattern preferences\n\ +;file \"%s\"\n\ +;%s +; +; +MSGID_LOADING_THUMBNAIL +\33cLade Miniatur-Vorschaubild für +;\33cLoading Pattern Thumbnail for +; +; +MSGID_PROGRESS_THUMBNAILS +\33c%ld/%ld +;\33c%ld/%ld +; +; +MSGID_LOADING_THUMBNAILS +\033cVorschaubilder laden... +;\033cLoading Pattern Thumbnails... +; +; +MSGID_WINDOW_STARTUP +Scalos Fenstereigenschaften Start +;Scalos Window Properties Startup +; +; +MSGID_PATTERNR_DEFAULT +(Standard) +;(default) +; +;----------------------------------------------------------- +; +MSGID_ICONSIZES_16x16 +16 x 16 +;16 x 16 +; +; +MSGID_ICONSIZES_24x24 +24 x 24 +;24 x 24 +; +; +MSGID_ICONSIZES_32x32 +32 x 32 +;32 x 32 +; +; +MSGID_ICONSIZES_48x48 +48 x 48 +;48 x 48 +; +; +MSGID_ICONSIZES_64x64 +64 x 64 +;64 x 64 +; +; +MSGID_ICONSIZES_96x96 +96 x 96 +;96 x 96 +; +; +MSGID_ICONSIZES_128x128 +128 x 128 +;128 x 128 +; +; +MSGID_ICONSIZES_UNLIMITED +unbegrenzt +;unlimited +; +;----------------------------------------------------------- +; +MSGID_REGISTERTITLE_WINDOW +Fenster +;Window +; +; +MSGID_REGISTERTITLE_ICONS +Piktogramme +;Icons +; +;----------------------------------------------------------- diff --git a/scalos/Modules/WindowProperties.MUI/Catalogs/deutsch/Scalos/config.mk b/scalos/Modules/WindowProperties.MUI/Catalogs/deutsch/Scalos/config.mk new file mode 100755 index 000000000..8631b0623 --- /dev/null +++ b/scalos/Modules/WindowProperties.MUI/Catalogs/deutsch/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = deutsch + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = german + +else + +############################################################################### +# AmigaOS and AROS + +LANG = deutsch + +endif +endif diff --git a/scalos/Modules/WindowProperties.MUI/Catalogs/deutsch/Scalos/makefile b/scalos/Modules/WindowProperties.MUI/Catalogs/deutsch/Scalos/makefile new file mode 100644 index 000000000..99a6aae8c --- /dev/null +++ b/scalos/Modules/WindowProperties.MUI/Catalogs/deutsch/Scalos/makefile @@ -0,0 +1,13 @@ +# makefile for WindowProperties.module (translated Texts : deutsch) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mdeutsch\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +WindowProperties.catalog : WindowProperties.ct ../../../WindowProperties.cd + +All: WindowProperties.catalog diff --git a/scalos/Modules/WindowProperties.MUI/Catalogs/deutsch/Scalos/makefile-new b/scalos/Modules/WindowProperties.MUI/Catalogs/deutsch/Scalos/makefile-new new file mode 100644 index 000000000..bd6ba0724 --- /dev/null +++ b/scalos/Modules/WindowProperties.MUI/Catalogs/deutsch/Scalos/makefile-new @@ -0,0 +1,30 @@ +# makefile for WindowProperties.module (translated Texts : deutsch) +# $Date: 2011-07-24 10:11:00 +0200 (So, 24. Jul 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = WindowProperties + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git "a/scalos/Modules/WindowProperties.MUI/Catalogs/fran\303\247ais/Scalos/WindowProperties.ct" "b/scalos/Modules/WindowProperties.MUI/Catalogs/fran\303\247ais/Scalos/WindowProperties.ct" new file mode 100755 index 000000000..b5894441b --- /dev/null +++ "b/scalos/Modules/WindowProperties.MUI/Catalogs/fran\303\247ais/Scalos/WindowProperties.ct" @@ -0,0 +1,423 @@ +; WindowProperties.ct +; $Date$ +; $Revision$ +; $Id$ +; +## version $VER: WindowProperties.catalog 40.6 (11.01.2009 19:01:45) +## codeset 0 +## language français +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Propriétés des fenêtres +; Scalos Window Properties +; +; +MSGID_OKBUTTON +D'accord +; Ok +; +; +MSGID_SHORTHELP_OKBUTTON +Enregistre les changements dans les types\n\ +d'outils de l'icône\n\ +Si nécessaire, une nouvelle icône sera\n\ +créée d'après le type d'icône par défaut. +; Save the changes in the icon's tooltypes.\n\ +; If necessary, a new icon will be\n\ +; created from a the default icon. +; +; +MSGID_CANCELBUTTON +Annuler +; Cancel +; +; +MSGID_SHORTHELP_CANCELBUTTON +Oublier tout changement en cours.\n\ +L'icône ne sera pas modifiée. +; Discard all changes and\n\ +; leave the icon unchanged. +; +; +MSGID_CYCLE_NOSTATUSBAR +Cacher la barre de statut: +; Hide Status Bar: +; +; +MSGID_CYCLE_NOSTATUSBAR_SHORTHELP +Si activé la barre de statut\n\ +de la fenêtre sera cachée.\n\ +Le type d'outil: \033bSCALOS_NOSTATUSBAR\033n,\n\ +sera insèrer dans l'icône du répertoire parent. +;This switch can be used to turn off the status bar\n\ +;for this window, independent of the global setting. +; +; +MSGID_POPUP_PATTERNNUMBER +Numéro du motif de fond: +; Pattern number: +; +; +MSGID_READ_ONLY +(Lecture-Seulement) +; (Read-Only) +; +; +MSGID_TEXT_WINDOWNAME_SHORTHELP +Nom de la fenêtre +; Window name +; +; +MSGID_TEXT_PARENTDIR_SHORTHELP +Chemin d'accès de la fenêtre +; Drawer window path +; +; +MSGID_SHOWTHUMBNAILS_NOTSET +(Non défini) +;(not set) +; +; +MSGID_SHOWTHUMBNAILS_NEVER +Jamais +;Never +; +; +MSGID_SHOWTHUMBNAILS_AS_DEFAULT +Icônes par défaut +;As default +; +; +MSGID_SHOWTHUMBNAILS_ALWAYS +Toujours +;Always +; +; +MSGID_CYCLE_THUMBNAILS +Afficher les vignettes: +;Show Thumbnails: +; +; +MSGID_CYCLE_THUMBNAILS_SHORTHELP +Option individuelle des répertoires\n\ +pour l'affichage des vignettes.\n\ +Si non défini, l'option par défaut,\n\ +depuis "Scalos prefs", est utilisée. +;Individual drawer-specific setting for thumbnail display.\n\ +;If not set, the default setting from Scalos prefs is used. +; +MSGID_CHECKOVERLAP_NO +Non +;No +; +MSGID_CHECKOVERLAP_YES +Oui +;Yes +; +MSGID_CHECKOVERLAP_NOTSET +(non saisi) +;(not set) +; +MSGID_CYCLE_CHECKOVERLAP +Analyser les icônes se chevauchant : +;Check Overlapping Icons: +; +MSGID_CYCLE_CHECKOVERLAP_SHORTHELP +Option spécifique au répertoires pour l'analyse des icônes se chevauchant.\n\ +Si coché les icônes chevauchant d'autres icônes seront repsitionnées. +;Individual drawer-specific setting for overlapping icons check.\n\ +;If set icons that overlap any other icon will be repositioned. +; +MSGID_HIDESTATUSBAR_NOTSET +(non saisi) +;(not set) +; +MSGID_HIDESTATUSBAR_HIDE +Caché +;Hidden +; +MSGID_TRANSPARENCY_ACTIVEWINDOW +Etat de la fenêtre active +;Active window state +; +MSGID_TRANSPARENCY_INACTIVEWINDOW +Etat de la fenêtre inactive +;Inactive window state +; +MSGID_TRANSPARENCY_ACTIVEWINDOW_SHORTHELP +Ici vous pouvez choisir le degrès de transparence\n\ +pour le bureau, icône ou la fenêtre en mode listeur activés.\n\ +Le bureau sera transparent seulement si il n'est pas en arrière-plan. +; Here you can select the degree of transparency\n\ +; for the active Scalos desktop, icon, or text window.\n\ +; The desktop will only get transparent if it is not a backdrop window. +; +MSGID_TRANSPARENCY_INACTIVEWINDOW_SHORTHELP +Ici vous pouvez choisir le degrès de transparence\n\ +pour le bureau, icône ou la fenêtre en mode listeur inactivés.\n\ +Le bureau sera tranparent seulement si il n'est pas en arrière-plan. +; Here you can select the degree of transparency\n\ +; for all inactive Scalos desktop, icon, or text windows.\n\ +; The desktop will only get transparent if it is not a backdrop window. +; +MSGID_TRANSPARENCY_OPAQUE +Opaque +;opaque +; +MSGID_TRANSPARENCY_TRANSPARENT +Transparent +; transparent +; +MSGID_CHECKBOX_TRANSPARENCY_USEDEFAULT +Par défaut +; Use default +; +MSGID_CHECKBOX_TRANSPARENCY_USEDEFAULT_SHORTHELP +Par défaut +; Use default +; +MSGID_CYCLE_NOCONTROLBAR +Cacher la barre de contrôle : +;Hide Control Bar: +; +MSGID_CYCLE_NOCONTROLBAR_SHORTHELP +Ce gadget peut être utilisé pour désactiver la barre de contrôle\n\ +pour cette fenêtre, indépendement du réglage global. +;This switch can be used to turn off the control bar\n\ +;for this window, independent of the global setting. +; +MSGID_HIDECONTROLBAR_NOTSET +(non saisi) +;(not set) +; +MSGID_HIDECONTROLBAR_HIDE +Caché +;Hidden +; +MSGID_GROUP_ICONSCALING +Dimensions de l'icône +;Icon Scaling +; +MSGID_ICONSCALING_NOMINALSIZE_SHORTHELP +Ajustement standard appliqué à toutes les icônes. +;Standard size adjustment applied to all icons. +; +MSGID_ICONSCALING_NOMINALSIZE +Taille nominale : +;Nominal Size: +; +MSGID_ICONSCALING_PERCENT +% +; +MSGID_ICONSCALING_MINSIZE +Taille minimum : +;Minimum Size: +; +MSGID_ICONSCALING_MINSIZE_SHORTHELP +Taille minimum d'affichage des icôness.\n\ +Les plus petites icônes seront redimensionnées\n\ +d'aprés la taille minimum spécifiée. +;Minimum size for displayed icons.\n\ +;Smaller icons will be scaled to\n\ +;the specified minimum size. +; +MSGID_ICONSCALING_MAXSIZE +Taille maximum : +;Maximum Size: +; +MSGID_ICONSCALING_MAXSIZE_SHORTHELP +taille maximum d'affichage des icônes.\n\ +Les plus grandes icônes seront redimensionnées\n\ +d'aprés la taille maxiimum spécifiée. +;Maximum size for displayed icons.\n\ +;Larger icons will be scaled to\n\ +;the specified maximum size. +; +MSGID_CHECKBOX_ICONSCALING_NOMINALSIZE +Par défaut : +;Use default: +; +MSGID_CHECKBOX_ICONSCALING_NOMINALSIZE_SHORTHELP +Si ce gadget est activé, la redimension globale, depuis les préferences de Scalos\n\ +est utilisée. Décochez ce gadget afin de spécifier la redimension individuelle d'une\n\ +icône, pour cette fenêtre. +;If this checkbox is checked, global icon scaling from Scalos Preferences is used.\n\ +;Turn off this checkbox to specify individual icon scaling for this window. +; +MSGID_CHECKBOX_ICONSIZECONSTRAINTS_USEDEFAULT +Par défaut : +;Use default: +; +MSGID_CHECKBOX_ICONSIZECONSTRAINTS_USEDEFAULT_SHORTHELP +Si ce gadget est activé, les contraintes globales de la taille\n\ +des icônes, depuis les préferences de Scalos, seront utilisées.\n\ +décochez ce gadget afin de spécifier les contraintes\n\ +de la taille des icônes pour cette fenêtre. +;If this checkbox is checked, global icon size\n\ +;constraints from Scalos Preferences are used.\n\ +;Turn off this checkbox to specify individual\n\ +;icon size constraints for this window. +; +;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Projet +; Project +; +; +MSGID_MENU_PROJECT_ABOUT +A propos... +; About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI +A propos de MUI... +; About MUI... +; +; +MSGID_MENU_PROJECT_QUIT +Quitter +; Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; Q +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +D'accord +; _OK +; +; +MSGID_ABOUTREQFORMAT +\033c\033bScalos Main IconProperties.module V\0333%ld\0332.\0333%ld\0332\033n\n\ +%s\n\ +© 2004%s The Scalos Team +; \33c\033bScalos Main IconProperties.module V%ld.%ld\033n\n\ +; © 2004 The Scalos Team +; +;----------------------------------------------------------- +MSGID_THUMBNAILS_LIFETIME_FOREVER +Jamais +;never +; +MSGID_THUMBNAILS_LIFETIME_NOTSET +(Défaut) +;(Default) +; +MSGID_ICONSPAGE_THUMBNAILS_MAXAGE +Nettoyage des vignettes après : +;Cleanup thumbnails after: +; +MSGID_ICONSPAGE_THUMBNAILS_MAXAGE_SHORTHELP +Les vignettes du cache seront supprimées\n\ +si elles n'ont pu être localisées aprés le\n\ +nombre de jours spécifié, afin de limiter autant\n\ +que possible la taille du cache.\n\ +Si \033b(Défaut)\033n est sélectionné, l'option globale est utilisée. +;Cached thumbnail images will be removed from the cache\n\ +;if they have not been accessed for more than the\n\ +;specified number of days, in order to keep cache\n\ +;size as small as possible.\n\ +;If \033b(Default)\033n is selected, the global setting is used. +; +MSGID_ICONSPAGE_THUMBNAILS_MAXAGE_DAYS +jours +;days +; +;----------------------------------------------------------- +; +MSGID_COLUMNTITLE_1 +\033bN°. +;\33bNr. +; +; +MSGID_COLUMNTITLE_3 +\33bAperçu +;\33bPreview +; +; +MSGID_REQTITLE_READERROR +Erreur de chargement des\n\ +préferences des motifs,\n\ +fichier : \"%s\"\n\ +%s +;Error reading pattern preferences\n\ +;file \"%s\"\n\ +;%s +; +; +MSGID_LOADING_THUMBNAIL +\33cChargement d'une vignette pour +;\33cLoading Pattern Thumbnail for +; +; +MSGID_PROGRESS_THUMBNAILS +\33c%ld/%ld +;\33c%ld/%ld +; +; +MSGID_LOADING_THUMBNAILS +\033cChargement des vignettes... +;\033cLoading Pattern Thumbnails... +; +; +MSGID_WINDOW_STARTUP +Proprièté des fenêtres de Scalos +;Scalos Window Properties Startup +; +; +MSGID_PATTERNR_DEFAULT +(défaut) +;(default) +; +;----------------------------------------------------------- +; +MSGID_ICONSIZES_16x16 +16 x 16 +;16 x 16 +; +MSGID_ICONSIZES_24x24 +24 x 24 +;24 x 24 +; +MSGID_ICONSIZES_32x32 +32 x 32 +;32 x 32 +; +MSGID_ICONSIZES_48x48 +48 x 48 +;48 x 48 +; +MSGID_ICONSIZES_64x64 +64 x 64 +;64 x 64 +; +MSGID_ICONSIZES_96x96 +96 x 96 +;96 x 96 +; +MSGID_ICONSIZES_128x128 +128 x 128 +;128 x 128 +; +MSGID_ICONSIZES_UNLIMITED +Illimitée +;unlimited +; +;----------------------------------------------------------- +; +MSGID_REGISTERTITLE_WINDOW +Fenêtre +;Window +; +MSGID_REGISTERTITLE_ICONS +Icônes +;Icons +; +;----------------------------------------------------------- diff --git "a/scalos/Modules/WindowProperties.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" "b/scalos/Modules/WindowProperties.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" new file mode 100755 index 000000000..8b7056423 --- /dev/null +++ "b/scalos/Modules/WindowProperties.MUI/Catalogs/fran\303\247ais/Scalos/config.mk" @@ -0,0 +1,40 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = français + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = french + +else + +############################################################################### +# AmigaOS and AROS + +LANG = français + +endif +endif diff --git "a/scalos/Modules/WindowProperties.MUI/Catalogs/fran\303\247ais/Scalos/makefile" "b/scalos/Modules/WindowProperties.MUI/Catalogs/fran\303\247ais/Scalos/makefile" new file mode 100644 index 000000000..73d0141f8 --- /dev/null +++ "b/scalos/Modules/WindowProperties.MUI/Catalogs/fran\303\247ais/Scalos/makefile" @@ -0,0 +1,13 @@ +# makefile for WindowProperties.module (translated Texts : français) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mfrançais\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +WindowProperties.catalog : WindowProperties.ct ../../../WindowProperties.cd + +All: WindowProperties.catalog diff --git "a/scalos/Modules/WindowProperties.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" "b/scalos/Modules/WindowProperties.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" new file mode 100644 index 000000000..c42377227 --- /dev/null +++ "b/scalos/Modules/WindowProperties.MUI/Catalogs/fran\303\247ais/Scalos/makefile-new" @@ -0,0 +1,30 @@ +# makefile for WindowProperties.module (translated Texts : français) +# $Date: 2011-07-24 10:11:00 +0200 (So, 24. Jul 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = WindowProperties + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Modules/WindowProperties.MUI/Catalogs/sample/Scalos/WindowProperties.ct b/scalos/Modules/WindowProperties.MUI/Catalogs/sample/Scalos/WindowProperties.ct new file mode 100644 index 000000000..c994ecf88 --- /dev/null +++ b/scalos/Modules/WindowProperties.MUI/Catalogs/sample/Scalos/WindowProperties.ct @@ -0,0 +1,429 @@ +; WindowProperties.ct +## version $VER: WindowProperties.catalog 40.6 (11.01.2009 19:01:45) +## codeset 0s +## language xxxxxx +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Window Properties +; +; +MSGID_OKBUTTON +Ok +; +; +MSGID_SHORTHELP_OKBUTTON +Save the changes in the icon's tooltypes.\n\ +If necessary, a new icon will be\n\ +created from a the default icon. +; +; +MSGID_CANCELBUTTON +Cancel +; +; +MSGID_SHORTHELP_CANCELBUTTON +Discard all changes and\n\ +leave the icon unchanged. +; +; +MSGID_CYCLE_NOSTATUSBAR +Hide Status Bar: +;Hide Status Bar: +; +; +MSGID_CYCLE_NOSTATUSBAR_SHORTHELP +This switch can be used to turn off the status bar\n\ +for this window, independent of the global setting. +;This switch can be used to turn off the status bar\n\ +;for this window, independent of the global setting. +; +; +MSGID_POPUP_PATTERNNUMBER +Pattern number: +;Pattern number: +; +; +MSGID_READ_ONLY +(Read-Only) +;(Read-Only) +; +; +MSGID_TEXT_WINDOWNAME_SHORTHELP +Window name +; Window name +; +; +MSGID_TEXT_PARENTDIR_SHORTHELP +Drawer window path +; Drawer window path +; +;+++translateme+++ +MSGID_SHOWTHUMBNAILS_NOTSET +(not set) +;(not set) +; +;+++translateme+++ +MSGID_SHOWTHUMBNAILS_NEVER +Never +;Never +; +;+++translateme+++ +MSGID_SHOWTHUMBNAILS_AS_DEFAULT +As default +;As default +; +;+++translateme+++ +MSGID_SHOWTHUMBNAILS_ALWAYS +Always +;Always +; +;+++translateme+++ +MSGID_CYCLE_THUMBNAILS +Show Thumbnails +;Show Thumbnails +; +;+++translateme+++ +MSGID_CYCLE_THUMBNAILS_SHORTHELP +Individual drawer-specific setting for thumbnail display.\n\ +If not set, the default setting from Scalos prefs is used. +;Individual drawer-specific setting for thumbnail display.\n\ +;If not set, the default setting from Scalos prefs is used. +; +;+++translateme+++ +MSGID_CHECKOVERLAP_NO +No +; +;+++translateme+++ +MSGID_CHECKOVERLAP_YES +Yes +; +;+++translateme+++ +MSGID_CHECKOVERLAP_NOTSET +(not set) +; +;+++translateme+++ +MSGID_CYCLE_CHECKOVERLAP +Check Overlapping Icons: +; +;+++translateme+++ +MSGID_CYCLE_CHECKOVERLAP_SHORTHELP +Individual drawer-specific setting for overlapping icons check.\n\ +If set icons that overlap any other icon will be repositioned. +; +;+++translateme+++ +MSGID_HIDESTATUSBAR_NOTSET +(not set) +;(not set) +; +;+++translateme+++ +MSGID_HIDESTATUSBAR_HIDE +Hidden +;Hidden +; +;+++translateme+++ +MSGID_TRANSPARENCY_ACTIVEWINDOW +Active window state +; +;+++translateme+++ +MSGID_TRANSPARENCY_INACTIVEWINDOW +Inactive window state +; +;+++translateme+++ +MSGID_TRANSPARENCY_ACTIVEWINDOW_SHORTHELP +Here you can select the degree of transparency\n\ +for the active Scalos desktop, icon, or text window.\n\ +The desktop will only get transparent if it is not a backdrop window. +; +;+++translateme+++ +MSGID_TRANSPARENCY_INACTIVEWINDOW_SHORTHELP +Here you can select the degree of transparency\n\ +for all inactive Scalos desktop, icon, or text windows.\n\ +The desktop will only get transparent if it is not a backdrop window. +; +;+++translateme+++ +MSGID_TRANSPARENCY_OPAQUE +opaque +; +;+++translateme+++ +MSGID_TRANSPARENCY_TRANSPARENT +transparent +; +;+++translateme+++ +MSGID_CHECKBOX_TRANSPARENCY_USEDEFAULT +Use default: +; +;+++translateme+++ +MSGID_CHECKBOX_TRANSPARENCY_USEDEFAULT_SHORTHELP +Use default: +; +;+++translateme+++ +MSGID_CYCLE_NOCONTROLBAR +Hide Control Bar: +;Hide Control Bar: +; +;+++translateme+++ +MSGID_CYCLE_NOCONTROLBAR_SHORTHELP +This switch can be used to turn off the control bar\n\ +for this window, independent of the global setting. +;This switch can be used to turn off the control bar\n\ +;for this window, independent of the global setting. +; +;+++translateme+++ +MSGID_HIDECONTROLBAR_NOTSET +(not set) +;(not set) +; +;+++translateme+++ +MSGID_HIDECONTROLBAR_HIDE +Hidden +;Hidden +; +;+++translateme+++ +MSGID_GROUP_ICONSCALING +Icon Scaling +;Icon Scaling +; +;+++translateme+++ +MSGID_ICONSCALING_NOMINALSIZE_SHORTHELP +Standard size adjustment applied to all icons. +;Standard size adjustment applied to all icons. +; +;+++translateme+++ +MSGID_ICONSCALING_NOMINALSIZE +Nominal Size: +;Nominal Size: +; +;+++translateme+++ +MSGID_ICONSCALING_PERCENT +% +; +;+++translateme+++ +MSGID_ICONSCALING_MINSIZE +Minimum Size: +;Minimum Size: +; +;+++translateme+++ +MSGID_ICONSCALING_MINSIZE_SHORTHELP +Minimum size for displayed icons.\n\ +Smaller icons will be scaled to\n\ +the specified minimum size. +;Minimum size for displayed icons.\n\ +;Smaller icons will be scaled to\n\ +;the specified minimum size. +; +;+++translateme+++ +MSGID_ICONSCALING_MAXSIZE +Maximum Size: +;Maximum Size: +; +;+++translateme+++ +MSGID_ICONSCALING_MAXSIZE_SHORTHELP +Maximum size for displayed icons.\n\ +Larger icons will be scaled to\n\ +the specified maximum size. +;Maximum size for displayed icons.\n\ +;Larger icons will be scaled to\n\ +;the specified maximum size. +; +;+++translateme+++ +MSGID_CHECKBOX_ICONSCALING_NOMINALSIZE +Use default: +;Use default: +; +;+++translateme+++ +MSGID_CHECKBOX_ICONSCALING_NOMINALSIZE_SHORTHELP +If this checkbox is checked, global icon scaling from Scalos Preferences is used.\n\ +Turn off this checkbox to specify individual icon scaling for this window. +;If this checkbox is checked, global icon scaling from Scalos Preferences is used.\n\ +;Turn off this checkbox to specify individual icon scaling for this window. +; +;+++translateme+++ +MSGID_CHECKBOX_ICONSIZECONSTRAINTS_USEDEFAULT +Use default: +;Use default: +; +;+++translateme+++ +MSGID_CHECKBOX_ICONSIZECONSTRAINTS_USEDEFAULT_SHORTHELP +If this checkbox is checked, global icon size\n\ +constraints from Scalos Preferences are used.\n\ +Turn off this checkbox to specify individual\n\ +icon size constraints for this window. +;If this checkbox is checked, global icon size\n\ +;constraints from Scalos Preferences are used.\n\ +;Turn off this checkbox to specify individual\n\ +;icon size constraints for this window. +; +;----------------------------------------------------------- +; +MSGID_MENU_PROJECT +Project +;Project +; +; +MSGID_MENU_PROJECT_ABOUT +About... +;About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI +About MUI... +;About MUI... +; +; +MSGID_MENU_PROJECT_QUIT +Quit +;Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +;Q +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +_OK +;_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Main IconProperties.module V%ld.%ld\033n\n\ +© 2004 The Scalos Team +;\33c\033bScalos Main IconProperties.module V%ld.%ld\033n\n\ +;© 2004 The Scalos Team +; +;----------------------------------------------------------- +; +MSGID_THUMBNAILS_LIFETIME_FOREVER +never +;never +; +; +MSGID_THUMBNAILS_LIFETIME_NOTSET +(Default) +;(Default) +; +; +MSGID_ICONSPAGE_THUMBNAILS_MAXAGE +Cleanup thumbnails after: +;Cleanup thumbnails after: +; +; +MSGID_ICONSPAGE_THUMBNAILS_MAXAGE_SHORTHELP +The thumbnail images in the cache will be removed\n\ +if they have not been accessed for more than the\n\ +specified number of days, in order to keep cache\n\ +size as small as possible.\n\ +If \033b(Default)\033n is selected, the global setting is used. +;Cached thumbnail images will be removed from the cache\n\ +;if they have not been accessed for more than the\n\ +;specified number of days, in order to keep cache\n\ +;size as small as possible.\n\ +;If \033b(Default)\033n is selected, the global setting is used. +; +; +MSGID_ICONSPAGE_THUMBNAILS_MAXAGE_DAYS +days +;days +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_COLUMNTITLE_1 +\33bNr. +;\33bNr. +; +;+++translateme+++ +MSGID_COLUMNTITLE_3 +\33bPreview +;\33bPreview +; +;+++translateme+++ +MSGID_REQTITLE_READERROR +Error reading pattern preferences\n\ +file \"%s\"\n\ +%s +;Error reading pattern preferences\n\ +;file \"%s\"\n\ +;%s +; +;+++translateme+++ +MSGID_LOADING_THUMBNAIL +\33cLoading Pattern Thumbnail for +;\33cLoading Pattern Thumbnail for +; +;+++translateme+++ +MSGID_PROGRESS_THUMBNAILS +\33c%ld/%ld +;\33c%ld/%ld +; +;+++translateme+++ +MSGID_LOADING_THUMBNAILS +\033cLoading Pattern Thumbnails... +;\033cLoading Pattern Thumbnails... +; +;+++translateme+++ +MSGID_WINDOW_STARTUP +Scalos Window Properties Startup +;Scalos Window Properties Startup +; +;+++translateme+++ +MSGID_PATTERNR_DEFAULT +(default) +;(default) +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_ICONSIZES_16x16 +16 x 16 +;16 x 16 +; +;+++translateme+++ +MSGID_ICONSIZES_24x24 +24 x 24 +;24 x 24 +; +;+++translateme+++ +MSGID_ICONSIZES_32x32 +32 x 32 +;32 x 32 +; +;+++translateme+++ +MSGID_ICONSIZES_48x48 +48 x 48 +;48 x 48 +; +;+++translateme+++ +MSGID_ICONSIZES_64x64 +64 x 64 +;64 x 64 +; +;+++translateme+++ +MSGID_ICONSIZES_96x96 +96 x 96 +;96 x 96 +; +;+++translateme+++ +MSGID_ICONSIZES_128x128 +128 x 128 +;128 x 128 +; +;+++translateme+++ +MSGID_ICONSIZES_UNLIMITED +unlimited +;unlimited +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_REGISTERTITLE_WINDOW +Window +;Window +; +;+++translateme+++ +MSGID_REGISTERTITLE_ICONS +Icons +;Icons +; +;----------------------------------------------------------- diff --git a/scalos/Modules/WindowProperties.MUI/NoDebug b/scalos/Modules/WindowProperties.MUI/NoDebug new file mode 100755 index 000000000..49ed68d29 --- /dev/null +++ b/scalos/Modules/WindowProperties.MUI/NoDebug @@ -0,0 +1,3 @@ +; NoDebug +; 23 Dec 2001 16:17:11 +splat -s -o "d2(" "d1(" #?.c diff --git a/scalos/Modules/WindowProperties.MUI/WindowProperties.c b/scalos/Modules/WindowProperties.MUI/WindowProperties.c new file mode 100644 index 000000000..d90476b9a --- /dev/null +++ b/scalos/Modules/WindowProperties.MUI/WindowProperties.c @@ -0,0 +1,3382 @@ +// WindowProperties.c +// $Date$ +// $Revision$ + + +#ifdef __AROS__ +#define MUIMASTER_YES_INLINE_STDARG +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include // +jmc+ + +#include "WindowProperties.h" +#include +#include "BitMapMCC.h" +#include "Backfill.h" +#include +#include "debug.h" + +#define CATCOMP_NUMBERS +#define CATCOMP_ARRAY +#define CATCOMP_CODE +#define WindowProperties_NUMBERS +#define WindowProperties_ARRAY +#define WindowProperties_CODE +#include STR(SCALOSLOCALE) + +//---------------------------------------------------------------------------- + +#define VERSION_MAJOR 40 +#define VERSION_MINOR 9 + +//---------------------------------------------------------------------------- + +#define ID_MAIN MAKE_ID('M','A','I','N') +#define PS_DATA(prefsstruct) ((STRPTR) (prefsstruct)) + sizeof((prefsstruct)->ps_Size) + +#define MAX_FILENAME 512 + +// dimensions of empty thumbnail image +#define THUMBNAIL_WIDTH 50 +#define THUMBNAIL_HEIGHT 50 + +//---------------------------------------------------------------------------- + +long _stack = 16384; // minimum stack size, used by SAS/C startup code + +//---------------------------------------------------------------------------- + +// local data structures + +struct TempRastPort + { + struct RastPort trp_rp; + ULONG trp_Width; + }; + +struct ThumbnailLifetimeSliderInst + { + char buf[20]; + }; + +struct PatternEntryDef + { + struct Node ped_Node; + struct ScaExtPatternPrefs ped_PatternPrefs; + Object *ped_MUI_ImageObject; + Object *ped_MUI_AllocatedImageObject; + ULONG ped_ThumbnailImageNr; + struct ScalosBitMapAndColor *ped_SAC; + UBYTE *ped_BitMapArray; + }; + +struct PatternListEntry + { + UWORD ple_PatternNumber; + char ple_ImageNrBuffer[25]; + STRPTR ple_ImageDescBuffer; + ULONG ple_PatternCount; + struct List ple_PatternList; + }; + +#ifdef __AROS__ +#define ThumbnailLifetimeSliderObject BOOPSIOBJMACRO_START(ThumbnailLifetimeSliderClass->mcc_Class) +#else +#define ThumbnailLifetimeSliderObject NewObject(ThumbnailLifetimeSliderClass->mcc_Class, 0 +#endif + +#define KeyButtonHelp(name,key,HelpText)\ + TextObject,\ + ButtonFrame,\ + MUIA_Font, MUIV_Font_Button,\ + MUIA_Text_Contents, name,\ + MUIA_Text_PreParse, "\33c",\ + MUIA_Text_HiChar , key,\ + MUIA_ControlChar , key,\ + MUIA_InputMode , MUIV_InputMode_RelVerify,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShortHelp, HelpText,\ + MUIA_CycleChain, TRUE, \ + End + +#define CheckMarkHelp(selected, HelpTextID)\ + ImageObject,\ + ImageButtonFrame,\ + MUIA_InputMode , MUIV_InputMode_Toggle,\ + MUIA_Image_Spec , MUII_CheckMark,\ + MUIA_Image_FreeVert , TRUE,\ + MUIA_Selected , selected,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShowSelState , FALSE,\ + MUIA_CycleChain , TRUE,\ + MUIA_ShortHelp , GetLocString(HelpTextID), \ + End + +#define Application_Return_Ok 1001 + +#define THUMBNAIL_LIFETIME_NOTSET 366 +#define CHECKOVERLAP_NOTSET 2 + +//---------------------------------------------------------------------------- + +// local functions + +static void init(void); +static void fail(APTR APP_Main, CONST_STRPTR str); +static BOOL OpenLibraries(void); +static void CloseLibraries(void); +static SAVEDS(APTR) INTERRUPT OpenAboutMUIFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT OpenAboutFunc(struct Hook *hook, Object *o, Msg msg); +static STRPTR GetLocString(ULONG MsgId); +static void TranslateStringArray(STRPTR *stringArray); +static void SaveSettings(Object *IconObj, struct ScaWindowStruct *ws); +static Object *GetIconObject(CONST_STRPTR IconName, BPTR DirLock); +static Object *GetDeviceIconObject(CONST_STRPTR IconName, CONST_STRPTR VolumeName, CONST_STRPTR DeviceName); +static BOOL isDiskWritable(BPTR dLock); +static ULONG CheckInfoData(const struct InfoData *info); +static BOOL IsDevice(struct WBArg *arg); +static void GetDeviceName(BPTR dLock, STRPTR DeviceName, size_t MaxLen); +static BOOL ReadScalosPrefs(void); +static CONST_STRPTR GetPrefsConfigString(APTR prefsHandle, ULONG Id, CONST_STRPTR DefaultString); +static void StripTrailingChar(STRPTR String, char CharToRemove); +static struct ScaWindowStruct *FindWindowByLock(BPTR xLock); +static void BuildDefVolumeNameNoSpace(STRPTR Buffer, CONST_STRPTR VolumeName, size_t MaxLength); +static SAVEDS(APTR) INTERRUPT PatternListConstructHookFunc(struct Hook *hook, Object *obj, struct NList_ConstructMessage *msg); +static SAVEDS(void) INTERRUPT PatternListDestructHookFunc(struct Hook *hook, Object *obj, struct NList_DestructMessage *msg); +static SAVEDS(ULONG) INTERRUPT PatternListDisplayHookFunc(struct Hook *hook, Object *obj, struct NList_DisplayMessage *ndm); +static SAVEDS(LONG) INTERRUPT PatternListCompareHookFunc(struct Hook *hook, Object *obj, struct NList_CompareMessage *msg); +static SAVEDS(void) INTERRUPT PatternPopupWindowHookFunc(struct Hook *hook, Object *pop, Object *win); +static SAVEDS(void) INTERRUPT NewPatternHookFunc(struct Hook *hook, Object *pop, Object *win); +static SAVEDS(void) INTERRUPT TogglePathHookFunc(struct Hook *hook, Object *o, Object *x); +static Object *CreateEmptyThumbnailImage(void); +static LONG ReadPatternPrefsFile(CONST_STRPTR Filename, BOOL Quiet); +static LONG ReadPrefsBitMap(struct IFFHandle *iff, struct PatternEntryDef *ped, struct TempRastPort *trp); +static void CreateThumbnailImages(void); +static void CreateThumbnailImage(struct PatternEntryDef *ped); +DISPATCHER_PROTO(ThumbnailLifetimeSlider); +static void SelectPattern(ULONG PatternNumber); +static void AddDefaultPatternEntry(void); +static struct PatternEntryDef *CreatePatternEntryDef(void); +static void SetIconSizeConstraints(const struct Rectangle *SizeConstraints); +static void GetIconSizeConstraints(struct Rectangle *SizeConstraints); + +//---------------------------------------------------------------------------- + +// local data items + +static UBYTE prefDefIconsFirst = TRUE; // Flag: try Def-Diskicons first +static CONST_STRPTR prefDefIconPath = "ENV:sys"; +static UWORD prefsActiveWindowTransparency; +static UWORD prefsInactiveWindowTransparency; +static UWORD prefsIconScaleFactor; +static struct Rectangle prefIconSizeConstraints; + +struct IntuitionBase *IntuitionBase = NULL; +struct Library *IconBase = NULL; +T_LOCALEBASE LocaleBase = NULL; +struct Library *MUIMasterBase = NULL; +struct Library *IconobjectBase = NULL; +struct ScalosBase *ScalosBase = NULL; +struct Library *PreferencesBase = NULL; +struct GfxBase *GfxBase; +struct ScalosGfxBase *ScalosGfxBase = NULL; +struct Library *IFFParseBase; +struct Library *CyberGfxBase; +T_TIMERBASE TimerBase; + +#ifdef __amigaos4__ +struct IntuitionIFace *IIntuition = NULL; +struct IconIFace *IIcon = NULL; +struct LocaleIFace *ILocale = NULL; +struct MUIMasterIFace *IMUIMaster = NULL; +struct IconobjectIFace *IIconobject = NULL; +struct ScalosIFace *IScalos = NULL; +struct PreferencesIFace *IPreferences = NULL; +struct ScalosGfxIFace *IScalosGfx = NULL; +struct GraphicsIFace *IGraphics = NULL; +struct IFFParseIFace *IIFFParse = NULL; +struct CyberGfxIFace *ICyberGfx = NULL; +struct TimerIFace *ITimer = NULL; +#endif + +static struct Screen *WBScreen; + +static struct Catalog *WindowPropertiesCatalog; + +static struct Hook AboutHook = + { + { NULL, NULL }, + HOOKFUNC_DEF(OpenAboutFunc), + NULL + }; +static struct Hook AboutMUIHook = + { { NULL, NULL }, + HOOKFUNC_DEF(OpenAboutMUIFunc), + NULL + }; + +static struct Hook PatternListDisplayHook = + { + { NULL, NULL }, + HOOKFUNC_DEF(PatternListDisplayHookFunc), + NULL + }; +static struct Hook PatternListConstructHook = + { + { NULL, NULL }, + HOOKFUNC_DEF(PatternListConstructHookFunc), + NULL + }; +static struct Hook PatternListDestructHook = + { + { NULL, NULL }, + HOOKFUNC_DEF(PatternListDestructHookFunc), + NULL + }; +static struct Hook PatternListCompareHook = + { + { NULL, NULL }, + HOOKFUNC_DEF(PatternListCompareHookFunc), + NULL + }; +static struct Hook PatternPopupWindowHook = + { + { NULL, NULL }, + HOOKFUNC_DEF(PatternPopupWindowHookFunc), + NULL + }; +static struct Hook NewPatternHook = + { + { NULL, NULL }, + HOOKFUNC_DEF(NewPatternHookFunc), + NULL + }; +static struct Hook TogglePathHook = + { + { NULL, NULL }, + HOOKFUNC_DEF(TogglePathHookFunc), + NULL + }; + +static STRPTR cShowThumbnails[] = + { + (STRPTR) MSGID_SHOWTHUMBNAILS_NOTSET, + (STRPTR) MSGID_SHOWTHUMBNAILS_NEVER, + (STRPTR) MSGID_SHOWTHUMBNAILS_AS_DEFAULT, + (STRPTR) MSGID_SHOWTHUMBNAILS_ALWAYS, + NULL + }; + +static STRPTR cCheckOverlap[] = + { + (STRPTR) MSGID_CHECKOVERLAP_NO, + (STRPTR) MSGID_CHECKOVERLAP_YES, + (STRPTR) MSGID_CHECKOVERLAP_NOTSET, + NULL + }; + +static STRPTR cHideStatusBar[] = + { + (STRPTR) MSGID_HIDESTATUSBAR_NOTSET, + (STRPTR) MSGID_HIDESTATUSBAR_HIDE, + NULL + }; + +static STRPTR cHideControlBar[] = + { + (STRPTR) MSGID_HIDECONTROLBAR_NOTSET, + (STRPTR) MSGID_HIDECONTROLBAR_HIDE, + NULL + }; + +static STRPTR cRegisterTitleStrings[] = + { + (STRPTR) MSGID_REGISTERTITLE_WINDOW, + (STRPTR) MSGID_REGISTERTITLE_ICONS, + NULL + }; + +static STRPTR cIconSizesMin[] = +{ + (STRPTR) MSGID_ICONSIZES_UNLIMITED, + (STRPTR) MSGID_ICONSIZES_16x16, + (STRPTR) MSGID_ICONSIZES_24x24, + (STRPTR) MSGID_ICONSIZES_32x32, + (STRPTR) MSGID_ICONSIZES_48x48, + (STRPTR) MSGID_ICONSIZES_64x64, + (STRPTR) MSGID_ICONSIZES_96x96, + (STRPTR) MSGID_ICONSIZES_128x128, + NULL +}; + +static STRPTR cIconSizesMax[] = +{ + (STRPTR) MSGID_ICONSIZES_16x16, + (STRPTR) MSGID_ICONSIZES_24x24, + (STRPTR) MSGID_ICONSIZES_32x32, + (STRPTR) MSGID_ICONSIZES_48x48, + (STRPTR) MSGID_ICONSIZES_64x64, + (STRPTR) MSGID_ICONSIZES_96x96, + (STRPTR) MSGID_ICONSIZES_128x128, + (STRPTR) MSGID_ICONSIZES_UNLIMITED, + NULL +}; + +static Object *Group_Buttons2; +static Object *APP_Main; +static Object *WIN_Main; +static Object *WIN_AboutMUI; +static Object *WIN_Progress; +static Object *OkButton, *CancelButton; +static Object *CycleMarkNoStatusBar; +static Object *CycleMarkNoControlBar; +static Object *NumericButtonThumbnailsLifetime; +static Object *CycleThumbnails; +static Object *MenuAbout, *MenuAboutMUI, *MenuQuit, *Path, *IconImage; +static Object *Group_Virtual; //+jmc+ To switch 0/1 "MUIA_ShowMe" the ScroolGroupObject group. +static Object *CycleCheckOverlap; + +static Object *PopObjectPatternNumber; +static Object *NListviewPatterns; +static Object *NListPatterns; +static Object *EmptyThumbnailBitmap; +static Object *GaugeProgress; +static Object *TextMsgProgress1, *TextMsgProgress2; +static Object *BackfillPatternPreview; +static Object *TextPatternNumber; + +static Object *SliderTransparencyActiveWindow; +static Object *SliderTransparencyInactiveWindow; +static Object *CheckboxTransparencyActiveWindow; +static Object *CheckboxTransparencyInactiveWindow; +static Object *GroupTransparencyActiveWindow; +static Object *GroupTransparencyInactiveWindow; + +static Object *SliderNominalIconSize; +static Object *CycleIconMinSize; +static Object *CycleIconMaxSize; +static Object *CheckboxNominalIconSize; +static Object *CheckboxIconSizeConstraints; +static Object *GroupNominalIconSize; +static Object *GroupIconSizeConstraints; + +static struct MUI_CustomClass *IconobjectClass; +static struct MUI_CustomClass *ThumbnailLifetimeSliderClass; +struct MUI_CustomClass *BitMapPicClass; + +static ULONG NewPatternNumber = 0; +static ULONG PatternNumber = 0; +static ULONG ThumbnailMode = 0; +static ULONG ThumbnailLifetime = THUMBNAIL_LIFETIME_NOTSET; +static ULONG CheckOverlap = CHECKOVERLAP_NOTSET; +static ULONG ActiveWindowTransparency = 100; +static ULONG InactiveWindowTransparency = 100; +static BOOL ActiveWindowTransparencyDefault = TRUE; +static BOOL InactiveWindowTransparencyDefault = TRUE; +static ULONG IconScaleFactor = 100; +static BOOL IconScaleFactorDefault = TRUE; +static struct Rectangle IconSizeConstraints = { 0, 0, SHRT_MAX, SHRT_MAX }; +static BOOL IconSizeConstraintsDefault = TRUE; + +static ULONG BitMapsRead = 0; +static ULONG ThumbnailImageNumber = 0; + +static ULONG ThumbnailWidth = THUMBNAIL_WIDTH; +static ULONG ThumbnailHeight = THUMBNAIL_HEIGHT; + +static struct ScaPatternDefs pDefs; + +static T_TIMEREQUEST *TimerIORequest; +static char PathName[MAX_FILENAME]; +static struct ScaWindowStruct *ws = NULL; + +static struct PatternListEntry *AllPatterns[USHRT_MAX]; + +//---------------------------------------------------------------------------- + +int main(int argc, char *argv[]) +{ + LONG win_opened = 0; + BPTR oldDir = (BPTR)NULL; + CONST_STRPTR IconName = ""; + Object *iconObj = NULL; + BOOL IsWriteable = TRUE; + struct WBStartup *WBenchMsg = + (argc == 0) ? (struct WBStartup *)argv : NULL; + + init(); + + if (WBenchMsg && WBenchMsg->sm_ArgList) + { + struct WBArg *arg; + + if (WBenchMsg->sm_NumArgs > 1) + { + // Scalos typically calls this module with wa_Lock pointing to the + // window's directory, and empty wa_Name + + arg = &WBenchMsg->sm_ArgList[1]; + + IconName = arg->wa_Name; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: wa_Lock=%08lx wa_Name=<%s>\n", \ + __LINE__, arg->wa_Lock, arg->wa_Name)); + debugLock_d1(arg->wa_Lock); + + oldDir = CurrentDir(arg->wa_Lock); + + if (IsDevice(arg)) + { + static char VolumeName[256]; + char DeviceName[256]; + + NameFromLock(arg->wa_Lock, VolumeName, sizeof(VolumeName)); + GetDeviceName(arg->wa_Lock, DeviceName, sizeof(DeviceName)); + + StripTrailingChar(VolumeName, ':'); + StripTrailingChar(DeviceName, ':'); + + iconObj = GetDeviceIconObject(IconName, VolumeName, DeviceName); + + if (iconObj) + SetAttrs(iconObj, DTA_Name, "disk", TAG_END); + + IconName = VolumeName; + stccpy(PathName, VolumeName, sizeof(PathName)); + } + else + { + if (NULL == IconName || strlen(IconName) < 1) + { + static char DirName[1024]; + + NameFromLock(arg->wa_Lock, DirName, sizeof(DirName)); + IconName = FilePart(DirName); + + iconObj = GetIconObject(DirName, arg->wa_Lock); + } + else + { + iconObj = GetIconObject(IconName, arg->wa_Lock); + } + NameFromLock(ParentDir(arg->wa_Lock), PathName, sizeof(PathName)); + } + + IsWriteable = isDiskWritable(arg->wa_Lock); + + ws = FindWindowByLock(arg->wa_Lock); + d1(kprintf("%s/%s/%ld: ws=%08lx\n", __FILE__, __FUNC__, __LINE__, ws)); + } + } + + d1(kprintf(__FUNC__ "/%ld: IconName=<%s>\n", __LINE__, IconName)); + + if (strlen(IconName) > 0) + { + ULONG NoStatusBar = FALSE; + ULONG NoControlBar = FALSE; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: IconObj=%08lx\n", __LINE__, iconObj)); + if (iconObj) + { + STRPTR tt; + + tt = NULL; + if (DoMethod(iconObj, IDTM_FindToolType, "SCALOS_THUMBNAIL_LIFETIME", &tt)) + { + DoMethod(iconObj, IDTM_GetToolTypeValue, tt, (ULONG *) &ThumbnailLifetime); + } + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: tt=%08lx\n", __LINE__, tt)); + + tt = NULL; + if (DoMethod(iconObj, IDTM_FindToolType, "SCALOS_PATTERNNO", &tt)) + { + DoMethod(iconObj, IDTM_GetToolTypeValue, tt, (ULONG *) &PatternNumber); + NewPatternNumber = PatternNumber; + } + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: tt=%08lx\n", __LINE__, tt)); + + tt = NULL; + if (DoMethod(iconObj, IDTM_FindToolType, "SCALOS_NOSTATUSBAR", &tt)) + NoStatusBar = TRUE; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: tt=%08lx\n", __LINE__, tt)); + + tt = NULL; + if (DoMethod(iconObj, IDTM_FindToolType, "SCALOS_NOCONTROLBAR", &tt)) + NoControlBar = TRUE; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: tt=%08lx\n", __LINE__, tt)); + + tt = NULL; + if (DoMethod(iconObj, IDTM_FindToolType, "SCALOS_THUMBNAILS", &tt)) + { + while (*tt && '=' != *tt) + tt++; + + if ('=' == *tt) + { + ++tt; // Skip "=" + if (0 == Stricmp(tt, "NEVER")) + ThumbnailMode = 1; + else if (0 == Stricmp(tt, "ASDEFAULT")) + ThumbnailMode = 2; + else if (0 == Stricmp(tt, "ALWAYS")) + ThumbnailMode = 3; + } + } + + tt = NULL; + if (DoMethod(iconObj, IDTM_FindToolType, "SCALOS_CHECKOVERLAP", &tt)) + { + DoMethod(iconObj, IDTM_GetToolTypeValue, tt, (ULONG *) &CheckOverlap); + CheckOverlap = CheckOverlap != 0; // allow only 0 or 1 + } + + tt = NULL; + if (DoMethod(iconObj, IDTM_FindToolType, "SCALOS_ACTIVETRANSPARENCY", &tt)) + { + DoMethod(iconObj, IDTM_GetToolTypeValue, tt, (ULONG *) &ActiveWindowTransparency); + ActiveWindowTransparencyDefault = FALSE; + } + + tt = NULL; + if (DoMethod(iconObj, IDTM_FindToolType, "SCALOS_INACTIVETRANSPARENCY", &tt)) + { + DoMethod(iconObj, IDTM_GetToolTypeValue, tt, (ULONG *) &InactiveWindowTransparency); + InactiveWindowTransparencyDefault = FALSE; + } + + tt = NULL; + if (DoMethod(iconObj, IDTM_FindToolType, "SCALOS_ICONSCALEFACTOR", &tt)) + { + IconScaleFactorDefault = FALSE; + + DoMethod(iconObj, IDTM_GetToolTypeValue, tt, (ULONG *) &IconScaleFactor); + + if (IconScaleFactor < IDTA_ScalePercentage_MIN) + IconScaleFactor = IDTA_ScalePercentage_MIN; + else if (IconScaleFactor > IDTA_ScalePercentage_MAX) + IconScaleFactor = IDTA_ScalePercentage_MAX; + + d1(KPrintF("%s/%s/%ld: iwp_IconScaleFactor=%lu\n", __FILE__, __FUNC__, __LINE__, iwp->iwp_IconScaleFactor)); + } + + tt = NULL; + if (DoMethod(iconObj, IDTM_FindToolType, "SCALOS_ICONSIZECONSTRAINTS", &tt)) + { + long long1, long2; + LONG IconSizeMin = 0, IconSizeMax = SHRT_MAX; + + IconSizeConstraintsDefault = FALSE; + + d1(KPrintF("%s/%s/%ld: tt=<%s>\n", __FILE__, __FUNC__, __LINE__, tt)); + while (*tt && '=' != *tt) + tt++; + + if (2 == sscanf(tt, "=%ld,%ld", &long1, &long2)) + { + IconSizeMin = long1; + IconSizeMax = long2; + + if ((IconSizeMax > 128) || (IconSizeMax < 0)) + IconSizeMax = SHRT_MAX; + if ((IconSizeMin < 0) || (IconSizeMin >= IconSizeMax)) + IconSizeMin = 0; + + IconSizeConstraints.MinX = IconSizeConstraints.MinY = IconSizeMin; + IconSizeConstraints.MaxX = IconSizeConstraints.MaxY = IconSizeMax; + } + d1(KPrintF("%s/%s/%ld: IconSizeMin=%ld IconSizeMax=%ld\n", __FILE__, __FUNC__, __LINE__, IconSizeMin, IconSizeMax)); + } + } + + TranslateStringArray(cShowThumbnails); + TranslateStringArray(cCheckOverlap); + TranslateStringArray(cHideStatusBar); + TranslateStringArray(cHideControlBar); + TranslateStringArray(cIconSizesMin); + TranslateStringArray(cIconSizesMax); + TranslateStringArray(cRegisterTitleStrings); + + APP_Main = ApplicationObject, + MUIA_Application_Title, GetLocString(MSGID_TITLENAME), + MUIA_Application_Version, "$VER: Scalos WindowProperties.module V" + STR(VERSION_MAJOR) "." STR(VERSION_MINOR) + " (" __DATE__ ") " COMPILER_STRING, + MUIA_Application_Copyright, "The Scalos Team, 2004" CURRENTYEAR, + MUIA_Application_Author, "The Scalos Team", + MUIA_Application_Description, "Scalos Window Properties module", + MUIA_Application_Base, "SCALOS_WINDOW_PROP", + + SubWindow, WIN_Main = WindowObject, + MUIA_Window_Title, GetLocString(MSGID_TITLENAME), +// MUIA_Window_ID, MAKE_ID('M','A','I','N'), + MUIA_Window_AppWindow, TRUE, + + MUIA_Window_TopEdge, MUIV_Window_TopEdge_Moused, + MUIA_Window_LeftEdge, MUIV_Window_LeftEdge_Moused, + + MUIA_Window_Width, MUIV_Window_Width_MinMax(0), + MUIA_Window_Height, MUIV_Window_Height_MinMax(0), + + WindowContents, VGroup, + Child, VGroup, + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, TextObject, + MUIA_Text_PreParse, MUIX_C MUIX_B, + MUIA_Text_Contents, IconName, + TextFrame, + MUIA_Background, MUII_TextBack, + MUIA_ShortHelp, GetLocString(MSGID_TEXT_WINDOWNAME_SHORTHELP), + End, //TextObject + + Child, TextObject, + MUIA_ShowMe, !IsWriteable, + MUIA_Text_PreParse, MUIX_C, + MUIA_Text_Contents, GetLocString(MSGID_READ_ONLY), + End, //TextObject + + + Child, HGroup, + + Child, RectangleObject, End, //--- Instead: Child, VSpace(0) + + Child, IconImage = IconobjectMCCObject, + MUIA_Iconobj_Object, iconObj, + MUIA_InputMode, MUIV_InputMode_Toggle, //MUIV_InputMode_RelVerify, + MUIA_ShowSelState, FALSE, + MUIA_CycleChain, TRUE, + End, //IconobjectMCCObject + + Child, RegisterObject, + MUIA_Register_Titles, cRegisterTitleStrings, + MUIA_CycleChain, TRUE, + + Child, VGroup, + Child, HGroup, + Child, Label1(GetLocString(MSGID_POPUP_PATTERNNUMBER)), + Child, HGroup, + MUIA_Disabled, !IsWriteable, + + Child, TextPatternNumber = TextObject, + MUIA_Text_PreParse, MUIX_C, + MUIA_Text_Contents, GetLocString(MSGID_PATTERNR_DEFAULT), + End, //TextObject + + Child, BackfillPatternPreview = BackfillObject, + ImageButtonFrame, + MUIA_Background, MUII_ButtonBack, + ImageButtonFrame, + MUIA_InputMode, MUIV_InputMode_RelVerify, + MUIA_CycleChain, TRUE, + BFA_BitmapObject, EmptyThumbnailBitmap, + End, //BackfillClass + + Child, PopObjectPatternNumber = PopobjectObject, + MUIA_CycleChain, TRUE, + MUIA_Popobject_WindowHook, &PatternPopupWindowHook, + MUIA_Popstring_Button, PopButton(MUII_PopUp), + MUIA_Popobject_Object, NListviewPatterns = NListviewObject, + MUIA_Listview_DragType, MUIV_Listview_DragType_None, + MUIA_Listview_Input, TRUE, + MUIA_CycleChain, TRUE, + MUIA_Listview_List, NListPatterns = NListObject, + InputListFrame, + MUIA_Background, MUII_ListBack, + MUIA_NList_Format, "P=\33r BAR, BAR", + MUIA_NList_TitleSeparator, FALSE, + MUIA_NList_Title, FALSE, + MUIA_NList_DisplayHook2, &PatternListDisplayHook, + MUIA_NList_ConstructHook2, &PatternListConstructHook, + MUIA_NList_DestructHook2, &PatternListDestructHook, + MUIA_NList_CompareHook2, &PatternListCompareHook, + MUIA_NList_PoolPuddleSize, sizeof(struct PatternListEntry) * 64, + MUIA_NList_PoolThreshSize, sizeof(struct PatternListEntry), + MUIA_NList_AutoVisible, TRUE, + MUIA_NList_SortType, 0, + MUIA_NList_TitleMark, MUIV_NList_TitleMark_Down | 0, + MUIA_NList_EntryValueDependent, TRUE, + MUIA_NList_MultiSelect, MUIV_NList_MultiSelect_None, + End, //NListObject + MUIA_NListview_Horiz_ScrollBar, MUIV_NListview_HSB_FullAuto, + End, //NListviewObject + End, //PopobjectObject + End, //HGroup + End, //HGroup + + Child, HVSpace, + + Child, ColGroup(2), + Child, Label1(GetLocString(MSGID_CYCLE_NOSTATUSBAR)), + Child, CycleMarkNoStatusBar = CycleObject, + MUIA_CycleChain, TRUE, + MUIA_Cycle_Active, NoStatusBar, + MUIA_Cycle_Entries, cHideStatusBar, + MUIA_Disabled, !IsWriteable, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_CYCLE_NOSTATUSBAR_SHORTHELP), + End, //CycleObject + + Child, Label1(GetLocString(MSGID_CYCLE_NOCONTROLBAR)), + Child, CycleMarkNoControlBar = CycleObject, + MUIA_CycleChain, TRUE, + MUIA_Cycle_Active, NoControlBar, + MUIA_Cycle_Entries, cHideControlBar, + MUIA_Disabled, !IsWriteable, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_CYCLE_NOCONTROLBAR_SHORTHELP), + End, //CycleObject + + End, //ColGroup + + Child, HVSpace, + + Child, VGroup, +#if defined(__MORPHOS__) + MUIA_ShowMe, IntuitionBase->LibNode.lib_Version >= 51, +#elif !defined(__amigaos4__) + MUIA_ShowMe, FALSE, +#endif //!defined(__MORPHOS__) && !defined(__amigaos4__) + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_TRANSPARENCY_ACTIVEWINDOW), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_TRANSPARENCY_ACTIVEWINDOW_SHORTHELP), + + Child, HGroup, + Child, Label1((ULONG) GetLocString(MSGID_CHECKBOX_TRANSPARENCY_USEDEFAULT)), + Child, CheckboxTransparencyActiveWindow = CheckMarkHelp(ActiveWindowTransparencyDefault, MSGID_CHECKBOX_TRANSPARENCY_USEDEFAULT_SHORTHELP), + Child, HVSpace, + End, //HGroup + + Child, GroupTransparencyActiveWindow = ColGroup(3), + MUIA_Disabled, ActiveWindowTransparencyDefault, + Child, Label1((ULONG) GetLocString(MSGID_TRANSPARENCY_TRANSPARENT)), + + Child, SliderTransparencyActiveWindow = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 100, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, ActiveWindowTransparency, + End, //Slider + + Child, Label1((ULONG) GetLocString(MSGID_TRANSPARENCY_OPAQUE)), + + End, //ColGroup + + End, //VGroup + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_TRANSPARENCY_INACTIVEWINDOW), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_TRANSPARENCY_INACTIVEWINDOW_SHORTHELP), + + Child, HGroup, + Child, Label1((ULONG) GetLocString(MSGID_CHECKBOX_TRANSPARENCY_USEDEFAULT)), + Child, CheckboxTransparencyInactiveWindow = CheckMarkHelp(InactiveWindowTransparencyDefault, MSGID_CHECKBOX_TRANSPARENCY_USEDEFAULT_SHORTHELP), + Child, HVSpace, + End, //HGroup + + Child, GroupTransparencyInactiveWindow = ColGroup(3), + MUIA_Disabled, InactiveWindowTransparencyDefault, + Child, Label1((ULONG) GetLocString(MSGID_TRANSPARENCY_TRANSPARENT)), + + Child, SliderTransparencyInactiveWindow = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 100, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, InactiveWindowTransparency, + End, //Slider + + Child, Label1((ULONG) GetLocString(MSGID_TRANSPARENCY_OPAQUE)), + + End, //ColGroup + + End, //VGroup + + End, //VGroup + + Child, HVSpace, + End, //VGroup + + Child, VGroup, + Child, ColGroup(2), + Child, Label1(GetLocString(MSGID_CYCLE_CHECKOVERLAP)), + Child, CycleCheckOverlap = CycleObject, + MUIA_CycleChain, TRUE, + MUIA_Disabled, !IsWriteable, + MUIA_Cycle_Entries, cCheckOverlap, + MUIA_Cycle_Active, CheckOverlap, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_CYCLE_CHECKOVERLAP_SHORTHELP), + End, //CycleObject + + Child, Label1(GetLocString(MSGID_CYCLE_THUMBNAILS)), + Child, CycleThumbnails = CycleObject, + MUIA_CycleChain, TRUE, + MUIA_Disabled, !IsWriteable, + MUIA_Cycle_Entries, cShowThumbnails, + MUIA_Cycle_Active, ThumbnailMode, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_CYCLE_THUMBNAILS_SHORTHELP), + End, //CycleObject + + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_THUMBNAILS_MAXAGE)), + Child, NumericButtonThumbnailsLifetime = ThumbnailLifetimeSliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 366, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, ThumbnailLifetime, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_THUMBNAILS_MAXAGE_SHORTHELP), + End, //ThumbnailLifetimeSliderClass + End, //ColGroup + + Child, HVSpace, + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_GROUP_ICONSCALING), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HGroup, + Child, Label1((ULONG) GetLocString(MSGID_CHECKBOX_ICONSCALING_NOMINALSIZE)), + Child, CheckboxNominalIconSize = CheckMarkHelp(IconScaleFactorDefault, MSGID_CHECKBOX_ICONSCALING_NOMINALSIZE_SHORTHELP), + Child, HVSpace, + End, //HGroup + + Child, GroupNominalIconSize = HGroup, + MUIA_Disabled, IconScaleFactorDefault, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSCALING_NOMINALSIZE_SHORTHELP), + + Child, Label1((ULONG) GetLocString(MSGID_ICONSCALING_NOMINALSIZE)), + + Child, SliderNominalIconSize = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, IDTA_ScalePercentage_MIN, + MUIA_Numeric_Max, IDTA_ScalePercentage_MAX, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, IconScaleFactor, + End, //Slider + + Child, Label1((ULONG) GetLocString(MSGID_ICONSCALING_PERCENT)), + End, //HGroup + + Child, HVSpace, + + Child, HGroup, + Child, Label1((ULONG) GetLocString(MSGID_CHECKBOX_ICONSIZECONSTRAINTS_USEDEFAULT)), + Child, CheckboxIconSizeConstraints = CheckMarkHelp(IconSizeConstraintsDefault, MSGID_CHECKBOX_ICONSIZECONSTRAINTS_USEDEFAULT_SHORTHELP), + Child, HVSpace, + End, //HGroup + + Child, GroupIconSizeConstraints = HGroup, + MUIA_Disabled, IconSizeConstraintsDefault, + + Child, HVSpace, + + Child, Label1((ULONG) GetLocString(MSGID_ICONSCALING_MINSIZE)), + Child, CycleIconMinSize = CycleObject, + MUIA_CycleChain, TRUE, + MUIA_Cycle_Entries, cIconSizesMin, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSCALING_MINSIZE_SHORTHELP), + End, //Cycle + + Child, HVSpace, + + Child, Label1((ULONG) GetLocString(MSGID_ICONSCALING_MAXSIZE)), + Child, CycleIconMaxSize = CycleObject, + MUIA_CycleChain, TRUE, + MUIA_Cycle_Entries, cIconSizesMax, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSCALING_MAXSIZE_SHORTHELP), + End, //Cycle + + Child, HVSpace, + End, //HGroup + + End, //VGroup + End, //VGroup + + Child, HVSpace, + End, //VGroup + + End, //RegisterObject + + Child, Group_Virtual = ScrollgroupObject, // +jmc+ + MUIA_Scrollgroup_VertBar, NULL, + MUIA_Scrollgroup_HorizBar, NULL, + MUIA_Scrollgroup_FreeHoriz, TRUE, + MUIA_Scrollgroup_FreeVert, FALSE, + MUIA_Scrollgroup_Contents, + VirtgroupObject, + Child, Path = TextObject, TextFrame, + MUIA_Background, MUII_TextBack, + MUIA_Text_PreParse, MUIX_C, + MUIA_Text_Contents, PathName, + MUIA_ShortHelp, GetLocString(MSGID_TEXT_PARENTDIR_SHORTHELP), + End, //TextObject + End, //VirtgroupObject + End, //ScrollgroupObject + + Child, HVSpace, + + End, //VGroup, + + Child, Group_Buttons2 = HGroup, + MUIA_Group_SameWidth, TRUE, + Child, OkButton = KeyButtonHelp(GetLocString(MSGID_OKBUTTON), + 'o', GetLocString(MSGID_SHORTHELP_OKBUTTON)), + Child, CancelButton = KeyButtonHelp(GetLocString(MSGID_CANCELBUTTON), + 'c', GetLocString(MSGID_SHORTHELP_CANCELBUTTON)), + End, //HGroup + End, //VGroup + End, //WindowObject + + SubWindow, WIN_Progress = WindowObject, + // MUIA_Window_Borderless, TRUE, + MUIA_Window_Activate, FALSE, + MUIA_Window_NoMenus, TRUE, + MUIA_Window_Title, GetLocString(MSGID_WINDOW_STARTUP), + WindowContents, VGroup, + Child, GaugeProgress = GaugeObject, + MUIA_Gauge_Horiz, TRUE, + GaugeFrame, + MUIA_Gauge_InfoText, " ", + End, //GaugeObject + Child, TextMsgProgress1 = TextObject, + MUIA_Text_PreParse, MUIX_C, + MUIA_Text_Contents, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + End, //TextObject + Child, TextMsgProgress2 = TextObject, + MUIA_Text_PreParse, MUIX_C, + MUIA_Text_Contents, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + End, //TextObject + End, //VGroup + End, //WindowObject + + MUIA_Application_Menustrip, MenustripObject, + Child, MenuObjectT(GetLocString(MSGID_MENU_PROJECT)), + + Child, MenuAbout = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUT), + End, + Child, MenuAboutMUI = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUTMUI), + End, + Child, MenuitemObject, + MUIA_Menuitem_Title, -1, + End, + Child, MenuQuit = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_QUIT), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_PROJECT_QUIT_SHORT), + End, + + End, //MenuObjectT + End, //MenuStripObject + End; //ApplicationObject + + if (NULL == APP_Main) + { + fail(APP_Main, "Failed to create Application."); + } + + if (ActiveWindowTransparencyDefault) + setslider(SliderTransparencyActiveWindow, prefsActiveWindowTransparency); + if (InactiveWindowTransparencyDefault) + setslider(SliderTransparencyInactiveWindow, prefsInactiveWindowTransparency); + if (IconScaleFactorDefault) + setslider(SliderNominalIconSize, prefsIconScaleFactor); + if (IconSizeConstraintsDefault) + SetIconSizeConstraints(&prefIconSizeConstraints); + else + SetIconSizeConstraints(&IconSizeConstraints); + + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + WIN_Main, 3, MUIM_Set, MUIA_Window_Open, FALSE); + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + DoMethod(CancelButton, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + DoMethod(OkButton, MUIM_Notify,MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_Application_ReturnID, Application_Return_Ok); + + DoMethod(MenuAbout, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &AboutHook); + DoMethod(MenuAboutMUI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &AboutMUIHook); + DoMethod(MenuQuit, MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + DoMethod(IconImage, MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &TogglePathHook); + + DoMethod(NListviewPatterns, MUIM_Notify, MUIA_Listview_DoubleClick, TRUE, + APP_Main, 2, MUIM_CallHook, &NewPatternHook); + + // Clicking on the preview image causes the popup to open + DoMethod(BackfillPatternPreview, MUIM_Notify, MUIA_Pressed, FALSE, + PopObjectPatternNumber, 1, MUIM_Popstring_Open); + + set(WIN_Main, MUIA_Window_ActiveObject, OkButton); + + // GroupTransparencyActiveWindow is disabled whenever CheckboxTransparencyActiveWindow is checked + DoMethod(CheckboxTransparencyActiveWindow, MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + GroupTransparencyActiveWindow, 3, MUIM_Set, MUIA_Disabled, MUIV_TriggerValue); + + // Set SliderTransparencyActiveWindow to prefs value when "use default" is checked + DoMethod(CheckboxTransparencyActiveWindow, MUIM_Notify, MUIA_Selected, TRUE, + SliderTransparencyActiveWindow, 3, MUIM_Set, MUIA_Numeric_Value, prefsActiveWindowTransparency); + + // GroupTransparencyInactiveWindow is disabled whenever CheckboxTransparencyInactiveWindow is checked + DoMethod(CheckboxTransparencyInactiveWindow, MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + GroupTransparencyInactiveWindow, 3, MUIM_Set, MUIA_Disabled, MUIV_TriggerValue); + + // Set SliderTransparencyInactiveWindow to prefs value when "use default" is checked + DoMethod(CheckboxTransparencyInactiveWindow, MUIM_Notify, MUIA_Selected, TRUE, + SliderTransparencyInactiveWindow, 3, MUIM_Set, MUIA_Numeric_Value, prefsInactiveWindowTransparency); + + // GroupIconSizeConstraints is disabled whenever CheckboxIconSizeConstraints is checked + DoMethod(CheckboxIconSizeConstraints, MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + GroupIconSizeConstraints, 3, MUIM_Set, MUIA_Disabled, MUIV_TriggerValue); + + // GroupNominalIconSize is disabled whenever CheckboxNominalIconSize is checked + DoMethod(CheckboxNominalIconSize, MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + GroupNominalIconSize, 3, MUIM_Set, MUIA_Disabled, MUIV_TriggerValue); + + // Set SliderNominalIconSize to prefs value when "use default" is checked + DoMethod(CheckboxNominalIconSize, MUIM_Notify, MUIA_Selected, TRUE, + SliderNominalIconSize, 3, MUIM_Set, MUIA_Numeric_Value, prefsIconScaleFactor); + + // disable Ok button for read-only icons + set(OkButton, MUIA_Disabled, !IsWriteable); + set(Group_Virtual, MUIA_ShowMe, 0); + + set(WIN_Main, MUIA_Window_Open, TRUE); + get(WIN_Main, MUIA_Window_Open, &win_opened); + get(WIN_Main, MUIA_Window_Screen, &WBScreen); + + if (win_opened) + { + ULONG sigs = 0; + BOOL Run = TRUE; + + ReadPatternPrefsFile("ENV:Scalos/Pattern.prefs", TRUE); + SelectPattern(PatternNumber); + + while (Run) + { + ULONG Action = DoMethod(APP_Main, MUIM_Application_NewInput, &sigs); + + switch (Action) + { + case Application_Return_Ok: + SaveSettings(iconObj, ws); + Run = FALSE; + break; + case MUIV_Application_ReturnID_Quit: + Run = FALSE; + break; + } + + if (Run && sigs) + { + sigs = Wait(sigs | SIGBREAKF_CTRL_C); + + if (sigs & SIGBREAKF_CTRL_C) + { + Run = FALSE; + } + } + } + } + else + { + printf("failed to open main window !\n"); + } + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + set(WIN_Main, MUIA_Window_Open, FALSE); + } + + d1(KPrintF("%s/%s/%ld: ws=%08lx\n", __FILE__, __FUNC__, __LINE__, ws)); + if (ws) + SCA_UnLockWindowList(); + d1(KPrintF("%s/%s/%ld: iconObj=%08lx\n", __FILE__, __FUNC__, __LINE__, iconObj)); + if (iconObj) + DisposeIconObject(iconObj); + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + if (oldDir) + CurrentDir(oldDir); + + fail(APP_Main, NULL); + + return 0; +} + +//---------------------------------------------------------------------------- + +DISPATCHER(ThumbnailLifetimeSlider) +{ + ULONG Result; + + switch (msg->MethodID) + { + case MUIM_Numeric_Stringify: + { + struct ThumbnailLifetimeSliderInst *inst = INST_DATA(cl,obj); + struct MUIP_Numeric_Stringify *mstr = (struct MUIP_Numeric_Stringify *) msg; + + if (0 == mstr->value) + snprintf(inst->buf, sizeof(inst->buf), MUIX_C "%s", GetLocString(MSGID_THUMBNAILS_LIFETIME_FOREVER)); + else if (mstr->value > 365) + snprintf(inst->buf, sizeof(inst->buf), MUIX_C "%s", GetLocString(MSGID_THUMBNAILS_LIFETIME_NOTSET)); + else + { + snprintf(inst->buf, sizeof(inst->buf), MUIX_C "%lu %s", + (unsigned long)mstr->value, + GetLocString(MSGID_ICONSPAGE_THUMBNAILS_MAXAGE_DAYS)); + } + d1(KPrintF("%s/%s/%ld: inst=%08lx buf=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, inst, inst->buf, inst->buf)); + Result = (ULONG) inst->buf; + } + break; + + default: + Result = DoSuperMethodA(cl, obj, msg); + break; + } + + return Result; +} +DISPATCHER_END + +//---------------------------------------------------------------------------- + +static VOID fail(APTR APP_Main, CONST_STRPTR str) +{ + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + if (APP_Main) + { + MUI_DisposeObject(APP_Main); + } + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + if (EmptyThumbnailBitmap) + { + MUI_DisposeObject(EmptyThumbnailBitmap); + EmptyThumbnailBitmap = NULL; + } + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + if (ThumbnailLifetimeSliderClass) + { + MUI_DeleteCustomClass(ThumbnailLifetimeSliderClass); + ThumbnailLifetimeSliderClass = NULL; + } + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + if (IconobjectClass) + { + CleanupIconobjectClass(IconobjectClass); + IconobjectClass = NULL; + } + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + if (BitMapPicClass) + { + CleanupBitMappicClass(BitMapPicClass); + BitMapPicClass = NULL; + } + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + CleanupBackfillClass(); + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + if (WindowPropertiesCatalog) + { + CloseCatalog(WindowPropertiesCatalog); + WindowPropertiesCatalog = NULL; + } + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + CloseLibraries(); + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + if (str) + { + puts(str); + exit(20); + } + + exit(0); +} + +//---------------------------------------------------------------------------- + +static void init(void) +{ + if (!OpenLibraries()) + fail(NULL, "Failed to call OpenLibraries."); + + if (LocaleBase) + WindowPropertiesCatalog = OpenCatalogA(NULL, "Scalos/WindowProperties.catalog", NULL); + + IconobjectClass = InitIconobjectClass(); + if (NULL == IconobjectClass) + fail(NULL, "Failed to create IconobjectClass."); + + ThumbnailLifetimeSliderClass = MUI_CreateCustomClass(NULL, MUIC_Numericbutton, NULL, + sizeof(struct ThumbnailLifetimeSliderInst), DISPATCHER_REF(ThumbnailLifetimeSlider)); + if (NULL == ThumbnailLifetimeSliderClass) + fail(NULL, "Unable to create ThumbnailLifetimeSliderClass."); + + if (NULL == BitMapPicClass) + { + BitMapPicClass = InitBitMappicClass(); + } + if (NULL == BitMapPicClass) + fail(NULL, "Unable to create BitMapPicClass."); + + if (NULL == BackfillClass) + { + BackfillClass = InitBackfillClass(); + } + if (NULL == BackfillClass) + fail(NULL, "Unable to create BackfillClass."); + + EmptyThumbnailBitmap = CreateEmptyThumbnailImage(); + if (NULL == EmptyThumbnailBitmap) + fail(NULL, "Unable to create empty thumbnail image."); + + ReadScalosPrefs(); +} + + +static BOOL OpenLibraries(void) +{ + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + if (NULL == IntuitionBase) + fail(NULL, "Failed to open intuition.library."); +#ifdef __amigaos4__ + else + { + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + fail(NULL, "Failed to open intuition interface."); + } +#endif /* __amigaos4__ */ + + MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN-1); + if (NULL == MUIMasterBase) + fail(NULL, "Failed to open muimaster.library."); +#ifdef __amigaos4__ + else + { + IMUIMaster = (struct MUIMasterIFace *)GetInterface((struct Library *)MUIMasterBase, "main", 1, NULL); + if (NULL == IMUIMaster) + fail(NULL, "Failed to open muimaster interface."); + } +#endif /* __amigaos4__ */ + + IconBase = OpenLibrary("icon.library", 0); + if (NULL == IconBase) + fail(NULL, "Failed to open icon.library."); +#ifdef __amigaos4__ + else + { + IIcon = (struct IconIFace *)GetInterface((struct Library *)IconBase, "main", 1, NULL); + if (NULL == IIcon) + fail(NULL, "Failed to open icon interface."); + } +#endif /* __amigaos4__ */ + + ScalosBase = (struct ScalosBase *) OpenLibrary("scalos.library", 40); + if (NULL == ScalosBase) + fail(NULL, "Failed to open scalos.library."); +#ifdef __amigaos4__ + else + { + IScalos = (struct ScalosIFace *)GetInterface((struct Library *)ScalosBase, "main", 1, NULL); + if (NULL == IScalos) + fail(NULL, "Failed to open scalos interface."); + } +#endif /* __amigaos4__ */ + + IFFParseBase = OpenLibrary("iffparse.library", 36); + if (NULL == IFFParseBase) + fail(NULL, "Failed to open iffparse.library."); +#ifdef __amigaos4__ + IIFFParse = (struct IFFParseIFace *) GetInterface((struct Library *) IFFParseBase, "main", 1, NULL); + if (NULL == IIFFParse) + fail(NULL, "Failed to open iffparse interface."); +#endif /* __amigaos4__ */ + + PreferencesBase = OpenLibrary("preferences.library", 39); + if (NULL == PreferencesBase) + fail(NULL, "Failed to open preferences."); +#ifdef __amigaos4__ + else + { + IPreferences = (struct PreferencesIFace *)GetInterface((struct Library *)PreferencesBase, "main", 1, NULL); + if (NULL == IPreferences) + fail(NULL, "Failed to open preferences interface."); + } +#endif /* __amigaos4__ */ + + IconobjectBase = OpenLibrary("iconobject.library", 0); + if (NULL == IconobjectBase) + fail(NULL, "Failed to open iconobject.library."); +#ifdef __amigaos4__ + else + { + IIconobject = (struct IconobjectIFace *)GetInterface((struct Library *)IconobjectBase, "main", 1, NULL); + if (NULL == IIconobject) + fail(NULL, "Failed to open iconobject interface."); + } +#endif /* __amigaos4__ */ + + GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 39); + if (NULL == GfxBase) + fail(NULL, "Failed to open graphics.library."); +#ifdef __amigaos4__ + IGraphics = (struct GraphicsIFace *) GetInterface((struct Library *) GfxBase, "main", 1, NULL); + if (NULL == IGraphics) + fail(NULL, "Failed to open graphics interface."); +#endif /* __amigaos4__ */ + + ScalosGfxBase = (struct ScalosGfxBase *) OpenLibrary(SCALOSGFXNAME, 41); + if (NULL == ScalosGfxBase) + fail(NULL, "Failed to open scalosgfx.library."); +#ifdef __amigaos4__ + IScalosGfx = (struct ScalosGfxIFace *) GetInterface((struct Library *) ScalosGfxBase, "main", 1, NULL); + if (NULL == IScalosGfx) + fail(NULL, "Failed to open scalosgfx interface."); +#endif /* __amigaos4__ */ + + TimerIORequest = (T_TIMEREQUEST *) CreateIORequest(CreateMsgPort(), sizeof(T_TIMEREQUEST)); + if (NULL == TimerIORequest) + fail(NULL, "Failed to call CreateIORequest."); + if (0 != OpenDevice("timer.device", UNIT_VBLANK, &TimerIORequest->tr_node, 0)) + { + // OpenDevice failed + DeleteIORequest((struct IORequest *)TimerIORequest); + TimerIORequest = NULL; + fail(NULL, "Failed to open timer.device."); + } + TimerBase = (T_TIMERBASE) TimerIORequest->tr_node.io_Device; + if (NULL == TimerBase) + fail(NULL, "Failed to get TimerBase."); +#ifdef __amigaos4__ + ITimer = (struct TimerIFace *)GetInterface((struct Library *)TimerBase, "main", 1, NULL); + if (NULL == ITimer) + fail(NULL, "Failed to open timer interface."); +#endif /* __amigaos4__ */ + + CyberGfxBase = (APTR) OpenLibrary( "cybergraphics.library", 40); +#ifdef __amigaos4__ + if (CyberGfxBase) + ICyberGfx = (struct CyberGfxIFace *) GetInterface((struct Library *) CyberGfxBase, "main", 1, NULL); +#endif + // CyberGfxBase may be NULL + + LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 39); +#ifdef __amigaos4__ + if (NULL != LocaleBase) + { + ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL); + if (NULL == ILocale) + fail(NULL, "Failed to get locale interface."); + } +#endif /* __amigaos4__ */ + + return TRUE; +} + + +static void CloseLibraries(void) +{ + if (LocaleBase) + { + if (WindowPropertiesCatalog) + { + CloseCatalog(WindowPropertiesCatalog); + WindowPropertiesCatalog = NULL; + } +#ifdef __amigaos4__ + if (ILocale) + { + DropInterface((struct Interface *)ILocale); + IIntuition = NULL; + } +#endif /* __amigaos4__ */ + CloseLibrary((struct Library *) LocaleBase); + LocaleBase = NULL; + } + +#ifdef __amigaos4__ + if (ICyberGfx) + { + DropInterface((struct Interface *)ICyberGfx); + ICyberGfx = NULL; + } +#endif /* __amigaos4__ */ + if (CyberGfxBase) + { + CloseLibrary(CyberGfxBase); + CyberGfxBase = NULL; + } + + if (TimerIORequest) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)ITimer); +#endif + CloseDevice(&TimerIORequest->tr_node); + DeleteIORequest((struct IORequest *)TimerIORequest); + TimerIORequest = NULL; + } + +#ifdef __amigaos4__ + if (IScalosGfx) + { + DropInterface((struct Interface *)IScalosGfx); + IScalosGfx = NULL; + } +#endif /* __amigaos4__ */ + if (ScalosGfxBase) + { + CloseLibrary((struct Library *) ScalosGfxBase); + ScalosGfxBase = NULL; + } +#ifdef __amigaos4__ + if (IGraphics) + { + DropInterface((struct Interface *)IGraphics); + IGraphics = NULL; + } +#endif /* __amigaos4__ */ + if (GfxBase) + { + CloseLibrary((struct Library *) GfxBase); + GfxBase = NULL; + } +#ifdef __amigaos4__ + if (IIconobject) + { + DropInterface((struct Interface *)IIconobject); + IIconobject = NULL; + } +#endif /* __amigaos4__ */ + if (IconobjectBase) + { + CloseLibrary(IconobjectBase); + IconobjectBase = NULL; + } +#ifdef __amigaos4__ + if (IPreferences) + { + DropInterface((struct Interface *)IPreferences); + IPreferences = NULL; + } +#endif /* __amigaos4__ */ + if (PreferencesBase) + { + CloseLibrary(PreferencesBase); + PreferencesBase = NULL; + } + +#ifdef __amigaos4__ + if (IIFFParse) + { + DropInterface((struct Interface *)IIFFParse); + IIFFParse = NULL; + } +#endif /* __amigaos4__ */ + if (IFFParseBase) + { + CloseLibrary(IFFParseBase); + IFFParseBase = NULL; + } + +#ifdef __amigaos4__ + if (IScalos) + { + DropInterface((struct Interface *)IScalos); + IScalos = NULL; + } +#endif /* __amigaos4__ */ + if (ScalosBase) + { + CloseLibrary((struct Library *) ScalosBase); + ScalosBase = NULL; + } +#ifdef __amigaos4__ + if (IIcon) + { + DropInterface((struct Interface *)IIcon); + IIcon = NULL; + } +#endif /* __amigaos4__ */ + if (IconBase) + { + CloseLibrary(IconBase); + IconBase = NULL; + } +#ifdef __amigaos4__ + if (IMUIMaster) + { + DropInterface((struct Interface *)IMUIMaster); + IMUIMaster = NULL; + } +#endif /* __amigaos4__ */ + if (MUIMasterBase) + { + CloseLibrary(MUIMasterBase); + MUIMasterBase = NULL; + } +#ifdef __amigaos4__ + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } +#endif /* __amigaos4__ */ + if (IntuitionBase) + { + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } +} + +//---------------------------------------------------------------------------- + +static STRPTR GetLocString(ULONG MsgId) +{ + struct WindowProperties_LocaleInfo li; + + li.li_Catalog = WindowPropertiesCatalog; +#ifndef __amigaos4__ + li.li_LocaleBase = LocaleBase; +#else /* __amigaos4__ */ + li.li_ILocale = ILocale; +#endif /* __amigaos4__ */ + + return (STRPTR)GetWindowPropertiesString(&li, MsgId); +} + +static void TranslateStringArray(STRPTR *stringArray) +{ + while (*stringArray) + { + *stringArray = GetLocString((ULONG) *stringArray); + stringArray++; + } +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT OpenAboutMUIFunc(struct Hook *hook, Object *o, Msg msg) +{ + if (NULL == WIN_AboutMUI) + { + WIN_AboutMUI = MUI_NewObject(MUIC_Aboutmui, + MUIA_Window_RefWindow, WIN_Main, + MUIA_Aboutmui_Application, APP_Main, + TAG_END); + } + + if (WIN_AboutMUI) + set(WIN_AboutMUI, MUIA_Window_Open, TRUE); + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT OpenAboutFunc(struct Hook *hook, Object *o, Msg msg) +{ + MUI_Request(APP_Main, WIN_Main, 0, NULL, + GetLocString(MSGID_ABOUTREQOK), + GetLocString(MSGID_ABOUTREQFORMAT), + VERSION_MAJOR, VERSION_MINOR, COMPILER_STRING, CURRENTYEAR); +} + +//---------------------------------------------------------------------------- + +static void SaveSettings(Object *IconObj, struct ScaWindowStruct *ws) +{ + if (IconObj) + { + ULONG HideStatusBar = 0; + ULONG HideControlBar = 0; + ULONG NewCheckOverlap = 0; + ULONG NewThumbnailMode = 0; + ULONG ThumbnailLifetime = THUMBNAIL_LIFETIME_NOTSET; + ULONG NewActiveWindowTransparencyDefault = 0; + ULONG NewInactiveWindowTransparencyDefault = 0; + ULONG NewIconScaleFactorDefault = 0; + ULONG NewIconSizeConstraintsDefault = 0; + APTR UndoStep = NULL; + CONST_STRPTR *ToolTypesArray; + STRPTR *OldToolTypesArray; + + if (ws) + { + UndoStep = (APTR) DoMethod(ws->ws_WindowTask->mt_MainObject, SCCM_IconWin_BeginUndoStep); + } + + GetAttr(IDTA_ToolTypes, IconObj, (APTR) &ToolTypesArray); + OldToolTypesArray = CloneToolTypeArray(ToolTypesArray, 0); + + get(CycleMarkNoStatusBar, MUIA_Cycle_Active, &HideStatusBar); + if (HideStatusBar) + SetToolType(IconObj, "SCALOS_NOSTATUSBAR", ""); + else + RemoveToolType(IconObj, "SCALOS_NOSTATUSBAR"); + + get(CycleMarkNoControlBar, MUIA_Cycle_Active, &HideControlBar); + if (HideControlBar) + SetToolType(IconObj, "SCALOS_NOCONTROLBAR", ""); + else + RemoveToolType(IconObj, "SCALOS_NOCONTROLBAR"); + + if (ws) + { + SetAttrs(ws->ws_WindowTask->mt_MainObject, + SCCA_IconWin_StatusBar, !HideStatusBar, + SCCA_IconWin_ControlBar, !HideControlBar, + TAG_END); + } + + get(NumericButtonThumbnailsLifetime, MUIA_Numeric_Value, &ThumbnailLifetime); + if (THUMBNAIL_LIFETIME_NOTSET != ThumbnailLifetime) + { + char ThumbnailLifetimeString[20]; + + snprintf(ThumbnailLifetimeString, sizeof(ThumbnailLifetimeString), + "%ld", (long)ThumbnailLifetime); + SetToolType(IconObj, "SCALOS_THUMBNAIL_LIFETIME", ThumbnailLifetimeString); + } + else + { + // system-wide default thumbnail lifetime has been selected + RemoveToolType(IconObj, "SCALOS_THUMBNAIL_LIFETIME"); + } + + if (PatternNumber != NewPatternNumber) + { + if (0 != NewPatternNumber) + { + char PatternNumberString[20]; + + snprintf(PatternNumberString, sizeof(PatternNumberString), + "%ld", (long)NewPatternNumber); + SetToolType(IconObj, "SCALOS_PATTERNNO", PatternNumberString); + } + else + { + // default pattern has been selected + RemoveToolType(IconObj, "SCALOS_PATTERNNO"); + } + + d1(KPrintF("%s/%s/%ld: ws=%08lx\n", __FILE__, __FUNC__, __LINE__, ws)); + if (ws) + { + if (0 == NewPatternNumber) + { + // default pattern has been selected + if (SCAV_ViewModes_Icon == ws->ws_Viewmodes) + NewPatternNumber = PATTERNNR_IconWindowDefault; + else + NewPatternNumber = PATTERNNR_TextWindowDefault; + } + + DoMethod(ws->ws_WindowTask->mt_MainObject, SCCM_IconWin_NewPatternNumber, NewPatternNumber); + } + } + + get(CycleThumbnails, MUIA_Cycle_Active, &NewThumbnailMode); + if (NewThumbnailMode != ThumbnailMode) + { + if (NewThumbnailMode > 0 && NewThumbnailMode <= 3) + { + static const char *ThumbnailModes[] = + { + "NEVER", + "ASDEFAULT", + "ALWAYS" + }; + char ThumbnailsString[20]; + + snprintf(ThumbnailsString, sizeof(ThumbnailsString), + "%s", ThumbnailModes[NewThumbnailMode - 1]); + SetToolType(IconObj, "SCALOS_THUMBNAILS", ThumbnailsString); + } + else + { + // default thumbnail mode has been selected + RemoveToolType(IconObj, "SCALOS_THUMBNAILS"); + } + + if (ws) + { + SetAttrs(ws->ws_WindowTask->mt_MainObject, + SCCA_IconWin_ThumbnailView, NewThumbnailMode - 1, + TAG_END); + } + } + + get(CycleCheckOverlap, MUIA_Cycle_Active, &NewCheckOverlap); + if (NewCheckOverlap != CheckOverlap) + { + if (CHECKOVERLAP_NOTSET == NewCheckOverlap) + { + // default overlap checking has been selected + RemoveToolType(IconObj, "SCALOS_CHECKOVERLAP"); + } + else + { + char CheckOverlapString[10]; + + snprintf(CheckOverlapString, sizeof(CheckOverlapString), "%ld", (long)NewCheckOverlap); + SetToolType(IconObj, "SCALOS_CHECKOVERLAP", CheckOverlapString); + } + + if (ws) + { + DoMethod(ws->ws_WindowTask->mt_MainObject, SCCM_IconWin_Update); + } + } + + get(CheckboxTransparencyActiveWindow, MUIA_Selected, &NewActiveWindowTransparencyDefault); + if (NewActiveWindowTransparencyDefault) + { + RemoveToolType(IconObj, "SCALOS_ACTIVETRANSPARENCY"); + + SetAttrs(ws->ws_WindowTask->mt_MainObject, + SCCA_IconWin_ActiveTransparency, prefsActiveWindowTransparency, + TAG_END); + } + else + { + char TransparencyString[10]; + + get(SliderTransparencyActiveWindow, MUIA_Numeric_Value, &ActiveWindowTransparency); + + snprintf(TransparencyString, sizeof(TransparencyString), "%ld", (long)ActiveWindowTransparency); + SetToolType(IconObj, "SCALOS_ACTIVETRANSPARENCY", TransparencyString); + + SetAttrs(ws->ws_WindowTask->mt_MainObject, + SCCA_IconWin_ActiveTransparency, ActiveWindowTransparency, + TAG_END); + } + + get(CheckboxTransparencyInactiveWindow, MUIA_Selected, &NewInactiveWindowTransparencyDefault); + if (NewInactiveWindowTransparencyDefault) + { + RemoveToolType(IconObj, "SCALOS_INACTIVETRANSPARENCY"); + + SetAttrs(ws->ws_WindowTask->mt_MainObject, + SCCA_IconWin_InactiveTransparency, prefsInactiveWindowTransparency, + TAG_END); + } + else + { + char TransparencyString[10]; + + get(SliderTransparencyInactiveWindow, MUIA_Numeric_Value, &InactiveWindowTransparency); + + snprintf(TransparencyString, sizeof(TransparencyString), "%ld", (long)InactiveWindowTransparency); + SetToolType(IconObj, "SCALOS_INACTIVETRANSPARENCY", TransparencyString); + + SetAttrs(ws->ws_WindowTask->mt_MainObject, + SCCA_IconWin_InactiveTransparency, InactiveWindowTransparency, + TAG_END); + } + + get(CheckboxNominalIconSize, MUIA_Selected, &NewIconScaleFactorDefault); + if (NewIconScaleFactorDefault) + { + RemoveToolType(IconObj, "SCALOS_ICONSCALEFACTOR"); + + SetAttrs(ws->ws_WindowTask->mt_MainObject, + SCCA_IconWin_IconScaleFactor, prefsIconScaleFactor, + TAG_END); + } + else + { + char IconSizeString[10]; + + get(SliderNominalIconSize, MUIA_Numeric_Value, &IconScaleFactor); + + snprintf(IconSizeString, sizeof(IconSizeString), "%ld", (long)IconScaleFactor); + SetToolType(IconObj, "SCALOS_ICONSCALEFACTOR", IconSizeString); + + SetAttrs(ws->ws_WindowTask->mt_MainObject, + SCCA_IconWin_IconScaleFactor, IconScaleFactor, + TAG_END); + } + + get(CheckboxIconSizeConstraints, MUIA_Selected, &NewIconSizeConstraintsDefault); + if (NewIconSizeConstraintsDefault) + { + RemoveToolType(IconObj, "SCALOS_ICONSIZECONSTRAINTS"); + + SetAttrs(ws->ws_WindowTask->mt_MainObject, + SCCA_IconWin_IconSizeConstraints, (ULONG) &prefIconSizeConstraints, + TAG_END); + } + else + { + char IconSizeConstraintsString[20]; + + GetIconSizeConstraints(&IconSizeConstraints); + + snprintf(IconSizeConstraintsString, sizeof(IconSizeConstraintsString), "%ld,%ld", + (long) IconSizeConstraints.MinX, (long) IconSizeConstraints.MaxX); + SetToolType(IconObj, "SCALOS_ICONSIZECONSTRAINTS", IconSizeConstraintsString); + + SetAttrs(ws->ws_WindowTask->mt_MainObject, + SCCA_IconWin_IconSizeConstraints, (ULONG) &IconSizeConstraints, + TAG_END); + } + + if (ws) + { + CONST_STRPTR *NewToolTypeArray = NULL; + STRPTR iconName = NULL; + BPTR dirLock = CurrentDir((BPTR) NULL); + + CurrentDir(dirLock); + + GetAttr(IDTA_ToolTypes, IconObj, (APTR) &NewToolTypeArray); + get(IconObj, DTA_Name, &iconName); + + DoMethod(ws->ws_WindowTask->mt_MainObject, + SCCM_IconWin_AddUndoEvent, + UNDO_SetToolTypes, + UNDOTAG_IconDirLock, dirLock, + UNDOTAG_IconName, (ULONG) iconName, + UNDOTAG_OldToolTypes, (ULONG) OldToolTypesArray, + UNDOTAG_NewToolTypes, (ULONG) NewToolTypeArray, + TAG_END + ); + + DoMethod(ws->ws_WindowTask->mt_MainObject, SCCM_IconWin_EndUndoStep, UndoStep); + } + if (OldToolTypesArray) + { + free(OldToolTypesArray); + } + } +} + +//---------------------------------------------------------------------------- + +static Object *GetIconObject(CONST_STRPTR IconName, BPTR DirLock) +{ + Object *IconObj; + struct ScaWindowList *WinList = NULL; + struct FileInfoBlock *fib = NULL; + BPTR fLock = (BPTR)NULL; + + do { + struct ScaWindowStruct *ws; + + IconObj = NewIconObject(IconName, NULL); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: IconObj=%08lx\n", __LINE__, IconObj)); + if (IconObj) + break; + + fLock = Lock(IconName, ACCESS_READ); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: fLock=%08lx IconName=<%s>\n", __LINE__, fLock, IconName)); + if ((BPTR)NULL == fLock) + break; + + fib = AllocDosObject(DOS_FIB, TAG_END); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: fib=%08lx\n", __LINE__, fib)); + if (NULL == fib) + break; + + if (!Examine(fLock, fib)) + break; + + WinList = SCA_LockWindowList(SCA_LockWindowList_Shared); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: WinList=%08lx\n", __LINE__, WinList)); + if (NULL == WinList) + break; + + + for (ws = WinList->wl_WindowStruct; ws; ws = (struct ScaWindowStruct *) ws->ws_Node.mln_Succ) + { + if (LOCK_SAME == SameLock(ws->ws_Lock, DirLock)) + { + IconObj = (Object *) DoMethod(ws->ws_WindowTask->mt_MainObject, + SCCM_IconWin_GetDefIcon, IconName, + fib->fib_DirEntryType, fib->fib_Protection); + } + } + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: IconObj=%08lx\n", __LINE__, IconObj)); + } while (0); + + if (fLock) + UnLock(fLock); + if (fib) + FreeDosObject(DOS_FIB, fib); + if (WinList) + SCA_UnLockWindowList(); + + return IconObj; +} + +//---------------------------------------------------------------------------- + +static Object *GetDeviceIconObject(CONST_STRPTR IconName, CONST_STRPTR VolumeName, CONST_STRPTR DeviceName) +{ + Object *IconObj = NULL; + BPTR OldDir = (BPTR)NULL; + BPTR dLock = (BPTR)NULL; + + do { + char DefIconName[256]; + + if (prefDefIconsFirst) + { + dLock = Lock(prefDefIconPath, ACCESS_READ); + if ((BPTR)NULL == dLock) + break; + + OldDir = CurrentDir(dLock); + + snprintf(DefIconName, sizeof(DefIconName), "def_%s", VolumeName); + + IconObj = NewIconObject(DefIconName, NULL); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: IconObj=%08lx <%s>\n", __LINE__, IconObj, DefIconName)); + if (IconObj) + break; + + BuildDefVolumeNameNoSpace(DefIconName, VolumeName, sizeof(DefIconName)); + + IconObj = NewIconObject(DefIconName, NULL); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: IconObj=%08lx <%s>\n", __LINE__, IconObj, DefIconName)); + if (IconObj) + break; + + snprintf(DefIconName, sizeof(DefIconName), "def_%s", DeviceName); + + IconObj = NewIconObject(DefIconName, NULL); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: IconObj=%08lx <%s>\n", __LINE__, IconObj, DefIconName)); + if (IconObj) + break; + + CurrentDir(OldDir); + OldDir = (BPTR)NULL; + + IconObj = NewIconObject("disk", NULL); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: IconObj=%08lx <%s>\n", __LINE__, IconObj, IconName)); + if (IconObj) + break; + + } + else + { + IconObj = NewIconObject("disk", NULL); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: IconObj=%08lx <%s>\n", __LINE__, IconObj, IconName)); + if (IconObj) + break; + + dLock = Lock(prefDefIconPath, ACCESS_READ); + if ((BPTR)NULL == dLock) + break; + + OldDir = CurrentDir(dLock); + + snprintf(DefIconName, sizeof(DefIconName), "def_%s", VolumeName); + + IconObj = NewIconObject(DefIconName, NULL); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: IconObj=%08lx <%s>\n", __LINE__, IconObj, DefIconName)); + if (IconObj) + break; + + BuildDefVolumeNameNoSpace(DefIconName, VolumeName, sizeof(DefIconName)); + + IconObj = NewIconObject(DefIconName, NULL); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: IconObj=%08lx <%s>\n", __LINE__, IconObj, DefIconName)); + if (IconObj) + break; + + snprintf(DefIconName, sizeof(DefIconName), "def_%s", DeviceName); + + IconObj = NewIconObject(DefIconName, NULL); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: IconObj=%08lx <%s>\n", __LINE__, IconObj, DefIconName)); + if (IconObj) + break; + } + + IconObj = GetDefIconObject(WBDISK, NULL); + } while (0); + + if (OldDir) + CurrentDir(OldDir); + if (dLock) + UnLock(dLock); + + return IconObj; +} + +//---------------------------------------------------------------------------- + +static BOOL isDiskWritable(BPTR dLock) +{ + struct InfoData *info = malloc(sizeof(struct InfoData)); + BOOL Result = TRUE; + + if (info) + { + Info(dLock, info); + + if (!CheckInfoData(info)) + Result = FALSE; + + free(info); + } + + return Result; +} + + +// return TRUE if Disk is writable +static ULONG CheckInfoData(const struct InfoData *info) +{ + ULONG Result = TRUE; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: DiskType=%ld DiskState=%ld\n", __LINE__, info->id_DiskType, info->id_DiskState)); + + switch (info->id_DiskType) + { + case ID_NO_DISK_PRESENT: + case ID_UNREADABLE_DISK: + Result = FALSE; + break; + } + + if (ID_WRITE_PROTECTED == info->id_DiskState) + Result = FALSE; + + return Result; +} + +//---------------------------------------------------------------------------- + +static BOOL IsDevice(struct WBArg *arg) +{ + BOOL isDevice = FALSE; + BPTR OldDir; + BPTR fLock = (BPTR)NULL; + + do { + char VolumeName[256]; + size_t Len; + + OldDir = CurrentDir(arg->wa_Lock); + + if (arg->wa_Name && strlen(arg->wa_Name) > 0) + { + fLock = Lock(arg->wa_Name, ACCESS_READ); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: fLock=%08lx Name=<%s>\n", __LINE__, fLock, arg->wa_Name)); + debugLock_d1(fLock); + if ((BPTR)NULL == fLock) + { + if (0 == stricmp(arg->wa_Name, "disk")) + { + struct WBArg ArgCopy = *arg; + + ArgCopy.wa_Name = ""; + isDevice = IsDevice(&ArgCopy); + } + break; + } + + NameFromLock(fLock, VolumeName, sizeof(VolumeName)); + } + else + { + NameFromLock(arg->wa_Lock, VolumeName, sizeof(VolumeName)); + } + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: VolumeName=<%s>\n", __LINE__, VolumeName)); + + Len = strlen(VolumeName); + isDevice = Len > 0 && ':' == VolumeName[Len - 1]; + } while (0); + + if (fLock) + UnLock(fLock); + CurrentDir(OldDir); + + return isDevice; +} + +//---------------------------------------------------------------------------- + +static void GetDeviceName(BPTR dLock, STRPTR DeviceName, size_t MaxLen) +{ + struct InfoData *info = malloc(sizeof(struct InfoData)); + + strcpy(DeviceName, ""); + if (info) + { + struct DosList *VolumeNode; + + Info(dLock, info); + + VolumeNode = (struct DosList *) BADDR(info->id_VolumeNode); + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: VolumeNode=%08lx\n", __LINE__, VolumeNode)); + + if (VolumeNode && VolumeNode->dol_Task && VolumeNode->dol_Task->mp_SigTask) + stccpy(DeviceName, ((struct Task *) VolumeNode->dol_Task->mp_SigTask)->tc_Node.ln_Name, MaxLen); + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: DeviceName=<%s>\n", __LINE__, DeviceName)); + + free(info); + } +} + +//---------------------------------------------------------------------------- + +static BOOL ReadScalosPrefs(void) +{ + CONST_STRPTR MainPrefsFileName = "ENV:Scalos/Scalos.prefs"; + APTR MainPrefsHandle; + + MainPrefsHandle = AllocPrefsHandle((STRPTR) "Scalos"); + if (NULL == MainPrefsHandle) + return FALSE; + + ReadPrefsHandle(MainPrefsHandle, (STRPTR) MainPrefsFileName); + + if (GetPreferences(MainPrefsHandle, ID_MAIN, SCP_ActiveWindowTransparency, &prefsActiveWindowTransparency, sizeof(&prefsActiveWindowTransparency))) + { + prefsActiveWindowTransparency = SCA_BE2WORD(prefsActiveWindowTransparency); + } + + if (GetPreferences(MainPrefsHandle, ID_MAIN, SCP_InactiveWindowTransparency, &prefsInactiveWindowTransparency, sizeof(&prefsInactiveWindowTransparency))) + { + prefsInactiveWindowTransparency = SCA_BE2WORD(prefsInactiveWindowTransparency); + } + + if (GetPreferences(MainPrefsHandle, ID_MAIN, SCP_IconSizeConstraints, &prefIconSizeConstraints, sizeof(prefIconSizeConstraints))) + { + prefIconSizeConstraints.MinX = SCA_BE2WORD(prefIconSizeConstraints.MinX); + prefIconSizeConstraints.MinY = SCA_BE2WORD(prefIconSizeConstraints.MinY); + prefIconSizeConstraints.MaxX = SCA_BE2WORD(prefIconSizeConstraints.MaxX); + prefIconSizeConstraints.MaxY = SCA_BE2WORD(prefIconSizeConstraints.MaxY); + } + + if (GetPreferences(MainPrefsHandle, ID_MAIN, SCP_IconNominalSize, &prefsIconScaleFactor, sizeof(prefsIconScaleFactor))) + { + prefsIconScaleFactor = SCA_BE2WORD(prefsIconScaleFactor); + } + + GetPreferences(MainPrefsHandle, ID_MAIN, SCP_LoadDefIconsFirst, &prefDefIconsFirst, sizeof(prefDefIconsFirst)); + // UBYTE + + prefDefIconPath = GetPrefsConfigString(MainPrefsHandle, SCP_PathsDefIcons, prefDefIconPath); + + if (prefDefIconPath) + prefDefIconPath = strdup(prefDefIconPath); + + FreePrefsHandle(MainPrefsHandle); + + return TRUE; +} + +static CONST_STRPTR GetPrefsConfigString(APTR prefsHandle, ULONG Id, CONST_STRPTR DefaultString) +{ + struct PrefsStruct *ps = FindPreferences(prefsHandle, ID_MAIN, Id); + + if (ps) + return (CONST_STRPTR) PS_DATA(ps); + + return DefaultString; +} + +//---------------------------------------------------------------------------- + +static void StripTrailingChar(STRPTR String, char CharToRemove) +{ + size_t Len = strlen(String); + + if (Len > 0 && CharToRemove == String[Len - 1]) + String[Len - 1] = '\0'; +} + +//---------------------------------------------------------------------------- + +// !! SCALOS WINDOW LIST WILL STAY LOCKED IF FOUND (Result != NULL) !! +static struct ScaWindowStruct *FindWindowByLock(BPTR xLock) +{ + struct ScaWindowList *swList = SCA_LockWindowList(SCA_LockWindowList_Shared); + struct ScaWindowStruct *Result = NULL; + + d1(kprintf(__FUNC__ "/%ld: xLock=%08lx\n", __LINE__, xLock)); + + if (swList) + { + struct ScaWindowStruct *swi; + + for (swi=swList->wl_WindowStruct; NULL == Result && swi; swi = (struct ScaWindowStruct *) swi->ws_Node.mln_Succ) + { + d1(kprintf(__FUNC__ "/%ld: swi=%08lx Lock=%08lx Same=%ld\n", __LINE__, \ + swi, swi->ws_Lock, SameLock(swi->ws_Lock, xLock))); + + if (LOCK_SAME == SameLock(swi->ws_Lock, xLock)) + { + d1(kprintf(__FUNC__ "/%ld: swi=%08lx\n", __LINE__, swi)); + Result = swi; + } + } + + if (NULL == Result) + { + d1(kprintf(__FUNC__ "/%ld: vor SCA_UnLockWindowList\n", __LINE__)); + SCA_UnLockWindowList(); + } + } + + d1(kprintf(__FUNC__ "/%ld: Result=%08lx\n", __LINE__, Result)); + + return Result; +} + +//---------------------------------------------------------------------------- + +static void BuildDefVolumeNameNoSpace(STRPTR Buffer, CONST_STRPTR VolumeName, size_t MaxLength) +{ + STRPTR dlp; + size_t Len; + + stccpy(Buffer, "def_", MaxLength); + + Len = MaxLength - 1 - strlen(Buffer); + + dlp = Buffer + strlen(Buffer); + while (Len && *VolumeName) + { + if (' ' != *VolumeName) + { + *dlp++ = *VolumeName; + Len--; + } + VolumeName++; + } + *dlp = '\0'; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT PatternListConstructHookFunc(struct Hook *hook, Object *obj, struct NList_ConstructMessage *msg) +{ + struct PatternListEntry *scp = AllocPooled(msg->pool, sizeof(struct PatternListEntry)); + + if (scp) + { + scp->ple_PatternCount = 0; + scp->ple_ImageDescBuffer = 0; + NewList(&scp->ple_PatternList); + } + + return scp; +} + +static SAVEDS(void) INTERRUPT PatternListDestructHookFunc(struct Hook *hook, Object *obj, struct NList_DestructMessage *msg) +{ + struct PatternListEntry *scp = (struct PatternListEntry *) msg->entry; + struct PatternEntryDef *ped; + + d1(KPrintF("%s/%s/%ld: START scp=%08lx ple_PatternNumber=%lu\n", __FILE__, __FUNC__, __LINE__, scp, scp->ple_PatternNumber)); + d1(KPrintF("%s/%s/%ld: ple_ImageDescBuffer=%08lx\n", __FILE__, __FUNC__, __LINE__, scp->ple_ImageDescBuffer)); + + if (scp->ple_ImageDescBuffer) + { + free(scp->ple_ImageDescBuffer); + scp->ple_ImageDescBuffer = NULL; + } + + while ((ped = (struct PatternEntryDef *) RemHead(&scp->ple_PatternList))) + { + if (ped->ped_BitMapArray) + { + free(ped->ped_BitMapArray); + ped->ped_BitMapArray = NULL; + } + if (ped->ped_MUI_ImageObject) + { + DoMethod(NListPatterns, + MUIM_NList_UseImage, NULL, ped->ped_ThumbnailImageNr, 0); + + if (ped->ped_MUI_AllocatedImageObject) + MUI_DisposeObject(ped->ped_MUI_AllocatedImageObject); + ped->ped_MUI_ImageObject = ped->ped_MUI_AllocatedImageObject = NULL; + } + if (ped->ped_SAC) + { + ScalosGfxFreeSAC(ped->ped_SAC); + ped->ped_SAC = NULL; + } + d1(KPrintF("%s/%s/%ld: ped=%08lx\n", __FILE__, __FUNC__, __LINE__, ped)); + free(ped); + } + + FreePooled(msg->pool, scp, sizeof(struct PatternListEntry)); + + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); +} + + +static SAVEDS(ULONG) INTERRUPT PatternListDisplayHookFunc(struct Hook *hook, Object *obj, struct NList_DisplayMessage *ndm) +{ + if (ndm->entry) + { + struct PatternListEntry *scp = (struct PatternListEntry *) ndm->entry; + + d1(KPrintF("%s/%s/%ld: ple_PatternNumber=%lu ple_ImageDescBuffer=%08lx\n", __FILE__, __FUNC__, __LINE__, scp->ple_PatternNumber, scp->ple_ImageDescBuffer)); + + if (NULL == scp->ple_ImageDescBuffer && scp->ple_PatternCount > 0) + scp->ple_ImageDescBuffer = malloc(scp->ple_PatternCount * 10); + + // 1st column -- pattern number + ndm->preparses[0] = "\033r"; + + // 2nd column -- thumbnail(s) + ndm->preparses[1] = "\033l"; + + // 1st column -- pattern number + if (scp->ple_PatternNumber) + { + snprintf(scp->ple_ImageNrBuffer, sizeof(scp->ple_ImageNrBuffer), + "%d", scp->ple_PatternNumber); + ndm->strings[0] = scp->ple_ImageNrBuffer; + } + else + ndm->strings[0] = GetLocString(MSGID_PATTERNR_DEFAULT); + + if (scp->ple_ImageDescBuffer) + { + // 2nd column -- thumbnail(s) + const struct PatternEntryDef *ped; + STRPTR lp = scp->ple_ImageDescBuffer; + + for (ped = (const struct PatternEntryDef *) scp->ple_PatternList.lh_Head; + ped != (const struct PatternEntryDef *) &scp->ple_PatternList.lh_Tail; + ped = (const struct PatternEntryDef *) ped->ped_Node.ln_Succ) + { + sprintf(lp, "\33o[%ld]", (unsigned long)ped->ped_ThumbnailImageNr); + lp += strlen(lp); + + d1(KPrintF("%s/%s/%ld: lp=<%s> ord=%ld scp=%08lx ImageObj=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, lp, ndm->entry_pos, scp, ped->ped_MUI_ImageObject)); + } + ndm->strings[1] = scp->ple_ImageDescBuffer; + d1(KPrintF("%s/%s/%ld: len=%lu ple_PatternCount=%lu\n", __FILE__, __FUNC__, __LINE__, lp - scp->ple_ImageDescBuffer, scp->ple_PatternCount)); + } + else + { + ndm->strings[1] = ""; + } + } + else + { + // display titles + + // 1st column -- pattern number + ndm->preparses[0] = "\033c"; + + // 2nd column -- thumbnail + ndm->preparses[1] = "\033c"; + + // 1st column -- pattern number + ndm->strings[0] = GetLocString(MSGID_COLUMNTITLE_1); + + // 2nd column -- thumbnail + ndm->strings[1] = GetLocString(MSGID_COLUMNTITLE_3); + } + + return 0; +} + + +static SAVEDS(LONG) INTERRUPT PatternListCompareHookFunc(struct Hook *hook, Object *obj, struct NList_CompareMessage *ncm) +{ + const struct PatternListEntry *scp1 = (const struct PatternListEntry *) ncm->entry1; + const struct PatternListEntry *scp2 = (const struct PatternListEntry *) ncm->entry2; + LONG Result = 0; + + if (ncm->sort_type != MUIV_NList_SortType_None) + { + // sort by number + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = scp2->ple_PatternNumber - scp1->ple_PatternNumber; + else + Result = scp1->ple_PatternNumber - scp2->ple_PatternNumber; + } + + return Result; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT PatternPopupWindowHookFunc(struct Hook *hook, Object *pop, Object *win) +{ + set(win, MUIA_Window_Width, MUIV_Window_Width_Default); +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT NewPatternHookFunc(struct Hook *hook, Object *o, Object *x) +{ + struct PatternListEntry *scp = NULL; + ULONG n = 0; + + get(NListPatterns, MUIA_NList_Active, &n); + DoMethod(PopObjectPatternNumber, MUIM_Popstring_Close, TRUE); + d1(KPrintF("%s/%s/%ld: n=%lu\n", __FILE__, __FUNC__, __LINE__, n)); + + DoMethod(NListPatterns, MUIM_NList_GetEntry, n, &scp); + + if (scp) + { + NewPatternNumber = scp->ple_PatternNumber; + SelectPattern(NewPatternNumber); + } +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT TogglePathHookFunc(struct Hook *hook, Object *o, Object *x) +{ + if (strlen(PathName) > 0) + { + LONG selected = 0; + + get(Group_Virtual, MUIA_ShowMe, &selected); + set(Group_Virtual, MUIA_ShowMe, !selected); + } +} + +//---------------------------------------------------------------------------- + +static Object *CreateEmptyThumbnailImage(void) +{ + static const ULONG ThumbnailImageColors[] = + { + 0xaaaaaaaa,0xaaaaaaaa,0xa0a0a0a0, + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, + 0x66666666,0x88888888,0xbbbbbbbb, + 0x99999999,0x99999999,0x99999999, + 0xbbbbbbbb,0xbbbbbbbb,0xbbbbbbbb, + 0xbbbbbbbb,0xaaaaaaaa,0x99999999, + 0xffffffff,0xbbbbbbbb,0xaaaaaaaa + }; + struct RastPort rp; + struct BitMap *bm; + Object *BitMapObj = NULL; + + rp.BitMap = NULL; + InitRastPort(&rp); + + do { + bm = rp.BitMap = AllocBitMap(ThumbnailWidth, ThumbnailHeight, 2, BMF_CLEAR, NULL); + d1(kprintf("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, bm)); + if (NULL == bm) + break; + + SetRast(&rp, 0); + SetAPen(&rp, 1); + + Move(&rp, 0, 0); + Draw(&rp, 0, ThumbnailHeight - 1); + Draw(&rp, ThumbnailWidth - 1, ThumbnailHeight - 1); + Draw(&rp, ThumbnailWidth - 1, 0); + Draw(&rp, 0, 0); + + Move(&rp, 0, 0); + Draw(&rp, ThumbnailWidth - 1, ThumbnailHeight - 1); + + Move(&rp, 0, ThumbnailHeight - 1); + Draw(&rp, ThumbnailWidth - 1, 0); + + BitMapObj = BitmapObject, + MUIA_Bitmap_Width, ThumbnailWidth, + MUIA_Bitmap_Height, ThumbnailHeight, + MUIA_Bitmap_Bitmap, (IPTR)bm, + MUIA_Bitmap_Transparent, 0, + MUIA_Bitmap_UseFriend, TRUE, + MUIA_Bitmap_Precision, PRECISION_ICON, + MUIA_Bitmap_SourceColors, (IPTR)ThumbnailImageColors, + End; + + d1(kprintf("%s/%s/%ld: BitMapObj=%08lx\n", __FILE__, __FUNC__, __LINE__, BitMapObj)); + + if (BitMapObj) + bm = NULL; // don't free bm + } while (0); + + if (bm) + FreeBitMap(bm); + + return BitMapObj; +} + +//---------------------------------------------------------------------------- + +static LONG ReadPatternPrefsFile(CONST_STRPTR Filename, BOOL Quiet) +{ + static const LONG StopChunkList[] = + { + ID_PREF, ID_PATT, + ID_PREF, ID_DEFS, + ID_PREF, ID_TCOL, + ID_PREF, ID_TBMP + }; + struct TempRastPort trp; + LONG Result; + struct IFFHandle *iff; + BOOL iffOpened = FALSE; + + InitRastPort(&trp.trp_rp); + trp.trp_rp.BitMap = NULL; + trp.trp_rp.Layer = NULL; + trp.trp_Width = 0; + + BitMapsRead = 0; + ThumbnailImageNumber = 0; + DoMethod(NListPatterns, MUIM_NList_Clear); + set(WIN_Main, MUIA_Window_Sleep, TRUE); + set(NListPatterns, MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + + do { + struct PatternEntryDef *ped = NULL; + + iff = AllocIFF(); + if (NULL == iff) + { + Result = IoErr(); + break; + } + + InitIFFasDOS(iff); + + iff->iff_Stream = (IPTR)Open(Filename, MODE_OLDFILE); + if (0 == iff->iff_Stream) + { + Result = IoErr(); + break; + } + + Result = OpenIFF(iff, IFFF_READ); + if (RETURN_OK != Result) + break; + + iffOpened = TRUE; + + Result = StopChunks(iff, StopChunkList, 5); + if (RETURN_OK != Result) + break; + + while (1) + { + struct ContextNode *cn; + + Result = ParseIFF(iff, IFFPARSE_SCAN); + d1(kprintf("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + if (RETURN_OK != Result) + break; + + cn = CurrentChunk(iff); + if (NULL == cn) + break; + + if (ID_DEFS == cn->cn_ID) + { + LONG Actual; + + Actual = ReadChunkBytes(iff, &pDefs, sizeof(pDefs)); + if (sizeof(pDefs) != Actual) + { + Result = IoErr(); + break; + } + pDefs.scd_Flags = SCA_BE2WORD(pDefs.scd_Flags); + pDefs.scd_WorkbenchPattern = SCA_BE2WORD(pDefs.scd_WorkbenchPattern); + pDefs.scd_ScreenPattern = SCA_BE2WORD(pDefs.scd_ScreenPattern); + pDefs.scd_WindowPattern = SCA_BE2WORD(pDefs.scd_ScreenPattern); + pDefs.scd_TextModePattern = SCA_BE2WORD(pDefs.scd_TextModePattern); + } + else if (ID_PATT == cn->cn_ID) + { + struct PatternListEntry *scp = NULL; + ULONG nEntries = 0; + + ped = CreatePatternEntryDef(); + if (NULL == ped) + break; + + if (0 == ReadChunkBytes(iff, &ped->ped_PatternPrefs.scxp_PatternPrefs, sizeof(struct ScaExtPatternPrefs))) + { + Result = IoErr(); + break; + } + + ped->ped_PatternPrefs.scxp_PatternPrefs.scp_Number = SCA_BE2WORD(ped->ped_PatternPrefs.scxp_PatternPrefs.scp_Number); + ped->ped_PatternPrefs.scxp_PatternPrefs.scp_RenderType = SCA_BE2WORD(ped->ped_PatternPrefs.scxp_PatternPrefs.scp_RenderType); + ped->ped_PatternPrefs.scxp_PatternPrefs.scp_Flags = SCA_BE2WORD(ped->ped_PatternPrefs.scxp_PatternPrefs.scp_Flags); + ped->ped_PatternPrefs.scxp_PatternPrefs.scp_NumColors = SCA_BE2WORD(ped->ped_PatternPrefs.scxp_PatternPrefs.scp_NumColors); + ped->ped_PatternPrefs.scxp_PatternPrefs.scp_DitherMode = SCA_BE2WORD(ped->ped_PatternPrefs.scxp_PatternPrefs.scp_DitherMode); + ped->ped_PatternPrefs.scxp_PatternPrefs.scp_DitherAmount = SCA_BE2WORD(ped->ped_PatternPrefs.scxp_PatternPrefs.scp_DitherAmount); + + if (AllPatterns[ped->ped_PatternPrefs.scxp_PatternPrefs.scp_Number]) + { + scp = AllPatterns[ped->ped_PatternPrefs.scxp_PatternPrefs.scp_Number]; + } + else + { + DoMethod(NListPatterns, MUIM_NList_InsertSingle, "", MUIV_NList_Insert_Bottom); + get(NListPatterns, MUIA_NList_Entries, &nEntries); + + nEntries--; + DoMethod(NListPatterns, MUIM_NList_GetEntry, nEntries, &scp); + } + + d1(KPrintF("%s/%s/%ld: ID_PATT scp=%08lx\n", __FILE__, __FUNC__, __LINE__, scp)); + if (scp) + { + scp->ple_PatternCount++; + scp->ple_PatternNumber = ped->ped_PatternPrefs.scxp_PatternPrefs.scp_Number; + + AllPatterns[ped->ped_PatternPrefs.scxp_PatternPrefs.scp_Number] = scp; + + AddTail(&scp->ple_PatternList, &ped->ped_Node); + } + } + else if (ID_TCOL == cn->cn_ID) + { + // ID_TCOL must always be immediately preceeded by ID_PATT for the same pattern + d1(KPrintF("%s/%s/%ld: ID_TCOL ped=%08lx sac=%08lx\n", __FILE__, __FUNC__, __LINE__, ped, ped->ped_SAC)); + if (ped) + { + if (NULL == ped->ped_SAC) + { + // create preliminary SAC with sac_ColorTable + ped->ped_SAC = ScalosGfxCreateSAC(1, 1, 8, NULL, NULL); + } + d1(KPrintF("%s/%s/%ld: ped=%08lx sac=%08lx\n", __FILE__, __FUNC__, __LINE__, ped, ped->ped_SAC)); + if (ped->ped_SAC) + { + ULONG n; + LONG Length; + WORD NumColors; + UBYTE byteColorTable[3*256]; + + Length = sizeof(NumColors); + + if (Length != ReadChunkBytes(iff, &NumColors, Length)) + { + Result = IoErr(); + break; + } + NumColors = SCA_BE2WORD(NumColors); + d1(KPrintF("%s/%s/%ld: NumColors=%ld\n", __FILE__, __FUNC__, __LINE__, NumColors)); + Length = NumColors * 3; + if (Length != ReadChunkBytes(iff, byteColorTable, Length)) + { + Result = IoErr(); + break; + } + + for (n=0; n < NumColors * 3; n++) + { + UBYTE ch = byteColorTable[n]; + + ped->ped_SAC->sac_ColorTable[n] = (ch << 24) + (ch << 16) + (ch << 8) + ch; + d1(KPrintF("%s/%s/%ld: ColorTable[%ld]=%08lx\n", __FILE__, __FUNC__, __LINE__, n, ped->ped_SAC->sac_ColorTable[n])); + } + } + } + } + else if (ID_TBMP == cn->cn_ID) + { + // ID_TBMP must always be preceeded by ID_PATT and ID_TCOL + d1(KPrintF("%s/%s/%ld: ID_TBMP ped=%08lx sac=%08lx\n", __FILE__, __FUNC__, __LINE__, ped, ped->ped_SAC)); + if (ped) + { + Result = ReadPrefsBitMap(iff, ped, &trp); + d1(KPrintF("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + if (RETURN_OK != Result) + break; + } + BitMapsRead++; + } + } + + d1(kprintf("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + if (IFFERR_EOF == Result) + Result = RETURN_OK; + } while (0); + + if (iff) + { + if (iffOpened) + CloseIFF(iff); + + if (iff->iff_Stream) + Close((BPTR)iff->iff_Stream); + + FreeIFF(iff); + } + + if (RETURN_OK != Result && !Quiet) + { + char Buffer[120]; + + Fault(Result, "", Buffer, sizeof(Buffer) - 1); + + // MUI_RequestA() + MUI_Request(APP_Main, WIN_Main, 0, NULL, + GetLocString(MSGID_ABOUTREQOK), + GetLocString(MSGID_REQTITLE_READERROR), + Filename, + Buffer); + } + + if (trp.trp_rp.BitMap) + FreeBitMap(trp.trp_rp.BitMap); + + CreateThumbnailImages(); + AddDefaultPatternEntry(); + + set(WIN_Main, MUIA_Window_Sleep, FALSE); + set(NListPatterns, MUIA_NList_Quiet, MUIV_NList_Quiet_None); + + d1(kprintf("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + + return Result; +} + + +static LONG ReadPrefsBitMap(struct IFFHandle *iff, struct PatternEntryDef *ped, struct TempRastPort *trp) +{ + LONG Result = RETURN_OK; + struct ScalosBitMapAndColor *sac = NULL; + + do { + LONG Length; + struct RastPort rp; + struct ScaPatternPrefsBitMap spb; + + if (sizeof(spb) != ReadChunkBytes(iff, &spb, sizeof(spb))) + { + Result = IoErr(); + break; + } + + spb.spb_Width = SCA_BE2WORD(spb.spb_Width); + spb.spb_Height = SCA_BE2WORD(spb.spb_Height); + + sac = ScalosGfxCreateSAC(spb.spb_Width, spb.spb_Height, + 8, NULL, NULL); + d1(KPrintF("%s/%s/%ld: sac=%08lx\n", __FILE__, __FUNC__, __LINE__, sac)); + if (NULL == sac) + break; + + InitRastPort(&rp); + rp.BitMap = sac->sac_BitMap; + + if (NULL == trp->trp_rp.BitMap || trp->trp_Width != TEMPRP_WIDTH(spb.spb_Width)) + { + if (trp->trp_rp.BitMap) + FreeBitMap(trp->trp_rp.BitMap); + + trp->trp_Width = TEMPRP_WIDTH(spb.spb_Width); + trp->trp_rp.BitMap = AllocBitMap(trp->trp_Width, 1, 8, BMF_STANDARD, NULL); + if (NULL == trp->trp_rp.BitMap) + { + Result = ERROR_NO_FREE_STORE; + break; + } + } + + Length = PIXELARRAY8_BUFFERSIZE(spb.spb_Width, spb.spb_Height - 1); + + ped->ped_BitMapArray = malloc(Length); + if (NULL == ped->ped_BitMapArray) + { + Result = ERROR_NO_FREE_STORE; + break; + } + + if (Length != ReadChunkBytes(iff, ped->ped_BitMapArray, Length)) + { + Result = IoErr(); + break; + } + + // Blit image data from ple_BitMapArray to sac_BitMap + WritePixelArray8(&rp, 0, 0, + spb.spb_Width - 1, spb.spb_Height - 1, + ped->ped_BitMapArray, &trp->trp_rp); + + if (ped->ped_SAC && ped->ped_SAC->sac_NumColors <= 256) + { + size_t Length = ped->ped_SAC->sac_NumColors * 3 * sizeof(ULONG); + + // copy ColorTable from preliminary SAC + memcpy(sac->sac_ColorTable, ped->ped_SAC->sac_ColorTable, Length); + + // free preliminary SAC + ScalosGfxFreeSAC(ped->ped_SAC); + } + + ped->ped_SAC = sac; + sac = NULL; + } while (0); + + if (RETURN_OK != Result) + { + if (ped->ped_SAC) + { + ScalosGfxFreeSAC(ped->ped_SAC); + ped->ped_SAC = NULL; + } + } + if (sac) + ScalosGfxFreeSAC(sac); + + return Result; +} + +//---------------------------------------------------------------------------- + +static void CreateThumbnailImages(void) +{ + T_TIMEVAL tvNow; + T_TIMEVAL tvStart; + ULONG n, nEntries = 0; + APTR prWindowPtr; + struct Process *MyProcess = (struct Process *) FindTask(NULL); + + prWindowPtr = MyProcess->pr_WindowPtr; + MyProcess->pr_WindowPtr = (APTR) ~0; // suppress error requesters + + set(WIN_Main, MUIA_Window_Sleep, TRUE); + + set(TextMsgProgress1, MUIA_Text_Contents, (ULONG) GetLocString(MSGID_LOADING_THUMBNAILS)); + + get(NListPatterns, MUIA_NList_Entries, &nEntries); + + set(NListPatterns, MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + + for (n = 0; n < nEntries; n++) + { + struct PatternListEntry *scp = NULL; + + DoMethod(NListPatterns, MUIM_NList_GetEntry, n, &scp); + + if (scp) + { + // replace images by empty thumbnail + struct PatternEntryDef *ped; + + for (ped = (struct PatternEntryDef *) scp->ple_PatternList.lh_Head; + ped != (struct PatternEntryDef *) &scp->ple_PatternList.lh_Tail; + ped = (struct PatternEntryDef *) ped->ped_Node.ln_Succ) + { + DoMethod(NListPatterns, MUIM_NList_UseImage, + EmptyThumbnailBitmap, + ped->ped_ThumbnailImageNr, 0); + + if (ped->ped_MUI_AllocatedImageObject) + { + MUI_DisposeObject(ped->ped_MUI_AllocatedImageObject); + ped->ped_MUI_ImageObject = ped->ped_MUI_AllocatedImageObject = NULL; + } + } + } + } + + ThumbnailImageNumber = 0; + + // for performance reasons, GaugeProgress, TextMsgProgress1, and TextMsgProgress2 + // are updated no faster than every 100ms + GetSysTime(&tvStart); + tvNow.tv_secs = 0; + tvNow.tv_micro = 100000; + AddTime(&tvStart, &tvNow); // +100ms + + set(GaugeProgress, MUIA_Gauge_Max, nEntries); + + for (n = 0; n < nEntries; n++) + { + struct PatternListEntry *scp = NULL; + + DoMethod(APP_Main, MUIM_Application_InputBuffered); + + GetSysTime(&tvNow); + + DoMethod(NListPatterns, MUIM_NList_GetEntry, n, &scp); + + if (scp) + { + struct PatternEntryDef *ped; + + for (ped = (struct PatternEntryDef *) scp->ple_PatternList.lh_Head; + ped != (struct PatternEntryDef *) &scp->ple_PatternList.lh_Tail; + ped = (struct PatternEntryDef *) ped->ped_Node.ln_Succ) + { + if (CmpTime(&tvStart, &tvNow) > 0) + { + // it's more than 100ms since initial start + char TextLine[150]; + ULONG WindowIsOpen = 0; + + tvNow.tv_secs = 0; + tvNow.tv_micro = 100000; + AddTime(&tvStart, &tvNow); // +100ms + + set(TextMsgProgress1, MUIA_Text_Contents, (ULONG) GetLocString(MSGID_LOADING_THUMBNAIL)); + set(TextMsgProgress2, MUIA_Text_Contents, (ULONG) ped->ped_PatternPrefs.scxp_Name); + + // make sure the progress display window is open + get(WIN_Progress, MUIA_Window_Open, &WindowIsOpen); + if (!WindowIsOpen) + { + set(WIN_Progress, MUIA_Window_Open, TRUE); + } + + snprintf(TextLine, sizeof(TextLine), GetLocString(MSGID_PROGRESS_THUMBNAILS), n, nEntries); + set(GaugeProgress, MUIA_Gauge_InfoText, (ULONG) TextLine); + + set(GaugeProgress, MUIA_Gauge_Current, n); + } + + CreateThumbnailImage(ped); + } + } + } + + set(GaugeProgress, MUIA_Gauge_Current, nEntries); // 100% + + set(NListPatterns, MUIA_NList_Quiet, MUIV_NList_Quiet_None); + + set(WIN_Progress, MUIA_Window_Open, FALSE); + set(WIN_Main, MUIA_Window_Sleep, FALSE); + + // restore pr_WindowPtr + MyProcess->pr_WindowPtr = prWindowPtr; +} + +//---------------------------------------------------------------------------- + +static void CreateThumbnailImage(struct PatternEntryDef *ped) +{ + struct RastPort rp; + + rp.BitMap = NULL; + InitRastPort(&rp); + + do { + d1(KPrintF("%s/%s/%ld: ple_MUI_ImageObject=%08lx ple_SAC=%08lx\n", __FILE__, __FUNC__, __LINE__, ped->ped_MUI_ImageObject, ped->ped_SAC)); + d1(KPrintF("%s/%s/%ld: Name=<%s>\n", __FILE__, __FUNC__, __LINE__, ped->ped_PatternPrefs.scxp_Name)); + + if (NULL == ped->ped_MUI_ImageObject) + { + UBYTE *BitMapArray; + ULONG ScreenDepth; + + ScreenDepth = GetBitMapAttr(WBScreen->RastPort.BitMap, BMA_DEPTH); + + d1(KPrintF("%s/%s/%ld: sac=%08lx\n", __FILE__, __FUNC__, __LINE__, ped->ped_SAC)); + if (NULL == ped->ped_SAC) + { + d1(KPrintF("%s/%s/%ld: sac=%08lx\n", __FILE__, __FUNC__, __LINE__, ped->ped_SAC)); + break; + } + else + { + BitMapArray = ped->ped_BitMapArray; + } + + if (CyberGfxBase && ScreenDepth > 8) + { + ped->ped_MUI_ImageObject = ped->ped_MUI_AllocatedImageObject = BitMapPicObject, + MUIA_ScaBitMappic_BitMap, (IPTR)ped->ped_SAC->sac_BitMap, + MUIA_ScaBitMappic_ColorTable, (IPTR)ped->ped_SAC->sac_ColorTable, + MUIA_ScaBitMappic_Width, ped->ped_SAC->sac_Width, + MUIA_ScaBitMappic_Height, ped->ped_SAC->sac_Height, + MUIA_ScaBitMappic_Screen, (IPTR)WBScreen, + MUIA_ScaBitmappic_BitMapArray, (IPTR)BitMapArray, + End; + } + else + { + ped->ped_MUI_ImageObject = ped->ped_MUI_AllocatedImageObject = BitmapObject, + MUIA_Bitmap_Width, ped->ped_SAC->sac_Width, + MUIA_Bitmap_Height, ped->ped_SAC->sac_Height, + MUIA_Bitmap_Bitmap, (IPTR)ped->ped_SAC->sac_BitMap, + MUIA_Bitmap_SourceColors, (IPTR)ped->ped_SAC->sac_ColorTable, + MUIA_Bitmap_UseFriend, TRUE, + MUIA_Bitmap_Precision, PRECISION_ICON, + End; + } + + d1(KPrintF("%s/%s/%ld: ple_MUI_ImageObject=%08lx\n", __FILE__, __FUNC__, __LINE__, ped->ped_MUI_ImageObject)); + if (NULL == ped->ped_MUI_ImageObject) + break; + + // generate unique image number + ped->ped_ThumbnailImageNr = ++ThumbnailImageNumber; + } + + rp.BitMap = NULL; // don't free rp.BitMap + } while (0); + + d1(KPrintF("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__)); + + if (rp.BitMap) + FreeBitMap(rp.BitMap); + + d1(KPrintF("%s/%s/%ld: ImageNr=%ld\n", __FILE__, __FUNC__, __LINE__, ped->ped_ThumbnailImageNr)); + d1(KPrintF("%s/%s/%ld: ple_MUI_ImageObject=%08lx\n", __FILE__, __FUNC__, __LINE__, ped->ped_MUI_ImageObject)); + + if (ped->ped_MUI_ImageObject) + { + DoMethod(NListPatterns, MUIM_NList_UseImage, + ped->ped_MUI_ImageObject, ped->ped_ThumbnailImageNr, 0); + } + else + { + DoMethod(NListPatterns, MUIM_NList_UseImage, + EmptyThumbnailBitmap, ped->ped_ThumbnailImageNr, 0); + } + + d1(KPrintF("%s/%s/%ld: end\n", __FILE__, __FUNC__, __LINE__)); +} + +//---------------------------------------------------------------------------- + +static void SelectPattern(ULONG PatternNumber) +{ + static char buffer[50]; + ULONG n, nEntries = 0; + BOOL Found; + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + get(NListPatterns, MUIA_NList_Entries, &nEntries); + + d1(KPrintF("%s/%s/%ld: Pattern=%lu Entries=%lu\n", __FILE__, __FUNC__, __LINE__, Pattern, nEntries)); + + for (Found = FALSE, n = 0; !Found && n < nEntries; n++) + { + struct PatternListEntry *scp = NULL; + + DoMethod(NListPatterns, MUIM_NList_GetEntry, n, &scp); + set(NListPatterns, MUIA_NList_Active, n); + + if (scp && scp->ple_PatternNumber == PatternNumber) + { + struct PatternEntryDef *ped = NULL; + + Found = TRUE; + + if (!IsListEmpty(&scp->ple_PatternList)) + ped = (struct PatternEntryDef *) scp->ple_PatternList.lh_Head; + + if (ped && ped->ped_MUI_ImageObject) + { + d1(KPrintF("%s/%s/%ld: ple_MUI_ImageObject=%08lx\n", __FILE__, __FUNC__, __LINE__, ped->ped_MUI_ImageObject)); + set(BackfillPatternPreview, BFA_BitmapObject, ped->ped_MUI_ImageObject); + } + } + } + + if (PatternNumber) + snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)PatternNumber); + else + stccpy(buffer, GetLocString(MSGID_PATTERNR_DEFAULT), sizeof(buffer)); + set(TextPatternNumber, MUIA_Text_Contents, buffer); + + if (!Found) + { + set(BackfillPatternPreview, BFA_BitmapObject, EmptyThumbnailBitmap); + set(NListPatterns, MUIA_NList_Active, MUIV_NList_Active_Off); + } +} + +//---------------------------------------------------------------------------- + +static void AddDefaultPatternEntry(void) +{ + struct PatternListEntry *scpDefault = NULL; + ULONG nEntries = 0; + BOOL Found; + ULONG n; + ULONG DefaultPatternNumber; + + if (ws && 0 == strcmp(ws->ms_ClassName, "TextWindow.sca")) + DefaultPatternNumber = pDefs.scd_TextModePattern; + else + DefaultPatternNumber = pDefs.scd_WindowPattern; + + + get(NListPatterns, MUIA_NList_Entries, &nEntries); + + for (Found = FALSE, n = 0; !Found && n < nEntries; n++) + { + DoMethod(NListPatterns, MUIM_NList_GetEntry, n, &scpDefault); + set(NListPatterns, MUIA_NList_Active, n); + + if (scpDefault && scpDefault->ple_PatternNumber == DefaultPatternNumber) + { + d1(KPrintF("%s/%s/%ld: BitMapObject=%08lx\n", __FILE__, __FUNC__, __LINE__, scp->ple_MUI_ImageObject)); + Found = TRUE; + } + } + + if (Found) + { + struct PatternListEntry *scpNew = NULL; + + set(NListPatterns, MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + + DoMethod(NListPatterns, MUIM_NList_InsertSingle, "", MUIV_NList_Insert_Top); + DoMethod(NListPatterns, MUIM_NList_GetEntry, 0, &scpNew); + + if (scpNew) + { + const struct PatternEntryDef *ped; + + scpNew->ple_PatternNumber = 0; + scpNew->ple_PatternCount = scpDefault->ple_PatternCount; + + for (ped = (const struct PatternEntryDef *) scpDefault->ple_PatternList.lh_Head; + ped != (const struct PatternEntryDef *) &scpDefault->ple_PatternList.lh_Tail; + ped = (const struct PatternEntryDef *) ped->ped_Node.ln_Succ) + { + struct PatternEntryDef *pedNew; + + pedNew = CreatePatternEntryDef(); + + if (pedNew) + { + *pedNew = *ped; + pedNew->ped_MUI_AllocatedImageObject = NULL; + pedNew->ped_SAC = ScalosGfxCreateSAC(1, 1, 8, NULL, NULL); + pedNew->ped_BitMapArray = NULL; + + AddTail(&scpNew->ple_PatternList, &pedNew->ped_Node); + } + } + } + + set(NListPatterns, MUIA_NList_Quiet, MUIV_NList_Quiet_None); + } + +} + +//---------------------------------------------------------------------------- + +static struct PatternEntryDef *CreatePatternEntryDef(void) +{ + struct PatternEntryDef *ped; + + ped = malloc(sizeof(struct PatternEntryDef)); + if (ped) + { + ped->ped_PatternPrefs.scxp_PatternPrefs.scp_Number = 1; + ped->ped_PatternPrefs.scxp_PatternPrefs.scp_RenderType = SCP_RenderType_Tiled; + ped->ped_PatternPrefs.scxp_PatternPrefs.scp_Flags = SCPF_ENHANCED | SCPF_AUTODITHER; + ped->ped_PatternPrefs.scxp_PatternPrefs.scp_NumColors = 100; + ped->ped_PatternPrefs.scxp_PatternPrefs.scp_DitherMode = DITHERMODE_FS; + ped->ped_PatternPrefs.scxp_PatternPrefs.scp_DitherAmount = 1; + ped->ped_PatternPrefs.scxp_PatternPrefs.scp_Precision = PRECISION_IMAGE; + ped->ped_PatternPrefs.scxp_PatternPrefs.scp_Type = SCP_BgType_Picture; + + ped->ped_ThumbnailImageNr = 0; + ped->ped_SAC = NULL; + ped->ped_MUI_ImageObject = ped->ped_MUI_AllocatedImageObject = NULL; + ped->ped_BitMapArray = NULL; + } + + return ped; +} + +//---------------------------------------------------------------------------- + +static void SetIconSizeConstraints(const struct Rectangle *SizeConstraints) +{ + ULONG MinSize, MaxSize; + + if (SizeConstraints->MinX < 16) + MinSize = ICONSIZEMIN_Unlimited; + else if (SizeConstraints->MinX < 24) + MinSize = ICONSIZEMIN_16; + else if (SizeConstraints->MinX < 32) + MinSize = ICONSIZEMIN_24; + else if (SizeConstraints->MinX < 48) + MinSize = ICONSIZEMIN_32; + else if (SizeConstraints->MinX < 64) + MinSize = ICONSIZEMIN_48; + else if (SizeConstraints->MinX < 96) + MinSize = ICONSIZEMIN_64; + else if (SizeConstraints->MinX < 128) + MinSize = ICONSIZEMIN_96; + else + MinSize = ICONSIZEMIN_128; + + if (SizeConstraints->MaxX <= 16) + MaxSize = ICONSIZEMAX_16; + else if (SizeConstraints->MaxX <= 24) + MaxSize = ICONSIZEMAX_24; + else if (SizeConstraints->MaxX <= 32) + MaxSize = ICONSIZEMAX_32; + else if (SizeConstraints->MaxX <= 48) + MaxSize = ICONSIZEMAX_48; + else if (SizeConstraints->MaxX <= 64) + MaxSize = ICONSIZEMAX_64; + else if (SizeConstraints->MaxX <= 96) + MaxSize = ICONSIZEMAX_96; + else if (SizeConstraints->MaxX <= 128) + MaxSize = ICONSIZEMAX_128; + else + MaxSize = ICONSIZEMAX_Unlimited; + + set(CycleIconMinSize, MUIA_Cycle_Active, MinSize); + set(CycleIconMaxSize, MUIA_Cycle_Active, MaxSize); +} + +//---------------------------------------------------------------------------- + +static void GetIconSizeConstraints(struct Rectangle *SizeConstraints) +{ + ULONG MinSize = 0, MaxSize = 0; + + get(CycleIconMinSize, MUIA_Cycle_Active, &MinSize); + get(CycleIconMaxSize, MUIA_Cycle_Active, &MaxSize); + + switch (MinSize) + { + case ICONSIZEMIN_16: + SizeConstraints->MinX = SizeConstraints->MinY = 16; + break; + case ICONSIZEMIN_24: + SizeConstraints->MinX = SizeConstraints->MinY = 24; + break; + case ICONSIZEMIN_32: + SizeConstraints->MinX = SizeConstraints->MinY = 32; + break; + case ICONSIZEMIN_48: + SizeConstraints->MinX = SizeConstraints->MinY = 48; + break; + case ICONSIZEMIN_64: + SizeConstraints->MinX = SizeConstraints->MinY = 64; + break; + case ICONSIZEMIN_96: + SizeConstraints->MinX = SizeConstraints->MinY = 96; + break; + case ICONSIZEMIN_128: + SizeConstraints->MinX = SizeConstraints->MinY = 128; + break; + case ICONSIZEMIN_Unlimited: + default: + SizeConstraints->MinX = SizeConstraints->MinY = 0; + break; + } + + switch (MaxSize) + { + case ICONSIZEMAX_16: + SizeConstraints->MaxX = SizeConstraints->MaxY = 16; + break; + case ICONSIZEMAX_24: + SizeConstraints->MaxX = SizeConstraints->MaxY = 24; + break; + case ICONSIZEMAX_32: + SizeConstraints->MaxX = SizeConstraints->MaxY = 32; + break; + case ICONSIZEMAX_48: + SizeConstraints->MaxX = SizeConstraints->MaxY = 48; + break; + case ICONSIZEMAX_64: + SizeConstraints->MaxX = SizeConstraints->MaxY = 64; + break; + case ICONSIZEMAX_96: + SizeConstraints->MaxX = SizeConstraints->MaxY = 96; + break; + case ICONSIZEMAX_128: + SizeConstraints->MaxX = SizeConstraints->MaxY = 128; + break; + case ICONSIZEMAX_Unlimited: + default: + SizeConstraints->MaxX = SizeConstraints->MaxY = SHRT_MAX; + break; + } +} + +//---------------------------------------------------------------------------- + + diff --git a/scalos/Modules/WindowProperties.MUI/WindowProperties.cd b/scalos/Modules/WindowProperties.MUI/WindowProperties.cd new file mode 100755 index 000000000..99d6de357 --- /dev/null +++ b/scalos/Modules/WindowProperties.MUI/WindowProperties.cd @@ -0,0 +1,354 @@ +; WindowProperties.cd +; version $VER: WindowProperties.catalog 40.6 (11.01.2009 19:01:45) +; codeset 0s +; language english +; +;#arrayopts static __far +; +; +MSGID_TITLENAME (//) +Scalos Window Properties +; +; +MSGID_OKBUTTON (//) +Ok +; +; +MSGID_SHORTHELP_OKBUTTON (//) +Save the changes in the icon's tooltypes.\n\ +If necessary, a new icon will be\n\ +created from a the default icon. +; +; +MSGID_CANCELBUTTON (//) +Cancel +; +; +MSGID_SHORTHELP_CANCELBUTTON (//) +Discard all changes and\n\ +leave the icon unchanged. +; +; +MSGID_CYCLE_NOSTATUSBAR (//) +Hide Status Bar: +; +; +MSGID_CYCLE_NOSTATUSBAR_SHORTHELP (//) +This switch can be used to turn off the status bar\n\ +for this window, independent of the global setting. +; +; +MSGID_POPUP_PATTERNNUMBER (//) +Pattern number: +; +; +MSGID_READ_ONLY (+1//) +(Read-Only) +; +; +MSGID_TEXT_WINDOWNAME_SHORTHELP (//) +Window name +; +; +MSGID_TEXT_PARENTDIR_SHORTHELP (//) +Drawer window path +; +; +MSGID_SHOWTHUMBNAILS_NOTSET (//) +(not set) +; +; +MSGID_SHOWTHUMBNAILS_NEVER (//) +Never +; +; +MSGID_SHOWTHUMBNAILS_AS_DEFAULT (//) +As default +; +; +MSGID_SHOWTHUMBNAILS_ALWAYS (//) +Always +; +; +MSGID_CYCLE_THUMBNAILS (//) +Show Thumbnails: +; +; +MSGID_CYCLE_THUMBNAILS_SHORTHELP (//) +Individual drawer-specific setting for thumbnail display.\n\ +If not set, the default setting from Scalos prefs is used. +; +; +MSGID_CHECKOVERLAP_NO (//) +No +; +; +MSGID_CHECKOVERLAP_YES (//) +Yes +; +; +MSGID_CHECKOVERLAP_NOTSET (//) +(not set) +; +; +MSGID_CYCLE_CHECKOVERLAP (//) +Check Overlapping Icons: +; +; +MSGID_CYCLE_CHECKOVERLAP_SHORTHELP (//) +Individual drawer-specific setting for overlapping icons check.\n\ +If set icons that overlap any other icon will be repositioned. +; +; +MSGID_HIDESTATUSBAR_NOTSET (//) +(not set) +; +; +MSGID_HIDESTATUSBAR_HIDE (//) +Hidden +; +; +MSGID_TRANSPARENCY_ACTIVEWINDOW (//) +Active window state +; +; +MSGID_TRANSPARENCY_INACTIVEWINDOW (//) +Inactive window state +; +; +MSGID_TRANSPARENCY_ACTIVEWINDOW_SHORTHELP (//) +Here you can select the degree of transparency\n\ +for the active Scalos desktop, icon, or text window.\n\ +The desktop will only get transparent if it is not a backdrop window. +; +; +MSGID_TRANSPARENCY_INACTIVEWINDOW_SHORTHELP (//) +Here you can select the degree of transparency\n\ +for all inactive Scalos desktop, icon, or text windows.\n\ +The desktop will only get transparent if it is not a backdrop window. +; +; +MSGID_TRANSPARENCY_OPAQUE (//) +opaque +; +; +MSGID_TRANSPARENCY_TRANSPARENT (//) +transparent +; +; +MSGID_CHECKBOX_TRANSPARENCY_USEDEFAULT (//) +Use default: +; +; +MSGID_CHECKBOX_TRANSPARENCY_USEDEFAULT_SHORTHELP (//) +Use default: +; +; +MSGID_CYCLE_NOCONTROLBAR (//) +Hide Control Bar: +; +; +MSGID_CYCLE_NOCONTROLBAR_SHORTHELP (//) +This switch can be used to turn off the control bar\n\ +for this window, independent of the global setting. +; +; +MSGID_HIDECONTROLBAR_NOTSET (//) +(not set) +; +; +MSGID_HIDECONTROLBAR_HIDE (//) +Hidden +; +; +MSGID_GROUP_ICONSCALING (//) +Icon Scaling +; +; +MSGID_ICONSCALING_NOMINALSIZE_SHORTHELP (//) +Standard size adjustment applied to all icons. +; +; +MSGID_ICONSCALING_NOMINALSIZE (//) +Nominal Size: +; +; +MSGID_ICONSCALING_PERCENT (//) +% +; +; +MSGID_ICONSCALING_MINSIZE (//) +Minimum Size: +; +; +MSGID_ICONSCALING_MINSIZE_SHORTHELP (//) +Minimum size for displayed icons.\n\ +Smaller icons will be scaled to\n\ +the specified minimum size. +; +; +MSGID_ICONSCALING_MAXSIZE (//) +Maximum Size: +; +; +MSGID_ICONSCALING_MAXSIZE_SHORTHELP (//) +Maximum size for displayed icons.\n\ +Larger icons will be scaled to\n\ +the specified maximum size. +; +; +MSGID_CHECKBOX_ICONSCALING_NOMINALSIZE (//) +Use default: +; +; +MSGID_CHECKBOX_ICONSCALING_NOMINALSIZE_SHORTHELP (//) +If this checkbox is checked, global icon scaling from Scalos Preferences is used.\n\ +Turn off this checkbox to specify individual icon scaling for this window. +; +; +MSGID_CHECKBOX_ICONSIZECONSTRAINTS_USEDEFAULT (//) +Use default: +; +; +MSGID_CHECKBOX_ICONSIZECONSTRAINTS_USEDEFAULT_SHORTHELP (//) +If this checkbox is checked, global icon size\n\ +constraints from Scalos Preferences are used.\n\ +Turn off this checkbox to specify individual\n\ +icon size constraints for this window. +; +;----------------------------------------------------------- +; +MSGID_MENU_PROJECT (2000//) +Project +; +; +MSGID_MENU_PROJECT_ABOUT (//) +About... +; +; +MSGID_MENU_PROJECT_ABOUTMUI (//) +About MUI... +; +; +MSGID_MENU_PROJECT_QUIT (//) +Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT (//) +Q +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK (3000//) +_OK +; +; +MSGID_ABOUTREQFORMAT (//) +\33c\033bScalos WindowProperties.module V%ld.%ld\033n\n\ +%s\n\ +© 2004%s The Scalos Team +; +;----------------------------------------------------------- +; +MSGID_THUMBNAILS_LIFETIME_FOREVER (3100//) +never +; +; +MSGID_THUMBNAILS_LIFETIME_NOTSET (//) +(Default) +; +; +MSGID_ICONSPAGE_THUMBNAILS_MAXAGE (//) +Cleanup thumbnails after: +; +; +MSGID_ICONSPAGE_THUMBNAILS_MAXAGE_SHORTHELP (//) +Cached thumbnail images will be removed from the cache\n\ +if they have not been accessed for more than the\n\ +specified number of days, in order to keep cache\n\ +size as small as possible.\n\ +If \033b(Default)\033n is selected, the global setting is used. +; +; +MSGID_ICONSPAGE_THUMBNAILS_MAXAGE_DAYS (//) +days +; +;----------------------------------------------------------- +; +MSGID_COLUMNTITLE_1 (3200//) +\33bNr. +; +; +MSGID_COLUMNTITLE_3 (+1//) +\33bPreview +; +; +MSGID_REQTITLE_READERROR (//) +Error reading pattern preferences\n\ +file \"%s\"\n\ +%s +; +; +MSGID_LOADING_THUMBNAIL (//) +\33cLoading Pattern Thumbnail for +; +; +MSGID_PROGRESS_THUMBNAILS (//) +\33c%ld/%ld +; +; +MSGID_LOADING_THUMBNAILS (//) +\033cLoading Pattern Thumbnails... +; +; +MSGID_WINDOW_STARTUP (//) +Scalos Window Properties Startup +; +; +MSGID_PATTERNR_DEFAULT (//) +(default) +; +;----------------------------------------------------------- +; +MSGID_ICONSIZES_16x16 (3300//) +16 x 16 +; +; +MSGID_ICONSIZES_24x24 (//) +24 x 24 +; +; +MSGID_ICONSIZES_32x32 (//) +32 x 32 +; +; +MSGID_ICONSIZES_48x48 (//) +48 x 48 +; +; +MSGID_ICONSIZES_64x64 (//) +64 x 64 +; +; +MSGID_ICONSIZES_96x96 (//) +96 x 96 +; +; +MSGID_ICONSIZES_128x128 (//) +128 x 128 +; +; +MSGID_ICONSIZES_UNLIMITED (//) +unlimited +; +;----------------------------------------------------------- +; +MSGID_REGISTERTITLE_WINDOW (//) +Window +; +; +MSGID_REGISTERTITLE_ICONS (//) +Icons +; +;----------------------------------------------------------- +; diff --git a/scalos/Modules/WindowProperties.MUI/WindowProperties.h b/scalos/Modules/WindowProperties.MUI/WindowProperties.h new file mode 100644 index 000000000..717f8f1ad --- /dev/null +++ b/scalos/Modules/WindowProperties.MUI/WindowProperties.h @@ -0,0 +1,63 @@ +// WindowProperties.h +// $Date$ +// $Revision$ + +#ifndef WINDOWPROPERTIES_H +#define WINDOWPROPERTIES_H + +//-------------------------------------------------------------------- + +// Values for Icon min size limits +enum IconSizesMin +{ + ICONSIZEMIN_Unlimited = 0, + ICONSIZEMIN_16, + ICONSIZEMIN_24, + ICONSIZEMIN_32, + ICONSIZEMIN_48, + ICONSIZEMIN_64, + ICONSIZEMIN_96, + ICONSIZEMIN_128, +}; + +//-------------------------------------------------------------------- + +// Values for Icon max size limits +enum IconSizesMax +{ + ICONSIZEMAX_16 = 0, + ICONSIZEMAX_24, + ICONSIZEMAX_32, + ICONSIZEMAX_48, + ICONSIZEMAX_64, + ICONSIZEMAX_96, + ICONSIZEMAX_128, + ICONSIZEMAX_Unlimited, +}; + +//-------------------------------------------------------------------- + +struct WindowProperties_LocaleInfo +{ + APTR li_LocaleBase; + APTR li_Catalog; + struct LocaleIFace *li_ILocale; +}; + +//-------------------------------------------------------------------- + +#define debugLock_d1(LockName) ; +#define debugLock_d2(LockName) \ + {\ + char xxName[200];\ + strcpy(xxName, "");\ + NameFromLock((LockName), xxName, sizeof(xxName));\ + kprintf(__FILE__ "/" __FUNC__ "/%ld: " #LockName "=%08lx <%s>\n", __LINE__, LockName, xxName);\ + } + +#if defined(__SASC) +int snprintf(char *, size_t, const char *, /*args*/ ...); +int vsnprintf(char *, size_t, const char *, va_list ap); +#endif /* __SASC */ + +#endif /* WINDOWPROPERTIES_H */ diff --git a/scalos/Modules/WindowProperties.MUI/config.mk b/scalos/Modules/WindowProperties.MUI/config.mk new file mode 100755 index 000000000..50db1f836 --- /dev/null +++ b/scalos/Modules/WindowProperties.MUI/config.mk @@ -0,0 +1,62 @@ +# $Date: 2011-07-16 18:28:30 +0200 (Sa, 16. Jul 2011) $ +# $Revision: 784 $ +############################################################# + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +TOOLTYPE_DIR = ../IconProperties.MUI +ICONOBJMCC_DIR = $(TOPLEVEL)/common/IconobjectMCC +BITMAPMCC_DIR = $(TOPLEVEL)/common/BitMapMCC +BACKFILLMCC_DIR = $(TOPLEVEL)/common/BackfillMCC + +vpath %.c $(TOOLTYPE_DIR) $(ICONOBJMCC_DIR) $(BITMAPMCC_DIR) $(BACKFILLMCC_DIR) + +INCLUDES += -I$(TOOLTYPE_DIR) \ + -I$(BITMAPMCC_DIR) \ + -I$(BACKFILLMCC_DIR) \ + -I$(ICONOBJMCC_DIR) + +SCALOS_LOCALE = $(OBJDIR)/WindowProperties_Locale.h + +CFLAGS += -D SCALOSLOCALE=$(SCALOS_LOCALE) + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += # + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += # + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +LFLAGS += -lmui -lutility + + +else + +############################################################################### +# AmigaOS + +LFLAGS += # + +endif +endif +endif diff --git a/scalos/Modules/WindowProperties.MUI/debug.h b/scalos/Modules/WindowProperties.MUI/debug.h new file mode 100644 index 000000000..aea559dac --- /dev/null +++ b/scalos/Modules/WindowProperties.MUI/debug.h @@ -0,0 +1,19 @@ +// debug.h +// $Date$ +// $Revision$ + +#ifndef DEBUG_H +#define DEBUG_H + +//---------------------------------------------------------------------------- + +#define d1(x) ; +#define d2(x) x; + +// from debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +//---------------------------------------------------------------------------- + +#endif /* DEBUG_H */ diff --git a/scalos/Modules/WindowProperties.MUI/makefile b/scalos/Modules/WindowProperties.MUI/makefile new file mode 100644 index 000000000..fd644d0f3 --- /dev/null +++ b/scalos/Modules/WindowProperties.MUI/makefile @@ -0,0 +1,181 @@ +# MakeFile für WindowProperties MUI module +# $Date$ +# $Revision$ +############################################################# + +TOPLEVEL = / +SUBDIRMAKE = $(MAKE) -s -C +CATCOMP = CatComp +FLEXCAT = FlexCat +CHEADERS = +CC = sc +CFLAGS = optimize nostackcheck nochkabort debug=s NOWVRET \ + strmer nover streq idlen=128 \ + data=far \ + define SCALOSLOCALE=$(SCALOS_LOCALE) \ + idir=sc:include/ \ + idir=include: \ + idir=//include \ + idir=$(subst ../,/,$(TOOLTYPE_DIR)) \ + idir=$(subst ../,/,$(ICONOBJMCC_DIR)) \ + idir=$(subst ../,/,$(BACKFILLMCC_DIR)) \ + idir=$(subst ../,/,$(BITMAPMCC_DIR)) +AS = phxass +AFLAGS = QUIET m=68020 linedebug opt=NRQB i=include: +LD = slink +LNFLAGS = quiet batch noicons stripdebug +LNDBFLAGS = quiet batch noicons addsym +LIBS = LIB:scnb.lib LIB:mempools.lib \ + LIB:debug.lib \ + //SAS-lib/snprintf.lib \ + LIB:amiga.lib +CSTARTUP = LIB:c.o +OBJDIR = .sasobj +TOOLTYPE_DIR = ../IconProperties.MUI +ICONOBJMCC_DIR = ../../common/IconobjectMCC +BITMAPMCC_DIR = ../../common/BitMapMCC +BACKFILLMCC_DIR = ../../common/BackfillMCC + +SCALOS_LOCALE = $(OBJDIR)/WindowProperties_Locale.h + +.SUFFIXES: .asm .cd + +############################################################# + +NAME = .bin_os3/WindowProperties.module +DBGNAME = $(NAME).debug +CATCOMPHEADER = $(SCALOS_LOCALE) +DESTTOOL = Scalos:modules/ +CAT_FILE = Scalos/WindowProperties.catalog +DESTCAT = Locale:Catalogs +ALLCATS = Catalogs/deutsch/$(CAT_FILE) \ + Catalogs/français/$(CAT_FILE) + +############################################################# + +all: $(NAME) \ + $(DBGNAME) \ + allcatalogs +# install +# clean + +############################################################# + +# make all Scalos .catalogs +allcatalogs: + @$(SUBDIRMAKE) Catalogs/deutsch/Scalos + @$(SUBDIRMAKE) Catalogs/français/Scalos + +############################################################# + +CSRCS = WindowProperties.c \ + $(ICONOBJMCC_DIR)/IconobjectMCC.c \ + $(BITMAPMCC_DIR)/BitMapMCC.c \ + $(TOOLTYPE_DIR)/ToolTypes.c \ + $(BACKFILLMCC_DIR)/Backfill.c \ + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +############################################################# + +XSRCS = $(notdir $(CSRCS)) +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(XSRCS:%.c=$(OBJDIR)/$(notdir %).o) + +############################################################# + +$(CATCOMPHEADER) : WindowProperties.cd + @printf '\033[32mMake Catcomp header: \033[31m\033[1m$@ \033[32mfrom \033[31m$<\033[0m\n' + @$(FLEXCAT) $< $@=$(TOPLEVEL)/CatComp_h.sd + +############################################################# + +$(OBJDIR)/WindowProperties.o : WindowProperties.c WindowProperties.h \ + $(SCALOS_LOCALE) \ + $(ICONOBJMCC_DIR)/IconobjectMCC.h \ + $(BITMAPMCC_DIR)/BitMapMCC.h \ + $(TOOLTYPE_DIR)/ToolTypes.h \ + debug.h + +$(OBJDIR)/BitMapMCC.o : $(BITMAPMCC_DIR)/BitMapMCC.c \ + $(BITMAPMCC_DIR)/BitMapMCC.h debug.h + +$(OBJDIR)/Backfill.o : $(BACKFILLMCC_DIR)/Backfill.c \ + $(BACKFILLMCC_DIR)/Backfill.h $(BITMAPMCC_DIR)/BitMapMCC.h + +$(OBJDIR)/IconobjectMCC.o : $(ICONOBJMCC_DIR)/IconobjectMCC.c \ + $(ICONOBJMCC_DIR)/IconobjectMCC.h debug.h + +$(OBJDIR)/ToolTypes.o : $(TOOLTYPE_DIR)/ToolTypes.c \ + $(TOOLTYPE_DIR)/ToolTypes.h debug.h + +############################################################# + +$(NAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNFLAGS) + +$(DBGNAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LIBS) $(LNDBFLAGS) + +############################################################# + +# commands generated a catalog (.catalog) from a catalog translation (.ct) file. +.ct.catalog: + $(CATCOMP) $*.cd $< CATALOG $*.catalog VB=1 + +$(OBJDIR)/IconobjectMCC.o : $(ICONOBJMCC_DIR)/IconobjectMCC.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/BitMapMCC.o : $(BITMAPMCC_DIR)/BitMapMCC.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/Backfill.o : $(BACKFILLMCC_DIR)/Backfill.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/ToolTypes.o : $(TOOLTYPE_DIR)/ToolTypes.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $< objectname $@ + +$(OBJDIR)/%.o : %.s + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +$(OBJDIR)/%.o : %.asm + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +############################################################# + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(NAME) \033[0mto \033[1m$(DESTTOOL) \033[0m\n' + @copy $(NAME) $(DESTTOOL) clone + @printf '\033[32mFlushing memory\033[0m\n' + @avail flush + @printf '\033[32mInstall: \033[31m\033[1m$(CAT_FILE)\033[0m\n' + -@copy 'catalogs/deutsch/$(CAT_FILE)' '$(DESTCAT)/Deutsch/Scalos/' clone + -@copy 'catalogs/français/$(CAT_FILE)' '$(DESTCAT)/français/Scalos/' clone + +############################################################# + +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + -@delete $(OBJS) $(NAME) $(DBGNAME) $(ALLCATS) $(CATCOMPHEADER) + @printf '\033[0m' + +############################################################# + +nodebug: + -splat -s -o "d2(" "d1(" "#?.c" + +############################################################# diff --git a/scalos/Modules/WindowProperties.MUI/makefile-new b/scalos/Modules/WindowProperties.MUI/makefile-new new file mode 100755 index 000000000..78da2558c --- /dev/null +++ b/scalos/Modules/WindowProperties.MUI/makefile-new @@ -0,0 +1,94 @@ +# $Date: 2011-07-16 18:28:30 +0200 (Sa, 16. Jul 2011) $ +# $Revision: 784 $ +############################################################# +TOPLEVEL = $(shell pwd)/../.. + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + SDPATH=/ +else + SDPATH=../.. +endif + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(OBJDIR)/WindowProperties.o \ + $(OBJDIR)/IconobjectMCC.o \ + $(OBJDIR)/BitMapMCC.o \ + $(OBJDIR)/Backfill.o \ + $(OBJDIR)/ToolTypes.o \ + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Subdirs +# + +SUBDIRS = $(filter-out Catalogs/sample/Scalos, $(wildcard Catalogs/*/Scalos)) + +############################################################################## +# +# Targets +# + +NAME = WindowProperties.module +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) \ + all_subdirs + +############################################################################## + +WindowProperties.c : $(OBJDIR)/WindowProperties_Locale.h + +$(OBJDIR)/WindowProperties_Locale.h : WindowProperties.cd + @$(ECHO) "FlexCat $@" + $(FLEXCAT) $< $@=$(SDPATH)/CatComp_h.sd + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + @$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) +ifneq ($(MACHINE), ppc-amigaos) + -@chmod u+x $@ +endif + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) Scalos:modules/ clone + +install: install_subdirs + + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* \ + $(OBJDIR)/WindowProperties_Locale.h + +clean: clean_subdirs + +############################################################################## + diff --git a/scalos/Modules/config.mk b/scalos/Modules/config.mk new file mode 100755 index 000000000..b41aef182 --- /dev/null +++ b/scalos/Modules/config.mk @@ -0,0 +1,35 @@ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += # + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += # + + +else + +############################################################################### +# AmigaOS + +LFLAGS += # + +endif +endif + diff --git a/scalos/Modules/makefile b/scalos/Modules/makefile new file mode 100644 index 000000000..04fc5f98d --- /dev/null +++ b/scalos/Modules/makefile @@ -0,0 +1,60 @@ +# makefile for all Scalos modules +# $Date$ +# $Revision$ + +############################################################# + +SUBDIRS = Rename.Reaction \ + NewDrawer.Reaction \ + Delete.Gadtools \ + Empty_Trashcan.Gadtools \ + Empty_Trashcan.MUI \ + Execute_Command.Gadtools \ + NewDrawer.Gadtools \ + Rename.Gadtools \ + Exchange.MUI \ + Find.MUI \ + FormatDisk.Gadtools \ + Rename.MUI \ + Delete.MUI \ + NewDrawer.MUI \ + IconProperties.MUI \ + WindowProperties.MUI \ + Information.MUI \ + Execute_Command.MUI \ + Updater.MUI \ + +############################################################# + +.PHONY: All install clean + +############################################################# + +define build_subdir +$(MAKE) -s --directory=$(1); +endef + +define install_subdir +$(MAKE) -s install --directory=$(1); +endef + +define clean_subdir +$(MAKE) -s clean --directory=$(1); +endef + +############################################################# + +All: + @$(foreach subdir,$(SUBDIRS),$(call build_subdir,$(subdir))) + +############################################################# + +install: + @$(foreach subdir,$(SUBDIRS),$(call install_subdir,$(subdir))) + +############################################################# + +clean: + @$(foreach subdir,$(SUBDIRS),$(call clean_subdir,$(subdir))) + +############################################################# diff --git a/scalos/Modules/makefile-new b/scalos/Modules/makefile-new new file mode 100755 index 000000000..f0707721a --- /dev/null +++ b/scalos/Modules/makefile-new @@ -0,0 +1,47 @@ +# $Date: 2011-08-10 17:07:41 +0200 (Mi, 10. Aug 2011) $ +# $Revision: 835 $ +############################################################# +TOPLEVEL = $(shell pwd)/.. + +include config.mk + +############################################################################## +# +# Project subdirectories +# + +SUBDIRS = WindowProperties.MUI \ + IconProperties.MUI \ + Information.MUI \ + Rename.MUI \ + NewDrawer.MUI \ + Execute_Command.MUI \ + Exchange.MUI \ + Find.MUI \ + Delete.MUI \ + Empty_Trashcan.MUI \ + Updater.MUI \ + FormatDisk.Gadtools \ + # + +# Delete.Gadtools \ +# Rename.Reaction \ +# Rename.Gadtools \ +# NewDrawer.Reaction \ +# NewDrawer.Gadtools \ +# Execute_Command.Gadtools \ +# Empty_Trashcan.Gadtools \ + +############################################################################## + +.PHONY: all install clean + +all: all_subdirs + +clean: clean_subdirs + +install: install_subdirs + +nodebug: nodebug_subdirs + + diff --git a/scalos/Plugins/FileTypes/DrawerContents/Catalogs/deutsch/Scalos/DrawerContentsPlugin.ct b/scalos/Plugins/FileTypes/DrawerContents/Catalogs/deutsch/Scalos/DrawerContentsPlugin.ct new file mode 100644 index 000000000..6fd8d2bc3 --- /dev/null +++ b/scalos/Plugins/FileTypes/DrawerContents/Catalogs/deutsch/Scalos/DrawerContentsPlugin.ct @@ -0,0 +1,23 @@ +; DrawerContentsPlugin.ct +## version $VER: DrawerContentsPlugin.catalog 40.7 (30.09.05) +## codeset 0 +## language deutsch +; +;#arrayopts static __far +; +; +MSGID_DRAWER_EMPTY +Dieses Verzeichnis ist leer. +;This drawer is empty. +; +; +MSGID_MORE_ENTRIES +... +;... +; +; +MSGID_ERROR_DOS +Fehler: %ld, %s. +;Error: %ld, %s. +; +; diff --git a/scalos/Plugins/FileTypes/DrawerContents/Catalogs/deutsch/Scalos/config.mk b/scalos/Plugins/FileTypes/DrawerContents/Catalogs/deutsch/Scalos/config.mk new file mode 100755 index 000000000..b60748fa3 --- /dev/null +++ b/scalos/Plugins/FileTypes/DrawerContents/Catalogs/deutsch/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = deutsch + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = german + +else + +############################################################################### +# AmigaOS and AROS + +LANG = deutsch + +endif +endif diff --git a/scalos/Plugins/FileTypes/DrawerContents/Catalogs/deutsch/Scalos/makefile b/scalos/Plugins/FileTypes/DrawerContents/Catalogs/deutsch/Scalos/makefile new file mode 100644 index 000000000..01f4e32fb --- /dev/null +++ b/scalos/Plugins/FileTypes/DrawerContents/Catalogs/deutsch/Scalos/makefile @@ -0,0 +1,13 @@ +# makefile for DrawerContentsPlugin (translated Texts : deutsch) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mdeutsch\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +DrawerContentsPlugin.catalog : DrawerContentsPlugin.ct ../../../DrawerContentsPlugin.cd + +All: DrawerContentsPlugin.catalog diff --git a/scalos/Plugins/FileTypes/DrawerContents/Catalogs/deutsch/Scalos/makefile-new b/scalos/Plugins/FileTypes/DrawerContents/Catalogs/deutsch/Scalos/makefile-new new file mode 100755 index 000000000..b59622868 --- /dev/null +++ b/scalos/Plugins/FileTypes/DrawerContents/Catalogs/deutsch/Scalos/makefile-new @@ -0,0 +1,33 @@ +# makefile for DrawerContentsPlugin (translated Texts : deutsch) +# $Date: 2011-07-31 22:05:01 +0200 (So, 31. Jul 2011) $ +# $Revision: 813 $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = DrawerContentsPlugin + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git "a/scalos/Plugins/FileTypes/DrawerContents/Catalogs/fran\303\247ais/Scalos/DrawerContentsPlugin.ct" "b/scalos/Plugins/FileTypes/DrawerContents/Catalogs/fran\303\247ais/Scalos/DrawerContentsPlugin.ct" new file mode 100755 index 000000000..896bb139c --- /dev/null +++ "b/scalos/Plugins/FileTypes/DrawerContents/Catalogs/fran\303\247ais/Scalos/DrawerContentsPlugin.ct" @@ -0,0 +1,23 @@ +; DrawerContentsPlugin.ct +## version $VER: DrawerContentsPlugin.catalog 40.7 (30.09.05) +## codeset 0 +## language français +; +;#arrayopts static __far +; +; +MSGID_DRAWER_EMPTY +Ce répertoire est vide. +;This drawer is empty. +; +; +MSGID_MORE_ENTRIES +... +;... +; +; +MSGID_ERROR_DOS +Erreur : %ld, %s. +;Error: %ld, %s. +; +; diff --git "a/scalos/Plugins/FileTypes/DrawerContents/Catalogs/fran\303\247ais/Scalos/config.mk" "b/scalos/Plugins/FileTypes/DrawerContents/Catalogs/fran\303\247ais/Scalos/config.mk" new file mode 100755 index 000000000..1b4cabf68 --- /dev/null +++ "b/scalos/Plugins/FileTypes/DrawerContents/Catalogs/fran\303\247ais/Scalos/config.mk" @@ -0,0 +1,40 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = français + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = french + +else + +############################################################################### +# AmigaOS and AROS + +LANG = français + +endif +endif diff --git "a/scalos/Plugins/FileTypes/DrawerContents/Catalogs/fran\303\247ais/Scalos/makefile" "b/scalos/Plugins/FileTypes/DrawerContents/Catalogs/fran\303\247ais/Scalos/makefile" new file mode 100644 index 000000000..48fec7af7 --- /dev/null +++ "b/scalos/Plugins/FileTypes/DrawerContents/Catalogs/fran\303\247ais/Scalos/makefile" @@ -0,0 +1,13 @@ +# makefile for DrawerContentsPlugin (translated Texts : français) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mfrançais\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +DrawerContentsPlugin.catalog : DrawerContentsPlugin.ct ../../../DrawerContentsPlugin.cd + +All: DrawerContentsPlugin.catalog diff --git "a/scalos/Plugins/FileTypes/DrawerContents/Catalogs/fran\303\247ais/Scalos/makefile-new" "b/scalos/Plugins/FileTypes/DrawerContents/Catalogs/fran\303\247ais/Scalos/makefile-new" new file mode 100755 index 000000000..f66b7484b --- /dev/null +++ "b/scalos/Plugins/FileTypes/DrawerContents/Catalogs/fran\303\247ais/Scalos/makefile-new" @@ -0,0 +1,33 @@ +# makefile for DrawerContentsPlugin (translated Texts : français) +# $Date: 2011-07-31 22:05:01 +0200 (So, 31. Jul 2011) $ +# $Revision: 813 $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = DrawerContentsPlugin + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Plugins/FileTypes/DrawerContents/Catalogs/sample/Scalos/DrawerContentsPlugin.ct b/scalos/Plugins/FileTypes/DrawerContents/Catalogs/sample/Scalos/DrawerContentsPlugin.ct new file mode 100644 index 000000000..e1f1f01fc --- /dev/null +++ b/scalos/Plugins/FileTypes/DrawerContents/Catalogs/sample/Scalos/DrawerContentsPlugin.ct @@ -0,0 +1,23 @@ +; DrawerContentsPlugin.ct +## version $VER: DrawerContentsPlugin.catalog 40.7 (30.09.05) +## codeset 0s +## language english +; +;#arrayopts static __far +; +; +MSGID_DRAWER_EMPTY +This drawer is empty. +;This drawer is empty. +; +; +MSGID_MORE_ENTRIES +... +;... +; +; +MSGID_ERROR_DOS +Error: %ld, %s. +;Error: %ld, %s. +; +; diff --git a/scalos/Plugins/FileTypes/DrawerContents/DrawerContents.c b/scalos/Plugins/FileTypes/DrawerContents/DrawerContents.c new file mode 100644 index 000000000..6c8464ea9 --- /dev/null +++ b/scalos/Plugins/FileTypes/DrawerContents/DrawerContents.c @@ -0,0 +1,420 @@ +// DrawerContents.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include "DrawerContents_base.h" +#include "DrawerContents.h" + +#define DrawerContentsPlugin_NUMBERS +#define DrawerContentsPlugin_ARRAY +#define DrawerContentsPlugin_CODE +#include STR(SCALOSLOCALE) + +//---------------------------------------------------------------------------- + +#ifndef __amigaos4__ +// aus mempools.lib +extern int _STI_240_InitMemFunctions(void); +extern void _STD_240_TerminateMemFunctions(void); +#endif + +//---------------------------------------------------------------------------- + +struct DosLibrary *DOSBase; +T_LOCALEBASE LocaleBase; + +#ifdef __amigaos4__ +struct DOSIFace *IDOS; +struct LocaleIFace *ILocale; +struct Library *NewlibBase; +struct Interface *INewlib; +#endif + +//--------------------------------------------------------------- + +static BOOL isDrawer(const struct FileInfoBlock *fib); +static CONST_STRPTR GetLocString(ULONG MsgId, struct DrawerContentsBase *DrawerContentsBase); + +//--------------------------------------------------------------- + +#define NOT_A_LOCK ((BPTR) ~0) +#define IS_VALID_LOCK(x) ((x) != NOT_A_LOCK) + +//--------------------------------------------------------------- + +BOOL initPlugin (struct PluginBase *PluginBase) +{ + struct DrawerContentsBase *DrawerContentsBase = (struct DrawerContentsBase *)PluginBase; + + d1(kprintf("%s/%s/%ld: DrawerContentsBase=%08lx procName=<%s>\n", __FILE__, __FUNC__, __LINE__, \ + DrawerContentsBase, FindTask(NULL)->tc_Node.ln_Name)); + + DrawerContentsBase->dcb_Locale = NULL; + DrawerContentsBase->dcb_Catalog = NULL; + +#if !defined(__amigaos4__) && !defined(__AROS__) + _STI_240_InitMemFunctions(); +#endif + + DOSBase = (APTR) OpenLibrary( "dos.library", 39 ); + if (NULL == DOSBase) + { + d1(kprintf("%s/%s/%ld: Fail\n", __FILE__, __FUNC__, __FILE__, __FUNC__, __LINE__)); + return FALSE; + } +#ifdef __amigaos4__ + IDOS = (struct DOSIFace *)GetInterface((struct Library *)DOSBase, "main", 1, NULL); + if (NULL == IDOS) + { + d1(kprintf("%s/%s/%ld: Fail\n", __FILE__, __FUNC__, __FILE__, __FUNC__, __LINE__)); + return FALSE; + } +#endif + +#ifdef __amigaos4__ + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + return FALSE; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + return FALSE; +#endif + + // LocaleBase may be NULL + LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 39 ); +#ifdef __amigaos4__ + if (NULL != LocaleBase) + { + ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL); + if (NULL == ILocale) + { + CloseLibrary((struct Library *)LocaleBase); + LocaleBase = NULL; + } + } +#endif + + if (LocaleBase) + { + if (NULL == DrawerContentsBase->dcb_Locale) + DrawerContentsBase->dcb_Locale = OpenLocale(NULL); + + if (DrawerContentsBase->dcb_Locale) + { + if (NULL == DrawerContentsBase->dcb_Catalog) + { + DrawerContentsBase->dcb_Catalog = OpenCatalog(DrawerContentsBase->dcb_Locale, + (STRPTR) "Scalos/DrawerContentsPlugin.catalog", NULL); + } + } + } + + d1(KPrintF("%s/%s/%ld: END - success\n", __FILE__, __FUNC__, __LINE__)); + + return TRUE; // Success +} + + +VOID closePlugin(struct PluginBase *PluginBase) +{ + struct DrawerContentsBase *DrawerContentsBase = (struct DrawerContentsBase *)PluginBase; + + d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__)); + + if (LocaleBase) + { + if (DrawerContentsBase->dcb_Catalog) + { + CloseCatalog(DrawerContentsBase->dcb_Catalog); + DrawerContentsBase->dcb_Catalog = NULL; + } + if (DrawerContentsBase->dcb_Locale) + { + CloseLocale(DrawerContentsBase->dcb_Locale); + DrawerContentsBase->dcb_Locale = NULL; + } + +#ifdef __amigaos4__ + if (ILocale) + { + DropInterface((struct Interface *)ILocale); + ILocale = NULL; + } +#endif + CloseLibrary((struct Library *)LocaleBase); + LocaleBase = NULL; + } +#ifdef __amigaos4__ + if (INewlib) + { + DropInterface(INewlib); + INewlib = NULL; + } + if (NewlibBase) + { + CloseLibrary(NewlibBase); + NewlibBase = NULL; + } + if (IDOS) + { + DropInterface((struct Interface *)IDOS); + IDOS = NULL; + } +#endif + if (DOSBase) + { + CloseLibrary((struct Library *) DOSBase); + DOSBase = NULL; + } + +#if !defined(__amigaos4__) && !defined(__AROS__) + _STD_240_TerminateMemFunctions(); +#endif +} + + +LIBFUNC_P3(STRPTR, LIBToolTipInfoString, + A0, struct ScaToolTipInfoHookData *, ttshd, + A1, CONST_STRPTR, args, + A6, struct PluginBase *, PluginBase) +{ + struct DrawerContentsBase *DrawerContentsBase = (struct DrawerContentsBase *)PluginBase; + struct RDArgs *allocRdArg; + struct RDArgs *rdArg = NULL; + STRPTR ArgsCopy = NULL; + struct FileInfoBlock *fib = NULL; + BOOL ScanForDirectories = FALSE; + BOOL SkipIcons = FALSE; + BOOL EmptyMsg = FALSE; + ULONG MaxLineLength = 30; + ULONG MaxEntries = 4; + + d1(kprintf(__FILE__ "/" "%s/%s/%ld: args=<%s>\n", __FILE__, __FUNC__, __LINE__, args)); + + do { + char FaultBuffer[100]; + char PatternBuffer[40]; + SIPTR ArgArray[5]; + ULONG *argMaxEntries; + ULONG *argLineLength; + STRPTR lp = ttshd->ttshd_Buffer; + size_t Len = ttshd->ttshd_BuffLen; + ULONG Entries, Count; + BOOL Success; + + memset(ArgArray, 0, sizeof(ArgArray)); + + allocRdArg = AllocDosObject(DOS_RDARGS, NULL); + + d1(kprintf("%s/%s/%ld: allocRdArg=%08lx\n", __FILE__, __FUNC__, __LINE__, allocRdArg)); + if (NULL == allocRdArg) + break; + + ArgsCopy = malloc(2 + strlen(args)); + if (NULL == ArgsCopy) + break; + + // important: ReadArgs() requires a trailing "\n" !! + strcpy(ArgsCopy, args); + strcat(ArgsCopy, "\n"); + + allocRdArg->RDA_Source.CS_Buffer = ArgsCopy; + allocRdArg->RDA_Source.CS_Length = strlen(ArgsCopy); + allocRdArg->RDA_Source.CS_CurChr = 0; + allocRdArg->RDA_Flags |= RDAF_NOPROMPT; + + rdArg = ReadArgs("DIRS/S,ENTRIES/K/N,LINELENGTH/K/N,NOICONS/S,SHOWEMPTY/S", + ArgArray, allocRdArg); + + d1(kprintf("%s/%s/%ld: rdArg=%08lx\n", __FILE__, __FUNC__, __LINE__, rdArg)); + if (NULL == rdArg) + { + Fault(IoErr(), NULL, FaultBuffer, sizeof(FaultBuffer)-1); + sprintf(ttshd->ttshd_Buffer, GetLocString(MSGID_ERROR_DOS, DrawerContentsBase), IoErr(), FaultBuffer); + + d1(kprintf(__FILE__ "/" "%s/%s/%ld: ReadArgs() returned error %ld\n", __FILE__, __FUNC__, __LINE__, IoErr())); + break; + } + + argMaxEntries = (ULONG *) ArgArray[1]; + argLineLength = (ULONG *) ArgArray[2]; + + if (ArgArray[0]) + ScanForDirectories = TRUE; + if (argMaxEntries) + MaxEntries = *argMaxEntries; + if (argLineLength) + MaxLineLength = *argLineLength; + if (ArgArray[3]) + SkipIcons = TRUE; + if (ArgArray[4]) + EmptyMsg = TRUE; + + if (MaxEntries < 1 || MaxEntries > 64) + break; + if (MaxLineLength < 5 || MaxLineLength > 256) + break; + + if (ParsePatternNoCase(SkipIcons ? "~(#?.INFO)" : "#?", PatternBuffer, sizeof(PatternBuffer)) < 0) + break; + + fib = AllocDosObject(DOS_FIB, NULL); + + d1(kprintf(__FILE__ "/" "%s/%s/%ld: fib=%08lx\n", __FILE__, __FUNC__, __LINE__, fib)); + if (NULL == fib) + break; + + if ((BPTR)NULL == ttshd->ttshd_FileLock) + break; + + if (!Examine(ttshd->ttshd_FileLock, fib)) + break; + + if (!isDrawer(fib)) + break; // this is a plain file... + + Entries = Count = 0; + while ((Success = ExNext(ttshd->ttshd_FileLock, fib)) && Count < MaxEntries && Len > 1) + { + d1(kprintf(__FILE__ "/" "%s/%s/%ld: FileName=<%s> EntryType=%ld\n", \ + __FILE__, __FUNC__, __LINE__, fib->fib_FileName, fib->fib_DirEntryType)); + + Entries++; + + if (strlen(ttshd->ttshd_Buffer) > MaxLineLength) + break; + + if (MatchPatternNoCase(PatternBuffer, fib->fib_FileName)) + { + if ((ScanForDirectories && isDrawer(fib)) + || (!ScanForDirectories && !isDrawer(fib))) + { + if (Count > 0) + { + stccpy(lp, ",", Len); + Len -= strlen(lp); + lp += strlen(lp); + } + + stccpy(lp, fib->fib_FileName, Len); + Len -= strlen(lp); + lp += strlen(lp); + + Count++; + } + } + } + if (0 == Entries) + { + if (EmptyMsg) + stccpy(lp, GetLocString(MSGID_DRAWER_EMPTY, DrawerContentsBase), Len); + } + else + { + if (Success && Count > 0) + stccpy(lp,GetLocString(MSGID_MORE_ENTRIES, DrawerContentsBase), Len); + } + } while (0); + + if (rdArg) + FreeArgs(rdArg); + if (allocRdArg) + FreeDosObject(DOS_RDARGS, allocRdArg); + if (fib) + FreeDosObject(DOS_FIB, fib); + if (ArgsCopy) + free(ArgsCopy); + + d1(kprintf(__FILE__ "/" "%s/%s/%ld: ResultString=<%s>\n", __FILE__, __FUNC__, __LINE__, ttshd->ttshd_Buffer)); + + return ttshd->ttshd_Buffer; +} +LIBFUNC_END + + +static BOOL isDrawer(const struct FileInfoBlock *fib) +{ + BOOL Result; + + switch (fib->fib_DirEntryType) + { + case ST_ROOT: + case ST_USERDIR: + case ST_LINKDIR: + Result = TRUE; + break; + case ST_SOFTLINK: + case ST_FILE: + case ST_LINKFILE: + Result = FALSE; + break; + default: + Result = fib->fib_DirEntryType >= 0; + } + + return Result; +} + +//---------------------------------------------------------------------------- + +static CONST_STRPTR GetLocString(ULONG MsgId, struct DrawerContentsBase *DrawerContentsBase) +{ + struct DrawerContentsPlugin_LocaleInfo li; + + li.li_Catalog = DrawerContentsBase->dcb_Catalog; +#ifndef __amigaos4__ + li.li_LocaleBase = LocaleBase; +#else + li.li_ILocale = ILocale; +#endif + + return GetDrawerContentsPluginString(&li, MsgId); +} + +//----------------------------------------------------------------------------- + +void _XCEXIT(long x) +{ +} + + +//---------------------------------------------------------------------------- + +#if !defined(__SASC) && !defined(__amigaos4__) +// Replacement for SAS/C library functions + +void exit(int x) +{ + (void) x; + while (1) + ; +} + +APTR _WBenchMsg; + +#endif /* !__SASC && !__amigaos4__ */ + +//---------------------------------------------------------------------------- diff --git a/scalos/Plugins/FileTypes/DrawerContents/DrawerContents.h b/scalos/Plugins/FileTypes/DrawerContents/DrawerContents.h new file mode 100644 index 000000000..abf4fe13b --- /dev/null +++ b/scalos/Plugins/FileTypes/DrawerContents/DrawerContents.h @@ -0,0 +1,35 @@ +// DrawerContents.h +// $Date$ +// $Revision$ + +#ifndef DRAWERCONTENTS_H +#define DRAWERCONTENTS_H + +int DrawerContentsInit(struct DrawerContentsBase *DrawerContentsBase); +int DrawerContentsOpen(struct DrawerContentsBase *DrawerContentsBase); +void DrawerContentsCleanup(struct DrawerContentsBase *DrawerContentsBase); +LIBFUNC_P3_PROTO(STRPTR, LIBToolTipInfoString, + A0, struct ScaToolTipInfoHookData *, ttshd, + A1, CONST_STRPTR, args, + A6, struct DrawerContentsBase *, DrawerContentsBase); + +//--------------------------------------------------------------- + +// Debugging... +#define d(x) ; +#define d1(x) ; +#define d2(x) x; + +// aus debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +struct DrawerContentsPlugin_LocaleInfo +{ + APTR li_LocaleBase; + APTR li_Catalog; + struct LocaleIFace *li_ILocale; +}; + +#endif /* DRAWERCONTENTS_H */ + diff --git a/scalos/Plugins/FileTypes/DrawerContents/DrawerContentsPlugin.cd b/scalos/Plugins/FileTypes/DrawerContents/DrawerContentsPlugin.cd new file mode 100644 index 000000000..ab5277be1 --- /dev/null +++ b/scalos/Plugins/FileTypes/DrawerContents/DrawerContentsPlugin.cd @@ -0,0 +1,20 @@ +; DrawerContentsPlugin.cd +; version $VER: DrawerContentsPlugin.catalog 40.7 (30.09.05) +; codeset 0s +; language english +; +;#arrayopts static __far +; +; +MSGID_DRAWER_EMPTY (//) +This drawer is empty. +; +; +MSGID_MORE_ENTRIES (//) +... +; +; +MSGID_ERROR_DOS (//) +Error: %ld, %s. +; +; diff --git a/scalos/Plugins/FileTypes/DrawerContents/DrawerContents_base.h b/scalos/Plugins/FileTypes/DrawerContents/DrawerContents_base.h new file mode 100644 index 000000000..a34f4300d --- /dev/null +++ b/scalos/Plugins/FileTypes/DrawerContents/DrawerContents_base.h @@ -0,0 +1,21 @@ +// DrawerContents.h +// $Date$ +// $Revision$ + +#ifndef __DRAWERCONTENTS_BASE_H +#define __DRAWERCONTENTS_BASE_H + +#include + +#include "plugin.h" + +struct DrawerContentsBase +{ + struct PluginBase dcb_LibNode; + + struct Locale *dcb_Locale; + struct Catalog *dcb_Catalog; +}; + +#endif // __DRAWERCONTENTS_BASE_H + diff --git a/scalos/Plugins/FileTypes/DrawerContents/config.mk b/scalos/Plugins/FileTypes/DrawerContents/config.mk new file mode 100755 index 000000000..e955930d2 --- /dev/null +++ b/scalos/Plugins/FileTypes/DrawerContents/config.mk @@ -0,0 +1,75 @@ +# $Date: 2011-07-31 22:05:01 +0200 (So, 31. Jul 2011) $ +# $Revision: 813 $ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +COMMON_DIR = $(TOPLEVEL)/common/Plugin + +INCLUDES += -I$(COMMON_DIR) + +SCALOS_LOCALE = $(OBJDIR)/DrawerContents_locale.h + +CFLAGS += -D SCALOSLOCALE=$(SCALOS_LOCALE) + +vpath %.c $(COMMON_DIR) + +############################################################################## + +include $(COMMON_DIR)/config.mk + +############################################################################## + +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +INCLUDES += # + +LFLAGS += -nostartfiles \ + -lmempools +# --verbose + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += -nostartfiles \ +# + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +LFLAGS += -nostartfiles \ +# + + +else + +############################################################################### +# AmigaOS + +INCLUDES += # + +LFLAGS += -lmempools \ + -ldebug \ + -lamiga21 \ + -lamiga \ + -lstubs + +endif +endif +endif diff --git a/scalos/Plugins/FileTypes/DrawerContents/makefile b/scalos/Plugins/FileTypes/DrawerContents/makefile new file mode 100644 index 000000000..1da9549a5 --- /dev/null +++ b/scalos/Plugins/FileTypes/DrawerContents/makefile @@ -0,0 +1,128 @@ +# $Date$ +# $Revision$ +# makefile für Scalos drawercontents.plugin +############################################################################## + +.SUFFIXES: .plugin .plugin.debug + +############################################################# + +SUBDIRMAKE = $(MAKE) -s -C +#SUBDIRMAKE = smakedir + +SDPATH = // + +CC = sc +CFLAGS = nostkchk nochkabort strmer dbg=f nover streq data=far \ + idlen=64 \ + define SCALOSLOCALE=$(SCALOS_LOCALE) \ + idir=///include \ + idir=///common/Plugin +AS = phxass +AFLAGS = quiet noexe m=68020 opt=NRQB i=sc:Assembler_Headers/ +LD = slink +LDFLAGS = quiet batch noicons sd +LDLIBS = LIB:mempools.lib LIB:scm.lib LIB:sc.lib LIB:debug.lib LIB:amiga.lib +ASTARTUP = +CSTARTUP = LIB:c.o +OBJDIR = .sasobj +CATCOMP = CatComp +FLEXCAT = FlexCat +PRECOMP = Include:all.gst +COMMON_DIR = ../../../common/Plugin + +############################################################# + +CSRCS = $(COMMON_DIR)/plugin-classic.c \ + DrawerContents.c + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +XSRCS = $(notdir $(CSRCS)) +OBJS = $(XSRCS:%.c=$(OBJDIR)/$(notdir %).o) + +############################################################# + +PLUGIN = drawercontents.plugin +SCALOS_LOCALE = $(OBJDIR)/DrawerContents_locale.h +CATCOMPHEADER = $(SCALOS_LOCALE) +CAT_FILE = Scalos/DrawerContentsPlugin.catalog +DESTTOOL = Scalos:plugins/FileTypes/ +DESTCAT = Locale:Catalogs +ALLCATS = Catalogs/deutsch/$(CAT_FILE) \ + Catalogs/français/$(CAT_FILE) + +############################################################# + +All: $(PLUGIN) \ + $(PLUGIN).debug \ + allcatalogs +# install +# clean + +############################################################# + +# commands generated a catalog (.catalog) from a catalog translation (.ct) file. +.ct.catalog: + $(CATCOMP) $*.cd $< CATALOG $*.catalog VB=1 + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-classic.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $*.c objectname $@ + +############################################################# + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-common.c \ + plugin_data.h DrawerContents_base.h $(COMMON_DIR)/plugin.h +$(OBJDIR)/DrawerContents.o : DrawerContents.h DrawerContents_base.h \ + $(SCALOS_LOCALE) + +############################################################# + +$(CATCOMPHEADER) : DrawerContentsPlugin.cd + @printf '\033[32mMake CatComp header: \033[31m\033[1m$@ \033[32mfrom \033[31m$<\033[0m\n' + $(FLEXCAT) $(subst ../,/,$<) $@=$(SDPATH)/CatComp_h.sd + +$(PLUGIN) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) to $@ FROM $(OBJS) lib $(LDLIBS) $(LDFLAGS) stripdebug + +$(PLUGIN).debug : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) to $@ FROM $(OBJS) lib $(LDLIBS) $(LDFLAGS) addsym + +############################################################# + +# A little something to clean it all up +clean: + @printf '\033[32mDelete: \033[31m\033[1m' + @delete $(OBJS) $(PLUGIN) $(PLUGIN).debug $(ALLCATS) $(CATCOMPHEADER) + @printf '\033[0m' + +############################################################# + +# copy all generated file to their final destinations +install: + @printf '\033[32mInstall: \033[31m\033[1m$(DESTTOOL)\033[0m\n' + @copy $(PLUGIN) $(DESTTOOL) clone + @printf '\033[32mFlushing memory\033[0m\n' + @avail flush + @printf '\033[32mInstall: \033[31m\033[1m$(CAT_FILE)\033[0m\n' + -@copy 'catalogs/deutsch/$(CAT_FILE)' '$(DESTCAT)/Deutsch/Scalos/' clone + -@copy 'catalogs/français/$(CAT_FILE)' '$(DESTCAT)/français/Scalos/' clone + +############################################################# + +# make all Scalos preferences .catalogs +allcatalogs: + @$(SUBDIRMAKE) Catalogs/deutsch/Scalos + @$(SUBDIRMAKE) Catalogs/français/Scalos +# @$(SUBDIRMAKE) Catalogs/sample/Scalos + diff --git a/scalos/Plugins/FileTypes/DrawerContents/makefile-new b/scalos/Plugins/FileTypes/DrawerContents/makefile-new new file mode 100755 index 000000000..11fce4009 --- /dev/null +++ b/scalos/Plugins/FileTypes/DrawerContents/makefile-new @@ -0,0 +1,98 @@ +# $Date: 2011-07-31 22:05:01 +0200 (So, 31. Jul 2011) $ +# $Revision: 813 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../../.. +endif + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + SDPATH=// +else + SDPATH=../../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(BEGIN_OBJS) \ + $(OBJDIR)/DrawerContents.o \ + $(END_OBJS) + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Targets +# + +NAME = drawercontents.plugin +NAME_DB = $(NAME).debug + +############################################################################## +# +# Subdirs +# + +SUBDIRS = $(filter-out Catalogs/sample/Scalos, $(wildcard Catalogs/*/Scalos)) +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) \ + all_subdirs + +############################################################################## + +$(OBJDIR)/%.o: $(FONTSAMPLE_DIR)/%.c + @$(run-cc) + +DrawerContents.c : $(SCALOS_LOCALE) + +$(SCALOS_LOCALE) : DrawerContentsPlugin.cd + @$(ECHO) "FlexCat $@" + $(FLEXCAT) $< $@=$(SDPATH)/CatComp_h.sd + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + @$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) Scalos:Plugins/FileTypes/ clone + @avail flush + +install: install_subdirs + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* \ + $(SCALOS_LOCALE) + +clean: clean_subdirs + +############################################################################## + + diff --git a/scalos/Plugins/FileTypes/DrawerContents/plugin_data.h b/scalos/Plugins/FileTypes/DrawerContents/plugin_data.h new file mode 100644 index 000000000..4c3311cb8 --- /dev/null +++ b/scalos/Plugins/FileTypes/DrawerContents/plugin_data.h @@ -0,0 +1,34 @@ +// plugin_data.h +// $Date$ +// $Revision$ + +#ifndef PLUGIN_DATA_H_INCLUDED +#define PLUGIN_DATA_H_INCLUDED + +#include +#include + +#define PLUGIN_TYPE FILETYPE + +#define LIB_BASETYPE struct DrawerContentsBase + +#define LIB_VERSION 40 +#define LIB_REVISION 7 + +#define LIB_NAME "drawercontents.plugin" +#define LIB_VERSTRING "$VER: drawercontents.plugin " \ + STR(LIB_VERSION) "." STR(LIB_REVISION) " (30.09.2005)" \ + COMPILER_STRING " ©2003" CURRENTYEAR \ + " The Scalos Team" + + +#define FT_INFOSTRING LIBToolTipInfoString +#define FT_INFOSTRING_AROS PluginBase_0_LIBToolTipInfoString + +//---------------------------------------------------------------------------- +// code and includes to define the structs and functions used above + +#include "DrawerContents_base.h" + +#endif /* PLUGUN_DATA_H_INCLUDED */ + diff --git a/scalos/Plugins/FileTypes/ExifPicture/Catalogs/deutsch/Scalos/ExifPicturePlugin.ct b/scalos/Plugins/FileTypes/ExifPicture/Catalogs/deutsch/Scalos/ExifPicturePlugin.ct new file mode 100644 index 000000000..d99cb6201 --- /dev/null +++ b/scalos/Plugins/FileTypes/ExifPicture/Catalogs/deutsch/Scalos/ExifPicturePlugin.ct @@ -0,0 +1,249 @@ +; ExifPicturePlugin.ct +; Date: $ +; Revision: $ +## version $VER: ExifPicturePlugin.catalog 40.0 (17.09.05) +## codeset 0 +## language deutsch +; +;#arrayopts static __far +; +; +MSGID_ERROR_NOJPEG +Fehler: Datei %s ist kein JPEG Bild!. +;Error, file: %s isn't a JPEG picture. +; +MSGID_PICTURE_FILESIZE +Dateigröße : %lD Bytes\n +;File size: %lD bytes\n +; +MSGID_PICTURE_FILEDATE +Datei-Datum : %s\n +;File date: %s\n +; +MSGID_CAMERA_MAKE_MODEL +Kamera-Hersteller : %s\n\ +Kamera-Modell : %s\n +;Camera make: %s\n\ +;Camera model: %s\n +; +MSGID_DATE_TIME +Aufnahmedatum : %s\n +;Date/Time: %s\n +; +MSGID_PICTURE_RESOLUTION +Auflösung : %d x %d\n +;Resolution: %d x %d\n +; +MSGID_ORIENTATION +Orientierung : %s\n +;Orientation: %s\n +; +MSGID_ISCOLOR +Farbe oder s/w : schwarzweiß\n +;Color/bw: Black and white\n +; +MSGID_FLASHUSED +Blitz benutzt : %s\n +;Flash used: %s\n +; +MSGID_NO +Nein +;No +; +MSGID_YES +Ja +;Yes +; +MSGID_FOCAL_LENGTH +Brennweite : %4.1fmm +;Focal length: %4.1fmm +; +MSGID_FOCAL_LENGTH_CDDWIDTH + (entspricht 35mm : %dmm) +; (35mm equivalent: %dmm) +; +MSGID_CDDWIDTH +Größe des CCD : %4.2fmm\n +;CCD width: %4.2fmm\n +; +MSGID_EXPOSURETIME64 +Belichtungszeit : %6.4f s +;Exposure time: %6.4f s +; +MSGID_EXPOSURETIME53 +Belichtungszeit : %5.3f s +;Exposure time: %5.3f s +; +MSGID_APERTUREFNUMBER +Blende : f/%3.1f\n +;Aperture: f/%3.1f\n +; +MSGID_DISTANCE_INFINITE +Fokus-Entfernung : unendlich\n +;Focus dist.: Infinite\n +; +MSGID_DISTANCE +Fokus-Entfernung : %4.2fm\n +;Focus dist.: %4.2fm\n +; +MSGID_ISOEQUIVALENT +ISO Empfindlichkeit : %2d\n +;ISO equiv.: %2d\n +; +MSGID_EXPOSUREBIAS +Belichtungskorrektur :%4.2f\n +;Exposure bias: %4.2f\n +; +MSGID_WHITEBALANCE1 +Weißabgleich : Sonne\n +;Whitebalance: sunny\n +; +MSGID_WHITEBALANCE2 +Weißabgleich : Leuchtstoffröhre\n +;Whitebalance: fluorescent\n +; +MSGID_WHITEBALANCE3 +Weißabgleich :Glühlampe\n +;Whitebalance: incandescent\n +; +MSGID_WHITEBALANCE4 +Weißabgleich : bewölkter Himmel\n +;Whitebalance: cloudy\n +; +MSGID_METERINGMODE_CENTER +Belichtungsmessung : mittenbetont\n +;Metering Mode: center weight\n +; +MSGID_METERINGMODE_SPOT +Belichtungsmessung : spot\n +;Metering Mode: spot\n +; +MSGID_METERINGMODE_MATRIX +Belichtungsmessung : Matrix\n +;Metering Mode: matrix\n +; +MSGID_EXPOSURE_PROGRAM1 +Belichtung : Programmautomatik\n +;Exposure : program (auto)\n +; +MSGID_EXPOSURE_PROGRAM2 +Belichtung : Blendenautomatik\n +;Exposure: aperture priority (semi-auto)\n +; +MSGID_EXPOSURE_PROGRAM3 +Belichtung : Zeitautomatik\n +;Exposure: shutter priority (semi-auto)\n +; +MSGID_JPEG_PROCESS +JPEG Typ : %s\n +;Jpeg process: %s\n +; +MSGID_COMMENT +Kommentar : +;Comment: +; +;-------------------- ProcessTable -------------------------------------------- +; +MSGID_BASELINE +Standard +;Baseline +; +MSGID_EXTENDED_SEQUENTIAL +Erweitert sequentiell +;Extended sequential +; +MSGID_PROGRESSIVE +Progressiv +;Progressive +; +MSGID_LOSSLESS +Verlustfrei +;Lossless +; +MSGID_DIFFERENTIAL_SEQUENTIAL +Differentiell sequentiell +;Differential sequential +; +MSGID_DIFFERENTIAL_PROGRESSIVE +Differentiell progressiv +;Differential progressive +; +MSGID_DIFFERENTIAL_LOSSLESS +Differentiell verlustfrei +;Differential lossless +; +MSGID_EXTENDED_SEQUENTIAL_ARITHMETIC_CODING +Erweitert sequentiell, arithmetische Kodierung +;Extended sequential, arithmetic coding +; +MSGID_PROGRESSIVE_ARITHMETIC_CODING +Progressiv, arithmetische Kodierung +;Progressive, arithmetic coding +; +MSGID_LOSSLESS_ARITHMETIC_CODING +Verlustfrei, arithmetische Kodierung +;Lossless, arithmetic coding +; +MSGID_DIFFERENTIAL_SEQUENTIAL_ARITHMETIC_CODING +Differentiell sequentiell, arithmetische Kodierung +;Differential sequential, arithmetic coding +; +MSGID_DIFFERENTIAL_PROGRESSIVE_ARITHMETIC_CODING +Differentiell progressiv, arithmetische Kodierung +;Differential progressive, arithmetic coding +; +MSGID_DIFFERENTIAL_LOSSLESS_ARITHMETIC_CODING +Differentiell verlustfrei, arithmetische Kodierung +;Differential lossless, arithmetic coding +; +MSGID_UNKNOWN +Unbekannt +;Unknown +; +;------------------------------------------------------------------------------ +; +MSGID_ERROR_DOS +Fehler: %ld, %s. +; Error: %ld, %s. +; +;---------------------------- OrientTab --------------------------------------- +; +MSGID_ORIENTTAB_UNDEFINED +Undefiniert +; Undefined +; +MSGID_ORIENTTAB_NORMAL +Normal +; Normal +; +MSGID_ORIENTTAB_FLIP_HORIZONTAL +Horizontal gespiegelt +; flip horizontal +; +MSGID_ORIENTTAB_ROTATE_180 +180° drehen +; rotate 180 +; +MSGID_ORIENTTAB_FLIP_VERTICAL +Vertikal gespiegelt +; flip vertical +; +MSGID_ORIENTTAB_TRANSPOSE +Transponiert +; transpose +; +MSGID_ORIENTTAB_ROTATE_90 +90° gedreht +; rotate 90 +; +; +MSGID_ORIENTTAB_TRANSVERSE +quer +; transverse +; +MSGID_ORIENTTAB_ROTATE_270 +270° gedreht +; rotate 270 +; +;------------------------------------------------------------------------------ +; diff --git a/scalos/Plugins/FileTypes/ExifPicture/Catalogs/deutsch/Scalos/config.mk b/scalos/Plugins/FileTypes/ExifPicture/Catalogs/deutsch/Scalos/config.mk new file mode 100755 index 000000000..b60748fa3 --- /dev/null +++ b/scalos/Plugins/FileTypes/ExifPicture/Catalogs/deutsch/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = deutsch + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = german + +else + +############################################################################### +# AmigaOS and AROS + +LANG = deutsch + +endif +endif diff --git a/scalos/Plugins/FileTypes/ExifPicture/Catalogs/deutsch/Scalos/makefile b/scalos/Plugins/FileTypes/ExifPicture/Catalogs/deutsch/Scalos/makefile new file mode 100755 index 000000000..072fec17b --- /dev/null +++ b/scalos/Plugins/FileTypes/ExifPicture/Catalogs/deutsch/Scalos/makefile @@ -0,0 +1,13 @@ +# makefile for ExifPicturePlugin (translated Texts : deutsch) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mdeutsch\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +ExifPicturePlugin.catalog : ExifPicturePlugin.ct ../../../ExifPicturePlugin.cd + +All: ExifPicturePlugin.catalog diff --git a/scalos/Plugins/FileTypes/ExifPicture/Catalogs/deutsch/Scalos/makefile-new b/scalos/Plugins/FileTypes/ExifPicture/Catalogs/deutsch/Scalos/makefile-new new file mode 100755 index 000000000..8c1e5057c --- /dev/null +++ b/scalos/Plugins/FileTypes/ExifPicture/Catalogs/deutsch/Scalos/makefile-new @@ -0,0 +1,32 @@ +# makefile for ExifPicturePlugin (translated Texts : deutsch) +# $Date: 2011-07-31 22:05:01 +0200 (So, 31. Jul 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = ExifPicturePlugin + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git "a/scalos/Plugins/FileTypes/ExifPicture/Catalogs/fran\303\247ais/Scalos/ExifPicturePlugin.ct" "b/scalos/Plugins/FileTypes/ExifPicture/Catalogs/fran\303\247ais/Scalos/ExifPicturePlugin.ct" new file mode 100755 index 000000000..e66986e67 --- /dev/null +++ "b/scalos/Plugins/FileTypes/ExifPicture/Catalogs/fran\303\247ais/Scalos/ExifPicturePlugin.ct" @@ -0,0 +1,248 @@ +; ExifPicturePlugin.ct +; $Date$ +; $Revision$ +## version $VER: ExifPicturePlugin.catalog 40.0 (17.09.05) +## codeset 0 +## language français +; +;#arrayopts static __far +; +; +MSGID_ERROR_NOJPEG +Le fichier : %s n'est pas une image JPEG +;Error, file: %s isn't a JPEG picture. +; +MSGID_PICTURE_FILESIZE +Taille du fchier : %lD octets\n +;File size: %lD bytes\n +; +MSGID_PICTURE_FILEDATE +Date du fchier : %s\n +;File date: %s\n +; +MSGID_CAMERA_MAKE_MODEL +Fabricant : %s\n\ +Modèle : %s\n +;Camera make: %s\n\ +;Camera model: %s\n +; +MSGID_DATE_TIME +Date/Heure : %s\n +;Date/Time: %s\n +; +MSGID_PICTURE_RESOLUTION +Dimensions : %d x %d\n +;Resolution: %d x %d\n +; +MSGID_ORIENTATION +Orientation : %s\n +;Orientation: %s\n +; +MSGID_ISCOLOR +Couleur/Noir et Blanc : Noir et Blanc\n +;Color/bw: Black and white\n +; +MSGID_FLASHUSED +Flash utilisé : %s\n +;Flash used: %s\n +; +MSGID_NO +Non +;No +; +MSGID_YES +Oui +;Yes +; +MSGID_FOCAL_LENGTH +Longueur Focale : %4.1fmm +;Focal length: %4.1fmm +; +MSGID_FOCAL_LENGTH_CDDWIDTH + (35mm équivalent: %dmm) +; (35mm equivalent: %dmm) +; +MSGID_CDDWIDTH +Capteur DTC (CCD) : %4.2fmm\n +;CCD width: %4.2fmm\n +; +MSGID_EXPOSURETIME64 +Temps d'exposition : %6.4f s +;Exposure time: %6.4f s +; +MSGID_EXPOSURETIME53 +Temps d'exposition : %5.3f s +;Exposure time: %5.3f s +; +MSGID_APERTUREFNUMBER +Ouverture : f/%3.1f\n +;Aperture: f/%3.1f\n +; +MSGID_DISTANCE_INFINITE +Mise au point dist. : Infini\n +;Focus dist.: Infinite\n +; +MSGID_DISTANCE +Mise au point dist. : %4.2fm\n +;Focus dist.: %4.2fm\n +; +MSGID_ISOEQUIVALENT +Réglage ISO : %2d\n +;ISO equiv.: %2d\n +; +MSGID_EXPOSUREBIAS +Compensation de l'exposition : %4.2f\n +;Exposure bias: %4.2f\n +; +MSGID_WHITEBALANCE1 +Equilibre des blancs : sunny\n +;Whitebalance: sunny\n +; +MSGID_WHITEBALANCE2 +Equilibre des blancs : Fluorescence\n +;Whitebalance: fluorescent\n +; +MSGID_WHITEBALANCE3 +Equilibre des blancs : Incandescense\n +;Whitebalance: incandescent\n +; +MSGID_WHITEBALANCE4 +Equilibre des blancs : Nuageux\n +;Whitebalance: cloudy\n +; +MSGID_METERINGMODE_CENTER +Méthode d'exposition : Moyenne pondérée au centre\n +;Metering Mode: center weight\n +; +MSGID_METERINGMODE_SPOT +Méthode d'exposition : Spot\n +;Metering Mode: spot\n +; +MSGID_METERINGMODE_MATRIX +Méthode d'exposition : Matrice\n +;Metering Mode: matrix\n +; +MSGID_EXPOSURE_PROGRAM1 +Programme d'exposition : Programme (auto)\n +;Exposure: program (auto)\n +; +MSGID_EXPOSURE_PROGRAM2 +Programme d'exposition : Priorité à l'ouverture (semi-auto)\n +;Exposure: aperture priority (semi-auto)\n +; +MSGID_EXPOSURE_PROGRAM3 +Programme d'exposition : Priorité à la vitesse d'obturation (semi-auto)\n +;Exposure: shutter priority (semi-auto)\n +; +MSGID_JPEG_PROCESS +Type de JPEG : %s\n +;Jpeg process: %s\n +; +MSGID_COMMENT +Commentaire : +;Comment: +; +;-------------------- ProcessTable -------------------------------------------- +; +MSGID_BASELINE +Normal +;Baseline +; +MSGID_EXTENDED_SEQUENTIAL +Extendu sequentiel +;Extended sequential +; +MSGID_PROGRESSIVE +Progressif +;Progressive +; +MSGID_LOSSLESS +Sans perte +;Lossless +; +MSGID_DIFFERENTIAL_SEQUENTIAL +Différentiel sequentiel +;Differential sequential +; +MSGID_DIFFERENTIAL_PROGRESSIVE +Différentiel progressif +;Differential progressive +; +MSGID_DIFFERENTIAL_LOSSLESS +Différentiel sans perte +;Differential lossless +; +MSGID_EXTENDED_SEQUENTIAL_ARITHMETIC_CODING +Extendu sequentiel, codage arithmétique +;Extended sequential, arithmetic coding +; +MSGID_PROGRESSIVE_ARITHMETIC_CODING +Progressif, codage arithmétique +;Progressive, arithmetic coding +; +MSGID_LOSSLESS_ARITHMETIC_CODING +Sans perte, codage arithmètique +;Lossless, arithmetic coding +; +MSGID_DIFFERENTIAL_SEQUENTIAL_ARITHMETIC_CODING +Différentiel sequentiel, codage arithmétique +;Differential sequential, arithmetic coding +; +MSGID_DIFFERENTIAL_PROGRESSIVE_ARITHMETIC_CODING +Différentiel progressif, codage arithmétique +;Differential progressive, arithmetic coding +; +MSGID_DIFFERENTIAL_LOSSLESS_ARITHMETIC_CODING +Différentiel sans perte, codage arithmétique +;Differential lossless, arithmetic coding +; +MSGID_UNKNOWN +Inconnu +;Unknown +; +;------------------------------------------------------------------------------ +; +MSGID_ERROR_DOS +Erreur : %ld, %s. +; Error: %ld, %s. +; +;---------------------------- OrientTab --------------------------------------- +; +MSGID_ORIENTTAB_UNDEFINED +Indéfini +; Undefined +; +MSGID_ORIENTTAB_NORMAL +Normal +; Normal +; +MSGID_ORIENTTAB_FLIP_HORIZONTAL +Inversé horizontalement +; flip horizontal +; +MSGID_ORIENTTAB_ROTATE_180 +Rotation 180° +; rotate 180 +; +MSGID_ORIENTTAB_FLIP_VERTICAL +Inversé verticalement +; flip vertical +; +MSGID_ORIENTTAB_TRANSPOSE +Transposition +; transpose +; +MSGID_ORIENTTAB_ROTATE_90 +Rotation 90° +; rotate 90 +; +MSGID_ORIENTTAB_TRANSVERSE +Transversalle +; transverse +; +MSGID_ORIENTTAB_ROTATE_270 +Rotation 270° +; rotate 270 +; +;------------------------------------------------------------------------------ +; diff --git "a/scalos/Plugins/FileTypes/ExifPicture/Catalogs/fran\303\247ais/Scalos/config.mk" "b/scalos/Plugins/FileTypes/ExifPicture/Catalogs/fran\303\247ais/Scalos/config.mk" new file mode 100755 index 000000000..1b4cabf68 --- /dev/null +++ "b/scalos/Plugins/FileTypes/ExifPicture/Catalogs/fran\303\247ais/Scalos/config.mk" @@ -0,0 +1,40 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = français + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = french + +else + +############################################################################### +# AmigaOS and AROS + +LANG = français + +endif +endif diff --git "a/scalos/Plugins/FileTypes/ExifPicture/Catalogs/fran\303\247ais/Scalos/makefile" "b/scalos/Plugins/FileTypes/ExifPicture/Catalogs/fran\303\247ais/Scalos/makefile" new file mode 100755 index 000000000..bf96b2015 --- /dev/null +++ "b/scalos/Plugins/FileTypes/ExifPicture/Catalogs/fran\303\247ais/Scalos/makefile" @@ -0,0 +1,14 @@ +# makefile for ExifPicturePlugin (translated Texts : français) +# $Date$ +# $Revision$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mfrançais\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +ExifPicturePlugin.catalog : ExifPicturePlugin.ct ../../../ExifPicturePlugin.cd + +All: ExifPicturePlugin.catalog diff --git "a/scalos/Plugins/FileTypes/ExifPicture/Catalogs/fran\303\247ais/Scalos/makefile-new" "b/scalos/Plugins/FileTypes/ExifPicture/Catalogs/fran\303\247ais/Scalos/makefile-new" new file mode 100755 index 000000000..1ef6b00eb --- /dev/null +++ "b/scalos/Plugins/FileTypes/ExifPicture/Catalogs/fran\303\247ais/Scalos/makefile-new" @@ -0,0 +1,32 @@ +# makefile for ExifPicturePlugin (translated Texts : français) +# $Date: 2011-07-31 22:05:01 +0200 (So, 31. Jul 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = ExifPicturePlugin + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Plugins/FileTypes/ExifPicture/Catalogs/sample/Scalos/ExifPicturePlugin.ct b/scalos/Plugins/FileTypes/ExifPicture/Catalogs/sample/Scalos/ExifPicturePlugin.ct new file mode 100755 index 000000000..d4f59a85f --- /dev/null +++ b/scalos/Plugins/FileTypes/ExifPicture/Catalogs/sample/Scalos/ExifPicturePlugin.ct @@ -0,0 +1,248 @@ +; ExifPicturePlugin.ct +; $Date$ +; $Revision$ +## version $VER: ExifPicturePlugin.catalog 40.0 (30.08.05) +## codeset 0s +## language english +; +;#arrayopts static __far +; +; +MSGID_ERROR_NOJPEG +Error, file: %s isn't a JPEG picture. +; Error, file: %s isn't a JPEG picture. +; +MSGID_PICTURE_FILESIZE + File size: %lD bytes\n +; File size: %lD bytes\n +; +MSGID_PICTURE_FILEDATE +File date: %s\n +; File date: %s\n +; +MSGID_CAMERA_MAKE_MODEL +Camera make: %s\n\ +Camera model: %s\n +; Camera make: %s\n\ +; Camera model: %s\n +; +MSGID_DATE_TIME +Date/Time: %s\n +; Date/Time: %s\n +; +MSGID_PICTURE_RESOLUTION +Resolution: %d x %d\n +; Resolution: %d x %d\n +; +MSGID_ORIENTATION +Orientation: %s\n +; Orientation: %s\n +; +MSGID_ISCOLOR +Color/bw: Black and white\n +; Color/bw: Black and white\n +; +MSGID_FLASHUSED +Flash used: %s\n +; Flash used: %s\n +; +MSGID_NO +No +; No +; +MSGID_YES +Yes +; Yes +; +MSGID_FOCAL_LENGTH +Focal length: %4.1fmm +; Focal length: %4.1fmm +; +MSGID_FOCAL_LENGTH_CDDWIDTH + (35mm equivalent: %dmm) +; (35mm equivalent: %dmm) +; +MSGID_CDDWIDTH +CCD width: %4.2fmm\n +; CCD width: %4.2fmm\n +; +MSGID_EXPOSURETIME64 +Exposure time: %6.4f s +; Exposure time: %6.4f s +; +MSGID_EXPOSURETIME53 +Exposure time: %5.3f s +; Exposure time: %5.3f s +; +MSGID_APERTUREFNUMBER +Aperture: f/%3.1f\n +; Aperture: f/%3.1f\n +; +MSGID_DISTANCE_INFINITE +Focus dist.: Infinite\n +; Focus dist.: Infinite\n +; +MSGID_DISTANCE +Focus dist.: %4.2fm\n +; Focus dist.: %4.2fm\n +; +MSGID_ISOEQUIVALENT +ISO equiv.: %2d\n +; ISO equiv.: %2d\n +; +MSGID_EXPOSUREBIAS +Exposure bias: %4.2f\n +; Exposure bias: %4.2f\n +; +MSGID_WHITEBALANCE1 +Whitebalance: sunny\n +; Whitebalance: sunny\n +; +MSGID_WHITEBALANCE2 +Whitebalance: fluorescent\n +; Whitebalance: fluorescent\n +; +MSGID_WHITEBALANCE3 +Whitebalance: incandescent\n +; Whitebalance: incandescent\n +; +MSGID_WHITEBALANCE4 +Whitebalance: cloudy\n +; Whitebalance: cloudy\n +; +MSGID_METERINGMODE_CENTER +Metering Mode: center weight\n +; Metering Mode: center weight\n +; +MSGID_METERINGMODE_SPOT +Metering Mode: spot\n +; Metering Mode: spot\n +; +MSGID_METERINGMODE_MATRIX +Metering Mode: matrix\n +; Metering Mode: matrix\n +; +MSGID_EXPOSURE_PROGRAM1 +Exposure: program (auto)\n +; Exposure: program (auto)\n +; +MSGID_EXPOSURE_PROGRAM2 +Exposure: aperture priority (semi-auto)\n +; Exposure: aperture priority (semi-auto)\n +; +MSGID_EXPOSURE_PROGRAM3 +Exposure: shutter priority (semi-auto)\n +; Exposure: shutter priority (semi-auto)\n +; +MSGID_JPEG_PROCESS +Jpeg process: %s\n +; Jpeg process: %s\n +; +MSGID_COMMENT +Comment: +; Comment: +; +;-------------------- ProcessTable -------------------------------------------- +; +MSGID_BASELINE +Baseline +;Baseline +; +MSGID_EXTENDED_SEQUENTIAL +Extended sequential +;Extended sequential +; +MSGID_PROGRESSIVE +Progressive +;Progressive +; +MSGID_LOSSLESS +Lossless +;Lossless +; +MSGID_DIFFERENTIAL_SEQUENTIAL +Differential sequential +;Differential sequential +; +MSGID_DIFFERENTIAL_PROGRESSIVE +Differential progressive +;Differential progressive +; +MSGID_DIFFERENTIAL_LOSSLESS +Differential lossless +;Differential lossless +; +MSGID_EXTENDED_SEQUENTIAL_ARITHMETIC_CODING +Extended sequential, arithmetic coding +;Extended sequential, arithmetic coding +; +MSGID_PROGRESSIVE_ARITHMETIC_CODING +Progressive, arithmetic coding +;Progressive, arithmetic coding +; +MSGID_LOSSLESS_ARITHMETIC_CODING +Lossless, arithmetic coding +;Lossless, arithmetic coding +; +MSGID_DIFFERENTIAL_SEQUENTIAL_ARITHMETIC_CODING +Differential sequential, arithmetic coding +;Differential sequential, arithmetic coding +; +MSGID_DIFFERENTIAL_PROGRESSIVE_ARITHMETIC_CODING +Differential progressive, arithmetic coding +;Differential progressive, arithmetic coding +; +MSGID_DIFFERENTIAL_LOSSLESS_ARITHMETIC_CODING +Differential lossless, arithmetic coding +;Differential lossless, arithmetic coding +; +MSGID_UNKNOWN +Unknown +;Unknown +; +;------------------------------------------------------------------------------ +; +MSGID_ERROR_DOS +Error: %ld, %s. +; Error: %ld, %s. +; +;---------------------------- OrientTab --------------------------------------- +; +MSGID_ORIENTTAB_UNDEFINED +Undefined +; Undefined +; +MSGID_ORIENTTAB_NORMAL +Normal +; Normal +; +MSGID_ORIENTTAB_FLIP_HORIZONTAL +flip horizontal +; flip horizontal +; +MSGID_ORIENTTAB_ROTATE_180 +rotate 180 +; rotate 180 +; +MSGID_ORIENTTAB_FLIP_VERTICAL +flip vertical +; flip vertical +; +MSGID_ORIENTTAB_TRANSPOSE +transpose +; transpose +; +MSGID_ORIENTTAB_ROTATE_90 +rotate 90 +; rotate 90 +; +MSGID_ORIENTTAB_TRANSVERSE +transverse +; transverse +; +MSGID_ORIENTTAB_ROTATE_270 +rotate 270 +; rotate 270 +; +;------------------------------------------------------------------------------ +; diff --git a/scalos/Plugins/FileTypes/ExifPicture/ExPicDefs.h b/scalos/Plugins/FileTypes/ExifPicture/ExPicDefs.h new file mode 100755 index 000000000..7731184bd --- /dev/null +++ b/scalos/Plugins/FileTypes/ExifPicture/ExPicDefs.h @@ -0,0 +1,97 @@ +// ExPicDefs.h +// Include file for jhead program. +// +// This include file only defines stuff that goes across modules. +// I like to keep the definitions for macros and structures as close to +// where they get used as possible, so include files only get stuff that +// gets used in more than one file. +//-------------------------------------------------------------------------- + +#ifndef EXPICDEFS_H +#define EXPICDEFS_H + +typedef unsigned char uchar; + +#ifndef TRUE + #define TRUE 1 + #define FALSE 0 +#endif + +#define MAX_COMMENT 2000 + +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + +// prototypes for error messages +void ErrFatal(char * msg); +void ErrNonfatal(char * msg, int a1, int a2); + +//-------------------------------------------------------------------------- +// JPEG markers consist of one or more 0xFF bytes, followed by a marker +// code byte (which is not an FF). Here are the marker codes of interest +// in this program. (See jdmarker.c for a more complete list.) +//-------------------------------------------------------------------------- + +#define M_SOF0 0xC0 // Start Of Frame N +#define M_SOF1 0xC1 // N indicates which compression process +#define M_SOF2 0xC2 // Only SOF0-SOF2 are now in common use +#define M_SOF3 0xC3 +#define M_SOF5 0xC5 // NB: codes C4 and CC are NOT SOF markers +#define M_SOF6 0xC6 +#define M_SOF7 0xC7 +#define M_SOF9 0xC9 +#define M_SOF10 0xCA +#define M_SOF11 0xCB +#define M_SOF13 0xCD +#define M_SOF14 0xCE +#define M_SOF15 0xCF +#define M_SOI 0xD8 // Start Of Image (beginning of datastream) +#define M_EOI 0xD9 // End Of Image (end of datastream) +#define M_SOS 0xDA // Start Of Scan (begins compressed data) +#define M_JFIF 0xE0 // Jfif marker +#define M_EXIF 0xE1 // Exif marker +#define M_COM 0xFE // COMment + + +//-------------------------------------------------------------------------- +// Describes tag values + +#define TAG_EXIF_OFFSET 0x8769 +#define TAG_INTEROP_OFFSET 0xa005 + +#define TAG_MAKE 0x010F +#define TAG_MODEL 0x0110 + +#define TAG_ORIENTATION 0x0112 + +#define TAG_EXPOSURETIME 0x829A +#define TAG_FNUMBER 0x829D + +#define TAG_SHUTTERSPEED 0x9201 +#define TAG_APERTURE 0x9202 +#define TAG_MAXAPERTURE 0x9205 +#define TAG_FOCALLENGTH 0x920A + +#define TAG_DATETIME_ORIGINAL 0x9003 +#define TAG_USERCOMMENT 0x9286 + +#define TAG_SUBJECT_DISTANCE 0x9206 +#define TAG_FLASH 0x9209 + +#define TAG_FOCALPLANEXRES 0xa20E +#define TAG_FOCALPLANEUNITS 0xa210 +#define TAG_EXIF_IMAGEWIDTH 0xA002 +#define TAG_EXIF_IMAGELENGTH 0xA003 + +// the following is added 05-jan-2001 vcs +#define TAG_EXPOSURE_BIAS 0x9204 +#define TAG_WHITEBALANCE 0x9208 +#define TAG_METERING_MODE 0x9207 +#define TAG_EXPOSURE_PROGRAM 0x8822 +#define TAG_ISO_EQUIVALENT 0x8827 + +#define TAG_THUMBNAIL_OFFSET 0x0201 +#define TAG_THUMBNAIL_LENGTH 0x0202 +#endif /* EXPICDEFS_H */ + diff --git a/scalos/Plugins/FileTypes/ExifPicture/ExifPicture.c b/scalos/Plugins/FileTypes/ExifPicture/ExifPicture.c new file mode 100755 index 000000000..1abd0b0af --- /dev/null +++ b/scalos/Plugins/FileTypes/ExifPicture/ExifPicture.c @@ -0,0 +1,2617 @@ +// ExifPicture.c +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include + +#include "plugin.h" + +#include "ExPicDefs.h" + +#include "ExifPicture_base.h" +#include "ExifPicture.h" +#define ExifPicturePlugin_NUMBERS +#define ExifPicturePlugin_ARRAY +#define ExifPicturePlugin_CODE +#include STR(SCALOSLOCALE) + +//--------------------------------------------------------------- + +#define NOT_A_LOCK ((BPTR) ~0) +#define IS_VALID_LOCK(x) ((x) != NOT_A_LOCK) + +//--------------------------------------------------------------- + +#define MEMPOOL_MEMFLAGS MEMF_ANY +#define MEMPOOL_PUDDLESIZE 4096 +#define MEMPOOL_THRESHSIZE 2048 + +//--------------------------------------------------------------- + +// Describes format descriptor + +#define NUM_FORMATS 12 + +#define FMT_BYTE 1 +#define FMT_STRING 2 +#define FMT_USHORT 3 +#define FMT_ULONG 4 +#define FMT_URATIONAL 5 +#define FMT_SBYTE 6 +#define FMT_UNDEFINED 7 +#define FMT_SSHORT 8 +#define FMT_SLONG 9 +#define FMT_SRATIONAL 10 +#define FMT_SINGLE 11 +#define FMT_DOUBLE 12 + +#define MAX_SECTIONS 20 +#define PSEUDO_IMAGE_MARKER 0x123; // Extra value. + +//--- Global buffer --- +typedef struct { + char Buffer[MAX_COMMENT*4]; +}Ttype; + + +//--- Readmodes --- +typedef enum { + READ_EXIF = 1, + READ_IMAGE = 2, + READ_ALL = 3 +}ReadMode_t; + +//---- Sections --- +typedef struct { + uchar * Data; + int Type; + unsigned Size; +}Section_t; + +//---- Image informations ---- +typedef struct { + char FileName[PATH_MAX+1]; + time_t FileDateTime; + unsigned FileSize; + char CameraMake[32]; + char CameraModel[40]; + char DateTime[20]; + int Height, Width; + int Orientation; + int IsColor; + int Process; + int FlashUsed; + float FocalLength; + float ExposureTime; + float ApertureFNumber; + float Distance; + float CCDWidth; + float ExposureBias; + int Whitebalance; + int MeteringMode; + int ExposureProgram; + int ISOequivalent; + char Comments[MAX_COMMENT]; + + unsigned char * ThumbnailPointer; // Pointer at the thumbnail + unsigned ThumbnailSize; // Size of thumbnail. + + char * DatePointer; +}ImageInfo_t; + +//---------------------- + +typedef struct { + unsigned short Tag; + char * Desc; +}TagTable_t; + + +//---------- Exif section -------------------------------- + +static unsigned char * LastExifRefd; +static unsigned char * DirWithThumbnailPtrs; +static double FocalplaneXRes; +static double FocalplaneUnits; +static int ExifImageWidth; +static int MotorolaOrder = 0; + +// for fixing the rotation. +static void * OrientationPtr; +static int OrientationNumFormat; +static int CheckFileSkip(void); +static BOOL ResultJPEG = TRUE; + +//static char * Processtable_Baseline; + +//--- Table of Jpeg encoding process names ------------------ + +static char LocBaseline[20]=""; +static char LocExtendedSeq[50]=""; +static char LocProgressive[30]=""; +static char LocLossless[20]=""; +static char LocDiffSeq[50]=""; +static char LocDiffProgressive[50]=""; +static char LocDiffLossless[50]=""; +static char LocExtendedSeqAritCoding[100]=""; +static char LocProgressiveAritCoding[100]=""; +static char LocLosslessAritCoding[100]=""; +static char LocDiffSeqAritCoding[100]=""; +static char LocDiffProgressiveAritCoding[100]=""; +static char LocDiffLosslessAritCoding[100]=""; +static char LocUnknown[20]=""; + +static TagTable_t ProcessTable[] = { + { M_SOF0, LocBaseline }, // "Baseline" + { M_SOF1, LocExtendedSeq }, // "Extended sequential" + { M_SOF2, LocProgressive }, // "Progressive" + { M_SOF3, LocLossless }, // "Lossless" + { M_SOF5, LocDiffSeq }, // "Differential sequential" + { M_SOF6, LocDiffProgressive }, // "Differential progressive" + { M_SOF7, LocDiffLossless }, // "Differential lossless" + { M_SOF9, LocExtendedSeqAritCoding }, // "Extended sequential, arithmetic coding", + { M_SOF10, LocProgressiveAritCoding }, // "Progressive, arithmetic coding" + { M_SOF11, LocLosslessAritCoding }, // "Lossless, arithmetic coding" + { M_SOF13, LocDiffSeqAritCoding }, // "Differential sequential, arithmetic coding" + { M_SOF14, LocDiffProgressiveAritCoding }, // "Differential progressive, arithmetic coding, + { M_SOF15, LocDiffLosslessAritCoding }, // "Differential lossless, arithmetic coding", + { 0, LocUnknown} +}; + +// 1 - "The 0th row is at the visual top of the image, and the 0th column is the visual left-hand side." +// 2 - "The 0th row is at the visual top of the image, and the 0th column is the visual right-hand side." +// 3 - "The 0th row is at the visual bottom of the image, and the 0th column is the visual right-hand side." +// 4 - "The 0th row is at the visual bottom of the image, and the 0th column is the visual left-hand side." +// 5 - "The 0th row is the visual left-hand side of of the image, and the 0th column is the visual top." +// 6 - "The 0th row is the visual right-hand side of of the image, and the 0th column is the visual top." +// 7 - "The 0th row is the visual right-hand side of of the image, and the 0th column is the visual bottom." +// 8 - "The 0th row is the visual left-hand side of of the image, and the 0th column is the visual bottom." + +// Note: The descriptions here are the same as the name of the command line +// option to pass to jpegtran to right the image + +static char LocOrientUndef[50]=""; +static char LocOrientNormal[50]=""; +static char LocOrientFlipHor[80]=""; +static char LocOrientRot180[80]=""; +static char LocOrientFlipVert[80]=""; +static char LocOrientTranspose[80]=""; +static char LocOrientRot90[80]=""; +static char LocOrientTransverse[80]=""; +static char LocOrientRot270[80]=""; + +static const char * OrientTab[9] = { + LocOrientUndef, // "Undefined" + LocOrientNormal, // "Normal" - 1 + LocOrientFlipHor, // "flip horizontal" - left right reversed mirror + LocOrientRot180, // "rotate 180" - 3 + LocOrientFlipVert, // "flip vertical" - upside down mirror + LocOrientTranspose, // "transpose" - Flipped about top-left <--> bottom-right axis. + LocOrientRot90, // "rotate 90" - rotate 90 cw to right it. + LocOrientTransverse, // "transverse" - flipped about top-right <--> bottom-left axis + LocOrientRot270, // "rotate 270" - rotate 270 to right it. +}; + + +//--- Prototypes from jpg files ------------------------------------------- + +Section_t * FindSection(int SectionType); +Section_t * CreateSection(int SectionType, unsigned char * Data, int size); + +//--- Describes format descriptor ------------------------------------------ + +static int BytesPerFormat[] = {0,1,1,2,4,8,1,1,2,4,8,4,8}; + +static TagTable_t TagTable[] = { + { 0x100, "ImageWidth"}, + { 0x101, "ImageLength"}, + { 0x102, "BitsPerSample"}, + { 0x103, "Compression"}, + { 0x106, "PhotometricInterpretation"}, + { 0x10A, "FillOrder"}, + { 0x10D, "DocumentName"}, + { 0x10E, "ImageDescription"}, + { 0x10F, "Make"}, + { 0x110, "Model"}, + { 0x111, "StripOffsets"}, + { 0x112, "Orientation"}, + { 0x115, "SamplesPerPixel"}, + { 0x116, "RowsPerStrip"}, + { 0x117, "StripByteCounts"}, + { 0x11A, "XResolution"}, + { 0x11B, "YResolution"}, + { 0x11C, "PlanarConfiguration"}, + { 0x128, "ResolutionUnit"}, + { 0x12D, "TransferFunction"}, + { 0x131, "Software"}, + { 0x132, "DateTime"}, + { 0x13B, "Artist"}, + { 0x13E, "WhitePoint"}, + { 0x13F, "PrimaryChromaticities"}, + { 0x156, "TransferRange"}, + { 0x200, "JPEGProc"}, + { 0x201, "ThumbnailOffset"}, + { 0x202, "ThumbnailLength"}, + { 0x211, "YCbCrCoefficients"}, + { 0x212, "YCbCrSubSampling"}, + { 0x213, "YCbCrPositioning"}, + { 0x214, "ReferenceBlackWhite"}, + { 0x828D, "CFARepeatPatternDim"}, + { 0x828E, "CFAPattern"}, + { 0x828F, "BatteryLevel"}, + { 0x8298, "Copyright"}, + { 0x829A, "ExposureTime"}, + { 0x829D, "FNumber"}, + { 0x83BB, "IPTC/NAA"}, + { 0x8769, "ExifOffset"}, + { 0x8773, "InterColorProfile"}, + { 0x8822, "ExposureProgram"}, + { 0x8824, "SpectralSensitivity"}, + { 0x8825, "GPSInfo"}, + { 0x8827, "ISOSpeedRatings"}, + { 0x8828, "OECF"}, + { 0x9000, "ExifVersion"}, + { 0x9003, "DateTimeOriginal"}, + { 0x9004, "DateTimeDigitized"}, + { 0x9101, "ComponentsConfiguration"}, + { 0x9102, "CompressedBitsPerPixel"}, + { 0x9201, "ShutterSpeedValue"}, + { 0x9202, "ApertureValue"}, + { 0x9203, "BrightnessValue"}, + { 0x9204, "ExposureBiasValue"}, + { 0x9205, "MaxApertureValue"}, + { 0x9206, "SubjectDistance"}, + { 0x9207, "MeteringMode"}, + { 0x9208, "LightSource"}, + { 0x9209, "Flash"}, + { 0x920A, "FocalLength"}, + { 0x927C, "MakerNote"}, + { 0x9286, "UserComment"}, + { 0x9290, "SubSecTime"}, + { 0x9291, "SubSecTimeOriginal"}, + { 0x9292, "SubSecTimeDigitized"}, + { 0xA000, "FlashPixVersion"}, + { 0xA001, "ColorSpace"}, + { 0xA002, "ExifImageWidth"}, + { 0xA003, "ExifImageLength"}, + { 0xA005, "InteroperabilityOffset"}, + { 0xA20B, "FlashEnergy"}, // 0x920B in TIFF/EP + { 0xA20C, "SpatialFrequencyResponse"}, // 0x920C - - + { 0xA20E, "FocalPlaneXResolution"}, // 0x920E - - + { 0xA20F, "FocalPlaneYResolution"}, // 0x920F - - + { 0xA210, "FocalPlaneResolutionUnit"}, // 0x9210 - - + { 0xA214, "SubjectLocation"}, // 0x9214 - - + { 0xA215, "ExposureIndex"}, // 0x9215 - - + { 0xA217, "SensingMethod"}, // 0x9217 - - + { 0xA300, "FileSource"}, + { 0xA301, "SceneType"}, + { 0, NULL} +} ; + +//--- Storage for simplified info extracted from file ----------------------------------- +//--- ImageInfo: Pointer to structure ImageInfo_t ----------------------------------- + +ImageInfo_t ImageInfo; + +//--- Pointer to structure Ttype (Global buffer) ---------------------------------------- + +Ttype BufType; + +//--------------------------------------------------------------------------------------- + +//static int FilesMatched; +static const char *CurrentFile; +static char *ShowImageInfo(struct ExifPictureBase *ExifPictureBase); + +//--- Some command line options flags - Currently Unused ------------------------------- +// +//static char *strftime_args = NULL; // Format for new file name. +//static int DoModify = FALSE; +//static int DoReadAction = FALSE; +static int ShowTags = FALSE; // Do not show raw by default. +//static int ShowConcise = FALSE; +//static char *ApplyCommand = NULL; // Apply this command to all images. +static char *FilterModel = NULL; + +//--- Variables for Arguments ---------------------------------------------------------- + +static int ExifOnly = FALSE; +static int ShowFileDateTime = TRUE; +static int ShowFileSize = TRUE; +static int ShowJpegProcess = TRUE; +static int ShowJpegComment = TRUE; + +//--------------------------------------------------------------------------------------- + +//static time_t ExifTimeAdjust = 0; // Timezone adjust +//static time_t ExifTimeSet = 0; // Set exif time to a value. + +//static char *ThumbnailName = NULL; // If not NULL, use this string to make up + // the filename to store the thumbnail to. + +//static char *ExifXferScrFile = NULL; // Extract Exif header from this file, and + // put it into the jpegs processed. + +//static int EditComment = FALSE; // Invoke an editor for editing the comment +//static int SupressNonFatalErrors = FALSE; // Wether or not to pint warnings on recoverable errors +//static char *CommentSavefileName = NULL; // Save comment to this file. +//static char *CommentInsertfileName = NULL; // Insert comment from this file. +//static int AutoRotate = 0; + +//--------------------------------------------------------------------------------------- + +static void *MemPool; +static struct SignalSemaphore MemPoolSemaphore; + +//--------------------------------------------------------------------------------------- + +struct DosLibrary *DOSBase; +T_UTILITYBASE UtilityBase; +T_LOCALEBASE LocaleBase; + +#ifdef __amigaos4__ +struct DOSIFace *IDOS; +struct UtilityIFace *IUtility; +struct LocaleIFace *ILocale; +struct Library *NewlibBase; +struct Interface *INewlib; +#endif + +#if defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) +extern T_UTILITYBASE __UtilityBase; +#endif /* defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) */ + +//-------------------------------- LOCALE MESSAGES --------------------------------------- + +static CONST_STRPTR GetLocString(ULONG MsgId, struct ExifPictureBase *ExifPictureBase); + +//--------------------------------------------------------------------------------------- +static void process_EXIF (unsigned char *ExifSection, unsigned int length); +static void ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength, int NestingLevel); +//static int Exif2tm(struct tm *timeptr, char *ExifTime); +static Section_t Sections[MAX_SECTIONS]; +static int SectionsRead; +static int HaveAll; +static BOOL ReadJpegSections(BPTR infile, ReadMode_t ReadMode); +static void process_COM(const uchar *Data, int length); +static void process_SOFn(const uchar *Data, int marker); +static void DiscardData(void); +//static void DiscardAllButExif(void); +//static int RemoveSectionType(int SectionType); +static void ResetJpgfile(void); +static double ConvertAnyFormat(void * ValuePtr, int Format); +static void PrintFormatNumber(void * ValuePtr, int Format, int ByteCount); +//static void Put16u(void * Short, unsigned short PutValue); +static int Get16u(void * Short); +static int Get32s(void * Long); +static unsigned Get32u(void * Long); +static int Get16m(const void * Short); +APTR MyAllocVecPooled(size_t Size); +void MyFreeVecPooled(APTR mem); + +//----------------------------------------------------------- + +static struct Locale *ExifPictureLocale; + +static STRPTR ScaFormatString(CONST_STRPTR FormatString, STRPTR Buffer, size_t MaxLen, LONG NumArgs, ...); +static void ScaFormatDate(struct DateTime *dt, ULONG DayMaxLen, ULONG DateMaxLen, ULONG TimeMaxLen); + +static M68KFUNC_P3_PROTO(void, FormatDateHookFunc, + A0, struct Hook *, theHook, + A2, struct Locale *, locale, + A1, char, ch); + +static struct FileInfoBlock fib; +static BOOL FibValid = FALSE; +static BOOL BreakPos = FALSE; + +//------------------------------------------------------------- + +struct FormatDateHookData + { + STRPTR fdhd_Buffer; // buffer to write characters to + size_t fdhd_Length; // length of buffer + }; + +//------------------------------------------------------------- + +BOOL initPlugin(struct PluginBase *base) +{ + struct ExifPictureBase *ExifPictureBase = (struct ExifPictureBase *)base; + + d1(kprintf("%s/%s/%ld: ExifPictureBase=%08lx procName=<%s>\n", \ + __FILE__, __FUNC__, __LINE__, \ + ExifPictureBase, FindTask(NULL)->tc_Node.ln_Name)); + + ExifPictureBase->pdb_Locale = NULL; + ExifPictureBase->pdb_Catalog = NULL; + + DOSBase = (APTR) OpenLibrary( "dos.library", 39 ); + if (NULL == DOSBase) + { + d1(kprintf("%s/%s/%ld: Fail\n", __FILE__, __FUNC__, __LINE__)); + return FALSE; + } +#ifdef __amigaos4__ + IDOS = (struct DOSIFace *)GetInterface((struct Library *)DOSBase, "main", 1, NULL); + if (NULL == IDOS) + { + d1(kprintf("%s/%s/%ld: Fail\n", __FILE__, __FUNC__, __LINE__)); + return FALSE; + } +#endif + + UtilityBase = (T_UTILITYBASE) OpenLibrary("utility.library", 39); + if (NULL == UtilityBase) + return FALSE; +#ifdef __amigaos4__ + IUtility = (struct UtilityIFace *)GetInterface((struct Library *)UtilityBase, "main", 1, NULL); + if (NULL == IUtility) + return FALSE; +#endif + +#if defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) + __UtilityBase = UtilityBase; +#endif /* defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) */ + +#ifdef __amigaos4__ + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + return FALSE; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + return FALSE; +#endif + + // LocaleBase may be NULL + LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 39 ); +#ifdef __amigaos4__ + if (NULL != LocaleBase) + { + ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL); + if (NULL == ILocale) + { + CloseLibrary((struct Library *)LocaleBase); + LocaleBase = NULL; + } + } +#endif + + if (LocaleBase) + { + InitSemaphore(&MemPoolSemaphore); + + MemPool = CreatePool(MEMPOOL_MEMFLAGS, MEMPOOL_PUDDLESIZE, MEMPOOL_THRESHSIZE); + if (NULL == MemPool) + return FALSE; + + if (NULL == ExifPictureBase->pdb_Locale) + ExifPictureLocale = ExifPictureBase->pdb_Locale = OpenLocale(NULL); + + if (ExifPictureBase->pdb_Locale) + { + if (NULL == ExifPictureBase->pdb_Catalog) + { + ExifPictureBase->pdb_Catalog = OpenCatalog(ExifPictureBase->pdb_Locale, + (STRPTR) "Scalos/ExifPicturePlugin.catalog", NULL); + } + } + } + + return TRUE; +} + + +VOID closePlugin(struct PluginBase *base) +{ + struct ExifPictureBase *ExifPictureBase = (struct ExifPictureBase *)base; + + d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__)); + + if (LocaleBase) + { + if (ExifPictureBase->pdb_Catalog) + { + CloseCatalog(ExifPictureBase->pdb_Catalog); + ExifPictureBase->pdb_Catalog = NULL; + } + if (ExifPictureBase->pdb_Locale) + { + CloseLocale(ExifPictureBase->pdb_Locale); + ExifPictureLocale = ExifPictureBase->pdb_Locale = NULL; + } + +#ifdef __amigaos4__ + if (ILocale) + { + DropInterface((struct Interface *)ILocale); + ILocale = NULL; + } +#endif + CloseLibrary((struct Library *)LocaleBase); + LocaleBase = NULL; + } +#ifdef __amigaos4__ + if (INewlib) + { + DropInterface(INewlib); + INewlib = NULL; + } + if (NewlibBase) + { + CloseLibrary(NewlibBase); + NewlibBase = NULL; + } + if (IUtility) + { + DropInterface((struct Interface *)IUtility); + IUtility = NULL; + } +#endif + if (UtilityBase) + { + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } +#ifdef __amigaos4__ + if (IDOS) + { + DropInterface((struct Interface *)IDOS); + IDOS = NULL; + } +#endif + if (DOSBase) + { + CloseLibrary((struct Library *) DOSBase); + DOSBase = NULL; + } + if (MemPool) + { + DeletePool(MemPool); + MemPool = NULL; + } +} + +void InitProccessTableLocale(struct ExifPictureBase *ExifPictureBase) +{ + CONST_STRPTR TempLine; + + TempLine = GetLocString(MSGID_BASELINE, ExifPictureBase); // "Baseline" + stccpy(LocBaseline, TempLine, sizeof(LocBaseline)); + + TempLine = GetLocString(MSGID_EXTENDED_SEQUENTIAL, ExifPictureBase); // "Extended sequential" + stccpy(LocExtendedSeq, TempLine, sizeof(LocExtendedSeq)); + + TempLine = GetLocString(MSGID_PROGRESSIVE, ExifPictureBase); // "Progressive" + stccpy(LocProgressive, TempLine, sizeof(LocProgressive)); + + TempLine = GetLocString(MSGID_LOSSLESS, ExifPictureBase); // "Lossless" + stccpy(LocLossless, TempLine, sizeof(LocLossless)); + + TempLine = GetLocString(MSGID_DIFFERENTIAL_SEQUENTIAL, ExifPictureBase); // "Differential sequential" + stccpy(LocDiffSeq, TempLine, sizeof(LocDiffSeq)); + + TempLine = GetLocString(MSGID_DIFFERENTIAL_PROGRESSIVE, ExifPictureBase); // "Differential progressive" + stccpy(LocDiffProgressive, TempLine, sizeof(LocDiffProgressive)); + + TempLine = GetLocString(MSGID_DIFFERENTIAL_LOSSLESS, ExifPictureBase); // "Differential lossless" + stccpy(LocDiffLossless, TempLine, sizeof(LocDiffLossless)); + + TempLine = GetLocString(MSGID_EXTENDED_SEQUENTIAL_ARITHMETIC_CODING, ExifPictureBase); // "Extended sequential, arithmetic coding" + stccpy(LocExtendedSeqAritCoding, TempLine, sizeof(LocExtendedSeqAritCoding)); + + TempLine = GetLocString(MSGID_PROGRESSIVE_ARITHMETIC_CODING, ExifPictureBase); // "Progressive, arithmetic coding" + stccpy(LocProgressiveAritCoding, TempLine, sizeof(LocProgressiveAritCoding)); + + TempLine = GetLocString(MSGID_LOSSLESS_ARITHMETIC_CODING, ExifPictureBase); // "Lossless, arithmetic coding" + stccpy(LocLosslessAritCoding, TempLine, sizeof(LocLosslessAritCoding)); + + TempLine = GetLocString(MSGID_DIFFERENTIAL_SEQUENTIAL_ARITHMETIC_CODING, ExifPictureBase); // "Differential sequential, arithmetic coding" + stccpy(LocDiffSeqAritCoding, TempLine, sizeof(LocDiffSeqAritCoding)); + + TempLine = GetLocString(MSGID_DIFFERENTIAL_PROGRESSIVE_ARITHMETIC_CODING, ExifPictureBase); // "Differential progressive, arithmetic coding" + stccpy(LocDiffProgressiveAritCoding, TempLine, sizeof(LocDiffProgressiveAritCoding)); + + TempLine = GetLocString(MSGID_DIFFERENTIAL_LOSSLESS_ARITHMETIC_CODING, ExifPictureBase); // "Differential lossless, arithmetic coding" + stccpy(LocDiffLosslessAritCoding, TempLine, sizeof(LocDiffLosslessAritCoding)); + + TempLine = GetLocString(MSGID_UNKNOWN, ExifPictureBase); // "Unknown" + stccpy(LocUnknown, TempLine, sizeof(LocUnknown)); + + //----------------------------- OrienTab[] locale strings ---------------------------------------------------------------------------------------- + + TempLine = GetLocString(MSGID_ORIENTTAB_UNDEFINED, ExifPictureBase); // "Undefined" + stccpy(LocOrientUndef, TempLine, sizeof(LocOrientUndef)); + + TempLine = GetLocString(MSGID_ORIENTTAB_NORMAL, ExifPictureBase); // "Normal" + stccpy(LocOrientNormal, TempLine, sizeof(LocOrientNormal)); + + TempLine = GetLocString(MSGID_ORIENTTAB_FLIP_HORIZONTAL, ExifPictureBase); // "flip horizontal" + stccpy(LocOrientFlipHor, TempLine, sizeof(LocOrientFlipHor)); + + TempLine = GetLocString(MSGID_ORIENTTAB_ROTATE_180, ExifPictureBase); // "rotate 180" + stccpy(LocOrientRot180, TempLine, sizeof(LocOrientRot180)); + + TempLine = GetLocString(MSGID_ORIENTTAB_FLIP_VERTICAL, ExifPictureBase); // "flip vertical" + stccpy(LocOrientFlipVert, TempLine, sizeof(LocOrientFlipVert)); + + TempLine = GetLocString(MSGID_ORIENTTAB_TRANSPOSE, ExifPictureBase); // "transpose" + stccpy(LocOrientTranspose, TempLine, sizeof(LocOrientTranspose)); + + TempLine = GetLocString(MSGID_ORIENTTAB_ROTATE_90, ExifPictureBase); // "rotate 90" + stccpy(LocOrientRot90, TempLine, sizeof(LocOrientRot90)); + + TempLine = GetLocString(MSGID_ORIENTTAB_TRANSVERSE, ExifPictureBase); // "transverse" + stccpy(LocOrientTransverse, TempLine, sizeof(LocOrientTransverse)); + + TempLine = GetLocString(MSGID_ORIENTTAB_ROTATE_270, ExifPictureBase); // "rotate 270" + stccpy(LocOrientRot270, TempLine, sizeof(LocOrientRot270)); + + +} + +// NewExifPicture() +LIBFUNC_P3(STRPTR, LIBToolTipInfoString, + A0, struct ScaToolTipInfoHookData *, ttshd, + A1, CONST_STRPTR, args, + A6, struct PluginBase *, PluginBase); +{ + struct ExifPictureBase *ExifPictureBase = (struct ExifPictureBase *)PluginBase; + BPTR oldDir = NOT_A_LOCK; + BPTR dirLock; + BPTR infile = (BPTR)NULL; + struct RDArgs *allocRdArg = NULL; + struct RDArgs *rdArg = NULL; + STRPTR ArgsCopy = NULL; + char FaultBuffer[120]; + InitProccessTableLocale(ExifPictureBase); + + (void) args; + + do { + SIPTR ArgArray[5]; + BPTR fLock; + + ReadMode_t ReadMode = READ_EXIF; + + dirLock = ParentDir(ttshd->ttshd_FileLock); + if ((BPTR)NULL == dirLock) + break; + memset(ArgArray, 0, sizeof(ArgArray)); + + allocRdArg = AllocDosObject(DOS_RDARGS, NULL); + + d1(kprintf("%s/%s/%ld: allocRdArg=%08lx\n", __FILE__, __FUNC__, __LINE__, allocRdArg)); + if (NULL == allocRdArg) + break; + + ArgsCopy = MyAllocVecPooled(2 + strlen(args)); + if (NULL == ArgsCopy) + break; + + // important: ReadArgs() requires a trailing "\n" !! + strcpy(ArgsCopy, args); + strcat(ArgsCopy, "\n"); + + allocRdArg->RDA_Source.CS_Buffer = ArgsCopy; + allocRdArg->RDA_Source.CS_Length = strlen(ArgsCopy); + allocRdArg->RDA_Source.CS_CurChr = 0; + allocRdArg->RDA_Flags |= RDAF_NOPROMPT; + + rdArg = ReadArgs("EXIFONLY/S,NOFILEDATETIME/S,NOFILESIZE/S,NOJPEGPROCESS/S,NOCOMMENT/S", ArgArray, allocRdArg); + + d1(kprintf("%s/%s/%ld: rdArg=%08lx\n", __FILE__, __FUNC__, __LINE__, rdArg)); + if (NULL == rdArg) + { + Fault(IoErr(), NULL, FaultBuffer, sizeof(FaultBuffer)-1); + sprintf(BufType.Buffer, GetLocString(MSGID_ERROR_DOS, ExifPictureBase), IoErr(), FaultBuffer); + + d1(kprintf("%s/%s/%ld: ReadArgs() returned error %ld\n", __FILE__, __FUNC__, __LINE__, IoErr())); + break; + } + + if (ArgArray[0]) + ExifOnly = TRUE; + if (ArgArray[1]) + ShowFileDateTime = FALSE; + if (ArgArray[2]) + ShowFileSize = FALSE; + if (ArgArray[3]) + ShowJpegProcess = FALSE; + if (ArgArray[4]) + ShowJpegComment = FALSE; + + oldDir = CurrentDir(dirLock); + + fLock = Lock(ttshd->ttshd_FileName, ACCESS_READ); + if (fLock) + { + if (Examine(fLock, &fib)) + FibValid = TRUE; + UnLock(fLock); + } + + CurrentFile = ttshd->ttshd_FileName; + + d1(kprintf("%s/%s/%ld: ResetJpgfile() \n", __FILE__, __FUNC__, __LINE__)); + + ResetJpgfile(); + + d1(kprintf("%s/%s/%ld: ImageInfo\n", __FILE__, __FUNC__, __LINE__)); + + memset(&ImageInfo, 0, sizeof(ImageInfo)); + ImageInfo.FlashUsed = -1; + ImageInfo.MeteringMode = -1; + + { + struct stat st; + + if (stat(ttshd->ttshd_FileName, &st) >= 0) + { + ImageInfo.FileDateTime = st.st_mtime; + ImageInfo.FileSize = st.st_size; + d1(kprintf("%s/%s/%ld: FileSize = %ld\n", __FILE__, __FUNC__, __LINE__, ImageInfo.FileSize)); + } + else + { + break; + } + } + + strncpy(ImageInfo.FileName, ttshd->ttshd_FileName, PATH_MAX); + + infile = Open(ttshd->ttshd_FileName, MODE_OLDFILE); + + if (infile == (BPTR)NULL) + break; + + d1(kprintf("%s/%s/%ld: ReadJpegSections(infile, ReadMde)\n", __FILE__, __FUNC__, __LINE__)); + + ResultJPEG = ReadJpegSections(infile, ReadMode); + + if (!ResultJPEG) + { + d1(kprintf("%s/%s/%ld: ResultJPEG = [%ld]\n", __FILE__, __FUNC__, __LINE__, ResultJPEG)); + sprintf(ttshd->ttshd_Buffer, GetLocString(MSGID_ERROR_NOJPEG, ExifPictureBase), ttshd->ttshd_FileName); + break; + } + + if (CheckFileSkip()) + { + DiscardData(); + break; + } + + d1(kprintf("%s/%s/%ld: ShowImageInfo()\n", __FILE__, __FUNC__, __LINE__, CurrentFile)); + + ttshd->ttshd_Buffer = ShowImageInfo(ExifPictureBase); + + if (BreakPos) + strcat(ttshd->ttshd_Buffer, "\n"); + +/* if ('\n' == ttshd->ttshd_Buffer[strlen(ttshd->ttshd_Buffer) - 2]) + d1(kprintf("%s/%s/%ld: BreakPos = [%ld] FOUND { n } POS - 2\n", __FILE__, __FUNC__, __LINE__, BreakPos)); + + if ('\n' == ttshd->ttshd_Buffer[strlen(ttshd->ttshd_Buffer) - 1]) + d1(kprintf("%s/%s/%ld: BreakPos = [%ld] FOUND { n } POS - 1\n", __FILE__, __FUNC__, __LINE__, BreakPos)); + + if ('\n' != ttshd->ttshd_Buffer[strlen(ttshd->ttshd_Buffer) - 1]) + d1(kprintf("%s/%s/%ld: BreakPos = [%ld] !!! NOT FOUND { n } POS - 1 !!!\n", __FILE__, __FUNC__, __LINE__, BreakPos)); + + d1(kprintf( "\n%s/%s/%ld: TEST BreakPos = [%ld] ttshd->ttshd_Buffer: \n%s.\n", __FILE__, __FUNC__, __LINE__, BreakPos, ttshd->ttshd_Buffer)); +*/ + + } while (0); + + BreakPos = FALSE; + + if (infile == (BPTR)NULL) + DiscardData(); + + if (infile) + Close(infile); + + if (IS_VALID_LOCK(oldDir)) + CurrentDir(oldDir); + + if (dirLock) + UnLock(dirLock); + + if (rdArg) + FreeArgs(rdArg); + if (allocRdArg) + FreeDosObject(DOS_RDARGS, allocRdArg); + + if (ArgsCopy) + MyFreeVecPooled(ArgsCopy); + + d1(kprintf("%s/%s/%ld: ResultString=<%s>\n", __FILE__, __FUNC__, __LINE__, ttshd->ttshd_Buffer)); + + return ttshd->ttshd_Buffer; +} +LIBFUNC_END + +static STRPTR ScaFormatString(CONST_STRPTR formatString, STRPTR Buffer, size_t MaxLen, LONG NumArgs, ...) +{ + va_list args; + + va_start(args, NumArgs); + + if (ExifPictureLocale) + { + ULONG *ArgArray; + + ArgArray = MyAllocVecPooled(sizeof(ULONG) * NumArgs); + if (ArgArray) + { + struct FormatDateHookData fd; + struct Hook fmtHook; + ULONG n; + STATIC_PATCHFUNC(FormatDateHookFunc) + + for (n = 0; n < NumArgs; n++) + ArgArray[n] = va_arg(args, LONG); + + fmtHook.h_Entry = (HOOKFUNC) PATCH_NEWFUNC(FormatDateHookFunc); + fmtHook.h_Data = &fd; + + fd.fdhd_Buffer = Buffer; + fd.fdhd_Length = MaxLen; + + FormatString(ExifPictureLocale, (STRPTR) formatString, ArgArray, &fmtHook); + + MyFreeVecPooled(ArgArray); + } + } + else + { + vsprintf(Buffer, formatString, args); + } + + va_end(args); + + return Buffer; +} +//---------------------------------------------------------------------------- + +static void ScaFormatDate(struct DateTime *dt, ULONG DayMaxLen, ULONG DateMaxLen, ULONG TimeMaxLen) +{ + if (ExifPictureLocale) + { + struct FormatDateHookData fd; + struct Hook fmtHook; + STATIC_PATCHFUNC(FormatDateHookFunc) + + d1(kprintf("%s/%s/%ld: DateBuff=%08lx Len=%ld TimeBuff=%08lx Len=%ld\n", \ + __FILE__, __FUNC__, __LINE__, dt->dat_StrDate, DateMaxLen, dt->dat_StrTime, DateMaxLen)); + + fmtHook.h_Entry = (HOOKFUNC) PATCH_NEWFUNC(FormatDateHookFunc); + fmtHook.h_Data = &fd; + + if (dt->dat_StrDay) + { + fd.fdhd_Buffer = dt->dat_StrDay; + fd.fdhd_Length = DayMaxLen; + + FormatDate(ExifPictureLocale, "%A", + &dt->dat_Stamp, &fmtHook); + } + + if (dt->dat_StrDate) + { + fd.fdhd_Buffer = dt->dat_StrDate; + fd.fdhd_Length = DateMaxLen; + + FormatDate(ExifPictureLocale, ExifPictureLocale->loc_ShortDateFormat, + &dt->dat_Stamp, &fmtHook); + } + + if (dt->dat_StrTime) + { + fd.fdhd_Buffer = dt->dat_StrTime; + fd.fdhd_Length = TimeMaxLen; + + FormatDate(ExifPictureLocale, ExifPictureLocale->loc_ShortTimeFormat, + &dt->dat_Stamp, &fmtHook); + } + } + else + { + DateToStr(dt); // no size checking possible here :( + } +} + +//---------------------------------------------------------------------------- + +static M68KFUNC_P3(void, FormatDateHookFunc, + A0, struct Hook *, theHook, + A2, struct Locale *, locale, + A1, char, ch) +{ + struct FormatDateHookData *fd = (struct FormatDateHookData *) theHook->h_Data; + + (void) locale; + + if (fd->fdhd_Length >= 1) + { + *(fd->fdhd_Buffer)++ = ch; + fd->fdhd_Length--; + } +} +M68KFUNC_END + +//---------------------------------------------------------------------------- + +static STRPTR GetChangeDate(STRPTR BufferDate, struct DateStamp *ChangeDate) +{ + char DayBuffer[64], DateBuffer[64], TimeBuffer[64]; + struct DateTime dt; + + memset(&dt, 0, sizeof(dt)); + + dt.dat_Stamp = *ChangeDate; + dt.dat_StrDay = DayBuffer; + dt.dat_StrDate = DateBuffer; + dt.dat_StrTime = TimeBuffer; + + ScaFormatDate(&dt, sizeof(DayBuffer), sizeof(DateBuffer), sizeof(TimeBuffer)); + + sprintf(BufferDate, "%s, %s %s", DayBuffer, DateBuffer, TimeBuffer); + + return BufferDate; +} + +/*** +//---------------------------------------------------------------------------- + +static STRPTR GetSizeString(void) +{ + STRPTR SizeString; + + if (FibValid) + SizeString = ScaFormatString(GetLocString(MSGID_SIZE_FORMAT), TextSize, sizeof(TextSize), 1, fib.fib_Size); + else + SizeString = GetLocString(MSGID_VERSION_NOT_AVAILABLE); + + return SizeString; +} +***/ +//---------------------------------------------------------------------------- +//-------------------------------------------------------------------------- +// Parse the marker stream until SOS or EOI is seen; +//-------------------------------------------------------------------------- +static BOOL ReadJpegSections (BPTR infile, ReadMode_t ReadMode) +{ + int a; + int HaveCom = FALSE; + + a = FGetC(infile); + + if (a != 0xff || FGetC(infile) != M_SOI) + { + d1(kprintf("%s/%s/%ld: return FALSE - [a != 0xff || fgetc(infile) != M_SOI]\n", __FILE__, __FUNC__, __LINE__)); + return FALSE; + } + + d1(kprintf("%s/%s/%ld: a = %04lx\n", __FILE__, __FUNC__, __LINE__, a)); + + for(;;) + { + int itemlen; + int ll,lh, got; + uchar * Data; + int marker = 0; + + if (SectionsRead >= MAX_SECTIONS) + { + d1(kprintf("%s/%s/%ld: ResultJPEG=[%ld]\n", __FILE__, __FUNC__, __LINE__, ResultJPEG)); + ErrFatal("Too many sections in jpg file"); + } + + for (a=0; a<7; a++) + { + marker = FGetC(infile); + if (marker != 0xff) + { + d1(kprintf("%s/%s/%ld: break - [marker != 0xff]\n", __FILE__, __FUNC__, __LINE__)); + break; + } + + if (a >= 6) + { + sprintf(BufType.Buffer, "too many padding bytes\n"); + d1(kprintf("%s/%s/%ld: 'too many padding bytes'\n", __FILE__, __FUNC__, __LINE__)); + return FALSE; + } + } + + if (marker == 0xff) + { + ErrFatal("too many padding bytes!"); + d1(kprintf("%s/%s/%ld: ErrFatal(too many padding bytes!)\n", __FILE__, __FUNC__, __LINE__)); + } + + Sections[SectionsRead].Type = marker; + + // Read the length of the section. + lh = FGetC(infile); + ll = FGetC(infile); + + itemlen = (lh << 8) | ll; + + d1(kprintf("%s/%s/%ld: itemlen=[%ld]\n", __FILE__, __FUNC__, __LINE__, itemlen)); + + if (itemlen < 2) + { + ErrFatal("invalid marker"); + d1(kprintf("%s/%s/%ld: ErrFatal(invalid marker)\n", __FILE__, __FUNC__, __LINE__)); + } + + d1(kprintf("%s/%s/%ld: ResultJPEG=[%ld] - itemlen=[%ld]\n", __FILE__, __FUNC__, __LINE__, ResultJPEG, itemlen)); + + Sections[SectionsRead].Size = itemlen; + + Data = (uchar *)MyAllocVecPooled(itemlen); + if (Data == NULL) + { + d1(kprintf("%s/%s/%ld: ErrFatal(Could not allocate memory)\n", __FILE__, __FUNC__, __LINE__)); + ErrFatal("Could not allocate memory"); + } + + Sections[SectionsRead].Data = Data; + + // Store first two pre-read bytes. + Data[0] = (uchar)lh; + Data[1] = (uchar)ll; + + got = FRead(infile, Data+2, 1, itemlen-2); // Read the whole section. + if (got != itemlen-2) + { + ErrFatal("Premature end of file?"); + d1(kprintf("%s/%s/%ld: ErrFatal(Premature end of file?)\n", __FILE__, __FUNC__, __LINE__)); + } + + SectionsRead += 1; + + switch (marker) + { + case M_SOS: // stop before hitting compressed data. If reading entire image is requested, read the rest of the data. + if (ReadMode & READ_IMAGE) + { + int cp, ep, size; + + // Determine how much file is left. + cp = Seek(infile, 0, SEEK_END); + ep = Seek(infile, cp, OFFSET_BEGINNING); + + size = ep-cp; + + Data = (uchar *)MyAllocVecPooled(size); + if (Data == NULL) + { + ErrFatal("could not allocate data for entire image"); + d1(kprintf("%s/%s/%ld: ErrFatal(could not allocate data for entire image)\n", __FILE__, __FUNC__, __LINE__)); + } + + got = FRead(infile, Data, 1, size); + if (got != size) + { + strcat(BufType.Buffer, "Could not read the rest of the image"); + ErrFatal("could not read the rest of the image"); + d1(kprintf("%s/%s/%ld: ErrFatal(could not read the rest of the image)\n", __FILE__, __FUNC__, __LINE__)); + } + + Sections[SectionsRead].Data = Data; + Sections[SectionsRead].Size = size; + Sections[SectionsRead].Type = PSEUDO_IMAGE_MARKER; + SectionsRead ++; + HaveAll = 1; + } + return TRUE; // ResultJPEG = TRUE; + + case M_EOI: // in case it's a tables-only JPEG stream + sprintf(BufType.Buffer, "No image in jpeg!\n"); + d1(kprintf("%s/%s/%ld: ResultJPEG = [%ld] - '%s'\n", __FILE__, __FUNC__, __LINE__, ResultJPEG, BufType.Buffer)); + return FALSE; + + case M_COM: // Comment section + if (HaveCom || ((ReadMode & READ_EXIF) == 0)) + { + // Discard this section. + MyFreeVecPooled(Sections[--SectionsRead].Data); + } + else + { + process_COM(Data, itemlen); + HaveCom = TRUE; + } + break; + + case M_JFIF: + // Regular jpegs always have this tag, exif images have the exif + // marker instead, althogh ACDsee will write images with both markers. + // this program will re-create this marker on absence of exif marker. + // hence no need to keep the copy from the file. + MyFreeVecPooled(Sections[--SectionsRead].Data); + break; + + case M_EXIF: + // Seen files from some 'U-lead' software with Vivitar scanner + // that uses marker 31 for non exif stuff. Thus make sure + // it says 'Exif' in the section before treating it as exif. + + if (((ReadMode & READ_EXIF) && memcmp(Data+2, "Exif", 4)) == 0) + { + d1(kprintf("%s/%s/%ld: ResultJPEG=[%ld] - (ReadMode & READ_EXIF) && memcmp(Data+2, 'Exif', 4)\n", __FILE__, __FUNC__, __LINE__, ResultJPEG)); + process_EXIF((unsigned char *)Data, itemlen); + } + else + { + d1(kprintf("%s/%s/%ld: MyFreeVecPooled(Sections[--SectionsRead].Data - ResultJPEG=[%ld]\n", __FILE__, __FUNC__, __LINE__, ResultJPEG)); + MyFreeVecPooled(Sections[--SectionsRead].Data); + } + d1(kprintf("%s/%s/%ld: ResultJPEG=[%ld]\n", __FILE__, __FUNC__, __LINE__, ResultJPEG)); + break; + + case M_SOF0: + case M_SOF1: + case M_SOF2: + case M_SOF3: + case M_SOF5: + case M_SOF6: + case M_SOF7: + case M_SOF9: + case M_SOF10: + case M_SOF11: + case M_SOF13: + case M_SOF14: + case M_SOF15: + d1(kprintf("%s/%s/%ld: process_SOFn(Data, marker) - ResultJPEG=[%ld]\n", __FILE__, __FUNC__, __LINE__, ResultJPEG)); + process_SOFn(Data, marker); + break; + + default: + // Skip any other sections. + if (ShowTags) + { + sprintf(BufType.Buffer,"Jpeg section marker 0x%02x size %d\n",marker, itemlen); + d1(kprintf("%s/%s/%ld: ShowTags=[%ld] - ResultJPEG=[%ld] - BufType.Buffer=%s\n", __FILE__, __FUNC__, __LINE__, ShowTags, ResultJPEG, BufType.Buffer)); + } + break; + } + + } + + d1(kprintf("%s/%s/%ld: %s\n", __FILE__, __FUNC__, __LINE__, BufType.Buffer)); + + return TRUE; +} + +//-------------------------------------------------------------------------- +// Error exit handler +//-------------------------------------------------------------------------- +void ErrFatal(char * msg) +{ + if (CurrentFile) + sprintf(BufType.Buffer, "Error : %s in file '%s'\n",CurrentFile, msg); + else + sprintf(BufType.Buffer, "Error : %s\n", msg); + + exit(EXIT_FAILURE); +} +#if 0 +//-------------------------------------------------------------------------- +// Report non fatal errors. Now that microsoft.net modifies exif headers, +// there's corrupted ones, and there could be more in the future. +//-------------------------------------------------------------------------- +void ErrNonfatal(char * msg, int a1, int a2) +{ + char Temp[100]; + + if (SupressNonFatalErrors) + return; + + sprintf(Temp, "%s %s %s\n", msg, a1, a2); + + if (CurrentFile) + sprintf(BufType.Buffer, "Nonfatal Error : '%s'",CurrentFile); + else + sprintf(BufType.Buffer, "Nonfatal Error : "); + + strcat(BufType.Buffer, Temp); // fprintf(stderr, msg, a1, a2); +} +#endif +//-------------------------------------------------------------------------- +// check if this file should be skipped based on contents. +//-------------------------------------------------------------------------- +static int CheckFileSkip(void) +{ + // I sometimes add code here to only process images based on certain + // criteria - for example, only to convert non progressive jpegs to progressives, etc.. + + if (FilterModel) + { + // Filtering processing by camera model. + if (strstr(ImageInfo.CameraModel, FilterModel) == NULL) + { + // Skip. + return TRUE; + } + } + + if (ExifOnly) + { + // Filtering by EXIF only. Skip all files that have no Exif. + if (FindSection(M_EXIF) == NULL) + return TRUE; + } + return FALSE; +} + +#if 0 +//-------------------------------------------------------------------------- +// Convert a 16 bit unsigned value from file's native byte order +//-------------------------------------------------------------------------- +static void Put16u(void * Short, unsigned short PutValue) +{ + if (MotorolaOrder) + { + ((uchar *)Short)[0] = (uchar)(PutValue>>8); + ((uchar *)Short)[1] = (uchar)PutValue; + } + else + { + ((uchar *)Short)[0] = (uchar)PutValue; + ((uchar *)Short)[1] = (uchar)(PutValue>>8); + } +} +#endif + +//-------------------------------------------------------------------------- +// Convert a 16 bit unsigned value from file's native byte order +//-------------------------------------------------------------------------- +static int Get16u(void * Short) +{ + if (MotorolaOrder) + return (((uchar *)Short)[0] << 8) | ((uchar *)Short)[1]; + else + return (((uchar *)Short)[1] << 8) | ((uchar *)Short)[0]; +} + +//-------------------------------------------------------------------------- +// Convert a 32 bit signed value from file's native byte order +//-------------------------------------------------------------------------- +static int Get32s(void * Long) +{ + if (MotorolaOrder) + return ((( char *)Long)[0] << 24) | (((uchar *)Long)[1] << 16) | (((uchar *)Long)[2] << 8 ) | (((uchar *)Long)[3] << 0 ); + else + return ((( char *)Long)[3] << 24) | (((uchar *)Long)[2] << 16) | (((uchar *)Long)[1] << 8 ) | (((uchar *)Long)[0] << 0 ); +} + +//-------------------------------------------------------------------------- +// Convert a 32 bit unsigned value from file's native byte order +//-------------------------------------------------------------------------- +static unsigned Get32u(void * Long) +{ + return (unsigned)Get32s(Long) & 0xffffffff; +} + +//-------------------------------------------------------------------------- +// Display a number as one of its many formats +//-------------------------------------------------------------------------- +static void PrintFormatNumber(void * ValuePtr, int Format, int ByteCount) +{ + switch(Format) + { + case FMT_SBYTE: + case FMT_BYTE: + sprintf(BufType.Buffer, "%02x\n",*(uchar *)ValuePtr); + break; + case FMT_USHORT: + sprintf(BufType.Buffer, "%d\n",Get16u(ValuePtr)); + break; + case FMT_ULONG: + case FMT_SLONG: + sprintf(BufType.Buffer, "%d\n",Get32s(ValuePtr)); + break; + case FMT_SSHORT: + sprintf(BufType.Buffer, "%hd\n",(signed short)Get16u(ValuePtr)); + break; + case FMT_URATIONAL: + case FMT_SRATIONAL: + sprintf(BufType.Buffer, "%d/%d\n",Get32s(ValuePtr), Get32s(4+(char *)ValuePtr)); + break; + case FMT_SINGLE: + sprintf(BufType.Buffer, "%f\n",(double)*(float *)ValuePtr); + break; + case FMT_DOUBLE: + sprintf(BufType.Buffer,"%f\n",*(double *)ValuePtr); + break; + default: + sprintf(BufType.Buffer, "Unknown format %d:\n", Format); + } +} + + +//-------------------------------------------------------------------------- +// Evaluate number, be it int, rational, or float from directory. +//-------------------------------------------------------------------------- +static double ConvertAnyFormat(void * ValuePtr, int Format) +{ + double Value; + Value = 0; + + switch(Format) + { + case FMT_SBYTE: + Value = *(signed char *)ValuePtr; + break; + + case FMT_BYTE: + Value = *(uchar *)ValuePtr; + break; + + case FMT_USHORT: + Value = Get16u(ValuePtr); + break; + + case FMT_ULONG: + Value = Get32u(ValuePtr); + break; + + case FMT_URATIONAL: + case FMT_SRATIONAL: + { + int Num,Den; + Num = Get32s(ValuePtr); + Den = Get32s(4+(char *)ValuePtr); + if (Den == 0) + Value = 0; + else + Value = (double)Num/Den; + break; + } + + case FMT_SSHORT: + Value = (signed short)Get16u(ValuePtr); + break; + + case FMT_SLONG: + Value = Get32s(ValuePtr); + break; + + case FMT_SINGLE: + Value = (double)*(float *)ValuePtr; + break; + + case FMT_DOUBLE: + Value = *(double *)ValuePtr; + break; + } + return Value; +} + +//-------------------------------------------------------------------------- +// Process one of the nested EXIF directories. +//-------------------------------------------------------------------------- +static void ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength, int NestingLevel) +{ + int de; + int a; + int NumDirEntries; + unsigned ThumbnailOffset = 0; + unsigned ThumbnailSize = 0; + char BufferTemp[256]; + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + if (NestingLevel > 4) + { + strcat(BufType.Buffer, "Maximum directory nesting exceeded (corrupt exif header)"); + // ErrNonfatal("Maximum directory nesting exceeded (corrupt exif header)", 0,0); + return; + } + + NumDirEntries = Get16u(DirStart); + #define DIR_ENTRY_ADDR(Start, Entry) (Start+2+12*(Entry)) + + { + unsigned char * DirEnd; + DirEnd = DIR_ENTRY_ADDR(DirStart, NumDirEntries); + if (DirEnd+4 > (OffsetBase+ExifLength)) + { + if (DirEnd+2 == OffsetBase+ExifLength || DirEnd == OffsetBase+ExifLength) + { + // Version 1.3 of jhead would truncate a bit too much. + // This also caught later on as well. + } + else + { + // Note: Files that had thumbnails trimmed with jhead 1.3 or earlier + // might trigger this. + // ErrNonfatal("Illegally sized directory",0,0); + strcat(BufType.Buffer, "Illegally sized directory"); + return; + } + } + if (DirEnd > LastExifRefd) + LastExifRefd = DirEnd; + } + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + if (ShowTags) + { + sprintf(BufferTemp, "Directory with %d entries\n", NumDirEntries); + strcat(BufType.Buffer, BufferTemp); + // printf("Directory with %d entries\n",NumDirEntries); + } + + for (de=0;de= NUM_FORMATS) + { + // (-1) catches illegal zero case as unsigned underflows to positive large. + // ErrNonfatal("Illegal number format %d for tag %04x", Format, Tag); + sprintf(BufferTemp, "Illegal number format %d for tag %04x", Format, Tag); + strcat(BufType.Buffer, BufferTemp); + continue; + } + + ByteCount = Components * BytesPerFormat[Format]; + + if (ByteCount > 4) + { + unsigned OffsetVal; + OffsetVal = Get32u(DirEntry+8); + + // If its bigger than 4 bytes, the dir entry contains an offset. + if (OffsetVal+ByteCount > ExifLength) + { + // Bogus pointer offset and / or bytecount value + // ErrNonfatal("Illegal value pointer for tag %04x", Tag,0); + sprintf(BufferTemp, "Illegal value pointer for tag %04x", Tag); + strcat(BufType.Buffer, BufferTemp); + continue; + } + ValuePtr = OffsetBase+OffsetVal; + } + else + { + // 4 bytes or less and value is in the dir entry itself + ValuePtr = DirEntry+8; + } + + if (LastExifRefd < ValuePtr+ByteCount) + { + // Keep track of last byte in the exif header that was actually referenced. + // That way, we know where the discardable thumbnail data begins. + LastExifRefd = ValuePtr+ByteCount; + } + + if (ShowTags) + { + // Show tag name + for (a=0;;a++) + { + if (TagTable[a].Tag == 0) + { + // printf(" Unknown Tag %04x Value = ", Tag); + sprintf(BufferTemp, "Unknown Tag %04x Value = ", Tag); + strcat(BufType.Buffer, BufferTemp); + break; + } + + if (TagTable[a].Tag == Tag) + { + // printf(" %s = ",TagTable[a].Desc); + sprintf(BufferTemp, " %s = ",TagTable[a].Desc); + strcat(BufType.Buffer, BufferTemp); + break; + } + } + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + // Show tag value. + switch(Format) + { + case FMT_UNDEFINED: + // Undefined is typically an ascii string. + + case FMT_STRING: + // String arrays printed without function call (different from int arrays) + { + int NoPrint = 0; + // printf("\""); + strcat(BufType.Buffer,"\""); + + for (a=0;a= 32) + { + // putchar((ValuePtr)[a]); + stccpy(BufferTemp, (char *)&ValuePtr[a], sizeof(BufferTemp) -1); + strcat(BufType.Buffer, BufferTemp); + NoPrint = 0; + } + else + { + // Avoiding indicating too many unprintable characters of proprietary + // bits of binary information this program may not know how to parse. + if (!NoPrint) + { + // putchar('?'); + strcat(BufType.Buffer, "?"); + NoPrint = 1; + } + } + } + // printf("\"\n"); + strcat(BufType.Buffer, "\n"); + } + break; + + default: + // Handle arrays of numbers later (will there ever be?) + PrintFormatNumber(ValuePtr, Format, ByteCount); + } + } + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + // Extract useful components of tag + switch(Tag) + { + case TAG_MAKE: + strncpy(ImageInfo.CameraMake, (char *)ValuePtr, 31); + break; + + case TAG_MODEL: + strncpy(ImageInfo.CameraModel, (char *)ValuePtr, 39); + break; + + case TAG_DATETIME_ORIGINAL: + strncpy(ImageInfo.DateTime, (char *)ValuePtr, 19); + ImageInfo.DatePointer = (char *)ValuePtr; + break; + + case TAG_USERCOMMENT: + // Olympus has this padded with trailing spaces. Remove these first. + for (a=ByteCount;;) + { + a--; + if ((ValuePtr)[a] == ' ') + { + (ValuePtr)[a] = '\0'; + } + else + { + break; + } + if (a == 0) + break; + } + // Copy the comment + if (memcmp(ValuePtr, "ASCII",5) == 0) + { + for (a=5;a<10;a++) + { + int c; + c = (ValuePtr)[a]; + if (c != '\0' && c != ' ') + { + strncpy(ImageInfo.Comments, (char *)(a+ValuePtr), 199); + break; + } + } + } + else + { + strncpy(ImageInfo.Comments, (char *)ValuePtr, 199); + } + break; + + case TAG_FNUMBER: + // Simplest way of expressing aperture, so I trust it the most. + // (overwrite previously computd value if there is one) + ImageInfo.ApertureFNumber = (float)ConvertAnyFormat(ValuePtr, Format); + break; + + case TAG_APERTURE: + case TAG_MAXAPERTURE: + // More relevant info always comes earlier, so only use this field if we don't + // have appropriate aperture information yet. + if (ImageInfo.ApertureFNumber == 0) + ImageInfo.ApertureFNumber = (float)exp(ConvertAnyFormat(ValuePtr, Format)*log(2.0)*0.5); + break; + + case TAG_FOCALLENGTH: + // Nice digital cameras actually save the focal length as a function + // of how farthey are zoomed in. + ImageInfo.FocalLength = (float)ConvertAnyFormat(ValuePtr, Format); + break; + + case TAG_SUBJECT_DISTANCE: + // Inidcates the distacne the autofocus camera is focused to. + // Tends to be less accurate as distance increases. + ImageInfo.Distance = (float)ConvertAnyFormat(ValuePtr, Format); + break; + + case TAG_EXPOSURETIME: + // Simplest way of expressing exposure time, so I trust it most. + // (overwrite previously computd value if there is one) + ImageInfo.ExposureTime = (float)ConvertAnyFormat(ValuePtr, Format); + break; + + case TAG_SHUTTERSPEED: + // More complicated way of expressing exposure time, so only use + // this value if we don't already have it from somewhere else. + if (ImageInfo.ExposureTime == 0) + ImageInfo.ExposureTime = (float)(1/exp(ConvertAnyFormat(ValuePtr, Format)*log(2.0))); + break; + + case TAG_FLASH: + if ((int)ConvertAnyFormat(ValuePtr, Format) & 7) + ImageInfo.FlashUsed = TRUE; + else + ImageInfo.FlashUsed = FALSE; + break; + + case TAG_ORIENTATION: + ImageInfo.Orientation = (int)ConvertAnyFormat(ValuePtr, Format); + OrientationPtr = ValuePtr; + OrientationNumFormat = Format; + if (ImageInfo.Orientation < 1 || ImageInfo.Orientation > 8) + { + sprintf(BufferTemp, "Undefined rotation value %d", ImageInfo.Orientation); + strcat(BufType.Buffer, BufferTemp); + ImageInfo.Orientation = 0; + } + break; + + case TAG_EXIF_IMAGELENGTH: + case TAG_EXIF_IMAGEWIDTH: + // Use largest of height and width to deal with images that have been + // rotated to portrait format. + a = (int)ConvertAnyFormat(ValuePtr, Format); + if (ExifImageWidth < a) + ExifImageWidth = a; + break; + + case TAG_FOCALPLANEXRES: + FocalplaneXRes = ConvertAnyFormat(ValuePtr, Format); + break; + + case TAG_FOCALPLANEUNITS: + switch((int)ConvertAnyFormat(ValuePtr, Format)) + { + case 1: + FocalplaneUnits = 25.4; + break; // inch + case 2: + // According to the information I was using, 2 means meters. + // But looking at the Cannon powershot's files, inches is the only + // sensible value. + FocalplaneUnits = 25.4; + break; + + case 3: FocalplaneUnits = 10; + break; // centimeter + case 4: FocalplaneUnits = 1; + break; // milimeter + case 5: FocalplaneUnits = .001; + break; // micrometer + } + break; + + // Remaining cases contributed by: Volker C. Schoech (schoech@gmx.de) + + case TAG_EXPOSURE_BIAS: + ImageInfo.ExposureBias = (float)ConvertAnyFormat(ValuePtr, Format); + break; + + case TAG_WHITEBALANCE: + ImageInfo.Whitebalance = (int)ConvertAnyFormat(ValuePtr, Format); + break; + + case TAG_METERING_MODE: + ImageInfo.MeteringMode = (int)ConvertAnyFormat(ValuePtr, Format); + break; + + case TAG_EXPOSURE_PROGRAM: + ImageInfo.ExposureProgram = (int)ConvertAnyFormat(ValuePtr, Format); + break; + + case TAG_ISO_EQUIVALENT: + ImageInfo.ISOequivalent = (int)ConvertAnyFormat(ValuePtr, Format); + if ( ImageInfo.ISOequivalent < 50 ) + ImageInfo.ISOequivalent *= 200; + break; + + case TAG_THUMBNAIL_OFFSET: + ThumbnailOffset = (unsigned)ConvertAnyFormat(ValuePtr, Format); + DirWithThumbnailPtrs = DirStart; + break; + + case TAG_THUMBNAIL_LENGTH: + ThumbnailSize = (unsigned)ConvertAnyFormat(ValuePtr, Format); + break; + + case TAG_EXIF_OFFSET: + case TAG_INTEROP_OFFSET: + { + unsigned char * SubdirStart; + SubdirStart = OffsetBase + Get32u(ValuePtr); + if (SubdirStart < OffsetBase || SubdirStart > OffsetBase+ExifLength) + { + // ErrNonfatal("Illegal exif or interop ofset directory link",0,0); + strcat(BufType.Buffer, "Illegal exif or interop ofset directory link\n"); + } + else + { + ProcessExifDir(SubdirStart, OffsetBase, ExifLength, NestingLevel+1); + } + continue; + } + break; + default: + d1(KPrintF("%s/%s/%ld: unknown tag: tag=%04lx format=%ld Components=%ld\n", __FILE__, __FUNC__, __LINE__, Tag, Format, Components)); + break; + } + } + + + { + // In addition to linking to subdirectories via exif tags, + // there's also a potential link to another directory at the end of each + // directory. this has got to be the result of a comitee! + unsigned char * SubdirStart; + unsigned Offset; + + if (DIR_ENTRY_ADDR(DirStart, NumDirEntries) + 4 <= OffsetBase+ExifLength) + { + Offset = Get32u(DirStart+2+12*NumDirEntries); + if (Offset) + { + SubdirStart = OffsetBase + Offset; + if (SubdirStart > OffsetBase+ExifLength) + { + if (SubdirStart < OffsetBase+ExifLength+20) + { + // Jhead 1.3 or earlier would crop the whole directory! + // As Jhead produces this form of format incorrectness, + // I'll just let it pass silently + if (ShowTags) + // printf("Thumbnail removed with Jhead 1.3 or earlier\n"); + strcat(BufType.Buffer, "Thumbnail removed with Jhead 1.3 or earlier\n"); + } + else + { + // ErrNonfatal("Illegal subdirectory link",0,0); + strcat(BufType.Buffer, "Illegal subdirectory link\n"); + } + } + else + { + if (SubdirStart <= OffsetBase+ExifLength) + { + ProcessExifDir(SubdirStart, OffsetBase, ExifLength, NestingLevel+1); + } + } + } + } + else + { + // The exif header ends before the last next directory pointer. + } + } + + + if (ThumbnailSize && ThumbnailOffset) + { + if (ThumbnailSize + ThumbnailOffset <= ExifLength) + { + // The thumbnail pointer appears to be valid. Store it. + ImageInfo.ThumbnailPointer = OffsetBase + ThumbnailOffset; + ImageInfo.ThumbnailSize = ThumbnailSize; + + if (ShowTags) + { + // printf("Thumbnail size: %d bytes\n",ThumbnailSize); + sprintf(BufferTemp, "Thumbnail size: %d bytes\n",ThumbnailSize); + strcat(BufType.Buffer, BufferTemp); + } + } + } + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); +} + +//-------------------------------------------------------------------------- +// Process a EXIF marker +// Describes all the drivel that most digital cameras include... +//-------------------------------------------------------------------------- +static void process_EXIF (unsigned char * ExifSection, unsigned int length) +{ + int FirstOffset; + char Btemp[256]; + + FocalplaneXRes = 0; + FocalplaneUnits = 0; + ExifImageWidth = 0; + OrientationPtr = NULL; + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + if (ShowTags) + { + sprintf(Btemp, "Exif header %d bytes long\n",length); + strcat(BufType.Buffer, Btemp); + //printf("Exif header %d bytes long\n",length); + } + + { // Check the EXIF header component + static uchar ExifHeader[] = "Exif\0\0"; + if (memcmp(ExifSection+2, ExifHeader,6)) + { + strcat(BufType.Buffer, "Incorrect Exif header\n"); + // ErrNonfatal("Incorrect Exif header",0,0); + return; + } + } + + if (memcmp(ExifSection+8,"II",2) == 0) + { + if (ShowTags) + // printf("Exif section in Intel order\n"); + strcat(BufType.Buffer, "Exif section in Intel order\n"); + MotorolaOrder = 0; + } + else + { + if (memcmp(ExifSection+8,"MM",2) == 0) + { + if (ShowTags) + // printf("Exif section in Motorola order\n"); + strcat(BufType.Buffer,"Exif section in Intel order\n"); + MotorolaOrder = 1; + } + else + { + strcat(BufType.Buffer,"Invalid Exif alignment marker."); + // ErrNonfatal("Invalid Exif alignment marker.",0,0); + return; + } + } + + // Check the next value for correctness. + if (Get16u(ExifSection+10) != 0x2a) + { + // ErrNonfatal("Invalid Exif start (1)",0,0); + strcat(BufType.Buffer, "Invalid Exif start (1)"); + return; + } + + FirstOffset = Get32u(ExifSection+12); + if (FirstOffset < 8 || FirstOffset > 16) + { + // I used to ensure this was set to 8 (website I used indicated its 8) + // but PENTAX Optio 230 has it set differently, and uses it as offset. (Sept 11 2002) + // ErrNonfatal("Suspicious offset of first IFD value",0,0); + strcat(BufType.Buffer, "Suspicious offset of first IFD value"); + } + + LastExifRefd = ExifSection; + DirWithThumbnailPtrs = NULL; + + // First directory starts 16 bytes in. All offset are relative to 8 bytes in. + + d1(kprintf("%s/%s/%ld: ProcessExifDir(ExifSection)\n", __FILE__, __FUNC__, __LINE__)); + + ProcessExifDir(ExifSection+8+FirstOffset, ExifSection+8, length-6, 0); + + // Compute the CCD width, in milimeters. + if (FocalplaneXRes != 0) + { + ImageInfo.CCDWidth = (float)(ExifImageWidth * FocalplaneUnits / FocalplaneXRes); + } + + if (ShowTags) + { + // printf("Non settings part of Exif header: %d bytes\n",ExifSection+length-LastExifRefd); + sprintf(Btemp, "Non settings part of Exif header: %d bytes\n",(int) (ExifSection+length-LastExifRefd)); + strcat(BufType.Buffer, Btemp); + } + + d1(kprintf("%s/%s/%ld: ProcessExifDir END\n", __FILE__, __FUNC__, __LINE__)); +} + +#if 0 +//-------------------------------------------------------------------------- +// Convert exif time to Unix time structure +//-------------------------------------------------------------------------- +static int Exif2tm(struct tm * timeptr, char * ExifTime) +{ + int a; + + timeptr->tm_wday = -1; + + // Check for format: YYYY:MM:DD HH:MM:SS format. + a = sscanf(ExifTime, "%d:%d:%d %d:%d:%d", &timeptr->tm_year, &timeptr->tm_mon, &timeptr->tm_mday, &timeptr->tm_hour, &timeptr->tm_min, &timeptr->tm_sec); + + if (a == 6) + { + timeptr->tm_isdst = -1; + timeptr->tm_mon -= 1; // Adjust for unix zero-based months + timeptr->tm_year -= 1900; // Adjust for year starting at 1900 + return TRUE; // worked. + } + + return FALSE; // Wasn't in Exif date format. +} +#endif + +//-------------------------------------------------------------------------- +// Show the collected image info, displaying camera F-stop and shutter speed +// in a consistent and legible fashion. +//-------------------------------------------------------------------------- +static char *ShowImageInfo(struct ExifPictureBase *ExifPictureBase) +{ + int a; + char BufFileSize[100]=""; + char BufFileDateTime[100]=""; + char BufCameraMake[300]=""; + char BufDateTime[50]=""; + char BufResolution[30]=""; + char BufOrientation[30]=""; + char BufFlashUsed[20]=""; + char BufExposureTime1[30]=""; + char BufExposureTime2[7]=""; + char BufApertureFNumber[30]=""; + char BufDistance[50]=""; + char BufISOequivalent[50]=""; + char BufExposureBias[50]=""; + char BufProcessTable[100]=""; + char BufFocalLength[50]=""; + char BufFocalLengthCCDWidth[50]=""; + char BufCCDWidth[10]=""; + char BufComment[3]=""; + char Temp[20]=""; + STRPTR SizeString; + STRPTR DateString; + char DateBuffer[128]=""; + struct tm ts; + + + if (ShowFileSize) + { + if (FibValid) + { + SizeString = ScaFormatString(GetLocString(MSGID_PICTURE_FILESIZE, ExifPictureBase), BufFileSize, sizeof(BufFileSize), 1, fib.fib_Size); + strcat(BufType.Buffer, SizeString); + } + else + { + sprintf(BufFileSize, GetLocString(MSGID_PICTURE_FILESIZE, ExifPictureBase),ImageInfo.FileSize); + strcat(BufType.Buffer, BufFileSize); + } + } + + if (ShowFileDateTime) + { + if (FibValid) + { + DateString = GetChangeDate(DateBuffer, &fib.fib_Date); + sprintf(BufFileDateTime, GetLocString(MSGID_PICTURE_FILEDATE, ExifPictureBase), DateString); + } + else + { + ts = *localtime(&ImageInfo.FileDateTime); + strftime(Temp, 20, "%Y/%m/%d %H:%M:%S", &ts); + sprintf(BufFileDateTime, GetLocString(MSGID_PICTURE_FILEDATE, ExifPictureBase), Temp); + } + strcat(BufType.Buffer, BufFileDateTime); + } + + if (ImageInfo.CameraMake[0]) + { + sprintf(BufCameraMake, GetLocString(MSGID_CAMERA_MAKE_MODEL, ExifPictureBase), ImageInfo.CameraMake, ImageInfo.CameraModel); + strcat(BufType.Buffer, BufCameraMake); + BreakPos = TRUE; + } + + if (ImageInfo.DateTime[0]) + { + sprintf(BufDateTime, GetLocString(MSGID_DATE_TIME, ExifPictureBase), ImageInfo.DateTime); + strcat(BufType.Buffer, BufDateTime); + BreakPos = TRUE; + } + + sprintf(BufResolution, GetLocString(MSGID_PICTURE_RESOLUTION, ExifPictureBase),ImageInfo.Width, ImageInfo.Height); + strcat(BufType.Buffer, BufResolution); + + + if (ImageInfo.Orientation > 1) + { + // Only print orientation if one was supplied, and if its not 1 (normal orientation) + sprintf(BufOrientation, GetLocString(MSGID_ORIENTATION, ExifPictureBase), OrientTab[ImageInfo.Orientation]); + strcat(BufType.Buffer, BufOrientation); + BreakPos = TRUE; + } + + if (ImageInfo.IsColor == 0) + { + strcat(BufType.Buffer, GetLocString(MSGID_ISCOLOR, ExifPictureBase)); + BreakPos = TRUE; + } + + if (ImageInfo.FlashUsed >= 0) + { + sprintf(BufFlashUsed, GetLocString(MSGID_FLASHUSED, ExifPictureBase), \ + ImageInfo.FlashUsed ? GetLocString(MSGID_YES, ExifPictureBase) :GetLocString(MSGID_NO, ExifPictureBase)); + + strcat(BufType.Buffer, BufFlashUsed); + BreakPos = TRUE; + } + + if (ImageInfo.FocalLength) + { + sprintf(BufFocalLength, GetLocString(MSGID_FOCAL_LENGTH, ExifPictureBase), (double)ImageInfo.FocalLength); // "Focal length : %4.1fmm" + strcat(BufType.Buffer, BufFocalLength); + if (ImageInfo.CCDWidth) + { + sprintf(BufFocalLengthCCDWidth, GetLocString(MSGID_FOCAL_LENGTH_CDDWIDTH, ExifPictureBase), \ + (int)(ImageInfo.FocalLength/ImageInfo.CCDWidth*36 + 0.5)); // " (35mm equivalent: %dmm)" + + strcat(BufType.Buffer, BufFocalLengthCCDWidth); + } + strcat(BufType.Buffer, "\n"); + BreakPos = TRUE; + } + + if (ImageInfo.CCDWidth) + { + sprintf(BufCCDWidth, GetLocString(MSGID_CDDWIDTH, ExifPictureBase), (double)ImageInfo.CCDWidth); // "CCD width : %4.2fmm\n" + strcat(BufType.Buffer, BufCCDWidth); + BreakPos = TRUE; + } + + if (ImageInfo.ExposureTime) + { + if (ImageInfo.ExposureTime < 0.010) + { + sprintf(BufExposureTime1, GetLocString(MSGID_EXPOSURETIME64, ExifPictureBase), (double)ImageInfo.ExposureTime); // "Exposure time: %6.4f s " + strcat(BufType.Buffer, BufExposureTime1); + } + else + { + sprintf(BufExposureTime1, GetLocString(MSGID_EXPOSURETIME53, ExifPictureBase), (double)ImageInfo.ExposureTime); // "Exposure time: %5.3f s " + strcat(BufType.Buffer, BufExposureTime1); + } + + if (ImageInfo.ExposureTime <= 0.5) + { + sprintf(BufExposureTime2, " (1/%d)",(int)(0.5 + 1/ImageInfo.ExposureTime)); + strcat(BufType.Buffer, BufExposureTime2); + } + + strcat(BufType.Buffer, "\n"); + BreakPos = TRUE; + } + + if (ImageInfo.ApertureFNumber) + { + sprintf(BufApertureFNumber, GetLocString(MSGID_APERTUREFNUMBER, ExifPictureBase), (double)ImageInfo.ApertureFNumber); // "Aperture : f/%3.1f\n" + strcat(BufType.Buffer, BufApertureFNumber); + BreakPos = TRUE; + } + + if (ImageInfo.Distance) + { + if (ImageInfo.Distance < 0) + { + strcat(BufType.Buffer, GetLocString(MSGID_DISTANCE_INFINITE, ExifPictureBase)); // "Focus dist. : Infinite\n" + } + else + { + sprintf(BufDistance, GetLocString(MSGID_DISTANCE, ExifPictureBase), (double)ImageInfo.Distance); // "Focus dist. : %4.2fm\n" + strcat(BufType.Buffer, BufDistance); + } + BreakPos = TRUE; + } + + if (ImageInfo.ISOequivalent) // 05-jan-2001 vcs + { + sprintf(BufISOequivalent, GetLocString(MSGID_ISOEQUIVALENT, ExifPictureBase), (int)ImageInfo.ISOequivalent); // "ISO equiv. : %2d\n" + strcat(BufType.Buffer,BufISOequivalent); + BreakPos = TRUE; + } + + if (ImageInfo.ExposureBias) // 05-jan-2001 vcs + { + sprintf(BufExposureBias, GetLocString(MSGID_EXPOSUREBIAS, ExifPictureBase), (double)ImageInfo.ExposureBias); // "Exposure bias:%4.2f\n" + strcat(BufType.Buffer, BufExposureBias); + BreakPos = TRUE; + } + + if (ImageInfo.Whitebalance) // 05-jan-2001 vcs + { + switch(ImageInfo.Whitebalance) + { + case 1: + strcat(BufType.Buffer, GetLocString(MSGID_WHITEBALANCE1, ExifPictureBase)); // "Whitebalance : sunny\n" + BreakPos = TRUE; + break; + case 2: + strcat(BufType.Buffer, GetLocString(MSGID_WHITEBALANCE2, ExifPictureBase)); // "Whitebalance : fluorescent\n" + BreakPos = TRUE; + break; + case 3: + strcat(BufType.Buffer, GetLocString(MSGID_WHITEBALANCE3, ExifPictureBase)); // "Whitebalance : incandescent\n" + BreakPos = TRUE; + break; + default: + strcat(BufType.Buffer, GetLocString(MSGID_WHITEBALANCE4, ExifPictureBase)); // "Whitebalance : cloudy\n" + BreakPos = TRUE; + } + } + + if (ImageInfo.MeteringMode) // 05-jan-2001 vcs + { + switch(ImageInfo.MeteringMode) + { + case 2: + strcat(BufType.Buffer,GetLocString(MSGID_METERINGMODE_CENTER, ExifPictureBase)); // "Metering Mode: center weight\n" + BreakPos = TRUE; + break; + case 3: + strcat(BufType.Buffer,GetLocString(MSGID_METERINGMODE_SPOT, ExifPictureBase)); // "Metering Mode: spot\n" + BreakPos = TRUE; + break; + case 5: + strcat(BufType.Buffer,GetLocString(MSGID_METERINGMODE_MATRIX, ExifPictureBase)); // "Metering Mode: matrix\n" + BreakPos = TRUE; + break; + } + } + + if (ImageInfo.ExposureProgram) // 05-jan-2001 vcs + { + switch(ImageInfo.ExposureProgram) + { + case 2: + strcat(BufType.Buffer, GetLocString(MSGID_EXPOSURE_PROGRAM1, ExifPictureBase)); // "Exposure : program (auto)\n" + BreakPos = TRUE; + break; + case 3: + strcat(BufType.Buffer, GetLocString(MSGID_EXPOSURE_PROGRAM2, ExifPictureBase)); // "Exposure : aperture priority (semi-auto)\n" + BreakPos = TRUE; + break; + case 4: + strcat(BufType.Buffer, GetLocString(MSGID_EXPOSURE_PROGRAM3, ExifPictureBase)); // "Exposure : shutter priority (semi-auto)\n" + BreakPos = TRUE; + break; + } + } + + if (ShowJpegProcess) + { + for (a=0;;a++) + { + if (ProcessTable[a].Tag == ImageInfo.Process || ProcessTable[a].Tag == 0) + { + sprintf(BufProcessTable, GetLocString(MSGID_JPEG_PROCESS, ExifPictureBase), ProcessTable[a].Desc); // "Jpeg process : %s\n" + strcat(BufType.Buffer, BufProcessTable); + break; + } + } + + } + + if (ShowJpegComment) + { + // Print the comment. Print 'Comment:' for each new line of comment. + if (ImageInfo.Comments[0]) + { + int a,c; + + strcat(BufType.Buffer,GetLocString(MSGID_COMMENT, ExifPictureBase)); // "Comment : " + for (a=0; a MAX_COMMENT) + length = MAX_COMMENT; // Truncate if it won't fit in our structure. + + for (a=2; a= 32 || ch == '\n' || ch == '\t') + Comment[nch++] = (char)ch; + else + break; + } + + Comment[nch] = '\0'; // Null terminate + + + d1(kprintf("%s/%s/%ld: Comment =<%s>\n", __FILE__, __FUNC__, __LINE__, Comment)); + +/* + if (ShowTags) + { + sprintf(BufType.Buffer,"COM marker comment: %s\n",Comment); + // printf("COM marker comment: %s\n",Comment); + } +*/ + strcpy(ImageInfo.Comments,Comment); +} + + +//-------------------------------------------------------------------------- +// Process a SOFn marker. This is useful for the image dimensions +//-------------------------------------------------------------------------- +static void process_SOFn(const uchar * Data, int marker) +{ + int data_precision, num_components; + + data_precision = Data[2]; + ImageInfo.Height = Get16m(Data+3); + ImageInfo.Width = Get16m(Data+5); + num_components = Data[7]; + + if (num_components == 3) + { + ImageInfo.IsColor = 1; + } + else + { + ImageInfo.IsColor = 0; + } + + ImageInfo.Process = marker; + + if (ShowTags) + { + // printf("JPEG image is %uw * %uh, %d color components, %d bits per sample\n", ImageInfo.Width, ImageInfo.Height, num_components, data_precision); + } +} + +//-------------------------------------------------------------------------- +// Discard read data. +//-------------------------------------------------------------------------- +static void DiscardData(void) +{ + int a; + for (a=0; a= MAX_SECTIONS) + { + ErrFatal("Too many sections!"); + } + + for (a=SectionsRead; a>2; a--) + { + Sections[a] = Sections[a-1]; + } + + SectionsRead += 1; + + NewSection = Sections+2; + + NewSection->Type = SectionType; + NewSection->Size = Size; + NewSection->Data = Data; + + return NewSection; +} + + +//-------------------------------------------------------------------------- +// Initialisation. +//-------------------------------------------------------------------------- +static void ResetJpgfile(void) +{ + memset(&Sections, 0, sizeof(Sections)); + SectionsRead = 0; + HaveAll = 0; +} + +//---------------------------------------------------------------------------- + +static CONST_STRPTR GetLocString(ULONG MsgId, struct ExifPictureBase *ExifPictureBase) +{ + struct ExifPicturePlugin_LocaleInfo li; + + li.li_Catalog = ExifPictureBase->pdb_Catalog; +#ifndef __amigaos4__ + li.li_LocaleBase = LocaleBase; +#else + li.li_ILocale = ILocale; +#endif + + return GetExifPicturePluginString(&li, MsgId); +} + +//----------------------------------------------------------------------------- + +void _XCEXIT(long x) +{ +} + +//---------------------------------------------------------------------------- + +#if !defined(__SASC) && !defined(__amigaos4__) +// Replacement for SAS/C library functions + +void exit(int x) +{ + (void) x; + while (1) + ; +} + +APTR _WBenchMsg; + +#endif /* !__SASC && !__amigaos4__ */ + +//----------------------------------------------------------------------------- + +APTR MyAllocVecPooled(size_t Size) +{ + APTR ptr; + + if (MemPool) + { + ObtainSemaphore(&MemPoolSemaphore); + ptr = AllocPooled(MemPool, Size + sizeof(size_t)); + ReleaseSemaphore(&MemPoolSemaphore); + if (ptr) + { + size_t *sptr = (size_t *) ptr; + + sptr[0] = Size; + + d1(kprintf("%s/%s/%ld: MemPool=%08lx Size=%lu mem=%08lx\n", __FILE__, __FUNC__, __LINE__, MemPool, Size, &sptr[1])); + return (APTR)(&sptr[1]); + } + } + + d1(kprintf("%s/%s/%ld: MemPool=%08lx Size=%lu\n", __FILE__, __FUNC__, __LINE__, MemPool, Size)); + + return NULL; +} + + +void MyFreeVecPooled(APTR mem) +{ + d1(kprintf("%s/%s/%ld: MemPool=%08lx mem=%08lx\n", __FILE__, __FUNC__, __LINE__, MemPool, mem)); + if (MemPool && mem) + { + size_t size; + size_t *sptr = (size_t *) mem; + + mem = &sptr[-1]; + size = sptr[-1]; + + ObtainSemaphore(&MemPoolSemaphore); + FreePooled(MemPool, mem, size + sizeof(size_t)); + ReleaseSemaphore(&MemPoolSemaphore); + } +} + +//----------------------------------------------------------------------------- diff --git a/scalos/Plugins/FileTypes/ExifPicture/ExifPicture.h b/scalos/Plugins/FileTypes/ExifPicture/ExifPicture.h new file mode 100755 index 000000000..5a3c993aa --- /dev/null +++ b/scalos/Plugins/FileTypes/ExifPicture/ExifPicture.h @@ -0,0 +1,37 @@ +// ExifPicture.h +// $Date$ +// $Revision$ + +#ifndef EXIFPICTURE_H +#define EXIFPICTURE_H + +int ExifPictureInit(struct ExifPictureBase *ExifPictureBase); +int ExifPictureOpen(struct ExifPictureBase *ExifPictureBase); +void ExifPictureCleanup(struct ExifPictureBase *ExifPictureBase); +LIBFUNC_P3_PROTO(STRPTR, LIBToolTipInfoString, + A0, struct ScaToolTipInfoHookData *, ttshd, + A1, CONST_STRPTR, args, + A6, struct ExifPictureBase *, ExifPictureBase); + +//--------------------------------------------------------------- + +// Debugging... +#define d(x) ; +#define d1(x) ; +#define d2(x) x; + +// aus debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +//--------------------------------------------------------------- + +struct ExifPicturePlugin_LocaleInfo +{ + APTR li_LocaleBase; + APTR li_Catalog; + struct LocaleIFace *li_ILocale; +}; + +#endif /* EXIFPICTURE_H */ + diff --git a/scalos/Plugins/FileTypes/ExifPicture/ExifPicturePlugin.cd b/scalos/Plugins/FileTypes/ExifPicture/ExifPicturePlugin.cd new file mode 100755 index 000000000..098c3709f --- /dev/null +++ b/scalos/Plugins/FileTypes/ExifPicture/ExifPicturePlugin.cd @@ -0,0 +1,241 @@ +; ExifPicturePlugin.cd +; Date: $ +; Revision: $ +; version $VER: ExifPicturePlugin.catalog 40.0 (17.09.05) +; codeset 0s +; language english +; +;#arrayopts static __far +; +; +MSGID_ERROR_NOJPEG (//) +Error, file: %s isn't a JPEG picture. +; +; +MSGID_PICTURE_FILESIZE (//) +File size: %lD bytes\n +; +; +MSGID_PICTURE_FILEDATE (//) +File date: %s\n +; +; +MSGID_CAMERA_MAKE_MODEL (//) +Camera make: %s\n\ +Camera model: %s\n +; +; +MSGID_DATE_TIME (//) +Date/Time: %s\n +; +; +MSGID_PICTURE_RESOLUTION (//) +Resolution: %d x %d\n +; +; +MSGID_ORIENTATION (//) +Orientation: %s\n +; +; +MSGID_ISCOLOR (//) +Color/bw: Black and white\n +; +; +MSGID_FLASHUSED (//) +Flash used: %s\n +; +; +MSGID_NO (//) +No +; +; +MSGID_YES (//) +Yes +; +; +MSGID_FOCAL_LENGTH (//) +Focal length: %4.1fmm +; +; +MSGID_FOCAL_LENGTH_CDDWIDTH (//) + (35mm equivalent: %dmm) +; +; +MSGID_CDDWIDTH (//) +CCD width: %4.2fmm\n +; +; +MSGID_EXPOSURETIME64 (//) +Exposure time: %6.4f s +; +; +MSGID_EXPOSURETIME53 (//) +Exposure time: %5.3f s +; +; +MSGID_APERTUREFNUMBER (//) +Aperture: f/%3.1f\n +; +; +MSGID_DISTANCE_INFINITE (//) +Focus dist.: Infinite\n +; +; +MSGID_DISTANCE (//) +Focus dist.: %4.2fm\n +; +; +MSGID_ISOEQUIVALENT (//) +ISO equiv.: %2d\n +; +; +MSGID_EXPOSUREBIAS (//) +Exposure bias:%4.2f\n +; +; +MSGID_WHITEBALANCE1 (//) +Whitebalance: sunny\n +; +; +MSGID_WHITEBALANCE2 (//) +Whitebalance: fluorescent\n +; +; +MSGID_WHITEBALANCE3 (//) +Whitebalance: incandescent\n +; +; +MSGID_WHITEBALANCE4 (//) +Whitebalance: cloudy\n +; +; +MSGID_METERINGMODE_CENTER (//) +Metering Mode: center weight\n +; +; +MSGID_METERINGMODE_SPOT (//) +Metering Mode: spot\n +; +; +MSGID_METERINGMODE_MATRIX (//) +Metering Mode: matrix\n +; +; +MSGID_EXPOSURE_PROGRAM1 (//) +Exposure: program (auto)\n +; +; +MSGID_EXPOSURE_PROGRAM2 (//) +Exposure: aperture priority (semi-auto)\n +; +; +MSGID_EXPOSURE_PROGRAM3 (//) +Exposure: shutter priority (semi-auto)\n +; +; +MSGID_JPEG_PROCESS (//) +Jpeg process: %s\n +; +; +MSGID_COMMENT (//) +Comment: +; +;------------------- +MSGID_BASELINE (//) +Baseline +; +; +MSGID_EXTENDED_SEQUENTIAL (//) +Extended sequential +; +; +MSGID_PROGRESSIVE (//) +Progressive +; +; +MSGID_LOSSLESS (//) +Lossless +; +; +MSGID_DIFFERENTIAL_SEQUENTIAL (//) +Differential sequential +; +; +MSGID_DIFFERENTIAL_PROGRESSIVE (//) +Differential progressive +; +; +MSGID_DIFFERENTIAL_LOSSLESS (//) +Differential lossless +; +; +MSGID_EXTENDED_SEQUENTIAL_ARITHMETIC_CODING (//) +Extended sequential, arithmetic coding +; +; +MSGID_PROGRESSIVE_ARITHMETIC_CODING (//) +Progressive, arithmetic coding +; +; +MSGID_LOSSLESS_ARITHMETIC_CODING (//) +Lossless, arithmetic coding +; +; +MSGID_DIFFERENTIAL_SEQUENTIAL_ARITHMETIC_CODING (//) +Differential sequential, arithmetic coding +; +; +MSGID_DIFFERENTIAL_PROGRESSIVE_ARITHMETIC_CODING (//) +Differential progressive, arithmetic coding +; +; +MSGID_DIFFERENTIAL_LOSSLESS_ARITHMETIC_CODING (//) +Differential lossless, arithmetic coding +; +; +MSGID_UNKNOWN (//) +Unknown +; +;------------------------------------------------------------------------------ +; +MSGID_ERROR_DOS (//) +Error: %ld, %s. +; +;---------------------------- OrientTab ---------------------------------------- +; +MSGID_ORIENTTAB_UNDEFINED (// ) +Undefined +; +; +MSGID_ORIENTTAB_NORMAL (//) +Normal +; +; +MSGID_ORIENTTAB_FLIP_HORIZONTAL (//) +flip horizontal +; +; +MSGID_ORIENTTAB_ROTATE_180 (//) +rotate 180 +; +; +MSGID_ORIENTTAB_FLIP_VERTICAL (//) +flip vertical +; +; +MSGID_ORIENTTAB_TRANSPOSE (//) +transpose +; +; +MSGID_ORIENTTAB_ROTATE_90 (//) +rotate 90 +; +; +MSGID_ORIENTTAB_TRANSVERSE (//) +transverse +; +; +MSGID_ORIENTTAB_ROTATE_270 (//) +rotate 270 +; +; diff --git a/scalos/Plugins/FileTypes/ExifPicture/ExifPicture_base.h b/scalos/Plugins/FileTypes/ExifPicture/ExifPicture_base.h new file mode 100755 index 000000000..9c593c8dd --- /dev/null +++ b/scalos/Plugins/FileTypes/ExifPicture/ExifPicture_base.h @@ -0,0 +1,21 @@ +// ExifPicture_base.h +// $Date$ +// $Revision$ + +#ifndef __EXIFPICTURE_BASE +#define __EXIFPICTURE_BASE + +#include + +#include "plugin.h" + +struct ExifPictureBase +{ + struct PluginBase pdb_PluginBase; + + struct Locale *pdb_Locale; + struct Catalog *pdb_Catalog; +}; + +#endif //__EXIFPICTURE_BASE + diff --git a/scalos/Plugins/FileTypes/ExifPicture/config.mk b/scalos/Plugins/FileTypes/ExifPicture/config.mk new file mode 100755 index 000000000..6ff7d3523 --- /dev/null +++ b/scalos/Plugins/FileTypes/ExifPicture/config.mk @@ -0,0 +1,75 @@ +# $Date: 2011-07-31 22:05:01 +0200 (So, 31. Jul 2011) $ +# $Revision: 813 $ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +COMMON_DIR = $(TOPLEVEL)/common/Plugin + +INCLUDES += -I$(COMMON_DIR) + +SCALOS_LOCALE = $(OBJDIR)/ExifPicture_locale.h + +CFLAGS += -D SCALOSLOCALE=$(SCALOS_LOCALE) + +vpath %.c $(COMMON_DIR) + +############################################################################## + +include $(COMMON_DIR)/config.mk + +############################################################################## + +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +INCLUDES += # + +LFLAGS += -nostartfiles \ + -lmempools +# --verbose + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += -nostartfiles \ +# + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +LFLAGS += -nostartfiles \ +# + + +else + +############################################################################### +# AmigaOS + +INCLUDES += # + +LFLAGS += -lmempools \ + -ldebug \ + -lamiga21 \ + -lamiga \ + -lstubs + +endif +endif +endif diff --git a/scalos/Plugins/FileTypes/ExifPicture/makefile b/scalos/Plugins/FileTypes/ExifPicture/makefile new file mode 100755 index 000000000..ea5572b44 --- /dev/null +++ b/scalos/Plugins/FileTypes/ExifPicture/makefile @@ -0,0 +1,139 @@ +# makefile für Scalos exifpicture.plugin +# $Date$ +# $Revision$ +############################################################################## + +.SUFFIXES: .plugin .plugin.debug .cd + +############################################################# + +SUBDIRMAKE = $(MAKE) -s -C +#SUBDIRMAKE = smakedir + +PRECOMP = Include:all.gst + +SDPATH = // + +CC = sc +CFLAGS = nostackcheck nochkabort strmer dbg=l nover streq data=far \ + idlen=64 Math=s \ + define SCALOSLOCALE=$(SCALOS_LOCALE) \ + idir=///include \ + idir=///common/Plugin + +############################################################# + +OPT_FLG = OPTIMIZE OPTINLOCAL OPTTIME OPTSCHED IGNORE=306 IGNORE=308 IGNORE=304 +COPTS = NOWVRET NOVERSION nostackcheck idlen=128 idir=///include +OPTIONS = $(OPT_FLG) Math=s DATA=FAR DEBUG=L $(COPTS) def=NDEBUG + +############################################################# + +AS = phxass +AFLAGS = quiet noexe m=68020 opt=NRQB i=sc:Assembler_Headers/ +LD = slink +LDFLAGS = quiet batch noicons sd +LDLIBS = LIB:scm.lib LIB:sc.lib LIB:debug.lib LIB:amiga.lib +ASTARTUP = +#CSTARTUP = LIB:c.o + +OBJDIR = .sasobj +CATCOMP = CatComp +FLEXCAT = FlexCat + +COMMON_DIR = ../../../common/Plugin + +############################################################# + +CSRCS = $(COMMON_DIR)/plugin-classic.c \ + ExifPicture.c + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +XSRCS = $(notdir $(CSRCS)) +OBJS = $(XSRCS:%.c=$(OBJDIR)/$(notdir %).o) + +############################################################# + +PLUGIN = exifpicture.plugin +SCALOS_LOCALE = $(OBJDIR)/ExifPicture_locale.h +CATCOMPHEADER = $(SCALOS_LOCALE) +CAT_FILE = Scalos/ExifPicturePlugin.catalog +DESTTOOL = Scalos:plugins/FileTypes/ +DESTCAT = Locale:Catalogs +ALLCATS = Catalogs/deutsch/$(CAT_FILE) \ + Catalogs/français/$(CAT_FILE) + +############################################################# + +All: $(PLUGIN) \ + $(PLUGIN).debug \ + allcatalogs +# install +# clean + +############################################################# + +# commands generated a catalog (.catalog) from a catalog translation (.ct) file. +.ct.catalog: + $(CATCOMP) $*.cd $< CATALOG $*.catalog VB=1 + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-classic.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $*.c objectname $@ + +############################################################# + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-common.c \ + plugin_data.h ExifPicture_base.h $(COMMON_DIR)/plugin.h +$(OBJDIR)/ExifPicture.o : ExifPicture.h ExifPicture_base.h $(SCALOS_LOCALE) + +############################################################# + +$(CATCOMPHEADER) : ExifPicturePlugin.cd + @printf '\033[32mMake CatComp header: \033[31m\033[1m$@ \033[32mfrom \033[31m$<\033[0m\n' + $(FLEXCAT) $(subst ../,/,$<) $@=$(SDPATH)/CatComp_h.sd + +$(PLUGIN) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) to $@ FROM $(CSTARTUP) $(OBJS) lib $(LDLIBS) $(LDFLAGS) stripdebug + +$(PLUGIN).debug : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) to $@ FROM $(CSTARTUP) $(OBJS) lib $(LDLIBS) $(LDFLAGS) addsym + +############################################################# + +# A little something to clean it all up +clean: + @printf '\033[32mDelete: \033[31m\033[1m' + @delete $(OBJS) $(PLUGIN) $(PLUGIN).debug $(ALLCATS) $(CATCOMPHEADER) + @printf '\033[0m' + +############################################################# + +# copy all generated file to their final destinations +install: + @printf '\033[32mInstall: \033[31m\033[1m$(PLUGIN)\033[0m\n' + @copy $(PLUGIN) $(DESTTOOL) clone + @printf '\033[32mFlushing memory\033[0m\n' + @avail flush + @printf '\033[32mInstall: \033[31m\033[1m$(CAT_FILE)\033[0m\n' + -@copy 'catalogs/deutsch/$(CAT_FILE)' '$(DESTCAT)/Deutsch/Scalos/' clone + -@copy 'catalogs/français/$(CAT_FILE)' '$(DESTCAT)/français/Scalos/' clone + +############################################################# + +# make all Scalos preferences .catalogs +allcatalogs: + @$(SUBDIRMAKE) Catalogs/deutsch/Scalos + @$(SUBDIRMAKE) Catalogs/français/Scalos +# @$(SUBDIRMAKE) Catalogs/sample/Scalos + diff --git a/scalos/Plugins/FileTypes/ExifPicture/makefile-new b/scalos/Plugins/FileTypes/ExifPicture/makefile-new new file mode 100755 index 000000000..f27396167 --- /dev/null +++ b/scalos/Plugins/FileTypes/ExifPicture/makefile-new @@ -0,0 +1,97 @@ +# $Date: 2011-07-31 22:05:01 +0200 (So, 31. Jul 2011) $ +# $Revision: 813 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../../.. +endif + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + SDPATH=// +else + SDPATH=../../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(BEGIN_OBJS) \ + $(OBJDIR)/ExifPicture.o \ + $(END_OBJS) \ +# + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Targets +# + +NAME = exifpicture.plugin +NAME_DB = $(NAME).debug + +############################################################################## +# +# Subdirs +# + +SUBDIRS = $(filter-out Catalogs/sample/Scalos, $(wildcard Catalogs/*/Scalos)) + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) \ + all_subdirs + +############################################################################## + +ExifPicture.c : $(SCALOS_LOCALE) + +$(SCALOS_LOCALE) : ExifPicturePlugin.cd + @$(ECHO) "FlexCat $@" + $(FLEXCAT) $< $@=$(SDPATH)/CatComp_h.sd + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + $(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) Scalos:Plugins/FileTypes/ clone + @avail flush + +install: install_subdirs + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* \ + $(SCALOS_LOCALE) + +clean: clean_subdirs + +############################################################################## + + diff --git a/scalos/Plugins/FileTypes/ExifPicture/plugin_data.h b/scalos/Plugins/FileTypes/ExifPicture/plugin_data.h new file mode 100644 index 000000000..ea4be2ab2 --- /dev/null +++ b/scalos/Plugins/FileTypes/ExifPicture/plugin_data.h @@ -0,0 +1,34 @@ +// plugin_data.h +// $Date$ +// $Revision$ + +#ifndef PLUGIN_DATA_H_INCLUDED +#define PLUGIN_DATA_H_INCLUDED + +#include +#include + +#define PLUGIN_TYPE FILETYPE + +#define LIB_BASETYPE struct ExifPictureBase + +#define LIB_VERSION 40 +#define LIB_REVISION 0 + +#define LIB_NAME "exifpicture.plugin" +#define LIB_VERSTRING "$VER: exifpicture.plugin " \ + STR(LIB_VERSION) "." STR(LIB_REVISION) " (30.09.2005)" \ + COMPILER_STRING " ©2005" CURRENTYEAR \ + " The Scalos Team, parts of code from Jhead(public domain software) ©Matthias Wandel" + + +#define FT_INFOSTRING LIBToolTipInfoString +#define FT_INFOSTRING_AROS PluginBase_0_LIBToolTipInfoString + +//---------------------------------------------------------------------------- +// code and includes to define the structs and functions used above + +#include "ExifPicture_base.h" + +#endif /* PLUGUN_DATA_H_INCLUDED */ + diff --git a/scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/deutsch/Scalos/PictureDimensionsPlugin.ct b/scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/deutsch/Scalos/PictureDimensionsPlugin.ct new file mode 100644 index 000000000..7d83e44d6 --- /dev/null +++ b/scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/deutsch/Scalos/PictureDimensionsPlugin.ct @@ -0,0 +1,13 @@ +; PictureDimensionsPlugin.ct +## version $VER: PictureDimensionsPlugin.catalog 40.3 (17 Jan 2004 14:47:10) +## codeset 0 +## language deutsch +; +;#arrayopts static __far +; +; +MSGID_PIXELS_COLOURS +%ld x %ld Pixel x %ld Bit, %ld Farben +;%ld x %ld pixels x %ld Bit, %ld colours +; +; diff --git a/scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/deutsch/Scalos/config.mk b/scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/deutsch/Scalos/config.mk new file mode 100755 index 000000000..b60748fa3 --- /dev/null +++ b/scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/deutsch/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = deutsch + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = german + +else + +############################################################################### +# AmigaOS and AROS + +LANG = deutsch + +endif +endif diff --git a/scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/deutsch/Scalos/makefile b/scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/deutsch/Scalos/makefile new file mode 100644 index 000000000..5653cb51f --- /dev/null +++ b/scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/deutsch/Scalos/makefile @@ -0,0 +1,13 @@ +# makefile for PictureDimensionsPlugin (translated Texts : deutsch) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mdeutsch\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +PictureDimensionsPlugin.catalog : PictureDimensionsPlugin.ct ../../../PictureDimensionsPlugin.cd + +All: PictureDimensionsPlugin.catalog diff --git a/scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/deutsch/Scalos/makefile-new b/scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/deutsch/Scalos/makefile-new new file mode 100755 index 000000000..6135db512 --- /dev/null +++ b/scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/deutsch/Scalos/makefile-new @@ -0,0 +1,33 @@ +# makefile for PictureDimensionsPlugin (translated Texts : deutsch) +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = PictureDimensionsPlugin + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git "a/scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/fran\303\247ais/Scalos/PictureDimensionsPlugin.ct" "b/scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/fran\303\247ais/Scalos/PictureDimensionsPlugin.ct" new file mode 100755 index 000000000..7eea08e79 --- /dev/null +++ "b/scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/fran\303\247ais/Scalos/PictureDimensionsPlugin.ct" @@ -0,0 +1,13 @@ +; PictureDimensionsPlugin.ct +## version $VER: PictureDimensionsPlugin.catalog 40.3 (17 Jan 2004 14:47:10) +## codeset 0 +## language français +; +;#arrayopts static __far +; +; +MSGID_PIXELS_COLOURS +%ld x %ld pixels x %ld Bit, %ld couleurs +;%ld x %ld pixels x %ld Bit, %ld colours +; +; diff --git "a/scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/fran\303\247ais/Scalos/config.mk" "b/scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/fran\303\247ais/Scalos/config.mk" new file mode 100755 index 000000000..25cf21c8a --- /dev/null +++ "b/scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/fran\303\247ais/Scalos/config.mk" @@ -0,0 +1,40 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = français + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = french + +else + +############################################################################### +# AmigaOS + +LANG = français + +endif +endif diff --git "a/scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/fran\303\247ais/Scalos/makefile" "b/scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/fran\303\247ais/Scalos/makefile" new file mode 100644 index 000000000..926956903 --- /dev/null +++ "b/scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/fran\303\247ais/Scalos/makefile" @@ -0,0 +1,13 @@ +# makefile for PictureDimensionsPlugin (translated Texts : français) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mfrançais\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +PictureDimensionsPlugin.catalog : PictureDimensionsPlugin.ct ../../../PictureDimensionsPlugin.cd + +All: PictureDimensionsPlugin.catalog diff --git "a/scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/fran\303\247ais/Scalos/makefile-new" "b/scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/fran\303\247ais/Scalos/makefile-new" new file mode 100755 index 000000000..c46533e4e --- /dev/null +++ "b/scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/fran\303\247ais/Scalos/makefile-new" @@ -0,0 +1,33 @@ +# makefile for PictureDimensionsPlugin (translated Texts : français) +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = PictureDimensionsPlugin + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/sample/Scalos/PictureDimensionsPlugin.ct b/scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/sample/Scalos/PictureDimensionsPlugin.ct new file mode 100644 index 000000000..917d9a14e --- /dev/null +++ b/scalos/Plugins/FileTypes/Picture_Dimensions/Catalogs/sample/Scalos/PictureDimensionsPlugin.ct @@ -0,0 +1,13 @@ +; PictureDimensionsPlugin.ct +## version $VER: PictureDimensionsPlugin.catalog 40.3 (17 Jan 2004 14:47:10) +## codeset 0s +## language english +; +;#arrayopts static __far +; +; +MSGID_PIXELS_COLOURS +%ld x %ld pixels x %ld Bit, %ld colours +;%ld x %ld pixels x %ld Bit, %ld colours +; +; diff --git a/scalos/Plugins/FileTypes/Picture_Dimensions/PictureDimensions.c b/scalos/Plugins/FileTypes/Picture_Dimensions/PictureDimensions.c new file mode 100644 index 000000000..3f4168271 --- /dev/null +++ b/scalos/Plugins/FileTypes/Picture_Dimensions/PictureDimensions.c @@ -0,0 +1,312 @@ +// PictureDimensions.c +// $Date$ + + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include "picturedimensions_base.h" +#include "PictureDimensions.h" + +#define PictureDimensionsPlugin_NUMBERS +#define PictureDimensionsPlugin_ARRAY +#define PictureDimensionsPlugin_CODE +#include STR(SCALOSLOCALE) + +//--------------------------------------------------------------- + +#define NOT_A_LOCK ((BPTR) ~0) +#define IS_VALID_LOCK(x) ((x) != NOT_A_LOCK) + +//--------------------------------------------------------------- + +//#define SysBase PictureDimensionsBase->pdb_SysBase +//#define DataTypesBase PictureDimensionsBase->pdb_DataTypesBase +//#define LocaleBase PictureDimensionsBase->pdb_LocaleBase +//#define DOSBase PictureDimensionsBase->pdb_DOSBase +struct Library *DataTypesBase; +struct DosLibrary *DOSBase; +T_LOCALEBASE LocaleBase; + +#ifdef __amigaos4__ +struct DataTypesIFace *IDataTypes; +struct DOSIFace *IDOS; +struct LocaleIFace *ILocale; +struct Library *NewlibBase; +struct Interface *INewlib; +#endif + +//--------------------------------------------------------------- + +static CONST_STRPTR GetLocString(ULONG MsgId, struct PictureDimensionsBase *PictureDimensionsBase); + +//--------------------------------------------------------------- + +BOOL initPlugin(struct PluginBase *PluginBase) +{ + struct PictureDimensionsBase *PictureDimensionsBase = (struct PictureDimensionsBase *)PluginBase; + + d1(kprintf(__FUNC__ "/%ld: PictureDimensionsBase=%08lx procName=<%s>\n", __LINE__, \ + PictureDimensionsBase, FindTask(NULL)->tc_Node.ln_Name)); + + PictureDimensionsBase->pdb_Locale = NULL; + PictureDimensionsBase->pdb_Catalog = NULL; + + DataTypesBase = (APTR) OpenLibrary( "datatypes.library", 39 ); + if (NULL == DataTypesBase) + { + d1(kprintf("%s/%s/%ld: Fail\n", __FILE__, __FUNC__, __LINE__)); + return FALSE; + } +#ifdef __amigaos4__ + IDataTypes = (struct DataTypesIFace *)GetInterface((struct Library *)DataTypesBase, "main", 1, NULL); + if (NULL == IDataTypes) + { + d1(kprintf("%s/%s/%ld: Fail\n", __FILE__, __FUNC__, __LINE__)); + return FALSE; + } +#endif + + DOSBase = (APTR) OpenLibrary( "dos.library", 39 ); + if (NULL == DOSBase) + { + d1(kprintf("%s/%s/%ld: Fail\n", __FILE__, __FUNC__, __LINE__)); + return FALSE; + } +#ifdef __amigaos4__ + IDOS = (struct DOSIFace *)GetInterface((struct Library *)DOSBase, "main", 1, NULL); + if (NULL == IDOS) + { + d1(kprintf("%s/%s/%ld: Fail\n", __FILE__, __FUNC__, __LINE__)); + return FALSE; + } +#endif + +#ifdef __amigaos4__ + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + return FALSE; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + return FALSE; +#endif + + // LocaleBase may be NULL + LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 39 ); +#ifdef __amigaos4__ + if (NULL != LocaleBase) + { + ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL); + if (NULL == ILocale) + { + CloseLibrary((struct Library *)LocaleBase); + LocaleBase = NULL; + } + } +#endif + + if (LocaleBase) + { + if (NULL == PictureDimensionsBase->pdb_Locale) + PictureDimensionsBase->pdb_Locale = OpenLocale(NULL); + + if (PictureDimensionsBase->pdb_Locale) + { + if (NULL == PictureDimensionsBase->pdb_Catalog) + { + PictureDimensionsBase->pdb_Catalog = OpenCatalog(PictureDimensionsBase->pdb_Locale, + (STRPTR) "Scalos/PictureDimensionsPlugin.catalog", NULL); + } + } + } + + return TRUE; // Success +} + + +VOID closePlugin(struct PluginBase *PluginBase) +{ + struct PictureDimensionsBase *PictureDimensionsBase = (struct PictureDimensionsBase *)PluginBase; + + d1(kprintf(__FUNC__ "/%ld:\n", __LINE__)); + + if (LocaleBase) + { + if (PictureDimensionsBase->pdb_Catalog) + { + CloseCatalog(PictureDimensionsBase->pdb_Catalog); + PictureDimensionsBase->pdb_Catalog = NULL; + } + if (PictureDimensionsBase->pdb_Locale) + { + CloseLocale(PictureDimensionsBase->pdb_Locale); + PictureDimensionsBase->pdb_Locale = NULL; + } + +#ifdef __amigaos4__ + if (ILocale) + { + DropInterface((struct Interface *)ILocale); + ILocale = NULL; + } +#endif + CloseLibrary((struct Library *)LocaleBase); + LocaleBase = NULL; + } +#ifdef __amigaos4__ + if (INewlib) + { + DropInterface(INewlib); + INewlib = NULL; + } + if (NewlibBase) + { + CloseLibrary(NewlibBase); + NewlibBase = NULL; + } + if (IDataTypes) + { + DropInterface((struct Interface *)IDataTypes); + IDataTypes = NULL; + } +#endif + if (DataTypesBase) + { + CloseLibrary(DataTypesBase); + DataTypesBase = NULL; + } +#ifdef __amigaos4__ + if (IDOS) + { + DropInterface((struct Interface *)IDOS); + IDOS = NULL; + } +#endif + if (DOSBase) + { + CloseLibrary((struct Library *) DOSBase); + DOSBase = NULL; + } +} + + +// NewPictureDimensions() +LIBFUNC_P3(STRPTR, LIBToolTipInfoString, + A0, struct ScaToolTipInfoHookData *, ttshd, + A1, CONST_STRPTR, args, + A6, struct PluginBase *, PluginBase); +{ + struct PictureDimensionsBase *PictureDimensionsBase = (struct PictureDimensionsBase *)PluginBase; + BPTR oldDir = NOT_A_LOCK; + BPTR dirLock; + Object *dt = NULL; + + (void) args; + + do { + struct BitMapHeader *bmhd = NULL; + + dirLock = ParentDir(ttshd->ttshd_FileLock); + if ((BPTR)NULL == dirLock) + break; + + oldDir = CurrentDir(dirLock); + + dt = NewDTObject((STRPTR) ttshd->ttshd_FileName, + DTA_SourceType, DTST_FILE, + PDTA_DestMode, PMODE_V43, + DTA_GroupID, GID_PICTURE, + PDTA_Remap, FALSE, + TAG_END); + + if (NULL == dt) + break; + + GetDTAttrs(dt, + PDTA_BitMapHeader, &bmhd, + TAG_END); + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: bmhd=%08lx\n", __LINE__, bmhd)); + + if (NULL == bmhd) + break; + + sprintf(ttshd->ttshd_Buffer, + GetLocString(MSGID_PIXELS_COLOURS, PictureDimensionsBase), + bmhd->bmh_Width, bmhd->bmh_Height, bmhd->bmh_Depth, 1 << bmhd->bmh_Depth); + } while (0); + + if (dt) + DisposeDTObject(dt); + + if (IS_VALID_LOCK(oldDir)) + CurrentDir(oldDir); + + if (dirLock) + UnLock(dirLock); + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: ResultString=<%s>\n", __LINE__, ttshd->ttshd_Buffer)); + + return ttshd->ttshd_Buffer; +} +LIBFUNC_END + +//---------------------------------------------------------------------------- + +static CONST_STRPTR GetLocString(ULONG MsgId, struct PictureDimensionsBase *PictureDimensionsBase) +{ + struct PictureDimensionsPlugin_LocaleInfo li; + + li.li_Catalog = PictureDimensionsBase->pdb_Catalog; +#ifndef __amigaos4__ + li.li_LocaleBase = LocaleBase; +#else + li.li_ILocale = ILocale; +#endif + + return GetPictureDimensionsPluginString(&li, MsgId); +} + +//---------------------------------------------------------------------------- + +#if !defined(__SASC) && !defined(__amigaos4__) +// Replacement for SAS/C library functions + +void exit(int x) +{ + (void) x; + while (1) + ; +} + +APTR _WBenchMsg; + +#endif /* !__SASC && !__amigaos4__ */ + +//---------------------------------------------------------------------------- diff --git a/scalos/Plugins/FileTypes/Picture_Dimensions/PictureDimensions.h b/scalos/Plugins/FileTypes/Picture_Dimensions/PictureDimensions.h new file mode 100644 index 000000000..be9d52196 --- /dev/null +++ b/scalos/Plugins/FileTypes/Picture_Dimensions/PictureDimensions.h @@ -0,0 +1,37 @@ +// PictureDimensions.h +// $Date$ +// $Revision$ + +#ifndef PICTUREDIMENSIONS_H +#define PICTUREDIMENSIONS_H + +int PictureDimensionsInit(struct PictureDimensionsBase *PictureDimensionsBase); +int PictureDimensionsOpen(struct PictureDimensionsBase *PictureDimensionsBase); +void PictureDimensionsCleanup(struct PictureDimensionsBase *PictureDimensionsBase); +LIBFUNC_P3_PROTO(STRPTR, LIBToolTipInfoString, + A0, struct ScaToolTipInfoHookData *, ttshd, + A1, CONST_STRPTR, args, + A6, struct PictureDimensionsBase *, PictureDimensionsBase); + +//--------------------------------------------------------------- + +// Debugging... +#define d(x) ; +#define d1(x) ; +#define d2(x) x; + +// aus debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +//---------------------------------------------------------------------------- + +struct PictureDimensionsPlugin_LocaleInfo +{ + APTR li_LocaleBase; + APTR li_Catalog; + struct LocaleIFace *li_ILocale; +}; + +#endif /* PICTUREDIMENSIONS_H */ + diff --git a/scalos/Plugins/FileTypes/Picture_Dimensions/PictureDimensionsPlugin.cd b/scalos/Plugins/FileTypes/Picture_Dimensions/PictureDimensionsPlugin.cd new file mode 100644 index 000000000..9d9f155b8 --- /dev/null +++ b/scalos/Plugins/FileTypes/Picture_Dimensions/PictureDimensionsPlugin.cd @@ -0,0 +1,12 @@ +; PictureDimensionsPlugin.cd +; version $VER: PictureDimensionsPlugin.catalog 40.2 (17 Jan 2004 14:47:10) +; codeset 0s +; language english +; +;#arrayopts static __far +; +; +MSGID_PIXELS_COLOURS (//) +%ld x %ld pixels x %ld Bit, %ld colours +; +; diff --git a/scalos/Plugins/FileTypes/Picture_Dimensions/config.mk b/scalos/Plugins/FileTypes/Picture_Dimensions/config.mk new file mode 100755 index 000000000..46af5084d --- /dev/null +++ b/scalos/Plugins/FileTypes/Picture_Dimensions/config.mk @@ -0,0 +1,82 @@ +# $Date: 2011-07-31 22:05:01 +0200 (So, 31. Jul 2011) $ +# $Revision: 813 $ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +COMMON_DIR = $(TOPLEVEL)/common/Plugin + +INCLUDES += -I$(COMMON_DIR) + +SCALOS_LOCALE = $(OBJDIR)/PictureDimensions_locale.h + +CFLAGS += -D SCALOSLOCALE=$(SCALOS_LOCALE) + +vpath %.c $(COMMON_DIR) + +############################################################################## + +include $(COMMON_DIR)/config.mk + +############################################################################## + +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +INCLUDES += # + +LFLAGS += -nostartfiles \ + -lmempools +# --verbose + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += -nostartfiles \ +# + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +LFLAGS += -nostartfiles \ +# + + +else + +############################################################################### +# AmigaOS + +INCLUDES += # + +LFLAGS += -lscalos \ + -lpreferences \ + -liconobject \ + -lmempools \ + -ldebug \ + -lmui \ + -lstack \ + -lnix \ + -lnixmain \ + -lamiga21 \ + -lamiga \ + -lstubs \ + +endif +endif +endif diff --git a/scalos/Plugins/FileTypes/Picture_Dimensions/makefile b/scalos/Plugins/FileTypes/Picture_Dimensions/makefile new file mode 100644 index 000000000..a595c3e54 --- /dev/null +++ b/scalos/Plugins/FileTypes/Picture_Dimensions/makefile @@ -0,0 +1,128 @@ +# makefile für Scalos picturedimensions.plugin +# $Date$ +# $Revision$ +############################################################################## + +.SUFFIXES: .plugin .plugin.debug .cd + +############################################################# + +SUBDIRMAKE = $(MAKE) -s -C +#SUBDIRMAKE = smakedir + +SDPATH = // + +CC = sc +CFLAGS = nostkchk nochkabort strmer dbg=f nover streq data=far \ + idlen=64 \ + define SCALOSLOCALE=$(SCALOS_LOCALE) \ + idir=///include \ + idir=///common/Plugin +AS = phxass +AFLAGS = quiet noexe m=68020 opt=NRQB i=sc:Assembler_Headers/ +LD = slink +LDFLAGS = quiet batch noicons sd +LDLIBS = LIB:mempools.lib LIB:sc.lib LIB:debug.lib LIB:amiga.lib +ASTARTUP = +CSTARTUP = LIB:c.o +OBJDIR = .sasobj +CATCOMP = CatComp +FLEXCAT = FlexCat +PRECOMP = Include:all.gst +COMMON_DIR = ../../../common/Plugin + +############################################################# + +CSRCS = $(COMMON_DIR)/plugin-classic.c \ + PictureDimensions.c + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +XSRCS = $(notdir $(CSRCS)) +OBJS = $(XSRCS:%.c=$(OBJDIR)/$(notdir %).o) + +############################################################# + +PLUGIN = picturedimensions.plugin +SCALOS_LOCALE = $(OBJDIR)/PictureDimensions_locale.h +CATCOMPHEADER = $(SCALOS_LOCALE) +CAT_FILE = Scalos/PictureDimensionsPlugin.catalog +DESTTOOL = Scalos:plugins/FileTypes/ +DESTCAT = Locale:Catalogs +ALLCATS = Catalogs/deutsch/$(CAT_FILE) \ + Catalogs/français/$(CAT_FILE) + +############################################################# + +All: $(PLUGIN) \ + $(PLUGIN).debug \ + allcatalogs +# install +# clean + +############################################################# + +# commands generated a catalog (.catalog) from a catalog translation (.ct) file. +.ct.catalog: + $(CATCOMP) $*.cd $< CATALOG $*.catalog VB=1 + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-classic.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $*.c objectname $@ + +############################################################# + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-common.c \ + plugin_data.h PictureDimensions_base.h $(COMMON_DIR)/plugin.h +$(OBJDIR)/PictureDimensions.o : PictureDimensions.h \ + PictureDimensions_base.h $(SCALOS_LOCALE) + +############################################################# + +$(CATCOMPHEADER) : PictureDimensionsPlugin.cd + @printf '\033[32mMake CatComp header: \033[31m\033[1m$@ \033[32mfrom \033[31m$<\033[0m\n' + $(FLEXCAT) $(subst ../,/,$<) $@=$(SDPATH)/CatComp_h.sd + +$(PLUGIN) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) to $@ FROM $(OBJS) lib $(LDLIBS) $(LDFLAGS) stripdebug + +$(PLUGIN).debug : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) to $@ FROM $(OBJS) lib $(LDLIBS) $(LDFLAGS) addsym + +############################################################# + +# A little something to clean it all up +clean: + @printf '\033[32mDelete: \033[31m\033[1m' + @delete $(OBJS) $(PLUGIN) $(PLUGIN).debug $(ALLCATS) $(CATCOMPHEADER) + @printf '\033[0m' + +############################################################# + +# copy all generated file to their final destinations +install: + @printf '\033[32mInstall: \033[31m\033[1m$(PLUGIN)\033[0m\n' + @copy $(PLUGIN) $(DESTTOOL) clone + @printf '\033[32mFlushing memory\033[0m\n' + @avail flush + @printf '\033[32mInstall: \033[31m\033[1m$(CAT_FILE)\033[0m\n' + -@copy 'catalogs/deutsch/$(CAT_FILE)' '$(DESTCAT)/Deutsch/Scalos/' clone + -@copy 'catalogs/français/$(CAT_FILE)' '$(DESTCAT)/français/Scalos/' clone + +############################################################# + +# make all Scalos preferences .catalogs +allcatalogs: + @$(SUBDIRMAKE) Catalogs/deutsch/Scalos + @$(SUBDIRMAKE) Catalogs/français/Scalos +# @$(SUBDIRMAKE) Catalogs/sample/Scalos + diff --git a/scalos/Plugins/FileTypes/Picture_Dimensions/makefile-new b/scalos/Plugins/FileTypes/Picture_Dimensions/makefile-new new file mode 100755 index 000000000..c9ae888bd --- /dev/null +++ b/scalos/Plugins/FileTypes/Picture_Dimensions/makefile-new @@ -0,0 +1,95 @@ +# $Date: 2011-07-31 22:05:01 +0200 (So, 31. Jul 2011) $ +# $Revision: 813 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../../.. +endif + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + SDPATH=// +else + SDPATH=../../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(BEGIN_OBJS) \ + $(OBJDIR)/PictureDimensions.o \ + $(END_OBJS) + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Targets +# +NAME = picturedimensions.plugin +NAME_DB = $(NAME).debug + +############################################################################## +# +# Subdirs +# + +SUBDIRS = $(filter-out Catalogs/sample/Scalos, $(wildcard Catalogs/*/Scalos)) + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) \ + all_subdirs + +############################################################################## + +PictureDimensions.c : $(SCALOS_LOCALE) + +$(SCALOS_LOCALE) : PictureDimensionsPlugin.cd + @$(ECHO) "FlexCat $@" + $(FLEXCAT) $< $@=$(SDPATH)/CatComp_h.sd + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + @$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) Scalos:Plugins/FileTypes/ clone + @avail flush + +install: install_subdirs + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* \ + $(SCALOS_LOCALE) \ + +clean: clean_subdirs + +############################################################################## + + diff --git a/scalos/Plugins/FileTypes/Picture_Dimensions/picturedimensions_base.h b/scalos/Plugins/FileTypes/Picture_Dimensions/picturedimensions_base.h new file mode 100644 index 000000000..2fe5650ba --- /dev/null +++ b/scalos/Plugins/FileTypes/Picture_Dimensions/picturedimensions_base.h @@ -0,0 +1,21 @@ +// scalos/PictureDimensions.h +// $Date$ +// $Revision$ + +#ifndef __PICTUREDIMENSIONS_BASE_H +#define __PICTUREDIMENSIONS_BASE_H + +#include + +#include "plugin.h" + +struct PictureDimensionsBase +{ + struct PluginBase pdb_PluginBase; + + struct Locale *pdb_Locale; + struct Catalog *pdb_Catalog; +}; + +#endif // __PICTUREDIMENSIONS_BASE_H + diff --git a/scalos/Plugins/FileTypes/Picture_Dimensions/plugin_data.h b/scalos/Plugins/FileTypes/Picture_Dimensions/plugin_data.h new file mode 100644 index 000000000..7544a6c6a --- /dev/null +++ b/scalos/Plugins/FileTypes/Picture_Dimensions/plugin_data.h @@ -0,0 +1,34 @@ +// plugin_data.h +// $Date$ +// $Revision$ + +#ifndef PLUGIN_DATA_H_INCLUDED +#define PLUGIN_DATA_H_INCLUDED + +#include +#include + +#define PLUGIN_TYPE FILETYPE + +#define LIB_BASETYPE struct PictureDimensionsBase + +#define LIB_VERSION 40 +#define LIB_REVISION 6 + +#define LIB_NAME "picturedimensions.plugin" +#define LIB_VERSTRING "$VER: picturedimensions.plugin " \ + STR(LIB_VERSION) "." STR(LIB_REVISION) " (20.02.2005)" \ + COMPILER_STRING " ©2003" CURRENTYEAR \ + " The Scalos Team" + + +#define FT_INFOSTRING LIBToolTipInfoString +#define FT_INFOSTRING_AROS PluginBase_0_LIBToolTipInfoString + +//---------------------------------------------------------------------------- +// code and includes to define the structs and functions used above + +#include "picturedimensions_base.h" + +#endif /* PLUGUN_DATA_H_INCLUDED */ + diff --git a/scalos/Plugins/FileTypes/config.mk b/scalos/Plugins/FileTypes/config.mk new file mode 100755 index 000000000..b5b58e5a6 --- /dev/null +++ b/scalos/Plugins/FileTypes/config.mk @@ -0,0 +1,36 @@ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += # + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += # + + +else + +############################################################################### +# AmigaOS + +LFLAGS += # + +endif +endif + + diff --git a/scalos/Plugins/FileTypes/makefile b/scalos/Plugins/FileTypes/makefile new file mode 100644 index 000000000..125cb667d --- /dev/null +++ b/scalos/Plugins/FileTypes/makefile @@ -0,0 +1,44 @@ +# makefile for Scalos FileTypes plugins +# $Date$ +# $Revision$ + +############################################################# + +SUBDIRS = DrawerContents \ + Picture_Dimensions \ + ExifPicture + +############################################################# + +.PHONY: All install clean + +############################################################# + +define build_subdir +$(MAKE) -s --directory=$(1); +endef + +define install_subdir +$(MAKE) -s install --directory=$(1); +endef + +define clean_subdir +$(MAKE) -s clean --directory=$(1); +endef + +############################################################# + +All: + @$(foreach subdir,$(SUBDIRS),$(call build_subdir,$(subdir))) + +############################################################# + +install: + @$(foreach subdir,$(SUBDIRS),$(call install_subdir,$(subdir))) + +############################################################# + +clean: + @$(foreach subdir,$(SUBDIRS),$(call clean_subdir,$(subdir))) + +############################################################# diff --git a/scalos/Plugins/FileTypes/makefile-new b/scalos/Plugins/FileTypes/makefile-new new file mode 100755 index 000000000..4a836e980 --- /dev/null +++ b/scalos/Plugins/FileTypes/makefile-new @@ -0,0 +1,28 @@ +# $Date: 2009-02-17 21:22:13 +0100 (Di, 17. Feb 2009) $ +# $Revision: 5 $ + +TOPLEVEL = $(shell pwd)/../.. + +include config.mk + +############################################################################## +# +# Project subdirectories +# + +SUBDIRS = DrawerContents \ + Picture_Dimensions \ + ExifPicture \ + +############################################################################## + +.PHONY: all install clean + +all: all_subdirs + +clean: clean_subdirs + +install: install_subdirs + +nodebug: nodebug_subdirs + diff --git a/scalos/Plugins/Menu/Sorted_Cleanup/makefile b/scalos/Plugins/Menu/Sorted_Cleanup/makefile new file mode 100644 index 000000000..d8443eee5 --- /dev/null +++ b/scalos/Plugins/Menu/Sorted_Cleanup/makefile @@ -0,0 +1,77 @@ +# makefile for Scalos sorted_cleanup.plugin +# $Date$ + +############################################################# + +.SUFFIXES: .s .plugin .plugin.debug + +############################################################# + +ASRCS = sorted_cleanup.s +AS = phxAss +LD = slink +LDLIBS = LIB:debug.lib LIB:amiga.lib +PRECOMP = Include:all.gst +OBJDIR = .sasobj + +############################################################# + +LNFLAGS = quiet batch noicons stripdebug +LNDBFLAGS = quiet batch noicons addsym + +ifdef L + AFLAGS = quiet DS NOEXE opt=NRQB LIST=* linedebug I=SC:Assembler_Headers +else + AFLAGS = quiet DS NOEXE opt=NRQB linedebug I=SC:Assembler_Headers +endif + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +OBJS = $(ASRCS:%.s=$(OBJDIR)/%.o) + +############################################################# + +NAME = sorted_cleanup.plugin +DBGNAME = $(NAME).debug + +############################################################# + +all: $(NAME) $(DBGNAME) +# install +# clean + +############################################################# + +$(OBJDIR)/%.o : %.s + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +############################################################# + +$(NAME) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(OBJS) to $@ LIB $(LDLIBS) $(LNFLAGS) + +$(DBGNAME) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(OBJS) to $@ LIB $(LDLIBS) $(LNDBFLAGS) + +############################################################# + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(NAME)\033[0m\n' + @copy $(NAME) scalos:plugins/menu/ clone + @avail flush + +############################################################# + +clean: + @printf '\033[32mDelete: \033[1m\033[31m' + @delete $(OBJS) $(NAME) $(DBGNAME) + @printf '\033[0m' + +############################################################# + diff --git a/scalos/Plugins/Menu/Sorted_Cleanup/scalos_macros.i b/scalos/Plugins/Menu/Sorted_Cleanup/scalos_macros.i new file mode 100755 index 000000000..9b0249980 --- /dev/null +++ b/scalos/Plugins/Menu/Sorted_Cleanup/scalos_macros.i @@ -0,0 +1,213 @@ +; Scalos_Macros.i +; 30 Aug 2001 20:47:16 + +tsta MACRO + IFNE mode020 + tst.l \1 + ELSE + cmp.l #0,'\1' + ENDC + ENDM + +tstpc: MACRO + IFNE mode020 + tst.\0 \1(pc) + ELSE + tst.\0 \1 + ENDC + ENDM + +bral: MACRO + IFNE mode020 + bra.l \1 + ELSE + jmp \1 + ENDC + ENDM + +bsrl: MACRO + IFNE mode020 + bsr.l \1 + ELSE + jsr \1 + ENDC + ENDM + +bnel: MACRO + IFNE mode020 + bne.l \1 + ELSE + beq.s skip\@ + jmp \1 +skip\@: + ENDC + ENDM + +DoMethod MACRO + movem.l d1/a0-a1/a6,-(a7) + move.l a7,a6 + clr.l -(a7) + ifge NARG-15 + move.l \f,-(a7) + endc + ifge NARG-14 + move.l \e,-(a7) + endc + ifge NARG-13 + move.l \d,-(a7) + endc + ifge NARG-12 + move.l \c,-(a7) + endc + ifge NARG-11 + move.l \b,-(a7) + endc + ifge NARG-10 + move.l \a,-(a7) + endc + ifge NARG-9 + move.l \9,-(a7) + endc + ifge NARG-8 + move.l \8,-(a7) + endc + ifge NARG-7 + move.l \7,-(a7) + endc + ifge NARG-6 + move.l \6,-(a7) + endc + ifge NARG-5 + move.l \5,-(a7) + endc + ifge NARG-4 + move.l \4,-(a7) + endc + ifge NARG-3 + move.l \3,-(a7) + endc + ifge NARG-2 + move.l \2,-(a7) + endc + ifge NARG-1 + move.l \1,-(a7) + endc + move.l a7,a1 + jsr _DoMethod + move.l a6,a7 + movem.l (a7)+,d1/a0-a1/a6 + ENDM + +cmv3 MACRO + ifge NARG-1 + move.l '\1',-(a7) + ENDC + ENDM + +;+++;30 = mu_sizeof +;+++GTMENU_USERDATA MACRO +;+++ move.l 30(\1),\2 +;+++ ENDM +;+++ +;+++;34 = mi_sizeof +;+++GTMENUITEM_USERDATA MACRO +;+++ move.l 34(\1),\2 +;+++ ENDM + +seti: MACRO + move.l \2,d0 + move.l \3,d1 + move.l \1,a0 + bsr.s setattr + ENDM + +geti: MACRO + move.l \1,a0 + move.l \2,d0 + bsr.s getattr + ENDM + +TRUE EQU 1 +FALSE EQU 0 + + +call MACRO +; xref _LVO\1 + jsr _LVO\1(a6) + ENDM + +RETURNSUPER MACRO + movem.l (a7)+,d1-a6 + move.l (cl_Super,a0),a0 + move.l (cl_Dispatcher+h_Entry,a0),-(a7) + rts + ENDM + +CALLSUPER MACRO + movem.l a0-a3,-(a7) + move.l (cl_Super,a0),a0 + move.l (cl_Dispatcher+h_Entry,a0),a3 + jsr (a3) + movem.l (a7)+,a0-a3 + ENDM + +STARTCLASS MACRO + movem.l d1-a6,-(a7) + lea \1,a3 + move.l (a1),d1 +.loop: + move.l (a3)+,d2 + beq.s .loopend + cmp.l d2,d1 + beq.s .found + addq.w #4,a3 + bra.s .loop +.found: + move.l (a3)+,a3 + jsr (a3) ; +jl+ 20010830 + movem.l (a7)+,d1-a6 + rts + +.loopend: + movem.l (a7)+,d1-a6 + move.l 24(a0),a0 + move.l 8(a0),-(a7) + rts + ENDM + +STARTMETHOD MACRO + movem.l d1-a6,-(sp) ; +jl+ 20010830 + move.w (cl_InstOffset,a0),d6 + lea (a2,d6.w),a4 ; instance data + move.l (a2),a5 ; ScaWindowTask + lea 4(a1),a3 ; skip MethodID + ENDM + +STARTMETHODNEW MACRO + movem.l d1-a6,-(sp) ; +jl+ 20010830 + ENDM + +ENDMETHOD MACRO + movem.l (a7)+,d1-a6 + rts + ENDM + +DBSTRING MACRO + movem.l a0/a1,-(a7) + move.l \1,-(a7) + move.l a7,a1 + lea debugstring,a0 + jsr dboutput + addq.w #4,a7 + movem.l (a7)+,a0/a1 + ENDM + +DBNUMBER MACRO + movem.l a0/a1,-(a7) + move.l \1,-(a7) + move.l a7,a1 + lea debugnumber,a0 + jsr dboutput + addq.w #4,a7 + movem.l (a7)+,a0/a1 + ENDM diff --git a/scalos/Plugins/Menu/Sorted_Cleanup/sorted_cleanup.s b/scalos/Plugins/Menu/Sorted_Cleanup/sorted_cleanup.s new file mode 100755 index 000000000..0769cefa1 --- /dev/null +++ b/scalos/Plugins/Menu/Sorted_Cleanup/sorted_cleanup.s @@ -0,0 +1,368 @@ +; sorted_cleanup.s +; Scalos Sorted Cleanup PlugIn +; $Date: 2009-12-24 13:25:21 +0100 (Do, 24. Dez 2009) $ +; $Revision: 401 $ + +;--------------------------------------------------------------- + machine 68020 + + incdir "SC:Assembler_Headers" + incdir "Scalos:Src/scalos/main/std_includes/asm" + + NOLIST ; skip includes in listing + + include "exec/types.i" + include "exec/macros.i" + include "exec/resident.i" + include "exec/initializers.i" + include "workbench/workbench.i" + include "scalos/iconobject.i" + include "scalos/scalos.i" + include "scalos/undo.i" + include "scalos_macros.i" + include "lvo/scalos_lib.i" + include "asmsupp.i" + + LIST + +INFO_LEVEL equ 0 + +;--------------------------------------------------------------- + +Startlib: + moveq #0,d0 + rts + +;--------------------------------------------------------------- + +RomTag: + dc.w RTC_MATCHWORD ;RT_MATCHWORD + dc.l RomTag ;RT_MATCHTAG + dc.l endep ;RT_ENDSKIP + dc.b RTF_AUTOINIT ;RT_FLAGS + dc.b 39 ;RT_VERSION + dc.b 9 ;RT_TYPE + dc.b 0 ;RT_PRI + dc.l libname ;RT_NAME + dc.l idstring ;RT_IDSTRING + dc.l init ;RT_INIT + + cnop 0,4 + +;--------------------------------------------------------------- + +libname: + dc.b 'sorted_cleanup.plugin',0 + even +idstring: + dc.b '$VER: sorted_cleanup.plugin 41.1 (23 Oct 2009 21:16:50)',10 + dc.b '(c) 2002-2009 The Scalos Team',0 + + cnop 0,4 + +;--------------------------------------------------------------- + +init: + dc.l LIB_SIZE + dc.l functable + dc.l datatable + dc.l InitRoutine + +functable: + dc.l Open + dc.l Close + dc.l Expunge + dc.l Startlib + dc.l menufunction + + dc.l -1 + +datatable: + INITBYTE LN_TYPE,NT_LIBRARY + INITLONG LN_NAME,libname + INITBYTE LIB_FLAGS,LIBF_SUMUSED!LIBF_CHANGED + INITWORD LIB_VERSION,39 + INITWORD LIB_REVISION,4 + INITLONG LIB_IDSTRING,idstring + dc.l 0 + + cnop 0,4 + +;--------------------------------------------------------------- + +InitRoutine: + movem.l d0-a6,-(sp) + move.l a0,seglist + move.l 4.w,a6 + lea scaname(pc),a1 + moveq #39,d0 + JSRLIB OpenLibrary + move.l d0,scabase + beq.s .openerror + lea utilname(pc),a1 + moveq #39,d0 + JSRLIB OpenLibrary + move.l d0,utilbase + lea intname(pc),a1 + moveq #39,d0 + JSRLIB OpenLibrary + move.l d0,intbase + + movem.l (sp)+,d0-a6 + rts +.openerror: + movem.l (sp)+,d0-a6 + moveq #0,d0 + rts + +;--------------------------------------------------------------- + +Open: ; ( libptr:a6, version:d0 ) + addq.w #1,(LIB_OPENCNT,A6) + bclr #LIBB_DELEXP,(LIB_FLAGS,A6) + move.l a6,d0 + rts + +;--------------------------------------------------------------- + +Close: ; ( libptr:a6 ) + subq.w #1,(LIB_OPENCNT,A6) + bne.s .nooneopen + btst #LIBB_DELEXP,(LIB_FLAGS,A6) + beq.s .nooneopen + bsr.s Expunge +.nooneopen: + moveq #0,d0 + rts + +;--------------------------------------------------------------- + +Expunge: ; ( libptr: a6 ) + tst.w (LIB_OPENCNT,A6) + beq.s .nooneopen2 + bset #LIBB_DELEXP,(LIB_FLAGS,A6) + moveq #0,d0 + rts + +;--------------------------------------------------------------- + +.nooneopen2: + movem.l d2/a4/a5/a6,-(sp) + move.l seglist(pc),d2 + move.l a6,a4 + move.l 4.w,a6 + move.l a4,a1 + JSRLIB Remove + moveq #0,d0 + move.l a4,a1 + move.w (LIB_NEGSIZE,A4),D0 + suba.w D0,A1 + add.w (LIB_POSSIZE,A4),D0 + JSRLIB FreeMem + + move.l scabase(pc),a1 + JSRLIB CloseLibrary + move.l utilbase(pc),a1 + JSRLIB CloseLibrary + + move.l d2,d0 + movem.l (sp)+,d2/a4/a5/a6 + rts + +;----------------------------- GetClass Info -------------------------------- + +;Input: A0 = WindowTask, A1 = ScaIconNode or NULL +;Ouput: none +menufunction: + movem.l d1-a6,-(a7) + move.l a0,a5 + + lea (RedoHook,pc),a0 + DoMethod (mt_MainObject,a5),#SCCM_IconWin_AddUndoEvent,#UNDO_Cleanup,#UNDOTAG_IconList,(wt_IconList,a5),#UNDOTAG_WindowTask,a5,#UNDOTAG_CleanupMode,#CLEANUP_Default,#UNDOTAG_RedoHook,a0,#TAG_END + +menufunction2: + move.l 4.w,a6 + move.l (wt_IconSemaphore,a5),a0 + JSRLIB ObtainSemaphore + + move.l (wt_LateIconList,a5),a2 + move.l scabase(pc),a6 +.loop: + tst.l a2 + beq.s .loopend + + lea (wt_LateIconList,a5),a0 + lea (wt_IconList,a5),a1 + move.l a2,d0 + JSRLIB2 SCA_MoveNode + move.l (LN_SUCC,a2),a2 + bra.s .loop +.loopend: + move.l (wt_IconList,a5),(wt_LateIconList,a5) + clr.l (wt_IconList,a5) + lea (wt_LateIconList,a5),a0 + lea CompareNameHook(pc),a1 + moveq #SCA_SortType_Best,d0 + JSRLIB2 SCA_SortNodes + + move.l 4.w,a6 + move.l (wt_IconSemaphore,a5),a0 + JSRLIB ReleaseSemaphore + + clr.l (wt_XOffset,a5) + move.l (mt_WindowStruct,a5),a0 + move.l (wt_XOffset,a5),(ws_xoffset,a0) + + DoMethod (mt_MainObject,a5),#SCCM_IconWin_CleanUp + DoMethod (mt_MainObject,a5),#SCCM_IconWin_SetVirtSize,#SETVIRTF_AdjustRightSlider|SETVIRTF_AdjustBottomSlider + DoMethod (mt_MainObject,a5),#SCCM_IconWin_Redraw,#0 + + movem.l (a7)+,d1-a6 + rts + +;--------------------------------------------------------------- + +; special entry for menufunction, without executing SCCM_IconWin_AddUndoEvent +InternalRedoFunc: + movem.l d1-a6,-(a7) + move.l a0,a5 + bra menufunction2 + +;--------------------------------------------------------------- + +CompareNameHook: + dc.l 0,0 + dc.l comparenamefunc + dc.l 0,0 + +;--------------------------------------------------------------- + +RedoHook: + dc.l 0,0 + dc.l RedoFunc + dc.l 0,0 + +;--------------------------------------------------------------- + +; a0 : hook (unused) +; a2 : object (unused) +; a1 : message (UndoEvent) +RedoFunc: + movem.l d1-a6,-(a7) + + + IFGE INFO_LEVEL-15 + move.l a1,-(SP) + move.l a2,-(SP) + move.l a0,-(SP) + PUTMSG 15,<'%s/RedoFunc hook=%08lx obj=%08lx msg=%08lx'> + add.l #3*4,sp + ENDC + + move.l a1,a3 ; UndoEvent + move.l uev_Data+ucd_WindowTask(a3),a0 ;WindowTask + CLEARA a1 + + IFGE INFO_LEVEL-15 + move.l a0,-(SP) + move.l a3,-(SP) + PUTMSG 15,<'%s/RedoFunc WindowTask=%08lx UndoEvent=%08lx'> + add.l #3*4,sp + ENDC + + bsr InternalRedoFunc + + movem.l (a7)+,d1-a6 + rts + +;--------------------------------------------------------------- + +; a0 : hook +; a2 : object +; a1 : message +comparenamefunc: + move.l a6,-(a7) + tst.l intbase + beq.s .noint + move.l a1,-(a7) + clr.l -(a7) + move.l #IDTA_Type,d0 + move.l (in_Icon,a1),a0 + move.l a7,a1 + move.l intbase(pc),a6 + JSRLIB GetAttr + clr.l -(a7) + move.l #IDTA_Type,d0 + move.l (in_Icon,a2),a0 + move.l a7,a1 + JSRLIB GetAttr + move.l (a7)+,d0 + move.l (a7)+,d1 + cmp.l #WBDRAWER,d0 ;Drawer ? + beq.s .firstdir + cmp.l #WBDRAWER,d1 ;Drawer ? + bne.s .files + bra.s .greater +.firstdir: + cmp.l #WBDRAWER,d1 ;Drawer ? + bne.s .smaller +.files: move.l (a7)+,a1 +.noint: move.l (in_Name,a2),a0 + move.l (in_Name,a1),a1 + tst.l a0 + beq .NullName + tst.l a1 + beq .NullName + move.l utilbase(pc),a6 + JSRLIB Stricmp + move.l (a7)+,a6 + rts +.NullName: + moveq #1,d0 + move.l (a7)+,a6 + rts +.greater: + moveq #1,d0 + bra.s .end +.smaller: + moveq #-1,d0 +.end: addq.w #4,a7 + move.l (a7)+,a6 + rts + + +;--------------------------- DoMethod -------------------------------------- + +_DoMethod: ;Standard-Function !! DON'T REMOVE !! + movem.l d1/a0-a2/a6,-(a7) + move.l (a1)+,a2 + cmp.w #0,a2 + beq.s .do + move.l -4(a2),a0 + move.l 8(a0),a6 + jsr (a6) + movem.l (a7)+,d1/a0-a2/a6 + rts +.do: moveq #0,d0 + movem.l (a7)+,d1/a0-a2/a6 + rts + +;---------------------------------------------------------------------------- + +seglist: dc.l 0 +scabase: dc.l 0 +utilbase: dc.l 0 +intbase: dc.l 0 + +scaname: dc.b 'scalos.library',0 +utilname: dc.b 'utility.library',0 +intname: dc.b 'intuition.library',0 + +; this is the name that the device will have +subSysName: + IFGE INFO_LEVEL-1 + dc.b '.',0 ; Dummy, für PUTMSG + ENDC + +endep: + diff --git a/scalos/Plugins/Menu/makefile b/scalos/Plugins/Menu/makefile new file mode 100644 index 000000000..6d673695b --- /dev/null +++ b/scalos/Plugins/Menu/makefile @@ -0,0 +1,42 @@ +# makefile for Scalos Menu plugins +# $Date$ +# $Revision$ + +############################################################# + +SUBDIRS = Sorted_Cleanup \ + +############################################################# + +.PHONY: All install clean + +############################################################# + +define build_subdir +$(MAKE) -s --directory=$(1); +endef + +define install_subdir +$(MAKE) -s install --directory=$(1); +endef + +define clean_subdir +$(MAKE) -s clean --directory=$(1); +endef + +############################################################# + +All: + @$(foreach subdir,$(SUBDIRS),$(call build_subdir,$(subdir))) + +############################################################# + +install: + @$(foreach subdir,$(SUBDIRS),$(call install_subdir,$(subdir))) + +############################################################# + +clean: + @$(foreach subdir,$(SUBDIRS),$(call clean_subdir,$(subdir))) + +############################################################# diff --git a/scalos/Plugins/OOP/DeviceFilter/config.mk b/scalos/Plugins/OOP/DeviceFilter/config.mk new file mode 100755 index 000000000..a31e3105c --- /dev/null +++ b/scalos/Plugins/OOP/DeviceFilter/config.mk @@ -0,0 +1,69 @@ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +COMMON_DIR = $(TOPLEVEL)/common/Plugin + +INCLUDES += -I$(COMMON_DIR) + +vpath %.c $(COMMON_DIR) + +############################################################################## + +include $(COMMON_DIR)/config.mk + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += -nostartfiles \ + -lmempools +# + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += -nostartfiles \ +# + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +LFLAGS += -nostartfiles \ +# + + +else + +############################################################################### +# AmigaOS + +LFLAGS += -lscalos \ + -lpreferences \ + -liconobject \ + -lmempools \ + -lstack \ + -lnix \ + -lnixmain \ + -lamiga21 \ + -lamiga \ + -lstubs \ + +endif +endif +endif diff --git a/scalos/Plugins/OOP/DeviceFilter/devicefilter.c b/scalos/Plugins/OOP/DeviceFilter/devicefilter.c new file mode 100644 index 000000000..f80e6546b --- /dev/null +++ b/scalos/Plugins/OOP/DeviceFilter/devicefilter.c @@ -0,0 +1,867 @@ +// devicefilter.c +// $Date$ +// $Revision$ + +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include "devicefilter.h" + +//----------------------------------------------------------------- + +#define WBPREFSNAME "ENV:sys/workbench.prefs" + +struct HiddenDevice + { + struct Node hd_Node; + char hd_Name[1]; // variable length + }; + +struct HiddenDevVol + { + struct Node hdv_Node; + STRPTR hdv_DeviceName; + STRPTR hdv_VolumeName; + }; + +//----------------------------------------------------------------- + +static BOOL OpenLibraries(void); +static void CloseLibraries(void); +static void FilterDevices(struct ScalosNodeList *devices); +static void HiddenDevicesCleanup(void); +static void HandleWBHD(CONST_STRPTR data, size_t length, struct List *HiddenDevsList); +static void FillHiddenDevicesList(void); +static void AddHiddenDeviceFromDosList(struct DosList *dl, struct InfoData *id, + BOOL Hidden, struct List *HiddenDevsList); +static void BtoCString(BPTR bstring, STRPTR Buffer, size_t Length); +static BOOL AddHiddenDevice(CONST_STRPTR Name, struct List *HiddenDevsList); +static BOOL FindHiddenDevice(CONST_STRPTR DevName, CONST_STRPTR VolName); +static void StripTrailingColon(STRPTR Line); +static APTR MyAllocVecPooled(size_t Size); +static void MyFreeVecPooled(APTR mem); +static void AddHiddenDevVol(CONST_STRPTR DevName, CONST_STRPTR VolName); +static BOOL StartWBPrefsProcess(void); +static SAVEDS(int) WBPrefsProcess(void); + +//---------------------------------------------------------------------------- + +// Some information for the library structure of the plugin. You should keep these +// variable names as they but feel free to change the contents + + +// Things we'll be using in this source +extern struct ExecBase *SysBase; +struct DosLibrary *DOSBase; +struct Library *IFFParseBase; +T_UTILITYBASE UtilityBase; + +#ifdef __amigaos4__ +struct IntuitionBase *IntuitionBase; +struct Library *NewlibBase; +#endif /* __amigaos4__ */ + +#ifdef __amigaos4__ +struct DOSIFace *IDOS = NULL; +struct UtilityIFace *IUtility = NULL; +struct IntuitionIFace *IIntuition = NULL; +struct IFFParseIFace *IIFFParse = NULL; +struct Interface *INewlib = NULL; +#endif /* __amigaos4__ */ + +static void *MemPool; + +static struct List HiddenDevicesList; +static struct SignalSemaphore HiddenDevicesSema; + +static struct SignalSemaphore PubMemPoolSemaphore; +static struct Process *WBPrefsProc; + +//---------------------------------------------------------------------------- + +// Plugin/library initialisation routine. Called once at OpenLibrary. +BOOL initPlugin(struct PluginBase *pluginbase) +{ + if (!OpenLibraries()) + return FALSE; + + d1(KPrintF("%s/%s/%ld: SysBase=%08lx DOSBase=%08lx\n", __FILE__, __FUNC__, __LINE__, SysBase, DOSBase)); + + NewList(&HiddenDevicesList); + InitSemaphore(&HiddenDevicesSema); + InitSemaphore(&PubMemPoolSemaphore); + + MemPool = CreatePool(MEMPOOL_MEMFLAGS, MEMPOOL_PUDDLESIZE, MEMPOOL_THRESHSIZE); + d1(KPrintF("%s/%ld: MemPool=%08lx\n", __FUNC__, __LINE__, MemPool)); + if (NULL == MemPool) + return FALSE; + + if (!StartWBPrefsProcess()) + return FALSE; + + d1(KPrintF(__FILE__ "/%s/%ld: Success\n", __FUNC__, __LINE__)); + + return TRUE; +} + + +// Plugin/library cleanup routine. Called at library expunge. +void closePlugin(struct PluginBase *pluginbase) +{ + (void)pluginbase; + + d1(KPrintF(__FILE__ "/%s/%ld: END\n", __FUNC__, __LINE__)); + + if (WBPrefsProc) + { + Signal((struct Task *) WBPrefsProc, SIGF_ABORT); + Delay(5); // wait for WBPrefs process to finish + } + + HiddenDevicesCleanup(); + + if (NULL != MemPool) + { + DeletePool(MemPool); + MemPool = NULL; + } + + CloseLibraries(); +} + +//----------------------------------------------------------------- + +// Opens all the libraries we need +static BOOL OpenLibraries(void) +{ + DOSBase = (struct DosLibrary *) OpenLibrary(DOSNAME, 39); + if (NULL == DOSBase ) + return FALSE; +#ifdef __amigaos4__ + IDOS = (struct DOSIFace *) GetInterface((struct Library *)DOSBase, "main", 1, NULL); + if (NULL == IDOS) + return FALSE; +#endif /* __amigaos4__ */ + + UtilityBase = (T_UTILITYBASE) OpenLibrary("utility.library", 39); + if (NULL == UtilityBase) + return FALSE; +#ifdef __amigaos4__ + IUtility = (struct UtilityIFace *)GetInterface((struct Library *)UtilityBase, "main", 1, NULL); + if (NULL == IUtility) + return FALSE; +#endif /* __amigaos4__ */ + +#ifdef __amigaos4__ + IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0); + if (NULL == IntuitionBase) + return FALSE; + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + return FALSE; +#endif /* __amigaos4__ */ + + IFFParseBase = OpenLibrary("iffparse.library", 39); + if (NULL == IFFParseBase) + return FALSE; +#ifdef __amigaos4__ + IIFFParse = (struct IFFParseIFace *) GetInterface(IFFParseBase, "main", 1, NULL); + if (NULL == IIFFParse) + return FALSE; + + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + return FALSE; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + return FALSE; +#endif /* __amigaos4__ */ + + return(TRUE); +} + + +// Closes all the opened libraries +static void CloseLibraries(void) +{ +#ifdef __amigaos4__ + if (INewlib) + { + DropInterface(INewlib); + INewlib = NULL; + } + if (NewlibBase) + { + CloseLibrary(NewlibBase); + NewlibBase = NULL; + } + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } + if (IntuitionBase) + { + CloseLibrary((struct Library *)IntuitionBase); + IntuitionBase = NULL; + } +#endif /* __amigaos4__ */ + +#ifdef __amigaos4__ + if (IIFFParse) + { + DropInterface((struct Interface *) IIFFParse); + IIFFParse = NULL; + } +#endif /* __amigaos4__ */ + if (IFFParseBase) + { + CloseLibrary(IFFParseBase); + IFFParseBase = NULL; + } + +#ifdef __amigaos4__ + if (IUtility) + { + DropInterface((struct Interface *)IUtility); + IUtility = NULL; + } +#endif /* __amigaos4__ */ + if (UtilityBase) + { + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } + +#ifndef __amigaos4__ + if (DOSBase) + { + CloseLibrary((struct Library *)DOSBase); + DOSBase = NULL; + } +#endif /* __amigaos4__ */ +} + +//----------------------------------------------------------------- + +/* The dispatcher hook which deals with the messages sent and calls the appropriate functions + * In this case, the DeviceList.cla does not take a return value + * + * It might be an idea to have a switch() in the dispatcher to call functions + * to deal with whatever the messages are (if you intend to respond to multiple + * messages), but in this case, I'll just stick everything in the dispatcher. + */ +M68KFUNC_P3(ULONG, Dispatcher, + A0, Class *, cl, + A2, Object *, obj, + A1, Msg, msg) +{ + ULONG Result = 0; + + if (msg) + { + /* Check message pointer, cure an enforcer hit? */ + + if (SCCM_DeviceList_Filter == msg->MethodID) + { + FilterDevices(((struct DeviceList_Filter_Msg *)msg)->devicenodes); + } + + // Call the original filter + Result = DoSuperMethodA(cl, obj, msg); + } + + return Result; +} +M68KFUNC_END + +//----------------------------------------------------------------- + +static void FilterDevices(struct ScalosNodeList *devices) +{ + struct ScaDeviceIcon *dev; // Current node in the list of devices Scalos provides + + d1(KPrintF(__FILE__ "/%s/%ld: START\n", __FUNC__, __LINE__)); + + ObtainSemaphoreShared(&HiddenDevicesSema); + + dev = (struct ScaDeviceIcon *) devices->snl_MinNode; + while (dev) + { + // Make sure device will be shown, then we hide it if required + dev->di_Flags &= ~(DIBF_DontDisplay); + + d1(KPrintF("%s/%s/%ld: Device=%08lx DiskType=%08lx Devname=<%s> di_Flags=%04x\n", __FILE__, __FUNC__, __LINE__, dev, dev->di_Info->id_DiskType, dev->di_Device, dev->di_Flags)); + + if ((dev->di_Info) && (ID_UNREADABLE_DISK == dev->di_Info->id_DiskType || ID_NOT_REALLY_DOS == dev->di_Info->id_DiskType)) + { + d1(KPrintF("%s/%s/%ld: NDOS or BAD\n", __FILE__, __FUNC__, __LINE__)); + dev->di_Flags |= DIBF_DontDisplay; + } + else + { + const struct HiddenDevVol *hdv; + + for (hdv = (const struct HiddenDevVol *) HiddenDevicesList.lh_Head; + hdv != (const struct HiddenDevVol *) &HiddenDevicesList.lh_Tail; + hdv = (const struct HiddenDevVol *) hdv->hdv_Node.ln_Succ) + { + d1(KPrintF("%s/%s/%ld: hdv=%08lx hdv_DeviceName=<%s> hvd_VolumeName=<%s>\n", __FILE__, __FUNC__, __LINE__, hdv, hdv->hdv_DeviceName, hdv->hdv_VolumeName)); + + if ((dev->di_Device && (0 == Stricmp(hdv->hdv_DeviceName, dev->di_Device))) + || (dev->di_Volume && (0 == Stricmp(hdv->hdv_VolumeName, dev->di_Volume)))) + { + d1(KPrintF("%s/%s/%ld: Matched\n", __FILE__, __FUNC__, __LINE__)); + dev->di_Flags |= DIBF_DontDisplay; + break; + } + } + } + dev = (struct ScaDeviceIcon *) dev->di_Node.mln_Succ; + } + + ReleaseSemaphore(&HiddenDevicesSema); +} + +//----------------------------------------------------------------- + +static void HiddenDevicesCleanup(void) +{ + struct HiddenDevVol *hdv; + + d1(KPrintF(__FILE__ "/%s/%ld: START\n", __FUNC__, __LINE__)); + + ObtainSemaphore(&HiddenDevicesSema); + + while ((hdv = (struct HiddenDevVol *) RemHead(&HiddenDevicesList))) + { + d1(KPrintF("%s/%ld: hdv=%08lx DevName=<%s> VolName=<%s>\n", __FUNC__, __LINE__, hdv, hdv->hdv_DeviceName, hdv->hdv_VolumeName)); + d1(KPrintF("%s/%ld: hdv=%08lx DevName=%08lx VolName=%08lx\n", __FUNC__, __LINE__, hdv, hdv->hdv_DeviceName, hdv->hdv_VolumeName)); + if (hdv->hdv_DeviceName) + { + MyFreeVecPooled(hdv->hdv_DeviceName); + hdv->hdv_DeviceName = NULL; + } + if (hdv->hdv_VolumeName) + { + MyFreeVecPooled(hdv->hdv_VolumeName); + hdv->hdv_VolumeName = NULL; + } + + MyFreeVecPooled(hdv); + } + + ReleaseSemaphore(&HiddenDevicesSema); + + d1(KPrintF(__FILE__ "/%s/%ld: END\n", __FUNC__, __LINE__)); +} + +//----------------------------------------------------------------- + +// Read workbench.prefs and build list of hidden devices +static BOOL ReadWorkbenchPrefs(CONST_STRPTR filename, struct List *HiddenDevsList) +{ + struct IFFHandle *iff; + LONG error; + BOOL IffOpened = FALSE; + static const ULONG pairs[] = {ID_PREF, ID_WBHD}; + + + d1(KPrintF(__FILE__ "/%s/%ld: START filename=<%s>\n", __FUNC__, __LINE__, filename)); + + do { + iff = AllocIFF(); + if (NULL == iff) + break; + + iff->iff_Stream = (ULONG) Open((STRPTR) filename, MODE_OLDFILE); + d1(KPrintF(__FILE__ "/%s/%ld: iff_Stream=%08lx\n", __FUNC__, __LINE__, iff->iff_Stream)); + if (0 == iff->iff_Stream) + break; + + InitIFFasDOS( iff ); + + error = OpenIFF( iff, IFFF_READ ); + d1(KPrintF(__FILE__ "/%s/%ld: error=%ld\n", __FUNC__, __LINE__, error)); + if (RETURN_OK != error) + break; + + IffOpened = TRUE; + + error = CollectionChunks( iff, (LONG*) pairs, Sizeof(pairs) / 2); + d1(KPrintF(__FILE__ "/%s/%ld: error=%ld\n", __FUNC__, __LINE__, error)); + if (RETURN_OK != error) + break; + + StopOnExit( iff, ID_PREF, ID_FORM ); + + while(TRUE) + { + if( ( error = ParseIFF( iff, IFFPARSE_SCAN ) ) == IFFERR_EOC ) + { + struct CollectionItem *ci; + + ci = FindCollection( iff, ID_PREF, ID_WBHD); + while( ci ) + { + HandleWBHD(ci->ci_Data, ci->ci_Size, HiddenDevsList); + ci = ci->ci_Next; + } + + } + else + break; + } + } while (0); + + if (iff) + { + if (IffOpened) + CloseIFF( iff ); + if (iff->iff_Stream) + Close((BPTR) iff->iff_Stream ); + FreeIFF( iff ); + } + + d1(KPrintF(__FILE__ "/%s/%ld: END\n", __FUNC__, __LINE__)); + + return TRUE; +} + +//----------------------------------------------------------------- + +static void HandleWBHD(CONST_STRPTR data, size_t length, struct List *HiddenDevsList) +{ + d1(KPrintF(__FILE__ "/%s/%ld: data=<%s> length=%lu\n", __FUNC__, __LINE__, data, length)); + + AddHiddenDevice(data, HiddenDevsList); +} + +//----------------------------------------------------------------- + +// Traverse DosList for all devices, and build list of hideable devices +static void FillHiddenDevicesList(void) +{ + ULONG LockDosListFlags = LDF_DEVICES | LDF_READ; + struct HiddenDevice *hd; + struct DosList *dl; + struct InfoData *id; + struct List WBHiddenDevList; + + d1(KPrintF(__FILE__ "/%s/%ld: START\n", __FUNC__, __LINE__)); + + NewList(&WBHiddenDevList); + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + HiddenDevicesCleanup(); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + ReadWorkbenchPrefs(WBPREFSNAME, &WBHiddenDevList); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + id = MyAllocVecPooled(sizeof(struct InfoData)); + d1(KPrintF(__FILE__ "/%s/%ld: id=%08lx\n", __FUNC__, __LINE__, id)); + if (NULL == id) + { + d1(KPrintF(__FILE__ "/%s/%ld: END\n", __FUNC__, __LINE__)); + return; + } + + dl = LockDosList(LockDosListFlags); + + while (dl = NextDosEntry(dl, LockDosListFlags)) + { + AddHiddenDeviceFromDosList(dl, id, FALSE, &WBHiddenDevList); + } + + UnLockDosList(LockDosListFlags); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + // Now walk through the list of devices marked as hidden, + // and add all entries. + + dl = LockDosList(LockDosListFlags); + + for (hd = (struct HiddenDevice *) WBHiddenDevList.lh_Head; + hd != (struct HiddenDevice *) &WBHiddenDevList.lh_Tail; + hd = (struct HiddenDevice *) hd->hd_Node.ln_Succ) + { + char HiddenDevName[128]; + struct DosList *dlFound; + + // Name must not have trailing ":" to use with FindDosEntry() + stccpy(HiddenDevName, hd->hd_Name, sizeof(HiddenDevName)); + StripTrailingColon(HiddenDevName); + + d1(KPrintF(__FILE__ "/%s/%ld: HiddenDevName=<%s>\n", __FUNC__, __LINE__, HiddenDevName)); + + dlFound = FindDosEntry(dl, HiddenDevName, LockDosListFlags); + d1(KPrintF(__FILE__ "/%s/%ld: dl=%08lx\n", __FUNC__, __LINE__, dlFound)); + if (dlFound) + { + AddHiddenDeviceFromDosList(dlFound, id, TRUE, &WBHiddenDevList); + } + else + { + AddHiddenDevVol(hd->hd_Name, ""); + } + } + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + MyFreeVecPooled(id); + UnLockDosList(LockDosListFlags); + + while ((hd = (struct HiddenDevice *) RemHead(&WBHiddenDevList))) + { + MyFreeVecPooled(hd); + } + + d1(KPrintF(__FILE__ "/%s/%ld: END\n", __FUNC__, __LINE__)); +} + +//----------------------------------------------------------------- + +static void AddHiddenDeviceFromDosList(struct DosList *dl, struct InfoData *id, + BOOL Hidden, struct List *HiddenDevsList) +{ + char DevName[128]; + char VolName[128]; + struct DosList *VolumeNode; + BOOL InfoDataValid = FALSE; + + d1(KPrintF(__FILE__ "/%s/%ld: START\n", __FUNC__, __LINE__)); + + strcpy(VolName, ""); + + if (dl->dol_Task && + DoPkt(dl->dol_Task, ACTION_DISK_INFO, + (IPTR)MKBADDR(id), + 0, 0, 0, 0)) + { + InfoDataValid = TRUE; + } + + if (!Hidden && !InfoDataValid) + { + d1(KPrintF(__FILE__ "/%s/%ld: END Hidden=%ld InfoDataValid=%ld\n", __FUNC__, __LINE__, Hidden, InfoDataValid)); + return; + } + + d1(KPrintF(__FILE__ "/%s/%ld: ACTION_DISK_INFO Success\n", __FUNC__, __LINE__)); + + BtoCString(dl->dol_Name, DevName, sizeof(DevName)); + + d1(KPrintF(__FILE__ "/%s/%ld: DevName=<%s>\n", __FUNC__, __LINE__, DevName)); + + if (InfoDataValid) + { + switch (id->id_DiskState) + { + case ID_WRITE_PROTECTED: + case ID_VALIDATING: + case ID_VALIDATED: + VolumeNode = BADDR(id->id_VolumeNode); + if (VolumeNode) + { + BtoCString(VolumeNode->dol_Name, VolName, sizeof(VolName)); + StripTrailingColon(VolName); + strcat(VolName, ":"); + } + break; + default: + break; + } + } + + StripTrailingColon(DevName); + strcat(DevName, ":"); + + d1(KPrintF(__FILE__ "/%s/%ld: VolName=<%s>\n", __FUNC__, __LINE__, VolName)); + + // add only visible devices here + if (Hidden) + { + AddHiddenDevVol(DevName, VolName); + } + + d1(KPrintF(__FILE__ "/%s/%ld: END\n", __FUNC__, __LINE__)); +} + +//----------------------------------------------------------------- + +static void BtoCString(BPTR bstring, STRPTR Buffer, size_t Length) +{ +#ifdef __AROS__ + // AROS needs special handling because it uses NULL-terminated + // strings on some platforms. + size_t Len = AROS_BSTR_strlen(bstring); + if (Len >= Length) + Len = Length - 1; + strncpy(Buffer, AROS_BSTR_ADDR(bstring), Len); + Buffer[Len] = '\0'; +#else + CONST_STRPTR Src = BADDR(bstring); + size_t bLength; + + // get BSTRING length (1st octet) + bLength = *Src++; + + while (bLength-- && (Length-- > 1)) + *Buffer++ = *Src++; + + *Buffer = '\0'; +#endif +} + +//----------------------------------------------------------------- + +// Add entry to hidden devices list +static BOOL AddHiddenDevice(CONST_STRPTR Name, struct List *HiddenDevsList) +{ + struct HiddenDevice *hd; + BOOL Success = FALSE; + + hd = MyAllocVecPooled(sizeof(struct HiddenDevice) + 1 + strlen(Name)); + if (hd) + { + strcpy(hd->hd_Name, Name); + + // make sure device name is terminated with exactly one ":" + StripTrailingColon(hd->hd_Name); + strcat(hd->hd_Name, ":"); + + AddHead(HiddenDevsList, &hd->hd_Node); + Success = TRUE; + } + + d1(KPrintF(__FILE__ "/%s/%ld: Name=<%s> hd=%08lx\n", __FUNC__, __LINE__, Name, hd)); + + return Success; +} + +//----------------------------------------------------------------- + +// search for entry in hidden devices list +static BOOL FindHiddenDevice(CONST_STRPTR DevName, CONST_STRPTR VolName) +{ + const struct HiddenDevVol *hdv; + BOOL Found = FALSE; + + d1(KPrintF(__FILE__ "/%s/%ld: DevName=<%s> VolName=<%s>\n", __FUNC__, __LINE__, DevName, VolName)); + + for (hdv = (struct HiddenDevVol *) HiddenDevicesList.lh_Head; + hdv->hdv_Node.ln_Succ; + hdv = (struct HiddenDevVol *) hdv->hdv_Node.ln_Succ) + { + d1(KPrintF("%s/%ld: hdv=%08lx DevName=%08lx VolName=%08lx\n", __FUNC__, __LINE__, hdv, hdv->hdv_DeviceName, hdv->hdv_VolumeName)); + d1(KPrintF(__FILE__ "/%s/%ld: hdv=%08lx ln_Succ=%08lx\n", __FUNC__, __LINE__, hdv, hdv->hdv_Node.ln_Succ)); + if (0 == Stricmp(DevName, hdv->hdv_DeviceName) + || 0 == Stricmp(VolName, hdv->hdv_VolumeName)) + { + Found = TRUE; + break; + } + } + + return Found; +} + +//----------------------------------------------------------------- + +static void StripTrailingColon(STRPTR Line) +{ + size_t Len = strlen(Line); + + Line += Len - 1; + + if (':' == *Line) + *Line = '\0'; +} + +//----------------------------------------------------------------- + +static APTR MyAllocVecPooled(size_t Size) +{ + APTR ptr; + + if (MemPool) + { + ObtainSemaphore(&PubMemPoolSemaphore); + ptr = AllocPooled(MemPool, Size + sizeof(size_t)); + ReleaseSemaphore(&PubMemPoolSemaphore); + if (ptr) + { + size_t *sptr = (size_t *) ptr; + + sptr[0] = Size; + + d1(kprintf("%s/%ld: MemPool=%08lx Size=%lu mem=%08lx\n", __FUNC__, __LINE__, MemPool, Size, &sptr[1])); + return (APTR)(&sptr[1]); + } + } + + d1(kprintf("%s/%ld: MemPool=%08lx Size=%lu\n", __FUNC__, __LINE__, MemPool, Size)); + + return NULL; +} + + +static void MyFreeVecPooled(APTR mem) +{ + d1(kprintf("%s/%ld: MemPool=%08lx mem=%08lx\n", __FUNC__, __LINE__, MemPool, mem)); + if (MemPool && mem) + { + size_t size; + size_t *sptr = (size_t *) mem; + + mem = &sptr[-1]; + size = sptr[-1]; + + ObtainSemaphore(&PubMemPoolSemaphore); + FreePooled(MemPool, mem, size + sizeof(size_t)); + ReleaseSemaphore(&PubMemPoolSemaphore); + } +} + +//----------------------------------------------------------------- + +static void AddHiddenDevVol(CONST_STRPTR DevName, CONST_STRPTR VolName) +{ + d1(KPrintF(__FILE__ "/%s/%ld: START\n", __FUNC__, __LINE__)); + + ObtainSemaphore(&HiddenDevicesSema); + + if (!FindHiddenDevice(DevName, VolName)) + { + struct HiddenDevVol *hdv; + + hdv = MyAllocVecPooled(sizeof(struct HiddenDevVol)); + if (hdv) + { + d1(KPrintF("%s/%ld: hdv=%08lx DevName=<%s> VolName=<%s>\n", __FUNC__, __LINE__, hdv, DevName, VolName)); + + hdv->hdv_DeviceName = MyAllocVecPooled(1 + strlen(DevName)); + if (hdv->hdv_DeviceName) + strcpy(hdv->hdv_DeviceName, DevName); + + hdv->hdv_VolumeName = MyAllocVecPooled(1 + strlen(VolName)); + if (hdv->hdv_VolumeName) + strcpy(hdv->hdv_VolumeName, VolName); + + d1(KPrintF("%s/%ld: hdv=%08lx DevName=%08lx VolName=%08lx\n", __FUNC__, __LINE__, hdv, hdv->hdv_DeviceName, hdv->hdv_VolumeName)); + + AddTail(&HiddenDevicesList, &hdv->hdv_Node); + } + } + + ReleaseSemaphore(&HiddenDevicesSema); + + d1(KPrintF(__FILE__ "/%s/%ld: END\n", __FUNC__, __LINE__)); +} + +//----------------------------------------------------------------- + +static BOOL StartWBPrefsProcess(void) +{ + STATIC_PATCHFUNC(WBPrefsProcess) + + FillHiddenDevicesList(); + + // CreateNewProc() + WBPrefsProc = CreateNewProcTags(NP_Name, (ULONG) "Scalos_DeviceFilter_WBPrefs", + NP_Priority, 0, + NP_Entry, (ULONG) PATCH_NEWFUNC(WBPrefsProcess), + NP_StackSize, 32768, + TAG_END); + d1(KPrintF(__FILE__ "/%s/%ld: WBPrefsProc=%08lx\n", __FUNC__, __LINE__, WBPrefsProc)); + if (WBPrefsProc == NULL) + { + return FALSE; + } + + return TRUE; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(int) WBPrefsProcess(void) +{ + ULONG mySignalBit; + struct NotifyRequest nr; + BOOL NotifyStarted = FALSE; + + d1(KPrintF(__FUNC__ "/%ld START\n", __LINE__);) + + do { + mySignalBit = AllocSignal(-1); + if (-1 == mySignalBit) + break; + + d1(KPrintF(__FILE__ "/%s/%ld: mySignalBit=%ld\n", __FUNC__, __LINE__, mySignalBit)); + + memset(&nr, 0, sizeof(nr)); + nr.nr_Name = (STRPTR) WBPREFSNAME; + nr.nr_Flags = NRF_SEND_SIGNAL; + nr.nr_stuff.nr_Signal.nr_Task = FindTask(NULL); + nr.nr_stuff.nr_Signal.nr_SignalNum = mySignalBit; + + if (!StartNotify(&nr)) + break; + + d1(KPrintF(__FILE__ "/%s/%ld: StartNotify succeeded\n", __FUNC__, __LINE__)); + NotifyStarted = TRUE; + + while (1) + { + ULONG Signals = Wait((1UL << mySignalBit) | SIGF_ABORT); + + d1(KPrintF(__FILE__ "/%s/%ld: Signals=%08lx\n", __FUNC__, __LINE__, Signals)); + + if (Signals & SIGF_ABORT) + break; + + if (Signals & (1UL << mySignalBit)) + FillHiddenDevicesList(); + } + + } while (0); + + if (NotifyStarted) + EndNotify(&nr); + if (-1 != mySignalBit) + FreeSignal(mySignalBit); + + d1(KPrintF(__FUNC__ "/%ld END\n", __LINE__);) + + return 0; +} + +//---------------------------------------------------------------------------- + + diff --git a/scalos/Plugins/OOP/DeviceFilter/devicefilter.h b/scalos/Plugins/OOP/DeviceFilter/devicefilter.h new file mode 100644 index 000000000..6a3312a78 --- /dev/null +++ b/scalos/Plugins/OOP/DeviceFilter/devicefilter.h @@ -0,0 +1,58 @@ +// devicefilter.h +// $Date$ +// $Revision$ + +#ifndef DEVICEFILTER_H_INCLUDED +#define DEVICEFILTER_H_INCLUDED + +#include + +#include "plugin.h" + +//----------------------------------------------------------------------------- + +#define MEMPOOL_MEMFLAGS MEMF_PUBLIC +#define MEMPOOL_PUDDLESIZE 4096 +#define MEMPOOL_THRESHSIZE 4096 + +//---------------------------------------------------------------------------- + +#define Sizeof(array) (sizeof(array) / sizeof(array[0])) + +//---------------------------------------------------------------------------- + +#define d(x) ; +#define d1(x) ; +#define d2(x) x; + +// from debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +//---------------------------------------------------------------------------- + +#if defined(__GNUC__) && !defined(mc68000) +#pragma pack(2) +#endif /* __GNUC__ */ + +// DeviceFilter library base +struct DeviceFilterBase + { + struct PluginBase df_LibNode; + }; + +#if defined(__GNUC__) && !defined(mc68000) +#pragma pack() +#endif /* __GNUC__ */ + +// Structure of the messages we want to be looking at +struct DeviceList_Filter_Msg +{ + ULONG MethodID; + struct ScalosNodeList *devicenodes; +}; + +//---------------------------------------------------------------------------- + +#endif /* DEVICEFILTER_H_INCLUDED */ + diff --git a/scalos/Plugins/OOP/DeviceFilter/makefile b/scalos/Plugins/OOP/DeviceFilter/makefile new file mode 100755 index 000000000..95853c4a1 --- /dev/null +++ b/scalos/Plugins/OOP/DeviceFilter/makefile @@ -0,0 +1,106 @@ +# makefile for devicefilter.plugin +# $Date$ +# $Revision$ +# using SAS/C + +############################################################# + +.PHONY: clean install nodebug + +.SUFFIXES: .s .asm .plugin .plugin.debug + +############################################################# + + +CHEADERS = devicefilter.h plugin_data.h $(COMMON_DIR)/plugin.h +CC = sc +CFLAGS = nostkchk nochkabort strcons strmer opt dbg=ff nover \ + streq data=far idir=sc:include/ idir=include: \ + idlen=64 idir=$(subst ../,/,$(COMMON_DIR)) idir=///include +SPLAT = sc:c/splat +AS = phxass +AFLAGS = quiet m=68020 linedebug opt=NRQB i=include: +LD = slink +ECHO = echo +LDFLAGS = quiet batch noicons sd +LDLIBS = LIB:sc.lib LIB:debug.lib LIB:amiga.lib +OBJDIR = .sasobj +COMMON_DIR = ../../../common/Plugin + +############################################################# + +PLUGNAME = devicefilter.plugin + +############################################################# + +all: $(PLUGNAME) $(PLUGNAME).debug +# install +# clean + +############################################################# + +CSRCS = $(COMMON_DIR)/plugin-classic.c \ + devicefilter.c + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +XSRCS = $(notdir $(CSRCS)) +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(XSRCS:%.c=$(OBJDIR)/$(notdir %).o) + +############################################################# + +$(OBJDIR)/devicefilter.o: $(CHEADERS) +$(OBJDIR)/plugin-classic.o: $(COMMON_DIR)/plugin-classic.c \ + $(COMMON_DIR)/plugin-common.c $(CHEADERS) + +############################################################# + +$(PLUGNAME): $(OBJS) + @printf '\033[32mLink: \033[1m\033[31m$@\033[0m\n' + @$(LD) FROM $(OBJS) TO $@ LIB $(LDLIBS) $(DBFLAG) $(LDFLAGS) stripdebug + +$(PLUGNAME).debug: $(OBJS) + @printf '\033[32mLink: \033[1m\033[31m$@\033[0m\n' + @$(LD) FROM $(OBJS) TO $@ LIB $(LDLIBS) $(DBFLAG) $(LDFLAGS) addsym + +############################################################# + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-classic.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[1m\033[31m$<\033[0m\n' + @$(CC) $(CFLAGS) $*.c objectname $@ + +$(OBJDIR)/%.o : %.s + @printf '\033[32mAssemble: \033[1m\033[31m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +$(OBJDIR)/%.o : %.asm + @printf '\033[32mAssemble: \033[1m\033[31m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +############################################################# + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(PLUGNAME)\033[0m\n' + @copy $(PLUGNAME) Scalos:Plugins/OOP clone + +############################################################# + +# A little something to clean it all up +clean: + @printf '\033[32mDelete: \033[31m\033[1m' + @delete $(OBJS) $(PLUGNAME) $(PLUGNAME).debug + @printf '\033[0m' + +############################################################# + +nodebug: + -@$(SPLAT) -s -o "d2(" "d1(" "#?.c" + +############################################################# diff --git a/scalos/Plugins/OOP/DeviceFilter/makefile-new b/scalos/Plugins/OOP/DeviceFilter/makefile-new new file mode 100755 index 000000000..508aeee98 --- /dev/null +++ b/scalos/Plugins/OOP/DeviceFilter/makefile-new @@ -0,0 +1,69 @@ +# $Date: 2011-08-02 00:13:23 +0200 (Di, 02. Aug 2011) $ +# $Revision: 816 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(BEGIN_OBJS) \ + $(OBJDIR)/devicefilter.o \ + $(END_OBJS) \ +# + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Targets +# + +NAME = devicefilter.plugin +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + $(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + copy $(BINDIR)/$(NAME) Scalos:Plugins/OOP clone + + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* + +############################################################################## + + diff --git a/scalos/Plugins/OOP/DeviceFilter/plugin_data.h b/scalos/Plugins/OOP/DeviceFilter/plugin_data.h new file mode 100644 index 000000000..12f602f51 --- /dev/null +++ b/scalos/Plugins/OOP/DeviceFilter/plugin_data.h @@ -0,0 +1,39 @@ +// plugin_data.h +// $Date$ +// $Revision$ + +#ifndef PLUGIN_DATA_H_INCLUDED +#define PLUGIN_DATA_H_INCLUDED + +#include +#include + +#define PLUGIN_TYPE OOP + +#define LIB_BASETYPE struct DeviceFilterBase + +#define LIB_VERSION 39 +#define LIB_REVISION 19 + +#define LIB_NAME "devicefilter.plugin" +#define LIB_VERSTRING "$VER: devicefilter.plugin " \ + STR(LIB_VERSION) "." STR(LIB_REVISION) \ + " (13.03.2007) " COMPILER_STRING \ + " ©1999" CURRENTYEAR " The Scalos Team" + + +#define CI_CLASSNAME "DeviceList.sca" +#define CI_SUPERCLASSNAME "DeviceList.sca" +#define CI_PLUGINNAME "Device Filter" +#define CI_DESCRIPTION "Filters out BAD and NDOS disks and devices " \ + "in the hidden list (in Workbench prefs) " COMPILER_STRING +#define CI_AUTHOR "Scalos Team" +#define CI_HOOKFUNC Dispatcher + +//---------------------------------------------------------------------------- +// code and includes to define the structs and functions used above + +#include "devicefilter.h" + +#endif /* PLUGUN_DATA_H_INCLUDED */ + diff --git a/scalos/Plugins/OOP/TitleClock/config.mk b/scalos/Plugins/OOP/TitleClock/config.mk new file mode 100755 index 000000000..0c2f0e918 --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/config.mk @@ -0,0 +1,67 @@ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +PREFS_DIR = ./prefs +COMMON_DIR = $(TOPLEVEL)/common/Plugin + +INCLUDES += -I$(COMMON_DIR) + +vpath %.c $(COMMON_DIR) $(PREFS_DIR) + +############################################################################## + +include $(COMMON_DIR)/config.mk + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += -nostartfiles \ + -lmempools +# + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += -nostartfiles \ +# + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +LFLAGS += -nostartfiles \ +# + +else + +############################################################################### +# AmigaOS + +LFLAGS += -lscalos \ + -lpreferences \ + -liconobject \ + -lmempools \ + -lstack \ + -lnix \ + -lnixmain \ + -lamiga21 \ + -lamiga \ + -lstubs \ + +endif +endif +endif diff --git a/scalos/Plugins/OOP/TitleClock/libbase.h b/scalos/Plugins/OOP/TitleClock/libbase.h new file mode 100755 index 000000000..5820ed809 --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/libbase.h @@ -0,0 +1,44 @@ +/* +** libbase.h + * + * $Date$ + * $Revision$ + * +** 5th May 2000 +** David McMinn +** The structure defining the library base of our example plugin +** (since plugins are nothing more than shared libraries) +*/ + +#ifndef LIBBASE_H +#define LIBBASE_H + +#include +#include +#include +#include +#include + +#include "plugin.h" + +#if defined(__GNUC__) && !defined(mc68000) +#pragma pack(2) +#endif /* __GNUC__ */ + +#define FORMAT_SIZE 32 + +struct myLibBase +{ + struct PluginBase lb_PluginBase; /* The actual Library structure for our librarybase, always first in a libbase */ + char lb_datestr[FORMAT_SIZE]; + char lb_timestr[FORMAT_SIZE]; + struct NotifyRequest lb_NotifyRequest; + struct MsgPort *lb_NotifyPort; +}; + +#if defined __GNUC__ && !defined(mc68000) +#pragma pack() +#endif /* __GNUC__ */ + +#endif + diff --git a/scalos/Plugins/OOP/TitleClock/libfuncs.c b/scalos/Plugins/OOP/TitleClock/libfuncs.c new file mode 100755 index 000000000..cd32ebbf5 --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/libfuncs.c @@ -0,0 +1,342 @@ +/* + * libfuncs.c + * + * $Date$ + * $Revision$ + * + */ + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include "prefs/prefs_file.h" +#include "libfuncs.h" + +/* +** The TITLETIME identifier (%ti in Scalos title prefs) adds the current time to the title bar. +** TITLEDATE adds %da so that the current date. Both are in their default locale. +*/ +#define TITLETIME 0x7469 +#define TITLEDATE 0x6461 + + +struct FormatDateHookData + { + STRPTR fdhd_Buffer; // buffer to write characters to + size_t fdhd_Length; // length of buffer + }; + + +struct DosLibrary *DOSBase; +T_LOCALEBASE LocaleBase; +#ifdef __amigaos4__ +struct IntuitionBase *IntuitionBase; +struct Library *NewlibBase; +#endif + +#ifdef __amigaos4__ +struct LocaleIFace *ILocale; +struct DOSIFace *IDOS; +struct IntuitionIFace *IIntuition; +struct Interface *INewlib; +#endif + +struct myLibBase *globalLibBase; + +STRPTR VersTag = LIB_VERSTRING; + +/* Hook function for FormatDate() which takes a character and pushes into + * the string specified in the hook.h_Data field + */ +static M68KFUNC_P3(void, FormatDateHookFunc, + A0, struct Hook *, theHook, + A2, struct Locale *, locale, + A1, char, ch) +{ + struct FormatDateHookData *fd = (struct FormatDateHookData *) theHook->h_Data; + + (void) locale; + + if (fd->fdhd_Length >= 1) + { + *(fd->fdhd_Buffer)++ = ch; + fd->fdhd_Length--; + } +} +M68KFUNC_END + + +/* The actual (hook) function which does the work for this plugin + + NAME + TimeDate + + SYNOPSIS + success = TimeDate(cls, object, message) + D0 A0 A2 A1 + + LONG = TimeDate(Class *, struct ScaRootList *, struct Title_Translate_Params *) + + FUNCTION + To add the current time and date to the title (bar) in Scalos + + INPUTS + cls - Pointer to the class from which this function was called + object - the ScaRootList pointer from Scalos + message - the message being passed to our function that we must act on + NB: These will always be the same except for the type of message that is + passed. Check scalos/scalos.h for what will be passed in the message for + a particular method. + + RESULT + success - boolean to show success or failure. + NB: This is different for different methods, so check what the return + value should be for a particular method in scalos/scalos.h + + SEE ALSO + scalos/scalos.h +*/ +M68KFUNC_P3(ULONG, TimeDate, + A0, Class *, cls, + A2, Object *, object, + A1, Msg, message) +{ + Class *keepclass = cls; /* a copy of the class just in case: register A0 is a scratch register remember */ + struct msg_Translate *msg = (struct msg_Translate *)message; /* a copy of the message just in case: register A1 is a scratch register remember */ + struct Locale *loc = NULL; /* So we can get the correct date/time format for the display */ + ULONG retval = 0; + BOOL dosup = TRUE; + + if (globalLibBase->lb_NotifyPort) + { + struct Message *msg; + BOOL ReloadPrefs = FALSE; + + d1(KPrintF(__FILE__ "/%s/%ld: check notification messages\n", __FUNC__, __LINE__)); + + while (msg = GetMsg(globalLibBase->lb_NotifyPort)) + { + d1(KPrintF(__FILE__ "/%s/%ld: msg=%08lx\n", __FUNC__, __LINE__, msg)); + ReloadPrefs = TRUE; + ReplyMsg(msg); + } + + if (ReloadPrefs) + { + LoadPrefs(globalLibBase->lb_datestr, FORMAT_SIZE, + globalLibBase->lb_timestr, FORMAT_SIZE); + d1(KPrintF(__FILE__ "/%s/%ld: date='%s' time='%s'\n", \ + __FUNC__, __LINE__, globalLibBase->lb_datestr, globalLibBase->lb_timestr)); + } + } + + /* Make sure that the method being called is the title translate method */ + if (msg->mxl_MethodID == SCCM_Title_Translate) + { + struct DateStamp ds; + struct FormatDateHookData fd; + struct Hook fmtHook; + STATIC_PATCHFUNC(FormatDateHookFunc) + + DateStamp(&ds); + + fmtHook.h_Entry = (HOOKFUNC) PATCH_NEWFUNC(FormatDateHookFunc); + fmtHook.h_Data = &fd; + + fd.fdhd_Buffer = msg->mxl_Buffer; + fd.fdhd_Length = msg->mxl_BuffLen; + + loc = OpenLocale(NULL); /* Guaranteed to be successful */ + + switch(msg->mxl_ParseID) + { + case TITLETIME: + if(*globalLibBase->lb_timestr) + { + FormatDate(loc, globalLibBase->lb_timestr, &ds, &fmtHook); + } + else + { + FormatDate(loc, loc->loc_TimeFormat, &ds, &fmtHook); + } + msg->mxl_BuffLen -= strlen(msg->mxl_Buffer); + msg->mxl_Buffer += strlen(msg->mxl_Buffer); + dosup = FALSE; + retval = 1; + break; + + case TITLEDATE: + if(*globalLibBase->lb_datestr) + { + FormatDate(loc, globalLibBase->lb_datestr, &ds, &fmtHook); + } + else + { + FormatDate(loc, loc->loc_DateFormat, &ds, &fmtHook); + } + msg->mxl_BuffLen -= strlen(msg->mxl_Buffer); + msg->mxl_Buffer += strlen(msg->mxl_Buffer); + dosup = FALSE; + retval = 1; + break; + } + } + + if (dosup) + { + /* Call superclass method if we have failed to do something (this method does not get processed by + ** this function, the parse characters were not what we were looking for, etc) */ + retval = DoSuperMethodA(keepclass, (Object *)object, (Msg) msg); + } + if (loc) + CloseLocale(loc); + + return(retval); +} +M68KFUNC_END + +BOOL initPlugin(struct PluginBase *pluginBase) +{ + struct myLibBase *myLibBase = (struct myLibBase *)pluginBase; + BOOL Success = FALSE; + + do { + globalLibBase = myLibBase; + + DOSBase = (struct DosLibrary *) OpenLibrary(DOSNAME, 36); + if (NULL == DOSBase) + break; +#ifdef __amigaos4__ + IDOS = (struct DOSIFace *)GetInterface((struct Library *)DOSBase, "main", 1, NULL); + if (NULL == IDOS) + break; +#endif + LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 0); + d1(KPrintF(__FILE__ "/%s/%ld: LocaleBase=0x%08X\n", __FUNC__, __LINE__, LocaleBase)); + if (NULL == LocaleBase) + break; +#ifdef __amigaos4__ + ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL); + if (NULL == ILocale) + break; + IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0); + if (NULL == IntuitionBase) + break; + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + break; + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + break; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + break; +#endif + + d1(KPrintF(__FILE__ "/%s/%ld: All libs OK\n", __FUNC__, __LINE__)); + + LoadPrefs(myLibBase->lb_datestr, FORMAT_SIZE, + myLibBase->lb_timestr, FORMAT_SIZE); + + d1(KPrintF(__FILE__ "/%s/%ld: LoadPrefs OK datestr=<%s> timestr=<%s>\n", \ + __FUNC__, __LINE__, myLibBase->lb_datestr, myLibBase->lb_timestr)); + + myLibBase->lb_NotifyPort = CreateMsgPort(); + d1(KPrintF(__FILE__ "/%s/%ld: NotifyPort=%08lx\n", __FUNC__, __LINE__, myLibBase->lb_NotifyPort)); + if (NULL == myLibBase->lb_NotifyPort) + break; + + myLibBase->lb_NotifyRequest.nr_Name = NULL; + myLibBase->lb_NotifyRequest.nr_UserData = (ULONG)NULL; + myLibBase->lb_NotifyRequest.nr_Flags = NRF_SEND_MESSAGE; + myLibBase->lb_NotifyRequest.nr_stuff.nr_Msg.nr_Port = myLibBase->lb_NotifyPort; + + (void) StartPrefsNotify(&myLibBase->lb_NotifyRequest); + + d1(KPrintF(__FILE__ "/%s/%ld: StartPrefsNotify OK\n", __FUNC__, __LINE__)); + + Success = TRUE; + + } while (0); + + return Success; +} + + +void closePlugin(struct PluginBase *pluginBase) +{ + struct myLibBase *myLibBase = (struct myLibBase *)pluginBase; + + EndPrefsNotify(&myLibBase->lb_NotifyRequest); + + if (myLibBase->lb_NotifyPort) + { + DeleteMsgPort(myLibBase->lb_NotifyPort); + myLibBase->lb_NotifyPort = NULL; + } +#ifdef __amigaos4_ + if (INewlib) + { + DropInterface(INewlib); + INewlib = NULL; + } + if (NewlibBase) + { + CloseLibrary(NewlibBase); + NewlibBase = NULL; + } + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } + if(IntuitionBase) + { + CloseLibrary((struct Library *)IntuitionBase); + IntuitionBase = NULL; + } + if(IDOS) + { + DropInterface((struct Interface *)IDOS); + IDOS = NULL; + } +#endif + if(DOSBase) + { + CloseLibrary((struct Library *)DOSBase); + DOSBase = NULL; + } +#ifdef __amigaos4_ + if(ILocale) + { + DropInterface((struct Interface *)ILocale); + ILocale = NULL; + } +#endif + if(LocaleBase) + { + CloseLibrary((struct Library *)LocaleBase); + LocaleBase = NULL; + } +} + + diff --git a/scalos/Plugins/OOP/TitleClock/libfuncs.h b/scalos/Plugins/OOP/TitleClock/libfuncs.h new file mode 100755 index 000000000..099992c09 --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/libfuncs.h @@ -0,0 +1,34 @@ +/* +** libfuncs.h + * + * $Date$ + * $Revision$ + * +** 20th May 2000 +** David McMinn +** Defines the prototypes for the only public function in the plugin +*/ + +#ifndef LIBFUNCS_H +#define LIBFUNCS_H + +#include + +#include "defs.h" +#include "libbase.h" + +LIBFUNC_PROTO(GetClassInfo, libbase, struct ScaClassInfo *); + +BOOL UserLibInit(struct myLibBase *myLibBase); +void UserLibCleanup(struct myLibBase *myLibBase); + +extern struct myLibBase *globalLibBase; + +#define d1(x) ; +#define d2(x) x; + +extern int KPrintF(CONST_STRPTR fmt, ...); +extern int kprintf(CONST_STRPTR fmt, ...); + +#endif + diff --git a/scalos/Plugins/OOP/TitleClock/makefile b/scalos/Plugins/OOP/TitleClock/makefile new file mode 100755 index 000000000..9d7ff5117 --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/makefile @@ -0,0 +1,107 @@ +# makefile for TitleClock.plugin +# $Date$ +# $Revision$ +# $Id$ +# using SAS/C + +############################################################# + +.SUFFIXES: .asm .plugin .plugin.debug + +############################################################# + +CHEADERS = libbase.h libfuncs.h plugin_data.h $(COMMON_DIR)/plugin.h +CC = sc +CFLAGS = nostkchk nochkabort strcons strmer opt dbg=ff nover \ + streq data=far idlen=64 idir=include: idir=$(subst ../,/,$(COMMON_DIR)) \ + idir=///include +LD = slink +ECHO = echo +LDFLAGS = QUIET NOICONS BATCH +LDLIBS = LIB:sc.lib LIB:debug.lib LIB:amiga.lib +OBJDIR = .sasobj +COMMON_DIR = ../../../common/Plugin +PREFS_DIR = prefs + +############################################################# + +PLUGNAME = title_clock.plugin + +############################################################# + +all: $(PLUGNAME) $(PLUGNAME).debug +# install +# clean + +############################################################# + +CSRCS = $(COMMON_DIR)/plugin-classic.c \ + libfuncs.c \ + $(PREFS_DIR)/prefs_file.c + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +XSRCS = $(notdir $(CSRCS)) +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(XSRCS:%.c=$(OBJDIR)/$(notdir %).o) + +############################################################# + +$(OBJDIR)/title_clock.o: $(CHEADERS) +$(OBJDIR)/plugin-classic.o: $(COMMON_DIR)/plugin-classic.c $(CHEADERS) + +############################################################# + +$(PLUGNAME) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(OBJS) TO $@ LIB $(LDLIBS) $(LDFLAGS) STRIPDEBUG + +$(PLUGNAME).debug : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(OBJS) TO $@ LIB $(LDLIBS) $(LDFLAGS) ADDSYM + +############################################################# + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-classic.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/prefs_file.o : $(PREFS_DIR)/prefs_file.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $< objectname $@ + +############################################################# + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $*.c objectname $@ + +$(OBJDIR)/%.o : %.s + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +$(OBJDIR)/%.o : %.asm + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +############################################################# + +$(OBJDIR)/libfuncs.o : $(CHEADERS) +$(OBJDIR)/prefs_file.o : $(PREFS_DIR)/prefs_file.h +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-common.c $(CHEADERS) + +############################################################# + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(PLUGNAME)\033[0m\n' + @copy $(PLUGNAME) Scalos:Plugins/OOP clone + +############################################################# + +# A little something to clean it all up +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + @delete $(OBJS) $(PLUGNAME) $(PLUGNAME).debug + @printf '\033[0m' diff --git a/scalos/Plugins/OOP/TitleClock/makefile-new b/scalos/Plugins/OOP/TitleClock/makefile-new new file mode 100755 index 000000000..38632b064 --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/makefile-new @@ -0,0 +1,78 @@ +# $Date: 2011-08-02 00:13:23 +0200 (Di, 02. Aug 2011) $ +# $Revision: 816 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(BEGIN_OBJS) \ + $(OBJDIR)/libfuncs.o \ + $(OBJDIR)/prefs_file.o \ + $(END_OBJS) \ +# + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################# +# +# Project subdirectories +# + +SUBDIRS = prefs \ + +############################################################################## +# +# Targets +# + +NAME = title_clock.plugin +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) \ + all_subdirs + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + $(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: install_subdirs + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) Scalos:Plugins/OOP clone + + +clean: clean_subdirs + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* + +############################################################################## + + diff --git a/scalos/Plugins/OOP/TitleClock/plugin_data.h b/scalos/Plugins/OOP/TitleClock/plugin_data.h new file mode 100644 index 000000000..f3686facc --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/plugin_data.h @@ -0,0 +1,42 @@ +// plugin_data.h +// $Date$ +// $Revision$ + +#ifndef PLUGIN_DATA_H_INCLUDED +#define PLUGIN_DATA_H_INCLUDED + +#include +#include + +#include +#include + +#define PLUGIN_TYPE OOP + +#define LIB_BASETYPE struct myLibBase + +#define LIB_VERSION 40 /* Version of our plugin */ +#define LIB_REVISION 5 /* Revision of our plugin */ +#define NAME "title_clock" /* Name of our plugin (must be the same as the executable filename minus the .plugin [gets added later]) */ +#define LIBVER STR(LIB_VERSION) "." STR(LIB_REVISION) /* part of the version string for our plugin */ + +#define LIB_NAME NAME ".plugin" +#define LIB_IDSTRING NAME LIBVER " " COMPILER_STRING +#define LIB_VERSTRING "\0$VER: " LIB_NAME " " LIBVER " (07.11.2009) " COMPILER_STRING \ + " ©2001" CURRENTYEAR " The Scalos Team" + +#define CI_CLASSNAME "Title.sca" +#define CI_SUPERCLASSNAME "Title.sca" +#define CI_PLUGINNAME "Title Clock" +#define CI_DESCRIPTION "%ti for current time and %da for date " COMPILER_STRING +#define CI_AUTHOR "The Scalos Team" + +#define CI_HOOKFUNC TimeDate + +//---------------------------------------------------------------------------- +// code and includes to define the structs and functions used above + +#include "libbase.h" + +#endif /* PLUGUN_DATA_H_INCLUDED */ + diff --git a/scalos/Plugins/OOP/TitleClock/prefs/cc_locale.h b/scalos/Plugins/OOP/TitleClock/prefs/cc_locale.h new file mode 100755 index 000000000..51ad659f8 --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/prefs/cc_locale.h @@ -0,0 +1,164 @@ +#ifndef CC_LOCALE_H +#define CC_LOCALE_H + + +/****************************************************************************/ + + +/* This file was created automatically by CatComp. + * Do NOT edit by hand! + */ + + +#ifndef EXEC_TYPES_H +#include +#endif + +#ifdef CATCOMP_ARRAY +#undef CATCOMP_NUMBERS +#undef CATCOMP_STRINGS +#define CATCOMP_NUMBERS +#define CATCOMP_STRINGS +#endif + +#ifdef CATCOMP_BLOCK +#undef CATCOMP_STRINGS +#define CATCOMP_STRINGS +#endif + + +/****************************************************************************/ + + +#ifdef CATCOMP_NUMBERS + +#define MSG_DATE_GAD 0 +#define MSG_DATE_SCT 1 +#define MSG_EXAMPLE_GAD 2 +#define MSG_TIME_GAD 3 +#define MSG_TIME_SCT 4 +#define MSG_SAVE_GAD 5 +#define MSG_SAVE_SCT 6 +#define MSG_USE_GAD 7 +#define MSG_USE_SCT 8 +#define MSG_CANCEL_GAD 9 +#define MSG_CANCEL_SCT 10 +#define MSG_PROJECT_MENU 11 +#define MSG_PROJECT_OPEN 12 +#define MSG_PROJECT_OPEN_SCT 13 +#define MSG_PROJECT_SAVEAS 14 +#define MSG_PROJECT_SAVEAS_SCT 15 +#define MSG_PROJECT_QUIT 16 +#define MSG_PROJECT_QUIT_SCT 17 +#define MSG_EDIT_MENU 18 +#define MSG_EDIT_RESET 19 +#define MSG_EDIT_RESET_SCT 20 +#define MSG_EDIT_LASTSAVED 21 +#define MSG_EDIT_LASTSAVED_SCT 22 +#define MSG_EDIT_RESTORE 23 +#define MSG_EDIT_RESTORE_SCT 24 +#define MSG_SETTINGS_MENU 25 +#define MSG_SETTINGS_CREATEICONS 26 +#define MSG_SETTINGS_CREATEICONS_SCT 27 +#define MSG_WINDOW 28 + +#endif /* CATCOMP_NUMBERS */ + + +/****************************************************************************/ + + +#ifdef CATCOMP_STRINGS + +#define MSG_DATE_GAD_STR "_Date" +#define MSG_DATE_SCT_STR "D" +#define MSG_EXAMPLE_GAD_STR "Example" +#define MSG_TIME_GAD_STR "_Time" +#define MSG_TIME_SCT_STR "T" +#define MSG_SAVE_GAD_STR "_Save" +#define MSG_SAVE_SCT_STR "S" +#define MSG_USE_GAD_STR "_Use" +#define MSG_USE_SCT_STR "U" +#define MSG_CANCEL_GAD_STR "_Cancel" +#define MSG_CANCEL_SCT_STR "C" +#define MSG_PROJECT_MENU_STR "Project" +#define MSG_PROJECT_OPEN_STR "Open..." +#define MSG_PROJECT_OPEN_SCT_STR "O" +#define MSG_PROJECT_SAVEAS_STR "Save As..." +#define MSG_PROJECT_SAVEAS_SCT_STR "A" +#define MSG_PROJECT_QUIT_STR "Quit" +#define MSG_PROJECT_QUIT_SCT_STR "Q" +#define MSG_EDIT_MENU_STR "Edit" +#define MSG_EDIT_RESET_STR "Reset to Defaults" +#define MSG_EDIT_RESET_SCT_STR "D" +#define MSG_EDIT_LASTSAVED_STR "Last Saved" +#define MSG_EDIT_LASTSAVED_SCT_STR "L" +#define MSG_EDIT_RESTORE_STR "Restore" +#define MSG_EDIT_RESTORE_SCT_STR "R" +#define MSG_SETTINGS_MENU_STR "Settings" +#define MSG_SETTINGS_CREATEICONS_STR "Create Icons?" +#define MSG_SETTINGS_CREATEICONS_SCT_STR "I" +#define MSG_WINDOW_STR "Titlebar Clock Plugin Preferences" + +#endif /* CATCOMP_STRINGS */ + + +/****************************************************************************/ + + +#ifdef CATCOMP_ARRAY + +struct CatCompArrayType +{ + LONG cca_ID; + STRPTR cca_Str; +}; + +static const struct CatCompArrayType CatCompArray[] = +{ + {MSG_DATE_GAD,(STRPTR)MSG_DATE_GAD_STR}, + {MSG_DATE_SCT,(STRPTR)MSG_DATE_SCT_STR}, + {MSG_EXAMPLE_GAD,(STRPTR)MSG_EXAMPLE_GAD_STR}, + {MSG_TIME_GAD,(STRPTR)MSG_TIME_GAD_STR}, + {MSG_TIME_SCT,(STRPTR)MSG_TIME_SCT_STR}, + {MSG_SAVE_GAD,(STRPTR)MSG_SAVE_GAD_STR}, + {MSG_SAVE_SCT,(STRPTR)MSG_SAVE_SCT_STR}, + {MSG_USE_GAD,(STRPTR)MSG_USE_GAD_STR}, + {MSG_USE_SCT,(STRPTR)MSG_USE_SCT_STR}, + {MSG_CANCEL_GAD,(STRPTR)MSG_CANCEL_GAD_STR}, + {MSG_CANCEL_SCT,(STRPTR)MSG_CANCEL_SCT_STR}, + {MSG_PROJECT_MENU,(STRPTR)MSG_PROJECT_MENU_STR}, + {MSG_PROJECT_OPEN,(STRPTR)MSG_PROJECT_OPEN_STR}, + {MSG_PROJECT_OPEN_SCT,(STRPTR)MSG_PROJECT_OPEN_SCT_STR}, + {MSG_PROJECT_SAVEAS,(STRPTR)MSG_PROJECT_SAVEAS_STR}, + {MSG_PROJECT_SAVEAS_SCT,(STRPTR)MSG_PROJECT_SAVEAS_SCT_STR}, + {MSG_PROJECT_QUIT,(STRPTR)MSG_PROJECT_QUIT_STR}, + {MSG_PROJECT_QUIT_SCT,(STRPTR)MSG_PROJECT_QUIT_SCT_STR}, + {MSG_EDIT_MENU,(STRPTR)MSG_EDIT_MENU_STR}, + {MSG_EDIT_RESET,(STRPTR)MSG_EDIT_RESET_STR}, + {MSG_EDIT_RESET_SCT,(STRPTR)MSG_EDIT_RESET_SCT_STR}, + {MSG_EDIT_LASTSAVED,(STRPTR)MSG_EDIT_LASTSAVED_STR}, + {MSG_EDIT_LASTSAVED_SCT,(STRPTR)MSG_EDIT_LASTSAVED_SCT_STR}, + {MSG_EDIT_RESTORE,(STRPTR)MSG_EDIT_RESTORE_STR}, + {MSG_EDIT_RESTORE_SCT,(STRPTR)MSG_EDIT_RESTORE_SCT_STR}, + {MSG_SETTINGS_MENU,(STRPTR)MSG_SETTINGS_MENU_STR}, + {MSG_SETTINGS_CREATEICONS,(STRPTR)MSG_SETTINGS_CREATEICONS_STR}, + {MSG_SETTINGS_CREATEICONS_SCT,(STRPTR)MSG_SETTINGS_CREATEICONS_SCT_STR}, + {MSG_WINDOW,(STRPTR)MSG_WINDOW_STR}, +}; + +#endif /* CATCOMP_ARRAY */ + + +/****************************************************************************/ + + +struct LocaleInfo +{ + APTR li_LocaleBase; + APTR li_Catalog; +}; + + + +#endif /* CC_LOCALE_H */ diff --git a/scalos/Plugins/OOP/TitleClock/prefs/config.mk b/scalos/Plugins/OOP/TitleClock/prefs/config.mk new file mode 100755 index 000000000..55827031b --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/prefs/config.mk @@ -0,0 +1,53 @@ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +INCLUDES += # + +LFLAGS += # + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +INCLUDES += # + +LFLAGS += # + +# Do not compile with __N0LIBBASE__ +OS4LIBBASE = -D__USE_BASETYPE__ + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +INCLUDES += # + +LFLAGS += # + +else + +############################################################################### +# AmigaOS + +INCLUDES += # + +LFLAGS += # + +endif +endif +endif diff --git a/scalos/Plugins/OOP/TitleClock/prefs/force b/scalos/Plugins/OOP/TitleClock/prefs/force new file mode 100755 index 0000000000000000000000000000000000000000..ed81afa35df0b807aa0226da3499525a0c22c872 GIT binary patch literal 4044 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 literal 0 HcwPel00001 diff --git a/scalos/Plugins/OOP/TitleClock/prefs/force.c b/scalos/Plugins/OOP/TitleClock/prefs/force.c new file mode 100644 index 000000000..b92982ea2 --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/prefs/force.c @@ -0,0 +1,20 @@ +#include +#include +#include "../plugin_api.h" + +#include +#include + +int main(void) +{ + struct Library *PluginBase; + + if(NULL != (PluginBase = OpenLibrary("title_clock.plugin", 40)) ) + { + printf("plugin poened\n"); + tcpl_ReReadPrefs(); + CloseLibrary(PluginBase); + } + return(0); +} + diff --git a/scalos/Plugins/OOP/TitleClock/prefs/interface.c b/scalos/Plugins/OOP/TitleClock/prefs/interface.c new file mode 100755 index 000000000..860ca5abb --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/prefs/interface.c @@ -0,0 +1,885 @@ +/* + * interface.c - Functions for creating the UI and handling IDCMP + * + * $Date$ + * $Revision$ + * + * 0.1 + * 20010723 DM + Routines for calculating sizes of gadgets, resizing window and font sensitivity. + * 20010717 DM + Created, although it's probably a bit messy + * + +On startup, load from ENV: +Write to ENV: on use +Write to ENV: and ENVARC: on save +Load from ENVARC: on "Last saved" + + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include "title_clock_prefs.h" +#include "screen.h" +#include "misc.h" +#include "tcp_locale.h" +#include "prefs_file.h" +#include "interface.h" +#include "requesters.h" +#include "saveicon.h" + +#include +#include + + +struct FormatDateHookData + { + STRPTR fdhd_Buffer; // buffer to write characters to + size_t fdhd_Length; // length of buffer + }; + +/* Gadget ID numbers */ +enum { + GID_DATE_FORMAT = 1, + GID_DATE_EXAMPLE, + GID_TIME_FORMAT, + GID_TIME_EXAMPLE, + GID_SAVE, + GID_USE, + GID_CANCEL, + GID_MAX_GADGETS +}; + + +/* Menu ID numbers (used for the UserData field) */ +enum { + MID_PROJECT_MENU, + MID_PROJECT_OPEN, + MID_PROJECT_SAVEAS, + MID_PROJECT_QUIT, + MID_EDIT_MENU, + MID_EDIT_RESET, + MID_EDIT_LASTSAVED, + MID_EDIT_RESTORE, + MID_SETTINGS_MENU, + MID_SETTINGS_CREATEICONS +}; + + +struct Screen *tcp_Screen = NULL; /* The screen we will be opening on */ +APTR tcp_vi = NULL; /* VisualInfo for gadtoosl and stuff */ +struct DrawInfo *tcp_Screen_dri = NULL; +struct Window *tcp_Window = NULL; /* There's only 1 window in this prefs program */ +struct Gadget *tcp_GadList = NULL; /* The gadgets in the window */ +struct Menu *tcp_MenuStrip = NULL; /* Menus to be attached to the window */ + +struct Gadget *tcp_Gadgets[GID_MAX_GADGETS] = {0}; /* Simple access to each created gadget */ + +struct TextAttr topaz = {"topaz.font", 8, 0, 0}; /* Default fallbasck font */ +//struct TextAttr screenfont; /* Font used for the screen (and also the one we want to use for our gadgets */ +struct TextAttr *tcp_UseFont; /* Font used for gadgets */ + +struct TextFont *tcp_WindowFont = NULL; /* The font used for the main window */ + + +/* Open's font, but checks if diskfont.library has been opened first, if not just uses graphics.library OpenFont, + * which should pretty much always be available, since it's one of the required libraries and it's in ROM. + */ +struct TextFont *myOpenDiskFont(struct TextAttr *ta) +{ + if(DiskfontBase) + { + return(OpenDiskFont(ta)); + } + return(OpenFont(ta)); +} + + +void SizeBorders(struct Screen *s, WORD *right, WORD *bottom) +{ + struct DrawInfo *dri; /* Screen's drawinfo data */ + struct Image *img; /* Image for size gadget */ + LONG sis; /* size of image for either med or low res screens */ + + /* Store the default sizes */ + if(right) *right = 18; + if(bottom) *bottom = 10; + + if(s) + { + if(NULL != (dri = GetScreenDrawInfo(s)) ) + { + if(s->Flags & SCREENHIRES) sis = SYSISIZE_MEDRES; else sis = SYSISIZE_LOWRES; + img = (struct Image *) NewObject(NULL, "sysiclass", SYSIA_DrawInfo, dri, + SYSIA_Which, SIZEIMAGE, + SYSIA_Size, sis, + TAG_DONE); + if(img) + { + if(right) *right = img->Width; + if(bottom) *bottom = img->Height; + DisposeObject((Object *) img); + } + FreeScreenDrawInfo(s, dri); + } /* drawinfo */ + } /* screen */ +} + + +/* Calculate sizes of required gadget area, include them with window border sizes and + * return true or false to say whether this window will fit on this screen. + * + * Current window layout is like this: + * + * |-----------------------------------| + * |#| Titlebar Clock plugin prefs |%|F| + * |-----------------------------------| + * | Date ========================== | + * |Example ========================== | + * | Time ========================== | + * |Example ========================== | + * | | + * | Save Use Cancel | + * |-----------------------------------| + */ + +#define GAP 4 /* Gap between gadgets and window borders */ +#define BUTTONEXTRA 12 /* Extra space at left and right of buttons */ +#define TEXTGADGAP 8 /* Gap between text and (string|text) gadgets */ +#define MINSIZE 70 /* Minimum size of string gadgets */ + +BOOL CalcMinSizes(struct Screen *scr, ULONG *width, ULONG *height, struct TextAttr *ta) +{ + BOOL willfit = 0; /* Flag to quickly show whether window will fit on screen or not */ + WORD wbl, wbt, wbr, wbb; /* Borders on windows */ + WORD gh; /* Height of a standard 1 line gadget */ + WORD miniw, minih; /* Minimum inner width and height (gadget area) */ + WORD strlabel; + WORD gadlabel; + struct TextFont *tf; + + if(!ta) return(0); + + if(NULL != (tf = myOpenDiskFont(ta)) ) + { + if(scr) + { + wbl = scr->WBorLeft; + wbt = scr->WBorTop + scr->Font->ta_YSize + 1; + wbb = scr->WBorBottom; + SizeBorders(scr, &wbr, NULL); + + gh = scr->Font->ta_YSize + 6; if(gh < 14) gh = 14; + + minih = gh * 5 + GAP * 6; + if(wbt + minih + wbb <= scr->Height) + { + /* Work out required width of string gadgets with an crappy example format string */ + strlabel = MaxLen(3,USTextLength(GetLocString(MSG_DATE_GAD), tf), + USTextLength(GetLocString(MSG_EXAMPLE_GAD), tf), + USTextLength(GetLocString(MSG_TIME_GAD), tf) ); + strlabel += TEXTGADGAP + USTextLength((STRPTR)"%%%%%%%%", tf); + + gadlabel = MaxLen(3,USTextLength(GetLocString(MSG_SAVE_GAD), tf), + USTextLength(GetLocString(MSG_USE_GAD), tf), + USTextLength(GetLocString(MSG_CANCEL_GAD), tf)) + BUTTONEXTRA; + gadlabel = 3 * gadlabel + 4 * GAP; + + miniw = strlabel; if(gadlabel > miniw) miniw = gadlabel; + if(wbl + miniw + wbr <= scr->Width) + { + willfit = 1; + if(width) *width = (wbl + miniw + wbr); + if(height) *height = (wbt + minih + wbb); + } /* width fits */ + } /* Height fits */ + } /* screen valid */ + CloseFont(tf); + } /* textfont opened */ + return(willfit); +} + + +void FreeMainGadgets(struct Gadget *gadlist) +{ + int i; /* Loop counter for clearing gadget pointer array */ + + if(gadlist) FreeGadgets(gadlist); + + for(i = 0; i < GID_MAX_GADGETS; i++) + { + tcp_Gadgets[i] = NULL; + } +} + + +#define RetFail(x,y) if(!(x)) { FreeMainGadgets(y); CloseFont(tf); return(NULL); } + +/* +void printng(struct NewGadget *ng) +{ + printf("ng.ng_LeftEdge=%d\n",ng->ng_LeftEdge); + printf("ng.ng_TopEdge=%d\n",ng->ng_TopEdge); + printf("ng.ng_Width=%d\n",ng->ng_Width); + printf("ng.ng_Height=%d\n",ng->ng_Height); + if(ng->ng_GadgetText) printf("ng.ng_GadgetText=%s\n",ng->ng_GadgetText); + printf("ng.ng_TextAttr=0x%08lX\n",(ULONG)ng->ng_TextAttr); + printf("ng.ng_GadgetID=%u\n",ng->ng_GadgetID); + printf("ng.ng_Flags=%lu\n",ng->ng_Flags); + printf("ng.ng_VisualInfo=0x%08lX\n",(ULONG)ng->ng_VisualInfo); + printf("ng.ng_UserData=0x%08lX\n",(ULONG)ng->ng_UserData); +} +*/ + + +struct Gadget *CreateMainGadgets(struct Screen *scr, APTR vi, ULONG ww, ULONG wh, struct TextAttr *gadfont) +{ + WORD wbl, wbt, wbr, wbb; /* Borders on windows */ + WORD gh; /* Height of a standard 1 line gadget */ +// WORD strlabel = 0; /* Maximum length of the 4 string/text gadget labels */ +// WORD gadlabel = 0; /* Maximum length of ONE!!! of the bottom 3 buttons */ + struct TextFont *tf; /* We need to open the font for some size calculations, but the gadgets take the TextAttr */ + struct NewGadget ng; /* Used in the creation of the gadtools gadgets */ + STRPTR examplemsg; /* Text for "Example" text gadget */ + STRPTR timemsg; /* Text for "Time" string gadget */ + struct Gadget *gadlist = NULL; /* Context for gadgets */ + struct Gadget *gad; /* Working pointer for creating gadgets */ + + if(!gadfont) + return(NULL); + + //printf("Gadfont OK\n"); + + if(NULL != (tf = myOpenDiskFont(gadfont)) ) + { + //printf("disk font opened ok\n"); + if(scr && vi) + { + //printf("screen and vi valid\n"); + gad = CreateContext(&gadlist); + //printf("Created context, gad=0x%08lX\n", (ULONG)gad); + RetFail(gad, gadlist); + + wbl = scr->WBorLeft; + wbt = scr->WBorTop + scr->Font->ta_YSize + 1; + wbb = scr->WBorBottom; + SizeBorders(scr, &wbr, NULL); + + //printf("border size l/t/r/b=%d/%d/%d/%d\n", wbl, wbt, wbr, wbb); + + gh = gadfont->ta_YSize + 6; + if(gh < 14) + gh = 14; + //printf("gadget height=%d\n", gh); + + + examplemsg = GetLocString(MSG_EXAMPLE_GAD); + timemsg = GetLocString(MSG_TIME_GAD); + + //printf("Example msg=%s\n", examplemsg); + //printf("Time msg=%s\n", timemsg); + + /* Set up the nasic newgadget structure (most of which will be reused for each gadget */ + //ng.ng_LeftEdge = + ng.ng_TopEdge = wbt + GAP; + //ng.ng_Width = + ng.ng_Height = gh; + ng.ng_GadgetText = GetLocString(MSG_DATE_GAD); + ng.ng_TextAttr = gadfont; + ng.ng_GadgetID = GID_DATE_FORMAT; + ng.ng_Flags = PLACETEXT_LEFT; + ng.ng_VisualInfo = vi; + ng.ng_LeftEdge = wbl + GAP + MaxLen(3, USTextLength(ng.ng_GadgetText, tf), USTextLength(examplemsg, tf), USTextLength(timemsg, tf)) + TEXTGADGAP; + ng.ng_Width = (ww - wbr - GAP - ng.ng_LeftEdge); + + //printng(&ng); + + gad = CreateGadget(STRING_KIND, gad, &ng, + GT_Underscore, (ULONG)'_', + GTST_String, (ULONG)datestr, + GTST_MaxChars, (ULONG)FORMAT_SIZE-1, + TAG_DONE); + //printf("gad=%08lx\n", (ULONG)gad); + RetFail(gad, gadlist); + //printf("gadget OK\n"); + tcp_Gadgets[ng.ng_GadgetID] = gad; + + + ng.ng_TopEdge += gh + GAP; + ng.ng_GadgetText = examplemsg; + ng.ng_GadgetID = GID_DATE_EXAMPLE; + //printng(&ng); + gad = CreateGadget(TEXT_KIND, gad, &ng, + GTTX_Text, date_ex, + GTTX_Border, 1, + TAG_DONE); + RetFail(gad, gadlist); + tcp_Gadgets[ng.ng_GadgetID] = gad; + + + ng.ng_TopEdge += gh + GAP; + ng.ng_GadgetText = timemsg; + ng.ng_GadgetID = GID_TIME_FORMAT; + //printng(&ng); + gad = CreateGadget(STRING_KIND, gad, &ng, + GT_Underscore, '_', + GTST_String, timestr, + GTST_MaxChars, EXAMPLE_SIZE-1, + TAG_DONE); + RetFail(gad, gadlist); + tcp_Gadgets[ng.ng_GadgetID] = gad; + + + ng.ng_TopEdge += gh + GAP; + ng.ng_GadgetText = examplemsg; + ng.ng_GadgetID = GID_TIME_EXAMPLE; + //printng(&ng); + //printf("time example='%s'\n", time_ex); + gad = CreateGadget(TEXT_KIND, gad, &ng, + GTTX_Text, time_ex, + GTTX_Border, 1, + TAG_DONE); + RetFail(gad, gadlist); + tcp_Gadgets[ng.ng_GadgetID] = gad; + + + examplemsg = GetLocString(MSG_USE_GAD); + timemsg = GetLocString(MSG_CANCEL_GAD); + + ng.ng_LeftEdge = wbl + GAP; + ng.ng_TopEdge += gh + GAP; + ng.ng_GadgetText = GetLocString(MSG_SAVE_GAD); + ng.ng_Width = MaxLen(3, USTextLength(ng.ng_GadgetText, tf), USTextLength(examplemsg, tf), USTextLength(timemsg, tf)) + BUTTONEXTRA; + ng.ng_GadgetID = GID_SAVE; + ng.ng_Flags = PLACETEXT_IN; + //printng(&ng); + gad = CreateGadget(BUTTON_KIND, gad, &ng, + GT_Underscore, '_', + TAG_DONE); + RetFail(gad, gadlist); + tcp_Gadgets[ng.ng_GadgetID] = gad; + + + ng.ng_LeftEdge = (ww + wbl - wbr - ng.ng_Width) / 2; + ng.ng_GadgetText = examplemsg; + ng.ng_GadgetID = GID_USE; + //printng(&ng); + gad = CreateGadget(BUTTON_KIND, gad, &ng, + GT_Underscore, '_', + TAG_DONE); + RetFail(gad, gadlist); + tcp_Gadgets[ng.ng_GadgetID] = gad; + + + ng.ng_LeftEdge = ww - wbr - GAP - ng.ng_Width; + ng.ng_GadgetText = timemsg; + ng.ng_GadgetID = GID_CANCEL; + //printng(&ng); + gad = CreateGadget(BUTTON_KIND, gad, &ng, + GT_Underscore, '_', + TAG_DONE); + RetFail(gad, gadlist); + tcp_Gadgets[ng.ng_GadgetID] = gad; + + } + CloseFont(tf); + } + return(gadlist); +} + + +void FreeMainMenus(struct Menu *mnu) +{ + if(mnu) FreeMenus(mnu); +} + + +/* Structure for helping with automatically creating locale string menus */ +/*struct LocaleNewMenu +{ + UBYTE lnm_Type; + UBYTE lnm_Pad; + ULONG lnm_LabelMsgNum; + ULONG lnm_CommKeyMsgNum; + UWORD lnm_Flags; + LONG lnm_MutualExclude; + APTR lnm_UserData; +}; +*/ + + +struct Menu *CreateMainMenus(struct Screen *scr, APTR visinf) +{ + /* Mwoahahaha, evil structure of doom for creating menus, with strings + * replaced by their locale MESSAGE NUMBER!!! which then gets parsed and + * the strings replaced. NULL still represents a NULL pointer, so make + * sure none of the menu strings are string number 0!!!! Oh, aye, + * barlabels stay as they are, so -1 numbered strings are out too. + */ + struct NewMenu nm[] = { {NM_TITLE, (STRPTR)MSG_PROJECT_MENU, NULL, 0, 0, (APTR)MID_PROJECT_MENU}, + {NM_ITEM, (STRPTR)MSG_PROJECT_OPEN, (STRPTR)MSG_PROJECT_OPEN_SCT, 0, 0, (APTR)MID_PROJECT_OPEN}, + {NM_ITEM, (STRPTR)MSG_PROJECT_SAVEAS, (STRPTR)MSG_PROJECT_SAVEAS_SCT, 0, 0, (APTR)MID_PROJECT_SAVEAS}, + {NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL}, + {NM_ITEM, (STRPTR)MSG_PROJECT_QUIT, (STRPTR)MSG_PROJECT_QUIT_SCT, 0, 0, (APTR)MID_PROJECT_QUIT}, + {NM_TITLE, (STRPTR)MSG_EDIT_MENU, NULL, 0, 0, (APTR)MID_EDIT_MENU}, + {NM_ITEM, (STRPTR)MSG_EDIT_RESET, (STRPTR)MSG_EDIT_RESET_SCT, 0, 0, (APTR)MID_EDIT_RESET}, + {NM_ITEM, (STRPTR)MSG_EDIT_LASTSAVED, (STRPTR)MSG_EDIT_LASTSAVED_SCT, 0, 0, (APTR)MID_EDIT_LASTSAVED}, + {NM_ITEM, (STRPTR)MSG_EDIT_RESTORE, (STRPTR)MSG_EDIT_RESTORE_SCT, 0, 0, (APTR)MID_EDIT_RESTORE}, + {NM_TITLE, (STRPTR)MSG_SETTINGS_MENU, NULL, 0, 0, (APTR)MID_SETTINGS_MENU}, + {NM_ITEM, (STRPTR)MSG_SETTINGS_CREATEICONS, (STRPTR)MSG_SETTINGS_CREATEICONS_SCT, CHECKIT, 0, (APTR)MID_SETTINGS_CREATEICONS}, + {NM_END, NULL, NULL, 0, 0, NULL}}; +// int i; + struct NewMenu *ptr; /* For parsing the above array */ + struct Menu *mnu; /* The menus we create */ + + for(ptr = nm; ptr->nm_Type != NM_END; ptr++) + { + //printf("Pointing to %08lx, type is %u, UD=%lu\n", (ULONG)ptr, ptr->nm_Type, (ULONG)ptr->nm_UserData); + + if(NULL != ptr->nm_Label && NM_BARLABEL != ptr->nm_Label) + { + ptr->nm_Label = GetLocString((ULONG)ptr->nm_Label); + } + + if(NULL != ptr->nm_CommKey) + { + ptr->nm_CommKey = GetLocString((ULONG)ptr->nm_CommKey); + } + } + + mnu = CreateMenus(nm, TAG_DONE); + if(mnu) + { + LayoutMenus(mnu, visinf, GTMN_NewLookMenus, 1, TAG_DONE); + } + return(mnu); +} + + +void CloseMainWindow(void) +{ + if(tcp_Window) + { + if(tcp_MenuStrip) + ClearMenuStrip(tcp_Window); + if(tcp_GadList) + RemoveGList(tcp_Window, tcp_GadList, -1); + CloseWindow(tcp_Window); + tcp_Window = NULL; + } + + if(tcp_MenuStrip) + { + FreeMenus(tcp_MenuStrip); + tcp_MenuStrip = NULL; + } + + if(tcp_GadList) + { + FreeGadgets(tcp_GadList); + tcp_GadList = NULL; + } + + if(tcp_Screen_dri) + FreeScreenDrawInfo(tcp_Screen, tcp_Screen_dri); + tcp_Screen_dri = NULL; + + if(tcp_vi) + FreeVisualInfo(tcp_vi); + tcp_vi = NULL; + + if(tcp_Screen) + UnlockPubScreen(NULL, tcp_Screen); + tcp_Screen = NULL; +} + + +BOOL OpenMainWindow(void) +{ + BOOL retval = 0; /* Result. =0 for something failed, !=0 for all (screen, window, gadgets, menus) opened/created successfully */ + ULONG wx, wy; /* X,Y position of window */ + ULONG ww, wh; /* Current window width and height */ + ULONG minww, minwh; /* Minimum sizes for window */ + BOOL sizeok; /* size of window fits on screen? */ + + if(!tcp_Screen) tcp_Screen = FindPubScreen("Workbench"); + if(tcp_Screen) + { + if(NULL != (tcp_Screen_dri = GetScreenDrawInfo(tcp_Screen)) ) + { + if(NULL != (tcp_vi = GetVisualInfo(tcp_Screen, (ULONG)NULL)) ) + { + tcp_UseFont = tcp_Screen->Font ? tcp_Screen->Font : &topaz; + sizeok = CalcMinSizes(tcp_Screen, &minww, &minwh, tcp_UseFont); + if(!sizeok && tcp_UseFont != &topaz) + { + //printf("screen font doesn't fit\n"); + + /* Repeat with topaz8 if too big from screen */ + tcp_UseFont = &topaz; + + /* Quit if that is too big */ + sizeok = CalcMinSizes(tcp_Screen, &minww, &minwh, tcp_UseFont); + } + + if(sizeok) + { + //printf("size ok, min width, height=%lu %lu\n", minww, minwh); + + /* Work out sizes and create gadgets */ + ww = (tcp_Screen->Width + minww) / 2; // halfway between inimum and screen size + wh = minwh; + + //printf("window sizes=%lu %lu\n", ww, wh); + + // Centred + wx = (tcp_Screen->Width - ww) / 2; + wy = (tcp_Screen->Height - wh) / 2; + + //printf("window positions=%lu %lu\n", wx, wy); + + ShowExample(datestr, GID_DATE_EXAMPLE, date_ex, sizeof(date_ex)); + ShowExample(timestr, GID_TIME_EXAMPLE, time_ex, sizeof(time_ex)); + tcp_GadList = CreateMainGadgets(tcp_Screen, tcp_vi, ww, wh, tcp_UseFont); + + //printf("gadgets created\n"); + + /* Create main menus */ + tcp_MenuStrip = CreateMainMenus(tcp_Screen, tcp_vi); + //tcp_MenuStrip = NULL; + + if(tcp_GadList && tcp_MenuStrip) + { + /* Open window and attach all the stuff */ + if(NULL != (tcp_Window=OpenWindowTags(NULL, + WA_Flags, WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_SIZEGADGET | WFLG_NEWLOOKMENUS, + WA_IDCMP, IDCMP_CLOSEWINDOW | BUTTONIDCMP | STRINGIDCMP | TEXTIDCMP | IDCMP_SIZEVERIFY | IDCMP_NEWSIZE | IDCMP_VANILLAKEY | IDCMP_MENUPICK | IDCMP_REFRESHWINDOW | IDCMP_CHANGEWINDOW | IDCMP_GADGETUP, + WA_Activate, TRUE, + WA_Left, wx, + WA_Top, wy, + WA_Width, ww, + WA_Height, wh, + WA_MinWidth, minww, + WA_MinHeight, minwh, + WA_MaxWidth, tcp_Screen->Width, + WA_MaxHeight, 0, + WA_Title, GetLocString(MSG_WINDOW), + WA_Gadgets, tcp_GadList, + WA_PubScreen, tcp_Screen, + WA_SimpleRefresh, -1, + //WA_MenuHelp, 1, + TAG_DONE)) ) + { + GT_RefreshWindow(tcp_Window, NULL); + SetMenuStrip(tcp_Window, tcp_MenuStrip); + retval = 1; + } + } + } + } + } + //if(tcp_GadList && tcp_MenuStrip && tcp_Window) retval = 1; + } + return(retval); +} + + +WORD HandleMainMessages(void) +{ + WORD quit = 0; + struct IntuiMessage *imsg; + ULONG ev; + UWORD code; + APTR iadd; + + ULONG oldww, oldwh, ww, wh; + STRPTR dateptr, timeptr; + + struct MenuItem *item; + ULONG mid; + + STRPTR fname; /* For Project->Open and Project->SaveAs */ + static BOOL saveicons = FALSE; + + oldww = tcp_Window->Width; + oldwh = tcp_Window->Height; + + while(NULL != (imsg = GT_GetIMsg(tcp_Window->UserPort)) && !quit) + { + ev = imsg->Class; + code = imsg->Code; + iadd = imsg->IAddress; + GT_ReplyIMsg(imsg); + + switch(ev) + { + case IDCMP_REFRESHWINDOW: + GT_BeginRefresh(tcp_Window); + GT_EndRefresh(tcp_Window, -1); + break; + + case IDCMP_CLOSEWINDOW: + quit = 1; + break; + + case IDCMP_GADGETUP: + //printf("gadget up=%u\n", ((struct Gadget *)iadd)->GadgetID); + switch(((struct Gadget *)iadd)->GadgetID) + { + case GID_DATE_FORMAT: + //printf("date format gadget up\n"); + GT_GetGadgetAttrs(tcp_Gadgets[GID_DATE_FORMAT], tcp_Window, NULL, GTST_String, &dateptr, TAG_DONE); + ShowExample(dateptr, GID_DATE_EXAMPLE, date_ex, sizeof(date_ex)); + break; + + case GID_TIME_FORMAT: + //printf("time format gadget up\n"); + GT_GetGadgetAttrs(tcp_Gadgets[GID_TIME_FORMAT], tcp_Window, NULL, GTST_String, &timeptr, TAG_DONE); + //printf("contents of string gadget='%s'\n", timeptr); + ShowExample(timeptr, GID_TIME_EXAMPLE, time_ex, sizeof(time_ex)); + //printf("exaaaample='%s'\n", time_ex); + break; + + case GID_SAVE: + //printf("save hit\n"); + GT_GetGadgetAttrs(tcp_Gadgets[GID_DATE_FORMAT], tcp_Window, NULL, GTST_String, &dateptr, TAG_DONE); + GT_GetGadgetAttrs(tcp_Gadgets[GID_TIME_FORMAT], tcp_Window, NULL, GTST_String, &timeptr, TAG_DONE); + SavePrefs(dateptr, timeptr); + if(saveicons) + { + SaveIcon(SAVENAME); + SaveIcon(USENAME); + } + ForcePluginRead(); + quit = 1; + break; + + case GID_USE: + //printf("use\n"); + GT_GetGadgetAttrs(tcp_Gadgets[GID_DATE_FORMAT], tcp_Window, NULL, GTST_String, &dateptr, TAG_DONE); + GT_GetGadgetAttrs(tcp_Gadgets[GID_TIME_FORMAT], tcp_Window, NULL, GTST_String, &timeptr, TAG_DONE); + UsePrefs(dateptr, timeptr); + if(saveicons) + { + SaveIcon(USENAME); + } + ForcePluginRead(); + case GID_CANCEL: + //printf("cancel/use exit\n"); + quit = 1; + break; + } + break; + + case IDCMP_MENUPICK: + while(code != MENUNULL) + { + item = ItemAddress(tcp_MenuStrip, code); + + /* */ + //printf("menu pick, item address=%08lx, menunum=%u\n", (ULONG)item, code); + mid = (ULONG)GTMENUITEM_USERDATA(item); + //printf("Menu item hit: %lu\n", mid); + switch(mid) + { + case MID_PROJECT_OPEN: + fname = OpenFileReq(tcp_Window); + if(fname) + { + ReadPrefsFile(fname, datestr, FORMAT_SIZE, timestr, FORMAT_SIZE); + GT_SetGadgetAttrs(tcp_Gadgets[GID_DATE_FORMAT], tcp_Window, NULL, GTST_String, datestr, TAG_DONE); + GT_SetGadgetAttrs(tcp_Gadgets[GID_TIME_FORMAT], tcp_Window, NULL, GTST_String, timestr, TAG_DONE); + ShowExample(datestr, GID_DATE_EXAMPLE, date_ex, sizeof(date_ex)); + ShowExample(timestr, GID_TIME_EXAMPLE, time_ex, sizeof(time_ex)); + FreeVec(fname); + } + break; + + case MID_PROJECT_SAVEAS: + GT_GetGadgetAttrs(tcp_Gadgets[GID_DATE_FORMAT], tcp_Window, NULL, GTST_String, &dateptr, TAG_DONE); + GT_GetGadgetAttrs(tcp_Gadgets[GID_TIME_FORMAT], tcp_Window, NULL, GTST_String, &timeptr, TAG_DONE); + fname = SaveFileReq(tcp_Window); + if(fname) + { + WritePrefsFile(fname, dateptr, timeptr); + if(saveicons) SaveIcon(fname); + FreeVec(fname); + } + break; + + case MID_PROJECT_QUIT: + quit = 1; + break; + + case MID_EDIT_RESET: + GT_SetGadgetAttrs(tcp_Gadgets[GID_DATE_FORMAT], tcp_Window, NULL, GTST_String, "", TAG_DONE); + GT_SetGadgetAttrs(tcp_Gadgets[GID_TIME_FORMAT], tcp_Window, NULL, GTST_String, "", TAG_DONE); + ShowExample("", GID_DATE_EXAMPLE, date_ex, sizeof(date_ex)); + ShowExample("", GID_TIME_EXAMPLE, time_ex, sizeof(time_ex)); + break; + + case MID_EDIT_LASTSAVED: + ReadPrefsFile(SAVENAME, datestr, FORMAT_SIZE, timestr, FORMAT_SIZE); + ShowExample(datestr, GID_DATE_EXAMPLE, date_ex, sizeof(date_ex)); + ShowExample(timestr, GID_TIME_EXAMPLE, time_ex, sizeof(time_ex)); + break; + + case MID_EDIT_RESTORE: + GT_SetGadgetAttrs(tcp_Gadgets[GID_DATE_FORMAT], tcp_Window, NULL, GTST_String, date_re, TAG_DONE); + GT_SetGadgetAttrs(tcp_Gadgets[GID_TIME_FORMAT], tcp_Window, NULL, GTST_String, time_re, TAG_DONE); + ShowExample(date_re, GID_DATE_EXAMPLE, date_ex, sizeof(date_ex)); + ShowExample(time_re, GID_TIME_EXAMPLE, time_ex, sizeof(time_ex)); + break; + + case MID_SETTINGS_CREATEICONS: + if(CHECKED == item->Flags & CHECKED) + { + saveicons = TRUE; + } + else + { + saveicons = FALSE; + } + break; + + default: + break; + } + + code = item->NextSelect; + } + break; + + case IDCMP_SIZEVERIFY: + oldww = tcp_Window->Width; + oldwh = tcp_Window->Height; + RemoveGList(tcp_Window, tcp_GadList, -1); + break; + + case IDCMP_CHANGEWINDOW: + RemoveGList(tcp_Window, tcp_GadList, -1); + case IDCMP_NEWSIZE: + ww = tcp_Window->Width; + wh = tcp_Window->Height; + + if(oldww != ww || oldwh != wh) + { + // Save contents of gadgets + GT_GetGadgetAttrs(tcp_Gadgets[GID_DATE_FORMAT], tcp_Window, NULL, GTST_String, &dateptr, TAG_DONE); + strcpy(datestr, dateptr); + + GT_GetGadgetAttrs(tcp_Gadgets[GID_TIME_FORMAT], tcp_Window, NULL, GTST_String, &timeptr, TAG_DONE); + strcpy(timestr, timeptr); + + // Delete gadget list + FreeMainGadgets(tcp_GadList); + + // Re-make gadgets + //ShowExample(datestr, NULL, date_ex, sizeof(date_ex)); + //ShowExample(timestr, NULL, time_ex, sizeof(time_ex)); + tcp_GadList = CreateMainGadgets(tcp_Screen, tcp_vi, ww, wh, tcp_UseFont); + + oldww = ww; oldwh = wh; + + RefreshWindowFrame(tcp_Window); + //SetRast(tcp_Window->RPort, tcp_Screen_dri->dri_Pens[BACKGROUNDPEN]); + SetAPen(tcp_Window->RPort, tcp_Screen_dri->dri_Pens[BACKGROUNDPEN]); + RectFill(tcp_Window->RPort, tcp_Window->BorderLeft, tcp_Window->BorderTop, tcp_Window->Width-tcp_Window->BorderRight-1,tcp_Window->Height-tcp_Window->BorderBottom-1); + } + + if(tcp_GadList) + { + // Attach gadgets + AddGList(tcp_Window, tcp_GadList, -1, -1, NULL); + + // Refresh gadgets + RefreshGList(tcp_GadList, tcp_Window, NULL, -1); + + // Refresh window frame + GT_RefreshWindow(tcp_Window, NULL); + } + else + { + quit = 1; + } + break; + } + } + + return(quit); +} + + +static M68KFUNC_P3(void, FormatDateHookFunc, + A0, struct Hook *, theHook, + A2, struct Locale *, locale, + A1, char, ch) +{ + struct FormatDateHookData *fd = (struct FormatDateHookData *) theHook->h_Data; + + (void) locale; + + if (fd->fdhd_Length >= 1) + { + *(fd->fdhd_Buffer)++ = ch; + fd->fdhd_Length--; + } +} +M68KFUNC_END + + +void ShowExample(STRPTR format, UWORD gid, STRPTR buffer, size_t BuffLen) +{ + struct FormatDateHookData fd; + struct Hook fmthook; + struct Locale *loc; + struct DateStamp ds; + STATIC_PATCHFUNC(FormatDateHookFunc) + + d1(KPrintF(__FILE__ "/%s/%ld: START\n", __FUNC__, __LINE__)); + + fmthook.h_Entry = (HOOKFUNC) PATCH_NEWFUNC(FormatDateHookFunc); + fmthook.h_Data = &fd; + + fd.fdhd_Buffer = buffer; + fd.fdhd_Length = BuffLen; + + d1(KPrintF(__FILE__ "/%s/%ld: format buffer=<%s>\n", __FUNC__, __LINE__, format)); + + loc = OpenLocale(NULL); // Guaranteed to suck seeds + DateStamp(&ds); + if(*format) + { + FormatDate(loc, format, &ds, &fmthook); + } + else + { + FormatDate(loc, (GID_DATE_EXAMPLE == gid ? loc->loc_DateFormat : loc->loc_TimeFormat), &ds, &fmthook); + } + + d1(KPrintF(__FILE__ "/%s/%ld: example string=<%s>\n", __FUNC__, __LINE__, buffer)); + + CloseLocale(loc); + + if(tcp_Gadgets[gid]) + { + GT_SetGadgetAttrs(tcp_Gadgets[gid], tcp_Window, NULL, + GTTX_Text, buffer, TAG_DONE); + } +} + diff --git a/scalos/Plugins/OOP/TitleClock/prefs/interface.h b/scalos/Plugins/OOP/TitleClock/prefs/interface.h new file mode 100755 index 000000000..06ce667f2 --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/prefs/interface.h @@ -0,0 +1,23 @@ +/* + * interface.h - Functions for creating the UI and handling IDCMP + * + * $Date$ + * $Revision$ + * + */ + +#ifndef INTERFACE_H +#define INTERFACE_H + +#include +#include + +extern struct Window *tcp_Window; + +void CloseMainWindow(void); +BOOL OpenMainWindow(void); +WORD HandleMainMessages(void); +void ShowExample(STRPTR format, UWORD gid, STRPTR buffer, size_t BuffLen); + +#endif /* INTERFACE_H */ + diff --git a/scalos/Plugins/OOP/TitleClock/prefs/makefile b/scalos/Plugins/OOP/TitleClock/prefs/makefile new file mode 100755 index 000000000..9e065f743 --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/prefs/makefile @@ -0,0 +1,32 @@ +# Makefile for title_clock_prefs + +HEADERS = title_clock_prefs.h ../plugin_api.h prefs_file.h screen.h tcp_locale.h cc_locale.h interface.h misc.h requesters.h saveicon.h +CC = vc +CFLAGS = -+ -c -O3 -Iinclude: -D__VBCC__ +LD = vlink +LDFLAGS = -Lvlib: -lamiga -lvc -lextra -ldebug +STARTUP = vlib:startup.o + +OBJS = title_clock_prefs.o prefs_file.o screen.o tcp_locale.o interface.o misc.o requesters.o saveicon.o + +all: title_clock_prefs + +title_clock_prefs: $(OBJS) + $(LD) $(STARTUP) $^ $(LDFLAGS) -o $@.debug + $(LD) $(STARTUP) $^ $(LDFLAGS) -s -o $@ + +.c.o: + $(CC) $(CFLAGS) $< -o $@ + +title_clock_prefs.o: title_clock_prefs.c $(HEADERS) +prefs_file.o: prefs_file.c prefs_file.h +screen.o: screen.c +tcp_locale.o: tcp_locale.c tcp_locale.h cc_locale.h +interface.o: interface.c $(HEADERS) +misc.o: misc.c +requesters.o: requesters.c +saveicon.o: saveicon.c + +clean: + delete title_clock_prefs title_clock_prefs.debug $(OBJS) >NIL: + diff --git a/scalos/Plugins/OOP/TitleClock/prefs/makefile-new b/scalos/Plugins/OOP/TitleClock/prefs/makefile-new new file mode 100755 index 000000000..ae1b7b8fc --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/prefs/makefile-new @@ -0,0 +1,69 @@ +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../../../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(OBJDIR)/title_clock_prefs.o \ + $(OBJDIR)/prefs_file.o \ + $(OBJDIR)/screen.o \ + $(OBJDIR)/tcp_locale.o \ + $(OBJDIR)/interface.o \ + $(OBJDIR)/requesters.o \ + $(OBJDIR)/saveicon.o \ + $(OBJDIR)/misc.o \ + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Targets +# + +TITLECLOCKPREFS = Title_Clock_Prefs + +############################################################################## + +.PHONY: all install clean bump dump + +all: $(TITLECLOCKPREFS) + +############################################################################## + +$(OBJDIR)/%.o: $(PREFS_DIR)/%.c + @$(run-cc) + +############################################################################## + +$(TITLECLOCKPREFS): $(OBJS) + @$(ECHO) "Link $@" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$@.debug + @$(STRIP) $(SFLAGS) $@.debug -o $@ +ifneq ($(MACHINE), ppc-amigaos) + @chmod u+x $@ +endif + +############################################################################## + +install: +# @copy $(TITLECLOCKPREFS) Scalos:Plugins/OOP clone + + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.i \ + $(OBJDIR)/*.s $(OBJDIR)/*.d.* \ + $(TITLECLOCKPREFS).debug $(TITLECLOCKPREFS) + diff --git a/scalos/Plugins/OOP/TitleClock/prefs/misc.c b/scalos/Plugins/OOP/TitleClock/prefs/misc.c new file mode 100644 index 000000000..2df937927 --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/prefs/misc.c @@ -0,0 +1,99 @@ +/* + * misc.c - routines for misc stuff + * + * $Date$ + * $Revision$ + * + * 0.1 + * 20010718 DM Created. Added routines for calculating length of a string in a given font (ignoring underscores) and the longest in an array of values + * + */ + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + + +WORD USTextLength(STRPTR string, struct TextFont *tf) +{ + char temp[256]; /* Some temporary gubbins */ + STRPTR t2; /* Working pointer to the above temporary string */ + struct RastPort rp; /* We need this for calculating the length */ + ULONG textlen = 0; /* Length of the text */ + + for(t2 = temp; *string; string++) + { + if(*string != '_') + { + *t2++ = *string; + textlen++; + } + } + *t2 = '\0'; + + //printf("Non-US: %s\n", temp); + + InitRastPort(&rp); + SetFont(&rp, tf); + return(TextLength(&rp, temp, textlen)); +} + + +WORD MaxLen(int count, ...) +{ + va_list vl; + WORD len, max = 0; + int i; + + va_start(vl, count); + + for(i = 0; i < count; i++) + { + len = va_arg(vl, int); + //printf("next arg: %d\n", len); + if(len > max) max = len; + } + + va_end(vl); + return(max); +} + + +#if 0 +struct GfxBase *GfxBase; +struct Library *DiskfontBase; + +int main(void) +{ + struct TextAttr ta = {"xen.font", 13, 0, 0}; + struct TextFont *tf; + GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 36); + DiskfontBase = (struct Library *)OpenLibrary("diskfont.library", 0); + + if(GfxBase && DiskfontBase) + { + tf = OpenDiskFont(&ta); + if(tf) + { + printf("Pixel length: %d\n", USTextLength("_Save", tf)); + CloseFont(tf); + } + } + + if(DiskfontBase) CloseLibrary(DiskfontBase); + if(GfxBase) CloseLibrary((struct Library *)GfxBase); + + printf("max is: %d\n", MaxLen(4, 9, 6, 3, 8)); + + return(0); +} +#endif + diff --git a/scalos/Plugins/OOP/TitleClock/prefs/misc.h b/scalos/Plugins/OOP/TitleClock/prefs/misc.h new file mode 100644 index 000000000..ab6c09555 --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/prefs/misc.h @@ -0,0 +1,24 @@ +/* + * misc.h - routines for misc stuff + * + * $Date$ + * $Revision$ + * + * 0.1 + * 20010718 DM Created. Added routines for calculating length of a string in a given font (ignoring underscores) and the longest in an array of values + * + */ + +#ifndef MISC_H +#define MISC_H + +WORD USTextLength(CONST_STRPTR string, struct TextFont *tf); +WORD MaxLen(int count, ...); + +extern int KPrintF(CONST_STRPTR fmt, ...); + +#define d1(x) ; +#define d2(x) x; + +#endif /* MISC_H */ + diff --git a/scalos/Plugins/OOP/TitleClock/prefs/prefs_file.c b/scalos/Plugins/OOP/TitleClock/prefs/prefs_file.c new file mode 100755 index 000000000..ecc21b890 --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/prefs/prefs_file.c @@ -0,0 +1,194 @@ +/* + * prefs_file.c + * + * $Date$ + * $Revision$ + * + * 20010716 DM Created. Will be used by prefs and plugin programs + * + */ + +#ifdef __NOLIBBASE__ +#undef __NOLIBBASE__ +#endif + +#include +#include +#include +#include + +#include +#include +#include + +#include "defs.h" +#include "prefs_file.h" + +#define d1(x) ; +#define d2(x) x; + + +/* Tries to find the volume or assign (confusingly ;) that is passed - without the + * colon!, e.g. FindDevice("ENV"); Returns true if found. Means you don't need to + * disable requesters when searching for volumes (e.g. ENV: :) + */ +static BOOL FindDevice(CONST_STRPTR devname) +{ + struct DosList *dl; /* For locking/finding volume or assign in the doslist */ + BOOL found = 0; /* flag to return showing if we found the device */ + struct DosList *de; /* entry in the doslist */ + + dl = LockDosList(LDF_VOLUMES|LDF_ASSIGNS|LDF_DEVICES|LDF_READ); + + d1(kprintf("FindDevice: finding '%s'\n", devname)); + if(NULL != (de = FindDosEntry(dl, devname, LDF_VOLUMES|LDF_ASSIGNS|LDF_DEVICES)) ) + { + d1(kprintf("FindDevice: found!\n")); + found = 1; + } + UnLockDosList(LDF_VOLUMES|LDF_ASSIGNS|LDF_DEVICES|LDF_READ); + return(found); +} + + +LONG ReadPrefsFile(CONST_STRPTR file, STRPTR datefmt, ULONG datelen, STRPTR timefmt, ULONG timelen) +{ + BPTR fh; /* File handle for the saved file */ + char *newline; /* pointer to the first newline character in each string */ + LONG result = 0; + + fh = Open(file, MODE_OLDFILE); + if(fh) + { + /* Fix for pre-V39 FGets() */ + if(((struct Library *)DOSBase)->lib_Version < 39) { datelen--; timelen--; } + + /* Read line for dat format into string and replace any newline with a NULL */ + if(FGets(fh, datefmt, datelen)) + { + newline = strchr(datefmt, '\n'); + if(newline) *newline = '\0'; + result++; + } + + /* Same for the time format */ + if(FGets(fh, timefmt, timelen)) + { + newline = strchr(timefmt, '\n'); + if(newline) *newline = '\0'; + result++; + } + + Close(fh); + } + return(result); +} + + +LONG WritePrefsFile(CONST_STRPTR file, CONST_STRPTR datefmt, CONST_STRPTR timefmt) +{ + BPTR fh; /* File handle for the saved file */ + LONG result = 0; + + fh = Open(file, MODE_NEWFILE); + if(fh) + { + FPuts(fh, datefmt); FPutC(fh, '\n'); + FPuts(fh, timefmt); FPutC(fh, '\n'); + Close(fh); + result = 1; + } + return(result); +} + + +LONG LoadPrefs(STRPTR datefmt, ULONG datelen, STRPTR timefmt, ULONG timelen) +{ + LONG result = 0; + + d1(kprintf("LoadPrefs: enter")); + if(FindDevice("ENV")) + { + result = ReadPrefsFile(USENAME, datefmt, datelen, timefmt, timelen); + d1(kprintf("LoadPrefs: ENV found, result=%ld\n", result)); + } + + if(!result && FindDevice("ENVARC")) + { + result = ReadPrefsFile(SAVENAME, datefmt, datelen, timefmt, timelen); + d1(kprintf("LoadPrefs: ENV found, result=%ld\n", result)); + } + + if(!result) + { + ReadPrefsFile("PROGDIR:title_clock.prefs", datefmt, datelen, timefmt, timelen); + d1(kprintf("LoadPrefs: Reading from PROGDIR:")); + } + return(result); +} + + +/* Saves prefs file to ENV: and ENVARC: */ +LONG SavePrefs(CONST_STRPTR datefmt, CONST_STRPTR timefmt) +{ + LONG result = 0; + + d1(kprintf("SavePrefs: enter")); + if(FindDevice("ENV")) + { + result += WritePrefsFile(USENAME, datefmt, timefmt); + d1(kprintf("SavePrefs: Env found, result of write=%ld\n", result)); + } + if(FindDevice("ENVARC")) + { + result += WritePrefsFile(SAVENAME, datefmt, timefmt); + d1(kprintf("SavePrefs: Env found, result of write=%ld\n", result)); + } + return(result); +} + + +/* Saves prefs only to ENV: */ +LONG UsePrefs(CONST_STRPTR datefmt, CONST_STRPTR timefmt) +{ + LONG result = 0; + + d1(kprintf("UsePrefs: enter\n")); + if(FindDevice("ENV")) + { + result = WritePrefsFile(USENAME, datefmt, timefmt); + d1(kprintf("UsePrefs: Env found, result of write ('%s','%s')=%ld\n", datefmt, timefmt, result)); + } + return(result); +} + +BOOL StartPrefsNotify(struct NotifyRequest *notify) +{ + BOOL Success; + + notify->nr_Name = (STRPTR) USENAME; + + Success = StartNotify(notify); + + if (!Success) + notify->nr_Name = NULL; + + return Success; +} + + +void EndPrefsNotify(struct NotifyRequest *notify) +{ + if (notify->nr_Name) + { + struct Message *msg; + + EndNotify(notify); + + while (msg = GetMsg(notify->nr_stuff.nr_Msg.nr_Port)) + { + ReplyMsg(msg); + } + } +} + diff --git a/scalos/Plugins/OOP/TitleClock/prefs/prefs_file.h b/scalos/Plugins/OOP/TitleClock/prefs/prefs_file.h new file mode 100755 index 000000000..4a74e5149 --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/prefs/prefs_file.h @@ -0,0 +1,31 @@ +/* + * prefs_file.h + * + * $Date$ + * $Revision$ + * + * 20010716 DM Created. Will be used by prefs and plugin programs. + * Headers for functions to read and write prefs files. + * + */ + +#ifndef PREFS_FILE_H +#define PREFS_FILE_H + +#include + +#define SAVENAME "ENVARC:Scalos/title_clock.prefs" +#define USENAME "ENV:Scalos/title_clock.prefs" + +LONG ReadPrefsFile(CONST_STRPTR file, STRPTR datefmt, ULONG datelen, STRPTR timefmt, ULONG timelen); +LONG WritePrefsFile(CONST_STRPTR file, CONST_STRPTR datefmt, CONST_STRPTR timefmt); + +LONG LoadPrefs(STRPTR datefmt, ULONG datelen, STRPTR timefmt, ULONG timelen); +LONG SavePrefs(CONST_STRPTR datefmt, CONST_STRPTR timefmt); +LONG UsePrefs(CONST_STRPTR datefmt, CONST_STRPTR timefmt); + +BOOL StartPrefsNotify(struct NotifyRequest *notify); +void EndPrefsNotify(struct NotifyRequest *notify); + +#endif /* PREFS_FILE_H */ + diff --git a/scalos/Plugins/OOP/TitleClock/prefs/requesters.c b/scalos/Plugins/OOP/TitleClock/prefs/requesters.c new file mode 100644 index 000000000..32334d834 --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/prefs/requesters.c @@ -0,0 +1,173 @@ +/* + * requesters.c Various routines for ASL requester and such like + * + * $Date$ + * $Revision$ + * + * 0.1 + * 20010804 DM + Created + * + */ + +#include + +#include +#include +#include + +#include +#include + +#include +#include + +STRPTR SaveFileReq(struct Window *win) +{ + struct FileRequester *aslfr; + STRPTR fbuf = NULL; + ULONG fblen; + + if(NULL != (aslfr = AllocAslRequest(ASL_FileRequest, NULL)) ) + { + if(AslRequestTags(aslfr,ASLFR_Window, win, + ASLFR_SleepWindow, TRUE, + ASLFR_RejectIcons, TRUE, + ASLFR_DoSaveMode, TRUE, + TAG_DONE) ) + { + //printf("OK\n"); + fblen = 0; + if(aslfr->fr_Drawer) + { + /* add 1 for any possible / character */ + fblen += strlen(aslfr->fr_Drawer); + if(fblen) fblen++; + //printf("Dir='%s'\n", aslfr->fr_Drawer); + } + + if(aslfr->fr_File) + { + fblen += strlen(aslfr->fr_File); + //printf("File='%s'\n", aslfr->fr_File); + } + if(fblen) fblen++; + //printf("length of string name buffer=%lu\n", fblen); + + fbuf = AllocVec(fblen, MEMF_ANY|MEMF_CLEAR); + if(fbuf) + { + if(aslfr->fr_Drawer) + { + strcpy(fbuf, aslfr->fr_Drawer); + } + + if(aslfr->fr_File) + { + AddPart(fbuf, aslfr->fr_File, fblen); + } + //printf("complete name='%s'\n", fbuf); + } + + FreeAslRequest(aslfr); + } + else + { + FreeAslRequest(aslfr); + aslfr = NULL; + fbuf = NULL; + } + } + return(fbuf); +} + + +STRPTR OpenFileReq(struct Window *win) +{ + struct FileRequester *aslfr; + STRPTR fbuf = NULL; + ULONG fblen; + + if(NULL != (aslfr = AllocAslRequest(ASL_FileRequest, NULL)) ) + { + if(AslRequestTags(aslfr,ASLFR_Window, win, + ASLFR_SleepWindow, TRUE, + ASLFR_RejectIcons, TRUE, + TAG_DONE) ) + { + //printf("OK\n"); + fblen = 0; + if(aslfr->fr_Drawer) + { + /* add 1 for any possible / character */ + fblen += strlen(aslfr->fr_Drawer); + if(fblen) fblen++; + //printf("Dir='%s'\n", aslfr->fr_Drawer); + } + + if(aslfr->fr_File) + { + fblen += strlen(aslfr->fr_File); + //printf("File='%s'\n", aslfr->fr_File); + } + if(fblen) fblen++; + //printf("length of string name buffer=%lu\n", fblen); + + fbuf = AllocVec(fblen, MEMF_ANY|MEMF_CLEAR); + if(fbuf) + { + if(aslfr->fr_Drawer) + { + strcpy(fbuf, aslfr->fr_Drawer); + } + + if(aslfr->fr_File) + { + AddPart(fbuf, aslfr->fr_File, fblen); + } + //printf("complete name='%s'\n", fbuf); + } + + FreeAslRequest(aslfr); + } + else + { + FreeAslRequest(aslfr); + aslfr = NULL; + fbuf = NULL; + } + } + return(fbuf); +} + +#if 0 +// Small test program for the above functions +struct Library *AslBase; + +int main(void) +{ + STRPTR fbuf; + + if(NULL != (AslBase = OpenLibrary("asl.library", 38)) ) + { + fbuf = OpenFileReq(NULL); + if(fbuf) + { + printf("File name='%s'\n", fbuf); + FreeVec(fbuf); + } + + + fbuf = SaveFileReq(NULL); + if(fbuf) + { + printf("File name='%s'\n", fbuf); + FreeVec(fbuf); + } + + CloseLibrary(AslBase); + } + return(0); +} +#endif + + diff --git a/scalos/Plugins/OOP/TitleClock/prefs/requesters.h b/scalos/Plugins/OOP/TitleClock/prefs/requesters.h new file mode 100644 index 000000000..544412419 --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/prefs/requesters.h @@ -0,0 +1,28 @@ +/* + * requesters.h Protos for ASL requester and such like + * + * $Date$ + * $Revision$ + * + * 0.1 + * 20010804 DM + Created + * + */ + +#ifndef REQUESTERS_H +#define REQUESTERS_H + +#ifndef EXEC_TYPES_H +#include +#endif + +#ifndef INTUITION_INTUITION_H +#include +#endif + +STRPTR SaveFileReq(struct Window *win); +STRPTR OpenFileReq(struct Window *win); + + +#endif /* REQUESTERS_H */ + diff --git a/scalos/Plugins/OOP/TitleClock/prefs/saveicon.c b/scalos/Plugins/OOP/TitleClock/prefs/saveicon.c new file mode 100644 index 000000000..fec4197e1 --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/prefs/saveicon.c @@ -0,0 +1,51 @@ +/* + * saveicon.h Public protos for functions to deal with saving icons + * + * $Date$ + * $Revision$ + * + * 0.1 + * 20010804 DM + Created. Added one function to save an icon (currently only + * saves a default projet icon) for a file, if the file exists. + * + */ + +#include + +#include +#include +#include + +#include + + +BOOL SaveIcon(STRPTR filename) +{ + BOOL saved = FALSE; + BPTR flock; + struct DiskObject *ico; /* Icon to save */ + + if(filename) + { + /* Make sure file exists */ + flock = Lock(filename, ACCESS_READ); + UnLock(flock); + + if(flock) + { + if(NULL != (IconBase = OpenLibrary("icon.library", 36)) ) + { + ico = GetDefDiskObject(WBPROJECT); + if(ico) + { + saved = PutDiskObject(filename, ico); + FreeDiskObject(ico); + } + CloseLibrary(IconBase); + } + } + } + return(saved); +} + + diff --git a/scalos/Plugins/OOP/TitleClock/prefs/saveicon.h b/scalos/Plugins/OOP/TitleClock/prefs/saveicon.h new file mode 100644 index 000000000..d8c8fe0ff --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/prefs/saveicon.h @@ -0,0 +1,19 @@ +/* + * saveicon.h Public protos for functions to deal with saving icons + * + * $Date$ + * $Revision$ + * + */ + +#ifndef SAVEICON_H +#define SAVEICON_H + +#ifndef EXEC_TYPES_H +#include +#endif + +BOOL SaveIcon(STRPTR filename); + +#endif /* SAVEICON_H */ + diff --git a/scalos/Plugins/OOP/TitleClock/prefs/screen.c b/scalos/Plugins/OOP/TitleClock/prefs/screen.c new file mode 100644 index 000000000..b8dbc4071 --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/prefs/screen.c @@ -0,0 +1,104 @@ +/* + * screen.c - Functions for grabbing and creating public screens + * + * $Date$ + * $Revision$ + * + * 0.1 + * 20010717 DM Created - only a function for finding public screens ATM + * + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include +#ifdef __VBCC__ +#include +#endif + + + + +/* Finds the named public screen, or the default if NULL is supplied. + * Specifying FRONT will search for the frontmost public screen in the + * public screen list. Drops back to try to get Workbench if the named + * screen could not be found, and if that fails, the default pubscreen. + * Returns pointer to screen or NULL if one couldn't be found. + */ +struct Screen *FindPubScreen(STRPTR name) +{ + struct Screen *pub = NULL; /* The public screen we are going to lock */ + struct List *psl; /* The public screen list */ + struct PubScreenNode *psn; /* For traversing the public screen list */ + struct Screen *front; /* The frontmost screen */ + BOOL found; /* Flag to show when to stop traversing lists */ + char lockname[MAXPUBSCREENNAME+1]; /* buffer name of screen to try to lock */ + + + if(name) + { + /* If the name is valid, we are either looking for a named screen + * or the frontmost public screen. + */ + if(stricmp(name, "FRONT")==0) + { + /* Find the frontmost public screen and copy name int buffer */ + psl = LockPubScreenList(); + front = IntuitionBase->FirstScreen; + found = 0; + while(front && !found) + { + psn = (struct PubScreenNode *)psl->lh_Head; + while(psn->psn_Node.ln_Succ) + { + if(front==psn->psn_Screen && psn->psn_Flags&PSNF_PRIVATE==0) + { + found = 1; + strncpy(lockname, psn->psn_Node.ln_Name, MAXPUBSCREENNAME); + } + psn = (struct PubScreenNode *)psn->psn_Node.ln_Succ; + } + front = front->NextScreen; + } + UnlockPubScreenList(); + } + else + { + /* Not looking for front screen, so just copy name into buffer */ + strncpy(lockname, name, MAXPUBSCREENNAME); + } + + /* Try to lock named screen (either found at front or named) and + * if that fails, try to grab the default public screen. + */ + if(NULL == (pub = LockPubScreen(lockname)) ) + { + pub = LockPubScreen(NULL); + } + } /* if(name) */ + else + { + /* No name specified, go for the default public screen */ + pub = LockPubScreen(NULL); + } + + if(!pub) + { + /* If we reach here, we will have failed to lock either the named/front + * public screen and/or the default public screen. Try the one which + * should exist. + */ + pub = LockPubScreen("Workbench"); + } + + return(pub); +} + + diff --git a/scalos/Plugins/OOP/TitleClock/prefs/screen.h b/scalos/Plugins/OOP/TitleClock/prefs/screen.h new file mode 100644 index 000000000..c56218407 --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/prefs/screen.h @@ -0,0 +1,28 @@ +/* + * screen.h - Functions for grabbing and creating public screens + * + * $Date$ + * $Revision$ + * + * 0.1 + * 20010717 DM Created - only a function for finding public screens ATM + * + */ + + +#ifndef SCREEN_H +#define SCREEN_H + +#ifndef EXEC_TYPES_H +#include +#endif + +#ifndef INTUITION_SCREENS_H +#include +#endif + +struct Screen *FindPubScreen(STRPTR name); + +#endif /* SCREEN_H */ + + diff --git a/scalos/Plugins/OOP/TitleClock/prefs/tcp_locale.c b/scalos/Plugins/OOP/TitleClock/prefs/tcp_locale.c new file mode 100644 index 000000000..c106699f2 --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/prefs/tcp_locale.c @@ -0,0 +1,51 @@ +/* + * tcp_locale.c - The locale function(s) + * + * $Date$ + * $Revision$ + * + * 40.1 + * 20010719 DM Created. Only contains function for reading locale strings from + * the CatCompArray + * + */ + +#include +#include + +#define CATCOMP_ARRAY +#include "tcp_locale.h" + +struct Catalog *tcp_Catalog = NULL;/* Pointer to a catalog if we opne one */ +static STRPTR EmptyStr = ""; /* An empty string - pointer to this returned if we cannot find the locale string */ + + +STRPTR GetLocString(ULONG msgid) +{ + STRPTR str = EmptyStr; /* String corresponding to the ID we were passed */ + int i; /* index into catcomp array while parsing for built-in string */ + int maxstr; /* Maximum number of strings in array */ + + /* Find default string from built-in CatComp array */ + maxstr = sizeof(CatCompArray)/sizeof(CatCompArray[0]); + for(i = 0; i < maxstr; i++) + { + if(CatCompArray[i].cca_ID == msgid) + str = CatCompArray[i].cca_Str; + } + + if(i != maxstr) + { + /* Try to get string from catalog, only if the string was found in the + * defaults. If it wasn't found, chances are it will not be in the + * catalog, or at least will not be correct. Anyway, what's the program + * doing, searching for a string not part of the program? + */ + if(LocaleBase) + { + str = (STRPTR)GetCatalogStr(tcp_Catalog, (LONG)msgid, str); + } + } + return(str); +} + diff --git a/scalos/Plugins/OOP/TitleClock/prefs/tcp_locale.h b/scalos/Plugins/OOP/TitleClock/prefs/tcp_locale.h new file mode 100644 index 000000000..c0f42e28a --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/prefs/tcp_locale.h @@ -0,0 +1,27 @@ +/* + * tcp_locale.h - The locale stuff not automatically created + * + * $Date$ + * $Revision$ + * + * 40.1 + * 20010719 DM Created. Only contains function for reading locale strings from + * the CatCompArray and incldues the automatically created CatComp + * locale header file. + * + */ + +#ifndef TCP_LOCALE_H +#define TCP_LOCALE_H + +#include + +extern struct Catalog *tcp_Catalog; + +STRPTR GetLocString(ULONG msgid); + +#define CATCOMP_NUMBERS +#include "cc_locale.h" + +#endif /* TCP_LOCALE_H */ + diff --git a/scalos/Plugins/OOP/TitleClock/prefs/title_clock.cd b/scalos/Plugins/OOP/TitleClock/prefs/title_clock.cd new file mode 100644 index 000000000..f585254a5 --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/prefs/title_clock.cd @@ -0,0 +1,98 @@ +; $Date$ +; $Revision$ +; +#header CC_LOCALE +; NB: In all the label texts for gadgets, use the underscore character ('_') +; to make it underscored by gadtools when using the GUI. You should also +; make sure the texts which contain the letters for the shortcuts match the +; character which is after the underscore. If there is to be no shortcut, +; do not include the underscore character in the label and leave the shortcut +; line blank (the same goes for menu shortcuts). +; +; String for date format entry gadget label +MSG_DATE_GAD (//) +_Date +; String for shortcut key for above string. +MSG_DATE_SCT (//) +D +; Label for example text display gadgets +MSG_EXAMPLE_GAD (//) +Example +; Label for time format entry gadget. +MSG_TIME_GAD (//) +_Time +; Letter for keypresses to activate time format gadget. +MSG_TIME_SCT (//) +T +; Label for the button to save preferences +MSG_SAVE_GAD (//) +_Save +; Letter to press for Save shortcut +MSG_SAVE_SCT (//) +S +; Label for the button to use the preferences +MSG_USE_GAD (//) +_Use +; Letter to press for shortcut for above gadget +MSG_USE_SCT (//) +U +; Label for gadget to cancel the preferences +MSG_CANCEL_GAD (//) +_Cancel +; Letter to press for shortcut to above gadget +MSG_CANCEL_SCT (//) +C +; Text for first (Project) menu title +MSG_PROJECT_MENU (//) +Project +; Text for menu item to open prefs file from a requester +MSG_PROJECT_OPEN (//) +Open... +; Shortcut key for the above menu item +MSG_PROJECT_OPEN_SCT (//) +O +; Text for menu item to save prefs to a file with a requester +MSG_PROJECT_SAVEAS (//) +Save As... +; Shortcut key for the above menu item +MSG_PROJECT_SAVEAS_SCT (//) +A +; Text for menu item to quit program +MSG_PROJECT_QUIT (//) +Quit +; Shortcut key for the above menu item +MSG_PROJECT_QUIT_SCT (//) +Q +; Title for second menu - Edit (control of currently edited prefs) +MSG_EDIT_MENU (//) +Edit +; Text for menu item to set preferences to defaults +MSG_EDIT_RESET (//) +Reset to Defaults +; Shortcut key for above menu item +MSG_EDIT_RESET_SCT (//) +D +; Text for menu item to load last saved preferences +MSG_EDIT_LASTSAVED (//) +Last Saved +; Shortcut key for the above menu item +MSG_EDIT_LASTSAVED_SCT (//) +L +; Text for menu item to restore prefs to state at program start +MSG_EDIT_RESTORE (//) +Restore +; Shortcut key for above menu item +MSG_EDIT_RESTORE_SCT (//) +R +; Menu title for Settings (program prefs) menu title +MSG_SETTINGS_MENU (//) +Settings +; Menu item for creating icons +MSG_SETTINGS_CREATEICONS (//) +Create Icons? +; Shortcut key for above menu item +MSG_SETTINGS_CREATEICONS_SCT (//) +I +; Window title +MSG_WINDOW (//) +Titlebar Clock Plugin Preferences diff --git a/scalos/Plugins/OOP/TitleClock/prefs/title_clock.ct b/scalos/Plugins/OOP/TitleClock/prefs/title_clock.ct new file mode 100755 index 000000000..0d81f819a --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/prefs/title_clock.ct @@ -0,0 +1,123 @@ +## version $VER: XX.catalog XX.XX (XX.XX.XX) +## codeset X +## language X +; +; $Date$ +; $Revision$ +; +MSG_DATE_GAD + +; _Date +; +MSG_DATE_SCT + +; D +; +MSG_EXAMPLE_GAD + +; Example +; +MSG_TIME_GAD + +; _Time +; +MSG_TIME_SCT + +; T +; +MSG_SAVE_GAD + +; _Save +; +MSG_SAVE_SCT + +; S +; +MSG_USE_GAD + +; _Use +; +MSG_USE_SCT + +; U +; +MSG_CANCEL_GAD + +; _Cancel +; +MSG_CANCEL_SCT + +; C +; +MSG_PROJECT_MENU + +; Project +; +MSG_PROJECT_OPEN + +; Open... +; +MSG_PROJECT_OPEN_SCT + +; O +; +MSG_PROJECT_SAVEAS + +; Save As... +; +MSG_PROJECT_SAVEAS_SCT + +; A +; +MSG_PROJECT_QUIT + +; Quit +; +MSG_PROJECT_QUIT_SCT + +; Q +; +MSG_EDIT_MENU + +; Edit +; +MSG_EDIT_RESET + +; Reset to Defaults +; +MSG_EDIT_RESET_SCT + +; D +; +MSG_EDIT_LASTSAVED + +; Last Saved +; +MSG_EDIT_LASTSAVED_SCT + +; L +; +MSG_EDIT_RESTORE + +; Restore +; +MSG_EDIT_RESTORE_SCT + +; R +; +MSG_SETTINGS_MENU + +; Settings +; +MSG_SETTINGS_CREATEICONS + +; Create Icons? +; +MSG_SETTINGS_CREATEICONS_SCT + +; I +; +MSG_WINDOW + +; Titlebar Clock Plugin Preferences +; diff --git a/scalos/Plugins/OOP/TitleClock/prefs/title_clock_prefs.c b/scalos/Plugins/OOP/TitleClock/prefs/title_clock_prefs.c new file mode 100755 index 000000000..a76a1b4a1 --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/prefs/title_clock_prefs.c @@ -0,0 +1,267 @@ +/* title_clock_prefs.c + * + * $Date$ + * $Revision$ + * + * 40.3 + * 20010804 DM + Fixed a couple of enforcer hits on startup in interface.c/ShowExample() + * when trying to use the default locale settings before the GUI was opened. + * 40.2 + * 20010804 DM + Added main loop processing + * + * 40.1 + * 20010720 DM + Bumped version to be in line with the new plugin API (tested and works :). + * Increased required OS version to 3.0 (since that's waht Sclaos needs) + * + * 39.1 + * 20010716 DM + Created, only has skeleton code for reading prefs file, printing + * contents and opening/closing libraries. + * + * + * To do: + * Get it compiling properly with SAS/C + * Parse any arguments passed as either WBArgs or CLI + * Save myself as the default tool for the project icons + * MUI GUI? + * Bugfixes :) + * + */ + +#include + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include "title_clock_prefs.h" +#include "prefs_file.h" +#include "interface.h" +#include "tcp_locale.h" + + +/* Version string */ +#define VERSION_STR "40" +#define REVISION_STR "3" +#define DATE_STR " (04/08/01)" +char version[] = "$VER: title_clock.prefs " VERSION_STR "." REVISION_STR DATE_STR " ©2001 The Scalos Team"; + +char datestr[FORMAT_SIZE] = {0}; /* String for entering date format string - can be small since it should just be a few %'s */ +char timestr[FORMAT_SIZE] = {0}; /* as above, for time */ + +char date_ex[EXAMPLE_SIZE] = {0}; /* Some space to store the example date */ +char time_ex[EXAMPLE_SIZE] = {0}; /* as above, for time */ + +char date_re[FORMAT_SIZE] = {0}; /* Copy of the date loaded at the start for restore */ +char time_re[FORMAT_SIZE] = {0}; /* Copy of time " */ + +/* Global variables for library bases */ +struct IntuitionBase *IntuitionBase; +struct GfxBase *GfxBase; +struct Library *GadToolsBase; +T_LOCALEBASE LocaleBase; +T_UTILITYBASE UtilityBase; +struct Library *DiskfontBase; +struct Library *AslBase; /* Open/Save As requesters */ +struct Library *IconBase; /* For saving icons */ + +#ifdef __amigaos4__ +struct IntuitionIFace *IIntuition; +struct GraphicsIFace *IGraphics; +struct GadToolsIFace *IGadTools; +struct LocaleIFace *ILocale; +struct UtilityIFace *IUtility; +struct DiskfontIFace *IDiskfont; +struct AslIFace *IAsl; +struct IconIFace *IIcon; +#endif + +/* Opens all required libraries. If one of the essential libraries + * cannot be opened, it will return 0, else non-zero. Non-essential + * libraries for this program are locale and utility. + */ +int OpenLibs(void) +{ + /* Open essential libraries */ + IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 39); + if(!IntuitionBase) return(0); +#ifdef __amigaos4__ + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if(!IIntuition) return(0); +#endif + + GadToolsBase = OpenLibrary("gadtools.library", 39); + if(!GadToolsBase) return(0); +#ifdef __amigaos4__ + IGadTools = (struct GadToolsIFace *)GetInterface(GadToolsBase, "main", 1, NULL); + if(!IGadTools) return(0); +#endif + + GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 36); + if(!GfxBase) return(0); +#ifdef __amigaos4__ + IGraphics = (struct GraphicsIFace *)GetInterface((struct Library *)GfxBase, "main", 1, NULL); + if(!IGraphics) return(0); +#endif + + /* Open non-essential libraries (do not return failure for any of these) */ + LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 0); + UtilityBase = (T_UTILITYBASE) OpenLibrary("utility.library", 0); + DiskfontBase =OpenLibrary("diskfont.library", 0); + AslBase = OpenLibrary("asl.library", 36); + +#ifdef __amigaos4__ + if (LocaleBase) ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL); + if (UtilityBase) IUtility = (struct UtilityIFace *)GetInterface((struct Library *)UtilityBase, "main", 1, NULL); + if (DiskfontBase) IDiskfont = (struct DiskfontIFace *)GetInterface(DiskfontBase, "main", 1, NULL); + if (AslBase) IAsl = (struct AslIFace *)GetInterface(AslBase, "main", 1, NULL); +#endif + + if(LocaleBase) tcp_Catalog = OpenCatalog(NULL, (STRPTR)"title_clock_prefs.catalog", OC_BuiltInLanguage, "english", TAG_DONE); + + return(1); +} + + +/* Closes all opened libraries and sets base pointers to NULL */ +void CloseLibs(void) +{ +#ifdef __amigaos4__ + if(IAsl) DropInterface((struct Interface *)IAsl); + IAsl = NULL; +#endif + if(AslBase) CloseLibrary(AslBase); + AslBase = NULL; + +#ifdef __amigaos4__ + if(IGraphics) DropInterface((struct Interface *)IGraphics); + IGraphics = NULL; +#endif + if(GfxBase) CloseLibrary((struct Library *)GfxBase); + GfxBase = NULL; + +#ifdef __amigaos4__ + if(IGadTools) DropInterface((struct Interface *)IGadTools); + IGadTools = NULL; +#endif + if(GadToolsBase) CloseLibrary(GadToolsBase); + GadToolsBase = NULL; + +#ifdef __amigaos4__ + if(IIntuition) DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; +#endif + if(IntuitionBase) CloseLibrary((struct Library *)IntuitionBase); + IntuitionBase = NULL; + +#ifdef __amigaos4__ + if(IUtility) DropInterface((struct Interface *)IUtility); + IUtility = NULL; +#endif + if(UtilityBase) CloseLibrary((struct Library *)UtilityBase); + UtilityBase = NULL; + + if(LocaleBase) + { + if(tcp_Catalog) CloseCatalog(tcp_Catalog); + tcp_Catalog = NULL; + +#ifdef __amigaos4__ + if(ILocale) DropInterface((struct Interface *)IAsl); + ILocale = NULL; +#endif + CloseLibrary((struct Library *)LocaleBase); + } + LocaleBase = NULL; +} + + +/* Tries to force plugin to re-read prefs. Will work if the plugin has been + * OpenLibrary'd already (since it will be in the exec lists as title_clock.plugin + * i.e. without the path, so we can open it easily. + */ +void ForcePluginRead(void) +{ + struct Library *PluginBase; + + if(NULL != (PluginBase = OpenLibrary("title_clock.plugin", 40)) ) + { + //printf("plugin poened\n"); +// tcpl_ReReadPrefs(); + CloseLibrary(PluginBase); + } +} + + +int main(int argc, char **argv) +{ + ULONG winmask, mask, sigs; + WORD quit; + + //printf("argc=%d\n", argc); + + if(!OpenLibs()) return(20); + + /* Try to read prefs file and if that doesn't happen, set it to the default + * (blank strings will be interpreted as use the standard locale strings) + */ + if(!LoadPrefs(datestr, FORMAT_SIZE, timestr, FORMAT_SIZE)) + { + datestr[0] = '\0'; timestr[0] = '\0'; + } + + /* Take copies for the restore function */ + strcpy(date_re, datestr); + strcpy(time_re, timestr); + + //printf("Blah %s\n", datestr); + //printf("Blah %s\n", timestr); + + + /* + strcpy(datestr, ""); + strcpy(timestr, ""); + SavePrefs(datestr, timestr); + ForcePluginRead(); + */ + + quit = 0; + if(OpenMainWindow()) + { + while(!quit) + { + if(tcp_Window) winmask = (1L << tcp_Window->UserPort->mp_SigBit); else winmask=0L; + mask = winmask | SIGBREAKF_CTRL_C; + sigs = Wait(mask); + + if(sigs & winmask) quit = HandleMainMessages(); + if(sigs & SIGBREAKF_CTRL_C) quit = 1; + } + } + CloseMainWindow(); // yes, it should be here, because it needs to close any partial opens too + + CloseLibs(); + + return 0; +} + + +/* Not needed for vbcc */ +#if 0 +/* Main function run when program is run from WB */ +int wbmain(struct WBStartup *wbs) +{ + return(main(0, (char **)wbs)); +} +#endif + diff --git a/scalos/Plugins/OOP/TitleClock/prefs/title_clock_prefs.h b/scalos/Plugins/OOP/TitleClock/prefs/title_clock_prefs.h new file mode 100644 index 000000000..3d010bf70 --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/prefs/title_clock_prefs.h @@ -0,0 +1,30 @@ +// title_clock_prefs.h +// $Date$ +// $Revision$ + +#ifndef TITLE_CLOCK_PREFS_H +#define TITLE_CLOCK_PREFS_H + +/* Maximum lengths of strings for date/time formats and the examples */ +#define FORMAT_SIZE 32 +#define EXAMPLE_SIZE 64 + +extern char datestr[FORMAT_SIZE]; +extern char timestr[FORMAT_SIZE]; + +extern char date_ex[EXAMPLE_SIZE]; +extern char time_ex[EXAMPLE_SIZE]; + +extern char date_re[FORMAT_SIZE]; +extern char time_re[FORMAT_SIZE]; +// from debug.lib +extern int kprintf(const char *fmt, ...); + +// Debugging Macros +#define d1(x) ; +#define d2(x) x; + +void ForcePluginRead(void); + +#endif + diff --git a/scalos/Plugins/OOP/TitleClock/prefs/title_clock_prefs.info b/scalos/Plugins/OOP/TitleClock/prefs/title_clock_prefs.info new file mode 100755 index 0000000000000000000000000000000000000000..06939a5d3ea1a92c20d52e0cf7ce04091f1af191 GIT binary patch literal 2464 zcwViPe@s(X6vyv-ue5-~KI%4g3Z*nA)3{jy5d&Fa@H*Z3uIO7BtW-e`~k5~ z(dyU|_-D}qnPhH5+hpyg0VxKWnW1yZM7F3IW>!%;aZHdz3$*v{oJUdS{&CrE+s}LF zyz{;9zI(oX10vxFj=f}%yaFF3#GJXX$YS2a^^&ItCp>NRXG4LS>w83f+ zs3+zCxsZU196W>+tVoU_3Bwf;HTh4&C?PX5k@6`gA9&INR1mk!_htH!@{TF=Sfkh^ z&(K9OaZm76K}iDc3ARTS$c%)%AyWafaRwe{=6u-y175tt>cc4G7NUS;$o)(sAb>Lv z5Cg1$kW|?)TEa>AoI1F5v=0}+jmXRJO|>uFM49yx@|pG|?493U`uE=X$KWhTejFJw zDFJ6aM9v*XF6&1Yw|jxcO5~pFKH!cnl$CX-0k0UFfq$}}fY-+Tz_H*M$Qa!X0xQb^ zfsuU%0xi1)0yXu6KsB5U0^z}Y6r^RKAdbr3VaY%hs|5<|Jl@kPyJpq@=$)A({O<`M zwG6q+Dgi&Z;|1RFmcSjWN1I0Nk_LJ$lSfRlo$yJ46jNcm={ez5Tij~sICzX1jCYU1g*{iwK8X? zAyq-7Km}a9wcbabVSjShy;%TG@5^7k?v326)j5z-zPuEem|u{U2TwUkVg!y;aD60h zUz9iz=T>O+%LYhXuY6<$KKaP!6pTzIG8g6EBw2|`)Uc&$L+LHD9Fklf%`}&iqk}{T z`CqE4Y$Z|7E(@ojhTBs?lONs;hC4ggl#<2{r=P@7!^0JF;OMfb^{J_5Jf|%SDkQ;V zqLl$gRymJdBwZ43G7hS32cfW|@yuP)Q(KAwbxpE{C2d3M!1IL=pIYE?b~Lu#<7_$E z2OGa#nm!$7S2doRlU6hx=D{^{QAcAqT-z}xZFA?z>CodbZ$4c#9e(WaY(D)~*;M$4 zdXl;BX>x2PkKNH}cUE|rdyl8eRyhzeouKa5t5T`)!Q%w`W>5Cp$%)xB;+*~F?41y| zL)`Gfn$m-Lc^-Rfp1lpCT=Ry!YL9(Q^$}Y|gK#j1N`8;W?zHc+4XPiiY}-7ZV8hD8 z73*o`h@#r*y34EqQa-}mORA|Q-B#}7+q?bT8Cu>Oaj5+;Etf)O@f@KJ%4iR8G0mrS zl+f*w{X4R5tXQ$15IR7nJiwnO(dYr*MiTc$`jnz5#<>G=y-fQ#6UBIuiTs3t55*gp zs4;#)jJH_)dM3V`vT-XdQBXr-tY1B<)aMiy4>F7Cqomlo(;>A)(w1ahygOW7=~vaA zIIg?*Hylbo!v{5#Q83$YxHd(}!G-xH4L@ar@u(L(Fpa%GRx$pUOtm zd|DVPo?!JuQM>A#I795RpZVS0-!tn3lcK3Lpmbs_(e^1IHiN#C-5S0FYcr* zb6tMb$xgW=G(n)ChrQ literal 0 HcwPel00001 diff --git a/scalos/Plugins/OOP/TitleClock/readme.1st b/scalos/Plugins/OOP/TitleClock/readme.1st new file mode 100755 index 000000000..74a96cf24 --- /dev/null +++ b/scalos/Plugins/OOP/TitleClock/readme.1st @@ -0,0 +1,54 @@ +Titlebar clock plugin and preferences +Example (and useful) plugin for Scalos title bars, written in C +Shows the current time or date in a configurable format + +The prefs file is stored in ENVARC:Scalos/title_clock.prefs or +ENV:Scalos/title_clock.prefs. It's just an ASCII file with two lines in it. +The first line is the date format and the second line in the time format. + +However, there's a handy prefs program to edit this file. + +You can put these special symbols in the date and time strings to have the +following effects: + + %a - abbreviated weekday name + %A - weekday name + %b - abbreviated month name + %B - month name + %c - same as "%a %b %d %H:%M:%S %Y" + %C - same as "%a %b %e %T %Z %Y" + %d - day number with leading 0s + %D - same as "%m/%d/%y" + %e - day number with leading spaces + %h - abbreviated month name + %H - hour using 24-hour style with leading 0s + %I - hour using 12-hour style with leading 0s + %j - julian date + %m - month number with leading 0s + %M - the number of minutes with leading 0s + %n - insert a linefeed + %p - AM or PM strings + %q - hour using 24-hour style + %Q - hour using 12-hour style + %r - same as "%I:%M:%S %p" + %R - same as "%H:%M" + %S - number of seconds with leadings 0s + %t - insert a tab character + %T - same as "%H:%M:%S" + %U - week number, taking Sunday as first day of week + %w - weekday number + %W - week number, taking Monday as first day of week + %x - same as "%m/%d/%y" + %X - same as "%H:%M:%S" + %y - year using two digits with leading 0s + %Y - year using four digits with leading 0s + +Leaving the format blank will result in the default time or date format +being used, which is defined depending on the country and language you have +specified in your system Locale preferences. + +For some reason, if you use %R then any part of the string AFTER the %R will +not be parsed. It seems to be a feature of locale.library, honestly. If you +do need to put something after the time, then use %H:%M. + + diff --git a/scalos/Plugins/OOP/XTWindows/AutoMsg.h b/scalos/Plugins/OOP/XTWindows/AutoMsg.h new file mode 100644 index 000000000..98a1f187d --- /dev/null +++ b/scalos/Plugins/OOP/XTWindows/AutoMsg.h @@ -0,0 +1,38 @@ +// AutoMsg.h +// $Date$ +// $Revision$ + +struct AutoReplyPort +{ + struct MsgPort msgPort; + struct Interrupt inter; + struct ScalosBase *ScalosBase; // 56 + short numMsgs; +}; + + +#define InitAutoReplyPort( rp, sb ) \ + { \ + (rp)->inter.is_Node.ln_Type = NT_INTERRUPT; \ + (rp)->inter.is_Node.ln_Pri = 32; \ + (rp)->inter.is_Data = rp; \ + (rp)->inter.is_Code = (VOID (*)(VOID)) DISPATCHER_REF(FreeMsgInter); \ + (rp)->msgPort.mp_Flags = PA_SOFTINT; \ + (rp)->msgPort.mp_SigTask = &(rp)->inter; \ + (rp)->ScalosBase = sb; \ + (rp)->numMsgs = 0; \ + NewList( &(rp)->msgPort.mp_MsgList ); \ + } + +#define FreeAutoReplyPort( rp ) \ + { \ + while( (rp)->numMsgs > 0 ) \ + ; \ + } + +#define PutAutoMsg( mp, msg, rp ) \ + { \ + (rp)->numMsgs ++; \ + (msg)->mn_ReplyPort = &(rp)->msgPort; \ + PutMsg( mp, msg ); \ + } diff --git a/scalos/Plugins/OOP/XTWindows/XTWindows.c b/scalos/Plugins/OOP/XTWindows/XTWindows.c new file mode 100644 index 000000000..d8825b85e --- /dev/null +++ b/scalos/Plugins/OOP/XTWindows/XTWindows.c @@ -0,0 +1,312 @@ +/*----------------------------··· + · + · XTWindows.c + · + ----------------------------··*/ +// $Date$ +// $Revision$ + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include "AutoMsg.h" + +#include +#include "XTWindows.h" + +DISPATCHER_PROTO(FreeMsgInter); + + +extern struct ExecBase *SysBase; +struct DosLibrary *DOSBase = NULL; +struct IntuitionBase *IntuitionBase = NULL; +struct Library *IconobjectBase = NULL; +struct ScalosBase *ScalosBase = NULL; +T_INPUTDEVICE InputBase = NULL; +T_UTILITYBASE UtilityBase = NULL; +#ifdef __amigaos4__ +struct Library *NewlibBase = NULL; + +struct DOSIFace *IDOS = NULL; +struct IntuitionIFace *IIntuition = NULL; +struct IconobjectIFace *IIconobject = NULL; +struct ScalosIFace *IScalos = NULL; +struct InputIFace *IInput = NULL; +struct UtilityIFace *IUtility = NULL; +struct Interface *INewlib = NULL; +#endif + +static struct AutoReplyPort replyPort; + +//----------------------------------------------------------------------------· + +DISPATCHER(FreeMsgInter) +{ + struct AutoReplyPort *arp = (struct AutoReplyPort *) msg; + + (void) cl; + (void) obj; + + while (1) + { + struct ScalosMessage *sMsg; + + sMsg = (struct ScalosMessage *) GetMsg(&arp->msgPort); + if (NULL == sMsg) + { + arp->numMsgs--; + break; + } + SCA_FreeMessage(sMsg); + } + return 0; +} +DISPATCHER_END + +//----------------------------------------------------------------------------· +// LibInit / LibCleanup / GetClassInfo +//----------------------------------------------------------------------------· + +BOOL initPlugin(struct PluginBase *base) +{ +///FrexxStartFold1.2.0. + d1(KPrintF(__FUNC__ "/%ld: lib_OpenCnt=%lu\n", __LINE__, base->lib_OpenCnt)); + + if( !(DOSBase = (struct DosLibrary *)OpenLibrary( "dos.library", 37 )) ) + { + d1(KPrintF(__FUNC__ "/%ld: Failure!\n", __LINE__)); + return FALSE; + } +#ifdef __amigaos4__ + if( !(IDOS = (struct DOSIFace *)GetInterface((struct Library *)DOSBase, "main", 1, NULL))) + return FALSE; +#endif + + if( !(IntuitionBase = (struct IntuitionBase *)OpenLibrary( "intuition.library", 37 )) ) + { + d1(KPrintF(__FUNC__ "/%ld: Failure!\n", __LINE__)); + return FALSE; + } +#ifdef __amigaos4__ + if( !(IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL))) + return FALSE; +#endif + + if( !(IconobjectBase = OpenLibrary( "iconobject.library", 39 )) ) + { + d1(KPrintF(__FUNC__ "/%ld: Failure!\n", __LINE__)); + return FALSE; + } +#ifdef __amigaos4__ + if( !(IIconobject = (struct IconobjectIFace *)GetInterface((struct Library *)IconobjectBase, "main", 1, NULL))) + return FALSE; +#endif + + UtilityBase = (T_UTILITYBASE) OpenLibrary("utility.library", 39); + if (NULL == UtilityBase) + { + d1(KPrintF(__FUNC__ "/%ld: Failure!\n", __LINE__)); + return FALSE; + } +#ifdef __amigaos4__ + if( !(IUtility = (struct UtilityIFace *)GetInterface((struct Library *)UtilityBase, "main", 1, NULL))) + return FALSE; +#endif + if( !(ScalosBase = (struct ScalosBase *) OpenLibrary( "scalos.library", 39 )) ) + { + d1(KPrintF(__FUNC__ "/%ld: Failure!\n", __LINE__)); + return FALSE; + } +#ifdef __amigaos4__ + if( !(IScalos = (struct ScalosIFace *)GetInterface((struct Library *)ScalosBase, "main", 1, NULL))) + return FALSE; +#endif + + Disable(); + InputBase = (T_INPUTDEVICE) FindName(&SysBase->DeviceList, "input.device"); + Enable(); + + if( !InputBase ) + { + d1(KPrintF(__FUNC__ "/%ld: Failure!\n", __LINE__)); + return FALSE; + } +#ifdef __amigaos4__ + if( !(IInput = (struct InputIFace *)GetInterface((struct Library *)InputBase, "main", 1, NULL))) + return FALSE; + + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + return FALSE; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + return FALSE; +#endif + + InitAutoReplyPort( &replyPort, ScalosBase ); + + d1(KPrintF(__FUNC__ "/%ld: Success!\n", __LINE__)); + + return TRUE; +} +///FrexxEndFold1. + +void closePlugin(struct PluginBase *base) +{ +///FrexxStartFold1.2.0. + + d1(kprintf(__FUNC__ "/%ld: lib_OpenCnt=%lu\n", __LINE__, base->lib_OpenCnt)); + + FreeAutoReplyPort( &replyPort ); + +#ifdef __amigaos4__ + if (INewlib) + DropInterface(INewlib); + if( IScalos ) + DropInterface( (struct Interface *)IScalos ); + if( IUtility ) + DropInterface( (struct Interface *)IUtility ); + if( IIconobject ) + DropInterface( (struct Interface *)IIconobject ); + if( IIntuition ) + DropInterface( (struct Interface *)IIntuition ); + if( IDOS ) + DropInterface( (struct Interface *)IDOS ); + + if (NewlibBase) + CloseLibrary(NewlibBase); +#endif + if( ScalosBase ) + CloseLibrary( (struct Library *)ScalosBase ); + if (UtilityBase) + CloseLibrary((struct Library *) UtilityBase); + if( IconobjectBase ) + CloseLibrary( IconobjectBase ); + if( IntuitionBase ) + CloseLibrary( (struct Library *)IntuitionBase ); + if( DOSBase ) + CloseLibrary( (struct Library *)DOSBase ); +} +///FrexxEndFold1. + +//----------------------------------------------------------------------------· +// Main entry point +//----------------------------------------------------------------------------· + +M68KFUNC_P3(ULONG, Dispatcher, + A0, Class *, cl, + A2, Object *, obj, + A1, Msg, msg) +{ +/// + ULONG Result; + struct XTWindowsInstanceData *inst; + + switch (msg->MethodID) + { + case OM_NEW: + obj = (Object *) DoSuperMethodA( cl,obj,msg ); + if (obj) + { + inst = INST_DATA(cl,obj); + inst->windowTask = ((struct ScaRootList *)obj)->rl_WindowTask; + } + Result = (ULONG) obj; + break; + + case SCCM_Message: + { + struct msg_Message *methodMsg = (struct msg_Message *) msg; + + inst = INST_DATA(cl, obj); + + if (IDCMP_CLOSEWINDOW == methodMsg->msm_iMsg->Class) + { + if ( PeekQualifier() & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT) ) + { + BPTR lock, windowLock; + char *name; + + // --------------------··· Open parentdrawer ------------------------·· + inst->windowTask = ((struct ScaRootList *)obj)->rl_WindowTask; + lock = inst->windowTask->mt_WindowStruct->ws_Lock; + windowLock = ParentDir( lock ); + if( windowLock ) + { + name = AllocVec( 1000, 0 ); + if( name ) + { + if( NameFromLock( windowLock, name, 1000 ) ) + { + SCA_OpenDrawerByNameTags(name, TAG_END); +/* + struct TagItem tags[2] = { SCA_Path, 0, TAG_END }; + + tags[0].ti_Data = (ULONG)name; + SCA_OpenIconWindow( tags ); +*/ + } + FreeVec( name ); + } + UnLock( windowLock ); + } + } + } + Result = DoSuperMethodA(cl, obj, msg); + } + break; + + case SCCM_IconWin_Open: + { + if( !DoSuperMethodA(cl, obj, msg) ) + Result = FALSE; + else + { + inst = INST_DATA(cl, obj); + Result = TRUE; + + if ( PeekQualifier() & (IEQUALIFIER_LALT | IEQUALIFIER_RALT) ) + { + // --------------------··· Close window ------------------------·· + struct SM_CloseWindow *message; + + inst->windowTask = ((struct ScaRootList *)obj)->rl_WindowTask; + + if( inst->windowTask ) + { + message = (struct SM_CloseWindow *)SCA_AllocMessage( MTYP_CloseWindow, 0 ); + if( message ) + { + PutAutoMsg( inst->windowTask->mt_WindowStruct->ws_MessagePort, + &message->ScalosMessage.sm_Message, &replyPort ); + } + } + } + } + } + break; + + default: + Result = DoSuperMethodA(cl, obj, msg); + break; + } + + return Result; +} +M68KFUNC_END +///FrexxEndFold2. + + diff --git a/scalos/Plugins/OOP/XTWindows/XTWindows.h b/scalos/Plugins/OOP/XTWindows/XTWindows.h new file mode 100644 index 000000000..e7d1bcf17 --- /dev/null +++ b/scalos/Plugins/OOP/XTWindows/XTWindows.h @@ -0,0 +1,48 @@ +// XTWindows.h +// $Date$ +// $Revision$ + +#ifndef XTWINDOWS_H_INCLUDED +#define XTWINDOWS_H_INCLUDED + +#include + +#include "plugin.h" + +#if defined(__GNUC__) && !defined(mc68000) +#pragma pack(2) +#endif /* __GNUC__ */ + +struct XTWindowsBase +{ + struct PluginBase xtw_PluginBase; + struct ScaClassInfo pl_ClassInfo; +}; + +#if defined(__GNUC__) && !defined(mc68000) +#pragma pack() +#endif /* __GNUC__ */ + +BOOL initPlugin(struct PluginBase *base); +void closePlugin(struct PluginBase *base); + +/* ------------------------------------------------- */ + +struct XTWindowsInstanceData + { + struct ScaWindowTask *windowTask; + }; + +/* ------------------------------------------------- */ + +// from debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + + +#define d1(x) ; +#define d2(x) { Forbid(); x; Permit(); } + +/* ------------------------------------------------- */ + +#endif /* XTWINDOWS_H_INCLUDED */ diff --git a/scalos/Plugins/OOP/XTWindows/config.mk b/scalos/Plugins/OOP/XTWindows/config.mk new file mode 100755 index 000000000..4f83609cd --- /dev/null +++ b/scalos/Plugins/OOP/XTWindows/config.mk @@ -0,0 +1,71 @@ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +COMMON_DIR = $(TOPLEVEL)/common/Plugin + +INCLUDES += -I$(COMMON_DIR) + +vpath %.c $(COMMON_DIR) + +############################################################################## + +include $(COMMON_DIR)/config.mk + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + + +OPENDRAWERBYNAME_DIR = ../wb39_plugin + +############################################################################### +# MorphOS + +LFLAGS += -nostartfiles \ +# -lmempools +# + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += -nostartfiles \ +# + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +LFLAGS += -nostartfiles \ +# + + +else + +############################################################################### +# AmigaOS + +LFLAGS += -lscalos \ + -liconobject \ + -lmempools \ + -lstack \ + -lnix \ + -lnixmain \ + -lamiga21 \ + -lamiga \ + -lstubs \ + +endif +endif +endif diff --git a/scalos/Plugins/OOP/XTWindows/makefile b/scalos/Plugins/OOP/XTWindows/makefile new file mode 100644 index 000000000..7e6b03a30 --- /dev/null +++ b/scalos/Plugins/OOP/XTWindows/makefile @@ -0,0 +1,98 @@ +# makefile für Scalos xtwindows.plugin +# $Date$ + +############################################################# + +CSRCS = $(COMMON_DIR)/plugin-classic.c \ + XTWindows.c \ + +############################################################# + +SUBDIRMAKE = $(MAKE) -s -C +CATCOMP = CatComp +AS = phxAss +LD = slink +CC = sc +LIBS = LIB:scm.lib LIB:sc.lib LIB:mempools.lib \ + LIB:debug.lib LIB:amiga.lib +PRECOMP = Include:all.gst +ECHO = echo +OBJDIR = .sasobj +LNFLAGS = quiet batch noicons stripdebug SD +LNDBFLAGS = quiet batch noicons addsym SD +OPENPATH = ../wb39_Plugin +COMMON_DIR = ../../../common/Plugin + +.SUFFIXES: .s .asm .plugin .plugin.debug +############################################################# + +CFLAGS = optimize nostackcheck nover dbg=s DATA=far \ + idlen=64 ignore=306 \ + idir=///include \ + idir=///common/Plugin +AFLAGS = QUIET DS opt=NRQB NOEXE linedebug I=SC:Assembler_Headers +#AFLAGS = -t -iINCLUDE: + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +XSRCS = $(notdir $(CSRCS)) +OBJS = $(XSRCS:%.c=$(OBJDIR)/$(notdir %).o) + +############################################################# + +PLUGIN = xtwindows.plugin +DESTTOOL = Scalos:plugins/OOP/ + +############################################################# + +All: $(PLUGIN) \ + $(PLUGIN).debug +# install +# clean + +############################################################# + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-classic.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[1m\033[31m$<\033[0m\n' + @$(CC) $(CFLAGS) $*.c objectname $@ + +############################################################# + +$(OBJDIR)/XTWindows.o : XTWindows.h AutoMsg.h $(COMMON_DIR)/plugin.h + +$(OBJDIR)/plugin-classic.o : plugin_data.h \ + $(COMMON_DIR)/plugin.h $(COMMON_DIR)/plugin-common.c + +############################################################# + +$(PLUGIN) : $(OBJS) + @printf '\033[32mLink: \033[1m\033[31m$@\033[0m\n' + @$(LD) to $@ FROM $(OBJS) lib $(LIBS) $(LNFLAGS) + +$(PLUGIN).debug : $(OBJS) + @printf '\033[32mLink: \033[1m\033[31m$@\033[0m\n' + @$(LD) to $@ FROM $(OBJS) lib $(LIBS) $(LNDBFLAGS) + +############################################################# + +# copy all generated files to their final destinations +install: + @printf '\033[32mInstall: \033[31m\033[1m$(PLUGIN)\033[0m\n' + @copy $(PLUGIN) $(DESTTOOL) clone + +############################################################# + +# A little something to clean it all up +clean: + @printf '\033[32mDelete: \033[31m\033[1m' + @delete $(OBJS) $(PLUGIN) $(PLUGIN).debug + @printf '\033[0m' + +############################################################# diff --git a/scalos/Plugins/OOP/XTWindows/makefile-new b/scalos/Plugins/OOP/XTWindows/makefile-new new file mode 100755 index 000000000..28e53fc33 --- /dev/null +++ b/scalos/Plugins/OOP/XTWindows/makefile-new @@ -0,0 +1,69 @@ +# $Date: 2011-08-02 00:13:23 +0200 (Di, 02. Aug 2011) $ +# $Revision: 816 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(BEGIN_OBJS) \ + $(OBJDIR)/XTWindows.o \ + $(END_OBJS) \ +# + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Targets +# + +NAME = xtwindows.plugin +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + $(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + copy $(BINDIR)/$(NAME) Scalos:Plugins/OOP clone + + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* + +############################################################################## + + diff --git a/scalos/Plugins/OOP/XTWindows/plugin_data.h b/scalos/Plugins/OOP/XTWindows/plugin_data.h new file mode 100644 index 000000000..55dfe608c --- /dev/null +++ b/scalos/Plugins/OOP/XTWindows/plugin_data.h @@ -0,0 +1,38 @@ +// plugin_data.h +// $Date$ +// $Revision$ + +#ifndef PLUGIN_DATA_H_INCLUDED +#define PLUGIN_DATA_H_INCLUDED + +#include +#include + +#define PLUGIN_TYPE OOP + +#define LIB_BASETYPE struct XTWindowsBase + +#define LIB_VERSION 40 +#define LIB_REVISION 6 + +#define LIB_NAME "xtwindows.plugin" +#define LIB_VERSTRING "$VER: xtwindows.plugin " \ + STR(LIB_VERSION) "." STR(LIB_REVISION) \ + " (25.04.05) " COMPILER_STRING + +#define CI_CLASSNAME "IconWindow.sca" +#define CI_SUPERCLASSNAME "IconWindow.sca" +#define CI_PLUGINNAME "XTWindows class" +#define CI_DESCRIPTION "This class extends the windows functions " COMPILER_STRING +#define CI_AUTHOR "David Rydh" +#define CI_PRIORITY -70 +#define CI_INSTSIZE sizeof(struct XTWindowsInstanceData) +#define CI_HOOKFUNC Dispatcher + +//---------------------------------------------------------------------------- +// code and includes to define the structs and functions used above + +#include "XTWindows.h" + +#endif /* PLUGUN_DATA_H_INCLUDED */ + diff --git a/scalos/Plugins/OOP/XTWindows/xtwindows.doc b/scalos/Plugins/OOP/XTWindows/xtwindows.doc new file mode 100644 index 000000000..431d0f822 --- /dev/null +++ b/scalos/Plugins/OOP/XTWindows/xtwindows.doc @@ -0,0 +1,26 @@ +This was just a small test to try out the Scalos plugin-API but it is quite useful. + +xtwindows.plugin currently has only two features: + + +1) When you press a qualifier while opening a drawer/file (ALT) the window is closed. + +2) When you press a qualifier while closing a drawer (SHIFT) the parent-drawer is opened. + + +The qualifier isn't settable yet, but will be soon... I'll probably add some other useful +functions too. + + + +History +------- + +1.1 First release + +1.2 Fixed excessive stack-usage + + +Originally By David Rydh +http://scalos.satanicdreams.com +mailto:scalos@satanicdreams.com \ No newline at end of file diff --git a/scalos/Plugins/OOP/config.mk b/scalos/Plugins/OOP/config.mk new file mode 100755 index 000000000..d9f0ed362 --- /dev/null +++ b/scalos/Plugins/OOP/config.mk @@ -0,0 +1,35 @@ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += # + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += # + + +else + +############################################################################### +# AmigaOS + +LFLAGS += -lscalos -lpreferences -lstack -lnix -lnixmain -lamiga2 -lamiga -lstubs + +endif +endif + diff --git a/scalos/Plugins/OOP/makefile b/scalos/Plugins/OOP/makefile new file mode 100644 index 000000000..dd7800e61 --- /dev/null +++ b/scalos/Plugins/OOP/makefile @@ -0,0 +1,48 @@ +# makefile for Scalos OOP plugins +# $Date$ +# $Revision$ + +############################################################# + +SUBDIRS = DeviceFilter \ + TitleClock \ + title_freepens \ + title_envvar \ + title_test \ + wb39_plugin \ + XTWindows \ + +############################################################# + +.PHONY: All install clean + +############################################################# + +define build_subdir +$(MAKE) -s --directory=$(1); +endef + +define install_subdir +$(MAKE) -s install --directory=$(1); +endef + +define clean_subdir +$(MAKE) -s clean --directory=$(1); +endef + +############################################################# + +All: + @$(foreach subdir,$(SUBDIRS),$(call build_subdir,$(subdir))) + +############################################################# + +install: + @$(foreach subdir,$(SUBDIRS),$(call install_subdir,$(subdir))) + +############################################################# + +clean: + @$(foreach subdir,$(SUBDIRS),$(call clean_subdir,$(subdir))) + +############################################################# diff --git a/scalos/Plugins/OOP/makefile-new b/scalos/Plugins/OOP/makefile-new new file mode 100755 index 000000000..932370586 --- /dev/null +++ b/scalos/Plugins/OOP/makefile-new @@ -0,0 +1,32 @@ +# $Date: 2009-02-17 21:22:13 +0100 (Di, 17. Feb 2009) $ +# $Revision: 5 $ +############################################################# +TOPLEVEL = $(shell pwd)/../.. + +include config.mk + +############################################################################## +# +# Project subdirectories +# + +SUBDIRS = wb39_plugin \ + DeviceFilter \ + XTWindows \ + title_freepens \ + TitleClock \ + title_envvar \ +# title_test \ + +############################################################################## + +.PHONY: all install clean + +all: all_subdirs + +clean: clean_subdirs + +install: install_subdirs + +nodebug: nodebug_subdirs + diff --git a/scalos/Plugins/OOP/title_envvar/config.mk b/scalos/Plugins/OOP/title_envvar/config.mk new file mode 100755 index 000000000..10dba47eb --- /dev/null +++ b/scalos/Plugins/OOP/title_envvar/config.mk @@ -0,0 +1,64 @@ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +COMMON_DIR = $(TOPLEVEL)/common/Plugin + +INCLUDES += -I$(COMMON_DIR) + +vpath %.c $(COMMON_DIR) + +############################################################################## + +include $(COMMON_DIR)/config.mk + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += -nostartfiles \ + -lmempools +# + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += -nostartfiles \ +# + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +LFLAGS += -nostartfiles \ +# + + +else + +############################################################################### +# AmigaOS + +LFLAGS += -lmempools \ + -lstack \ + -lamiga21 \ + -lamiga \ + -lstubs \ + +endif +endif +endif diff --git a/scalos/Plugins/OOP/title_envvar/libfuncs.c b/scalos/Plugins/OOP/title_envvar/libfuncs.c new file mode 100755 index 000000000..80ddd2b62 --- /dev/null +++ b/scalos/Plugins/OOP/title_envvar/libfuncs.c @@ -0,0 +1,217 @@ +/* +** libfuncs.c +** +// $Date$ +// $Revision$ +*/ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include "plugin_data.h" + +//---------------------------------------------------------------- + +/* This is the UWORD which contains the ASCII value of +** the characters that this plugin should be activated by. +** in this case the ASCII characters are 0x65 followed by +** 0x76 which corresponds to "ev". This means that to +** activate this plugin you need to have "%ev" enetered +** somewhere in the title string in the Scalos main prefs. +*/ +#define PARSE 0x6576 + +//---------------------------------------------------------------- + +struct DosLibrary *DOSBase = NULL; + +#ifdef __amigaos4__ +/* On OS4 DoSuperMethod is part of intuition.library */ +struct IntuitionBase *IntuitionBase = NULL; +struct IntuitionIFace *IIntuition = NULL; +struct DOSIFace *IDOS = NULL; +struct Library *NewlibBase = NULL; +struct Interface *INewlib = NULL; +#endif /* __amigaos4__ */ + +STRPTR VersTag = LIB_VERSTRING; + + +BOOL initPlugin(APTR base) +{ + DOSBase = (struct DosLibrary *) OpenLibrary(DOSNAME, 39); + if (NULL == DOSBase) + return FALSE; +#ifdef __amigaos4__ + IDOS = (struct DOSIFace *)GetInterface((struct Library *)DOSBase, "main", 1, NULL); + if (NULL == IDOS) + return FALSE; + + IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0); + if (NULL == IntuitionBase) + return FALSE; + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + return FALSE; + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + return FALSE; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + return FALSE; +#endif /* __amigaos4__ */ + + return TRUE; +} + +void closePlugin(APTR base) +{ +#ifdef __amigaos4__ + if (INewlib) + { + DropInterface(INewlib); + INewlib = NULL; + } + if (NewlibBase) + { + CloseLibrary(NewlibBase); + NewlibBase = NULL; + } + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } + if(IntuitionBase) + { + CloseLibrary((struct Library *)IntuitionBase); + IntuitionBase = NULL; + } + + if (IDOS) + { + DropInterface((struct Interface *)IDOS); + IDOS = NULL; + } +#endif + if (DOSBase) + { + CloseLibrary((struct Library *) DOSBase); + DOSBase = NULL; + } +} + +//---------------------------------------------------------------- + +/* The actual (hook) function which does the work for this plugin + + NAME + EnvVar + + SYNOPSIS + success = EnvVar(cls, object, message) + D0 A0 A2 A1 + + LONG = EnvVar(Class *, struct ScaRootList *, struct Title_Translate_Params *) + + FUNCTION + To add the number of free pens to the title (bar) in Scalos + + INPUTS + cls - Pointer to the class from which this function was called + object - the ScaRootList pointer from Scalos + message - the message being passed to our function that we must act on + NB: These will always be the same except for the type of message that is + passed. Check scalos/scalos.h for what will be passed in the message for + a particular method. + + RESULT + success - boolean to show success or failure. + NB: This is different for different methods, so check what the return + value should be for a particular method in scalos/scalos.h + + SEE ALSO + scalos/scalos.h +*/ +M68KFUNC_P3(ULONG, EnvVar, + A0, Class *, cls, + A2, Object *, object, + A1, Msg, message) +{ + Class *keepclass = cls; /* a copy of the class just in case: register A0 is a scratch register remember */ + struct msg_Translate *msg = (struct msg_Translate *)message; /* a copy of the message just in case: register A1 is a scratch register remember */ + + /* Make sure that the method being called is the title translate method */ + if(msg->mxl_MethodID == SCCM_Title_Translate) + { + /* also check that the parse characters we have been passed are the ones that our + ** function will deal with */ + if(msg->mxl_ParseID == PARSE) + { + char VarName[128]; + CONST_STRPTR FmtPtr; + STRPTR DestPtr; + size_t Len; + ULONG Success = FALSE; + + for (FmtPtr = msg->mxl_TitleFormat, DestPtr = VarName, Len = sizeof(VarName); + *FmtPtr && '?' != *FmtPtr && Len > 1; + *DestPtr++ = *FmtPtr++, Len--) + ; + if ('?' == *FmtPtr) + { + // End of variable name found. + LONG VarLen; + + *DestPtr = '\0'; + + // Skip variable name + msg->mxl_TitleFormat = FmtPtr + 1; + + // First, check for local variable + VarLen = GetVar(VarName, msg->mxl_Buffer, msg->mxl_BuffLen, GVF_LOCAL_ONLY); + + // if no local variable found, check global variable + if (-1 == VarLen) + VarLen = GetVar(VarName, msg->mxl_Buffer, msg->mxl_BuffLen, GVF_GLOBAL_ONLY); + + if (VarLen > 0) + { + /* Advance the pointer to the title text to the new end + ** of the title Text (add on the number of characters we have added + */ + Success = TRUE; + msg->mxl_BuffLen -= VarLen; + msg->mxl_Buffer += VarLen; + } + } + + /* return boolean success value. Note that this may differ + ** depending on what method you are dealing with + */ + return Success; + } + } + + /* Call superclass method if we have failed to do something (this method does not get processed by + ** this function, the parse characters were not what we were looking for, etc) */ + return (ULONG) DoSuperMethodA(keepclass, object, (Msg)msg); +} +M68KFUNC_END + diff --git a/scalos/Plugins/OOP/title_envvar/makefile b/scalos/Plugins/OOP/title_envvar/makefile new file mode 100644 index 000000000..cf65b1050 --- /dev/null +++ b/scalos/Plugins/OOP/title_envvar/makefile @@ -0,0 +1,86 @@ +# makefile for SAS/C +# $Date$ + +############################################################# + +.SUFFIXES: .s .asm .plugin .plugin.debug + +############################################################# + +CC = sc +CFLAGS = optimize nostackcheck nover dbg=s DATA=far \ + idlen=64 idir=///include +LD = slink +ECHO = echo +LDFLAGS = quiet batch noicons SD +LIBS = LIB:sc.lib LIB:debug.lib LIB:amiga.lib +ECHO = echo +OBJDIR = .sasobj +COMMON_DIR = ../../../common/Plugin + +############################################################# + +PLUGNAME = title_envvar.plugin + +############################################################# + +all: $(PLUGNAME) $(PLUGNAME).debug +# install +# clean + +############################################################# + +CSRCS = $(COMMON_DIR)/plugin-classic.c \ + libfuncs.c + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +XSRCS = $(notdir $(CSRCS)) +OBJS = $(XSRCS:%.c=$(OBJDIR)/$(notdir %).o) + +############################################################# + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-classic.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $*.c objectname $@ + +############################################################# + +# CLI command used when linking the final executable +$(PLUGNAME) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) to $@ FROM $(OBJS) lib $(LIBS) $(LDFLAGS) STRIPDEBUG + +$(PLUGNAME).debug : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) to $@ FROM $(OBJS) lib $(LIBS) $(LDFLAGS) ADDSYM + +############################################################# + +$(OBJDIR)/plugin-classic.o : plugin_data.h \ + $(COMMON_DIR)/plugin.h $(COMMON_DIR)/plugin-common.c + + +############################################################# + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(PLUGNAME)\033[0m\n' + @copy $(PLUGNAME) Scalos:Plugins/OOP clone + +############################################################# + + +# A little something to clean it all up +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + -@delete $(OBJS) $(PLUGNAME) $(PLUGNAME).debug + @printf '\033[0m' + +############################################################# diff --git a/scalos/Plugins/OOP/title_envvar/makefile-new b/scalos/Plugins/OOP/title_envvar/makefile-new new file mode 100755 index 000000000..5e3adb999 --- /dev/null +++ b/scalos/Plugins/OOP/title_envvar/makefile-new @@ -0,0 +1,69 @@ +# $Date: 2011-08-02 00:13:23 +0200 (Di, 02. Aug 2011) $ +# $Revision: 816 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(BEGIN_OBJS) \ + $(OBJDIR)/libfuncs.o \ + $(END_OBJS) \ +# + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Targets +# + +NAME = title_envvar.plugin +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + $(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + copy $(BINDIR)/$(NAME) Scalos:Plugins/OOP clone + + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* + +############################################################################## + + diff --git a/scalos/Plugins/OOP/title_envvar/plugin_data.h b/scalos/Plugins/OOP/title_envvar/plugin_data.h new file mode 100644 index 000000000..992989ab4 --- /dev/null +++ b/scalos/Plugins/OOP/title_envvar/plugin_data.h @@ -0,0 +1,43 @@ +// plugin_data.h +// $Date$ +// $Revision$ + +#ifndef PLUGIN_DATA_H_INCLUDED +#define PLUGIN_DATA_H_INCLUDED + +#include +#include + +#include +#include + +#define PLUGIN_TYPE OOP + +#define LIB_VERSION 40 /* Version of our plugin */ +#define LIB_REVISION 2 /* Revision of our plugin */ +#define NAME "title_envvar" /* Name of our plugin (must be the same as the executable filename minus the .plugin [gets added later]) */ +#define LIBVER STR(LIB_VERSION) "." STR(LIB_REVISION) /* part of the version string for our plugin */ + +#define LIB_NAME NAME ".plugin" +#define LIB_IDSTRING NAME LIBVER " " COMPILER_STRING +#define LIB_VERSTRING "\0$VER: " LIB_NAME " " LIBVER " (07.11.2009) " COMPILER_STRING + +#define CI_CLASSNAME "Title.sca" +#define CI_SUPERCLASSNAME "Title.sca" +#define CI_PLUGINNAME "Title ENVVar" +#define CI_DESCRIPTION "Adds a %ev function to the screentitle " \ + "to show the contents of an ENV variable. " COMPILER_STRING +#define CI_AUTHOR "Michael Knoke" + +#define CI_HOOKFUNC EnvVar + +#ifndef __amigaos4__ +#define NOINITPLUGIN +#define NOCLOSEPLUGIN +#endif + +//---------------------------------------------------------------------------- +// code and includes to define the structs and functions used above + +#endif /* PLUGUN_DATA_H_INCLUDED */ + diff --git a/scalos/Plugins/OOP/title_freepens/config.mk b/scalos/Plugins/OOP/title_freepens/config.mk new file mode 100755 index 000000000..94aa79715 --- /dev/null +++ b/scalos/Plugins/OOP/title_freepens/config.mk @@ -0,0 +1,69 @@ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +COMMON_DIR = $(TOPLEVEL)/common/Plugin + +INCLUDES += -I$(COMMON_DIR) + +vpath %.c $(COMMON_DIR) + +############################################################################## + +include $(COMMON_DIR)/config.mk + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += -nostartfiles \ + -lmempools +# + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += -nostartfiles \ +# + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +LFLAGS += -nostartfiles \ +# + + +else + +############################################################################### +# AmigaOS + +LFLAGS += -lscalos \ + -lpreferences \ + -liconobject \ + -lmempools \ + -lstack \ + -lnix \ + -lnixmain \ + -lamiga21 \ + -lamiga \ + -lstubs \ + +endif +endif +endif diff --git a/scalos/Plugins/OOP/title_freepens/libfuncs.c b/scalos/Plugins/OOP/title_freepens/libfuncs.c new file mode 100755 index 000000000..51bfbcbb8 --- /dev/null +++ b/scalos/Plugins/OOP/title_freepens/libfuncs.c @@ -0,0 +1,198 @@ +/* +** libfuncsc +** 19th May 2000 +** David McMinn +** The actual public functions that are in our plugin. Remember, there +** is only one public function in a Scalos plugin, and it simply returns +** a pointer to a ScaClassInfo. The h_Entry field of the Hook structure +** within the ScaClassInfo structure points to the actual function which +** performs the task required (adding text to the titles of screens, +** windows etc). +// $Date$ +// $Revision$ +*/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include + +#include "plugin_data.h" + +/* This is the UWORD which contains the ASCII value of +** the characters that this plugin should be activated by. +** in this case the ASCII characters are 0x77 followed by +** 0x70 which corresponds to w and p. This means that to +** activate this plugin you need to have "%wp" enetered +** somewhere in the title string in the Scalos main prefs. +*/ +#define PARSE 0x7770 + + +#if 0 +/* Our own version of the strlen function, to save having to link +** the standard libraries +*/ +ULONG strlen(STRPTR s0) +{ + ULONG n=0; + while(*s0++) + { + n++; + } + return(n); +} +#endif + +#ifdef __amigaos4__ +/* On OS4 DoSuperMethod is part of intuition.library */ +struct IntuitionBase *IntuitionBase = NULL; +struct IntuitionIFace *IIntuition = NULL; +struct Library *NewlibBase; +struct Interface *INewlib; +#endif /* __amigaos4__ */ + +STRPTR VersTag = LIB_VERSTRING; + +BOOL initPlugin(APTR base) +{ +#ifdef __amigaos4__ + IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0); + if (NULL == IntuitionBase) + return FALSE; + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + return FALSE; + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + return FALSE; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + return FALSE; +#endif /* __amigaos4__ */ + + return TRUE; +} + +void closePlugin(APTR base) +{ +#ifdef __amigaos4__ + if (INewlib) + { + DropInterface(INewlib); + INewlib = NULL; + } + if (NewlibBase) + { + CloseLibrary(NewlibBase); + NewlibBase = NULL; + } + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } + if(IntuitionBase) + { + CloseLibrary((struct Library *)IntuitionBase); + IntuitionBase = NULL; + } +#endif /* __amigaos4__ */ +} + +/* The actual (hook) function which does the work for this plugin + + NAME + FreePens + + SYNOPSIS + success = FreePens(cls, object, message) + D0 A0 A2 A1 + + LONG = FreePens(Class *, struct ScaRootList *, struct Title_Translate_Params *) + + FUNCTION + To add the number of free pens to the title (bar) in Scalos + + INPUTS + cls - Pointer to the class from which this function was called + object - the ScaRootList pointer from Scalos + message - the message being passed to our function that we must act on + NB: These will always be the same except for the type of message that is + passed. Check scalos/scalos.h for what will be passed in the message for + a particular method. + + RESULT + success - boolean to show success or failure. + NB: This is different for different methods, so check what the return + value should be for a particular method in scalos/scalos.h + + SEE ALSO + scalos/scalos.h +*/ +M68KFUNC_P3(ULONG, FreePens, + A0, Class *, cls, + A2, Object *, obj, + A1, Msg, message) +{ + Class *keepclass = cls; /* a copy of the class just in case: register A0 is a scratch register remember */ + struct msg_Translate *msg = (struct msg_Translate *)message; /* a copy of the message just in case: register A1 is a scratch register remember */ + ULONG freepens = 0; /* a count of the number of free pens */ + struct ScaRootList *object = (struct ScaRootList *)obj; + + /* Make sure that the method being called is the title translate method */ + if(msg->mxl_MethodID == SCCM_Title_Translate) + { + /* also check that the parse characters we have been passed are the ones that our + ** function will deal with */ + if(msg->mxl_ParseID == PARSE) + { + /* if the pointer to the Scalos screen is valid, then work our + ** way through the vast amounts of pointers :) to get the + ** number of free pens in the screen + */ + if(object->rl_internInfos->ii_Screen != NULL) + freepens = (ULONG)object->rl_internInfos->ii_Screen->ViewPort.ColorMap->PalExtra->pe_NFree; + + if (msg->mxl_BuffLen >= 4) + { + size_t Length; + + /* Add our text to the end of the title text*/ + sprintf(msg->mxl_Buffer, "%lu", (unsigned long)freepens); + + /* Advance the pointer to the title text to the new end + ** of the title Text (add on the number of characters we have added + */ + Length = strlen(msg->mxl_Buffer); + msg->mxl_BuffLen -= Length; + msg->mxl_Buffer += Length; + } + + /* return boolean success value. Note that this may differ + ** depending on what method you are dealing with + */ + return(1); + } + } + + /* Call superclass method if we have failed to do something (this method does not get processed by + ** this function, the parse characters were not what we were looking for, etc) */ + return (ULONG) DoSuperMethodA(keepclass, (Object *)object, (Msg) msg); +} +M68KFUNC_END + diff --git a/scalos/Plugins/OOP/title_freepens/makefile b/scalos/Plugins/OOP/title_freepens/makefile new file mode 100755 index 000000000..92b92f1a8 --- /dev/null +++ b/scalos/Plugins/OOP/title_freepens/makefile @@ -0,0 +1,86 @@ +# makefile for SAS/C +# $Date$ + +############################################################# + +.SUFFIXES: .s .asm .plugin .plugin.debug + +############################################################# + +CC = sc +CFLAGS = optimize nostackcheck nover dbg=s DATA=far \ + idlen=64 idir=///include +LD = slink +ECHO = echo +LDFLAGS = quiet batch noicons SD +LIBS = LIB:sc.lib LIB:debug.lib LIB:amiga.lib +ECHO = echo +OBJDIR = .sasobj +COMMON_DIR = ../../../common/Plugin + +############################################################# + +PLUGNAME = title_freepens.plugin + +############################################################# + +all: $(PLUGNAME) $(PLUGNAME).debug +# install +# clean + +############################################################# + +CSRCS = $(COMMON_DIR)/plugin-classic.c \ + libfuncs.c + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +XSRCS = $(notdir $(CSRCS)) +OBJS = $(XSRCS:%.c=$(OBJDIR)/$(notdir %).o) + +############################################################# + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-classic.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $*.c objectname $@ + +############################################################# + +# CLI command used when linking the final executable +$(PLUGNAME) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) to $@ FROM $(OBJS) lib $(LIBS) $(LDFLAGS) STRIPDEBUG + +$(PLUGNAME).debug : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) to $@ FROM $(OBJS) lib $(LIBS) $(LDFLAGS) ADDSYM + +############################################################# + +$(OBJDIR)/plugin-classic.o : plugin_data.h \ + $(COMMON_DIR)/plugin.h $(COMMON_DIR)/plugin-common.c + + +############################################################# + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(PLUGNAME)\033[0m\n' + @copy $(PLUGNAME) Scalos:Plugins/OOP clone + +############################################################# + + +# A little something to clean it all up +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + -@delete $(OBJS) $(PLUGNAME) $(PLUGNAME).debug + @printf '\033[0m' + +############################################################# diff --git a/scalos/Plugins/OOP/title_freepens/makefile-new b/scalos/Plugins/OOP/title_freepens/makefile-new new file mode 100755 index 000000000..b35f22804 --- /dev/null +++ b/scalos/Plugins/OOP/title_freepens/makefile-new @@ -0,0 +1,69 @@ +# $Date: 2011-08-02 00:13:23 +0200 (Di, 02. Aug 2011) $ +# $Revision: 816 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(BEGIN_OBJS) \ + $(OBJDIR)/libfuncs.o \ + $(END_OBJS) \ +# + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Targets +# + +NAME = title_freepens.plugin +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + $(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + copy $(BINDIR)/$(NAME) Scalos:Plugins/OOP clone + + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* + +############################################################################## + + diff --git a/scalos/Plugins/OOP/title_freepens/plugin_data.h b/scalos/Plugins/OOP/title_freepens/plugin_data.h new file mode 100644 index 000000000..cecc0fe83 --- /dev/null +++ b/scalos/Plugins/OOP/title_freepens/plugin_data.h @@ -0,0 +1,43 @@ +// plugin_data.h +// $Date$ +// $Revision$ + +#ifndef PLUGIN_DATA_H_INCLUDED +#define PLUGIN_DATA_H_INCLUDED + +#include +#include + +#include +#include + +#define PLUGIN_TYPE OOP + +#define LIB_VERSION 40 /* Version of our plugin */ +#define LIB_REVISION 3 /* Revision of our plugin */ +#define NAME "title_freepens"/* Name of our plugin (must be the same as the executable filename minus the .plugin [gets added later]) */ +#define LIBVER STR(LIB_VERSION) "." STR(LIB_REVISION) /* part of the version string for our plugin */ + +#define LIB_NAME NAME ".plugin" +#define LIB_IDSTRING NAME LIBVER " " COMPILER_STRING +#define LIB_VERSTRING "\0$VER: " LIB_NAME " " LIBVER " (07.11.2009) " COMPILER_STRING + +#define CI_CLASSNAME "Title.sca" +#define CI_SUPERCLASSNAME "Title.sca" +#define CI_PLUGINNAME "Title FreePens" +#define CI_DESCRIPTION "Adds a %wp function to the screentitle to " \ + "show all free pens. " COMPILER_STRING +#define CI_AUTHOR "David McMinn, Stefan Sommerfield" + +#define CI_HOOKFUNC FreePens + +#ifndef __amigaos4__ +#define NOINITPLUGIN +#define NOCLOSEPLUGIN +#endif + +//---------------------------------------------------------------------------- +// code and includes to define the structs and functions used above + +#endif /* PLUGUN_DATA_H_INCLUDED */ + diff --git a/scalos/Plugins/OOP/title_test/makefile b/scalos/Plugins/OOP/title_test/makefile new file mode 100644 index 000000000..76d2eb01e --- /dev/null +++ b/scalos/Plugins/OOP/title_test/makefile @@ -0,0 +1,81 @@ +# makefile for title_test.plugin +# $Date$ +# using SAS/C + +############################################################# + +.SUFFIXES: .s .asm .plugin .plugin.debug + +############################################################# + +CHEADERS = +CC = sc +CFLAGS = nostkchk nochkabort strcons strmer opt dbg=ff nover \ + streq data=far idir=sc:include/ idir=include: \ + idlen=64 idir=///include +AS = phxass +AFLAGS = quiet m=68020 linedebug opt=NRQB i=SC:Assembler_Headers +LD = slink +ECHO = echo +LDFLAGS = quiet batch noicons sd +LDLIBS = LIB:sc.lib LIB:debug.lib LIB:amiga.lib +CSTARTUP = +OBJDIR = .sasobj + +############################################################# + +PLUGNAME = title_test.plugin + +############################################################# + +all: $(PLUGNAME) + +############################################################# + +CSRCS = +ASRCS = title_test.s + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +OBJS = $(ASRCS:%.s=$(OBJDIR)/%.o) $(CSRCS:%.c=$(OBJDIR)/%.o) + +############################################################# + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile $<\033[0m\n' + @$(CC) $(CFLAGS) $*.c objectname $@ + +$(OBJDIR)/%.o : %.s + @printf '\033[32mAssemble $<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +$(OBJDIR)/%.o : %.asm + @printf '\033[32mAssemble $<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +############################################################# + +$(PLUGNAME): $(OBJS) + @printf '\033[32mLink $@\033[0m\n' + @$(LD) FROM $(OBJS) TO $(PLUGNAME) LIB $(LDLIBS) $(DBFLAG) $(LDFLAGS) stripdebug + @$(LD) FROM $(OBJS) TO $(PLUGNAME).debug LIB $(LDLIBS) $(DBFLAG) $(LDFLAGS) addsym + +############################################################# + +$(OBJDIR)/title_test : scalos_macros.i + +############################################################# + +# A little something to clean it all up +clean: + -@delete $(OBJS) $(PLUGNAME) $(PLUGNAME).debug + +############################################################# + +install: + copy $(PLUGNAME) Scalos:Plugins/OOP clone + +############################################################# diff --git a/scalos/Plugins/OOP/title_test/scalos_macros.i b/scalos/Plugins/OOP/title_test/scalos_macros.i new file mode 100755 index 000000000..9b0249980 --- /dev/null +++ b/scalos/Plugins/OOP/title_test/scalos_macros.i @@ -0,0 +1,213 @@ +; Scalos_Macros.i +; 30 Aug 2001 20:47:16 + +tsta MACRO + IFNE mode020 + tst.l \1 + ELSE + cmp.l #0,'\1' + ENDC + ENDM + +tstpc: MACRO + IFNE mode020 + tst.\0 \1(pc) + ELSE + tst.\0 \1 + ENDC + ENDM + +bral: MACRO + IFNE mode020 + bra.l \1 + ELSE + jmp \1 + ENDC + ENDM + +bsrl: MACRO + IFNE mode020 + bsr.l \1 + ELSE + jsr \1 + ENDC + ENDM + +bnel: MACRO + IFNE mode020 + bne.l \1 + ELSE + beq.s skip\@ + jmp \1 +skip\@: + ENDC + ENDM + +DoMethod MACRO + movem.l d1/a0-a1/a6,-(a7) + move.l a7,a6 + clr.l -(a7) + ifge NARG-15 + move.l \f,-(a7) + endc + ifge NARG-14 + move.l \e,-(a7) + endc + ifge NARG-13 + move.l \d,-(a7) + endc + ifge NARG-12 + move.l \c,-(a7) + endc + ifge NARG-11 + move.l \b,-(a7) + endc + ifge NARG-10 + move.l \a,-(a7) + endc + ifge NARG-9 + move.l \9,-(a7) + endc + ifge NARG-8 + move.l \8,-(a7) + endc + ifge NARG-7 + move.l \7,-(a7) + endc + ifge NARG-6 + move.l \6,-(a7) + endc + ifge NARG-5 + move.l \5,-(a7) + endc + ifge NARG-4 + move.l \4,-(a7) + endc + ifge NARG-3 + move.l \3,-(a7) + endc + ifge NARG-2 + move.l \2,-(a7) + endc + ifge NARG-1 + move.l \1,-(a7) + endc + move.l a7,a1 + jsr _DoMethod + move.l a6,a7 + movem.l (a7)+,d1/a0-a1/a6 + ENDM + +cmv3 MACRO + ifge NARG-1 + move.l '\1',-(a7) + ENDC + ENDM + +;+++;30 = mu_sizeof +;+++GTMENU_USERDATA MACRO +;+++ move.l 30(\1),\2 +;+++ ENDM +;+++ +;+++;34 = mi_sizeof +;+++GTMENUITEM_USERDATA MACRO +;+++ move.l 34(\1),\2 +;+++ ENDM + +seti: MACRO + move.l \2,d0 + move.l \3,d1 + move.l \1,a0 + bsr.s setattr + ENDM + +geti: MACRO + move.l \1,a0 + move.l \2,d0 + bsr.s getattr + ENDM + +TRUE EQU 1 +FALSE EQU 0 + + +call MACRO +; xref _LVO\1 + jsr _LVO\1(a6) + ENDM + +RETURNSUPER MACRO + movem.l (a7)+,d1-a6 + move.l (cl_Super,a0),a0 + move.l (cl_Dispatcher+h_Entry,a0),-(a7) + rts + ENDM + +CALLSUPER MACRO + movem.l a0-a3,-(a7) + move.l (cl_Super,a0),a0 + move.l (cl_Dispatcher+h_Entry,a0),a3 + jsr (a3) + movem.l (a7)+,a0-a3 + ENDM + +STARTCLASS MACRO + movem.l d1-a6,-(a7) + lea \1,a3 + move.l (a1),d1 +.loop: + move.l (a3)+,d2 + beq.s .loopend + cmp.l d2,d1 + beq.s .found + addq.w #4,a3 + bra.s .loop +.found: + move.l (a3)+,a3 + jsr (a3) ; +jl+ 20010830 + movem.l (a7)+,d1-a6 + rts + +.loopend: + movem.l (a7)+,d1-a6 + move.l 24(a0),a0 + move.l 8(a0),-(a7) + rts + ENDM + +STARTMETHOD MACRO + movem.l d1-a6,-(sp) ; +jl+ 20010830 + move.w (cl_InstOffset,a0),d6 + lea (a2,d6.w),a4 ; instance data + move.l (a2),a5 ; ScaWindowTask + lea 4(a1),a3 ; skip MethodID + ENDM + +STARTMETHODNEW MACRO + movem.l d1-a6,-(sp) ; +jl+ 20010830 + ENDM + +ENDMETHOD MACRO + movem.l (a7)+,d1-a6 + rts + ENDM + +DBSTRING MACRO + movem.l a0/a1,-(a7) + move.l \1,-(a7) + move.l a7,a1 + lea debugstring,a0 + jsr dboutput + addq.w #4,a7 + movem.l (a7)+,a0/a1 + ENDM + +DBNUMBER MACRO + movem.l a0/a1,-(a7) + move.l \1,-(a7) + move.l a7,a1 + lea debugnumber,a0 + jsr dboutput + addq.w #4,a7 + movem.l (a7)+,a0/a1 + ENDM diff --git a/scalos/Plugins/OOP/title_test/title_test.s b/scalos/Plugins/OOP/title_test/title_test.s new file mode 100755 index 000000000..04e81e9df --- /dev/null +++ b/scalos/Plugins/OOP/title_test/title_test.s @@ -0,0 +1,320 @@ +; title_test.s +; 02 Jan 2004 20:22:13 + +;--------------------------------------------------------------- + machine 68020 + + incdir "SC:Assembler_Headers" + + NOLIST ; skip includes in listing + + include "exec/types.i" + include "exec/macros.i" + include "exec/resident.i" + include "exec/initializers.i" + include "scalos/iconobject.i" + include "scalos/scalos.i" + include "scalos_macros.i" + include "lvo/scalos_lib.i" + include "asmsupp.i" + +;--------------------------------------------------------------- + +Startlib: + moveq #0,d0 + rts + +; This is so that the library doesn't crash if you try to run +; it as normal executable + +;--------------------------------------------------------------- + + +RomTag: + dc.w RTC_MATCHWORD ;RT_MATCHWORD + dc.l RomTag ;RT_MATCHTAG + dc.l endep ;RT_ENDSKIP + dc.b RTF_AUTOINIT ;RT_FLAGS + dc.b 39 ;RT_VERSION + dc.b 9 ;RT_TYPE + dc.b 0 ;RT_PRI + dc.l libname ;RT_NAME + dc.l idstring ;RT_IDSTRING + dc.l init ;RT_INIT + + cnop 0,4 + +;--------------------------------------------------------------- + +; AmigaOS detects a library or device by the above ROMTag structure. +; +; From : +; +; STRUCTURE RT,0 +; UWORD RT_MATCHWORD ; word to match on (ILLEGAL) +; APTR RT_MATCHTAG ; pointer to the above (RT_MATCHWORD) +; APTR RT_ENDSKIP ; address to continue scan +; UBYTE RT_FLAGS ; various tag flags +; UBYTE RT_VERSION ; release version number +; UBYTE RT_TYPE ; type of module (NT_XXXXXX) +; BYTE RT_PRI ; initialization priority +; APTR RT_NAME ; pointer to node name +; APTR RT_IDSTRING ; pointer to identification string +; APTR RT_INIT ; pointer to init code +; LABEL RT_SIZE +; +; RTC_MATCHWORD EQU $4AFC ; The 68000 "ILLEGAL" instruction +; +; The system uses LoadSeg() to get the library code into memory and then +; does an InitResident() call on it. +; +; This scans through the code until it finds the ROMTag structure. It is +; recognized by RTC_MATCHWORD, which is an illegal 68000 opcode. +; +; If the RTF_AUTOINIT flags is set in RT_FLAGS then the address in RT_INIT +; is a pointer to a table of longs used to initialize the library. +; +; - The size of your library/device base structure including initial +; Library or Device structure. +; +; - A pointer to a longword table of standard, then library +; specific function offsets, terminated with -1L. +; (short format offsets are also acceptable) +; +; - Pointer to data table in exec/InitStruct format for +; initialization of Library or Device astructure. +; +; - Pointer to library initialization function, or NULL. +; Calling sequence: +; D0 = library base +; A0 = segList +; A6 = ExecBase +; This function must return in D0 the library/device base to be +; linked into the library/device list. If the initialization +; function fails, the device memory must be manually deallocated, +; then NULL returned in D0. + + +libname: + dc.b 'title_freepens.plugin',0 + cnop 0,4 +idstring: + dc.b '$VER: title_freepens.plugin 39.1 (05-09-97)',10 + dc.b '(c)1997 by ALiENDESiGN',0 + cnop 0,4 + +;--------------------------------------------------------------- + +init: + dc.l 38 ; Size of library base + dc.l functable ; Pointer to function table + dc.l datatable ; Pointer to data init table + dc.l InitRoutine ; Pointer to init function + +;--------------------------------------------------------------- + +; Table of offsets for library functions + +functable: + dc.l Open ; Called when a client opens the library + dc.l Close ; Called when a client close the library + dc.l Expunge ; Called when the library needs to be flushed from memory + dc.l Startlib ; Currently unused. + + + dc.l getclassinfo ; This is where you start your library functions + + dc.l -1 ; Marks the end of the table + + +;--------------------------------------------------------------- + +; This the data table used to fill various values in the +; the library base vector. +; This in a format understood by the InitStruct() function + + +datatable: + INITBYTE 8,9 ;LN_TYPE,NT_LIBRARY + INITLONG 10,libname ;LN_NAME,LibName + INITBYTE 14,3 ;LIB_FLAGS,LIBF_SUMUSED!LIBF_CHANGED + INITWORD 20,39 ;LIB_VERSION,VERSION + INITWORD 22,1 ;LIB_REVISION,REVISION + INITLONG 24,idstring ;LIB_IDSTRING,IDString + dc.l 0 + + cnop 0,4 + +;--------------------------------------------------------------- + +; Init routine - called when library is loaded into memory. +; Parameters +; D0 = library base +; A0 = segList (This needs to be stored so we can manually +; unload the library from memory) +; A6 = ExecBase + +InitRoutine: + movem.l d0-a6,-(sp) + + move.l a0,seglist + + move.l d0,a0 + move.l #'PLUG',34(a0) ;Store identifier for plugins into LibBase + + movem.l (sp)+,d0-a6 + rts +.openerror: + movem.l (sp)+,d0-a6 + moveq #0,d0 + rts + +;--------------------------------------------------------------- + +Open: ; ( libptr:a6, version:d0 ) + addq.w #1,32(a6) ; LIB_OPENCNT + bclr #3,14(a6) ; LIB_FLAGS + move.l a6,d0 + rts + +;--------------------------------------------------------------- + +Close: ; ( libptr:a6 ) + subq.w #1,32(a6) ; LIB_OPENCNT + bne.s .nooneopen + btst #3,14(a6) ; LIB_FLAGS + beq.s .nooneopen + bsr.s Expunge +.nooneopen: + moveq #0,d0 + rts + +;--------------------------------------------------------------- + +Expunge: ; ( libptr: a6 ) + tst.w 32(a6) + beq.s .nooneopen2 + bset #3,14(a6) + moveq #0,d0 + rts + +.nooneopen2: + movem.l d2/a4/a5/a6,-(sp) + move.l seglist(pc),d2 + move.l a6,a4 + move.l 4.w,a6 + move.l a4,a1 + jsr -252(a6) ;Remove + moveq #0,d0 + move.l a4,a1 + move.w 16(a4),d0 ;LIB_NEGSIZE + sub.w d0,a1 + add.w 18(a4),d0 ;LIB_POSSIZE + jsr -210(a6) ;FreeMem + + move.l d2,d0 + movem.l (sp)+,d2/a4/a5/a6 + rts + +;----------------------------- GetClass Info -------------------------------- + +;Input: none +;Ouput: ClassInfo +getclassinfo: + lea classinfo(pc),a0 + move.l a0,d0 + rts + +classinfo: + dc.l 0,0 + dc.l hookfunc + dc.l 0,0 + dc.w 0 ;Priority + dc.w 0 ;Instance Size + dc.w 39 ;Needed Scalos Version + dc.w 0 ;Reserved + dc.l superclassname ;Name of the Class + dc.l superclassname ;Name of the SuperClass + dc.l name + dc.l description + dc.l makername + +superclassname: dc.b 'Title.sca',0 +name: dc.b 'Title FreePens',0 +description: dc.b 'Adds a %wp function to the screentitle to show all free pens.',0 +makername: dc.b 'Stefan Sommerfeld',0 + even + +;-------------------------------- Class ------------------------------------- + +hookfunc: + cmp.l #SCCM_Title_Translate,(a1) + beq.s .translate +.call_super: + move.l 24(a0),a0 ;Call Superclass + move.l 8(a0),-(a7) + rts + +.translate: + cmp.w #'wp',12(a1) + bne.s .call_super + move.l a3,-(a7) + move.l 4(a1),a3 ;TextPtr + moveq #0,d0 + move.l 4(a2),a0 ;Internal Info + move.l 12(a0),a0 ;Screen + cmp.w #0,a0 + beq.s .noscreen + move.l 48(a0),a0 ;ColorMap + move.l 40(a0),a0 ;PaletteExtra + moveq #0,d0 + move.w 48(a0),d0 ;FreePens +.noscreen: + bsr.s hextoascii + move.l a3,4(a1) ;set the new offset + move.l (a7)+,a3 + moveq #1,d0 + rts + + +;-------------------------------------------- +;Hexvalue to decimal ascii +;Input: D0 = Value - 32Bit +;Output: Text to A3 +hextoascii: + movem.l d0-d1/a2,-(a7) + move.l a7,a2 + lea -14(a7),a7 + clr.b -(a2) +.loop: moveq #0,d1 + + swap d0 ;4 + move.w d0,d1 ;4 ;HiNibble => d1 + beq.s .nohinib ;8 ;HiNibble =0 => Div Only Lo! + divu #10,d1 ;144 ;HiNibble/10 + move.w d1,d0 ; ;Result =>d0 +.nohinib: + swap d0 ;4 ;Restore LowNibble + move.w d0,d1 ;4 ;Transfer for Div + divu #10,d1 ;144 ;LowNibble/10 + move.w d1,d0 ;4 ;Result => d0 + swap d1 ;4 ;Result! + + add.b #$30,d1 + move.b d1,-(a2) + tst.l d0 + bne.s .loop +.exit: move.b (a2)+,(a3)+ + tst.b (a2) + bne.s .exit + lea 14(a7),a7 + movem.l (a7)+,d0-d1/a2 + rts + + + +;---------------------------------------------------------------------------- + +seglist: dc.l 0 +endep: + diff --git a/scalos/Plugins/OOP/wb39_plugin/AppIcons.c b/scalos/Plugins/OOP/wb39_plugin/AppIcons.c new file mode 100644 index 000000000..2c7c1caf5 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/AppIcons.c @@ -0,0 +1,225 @@ +// AppIcons.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "wb39.h" +#include "wb39proto.h" + + +// aus wb39.c +extern struct Library *WorkbenchBase; +extern struct ScalosBase *ScalosBase; + +#if 0 +static SAVEDS(struct AppIcon *) INTERRUPT ASM myAddAppIcon( + REG(d0, ULONG id), REG(d1, ULONG userdata), + REG(a0, char *text), REG(a1, struct MsgPort *msgport), + REG(a2, BPTR lock), REG(a3, struct DiskObject *diskobj), + REG(a4, struct TagItem *taglist)); +static SAVEDS(BOOL) INTERRUPT ASM myRemoveAppIcon(REG(a0, struct myAppIcon *ai)); +static SAVEDS(struct myAppIcon *) INTERRUPT ASM myNewAddAppIcon( + REG(d0, ULONG ID), REG(d1, ULONG UserData), + REG(a0, Object *iObj), REG(a1, struct MsgPort *MessagePort), + REG(a2, struct TagItem *TagList)); +#endif + + +#ifdef __AROS__ +static APTR origNewAddAppIcon; +static APTR origRemoveAppIcon; +static APTR origAddAppIcon; +#else +static LIBFUNC_P5_DPROTO(struct ScaAppObjNode *, (*origNewAddAppIcon), + D0, ULONG, ID, + D1, ULONG, UserData, + A0, Object *, iObj, + A1, struct MsgPort *, MessagePort, + A2, struct TagItem *, TagList); +static LIBFUNC_P1_DPROTO(BOOL, (*origRemoveAppIcon), + A0, struct ScaAppObjNode *, ai); +static LIBFUNC_P7_DPROTO(struct AppIcon *, (*origAddAppIcon), + D0, ULONG, id, + D1, ULONG, userdata, + A0, char *, text, + A1, struct MsgPort *, msgport, + A2, BPTR, lock, + A3, struct DiskObject *, diskobj, + A4, struct TagItem *, taglist); +#endif + + +BOOL AppIconsInit(void) +{ +#if 0 +#if defined(__MORPHOS__) + STATIC_PATCHFUNC(myRemoveAppIcon); + STATIC_PATCHFUNC(myAddAppIcon); + STATIC_PATCHFUNC(myNewAddAppIcon); +#endif /* __MORPHOS__ */ + + origRemoveAppIcon = (BOOL (* ASM) ()) SetFunction(WorkbenchBase, + -66, PATCH_NEWFUNC(myRemoveAppIcon)); + origAddAppIcon = (struct AppIcon * (* ASM) ()) SetFunction(WorkbenchBase, + -60, PATCH_NEWFUNC(myAddAppIcon)); + + origNewAddAppIcon = (struct ScaAppObjNode * (* ASM) ()) SetFunction(ScalosBase->scb_LibNode, + -42, PATCH_NEWFUNC(myNewAddAppIcon)); +#endif + return TRUE; +} + + +void AppIconsCleanup(void) +{ + if (origRemoveAppIcon) + { + SetFunction(WorkbenchBase, -66 , (ULONG (* const )()) origRemoveAppIcon); + origRemoveAppIcon = NULL; + } + if (origAddAppIcon) + { + SetFunction(WorkbenchBase, -60, (ULONG (* const )()) origAddAppIcon); + origAddAppIcon = NULL; + } + if (origNewAddAppIcon) + { + SetFunction(&ScalosBase->scb_LibNode, -42, (ULONG (* const )()) origNewAddAppIcon); + origNewAddAppIcon = NULL; + } +} + +#if 0 +// AddAppIconA +static SAVEDS(struct AppIcon *) INTERRUPT ASM myAddAppIcon( + REG(d0, ULONG id), REG(d1, ULONG userdata), + REG(a0, char *text), REG(a1, struct MsgPort *msgport), + REG(a2, BPTR lock), REG(a3, struct DiskObject *diskobj), + REG(a4, struct TagItem *taglist)) +{ + struct myAppIcon *ai; + + d1(kprintf(__FUNC__ "/%ld: diskobj=%08lx\n", __LINE__, diskobj)); + if (diskobj) + { + d1(kprintf(__FUNC__ "/%ld: x=%ld y=%ld w=%ld h=%ld\n", __LINE__, \ + diskobj->do_Gadget.LeftEdge, diskobj->do_Gadget.TopEdge, \ + diskobj->do_Gadget.Width, diskobj->do_Gadget.Height)); + } + + ai = (struct myAppIcon *) origAddAppIcon(id, userdata, text, msgport, lock, diskobj, taglist); + if (ai) + { + struct Hook *RenderHook; + Object *iObj = (Object *) ai->mai_AppIconClone.an_object; + + RenderHook = (struct Hook *) GetTagData(WBAPPICONA_RenderHook, NULL, taglist); + d1(kprintf(__FUNC__ "/%ld: RenderHook=%08lx iObj=%08lx\n", __LINE__, RenderHook, iObj)); + if (RenderHook && iObj) + { + SetAttrs(iObj, + IDTA_RenderHook, RenderHook, + TAG_END); + } + + d(kprintf(__FUNC__ "/%ld:\n", __LINE__)); + } + + return (struct AppIcon *) ai; +} + + +// RemoveAppIcon +static SAVEDS(BOOL) INTERRUPT ASM myRemoveAppIcon(REG(a0, struct myAppIcon *mai)) +{ + struct ScaAppObjNode *sNode; + struct DiskObject *diskObj; + + d(kprintf(__FUNC__ "/%ld: mai=%08lx\n", __LINE__, mai)); + + if (NULL == mai) + return FALSE; + + sNode = mai->mai_OrigAppIcon; + + d(kprintf(__FUNC__ "/%ld: sNode=%08lx\n", __LINE__, sNode)); + + if (0x5343 != sNode->an_Kennug) // "SC" + return origRemoveAppIcon(sNode); + + if (0 != sNode->an_type) + return origRemoveAppIcon(sNode); + + diskObj = (struct DiskObject *) mai->mai_AppIconClone.an_userdata2; + + d(kprintf(__FUNC__ "/%ld: DiskObj=%08lx\n", __LINE__, diskObj)); + + SCA_RemoveAppObject((struct AppObject *) sNode); + + if (mai->mai_TagListClone) + FreeTagItems(mai->mai_TagListClone); + if (diskObj) + FreeDiskObject(diskObj); + + free(mai); + + return TRUE; +} + + +// SCA_NewAddAppIcon +static SAVEDS(struct myAppIcon *) INTERRUPT ASM myNewAddAppIcon( + REG(d0, ULONG ID), REG(d1, ULONG UserData), + REG(a0, Object *iObj), REG(a1, struct MsgPort *MessagePort), + REG(a2, struct TagItem *TagList)) +{ + struct ScaAppObjNode *appObj = origNewAddAppIcon(ID, UserData, iObj, MessagePort, TagList); + struct myAppIcon *mai; + + if (NULL == appObj) + return NULL; + + d(kprintf(__FUNC__ "/%ld: appObj=%08lx\n", __LINE__, appObj)); + + mai = malloc(sizeof(struct myAppIcon)); + if (NULL == mai) + { + SCA_RemoveAppObject((struct AppObject *) appObj); + } + + mai->mai_AppIconClone = *appObj; + mai->mai_OrigAppIcon = appObj; + mai->mai_TagListClone = CloneTagItems(TagList); + + d(kprintf(__FUNC__ "/%ld: myAppIcon=%08lx TagList=%08lx\n", __LINE__, mai, mai->mai_TagListClone)); + + return mai; +} + +#endif diff --git a/scalos/Plugins/OOP/wb39_plugin/AppWindow.c b/scalos/Plugins/OOP/wb39_plugin/AppWindow.c new file mode 100644 index 000000000..709b2e016 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/AppWindow.c @@ -0,0 +1,927 @@ +// AppWindow.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "wb39.h" +#include "wb39proto.h" + +//------------------------------------------------------------------------------------- + +struct ProcessData + { + struct NotifyRequest pd_NotifyReq; + BOOL pd_NotifyOk; + }; + +//------------------------------------------------------------------------------------- + +static void GetDropZoneDropBox(struct myAppWindowDropZone *dz); +static struct Layer *WhichMouseLayer(WORD x, WORD y); +static BOOL PointInDropZone(const struct myAppWindowDropZone *dzz, WORD x, WORD y); +static void SignalDropzoneMouseEnterLeave(APTR draghandle, + const struct myAppWindowDropZone *dzz, ULONG EnterLeave); +static SAVEDS(void) myProcess(void); +static BOOL myProcessInit(struct ProcessData *pd); +static void myProcessCleanup(struct ProcessData *pd); +static void ServiceMyPort(void); + +//------------------------------------------------------------------------------------- + +static struct Task *HandshakeTask; +static ULONG HandshakeSignal = -1; +static struct MsgPort *myPort = NULL; +static BOOL myProcessRunning = FALSE; +static struct Process *myProc = NULL; + +static const ULONG Maw_ID = MAKE_ID('M','A','W','X'); + +//------------------------------------------------------------------------------------- + +// aus wb39.c +extern struct List AppWindowList; // list of all AppWindows +extern struct SignalSemaphore AppWindowSema; + + +#ifdef __AROS__ +extern APTR origAddAppWindowA; +extern APTR origRemoveAppWindow; +extern APTR origSCA_DrawDrag; +#else +extern LIBFUNC_P6_DPROTO(struct ScaAppObjNode *, (*origAddAppWindowA), + D0, ULONG, id, + D1, ULONG, userdata, + A0, struct Window *, window, + A1, struct MsgPort *, msgport, + A2, struct TagItem *, taglist, + A6, struct Library *, WorkbenchBase); +extern LIBFUNC_P2_DPROTO(BOOL, (*origRemoveAppWindow), + A0, struct ScaAppObjNode *, appWindow, + A6, struct Library *, WorkbenchBase); +extern LIBFUNC_P5_DPROTO(void, (*origSCA_DrawDrag), + A0, struct DragHandle *, draghandle, + D0, LONG, X, + D1, LONG, Y, + D2, LONG, Flags, + A6, struct Library *, ScalosBase); +#endif + +//------------------------------------------------------------------------------------- + +// AddAppWindowDropZoneA +LIBFUNC_P5(struct myAppWindowDropZone *, myAddAppWindowDropZoneA, + A0, struct myAppWindow *, maw, + D0, ULONG, id, + D1, ULONG, userdata, + A1, struct TagItem *, tags, + A6, struct Library *, WorkbenchBase) +{ + struct myAppWindowDropZone *dz; + struct TagItem *ti; + + (void)WorkbenchBase; + + d1(kprintf(__FUNC__ "/%ld: AppWindow=%08lx id=%08lx userdata=%08lx tags=%08lx\n", \ + __LINE__, maw, id, userdata, tags)); + + if (NULL == maw) + return NULL; + + if (Maw_ID != maw->maw_Magic) + return NULL; + + dz = malloc(sizeof(struct myAppWindowDropZone)); + if (NULL == dz) + return NULL; + + dz->awz_AppWindow = maw; + dz->awz_ID = id; + dz->awz_UserData = userdata; + dz->awz_Hook = (struct Hook *) GetTagData(WBDZA_Hook, (ULONG)NULL, tags); + + if (ti = FindTagItem(WBDZA_Box, tags)) + { + dz->awz_MeasureBox = *((struct IBox *) (ti->ti_Data)); + + d1(kprintf(__FUNC__ "/%ld: MeasureBox left=%ld top=%ld width=%ld height=%ld\n", \ + __LINE__, dz->awz_MeasureBox.Left, dz->awz_MeasureBox.Top, dz->awz_MeasureBox.Width, dz->awz_MeasureBox.Height)); + + dz->awz_RelRight = FALSE; + dz->awz_RelBottom = FALSE; + dz->awz_RelWidth = FALSE; + dz->awz_RelHeight = FALSE; + } + else + { + if (ti = FindTagItem(WBDZA_RelRight, tags)) + { + dz->awz_MeasureBox.Left = ti->ti_Data; + dz->awz_RelRight = TRUE; + } + else + { + if (ti = FindTagItem(WBDZA_Left, tags)) + { + dz->awz_MeasureBox.Left = ti->ti_Data; + } + else + { + // no LEFT + free(dz); + return NULL; + } + dz->awz_RelRight = FALSE; + } + if (ti = FindTagItem(WBDZA_RelBottom, tags)) + { + dz->awz_MeasureBox.Top = ti->ti_Data; + dz->awz_RelBottom = TRUE; + } + else + { + if (ti = FindTagItem(WBDZA_Top, tags)) + { + dz->awz_MeasureBox.Top = ti->ti_Data; + } + else + { + // no TOP + free(dz); + return NULL; + } + dz->awz_RelBottom = FALSE; + } + if (ti = FindTagItem(WBDZA_RelWidth, tags)) + { + dz->awz_MeasureBox.Width = ti->ti_Data; + dz->awz_RelWidth = TRUE; + } + else + { + if (ti = FindTagItem(WBDZA_Width, tags)) + { + dz->awz_MeasureBox.Width = ti->ti_Data; + } + else + { + // no WIDTH + free(dz); + return NULL; + } + dz->awz_RelWidth = FALSE; + } + if (ti = FindTagItem(WBDZA_RelHeight, tags)) + { + dz->awz_MeasureBox.Height = ti->ti_Data; + dz->awz_RelHeight = TRUE; + } + else + { + if (ti = FindTagItem(WBDZA_Height, tags)) + { + dz->awz_MeasureBox.Height = ti->ti_Data; + } + else + { + // no HEIGHT + free(dz); + return NULL; + } + dz->awz_RelHeight = FALSE; + } + } + + dz->awz_DropBox = dz->awz_MeasureBox; + + GetDropZoneDropBox(dz); + + d1(kprintf(__FUNC__ "/%ld: dz=%08lx left=%ld top=%ld width=%ld height=%ld\n", \ + __LINE__, dz, dz->awz_DropBox.Left, dz->awz_DropBox.Top, \ + dz->awz_DropBox.Width, dz->awz_DropBox.Height)); + + ObtainSemaphore(&maw->maw_Sema); + + AddTail(&maw->maw_DropZoneList, &dz->awz_Node); + + ReleaseSemaphore(&maw->maw_Sema); + + return dz; +} +LIBFUNC_END + + +// RemoveAppWindowDropZone +LIBFUNC_P3(BOOL, myRemoveAppWindowDropZone, + A0, struct myAppWindow *, maw, + A1, struct myAppWindowDropZone *, dz, + A6, struct Library *, WorkbenchBase) +{ + struct myAppWindowDropZone *dzz; + BOOL Found = FALSE; + + (void)WorkbenchBase; + + d1(kprintf(__FUNC__ "/%ld: AppWindow=%08lx dropZone=%08lx\n", \ + __LINE__, maw, dz)); + + if (NULL== maw) + return TRUE; + if (Maw_ID != maw->maw_Magic) + return FALSE; + if (NULL == dz) + return TRUE; + + ObtainSemaphore(&maw->maw_Sema); + + for (dzz = (struct myAppWindowDropZone *) maw->maw_DropZoneList.lh_Head; + !Found && dzz != (struct myAppWindowDropZone *) &maw->maw_DropZoneList.lh_Tail; + dzz = (struct myAppWindowDropZone *) dzz->awz_Node.ln_Succ) + { + d1(kprintf(__FUNC__ "/%ld: dz=%08lx dzz=%08lx\n", __LINE__, dz, dzz)); + if (dz == dzz) + Found = TRUE; + } + + if (Found) + { + Remove(&dz->awz_Node); // remove dropzone from list + free(dz); + } + + ReleaseSemaphore(&maw->maw_Sema); + + d1(kprintf(__FUNC__ "/%ld: Found=%ld\n", __LINE__, Found)); + + return Found; +} +LIBFUNC_END + + +// AddAppWindowA +LIBFUNC_P6(struct myAppWindow *, myAddAppWindowA, + D0, ULONG, id, + D1, ULONG, userdata, + A0, struct Window *, window, + A1, struct MsgPort *, msgport, + A2, struct TagItem *, taglist, + A6, struct Library *, WorkbenchBase) +{ + struct ScaAppObjNode *aw; + struct myAppWindow *maw; + + d1(KPrintF(__FUNC__ "/%ld: id=%08lx userdata=%08lx\n", __LINE__, id, userdata)); + + maw = calloc(sizeof(struct myAppWindow), 1); + d1(KPrintF(__FUNC__ "/%ld: maw=%08lx\n", __LINE__, maw)); + if (NULL == maw) + { + return NULL; + } + + maw->maw_Magic = Maw_ID; + maw->maw_AppWindow = NULL; + maw->maw_ActiveDropZone = NULL; + maw->maw_origUserData = userdata; + maw->maw_origMsgPort = msgport; + + NewList(&maw->maw_DropZoneList); + InitSemaphore(&maw->maw_Sema); + + d1(KPrintF(__FUNC__ "/%ld: origAddAppWindowA=%08lx\n", __LINE__, origAddAppWindowA)); + + // all AppWindow Messages will be relayed to myPort +#ifdef __AROS__ + aw = (struct ScaAppObjNode *)AROS_CALL5(struct AppWindow *, origAddAppWindowA, + AROS_LDA(ULONG, id, D0), + AROS_LDA(ULONG, (ULONG)maw, D1), + AROS_LDA(struct Window *, window, A0), + AROS_LDA(struct MsgPort *, msgport, A1), + AROS_LDA(struct TagItem *, taglist, A2), + struct Library *, WorkbenchBase); +#else + aw = (struct ScaAppObjNode *) CALLLIBFUNC_P6(origAddAppWindowA, + D0, id, + D1, (ULONG) maw, + A0, window, + A1, myPort, + A2, taglist, + A6, WorkbenchBase); +#endif + + d1(KPrintF(__FUNC__ "/%ld: aw=%08lx\n", __LINE__, aw)); + if (NULL == aw) + { + return NULL; + } + + maw->maw_AppWindow = aw; + + ObtainSemaphore(&AppWindowSema); + AddTail(&AppWindowList, &maw->maw_Node); + ReleaseSemaphore(&AppWindowSema); + + d1(KPrintF(__FUNC__ "/%ld: maw=%08lx\n", __LINE__, maw)); + + return maw; +} +LIBFUNC_END + + +LIBFUNC_P2(BOOL, myRemoveAppWindow, + A0, struct myAppWindow *, maw, + A6, struct Library *, WorkbenchBase) +{ + BOOL Result; + struct myAppWindowDropZone *dz; + + d1(KPrintF(__FUNC__ "/%ld: maw=%08lx\n", __LINE__, maw)); + + if (NULL == maw || 0 == TypeOfMem(maw)) + return TRUE; + if (Maw_ID != maw->maw_Magic) + { +#ifdef __AROS__ + return AROS_CALL1(BOOL, origRemoveAppWindow, + AROS_LDA(struct AppWindow *, maw, A0), + struct Library *, WorkbenchBase); +#else + return CALLLIBFUNC_P2(origRemoveAppWindow, + A0, (struct ScaAppObjNode *) maw, + A6, WorkbenchBase); +#endif + } + + d1(KPrintF(__FUNC__ "/%ld: maw=%08lx\n", __LINE__, maw)); + + ObtainSemaphore(&AppWindowSema); + Remove(&maw->maw_Node); + ReleaseSemaphore(&AppWindowSema); + + ObtainSemaphore(&maw->maw_Sema); + +#ifdef __AROS__ + Result = AROS_CALL1(BOOL, origRemoveAppWindow, + AROS_LDA(struct AppWindow *, maw->maw_AppWindow, A0), + struct Library *, WorkbenchBase); +#else + Result = CALLLIBFUNC_P2(origRemoveAppWindow, + A0, maw->maw_AppWindow, + A6, WorkbenchBase); +#endif + + d1(KPrintF(__FUNC__ "/%ld: Result=%08lx\n", __LINE__, Result)); + + // Cleanup all added dropzones + while (dz = (struct myAppWindowDropZone *) RemHead(&maw->maw_DropZoneList)) + { + free(dz); + } + + ReleaseSemaphore(&maw->maw_Sema); + + free(maw); + + return Result; +} +LIBFUNC_END + + +LIBFUNC_P5(void, mySCA_DrawDrag, + A0, APTR, draghandle, + D0, LONG, X, + D1, LONG, Y, + D2, LONG, Flags, + A6, struct Library *, ScalosBase) +{ + struct Layer *mLayer; + + d1(kprintf(__FUNC__ "/%ld: draghandle=%08lx x=%ld y=%ld\n", __LINE__, draghandle, X, Y)); + + mLayer = WhichMouseLayer(X, Y); + if (mLayer && mLayer->Window) + { + struct myAppWindow *maw, *mmaw = NULL; + + ObtainSemaphore(&AppWindowSema); + + for (maw = (struct myAppWindow *) AppWindowList.lh_Head; + maw != (struct myAppWindow *) &AppWindowList.lh_Tail; + maw = (struct myAppWindow *) maw->maw_Node.ln_Succ) + { + if ((struct Window *) maw->maw_AppWindow->an_object == mLayer->Window) + { + mmaw = maw; + break; + } + } + + ReleaseSemaphore(&AppWindowSema); + + d1(kprintf(__FUNC__ "/%ld: AppWindow=%08lx\n", __LINE__, mmaw)); + + // Mouse is inside AppWindow, now check DropZones + if (mmaw && !IsListEmpty(&mmaw->maw_DropZoneList)) + { + struct myAppWindowDropZone *dzz; + WORD wx, wy; + struct Window *win = (struct Window *) mmaw->maw_AppWindow->an_object; + BOOL Found = FALSE; + + wx = X - win->LeftEdge; + wy = Y - win->TopEdge; + + for (dzz = (struct myAppWindowDropZone *) maw->maw_DropZoneList.lh_Head; + dzz != (struct myAppWindowDropZone *) &maw->maw_DropZoneList.lh_Tail; + dzz = (struct myAppWindowDropZone *) dzz->awz_Node.ln_Succ) + { + d1(kprintf(__FUNC__ "/%ld: DropZone=%08lx\n", __LINE__, dzz)); + + GetDropZoneDropBox(dzz); + + if (PointInDropZone(dzz, wx, wy)) + { + d1(kprintf(__FUNC__ "/%ld: INSIDE \n", __LINE__)); + if (mmaw->maw_ActiveDropZone != dzz) + { +#ifdef __AROS__ + AROS_CALL4(VOID, origSCA_DrawDrag, + AROS_LDA(struct DragHandle *, draghandle, A0), + AROS_LDA(LONG, 400 + win->WScreen->Width, D0), + AROS_LDA(LONG, 400 + win->WScreen->Height, D1), + AROS_LDA(ULONG, (Flags | SCAF_Drag_Hide), D2), + struct Library *, ScalosBase); // Hide Bobs +#else + CALLLIBFUNC_P5(origSCA_DrawDrag, + A0, draghandle, + D0, 400 + win->WScreen->Width, + D1, 400 + win->WScreen->Height, + D2, (Flags | SCAF_Drag_Hide), + A6, ScalosBase); // Hide Bobs +#endif + + if (mmaw->maw_ActiveDropZone) + { + SignalDropzoneMouseEnterLeave(draghandle, mmaw->maw_ActiveDropZone, ADZMACTION_Leave); + } + + mmaw->maw_ActiveDropZone = dzz; + SignalDropzoneMouseEnterLeave(draghandle, dzz, ADZMACTION_Enter); + } + + Found = TRUE; + break; + } + } + + if (!Found && mmaw->maw_ActiveDropZone) + { + d1(kprintf(__FUNC__ "/%ld: OUTSIDE \n", __LINE__)); + +#ifdef __AROS__ + AROS_CALL4(VOID, origSCA_DrawDrag, + AROS_LDA(struct DragHandle *, draghandle, A0), + AROS_LDA(LONG, 400 + win->WScreen->Width, D0), + AROS_LDA(LONG, 400 + win->WScreen->Height, D1), + AROS_LDA(ULONG, (Flags | SCAF_Drag_Hide), D2), + struct Library *, ScalosBase); +#else + CALLLIBFUNC_P5(origSCA_DrawDrag, + A0, draghandle, + D0, 400 + win->WScreen->Width, + D1, 400 + win->WScreen->Height, + D2, (Flags | SCAF_Drag_Hide), + A6, ScalosBase); // Hide Bobs +#endif + + SignalDropzoneMouseEnterLeave(draghandle, mmaw->maw_ActiveDropZone, ADZMACTION_Leave); + mmaw->maw_ActiveDropZone = NULL; + } + } + } + +#ifdef __AROS__ + AROS_CALL4(VOID, origSCA_DrawDrag, + AROS_LCA(struct DragHandle *, draghandle, A0), + AROS_LCA(LONG, X, D0), + AROS_LCA(LONG, Y, D1), + AROS_LCA(ULONG, Flags, D2), + struct Library *, ScalosBase); +#else + CALLLIBFUNC_P5(origSCA_DrawDrag, + A0, draghandle, + D0, X, + D1, Y, + D2, Flags, + A6, ScalosBase); +#endif +} +LIBFUNC_END + + +// Calculate awz_DropBox from awz_MeasureBox, taking into account window-relative coordinates +static void GetDropZoneDropBox(struct myAppWindowDropZone *dz) +{ + struct Window *win = (struct Window *) dz->awz_AppWindow->maw_AppWindow->an_object; + + d1(kprintf(__FUNC__ "/%ld: AppWindow=%08lx win=%08lx\n", \ + __LINE__, dz->awz_AppWindow->maw_AppWindow, win)); + + d1(kprintf(__FUNC__ "/%ld: relright=%ld relbottom=%ld relwidth=%ld relheight=%ld\n", \ + __LINE__, dz->awz_RelRight, dz->awz_RelBottom, dz->awz_RelWidth, dz->awz_RelHeight)); + + if (dz->awz_RelRight) + dz->awz_DropBox.Left = win->Width + dz->awz_MeasureBox.Left; + if (dz->awz_RelBottom) + dz->awz_DropBox.Top = win->Height + dz->awz_MeasureBox.Top; + if (dz->awz_RelWidth) + dz->awz_DropBox.Width = win->Width + dz->awz_MeasureBox.Width; + if (dz->awz_RelHeight) + dz->awz_DropBox.Height = win->Height + dz->awz_MeasureBox.Height; +} + + +static struct Layer *WhichMouseLayer(WORD x, WORD y) +{ + struct Layer *layer = NULL; + struct Screen *scr; + extern struct IntuitionBase *IntuitionBase; + + Forbid(); + + for (scr = IntuitionBase->FirstScreen; scr; scr = scr->NextScreen) + { + d1( kprintf("screen=%lx Offsetx=%ld ", scr, scr->ViewPort.DyOffset) ); + d1( kprintf("x=%ld y=%ld\n", scr->MouseX, scr->MouseY) ); + + if (scr->MouseY >= 0 && scr->MouseY < scr->Height) + break; + } + + Permit(); + + if (scr) + { + layer = WhichLayer(&scr->LayerInfo, x, y); + } + + d1(kprintf("Screen=%lx x=%3ld y=%3ld\n", scr, IntuitionBase->MouseX, + IntuitionBase->MouseY) ); + + return(layer); +} + + +static BOOL PointInDropZone(const struct myAppWindowDropZone *dzz, WORD x, WORD y) +{ + if (x < dzz->awz_DropBox.Left || y < dzz->awz_DropBox.Top) + return FALSE; + if (x >= dzz->awz_DropBox.Left + dzz->awz_DropBox.Width) + return FALSE; + if (y >= dzz->awz_DropBox.Top + dzz->awz_DropBox.Height) + return FALSE; + + return TRUE; +} + + +static void SignalDropzoneMouseEnterLeave(APTR draghandle, + const struct myAppWindowDropZone *dzz, ULONG EnterLeave) +{ + d1(kprintf(__FUNC__ "/%ld: DropZone=%08lx Hook=%08lx Action=%ld x=%ld y=%ld w=%ld h=%ld\n", \ + __LINE__, dzz, dzz->awz_Hook, EnterLeave, dzz->awz_DropBox.Left, \ + dzz->awz_DropBox.Top, dzz->awz_DropBox.Width, dzz->awz_DropBox.Height)); + + if (dzz->awz_Hook) + { + struct AppWindowDropZoneMsg msg; + ULONG WasLocked; + + msg.adzm_RastPort = ((struct Window *) dzz->awz_AppWindow->maw_AppWindow->an_object)->RPort; + msg.adzm_Action = EnterLeave; + msg.adzm_DropZoneBox = dzz->awz_DropBox; + msg.adzm_ID = dzz->awz_ID; + msg.adzm_UserData = dzz->awz_UserData; + + WasLocked = SCA_UnlockDrag(draghandle); + CallHookPkt(dzz->awz_Hook, NULL, &msg); + if (WasLocked) + SCA_LockDrag(draghandle); + } +} + +/* ====================================================== */ + +BOOL DetachMyProcess(void) +{ + STATIC_PATCHFUNC(myProcess); + HandshakeTask = FindTask(NULL); + HandshakeSignal = AllocSignal(-1); + if (-1 == HandshakeSignal) + { +// alarm("AllocSignal() failed"); + return FALSE; + } + + myProc = CreateNewProcTags(NP_Name, (ULONG) "wb39_plugin", + NP_Priority, 0, + NP_Entry, (ULONG) PATCH_NEWFUNC(myProcess), + NP_StackSize, 16384, + TAG_END); + if (myProc == NULL) + { +// alarm("TNC_INit: CreateProc() failed"); + return FALSE; + } + + Wait(1 << HandshakeSignal); /* Warten auf Ergebnis */ + + FreeSignal(HandshakeSignal); + HandshakeSignal = -1; + + if (!myProcessRunning) + myProc = NULL; + + return myProcessRunning; +} + + +void ShutdownMyProcess(void) +{ + if (NULL == myProc) + return; + + HandshakeTask = FindTask(NULL); + HandshakeSignal = AllocSignal(-1); + if (-1 == HandshakeSignal) + { +// alarm("AllocSignal() failed"); + return; + } + + myProcessRunning = FALSE; + + Signal(&myProc->pr_Task, 1 << myPort->mp_SigBit); // Signal myProc + + Wait(1 << HandshakeSignal); /* Warten auf Ergebnis */ + + FreeSignal(HandshakeSignal); + HandshakeSignal = -1; + + myProc = NULL; +} + + +/* ====================================================== */ + +static SAVEDS(void) myProcess(void) +{ + struct ProcessData pd = + { + { NULL }, + FALSE, + }; + + d1(kprintf("%s/%s/%ld Start TNCProcess\n", __FILE__, __FUNC__, __LINE__);) + + if (myProcessInit(&pd)) + { + ULONG myPortMask = 1UL << myPort->mp_SigBit; + ULONG NotifyMask = 1UL << pd.pd_NotifyReq.nr_stuff.nr_Signal.nr_SignalNum; + ULONG Event; + + d1(kprintf("%s/%s/%ld: myPortMask=%08lx NotifyMask=%08lx\n", __FILE__, __FUNC__, __LINE__, + myPortMask, NotifyMask)); + + myProcessRunning = TRUE; + + if (HandshakeSignal != -1) + Signal(HandshakeTask, 1 << HandshakeSignal); + + while (myProcessRunning) + { + Event = Wait(myPortMask | NotifyMask); + + d1(kprintf("%s/%s/%ld: Event=%08lx\n", __FILE__, __FUNC__, __LINE__, + Event)); + + if (Event & myPortMask) + { + ServiceMyPort(); + } + if (Event & NotifyMask) + { + ParseWBPrefs("ENV:sys/Workbench.prefs"); + } + } + } + + myProcessRunning = FALSE; + + myProcessCleanup(&pd); + + d1(kprintf("%s/%s/%ld End TNCProcess\n", __FILE__, __FUNC__, __LINE__);) + + Forbid(); + if (HandshakeSignal != -1) + Signal(HandshakeTask, 1 << HandshakeSignal); +} + + +static BOOL myProcessInit(struct ProcessData *pd) +{ + myPort = CreateMsgPort(); + if (!myPort) + { +// alarm(__FUNC__ ": CreateMsgPort() failed"); + return FALSE; + } + + memset(&pd->pd_NotifyReq, 0, sizeof(pd->pd_NotifyReq)); + + pd->pd_NotifyReq.nr_Name = "ENV:sys/Workbench.prefs"; + pd->pd_NotifyReq.nr_UserData = 0; + pd->pd_NotifyReq.nr_Flags = NRF_SEND_SIGNAL; + pd->pd_NotifyReq.nr_stuff.nr_Signal.nr_Task = FindTask(NULL); + pd->pd_NotifyReq.nr_stuff.nr_Signal.nr_SignalNum = AllocSignal(-1); + + pd->pd_NotifyOk = StartNotify(&pd->pd_NotifyReq); + + d1(kprintf(__FUNC__ "/%ld: NotifyOk=%ld\n", __LINE__, pd->pd_NotifyOk)); + + return TRUE; +} + + +static void myProcessCleanup(struct ProcessData *pd) +{ + if (myPort) + { + struct Message *Msg; + + while (Msg = GetMsg(myPort)) + { + switch (Msg->mn_Node.ln_Type) + { + case NT_MESSAGE: + ReplyMsg(Msg); + break; + + case NT_REPLYMSG: + free(Msg); + break; + } + } + + DeleteMsgPort(myPort); + myPort = NULL; + } + + if (pd->pd_NotifyOk) + { + EndNotify(&pd->pd_NotifyReq); + pd->pd_NotifyOk = FALSE; + } +} + + +static void ServiceMyPort(void) +{ + struct AppMessage *Msg; + + while (Msg = (struct AppMessage *) GetMsg(myPort)) + { + struct AppMessage *myMsg; + struct myAppWindow *maw; + + switch (Msg->am_Message.mn_Node.ln_Type) + { + case NT_MESSAGE: + switch (Msg->am_Type) + { + case AMTYPE_APPWINDOW: + maw = (struct myAppWindow *) Msg->am_UserData; + + d1(kprintf(__FUNC__ "/%ld: Msg=%08lx maw=%08lx ID=%08lx\n", __LINE__, Msg, maw, Msg->am_ID)); + + myMsg = malloc(sizeof(struct AppMessage)); + if (myMsg) + { + *myMsg = *Msg; + myMsg->am_Message.mn_ReplyPort = myPort; + myMsg->am_UserData = maw->maw_origUserData; + myMsg->am_Reserved[7] = (ULONG) Msg; // Remember original Msg for Replying + + if (maw->maw_ActiveDropZone) + { + d1(kprintf(__FUNC__ "/%ld: DropZone dzz=%08lx\n", __LINE__, maw->maw_ActiveDropZone)); + + if (PointInDropZone(maw->maw_ActiveDropZone, + Msg->am_MouseX, Msg->am_MouseY)) + { + d1(kprintf(__FUNC__ "/%ld: DropZone dzz=%08lx\n", __LINE__, maw->maw_ActiveDropZone)); + + myMsg->am_Type = AMTYPE_APPWINDOWZONE; + myMsg->am_UserData = maw->maw_ActiveDropZone->awz_UserData; + myMsg->am_ID = maw->maw_ActiveDropZone->awz_ID; + } + else + { + maw->maw_ActiveDropZone = NULL; + } + } + + PutMsg(maw->maw_origMsgPort, (struct Message *) myMsg); + } + break; + default: + ReplyMsg((struct Message *) Msg); + break; + } + break; + + case NT_REPLYMSG: + if (MAKE_ID('A','P','P','M') == Msg->am_Reserved[0] && Msg->am_Reserved[7]) + { + // Reply original Msg + ReplyMsg((struct Message *) Msg->am_Reserved[7]); + } + free(Msg); + break; + } + } +} + +#ifdef __amigaos4__ +LIBFUNC_P4VA(struct AppWindowDropZone *, myAddAppWindowDropZone, + A0, struct AppWindow *, maw, + D0, ULONG, id, + D1, ULONG, userdata, + A6, struct Library *, WorkbenchBase) +{ + struct AppWindowDropZone *ret; + struct WorkbenchIFace *IWorkbench = (struct WorkbenchIFace *)self; + va_list args; + va_startlinear(args, userdata); + + (void)WorkbenchBase; + + ret = AddAppWindowDropZoneA(maw, id, userdata, va_getlinearva(args, const struct TagItem *)); + + va_end(args); + + return(ret); +} +LIBFUNC_END + +LIBFUNC_P5VA(struct AppWindow *, myAddAppWindow, + D0, ULONG, id, + D1, ULONG, userdata, + A0, struct Window *, window, + A1, struct MsgPort *, msgport, + A6, struct Library *, WorkbenchBase) +{ + struct AppWindow *ret; + struct WorkbenchIFace *IWorkbench = (struct WorkbenchIFace *)self; + va_list args; + va_startlinear(args, msgport); + + (void)WorkbenchBase; + + ret = AddAppWindowA(id, userdata, window, msgport, va_getlinearva(args, const struct TagItem *)); + + va_end(args); + + return(ret); +} +LIBFUNC_END +#endif + + diff --git a/scalos/Plugins/OOP/wb39_plugin/DefIcons.c b/scalos/Plugins/OOP/wb39_plugin/DefIcons.c new file mode 100644 index 000000000..cbd55773d --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/DefIcons.c @@ -0,0 +1,356 @@ +// DefIcons.c +// 13 Nov 2004 19:37:42 + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + + +#include + +/* How it works: + gets the "Global Identify Hook" from icon.library and calls this hook itself. + If DefIcons is being started automatically, like it is default in OS3.9, + its identify hook will be got from icon.library. +*/ + +//---------------------------------------------------------------------------- +// Revision history : +// +// 20010405 jl 44.5 +// Forgot to set DTA_Name for generated default icons. Fixed. +//---------------------------------------------------------------------------- + +struct SM_GetDefIcon + { + ULONG MethodID; + STRPTR filename; + ULONG filetype; // from FileInfoBlock fib_DirEntryType + ULONG protectionbits; + }; + + +#define d(x) ; +#define d1(x) ; +#define d2 (x) x; + + +// aus debug.lib +extern int kprintf(const char *fmt, ...); + +static BOOL Init(void); +SAVEDS(void) INTERRUPT ASM DefIconsCleanup(void); +static BOOL OpenLibraries(void); +static void CloseLibraries(void); +static Object *GetDefIcon(Class *cl, Object *obj, struct SM_GetDefIcon *msg); + + +struct ExecBase *SysBase; +struct DosLibrary *DOSBase; +struct Library *IconobjectBase; +struct Library *UtilityBase; +struct Library *IconBase; +struct Library *ScalosBase; +struct IntuitionBase *IntuitionBase; + + +static BOOL fInit; + + +SAVEDS(ULONG) INTERRUPT ASM myHookFunc(REG(a0, Class *cl), + REG(a2, Object *obj), + REG(a1, Msg msg)) +{ + ULONG Result; + + d(kprintf(__FUNC__ "/%ld: MethodID=%08lx\n", __LINE__, msg->MethodID)); + + switch (msg->MethodID) + { + case SCCM_IconWin_GetDefIcon: + Result = (ULONG) GetDefIcon(cl, obj, (struct SM_GetDefIcon *) msg); + + d(kprintf(__FUNC__ "/%ld: RootList=%08lx InternInfos=%08lx\n", __LINE__, \ + rList, rList->rl_internInfos)); + + break; + + default: + d(kprintf(__FUNC__ "/%ld: MethodID=%08lx\n", __LINE__, msg->MethodID)); + Result = DoSuperMethodA(cl, obj, msg); + break; + } + + return Result; +} + + +SAVEDS(ULONG) INTERRUPT ASM DefIconsInit(void) +{ + d(kprintf(__FUNC__ "/%ld: \n", __LINE__)); + + if (!fInit) + { + BOOL Success = fInit = Init(); + + if (!Success) + DefIconsCleanup(); + + return Success; + } + + return TRUE; +} + + +static BOOL Init(void) +{ + if (!OpenLibraries()) + return FALSE; + + d(kprintf(__FUNC__ "/%ld: IconobjectBase=%08lx UtilityBase=%08lx\n", \ + __LINE__, IconobjectBase, UtilityBase)); + + return TRUE; +} + + +SAVEDS(void) INTERRUPT ASM DefIconsCleanup(void) +{ + CloseLibraries(); + + fInit = FALSE; +} + + +static BOOL OpenLibraries(void) +{ +#ifndef __AROS__ + SysBase = *( (struct ExecBase **) 4l); +#endif + + DOSBase = (struct DosLibrary *) OpenLibrary(DOSNAME, 39); + if (NULL == DOSBase) + return FALSE; + + IconobjectBase = OpenLibrary("iconobject.library", 39); + if (NULL == IconobjectBase) + return FALSE; + + UtilityBase = OpenLibrary("utility.library", 40); + if (NULL == UtilityBase) + return FALSE; + + IconBase = OpenLibrary("icon.library", 44); + if (NULL == IconBase) + return FALSE; + + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + if (NULL == IntuitionBase) + return FALSE; + + ScalosBase = OpenLibrary(SCALOSNAME, 41); + if (NULL == ScalosBase) + return FALSE; + + return TRUE; +} + + +static void CloseLibraries(void) +{ + if (ScalosBase) + { + CloseLibrary(ScalosBase); + ScalosBase = NULL; + } + if (IntuitionBase) + { + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } + if (IconBase) + { + CloseLibrary(IconBase); + IconBase = NULL; + } + if (DOSBase) + { + CloseLibrary((struct Library *) DOSBase); + DOSBase = NULL; + } + if (IconobjectBase) + { + CloseLibrary(IconobjectBase); + IconobjectBase = NULL; + } + if (UtilityBase) + { + CloseLibrary(UtilityBase); + UtilityBase = NULL; + } +} + + +void _XCEXIT(long x) +{ +} + + +static Object *GetDefIcon(Class *cl, Object *obj, struct SM_GetDefIcon *msg) +{ + Object *IconObj = NULL; + struct DiskObject *diskObj = NULL; + struct Hook *pHook = NULL; + + d1(kprintf(__FUNC__ "/%ld: filename=<%s> type=%08lx protection=%08lx\n", __LINE__, \ + msg->filename, msg->filetype, msg->protectionbits)); + + // IconControlA() + IconControl(NULL, + ICONCTRLA_GetGlobalIdentifyHook, &pHook, + TAG_END); + + d1(kprintf(__FUNC__ "/%ld: pHook=%08lx\n", __LINE__, pHook)); + if (pHook) + { + struct TagItem EmptyTagList = { TAG_END, 0 }; + BPTR fLock; + struct FileInfoBlock *fib; + + fLock = Lock(msg->filename, ACCESS_READ); + d1(kprintf(__FUNC__ "/%ld: fLock=%08lx\n", __LINE__, fLock)); + if (fLock) + { + BPTR fh; + BPTR parentLock = ParentDir(fLock); + + fh = Open(msg->filename, MODE_OLDFILE); + + fib = AllocDosObject(DOS_FIB, TAG_END); + d1(kprintf(__FUNC__ "/%ld: fib=%08lx fh=%08lx\n", __LINE__, fib, fh)); + if (fib) + { + struct IconIdentifyMsg iim; + + Examine(fLock, fib); + + iim.iim_SysBase = (struct Library *) SysBase; + iim.iim_DOSBase = (struct Library *) DOSBase; + iim.iim_UtilityBase = UtilityBase; + iim.iim_IconBase = IconBase; + + iim.iim_FileLock = fLock; + iim.iim_ParentLock = parentLock; + iim.iim_FIB = fib; + iim.iim_FileHandle = fh; + + iim.iim_Tags = &EmptyTagList; + + diskObj = (struct DiskObject *) CallHookPkt(pHook, NULL, &iim); + + d1(kprintf(__FUNC__ "/%ld: diskobj=%08lx\n", __LINE__, diskObj)); + + FreeDosObject(DOS_FIB, fib); + } + + if (parentLock) + UnLock(parentLock); + if (fh) + Close(fh); + + UnLock(fLock); + } + } + + d1(kprintf(__FUNC__ "/%ld: diskobj=%08lx FileType=%ld\n", __LINE__, diskObj, msg->filetype)); + + if (NULL == diskObj && IconBase->lib_Version >= 44) + { + ULONG iconType; + + switch (msg->filetype) + { + case ST_ROOT: + iconType = WBDISK; + break; + + case ST_USERDIR: + case ST_LINKDIR: + iconType = WBDRAWER; + break; + + default: + iconType = WBPROJECT; + break; + } + + // GetIconTagList + diskObj = GetIconTags(msg->filename, + ICONGETA_GetDefaultType, iconType, + ICONGETA_FailIfUnavailable, FALSE, + TAG_END); + d1(kprintf(__FUNC__ "/%ld: diskobj=%08lx\n", __LINE__, diskObj)); + } + + if (NULL == diskObj) + { + diskObj = GetDiskObjectNew(msg->filename); + d1(kprintf(__FUNC__ "/%ld: diskobj=%08lx\n", __LINE__, diskObj)); + } + + d1(kprintf(__FUNC__ "/%ld: diskobj=%08lx\n", __LINE__, diskObj)); + + if (diskObj) + { + ULONG SupportedIconTypes = ~0; + + if (ScalosBase->lib_Version >= 40) + { + SCA_ScalosControl(NULL, + SCALOSCTRLA_GetSupportedIconTypes, &SupportedIconTypes, + TAG_END); + } + + IconObj = Convert2IconObjectTags(diskObj, + IDTA_SupportedIconTypes, SupportedIconTypes, + TAG_END); + + if (IconObj) + { + SetAttrs(IconObj, + DTA_Name, msg->filename, + IDTA_DoFreeDiskObject, TRUE, + TAG_END); + } + else + FreeDiskObject(diskObj); + } + + d1(if (diskObj && diskObj->do_DrawerData)\ + kprintf(__FUNC__ "/%ld: dd_Flags=%08lx\n", __LINE__, diskObj->do_DrawerData->dd_Flags)); + + d1(kprintf(__FUNC__ "/%ld: IconObj=%08lx\n", __LINE__, diskObj, IconObj)); + + return IconObj; +} + diff --git a/scalos/Plugins/OOP/wb39_plugin/NoDebug b/scalos/Plugins/OOP/wb39_plugin/NoDebug new file mode 100644 index 000000000..49ed68d29 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/NoDebug @@ -0,0 +1,3 @@ +; NoDebug +; 23 Dec 2001 16:17:11 +splat -s -o "d2(" "d1(" #?.c diff --git a/scalos/Plugins/OOP/wb39_plugin/Scalos_Helper.c b/scalos/Plugins/OOP/wb39_plugin/Scalos_Helper.c new file mode 100644 index 000000000..a0d33b528 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/Scalos_Helper.c @@ -0,0 +1,1073 @@ +// Scalos_Helper.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wb39.h" +#include "wb39proto.h" + + +// from wb39.c +extern struct ExecBase *SysBase; +extern struct DosLibrary *DOSBase; +extern struct Library *IconobjectBase; +extern T_UTILITYBASE UtilityBase; +extern struct ScalosBase *ScalosBase; +extern struct IntuitionBase *IntuitionBase; +extern struct Library *LayersBase; +extern struct GfxBase *GfxBase; +extern struct Library *IconBase; +extern struct Library *IFFParseBase; + +extern struct ScaRootList *rList; +extern WORD ScalosPrefs_IconOffsets[4]; + +extern ULONG DefaultStackSize; +extern ULONG fVolumeGauge; +extern ULONG fTitleBar; +extern ULONG TypeRestartTime; // Keyboard restart delay in s +extern BOOL NewIconsSupport; +extern BOOL ColorIconsSupport; + + +static void HandleWBNC(UWORD *Data, size_t Length); +static BOOL SetViewMode(struct ScaWindowStruct *swi, long ViewMode); +static BOOL IconsOverlap(const struct ScaIconNode *in1, const struct ScaIconNode *in2); + + +struct Library *PreferencesBase = NULL; +#ifdef __amigaos4__ +struct PreferencesIFace *IPreferences = NULL; +#endif + +ULONG MenuOpenParentWindow(struct ScaWindowStruct *swi) +{ + ULONG Result = RETURN_OK; + BPTR parentLock; + + if ((BPTR)NULL == swi->ws_Lock) + return ERROR_OBJECT_NOT_FOUND; + + parentLock = ParentDir(swi->ws_Lock); + if (parentLock) + { + char Path[200]; + + if(NameFromLock(parentLock, Path, sizeof(Path))) + { + if (!SCA_OpenDrawerByName(Path, NULL)) + Result = ERROR_OBJECT_NOT_FOUND; + } + + UnLock(parentLock); + } + + return Result; +} + + +ULONG MenuUnselectAll(struct ScaWindowStruct *swi) +{ + struct ScaWindowTask *wt = swi->ws_WindowTask; + struct ScaIconNode *icon; + + d1(kprintf(__FUNC__ "/%ld: swi=%08lx\n", __LINE__, swi);) + + ObtainSemaphore(wt->wt_IconSemaphore); + + for (icon=wt->wt_IconList; icon; icon = (struct ScaIconNode *) icon->in_Node.mln_Succ) + { + SelectIcon(swi, icon, FALSE); + } + + ReleaseSemaphore(wt->wt_IconSemaphore); + + return RETURN_OK; +} + + + +static BOOL SetViewMode(struct ScaWindowStruct *swi, long ViewMode) +{ + Object *newIconWindow; + + if (swi->ws_Viewmodes == ViewMode) + return TRUE; + + newIconWindow = (Object *) DoMethod(swi->ws_WindowTask->mt_MainObject, + SCCM_IconWin_NewViewMode, ViewMode); + if (newIconWindow) + { + DisposeObject(swi->ws_WindowTask->mt_MainObject); + swi->ws_WindowTask->mt_MainObject = newIconWindow; + } + + DoMethod(swi->ws_WindowTask->mt_WindowObject, + SCCM_Window_SetInnerSize); + + return UpdateScalosWindow(swi); +} + + +ULONG MenuSetViewModeByIcon(struct ScaWindowStruct *swi) +{ + if (SetViewMode(swi, SCAV_ViewModes_Icon)) + return RETURN_OK; + + return ERROR_OBJECT_NOT_FOUND; +} + + +ULONG MenuSetViewModeByName(struct ScaWindowStruct *swi) +{ + if (SetViewMode(swi, SCAV_ViewModes_Name)) + return RETURN_OK; + + return ERROR_OBJECT_NOT_FOUND; +} + + +ULONG MenuSetViewModeBySize(struct ScaWindowStruct *swi) +{ + if (SetViewMode(swi, SCAV_ViewModes_Size)) + return RETURN_OK; + + return ERROR_OBJECT_NOT_FOUND; +} + +ULONG MenuSetViewModeByType(struct ScaWindowStruct *swi) +{ + if (SetViewMode(swi, SCAV_ViewModes_Size)) + return RETURN_OK; + + return ERROR_OBJECT_NOT_FOUND; +} + +ULONG MenuSetViewModeByDate(struct ScaWindowStruct *swi) +{ + if (SetViewMode(swi, SCAV_ViewModes_Date)) + return RETURN_OK; + + return ERROR_OBJECT_NOT_FOUND; +} + + +ULONG MenuShowAllFiles(struct ScaWindowStruct *swi) +{ + ULONG showAllFiles = FALSE; + + GetAttr(SCCA_IconWin_ShowType, swi->ws_WindowTask->mt_MainObject, &showAllFiles); + if (showAllFiles) + return RETURN_OK; + + DoMethod(swi->ws_WindowTask->mt_MainObject, + SCCM_IconWin_MenuCommand, "showallfiles", + NULL, 0); + + return MenuUpdateScalosWindow(swi); +} + + +static void HandleWBNC(UWORD *Data, size_t Length) +{ + const struct WorkbenchPrefs *prefs = (const struct WorkbenchPrefs *) Data; + + d1(kprintf(__FUNC__ "/%ld: Data %04lx %04lx %04lx %04lx %04lx %04lx %04lx %04lx\n", \ + __LINE__, Data[0], Data[1], Data[2], Data[3], Data[4], Data[5], Data[6], Data[7])); + + DefaultStackSize = prefs->wbp_DefaultStackSize + d1(kprintf(__FUNC__ "/%ld: DefaultStackSize=%lu\n", __LINE__, DefaultStackSize)); + + if (DefaultStackSize < 4096) + DefaultStackSize = 4096; + + TypeRestartTime = prefs->wbp_TypeRestartTime; + + NewIconsSupport = prefs->wbp_NewIconsSupport; + ColorIconsSupport = prefs->wbp_ColorIconSupport; + + if (Length >= wpi_NoVolumeGauge) + fVolumeGauge = 0 == Data[wpi_NoVolumeGauge]; + + if (Length >= wpi_NoTitleBar) + fTitleBar = 0 == Data[wpi_NoTitleBar]; + +} + + +// +dm+ 20010518 Start +static void HandleWBHD(char *Data, size_t Length) +{ + if(Data && Length) + { + WorkbenchControl(NULL, + WBCTRLA_AddHiddenDeviceName, (ULONG) Data, + TAG_DONE); + } +} +// +dm+ 20010518 end + + +BOOL ParseWBPrefs(CONST_STRPTR filename) +{ + struct IFFHandle *iff; + LONG error; + + #define NUMPAIRS 2l + ULONG pairs[NUMPAIRS * 2] = {ID_PREF, ID_WBNC, ID_PREF, ID_WBHD}; + + d1(kprintf(__FUNC__ "/%ld: filename=<%s>\n", __LINE__, filename)); + + if( iff = AllocIFF() ) + { + if( iff->iff_Stream = (ULONG) Open((STRPTR) filename, MODE_OLDFILE ) ) + { + InitIFFasDOS( iff ); + + if( !(error = OpenIFF( iff, IFFF_READ ) ) ) + { + // +dm+ 20010518 Changed to parse each chunk as we find it rather than using collections + if( !(error = CollectionChunks( iff, (LONG*)pairs, NUMPAIRS) ) ) + { + StopOnExit( iff, ID_PREF, ID_FORM ); // +dm+ Changed 20010518 + + while(TRUE) + { + if( ( error = ParseIFF( iff, IFFPARSE_SCAN ) ) == IFFERR_EOC ) + { + struct CollectionItem *ci; + + ci = FindCollection( iff, ID_PREF, ID_WBNC); + while( ci ) + { + HandleWBNC(ci->ci_Data, ci->ci_Size); + ci = ci->ci_Next; + } + + // +dm+ 20010518 start + ci = FindCollection( iff, ID_PREF, ID_WBHD); + while( ci ) + { + HandleWBHD(ci->ci_Data, ci->ci_Size); + ci = ci->ci_Next; + } + // +dm+ 20010518 end + + } + else + break; + } + } + + CloseIFF( iff ); + } + Close( (BPTR) iff->iff_Stream ); + } + FreeIFF( iff ); + } + + if (ScalosBase->scb_LibNode.lib_Version >= 40) + { + ULONG IconTypes = 0; + + if (NewIconsSupport) + IconTypes |= IDTV_IconType_NewIcon; + if (ColorIconsSupport) + IconTypes |= IDTV_IconType_ColorIcon; + + SCA_ScalosControl(NULL, + SCALOSCTRLA_SetDefaultStackSize, DefaultStackSize, + SCALOSCTRLA_SetSupportedIconTypes, IconTypes, + TAG_END); + } + + return TRUE; +} + + +BOOL ReadScalosPrefs(void) +{ + APTR PrefsHandle; + BOOL Result = FALSE; + + d1(kprintf(__FUNC__ "/%ld\n", __LINE__)); + + PreferencesBase = OpenLibrary("preferences.library", 39); + if (NULL == PreferencesBase) + return FALSE; +#ifdef __amigaos4__ + IPreferences = (struct PreferencesIFace *)GetInterface((struct Library *)PreferencesBase, "main", 1, NULL); + if (NULL == IPreferences) + { + CloseLibrary(PreferencesBase); + return FALSE; + } +#endif + + d1(kprintf(__FUNC__ "/%ld\n", __LINE__)); + + PrefsHandle = AllocPrefsHandle("Scalos"); + if (PrefsHandle) + { + d1(kprintf(__FUNC__ "/%ld\n", __LINE__)); + + ReadPrefsHandle(PrefsHandle, "ENV:Scalos/Scalos.prefs"); + + if (sizeof(ScalosPrefs_IconOffsets) == GetPreferences(PrefsHandle, + MAKE_ID('M','A','I','N'), + SCP_IconOffsets, + ScalosPrefs_IconOffsets, sizeof(ScalosPrefs_IconOffsets))) + { + d1(kprintf(__FUNC__ "/%ld Icon Offsets = %ld %ld %ld %ld\n", \ + __LINE__, (LONG) ScalosPrefs_IconOffsets[0], \ + (LONG) ScalosPrefs_IconOffsets[1], \ + (LONG) ScalosPrefs_IconOffsets[2], \ + (LONG) ScalosPrefs_IconOffsets[3])); + Result = TRUE; + } + + FreePrefsHandle(PrefsHandle); + } + +#ifdef __amigaos4__ + DropInterface((struct Interface *)IPreferences); +#endif + CloseLibrary(PreferencesBase); + + if (ScalosBase->scb_LibNode.lib_Version >= 39 && ScalosBase->scb_LibNode.lib_Revision >= 234) + { + SCA_ScalosControl(NULL, + SCALOSCTRLA_GetDefaultStackSize, (ULONG) &DefaultStackSize, + TAG_END); + } + + d1(kprintf(__FUNC__ "/%ld Result=%ld\n", __LINE__, Result)); + + return Result; +} + + +// !!! wt->wt_IconSemaphore WILL STAY LOCKED IF ICON FOUND !!! +struct ScaIconNode *GetIconByName(struct ScaWindowStruct *swi, CONST_STRPTR IconName) +{ + struct ScaWindowTask *wt = swi->ws_WindowTask; + struct ScaIconNode *icon, *iconFound=NULL; + char wBuffer[256]; + + if (swi->ws_Lock) + NameFromLock(swi->ws_Lock, wBuffer, sizeof(wBuffer)); + + ObtainSemaphoreShared(wt->wt_IconSemaphore); + + for (icon=wt->wt_IconList; (NULL == iconFound) && icon; icon = (struct ScaIconNode *) icon->in_Node.mln_Succ) + { + char *Name = NULL; + + GetAttr(IDTA_Text, icon->in_Icon, (APTR) &Name); + + if (Name && 0 == Stricmp((STRPTR) IconName, Name)) + { + iconFound = icon; + } + } + + if (NULL == iconFound) + ReleaseSemaphore(wt->wt_IconSemaphore); + + return iconFound; +} + + +// !! SCALOS WINDOW LIST WILL STAY LOCKED IF FOUND (Result != NULL) !! +struct ScaWindowStruct *FindWindowByLock(BPTR xLock) +{ + struct ScaWindowList *swList = SCA_LockWindowList(SCA_LockWindowList_Shared); + struct ScaWindowStruct *Result = NULL; + + d1(kprintf(__FUNC__ "/%ld: xLock=%08lx\n", __LINE__, xLock)); + + if (swList) + { + struct ScaWindowStruct *swi; + + for (swi=swList->wl_WindowStruct; NULL == Result && swi; swi = (struct ScaWindowStruct *) swi->ws_Node.mln_Succ) + { + d1(kprintf(__FUNC__ "/%ld: swi=%08lx Lock=%08lx Same=%ld\n", __LINE__, \ + swi, swi->ws_Lock, SameLock(swi->ws_Lock, xLock))); + + if (LOCK_SAME == SameLock(swi->ws_Lock, xLock)) + { + d1(kprintf(__FUNC__ "/%ld: swi=%08lx\n", __LINE__, swi)); + Result = swi; + } + } + + if (NULL == Result) + { + d1(kprintf(__FUNC__ "/%ld: vor SCA_UnLockWindowList\n", __LINE__)); + SCA_UnLockWindowList(); + } + } + + d1(kprintf(__FUNC__ "/%ld: Result=%08lx\n", __LINE__, Result)); + + return Result; +} + + +// Return open IconWindow belonging to +// !! SCALOS WINDOW LIST WILL STAY LOCKED IF FOUND (Result != NULL) !! +struct ScaWindowStruct *GetIconNodeOpenWindow(BPTR dirLock, struct ScaIconNode *sIcon) +{ + struct ScaWindowStruct *swiFound = NULL; + char *IconName = NULL; + BPTR oldDir; + BPTR fLock; + + GetAttr(IDTA_Text, sIcon->in_Icon, (APTR) &IconName); + if (NULL == IconName) + return FALSE; + + oldDir = CurrentDir(dirLock); + + fLock = Lock(IconName, ACCESS_READ); + if (fLock) + { + struct ScaWindowList *swList = SCA_LockWindowList(SCA_LockWindowList_Shared); + + if (swList) + { + struct ScaWindowStruct *swi; + + for (swi=swList->wl_WindowStruct; !swiFound && swi; swi = (struct ScaWindowStruct *) swi->ws_Node.mln_Succ) + { + d1(kprintf(__FUNC__ "/%ld: swi=%08lx Lock=%08lx Flags=%08lx\n", __LINE__, \ + swi, swi->ws_Lock, swi->ws_Flags)); + + if (swi->ws_Lock) + { + if (LOCK_SAME == SameLock(swi->ws_Lock, fLock)) + swiFound = swi; + } + } + + if (NULL == swiFound) + { + d1(kprintf(__FUNC__ "/%ld: vor SCA_UnLockWindowList\n", __LINE__)); + SCA_UnLockWindowList(); + } + } + UnLock(fLock); + } + + CurrentDir(oldDir); + + return swiFound; +} + + +void MakeIconVisible(struct ScaWindowStruct *swi, struct ScaIconNode *sIcon) +{ + struct ExtGadget *gg = (struct ExtGadget *) sIcon->in_Icon; + LONG deltaX = 0, deltaY = 0; + LONG winRight, winBottom; + WORD iconLeft, iconTop, iconRight, iconBottom; + WORD winLeft, winTop; + + iconLeft = gg->BoundsLeftEdge - swi->ws_xoffset; + iconRight = iconLeft + gg->BoundsWidth - 1; + iconTop = gg->BoundsTopEdge - swi->ws_yoffset; + iconBottom = iconTop + gg->BoundsHeight - 1; + + winLeft = 0; + winTop = 0; + + GetAttr(SCCA_IconWin_InnerWidth, swi->ws_WindowTask->mt_MainObject, (ULONG *) &winRight); + GetAttr(SCCA_IconWin_InnerHeight, swi->ws_WindowTask->mt_MainObject, (ULONG *) &winBottom); + + d1(kprintf(__FUNC__ "/%ld: iconLeft=%ld iconRight=%ld iconTop=%ld iconBottom=%ld\n", \ + __LINE__, iconLeft, iconRight, iconTop, iconBottom);) + d1(kprintf(__FUNC__ "/%ld: winLeft=%ld winRight=%ld winTop=%ld winBottom=%ld\n", \ + __LINE__, winLeft, winRight, winTop, winBottom);) + + if (iconLeft < winLeft) + { + // must move Right + deltaX = iconLeft - winLeft; + } + else if (iconRight > winRight) + { + // must move iconLeft + deltaX = iconRight - winRight; + } + + if (iconTop < winTop) + { + // must move DOWN + deltaY = iconTop - winTop; + } + else if (iconBottom > winBottom) + { + // must move UP + deltaY = iconBottom - winBottom; + } + + d1(kprintf(__FUNC__ "/%ld: deltaX=%ld deltaY=%ld\n", __LINE__, deltaX, deltaY);) + + if (deltaX != 0 || deltaY != 0) + { + DoMethod(swi->ws_WindowTask->mt_MainObject, + SCCM_IconWin_DeltaMove, deltaX, deltaY); + + DoMethod(swi->ws_WindowTask->mt_MainObject, + SCCM_IconWin_SetVirtSize, SETVIRTF_AdjustRightSlider | SETVIRTF_AdjustBottomSlider); + } +} + + +void MoveIcon(struct ScaWindowStruct *swi, struct ScaIconNode *sIcon, LONG x, LONG y) +{ + struct ScaIconNode *in; + struct Region *oldClipRegion; + struct ExtGadget *gg = (struct ExtGadget *) sIcon->in_Icon; + long DeltaX, DeltaY; + + d1(kprintf(__FUNC__ "/%ld: swi=%08lx sIcon=%08lx x=%ld y=%ld\n", __LINE__, swi, sIcon, x, y);) + + oldClipRegion = (struct Region *) DoMethod(swi->ws_WindowTask->mt_WindowObject, + SCCM_Window_InitClipRegion); + + d1(kprintf(__FUNC__ "/%ld: ClipRegion=%08lx\n", __LINE__, swi->ws_Window->WLayer->ClipRegion);) + + // Erase original Icon + EraseRect(swi->ws_Window->RPort, + swi->ws_Window->BorderLeft + gg->BoundsLeftEdge - swi->ws_xoffset, + swi->ws_Window->BorderTop + gg->BoundsTopEdge - swi->ws_yoffset, + swi->ws_Window->BorderLeft + gg->BoundsLeftEdge + gg->BoundsWidth - 1 - swi->ws_xoffset, + swi->ws_Window->BorderTop + gg->BoundsTopEdge + gg->BoundsHeight - 1 - swi->ws_yoffset); + + // now redraw all icons overlapping the erased one + for (in=swi->ws_WindowTask->wt_IconList; in; in = (struct ScaIconNode *) in->in_Node.mln_Succ) + { + if (in != sIcon && IconsOverlap(sIcon, in)) + { + DoMethod(swi->ws_WindowTask->mt_MainObject, + SCCM_IconWin_DrawIcon, in->in_Icon); + } + } + + DeltaX = x - gg->LeftEdge; + DeltaY = y - gg->TopEdge; + + SetAttrs(sIcon->in_Icon, + GA_Left, x, + GA_Top, y, + TAG_END); + + gg->BoundsLeftEdge += DeltaX; + gg->BoundsTopEdge += DeltaY; + + DoMethod(swi->ws_WindowTask->mt_MainObject, + SCCM_IconWin_DrawIcon, sIcon->in_Icon); + + DoMethod(swi->ws_WindowTask->mt_WindowObject, + SCCM_Window_RemClipRegion, oldClipRegion); + + DoMethod(swi->ws_WindowTask->mt_MainObject, + SCCM_IconWin_SetVirtSize, SETVIRTF_AdjustRightSlider | SETVIRTF_AdjustBottomSlider); +} + + +void SelectIcon(struct ScaWindowStruct *swi, struct ScaIconNode *sIcon, BOOL Selected) +{ + struct ExtGadget *gg = (struct ExtGadget *) sIcon->in_Icon; + + d1(kprintf(__FUNC__ "/%ld: swi=%08lx sIcon=%08lx Selected=%ld\n", __LINE__, swi, sIcon, Selected);) + + if ( (!Selected && (gg->Flags & GFLG_SELECTED)) || (Selected && !(gg->Flags & GFLG_SELECTED))) + { + struct Region *oldClipRegion; + + oldClipRegion = (struct Region *) DoMethod(swi->ws_WindowTask->mt_WindowObject, + SCCM_Window_InitClipRegion); + + d1(kprintf(__FUNC__ "/%ld: ClipRegion=%08lx\n", __LINE__, swi->ws_Window->WLayer->ClipRegion);) + + SetAttrs(sIcon->in_Icon, + GA_Selected, Selected, + TAG_END); + + if (Selected && NULL == gg->SelectRender) + { + DoMethod(swi->ws_WindowTask->mt_MainObject, + SCCM_IconWin_LayoutIcon, sIcon->in_Icon, + IOLAYOUTF_SelectedImage); + } + else if (!Selected && NULL == gg->GadgetRender) + { + DoMethod(swi->ws_WindowTask->mt_MainObject, + SCCM_IconWin_LayoutIcon, sIcon->in_Icon, + IOLAYOUTF_NormalImage); + } + + DoMethod(swi->ws_WindowTask->mt_MainObject, + SCCM_IconWin_DrawIcon, sIcon->in_Icon); + + DoMethod(swi->ws_WindowTask->mt_WindowObject, + SCCM_Window_RemClipRegion, oldClipRegion); + } +} + + +// special names: "root" "active" +struct ScaWindowStruct *FindWindowByName(CONST_STRPTR WinName) +{ + struct ScaWindowList *swList = SCA_LockWindowList(SCA_LockWindowList_Shared); + struct ScaWindowStruct *Result = NULL; + BOOL FindActive = 0 == Stricmp((STRPTR) WinName, "active"); + BOOL FindRoot = 0 == Stricmp((STRPTR) WinName, "root"); + BPTR wnLock; + + if (!FindActive && !FindRoot) + wnLock = Lock((STRPTR) WinName, ACCESS_READ); + else + wnLock = (BPTR)NULL; + + if (swList) + { + struct ScaWindowStruct *swi; + + for (swi=swList->wl_WindowStruct; NULL == Result && swi; swi = (struct ScaWindowStruct *) swi->ws_Node.mln_Succ) + { + d1(kprintf(__FUNC__ "/%ld: swi=%08lx Lock=%08lx Flags=%08lx\n", __LINE__, \ + swi, swi->ws_Lock, swi->ws_Flags)); + + if (swi->ws_Window) + { + if (FindActive) + { + if (IntuitionBase->ActiveWindow == swi->ws_Window) + Result = swi; + } + else + { + if (swi->ws_Lock && !FindRoot) + { + if (LOCK_SAME == SameLock(swi->ws_Lock, wnLock)) + { + Result = swi; + } + } + else + { + // root window + if (FindRoot) + Result = swi; + } + } + } + } + + d1(kprintf(__FUNC__ "/%ld: vor SCA_UnLockWindowList\n", __LINE__)); + SCA_UnLockWindowList(); + } + + if (wnLock) + UnLock(wnLock); + + return Result; +} + + +BOOL CloseScalosWindow(struct ScaWindowStruct *swi) +{ + struct MsgPort *ReplyPort = CreateMsgPort(); + struct Message *Msg; + + if (NULL == ReplyPort) + { + d1(kprintf(__FUNC__ "/%ld: vor SCA_UnLockWindowList\n", __LINE__)); + SCA_UnLockWindowList(); + return FALSE; + } + + Msg = (struct Message *) SCA_AllocMessage(MTYP_CloseWindow, 0); + if (NULL == Msg) + { + d1(kprintf(__FUNC__ "/%ld: vor SCA_UnLockWindowList\n", __LINE__)); + SCA_UnLockWindowList(); + DeleteMsgPort(ReplyPort); + + return FALSE; + } + + Msg->mn_ReplyPort = ReplyPort; + + d1(kprintf(__FUNC__ "/%ld: vor SCA_UnLockWindowList\n", __LINE__)); + SCA_UnLockWindowList(); + + PutMsg(swi->ws_MessagePort, Msg); + + WaitPort(ReplyPort); + while (Msg = GetMsg(ReplyPort)) + { + SCA_FreeMessage((struct ScalosMessage *) Msg); + } + + DeleteMsgPort(ReplyPort); + + return TRUE; +} + + +BOOL UpdateScalosWindow(struct ScaWindowStruct *swi) +{ + struct MsgPort *ReplyPort = CreateMsgPort(); + struct Message *Msg; + + if (NULL == ReplyPort) + return FALSE; + + Msg = (struct Message *) SCA_AllocMessage(MTYP_Update, 0); + if (NULL == Msg) + { + DeleteMsgPort(ReplyPort); + + return FALSE; + } + + Msg->mn_ReplyPort = ReplyPort; + + PutMsg(swi->ws_MessagePort, Msg); + + WaitPort(ReplyPort); + while (Msg = GetMsg(ReplyPort)) + { + SCA_FreeMessage((struct ScalosMessage *) Msg); + } + + DeleteMsgPort(ReplyPort); + + return TRUE; +} + + +struct ScaWindowStruct *GetNextWindow(struct ScaWindowStruct *swi) +{ + struct ScaWindowStruct *Result = (struct ScaWindowStruct *) swi->ws_Node.mln_Succ; + + if (NULL == Result) + { + // no successor, return first window in list + struct ScaWindowList *swList = SCA_LockWindowList(SCA_LockWindowList_Shared); + + if (swList) + { + Result = swList->wl_WindowStruct; + + SCA_UnLockWindowList(); + } + } + + return Result; +} + + +struct ScaWindowStruct *GetPrevWindow(struct ScaWindowStruct *swi) +{ + struct ScaWindowStruct *Result = (struct ScaWindowStruct *) swi->ws_Node.mln_Pred; + + if (NULL == Result) + { + // no predecessor, return last window in list + struct ScaWindowList *swList = SCA_LockWindowList(SCA_LockWindowList_Shared); + + if (swList) + { + Result = swList->wl_WindowStruct; + while (Result->ws_Node.mln_Succ) + Result = (struct ScaWindowStruct *) Result->ws_Node.mln_Succ; + + SCA_UnLockWindowList(); + } + } + + return Result; +} + + +BOOL DeleteDirectory(CONST_STRPTR Path) +{ + BPTR dirLock; + BOOL Success = TRUE; + + d1(kprintf(__FUNC__ "/%ld: Path=<%s>\n", __LINE__, Path);) + + dirLock = Lock((STRPTR) Path, ACCESS_READ); + if (dirLock) + { + struct FileInfoBlock *fib = AllocDosObject(DOS_FIB, TAG_END); + + if (fib) + { + BPTR oldDir; + + Examine(dirLock, fib); + + d1(kprintf(__FUNC__ "/%ld: Name=<%s> Type=%ld\n", __LINE__, fib->fib_FileName, fib->fib_DirEntryType);) + + switch (fib->fib_DirEntryType) + { + case ST_ROOT: + case ST_USERDIR: + case ST_LINKDIR: + oldDir = CurrentDir(dirLock); + + while (Success && ExNext(dirLock, fib)) + { + d1(kprintf(__FUNC__ "/%ld: Name=<%s> Type=%ld\n", \ + __LINE__, fib->fib_FileName, fib->fib_DirEntryType);) + Success = DeleteDirectory(fib->fib_FileName); + }; + + if (ERROR_NO_MORE_ENTRIES != IoErr()) + Success = FALSE; + + CurrentDir(oldDir); + + d1(kprintf(__FUNC__ "/%ld: Success=%ld\n", __LINE__, Success);) + break; + } + + FreeDosObject(DOS_FIB, fib); + } + else + Success = FALSE; + + UnLock(dirLock); + + if (Success) + { + if (!DeleteFile((STRPTR) Path)) + Success = FALSE; + + d1(kprintf(__FUNC__ "/%ld: Success=%ld\n", __LINE__, Success);) + } + } + else + Success = FALSE; + + d1(kprintf(__FUNC__ "/%ld: Success=%ld\n", __LINE__, Success);) + + return Success; +} + + +BOOL RemScalosIcon(BPTR Lock, CONST_STRPTR Name) +{ + struct ScaWindowStruct *swi = FindWindowByLock(Lock); + + if (swi) + { + DoMethod(swi->ws_WindowTask->mt_MainObject, + SCCM_IconWin_RemIcon, Lock, Name); + + SCA_UnLockWindowList(); + } + + return TRUE; +} + + +BOOL isIconSelected(const struct ScaIconNode *icon) +{ + struct Gadget *gg = (struct Gadget *) icon->in_Icon; + + return (BOOL) ((gg->Flags & GFLG_SELECTED) ? TRUE : FALSE); +} + + +struct ScaRootList *GetScalosRootList(void) +{ + static struct ScaRootList rl; + struct ScaRootList *Result; + + struct ScaWindowList *swList = SCA_LockWindowList(SCA_LockWindowList_Shared); + + if (swList && swList->wl_WindowStruct && swList->wl_WindowStruct->ws_WindowTask + && swList->wl_WindowStruct->ws_WindowTask->mt_MainObject) + { + struct ScaRootList *prl = (struct ScaRootList *) swList->wl_WindowStruct->ws_WindowTask->mt_MainObject; + + rl = *prl; + Result = &rl; + } + else + Result = NULL; + + d1(kprintf(__FUNC__ "/%ld: rl_WindowTask=%08lx rl_InternInfos=%08lx\n", \ + __LINE__, rl.rl_WindowTask, rl.rl_internInfos)); + + SCA_UnLockWindowList(); + + return Result; +} + + +ULONG MenuNewDrawer(CONST_STRPTR Name) +{ + BPTR dirLock; + ULONG Result = RETURN_OK; + + dirLock = CreateDir((STRPTR) Name); + if (dirLock) + { + // Drawer created Ok, new create default drawer icon + struct DiskObject *diskObj = GetDefDiskObject(WBDRAWER); + + if (diskObj) + { + if (!PutDiskObject((STRPTR) Name, diskObj)) + Result = IoErr(); + + FreeDiskObject(diskObj); + } + else + Result = IoErr(); + + UnLock(dirLock); + } + else + Result = IoErr(); + + return Result; +} + + +ULONG MenuUpdateScalosWindow(struct ScaWindowStruct *swi) +{ + if (!UpdateScalosWindow(swi)) + return ERROR_NO_FREE_STORE; + + return RETURN_OK; +} + + +ULONG MenuCloseScalosWindow(struct ScaWindowStruct *swi) +{ + if (CloseScalosWindow(swi)) + return RETURN_OK; + + return ERROR_OBJECT_NOT_FOUND; +} + + +static BOOL IconsOverlap(const struct ScaIconNode *in1, const struct ScaIconNode *in2) +{ + const struct ExtGadget *gg1 = (struct ExtGadget *) in1->in_Icon; + const struct ExtGadget *gg2 = (struct ExtGadget *) in2->in_Icon; + + if (gg1->BoundsLeftEdge < (gg2->BoundsLeftEdge + gg2->BoundsWidth) + && (gg1->BoundsLeftEdge + gg1->BoundsWidth) >= gg2->BoundsLeftEdge + && gg1->BoundsTopEdge < (gg2->BoundsTopEdge + gg2->BoundsHeight) + && (gg1->BoundsTopEdge + gg1->BoundsHeight) >= gg2->BoundsTopEdge) + return TRUE; + + return FALSE; +} + + +// returns correct name for all icon types. +// guaranteed to NEVER return NULL. +CONST_STRPTR GetIconName(struct ScaIconNode *in) +{ + CONST_STRPTR IconName = NULL; + + if (in) + { + ULONG IconType; + + GetAttr(IDTA_Type, in->in_Icon, &IconType); + + if (WBAPPICON == IconType) + { + GetAttr(IDTA_Text, in->in_Icon, (APTR) &IconName); + } + else + { + if (in->in_DeviceIcon) + { + if (in->in_DeviceIcon->di_Volume) + IconName = in->in_DeviceIcon->di_Volume; + else + IconName = in->in_DeviceIcon->di_Device; + } + else + { + IconName = in->in_Name; + } + } + } + + if (NULL == IconName) + IconName = ""; + + return IconName; +} + + +struct ScaWindowStruct *WaitOpen(struct ScaWindowStruct *ws) +{ + d1(kprintf(__FUNC__ "/%ld: ws=%08lx\n", __LINE__, ws)); + if (ws) + { + ULONG Reading = FALSE; + + // if ws is non-NULL, wait until icon reading is finished + do { + GetAttr(SCCA_IconWin_Reading, ws->ws_WindowTask->mt_MainObject, &Reading); + + d1(kprintf(__FUNC__ "/%ld: Reading=%ld\n", __LINE__, Reading)); + if (Reading) + Delay(20); // Wait 400ms + } while (Reading); + } + + return ws; +} diff --git a/scalos/Plugins/OOP/wb39_plugin/Scalos_Helper.h b/scalos/Plugins/OOP/wb39_plugin/Scalos_Helper.h new file mode 100644 index 000000000..3b9181b65 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/Scalos_Helper.h @@ -0,0 +1,43 @@ +// wb39proto.h +// $Date$ +// $Revision$ + + +#ifndef SCALOS_HELPER_H_INCLUDED +#define SCALOS_HELPER_H_INCLUDED + +#include + +ULONG MenuOpenParentWindow(struct ScaWindowStruct *swi); +ULONG MenuUnselectAll(struct ScaWindowStruct *swi); +ULONG MenuSetViewModeByIcon(struct ScaWindowStruct *swi); +ULONG MenuSetViewModeByName(struct ScaWindowStruct *swi); +ULONG MenuSetViewModeBySize(struct ScaWindowStruct *swi); +ULONG MenuSetViewModeByDate(struct ScaWindowStruct *swi); +ULONG MenuSetViewModeByType(struct ScaWindowStruct *swi); +ULONG MenuShowAllFiles(struct ScaWindowStruct *swi); +BOOL ParseWBPrefs(CONST_STRPTR filename); +BOOL ReadScalosPrefs(void); +struct ScaWindowStruct *GetIconNodeOpenWindow(BPTR dirLock, struct ScaIconNode *sIcon); +struct ScaIconNode *GetIconByName(struct ScaWindowStruct *swi, CONST_STRPTR IconName); +struct ScaWindowStruct *FindWindowByLock(BPTR xLock); +void MakeIconVisible(struct ScaWindowStruct *swi, struct ScaIconNode *sIcon); +void MoveIcon(struct ScaWindowStruct *swi, struct ScaIconNode *sIcon, LONG x, LONG y); +void SelectIcon(struct ScaWindowStruct *swi, struct ScaIconNode *sIcon, BOOL Selected); +struct ScaWindowStruct *FindWindowByName(CONST_STRPTR WinName); +BOOL CloseScalosWindow(struct ScaWindowStruct *swi); +BOOL UpdateScalosWindow(struct ScaWindowStruct *swi); +struct ScaWindowStruct *GetNextWindow(struct ScaWindowStruct *swi); +struct ScaWindowStruct *GetPrevWindow(struct ScaWindowStruct *swi); +BOOL DeleteDirectory(CONST_STRPTR Path); +BOOL RemScalosIcon(BPTR Lock, CONST_STRPTR Name); +BOOL isIconSelected(const struct ScaIconNode *icon); +struct ScaRootList *GetScalosRootList(void); +ULONG MenuNewDrawer(CONST_STRPTR Name); +ULONG MenuUpdateScalosWindow(struct ScaWindowStruct *swi); +ULONG MenuCloseScalosWindow(struct ScaWindowStruct *swi); +CONST_STRPTR GetIconName(struct ScaIconNode *in); +struct ScaWindowStruct *WaitOpen(struct ScaWindowStruct *ws); + + +#endif /* SCALOS_HELPER_H_INCLUDED */ diff --git a/scalos/Plugins/OOP/wb39_plugin/WorkbenchControl.c b/scalos/Plugins/OOP/wb39_plugin/WorkbenchControl.c new file mode 100644 index 000000000..5013f3a62 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/WorkbenchControl.c @@ -0,0 +1,1211 @@ +// workbenchcontrol.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "wb39.h" +#include "wb39proto.h" + +//------------------------------------------------------------------------- + +enum HiddenDevArg { HIDDENDEV_Verbose, HIDDENDEV_Quiet }; + +//------------------------------------------------------------------------- + +// aus wb39.c +extern ULONG DefaultStackSize; +extern ULONG fVolumeGauge; +extern ULONG fTitleBar; +extern ULONG TypeRestartTime; // Keyboard restart delay in s +extern struct ScaRootList *rList; +extern struct List HiddenDeviceList; // +dm+ 20010518 +extern struct SignalSemaphore HiddenDevListSema; // +jl+ 20010523 Semaphore to protect HiddenDeviceList + + +static struct List *AllocList(void); +static void FreeList(struct List *pl); +static BPTR DupWBPathList(void); +static void FreePathList(BPTR bList); +static struct List *GetOpenDrawerList(void); +static BOOL IsOpen(const char *Name); +static BOOL RedrawAppIcon(struct ScaAppObjNode *AppIcon); +static struct List *GetSelectedIconList(void); +static struct List *GetHiddenDeviceList(void); +static void AddHiddenDevice(STRPTR devname, enum HiddenDevArg Quiet); +static void RemoveHiddenDevice(STRPTR devname, enum HiddenDevArg Quiet); +#if !defined(__SASC) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) +static size_t stccpy(char *dest, const char *src, size_t MaxLen); +#endif /* !defined(__SASC) &&!defined(__MORPHOS__) */ + +//------------------------------------------------------------------------- + +static ULONG fIconBorder = FALSE; +static ULONG fDrawerNotification = TRUE; +static ULONG IconMemoryType = MEMF_ANY; + +//------------------------------------------------------------------------- + +// undocumented WorkbenchControl tags + +#ifdef __AROS__ +#define WBA_Dummy WBA_BASE +#endif + +#define WBCTRLAX_GetMaxCopyMemory (WBA_Dummy+40) +#define WBCTRLAX_SetMaxCopyMemory (WBA_Dummy+41) + +#define WBCTRLAX_GetIconMemoryType (WBA_Dummy+49) +#define WBCTRLAX_SetIconMemoryType (WBA_Dummy+50) + +#define WBCTRLAX_GetDrawerNotification (WBA_Dummy+51) +#define WBCTRLAX_SetDrawerNotification (WBA_Dummy+52) + +#define WBCTRLAX_AddHiddenDeviceName (WBA_Dummy+53) /* used by workbench prefs */ +#define WBCTRLAX_RemoveHiddenDeviceName (WBA_Dummy+54) /* used by workbench prefs */ + +#define WBCTRLAX_SetVolumeGauge (WBA_Dummy+59) +#define WBCTRLAX_GetVolumeGauge (WBA_Dummy+60) + +#define WBCTRLAX_GetStrangeString (WBA_Dummy+62) + +#define WBCTRLAX_GetIconBorder (WBA_Dummy+63) +#define WBCTRLAX_SetIconBorder (WBA_Dummy+64) + +#define WBCTRLAX_GetTitleBar (WBA_Dummy+67) +#define WBCTRLAX_SetTitleBar (WBA_Dummy+68) + +//------------------------------------------------------------------------- + +// WorkbenchControlA() +LIBFUNC_P3(BOOL, myWorkbenchControlA, + A0, STRPTR, name, + A1, struct TagItem *, tags, + A6, struct Library *, WorkbenchBase) +{ + BOOL Success = TRUE; + struct TagItem *taglist = tags, *ti; + LONG ErrorCode = RETURN_OK; + + (void)WorkbenchBase; + + d1(kprintf("%s/%s/%ld: START Caller=<%s>\n", __FILE__, __FUNC__, __LINE__, FindTask(NULL)->tc_Node.ln_Name)); + + while (ti = NextTagItem(&taglist)) + { + d1(kprintf("%s/%s/%ld: Tag=%08lx : Data=%08lx name=<%s>\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Tag, ti->ti_Data, name ? name : (STRPTR) "")); + + switch (ti->ti_Tag) + { + case WBCTRLA_IsOpen: // (LONG *) + d1(kprintf("%s/%s/%ld: WBCTRLA_IsOpen\n", __FILE__, __FUNC__, __LINE__)); + if (ti->ti_Data) + { + *((LONG *) ti->ti_Data) = IsOpen(name); + d1(kprintf("%s/%s/%ld: WBCTRLA_IsOpen = %ld\n", __FILE__, __FUNC__, __LINE__, \ + *((LONG *) ti->ti_Data))); + } + else + ErrorCode = ERROR_REQUIRED_ARG_MISSING; + break; + + case WBCTRLA_DuplicateSearchPath: // (BPTR *) + if (ti->ti_Data) + { + d1(kprintf("%s/%s/%ld: WBCTRLA_DuplicateSearchPath\n", __FILE__, __FUNC__, __LINE__)); + *((BPTR *) ti->ti_Data) = DupWBPathList(); + if ((BPTR)NULL == *((BPTR *) ti->ti_Data)) + ErrorCode = ERROR_NO_FREE_STORE; + } + else + ErrorCode = ERROR_REQUIRED_ARG_MISSING; + break; + + case WBCTRLA_FreeSearchPath: // (BPTR) + d1(kprintf("%s/%s/%ld: WBCTRLA_FreeSearchPath\n", __FILE__, __FUNC__, __LINE__)); + FreePathList((BPTR) ti->ti_Data); + break; + + case WBCTRLA_GetDefaultStackSize: // (ULONG *) + d1(kprintf("%s/%s/%ld: WBCTRLA_GetDefaultStackSize\n", __FILE__, __FUNC__, __LINE__)); + if (ti->ti_Data) + { + if (ScalosBase->scb_LibNode.lib_Version >= 40) + { + SCA_ScalosControl(NULL, + SCALOSCTRLA_GetDefaultStackSize, (ULONG) &DefaultStackSize, + TAG_END); + } + *((ULONG *) ti->ti_Data) = DefaultStackSize; + } + else + ErrorCode = ERROR_REQUIRED_ARG_MISSING; + break; + + case WBCTRLA_SetDefaultStackSize: // (ULONG) + d1(kprintf("%s/%s/%ld: WBCTRLA_SetDefaultStackSize Size=%lu\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + if (ti->ti_Data > 4096) + DefaultStackSize = ti->ti_Data; + else + ErrorCode = ERROR_BAD_NUMBER; + + if (ScalosBase->scb_LibNode.lib_Version >= 40) + { + SCA_ScalosControl(NULL, + SCALOSCTRLA_SetDefaultStackSize, DefaultStackSize, + TAG_END); + } + break; + + case WBCTRLA_RedrawAppIcon: // (struct AppIcon *) + d1(kprintf("%s/%s/%ld: WBCTRLA_RedrawAppIcon AppIcon=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + if (ti->ti_Data) + { + Success = RedrawAppIcon((struct ScaAppObjNode *) ti->ti_Data); + } + else + ErrorCode = ERROR_REQUIRED_ARG_MISSING; + break; + + case WBCTRLA_GetProgramList: // (struct List **) + d1(kprintf("%s/%s/%ld: WBCTRLA_GetProgramList\n", __FILE__, __FUNC__, __LINE__)); + if (ti->ti_Data) + { + if (ScalosBase->scb_LibNode.lib_Version >= 40) + { + SCA_ScalosControl(NULL, + SCALOSCTRLA_GetProgramList, ti->ti_Data, + TAG_END); + } + else + { + *((struct List **) ti->ti_Data) = AllocList(); + } + + if (NULL == *((struct List **) ti->ti_Data)) + ErrorCode = ERROR_NO_FREE_STORE; + + } + else + ErrorCode = ERROR_REQUIRED_ARG_MISSING; + break; + + case WBCTRLA_FreeProgramList: // (struct List *) + d1(kprintf("%s/%s/%ld: WBCTRLA_FreeProgramList List=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + if (ScalosBase->scb_LibNode.lib_Version >= 40) + { + SCA_ScalosControl(NULL, + SCALOSCTRLA_FreeProgramList, ti->ti_Data, + TAG_END); + } + else + { + FreeList((struct List *) ti->ti_Data); + } + break; + + case WBCTRLA_GetSelectedIconList: // (struct List **) + d1(kprintf("%s/%s/%ld: WBCTRLA_GetSelectedIconList\n", __FILE__, __FUNC__, __LINE__)); + if (ti->ti_Data) + { + *((struct List **) ti->ti_Data) = GetSelectedIconList(); + if (NULL == *((struct List **) ti->ti_Data)) + ErrorCode = ERROR_NO_FREE_STORE; + } + else + ErrorCode = ERROR_REQUIRED_ARG_MISSING; + break; + + case WBCTRLA_FreeSelectedIconList: // (struct List *) + d1(kprintf("%s/%s/%ld: FreeSelectedIconList List=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + FreeList((struct List *) ti->ti_Data); + break; + + case WBCTRLA_GetOpenDrawerList: // (struct List **) + d1(kprintf("%s/%s/%ld: WBCTRLA_GetOpenDrawerList\n", __FILE__, __FUNC__, __LINE__)); + if (ti->ti_Data) + { + *((struct List **) ti->ti_Data) = GetOpenDrawerList(); + if (NULL == *((struct List **) ti->ti_Data)) + ErrorCode = ERROR_NO_FREE_STORE; + } + else + ErrorCode = ERROR_REQUIRED_ARG_MISSING; + break; + + case WBCTRLA_FreeOpenDrawerList: // (struct List *) + d1(kprintf("%s/%s/%ld: WBCTRLA_FreeOpenDrawerList List=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + FreeList((struct List *) ti->ti_Data); + break; + + case WBCTRLA_AddHiddenDeviceName: // (STRPTR) + d1(kprintf("%s/%s/%ld: WBCTRLA_AddHiddenDeviceName name=<%s>\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + AddHiddenDevice((STRPTR)ti->ti_Data, HIDDENDEV_Verbose); + break; + + case WBCTRLAX_AddHiddenDeviceName: // (STRPTR) used by workbench prefs + d1(kprintf("%s/%s/%ld: WBCTRLA_AddHiddenDeviceName (+53) name=<%s>\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + AddHiddenDevice((STRPTR)ti->ti_Data, HIDDENDEV_Quiet); + break; + + case WBCTRLA_RemoveHiddenDeviceName: // (STRPTR) + d1(kprintf("%s/%s/%ld: WBCTRLA_RemoveHiddenDeviceName name=<%s>\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + RemoveHiddenDevice((STRPTR)ti->ti_Data, HIDDENDEV_Verbose); + break; + + case WBCTRLAX_RemoveHiddenDeviceName: // (STRPTR) user by workbench prefs + d1(kprintf("%s/%s/%ld: WBCTRLA_RemoveHiddenDeviceName (+54) name=<%s>\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + RemoveHiddenDevice((STRPTR)ti->ti_Data, HIDDENDEV_Quiet); + break; + + case WBCTRLA_GetHiddenDeviceList: // (struct List **) + // +dm+ 20010518 start + d1(kprintf("%s/%s/%ld: WBCTRLA_GetHiddenDeviceList List **=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + if(ti->ti_Data) + { + *((struct List **) ti->ti_Data) = GetHiddenDeviceList(); + d1(kprintf("%s/%s/%ld: WBCTRLA_GetHiddenDeviceList List *=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + *((struct List **) ti->ti_Data))); + if (NULL == *((struct List **) ti->ti_Data)) + ErrorCode = ERROR_NO_FREE_STORE; + } + // +dm+ 20010518 end + else + ErrorCode = ERROR_REQUIRED_ARG_MISSING; + break; + + case WBCTRLA_FreeHiddenDeviceList: // (struct List *) + d1(kprintf("%s/%s/%ld: WBCTRLA_FreeHiddenDeviceList List=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + FreeList((struct List *) ti->ti_Data); + break; + + case WBCTRLA_GetTypeRestartTime: // (ULONG *) + d1(kprintf("%s/%s/%ld: WBCTRLA_GetTypeRestartTime\n", __FILE__, __FUNC__, __LINE__)); + if (ti->ti_Data) + { + if (ScalosBase->scb_LibNode.lib_Version >= 40) + { + SCA_ScalosControl(NULL, + SCALOSCTRLA_GetTypeRestartTime, (ULONG) &TypeRestartTime, + TAG_END); + } + + *((ULONG *) ti->ti_Data) = TypeRestartTime; + } + else + ErrorCode = ERROR_REQUIRED_ARG_MISSING; + break; + + case WBCTRLA_SetTypeRestartTime: // (ULONG) + d1(kprintf("%s/%s/%ld: WBCTRLA_SetTypeRestartTime time=%lu\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + if (ti->ti_Data > 0) + { + // nop + TypeRestartTime = ti->ti_Data; + + if (ScalosBase->scb_LibNode.lib_Version >= 40) + { + SCA_ScalosControl(NULL, + SCALOSCTRLA_SetTypeRestartTime, TypeRestartTime, + TAG_END); + } + } + else + ErrorCode = ERROR_BAD_NUMBER; + break; + + case WBA_Dummy+46: // (ULONG) + // Set/clear icon.library global screen + // TRUE=set, FALSE=clear + d1(kprintf("%s/%s/%ld: (set global screen) f=%lu\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + + switch (ti->ti_Data) + { + case FALSE: + // IconControlA() + IconControl(NULL, + ICONCTRLA_SetGlobalScreen, NULL, + TAG_END); + break; + case TRUE: + { + struct Screen *wbScreen = LockPubScreen("Workbench"); + + IconControl(NULL, + ICONCTRLA_SetGlobalScreen, (ULONG) wbScreen, + TAG_END); + + UnlockPubScreen(NULL, wbScreen); + } + break; + } + break; + + case WBCTRLAX_GetMaxCopyMemory: // (ULONG *) + d1(kprintf("%s/%s/%ld: (get max copy memory) f=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + if (ti->ti_Data) + { + if (ScalosBase->scb_LibNode.lib_Version >= 40) + { + SCA_ScalosControl(NULL, + SCALOSCTRLA_GetCopyBuffSize, ti->ti_Data, + TAG_END); + } + else + { + ErrorCode = ERROR_INVALID_RESIDENT_LIBRARY; + } + } + else + ErrorCode = ERROR_REQUIRED_ARG_MISSING; + break; + + case WBCTRLAX_SetMaxCopyMemory: // (ULONG) + d1(kprintf("%s/%s/%ld: (set max copy memory) f=%lu\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + if (ti->ti_Data >= 1000 && ti->ti_Data <= 0x400000) + { + if (ScalosBase->scb_LibNode.lib_Version >= 40) + { + SCA_ScalosControl(NULL, + SCALOSCTRLA_SetCopyBuffSize, ti->ti_Data, + TAG_END); + } + else + { + ErrorCode = ERROR_INVALID_RESIDENT_LIBRARY; + } + } + else + ErrorCode = ERROR_BAD_NUMBER; + break; + + case WBCTRLAX_GetDrawerNotification: // (ULONG *) + d1(kprintf("%s/%s/%ld: (get drawer notification) f=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + if (ti->ti_Data) + { + *((ULONG *) ti->ti_Data) = fDrawerNotification; + } + else + ErrorCode = ERROR_REQUIRED_ARG_MISSING; + break; + + case WBCTRLAX_SetDrawerNotification: // (ULONG) + d1(kprintf("%s/%s/%ld: (set drawer notification) f=%lu\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + fDrawerNotification = 0 != ti->ti_Data; + break; + + case WBCTRLAX_GetIconMemoryType: // (ULONG *) + d1(kprintf("%s/%s/%ld: (get Icon memory type) f=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + if (ti->ti_Data) + { + *((ULONG *) ti->ti_Data) = IconMemoryType; + } + else + ErrorCode = ERROR_REQUIRED_ARG_MISSING; + break; + + case WBCTRLAX_SetIconMemoryType: // (ULONG) + d1(kprintf("%s/%s/%ld: (set Icon memory type) f=%lu\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + IconMemoryType = ti->ti_Data; + break; + + case WBCTRLAX_GetVolumeGauge: // (ULONG *) + // query Volume Gauge + // TRUE=on, FALSE=off + d1(kprintf("%s/%s/%ld: (get Volume Gauge) f=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + if (ti->ti_Data) + { + *((ULONG *) ti->ti_Data) = fVolumeGauge; + } + else + ErrorCode = ERROR_REQUIRED_ARG_MISSING; + break; + + case WBCTRLAX_SetVolumeGauge: // (ULONG) + // Switch Volume Gauge + // TRUE=on, FALSE=off + d1(kprintf("%s/%s/%ld: (set Volume Gauge) f=%lu\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + + fVolumeGauge = 0 != ti->ti_Data; + break; + + case WBCTRLAX_GetStrangeString: // (ULONG *) + d1(kprintf("%s/%s/%ld: WBCTRLAX_GetStrangeString f=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + if (ti->ti_Data) + { + // Heaven knowns what is it good for... + // but workbench does it that way... + ULONG *lPtr = (ULONG *) ti->ti_Data; + + *lPtr++ = 0x67452301; + *lPtr++ = 0xEFCDAB89; + *lPtr++ = 0x98BADCFE; + *lPtr++ = 0x10325476; + *lPtr++ = 0; + *lPtr = 0; + } + else + ErrorCode = ERROR_REQUIRED_ARG_MISSING; + break; + + case WBCTRLAX_GetIconBorder: // (ULONG *) + d1(kprintf("%s/%s/%ld: (get icon border) f=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + if (ti->ti_Data) + { + *((ULONG *) ti->ti_Data) = fIconBorder; + } + else + ErrorCode = ERROR_REQUIRED_ARG_MISSING; + break; + + case WBCTRLAX_SetIconBorder: // (ULONG) + d1(kprintf("%s/%s/%ld: (set Icon border) f=%lu\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + fIconBorder = 0 != ti->ti_Data; + break; + + case WBCTRLAX_GetTitleBar: // (ULONG *) + d1(kprintf("%s/%s/%ld: (get Title bar) f=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + if (ti->ti_Data) + { + *((ULONG *) ti->ti_Data) = fTitleBar; + } + else + ErrorCode = ERROR_REQUIRED_ARG_MISSING; + d1(kprintf("%s/%s/%ld: fTitleBar=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + fTitleBar)); + break; + + case WBCTRLAX_SetTitleBar: // (ULONG) + // Switch Title Bar + // TRUE=on, FALSE=off + d1(kprintf("%s/%s/%ld: (set Title bar) f=%lu\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + + fTitleBar = 0 != ti->ti_Data; + d1(kprintf("%s/%s/%ld: fTitleBar=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + fTitleBar)); + break; + + case WBA_Dummy+55: // (ULONG *) + // seems to do some kind of Workbench refresh + d1(kprintf("%s/%s/%ld: (refresh WB) f=%lu\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + + if (rList && rList->rl_internInfos->ii_MainWindowStruct) + { + UpdateScalosWindow(rList->rl_internInfos->ii_MainWindowStruct); + } + break; + + case WBA_Dummy+58: // (ULONG *) + // looks like some kind of copy protection for AWeb-II + d1(kprintf("%s/%s/%ld: 0x8000A03A\n", __FILE__, __FUNC__, __LINE__)); + if (ti->ti_Data) + { + *((ULONG *) ti->ti_Data) = 0x1731f8e9; + } + else + ErrorCode = ERROR_REQUIRED_ARG_MISSING; + break; + + case WBCTRLA_GetCopyHook: + d1(kprintf("%s/%s/%ld: WBCTRLA_GetCopyHook\n", __FILE__, __FUNC__, __LINE__)); + if (ScalosBase->scb_LibNode.lib_Version >= 40) + { + SCA_ScalosControl(NULL, + SCALOSCTRLA_GetCopyHook, ti->ti_Data, + TAG_END); + } + else + Success = FALSE; + break; + + case WBCTRLA_SetCopyHook: + d1(kprintf("%s/%s/%ld: WBCTRLA_SetCopyHook Hook=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + if (ScalosBase->scb_LibNode.lib_Version >= 40) + { + SCA_ScalosControl(NULL, + SCALOSCTRLA_SetCopyHook, ti->ti_Data, + TAG_END); + } + else + Success = FALSE; + break; + + case WBCTRLA_GetDeleteHook: + d1(kprintf("%s/%s/%ld: WBCTRLA_GetDeleteHook\n", __FILE__, __FUNC__, __LINE__)); + if (ScalosBase->scb_LibNode.lib_Version >= 40) + { + SCA_ScalosControl(NULL, + SCALOSCTRLA_GetDeleteHook, ti->ti_Data, + TAG_END); + } + else + Success = FALSE; + break; + + case WBCTRLA_SetDeleteHook: + d1(kprintf("%s/%s/%ld: WBCTRLA_SetDeleteHook Hook=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + if (ScalosBase->scb_LibNode.lib_Version >= 40) + { + SCA_ScalosControl(NULL, + SCALOSCTRLA_SetDeleteHook, ti->ti_Data, + TAG_END); + } + else + Success = FALSE; + break; + + case WBCTRLA_GetTextInputHook: + d1(kprintf("%s/%s/%ld: WBCTRLA_GetTextInputHook\n", __FILE__, __FUNC__, __LINE__)); + if (ScalosBase->scb_LibNode.lib_Version >= 40) + { + SCA_ScalosControl(NULL, + SCALOSCTRLA_GetTextInputHook, ti->ti_Data, + TAG_END); + } + else + Success = FALSE; + break; + + case WBCTRLA_SetTextInputHook: + d1(kprintf("%s/%s/%ld: WBCTRLA_SetTextInputHook Hook=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + if (ScalosBase->scb_LibNode.lib_Version >= 40) + { + SCA_ScalosControl(NULL, + SCALOSCTRLA_SetTextInputHook, ti->ti_Data, + TAG_END); + } + else + Success = FALSE; + break; + + case WBCTRLA_AddSetupCleanupHook: // Add hook to CloseWB list + d1(kprintf("%s/%s/%ld: WBCTRLA_AddCloseWBHook Hook=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + if (ScalosBase->scb_LibNode.lib_Version >= 40) + { + SCA_ScalosControl(NULL, + SCALOSCTRLA_AddCloseWBHook, ti->ti_Data, + TAG_END); + } + else + Success = FALSE; + break; + + case WBCTRLA_RemSetupCleanupHook: // Remove hook from CloseWB list + d1(kprintf("%s/%s/%ld: WBCTRLA_RemCloseWBHook Hook=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Data)); + if (ScalosBase->scb_LibNode.lib_Version >= 40) + { + SCA_ScalosControl(NULL, + SCALOSCTRLA_RemCloseWBHook, ti->ti_Data, + TAG_END); + } + else + Success = FALSE; + break; + + default: + d1(kprintf("%s/%s/%ld: Tag=%08lx (WBA_Dummy+%ld): Data=%lu (0x%08lx)\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Tag, ti->ti_Tag-WBA_Dummy, ti->ti_Data, ti->ti_Data)); + Success = FALSE; + break; + } + } + + if (RETURN_OK != ErrorCode) + { + SetIoErr(ErrorCode); + Success = FALSE; + } +#if 0 + APTR ptr; + + kprintf("%s/%s/%ld: name=<%s>\n", __FILE__, __FUNC__, __LINE__, \ + name ? name : (STRPTR) ""); + + Success = origWorkbenchControlA(name, tags); + + while (ti = NextTagItem(&taglist)) + { + kprintf("%s/%s/%ld: Tag=%08lx : Data=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + ti->ti_Tag, ti->ti_Data); + } +#endif + + return Success; +} +LIBFUNC_END + + +static struct List *AllocList(void) +{ + struct List *pl = malloc(sizeof(struct List)); + + if (pl) + { + pl->lh_Type = 0; + + NewList(pl); + } + + return pl; +} + + +static void FreeList(struct List *pl) +{ + struct Node *xNode; + + if (NULL == pl) + return; + + while (xNode = RemHead(pl)) + { + if (xNode->ln_Name) + { + free(xNode->ln_Name); + xNode->ln_Name = NULL; + } + free(xNode); + } + + free(pl); +} + + +static BPTR DupWBPathList(void) +{ + struct Process *wbProc = (struct Process *) FindTask("Workbench"); + struct CommandLineInterface *cli; + struct AssignList *aList, *StartList = NULL, **nList = NULL; + + d1(KPrintF("%s/%s/%ld: START wbProc=%08lx\n", __FILE__, __FUNC__, __LINE__, wbProc)); + if (NULL == wbProc) + wbProc = (struct Process *) FindTask("Scalos_Window_Task_Main"); + d1(KPrintF("%s/%s/%ld: wbProc=%08lx\n", __FILE__, __FUNC__, __LINE__, wbProc)); + if (NULL == wbProc) + return (BPTR)NULL; + if (NT_PROCESS != wbProc->pr_Task.tc_Node.ln_Type) + return (BPTR)NULL; + + cli = BADDR(wbProc->pr_CLI); + d1(KPrintF("%s/%s/%ld: cli=%08lx\n", __FILE__, __FUNC__, __LINE__, cli)); + if (NULL == cli) + return (BPTR)NULL; + + aList = BADDR(cli->cli_CommandDir); + d1(KPrintF("%s/%s/%ld: aList=%08lx\n", __FILE__, __FUNC__, __LINE__, aList)); + if (NULL == aList) + return (BPTR)NULL; + + while (aList) + { + struct AssignList *nNode = AllocVec(sizeof(struct AssignList), MEMF_PUBLIC); + + if (NULL == nNode) + break; + if (NULL == nList) + StartList = nNode; + else + *nList = (struct AssignList *) MKBADDR(nNode); + + nNode->al_Next = NULL; + nNode->al_Lock = DupLock(aList->al_Lock); + nList = &nNode->al_Next; + + d1(KPrintF("%s/%s/%ld: aList=%08lx Next=%08lx Lock=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + aList, aList->al_Next, aList->al_Lock)); + debugLock_d1(aList->al_Lock); + + aList = BADDR(aList->al_Next); + } + + d1(KPrintF("%s/%s/%ld: END StartList=%08lx\n", __FILE__, __FUNC__, __LINE__, StartList)); + + return MKBADDR(StartList); +} + + +static void FreePathList(BPTR bList) +{ + struct AssignList *aList; + + aList = BADDR(bList); + while (aList) + { + struct AssignList *NextList = BADDR(aList->al_Next); + + d1(kprintf("%s/%s/%ld: aList=%08lx Next=%08lx Lock=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + aList, NextList, aList->al_Lock)); + + UnLock(aList->al_Lock); + FreeVec(aList); + + aList = NextList; + } +} + + +static struct List *GetOpenDrawerList(void) +{ + struct ScaWindowList *swList = SCA_LockWindowList(SCA_LockWindowList_AttemptShared); + struct List *odList = AllocList(); + + if (swList) + { + struct ScaWindowStruct *swi; + + for (swi=swList->wl_WindowStruct; swi; swi = (struct ScaWindowStruct *) swi->ws_Node.mln_Succ) + { + d1(kprintf("%s/%s/%ld: swi=%08lx Lock=%08lx Flags=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + swi, swi->ws_Lock, swi->ws_Flags)); + + if (swi->ws_Lock) + { + char Buffer[255]; + + if (NameFromLock(swi->ws_Lock, Buffer, sizeof(Buffer))) + { + struct Node *newNode = calloc(1, sizeof(struct Node)); + + if (newNode) + { + newNode->ln_Type = 0; + newNode->ln_Name = strdup(Buffer); + + AddTail(odList, newNode); + } + } + } + } + + SCA_UnLockWindowList(); + } + + return odList; +} + + +static BOOL IsOpen(const char *Name) +{ + BOOL Found = FALSE; + struct ScaWindowList *swList = NULL; + BPTR nLock = (BPTR)NULL; + + do { + struct ScaWindowStruct *swi; + + if (NULL == Name) + break; + + swList = SCA_LockWindowList(SCA_LockWindowList_AttemptShared); + if (NULL == swList) + break; + + nLock = Lock((STRPTR) Name, ACCESS_READ); + if ((BPTR)NULL == nLock) + break; + + for (swi=swList->wl_WindowStruct; !Found && swi; swi = (struct ScaWindowStruct *) swi->ws_Node.mln_Succ) + { + d1(kprintf("%s/%s/%ld: swi=%08lx Lock=%08lx nLock=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + swi, swi->ws_Lock, nLock)); + + if (LOCK_SAME == SameLock(swi->ws_Lock, nLock)) + { + Found = TRUE; + } + } + } while (0); + + if (swList) + SCA_UnLockWindowList(); + if (nLock) + UnLock(nLock); + + d1(kprintf("%s/%s/%ld: Found=%ld\n", __FILE__, __FUNC__, __LINE__, Found)); + + return Found; +} + + +static BOOL RedrawAppIcon(struct ScaAppObjNode *ai) +{ + struct ScaWindowList *swList; + struct ScaWindowStruct *RootWindow = NULL; + BOOL Result = FALSE; + + d1(kprintf("%s/%s/%ld: AppIcon=%08lx\n", __FILE__, __FUNC__, __LINE__, + ai)); + + d1(kprintf("%s/%s/%ld: RootList=%08lx InternInfos=%08lx\n", __FILE__, __FUNC__, __LINE__, + rList, rList->rl_internInfos)); + + if (NULL == ai) + return FALSE; + + swList = SCA_LockWindowList(SCA_LockWindowList_AttemptShared); + if (swList) + { + struct ScaWindowStruct *swi; + + for (swi=swList->wl_WindowStruct; !RootWindow && swi; swi = (struct ScaWindowStruct *) swi->ws_Node.mln_Succ) + { + if ((BPTR)NULL == swi->ws_Lock) + RootWindow = swi; + } + + d1(kprintf("%s/%s/%ld: RootWindow=%08lx\n", __FILE__, __FUNC__, __LINE__, + RootWindow)); + + if (RootWindow) + { + struct ScaWindowTask *rwt = RootWindow->ws_WindowTask; + + if (AttemptSemaphoreShared(rwt->wt_IconSemaphore)) + { + struct ScaIconNode *in; + + for (in = rwt->wt_IconList; in; in = (struct ScaIconNode *) in->in_Node.mln_Succ) + { + if (in->in_Icon == (Object *) ai->an_object) + { + DoMethod(rwt->mt_MainObject, + SCCM_IconWin_DrawIcon, ai->an_object); + break; + } + } + + ReleaseSemaphore(rwt->wt_IconSemaphore); + } + + Result = TRUE; + } + + SCA_UnLockWindowList(); + } + + return Result; +} + + +static struct List *GetSelectedIconList(void) +{ + struct ScaWindowList *swList = SCA_LockWindowList(SCA_LockWindowList_AttemptShared); + struct List *odList = AllocList(); + + if (swList) + { + struct ScaWindowStruct *swi; + + for (swi=swList->wl_WindowStruct; swi; swi = (struct ScaWindowStruct *) swi->ws_Node.mln_Succ) + { + struct ScaWindowTask *wt = swi->ws_WindowTask; + + d1(kprintf("%s/%s/%ld: ScaWindowStruct=%08lx ScaWindowTask=%08lx\n", __FILE__, __FUNC__, __LINE__, + swi, wt)); + + if (wt) + { + struct ScaIconNode *icon; + char wBuffer[256]; + + if (swi->ws_Lock) + NameFromLock(swi->ws_Lock, wBuffer, sizeof(wBuffer)); + + ObtainSemaphore(wt->wt_IconSemaphore); + + for (icon=wt->wt_IconList; icon; icon = (struct ScaIconNode *) icon->in_Node.mln_Succ) + { + char *Name = icon->in_Name; + + if (NULL == Name) + GetAttr(IDTA_Text, icon->in_Icon, (APTR) &Name); + + if (Name && isIconSelected(icon)) + { + struct Node *newNode; + char Buffer[255]; + + d1(kprintf("%s/%s/%ld: icon=%08lx Lock=%08lx Name=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + icon, icon->in_Lock, Name)); + + if (icon->in_Lock) + { + if (NameFromLock(icon->in_Lock, Buffer, sizeof(Buffer))) + { + AddPart(Buffer, Name, sizeof(Buffer)); + } + } + else + { + stccpy(Buffer, wBuffer, sizeof(Buffer)); + AddPart(Buffer, Name, sizeof(Buffer)); + } + + newNode = calloc(1, sizeof(struct Node)); + if (newNode) + { + newNode->ln_Type = NT_WB; + newNode->ln_Name = strdup(Buffer); + + AddTail(odList, newNode); + } + } + } + + ReleaseSemaphore(wt->wt_IconSemaphore); + } + } + + SCA_UnLockWindowList(); + } + + return odList; +} + + +// +dm+ 20010518 Full support for hidden device lists in workbench +static struct List *GetHiddenDeviceList(void) +{ + struct List *newdevlist; + struct Node *hiddennode, *newdevnode; + + newdevlist = AllocList(); + d1(kprintf("%s/%s/%ld: newdevlist=%08lx\n", __FILE__, __FUNC__, __LINE__, + newdevlist)); + if(newdevlist) + { + ObtainSemaphoreShared(&HiddenDevListSema); + + hiddennode = HiddenDeviceList.lh_Head; + while(hiddennode->ln_Succ) + { + if(hiddennode->ln_Name) + { + d1(kprintf("%s/%s/%ld: hiddennode=%08lx name=<%s>\n", __FILE__, __FUNC__, __LINE__, + hiddennode, hiddennode->ln_Name)); + newdevnode = calloc(1, sizeof(struct Node)); + if(newdevnode) + { + newdevnode->ln_Type = NT_WB; // +jl+ 20010524 + newdevnode->ln_Name = calloc(strlen(hiddennode->ln_Name)+1, sizeof(char)); + if(newdevnode->ln_Name) + { + strcpy(newdevnode->ln_Name, hiddennode->ln_Name); + AddTail(newdevlist, newdevnode); + d1(kprintf("%s/%s/%ld: newdevnode=%08lx name=<%s>\n", __FILE__, __FUNC__, __LINE__, + newdevnode, newdevnode->ln_Name)); + } + else + { + free(newdevnode); + } // if(newdevnode->ln_Name) + } // if(newdevnode) + } // if(hiddennode->ln_Name) + hiddennode = hiddennode->ln_Succ; + } // while(hiddennode->ln_Succ) + + ReleaseSemaphore(&HiddenDevListSema); + } + return(newdevlist); +} + + +static void AddHiddenDevice(STRPTR devname, enum HiddenDevArg Quiet) +{ + struct Node *hiddennode; + int devlen = strlen(devname); + BOOL notfound = TRUE; + + if(devname) + { + ObtainSemaphore(&HiddenDevListSema); + + if(devname[devlen-1] == ':') + { + hiddennode = HiddenDeviceList.lh_Head; + while(hiddennode->ln_Succ && notfound) + { + if(hiddennode->ln_Name) + { + d1(kprintf("%s/%s/%ld: hiddennode=%08lx name=<%s> addname=<%s>\n", __FILE__, __FUNC__, __LINE__, + hiddennode, hiddennode->ln_Name, devname)); + notfound = Stricmp(hiddennode->ln_Name, devname); + } + hiddennode = hiddennode->ln_Succ; + } + + if(notfound) + { + // Allocate new node + hiddennode = calloc(1, sizeof(struct Node)); + if(hiddennode) + { + hiddennode->ln_Type = NT_WB; + hiddennode->ln_Name = calloc(devlen+1, sizeof(char)); + if(hiddennode->ln_Name) + { + strcpy(hiddennode->ln_Name, devname); + AddTail(&HiddenDeviceList, hiddennode); + d1(kprintf("%s/%s/%ld: newnode=%08lx newname=<%s>\n", __FILE__, __FUNC__, __LINE__, + hiddennode, hiddennode->ln_Name)); + } + else + { + free(hiddennode); + } + } // if(hiddennode) allocated + } // if device name not found + } // if proper device name + ReleaseSemaphore(&HiddenDevListSema); + + if ((HIDDENDEV_Verbose == Quiet) && notfound && rList && rList->rl_internInfos->ii_MainWindowStruct) + UpdateScalosWindow(rList->rl_internInfos->ii_MainWindowStruct); + } // if devname valid +} + + +static void RemoveHiddenDevice(STRPTR devname, enum HiddenDevArg Quiet) +{ + struct Node *hiddennode, *xNode = NULL; + int devlen = strlen(devname); + + if(devname) + { + ObtainSemaphore(&HiddenDevListSema); + + if(devname[devlen-1] == ':') + { + hiddennode = HiddenDeviceList.lh_Head; + while(hiddennode->ln_Succ && !xNode) + { + if(hiddennode->ln_Name) + { + d1(kprintf("%s/%s/%ld: hiddennode=%08lx name=<%s> remname=<%s>\n", __FILE__, __FUNC__, __LINE__, + hiddennode, hiddennode->ln_Name, devname)); + if(Stricmp(hiddennode->ln_Name, devname) == 0) + xNode = hiddennode; + } + hiddennode = hiddennode->ln_Succ; + } + + if(xNode) + { + d1(kprintf("%s/%s/%ld: remnode=%08lx nodename=<%s> remname=<%s>\n", __FILE__, __FUNC__, __LINE__, + xNode, xNode->ln_Name, devname)); + Remove(xNode); + if(xNode->ln_Name) free(xNode->ln_Name); + free(xNode); + } // if device name not found + } // if proper device name + + ReleaseSemaphore(&HiddenDevListSema); + + if ((HIDDENDEV_Verbose == Quiet) && xNode && rList && rList->rl_internInfos->ii_MainWindowStruct) + UpdateScalosWindow(rList->rl_internInfos->ii_MainWindowStruct); + } // if devname valid +} +// +dm+ 20010518 end + + +#ifdef __amigaos4__ +LIBFUNC_P2VA(BOOL, myWorkbenchControl, + A0, STRPTR, name, + A6, struct Library *, WorkbenchBase) +{ + BOOL ret; + struct WorkbenchIFace *IWorkbench = (struct WorkbenchIFace *)self; + va_list args; + va_startlinear(args, name); + + (void)WorkbenchBase; + + ret = WorkbenchControlA(name, va_getlinearva(args, const struct TagItem *)); + + va_end(args); + + return(ret); +} +LIBFUNC_END +#endif + +#if !defined(__SASC) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) +// Replacement for SAS/C library functions + +static size_t stccpy(char *dest, const char *src, size_t MaxLen) +{ + size_t Count = 0; + + while (*src && MaxLen > 1) + { + *dest++ = *src++; + MaxLen--; + Count++; + } + *dest = '\0'; + Count++; + + return Count; +} +#endif /* !defined(__SASC) && !defined(__MORPHOS__) && !defined(__amigaos4__) */ diff --git a/scalos/Plugins/OOP/wb39_plugin/config.mk b/scalos/Plugins/OOP/wb39_plugin/config.mk new file mode 100755 index 000000000..57139ebd8 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/config.mk @@ -0,0 +1,78 @@ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +COMMON_DIR = $(TOPLEVEL)/common/Plugin + +INCLUDES += -I$(COMMON_DIR) + +vpath %.c $(COMMON_DIR) + +############################################################################## + +include $(COMMON_DIR)/config.mk + +############################################################################## + +INCLUDES += -I. -Ivolumegauge -Iwbrexx + +vpath %.c volumegauge + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += -lmempools +# --verbose + +LFLAGS2 = $(LFLAGS) \ + -nostartfiles + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS2 = $(LFLAGS) \ + -nostartfiles \ +# + +#INCLUDES += -I/Werk/Programming/WBStart/dev/OS4/include -I/Werk/Programming/WBStart/dev/c/include + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +LFLAGS2 = $(LFLAGS) \ + -nostartfiles \ +# + +else + +############################################################################### +# AmigaOS + +LFLAGS += -lscalos \ + -lpreferences \ + -liconobject \ + -lmempools \ + -lstack \ + -lnix \ + -lnixmain \ + -lamiga21 \ + -lamiga \ + -lstubs \ + +endif +endif +endif diff --git a/scalos/Plugins/OOP/wb39_plugin/deficons_library.c b/scalos/Plugins/OOP/wb39_plugin/deficons_library.c new file mode 100644 index 000000000..9ea269c3d --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/deficons_library.c @@ -0,0 +1,194 @@ +// deficons_library.c +// 13 Nov 2004 17:23:19 + + +#include +#include +#include + +#include +#include + +#include + +#include + +#include + +#include +#include "deficons.h" + +//---------------------------------------------------------------------------- + +struct DefIconsLibraryBase + { + struct Library deficons_LibNode; + ULONG deficons_PlugID; + struct SegList *deficons_SegList; + }; + +//---------------------------------------------------------------------------- + +static SAVEDS(struct Library *) ASM INTERRUPT Initlib(REG(d0, struct Library *libbase), + REG(a0, struct SegList *seglist), REG(a6, struct ExecBase *sysbase)); +static SAVEDS(struct Library *) INTERRUPT ASM Openlib(REG(a6, struct Library *libbase)); +static SAVEDS(struct SegList *) ASM INTERRUPT Closelib(REG(a6, struct Library *libbase)); +static SAVEDS(struct SegList *) ASM INTERRUPT Expungelib(REG(a6, struct Library *libbase)); +static SAVEDS(ULONG) ASM INTERRUPT Extfunclib(REG(a6, struct Library *libbase)); +static SAVEDS(struct ScaClassInfo *) ASM INTERRUPT GetClassInfo(REG(a6, struct Library *libbase)); + +//---------------------------------------------------------------------------- + +SAVEDS(LONG) ASM Libstart(void) +{ + return -1; +} + +//---------------------------------------------------------------------------- + +#define LIB_VERSION 45 +#define LIB_REVISION 6 + +static char __aligned libName[] = "deficons.plugin"; +static char __aligned libIdString[] = "$VER: deficons.plugin 45.6 (30 Dec 2001 16:12:22)"; + +//---------------------------------------------------------------------------- + +/* OS3.x Library */ + +static APTR functable[] = + { + Openlib, + Closelib, + Expungelib, + Extfunclib, + GetClassInfo, + (APTR) -1 + }; + +/* Init table used in library initialization. */ +static ULONG inittab[] = + { + sizeof(struct DefIconsLibraryBase), + (ULONG) functable, + 0, + (ULONG) Initlib + }; + + +/* The ROM tag */ +struct Resident __aligned romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, + RTF_AUTOINIT, + LIB_VERSION, + NT_LIBRARY, + 0, + libName, + libIdString, + inittab + }; + +//---------------------------------------------------------------------------- + +static SAVEDS(struct Library *) ASM INTERRUPT Initlib(REG(d0, struct Library *libbase), + REG(a0, struct SegList *seglist), REG(a6, struct ExecBase *sysbase)) +{ + struct DefIconsLibraryBase *DefIconsLibBase = (struct DefIconsLibraryBase *) libbase; + + DefIconsLibBase->deficons_LibNode.lib_Revision = LIB_REVISION; + DefIconsLibBase->deficons_SegList = seglist; + + DefIconsLibBase->deficons_PlugID = MAKE_ID('P','L','U','G'); + + return &DefIconsLibBase->deficons_LibNode; +} + + +static SAVEDS(struct Library *) INTERRUPT ASM Openlib(REG(a6, struct Library *libbase)) +{ + struct DefIconsLibraryBase *DefIconsLibBase = (struct DefIconsLibraryBase *) libbase; + + DefIconsLibBase->deficons_LibNode.lib_OpenCnt++; + DefIconsLibBase->deficons_LibNode.lib_Flags &= ~LIBF_DELEXP; + + if (!initDefIcons()) + { + Closelib(&DefIconsLibBase->deficons_LibNode); + return NULL; + } + + return &DefIconsLibBase->deficons_LibNode; +} + + +static SAVEDS(struct SegList *) ASM INTERRUPT Closelib(REG(a6, struct Library *libbase)) +{ + struct DefIconsLibraryBase *DefIconsLibBase = (struct DefIconsLibraryBase *) libbase; + + DefIconsLibBase->deficons_LibNode.lib_OpenCnt--; + + if (0 == DefIconsLibBase->deficons_LibNode.lib_OpenCnt) + { + if (DefIconsLibBase->deficons_LibNode.lib_Flags & LIBF_DELEXP) + { + return Expungelib(&DefIconsLibBase->deficons_LibNode); + } + } + + return NULL; +} + + +static SAVEDS(struct SegList *) ASM INTERRUPT Expungelib(REG(a6, struct Library *libbase)) +{ + struct DefIconsLibraryBase *DefIconsLibBase = (struct DefIconsLibraryBase *) libbase; + + if (0 == DefIconsLibBase->deficons_LibNode.lib_OpenCnt) + { + ULONG size = DefIconsLibBase->deficons_LibNode.lib_NegSize + DefIconsLibBase->deficons_LibNode.lib_PosSize; + UBYTE *ptr = (UBYTE *) DefIconsLibBase - DefIconsLibBase->deficons_LibNode.lib_NegSize; + struct SegList *libseglist = DefIconsLibBase->deficons_SegList; + + Remove((struct Node *) DefIconsLibBase); + cleanupDefIcons(); + FreeMem(ptr,size); + + return libseglist; + } + + DefIconsLibBase->deficons_LibNode.lib_Flags |= LIBF_DELEXP; + + return NULL; +} + + +static SAVEDS(ULONG) ASM INTERRUPT Extfunclib(REG(a6, struct Library *libbase)) +{ + return 0; +} + + +static SAVEDS(struct ScaClassInfo *) ASM INTERRUPT GetClassInfo(REG(a6, struct Library *libbase)) +{ + static struct ScaClassInfo LibClassInfo = + { + { NULL, NULL, DefIconsHookFunc, NULL, NULL }, + + -79, // Priority (just after IconWindow.sca !!!) + 2 * 4, // Instance Size + 41, + 0, + "IconWindow.sca", + "IconWindow.sca", + "Scalos DefIcons Class", + "This class gives files lacking an icon a filetype dependent icon" COMPILER_STRING, + "Jürgen Lachmann", + }; + + return &LibClassInfo; +} + +//---------------------------------------------------------------------------- diff --git a/scalos/Plugins/OOP/wb39_plugin/deficons_plugin.asm b/scalos/Plugins/OOP/wb39_plugin/deficons_plugin.asm new file mode 100644 index 000000000..c1755df12 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/deficons_plugin.asm @@ -0,0 +1,198 @@ +; DefIcons_Plugin.asm +; 30 Dec 2001 16:12:14 + + incdir System:sc/Assembler_Headers + + include exec/types.i + include exec/nodes.i + include exec/ports.i + include exec/libraries.i + include exec/initializers.i + include exec/resident.i + include dos/dos.i + include utility/hooks.i + include scalos/scalos.i + +;---------------------------------------------------------------------------- + + xref _LVORemove + xref _LVOFreeMem + + xref _myHookFunc + xref _DefIconsInit + xref _DefIconsCleanup + +;---------------------------------------------------------------------------- + + STRUCTURE DefIconsLib,LIB_SIZE + ULONG PL_PlugID + LABEL DefIcons_SIZE + +;---------------------------------------------------------------------------- + +Startlib: + moveq #0,d0 + rts + +;---------------------------------------------------------------------------- + +RomTag: + dc.w RTC_MATCHWORD ;RT_MATCHWORD + dc.l RomTag ;RT_MATCHTAG + dc.l endep ;RT_ENDSKIP + dc.b RTF_AUTOINIT ;RT_FLAGS + dc.b 45 ;RT_VERSION + dc.b NT_LIBRARY ;RT_TYPE + dc.b 0 ;RT_PRI + dc.l libname ;RT_NAME + dc.l idstring ;RT_IDSTRING + dc.l init ;RT_INIT + +;---------------------------------------------------------------------------- + +libname: + dc.b 'deficons.plugin',0 + even +idstring: + dc.b '$VER: deficons.plugin 45.6 (30 Dec 2001 16:12:22)',0 + +;---------------------------------------------------------------------------- + cnop 0,4 +init: + dc.l DefIcons_SIZE ;BaseSize + dc.l functable + dc.l datatable + dc.l InitRoutine + +;---------------------------------------------------------------------------- +functable: + dc.l Open + dc.l Close + dc.l Expunge + dc.l Startlib + dc.l getclassinfo + + dc.l -1 + +;---------------------------------------------------------------------------- +datatable: + INITBYTE LN_TYPE,NT_LIBRARY + INITLONG LN_NAME,libname + INITBYTE LIB_FLAGS,LIBF_SUMUSED!LIBF_CHANGED + INITWORD LIB_VERSION,45 + INITWORD LIB_REVISION,6 + INITLONG LIB_IDSTRING,idstring + dc.l 0 + + cnop 0,4 +;---------------------------------------------------------------------------- + +InitRoutine: + movem.l d0-a6,-(sp) + + move.l a0,seglist + + move.l d0,a0 + move.l #'PLUG',PL_PlugID(a0) ;Store identifier for plugins into LibBase + + movem.l (sp)+,d0-a6 + rts +.openerror: + movem.l (sp)+,d0-a6 + moveq #0,d0 + rts + +;---------------------------------------------------------------------------- + +Open: ; ( libptr:a6, version:d0 ) + addq.w #1,(LIB_OPENCNT,a6) + bclr #LIBB_DELEXP,(LIB_FLAGS,a6) + + jsr _DefIconsInit + tst.l d0 ; Success ?? + beq .openerror + + move.l a6,d0 + rts + +.openerror: + sub.w #1,(LIB_OPENCNT,a6) + moveq #0,d0 + rts +;---------------------------------------------------------------------------- + +Close: ; ( libptr:a6 ) + subq.w #1,(LIB_OPENCNT,a6) + bne.s .nooneopen + btst #LIBB_DELEXP,(LIB_FLAGS,a6) + beq.s .nooneopen + bsr.s Expunge +.nooneopen: + moveq #0,d0 + rts + +;---------------------------------------------------------------------------- + +Expunge: ; ( libptr: a6 ) + tst.w (LIB_OPENCNT,a6) + beq.s .nooneopen2 + bset #LIBB_DELEXP,(LIB_FLAGS,a6) + moveq #0,d0 + rts + +.nooneopen2: + jsr _DefIconsCleanup + + movem.l d2/a4/a5/a6,-(sp) + move.l seglist(pc),d2 + move.l a6,a4 + move.l 4.w,a6 + move.l a4,a1 + jsr -252(a6) ;Remove + moveq #0,d0 + move.l a4,a1 + move.w (LIB_NEGSIZE,a4),d0 + sub.w d0,a1 + add.w (LIB_POSSIZE,a4),d0 + jsr -210(a6) ;FreeMem + + move.l d2,d0 + movem.l (sp)+,d2/a4/a5/a6 + rts + +;----------------------------- GetClass Info -------------------------------- + +;Input: none +;Output: ScaClassInfo +getclassinfo: + lea classinfo(pc),a0 +; move.w #2*4,ci_instsize(a0) + move.l a0,d0 + rts + +classinfo: + dc.l 0,0 + dc.l _myHookFunc + dc.l 0,0 + dc.w -79 ;Priority (just after IconWindow.sca !!!) + dc.w 2*4 ;Instance Size + dc.w 39 ;Needed Scalos Version + dc.w 0 ;Reserved + dc.l superclassname ;Name of the Class + dc.l superclassname ;Name of the SuperClass + dc.l name + dc.l description + dc.l makername + +classname: dc.b 'DefIcons.sca',0 +superclassname: dc.b 'IconWindow.sca',0 +name: dc.b 'Scalos DefIcons Class',0 +description: dc.b 'This class gives files lacking an icon a filetype dependent icon',0 +makername: dc.b 'Jürgen Lachmann',0 + even + +;---------------------------------------------------------------------------- + +seglist: dc.l 0 +endep: + diff --git a/scalos/Plugins/OOP/wb39_plugin/makefile b/scalos/Plugins/OOP/wb39_plugin/makefile new file mode 100644 index 000000000..07990a455 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/makefile @@ -0,0 +1,166 @@ +# makefile for several Scalos plugins +# $Date$ +# using GNU make and SAS/C 6.58 + + +############################################################# + +SUBDIRMAKE = $(MAKE) -s -C +CC = sc +AS = phxass +PRECOMP = INCLUDE:All.gst +LD = slink +LDFLAGS = quiet batch noicons sd +LDLIBS = LIB:sc.lib LIB:debug.lib LIB:amiga.lib +OBJDIR = .sasobj +DESTPLUG = Scalos:Plugins/OOP +COMMON_DIR = ../../../common/Plugin + +.SUFFIXES: .plugin .plugin.debug + +############################################################# + +SUBDIRS = persist \ + volumegauge \ + wbrexx \ + +############################################################# + +# Optimizer Flags +# Ignore Note 306: local function inlined: "InsertMH" +OPT_FLG = OPTIMIZE OPTINLOCAL OPTTIME OPTSCHED IGNORE=306,308 ERROR=87 +OPT_FLG2 = NOOPTIMIZE IGNORE=306,308 ERROR=87 + +ifdef DEBUG + CFLAGS = nostkchk nochkabort dbg=ff nover gst=$(PRECOMP) idlen=64 \ + idir=///include \ + idir=volumegauge \ + idir=$(subst ../,/,$(DATATYPESMCC_DIR)) + + CFLAGS2 = nostkchk nochkabort dbg=ff nover gst=$(PRECOMP) idlen=64 \ + idir=///include \ + idir=volumegauge \ + idir=$(subst ../,/,$(DATATYPESMCC_DIR)) + CSTARTUP = LIB:c.o +else + CFLAGS = nostkchk nochkabort $(OPT_FLG) dbg=f def=NDEBUG \ + def=NODEBUG nover gst=$(PRECOMP) idlen=64 \ + idir=///include \ + idir=volumegauge \ + idir=$(subst ../,/,$(DATATYPESMCC_DIR)) + CFLAGS2 = nostkchk nochkabort $(OPT_FLG2) dbg=f def=NDEBUG \ + def=NODEBUG nover gst=$(PRECOMP) idlen=64 \ + idir=///include \ + idir=volumegauge \ + idir=$(subst ../,/,$(DATATYPESMCC_DIR)) + CSTARTUP = LIB:cback.o +endif + +AFLAGS = quiet I=sc:Assembler_Headers + +############################################################# + +# Files for wb39.plugin +WB39NAME = wb39.plugin + +WB39CSRCS = $(COMMON_DIR)/plugin-classic.c \ + wb39.c \ + AppWindow.c \ + WorkbenchControl.c \ + volumegauge/VolumeGauge.c \ + AppIcons.c \ + Scalos_Helper.c \ + +XSRCS = $(notdir $(WB39CSRCS)) +WB39OBJS= $(XSRCS:%.c=$(OBJDIR)/$(notdir %).o) + +############################################################# + +LIBS = LIB:mempools.lib LIB:sc.lib LIB:debug.lib LIB:amiga.lib + +############################################################# + +all: $(WB39NAME) \ + $(WB39NAME).debug \ + allsubdirs \ + test +# install +# clean +# $(DEFICONSNAME) $(DEFICONSNAME).debug + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +############################################################# + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-classic.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/VolumeGauge.o : volumegauge/VolumeGauge.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $*.c objectname $@ + +$(OBJDIR)/wb39.o : wb39.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS2) $< objectname $@ + +############################################################# + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-classic.c \ + $(COMMON_DIR)/plugin-common.c $(COMMON_DIR)/plugin.h plugin_data.h + +$(OBJDIR)/wb39.o AppWindow.o WorkbenchControl.o VolumeGauge.o \ + AppIcons.o Scalos_Helper.o : wb39.h + +$(OBJDIR)/wb39.o VolumeGauge.o vg_plugin.o : volumegauge/VolumeGauge.h + +############################################################# + +$(WB39NAME): $(WB39OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(WB39OBJS) TO $(WB39NAME) lib $(LIBS) $(LDFLAGS) STRIPDEBUG + +$(WB39NAME).debug: $(WB39OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(WB39OBJS) TO $(WB39NAME).debug lib $(LIBS) $(LDFLAGS) ADDSYM + +############################################################# + +test: $(OBJDIR)/test.o + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM LIB:c.o $(OBJDIR)/test.o TO $@ LIB $(LIBS) $(LDFLAGS) $(DBFLAG) + +############################################################# + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(WB39NAME).\033[0m\n' + @copy $(WB39NAME) $(DESTPLUG) clone + -@$(foreach cat,$(SUBDIRS),$(SUBDIRMAKE) $(cat) install;) + +############################################################# + +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + -@delete $(WB39OBJS) \ + $(OBJDIR)/test.o \ + test \ + $(WB39NAME) \ + $(WB39NAME).debug + @printf '\033[0m' + -@$(foreach cat,$(SUBDIRS),$(SUBDIRMAKE) $(cat) clean;) + +############################################################# + +# make all subdirectories +allsubdirs: + -@$(foreach cat,$(SUBDIRS),$(SUBDIRMAKE) $(cat);) + +############################################################# + diff --git a/scalos/Plugins/OOP/wb39_plugin/makefile-new b/scalos/Plugins/OOP/wb39_plugin/makefile-new new file mode 100755 index 000000000..1cbba1a6d --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/makefile-new @@ -0,0 +1,98 @@ +# $Date: 2011-08-02 00:13:23 +0200 (Di, 02. Aug 2011) $ +# $Revision: 816 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS_NAME = $(BEGIN_OBJS) \ + $(OBJDIR)/wb39.o \ + $(OBJDIR)/AppWindow.o \ + $(OBJDIR)/WorkbenchControl.o \ + $(OBJDIR)/VolumeGauge.o \ + $(OBJDIR)/AppIcons.o \ + $(OBJDIR)/Scalos_Helper.o \ + $(END_OBJS) + +OBJS_TEST = $(OBJDIR)/test.o + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS_NAME:.o=.d) + -include $(OBJS_TEST:.o=.d) +endif + +############################################################################## +# +# Targets +# + +NAME = wb39.plugin +TEST = test +NAME_DB = $(NAME).debug +TEST_DB = $(TEST).debug + +############################################################################## +# +# Subdirs +# + +SUBDIRS = persist \ + wbrexx \ + volumegauge \ + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) \ + $(BINDIR)/$(TEST) \ + all_subdirs \ + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS_NAME) + $(ECHO) "Link $(NAME)" + @$(CC) $(OBJS_NAME) $(LFLAGS2) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +$(BINDIR)/$(TEST) $(BINDIR)/$(TEST_DB) : $(OBJS_TEST) + @$(ECHO) "Link $(TEST)" + @$(CC) $(STARTUP) $(OBJS_TEST) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(TEST_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(TEST_DB) -o $(BINDIR)/$(TEST) + @chmod u+x $@ + +############################################################################## + +install: install_subdirs + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) Scalos:Plugins/OOP clone + + +clean: clean_subdirs + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + $(BINDIR)/$(TEST) $(BINDIR)/$(TEST_DB) \ + *.dump *_str.* + +nodebug: nodebug_subdirs + +############################################################################## + + diff --git a/scalos/Plugins/OOP/wb39_plugin/persist/Persist.h b/scalos/Plugins/OOP/wb39_plugin/persist/Persist.h new file mode 100644 index 000000000..dba34d7f5 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/persist/Persist.h @@ -0,0 +1,54 @@ +// persist.h +// $Date$ +// $Revision$ + + +#ifndef PERSIST_H_INCLUDED +#define PERSIST_H_INCLUDED + +//---------------------------------------------------------------------------- + +#define d(x) ; +#define d1(x) ; +#define d2(x) x; + +// aus debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +//---------------------------------------------------------------------------- + +#include +#include +#include + +#define PERSIST_CONFIGFILENAME "ENV:Scalos/Persist.prefs" +#define PERSIST_FILENAME "ENVARC:Scalos/Persistant_Windows" +#define TEMP_FILENAME "t:PersistTemp" + +//---------------------------------------------------------------------------- + +struct OpenNode + { + struct Node on_Node; + BOOL on_Iconified; + BOOL on_BrowserMode; + const struct ScaWindowTask *on_WindowTask; + char *on_Path; + WORD on_Left; // Window LeftEdge + WORD on_Top; // Window TopEdge + WORD on_Width; // Window Width + WORD on_Height; // Window Height + }; + +struct ProcessTimerInfo + { + struct MsgPort *ppt_ioPort; + T_TIMEREQUEST *ppt_TimeReq; + BOOL ppt_timerOpen; + BOOL ppt_timerPending; // TRUE when spt_TimeReq is in use + }; + +//---------------------------------------------------------------------------- + +#endif /* PERSIST_H_INCLUDED */ diff --git a/scalos/Plugins/OOP/wb39_plugin/persist/config.mk b/scalos/Plugins/OOP/wb39_plugin/persist/config.mk new file mode 100755 index 000000000..090d72d27 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/persist/config.mk @@ -0,0 +1,72 @@ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +COMMON_DIR = $(TOPLEVEL)/common/Plugin + +INCLUDES += -I$(COMMON_DIR) + +vpath %.c $(COMMON_DIR) + +############################################################################## + +include $(COMMON_DIR)/config.mk + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += -lmempools +# --verbose + +LFLAGS2 = $(LFLAGS) \ + -nostartfiles + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS2 = $(LFLAGS) \ + -nostartfiles \ +# + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +LFLAGS2 = $(LFLAGS) \ + -nostartfiles \ +# + + +else + +############################################################################### +# AmigaOS + +LFLAGS += -lscalos \ + -lpreferences \ + -liconobject \ + -lmempools \ + -lstack \ + -lnix \ + -lnixmain \ + -lamiga21 \ + -lamiga \ + -lstubs \ + +endif +endif +endif diff --git a/scalos/Plugins/OOP/wb39_plugin/persist/makefile b/scalos/Plugins/OOP/wb39_plugin/persist/makefile new file mode 100644 index 000000000..30c8ce046 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/persist/makefile @@ -0,0 +1,110 @@ +# makefile for Scalos persist.plugin +# $Date$ +# using GNU make and SAS/C 6.58 + + +############################################################# + +CC = sc +AS = phxass +PRECOMP = INCLUDE:All.gst +LD = slink +LDFLAGS = quiet batch noicons sd +LDLIBS = LIB:sc.lib LIB:debug.lib LIB:amiga.lib +OBJDIR = .sasobj +DESTPLUG = Scalos:Plugins/OOP +COMMON_DIR = ../../../../common/Plugin + +.SUFFIXES: .plugin .plugin.debug + +############################################################# + +# Optimizer Flags +# Ignore Note 306: local function inlined: "InsertMH" +OPT_FLG = OPTIMIZE OPTINLOCAL OPTTIME OPTSCHED IGNORE=306,308 ERROR=87 +OPT_FLG2 = NOOPTIMIZE IGNORE=306,308 ERROR=87 + +ifdef DEBUG + CFLAGS = nostkchk nochkabort dbg=ff nover gst=$(PRECOMP) idlen=64 \ + idir=////include \ + idir=$(subst ../,/,$(COMMON_DIR)) + + CSTARTUP = LIB:c.o +else + CFLAGS = nostkchk nochkabort $(OPT_FLG) DBG=f def=NDEBUG \ + nover gst=$(PRECOMP) idlen=64 \ + idir=////include \ + idir=$(subst ../,/,$(COMMON_DIR)) + CSTARTUP = LIB:cback.o +endif + +AFLAGS = quiet I=sc:Assembler_Headers + +############################################################# + +PERSISTNAME = persist.plugin +CSRCS = $(COMMON_DIR)/plugin-classic.c \ + persist.c \ + +XSRCS = $(notdir $(CSRCS)) +OBJS= $(XSRCS:%.c=$(OBJDIR)/$(notdir %).o) + +############################################################# + +LIBS = LIB:mempools.lib LIB:sc.lib LIB:debug.lib LIB:amiga.lib + +############################################################# + +all: $(PERSISTNAME) \ + $(PERSISTNAME).debug \ +# install +# clean + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +############################################################# + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-classic.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $*.c objectname $@ + +############################################################# + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-classic.c \ + $(COMMON_DIR)/plugin-common.c $(COMMON_DIR)/plugin.h plugin_data.h + +$(OBJDIR)/persist.o : Persist.c Persist.h plugin_data.h + +############################################################# + +$(PERSISTNAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(OBJS) TO $(PERSISTNAME) lib $(LIBS) $(LDFLAGS) STRIPDEBUG + +$(PERSISTNAME).debug: $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(OBJS) TO $(PERSISTNAME).debug lib $(LIBS) $(LDFLAGS) ADDSYM + +############################################################# + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(PERSISTNAME).\033[0m\n' + @copy $(PERSISTNAME) $(DESTPLUG) clone + +############################################################# + +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + -@delete $(OBJS) \ + $(PERSISTNAME) \ + $(PERSISTNAME).debug + @printf '\033[0m' + +############################################################# diff --git a/scalos/Plugins/OOP/wb39_plugin/persist/makefile-new b/scalos/Plugins/OOP/wb39_plugin/persist/makefile-new new file mode 100755 index 000000000..5617fbc7d --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/persist/makefile-new @@ -0,0 +1,68 @@ +# $Date: 2011-08-02 00:13:23 +0200 (Di, 02. Aug 2011) $ +# $Revision: 816 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../../../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(BEGIN_OBJS) \ + $(OBJDIR)/persist.o \ + $(END_OBJS) + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Targets +# + +NAME = persist.plugin +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + @$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS2) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + copy $(BINDIR)/$(NAME) Scalos:Plugins/OOP clone + + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* + +############################################################################## + + diff --git a/scalos/Plugins/OOP/wb39_plugin/persist/persist.c b/scalos/Plugins/OOP/wb39_plugin/persist/persist.c new file mode 100644 index 000000000..450b2958a --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/persist/persist.c @@ -0,0 +1,1643 @@ +// Persist.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +//#include + +#include "Persist.h" +#include "plugin.h" + +// moved revision history to file "History" + +//---------------------------------------------------------------------------- + +// aus mempools.lib +#ifndef __amigaos4__ +extern int _STI_240_InitMemFunctions(void); +extern void _STD_240_TerminateMemFunctions(void); +#endif /* __amigaos4__ */ + +static void GetScalosPath(Object *o, char *Path, size_t MaxLen); +static struct OpenNode *AddWindowPath(const struct ScaWindowStruct *ws, CONST_STRPTR Path); +static void RemoveWindowPath(CONST_STRPTR Path); +static void SetIconifyState_WindowTask(const struct ScaWindowTask *wt, BOOL Iconified); +static void SetWindowDimensions_WindowTask(const struct ScaWindowTask *wt, + WORD Left, WORD Top, WORD Width, WORD Height); +// static void striplf(char *Line); +static void ScalosWindowOpen(Class *cl, Object *obj, Msg msg); +static void ScalosWindowClose(Class *cl, Object *obj, Msg msg); +static void ScalosWindowIconify(Class *cl, Object *obj, Msg msg); +static void ScalosWindowUnIconify(Class *cl, Object *obj, Msg msg); +static void ScalosWindowNewPath(Class *cl, Object *obj, Msg msg); +static void ScalosWindowSetSize(Class *cl, Object *obj, Msg msg); +static void DeleteNamedNode(CONST_STRPTR Path); +static void FreeNode(struct OpenNode *OldNode); +static void RewriteNodeListFile(void); +static BOOL StartReOpenProcess(void); +static SAVEDS(int) ReOpenProcess(void); +static void ReadNodes(void); +static BOOL OpenNodes(void); +static void CleanupNodes(void); +static void striplf(char *Line); +static void ReadConfig(CONST_STRPTR Filename); +static BOOL ExistsDevice(CONST_STRPTR Path); +static struct OpenNode *FindNamedNode(CONST_STRPTR Path); +static struct ScaWindowStruct *FindWindowByLock(BPTR xLock); +static BOOL StartUpdaterProcess(void); +static void KillUpdaterProcess(void); +static void TriggerUpdater(void); +static BOOL InitProcessTimer(struct ProcessTimerInfo *Timer); +static void CleanupProcessTimer(struct ProcessTimerInfo *Timer); +static SAVEDS(int) UpdaterProcess(void); + +#if !defined(__SASC) && !defined(__MORPHOS__) && !defined(__AROS__) +static char *stpblk(CONST_STRPTR q); +#endif /* !defined(__SASC) &&!defined(__MORPHOS__) */ + +//---------------------------------------------------------------------------- + +struct DosLibrary *DOSBase; +struct ScalosBase *ScalosBase; +T_UTILITYBASE UtilityBase; +struct Library *IconBase; +struct Library *IconobjectBase; +struct IntuitionBase *IntuitionBase; +T_INPUTBASE InputBase; +#ifdef __amigaos4__ +struct Library *NewlibBase; + +struct DOSIFace *IDOS; +struct ScalosIFace *IScalos; +struct UtilityIFace *IUtility; +struct IconIFace *IIcon; +struct IconobjectIFace *IIconobject; +struct IntuitionIFace *IIntuition; +struct InputIFace *IInput; +struct Interface *INewlib; +#endif /* __amigaos4__ */ + +#if defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) +extern T_UTILITYBASE __UtilityBase; +#endif /* defined(__GNUC__) && !defined(__MORPHOS__) && ! defined(__amigaos4__) */ + +STRPTR DefIconsPath = "ENV:sys/def_"; + +static BOOL fInit; + +static BOOL ignoreWindowClose = FALSE; +static BOOL wbStartupFinished = FALSE; + +static struct SignalSemaphore PersistSema; +static struct List OpenList; + +static struct List ReOpenList; + +static long OpenDelayTicks = 20l; // number of Delay() ticks to wait before opening each window +static BOOL UseScaIconify = FALSE; // Flag : use SCA_Iconify with OpenDrawerByNameTags() +static long UseWindowSizes = TRUE; // Flag: size and position is retained for each window + +static char Persist_FileName[256] = PERSIST_FILENAME; + +static ULONG UpdaterProcSignal = 0L; +struct Process *UpdaterProc = NULL; + +//---------------------------------------------------------------------------- + +BOOL initPlugin(struct PluginBase *pluginbase) +{ + BOOL Success = FALSE; + + d(kprintf(__FUNC__ "/%ld \n", __LINE__);) + + if (fInit) + return TRUE; + + do { + d(kprintf(__FUNC__ "/%ld \n", __LINE__);) + + NewList(&OpenList); + + InitSemaphore(&PersistSema); + + DOSBase = (struct DosLibrary *) OpenLibrary(DOSNAME, 39); + if (NULL == DOSBase) + break; +#ifdef __amigaos4__ + IDOS = (struct DOSIFace *)GetInterface((struct Library *)DOSBase, "main", 1, NULL); + if (NULL == IDOS) + break; +#endif /* __amigaos4__ */ + + UtilityBase = (T_UTILITYBASE) OpenLibrary("utility.library", 39); + if (NULL == UtilityBase) + break; +#ifdef __amigaos4__ + IUtility = (struct UtilityIFace *)GetInterface((struct Library *)UtilityBase, "main", 1, NULL); + if (NULL == IUtility) + break; +#endif /* __amigaos4__ */ + +#if defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) + __UtilityBase = UtilityBase; +#endif /* defined(__GNUC__) && !defined(__MORPHOS__) */ + + ScalosBase = (struct ScalosBase *) OpenLibrary(SCALOSNAME, 41); + if (NULL == ScalosBase) + break; +#ifdef __amigaos4__ + IScalos = (struct ScalosIFace *)GetInterface((struct Library *)ScalosBase, "main", 1, NULL); + if (NULL == IScalos) + break; +#endif /* __amigaos4__ */ + + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + if (NULL == IntuitionBase) + break; +#ifdef __amigaos4__ + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + break; + + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + break; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + break; +#endif /* __amigaos4__ */ + + +#if !defined(__amigaos4__) && !defined(__AROS__) + if (_STI_240_InitMemFunctions()) + break; +#endif /* __amigaos4__ */ + + fInit = TRUE; + + if (ScalosBase->scb_LibNode.lib_Version >= 40) + UseScaIconify = TRUE; + + ReadConfig(PERSIST_CONFIGFILENAME); + + if (!StartReOpenProcess()) + break; + + if (!StartUpdaterProcess()) + break; + + Success = TRUE; + } while (0); + + if (!fInit) + closePlugin(pluginbase); + + return Success; +} + +//---------------------------------------------------------------------------- + +VOID closePlugin(struct PluginBase *pluginbase) +{ + (void) pluginbase; + + KillUpdaterProcess(); + + ObtainSemaphore(&PersistSema); + + fInit = FALSE; + +#if !defined(__amigaos4__) && !defined(__AROS__) + _STD_240_TerminateMemFunctions(); +#endif /* __amigaos4__ */ + + +#ifdef __amigaos4__ + if (IScalos) + { + DropInterface((struct Interface *)IScalos); + IScalos = NULL; + } +#endif /* __amigaos4__ */ + if (ScalosBase) + { + CloseLibrary((struct Library *) ScalosBase); + ScalosBase = NULL; + } +#ifdef __amigaos4__ + if (INewlib) + { + DropInterface(INewlib); + INewlib = NULL; + } + if (NewlibBase) + { + CloseLibrary(NewlibBase); + NewlibBase = NULL; + } + if (IUtility) + { + DropInterface((struct Interface *)IUtility); + IUtility = NULL; + } +#endif /* __amigaos4__ */ + if (UtilityBase) + { + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } +#ifdef __amigaos4__ + if (IDOS) + { + DropInterface((struct Interface *)IDOS); + IDOS = NULL; + } +#endif /* __amigaos4__ */ + if (DOSBase) + { + CloseLibrary((struct Library *) DOSBase); + DOSBase = NULL; + } +#ifdef __amigaos4__ + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } +#endif /* __amigaos4__ */ + if (IntuitionBase) + { + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } + ReleaseSemaphore(&PersistSema); +} + +//---------------------------------------------------------------------------- + +M68KFUNC_P3(ULONG, persistHookFunc, + A0, Class *, cl, + A2, Object *, obj, + A1, Msg, msg) +{ + switch (msg->MethodID) + { + case SCCM_Window_Open: + d(kprintf(__FUNC__ "/%ld SCCM_Window_Open\n", __LINE__);) + ScalosWindowOpen(cl, obj, msg); + break; + + case SCCM_Window_Close: + d(kprintf(__FUNC__ "/%ld SCCM_Window_Close\n", __LINE__);) + ScalosWindowClose(cl, obj, msg); + break; + + case SCCM_Window_Iconify: + d(kprintf(__FUNC__ "/%ld SCCM_Window_Iconify\n", __LINE__);) + ScalosWindowIconify(cl, obj, msg); + break; + + case SCCM_Window_UnIconify: + d(kprintf(__FUNC__ "/%ld SCCM_Window_UnIconify\n", __LINE__);) + ScalosWindowUnIconify(cl, obj, msg); + break; + + case SCCM_Window_NewPath: + ScalosWindowNewPath(cl, obj, msg); + break; + + case SCCM_Window_SetInnerSize: + d(KPrintF(__FUNC__ "/%ld SCCM_Window_SetInnerSize\n", __LINE__);) + ScalosWindowSetSize(cl, obj, msg); + break; + + case SCCM_Window_WBStartupFinished: + d1(KPrintF("%s/%ld SCCM_Window_WBStartupFinished\n", __FUNC__, __LINE__);) + wbStartupFinished = TRUE; + break; + } + + d(kprintf(__FUNC__ "/%ld: MethodID=%08lx\n", __LINE__, msg->MethodID)); + + return DoSuperMethodA(cl, obj, msg); +} +M68KFUNC_END + +//---------------------------------------------------------------------------- + +static void GetScalosPath(Object *o, char *Path, size_t MaxLen) +{ + struct ScaRootList *rList = (struct ScaRootList *) o; + struct ScaWindowStruct *ws = rList->rl_WindowTask->mt_WindowStruct; + + *Path = '\0'; + + d(kprintf(__FUNC__ "/%ld: ScaWindowStruct=%08lx Task=%08lx Lock=%08lx Window=%08lx\n", \ + __LINE__, ws, ws->ws_Task, ws->ws_Lock, ws->ws_Window)); + + if (ws && ws->ws_Lock) + { + NameFromLock(ws->ws_Lock, Path, MaxLen); + } +} + +//---------------------------------------------------------------------------- + +static struct OpenNode *AddWindowPath(const struct ScaWindowStruct *ws, CONST_STRPTR Path) +{ + struct OpenNode *NewNode; + + d(kprintf(__FUNC__ "/%ld: Path = <%s>\n", __LINE__, Path)); + + NewNode = FindNamedNode(Path); + if (NewNode) + { + NewNode->on_Iconified = FALSE; + } + else + { + NewNode = malloc(sizeof(struct OpenNode)); + if (NewNode) + { + ObtainSemaphore(&PersistSema); + + NewNode->on_BrowserMode = FALSE; + NewNode->on_Iconified = FALSE; + NewNode->on_Path = strdup(Path); + + if (ws) + { + NewNode->on_WindowTask = ws->ws_WindowTask; + + NewNode->on_Left = ws->ws_Left; + NewNode->on_Top = ws->ws_Top; + NewNode->on_Width = ws->ws_Width; + NewNode->on_Height = ws->ws_Height; + } + else + { + NewNode->on_WindowTask = NULL; + + NewNode->on_Left = 0; + NewNode->on_Top = 0; + NewNode->on_Width = 0; + NewNode->on_Height = 0; + } + + DeleteNamedNode(Path); + AddTail(&OpenList, &NewNode->on_Node); + + ReleaseSemaphore(&PersistSema); + } + } + + if (ws && (ws->ws_Flags & WSV_FlagF_BrowserMode)) + NewNode->on_BrowserMode = TRUE; + + TriggerUpdater(); + + return NewNode; +} + +//---------------------------------------------------------------------------- + +static void RemoveWindowPath(CONST_STRPTR Path) +{ + d(kprintf(__FUNC__ "/%ld: Path = <%s>\n", __LINE__, Path)); + + DeleteNamedNode(Path); + + TriggerUpdater(); +} + +//---------------------------------------------------------------------------- + +static void SetIconifyState_WindowTask(const struct ScaWindowTask *wt, BOOL Iconified) +{ + char Path[512]; + struct OpenNode *OldNode; + + ObtainSemaphoreShared(&PersistSema); + + if (!NameFromLock(wt->mt_WindowStruct->ws_Lock, Path, sizeof(Path))) + { + *Path = '\0'; + } + + d(kprintf(__FUNC__ "/%ld: Path = <%s>\n", __LINE__, Path)); + + // Iconify-Zustand beim Eintrag mit Namen einstellen + for (OldNode = (struct OpenNode *) OpenList.lh_Head; + OldNode != (struct OpenNode *) &OpenList.lh_Tail; + OldNode = (struct OpenNode *) OldNode->on_Node.ln_Succ ) + { + if (wt == OldNode->on_WindowTask) + { + OldNode->on_Iconified = Iconified; + break; + } + if (NULL == OldNode->on_WindowTask) + { + if (0 == Stricmp(OldNode->on_Path, Path)) + { + OldNode->on_WindowTask = wt; + OldNode->on_Iconified = Iconified; + break; + } + } + } + + ReleaseSemaphore(&PersistSema); + + TriggerUpdater(); +} + +//---------------------------------------------------------------------------- + +static void SetWindowDimensions_WindowTask(const struct ScaWindowTask *wt, + WORD Left, WORD Top, WORD Width, WORD Height) +{ + struct OpenNode *OldNode; + + ObtainSemaphoreShared(&PersistSema); + + d(kprintf(__FUNC__ "/%ld: Path = <%s>\n", __LINE__, Path)); + + // Iconify-Zustand beim Eintrag mit Namen einstellen + for (OldNode = (struct OpenNode *) OpenList.lh_Head; + OldNode != (struct OpenNode *) &OpenList.lh_Tail; + OldNode = (struct OpenNode *) OldNode->on_Node.ln_Succ) + { + if (wt == OldNode->on_WindowTask) + { + OldNode->on_Left = Left; + OldNode->on_Top = Top; + OldNode->on_Width = Width; + OldNode->on_Height = Height; + break; + } + } + + ReleaseSemaphore(&PersistSema); + + TriggerUpdater(); +} + +//---------------------------------------------------------------------------- + +static void ScalosWindowOpen(Class *cl, Object *obj, Msg msg) +{ + struct ScaRootList *rList = (struct ScaRootList *) obj; + struct ScaWindowStruct *ws = rList->rl_WindowTask->mt_WindowStruct; + char Filename[512]; + + d(kprintf(__FUNC__ "/%ld: InstOffset=%08lx InstSize=%08lx SubclassCount=%lu ObjectCount=%lu\n", \ + __LINE__, cl->cl_InstOffset, cl->cl_InstSize, cl->cl_SubclassCount, cl->cl_ObjectCount)); + + d(kprintf(__FUNC__ "/%ld: ws=%08lx name=%08lx <%s>\n", __LINE__, \ + ws, ws->ws_Name, ws->ws_Name ? ws->ws_Name : (STRPTR) "")); + + if (NULL == ws->ws_Name) + { + // Root window is being opened (ws_Name == NULL) + ignoreWindowClose = FALSE; + } + + GetScalosPath(obj, Filename, sizeof(Filename)); + if (*Filename) + AddWindowPath(ws, Filename); + + d(kprintf(__FUNC__ "/%ld: OM_NEW Result=%08lx obj=%08lx WindowStruct=%08lx\n", __LINE__, Result, obj, ws)); + d(kprintf(__FUNC__ "/%ld: ExecBase=%08lx DosBase=%08lx\n", __LINE__, SysBase, DOSBase)); +} + +//---------------------------------------------------------------------------- + +static void ScalosWindowClose(Class *cl, Object *obj, Msg msg) +{ + struct ScaRootList *rList = (struct ScaRootList *) obj; + struct ScaWindowStruct *ws = rList->rl_WindowTask->mt_WindowStruct; + char Filename[512]; + + d(kprintf(__FUNC__ "/%ld: InstOffset=%08lx InstSize=%08lx SubclassCount=%lu ObjectCount=%lu\n", \ + __LINE__, cl->cl_InstOffset, cl->cl_InstSize, cl->cl_SubclassCount, cl->cl_ObjectCount)); + d(kprintf(__FUNC__ "/%ld: OM_DISPOSE Result=%08lx obj=%08lx MethodID=%08lx\n", __LINE__, Result, obj, msg->MethodID)); + d(kprintf(__FUNC__ "/%ld: ExecBase=%08lx DosBase=%08lx\n", __LINE__, inst->pi_ExecBase, inst->pi_DosBase)); + + d(kprintf(__FUNC__ "/%ld: ws=%08lx name=%08lx <%s>\n", __LINE__, \ + ws, ws->ws_Name, ws->ws_Name ? ws->ws_Name : (STRPTR) "")); + + if (NULL == ws->ws_Name) + { + // Root window is being closed (ws_Name == NULL) + // Scalos is going to quit or CloseWorkBench() + ignoreWindowClose = TRUE; + } + + if (!ignoreWindowClose) + { + GetScalosPath(obj, Filename, sizeof(Filename)); + if (*Filename) + RemoveWindowPath(Filename); + } +} + +//---------------------------------------------------------------------------- + +static void ScalosWindowIconify(Class *cl, Object *o, Msg msg) +{ + struct ScaWindowTask *wt = ((struct ScaRootList *) o)->rl_WindowTask; + + d(KPrintF(__FUNC__ "/%ld: wt=%08lx name=%08lx <%s>\n", __LINE__, \ + wt, wt->mt_WindowStruct->ws_Name, \ + wt->mt_WindowStruct->ws_Name ? wt->mt_WindowStruct->ws_Name : (STRPTR) "")); + + SetIconifyState_WindowTask(wt, TRUE); +} + +//---------------------------------------------------------------------------- + +static void ScalosWindowUnIconify(Class *cl, Object *o, Msg msg) +{ + struct ScaWindowTask *wt = ((struct ScaRootList *) o)->rl_WindowTask; + + d(KPrintF(__FUNC__ "/%ld: wt=%08lx name=%08lx <%s>\n", __LINE__, \ + wt, wt->mt_WindowStruct->ws_Name, \ + wt->mt_WindowStruct->ws_Name ? wt->mt_WindowStruct->ws_Name : (STRPTR) "")); + + SetIconifyState_WindowTask(wt, FALSE); +} + +//---------------------------------------------------------------------------- + +static void ScalosWindowNewPath(Class *cl, Object *obj, Msg msg) +{ + const struct msg_NewPath *npa = (const struct msg_NewPath *) msg; + struct ScaRootList *rList = (struct ScaRootList *) obj; + struct ScaWindowStruct *ws = rList->rl_WindowTask->mt_WindowStruct; + char Filename[512]; + BPTR OldDir; + BPTR pLock; + + d(kprintf(__FUNC__ "/%ld: InstOffset=%08lx InstSize=%08lx SubclassCount=%lu ObjectCount=%lu\n", \ + __LINE__, cl->cl_InstOffset, cl->cl_InstSize, cl->cl_SubclassCount, cl->cl_ObjectCount)); + d(kprintf(__FUNC__ "/%ld: OM_DISPOSE Result=%08lx obj=%08lx MethodID=%08lx\n", __LINE__, Result, obj, msg->MethodID)); + d(kprintf(__FUNC__ "/%ld: ExecBase=%08lx DosBase=%08lx\n", __LINE__, inst->pi_ExecBase, inst->pi_DosBase)); + + d(kprintf(__FUNC__ "/%ld: ws=%08lx name=%08lx <%s>\n", __LINE__, \ + ws, ws->ws_Name, ws->ws_Name ? ws->ws_Name : (STRPTR) "")); + + GetScalosPath(obj, Filename, sizeof(Filename)); + if (*Filename) + RemoveWindowPath(Filename); + + OldDir = CurrentDir(ws->ws_Lock); + pLock = Lock(npa->npa_Path, ACCESS_READ); + if (pLock) + { + NameFromLock(pLock, Filename, sizeof(Filename)); + (void) AddWindowPath(ws, Filename); + UnLock(pLock); + } + CurrentDir(OldDir); + +} + +//---------------------------------------------------------------------------- + +static void ScalosWindowSetSize(Class *cl, Object *o, Msg msg) +{ + struct ScaWindowTask *wt = ((struct ScaRootList *) o)->rl_WindowTask; + + d1(KPrintF("%s/%s/%ld: ws=<%s> ws_Left=%ld ws_Top=%ld ws_Width=%ld ws_Height=%ld\n", __FILE__, __FUNC__, __LINE__, \ + wt->mt_WindowStruct->ws_Name ? wt->mt_WindowStruct->ws_Name : (STRPTR) "", \ + wt->mt_WindowStruct->ws_Left, wt->mt_WindowStruct->ws_Top,\ + wt->mt_WindowStruct->ws_Width, wt->mt_WindowStruct->ws_Height )); + + SetWindowDimensions_WindowTask(wt, + wt->mt_WindowStruct->ws_Left, + wt->mt_WindowStruct->ws_Top, + wt->mt_WindowStruct->ws_Width, + wt->mt_WindowStruct->ws_Height); +} + +//---------------------------------------------------------------------------- + +static void DeleteNamedNode(CONST_STRPTR Path) +{ + struct OpenNode *NextNode, *OldNode; + + ObtainSemaphore(&PersistSema); + + // alle Einträge mit gleichen Namen entfernen + for (OldNode = (struct OpenNode *) OpenList.lh_Head; OldNode != (struct OpenNode *) &OpenList.lh_Tail; ) + { + NextNode = (struct OpenNode *) OldNode->on_Node.ln_Succ; + + if (0 == Stricmp(OldNode->on_Path, Path) && !OldNode->on_Iconified) + { + Remove(&OldNode->on_Node); + FreeNode(OldNode); + } + + OldNode = NextNode; + } + + ReleaseSemaphore(&PersistSema); +} + +//---------------------------------------------------------------------------- + +static void FreeNode(struct OpenNode *OldNode) +{ + if (OldNode) + { + if (OldNode->on_Path) + { + free(OldNode->on_Path); + OldNode->on_Path = NULL; + } + free(OldNode); + } +} + +//---------------------------------------------------------------------------- + +static void RewriteNodeListFile(void) +{ + static CONST_STRPTR NewSuffix = "-new"; + static CONST_STRPTR OldSuffix = "-old"; + STRPTR FNameNew; + STRPTR FNameOld; + + FNameNew = malloc(1 + strlen(Persist_FileName) + strlen(NewSuffix)); + FNameOld = malloc(1 + strlen(Persist_FileName) + strlen(OldSuffix)); + if (FNameNew && FNameOld) + { + BOOL Success = TRUE; + + strcpy(FNameNew, Persist_FileName); + strcat(FNameNew, NewSuffix); + + strcpy(FNameOld, Persist_FileName); + strcat(FNameOld, OldSuffix); + + do { + BPTR fh; + + fh = Open(FNameNew, MODE_NEWFILE); + if (fh) + { + LONG rc; + struct OpenNode *OldNode; + + rc = FPuts(fh, "# written by persist.plugin\n"); + if (rc < 0) + { + Success = FALSE; + break; + } + rc = FPuts(fh, "#\n"); + if (rc < 0) + { + Success = FALSE; + break; + } + ObtainSemaphoreShared(&PersistSema); + + for (OldNode = (struct OpenNode *) OpenList.lh_Head; + Success && (OldNode != (struct OpenNode *) &OpenList.lh_Tail); + OldNode = (struct OpenNode *) OldNode->on_Node.ln_Succ ) + { + if (OldNode->on_Left) + { + rc = FPrintf(fh, "X=%ld ", OldNode->on_Left); + if (rc < 0) + { + Success = FALSE; + break; + } + } + if (OldNode->on_Top) + { + rc = FPrintf(fh, "Y=%ld ", OldNode->on_Top); + if (rc < 0) + { + Success = FALSE; + break; + } + } + if (OldNode->on_Width) + { + rc = FPrintf(fh, "W=%ld ", OldNode->on_Width); + if (rc < 0) + { + Success = FALSE; + break; + } + } + if (OldNode->on_Height) + { + rc = FPrintf(fh, "H=%ld ", OldNode->on_Height); + if (rc < 0) + { + Success = FALSE; + break; + } + } + rc = FPrintf(fh, "%s%sP=%s\n", + (ULONG) (OldNode->on_Iconified ? "I " : ""), + (ULONG) (OldNode->on_BrowserMode ? "B " : ""), + (ULONG) OldNode->on_Path); + if (rc < 0) + { + Success = FALSE; + break; + } + } + + ReleaseSemaphore(&PersistSema); + + if (!Close(fh)) + Success = FALSE; + } + else + { + Success = FALSE; + } + } while (0); + + if (Success) + { + (void) DeleteFile(FNameOld); + (void) Rename(Persist_FileName, FNameOld); + + if (Rename(FNameNew, Persist_FileName)) + { + (void) DeleteFile(FNameOld); + } + } + else + { + (void) DeleteFile(FNameNew); + } + } + if (FNameNew) + free(FNameNew); + if (FNameOld) + free(FNameOld); +} + +//---------------------------------------------------------------------------- + +static BOOL StartReOpenProcess(void) +{ + STATIC_PATCHFUNC(ReOpenProcess) + struct Process *myProc; + + // CreateNewProc() + myProc = CreateNewProcTags(NP_Name, (ULONG) "ReOpenScaloswindows", + NP_Priority, 0, + NP_Entry, (ULONG) PATCH_NEWFUNC(ReOpenProcess), + NP_StackSize, 32768, + TAG_END); + if (myProc == NULL) + { +// alarm("StartReOpenProcess: CreateProc() failed"); + return FALSE; + } + + return TRUE; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(int) ReOpenProcess(void) +{ + struct MsgPort *inputPort = NULL; + struct IOStdReq *inputRequest = NULL; + + d(KPrintF(__FUNC__ "/%ld Start\n", __LINE__);) + + do { + NewList(&ReOpenList); + + IconBase = OpenLibrary("icon.library", 39); + if (NULL == IconBase) + break; +#ifdef __amigaos4__ + IIcon = (struct IconIFace *)GetInterface((struct Library *)IconBase, "main", 1, NULL); + if (NULL == IIcon) + break; +#endif /* __amigaos4__ */ + + IconobjectBase = OpenLibrary("iconobject.library", 39); + if (NULL == IconobjectBase) + break; +#ifdef __amigaos4__ + IIconobject = (struct IconobjectIFace *)GetInterface((struct Library *)IconobjectBase, "main", 1, NULL); + if (NULL == IIconobject) + break; +#endif /* __amigaos4__ */ + + d(kprintf(__FUNC__ "/%ld \n", __LINE__);) + + // open input.device for use by PeekQualifier() + inputPort = CreateMsgPort(); + if (NULL == inputPort) + break; + inputRequest = (struct IOStdReq *) CreateExtIO(inputPort, sizeof(struct IOStdReq)); + if (NULL == inputRequest) + break; + + if (0 != OpenDevice("input.device", 0, (struct IORequest *) inputRequest, 0)) + break; + InputBase = (T_INPUTBASE) inputRequest->io_Device; +#ifdef __amigaos4__ + IInput = (struct InputIFace *) GetInterface((struct Library *)InputBase, "main", 1, NULL); + if (NULL == IInput) + break; +#endif /* __amigaos4__ */ + + d(kprintf("%s/%ld \n", __FUNC__, __LINE__);) + + ReadNodes(); + + d1(kprintf("%s/%ld \n", __FUNC__, __LINE__);) + + while (!wbStartupFinished) + { + Delay(5); + } + + d1(kprintf("%s/%ld \n", __FUNC__, __LINE__);) + + if (!OpenNodes()) + break; + + CleanupNodes(); + } while (0); + +#ifdef __amigaos4__ + if (IInput) + { + DropInterface((struct Interface *)IInput); + IInput = NULL; + } +#endif /* __amigaos4__ */ + if (InputBase) + { + CloseDevice((struct IORequest *) inputRequest); + InputBase = NULL; + } + if (inputRequest) + DeleteExtIO((struct IORequest *) inputRequest); + if (inputPort) + DeleteMsgPort(inputPort); +#ifdef __amigaos4__ + if (IIconobject) + { + DropInterface((struct Interface *)IIconobject); + IIconobject = NULL; + } +#endif /* __amigaos4__ */ + if (IconobjectBase) + { + CloseLibrary(IconobjectBase); + IconobjectBase = NULL; + } +#ifdef __amigaos4__ + if (IIcon) + { + DropInterface((struct Interface *)IIcon); + IIcon = NULL; + } +#endif /* __amigaos4__ */ + if (IconBase) + { + CloseLibrary(IconBase); + IconBase = NULL; + } + + return 0; +} + +//---------------------------------------------------------------------------- + +static void ReadNodes(void) +{ + BPTR fd; + struct RDArgs *rdArgs; + + rdArgs = AllocDosObject(DOS_RDARGS, NULL); + if (NULL == rdArgs) + { +// Printf("AllocDosObject(DOS_RDARG) failed, err=%ld\n", IoErr()); + return; + } + + fd = Open(Persist_FileName, MODE_OLDFILE); + if (fd) + { + char Line[256]; + + while (FGets(fd, Line, sizeof(Line))) + { + striplf(Line); + + d1(KPrintF(__FUNC__ "/%ld: Line = <%s>\n", __LINE__, Line)); + + if (strlen(Line) > 0 && '#' != *Line) + { + static CONST_STRPTR Template = "I=ICONIFIED/S,B=BROWSERMODE/S,P=PATH/A/F,X=LEFT/K/N,Y=TOP/K/N,W=WIDTH/K/N,H=HEIGHT/K/N"; + enum { + ARG_Iconified, + ARG_BrowserMode, + ARG_Path, + ARG_Left, + ARG_Top, + ARG_Width, + ARG_Height + }; + SIPTR ArgArray[7]; + struct RDArgs *rdArg; + char *ArgString; + + memset(ArgArray, 0, sizeof(ArgArray)); + + ArgString = malloc(strlen(Line) + 2); + if (ArgString) + { + strcpy(ArgString, Line); + strcat(ArgString, "\n"); + + rdArgs->RDA_Source.CS_Buffer = ArgString; + rdArgs->RDA_Source.CS_Length = strlen(ArgString); + rdArgs->RDA_Source.CS_CurChr = 0; + rdArgs->RDA_Flags |= RDAF_NOPROMPT; + + rdArg = ReadArgs((STRPTR) Template, ArgArray, rdArgs); + + d1(KPrintF(__FUNC__ "/%ld: rdArg=%08lx\n", __LINE__, rdArg)); + if (rdArg) + { + struct OpenNode *NewNode = malloc(sizeof(struct OpenNode)); + + if (NewNode) + { + d1(KPrintF(__FUNC__ "/%ld: Iconified=%ld Path=<%s>\n", __LINE__, ArgArray[ARG_Iconified], ArgArray[ARG_Path])); + + NewNode->on_Path = strdup((char *) ArgArray[ARG_Path]); + + if (ArgArray[ARG_Iconified]) + NewNode->on_Iconified = TRUE; + else + NewNode->on_Iconified = FALSE; + + if (ArgArray[ARG_BrowserMode]) + NewNode->on_BrowserMode = TRUE; + else + NewNode->on_BrowserMode = FALSE; + + if (ArgArray[ARG_Left]) + NewNode->on_Left = *((LONG *) ArgArray[ARG_Left]); + else + NewNode->on_Left = 0; + if (ArgArray[ARG_Top]) + NewNode->on_Top = *((LONG *) ArgArray[ARG_Top]); + else + NewNode->on_Top = 0; + if (ArgArray[ARG_Width]) + NewNode->on_Width = *((LONG *) ArgArray[ARG_Width]); + else + NewNode->on_Width = 0; + if (ArgArray[ARG_Height]) + NewNode->on_Height = *((LONG *) ArgArray[ARG_Height]); + else + NewNode->on_Height = 0; + + d1(KPrintF("%s/%s/%ld: Path=<%s> Left=%ld Top=%ld Width=%ld Height=%ld\n", __FILE__, __FUNC__, __LINE__, \ + NewNode->on_Path, \ + NewNode->on_Left, NewNode->on_Top, NewNode->on_Width, NewNode->on_Height )); + + AddTail(&ReOpenList, &NewNode->on_Node); + } + + FreeArgs(rdArg); + } + else + { +// LONG Error = IoErr(); + + d(kprintf(__FUNC__ "/%ld: ReadArgs() error = %ld\n", __LINE__, Error)); +// Printf("ReadArgs(%s) returned> error=%ld\n", Line, Error); + } + free(ArgString); + } + } + } + + Close(fd); + // persist file autimatically gets rewritten when first window opens + } + else + { +// Printf("Failed to open file <%s> err=%ld\n", Persist_FileName, IoErr()); + } + + FreeDosObject(DOS_RDARGS, rdArgs); +} + +//---------------------------------------------------------------------------- + +static BOOL OpenNodes(void) +{ + struct OpenNode *OldNode; + BOOL NormalFinished = TRUE; + + while (OldNode = (struct OpenNode *) RemHead(&ReOpenList)) + { + UWORD Qualifier = PeekQualifier(); + + if (Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)) + { + NormalFinished = FALSE; + break; + } + + Delay(OpenDelayTicks); + + if (ExistsDevice(OldNode->on_Path)) + { + struct IBox WindowRect; + + d1(KPrintF("%s/%s/%ld: path=<%s> iconified=%ld Left=%ld Top=%ld Width=%ld Height=%ld\n", \ + __FILE__, __FUNC__, __LINE__, OldNode->on_Path, OldNode->on_Iconified, \ + OldNode->on_Left, OldNode->on_Top, OldNode->on_Width, OldNode->on_Height)); + + WindowRect.Left = OldNode->on_Left; + WindowRect.Top = OldNode->on_Top; + + if (UseWindowSizes) + { + WindowRect.Width = OldNode->on_Width; + WindowRect.Height = OldNode->on_Height; + } + else + { + // Do not use stored window position and size + WindowRect.Width = WindowRect.Height = 0; + } + + SCA_OpenDrawerByNameTags(OldNode->on_Path, + UseScaIconify ? SCA_Iconify : TAG_IGNORE, OldNode->on_Iconified, + SCA_NoActivateWindow, TRUE, + SCA_BrowserMode, OldNode->on_BrowserMode, + ((0 != WindowRect.Width) && (0 != WindowRect.Height)) + ? SCA_WindowRect : TAG_IGNORE, (ULONG) &WindowRect, + TAG_END); + } + + if (OldNode->on_Iconified) + { + if (UseScaIconify) + { + struct OpenNode *NewNode; + + NewNode = AddWindowPath(NULL, OldNode->on_Path); + + if (NewNode) + { + NewNode->on_Iconified = TRUE; + TriggerUpdater(); + } + } + else + { + BPTR wLock = Lock(OldNode->on_Path, ACCESS_READ); + + if (wLock) + { + struct ScaWindowStruct *sw; + + Delay(2 * 50); // allow window to open... + + sw = FindWindowByLock(wLock); + if (sw) + { + SCA_UnLockWindowList(); + DoMethod(sw->ws_WindowTask->mt_WindowObject, SCCM_Window_Iconify); + } + + UnLock(wLock); + } + } + } + + if (OldNode->on_Path) + { + free(OldNode->on_Path); + OldNode->on_Path = NULL; + } + free(OldNode); + } + + return NormalFinished; +} + +//---------------------------------------------------------------------------- + +static void CleanupNodes(void) +{ + struct OpenNode *OldNode; + + while (OldNode = (struct OpenNode *) RemTail(&ReOpenList)) + { + if (OldNode->on_Path) + { + free(OldNode->on_Path); + OldNode->on_Path = NULL; + } + free(OldNode); + } +} + +//---------------------------------------------------------------------------- + +static void striplf(char *Line) +{ + size_t Len = strlen(Line); + + if ('\n' == Line[Len - 1]) + Line[Len - 1] = '\0'; +} + +//---------------------------------------------------------------------------- + +static void ReadConfig(CONST_STRPTR Filename) +{ + BPTR fh; + + fh = Open(Filename, MODE_OLDFILE); + if ((BPTR)NULL == fh) + return; + + while (1) + { + char Line[160]; + char *lp; + + lp = FGets(fh, Line, sizeof(Line)); + + if (lp) + { + char OptName[40]; + size_t len = strlen(lp); + size_t Length; + char *p; + + d1(kprintf(__FUNC__ "/%ld Line=<%s>\n", __LINE__, Line);) + + if (';' == *lp || '#' == *lp) + continue; // skip comment lines + if (isspace((int) *lp)) + continue; // skip lines beginning with spaces (or empty lines) + if (0 == len) + continue; + + if ('\n' == lp[len - 1]) + lp[len - 1] = '\0'; + + // OptName lesen + for (p=OptName, Length=sizeof(OptName)-1; + *lp && !isspace((int) *lp) && *lp != ':' && *lp != '.' && Length; + *p++ = *lp++, Length--); + *p = '\0'; + + while (*lp && *lp != '=') + lp++; + if (*lp == '\0') + break; + + lp = stpblk(++lp); + + d1(kprintf(__FUNC__ "/%ld OptName=<%s> Arg=<%s>\n", __LINE__, OptName, lp);) + + if (0 == Stricmp(OptName, "OpenDelay_Ticks")) + { + sscanf(lp, "%ld", &OpenDelayTicks); + d1(kprintf(__FUNC__ "/%ld OpenDelayTicks = %ld\n", __LINE__, OpenDelayTicks);) + } + else if (0 == Stricmp(OptName, "Use_SCA_Iconify")) + { + UseScaIconify = TRUE; + d1(kprintf(__FUNC__ "/%ld UseScaIconify = %ld\n", __LINE__, UseScaIconify);) + } + else if (0 == Stricmp(OptName, "Use_Window_Sizes")) + { + sscanf(lp, "%ld", &UseWindowSizes); + d1(KPrintF(__FUNC__ "/%ld UseWindowSizes = %ld\n", __LINE__, UseWindowSizes);) + } + else if (0 == Stricmp(OptName, "Persist_FileName")) + { + char *dp; + size_t l; + char StopChar = '\0'; + + if ('"' == *lp) + { + lp++; + StopChar = '"'; + } + + for (dp=Persist_FileName, l=sizeof(Persist_FileName); + l > 1 && *lp && *lp != StopChar; ) + { + *dp++ = *lp++; + l--; + } + *dp = '\0'; + + d1(kprintf(__FUNC__ "/%ld Persist_FileName = <%s>\n", __LINE__, Persist_FileName);) + } + } + else + { + break; + } + } + + Close(fh); +} + +//---------------------------------------------------------------------------- + +static BOOL ExistsDevice(CONST_STRPTR Path) +{ + char DeviceName[256]; + short n; + char *dp; + struct DosList *dl, *dlFound; + + n = sizeof(DeviceName); + dp = DeviceName; + while (*Path && ':' != *Path && n > 1) + { + *dp++ = *Path++; + n--; + } + *dp = '\0'; + + dl = LockDosList(LDF_VOLUMES | LDF_DEVICES | LDF_ASSIGNS | LDF_READ); + + dlFound = FindDosEntry(dl, DeviceName, LDF_VOLUMES | LDF_DEVICES | LDF_ASSIGNS); + + d(kprintf(__FUNC__ "/%ld Dev=<%s> dlFound=%08lx\n", __LINE__, DeviceName, dlFound)); + + UnLockDosList(LDF_VOLUMES | LDF_DEVICES | LDF_ASSIGNS | LDF_READ); + + return (BOOL) (dlFound != NULL); +} + +//---------------------------------------------------------------------------- + +static struct OpenNode *FindNamedNode(CONST_STRPTR Path) +{ + struct OpenNode *OldNode; + + ObtainSemaphoreShared(&PersistSema); + + for (OldNode = (struct OpenNode *) OpenList.lh_Head; OldNode != (struct OpenNode *) &OpenList.lh_Tail; ) + { + struct OpenNode *NextNode = (struct OpenNode *) OldNode->on_Node.ln_Succ; + + if (0 == Stricmp(OldNode->on_Path, Path) && !OldNode->on_Iconified) + { + ReleaseSemaphore(&PersistSema); + return OldNode; + } + + OldNode = NextNode; + } + + ReleaseSemaphore(&PersistSema); + + return NULL; +} + +//---------------------------------------------------------------------------- + +static struct ScaWindowStruct *FindWindowByLock(BPTR xLock) +{ + struct ScaWindowList *swList = SCA_LockWindowList(SCA_LockWindowList_Shared); + struct ScaWindowStruct *Result = NULL; + + d(kprintf(__FUNC__ "/%ld: xLock=%08lx\n", __LINE__, xLock)); + + if (swList) + { + struct ScaWindowStruct *swi; + + for (swi=swList->wl_WindowStruct; NULL == Result && swi; swi = (struct ScaWindowStruct *) swi->ws_Node.mln_Succ) + { + d(kprintf(__FUNC__ "/%ld: swi=%08lx Lock=%08lx Same=%ld\n", __LINE__, \ + swi, swi->ws_Lock, SameLock(swi->ws_Lock, xLock))); + + if (LOCK_SAME == SameLock(swi->ws_Lock, xLock)) + { + d(kprintf(__FUNC__ "/%ld: swi=%08lx\n", __LINE__, swi)); + Result = swi; + } + } + + if (NULL == Result) + SCA_UnLockWindowList(); + } + + d(kprintf(__FUNC__ "/%ld: Result=%08lx\n", __LINE__, Result)); + + return Result; +} + +//---------------------------------------------------------------------------- + +static BOOL StartUpdaterProcess(void) +{ + STATIC_PATCHFUNC(UpdaterProcess) + + // CreateNewProc() + UpdaterProc = CreateNewProcTags(NP_Name, (ULONG) "Scalos_PersistentWindowsUpdater", + NP_Priority, 0, + NP_Entry, (ULONG) PATCH_NEWFUNC(UpdaterProcess), + NP_StackSize, 32768, + TAG_END); + if (UpdaterProc == NULL) + { +// alarm("StartReOpenProcess: CreateProc() failed"); + return FALSE; + } + + return TRUE; +} + +//---------------------------------------------------------------------------- + +static void KillUpdaterProcess(void) +{ + if (UpdaterProc) + { + Signal(&UpdaterProc->pr_Task, SIGF_ABORT); + UpdaterProc = NULL; + Delay(4); + } +} + +//---------------------------------------------------------------------------- + +static void TriggerUpdater(void) +{ + d1(KPrintF("%s/%s/%ld UpdaterProc=%08lx UpdaterProcSignal=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, UpdaterProc, UpdaterProcSignal)); + + if (UpdaterProc && UpdaterProcSignal) + { + Signal(&UpdaterProc->pr_Task, UpdaterProcSignal); + } +} + +//---------------------------------------------------------------------------- + +static BOOL InitProcessTimer(struct ProcessTimerInfo *Timer) +{ +/// + BYTE odError; + + memset(Timer, 0, sizeof(struct ProcessTimerInfo)); + + Timer->ppt_ioPort = CreateMsgPort(); + if (NULL == Timer->ppt_ioPort) + return FALSE; + + d1(kprintf("%s/%s/%ld: ioPort=%08lx\n", __FILE__, __FUNC__, __LINE__, Timer->ppt_ioPort)); + + Timer->ppt_TimeReq = (T_TIMEREQUEST *) CreateIORequest(Timer->ppt_ioPort, sizeof(T_TIMEREQUEST )); + if (NULL == Timer->ppt_TimeReq) + return FALSE; + + d1(kprintf("%s/%s/%ld: TimeReq=%08lx\n", __FILE__, __FUNC__, __LINE__, Timer->ppt_TimeReq)); + + odError = OpenDevice(TIMERNAME, UNIT_VBLANK, &Timer->ppt_TimeReq->tr_node, 0); + d1(kprintf("%s/%s/%ld: OpenDevice returned %ld\n", __FILE__, __FUNC__, __LINE__, odError)); + if (0 != odError) + return FALSE; + + Timer->ppt_timerOpen = TRUE; + + return TRUE; +/// +} + +//---------------------------------------------------------------------------- + +static void CleanupProcessTimer(struct ProcessTimerInfo *Timer) +{ +/// + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + if (Timer->ppt_TimeReq) + { + if (Timer->ppt_timerPending) + { + AbortIO((struct IORequest *) Timer->ppt_TimeReq); + WaitIO((struct IORequest *) Timer->ppt_TimeReq); + + Timer->ppt_timerPending = FALSE; + } + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + if (Timer->ppt_timerOpen) + { + CloseDevice(&Timer->ppt_TimeReq->tr_node); + Timer->ppt_timerOpen = FALSE; + } + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + DeleteIORequest((struct IORequest *) Timer->ppt_TimeReq); + Timer->ppt_TimeReq = NULL; + } + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + if (Timer->ppt_ioPort) + { + DeleteMsgPort(Timer->ppt_ioPort); + Timer->ppt_ioPort = NULL; + } + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); +/// +} + +//---------------------------------------------------------------------------- + +static SAVEDS(int) UpdaterProcess(void) +{ + struct ProcessTimerInfo UpdateTimer; + struct Process *myProc = (struct Process *) FindTask(NULL); + APTR prWindowPtr; + + memset(&UpdateTimer, 0, sizeof(UpdateTimer)); + + prWindowPtr = myProc->pr_WindowPtr; + myProc->pr_WindowPtr = (APTR) ~0; // suppress error requesters + + d1(KPrintF("%s/%s/%ld START\n", __FILE__, __FUNC__, __LINE__);) + + do { + ULONG ioMask; + BYTE signal; + + signal = AllocSignal(-1); + d1(KPrintF("%s/%s/%ld: signal=%ld\n", __FILE__, __FUNC__, __LINE__, signal)); + if (-1 == signal) + break; + UpdaterProcSignal = 1 << signal; + d1(KPrintF("%s/%s/%ld: UpdaterProcSignal=%08lx\n", __FILE__, __FUNC__, __LINE__, UpdaterProcSignal)); + + if (!InitProcessTimer(&UpdateTimer)) + break; + + d1(KPrintF("%s/%s/%ld: InitProcessTimer succeeded\n", __FILE__, __FUNC__, __LINE__)); + + ioMask = 1 << UpdateTimer.ppt_ioPort->mp_SigBit; + + d1(KPrintF("%s/%s/%ld: ioMask=%08lx\n", __FILE__, __FUNC__, __LINE__, ioMask)); + + do { + ULONG RcvdMask; + + d1(KPrintF("%s/%s/%ld: Mask=%08lx\n", __FILE__, __FUNC__, __LINE__, UpdaterProcSignal | ioMask | SIGF_ABORT)); + + RcvdMask = Wait(UpdaterProcSignal | ioMask | SIGF_ABORT); + + d1(KPrintF("%s/%s/%ld: RcvdMask=%08lx\n", __FILE__, __FUNC__, __LINE__, RcvdMask)); + + if (SIGF_ABORT & RcvdMask) + { + d1(KPrintF("%s/%s/%ld SIGF_ABORT\n", __FILE__, __FUNC__, __LINE__);) + break; + } + + if (RcvdMask & UpdaterProcSignal) + { + // Received new update trigger + d1(KPrintF("%s/%s/%ld: Triggered! \n", __FILE__, __FUNC__, __LINE__)); + + if (UpdateTimer.ppt_timerPending) + { + d1(KPrintF("%s/%s/%ld: Abort running timer\n", __FILE__, __FUNC__, __LINE__)); + + AbortIO((struct IORequest *) UpdateTimer.ppt_TimeReq); + WaitIO((struct IORequest *) UpdateTimer.ppt_TimeReq); + + UpdateTimer.ppt_timerPending = FALSE; + RcvdMask &= ~ioMask; + } + + // Restart timer + UpdateTimer.ppt_TimeReq->tr_node.io_Command = TR_ADDREQUEST; + UpdateTimer.ppt_TimeReq->tr_time.tv_micro = 0; + UpdateTimer.ppt_TimeReq->tr_time.tv_secs = 1; + + BeginIO((struct IORequest *) UpdateTimer.ppt_TimeReq); + UpdateTimer.ppt_timerPending = TRUE; + } + + if (RcvdMask & ioMask) + { + // Update timer expired + d1(KPrintF("%s/%s/%ld: Update timer expired, timerPending=%ld\n", __FILE__, __FUNC__, __LINE__, UpdateTimer.ppt_timerPending)); + + if (UpdateTimer.ppt_timerPending) + { + WaitIO((struct IORequest *) UpdateTimer.ppt_TimeReq); + UpdateTimer.ppt_timerPending = FALSE; + } + + RewriteNodeListFile(); + } + } while (1); + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + } while (0); + + // restore pr_WindowPtr + myProc->pr_WindowPtr = prWindowPtr; + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + CleanupProcessTimer(&UpdateTimer); + + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); + + return 0; +} + +//---------------------------------------------------------------------------- + +#ifdef __SASC + +void _XCEXIT(long x) +{ + (void) x; +} + +#else /* __SASC */ + +#if !defined(__MORPHOS__) && !defined(__AROS__) +// Replacement for SAS/C library functions + +static char *stpblk(CONST_STRPTR q) +{ + while (q && *q && isspace((int) *q)) + q++; + + return (char *) q; +} +#endif /* __MORPHOS__ */ + +#if !defined(__amigaos4__) + +void exit(int x) +{ + (void) x; + while (1) + ; +} + +APTR _WBenchMsg; + +#endif /* __amigaos4__ */ + +#endif /* __SASC */ + +//---------------------------------------------------------------------------- + diff --git a/scalos/Plugins/OOP/wb39_plugin/persist/plugin_data.h b/scalos/Plugins/OOP/wb39_plugin/persist/plugin_data.h new file mode 100644 index 000000000..cd0cf5bc4 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/persist/plugin_data.h @@ -0,0 +1,36 @@ +// plugin_data.h +// $Date$ +// $Revision$ + +#ifndef PLUGIN_DATA_H_INCLUDED +#define PLUGIN_DATA_H_INCLUDED + +#include +#include + +#define PLUGIN_TYPE OOP + +#define LIB_VERSION 39 +#define LIB_REVISION 26 + +#define LIB_NAME "persist.plugin" +#define LIB_VERSTRING "$VER: persist.plugin " \ + STR(LIB_VERSION) "." STR(LIB_REVISION) \ + " " __DATE__ " " COMPILER_STRING \ + " ©1999" CURRENTYEAR " The Scalos Team" + + +#define CI_CLASSNAME "Window.sca" +#define CI_SUPERCLASSNAME "Window.sca" +#define CI_PLUGINNAME "Persistant Windows" +#define CI_DESCRIPTION "Remembers all open Workbench windows" COMPILER_STRING +#define CI_AUTHOR "Jürgen Lachmann" +#define CI_HOOKFUNC persistHookFunc + +//---------------------------------------------------------------------------- +// code and includes to define the structs and functions used above + +#include "Persist.h" + +#endif /* PLUGUN_DATA_H_INCLUDED */ + diff --git a/scalos/Plugins/OOP/wb39_plugin/plugin_data.h b/scalos/Plugins/OOP/wb39_plugin/plugin_data.h new file mode 100644 index 000000000..0316db3b9 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/plugin_data.h @@ -0,0 +1,36 @@ +// plugin_data.h +// $Date$ +// $Revision$ + +#ifndef PLUGIN_DATA_H_INCLUDED +#define PLUGIN_DATA_H_INCLUDED + +#include +#include + +#define PLUGIN_TYPE OOP + +#define LIB_VERSION 45 +#define LIB_REVISION 34 + +#define LIB_NAME "wb39.plugin" +#define LIB_VERSTRING "$VER: wb39.plugin " \ + STR(LIB_VERSION) "." STR(LIB_REVISION) \ + " (11.02.2008) " COMPILER_STRING \ + " ©1999" CURRENTYEAR " The Scalos Team" + + +#define CI_CLASSNAME "Window.sca" +#define CI_SUPERCLASSNAME "Window.sca" +#define CI_PLUGINNAME "Scalos API Extension" +#define CI_DESCRIPTION "Extends Scalos API towards OS3.9. " COMPILER_STRING +#define CI_AUTHOR "Jürgen Lachmann" +#define CI_HOOKFUNC myHookFunc + +//---------------------------------------------------------------------------- +// code and includes to define the structs and functions used above + +#include "wb39.h" + +#endif /* PLUGUN_DATA_H_INCLUDED */ + diff --git a/scalos/Plugins/OOP/wb39_plugin/test.c b/scalos/Plugins/OOP/wb39_plugin/test.c new file mode 100644 index 000000000..471dd4934 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/test.c @@ -0,0 +1,305 @@ +// test.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +//#include +#include +#include +#include +#include +#include + +#if 0 +#include +#include "wb39.h" +#endif + +#include + +static void PrintPathList(BPTR bList); +static SAVEDS(ULONG) cwbselHookFunc(struct Hook *hook, APTR reserved, struct IconSelectMsg *ism); + + +struct Library *WorkbenchBase; +extern struct ExecBase *SysBase; + +#ifdef __amigaos4__ +struct WorkbenchIFace *IWorkbench; +#endif + +struct Hook cwbselHook; + +int main() +{ + BOOL Result; + LONG Found = FALSE; + ULONG stackSize = 0; + struct List *dList = NULL; + char *fName = "HD1-6GB:Bilder/Normal"; + char *kName; + int ch; + + + WorkbenchBase = OpenLibrary(WORKBENCH_NAME, 44); + if (NULL == WorkbenchBase) + return 10; +#ifdef __amigaos4__ + IWorkbench = (struct WorkbenchIFace *)GetInterface(WorkbenchBase, "main", 1, NULL); + if (NULL == IWorkbench) + return 10; +#endif + +// printf("wt_fDragging = %08lx\n", offsetof(struct extScaWindowTask, wt_fDragging)); + +#if 1 + printf("======================================================\n"); + + Result = WorkbenchControl(NULL, + WBCTRLA_GetDefaultStackSize, (ULONG) &stackSize, + TAG_END); + printf("WorkbenchControl(WBCTRLA_GetDefaultStackSize) returned %d DefaultStackSize=%lu\n", Result, (unsigned long) stackSize); + + printf("======================================================\n"); + + Result = WorkbenchControl(NULL, + WBCTRLA_GetProgramList, (ULONG) &dList, + TAG_END); + printf("WorkbenchControl(WBCTRLA_GetProgramList) returned %d List=%08lx\n", Result, (unsigned long) dList); + + if (dList) + { + struct Node *xNode; + + for (xNode=dList->lh_Head; xNode != (struct Node *) &dList->lh_Tail; xNode=xNode->ln_Succ) + { + printf(" Node=%08lx Type=%02x Name=<%s>\n", (unsigned long) xNode, xNode->ln_Type, xNode->ln_Name); + } + + Result = WorkbenchControl(NULL, + WBCTRLA_FreeProgramList, (ULONG) dList, + TAG_END); + + printf("WorkbenchControl(WBCTRLA_FreeProgramList) returned %d\n", Result); + } + + printf("======================================================\n"); + + Result = WorkbenchControl(NULL, + WBCTRLA_GetOpenDrawerList, (ULONG) &dList, + TAG_END); + printf("WorkbenchControl(WBCTRLA_GetOpenDrawerList) returned %d List=%08lx\n", Result, (unsigned long) dList); + + if (dList) + { + struct Node *xNode; + + for (xNode=dList->lh_Head; xNode != (struct Node *) &dList->lh_Tail; xNode=xNode->ln_Succ) + { + printf(" Node=%08lx Type=%02x Name=<%s>\n", (unsigned long) xNode, xNode->ln_Type, xNode->ln_Name); + } + + Result = WorkbenchControl(NULL, + WBCTRLA_FreeOpenDrawerList, (ULONG) dList, + TAG_END); + + printf("WorkbenchControl(WBCTRLA_FreeOpenDrawerList) returned %d\n", Result); + } + + printf("======================================================\n"); + + Result = WorkbenchControl(NULL, + WBCTRLA_GetHiddenDeviceList, (ULONG) &dList, + TAG_END); + printf("WorkbenchControl(WBCTRLA_GetHiddenDeviceList) returned %d List=%08lx\n", Result, (unsigned long) dList); + + if (dList) + { + struct Node *xNode; + + for (xNode=dList->lh_Head; xNode != (struct Node *) &dList->lh_Tail; xNode=xNode->ln_Succ) + { + printf(" Node=%08lx Type=%02x Name=<%s>\n", (unsigned long) xNode, xNode->ln_Type, xNode->ln_Name); + } + + Result = WorkbenchControl(NULL, + WBCTRLA_FreeHiddenDeviceList, (ULONG) dList, + TAG_END); + + printf("WorkbenchControl(WBCTRLA_FreeHiddenDeviceList) returned %d\n", Result); + } + + printf("======================================================\n"); + + Result = WorkbenchControl(NULL, + WBCTRLA_GetSelectedIconList, (ULONG) &dList, + TAG_END); + printf("WorkbenchControl(WBCTRLA_GetSelectedIconList) returned %d List=%08lx\n", Result, (unsigned long) dList); + + if (dList) + { + struct Node *xNode; + + for (xNode=dList->lh_Head; xNode != (struct Node *) &dList->lh_Tail; xNode=xNode->ln_Succ) + { + printf(" Node=%08lx Type=%02x Name=<%s>\n", (unsigned long) xNode, xNode->ln_Type, xNode->ln_Name); + } + + // WorkbenchControlA() + Result = WorkbenchControl(NULL, + WBCTRLA_FreeSelectedIconList, (ULONG) dList, + TAG_END); + + printf("WorkbenchControl(WBCTRLA_FreeSelectedIconList) returned %d\n", Result); + } + + printf("======================================================\n"); + + Result = WorkbenchControl(fName, + WBCTRLA_IsOpen, (ULONG) &Found, + TAG_END); + printf("WorkbenchControl(<%s>, WBCTRLA_IsOpen) returned %d, Open=%ld\n", fName, Result, (long) Found); + + printf("======================================================\n"); + + dList = NULL; + Result = WorkbenchControl(fName, + WBCTRLA_DuplicateSearchPath, (ULONG) &dList, + TAG_END); + printf("WorkbenchControl(WBCTRLA_DuplicateSearchPath) returned %d, List=%08lx\n", Result, (unsigned long) dList); + + if (dList) + PrintPathList((BPTR) dList); + + Result = WorkbenchControl(fName, + WBCTRLA_FreeSearchPath, (ULONG) dList, + TAG_END); + printf("WorkbenchControl(WBCTRLA_FreeSearchPath) returned %d\n", Result); + + printf("======================================================\n"); + + kName = "SYS:"; + printf("Press \"O\"+Enter to open %s Drawer...\n", kName); + ch = getchar(); + + if ('O' == toupper(ch)) + { + // OpenWorkbenchObjectA() + Result = OpenWorkbenchObject(kName, TAG_END); + printf("OpenWorkbenchObject(%s) returned %d\n", kName, Result); + + if (Result) + { + printf("======================================================\n"); + + Delay(50 * 3); // Wait until drawer opened + + SETHOOKFUNC(cwbselHook, cwbselHookFunc); + cwbselHook.h_Data = NULL; + + kName = "SYS:"; + // ChangeWorkbenchSelectionA() + Result = ChangeWorkbenchSelection(kName, &cwbselHook, TAG_END); + printf("ChangeWorkbenchSelection(%s) returned %d\n", kName, Result); + + printf("======================================================\n"); + + printf("Press Enter to close %s Drawer...\n", kName); + getchar(); + + kName = "SYS:"; + Result = CloseWorkbenchObject(kName, TAG_END); + printf("CloseWorkbenchObject(%s) returned %d\n", kName, Result); + } + } + + printf("======================================================\n"); + + kName = "HD1-6GB:PD/BasiliskII/src/sony.cpp"; + + // MakeWorkbenchObjectVisibleA() + Result = MakeWorkbenchObjectVisible(kName, + TAG_END); + printf("MakeWorkbenchObjectVisible(%s) returned %d\n", kName, Result); + + printf("======================================================\n"); +#endif +#ifdef __amigaos4__ + if (IWorkbench) + { + DropInterface((struct Interface *)IWorkbench); + IWorkbench = NULL; + } +#endif + if (WorkbenchBase) + { + CloseLibrary(WorkbenchBase); + WorkbenchBase = NULL; + } + + return 0; +} + + +static void PrintPathList(BPTR bList) +{ + struct AssignList *aList; + + aList = BADDR(bList); + while (aList) + { + char Buffer[250]; + + NameFromLock(aList->al_Lock, Buffer, sizeof(Buffer)); + printf("Path <%s>\n", Buffer); + + aList = BADDR(aList->al_Next); + } +} + + +static SAVEDS(ULONG) cwbselHookFunc(struct Hook *hook, APTR reserved, struct IconSelectMsg *ism) +{ +#if 0 + printf("Length = %ld\n", ism->ism_Length); + printf("Drawer = %08lx\n", ism->ism_Drawer); + printf("Name = <%s>\n", ism->ism_Name); + printf("Type = %ld\n", ism->ism_Type); + printf("Selected= %ld\n", ism->ism_Selected); + printf("Tags = %08lx\n", ism->ism_Tags); + printf("DrwWind = %08lx\n", ism->ism_DrawerWindow); + printf("ParWind = %08lx\n", ism->ism_ParentWindow); + printf("Left = %ld\n", ism->ism_Left); + printf("Top = %ld\n", ism->ism_Top); + printf("Width = %ld\n", ism->ism_Width); + printf("Height = %ld\n", ism->ism_Height); +#endif + if (0 == stricmp(ism->ism_Name, "devs")) + ism->ism_Top -= 20; + +// if (0 == stricmp(ism->ism_Name, "Trashcan")) +// return ISMACTION_Stop; + + // Select "Prefs" drawer + if (0 == stricmp("Prefs", ism->ism_Name)) + return ISMACTION_Select; + + return ISMACTION_Ignore; +} + diff --git a/scalos/Plugins/OOP/wb39_plugin/volumegauge/VolumeGauge.c b/scalos/Plugins/OOP/wb39_plugin/volumegauge/VolumeGauge.c new file mode 100644 index 000000000..784a4a592 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/volumegauge/VolumeGauge.c @@ -0,0 +1,474 @@ +// VolumeGauge.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include + +#include "volumegauge.h" + +// aus Amiga.lib +#if !defined(__amigaos4__) && !defined(__AROS__) +extern ULONG HookEntry(struct Hook *, Object *, APTR); +#endif + + +static struct RastPort *NewObtainGIRPort(struct GadgetInfo *gInfo); + + +/***********************************************************/ +/**************** Class specifics ****************/ +/***********************************************************/ + +// The functions in this module +static ULONG INTERRUPT InitVolumeGauge(Class *cl, struct Gadget *g, struct opSet *ops); +static ULONG LayoutVolumeGauge(Class *cl, struct Gadget *g, struct gpLayout *gpr); +static ULONG RenderVolumeGauge(Class *, struct Gadget *, struct gpRender *); +static ULONG UpdateVolumeGauge(Class *cl, struct Gadget *g, struct opSet *msg); +static void DrawGauge(struct RastPort *rp, struct VolumeGaugeInst *inst, + struct Gadget *g, struct GadgetInfo *GInfo, short BarHeight); +static void DrawTick(struct RastPort *rp, struct VolumeGaugeInst *inst, + short x, short y, short TickSize, BOOL active); +static short GetVolumeGaugeHeight(struct VolumeGaugeInst *inst, struct Gadget *g, struct GadgetInfo *GInfo); +static SAVEDS(ULONG) dispatchVolumeGaugeGad(Class *cl, Object *o, Msg msg); +static void ScaleValue(struct VolumeGaugeInst *inst); +static long GetLeftEdge(const struct Gadget *g, const struct GadgetInfo *gi); +static long GetTopEdge(const struct Gadget *g, const struct GadgetInfo *gi); +static long GetWidth(const struct Gadget *g, const struct GadgetInfo *gi); +static long GetHeight(const struct Gadget *g, const struct GadgetInfo *gi); + + +static Class *VolumeGaugecl; + + +/***********************************************************/ +/** Make the class and set up the dispatcher's hook **/ +/***********************************************************/ +Class *VOLUMEGAUGE_GetClass(void) +{ + if (VolumeGaugecl) + return VolumeGaugecl; + + VolumeGaugecl = MakeClass( NULL, (STRPTR) GADGETCLASS, NULL, sizeof(struct VolumeGaugeInst), 0); + + if (VolumeGaugecl) + { + // initialize the cl_Dispatcher Hook + SETHOOKFUNC(VolumeGaugecl->cl_Dispatcher, dispatchVolumeGaugeGad); + } + + return VolumeGaugecl; +} + +/***********************************************************/ +/****************** Free the class ****************/ +/***********************************************************/ +BOOL freeVolumeGaugeGadClass(void) +{ + return (FreeClass(VolumeGaugecl)); +} + +/***********************************************************/ +/********** The VolumeGauge class dispatcher *********/ +/***********************************************************/ +static SAVEDS(ULONG) INTERRUPT dispatchVolumeGaugeGad(Class *cl, Object *o, Msg msg) +{ + struct VolumeGaugeInst *inst; + ULONG retval = FALSE; + Object *object; + + switch (msg->MethodID) + { + case OM_NEW: /* First, pass up to superclass */ + if (object = (Object *) DoSuperMethodA(cl, o, msg)) + retval = InitVolumeGauge(cl, (struct Gadget *) object, (struct opSet *) msg); + break; + + case OM_DISPOSE: +// inst = INST_DATA(cl, o); + DoSuperMethodA(cl, o, msg); + break; + + case GM_HITTEST: + retval = 0; + break; + + case GM_LAYOUT: + retval = LayoutVolumeGauge(cl, (struct Gadget *)o, (struct gpLayout *)msg); + break; + + case GM_RENDER: + retval = RenderVolumeGauge(cl, (struct Gadget *)o, (struct gpRender *)msg); + break; + + case OM_SET: + inst = INST_DATA(cl, o); + + { + DoSuperMethodA(cl, o, msg); /* Größe & Ort ändern */ + + inst->MinValue = GetTagData(VOLUMEGAUGE_Min, inst->MinValue, ((struct opSet *)msg)->ops_AttrList); + inst->MaxValue = GetTagData(VOLUMEGAUGE_Max, inst->MaxValue, ((struct opSet *)msg)->ops_AttrList); + inst->Level = GetTagData(VOLUMEGAUGE_Level, inst->Level, ((struct opSet *)msg)->ops_AttrList); + + ScaleValue(inst); + + retval = UpdateVolumeGauge(cl, (struct Gadget *)o, (struct opSet *)msg); + } + break; + + default: + retval = DoSuperMethodA(cl, o, msg); + break; + } + + return(retval); +} + + +/*************************************************************************************************/ +/******************************* Initialize the gadget. **************************************/ +/*************************************************************************************************/ +static ULONG INTERRUPT InitVolumeGauge(Class *cl, struct Gadget *g, struct opSet *ops) +{ + struct VolumeGaugeInst *inst = INST_DATA(cl, (Object *)g); + + g->Width = 0; + + inst->LastLevel = ~0; + inst->ScaleFactor = 0; + + inst->MinValue = GetTagData(VOLUMEGAUGE_Min, 0, ops->ops_AttrList); + inst->MaxValue = GetTagData(VOLUMEGAUGE_Max, 0, ops->ops_AttrList); + inst->Level = GetTagData(VOLUMEGAUGE_Level, 0, ops->ops_AttrList); + inst->Ticks = GetTagData(VOLUMEGAUGE_Ticks, 0, ops->ops_AttrList); + inst->ShortTicks= GetTagData(VOLUMEGAUGE_ShortTicks, 0, ops->ops_AttrList); + inst->TickSize = GetTagData(VOLUMEGAUGE_TickSize, 6, ops->ops_AttrList); + + ScaleValue(inst); + + return (ULONG) g; +} + + +/*************************************************************************************************/ +/************************************* Layout the gadget. ************************************/ +/*************************************************************************************************/ +static ULONG LayoutVolumeGauge(Class *cl, struct Gadget *g, struct gpLayout *gpl) +{ + struct VolumeGaugeInst *inst = INST_DATA(cl, (Object *)g); + ULONG retval = TRUE; + + d1(kprintf("%s/%s/%ld: GInfo=%08lx\n", __FILE__, __FUNC__, __LINE__, gpl->gpl_GInfo)); + + if (gpl->gpl_GInfo && gpl->gpl_GInfo->gi_Window) + { + Object *CloseImage; + ULONG GWidth = 14; + + d1(kprintf("%s/%s/%ld: Window=%08lx\n", __FILE__, __FUNC__, __LINE__, gpl->gpl_GInfo->gi_Window)); + d1(kprintf("%s/%s/%ld: BorderLeft=%ld BorderRight=%ld\n", __FILE__, __FUNC__, __LINE__, gpl->gpl_GInfo->gi_Window->BorderLeft, gpl->gpl_GInfo->gi_Window->BorderRight)); + + CloseImage = NewObject(NULL, SYSICLASS, + SYSIA_Which, CLOSEIMAGE, + SYSIA_DrawInfo, gpl->gpl_GInfo->gi_DrInfo, + TAG_END); + if (CloseImage) + { + GetAttr(IA_Width, CloseImage, &GWidth); + GWidth--; + + DisposeObject(CloseImage); + } + + if (gpl->gpl_GInfo->gi_Window->BorderLeft < GWidth) + gpl->gpl_GInfo->gi_Window->BorderLeft = GWidth; + if (gpl->gpl_GInfo->gi_Window->BorderLeft < gpl->gpl_GInfo->gi_Window->BorderRight) + gpl->gpl_GInfo->gi_Window->BorderLeft = gpl->gpl_GInfo->gi_Window->BorderRight; + + SetAttrs(g, + GA_Left, 4, + GA_Top, gpl->gpl_GInfo->gi_Window->BorderTop + 2, + GA_Width, gpl->gpl_GInfo->gi_Window->BorderLeft - 4 - 4, + GA_RelHeight, - (gpl->gpl_GInfo->gi_Window->BorderTop + 2) - gpl->gpl_GInfo->gi_Window->BorderBottom, + TAG_END); + + // Get the pens for drawing + inst->InactiveShinePen = inst->ActiveShinePen = gpl->gpl_GInfo->gi_DrInfo->dri_Pens[SHINEPEN]; + inst->InactiveShadowPen = inst->ActiveShadowPen = gpl->gpl_GInfo->gi_DrInfo->dri_Pens[SHADOWPEN]; + inst->ActiveFillPen = gpl->gpl_GInfo->gi_DrInfo->dri_Pens[FILLPEN]; + inst->InactiveFillPen = gpl->gpl_GInfo->gi_DrInfo->dri_Pens[DETAILPEN]; + +#if DRI_VERSION >= 3 && !defined(__MORPHOS__) + if (gpl->gpl_GInfo->gi_DrInfo->dri_Version >= 3) + { + inst->ActiveShinePen = gpl->gpl_GInfo->gi_DrInfo->dri_Pens[FILLSHINEPEN]; + inst->ActiveShadowPen = gpl->gpl_GInfo->gi_DrInfo->dri_Pens[FILLSHADOWPEN]; + inst->InactiveFillPen = gpl->gpl_GInfo->gi_DrInfo->dri_Pens[INACTIVEFILLPEN]; + inst->InactiveShinePen = gpl->gpl_GInfo->gi_DrInfo->dri_Pens[INACTIVEFILLSHINEPEN]; + inst->InactiveShadowPen = gpl->gpl_GInfo->gi_DrInfo->dri_Pens[INACTIVEFILLSHADOWPEN]; + } +#endif + } + + return(retval); +} + + +/*************************************************************************************************/ +/******************************* Erase and rerender the gadget. ******************************/ +/*************************************************************************************************/ +static ULONG INTERRUPT RenderVolumeGauge(Class *cl, struct Gadget *g, struct gpRender *gpr) +{ + struct VolumeGaugeInst *inst = INST_DATA(cl, (Object *)g); + ULONG retval = TRUE; + BOOL active = (gpr->gpr_GInfo->gi_Window->Flags & WFLG_WINDOWACTIVE) != 0; + + d1(kprintf("%s/%s/%ld: RPort=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + gpr->gpr_RPort)); + + if (gpr->gpr_RPort) + { + short x = GetLeftEdge(g, gpr->gpr_GInfo); + short y = GetTopEdge(g, gpr->gpr_GInfo); + short w = GetWidth(g, gpr->gpr_GInfo); + short h = GetHeight(g, gpr->gpr_GInfo); + short y2 = y + h - 1; + short x2 = x + w - 1; + + SetAPen(gpr->gpr_RPort, active ? inst->ActiveShadowPen : inst->InactiveShadowPen); + + Move(gpr->gpr_RPort, x2, y); + Draw(gpr->gpr_RPort, x, y); + Draw(gpr->gpr_RPort, x, y2); + + SetAPen(gpr->gpr_RPort, active ? inst->ActiveShinePen : inst->InactiveShinePen); + + Move(gpr->gpr_RPort, x2, 1 + y); + Draw(gpr->gpr_RPort, x2, y2+1); + Draw(gpr->gpr_RPort, x + 1, y2+1); + + DrawGauge(gpr->gpr_RPort, inst, g, + gpr->gpr_GInfo, + GetVolumeGaugeHeight(inst, g, gpr->gpr_GInfo)); + } + + return(retval); +} + + +static ULONG INTERRUPT UpdateVolumeGauge(Class *cl, struct Gadget *g, struct opSet *ops) +{ + struct VolumeGaugeInst *inst = INST_DATA(cl, (Object *)g); + struct RastPort *rp; + ULONG retval = TRUE; + + rp = NewObtainGIRPort(ops->ops_GInfo); + if (rp) + { + short BarHeight; + + BarHeight = GetVolumeGaugeHeight(inst, g, ops->ops_GInfo); + + if (BarHeight != inst->LastLevel) + { + DrawGauge(rp, inst, g, ops->ops_GInfo, BarHeight); + + inst->LastLevel = BarHeight; + } + + ReleaseGIRPort(rp); + } + + return(retval); +} + + +static void DrawGauge(struct RastPort *rp, struct VolumeGaugeInst *inst, + struct Gadget *g, struct GadgetInfo *GInfo, short BarHeight) +{ + short x = GetLeftEdge(g, GInfo) + 1; + short y1, y = GetTopEdge(g, GInfo) + 1; + short w = GetWidth(g, GInfo) - 2; + short h = GetHeight(g, GInfo) - 2; + short y2 = y + h - 1; + short x2 = x + w - 1; + short n; + BOOL active = (GInfo->gi_Window->Flags & WFLG_WINDOWACTIVE) != 0; + + y1 = y; + y = y + h - BarHeight; + + SetAPen(rp, active ? inst->ActiveFillPen : inst->InactiveFillPen); + + RectFill(rp, x, y1, x2, y2); + + SetAPen(rp, active ? inst->ActiveShinePen : inst->InactiveShinePen); + + Move(rp, x2, y); + Draw(rp, x, y); + Draw(rp, x, y + BarHeight); + + SetAPen(rp, active ? inst->ActiveShadowPen : inst->InactiveShadowPen); + + Move(rp, x2, 1 + y); + Draw(rp, x2, y + BarHeight); + Draw(rp, x + 1, y + BarHeight); + + for (n=0; n<=inst->Ticks; n++) + { + short yTick = y1 + h - ((n * h) / inst->Ticks); + + if (yTick < y && yTick > y1) + { + DrawTick(rp, inst, x, yTick, inst->TickSize, active); + } + + if (inst->ShortTicks && yTick < y) + { + yTick += h / (2 * inst->Ticks); + + if (yTick < y) + { + DrawTick(rp, inst, x, yTick, inst->TickSize / 2, active); + } + } + } +} + + +static void DrawTick(struct RastPort *rp, struct VolumeGaugeInst *inst, short x, short y, short TickSize, BOOL active) +{ + SetAPen(rp, active ? inst->ActiveShinePen : inst->InactiveShinePen); + Move(rp, x, y); + Draw(rp, x + TickSize, y); + + SetAPen(rp, active ? inst->ActiveShadowPen : inst->InactiveShadowPen); + Move(rp, x, y-1); + Draw(rp, x + TickSize, y-1); +} + + +static short GetVolumeGaugeHeight(struct VolumeGaugeInst *inst, struct Gadget *g, struct GadgetInfo *GInfo) +{ + short BarHeight; + + if (inst->MaxValue - inst->MinValue) + { + BarHeight = ((long)(GetHeight(g, GInfo) - 2l) * + ((inst->Level >> inst->ScaleFactor) - (inst->MinValue >> inst->ScaleFactor))) / + ((inst->MaxValue >> inst->ScaleFactor) - (inst->MinValue >> inst->ScaleFactor)); + } + else + BarHeight = 0; + + return BarHeight; +} + + +static void ScaleValue(struct VolumeGaugeInst *inst) +{ + ULONG val = inst->MaxValue; + + inst->ScaleFactor = 0; + while (val & 0xffff0000) + { + val = (val >> 1) & 0x7fffffff; + inst->ScaleFactor++; + } +} + + +static long GetLeftEdge(const struct Gadget *g, const struct GadgetInfo *gi) +{ + if (g->Flags & GFLG_RELRIGHT) + return gi->gi_Window->Width + g->LeftEdge; + + return g->LeftEdge; +} + + +static long GetTopEdge(const struct Gadget *g, const struct GadgetInfo *gi) +{ + if (g->Flags & GFLG_RELBOTTOM) + return gi->gi_Window->Height + g->TopEdge; + + return g->TopEdge; +} + + +static long GetWidth(const struct Gadget *g, const struct GadgetInfo *gi) +{ + if (g->Flags & GFLG_RELWIDTH) + return gi->gi_Window->Width + g->Width; + + return g->Width; +} + + +static long GetHeight(const struct Gadget *g, const struct GadgetInfo *gi) +{ + if (g->Flags & GFLG_RELHEIGHT) + return gi->gi_Window->Height + g->Height; + + return g->Height; +} + + +static struct RastPort *NewObtainGIRPort(struct GadgetInfo *gInfo) +{ + struct RastPort *Result; + + if (gInfo && gInfo->gi_Layer) + { + if (AttemptLockLayerRom(gInfo->gi_Layer)) + { + Forbid(); // no chance for anyone to lock Layers inbetween... + + UnlockLayerRom(gInfo->gi_Layer); // Got a lock, free it + Result = ObtainGIRPort(gInfo); // call original function + + Permit(); + } + else + { + // Attempt to lock the layer failed, return NULL + Result = NULL; + } + } + else + Result = ObtainGIRPort(gInfo); + + return Result; +} diff --git a/scalos/Plugins/OOP/wb39_plugin/volumegauge/config.mk b/scalos/Plugins/OOP/wb39_plugin/volumegauge/config.mk new file mode 100755 index 000000000..4a90eb3bc --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/volumegauge/config.mk @@ -0,0 +1,71 @@ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +COMMON_DIR = $(TOPLEVEL)/common/Plugin + +INCLUDES += -I$(COMMON_DIR) + +vpath %.c $(COMMON_DIR) + +############################################################################## + +include $(COMMON_DIR)/config.mk + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += -lmempools +# --verbose + +LFLAGS2 = $(LFLAGS) \ + -nostartfiles + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS2 = $(LFLAGS) \ + -nostartfiles \ +# + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +LFLAGS2 = $(LFLAGS) \ + -nostartfiles \ +# + +else + +############################################################################### +# AmigaOS + +LFLAGS += -lscalos \ + -lpreferences \ + -liconobject \ + -lmempools \ + -lstack \ + -lnix \ + -lnixmain \ + -lamiga21 \ + -lamiga \ + -lstubs \ + +endif +endif +endif diff --git a/scalos/Plugins/OOP/wb39_plugin/volumegauge/makefile b/scalos/Plugins/OOP/wb39_plugin/volumegauge/makefile new file mode 100644 index 000000000..77aba5e13 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/volumegauge/makefile @@ -0,0 +1,112 @@ +# makefile for Scalos volumegauge.plugin +# $Date$ +# using GNU make and SAS/C 6.58 + + +############################################################# + +CC = sc +AS = phxass +PRECOMP = INCLUDE:All.gst +LD = slink +LDFLAGS = quiet batch noicons sd +LDLIBS = LIB:sc.lib LIB:debug.lib LIB:amiga.lib +OBJDIR = .sasobj +DESTPLUG = Scalos:Plugins/OOP +COMMON_DIR = ../../../../common/Plugin + +.SUFFIXES: .plugin .plugin.debug + +############################################################# + +# Optimizer Flags +# Ignore Note 306: local function inlined: "InsertMH" +OPT_FLG = OPTIMIZE OPTINLOCAL OPTTIME OPTSCHED IGNORE=306,308 ERROR=87 +OPT_FLG2 = NOOPTIMIZE IGNORE=306,308 ERROR=87 + +ifdef DEBUG + CFLAGS = nostkchk nochkabort dbg=ff nover gst=$(PRECOMP) idlen=64 \ + idir=////include \ + idir=$(subst ../,/,$(COMMON_DIR)) + CSTARTUP = LIB:c.o +else + CFLAGS = nostkchk nochkabort $(OPT_FLG) dbg=f def=NDEBUG \ + def=NODEBUG nover gst=$(PRECOMP) idlen=64 \ + idir=////include \ + idir=$(subst ../,/,$(COMMON_DIR)) + CSTARTUP = LIB:cback.o +endif + +AFLAGS = quiet I=sc:Assembler_Headers + +############################################################# + +# Files for volumegauge.plugin +VOLGAUGENAME = volumegauge.plugin + +VOLGAUGECSRCS = $(COMMON_DIR)/plugin-classic.c \ + vg_plugin.c \ + VolumeGauge.c + +XSRCS = $(notdir $(VOLGAUGECSRCS)) +VOLGAUGEOBJS= $(XSRCS:%.c=$(OBJDIR)/$(notdir %).o) + +############################################################# + +LIBS = LIB:mempools.lib LIB:sc.lib LIB:debug.lib LIB:amiga.lib + +############################################################# + +all: $(VOLGAUGENAME) \ + $(VOLGAUGENAME).debug \ +# install +# clean + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +############################################################# + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-classic.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $*.c objectname $@ + +############################################################# + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-classic.c \ + $(COMMON_DIR)/plugin-common.c $(COMMON_DIR)/plugin.h plugin_data.h + +$(OBJDIR)/persist.o : Persist.c Persist.h plugin_data.h + +############################################################# + +$(VOLGAUGENAME): $(VOLGAUGEOBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(VOLGAUGEOBJS) TO $(VOLGAUGENAME) lib $(LIBS) $(LDFLAGS) STRIPDEBUG + +$(VOLGAUGENAME).debug: $(VOLGAUGEOBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(VOLGAUGEOBJS) TO $(VOLGAUGENAME).debug lib $(LIBS) $(LDFLAGS) ADDSYM + +############################################################# + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(VOLGAUGENAME).\033[0m\n' + @copy $(VOLGAUGENAME) $(DESTPLUG) clone + +############################################################# + +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + -@delete $(OBJS) \ + $(VOLGAUGENAME) \ + $(VOLGAUGENAME).debug + @printf '\033[0m' + +############################################################# diff --git a/scalos/Plugins/OOP/wb39_plugin/volumegauge/makefile-new b/scalos/Plugins/OOP/wb39_plugin/volumegauge/makefile-new new file mode 100755 index 000000000..6559ece6e --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/volumegauge/makefile-new @@ -0,0 +1,70 @@ +# $Date: 2011-08-02 00:13:23 +0200 (Di, 02. Aug 2011) $ +# $Revision: 816 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../../../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(BEGIN_OBJS) \ + $(OBJDIR)/vg_plugin.o \ + $(OBJDIR)/VolumeGauge.o \ + $(END_OBJS) + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Targets +# + +NAME = volumegauge.plugin +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + $(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS2) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + copy $(BINDIR)/$(NAME) Scalos:Plugins/OOP clone + + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* + +############################################################################## + + + diff --git a/scalos/Plugins/OOP/wb39_plugin/volumegauge/plugin_data.h b/scalos/Plugins/OOP/wb39_plugin/volumegauge/plugin_data.h new file mode 100644 index 000000000..fd599a742 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/volumegauge/plugin_data.h @@ -0,0 +1,36 @@ +// plugin_data.h +// $Date$ +// $Revision$ + +#ifndef PLUGIN_DATA_H_INCLUDED +#define PLUGIN_DATA_H_INCLUDED + +#include +#include + +#define PLUGIN_TYPE OOP + +#define LIB_VERSION 39 +#define LIB_REVISION 8 + +#define LIB_NAME "volumegauge.plugin" +#define LIB_VERSTRING "$VER: volumegauge.plugin " \ + STR(LIB_VERSION) "." STR(LIB_REVISION) \ + " (02.01.2007) " COMPILER_STRING \ + " ©1999" CURRENTYEAR " The Scalos Team" + +#define CI_CLASSNAME "Window.sca" +#define CI_SUPERCLASSNAME "Window.sca" +#define CI_PLUGINNAME "Scalos VolumeGauge Class" +#define CI_DESCRIPTION "This class gives root windows a volume gauge" COMPILER_STRING +#define CI_AUTHOR "Jürgen Lachmann" +#define CI_INSTSIZE sizeof(struct VolumeGaugeInst) +#define CI_HOOKFUNC myHookFunc + +//---------------------------------------------------------------------------- +// code and includes to define the structs and functions used above + +#include "volumegauge.h" + +#endif /* PLUGUN_DATA_H_INCLUDED */ + diff --git a/scalos/Plugins/OOP/wb39_plugin/volumegauge/vg_plugin.c b/scalos/Plugins/OOP/wb39_plugin/volumegauge/vg_plugin.c new file mode 100644 index 000000000..a88614d27 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/volumegauge/vg_plugin.c @@ -0,0 +1,469 @@ +// vg_plugin.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "volumegauge.h" + + +// Instance structure for overridden window.sca class +struct VGinst + { + Object *vgi_VolumeGaugeObject; + }; + + +// aus debug.lib +extern int kprintf(const char *fmt, ...); + + +static BOOL Init(void); +VOID closePlugin(void); +static BOOL OpenLibraries(void); +static void CloseLibraries(void); +static void UpdateVolumeGauge(struct Gadget *gad, struct Window *win, BPTR iLock); + + +// Instance Size +const ULONG VGinstSize = sizeof(struct VGinst); + + +struct DosLibrary *DOSBase; +T_UTILITYBASE UtilityBase; +struct IntuitionBase *IntuitionBase; +struct Library *LayersBase; +struct Library *GfxBase; +struct Library *ScalosBase; +#ifdef __amigaos4__ +struct Library *NewlibBase; + +struct DOSIFace *IDOS; +struct UtilityIFace *IUtility; +struct IntuitionIFace *IIntuition; +struct LayersIFace *ILayers; +struct GraphicsIFace *IGraphics; +struct ScalosIFace *IScalos; +struct Interface *INewlib; +#endif + +#if defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) +extern T_UTILITYBASE __UtilityBase; +#endif /* defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) */ + +static BOOL fInit; + + +M68KFUNC_P3(ULONG, myHookFunc, + A0, Class *, cl, + A2, Object *, obj, + A1, Msg, msg) +{ + struct ScaRootList *rootList = (struct ScaRootList *) obj; + struct ScaWindowStruct *sWin = NULL; + ULONG Result; + BOOL Scalos4014; + + d(kprintf(__FUNC__ "/%ld: MethodID=%08lx\n", __LINE__, msg->MethodID)); + + if (rootList && rootList->rl_WindowTask) + sWin = rootList->rl_WindowTask->mt_WindowStruct; + + switch (msg->MethodID) + { + case OM_NEW: /* First, pass up to superclass */ + obj = (Object *) DoSuperMethodA(cl, obj, msg); + if (obj) + { + struct VGinst *inst = INST_DATA(cl, obj); + + inst->vgi_VolumeGaugeObject = NULL; + + Result = (ULONG) obj; + } + else + Result = 0; + break; + + case SCCM_Window_Open: + Scalos4014 = ScalosBase->lib_Version >= 40 && ScalosBase->lib_Revision >= 14; + + if (sWin && (sWin->ws_Flags & WSV_FlagF_RootWindow) + && cl->cl_InstSize >= sizeof(struct VGinst) + && Scalos4014) + { + struct Gadget *gg; + struct VGinst *inst = INST_DATA(cl, obj); + + inst->vgi_VolumeGaugeObject = NewObject(VOLUMEGAUGE_GetClass(), NULL, + GA_DrawInfo, (ULONG) rootList->rl_internInfos->ii_DrawInfo, + GA_LeftBorder, TRUE, + GA_RelSpecial, TRUE, + VOLUMEGAUGE_Ticks, 5, + VOLUMEGAUGE_ShortTicks, TRUE, + VOLUMEGAUGE_TickSize, 3, + VOLUMEGAUGE_Min, 0, + VOLUMEGAUGE_Max, 1000, + VOLUMEGAUGE_Level, 500, + TAG_END); + + gg = (struct Gadget *) inst->vgi_VolumeGaugeObject; + if (gg) + { + // insert volume gauge in front of other window gadgets + DoMethod(sWin->ws_WindowTask->mt_MainObject, + SCCM_IconWin_AddGadget, gg); + + UpdateVolumeGauge(gg, NULL, sWin->ws_Lock); + } + } + + Result = DoSuperMethodA(cl, obj, msg); + + d(kprintf(__FUNC__ "/%ld: RootList=%08lx InternInfos=%08lx\n", __LINE__, \ + rootList, rootList->rl_internInfos)); + + if (sWin && (sWin->ws_Flags & WSV_FlagF_RootWindow) + && cl->cl_InstSize >= sizeof(struct VGinst) + && !Scalos4014) + { + struct Window *win = rootList->rl_WindowTask->wt_Window; + + if (win) + { + struct VGinst *inst = INST_DATA(cl, obj); + struct Gadget *gad; + + if (win->BorderLeft < 14) + win->BorderLeft = 14; + if (win->BorderLeft < win->BorderRight) + win->BorderLeft = win->BorderRight; + + inst->vgi_VolumeGaugeObject = NewObject(VOLUMEGAUGE_GetClass(), NULL, + GA_Top, win->BorderTop + 2, + GA_Left, 4, + GA_Width, win->BorderLeft - 4 - 4, + GA_RelHeight, - (win->BorderTop + 2) - win->BorderBottom, + GA_DrawInfo, (ULONG) rootList->rl_internInfos->ii_DrawInfo, + GA_LeftBorder, TRUE, + GA_RelSpecial, TRUE, + VOLUMEGAUGE_Ticks, 5, + VOLUMEGAUGE_ShortTicks, TRUE, + VOLUMEGAUGE_TickSize, 3, + VOLUMEGAUGE_Min, 0, + VOLUMEGAUGE_Max, 1000, + VOLUMEGAUGE_Level, 500, + TAG_END); + + gad = (struct Gadget *) inst->vgi_VolumeGaugeObject; + if (gad) + { + AddGadget(win, gad, ~0); + RefreshGList(gad, win, NULL, 1); + + UpdateVolumeGauge(gad, win, sWin->ws_Lock); + } + RefreshWindowFrame(win); + + DoMethod(sWin->ws_WindowTask->mt_WindowObject, SCCM_Window_SetInnerSize); + + d1(kprintf(__FUNC__ "/%ld: Lock=%08lx\n", __LINE__, sWin->ws_Lock)); + } + d1(kprintf(__FUNC__ "/%ld: Window=%08lx bLeft=%ld bRight=%ld vgi_VolumeGaugeObject=%08lx\n", __LINE__, \ + win, win->BorderLeft, win->BorderRight, inst->vgi_VolumeGaugeObject)); + } + break; + + case SCCM_Window_Close: + if (sWin && (sWin->ws_Flags & WSV_FlagF_RootWindow) && cl->cl_InstSize >= sizeof(struct VGinst)) + { + struct VGinst *inst = INST_DATA(cl, obj); + struct Window *win = rootList->rl_WindowTask->wt_Window; + struct Gadget *gad = (struct Gadget *) inst->vgi_VolumeGaugeObject; + + d(kprintf(__FUNC__ "/%ld: Window=%08lx gad=%08lx\n", __LINE__, \ + win, gad)); + + if (gad) + { + RemoveGadget(win, gad); + DisposeObject((Object *) gad); + } + } + Result = DoSuperMethodA(cl, obj, msg); + break; + + case SCCM_Window_SetTitle: + if (sWin && (sWin->ws_Flags & WSV_FlagF_RootWindow) && cl->cl_InstSize >= sizeof(struct VGinst)) + { + struct VGinst *inst = INST_DATA(cl, obj); + struct Window *win = rootList->rl_WindowTask->wt_Window; + struct Gadget *gad = (struct Gadget *) inst->vgi_VolumeGaugeObject; + + d(kprintf(__FUNC__ "/%ld: Window=%08lx gad=%08lx\n", __LINE__, \ + win, gad)); + + if (gad) + UpdateVolumeGauge(gad, win, sWin->ws_Lock); + } + Result = DoSuperMethodA(cl, obj, msg); + break; + + default: + d(kprintf(__FUNC__ "/%ld: MethodID=%08lx\n", __LINE__, msg->MethodID)); + Result = DoSuperMethodA(cl, obj, msg); + break; + } + + return Result; +} +M68KFUNC_END + + +BOOL initPlugin(void) +{ + d(kprintf(__FUNC__ "/%ld: \n", __LINE__)); + + if (!fInit) + { + BOOL Success = Init(); + + if (!Success) + closePlugin(); + + return Success; + } + + return TRUE; +} + + +static BOOL Init(void) +{ + if (!OpenLibraries()) + return FALSE; + + d(kprintf(__FUNC__ "/%ld: UtilityBase=%08lx\n", \ + __LINE__, UtilityBase)); + + fInit = TRUE; + + return TRUE; +} + + +VOID closePlugin(void) +{ + CloseLibraries(); + + fInit = FALSE; +} + + +static BOOL OpenLibraries(void) +{ + DOSBase = (struct DosLibrary *) OpenLibrary(DOSNAME, 39); + if (NULL == DOSBase) + return FALSE; +#ifdef __amigaos4__ + IDOS = (struct DOSIFace *)GetInterface((struct Library *)DOSBase, "main", 1, NULL); + if (NULL == IDOS) + return FALSE; +#endif + + UtilityBase = (T_UTILITYBASE) OpenLibrary("utility.library", 39); + if (NULL == UtilityBase) + return FALSE; +#ifdef __amigaos4__ + IUtility = (struct UtilityIFace *)GetInterface((struct Library *)UtilityBase, "main", 1, NULL); + if (NULL == IUtility) + return FALSE; +#endif + +#if defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) + __UtilityBase = UtilityBase; +#endif /* defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) */ + + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + if (NULL == IntuitionBase) + return FALSE; +#ifdef __amigaos4__ + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + return FALSE; +#endif + + LayersBase = OpenLibrary("layers.library", 39); + if (NULL == LayersBase) + return FALSE; +#ifdef __amigaos4__ + ILayers = (struct LayersIFace *)GetInterface((struct Library *)LayersBase, "main", 1, NULL); + if (NULL == ILayers) + return FALSE; +#endif + + GfxBase = OpenLibrary("graphics.library", 39); + if (NULL == GfxBase) + return FALSE; +#ifdef __amigaos4__ + IGraphics = (struct GraphicsIFace *)GetInterface((struct Library *)GfxBase, "main", 1, NULL); + if (NULL == IGraphics) + return FALSE; + + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + return FALSE; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + return FALSE; +#endif + + ScalosBase = OpenLibrary(SCALOSNAME, 41); + if (NULL == ScalosBase) + return FALSE; +#ifdef __amigaos4__ + IScalos = (struct ScalosIFace *)GetInterface((struct Library *)ScalosBase, "main", 1, NULL); + if (NULL == IScalos) + return FALSE; +#endif + + return TRUE; +} + + +static void CloseLibraries(void) +{ +#ifdef __amigaos4__ + if (IScalos) + { + DropInterface((struct Interface *)IScalos); + IScalos = NULL; + } +#endif + if (ScalosBase) + { + CloseLibrary(ScalosBase); + ScalosBase = NULL; + } +#ifdef __amigaos4__ + if (INewlib) + { + DropInterface(INewlib); + INewlib = NULL; + } + if (NewlibBase) + { + CloseLibrary(NewlibBase); + NewlibBase = NULL; + } + if (IGraphics) + { + DropInterface((struct Interface *)IGraphics); + IGraphics = NULL; + } +#endif + if (GfxBase) + { + CloseLibrary(GfxBase); + GfxBase = NULL; + } +#ifdef __amigaos4__ + if (IDOS) + { + DropInterface((struct Interface *)IDOS); + IDOS = NULL; + } +#endif + if (DOSBase) + { + CloseLibrary((struct Library *) DOSBase); + DOSBase = NULL; + } +#ifdef __amigaos4__ + if (IUtility) + { + DropInterface((struct Interface *)IUtility); + IUtility = NULL; + } +#endif + if (UtilityBase) + { + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } +#ifdef __amigaos4__ + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } +#endif + if (IntuitionBase) + { + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } +#ifdef __amigaos4__ + if (ILayers) + { + DropInterface((struct Interface *)ILayers); + ILayers = NULL; + } +#endif + if (LayersBase) + { + CloseLibrary(LayersBase); + LayersBase = NULL; + } +} + + +/* ====================================================== */ + +static void UpdateVolumeGauge(struct Gadget *gad, struct Window *win, BPTR iLock) +{ + struct InfoData *id = AllocVec(sizeof(struct InfoData), MEMF_PUBLIC); + + if (id) + { + Info(iLock, id); + + d(kprintf(__FUNC__ "/%ld: NumBlocks=%lu NumBlocksUsed=%lu\n", __LINE__, \ + id->id_NumBlocks, id->id_NumBlocksUsed)); + + SetGadgetAttrs(gad, win, NULL, + VOLUMEGAUGE_Level, id->id_NumBlocksUsed, + VOLUMEGAUGE_Max, id->id_NumBlocks, + TAG_END); + + FreeVec(id); + } +} + + +void _XCEXIT(long x) +{ +} + + diff --git a/scalos/Plugins/OOP/wb39_plugin/volumegauge/volumegauge.h b/scalos/Plugins/OOP/wb39_plugin/volumegauge/volumegauge.h new file mode 100644 index 000000000..8ea7b79da --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/volumegauge/volumegauge.h @@ -0,0 +1,65 @@ +// VolumeGauge.h +// $Date$ +// $Revision$ + + +#ifndef VOLUMEGAUGE_H_INCLUDED +#define VOLUMEGAUGE_H_INCLUDED + +#include +#include + +#include + +//---------------------------------------------------------------------------- + +#define d(x) ; +#define d1(x) ; +#define d2(x) x; + +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +//---------------------------------------------------------------------------- + +#define VOLUMEGAUGE_Dummy (TAG_USER+0xea00) + +#define VOLUMEGAUGE_Ticks (VOLUMEGAUGE_Dummy+0) // (I..) +#define VOLUMEGAUGE_TickSize (VOLUMEGAUGE_Dummy+1) // (I..) +#define VOLUMEGAUGE_Min (VOLUMEGAUGE_Dummy+2) // (IS.) +#define VOLUMEGAUGE_Max (VOLUMEGAUGE_Dummy+3) // (IS.) +#define VOLUMEGAUGE_Level (VOLUMEGAUGE_Dummy+4) // (IS.) +#define VOLUMEGAUGE_ShortTicks (VOLUMEGAUGE_Dummy+5) // (I..) + +//---------------------------------------------------------------------------- + +struct VolumeGaugeInst +{ + struct Window *BarWindow; + short Left, Top, Width, Height; + + short LastLevel; + long Level; + long MinValue, MaxValue; + + long ScaleFactor; + long Ticks; + long ShortTicks; + long TickSize; + + UWORD ActiveFillPen; + UWORD ActiveShinePen; + UWORD ActiveShadowPen; + UWORD InactiveFillPen; + UWORD InactiveShinePen; + UWORD InactiveShadowPen; +}; + +//---------------------------------------------------------------------------- + +Class *VOLUMEGAUGE_GetClass(void); +BOOL freeVolumeGaugeGadClass(void); + +//---------------------------------------------------------------------------- + +#endif /* VOLUMEGAUGE_H_INCLUDED */ diff --git a/scalos/Plugins/OOP/wb39_plugin/wb39.c b/scalos/Plugins/OOP/wb39_plugin/wb39.c new file mode 100644 index 000000000..c61cf2a2a --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/wb39.c @@ -0,0 +1,1745 @@ +// wb39.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#ifdef __amigaos4__ +#include +#endif + +#include "wb39.h" +#include "wb39proto.h" +#include "volumegauge.h" + +// moved revision history to file "History" + + +/* + +State of WB3.5/3.9 API emulation +================================ + +AddAppIconA - partially supported : + WBAPPICONA_SupportsOpen - native support by Scalos ver >= 40 + WBAPPICONA_SupportsCopy - native support by Scalos ver >= 40 + WBAPPICONA_SupportsRename - native support by Scalos ver >= 40 + WBAPPICONA_SupportsInformation - native support by Scalos ver >= 40 + WBAPPICONA_SupportsSnapshot - native support by Scalos ver >= 40 + WBAPPICONA_SupportsUnSnapshot - native support by Scalos ver >= 40 + WBAPPICONA_SupportsLeaveOut - native support by Scalos ver >= 40 + WBAPPICONA_SupportsPutAway - native support by Scalos ver >= 40 + WBAPPICONA_SupportsDelete - native support by Scalos ver >= 40 + WBAPPICONA_SupportsFormatDisk - native support by Scalos ver >= 40 + WBAPPICONA_SupportsEmptyTrash - native support by Scalos ver >= 40 + WBAPPICONA_PropagatePosition - supported, only works with Scalos ver >= 40 + WBAPPICONA_RenderHook - supported, only works with Scalos ver >= 40 + WBAPPICONA_NotifySelectState - ./. +AddAppMenuItemA - full native support by Scalos ver >= 40 +AddAppWindowA - supported +AddAppWindowDropZoneA - supported +ChangeWorkbenchSelectionA - supported +CloseWorkbenchObjectA - supported +MakeWorkbenchObjectVisibleA - supported +OpenWorkbenchObjectA - supported +RemoveAppIcon - partially supported +RemoveAppMenuItem - ./. unchanged +RemoveAppWindow - supported +RemoveAppWindowDropZone - supported +WBInfo - ./. unchanged +WorkbenchControlA - fully supported : + WBCTRLA_IsOpen - supported + WBCTRLA_DuplicateSearchPath - supported + WBCTRLA_FreeSearchPath - supported + WBCTRLA_GetDefaultStackSize - supported with Scalos ver >= 40 + WBCTRLA_SetDefaultStackSize - supported with Scalos ver >= 40 + WBCTRLA_RedrawAppIcon - does Icon Redraw, only works with Scalos ver >= 40 + WBCTRLA_GetProgramList - supported with Scalos ver >= 40 + WBCTRLA_FreeProgramList - supported + WBCTRLA_GetSelectedIconList - supported + WBCTRLA_FreeSelectedIconList - supported + WBCTRLA_GetOpenDrawerList - supported + WBCTRLA_FreeOpenDrawerList - supported + WBCTRLA_AddHiddenDeviceName - supported + WBCTRLA_RemoveHiddenDeviceName - supported + WBCTRLA_GetHiddenDeviceList - supported + WBCTRLA_FreeHiddenDeviceList - supported + WBCTRLA_GetTypeRestartTime - supported, with Scalos ver >= 40 + WBCTRLA_SetTypeRestartTime - supported, with Scalos ver >= 40 +*/ + +// aus mempools.lib +#if !defined(__amigaos4__) && !defined(__AROS__) +extern int _STI_240_InitMemFunctions(void); +extern void _STD_240_TerminateMemFunctions(void); +#endif + +static BOOL LateInit(void); +static BOOL OpenLibraries(void); +static void CloseLibraries(void); +static LIBFUNC_P3_PROTO(BOOL, myOpenWorkbenchObjectA, + A0, STRPTR, name, + A1, struct TagItem *, tags, + A6, struct Library *, WorkbenchBase); +static struct WBArg *BuildWBArg(struct TagItem *Tags, ULONG *ArgCount); +static void FreeWBArg(struct WBArg *ArgList, ULONG ArgCount, BOOL FreeLocks); +static LIBFUNC_P3_PROTO(BOOL, myCloseWorkbenchObjectA, + A0, STRPTR, name, + A1, struct TagItem *, tags, + A6, struct Library *, WorkbenchBase); +static LIBFUNC_P3_PROTO(ULONG, myWbprivate1, + A0, STRPTR, Name, + A1, BPTR, iLock, + A6, struct Library *, WorkbenchBase); +static LIBFUNC_P3_PROTO(BOOL, myMakeWorkbenchObjectVisibleA, + A0, STRPTR, name, + A1, struct TagItem *, tags, + A6, struct Library *, WorkbenchBase); +static void UpdateVolumeGauge(struct Gadget *gad, struct Window *win, BPTR iLock); +static LIBFUNC_P4_PROTO(BOOL, myChangeWorkbenchSelectionA, + A0, STRPTR, name, + A1, struct Hook *, hook, + A2, struct TagItem *, tags, + A6, struct Library *, WorkbenchBase); +static void FreeAllNodes(struct List *pl); // +dm+ 20010518 + +#ifdef __amigaos4__ +static LIBFUNC_P2VA_PROTO(BOOL, myOpenWorkbenchObject, + A0, STRPTR, name, + A6, struct Library *, WorkbenchBase); +static LIBFUNC_P2VA_PROTO(BOOL, myCloseWorkbenchObject, + A0, STRPTR, name, + A6, struct Library *, WorkbenchBase); +static LIBFUNC_P2VA_PROTO(BOOL, myMakeWorkbenchObjectVisible, + A0, STRPTR, name, + A6, struct Library *, WorkbenchBase); +static LIBFUNC_P3VA_PROTO(BOOL, myChangeWorkbenchSelection, + A0, STRPTR, name, + A1, struct Hook *, hook, + A6, struct Library *, WorkbenchBase); +#endif + +struct DosLibrary *DOSBase = NULL; +struct Library *IconobjectBase = NULL; +struct Library *WorkbenchBase = NULL; +T_UTILITYBASE UtilityBase = NULL; +struct ScalosBase *ScalosBase = NULL; +struct IntuitionBase *IntuitionBase = NULL; +struct Library *LayersBase = NULL; +struct Library *GfxBase = NULL; +struct Library *IconBase = NULL; +struct Library *IFFParseBase = NULL; +#ifdef __amigaos4__ +struct Library *NewlibBase = NULL; + +struct DOSIFace *IDOS = NULL; +struct IconobjectIFace *IIconobject = NULL; +struct WorkbenchIFace *IWorkbench = NULL; +struct UtilityIFace *IUtility = NULL; +struct ScalosIFace *IScalos = NULL; +struct IntuitionIFace *IIntuition = NULL; +struct LayersIFace *ILayers = NULL; +struct GraphicsIFace *IGraphics = NULL; +struct IconIFace *IIcon = NULL; +struct IFFParseIFace *IIFFParse = NULL; +struct Interface *INewlib = NULL; +#endif + +#if defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) +extern T_UTILITYBASE __UtilityBase; +#endif /* defined(__GNUC__) && !defined(__MORPHOS__) */ + +APTR origOpenWorkbenchObjectA = NULL; +APTR origCloseWorkbenchObjectA = NULL; +APTR origAddAppWindowDropZoneA = NULL; +APTR origRemoveAppWindowDropZone = NULL; +APTR origWbprivate1 = NULL; +APTR origMakeWorkbenchObjectVisibleA = NULL; +APTR origChangeWorkbenchSelectionA = NULL; + + +/*LIBFUNC_P6_DPROTO(struct ScaAppObjNode *, (*origAddAppWindowA), + D0, ULONG, id, + D1, ULONG, userdata, + A0, struct Window *, window, + A1, struct MsgPort *, msgport, + A2, struct TagItem *, taglist, + A6, struct Library *, WorkbenchBase); +LIBFUNC_P2_DPROTO(BOOL, (*origRemoveAppWindow), + A0, struct ScaAppObjNode *, appWindow, + A6, struct Library *, WorkbenchBase); +LIBFUNC_P5_DPROTO(void, (*origSCA_DrawDrag), + A0, struct DragHandle *, draghandle, + D0, LONG, X, + D1, LONG, Y, + D2, LONG, Flags, + A6, struct Library *, ScalosBase); +static LIBFUNC_P3_DPROTO(BOOL, (*origWorkbenchControlA), + A0, STRPTR, name, + A1, struct TagItem *, tags, + A6, struct Library *, WorkbenchBase); +*/ +APTR origAddAppWindowA = NULL; +APTR origRemoveAppWindow = NULL; +APTR origSCA_DrawDrag = NULL; +APTR origWorkbenchControlA = NULL; + +#ifdef __amigaos4__ +APTR origOpenWorkbenchObject = NULL; +APTR origCloseWorkbenchObject = NULL; +APTR origAddAppWindowDropZone = NULL; +APTR origMakeWorkbenchObjectVisible = NULL; +APTR origChangeWorkbenchSelection = NULL; +APTR origAddAppWindow = NULL; +APTR origWorkbenchControl = NULL; +#endif + +static BOOL fInit = FALSE; + +STRPTR DefIconsPath = "ENV:sys/def_"; + +struct List AppWindowList; // list of all AppWindows +struct SignalSemaphore AppWindowSema; + +ULONG DefaultStackSize = 4096; // +dm+ 20010518 changed to 4096 (was 4095???) +ULONG fVolumeGauge = TRUE; +ULONG fTitleBar = TRUE; +ULONG TypeRestartTime = 3; // Keyboard restart delay in s +BOOL NewIconsSupport = TRUE; +BOOL ColorIconsSupport = TRUE; + + +WORD ScalosPrefs_IconOffsets[4] = { 1, 1, 1, 1 }; + +struct ScaRootList *rList = NULL; + +struct List HiddenDeviceList; // +dm+ 20010518 for storing names of hidden devices +struct SignalSemaphore HiddenDevListSema; // +jl+ 20010523 Semaphore to protect HiddenDeviceList + + +M68KFUNC_P3(ULONG, myHookFunc, + A0, Class *, cl, + A2, Object *, obj, + A1, Msg, msg) +{ + struct ScaRootList *rootList; + struct ScaWindowStruct *sWin = NULL; + ULONG Result; + BOOL Scalos4014; + + rList = rootList = (struct ScaRootList *) obj; + + d1(kprintf("%s/%s/%ld: MethodID=%08lx\n"__FILE__, __FUNC__, __LINE__, msg->MethodID)); + + if (rootList && rootList->rl_WindowTask) + sWin = rootList->rl_WindowTask->mt_WindowStruct; + + switch (msg->MethodID) + { + case OM_NEW: /* First, pass up to superclass */ + LateInit(); + + obj = (Object *) DoSuperMethodA(cl, obj, msg); + if (obj) + { + struct WB39inst *inst = INST_DATA(cl, obj); + + inst->wb39i_VolumeGaugeObject = NULL; + + Result = (ULONG) obj; + } + else + Result = 0; + break; + + case SCCM_Window_Open: + d1(kprintf("%s/%s/%ld: instOffset=%lu instSize=%lu\n"__FILE__, __FUNC__, __LINE__, cl->cl_InstOffset, cl->cl_InstSize)); + + Scalos4014 = ScalosBase->scb_LibNode.lib_Version >= 40 && ScalosBase->scb_LibNode.lib_Revision >= 14; + + if (sWin && (sWin->ws_Flags & WSV_FlagF_RootWindow) + && cl->cl_InstSize >= sizeof(struct WB39inst)) + { + if (Scalos4014 && fVolumeGauge) + { + struct Gadget *gg; + struct WB39inst *inst = INST_DATA(cl, obj); + + inst->wb39i_VolumeGaugeObject = NewObject(VOLUMEGAUGE_GetClass(), NULL, + GA_DrawInfo, (ULONG) rootList->rl_internInfos->ii_DrawInfo, + GA_LeftBorder, TRUE, + GA_RelSpecial, TRUE, + VOLUMEGAUGE_Ticks, 5, + VOLUMEGAUGE_ShortTicks, TRUE, + VOLUMEGAUGE_TickSize, 3, + VOLUMEGAUGE_Min, 0, + VOLUMEGAUGE_Max, 1000, + VOLUMEGAUGE_Level, 500, + TAG_END); + + gg = (struct Gadget *) inst->wb39i_VolumeGaugeObject; + if (gg) + { + // insert volume gauge in front of other window gadgets + DoMethod(sWin->ws_WindowTask->mt_MainObject, + SCCM_IconWin_AddGadget, gg); + + UpdateVolumeGauge(gg, NULL, sWin->ws_Lock); + } + } + } + + Result = DoSuperMethodA(cl, obj, msg); + + d1(kprintf("%s/%s/%ld: RootList=%08lx InternInfos=%08lx\n"__FILE__, __FUNC__, __LINE__, \ + rootList, rootList->rl_internInfos)); + + if (sWin && (sWin->ws_Flags & WSV_FlagF_RootWindow) + && cl->cl_InstSize >= sizeof(struct WB39inst) + && !Scalos4014) + { + struct Window *win = rootList->rl_WindowTask->wt_Window; + + if (win && fVolumeGauge) + { + struct WB39inst *inst = INST_DATA(cl, obj); + struct Gadget *gad; + + if (win->BorderLeft < 14) + win->BorderLeft = 14; + if (win->BorderLeft < win->BorderRight) + win->BorderLeft = win->BorderRight; + + inst->wb39i_VolumeGaugeObject = NewObject(VOLUMEGAUGE_GetClass(), NULL, + GA_Top, win->BorderTop + 2, + GA_Left, 4, + GA_Width, win->BorderLeft - 4 - 4, + GA_RelHeight, - (win->BorderTop + 2) - win->BorderBottom, + GA_DrawInfo, (ULONG) rootList->rl_internInfos->ii_DrawInfo, + GA_LeftBorder, TRUE, + GA_RelSpecial, TRUE, + VOLUMEGAUGE_Ticks, 5, + VOLUMEGAUGE_ShortTicks, TRUE, + VOLUMEGAUGE_TickSize, 3, + VOLUMEGAUGE_Min, 0, + VOLUMEGAUGE_Max, 1000, + VOLUMEGAUGE_Level, 500, + TAG_END); + + gad = (struct Gadget *) inst->wb39i_VolumeGaugeObject; + if (gad) + { + AddGadget(win, gad, ~0); + RefreshGList(gad, win, NULL, 1); + + UpdateVolumeGauge(gad, win, sWin->ws_Lock); + } + RefreshWindowFrame(win); + + DoMethod(sWin->ws_WindowTask->mt_WindowObject, SCCM_Window_SetInnerSize); + + d1(kprintf("%s/%s/%ld: Lock=%08lx\n"__FILE__, __FUNC__, __LINE__, sWin->ws_Lock)); + } + d1(KPrintF("%s/%s/%ld: Window=%08lx bLeft=%ld bRight=%ld wb39i_VolumeGaugeObject=%08lx\n"__FILE__, __FUNC__, __LINE__, \ + win, win->BorderLeft, win->BorderRight, inst->wb39i_VolumeGaugeObject)); + } + break; + + case SCCM_Window_Close: + if (sWin && (sWin->ws_Flags & WSV_FlagF_RootWindow) && cl->cl_InstSize >= sizeof(struct WB39inst)) + { + struct WB39inst *inst = INST_DATA(cl, obj); + struct Window *win = rootList->rl_WindowTask->wt_Window; + struct Gadget *gad = (struct Gadget *) inst->wb39i_VolumeGaugeObject; + + d1(kprintf("%s/%s/%ld: Window=%08lx gad=%08lx\n"__FILE__, __FUNC__, __LINE__, \ + win, gad)); + + if (gad) + { + RemoveGadget(win, gad); + DisposeObject((Object *) gad); + } + } + Result = DoSuperMethodA(cl, obj, msg); + break; + + case SCCM_Window_SetTitle: + if (sWin && (sWin->ws_Flags & WSV_FlagF_RootWindow) && cl->cl_InstSize >= sizeof(struct WB39inst)) + { + struct WB39inst *inst = INST_DATA(cl, obj); + struct Window *win = rootList->rl_WindowTask->wt_Window; + struct Gadget *gad = (struct Gadget *) inst->wb39i_VolumeGaugeObject; + + d1(kprintf("%s/%s/%ld: Window=%08lx gad=%08lx\n"__FILE__, __FUNC__, __LINE__, \ + win, gad)); + + if (gad) + UpdateVolumeGauge(gad, win, sWin->ws_Lock); + } + Result = DoSuperMethodA(cl, obj, msg); + break; + + default: + d1(kprintf("%s/%s/%ld: MethodID=%08lx\n"__FILE__, __FUNC__, __LINE__, msg->MethodID)); + Result = DoSuperMethodA(cl, obj, msg); + break; + } + + return Result; +} +M68KFUNC_END + + +static BOOL LateInit(void) +{ + static BOOL First = TRUE; + + d1(KPrintF("/%s/%ld: First=%ld\n", __FUNC__, __FILE__, __FUNC__, __LINE__, First)); + + if (First) + { + ULONG EmulationMode = TRUE; + + rList = GetScalosRootList(); + d1(kprintf("%s/%s/%ld: ScaRootList=%08lx\n"__FILE__, __FUNC__, __LINE__, rList)); + + { + // Set Flag "Workbench open" + // bset #5,($2d,a6) + UBYTE * wbb = (UBYTE *) WorkbenchBase; + + wbb[0x2d] |= 0x20; + } + + if (ScalosBase->scb_LibNode.lib_Version >= 40) + { + SCA_ScalosControl(NULL, + SCALOSCTRLA_GetEmulationMode, (ULONG) &EmulationMode, + TAG_END); + } + + NewList(&AppWindowList); + NewList(&HiddenDeviceList); // +dm+ 20010518 + + InitSemaphore(&AppWindowSema); + InitSemaphore(&HiddenDevListSema); // +jl+ 20010523 + + if (EmulationMode) + { +#ifndef __amigaos4__ + STATIC_PATCHFUNC(myOpenWorkbenchObjectA) + STATIC_PATCHFUNC(myCloseWorkbenchObjectA) + STATIC_PATCHFUNC(myMakeWorkbenchObjectVisibleA) + STATIC_PATCHFUNC(myChangeWorkbenchSelectionA) + + STATIC_PATCHFUNC(myAddAppWindowDropZoneA) + STATIC_PATCHFUNC(myRemoveAppWindowDropZone) + STATIC_PATCHFUNC(myAddAppWindowA) + STATIC_PATCHFUNC(myRemoveAppWindow) + + STATIC_PATCHFUNC(myWorkbenchControlA) + + STATIC_PATCHFUNC(myWbprivate1) + STATIC_PATCHFUNC(mySCA_DrawDrag) +#endif + + if (!AppIconsInit()) + return FALSE; + +#if defined(__amigaos4__) + origOpenWorkbenchObjectA = SetMethod((struct Interface *)IWorkbench, + offsetof(struct WorkbenchIFace, OpenWorkbenchObjectA), + (APTR)myOpenWorkbenchObjectA); + origOpenWorkbenchObject = SetMethod((struct Interface *)IWorkbench, + offsetof(struct WorkbenchIFace, OpenWorkbenchObject), + (APTR)myOpenWorkbenchObject); + origCloseWorkbenchObjectA = SetMethod((struct Interface *)IWorkbench, + offsetof(struct WorkbenchIFace, CloseWorkbenchObjectA), + (APTR)myCloseWorkbenchObjectA); + origCloseWorkbenchObject = SetMethod((struct Interface *)IWorkbench, + offsetof(struct WorkbenchIFace, CloseWorkbenchObject), + (APTR)myCloseWorkbenchObject); + origMakeWorkbenchObjectVisibleA = SetMethod((struct Interface *)IWorkbench, + offsetof(struct WorkbenchIFace, MakeWorkbenchObjectVisibleA), + (APTR)myMakeWorkbenchObjectVisibleA); + origMakeWorkbenchObjectVisible = SetMethod((struct Interface *)IWorkbench, + offsetof(struct WorkbenchIFace, MakeWorkbenchObjectVisible), + (APTR)myMakeWorkbenchObjectVisible); + origChangeWorkbenchSelectionA = SetMethod((struct Interface *)IWorkbench, + offsetof(struct WorkbenchIFace, ChangeWorkbenchSelectionA), + (APTR)myChangeWorkbenchSelectionA); + origChangeWorkbenchSelection = SetMethod((struct Interface *)IWorkbench, + offsetof(struct WorkbenchIFace, ChangeWorkbenchSelection), + (APTR)myChangeWorkbenchSelection); + + origAddAppWindowDropZoneA = SetMethod((struct Interface *)IWorkbench, + offsetof(struct WorkbenchIFace, AddAppWindowDropZoneA), + (APTR)myAddAppWindowDropZoneA); + origAddAppWindowDropZone = SetMethod((struct Interface *)IWorkbench, + offsetof(struct WorkbenchIFace, AddAppWindowDropZone), + (APTR)myAddAppWindowDropZone); + origRemoveAppWindowDropZone = SetMethod((struct Interface *)IWorkbench, + offsetof(struct WorkbenchIFace, RemoveAppWindowDropZone), + (APTR)myRemoveAppWindowDropZone); + origAddAppWindowA = SetMethod((struct Interface *)IWorkbench, + offsetof(struct WorkbenchIFace, AddAppWindowA), + (APTR)myAddAppWindowA); + origAddAppWindow = SetMethod((struct Interface *)IWorkbench, + offsetof(struct WorkbenchIFace, AddAppWindow), + (APTR)myAddAppWindow); + origRemoveAppWindow = SetMethod((struct Interface *)IWorkbench, + offsetof(struct WorkbenchIFace, RemoveAppWindow), + (APTR)myRemoveAppWindow); + + origWorkbenchControlA = SetMethod((struct Interface *)IWorkbench, + offsetof(struct WorkbenchIFace, WorkbenchControlA), + (APTR)myWorkbenchControlA); + origWorkbenchControl = SetMethod((struct Interface *)IWorkbench, + offsetof(struct WorkbenchIFace, WorkbenchControl), + (APTR)myWorkbenchControl); + + origWbprivate1 = SetMethod((struct Interface *)IWorkbench, + offsetof(struct WorkbenchIFace, Private1), + (APTR)myWbprivate1); + + origSCA_DrawDrag = SetMethod((struct Interface *)IScalos, + offsetof(struct ScalosIFace, SCA_DrawDrag), + (APTR)mySCA_DrawDrag); +#elif defined(__AROS__) + origOpenWorkbenchObjectA = SetFunction(WorkbenchBase, + -16 * LIB_VECTSIZE, AROS_SLIB_ENTRY(myOpenWorkbenchObjectA, WorkbenchBase, 0)); + origCloseWorkbenchObjectA = SetFunction(WorkbenchBase, + -17 * LIB_VECTSIZE, AROS_SLIB_ENTRY(myCloseWorkbenchObjectA, WorkbenchBase, 0)); + origMakeWorkbenchObjectVisibleA = SetFunction(WorkbenchBase, + -22 * LIB_VECTSIZE, AROS_SLIB_ENTRY(myMakeWorkbenchObjectVisibleA, WorkbenchBase, 0)); + origChangeWorkbenchSelectionA = SetFunction(WorkbenchBase, + -21 * LIB_VECTSIZE, AROS_SLIB_ENTRY(myChangeWorkbenchSelectionA, WorkbenchBase, 0)); + + origAddAppWindowDropZoneA = SetFunction(WorkbenchBase, + -19 * LIB_VECTSIZE, AROS_SLIB_ENTRY(myAddAppWindowDropZoneA, WorkbenchBase, 0)); + origRemoveAppWindowDropZone = SetFunction(WorkbenchBase, + -20 * LIB_VECTSIZE, AROS_SLIB_ENTRY(myRemoveAppWindowDropZone, WorkbenchBase, 0)); + origAddAppWindowA = SetFunction(WorkbenchBase, + -8 * LIB_VECTSIZE, AROS_SLIB_ENTRY(myAddAppWindowA, WorkbenchBase, 0)); + origRemoveAppWindow = SetFunction(WorkbenchBase, + -9 * LIB_VECTSIZE, AROS_SLIB_ENTRY(myRemoveAppWindow, WorkbenchBase, 0)); + + origWorkbenchControlA = SetFunction(WorkbenchBase, + -18 * LIB_VECTSIZE, AROS_SLIB_ENTRY(myWorkbenchControlA, WorkbenchBase, 0)); + + origWbprivate1 = SetFunction(WorkbenchBase, + -5 * LIB_VECTSIZE, AROS_SLIB_ENTRY(myWbprivate1, WorkbenchBase, 0)); + + origSCA_DrawDrag = SetFunction(&ScalosBase->scb_LibNode, + -25 * LIB_VECTSIZE, AROS_SLIB_ENTRY(mySCA_DrawDrag, ScalosBase, 0)); +#else + origOpenWorkbenchObjectA = SetFunction(WorkbenchBase, + -96, PATCH_NEWFUNC(myOpenWorkbenchObjectA)); + origCloseWorkbenchObjectA = SetFunction(WorkbenchBase, + -102, PATCH_NEWFUNC(myCloseWorkbenchObjectA)); + origMakeWorkbenchObjectVisibleA = SetFunction(WorkbenchBase, + -132, PATCH_NEWFUNC(myMakeWorkbenchObjectVisibleA)); + origChangeWorkbenchSelectionA = SetFunction(WorkbenchBase, + -126, PATCH_NEWFUNC(myChangeWorkbenchSelectionA)); + + origAddAppWindowDropZoneA = SetFunction(WorkbenchBase, + -114, PATCH_NEWFUNC(myAddAppWindowDropZoneA)); + origRemoveAppWindowDropZone = SetFunction(WorkbenchBase, + -120, PATCH_NEWFUNC(myRemoveAppWindowDropZone)); + origAddAppWindowA = SetFunction(WorkbenchBase, + -48, PATCH_NEWFUNC(myAddAppWindowA)); + origRemoveAppWindow = SetFunction(WorkbenchBase, + -54, PATCH_NEWFUNC(myRemoveAppWindow)); + + origWorkbenchControlA = SetFunction(WorkbenchBase, + -108, PATCH_NEWFUNC(myWorkbenchControlA)); + + origWbprivate1 = SetFunction(WorkbenchBase, + -30, PATCH_NEWFUNC(myWbprivate1)); + + origSCA_DrawDrag = SetFunction(&ScalosBase->scb_LibNode, + -150, PATCH_NEWFUNC(mySCA_DrawDrag)); +#endif + DetachMyProcess(); + } + + // try to use current WB settings + ParseWBPrefs("ENV:sys/Workbench.prefs"); + + // Read some Scalos preferences settings + ReadScalosPrefs(); + + First = FALSE; + } + + return TRUE; +} + + +BOOL initPlugin(struct Library *libbase) +{ + d1(KPrintF("%s/%s/%ld: Start.\n"__FILE__, __FUNC__, __LINE__)); + + (void)libbase; + if (!fInit) + { + if (!OpenLibraries()) + return FALSE; + + d1(KPrintF("%s/%s/%ld: IconobjectBase=%08lx WorkbenchBase=%08lx UtilityBase=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, \ + IconobjectBase, WorkbenchBase, UtilityBase)); + +#if !defined(__amigaos4__) && !defined(__AROS__) + _STI_240_InitMemFunctions(); +#endif + + fInit = TRUE; // +dm+ 20010520 Added + } + + d1(KPrintF("%s/%s/%ld: End.\n"__FILE__, __FUNC__, __LINE__)); + + return TRUE; +} + + +VOID closePlugin(struct Library *libbase) +{ + fInit = FALSE; + + d1(kprintf("%s/%s/%ld: \n"__FILE__, __FUNC__, __LINE__)); + + ShutdownMyProcess(); + +#if defined(__amigaos4__) + if (origWbprivate1) + { + SetMethod((struct Interface *)IWorkbench, offsetof(struct WorkbenchIFace, Private1), + (APTR) origWbprivate1); + origWbprivate1 = NULL; + } + if (origWorkbenchControlA) + { + SetMethod((struct Interface *)IWorkbench, offsetof(struct WorkbenchIFace, WorkbenchControlA), + (APTR) origWorkbenchControlA); + origWorkbenchControlA = NULL; + } + if (origRemoveAppWindow) + { + SetMethod((struct Interface *)IWorkbench, offsetof(struct WorkbenchIFace, RemoveAppWindow), + (APTR) origRemoveAppWindow); + origRemoveAppWindow = NULL; + } + if (origAddAppWindowA) + { + SetMethod((struct Interface *)IWorkbench, offsetof(struct WorkbenchIFace, AddAppWindowA), + (APTR) origAddAppWindowA); + origAddAppWindowA = NULL; + } + if (origRemoveAppWindowDropZone) + { + SetMethod((struct Interface *)IWorkbench, offsetof(struct WorkbenchIFace, RemoveAppWindowDropZone), + (APTR) origRemoveAppWindowDropZone); + origRemoveAppWindowDropZone = NULL; + } + if (origAddAppWindowDropZoneA) + { + SetMethod((struct Interface *)IWorkbench, offsetof(struct WorkbenchIFace, AddAppWindowDropZoneA), + (APTR) origAddAppWindowDropZoneA); + origAddAppWindowDropZoneA = NULL; + } + if (origMakeWorkbenchObjectVisibleA) + { + SetMethod((struct Interface *)IWorkbench, offsetof(struct WorkbenchIFace, MakeWorkbenchObjectVisibleA), + (APTR) origMakeWorkbenchObjectVisibleA); + origMakeWorkbenchObjectVisibleA = NULL; + } + if (origOpenWorkbenchObjectA) + { + SetMethod((struct Interface *)IWorkbench, offsetof(struct WorkbenchIFace, OpenWorkbenchObjectA), + (APTR) origOpenWorkbenchObjectA); + origOpenWorkbenchObjectA = NULL; + } + if (origOpenWorkbenchObject) + { + SetMethod((struct Interface *)IWorkbench, offsetof(struct WorkbenchIFace, OpenWorkbenchObject), + (APTR) origOpenWorkbenchObject); + origOpenWorkbenchObject = NULL; + } + if (origSCA_DrawDrag) + { + SetMethod((struct Interface *)IScalos, offsetof(struct ScalosIFace, SCA_DrawDrag), + (APTR) origSCA_DrawDrag); + origSCA_DrawDrag = NULL; + } +#elif defined(__AROS__) + if (origWbprivate1) + { + SetFunction(WorkbenchBase, -5 * LIB_VECTSIZE, (ULONG (* const )()) origWbprivate1); + origWbprivate1 = NULL; + } + if (origWorkbenchControlA) + { + SetFunction(WorkbenchBase, -18 * LIB_VECTSIZE, (ULONG (* const )()) origWorkbenchControlA); + origWorkbenchControlA = NULL; + } + if (origRemoveAppWindow) + { + SetFunction(WorkbenchBase, -9 * LIB_VECTSIZE, (ULONG (* const )()) origRemoveAppWindow); + origRemoveAppWindow = NULL; + } + if (origAddAppWindowA) + { + SetFunction(WorkbenchBase, -8 * LIB_VECTSIZE, (ULONG (* const )()) origAddAppWindowA); + origAddAppWindowA = NULL; + } + if (origRemoveAppWindowDropZone) + { + SetFunction(WorkbenchBase, -20 * LIB_VECTSIZE, (ULONG (* const )()) origRemoveAppWindowDropZone); + origRemoveAppWindowDropZone = NULL; + } + if (origAddAppWindowDropZoneA) + { + SetFunction(WorkbenchBase, -19 * LIB_VECTSIZE, (ULONG (* const )()) origAddAppWindowDropZoneA); + origAddAppWindowDropZoneA = NULL; + } + if (origMakeWorkbenchObjectVisibleA) + { + SetFunction(WorkbenchBase, -22 * LIB_VECTSIZE, (ULONG (* const )()) origMakeWorkbenchObjectVisibleA); + origMakeWorkbenchObjectVisibleA = NULL; + } + if (origOpenWorkbenchObjectA) + { + SetFunction(WorkbenchBase, -16 * LIB_VECTSIZE, (ULONG (* const )()) origOpenWorkbenchObjectA); + origOpenWorkbenchObjectA = NULL; + } + if (origSCA_DrawDrag) + { + SetFunction(&ScalosBase->scb_LibNode, -25 * LIB_VECTSIZE, (ULONG (* const )()) origSCA_DrawDrag); + origSCA_DrawDrag = NULL; + } +#else + if (origWbprivate1) + { + SetFunction(WorkbenchBase, -30, (ULONG (* const )()) origWbprivate1); + origWbprivate1 = NULL; + } + if (origWorkbenchControlA) + { + SetFunction(WorkbenchBase, -108, (ULONG (* const )()) origWorkbenchControlA); + origWorkbenchControlA = NULL; + } + if (origRemoveAppWindow) + { + SetFunction(WorkbenchBase, -54, (ULONG (* const )()) origRemoveAppWindow); + origRemoveAppWindow = NULL; + } + if (origAddAppWindowA) + { + SetFunction(WorkbenchBase, -48, (ULONG (* const )()) origAddAppWindowA); + origAddAppWindowA = NULL; + } + if (origRemoveAppWindowDropZone) + { + SetFunction(WorkbenchBase, -120, (ULONG (* const )()) origRemoveAppWindowDropZone); + origRemoveAppWindowDropZone = NULL; + } + if (origAddAppWindowDropZoneA) + { + SetFunction(WorkbenchBase, -114, (ULONG (* const )()) origAddAppWindowDropZoneA); + origAddAppWindowDropZoneA = NULL; + } + if (origMakeWorkbenchObjectVisibleA) + { + SetFunction(WorkbenchBase, -132, (ULONG (* const )()) origMakeWorkbenchObjectVisibleA); + origMakeWorkbenchObjectVisibleA = NULL; + } + if (origOpenWorkbenchObjectA) + { + SetFunction(WorkbenchBase, -96, (ULONG (* const )()) origOpenWorkbenchObjectA); + origOpenWorkbenchObjectA = NULL; + } + if (origSCA_DrawDrag) + { + SetFunction(&ScalosBase->scb_LibNode, -150, (ULONG (* const )()) origSCA_DrawDrag); + origSCA_DrawDrag = NULL; + } +#endif + + FreeAllNodes(&HiddenDeviceList); // +dm+ 20010518 + CloseLibraries(); + +#if !defined(__amigaos4__) && !defined(__AROS__) + _STD_240_TerminateMemFunctions(); +#endif + + d1(kprintf("%s/%s/%ld: \n"__FILE__, __FUNC__, __LINE__)); + +} + + +static BOOL OpenLibraries(void) +{ + DOSBase = (struct DosLibrary *) OpenLibrary(DOSNAME, 39); + if (NULL == DOSBase) + return FALSE; +#ifdef __amigaos4__ + IDOS = (struct DOSIFace *)GetInterface((struct Library *)DOSBase, "main", 1, NULL); + if (NULL == IDOS) + return FALSE; +#endif + + IconobjectBase = OpenLibrary("iconobject.library", 39); + if (NULL == IconobjectBase) + return FALSE; +#ifdef __amigaos4__ + IIconobject = (struct IconobjectIFace *)GetInterface((struct Library *)IconobjectBase, "main", 1, NULL); + if (NULL == IIconobject) + return FALSE; +#endif + + WorkbenchBase = OpenLibrary(WORKBENCH_NAME, 44); + if (NULL == WorkbenchBase) + return FALSE; +#ifdef __amigaos4__ + IWorkbench = (struct WorkbenchIFace *)GetInterface((struct Library *)WorkbenchBase, "main", 1, NULL); + if (NULL == IWorkbench) + return FALSE; +#endif + + UtilityBase = (T_UTILITYBASE) OpenLibrary("utility.library", 40); + if (NULL == UtilityBase) + return FALSE; +#ifdef __amigaos4__ + IUtility = (struct UtilityIFace *)GetInterface((struct Library *)UtilityBase, "main", 1, NULL); + if (NULL == IUtility) + return FALSE; +#endif + +#if defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) + __UtilityBase = UtilityBase; +#endif /* defined(__GNUC__) && !defined(__MORPHOS__) */ + + ScalosBase = (struct ScalosBase *) OpenLibrary(SCALOSNAME, 41); + if (NULL == ScalosBase) + return FALSE; +#ifdef __amigaos4__ + IScalos = (struct ScalosIFace *)GetInterface((struct Library *)ScalosBase, "main", 1, NULL); + if (NULL == IScalos) + return FALSE; +#endif + + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 40); + if (NULL == IntuitionBase) + return FALSE; +#ifdef __amigaos4__ + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + return FALSE; +#endif + + LayersBase = OpenLibrary("layers.library", 40); + if (NULL == LayersBase) + return FALSE; +#ifdef __amigaos4__ + ILayers = (struct LayersIFace *)GetInterface((struct Library *)LayersBase, "main", 1, NULL); + if (NULL == ILayers) + return FALSE; +#endif + + GfxBase = OpenLibrary("graphics.library", 40); + if (NULL == GfxBase) + return FALSE; +#ifdef __amigaos4__ + IGraphics = (struct GraphicsIFace *)GetInterface((struct Library *)GfxBase, "main", 1, NULL); + if (NULL == IGraphics) + return FALSE; +#endif + + IconBase = OpenLibrary("icon.library", 41); + if (NULL == IconBase) + return FALSE; +#ifdef __amigaos4__ + IIcon = (struct IconIFace *)GetInterface((struct Library *)IconBase, "main", 1, NULL); + if (NULL == IIcon) + return FALSE; +#endif + + IFFParseBase = OpenLibrary("iffparse.library", 39); + if (NULL == IFFParseBase) + return FALSE; +#ifdef __amigaos4__ + IIFFParse = (struct IFFParseIFace *)GetInterface((struct Library *)IFFParseBase, "main", 1, NULL); + if (NULL == IIFFParse) + return FALSE; + + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + return FALSE; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + return FALSE; +#endif + + return TRUE; +} + + +static void CloseLibraries(void) +{ +#ifdef __amigaos4__ + if (IIFFParse) + { + DropInterface((struct Interface *)IIFFParse); + IIFFParse = NULL; + } +#endif + if (IFFParseBase) + { + CloseLibrary(IFFParseBase); + IFFParseBase = NULL; + } +#ifdef __amigaos4__ + if (IIcon) + { + DropInterface((struct Interface *)IIcon); + IIcon = NULL; + } +#endif + if (IconBase) + { + CloseLibrary(IconBase); + IconBase = NULL; + } +#ifdef __amigaos4__ + if (IGraphics) + { + DropInterface((struct Interface *)IGraphics); + IGraphics = NULL; + } +#endif + if (GfxBase) + { + CloseLibrary(GfxBase); + GfxBase = NULL; + } +#ifdef __amigaos4__ + if (IDOS) + { + DropInterface((struct Interface *)IDOS); + IDOS = NULL; + } +#endif + if (DOSBase) + { + CloseLibrary((struct Library *) DOSBase); + DOSBase = NULL; + } +#ifdef __amigaos4__ + if (IIconobject) + { + DropInterface((struct Interface *)IIconobject); + IIconobject = NULL; + } +#endif + if (IconobjectBase) + { + CloseLibrary(IconobjectBase); + IconobjectBase = NULL; + } +#ifdef __amigaos4__ + if (IWorkbench) + { + DropInterface((struct Interface *)IWorkbench); + IWorkbench = NULL; + } +#endif + if (WorkbenchBase) + { + CloseLibrary(WorkbenchBase); + WorkbenchBase = NULL; + } +#ifdef __amigaos4__ + if (IUtility) + { + DropInterface((struct Interface *)IUtility); + IUtility = NULL; + } +#endif + if (UtilityBase) + { + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } +#ifdef __amigaos4__ + if (IScalos) + { + DropInterface((struct Interface *)IScalos); + IScalos = NULL; + } +#endif + if (ScalosBase) + { + CloseLibrary((struct Library *) ScalosBase); + ScalosBase = NULL; + } +#ifdef __amigaos4__ + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } +#endif + if (IntuitionBase) + { + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } +#ifdef __amigaos4__ + if (ILayers) + { + DropInterface((struct Interface *)ILayers); + ILayers = NULL; + } +#endif + if (LayersBase) + { + CloseLibrary(LayersBase); + LayersBase = NULL; + } +} + + +// OpenWorkbenchObjectA emulation +static LIBFUNC_P3(BOOL, myOpenWorkbenchObjectA, + A0, STRPTR, name, + A1, struct TagItem *, tags, + A6, struct Library *, WorkbenchBase) +{ + struct WBArg *ArgList; + struct Process *myProc; + Object *IconObj = NULL; + struct DiskObject *diskObj = NULL; + struct TagItem TagList[5]; + ULONG ArgCount = 1; + BPTR fLock, dLock = (BPTR)NULL; + BOOL Result = FALSE; + + /* Suppress warning */ + (void)WorkbenchBase; + + d1(KPrintF("%s/%ld\n", __FUNC__, __FILE__, __FUNC__, __LINE__)); + + myProc = (struct Process *) FindTask(NULL); + if (NT_PROCESS == myProc->pr_Task.tc_Node.ln_Type) + { + dLock = myProc->pr_CurrentDir; + } + + fLock = Lock(name, ACCESS_READ); + if (fLock) + { + char Buffer[256]; + struct FileInfoBlock *fib; + + NameFromLock(fLock, Buffer, sizeof(Buffer)); + + fib = AllocDosObject(DOS_FIB, TAG_END); + if (fib) + { + LONG DirEntryType; + BOOL ShowAllFiles = FALSE; + ULONG ViewByMode = SCAV_ViewModes_Icon; + struct TagItem *tiShowAll, *tiViewBy; + + Examine(fLock, fib); + UnLock(fLock); + + d1(KPrintF("%s/%s/%ld: name=<%s> \n"__FILE__, __FUNC__, __LINE__, fib->fib_FileName)); + + DirEntryType = fib->fib_DirEntryType; + + FreeDosObject(DOS_FIB, fib); + + d1(KPrintF(__FUNC__ "/%ld\n"__FILE__, __FUNC__, __LINE__)); + + tiShowAll = FindTagItem(WBOPENA_Show, tags); + if (tiShowAll) + { + switch (tiShowAll->ti_Data) + { + case DDFLAGS_SHOWICONS: + ShowAllFiles = FALSE; + break; + case DDFLAGS_SHOWALL: + ShowAllFiles = TRUE; + break; + default: + tiShowAll = NULL; + break; + } + } + + tiViewBy = FindTagItem(WBOPENA_ViewBy, tags); + if (tiViewBy) + { + switch (tiViewBy->ti_Data) + { + case DDVM_BYICON: + ViewByMode = SCAV_ViewModes_Icon; + break; + case DDVM_BYNAME: + ViewByMode = SCAV_ViewModes_Name; + break; + case DDVM_BYDATE: + ViewByMode = SCAV_ViewModes_Date; + break; + case DDVM_BYSIZE: + ViewByMode = SCAV_ViewModes_Size; + break; + case DDVM_BYTYPE: + default: + tiViewBy = NULL; + break; + } + } + + d1(KPrintF(__FUNC__ "/%ld DirEntryType=%ld\n"__FILE__, __FUNC__, __LINE__, DirEntryType)); + + switch (DirEntryType) + { + case ST_ROOT: + case ST_USERDIR: + case ST_LINKDIR: + // Volume or Directory : open Icon Window + d1(KPrintF(__FUNC__ "/%ld Buffer=<%s>\n"__FILE__, __FUNC__, __LINE__, Buffer)); + Result = NULL != SCA_OpenDrawerByNameTags(Buffer, + tiShowAll ? SCA_ShowAllFiles : TAG_IGNORE, ShowAllFiles, + tiViewBy ? SCA_ViewModes : TAG_IGNORE, ViewByMode, + TAG_END); + + d1(KPrintF(__FUNC__ "/%ld Result=%08lx\n"__FILE__, __FUNC__, __LINE__, Result)); + + return Result; + break; + + case ST_FILE: + case ST_LINKFILE: + diskObj = GetDiskObjectNew(Buffer); + if (diskObj) + { + IconObj = Convert2IconObjectA(diskObj, NULL); + } + + d1(kprintf("%s/%s/%ld: FILE diskobj=%08lx iconobj=%08lx\n", \ + __LINE__, diskObj, IconObj)); + break; + } + + d1(kprintf(__FUNC__ "/%ld\n"__FILE__, __FUNC__, __LINE__)); + } + else + UnLock(fLock); + } + + d1(kprintf(__FUNC__ "/%ld\n"__FILE__, __FUNC__, __LINE__)); + + ArgList = BuildWBArg(tags, &ArgCount); + if (NULL == ArgList) + { + if (IconObj) + DisposeIconObject(IconObj); + if (diskObj) + FreeDiskObject(diskObj); + return FALSE; + } + + d1(kprintf("%s/%s/%ld: diskobj=%08lx iconobj=%08lx\n", \ + __LINE__, diskObj, IconObj)); + + if (NULL == IconObj) + { + IconObj = NewIconObjectTags(name, TAG_END); + d1(kprintf("%s/%s/%ld: diskobj=%08lx iconobj=%08lx\n", \ + __LINE__, diskObj, IconObj)); + } + if (IconObj) + { + ArgList[0].wa_Lock = DupLock(dLock); + ArgList[0].wa_Name = name; + + TagList[0].ti_Tag = SCA_IconObject; + TagList[0].ti_Data = (ULONG) IconObj; + TagList[1].ti_Tag = SCA_Stacksize; + TagList[1].ti_Data = DefaultStackSize; + TagList[2].ti_Tag = SCA_Flags; + TagList[2].ti_Data = SCAV_WBStart_PathSearch; + TagList[3].ti_Tag = TAG_END; + TagList[3].ti_Data = 0; + + Result = SCA_WBStart(ArgList, TagList, ArgCount); + + FreeWBArg(ArgList, ArgCount, FALSE); + } + else + FreeWBArg(ArgList, ArgCount, TRUE); + + d1(kprintf(__FUNC__ "/%ld\n"__FILE__, __FUNC__, __LINE__)); + if (IconObj) + DisposeIconObject(IconObj); + d1(kprintf(__FUNC__ "/%ld\n"__FILE__, __FUNC__, __LINE__)); + if (diskObj) + FreeDiskObject(diskObj); + + d1(kprintf("%s/%s/%ld: Result=%ld\n"__FILE__, __FUNC__, __LINE__, Result)); + + return Result; +} +LIBFUNC_END + + +static struct WBArg *BuildWBArg(struct TagItem *tags, ULONG *ArgCount) +{ + struct WBArg *ArgList; + struct TagItem *tp; + struct TagItem *tag; + short n; + + *ArgCount = 1; + + // Count arguments (program itself is argument #0) + tp = tags; + d1(kprintf("%s/%s/%ld: tags=%08lx tp=%08lx\n", \ + __LINE__, tags, tp)); + + while (tag = NextTagItem(&tp)) + { + if (WBOPENA_ArgName == tag->ti_Tag) + { + (*ArgCount)++; + d1(kprintf("%s/%s/%ld: ArgCount=%ld\n", \ + __LINE__, *ArgCount)); + } + } + + d1(kprintf("%s/%s/%ld: tags=%08lx ArgCount=%ld\n", \ + __LINE__, tags, *ArgCount)); + + // build Program's ArgList + ArgList = calloc(sizeof(struct WBArg), *ArgCount); + if (NULL == ArgList) + return NULL; + + tp = tags; + n = 1; + while (tag = NextTagItem(&tp)) + { + switch (tag->ti_Tag) + { + case WBOPENA_ArgLock: + if (ArgList[n].wa_Lock) + n++; + ArgList[n].wa_Lock = DupLock((BPTR)tag->ti_Data); +#if 0 + { + char Path[256]; + + NameFromLock(tag->ti_Data, Path, sizeof(Path)); + kprintf("%s/%s/%ld: Arg[%ld] ArgLock=<%s>\n", \ + __LINE__, n, Path); + } +#endif + break; + case WBOPENA_ArgName: + if (ArgList[n].wa_Name) + n++; + ArgList[n].wa_Name = (STRPTR) tag->ti_Data; + d1(kprintf("%s/%s/%ld: Arg[%ld] ArgName=<%s>\n", \ + __LINE__, n, tag->ti_Data)); + break; + + default: + d1(kprintf("%s/%s/%ld: tag=%08lx data=%08lx\n", \ + __LINE__, tag->ti_Tag, tag->ti_Data)); + break; + } + } + + return ArgList; +} + + +static void FreeWBArg(struct WBArg *ArgList, ULONG ArgCount, BOOL FreeLocks) +{ + short n; + + if (NULL == ArgList) + return; + + if (FreeLocks) + { + for (n=0; nwl_WindowStruct; !Found && swi; swi = (struct ScaWindowStruct *) swi->ws_Node.mln_Succ) + { + d1(kprintf("%s/%s/%ld: swi=%08lx Lock=%08lx nLock=%08lx\n"__FILE__, __FUNC__, __LINE__, \ + swi, swi->ws_Lock, nLock)); + + if (swi->ws_Lock && LOCK_SAME == SameLock(swi->ws_Lock, nLock)) + { + CloseScalosWindow(swi); + // swi is now invalid + swi = NULL; + Found = TRUE; + break; + } + } + + if (swi) + SCA_UnLockWindowList(); + } + + UnLock(nLock); + + d1(kprintf("%s/%s/%ld: Found=%ld\n"__FILE__, __FUNC__, __LINE__, Found)); + + return Found; +} +LIBFUNC_END + + +// "updateicon" +static LIBFUNC_P3(ULONG, myWbprivate1, + A0, STRPTR, Name, + A1, BPTR, iLock, + A6, struct Library *, WorkbenchBase) +{ + struct Task *myTask = FindTask(NULL); + + /* Suppress warning */ + (void)WorkbenchBase; + + d1(kprintf("%s/%s/%ld: Lock=%08lx Name=<%s>\n"__FILE__, __FUNC__, __LINE__, iLock, Name)); + + if (myTask->tc_Node.ln_Name) + { + d1(kprintf("%s/%s/%ld: Task=<%s>\n"__FILE__, __FUNC__, __LINE__, myTask->tc_Node.ln_Name)); + + if (0 != Stricmp(myTask->tc_Node.ln_Name, "Scalos_Window_Task") && + 0 != Stricmp(myTask->tc_Node.ln_Name, "Scalos_Drag&Drop")) + { + struct ScaUpdateIcon_IW Upd; + + Upd.ui_iw_Lock = iLock; + Upd.ui_iw_Name = Name; + + d1(kprintf("%s/%s/%ld: Lock=%08lx Name=<%s>\n"__FILE__, __FUNC__, __LINE__, iLock, Name)); + + SCA_UpdateIcon(WSV_Type_IconWindow, &Upd, sizeof(Upd)); + } + } + + return 0; +} +LIBFUNC_END + +/* ====================================================== */ + +static void UpdateVolumeGauge(struct Gadget *gad, struct Window *win, BPTR iLock) +{ + struct InfoData *id = AllocVec(sizeof(struct InfoData), MEMF_PUBLIC); + + if (id) + { + Info(iLock, id); + + d1(kprintf("%s/%s/%ld: NumBlocks=%lu NumBlocksUsed=%lu\n"__FILE__, __FUNC__, __LINE__, \ + id->id_NumBlocks, id->id_NumBlocksUsed)); + + SetGadgetAttrs(gad, win, NULL, + VOLUMEGAUGE_Level, id->id_NumBlocksUsed, + VOLUMEGAUGE_Max, id->id_NumBlocks, + TAG_END); + + FreeVec(id); + } +} + + +void _XCEXIT(long x) +{ +} + + +static LIBFUNC_P3(BOOL, myMakeWorkbenchObjectVisibleA, + A0, STRPTR, name, + A1, struct TagItem *, tags, + A6, struct Library *, WorkbenchBase) +{ + struct Process *myProc; + BPTR fLock; + // dLock = (BPTR)NULL; // unused + BOOL Result = FALSE; + + /* Suppress warning */ + (void)WorkbenchBase; + (void) tags; + + myProc = (struct Process *) FindTask(NULL); + if (NT_PROCESS == myProc->pr_Task.tc_Node.ln_Type) + { + // dLock = myProc->pr_CurrentDir; + } + + fLock = Lock(name, ACCESS_READ); + if (fLock) + { + struct ScaWindowStruct *swi; + BPTR parentLock = ParentDir(fLock); + + swi = FindWindowByLock(parentLock); + if (swi) + { + struct ScaIconNode *sIcon = GetIconByName(swi, FilePart(name)); + + if (sIcon) + { + Result = TRUE; + + MakeIconVisible(swi, sIcon); + ReleaseSemaphore(swi->ws_WindowTask->wt_IconSemaphore); + } + + SCA_UnLockWindowList(); + } + + UnLock(parentLock); + UnLock(fLock); + } + + return Result; +} +LIBFUNC_END + + +// ChangeWorkbenchSelectionA() +static LIBFUNC_P4(BOOL, myChangeWorkbenchSelectionA, + A0, STRPTR, name, + A1, struct Hook *, hook, + A2, struct TagItem *, tags, + A6, struct Library *, WorkbenchBase) +{ + struct ScaWindowStruct *swi = NULL; + BOOL Result = FALSE; + + /* Suppress warning */ + (void)WorkbenchBase; + + d1(kprintf("%s/%s/%ld: name=%08lx hook=%08lx tags=%08lx\n"__FILE__, __FUNC__, __LINE__, name, hook, tags)); + d1(kprintf("%s/%s/%ld: name=<%s>\n"__FILE__, __FUNC__, __LINE__, name ? name : (STRPTR) "")); + + if (name) + { + BPTR fLock = Lock(name, ACCESS_READ); + + d1(kprintf("%s/%s/%ld: fLock=%08lx\n"__FILE__, __FUNC__, __LINE__, fLock)); + if (fLock) + { + swi = FindWindowByLock(fLock); + + d1(kprintf("%s/%s/%ld: swi=%08lx\n"__FILE__, __FUNC__, __LINE__, swi)); + UnLock(fLock); + + if (swi) + SCA_UnLockWindowList(); + } + } + else + { + // get Workbench Backdrop window + swi = FindWindowByName("root"); + } + + d1(kprintf("%s/%s/%ld: swi=%08lx\n"__FILE__, __FUNC__, __LINE__, swi)); + + if (swi) + { + struct ScaWindowTask *wt = swi->ws_WindowTask; + struct ScaIconNode *icon; + BOOL GoOn = TRUE; + + Result = TRUE; + + ObtainSemaphore(wt->wt_IconSemaphore); + + for (icon=wt->wt_IconList; GoOn && icon; icon = (struct ScaIconNode *) icon->in_Node.mln_Succ) + { + struct ExtGadget *gg = (struct ExtGadget *) icon->in_Icon; + struct IconSelectMsg ism; + ULONG IconType; + WORD iconLeft, iconTop; + struct ScaWindowStruct *swiDrawer = GetIconNodeOpenWindow(swi->ws_Lock, icon); + + ism.ism_Name = NULL; + + GetAttr(IDTA_Text, icon->in_Icon, (ULONG *) &ism.ism_Name); + GetAttr(IDTA_Type, icon->in_Icon, (ULONG *) &IconType); + + d1(kprintf("%s/%s/%ld: icon=%08lx <%s> IconType=%ld swiDrawer=%08lx\n", \ + __LINE__, icon, ism.ism_Name, IconType, swiDrawer)); + + // Translate Scalos-specific icon types + switch (IconType) + { + case WB_TEXTICON_TOOL: + IconType = WBTOOL; + break; + case WB_TEXTICON_DRAWER: + IconType = WBDRAWER; + break; + default: + break; + } + + iconLeft = gg->BoundsLeftEdge + swi->ws_Window->BorderLeft - swi->ws_xoffset; + iconTop = gg->BoundsTopEdge + swi->ws_Window->BorderTop - swi->ws_yoffset; + + ism.ism_Length = sizeof(ism); + ism.ism_Drawer = swi->ws_Lock; + ism.ism_Type = IconType; + ism.ism_Selected = (gg->Flags & GFLG_SELECTED) ? TRUE : FALSE; + ism.ism_Tags = tags; + ism.ism_DrawerWindow = swiDrawer ? swiDrawer->ws_Window : NULL; + ism.ism_ParentWindow = swi->ws_Window; + ism.ism_Left = iconLeft; + ism.ism_Top = iconTop; + ism.ism_Width = gg->BoundsWidth; + ism.ism_Height = gg->BoundsHeight; + + switch (CallHookPkt(hook, NULL, &ism)) + { + case ISMACTION_Unselect: + d1(kprintf("%s/%s/%ld: ISMACTION_Unselect\n"__FILE__, __FUNC__, __LINE__)); + SelectIcon(swi, icon, FALSE); + break; + case ISMACTION_Select: + d1(kprintf("%s/%s/%ld: ISMACTION_Select\n"__FILE__, __FUNC__, __LINE__)); + SelectIcon(swi, icon, TRUE); + break; + case ISMACTION_Ignore: + d1(kprintf("%s/%s/%ld: ISMACTION_Ignore\n"__FILE__, __FUNC__, __LINE__)); + break; + case ISMACTION_Stop: + d1(kprintf("%s/%s/%ld: ISMACTION_Stop\n"__FILE__, __FUNC__, __LINE__)); + GoOn = FALSE; + break; + } + + if (swiDrawer) + SCA_UnLockWindowList(); + + if (ism.ism_Left != iconLeft || ism.ism_Top != iconTop) + { + d1(kprintf("%s/%s/%ld: oldLeft=%ld Left=%ld\n"__FILE__, __FUNC__, __LINE__, ism.ism_Left, iconLeft)); + d1(kprintf("%s/%s/%ld: oldTop=%ld Top=%ld\n"__FILE__, __FUNC__, __LINE__, ism.ism_Top, iconTop)); + + MoveIcon(swi, icon, + ism.ism_Left - swi->ws_Window->BorderLeft + swi->ws_xoffset, + ism.ism_Top - swi->ws_Window->BorderTop + swi->ws_yoffset); + } + } + + ReleaseSemaphore(wt->wt_IconSemaphore); + } + + d1(kprintf("%s/%s/%ld: Result=%ld\n"__FILE__, __FUNC__, __LINE__, Result)); // +dm+ 20010518 Added another %ld + + return Result; +} +LIBFUNC_END + + +// +dm+ 20010518 start +// Needed for not having to free the list structure also +static void FreeAllNodes(struct List *pl) +{ + struct Node *xNode; + + d1(kprintf("%s/%s/%ld: List=%08lx\n"__FILE__, __FUNC__, __LINE__, pl)); + if(pl) + { + while(xNode = RemHead(pl)) + { + d1(kprintf("%s/%s/%ld: Node=%08lx Name=%08lx Succ=%08lx\n"__FILE__, __FUNC__, __LINE__, xNode, xNode->ln_Name, xNode->ln_Succ)); + if(xNode->ln_Name) free(xNode->ln_Name); + free(xNode); + } + } +} +// +dm+ 20010518 end + +#ifdef __amigaos4__ +static LIBFUNC_P2VA(BOOL, myOpenWorkbenchObject, + A0, STRPTR, name, + A6, struct Library *, WorkbenchBase) +{ + BOOL ret; + struct WorkbenchIFace *IWorkbench = (struct WorkbenchIFace *)self; + va_list args; + va_startlinear(args, name); + + (void)WorkbenchBase; + + ret = OpenWorkbenchObjectA(name, va_getlinearva(args, const struct TagItem *)); + + va_end(args); + + return(ret); +} +LIBFUNC_END + +static LIBFUNC_P2VA(BOOL, myCloseWorkbenchObject, + A0, STRPTR, name, + A6, struct Library *, WorkbenchBase) +{ + BOOL ret; + struct WorkbenchIFace *IWorkbench = (struct WorkbenchIFace *)self; + va_list args; + va_startlinear(args, name); + + (void)WorkbenchBase; + + ret = CloseWorkbenchObjectA(name, va_getlinearva(args, const struct TagItem *)); + + va_end(args); + + return(ret); +} +LIBFUNC_END + +static LIBFUNC_P2VA(BOOL, myMakeWorkbenchObjectVisible, + A0, STRPTR, name, + A6, struct Library *, WorkbenchBase) +{ + BOOL ret; + struct WorkbenchIFace *IWorkbench = (struct WorkbenchIFace *)self; + va_list args; + va_startlinear(args, name); + + (void)WorkbenchBase; + + ret = MakeWorkbenchObjectVisibleA(name, va_getlinearva(args, const struct TagItem *)); + + va_end(args); + + return(ret); +} +LIBFUNC_END + +static LIBFUNC_P3VA(BOOL, myChangeWorkbenchSelection, + A0, STRPTR, name, + A1, struct Hook *, hook, + A6, struct Library *, WorkbenchBase) +{ + BOOL ret; + struct WorkbenchIFace *IWorkbench = (struct WorkbenchIFace *)self; + va_list args; + va_startlinear(args, hook); + + (void)WorkbenchBase; + + ret = ChangeWorkbenchSelectionA(name, hook, va_getlinearva(args, const struct TagItem *)); + + va_end(args); + + return(ret); +} +LIBFUNC_END + +#endif + +#ifdef __SASC +#elif !defined(__amigaos4__) /* __SASC */ + +void exit(int x) +{ + (void) x; + while (1) + ; +} + +APTR _WBenchMsg; + +#endif /* __SASC */ + diff --git a/scalos/Plugins/OOP/wb39_plugin/wb39.h b/scalos/Plugins/OOP/wb39_plugin/wb39.h new file mode 100644 index 000000000..c5832a572 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/wb39.h @@ -0,0 +1,113 @@ +// wb39.h +// $Date$ +// $Revision$ + + +#ifndef WB39_H_INCLUDED +#define WB39_H_INCLUDED + +//---------------------------------------------------------------------------- + +#include +#include + +//---------------------------------------------------------------------------- + +#define d(x) ; +#define d1(x) ; +#define d2(x) x; + +#define debugLock_d1(LockName) ; +#define debugLock_d2(LockName) \ + {\ + char xxName[200];\ + strcpy(xxName, "");\ + NameFromLock((LockName), xxName, sizeof(xxName));\ + KPrintF("%s/%s/%ld: " #LockName "=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, LockName, xxName);\ + } + +//---------------------------------------------------------------------------- + +struct myAppIcon + { + struct ScaAppObjNode mai_AppIconClone; // Copy of OrigAppIcon + struct TagItem *mai_TagListClone; // AddAppIcon() Taglist cloned by CloneTagItems(); + struct ScaAppObjNode *mai_OrigAppIcon; + }; + +struct myAppWindow + { + struct Node maw_Node; + + ULONG maw_Magic; // Magic ID = "MAWX" + + struct ScaAppObjNode *maw_AppWindow; + + struct MsgPort *maw_origMsgPort; // original AddAppWindowA MsgPort + ULONG maw_origUserData; // original AddAppWindowA UserData + + struct List maw_DropZoneList; + struct SignalSemaphore maw_Sema; // Semaphore for maw_DropZoneList + + struct myAppWindowDropZone *maw_ActiveDropZone; + }; + +struct myAppWindowDropZone + { + struct Node awz_Node; + + struct myAppWindow *awz_AppWindow; + + struct IBox awz_DropBox; + struct IBox awz_MeasureBox; // original dimensions, may be <0 if relative + + BOOL awz_RelBottom; + BOOL awz_RelRight; + BOOL awz_RelWidth; + BOOL awz_RelHeight; + + ULONG awz_ID; + ULONG awz_UserData; + + struct Hook *awz_Hook; + }; + + +// aus debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + + +// node type for workbench lists +#define NT_WB 0x67 + + +// Hunk IDs in Worbench prefs file + +#define ID_PREF MAKE_ID('P','R','E','F') +#define ID_WBNC MAKE_ID('W','B','N','C') +#define ID_WBHD MAKE_ID('W','B','H','D') + +// Offsets of several WB prefs settings in WBNC hunk +enum WBPrefsItems + { + wpi_DefaultStackSize_Hi = 0, // ULONG : 0,1 + wpi_DefaultStackSize_Lo = 1, // ULONG : 0,1 + wpi_KeyboardRestart = 3, // keyboard restart delay in seconds + wpi_UseNewIcons = 13, + wpi_NoColorIcons = 14, + wpi_SetMWBColor = 17, + wpi_NoTitleBar = 18, + wpi_NoVolumeGauge = 19, + }; + + +// Instance structure for overriden window.sca class +struct WB39inst + { + Object *wb39i_VolumeGaugeObject; + }; + +//---------------------------------------------------------------------------- + +#endif /* WB39_H_INCLUDED */ diff --git a/scalos/Plugins/OOP/wb39_plugin/wb39proto.h b/scalos/Plugins/OOP/wb39_plugin/wb39proto.h new file mode 100644 index 000000000..04358a691 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/wb39proto.h @@ -0,0 +1,107 @@ +// wb39proto.h +// $Date$ +// $Revision$ + + +#ifndef WB39PROTO_H_INCLUDED +#define WB39PROTO_H_INCLUDED + +#include +#include "Scalos_Helper.h" + + +// AppWindow.c +BOOL DetachMyProcess(void); +void ShutdownMyProcess(void); +LIBFUNC_P5_PROTO(struct myAppWindowDropZone *, myAddAppWindowDropZoneA, + A0, struct myAppWindow *, maw, + D0, ULONG, id, + D1, ULONG, userdata, + A1, struct TagItem *, tags, + A6, struct Library *, WorkbenchBase); +LIBFUNC_P3_PROTO(BOOL, myRemoveAppWindowDropZone, + A0, struct myAppWindow *, maw, + A1, struct myAppWindowDropZone *, dropZone, + A6, struct Library *, WorkbenchBase); +LIBFUNC_P6_PROTO(struct myAppWindow *, myAddAppWindowA, + D0, ULONG, id, + D1, ULONG, userdata, + A0, struct Window *, window, + A1, struct MsgPort *, msgport, + A2, struct TagItem *, taglist, + A6, struct Library *, WorkbenchBase); +LIBFUNC_P2_PROTO(BOOL, myRemoveAppWindow, + A0, struct myAppWindow *, appWindow, + A6, struct Library *, WorkbenchBase); +LIBFUNC_P5_PROTO(void, mySCA_DrawDrag, + A0, APTR, draghandle, + D0, LONG, X, + D1, LONG, Y, + D2, LONG, Flags, + A6, struct Library *, ScalosBase); + +#ifdef __amigaos4__ +LIBFUNC_P4VA_PROTO(struct AppWindowDropZone *, myAddAppWindowDropZone, + A0, struct AppWindow *, maw, + D0, ULONG, id, + D1, ULONG, userdata, + A6, struct Library *, WorkbenchBase); +LIBFUNC_P5VA_PROTO(struct AppWindow *, myAddAppWindow, + D0, ULONG, id, + D1, ULONG, userdata, + A0, struct Window *, window, + A1, struct MsgPort *, msgport, + A6, struct Library *, WorkbenchBase); +#endif + +// WorkbenchControl.c +LIBFUNC_P3_PROTO(BOOL, myWorkbenchControlA, + A0, STRPTR, name, + A1, struct TagItem *, tags, + A6, struct Library *, WorkbenchBase); + +#ifdef __amigaos4__ +LIBFUNC_P2VA_PROTO(BOOL, myWorkbenchControl, + A0, STRPTR, name, + A6, struct Library *, WorkbenchBase); +#endif + +// AppIcons.c +BOOL AppIconsInit(void); +void AppIconsCleanup(void); + + +// Scalos_Helper.c +ULONG MenuOpenParentWindow(struct ScaWindowStruct *swi); +ULONG MenuUnselectAll(struct ScaWindowStruct *swi); +ULONG MenuSetViewModeByIcon(struct ScaWindowStruct *swi); +ULONG MenuSetViewModeByName(struct ScaWindowStruct *swi); +ULONG MenuSetViewModeBySize(struct ScaWindowStruct *swi); +ULONG MenuSetViewModeByDate(struct ScaWindowStruct *swi); +ULONG MenuSetViewModeByType(struct ScaWindowStruct *swi); +ULONG MenuShowAllFiles(struct ScaWindowStruct *swi); +BOOL ParseWBPrefs(CONST_STRPTR filename); +BOOL ReadScalosPrefs(void); +struct ScaWindowStruct *GetIconNodeOpenWindow(BPTR dirLock, struct ScaIconNode *sIcon); +struct ScaIconNode *GetIconByName(struct ScaWindowStruct *swi, CONST_STRPTR IconName); +struct ScaWindowStruct *FindWindowByLock(BPTR xLock); +void MakeIconVisible(struct ScaWindowStruct *swi, struct ScaIconNode *sIcon); +void MoveIcon(struct ScaWindowStruct *swi, struct ScaIconNode *sIcon, LONG x, LONG y); +void SelectIcon(struct ScaWindowStruct *swi, struct ScaIconNode *sIcon, BOOL Selected); +struct ScaWindowStruct *FindWindowByName(CONST_STRPTR WinName); +BOOL CloseScalosWindow(struct ScaWindowStruct *swi); +BOOL UpdateScalosWindow(struct ScaWindowStruct *swi); +struct ScaWindowStruct *GetNextWindow(struct ScaWindowStruct *swi); +struct ScaWindowStruct *GetPrevWindow(struct ScaWindowStruct *swi); +BOOL DeleteDirectory(CONST_STRPTR Path); +BOOL RemScalosIcon(BPTR Lock, CONST_STRPTR Name); +BOOL isIconSelected(const struct ScaIconNode *icon); +struct ScaRootList *GetScalosRootList(void); +ULONG MenuNewDrawer(CONST_STRPTR Name); +ULONG MenuUpdateScalosWindow(struct ScaWindowStruct *swi); +ULONG MenuCloseScalosWindow(struct ScaWindowStruct *swi); +CONST_STRPTR GetIconName(struct ScaIconNode *in); +struct ScaWindowStruct *WaitOpen(struct ScaWindowStruct *ws); + + +#endif diff --git a/scalos/Plugins/OOP/wb39_plugin/wbrexx/MenuTest.rexx b/scalos/Plugins/OOP/wb39_plugin/wbrexx/MenuTest.rexx new file mode 100755 index 000000000..f97ae5395 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/wbrexx/MenuTest.rexx @@ -0,0 +1,11 @@ +/* test */ +address WORKBENCH; + +MENU REMOVE NAME test4 +MENU REMOVE NAME test5 +MENU REMOVE NAME test6 + +MENU ADD NAME test4 TITLE '"Say something\Hello"' CMD "'say hello'"; +MENU ADD NAME test5 TITLE '"Say something\World"' CMD "'say world"; + +MENU ADD NAME test6 TITLE '"\New title\Say something\Hello"' CMD "'say hello"; diff --git a/scalos/Plugins/OOP/wb39_plugin/wbrexx/RexxCmd.c b/scalos/Plugins/OOP/wb39_plugin/wbrexx/RexxCmd.c new file mode 100644 index 000000000..2029832a9 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/wbrexx/RexxCmd.c @@ -0,0 +1,2768 @@ +// RexxCmd.c +// $Date$ +// $Revision$ + + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + + +//#include "wb39.h" +#include "wbrexx.h" +#include "Scalos_Helper.h" +//#include "wb39proto.h" + + +static LONG OpenWBHelpFile(void); +static SAVEDS(void) WBHelpProcess(void); + +#if !defined(__SASC) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) +static size_t stccpy(char *dest, const char *src, size_t MaxLen); +#endif /* !defined(__SASC) && !defined(__MORPHOS__) */ + +// aus wb39.c +extern struct ScaRootList *rList; + +extern T_UTILITYBASE UtilityBase; +extern struct DosLibrary *DOSBase; +extern struct IntuitionBase *IntuitionBase; +extern struct GfxBase *GfxBase; +extern struct Library *LayersBase; +extern struct Library *WorkbenchBase; +extern struct Library *IconBase; + + +#if 0 +------------------------------------------------------------------------------ +ACTIVATEWINDOW command + +Purpose: + +This command will attempt to make a window the active one. + +Format: + +ACTIVATEWINDOW [WINDOW] + +Template: + +ACTIVATEWINDOW WINDOW + +Parameters: + +WINDOW + +Either ROOT to activate the Workbench root window (where volume icons and +AppIcons live) or the fully qualified name of a drawer window to activate. +Note that the drawer window must already be open. + +If no WINDOW parameter is specified, this command will try to operate on the +currently active Workbench window. + +Errors: + +10 - If the named window cannot be activated. The error code will be placed +in the WORKBENCH.LASTERROR variable. + +Result: + +- + +Notes: + +If you choose to have a window activated that is not the root window you must +make sure that the window name is given as a fully qualified path name. For +example Work: is a fully qualified name, and so is SYS:Utilities. +Devs/Printers would not be a fully qualified name. A fully qualified name +always contains the name of an assignment, a volume or a device. + +Example: + +/* Activate the root window. */ ADDRESS workbench +ACTIVATEWINDOW root + +/* Activate the Work: partition`s window. */ +ACTIVATEWINDOW ,Work:` +------------------------------------------------------------------------------ +#endif +LONG Cmd_ActivateWindow(APTR UserData, struct RexxMsg *Message, STRPTR *Args) +{ + enum { ARG_WINDOW }; + LONG Result = RETURN_OK; + char *ResultString = NULL; + struct ScaWindowStruct *swi; + + d(kprintf(__FUNC__ "/%ld: Window=<%s>\n", __LINE__, Args[ARG_WINDOW] ? Args[ARG_WINDOW] : (STRPTR) "");) + + if (Args[ARG_WINDOW]) + swi = FindWindowByName(Args[ARG_WINDOW]); + else + swi = FindWindowByName("active"); + + if (NULL == swi) + return(ERROR_OBJECT_NOT_FOUND); + + ActivateWindow(swi->ws_Window); + + d(kprintf(__FUNC__ "/%ld: Result=%ld\n", __LINE__, Result);) + + if (RETURN_OK == Result) + ReturnRexxMsg(Message, ResultString); + + return Result; +} + + + +#if 0 +------------------------------------------------------------------------------ +CHANGEWINDOW command + +Purpose: + +This command will attempt to change the size and the position of a window. + +Format: + +CHANGEWINDOW [WINDOW] [[LEFTEDGE] ][[TOPEDGE] ][[WIDTH] ][[HEIGHT] ] + +Template: + +CHANGEWINDOW WINDOW,LEFTEDGE/N,TOPEDGE/N,WIDTH/N,HEIGHT/N + +Parameter: + +WINDOW + +Either ROOT to resize/move the Workbench root window (where volume icons and +AppIcons live), ACTIVE to change the currently active Workbench window or +the fully qualified name of a drawer window to change. Note that the drawer +window must already be open. + +If no WINDOW parameter is specified, this command will try to operate on the +currently active Workbench window. + +LEFTEDGE + +New left edge window position. + +TOPEDGE + +New top edge window position. + +WIDTH + +New window width. + +HEIGHT + +New window height. + +Errors: + +10 - If the named window cannot be changed; this can also happen if you +specified ACTIVE as the window name and none of the Workbench windows is +currently active. The error code will be placed in the WORBENCH.LASTERROR +variable. + +Result: + +- + +Notes: + +If you choose to have a window changed that is neither the root nor the +active window you must make sure that the window name is given as a fully +qualified path name. For example Work: is a fully qualified name, and so is +SYS:Utilities. Devs/Printers would not be a fully qualified name. A fully +qualified name always contains the name of an assignment, a volume or a +device. + +Example: + +/* Change the root window; move it to position 10,30. * and change its size +to 200100 pixels. */ +ADDRESS workbench +CHANGEWINDOW root LEFTEDGE 10 TOPEDGE 30 WIDTH 200 HEIGHT 100 + +/* Change the currently active window. */ +CHANGEWINDOW active 20 40 200 100 + + +------------------------------------------------------------------------------ +#endif +LONG Cmd_ChangeWindow(APTR UserData, struct RexxMsg *Message, STRPTR *Args) +{ + enum { ARG_WINDOW, ARG_LEFTEDGE, ARG_TOPEDGE, ARG_WIDTH, ARG_HEIGHT }; + LONG Result = RETURN_OK; + char *ResultString = NULL; + struct ScaWindowStruct *swi; + WORD Left, Top, Width, Height; + + d(kprintf(__FUNC__ "/%ld: Window=<%s>\n", __LINE__, Args[ARG_WINDOW] ? Args[ARG_WINDOW] : (STRPTR) "");) + + if (Args[ARG_WINDOW]) + swi = FindWindowByName(Args[ARG_WINDOW]); + else + swi = FindWindowByName("active"); + + if (NULL == swi) + return(ERROR_OBJECT_NOT_FOUND); + + if (Args[ARG_LEFTEDGE]) + Left = *((LONG *) Args[ARG_LEFTEDGE]); + else + Left = swi->ws_Window->LeftEdge; + if (Args[ARG_TOPEDGE]) + Top = *((LONG *) Args[ARG_TOPEDGE]); + else + Top = swi->ws_Window->TopEdge; + if (Args[ARG_WIDTH]) + Width = *((LONG *) Args[ARG_WIDTH]); + else + Width = swi->ws_Window->Width; + if (Args[ARG_HEIGHT]) + Height = *((LONG *) Args[ARG_HEIGHT]); + else + Height = swi->ws_Window->Height; + + ChangeWindowBox(swi->ws_Window, Left, Top, Width,Height); + + DoMethod(swi->ws_WindowTask->mt_MainObject, + SCCM_IconWin_SetVirtSize, SETVIRTF_AdjustRightSlider | SETVIRTF_AdjustBottomSlider); + + d(kprintf(__FUNC__ "/%ld: Result=%ld\n", __LINE__, Result);) + + if (RETURN_OK == Result) + ReturnRexxMsg(Message, ResultString); + + return Result; +} + + +#if 0 +------------------------------------------------------------------------------ +DELETE command + +Purpose: + +This command is for deleting files and drawers (and their contents). + +Format: + +DELETE [NAME] [ALL] + +Template: + +DELETE NAME/A,ALL/S + +Parameters: + +NAME + +Name of the file or drawer or volume to delete. + +ALL + +If the object in question is a drawer, attempt to delete the contents of the +drawer as well as the drawer itself. If this option is not specified, the +DELETE command will only attempt to delete the drawer itself, which may fail +if the drawer is not yet empty. + +Errors: + +10 - If the named file, drawer or volume could not be found or could not be +deleted. + +Result: + +- + +Notes: + +The file name given must be an absolute path, such as in RAM:Empty. A +relative path, such as /fred/barney will not work. + +Example: + +/* Delete the contents of the drawer RAM:Empty. */ + +ADDRESS workbench +DELETE ,RAM:Empty` ALL + + +------------------------------------------------------------------------------ +#endif +LONG Cmd_Delete(APTR UserData, struct RexxMsg *Message, STRPTR *Args) +{ + enum { ARG_NAME, ARG_ALL }; + LONG Result = RETURN_OK; + char *ResultString = NULL; + + d1(kprintf(__FUNC__ "/%ld: Name=<%s>\n", __LINE__, Args[ARG_NAME]);) + + if (Args[ARG_ALL]) + { + if (DeleteDirectory(Args[ARG_NAME])) + { + // Object deleted, now delete icon + if (!DeleteDiskObject(Args[ARG_NAME])) + { + Result = IoErr(); + + // ignore errors from missing icons + if (ERROR_OBJECT_NOT_FOUND == Result) + Result = RETURN_OK; + } + } + else + Result = IoErr(); + } + else + { + if (DeleteFile(Args[ARG_NAME])) + { + // Object deleted, now delete icon + if (!DeleteDiskObject(Args[ARG_NAME])) + { + Result = IoErr(); + + // ignore errors from missing icons + if (ERROR_OBJECT_NOT_FOUND == Result) + Result = RETURN_OK; + } + } + else + Result = IoErr(); + } + + d(kprintf(__FUNC__ "/%ld: Result=%ld\n", __LINE__, Result);) + + if (RETURN_OK == Result) + ReturnRexxMsg(Message, ResultString); + + return Result; +} + + +#if 0 +------------------------------------------------------------------------------ +FAULT command + +Purpose: + +This command will return a human readable explanation corresponding to an +error code. + +Format: + +FAULT [CODE] + +Template: + +FAULT CODE/A/N + +Parameters: + +CODE + +Error code to return a human readable explanation for. + +Errors: + +- + +Result: + +- + +Example: + +/* Query the error message corresponding to error code #205. */ +ADDRESS workbench +OPTIONS RESULTS +FAULT 205 +SAY result + + +------------------------------------------------------------------------------ +#endif +LONG Cmd_Fault(APTR UserData,struct RexxMsg *Message,STRPTR *Args) +{ + enum { ARG_NUMBER }; + + UBYTE ErrorText[100]; + LONG Number; + + Number = *(LONG *)Args[ARG_NUMBER]; + + Printf("FAULT %d",Number); + Printf("\n"); + + /* Obtain the AmigaDOS error text corresponding + * to the error code. In your own applications + * you would want to supply descriptive texts + * for each error code your program supports + * in addition to the standard AmigaDOS set. + */ + + if(Fault(Number,"",(STRPTR)ErrorText,99) > 0) + { + ReturnRexxMsg(Message,(STRPTR)&ErrorText[2]); + + return(0); + } + else + return(ERROR_OBJECT_NOT_FOUND); +} + + +#if 0 +------------------------------------------------------------------------------ +HELP command + +Purpose: + +This command can be used to open the online help and to obtain information on +the supported menus, commands and command parameters. + +Format: + +HELP [COMMAND ] [MENUS] [PROMPT] + +Template: + +HELP COMMAND/K,MENUS/S,PROMPT/S + +Parameters: + +COMMAND + +Name of the command whose command template should be retrieved. + +MENUS + +Specify this parameter to retrieve a list of menu items currently available. + +PROMPT + +Specify this parameter to invoke the online help system. + +If no parameter is provided, a list of supported commands will be returned. + +Errors: + +10 - If the named command is not supported by the ARexx interface. The error +code will be placed in the WORKBENCH.LASTERROR variable. + +Result: + +RESULT + +The command template, list of menu items or commands, as specified in the +command parameters. + +Example: + +/* Retrieve the list of supported commands. */ +ADDRESS workbench +OPTIONS results + +HELP +SAY result + +/* Retrieve the command template of the `GETATTR` command. */ +HELP COMMAND getattr +SAY result + +/* Retrieve the list of available menu items. */ +HELP MENUS +SAY result + + +------------------------------------------------------------------------------ +#endif +LONG Cmd_Help(APTR UserData,struct RexxMsg *Message,STRPTR *Args) +{ + enum { ARG_COMMAND,ARG_MENUS,ARG_PROMPT }; + + struct LocalData *LocalData; + struct CmdFunc *Table; + STRPTR String; + STRPTR Command; + LONG Len; + LONG i; + + if (Args[ARG_PROMPT]) + { + return OpenWBHelpFile(); + } + else + { + LocalData = (struct LocalData *)UserData; + + Table = LocalData->CommandTable; + + /* If no command is specified then we should + * return a list of all the commands this host + * supports. + */ + + if(Args[ARG_COMMAND] == NULL) + { + /* Count the number of bytes to allocate + * for a list of all commands. + */ + for(i = 0, Len = 1 ; Table[i].CommandName ; i++) + Len += strlen(Table[i].CommandName) + 1; + + /* Make room for the command list. */ + String = AllocVec(Len,MEMF_ANY); + + if(String == NULL) + return(ERROR_NO_FREE_STORE); + else + { + /* Start with an empty string. */ + String[0] = 0; + + /* Add all the commands to the list. */ + for(i = 0 ; Table[i].CommandName ; i++) + { + strcat(String,Table[i].CommandName); + strcat(String," "); + } + + /* Terminate the string. */ + String[Len - 1] = 0; + + /* Reply the RexxMsg and return the + * command list as the command result. + */ + ReturnRexxMsg(Message,String); + + /* Dispose of the temporary storage. */ + FreeVec(String); + + return(0); + } + } + else + { + /* So we should return the argument template + * of a specific command. + */ + Command = Args[ARG_COMMAND]; + + /* Try to find the command in the table. */ + for(i = 0 ; Table[i].CommandName ; i++) + { + /* Is this the command we are + * looking for? + */ + if(Stricmp(Table[i].CommandName,Command) == 0) + { + /* Get the argument template. */ + String = Table[i].Template; + + /* Is the template an empty + * string? + */ + if(String[0] == '\0') + { + /* Provide an empty template. */ + String = ","; + } + + /* Reply the RexxMsg and return + * the template as the command + * result. + */ + ReturnRexxMsg(Message,String); + + return(0); + } + } + + /* No matching command was found. */ + return(ERROR_OBJECT_NOT_FOUND); + } + } +} + + +#if 0 +------------------------------------------------------------------------------ +INFO command + +Purpose: + +This command is for opening the Workbench icon information requester. + +Format: + +INFO [NAME] + +Template: + +INFO NAME/A + +Parameters : + +NAME + +Name of the file, drawer or volume to open the information window for. + +Errors: + +10 - If the named file, drawer or volume could not be found. The error code +will be placed in the WORKBENCH.LASTERROR variable. + +Result: + +- + +Example: + +/* Open the information window for SYS:. */ +ADDRESS workbench + +INFO NAME ,SYS:` + + +------------------------------------------------------------------------------ +#endif +LONG Cmd_Info(APTR UserData, struct RexxMsg *Message, STRPTR *Args) +{ + enum { ARG_NAME }; + LONG Result = RETURN_OK; + BPTR fLock; + char *ResultString = NULL; + + d1(kprintf(__FUNC__ "/%ld: Name=<%s>\n", __LINE__, Args[ARG_NAME]);) + + fLock = Lock(Args[ARG_NAME], ACCESS_READ); + if (fLock) + { + WBInfo((BPTR)NULL, Args[ARG_NAME], rList->rl_internInfos->ii_Screen); + UnLock(fLock); + } + else + Result = ERROR_OBJECT_NOT_FOUND; + + d(kprintf(__FUNC__ "/%ld: Result=%ld\n", __LINE__, Result);) + + if (RETURN_OK == Result) + ReturnRexxMsg(Message, ResultString); + + return Result; +} + + +#if 0 +------------------------------------------------------------------------------ +KEYBOARD command + +Purpose: + +This command can be used to bind ARexx commands to key combinations. + +Format: + +KEYBOARD [NAME] ADD|REMOVE [KEY ] +[CMD ] + +Template: + +KEYBOARD NAME/A,ADD/S,REMOVE/S,KEY,CMD/F + +Parameters: + +NAME + +Name of the key combination to add or remove. Each key combination must have +a name with which it is associated. The name must be unique. + +ADD + +This tells the KEYBOARD command to add a new keyboard combination. You will +also need to specify the KEY and CMD parameters. + +REMOVE + +This tells the KEYBOARD command to remove an existing keyboard combination. + +KEY + +The keyboard combination to add; this must be in the same format as used by +the Commodities programs. + +CMD + +This is the ARexx command to bind to the keyboard combination. The command +can either be the name of an ARexx script to execute or a short ARexx program +in a single line. + +Errors: + +10 - The command will fail if you tried to add a duplicate of an existing key +combination or if the key combination to remove does not exist. The error +code will be placed in the WORKBENCH.LASTERROR variable. + +Result: + +- + +Example: + +/* Bind an ARexx script to the [Control]+A key combination. * When pressed, +this will cause the ARexx script by the name * test.wb to be executed. ARexx +will search for that program * in the REXX: directory. If no test.wb file +can * be found, ARexx will attempt to execute a script * by the name of +test.rexx. */ + +ADDRESS workbench + +KEYBOARD ADD NAME test1 KEY ,ctrl a, CMD ,test` + +/* Bind an ARexx script to the [Alt]+[F1] key combination. * When pressed, +this will cause a short inline program to be * executed. */ +KEYBOARD ADD NAME test2 KEY ,alt f1, CMD `say 42 + +/* Bind an ARexx script to the [Shift]+[Help] key combination. * When +pressed, this will cause the Workbench About menu item * to be invoked. */ +KEYBOARD ADD NAME test3 KEY ,shift help, CMD `MENU INVOKE WORKBENCH.ABOUT + +/* Remove the first key combination we added above. */ +KEYBOARD REMOVE NAME test1 + + +------------------------------------------------------------------------------ +#endif +LONG Cmd_Keyboard(APTR UserData, struct RexxMsg *Message, STRPTR *Args) +{ + enum { ARG_NAME, ARG_ADD, ARG_REMOVE, ARG_KEY, ARG_CMD }; + LONG Result = RETURN_OK; + char *ResultString = NULL; + + d1(kprintf(__FUNC__ "/%ld: Name=<%s>\n", __LINE__, Args[ARG_NAME]);) + + if (NULL == Args[ARG_ADD] && NULL == Args[ARG_REMOVE]) + return ERROR_REQUIRED_ARG_MISSING; + + if (Args[ARG_ADD]) + { + d1(kprintf(__FUNC__ "/%ld: ADD\n", __LINE__);) + + if (NULL == Args[ARG_NAME]) + return ERROR_REQUIRED_ARG_MISSING; + if (NULL == Args[ARG_KEY]) + return ERROR_REQUIRED_ARG_MISSING; + if (NULL == Args[ARG_CMD]) + return ERROR_REQUIRED_ARG_MISSING; + + Result = AddKeyboardCommand(Args[ARG_NAME], Args[ARG_KEY], Args[ARG_CMD]); + } + else if (Args[ARG_REMOVE]) + { + d1(kprintf(__FUNC__ "/%ld: REMOVE\n", __LINE__);) + + if (NULL == Args[ARG_NAME]) + return ERROR_REQUIRED_ARG_MISSING; + + Result = RemoveKeyboardCommand(Args[ARG_NAME]); + } + + d(kprintf(__FUNC__ "/%ld: Result=%ld\n", __LINE__, Result);) + + if (RETURN_OK == Result) + ReturnRexxMsg(Message, ResultString); + + return Result; +} + + +#if 0 +------------------------------------------------------------------------------ +LOCKGUI command + +Purpose: + +This command will block access to all Workbench drawer windows. + +Format: + +LOCKGUI + +Template: + +LOCKGUI + +Parameters: + +- + +Errors: + +- + +Result: + +- + +Notes: + +It takes as many UNLOCKGUI commands as there were LOCKGUI commands to make +the Workbench drawer windows usable again. In other words, the LOCKGUI +command nests. + +Example: + +/* Block access to all Workbench drawer windows. */ +ADDRESS workbench + +LOCKGUI + + +------------------------------------------------------------------------------ +#endif +LONG Cmd_LockGUI(APTR UserData, struct RexxMsg *Message, STRPTR *Args) +{ + LONG Result = RETURN_OK; + char *ResultString = NULL; + + /* !!! */ + + d(kprintf(__FUNC__ "/%ld: Result=%ld\n", __LINE__, Result);) + + if (RETURN_OK == Result) + ReturnRexxMsg(Message, ResultString); + + return Result; +} + + +#if 0 +------------------------------------------------------------------------------ +UNZOOMWINDOW command + +Purpose: + +This command will attempt return a window to its original position and +dimensions. + +Format: + +UNZOOMWINDOW [WINDOW] + +Template: + +UNZOOMWINDOW WINDOW + +Parameters: + +WINDOW + +Name of the window to operate on. ROOT will use the Workbench root window +(where volume icons and AppIcons live), ACTIVE will use the currently active +Workbench window. Any other fully qualified path name will use the drawer +window corresponding to the path. If no WINDOW parameter is specified, this +command will try to operate on the currently active Workbench window. + +Errors: + +10 - If the named window cannot be found. The error code will be placed in +the WORKBENCH.LASTERROR variable. + +Result: + +- + +Example: + +/* Change the root window. */ +ADDRESS workbench + +UNZOOMWINDOW root + + +------------------------------------------------------------------------------ +#endif +LONG Cmd_UnzoomWindow(APTR UserData, struct RexxMsg *Message, STRPTR *Args) +{ + enum { ARG_WINDOW }; + LONG Result = RETURN_OK; + char *ResultString = NULL; + struct ScaWindowStruct *swi; + + d(kprintf(__FUNC__ "/%ld: Window=<%s>\n", __LINE__, Args[ARG_WINDOW] ? Args[ARG_WINDOW] : (STRPTR) "");) + + if (Args[ARG_WINDOW]) + swi = FindWindowByName(Args[ARG_WINDOW]); + else + swi = FindWindowByName("active"); + + if (NULL == swi) + return(ERROR_OBJECT_NOT_FOUND); + + if (swi->ws_Window->Flags & WFLG_HASZOOM) + { + if (swi->ws_Window->Flags & WFLG_ZOOMED) + ZipWindow(swi->ws_Window); + } + + d(kprintf(__FUNC__ "/%ld: Result=%ld\n", __LINE__, Result);) + + if (RETURN_OK == Result) + ReturnRexxMsg(Message, ResultString); + + return Result; +} + + +#if 0 +------------------------------------------------------------------------------ +MENU command + +Purpose: + +This command is for invoking items of the Workbench menu, as if the user had +selected them with the mouse and for adding/removing user menus. + +Format: + +MENU [WINDOW ] [INVOKE]

[NAME ] [TITLE +] [SHORTCUT ] [ADD|REMOVE] [CMD ] + +Template: + +MENU WINDOW/K,INVOKE,NAME/K,TITLE/K,SHORTCUT/K,ADD/S,REMOVE/S,CMD/K/F + +Parameters: + +The following set of parameters can be used solely for invoking menu items. + +WINDOW + +Name of the window whose menu should be invoked. This can be ROOT to work on +the Workbench root window (where volume icons and AppIcons live), ACTIVE to +work on the currently active Workbench window or the fully qualified name of +a drawer window. Note that the drawer window must already be open. + +If no WINDOW parameter is specified, this command will try to operate on the +currently active Workbench window. + +INVOKE + +Name of the menu to invoke. See below for a list of available menu items. + +The following set of parameters are for adding and removing menu items. + +NAME + +Name of the menu item to add or remove. Each menu item must have a name with +which it is associated. The name must be unique and has nothing to do with +the title of the item, as shown in the Tools menu. + +TITLE + +This is the text that will be used as the menu item title, as it will appear +in the Tools menu. This parameter is required if you ADD a new menu item. + +SHORTCUT + +When adding a new menu item, this will be the menu shortcut associated with +the item. Please note that the shortcut cannot be longer than a single +character and that it will be ignored if there already is an item in any of +the menus which uses this shortcut. This parameter is optional. + +ADD + +This tells the MENU command to add a new item to the Tools menu. When adding +a menu item you will also need to specify the NAME, TITLE and CMD parameters. + +REMOVE + +This tells the MENU command to remove a menu item previously added via the +ARexx interface. When removing a menu item you will also need to specify the +NAME parameter. + +CMD + +This is the ARexx command to bind to the new menu item. The command can +either be the name of an ARexx script to execute or a short ARexx program in +a single line. + +Menu items: + +WORKBENCH.BACKDROP + +Toggles the Workbench Backdrop window switch. + +WORKBENCH.EXECUTE + +Invokes the Workbench Execute Command requester. The user will be prompted +to enter the command to be executed. + +WORKBENCH.REDRAWALL + +Invokes the Workbench Redraw All function. + +WORKBENCH.UPDATEALL + +Invokes the Workbench Update All function. + +WORKBENCH.LASTMESSAGE + +Redisplays the last Workbench error message. + +WORKBENCH.ABOUT + +Displays the Workbench About... requester. + +WORKBENCH.QUIT + +Attempts to close Workbench; this may bring up a requester the user will have +to answer. + +WINDOW.NEWDRAWER + +Prompts the user to enter the name of a new drawer to be created. + +WINDOW.OPENPARENT + +If possible, this will open the parent directory of the drawer the command +operates on. + +WINDOW.CLOSE + +If possible, this will close the drawer the command operates on. + +WINDOW.UPDATE + +This will update the drawer the command operates on, i.e. the contents will +be reread. + +WINDOW.SELECTCONTENTS + +This will select the contents of the drawer the command operates on. + +WINDOW.CLEARSELECTION + +This unselects all icons selected in the drawer the command operates on. + +WINDOW.CLEANUPBY.COLUMN + +This will sort the contents of the drawer and place the icons in columns. + +WINDOW.CLEANUPBY.NAME + +This will sort the contents of the drawer by name and place the icons in +rows. + +WINDOW.CLEANUPBY.DATE + +This will sort the contents of the drawer by date and place the icons in +rows. + +WINDOW.CLEANUPBY.SIZE + +This will sort the contents of the drawer by size and place the icons in +rows. + +WINDOW.CLEANUPBY.TYPE + +This will sort the contents of the drawer by type and place the icons in +rows. + +WINDOW.RESIZETOFIT + +This will resize the drawer window, trying to make it just as large as to +allow all its icons to fit. + +WINDOW.SNAPSHOT.WINDOW + +This will snapshot the drawer window, but none of its contents. + +WINDOW.SNAPSHOT.ALL + +This will snapshot the drawer window and its contents. + +WINDOW.SHOW.ONLYICONS + +This will change the display mode of the drawer to show only files and +drawers which have icons attached. + +WINDOW.SHOW.ALLFILES + +This will change the display mode of the drawer to show all files and +drawers, regardless of whether they have icons attached or not. + +WINDOW.VIEWBY.ICON + +This will change the display mode of the drawer to show its contents as +icons. + +WINDOW.VIEWBY.NAME + +This will change the display mode of the drawer to show its contents in +textual format, sorted by name. + +WINDOW.VIEWBY.DATE + +This will change the display mode of the drawer to show its contents in +textual format, sorted by date. + +WINDOW.VIEWBY.SIZE + +This will change the display mode of the drawer to show its contents in +textual format, sorted by size. + +WINDOW.VIEWBY.TYPE + +This will change the display mode of the drawer to show its contents in +textual format, sorted by type. + +ICONS.OPEN + +This will open the currently selected icons. Workbench may bring up a requester in case project icons are found which lack a default tool. + +ICONS.COPY + +This will duplicate the currently selected icons. + +ICONS.RENAME + +This will prompt the user to choose a new name for each currently selected icon. + +ICONS.INFORMATION + +This will open the information window for every currently selected icon. + +ICONS.SNAPSHOT + +This will lock the position of every currently selected icon. + +ICONS.UNSNAPSHOT + +This will unlock the position of every currently selected icon. + +ICONS.LEAVEOUT + +This will permanently put all currently selected icons on the Workbench root window. + +ICONS.PUTAWAY + +This will move all currently selected icons out of the root window and put them back into the drawers they belong. + +ICONS.DELETE + +This will cause all currently selected files to be deleted, provided the user confirms this action first. + +ICONS.FORMATDISK + +This will invoke the Format command on every currently selected disk icon. This will not format the disks immediately. The user will have to confirm this action first. + +ICONS.EMPTYTRASH + +With a trashcan icon selected, this will empty it. + +TOOLS.RESETWB + +This will close and reopen all Workbench windows. + +------------------------------------------------------------------------------ +#endif + +static const struct InvokeMenu WBMenus[] = + { + { "WORKBENCH.BACKDROP", FALSE, "backdrop", NULL }, + { "WORKBENCH.EXECUTE", FALSE, "executecommand", NULL }, + { "WORKBENCH.REDRAWALL", FALSE, "redrawall", NULL }, + { "WORKBENCH.UPDATEALL", FALSE, "updateall", NULL }, + { "WORKBENCH.LASTMESSAGE", FALSE, "lastmsg", NULL }, + { "WORKBENCH.ABOUT", FALSE, "about", NULL }, + { "WORKBENCH.QUIT", FALSE, "quit", NULL }, + + { "WINDOW.NEWDRAWER", TRUE, "makedir", NULL }, + { "WINDOW.OPENPARENT", TRUE, NULL, MenuOpenParentWindow }, + { "WINDOW.CLOSE", TRUE, NULL, MenuCloseScalosWindow }, + { "WINDOW.UPDATE", TRUE, NULL, MenuUpdateScalosWindow }, + { "WINDOW.SELECTCONTENTS", TRUE, "selectall", NULL }, + { "WINDOW.CLEARSELECTION", TRUE, NULL, MenuUnselectAll }, + { "WINDOW.CLEANUPBY.COLUMN", TRUE, "cleanup", NULL }, + { "WINDOW.CLEANUPBY.NAME", TRUE, "cleanupbyname", NULL }, + { "WINDOW.CLEANUPBY.DATE", TRUE, "cleanupbydate", NULL }, + { "WINDOW.CLEANUPBY.SIZE", TRUE, "cleanupbysize", NULL }, + { "WINDOW.CLEANUPBY.TYPE", TRUE, "cleanupbytype", NULL }, + { "WINDOW.RESIZETOFIT", TRUE, "sizetofit", NULL }, + { "WINDOW.SNAPSHOT.WINDOW", TRUE, "snapshotwindow", NULL }, + { "WINDOW.SNAPSHOT.ALL", TRUE, "snapshotall", NULL }, + { "WINDOW.SHOW.ONLYICONS", TRUE, "showonlyicons", NULL }, + { "WINDOW.SHOW.ALLFILES", TRUE, NULL, MenuShowAllFiles }, + { "WINDOW.VIEWBY.ICON", TRUE, NULL, MenuSetViewModeByIcon }, + { "WINDOW.VIEWBY.NAME", TRUE, NULL, MenuSetViewModeByName }, + { "WINDOW.VIEWBY.DATE", TRUE, NULL, MenuSetViewModeByDate }, + { "WINDOW.VIEWBY.SIZE", TRUE, NULL, MenuSetViewModeBySize }, + { "WINDOW.VIEWBY.TYPE", TRUE, NULL, MenuSetViewModeByType }, + { "WINDOW.FIND", TRUE, NULL, NULL }, /* !!! */ + + { "ICONS.OPEN", TRUE, "open", NULL }, + { "ICONS.COPY", TRUE, "clone", NULL }, + { "ICONS.RENAME", TRUE, "rename", NULL }, + { "ICONS.INFORMATION", TRUE, "iconinfo", NULL }, + { "ICONS.SNAPSHOT", TRUE, "snapshot", NULL }, + { "ICONS.UNSNAPSHOT", TRUE, "unsnapshot", NULL }, + { "ICONS.LEAVEOUT", TRUE, "leaveout", NULL }, + { "ICONS.PUTAWAY", TRUE, "putaway", NULL }, + { "ICONS.DELETE", TRUE, "reset", NULL }, + { "ICONS.FORMATDISK", TRUE, "formatdisk", NULL }, + { "ICONS.EMPTYTRASH", TRUE, "emptytrashcan", NULL }, + + { "TOOLS.RESETWB", FALSE, NULL, NULL }, /* !!! */ + + { "DEBUG.SAD", FALSE, NULL, NULL }, /* !!! */ + { "DEBUG.FLUSHLIBS", FALSE, NULL, NULL }, /* !!! */ + + { NULL, FALSE, NULL, NULL } + }; + +LONG Cmd_Menu(APTR UserData, struct RexxMsg *Message, STRPTR *Args) +{ + enum { ARG_WINDOW, ARG_INVOKE, ARG_NAME, ARG_TITLE, + ARG_SHORTCUT, ARG_ADD, ARG_REMOVE, ARG_CMD }; + LONG Result = RETURN_OK; + char *ResultString = NULL; + struct ScaWindowStruct *swi; + + d1(kprintf(__FUNC__ "/%ld: Window=<%s>\n", __LINE__, Args[ARG_WINDOW] ? Args[ARG_WINDOW] : (STRPTR) "");) + + if (Args[ARG_WINDOW]) + swi = FindWindowByName(Args[ARG_WINDOW]); + else + swi = FindWindowByName("active"); + + if (Args[ARG_ADD]) + { + d1(kprintf(__FUNC__ "/%ld: ADD\n", __LINE__);) + + if (NULL == Args[ARG_NAME]) + return ERROR_REQUIRED_ARG_MISSING; + if (NULL == Args[ARG_TITLE]) + return ERROR_REQUIRED_ARG_MISSING; + if (NULL == Args[ARG_CMD]) + return ERROR_REQUIRED_ARG_MISSING; + + Result = AddMenuItem(Args[ARG_NAME], Args[ARG_TITLE], Args[ARG_CMD], Args[ARG_SHORTCUT]); + } + else if (Args[ARG_REMOVE]) + { + d1(kprintf(__FUNC__ "/%ld: REMOVE\n", __LINE__);) + + if (NULL == Args[ARG_NAME]) + return ERROR_REQUIRED_ARG_MISSING; + + Result = RemoveMenuItem(Args[ARG_NAME]); + } + else // Args[ARG_INVOKE] is optional + { + const struct InvokeMenu *menu = WBMenus; + BOOL Found = FALSE; + + d1(kprintf(__FUNC__ "/%ld: INVOKE <%s>\n", __LINE__, Args[ARG_INVOKE]);) + + while (menu->ivm_WBmenuName && !Found && RETURN_OK == Result) + { + if (0 == Stricmp((STRPTR) menu->ivm_WBmenuName, Args[ARG_INVOKE])) + { + if (!menu->ivm_WindowRequired && (NULL == swi)) + swi = FindWindowByName("root"); + + if (NULL == swi) + return(ERROR_OBJECT_NOT_FOUND); + + if (menu->ivm_ScalosMenuName) + { + DoMethod(swi->ws_WindowTask->mt_MainObject, + SCCM_IconWin_MenuCommand, menu->ivm_ScalosMenuName, + NULL, 0); + } + else if (menu->ivm_MenuFunc) + { + Result = (*menu->ivm_MenuFunc)(swi); + } + Found = TRUE; + } + menu++; + } + if (!Found) + Result = ERROR_OBJECT_NOT_FOUND; + } + + d(kprintf(__FUNC__ "/%ld: Result=%ld\n", __LINE__, Result);) + + if (RETURN_OK == Result) + ReturnRexxMsg(Message, ResultString); + + return Result; +} + + +#if 0 +------------------------------------------------------------------------------ +MOVEWINDOW command + +Purpose: + +This command will attempt to change the position of a window. + +Format: + +MOVEWINDOW [WINDOW] [[LEFTEDGE] ] [[TOPEDGE] ] + +Template: + +MOVEWINDOW WINDOW,LEFTEDGE/N,TOPEDGE/N + +Parameters: + +WINDOW + +Either ROOT to move the Workbench root window (where volume icons and +AppIcons live), ACTIVE to move the currently active Workbench window or the +fully qualified name of a drawer window to change. Note that the drawer +window must already be open. + +If no WINDOW parameter is specified, this command will try to operate on the +currently active Workbench window. + +LEFTEDGE + +New left edge window position. + +TOPEDGE + +New top edge window position. + +Errors: + +10 - If the named window cannot be moved; this can also happen if you +specified ACTIVE as the window name and none of the Workbench windows is +currently active. The error code will be placed in the WORKBENCH.LASTERROR +variable. + +Result: + +- + +Notes: + +If you choose to have a window changed that is neither the root nor the +active window you must make sure that the window name is given as a fully +qualified path name. For example Work: is a fully qualified name, and so is +SYS:Utilities. Devs/Printers would not be a fully qualified name. A fully +qualified name always contains the name of an assignment, a volume or a +device. + +Example: + +/* Move the root window to position 10,30. */ +ADDRESS workbench + +MOVEWINDOW root LEFTEDGE 10 TOPEDGE 30 + +/* Move the currently active window. */ +MOVEWINDOW active 20 40 + + +------------------------------------------------------------------------------ +#endif +LONG Cmd_MoveWindow(APTR UserData, struct RexxMsg *Message, STRPTR *Args) +{ + enum { ARG_WINDOW, ARG_LEFTEDGE, ARG_TOPEDGE }; + LONG Result = RETURN_OK; + char *ResultString = NULL; + struct ScaWindowStruct *swi; + WORD Left, Top; + + d(kprintf(__FUNC__ "/%ld: Window=<%s>\n", __LINE__, Args[ARG_WINDOW] ? Args[ARG_WINDOW] : (STRPTR) "");) + + if (Args[ARG_WINDOW]) + swi = FindWindowByName(Args[ARG_WINDOW]); + else + swi = FindWindowByName("active"); + + if (NULL == swi) + return(ERROR_OBJECT_NOT_FOUND); + + if (Args[ARG_LEFTEDGE]) + Left = *((LONG *) Args[ARG_LEFTEDGE]); + else + Left = swi->ws_Window->LeftEdge; + if (Args[ARG_TOPEDGE]) + Top = *((LONG *) Args[ARG_TOPEDGE]); + else + Top = swi->ws_Window->TopEdge; + + ChangeWindowBox(swi->ws_Window, Left, Top, swi->ws_Window->Width, swi->ws_Window->Height); + + DoMethod(swi->ws_WindowTask->mt_MainObject, + SCCM_IconWin_SetVirtSize, SETVIRTF_AdjustRightSlider | SETVIRTF_AdjustBottomSlider); + + d(kprintf(__FUNC__ "/%ld: Result=%ld\n", __LINE__, Result);) + + if (RETURN_OK == Result) + ReturnRexxMsg(Message, ResultString); + + return Result; +} + + +#if 0 +------------------------------------------------------------------------------ +NEWDRAWER command + +Purpose: + +This command is for creating new drawers. + +Format: + +NEWDRAWER [NAME] + +Template: + +NEWDRAWER NAME/A + +Parameters: + +NAME + +Name of the drawer to be created. + +Errors: + +10 - If the named drawer could not be created. + +Result: + +- + +Notes: + +The drawer name given must be an absolute path, such as in RAM:Empty. A +relative path, such as /fred/barney will not work. + +Example : + +/* Create a drawer by the name of Empty in the RAM disk. */ +ADDRESS workbench + +NEWDRAWER ,RAM:Empty` + + +------------------------------------------------------------------------------ +#endif +LONG Cmd_NewDrawer(APTR UserData, struct RexxMsg *Message, STRPTR *Args) +{ + enum { ARG_NAME }; + LONG Result; + char *ResultString = NULL; + + d(kprintf(__FUNC__ "/%ld: Name=<%s>\n", __LINE__, Args[ARG_NAME]);) + + Result = MenuNewDrawer(Args[ARG_NAME]); + + d(kprintf(__FUNC__ "/%ld: Result=%ld\n", __LINE__, Result);) + + if (RETURN_OK == Result) + ReturnRexxMsg(Message, ResultString); + + return Result; +} + + +#if 0 +------------------------------------------------------------------------------ +RENAME command + +Purpose: + +This command is for renaming files, drawers and volumes. + +Format: + +RENAME [OLDNAME] [NEWNAME] + +Template: + +RENAME OLDNAME/A,NEWNAME/A + +Parameters: + +OLDNAME + +Name of the file/drawer/volume to be renamed. This must be an absolute path, +such as in RAM:Empty. A relative path, such as /fred/barney, will not work. + +NEWNAME + +The new name to assign to the file/drawer/volume. This must not be an +absolute or relative path. For example, wilma is valid new name, /wilma or +wilma: would be invalid names. + +Errors: + +10 - If the object cannot be renamed. + +Result: + +- + +Notes: + +The RENAME command does not work like for example the AmigaDOS Rename +command. For example, RENAME ,ram:empty` ,newname` will rename the file +,RAM:empty` to ,RAM:newname`. + +Example: + +/* Rename a drawer by the name of Old in the RAM disk to New. */ +ADDRESS workbench + +RENAME ,RAM:Old` ,New` + + +------------------------------------------------------------------------------ +#endif +LONG Cmd_Rename(APTR UserData, struct RexxMsg *Message, STRPTR *Args) +{ + enum { ARG_OLDNAME, ARG_NEWNAME }; + LONG Result = RETURN_OK; + char *ResultString = NULL; + + d(kprintf(__FUNC__ "/%ld: Old=<%s> New=<%s>\n", __LINE__, Args[ARG_OLDNAME], Args[ARG_NEWNAME]);) + + // rename object "xyzzy" + if (Rename(Args[ARG_OLDNAME], Args[ARG_NEWNAME])) + { + char oldNameIcon[256], newNameIcon[256]; + + stccpy(oldNameIcon, Args[ARG_OLDNAME], sizeof(oldNameIcon)-6); + strcat(oldNameIcon, ".info"); + + stccpy(newNameIcon, Args[ARG_NEWNAME], sizeof(newNameIcon)-6); + strcat(newNameIcon, ".info"); + + // Rename icon "xyzzy.info" + if (!Rename(oldNameIcon, newNameIcon)) + Result = IoErr(); + } + else + Result = IoErr(); + + d(kprintf(__FUNC__ "/%ld: Result=%ld\n", __LINE__, Result);) + + if (RETURN_OK == Result) + ReturnRexxMsg(Message, ResultString); + + return Result; +} + + +#if 0 +------------------------------------------------------------------------------ +RX command + +Purpose: + +This command is for executing ARexx scripts and commands. + +Format: + +RX [CONSOLE] [ASYNC] [CMD] + +Template: + +RX CONSOLE/S,ASYNC/S,CMD/A/F + +Parameters: + +CONSOLE + +This switch indicates that a console (for default I/O) is needed. + +ASYNC + +This switch indicates that the command should be run asynchronously, i.e. the +RX command will return as soon as ARexx has been instructed to run the +command you specified. Otherwise, the RX command will wait for the specified +ARexx command to complete execution. + +COMMAND + +This is the name of the ARexx program to execute. + +Errors: + +10 - If the given ARexx program could not be executed. + +Result: + +- + +Example: + +/* Execute an ARexx program by the name of ,test.wb`; * its output should be +sent to a console window. */ +ADDRESS workbench + +RX CONSOLE CMD ,test.wb` + + +------------------------------------------------------------------------------ +#endif +LONG Cmd_Rx(APTR UserData,struct RexxMsg *Message,STRPTR *Args) +{ + enum { ARG_CONSOLE,ARG_ASYNC,ARG_COMMAND }; + + struct LocalData *LocalData; + struct ChildMessage *ChildMessage; + BPTR Stream; + struct Process *Child; + struct FileHandle *Handle; + LONG Error; + + Printf("RX"); + + if(Args[ARG_CONSOLE] != NULL) + Printf(" CONSOLE"); + + if(Args[ARG_ASYNC] != NULL) + Printf(" ASYNC"); + + if(Args[ARG_COMMAND] != NULL) + Printf(" COMMAND=\"%s\"", (ULONG) Args[ARG_COMMAND]); + + Printf("\n"); + + /* If no command was invoked, return without + * doing any real work. + */ + + if(Args[ARG_COMMAND] == NULL) + { + ReturnRexxMsg(Message,0); + return(0); + } + + /* Should we open a console output window? */ + + if(Args[ARG_CONSOLE]) + { + LocalData = (struct LocalData *)UserData; + + /* Create the process startup message. */ + + ChildMessage = CreateChildMessage(LocalData->GlobalPort,Args[ARG_COMMAND],Message); + + if(ChildMessage != NULL) + { + /* Fill in the name of the Rexx host. */ + + ChildMessage->PortName = LocalData->PortName; + + /* If the command should execute synchronously, + * store the RexxMsg pointer in the startup + * message. The background process will then + * return the message after executing the + * command. + */ + + if(Args[ARG_ASYNC] == NULL) + ChildMessage->RexxMsg = Message; + + /* Open the output console; you may want to substitute + * the title "Host" in your own programs. + */ + + if(Stream = Open("CON:0/25/640/150/Host/AUTO/WAIT",MODE_NEWFILE)) + { + /* Turn the BPTR to the file handle into a + * pointer to the file handle. + */ + STATIC_PATCHFUNC(RxEntry); + Handle = (struct FileHandle *)BADDR(Stream); + + /* Create the background process. */ + + Child = CreateNewProcTags( + NP_Input, Stream, + NP_CloseInput, FALSE, + NP_Output, NULL, + NP_ConsoleTask, (ULONG) Handle->fh_Type, + NP_WindowPtr, -1, + NP_Entry, (ULONG) PATCH_NEWFUNC(RxEntry), + TAG_DONE); + + if(Child != NULL) + { + /* Send the startup message. */ + + PutMsg(&Child->pr_MsgPort, (struct Message *) ChildMessage); + + /* Increment the number of outstanding + * startup messages. + */ + + LocalData->Usage++; + + /* If the command was to be executed + * asynchronously, return the message + * now so the calling program can + * continue running while the process + * is dealing with the command. + */ + + if(Args[ARG_ASYNC] != NULL) + ReturnRexxMsg(Message,0); + + return(0); + } + else + Error = IoErr(); + + Close(Stream); + } + else + Error = IoErr(); + + DeleteChildMessage(ChildMessage); + } + else + Error = IoErr(); + } + else + { + /* If the command should execute asynchronously, + * reply the RexxMsg now. + */ + + if(Args[ARG_ASYNC] != NULL) + ReturnRexxMsg(Message,0); + + /* Execute the command. */ + + Error = DoRexxCommand(Args[ARG_COMMAND]); + + /* If the RexxMsg was already replied, + * return now. + */ + + if(Args[ARG_ASYNC] != NULL) + return(0); + + /* If no error occured, return the RexxMsg. */ + + if(Error == 0) + { + ReturnRexxMsg(Message,0); + return(0); + } + } + + return(Error); +} + + +#if 0 +------------------------------------------------------------------------------ +SIZEWINDOW command + +Purpose: + +This command will attempt to change the size of a window. + +Format: + +SIZEWINDOW [WINDOW] [[WIDTH] ] +[[HEIGHT] ] + +Template: + +SIZEWINDOW WINDOW,WIDTH/N,HEIGHT/N + +Parameters: + +WINDOW + +Either ROOT to resize the Workbench root window (where volume icons and +AppIcons live), ACTIVE to resize the currently active Workbench window or +the fully qualified name of a drawer window to change. Note that the drawer +window must already be open. + +If no WINDOW parameter is specified, this command will try to operate on the +currently active Workbench window. + +WIDTH + +New window width. + +HEIGHT + +New window height. + +Errors: + +10 - If the named window cannot be resized; this can also happen if you +specified ACTIVE as the window name and none of the Workbench windows is +currently active. The error code will be placed in the WORKBENCH.LASTERROR +variable. + +Result: + +- + +Notes: + +If you choose to have a window resized that is neither the root nor the +active window you must make sure that the window name is given as a fully +qualified path name. For example Work: is a fully qualified name, and so is +SYS:Utilities. Devs/Printers would not be a fully qualified name. A fully +qualified name always contains the name of an assignment, a volume or a +device. + +Example: + +/* Change the root window size to 200100 pixels. */ +ADDRESS workbench + +SIZEWINDOW root 30 WIDTH 200 HEIGHT 100 + +/* Resize the currently active window. */ +SIZEWINDOW active 200 100 + + +------------------------------------------------------------------------------ +#endif +LONG Cmd_SizeWindow(APTR UserData, struct RexxMsg *Message, STRPTR *Args) +{ + enum { ARG_WINDOW, ARG_WIDTH, ARG_HEIGHT }; + LONG Result = RETURN_OK; + char *ResultString = NULL; + struct ScaWindowStruct *swi; + WORD Width, Height; + + d(kprintf(__FUNC__ "/%ld: Window=<%s>\n", __LINE__, Args[ARG_WINDOW] ? Args[ARG_WINDOW] : (STRPTR) "");) + + if (Args[ARG_WINDOW]) + swi = FindWindowByName(Args[ARG_WINDOW]); + else + swi = FindWindowByName("active"); + + if (NULL == swi) + return(ERROR_OBJECT_NOT_FOUND); + + if (Args[ARG_WIDTH]) + Width = *((LONG *) Args[ARG_WIDTH]); + else + Width = swi->ws_Window->Width; + if (Args[ARG_HEIGHT]) + Height = *((LONG *) Args[ARG_HEIGHT]); + else + Height = swi->ws_Window->Height; + + ChangeWindowBox(swi->ws_Window, swi->ws_Window->LeftEdge, swi->ws_Window->TopEdge, Width,Height); + + DoMethod(swi->ws_WindowTask->mt_MainObject, + SCCM_IconWin_SetVirtSize, SETVIRTF_AdjustRightSlider | SETVIRTF_AdjustBottomSlider); + + d(kprintf(__FUNC__ "/%ld: Result=%ld\n", __LINE__, Result);) + + if (RETURN_OK == Result) + ReturnRexxMsg(Message, ResultString); + + return Result; +} + + +#if 0 +------------------------------------------------------------------------------ +UNLOCKGUI command + +Purpose: + +This command will allow access to all Workbench drawer windows locked with +the LOCKGUI command. + +Format: + +UNLOCKGUI + +Template: + +UNLOCKGUI + +Parameters: + +- + +Errors: + +- + +Result: + +- + +Notes: + +It takes as many UNLOCKGUI commands as there were LOCKGUI commands to make +the Workbench drawer windows usable again. In other words, the LOCKGUI +command nests. + +Example: + +/* Reallow access to all Workbench drawer windows. */ +ADDRESS workbench + +UNLOCKGUI + + +------------------------------------------------------------------------------ +#endif +LONG Cmd_UnlockGUI(APTR UserData, struct RexxMsg *Message, STRPTR *Args) +{ + LONG Result = RETURN_OK; + char *ResultString = NULL; + + /* !!! */ + + d(kprintf(__FUNC__ "/%ld: Result=%ld\n", __LINE__, Result);) + + if (RETURN_OK == Result) + ReturnRexxMsg(Message, ResultString); + + return Result; +} + + +#if 0 +------------------------------------------------------------------------------ +VIEW command + +Purpose: + +This command will change the position of the viewable display area of a +window. + +Format: + +VIEW [WINDOW] [PAGE|PIXEL] [UP|DOWN|LEFT|RIGHT] + +Template: + +VIEW WINDOW,PAGE/S,PIXEL/S,UP/S,DOWN/S,LEFT/S,RIGHT/S + +Parameters: + +WINDOW + +Either ROOT to change the Workbench root window view (where volume icons and +AppIcons live), ACTIVE to change the currently active Workbench window view +or the fully qualified name of a drawer window to change. Note that the +drawer window must already be open. + +If no WINDOW parameter is specified, this command will try to operate on the +currently active Workbench window. + +UP + +Move the view up by about 1/8 of the window height. If PAGE is specified, +moves the view up by a whole page. If PIXEL is specified, moves the view up +by a single pixel. + +DOWN + +Move the view down by about 1/8 of the window height. If PAGE is specified, +moves the view down by a whole page. If PIXEL is specified, moves the view +down by a single pixel. + +LEFT + +Move the view left by about 1/8 of the window height. If PAGE is specified, +moves the view left by a whole page. If PIXEL is specified, moves the view +left by a single pixel. + +RIGHT + +Move the view right by about 1/8 of the window height. If PAGE is specified, +moves the view right by a whole page. If PIXEL is specified, moves the view +right by a single pixel. + +Errors: + +10 - If the named window view cannot be changed; this can also happen if you +specified ACTIVE as the window name and none of the Workbench windows is +currently active. The error code will be placed in the WORKBENCH.LASTERROR +variable. + +Result: + +- + +Notes: + +If you choose to have a window view changed that is neither the root nor the +active window you must make sure that the window name is given as a fully +qualified path name. For example Work: is a fully qualified name, and so is +SYS:Utilities. Devs/Printers would not be a fully qualified name. A fully +qualified name always contains the name of an assignment, a volume or a +device. + +To find out about a window`s current view position, use the GETATTR command +and query the window`s WINDOW.VIEW.LEFT and WINDOW.VIEW.TOP attributes. + +Example: + +/* Change the root window view; move it up by a whole page. */ +ADDRESS workbench + +VIEW root PAGE UP + +------------------------------------------------------------------------------ +#endif +LONG Cmd_View(APTR UserData, struct RexxMsg *Message, STRPTR *Args) +{ + enum { ARG_WINDOW, ARG_PAGE, ARG_PIXEL, + ARG_UP, ARG_DOWN, ARG_LEFT, ARG_RIGHT }; + LONG Result = RETURN_OK; + char *ResultString = NULL; + struct ScaWindowStruct *swi; + WORD Width, Height; + LONG DeltaX, DeltaY; + LONG deltaX = 0, deltaY = 0; + + d(kprintf(__FUNC__ "/%ld: Window=<%s>\n", __LINE__, Args[ARG_WINDOW] ? Args[ARG_WINDOW] : (STRPTR) "");) + + if (Args[ARG_WINDOW]) + swi = FindWindowByName(Args[ARG_WINDOW]); + else + swi = FindWindowByName("active"); + + if (NULL == swi) + return(ERROR_OBJECT_NOT_FOUND); + + Width = swi->ws_Window->Width - swi->ws_Window->BorderLeft - swi->ws_Window->BorderRight; + Height = swi->ws_Window->Height - swi->ws_Window->BorderTop - swi->ws_Window->BorderBottom; + + if (Args[ARG_PAGE]) + { + DeltaX = Width; + DeltaY = Height; + } + else if (Args[ARG_PIXEL]) + { + DeltaX = DeltaY = 1; + } + else + { + DeltaX = Width / 8; + DeltaY = Height / 8; + } + + if (Args[ARG_LEFT]) + { + deltaX = -DeltaX; + } + else if (Args[ARG_RIGHT]) + { + deltaX = DeltaX; + } + + if (Args[ARG_UP]) + { + deltaY = DeltaY; + } + else if (Args[ARG_DOWN]) + { + deltaY = -DeltaY; + } + + if (deltaX != 0 || deltaY != 0) + { + DoMethod(swi->ws_WindowTask->mt_MainObject, + SCCM_IconWin_DeltaMove, deltaX, deltaY); + + DoMethod(swi->ws_WindowTask->mt_MainObject, + SCCM_IconWin_SetVirtSize, SETVIRTF_AdjustRightSlider | SETVIRTF_AdjustBottomSlider); + } + + d(kprintf(__FUNC__ "/%ld: Result=%ld\n", __LINE__, Result);) + + if (RETURN_OK == Result) + ReturnRexxMsg(Message, ResultString); + + return Result; +} + + +#if 0 +------------------------------------------------------------------------------ +WINDOW command + +Purpose: + +This command will change, open, close or snapshot windows. + +Format: + +WINDOW [WINDOWS] .. [OPEN|CLOSE] [SNAPSHOT] +[ACTIVATE] [MIN|MAX] [FRONT|BACK] [CYCLE PREVIOUS|NEXT] + +Template: + +WINDOW WINDOWS/M/A,OPEN/S,CLOSE/S,SNAPSHOT/S,ACTIVATE/S,MIN/S,MAX/S, +FRONT/S,BACK/S,CYCLE/K + +Parameters: + +WINDOWS + +Names of the windows to operate on. This can be ROOT to for the Workbench +root window (where volume icons and AppIcons live), ACTIVE for the currently +active Workbench window or the fully qualified name of a drawer window. + +OPEN + +Attempt to open the specified windows. + +CLOSE + +Close the specified windows. Note that if a window is closed no further +operations (such as SNAPSHOT, ACTIVATE, etc.) can be performed on it. + +SNAPSHOT + +Snapshot the sizes and positions of the specified windows. + +ACTIVATE + +Activate the specified windows. With multiple windows to activate, only one +window will wind up as the active one. Commonly, this will be the last window +in the list. + +MIN + +Resize the windows to their minimum dimensions. + +MAX + +Resize the windows to their maximum dimensions. + +FRONT + +Move the windows into the foreground. + +BACK + +Move the windows into the background. + +CYCLE + +This command operates on the currently active drawer window. You can specify +either PREVIOUS, to activate the previous drawer window in the list, or +NEXT, to activate the next following drawer window in the list. + +Errors: + +10 - If the named windows cannot be opened or operated on; this can also +happen if you specified ACTIVE as a window name and none of the Workbench +windows is currently active. The error code will be placed in the +WORKBENCH.LASTERROR variable. + +Result: + +- + +Notes: + +If you choose to have a window operated on that is neither the root nor the +active window you must make sure that the window name is given as a fully +qualified path name. For example Work: is a fully qualified name, and so is +SYS:Utilities. Devs/Printers would not be a fully qualified name. A fully +qualified name always contains the name of an assignment, a volume or a +device. + +Example: + +/* Open the Work: drawer. */ +ADDRESS workbench + +WINDOW ,Work:` OPEN + +/* Activate the root window. */ +WINDOW root ACTIVATE + + +------------------------------------------------------------------------------ +#endif +LONG Cmd_Window(APTR UserData, struct RexxMsg *Message, STRPTR *Args) +{ + enum { ARG_WINDOWS, ARG_OPEN, ARG_CLOSE, ARG_SNAPSHOT, ARG_ACTIVATE, + ARG_MIN, ARG_MAX, ARG_FRONT, ARG_BACK, ARG_CYCLE }; + LONG Result = RETURN_OK; + char *ResultString = NULL; + struct ScaWindowStruct *swi; + STRPTR *NamesPtr = (STRPTR *) Args[ARG_WINDOWS]; + + d(kprintf(__FUNC__ "/%ld: \n", __LINE__);) + + while (*NamesPtr && RETURN_OK == Result) + { + d(kprintf(__FUNC__ "/%ld: Window=<%s>\n", __LINE__, *NamesPtr);) + + swi = FindWindowByName(*NamesPtr); + + d(kprintf(__FUNC__ "/%ld: swi=%08lx\n", __LINE__, swi);) + + if (Args[ARG_OPEN]) + { + d(kprintf(__FUNC__ "/%ld: OPEN\n", __LINE__);) + + WaitOpen(SCA_OpenDrawerByName(*NamesPtr, NULL)); + } + if (Args[ARG_CLOSE]) + { + d(kprintf(__FUNC__ "/%ld: CLOSE\n", __LINE__);) + + if (NULL == swi) + return ERROR_OBJECT_NOT_FOUND; + + SCA_LockWindowList(SCA_LockWindowList_Shared); + + // CloseScalosWindow() expects windowlist to be locked + CloseScalosWindow(swi); + swi = NULL; + } + if (Args[ARG_SNAPSHOT]) + { + d(kprintf(__FUNC__ "/%ld: SNAPSHOT\n", __LINE__);) + + if (NULL == swi) + return ERROR_OBJECT_NOT_FOUND; + + DoMethod(swi->ws_WindowTask->mt_MainObject, + SCCM_IconWin_MenuCommand, "snapshotwindow", + NULL, 0); + } + if (Args[ARG_ACTIVATE]) + { + d(kprintf(__FUNC__ "/%ld: ACTIVATE\n", __LINE__);) + + if (NULL == swi) + return ERROR_OBJECT_NOT_FOUND; + + ActivateWindow(swi->ws_Window); + } + if (Args[ARG_MIN]) + { + d(kprintf(__FUNC__ "/%ld: MIN\n", __LINE__);) + + if (NULL == swi) + return ERROR_OBJECT_NOT_FOUND; + + ChangeWindowBox(swi->ws_Window, + swi->ws_Window->LeftEdge, swi->ws_Window->TopEdge, + swi->ws_Window->MinWidth, swi->ws_Window->MinHeight); + } + if (Args[ARG_MAX]) + { + d(kprintf(__FUNC__ "/%ld: MAX\n", __LINE__);) + + if (NULL == swi) + return ERROR_OBJECT_NOT_FOUND; + + ChangeWindowBox(swi->ws_Window, + swi->ws_Window->LeftEdge, swi->ws_Window->TopEdge, + swi->ws_Window->MaxWidth, swi->ws_Window->MaxHeight); + } + if (Args[ARG_FRONT]) + { + d(kprintf(__FUNC__ "/%ld: FRONT\n", __LINE__);) + + if (NULL == swi) + return ERROR_OBJECT_NOT_FOUND; + + WindowToFront(swi->ws_Window); + } + if (Args[ARG_BACK]) + { + d(kprintf(__FUNC__ "/%ld: BACK\n", __LINE__);) + + if (NULL == swi) + return ERROR_OBJECT_NOT_FOUND; + + WindowToBack(swi->ws_Window); + } + if (Args[ARG_CYCLE]) + { + d(kprintf(__FUNC__ "/%ld: CYCLE\n", __LINE__);) + + if (NULL == swi) + return ERROR_OBJECT_NOT_FOUND; + + if (0 == Stricmp(Args[ARG_CYCLE], "PREVIOUS")) + { + d(kprintf(__FUNC__ "/%ld: CYCLE PREVIOUS\n", __LINE__);) + + swi = GetPrevWindow(swi); + if (swi) + ActivateWindow(swi->ws_Window); + else + Result = ERROR_OBJECT_NOT_FOUND; + } + else if (0 == Stricmp(Args[ARG_CYCLE], "NEXT")) + { + d(kprintf(__FUNC__ "/%ld: CYCLE NEXT\n", __LINE__);) + + swi = GetNextWindow(swi); + if (swi) + ActivateWindow(swi->ws_Window); + else + Result = ERROR_OBJECT_NOT_FOUND; + } + } + + NamesPtr++; + } + + d(kprintf(__FUNC__ "/%ld: Result=%ld\n", __LINE__, Result);) + + if (RETURN_OK == Result) + ReturnRexxMsg(Message, ResultString); + + return Result; +} + + +#if 0 +------------------------------------------------------------------------------ +WINDOWTOBACK command + +Purpose: + +This command will push a window into the background. + +Format: + +WINDOWTOBACK [WINDOW] + +Template: + +WINDOWTOBACK WINDOW + +Parameters: + +WINDOW + +ROOT to push the the Workbench root window (where volume icons and AppIcons +live) into to the background, ACTIVE to push the currently active Workbench +window into the background or the fully qualified name of a drawer window. +Note that the drawer window must already be open. + +If no WINDOW parameter is specified, this command will try to operate on the +currently active Workbench window. + +Errors: + +10 - If the named window cannot be found. The error code will be placed in +the WORKBENCH.LASTERROR variable. + +Result: + +- + +Notes: + +If you choose to have a window pushed into the background that is not the +root window or the currently active window you must make sure that the window +name is given as a fully qualified path name. For example Work: is a fully +qualified name, and so is SYS:Utilities. Devs/Printers would not be a fully +qualified name. A fully qualified name always contains the name of an +assignment, a volume or a device. + +Example: + +/* Push the root window into the background. */ +ADDRESS workbench + +WINDOWTOBACK root + + +------------------------------------------------------------------------------ +#endif +LONG Cmd_WindowToBack(APTR UserData, struct RexxMsg *Message, STRPTR *Args) +{ + enum { ARG_WINDOW }; + LONG Result = RETURN_OK; + char *ResultString = NULL; + struct ScaWindowStruct *swi; + + d(kprintf(__FUNC__ "/%ld: Window=<%s>\n", __LINE__, Args[ARG_WINDOW] ? Args[ARG_WINDOW] : (STRPTR) "");) + + if (Args[ARG_WINDOW]) + swi = FindWindowByName(Args[ARG_WINDOW]); + else + swi = FindWindowByName("active"); + + if (NULL == swi) + return(ERROR_OBJECT_NOT_FOUND); + + WindowToBack(swi->ws_Window); + + d(kprintf(__FUNC__ "/%ld: Result=%ld\n", __LINE__, Result);) + + if (RETURN_OK == Result) + ReturnRexxMsg(Message, ResultString); + + return Result; +} + + +#if 0 +------------------------------------------------------------------------------ +WINDOWTOFRONT command + +Purpose: + +This command will bring a window to the foreground. + +Format: + +WINDOWTOFRONT [WINDOW] + +Template: + +WINDOWTOFRONT WINDOW + +Parameters: + +WINDOW + +ROOT to bring the the Workbench root window (where volume icons and AppIcons +live) to the foreground, ACTIVE to bring the currently active Workbench +window to the foreground or the fully qualified name of a drawer window. Note +that the drawer window must already be open. + +If no WINDOW parameter is specified, this command will try to operate on the +currently active Workbench window. + +Errors: + +10 - If the named window cannot be found. The error code will be placed in +the WORKBENCH.LASTERROR variable. + +Result: + +- + +Notes: + +If you choose to have a window brought to the foreground that is not the root +window or the currently active window you must make sure that the window name +is given as a fully qualified path name. For example Work: is a fully +qualified name, and so is SYS:Utilities. Devs/Printers would not be a fully +qualified name. A fully qualified name always contains the name of an +assignment, a volume or a device. + +Example: + +/* Bring the root window to the foreground. */ ADDRESS workbench + +WINDOWTOFRONT root + + +------------------------------------------------------------------------------ +#endif +LONG Cmd_WindowToFront(APTR UserData, struct RexxMsg *Message, STRPTR *Args) +{ + enum { ARG_WINDOW }; + LONG Result = RETURN_OK; + char *ResultString = NULL; + struct ScaWindowStruct *swi; + + d(kprintf(__FUNC__ "/%ld: Window=<%s>\n", __LINE__, Args[ARG_WINDOW] ? Args[ARG_WINDOW] : (STRPTR) "");) + + if (Args[ARG_WINDOW]) + swi = FindWindowByName(Args[ARG_WINDOW]); + else + swi = FindWindowByName("active"); + + if (NULL == swi) + return(ERROR_OBJECT_NOT_FOUND); + + WindowToFront(swi->ws_Window); + + d(kprintf(__FUNC__ "/%ld: Result=%ld\n", __LINE__, Result);) + + if (RETURN_OK == Result) + ReturnRexxMsg(Message, ResultString); + + return Result; +} + + +#if 0 +------------------------------------------------------------------------------ +ZOOMWINDOW command + +Purpose: + +This command will change a window to alternate position and dimensions. + +Format: + +ZOOMWINDOW [WINDOW] + +Template: + +ZOOMWINDOW WINDOW + +Parameters: + +WINDOW + +Name of the window to operate on. ROOT will use the Workbench root window +(where volume icons and AppIcons live), ACTIVE will use the currently active +Workbench window. Any other fully qualified path name will use the drawer +window corresponding to the path. If no WINDOW parameter is specified, this +command will try to operate on the currently active Workbench window. + +Errors: + +10 - If the named window cannot be found. The error code will be placed in +the WORKBENCH.LASTERROR variable. + +Result: + +- + +Example: + +/* Change the root window. */ +ADDRESS workbench + +ZOOMWINDOW root + + +------------------------------------------------------------------------------ +#endif +LONG Cmd_ZoomWindow(APTR UserData, struct RexxMsg *Message, STRPTR *Args) +{ + enum { ARG_WINDOW }; + LONG Result = RETURN_OK; + char *ResultString = NULL; + struct ScaWindowStruct *swi; + + d(kprintf(__FUNC__ "/%ld: Window=<%s>\n", __LINE__, Args[ARG_WINDOW] ? Args[ARG_WINDOW] : (STRPTR) "");) + + if (Args[ARG_WINDOW]) + swi = FindWindowByName(Args[ARG_WINDOW]); + else + swi = FindWindowByName("active"); + + if (NULL == swi) + return(ERROR_OBJECT_NOT_FOUND); + + if (swi->ws_Window->Flags & WFLG_HASZOOM) + { + if (!(swi->ws_Window->Flags & WFLG_ZOOMED)) + ZipWindow(swi->ws_Window); + } + + d(kprintf(__FUNC__ "/%ld: Result=%ld\n", __LINE__, Result);) + + if (RETURN_OK == Result) + ReturnRexxMsg(Message, ResultString); + + return Result; +} + + +static LONG OpenWBHelpFile(void) +{ + struct Process *WBHelpProc; + STATIC_PATCHFUNC(WBHelpProcess); + + WBHelpProc = CreateNewProcTags(NP_Name, (ULONG) "WB39 WBHelp Handler", + NP_Priority, 0, + NP_Entry, (ULONG) PATCH_NEWFUNC(WBHelpProcess), + NP_StackSize, 16384, + TAG_END); + if (WBHelpProc == NULL) + { + return IoErr(); + } + + return RETURN_OK; +} + + +static SAVEDS(void) WBHelpProcess(void) +{ +// LONG Result; + BPTR lock = 0; + struct Locale *locale; + AMIGAGUIDECONTEXT handle = NULL; + + d1(kprintf("%s/%s/%ld Start WBHelp Process\n", __FILE__, __FUNC__, __LINE__);) + + do { + struct NewAmigaGuide nag; + char LanguageName[40]; + char HelpDir[256]; + CONST_STRPTR HelpFile = "workbench.guide"; + size_t len; + STRPTR context[] = + { + NULL + }; + + memset(&nag, 0, sizeof(nag)); + + locale = OpenLocale(NULL); + if (NULL == locale) + { + //Result = IoErr(); + break; + } + + d1(kprintf( "%s/%s/%ld: loc_LocaleName=<%s> loc_LanguageName=<%s>\n", __FILE__, __FUNC__, __LINE__, locale->loc_LocaleName, locale->loc_LanguageName);) + + // first try to find help file in native language + // use name from locale without the trailing ".language" + len = strlen(locale->loc_LanguageName); + if (len > strlen(".language")) + len -= strlen(".language"); + len++; // include room for trailing "\0" + if (len > sizeof(LanguageName)) + len = sizeof(LanguageName); + stccpy(LanguageName, locale->loc_LanguageName, len); + snprintf(HelpDir, sizeof(HelpDir), "HELP:%s/sys/%s", LanguageName, HelpFile); + + lock = Lock(HelpDir, ACCESS_READ); + d1(kprintf( "%s/%s/%ld: HelpDir=<%s> lock=%08lx\n", __FILE__, __FUNC__, __LINE__, HelpDir, lock);) + + if (lock) + { + snprintf(HelpDir, sizeof(HelpDir), "HELP:%s/sys", locale->loc_LanguageName); + UnLock(lock); + } + else + { + // if native language not found, try "english" + snprintf(HelpDir, sizeof(HelpDir), "HELP:english/sys"); + } + + nag.nag_Name = (STRPTR) HelpFile; + nag.nag_Flags = 0; + nag.nag_Context = context; + nag.nag_HostPort = ""; + nag.nag_ClientPort = "WBHelp"; + nag.nag_Node = "main"; + + nag.nag_Lock = lock = Lock(HelpDir, ACCESS_READ); + + d1(kprintf( "%s/%s/%ld: nag_Lock=%08lx\n", __FILE__, __FUNC__, __LINE__, nag.nag_Lock);) + if (0 == nag.nag_Lock) + { + //Result = IoErr(); + break; + } + + d1(kprintf("%s/%s/%ld: before OpenAmigaGuide\n", __FILE__, __FUNC__, __LINE__);) + + // OpenAmigaGuideA + handle = OpenAmigaGuide(&nag, + TAG_END); + + d1(kprintf("%s/%s/%ld: handle=%08lx\n", __FILE__, __FUNC__, __LINE__, handle);) + if (NULL == handle) + { + //Result = IoErr(); + break; + } + + } while (0); + + if (locale) + CloseLocale(locale); + if (handle) + CloseAmigaGuide(handle); + + if (lock) + UnLock(lock); + + d1(kprintf("%s/%s/%ld END WBHelp Process\n", __FILE__, __FUNC__, __LINE__);) +} + + +#if !defined(__SASC) &&!defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) +// Replacement for SAS/C library functions + +static size_t stccpy(char *dest, const char *src, size_t MaxLen) +{ + size_t Count = 0; + + while (*src && MaxLen > 1) + { + *dest++ = *src++; + MaxLen--; + Count++; + } + *dest = '\0'; + Count++; + + return Count; +} +#endif /* !defined(__SASC) &&!defined(__MORPHOS__) */ diff --git a/scalos/Plugins/OOP/wb39_plugin/wbrexx/RexxGetAttrs.c b/scalos/Plugins/OOP/wb39_plugin/wbrexx/RexxGetAttrs.c new file mode 100644 index 000000000..aa6f31edc --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/wbrexx/RexxGetAttrs.c @@ -0,0 +1,2567 @@ +// RexxGetAttrs.c +// $Date$ +// $Revision$ + + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + + +#include "wbrexx.h" +#include "Scalos_Helper.h" + +#ifdef __amigaos4__ +#define SetRexxVar(msg, var, val, len) SetRexxVarFromMsg((var), (val), (msg)) +#endif + +static ULONG GetWindowCount(void); +static void SetRexxStemVar(struct RexxMsg *Message, const char *Stem, const char *VarName, const char *Value); +static ULONG GetWindowIconCount(struct ScaWindowStruct *swi, enum IconState Mode); +static struct ScaIconNode *GetWindowIconN(struct ScaWindowStruct *swi, enum IconState Mode, ULONG Index); +static struct UData GetAttr_WindowLeft(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_WindowTop(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_WindowWidth(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_WindowHeight(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_WindowMinWidth(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_WindowMinHeight(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_WindowMaxWidth(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_WindowMaxHeight(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_WindowViewLeft(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_WindowViewTop(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_Get_WindowFromName(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_Get_ScreenFromWindow(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_WindowScreenName(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_WindowScreenWidth(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_WindowScreenHeight(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_WindowIconsAllCount(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_Get_AllIconENUM(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_WindowIconsName(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_WindowIconsLeft(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_WindowIconsTop(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_WindowIconsWidth(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_WindowIconsHeight(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_WindowIconsType(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_WindowIconsStatus(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_WindowIconsSelectedCount(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_WindowIconsUnselectedCount(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_Get_SelectedIconENUM(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_Get_UnselectedIconENUM(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_ApplicationVersion(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_ApplicationScreen(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_ApplicationARexx(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_ApplicationLastError(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_ApplicationIconBorder(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_Get_ScreenFont(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_Get_IconFont(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_Get_SystemFont(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_ApplicationFontName(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_ApplicationFontWidth(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_ApplicationFontHeight(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_ApplicationFontSize(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_WindowsCount(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_WindowsEnum(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_WindowsActive(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_KeyCommandsCount(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_MenuCommandsCount(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static ULONG GetCount_KeyCommands(struct UData UserData, struct LeafData *lData); +static ULONG GetCount_MenuCommands(struct UData UserData, struct LeafData *lData); +static struct UData GetAttr_MenuCommandENUM(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_KeyCommandENUM(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_KeyCommandName(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_KeyCommandKey(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_KeyCommandCommand(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_MenuCommandName(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_MenuCommandTitle(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_MenuCommandShortcut(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static struct UData GetAttr_MenuCommandCommand(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index); +static void PutResult(struct LeafData *lData, const char *Value, const char *StemLeaf); +static ULONG GetCount_Windows(struct UData UserData, struct LeafData *lData); +static ULONG GetCount_AllIcon(struct UData UserData, struct LeafData *lData); +static ULONG GetCount_SelectedIcon(struct UData UserData, struct LeafData *lData); +static ULONG GetCount_UnselectedIcon(struct UData UserData, struct LeafData *lData); +static BOOL IsIconNodeOpen(struct ScaIconNode *sIcon); +#if defined(__GNUC__) && !defined(__MORPHOS__) && ! defined(__amigaos4__) && !defined(__AROS__) +static size_t stccpy(char *dest, const char *src, size_t MaxLen); +static char *strupr(char *q); +#endif /* defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) */ + + +// aus wb39.c +extern WORD ScalosPrefs_IconOffsets[4]; +extern struct ScaRootList *rList; + +extern struct ScalosBase *ScalosBase; +extern T_UTILITYBASE UtilityBase; +extern struct DosLibrary *DOSBase; +extern struct IntuitionBase *IntuitionBase; +extern struct GfxBase *GfxBase; + + +// aus WBRExx.c +extern LONG LastError; // will be returned by APPLICATION.LASTERROR +extern struct List MenuItemList; // list of added tool menu items +extern struct List KbdCommandList; // list of keyboard commands + + +static const char *ScreenName = "Workbench"; +static const char *ARexxPortName = "WORKBENCH"; + +enum { ARG_OBJECT, ARG_NAME, ARG_STEM, ARG_VAR }; + + +#define ENUM "" +#define IS_ENUM(str) (0 == strlen(str)) + + +static const struct LeafCmd GAObjects[] = + { +/* 0*/ { "WINDOW", &GAObjects[49], &GAObjects[1], GetAttr_Get_WindowFromName }, +/* 1*/ { "LEFT", &GAObjects[ 2], NULL, GetAttr_WindowLeft }, +/* 2*/ { "TOP", &GAObjects[ 3], NULL, GetAttr_WindowTop }, +/* 3*/ { "WIDTH", &GAObjects[ 4], NULL, GetAttr_WindowWidth }, +/* 4*/ { "HEIGHT", &GAObjects[ 5], NULL, GetAttr_WindowHeight }, +/* 5*/ { "MIN", &GAObjects[ 8], &GAObjects[6], NULL }, +/* 6*/ { "WIDTH", &GAObjects[ 7], NULL, GetAttr_WindowMinWidth }, +/* 7*/ { "HEIGHT", NULL, NULL, GetAttr_WindowMinHeight }, +/* 8*/ { "MAX", &GAObjects[11], &GAObjects[9], NULL }, +/* 9*/ { "WIDTH", &GAObjects[10], NULL, GetAttr_WindowMaxWidth }, +/*10*/ { "HEIGHT", NULL, NULL, GetAttr_WindowMaxHeight }, +/*11*/ { "VIEW", &GAObjects[14], &GAObjects[12], NULL }, +/*12*/ { "LEFT", &GAObjects[13], NULL, GetAttr_WindowViewLeft }, +/*13*/ { "TOP", NULL, NULL, GetAttr_WindowViewTop }, +/*14*/ { "SCREEN", &GAObjects[18], &GAObjects[15], GetAttr_Get_ScreenFromWindow }, +/*15*/ { "NAME", &GAObjects[16], NULL, GetAttr_WindowScreenName }, +/*16*/ { "WIDTH", &GAObjects[17], NULL, GetAttr_WindowScreenWidth }, +/*17*/ { "HEIGHT", NULL, NULL, GetAttr_WindowScreenHeight }, +/*18*/ { "ICONS", NULL, &GAObjects[19], NULL }, +/*19*/ { "ALL", &GAObjects[29], &GAObjects[20], NULL }, +/*20*/ { "COUNT", &GAObjects[21], NULL, GetAttr_WindowIconsAllCount }, +/*21*/ { ENUM, NULL, &GAObjects[22], GetAttr_Get_AllIconENUM, GetCount_AllIcon }, +/*22*/ { "NAME", &GAObjects[23], NULL, GetAttr_WindowIconsName }, +/*23*/ { "LEFT", &GAObjects[24], NULL, GetAttr_WindowIconsLeft }, +/*24*/ { "TOP", &GAObjects[25], NULL, GetAttr_WindowIconsTop }, +/*25*/ { "WIDTH", &GAObjects[26], NULL, GetAttr_WindowIconsWidth }, +/*26*/ { "HEIGHT", &GAObjects[27], NULL, GetAttr_WindowIconsHeight }, +/*27*/ { "TYPE", &GAObjects[28], NULL, GetAttr_WindowIconsType }, +/*28*/ { "STATUS", NULL, NULL, GetAttr_WindowIconsStatus }, +/*29*/ { "SELECTED", &GAObjects[39], &GAObjects[30], NULL }, +/*30*/ { "COUNT", &GAObjects[31], NULL, GetAttr_WindowIconsSelectedCount }, +/*31*/ { ENUM, NULL, &GAObjects[32], GetAttr_Get_SelectedIconENUM, GetCount_SelectedIcon }, +/*32*/ { "NAME", &GAObjects[33], NULL, GetAttr_WindowIconsName }, +/*33*/ { "LEFT", &GAObjects[34], NULL, GetAttr_WindowIconsLeft }, +/*34*/ { "TOP", &GAObjects[35], NULL, GetAttr_WindowIconsTop }, +/*35*/ { "WIDTH", &GAObjects[36], NULL, GetAttr_WindowIconsWidth }, +/*36*/ { "HEIGHT", &GAObjects[37], NULL, GetAttr_WindowIconsHeight }, +/*37*/ { "TYPE", &GAObjects[38], NULL, GetAttr_WindowIconsType }, +/*38*/ { "STATUS", NULL, NULL, GetAttr_WindowIconsStatus }, +/*39*/ { "UNSELECTED", NULL, &GAObjects[40], NULL }, +/*40*/ { "COUNT", &GAObjects[41], NULL, GetAttr_WindowIconsUnselectedCount }, +/*41*/ { ENUM, NULL, &GAObjects[42], GetAttr_Get_UnselectedIconENUM, GetCount_UnselectedIcon }, +/*42*/ { "NAME", &GAObjects[43], NULL, GetAttr_WindowIconsName }, +/*43*/ { "LEFT", &GAObjects[44], NULL, GetAttr_WindowIconsLeft }, +/*44*/ { "TOP", &GAObjects[45], NULL, GetAttr_WindowIconsTop }, +/*45*/ { "WIDTH", &GAObjects[46], NULL, GetAttr_WindowIconsWidth }, +/*46*/ { "HEIGHT", &GAObjects[47], NULL, GetAttr_WindowIconsHeight }, +/*47*/ { "TYPE", &GAObjects[48], NULL, GetAttr_WindowIconsType }, +/*48*/ { "STATUS", NULL, NULL, GetAttr_WindowIconsStatus }, +/*49*/ { "APPLICATION", &GAObjects[71], &GAObjects[50], NULL }, +/*50*/ { "VERSION", &GAObjects[51], NULL, GetAttr_ApplicationVersion }, +/*51*/ { "SCREEN", &GAObjects[52], NULL, GetAttr_ApplicationScreen }, +/*52*/ { "AREXX", &GAObjects[53], NULL, GetAttr_ApplicationARexx }, +/*53*/ { "LASTERROR", &GAObjects[54], NULL, GetAttr_ApplicationLastError }, +/*54*/ { "ICONBORDER", &GAObjects[55], NULL, GetAttr_ApplicationIconBorder }, +/*55*/ { "FONT", NULL, &GAObjects[56], NULL }, +/*56*/ { "SCREEN", &GAObjects[61], &GAObjects[57], GetAttr_Get_ScreenFont }, +/*57*/ { "NAME", &GAObjects[58], NULL, GetAttr_ApplicationFontName }, +/*58*/ { "WIDTH", &GAObjects[59], NULL, GetAttr_ApplicationFontWidth }, +/*59*/ { "HEIGHT", &GAObjects[60], NULL, GetAttr_ApplicationFontHeight }, +/*60*/ { "SIZE", NULL, NULL, GetAttr_ApplicationFontSize }, +/*61*/ { "ICON", &GAObjects[66], &GAObjects[62], GetAttr_Get_IconFont }, +/*62*/ { "NAME", &GAObjects[63], NULL, GetAttr_ApplicationFontName }, +/*63*/ { "WIDTH", &GAObjects[64], NULL, GetAttr_ApplicationFontWidth }, +/*64*/ { "HEIGHT", &GAObjects[65], NULL, GetAttr_ApplicationFontHeight }, +/*65*/ { "SIZE", NULL, NULL, GetAttr_ApplicationFontSize }, +/*66*/ { "SYSTEM", NULL, &GAObjects[67], GetAttr_Get_SystemFont }, +/*67*/ { "NAME", &GAObjects[68], NULL, GetAttr_ApplicationFontName }, +/*68*/ { "WIDTH", &GAObjects[69], NULL, GetAttr_ApplicationFontWidth }, +/*69*/ { "HEIGHT", &GAObjects[70], NULL, GetAttr_ApplicationFontHeight }, +/*70*/ { "SIZE", NULL, NULL, GetAttr_ApplicationFontSize }, +/*71*/ { "WINDOWS", &GAObjects[75], &GAObjects[72], NULL }, +/*72*/ { "COUNT", &GAObjects[73], NULL, GetAttr_WindowsCount }, +/*73*/ { ENUM, &GAObjects[74], NULL, GetAttr_WindowsEnum, GetCount_Windows }, +/*74*/ { "ACTIVE", NULL, NULL, GetAttr_WindowsActive }, + +/*75*/ { "KEYCOMMANDS", &GAObjects[81], &GAObjects[76], NULL }, +/*76*/ { "COUNT", &GAObjects[77], NULL, GetAttr_KeyCommandsCount }, +/*77*/ { ENUM, NULL, &GAObjects[78], GetAttr_KeyCommandENUM, GetCount_KeyCommands }, +/*78*/ { "NAME", &GAObjects[79], NULL, GetAttr_KeyCommandName }, +/*79*/ { "KEY", &GAObjects[80], NULL, GetAttr_KeyCommandKey }, +/*80*/ { "COMMAND", NULL, NULL, GetAttr_KeyCommandCommand }, + +/*81*/ { "MENUCOMMANDS", NULL, &GAObjects[82], NULL }, +/*82*/ { "COUNT", &GAObjects[83], NULL, GetAttr_MenuCommandsCount }, +/*83*/ { ENUM, NULL, &GAObjects[84], GetAttr_MenuCommandENUM, GetCount_MenuCommands }, +/*84*/ { "NAME", &GAObjects[85], NULL, GetAttr_MenuCommandName }, +/*85*/ { "TITLE", &GAObjects[86], NULL, GetAttr_MenuCommandTitle }, +/*86*/ { "SHORTCUT", &GAObjects[87], NULL, GetAttr_MenuCommandShortcut }, +/*87*/ { "COMMAND", NULL, NULL, GetAttr_MenuCommandCommand }, + + }; + + +static void DoLeafCmd(const struct LeafCmd *lc, struct UData UserData, struct LeafData *lData, const char *ObjName, char *StemLeaf) +{ + BOOL NumFound = FALSE; + long long1; + + d1(kprintf(__FUNC__ "/%ld: lc=<%s> ObjName=<%s> ArgPtr=<%s> StemLeaf=<%s>\n", __LINE__, \ + lc ? lc->lc_Name : "---",\ + ObjName, lData->lres_ArgPtr, StemLeaf);) + + while (lc && RETURN_OK == lData->lres_Result) + { + ULONG Index = ~0; + + if (IS_ENUM(lc->lc_Name) /* && 0 == strlen(lData->lres_ArgPtr) */) + { + // "WINDOW.0" or "KEYCOMMANDS.4.NAME" + + if (1 == sscanf(ObjName, "%ld", &long1)) + NumFound = TRUE; + + Index = long1; + + d1(kprintf(__FUNC__ "/%ld: lc=<%s> Index=%08lx\n", __LINE__, lc->lc_Name, Index);) + } + if (NumFound || 0 == Stricmp((STRPTR) ObjName, (STRPTR) lc->lc_Name)) + { + char StemLeafBuff[100]; + + d1(kprintf(__FUNC__ "/%ld: lc=<%s>\n", __LINE__, lc->lc_Name);) + + if (IS_ENUM(lc->lc_Name) && ~0 == Index) + { + ULONG n, Count = 0; + + if (lc->lc_GetCount) + Count = (lc->lc_GetCount)(UserData, lData); + + d1(kprintf(__FUNC__ "/%ld: GetCount=%08lx Count=%ld\n", __LINE__, lc->lc_GetCount, Count);) + + // enumerate all objects + for (n=0; n < Count && RETURN_OK == lData->lres_Result; n++) + { + char NameBuff[20]; + + sprintf(NameBuff, "%ld", (long)n); + + if ('.' == *StemLeaf) + sprintf(StemLeafBuff, "%s%ld", StemLeaf, (long)n); + else + sprintf(StemLeafBuff, "%s.%ld", StemLeaf, (long)n); + + DoLeafCmd(lc, UserData, lData, NameBuff, StemLeafBuff); + } + return; + } + if (lc->lc_Function) + { + d1(kprintf(__FUNC__ "/%ld: lc=<%s> Index=%08lx\n", __LINE__, lc->lc_Name, Index);) + + UserData = (*lc->lc_Function)(UserData, lData, StemLeaf, Index); + } + + if (0 == strlen(lData->lres_ArgPtr)) + { + // end of Object name + // walk through all sub-objects + const struct LeafCmd *lcs = lc->lc_Sub; + + d1(kprintf(__FUNC__ "/%ld: Sub=%08lx\n", __LINE__, lcs);) + + if (lData->lres_Flags & LRESF_ORIGINALNAME) + { + if ((NULL == lcs && lData->lres_Args[ARG_STEM]) || + (lcs && NULL == lData->lres_Args[ARG_STEM]) ) + { + lData->lres_Result = ERROR_REQUIRED_ARG_MISSING; + d1(kprintf(__FUNC__ "/%ld: ERROR_REQUIRED_ARG_MISSING\n", __LINE__);) + } + } + + lData->lres_Flags &= ~LRESF_ORIGINALNAME; + + while (lcs && RETURN_OK == lData->lres_Result) + { + d1(kprintf(__FUNC__ "/%ld: Sub=<%s>\n", __LINE__, lcs->lc_Name);) + + strcpy(StemLeafBuff, StemLeaf); + strcat(StemLeafBuff, "."); + strcat(StemLeafBuff, lcs->lc_Name); + + DoLeafCmd(lcs, UserData, lData, lcs->lc_Name, StemLeafBuff); + + lcs = lcs->lc_Next; + } + + d1(kprintf(__FUNC__ "/%ld: Result=%08lx\n", __LINE__, lData->lres_Result);) + return; + } + else + { + char ArgName[100]; + + lData->lres_ArgPtr = GetNextArgPart(lData->lres_ArgPtr, ArgName, sizeof(ArgName)); + d1(kprintf(__FUNC__ "/%ld: ArgName=<%s> ArgPtr=<%s>\n", __LINE__, ArgName, lData->lres_ArgPtr);) + + DoLeafCmd(lc->lc_Sub, UserData, lData, ArgName, ""); + return; + } + } + + lc = lc->lc_Next; + } + + lData->lres_Result = ERROR_REQUIRED_ARG_MISSING; + + d1(kprintf(__FUNC__ "/%ld: ERROR_REQUIRED_ARG_MISSING\n", __LINE__);) +} + + +#if 0 +------------------------------------------------------------------------------ +GETATTR command + +Purpose: + +This command will retrieve information from the Workbench database, such the +names of the drawers currently open and the icons currently selected. + +Format: + +GETATTR [OBJECT] [NAME ][STEM ] [VAR ] + +Template: + +GETATTR OBJECT/A,NAME/K,STEM/K,VAR/K + +Parameters: + +OBJECT + +Name of the database entry to retrieve. For a list of valid entries see +below. + +NAME + +For some datatabase entries further information is required to identify the +data to retrieve. This is when you will need to provide a name. + +STEM + +If you request more than one database entry you will need to provide a +variable to store the information in. For an example of its use, see below. + +VAR + +If you want the queried information to be stored in a specific variable +(other than the RESULT variable), this is where you provive its name. + +Attributes: + +You can obtain information on the following attributes: + +APPLICATION.VERSION + +Version number of workbench.library. + +APPLICATION.SCREEN + +Name of the public screen Workbench uses. + +APPLICATION.AREXX + +Name of the Workbench ARexx port. + +APPLICATION.LASTERROR + +Number of the last error caused by the ARexx interface. + +APPLICATION.ICONBORDER + +Sizes of the icon borders, returned as four numbers separated by blank +spaces, e.g. "4 3 4 3". The four numbers represent the left border width, the +top border height, the right border width and the bottom border height (in +exactly that order). + +APPLICATION.FONT.SCREEN.NAME + +Name of the Workbench screen font. + +APPLICATION.FONT.SCREEN.WIDTH APPLICATION.FONT.SCREEN.HEIGHT + +Size of a single character of the Workbench screen font. Please note that +since the font in question may be proportional spaced the width information +may be of little value. To measure the accurate pixel width of a text in +reference to the font, use the .SIZE attribute. + +APPLICATION.FONT.SCREEN.SIZE + +Size of a text, measured in pixels, in reference to the screen font. The text +to measure must be provided with the NAME parameter of the GETATTR command. + +APPLICATION.FONT.ICON.NAME + +Name of the Workbench icon font. + +APPLICATION.FONT.ICON.WIDTH APPLICATION.FONT.ICON.HEIGHT + +Size of a single character of the Workbench icon font. Please note that since +the font in question may be proportional spaced the width information may be +of little value. To measure the accurate pixel width of a text in reference +to the font, use the .SIZE attribute. + +APPLICATION.FONT.ICON.SIZE + +Size of a text, measured in pixels, in reference to the icon font. The text +to measure must be provided with the NAME parameter of the GETATTR command. + +APPLICATION.FONT.SYSTEM.NAME + +Name of the system font. + +APPLICATION.FONT.SYSTEM.WIDTH +APPLICATION.FONT.SYSTEM.HEIGHT + +Size of a single character of the system font. + +APPLICATION.FONT.SYSTEM.SIZE + +Size of a text, measured in pixels, in reference to the system font. The text +to measure must be provided with the NAME parameter of the GETATTR command. + +WINDOWS.COUNT + +Number of the drawer windows currently open. This can be 0. + +WINDOWS.0 .. WINDOWS.N + +Names of the windows currently open. + +WINDOWS.ACTIVE + +Name of the currently active Workbench window; this will be "" if none of +Workbench`s windows is currently active. + +KEYCOMMANDS.COUNT + +Number of keyboard commands assigned. This can be 0. + +KEYCOMMANDS.0 .. KEYCOMMANDS.N + +Information on all the keyboard commands assigned. + +KEYCOMMANDS..NAME + +Name of the keyboard command. + +KEYCOMMANDS..KEY + +The key combination assigned to this keyboard command. + +KEYCOMMANDS..COMMAND + +The ARexx command assigned to this key combination. + +MENUCOMMANDS.COUNT + +Number of menu commands assigned (through the "MENU ADD .." command). This can +be 0. + +MENUCOMMANDS.0 .. MENUCOMMANDS.N + +Information on all the menu commands assigned. + +MENUCOMMANDS..NAME + +Name of this menu item. + +MENUCOMMANDS..TITLE + +Title of this menu item. + +MENUCOMMANDS..SHORTCUT + +The keyboard shortcut assigned to this menu item. + +MENUCOMMANDS..COMMAND + +The ARexx command assigned to this menu item. + +The following attributes require that the name of the window to obtain +information on is provided. + +Example: + +WINDOW.LEFT + +Left edge of the window. + +WINDOW.TOP + +Top edge of the window. + +WINDOW.WIDTH + +Width of the window. + +WINDOW.HEIGHT + +Height of the window. + +WINDOW.MIN.WIDTH + +Minimum width of the window. + +WINDOW.MIN.HEIGHT + +Minimum height of the window. + +WINDOW.MAX.WIDTH + +Maximum width of the window. + +WINDOW.MAX.HEIGHT + +Maximum height of the window. + +WINDOW.VIEW.LEFT + +Horizontal offset of the drawer contents; this value corresponds to the +horizontal window scroller position. + +WINDOW.VIEW.TOP + +Vertical offset of the drawer contents; this value corresponds to the +vertical window scroller position. + +WINDOW.SCREEN.NAME + +Name of the public screen the window was opened on. + +WINDOW.SCREEN.WIDTH WINDOW.SCREEN.HEIGHT + +Size of the public screen the window was opened on. + +WINDOW.ICONS.ALL.COUNT + +Number of the icons displayed in the window. This can be 0. + +WINDOW.ICONS.ALL.0 .. WINDOW.ICONS.ALL.N + +Information on all the icons displayed in the window: + +WINDOW.ICONS.ALL..NAME + +Name of the icon in question. + +WINDOW.ICONS.ALL..LEFT WINDOW.ICONS.ALL..TOP + +Position of the icon in question. + +WINDOW.ICONS.ALL..WIDTH WINDOW.ICONS.ALL..HEIGHT + +Size of the icon in question. + +WINDOW.ICONS.ALL..TYPE + +Type of the icon; one of DISK, DRAWER, TOOL, PROJECT,GARBAGE, DEVICE, KICK or +APPICON. + +WINDOW.ICONS.ALL..STATUS + +Whether the icon is selected and (if the icon is a drawer-likeobject, such as +a disk, drawer or trashcan icon) whether thecorresponding drawer is currently +open or closed. This attributeis returned in the form of a string, such as +"SELECTED OPEN" which means that the icon is selected and the corresponding +draweris currently open. The other options include "UNSELECTED" and "CLOSED". + +WINDOW.ICONS.SELECTED.COUNT + +Number of the selected icons displayed in the window. This can be 0. + +WINDOW.ICONS.SELECTED.0 .. WINDOW.ICONS.SELECTED.N + +Information on all selected the icons in the window: + +WINDOW.ICONS.SELECTED..NAME + +Name of the icon in question. + +WINDOW.ICONS.SELECTED..LEFT WINDOW.ICONS.SELECTED..TOP + +Position of the icon in question. + +WINDOW.ICONS.SELECTED..WIDTH WINDOW.ICONS.SELECTED..HEIGHT + +Size of the icon in question. + +WINDOW.ICONS.SELECTED..TYPE + +Type of the icon; one of DISK, DRAWER, TOOL, PROJECT,GARBAGE, DEVICE, KICK or +APPICON. + +WINDOW.ICONS.SELECTED..STATUS + +Whether the icon is selected and (if the icon is a drawer-like object, such +as a disk, drawer or trashcan icon) whether the corresponding drawer is +currently open or closed. This attribute is returned in the form of a string, +such as "SELECTED OPEN" which means that the icon is selected and the +corresponding drawer is currently open. The other options include "UNSELECTED" +and "CLOSED". Of course, for the WINDOW.ICONS.SELECTED stem the icon status +will always be reported as "SELECTED". + +WINDOW.ICONS.UNSELECTED.COUNT + +Number of the unselected icons displayed in the window. This can be 0. + +WINDOW.ICONS.UNSELECTED.0 .. WINDOW.ICONS.UNSELECTED.N + +Information on all selected the icons in the window: + +WINDOW.ICONS.UNSELECTED..NAME + +Name of the icon in question. + +WINDOW.ICONS.UNSELECTED..LEFT WINDOW.ICONS.UNSELECTED..TOP + +Position of the icon in question. + +WINDOW.ICONS.UNSELECTED..WIDTH WINDOW.ICONS.UNSELECTED..HEIGHT + +Size of the icon in question. + +WINDOW.ICONS.UNSELECTED..TYPE + +Type of the icon; one of DISK, DRAWER, TOOL, PROJECT, GARBAGE, DEVICE, KICK +or APPICON. + +WINDOW.ICONS.UNSELECTED..STATUS + +Whether the icon is selected and (if the icon is a drawer-like object, such +as a disk, drawer or trashcan icon) whether the corresponding drawer is +currently open or closed. This attribute is returned in the form of a string, +such as "UNSELECTED OPEN" which means that the icon is selected and the +corresponding drawer is currently open. The other options include "SELECTED" +and "CLOSED". Of course, for the WINDOW.ICONS.UNSELECTED stem the icon status +will always be reported as "UNSELECTED". + +Errors: + +10 - If the requester information could not be retrieved, you requested more +than one database entry and did not provide a stem variable or if you +provided a stem variable but did not request more than one database entry. +The error code will be placed in the WORKBENCH.LASTERROR variable. + +Result: + +RESULT - The information retrieved from the database. + +Example: + +/* Query the Workbench version. */ +ADDRESS workbench +OPTIONS RESULTS + +GETATTR application.version +SAY result + +/* Query the Workbench version and store it in the * variable +`version_number`. */ +GETATTR application.version +VAR version_number +SAY version_number + +/* Query the names of all currently open windows, * then print them. */ +GETATTR windows +STEM window_list + +DO i = 0 TO window_list.count-1 +SAY window_list.i; +END; + +/* Query name, position and size of the first icon * shown in the root +window. */ +GETATTR window.icons.all.0 +NAME root +STEM root + +SAY root.name +SAY root.left +SAY root.top +SAY root.width +SAY root.height +SAY root.type + +/* Query the width and height of the root window. */ +GETATTR window.width +NAME root +SAY result + +GETATTR window.height +NAME root +SAY result + +/* Query the length of a text (in pixels) with reference * to the icon font. +*/ +GETATTR application.font.icon.size +NAME ,Text to measure` +SAY result + +------------------------------------------------------------------------------ +#endif +LONG Cmd_GetAttr(APTR UserData, struct RexxMsg *Message,STRPTR *Args) +{ + char ArgName[100]; + struct LeafData lData; + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: obj=%08lx name=%08lx stem=%08lx var=%08lx\n", __LINE__,\ + Args[ARG_OBJECT], Args[ARG_NAME], Args[ARG_STEM], Args[ARG_VAR]);) + + if (NULL == Args[ARG_OBJECT]) + { + d1(kprintf(__FUNC__ "/%ld: ERROR_REQUIRED_ARG_MISSING\n", __LINE__);) + return(ERROR_REQUIRED_ARG_MISSING); + } + + d(kprintf(__FUNC__ "/%ld: obj=<%s>\n", __LINE__, Args[ARG_OBJECT] ? Args[ARG_OBJECT] : (unsigned char *) "");) + d(kprintf(__FUNC__ "/%ld: name=<%s>\n", __LINE__, Args[ARG_NAME] ? Args[ARG_NAME] : (unsigned char *) "");) + d(kprintf(__FUNC__ "/%ld: stem=<%s>\n", __LINE__, Args[ARG_STEM] ? Args[ARG_STEM] : (unsigned char *) "");) + d(kprintf(__FUNC__ "/%ld: var=<%s>\n", __LINE__, Args[ARG_VAR] ? Args[ARG_VAR] : (unsigned char *) "");) + + lData.lres_ArgPtr = GetNextArgPart(Args[ARG_OBJECT], ArgName, sizeof(ArgName)); + d(kprintf(__FUNC__ "/%ld: ArgName=<%s> ArgPtr=<%s>\n", __LINE__, ArgName, lData.lres_ArgPtr);) + + lData.lres_Message = Message; + lData.lres_Result = RETURN_OK; + lData.lres_ResultString = NULL; + lData.lres_Args = Args; + lData.lres_Flags = LRESF_ORIGINALNAME; + + DoLeafCmd(&GAObjects[0], uEmpty, &lData, ArgName, ""); + + if (RETURN_OK == lData.lres_Result) + { + if (Args[ARG_VAR]) + { + strupr(Args[ARG_VAR]); + + if (lData.lres_ResultString) + SetRexxVar(Message, Args[ARG_VAR], (STRPTR) lData.lres_ResultString, strlen(lData.lres_ResultString)); + else + SetRexxVar(Message, Args[ARG_VAR], "", 0); + + ReturnRexxMsg(Message, NULL); + } + else + { + ReturnRexxMsg(Message, (STRPTR) lData.lres_ResultString); + } + } + + + return lData.lres_Result; +} + + +static ULONG GetWindowCount(void) +{ + struct ScaWindowList *swList = SCA_LockWindowList(SCA_LockWindowList_Shared); + ULONG Count = 0; + + if (swList) + { + struct ScaWindowStruct *swi; + + for (swi=swList->wl_WindowStruct; swi; swi = (struct ScaWindowStruct *) swi->ws_Node.mln_Succ) + { + d(kprintf(__FUNC__ "/%ld: swi=%08lx Lock=%08lx Flags=%08lx\n", __LINE__, \ + swi, swi->ws_Lock, swi->ws_Flags)); + + Count++; + } + + SCA_UnLockWindowList(); + } + + return Count; +} + + +static void SetRexxStemVar(struct RexxMsg *Message, const char *Stem, const char *VarName, const char *Value) +{ + char vName[100]; + + strcpy(vName, Stem); + if (*VarName && '.' != *VarName) + strcat(vName, "."); + + strcat(vName, VarName); + + SetRexxVar(Message, vName, (STRPTR) Value, strlen(Value)); +} + + +static ULONG GetWindowIconCount(struct ScaWindowStruct *swi, enum IconState Mode) +{ + ULONG Count = 0; + struct ScaWindowTask *wt = swi->ws_WindowTask; + + d(kprintf(__FUNC__ "/%ld: ScaWindowStruct=%08lx ScaWindowTask=%08lx\n", __LINE__, swi, wt)); + + if (wt) + { + struct ScaIconNode *icon; + char wBuffer[256]; + + if (swi->ws_Lock) + NameFromLock(swi->ws_Lock, wBuffer, sizeof(wBuffer)); + + ObtainSemaphore(wt->wt_IconSemaphore); + + for (icon=wt->wt_IconList; icon; icon = (struct ScaIconNode *) icon->in_Node.mln_Succ) + { + char *Name = NULL; + + GetAttr(IDTA_Text, icon->in_Icon, (APTR) &Name); + + if (Name) + { + switch (Mode) + { + case icst_All: + Count++; + break; + case icst_Selected: + if (isIconSelected(icon)) + Count++; + break; + case icst_Unselected: + if (!isIconSelected(icon)) + Count++; + break; + } + } + } + + ReleaseSemaphore(wt->wt_IconSemaphore); + } + + return Count; +} + + +static struct ScaIconNode *GetWindowIconN(struct ScaWindowStruct *swi, enum IconState Mode, ULONG Index) +{ + ULONG Count = 0; + struct ScaWindowTask *wt = swi->ws_WindowTask; + struct ScaIconNode *Result = NULL; + + d1(kprintf(__FUNC__ "/%ld: ScaWindowStruct=%08lx ScaWindowTask=%08lx Mode=%ld\n", __LINE__, swi, wt, Mode)); + + if (wt) + { + struct ScaIconNode *icon; + + ObtainSemaphore(wt->wt_IconSemaphore); + + for (icon=wt->wt_IconList; NULL == Result && icon; icon = (struct ScaIconNode *) icon->in_Node.mln_Succ) + { + d1(kprintf(__FUNC__ "/%ld: Index=%ld Count=%ld icon=%08lx\n", __LINE__, Index, Count, icon)); + + switch (Mode) + { + case icst_All: + if (Count++ == Index) + Result = icon; + break; + case icst_Selected: + if (isIconSelected(icon)) + { + if (Count++ == Index) + Result = icon; + } + break; + case icst_Unselected: + if (!isIconSelected(icon)) + { + if (Count++ == Index) + Result = icon; + } + break; + } + } + + ReleaseSemaphore(wt->wt_IconSemaphore); + } + + d1(kprintf(__FUNC__ "/%ld: Result=%08lx\n", __LINE__, Result)); + + return Result; +} + + +static struct UData GetAttr_WindowLeft(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct ScaWindowStruct *swi = (struct ScaWindowStruct *) UserData.uda_Data; + struct UData uEmpty = { NULL, udaType_Nothing }; + + if (NULL == swi) + swi = FindWindowByName(lData->lres_Args[ARG_NAME]); + else + { + if (udaType_ScaWindowStruct != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + } + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (swi && swi->ws_Window) + { + sprintf(lData->lres_ResultBuffer, "%d", swi->ws_Window->LeftEdge); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + + return uEmpty; +} + + +static struct UData GetAttr_WindowTop(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct ScaWindowStruct *swi = (struct ScaWindowStruct *) UserData.uda_Data; + struct UData uEmpty = { NULL, udaType_Nothing }; + + if (NULL == swi) + swi = FindWindowByName(lData->lres_Args[ARG_NAME]); + else + { + if (udaType_ScaWindowStruct != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + } + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (swi && swi->ws_Window) + { + sprintf(lData->lres_ResultBuffer, "%d", swi->ws_Window->TopEdge); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + + return uEmpty; +} + + +static struct UData GetAttr_WindowWidth(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct ScaWindowStruct *swi = (struct ScaWindowStruct *) UserData.uda_Data; + struct UData uEmpty = { NULL, udaType_Nothing }; + + if (NULL == swi) + swi = FindWindowByName(lData->lres_Args[ARG_NAME]); + else + { + if (udaType_ScaWindowStruct != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + } + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (swi && swi->ws_Window) + { + sprintf(lData->lres_ResultBuffer, "%d", swi->ws_Window->Width); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + return uEmpty; +} + + +static struct UData GetAttr_WindowHeight(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct ScaWindowStruct *swi = (struct ScaWindowStruct *) UserData.uda_Data; + struct UData uEmpty = { NULL, udaType_Nothing }; + + if (NULL == swi) + swi = FindWindowByName(lData->lres_Args[ARG_NAME]); + else + { + if (udaType_ScaWindowStruct != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + } + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (swi && swi->ws_Window) + { + sprintf(lData->lres_ResultBuffer, "%d", swi->ws_Window->Height); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + return uEmpty; +} + + +static struct UData GetAttr_WindowMinWidth(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct ScaWindowStruct *swi = (struct ScaWindowStruct *) UserData.uda_Data; + struct UData uEmpty = { NULL, udaType_Nothing }; + + if (NULL == swi) + swi = FindWindowByName(lData->lres_Args[ARG_NAME]); + else + { + if (udaType_ScaWindowStruct != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + } + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (swi && swi->ws_Window) + { + sprintf(lData->lres_ResultBuffer, "%d", swi->ws_Window->MinWidth); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + return uEmpty; +} + + +static struct UData GetAttr_WindowMinHeight(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct ScaWindowStruct *swi = (struct ScaWindowStruct *) UserData.uda_Data; + struct UData uEmpty = { NULL, udaType_Nothing }; + + if (NULL == swi) + swi = FindWindowByName(lData->lres_Args[ARG_NAME]); + else + { + if (udaType_ScaWindowStruct != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + } + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (swi && swi->ws_Window) + { + sprintf(lData->lres_ResultBuffer, "%d", swi->ws_Window->MinHeight); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + return uEmpty; +} + + +static struct UData GetAttr_WindowMaxWidth(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct ScaWindowStruct *swi = (struct ScaWindowStruct *) UserData.uda_Data; + struct UData uEmpty = { NULL, udaType_Nothing }; + + if (NULL == swi) + swi = FindWindowByName(lData->lres_Args[ARG_NAME]); + else + { + if (udaType_ScaWindowStruct != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + } + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (swi && swi->ws_Window) + { + sprintf(lData->lres_ResultBuffer, "%d", swi->ws_Window->MaxWidth); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + + return uEmpty; +} + + +static struct UData GetAttr_WindowMaxHeight(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct ScaWindowStruct *swi = (struct ScaWindowStruct *) UserData.uda_Data; + struct UData uEmpty = { NULL, udaType_Nothing }; + + if (NULL == swi) + swi = FindWindowByName(lData->lres_Args[ARG_NAME]); + else + { + if (udaType_ScaWindowStruct != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + } + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (swi && swi->ws_Window) + { + sprintf(lData->lres_ResultBuffer, "%d", swi->ws_Window->MaxHeight); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + + return uEmpty; +} + + +static struct UData GetAttr_WindowViewLeft(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct ScaWindowStruct *swi = (struct ScaWindowStruct *) UserData.uda_Data; + struct UData uEmpty = { NULL, udaType_Nothing }; + + if (NULL == swi) + swi = FindWindowByName(lData->lres_Args[ARG_NAME]); + else + { + if (udaType_ScaWindowStruct != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + } + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (swi) + { + sprintf(lData->lres_ResultBuffer, "%d", swi->ws_xoffset); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + + return uEmpty; +} + + +static struct UData GetAttr_WindowViewTop(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct ScaWindowStruct *swi = (struct ScaWindowStruct *) UserData.uda_Data; + struct UData uEmpty = { NULL, udaType_Nothing }; + + if (NULL == swi) + swi = FindWindowByName(lData->lres_Args[ARG_NAME]); + else + { + if (udaType_ScaWindowStruct != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + } + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (swi) + { + sprintf(lData->lres_ResultBuffer, "%d", swi->ws_yoffset); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + + return uEmpty; +} + + +static struct UData GetAttr_Get_WindowFromName(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct ScaWindowStruct *swi = FindWindowByName(lData->lres_Args[ARG_NAME]); + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (NULL == swi) + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + else + { + uEmpty.uda_Data = swi; + uEmpty.uda_Type = udaType_ScaWindowStruct; + } + + return uEmpty; +} + + +static struct UData GetAttr_Get_ScreenFromWindow(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct ScaWindowStruct *swi = (struct ScaWindowStruct *) UserData.uda_Data; + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (udaType_ScaWindowStruct != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + + if (swi && swi->ws_Window) + { + uEmpty.uda_Data = swi->ws_Window->WScreen; + uEmpty.uda_Type = udaType_Screen; + } + + return uEmpty; +} + + +static struct UData GetAttr_WindowScreenName(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct Screen *scr = (struct Screen *) UserData.uda_Data; + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (udaType_Screen != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + + strcpy(lData->lres_ResultBuffer, ""); + + if (scr) + { + struct PubScreenNode *pubscreen; + struct List *pubList = LockPubScreenList(); + + pubscreen = (struct PubScreenNode *) pubList->lh_Head; + + while (pubscreen->psn_Node.ln_Succ != 0) + { + if (pubscreen->psn_Screen == scr) + { + sprintf(lData->lres_ResultBuffer, "%s", pubscreen->psn_Node.ln_Name); + break; + } + + pubscreen = (struct PubScreenNode *) pubscreen->psn_Node.ln_Succ; + } + + UnlockPubScreenList(); + } + + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + + return uEmpty; +} + + +static struct UData GetAttr_WindowScreenWidth(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct Screen *scr = (struct Screen *) UserData.uda_Data; + struct UData uEmpty = { NULL, udaType_Nothing }; + WORD Width = 0; + + if (udaType_Screen != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (scr) + { + Width = scr->Width; + } + + sprintf(lData->lres_ResultBuffer, "%d", Width); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + + return uEmpty; +} + + +static struct UData GetAttr_WindowScreenHeight(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct Screen *scr = (struct Screen *) UserData.uda_Data; + struct UData uEmpty = { NULL, udaType_Nothing }; + WORD Height = 0; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (udaType_Screen != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + if (scr) + { + Height = scr->Height; + } + + sprintf(lData->lres_ResultBuffer, "%d", Height); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + + return uEmpty; +} + + +static struct UData GetAttr_WindowIconsAllCount(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + sprintf(lData->lres_ResultBuffer, "%ld", (long)GetCount_AllIcon(UserData, lData)); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + + return uEmpty; +} + + +static struct UData GetAttr_Get_AllIconENUM(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct ScaWindowStruct *swi = (struct ScaWindowStruct *) UserData.uda_Data; + struct ScaIconNode *sIcon = NULL; + struct UData uEmpty = { NULL, udaType_Nothing }; + + if (udaType_ScaWindowStruct != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + if (NULL == swi) + swi = FindWindowByName(lData->lres_Args[ARG_NAME]); + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (swi) + { + sIcon = GetWindowIconN(swi, icst_All, Index); + } + + if (NULL == sIcon) + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + else + { + uEmpty.uda_Data = sIcon; + uEmpty.uda_Type = udaType_ScaIconNode; + } + + return uEmpty; +} + + +static struct UData GetAttr_WindowIconsName(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct ScaIconNode *sIcon = (struct ScaIconNode *) UserData.uda_Data; + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (udaType_ScaIconNode != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + if (sIcon) + { + char *Name = NULL; + + GetAttr(IDTA_Text, sIcon->in_Icon, (APTR) &Name); + + if (Name) + { + stccpy(lData->lres_ResultBuffer, Name, sizeof(lData->lres_ResultBuffer)); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + + return uEmpty; +} + + +static struct UData GetAttr_WindowIconsLeft(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct ScaIconNode *sIcon = (struct ScaIconNode *) UserData.uda_Data; + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (udaType_ScaIconNode != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + if (sIcon) + { + struct ExtGadget *gg = (struct ExtGadget *) sIcon->in_Icon; + + if (gg) + { + sprintf(lData->lres_ResultBuffer, "%d", gg->LeftEdge); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + + return uEmpty; +} + + +static struct UData GetAttr_WindowIconsTop(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct ScaIconNode *sIcon = (struct ScaIconNode *) UserData.uda_Data; + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (udaType_ScaIconNode != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + if (sIcon) + { + struct ExtGadget *gg = (struct ExtGadget *) sIcon->in_Icon; + + if (gg) + { + sprintf(lData->lres_ResultBuffer, "%d", gg->TopEdge); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + + return uEmpty; +} + + +static struct UData GetAttr_WindowIconsWidth(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct ScaIconNode *sIcon = (struct ScaIconNode *) UserData.uda_Data; + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (udaType_ScaIconNode != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + if (sIcon) + { + struct ExtGadget *gg = (struct ExtGadget *) sIcon->in_Icon; + + if (gg) + { + sprintf(lData->lres_ResultBuffer, "%d", gg->Width); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + + return uEmpty; +} + + +static struct UData GetAttr_WindowIconsHeight(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct ScaIconNode *sIcon = (struct ScaIconNode *) UserData.uda_Data; + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (udaType_ScaIconNode != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + if (sIcon) + { + struct ExtGadget *gg = (struct ExtGadget *) sIcon->in_Icon; + + if (gg) + { + sprintf(lData->lres_ResultBuffer, "%d", gg->Height); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + + return uEmpty; +} + + +static struct UData GetAttr_WindowIconsType(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct ScaIconNode *sIcon = (struct ScaIconNode *) UserData.uda_Data; + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (udaType_ScaIconNode != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + if (sIcon) + { + if (sIcon->in_Icon) + { + IPTR Type; + + GetAttr(IDTA_Type, sIcon->in_Icon, &Type); + + switch (Type) + { + case WBDISK: + strcpy(lData->lres_ResultBuffer, "DISK"); + break; + case WBDRAWER: + strcpy(lData->lres_ResultBuffer, "DRAWER"); + break; + case WBTOOL: + strcpy(lData->lres_ResultBuffer, "TOOL"); + break; + case WBPROJECT: + strcpy(lData->lres_ResultBuffer, "PROJECT"); + break; + case WBGARBAGE: + strcpy(lData->lres_ResultBuffer, "GARBAGE"); + break; + case WBDEVICE: + strcpy(lData->lres_ResultBuffer, "DEVICE"); + break; + case WBKICK: + strcpy(lData->lres_ResultBuffer, "KICK"); + break; + case WBAPPICON: + strcpy(lData->lres_ResultBuffer, "APPICON"); + break; + default: + strcpy(lData->lres_ResultBuffer, "????"); + break; + } + + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + + return uEmpty; +} + + +static struct UData GetAttr_WindowIconsStatus(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct ScaIconNode *sIcon = (struct ScaIconNode *) UserData.uda_Data; + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (udaType_ScaIconNode != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + if (sIcon) + { + struct Gadget *gg = (struct Gadget *) sIcon->in_Icon; + + if (gg) + { + sprintf(lData->lres_ResultBuffer, "%s %s", + (gg->Flags & GFLG_SELECTED) ? "SELECTED" : "UNSELECTED", + IsIconNodeOpen(sIcon) ? "OPEN" : "CLOSED"); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + + return uEmpty; +} + + +static struct UData GetAttr_WindowIconsSelectedCount(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + sprintf(lData->lres_ResultBuffer, "%ld", (long)GetCount_SelectedIcon(UserData, lData)); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + + return uEmpty; +} + + +static struct UData GetAttr_WindowIconsUnselectedCount(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + sprintf(lData->lres_ResultBuffer, "%ld", (long)GetCount_UnselectedIcon(UserData, lData)); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + + return uEmpty; +} + + +static struct UData GetAttr_Get_SelectedIconENUM(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct ScaWindowStruct *swi = (struct ScaWindowStruct *) UserData.uda_Data; + struct ScaIconNode *sIcon = NULL; + struct UData uEmpty = { NULL, udaType_Nothing }; + + if (NULL == swi) + swi = FindWindowByName(lData->lres_Args[ARG_NAME]); + else + { + if (udaType_ScaWindowStruct != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + } + + d1(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s> Index=%ld\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr, Index);) + + if (swi) + { + sIcon = GetWindowIconN(swi, icst_Selected, Index); + } + + if (NULL == sIcon) + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + else + { + uEmpty.uda_Data = sIcon; + uEmpty.uda_Type = udaType_ScaIconNode; + } + + return uEmpty; +} + + +static struct UData GetAttr_Get_UnselectedIconENUM(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct ScaWindowStruct *swi = (struct ScaWindowStruct *) UserData.uda_Data; + struct ScaIconNode *sIcon = NULL; + struct UData uEmpty = { NULL, udaType_Nothing }; + + if (NULL == swi) + swi = FindWindowByName(lData->lres_Args[ARG_NAME]); + else + { + if (udaType_ScaWindowStruct != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + } + + d1(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s> Index=%ld\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr, Index);) + + if (swi) + { + sIcon = GetWindowIconN(swi, icst_Unselected, Index); + } + + if (NULL == sIcon) + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + else + { + uEmpty.uda_Data = sIcon; + uEmpty.uda_Type = udaType_ScaIconNode; + } + + return uEmpty; +} + + +static struct UData GetAttr_ApplicationVersion(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + sprintf(lData->lres_ResultBuffer, "%d.%d", ScalosBase->scb_LibNode.lib_Version, ScalosBase->scb_LibNode.lib_Revision); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + + return uEmpty; +} + + +static struct UData GetAttr_ApplicationScreen(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + d(kprintf(__FUNC__ "/%ld: rList=%08lx\n", __LINE__, rList);) + + PutResult(lData, ScreenName, StemLeaf); + + return uEmpty; +} + + +static struct UData GetAttr_ApplicationARexx(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + PutResult(lData, ARexxPortName, StemLeaf); + + return uEmpty; +} + + +static struct UData GetAttr_ApplicationLastError(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + d(kprintf(__FUNC__ "/%ld: LastError=%ld\n", __LINE__, LastError);) + + sprintf(lData->lres_ResultBuffer, "%ld", (long)LastError); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + + return uEmpty; +} + + +static struct UData GetAttr_ApplicationIconBorder(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + sprintf(lData->lres_ResultBuffer, "%d %d %d %d", + ScalosPrefs_IconOffsets[0], + ScalosPrefs_IconOffsets[1], + ScalosPrefs_IconOffsets[2], + ScalosPrefs_IconOffsets[3]); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + + return uEmpty; +} + + +static struct UData GetAttr_Get_ScreenFont(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct TextFont *font; + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + font = rList->rl_internInfos->ii_DrawInfo->dri_Font; + + uEmpty.uda_Data = font; + uEmpty.uda_Type = udaType_TextFont; + + return uEmpty; +} + + +static struct UData GetAttr_Get_IconFont(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct TextFont *font = NULL; + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (rList) + { + GetAttr(SCCA_IconWin_IconFont, rList->rl_internInfos->ii_MainWindowStruct->ws_WindowTask->mt_MainObject, (APTR) &font); + } + + uEmpty.uda_Data = font; + uEmpty.uda_Type = udaType_TextFont; + + return uEmpty; +} + + +static struct UData GetAttr_Get_SystemFont(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct TextFont *font = NULL; + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (rList->rl_internInfos->ii_MainWindowStruct->ws_Window) + font = rList->rl_internInfos->ii_MainWindowStruct->ws_Window->IFont; + + uEmpty.uda_Data = font; + uEmpty.uda_Type = udaType_TextFont; + + return uEmpty; +} + + +static struct UData GetAttr_ApplicationFontName(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct TextFont *font = (struct TextFont *) UserData.uda_Data; + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (udaType_TextFont != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + if (font) + { + sprintf(lData->lres_ResultBuffer, "%s", font->tf_Message.mn_Node.ln_Name); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + } + + return uEmpty; +} + + +static struct UData GetAttr_ApplicationFontWidth(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct TextFont *font = (struct TextFont *) UserData.uda_Data; + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (udaType_TextFont != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + if (font) + { + sprintf(lData->lres_ResultBuffer, "%d", font->tf_XSize); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + } + + return uEmpty; +} + + +static struct UData GetAttr_ApplicationFontHeight(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct TextFont *font = (struct TextFont *) UserData.uda_Data; + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (udaType_TextFont != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + if (font) + { + sprintf(lData->lres_ResultBuffer, "%d", font->tf_YSize); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + } + + return uEmpty; +} + + +static struct UData GetAttr_ApplicationFontSize(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct TextFont *font = (struct TextFont *) UserData.uda_Data; + STRPTR Text = lData->lres_Args[ARG_NAME]; + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (NULL == Text) + Text = ""; + + if (udaType_TextFont != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + if (font) + { + struct RastPort rp; + + InitRastPort(&rp); + SetFont(&rp, font); + + sprintf(lData->lres_ResultBuffer, "%d", TextLength(&rp, Text, strlen(Text))); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + } + + return uEmpty; +} + + +static struct UData GetAttr_WindowsCount(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + sprintf(lData->lres_ResultBuffer, "%ld", (long)GetCount_Windows(UserData, lData)); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + + return uEmpty; +} + + +static struct UData GetAttr_WindowsEnum(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct UData uEmpty = { NULL, udaType_Nothing }; + struct ScaWindowList *swList = SCA_LockWindowList(SCA_LockWindowList_Shared); + ULONG Count = 0; + BOOL Found = FALSE; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s> Index=%ld\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr, Index);) + + if (swList) + { + struct ScaWindowStruct *swi; + + for (swi=swList->wl_WindowStruct; !Found && swi; swi = (struct ScaWindowStruct *) swi->ws_Node.mln_Succ) + { + d(kprintf(__FUNC__ "/%ld: swi=%08lx Lock=%08lx Flags=%08lx\n", __LINE__, \ + swi, swi->ws_Lock, swi->ws_Flags)); + + if (swi->ws_Lock) + { + if (NameFromLock(swi->ws_Lock, lData->lres_ResultBuffer, sizeof(lData->lres_ResultBuffer))) + { + } + else + { + strcpy(lData->lres_ResultBuffer, "???"); + } + } + else + { + strcpy(lData->lres_ResultBuffer, "root"); + } + + if (Count == Index) + { + Found = TRUE; + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + break; + } + + Count++; + } + + SCA_UnLockWindowList(); + } + + if (!Found) + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + + return uEmpty; +} + + +static struct UData GetAttr_WindowsActive(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct UData uEmpty = { NULL, udaType_Nothing }; + struct ScaWindowList *swList = SCA_LockWindowList(SCA_LockWindowList_Shared); + BOOL Found = FALSE; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s> Index=%ld\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr, Index);) + + if (swList) + { + struct ScaWindowStruct *swi; + + for (swi=swList->wl_WindowStruct; !Found && swi; swi = (struct ScaWindowStruct *) swi->ws_Node.mln_Succ) + { + d(kprintf(__FUNC__ "/%ld: swi=%08lx Lock=%08lx Flags=%08lx\n", __LINE__, \ + swi, swi->ws_Lock, swi->ws_Flags)); + + if (swi->ws_Lock) + { + if (NameFromLock(swi->ws_Lock, lData->lres_ResultBuffer, sizeof(lData->lres_ResultBuffer))) + { + } + else + { + strcpy(lData->lres_ResultBuffer, "???"); + } + } + else + { + strcpy(lData->lres_ResultBuffer, "root"); + } + + if (swi->ws_Window == IntuitionBase->ActiveWindow) + { + Found = TRUE; + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + break; + } + } + + SCA_UnLockWindowList(); + } + + if (!Found) + PutResult(lData, "", StemLeaf); + + return uEmpty; +} + + +static void PutResult(struct LeafData *lData, const char *Value, const char *StemLeaf) +{ + d(kprintf(__FUNC__ "/%ld: Value=<%s>\n", __LINE__, Value);) + + if (lData->lres_Args[ARG_STEM]) + { + d(kprintf(__FUNC__ "/%ld: Value=<%s> StemLeaf=<%s>\n", __LINE__, Value, StemLeaf);) + + SetRexxStemVar(lData->lres_Message, lData->lres_Args[ARG_STEM], StemLeaf, Value); + } + else + { + lData->lres_ResultString = Value; + } +} + + +static ULONG GetCount_Windows(struct UData UserData, struct LeafData *lData) +{ + return GetWindowCount(); +} + + +static ULONG GetCount_AllIcon(struct UData UserData, struct LeafData *lData) +{ + struct ScaWindowStruct *swi = (struct ScaWindowStruct *) UserData.uda_Data; + ULONG Count = 0; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (udaType_ScaWindowStruct != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return 0; + } + if (swi) + Count = GetWindowIconCount(swi, icst_All); + + return Count; +} + + +static ULONG GetCount_SelectedIcon(struct UData UserData, struct LeafData *lData) +{ + struct ScaWindowStruct *swi = (struct ScaWindowStruct *) UserData.uda_Data; + ULONG Count = 0; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (udaType_ScaWindowStruct != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return 0; + } + if (swi) + Count = GetWindowIconCount(swi, icst_Selected); + + return Count; +} + + +static ULONG GetCount_UnselectedIcon(struct UData UserData, struct LeafData *lData) +{ + struct ScaWindowStruct *swi = (struct ScaWindowStruct *) UserData.uda_Data; + ULONG Count = 0; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (udaType_ScaWindowStruct != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return 0; + } + if (swi) + Count = GetWindowIconCount(swi, icst_Unselected); + + return Count; +} + + +static struct UData GetAttr_KeyCommandsCount(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + sprintf(lData->lres_ResultBuffer, "%ld", (long)GetCount_KeyCommands(UserData, lData)); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + + return uEmpty; +} + + +static struct UData GetAttr_MenuCommandsCount(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + sprintf(lData->lres_ResultBuffer, "%ld", (long)GetCount_MenuCommands(UserData, lData)); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + + return uEmpty; +} + + +static ULONG GetCount_KeyCommands(struct UData UserData, struct LeafData *lData) +{ + ULONG Count = 0; + const struct KeyboardCommand *kbc; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + for (kbc = (struct KeyboardCommand *) KbdCommandList.lh_Head; + kbc != (struct KeyboardCommand *) &KbdCommandList.lh_Tail; + kbc = (struct KeyboardCommand *) kbc->kbc_Node.ln_Succ) + { + Count++; + } + + return Count; +} + + +static ULONG GetCount_MenuCommands(struct UData UserData, struct LeafData *lData) +{ + ULONG Count = 0; + const struct ToolMenuItem *tmi; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + for (tmi = (struct ToolMenuItem *) MenuItemList.lh_Head; + tmi != (struct ToolMenuItem *) &MenuItemList.lh_Tail; + tmi = (struct ToolMenuItem *) tmi->tmi_Node.ln_Succ) + { + Count++; + } + + d1(kprintf(__FUNC__ "/%ld: Count=%lu\n", __LINE__, Count);) + + return Count; +} + + +static struct UData GetAttr_MenuCommandENUM(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct ToolMenuItem *tmi, *tmiFound; + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + tmiFound = NULL; + + for (tmi = (struct ToolMenuItem *) MenuItemList.lh_Head; + tmi != (struct ToolMenuItem *) &MenuItemList.lh_Tail; + tmi = (struct ToolMenuItem *) tmi->tmi_Node.ln_Succ) + { + if (Index-- == 0) + { + tmiFound = tmi; + break; + } + } + + if (tmiFound) + { + uEmpty.uda_Data = tmiFound; + uEmpty.uda_Type = udaType_MenuCommand; + } + else + { + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + } + + return uEmpty; +} + + +static struct UData GetAttr_KeyCommandENUM(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct KeyboardCommand *kbc, *kbcFound; + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + kbcFound = NULL; + + for (kbc = (struct KeyboardCommand *) KbdCommandList.lh_Head; + kbc != (struct KeyboardCommand *) &KbdCommandList.lh_Tail; + kbc = (struct KeyboardCommand *) kbc->kbc_Node.ln_Succ) + { + if (Index-- == 0) + { + kbcFound = kbc; + break; + } + } + + if (kbcFound) + { + d1(kprintf(__FUNC__ "/%ld: kbc=%08lx\n", __LINE__, kbcFound);) + + uEmpty.uda_Data = kbcFound; + uEmpty.uda_Type = udaType_KeyCommand; + } + else + { + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + } + + return uEmpty; +} + + +static struct UData GetAttr_KeyCommandName(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct KeyboardCommand *kbc; + struct UData uEmpty = { NULL, udaType_Nothing }; + + d1(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (udaType_KeyCommand != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + + kbc = (struct KeyboardCommand *) UserData.uda_Data; + + d1(kprintf(__FUNC__ "/%ld: kbc=%08lx\n", __LINE__, kbc);) + + if (kbc) + { + stccpy(lData->lres_ResultBuffer, kbc->kbc_Name, sizeof(lData->lres_ResultBuffer)); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + + return uEmpty; +} + + +static struct UData GetAttr_KeyCommandKey(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct KeyboardCommand *kbc; + struct UData uEmpty = { NULL, udaType_Nothing }; + + d1(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (udaType_KeyCommand != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + + kbc = (struct KeyboardCommand *) UserData.uda_Data; + + d1(kprintf(__FUNC__ "/%ld: kbc=%08lx\n", __LINE__, kbc);) + + if (kbc) + { + stccpy(lData->lres_ResultBuffer, kbc->kbc_Key, sizeof(lData->lres_ResultBuffer)); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + + return uEmpty; +} + + +static struct UData GetAttr_KeyCommandCommand(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct KeyboardCommand *kbc; + struct UData uEmpty = { NULL, udaType_Nothing }; + + d1(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (udaType_KeyCommand != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + + kbc = (struct KeyboardCommand *) UserData.uda_Data; + + d1(kprintf(__FUNC__ "/%ld: kbc=%08lx\n", __LINE__, kbc);) + + if (kbc) + { + stccpy(lData->lres_ResultBuffer, kbc->kbc_Cmd, sizeof(lData->lres_ResultBuffer)); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + + return uEmpty; +} + + +static struct UData GetAttr_MenuCommandName(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct ToolMenuItem *tmi; + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (udaType_MenuCommand != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + + tmi = (struct ToolMenuItem *) UserData.uda_Data; + + if (tmi) + { + stccpy(lData->lres_ResultBuffer, tmi->tmi_Name, sizeof(lData->lres_ResultBuffer)); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + + return uEmpty; +} + + +static struct UData GetAttr_MenuCommandTitle(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct ToolMenuItem *tmi; + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (udaType_MenuCommand != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + + tmi = (struct ToolMenuItem *) UserData.uda_Data; + + if (tmi) + { + stccpy(lData->lres_ResultBuffer, tmi->tmi_Title, sizeof(lData->lres_ResultBuffer)); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + + return uEmpty; +} + + +static struct UData GetAttr_MenuCommandShortcut(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct ToolMenuItem *tmi; + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr);) + + if (udaType_MenuCommand != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + + tmi = (struct ToolMenuItem *) UserData.uda_Data; + + if (tmi) + { + stccpy(lData->lres_ResultBuffer, tmi->tmi_Shortcut, sizeof(lData->lres_ResultBuffer)); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + + return uEmpty; +} + + +static struct UData GetAttr_MenuCommandCommand(struct UData UserData, struct LeafData *lData, const char *StemLeaf, ULONG Index) +{ + struct ToolMenuItem *tmi; + struct UData uEmpty = { NULL, udaType_Nothing }; + + d(kprintf(__FUNC__ "/%ld: UserData=%08lx ArgPtr=<%s>\n", __LINE__, UserData.uda_Type, lData->lres_ArgPtr)); + + if (udaType_MenuCommand != UserData.uda_Type) + { + lData->lres_Result = ERROR_OBJECT_WRONG_TYPE; + return uEmpty; + } + + tmi = (struct ToolMenuItem *) UserData.uda_Data; + + if (tmi) + { + stccpy(lData->lres_ResultBuffer, tmi->tmi_Cmd, sizeof(lData->lres_ResultBuffer)); + PutResult(lData, lData->lres_ResultBuffer, StemLeaf); + } + else + lData->lres_Result = ERROR_OBJECT_NOT_FOUND; + + return uEmpty; +} + + +// check if is open somewhere as an icon window +static BOOL IsIconNodeOpen(struct ScaIconNode *sIcon) +{ + struct ScaWindowStruct *swi; + BOOL Result = FALSE; + + if ((BPTR)NULL == sIcon->in_Lock) + return FALSE; + + swi = GetIconNodeOpenWindow(sIcon->in_Lock, sIcon); + + if (swi) + { + SCA_UnLockWindowList(); + Result = TRUE; + } + + return Result; +} + + +#if defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) +// Replacement for SAS/C library functions + +static size_t stccpy(char *dest, const char *src, size_t MaxLen) +{ + size_t Count = 0; + + while (*src && MaxLen > 1) + { + *dest++ = *src++; + MaxLen--; + Count++; + } + *dest = '\0'; + Count++; + + return Count; +} + +static char *strupr(char *q) +{ + while (q && *q) + { + char c = toupper(*q); + *(q++) = c; + } + + return q; +} + + +#endif /* defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) */ diff --git a/scalos/Plugins/OOP/wb39_plugin/wbrexx/RexxIcon.c b/scalos/Plugins/OOP/wb39_plugin/wbrexx/RexxIcon.c new file mode 100644 index 000000000..f2b6fc7d4 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/wbrexx/RexxIcon.c @@ -0,0 +1,442 @@ +// RexxIcon.c +// $Date$ +// $Revision$ + + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + + +#include "wbrexx.h" +#include "Scalos_Helper.h" + +// aus wb39.c +extern struct ScaRootList *rList; + +extern T_UTILITYBASE UtilityBase; +extern struct DosLibrary *DOSBase; +extern struct IntuitionBase *IntuitionBase; +extern struct GfxBase *GfxBase; +extern struct Library *LayersBase; + +struct IconListNode + { + struct MinNode iln_Node; + struct ScaIconNode *iln_IconNode; + }; + +static struct ScaIconNode *FindActiveIcon(struct ScaWindowStruct *swi); +static void OpenIcon(struct ScaWindowStruct *swi, struct ScaIconNode *sIcon); + + +#if 0 +/* +------------------------------------------------------------------------------ +ICON command + +Purpose: + +This command is for manipulating the icons displayed in a window. + +Format: + +ICON [WINDOW] .. [OPEN] [MAKEVISIBLE] +[SELECT] [UNSELECT] [UP ] [DOWN ] [LEFT ] [RIGHT +] [X ] [Y ] [ACTIVATE +UP|DOWN|LEFT|RIGHT] [CYCLE PREVIOUS|NEXT] [MOVE IN|OUT] + +Template: + +ICON WINDOW,NAMES/M,OPEN/S,MAKEVISIBLE/S,SELECT/S,UNSELECT/S, +UP/N,DOWN/N,LEFT/N,RIGHT/N,X/N,Y/N,ACTIVATE/K,CYCLE/K, MOVE/K + +Parameters: + +WINDOW + +Name of the window whose icons should be manipulated. This can be ROOT" to +work on the Workbench root window (where volume icons and AppIcons live), +ACTIVE" to work on the currently active Workbench window or the fully +qualified name of a drawer window. Note that the drawer window must already +be open. + +If no WINDOW parameter is specified, this command will try to operate on the +currently active Workbench window. + +NAMES + +Names of the icons to manipulate. + +OPEN + +Specifies that the named icons should be opened. + +MAKEVISIBLE + +Specifies that the named icons should be made visible. This generally works +well for the first icon in a list but does not always work for a whole list. + +SELECT + +Select the named icons. + +UNSELECT + +Unselect the named icons. + +UP, DOWN, LEFT, RIGHT + +Move the named icons by the specified number of pixels. + +X, Y + +Move the named icons to the specified position. + +ACTIVATE + +This command is for activating the icon closest to the currently selected +icon in the window. Activating" in this context means selecting an icon, +whilst at the same time unselecting all others". Thus, the active" icon is +the only selected icon in the window. + +You can indicate which direction the next icon to be activated should be +searched for, relative to the currently active icon. UP" searches upwards, +DOWN" searches downwards, LEFT" searches to the left and RIGHT" searches to +the right. + +CYCLE + +This command is for cycling through all icons in a window, making each one +the active one in turn (for a description of what active" means in this +context, see the ACTIVATE" description above). You must indicate in which +direction you want to cycle through the icons: you can either specify +PREVIOUS" or NEXT". + +MOVE + +This command is not for moving icons but for moving through a file system +hierarchy. Thus, moving in" will open a drawer and moving out" will open the +drawer`s parent directory. The IN" parameter will cause the drawer +represented by the active icon to be opened. Please note that an icon must be +selected and it must be a drawer. The OUT" parameter will open the drawer`s +parent directory, and it also requires that in the drawer there is an icon +selected. This may sound strange, but this feature is not meant as a +replacement for the Open Parent" menu item. + +Errors: + +10 - If the named window cannot be found, none of the Workbench windows are +currently active and the command was set to work on the currently active +Workbench window. The error code will be placed in the WORKBENCH.LASTERROR +variable. + +Result: + +- + +Example: + +* Select the icons of the Workbench" and Work" volumes * displayed in the +* root window. +ADDRESS workbench + +ICON WINDOW root +NAMES Workbench Work SELECT + +* Open the Workbench" volume icon displayed in the root * window. +ICON WINDOW root +NAMES Workbench OPEN + +------------------------------------------------------------------------------ +*/ +#endif +LONG Cmd_Icon(APTR UserData, struct RexxMsg *Message, STRPTR *Args) +{ + enum { ARG_WINDOW, ARG_NAMES, ARG_OPEN, ARG_MAKEVISIBLE, ARG_SELECT, + ARG_UNSELECT, ARG_UP, ARG_DOWN, ARG_LEFT, ARG_RIGHT, ARG_X, + ARG_Y, ARG_ACTIVATE, ARG_CYCLE, ARG_MOVE }; + LONG Result = RETURN_OK; + char *ResultString = NULL; + struct ScaWindowStruct *swi; + + d1(kprintf(__FUNC__ "/%ld: Window=<%s>\n", __LINE__, Args[ARG_WINDOW] ? Args[ARG_WINDOW] : (STRPTR) "");) + + if (Args[ARG_WINDOW]) + swi = FindWindowByName(Args[ARG_WINDOW]); + else + swi = FindWindowByName("active"); + + if (NULL == swi) + return(ERROR_OBJECT_NOT_FOUND); + + if (Args[ARG_NAMES]) + { + STRPTR *NamesPtr = (STRPTR *) Args[ARG_NAMES]; + while (*NamesPtr && RETURN_OK == Result) + { + struct ScaIconNode *sIcon; + + d(kprintf(__FUNC__ "/%ld: Name=<%s>\n", __LINE__, *NamesPtr);) + + sIcon = GetIconByName(swi, *NamesPtr); + d(kprintf(__FUNC__ "/%ld: sIcon=%08lx\n", __LINE__, sIcon);) + + if (NULL == sIcon) + return ERROR_OBJECT_NOT_FOUND; + + if (Args[ARG_OPEN]) + { + d(kprintf(__FUNC__ "/%ld: OPEN\n", __LINE__);) + + if (NULL == sIcon) + Result = ERROR_OBJECT_NOT_FOUND; + else + { + OpenIcon(swi, sIcon); + } + } + if (Args[ARG_MAKEVISIBLE]) + { + d(kprintf(__FUNC__ "/%ld: MAKEVISIBLE\n", __LINE__);) + + if (NULL == sIcon) + Result = ERROR_OBJECT_NOT_FOUND; + else + { + MakeIconVisible(swi, sIcon); + } + } + if (Args[ARG_SELECT]) + { + d(kprintf(__FUNC__ "/%ld: SELECT\n", __LINE__);) + + if (NULL == sIcon) + Result = ERROR_OBJECT_NOT_FOUND; + else + { + SelectIcon(swi, sIcon, TRUE); + } + } + if (Args[ARG_UNSELECT]) + { + d(kprintf(__FUNC__ "/%ld: UNSELECT\n", __LINE__);) + + if (NULL == sIcon) + Result = ERROR_OBJECT_NOT_FOUND; + else + { + SelectIcon(swi, sIcon, FALSE); + } + } + if (Args[ARG_X] || Args[ARG_Y] || Args[ARG_LEFT] || Args[ARG_RIGHT] || Args[ARG_UP] || Args[ARG_DOWN]) + { + // Move Icon + if (NULL == sIcon) + Result = ERROR_OBJECT_NOT_FOUND; + else + { + struct Gadget *gg = (struct Gadget *) sIcon->in_Icon; + LONG x, y; + + x = gg->LeftEdge; + y = gg->TopEdge; + + if (Args[ARG_X]) + x = *((LONG *) (Args[ARG_X])); + if (Args[ARG_Y]) + y = *((LONG *) (Args[ARG_Y])); + if (Args[ARG_RIGHT]) + x += *((LONG *) (Args[ARG_RIGHT])); + if (Args[ARG_LEFT]) + x -= *((LONG *) (Args[ARG_LEFT])); + if (Args[ARG_UP]) + y -= *((LONG *) (Args[ARG_UP])); + if (Args[ARG_DOWN]) + y += *((LONG *) (Args[ARG_DOWN])); + + MoveIcon(swi, sIcon, x, y); + } + } + + ReleaseSemaphore(swi->ws_WindowTask->wt_IconSemaphore); + + NamesPtr++; + } + } + else + { + struct ScaIconNode *sIcon = NULL; + + if (Args[ARG_ACTIVATE]) + { + d1(kprintf(__FUNC__ "/%ld: ACTIVATE\n", __LINE__);) + + sIcon = FindActiveIcon(swi); + + if (sIcon) + { + if (0 == Stricmp(Args[ARG_ACTIVATE], "UP")) + { + DoMethod(swi->ws_WindowTask->mt_MainObject, SCCM_IconWin_ActivateIconUp); + } + else if (0 == Stricmp(Args[ARG_ACTIVATE], "DOWN")) + { + DoMethod(swi->ws_WindowTask->mt_MainObject, SCCM_IconWin_ActivateIconDown); + } + else if (0 == Stricmp(Args[ARG_ACTIVATE], "LEFT")) + { + DoMethod(swi->ws_WindowTask->mt_MainObject, SCCM_IconWin_ActivateIconLeft); + } + else if (0 == Stricmp(Args[ARG_ACTIVATE], "RIGHT")) + { + DoMethod(swi->ws_WindowTask->mt_MainObject, SCCM_IconWin_ActivateIconRight); + } + else + Result = ERROR_REQUIRED_ARG_MISSING; + } + else + Result = ERROR_OBJECT_NOT_FOUND; + } + if (Args[ARG_CYCLE]) + { + d(kprintf(__FUNC__ "/%ld: CYCLE Result=%ld\n", __LINE__, Result);) + + if (0 == Stricmp(Args[ARG_CYCLE], "PREVIOUS")) + { + DoMethod(swi->ws_WindowTask->mt_MainObject, SCCM_IconWin_ActivateIconPrevious); + } + else if (0 == Stricmp(Args[ARG_CYCLE], "NEXT")) + { + DoMethod(swi->ws_WindowTask->mt_MainObject, SCCM_IconWin_ActivateIconNext); + } + else + Result = ERROR_REQUIRED_ARG_MISSING; + } + if (Args[ARG_MOVE]) + { + d1(kprintf(__FUNC__ "/%ld: MOVE\n", __LINE__);) + + sIcon = FindActiveIcon(swi); + + if (0 == Stricmp(Args[ARG_MOVE], "IN")) + { + IPTR IconType; + + d1(kprintf(__FUNC__ "/%ld: MOVE IN\n", __LINE__);) + + if (sIcon) + { + GetAttr(IDTA_Type, sIcon->in_Icon, &IconType); + + if (WBDRAWER == IconType) + OpenIcon(swi, sIcon); + else + Result = ERROR_OBJECT_WRONG_TYPE; + } + else + Result = ERROR_OBJECT_WRONG_TYPE; + } + else if (0 == Stricmp(Args[ARG_MOVE], "OUT")) + { + d1(kprintf(__FUNC__ "/%ld: MOVE IN\n", __LINE__);) + + if (sIcon) + Result = MenuOpenParentWindow(swi); + else + Result = ERROR_OBJECT_WRONG_TYPE; + } + } + + if (sIcon) + ReleaseSemaphore(swi->ws_WindowTask->wt_IconSemaphore); + } + + d(kprintf(__FUNC__ "/%ld: Result=%ld\n", __LINE__, Result);) + + if (RETURN_OK == Result) + ReturnRexxMsg(Message, ResultString); + + return Result; +} + + +// ! wt->wt_IconSemaphore WILL STAY LOCKED IF ICON FOUND ! +static struct ScaIconNode *FindActiveIcon(struct ScaWindowStruct *swi) +{ + struct ScaWindowTask *wt = swi->ws_WindowTask; + struct ScaIconNode *icon, *iconFound=NULL; + + d(kprintf(__FUNC__ "/%ld: swi=%08lx\n", __LINE__, swi);) + + ObtainSemaphore(wt->wt_IconSemaphore); + + for (icon=wt->wt_IconList; (NULL == iconFound) && icon; icon = (struct ScaIconNode *) icon->in_Node.mln_Succ) + { + struct Gadget *gg = (struct Gadget *) icon->in_Icon; + + d(kprintf(__FUNC__ "/%ld: icon=%08lx Selected=%08lx\n", __LINE__, \ + icon, gg->Flags & GFLG_SELECTED);) + + if (gg->Flags & GFLG_SELECTED) + { + iconFound = icon; + } + } + + if (NULL == iconFound) + ReleaseSemaphore(wt->wt_IconSemaphore); + + d(kprintf(__FUNC__ "/%ld: iconFound=%08lx\n", __LINE__, iconFound);) + + return iconFound; +} + + +static void OpenIcon(struct ScaWindowStruct *swi, struct ScaIconNode *sIcon) +{ + BPTR dirLock = (BPTR)NULL; + char *Name = NULL; + + if (swi->ws_Lock) + dirLock = CurrentDir(swi->ws_Lock); + + GetAttr(IDTA_Text, sIcon->in_Icon, (APTR) &Name); + + if (Name) + WaitOpen(SCA_OpenDrawerByName(Name, NULL)); + + if (dirLock) + CurrentDir(dirLock); +} + + diff --git a/scalos/Plugins/OOP/wb39_plugin/wbrexx/WBRexx.c b/scalos/Plugins/OOP/wb39_plugin/wbrexx/WBRexx.c new file mode 100644 index 000000000..7d12109c2 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/wbrexx/WBRexx.c @@ -0,0 +1,2067 @@ +// WBRexx.c +// $Date$ +// $Revision$ + +#define __USE_OLD_TIMEVAL__ 1 + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +#include "wbrexx.h" + +#ifdef __amigaos4__ +#define SetRexxVar(msg, var, val, len) SetRexxVarFromMsg((var), (val), (msg)) +#endif + +/****************************************************************************/ + +static struct RexxHost *CreateRexxHost(CONST_STRPTR, ULONG, const struct CmdFunc *, const APTR); +static VOID DeleteRexxHost(struct RexxHost * Host); +static struct RexxParseData *CreateRexxParseData(VOID); +static VOID DeleteRexxParseData(struct RexxParseData **Data); +static VOID ReturnErrorMsg(struct RexxMsg *, CONST_STRPTR, LONG); +static VOID HandleRexxMsg(const struct RexxHost *, struct RexxParseData *, struct RexxMsg *); + +static SAVEDS(void) WBRexxProcess(void); +static int WBRexxProcessInit(struct LocalData *LocalData); +static void DeleteToolMenuItem(struct ToolMenuItem *oldItem); +static STRPTR StringDup(CONST_STRPTR str); +static void DeleteKbdCommand(struct KeyboardCommand *kbc); +CONST_STRPTR CopyMenuTitle(STRPTR Dest, CONST_STRPTR Src, size_t MaxLen); +static struct ToolMenuItem *FindParentMenuItem(struct ToolMenuItem *tmi); + +/****************************************************************************/ + +// from WBRexxMain.c +extern struct DosLibrary *DOSBase; +extern T_UTILITYBASE UtilityBase; +extern struct ScalosBase *ScalosBase; +extern struct Library *CxBase; + + +// To be initialized by this module +T_REXXSYSBASE RexxSysBase; + +#ifdef __amigaos4__ +struct RexxSysIFace *IRexxSys; +#endif + +LONG LastError = RETURN_OK; // will be returned by APPLICATION.LASTERROR + +struct List MenuItemList; // list of added tool menu items + +static struct SignalSemaphore MenuItemListSemaphore; + +static struct MsgPort *ToolMenuMsgPort; // MsgPort for tool menu APPMENU messages + +struct List KbdCommandList; // list of keyboard commands + +static struct SignalSemaphore KbdCommandListSemaphore; + +static struct MsgPort *globalReplyPort; // ReplyPort for DoRexxCommand + + +CONST_STRPTR DefIconsPath = "ENV:sys/def_"; + + +/****************************************************************************/ + +/****** Host/CreateRexxHost ************************************************** +* +* NAME +* CreateRexxHost -- Create a public message port for use as an ARexx +* host address. +* +* SYNOPSIS +* Host = CreateRexxHost(BaseName,Index,CommandTable,UserData) +* +* struct RexxHost *CreateRexxHost(const STRPTR BaseName,ULONG Index, +* const struct CmdFunc *CommandTable,const APTR UserData); +* +* FUNCTION +* You supply a name and a project index, this routine will set up +* a public message port for use as an ARexx host address for you +* with the name you provided. The name will be checked for validity +* (it may not hold blank spaces or tabs) and converted to all +* upper case letters. If a non-zero project index number is provided, +* a numeric extension will be added to the message port name. +* This routine will try to make sure that the message port will bear +* a unique name. For your convenience, you can have the host data +* structure with a user data pointer. +* +* Please keep the length of the port name down to up to 20 characters, +* many users prefer short host names. This routine will reject names +* longer than 80 characters. +* +* The name is converted to all upper case characters to make it easier +* to access the host name in ARexx scripts. Lower case names require +* quoting whereas upper case names do not. +* +* INPUTS +* BaseName - Name of message port to create; the name may not +* contain blank spaces or tabs and will be converted to +* all upper case letters. The name you provide may be up to +* 80 characters long. +* +* Index - Project index number; if nonzero will cause a numeric +* extension to be added to the port name, i.e. for an index +* number of 1 the name "BASENAME" will become "BASENAME.1". +* +* CommandTable - Points to the first element of the array in +* which command names, templates and functions are stored. +* +* UserData - User data pointer which will be copied into the +* RexxHost structure. +* +* RESULT +* Host - Pointer to RexxHost created or NULL if creation failed. +* If NULL is returned you can retrieve an error code through +* dos.library/IoErr. +* +* SEE ALSO +* exec.library/AddPort +* exec.library/CreateMsgPort +* dos.library/IoErr +* +****************************************************************************** +* +*/ + +static struct RexxHost * +CreateRexxHost( + CONST_STRPTR BaseName, + ULONG Index, + const struct CmdFunc * CommandTable, + const APTR UserData) +{ + struct RexxHost * Host; + UBYTE PortName[90]; + LONG Error; + LONG Size; + LONG Len = 0; + LONG i; + + d1(kprintf(__FUNC__ "/%ld BaseName=<%s> Index=%ld\n", __LINE__, BaseName, Index);) + + /* No host created yet. */ + + Host = NULL; + + /* No error so far. */ + + Error = RETURN_OK; + + /* Check for NULL name. */ + + if(BaseName == NULL) + Error = ERROR_REQUIRED_ARG_MISSING; + + /* Check for illegal characters. */ + + if (RETURN_OK == Error) + { + Len = strlen(BaseName); + + for(i = 0 ; (Error == RETURN_OK) && (i < Len) ; i++) + { + if(BaseName[i] == ' ' || BaseName[i] == '\t') + Error = ERROR_INVALID_COMPONENT_NAME; + } + } + + /* Check the name length. */ + + if (Error == RETURN_OK) + { + if(Len > 80) + Error = ERROR_OBJECT_TOO_LARGE; + } + + /* Create the RexxHost data. */ + + if (Error == RETURN_OK) + { + /* Add the index number if provided. */ + + if(Index != 0) + sprintf((char *)PortName,"%s.%ld",BaseName,(long)Index); + else + strcpy((char *)PortName,BaseName); + + /* Convert the port name to all upper case + * characters. + */ + + for(i = 0 ; i < Len ; i++) + PortName[i] = ToUpper(PortName[i]); + + /* Allocate space for the RexxHost. The name + * requires a terminating 0-byte which is included + * in the RexxHost structure. + */ + + Size = sizeof(struct RexxHost) + strlen((char *)PortName); + + Host = (struct RexxHost *)AllocVec(Size, + MEMF_ANY|MEMF_CLEAR|MEMF_PUBLIC); + + /* Did we get the memory we wanted? */ + + if(Host == NULL) + Error = ERROR_NO_FREE_STORE; + else + { + /* Set up the message port. */ + + Host->GlobalPort = CreateMsgPort(); + + /* Did we get the port? If the creation + * failed we either ran out of free + * signal bits or memory. + */ + + if(Host->GlobalPort == NULL) + Error = ERROR_NO_FREE_STORE; + else + { + /* Fill in the host data. Since the + * port will be searched for often + * by the ARexx resident process we + * assign it a priority of 1. + */ + + strcpy((char *)Host->PortName,(char *)PortName); + + Host->GlobalPort->mp_Node.ln_Name = + (char *)Host->PortName; + + Host->GlobalPort->mp_Node.ln_Pri = 1; + + Host->CommandTable = CommandTable; + Host->UserData = UserData; + } + } + } + + /* Try to add the message port. */ + + if (Error == RETURN_OK) + { + /* We need to turn off multitasking for a moment + * while we access the global message port list. + */ + + Forbid(); + + /* Check if there already is a message port by + * the name we just used. + */ + + if(FindPort((CONST_STRPTR)Host->PortName)) + Error = ERROR_OBJECT_EXISTS; + + /* If there is no such port yet, add the new + * message port to the public list. + */ + + if (Error == RETURN_OK) + AddPort(Host->GlobalPort); + + /* Enable multitasking again. */ + + Permit(); + } + + d1(kprintf(__FUNC__ "/%ld Host=%08lx\n", __LINE__, Host);) + + /* Did we succeed? */ + + if (Error == RETURN_OK) + return(Host); + else + { + /* Clean up the host data. */ + + d1(kprintf(__FUNC__ "/%ld Host=%08lx\n", __LINE__, Host);) + + if (Host != NULL) + { + /* Delete the message port. This call + * will succeed even if the pointer is + * NULL. + */ + + DeleteMsgPort(Host->GlobalPort); + + /* Free the memory allocated for the + * host data. + */ + + FreeVec(Host); + } + + d1(kprintf(__FUNC__ "/%ld Host=%08lx\n", __LINE__, Host);) + + /* Return failure. */ + + return(NULL); + } +} + +/****** Host/DeleteRexxHost ************************************************** +* +* NAME +* DeleteRexxHost -- Remove a rexx host port previously created by +* CreateRexxHost. +* +* SYNOPSIS +* DeleteRexxHost(Host) +* +* VOID DeleteRexxHost(struct RexxHost *); +* +* FUNCTION +* Before your application exits, call this routine on every rexx host +* environment you created with CreateRexxHost(). If you forget to do so +* your application will leave unused memory and, in case it was +* run from Shell, signal bits allocated which can never be reclaimed. +* +* INPUTS +* Host - Result of CreateRexxHost() call. May be NULL in which case +* this routine will do nothing. +* +* RESULT +* None +* +* SEE ALSO +* exec.library/DeleteMsgPort +* exec.library/RemPort +* CreateRexxHost +* +****************************************************************************** +* +*/ + +static VOID DeleteRexxHost(struct RexxHost * Host) +{ + /* Did we get a valid host pointer? */ + + d1(kprintf(__FUNC__ "/%ld Host=%08lx\n", __LINE__, Host);) + + if (Host != NULL) + { + d1(kprintf(__FUNC__ "/%ld GlobalPort=%08lx\n", __LINE__, Host->GlobalPort);) + + if (Host->GlobalPort) + { + struct RexxMsg * Message; + + /* Turn off multitasking while we remove the + * public message port. + */ + + Forbid(); + + /* Remove the message port. */ + + RemPort(Host->GlobalPort); + + /* Now enable multitasking again. */ + + Permit(); + + /* Remove all pending rexx messages from the + * port and reply them to their owners. + */ + + while((Message = (struct RexxMsg *)GetMsg(Host->GlobalPort)) + != NULL) + { + /* Reject all messages. */ + + Message->rm_Result1 = RC_FATAL; + + ReplyMsg((struct Message *)Message); + } + + /* Delete the message port. */ + + DeleteMsgPort(Host->GlobalPort); + } + + /* Free the memory allocated. */ + + FreeVec(Host); + } +} + +/****************************************************************************/ + +/****** Host/CreateRexxParseData ********************************************* +* +* NAME +* CreateRexxParseData -- Create working data for command parsing. +* +* SYNOPSIS +* Data = CreateRexxParseData() +* +* struct RexxParseData *CreateRexxParseData(VOID); +* +* FUNCTION +* The commands the host receives from the Rexx resident process will +* need further processing. This is what the command parser will do, +* but it needs environment data to work with. This routine allocates +* the work space it needs. +* +* INPUTS +* None +* +* RESULT +* Data - Pointer to RexxParseData structure or NULL if it could not +* be allocated. If NULL is returned the error code can be +* obtained through IoErr(). +* +* SEE ALSO +* dos.library/AllocDosObject +* dos.library/IoErr +* +****************************************************************************** +* +*/ + +static struct RexxParseData *CreateRexxParseData(VOID) +{ + struct Process * ThisProcess; + struct RexxParseData * Data; + LONG Error; + + /* No error has occured yet. */ + Error = RETURN_OK; + + /* Allocate the basic parser data. */ + + Data = AllocVec(sizeof(struct RexxParseData),MEMF_ANY|MEMF_CLEAR); + + /* Did we get the memory? */ + + if(Data == NULL) + Error = ERROR_NO_FREE_STORE; + + /* Allocate the ReadArgs data. */ + + if(Error == RETURN_OK) + { + /* AllocDosObjectTagList is a dos.library call which + * can be made by a Task. + */ + + Data->ReadArgs = AllocDosObjectTagList(DOS_RDARGS,NULL); + + /* Did we get the data? */ + + if(Data->ReadArgs == NULL) + Error = ERROR_NO_FREE_STORE; + } + + /* Did we succeed? */ + + if(Error == RETURN_OK) + return(Data); + else + { + /* Clean up the parser data; in this case failure + * means either the ReadArgs data or the data + * structure itself could not be allocated. Thus, + * we only need to take care of the data, a single + * call to FreeVec() is sufficient. Since FreeVec() + * can be called with a NULL parameter we do not + * need to check if the data pointer is valid. + */ + + FreeVec(Data); + + /* Obtain the control structure for this Process + * or Task. We need to set an error code, but the + * system call we will make can only be made by + * a Process. + */ + + ThisProcess = (struct Process *)FindTask(NULL); + + /* If a process is making the call, set the + * error code so it can later be retrieved + * through IoErr(). + */ + + if(ThisProcess->pr_Task.tc_Node.ln_Type == NT_PROCESS) + SetIoErr(Error); + + /* Return failure. */ + + return(NULL); + } +} + +/****** Host/DeleteRexxParseData ********************************************* +* +* NAME +* DeleteRexxParseData -- Free data allocated by CreateRexxParseData. +* +* SYNOPSIS +* DeleteRexxParseData(Data) +* +* VOID DeleteRexxParseData(struct RexxParseData **); +* +* FUNCTION +* Before your program exits it should call this routine to release +* all the memory allocated for command parsing. Otherwise it will lose +* memory that can never be reclaimed. +* +* INPUTS +* Data - Pointer to RexxParseData structure created by +* CreateRexxParseData. May be NULL in which case this routine +* does nothing. +* +* RESULT +* None +* +* SEE ALSO +* dos.library/FreeDosObject +* +****************************************************************************** +* +*/ + +static VOID DeleteRexxParseData(struct RexxParseData **Data) +{ + /* Did we get a valid data pointer? */ + + d1(kprintf(__FUNC__ "/%ld *Data=%08lx\n", __LINE__, *Data);) + + if (*Data != NULL) + { + /* Clean up the parser data. */ + + d1(kprintf(__FUNC__ "/%ld ReadArgs=%08lx\n", __LINE__, (*Data)->ReadArgs);) + + if ((*Data)->ReadArgs != NULL) + { + FreeDosObject(DOS_RDARGS, (*Data)->ReadArgs); + (*Data)->ReadArgs = NULL; + } + + /* Free the memory. */ + + FreeVec(*Data); + *Data = NULL; + } +} + +/****** Host/ReturnRexxMsg *************************************************** +* +* NAME +* ReturnRexxMsg -- Return a Rexx command message to the sender, +* including a result code. +* +* SYNOPSIS +* ErrorCode = ReturnRexxMsg(Message,Result) +* +* LONG ReturnRexxMsg(struct RexxMsg *Message,CONST_STRPTR Result); +* +* FUNCTION +* Clients addressing the host send special messages carrying the +* commands and command arguments to the host message port. After +* processing the commands the host needs to return these messages. +* +* This routine cannot be used to return error or failure messages +* to the client. For this purpose use ReturnErrorMsg() instead. +* +* INPUTS +* Message - Pointer to RexxMsg received from client. +* +* Result - Pointer to string that should be transmitted to +* the client as the command result. This may be NULL in +* which case no result string will be transmitted. +* +* RESULT +* Error - 0 for success, any other value indicates failure. +* +* SEE ALSO +* exec.library/ReplyMsg +* rexxsyslib.library/CreateArgstring +* ReturnErrorMsg +* +****************************************************************************** +* +*/ + +LONG ReturnRexxMsg(struct RexxMsg * Message,CONST_STRPTR Result) +{ + STRPTR ResultString; + LONG ErrorCode; + + /* No error has occured yet. */ + + ErrorCode = 0; + + /* Set up the RexxMsg to return no error. */ + + Message->rm_Result1 = RC_OK; + Message->rm_Result2 = 0; + + /* Check if the command should return a result. */ + + if((Message->rm_Action & RXFF_RESULT) && Result != NULL) + { + /* To return the result string we need to make + * a copy for ARexx to use. + */ + + if(ResultString = CreateArgstring((STRPTR) Result,strlen(Result))) + { + /* Put the string into the secondary + * result field. + */ + + Message->rm_Result2 = (LONG)ResultString; + } + else + { + /* No memory available. */ + + ErrorCode = ERR10_003; + } + } + + /* Reply the message, regardless of the error code. */ + + ReplyMsg((struct Message *)Message); + + return(ErrorCode); +} + +/****** Host/ReturnErrorMsg ************************************************** +* +* NAME +* ReturnErrorMsg -- Return a Rexx command message to the sender and +* indicate that the command failed. +* +* SYNOPSIS +* ReturnErrorMsg(Message,PortName,Error) +* +* VOID ReturnErrorMsg(struct RexxMsg *Message,CONST_STRPTR PortName, +* LONG Error) +* +* FUNCTION +* This routine permits to return a command message sent by a client +* and set an error code the client to send the message can query. +* The error code is stored in a variable whose name is made up from +* the name of the host name and the prefix ".LASTERROR". Thus, +* for the host name "HOST" the variable becomes "HOST.LASTERROR". +* +* INPUTS +* Message - Pointer to RexxMsg received from client. +* +* PortName - Name of the host the message was sent to. +* +* Error - Error code to return. +* +* RESULT +* None +* +* SEE ALSO +* exec.library/ReplyMsg +* amiga.lib/SetRexxVar +* +****************************************************************************** +* +*/ + +static VOID ReturnErrorMsg( + struct RexxMsg * Message, + CONST_STRPTR PortName, + LONG Error) +{ + BYTE Value[12]; + + /* To signal an error the rc_Result1 + * entry of the RexxMsg needs to be set to + * RC_ERROR. Unfortunately, we cannot convey + * the more meaningful error code through + * this interface which is why we set a + * Rexx variable to the error number. The + * Rexx script can then take a look at this + * variable and decide which further steps + * it should take. + */ + + Message->rm_Result1 = RC_ERROR; + + /* Turn the error number into a string as + * ARexx only deals with strings. + */ + + sprintf((char *)Value,"%ld",(long)Error); + + /* Now set the variable to the error code. + * We use the RVI (Rexx Variables Interface) + * routine for this purpose. + */ + + SetRexxVar(Message, "WORKBENCH.LASTERROR", (STRPTR)Value, strlen(Value)); + + ReplyMsg((struct Message *)Message); +} + +/****** Host/HandleRexxMsg *************************************************** +* +* NAME +* HandleRexxMsg -- Process incoming rexx message and invoke the +* apropriate function handler. +* +* SYNOPSIS +* HandleRexxMsg(Host,Data,Message) +* +* VOID HandleRexxMsg(const struct RexxHost *Host, +* struct RexxParseData *Data,struct RexxMsg *Message); +* +* FUNCTION +* This routine prepares the ground for the final command execution. +* It tries to find the command the Rexx message should invoke and +* parses the command arguments. If a matching command could be found +* and the arguments are correct the corresponding function is invoked. +* When control has passed through this routine the Rexx message will +* have been replied. +* +* INPUTS +* Host - ARexx Host environment as created by CreateRexxHost +* +* Data - Parser data as created by CreateParseData +* +* Message - Pointer to RexxMsg received from client. +* +* NOTES +* This routine should only be called by a Process. +* +* RESULT +* None +* +* SEE ALSO +* dos.library/ReadArgs +* CreateParseData +* CreateRexxHost +* +****************************************************************************** +* +*/ + +static VOID HandleRexxMsg( + const struct RexxHost * Host, + struct RexxParseData * Data, + struct RexxMsg * Message) +{ + const struct CmdFunc * Table; + const struct CmdFunc * CmdFunc; + STRPTR Command; + STRPTR Arguments; + LONG Error; + LONG Len; + LONG i; + + /* This is where the entire command string is stored, + * including following arguments. + */ + + Command = (STRPTR)Message->rm_Args[0]; + + /* Skip leading blanks. */ + + while(*Command == ' ' || *Command == '\t') + Command++; + + /* Now determine the length of the command. */ + + Len = 0; + + while (Command[Len]) + { + if(Command[Len] == '\t' || Command[Len] == ' ') + break; + else + Len++; + } + + /* Now we need to check if the command we received + * can be handled by one of the routines in the + * command table. + */ + + Table = Host->CommandTable; + CmdFunc = NULL; + + d1(kprintf(__FUNC__ "/%ld: cmd=<%s>\n", __LINE__, Command);) + + for(i = 0 ; Table[i].CommandName != NULL ; i++) + { + if((strlen(Table[i].CommandName) == Len) && (Strnicmp(Command,Table[i].CommandName,Len) == 0)) + { + CmdFunc = &Table[i]; + break; + } + } + + d1(kprintf(__FUNC__ "/%ld: CmdFunc=%08lx\n", __LINE__, CmdFunc);) + + /* If no matching command could be found, return + * an error. + */ + + if(CmdFunc == NULL) + LastError = Error = ERROR_OBJECT_NOT_FOUND; + else + { + /* Reset the argument pointers. */ + + memset(Data->Args,0,sizeof(Data->Args)); + + /* Separate the arguments from the command; + * first skip the leading blanks. + */ + + Arguments = &Command[Len]; + + while(*Arguments == '\t' || *Arguments == ' ') + Arguments++; + + /* Remove trailing blanks. */ + + Len = strlen(Arguments); + + while((Len > 0) && + (Arguments[Len - 1] == '\t' || Arguments[Len - 1] == ' ')) + Len--; + + /* We only allow for 510 characters of argument data. */ + + if(Len > 510) + Len = 510; + + /* Put the arguments into the parser buffer. */ + + if(Len > 0) + CopyMem(Arguments,Data->Line,Len); + + /* Add the line feed and the null-termination. */ + + Data->Line[Len] = '\n'; + Data->Line[Len+1] = 0; + + /* Set up the parser to read from the argument buffer. */ + + Data->ReadArgs->RDA_Source.CS_Buffer = (STRPTR)Data->Line; + Data->ReadArgs->RDA_Source.CS_Length = Len + 1; + Data->ReadArgs->RDA_Source.CS_CurChr = 0; + Data->ReadArgs->RDA_Flags |= RDAF_NOPROMPT; + + /* Run the arguments through the parser. This will + * set up the Data->Args array. + */ + + if(ReadArgs(CmdFunc->Template,(IPTR *)Data->Args,Data->ReadArgs)) + { + /* Invoke the command. */ + + Error = (*CmdFunc->Function)(Host->UserData,Message,Data->Args); + if (RETURN_OK != Error) + LastError = Error; + + d1(kprintf(__FUNC__ "/%ld: LastError=%ld Error=%ld\n", __LINE__, LastError, Error);) + + /* Free the parser data. */ + + FreeArgs(Data->ReadArgs); + } + else + LastError = Error = IoErr(); + } + + /* If an error occured, return the message now. + * In any other case the command handler will have + * taken care of it already. + */ + + if (Error) + ReturnErrorMsg(Message, (STRPTR) Host->PortName,Error); +} + +/****************************************************************************/ + + /* The following routines implement the 15 mandatory ARexx commands + * every ARexx host should support, as per the "Amiga User Interface + * Style Guide". With the exception of the FAULT, HELP, QUIT and RX + * commands none of the example commands do any real work. They just + * print their arguments and return an error code. + * + * Every routine is invoked with three parameters: + * + * UserData -- The user data pointer passed to CreateRexxHost. + * + * Message -- Pointer to the RexxMsg received from the client. + * + * Args -- Pointer to an array of 32 string pointers, as set up + * by the dos.library/ReadArgs parser. + * + * Each routine has to return an error code. If the code returned + * is nonzero the command dispatcher in HandleRexxMsg() will + * reply the RexxMsg. If the code is zero, the routine is + * responsible for replying the RexxMsg. + */ + +/****** Host/DoRexxCommand *************************************************** +* +* NAME +* DoRexxCommand -- Send a command to the Rexx resident process. +* +* SYNOPSIS +* Error = DoRexxCommand(Command) +* +* LONG DoRexxCommand(CONST_STRPTR Command); +* +* FUNCTION +* A command is sent to the Rexx resident process. In this context +* "command" either means the name of an ARexx script the resident +* process is to load and execute or a small one-line program. +* +* INPUTS +* Command - Name of command to execute. +* +* RESULT +* Error - 0 for success, otherwise an error code. +* +* SEE ALSO +* rexxsyslib.library/CreateArgstring +* rexxsyslib.library/DeleteArgstring +* rexxsyslib.library/CreateRexxMsg +* rexxsyslib.library/DeleteRexxMsg +* exec.library/CreateMsgPort +* exec.library/DeleteMsgPort +* exec.library/FindPort +* exec.library/PutMsg +* exec.library/WaitPort +* +****************************************************************************** +* +*/ + +LONG DoRexxCommand(CONST_STRPTR Command) +{ + struct RexxMsg *RexxMsg; + LONG Error; + + do { + struct MsgPort *RexxPort; + static CONST_STRPTR ConsoleName = "CON:0/11//189/WBRexx Output Window/AUTO/WAIT"; + + /* Build a RexxMsg we can use. */ + RexxMsg = CreateRexxMsg(globalReplyPort,"WB","WORKBENCH"); + if (NULL == RexxMsg) + { + Error = ERROR_NO_FREE_STORE; + break; + } + + /* The command goes into the first + * message argument. + */ + RexxMsg->rm_Args[0] = CreateArgstring((STRPTR) Command,strlen(Command)); + if (0 == RexxMsg->rm_Args[0]) + { + Error = ERROR_NO_FREE_STORE; + break; + } + + /* Mark the message as a command. */ + RexxMsg->rm_Action = RXCOMM; + + RexxMsg->rm_Stdin = Open("NIL:", MODE_OLDFILE); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: stdin=%08lx\n", __LINE__, RexxMsg->rm_Stdin)); + if ((BPTR)NULL == RexxMsg->rm_Stdin) + { + Error = IoErr(); + break; + } + + RexxMsg->rm_Stdout = Open((STRPTR) ConsoleName, MODE_NEWFILE); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: stdout=%08lx\n", __LINE__, RexxMsg->rm_Stdout)); + if ((BPTR)NULL == RexxMsg->rm_Stdout) + { + Error = IoErr(); + break; + } + + /* Now try to find the resident process + * communications port. We need to + * turn off multitasking while we look + * for it and send the message. + */ + + Forbid(); + + if (RexxPort = FindPort(RXSDIR)) + { + PutMsg(RexxPort, &RexxMsg->rm_Node); + + Error = RETURN_OK; + RexxMsg = NULL; + } + else + Error = ERROR_OBJECT_NOT_FOUND; + + Permit(); + } while (0); + + if (RexxMsg) + { + if (RexxMsg->rm_Stdin) + Close(RexxMsg->rm_Stdin); + if (RexxMsg->rm_Stdout) + Close(RexxMsg->rm_Stdout); + + ClearRexxMsg(RexxMsg, 16); + + DeleteRexxMsg(RexxMsg); + } + + return(Error); +} + + /* RxEntry(VOID): + * + * This is the entry point of a process that will get launched + * if the RX command is invoked with the "CONSOLE" parameter. + */ + +SAVEDS(VOID) RxEntry(VOID) +{ + struct Process *ThisProcess; + BPTR Stream; + struct ChildMessage *ChildMessage; + struct RexxMsg *SyncMsg; + LONG Error; + + /* Obtain current process identifier. */ + + ThisProcess = (struct Process *)FindTask(NULL); + + /* Pick up the startup message. */ + + WaitPort(&ThisProcess->pr_MsgPort); + ChildMessage = (struct ChildMessage *)GetMsg(&ThisProcess->pr_MsgPort); + + /* Remember the RexxMsg if any. If nonzero, the RX command + * was invoked without the ASYNC parameter and the message + * still need to be replied. + */ + + SyncMsg = ChildMessage->RexxMsg; + + /* Redirect process output to the console window. */ + + if(Stream = Open("CONSOLE:",MODE_NEWFILE)) + { + SelectOutput(Stream); + + /* Send the command to the Rexx process. */ + + Error = DoRexxCommand((CONST_STRPTR)ChildMessage->Command); + + /* Close the output stream. */ + + SelectOutput((BPTR)NULL); + Close(Stream); + } + else + Error = IoErr(); + + /* Do we need to reply the RexxMsg? */ + + if(SyncMsg) + { + if(Error) + ReturnErrorMsg(SyncMsg,ChildMessage->PortName,Error); + else + ReturnRexxMsg(SyncMsg,0); + } + + ReplyMsg((struct Message *) ChildMessage); +} + + +/* DeleteChildMessage(struct ChildMessage *ChildMessage): + * + * Dispose of a message created by CreateChildMessage(). + */ +VOID DeleteChildMessage(struct ChildMessage *ChildMessage) +{ + FreeMem(ChildMessage,ChildMessage->Message.mn_Length); +} + + +/* CreateChildMessage(): + * + * This routine sets up a custom message to send to a + * child process which gets launched if the RX command + * is invoked with the CONSOLE keyword. + */ +struct ChildMessage *CreateChildMessage(struct MsgPort *ReplyPort,CONST_STRPTR Command,struct RexxMsg *RexxMessage) +{ + UWORD Length; + struct ChildMessage *ChildMessage; + + /* Make room for the message plus the command string. */ + + Length = sizeof(struct ChildMessage) + strlen(Command); + + ChildMessage = (struct ChildMessage *)AllocMem(Length,MEMF_CLEAR|MEMF_PUBLIC); + + if(ChildMessage != NULL) + { + /* Initialize the message. */ + + ChildMessage->Message.mn_Length = Length; + ChildMessage->Message.mn_ReplyPort = ReplyPort; + + strcpy((char *)ChildMessage->Command,Command); + } + + return(ChildMessage); +} + +/****************************************************************************/ + + /* This is the table which lists the single commands this ARexx + * host implements. Each entry lists the name of the command to + * invoke, the argument template and the pointer to the routine + * which implements the command. The table is terminated by a + * NULL command name. + */ + +struct CmdFunc CommandTable[] = +{ + { "ACTIVATEWINDOW", "WINDOW", Cmd_ActivateWindow }, + { "CHANGEWINDOW", "WINDOW,LEFTEDGE/N,TOPEDGE/N,WIDTH/N,HEIGHT/N", Cmd_ChangeWindow }, + { "DELETE", "NAME/A,ALL/S", Cmd_Delete }, + { "FAULT", "CODE/A/N", Cmd_Fault }, + { "GETATTR", "OBJECT/A,NAME/K,STEM/K,VAR/K", Cmd_GetAttr }, + { "HELP", "COMMAND/K,MENUS/S,PROMPT/S", Cmd_Help }, + { "ICON", "WINDOW,NAMES/M,OPEN/S,MAKEVISIBLE/S," + "SELECT/S,UNSELECT/S,UP/N,DOWN/N,LEFT/N," + "RIGHT/N,X/N,Y/N,ACTIVATE/K,CYCLE/K,MOVE/K", Cmd_Icon }, + { "INFO", "NAME/A", Cmd_Info }, + { "KEYBOARD", "NAME/A,ADD/S,REMOVE/S,KEY,CMD/F", Cmd_Keyboard }, + { "LOCKGUI", "", Cmd_LockGUI }, + { "MENU", "WINDOW/K,INVOKE,NAME/K,TITLE/K," + "SHORTCUT/K,ADD/S,REMOVE/S,CMD/K/F", Cmd_Menu }, + { "MOVEWINDOW", "WINDOW,LEFTEDGE/N,TOPEDGE/N", Cmd_MoveWindow }, + { "NEWDRAWER", "NAME/A", Cmd_NewDrawer }, + { "RENAME", "OLDNAME/A,NEWNAME/A", Cmd_Rename }, + { "RX", "CONSOLE/S,ASYNC/S,CMD/A/F", Cmd_Rx }, + { "SIZEWINDOW", "WINDOW,WIDTH/N,HEIGHT/N", Cmd_SizeWindow }, + { "UNLOCKGUI", "", Cmd_UnlockGUI }, + { "UNZOOMWINDOW", "WINDOW", Cmd_UnzoomWindow }, + { "VIEW", "WINDOW,PAGE/S,PIXEL/S,UP/S,DOWN/S," + "LEFT/S,RIGHT/S", Cmd_View }, + { "WINDOW", "WINDOWS/A/M,OPEN/S,CLOSE/S,SNAPSHOT/S," + "ACTIVATE/S,MIN/S,MAX/S,FRONT/S," + "BACK/S,CYCLE/K", Cmd_Window }, + { "WINDOWTOBACK", "WINDOW", Cmd_WindowToBack }, + { "WINDOWTOFRONT", "WINDOW", Cmd_WindowToFront }, + { "ZOOMWINDOW", "WINDOW", Cmd_ZoomWindow }, + + { NULL, NULL, NULL } +}; + + + +/* ====================================================== */ + +static struct Task *HandshakeTask = NULL; +static ULONG HandshakeSignal = -1; +static struct Process *WBRexxProc = NULL; // the Rexx Handler Process +struct MsgPort *WBRexxPort = NULL; +static BOOL WBRexxProcessRunning = FALSE; + + +BOOL StartWBRexxProcess(void) +{ + ULONG EmulationMode = TRUE; + + NewList(&MenuItemList); + NewList(&KbdCommandList); + + InitSemaphore(&MenuItemListSemaphore); + InitSemaphore(&KbdCommandListSemaphore); + + if (ScalosBase->scb_LibNode.lib_Version >= 40) + { + SCA_ScalosControl(NULL, + SCALOSCTRLA_GetEmulationMode, (ULONG) &EmulationMode, + TAG_END); + } + + if (EmulationMode) + { + STATIC_PATCHFUNC(WBRexxProcess); + + HandshakeTask = FindTask(NULL); + + HandshakeSignal = AllocSignal(-1); + if (-1 == HandshakeSignal) + { +// alarm("AllocSignal() failed"); + return FALSE; + } + + WBRexxProc = CreateNewProcTags(NP_Name, (ULONG) "WB39 Rexx Handler", + NP_Priority, 0, + NP_Entry, (ULONG) PATCH_NEWFUNC(WBRexxProcess), + NP_StackSize, 16384, + TAG_END); + if (WBRexxProc == NULL) + { +// alarm("TNC_INit: CreateProc() failed"); + return FALSE; + } + + Wait(1 << HandshakeSignal); /* Warten auf Ergebnis */ + + FreeSignal(HandshakeSignal); + HandshakeSignal = -1; + + if (!WBRexxProcessRunning) + WBRexxProc = NULL; + + return WBRexxProcessRunning; + } + + return TRUE; +} + + +void ShutdownWBRexxProcess(void) +{ + if (NULL == WBRexxProc) + return; + + HandshakeTask = FindTask(NULL); + HandshakeSignal = AllocSignal(-1); + if (-1 == HandshakeSignal) + { +// alarm("AllocSignal() failed"); + return; + } + + WBRexxProcessRunning = FALSE; + + Signal(&WBRexxProc->pr_Task, SIGBREAKF_CTRL_C); // Signal WBRexxProc to terminate + + Wait(1 << HandshakeSignal); /* Warten auf Ergebnis */ + + FreeSignal(HandshakeSignal); + HandshakeSignal = -1; + + WBRexxProc = NULL; +} + + +/* ====================================================== */ + +static SAVEDS(void) WBRexxProcess(void) +{ + struct LocalData LocalData; + + d1(kprintf(__FUNC__ "/%ld Start WBRexx Process\n", __LINE__);) + + memset(&LocalData, 0, sizeof(LocalData)); + + if (RETURN_OK == WBRexxProcessInit(&LocalData)) + { + ULONG GlobalPortMask = 1L << LocalData.Host->GlobalPort->mp_SigBit; + ULONG ToolMenuPortMask = 1L << ToolMenuMsgPort->mp_SigBit; + ULONG ReplyPortMask = 1L << globalReplyPort->mp_SigBit; + + WBRexxProcessRunning = TRUE; + + if (HandshakeSignal != -1) + Signal(HandshakeTask, 1 << HandshakeSignal); + + /* Set up the local data. This must be done + * before the first Rexx command is processed. + */ + + LocalData.CommandTable = CommandTable; + LocalData.Usage = 0; + LocalData.GlobalPort = LocalData.Host->GlobalPort; + LocalData.PortName = (STRPTR)LocalData.Host->PortName; + LocalData.Terminate = FALSE; + + d1(kprintf(__FUNC__ "/%ld Ok Hostname=<%s>\n", __LINE__, LocalData.Host->PortName);) +// Printf("Host name is \"%s\", waiting for commands.\n", LocalData.Host->PortName); + + /* Loop until either the QUIT command is executed or + * Ctrl-C is pressed. + */ + + do + { + ULONG Signals; + /* Wait for Ctrl-C or an incoming Message. */ + + Signals = Wait(SIGBREAKF_CTRL_C | GlobalPortMask | ToolMenuPortMask | ReplyPortMask); + + /* Ctrl-C signal received? */ + if(Signals & SIGBREAKF_CTRL_C) + LocalData.Terminate = TRUE; + + /* Message received? */ + if(Signals & GlobalPortMask) + { + struct RexxMsg * RexxMessage; + /* Process all incoming messages. */ + + while((RexxMessage = (struct RexxMsg *)GetMsg(LocalData.Host->GlobalPort)) != NULL) + { + /* If the incoming message is indeed + * a RexxMsg, process the command + */ + + if(IsRexxMsg(RexxMessage)) + HandleRexxMsg(LocalData.Host, LocalData.ParseData, RexxMessage); + else + { + /* Otherwise it is a startup message + * sent to a background process. We + * need to delete this message and + * decrement the number of outstanding + * startup messages. + */ + + DeleteChildMessage((struct ChildMessage *)RexxMessage); + + LocalData.Usage--; + } + } + } + if (Signals & ToolMenuPortMask) + { + struct AppMessage *aMsg; + + while (aMsg = (struct AppMessage *)GetMsg(ToolMenuMsgPort)) + { + struct ToolMenuItem *tmItem; + + d1(kprintf(__FUNC__ "/%ld Msg=%08lx Type=%ld ID=%08lx UserData=%08lx\n", \ + __LINE__, aMsg, aMsg->am_Type, aMsg->am_ID, aMsg->am_UserData);) + + tmItem = (struct ToolMenuItem *) aMsg->am_UserData; + + d1(kprintf(__FUNC__ "/%ld Cmd=<%s>\n", __LINE__, tmItem->tmi_Cmd);) + + // execute command string + if (tmItem->tmi_Cmd) + DoRexxCommand(tmItem->tmi_Cmd); + + ReplyMsg(&aMsg->am_Message); + } + } + if (Signals & ReplyPortMask) + { + struct RexxMsg *rMsg; + + while (rMsg = (struct RexxMsg *)GetMsg(globalReplyPort)) + { + ClearRexxMsg(rMsg, 1); + + if (rMsg->rm_Stdin) + Close(rMsg->rm_Stdin); + + if (rMsg->rm_Stdout && RETURN_OK == rMsg->rm_Result1) + { + // only close Stdout if no error ! + Close(rMsg->rm_Stdout); + } + + DeleteRexxMsg(rMsg); + } + } + + /* The loop will be terminated when the "Terminate" flag changes + * to TRUE and no further startup messages are outstanding. + */ + } + + while(LocalData.Usage > 0 || LocalData.Terminate == FALSE); + } + + d1(kprintf(__FUNC__ "/%ld \n", __LINE__);) + + DeleteRexxHost(LocalData.Host); + + d1(kprintf(__FUNC__ "/%ld \n", __LINE__);) + + DeleteRexxParseData(&LocalData.ParseData); + +#ifdef __amigaos4__ + if (IRexxSys) + { + DropInterface((struct Interface *)IRexxSys); + IRexxSys = NULL; + } +#endif + if (RexxSysBase) + { + CloseLibrary((struct Library *) RexxSysBase); + RexxSysBase = NULL; + } + + if (ToolMenuMsgPort) + { + DeleteMsgPort(ToolMenuMsgPort); + ToolMenuMsgPort = NULL; + } + if (globalReplyPort) + { + DeleteMsgPort(globalReplyPort); + globalReplyPort = NULL; + } + + d1(kprintf(__FUNC__ "/%ld \n", __LINE__);) + + WBRexxProcessRunning = FALSE; + + Forbid(); + if (HandshakeSignal != -1) + Signal(HandshakeTask, 1 << HandshakeSignal); +} + + +static int WBRexxProcessInit(struct LocalData *LocalData) +{ + struct Process *myProc = (struct Process *) FindTask(NULL); + + /* Open the rexx system library. */ + RexxSysBase = (T_REXXSYSBASE) OpenLibrary(RXSNAME,0); + + myProc->pr_WindowPtr = NULL; + + ToolMenuMsgPort = CreateMsgPort(); + if (NULL == ToolMenuMsgPort) + { +// Printf("Could not create tool menu msgport\n"); + + return(RETURN_FAIL); + } + + globalReplyPort = CreateMsgPort(); + if (NULL == globalReplyPort) + { +// Printf("Could not create global reply msgport\n"); + + return(RETURN_FAIL); + } + + d1(kprintf(__FUNC__ "/%ld RexxSysBase=%08lx\n", __LINE__, RexxSysBase);) + if (RexxSysBase == NULL) + { +// Printf("Could not open %s.\n",RXSNAME); + + return(RETURN_FAIL); + } +#ifdef __amigaos4__ + IRexxSys = (struct RexxSysIFace *)GetInterface((struct Library *)RexxSysBase, "main", 1, NULL); + if (NULL == IRexxSys) + { +// Printf("Could not get RexxSys' OS4 Interface"); + + return(RETURN_FAIL); + } +#endif + + /* Create the command parser data. */ + + LocalData->ParseData = CreateRexxParseData(); + + d1(kprintf(__FUNC__ "/%ld ParseData=%08lx\n", __LINE__, LocalData->ParseData);) + if (LocalData->ParseData == NULL) + { +// Printf("Error creating rexx parse data.\n"); + +#ifdef __amigaos4__ + DropInterface((struct Interface *)IRexxSys); + IRexxSys = NULL; +#endif + CloseLibrary((struct Library *) RexxSysBase); + RexxSysBase = NULL; + + return(RETURN_FAIL); + } + + /* Finally create the Rexx host. */ + + LocalData->Host = CreateRexxHost("WORKBENCH", 0, CommandTable,LocalData); + + d1(kprintf(__FUNC__ "/%ld Host=%08lx\n", __LINE__, LocalData->Host);) + if (LocalData->Host == NULL) + { +// Printf("Error creating rexx host.\n"); + + DeleteRexxParseData(&LocalData->ParseData); + +#ifdef __amigaos4__ + DropInterface((struct Interface *)IRexxSys); + IRexxSys = NULL; +#endif + CloseLibrary((struct Library *) RexxSysBase); + RexxSysBase = NULL; + + return(RETURN_FAIL); + } + + return RETURN_OK; +} + + +// Split Argument into "."-delimited parts +CONST_STRPTR GetNextArgPart(CONST_STRPTR ArgSrc, STRPTR Buffer, size_t MaxLen) +{ + if ('.' == *ArgSrc) + ArgSrc++; + + while (MaxLen > 1 && *ArgSrc && '.' != *ArgSrc) + { + *Buffer++ = *ArgSrc++; + MaxLen--; + } + *Buffer = '\0'; + + return ArgSrc; +} + + +ULONG AddMenuItem(CONST_STRPTR Name, CONST_STRPTR Title, CONST_STRPTR Cmd, CONST_STRPTR Shortcut) +{ + ULONG Result = RETURN_OK; + struct ToolMenuItem *tmi; + size_t len; + + d1(kprintf(__FUNC__ "/%ld: Name=<%s> Title=<%s> Cmd=<%s> Shortcut=<%s>\n", \ + __LINE__, Name, Title, Cmd, Shortcut);) + + ObtainSemaphore(&MenuItemListSemaphore); + + do { + for (tmi = (struct ToolMenuItem *) MenuItemList.lh_Head; + tmi != (struct ToolMenuItem *) &MenuItemList.lh_Tail; + tmi = (struct ToolMenuItem *) tmi->tmi_Node.ln_Succ) + { + if (0 == Stricmp((STRPTR) Name, tmi->tmi_Name)) + { + d1(kprintf(__FUNC__ "/%ld: ERROR_OBJECT_EXISTS\n", __LINE__);) + Result = ERROR_OBJECT_EXISTS; + tmi = NULL; + break; + } + } + if (RETURN_OK != Result) + break; + + tmi = AllocVec(sizeof(struct ToolMenuItem), MEMF_PUBLIC | MEMF_CLEAR); + if (NULL == tmi) + { + Result = ERROR_NO_FREE_STORE; + break; + } + + tmi->tmi_wbKey = NULL; + tmi->tmi_wbTitleKey = NULL; + + tmi->tmi_UseCount = 1; + + tmi->tmi_Name = StringDup(Name); + tmi->tmi_Cmd = StringDup(Cmd); + tmi->tmi_Shortcut = StringDup(Shortcut); + + if ('\\' == *Title && '\\' != Title[1]) + { + Title++; // Skip "\" + + len = 1 + strlen(Title); + tmi->tmi_MenuTitle = AllocVec(len, MEMF_PUBLIC); + d1(kprintf(__FUNC__ "/%ld: tmi_MenuTitle=%08lx\n", __LINE__, tmi->tmi_MenuTitle);) + if (NULL == tmi->tmi_MenuTitle) + { + d1(kprintf(__FUNC__ "/%ld: ERROR_NO_FREE_STORE\n", __LINE__);) + Result = ERROR_NO_FREE_STORE; + break; + } + + Title = CopyMenuTitle(tmi->tmi_MenuTitle, Title, len); + + d1(kprintf(__FUNC__ "/%ld: tmi_MenuTitle=<%s> Title=<%s>\n", __LINE__, tmi->tmi_MenuTitle, Title);) + } + else + { + tmi->tmi_MenuTitle = NULL; + } + + + len = 1 + strlen(Title); + tmi->tmi_Title = AllocVec(len, MEMF_PUBLIC); + if (NULL == tmi->tmi_Title) + { + d1(kprintf(__FUNC__ "/%ld: ERROR_NO_FREE_STORE\n", __LINE__);) + Result = ERROR_NO_FREE_STORE; + break; + } + + Title = CopyMenuTitle(tmi->tmi_Title, Title, len); + + d1(kprintf(__FUNC__ "/%ld: tmi_Title=<%s> Title=<%s>\n", __LINE__, tmi->tmi_Title, Title);) + + if (*Title) + { + len = 1 + strlen(Title); + tmi->tmi_SubItem = AllocVec(len, MEMF_PUBLIC); + if (NULL == tmi->tmi_SubItem) + { + d1(kprintf(__FUNC__ "/%ld: ERROR_NO_FREE_STORE\n", __LINE__);) + Result = ERROR_NO_FREE_STORE; + break; + } + + CopyMenuTitle(tmi->tmi_SubItem, Title, len); + + d1(kprintf(__FUNC__ "/%ld: tmi_SubItem=<%s>\n", __LINE__, tmi->tmi_SubItem);) + } + else + tmi->tmi_SubItem = NULL; + + if (NULL == tmi->tmi_Name || NULL == tmi->tmi_Title + || NULL == tmi->tmi_Cmd || NULL == tmi->tmi_Shortcut) + { + d1(kprintf(__FUNC__ "/%ld: ERROR_NO_FREE_STORE\n", __LINE__);) + Result = ERROR_NO_FREE_STORE; + break; + } + + tmi->tmi_Parent = FindParentMenuItem(tmi); + + if (tmi->tmi_MenuTitle && NULL == tmi->tmi_wbTitleKey) + { + tmi->tmi_MenuAppObject = SCA_NewAddAppMenuItemTags(0, (ULONG) tmi, + tmi->tmi_MenuTitle, ToolMenuMsgPort, + WBAPPMENUA_GetTitleKey, (ULONG) &tmi->tmi_wbTitleKey, + TAG_END); + + if (NULL == tmi->tmi_MenuAppObject) + { + d1(kprintf(__FUNC__ "/%ld: ERROR_NO_FREE_STORE\n", __LINE__);) + Result = ERROR_NO_FREE_STORE; + break; + } + + d1(kprintf(__FUNC__ "/%ld: tmi_wbTitleKey=%08lx\n", __LINE__, tmi->tmi_wbTitleKey);) + } + + if (NULL == tmi->tmi_SubItem || NULL == tmi->tmi_wbKey) + { + tmi->tmi_ItemAppObject = SCA_NewAddAppMenuItemTags(0, (ULONG) tmi, + tmi->tmi_Title, ToolMenuMsgPort, + tmi->tmi_SubItem ? TAG_IGNORE : WBAPPMENUA_CommandKeyString, (ULONG) Shortcut, + WBAPPMENUA_UseKey, (ULONG) tmi->tmi_wbTitleKey, + tmi->tmi_SubItem ? WBAPPMENUA_GetKey : TAG_IGNORE, (ULONG) &tmi->tmi_wbKey, + TAG_END); + + if (NULL == tmi->tmi_ItemAppObject) + { + d1(kprintf(__FUNC__ "/%ld: ERROR_NO_FREE_STORE\n", __LINE__);) + Result = ERROR_NO_FREE_STORE; + break; + } + } + + d1(kprintf(__FUNC__ "/%ld: tmi_wbKey=%08lx\n", __LINE__, tmi->tmi_wbKey);) + + if (tmi->tmi_SubItem) + { + tmi->tmi_SubAppObject = SCA_NewAddAppMenuItemTags(0, (ULONG) tmi, + tmi->tmi_SubItem, ToolMenuMsgPort, + WBAPPMENUA_CommandKeyString, (ULONG) Shortcut, + WBAPPMENUA_UseKey, (ULONG) tmi->tmi_wbKey, + TAG_END); + + if (NULL == tmi->tmi_SubAppObject) + { + d1(kprintf(__FUNC__ "/%ld: ERROR_NO_FREE_STORE\n", __LINE__);) + Result = ERROR_NO_FREE_STORE; + break; + } + } + + AddTail(&MenuItemList, &tmi->tmi_Node); + } while (0); + + if (RETURN_OK != Result && tmi) + DeleteToolMenuItem(tmi); + + ReleaseSemaphore(&MenuItemListSemaphore); + + return Result; +} + + +ULONG RemoveMenuItem(CONST_STRPTR Name) +{ + struct ToolMenuItem *tmi; + ULONG Result = ERROR_OBJECT_NOT_FOUND; + + d1(kprintf(__FUNC__ "/%ld: Name=<%s>\n", __LINE__, Name);) + + ObtainSemaphore(&MenuItemListSemaphore); + + for (tmi = (struct ToolMenuItem *) MenuItemList.lh_Head; + tmi != (struct ToolMenuItem *) &MenuItemList.lh_Tail; + tmi = (struct ToolMenuItem *) tmi->tmi_Node.ln_Succ) + { + if (0 == Stricmp((STRPTR) Name, tmi->tmi_Name)) + { + d1(kprintf(__FUNC__ "/%ld: FOUND tmi=%08lx\n", __LINE__, tmi);) + + if (tmi->tmi_Parent) + { + tmi->tmi_Parent->tmi_UseCount--; + + if (0 == tmi->tmi_Parent->tmi_UseCount) + { + Remove(&tmi->tmi_Parent->tmi_Node); + DeleteToolMenuItem(tmi->tmi_Parent); + } + } + + tmi->tmi_UseCount--; + + if (0 == tmi->tmi_UseCount) + { + Remove(&tmi->tmi_Node); + DeleteToolMenuItem(tmi); + } + + Result = RETURN_OK; + break; + } + } + + ReleaseSemaphore(&MenuItemListSemaphore); + + return Result; +} + + +static void DeleteToolMenuItem(struct ToolMenuItem *oldItem) +{ + if (oldItem) + { + if (oldItem->tmi_SubAppObject) + SCA_RemoveAppObject(oldItem->tmi_SubAppObject); + if (oldItem->tmi_ItemAppObject) + SCA_RemoveAppObject(oldItem->tmi_ItemAppObject); + if (oldItem->tmi_MenuAppObject) + SCA_RemoveAppObject(oldItem->tmi_MenuAppObject); + + if (oldItem->tmi_Name) + FreeVec(oldItem->tmi_Name); + if (oldItem->tmi_Title) + FreeVec(oldItem->tmi_Title); + if (oldItem->tmi_Cmd) + FreeVec(oldItem->tmi_Cmd); + if (oldItem->tmi_Shortcut) + FreeVec(oldItem->tmi_Shortcut); + if (oldItem->tmi_MenuTitle) + FreeVec(oldItem->tmi_MenuTitle); + if (oldItem->tmi_SubItem) + FreeVec(oldItem->tmi_SubItem); + + FreeVec(oldItem); + } +} + + +static STRPTR StringDup(CONST_STRPTR str) +{ + STRPTR copy; + + if (str) + { + copy = AllocVec(1 + strlen(str), MEMF_PUBLIC); + if (copy) + strcpy(copy, str); + } + else + copy = AllocVec(1, MEMF_PUBLIC | MEMF_CLEAR); + + return copy; +} + + +ULONG AddKeyboardCommand(CONST_STRPTR Name, CONST_STRPTR Key, CONST_STRPTR Cmd) +{ + struct KeyboardCommand *kbc; + ULONG Result = RETURN_OK; + + d1(kprintf(__FUNC__ "/%ld: Name=<%s> Cmd=<%s> Key=<%s>\n", __LINE__, Name, Cmd, Key);) + + ObtainSemaphore(&KbdCommandListSemaphore); + + do { + for (kbc = (struct KeyboardCommand *) KbdCommandList.lh_Head; + kbc != (struct KeyboardCommand *) &KbdCommandList.lh_Tail; + kbc = (struct KeyboardCommand *) kbc->kbc_Node.ln_Succ) + { + d1(kprintf(__FUNC__ "/%ld: Name=<%s> kbc=%08lx kbc_Name=<%s> Next=%08lx\n", \ + __LINE__, Name, kbc, kbc->kbc_Name, kbc->kbc_Node.ln_Succ);) + + if (0 == Stricmp((STRPTR) Name, kbc->kbc_Name)) + { + Result = ERROR_OBJECT_EXISTS; + kbc = NULL; + break; + } + } + + d1(kprintf(__FUNC__ "/%ld: Result=%ld\n", __LINE__, Result);) + + if (RETURN_OK != Result) + break; + + kbc = AllocVec(sizeof(struct KeyboardCommand), MEMF_PUBLIC | MEMF_CLEAR); + d1(kprintf(__FUNC__ "/%ld: kbc=%08lx\n", __LINE__, kbc);) + if (NULL == kbc) + { + Result = ERROR_NO_FREE_STORE; + break; + } + + kbc->kbc_IX.ix_Version = IX_VERSION; + kbc->kbc_Name = StringDup(Name); + kbc->kbc_Cmd = StringDup(Cmd); + kbc->kbc_Key = StringDup(Key); + + if (NULL == kbc->kbc_Name || NULL == kbc->kbc_Cmd || NULL == kbc->kbc_Key) + { + Result = ERROR_NO_FREE_STORE; + break; + } + + d1(kprintf(__FUNC__ "/%ld: \n", __LINE__);) + + if (0 != ParseIX((STRPTR) Key, &kbc->kbc_IX)) + { + d1(kprintf(__FUNC__ "/%ld: ParseIX() failed.\n", __LINE__);) + Result = ERROR_BAD_TEMPLATE; + break; + } + + d1(kprintf(__FUNC__ "/%ld: \n", __LINE__);) + + AddTail(&KbdCommandList, &kbc->kbc_Node); + } while (0); + + d1(kprintf(__FUNC__ "/%ld: \n", __LINE__);) + + if (RETURN_OK != Result && kbc) + DeleteKbdCommand(kbc); + + ReleaseSemaphore(&KbdCommandListSemaphore); + + return RETURN_OK; +} + + +ULONG RemoveKeyboardCommand(CONST_STRPTR Name) +{ + ULONG Result = ERROR_OBJECT_NOT_FOUND; + struct KeyboardCommand *kbc; + + d1(kprintf(__FUNC__ "/%ld: Name=<%s>\n", __LINE__, Name);) + + ObtainSemaphore(&KbdCommandListSemaphore); + + for (kbc = (struct KeyboardCommand *) KbdCommandList.lh_Head; + kbc != (struct KeyboardCommand *) &KbdCommandList.lh_Tail; + kbc = (struct KeyboardCommand *) kbc->kbc_Node.ln_Succ) + { + if (0 == Stricmp((STRPTR) Name, kbc->kbc_Name)) + { + d1(kprintf(__FUNC__ "/%ld: Found kbc=%08lx\n", __LINE__, kbc);) + + Remove(&kbc->kbc_Node); + + DeleteKbdCommand(kbc); + + Result = RETURN_OK; + break; + } + } + + ReleaseSemaphore(&KbdCommandListSemaphore); + + return Result; +} + + +BOOL DoKeyboardCommand(struct IntuiMessage *iMsg) +{ + struct InputEvent ie; + struct KeyboardCommand *kbc; + BOOL Success = FALSE; + + memset(&ie, 0, sizeof(ie)); + + ie.ie_Class = IECLASS_RAWKEY; + ie.ie_SubClass = IESUBCLASS_COMPATIBLE; + ie.ie_Code = iMsg->Code; + ie.ie_Qualifier = iMsg->Qualifier; + ie.ie_TimeStamp.tv_secs = iMsg->Seconds; + ie.ie_TimeStamp.tv_micro = iMsg->Micros; + + d1(kprintf(__FUNC__ "/%ld: Code=%08lx Qualifier=%08lx\n", __LINE__, ie.ie_Code, ie.ie_Qualifier);) + + ObtainSemaphoreShared(&KbdCommandListSemaphore); + + for (kbc = (struct KeyboardCommand *) KbdCommandList.lh_Head; + kbc != (struct KeyboardCommand *) &KbdCommandList.lh_Tail; + kbc = (struct KeyboardCommand *) kbc->kbc_Node.ln_Succ) + { + if (MatchIX(&ie, &kbc->kbc_IX)) + { + d1(kprintf(__FUNC__ "/%ld: FOUND Name=<%s> Cmd=<%s>\n", __LINE__, kbc->kbc_Name, kbc->kbc_Cmd);) + DoRexxCommand(kbc->kbc_Cmd); + + Success = TRUE; + break; + } + } + + ReleaseSemaphore(&KbdCommandListSemaphore); + + return Success; +} + + +static void DeleteKbdCommand(struct KeyboardCommand *kbc) +{ + if (kbc) + { + if (kbc->kbc_Name) + FreeVec(kbc->kbc_Name); + if (kbc->kbc_Cmd) + FreeVec(kbc->kbc_Cmd); + if (kbc->kbc_Key) + FreeVec(kbc->kbc_Key); + + FreeVec(kbc); + } +} + + +CONST_STRPTR CopyMenuTitle(STRPTR Dest, CONST_STRPTR Src, size_t MaxLen) +{ + while (*Src && MaxLen > 1) + { + if ('\\' == *Src) + { + Src++; + if ('\\' == *Src) + *Dest++ = *Src++; // copy "\\" as "\" + else + { + break; + } + } + else + *Dest++ = *Src++; + + MaxLen--; + } + + *Dest = '\0'; + + if ('\\' == *Src) + Src++; // skip "\" between menu Src and item Src + + return Src; +} + + +static struct ToolMenuItem *FindParentMenuItem(struct ToolMenuItem *tmi) +{ + struct ToolMenuItem *tmiParent; + + for (tmiParent = (struct ToolMenuItem *) MenuItemList.lh_Head; + tmiParent != (struct ToolMenuItem *) &MenuItemList.lh_Tail; + tmiParent = (struct ToolMenuItem *) tmiParent->tmi_Node.ln_Succ) + { + if (tmi->tmi_MenuTitle) + { + if (tmiParent->tmi_MenuTitle && 0 == Stricmp(tmiParent->tmi_MenuTitle, tmi->tmi_MenuTitle)) + { + tmiParent->tmi_UseCount++; + tmi->tmi_wbTitleKey = tmiParent->tmi_wbTitleKey; + tmi->tmi_wbKey = tmiParent->tmi_wbKey; + + return tmiParent; + } + } + else + { + if (tmi->tmi_SubItem && tmiParent->tmi_SubItem + && 0 == Stricmp(tmiParent->tmi_Title, tmi->tmi_Title)) + { + tmiParent->tmi_UseCount++; + tmi->tmi_wbTitleKey = tmiParent->tmi_wbTitleKey; + tmi->tmi_wbKey = tmiParent->tmi_wbKey; + + return tmiParent; + } + } + } + + return NULL; +} + diff --git a/scalos/Plugins/OOP/wb39_plugin/wbrexx/WBRexx.doc b/scalos/Plugins/OOP/wb39_plugin/wbrexx/WBRexx.doc new file mode 100644 index 000000000..9dce0369d --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/wbrexx/WBRexx.doc @@ -0,0 +1,1930 @@ +In the following you will find an alphabetical description +of the WB3.9 ARexx command set. This description is copyrighted +by Amiga (copied from the OS3.9 CD) and must not be distributed ! + + +Currently WBRexx supports the complete WB3.9 ARexx command set, +with the following exceptions : + + +ACTIVATEWINDOW fully supported + +CHANGEWINDOW fully supported + +DELETE fully supported + +FAULT fully supported + +GETATTR fully supported + +HELP unsupported + +ICON fully supported + +INFO fully supported + +KEYBOARD fully supported + +LOCKGUI unsupported, no-op + +MENU INVOKE mostlysupported + WINDOW.CLEANUPBY.NAME unsupported, no-op + WINDOW.CLEANUPBY.DATE unsupported, no-op + WINDOW.CLEANUPBY.SIZE unsupported, no-op + WINDOW.CLEANUPBY.TYPE unsupported, no-op + WINDOW.VIEWBY.TYPE unsupported, no-op + TOOLS.RESETWB unsupported, no-op + DEBUG.SAD unsupported, no-op + DEBUG.FLUSHLIBS unsupported, no-op + +MOVEWINDOW fully supported + +NEWDRAWER fully supported + +RENAME fully supported + +RX fully supported + +SIZEWINDOW fully supported + +UNLOCKGUI unsupported, no-op + +UNZOOMWINDOW fully supported + +VIEW fully supported + +WINDOW fully supported + +WINDOWTOBACK fully supported + +WINDOWTOFRONT fully supported + +ZOOMWINDOW fully supported + + +------------------------------------------------------------------------------ +ACTIVATEWINDOW command + +Purpose: + +This command will attempt to make a window the active one. + +Format: + +ACTIVATEWINDOW [WINDOW] + +Template: + +ACTIVATEWINDOW WINDOW + +Parameters: + +WINDOW + +Either ROOT" to activate the Workbench root window (where volume icons and +AppIcons live) or the fully qualified name of a drawer window to activate. +Note that the drawer window must already be open. + +If no WINDOW parameter is specified, this command will try to operate on the +currently active Workbench window. + +Errors: + +10 - If the named window cannot be activated. The error code will be placed +in the WORKBENCH.LASTERROR variable. + +Result: + +- + +Notes: + +If you choose to have a window activated that is not the root window you must +make sure that the window name is given as a fully qualified path name. For +example Work:" is a fully qualified name, and so is SYS:Utilities". +Devs/Printers" would not be a fully qualified name. A fully qualified name +always contains the name of an assignment, a volume or a device. + +Example: + +/* Activate the root window. */ ADDRESS workbench +ACTIVATEWINDOW root + +/* Activate the Work:" partition`s window. */ +ACTIVATEWINDOW ,Work:` +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +CHANGEWINDOW command + +Purpose: + +This command will attempt to change the size and the position of a window. + +Format: + +CHANGEWINDOW [WINDOW] [[LEFTEDGE] ][[TOPEDGE] ][[WIDTH] ][[HEIGHT] ] + +Template: + +CHANGEWINDOW WINDOW,LEFTEDGE/N,TOPEDGE/N,WIDTH/N,HEIGHT/N + +Parameter: + +WINDOW + +Either ROOT" to resize/move the Workbench root window (where volume icons and +AppIcons live), ACTIVE" to change the currently active Workbench window or +the fully qualified name of a drawer window to change. Note that the drawer +window must already be open. + +If no WINDOW parameter is specified, this command will try to operate on the +currently active Workbench window. + +LEFTEDGE + +New left edge window position. + +TOPEDGE + +New top edge window position. + +WIDTH + +New window width. + +HEIGHT + +New window height. + +Errors: + +10 - If the named window cannot be changed; this can also happen if you +specified ACTIVE" as the window name and none of the Workbench windows is +currently active. The error code will be placed in the WORBENCH.LASTERROR +variable. + +Result: + +- + +Notes: + +If you choose to have a window changed that is neither the root nor the +active window you must make sure that the window name is given as a fully +qualified path name. For example Work:" is a fully qualified name, and so is +SYS:Utilities". Devs/Printers" would not be a fully qualified name. A fully +qualified name always contains the name of an assignment, a volume or a +device. + +Example: + +/* Change the root window; move it to position 10,30. * and change its size +to 200100 pixels. */ +ADDRESS workbench +CHANGEWINDOW root LEFTEDGE 10 TOPEDGE 30 WIDTH 200 HEIGHT 100 + +/* Change the currently active window. */ +CHANGEWINDOW active 20 40 200 100 + + +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +DELETE command + +Purpose: + +This command is for deleting files and drawers (and their contents). + +Format: + +DELETE [NAME] [ALL] + +Template: + +DELETE NAME/A,ALL/S + +Parameters: + +NAME + +Name of the file or drawer or volume to delete. + +ALL + +If the object in question is a drawer, attempt to delete the contents of the +drawer as well as the drawer itself. If this option is not specified, the +DELETE command will only attempt to delete the drawer itself, which may fail +if the drawer is not yet empty. + +Errors: + +10 - If the named file, drawer or volume could not be found or could not be +deleted. + +Result: + +- + +Notes: + +The file name given must be an absolute path, such as in RAM:Empty". A +relative path, such as /fred/barney" will not work. + +Example: + +/* Delete the contents of the drawer RAM:Empty". */ + +ADDRESS workbench +DELETE ,RAM:Empty` ALL + + +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +FAULT command + +Purpose: + +This command will return a human readable explanation corresponding to an +error code. + +Format: + +FAULT [CODE] + +Template: + +FAULT CODE/A/N + +Parameters: + +CODE + +Error code to return a human readable explanation for. + +Errors: + +- + +Result: + +- + +Example: + +/* Query the error message corresponding to error code #205. */ +ADDRESS workbench +OPTIONS RESULTS +FAULT 205 +SAY result + + +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +GETATTR command + +Purpose: + +This command will retrieve information from the Workbench database, such the +names of the drawers currently open and the icons currently selected. + +Format: + +GETATTR [OBJECT] [NAME ][STEM ] [VAR ] + +Template: + +GETATTR OBJECT/A,NAME/K,STEM/K,VAR/K + +Parameters: + +OBJECT + +Name of the database entry to retrieve. For a list of valid entries see +below. + +NAME + +For some datatabase entries further information is required to identify the +data to retrieve. This is when you will need to provide a name. + +STEM + +If you request more than one database entry you will need to provide a +variable to store the information in. For an example of its use, see below. + +VAR + +If you want the queried information to be stored in a specific variable +(other than the RESULT variable), this is where you provive its name. + +Attributes: + +You can obtain information on the following attributes: + +APPLICATION.VERSION + +Version number of workbench.library". + +APPLICATION.SCREEN + +Name of the public screen Workbench uses. + +APPLICATION.AREXX + +Name of the Workbench ARexx port. + +APPLICATION.LASTERROR + +Number of the last error caused by the ARexx interface. + +APPLICATION.ICONBORDER + +Sizes of the icon borders, returned as four numbers separated by blank +spaces, e.g. 4 3 4 3". The four numbers represent the left border width, the +top border height, the right border width and the bottom border height (in +exactly that order). + +APPLICATION.FONT.SCREEN.NAME + +Name of the Workbench screen font. + +APPLICATION.FONT.SCREEN.WIDTH APPLICATION.FONT.SCREEN.HEIGHT + +Size of a single character of the Workbench screen font. Please note that +since the font in question may be proportional spaced the width information +may be of little value. To measure the accurate pixel width of a text in +reference to the font, use the .SIZE attribute. + +APPLICATION.FONT.SCREEN.SIZE + +Size of a text, measured in pixels, in reference to the screen font. The text +to measure must be provided with the NAME parameter of the GETATTR command. + +APPLICATION.FONT.ICON.NAME + +Name of the Workbench icon font. + +APPLICATION.FONT.ICON.WIDTH APPLICATION.FONT.ICON.HEIGHT + +Size of a single character of the Workbench icon font. Please note that since +the font in question may be proportional spaced the width information may be +of little value. To measure the accurate pixel width of a text in reference +to the font, use the .SIZE attribute. + +APPLICATION.FONT.ICON.SIZE + +Size of a text, measured in pixels, in reference to the icon font. The text +to measure must be provided with the NAME parameter of the GETATTR command. + +APPLICATION.FONT.SYSTEM.NAME + +Name of the system font. + +APPLICATION.FONT.SYSTEM.WIDTH +APPLICATION.FONT.SYSTEM.HEIGHT + +Size of a single character of the system font. + +APPLICATION.FONT.SYSTEM.SIZE + +Size of a text, measured in pixels, in reference to the system font. The text +to measure must be provided with the NAME parameter of the GETATTR command. + +WINDOWS.COUNT + +Number of the drawer windows currently open. This can be 0. + +WINDOWS.0 .. WINDOWS.N + +Names of the windows currently open. + +WINDOWS.ACTIVE + +Name of the currently active Workbench window; this will be " if none of +Workbench`s windows is currently active. + +KEYCOMMANDS.COUNT + +Number of keyboard commands assigned. This can be 0. + +KEYCOMMANDS.0 .. KEYCOMMANDS.N + +Information on all the keyboard commands assigned. + +KEYCOMMANDS..NAME + +Name of the keyboard command. + +KEYCOMMANDS..KEY + +The key combination assigned to this keyboard command. + +KEYCOMMANDS..COMMAND + +The ARexx command assigned to this key combination. + +MENUCOMMANDS.COUNT + +Number of menu commands assigned (through the MENU ADD .." command). This can +be 0. + +MENUCOMMANDS.0 .. MENUCOMMANDS.N + +Information on all the menu commands assigned. + +MENUCOMMANDS..NAME + +Name of this menu item. + +MENUCOMMANDS..TITLE + +Title of this menu item. + +MENUCOMMANDS..SHORTCUT + +The keyboard shortcut assigned to this menu item. + +MENUCOMMANDS..COMMAND + +The ARexx command assigned to this menu item. + +The following attributes require that the name of the window to obtain +information on is provided. + +Example: + +WINDOW.LEFT + +Left edge of the window. + +WINDOW.TOP + +Top edge of the window. + +WINDOW.WIDTH + +Width of the window. + +WINDOW.HEIGHT + +Height of the window. + +WINDOW.MIN.WIDTH + +Minimum width of the window. + +WINDOW.MIN.HEIGHT + +Minimum height of the window. + +WINDOW.MAX.WIDTH + +Maximum width of the window. + +WINDOW.MAX.HEIGHT + +Maximum height of the window. + +WINDOW.VIEW.LEFT + +Horizontal offset of the drawer contents; this value corresponds to the +horizontal window scroller position. + +WINDOW.VIEW.TOP + +Vertical offset of the drawer contents; this value corresponds to the +vertical window scroller position. + +WINDOW.SCREEN.NAME + +Name of the public screen the window was opened on. + +WINDOW.SCREEN.WIDTH WINDOW.SCREEN.HEIGHT + +Size of the public screen the window was opened on. + +WINDOW.ICONS.ALL.COUNT + +Number of the icons displayed in the window. This can be 0. + +WINDOW.ICONS.ALL.0 .. WINDOW.ICONS.ALL.N + +Information on all the icons displayed in the window: + +WINDOW.ICONS.ALL..NAME + +Name of the icon in question. + +WINDOW.ICONS.ALL..LEFT WINDOW.ICONS.ALL..TOP + +Position of the icon in question. + +WINDOW.ICONS.ALL..WIDTH WINDOW.ICONS.ALL..HEIGHT + +Size of the icon in question. + +WINDOW.ICONS.ALL..TYPE + +Type of the icon; one of DISK, DRAWER, TOOL, PROJECT,GARBAGE, DEVICE, KICK or +APPICON. + +WINDOW.ICONS.ALL..STATUS + +Whether the icon is selected and (if the icon is a drawer-likeobject, such as +a disk, drawer or trashcan icon) whether thecorresponding drawer is currently +open or closed. This attributeis returned in the form of a string, such as +SELECTED OPEN" which means that the icon is selected and the corresponding +draweris currently open. The other options include UNSELECTED" andCLOSED". + +WINDOW.ICONS.SELECTED.COUNT + +Number of the selected icons displayed in the window. This can be 0. + +WINDOW.ICONS.SELECTED.0 .. WINDOW.ICONS.SELECTED.N + +Information on all selected the icons in the window: + +WINDOW.ICONS.SELECTED..NAME + +Name of the icon in question. + +WINDOW.ICONS.SELECTED..LEFT WINDOW.ICONS.SELECTED..TOP + +Position of the icon in question. + +WINDOW.ICONS.SELECTED..WIDTH WINDOW.ICONS.SELECTED..HEIGHT + +Size of the icon in question. + +WINDOW.ICONS.SELECTED..TYPE + +Type of the icon; one of DISK, DRAWER, TOOL, PROJECT,GARBAGE, DEVICE, KICK or +APPICON. + +WINDOW.ICONS.SELECTED..STATUS + +Whether the icon is selected and (if the icon is a drawer-like object, such +as a disk, drawer or trashcan icon) whether the corresponding drawer is +currently open or closed. This attribute is returned in the form of a string, +such as SELECTED OPEN" which means that the icon is selected and the +corresponding drawer is currently open. The other options include UNSELECTED" +and CLOSED". Of course, for the WINDOW.ICONS.SELECTED stem the icon status +will always be reported as SELECTED". + +WINDOW.ICONS.UNSELECTED.COUNT + +Number of the unselected icons displayed in the window. This can be 0. + +WINDOW.ICONS.UNSELECTED.0 .. WINDOW.ICONS.UNSELECTED.N + +Information on all selected the icons in the window: + +WINDOW.ICONS.UNSELECTED..NAME + +Name of the icon in question. + +WINDOW.ICONS.UNSELECTED..LEFT WINDOW.ICONS.UNSELECTED..TOP + +Position of the icon in question. + +WINDOW.ICONS.UNSELECTED..WIDTH WINDOW.ICONS.UNSELECTED..HEIGHT + +Size of the icon in question. + +WINDOW.ICONS.UNSELECTED..TYPE + +Type of the icon; one of DISK, DRAWER, TOOL, PROJECT, GARBAGE, DEVICE, KICK +or APPICON. + +WINDOW.ICONS.UNSELECTED..STATUS + +Whether the icon is selected and (if the icon is a drawer-like object, such +as a disk, drawer or trashcan icon) whether the corresponding drawer is +currently open or closed. This attribute is returned in the form of a string, +such as UNSELECTED OPEN" which means that the icon is selected and the +corresponding drawer is currently open. The other options include SELECTED" +and CLOSED". Of course, for the WINDOW.ICONS.UNSELECTED stem the icon status +will always be reported as UNSELECTED". + +Errors: + +10 - If the requester information could not be retrieved, you requested more +than one database entry and did not provide a stem variable or if you +provided a stem variable but did not request more than one database entry. +The error code will be placed in the WORKBENCH.LASTERROR variable. + +Result: + +RESULT - The information retrieved from the database. + +Example: + +/* Query the Workbench version. */ +ADDRESS workbench +OPTIONS RESULTS + +GETATTR application.version +SAY result + +/* Query the Workbench version and store it in the * variable +`version_number`. */ +GETATTR application.version +VAR version_number +SAY version_number + +/* Query the names of all currently open windows, * then print them. */ +GETATTR windows +STEM window_list + +DO i = 0 TO window_list.count-1 +SAY window_list.i; +END; + +/* Query name, position and size of the first icon * shown in the root +window. */ +GETATTR window.icons.all.0 +NAME root +STEM root + +SAY root.name +SAY root.left +SAY root.top +SAY root.width +SAY root.height +SAY root.type + +/* Query the width and height of the root window. */ +GETATTR window.width +NAME root +SAY result + +GETATTR window.height +NAME root +SAY result + +/* Query the length of a text (in pixels) with reference * to the icon font. +*/ +GETATTR application.font.icon.size +NAME ,Text to measure` +SAY result + +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +HELP command + +Purpose: + +This command can be used to open the online help and to obtain information on +the supported menus, commands and command parameters. + +Format: + +HELP [COMMAND ] [MENUS] [PROMPT] + +Template: + +HELP COMMAND/K,MENUS/S,PROMPT/S + +Parameters: + +COMMAND + +Name of the command whose command template should be retrieved. + +MENUS + +Specify this parameter to retrieve a list of menu items currently available. + +PROMPT + +Specify this parameter to invoke the online help system. + +If no parameter is provided, a list of supported commands will be returned. + +Errors: + +10 - If the named command is not supported by the ARexx interface. The error +code will be placed in the WORKBENCH.LASTERROR variable. + +Result: + +RESULT + +The command template, list of menu items or commands, as specified in the +command parameters. + +Example: + +/* Retrieve the list of supported commands. */ +ADDRESS workbench +OPTIONS results + +HELP +SAY result + +/* Retrieve the command template of the `GETATTR` command. */ +HELP COMMAND getattr +SAY result + +/* Retrieve the list of available menu items. */ +HELP MENUS +SAY result + + +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +ICON command + +Purpose: + +This command is for manipulating the icons displayed in a window. + +Format: + +ICON [WINDOW] .. [OPEN] [MAKEVISIBLE] +[SELECT] [UNSELECT] [UP ] [DOWN ] [LEFT ] [RIGHT +] [X ] [Y ] [ACTIVATE +UP|DOWN|LEFT|RIGHT] [CYCLE PREVIOUS|NEXT] [MOVE IN|OUT] + +Template: + +ICON WINDOW,NAMES/M,OPEN/S,MAKEVISIBLE/S,SELECT/S,UNSELECT/S, +UP/N,DOWN/N,LEFT/N,RIGHT/N,X/N,Y/N,ACTIVATE/K,CYCLE/K, MOVE/K + +Parameters: + +WINDOW + +Name of the window whose icons should be manipulated. This can be ROOT" to +work on the Workbench root window (where volume icons and AppIcons live), +ACTIVE" to work on the currently active Workbench window or the fully +qualified name of a drawer window. Note that the drawer window must already +be open. + +If no WINDOW parameter is specified, this command will try to operate on the +currently active Workbench window. + +NAMES + +Names of the icons to manipulate. + +OPEN + +Specifies that the named icons should be opened. + +MAKEVISIBLE + +Specifies that the named icons should be made visible. This generally works +well for the first icon in a list but does not always work for a whole list. + +SELECT + +Select the named icons. + +UNSELECT + +Unselect the named icons. + +UP, DOWN, LEFT, RIGHT + +Move the named icons by the specified number of pixels. + +X, Y + +Move the named icons to the specified position. + +ACTIVATE + +This command is for activating the icon closest to the currently selected +icon in the window. Activating" in this context means selecting an icon, +whilst at the same time unselecting all others". Thus, the active" icon is +the only selected icon in the window. + +You can indicate which direction the next icon to be activated should be +searched for, relative to the currently active icon. UP" searches upwards, +DOWN" searches downwards, LEFT" searches to the left and RIGHT" searches to +the right. + +CYCLE + +This command is for cycling through all icons in a window, making each one +the active one in turn (for a description of what active" means in this +context, see the ACTIVATE" description above). You must indicate in which +direction you want to cycle through the icons: you can either specify +PREVIOUS" or NEXT". + +MOVE + +This command is not for moving icons but for moving through a file system +hierarchy. Thus, moving in" will open a drawer and moving out" will open the +drawer`s parent directory. The IN" parameter will cause the drawer +represented by the active icon to be opened. Please note that an icon must be +selected and it must be a drawer. The OUT" parameter will open the drawer`s +parent directory, and it also requires that in the drawer there is an icon +selected. This may sound strange, but this feature is not meant as a +replacement for the Open Parent" menu item. + +Errors: + +10 - If the named window cannot be found, none of the Workbench windows are +currently active and the command was set to work on the currently active +Workbench window. The error code will be placed in the WORKBENCH.LASTERROR +variable. + +Result: + +- + +Example: + +/* Select the icons of the Workbench" and Work" volumes * displayed in the +root window. */ +ADDRESS workbench + +ICON WINDOW root +NAMES Workbench Work SELECT + +/* Open the Workbench" volume icon displayed in the root * window. */ +ICON WINDOW root +NAMES Workbench OPEN + +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +INFO command + +Purpose: + +This command is for opening the Workbench icon information requester. + +Format: + +INFO [NAME] + +Template: + +INFO NAME/A + +Parameters : + +NAME + +Name of the file, drawer or volume to open the information window for. + +Errors: + +10 - If the named file, drawer or volume could not be found. The error code +will be placed in the WORKBENCH.LASTERROR variable. + +Result: + +- + +Example: + +/* Open the information window for SYS:". */ +ADDRESS workbench + +INFO NAME ,SYS:` + + +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +KEYBOARD command + +Purpose: + +This command can be used to bind ARexx commands to key combinations. + +Format: + +KEYBOARD [NAME] ADD|REMOVE [KEY ] +[CMD ] + +Template: + +KEYBOARD NAME/A,ADD/S,REMOVE/S,KEY,CMD/F + +Parameters: + +NAME + +Name of the key combination to add or remove. Each key combination must have +a name with which it is associated. The name must be unique. + +ADD + +This tells the KEYBOARD command to add a new keyboard combination. You will +also need to specify the KEY and CMD parameters. + +REMOVE + +This tells the KEYBOARD command to remove an existing keyboard combination. + +KEY + +The keyboard combination to add; this must be in the same format as used by +the Commodities programs. + +CMD + +This is the ARexx command to bind to the keyboard combination. The command +can either be the name of an ARexx script to execute or a short ARexx program +in a single line. + +Errors: + +10 - The command will fail if you tried to add a duplicate of an existing key +combination or if the key combination to remove does not exist. The error +code will be placed in the WORKBENCH.LASTERROR variable. + +Result: + +- + +Example: + +/* Bind an ARexx script to the [Control]+A key combination. * When pressed, +this will cause the ARexx script by the name * test.wb" to be executed. ARexx +will search for that program * in the REXX:" directory. If no test.wb" file +can * be found, ARexx will attempt to execute a script * by the name of +test.rexx". */ + +ADDRESS workbench + +KEYBOARD ADD NAME test1 KEY ,"ctrl a", CMD ,test` + +/* Bind an ARexx script to the [Alt]+[F1] key combination. * When pressed, +this will cause a short inline program to be * executed. */ +KEYBOARD ADD NAME test2 KEY ,"alt f1", CMD `say 42" + +/* Bind an ARexx script to the [Shift]+[Help] key combination. * When +pressed, this will cause the Workbench About" menu item * to be invoked. */ +KEYBOARD ADD NAME test3 KEY ,"shift help", CMD `MENU INVOKE WORKBENCH.ABOUT" + +/* Remove the first key combination we added above. */ +KEYBOARD REMOVE NAME test1 + + +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +LOCKGUI command + +Purpose: + +This command will block access to all Workbench drawer windows. + +Format: + +LOCKGUI + +Template: + +LOCKGUI + +Parameters: + +- + +Errors: + +- + +Result: + +- + +Notes: + +It takes as many UNLOCKGUI commands as there were LOCKGUI commands to make +the Workbench drawer windows usable again. In other words, the LOCKGUI +command nests". + +Example: + +/* Block access to all Workbench drawer windows. */ +ADDRESS workbench + +LOCKGUI + + +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +UNZOOMWINDOW command + +Purpose: + +This command will attempt return a window to its original position and +dimensions. + +Format: + +UNZOOMWINDOW [WINDOW] + +Template: + +UNZOOMWINDOW WINDOW + +Parameters: + +WINDOW + +Name of the window to operate on. ROOT" will use the Workbench root window +(where volume icons and AppIcons live), ACTIVE" will use the currently active +Workbench window. Any other fully qualified path name will use the drawer +window corresponding to the path. If no WINDOW parameter is specified, this +command will try to operate on the currently active Workbench window. + +Errors: + +10 - If the named window cannot be found. The error code will be placed in +the WORKBENCH.LASTERROR variable. + +Result: + +- + +Example: + +/* Change the root window. */ +ADDRESS workbench + +UNZOOMWINDOW root + + +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +MENU command + +Purpose: + +This command is for invoking items of the Workbench menu, as if the user had +selected them with the mouse and for adding/removing user menus. + +Format: + +MENU [WINDOW ] [INVOKE] [NAME ] [TITLE +] [SHORTCUT ] [ADD|REMOVE] [CMD ] + +Template: + +MENU WINDOW/K,INVOKE,NAME/K,TITLE/K,SHORTCUT/K,ADD/S,REMOVE/S,CMD/K/F + +Parameters: + +The following set of parameters can be used solely for invoking menu items. + +WINDOW + +Name of the window whose menu should be invoked. This can be ROOT" to work on +the Workbench root window (where volume icons and AppIcons live), ACTIVE" to +work on the currently active Workbench window or the fully qualified name of +a drawer window. Note that the drawer window must already be open. + +If no WINDOW parameter is specified, this command will try to operate on the +currently active Workbench window. + +INVOKE + +Name of the menu to invoke. See below for a list of available menu items. + +The following set of parameters are for adding and removing menu items. + +NAME + +Name of the menu item to add or remove. Each menu item must have a name with +which it is associated. The name must be unique and has nothing to do with +the title of the item, as shown in the Tools" menu. + +TITLE + +This is the text that will be used as the menu item title, as it will appear +in the Tools" menu. This parameter is required if you ADD a new menu item. + +SHORTCUT + +When adding a new menu item, this will be the menu shortcut associated with +the item. Please note that the shortcut cannot be longer than a single +character and that it will be ignored if there already is an item in any of +the menus which uses this shortcut. This parameter is optional. + +ADD + +This tells the MENU command to add a new item to the Tools" menu. When adding +a menu item you will also need to specify the NAME, TITLE and CMD parameters. + +Starting with V45 you can also add new menu titles beyond +the "Tools" menu. For such menu titles, the first letter of +the TITLE parameter must indicate the name of the title +to add. This means for example that a title like +"\menu title\menu item\submenu item" will a new menu title +by the name of "menu title", and below that add a menu item +labeled "menu item" and below that a submenu item by the +name of "submenu item". + +Before the respective menu titles, items and subitems are +added, all backslashes are removed from their labels; if +you want to retain a single backslash, use two \\ in place +of one; the cleanup code will only remove the first one. + +REMOVE + +This tells the MENU command to remove a menu item previously added via the +ARexx interface. When removing a menu item you will also need to specify the +NAME parameter. + +CMD + +This is the ARexx command to bind to the new menu item. The command can +either be the name of an ARexx script to execute or a short ARexx program in +a single line. + +Menu items: + +WORKBENCH.BACKDROP + +Toggles the Workbench Backdrop" window switch. + +WORKBENCH.EXECUTE + +Invokes the Workbench Execute Command" requester. The user will be prompted +to enter the command to be executed. + +WORKBENCH.REDRAWALL + +Invokes the Workbench Redraw All" function. + +WORKBENCH.UPDATEALL + +Invokes the Workbench Update All" function. + +WORKBENCH.LASTMESSAGE + +Redisplays the last Workbench error message. + +WORKBENCH.ABOUT + +Displays the Workbench About..." requester. + +WORKBENCH.QUIT + +Attempts to close Workbench; this may bring up a requester the user will have +to answer. + +WINDOW.NEWDRAWER + +Prompts the user to enter the name of a new drawer to be created. + +WINDOW.OPENPARENT + +If possible, this will open the parent directory of the drawer the command +operates on. + +WINDOW.CLOSE + +If possible, this will close the drawer the command operates on. + +WINDOW.UPDATE + +This will update the drawer the command operates on, i.e. the contents will +be reread. + +WINDOW.SELECTCONTENTS + +This will select the contents of the drawer the command operates on. + +WINDOW.CLEARSELECTION + +This unselects all icons selected in the drawer the command operates on. + +WINDOW.CLEANUPBY.COLUMN + +This will sort the contents of the drawer and place the icons in columns. + +WINDOW.CLEANUPBY.NAME + +This will sort the contents of the drawer by name and place the icons in +rows. + +WINDOW.CLEANUPBY.DATE + +This will sort the contents of the drawer by date and place the icons in +rows. + +WINDOW.CLEANUPBY.SIZE + +This will sort the contents of the drawer by size and place the icons in +rows. + +WINDOW.CLEANUPBY.TYPE + +This will sort the contents of the drawer by type and place the icons in +rows. + +WINDOW.RESIZETOFIT + +This will resize the drawer window, trying to make it just as large as to +allow all its icons to fit. + +WINDOW.SNAPSHOT.WINDOW + +This will snapshot the drawer window, but none of its contents. + +WINDOW.SNAPSHOT.ALL + +This will snapshot the drawer window and its contents. + +WINDOW.SHOW.ONLYICONS + +This will change the display mode of the drawer to show only files and +drawers which have icons attached. + +WINDOW.SHOW.ALLFILES + +This will change the display mode of the drawer to show all files and +drawers, regardless of whether they have icons attached or not. + +WINDOW.VIEWBY.ICON + +This will change the display mode of the drawer to show its contents as +icons. + +WINDOW.VIEWBY.NAME + +This will change the display mode of the drawer to show its contents in +textual format, sorted by name. + +WINDOW.VIEWBY.DATE + +This will change the display mode of the drawer to show its contents in +textual format, sorted by date. + +WINDOW.VIEWBY.SIZE + +This will change the display mode of the drawer to show its contents in +textual format, sorted by size. + +WINDOW.VIEWBY.TYPE + +This will change the display mode of the drawer to show its contents in +textual format, sorted by type. + + +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +MOVEWINDOW command + +Purpose: + +This command will attempt to change the position of a window. + +Format: + +MOVEWINDOW [WINDOW] [[LEFTEDGE] ] [[TOPEDGE] ] + +Template: + +MOVEWINDOW WINDOW,LEFTEDGE/N,TOPEDGE/N + +Parameters: + +WINDOW + +Either ROOT" to move the Workbench root window (where volume icons and +AppIcons live), ACTIVE" to move the currently active Workbench window or the +fully qualified name of a drawer window to change. Note that the drawer +window must already be open. + +If no WINDOW parameter is specified, this command will try to operate on the +currently active Workbench window. + +LEFTEDGE + +New left edge window position. + +TOPEDGE + +New top edge window position. + +Errors: + +10 - If the named window cannot be moved; this can also happen if you +specified ACTIVE" as the window name and none of the Workbench windows is +currently active. The error code will be placed in the WORKBENCH.LASTERROR +variable. + +Result: + +- + +Notes: + +If you choose to have a window changed that is neither the root nor the +active window you must make sure that the window name is given as a fully +qualified path name. For example Work:" is a fully qualified name, and so is +SYS:Utilities". Devs/Printers" would not be a fully qualified name. A fully +qualified name always contains the name of an assignment, a volume or a +device. + +Example: + +/* Move the root window to position 10,30. */ +ADDRESS workbench + +MOVEWINDOW root LEFTEDGE 10 TOPEDGE 30 + +/* Move the currently active window. */ +MOVEWINDOW active 20 40 + + +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +NEWDRAWER command + +Purpose: + +This command is for creating new drawers. + +Format: + +NEWDRAWER [NAME] + +Template: + +NEWDRAWER NAME/A + +Parameters: + +NAME + +Name of the drawer to be created. + +Errors: + +10 - If the named drawer could not be created. + +Result: + +- + +Notes: + +The drawer name given must be an absolute path, such as in RAM:Empty". A +relative path, such as /fred/barney" will not work. + +Example : + +/* Create a drawer by the name of Empty" in the RAM disk. */ +ADDRESS workbench + +NEWDRAWER ,RAM:Empty` + + +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +RENAME command + +Purpose: + +This command is for renaming files, drawers and volumes. + +Format: + +RENAME [OLDNAME] [NEWNAME] + +Template: + +RENAME OLDNAME/A,NEWNAME/A + +Parameters: + +OLDNAME + +Name of the file/drawer/volume to be renamed. This must be an absolute path, +such as in RAM:Empty". A relative path, such as /fred/barney", will not work. + +NEWNAME + +The new name to assign to the file/drawer/volume. This must not be an +absolute or relative path. For example, wilma" is valid new name, /wilma" or +wilma:" would be invalid names. + +Errors: + +10 - If the object cannot be renamed. + +Result: + +- + +Notes: + +The RENAME command does not work like for example the AmigaDOS Rename" +command. For example, RENAME ,ram:empty` ,newname`" will rename the file +,RAM:empty` to ,RAM:newname`. + +Example: + +/* Rename a drawer by the name of Old" in the RAM disk to New". */ +ADDRESS workbench + +RENAME ,RAM:Old` ,New` + + +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +RX command + +Purpose: + +This command is for executing ARexx scripts and commands. + +Format: + +RX [CONSOLE] [ASYNC] [CMD] + +Template: + +RX CONSOLE/S,ASYNC/S,CMD/A/F + +Parameters: + +CONSOLE + +This switch indicates that a console (for default I/O) is needed. + +ASYNC + +This switch indicates that the command should be run asynchronously, i.e. the +RX" command will return as soon as ARexx has been instructed to run the +command you specified. Otherwise, the RX" command will wait for the specified +ARexx command to complete execution. + +COMMAND + +This is the name of the ARexx program to execute. + +Errors: + +10 - If the given ARexx program could not be executed. + +Result: + +- + +Example: + +/* Execute an ARexx program by the name of ,test.wb`; * its output should be +sent to a console window. */ +ADDRESS workbench + +RX CONSOLE CMD ,test.wb` + + +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +SIZEWINDOW command + +Purpose: + +This command will attempt to change the size of a window. + +Format: + +SIZEWINDOW [WINDOW] [[WIDTH] ] +[[HEIGHT] ] + +Template: + +SIZEWINDOW WINDOW,WIDTH/N,HEIGHT/N + +Parameters: + +WINDOW + +Either ROOT" to resize the Workbench root window (where volume icons and +AppIcons live), ACTIVE" to resize the currently active Workbench window or +the fully qualified name of a drawer window to change. Note that the drawer +window must already be open. + +If no WINDOW parameter is specified, this command will try to operate on the +currently active Workbench window. + +WIDTH + +New window width. + +HEIGHT + +New window height. + +Errors: + +10 - If the named window cannot be resized; this can also happen if you +specified ACTIVE" as the window name and none of the Workbench windows is +currently active. The error code will be placed in the WORKBENCH.LASTERROR +variable. + +Result: + +- + +Notes: + +If you choose to have a window resized that is neither the root nor the +active window you must make sure that the window name is given as a fully +qualified path name. For example Work:" is a fully qualified name, and so is +SYS:Utilities". Devs/Printers" would not be a fully qualified name. A fully +qualified name always contains the name of an assignment, a volume or a +device. + +Example: + +/* Change the root window size to 200100 pixels. */ +ADDRESS workbench + +SIZEWINDOW root 30 WIDTH 200 HEIGHT 100 + +/* Resize the currently active window. */ +SIZEWINDOW active 200 100 + + +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +UNLOCKGUI command + +Purpose: + +This command will allow access to all Workbench drawer windows locked with +the LOCKGUI command. + +Format: + +UNLOCKGUI + +Template: + +UNLOCKGUI + +Parameters: + +- + +Errors: + +- + +Result: + +- + +Notes: + +It takes as many UNLOCKGUI commands as there were LOCKGUI commands to make +the Workbench drawer windows usable again. In other words, the LOCKGUI +command nests". + +Example: + +/* Reallow access to all Workbench drawer windows. */ +ADDRESS workbench + +UNLOCKGUI + + +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +VIEW command + +Purpose: + +This command will change the position of the viewable display area of a +window. + +Format: + +VIEW [WINDOW] [PAGE|PIXEL] [UP|DOWN|LEFT|RIGHT] + +Template: + +VIEW WINDOW,PAGE/S,PIXEL/S,UP/S,DOWN/S,LEFT/S,RIGHT/S + +Parameters: + +WINDOW + +Either ROOT" to change the Workbench root window view (where volume icons and +AppIcons live), ACTIVE" to change the currently active Workbench window view +or the fully qualified name of a drawer window to change. Note that the +drawer window must already be open. + +If no WINDOW parameter is specified, this command will try to operate on the +currently active Workbench window. + +UP + +Move the view up by about 1/8 of the window height. If PAGE is specified, +moves the view up by a whole page. If PIXEL is specified, moves the view up +by a single pixel. + +DOWN + +Move the view down by about 1/8 of the window height. If PAGE is specified, +moves the view down by a whole page. If PIXEL is specified, moves the view +down by a single pixel. + +LEFT + +Move the view left by about 1/8 of the window height. If PAGE is specified, +moves the view left by a whole page. If PIXEL is specified, moves the view +left by a single pixel. + +RIGHT + +Move the view right by about 1/8 of the window height. If PAGE is specified, +moves the view right by a whole page. If PIXEL is specified, moves the view +right by a single pixel. + +Errors: + +10 - If the named window view cannot be changed; this can also happen if you +specified ACTIVE" as the window name and none of the Workbench windows is +currently active. The error code will be placed in the WORKBENCH.LASTERROR +variable. + +Result: + +- + +Notes: + +If you choose to have a window view changed that is neither the root nor the +active window you must make sure that the window name is given as a fully +qualified path name. For example Work:" is a fully qualified name, and so is +SYS:Utilities". Devs/Printers" would not be a fully qualified name. A fully +qualified name always contains the name of an assignment, a volume or a +device. + +To find out about a window`s current view position, use the GETATTR command +and query the window`s WINDOW.VIEW.LEFT and WINDOW.VIEW.TOP attributes. + +Example: + +/* Change the root window view; move it up by a whole page. */ +ADDRESS workbench + +VIEW root PAGE UP + +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +WINDOW command + +Purpose: + +This command will change, open, close or snapshot windows. + +Format: + +WINDOW [WINDOWS] .. [OPEN|CLOSE] [SNAPSHOT] +[ACTIVATE] [MIN|MAX] [FRONT|BACK] [CYCLE PREVIOUS|NEXT] + +Template: + +WINDOW WINDOWS/M/A,OPEN/S,CLOSE/S,SNAPSHOT/S,ACTIVATE/S,MIN/S,MAX/S, +FRONT/S,BACK/S,CYCLE/K + +Parameters: + +WINDOWS + +Names of the windows to operate on. This can be ROOT" to for the Workbench +root window (where volume icons and AppIcons live), ACTIVE" for the currently +active Workbench window or the fully qualified name of a drawer window. + +OPEN + +Attempt to open the specified windows. + +CLOSE + +Close the specified windows. Note that if a window is closed no further +operations (such as SNAPSHOT, ACTIVATE, etc.) can be performed on it. + +SNAPSHOT + +Snapshot the sizes and positions of the specified windows. + +ACTIVATE + +Activate the specified windows. With multiple windows to activate, only one +window will wind up as the active one. Commonly, this will be the last window +in the list. + +MIN + +Resize the windows to their minimum dimensions. + +MAX + +Resize the windows to their maximum dimensions. + +FRONT + +Move the windows into the foreground. + +BACK + +Move the windows into the background. + +CYCLE + +This command operates on the currently active drawer window. You can specify +either PREVIOUS", to activate the previous drawer window in the list, or +NEXT", to activate the next following drawer window in the list. + +Errors: + +10 - If the named windows cannot be opened or operated on; this can also +happen if you specified ACTIVE" as a window name and none of the Workbench +windows is currently active. The error code will be placed in the +WORKBENCH.LASTERROR variable. + +Result: + +- + +Notes: + +If you choose to have a window operated on that is neither the root nor the +active window you must make sure that the window name is given as a fully +qualified path name. For example Work:" is a fully qualified name, and so is +SYS:Utilities". Devs/Printers" would not be a fully qualified name. A fully +qualified name always contains the name of an assignment, a volume or a +device. + +Example: + +/* Open the Work:" drawer. */ +ADDRESS workbench + +WINDOW ,Work:` OPEN + +/* Activate the root window. */ +WINDOW root ACTIVATE + + +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +WINDOWTOBACK command + +Purpose: + +This command will push a window into the background. + +Format: + +WINDOWTOBACK [WINDOW] + +Template: + +WINDOWTOBACK WINDOW + +Parameters: + +WINDOW + +ROOT" to push the the Workbench root window (where volume icons and AppIcons +live) into to the background, ACTIVE" to push the currently active Workbench +window into the background or the fully qualified name of a drawer window. +Note that the drawer window must already be open. + +If no WINDOW parameter is specified, this command will try to operate on the +currently active Workbench window. + +Errors: + +10 - If the named window cannot be found. The error code will be placed in +the WORKBENCH.LASTERROR variable. + +Result: + +- + +Notes: + +If you choose to have a window pushed into the background that is not the +root window or the currently active window you must make sure that the window +name is given as a fully qualified path name. For example Work:" is a fully +qualified name, and so is SYS:Utilities". Devs/Printers" would not be a fully +qualified name. A fully qualified name always contains the name of an +assignment, a volume or a device. + +Example: + +/* Push the root window into the background. */ +ADDRESS workbench + +WINDOWTOBACK root + + +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +WINDOWTOFRONT command + +Purpose: + +This command will bring a window to the foreground. + +Format: + +WINDOWTOFRONT [WINDOW] + +Template: + +WINDOWTOFRONT WINDOW + +Parameters: + +WINDOW + +ROOT" to bring the the Workbench root window (where volume icons and AppIcons +live) to the foreground, ACTIVE" to bring the currently active Workbench +window to the foreground or the fully qualified name of a drawer window. Note +that the drawer window must already be open. + +If no WINDOW parameter is specified, this command will try to operate on the +currently active Workbench window. + +Errors: + +10 - If the named window cannot be found. The error code will be placed in +the WORKBENCH.LASTERROR variable. + +Result: + +- + +Notes: + +If you choose to have a window brought to the foreground that is not the root +window or the currently active window you must make sure that the window name +is given as a fully qualified path name. For example Work:" is a fully +qualified name, and so is SYS:Utilities". Devs/Printers" would not be a fully +qualified name. A fully qualified name always contains the name of an +assignment, a volume or a device. + +Example: + +/* Bring the root window to the foreground. */ ADDRESS workbench + +WINDOWTOFRONT root + + +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +ZOOMWINDOW command + +Purpose: + +This command will change a window to alternate position and dimensions. + +Format: + +ZOOMWINDOW [WINDOW] + +Template: + +ZOOMWINDOW WINDOW + +Parameters: + +WINDOW + +Name of the window to operate on. ROOT" will use the Workbench root window +(where volume icons and AppIcons live), ACTIVE" will use the currently active +Workbench window. Any other fully qualified path name will use the drawer +window corresponding to the path. If no WINDOW parameter is specified, this +command will try to operate on the currently active Workbench window. + +Errors: + +10 - If the named window cannot be found. The error code will be placed in +the WORKBENCH.LASTERROR variable. + +Result: + +- + +Example: + +/* Change the root window. */ +ADDRESS workbench + +ZOOMWINDOW root + + +------------------------------------------------------------------------------ diff --git a/scalos/Plugins/OOP/wb39_plugin/wbrexx/WBRexxMain.c b/scalos/Plugins/OOP/wb39_plugin/wbrexx/WBRexxMain.c new file mode 100644 index 000000000..45ea110cd --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/wbrexx/WBRexxMain.c @@ -0,0 +1,519 @@ +// WBRexxMain.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +//#include "wb39.h" +//#include "wb39proto.h" +#include "wbrexx.h" +#include "Scalos_Helper.h" + +VOID closePlugin(void); +static BOOL OpenLibraries(void); +static void CloseLibraries(void); + + +struct DosLibrary *DOSBase; +struct Library *IconobjectBase; +struct Library *WorkbenchBase; +T_UTILITYBASE UtilityBase; +struct ScalosBase *ScalosBase; +struct IntuitionBase *IntuitionBase; +struct Library *LayersBase; +struct Library *GfxBase; +struct Library *IconBase; +struct Library *IFFParseBase; +struct Library *CxBase; +struct Library *AmigaGuideBase; +T_LOCALEBASE *LocaleBase; +#ifdef __amigaos4__ +struct Library *NewlibBase; + +struct DOSIFace *IDOS; +struct IconobjectIFace *IIconobject; +struct WorkbenchIFace *IWorkbench; +struct UtilityIFace *IUtility; +struct ScalosIFace *IScalos; +struct IntuitionIFace *IIntuition; +struct LayersIFace *ILayers; +struct GraphicsIFace *IGraphics; +struct IconIFace *IIcon; +struct IFFParseIFace *IIFFParse; +struct CommoditiesIFace *ICommodities; +struct Interface *INewlib; +struct AmigaGuideIFace *IAmigaGuide; +struct LocaleIFace *ILocale; +#endif + +#if defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) +extern T_UTILITYBASE __UtilityBase; +#endif /* defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) */ + +static BOOL fInit; + +struct List AppWindowList; // list of all AppWindows +struct SignalSemaphore AppWindowSema; + +ULONG DefaultStackSize = 4095; +ULONG fVolumeGauge = TRUE; +ULONG fTitleBar = TRUE; +ULONG TypeRestartTime = 3; // Keyboard restart delay in s +BOOL NewIconsSupport = TRUE; +BOOL ColorIconsSupport = TRUE; + + +WORD ScalosPrefs_IconOffsets[4] = { 1, 1, 1, 1 }; + +struct ScaRootList *rList = NULL; + + +M68KFUNC_P3(ULONG, myHookFunc, + A0, Class *, cl, + A2, Object *, obj, + A1, Msg, msg) +{ + ULONG Result; + + d1(kprintf(__FUNC__ "/%ld: MethodID=%08lx\n", __LINE__, msg->MethodID)); + + rList = (struct ScaRootList *) obj; + + d1(kprintf(__FUNC__ "/%ld: rList=%08lx\n", __LINE__, rList);) + + switch (msg->MethodID) + { + case SCCM_IconWin_RawKey: + { + struct msg_RawKey *mrk = (struct msg_RawKey *) msg; + + DoKeyboardCommand(mrk->mrk_iMsg); + + Result = DoSuperMethodA(cl, obj, msg); + } + break; + + default: + Result = DoSuperMethodA(cl, obj, msg); + break; + } + + return Result; +} +M68KFUNC_END + + +BOOL initPlugin(void) +{ + d(kprintf(__FUNC__ "/%ld: \n", __LINE__)); + + if (!fInit) + { + if (!OpenLibraries()) + return FALSE; + + d(kprintf(__FUNC__ "/%ld: IconobjectBase=%08lx WorkbenchBase=%08lx UtilityBase=%08lx\n", \ + __LINE__, IconobjectBase, WorkbenchBase, UtilityBase)); + + rList = GetScalosRootList(); + d1(kprintf(__FUNC__ "/%ld: ScaRootList=%08lx\n", __LINE__, rList)); + + fInit = StartWBRexxProcess(); + + if (fInit) + { + // try to use current WB settings + ParseWBPrefs("ENV:sys/Workbench.prefs"); + + // Read some Scalos preferences settings + ReadScalosPrefs(); + } + else + closePlugin(); + + return fInit; + } + + return TRUE; +} + + +VOID closePlugin(void) +{ + ShutdownWBRexxProcess(); + + CloseLibraries(); + + fInit = FALSE; +} + + +static BOOL OpenLibraries(void) +{ + DOSBase = (struct DosLibrary *) OpenLibrary(DOSNAME, 39); + if (NULL == DOSBase) + return FALSE; +#ifdef __amigaos4__ + IDOS = (struct DOSIFace *)GetInterface((struct Library *)DOSBase, "main", 1, NULL); + if (NULL == IDOS) + return FALSE; +#endif //__amigaos4__ + + IconobjectBase = OpenLibrary("iconobject.library", 39); + if (NULL == IconobjectBase) + return FALSE; +#ifdef __amigaos4__ + IIconobject = (struct IconobjectIFace *)GetInterface((struct Library *)IconobjectBase, "main", 1, NULL); + if (NULL == IIconobject) + return FALSE; +#endif //__amigaos4__ + + WorkbenchBase = OpenLibrary(WORKBENCH_NAME, 39); + if (NULL == WorkbenchBase) + return FALSE; +#ifdef __amigaos4__ + IWorkbench = (struct WorkbenchIFace *)GetInterface((struct Library *)WorkbenchBase, "main", 1, NULL); + if (NULL == IWorkbench) + return FALSE; +#endif //__amigaos4__ + + UtilityBase = (T_UTILITYBASE) OpenLibrary("utility.library", 39); + if (NULL == UtilityBase) + return FALSE; +#ifdef __amigaos4__ + IUtility = (struct UtilityIFace *)GetInterface((struct Library *)UtilityBase, "main", 1, NULL); + if (NULL == IUtility) + return FALSE; +#endif +#if defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) + __UtilityBase = UtilityBase; +#endif /* defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) */ + + ScalosBase = (struct ScalosBase *) OpenLibrary(SCALOSNAME, 41); + if (NULL == ScalosBase) + return FALSE; +#ifdef __amigaos4__ + IScalos = (struct ScalosIFace *)GetInterface((struct Library *)ScalosBase, "main", 1, NULL); + if (NULL == IScalos) + return FALSE; +#endif //__amigaos4__ + + // keep library open count at 0 otherwise Scalos will refuse to quit + CloseLibrary((struct Library *) ScalosBase); + + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + if (NULL == IntuitionBase) + return FALSE; +#ifdef __amigaos4__ + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + return FALSE; +#endif //__amigaos4__ + + LayersBase = OpenLibrary("layers.library", 39); + if (NULL == LayersBase) + return FALSE; +#ifdef __amigaos4__ + ILayers = (struct LayersIFace *)GetInterface((struct Library *)LayersBase, "main", 1, NULL); + if (NULL == ILayers) + return FALSE; +#endif //__amigaos4__ + + GfxBase = OpenLibrary("graphics.library", 39); + if (NULL == GfxBase) + return FALSE; +#ifdef __amigaos4__ + IGraphics = (struct GraphicsIFace *)GetInterface((struct Library *)GfxBase, "main", 1, NULL); + if (NULL == IGraphics) + return FALSE; +#endif //__amigaos4__ + + IconBase = OpenLibrary("icon.library", 39); + if (NULL == IconBase) + return FALSE; +#ifdef __amigaos4__ + IIcon = (struct IconIFace *)GetInterface((struct Library *)IconBase, "main", 1, NULL); + if (NULL == IIcon) + return FALSE; +#endif //__amigaos4__ + + IFFParseBase = OpenLibrary("iffparse.library", 39); + if (NULL == IFFParseBase) + return FALSE; +#ifdef __amigaos4__ + IIFFParse = (struct IFFParseIFace *)GetInterface((struct Library *)IFFParseBase, "main", 1, NULL); + if (NULL == IIFFParse) + return FALSE; +#endif //__amigaos4__ + + LocaleBase = (T_LOCALEBASE *) OpenLibrary("locale.library", 39); + if (NULL == LocaleBase) + return FALSE; +#ifdef __amigaos4__ + ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL); + if (NULL == ILocale) + return FALSE; + +#endif //__amigaos4__ + AmigaGuideBase = OpenLibrary("amigaguide.library", 39); + if (NULL == AmigaGuideBase) + return FALSE; +#ifdef __amigaos4__ + IAmigaGuide = (struct AmigaGuideIFace *)GetInterface((struct Library *)AmigaGuideBase, "main", 1, NULL); + if (NULL == IAmigaGuide) + return FALSE; +#endif //__amigaos4__ + + CxBase = OpenLibrary("commodities.library", 39); + if (NULL == CxBase) + return FALSE; + +#ifdef __amigaos4__ + ICommodities = (struct CommoditiesIFace *)GetInterface((struct Library *)CxBase, "main", 1, NULL); + if (NULL == ICommodities) + return FALSE; + + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + return FALSE; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + return FALSE; +#endif //__amigaos4__ + + return TRUE; +} + + +static void CloseLibraries(void) +{ +#ifdef __amigaos4__ + if (INewlib) + { + DropInterface(INewlib); + INewlib = NULL; + } + if (NewlibBase) + { + CloseLibrary(NewlibBase); + NewlibBase = NULL; + } + if (ICommodities) + { + DropInterface((struct Interface *)ICommodities); + ICommodities = NULL; + } +#endif //__amigaos4__ + if (CxBase) + { + CloseLibrary(CxBase); + CxBase = NULL; + } + +#ifdef __amigaos4__ + if (ILocale) + { + DropInterface((struct Interface *) ILocale); + ILocale = NULL; + } +#endif //__amigaos4__ + if (LocaleBase) + { + CloseLibrary((struct Library *) LocaleBase); + LocaleBase = NULL; + } + +#ifdef __amigaos4__ + if (IAmigaGuide) + { + DropInterface((struct Interface *) IAmigaGuide); + IAmigaGuide = NULL; + } +#endif //__amigaos4__ + if (AmigaGuideBase) + { + CloseLibrary(AmigaGuideBase); + AmigaGuideBase = NULL; + } + +#ifdef __amigaos4__ + if (IIFFParse) + { + DropInterface((struct Interface *)IIFFParse); + IIFFParse = NULL; + } +#endif //__amigaos4__ + if (IFFParseBase) + { + CloseLibrary(IFFParseBase); + IFFParseBase = NULL; + } +#ifdef __amigaos4__ + if (IIcon) + { + DropInterface((struct Interface *)IIcon); + IIcon = NULL; + } +#endif //__amigaos4__ + if (IconBase) + { + CloseLibrary(IconBase); + IconBase = NULL; + } +#ifdef __amigaos4__ + if (IGraphics) + { + DropInterface((struct Interface *)IGraphics); + IGraphics = NULL; + } +#endif //__amigaos4__ + if (GfxBase) + { + CloseLibrary(GfxBase); + GfxBase = NULL; + } +#ifdef __amigaos4__ + if (IDOS) + { + DropInterface((struct Interface *)IDOS); + IDOS = NULL; + } +#endif //__amigaos4__ + if (DOSBase) + { + CloseLibrary((struct Library *) DOSBase); + DOSBase = NULL; + } +#ifdef __amigaos4__ + if (IIconobject) + { + DropInterface((struct Interface *)IIconobject); + IIconobject = NULL; + } +#endif //__amigaos4__ + if (IconobjectBase) + { + CloseLibrary(IconobjectBase); + IconobjectBase = NULL; + } +#ifdef __amigaos4__ + if (IWorkbench) + { + DropInterface((struct Interface *)IWorkbench); + IWorkbench = NULL; + } +#endif //__amigaos4__ + if (WorkbenchBase) + { + CloseLibrary(WorkbenchBase); + WorkbenchBase = NULL; + } +#ifdef __amigaos4__ + if (IUtility) + { + DropInterface((struct Interface *)IUtility); + IUtility = NULL; + } +#endif //__amigaos4__ + if (UtilityBase) + { + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } +#ifdef __amigaos4__ + if (IScalos) + { + DropInterface((struct Interface *)IScalos); + IScalos = NULL; + } +#endif //__amigaos4__ +#if 0 + if (ScalosBase) + { + CloseLibrary((struct Library *) ScalosBase); + ScalosBase = NULL; + } +#endif //0 +#ifdef __amigaos4__ + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } +#endif //__amigaos4__ + if (IntuitionBase) + { + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } +#ifdef __amigaos4__ + if (ILayers) + { + DropInterface((struct Interface *)ILayers); + ILayers = NULL; + } +#endif //__amigaos4__ + if (LayersBase) + { + CloseLibrary(LayersBase); + LayersBase = NULL; + } +} + +#ifdef __SASC + +void _XCEXIT(long x) +{ + (void) x; +} + +#else /* __SASC */ + +#ifndef __amigaos4__ + +void exit(int x) +{ + (void) x; + while (1) + ; +} + +APTR _WBenchMsg; + +#endif /* __amigaos4__ */ + +#endif /* __SASC */ + diff --git a/scalos/Plugins/OOP/wb39_plugin/wbrexx/config.mk b/scalos/Plugins/OOP/wb39_plugin/wbrexx/config.mk new file mode 100755 index 000000000..6b77dec1b --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/wbrexx/config.mk @@ -0,0 +1,72 @@ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +COMMON_DIR = $(TOPLEVEL)/common/Plugin + +INCLUDES += -I. -I$(COMMON_DIR) -I.. + +vpath %.c $(COMMON_DIR) .. + +############################################################################## + +include $(COMMON_DIR)/config.mk + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += -lmempools +# --verbose + +LFLAGS2 = $(LFLAGS) \ + -nostartfiles + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS2 = $(LFLAGS) \ + -nostartfiles \ +# + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +LFLAGS2 = $(LFLAGS) \ + -nostartfiles \ +# + + +else + +############################################################################### +# AmigaOS + +LFLAGS += -lscalos \ + -lpreferences \ + -liconobject \ + -lmempools \ + -lstack \ + -lnix \ + -lnixmain \ + -lamiga21 \ + -lamiga \ + -lstubs \ + +endif +endif +endif diff --git a/scalos/Plugins/OOP/wb39_plugin/wbrexx/makefile b/scalos/Plugins/OOP/wb39_plugin/wbrexx/makefile new file mode 100644 index 000000000..dd2b2a9e4 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/wbrexx/makefile @@ -0,0 +1,129 @@ +# makefile for Scalos wbrexx.plugin +# $Date$ +# using GNU make and SAS/C 6.58 + + +############################################################# + +CC = sc +AS = phxass +PRECOMP = INCLUDE:All.gst +LD = slink +LDFLAGS = quiet batch noicons sd +LDLIBS = LIB:sc.lib \ + LIB:debug.lib \ + LIB:amiga.lib \ + LIB:mempools.lib \ + ////SAS-lib/snprintf.lib \ + LIB:sc.lib +OBJDIR = .sasobj +DESTPLUG = Scalos:Plugins/OOP +COMMON_DIR = ../../../../common/Plugin + +.SUFFIXES: .plugin .plugin.debug + +############################################################# + +# Optimizer Flags +# Ignore Note 306: local function inlined: "InsertMH" +OPT_FLG = OPTIMIZE OPTINLOCAL OPTTIME OPTSCHED IGNORE=306,308 ERROR=87 +OPT_FLG2 = NOOPTIMIZE IGNORE=306,308 ERROR=87 + +ifdef DEBUG + CFLAGS = nostkchk nochkabort dbg=ff nover gst=$(PRECOMP) idlen=64 \ + idir=/ \ + idir=////include \ + idir=$(subst ../,/,$(COMMON_DIR)) + CSTARTUP = LIB:c.o +else + CFLAGS = nostkchk nochkabort $(OPT_FLG) dbg=f def=NDEBUG \ + def=NODEBUG nover gst=$(PRECOMP) idlen=64 \ + idir=/ \ + idir=////include \ + idir=$(subst ../,/,$(COMMON_DIR)) + CSTARTUP = LIB:cback.o +endif + +AFLAGS = quiet I=sc:Assembler_Headers + +############################################################# + +# Files for wbrexx.plugin +WBREXXNAME = wbrexx.plugin + +WBREXXCSRCS = $(COMMON_DIR)/plugin-classic.c \ + WBRexxMain.c \ + WBRexx.c \ + RexxGetAttrs.c \ + RexxIcon.c \ + RexxCmd.c \ + ../Scalos_Helper.c \ + +WBREXXOBJS = $(WBREXXCSRCS:%.c=$(OBJDIR)/%.o) + +############################################################# + +all: $(WBREXXNAME) \ + $(WBREXXNAME).debug \ +# install +# clean + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +XSRCS = $(notdir $(WBREXXCSRCS)) +WBREXXOBJS = $(XSRCS:%.c=$(OBJDIR)/$(notdir %).o) + +############################################################# + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-classic.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/Scalos_Helper.o : ../Scalos_Helper.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $*.c objectname $@ + +############################################################# + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-classic.c \ + $(COMMON_DIR)/plugin-common.c $(COMMON_DIR)/plugin.h plugin_data.h + +$(OBJDIR)/RexxGetAttrs.o $(OBJDIR)/RexxIcon.o $(OBJDIR)/Scalos_Helper.o \ + $(OBJDIR)/WBRexxMain.o : ../wb39.h + +$(OBJDIR)/WBRexx.o $(OBJDIR)/RexxGetAttrs.o $(OBJDIR)/RexxIcon.o \ + $(OBJDIR)/RexxCmd.o : wbrexx.h ../Scalos_Helper.h + +############################################################# + +$(WBREXXNAME): $(WBREXXOBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(WBREXXOBJS) TO $@ LIB $(LDLIBS) $(LDFLAGS) STRIPDEBUG + +$(WBREXXNAME).debug: $(WBREXXOBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(WBREXXOBJS) TO $@ lib $(LDLIBS) $(LDFLAGS) ADDSYM + +############################################################# + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(WBREXXNAME).\033[0m\n' + @copy $(WBREXXNAME) $(DESTPLUG) clone + +############################################################# + +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + -@delete $(OBJS) \ + $(WBREXXNAME) \ + $(WBREXXNAME).debug + @printf '\033[0m' + +############################################################# diff --git a/scalos/Plugins/OOP/wb39_plugin/wbrexx/makefile-new b/scalos/Plugins/OOP/wb39_plugin/wbrexx/makefile-new new file mode 100755 index 000000000..46f21141d --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/wbrexx/makefile-new @@ -0,0 +1,73 @@ +# $Date: 2011-08-02 00:13:23 +0200 (Di, 02. Aug 2011) $ +# $Revision: 816 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../../../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(BEGIN_OBJS) \ + $(OBJDIR)/WBRexxMain.o \ + $(OBJDIR)/WBRexx.o \ + $(OBJDIR)/RexxGetAttrs.o \ + $(OBJDIR)/RexxIcon.o \ + $(OBJDIR)/RexxCmd.o \ + $(OBJDIR)/Scalos_Helper.o \ + $(END_OBJS) + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Targets +# + +NAME = wbrexx.plugin +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + $(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS2) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + copy $(BINDIR)/$(NAME) Scalos:Plugins/OOP clone + + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* + +############################################################################## + + diff --git a/scalos/Plugins/OOP/wb39_plugin/wbrexx/plugin_data.h b/scalos/Plugins/OOP/wb39_plugin/wbrexx/plugin_data.h new file mode 100644 index 000000000..e531582d5 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/wbrexx/plugin_data.h @@ -0,0 +1,36 @@ +// plugin_data.h +// $Date$ +// $Revision$ + +#ifndef PLUGIN_DATA_H_INCLUDED +#define PLUGIN_DATA_H_INCLUDED + +#include +#include + +#define PLUGIN_TYPE OOP + +#define LIB_VERSION 39 +#define LIB_REVISION 22 + +#define LIB_NAME "wbrexx.plugin" +#define LIB_VERSTRING "$VER: wbrexx.plugin " \ + STR(LIB_VERSION) "." STR(LIB_REVISION) \ + " (20.12.2009) " COMPILER_STRING \ + " ©1999" CURRENTYEAR " The Scalos Team" + +#define CI_PRIORITY -79 +#define CI_CLASSNAME "IconWindow.sca" +#define CI_SUPERCLASSNAME "IconWindow.sca" +#define CI_PLUGINNAME "Scalos WBRexx Class" +#define CI_DESCRIPTION "Workbench ARexx support" COMPILER_STRING +#define CI_AUTHOR "Jürgen Lachmann" +#define CI_HOOKFUNC myHookFunc + +//---------------------------------------------------------------------------- +// code and includes to define the structs and functions used above + +#include "wbrexx.h" + +#endif /* PLUGUN_DATA_H_INCLUDED */ + diff --git a/scalos/Plugins/OOP/wb39_plugin/wbrexx/rxtest.rexx b/scalos/Plugins/OOP/wb39_plugin/wbrexx/rxtest.rexx new file mode 100755 index 000000000..6fd184184 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/wbrexx/rxtest.rexx @@ -0,0 +1,246 @@ +/* rxtest.rexx */ +/* Test file for WBRexx.plugin */ +/* 11 Jan 2001 17:41:47 */ + +options results + +address workbench + +say "-----------------------------------------------------" + +say "Application.Version" +getattr application.version var xyzzy +res = result + +say "result = <" || res || ">" +say "xyzzy = <" || xyzzy || ">" + + + +say "Application.screen" +getattr application.screen var "xyzzy1" +res = result + +say "result = <" || res || ">" +say "xyzzy1 = <" || xyzzy1 || ">" + + +say "Aplication.arexx" +getattr application.arexx var xyzzy2 +res = result + +say "result = <" || res || ">" +say "xyzzy = <" || xyzzy2 || ">" + +if rc > 0 then do + getattr application.lasterror + res = result + fault code res + say "lasterror =" result + end + + +say "Aplication.iconborder" +getattr application.iconborder +res = result +say "result = <" || res || ">" + + + +say "-----------------------------------------------------" + +say "windows" +getattr windows.count VAR wincount +say "Windows.Count = <" || wincount || ">" + +getattr windows stem win +res = result + +do n = 0 to wincount-1 + say "win." || n || " = <" || win.n || ">" +end + +if rc > 0 then do + getattr application.lasterror + res = result + fault code res + say "lasterror =" result + end +say + + +wn = wincount - 1 + +getattr windows.wn var win3 +res = result +say "windows.3 = <" || win3 || ">" +say + + +say "this one ought to return an error:" +wn = wincount + 4 +getattr windows.wn var win4 +res = result +say "windows.13 = <" || win4 || ">" +if rc > 0 then do + getattr application.lasterror + res = result + fault code res + say "lasterror =" result + end +say + +/* +say "application" +getattr application stem app1 +say "Version =" app1.version +say "LastError =" app1.lasterror +say "IconBorder =" app1.iconborder +*/ + + +say "-----------------------------------------------------" + +say "Selected Icons list in Root window" +getattr window.icons.selected name "root" stem rootwin +res = result +if rc > 0 then do + getattr application.lasterror + res = result + fault code res + say "lasterror =" result + end + +say "Count =" rootwin.count + +do n = 0 to rootwin.count-1 + say n + say "Name =" rootwin.n.name + say "Left =" rootwin.n.left + say "Top =" rootwin.n.top + say "Width =" rootwin.n.width + say "Height =" rootwin.n.height + say "Type =" rootwin.n.type + say "Status =" rootwin.n.status +end +say + + +say "-----------------------------------------------------" +say "KeyCommands" +getattr keycommands.count VAR kccount +say "keycommands.Count = <" || kccount || ">" + +if kccount > 0 then do + getattr keycommands.0.name var kc + say "<" || kc || ">" + getattr keycommands.0.key var kc2 + say "<" || kc2 || ">" + end + + +getattr keycommands stem kcc +res = result + +do n = 0 to kccount-1 + say "kcc." || n || " Name= <" || kcc.n.name || "> Key= <" || kcc.n.key || "> Cmd= <" || kcc.n.command || ">" +end + +say "-----------------------------------------------------" +say "MenuCommands" +getattr menucommands.count VAR mccount +say "Menucommands.Count = <" || mccount || ">" + +getattr Menucommands stem mcc +res = result + +do n = 0 to mccount-1 + say "mcc." || n || " Name= <" || mcc.n.name || "> Title= <" || mcc.n.title || "> Shortcut= <" || mcc.n.shortcut || "> Cmd= <" || mcc.n.command || ">" +end + + +say "-----------------------------------------------------" + +getattr window.screen name "root" stem rootscreen +say "Screen.name = " rootscreen.name +say "Screen.width = " rootscreen.width +say "Screen.height = " rootscreen.height + +say + +getattr application.font.icon stem iconfont name "Text" +say "font.icon.name = " iconfont.name +say "font.icon.width = " iconfont.width +say "font.icon.height = " iconfont.height +say "font.icon.size = " iconfont.size +say + +getattr application.font.screen stem screenfont name "Text" +say "font.screen.name = " screenfont.name +say "font.screen.width = " screenfont.width +say "font.screen.height = " screenfont.height +say "font.screen.size = " screenfont.size +say + +/* +address command "wait" + +getattr windows.active +res = result +say "Active Window = <" || res || ">" +*/ + + +/* +icon window "HD1-6GB:Bilder" names "normal spezial" right 30 + +icon window "HD1-6GB:Bilder" names "normal" select + +do n = 0 to 3 + icon window "HD1-6GB:Bilder" cycle previous + if rc > 0 then do + getattr application.lasterror + res = result + fault code res + say "lasterror =" result + leave + end + address command "wait" +end +say +*/ + + +icon window "HD1-6GB:PD/BasiliskII" names "src" open +menu window "HD1-6GB:PD/BasiliskII/src" invoke "WINDOW.SHOW.ALLFILES" + +address command "wait" +icon window "HD1-6GB:PD/BasiliskII/src" names "xpram.cpp" makevisible select + +view window "HD1-6GB:PD/BasiliskII" up + + +/* +menu window "HD1-6GB:PD/BasiliskII" invoke "WINDOW.OPENPARENT" +if rc > 0 then do + fault code workbench.lasterror + say "lasterror =" result + end +*/ + + +window "HD1-6GB:PD/BasiliskII" activate +window "active" cycle previous + + +window "RAM:" open +newdrawer "RAM:xyzzy" +rename "RAM:xyzzy" "RAM:BlahBlah" +if rc > 0 then do + fault code workbench.lasterror + say "lasterror =" result + end + + +delete "RAM:BlahBlah" +delete "RAM:Spezial" all diff --git a/scalos/Plugins/OOP/wb39_plugin/wbrexx/rxtest2.rexx b/scalos/Plugins/OOP/wb39_plugin/wbrexx/rxtest2.rexx new file mode 100755 index 000000000..3c194f19c --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/wbrexx/rxtest2.rexx @@ -0,0 +1,17 @@ +/* rxtest2.rexx */ + +OPTIONS RESULTS + +ADDRESS WORKBENCH + +activeWin = "HD1-6GB:Bilder" + +GETATTR WINDOW.ICONS.UNSELECTED.0 NAME '"'||activeWin||'"' STEM IconInfo.0 +say IconInfo.0.name + +GETATTR WINDOW.ICONS.SELECTED.0 NAME '"'||activeWin||'"' STEM IconInfo.0 +say IconInfo.0.name + +GETATTR WINDOW.ICONS.ALL.0 NAME '"'||activeWin||'"' STEM IconInfo.0 +say IconInfo.0.name + diff --git a/scalos/Plugins/OOP/wb39_plugin/wbrexx/rxtest3.rexx b/scalos/Plugins/OOP/wb39_plugin/wbrexx/rxtest3.rexx new file mode 100755 index 000000000..de0b2c420 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/wbrexx/rxtest3.rexx @@ -0,0 +1,27 @@ +/* rxtest3.rexx */ + +OPTIONS RESULTS + +ADDRESS WORKBENCH + +window "Download:" open + +address command "wait" + +getattr object window.icons.all.count name "Download:" var IconCount + +say IconCount || " Icons found." + +getattr object window.icons.all name "Download:" stem icons + +do n = 0 to IconCount-1 + say "Name = <" || icons.n.name || "> Width=" || icons.n.width || " Height=" icons.n.height +end + + +if rc > 0 then do + getattr application.lasterror + res = result + fault code res + say "lasterror =" result + end diff --git a/scalos/Plugins/OOP/wb39_plugin/wbrexx/rxtest4.rexx b/scalos/Plugins/OOP/wb39_plugin/wbrexx/rxtest4.rexx new file mode 100755 index 000000000..79fbe5671 --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/wbrexx/rxtest4.rexx @@ -0,0 +1,18 @@ +/* rxtest4.rexx */ + +OPTIONS RESULTS + + IF ~SHOW(LIBRARIES,'rexxtricks.library') THEN + IF ~ADDLIB('rexxtricks.library',9,-30,38) THEN + quit('Cannot open rexxtricks.library!',10) + + IF ~SHOW('LIBRARIES','rexxreqtools.library') THEN + IF ~ADDLIB('rexxreqtools.library',9,-30,0) THEN + quit('Cannot open rexxreqtools.library!',10) + + IF ~SHOW('LIBRARIES','rexxdossupport.library') THEN + IF ~ADDLIB('rexxdossupport.library',9,-30,0) THEN + quit('Cannot open rexxdossupport.library!',10) + +erg = rtezrequest("Test Request?","_Yes|_No","RxTest4.rexx",) +say "Result was " || erg diff --git a/scalos/Plugins/OOP/wb39_plugin/wbrexx/wbrexx.h b/scalos/Plugins/OOP/wb39_plugin/wbrexx/wbrexx.h new file mode 100644 index 000000000..9515efbfd --- /dev/null +++ b/scalos/Plugins/OOP/wb39_plugin/wbrexx/wbrexx.h @@ -0,0 +1,248 @@ +// WBRexx.h +// $Date$ +// $Revision$ + + +#ifndef WBREXX_H_INCLUDED +#define WBREXX_H_INCLUDED + +#define d(x) ; +#define d1(x) ; +#define d2(x) x; + +// from debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +#include +#include + +#include +#include + +struct InvokeMenu + { + const char *ivm_WBmenuName; + BOOL ivm_WindowRequired; + const char *ivm_ScalosMenuName; + ULONG (*ivm_MenuFunc)(struct ScaWindowStruct *swi); + }; + +enum UDataType + { + udaType_Nothing = 0, + udaType_ScaWindowStruct, + udaType_ScaIconNode, + udaType_TextFont, + udaType_Screen, + udaType_KeyCommand, + udaType_MenuCommand, + }; + +struct UData + { + APTR uda_Data; + enum UDataType uda_Type; + }; + +struct LeafData + { + long lres_Result; + + const char *lres_ResultString; // nur wenn lres_Result == RETURN_OK; + + const char *lres_ArgPtr; // Pointer auf nächsten Teil des Object-Namens + + STRPTR *lres_Args; // die originalen Argumente + + struct RexxMsg *lres_Message; + + ULONG lres_Flags; + + char lres_ResultBuffer[128]; + }; + +#define LRESF_ORIGINALNAME 0x00000001 + + +struct LeafCmd + { + const char *lc_Name; + + const struct LeafCmd *lc_Next; // next Leaf on this Level or NULL + + const struct LeafCmd *lc_Sub; // Sub-Tree or NULL; + + struct UData (*lc_Function)(struct UData, struct LeafData *, const char *StemLeaf, ULONG Index); + + ULONG (*lc_GetCount)(struct UData, struct LeafData *); // only if ENUM == lc_Name + }; + +struct RexxHost +{ + APTR UserData; + const struct CmdFunc * CommandTable; + + struct MsgPort * GlobalPort; + UBYTE PortName[1]; +}; + + /* This is for parsing commands the ARexx port receives. We employ + * the dos.library/ReadArgs parser for this purpose. + */ + +struct RexxParseData +{ + struct RDArgs * ReadArgs; + UBYTE Line[512]; /* We allow for commands to be up to + * 511 characters long. This is far + * below the maximum string length + * limit ARexx imposed (32768 + * characters) but should be more + * than sufficient for normal + * applications. + */ + STRPTR Args[32]; /* Up to 32 command arguments are + * allowed. + */ +}; + + /* A table to map command names to functions which + * will handle them. + */ + +struct CmdFunc +{ + STRPTR CommandName; /* Name of the command. */ + STRPTR Template; /* The command template in standard + * AmigaDOS syntax. + */ + + /* Pointer to the function which implements this command. */ + + LONG (*Function)(APTR,struct RexxMsg *,STRPTR *); +}; + +/* The local data used by the functions the host supports. */ + +struct LocalData +{ + struct RexxParseData * ParseData; + struct RexxHost * Host; + struct CmdFunc * CommandTable; /* Pointer to table of commands. */ + struct MsgPort * GlobalPort; /* Copied from RexxHost. */ + STRPTR PortName; /* Copied from RexxHost. */ + ULONG Usage; /* Usage count for Rx command. */ + BOOL Terminate; /* Set to TRUE if host should exit. */ +}; + +/* This is a custom message the Rx command will need if the + * "CONSOLE" keyword is used. + */ + +struct ChildMessage +{ + struct Message Message; /* Common message header. */ + + struct RexxMsg * RexxMsg; /* The client message. */ + STRPTR PortName; /* Copied from LocalData. */ + UBYTE Command[1]; /* Command to execute. */ +}; + + +enum IconState { icst_All, icst_Selected, icst_Unselected }; + + +struct ToolMenuItem + { + struct Node tmi_Node; + STRPTR tmi_Name; // this is the "handle" to refer to this menu item + STRPTR tmi_Title; // the item title + STRPTR tmi_Cmd; // the command string + STRPTR tmi_Shortcut; + + STRPTR tmi_MenuTitle; // menu title for menus NULL for common tool menu items + STRPTR tmi_SubItem; // sub item name or NULL for common tool menu items + + APTR tmi_wbKey; // "key" retrieved by WBAPPMENUA_GetKey + APTR tmi_wbTitleKey; // "key" retrieved by WBAPPMENUA_GetTitleKey + + struct AppObject *tmi_MenuAppObject; + struct AppObject *tmi_ItemAppObject; + struct AppObject *tmi_SubAppObject; + + ULONG tmi_UseCount; + struct ToolMenuItem *tmi_Parent; + }; + +struct KeyboardCommand + { + struct Node kbc_Node; + STRPTR kbc_Name; + STRPTR kbc_Cmd; + STRPTR kbc_Key; + IX kbc_IX; + }; + +//---------------------------------------------------------------------------- + +#if defined(__SASC) +#include +int snprintf(char *, size_t, const char *, /*args*/ ...); +int vsnprintf(char *, size_t, const char *, va_list ap); +#endif /* __SASC */ + +//---------------------------------------------------------------------------- + +// WBRexx.c +LONG DoRexxCommand(CONST_STRPTR Command); +LONG ReturnRexxMsg(struct RexxMsg * Message,CONST_STRPTR Result); +SAVEDS(VOID) RxEntry(VOID); +VOID DeleteChildMessage(struct ChildMessage *ChildMessage); +struct ChildMessage *CreateChildMessage(struct MsgPort *ReplyPort, + CONST_STRPTR Command,struct RexxMsg *RexxMessage); +void ShutdownWBRexxProcess(void); +BOOL StartWBRexxProcess(void); +CONST_STRPTR GetNextArgPart(CONST_STRPTR ArgSrc, STRPTR Buffer, size_t MaxLen); +ULONG AddMenuItem(CONST_STRPTR Name, CONST_STRPTR Title, CONST_STRPTR Cmd, CONST_STRPTR Shortcut); +ULONG RemoveMenuItem(CONST_STRPTR Name); +ULONG AddKeyboardCommand(CONST_STRPTR Name, CONST_STRPTR Key, CONST_STRPTR Cmd); +ULONG RemoveKeyboardCommand(CONST_STRPTR Name); +BOOL DoKeyboardCommand(struct IntuiMessage *iMsg); + + +// RexxGetAttrs.c +LONG Cmd_GetAttr(APTR UserData,struct RexxMsg *Message,STRPTR *Args); + + +// RexxIcon.c +LONG Cmd_Icon(APTR UserData, struct RexxMsg *Message, STRPTR *Args); + + +// RexxCmd.c +LONG Cmd_ActivateWindow(APTR UserData, struct RexxMsg *Message, STRPTR *Args); +LONG Cmd_ChangeWindow(APTR UserData, struct RexxMsg *Message, STRPTR *Args); +LONG Cmd_Delete(APTR UserData, struct RexxMsg *Message, STRPTR *Args); +LONG Cmd_Fault(APTR UserData,struct RexxMsg *Message,STRPTR *Args); +LONG Cmd_Help(APTR UserData,struct RexxMsg *Message,STRPTR *Args); +LONG Cmd_Info(APTR UserData, struct RexxMsg *Message, STRPTR *Args); +LONG Cmd_Keyboard(APTR UserData, struct RexxMsg *Message, STRPTR *Args); +LONG Cmd_LockGUI(APTR UserData, struct RexxMsg *Message, STRPTR *Args); +LONG Cmd_Menu(APTR UserData, struct RexxMsg *Message, STRPTR *Args); +LONG Cmd_MoveWindow(APTR UserData, struct RexxMsg *Message, STRPTR *Args); +LONG Cmd_NewDrawer(APTR UserData, struct RexxMsg *Message, STRPTR *Args); +LONG Cmd_Rename(APTR UserData, struct RexxMsg *Message, STRPTR *Args); +LONG Cmd_Rx(APTR UserData,struct RexxMsg *Message,STRPTR *Args); +LONG Cmd_SizeWindow(APTR UserData, struct RexxMsg *Message, STRPTR *Args); +LONG Cmd_UnlockGUI(APTR UserData, struct RexxMsg *Message, STRPTR *Args); +LONG Cmd_UnzoomWindow(APTR UserData, struct RexxMsg *Message, STRPTR *Args); +LONG Cmd_View(APTR UserData, struct RexxMsg *Message, STRPTR *Args); +LONG Cmd_Window(APTR UserData, struct RexxMsg *Message, STRPTR *Args); +LONG Cmd_WindowToBack(APTR UserData, struct RexxMsg *Message, STRPTR *Args); +LONG Cmd_WindowToFront(APTR UserData, struct RexxMsg *Message, STRPTR *Args); +LONG Cmd_ZoomWindow(APTR UserData, struct RexxMsg *Message, STRPTR *Args); + + +//---------------------------------------------------------------------------- + +#endif diff --git a/scalos/Plugins/Prefs/FileTypes/DefIcons.c b/scalos/Plugins/Prefs/FileTypes/DefIcons.c new file mode 100644 index 000000000..b20bf3d6c --- /dev/null +++ b/scalos/Plugins/Prefs/FileTypes/DefIcons.c @@ -0,0 +1,739 @@ +// DefIcons.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include +#define NO_INLINE_STDARG +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#include "debug.h" +#include "FileTypesPrefs.h" +#include "FileTypesPrefs_proto.h" + +//---------------------------------------------------------------------------- + +// local data structures + +#define IOBUFFERLEN 480 +#define NO_TYPE_NODE ((struct TypeNode *) -1) + +#define DEFICON_THEME_PREFIX "THEME:DefIcons/def_" +#define DEFICON_PATH_PREFIX "ENV:Sys/def_" + +//---------------------------------------------------------------------------- + +// local functions + +static void ReloadDefIcons(struct FileTypesPrefsInst *inst, CONST_STRPTR DefIconPrefsName); +static VOID InitTypeTree(struct FileTypesPrefsInst *inst, + struct TypeNode *parentnode, const UBYTE **desclist); +static struct TypeNode *AllocTypeNode(const UBYTE **description); +static VOID AddSon(struct TypeNode *parent,struct TypeNode *son); +static void DeleteTypeNode(struct TypeNode *tn); +static void AddFileTypesToList(struct FileTypesPrefsInst *inst); +static void AddTypeNodeToList(struct FileTypesPrefsInst *inst, struct TypeNode *tn); +static void AddTypeNodeToFileTypesList(struct FileTypesPrefsInst *inst, struct TypeNode *tn, + struct MUI_NListtree_TreeNode *parentNode); +static BOOL WriteDefIconsNodes(struct FileTypesPrefsInst *inst, BPTR fh, + struct MUI_NListtree_TreeNode *ln, ULONG *Length); +static BOOL WriteDefIconsActions(BPTR fh, const struct FileTypesEntry *fte, ULONG *Length); +static void AddRootTypeNodeToList(struct FileTypesPrefsInst *inst, CONST_STRPTR Name); + +//---------------------------------------------------------------------------- + +// defined in DefaultDefIconsPrefs.c +extern const UBYTE DefaultDeficonsPrefs[]; + +//---------------------------------------------------------------------------- + +LONG InitDefIcons(struct FileTypesPrefsInst *inst, CONST_STRPTR DefIconPrefsName) +{ + CleanupDefIcons(inst); + + inst->fpb_DefIconsInit = TRUE; + + d1(KPrintF(__FILE__ "/%s/%ld: DefIconPrefsName=<%s>\n", __FUNC__, __LINE__, DefIconPrefsName)); + + ReloadDefIcons(inst, DefIconPrefsName); + + AddFileTypesToList(inst); + + return RETURN_OK; +} + + +static void ReloadDefIcons(struct FileTypesPrefsInst *inst, CONST_STRPTR DefIconPrefsName) +{ + if (DefIconPrefsName) + { + inst->fpb_DefIconsSegList = LoadSeg(DefIconPrefsName); + + d1(KPrintF(__FILE__ "/%s/%ld: SegList=%08lx\n", __FUNC__, __LINE__, inst->fpb_DefIconsSegList)); + + if (inst->fpb_DefIconsSegList) + { + const UBYTE *inittable; + + inittable = ((UBYTE *)BADDR(inst->fpb_DefIconsSegList))+4; + InitTypeTree(inst, NO_TYPE_NODE, &inittable); + + d1(KPrintF(__FILE__ "/%s/%ld: RootType=%08lx\n", __FUNC__, __LINE__, inst->fpb_RootType)); + } + } + else + { + // use predefined prefs + const UBYTE *inittable = DefaultDeficonsPrefs; + + InitTypeTree(inst, NO_TYPE_NODE, &inittable); + } +} + + +void CleanupDefIcons(struct FileTypesPrefsInst *inst) +{ + if (inst->fpb_DefIconsInit) + { + if (inst->fpb_RootType) + { + DeleteTypeNode(inst->fpb_RootType); + inst->fpb_RootType = NULL; + } + + if (inst->fpb_DefIconsSegList) + { + UnLoadSeg(inst->fpb_DefIconsSegList); + inst->fpb_DefIconsSegList = (BPTR)NULL; + } + } +} + + +static VOID InitTypeTree(struct FileTypesPrefsInst *inst, + struct TypeNode *parentnode, const UBYTE **desclist) +{ + struct TypeNode *newTn = NULL; + + while (1) + { + switch(**desclist) + { + case TYPE_DOWN_LEVEL: + (*desclist)++; + InitTypeTree(inst, newTn, desclist); + break; + + case TYPE_UP_LEVEL: + (*desclist)++; + /* fall thru next case */ + case TYPE_END: + return; + break; + + default: + if ((newTn = AllocTypeNode(desclist))) /* desclist will be incremented by */ + /* AllocTypeNode */ + { + if (parentnode != NO_TYPE_NODE) + { + AddSon(parentnode, newTn); + } + else + { + if (inst->fpb_RootType) + inst->fpb_RootType->tn_RightBrother = newTn; + else + inst->fpb_RootType = newTn; + } + } + break; + } + } +} + + +static struct TypeNode *AllocTypeNode(const UBYTE **description) +{ + struct TypeNode *nd; + ULONG j; + const UBYTE *arg; + const UBYTE *name; + + j = 0; + name = *description; + arg = name + strlen((char *)name) + 1; + d1(KPrintF(__FILE__ "/%s/%ld: name=<%s>\n", __FUNC__, __LINE__, name)); + while (*arg != ACT_END) + { + j++; + switch(*(arg++)) + { + case ACT_MATCH: + arg = arg + 3 + abs((BYTE)arg[2]); + break; + case ACT_SEARCH: + case ACT_SEARCHSKIPSPACES: + arg = arg + 1 + abs((BYTE)arg[0]); + break; + case ACT_PROTECTION: + arg += 8; + break; + case ACT_FILESIZE: + case ACT_MINSIZEMB: + arg += 4; + break; + case ACT_NAMEPATTERN: + case ACT_DOSDEVICE: + case ACT_DEVICENAME: + case ACT_CONTENTS: + arg = arg + strlen((char *)arg) + 1; + break; + case ACT_DOSTYPE: + arg = arg + 1 + arg[0]; + break; + } + } + + if ((nd = calloc(sizeof(struct TypeNode) + j * sizeof(struct Magic), 1))) + { + nd->tn_Name = (STRPTR) name; + + j = 0; + arg = name + strlen((char *)name) + 1; + while (*arg != ACT_END) + { + switch(nd->tn_Description[j].action = *(arg++)) + { + case ACT_MATCH: + nd->tn_Description[j].arg1 = *(arg++); + nd->tn_Description[j].arg1 <<= 8; + nd->tn_Description[j].arg1 |= *(arg++); + nd->tn_Description[j].arg2 = (BYTE)*(arg++); + nd->tn_Description[j].str = (STRPTR) arg; + arg += abs(nd->tn_Description[j].arg2); + break; + case ACT_SEARCH: + case ACT_SEARCHSKIPSPACES: + nd->tn_Description[j].arg2 = (BYTE)*(arg++); + nd->tn_Description[j].str = (STRPTR) arg; + arg += abs(nd->tn_Description[j].arg2); + break; + case ACT_FILESIZE: + case ACT_MINSIZEMB: + nd->tn_Description[j].arg2 = *(arg++); + nd->tn_Description[j].arg2 <<= 8; + nd->tn_Description[j].arg2 |= *(arg++); + nd->tn_Description[j].arg2 <<= 8; + nd->tn_Description[j].arg2 |= *(arg++); + nd->tn_Description[j].arg2 <<= 8; + nd->tn_Description[j].arg2 |= *(arg++); + break; + case ACT_DOSTYPE: + nd->tn_Description[j].arg2 = (BYTE)*(arg++); + nd->tn_Description[j].str = (STRPTR) arg; + arg += nd->tn_Description[j].arg2; + d1(KPrintF(__FILE__ "/%s/%ld: arg2=%ld str=<%s>\n", __FUNC__, __LINE__, nd->tn_Description[j].arg2, nd->tn_Description[j].str)); + break; + case ACT_NAMEPATTERN: + case ACT_DOSDEVICE: + case ACT_DEVICENAME: + case ACT_CONTENTS: + nd->tn_Description[j].str = (STRPTR) arg; + arg += strlen((char *)arg) + 1; + break; + case ACT_PROTECTION: + nd->tn_Description[j].arg1 = *(arg++); + nd->tn_Description[j].arg1 <<= 8; + nd->tn_Description[j].arg1 |= *(arg++); + nd->tn_Description[j].arg1 <<= 8; + nd->tn_Description[j].arg1 |= *(arg++); + nd->tn_Description[j].arg1 <<= 8; + nd->tn_Description[j].arg1 |= *(arg++); + nd->tn_Description[j].arg2 = *(arg++); + nd->tn_Description[j].arg2 <<= 8; + nd->tn_Description[j].arg2 |= *(arg++); + nd->tn_Description[j].arg2 <<= 8; + nd->tn_Description[j].arg2 |= *(arg++); + nd->tn_Description[j].arg2 <<= 8; + nd->tn_Description[j].arg2 |= *(arg++); + break; + } + + j++; + } + nd->tn_Description[j].action = ACT_END; + } + + *description = arg+1; /* increment *description for recursion */ + + return(nd); +} + + + +static VOID AddSon(struct TypeNode *parent,struct TypeNode *son) +{ + struct TypeNode *nd; + + if (!parent || !son) + return; + + if ((nd = parent->tn_FirstSon)) + { + while (nd->tn_RightBrother) + nd = nd->tn_RightBrother; + + nd->tn_RightBrother = son; + } + else + parent->tn_FirstSon = son; + + son->tn_Parent = parent; +} + + +static void DeleteTypeNode(struct TypeNode *tn) +{ + while (tn) + { + struct TypeNode *tnNext = tn->tn_RightBrother; + + DeleteTypeNode(tn->tn_FirstSon); + + free(tn); + + tn = tnNext; + } +} + + +static void AddFileTypesToList(struct FileTypesPrefsInst *inst) +{ + DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], + MUIM_NListtree_Clear, NULL, 0); + + set(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], MUIA_NListtree_Quiet, TRUE); + + AddTypeNodeToFileTypesList(inst, inst->fpb_RootType, + (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_ListNode_Root); + + // Make sure required root entries are present + AddRootTypeNodeToList(inst, "Project"); + AddRootTypeNodeToList(inst, "Disk"); + + set(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], MUIA_NListtree_Quiet, FALSE); + + // Activate first entry (which should be "project" + set(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], + MUIA_NListtree_Active, MUIV_NListtree_Active_First); + // For some obscure reason, the MUIA_NListtree_Active scrolls the list + // so the first (active) entry is not visible. + set(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], + MUIA_NList_First, MUIV_NList_First_Top); + + if (inst->fpb_FileTypesDirLock) + { + BPTR oldDir; + + oldDir = CurrentDir(inst->fpb_FileTypesDirLock); + + GenerateFileTypesNewEntry(inst, "disk"); + GenerateFileTypesNewEntry(inst, "drawer"); + GenerateFileTypesNewEntry(inst, "trashcan"); + GenerateFileTypesNewEntry(inst, "project"); + GenerateFileTypesNewEntry(inst, "tool"); + GenerateFileTypesNewEntry(inst, "appicon"); + + AddTypeNodeToList(inst, inst->fpb_RootType); + + CurrentDir(oldDir); + } +} + + +static void AddTypeNodeToList(struct FileTypesPrefsInst *inst, struct TypeNode *tn) +{ + while (tn) + { + // avoid duplicate entries + if (0 == DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_FindName, + MUIV_NListtree_FindName_ListNode_Root, + tn->tn_Name, + 0)) + { + GenerateFileTypesNewEntry(inst, (STRPTR) tn->tn_Name); + } + + AddTypeNodeToList(inst, tn->tn_FirstSon); + + tn = tn->tn_RightBrother; + } +} + + +static void AddTypeNodeToFileTypesList(struct FileTypesPrefsInst *inst, struct TypeNode *tn, + struct MUI_NListtree_TreeNode *parentNode) +{ + while (tn) + { + struct MUI_NListtree_TreeNode *lnNew; + + d1(KPrintF(__FILE__ "/%s/%ld: tn=%08lx <%s> Next=%08lx Son=%08lx\n", \ + __FUNC__, __LINE__, tn, tn->tn_Name, tn->tn_RightBrother, tn->tn_FirstSon)); + + lnNew = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], + MUIM_NListtree_Insert, + tn->tn_Name, + tn, + parentNode, + MUIV_NListtree_Insert_PrevNode_Tail, + TNF_LIST | TNF_OPEN); + + d1(KPrintF(__FILE__ "/%s/%ld: parentNode=%08lx lnNew=%08lx\n", __FUNC__, __LINE__, parentNode, lnNew)); + + if (tn->tn_FirstSon) + AddTypeNodeToFileTypesList(inst, tn->tn_FirstSon, lnNew); + + tn = tn->tn_RightBrother; + } +} + +//---------------------------------------------------------------------------- + +BOOL WriteDefIconsPrefs(struct FileTypesPrefsInst *inst, CONST_STRPTR FileName) +{ + static ULONG DefIconHeader[8]; + static ULONG DefIconTrailer[1]; + BPTR fh; + BOOL Success = FALSE; + + DefIconHeader[0] = SCA_LONG2BE(HUNK_HEADER); + DefIconHeader[1] = 0; + DefIconHeader[2] = SCA_LONG2BE(1); + DefIconHeader[3] = 0; + DefIconHeader[4] = 0; + DefIconHeader[5] = 0; // HunkLength must be written here + DefIconHeader[6] = SCA_LONG2BE(HUNK_DATA); + DefIconHeader[7] = 0; // HunkLength must be written here + + DefIconTrailer[0] = SCA_LONG2BE(HUNK_END); + + do { + ULONG HunkLength = 0; + ULONG HunkLengthBE = 0; // Hunk length in big endian + struct MUI_NListtree_TreeNode *ln; + + fh = Open(FileName, MODE_NEWFILE); + if ((BPTR)NULL == fh) + break; + + if (0 != SetVBuf(fh, NULL, BUF_FULL, 2048)) + break; + + // write HUNK_HEADER and HUNK_DATA + if (1 != FWrite(fh, (APTR) DefIconHeader, sizeof(DefIconHeader), 1)) + break; + + // get the very first root level node + ln = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Root, + MUIV_NListtree_GetEntry_Position_Head, + 0); + if (NULL == ln) + break; + + do { + if (!WriteDefIconsNodes(inst, fh, ln, &HunkLength)) + break; + + // get next root level node + ln = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Root, + MUIV_NListtree_GetEntry_Position_Next, + MUIV_NListtree_GetEntry_Flag_SameLevel); + } while (ln); + + FPutC(fh, TYPE_END); + HunkLength++; + + // pad with 0x00 until length is multiple of sizeof(ULONG) + while (HunkLength & 0x03) + { + d1(KPrintF(__FILE__ "/%s/%ld: HunkLength=%lu\n", __FUNC__, __LINE__, HunkLength)); + FPutC(fh, 0); + HunkLength++; + } + + // write HUNK_END + if (1 != FWrite(fh, (APTR) DefIconTrailer, sizeof(DefIconTrailer), 1)) + break; + + HunkLength /= sizeof(ULONG); + + // Write hunk length in H_HEADER + Seek(fh, 5 * sizeof(ULONG), OFFSET_BEGINNING); + + HunkLengthBE = SCA_LONG2BE(HunkLength); + if (1 != FWrite(fh, &HunkLengthBE, sizeof(HunkLengthBE), 1)) + break; + + // Write hunk length in H_DATA + Seek(fh, 7 * sizeof(ULONG), OFFSET_BEGINNING); + + HunkLengthBE = SCA_LONG2BE(HunkLength); + if (1 != FWrite(fh, &HunkLengthBE, sizeof(HunkLengthBE), 1)) + break; + + Success = TRUE; + } while (0); + + if (fh) + Close(fh); + + return Success; +} + +//---------------------------------------------------------------------------- + +static BOOL WriteDefIconsNodes(struct FileTypesPrefsInst *inst, BPTR fh, + struct MUI_NListtree_TreeNode *ln, ULONG *Length) +{ + BOOL Success = TRUE; + + while (ln && Success) + { + const struct FileTypesEntry *fte = (const struct FileTypesEntry *) ln->tn_User; + struct MUI_NListtree_TreeNode *lnSub; + ULONG len; + + // write TypeNode name, including trailing "\0" + len = 1 + strlen((char *)fte->fte_TypeNode.tn_Name); + if (1 != FWrite(fh, fte->fte_TypeNode.tn_Name, len, 1)) + { + Success = FALSE; + break; + } + *Length += len; + + if (!WriteDefIconsActions(fh, fte, Length)) + { + Success = FALSE; + break; + } + + lnSub = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], + MUIM_NListtree_GetEntry, + ln, + MUIV_NListtree_GetEntry_Position_Head, + 0); + if (lnSub) + { + FPutC(fh, TYPE_DOWN_LEVEL); + (*Length)++; + + if (!WriteDefIconsNodes(inst, fh, lnSub, Length)) + { + Success = FALSE; + break; + } + + FPutC(fh, TYPE_UP_LEVEL); + (*Length)++; + } + + // get next node + ln = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], + MUIM_NListtree_GetEntry, + ln, + MUIV_NListtree_GetEntry_Position_Next, + MUIV_NListtree_GetEntry_Flag_SameLevel); + } + + return Success; +} + +//---------------------------------------------------------------------------- + +static BOOL WriteDefIconsActions(BPTR fh, const struct FileTypesEntry *fte, ULONG *Length) +{ + BOOL Success = TRUE; + struct FileTypesActionListEntry *ftale; + + for (ftale = (struct FileTypesActionListEntry *) fte->fte_MagicList.lh_Head; + Success && ftale != (struct FileTypesActionListEntry *) &fte->fte_MagicList.lh_Tail; + ftale = (struct FileTypesActionListEntry *) ftale->ftale_Node.ln_Succ) + { + ULONG len; + + d1(KPrintF(__FILE__ "/%s/%ld: ftale=%08lx action=%ld\n", \ + __FUNC__, __LINE__, ftale, ftale->ftale_Magic.action)); + + FPutC(fh, ftale->ftale_Magic.action); + (*Length)++; + + switch (ftale->ftale_Magic.action) + { + case ACT_SEARCH: + case ACT_SEARCHSKIPSPACES: + FPutC(fh, (UBYTE) ftale->ftale_Magic.arg2); + (*Length)++; + len = abs(ftale->ftale_Magic.arg2); + if (1 != FWrite(fh, ftale->ftale_Magic.str, len, 1)) + { + Success = FALSE; + break; + } + *Length += len; + break; + case ACT_MATCH: + FPutC(fh, (UBYTE) (ftale->ftale_Magic.arg1 >> 8)); + (*Length)++; + FPutC(fh, (UBYTE) ftale->ftale_Magic.arg1); + (*Length)++; + FPutC(fh, (UBYTE) ftale->ftale_Magic.arg2); + (*Length)++; + + len = abs(ftale->ftale_Magic.arg2); + if (1 != FWrite(fh, ftale->ftale_Magic.str, len, 1)) + { + Success = FALSE; + break; + } + *Length += len; + break; + case ACT_NAMEPATTERN: + case ACT_DOSDEVICE: + case ACT_DEVICENAME: + case ACT_CONTENTS: + len = 1 + strlen(ftale->ftale_Magic.str); + if (1 != FWrite(fh, ftale->ftale_Magic.str, len, 1)) + { + Success = FALSE; + break; + } + *Length += len; + break; + case ACT_PROTECTION: + FPutC(fh, (UBYTE) (ftale->ftale_Magic.arg1 >> 24)); + (*Length)++; + FPutC(fh, (UBYTE) (ftale->ftale_Magic.arg1 >> 16)); + (*Length)++; + FPutC(fh, (UBYTE) (ftale->ftale_Magic.arg1 >> 8)); + (*Length)++; + FPutC(fh, (UBYTE) ftale->ftale_Magic.arg1); + (*Length)++; + + FPutC(fh, (UBYTE) (ftale->ftale_Magic.arg2 >> 24)); + (*Length)++; + FPutC(fh, (UBYTE) (ftale->ftale_Magic.arg2 >> 16)); + (*Length)++; + FPutC(fh, (UBYTE) (ftale->ftale_Magic.arg2 >> 8)); + (*Length)++; + FPutC(fh, (UBYTE) ftale->ftale_Magic.arg2); + (*Length)++; + break; + case ACT_FILESIZE: + case ACT_MINSIZEMB: + FPutC(fh, (UBYTE) (ftale->ftale_Magic.arg2 >> 24)); + (*Length)++; + FPutC(fh, (UBYTE) (ftale->ftale_Magic.arg2 >> 16)); + (*Length)++; + FPutC(fh, (UBYTE) (ftale->ftale_Magic.arg2 >> 8)); + (*Length)++; + FPutC(fh, (UBYTE) ftale->ftale_Magic.arg2); + (*Length)++; + break; + case ACT_DOSTYPE: + FPutC(fh, (UBYTE) ftale->ftale_Magic.arg2); + (*Length)++; + + len = ftale->ftale_Magic.arg2; + if (1 != FWrite(fh, ftale->ftale_Magic.str, len, 1)) + { + Success = FALSE; + break; + } + *Length += len; + break; + default: + case ACT_END: + case ACT_ISASCII: + case ACT_OR: + case ACT_MACROCLASS: + // no additional parameters here + break; + } + } + + FPutC(fh, ACT_END); + (*Length)++; + + return Success; +} + +//---------------------------------------------------------------------------- + +static void AddRootTypeNodeToList(struct FileTypesPrefsInst *inst, CONST_STRPTR Name) +{ + d1(KPrintF(__FILE__ "/%s/%ld: Name=<%s>\n", __FUNC__, __LINE__, Name)); + + if (0 == DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], + MUIM_NListtree_FindName, + MUIV_NListtree_FindName_ListNode_Root, + Name, + MUIV_NListtree_FindName_Flag_SameLevel)) + { + struct TypeNode tn; + + d1(KPrintF(__FILE__ "/%s/%ld: Name=<%s> not found, creating new\n", __FUNC__, __LINE__, Name)); + + tn.tn_RightBrother = tn.tn_FirstSon = tn.tn_Parent = NULL; + tn.tn_IconObject = NULL; + tn.tn_Name = (STRPTR) Name; + tn.tn_Description[0].action = ACT_END; + + AddTypeNodeToFileTypesList(inst, &tn, + (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_ListNode_Root); + } +} + +//---------------------------------------------------------------------------- + + diff --git a/scalos/Plugins/Prefs/FileTypes/DefIconsPrefs.c b/scalos/Plugins/Prefs/FileTypes/DefIconsPrefs.c new file mode 100644 index 000000000..9bb5d62c1 --- /dev/null +++ b/scalos/Plugins/Prefs/FileTypes/DefIconsPrefs.c @@ -0,0 +1,2010 @@ +// DefIconsPrefs.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include +#include +#define NO_INLINE_STDARG +#include + +#include + +#include +#include +#include + +#define ScalosFileTypes_NUMBERS +#include STR(SCALOSLOCALE) + +#include +#include +#include + +#include + +#include "debug.h" +#include "FileTypesPrefs.h" +#include "FileTypesPrefs_proto.h" +#include "IconobjectMCC.h" + +//---------------------------------------------------------------------------- + +// local data structures + +#define IOBUFFERLEN 480 + +#define DEFICON_THEME_PREFIX "THEME:DefIcons/def_" +#define DEFICON_PATH_PREFIX "ENV:Sys/def_" + +#define IS_CASE_SENSITIVE(magic) ((magic)->arg2 >= 0) + +enum ProtectionMode + { + PROT_Set, + PROT_Unset, + PROT_Ignore, + }; + +//---------------------------------------------------------------------------- + +// defined in FileTypesPrefs.c +extern STRPTR AddFileTypeActionStrings[]; +extern STRPTR AddFileTypeActionStringsProject[]; +extern STRPTR AddFileTypeActionStringsDisk[]; + +//---------------------------------------------------------------------------- + +static void FillFileTypesActions(struct FileTypesPrefsInst *inst, + struct FileTypesEntry *fte, BOOL IsRootEntry); +static void TranslateMatchStringToPrintable(STRPTR Dest, size_t DestLength, + CONST_STRPTR Src, size_t SrcLength); +static void GetProtectionString(STRPTR Buffer, size_t BuffSize, + ULONG AndMask, ULONG CmpMask); +static STRPTR GetProtectionBitString(ULONG BitMask, ULONG AndMask, ULONG CmpMask, + ULONG MsgIdSet, ULONG MsgIdCleared, + STRPTR Buffer, size_t *BuffSize); +static void SetProtectionCycle(Object *o, ULONG BitMask, + ULONG AndMask, ULONG CmpMask); +static void SetMagicString(struct FileTypesActionEntry *fae, CONST_STRPTR String, size_t Length); +static size_t TranslateFromPrintable(STRPTR Buffer, size_t BuffLength, + CONST_STRPTR InputString); +static UBYTE HexValue(char ch); +static void SetProtectionBits(struct FileTypesActionEntry *fae, + enum ProtectionMode Protect, ULONG Mask); +static struct FileTypesActionListEntry *AddFileTypesAction(struct FileTypesEntry *fte, + const struct Magic *curr, struct Node *PrevNode); +static void CleanupFileTypesActions(struct FileTypesEntry *fte); +static ULONG GetActionFromString(CONST_STRPTR ActionString); +static void DefIconFullName(struct FileTypesPrefsInst *inst, + STRPTR Path, size_t MaxLen, CONST_STRPTR FileTypeName); +static void InvokeWBInfo(struct FileTypesPrefsInst *inst, + BPTR DirLock, STRPTR DefIconName); +static void SelectFileType(struct FileTypesPrefsInst *inst, const struct TypeNode *tn); +static struct MUI_NListtree_TreeNode *GetRootEntry(struct FileTypesPrefsInst *inst, + struct MUI_NListtree_TreeNode *ln); + +//---------------------------------------------------------------------------- + +static void FillFileTypesActions(struct FileTypesPrefsInst *inst, + struct FileTypesEntry *fte, BOOL IsRootEntry) +{ + d1(KPrintF(__FILE__ "/%s/%ld: fte=%08lx <%s> IsRootEntry=%ld\n", __FUNC__, __LINE__, fte, fte->fte_TypeNode.tn_Name, IsRootEntry)); + + if (fte) + { + struct FileTypesActionListEntry *ftale; + + // OBJNDX_String_FileTypes_Name is read-only for root entries + set(inst->fpb_Objects[OBJNDX_String_FileTypes_Name], + MUIA_Disabled, IsRootEntry); + + set(inst->fpb_Objects[OBJNDX_String_FileTypes_Name], MUIA_String_Contents, + fte->fte_TypeNode.tn_Name); + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_Clear); + set(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + + + for (ftale = (struct FileTypesActionListEntry *) fte->fte_MagicList.lh_Head; + ftale != (struct FileTypesActionListEntry *) &fte->fte_MagicList.lh_Tail; + ftale = (struct FileTypesActionListEntry *) ftale->ftale_Node.ln_Succ) + { + d1(KPrintF(__FILE__ "/%s/%ld: ftale=%08lx action=%ld\n", \ + __FUNC__, __LINE__, ftale, ftale->ftale_Magic.action)); + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_InsertSingle, + ftale, + MUIV_NList_Insert_Bottom); + } + + set(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIA_NList_Quiet, MUIV_NList_Quiet_None); + } +} + +//---------------------------------------------------------------------------- + +SAVEDS(APTR) INTERRUPT FileTypesActionConstructFunc(struct Hook *hook, APTR obj, struct NList_ConstructMessage *ltcm) +{ + struct FileTypesActionListEntry *ftale = ltcm->entry; + struct FileTypesActionEntry *fae = (struct FileTypesActionEntry *) AllocPooled(ltcm->pool, sizeof(struct FileTypesActionEntry)); + + d1(KPrintF(__FILE__ "/%s/%ld: obj=%08lx ltcm=%08lx memPool=%08lx UserData=%08lx\n", \ + __FUNC__, __LINE__, obj, ltcm, ltcm->pool, ltcm->entry)); + d1(KPrintF(__FILE__ "/%s/%ld: fae=%08lx\n", __FUNC__, __LINE__, fae)); + + if (fae) + { + fae->fae_ftale = ftale; + } + + return fae; +} + +SAVEDS(void) INTERRUPT FileTypesActionDestructFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm) +{ + struct FileTypesActionEntry *fae = ltdm->entry; + + d1(KPrintF(__FILE__ "/%s/%ld: fae=%08lx\n", __FUNC__, __LINE__, fae)); + if (fae) + { + FreePooled(ltdm->pool, fae, sizeof(struct FileTypesActionEntry)); + ltdm->entry = NULL; + } +} + +SAVEDS(ULONG) INTERRUPT FileTypesActionDisplayFunc(struct Hook *hook, APTR obj, struct NList_DisplayMessage *ltdm) +{ + struct FileTypesActionEntry *fae = ltdm->entry; + + d1(KPrintF(__FILE__ "/%s/%ld: fae=%08lx\n", __FUNC__, __LINE__, fae)); + + if (fae) + { + char TempString[80]; + + d1(KPrintF(__FILE__ "/%s/%ld: action=%d\n", __FUNC__, __LINE__, fae->fae_ftale->ftale_Magic.action)); + + ltdm->preparses[0] = ""; + + strcpy(fae->fae_ActionAttrs, ""); + + switch (fae->fae_ftale->ftale_Magic.action) + { + case ACT_MATCH: + ltdm->strings[0] = AddFileTypeActionStrings[0]; + TranslateMatchStringToPrintable(TempString, sizeof(TempString), + fae->fae_ftale->ftale_Magic.str, abs(fae->fae_ftale->ftale_Magic.arg2)); + sprintf(fae->fae_ActionAttrs, "%lu \"%s\"%s", + (unsigned long) fae->fae_ftale->ftale_Magic.arg1, + TempString, + IS_CASE_SENSITIVE(&fae->fae_ftale->ftale_Magic) ? GetLocString(MSGID_FILETYPESACTION_CASE_SENSITIVE) : (STRPTR) ""); + break; + case ACT_SEARCH: + ltdm->strings[0] = AddFileTypeActionStrings[1]; + TranslateMatchStringToPrintable(TempString, sizeof(TempString), + fae->fae_ftale->ftale_Magic.str, abs(fae->fae_ftale->ftale_Magic.arg2)); + sprintf(fae->fae_ActionAttrs, "\"%s\"%s", + TempString, + IS_CASE_SENSITIVE(&fae->fae_ftale->ftale_Magic) ? GetLocString(MSGID_FILETYPESACTION_CASE_SENSITIVE) : (STRPTR) ""); + break; + case ACT_SEARCHSKIPSPACES: + ltdm->strings[0] = AddFileTypeActionStrings[1]; + TranslateMatchStringToPrintable(TempString, sizeof(TempString), + fae->fae_ftale->ftale_Magic.str, abs(fae->fae_ftale->ftale_Magic.arg2)); + sprintf(fae->fae_ActionAttrs, "\"%s\"%s%s", + TempString, + GetLocString(MSGID_FILETYPESACTION_SKIP_SPACES), + IS_CASE_SENSITIVE(&fae->fae_ftale->ftale_Magic) ? GetLocString(MSGID_FILETYPESACTION_CASE_SENSITIVE) : (STRPTR) ""); + break; + case ACT_DOSDEVICE: + ltdm->strings[0] = AddFileTypeActionStrings[7]; + sprintf(fae->fae_ActionAttrs, "\"%s\"", fae->fae_ftale->ftale_Magic.str); + break; + case ACT_DEVICENAME: + ltdm->strings[0] = AddFileTypeActionStrings[8]; + sprintf(fae->fae_ActionAttrs, "\"%s\"", fae->fae_ftale->ftale_Magic.str); + break; + case ACT_CONTENTS: + ltdm->strings[0] = AddFileTypeActionStrings[9]; + sprintf(fae->fae_ActionAttrs, "\"%s\"", fae->fae_ftale->ftale_Magic.str); + break; + case ACT_DOSTYPE: + ltdm->strings[0] = AddFileTypeActionStrings[10]; + TranslateMatchStringToPrintable(TempString, sizeof(TempString), + fae->fae_ftale->ftale_Magic.str, abs(fae->fae_ftale->ftale_Magic.arg2)); + sprintf(fae->fae_ActionAttrs, "\"%s\"", TempString); + break; + case ACT_MINSIZEMB: + ltdm->strings[0] = AddFileTypeActionStrings[11]; + sprintf(fae->fae_ActionAttrs, + GetLocString(MSGID_FILETYPESACTION_MINSIZEMB), + fae->fae_ftale->ftale_Magic.arg2); + break; + case ACT_FILESIZE: + ltdm->strings[0] = AddFileTypeActionStrings[2]; + sprintf(fae->fae_ActionAttrs, + GetLocString(MSGID_FILETYPESACTION_FILESIZE), + fae->fae_ftale->ftale_Magic.arg2); + break; + case ACT_NAMEPATTERN: + ltdm->strings[0] = AddFileTypeActionStrings[3]; + sprintf(fae->fae_ActionAttrs, "\"%s\"", fae->fae_ftale->ftale_Magic.str); + break; + case ACT_PROTECTION: + ltdm->strings[0] = AddFileTypeActionStrings[4]; + GetProtectionString(fae->fae_ActionAttrs, sizeof(fae->fae_ActionAttrs), + fae->fae_ftale->ftale_Magic.arg1, fae->fae_ftale->ftale_Magic.arg2); + break; + case ACT_OR: + strcpy(fae->fae_ActionAttrs, "\033C"); + ltdm->strings[0] = AddFileTypeActionStrings[5]; + break; + case ACT_ISASCII: + ltdm->strings[0] = AddFileTypeActionStrings[6]; + break; + case ACT_MACROCLASS: + ltdm->strings[0] = AddFileTypeActionStrings[12]; + break; + case ACT_END: + default: + ltdm->strings[0] = "???"; + break; + } + + ltdm->strings[1] = fae->fae_ActionAttrs; + } + else + { + // display titles + ltdm->preparses[0] = ""; + + ltdm->strings[0] = ""; + } + + return 0; +} + +//---------------------------------------------------------------------------- + +static void TranslateMatchStringToPrintable(STRPTR Dest, size_t DestLength, + CONST_STRPTR Src, size_t SrcLength) +{ + while (SrcLength && DestLength > 1) + { + if (isprint(*Src) && isascii(*Src)) + { + *Dest++ = *Src++; + SrcLength--; + DestLength--; + } + else + { + if (DestLength < 4 + 1) + break; + sprintf(Dest, "\\x%02x", *Src); + Src++; + SrcLength--; + DestLength -= strlen(Dest); + Dest += strlen(Dest); + } + } + *Dest = '\0'; +} + +//---------------------------------------------------------------------------- + +static void GetProtectionString(STRPTR Buffer, size_t BuffSize, + ULONG AndMask, ULONG CmpMask) +{ + Buffer = GetProtectionBitString(FIBF_HIDDEN, AndMask, CmpMask, + MSGID_FILETYPESACTION_PROTECTION_H_SET, + MSGID_FILETYPESACTION_PROTECTION_H_CLEARED, + Buffer, &BuffSize); + Buffer = GetProtectionBitString(FIBF_SCRIPT, AndMask, CmpMask, + MSGID_FILETYPESACTION_PROTECTION_S_SET, + MSGID_FILETYPESACTION_PROTECTION_S_CLEARED, + Buffer, &BuffSize); + Buffer = GetProtectionBitString(FIBF_PURE, AndMask, CmpMask, + MSGID_FILETYPESACTION_PROTECTION_P_SET, + MSGID_FILETYPESACTION_PROTECTION_P_CLEARED, + Buffer, &BuffSize); + Buffer = GetProtectionBitString(FIBF_ARCHIVE, AndMask, CmpMask, + MSGID_FILETYPESACTION_PROTECTION_A_SET, + MSGID_FILETYPESACTION_PROTECTION_A_CLEARED, + Buffer, &BuffSize); + + Buffer = GetProtectionBitString(FIBF_READ, AndMask, CmpMask, + MSGID_FILETYPESACTION_PROTECTION_R_SET, + MSGID_FILETYPESACTION_PROTECTION_R_CLEARED, + Buffer, &BuffSize); + Buffer = GetProtectionBitString(FIBF_WRITE, AndMask, CmpMask, + MSGID_FILETYPESACTION_PROTECTION_W_SET, + MSGID_FILETYPESACTION_PROTECTION_W_CLEARED, + Buffer, &BuffSize); + Buffer = GetProtectionBitString(FIBF_EXECUTE, AndMask, CmpMask, + MSGID_FILETYPESACTION_PROTECTION_E_SET, + MSGID_FILETYPESACTION_PROTECTION_E_CLEARED, + Buffer, &BuffSize); + /* Buffer = */ GetProtectionBitString(FIBF_DELETE, AndMask, CmpMask, + MSGID_FILETYPESACTION_PROTECTION_D_SET, + MSGID_FILETYPESACTION_PROTECTION_D_CLEARED, + Buffer, &BuffSize); + +} + +//---------------------------------------------------------------------------- + +static STRPTR GetProtectionBitString(ULONG BitMask, ULONG AndMask, ULONG CmpMask, + ULONG MsgIdSet, ULONG MsgIdCleared, + STRPTR Buffer, size_t *BuffSize) +{ + if (BitMask & AndMask) + { + if (BitMask & CmpMask) + stccpy(Buffer, GetLocString(MsgIdSet), *BuffSize); + else + stccpy(Buffer, GetLocString(MsgIdCleared), *BuffSize); + } + else + stccpy(Buffer, GetLocString(MSGID_FILETYPESACTION_PROTECTION_IGNORE), *BuffSize); + + *BuffSize -= strlen(Buffer); + + return Buffer + strlen(Buffer); +} + +//---------------------------------------------------------------------------- + +static void SetProtectionCycle(Object *o, ULONG BitMask, + ULONG AndMask, ULONG CmpMask) +{ + if (BitMask & AndMask) + { + if (BitMask & CmpMask) + set(o, MUIA_Cycle_Active, 0); // set + else + set(o, MUIA_Cycle_Active, 1); // unset + } + else + { + set(o, MUIA_Cycle_Active, 2); // ignore + } +} + +//---------------------------------------------------------------------------- + +void SetFileTypesIcon(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *ln) +{ + BOOL FoundNative = TRUE; + + while (ln) + { + struct FileTypesEntry *fte = (struct FileTypesEntry *) ln->tn_User; + + d1(KPrintF(__FILE__ "/%s/%ld: fte=%08lx\n", __FUNC__, __LINE__, fte)); + if (fte) + { + d1(KPrintF(__FILE__ "/%s/%ld: fte=%08lx <%s>\n", __FUNC__, __LINE__, fte, fte->fte_TypeNode.tn_Name)); + + if (DisplayFileTypesIcon(inst, fte->fte_TypeNode.tn_Name)) + break; + } + + FoundNative = FALSE; + + ln = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], + MUIM_NListtree_GetEntry, + ln, + MUIV_NListtree_GetEntry_Position_Parent, 0); + } + + set(inst->fpb_Objects[OBJNDX_Button_FileTypes_CreateIcon], + MUIA_Disabled, FoundNative); + set(inst->fpb_Objects[OBJNDX_Button_FileTypes_EditIcon], + MUIA_Disabled, !FoundNative); +} + +//---------------------------------------------------------------------------- + +SAVEDS(ULONG) INTERRUPT SelectFileTypesEntryHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct MUI_NListtree_TreeNode *ln = NULL; + + // Make sure Popobject is closed + DoMethod(inst->fpb_Objects[OBJNDX_Popobject_FileTypes_Methods_Add], + MUIM_Popstring_Close, FALSE); + + get(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], MUIA_NListtree_Active, &ln); + + d1(KPrintF("%s/%s/%ld: inst=%08lx ln=%08lx\n", __FILE__, __FUNC__, __LINE__, inst, ln)); + + if (ln) + { + struct FileTypesEntry *fte = (struct FileTypesEntry *) ln->tn_User; + struct MUI_NListtree_TreeNode *lnRoot; + struct MUI_NListtree_TreeNode *pln; + ULONG Level; + + for (pln = ln, Level = 0; pln && Level < 5; Level++) + { + pln = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], + MUIM_NListtree_GetEntry, pln, + MUIV_NListtree_GetEntry_Position_Parent, 0); + d1(KPrintF("%s/%s/%ld: pln=%08lx <%s> Level=%lu\n", __FILE__, __FUNC__, __LINE__, \ + pln, pln ? pln->tn_Name : (STRPTR) "", Level)); + } + + d1(KPrintF("%s/%s/%ld: pln=%08lx pln=%08lx\n", __FILE__, __FUNC__, __LINE__, pln + 0, pln + 1)); + d1(KPrintF("%s/%s/%ld: Level=%lu\n", __FILE__, __FUNC__, __LINE__, Level)); + + set(inst->fpb_Objects[OBJNDX_String_FileTypes_Name], MUIA_Disabled, FALSE); + set(inst->fpb_Objects[OBJNDX_Button_FileTypes_Remove], MUIA_Disabled, FALSE); + + set(inst->fpb_Objects[OBJNDX_Button_FileTypes_Actions_Learn], MUIA_Disabled, FALSE); + set(inst->fpb_Objects[OBJNDX_Popobject_FileTypes_Methods_Add], MUIA_Disabled, FALSE); + + lnRoot = GetRootEntry(inst, ln); + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods_Add], + MUIM_NList_Clear); + if (0 == Stricmp(lnRoot->tn_Name, "Project")) + { + d1(KPrintF("%s/%s/%ld: Add Project\n", __FILE__, __FUNC__, __LINE__)); + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods_Add], + MUIM_NList_Insert, AddFileTypeActionStringsProject, + -1, MUIV_NList_Insert_Sorted, 0); + } + else if (0 == Stricmp(lnRoot->tn_Name, "Disk")) + { + d1(KPrintF("%s/%s/%ld: Add Disk\n", __FILE__, __FUNC__, __LINE__)); + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods_Add], + MUIM_NList_Insert, AddFileTypeActionStringsDisk, + -1, MUIV_NList_Insert_Sorted, 0); + } + set(inst->fpb_Objects[OBJNDX_Menu_ExpandFileTypes], MUIA_Menuitem_Enabled, TRUE); + set(inst->fpb_Objects[OBJNDX_Menu_CollapseFileTypes], MUIA_Menuitem_Enabled, TRUE); + + set(inst->fpb_Objects[OBJNDX_Text_FileTypes_FileTypesName], + MUIA_Text_Contents, fte->fte_TypeNode.tn_Name); + + FillFileTypesActions(inst, fte, Level <= 2); + + SetFileTypesIcon(inst, ln); + + // Select corresponding entry in OBJNDX_MainListTree + SelectFileType(inst, &fte->fte_TypeNode); + } + else + { + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_Clear); + + set(inst->fpb_Objects[OBJNDX_Text_FileTypes_FileTypesName], + MUIA_Text_Contents, ""); + + set(inst->fpb_Objects[OBJNDX_Menu_ExpandFileTypes], MUIA_Menuitem_Enabled, TRUE); + set(inst->fpb_Objects[OBJNDX_Menu_CollapseFileTypes], MUIA_Menuitem_Enabled, TRUE); + + set(inst->fpb_Objects[OBJNDX_Button_FileTypes_Actions_Remove], MUIA_Disabled, TRUE); + set(inst->fpb_Objects[OBJNDX_Button_FileTypes_Actions_Learn], MUIA_Disabled, TRUE); + set(inst->fpb_Objects[OBJNDX_Popobject_FileTypes_Methods_Add], MUIA_Disabled, TRUE); + + set(inst->fpb_Objects[OBJNDX_String_FileTypes_Name], MUIA_Disabled, TRUE); + set(inst->fpb_Objects[OBJNDX_Button_FileTypes_Remove], MUIA_Disabled, TRUE); + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods_Add], + MUIM_NList_Clear); + } + + return 0; +} + +//---------------------------------------------------------------------------- + +SAVEDS(ULONG) INTERRUPT SelectFileTypesActionEntryHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct FileTypesActionEntry *fae; + ULONG n; + ULONG visibleNdx = 0; + + d1(KPrintF(__FUNC__ "/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst)); + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, &fae); + + d1(KPrintF(__FUNC__ "/%ld: fae=%08lx\n", __FUNC__, __LINE__, fae)); + + if (fae) + { + char TempString[80]; + + d1(KPrintF(__FUNC__ "/%ld: fae=%08lx action=%ld\n", __FUNC__, __LINE__, fae, fae->fae_ftale->ftale_Magic.action)); + + set(inst->fpb_Objects[OBJNDX_Button_FileTypes_Actions_Remove], MUIA_Disabled, FALSE); + + switch (fae->fae_ftale->ftale_Magic.action) + { + case ACT_MATCH: + set(inst->fpb_Objects[OBJNDX_String_Filetypes_Actions_Match_Offset], MUIA_String_Integer, fae->fae_ftale->ftale_Magic.arg1); + set(inst->fpb_Objects[OBJNDX_Checkmark_FileTypes_Action_Match_Case], MUIA_Selected, IS_CASE_SENSITIVE(&fae->fae_ftale->ftale_Magic)); + TranslateMatchStringToPrintable(TempString, sizeof(TempString), + fae->fae_ftale->ftale_Magic.str, abs(fae->fae_ftale->ftale_Magic.arg2)); + set(inst->fpb_Objects[OBJNDX_String_Filetypes_Actions_Match_Match], MUIA_String_Contents, TempString); + + visibleNdx = OBJNDX_Group_Filetypes_Actions_Match; + break; + + case ACT_SEARCH: + set(inst->fpb_Objects[OBJNDX_Checkmark_FileTypes_Action_Search_SkipSpaces], MUIA_Selected, FALSE); + set(inst->fpb_Objects[OBJNDX_Checkmark_FileTypes_Action_Search_Case], MUIA_Selected, IS_CASE_SENSITIVE(&fae->fae_ftale->ftale_Magic)); + TranslateMatchStringToPrintable(TempString, sizeof(TempString), + fae->fae_ftale->ftale_Magic.str, abs(fae->fae_ftale->ftale_Magic.arg2)); + set(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Search_Search], MUIA_String_Contents, TempString); + + visibleNdx =OBJNDX_Group_Filetypes_Actions_Search; + break; + + case ACT_SEARCHSKIPSPACES: + set(inst->fpb_Objects[OBJNDX_Checkmark_FileTypes_Action_Search_SkipSpaces], MUIA_Selected, TRUE); + set(inst->fpb_Objects[OBJNDX_Checkmark_FileTypes_Action_Search_Case], MUIA_Selected, IS_CASE_SENSITIVE(&fae->fae_ftale->ftale_Magic)); + TranslateMatchStringToPrintable(TempString, sizeof(TempString), + fae->fae_ftale->ftale_Magic.str, abs(fae->fae_ftale->ftale_Magic.arg2)); + set(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Search_Search], MUIA_String_Contents, TempString); + + visibleNdx = OBJNDX_Group_Filetypes_Actions_Search; + break; + + case ACT_FILESIZE: + set(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Filesize_Filesize], MUIA_String_Integer, fae->fae_ftale->ftale_Magic.arg2); + visibleNdx = OBJNDX_Group_Filetypes_Actions_Filesize; + break; + + case ACT_MINSIZEMB: + set(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_MinSizeMB_MinSize], MUIA_String_Integer, fae->fae_ftale->ftale_Magic.arg2); + visibleNdx =OBJNDX_Group_FileTypes_Action_MinSizeMB; + break; + + case ACT_NAMEPATTERN: + set(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Pattern_Pattern], MUIA_String_Contents, fae->fae_ftale->ftale_Magic.str); + visibleNdx =OBJNDX_Group_Filetypes_Actions_Pattern; + break; + + case ACT_DOSDEVICE: + set(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_DosDevice_Pattern], MUIA_String_Contents, fae->fae_ftale->ftale_Magic.str); + visibleNdx = OBJNDX_Group_Filetypes_Actions_DosDevice; + break; + + case ACT_DEVICENAME: + set(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_DeviceName_Pattern], MUIA_String_Contents, fae->fae_ftale->ftale_Magic.str); + visibleNdx = OBJNDX_Group_Filetypes_Actions_DeviceName; + break; + + case ACT_CONTENTS: + set(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Contents_Pattern], MUIA_String_Contents, fae->fae_ftale->ftale_Magic.str); + visibleNdx = OBJNDX_Group_Filetypes_Actions_Contents; + break; + + case ACT_DOSTYPE: + set(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_DosType_Pattern], MUIA_String_Contents, fae->fae_ftale->ftale_Magic.str); + visibleNdx = OBJNDX_Group_Filetypes_Actions_DosType; + break; + + case ACT_PROTECTION: + SetProtectionCycle(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_R], + FIBF_READ, fae->fae_ftale->ftale_Magic.arg1, fae->fae_ftale->ftale_Magic.arg2); + SetProtectionCycle(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_W], + FIBF_WRITE, fae->fae_ftale->ftale_Magic.arg1, fae->fae_ftale->ftale_Magic.arg2); + SetProtectionCycle(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_E], + FIBF_EXECUTE, fae->fae_ftale->ftale_Magic.arg1, fae->fae_ftale->ftale_Magic.arg2); + SetProtectionCycle(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_D], + FIBF_DELETE, fae->fae_ftale->ftale_Magic.arg1, fae->fae_ftale->ftale_Magic.arg2); + SetProtectionCycle(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_H], + FIBF_HIDDEN, fae->fae_ftale->ftale_Magic.arg1, fae->fae_ftale->ftale_Magic.arg2); + SetProtectionCycle(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_S], + FIBF_SCRIPT, fae->fae_ftale->ftale_Magic.arg1, fae->fae_ftale->ftale_Magic.arg2); + SetProtectionCycle(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_P], + FIBF_PURE, fae->fae_ftale->ftale_Magic.arg1, fae->fae_ftale->ftale_Magic.arg2); + SetProtectionCycle(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_A], + FIBF_ARCHIVE, fae->fae_ftale->ftale_Magic.arg1, fae->fae_ftale->ftale_Magic.arg2); + + visibleNdx = OBJNDX_Group_Filetypes_Actions_Protection; + break; + + case ACT_OR: + case ACT_ISASCII: + case ACT_MACROCLASS: + case ACT_END: + visibleNdx = OBJNDX_Group_Filetypes_Actions_Empty; + break; + } + } + else + { + set(inst->fpb_Objects[OBJNDX_Button_FileTypes_Actions_Remove], MUIA_Disabled, TRUE); + visibleNdx = OBJNDX_Group_Filetypes_Actions_Empty; + } + + for (n = OBJNDX_Group_Filetypes_Actions_Protection; + n <= OBJNDX_Group_Filetypes_Actions_DosType; n++) + { + set(inst->fpb_Objects[n], MUIA_ShowMe, n == visibleNdx); + } + + return 0; +} + +//---------------------------------------------------------------------------- + +SAVEDS(void) INTERRUPT ChangedFileTypesActionMatchMatchHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct FileTypesActionEntry *fae; + + d1(KPrintF(__FUNC__ "/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst)); + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, &fae); + + d1(KPrintF(__FUNC__ "/%ld: fae=%08lx\n", __FUNC__, __LINE__, fae)); + + if (fae && ACT_MATCH == fae->fae_ftale->ftale_Magic.action) + { + char TempString[255]; + CONST_STRPTR MatchString = NULL; + size_t Length; + + get(inst->fpb_Objects[OBJNDX_String_Filetypes_Actions_Match_Match], MUIA_String_Contents, &MatchString); + + Length = TranslateFromPrintable(TempString, sizeof(TempString), MatchString); + + SetMagicString(fae, TempString, Length); + + if (IS_CASE_SENSITIVE(&fae->fae_ftale->ftale_Magic)) + fae->fae_ftale->ftale_Magic.arg2 = Length; + else + fae->fae_ftale->ftale_Magic.arg2 = -Length; + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_RedrawEntry, fae); + } +} + +SAVEDS(void) INTERRUPT ChangedFileTypesActionMatchCaseHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct FileTypesActionEntry *fae; + + d1(KPrintF(__FUNC__ "/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst)); + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, &fae); + + d1(KPrintF(__FUNC__ "/%ld: fae=%08lx\n", __FUNC__, __LINE__, fae)); + + if (fae && ACT_MATCH == fae->fae_ftale->ftale_Magic.action) + { + size_t Length = abs(fae->fae_ftale->ftale_Magic.arg2); + ULONG MatchCase = 0; + + get(inst->fpb_Objects[OBJNDX_Checkmark_FileTypes_Action_Match_Case], MUIA_Selected, &MatchCase); + + if (MatchCase) + fae->fae_ftale->ftale_Magic.arg2 = Length; + else + fae->fae_ftale->ftale_Magic.arg2 = -Length; + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_RedrawEntry, fae); + } +} + +SAVEDS(void) INTERRUPT ChangedFileTypesActionMatchOffsetHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct FileTypesActionEntry *fae; + + d1(KPrintF(__FUNC__ "/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst)); + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, &fae); + + d1(KPrintF(__FUNC__ "/%ld: fae=%08lx\n", __FUNC__, __LINE__, fae)); + + if (fae && ACT_MATCH == fae->fae_ftale->ftale_Magic.action) + { + ULONG MatchOffset = 0; + + get(inst->fpb_Objects[OBJNDX_String_Filetypes_Actions_Match_Offset], MUIA_String_Integer, &MatchOffset); + + fae->fae_ftale->ftale_Magic.arg1 = MatchOffset; + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_RedrawEntry, fae); + } +} + +SAVEDS(void) INTERRUPT ChangedFileTypesActionSearchSearchHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct FileTypesActionEntry *fae; + + d1(KPrintF(__FUNC__ "/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst)); + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, &fae); + + d1(KPrintF(__FUNC__ "/%ld: fae=%08lx\n", __FUNC__, __LINE__, fae)); + + if (fae && (ACT_SEARCH == fae->fae_ftale->ftale_Magic.action || ACT_SEARCHSKIPSPACES == fae->fae_ftale->ftale_Magic.action)) + { + char TempString[255]; + CONST_STRPTR SearchString = NULL; + size_t Length; + + get(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Search_Search], MUIA_String_Contents, &SearchString); + + Length = TranslateFromPrintable(TempString, sizeof(TempString), SearchString); + + if (IS_CASE_SENSITIVE(&fae->fae_ftale->ftale_Magic)) + fae->fae_ftale->ftale_Magic.arg2 = Length; + else + fae->fae_ftale->ftale_Magic.arg2 = -Length; + + SetMagicString(fae, TempString, Length); + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_RedrawEntry, fae); + } +} + +SAVEDS(void) INTERRUPT ChangedFileTypesActionSearchCaseHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct FileTypesActionEntry *fae; + + d1(KPrintF(__FUNC__ "/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst)); + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, &fae); + + d1(KPrintF(__FUNC__ "/%ld: fae=%08lx\n", __FUNC__, __LINE__, fae)); + + if (fae && (ACT_SEARCH == fae->fae_ftale->ftale_Magic.action || ACT_SEARCHSKIPSPACES == fae->fae_ftale->ftale_Magic.action)) + { + ULONG SearchCaseSensitive = 0; + size_t Length = abs(fae->fae_ftale->ftale_Magic.arg2); + + get(inst->fpb_Objects[OBJNDX_Checkmark_FileTypes_Action_Search_Case], MUIA_Selected, &SearchCaseSensitive); + + if (SearchCaseSensitive) + fae->fae_ftale->ftale_Magic.arg2 = Length; + else + fae->fae_ftale->ftale_Magic.arg2 = -Length; + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_RedrawEntry, fae); + } +} + +SAVEDS(void) INTERRUPT ChangedFileTypesActionSearchSkipSpacesHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct FileTypesActionEntry *fae; + + d1(KPrintF(__FUNC__ "/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst)); + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, &fae); + + d1(KPrintF(__FUNC__ "/%ld: fae=%08lx\n", __FUNC__, __LINE__, fae)); + + if (fae && (ACT_SEARCH == fae->fae_ftale->ftale_Magic.action || ACT_SEARCHSKIPSPACES == fae->fae_ftale->ftale_Magic.action)) + { + ULONG SkipSpaces = 0; + + get(inst->fpb_Objects[OBJNDX_Checkmark_FileTypes_Action_Search_SkipSpaces], MUIA_Selected, &SkipSpaces); + + if (SkipSpaces) + fae->fae_ftale->ftale_Magic.action = ACT_SEARCHSKIPSPACES; + else + fae->fae_ftale->ftale_Magic.action = ACT_SEARCH; + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_RedrawEntry, fae); + } +} + +SAVEDS(void) INTERRUPT ChangedFileTypesActionFilesizeHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct FileTypesActionEntry *fae; + + d1(KPrintF(__FUNC__ "/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst)); + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, &fae); + + d1(KPrintF(__FUNC__ "/%ld: fae=%08lx\n", __FUNC__, __LINE__, fae)); + + if (fae && ACT_FILESIZE == fae->fae_ftale->ftale_Magic.action) + { + ULONG FileSize = 0; + + get(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Filesize_Filesize], MUIA_String_Integer, &FileSize); + + fae->fae_ftale->ftale_Magic.arg2 = FileSize; + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_RedrawEntry, fae); + } +} + +SAVEDS(void) INTERRUPT ChangedFileTypesActionMinSizeHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct FileTypesActionEntry *fae; + + d1(KPrintF(__FUNC__ "/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst)); + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, &fae); + + d1(KPrintF(__FUNC__ "/%ld: fae=%08lx\n", __FUNC__, __LINE__, fae)); + + if (fae && ACT_MINSIZEMB == fae->fae_ftale->ftale_Magic.action) + { + ULONG FileSize = 0; + + get(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_MinSizeMB_MinSize], MUIA_String_Integer, &FileSize); + + fae->fae_ftale->ftale_Magic.arg2 = FileSize; + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_RedrawEntry, fae); + } +} +SAVEDS(void) INTERRUPT ChangedFileTypesActionPatternHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct FileTypesActionEntry *fae; + + d1(KPrintF(__FUNC__ "/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst)); + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, &fae); + + d1(KPrintF(__FUNC__ "/%ld: fae=%08lx\n", __FUNC__, __LINE__, fae)); + + if (fae && ACT_NAMEPATTERN == fae->fae_ftale->ftale_Magic.action) + { + CONST_STRPTR Pattern = NULL; + + get(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Pattern_Pattern], MUIA_String_Contents, &Pattern); + + SetMagicString(fae, Pattern, 1 + strlen(Pattern)); + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_RedrawEntry, fae); + } +} + + +SAVEDS(void) INTERRUPT ChangedFileTypesActionDosDeviceHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct FileTypesActionEntry *fae; + + d1(KPrintF(__FUNC__ "/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst)); + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, &fae); + + d1(KPrintF(__FUNC__ "/%ld: fae=%08lx\n", __FUNC__, __LINE__, fae)); + + if (fae && ACT_DOSDEVICE == fae->fae_ftale->ftale_Magic.action) + { + CONST_STRPTR Pattern = NULL; + + get(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_DosDevice_Pattern], MUIA_String_Contents, &Pattern); + + SetMagicString(fae, Pattern, 1 + strlen(Pattern)); + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_RedrawEntry, fae); + } +} + + +SAVEDS(void) INTERRUPT ChangedFileTypesActionDeviceNameHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct FileTypesActionEntry *fae; + + d1(KPrintF(__FUNC__ "/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst)); + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, &fae); + + d1(KPrintF(__FUNC__ "/%ld: fae=%08lx\n", __FUNC__, __LINE__, fae)); + + if (fae && ACT_DEVICENAME == fae->fae_ftale->ftale_Magic.action) + { + CONST_STRPTR Pattern = NULL; + + get(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_DeviceName_Pattern], MUIA_String_Contents, &Pattern); + + SetMagicString(fae, Pattern, 1 + strlen(Pattern)); + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_RedrawEntry, fae); + } +} + + +SAVEDS(void) INTERRUPT ChangedFileTypesActionContentsHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct FileTypesActionEntry *fae; + + d1(KPrintF(__FUNC__ "/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst)); + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, &fae); + + d1(KPrintF(__FUNC__ "/%ld: fae=%08lx\n", __FUNC__, __LINE__, fae)); + + if (fae && ACT_CONTENTS == fae->fae_ftale->ftale_Magic.action) + { + CONST_STRPTR Pattern = NULL; + + get(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Contents_Pattern], MUIA_String_Contents, &Pattern); + + SetMagicString(fae, Pattern, 1 + strlen(Pattern)); + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_RedrawEntry, fae); + } +} + + +SAVEDS(void) INTERRUPT ChangedFileTypesActionDosTypeHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct FileTypesActionEntry *fae; + + d1(KPrintF(__FUNC__ "/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst)); + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, &fae); + + d1(KPrintF(__FUNC__ "/%ld: fae=%08lx\n", __FUNC__, __LINE__, fae)); + + if (fae && ACT_DOSTYPE == fae->fae_ftale->ftale_Magic.action) + { + char TempString[255]; + size_t Length; + CONST_STRPTR MatchString = NULL; + + get(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_DosType_Pattern], MUIA_String_Contents, &MatchString); + + Length = TranslateFromPrintable(TempString, sizeof(TempString), MatchString); + + SetMagicString(fae, TempString, Length); + fae->fae_ftale->ftale_Magic.arg2 = Length; + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_RedrawEntry, fae); + } +} + + +SAVEDS(void) INTERRUPT ChangedFileTypesActionProtectionHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct FileTypesActionEntry *fae; + + d1(KPrintF(__FUNC__ "/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst)); + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, &fae); + + d1(KPrintF(__FUNC__ "/%ld: fae=%08lx\n", __FUNC__, __LINE__, fae)); + + if (fae && ACT_PROTECTION == fae->fae_ftale->ftale_Magic.action) + { + ULONG Protect = 0; + + if (inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_R] == obj) + { + get(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_R], MUIA_Cycle_Active, &Protect); + SetProtectionBits(fae, Protect, FIBF_READ); + } + else if (inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_W] == obj) + { + get(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_W], MUIA_Cycle_Active, &Protect); + SetProtectionBits(fae, Protect, FIBF_WRITE); + } + else if (inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_E] == obj) + { + get(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_E], MUIA_Cycle_Active, &Protect); + SetProtectionBits(fae, Protect, FIBF_EXECUTE); + } + else if (inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_D] == obj) + { + get(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_D], MUIA_Cycle_Active, &Protect); + SetProtectionBits(fae, Protect, FIBF_DELETE); + } + else if (inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_S] == obj) + { + get(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_S], MUIA_Cycle_Active, &Protect); + SetProtectionBits(fae, Protect, FIBF_SCRIPT); + } + else if (inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_P] == obj) + { + get(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_P], MUIA_Cycle_Active, &Protect); + SetProtectionBits(fae, Protect, FIBF_PURE); + } + else if (inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_A] == obj) + { + get(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_A], MUIA_Cycle_Active, &Protect); + SetProtectionBits(fae, Protect, FIBF_ARCHIVE); + } + else if (inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_H] == obj) + { + get(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_H], MUIA_Cycle_Active, &Protect); + SetProtectionBits(fae, Protect, FIBF_HIDDEN); + } + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_RedrawEntry, fae); + } +} + +//---------------------------------------------------------------------------- + +static void SetMagicString(struct FileTypesActionEntry *fae, CONST_STRPTR String, size_t Length) +{ + if (fae->fae_ftale->ftale_AllocatedString) + free(fae->fae_ftale->ftale_AllocatedString); + + fae->fae_ftale->ftale_AllocatedString = fae->fae_ftale->ftale_Magic.str = malloc(Length); + if (fae->fae_ftale->ftale_Magic.str) + memcpy(fae->fae_ftale->ftale_Magic.str, String, Length); +} + +//---------------------------------------------------------------------------- + +static size_t TranslateFromPrintable(STRPTR Buffer, size_t BuffLength, + CONST_STRPTR InputString) +{ + size_t DestLength = 0; + + d1(KPrintF(__FUNC__ "/%ld: InputString=<%s>\n", __FUNC__, __LINE__, InputString)); + + while (BuffLength && *InputString) + { + if ('\\' == InputString[0] + && strlen(InputString) >= 4 + && 'x' == tolower(InputString[1]) + && isxdigit(InputString[2]) + && isxdigit(InputString[3])) + { + *Buffer++ = (HexValue(InputString[2]) << 4) + + HexValue(InputString[3]); + InputString += 4; // skip "0x99" + } + else + { + *Buffer++ = *InputString++; + } + + DestLength++; + BuffLength--; + } + + d1(KPrintF(__FUNC__ "/%ld: DestLength=%d\n", __FUNC__, __LINE__, DestLength)); + + return DestLength; +} + +//---------------------------------------------------------------------------- + +static UBYTE HexValue(char ch) +{ + if (isdigit(ch)) + return (UBYTE) (ch - '0'); + else + return (UBYTE) (tolower(ch) + 10 - 'a'); +} + +//---------------------------------------------------------------------------- + +static void SetProtectionBits(struct FileTypesActionEntry *fae, + enum ProtectionMode Protect, ULONG Mask) +{ + switch (Protect) + { + case PROT_Set: + fae->fae_ftale->ftale_Magic.arg1 |= Mask; + fae->fae_ftale->ftale_Magic.arg2 |= Mask; + break; + case PROT_Unset: + fae->fae_ftale->ftale_Magic.arg1 |= Mask; + fae->fae_ftale->ftale_Magic.arg2 &= ~Mask; + break; + case PROT_Ignore: + default: + fae->fae_ftale->ftale_Magic.arg1 &= ~Mask; + fae->fae_ftale->ftale_Magic.arg2 &= ~Mask; + } +} + +//---------------------------------------------------------------------------- + +SAVEDS(void) INTERRUPT RenameFileTypeHookFunc(struct Hook *hook, APTR obj, Msg *msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct MUI_NListtree_TreeNode *ln = NULL; + + get(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], MUIA_NListtree_Active, &ln); + + if (ln) + { + struct FileTypesEntry *fte = (struct FileTypesEntry *) ln->tn_User; + CONST_STRPTR NewName = NULL; + + CleanupFoundNodes(inst); + + get(inst->fpb_Objects[OBJNDX_String_FileTypes_Name], MUIA_String_Contents, &NewName); + + if (fte->fte_AllocatedName) + free(fte->fte_AllocatedName); + fte->fte_AllocatedName = fte->fte_TypeNode.tn_Name = strdup(NewName); + + DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], + MUIM_NListtree_Redraw, + ln); + + set(inst->fpb_Objects[OBJNDX_Text_FileTypes_FileTypesName], + MUIA_Text_Contents, fte->fte_TypeNode.tn_Name); + + SetFileTypesIcon(inst, ln); + } +} + + +SAVEDS(void) INTERRUPT AddFileTypeHookFunc(struct Hook *hook, APTR obj, Msg *msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct TypeNode NewTn; + struct MUI_NListtree_TreeNode *ln; + + memset(&NewTn, 0, sizeof(NewTn)); + + CleanupFoundNodes(inst); + + NewTn.tn_Name = GetLocString(MSGID_NEW_FILETYPE); + NewTn.tn_Description[0].action = ACT_END; + + ln = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], + MUIM_NListtree_Insert, + NewTn.tn_Name, + &NewTn, + MUIV_NListtree_Insert_ListNode_Active, + MUIV_NListtree_Insert_PrevNode_Active, + TNF_LIST); + + if (ln) + { + // Make the new filetype the active one + set(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], MUIA_NListtree_Active, ln); + + // try to activate filetype name string gadget + set(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_ActiveObject, inst->fpb_Objects[OBJNDX_String_FileTypes_Name]); + } +} + + +SAVEDS(void) INTERRUPT RemoveFileTypeHookFunc(struct Hook *hook, APTR obj, Msg *msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct MUI_NListtree_TreeNode *ln = NULL; + + CleanupFoundNodes(inst); + get(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], MUIA_NListtree_Active, &ln); + + if (ln) + { + DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], + MUIM_NListtree_Remove, + MUIV_NListtree_Remove_ListNode_Active, + ln); + } +} + + +// Close "Add method" popup +SAVEDS(void) INTERRUPT AddFileTypesMethodHookFunc(struct Hook *hook, APTR obj, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct FileTypesActionEntry *fae; + struct MUI_NListtree_TreeNode *ln = NULL; + + d1(KPrintF("%s/%s//%ld: inst=%08lx\n", __FILE__, __FUNC__, __LINE__, inst)); + + get(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], MUIA_NListtree_Active, &ln); + d1(KPrintF("%s/%s//%ld: ln=%08lx\n", __FILE__, __FUNC__, __LINE__, ln)); + if (ln) + { + struct FileTypesEntry *fte = (struct FileTypesEntry *) ln->tn_User; + CONST_STRPTR NewActionString; + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, &fae); + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods_Add], + MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, + &NewActionString); + d1(KPrintF("%s/%s//%ld: NewAction=<%s>\n", __FILE__, __FUNC__, __LINE__, NewActionString)); + + if (NewActionString && strlen(NewActionString)) + { + struct Magic Newmg; + struct FileTypesActionListEntry *ftaleNew; + + memset(&Newmg, 0, sizeof(Newmg)); + Newmg.action = GetActionFromString(NewActionString); + Newmg.str = (STRPTR) ""; + d1(KPrintF("%s/%s//%ld: NewAction=<%s> %ld\n", __FILE__, __FUNC__, __LINE__, NewActionString, Newmg.action)); + + ftaleNew = AddFileTypesAction(fte, &Newmg, fae ? &fae->fae_ftale->ftale_Node : NULL); + + if (ftaleNew) + { + ULONG InsertPos; + + if (fae) + { + InsertPos = MUIV_NList_GetPos_Start; + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_GetPos, fae, &InsertPos); + + d1(KPrintF("%s/%s/%ld: InsertPos=%ld\n", __FILE__, __FUNC__, __LINE__, InsertPos)); + + InsertPos++; + } + else + InsertPos = MUIV_NList_Insert_Bottom; + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_InsertSingle, + ftaleNew, + InsertPos); + + // Make the new action the active one + get(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], MUIA_NList_InsertPosition, &InsertPos); + set(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], MUIA_NList_Active, InsertPos); + } + } + } + + DoMethod(inst->fpb_Objects[OBJNDX_Popobject_FileTypes_Methods_Add], MUIM_Popstring_Close, TRUE); +} + + +SAVEDS(void) INTERRUPT RemoveFileTypesActionHookFunc(struct Hook *hook, APTR obj, Msg *msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct FileTypesActionEntry *fae; + + d1(KPrintF(__FUNC__ "/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst)); + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, &fae); + + d1(KPrintF(__FUNC__ "/%ld: fae=%08lx\n", __FUNC__, __LINE__, fae)); + + if (fae) + { + Remove(&fae->fae_ftale->ftale_Node); + + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_Remove, + MUIV_NList_Remove_Active); + } +} + +//---------------------------------------------------------------------------- + +SAVEDS(APTR) INTERRUPT FileTypesConstructFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_ConstructMessage *ltcm) +{ + struct FileTypesEntry *fte; + BOOL Success = FALSE; + + d1(kprintf(__FILE__ "/%s/%ld: obj=%08lx ltcm=%08lx memPool=%08lx UserData=%08lx\n", \ + __FUNC__, __LINE__, obj, ltcm, ltcm->MemPool, ltcm->UserData)); + + do { + const struct TypeNode *TnOrig = ltcm->UserData; + const struct Magic *curr; + + fte = AllocPooled(ltcm->MemPool, sizeof(struct FileTypesEntry)); + d1(KPrintF(__FILE__ "/%s/%ld: fte=%08lx\n", __FUNC__, __LINE__, fte)); + if (NULL == fte) + break; + + NewList(&fte->fte_MagicList); + fte->fte_TypeNode = *TnOrig; + + fte->fte_FindStart = 0; + fte->fte_FindLength = 0; + + fte->fte_AllocatedName2 = NULL; + + fte->fte_AllocatedName = fte->fte_TypeNode.tn_Name = strdup(TnOrig->tn_Name); + if (NULL == fte->fte_AllocatedName) + break; + + // add all ACT_*** entries to fte_MagicList + for (curr = TnOrig->tn_Description; ACT_END != curr->action; curr++) + { + d1(KPrintF(__FILE__ "/%s/%ld: curr=%08lx action=%ld\n", __FUNC__, __LINE__, curr, curr->action)); + + if (!AddFileTypesAction(fte, curr, NULL)) + break; + } + + Success = TRUE; + } while (0); + + if (!Success && fte) + { + CleanupFileTypesActions(fte); + if (fte->fte_AllocatedName) + { + free(fte->fte_AllocatedName); + fte->fte_AllocatedName = NULL; + } + FreePooled(ltcm->MemPool, fte, sizeof(struct FileTypesEntry)); + fte = NULL; + } + + return fte; +} + +SAVEDS(void) INTERRUPT FileTypesDestructFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_DestructMessage *ltdm) +{ + struct FileTypesEntry *fte = (struct FileTypesEntry *) ltdm->UserData; + + d1(KPrintF(__FILE__ "/%s/%ld: fte=%08lx\n", __FUNC__, __LINE__, fte)); + + CleanupFileTypesActions(fte); + + if (fte->fte_AllocatedName) + free(fte->fte_AllocatedName); + if (fte->fte_AllocatedName2) + free(fte->fte_AllocatedName2); + + FreePooled(ltdm->MemPool, fte, sizeof(struct FileTypesEntry)); + ltdm->UserData = NULL; +} + +SAVEDS(ULONG) INTERRUPT FileTypesDisplayFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_DisplayMessage *ltdm) +{ + struct FileTypesEntry *fte = (struct FileTypesEntry *) ltdm->TreeNode->tn_User; + + d1(KPrintF(__FILE__ "/%s/%ld: fte=%08lx\n", __FUNC__, __LINE__, fte)); + + if (fte) + { + if (fte->fte_FindLength > 0) + { + if (fte->fte_AllocatedName2) + free(fte->fte_AllocatedName2); + + fte->fte_AllocatedName2 = malloc(1 + strlen(fte->fte_TypeNode.tn_Name) + 2 * 6); + if (fte->fte_AllocatedName2) + { + if (fte->fte_FindStart) + stccpy(fte->fte_AllocatedName2, fte->fte_TypeNode.tn_Name, fte->fte_FindStart); + else + strcpy(fte->fte_AllocatedName2, ""); + + strcat(fte->fte_AllocatedName2, "\0335" ); // FILLPEN + strncat(fte->fte_AllocatedName2, fte->fte_TypeNode.tn_Name + fte->fte_FindStart, fte->fte_FindLength); + strcat(fte->fte_AllocatedName2, MUIX_PT); + strcat(fte->fte_AllocatedName2, fte->fte_TypeNode.tn_Name + fte->fte_FindStart + fte->fte_FindLength); + + ltdm->Array[0] = fte->fte_AllocatedName2; + } + else + { + ltdm->Array[0] = fte->fte_TypeNode.tn_Name; + } + } + else + { + ltdm->Array[0] = fte->fte_TypeNode.tn_Name; + } + } + + return 0; +} + +//---------------------------------------------------------------------------- + +static struct FileTypesActionListEntry *AddFileTypesAction(struct FileTypesEntry *fte, + const struct Magic *curr, struct Node *PrevNode) +{ + struct FileTypesActionListEntry *ftale; + BOOL Success = FALSE; + + ftale = calloc(1, sizeof(struct FileTypesActionListEntry)); + if (ftale) + { + ftale->ftale_AllocatedString = NULL; + ftale->ftale_Magic = *curr; + + switch (curr->action) + { + case ACT_SEARCHSKIPSPACES: + case ACT_MATCH: + ftale->ftale_AllocatedString = ftale->ftale_Magic.str = malloc(1 + abs(ftale->ftale_Magic.arg2)); + if (ftale->ftale_Magic.str) + { + memcpy(ftale->ftale_Magic.str, curr->str, abs(ftale->ftale_Magic.arg2)); + Success = TRUE; + } + break; + case ACT_NAMEPATTERN: + ftale->ftale_AllocatedString = ftale->ftale_Magic.str = malloc(1 + strlen(ftale->ftale_Magic.str)); + if (ftale->ftale_Magic.str) + { + strcpy(ftale->ftale_Magic.str, curr->str); + Success = TRUE; + } + break; + default: + Success = TRUE; + break; + } + } + + if (Success) + { + if (PrevNode) + Insert(&fte->fte_MagicList, &ftale->ftale_Node, PrevNode->ln_Pred); + else + AddTail(&fte->fte_MagicList, &ftale->ftale_Node); + } + else + { + if (ftale) + free(ftale); + ftale = NULL; + } + + return ftale; +} + +//---------------------------------------------------------------------------- + +static void CleanupFileTypesActions(struct FileTypesEntry *fte) +{ + struct FileTypesActionListEntry *ftale; + + while ((ftale = (struct FileTypesActionListEntry *) RemTail(&fte->fte_MagicList))) + { + if (ftale->ftale_AllocatedString) + free(ftale->ftale_AllocatedString); + free(ftale); + } +} + +//---------------------------------------------------------------------------- + +static ULONG GetActionFromString(CONST_STRPTR ActionString) +{ + static const ULONG Actions[] = + { + ACT_MATCH, + ACT_SEARCH, + ACT_FILESIZE, + ACT_NAMEPATTERN, + ACT_PROTECTION, + ACT_OR, + ACT_ISASCII, + ACT_DOSDEVICE, + ACT_DEVICENAME, + ACT_CONTENTS, + ACT_DOSTYPE, + ACT_MINSIZEMB, + ACT_MACROCLASS, + }; + ULONG n; + + for (n = 0; AddFileTypeActionStrings[n]; n++) + { + if (n < Sizeof(Actions) && + 0 == strcmp(AddFileTypeActionStrings[n], ActionString)) + { + return Actions[n]; + } + } + + // not found -- this should never happen + return ACT_END; +} + +//---------------------------------------------------------------------------- + +SAVEDS(void) INTERRUPT FileTypesActionDragDropSortHookFunc(struct Hook *hook, APTR obj, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct FileTypesActionEntry *fae; + struct MUI_NListtree_TreeNode *ln = NULL; + ULONG InsertPosition = 0; + + d1(KPrintF(__FUNC__ "/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst)); + + get(obj, MUIA_NList_DragSortInsert, &InsertPosition); + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_GetEntry, + InsertPosition, &fae); + + get(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], MUIA_NListtree_Active, &ln); + + if (ln && fae) + { + struct FileTypesEntry *fte = (struct FileTypesEntry *) ln->tn_User; + struct FileTypesActionEntry *faeParent = NULL; + + d1(KPrintF(__FUNC__ "/%ld: InsertPosition=%lu fae=%08lx\n", __FUNC__, __LINE__, InsertPosition, fae)); + + // Remove from parent list at former position + Remove(&fae->fae_ftale->ftale_Node); + + if (InsertPosition > 0) + { + // Get new parent + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_GetEntry, + InsertPosition - 1, &faeParent); + } + + d1(KPrintF(__FUNC__ "/%ld: faeParent=%08lx\n", __FUNC__, __LINE__)); + + // insert into parent list at new position + if (faeParent) + Insert(&fte->fte_MagicList, &fae->fae_ftale->ftale_Node, &faeParent->fae_ftale->ftale_Node); + else + AddHead(&fte->fte_MagicList, &fae->fae_ftale->ftale_Node); + } +} + +//---------------------------------------------------------------------------- + +SAVEDS(void) INTERRUPT LearnFileTypeHookFunc(struct Hook *hook, APTR obj, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + BPTR OldDir = (BPTR)NULL; + BPTR fh = (BPTR)NULL; + STRPTR MergedDataBuffer = NULL; + STRPTR ReadDataBuffer = NULL; + UBYTE *CompareFlags = NULL; + size_t BuffLength = 488; + + struct MUI_NListtree_TreeNode *ln = NULL; + + get(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], MUIA_NListtree_Active, &ln); + + d1(KPrintF(__FUNC__ "/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst, ln)); + + do { + BOOL Result; + struct Window *win = NULL; + ULONG n; + ULONG StartOffset, Count; + size_t MergedLength = BuffLength; + struct MUI_NListtree_TreeNode *ln = NULL; + struct FileTypesEntry *fte; + + get(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], MUIA_NListtree_Active, &ln); + + d1(KPrintF(__FUNC__ "/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst, ln)); + + if (NULL == ln) + break; + + fte = (struct FileTypesEntry *) ln->tn_User; + + get(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Window, &win); + if (NULL == win) + break; + + CompareFlags = malloc(BuffLength); + if (NULL == CompareFlags) + break; + + ReadDataBuffer = malloc(BuffLength); + if (NULL == ReadDataBuffer) + break; + + MergedDataBuffer = malloc(BuffLength); + if (NULL == MergedDataBuffer) + break; + + if (NULL == inst->fpb_LearnReq) + { + inst->fpb_LearnReq = MUI_AllocAslRequestTags(ASL_FileRequest, + ASLFR_Flags1, FRF_DOPATTERNS, + ASLFR_UserData, inst, + ASLFR_DoMultiSelect, TRUE, + ASLFR_IntuiMsgFunc, &inst->fpb_Hooks[HOOKNDX_AslIntuiMsg], + TAG_END); + } + + if (NULL == inst->fpb_LearnReq) + break; + + //AslRequest( + Result = MUI_AslRequestTags(inst->fpb_LearnReq, + ASLFR_Window, win, + ASLFR_SleepWindow, TRUE, + ASLFR_TitleText, GetLocString(MSGID_LEARN_OPEN), + TAG_END); + + if (!Result) + break; + + if (inst->fpb_LearnReq->fr_NumArgs < 2) + { + MUI_Request(inst->fpb_Objects[OBJNDX_APP_Main], inst->fpb_Objects[OBJNDX_WIN_Main], 0, NULL, + GetLocString(MSGID_SELECT_TWO_REQ_OK), + GetLocString(MSGID_SELECT_TWO_REQ_CONTENTS)); + break; + } + + // read all specified sample files, + // and collect equal areas + for (n = 0; n < inst->fpb_LearnReq->fr_NumArgs; n++) + { + OldDir = CurrentDir(inst->fpb_LearnReq->fr_ArgList[n].wa_Lock); + + // open next file + fh = Open(inst->fpb_LearnReq->fr_ArgList[n].wa_Name, MODE_OLDFILE); + if ((BPTR)NULL == fh) + break; + + // Read one block + MergedLength = FRead(fh, ReadDataBuffer, 1, MergedLength); + if (MergedLength < 1) + break; + + if (0 == n) + { + // if first file, then initialize MergedDataBuffer and CompareFlags + memcpy(MergedDataBuffer, ReadDataBuffer, MergedLength); + memset(CompareFlags, 1, MergedLength); + } + else + { + // mask out all different bytes + ULONG k; + + for (k = 0; k < MergedLength; k++) + { + if (MergedDataBuffer[k] != ReadDataBuffer[k]) + CompareFlags[k] = 0; + } + } + + Close(fh); + fh = (BPTR)NULL; + + CurrentDir(OldDir); + OldDir = (BPTR)NULL; + } + + // now we have the common data in MergedDataBuffer, + // and a 1 in CompareFlags for each byte that was + // equal for all sample files + for (n = Count = StartOffset= 0; n < MergedLength; n++) + { + if (CompareFlags[n]) + { + if (0 == Count++) + StartOffset = n; + } + else + { + // ignore all equal sections of less than 2 bytes + if (Count >= 2) + { + struct Magic Newmg; + struct FileTypesActionListEntry *ftaleNew; + + memset(&Newmg, 0, sizeof(Newmg)); + Newmg.action = ACT_MATCH; + Newmg.arg1 = StartOffset; + Newmg.arg2 = Count; + Newmg.str = MergedDataBuffer + StartOffset; + + ftaleNew = AddFileTypesAction(fte, &Newmg, NULL); + + if (ftaleNew) + { + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], + MUIM_NList_InsertSingle, + ftaleNew, + MUIV_NList_Insert_Bottom); + } + } + Count = 0; + } + } + } while (0); + + if (fh) + Close(fh); + if (OldDir) + CurrentDir(OldDir); + if (MergedDataBuffer) + free(MergedDataBuffer); + if (ReadDataBuffer) + free(ReadDataBuffer); + if (CompareFlags) + free(CompareFlags); +} + +//---------------------------------------------------------------------------- + +SAVEDS(void) INTERRUPT CreateNewFileTypesIconHookFunc(struct Hook *hook, APTR obj, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + + if (inst->fpb_IconObject) + { + struct MUI_NListtree_TreeNode *ln; + + ln = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, 0); + if (ln) + { + struct FileTypesEntry *fte = (struct FileTypesEntry *) ln->tn_User; + char IconPath[MAX_FILENAME]; + struct TagItem ti[] = { + {ICONA_NoPosition, TRUE}, + {TAG_END}}; + + DefIconFullName(inst, IconPath, sizeof(IconPath), + fte->fte_TypeNode.tn_Name); + + DoMethod(inst->fpb_IconObject, + IDTM_Write, + IconPath, + NULL, + ti); + + // Toggle selection of current entry to enforce re-evaluation of icon via HOOKNDX_SelectFileTypesEntry + set(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], + MUIA_NListtree_Active, MUIV_NListtree_Active_Off); + set(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], + MUIA_NListtree_Active, ln); + } + } +} + +//---------------------------------------------------------------------------- + +SAVEDS(void) INTERRUPT EditFileTypesIconHookFunc(struct Hook *hook, APTR obj, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + BPTR DirLock = (BPTR)NULL; + + do { + struct MUI_NListtree_TreeNode *ln; + char IconPath[MAX_FILENAME]; + STRPTR DefIconName = ""; + + if (NULL == inst->fpb_IconObject) + break; + + ln = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, 0); + if (NULL == ln) + break; + + get(inst->fpb_Objects[OBJNDX_Text_FileTypes_DefIconName], MUIA_Text_Contents, &DefIconName); + + stccpy(IconPath, inst->fpb_DefIconPath, sizeof(IconPath)); + AddPart(IconPath, DefIconName, sizeof(IconPath)); + + DirLock = Lock(inst->fpb_DefIconPath, ACCESS_READ); + if ((BPTR)NULL == DirLock) + break; + + DefIconName = FilePart(IconPath); + if (NULL == DefIconName) + break; + + set(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, TRUE); + InvokeWBInfo(inst, DirLock, DefIconName); + SetFileTypesIcon(inst, ln); + set(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, FALSE); + } while (0); + + if (DirLock) + UnLock(DirLock); +} + +//---------------------------------------------------------------------------- + +BOOL DisplayFileTypesIcon(struct FileTypesPrefsInst *inst, CONST_STRPTR FileTypesName) +{ + char IconPath[MAX_FILENAME]; + BOOL Success = FALSE; + + if (inst->fpb_IconObject) + { + DisposeIconObject(inst->fpb_IconObject); + inst->fpb_IconObject = NULL; + } + + DefIconFullName(inst, IconPath, sizeof(IconPath), FileTypesName); + + inst->fpb_IconObject = NewIconObject(IconPath, NULL); + if (inst->fpb_IconObject) + { + // display name of filetype + set(inst->fpb_Objects[OBJNDX_Text_FileTypes_DefIconName], + MUIA_Text_Contents, FilePart(IconPath)); + + // display icon for filetype + set(inst->fpb_Objects[OBJNDX_IconObjectMCC_FileTypes_Icon], + MUIA_Iconobj_Object, inst->fpb_IconObject); + + Success = TRUE; + } + + return Success; +} + +//---------------------------------------------------------------------------- + +static void DefIconFullName(struct FileTypesPrefsInst *inst, + STRPTR Path, size_t MaxLen, CONST_STRPTR FileTypesName) +{ + stccpy(Path, inst->fpb_DefIconPath, MaxLen); + AddPart(Path, "def_", MaxLen); + strcat(Path, FileTypesName); +} + +//---------------------------------------------------------------------------- + +static void InvokeWBInfo(struct FileTypesPrefsInst *inst, + BPTR DirLock, STRPTR DefIconName) +{ + d1(KPrintF(__FILE__ "/%s/%ld: START DefIconName=<%s>\n", __FUNC__, __LINE__, DefIconName)); + + WBInfo(DirLock, DefIconName, inst->fpb_WBScreen); + + d1(KPrintF(__FILE__ "/%s/%ld: END\n", __FUNC__, __LINE__)); +} + +//---------------------------------------------------------------------------- + +static void SelectFileType(struct FileTypesPrefsInst *inst, const struct TypeNode *tn) +{ + d1(KPrintF(__FILE__ "/%s/%ld: START tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn->tn_Name)); + + // first, deselect current entry + set(inst->fpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Active, MUIV_NListtree_Active_Off); + + while (tn) + { + struct MUI_NListtree_TreeNode *lttn; + + d1(KPrintF(__FILE__ "/%s/%ld: tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn->tn_Name)); + + lttn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_FindName, + MUIV_NListtree_FindName_ListNode_Root, + tn->tn_Name, + MUIV_NListtree_FindName_Flag_SameLevel); + d1(KPrintF(__FILE__ "/%s/%ld: lttn=%08lx <%s>\n", __FUNC__, __LINE__, lttn, lttn ? lttn->tn_Name : "")); + if (lttn) + { + // Select correcponding entry in OBJNDX_MainListTree + set(inst->fpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Active, lttn); + break; + } + + tn = tn->tn_Parent; + } + + d1(KPrintF(__FILE__ "/%s/%ld: END\n", __FUNC__, __LINE__)); +} + +//---------------------------------------------------------------------------- + +static struct MUI_NListtree_TreeNode *GetRootEntry(struct FileTypesPrefsInst *inst, + struct MUI_NListtree_TreeNode *ln) +{ + struct MUI_NListtree_TreeNode *lnp; + struct MUI_NListtree_TreeNode *lnRoot = ln; + + do { + lnp = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], + MUIM_NListtree_GetEntry, + ln, + MUIV_NListtree_GetEntry_Position_Parent, + 0); + if (lnp) + { + lnRoot = ln; + ln = lnp; + } + } while (lnp); + + d1(KPrintF(__FILE__ "/%s/%ld: lnRoot=%08lx <%s>\n", __FUNC__, __LINE__, lnRoot, lnRoot ? lnRoot->tn_Name : (STRPTR) "")); + + return lnRoot; +} + +//---------------------------------------------------------------------------- + + diff --git a/scalos/Plugins/Prefs/FileTypes/DefaultDefIconsPrefs.c b/scalos/Plugins/Prefs/FileTypes/DefaultDefIconsPrefs.c new file mode 100644 index 000000000..7c1e091b0 --- /dev/null +++ b/scalos/Plugins/Prefs/FileTypes/DefaultDefIconsPrefs.c @@ -0,0 +1,255 @@ +// DefaultDefIconsPrefs.c +// $Date$ +// $Revision$ + + +//---------------------------------------------------------------------------- + +#include + +//---------------------------------------------------------------------------- + +const UBYTE DefaultDeficonsPrefs[] = + { + 0x70, 0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74, 0x00, 0x00, 0x01, 0x61, 0x73, 0x63, 0x69, 0x69, 0x00, + 0x08, 0x05, 0x7E, 0x28, 0x23, 0x3F, 0x2E, 0x70, 0x64, 0x66, 0x29, 0x00, 0x00, 0x01, 0x53, 0x63, + 0x61, 0x46, 0x69, 0x6C, 0x65, 0x54, 0x79, 0x70, 0x65, 0x00, 0x01, 0x00, 0x00, 0x1D, 0x23, 0x20, + 0x53, 0x63, 0x61, 0x6C, 0x6F, 0x73, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x74, 0x79, 0x70, 0x65, 0x20, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x07, 0x01, 0x00, 0x00, 0x20, + 0x23, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6F, 0x6E, + 0x07, 0x01, 0x00, 0x00, 0x1E, 0x23, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, + 0x66, 0x69, 0x6C, 0x65, 0x20, 0x54, 0x6F, 0x6F, 0x6C, 0x74, 0x69, 0x70, 0x20, 0x68, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x00, 0x68, 0x74, 0x6D, 0x6C, 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x68, 0x74, 0x6D, + 0x28, 0x7C, 0x6C, 0x29, 0x00, 0x00, 0x61, 0x6D, 0x69, 0x67, 0x61, 0x67, 0x75, 0x69, 0x64, 0x65, + 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x67, 0x75, 0x69, 0x64, 0x65, 0x00, 0x07, 0x03, 0xF7, 0x40, 0x64, + 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x00, 0x64, 0x6F, 0x63, 0x00, 0x05, 0x23, 0x3F, 0x28, + 0x2E, 0x64, 0x6F, 0x63, 0x7C, 0x2E, 0x74, 0x65, 0x78, 0x74, 0x7C, 0x72, 0x65, 0x61, 0x64, 0x6D, + 0x65, 0x23, 0x3F, 0x29, 0x00, 0x00, 0x70, 0x6F, 0x73, 0x74, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x70, 0x73, 0x00, 0x07, 0x01, 0x00, 0x00, 0xFC, 0x25, 0x21, 0x50, + 0x53, 0x00, 0x70, 0x6F, 0x73, 0x74, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x66, 0x6F, 0x6E, 0x74, + 0x00, 0x01, 0x00, 0x00, 0xF6, 0x25, 0x21, 0x46, 0x6F, 0x6E, 0x74, 0x54, 0x79, 0x70, 0x65, 0x07, + 0x01, 0x00, 0x00, 0xF2, 0x25, 0x21, 0x50, 0x53, 0x2D, 0x41, 0x64, 0x6F, 0x62, 0x65, 0x46, 0x6F, + 0x6E, 0x74, 0x00, 0x66, 0x64, 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x66, 0x64, 0x00, 0x00, 0x6D, 0x6F, + 0x75, 0x6E, 0x74, 0x6C, 0x69, 0x73, 0x74, 0x00, 0x02, 0xFA, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x02, 0x01, 0x3D, 0x02, 0xF8, 0x2E, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x0A, 0x07, 0x02, 0xF6, + 0x66, 0x69, 0x6C, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x02, 0x01, 0x3D, 0x02, 0xF5, 0x66, + 0x69, 0x6C, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x0A, 0x07, 0x02, 0xF9, 0x68, 0x61, 0x6E, + 0x64, 0x6C, 0x65, 0x72, 0x02, 0x01, 0x3D, 0x02, 0xF7, 0x2D, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, + 0x72, 0x0A, 0x00, 0x66, 0x69, 0x6C, 0x65, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x00, 0x14, + 0x00, 0x01, 0x75, 0x75, 0x65, 0x6E, 0x63, 0x6F, 0x64, 0x65, 0x00, 0x02, 0xFA, 0x62, 0x65, 0x67, + 0x69, 0x6E, 0x20, 0x02, 0x02, 0x0A, 0x4D, 0x01, 0x00, 0x3E, 0x02, 0x0A, 0x4D, 0x07, 0x02, 0xFA, + 0x62, 0x65, 0x67, 0x69, 0x6E, 0x20, 0x02, 0x02, 0x0A, 0x4D, 0x01, 0x00, 0x3F, 0x02, 0x0A, 0x4D, + 0x00, 0x02, 0x69, 0x6E, 0x73, 0x74, 0x61, 0x6C, 0x6C, 0x00, 0x02, 0xFB, 0x28, 0x69, 0x66, 0x20, + 0x28, 0x07, 0x02, 0xF6, 0x28, 0x63, 0x6F, 0x6D, 0x70, 0x6C, 0x65, 0x74, 0x65, 0x20, 0x07, 0x02, + 0xFB, 0x28, 0x73, 0x65, 0x74, 0x20, 0x00, 0x73, 0x72, 0x63, 0x00, 0x14, 0x00, 0x01, 0x70, 0x00, + 0x05, 0x23, 0x3F, 0x2E, 0x70, 0x28, 0x61, 0x73, 0x7C, 0x29, 0x28, 0x2E, 0x62, 0x61, 0x6B, 0x7C, + 0x29, 0x00, 0x00, 0x63, 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x63, 0x28, 0x2E, 0x62, 0x61, 0x6B, 0x7C, + 0x29, 0x00, 0x00, 0x63, 0x70, 0x70, 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x63, 0x28, 0x70, 0x70, 0x7C, + 0x78, 0x78, 0x7C, 0x63, 0x29, 0x28, 0x2E, 0x62, 0x61, 0x6B, 0x7C, 0x29, 0x00, 0x00, 0x68, 0x00, + 0x05, 0x23, 0x3F, 0x2E, 0x68, 0x28, 0x70, 0x70, 0x7C, 0x29, 0x28, 0x2E, 0x62, 0x61, 0x6B, 0x7C, + 0x29, 0x00, 0x00, 0x69, 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x69, 0x28, 0x2E, 0x62, 0x61, 0x6B, 0x7C, + 0x29, 0x00, 0x00, 0x61, 0x73, 0x6D, 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x28, 0x61, 0x7C, 0x61, 0x73, + 0x6D, 0x7C, 0x61, 0x36, 0x38, 0x7C, 0x73, 0x29, 0x28, 0x2E, 0x62, 0x61, 0x6B, 0x7C, 0x29, 0x00, + 0x00, 0x6A, 0x61, 0x76, 0x61, 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x28, 0x6A, 0x61, 0x76, 0x7C, 0x6A, + 0x61, 0x76, 0x61, 0x29, 0x00, 0x00, 0x62, 0x61, 0x73, 0x69, 0x63, 0x00, 0x14, 0x00, 0x01, 0x62, + 0x62, 0x61, 0x73, 0x69, 0x63, 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x28, 0x62, 0x61, 0x73, 0x7C, 0x67, + 0x66, 0x61, 0x29, 0x28, 0x2E, 0x62, 0x61, 0x6B, 0x7C, 0x29, 0x00, 0x00, 0x02, 0x65, 0x00, 0x05, + 0x23, 0x3F, 0x2E, 0x65, 0x28, 0x2E, 0x62, 0x61, 0x6B, 0x7C, 0x29, 0x00, 0x00, 0x6D, 0x00, 0x05, + 0x23, 0x3F, 0x2E, 0x6D, 0x28, 0x2E, 0x62, 0x61, 0x6B, 0x7C, 0x29, 0x00, 0x00, 0x02, 0x74, 0x65, + 0x78, 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x28, 0x74, 0x65, 0x78, 0x7C, 0x73, 0x74, 0x79, 0x29, 0x28, + 0x2E, 0x62, 0x61, 0x6B, 0x7C, 0x29, 0x00, 0x00, 0x6D, 0x61, 0x6B, 0x65, 0x00, 0x05, 0x23, 0x3F, + 0x6D, 0x61, 0x6B, 0x65, 0x66, 0x69, 0x6C, 0x65, 0x23, 0x3F, 0x00, 0x00, 0x65, 0x6D, 0x61, 0x69, + 0x6C, 0x00, 0x02, 0xFB, 0x46, 0x72, 0x6F, 0x6D, 0x3A, 0x02, 0xFD, 0x54, 0x6F, 0x3A, 0x07, 0x02, + 0xF7, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x3A, 0x07, 0x02, 0xF4, 0x52, 0x65, 0x74, + 0x75, 0x72, 0x6E, 0x2D, 0x50, 0x61, 0x74, 0x68, 0x3A, 0x02, 0xF3, 0x44, 0x65, 0x6C, 0x69, 0x76, + 0x65, 0x72, 0x65, 0x64, 0x2D, 0x54, 0x6F, 0x3A, 0x00, 0x70, 0x72, 0x6F, 0x6C, 0x6F, 0x67, 0x00, + 0x05, 0x23, 0x3F, 0x2E, 0x70, 0x6C, 0x28, 0x2E, 0x62, 0x61, 0x6B, 0x7C, 0x29, 0x00, 0x00, 0x72, + 0x65, 0x78, 0x78, 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x72, 0x65, 0x78, 0x78, 0x00, 0x00, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x02, + 0x69, 0x63, 0x6F, 0x6E, 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x69, 0x6E, 0x66, 0x6F, 0x00, 0x01, 0x00, + 0x00, 0x02, 0xE3, 0x10, 0x00, 0x70, 0x64, 0x66, 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x70, 0x64, 0x66, + 0x00, 0x00, 0x74, 0x6F, 0x6F, 0x6C, 0x00, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0xF3, 0x07, + 0x01, 0x00, 0x00, 0x04, 0x7F, 0x45, 0x4C, 0x46, 0x00, 0x01, 0x45, 0x4C, 0x46, 0x00, 0x01, 0x00, + 0x00, 0x04, 0x7F, 0x45, 0x4C, 0x46, 0x00, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x00, 0x02, 0x02, + 0x03, 0xE9, 0x02, 0x02, 0x4A, 0xFC, 0x01, 0x00, 0x0C, 0x01, 0x03, 0x07, 0x05, 0x23, 0x3F, 0x2E, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x6C, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x00, + 0x02, 0x02, 0x03, 0xE9, 0x02, 0x02, 0x4A, 0xFC, 0x01, 0x00, 0x0C, 0x01, 0x09, 0x07, 0x05, 0x23, + 0x3F, 0x2E, 0x28, 0x6C, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x7C, 0x64, 0x61, 0x74, 0x61, 0x74, + 0x79, 0x70, 0x65, 0x7C, 0x67, 0x61, 0x64, 0x67, 0x65, 0x74, 0x7C, 0x63, 0x6C, 0x61, 0x73, 0x73, + 0x7C, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x29, 0x00, 0x00, 0x6B, 0x65, 0x79, 0x6D, 0x61, 0x70, 0x00, + 0x02, 0x02, 0x03, 0xE9, 0x01, 0x00, 0x06, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x66, 0x6F, 0x6E, 0x74, 0x00, 0x02, 0x02, 0x03, 0xE9, 0x01, 0x00, 0x06, 0x01, + 0x70, 0x01, 0x00, 0x08, 0x0C, 0x4E, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, + 0x00, 0x01, 0x00, 0x18, 0x02, 0x0F, 0x80, 0x00, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x00, + 0x02, 0x02, 0x03, 0xE9, 0x01, 0x00, 0x06, 0x05, 0x70, 0x00, 0x4E, 0x75, 0x00, 0x01, 0x00, 0x0E, + 0x02, 0x00, 0x00, 0x01, 0x00, 0x12, 0x02, 0x00, 0x00, 0x01, 0x00, 0x16, 0x02, 0x00, 0x00, 0x01, + 0x00, 0x1A, 0x02, 0x00, 0x00, 0x01, 0x00, 0x1E, 0x02, 0x00, 0x00, 0x00, 0x73, 0x66, 0x78, 0x00, + 0x01, 0x00, 0x2C, 0x04, 0x53, 0x46, 0x58, 0x21, 0x00, 0x66, 0x69, 0x6C, 0x65, 0x73, 0x79, 0x73, + 0x74, 0x65, 0x6D, 0x00, 0x05, 0x23, 0x3F, 0x66, 0x69, 0x6C, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, + 0x6D, 0x00, 0x00, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x72, 0x00, 0x05, 0x23, 0x3F, 0x68, 0x61, + 0x6E, 0x64, 0x6C, 0x65, 0x72, 0x00, 0x00, 0x6C, 0x6F, 0x61, 0x64, 0x6D, 0x6F, 0x64, 0x75, 0x6C, + 0x65, 0x00, 0x02, 0x02, 0x03, 0xE9, 0x01, 0x00, 0x06, 0x01, 0x70, 0x01, 0x00, 0x08, 0x02, 0x4E, + 0x75, 0x07, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x69, 0x66, 0x66, + 0x00, 0x01, 0x00, 0x00, 0x04, 0x43, 0x41, 0x54, 0x20, 0x07, 0x01, 0x00, 0x00, 0x04, 0x4C, 0x49, + 0x53, 0x54, 0x00, 0x01, 0x76, 0x69, 0x64, 0x65, 0x6F, 0x00, 0x14, 0x00, 0x01, 0x46, 0x49, 0x4C, + 0x4D, 0x00, 0x01, 0x00, 0x08, 0x04, 0x46, 0x49, 0x4C, 0x4D, 0x00, 0x02, 0x02, 0x69, 0x66, 0x66, + 0x00, 0x01, 0x00, 0x00, 0x04, 0x46, 0x4F, 0x52, 0x4D, 0x01, 0x00, 0x10, 0x01, 0x00, 0x00, 0x01, + 0x53, 0x63, 0x61, 0x6C, 0x6F, 0x73, 0x50, 0x72, 0x65, 0x66, 0x73, 0x00, 0x01, 0x00, 0x08, 0x04, + 0x50, 0x52, 0x45, 0x46, 0x01, 0x00, 0x0C, 0x04, 0x50, 0x52, 0x48, 0x44, 0x00, 0x01, 0x53, 0x63, + 0x61, 0x4D, 0x61, 0x69, 0x6E, 0x50, 0x72, 0x65, 0x66, 0x73, 0x00, 0x01, 0x00, 0x1A, 0x04, 0x4D, + 0x41, 0x49, 0x4E, 0x00, 0x53, 0x63, 0x61, 0x50, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6E, 0x50, 0x72, + 0x65, 0x66, 0x73, 0x00, 0x01, 0x00, 0x1A, 0x04, 0x44, 0x45, 0x46, 0x53, 0x00, 0x53, 0x63, 0x61, + 0x50, 0x61, 0x6C, 0x65, 0x74, 0x74, 0x65, 0x50, 0x72, 0x65, 0x66, 0x73, 0x00, 0x01, 0x00, 0x1A, + 0x04, 0x53, 0x50, 0x41, 0x4C, 0x00, 0x53, 0x63, 0x61, 0x4D, 0x65, 0x6E, 0x75, 0x50, 0x72, 0x65, + 0x66, 0x73, 0x00, 0x01, 0x00, 0x1A, 0x04, 0x4D, 0x45, 0x4E, 0x55, 0x00, 0x02, 0x43, 0x54, 0x4C, + 0x47, 0x00, 0x01, 0x00, 0x08, 0x04, 0x43, 0x54, 0x4C, 0x47, 0x00, 0x46, 0x54, 0x58, 0x54, 0x00, + 0x01, 0x00, 0x08, 0x04, 0x46, 0x54, 0x58, 0x54, 0x00, 0x44, 0x54, 0x59, 0x50, 0x00, 0x01, 0x00, + 0x08, 0x04, 0x44, 0x54, 0x59, 0x50, 0x00, 0x66, 0x61, 0x78, 0x00, 0x01, 0x00, 0x08, 0x04, 0x46, + 0x41, 0x58, 0x58, 0x00, 0x77, 0x77, 0x64, 0x00, 0x01, 0x00, 0x08, 0x04, 0x57, 0x4F, 0x57, 0x4F, + 0x00, 0x66, 0x77, 0x64, 0x00, 0x01, 0x00, 0x08, 0x04, 0x53, 0x57, 0x52, 0x54, 0x00, 0x50, 0x54, + 0x43, 0x48, 0x00, 0x01, 0x00, 0x08, 0x04, 0x50, 0x54, 0x43, 0x48, 0x00, 0x73, 0x6F, 0x75, 0x6E, + 0x64, 0x00, 0x14, 0x00, 0x01, 0x38, 0x73, 0x76, 0x78, 0x00, 0x01, 0x00, 0x08, 0x04, 0x38, 0x53, + 0x56, 0x58, 0x00, 0x41, 0x49, 0x46, 0x46, 0x00, 0x01, 0x00, 0x08, 0x03, 0x41, 0x49, 0x46, 0x00, + 0x02, 0x76, 0x69, 0x64, 0x65, 0x6F, 0x00, 0x14, 0x00, 0x01, 0x61, 0x6E, 0x69, 0x6D, 0x00, 0x01, + 0x00, 0x08, 0x04, 0x41, 0x4E, 0x49, 0x4D, 0x00, 0x02, 0x6D, 0x75, 0x73, 0x69, 0x63, 0x00, 0x14, + 0x00, 0x01, 0x73, 0x6D, 0x75, 0x73, 0x00, 0x01, 0x00, 0x08, 0x04, 0x53, 0x4D, 0x55, 0x53, 0x00, + 0x63, 0x6D, 0x75, 0x73, 0x00, 0x01, 0x00, 0x08, 0x04, 0x43, 0x4D, 0x55, 0x53, 0x00, 0x64, 0x6D, + 0x63, 0x73, 0x00, 0x01, 0x00, 0x08, 0x04, 0x44, 0x4D, 0x43, 0x53, 0x00, 0x02, 0x49, 0x4C, 0x42, + 0x4D, 0x00, 0x01, 0x00, 0x08, 0x04, 0x49, 0x4C, 0x42, 0x4D, 0x00, 0x01, 0x62, 0x72, 0x75, 0x73, + 0x68, 0x00, 0x02, 0x04, 0x47, 0x52, 0x41, 0x42, 0x00, 0x02, 0x02, 0x50, 0x52, 0x45, 0x46, 0x00, + 0x04, 0x00, 0x00, 0x00, 0xE8, 0x01, 0x00, 0x00, 0x01, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0xE8, + 0x01, 0x00, 0x00, 0x01, 0x09, 0x07, 0x05, 0x23, 0x3F, 0x28, 0x2E, 0x7C, 0x29, 0x70, 0x72, 0x65, + 0x66, 0x28, 0x73, 0x7C, 0x29, 0x00, 0x07, 0x05, 0x23, 0x3F, 0x28, 0x2E, 0x7C, 0x29, 0x28, 0x63, + 0x6F, 0x6E, 0x66, 0x69, 0x67, 0x7C, 0x63, 0x66, 0x67, 0x29, 0x00, 0x00, 0x6B, 0x69, 0x63, 0x6B, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x00, 0x01, 0x00, 0x08, 0x04, 0x4B, 0x49, 0x43, 0x4B, 0x00, 0x67, + 0x61, 0x6D, 0x65, 0x00, 0x14, 0x00, 0x01, 0x64, 0x75, 0x6E, 0x65, 0x32, 0x00, 0x05, 0x5F, 0x53, + 0x41, 0x56, 0x45, 0x3F, 0x3F, 0x3F, 0x2E, 0x44, 0x41, 0x54, 0x00, 0x01, 0x00, 0x00, 0x04, 0x46, + 0x4F, 0x52, 0x4D, 0x01, 0x00, 0x08, 0x08, 0x53, 0x43, 0x45, 0x4E, 0x4E, 0x41, 0x4D, 0x45, 0x00, + 0x02, 0x65, 0x6D, 0x70, 0x74, 0x79, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6F, 0x62, 0x6A, + 0x65, 0x63, 0x74, 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x28, 0x6F, 0x7C, 0x6F, 0x62, 0x6A, 0x29, 0x00, + 0x00, 0x6C, 0x69, 0x62, 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x6C, 0x69, 0x62, 0x00, 0x07, 0x05, 0x23, + 0x3F, 0x2E, 0x61, 0x00, 0x00, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x00, 0x14, 0x00, 0x01, + 0x62, 0x7A, 0x69, 0x70, 0x32, 0x00, 0x01, 0x00, 0x00, 0x03, 0x42, 0x5A, 0x68, 0x05, 0x23, 0x3F, + 0x2E, 0x62, 0x7A, 0x32, 0x00, 0x00, 0x6C, 0x68, 0x61, 0x72, 0x63, 0x00, 0x01, 0x00, 0x02, 0x03, + 0x2D, 0x6C, 0x68, 0x01, 0x00, 0x06, 0x01, 0x2D, 0x00, 0x6C, 0x7A, 0x78, 0x00, 0x01, 0x00, 0x00, + 0x03, 0x4C, 0x5A, 0x58, 0x00, 0x61, 0x72, 0x63, 0x00, 0x01, 0x00, 0x00, 0x02, 0x1A, 0x08, 0x00, + 0x61, 0x72, 0x6A, 0x00, 0x01, 0x00, 0x00, 0x02, 0x60, 0xEA, 0x00, 0x72, 0x61, 0x72, 0x00, 0x01, + 0x00, 0x00, 0x04, 0x52, 0x61, 0x72, 0x21, 0x00, 0x70, 0x61, 0x6B, 0x00, 0x01, 0x00, 0x00, 0x04, + 0x50, 0x41, 0x43, 0x4B, 0x05, 0x23, 0x3F, 0x2E, 0x70, 0x61, 0x6B, 0x00, 0x00, 0x73, 0x69, 0x74, + 0x00, 0x01, 0x00, 0x00, 0x08, 0x53, 0x74, 0x75, 0x66, 0x66, 0x49, 0x74, 0x20, 0x05, 0x23, 0x3F, + 0x2E, 0x73, 0x69, 0x74, 0x00, 0x00, 0x77, 0x61, 0x64, 0x00, 0x01, 0x00, 0x00, 0x04, 0x49, 0x57, + 0x41, 0x44, 0x05, 0x23, 0x3F, 0x2E, 0x77, 0x61, 0x64, 0x00, 0x00, 0x7A, 0x69, 0x70, 0x00, 0x01, + 0x00, 0x00, 0x04, 0x50, 0x4B, 0x03, 0x04, 0x00, 0x7A, 0x6F, 0x6F, 0x00, 0x01, 0x00, 0x00, 0x04, + 0x5A, 0x4F, 0x4F, 0x20, 0x00, 0x74, 0x61, 0x72, 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x74, 0x61, 0x72, + 0x2E, 0x67, 0x7A, 0x00, 0x07, 0x05, 0x23, 0x3F, 0x2E, 0x74, 0x61, 0x72, 0x00, 0x07, 0x05, 0x23, + 0x3F, 0x2E, 0x74, 0x67, 0x7A, 0x00, 0x07, 0x01, 0x01, 0x59, 0x08, 0x41, 0x6D, 0x69, 0x67, 0x61, + 0x54, 0x61, 0x72, 0x00, 0x72, 0x70, 0x6D, 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x72, 0x70, 0x6D, 0x00, + 0x01, 0x00, 0x00, 0x04, 0xED, 0xAB, 0xEE, 0xDB, 0x00, 0x02, 0x64, 0x69, 0x73, 0x6B, 0x61, 0x72, + 0x63, 0x68, 0x69, 0x76, 0x65, 0x00, 0x14, 0x00, 0x01, 0x64, 0x6D, 0x73, 0x00, 0x01, 0x00, 0x00, + 0x04, 0x44, 0x4D, 0x53, 0x21, 0x00, 0x77, 0x61, 0x72, 0x70, 0x00, 0x01, 0x00, 0x00, 0x04, 0x57, + 0x61, 0x72, 0x70, 0x00, 0x7A, 0x6F, 0x6F, 0x6D, 0x00, 0x01, 0x00, 0x00, 0x04, 0x5A, 0x4F, 0x4F, + 0x4D, 0x07, 0x01, 0x00, 0x00, 0x04, 0x5A, 0x4F, 0x4D, 0x35, 0x00, 0x6C, 0x68, 0x77, 0x61, 0x72, + 0x70, 0x00, 0x01, 0x00, 0x00, 0x04, 0x01, 0x03, 0x09, 0x00, 0x00, 0x61, 0x64, 0x66, 0x00, 0x01, + 0x00, 0x00, 0x03, 0x44, 0x4F, 0x53, 0x05, 0x23, 0x3F, 0x2E, 0x61, 0x64, 0x66, 0x00, 0x00, 0x02, + 0x70, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x00, 0x14, 0x00, 0x01, 0x67, 0x69, 0x66, 0x00, 0x01, + 0x00, 0x00, 0x06, 0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x07, 0x01, 0x00, 0x00, 0x06, 0x47, 0x49, + 0x46, 0x38, 0x39, 0x61, 0x00, 0x6A, 0x70, 0x65, 0x67, 0x00, 0x01, 0x00, 0x00, 0x02, 0xFF, 0xD8, + 0x07, 0x01, 0x00, 0x06, 0x04, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x70, 0x6E, 0x67, 0x00, 0x01, 0x00, + 0x00, 0x08, 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x72, 0x65, 0x6B, 0x6F, 0x00, + 0x01, 0x00, 0x00, 0x04, 0x52, 0x45, 0x4B, 0x4F, 0x00, 0x62, 0x6D, 0x70, 0x00, 0x01, 0x00, 0x00, + 0x02, 0x42, 0x4D, 0x01, 0x00, 0x06, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x69, 0x66, 0x66, + 0x00, 0x01, 0x00, 0x00, 0x04, 0x4D, 0x4D, 0x00, 0x2A, 0x07, 0x01, 0x00, 0x00, 0x04, 0x4D, 0x4D, + 0x2A, 0x00, 0x07, 0x01, 0x00, 0x00, 0x04, 0x49, 0x49, 0x2A, 0x00, 0x00, 0x73, 0x75, 0x6E, 0x72, + 0x61, 0x73, 0x74, 0x65, 0x72, 0x00, 0x01, 0x00, 0x00, 0x04, 0x59, 0xA6, 0x6A, 0x95, 0x00, 0x70, + 0x63, 0x78, 0x00, 0x01, 0x00, 0x00, 0x03, 0x0A, 0x05, 0x01, 0x07, 0x01, 0x00, 0x00, 0x03, 0x0A, + 0x02, 0x01, 0x00, 0x49, 0x43, 0x4F, 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x49, 0x43, 0x4F, 0x00, 0x00, + 0x74, 0x61, 0x72, 0x67, 0x61, 0x00, 0x01, 0x00, 0x0C, 0x04, 0x50, 0x00, 0x40, 0x00, 0x00, 0x02, + 0x76, 0x69, 0x64, 0x65, 0x6F, 0x00, 0x14, 0x00, 0x01, 0x77, 0x6D, 0x76, 0x00, 0x05, 0x23, 0x3F, + 0x2E, 0x77, 0x6D, 0x76, 0x00, 0x01, 0x00, 0x00, 0x04, 0x30, 0x26, 0xB2, 0x75, 0x00, 0x6D, 0x70, + 0x65, 0x67, 0x34, 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x6D, 0x70, 0x34, 0x00, 0x07, 0x05, 0x23, 0x3F, + 0x2E, 0x6D, 0x70, 0x65, 0x67, 0x34, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x71, + 0x75, 0x69, 0x63, 0x6B, 0x74, 0x69, 0x6D, 0x65, 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x6D, 0x6F, 0x76, + 0x00, 0x00, 0x66, 0x6C, 0x69, 0x00, 0x01, 0x00, 0x03, 0x03, 0x00, 0x11, 0xAF, 0x00, 0x72, 0x65, + 0x61, 0x6C, 0x76, 0x69, 0x64, 0x65, 0x6F, 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x72, 0x6D, 0x00, 0x01, + 0x00, 0x00, 0x04, 0x2E, 0x52, 0x4D, 0x46, 0x00, 0x6D, 0x70, 0x65, 0x67, 0x00, 0x05, 0x23, 0x3F, + 0x2E, 0x28, 0x6D, 0x70, 0x67, 0x7C, 0x6D, 0x70, 0x65, 0x67, 0x29, 0x00, 0x01, 0x00, 0x00, 0x0A, + 0x00, 0x00, 0x01, 0xBA, 0x21, 0x00, 0x01, 0x00, 0x01, 0x80, 0x07, 0x05, 0x23, 0x3F, 0x2E, 0x28, + 0x6D, 0x70, 0x67, 0x7C, 0x6D, 0x70, 0x65, 0x67, 0x29, 0x00, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, + 0x01, 0xBA, 0x21, 0x00, 0x07, 0x05, 0x23, 0x3F, 0x2E, 0x28, 0x6D, 0x70, 0x67, 0x7C, 0x6D, 0x70, + 0x65, 0x67, 0x29, 0x00, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0xB3, 0x00, 0x72, 0x69, 0x66, + 0x66, 0x00, 0x14, 0x01, 0x00, 0x00, 0x04, 0x52, 0x49, 0x46, 0x46, 0x00, 0x01, 0x61, 0x76, 0x69, + 0x00, 0x01, 0x00, 0x08, 0x04, 0x41, 0x56, 0x49, 0x20, 0x00, 0x02, 0x6F, 0x67, 0x67, 0x00, 0x01, + 0x00, 0x00, 0x04, 0x4F, 0x67, 0x67, 0x53, 0x00, 0x02, 0x73, 0x6F, 0x75, 0x6E, 0x64, 0x00, 0x14, + 0x00, 0x01, 0x72, 0x69, 0x66, 0x66, 0x00, 0x01, 0x00, 0x00, 0x04, 0x52, 0x49, 0x46, 0x46, 0x00, + 0x01, 0x77, 0x61, 0x76, 0x00, 0x01, 0x00, 0x08, 0x04, 0x57, 0x41, 0x56, 0x45, 0x00, 0x02, 0x73, + 0x75, 0x6E, 0x61, 0x75, 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x61, 0x75, 0x00, 0x07, 0x01, 0x00, 0x00, + 0x04, 0x2E, 0x73, 0x6E, 0x64, 0x00, 0x68, 0x73, 0x6E, 0x64, 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x68, + 0x73, 0x6E, 0x00, 0x07, 0x01, 0x00, 0x00, 0x04, 0x48, 0x53, 0x4E, 0x44, 0x00, 0x76, 0x6F, 0x63, + 0x00, 0x01, 0x00, 0x00, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x56, 0x6F, + 0x69, 0x63, 0x65, 0x20, 0x46, 0x69, 0x6C, 0x65, 0x00, 0x02, 0x6D, 0x75, 0x73, 0x69, 0x63, 0x00, + 0x14, 0x00, 0x01, 0x6D, 0x65, 0x64, 0x00, 0x01, 0x00, 0x00, 0x03, 0x4D, 0x45, 0x44, 0x07, 0x01, + 0x00, 0x00, 0x03, 0x4D, 0x4D, 0x44, 0x07, 0x05, 0x23, 0x3F, 0x2E, 0x6D, 0x65, 0x64, 0x00, 0x00, + 0x6D, 0x6F, 0x64, 0x00, 0x05, 0x28, 0x6D, 0x6F, 0x64, 0x2E, 0x23, 0x3F, 0x7C, 0x23, 0x3F, 0x2E, + 0x6D, 0x6F, 0x64, 0x7C, 0x23, 0x3F, 0x2E, 0x6D, 0x6F, 0x64, 0x2E, 0x23, 0x3F, 0x29, 0x00, 0x00, + 0x63, 0x61, 0x6B, 0x65, 0x77, 0x61, 0x6C, 0x6B, 0x00, 0x01, 0x00, 0x00, 0x08, 0x43, 0x41, 0x4B, + 0x45, 0x57, 0x41, 0x4C, 0x4B, 0x00, 0x6D, 0x69, 0x64, 0x69, 0x00, 0x01, 0x00, 0x00, 0x08, 0x4D, + 0x54, 0x68, 0x64, 0x00, 0x00, 0x00, 0x06, 0x00, 0x73, 0x33, 0x6D, 0x00, 0x05, 0x23, 0x3F, 0x2E, + 0x73, 0x33, 0x6D, 0x00, 0x07, 0x02, 0x04, 0x53, 0x43, 0x52, 0x4D, 0x00, 0x6D, 0x70, 0x33, 0x00, + 0x05, 0x23, 0x3F, 0x2E, 0x6D, 0x70, 0x33, 0x00, 0x07, 0x01, 0x00, 0x00, 0x02, 0xFF, 0xFB, 0x00, + 0x6D, 0x70, 0x32, 0x00, 0x01, 0x00, 0x00, 0x02, 0xFF, 0xFD, 0x00, 0x6F, 0x67, 0x67, 0x00, 0x05, + 0x23, 0x3F, 0x2E, 0x6F, 0x67, 0x67, 0x00, 0x01, 0x00, 0x00, 0x04, 0x4F, 0x67, 0x67, 0x53, 0x00, + 0x72, 0x65, 0x61, 0x6C, 0x61, 0x75, 0x64, 0x69, 0x6F, 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x72, 0x61, + 0x00, 0x00, 0x78, 0x6D, 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x78, 0x6D, 0x00, 0x07, 0x01, 0x00, 0x00, + 0x0F, 0x45, 0x78, 0x74, 0x65, 0x6E, 0x64, 0x65, 0x64, 0x20, 0x4D, 0x6F, 0x64, 0x75, 0x6C, 0x65, + 0x00, 0x63, 0x6D, 0x6F, 0x64, 0x00, 0x01, 0x00, 0x00, 0x08, 0x4F, 0x4B, 0x54, 0x41, 0x53, 0x4F, + 0x4E, 0x47, 0x00, 0x02, 0x6B, 0x69, 0x63, 0x6B, 0x73, 0x74, 0x61, 0x72, 0x74, 0x00, 0x01, 0x00, + 0x00, 0x04, 0x11, 0x11, 0x4E, 0xF9, 0x01, 0x00, 0x08, 0x04, 0x00, 0x00, 0xFF, 0xFF, 0x07, 0x01, + 0x00, 0x00, 0x04, 0x11, 0x14, 0x4E, 0xF9, 0x01, 0x00, 0x08, 0x04, 0x00, 0x00, 0xFF, 0xFF, 0x07, + 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x04, 0x11, 0x14, 0x4E, 0xF9, + 0x01, 0x00, 0x10, 0x04, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x66, 0x6F, 0x6E, 0x74, 0x00, 0x01, 0x00, + 0x00, 0x02, 0x0F, 0x00, 0x07, 0x01, 0x00, 0x00, 0x02, 0x0F, 0x02, 0x00, 0x6F, 0x75, 0x74, 0x6C, + 0x69, 0x6E, 0x65, 0x66, 0x6F, 0x6E, 0x74, 0x00, 0x01, 0x00, 0x00, 0x02, 0x0F, 0x03, 0x07, 0x01, + 0x00, 0x00, 0x04, 0x80, 0x00, 0x10, 0x01, 0x07, 0x01, 0x00, 0x00, 0x04, 0x00, 0x44, 0x00, 0x01, + 0x01, 0x00, 0x12, 0x02, 0xFF, 0xFF, 0x00, 0x70, 0x6F, 0x73, 0x74, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x66, 0x6F, 0x6E, 0x74, 0x00, 0x01, 0x00, 0x00, 0xF6, 0x25, 0x21, 0x46, 0x6F, 0x6E, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x07, 0x01, 0x00, 0x00, 0xF2, 0x25, 0x21, 0x50, 0x53, 0x2D, 0x41, 0x64, + 0x6F, 0x62, 0x65, 0x46, 0x6F, 0x6E, 0x74, 0x07, 0x01, 0x00, 0x06, 0xF6, 0x25, 0x21, 0x46, 0x6F, + 0x6E, 0x74, 0x54, 0x79, 0x70, 0x65, 0x07, 0x01, 0x00, 0x06, 0xF2, 0x25, 0x21, 0x50, 0x53, 0x2D, + 0x41, 0x64, 0x6F, 0x62, 0x65, 0x46, 0x6F, 0x6E, 0x74, 0x00, 0x74, 0x72, 0x75, 0x65, 0x74, 0x79, + 0x70, 0x65, 0x66, 0x6F, 0x6E, 0x74, 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x74, 0x74, 0x66, 0x00, 0x01, + 0x00, 0x00, 0xFC, 0x00, 0x01, 0x00, 0x00, 0x00, 0x4C, 0x57, 0x4F, 0x42, 0x00, 0x01, 0x00, 0x00, + 0x04, 0x4C, 0x57, 0x53, 0x43, 0x00, 0x57, 0x6F, 0x72, 0x64, 0x50, 0x65, 0x72, 0x66, 0x65, 0x63, + 0x74, 0x00, 0x01, 0x00, 0x00, 0x04, 0xFF, 0x57, 0x50, 0x43, 0x00, 0x4D, 0x53, 0x57, 0x6F, 0x72, + 0x64, 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x44, 0x4F, 0x43, 0x00, 0x01, 0x00, 0x00, 0x08, 0xD0, 0xCF, + 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1, 0x07, 0x01, 0x00, 0x00, 0x08, 0xFE, 0x37, 0x00, 0x23, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x4D, 0x53, 0x45, 0x78, 0x63, 0x65, 0x6C, 0x00, 0x05, 0x23, 0x3F, 0x2E, + 0x58, 0x4C, 0x3F, 0x00, 0x01, 0x00, 0x00, 0x08, 0xFE, 0x37, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, + 0x07, 0x01, 0x00, 0x00, 0x08, 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1, 0x00, 0x50, 0x69, + 0x63, 0x56, 0x69, 0x65, 0x77, 0x00, 0x01, 0x00, 0x00, 0x04, 0x50, 0x56, 0x44, 0x03, 0x07, 0x01, + 0x00, 0x00, 0x04, 0x50, 0x56, 0x44, 0x01, 0x00, 0x6B, 0x65, 0x79, 0x00, 0x05, 0x23, 0x3F, 0x2E, + 0x6B, 0x65, 0x79, 0x28, 0x7C, 0x66, 0x69, 0x6C, 0x65, 0x29, 0x00, 0x00, 0x66, 0x69, 0x6C, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x00, 0x14, 0x00, 0x01, 0x70, 0x6F, 0x77, 0x65, 0x72, + 0x70, 0x61, 0x63, 0x6B, 0x65, 0x72, 0x00, 0x01, 0x00, 0x00, 0x04, 0x50, 0x50, 0x32, 0x30, 0x07, + 0x01, 0x00, 0x00, 0x04, 0x50, 0x50, 0x33, 0x30, 0x07, 0x01, 0x00, 0x00, 0x04, 0x50, 0x50, 0x34, + 0x30, 0x07, 0x01, 0x00, 0x00, 0x04, 0x50, 0x58, 0x32, 0x30, 0x07, 0x01, 0x00, 0x00, 0x04, 0x50, + 0x58, 0x33, 0x30, 0x07, 0x01, 0x00, 0x00, 0x04, 0x50, 0x58, 0x34, 0x30, 0x00, 0x69, 0x6D, 0x70, + 0x6C, 0x6F, 0x64, 0x65, 0x72, 0x00, 0x01, 0x00, 0x00, 0x04, 0x49, 0x4D, 0x50, 0x21, 0x00, 0x78, + 0x70, 0x61, 0x63, 0x6B, 0x65, 0x72, 0x00, 0x01, 0x00, 0x00, 0x04, 0x58, 0x50, 0x4B, 0x46, 0x00, + 0x72, 0x6E, 0x63, 0x00, 0x01, 0x00, 0x00, 0x03, 0x52, 0x4E, 0x43, 0x00, 0x63, 0x6F, 0x6D, 0x70, + 0x72, 0x65, 0x73, 0x73, 0x00, 0x01, 0x00, 0x00, 0x02, 0x1F, 0x9D, 0x00, 0x67, 0x7A, 0x69, 0x70, + 0x00, 0x01, 0x00, 0x00, 0x02, 0x1F, 0x8B, 0x00, 0x02, 0x6C, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, + 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x62, 0x6D, 0x61, 0x70, 0x00, 0x00, 0x70, 0x74, 0x63, 0x68, 0x00, + 0x01, 0x00, 0x00, 0x04, 0x50, 0x54, 0x47, 0x32, 0x00, 0x74, 0x63, 0x64, 0x00, 0x05, 0x23, 0x3F, + 0x2E, 0x74, 0x63, 0x64, 0x00, 0x07, 0x01, 0x00, 0x03, 0x09, 0x54, 0x55, 0x52, 0x42, 0x4F, 0x43, + 0x41, 0x4C, 0x43, 0x00, 0x6A, 0x61, 0x76, 0x61, 0x00, 0x05, 0x23, 0x3F, 0x2E, 0x63, 0x6C, 0x61, + 0x73, 0x73, 0x00, 0x01, 0x00, 0x00, 0x04, 0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x02, 0x44, 0x69, 0x73, + 0x6B, 0x00, 0x00, 0x01, 0x43, 0x44, 0x00, 0x0A, 0x43, 0x44, 0x23, 0x3F, 0x00, 0x00, 0x01, 0x44, + 0x56, 0x44, 0x00, 0x0D, 0x00, 0x00, 0x03, 0xE8, 0x00, 0x01, 0x56, 0x69, 0x64, 0x65, 0x6F, 0x2D, + 0x44, 0x56, 0x44, 0x00, 0x0C, 0x3A, 0x56, 0x49, 0x44, 0x45, 0x4F, 0x5F, 0x54, 0x53, 0x2F, 0x23, + 0x3F, 0x2E, 0x56, 0x4F, 0x42, 0x00, 0x00, 0x02, 0x02, 0x53, 0x4D, 0x42, 0x2D, 0x44, 0x69, 0x73, + 0x6B, 0x00, 0x0A, 0x23, 0x3F, 0x73, 0x6D, 0x62, 0x66, 0x73, 0x00, 0x00, 0x55, 0x53, 0x42, 0x2D, + 0x44, 0x69, 0x73, 0x6B, 0x00, 0x0B, 0x23, 0x3F, 0x75, 0x73, 0x62, 0x23, 0x3F, 0x00, 0x00, 0x52, + 0x41, 0x4D, 0x44, 0x69, 0x73, 0x6B, 0x00, 0x0A, 0x52, 0x41, 0x4D, 0x00, 0x00, 0x00, 0x00 + }; + diff --git a/scalos/Plugins/Prefs/FileTypes/FileTypesPrefs.c b/scalos/Plugins/Prefs/FileTypes/FileTypesPrefs.c new file mode 100644 index 000000000..c88bc4e21 --- /dev/null +++ b/scalos/Plugins/Prefs/FileTypes/FileTypesPrefs.c @@ -0,0 +1,7887 @@ +// FileTypesPrefs.c +// $Date$ +// $Revision$ + +#ifdef __AROS__ +#define MUIMASTER_YES_INLINE_STDARG +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define USE_INLINE_STDARG +#include +#undef USE_INLINE_STDARG + +#if !defined(__AROS__) +#define NO_INLINE_STDARG +#endif +#include + +#include +#include +#include + +#include +#include +#include + +#include "defs.h" +#include // +jmc+ + +#include +#include "IconobjectMCC.h" +#include "DataTypesMCC.h" +#include "debug.h" + +#include "FileTypesPrefs.h" +#include "FileTypesPrefs_proto.h" + +#define ScalosFileTypes_NUMBERS +#define ScalosFileTypes_ARRAY +#define ScalosFileTypes_CODE +#include STR(SCALOSLOCALE) + +#include "plugin.h" + +//---------------------------------------------------------------------------- + +#define ID_MAIN MAKE_ID('M','A','I','N') +#define PS_DATA(prefsstruct) ((STRPTR) (prefsstruct)) + sizeof((prefsstruct)->ps_Size) + +#define ENV_FILETYPES_DIR "ENV:Scalos/FileTypes" +#define ENVARC_FILETYPES_DIR "ENVARC:Scalos/FileTypes" +#define ENV_DEFICONS_PREFS "ENV:deficons.prefs" +#define ENVARC_DEFICONS_PREFS "ENVARC:deficons.prefs" + +//---------------------------------------------------------------------------- + +#define IMG(prefix1,PREFIX2) \ + BodychunkObject,\ + MUIA_FixWidth , PREFIX2##_WIDTH ,\ + MUIA_FixHeight , PREFIX2##_HEIGHT,\ + MUIA_Bitmap_Width , PREFIX2##_WIDTH ,\ + MUIA_Bitmap_Height , PREFIX2##_HEIGHT,\ + MUIA_Bodychunk_Depth , PREFIX2##_DEPTH ,\ + MUIA_Bodychunk_Body , (UBYTE *) prefix1##_body,\ + MUIA_Bodychunk_Compression, PREFIX2##_COMPRESSION,\ + MUIA_Bodychunk_Masking , PREFIX2##_MASKING,\ + MUIA_Bitmap_SourceColors , (ULONG *) prefix1##_colors,\ + MUIA_Bitmap_Transparent , 0,\ + End + +//---------------------------------------------------------------------------- + +// local data structures + +#define KeyButtonHelp(name,key,HelpText)\ + TextObject,\ + ButtonFrame,\ + MUIA_CycleChain, TRUE, \ + MUIA_Font, MUIV_Font_Button,\ + MUIA_Text_Contents, (ULONG) GetLocString(name),\ + MUIA_Text_PreParse, "\33c",\ + MUIA_Text_HiChar , key,\ + MUIA_ControlChar , key,\ + MUIA_InputMode , MUIV_InputMode_RelVerify,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShortHelp , (ULONG) GetLocString(HelpText),\ + End + +#define KeyButtonHelp2(name,key,HelpText,Weight)\ + TextObject,\ + ButtonFrame,\ + MUIA_CycleChain, TRUE, \ + MUIA_Font, MUIV_Font_Button,\ + MUIA_Text_Contents, (ULONG) GetLocString(name),\ + MUIA_Text_PreParse, "\33c",\ + MUIA_Text_HiChar , (ULONG) *GetLocString(key),\ + MUIA_ControlChar , (ULONG) *GetLocString(key),\ + MUIA_InputMode , MUIV_InputMode_RelVerify,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShortHelp , (ULONG) GetLocString(HelpText),\ + MUIA_Weight , (Weight), \ + End + +#define CheckMarkHelp(selected, HelpTextID)\ + ImageObject,\ + ImageButtonFrame,\ + MUIA_CycleChain , TRUE, \ + MUIA_InputMode , MUIV_InputMode_Toggle,\ + MUIA_Image_Spec , MUII_CheckMark,\ + MUIA_Image_FreeVert , TRUE,\ + MUIA_Selected , selected,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShowSelState , FALSE,\ + MUIA_ShortHelp , GetLocString(HelpTextID),\ + End + +struct AddEntryListEntry + { + enum FtEntryType ael_EntryType; + }; + +struct AddAttrListEntry + { + enum ftAttributeType aal_EntryType; + }; + +struct EditAttrListEntry + { + char eal_ValueString[MAX_ATTRVALUE]; + struct FtAttribute eal_fta; + }; + +enum AttrDefaultType + { + ATTRDEFTYPE_None, + ATTRDEFTYPE_ULong, + ATTRDEFTYPE_LocString, + ATTRDEFTYPE_String, + ATTRDEFTYPE_String2, + ATTRDEFTYPE_PathName, + ATTRDEFTYPE_FileName, + ATTRDEFTYPE_FontString, + ATTRDEFTYPE_TTFontString, + }; + +struct AttrDefaultValue + { + enum AttrDefaultType avd_Type; + ULONG avd_ULongValue; + + char *avd_StringValue; + + ULONG (*avd_ConvertValueFromString)(CONST_STRPTR DisplayString); + }; + +struct AttributeDef + { + enum ftAttributeType atd_Type; + + BOOL atd_Required; + + ULONG atd_ExcludeCount; + enum ftAttributeType atd_Exclude[10]; + + ULONG atd_MinValue; // Minimum ULONG value or minimal string length + ULONG atd_MaxValue; // Maximum ULONG value or maximal string length + + struct AttrDefaultValue atd_DefaultContents; + + struct AttrDefaultValue *atd_PossibleContents; + ULONG atd_NumberOfValues; + }; + +struct EntryAttributes + { + enum FtEntryType eat_EntryType; + const struct AttributeDef *eat_AttrArray; + ULONG eat_AttrCount; // number of entries in eat_AttrArray + }; + +enum FindDir + { + FINDDIR_First = 0, + FINDDIR_Next, + FINDDIR_Prev + }; + +struct FoundNode + { + struct Node fdn_Node; + Object *fdn_ListTree; + struct MUI_NListtree_TreeNode *fdn_TreeNode; + ULONG fdn_Index; + }; + +//---------------------------------------------------------------------------- + +// aus mempools.lib +#if !defined(__amigaos4__) && !defined(__AROS__) +extern int _STI_240_InitMemFunctions(void); +extern void _STD_240_TerminateMemFunctions(void); +#endif + +//---------------------------------------------------------------------------- + +// local functions + +DISPATCHER_PROTO(FileTypesPrefs); +static Object *CreatePrefsGroup(struct FileTypesPrefsInst *inst); +static Object **CreateSubWindows(Class *cl, Object *o); +static Object *CreatePrefsImage(void); +static void InitHooks(struct FileTypesPrefsInst *inst); + +static BOOL OpenLibraries(void); +static void CloseLibraries(void); +static void TranslateNewMenu(struct NewMenu *nm); +static void TranslateStringArray(STRPTR *stringArray); + +static SAVEDS(APTR) INTERRUPT TreeConstructFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_ConstructMessage *ltcm); +static SAVEDS(void) INTERRUPT TreeDestructFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_DestructMessage *ltdm); +static SAVEDS(ULONG) INTERRUPT TreeDisplayFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_DisplayMessage *ltdm); + +static SAVEDS(APTR) INTERRUPT AttrConstructFunc(struct Hook *hook, APTR obj, struct NList_ConstructMessage *ltcm); +static SAVEDS(void) INTERRUPT AttrDestructFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm); +static SAVEDS(ULONG) INTERRUPT AttrDisplayFunc(struct Hook *hook, APTR obj, struct NList_DisplayMessage *ltdm); + +static SAVEDS(APTR) INTERRUPT AddEntryConstructFunc(struct Hook *hook, APTR obj, struct NList_ConstructMessage *ltcm); +static SAVEDS(void) INTERRUPT AddEntryDestructFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm); +static SAVEDS(ULONG) INTERRUPT AddEntryDisplayFunc(struct Hook *hook, APTR obj, struct NList_DisplayMessage *ltdm); + +static SAVEDS(APTR) INTERRUPT AddAttrConstructFunc(struct Hook *hook, APTR obj, struct NList_ConstructMessage *ltcm); +static SAVEDS(void) INTERRUPT AddAttrDestructFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm); +static SAVEDS(ULONG) INTERRUPT AddAttrDisplayFunc(struct Hook *hook, APTR obj, struct NList_DisplayMessage *ltdm); + +static SAVEDS(APTR) INTERRUPT EditAttrConstructFunc(struct Hook *hook, APTR obj, struct NList_ConstructMessage *ltcm); +static SAVEDS(void) INTERRUPT EditAttrDestructFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm); +static SAVEDS(ULONG) INTERRUPT EditAttrDisplayFunc(struct Hook *hook, APTR obj, struct NList_DisplayMessage *ltdm); + +static SAVEDS(ULONG) INTERRUPT EditAttrTTFontOpenHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(ULONG) INTERRUPT EditAttrTTFontCloseHookFunc(struct Hook *hook, Object *obj, Msg msg); + +static SAVEDS(APTR) INTERRUPT ResetToDefaultsHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT LastSavedHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT RestoreHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT HideEmptyEntriesHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT CollapseHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT ExpandHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT CollapseAllHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT ExpandAllHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT CollapseFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT ExpandFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT CollapseAllFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT ExpandAllFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT CopyHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT CutHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT PasteHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT CopyAttrHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT CutAttrHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT PasteAttrHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT SelectEntryHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT SelectAttributeHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT EditAttributeHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT AboutFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT ContextMenuTriggerHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT AddEntryHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT AddAttributeHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT RemoveEntryHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT RemoveAttributeHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT ChangeAttributeHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT SelectAttributeValueHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(ULONG) INTERRUPT EditAttributePopAslFileStartHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(ULONG) INTERRUPT EditAttributePopAslPathStartHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT OpenHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT SaveAsHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT AslIntuiMsgHookFunc(struct Hook *hook, Object *o, Msg msg); +static BOOL IncrementalSearchFileType(struct FileTypesPrefsInst *inst, + CONST_STRPTR SearchString, enum FindDir dir); +static void BuildFindTree(struct FileTypesPrefsInst *inst, + Object *ListTree, + struct MUI_NListtree_TreeNode *list, CONST_STRPTR pattern, + struct MUI_NListtree_TreeNode *startnode, ULONG *dosearch, BOOL CaseSensitive); +static SAVEDS(void) INTERRUPT ShowFindGroupHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT HideFindGroupHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT IncrementalFindFileTypeHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT IncrementalFindNextFileTypeHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT IncrementalFindPrevFileTypeHookFunc(struct Hook *hook, Object *o, Msg msg); + +static LONG ReadPrefs(struct FileTypesPrefsInst *inst, + CONST_STRPTR LoadName, CONST_STRPTR DefIconPrefsName); +static LONG WritePrefs(struct FileTypesPrefsInst *inst, + CONST_STRPTR SaveName, CONST_STRPTR DefIconPrefsName, ULONG Flags); + +DISPATCHER_PROTO(myNListTree); +DISPATCHER_PROTO(myFileTypesNListTree); +DISPATCHER_PROTO(myNList); +DISPATCHER_PROTO(myFileTypesActionsNList); + + +static void DisposeAttribute(struct FtAttribute *fta); +static void CleanupAttributes(struct List *AttributesList); +static const struct FtAttribute *FindAttribute(const struct FileTypesListEntry *fte, enum FtEntryType AttrType); +static void RemoveAttribute(struct FileTypesListEntry *fte, enum ftAttributeType AttrType); +static struct FileTypesListEntry *FindChildByType(struct FileTypesPrefsInst *inst, + struct MUI_NListtree_TreeNode *tn, enum FtEntryType RequestedType); +static BOOL HasChildren(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn); +static void AddDefaultAttributes(struct FileTypesPrefsInst *inst, struct FileTypesListEntry *fte); +static void SetAddableAttributes(struct FileTypesPrefsInst *inst, struct FileTypesListEntry *fte); +static void UpdateAttributes(struct FileTypesPrefsInst *inst, struct FileTypesListEntry *fte); +static void AddNewAttribute(struct FileTypesPrefsInst *inst, struct FileTypesListEntry *fte, enum ftAttributeType AttrType); +static void BeginSetMenuDefaultAction(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn); +static void SetMenuDefaultAction(struct FileTypesPrefsInst *inst, + struct MUI_NListtree_TreeNode *tnMenu, struct MUI_NListtree_TreeNode *tnNewDefault); +static const struct AttributeDef *GetAttributeDef(enum ftAttributeType AttrType, enum FtEntryType fteEntryType); +static void FillListOfAttributeValues(struct FileTypesPrefsInst *inst, + const struct FileTypesListEntry *fte, const struct AttributeDef *atd, + const struct AttrListEntry *Attr); +static ULONG ConvertGroupOrientationFromString(CONST_STRPTR DisplayString); +static struct MUI_NListtree_TreeNode *CopyFileTypesEntry(struct FileTypesPrefsInst *inst, + struct MUI_NListtree_TreeNode *tnToListNode, struct MUI_NListtree_TreeNode *tnToPrevNode, + struct MUI_NListtree_TreeNode *tnFrom, ULONG destList, ULONG srcList); +static BOOL MayPasteOnto(struct FileTypesPrefsInst *inst, + struct MUI_NListtree_TreeNode *tnTo, struct MUI_NListtree_TreeNode *tnFrom); +static struct MUI_NListtree_TreeNode *MayPasteBelow(struct FileTypesPrefsInst *inst, + struct MUI_NListtree_TreeNode *tnTo, struct MUI_NListtree_TreeNode *tnFrom); +static void EnablePasteMenuEntry(struct FileTypesPrefsInst *inst); +static BOOL MayPasteAttr(struct FileTypesPrefsInst *inst, const struct FileTypesListEntry *fte, const struct AttrListEntry *Attr); +static void EnablePasteAttrMenuEntry(struct FileTypesPrefsInst *inst); +static BOOL IsAttrRequired(struct FileTypesListEntry *fte, const struct AttributeDef *atd); +static void EntryHasChanged(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn); +static void SetChangedFlag(struct FileTypesPrefsInst *inst, BOOL changed); +static void BuildTTDescFromAttrList(char *buffer, size_t length, struct TagItem *AttrList); +static BOOL ParseTTFontFromDesc(CONST_STRPTR FontDesc, + ULONG *FontStyle, ULONG *FontWeight, ULONG *FontSize, + STRPTR FontName, size_t FontNameSize); +static void ShowHiddenNodes(struct FileTypesPrefsInst *inst); +static void ParseToolTypes(struct FileTypesPrefsInst *inst, struct MUIP_ScalosPrefs_ParseToolTypes *ptt); +static LONG ReadScalosPrefs(struct FileTypesPrefsInst *inst, CONST_STRPTR PrefsFileName); +static CONST_STRPTR GetPrefsConfigString(APTR prefsHandle, ULONG Id, CONST_STRPTR DefaultString); +static ULONG DoDragDrop(Class *cl, Object *obj, Msg msg); +static struct FoundNode *AddFoundNode(struct FileTypesPrefsInst *inst, Object *ListTree, struct MUI_NListtree_TreeNode *tn); +static CONST_STRPTR FindString(CONST_STRPTR string, CONST_STRPTR pattern, BOOL CaseSensitive); + +#if !defined(__SASC) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) +static size_t stccpy(char *dest, const char *src, size_t MaxLen); +#endif /* !defined(__SASC) && !defined(__MORPHOS__) && !defined(__amigaos4__) */ + +//---------------------------------------------------------------------------- + +// local data items + +struct Library *MUIMasterBase; +T_LOCALEBASE LocaleBase; +struct GfxBase *GfxBase; +struct Library *WorkbenchBase; +struct Library *IconBase; +struct Library *IFFParseBase; +struct Library *IconobjectBase; +T_UTILITYBASE UtilityBase; +struct IntuitionBase *IntuitionBase; +struct Library *TTEngineBase; +struct Library *DiskfontBase; +struct Library *PreferencesBase; +struct Library *DataTypesBase; + +#ifdef __amigaos4__ +struct Library *DOSBase; +struct DOSIFace *IDOS; +struct MUIMasterIFace *IMUIMaster; +struct LocaleIFace *ILocale; +struct GraphicsIFace *IGraphics; +struct WorkbenchIFace *IWorkbench; +struct IconIFace *IIcon; +struct IFFParseIFace *IIFFParse; +struct IconobjectIFace *IIconobject; +struct UtilityIFace *IUtility; +struct IntuitionIFace *IIntuition; +struct TTEngineIFace *ITTEngine; +struct DiskfontIFace *IDiskfont; +struct PreferencesIFace *IPreferences; +struct DataTypesIFace *IDataTypes; +struct Library *NewlibBase; +struct Interface *INewlib; +#endif + +#ifdef __AROS__ +struct DosLibrary *DOSBase; +#endif + +struct MUI_CustomClass *FileTypesPrefsClass; +struct MUI_CustomClass *myNListClass; +struct MUI_CustomClass *myFileTypesActionsNListClass; +struct MUI_CustomClass *myNListTreeClass; +struct MUI_CustomClass *myFileTypesNListTreeClass; +struct MUI_CustomClass *FontSampleClass; +struct MUI_CustomClass *IconobjectClass; +struct MUI_CustomClass *DataTypesImageClass; + +#ifdef __AROS__ +#define myNListTreeObject BOOPSIOBJMACRO_START(myNListTreeClass->mcc_Class) +#define myNListObject BOOPSIOBJMACRO_START(myNListClass->mcc_Class) +#define myFileTypesNListTreeObject BOOPSIOBJMACRO_START(myFileTypesNListTreeClass->mcc_Class) +#define myFileTypesActionsNListObject BOOPSIOBJMACRO_START(myFileTypesActionsNListClass->mcc_Class) +#else +#define myNListTreeObject NewObject(myNListTreeClass->mcc_Class, 0 +#define myNListObject NewObject(myNListClass->mcc_Class, 0 +#define myFileTypesNListTreeObject NewObject(myFileTypesNListTreeClass->mcc_Class, 0 +#define myFileTypesActionsNListObject NewObject(myFileTypesActionsNListClass->mcc_Class, 0 +#endif + +static struct Catalog *FileTypesPrefsCatalog; +static struct Locale *FileTypesPrefsLocale; + +static BOOL StaticsTranslated; + +static const struct MUIP_ScalosPrefs_MCCList RequiredMccList[] = + { + { MUIC_NListtree, 18, 18 }, + { MUIC_NList, 18, 0 }, + { NULL, 0, 0 } + }; + +static ULONG MajorVersion, MinorVersion; + +static const struct Hook FileTypesPrefsHooks[] = +{ + { { NULL, NULL }, NULL, NULL, NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(OpenHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(SaveAsHookFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(TreeDisplayFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(TreeConstructFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(TreeDestructFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(AttrDisplayFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(AttrConstructFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(AttrDestructFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(AddEntryDisplayFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(AddEntryConstructFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(AddEntryDestructFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(AddAttrDisplayFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(AddAttrConstructFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(AddAttrDestructFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(EditAttrDisplayFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(EditAttrConstructFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(EditAttrDestructFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(FileTypesDisplayFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(FileTypesConstructFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(FileTypesDestructFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(FileTypesActionDisplayFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(FileTypesActionConstructFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(FileTypesActionDestructFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(SelectEntryHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(SelectAttributeHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(EditAttributeHookFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(AboutFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(ContextMenuTriggerHookFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(CollapseHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ExpandHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(CollapseAllHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ExpandAllHookFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(CollapseFileTypesHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ExpandFileTypesHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(CollapseAllFileTypesHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ExpandAllFileTypesHookFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(CopyHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(CutHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(PasteHookFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(CopyAttrHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(CutAttrHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(PasteAttrHookFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(AddEntryHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(AddAttributeHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(RemoveEntryHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(RemoveAttributeHookFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(ChangeAttributeHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(SelectAttributeValueHookFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(EditAttributePopAslFileStartHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(EditAttributePopAslPathStartHookFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(EditAttrTTFontOpenHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(EditAttrTTFontCloseHookFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(ResetToDefaultsHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(LastSavedHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(RestoreHookFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(HideEmptyEntriesHookFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(SelectFileTypesEntryHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(SelectFileTypesActionEntryHookFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(RenameFileTypeHookFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(AddFileTypeHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(RemoveFileTypeHookFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(AddFileTypesMethodHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(RemoveFileTypesActionHookFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(ChangedFileTypesActionMatchMatchHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ChangedFileTypesActionMatchCaseHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ChangedFileTypesActionMatchOffsetHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ChangedFileTypesActionSearchSearchHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ChangedFileTypesActionSearchCaseHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ChangedFileTypesActionSearchSkipSpacesHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ChangedFileTypesActionFilesizeHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ChangedFileTypesActionPatternHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ChangedFileTypesActionProtectionHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ChangedFileTypesActionDosDeviceHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ChangedFileTypesActionDeviceNameHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ChangedFileTypesActionContentsHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ChangedFileTypesActionDosTypeHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ChangedFileTypesActionMinSizeHookFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(FileTypesActionDragDropSortHookFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(ShowFindGroupHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(HideFindGroupHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(IncrementalFindFileTypeHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(IncrementalFindNextFileTypeHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(IncrementalFindPrevFileTypeHookFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(LearnFileTypeHookFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(CreateNewFileTypesIconHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(EditFileTypesIconHookFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(AslIntuiMsgHookFunc), NULL }, +}; + + +// Context menu in "filetypes" list +static struct NewMenu ContextMenuFileTypes[] = + { + { NM_TITLE, (STRPTR) MSGID_TITLENAME, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_EDIT_COLLAPSE, NULL, NM_ITEMDISABLED, 0, (APTR) HOOKNDX_CollapseFileTypes }, + { NM_ITEM, (STRPTR) MSGID_MENU_EDIT_EXPAND, NULL, NM_ITEMDISABLED, 0, (APTR) HOOKNDX_ExpandFileTypes }, + { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_EDIT_COLLAPSEALL, NULL, 0, 0, (APTR) HOOKNDX_CollapseAllFileTypes }, + { NM_ITEM, (STRPTR) MSGID_MENU_EDIT_EXPANDALL, NULL, 0, 0, (APTR) HOOKNDX_ExpandAllFileTypes }, + { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_EDIT_FIND, NULL, NM_ITEMDISABLED, 0, (APTR) HOOKNDX_ShowFindGroup }, + { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_ABOUT, NULL, 0, 0, (APTR) HOOKNDX_About }, + + { NM_END, NULL, NULL, 0, 0, 0,}, + }; + +// Context menu on "methods" list +static struct NewMenu ContextMenuFileTypesActions[] = + { + { NM_TITLE, (STRPTR) MSGID_TITLENAME, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_OPEN, (STRPTR) MSGID_MENU_PROJECT_OPEN_SHORT, 0, 0, (APTR) HOOKNDX_Open }, + { NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_SAVEAS, (STRPTR) MSGID_MENU_PROJECT_SAVEAS_SHORT, 0, 0, (APTR) HOOKNDX_SaveAs }, + { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_ABOUT, NULL, 0, 0, (APTR) HOOKNDX_About }, + + { NM_END, NULL, NULL, 0, 0, 0,}, + }; + +static struct NewMenu ContextMenus[] = + { + { NM_TITLE, (STRPTR) MSGID_TITLENAME, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_EDIT_COLLAPSE, NULL, NM_ITEMDISABLED, 0, (APTR) HOOKNDX_Collapse }, + { NM_ITEM, (STRPTR) MSGID_MENU_EDIT_EXPAND, NULL, NM_ITEMDISABLED, 0, (APTR) HOOKNDX_Expand }, + { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_HIDE_EMPTY_ENTRIES, NULL, CHECKIT|MENUTOGGLE, 0, (APTR) HOOKNDX_HideEmptyEntries }, + { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_EDIT_COPY, NULL, NM_ITEMDISABLED, 0, (APTR) HOOKNDX_Copy }, + { NM_ITEM, (STRPTR) MSGID_MENU_EDIT_CUT, NULL, NM_ITEMDISABLED, 0, (APTR) HOOKNDX_Cut }, + { NM_ITEM, (STRPTR) MSGID_MENU_EDIT_PASTE, NULL, NM_ITEMDISABLED, 0, (APTR) HOOKNDX_Paste }, + { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_EDIT_COLLAPSEALL, NULL, 0, 0, (APTR) HOOKNDX_CollapseAll }, + { NM_ITEM, (STRPTR) MSGID_MENU_EDIT_EXPANDALL, NULL, 0, 0, (APTR) HOOKNDX_ExpandAll }, + { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_ABOUT, NULL, 0, 0, (APTR) HOOKNDX_About }, + + { NM_END, NULL, NULL, 0, 0, 0,}, + }; + +static struct NewMenu ContextMenusAttrList[] = + { + { NM_TITLE, (STRPTR) MSGID_TITLENAME, NULL, 0, 0, NULL }, + { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_EDIT_COPY, NULL, NM_ITEMDISABLED, 0, (APTR) HOOKNDX_CopyAttr }, + { NM_ITEM, (STRPTR) MSGID_MENU_EDIT_CUT, NULL, NM_ITEMDISABLED, 0, (APTR) HOOKNDX_CutAttr }, + { NM_ITEM, (STRPTR) MSGID_MENU_EDIT_PASTE, NULL, NM_ITEMDISABLED, 0, (APTR) HOOKNDX_PasteAttr }, + { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_ABOUT, NULL, 0, 0, (APTR) HOOKNDX_About }, + + { NM_END, NULL, NULL, 0, 0, 0,}, + }; + +static const BOOL MayPasteAfterMatrix[ENTRYTYPE_MAX][ENTRYTYPE_MAX] = + { + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 + /* 0 ENTRYTYPE_FileType */ + { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + + /* 1 ENTRYTYPE_PopupMenu */ + { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + + /* 2 ENTRYTYPE_PopupMenu_SubMenu */ + { FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + /* 3 ENTRYTYPE_PopupMenu_MenuItem */ + { FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + + /* 4 ENTRYTYPE_PopupMenu_InternalCmd */ + { FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + /* 5 ENTRYTYPE_PopupMenu_WbCmd */ + { FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + /* 6 ENTRYTYPE_PopupMenu_ARexxCmd */ + { FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + /* 7 ENTRYTYPE_PopupMenu_CliCmd */ + { FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + /* 8 ENTRYTYPE_PopupMenu_PluginCmd */ + { FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + /* 9 ENTRYTYPE_PopupMenu_IconWindowCmd */ + { FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + + /* 10 ENTRYTYPE_PopupMenu_MenuSeparator */ + { FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + + /* 11 ENTRYTYPE_ToolTip */ + { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + /* 12 ENTRYTYPE_ToolTip_Group */ + { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + /* 13 ENTRYTYPE_ToolTip_Member */ + { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE}, + /* 14 ENTRYTYPE_ToolTip_HBar */ + { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + /* 15 ENTRYTYPE_ToolTip_String */ + { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + /* 16 ENTRYTYPE_ToolTip_Space */ + { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + /* 17 ENTRYTYPE_ToolTip_DtImage */ + { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 + }; +static const BOOL MayPasteIntoMatrix[ENTRYTYPE_MAX][ENTRYTYPE_MAX] = + { + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 + /* 0 ENTRYTYPE_FileType */ + { FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + + /* 1 ENTRYTYPE_PopupMenu */ + { FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + /* 2 ENTRYTYPE_PopupMenu_SubMenu */ + { FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + /* 3 ENTRYTYPE_PopupMenu_MenuItem */ + { FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + + /* 4 ENTRYTYPE_PopupMenu_InternalCmd */ + { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + /* 5 ENTRYTYPE_PopupMenu_WbCmd */ + { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + /* 6 ENTRYTYPE_PopupMenu_ARexxCmd */ + { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + /* 7 ENTRYTYPE_PopupMenu_CliCmd */ + { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + /* 8 ENTRYTYPE_PopupMenu_PluginCmd */ + { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + /* 9 ENTRYTYPE_PopupMenu_IconWindowCmd */ + { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + + /* 10 ENTRYTYPE_PopupMenu_MenuSeparator */ + { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + + /* 11 ENTRYTYPE_ToolTip */ + { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE}, + /* 12 ENTRYTYPE_ToolTip_Group */ + { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE}, + /* 13 ENTRYTYPE_ToolTip_Member */ + { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE}, + /* 14 ENTRYTYPE_ToolTip_HBar */ + { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + /* 15 ENTRYTYPE_ToolTip_String */ + { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + /* 16 ENTRYTYPE_ToolTip_Space */ + { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + /* 17 ENTRYTYPE_ToolTip_DtImage */ + { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 + }; + +static const ULONG EntryTypeNames[] = + { + MSGID_ENTRYTYPE_FILETYPE, + + MSGID_ENTRYTYPE_POPUPMENU, + MSGID_ENTRYTYPE_SUBMENU, + MSGID_ENTRYTYPE_MENUITEM, + MSGID_ENTRYTYPE_INTERNALCMD, + MSGID_ENTRYTYPE_WBCMD, + MSGID_ENTRYTYPE_AREXXCMD, + MSGID_ENTRYTYPE_CLICMD, + MSGID_ENTRYTYPE_PLUGINCMD, + MSGID_ENTRYTYPE_ICONWINDOWCMD, + MSGID_ENTRYTYPE_MENUSEPARATOR, + + MSGID_ENTRYTYPE_TOOLTIP, + MSGID_ENTRYTYPE_GROUP, + MSGID_ENTRYTYPE_MEMBER, + MSGID_ENTRYTYPE_HBAR, + MSGID_ENTRYTYPE_STRING, + MSGID_ENTRYTYPE_SPACE, + MSGID_ENTRYTYPE_DTIMAGE, + }; + +static const ULONG AddFiletypeStringsPM[] = + { + ENTRYTYPE_PopupMenu, + 0 + }; +static const ULONG AddFiletypeStringsTT[] = + { + ENTRYTYPE_ToolTip, + 0 + }; +static const ULONG AddFiletypeStringsPMTT[] = + { + ENTRYTYPE_PopupMenu, + ENTRYTYPE_ToolTip, + 0 + }; +static const ULONG AddPopupMenuStrings[] = + { + ENTRYTYPE_PopupMenu_SubMenu, + ENTRYTYPE_PopupMenu_MenuItem, + ENTRYTYPE_PopupMenu_MenuSeparator, + 0 + }; +static const ULONG AddSubMenuStrings[] = + { + ENTRYTYPE_PopupMenu_MenuItem, + ENTRYTYPE_PopupMenu_MenuSeparator, + 0 + }; +static const ULONG AddMenuItemStrings[] = + { + ENTRYTYPE_PopupMenu_InternalCmd, + ENTRYTYPE_PopupMenu_WbCmd, + ENTRYTYPE_PopupMenu_ARexxCmd, + ENTRYTYPE_PopupMenu_CliCmd, + ENTRYTYPE_PopupMenu_PluginCmd, + ENTRYTYPE_PopupMenu_IconWindowCmd, + 0 + }; +static const ULONG AddToolTipStrings[] = + { + ENTRYTYPE_ToolTip_Group, + 0 + }; +static const ULONG AddGroupStrings[] = + { + ENTRYTYPE_ToolTip_Member, + 0 + }; +static const ULONG AddMemberStrings[] = + { + ENTRYTYPE_ToolTip_Group, + ENTRYTYPE_ToolTip_HBar, + ENTRYTYPE_ToolTip_String, + ENTRYTYPE_ToolTip_Space, + ENTRYTYPE_ToolTip_DtImage, + 0 + }; + +static STRPTR RegisterTitles[] = + { + (STRPTR) MSGID_REGISTERTITLE_RECOGNITION, + (STRPTR) MSGID_REGISTERTITLE_ACTIONS, + NULL + }; + +STRPTR AddFileTypeActionStrings[] = + { + (STRPTR) MSGID_FILETYPE_ADD_ACTION_MATCH, + (STRPTR) MSGID_FILETYPE_ADD_ACTION_SEARCH, + (STRPTR) MSGID_FILETYPE_ADD_ACTION_FILESIZE, + (STRPTR) MSGID_FILETYPE_ADD_ACTION_PATTERN, + (STRPTR) MSGID_FILETYPE_ADD_ACTION_PROTECTION, + (STRPTR) MSGID_FILETYPE_ADD_ACTION_OR, + (STRPTR) MSGID_FILETYPE_ADD_ACTION_ISASCII, + (STRPTR) MSGID_FILETYPE_ADD_ACTION_DOSDEVICE, + (STRPTR) MSGID_FILETYPE_ADD_ACTION_DEVICENAME, + (STRPTR) MSGID_FILETYPE_ADD_ACTION_CONTENTS, + (STRPTR) MSGID_FILETYPE_ADD_ACTION_DOSTYPE, + (STRPTR) MSGID_FILETYPE_ADD_ACTION_MINSIZEMB, + (STRPTR) MSGID_FILETYPE_ADD_ACTION_MACROCLASS, + NULL + }; + +STRPTR AddFileTypeActionStringsProject[] = + { + (STRPTR) MSGID_FILETYPE_ADD_ACTION_MATCH, + (STRPTR) MSGID_FILETYPE_ADD_ACTION_SEARCH, + (STRPTR) MSGID_FILETYPE_ADD_ACTION_FILESIZE, + (STRPTR) MSGID_FILETYPE_ADD_ACTION_PATTERN, + (STRPTR) MSGID_FILETYPE_ADD_ACTION_PROTECTION, + (STRPTR) MSGID_FILETYPE_ADD_ACTION_OR, + (STRPTR) MSGID_FILETYPE_ADD_ACTION_ISASCII, + (STRPTR) MSGID_FILETYPE_ADD_ACTION_MACROCLASS, + NULL + }; + +STRPTR AddFileTypeActionStringsDisk[] = + { + (STRPTR) MSGID_FILETYPE_ADD_ACTION_OR, + (STRPTR) MSGID_FILETYPE_ADD_ACTION_ISASCII, + (STRPTR) MSGID_FILETYPE_ADD_ACTION_DOSDEVICE, + (STRPTR) MSGID_FILETYPE_ADD_ACTION_DEVICENAME, + (STRPTR) MSGID_FILETYPE_ADD_ACTION_CONTENTS, + (STRPTR) MSGID_FILETYPE_ADD_ACTION_DOSTYPE, + (STRPTR) MSGID_FILETYPE_ADD_ACTION_MINSIZEMB, + (STRPTR) MSGID_FILETYPE_ADD_ACTION_MACROCLASS, + NULL + }; + +static STRPTR FileTypeActionProtectionStrings[] = + { + (STRPTR) MSGID_FILETYPE_PROTECTION_SET, + (STRPTR) MSGID_FILETYPE_PROTECTION_UNSET, + (STRPTR) MSGID_FILETYPE_PROTECTION_IGNORE, + NULL, + }; + +static struct AttrDefaultValue AttrDefStringStyleContents[] = + { + { ATTRDEFTYPE_String, 0, "normal" }, + { ATTRDEFTYPE_String, 0, "bold" }, + { ATTRDEFTYPE_String, 0, "italic" }, + { ATTRDEFTYPE_String, MSGID_CHANGEME, "bolditalic" }, + }; +static struct AttrDefaultValue AttrDefStringHAlignContents[] = + { + { ATTRDEFTYPE_String, 0, "left" }, + { ATTRDEFTYPE_String, 0, "center" }, + { ATTRDEFTYPE_String, 0, "right" }, + }; +static struct AttrDefaultValue AttrDefStringVAlignContents[] = + { + { ATTRDEFTYPE_String, 0, "top" }, + { ATTRDEFTYPE_String, 0, "center" }, + { ATTRDEFTYPE_String, 0, "bottom" }, + }; +static struct AttrDefaultValue AttrDefStringPenContents[] = + { + { ATTRDEFTYPE_String, 0, "PENIDX_HSHINEPEN" }, + { ATTRDEFTYPE_String, 0, "PENIDX_HSHADOWPEN" }, + { ATTRDEFTYPE_String, 0, "PENIDX_ICONTEXTOUTLINEPEN", }, + { ATTRDEFTYPE_String, 0, "PENIDX_DRAWERTEXT" }, + { ATTRDEFTYPE_String, 0, "PENIDX_DRAWERTEXTSEL" }, + { ATTRDEFTYPE_String, 0, "PENIDX_DRAWERBG", }, + { ATTRDEFTYPE_String, 0, "PENIDX_FILETEXT" }, + { ATTRDEFTYPE_String, 0, "PENIDX_FILETEXTSEL" }, + { ATTRDEFTYPE_String, 0, "PENIDX_FILEBG" }, + { ATTRDEFTYPE_String, 0, "PENIDX_BACKDROPDETAIL" }, + { ATTRDEFTYPE_String, 0, "PENIDX_BACKDROPBLOCK" }, + { ATTRDEFTYPE_String, 0, "PENIDX_TOOLTIP_TEXT" }, + { ATTRDEFTYPE_String, 0, "PENIDX_TOOLTIP_BG" }, + { ATTRDEFTYPE_String, 0, "PENIDX_DRAGINFOTEXT_TEXT" }, + { ATTRDEFTYPE_String, 0, "PENIDX_DRAGINFOTEXT_BG" }, + { ATTRDEFTYPE_String, 0, "PENIDX_STATUSBAR_BG" }, + { ATTRDEFTYPE_String, 0, "PENIDX_STATUSBAR_TEXT" }, + { ATTRDEFTYPE_String, 0, "PENIDX_ICONTEXTPEN" }, + { ATTRDEFTYPE_String, 0, "PENIDX_ICONTEXTPENSEL" }, + { ATTRDEFTYPE_String, 0, "PENIDX_ICONTEXTSHADOWPEN" }, + }; +static struct AttrDefaultValue AttrDefStringIDContents[] = + { + { ATTRDEFTYPE_String, 0, "MSGID_BYTENAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_KBYTENAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_MBYTENAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_GBYTENAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_TBYTENAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_PBYTENAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_HBYTENAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_REQTITLE" }, + { ATTRDEFTYPE_String, 0, "MSGID_OPENERRORNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_OPENERRORGADGETS" }, + { ATTRDEFTYPE_String, 0, "MSGID_QUITERRORNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_GADGETSNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_WBLOADNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_WBLOAD_ASLTITLE" }, + { ATTRDEFTYPE_String, 0, "MSGID_REPLACENAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_REPLACEGNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_DOWAITERRNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_SCAERRORNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_CLOSEWBNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_ABOUTNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_OKNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_UPDATENAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_SYSINFONAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_FLUSHNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_REBOOTNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_EXISTSNAME_COPY" }, + { ATTRDEFTYPE_String, 0, "MSGID_EXISTSGNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_SUREREBOOTNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_OKCANCELNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_LIBERRORNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_SCALIBERRORNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_COLNAMENAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_COLSIZENAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_COLACCESSNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_COLDATENAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_COLTIMENAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_COLCOMNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_USEDLIBSNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_SCARUNNINGNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_PREVIEWNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_EMULATIONNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_FILETRANSTITLE_COPY" }, + { ATTRDEFTYPE_String, 0, "MSGID_COPYINGNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_FROMNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_TONAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_PMTITLE1NAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_PMTITLE2NAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_PMTITLE3NAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_PMTITLE4NAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_PMTITLE5NAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_PMTITLE6NAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_COPYERRORNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_COPYERRORGNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_MOVEERRORNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_DELETEERRORNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_ABOUT_TESTTEXT" }, + { ATTRDEFTYPE_String, 0, "MSGID_ABOUT_UNREGTEXT" }, + { ATTRDEFTYPE_String, 0, "MSGID_ABOUT_REGTOTEXT" }, + { ATTRDEFTYPE_String, 0, "MSGID_ABOUT_REGTEXT" }, + { ATTRDEFTYPE_String, 0, "MSGID_ABOUT_COMREGINFO" }, + { ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_SETUPSCREEN" }, + { ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_SETUPSCRPATTERN" }, + { ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_INITMENU" }, + { ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_INITTIMER" }, + { ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_STARTWINDOWPROC" }, + { ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_INITNOTIFY" }, + { ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_WBSTARTUP" }, + { ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_WBSTARTUP_RUNPRG" }, + { ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_READDEVICEICONS" }, + { ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_INITDEVICEWINDOW" }, + { ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_WBSTARTUPFINISHED" }, + { ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_SCALOSVERSION" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_ROOTDIR" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_USERDIR" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_SOFTLINK" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_HARDLINKDIR" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_FILE" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_HARDLINKFILE" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_PIPEFILE" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_UNKNOWNTYPE" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_LASTCHANGE" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_SIZE" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_PROTECTION" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_STATE_WRITEPROTECT" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_STATE_VALIDATING" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_STATE_READWRITE" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_STATE_UNKNOWN" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_DISK" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_USEDCOUNTFMT" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_CREATED" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_STATE" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_USED" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_FILESIZEFMT" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_APPICON" }, + { ATTRDEFTYPE_String, 0, "MSGID_ICON_WITHOUT_FILE" }, + { ATTRDEFTYPE_String, 0, "MSGID_ICONIFIED_WINDOW" }, + { ATTRDEFTYPE_String, 0, "MSGID_PMMENU_APPICON_OPEN" }, + { ATTRDEFTYPE_String, 0, "MSGID_PMMENU_APPICON_COPY" }, + { ATTRDEFTYPE_String, 0, "MSGID_PMMENU_APPICON_RENAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_PMMENU_APPICON_INFO" }, + { ATTRDEFTYPE_String, 0, "MSGID_PMMENU_APPICON_SNAPSHOT" }, + { ATTRDEFTYPE_String, 0, "MSGID_PMMENU_APPICON_UNSNAPSHOT" }, + { ATTRDEFTYPE_String, 0, "MSGID_PMMENU_APPICON_LEAVEOUT" }, + { ATTRDEFTYPE_String, 0, "MSGID_PMMENU_APPICON_PUTAWAY" }, + { ATTRDEFTYPE_String, 0, "MSGID_PMMENU_APPICON_DELETE" }, + { ATTRDEFTYPE_String, 0, "MSGID_PMMENU_APPICON_FORMATDISK" }, + { ATTRDEFTYPE_String, 0, "MSGID_PMMENU_APPICON_EMPTYTRASHCAN" }, + { ATTRDEFTYPE_String, 0, "MSGID_EXISTSNAME_MOVE" }, + { ATTRDEFTYPE_String, 0, "MSGID_MULTIDRAG" }, + { ATTRDEFTYPE_String, 0, "MSGID_MULTIDRAG_DRAWER_1" }, + { ATTRDEFTYPE_String, 0, "MSGID_MULTIDRAG_DRAWER_2" }, + { ATTRDEFTYPE_String, 0, "MSGID_MULTIDRAG_FILE_1" }, + { ATTRDEFTYPE_String, 0, "MSGID_MULTIDRAG_FILE_2" }, + { ATTRDEFTYPE_String, 0, "MSGID_TEXTICON_DRAWER" }, + { ATTRDEFTYPE_String, 0, "MSGID_TEXTICON_TRASHCAN" }, + { ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_ENDREADDEVICEICONS" }, + { ATTRDEFTYPE_String, 0, "MSGID_STATUSBARTEXT" }, + { ATTRDEFTYPE_String, 0, "MSGID_MULTIDRAG_DEVICE_1" }, + { ATTRDEFTYPE_String, 0, "MSGID_MULTIDRAG_DEVICE_2" }, + { ATTRDEFTYPE_String, 0, "MSGID_CANCELBUTTON" }, + { ATTRDEFTYPE_String, 0, "MSGID_PREPARING_COPY" }, + { ATTRDEFTYPE_String, 0, "MSGID_PREPARING_MOVE" }, + { ATTRDEFTYPE_String, 0, "MSGID_FILETRANSFER_REMAININGTIME" }, + { ATTRDEFTYPE_String, 0, "MSGID_FILETRANSFER_MINUTES" }, + { ATTRDEFTYPE_String, 0, "MSGID_FILETRANSFER_SECONDS" }, + { ATTRDEFTYPE_String, 0, "MSGID_FILETRANSFER_SECOND" }, + { ATTRDEFTYPE_String, 0, "MSGID_FILETRANSTITLE_MOVE" }, + { ATTRDEFTYPE_String, 0, "MSGID_MOVINGNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_READINGPREFS" }, + { ATTRDEFTYPE_String, 0, "MSGID_DISK_UNREADABLE" }, + { ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_MAINWINDOW" }, + { ATTRDEFTYPE_String, 0, "MSGID_NEW_DRAWER_NAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_CANNOT_OPEN_DRAWER" }, + { ATTRDEFTYPE_String, 0, "MSGID_ALLOCPENSREQ_CONTENTS" }, + { ATTRDEFTYPE_String, 0, "MSGID_ALLOCPENSREQ_GADGETSNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_FILETYPE_WBGARBAGE" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_FILETYPE_WBPROJECT" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_FILETYPE_WBDEVICE" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_FILETYPE_WBKICK" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_FILETYPE_WBTOOL" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_FILETYPE_WBDISK" }, + { ATTRDEFTYPE_String, 0, "MSGID_ERROR_NO_DEFAULTTOOL" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_GADGET_RIGHTSCROLLER" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_GADGET_BOTTOMSCROLLER" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_GADGET_UPARROW" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_GADGET_DOWNARROW" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_GADGET_RIGHTARROW" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_GADGET_LEFTARROW" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_GADGET_ICONIFY" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_GADGET_STATUSBAR_TEXT" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_GADGET_STATUSBAR_READONLY" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_GADGET_STATUSBAR_READING" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_GADGET_STATUSBAR_TYPING" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_GADGET_STATUSBAR_SHOWALL" }, + { ATTRDEFTYPE_String, 0, "MSGID_EXISTSICON_COPY" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_USEDCOUNTFMT_FULL" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_USEDCOUNTFMT_FREE" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_USEDCOUNTFMT_INUSE" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_DRAWERS" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_FILES" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_LINKTO" }, + { ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_KICKSTART" }, + { ATTRDEFTYPE_String, 0, "MSGID_NODEFAULTTOOL_REQ" }, + { ATTRDEFTYPE_String, 0, "MSGID_NODEFAULTTOOL_REQ_GADGETS" }, + { ATTRDEFTYPE_String, 0, "MSGID_REQ_SELECTDEFTOOL" }, + { ATTRDEFTYPE_String, 0, "MSGID_TEXTICON_SOLOICON" }, + { ATTRDEFTYPE_String, 0, "MSGID_COLOWNERNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_COLGROUPNAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_COLFILETYPENAME" }, + { ATTRDEFTYPE_String, 0, "MSGID_COLVERSIONNAME" }, + }; +static struct AttrDefaultValue AttrDefGroupOrientationContents[] = + { + { ATTRDEFTYPE_ULong, TTL_Horizontal, "", ConvertGroupOrientationFromString }, + { ATTRDEFTYPE_ULong, TTL_Vertical, "", ConvertGroupOrientationFromString }, + }; +static struct AttrDefaultValue AttrDefGroupStringSrcContents[] = + { + { ATTRDEFTYPE_String, 0, "diskstate", }, + { ATTRDEFTYPE_String, 0, "diskusage", }, + { ATTRDEFTYPE_String, 0, "diskusagefree", }, + { ATTRDEFTYPE_String, 0, "diskusageinuse", }, + { ATTRDEFTYPE_String, 0, "diskusagepercent", }, + { ATTRDEFTYPE_String, 0, "fibfilename", }, + { ATTRDEFTYPE_String, 0, "filecomment", }, + { ATTRDEFTYPE_String, 0, "filedate", }, + { ATTRDEFTYPE_String, 0, "fileprotection", }, + { ATTRDEFTYPE_String, 0, "filesize", }, + { ATTRDEFTYPE_String, 0, "filetime", }, + { ATTRDEFTYPE_String, 0, "filetypestring", }, + { ATTRDEFTYPE_String, 0, "iconname", }, + { ATTRDEFTYPE_String, 0, "linktarget", }, + { ATTRDEFTYPE_String, 0, "plugin", }, + { ATTRDEFTYPE_String, 0, "versionstring", }, + { ATTRDEFTYPE_String, 0, "volumecreateddate", }, + { ATTRDEFTYPE_String, 0, "volumecreatedtime", }, + { ATTRDEFTYPE_String, 0, "volumeordevicename", }, + }; +static struct AttrDefaultValue AttrDefPopupMenuInternalCmds[] = + { + { ATTRDEFTYPE_String2, MSGID_COM5NAME, "about", }, + { ATTRDEFTYPE_String2, MSGID_COM1NAME, "backdrop", }, + { ATTRDEFTYPE_String2, MSGID_COM12NAME, "cleanup", }, + { ATTRDEFTYPE_String2, MSGID_COM43NAME, "cleanupbyname", }, + { ATTRDEFTYPE_String2, MSGID_COM44NAME, "cleanupbydate", }, + { ATTRDEFTYPE_String2, MSGID_COM45NAME, "cleanupbysize", }, + { ATTRDEFTYPE_String2, MSGID_COM46NAME, "cleanupbytype", }, + { ATTRDEFTYPE_String2, MSGID_COM36NAME, "clearselection", }, + { ATTRDEFTYPE_String2, MSGID_COM28NAME, "clone", }, + { ATTRDEFTYPE_String2, MSGID_COM9NAME, "close", }, + { ATTRDEFTYPE_String2, MSGID_COM39NAME, "copy", }, + { ATTRDEFTYPE_String2, MSGID_COM51NAME, "createthumbnail", }, + { ATTRDEFTYPE_String2, MSGID_COM40NAME, "cut", }, + { ATTRDEFTYPE_String2, MSGID_COM49NAME, "copyto", }, + { ATTRDEFTYPE_String2, MSGID_COM27NAME, "delete", }, + { ATTRDEFTYPE_String2, MSGID_COM29NAME, "emptytrashcan", }, + { ATTRDEFTYPE_String2, MSGID_COM2NAME, "executecommand", }, + { ATTRDEFTYPE_String2, MSGID_COM_FIND, "find", }, + { ATTRDEFTYPE_String2, MSGID_COM33NAME, "formatdisk", }, + { ATTRDEFTYPE_String2, MSGID_COM32NAME, "iconify", }, + { ATTRDEFTYPE_String2, MSGID_COM22NAME, "iconinfo", }, + { ATTRDEFTYPE_String2, MSGID_COM_ICONPROPERTIES, "iconproperties", }, + { ATTRDEFTYPE_String2, MSGID_COM30NAME, "lastmsg", }, + { ATTRDEFTYPE_String2, MSGID_COM25NAME, "leaveout", }, + { ATTRDEFTYPE_String2, MSGID_COM7NAME, "makedir", }, + { ATTRDEFTYPE_String2, MSGID_COM50NAME, "moveto", }, + { ATTRDEFTYPE_String2, MSGID_COM19NAME, "open", }, + { ATTRDEFTYPE_String2, MSGID_COM_OPENBROWSERWINDOW, "openinbrowserwindow", }, + { ATTRDEFTYPE_String2, MSGID_COM_OPENNEWWINDOW, "openinnewwindow", }, + { ATTRDEFTYPE_String2, MSGID_COM8NAME, "parent", }, + { ATTRDEFTYPE_String2, MSGID_COM41NAME, "paste", }, + { ATTRDEFTYPE_String2, MSGID_COM26NAME, "putaway", }, + { ATTRDEFTYPE_String2, MSGID_COM6NAME, "quit", }, + { ATTRDEFTYPE_String2, MSGID_COM_REDO, "redo", }, + { ATTRDEFTYPE_String2, MSGID_COM31NAME, "redraw", }, + { ATTRDEFTYPE_String2, MSGID_COM3NAME, "redrawall", }, + { ATTRDEFTYPE_String2, MSGID_COM21NAME, "rename", }, + { ATTRDEFTYPE_String2, MSGID_COM20NAME, "reset", }, + { ATTRDEFTYPE_String2, MSGID_COM11NAME, "selectall", }, + { ATTRDEFTYPE_String2, MSGID_COM16NAME, "showallfiles", }, + { ATTRDEFTYPE_String2, MSGID_COM15NAME, "showonlyicons", }, + { ATTRDEFTYPE_String2, MSGID_COM48NAME, "showdefault", }, + { ATTRDEFTYPE_String2, MSGID_COM34NAME, "shutdown", }, + { ATTRDEFTYPE_String2, MSGID_COM35NAME, "sizetofit", }, + { ATTRDEFTYPE_String2, MSGID_COM23NAME, "snapshot", }, + { ATTRDEFTYPE_String2, MSGID_COM14NAME, "snapshotall", }, + { ATTRDEFTYPE_String2, MSGID_COM13NAME, "snapshotwindow", }, + { ATTRDEFTYPE_String2, MSGID_COM_THUMBNAILCACHECLEANUP, "thumbnailcachecleanup", }, + { ATTRDEFTYPE_String2, MSGID_COM24NAME, "unsnapshot", }, + { ATTRDEFTYPE_String2, MSGID_COM_UNDO, "undo", }, + { ATTRDEFTYPE_String2, MSGID_COM10NAME, "update", }, + { ATTRDEFTYPE_String2, MSGID_COM4NAME, "updateall", }, + { ATTRDEFTYPE_String2, MSGID_COM47NAME, "viewbydefault", }, + { ATTRDEFTYPE_String2, MSGID_COM38NAME, "viewbydate", }, + { ATTRDEFTYPE_String2, MSGID_COM17NAME, "viewbyicon", }, + { ATTRDEFTYPE_String2, MSGID_COM37NAME, "viewbysize", }, + { ATTRDEFTYPE_String2, MSGID_COM42NAME, "viewbytype", }, + { ATTRDEFTYPE_String2, MSGID_COM18NAME, "viewbytext", }, + { ATTRDEFTYPE_String2, MSGID_COM_WINDOWPROPERTIES, "windowproperties", }, + }; +static struct AttrDefaultValue AttrDefGroupMemberHideContents[] = + { + { ATTRDEFTYPE_String, 0, "novolumenode", }, + { ATTRDEFTYPE_String, 0, "isempty", }, + }; + +static struct AttributeDef AttrDefFileType[] = + { + { + ATTRTYPE_FtDescription, + FALSE, + 0, { ATTRTYPE_FtDescription }, + 0, MAX_ATTRVALUE, + { ATTRDEFTYPE_String, 0, "" }, + NULL, 0, + }, + { + ATTRTYPE_PvPluginName, + FALSE, + 0, { ATTRTYPE_PvPluginName }, + 0, MAX_ATTRVALUE, + { ATTRDEFTYPE_FileName, 0, "Scalos:Plugins/Preview/" }, + NULL, 0, + }, + }; +static struct AttributeDef AttrDefDtImage[] = + { + { + ATTRTYPE_DtImageName, + TRUE, + 0, { ATTRTYPE_DtImageName }, + 0, MAX_ATTRVALUE, + { ATTRDEFTYPE_FileName, 0, "SYS:" }, + NULL, 0, + }, + }; +static struct AttributeDef AttrDefSubMenu[] = + { + { + ATTRTYPE_MenuItemName, + TRUE, + 0, { ATTRTYPE_MenuItemName }, + 0, MAX_ATTRVALUE, + { ATTRDEFTYPE_LocString, MSGID_CHANGEME, "" }, + NULL, 0, + }, + { + ATTRTYPE_UnselIconName, + FALSE, + 0, { ATTRTYPE_UnselIconName }, + 0, MAX_ATTRVALUE, + { ATTRDEFTYPE_FileName, 0, "THEME:Filetypes/" }, + NULL, 0, + }, + { + ATTRTYPE_SelIconName, + FALSE, + 0, { ATTRTYPE_SelIconName }, + 0, MAX_ATTRVALUE, + { ATTRDEFTYPE_FileName, 0, "THEME:Filetypes/" }, + NULL, 0, + }, + }; +static struct AttributeDef AttrDefMenuItem[] = + { + { + ATTRTYPE_MenuItemName, + TRUE, + 0, { ATTRTYPE_MenuItemName }, + 0, MAX_ATTRVALUE, + { ATTRDEFTYPE_LocString, MSGID_CHANGEME, "" }, + NULL, 0, + }, + { + ATTRTYPE_MenuCommKey, + FALSE, + 0, { ATTRTYPE_MenuCommKey }, + 1, 1, + { ATTRDEFTYPE_String, 0, "" }, + NULL, 0, + }, + { + ATTRTYPE_MenuDefaultAction, + FALSE, + 0, { ATTRTYPE_MenuDefaultAction }, + 0, 0, + { ATTRDEFTYPE_None, 0, "" }, + NULL, 0, + }, + { + ATTRTYPE_UnselIconName, + FALSE, + 0, { ATTRTYPE_UnselIconName }, + 0, MAX_ATTRVALUE, + { ATTRDEFTYPE_FileName, 0, "THEME:Filetypes/" }, + NULL, 0, + }, + { + ATTRTYPE_SelIconName, + FALSE, + 0, { ATTRTYPE_SelIconName }, + 0, MAX_ATTRVALUE, + { ATTRDEFTYPE_FileName, 0, "THEME:Filetypes/" }, + NULL, 0, + }, + }; +static struct AttributeDef AttrDefWBCmd[] = + { + { + ATTRTYPE_CommandName, + TRUE, + 0, { ATTRDEFTYPE_FileName }, + 0, MAX_ATTRVALUE, + { ATTRDEFTYPE_FileName, 0, "SYS:" }, + NULL, 0, + }, + { + ATTRTYPE_CommandStacksize, + FALSE, + 0, { ATTRTYPE_CommandStacksize }, + 4096, 4194304, + { ATTRDEFTYPE_ULong, 16384, "", NULL }, + NULL, 0, + }, + { + ATTRTYPE_CommandPriority, + FALSE, + 0, { ATTRTYPE_CommandPriority }, + SCHAR_MIN, SCHAR_MAX, + { ATTRDEFTYPE_ULong, 0, "", NULL }, + NULL, 0, + }, + { + ATTRTYPE_CommandWbArgs, + FALSE, + 0, { ATTRTYPE_CommandWbArgs }, + 0, 0, + { ATTRDEFTYPE_None, 0, "" }, + NULL, 0, + }, + }; +static struct AttributeDef AttrDefCmd[] = + { + { + ATTRTYPE_CommandName, + TRUE, + 0, { ATTRTYPE_CommandName }, + 0, MAX_ATTRVALUE, + { ATTRDEFTYPE_FileName, 0, "SYS:" }, + NULL, 0, + }, + { + ATTRTYPE_CommandStacksize, + FALSE, + 0, { ATTRTYPE_CommandStacksize }, + 4096, 4194304, + { ATTRDEFTYPE_ULong, 16384, "", NULL }, + NULL, 0, + }, + { + ATTRTYPE_CommandPriority, + FALSE, + 0, { ATTRTYPE_CommandPriority }, + SCHAR_MIN, SCHAR_MAX, + { ATTRDEFTYPE_ULong, 0, "", NULL }, + NULL, 0, + }, + { + ATTRTYPE_CommandWbArgs, + FALSE, + 0, { ATTRTYPE_CommandWbArgs }, + 0, 0, + { ATTRDEFTYPE_None, 0, "" }, + NULL, 0, + }, + }; +static struct AttributeDef AttrDefInternalCmd[] = + { + { + ATTRTYPE_CommandName, + TRUE, + 0, { ATTRTYPE_CommandName }, + 0, MAX_ATTRVALUE, + { ATTRDEFTYPE_LocString, MSGID_CHANGEME, "" }, + AttrDefPopupMenuInternalCmds, Sizeof(AttrDefPopupMenuInternalCmds), + }, + }; +static struct AttributeDef AttrDefPluginCmd[] = + { + { + ATTRTYPE_CommandName, + TRUE, + 0, { ATTRTYPE_CommandName }, + 0, MAX_ATTRVALUE, + { ATTRDEFTYPE_LocString, MSGID_CHANGEME, "" }, + NULL, 0, + }, + }; +static struct AttributeDef AttrDefIconWindowCmd[] = + { + { + ATTRTYPE_CommandName, + TRUE, + 0, { ATTRTYPE_CommandName }, + 0, MAX_ATTRVALUE, + { ATTRDEFTYPE_PathName, 0, "SYS:" }, + NULL, 0, + }, + }; +static struct AttributeDef AttrDefGroup[] = + { + { + ATTRTYPE_GroupOrientation, + TRUE, + 0, { ATTRTYPE_GroupOrientation }, + TTL_Horizontal, TTL_Vertical, + { ATTRDEFTYPE_ULong, TTL_Vertical, "", ConvertGroupOrientationFromString }, + AttrDefGroupOrientationContents, Sizeof(AttrDefGroupOrientationContents), + }, + }; +static struct AttributeDef AttrDefMember[] = + { + { + ATTRTYPE_MemberHideString, + FALSE, + 0, { ATTRTYPE_MemberHideString }, + 0, MAX_ATTRVALUE, + { ATTRDEFTYPE_LocString, MSGID_CHANGEME, "" }, + AttrDefGroupMemberHideContents, Sizeof(AttrDefGroupMemberHideContents), + }, + }; +static struct AttributeDef AttrDefString[] = + { + { + ATTRTYPE_StringText, + TRUE, + 2, { ATTRTYPE_StringSrc, ATTRTYPE_StringId }, + 0, MAX_ATTRVALUE, + { ATTRDEFTYPE_LocString, MSGID_CHANGEME, "" }, + NULL, 0, + }, + { + ATTRTYPE_StringSrc, + TRUE, + 2, { ATTRTYPE_StringText, ATTRTYPE_StringId }, + 0, MAX_ATTRVALUE, + { ATTRDEFTYPE_String, 0, "diskstate" }, + AttrDefGroupStringSrcContents, Sizeof(AttrDefGroupStringSrcContents), + }, + { + ATTRTYPE_StringId, + TRUE, + 2, { ATTRTYPE_StringText, ATTRTYPE_StringSrc }, + 0, MAX_ATTRVALUE, + { ATTRDEFTYPE_String, 0, "MSGID_BYTENAME" }, + AttrDefStringIDContents, Sizeof(AttrDefStringIDContents), + }, + { + ATTRTYPE_StringPen, + FALSE, + 0, { ATTRTYPE_StringPen }, + 0, MAX_ATTRVALUE, + { ATTRDEFTYPE_String, 0, "PENIDX_TOOLTIP_TEXT" }, + AttrDefStringPenContents, Sizeof(AttrDefStringPenContents), + }, + { + ATTRTYPE_StringFont, + FALSE, + 0, { ATTRTYPE_StringFont }, + 0, MAX_ATTRVALUE, + { ATTRDEFTYPE_FontString, 0, "" }, + NULL, + }, + { + ATTRTYPE_StringTTFont, + FALSE, + 0, { ATTRTYPE_StringTTFont }, + 0, MAX_ATTRVALUE, + { ATTRDEFTYPE_TTFontString, 0, "" }, + NULL, + }, + { + ATTRTYPE_StringStyle, + FALSE, + 0, { ATTRTYPE_StringStyle }, + 0, MAX_ATTRVALUE, + { ATTRDEFTYPE_String, 0, "normal" }, + AttrDefStringStyleContents, Sizeof(AttrDefStringStyleContents), + }, + { + ATTRTYPE_StringVAlign, + FALSE, + 0, { ATTRTYPE_StringVAlign }, + 0, MAX_ATTRVALUE, + { ATTRDEFTYPE_String, 0, "center" }, + AttrDefStringVAlignContents, Sizeof(AttrDefStringVAlignContents), + }, + { + ATTRTYPE_StringHAlign, + FALSE, + 0, { ATTRTYPE_StringHAlign }, + 0, MAX_ATTRVALUE, + { ATTRDEFTYPE_String, 0, "center" }, + AttrDefStringHAlignContents, Sizeof(AttrDefStringHAlignContents), + }, + }; +static struct AttributeDef AttrDefSpace[] = + { + { + ATTRTYPE_SpaceSize, + TRUE, + 0, { ATTRTYPE_SpaceSize }, + 1, 255, + { ATTRDEFTYPE_ULong, 1, "", NULL }, + NULL, 0, + }, + }; + +static const struct EntryAttributes AllEntryAttributes[] = + { + { + ENTRYTYPE_FileType, + AttrDefFileType, Sizeof(AttrDefFileType), + }, + { + ENTRYTYPE_PopupMenu, + NULL, 0, + }, + { + ENTRYTYPE_PopupMenu_SubMenu, + AttrDefSubMenu, Sizeof(AttrDefSubMenu), + }, + { + ENTRYTYPE_PopupMenu_MenuItem, + AttrDefMenuItem, Sizeof(AttrDefMenuItem), + }, + { + ENTRYTYPE_PopupMenu_InternalCmd, + AttrDefInternalCmd, Sizeof(AttrDefInternalCmd), + }, + { + ENTRYTYPE_PopupMenu_WbCmd, + AttrDefWBCmd, Sizeof(AttrDefWBCmd), + }, + { + ENTRYTYPE_PopupMenu_ARexxCmd, + AttrDefCmd, Sizeof(AttrDefCmd), + }, + { + ENTRYTYPE_PopupMenu_CliCmd, + AttrDefCmd, Sizeof(AttrDefCmd), + }, + { + ENTRYTYPE_PopupMenu_PluginCmd, + AttrDefPluginCmd, Sizeof(AttrDefPluginCmd), + }, + { + ENTRYTYPE_PopupMenu_IconWindowCmd, + AttrDefIconWindowCmd, Sizeof(AttrDefIconWindowCmd), + }, + { + ENTRYTYPE_PopupMenu_MenuSeparator, + NULL, 0, + }, + { + ENTRYTYPE_ToolTip, + NULL, 0, + }, + { + ENTRYTYPE_ToolTip_Group, + AttrDefGroup, Sizeof(AttrDefGroup), + }, + { + ENTRYTYPE_ToolTip_Member, + AttrDefMember, Sizeof(AttrDefMember), + }, + { + ENTRYTYPE_ToolTip_HBar, + NULL, 0, + }, + { + ENTRYTYPE_ToolTip_String, + AttrDefString, Sizeof(AttrDefString), + }, + { + ENTRYTYPE_ToolTip_Space, + AttrDefSpace, Sizeof(AttrDefSpace), + }, + { + ENTRYTYPE_ToolTip_DtImage, + AttrDefDtImage, Sizeof(AttrDefDtImage), + } + }; + +//--------------------------------------------------------------- + +VOID closePlugin(struct PluginBase *PluginBase) +{ + d1(kprintf(__FILE__ "/%s/%ld:\n", __FUNC__, __LINE__)); + + if (DataTypesImageClass) + { + CleanupDtpicClass(DataTypesImageClass); + DataTypesImageClass = NULL; + } + if (FontSampleClass) + { + CleanupFontSampleClass(FontSampleClass); + FontSampleClass = NULL; + } + if (IconobjectClass) + { + CleanupIconobjectClass(IconobjectClass); + IconobjectClass = NULL; + } + if (myNListClass) + { + MUI_DeleteCustomClass(myNListClass); + myNListClass = NULL; + } + if (myFileTypesActionsNListClass) + { + MUI_DeleteCustomClass(myFileTypesActionsNListClass); + myFileTypesActionsNListClass = NULL; + } + if (myNListTreeClass) + { + MUI_DeleteCustomClass(myNListTreeClass); + myNListTreeClass = NULL; + } + if (myFileTypesNListTreeClass) + { + MUI_DeleteCustomClass(myFileTypesNListTreeClass); + myFileTypesNListTreeClass = NULL; + } + + if (FileTypesPrefsCatalog) + { + CloseCatalog(FileTypesPrefsCatalog); + FileTypesPrefsCatalog = NULL; + } + if (FileTypesPrefsLocale) + { + CloseLocale(FileTypesPrefsLocale); + FileTypesPrefsLocale = NULL; + } + + if (FileTypesPrefsClass) + { + MUI_DeleteCustomClass(FileTypesPrefsClass); + FileTypesPrefsClass = NULL; + } + + CloseLibraries(); + +#if !defined(__amigaos4__) && !defined(__AROS__) + _STD_240_TerminateMemFunctions(); +#endif +} + + +LIBFUNC_P2(ULONG, LIBSCAGetPrefsInfo, + D0, ULONG, which, + A6, struct PluginBase *, PluginBase) +{ + ULONG result; + + (void) PluginBase; + + d1(kprintf(__FILE__ "/%s/%ld: which=%ld\n", __FUNC__, __LINE__, which)); + + switch(which) + { + case SCAPREFSINFO_GetClass: + result = (ULONG) FileTypesPrefsClass; + break; + + case SCAPREFSINFO_GetTitle: + result = (ULONG) GetLocString(MSGID_PLUGIN_LIST_TITLE); + break; + + case SCAPREFSINFO_GetTitleImage: + result = (ULONG) CreatePrefsImage(); + break; + + default: + result = (ULONG) NULL; + break; + } + + d1(kprintf(__FILE__ "/%s/%ld: Result=%08lx\n", __FUNC__, __LINE__, result)); + + return result; +} +LIBFUNC_END + +//---------------------------------------------------------------------------- + +DISPATCHER(FileTypesPrefs) +{ + struct FileTypesPrefsInst *inst; + ULONG n; + ULONG result = 0; + + d1(kprintf("%s/%ld: START obj=%08lx\n", __FUNC__, __LINE__, obj)); + + switch(msg->MethodID) + { + case OM_NEW: + obj = (Object *) DoSuperMethodA(cl, obj, msg); + d1(kprintf(__FILE__ "/%s/%ld: OM_NEW obj=%08lx\n", __FUNC__, __LINE__, obj)); + if (obj) + { + Object *prefsobject; + struct opSet *ops = (struct opSet *) msg; + + inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj); + + memset(inst, 0, sizeof(struct FileTypesPrefsInst)); + + inst->fpb_SaveFlags = FTWRITEFLAG_ONLY_SAVE_CHANGED | FTWRITEFLAG_CLEAR_CHANGE_FLAG; + inst->fpb_Changed = FALSE; + inst->fpb_HideEmptyNodes = FALSE; + inst->fpb_FileTypesDirLock = (BPTR) NULL; + inst->fpb_IncludeNesting = 0; + inst->fpb_WBScreen = LockPubScreen("Workbench"); + inst->fpb_MenuImageIndex = 0; + + inst->fpb_TTfAntialias = TT_Antialias_Auto; + inst->fpb_TTfGamma = 2500; + + NewList(&inst->fpb_FoundList); + inst->fpb_CurrentFound = (struct FoundNode *) &inst->fpb_FoundList.lh_Tail; + + InitHooks(inst); + + ReadScalosPrefs(inst, "ENV:scalos/scalos.prefs"); + + inst->fpb_fCreateIcons = GetTagData(MUIA_ScalosPrefs_CreateIcons, TRUE, ops->ops_AttrList); + inst->fpb_ProgramName = (CONST_STRPTR) GetTagData(MUIA_ScalosPrefs_ProgramName, (ULONG) "", ops->ops_AttrList); + inst->fpb_Objects[OBJNDX_WIN_Main] = (APTR) GetTagData(MUIA_ScalosPrefs_MainWindow, (ULONG) NULL, ops->ops_AttrList); + inst->fpb_Objects[OBJNDX_APP_Main] = (APTR) GetTagData(MUIA_ScalosPrefs_Application, (ULONG) NULL, ops->ops_AttrList); + + prefsobject = CreatePrefsGroup(inst); + d1(kprintf(__FILE__ "/%s/%ld: prefsobject=%08lx\n", __FUNC__, __LINE__, prefsobject)); + if (prefsobject) + { + DoMethod(obj, OM_ADDMEMBER, prefsobject); + + result = (ULONG) obj; + } + else + { + CoerceMethod(cl, obj, OM_DISPOSE); + } + } + break; + + case OM_DISPOSE: + d1(kprintf(__FILE__ "/%s/%ld: OM_DISPOSE obj=%08lx\n", __FUNC__, __LINE__, obj)); + inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj); + + CleanupFoundNodes(inst); + + if (inst->fpb_WBScreen) + { + UnlockPubScreen(NULL, inst->fpb_WBScreen); + inst->fpb_WBScreen = NULL; + } + for (n=0; nfpb_FileHandles); n++) + { + if (inst->fpb_FileHandles[n].ftfd_FileHandle) + { + Close(inst->fpb_FileHandles[n].ftfd_FileHandle); + inst->fpb_FileHandles[n].ftfd_FileHandle = (BPTR) NULL; + } + } + if (inst->fpb_LearnReq) + { + MUI_FreeAslRequest(inst->fpb_LearnReq); + inst->fpb_LearnReq = NULL; + } + if (inst->fpb_LoadReq) + { + MUI_FreeAslRequest(inst->fpb_LoadReq); + inst->fpb_LoadReq = NULL; + } + if (inst->fpb_SaveReq) + { + MUI_FreeAslRequest(inst->fpb_SaveReq); + inst->fpb_SaveReq = NULL; + } + if (inst->fpb_FileTypesDirLock) + { + UnLock(inst->fpb_FileTypesDirLock); + inst->fpb_FileTypesDirLock = (BPTR) NULL; + } + if (inst->fpb_Objects[OBJNDX_ContextMenuFileTypes]) + { + MUI_DisposeObject(inst->fpb_Objects[OBJNDX_ContextMenuFileTypes]); + inst->fpb_Objects[OBJNDX_ContextMenuFileTypes] = NULL; + } + if (inst->fpb_Objects[OBJNDX_ContextMenuFileTypesActions]) + { + MUI_DisposeObject(inst->fpb_Objects[OBJNDX_ContextMenuFileTypesActions]); + inst->fpb_Objects[OBJNDX_ContextMenuFileTypesActions] = NULL; + } + if (inst->fpb_Objects[OBJNDX_ContextMenu]) + { + MUI_DisposeObject(inst->fpb_Objects[OBJNDX_ContextMenu]); + inst->fpb_Objects[OBJNDX_ContextMenu] = NULL; + } + if (inst->fpb_Objects[OBJNDX_ContextMenuAttrList]) + { + MUI_DisposeObject(inst->fpb_Objects[OBJNDX_ContextMenuAttrList]); + inst->fpb_Objects[OBJNDX_ContextMenuAttrList] = NULL; + } + if (inst->fpb_IconObject) + { + DisposeIconObject(inst->fpb_IconObject); + inst->fpb_IconObject = NULL; + } + + CleanupDefIcons(inst); + + d1(kprintf("%s/%ld: FileTypesPrefsCatalog=%08lx\n", __FUNC__, __LINE__, FileTypesPrefsCatalog)); + return DoSuperMethodA(cl, obj, msg); + break; + + case OM_SET: + { + struct opSet *ops = (struct opSet *) msg; + + inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj); + d1(kprintf("%s/%ld: OM_SET createIcons=%ld\n", __FUNC__, __LINE__, inst->fpb_fCreateIcons)); + + inst->fpb_fCreateIcons = GetTagData(MUIA_ScalosPrefs_CreateIcons, inst->fpb_fCreateIcons, ops->ops_AttrList); + inst->fpb_ProgramName = (CONST_STRPTR) GetTagData(MUIA_ScalosPrefs_ProgramName, (ULONG) inst->fpb_ProgramName, ops->ops_AttrList); + inst->fpb_Objects[OBJNDX_WIN_Main] = (APTR) GetTagData(MUIA_ScalosPrefs_MainWindow, + (ULONG) inst->fpb_Objects[OBJNDX_WIN_Main], ops->ops_AttrList); + inst->fpb_Objects[OBJNDX_APP_Main] = (APTR) GetTagData(MUIA_ScalosPrefs_Application, + (ULONG) inst->fpb_Objects[OBJNDX_APP_Main], ops->ops_AttrList); + + d1(kprintf("%s/%ld: OM_SET createIcons=%ld\n", __FUNC__, __LINE__, inst->fpb_fCreateIcons)); + + return DoSuperMethodA(cl, obj, msg); + } + break; + + case OM_GET: + { + struct opGet *opg = (struct opGet *) msg; + + d1(kprintf(__FILE__ "/%s/%ld: OM_GET obj=%08lx\n", __FUNC__, __LINE__, obj)); + + inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj); + switch (opg->opg_AttrID) + { + case MUIA_ScalosPrefs_CreateIcons: + *opg->opg_Storage = inst->fpb_fCreateIcons; + result = 0; + break; + default: + result = DoSuperMethodA(cl, obj, msg); + } + } + break; + + case MUIM_ScalosPrefs_ParseToolTypes: + d1(kprintf(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_ParseToolTypes obj=%08lx\n", __FUNC__, __LINE__, obj)); + inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj); + d1(kprintf(__FILE__ "/%s/%ld: before ParseToolTypes\n", __FUNC__, __LINE__)); + ParseToolTypes(inst, (struct MUIP_ScalosPrefs_ParseToolTypes *) msg); + d1(kprintf(__FILE__ "/%s/%ld: after ParseToolTypes\n", __FUNC__, __LINE__)); + break; + + case MUIM_ScalosPrefs_LoadConfig: + d1(kprintf(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_LoadConfig obj=%08lx\n", __FUNC__, __LINE__, obj)); + inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj); + ReadPrefs(inst, ENV_FILETYPES_DIR, ENV_DEFICONS_PREFS); + inst->fpb_SaveFlags = FTWRITEFLAG_ONLY_SAVE_CHANGED | FTWRITEFLAG_CLEAR_CHANGE_FLAG; + SetChangedFlag(inst, FALSE); + break; + + case MUIM_ScalosPrefs_UseConfig: + d1(kprintf(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_UseConfig obj=%08lx\n", __FUNC__, __LINE__, obj)); + inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj); + WritePrefs(inst, ENV_FILETYPES_DIR, ENV_DEFICONS_PREFS, inst->fpb_SaveFlags); + SetChangedFlag(inst, FALSE); + break; + + case MUIM_ScalosPrefs_UseConfigIfChanged: + d1(kprintf(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_UseConfigIfChanged obj=%08lx\n", __FUNC__, __LINE__, obj)); + inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj); + if (inst->fpb_Changed) + { + WritePrefs(inst, ENV_FILETYPES_DIR, ENV_DEFICONS_PREFS, inst->fpb_SaveFlags); + SetChangedFlag(inst, FALSE); + } + break; + + case MUIM_ScalosPrefs_SaveConfig: + d1(kprintf(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_SaveConfig obj=%08lx\n", __FUNC__, __LINE__, obj)); + inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj); + WritePrefs(inst, ENV_FILETYPES_DIR, ENV_DEFICONS_PREFS, inst->fpb_SaveFlags & ~FTWRITEFLAG_CLEAR_CHANGE_FLAG); + WritePrefs(inst, ENVARC_FILETYPES_DIR, ENVARC_DEFICONS_PREFS, inst->fpb_SaveFlags); + SetChangedFlag(inst, FALSE); + break; + + case MUIM_ScalosPrefs_SaveConfigIfChanged: + d1(kprintf(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_SaveConfigIfChanged obj=%08lx\n", __FUNC__, __LINE__, obj)); + inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj); + if (inst->fpb_Changed) + { + WritePrefs(inst, ENV_FILETYPES_DIR, ENV_DEFICONS_PREFS, inst->fpb_SaveFlags & ~FTWRITEFLAG_CLEAR_CHANGE_FLAG); + WritePrefs(inst, ENVARC_FILETYPES_DIR, ENVARC_DEFICONS_PREFS, inst->fpb_SaveFlags); + SetChangedFlag(inst, FALSE); + } + break; + + case MUIM_ScalosPrefs_RestoreConfig: + inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj); + d1(KPrintF(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_RestoreConfig\n", __FUNC__, __LINE__)); + DoMethod(obj, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_Restore], 0); + break; + + case MUIM_ScalosPrefs_ResetToDefaults: + inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj); + d1(KPrintF(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_ResetToDefaults", __FUNC__, __LINE__)); + DoMethod(obj, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_ResetToDefaults], 0); + break; + + case MUIM_ScalosPrefs_LastSavedConfig: + inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj); + d1(KPrintF(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_LastSavedConfig", __FUNC__, __LINE__)); + DoMethod(obj, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_LastSaved], 0); + break; + + case MUIM_ScalosPrefs_OpenConfig: + d1(kprintf(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_OpenConfig obj=%08lx\n", __FUNC__, __LINE__, obj)); + inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_Open], 0); + break; + + case MUIM_ScalosPrefs_SaveConfigAs: + d1(kprintf(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_SaveConfigAs obj=%08lx\n", __FUNC__, __LINE__, obj)); + inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_SaveAs], 0); + break; + + case MUIM_ScalosPrefs_About: + d1(kprintf(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_About obj=%08lx\n", __FUNC__, __LINE__, obj)); + inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_About], 0); + break; + + case MUIM_ScalosPrefs_LoadNamedConfig: + { + struct MUIP_ScalosPrefs_LoadNamedConfig *lnc = (struct MUIP_ScalosPrefs_LoadNamedConfig *) msg; + + d1(kprintf(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_LoadNamedConfig obj=%08lx\n", __FUNC__, __LINE__, obj)); + + inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj); + ReadPrefs(inst, lnc->ConfigFileName, ENV_DEFICONS_PREFS); + inst->fpb_SaveFlags = FTWRITEFLAG_ONLY_SAVE_CHANGED | FTWRITEFLAG_CLEAR_CHANGE_FLAG; + } + break; + + case MUIM_ScalosPrefs_CreateSubWindows: + d1(kprintf(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_CreateSubWindows obj=%08lx\n", __FUNC__, __LINE__, obj)); + result = (ULONG) CreateSubWindows(cl, obj); + break; + + case MUIM_ScalosPrefs_PageActive: + { + struct MUIP_ScalosPrefs_PageActive *spa = (struct MUIP_ScalosPrefs_PageActive *) msg; + + inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj); + inst->fpb_PageIsActive = spa->isActive; + d1(kprintf(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_PageActive isActive=%08lx inst=%08lx\n", __FUNC__, __LINE__, spa->isActive, inst)); + } + break; + + case MUIM_ScalosPrefs_GetListOfMCCs: + result = (ULONG) RequiredMccList; + break; + + default: + d1(kprintf(__FILE__ "/%s/%ld: MethodID=%08lx\n", __FUNC__, __LINE__, msg->MethodID)); + result = DoSuperMethodA(cl, obj, msg); + break; + } + + d1(kprintf("%s/%ld: END inst=%08lx\n", __FUNC__, __LINE__, inst)); + return result; +} +DISPATCHER_END + +//---------------------------------------------------------------------------- + +static Object *CreatePrefsGroup(struct FileTypesPrefsInst *inst) +{ + d1(kprintf("%s/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst)); + + inst->fpb_Objects[OBJNDX_ContextMenuFileTypes] = MUI_MakeObject(MUIO_MenustripNM, ContextMenuFileTypes, 0); + if (NULL == inst->fpb_Objects[OBJNDX_ContextMenuFileTypes]) + return NULL; + + inst->fpb_Objects[OBJNDX_ContextMenuFileTypesActions] = MUI_MakeObject(MUIO_MenustripNM, ContextMenuFileTypesActions, 0); + if (NULL == inst->fpb_Objects[OBJNDX_ContextMenuFileTypesActions]) + return NULL; + + inst->fpb_Objects[OBJNDX_Menu_ExpandFileTypes] = (Object *) DoMethod(inst->fpb_Objects[OBJNDX_ContextMenuFileTypes], + MUIM_FindUData, HOOKNDX_ExpandFileTypes); + inst->fpb_Objects[OBJNDX_Menu_CollapseFileTypes] = (Object *) DoMethod(inst->fpb_Objects[OBJNDX_ContextMenuFileTypes], + MUIM_FindUData, HOOKNDX_CollapseFileTypes); + + inst->fpb_Objects[OBJNDX_Menu_Find] = (Object *) DoMethod(inst->fpb_Objects[OBJNDX_ContextMenuFileTypes], + MUIM_FindUData, HOOKNDX_ShowFindGroup); + + inst->fpb_Objects[OBJNDX_ContextMenu] = MUI_MakeObject(MUIO_MenustripNM, ContextMenus, 0); + if (NULL == inst->fpb_Objects[OBJNDX_ContextMenu]) + return NULL; + + inst->fpb_Objects[OBJNDX_Menu_Expand] = (Object *) DoMethod(inst->fpb_Objects[OBJNDX_ContextMenu], + MUIM_FindUData, HOOKNDX_Expand); + inst->fpb_Objects[OBJNDX_Menu_Collapse] = (Object *) DoMethod(inst->fpb_Objects[OBJNDX_ContextMenu], + MUIM_FindUData, HOOKNDX_Collapse); + + inst->fpb_Objects[OBJNDX_Menu_Copy] = (Object *) DoMethod(inst->fpb_Objects[OBJNDX_ContextMenu], + MUIM_FindUData, HOOKNDX_Copy); + inst->fpb_Objects[OBJNDX_Menu_Cut] = (Object *) DoMethod(inst->fpb_Objects[OBJNDX_ContextMenu], + MUIM_FindUData, HOOKNDX_Cut); + inst->fpb_Objects[OBJNDX_Menu_Paste] = (Object *) DoMethod(inst->fpb_Objects[OBJNDX_ContextMenu], + MUIM_FindUData, HOOKNDX_Paste); + + inst->fpb_Objects[OBJNDX_Menu_HideEmptyEntries] = (Object *) DoMethod(inst->fpb_Objects[OBJNDX_ContextMenu], + MUIM_FindUData, HOOKNDX_HideEmptyEntries); + + + inst->fpb_Objects[OBJNDX_ContextMenuAttrList] = MUI_MakeObject(MUIO_MenustripNM, ContextMenusAttrList, 0); + if (NULL == inst->fpb_Objects[OBJNDX_ContextMenuAttrList]) + return NULL; + + inst->fpb_Objects[OBJNDX_Menu_CopyAttr] = (Object *) DoMethod(inst->fpb_Objects[OBJNDX_ContextMenuAttrList], + MUIM_FindUData, HOOKNDX_CopyAttr); + inst->fpb_Objects[OBJNDX_Menu_CutAttr] = (Object *) DoMethod(inst->fpb_Objects[OBJNDX_ContextMenuAttrList], + MUIM_FindUData, HOOKNDX_CutAttr); + inst->fpb_Objects[OBJNDX_Menu_PasteAttr] = (Object *) DoMethod(inst->fpb_Objects[OBJNDX_ContextMenuAttrList], + MUIM_FindUData, HOOKNDX_PasteAttr); + + + d1(kprintf("%s/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst)); + + inst->fpb_Objects[OBJNDX_Group_Main] = VGroup, + MUIA_Background, MUII_PageBack, + + // OBJNDX_ShadowListView is used as invisible storage + // for copy and paste operations + Child, inst->fpb_Objects[OBJNDX_ShadowListView] = NListviewObject, + MUIA_ShowMe, FALSE, + MUIA_CycleChain, TRUE, + MUIA_NListview_NList, inst->fpb_Objects[OBJNDX_ShadowListTree] = myNListTreeObject, + MUIA_NList_PrivateData, inst, + MUIA_NList_Format, "", + MUIA_NListtree_DisplayHook, &inst->fpb_Hooks[HOOKNDX_TreeDisplay], + MUIA_NListtree_ConstructHook, &inst->fpb_Hooks[HOOKNDX_TreeConstruct], + MUIA_NListtree_DestructHook, &inst->fpb_Hooks[HOOKNDX_TreeDestruct], + End, // myNListTreeClass + End, // NListviewObject + + Child, inst->fpb_Objects[OBJNDX_ShadowAttrListView] = NListviewObject, + MUIA_ShowMe, FALSE, + MUIA_CycleChain, TRUE, + MUIA_NListview_NList, inst->fpb_Objects[OBJNDX_ShadowAttrList] = myNListObject, + MUIA_NList_PrivateData, inst, + MUIA_NList_Format, ",", + InputListFrame, + MUIA_Background, MUII_ListBack, + MUIA_NList_DisplayHook2, &inst->fpb_Hooks[HOOKNDX_AttrDisplay], + MUIA_NList_ConstructHook2, &inst->fpb_Hooks[HOOKNDX_AttrConstruct], + MUIA_NList_DestructHook2, &inst->fpb_Hooks[HOOKNDX_AttrDestruct], + MUIA_NList_DragSortable, FALSE, + MUIA_NList_ShowDropMarks, FALSE, + MUIA_NList_Title, TRUE, + MUIA_NList_TitleSeparator, TRUE, + End, // myNListTreeClass + + MUIA_Listview_DragType, MUIV_Listview_DragType_None, + MUIA_Weight, 50, + End, // NListviewObject + + Child, RegisterObject, + MUIA_Register_Titles, RegisterTitles, + MUIA_CycleChain, TRUE, + + // --- filetypes + Child, VGroup, + Child, HGroup, + MUIA_Weight, 200, + Child, VGroup, + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_GROUP_FILETYPES_FILETYPES), + GroupFrame, + + Child, inst->fpb_Objects[OBJNDX_Group_FindFiletype] = HGroup, + GroupFrame, + Child, inst->fpb_Objects[OBJNDX_Button_HideFind] = TextObject, + MUIA_Weight, 10, + ButtonFrame, + MUIA_CycleChain, TRUE, +#if defined(MUII_Close) + MUIA_Text_Contents, MUIX_C "\33I[6:" STR(MUII_Close) "]", +#else + MUIA_Text_Contents, MUIX_C "\33I[6:" STR(MUII_TapeStop) "]", +#endif + MUIA_InputMode, MUIV_InputMode_RelVerify, + MUIA_Background, MUII_ButtonBack, + MUIA_ShortHelp, GetLocString(MSGID_BUTTON_FIND_HIDE_SHORTHELP), + End, + + Child, inst->fpb_Objects[OBJNDX_String_FindFileType] = StringObject, + MUIA_CycleChain, TRUE, + StringFrame, + MUIA_ShortHelp, GetLocString(MSGID_STRING_FIND_SHORTHELP), + End, //StringObject + Child, inst->fpb_Objects[OBJNDX_Button_FindPrevFileType] = TextObject, + MUIA_Weight, 10, + ButtonFrame, + MUIA_CycleChain, TRUE, + MUIA_Text_Contents, MUIX_C "\33I[6:" STR(MUII_TapePlayBack) "]", + MUIA_InputMode, MUIV_InputMode_RelVerify, + MUIA_Background, MUII_ButtonBack, + MUIA_ShortHelp, GetLocString(MSGID_BUTTON_FIND_PREV_SHORTHELP), + End, + Child, inst->fpb_Objects[OBJNDX_Button_FindNextFileType] = TextObject, + MUIA_Weight, 10, + ButtonFrame, + MUIA_CycleChain, TRUE, + MUIA_Text_Contents, MUIX_C "\33I[6:" STR(MUII_TapePlay) "]", + MUIA_InputMode, MUIV_InputMode_RelVerify, + MUIA_Background, MUII_ButtonBack, + MUIA_ShortHelp, GetLocString(MSGID_BUTTON_FIND_NEXT_SHORTHELP), + End, + Child, inst->fpb_Objects[OBJNDX_Button_FindHitCount] = TextObject, + MUIA_Weight, 10, + MUIA_Text_Contents, "", + End, //TextObject + + End, //HGroup + + Child, inst->fpb_Objects[OBJNDX_NListview_FileTypes] = NListviewObject, + MUIA_CycleChain, TRUE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_SHORTHELP_LISTVIEW_FILETYPES), + MUIA_NListview_NList, inst->fpb_Objects[OBJNDX_NListtree_FileTypes] = myFileTypesNListTreeObject, + MUIA_Background, MUII_ListBack, + MUIA_NList_PrivateData, inst, + MUIA_ContextMenu, inst->fpb_Objects[OBJNDX_ContextMenuFileTypes], + MUIA_NListtree_DisplayHook, &inst->fpb_Hooks[HOOKNDX_FileTypesDisplay], + MUIA_NListtree_ConstructHook, &inst->fpb_Hooks[HOOKNDX_FileTypesConstruct], + MUIA_NListtree_DestructHook, &inst->fpb_Hooks[HOOKNDX_FileTypesDestruct], + MUIA_NListtree_DragDropSort, TRUE, + MUIA_NList_ShowDropMarks, TRUE, + MUIA_NListtree_EmptyNodes, TRUE, + MUIA_NListtree_AutoVisible, MUIV_NListtree_AutoVisible_Expand, + End, //myFileTypesNListTreeClass + End, //NListtreeObject + + Child, inst->fpb_Objects[OBJNDX_String_FileTypes_Name] = StringObject, + MUIA_CycleChain, TRUE, + MUIA_Disabled, TRUE, + MUIA_String_AdvanceOnCR, TRUE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_SHORTHELP_STRING_FILETYPES), + StringFrame, + End, //StringObject + + Child, ColGroup(2), + Child, inst->fpb_Objects[OBJNDX_Button_FileTypes_Add] = KeyButtonHelp(MSGID_BUTTON_ADD_FILETYPE, + 'a', + MSGID_SHORTHELP_BUTTON_ADD_FILETYPE), + Child, inst->fpb_Objects[OBJNDX_Button_FileTypes_Remove] = KeyButtonHelp(MSGID_BUTTON_DELETE_FILETYPE, + 'r', + MSGID_SHORTHELP_BUTTON_DELETE_FILETYPE), + End, //ColGroup + End, //VGroup + End, //VGroup + + Child, VGroup, + Child, HVSpace, + MUIA_Weight, 10, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_SHORTHELP_DEFAULTICON), + + Child, inst->fpb_Objects[OBJNDX_Text_FileTypes_FileTypesName] = TextObject, + MUIA_ShowMe, FALSE, + MUIA_Text_Contents, "", + MUIA_Text_PreParse, MUIX_B "\33c", + End, //TextObject + + Child, HVSpace, + + Child, inst->fpb_Objects[OBJNDX_Text_FileTypes_DefIconName] = TextObject, + MUIA_Text_Contents, "", + MUIA_Text_PreParse, "\33c", + MUIA_Text_SetMin, TRUE, + End, //TextObject + Child, inst->fpb_Objects[OBJNDX_IconObjectMCC_FileTypes_Icon] = IconobjectMCCObject, + MUIA_InputMode, MUIV_InputMode_RelVerify, + NoFrame, + MUIA_ShowSelState, FALSE, + End, //IconobjectMCCObject + + Child, HVSpace, + + Child, inst->fpb_Objects[OBJNDX_Button_FileTypes_CreateIcon] = KeyButtonHelp(MSGID_BUTTON_CREATE_ICON, + 'i', + MSGID_SHORTHELP_BUTTON_CREATE_ICON), + + Child, HVSpace, + End, //VGroup + End, //HGroup + + Child, BalanceObject, + End, // BalanceObject + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_GROUP_FILETYPES_METHODS), + GroupFrame, + MUIA_Weight, 50, + + Child, inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods] = NListviewObject, + MUIA_CycleChain, TRUE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_SHORTHELP_LISTVIEW_FILETYPE_ACTION), + MUIA_NListview_NList, inst->fpb_Objects[OBJNDX_NList_FileTypes_Actions] = myFileTypesActionsNListObject, + MUIA_NList_PrivateData, inst, + MUIA_NList_Format, "BAR,", + InputListFrame, + MUIA_Background, MUII_ListBack, + MUIA_ContextMenu, inst->fpb_Objects[OBJNDX_ContextMenuFileTypesActions], + MUIA_NList_DragSortable, TRUE, + MUIA_NList_DisplayHook2, &inst->fpb_Hooks[HOOKNDX_FileTypesActionDisplay], + MUIA_NList_ConstructHook2, &inst->fpb_Hooks[HOOKNDX_FileTypesActionConstruct], + MUIA_NList_DestructHook2, &inst->fpb_Hooks[HOOKNDX_FileTypesActionDestruct], + End, //myFileTypesActionsNListClass + End, //NListviewObject + + Child, ColGroup(3), + Child, inst->fpb_Objects[OBJNDX_Popobject_FileTypes_Methods_Add] = PopobjectObject, + MUIA_Disabled, TRUE, + MUIA_UserData, inst, + MUIA_CycleChain, TRUE, + MUIA_Popstring_Button, KeyButtonHelp(MSGID_BUTTON_ADD_FILETYPEACTION, + 'a', + MSGID_SHORTHELP_BUTTON_ADD_FILETYPEACTION), + MUIA_Popobject_Object, inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods_Add] = NListviewObject, + MUIA_NListview_NList, inst->fpb_Objects[OBJNDX_Nlist_FileTypes_Methods_Add] = NListObject, + InputListFrame, + MUIA_Background, MUII_ListBack, + MUIA_NList_AdjustWidth, TRUE, + End, //NListObject + End, //NListviewObject + MUIA_Popstring_CloseHook, &inst->fpb_Hooks[HOOKNDX_AddFileTypesMethod], + End, //PopobjectObject + Child, inst->fpb_Objects[OBJNDX_Button_FileTypes_Actions_Remove] = KeyButtonHelp(MSGID_BUTTON_REMOVE_FILETYPEACTION, + 'r', + MSGID_SHORTHELP_BUTTON_REMOVE_FILETYPEACTION), + Child, inst->fpb_Objects[OBJNDX_Button_FileTypes_Actions_Learn] = KeyButtonHelp(MSGID_BUTTON_LEARN_FILETYPEACTION, + 'l', + MSGID_SHORTHELP_BUTTON_LEARN_FILETYPEACTION), + End, //ColGroup + End, //VGroup + + Child, BalanceObject, + End, // BalanceObject + + Child, ScrollgroupObject, + MUIA_Weight, 25, + MUIA_Scrollgroup_Contents, VirtgroupObject, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_SHORTHELP_VIRTGROUP_FILETYPE_ACTION_ATTRIBUTES), + + // empty placeholder + Child, inst->fpb_Objects[OBJNDX_Group_Filetypes_Actions_Empty] = VGroup, + MUIA_ShowMe, TRUE, + Child, HVSpace, + End, //VGroup + + // for MATCH + Child, inst->fpb_Objects[OBJNDX_Group_Filetypes_Actions_Match] = VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_GROUP_FILETYPESACTION_MATCH), + GroupFrame, + MUIA_ShowMe, FALSE, + + Child, HGroup, + Child, Label2((ULONG) GetLocString(MSGID_FILETYPEACTION_MATCH_OFFSET)), + Child, inst->fpb_Objects[OBJNDX_String_Filetypes_Actions_Match_Offset] = StringObject, + MUIA_CycleChain, TRUE, + StringFrame, + MUIA_String_Integer, 0, + MUIA_String_AdvanceOnCR, TRUE, + MUIA_String_Accept , "0123456879", + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_MATCH_OFFSET), + End, //StringObject + Child, Label2((ULONG) GetLocString(MSGID_FILETYPEACTION_MATCH_CASE_SENSITIVE)), + Child, inst->fpb_Objects[OBJNDX_Checkmark_FileTypes_Action_Match_Case] = KeyCheckMark(FALSE, "v"), + End, //HGroup + + Child, HGroup, + Child, Label2((ULONG) GetLocString(MSGID_FILETYPEACTION_MATCH_MATCH)), + Child, inst->fpb_Objects[OBJNDX_String_Filetypes_Actions_Match_Match] = StringObject, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_MATCH), + MUIA_CycleChain, TRUE, + MUIA_String_AdvanceOnCR, TRUE, + StringFrame, + End, //StringObject + End, //HGroup + Child, HVSpace, + End, //VGroup + + // for SEARCH + Child, inst->fpb_Objects[OBJNDX_Group_Filetypes_Actions_Search] = VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_GROUP_FILETYPESACTION_SEARCH), + GroupFrame, + MUIA_ShowMe, FALSE, + + Child, HGroup, + Child, HVSpace, + Child, Label2((ULONG) GetLocString(MSGID_FILETYPEACTION_SEARCH_SKIP_SPACES)), + Child, inst->fpb_Objects[OBJNDX_Checkmark_FileTypes_Action_Search_SkipSpaces] = KeyCheckMark(FALSE, "v"), + Child, HVSpace, + Child, Label2((ULONG) GetLocString(MSGID_FILETYPEACTION_SEARCH_CASE_SENSITIVE)), + Child, inst->fpb_Objects[OBJNDX_Checkmark_FileTypes_Action_Search_Case] = KeyCheckMark(FALSE, "v"), + Child, HVSpace, + End, //HGroup + + Child, HGroup, + Child, Label2((ULONG) GetLocString(MSGID_FILETYPEACTION_SEARCH_SEARCH)), + Child, inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Search_Search] = StringObject, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_SEARCH), + MUIA_CycleChain, TRUE, + MUIA_String_AdvanceOnCR, TRUE, + StringFrame, + End, //StringObject + End, //HGroup + Child, HVSpace, + End, //VGroup + + // for FILESIZE + Child, inst->fpb_Objects[OBJNDX_Group_Filetypes_Actions_Filesize] = VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_GROUP_FILETYPESACTION_FILESIZE), + GroupFrame, + MUIA_ShowMe, FALSE, + + Child, HGroup, + Child, Label2((ULONG) GetLocString(MSGID_FILETYPEACTION_FILESIZE_FILESIZE)), + Child, inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Filesize_Filesize] = StringObject, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_FILESIZE), + MUIA_CycleChain, TRUE, + StringFrame, + MUIA_String_Integer, 0, + MUIA_String_Accept , "0123456879", + MUIA_String_AdvanceOnCR, TRUE, + End, //StringObject + End, //HGroup + Child, HVSpace, + End, //VGroup + + // for MINSIZEMB + Child, inst->fpb_Objects[OBJNDX_Group_FileTypes_Action_MinSizeMB] = VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_GROUP_FILETYPESACTION_MINSIZEMB), + GroupFrame, + MUIA_ShowMe, FALSE, + + Child, HGroup, + Child, Label2((ULONG) GetLocString(MSGID_FILETYPEACTION_MINSIZEMB_SIZE)), + Child, inst->fpb_Objects[OBJNDX_String_FileTypes_Action_MinSizeMB_MinSize] = StringObject, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_MINSIZEMB), + MUIA_CycleChain, TRUE, + StringFrame, + MUIA_String_Integer, 0, + MUIA_String_Accept , "0123456879", + MUIA_String_AdvanceOnCR, TRUE, + End, //StringObject + End, //HGroup + Child, HVSpace, + End, //VGroup + // for PATTERN + Child, inst->fpb_Objects[OBJNDX_Group_Filetypes_Actions_Pattern] = VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_GROUP_FILETYPESACTION_PATTERN), + GroupFrame, + MUIA_ShowMe, FALSE, + + Child, HGroup, + Child, Label2((ULONG) GetLocString(MSGID_FILETYPEACTION_PATTERN_PATTERN)), + Child, inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Pattern_Pattern] = StringObject, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_PATTERN), + MUIA_CycleChain, TRUE, + StringFrame, + MUIA_String_AdvanceOnCR, TRUE, + End, //StringObject + End, //HGroup + Child, HVSpace, + End, //VGroup + + // for DOSDEVICE + Child, inst->fpb_Objects[OBJNDX_Group_Filetypes_Actions_DosDevice] = VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_GROUP_FILETYPESACTION_DOSDEVICE), + GroupFrame, + MUIA_ShowMe, FALSE, + + Child, HGroup, + Child, Label2((ULONG) GetLocString(MSGID_FILETYPEACTION_DOSDEVICE_PATTERN)), + Child, inst->fpb_Objects[OBJNDX_String_FileTypes_Action_DosDevice_Pattern] = StringObject, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_DOSDEVICE), + MUIA_CycleChain, TRUE, + StringFrame, + MUIA_String_AdvanceOnCR, TRUE, + End, //StringObject + End, //HGroup + Child, HVSpace, + End, //VGroup + + // for DEVICENAME + Child, inst->fpb_Objects[OBJNDX_Group_Filetypes_Actions_DeviceName] = VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_GROUP_FILETYPESACTION_DEVICENAME), + GroupFrame, + MUIA_ShowMe, FALSE, + + Child, HGroup, + Child, Label2((ULONG) GetLocString(MSGID_FILETYPEACTION_DEVICENAME_PATTERN)), + Child, inst->fpb_Objects[OBJNDX_String_FileTypes_Action_DeviceName_Pattern] = StringObject, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_DEVICENAME), + MUIA_CycleChain, TRUE, + StringFrame, + MUIA_String_AdvanceOnCR, TRUE, + End, //StringObject + End, //HGroup + Child, HVSpace, + End, //VGroup + + // for CONTENTS + Child, inst->fpb_Objects[OBJNDX_Group_Filetypes_Actions_Contents] = VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_GROUP_FILETYPESACTION_CONTENTS), + GroupFrame, + MUIA_ShowMe, FALSE, + + Child, HGroup, + Child, Label2((ULONG) GetLocString(MSGID_FILETYPEACTION_CONTENTS_PATTERN)), + Child, inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Contents_Pattern] = StringObject, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_CONTENTS), + MUIA_CycleChain, TRUE, + StringFrame, + MUIA_String_AdvanceOnCR, TRUE, + End, //StringObject + End, //HGroup + Child, HVSpace, + End, //VGroup + + // for DOSTYPE + Child, inst->fpb_Objects[OBJNDX_Group_Filetypes_Actions_DosType] = VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_GROUP_FILETYPESACTION_DOSTYPE), + GroupFrame, + MUIA_ShowMe, FALSE, + + Child, HGroup, + Child, Label2((ULONG) GetLocString(MSGID_FILETYPEACTION_DOSTYPE_PATTERN)), + Child, inst->fpb_Objects[OBJNDX_String_FileTypes_Action_DosType_Pattern] = StringObject, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_DOSTYPE), + MUIA_CycleChain, TRUE, + StringFrame, + MUIA_String_AdvanceOnCR, TRUE, + End, //StringObject + End, //HGroup + Child, HVSpace, + End, //VGroup + + // for PROTECTION + Child, inst->fpb_Objects[OBJNDX_Group_Filetypes_Actions_Protection] = VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_GROUP_FILETYPESACTION_PROTECTION), + GroupFrame, + MUIA_ShowMe, FALSE, + + Child, ColGroup(4), + Child, Label2((ULONG) GetLocString(MSGID_FILETYPEACTION_PROTECTION_R)), + Child, inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_R] = CycleObject, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_R), + MUIA_CycleChain, TRUE, + MUIA_Font, MUIV_Font_Button, + MUIA_Cycle_Entries, FileTypeActionProtectionStrings, + End, //CycleObject + + Child, Label2((ULONG) GetLocString(MSGID_FILETYPEACTION_PROTECTION_W)), + Child, inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_W] = CycleObject, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_W), + MUIA_CycleChain, TRUE, + MUIA_Font, MUIV_Font_Button, + MUIA_Cycle_Entries, FileTypeActionProtectionStrings, + End, //CycleObject + + Child, Label2((ULONG) GetLocString(MSGID_FILETYPEACTION_PROTECTION_E)), + Child, inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_E] = CycleObject, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_E), + MUIA_CycleChain, TRUE, + MUIA_Font, MUIV_Font_Button, + MUIA_Cycle_Entries, FileTypeActionProtectionStrings, + End, //CycleObject + + Child, Label2((ULONG) GetLocString(MSGID_FILETYPEACTION_PROTECTION_D)), + Child, inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_D] = CycleObject, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_D), + MUIA_CycleChain, TRUE, + MUIA_Font, MUIV_Font_Button, + MUIA_Cycle_Entries, FileTypeActionProtectionStrings, + End, //CycleObject + + Child, Label2((ULONG) GetLocString(MSGID_FILETYPEACTION_PROTECTION_S)), + Child, inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_S] = CycleObject, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_S), + MUIA_CycleChain, TRUE, + MUIA_Font, MUIV_Font_Button, + MUIA_Cycle_Entries, FileTypeActionProtectionStrings, + End, //CycleObject + + Child, Label2((ULONG) GetLocString(MSGID_FILETYPEACTION_PROTECTION_P)), + Child, inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_P] = CycleObject, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_P), + MUIA_CycleChain, TRUE, + MUIA_Font, MUIV_Font_Button, + MUIA_Cycle_Entries, FileTypeActionProtectionStrings, + End, //CycleObject + + Child, Label2((ULONG) GetLocString(MSGID_FILETYPEACTION_PROTECTION_A)), + Child, inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_A] = CycleObject, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_A), + MUIA_CycleChain, TRUE, + MUIA_Font, MUIV_Font_Button, + MUIA_Cycle_Entries, FileTypeActionProtectionStrings, + End, //CycleObject + + Child, Label2((ULONG) GetLocString(MSGID_FILETYPEACTION_PROTECTION_H)), + Child, inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_H] = CycleObject, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_H), + MUIA_CycleChain, TRUE, + MUIA_Font, MUIV_Font_Button, + MUIA_Cycle_Entries, FileTypeActionProtectionStrings, + End, //CycleObject + + End, //ColGroup + Child, HVSpace, + End, //VGroup + End, //VirtualGroup + End, //Scrollgroup + + End, //VGroup + + // --- filetype actions + Child, VGroup, + Child, inst->fpb_Objects[OBJNDX_MainListView] = NListviewObject, + MUIA_CycleChain, TRUE, + MUIA_NListview_NList, inst->fpb_Objects[OBJNDX_MainListTree] = myNListTreeObject, + MUIA_ContextMenu, inst->fpb_Objects[OBJNDX_ContextMenu], + MUIA_NList_PrivateData, inst, + MUIA_NList_Format, "", + InputListFrame, + MUIA_Background, MUII_ListBack, + MUIA_NListtree_DisplayHook, &inst->fpb_Hooks[HOOKNDX_TreeDisplay], + MUIA_NListtree_ConstructHook, &inst->fpb_Hooks[HOOKNDX_TreeConstruct], + MUIA_NListtree_DestructHook, &inst->fpb_Hooks[HOOKNDX_TreeDestruct], + MUIA_NListtree_DragDropSort, TRUE, + MUIA_NList_ShowDropMarks, TRUE, + MUIA_NListtree_EmptyNodes, TRUE, + MUIA_NListtree_AutoVisible, MUIV_NListtree_AutoVisible_Expand, + End, // myNListTreeClass + + MUIA_Listview_DragType, MUIV_Listview_DragType_None, + End, // NListviewObject + + Child, inst->fpb_Objects[OBJNDX_HiddenListView] = NListviewObject, + MUIA_ShowMe, FALSE, + MUIA_CycleChain, TRUE, + MUIA_NListview_NList, inst->fpb_Objects[OBJNDX_HiddenListTree] = myNListTreeObject, + MUIA_ContextMenu, inst->fpb_Objects[OBJNDX_ContextMenu], + MUIA_NList_PrivateData, inst, + MUIA_NList_Format, "", + InputListFrame, + MUIA_Background, MUII_ListBack, + MUIA_NListtree_DisplayHook, &inst->fpb_Hooks[HOOKNDX_TreeDisplay], + MUIA_NListtree_ConstructHook, &inst->fpb_Hooks[HOOKNDX_TreeConstruct], + MUIA_NListtree_DestructHook, &inst->fpb_Hooks[HOOKNDX_TreeDestruct], + MUIA_NListtree_DragDropSort, TRUE, + MUIA_NList_ShowDropMarks, TRUE, + MUIA_NListtree_EmptyNodes, TRUE, + MUIA_NListtree_AutoVisible, MUIV_NListtree_AutoVisible_Expand, + End, // myNListTreeClass + + MUIA_Listview_DragType, MUIV_Listview_DragType_None, + End, // NListviewObject + + Child, HGroup, + Child, inst->fpb_Objects[OBJNDX_Lamp_Changed] = LampObject, + MUIA_Lamp_Type, MUIV_Lamp_Type_Huge, + MUIA_Lamp_Color, MUIV_Lamp_Color_Off, + MUIA_ShortHelp, GetLocString(MSGID_SHORTHELP_LAMP_CHANGED), + End, //LampObject + + Child, ColGroup(2), + Child, inst->fpb_Objects[OBJNDX_AddEntryPopObject] = PopobjectObject, + MUIA_Disabled, TRUE, + MUIA_CycleChain, TRUE, + MUIA_Popstring_Button, inst->fpb_Objects[OBJNDX_ButtonAddEntry] = KeyButtonHelp(MSGID_BUTTON_ADD_ENTRY, + 'a', + MSGID_SHORTHELP_BUTTON_ADD_ENTRY), + MUIA_Popobject_Object, inst->fpb_Objects[OBJNDX_AddEntryListView] = NListviewObject, + MUIA_NListview_NList, inst->fpb_Objects[OBJNDX_AddEntryList] = NListObject, + InputListFrame, + MUIA_Background, MUII_ListBack, + MUIA_NList_ConstructHook2, &inst->fpb_Hooks[HOOKNDX_AddEntryListConstruct], + MUIA_NList_DestructHook2, &inst->fpb_Hooks[HOOKNDX_AddEntryListDestruct], + MUIA_NList_DisplayHook2, &inst->fpb_Hooks[HOOKNDX_AddEntryListDisplay], + MUIA_NList_AdjustWidth, TRUE, + End, //NListObject + End, //NListviewObject + End, //PopobjectObject + + Child, inst->fpb_Objects[OBJNDX_ButtonRemoveEntry] = KeyButtonHelp(MSGID_BUTTON_DELETE_ENTRY, + 'd', + MSGID_SHORTHELP_BUTTON_DELETE_ENTRY), + End, //ColGroup + End, //HGroup + + Child, BalanceObject, + End, // BalanceObject + + Child, inst->fpb_Objects[OBJNDX_AttrListView] = NListviewObject, + MUIA_CycleChain, TRUE, + MUIA_NListview_NList, inst->fpb_Objects[OBJNDX_AttrList] = myNListObject, + MUIA_ContextMenu, inst->fpb_Objects[OBJNDX_ContextMenuAttrList], + MUIA_NList_PrivateData, inst, + MUIA_NList_Format, ",", + InputListFrame, + MUIA_Background, MUII_ListBack, + MUIA_NList_DisplayHook2, &inst->fpb_Hooks[HOOKNDX_AttrDisplay], + MUIA_NList_ConstructHook2, &inst->fpb_Hooks[HOOKNDX_AttrConstruct], + MUIA_NList_DestructHook2, &inst->fpb_Hooks[HOOKNDX_AttrDestruct], + MUIA_NList_DragSortable, FALSE, + MUIA_NList_ShowDropMarks, FALSE, + MUIA_NList_Title, TRUE, + MUIA_NList_TitleSeparator, TRUE, + End, // myNListTreeClass + + MUIA_Listview_DragType, MUIV_Listview_DragType_None, + MUIA_Weight, 50, + End, // NListviewObject + + Child, ColGroup(3), + Child, inst->fpb_Objects[OBJNDX_AddAttrPopObject] = PopobjectObject, + MUIA_Disabled, TRUE, + MUIA_CycleChain, TRUE, + MUIA_Popstring_Button, inst->fpb_Objects[OBJNDX_ButtonAddAttribute] = KeyButtonHelp(MSGID_BUTTON_ADD_ATTRIBUTE, + ' ', + MSGID_SHORTHELP_BUTTON_ADD_ATTRIBUTE), + MUIA_Popobject_Object, inst->fpb_Objects[OBJNDX_AddAttrListView] = NListviewObject, + MUIA_NListview_NList, inst->fpb_Objects[OBJNDX_AddAttrList] = NListObject, + InputListFrame, + MUIA_Background, MUII_ListBack, + MUIA_NList_ConstructHook2, &inst->fpb_Hooks[HOOKNDX_AddAttrListConstruct], + MUIA_NList_DestructHook2, &inst->fpb_Hooks[HOOKNDX_AddAttrListDestruct], + MUIA_NList_DisplayHook2, &inst->fpb_Hooks[HOOKNDX_AddAttrListDisplay], + MUIA_NList_AdjustWidth, TRUE, + End, //NListObject + End, //NListviewObject + End, //PopobjectObject + Child, inst->fpb_Objects[OBJNDX_ButtonEditAttribute] = KeyButtonHelp(MSGID_BUTTON_EDIT_ATTRIBUTE, + 'e', + MSGID_SHORTHELP_BUTTON_EDIT_ATTRIBUTE), + Child, inst->fpb_Objects[OBJNDX_ButtonRemoveAttribute] = KeyButtonHelp(MSGID_BUTTON_DELETE_ATTRIBUTE, + 'r', + MSGID_SHORTHELP_BUTTON_DELETE_ATTRIBUTE), + End, //HGroup + + MUIA_ContextMenu, inst->fpb_Objects[OBJNDX_ContextMenu], + + End, //VGroup + + End, //RegisterObject + + End; //VGroup + + if (NULL == inst->fpb_Objects[OBJNDX_Group_Main]) + return NULL; + + d1(kprintf("%s/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst)); + + set(inst->fpb_Objects[OBJNDX_Menu_HideEmptyEntries], MUIA_Menuitem_Checked, inst->fpb_HideEmptyNodes); + set(inst->fpb_Objects[OBJNDX_ButtonRemoveEntry], MUIA_Disabled, TRUE); + set(inst->fpb_Objects[OBJNDX_ButtonRemoveAttribute], MUIA_Disabled, TRUE); + set(inst->fpb_Objects[OBJNDX_ButtonEditAttribute], MUIA_Disabled, TRUE); + set(inst->fpb_Objects[OBJNDX_Menu_CopyAttr], MUIA_Menuitem_Enabled, FALSE); + set(inst->fpb_Objects[OBJNDX_Menu_CutAttr], MUIA_Menuitem_Enabled, FALSE); + set(inst->fpb_Objects[OBJNDX_HiddenListView], MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + + set(inst->fpb_Objects[OBJNDX_Button_FindNextFileType], MUIA_Disabled, TRUE); + set(inst->fpb_Objects[OBJNDX_Button_FindPrevFileType], MUIA_Disabled, TRUE); + + set(inst->fpb_Objects[OBJNDX_Button_FileTypes_Remove], MUIA_Disabled, TRUE); + set(inst->fpb_Objects[OBJNDX_Button_FileTypes_Actions_Remove], MUIA_Disabled, TRUE); + set(inst->fpb_Objects[OBJNDX_Button_FileTypes_Actions_Learn], MUIA_Disabled, TRUE); + set(inst->fpb_Objects[OBJNDX_Popobject_FileTypes_Methods_Add], MUIA_Disabled, TRUE); + + DoMethod(inst->fpb_Objects[OBJNDX_Group_Main], MUIM_Notify, MUIA_ContextMenuTrigger, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_Group_Main], 3, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_ContextMenuTrigger], MUIV_TriggerValue ); + + DoMethod(inst->fpb_Objects[OBJNDX_AddEntryListView], MUIM_Notify, MUIA_Listview_DoubleClick, TRUE, + inst->fpb_Objects[OBJNDX_AddEntryPopObject], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_AddEntry]); + DoMethod(inst->fpb_Objects[OBJNDX_AddAttrListView], MUIM_Notify, MUIA_Listview_DoubleClick, TRUE, + inst->fpb_Objects[OBJNDX_AddAttrPopObject], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_AddAttribute]); + + // Call hook when Find Filetype Hide button is clicked + DoMethod(inst->fpb_Objects[OBJNDX_Button_HideFind], MUIM_Notify, MUIA_Pressed, FALSE, + inst->fpb_Objects[OBJNDX_Button_HideFind], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_HideFindGroup]); + + // Call hook everytime the contents of StringFindFileType changes + DoMethod(inst->fpb_Objects[OBJNDX_String_FindFileType], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_String_FindFileType], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_IncrementalFindFileType]); + + // Call FindNextFileTypeHook when "Next" button is clicked + DoMethod(inst->fpb_Objects[OBJNDX_Button_FindNextFileType], MUIM_Notify, MUIA_Pressed, FALSE, + inst->fpb_Objects[OBJNDX_Button_FindNextFileType], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_IncrementalFindNextFileType]); + + // Call FindPrevFileTypeHook when "Prev" button is clicked + DoMethod(inst->fpb_Objects[OBJNDX_Button_FindPrevFileType], MUIM_Notify, MUIA_Pressed, FALSE, + inst->fpb_Objects[OBJNDX_Button_FindPrevFileType], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_IncrementalFindPrevFileType]); + + // call hook on double click into "Add Method" popup listview + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods_Add], MUIM_Notify, MUIA_Listview_DoubleClick, TRUE, + inst->fpb_Objects[OBJNDX_Popobject_FileTypes_Methods_Add], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_AddFileTypesMethod]); + + // call hook when the "Learn" button is pressed + DoMethod(inst->fpb_Objects[OBJNDX_Button_FileTypes_Actions_Learn], MUIM_Notify, MUIA_Pressed, FALSE, + inst->fpb_Objects[OBJNDX_Button_FileTypes_Actions_Learn], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_Learn_FileType] ); + + // call hook everytime the filetype actions list is drag-drop sorted + DoMethod(inst->fpb_Objects[OBJNDX_NList_FileTypes_Actions], MUIM_Notify, MUIA_NList_DragSortInsert, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_NList_FileTypes_Actions], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_DragDropSort_FileTypesAction] ); + + // call hook everytime a new filetype is added + DoMethod(inst->fpb_Objects[OBJNDX_Button_FileTypes_Add], MUIM_Notify, MUIA_Pressed, FALSE, + inst->fpb_Objects[OBJNDX_Button_FileTypes_Add], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_AddFileType] ); + + // call hook everytime a new filetype is removed + DoMethod(inst->fpb_Objects[OBJNDX_Button_FileTypes_Remove], MUIM_Notify, MUIA_Pressed, FALSE, + inst->fpb_Objects[OBJNDX_Button_FileTypes_Remove], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_RemoveFileType] ); + + // call hook everytime a new filetype is selected + DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], MUIM_Notify, MUIA_NListtree_Active, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_NListtree_FileTypes], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_SelectFileTypesEntry] ); + + // call hook everytime a new filetype is renamed + DoMethod(inst->fpb_Objects[OBJNDX_String_FileTypes_Name], MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_String_FileTypes_Name], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_RenameFileType] ); + + // call hook everytime a new filetypes action is removed + DoMethod(inst->fpb_Objects[OBJNDX_Button_FileTypes_Actions_Remove], MUIM_Notify, MUIA_Pressed, FALSE, + inst->fpb_Objects[OBJNDX_Button_FileTypes_Actions_Remove], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_RemoveFileTypeAction] ); + + // setup hook if "create new" button is presseed for filetypes icon + DoMethod(inst->fpb_Objects[OBJNDX_Button_FileTypes_CreateIcon], MUIM_Notify, MUIA_Pressed, FALSE, + inst->fpb_Objects[OBJNDX_Button_FileTypes_CreateIcon], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_CreateNewFileTypesIcon] ); + + // setup hook if filetypes icon is clicked + DoMethod(inst->fpb_Objects[OBJNDX_IconObjectMCC_FileTypes_Icon], MUIM_Notify, MUIA_Pressed, FALSE, + inst->fpb_Objects[OBJNDX_IconObjectMCC_FileTypes_Icon], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_EditFileTypesIcon] ); + + // call hook if filetypes action MATCH attributes are changed + DoMethod(inst->fpb_Objects[OBJNDX_String_Filetypes_Actions_Match_Offset], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_String_Filetypes_Actions_Match_Match], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionMatchOffset] ); + DoMethod(inst->fpb_Objects[OBJNDX_Checkmark_FileTypes_Action_Match_Case], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_Checkmark_FileTypes_Action_Match_Case], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionMatchCase] ); + DoMethod(inst->fpb_Objects[OBJNDX_String_Filetypes_Actions_Match_Match], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_String_Filetypes_Actions_Match_Match], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionMatchMatch] ); + + // call hook if filetypes action SEARCH attributes are changed + DoMethod(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Search_Search], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Search_Search], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionSearchSearch] ); + DoMethod(inst->fpb_Objects[OBJNDX_Checkmark_FileTypes_Action_Search_Case], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_Checkmark_FileTypes_Action_Search_Case], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionSearchCase] ); + DoMethod(inst->fpb_Objects[OBJNDX_Checkmark_FileTypes_Action_Search_SkipSpaces], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_Checkmark_FileTypes_Action_Search_SkipSpaces], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionSearchSkipSpaces] ); + + // call hook if filetypes action FILESIZE attributes are changed + DoMethod(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Filesize_Filesize], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Filesize_Filesize], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionFilesize] ); + + // call hook if filetypes action PATTERN attributes are changed + DoMethod(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Pattern_Pattern], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Pattern_Pattern], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionPattern] ); + + // call hook if filetypes action DOSDEVICE attributes are changed + DoMethod(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_DosDevice_Pattern], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_String_FileTypes_Action_DosDevice_Pattern], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionDosDevice] ); + + // call hook if filetypes action DEVICENAME attributes are changed + DoMethod(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_DeviceName_Pattern], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_String_FileTypes_Action_DeviceName_Pattern], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionDeviceName] ); + + // call hook if filetypes action CONTENTS attributes are changed + DoMethod(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Contents_Pattern], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Contents_Pattern], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionContents] ); + + // call hook if filetypes action DOSTYPE attributes are changed + DoMethod(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_DosType_Pattern], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_String_FileTypes_Action_DosType_Pattern], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionDosType] ); + + // call hook if filetypes action MINSIZEMB attributes are changed + DoMethod(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_MinSizeMB_MinSize], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_String_FileTypes_Action_MinSizeMB_MinSize], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionMinSize] ); + + // call hook if filetypes action PROTECTION attributes are changed + DoMethod(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_R], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_R], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionProtection] ); + DoMethod(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_W], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_W], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionProtection] ); + DoMethod(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_E], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_E], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionProtection] ); + DoMethod(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_D], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_D], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionProtection] ); + DoMethod(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_S], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_S], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionProtection] ); + DoMethod(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_P], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_P], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionProtection] ); + DoMethod(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_A], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_A], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionProtection] ); + DoMethod(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_H], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_H], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionProtection] ); + + // call hook everytime a filetypes action entry is selected + DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], MUIM_Notify, MUIA_NList_Active, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_Group_Main], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_SelectFileTypesActionEntry] ); + + DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], MUIM_Notify, MUIA_NListtree_Active, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_Group_Main], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_SelectEntry] ); + + DoMethod(inst->fpb_Objects[OBJNDX_AttrList], MUIM_Notify, MUIA_NList_Active, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_Group_Main], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_SelectAttribute] ); + + DoMethod(inst->fpb_Objects[OBJNDX_ButtonRemoveEntry], MUIM_Notify, MUIA_Pressed, FALSE, + inst->fpb_Objects[OBJNDX_Group_Main], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_RemoveEntry]); + + DoMethod(inst->fpb_Objects[OBJNDX_ButtonRemoveAttribute], MUIM_Notify, MUIA_Pressed, FALSE, + inst->fpb_Objects[OBJNDX_Group_Main], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_RemoveAttribute]); + + // Edit Attribute by pressing "Edit" button of double-clicking attribute in list + + DoMethod(inst->fpb_Objects[OBJNDX_AttrList], MUIM_Notify, MUIA_Listview_DoubleClick, TRUE, + inst->fpb_Objects[OBJNDX_Group_Main], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_EditAttribute] ); + + DoMethod(inst->fpb_Objects[OBJNDX_ButtonEditAttribute], MUIM_Notify, MUIA_Pressed, FALSE, + inst->fpb_Objects[OBJNDX_Group_Main], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_EditAttribute]); + + // initially display icon for "project" filetype + // "Create new" icon is disabled if "def_project" icon is present + set(inst->fpb_Objects[OBJNDX_Button_FileTypes_CreateIcon], + MUIA_Disabled, DisplayFileTypesIcon(inst, "project")); + + return inst->fpb_Objects[OBJNDX_Group_Main]; +} + + +static Object **CreateSubWindows(Class *cl, Object *o) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) INST_DATA(cl, o); + + d1(KPrintF(__FILE__ "/%s/%ld: START\n", __FUNC__, __LINE__)); + + inst->fpb_SubWindows[0] = inst->fpb_Objects[OBJNDX_WIN_EditAttribute] = WindowObject, + MUIA_Window_Title, GetLocString(MSGID_EDITATTRIBUTE_WINDOWTITLE), + MUIA_Window_ID, MAKE_ID('F','T','P','R'), + WindowContents, VGroup, + + Child, TextObject, + MUIA_Text_PreParse, MUIX_C, + MUIA_Text_Contents, GetLocString(MSGID_EDITATTRIBUTE_TITLE), + End, // TextObject + + Child, HGroup, + TextFrame, + Child, HVSpace, + Child, inst->fpb_Objects[OBJNDX_Text_AttributeName] = TextObject, + MUIA_HorizWeight, 200, + MUIA_Text_PreParse, MUIX_C, + MUIA_Text_Contents, "xxxxxxxxxxxxxxxxxxxxxxxxxxx", + MUIA_Text_SetMin, TRUE, + End, // TextObject + Child, HVSpace, + End, //HGroup + + Child, inst->fpb_Objects[OBJNDX_Group_AttributeValue] = VGroup, + MUIA_ShowMe, FALSE, + + Child, inst->fpb_Objects[OBJNDX_String_AttributeValue] = StringObject, + MUIA_CycleChain, TRUE, + StringFrame, + MUIA_String_Contents, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + MUIA_String_AdvanceOnCR, TRUE, + MUIA_Text_SetMin, TRUE, + End, // StringObject + End, //VGroup + + Child, inst->fpb_Objects[OBJNDX_Group_AttributeAslPath] = VGroup, + MUIA_ShowMe, FALSE, + + Child, inst->fpb_Objects[OBJNDX_Pop_AttributeSelectAslPath] = PopaslObject, + MUIA_CycleChain, TRUE, + MUIA_Popasl_StartHook, &inst->fpb_Hooks[HOOKNDX_EditAttributePopAslPathStartHook], + MUIA_Popasl_Type, ASL_FileRequest, + MUIA_String_AdvanceOnCR, TRUE, + MUIA_Popstring_String, KeyString("", MAX_ATTRVALUE, '\0'), + MUIA_Popstring_Button, PopButton(MUII_PopDrawer), + End, //PopaslObject + End, //VGroup + + Child, inst->fpb_Objects[OBJNDX_Group_AttributeAslFile] = HGroup, + MUIA_ShowMe, FALSE, + + Child, inst->fpb_Objects[OBJNDX_DtPic_AttributeSelectAslFile] = DataTypesImageObject, + MUIA_ScaDtpic_Name, (ULONG) "", + MUIA_ScaDtpic_FailIfUnavailable, FALSE, + End, //DataTypesMCCObject + + Child, inst->fpb_Objects[OBJNDX_Pop_AttributeSelectAslFile] = PopaslObject, + MUIA_CycleChain, TRUE, + MUIA_Popasl_StartHook, &inst->fpb_Hooks[HOOKNDX_EditAttributePopAslFileStartHook], + MUIA_Popasl_Type, ASL_FileRequest, + MUIA_Popstring_String, KeyString("", MAX_ATTRVALUE, '\0'), + MUIA_Popstring_Button, PopButton(MUII_PopFile), + End, //PopaslObject + End, //VGroup + + Child, inst->fpb_Objects[OBJNDX_Group_AttributeAslFont] = VGroup, + MUIA_ShowMe, FALSE, + + Child, inst->fpb_Objects[OBJNDX_Pop_AttributeSelectAslFont] = PopaslObject, + MUIA_CycleChain, TRUE, + TAG_IGNORE, 993, + MUIA_Popasl_Type, ASL_FontRequest, + MUIA_Popstring_String, KeyString("", MAX_ATTRVALUE, '\0'), + MUIA_Popstring_Button, PopButton(MUII_PopUp), + End, //PopaslObject + + Child, inst->fpb_Objects[OBJNDX_AslFont_Sample] = FontSampleObject, + TextFrame, + MUIA_Background, MUII_TextBack, + MUIA_FontSample_DemoString, (ULONG) GetLocString(MSGID_TTFONTSPAGE_SAMPLETEXT), + MUIA_FontSample_Antialias, inst->fpb_TTfAntialias, + MUIA_FontSample_Gamma, inst->fpb_TTfGamma, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_TTFONTSPAGE_SCREENFONT_SAMPLETEXT_SHORTHELP), + End, //FontSampleMCCObject + End, //VGroup + + Child, inst->fpb_Objects[OBJNDX_Group_AttributeTTFont] = VGroup, + MUIA_ShowMe, FALSE, + + Child, inst->fpb_Objects[OBJNDX_Pop_AttributeSelectTTFont] = PopstringObject, + MUIA_CycleChain, TRUE, + TAG_IGNORE, 994, + MUIA_Popstring_String, KeyString("", MAX_ATTRVALUE, '\0'), + MUIA_String_AdvanceOnCR, TRUE, + MUIA_Popstring_Button, PopButton(MUII_PopUp), + MUIA_Popstring_OpenHook, &inst->fpb_Hooks[HOOKNDX_EditAttributeTTFontOpen], + MUIA_Popstring_CloseHook, &inst->fpb_Hooks[HOOKNDX_EditAttributeTTFontClose], + End, //PopstringObject + + Child, inst->fpb_Objects[OBJNDX_TTFont_Sample] = FontSampleObject, + TextFrame, + MUIA_Background, MUII_TextBack, + MUIA_FontSample_Antialias, inst->fpb_TTfAntialias, + MUIA_FontSample_Gamma, inst->fpb_TTfGamma, + MUIA_FontSample_DemoString, (ULONG) GetLocString(MSGID_TTFONTSPAGE_SAMPLETEXT), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_TTFONTSPAGE_SCREENFONT_SAMPLETEXT_SHORTHELP), + End, //FontSampleMCCObject + End, //VGroup + + Child, inst->fpb_Objects[OBJNDX_Group_AttributeSelectValue] = VGroup, + MUIA_ShowMe, FALSE, + + Child, inst->fpb_Objects[OBJNDX_Pop_AttributeSelectValue] = PopobjectObject, + MUIA_CycleChain, TRUE, + MUIA_Popstring_Button, PopButton(MUII_PopUp), + MUIA_Popstring_String, KeyString("", MAX_ATTRVALUE, '\0'), + MUIA_Popobject_Object, inst->fpb_Objects[OBJNDX_Listview_AttributeSelectValue] = NListviewObject, + MUIA_NListview_NList, inst->fpb_Objects[OBJNDX_List_AttributeSelectValue] = NListObject, + InputListFrame, + MUIA_Background, MUII_ListBack, + MUIA_NList_ConstructHook2, &inst->fpb_Hooks[HOOKNDX_EditAttributeListConstruct], + MUIA_NList_DestructHook2, &inst->fpb_Hooks[HOOKNDX_EditAttributeListDestruct], + MUIA_NList_DisplayHook2, &inst->fpb_Hooks[HOOKNDX_EditAttributeListDisplay], + MUIA_NList_AdjustWidth, TRUE, + End, //NListObject + End, //NListviewObject + End, //PopobjectObject + End, //VGroup + + Child, ColGroup(2), + Child, inst->fpb_Objects[OBJNDX_ButtonChangeAttribute] = KeyButtonHelp(MSGID_BUTTON_CHANGE_ATTRIBUTE, + ' ', + MSGID_SHORTHELP_BUTTON_CHANGE_ATTRIBUTE), + Child, inst->fpb_Objects[OBJNDX_ButtonKeepAttribute] = KeyButtonHelp(MSGID_BUTTON_KEEP_ATTRIBUTE, + ' ', + MSGID_SHORTHELP_BUTTON_KEEP_ATTRIBUTE), + End, //ColGroup + End, //VGroup + End; + + d1(KPrintF(__FILE__ "/%s/%ld: fpb_SubWindows[0]=%08lx\n", __FUNC__, __LINE__, inst->fpb_SubWindows[0])); + + inst->fpb_SubWindows[1] = NULL; + + set(inst->fpb_Objects[OBJNDX_Group_AttributeTTFont], MUIA_Disabled, NULL == TTEngineBase); + + // Selecting a new ASL font updates Asl font sample + DoMethod(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectAslFont], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_AslFont_Sample], 3, MUIM_Set, MUIA_FontSample_StdFontDesc, MUIV_TriggerValue); + + // Pressing "change" button in "edit attribute" window calls hook + DoMethod(inst->fpb_Objects[OBJNDX_ButtonChangeAttribute], MUIM_Notify, MUIA_Pressed, FALSE, + inst->fpb_Objects[OBJNDX_Group_Main], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_ChangeAttribute]); + + // Pressing "cancel" button in "edit attribute" window closes window + DoMethod(inst->fpb_Objects[OBJNDX_ButtonKeepAttribute], MUIM_Notify, MUIA_Pressed, FALSE, + inst->fpb_Objects[OBJNDX_WIN_EditAttribute], 3, MUIM_Set, MUIA_Window_Open, FALSE); + + // Doubleclick in "edit attribute" selection listview calls hook + DoMethod(inst->fpb_Objects[OBJNDX_Listview_AttributeSelectValue], MUIM_Notify, MUIA_Listview_DoubleClick, TRUE, + inst->fpb_Objects[OBJNDX_Pop_AttributeSelectValue], 2, MUIM_CallHook, &inst->fpb_Hooks[HOOKNDX_SelectAttributeValue]); + + // Update sample image everytime the image file string changes + DoMethod(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectAslFile], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + inst->fpb_Objects[OBJNDX_DtPic_AttributeSelectAslFile], 3, MUIM_Set, MUIA_ScaDtpic_Name, MUIV_TriggerValue); + + return inst->fpb_SubWindows; +} + + +static Object *CreatePrefsImage(void) +{ +#include "FileTypesPrefsImage.h" + Object *img; + + // First try to load datatypes image from THEME: tree + img = DataTypesImageObject, + MUIA_ScaDtpic_Name, (ULONG) "THEME:prefs/plugins/filetypes", + MUIA_ScaDtpic_FailIfUnavailable, TRUE, + End; //DataTypesMCCObject + + if (NULL == img) + img = IMG(FileTypes, FILETYPES); // use built-in fallback image + + return img; +} + + +static void InitHooks(struct FileTypesPrefsInst *inst) +{ + ULONG n; + + for (n=0; nfpb_Hooks[n] = FileTypesPrefsHooks[n]; + inst->fpb_Hooks[n].h_Data = inst; + } +} + + +static BOOL OpenLibraries(void) +{ + DOSBase = (APTR) OpenLibrary( "dos.library", 39 ); + if (NULL == DOSBase) + return FALSE; +#ifdef __amigaos4__ + IDOS = (struct DOSIFace *)GetInterface((struct Library *)DOSBase, "main", 1, NULL); + if (NULL == IDOS) + return FALSE; +#endif + + DiskfontBase = OpenLibrary("diskfont.library", 39); + if (NULL == DiskfontBase) + return FALSE; +#ifdef __amigaos4__ + IDiskfont = (struct DiskfontIFace *)GetInterface((struct Library *)DiskfontBase, "main", 1, NULL); + if (NULL == IDiskfont) + return FALSE; +#endif + + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + if (NULL == IntuitionBase) + return FALSE; +#ifdef __amigaos4__ + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + return FALSE; +#endif + + MUIMasterBase = OpenLibrary("zune.library", 0); + if (NULL == MUIMasterBase) + MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN-1); + if (NULL == MUIMasterBase) + return FALSE; +#ifdef __amigaos4__ + IMUIMaster = (struct MUIMasterIFace *)GetInterface((struct Library *)MUIMasterBase, "main", 1, NULL); + if (NULL == IMUIMaster) + return FALSE; +#endif + + IFFParseBase = OpenLibrary("iffparse.library", 36); + if (NULL == IFFParseBase) + return FALSE; +#ifdef __amigaos4__ + IIFFParse = (struct IFFParseIFace *)GetInterface((struct Library *)IFFParseBase, "main", 1, NULL); + if (NULL == IIFFParse) + return FALSE; +#endif + + IconBase = OpenLibrary("icon.library", 0); + if (NULL == IconBase) + return FALSE; +#ifdef __amigaos4__ + IIcon = (struct IconIFace *)GetInterface((struct Library *)IconBase, "main", 1, NULL); + if (NULL == IIcon) + return FALSE; +#endif + + IconobjectBase = OpenLibrary("iconobject.library", 0); + if (NULL == IconobjectBase) + return FALSE; +#ifdef __amigaos4__ + IIconobject = (struct IconobjectIFace *)GetInterface((struct Library *)IconobjectBase, "main", 1, NULL); + if (NULL == IIconobject) + return FALSE; +#endif + + GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 39); + if (NULL == GfxBase) + return FALSE; +#ifdef __amigaos4__ + IGraphics = (struct GraphicsIFace *)GetInterface((struct Library *)GfxBase, "main", 1, NULL); + if (NULL == IGraphics) + return FALSE; +#endif + + WorkbenchBase = OpenLibrary("workbench.library", 39); + if (NULL == WorkbenchBase) + return FALSE; +#ifdef __amigaos4__ + IWorkbench = (struct WorkbenchIFace *)GetInterface((struct Library *)WorkbenchBase, "main", 1, NULL); + if (NULL == IWorkbench) + return FALSE; +#endif + + UtilityBase = (T_UTILITYBASE) OpenLibrary(UTILITYNAME, 39); + if (NULL == UtilityBase) + return FALSE; +#ifdef __amigaos4__ + IUtility = (struct UtilityIFace *)GetInterface((struct Library *)UtilityBase, "main", 1, NULL); + if (NULL == IUtility) + return FALSE; +#endif + + PreferencesBase = OpenLibrary("preferences.library", 39); + if (NULL == PreferencesBase) + return FALSE; +#ifdef __amigaos4__ + IPreferences = (struct PreferencesIFace *)GetInterface((struct Library *)PreferencesBase, "main", 1, NULL); + if (NULL == IPreferences) + return FALSE; +#endif + + DataTypesBase = OpenLibrary("datatypes.library", 39); + if (NULL == DataTypesBase) + return FALSE; +#ifdef __amigaos4__ + IDataTypes = (struct DataTypesIFace *)GetInterface((struct Library *)DataTypesBase, "main", 1, NULL); + if (NULL == IDataTypes) + return FALSE; +#endif + + // TTEngineBase is optional + TTEngineBase = OpenLibrary(TTENGINENAME, 6); +#ifdef __amigaos4__ + if (TTEngineBase) + ITTEngine = (struct TTEngineIFace *)GetInterface(TTEngineBase, "main", 1, NULL); +#endif + +#ifdef __amigaos4__ + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + return FALSE; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + return FALSE; +#endif + + LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 39); +#ifdef __amigaos4__ + if (LocaleBase) + ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL); +#endif + + return TRUE; +} + + +static void CloseLibraries(void) +{ +#ifdef __amigaos4__ + if (INewlib) + { + DropInterface(INewlib); + INewlib = NULL; + } + if (NewlibBase) + { + CloseLibrary(NewlibBase); + NewlibBase = NULL; + } + if (IDataTypes) + { + DropInterface((struct Interface *)IDataTypes); + IDataTypes = NULL; + } +#endif + if (DataTypesBase) + { + CloseLibrary(DataTypesBase); + DataTypesBase = NULL; + } +#ifdef __amigaos4__ + if (ILocale) + { + DropInterface((struct Interface *)ILocale); + ILocale = NULL; + } +#endif + if (LocaleBase) + { + CloseLibrary((struct Library *) LocaleBase); + LocaleBase = NULL; + } +#ifdef __amigaos4__ + if (ITTEngine) + { + DropInterface((struct Interface *)ITTEngine); + ITTEngine = NULL; + } +#endif + if (TTEngineBase) + { + CloseLibrary(TTEngineBase); + TTEngineBase = NULL; + } +#ifdef __amigaos4__ + if (IPreferences) + { + DropInterface((struct Interface *)IPreferences); + IPreferences = NULL; + } +#endif + if (PreferencesBase) + { + CloseLibrary(PreferencesBase); + PreferencesBase = NULL; + } +#ifdef __amigaos4__ + if (IIconobject) + { + DropInterface((struct Interface *)IIconobject); + IIconobject = NULL; + } +#endif + if (IconobjectBase) + { + CloseLibrary(IconobjectBase); + IconobjectBase = NULL; + } +#ifdef __amigaos4__ + if (IUtility) + { + DropInterface((struct Interface *)IUtility); + IUtility = NULL; + } +#endif + if (UtilityBase) + { + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } +#ifdef __amigaos4__ + if (IWorkbench) + { + DropInterface((struct Interface *)IWorkbench); + IWorkbench = NULL; + } +#endif + if (WorkbenchBase) + { + CloseLibrary(WorkbenchBase); + WorkbenchBase = NULL; + } +#ifdef __amigaos4__ + if (IGraphics) + { + DropInterface((struct Interface *)IGraphics); + IGraphics = NULL; + } +#endif + if (GfxBase) + { + CloseLibrary((struct Library *) GfxBase); + GfxBase = NULL; + } +#ifdef __amigaos4__ + if (IIcon) + { + DropInterface((struct Interface *)IIcon); + IIcon = NULL; + } +#endif + if (IconBase) + { + CloseLibrary(IconBase); + IconBase = NULL; + } +#ifdef __amigaos4__ + if (IIFFParse) + { + DropInterface((struct Interface *)IIFFParse); + IIFFParse = NULL; + } +#endif + if (IFFParseBase) + { + CloseLibrary(IFFParseBase); + IFFParseBase = NULL; + } +#ifdef __amigaos4__ + if (IMUIMaster) + { + DropInterface((struct Interface *)IMUIMaster); + IMUIMaster = NULL; + } +#endif + if (MUIMasterBase) + { + CloseLibrary(MUIMasterBase); + MUIMasterBase = NULL; + } +#ifdef __amigaos4__ + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } +#endif + if (IntuitionBase) + { + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } +#ifdef __amigaos4__ + if (IDiskfont) + { + DropInterface((struct Interface *)IDiskfont); + IDiskfont = NULL; + } +#endif + if (DiskfontBase) + { + CloseLibrary(DiskfontBase); + DiskfontBase = NULL; + } +#ifdef __amigaos4__ + if (IDOS) + { + DropInterface((struct Interface *)IDOS); + IDOS = NULL; + } +#endif + if (DOSBase) + { + CloseLibrary((struct Library *) DOSBase); + DOSBase = NULL; + } +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT TreeConstructFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_ConstructMessage *ltcm) +{ + struct FileTypesListEntry *fte = AllocPooled(ltcm->MemPool, sizeof(struct FileTypesListEntry)); + + d1(kprintf(__FILE__ "/%s/%ld: obj=%08lx ltcm=%08lx memPool=%08lx UserData=%08lx\n", \ + __FUNC__, __LINE__, obj, ltcm, ltcm->MemPool, ltcm->UserData)); + d1(kprintf(__FILE__ "/%s/%ld: fte=%08lx\n", __FUNC__, __LINE__, fte)); + + if (fte) + { + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + char UnSelIconName[MAX_ATTRVALUE]; + + NewList(&fte->ftle_AttributesList); + fte->ftle_FileFound = FALSE; + fte->ftle_Changed = FALSE; + + GetAttributeValueString(FindAttribute(fte, ATTRTYPE_UnselIconName), UnSelIconName, sizeof(UnSelIconName)); + if (strlen(UnSelIconName) > 0) + { + fte->fte_ImageObject = DataTypesImageObject, 0, + MUIA_ScaDtpic_Name, (ULONG) UnSelIconName, + MUIA_ScaDtpic_FailIfUnavailable, TRUE, + End; //DataTypesMCCObject + + if (fte->fte_ImageObject) + { + fte->fte_ImageIndex = ++inst->fpb_MenuImageIndex; + DoMethod(obj, MUIM_NList_UseImage, fte->fte_ImageObject, fte->fte_ImageIndex, 0); + } + else + { + fte->fte_ImageIndex = 0; + } + } + } + + return fte; +} + +static SAVEDS(void) INTERRUPT TreeDestructFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_DestructMessage *ltdm) +{ + struct FileTypesListEntry *fte = (struct FileTypesListEntry *) ltdm->UserData; + + d1(kprintf(__FILE__ "/%s/%ld: mle=%08lx\n", __FUNC__, __LINE__, ltdm->UserData)); + + if (fte) + { + CleanupAttributes(&fte->ftle_AttributesList); + + if (fte->fte_ImageObject) + { + DoMethod(obj, MUIM_NList_UseImage, NULL, fte->fte_ImageIndex, 0); + + MUI_DisposeObject(fte->fte_ImageObject); + fte->fte_ImageObject = NULL; + } + } + + FreePooled(ltdm->MemPool, ltdm->UserData, sizeof(struct FileTypesListEntry)); + ltdm->UserData = NULL; +} + +static SAVEDS(ULONG) INTERRUPT TreeDisplayFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_DisplayMessage *ltdm) +{ + struct FileTypesListEntry *fte = (struct FileTypesListEntry *) ltdm->TreeNode->tn_User; + + d1(kprintf(__FILE__ "/%s/%ld: <%s> fte=%08lx\n", __FUNC__, __LINE__, ltdm->TreeNode->tn_Name, fte)); + + if (fte) + { + const struct FtAttribute *fta; + char Line[MAX_ATTRVALUE]; + + // indicate changed entries + if (fte->ftle_Changed) + ltdm->Preparse[0] = MUIX_PH; + else + ltdm->Preparse[0] = MUIX_PT; + + switch (fte->ftle_EntryType) + { + case ENTRYTYPE_ToolTip_Member: + fta = FindAttribute(fte, ATTRTYPE_MemberHideString); + if (fta) + { + GetAttributeValueString(fta, Line, sizeof(Line)); + snprintf(fte->ftle_NameBuffer, sizeof(fte->ftle_NameBuffer), + "%s" MUIX_I " %s %s" MUIX_N, + ltdm->TreeNode->tn_Name, GetAttributeName(fta->fta_Type), Line); + } + else + { + snprintf(fte->ftle_NameBuffer, sizeof(fte->ftle_NameBuffer), + "%s", ltdm->TreeNode->tn_Name); + } + + ltdm->Array[0] = fte->ftle_NameBuffer; + break; + + case ENTRYTYPE_ToolTip_String: + fta = FindAttribute(fte, ATTRTYPE_StringId); + if (NULL == fta) + fta = FindAttribute(fte, ATTRTYPE_StringText); + if (NULL == fta) + fta = FindAttribute(fte, ATTRTYPE_StringSrc); + + GetAttributeValueString(fta, Line, sizeof(Line)); + snprintf(fte->ftle_NameBuffer, sizeof(fte->ftle_NameBuffer), + "%s" MUIX_I " %s %.*s" MUIX_N, + ltdm->TreeNode->tn_Name, GetAttributeName(fta->fta_Type), MAX_FTE_NAME, Line); + ltdm->Array[0] = fte->ftle_NameBuffer; + break; + + case ENTRYTYPE_ToolTip_DtImage: + GetAttributeValueString(FindAttribute(fte, ATTRTYPE_DtImageName), Line, sizeof(Line)); + snprintf(fte->ftle_NameBuffer, sizeof(fte->ftle_NameBuffer), + "%s" MUIX_I " FILENAME %.*s" MUIX_N, + ltdm->TreeNode->tn_Name, MAX_FTE_NAME, Line); + ltdm->Array[0] = fte->ftle_NameBuffer; + break; + + case ENTRYTYPE_PopupMenu_InternalCmd: + case ENTRYTYPE_PopupMenu_WbCmd: + case ENTRYTYPE_PopupMenu_ARexxCmd: + case ENTRYTYPE_PopupMenu_CliCmd: + case ENTRYTYPE_PopupMenu_PluginCmd: + case ENTRYTYPE_PopupMenu_IconWindowCmd: + GetAttributeValueString(FindAttribute(fte, ATTRTYPE_CommandName), Line, sizeof(Line)); + snprintf(fte->ftle_NameBuffer, sizeof(fte->ftle_NameBuffer), + "%s" MUIX_I " NAME %.*s" MUIX_N, + ltdm->TreeNode->tn_Name, MAX_FTE_NAME, Line); + ltdm->Array[0] = fte->ftle_NameBuffer; + break; + + case ENTRYTYPE_PopupMenu_SubMenu: + GetAttributeValueString(FindAttribute(fte, ATTRTYPE_MenuItemName), Line, sizeof(Line)); + if (fte->fte_ImageObject) + { + snprintf(fte->ftle_NameBuffer, sizeof(fte->ftle_NameBuffer), + "\33o[%ld]" "%s" MUIX_I " NAME %.*s" MUIX_N, + (long) fte->fte_ImageIndex, ltdm->TreeNode->tn_Name, MAX_FTE_NAME, Line); + } + else + { + snprintf(fte->ftle_NameBuffer, sizeof(fte->ftle_NameBuffer), + "%s" MUIX_I " NAME %.*s" MUIX_N, + ltdm->TreeNode->tn_Name, MAX_FTE_NAME, Line); + } + ltdm->Array[0] = fte->ftle_NameBuffer; + break; + + case ENTRYTYPE_ToolTip_Group: + GetAttributeValueString(FindAttribute(fte, ATTRTYPE_GroupOrientation), Line, sizeof(Line)); + snprintf(fte->ftle_NameBuffer, sizeof(fte->ftle_NameBuffer), + "%s" MUIX_I " ORIENTATION %.*s" MUIX_N, + ltdm->TreeNode->tn_Name, MAX_FTE_NAME, Line); + ltdm->Array[0] = fte->ftle_NameBuffer; + break; + + case ENTRYTYPE_PopupMenu_MenuItem: + GetAttributeValueString(FindAttribute(fte, ATTRTYPE_MenuItemName), Line, sizeof(Line)); + + if (FindAttribute(fte, ATTRTYPE_MenuDefaultAction)) + { + if (fte->fte_ImageObject) + { + snprintf(fte->ftle_NameBuffer, sizeof(fte->ftle_NameBuffer), + "\33o[%ld]" MUIX_B "%s" MUIX_I " NAME %.*s" MUIX_N, + fte->fte_ImageIndex, ltdm->TreeNode->tn_Name, MAX_FTE_NAME, Line); + } + else + { + snprintf(fte->ftle_NameBuffer, sizeof(fte->ftle_NameBuffer), + MUIX_B "%s" MUIX_I " NAME %.*s" MUIX_N, + ltdm->TreeNode->tn_Name, MAX_FTE_NAME, Line); + } + } + else + { + if (fte->fte_ImageObject) + { + snprintf(fte->ftle_NameBuffer, sizeof(fte->ftle_NameBuffer), + "\33o[%ld]%s" MUIX_I " NAME %.*s" MUIX_N, + fte->fte_ImageIndex, ltdm->TreeNode->tn_Name, MAX_FTE_NAME, Line); + } + else + { + snprintf(fte->ftle_NameBuffer, sizeof(fte->ftle_NameBuffer), + "%s" MUIX_I " NAME %.*s" MUIX_N, + ltdm->TreeNode->tn_Name, MAX_FTE_NAME, Line); + } + } + ltdm->Array[0] = fte->ftle_NameBuffer; + break; + + default: + ltdm->Array[0] = ltdm->TreeNode->tn_Name; + break; + } + } + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT AttrConstructFunc(struct Hook *hook, APTR obj, struct NList_ConstructMessage *ltcm) +{ + const struct FtAttribute *fta = (const struct FtAttribute *) ltcm->entry; + struct AttrListEntry *ale = (struct AttrListEntry *) AllocPooled(ltcm->pool, sizeof(struct AttrListEntry) + fta->fta_Length); + + d1(kprintf(__FILE__ "/%s/%ld: obj=%08lx ltcm=%08lx memPool=%08lx UserData=%08lx\n", \ + __FUNC__, __LINE__, obj, ltcm, ltcm->MemPool, ltcm->entry)); + d1(kprintf(__FILE__ "/%s/%ld: fta=%08lx\n", __FUNC__, __LINE__, ale)); + + if (ale) + { + memcpy(&ale->ale_Attribute, fta, sizeof(struct FtAttribute) + fta->fta_Length); + } + + return ale; +} + +static SAVEDS(void) INTERRUPT AttrDestructFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm) +{ + struct AttrListEntry *ale = (struct AttrListEntry *) ltdm->entry; + + d1(kprintf(__FILE__ "/%s/%ld: START fta=%08lx\n", __FUNC__, __LINE__, ale)); + + if (ale) + { + FreePooled(ltdm->pool, ale, sizeof(struct AttrListEntry) + ale->ale_Attribute.fta_Length); + ltdm->entry = NULL; + } + + d1(kprintf(__FILE__ "/%s/%ld: END fta=%08lx\n", __FUNC__, __LINE__, ale)); +} + +static SAVEDS(ULONG) INTERRUPT AttrDisplayFunc(struct Hook *hook, APTR obj, struct NList_DisplayMessage *ltdm) +{ + struct AttrListEntry *ale = (struct AttrListEntry *) ltdm->entry; + + d1(kprintf(__FILE__ "/%s/%ld: <%s> fta=%08lx\n", __FUNC__, __LINE__, ltdm->TreeNode->tn_Name, fta)); + + if (ale) + { + ltdm->preparses[0] = ""; + ltdm->preparses[1] = ""; + + ltdm->strings[0] = (STRPTR) GetAttributeName(ale->ale_Attribute.fta_Type); + ltdm->strings[1] = (STRPTR) GetAttributeValueString(&ale->ale_Attribute, + ale->ale_ValueString, sizeof(ale->ale_ValueString)); + } + else + { + // display titles + ltdm->preparses[0] = "\033c"; + ltdm->preparses[1] = "\033c"; + + ltdm->strings[0] = GetLocString(MSGID_ATTRCOLUMNTITLE_NAME); + ltdm->strings[1] = GetLocString(MSGID_ATTRCOLUMNTITLE_VALUE); + } + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT AddEntryConstructFunc(struct Hook *hook, APTR obj, struct NList_ConstructMessage *ltcm) +{ + struct AddEntryListEntry *ael = (struct AddEntryListEntry *) AllocPooled(ltcm->pool, sizeof(struct AddEntryListEntry)); + + d1(kprintf(__FILE__ "/%s/%ld: obj=%08lx ltcm=%08lx memPool=%08lx UserData=%08lx\n", \ + __FUNC__, __LINE__, obj, ltcm, ltcm->pool, ltcm->entry)); + d1(kprintf(__FILE__ "/%s/%ld: ael=%08lx\n", __FUNC__, __LINE__, ael)); + + if (ael) + { + ael->ael_EntryType = (enum FtEntryType) ltcm->entry; + d1(kprintf(__FILE__ "/%s/%ld: ael_EntryType=%lu\n", __FUNC__, __LINE__, ael->ael_EntryType)); + } + + return ael; +} + +static SAVEDS(void) INTERRUPT AddEntryDestructFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm) +{ + struct AddEntryListEntry *ael = (struct AddEntryListEntry *) ltdm->entry; + + d1(kprintf(__FILE__ "/%s/%ld: ael=%08lx\n", __FUNC__, __LINE__, ael)); + + if (ael) + { + FreePooled(ltdm->pool, ael, sizeof(struct AddEntryListEntry)); + ltdm->entry = NULL; + } +} + +static SAVEDS(ULONG) INTERRUPT AddEntryDisplayFunc(struct Hook *hook, APTR obj, struct NList_DisplayMessage *ltdm) +{ + struct AddEntryListEntry *ael = (struct AddEntryListEntry *) ltdm->entry; + + d1(kprintf(__FILE__ "/%s/%ld: ael=%08lx\n", __FUNC__, __LINE__, ael)); + + if (ael) + { + ltdm->preparses[0] = ""; + + ltdm->strings[0] = (STRPTR) GetNameFromEntryType(ael->ael_EntryType); + } + else + { + // display titles + ltdm->preparses[0] = ""; + + ltdm->strings[0] = ""; + } + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT AddAttrConstructFunc(struct Hook *hook, APTR obj, struct NList_ConstructMessage *ltcm) +{ + struct AddAttrListEntry *aal = (struct AddAttrListEntry *) AllocPooled(ltcm->pool, sizeof(struct AddAttrListEntry)); + + d1(kprintf(__FILE__ "/%s/%ld: obj=%08lx ltcm=%08lx memPool=%08lx UserData=%08lx\n", \ + __FUNC__, __LINE__, obj, ltcm, ltcm->pool, ltcm->entry)); + d1(kprintf(__FILE__ "/%s/%ld: aal=%08lx\n", __FUNC__, __LINE__, aal)); + + if (aal) + { + aal->aal_EntryType = (enum FtEntryType) ltcm->entry; + d1(kprintf(__FILE__ "/%s/%ld: aal_EntryType=%lu\n", __FUNC__, __LINE__, aal->aal_EntryType)); + } + + return aal; +} + +static SAVEDS(void) INTERRUPT AddAttrDestructFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm) +{ + struct AddAttrListEntry *aal = (struct AddAttrListEntry *) ltdm->entry; + + d1(kprintf(__FILE__ "/%s/%ld: aal=%08lx\n", __FUNC__, __LINE__, aal)); + + if (aal) + { + FreePooled(ltdm->pool, aal, sizeof(struct AddAttrListEntry)); + ltdm->entry = NULL; + } +} + +static SAVEDS(ULONG) INTERRUPT AddAttrDisplayFunc(struct Hook *hook, APTR obj, struct NList_DisplayMessage *ltdm) +{ + struct AddAttrListEntry *aal = (struct AddAttrListEntry *) ltdm->entry; + + d1(kprintf(__FILE__ "/%s/%ld: aal=%08lx\n", __FUNC__, __LINE__, aal)); + + if (aal) + { + ltdm->preparses[0] = ""; + + ltdm->strings[0] = (STRPTR) GetAttributeName(aal->aal_EntryType); + } + else + { + // display titles + ltdm->preparses[0] = ""; + + ltdm->strings[0] = ""; + } + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT EditAttrConstructFunc(struct Hook *hook, APTR obj, struct NList_ConstructMessage *ltcm) +{ + const struct EditAttrListEntry *newEntry = ltcm->entry; + struct EditAttrListEntry *eal = (struct EditAttrListEntry *) AllocPooled(ltcm->pool, sizeof(struct EditAttrListEntry) + newEntry->eal_fta.fta_Length); + + d1(kprintf(__FILE__ "/%s/%ld: obj=%08lx ltcm=%08lx memPool=%08lx UserData=%08lx\n", \ + __FUNC__, __LINE__, obj, ltcm, ltcm->pool, ltcm->entry)); + d1(kprintf(__FILE__ "/%s/%ld: eal=%08lx\n", __FUNC__, __LINE__, eal)); + + if (eal) + { + memcpy(eal, newEntry, sizeof(struct EditAttrListEntry) + newEntry->eal_fta.fta_Length); + } + + return eal; +} + +static SAVEDS(void) INTERRUPT EditAttrDestructFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm) +{ + struct EditAttrListEntry *eal = (struct EditAttrListEntry *) ltdm->entry; + + d1(kprintf(__FILE__ "/%s/%ld: START aal=%08lx\n", __FUNC__, __LINE__, eal)); + + if (eal) + { + FreePooled(ltdm->pool, eal, sizeof(struct EditAttrListEntry) + eal->eal_fta.fta_Length); + ltdm->entry = NULL; + } + + d1(kprintf(__FILE__ "/%s/%ld: END aal=%08lx\n", __FUNC__, __LINE__, eal)); +} + +static SAVEDS(ULONG) INTERRUPT EditAttrDisplayFunc(struct Hook *hook, APTR obj, struct NList_DisplayMessage *ltdm) +{ + struct EditAttrListEntry *eal = (struct EditAttrListEntry *) ltdm->entry; + + d1(kprintf(__FILE__ "/%s/%ld: eal=%08lx\n", __FUNC__, __LINE__, eal)); + + if (eal) + { + ltdm->preparses[0] = ""; + + GetAttributeValueString(&eal->eal_fta, eal->eal_ValueString, sizeof(eal->eal_ValueString)); + + if (eal->eal_fta.fta_Value2) + { + d1(KPrintF(__FILE__ "/%s/%ld: Type=%ld <%s>\n", __FUNC__, __LINE__, \ + eal->eal_fta.fta_Type, eal->eal_ValueString)); + + ltdm->strings[0] = GetLocString(eal->eal_fta.fta_Value2); + ltdm->strings[1] = eal->eal_ValueString; + } + else + { + d1(KPrintF(__FILE__ "/%s/%ld: Type=%ld <%s>\n", __FUNC__, __LINE__, \ + eal->eal_fta.fta_Type, eal->eal_ValueString)); + + ltdm->strings[0] = eal->eal_ValueString; + } + } + else + { + // display titles + ltdm->preparses[0] = ""; + ltdm->strings[0] = ""; + + if (eal->eal_fta.fta_Value2) + { + ltdm->preparses[1] = ""; + ltdm->strings[1] = ""; + } + } + + return 0; +} + +//---------------------------------------------------------------------------- + +STRPTR GetLocString(ULONG MsgId) +{ + struct ScalosFileTypes_LocaleInfo li; + + li.li_Catalog = FileTypesPrefsCatalog; +#ifndef __amigaos4__ + li.li_LocaleBase = LocaleBase; +#else + li.li_ILocale = ILocale; +#endif + + return (STRPTR) GetScalosFileTypesString(&li, MsgId); +} + + +static void TranslateNewMenu(struct NewMenu *nm) +{ + while (nm && NM_END != nm->nm_Type) + { + if (NM_BARLABEL != nm->nm_Label) + nm->nm_Label = GetLocString((ULONG) nm->nm_Label); + + if (nm->nm_CommKey) + nm->nm_CommKey = GetLocString((ULONG) nm->nm_CommKey); + + nm++; + } +} + +static void TranslateStringArray(STRPTR *stringArray) +{ + while (*stringArray) + { + *stringArray = GetLocString((ULONG) *stringArray); + stringArray++; + } +} + +//---------------------------------------------------------------------------- + +void _XCEXIT(long x) +{ +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT AboutFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + + MUI_Request(inst->fpb_Objects[OBJNDX_APP_Main], inst->fpb_Objects[OBJNDX_WIN_Main], 0, NULL, + GetLocString(MSGID_ABOUTREQOK), + GetLocString(MSGID_ABOUTREQFORMAT), + MajorVersion, MinorVersion, COMPILER_STRING, CURRENTYEAR); + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT ResetToDefaultsHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + + set(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, TRUE); + + DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], MUIM_NListtree_Clear, NULL, 0); + set(inst->fpb_Objects[OBJNDX_MainListView], MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + + inst->fpb_SaveFlags = FTWRITEFLAG_CLEAR_CHANGE_FLAG; + + InitDefIcons(inst, NULL); + + set(inst->fpb_Objects[OBJNDX_MainListView], MUIA_NList_Quiet, MUIV_NList_Quiet_None); + set(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, FALSE); + + return 0; +} + + +static SAVEDS(APTR) INTERRUPT LastSavedHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + set(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, TRUE); + + ReadPrefs(inst, ENVARC_FILETYPES_DIR, ENVARC_DEFICONS_PREFS); + + set(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, FALSE); + inst->fpb_SaveFlags = FTWRITEFLAG_CLEAR_CHANGE_FLAG; + + return 0; +} + +static SAVEDS(APTR) INTERRUPT RestoreHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + + set(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, TRUE); + + ReadPrefs(inst, ENV_FILETYPES_DIR, ENV_DEFICONS_PREFS); + + set(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, FALSE); + inst->fpb_SaveFlags = FTWRITEFLAG_CLEAR_CHANGE_FLAG; + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT HideEmptyEntriesHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + ULONG Checked = FALSE; + + get(inst->fpb_Objects[OBJNDX_Menu_HideEmptyEntries], MUIA_Menuitem_Checked, &Checked); + inst->fpb_HideEmptyNodes = Checked; + + set(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, TRUE); + set(inst->fpb_Objects[OBJNDX_MainListView], MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + + if (inst->fpb_HideEmptyNodes) + HideEmptyNodes(inst); + else + ShowHiddenNodes(inst); + + set(inst->fpb_Objects[OBJNDX_MainListView], MUIA_NList_Quiet, MUIV_NList_Quiet_None); + set(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, FALSE); + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT CollapseHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct MUI_NListtree_TreeNode *tn; + + set(inst->fpb_Objects[OBJNDX_MainListTree], MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, + 0); + d1(kprintf("%s/%ld: active tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) "")); + + if (tn) + { + struct MUI_NListtree_TreeNode *tnChild; + + tnChild = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + tn, + MUIV_NListtree_GetEntry_Position_Head, + 0); + d1(kprintf("%s/%ld: Head tn=%08lx <%s>\n", __FUNC__, __LINE__, tnChild, tnChild ? tnChild->tn_Name : (STRPTR) "")); + + if (tnChild) + { + set(inst->fpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Active, (ULONG) tnChild); + + DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Close, + MUIV_NListtree_Close_ListNode_Active, + MUIV_NListtree_Close_TreeNode_All, + 0); + } + + set(inst->fpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Active, (ULONG) tn); + } + + DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Close, + MUIV_NListtree_Close_ListNode_Active, + tn, + 0); + + set(inst->fpb_Objects[OBJNDX_MainListTree], MUIA_NList_Quiet, MUIV_NList_Quiet_None); + + return NULL; +} + +static SAVEDS(APTR) INTERRUPT ExpandHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct MUI_NListtree_TreeNode *tn; + + set(inst->fpb_Objects[OBJNDX_MainListTree], MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, + 0); + d1(kprintf("%s/%ld: active tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) "")); + + DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Open, + MUIV_NListtree_Open_ListNode_Active, + MUIV_NListtree_Open_TreeNode_Active, + 0); + + if (tn) + { + struct MUI_NListtree_TreeNode *tnChild; + + tnChild = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + tn, + MUIV_NListtree_GetEntry_Position_Head, + 0); + d1(kprintf("%s/%ld: Head tn=%08lx <%s>\n", __FUNC__, __LINE__, tnChild, tnChild ? tnChild->tn_Name : (STRPTR) "")); + + if (tnChild) + { + set(inst->fpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Active, (ULONG) tnChild); + + DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Open, + MUIV_NListtree_Open_ListNode_Active, + MUIV_NListtree_Open_TreeNode_All, + 0); + } + + set(inst->fpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Active, (ULONG) tn); + } + + set(inst->fpb_Objects[OBJNDX_MainListTree], MUIA_NList_Quiet, MUIV_NList_Quiet_None); + + return NULL; +} + +static SAVEDS(APTR) INTERRUPT CollapseAllHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + + DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], MUIM_NListtree_Close, + MUIV_NListtree_Close_ListNode_Root, + MUIV_NListtree_Close_TreeNode_All, + 0); + + return NULL; +} + +static SAVEDS(APTR) INTERRUPT ExpandAllHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + + DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], MUIM_NListtree_Open, + MUIV_NListtree_Open_ListNode_Root, + MUIV_NListtree_Open_TreeNode_All, + 0); + + return NULL; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT CollapseFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + + DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], + MUIM_NListtree_Close, + MUIV_NListtree_Close_ListNode_Active, + MUIV_NListtree_Close_TreeNode_All, + 0); + + return NULL; +} + +static SAVEDS(APTR) INTERRUPT ExpandFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct MUI_NListtree_TreeNode *tn; + + set(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, + 0); + d1(kprintf("%s/%ld: active tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) "")); + + DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], + MUIM_NListtree_Open, + MUIV_NListtree_Open_ListNode_Active, + MUIV_NListtree_Open_TreeNode_Active, + 0); + + if (tn) + { + struct MUI_NListtree_TreeNode *tnChild; + + tnChild = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], + MUIM_NListtree_GetEntry, + tn, + MUIV_NListtree_GetEntry_Position_Head, + 0); + d1(kprintf("%s/%ld: Head tn=%08lx <%s>\n", __FUNC__, __LINE__, tnChild, tnChild ? tnChild->tn_Name : (STRPTR) "")); + + if (tnChild) + { + set(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], MUIA_NListtree_Active, (ULONG) tnChild); + + DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], + MUIM_NListtree_Open, + MUIV_NListtree_Open_ListNode_Active, + MUIV_NListtree_Open_TreeNode_All, + 0); + } + + set(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], MUIA_NListtree_Active, (ULONG) tn); + } + + set(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], MUIA_NList_Quiet, MUIV_NList_Quiet_None); + + return NULL; +} + +static SAVEDS(APTR) INTERRUPT CollapseAllFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + + DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], MUIM_NListtree_Close, + MUIV_NListtree_Close_ListNode_Root, + MUIV_NListtree_Close_TreeNode_All, + 0); + + return NULL; +} + +static SAVEDS(APTR) INTERRUPT ExpandAllFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + + DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], MUIM_NListtree_Open, + MUIV_NListtree_Open_ListNode_Root, + MUIV_NListtree_Open_TreeNode_All, + 0); + + return NULL; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT CopyHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct MUI_NListtree_TreeNode *tn; + + DoMethod(inst->fpb_Objects[OBJNDX_ShadowListTree], MUIM_NListtree_Clear); + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, + 0); + d1(kprintf("%s/%ld: active tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) "")); + + if (tn) + { + CopyFileTypesEntry(inst, + (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_ListNode_Root, + (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_PrevNode_Tail, + tn, + OBJNDX_ShadowListTree, OBJNDX_MainListTree); + } + + EnablePasteMenuEntry(inst); + + return NULL; +} + +static SAVEDS(APTR) INTERRUPT CutHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct MUI_NListtree_TreeNode *tn; + + DoMethod(inst->fpb_Objects[OBJNDX_ShadowListTree], MUIM_NListtree_Clear); + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, + 0); + d1(kprintf("%s/%ld: active tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) "")); + + if (tn) + { + CopyFileTypesEntry(inst, + (struct MUI_NListtree_TreeNode *) MUIV_NListtree_GetEntry_ListNode_Root, + (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_PrevNode_Tail, + tn, + OBJNDX_ShadowListTree, OBJNDX_MainListTree); + + EntryHasChanged(inst, tn); + + DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Remove, + MUIV_NListtree_Remove_ListNode_Active, + MUIV_NListtree_Remove_TreeNode_Active, + 0); + } + + EnablePasteMenuEntry(inst); + + return NULL; +} + +static SAVEDS(APTR) INTERRUPT PasteHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct MUI_NListtree_TreeNode *tn; + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, + 0); + d1(kprintf("%s/%ld: active tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) "")); + + if (tn) + { + struct MUI_NListtree_TreeNode *tnParent; + struct MUI_NListtree_TreeNode *tnShadow; + + tnParent = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + tn, + MUIV_NListtree_GetEntry_Position_Parent, + 0); + + tnShadow = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_ShadowListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_Insert_ListNode_Root, + MUIV_NListtree_GetEntry_Position_Head, + 0); + + set(inst->fpb_Objects[OBJNDX_MainListTree], MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + + if (MayPasteBelow(inst, tn, tnShadow)) + { + CopyFileTypesEntry(inst, + tnParent, tn, + tnShadow, + OBJNDX_MainListTree, OBJNDX_ShadowListTree); + + EntryHasChanged(inst, tnParent); + } + else if (MayPasteOnto(inst, tn, tnShadow)) + { + CopyFileTypesEntry(inst, + tn, (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_PrevNode_Tail, + tnShadow, + OBJNDX_MainListTree, OBJNDX_ShadowListTree); + + EntryHasChanged(inst, tn); + } + + set(inst->fpb_Objects[OBJNDX_MainListTree], MUIA_NList_Quiet, MUIV_NList_Quiet_None); + + DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Redraw, + tn, + 0); + } + + return NULL; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT CopyAttrHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + + struct MUI_NListtree_TreeNode *tn; + struct AttrListEntry *Attr = NULL; + + DoMethod(inst->fpb_Objects[OBJNDX_ShadowAttrList], MUIM_NList_Clear); + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, + 0); + + d1(kprintf("%s/%ld: active tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) "")); + + if (tn) + { + DoMethod(inst->fpb_Objects[OBJNDX_AttrList], + MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, + &Attr); + + d1(kprintf("%s/%ld: Attr=%08lx\n", __FUNC__, __LINE__, Attr)); + } + if (Attr) + { + d1(kprintf("%s/%ld: Attr=%08lx\n", __FUNC__, __LINE__, Attr)); + + DoMethod(inst->fpb_Objects[OBJNDX_ShadowAttrList], + MUIM_NList_InsertSingle, + &Attr->ale_Attribute, + MUIV_NList_Insert_Bottom); + } + + EnablePasteAttrMenuEntry(inst); + + return NULL; +} + +static SAVEDS(APTR) INTERRUPT CutAttrHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct MUI_NListtree_TreeNode *tn; + struct AttrListEntry *Attr = NULL; + + DoMethod(inst->fpb_Objects[OBJNDX_ShadowAttrList], MUIM_NList_Clear); + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, + 0); + d1(kprintf("%s/%ld: active tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) "")); + + if (tn) + { + DoMethod(inst->fpb_Objects[OBJNDX_AttrList], + MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, + &Attr); + } + if (Attr) + { + struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User; + + DoMethod(inst->fpb_Objects[OBJNDX_ShadowAttrList], + MUIM_NList_InsertSingle, + &Attr->ale_Attribute, + MUIV_NList_Insert_Bottom); + + // Remove attribute from fte's list + RemoveAttribute(fte, Attr->ale_Attribute.fta_Type); + + DoMethod(inst->fpb_Objects[OBJNDX_AttrList], + MUIM_NList_Remove, + MUIV_NList_Remove_Active); + + EntryHasChanged(inst, tn); + } + + EnablePasteAttrMenuEntry(inst); + + return NULL; +} + +static SAVEDS(APTR) INTERRUPT PasteAttrHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct MUI_NListtree_TreeNode *tn; + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, + 0); + d1(kprintf("%s/%ld: active tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) "")); + + if (tn) + { + struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User; + struct AttrListEntry *Attr = NULL; + + DoMethod(inst->fpb_Objects[OBJNDX_ShadowAttrList], + MUIM_NList_GetEntry, + 0, + &Attr); + + if (Attr) + { + set(inst->fpb_Objects[OBJNDX_AttrList], MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + + if (MayPasteAttr(inst, fte, Attr)) + { + struct FtAttribute *ftaNew; + + ftaNew = AddAttribute(fte, Attr->ale_Attribute.fta_Type, + Attr->ale_Attribute.fta_Length, Attr->ale_Attribute.fta_Data); + + if (ftaNew) + { + DoMethod(inst->fpb_Objects[OBJNDX_AttrList], MUIM_NList_InsertSingle, + ftaNew, MUIV_NList_Insert_Bottom); + } + + UpdateMenuImage(inst, OBJNDX_MainListTree, fte); + EntryHasChanged(inst, tn); + } + + set(inst->fpb_Objects[OBJNDX_AttrList], MUIA_NList_Quiet, MUIV_NList_Quiet_None); + EnablePasteAttrMenuEntry(inst); + } + } + + return NULL; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT AddEntryHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct AddEntryListEntry *ael = NULL; + + DoMethod(inst->fpb_Objects[OBJNDX_AddEntryList], + MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, + &ael); + + d1(kprintf("%s/%ld: inst=%08lx ael=%08lx\n", __FUNC__, __LINE__, inst, ael)); + + DoMethod(inst->fpb_Objects[OBJNDX_AddEntryPopObject], MUIM_Popstring_Close, TRUE); + + if (ael) + { + struct MUI_NListtree_TreeNode *tn; + + d1(kprintf("%s/%ld: EntryType=%lu\n", __FUNC__, __LINE__, ael->ael_EntryType)); + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, + 0); + + if (tn) + { + struct FileTypesListEntry *fte; + struct MUI_NListtree_TreeNode *tnNew; + + d1(kprintf("%s/%ld: active tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) "")); + + set(inst->fpb_Objects[OBJNDX_MainListView], MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + + tnNew = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, + GetNameFromEntryType(ael->ael_EntryType), NULL, + tn, + MUIV_NListtree_Insert_PrevNode_Tail, + TNF_LIST | TNF_OPEN); + + fte = (struct FileTypesListEntry *) tnNew->tn_User; + fte->ftle_EntryType = ael->ael_EntryType; + + AddDefaultAttributes(inst, fte); + + set(inst->fpb_Objects[OBJNDX_MainListView], MUIA_NList_Quiet, MUIV_NList_Quiet_None); + + DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Redraw, + tn, + 0); + + UpdateAttributes(inst, (struct FileTypesListEntry *) tn->tn_User); + + // Make sure the new entry is the active one + set(inst->fpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Active, (ULONG) tnNew); + + EntryHasChanged(inst, tnNew); + } + } + + return NULL; +} + + +static SAVEDS(APTR) INTERRUPT AddAttributeHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct MUI_NListtree_TreeNode *tn; + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, + 0); + + d1(kprintf("%s/%ld: inst=%08lx tn=%08lx\n", __FUNC__, __LINE__, inst, tn)); + + if (tn) + { + struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User; + struct AddAttrListEntry *aal = NULL; + + DoMethod(inst->fpb_Objects[OBJNDX_AddAttrList], + MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, + &aal); + + d1(kprintf("%s/%ld: inst=%08lx aal=%08lx\n", __FUNC__, __LINE__, inst, aal)); + + if (aal) + { + const struct AttributeDef *atd; + ULONG n; + + atd = GetAttributeDef(aal->aal_EntryType, fte->ftle_EntryType); + + // remove all attributes which are excluded by the new one + for (n = 0; atd && n < atd->atd_ExcludeCount; n++) + { + const struct FtAttribute *fta; + + fta = FindAttribute(fte, atd->atd_Exclude[n]); + + if (fta) + { + ULONG Entries = 0; + ULONG pos; + + // Remove attribute from fte's list + RemoveAttribute(fte, fta->fta_Type); + + get(inst->fpb_Objects[OBJNDX_AttrList], MUIA_NList_Entries, &Entries); + + // Remove Attribute from Attribute List + for (pos = 0; pos < Entries; pos++) + { + struct AttrListEntry *Attr = NULL; + + DoMethod(inst->fpb_Objects[OBJNDX_AttrList], + MUIM_NList_GetEntry, + pos, + &Attr); + if (Attr && Attr->ale_Attribute.fta_Type == atd->atd_Exclude[n]) + { + DoMethod(inst->fpb_Objects[OBJNDX_AttrList], + MUIM_NList_Remove, + pos); + } + } + } + } + + AddNewAttribute(inst, fte, aal->aal_EntryType); + SetAddableAttributes(inst, fte); + + UpdateMenuImage(inst, OBJNDX_MainListTree, fte); + + DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Redraw, + tn, + 0); + + if (ATTRTYPE_MenuDefaultAction == aal->aal_EntryType) + BeginSetMenuDefaultAction(inst, tn); + + EntryHasChanged(inst, tn); + } + } + + DoMethod(inst->fpb_Objects[OBJNDX_AddAttrPopObject], MUIM_Popstring_Close, TRUE); + + return NULL; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT RemoveEntryHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct MUI_NListtree_TreeNode *tn; + + d1(kprintf("%s/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst)); + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, + 0); + + if (tn) + { + EntryHasChanged(inst, tn); + + DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Remove, + MUIV_NListtree_Remove_ListNode_Active, + MUIV_NListtree_Remove_TreeNode_Active, + 0); + } + + return NULL; +} + +static SAVEDS(APTR) INTERRUPT RemoveAttributeHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct MUI_NListtree_TreeNode *tn; + struct AttrListEntry *Attr = NULL; + + d1(kprintf("%s/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst)); + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, + 0); + + d1(kprintf("%s/%ld: inst=%08lx tn=%08lx\n", __FUNC__, __LINE__, inst, tn)); + + if (tn) + { + DoMethod(inst->fpb_Objects[OBJNDX_AttrList], + MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, + &Attr); + } + + d1(kprintf("%s/%ld: active Attr=%08lx\n", __FUNC__, __LINE__, Attr)); + if (Attr) + { + struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User; + + // Remove attribute from fte's list + RemoveAttribute(fte, Attr->ale_Attribute.fta_Type); + + DoMethod(inst->fpb_Objects[OBJNDX_AttrList], + MUIM_NList_Remove, + MUIV_NList_Remove_Active); + + UpdateMenuImage(inst, OBJNDX_MainListTree, fte); + + DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Redraw, + tn, + 0); + + EntryHasChanged(inst, tn); + + set(inst->fpb_Objects[OBJNDX_ButtonRemoveAttribute], MUIA_Disabled, TRUE); + set(inst->fpb_Objects[OBJNDX_ButtonEditAttribute], MUIA_Disabled, TRUE); + set(inst->fpb_Objects[OBJNDX_Menu_CopyAttr], MUIA_Menuitem_Enabled, FALSE); + set(inst->fpb_Objects[OBJNDX_Menu_CutAttr], MUIA_Menuitem_Enabled, FALSE); + + EnablePasteAttrMenuEntry(inst); + } + + return NULL; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT ChangeAttributeHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct MUI_NListtree_TreeNode *tn; + struct AttrListEntry *Attr = NULL; + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, + 0); + d1(kprintf("%s/%ld: active tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) "")); + + if (tn) + { + DoMethod(inst->fpb_Objects[OBJNDX_AttrList], + MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, + &Attr); + } + + d1(kprintf("%s/%ld: active Attr=%08lx\n", __FUNC__, __LINE__, Attr)); + if (Attr) + { + struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User; + const struct AttributeDef *atd; + + d1(kprintf("%s/%ld: active fte=%08lx\n", __FUNC__, __LINE__, fte)); + + atd = GetAttributeDef(Attr->ale_Attribute.fta_Type, fte->ftle_EntryType); + d1(kprintf("%s/%ld: atd=%08lx\n", __FUNC__, __LINE__, atd)); + if (atd) + { + CONST_STRPTR ValueString = ""; + ULONG ValueULong = 0; + + switch (atd->atd_DefaultContents.avd_Type) + { + case ATTRDEFTYPE_ULong: + if (atd->atd_NumberOfValues > 0) + { + get(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectValue], + MUIA_String_Contents, &ValueString); + } + else + { + get(inst->fpb_Objects[OBJNDX_String_AttributeValue], + MUIA_String_Contents, &ValueString); + } + + if (atd->atd_DefaultContents.avd_ConvertValueFromString) + ValueULong = (atd->atd_DefaultContents.avd_ConvertValueFromString)(ValueString); + else + { + unsigned long ulong1; + sscanf(ValueString, "%lu", &ulong1); + ValueULong = ulong1; + } + // Remove attribute from fte's list + RemoveAttribute(fte, atd->atd_Type); + AddAttribute(fte, atd->atd_Type, sizeof(ValueULong), &ValueULong); + break; + + case ATTRDEFTYPE_FileName: + get(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectAslFile], + MUIA_String_Contents, &ValueString); + + // Remove attribute from fte's list + RemoveAttribute(fte, atd->atd_Type); + AddAttribute(fte, atd->atd_Type, 1 + strlen(ValueString), ValueString); + break; + + case ATTRDEFTYPE_PathName: + get(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectAslPath], + MUIA_String_Contents, &ValueString); + + // Remove attribute from fte's list + RemoveAttribute(fte, atd->atd_Type); + AddAttribute(fte, atd->atd_Type, 1 + strlen(ValueString), ValueString); + break; + + case ATTRDEFTYPE_FontString: + get(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectAslFont], + MUIA_String_Contents, &ValueString); + + // Remove attribute from fte's list + RemoveAttribute(fte, atd->atd_Type); + AddAttribute(fte, atd->atd_Type, 1 + strlen(ValueString), ValueString); + break; + + case ATTRDEFTYPE_TTFontString: + get(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectTTFont], + MUIA_String_Contents, &ValueString); + + // Remove attribute from fte's list + RemoveAttribute(fte, atd->atd_Type); + AddAttribute(fte, atd->atd_Type, 1 + strlen(ValueString), ValueString); + break; + + case ATTRDEFTYPE_LocString: + case ATTRDEFTYPE_String: + case ATTRDEFTYPE_String2: + if (atd->atd_NumberOfValues > 0) + { + get(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectValue], + MUIA_String_Contents, &ValueString); + } + else + { + get(inst->fpb_Objects[OBJNDX_String_AttributeValue], + MUIA_String_Contents, &ValueString); + } + // Remove attribute from fte's list + RemoveAttribute(fte, atd->atd_Type); + AddAttribute(fte, atd->atd_Type, 1 + strlen(ValueString), ValueString); + break; + default: + break; + } + + d1(kprintf("%s/%ld:\n", __FUNC__, __LINE__)); + + UpdateAttributes(inst, fte); + UpdateMenuImage(inst, OBJNDX_MainListTree, fte); + + DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Redraw, + tn, + 0); + + EntryHasChanged(inst, tn); + } + } + + // Close "Edit Attribute" window + set(inst->fpb_Objects[OBJNDX_WIN_EditAttribute], MUIA_Window_Open, FALSE); + + return NULL; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT SelectAttributeValueHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct EditAttrListEntry *eal = NULL; + + DoMethod(inst->fpb_Objects[OBJNDX_List_AttributeSelectValue], + MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, + &eal); + + if (eal) + { + set(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectValue], + MUIA_String_Contents, (ULONG) eal->eal_ValueString); + } + + d1(kprintf("%s/%ld: eal=%08lx\n", __FUNC__, __LINE__, eal)); + + DoMethod(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectValue], MUIM_Popstring_Close, TRUE); + + return NULL; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(ULONG) INTERRUPT EditAttributePopAslFileStartHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct TagItem *TagList = (struct TagItem *) msg; + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + CONST_STRPTR ValueString; + STRPTR lp; + + d1(KPrintF("%s/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst)); + + get(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectAslFile], MUIA_String_Contents, &ValueString); + + d1(KPrintF("%s/%ld: ValueString=<%s>\n", __FUNC__, __LINE__, ValueString)); + + while (TAG_END != TagList->ti_Tag) + TagList++; + + stccpy(inst->fpb_FileName, FilePart(ValueString), sizeof(inst->fpb_FileName)); + stccpy(inst->fpb_Path, ValueString, sizeof(inst->fpb_Path)); + + lp = PathPart(inst->fpb_Path); + *lp = '\0'; + + TagList->ti_Tag = ASLFR_DrawersOnly; + TagList->ti_Data = FALSE; + TagList++; + + TagList->ti_Tag = ASLFR_InitialFile; + TagList->ti_Data = (ULONG) inst->fpb_FileName; + TagList++; + + TagList->ti_Tag = ASLFR_InitialDrawer; + TagList->ti_Data = (ULONG) inst->fpb_Path; + TagList++; + + TagList->ti_Tag = TAG_END; + + d1(KPrintF("%s/%ld: ASLFR_InitialFile=<%s> ASLFR_InitialDrawer=<%s>\n", __FUNC__, __LINE__, inst->fpb_FileName, inst->fpb_Path)); + + return TRUE; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(ULONG) INTERRUPT EditAttributePopAslPathStartHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct TagItem *TagList = (struct TagItem *) msg; + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + CONST_STRPTR ValueString; + STRPTR lp; + + d1(kprintf("%s/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst)); + + get(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectAslPath], MUIA_String_Contents, &ValueString); + + while (TAG_END != TagList->ti_Tag) + TagList++; + + stccpy(inst->fpb_FileName, FilePart(ValueString), sizeof(inst->fpb_FileName)); + stccpy(inst->fpb_Path, ValueString, sizeof(inst->fpb_Path)); + + lp = PathPart(inst->fpb_Path); + *lp = '\0'; + + TagList->ti_Tag = ASLFR_DrawersOnly; + TagList->ti_Data = TRUE; + TagList++; + + TagList->ti_Tag = ASLFR_InitialFile; + TagList->ti_Data = (ULONG) inst->fpb_FileName; + TagList++; + + TagList->ti_Tag = ASLFR_InitialDrawer; + TagList->ti_Data = (ULONG) inst->fpb_Path; + TagList++; + + TagList->ti_Tag = TAG_END; + + return TRUE; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(ULONG) INTERRUPT EditAttrTTFontOpenHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + APTR ttRequest; + ULONG Success = 0; + + ttRequest = TT_AllocRequest(); + + if (ttRequest) + { + struct Window *PrefsWindow; + struct TagItem *AttrList; + char FontName[MAX_ATTRVALUE]; + ULONG FontStyle, FontWeight, FontSize; + STRPTR FontDesc; + + get(o, MUIA_String_Contents, &FontDesc); + + ParseTTFontFromDesc(FontDesc, &FontStyle, &FontWeight, + &FontSize, FontName, sizeof(FontName)); + +// set(inst->fpb_Objects[OBJNDX_WIN_EditAttribute], MUIA_Window_Sleep, TRUE); + get(inst->fpb_Objects[OBJNDX_WIN_EditAttribute], MUIA_Window_Window, &PrefsWindow); + + //TT_RequestA() + AttrList = TT_Request(ttRequest, + TTRQ_Window, (ULONG) PrefsWindow, + TTRQ_TitleText, (ULONG) GetLocString(MSGID_EDITATTRIBUTE_TTFONT_ASLTITLE), + TTRQ_PositiveText, (ULONG) GetLocString(MSGID_EDITATTRIBUTE_TTFONT_ASL_OKBUTTON), + TTRQ_NegativeText, (ULONG) GetLocString(MSGID_EDITATTRIBUTE_TTFONT_ASL_CANCELBUTTON), + TTRQ_DoSizes, TRUE, + TTRQ_DoStyle, TRUE, + TTRQ_DoWeight, TRUE, + TTRQ_Activate, TRUE, + TTRQ_DoPreview, TRUE, + TTRQ_InitialName, (ULONG) FontName, + TTRQ_InitialSize, FontSize, + TTRQ_InitialStyle, FontStyle, + TAG_END); + + d1(kprintf("%s/%ld: AttrList=%08lx\n", __FUNC__, __LINE__, AttrList)); + + if (AttrList) + { + char buffer[MAX_ATTRVALUE]; + + BuildTTDescFromAttrList(buffer, sizeof(buffer), AttrList); + + d1(kprintf("%s/%ld: FontDesc=<%s>\n", __FUNC__, __LINE__, buffer)); + + set(o, MUIA_String_Contents, (ULONG) buffer); + set(inst->fpb_Objects[OBJNDX_TTFont_Sample], MUIA_FontSample_TTFontDesc, (ULONG) buffer); + + Success = 1; + } + + TT_FreeRequest(ttRequest); + } + + DoMethod(o, MUIM_Popstring_Close, Success); + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(ULONG) INTERRUPT EditAttrTTFontCloseHookFunc(struct Hook *hook, Object *o, Msg msg) +{ +// struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + +// set(inst->fpb_Objects[OBJNDX_WIN_EditAttribute], MUIA_Window_Sleep, FALSE); + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT SelectEntryHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct MUI_NListtree_TreeNode *tn; +// struct MUI_NListtree_TreeNode *tn1; + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, + 0); + d1(kprintf("%s/%ld: active tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) "")); +#if 0 + tn1 = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + tn, + MUIV_NListtree_GetEntry_Position_Head, + 0); + d1(kprintf("%s/%ld: Head tn=%08lx <%s>\n", __FUNC__, __LINE__, tn1, tn1 ? tn1->tn_Name : (STRPTR) "")); + + tn1 = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + tn, + MUIV_NListtree_GetEntry_Position_Tail, + 0); + d1(kprintf("%s/%ld: Tail tn=%08lx <%s>\n", __FUNC__, __LINE__, tn1, tn1 ? tn1->tn_Name : (STRPTR) "")); +#endif + if (tn) + { + struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User; + + set(inst->fpb_Objects[OBJNDX_Menu_Expand], MUIA_Menuitem_Enabled, TRUE); + set(inst->fpb_Objects[OBJNDX_Menu_Collapse], MUIA_Menuitem_Enabled, TRUE); + + switch (fte->ftle_EntryType) + { + case ENTRYTYPE_FileType: + set(inst->fpb_Objects[OBJNDX_ButtonRemoveEntry], MUIA_Disabled, TRUE); + set(inst->fpb_Objects[OBJNDX_Menu_Copy], MUIA_Menuitem_Enabled, FALSE); + set(inst->fpb_Objects[OBJNDX_Menu_Cut], MUIA_Menuitem_Enabled, FALSE); + break; + case ENTRYTYPE_PopupMenu: + case ENTRYTYPE_PopupMenu_SubMenu: + case ENTRYTYPE_PopupMenu_MenuItem: + case ENTRYTYPE_PopupMenu_InternalCmd: + case ENTRYTYPE_PopupMenu_WbCmd: + case ENTRYTYPE_PopupMenu_ARexxCmd: + case ENTRYTYPE_PopupMenu_CliCmd: + case ENTRYTYPE_PopupMenu_PluginCmd: + case ENTRYTYPE_PopupMenu_IconWindowCmd: + case ENTRYTYPE_PopupMenu_MenuSeparator: + case ENTRYTYPE_ToolTip: + case ENTRYTYPE_ToolTip_Group: + case ENTRYTYPE_ToolTip_Member: + case ENTRYTYPE_ToolTip_HBar: + case ENTRYTYPE_ToolTip_String: + case ENTRYTYPE_ToolTip_Space: + case ENTRYTYPE_ToolTip_DtImage: + default: + set(inst->fpb_Objects[OBJNDX_Menu_Copy], MUIA_Menuitem_Enabled, TRUE); + set(inst->fpb_Objects[OBJNDX_Menu_Cut], MUIA_Menuitem_Enabled, TRUE); + set(inst->fpb_Objects[OBJNDX_ButtonRemoveEntry], MUIA_Disabled, FALSE); + break; + } + + UpdateAttributes(inst, fte); + } + else + { + DoMethod(inst->fpb_Objects[OBJNDX_AddAttrList], MUIM_NList_Clear); + set(inst->fpb_Objects[OBJNDX_Menu_Expand], MUIA_Menuitem_Enabled, FALSE); + set(inst->fpb_Objects[OBJNDX_Menu_Collapse], MUIA_Menuitem_Enabled, FALSE); + + set(inst->fpb_Objects[OBJNDX_Menu_Copy], MUIA_Menuitem_Enabled, FALSE); + set(inst->fpb_Objects[OBJNDX_Menu_Cut], MUIA_Menuitem_Enabled, FALSE); + + set(inst->fpb_Objects[OBJNDX_ButtonRemoveEntry], MUIA_Disabled, TRUE); + } + + + EnablePasteMenuEntry(inst); + EnablePasteAttrMenuEntry(inst); + + return NULL; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT SelectAttributeHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct MUI_NListtree_TreeNode *tn; + struct AttrListEntry *Attr = NULL; + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, + 0); + d1(kprintf("%s/%ld: active tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) "")); + + if (tn) + { + DoMethod(inst->fpb_Objects[OBJNDX_AttrList], + MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, + &Attr); + } + + d1(kprintf("%s/%ld: active Attr=%08lx\n", __FUNC__, __LINE__, Attr)); + if (Attr) + { + struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User; + const struct AttributeDef *atd; + + d1(kprintf("%s/%ld: active fte=%08lx\n", __FUNC__, __LINE__, fte)); + + set(inst->fpb_Objects[OBJNDX_Menu_CopyAttr], MUIA_Menuitem_Enabled, TRUE); + set(inst->fpb_Objects[OBJNDX_Menu_CutAttr], MUIA_Menuitem_Enabled, TRUE); + + atd = GetAttributeDef(Attr->ale_Attribute.fta_Type, fte->ftle_EntryType); + d1(kprintf("%s/%ld: atd=%08lx\n", __FUNC__, __LINE__, atd)); + if (atd) + { + set(inst->fpb_Objects[OBJNDX_ButtonRemoveAttribute], MUIA_Disabled, IsAttrRequired(fte, atd)); + + // "Edit Attribute" button stays disabled when attribute has type ATTRDEFTYPE_None + set(inst->fpb_Objects[OBJNDX_ButtonEditAttribute], MUIA_Disabled, + ATTRDEFTYPE_None == atd->atd_DefaultContents.avd_Type); + } + } + else + { + set(inst->fpb_Objects[OBJNDX_Menu_CopyAttr], MUIA_Menuitem_Enabled, FALSE); + set(inst->fpb_Objects[OBJNDX_Menu_CutAttr], MUIA_Menuitem_Enabled, FALSE); + set(inst->fpb_Objects[OBJNDX_ButtonRemoveAttribute], MUIA_Disabled, TRUE); + set(inst->fpb_Objects[OBJNDX_ButtonEditAttribute], MUIA_Disabled, TRUE); + } + + return NULL; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT EditAttributeHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct MUI_NListtree_TreeNode *tn; + struct AttrListEntry *Attr = NULL; + + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, + 0); + d1(KPrintF("%s/%ld: active tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) "")); + + if (tn) + { + DoMethod(inst->fpb_Objects[OBJNDX_AttrList], + MUIM_NList_GetEntry, + MUIV_NList_GetEntry_Active, + &Attr); + } + + d1(KPrintF("%s/%ld: active Attr=%08lx\n", __FUNC__, __LINE__, Attr)); + if (Attr) + { + struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User; + const struct AttributeDef *atd; + + atd = GetAttributeDef(Attr->ale_Attribute.fta_Type, fte->ftle_EntryType); + d1(KPrintF("%s/%ld: atd=%08lx\n", __FUNC__, __LINE__, atd)); + if (atd) + { + char ValueString[MAX_ATTRVALUE]; + + set(inst->fpb_Objects[OBJNDX_Text_AttributeName], + MUIA_Text_Contents, (ULONG) GetAttributeName(atd->atd_Type)); + + GetAttributeValueString(&Attr->ale_Attribute, ValueString, sizeof(ValueString)); + + d1(KPrintF("%s/%ld: avd_Type=%ld\n", __FUNC__, __LINE__, atd->atd_DefaultContents.avd_Type)); + + switch (atd->atd_DefaultContents.avd_Type) + { + case ATTRDEFTYPE_None: + // nothing to edit here... + return NULL; + break; + + case ATTRDEFTYPE_PathName: + set(inst->fpb_Objects[OBJNDX_Group_AttributeSelectValue], MUIA_ShowMe, FALSE); + set(inst->fpb_Objects[OBJNDX_Group_AttributeValue], MUIA_ShowMe, FALSE); + set(inst->fpb_Objects[OBJNDX_Group_AttributeAslFile], MUIA_ShowMe, FALSE); + set(inst->fpb_Objects[OBJNDX_Group_AttributeAslPath], MUIA_ShowMe, TRUE); + set(inst->fpb_Objects[OBJNDX_Group_AttributeAslFont], MUIA_ShowMe, FALSE); + set(inst->fpb_Objects[OBJNDX_Group_AttributeTTFont], MUIA_ShowMe, FALSE); + + set(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectAslPath], + MUIA_String_Contents, (ULONG) ValueString); + + set(inst->fpb_Objects[OBJNDX_WIN_EditAttribute], + MUIA_Window_ActiveObject, + inst->fpb_Objects[OBJNDX_Group_AttributeAslPath]); + break; + + case ATTRDEFTYPE_FileName: + set(inst->fpb_Objects[OBJNDX_Group_AttributeSelectValue], MUIA_ShowMe, FALSE); + set(inst->fpb_Objects[OBJNDX_Group_AttributeValue], MUIA_ShowMe, FALSE); + set(inst->fpb_Objects[OBJNDX_Group_AttributeAslFile], MUIA_ShowMe, TRUE); + set(inst->fpb_Objects[OBJNDX_Group_AttributeAslPath], MUIA_ShowMe, FALSE); + set(inst->fpb_Objects[OBJNDX_Group_AttributeAslFont], MUIA_ShowMe, FALSE); + set(inst->fpb_Objects[OBJNDX_Group_AttributeTTFont], MUIA_ShowMe, FALSE); + + switch (atd->atd_Type) + { + case ATTRTYPE_DtImageName: + case ATTRTYPE_UnselIconName: + case ATTRTYPE_SelIconName: + d1(KPrintF("%s/%ld: OBJNDX_DtPic_AttributeSelectAslFile=%08lx ValueString=<%s>\n", \ + __FUNC__, __LINE__, inst->fpb_Objects[OBJNDX_DtPic_AttributeSelectAslFile], ValueString)); + set(inst->fpb_Objects[OBJNDX_DtPic_AttributeSelectAslFile], MUIA_ScaDtpic_Name, ValueString); + break; + default: + set(inst->fpb_Objects[OBJNDX_DtPic_AttributeSelectAslFile], MUIA_ScaDtpic_Name, ""); + break; + } + + set(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectAslFile], + MUIA_String_Contents, (ULONG) ValueString); + + set(inst->fpb_Objects[OBJNDX_WIN_EditAttribute], + MUIA_Window_ActiveObject, + inst->fpb_Objects[OBJNDX_Group_AttributeAslFile]); + break; + + case ATTRDEFTYPE_FontString: + set(inst->fpb_Objects[OBJNDX_Group_AttributeSelectValue], MUIA_ShowMe, FALSE); + set(inst->fpb_Objects[OBJNDX_Group_AttributeValue], MUIA_ShowMe, FALSE); + set(inst->fpb_Objects[OBJNDX_Group_AttributeAslPath], MUIA_ShowMe, FALSE); + set(inst->fpb_Objects[OBJNDX_Group_AttributeAslFile], MUIA_ShowMe, FALSE); + set(inst->fpb_Objects[OBJNDX_Group_AttributeAslFont], MUIA_ShowMe, TRUE); + set(inst->fpb_Objects[OBJNDX_Group_AttributeTTFont], MUIA_ShowMe, FALSE); + + set(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectAslFont], + MUIA_String_Contents, (ULONG) ValueString); + set(inst->fpb_Objects[OBJNDX_AslFont_Sample], + MUIA_FontSample_StdFontDesc, (ULONG) ValueString); + + set(inst->fpb_Objects[OBJNDX_WIN_EditAttribute], + MUIA_Window_ActiveObject, + inst->fpb_Objects[OBJNDX_Group_AttributeAslFont]); + break; + + case ATTRDEFTYPE_TTFontString: + set(inst->fpb_Objects[OBJNDX_Group_AttributeSelectValue], MUIA_ShowMe, FALSE); + set(inst->fpb_Objects[OBJNDX_Group_AttributeValue], MUIA_ShowMe, FALSE); + set(inst->fpb_Objects[OBJNDX_Group_AttributeAslPath], MUIA_ShowMe, FALSE); + set(inst->fpb_Objects[OBJNDX_Group_AttributeAslFile], MUIA_ShowMe, FALSE); + set(inst->fpb_Objects[OBJNDX_Group_AttributeAslFont], MUIA_ShowMe, FALSE); + set(inst->fpb_Objects[OBJNDX_Group_AttributeTTFont], MUIA_ShowMe, TRUE); + + set(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectTTFont], + MUIA_String_Contents, (ULONG) ValueString); + set(inst->fpb_Objects[OBJNDX_TTFont_Sample], + MUIA_FontSample_TTFontDesc, (ULONG) ValueString); + + set(inst->fpb_Objects[OBJNDX_WIN_EditAttribute], + MUIA_Window_ActiveObject, + inst->fpb_Objects[OBJNDX_Group_AttributeTTFont]); + break; + + case ATTRDEFTYPE_ULong: + //... TBD + case ATTRDEFTYPE_LocString: + case ATTRDEFTYPE_String: + case ATTRDEFTYPE_String2: + set(inst->fpb_Objects[OBJNDX_Group_AttributeAslFile], MUIA_ShowMe, FALSE); + set(inst->fpb_Objects[OBJNDX_Group_AttributeAslPath], MUIA_ShowMe, FALSE); + set(inst->fpb_Objects[OBJNDX_Group_AttributeAslFont], MUIA_ShowMe, FALSE); + set(inst->fpb_Objects[OBJNDX_Group_AttributeTTFont], MUIA_ShowMe, FALSE); + + d1(KPrintF("%s/%ld: atd_NumberOfValues=%ld\n", __FUNC__, __LINE__, atd->atd_NumberOfValues)); + if (atd->atd_NumberOfValues > 0) + { + set(inst->fpb_Objects[OBJNDX_Group_AttributeSelectValue], MUIA_ShowMe, TRUE); + set(inst->fpb_Objects[OBJNDX_Group_AttributeValue], MUIA_ShowMe, FALSE); + + FillListOfAttributeValues(inst, fte, atd, Attr); + + set(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectValue], + MUIA_String_Contents, (ULONG) ValueString); + + set(inst->fpb_Objects[OBJNDX_WIN_EditAttribute], + MUIA_Window_ActiveObject, + inst->fpb_Objects[OBJNDX_Pop_AttributeSelectValue]); + } + else + { + set(inst->fpb_Objects[OBJNDX_Group_AttributeSelectValue], MUIA_ShowMe, FALSE); + set(inst->fpb_Objects[OBJNDX_Group_AttributeValue], MUIA_ShowMe, TRUE); + + set(inst->fpb_Objects[OBJNDX_String_AttributeValue], + MUIA_String_Contents, (ULONG) ValueString); + + set(inst->fpb_Objects[OBJNDX_WIN_EditAttribute], + MUIA_Window_ActiveObject, + inst->fpb_Objects[OBJNDX_String_AttributeValue]); + } + break; + } + + DoMethod(inst->fpb_Objects[OBJNDX_WIN_EditAttribute], MUIM_Notify, MUIA_Window_Open, TRUE, + inst->fpb_Objects[OBJNDX_WIN_Main], 3, MUIM_Set, MUIA_Window_Sleep, TRUE); + DoMethod(inst->fpb_Objects[OBJNDX_WIN_EditAttribute], MUIM_Notify, MUIA_Window_Open, FALSE, + inst->fpb_Objects[OBJNDX_WIN_Main], 3, MUIM_Set, MUIA_Window_Sleep, FALSE); + + d1(KPrintF("%s/%ld: atd=%08lx OBJNDX_WIN_EditAttribute=%08lx\n", __FUNC__, __LINE__, atd, inst->fpb_Objects[OBJNDX_WIN_EditAttribute])); + + set(inst->fpb_Objects[OBJNDX_WIN_EditAttribute], MUIA_Window_Open, TRUE); + + d1(KPrintF("%s/%ld: atd=%08lx\n", __FUNC__, __LINE__, atd)); + } + } + + d1(KPrintF("%s/%ld: END\n", __FUNC__, __LINE__)); + + return NULL; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT ContextMenuTriggerHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + Object *MenuObj = *((Object **) msg); + ULONG MenuHookIndex = 0; + struct Hook *MenuHook = NULL; + + d1(KPrintF("%s/%ld: MenuObj=%08lx\n", __FUNC__, __LINE__, MenuObj)); + d1(KPrintF("%s/%ld: msg=%08lx *msg=%08lx\n", __FUNC__, __LINE__, msg, *((ULONG *) msg))); + + get(MenuObj, MUIA_UserData, &MenuHookIndex); + + if (MenuHookIndex > 0 && MenuHookIndex < HOOKNDX_MAX) + MenuHook = &inst->fpb_Hooks[MenuHookIndex]; + + d1(KPrintF("%s/%ld: MenuHook=%08lx\n", __FUNC__, __LINE__, MenuHook)); + if (MenuHook) + DoMethod(inst->fpb_Objects[OBJNDX_Group_Main], MUIM_CallHook, MenuHook, MenuObj); + + return NULL; +} + +//---------------------------------------------------------------------------- + +static LONG ReadPrefs(struct FileTypesPrefsInst *inst, + CONST_STRPTR LoadFileName, CONST_STRPTR DefIconPrefsName) +{ + d1(time_t now = time(NULL)); + + d1(KPrintF(__FILE__ "/%s/%ld: LoadFileName=<%s> DefIconPrefsName=<%s>\n", __FUNC__, __LINE__, LoadFileName, DefIconPrefsName)); + + ReadFileTypes(inst, LoadFileName, DefIconPrefsName); + + d1(kprintf(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + d1(kprintf(__FILE__ "/%s/%ld: ReadFileTypes took %lu s\n", __FUNC__, __LINE__, time(NULL) - now)); + + return RETURN_OK; +} + + +static LONG WritePrefs(struct FileTypesPrefsInst *inst, + CONST_STRPTR SaveName, CONST_STRPTR DefIconPrefsName, ULONG Flags) +{ + LONG Result; + + d1(time_t now = time(NULL)); + + WriteDefIconsPrefs(inst, DefIconPrefsName); + + Result = WriteFileTypes(inst, SaveName, Flags); + + d1(kprintf(__FILE__ "/%s/%ld: WriteFileTypes took %lu s\n", __FUNC__, __LINE__, time(NULL) - now)); + + if (RETURN_OK == Result) + { + } + else + { + char Buffer[120]; + + Fault(Result, "", Buffer, sizeof(Buffer) - 1); + + // MUI_RequestA() + MUI_Request(inst->fpb_Objects[OBJNDX_APP_Main], inst->fpb_Objects[OBJNDX_WIN_Main], 0, NULL, + GetLocString(MSGID_ABOUTREQOK), + GetLocString(MSGID_REQTITLE_SAVEERROR), + SaveName, + Buffer); + } + + return Result; +} + +//---------------------------------------------------------------------------- + +DISPATCHER(myNListTree) +{ + struct FileTypesPrefsInst *inst; + ULONG Result; + + d1(kprintf(__FILE__ "/%s/%ld: MethodID=%08lx\n", __FUNC__, __LINE__, msg->MethodID)); + + switch(msg->MethodID) + { + case MUIM_ContextMenuChoice: + { + struct MUIP_ContextMenuChoice *cmc = (struct MUIP_ContextMenuChoice *) msg; + Object *MenuObj; + ULONG MenuHookIndex = 0; + struct Hook *MenuHook = NULL; + + get(obj, MUIA_NList_PrivateData, &inst); + + d1(kprintf("%s/%ld: MUIM_ContextMenuChoice item=%08lx\n", __FUNC__, __LINE__, cmc->item)); + + MenuObj = cmc->item; + + d1(kprintf("%s/%ld: MenuObj=%08lx\n", __FUNC__, __LINE__, MenuObj)); + d1(kprintf("%s/%ld: msg=%08lx *msg=%08lx\n", __FUNC__, __LINE__, msg, *((ULONG *) msg))); + + get(MenuObj, MUIA_UserData, &MenuHookIndex); + + if (MenuHookIndex > 0 && MenuHookIndex < HOOKNDX_MAX) + MenuHook = &inst->fpb_Hooks[MenuHookIndex]; + + d1(kprintf("%s/%ld: MenuHook=%08lx\n", __FUNC__, __LINE__, MenuHook)); + if (MenuHook) + DoMethod(inst->fpb_Objects[OBJNDX_Group_Main], MUIM_CallHook, MenuHook, 0); + + Result = 0; + } + break; + + case MUIM_NList_TestPos: + { + struct TestPosArg + { + ULONG MethodID; + LONG x, y; + struct MUI_NList_TestPos_Result *res; + }; + struct TestPosArg *tpa = (struct TestPosArg *) msg; + + get(obj, MUIA_NList_PrivateData, &inst); + + if (inst->fpb_PageIsActive) + Result = DoSuperMethodA(cl, obj, msg); + else + { + Result = 0; + tpa->res->entry = tpa->res->column = -1; + } + + d1(kprintf("%s/%ld: MUIM_NList_TestPos Result=%08lx x=%ld y=%ld tpr=%08lx entry=%ld column=%ld\n", \ + __FUNC__, __LINE__, Result, tpa->x, tpa->y, tpa->res, tpa->res->entry, tpa->res->column)); + } + break; + + case MUIM_DragQuery: + { + struct MUIP_DragQuery *dq = (struct MUIP_DragQuery *) msg; + + get(obj, MUIA_NList_PrivateData, &inst); + + d1(kprintf("%s/%ld: MUIM_DragQuery obj=%08lx\n", __FUNC__, __LINE__, dq->obj)); + + if (inst->fpb_Objects[OBJNDX_MainListTree] == dq->obj) + Result = MUIV_DragQuery_Accept; + else + Result = MUIV_DragQuery_Refuse; + } + break; + + case MUIM_DragDrop: + Result = DoDragDrop(cl, obj, msg); + break; + + case MUIM_NList_DropType: + { + struct MUIP_NList_DropType *dr = (struct MUIP_NList_DropType *)msg; + struct MUI_NListtree_TreeNode *tnTo, *tnFrom; + struct MUI_NListtree_TestPos_Result res; + + get(obj, MUIA_NList_PrivateData, &inst); + + inst->fpb_MenuTreeMayDrop = FALSE; + + Result = DoSuperMethodA(cl, obj, msg); + d1(KPrintF("%s/%ld: DropType=%ld pos=%ld\n", __FUNC__, __LINE__, *(dr->type), *(dr->pos))); + + DoMethod(obj, MUIM_NListtree_TestPos, dr->mousex, dr->mousey, &res); + + tnTo = res.tpr_TreeNode; + + tnFrom = MUIV_NListtree_Active_Off; + get(obj, MUIA_NListtree_Active, &tnFrom); + + d1(KPrintF("%s/%ld: tnFrom=%08lx tnTo=%08lx\n", __FUNC__, __LINE__, tnFrom, tnTo)); + + if (tnTo && tnFrom) + { + switch (*(dr->type)) + { + case MUIV_NListtree_DropType_None: + case MUIV_NListtree_DropType_Sorted: + default: + break; + case MUIV_NListtree_DropType_Above: + case MUIV_NListtree_DropType_Below: + if (MayPasteBelow(inst, tnTo, tnFrom)) + inst->fpb_MenuTreeMayDrop = TRUE; + break; + case MUIV_NListtree_DropType_Onto: + if (MayPasteOnto(inst, tnTo, tnFrom)) + inst->fpb_MenuTreeMayDrop = TRUE; + break; + } + d1(KPrintF("%s/%ld: DropType=%ld\n", __FUNC__, __LINE__, *(dr->type))); + } + } + break; + + // we catch MUIM_DragReport because we want to restrict some dragging for some special objects + case MUIM_DragReport: + { + get(obj, MUIA_NList_PrivateData, &inst); + + d1(KPrintF("%s/%ld: MUIM_DragReport\n", __FUNC__, __LINE__)); + + Result = DoSuperMethodA(cl, obj, msg); + if (!inst->fpb_MenuTreeMayDrop) + Result = MUIV_DragReport_Abort; + + d1(KPrintF("%s/%ld: MUIM_DragReport\n", __FUNC__, __LINE__)); + } + break; + + default: + Result = DoSuperMethodA(cl, obj, msg); + } + + return Result; +} +DISPATCHER_END + +//---------------------------------------------------------------------------- + +DISPATCHER(myFileTypesNListTree) +{ + struct FileTypesPrefsInst *inst; + ULONG Result; + + d1(kprintf(__FILE__ "/%s/%ld: MethodID=%08lx\n", __FUNC__, __LINE__, msg->MethodID)); + + switch(msg->MethodID) + { + case MUIM_ContextMenuChoice: + { + struct MUIP_ContextMenuChoice *cmc = (struct MUIP_ContextMenuChoice *) msg; + Object *MenuObj; + ULONG MenuHookIndex = 0; + struct Hook *MenuHook = NULL; + + get(obj, MUIA_NList_PrivateData, &inst); + + d1(kprintf("%s/%ld: MUIM_ContextMenuChoice item=%08lx\n", __FUNC__, __LINE__, cmc->item)); + + MenuObj = cmc->item; + + d1(kprintf("%s/%ld: MenuObj=%08lx\n", __FUNC__, __LINE__, MenuObj)); + d1(kprintf("%s/%ld: msg=%08lx *msg=%08lx\n", __FUNC__, __LINE__, msg, *((ULONG *) msg))); + + get(MenuObj, MUIA_UserData, &MenuHookIndex); + + if (MenuHookIndex > 0 && MenuHookIndex < HOOKNDX_MAX) + MenuHook = &inst->fpb_Hooks[MenuHookIndex]; + + d1(kprintf("%s/%ld: MenuHook=%08lx\n", __FUNC__, __LINE__, MenuHook)); + if (MenuHook) + DoMethod(inst->fpb_Objects[OBJNDX_Group_Main], MUIM_CallHook, MenuHook, 0); + + Result = 0; + } + break; + + case MUIM_DragQuery: + { + struct MUIP_DragQuery *dq = (struct MUIP_DragQuery *) msg; + + d1(kprintf("%s/%ld: MUIM_DragQuery obj=%08lx\n", __FUNC__, __LINE__, dq->obj)); + + // only accept objects from ourselves + if (obj == dq->obj) + Result = MUIV_DragQuery_Accept; + else + Result = MUIV_DragQuery_Refuse; + } + break; + + case MUIM_DragDrop: + { + //struct MUIP_DragDrop *dq = (struct MUIP_DragDrop *) msg; + struct MUI_NListtree_TreeNode *ln; + + get(obj, MUIA_NList_PrivateData, &inst); + d1(kprintf("%s/%ld: MUIP_DragDrop obj=%08lx\n", __FUNC__, __LINE__, obj)); + + Result = DoSuperMethodA(cl, obj, msg); + + ln = (struct MUI_NListtree_TreeNode *) DoMethod(obj, + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, + 0); + + d1(kprintf("%s/%ld: ln=%08lx tn_User=%08lx\n", __FUNC__, __LINE__, ln, ln->tn_User)); + + if (ln) + { + SetFileTypesIcon(inst, ln); + } + } + break; + + default: + Result = DoSuperMethodA(cl, obj, msg); + } + + return Result; +} +DISPATCHER_END + +//---------------------------------------------------------------------------- + +DISPATCHER(myNList) +{ + struct FileTypesPrefsInst *inst; + ULONG Result; + + d1(kprintf(__FILE__ "/%s/%ld: MethodID=%08lx\n", __FUNC__, __LINE__, msg->MethodID)); + + switch(msg->MethodID) + { + case MUIM_ContextMenuChoice: + { + struct MUIP_ContextMenuChoice *cmc = (struct MUIP_ContextMenuChoice *) msg; + Object *MenuObj; + ULONG MenuHookIndex = 0; + struct Hook *MenuHook = NULL; + + get(obj, MUIA_NList_PrivateData, &inst); + + d1(kprintf("%s/%ld: MUIM_ContextMenuChoice item=%08lx\n", __FUNC__, __LINE__, cmc->item)); + + MenuObj = cmc->item; + + d1(kprintf("%s/%ld: MenuObj=%08lx\n", __FUNC__, __LINE__, MenuObj)); + d1(kprintf("%s/%ld: msg=%08lx *msg=%08lx\n", __FUNC__, __LINE__, msg, *((ULONG *) msg))); + + get(MenuObj, MUIA_UserData, &MenuHookIndex); + + if (MenuHookIndex > 0 && MenuHookIndex < HOOKNDX_MAX) + MenuHook = &inst->fpb_Hooks[MenuHookIndex]; + + d1(kprintf("%s/%ld: MenuHook=%08lx\n", __FUNC__, __LINE__, MenuHook)); + if (MenuHook) + DoMethod(inst->fpb_Objects[OBJNDX_Group_Main], MUIM_CallHook, MenuHook, MenuObj); + + Result = 0; + } + break; + + default: + Result = DoSuperMethodA(cl, obj, msg); + } + + return Result; +} +DISPATCHER_END + +//---------------------------------------------------------------------------- + +DISPATCHER(myFileTypesActionsNList) +{ + struct FileTypesPrefsInst *inst; + ULONG Result; + + d1(kprintf(__FILE__ "/%s/%ld: MethodID=%08lx\n", __FUNC__, __LINE__, msg->MethodID)); + + switch(msg->MethodID) + { + case MUIM_DragDrop: + Result = DoSuperMethodA(cl, obj, msg); + get(obj, MUIA_NList_PrivateData, &inst); + CallHookPkt(&inst->fpb_Hooks[HOOKNDX_DragDropSort_FileTypesAction], obj, msg); + break; + + case MUIM_ContextMenuChoice: + { + struct MUIP_ContextMenuChoice *cmc = (struct MUIP_ContextMenuChoice *) msg; + Object *MenuObj; + ULONG MenuHookIndex = 0; + struct Hook *MenuHook = NULL; + + get(obj, MUIA_NList_PrivateData, &inst); + + d1(kprintf("%s/%ld: MUIM_ContextMenuChoice item=%08lx\n", __FUNC__, __LINE__, cmc->item)); + + MenuObj = cmc->item; + + d1(kprintf("%s/%ld: MenuObj=%08lx\n", __FUNC__, __LINE__, MenuObj)); + d1(kprintf("%s/%ld: msg=%08lx *msg=%08lx\n", __FUNC__, __LINE__, msg, *((ULONG *) msg))); + + get(MenuObj, MUIA_UserData, &MenuHookIndex); + + if (MenuHookIndex > 0 && MenuHookIndex < HOOKNDX_MAX) + MenuHook = &inst->fpb_Hooks[MenuHookIndex]; + + d1(kprintf("%s/%ld: MenuHook=%08lx\n", __FUNC__, __LINE__, MenuHook)); + if (MenuHook) + DoMethod(inst->fpb_Objects[OBJNDX_Group_Main], MUIM_CallHook, MenuHook, MenuObj); + + Result = 0; + } + break; + + default: + Result = DoSuperMethodA(cl, obj, msg); + } + + return Result; +} +DISPATCHER_END + +//---------------------------------------------------------------------------- + +struct FtAttribute *AddAttribute(struct FileTypesListEntry *fte, + enum ftAttributeType AttrType, ULONG DataLength, const void *AttrData) +{ + struct FtAttribute *fta; + + fta = malloc(sizeof(struct FtAttribute) + DataLength); + d1(kprintf(__FILE__ "/%s/%ld: fta=%08lx size=%lu\n", __FUNC__, __LINE__, \ + fta, sizeof(struct FtAttribute) + DataLength)); + + if (fta) + { + AddTail(&fte->ftle_AttributesList, &fta->fta_Node); + + fta->fta_Type = AttrType; + fta->fta_Length = DataLength; + memcpy(fta->fta_Data, AttrData, DataLength); + } + + return fta; +} + +static void DisposeAttribute(struct FtAttribute *fta) +{ + free(fta); +} + +static void CleanupAttributes(struct List *AttributesList) +{ + struct FtAttribute *fta; + + while ((fta = (struct FtAttribute *) RemHead(AttributesList))) + { + DisposeAttribute(fta); + } +} + +//---------------------------------------------------------------------------- + +CONST_STRPTR GetAttributeName(enum ftAttributeType Type) +{ + CONST_STRPTR Name; + + switch (Type) + { + case ATTRTYPE_FtDescription: + Name = "DESCRIPTION"; + break; + + case ATTRTYPE_PvPluginName: + Name = "PREVIEWPLUGIN"; + break; + + case ATTRTYPE_GroupOrientation: + Name = "ORIENTATION"; + break; + + case ATTRTYPE_MemberHideString: + Name = "HIDE"; + break; + + case ATTRTYPE_StringHAlign: + Name = "HALIGN"; + break; + + case ATTRTYPE_StringVAlign: + Name = "VALIGN"; + break; + + case ATTRTYPE_StringStyle: + Name = "STYLE"; + break; + + case ATTRTYPE_StringFont: + Name = "FONT"; + break; + + case ATTRTYPE_StringTTFont: + Name = "TTFONT"; + break; + + case ATTRTYPE_StringPen: + Name = "TEXTPEN"; + break; + + case ATTRTYPE_StringId: + Name = "ID"; + break; + + case ATTRTYPE_StringText: + Name = "TEXT"; + break; + + case ATTRTYPE_StringSrc: + Name = "SRC"; + break; + + case ATTRTYPE_SpaceSize: + Name = "SIZE"; + break; + + case ATTRTYPE_DtImageName: + Name = "FILENAME"; + break; + + case ATTRTYPE_UnselIconName: + Name = "UNSELECTEDICON"; + break; + + case ATTRTYPE_SelIconName: + Name = "SELECTEDICON"; + break; + + case ATTRTYPE_MenuItemName: + Name = "NAME"; + break; + + case ATTRTYPE_MenuCommKey: + Name = "KEY"; + break; + + case ATTRTYPE_MenuDefaultAction: + Name = "DEFAULTACTION"; + break; + + case ATTRTYPE_CommandName: + Name = "NAME"; + break; + + case ATTRTYPE_CommandStacksize: + Name = "STACK"; + break; + + case ATTRTYPE_CommandPriority: + Name = "PRIORITY"; + break; + + case ATTRTYPE_CommandWbArgs: + Name = "WBARGS"; + break; + + default: + Name = "??unknown_Name??"; + break; + } + + return Name; +} + +STRPTR GetAttributeValueString(const struct FtAttribute *fta, char *Buffer, size_t BuffLen) +{ + if (NULL == fta) + strcpy(Buffer, ""); + else + { + switch (fta->fta_Type) + { + case ATTRTYPE_FtDescription: + case ATTRTYPE_PvPluginName: + case ATTRTYPE_StringHAlign: + case ATTRTYPE_StringVAlign: + case ATTRTYPE_StringStyle: + case ATTRTYPE_StringFont: + case ATTRTYPE_StringTTFont: + case ATTRTYPE_StringPen: + case ATTRTYPE_StringId: + case ATTRTYPE_StringText: + case ATTRTYPE_StringSrc: + case ATTRTYPE_DtImageName: + case ATTRTYPE_UnselIconName: + case ATTRTYPE_SelIconName: + case ATTRTYPE_MenuItemName: + case ATTRTYPE_MenuCommKey: + case ATTRTYPE_CommandName: + case ATTRTYPE_MemberHideString: + stccpy(Buffer, (char *)fta->fta_Data, BuffLen); + break; + + case ATTRTYPE_GroupOrientation: + switch (*((enum TTLayoutMode *) fta->fta_Data)) + { + case TTL_Horizontal: + stccpy(Buffer, "horizontal", BuffLen); + break; + case TTL_Vertical: + stccpy(Buffer, "vertical", BuffLen); + break; + default: + sprintf(Buffer, "??unknown_Orientation??:%d", *((enum TTLayoutMode *) fta->fta_Data)); + break; + } + break; + + case ATTRTYPE_CommandStacksize: + case ATTRTYPE_CommandPriority: + case ATTRTYPE_SpaceSize: + sprintf(Buffer, "%ld", *((ULONG *) fta->fta_Data)); + break; + + case ATTRTYPE_CommandWbArgs: + case ATTRTYPE_MenuDefaultAction: + strcpy(Buffer, ""); + break; + + default: + stccpy(Buffer, "??unknown_AttrType??", BuffLen); + break; + } + } + + return Buffer; +} + + +static const struct FtAttribute *FindAttribute(const struct FileTypesListEntry *fte, enum FtEntryType AttrType) +{ + struct FtAttribute *fta; + + for (fta = (struct FtAttribute *) fte->ftle_AttributesList.lh_Head; + fta != (struct FtAttribute *) &fte->ftle_AttributesList.lh_Tail; + fta = (struct FtAttribute *) fta->fta_Node.ln_Succ) + { + if (AttrType == fta->fta_Type) + return fta; + } + + return NULL; +} + + +static void RemoveAttribute(struct FileTypesListEntry *fte, enum ftAttributeType AttrType) +{ + struct FtAttribute *fta; + + for (fta = (struct FtAttribute *) fte->ftle_AttributesList.lh_Head; + fta != (struct FtAttribute *) &fte->ftle_AttributesList.lh_Tail; + fta = (struct FtAttribute *) fta->fta_Node.ln_Succ) + { + if (AttrType == fta->fta_Type) + { + Remove(&fta->fta_Node); + free(fta); + break; + } + } + +} + + +static struct FileTypesListEntry *FindChildByType(struct FileTypesPrefsInst *inst, + struct MUI_NListtree_TreeNode *tn, enum FtEntryType RequestedType) +{ + struct FileTypesListEntry *fte = NULL; + + d1(kprintf("%s/%ld: active tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) "")); + + if (tn) + { + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + tn, + MUIV_NListtree_GetEntry_Position_Head, + 0); + + fte = tn ? ((struct FileTypesListEntry *) tn->tn_User) : NULL; + + while (fte && fte->ftle_EntryType != RequestedType) + { + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + tn, + MUIV_NListtree_GetEntry_Position_Next, + 0); + + fte = tn ? ((struct FileTypesListEntry *) tn->tn_User) : NULL; + } + } + + return fte; +} + + +static BOOL HasChildren(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn) +{ + BOOL HasChildren = FALSE; + + d1(kprintf("%s/%ld: active tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) "")); + + if (tn) + { + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + tn, + MUIV_NListtree_GetEntry_Position_Head, + 0); + + if (tn) + HasChildren = TRUE; + } + + return HasChildren; +} + +//---------------------------------------------------------------------------- + +CONST_STRPTR GetNameFromEntryType(enum ftAttributeType EntryType) +{ + if (EntryType >= 0 && EntryType < Sizeof(EntryTypeNames)) + return GetLocString(EntryTypeNames[EntryType]); + else + return "??unknown_EntryType??"; +} + +//---------------------------------------------------------------------------- + +static void AddDefaultAttributes(struct FileTypesPrefsInst *inst, struct FileTypesListEntry *fte) +{ + ULONG n; + + for (n = 0; n < Sizeof(AllEntryAttributes); n++) + { + if (AllEntryAttributes[n].eat_EntryType == fte->ftle_EntryType) + { + ULONG m; + + d1(kprintf("%s/%ld: EntryType=%lu\n", __FUNC__, __LINE__, AllEntryAttributes[n].eat_EntryType)); + + for (m = 0; m < AllEntryAttributes[n].eat_AttrCount; m++) + { + if (IsAttrRequired(fte, &AllEntryAttributes[n].eat_AttrArray[m])) + { + d1(kprintf("%s/%ld: Add AttrType=%lu\n", __FUNC__, __LINE__, \ + AllEntryAttributes[n].eat_AttrArray[m].atd_Type)); + + AddNewAttribute(inst, fte, AllEntryAttributes[n].eat_AttrArray[m].atd_Type); + } + } + break; + } + } +} + +//---------------------------------------------------------------------------- + +static void SetAddableAttributes(struct FileTypesPrefsInst *inst, struct FileTypesListEntry *fte) +{ + ULONG Added = 0; + ULONG n; + + set(inst->fpb_Objects[OBJNDX_AddAttrList], MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + + DoMethod(inst->fpb_Objects[OBJNDX_AddAttrList], MUIM_NList_Clear); + + for (n = 0; n < Sizeof(AllEntryAttributes); n++) + { + if (AllEntryAttributes[n].eat_EntryType == fte->ftle_EntryType) + { + ULONG m; + + for (m = 0; m < AllEntryAttributes[n].eat_AttrCount; m++) + { + if (NULL == FindAttribute(fte, AllEntryAttributes[n].eat_AttrArray[m].atd_Type)) + { + Added++; + DoMethod(inst->fpb_Objects[OBJNDX_AddAttrList], MUIM_NList_InsertSingle, + AllEntryAttributes[n].eat_AttrArray[m].atd_Type, + MUIV_NList_Insert_Sorted); + } + } + break; + } + } + + d1(kprintf("%s/%ld: Added=%lu\n", __FUNC__, __LINE__, Added)); + + set(inst->fpb_Objects[OBJNDX_AddAttrPopObject], MUIA_Disabled, 0 == Added); + + set(inst->fpb_Objects[OBJNDX_AddAttrList], MUIA_NList_Quiet, MUIV_NList_Quiet_None); +} + +//---------------------------------------------------------------------------- + +static void UpdateAttributes(struct FileTypesPrefsInst *inst, struct FileTypesListEntry *fte) +{ + struct FtAttribute *fta; + struct FileTypesListEntry *ftePopupMenu; + struct FileTypesListEntry *fteToolTip; + const ULONG *AddEntryList; + struct MUI_NListtree_TreeNode *tn; + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, + 0); + d1(kprintf("%s/%ld: active tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) "")); + + DoMethod(inst->fpb_Objects[OBJNDX_AddEntryPopObject], MUIM_Popstring_Close, FALSE); + DoMethod(inst->fpb_Objects[OBJNDX_AddAttrPopObject], MUIM_Popstring_Close, FALSE); + + set(inst->fpb_Objects[OBJNDX_AttrList], MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + set(inst->fpb_Objects[OBJNDX_AddEntryList], MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + + DoMethod(inst->fpb_Objects[OBJNDX_AttrList], MUIM_NList_Clear); + DoMethod(inst->fpb_Objects[OBJNDX_AddEntryList], MUIM_NList_Clear); + + set(inst->fpb_Objects[OBJNDX_ButtonRemoveAttribute], MUIA_Disabled, TRUE); + set(inst->fpb_Objects[OBJNDX_ButtonEditAttribute], MUIA_Disabled, TRUE); + set(inst->fpb_Objects[OBJNDX_Menu_CopyAttr], MUIA_Menuitem_Enabled, FALSE); + set(inst->fpb_Objects[OBJNDX_Menu_CutAttr], MUIA_Menuitem_Enabled, FALSE); + + for (fta = (struct FtAttribute *) fte->ftle_AttributesList.lh_Head; + fta != (struct FtAttribute *) &fte->ftle_AttributesList.lh_Tail; + fta = (struct FtAttribute *) fta->fta_Node.ln_Succ) + { + DoMethod(inst->fpb_Objects[OBJNDX_AttrList], MUIM_NList_InsertSingle, + fta, MUIV_NList_Insert_Bottom); + } + + switch (fte->ftle_EntryType) + { + case ENTRYTYPE_FileType: + ftePopupMenu = FindChildByType(inst, tn, ENTRYTYPE_PopupMenu); + fteToolTip = FindChildByType(inst, tn, ENTRYTYPE_ToolTip); + + if (ftePopupMenu) + { + if (fteToolTip) + AddEntryList = NULL; + else + AddEntryList = AddFiletypeStringsTT; + } + else + { + if (fteToolTip) + AddEntryList = AddFiletypeStringsPM; + else + AddEntryList = AddFiletypeStringsPMTT; + } + break; + + case ENTRYTYPE_PopupMenu: + AddEntryList = AddPopupMenuStrings; + break; + + case ENTRYTYPE_PopupMenu_SubMenu: + AddEntryList = AddSubMenuStrings; + break; + + case ENTRYTYPE_PopupMenu_MenuItem: + AddEntryList = AddMenuItemStrings; + break; + + case ENTRYTYPE_ToolTip: + AddEntryList = AddToolTipStrings; + break; + + case ENTRYTYPE_ToolTip_Group: + AddEntryList = AddGroupStrings; + break; + + case ENTRYTYPE_ToolTip_Member: + // only 1 child allowed + if (HasChildren(inst, tn)) + AddEntryList = NULL; + else + AddEntryList = AddMemberStrings; + break; + + default: + AddEntryList = NULL; + break; + } + + SetAddableAttributes(inst, fte); + + if (AddEntryList) + { + DoMethod(inst->fpb_Objects[OBJNDX_AddEntryList], MUIM_NList_Insert, + AddEntryList, -1, MUIV_NList_Insert_Sorted); + } + + set(inst->fpb_Objects[OBJNDX_AddEntryList], MUIA_NList_Quiet, MUIV_NList_Quiet_None); + set(inst->fpb_Objects[OBJNDX_AttrList], MUIA_NList_Quiet, MUIV_NList_Quiet_None); + + set(inst->fpb_Objects[OBJNDX_AddEntryPopObject], MUIA_Disabled, NULL == AddEntryList); +} + +//---------------------------------------------------------------------------- + +static void AddNewAttribute(struct FileTypesPrefsInst *inst, struct FileTypesListEntry *fte, enum ftAttributeType AttrType) +{ + ULONG n; + + d1(kprintf("%s/%ld: inst=%08lx EntryType=%ld AttrType=%ld\n", __FUNC__, __LINE__, inst, fte->ftle_EntryType, AttrType)); + + set(inst->fpb_Objects[OBJNDX_AttrList], MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + + for (n = 0; n < Sizeof(AllEntryAttributes); n++) + { + if (AllEntryAttributes[n].eat_EntryType == fte->ftle_EntryType) + { + ULONG m; + + d1(kprintf("%s/%ld: AttrCount=%lu\n", __FUNC__, __LINE__, AllEntryAttributes[n].eat_AttrCount)); + + for (m = 0; m < AllEntryAttributes[n].eat_AttrCount; m++) + { + const struct AttrDefaultValue *avd = &AllEntryAttributes[n].eat_AttrArray[m].atd_DefaultContents; + + d1(kprintf("%s/%ld: atd_Type=%lu\n", __FUNC__, __LINE__, AllEntryAttributes[n].eat_AttrArray[m].atd_Type)); + + if (AllEntryAttributes[n].eat_AttrArray[m].atd_Type == AttrType) + { + struct FtAttribute *ftaNew = NULL; + + switch (avd->avd_Type) + { + case ATTRDEFTYPE_None: + ftaNew = AddAttribute(fte, AllEntryAttributes[n].eat_AttrArray[m].atd_Type, + 0, NULL); + break; + case ATTRDEFTYPE_ULong: + ftaNew = AddAttribute(fte, AllEntryAttributes[n].eat_AttrArray[m].atd_Type, + sizeof(ULONG), &avd->avd_ULongValue); + break; + case ATTRDEFTYPE_LocString: + ftaNew = AddAttribute(fte, AllEntryAttributes[n].eat_AttrArray[m].atd_Type, + 1 + strlen(GetLocString(avd->avd_ULongValue)), GetLocString(avd->avd_ULongValue)); + break; + case ATTRDEFTYPE_String: + case ATTRDEFTYPE_String2: + case ATTRDEFTYPE_PathName: + case ATTRDEFTYPE_FileName: + case ATTRDEFTYPE_FontString: + case ATTRDEFTYPE_TTFontString: + ftaNew = AddAttribute(fte, AllEntryAttributes[n].eat_AttrArray[m].atd_Type, + 1 + strlen(avd->avd_StringValue), avd->avd_StringValue); + break; + } + + if (ftaNew) + { + DoMethod(inst->fpb_Objects[OBJNDX_AttrList], MUIM_NList_InsertSingle, + ftaNew, MUIV_NList_Insert_Bottom); + } + break; + } + } + } + } + + set(inst->fpb_Objects[OBJNDX_AttrList], MUIA_NList_Quiet, MUIV_NList_Quiet_None); + + EnablePasteAttrMenuEntry(inst); +} + +//---------------------------------------------------------------------------- + +static void BeginSetMenuDefaultAction(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tnMenuItem) +{ + struct MUI_NListtree_TreeNode *tn = tnMenuItem; + struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User; + + // Find root of PopupMenu + while (tn && ENTRYTYPE_PopupMenu != fte->ftle_EntryType) + { + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + tn, + MUIV_NListtree_GetEntry_Position_Parent, + 0); + + if (tn) + fte = (struct FileTypesListEntry *) tn->tn_User; + } + + d1(kprintf("%s/%ld: Head tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) "")); + + // Now walk through entire Menu and remove "DefaultAction" atrribute from every MenuItem + // except + SetMenuDefaultAction(inst, tn, tnMenuItem); +} + + +static void SetMenuDefaultAction(struct FileTypesPrefsInst *inst, + struct MUI_NListtree_TreeNode *tnMenu, struct MUI_NListtree_TreeNode *tnNewDefault) +{ + struct MUI_NListtree_TreeNode *tn; + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + tnMenu, + MUIV_NListtree_GetEntry_Position_Head, + 0); + + d1(kprintf("%s/%ld: Head tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) "")); + + while (tn) + { + struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User; + + d1(kprintf("%s/%ld: tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) "")); + + switch (fte->ftle_EntryType) + { + case ENTRYTYPE_PopupMenu_MenuItem: + if (tn != tnNewDefault) + { + const struct FtAttribute *fta = FindAttribute(fte, ATTRTYPE_MenuDefaultAction); + + d1(kprintf("%s/%ld: fta=%08lx\n", __FUNC__, __LINE__, fta)); + if (fta) + { + RemoveAttribute(fte, ATTRTYPE_MenuDefaultAction); + + DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Redraw, + tn, + 0); + } + } + break; + + case ENTRYTYPE_PopupMenu_SubMenu: + SetMenuDefaultAction(inst, tn, tnNewDefault); + break; + + default: + break; + } + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + tn, + MUIV_NListtree_GetEntry_Position_Next, + 0); + } +} + +//---------------------------------------------------------------------------- + +static const struct AttributeDef *GetAttributeDef(enum ftAttributeType AttrType, enum FtEntryType fteEntryType) +{ + const struct EntryAttributes *eat; + ULONG n; + + for (n = 0, eat = AllEntryAttributes; n < Sizeof(AllEntryAttributes); n++, eat++) + { + if (fteEntryType == eat->eat_EntryType) + { + const struct AttributeDef *atd = eat->eat_AttrArray; + ULONG m; + + for (m = 0; m < eat->eat_AttrCount; m++, atd++) + { + if (atd->atd_Type == AttrType) + return atd; + } + break; + } + } + + return NULL; +} + +//---------------------------------------------------------------------------- + +static void FillListOfAttributeValues(struct FileTypesPrefsInst *inst, + const struct FileTypesListEntry *fte, const struct AttributeDef *atd, + const struct AttrListEntry *Attr) +{ + ULONG n; + + set(inst->fpb_Objects[OBJNDX_List_AttributeSelectValue], MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + DoMethod(inst->fpb_Objects[OBJNDX_List_AttributeSelectValue], MUIM_NList_Clear); + + d1(KPrintF("%s/%ld: atd_NumberOfValues=%ld\n", __FUNC__, __LINE__, atd->atd_NumberOfValues)); + + if (ATTRDEFTYPE_String2 == atd->atd_PossibleContents[0].avd_Type) + { + set(inst->fpb_Objects[OBJNDX_List_AttributeSelectValue], + MUIA_NList_Format, ","); + } + else + { + set(inst->fpb_Objects[OBJNDX_List_AttributeSelectValue], + MUIA_NList_Format, ""); + } + + for (n = 0; n < atd->atd_NumberOfValues; n++) + { + size_t len; + struct EditAttrListEntry *eal; + + len = sizeof(struct EditAttrListEntry); + + switch (atd->atd_PossibleContents[n].avd_Type) + { + case ATTRDEFTYPE_ULong: + len += sizeof(atd->atd_PossibleContents[n].avd_ULongValue); + break; + case ATTRDEFTYPE_LocString: + case ATTRDEFTYPE_String: + case ATTRDEFTYPE_String2: + case ATTRDEFTYPE_PathName: + case ATTRDEFTYPE_FileName: + case ATTRDEFTYPE_FontString: + case ATTRDEFTYPE_TTFontString: + len += 1 + strlen(atd->atd_PossibleContents[n].avd_StringValue); + break; + default: + break; + } + + eal = malloc(len); + + if (eal) + { + d1(KPrintF("%s/%ld: avd_Type=%ld\n", __FUNC__, __LINE__, atd->atd_PossibleContents[n].avd_Type)); + + eal->eal_fta = Attr->ale_Attribute; + eal->eal_fta.fta_Value2 = 0; + + switch (atd->atd_PossibleContents[n].avd_Type) + { + case ATTRDEFTYPE_ULong: + memcpy(eal->eal_fta.fta_Data, &atd->atd_PossibleContents[n].avd_ULongValue, sizeof(ULONG)); + eal->eal_fta.fta_Length = sizeof(ULONG); + break; + case ATTRDEFTYPE_LocString: + case ATTRDEFTYPE_String: + case ATTRDEFTYPE_PathName: + case ATTRDEFTYPE_FileName: + case ATTRDEFTYPE_FontString: + case ATTRDEFTYPE_TTFontString: + strcpy((char *)eal->eal_fta.fta_Data, atd->atd_PossibleContents[n].avd_StringValue); + eal->eal_fta.fta_Length = strlen(atd->atd_PossibleContents[n].avd_StringValue); + break; + case ATTRDEFTYPE_String2: + eal->eal_fta.fta_Value2 = atd->atd_PossibleContents[n].avd_ULongValue; + strcpy((char *)eal->eal_fta.fta_Data, atd->atd_PossibleContents[n].avd_StringValue); + eal->eal_fta.fta_Length = strlen(atd->atd_PossibleContents[n].avd_StringValue); + break; + default: + break; + } + + DoMethod(inst->fpb_Objects[OBJNDX_List_AttributeSelectValue], + MUIM_NList_InsertSingle, + eal, + MUIV_NList_Insert_Bottom); + + free(eal); + } + } + + set(inst->fpb_Objects[OBJNDX_List_AttributeSelectValue], MUIA_NList_Quiet, MUIV_NList_Quiet_None); +} + +//---------------------------------------------------------------------------- + +static ULONG ConvertGroupOrientationFromString(CONST_STRPTR DisplayString) +{ + ULONG Result = TTL_Horizontal; + + if (0 == Stricmp(DisplayString, "horizontal")) + Result = TTL_Horizontal; + else if (0 == Stricmp(DisplayString, "vertical")) + Result = TTL_Vertical; + + return Result; +} + +//---------------------------------------------------------------------------- + +static struct MUI_NListtree_TreeNode *CopyFileTypesEntry(struct FileTypesPrefsInst *inst, + struct MUI_NListtree_TreeNode *tnToListNode, struct MUI_NListtree_TreeNode *tnToPrevNode, + struct MUI_NListtree_TreeNode *tnFrom, ULONG destList, ULONG srcList) +{ + struct FileTypesListEntry *fteFrom = (struct FileTypesListEntry *) tnFrom->tn_User; + struct FileTypesListEntry *fteTo; + struct MUI_NListtree_TreeNode *tnNew; + struct MUI_NListtree_TreeNode *tnChild; + const struct FtAttribute *fta; + + if (NULL == tnFrom) + return NULL; + + tnChild = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[srcList], + MUIM_NListtree_GetEntry, + tnFrom, + MUIV_NListtree_GetEntry_Position_Head, + 0); + + tnNew = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[destList], + MUIM_NListtree_Insert, + tnFrom->tn_Name, NULL, + tnToListNode, + tnToPrevNode, + TNF_LIST | TNF_OPEN); + + fteTo = (struct FileTypesListEntry *) tnNew->tn_User; + fteTo->ftle_EntryType = fteFrom->ftle_EntryType; + + fteTo->fte_ImageObject = NULL; // do not try to copy fte_ImageObject !! + fteTo->fte_ImageIndex = 0; + + // Copy Attributes + for (fta = (const struct FtAttribute *) fteFrom->ftle_AttributesList.lh_Head; + fta != (const struct FtAttribute *) &fteFrom->ftle_AttributesList.lh_Tail; + fta = (const struct FtAttribute *) fta->fta_Node.ln_Succ) + { + AddAttribute(fteTo, fta->fta_Type, fta->fta_Length, fta->fta_Data); + } + + UpdateMenuImage(inst, destList, fteTo); + + // Copy Children + while (tnChild) + { + d1(kprintf("%s/%ld: tnChild=%08lx <%s>\n", __FUNC__, __LINE__, tnChild, tnChild->tn_Name)); + + CopyFileTypesEntry(inst, + tnNew, (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_PrevNode_Tail, + tnChild, destList, srcList); + + tnChild = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[srcList], + MUIM_NListtree_GetEntry, + tnChild, + MUIV_NListtree_GetEntry_Position_Next, + 0); + } + + return tnNew; +} + +//---------------------------------------------------------------------------- + +static BOOL MayPasteOnto(struct FileTypesPrefsInst *inst, + struct MUI_NListtree_TreeNode *tnTo, struct MUI_NListtree_TreeNode *tnFrom) +{ + const struct FileTypesListEntry *fteFrom = (const struct FileTypesListEntry *) tnFrom->tn_User; + const struct FileTypesListEntry *fteTo = (const struct FileTypesListEntry *) tnTo->tn_User; + BOOL MayPaste = FALSE; + + d1(kprintf("%s/%ld: fteTo=%08lx <%s> %ld fteFrom=%08lx <%s> %ld\n", __FUNC__, __LINE__, \ + fteTo, tnTo->tn_Name, fteTo->ftle_EntryType, fteFrom, tnFrom->tn_Name, fteFrom->ftle_EntryType)); + + if (fteTo->ftle_EntryType >= ENTRYTYPE_MAX || fteFrom->ftle_EntryType >= ENTRYTYPE_MAX) + return FALSE; + + d1(kprintf("%s/%ld: MayPaste=%ld\n", __FUNC__, __LINE__, \ + MayPasteIntoMatrix[fteTo->ftle_EntryType][fteFrom->ftle_EntryType])); + + if (MayPasteIntoMatrix[fteTo->ftle_EntryType][fteFrom->ftle_EntryType]) + { + switch (fteTo->ftle_EntryType) + { + case ENTRYTYPE_FileType: + // There is only one Popupmenu and one Tooltip allowed! + switch (fteFrom->ftle_EntryType) + { + case ENTRYTYPE_PopupMenu: + if (NULL == FindChildByType(inst, tnTo, ENTRYTYPE_PopupMenu)) + MayPaste = TRUE; + break; + case ENTRYTYPE_ToolTip: + if (NULL == FindChildByType(inst, tnTo, ENTRYTYPE_ToolTip)) + MayPaste = TRUE; + break; + default: + break; + } + break; + + case ENTRYTYPE_ToolTip_Member: + // only 1 child allowed + if (!HasChildren(inst, tnTo)) + MayPaste = TRUE; + break; + + default: + MayPaste = TRUE; + break; + } + } + + return MayPaste; +} + + +static struct MUI_NListtree_TreeNode *MayPasteBelow(struct FileTypesPrefsInst *inst, + struct MUI_NListtree_TreeNode *tnTo, struct MUI_NListtree_TreeNode *tnFrom) +{ + const struct FileTypesListEntry *fteFrom = (const struct FileTypesListEntry *) tnFrom->tn_User; + const struct FileTypesListEntry *fteTo = (const struct FileTypesListEntry *) tnTo->tn_User; + struct MUI_NListtree_TreeNode *tn; + BOOL Result = FALSE; + + d1(KPrintF("%s/%ld: START fteTo=%08lx <%s> %ld fteFrom=%08lx <%s> %ld\n", __FUNC__, __LINE__, \ + fteTo, tnTo->tn_Name, fteTo->ftle_EntryType, fteFrom, tnFrom->tn_Name, fteFrom->ftle_EntryType)); + + do { + if (fteTo->ftle_EntryType >= ENTRYTYPE_MAX || fteFrom->ftle_EntryType >= ENTRYTYPE_MAX) + break; + + if (tnTo->tn_Flags & TNF_OPEN) + { + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + tnTo, + MUIV_NListtree_GetEntry_Position_Head, + MUIV_NListtree_GetEntry_Flag_Visible); + d1(KPrintF("%s/%ld: tn=%08lx\n", __FUNC__, __LINE__, tn)); + + if (tn) + break; + } + + do { + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + tnTo, + MUIV_NListtree_GetEntry_Position_Next, + MUIV_NListtree_GetEntry_Flag_SameLevel | MUIV_NListtree_GetEntry_Flag_Visible); + d1(KPrintF("%s/%ld: tn=%08lx\n", __FUNC__, __LINE__, tn)); + if (tn) + break; + + tnTo = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + tnTo, + MUIV_NListtree_GetEntry_Position_Parent, + MUIV_NListtree_GetEntry_Flag_Visible); + d1(KPrintF("%s/%ld: tnTo=%08lx\n", __FUNC__, __LINE__, tnTo)); + + if (tnTo) + { + fteTo = (const struct FileTypesListEntry *) tnTo->tn_User; + + Result = MayPasteAfterMatrix[fteTo->ftle_EntryType][fteFrom->ftle_EntryType]; + } + } while (tnTo && !Result); + + if (NULL == tnTo) + break; + + Result = MayPasteAfterMatrix[fteTo->ftle_EntryType][fteFrom->ftle_EntryType]; + } while (0); + + d1(KPrintF("%s/%ld: END MayPaste=%ld\n", __FUNC__, __LINE__, Result)); + + return Result ? tnTo : NULL; +} + +//---------------------------------------------------------------------------- + +static void EnablePasteMenuEntry(struct FileTypesPrefsInst *inst) +{ + struct MUI_NListtree_TreeNode *tnMain; + struct MUI_NListtree_TreeNode *tnShadow; + + tnMain = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, + 0); + + tnShadow = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_ShadowListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_Insert_ListNode_Root, + MUIV_NListtree_GetEntry_Position_Head, + 0); + + if (tnMain && tnShadow && + ( MayPasteBelow(inst, tnMain, tnShadow) || MayPasteOnto(inst, tnMain, tnShadow) )) + { + set(inst->fpb_Objects[OBJNDX_Menu_Paste], MUIA_Menuitem_Enabled, TRUE); + } + else + { + set(inst->fpb_Objects[OBJNDX_Menu_Paste], MUIA_Menuitem_Enabled, FALSE); + } +} + +//---------------------------------------------------------------------------- + +static BOOL MayPasteAttr(struct FileTypesPrefsInst *inst, const struct FileTypesListEntry *fte, const struct AttrListEntry *Attr) +{ + d1(kprintf("%s/%ld: \n", __FUNC__, __LINE__)); + + if (NULL == Attr) + return FALSE; + + if (NULL == FindAttribute(fte, Attr->ale_Attribute.fta_Type)) + { + ULONG n; + + d1(kprintf("%s/%ld: Attr=%08lx Type=%ld\n", __FUNC__, __LINE__, Attr, Attr->ale_Attribute.fta_Type)); + + for (n = 0; n < Sizeof(AllEntryAttributes); n++) + { + if (AllEntryAttributes[n].eat_EntryType == fte->ftle_EntryType) + { + ULONG m; + + d1(kprintf("%s/%ld: AttrCount=%ld\n", __FUNC__, __LINE__, AllEntryAttributes[n].eat_AttrCount)); + + for (m = 0; m < AllEntryAttributes[n].eat_AttrCount; m++) + { + if (Attr->ale_Attribute.fta_Type == AllEntryAttributes[n].eat_AttrArray[m].atd_Type) + { + d1(kprintf("%s/%ld: Found!\n", __FUNC__, __LINE__)); + return TRUE; + } + } + break; + } + } + } + + d1(kprintf("%s/%ld: May not paste!\n", __FUNC__, __LINE__)); + + return FALSE; +} + +//---------------------------------------------------------------------------- + +static void EnablePasteAttrMenuEntry(struct FileTypesPrefsInst *inst) +{ + struct MUI_NListtree_TreeNode *tn; + struct AttrListEntry *Attr = NULL; + + set(inst->fpb_Objects[OBJNDX_Menu_PasteAttr], MUIA_Menuitem_Enabled, FALSE); + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, + 0); + d1(kprintf("%s/%ld: active tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) "")); + + if (tn) + { + DoMethod(inst->fpb_Objects[OBJNDX_ShadowAttrList], + MUIM_NList_GetEntry, + 0, + &Attr); + + d1(kprintf("%s/%ld: Attr=%08lx\n", __FUNC__, __LINE__, Attr)); + + if (Attr) + { + struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User; + + if (MayPasteAttr(inst, fte, Attr)) + set(inst->fpb_Objects[OBJNDX_Menu_PasteAttr], MUIA_Menuitem_Enabled, TRUE); + } + } +} + +//---------------------------------------------------------------------------- + +static BOOL IsAttrRequired(struct FileTypesListEntry *fte, const struct AttributeDef *atd) +{ + ULONG n; + + if (!atd->atd_Required) + return FALSE; + + for (n = 0; n < atd->atd_ExcludeCount; n++) + { + if (NULL != FindAttribute(fte, atd->atd_Exclude[n])) + { + // if one of the atd_Exclude[] members is already present + // in the Attribute list, this Attribute is NOT required + return FALSE; + } + } + + return TRUE; +} + +//---------------------------------------------------------------------------- + +static void EntryHasChanged(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn) +{ + struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User; + + set(inst->fpb_Objects[OBJNDX_MainListView], MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + + SetChangedFlag(inst, TRUE); + fte->ftle_Changed = TRUE; + + DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Redraw, + tn, + 0); + + // set CHANGED flag for all parent entries up to the ENTRYTYPE_FileType + while (tn && ENTRYTYPE_FileType != fte->ftle_EntryType) + { + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + tn, + MUIV_NListtree_GetEntry_Position_Parent, + 0); + if (tn) + { + fte = (struct FileTypesListEntry *) tn->tn_User; + fte->ftle_Changed = TRUE; + + DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Redraw, + tn, + 0); + } + } + + set(inst->fpb_Objects[OBJNDX_MainListView], MUIA_NList_Quiet, MUIV_NList_Quiet_None); +} + +//---------------------------------------------------------------------------- + +static void SetChangedFlag(struct FileTypesPrefsInst *inst, BOOL changed) +{ + if (changed != inst->fpb_Changed) + { + set(inst->fpb_Objects[OBJNDX_Lamp_Changed], + MUIA_Lamp_Color, changed ? MUIV_Lamp_Color_Ok : MUIV_Lamp_Color_Off); + inst->fpb_Changed = changed; + } +} + +//---------------------------------------------------------------------------- + +static void BuildTTDescFromAttrList(char *buffer, size_t length, struct TagItem *AttrList) +{ + ULONG FontStyle; + ULONG FontWeight; + ULONG FontSize; + const STRPTR *FontFamilyTable; + + FontStyle = GetTagData(TT_FontStyle, TT_FontStyle_Regular, AttrList); + FontWeight = GetTagData(TT_FontWeight, TT_FontWeight_Normal, AttrList); + FontSize = GetTagData(TT_FontSize, 12, AttrList); + FontFamilyTable = (const STRPTR *) GetTagData(TT_FamilyTable, (ULONG) NULL, AttrList); + + sprintf(buffer, "%ld/%ld/%ld/%s", FontStyle, FontWeight, FontSize, FontFamilyTable[0]); +} + +//----------------------------------------------------------------- + +static BOOL ParseTTFontFromDesc(CONST_STRPTR FontDesc, + ULONG *FontStyle, ULONG *FontWeight, ULONG *FontSize, + STRPTR FontName, size_t FontNameSize) +{ + CONST_STRPTR lp; + + strcpy(FontName, ""); + *FontStyle = 0; + *FontWeight = 0; + *FontSize = 0; + + // Font Desc format: + // "style/weight/size/fontname" + + if (3 != sscanf(FontDesc, "%ld/%ld/%ld", FontStyle, FontWeight, FontSize)) + return FALSE; + + lp = strchr(FontDesc, '/'); // Find "/" between style and weight + if (NULL == lp) + return FALSE; + + lp = strchr(lp + 1, '/'); // Find "/" between weight and size + if (NULL == lp) + return FALSE; + + lp = strchr(lp + 1, '/'); // Find "/" between size and name + if (NULL == lp) + return FALSE; + + // copy font name + stccpy(FontName, 1 + lp, FontNameSize); + + return TRUE; +} + +//----------------------------------------------------------------- + +void HideEmptyNodes(struct FileTypesPrefsInst *inst) +{ + struct MUI_NListtree_TreeNode *tn; + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Root, + MUIV_NListtree_GetEntry_Position_Head, + 0); + d1(kprintf("%s/%ld: tn=%08lx\n", __FUNC__, __LINE__, tn)); + + while (tn) + { + struct MUI_NListtree_TreeNode *tnNext; + struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User; + + d1(kprintf("%s/%ld: tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn->tn_Name)); + + if (!HasChildren(inst, tn) && IsListEmpty(&fte->ftle_AttributesList)) + { + struct MUI_NListtree_TreeNode *tnNew; + struct FileTypesListEntry *fteNew; + + d1(kprintf("%s/%ld: tn=%08lx\n", __FUNC__, __LINE__, tn)); + d1(kprintf("%s/%ld: filetype <%s> \n", __FUNC__, __LINE__, tn->tn_Name)); + + tnNew = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_HiddenListTree], + MUIM_NListtree_Insert, + tn->tn_Name, NULL, + MUIV_NListtree_Insert_ListNode_Root, + MUIV_NListtree_Insert_PrevNode_Sorted, + TNF_LIST); + + d1(kprintf("%s/%ld: tnNew=%08lx\n", __FUNC__, __LINE__, tnNew)); + + fteNew = (struct FileTypesListEntry *) tnNew->tn_User; + fteNew->ftle_EntryType = ENTRYTYPE_FileType; + } + + tnNext = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + tn, + MUIV_NListtree_GetEntry_Position_Next, + MUIV_NListtree_GetEntry_Flag_SameLevel); + + if (!HasChildren(inst, tn) && IsListEmpty(&fte->ftle_AttributesList)) + { + DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Remove, + MUIV_NListtree_Remove_ListNode_Active, + tn, + 0); + } + + tn = tnNext; + } +} + +//----------------------------------------------------------------- + +static void ShowHiddenNodes(struct FileTypesPrefsInst *inst) +{ + struct MUI_NListtree_TreeNode *tn; + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_HiddenListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Root, + MUIV_NListtree_GetEntry_Position_Head, + 0); + d1(kprintf("%s/%ld: tn=%08lx\n", __FUNC__, __LINE__, tn)); + + while (tn) + { + struct MUI_NListtree_TreeNode *tnNew; + struct FileTypesListEntry *fteNew; + + d1(kprintf("%s/%ld: tn=%08lx\n", __FUNC__, __LINE__, tn)); + d1(kprintf("%s/%ld: filetype <%s> \n", __FUNC__, __LINE__, tn->tn_Name)); + + tnNew = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, + tn->tn_Name, NULL, + MUIV_NListtree_Insert_ListNode_Root, + MUIV_NListtree_Insert_PrevNode_Sorted, + TNF_LIST); + + d1(kprintf("%s/%ld: tnNew=%08lx\n", __FUNC__, __LINE__, tnNew)); + + fteNew = (struct FileTypesListEntry *) tnNew->tn_User; + fteNew->ftle_EntryType = ENTRYTYPE_FileType; + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_HiddenListTree], + MUIM_NListtree_GetEntry, + tn, + MUIV_NListtree_GetEntry_Position_Next, + MUIV_NListtree_GetEntry_Flag_SameLevel); + } + + DoMethod(inst->fpb_Objects[OBJNDX_HiddenListTree], + MUIM_NListtree_Remove, + MUIV_NListtree_Remove_ListNode_Root, + MUIV_NListtree_Remove_TreeNode_All, + 0); + +} + +//----------------------------------------------------------------- + +static void ParseToolTypes(struct FileTypesPrefsInst *inst, struct MUIP_ScalosPrefs_ParseToolTypes *ptt) +{ + STRPTR tt; + + d1(kprintf("%s/%ld: start ptt=%08lx tooltypes=%08lx\n", __FUNC__, __LINE__, ptt, ptt->ToolTypes)); + d1(kprintf("%s/%ld: start tooltypes=%08lx %08lx %08lx\n", __FUNC__, __LINE__, ptt, ptt->ToolTypes[0], ptt->ToolTypes[1], ptt->ToolTypes[2])); + + tt = FindToolType(ptt->ToolTypes, "HIDEEMPTYENTRIES"); + d1(kprintf("%s/%ld: tt=%08lx\n", __FUNC__, __LINE__, tt)); + if (tt) + { + d1(kprintf("%s/%ld:\n", __FUNC__, __LINE__)); + + if (MatchToolValue(tt, "YES")) + inst->fpb_HideEmptyNodes = TRUE; + else if (MatchToolValue(tt, "NO")) + inst->fpb_HideEmptyNodes = FALSE; + + d1(kprintf("%s/%ld:\n", __FUNC__, __LINE__)); + } + + if (inst->fpb_Objects[OBJNDX_Menu_HideEmptyEntries]) + set(inst->fpb_Objects[OBJNDX_Menu_HideEmptyEntries], MUIA_Menuitem_Checked, inst->fpb_HideEmptyNodes); + + d1(kprintf("%s/%ld: end\n", __FUNC__, __LINE__)); +} + +//---------------------------------------------------------------------------- + +static LONG ReadScalosPrefs(struct FileTypesPrefsInst *inst, CONST_STRPTR PrefsFileName) +{ + LONG lID; + APTR p_MyPrefsHandle; + + p_MyPrefsHandle = AllocPrefsHandle("ScalosPrefs"); + lID = ID_MAIN; + + if (p_MyPrefsHandle) + { + CONST_STRPTR prefDefIconPath; + + ReadPrefsHandle(p_MyPrefsHandle, PrefsFileName); + + GetPreferences(p_MyPrefsHandle, lID, SCP_TTfAntialiasing, &inst->fpb_TTfAntialias, sizeof(inst->fpb_TTfAntialias) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_TTfGamma, &inst->fpb_TTfGamma, sizeof(inst->fpb_TTfGamma) ); + inst->fpb_TTfGamma = SCA_BE2WORD(inst->fpb_TTfGamma); + + prefDefIconPath = GetPrefsConfigString(p_MyPrefsHandle, SCP_PathsDefIcons, "ENV:sys"); + stccpy(inst->fpb_DefIconPath, prefDefIconPath, sizeof(inst->fpb_DefIconPath)); + + FreePrefsHandle(p_MyPrefsHandle); + } + + return RETURN_OK; +} + +//---------------------------------------------------------------------------- + +static CONST_STRPTR GetPrefsConfigString(APTR prefsHandle, ULONG Id, CONST_STRPTR DefaultString) +{ + struct PrefsStruct *ps = FindPreferences(prefsHandle, ID_MAIN, Id); + + if (ps) + return (CONST_STRPTR) PS_DATA(ps); + + return DefaultString; +} + + +//--------------------------------------------------------------- + +BOOL initPlugin(struct PluginBase *PluginBase) +{ + MajorVersion = PluginBase->pl_LibNode.lib_Version; + MinorVersion = PluginBase->pl_LibNode.lib_Revision; + + d1(kprintf("%s/%ld:\n", __FUNC__, __LINE__)); + + d1(kprintf("%s/%ld: PluginBase=%08lx procName=<%s>\n", __FUNC__, __LINE__, \ + PluginBase, FindTask(NULL)->tc_Node.ln_Name)); + + d1(kprintf("%s/%ld:\n", __FUNC__, __LINE__)); + + if (!OpenLibraries()) + return FALSE; + +#if !defined(__amigaos4__) && !defined(__AROS__) + if (_STI_240_InitMemFunctions()) + return FALSE; +#endif + + FontSampleClass = InitFontSampleClass(); + if (NULL == FontSampleClass) + return FALSE; + + FileTypesPrefsClass = MUI_CreateCustomClass(&PluginBase->pl_LibNode, MUIC_Group, + NULL, sizeof(struct FileTypesPrefsInst), DISPATCHER_REF(FileTypesPrefs)); + + d1(kprintf("%s/%ld: FileTypesPrefsClass=%08lx\n", __FUNC__, __LINE__, FileTypesPrefsClass)); + if (NULL == FileTypesPrefsClass) + return FALSE; + + d1(kprintf("%s/%ld: FileTypesPrefsCatalog=%08lx\n", __FUNC__, __LINE__, FileTypesPrefsCatalog)); + + d1(kprintf("%s/%ld: LocaleBase=%08lx\n", __FUNC__, __LINE__, LocaleBase)); + + if (LocaleBase) + { + d1(kprintf("%s/%ld: FileTypesPrefsLocale=%08lx\n", __FUNC__, __LINE__, FileTypesPrefsLocale)); + + if (NULL == FileTypesPrefsLocale) + FileTypesPrefsLocale = OpenLocale(NULL); + + d1(kprintf("%s/%ld: FileTypesPrefsLocale=%08lx\n", __FUNC__, __LINE__, FileTypesPrefsLocale)); + + if (FileTypesPrefsLocale) + { + d1(kprintf("%s/%ld: FileTypesPrefsCatalog=%08lx\n", __FUNC__, __LINE__, FileTypesPrefsCatalog)); + + if (NULL == FileTypesPrefsCatalog) + { + FileTypesPrefsCatalog = OpenCatalog(FileTypesPrefsLocale, + (STRPTR) "Scalos/ScalosFileTypes.catalog", NULL); + + d1(kprintf("%s/%ld: \n", __FUNC__, __LINE__)); + } + } + } + + if (!StaticsTranslated) + { + StaticsTranslated = TRUE; + + TranslateNewMenu(ContextMenuFileTypes); + TranslateNewMenu(ContextMenuFileTypesActions); + TranslateNewMenu(ContextMenus); + TranslateNewMenu(ContextMenusAttrList); + TranslateStringArray(RegisterTitles); + TranslateStringArray(AddFileTypeActionStrings); + TranslateStringArray(AddFileTypeActionStringsProject); + TranslateStringArray(AddFileTypeActionStringsDisk); + TranslateStringArray(FileTypeActionProtectionStrings); + } + + if (NULL == myFileTypesNListTreeClass) + { + myFileTypesNListTreeClass = MUI_CreateCustomClass(NULL, MUIC_NListtree, + NULL, 0, DISPATCHER_REF(myFileTypesNListTree)); + } + if (NULL == myFileTypesNListTreeClass) + return FALSE; // Failure + + if (NULL == myNListTreeClass) + { + myNListTreeClass = MUI_CreateCustomClass(NULL, MUIC_NListtree, + NULL, 0, DISPATCHER_REF(myNListTree)); + } + if (NULL == myNListTreeClass) + return FALSE; // Failure + + if (NULL == myFileTypesActionsNListClass) + { + myFileTypesActionsNListClass = MUI_CreateCustomClass(NULL, MUIC_NList, + NULL, 0, DISPATCHER_REF(myFileTypesActionsNList)); + } + if (NULL == myFileTypesActionsNListClass) + return FALSE; // Failure + + if (NULL == myNListClass) + { + myNListClass = MUI_CreateCustomClass(NULL, MUIC_NList, + NULL, 0, DISPATCHER_REF(myNList)); + } + if (NULL == myNListClass) + return FALSE; // Failure + + if (NULL == IconobjectClass) + { + IconobjectClass = InitIconobjectClass(); + } + if (NULL == IconobjectClass) + return FALSE; // Failure + + if (NULL == DataTypesImageClass) + DataTypesImageClass = InitDtpicClass(); + d1(KPrintF(__FUNC__ "/%ld: DataTypesImageClass=%08lx\n", __LINE__, DataTypesImageClass)); + if (NULL == DataTypesImageClass) + return FALSE; // Failure + + d1(KPrintF("%s/%ld: Success\n", __FUNC__, __LINE__)); + + return TRUE; // Success +} + +//---------------------------------------------------------------------------- + +static ULONG DoDragDrop(Class *cl, Object *obj, Msg msg) +{ + struct FileTypesPrefsInst *inst; + struct MUI_NListtree_TreeNode *tnTo, *tnFrom; + + get(obj, MUIA_NList_PrivateData, &inst); + + get(obj, MUIA_NListtree_DropTarget, &tnTo); + + tnFrom = MUIV_NListtree_Active_Off; + get(obj, MUIA_NListtree_Active, &tnFrom); + + d1(kprintf(__FILE__ "/%s/%ld: tnFrom=%08lx tnTo=%08lx\n", __FUNC__, __LINE__, tnFrom, tnTo)); + + if (tnTo && tnFrom && tnTo != tnFrom && MUIV_NListtree_Active_Off != tnFrom) + { + struct MUI_NListtree_TreeNode *oldListNode; + + oldListNode = (struct MUI_NListtree_TreeNode *) DoMethod(obj, + MUIM_NListtree_GetEntry, + tnFrom, + MUIV_NListtree_GetEntry_Position_Parent, + 0); + + if (MayPasteOnto(inst, tnTo, tnFrom)) + { + DoMethod(obj, MUIM_NListtree_Move, + oldListNode, + tnFrom, + tnTo, + MUIV_NListtree_Move_NewTreeNode_Tail, + 0); + EntryHasChanged(inst, tnFrom); + EntryHasChanged(inst, tnTo); + } + else + { + tnTo = MayPasteBelow(inst, tnTo, tnFrom); + if (tnTo) + { + struct MUI_NListtree_TreeNode *newListNode; + + newListNode = (struct MUI_NListtree_TreeNode *) DoMethod(obj, + MUIM_NListtree_GetEntry, + tnTo, + MUIV_NListtree_GetEntry_Position_Parent, + 0); + + DoMethod(obj, MUIM_NListtree_Move, + oldListNode, + tnFrom, + newListNode, + tnTo, + 0); + EntryHasChanged(inst, tnFrom); + EntryHasChanged(inst, tnTo); + } + } + } + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT OpenHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + + if (NULL == inst->fpb_LoadReq) + { + inst->fpb_LoadReq = MUI_AllocAslRequestTags(ASL_FileRequest, + ASLFR_InitialFile, "deficons.prefs", + ASLFR_Flags1, FRF_DOPATTERNS, + ASLFR_InitialDrawer, "SYS:Prefs/presets", + ASLFR_InitialPattern, "#?.(pre|prefs)", + ASLFR_UserData, inst, + ASLFR_IntuiMsgFunc, &inst->fpb_Hooks[HOOKNDX_AslIntuiMsg], + TAG_END); + } + + if (inst->fpb_LoadReq) + { + BOOL Result; + struct Window *win = NULL; + + get(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Window, &win); + + //AslRequest( + Result = MUI_AslRequestTags(inst->fpb_LoadReq, + ASLFR_Window, win, + ASLFR_SleepWindow, TRUE, + ASLFR_TitleText, GetLocString(MSGID_MENU_PROJECT_OPEN), + TAG_END); + + if (Result) + { + BPTR dirLock = Lock(inst->fpb_LoadReq->fr_Drawer, ACCESS_READ); + + if (dirLock) + { + BPTR oldDir = CurrentDir(dirLock); + + InitDefIcons(inst, inst->fpb_LoadReq->fr_File); + + CurrentDir(oldDir); + UnLock(dirLock); + } + } + } + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT SaveAsHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + + if (NULL == inst->fpb_SaveReq) + { + inst->fpb_SaveReq = MUI_AllocAslRequestTags(ASL_FileRequest, + ASLFR_InitialFile, "deficons.prefs", + ASLFR_DoSaveMode, TRUE, + ASLFR_InitialDrawer, "SYS:Prefs/presets", + ASLFR_UserData, inst, + ASLFR_IntuiMsgFunc, &inst->fpb_Hooks[HOOKNDX_AslIntuiMsg], + TAG_END); + } + + if (inst->fpb_SaveReq) + { + BOOL Result; + struct Window *win = NULL; + + get(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Window, &win); + + //AslRequest( + Result = MUI_AslRequestTags(inst->fpb_SaveReq, + ASLFR_TitleText, GetLocString(MSGID_MENU_PROJECT_SAVEAS), + ASLFR_Window, win, + ASLFR_SleepWindow, TRUE, + TAG_END); + + if (Result) + { + BPTR dirLock = Lock(inst->fpb_SaveReq->fr_Drawer, ACCESS_READ); + + if (dirLock) + { + BPTR oldDir = CurrentDir(dirLock); + + WriteDefIconsPrefs(inst, inst->fpb_SaveReq->fr_File); + + CurrentDir(oldDir); + UnLock(dirLock); + } + } + } + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT AslIntuiMsgHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + struct IntuiMessage *iMsg = (struct IntuiMessage *) msg; + + if (IDCMP_REFRESHWINDOW == iMsg->Class) + { + DoMethod(inst->fpb_Objects[OBJNDX_APP_Main], MUIM_Application_CheckRefresh); + } +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT ShowFindGroupHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + + (void) hook; + (void) o; + (void) msg; + + CleanupFoundNodes(inst); + + setstring(inst->fpb_Objects[OBJNDX_String_FindFileType], ""); + + set(inst->fpb_Objects[OBJNDX_Menu_Find], MUIA_Menuitem_Enabled, FALSE); + set(inst->fpb_Objects[OBJNDX_Group_FindFiletype], MUIA_ShowMe, TRUE); + + set(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_ActiveObject, + inst->fpb_Objects[OBJNDX_String_FindFileType]); + +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT HideFindGroupHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + + (void) hook; + (void) o; + (void) msg; + + CleanupFoundNodes(inst); + + set(inst->fpb_Objects[OBJNDX_Menu_Find], MUIA_Menuitem_Enabled, TRUE); + set(inst->fpb_Objects[OBJNDX_Group_FindFiletype], MUIA_ShowMe, FALSE); +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT IncrementalFindFileTypeHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + CONST_STRPTR FindString = NULL; + + (void) hook; + (void) o; + (void) msg; + + get(inst->fpb_Objects[OBJNDX_String_FindFileType], MUIA_String_Contents, &FindString); + + if (FindString && strlen(FindString) > 0) + { + set(inst->fpb_Objects[OBJNDX_Button_FindNextFileType], MUIA_Disabled, FALSE); + set(inst->fpb_Objects[OBJNDX_Button_FindPrevFileType], MUIA_Disabled, FALSE); + + IncrementalSearchFileType(inst, FindString, FINDDIR_First); + } + else + { + CleanupFoundNodes(inst); + set(inst->fpb_Objects[OBJNDX_Button_FindNextFileType], MUIA_Disabled, TRUE); + set(inst->fpb_Objects[OBJNDX_Button_FindPrevFileType], MUIA_Disabled, TRUE); + set(inst->fpb_Objects[OBJNDX_Button_FindHitCount], MUIA_Text_Contents, ""); + } +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT IncrementalFindNextFileTypeHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + CONST_STRPTR FindString = NULL; + + (void) hook; + (void) o; + (void) msg; + + get(inst->fpb_Objects[OBJNDX_String_FindFileType], MUIA_String_Contents, &FindString); + + if (FindString && strlen(FindString) > 0) + { + IncrementalSearchFileType(inst, FindString, FINDDIR_Next); + } + +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT IncrementalFindPrevFileTypeHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + CONST_STRPTR FindString = NULL; + + (void) hook; + (void) o; + (void) msg; + + get(inst->fpb_Objects[OBJNDX_String_FindFileType], MUIA_String_Contents, &FindString); + + if (FindString && strlen(FindString) > 0) + { + IncrementalSearchFileType(inst, FindString, FINDDIR_Prev); + } + +} + +//---------------------------------------------------------------------------- + +static BOOL IncrementalSearchFileType(struct FileTypesPrefsInst *inst, + CONST_STRPTR SearchString, enum FindDir dir) +{ + BOOL Found = FALSE; + BOOL CaseSensitive = FALSE; + + do { + struct MUI_NListtree_TreeNode *tn = NULL; + Object *ActiveObject; + + if (SearchString == NULL || strlen(SearchString) < 1) + { + CleanupFoundNodes(inst); + break; + } + + get(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_ActiveObject, &ActiveObject); + + /* + * When searching for next one, fetch selected one first. + */ + + if (FINDDIR_Next == dir) + { + d1(kprintf(__FILE__ "/%s/%ld: fpb_CurrentFound=%08lx\n", __FUNC__, __LINE__, inst->fpb_CurrentFound)); + + if (inst->fpb_CurrentFound != (struct FoundNode *) &inst->fpb_FoundList.lh_Tail) + inst->fpb_CurrentFound = (struct FoundNode *) inst->fpb_CurrentFound->fdn_Node.ln_Succ; + + if (inst->fpb_CurrentFound != (struct FoundNode *) &inst->fpb_FoundList.lh_Tail) + tn = inst->fpb_CurrentFound->fdn_TreeNode; + else + tn = NULL; + + d1(kprintf(__FILE__ "/%s/%ld: fpb_CurrentFound=%08lx tn=%08lx\n", __FUNC__, __LINE__, inst->fpb_CurrentFound, tn)); + } + else if (FINDDIR_Prev == dir) + { + d1(kprintf(__FILE__ "/%s/%ld: fpb_CurrentFound=%08lx\n", __FUNC__, __LINE__, inst->fpb_CurrentFound)); + + if (inst->fpb_CurrentFound != (struct FoundNode *) &inst->fpb_FoundList.lh_Head) + inst->fpb_CurrentFound = (struct FoundNode *) inst->fpb_CurrentFound->fdn_Node.ln_Pred; + + if (inst->fpb_CurrentFound != (struct FoundNode *) &inst->fpb_FoundList.lh_Head) + tn = inst->fpb_CurrentFound->fdn_TreeNode; + else + tn = NULL; + + d1(kprintf(__FILE__ "/%s/%ld: fpb_CurrentFound=%08lx tn=%08lx\n", __FUNC__, __LINE__, inst->fpb_CurrentFound, tn)); + } + else + { + ULONG dosearch = TRUE; + + d1(kprintf(__FILE__ "/%s/%ld:\n", __FUNC__, __LINE__)); + + CleanupFoundNodes(inst); + + BuildFindTree(inst, + inst->fpb_Objects[OBJNDX_NListtree_FileTypes], + MUIV_NListtree_GetEntry_ListNode_Root, + SearchString, + MUIV_NListtree_GetEntry_Position_Head, + &dosearch, CaseSensitive); + + if (IsListEmpty(&inst->fpb_FoundList)) + { + d1(kprintf(__FILE__ "/%s/%ld:\n", __FUNC__, __LINE__)); + tn = NULL; + inst->fpb_CurrentFound = (struct FoundNode *) &inst->fpb_FoundList.lh_Tail; + } + else + { + d1(kprintf(__FILE__ "/%s/%ld:\n", __FUNC__, __LINE__)); + inst->fpb_CurrentFound = (struct FoundNode *) inst->fpb_FoundList.lh_Head; + tn = inst->fpb_CurrentFound->fdn_TreeNode; + } + d1(kprintf(__FILE__ "/%s/%ld: fpb_CurrentFound=%08lx tn=%08lx\n", __FUNC__, __LINE__, inst->fpb_CurrentFound, tn)); + + snprintf(inst->fpb_FindHitCount, sizeof(inst->fpb_FindHitCount), + GetLocString(MSGID_FIND_HITCOUNT_FMT), inst->fpb_FoundCount); + set(inst->fpb_Objects[OBJNDX_Button_FindHitCount], MUIA_Text_Contents, inst->fpb_FindHitCount); + } + + if (NULL == tn) + { + // nothing found + set(inst->fpb_Objects[OBJNDX_Button_FindNextFileType], MUIA_Disabled, TRUE); + set(inst->fpb_Objects[OBJNDX_Button_FindPrevFileType], MUIA_Disabled, TRUE); + set(inst->fpb_Objects[OBJNDX_Button_FindHitCount], MUIA_Text_Contents, ""); + break; + } + + Found = TRUE; + /* + * Open node if needed and select. + */ + DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], + MUIM_NListtree_Open, + MUIV_NListtree_Open_ListNode_Parent, + tn, + 0); + set(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], MUIA_NListtree_Active, tn); + + set(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_ActiveObject, ActiveObject); + + set(inst->fpb_Objects[OBJNDX_Button_FindNextFileType], MUIA_Disabled, + inst->fpb_CurrentFound->fdn_Node.ln_Succ == (struct Node *) &inst->fpb_FoundList.lh_Tail); + + set(inst->fpb_Objects[OBJNDX_Button_FindPrevFileType], MUIA_Disabled, + inst->fpb_CurrentFound->fdn_Node.ln_Pred == (struct Node *) &inst->fpb_FoundList.lh_Head); + } while (0); + + return Found; +} + +//---------------------------------------------------------------------------- + +static void BuildFindTree(struct FileTypesPrefsInst *inst, + Object *ListTree, + struct MUI_NListtree_TreeNode *list, CONST_STRPTR pattern, + struct MUI_NListtree_TreeNode *startnode, + ULONG *dosearch, BOOL CaseSensitive) +{ + ULONG pos; + + for (pos = 0; ; pos++) + { + struct MUI_NListtree_TreeNode *tn; + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(ListTree, + MUIM_NListtree_GetEntry, + list, + pos, + MUIV_NListtree_GetEntry_Flag_SameLevel); + + if (NULL == tn) + break; + + if (tn->tn_Flags & TNF_LIST) + { + // Current node is a list + if (*dosearch) + { + // Check if list node matches + CONST_STRPTR Found; + + Found = FindString(tn->tn_Name, pattern, CaseSensitive); + + if (Found) + { + struct FileTypesEntry *fte = (struct FileTypesEntry *) tn->tn_User; + + fte->fte_FindLength = strlen(pattern); + fte->fte_FindStart = Found - tn->tn_Name; + + DoMethod(ListTree, MUIM_NListtree_Redraw, tn, 0); + AddFoundNode(inst, ListTree, tn); + } + } + + // check children for matches + BuildFindTree(inst, + ListTree, + tn, + pattern, + startnode, + dosearch, + CaseSensitive); + } + + if ( tn == startnode ) + *dosearch = TRUE; + } +} + +//---------------------------------------------------------------------------- + +static CONST_STRPTR FindString(CONST_STRPTR string, CONST_STRPTR pattern, BOOL CaseSensitive) +{ + while (*string) + { + size_t i; + + for(i = 0 ; ; i++) + { + char c = pattern[i]; + + /* End of substring? We got a match... */ + if ('\0' == c) + { + return string; + } + + if (CaseSensitive) + { + if (c != string[i]) + break; + } + else + { + if (ToLower(c) != ToLower(string[i])) + break; + } + } + + string++; + } + + return NULL; +} + +//---------------------------------------------------------------------------- + +static struct FoundNode *AddFoundNode(struct FileTypesPrefsInst *inst, Object *ListTree, struct MUI_NListtree_TreeNode *tn) +{ + struct FoundNode *fdn; + + d1(kprintf(__FILE__ "/%s/%ld: <%s>\n", __FUNC__, __LINE__, tn->tn_Name)); + + fdn = malloc(sizeof(struct FoundNode)); + if (fdn) + { + fdn->fdn_ListTree = ListTree; + fdn->fdn_TreeNode = tn; + fdn->fdn_Index = ++inst->fpb_FoundCount; + + AddTail(&inst->fpb_FoundList, &fdn->fdn_Node); + } + + return fdn; +} + +//---------------------------------------------------------------------------- + +void CleanupFoundNodes(struct FileTypesPrefsInst *inst) +{ + struct FoundNode *fdn; + + d1(kprintf(__FILE__ "/%s/%ld:\n", __FUNC__, __LINE__)); + + while ( (fdn = (struct FoundNode *) RemHead(&inst->fpb_FoundList)) ) + { + struct FileTypesEntry *fte = (struct FileTypesEntry *) fdn->fdn_TreeNode->tn_User; + + fte->fte_FindLength = 0; + fte->fte_FindStart = 0; + DoMethod(fdn->fdn_ListTree, MUIM_NListtree_Redraw, fdn->fdn_TreeNode, 0); + + free(fdn); + } + + inst->fpb_FoundCount = 0; + + set(inst->fpb_Objects[OBJNDX_Button_FindNextFileType], MUIA_Disabled, TRUE); + set(inst->fpb_Objects[OBJNDX_Button_FindPrevFileType], MUIA_Disabled, TRUE); + set(inst->fpb_Objects[OBJNDX_Button_FindHitCount], MUIA_Text_Contents, ""); +} + +//---------------------------------------------------------------------------- + +void UpdateMenuImage(struct FileTypesPrefsInst *inst, ULONG ListTree, struct FileTypesListEntry *fte) +{ + char UnSelIconName[MAX_ATTRVALUE]; + + if (fte->fte_ImageObject) + { + DoMethod(inst->fpb_Objects[ListTree], + MUIM_NList_UseImage, NULL, fte->fte_ImageIndex, 0); + + MUI_DisposeObject(fte->fte_ImageObject); + fte->fte_ImageObject = NULL; + } + + GetAttributeValueString(FindAttribute(fte, ATTRTYPE_UnselIconName), UnSelIconName, sizeof(UnSelIconName)); + if (strlen(UnSelIconName) > 0) + { + fte->fte_ImageObject = DataTypesImageObject, + MUIA_ScaDtpic_Name, (ULONG) UnSelIconName, + MUIA_ScaDtpic_FailIfUnavailable, TRUE, + End; //DataTypesMCCObject + + if (fte->fte_ImageObject) + { + if (0 == fte->fte_ImageIndex) + fte->fte_ImageIndex = ++inst->fpb_MenuImageIndex; + + DoMethod(inst->fpb_Objects[ListTree], + MUIM_NList_UseImage, fte->fte_ImageObject, fte->fte_ImageIndex, 0); + } + } +} + +//---------------------------------------------------------------------------- + +#if !defined(__SASC) && ! defined(__amigaos4__) +// Replacement for SAS/C library functions + +#if !defined(__MORPHOS__) && !defined(__AROS__) +static size_t stccpy(char *dest, const char *src, size_t MaxLen) +{ + size_t Count = 0; + + while (*src && MaxLen > 1) + { + *dest++ = *src++; + MaxLen--; + Count++; + } + *dest = '\0'; + Count++; + + return Count; +} +#endif /* __MORPHOS__ */ + +void exit(int x) +{ + (void) x; + while (1) + ; +} + +APTR _WBenchMsg; + +#endif /* !__SASC && !__amigaos4__ */ + +//---------------------------------------------------------------------------- diff --git a/scalos/Plugins/Prefs/FileTypes/FileTypesPrefs.h b/scalos/Plugins/Prefs/FileTypes/FileTypesPrefs.h new file mode 100644 index 000000000..9ebc34103 --- /dev/null +++ b/scalos/Plugins/Prefs/FileTypes/FileTypesPrefs.h @@ -0,0 +1,549 @@ +// FileTypesPrefs.h +// $Date$ +// $Revision$ + + +#ifndef SCALOS_FILETYPESPREFS_H +#define SCALOS_FILETYPESPREFS_H + +//---------------------------------------------------------------------------- + +#include "DefIcons.h" + +//---------------------------------------------------------------------------- + +// Include nesting limit for filetype descriptions +#define MAX_INCLUDE_NESTING 10 + +#define MAX_ATTRNAME 50 +#define MAX_ATTRVALUE 512 + +#define MAX_FTE_NAME 100 + +#define MAX_FILENAME 512 + +//---------------------------------------------------------------------------- + +#define FIBF_HIDDEN (1 << 7) + +//---------------------------------------------------------------------------- + +// Flags for writing FileTypes +#define FTWRITEFLAG_NONE 0x00000000 +#define FTWRITEFLAG_ONLY_SAVE_CHANGED 0x00000001 +#define FTWRITEFLAG_CLEAR_CHANGE_FLAG 0x00000002 + +//---------------------------------------------------------------------------- + +enum HookIndex +{ + HOOKNDX_Open = 1, + HOOKNDX_SaveAs, + + HOOKNDX_TreeDisplay, + HOOKNDX_TreeConstruct, + HOOKNDX_TreeDestruct, + + HOOKNDX_AttrDisplay, + HOOKNDX_AttrConstruct, + HOOKNDX_AttrDestruct, + + HOOKNDX_AddEntryListDisplay, + HOOKNDX_AddEntryListConstruct, + HOOKNDX_AddEntryListDestruct, + + HOOKNDX_AddAttrListDisplay, + HOOKNDX_AddAttrListConstruct, + HOOKNDX_AddAttrListDestruct, + + HOOKNDX_EditAttributeListDisplay, + HOOKNDX_EditAttributeListConstruct, + HOOKNDX_EditAttributeListDestruct, + + HOOKNDX_FileTypesDisplay, + HOOKNDX_FileTypesConstruct, + HOOKNDX_FileTypesDestruct, + + HOOKNDX_FileTypesActionDisplay, + HOOKNDX_FileTypesActionConstruct, + HOOKNDX_FileTypesActionDestruct, + + HOOKNDX_SelectEntry, + HOOKNDX_SelectAttribute, + HOOKNDX_EditAttribute, + + HOOKNDX_About, + HOOKNDX_ContextMenuTrigger, + + HOOKNDX_Collapse, + HOOKNDX_Expand, + HOOKNDX_CollapseAll, + HOOKNDX_ExpandAll, + + HOOKNDX_CollapseFileTypes, + HOOKNDX_ExpandFileTypes, + HOOKNDX_CollapseAllFileTypes, + HOOKNDX_ExpandAllFileTypes, + + HOOKNDX_Copy, + HOOKNDX_Cut, + HOOKNDX_Paste, + + HOOKNDX_CopyAttr, + HOOKNDX_CutAttr, + HOOKNDX_PasteAttr, + + HOOKNDX_AddEntry, + HOOKNDX_AddAttribute, + HOOKNDX_RemoveEntry, + HOOKNDX_RemoveAttribute, + + HOOKNDX_ChangeAttribute, + + HOOKNDX_SelectAttributeValue, + + HOOKNDX_EditAttributePopAslFileStartHook, + HOOKNDX_EditAttributePopAslPathStartHook, + + HOOKNDX_EditAttributeTTFontOpen, + HOOKNDX_EditAttributeTTFontClose, + + HOOKNDX_ResetToDefaults, + HOOKNDX_LastSaved, + HOOKNDX_Restore, + + HOOKNDX_HideEmptyEntries, + + HOOKNDX_SelectFileTypesEntry, + HOOKNDX_SelectFileTypesActionEntry, + + HOOKNDX_RenameFileType, + + HOOKNDX_AddFileType, + HOOKNDX_RemoveFileType, + + HOOKNDX_AddFileTypesMethod, + HOOKNDX_RemoveFileTypeAction, + + HOOKNDX_ChangedFileTypesActionMatchMatch, + HOOKNDX_ChangedFileTypesActionMatchCase, + HOOKNDX_ChangedFileTypesActionMatchOffset, + HOOKNDX_ChangedFileTypesActionSearchSearch, + HOOKNDX_ChangedFileTypesActionSearchCase, + HOOKNDX_ChangedFileTypesActionSearchSkipSpaces, + HOOKNDX_ChangedFileTypesActionFilesize, + HOOKNDX_ChangedFileTypesActionPattern, + HOOKNDX_ChangedFileTypesActionProtection, + HOOKNDX_ChangedFileTypesActionDosDevice, + HOOKNDX_ChangedFileTypesActionDeviceName, + HOOKNDX_ChangedFileTypesActionContents, + HOOKNDX_ChangedFileTypesActionDosType, + HOOKNDX_ChangedFileTypesActionMinSize, + + HOOKNDX_DragDropSort_FileTypesAction, + + HOOKNDX_ShowFindGroup, + HOOKNDX_HideFindGroup, + HOOKNDX_IncrementalFindFileType, + HOOKNDX_IncrementalFindNextFileType, + HOOKNDX_IncrementalFindPrevFileType, + + HOOKNDX_Learn_FileType, + + HOOKNDX_CreateNewFileTypesIcon, + HOOKNDX_EditFileTypesIcon, + + HOOKNDX_AslIntuiMsg, + + HOOKNDX_MAX +}; + +enum ObjectIndex +{ + OBJNDX_APP_Main, + OBJNDX_WIN_Main, + + OBJNDX_MainListView, + OBJNDX_MainListTree, + + OBJNDX_HiddenListView, + OBJNDX_HiddenListTree, + + OBJNDX_ShadowListView, + OBJNDX_ShadowListTree, + OBJNDX_ShadowAttrListView, + OBJNDX_ShadowAttrList, + + OBJNDX_AttrList, + OBJNDX_AttrListView, + + OBJNDX_ButtonAddEntry, + OBJNDX_ButtonRemoveEntry, + OBJNDX_ButtonAddAttribute, + OBJNDX_ButtonRemoveAttribute, + OBJNDX_ButtonEditAttribute, + OBJNDX_ButtonChangeAttribute, + OBJNDX_ButtonKeepAttribute, + + OBJNDX_AddEntryPopObject, + OBJNDX_AddEntryList, + OBJNDX_AddEntryListView, + + OBJNDX_AddAttrPopObject, + OBJNDX_AddAttrListView, + OBJNDX_AddAttrList, + + OBJNDX_ContextMenuFileTypes, + OBJNDX_ContextMenuFileTypesActions, + OBJNDX_ContextMenu, + OBJNDX_ContextMenuAttrList, + OBJNDX_Menu_Expand, + OBJNDX_Menu_Collapse, + OBJNDX_Menu_Copy, + OBJNDX_Menu_Cut, + OBJNDX_Menu_Paste, + + OBJNDX_Menu_Find, + + OBJNDX_Menu_CopyAttr, + OBJNDX_Menu_CutAttr, + OBJNDX_Menu_PasteAttr, + + OBJNDX_Menu_ExpandFileTypes, + OBJNDX_Menu_CollapseFileTypes, + + OBJNDX_Menu_HideEmptyEntries, + + OBJNDX_Text_AttributeName, + OBJNDX_Pop_AttributeSelectValue, + OBJNDX_Listview_AttributeSelectValue, + OBJNDX_Group_AttributeSelectValue, + OBJNDX_List_AttributeSelectValue, + OBJNDX_String_AttributeValue, + OBJNDX_Group_AttributeValue, + OBJNDX_Pop_AttributeSelectAslFile, + OBJNDX_DtPic_AttributeSelectAslFile, + OBJNDX_Group_AttributeAslFile, + OBJNDX_Pop_AttributeSelectAslPath, + OBJNDX_Group_AttributeAslPath, + OBJNDX_Group_AttributeAslFont, + OBJNDX_Pop_AttributeSelectAslFont, + OBJNDX_AslFont_Sample, + OBJNDX_Pop_AttributeSelectTTFont, + OBJNDX_Group_AttributeTTFont, + OBJNDX_TTFont_Sample, + + OBJNDX_Lamp_Changed, + + OBJNDX_Group_Main, + + // make sure ALL OBJNDX_Group_Filetypes_Actions_** entries are contiguous + OBJNDX_Group_Filetypes_Actions_Protection, + OBJNDX_Group_Filetypes_Actions_Pattern, + OBJNDX_Group_Filetypes_Actions_Filesize, + OBJNDX_Group_Filetypes_Actions_Search, + OBJNDX_Group_Filetypes_Actions_Match, + OBJNDX_Group_Filetypes_Actions_Empty, + OBJNDX_Group_FileTypes_Action_MinSizeMB, + OBJNDX_Group_Filetypes_Actions_DosDevice, + OBJNDX_Group_Filetypes_Actions_DeviceName, + OBJNDX_Group_Filetypes_Actions_Contents, + OBJNDX_Group_Filetypes_Actions_DosType, + + OBJNDX_Cycle_Filetypes_Protection_R, + OBJNDX_Cycle_Filetypes_Protection_W, + OBJNDX_Cycle_Filetypes_Protection_E, + OBJNDX_Cycle_Filetypes_Protection_D, + OBJNDX_Cycle_Filetypes_Protection_S, + OBJNDX_Cycle_Filetypes_Protection_P, + OBJNDX_Cycle_Filetypes_Protection_A, + OBJNDX_Cycle_Filetypes_Protection_H, + + OBJNDX_Text_FileTypes_FileTypesName, + OBJNDX_IconObjectMCC_FileTypes_Icon, + OBJNDX_Text_FileTypes_DefIconName, + OBJNDX_Button_FileTypes_CreateIcon, + OBJNDX_Button_FileTypes_EditIcon, + + OBJNDX_NListview_FileTypes, + OBJNDX_NListtree_FileTypes, + OBJNDX_String_FileTypes_Name, + OBJNDX_Button_FileTypes_Add, + OBJNDX_Button_FileTypes_Remove, + + OBJNDX_NListview_FileTypes_Methods, + OBJNDX_NList_FileTypes_Actions, + + OBJNDX_Popobject_FileTypes_Methods_Add, + OBJNDX_NListview_FileTypes_Methods_Add, + OBJNDX_Nlist_FileTypes_Methods_Add, + + OBJNDX_Button_FileTypes_Actions_Remove, + OBJNDX_Button_FileTypes_Actions_Learn, + + OBJNDX_String_Filetypes_Actions_Match_Offset, + OBJNDX_Checkmark_FileTypes_Action_Match_Case, + OBJNDX_String_Filetypes_Actions_Match_Match, + + OBJNDX_Checkmark_FileTypes_Action_Search_SkipSpaces, + OBJNDX_Checkmark_FileTypes_Action_Search_Case, + OBJNDX_String_FileTypes_Action_Search_Search, + + OBJNDX_String_FileTypes_Action_Filesize_Filesize, + + OBJNDX_String_FileTypes_Action_MinSizeMB_MinSize, + + OBJNDX_String_FileTypes_Action_Pattern_Pattern, + + OBJNDX_String_FileTypes_Action_DosDevice_Pattern, + + OBJNDX_String_FileTypes_Action_DeviceName_Pattern, + + OBJNDX_String_FileTypes_Action_Contents_Pattern, + + OBJNDX_String_FileTypes_Action_DosType_Pattern, + + OBJNDX_Group_FindFiletype, + OBJNDX_Button_HideFind, + OBJNDX_String_FindFileType, + OBJNDX_Button_FindNextFileType, + OBJNDX_Button_FindPrevFileType, + OBJNDX_Button_FindHitCount, + + OBJNDX_WIN_EditAttribute, + + OBJNDX_MAX +}; + +enum FileTypeDefSections + { + FTSECTION_All, + FTSECTION_PopupMenu, + FTSECTION_Tooltip, + }; + +struct FileTypeFileDesc + { + ULONG ftfd_LineNumber; + BPTR ftfd_FileHandle; + }; + +enum ftAttributeType + { + ATTRTYPE_FtDescription = 1, // char[] + ATTRTYPE_PvPluginName, // char[] + + ATTRTYPE_GroupOrientation, // enum TTLayoutMode + + ATTRTYPE_MemberHideString, // char[] + + ATTRTYPE_StringHAlign, // char[] + ATTRTYPE_StringVAlign, // char[] + ATTRTYPE_StringStyle, // char[] + ATTRTYPE_StringFont, // char[] + ATTRTYPE_StringTTFont, // char[] + ATTRTYPE_StringPen, // char[] + ATTRTYPE_StringId, // char[] + ATTRTYPE_StringText, // char[] + ATTRTYPE_StringSrc, // char[] + + ATTRTYPE_SpaceSize, // ULONG + + ATTRTYPE_DtImageName, // char[] + ATTRTYPE_UnselIconName, // char[] + ATTRTYPE_SelIconName, // char[] + + ATTRTYPE_MenuItemName, // char[] + ATTRTYPE_MenuCommKey, // char[] + ATTRTYPE_MenuDefaultAction, // ./. + + ATTRTYPE_CommandName, // char[] + ATTRTYPE_CommandStacksize, // ULONG + ATTRTYPE_CommandPriority, // ULONG + ATTRTYPE_CommandWbArgs, // ./. + }; + +struct FtAttribute + { + struct Node fta_Node; + + enum ftAttributeType fta_Type; + ULONG fta_Value2; + ULONG fta_Length; + BYTE fta_Data[1]; + }; + +struct AttrListEntry + { + char ale_ValueString[MAX_ATTRVALUE]; + struct FtAttribute ale_Attribute; + }; + + +enum FtEntryType + { + ENTRYTYPE_FileType, + + ENTRYTYPE_PopupMenu, + ENTRYTYPE_PopupMenu_SubMenu, + ENTRYTYPE_PopupMenu_MenuItem, + ENTRYTYPE_PopupMenu_InternalCmd, + ENTRYTYPE_PopupMenu_WbCmd, + ENTRYTYPE_PopupMenu_ARexxCmd, + ENTRYTYPE_PopupMenu_CliCmd, + ENTRYTYPE_PopupMenu_PluginCmd, + ENTRYTYPE_PopupMenu_IconWindowCmd, + ENTRYTYPE_PopupMenu_MenuSeparator, + + ENTRYTYPE_ToolTip, + ENTRYTYPE_ToolTip_Group, + ENTRYTYPE_ToolTip_Member, + ENTRYTYPE_ToolTip_HBar, + ENTRYTYPE_ToolTip_String, + ENTRYTYPE_ToolTip_Space, + ENTRYTYPE_ToolTip_DtImage, + + // MUST be last entry !!! + ENTRYTYPE_MAX + }; + +enum TTLayoutMode + { + TTL_Horizontal, + TTL_Vertical + }; + +enum TTItemTypes + { + TTITYPE_Tooltip, + TTITYPE_Group, + TTITYPE_Member, + }; + +struct FileTypesToolTipEntry + { + struct MUI_NListtree_TreeNode *ftti_Parent; + }; + +struct FileTypesActionListEntry + { + struct Node ftale_Node; + struct Magic ftale_Magic; + STRPTR ftale_AllocatedString; + }; + +struct FileTypesEntry + { + ULONG fte_FindStart; // start position of find marker (0=name start) + ULONG fte_FindLength; // length of find marker (0=no marker) + + STRPTR fte_AllocatedName2; // allocated space for find marker in tn_Name + STRPTR fte_AllocatedName; // allocated space for tn_Name + struct TypeNode fte_TypeNode; + + struct List fte_MagicList; // List of FileTypesActionListEntry + }; + +struct FileTypesActionEntry + { + struct FileTypesActionListEntry *fae_ftale; + char fae_ActionAttrs[80]; + }; + + +struct FileTypesListEntry + { + char ftle_NameBuffer[MAX_FTE_NAME + MAX_ATTRVALUE]; + + enum FtEntryType ftle_EntryType; // Type of this node + + BOOL ftle_FileFound; + BOOL ftle_Changed; + + ULONG fte_ImageIndex; + Object *fte_ImageObject; + + struct List ftle_AttributesList; + + union + { + struct FileTypesToolTipEntry ftle_ToolTipEntry; + } ftle_TypeEntry; + }; + +struct FileTypesPrefsInst +{ + ULONG fpb_fCreateIcons; + ULONG fpb_PageIsActive; + BOOL fpb_Changed; + + BPTR fpb_DefIconsSegList; + struct TypeNode *fpb_RootType; + BOOL fpb_DefIconsInit; + + struct Screen *fpb_WBScreen; + + CONST_STRPTR fpb_ProgramName; + + struct Hook fpb_Hooks[HOOKNDX_MAX]; + Object *fpb_Objects[OBJNDX_MAX]; + + char fpb_FileName[MAX_FILENAME]; + char fpb_Path[MAX_FILENAME]; + + char fpb_DefIconPath[MAX_FILENAME]; + + char fpb_FindHitCount[80]; + + struct FileTypeFileDesc fpb_FileHandles[MAX_INCLUDE_NESTING]; + ULONG fpb_IncludeNesting; // index into fpb_FileHandles[] + + enum FileTypeDefSections fpb_RequestedSection; + + ULONG fpb_SaveFlags; + + BOOL fpb_HideEmptyNodes; + BOOL fpb_DefaultActionSet; + + BYTE fpb_TTfAntialias; + WORD fpb_TTfGamma; + + BOOL fpb_MenuTreeMayDrop; + + BPTR fpb_FileTypesDirLock; + + Object *fpb_IconObject; + + ULONG fpb_MenuImageIndex; + + struct List fpb_FoundList; + struct FoundNode *fpb_CurrentFound; + ULONG fpb_FoundCount; // number of entries in fpb_FoundList + + struct MUI_NListtree_TreeNode *fpb_PopupMenu; + struct MUI_NListtree_TreeNode *fpb_CurrentTTItem; + struct MUI_NListtree_TreeNode *fpb_CurrentMenuItem; + struct MUI_NListtree_TreeNode *fpb_ParentMenuItem; + + struct FileRequester *fpb_LearnReq; + struct FileRequester *fpb_LoadReq; + struct FileRequester *fpb_SaveReq; + + Object *fpb_SubWindows[2]; +}; + + +#define Sizeof(array) (sizeof(array) / sizeof((array)[0])) + +//---------------------------------------------------------------------------- + +struct ScalosFileTypes_LocaleInfo +{ + APTR li_LocaleBase; + APTR li_Catalog; + struct LocaleIFace *li_ILocale; +}; + +//---------------------------------------------------------------------------- + +#endif /* SCALOS_FILETYPESPREFS_H */ diff --git a/scalos/Plugins/Prefs/FileTypes/FileTypesPrefsImage.h b/scalos/Plugins/Prefs/FileTypes/FileTypesPrefsImage.h new file mode 100644 index 000000000..4a993a3b3 --- /dev/null +++ b/scalos/Plugins/Prefs/FileTypes/FileTypesPrefsImage.h @@ -0,0 +1,55 @@ +static const ULONG FileTypes_colors[48] = +{ + 0x22222222,0x33333333,0x33333333, + 0x9e9e9e9e,0x9e9e9e9e,0x9e9e9e9e, + 0x22222222,0x55555555,0x22222222, + 0x55555555,0x55555555,0x55555555, + 0x55555555,0x66666666,0x99999999, + 0x33333333,0x88888888,0x44444444, + 0x44444444,0x88888888,0x88888888, + 0x77777777,0x88888888,0xcccccccc, + 0x66666666,0xcccccccc,0xcccccccc, + 0xbbbbbbbb,0x44444444,0x22222222, + 0xdddddddd,0xaaaaaaaa,0x55555555, + 0xbbbbbbbb,0xbbbbbbbb,0xbbbbbbbb, + 0x99999999,0xcccccccc,0xdddddddd, + 0xcccccccc,0xaaaaaaaa,0x99999999, + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, +}; + +#define FILETYPES_WIDTH 21 +#define FILETYPES_HEIGHT 21 +#define FILETYPES_DEPTH 4 +#define FILETYPES_COMPRESSION 0 +#define FILETYPES_MASKING 2 + +#ifdef USE_FILETYPES_HEADER +static const struct BitMapHeader FileTypes_header = +{ 21,21,0,0,4,2,0,0,0,44,44,320,256 }; +#endif + +static const UBYTE FileTypes_body[336] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x40,0x00,0x80,0x00,0x40,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x40,0x00, +0x80,0x00,0x61,0xff,0xc0,0x00,0x3f,0xfe,0x40,0x00,0x00,0x00,0x00,0x00,0x21, +0xff,0xc0,0x00,0x35,0x0f,0xa0,0x00,0x1f,0x28,0x20,0x00,0x04,0x00,0x00,0x00, +0x15,0x0f,0x80,0x00,0x3d,0x1f,0x70,0x00,0x2f,0xd0,0x70,0x00,0x04,0x00,0x00, +0x00,0x2d,0x1f,0x30,0x00,0x2d,0x0e,0x70,0x00,0x27,0xc8,0x70,0x00,0x10,0x00, +0x60,0x00,0x25,0x0e,0x60,0x00,0x07,0x3d,0xf0,0x00,0x03,0xf9,0xf0,0x00,0x38, +0x11,0xe0,0x00,0x03,0x3d,0xe0,0x00,0x3f,0x3b,0xf0,0x00,0x29,0x3b,0x60,0x00, +0x04,0x03,0x60,0x00,0x25,0x3b,0x60,0x00,0x5f,0x87,0xe0,0x00,0x1e,0x87,0xe0, +0x00,0x04,0x01,0xe0,0x00,0x16,0x85,0xe0,0x00,0x77,0xce,0x40,0x00,0x76,0x4e, +0x00,0x00,0x03,0x06,0x00,0x00,0x27,0x4e,0x00,0x00,0x27,0xdf,0xc0,0x00,0x23, +0x9f,0xc0,0x00,0x04,0x9f,0xc0,0x00,0x07,0x9f,0xc0,0x00,0x3b,0xbf,0xc0,0x00, +0x29,0xbf,0xc0,0x00,0x00,0x0f,0xc0,0x00,0x21,0x1f,0xc0,0x00,0x2e,0x5e,0xc0, +0x00,0x26,0x4e,0xc0,0x00,0x00,0x44,0x40,0x00,0x26,0x4c,0x40,0x00,0x2c,0x3c, +0x20,0x00,0x2c,0x2f,0xa0,0x00,0x00,0x23,0xa0,0x00,0x24,0x7b,0xa0,0x00,0x2d, +0xa1,0x00,0x00,0x28,0x2f,0xe0,0x00,0x00,0x0f,0xe0,0x00,0x2d,0xaf,0xe0,0x00, +0x32,0xd2,0x90,0x00,0x31,0x1f,0xf0,0x00,0x01,0x1f,0xf0,0x00,0x33,0xdf,0xf0, +0x00,0x33,0xf0,0x90,0x00,0x31,0x1f,0xf0,0x00,0x15,0x1f,0xf0,0x00,0x33,0xff, +0xf0,0x00,0x2e,0xe1,0x00,0x00,0x2d,0x0f,0xe0,0x00,0x2c,0x1f,0xe0,0x00,0x23, +0xef,0xe0,0x00,0x1f,0xfb,0x20,0x00,0x1c,0x0f,0xe0,0x00,0x1c,0x0d,0xe0,0x00, +0x03,0xfd,0xe0,0x00,0x3f,0xff,0xf0,0x00,0x3c,0x0f,0xd0,0x00,0x3c,0x04,0x40, +0x00,0x03,0xfc,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00, }; diff --git a/scalos/Plugins/Prefs/FileTypes/FileTypesPrefs_proto.h b/scalos/Plugins/Prefs/FileTypes/FileTypesPrefs_proto.h new file mode 100644 index 000000000..31094346d --- /dev/null +++ b/scalos/Plugins/Prefs/FileTypes/FileTypesPrefs_proto.h @@ -0,0 +1,105 @@ +// FileTypesPrefs_proto.h +// $Date$ +// $Revision$ + + +#ifndef FILETYPESPREFS_PROTO_H +#define FILETYPESPREFS_PROTO_H + +//---------------------------------------------------------------------------- + +#include +#include + +//---------------------------------------------------------------------------- + +// defined in DefIconsPrefs.c +SAVEDS(APTR) INTERRUPT FileTypesActionConstructFunc(struct Hook *hook, APTR obj, struct NList_ConstructMessage *ltcm); +SAVEDS(void) INTERRUPT FileTypesActionDestructFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm); +SAVEDS(ULONG) INTERRUPT FileTypesActionDisplayFunc(struct Hook *hook, APTR obj, struct NList_DisplayMessage *ltdm); + +void SetFileTypesIcon(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *ln); + +SAVEDS(ULONG) INTERRUPT SelectFileTypesEntryHookFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(ULONG) INTERRUPT SelectFileTypesActionEntryHookFunc(struct Hook *hook, Object *o, Msg msg); + +SAVEDS(void) INTERRUPT ChangedFileTypesActionMatchMatchHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm); +SAVEDS(void) INTERRUPT ChangedFileTypesActionMatchCaseHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm); +SAVEDS(void) INTERRUPT ChangedFileTypesActionMatchOffsetHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm); + +SAVEDS(void) INTERRUPT ChangedFileTypesActionSearchSearchHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm); +SAVEDS(void) INTERRUPT ChangedFileTypesActionSearchCaseHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm); +SAVEDS(void) INTERRUPT ChangedFileTypesActionSearchSkipSpacesHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm); + +SAVEDS(void) INTERRUPT ChangedFileTypesActionFilesizeHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm); +SAVEDS(void) INTERRUPT ChangedFileTypesActionMinSizeHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm); +SAVEDS(void) INTERRUPT ChangedFileTypesActionPatternHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm); +SAVEDS(void) INTERRUPT ChangedFileTypesActionProtectionHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm); +SAVEDS(void) INTERRUPT ChangedFileTypesActionDosDeviceHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm); +SAVEDS(void) INTERRUPT ChangedFileTypesActionDeviceNameHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm); +SAVEDS(void) INTERRUPT ChangedFileTypesActionContentsHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm); +SAVEDS(void) INTERRUPT ChangedFileTypesActionDosTypeHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm); + +SAVEDS(void) INTERRUPT RenameFileTypeHookFunc(struct Hook *hook, APTR obj, Msg *msg); + +SAVEDS(void) INTERRUPT AddFileTypeHookFunc(struct Hook *hook, APTR obj, Msg *msg); +SAVEDS(void) INTERRUPT RemoveFileTypeHookFunc(struct Hook *hook, APTR obj, Msg *msg); + +SAVEDS(void) INTERRUPT AddFileTypesMethodHookFunc(struct Hook *hook, APTR obj, Msg msg); +SAVEDS(void) INTERRUPT AddFileTypesActionHookFunc(struct Hook *hook, APTR obj, Msg msg); +SAVEDS(void) INTERRUPT RemoveFileTypesActionHookFunc(struct Hook *hook, APTR obj, Msg *msg); + +SAVEDS(APTR) INTERRUPT FileTypesConstructFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_ConstructMessage *ltcm); +SAVEDS(void) INTERRUPT FileTypesDestructFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_DestructMessage *ltdm); +SAVEDS(ULONG) INTERRUPT FileTypesDisplayFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_DisplayMessage *ltdm); + +SAVEDS(void) INTERRUPT FileTypesActionDragDropSortHookFunc(struct Hook *hook, APTR obj, Msg msg); +SAVEDS(void) INTERRUPT LearnFileTypeHookFunc(struct Hook *hook, APTR obj, Msg msg); + +SAVEDS(void) INTERRUPT CreateNewFileTypesIconHookFunc(struct Hook *hook, APTR obj, Msg msg); +SAVEDS(void) INTERRUPT EditFileTypesIconHookFunc(struct Hook *hook, APTR obj, Msg msg); + +BOOL DisplayFileTypesIcon(struct FileTypesPrefsInst *inst, CONST_STRPTR FileTypesName); + +//---------------------------------------------------------------------------- + +// defined in FileTypesPrefs.c +CONST_STRPTR GetAttributeName(enum ftAttributeType Type); +STRPTR GetAttributeValueString(const struct FtAttribute *fta, char *Buffer, size_t BuffLen); +void HideEmptyNodes(struct FileTypesPrefsInst *inst); +STRPTR GetLocString(ULONG MsgId); +void UpdateMenuImage(struct FileTypesPrefsInst *inst, ULONG ListTree, struct FileTypesListEntry *fte); +void CleanupFoundNodes(struct FileTypesPrefsInst *inst); + +//---------------------------------------------------------------------------- + +// defined in ReadFtPrefs.c +void ReadFileTypes(struct FileTypesPrefsInst *inst, + CONST_STRPTR LoadName, CONST_STRPTR DefIconsName); +struct FtAttribute *AddAttribute(struct FileTypesListEntry *fte, + enum ftAttributeType AttrType, ULONG DataLength, const void *AttrData); +CONST_STRPTR GetNameFromEntryType(enum ftAttributeType EntryType); +void GenerateFileTypesNewEntry(struct FileTypesPrefsInst *inst, CONST_STRPTR Name); + +//---------------------------------------------------------------------------- + +// defined in WriteFtPrefs.c +LONG WriteFileTypes(struct FileTypesPrefsInst *inst, CONST_STRPTR SaveName, ULONG Flags); + +//---------------------------------------------------------------------------- + +// defined in DefIcons.c +LONG InitDefIcons(struct FileTypesPrefsInst *inst, CONST_STRPTR DefIconPrefsName); +void CleanupDefIcons(struct FileTypesPrefsInst *inst); +BOOL WriteDefIconsPrefs(struct FileTypesPrefsInst *inst, CONST_STRPTR FileName); + +//---------------------------------------------------------------------------- + +#if defined(__SASC) +int snprintf(char *, size_t, const char *, /*args*/ ...); +int vsnprintf(char *, size_t, const char *, va_list ap); +#endif /* __SASC */ + +//---------------------------------------------------------------------------- + +#endif /* FILETYPESPREFS_PROTO_H */ diff --git a/scalos/Plugins/Prefs/FileTypes/NoDebug b/scalos/Plugins/Prefs/FileTypes/NoDebug new file mode 100755 index 000000000..49ed68d29 --- /dev/null +++ b/scalos/Plugins/Prefs/FileTypes/NoDebug @@ -0,0 +1,3 @@ +; NoDebug +; 23 Dec 2001 16:17:11 +splat -s -o "d2(" "d1(" #?.c diff --git a/scalos/Plugins/Prefs/FileTypes/ReadFtPrefs.c b/scalos/Plugins/Prefs/FileTypes/ReadFtPrefs.c new file mode 100644 index 000000000..b96b1628e --- /dev/null +++ b/scalos/Plugins/Prefs/FileTypes/ReadFtPrefs.c @@ -0,0 +1,1343 @@ +// ReadFtPrefs.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define NO_INLINE_STDARG +#include + +#include +#include + +#include + +#include "debug.h" +#include "FileTypesPrefs.h" +#include "FileTypesPrefs_proto.h" + +//---------------------------------------------------------------------------- + +struct CmdFunc + { + CONST_STRPTR cf_CommandName; // Name of the command. + CONST_STRPTR cf_Template; // The command template in standard AmigaDOS syntax. + + enum FileTypeDefSections cf_validForSection; + + // Pointer to the function which implements this command. + LONG (*cf_Function)(struct FileTypesPrefsInst *, struct MUI_NListtree_TreeNode *, LONG *); + }; + +//---------------------------------------------------------------------------- + +static void ReadFileTypeDef(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn); +static LONG ReadFileTypeDefFile(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, CONST_STRPTR fileName); +static const struct CmdFunc *ParseFileTypeLine(CONST_STRPTR *Line); + +static LONG FtBeginToolTip(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray); +static LONG FtEndToolTip(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray); +static LONG FtHBar(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray); +static LONG FtBeginGroup(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray); +static LONG FtEndGroup(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray); +static LONG FtBeginMember(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray); +static LONG FtEndMember(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray); +static LONG FtString(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray); +static LONG FtSpace(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray); +static LONG FtImage(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray); +static LONG FtBeginPopupMenu(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray); +static LONG FtEndPopupMenu(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray); +static LONG FtIncludeFile(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray); +static LONG GetFtDescription(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray); +static LONG GetFtPvPlugin(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray); +static LONG AddFtMenuSeparator(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray); +static LONG NewFtMenuEntry(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray); +static LONG EndFtMenuEntry(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray); +static LONG AddSubMenuEntry(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray); +static LONG EndSubMenuEntry(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray); +static LONG FtInternalCmd(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray); +static LONG FtWbCmd(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray); +static LONG FtARexxCmd(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray); +static LONG FtCliCmd(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray); +static LONG FtPluginCmd(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray); +static LONG FtIconWindowCmd(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray); + +#if !defined(__SASC) && !defined(__MORPHOS__) && !defined(__AROS__) +static char *stpblk(const char *q); +#endif /* !defined(__SASC) && !defined(__MORPHOS__) */ + +//---------------------------------------------------------------------------- + +static const struct CmdFunc CommandTable[] = +{ + { "INCLUDE", "NAME/A", FTSECTION_All, FtIncludeFile }, + + { "DESCRIPTION", "NAME/A", FTSECTION_All, GetFtDescription }, + + { "PREVIEWPLUGIN", "NAME/A", FTSECTION_All, GetFtPvPlugin }, + + { "POPUPMENU", "", FTSECTION_PopupMenu, FtBeginPopupMenu }, + { "ENDPOPUPMENU", "", FTSECTION_PopupMenu, FtEndPopupMenu }, + + { "SUBMENU", "NAME/A,SELECTEDICON/K,UNSELECTEDICON/K", FTSECTION_PopupMenu, AddSubMenuEntry }, + { "ENDSUBMENU", "", FTSECTION_PopupMenu, EndSubMenuEntry }, + + { "MENUENTRY", "NAME/A,KEY/K,DEFAULTACTION/S,SELECTEDICON/K,UNSELECTEDICON/K", FTSECTION_PopupMenu, NewFtMenuEntry }, + { "ENDMENUENTRY", "", FTSECTION_PopupMenu, EndFtMenuEntry }, + + { "INTERNALCMD", "NAME/A", FTSECTION_PopupMenu, FtInternalCmd }, + { "WBCMD", "NAME/A,STACK/K/N,WBARGS/S,PRI=PRIORITY/K/N", FTSECTION_PopupMenu, FtWbCmd }, + { "AREXXCMD", "NAME/A,STACK/K/N,WBARGS/S,P=PRIORITY/K/N", FTSECTION_PopupMenu, FtARexxCmd }, + { "CLICMD", "NAME/A,STACK/K/N,WBARGS/S,P=PRIORITY/K/N", FTSECTION_PopupMenu, FtCliCmd }, + { "ICONWINDOWCMD", "NAME/A", FTSECTION_PopupMenu, FtIconWindowCmd }, + { "PLUGINCMD", "NAME/A", FTSECTION_PopupMenu, FtPluginCmd }, + + { "MENUSEPARATOR", "", FTSECTION_PopupMenu, AddFtMenuSeparator }, + + { "TOOLTIP", "", FTSECTION_Tooltip, FtBeginToolTip }, + { "ENDTOOLTIP", "", FTSECTION_Tooltip, FtEndToolTip }, + + { "GROUP", "ORIENTATION/K", FTSECTION_Tooltip, FtBeginGroup }, + { "ENDGROUP", "", FTSECTION_Tooltip, FtEndGroup }, + + { "MEMBER", "HIDE/K", FTSECTION_Tooltip, FtBeginMember }, + { "ENDMEMBER", "", FTSECTION_Tooltip, FtEndMember }, + + { "HBAR", "", FTSECTION_Tooltip, FtHBar }, + { "STRING", "ID/K,TEXT/K,SRC/K,TEXTPEN/K,HALIGN/K,STYLE/K,FONT/K,TTFONT/K,VALIGN/K", + FTSECTION_Tooltip, FtString }, + { "SPACE", "SIZE/N/A", FTSECTION_Tooltip, FtSpace }, + { "DTIMAGE", "FILENAME/A", FTSECTION_Tooltip, FtImage }, + + { NULL, NULL, FTSECTION_All, NULL }, +}; + +//---------------------------------------------------------------------------- + +void ReadFileTypes(struct FileTypesPrefsInst *inst, + CONST_STRPTR LoadName, CONST_STRPTR DefIconPrefsName) +{ + BPTR OldDir = (BPTR) NULL; + BPTR fLock; + struct MUI_NListtree_TreeNode *tn; + struct FileInfoBlock *fib = NULL; + BOOL SingleFile = FALSE; + + d1(kprintf(__FUNC__ "/%ld: LoadName=%08lx <%s>\n", __FUNC__, __LINE__, LoadName, LoadName ? LoadName : (CONST_STRPTR) "")); + + DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Clear, NULL, 0); + + if (inst->fpb_FileTypesDirLock) + { + UnLock(inst->fpb_FileTypesDirLock); + inst->fpb_FileTypesDirLock = (BPTR) NULL; + } + + do { + set(inst->fpb_Objects[OBJNDX_MainListView], MUIA_NList_Quiet, TRUE); + + fLock = Lock(LoadName, ACCESS_READ); + if ((BPTR)NULL == fLock) + break; + + fib = AllocDosObject(DOS_FIB, NULL); + d1(kprintf(__FUNC__ "/%ld: fib=%08lx\n", __FUNC__, __LINE__, fib)); + if (NULL == fib) + break; + + if (!Examine(fLock, fib)) + break; + + d1(kprintf(__FUNC__ "/%ld: fib_DirEntryType=%ld\n", __FUNC__, __LINE__, fib->fib_DirEntryType)); + + if (fib->fib_DirEntryType > 0) + { + // "LoadName" is a directory -> use it to load filetypes descriptions + inst->fpb_FileTypesDirLock = DupLock(fLock); + if ((BPTR)NULL == inst->fpb_FileTypesDirLock) + break; + } + else + { + // Single file specified, generate one entry for it + SingleFile = TRUE; + GenerateFileTypesNewEntry(inst, LoadName); + } + + if (!SingleFile) + { + OldDir = CurrentDir(inst->fpb_FileTypesDirLock); + + d1(kprintf(__FUNC__ "/%ld: before InitDefIcons()\n", __FUNC__, __LINE__)); + + InitDefIcons(inst, DefIconPrefsName); + } + + // Now walk through all entries of OBJNDX_MainListTree + // and try to read contents of every entry + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Root, + MUIV_NListtree_GetEntry_Position_Head, + 0); + d1(kprintf(__FUNC__ "/%ld: tn=%08lx\n", __FUNC__, __LINE__, tn)); + + while (tn) + { + d1(kprintf(__FUNC__ "/%ld: tn=%08lx\n", __FUNC__, __LINE__, tn)); + + ReadFileTypeDef(inst, tn); + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + tn, + MUIV_NListtree_GetEntry_Position_Next, + MUIV_NListtree_GetEntry_Flag_SameLevel); + } while (tn); + + } while (0); + + if (inst->fpb_HideEmptyNodes) + HideEmptyNodes(inst); + + set(inst->fpb_Objects[OBJNDX_MainListView], MUIA_NList_Quiet, FALSE); + + if (fib) + FreeDosObject(DOS_FIB, fib); + if (fLock) + UnLock(fLock); + if (OldDir) + CurrentDir(OldDir); +} + +//---------------------------------------------------------------------------- + +static void ReadFileTypeDef(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn) +{ + do { + ULONG n; + + inst->fpb_RequestedSection = FTSECTION_All; + inst->fpb_PopupMenu = NULL; + inst->fpb_CurrentTTItem = NULL; + inst->fpb_CurrentMenuItem = NULL; + inst->fpb_ParentMenuItem = NULL; + inst->fpb_DefaultActionSet = FALSE; + + for (n=0; nfpb_FileHandles); n++) + { + inst->fpb_FileHandles[n].ftfd_LineNumber = 0; + + d1(kprintf(__FUNC__ "/%ld: fpd_FileHandles[%ld].ftfd_FileHandle=%08lx\n", __FUNC__, __LINE__, n, inst->fpb_FileHandles[n].ftfd_FileHandle)); + + if (inst->fpb_FileHandles[n].ftfd_FileHandle) + { + Close(inst->fpb_FileHandles[n].ftfd_FileHandle); + inst->fpb_FileHandles[n].ftfd_FileHandle = (BPTR)NULL; + } + } + + inst->fpb_IncludeNesting = 0; + + ReadFileTypeDefFile(inst, tn, tn->tn_Name); + } while (0); +} + +//---------------------------------------------------------------------------- + +static LONG ReadFileTypeDefFile(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, CONST_STRPTR fileName) +{ + struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User; + LONG Result = RETURN_OK; + char Line[8192]; + + inst->fpb_FileHandles[inst->fpb_IncludeNesting].ftfd_LineNumber = 0; + inst->fpb_FileHandles[inst->fpb_IncludeNesting].ftfd_FileHandle = Open(fileName, MODE_OLDFILE); + + fte->ftle_FileFound = (BPTR)NULL != inst->fpb_FileHandles[inst->fpb_IncludeNesting].ftfd_FileHandle; + + d1(kprintf(__FILE__ "/%s/%ld: fd=%08lx\n", __FUNC__, __LINE__, inst->fpb_FileHandles[inst->fpb_IncludeNesting].ftfd_FileHandle)); + if ((BPTR)NULL == inst->fpb_FileHandles[inst->fpb_IncludeNesting].ftfd_FileHandle) + return IoErr(); + + while (RETURN_OK == Result && FGets(inst->fpb_FileHandles[inst->fpb_IncludeNesting].ftfd_FileHandle, Line, sizeof(Line))) + { + d1(kprintf(__FUNC__ "/%ld: Line = <%s>\n", __FUNC__, __LINE__, Line)); + + inst->fpb_FileHandles[inst->fpb_IncludeNesting].ftfd_LineNumber++; + + if (strlen(stpblk(Line)) > 0 && '#' != *Line) + { + const struct CmdFunc *cmdTableEntry; + CONST_STRPTR LinePtr = Line; + + cmdTableEntry = ParseFileTypeLine(&LinePtr); + d1(kprintf(__FUNC__ "/%ld: Line = <%s> LinePtr=<%s> cmdTableEntry=%08lx\n", __FUNC__, __LINE__, Line, LinePtr, cmdTableEntry)); + if (cmdTableEntry) + { + struct RDArgs *InputRdArgs; + + d1(kprintf(__FUNC__ "/%ld: CommandName=<%s>\n", __FUNC__, __LINE__, cmdTableEntry->cf_CommandName)); + + InputRdArgs = AllocDosObject(DOS_RDARGS, NULL); + d1(kprintf(__FILE__ "/%s/%ld: rdArgs=%08lx\n", __FUNC__, __LINE__, InputRdArgs)); + if (InputRdArgs) + { + struct RDArgs *rdArg; + SIPTR ArgArray[10]; + + d1(kprintf(__FUNC__ "/%ld: Template = <%s>\n", __FUNC__, __LINE__, cmdTableEntry->cf_Template)); + + memset(ArgArray, 0, sizeof(ArgArray)); + + InputRdArgs->RDA_Source.CS_Buffer = (STRPTR) LinePtr; + InputRdArgs->RDA_Source.CS_Length = strlen(LinePtr); + InputRdArgs->RDA_Source.CS_CurChr = 0; + InputRdArgs->RDA_Flags |= RDAF_NOPROMPT; + + rdArg = ReadArgs(cmdTableEntry->cf_Template, ArgArray, InputRdArgs); + d1(kprintf(__FUNC__ "/%ld: rdArg=%08lx\n", __FUNC__, __LINE__, rdArg)); + if (rdArg) + { + if (cmdTableEntry->cf_Function) + Result = (cmdTableEntry->cf_Function)(inst, tn, ArgArray); + + FreeArgs(rdArg); + + d1(kprintf(__FUNC__ "/%ld: Result=%ld\n", __FUNC__, __LINE__, Result)); + } + else + { + Result = IoErr(); + d1(kprintf(__FUNC__ "/%ld: ReadArgs() returned error %ld\n", __FUNC__, __LINE__, Result)); + d1(kprintf(__FUNC__ "/%ld: LinePtr=<%s>\n", __FUNC__, __LINE__, LinePtr)); + d1(kprintf(__FUNC__ "/%ld: Template = <%s>\n", __FUNC__, __LINE__, cmdTableEntry->cf_Template)); + d1(kprintf(__FUNC__ "/%ld: CommandName=<%s>\n", __FUNC__, __LINE__, cmdTableEntry->cf_CommandName)); + break; + } + + FreeDosObject(DOS_RDARGS, InputRdArgs); + } + } + else + { + d1(kprintf(__FUNC__ "/%ld: unknown keyword Line=<%s>\n", __FUNC__, __LINE__, LinePtr)); + } + } + + d1(kprintf(__FUNC__ "/%ld: Result=%ld\n", __FUNC__, __LINE__, Result)); + } + + Close(inst->fpb_FileHandles[inst->fpb_IncludeNesting].ftfd_FileHandle); + inst->fpb_FileHandles[inst->fpb_IncludeNesting].ftfd_FileHandle = (BPTR)NULL; + + if (inst->fpb_IncludeNesting > 0) + inst->fpb_IncludeNesting--; // return to previous include nesting level + + d1(kprintf(__FUNC__ "/%ld: Result=%ld IncludeNesting=%ld\n", __FUNC__, __LINE__, Result, inst->fpb_IncludeNesting)); + + return Result; +} + + +static const struct CmdFunc *ParseFileTypeLine(CONST_STRPTR *Line) +{ + short i; + size_t Len; + CONST_STRPTR Command = *Line; + const struct CmdFunc *Table; + + /* Skip leading blanks. */ + + Command = stpblk(Command); + + /* Now determine the length of the command. */ + + Len = 0; + + while (Command[Len]) + { + if ('\n' == Command[Len] || Command[Len] == '\t' || Command[Len] == ' ') + break; + else + Len++; + } + + *Line = Command + Len; + + /* Now we need to check if the command we received + * can be handled by one of the routines in the + * command table. + */ + + Table = CommandTable; + + d1(kprintf(__FUNC__ "/%ld: cmd=<%s>\n", __FUNC__, __LINE__, Command);) + + for(i = 0 ; Table[i].cf_CommandName != NULL ; i++) + { + if((strlen(Table[i].cf_CommandName) == Len) && (Strnicmp(Command, Table[i].cf_CommandName,Len) == 0)) + { + return &Table[i]; + } + } + + return NULL; +} + +//---------------------------------------------------------------------------- + +static LONG FtBeginToolTip(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray) +{ + struct FileTypesListEntry *fte; + + (void) ArgArray; + + d1(kprintf(__FILE__ "/%s/%ld: tn=%08lx\n", __FUNC__, __LINE__, tn)); + + if (inst->fpb_CurrentTTItem) + { + d1(kprintf(__FILE__ "/%s/%ld: RETURN_ERROR TOOLTIP inside TOOLTIP\n", __FUNC__, __LINE__)); + return RETURN_ERROR; + } + + inst->fpb_CurrentTTItem = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, + GetNameFromEntryType(ENTRYTYPE_ToolTip), NULL, + tn, + MUIV_NListtree_Insert_PrevNode_Tail, + TNF_LIST); + if (NULL == inst->fpb_CurrentTTItem) + return RETURN_ERROR; + + fte = (struct FileTypesListEntry *) inst->fpb_CurrentTTItem->tn_User; + fte->ftle_EntryType = ENTRYTYPE_ToolTip; + + return RETURN_OK; +} + + +static LONG FtEndToolTip(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray) +{ + struct FileTypesListEntry *fte; + + (void) ArgArray; + + d1(kprintf(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + if (NULL == inst->fpb_CurrentTTItem) + return RETURN_ERROR; + + fte = (struct FileTypesListEntry *) inst->fpb_CurrentTTItem->tn_User; + + switch (fte->ftle_EntryType) + { + case ENTRYTYPE_ToolTip: + break; + default: + d1(kprintf(__FILE__ "/%s/%ld: RETURN_ERROR: ENDTOOLTIP inside non-TOOLTIP\n", __FUNC__, __LINE__)); + inst->fpb_CurrentTTItem = NULL; + return RETURN_ERROR; + } + + inst->fpb_CurrentTTItem = NULL; + + return RETURN_OK; +} + + +static LONG FtHBar(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray) +{ + struct FileTypesListEntry *fte; + struct MUI_NListtree_TreeNode *barTTd; + + d1(kprintf(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + if (NULL == inst->fpb_CurrentTTItem) + return RETURN_ERROR; + + fte = (struct FileTypesListEntry *) inst->fpb_CurrentTTItem->tn_User; + + if (ENTRYTYPE_ToolTip_Member != fte->ftle_EntryType) + { + d1(kprintf(__FILE__ "/%s/%ld: RETURN_ERROR: HBAR outside MEMBER\n", __FUNC__, __LINE__)); + return RETURN_ERROR; + } + + barTTd = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, + GetNameFromEntryType(ENTRYTYPE_ToolTip_HBar), NULL, + inst->fpb_CurrentTTItem, + MUIV_NListtree_Insert_PrevNode_Tail, + TNF_LIST); + + d1(kprintf(__FILE__ "/%s/%ld: barTTd=%08lx\n", __FUNC__, __LINE__, barTTd)); + + if (NULL == barTTd) + return RETURN_ERROR; + + fte = (struct FileTypesListEntry *) barTTd->tn_User; + fte->ftle_EntryType = ENTRYTYPE_ToolTip_HBar; + + return RETURN_OK; +} + + +static LONG FtBeginGroup(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray) +{ + struct FileTypesListEntry *fte; + struct MUI_NListtree_TreeNode *groupTTi; + enum TTLayoutMode orientation = TTL_Vertical; + STRPTR orientationString = (STRPTR) ArgArray[0]; + + d1(kprintf(__FILE__ "/%s/%ld: orientation=<%s>\n", __FUNC__, __LINE__, orientationString)); + + if (NULL == inst->fpb_CurrentTTItem) + return RETURN_ERROR; + + if (orientationString && strlen(orientationString) > 0) + { + if (0 == Stricmp(orientationString, "horizontal")) + orientation = TTL_Horizontal; + else if (0 == Stricmp(orientationString, "vertical")) + orientation = TTL_Vertical; + else + return RETURN_ERROR; + } + + groupTTi = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, + GetNameFromEntryType(ENTRYTYPE_ToolTip_Group), NULL, + inst->fpb_CurrentTTItem, + MUIV_NListtree_Insert_PrevNode_Tail, + TNF_LIST); + + d1(kprintf(__FILE__ "/%s/%ld: groupTTi=%08lx\n", __FUNC__, __LINE__, groupTTi)); + + if (NULL == groupTTi) + return RETURN_ERROR; + + fte = (struct FileTypesListEntry *) groupTTi->tn_User; + + AddAttribute(fte, ATTRTYPE_GroupOrientation, sizeof(orientation), &orientation); + + fte->ftle_TypeEntry.ftle_ToolTipEntry.ftti_Parent = inst->fpb_CurrentTTItem; + fte->ftle_EntryType = ENTRYTYPE_ToolTip_Group; + inst->fpb_CurrentTTItem = groupTTi; + + return RETURN_OK; +} + + +static LONG FtEndGroup(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray) +{ + struct FileTypesListEntry *fte; + + d1(kprintf(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + if (NULL == inst->fpb_CurrentTTItem) + return RETURN_ERROR; + + fte = (struct FileTypesListEntry *) inst->fpb_CurrentTTItem->tn_User; + + if (fte->ftle_EntryType != ENTRYTYPE_ToolTip_Group) + { + d1(kprintf(__FILE__ "/%s/%ld: RETURN_ERROR: ENDGROUP outside GROUP\n", __FUNC__, __LINE__)); + return RETURN_ERROR; + } + + fte = (struct FileTypesListEntry *) inst->fpb_CurrentTTItem->tn_User; + if (NULL == fte->ftle_TypeEntry.ftle_ToolTipEntry.ftti_Parent) + return RETURN_ERROR; + + inst->fpb_CurrentTTItem = fte->ftle_TypeEntry.ftle_ToolTipEntry.ftti_Parent; + + d1(kprintf(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + return RETURN_OK; +} + + +static LONG FtBeginMember(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray) +{ + struct MUI_NListtree_TreeNode *memberTTi; + struct FileTypesListEntry *fte; + STRPTR hideString = (STRPTR) ArgArray[0]; + + d1(kprintf(__FILE__ "/%s/%ld: hide=<%s>\n", __FUNC__, __LINE__, hideString)); + + if (NULL == inst->fpb_CurrentTTItem) + return RETURN_ERROR; + + fte = (struct FileTypesListEntry *) inst->fpb_CurrentTTItem->tn_User; + + if (fte->ftle_EntryType != ENTRYTYPE_ToolTip_Group) + { + d1(kprintf(__FILE__ "/%s/%ld: RETURN_ERROR: MEMBER not inside GROUP\n", __FUNC__, __LINE__)); + return RETURN_ERROR; + } + + memberTTi = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, + GetNameFromEntryType(ENTRYTYPE_ToolTip_Member), NULL, + inst->fpb_CurrentTTItem, + MUIV_NListtree_Insert_PrevNode_Tail, + TNF_LIST); + + d1(kprintf(__FILE__ "/%s/%ld: memberTTi=%08lx\n", __FUNC__, __LINE__, memberTTi)); + + if (NULL == memberTTi) + return RETURN_ERROR; + + fte = (struct FileTypesListEntry *) memberTTi->tn_User; + fte->ftle_TypeEntry.ftle_ToolTipEntry.ftti_Parent = inst->fpb_CurrentTTItem; + fte->ftle_EntryType = ENTRYTYPE_ToolTip_Member; + inst->fpb_CurrentTTItem = memberTTi; + + if (hideString && strlen(hideString) > 0) + AddAttribute(fte, ATTRTYPE_MemberHideString, 1 + strlen(hideString), hideString); + + return RETURN_OK; +} + + +static LONG FtEndMember(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray) +{ + struct FileTypesListEntry *fte; + + d1(kprintf(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + if (NULL == inst->fpb_CurrentTTItem) + return RETURN_ERROR; + + fte = (struct FileTypesListEntry *) inst->fpb_CurrentTTItem->tn_User; + + if (ENTRYTYPE_ToolTip_Member != fte->ftle_EntryType) + { + d1(kprintf(__FILE__ "/%s/%ld: RETURN_ERROR: ENDMEMBER outside MEMBER\n", __FUNC__, __LINE__)); + return RETURN_ERROR; + } + + fte = (struct FileTypesListEntry *) inst->fpb_CurrentTTItem->tn_User; + if (NULL == fte->ftle_TypeEntry.ftle_ToolTipEntry.ftti_Parent) + return RETURN_ERROR; + + inst->fpb_CurrentTTItem = fte->ftle_TypeEntry.ftle_ToolTipEntry.ftti_Parent; + + return RETURN_OK; +} + + +static LONG FtString(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray) +{ + struct FileTypesListEntry *fte; + struct MUI_NListtree_TreeNode *stringTTd; + STRPTR idString = (STRPTR) ArgArray[0]; + STRPTR textString = (STRPTR) ArgArray[1]; + STRPTR srcString = (STRPTR) ArgArray[2]; + STRPTR textpenString = (STRPTR) ArgArray[3]; + STRPTR halignString = (STRPTR) ArgArray[4]; + STRPTR styleString = (STRPTR) ArgArray[5]; + STRPTR fontString = (STRPTR) ArgArray[6]; + STRPTR ttFontDescString = (STRPTR) ArgArray[7]; + STRPTR valignString = (STRPTR) ArgArray[8]; + + d1(kprintf(__FILE__ "/%s/%ld: id=<%s> text=<%s> src=<%s>\n", __FUNC__, __LINE__, idString, textString, srcString)); + d1(kprintf(__FILE__ "/%s/%ld: textpen=<%s> halign=<%s> style=<%s>\n", __FUNC__, __LINE__, textpenString, halignString, styleString)); + + if (NULL == inst->fpb_CurrentTTItem) + return RETURN_ERROR; + + fte = (struct FileTypesListEntry *) inst->fpb_CurrentTTItem->tn_User; + + if (ENTRYTYPE_ToolTip_Member != fte->ftle_EntryType) + { + d1(kprintf(__FILE__ "/%s/%ld: RETURN_ERROR: STRING outside MEMBER\n", __FUNC__, __LINE__)); + return RETURN_ERROR; + } + + if (NULL == fte->ftle_TypeEntry.ftle_ToolTipEntry.ftti_Parent) + return RETURN_ERROR; + + d1(kprintf(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + stringTTd = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, + GetNameFromEntryType(ENTRYTYPE_ToolTip_String), NULL, + inst->fpb_CurrentTTItem, + MUIV_NListtree_Insert_PrevNode_Tail, + TNF_LIST); + + d1(kprintf(__FILE__ "/%s/%ld: stringTTd=%08lx\n", __FUNC__, __LINE__, stringTTd)); + + if (NULL == stringTTd) + return RETURN_ERROR; + + fte = (struct FileTypesListEntry *) stringTTd->tn_User; + + if (idString && strlen(idString) > 0) + AddAttribute(fte, ATTRTYPE_StringId, 1 + strlen(idString), idString); + else if (textString && strlen(textString) > 0) + AddAttribute(fte, ATTRTYPE_StringText, 1 + strlen(textString), textString); + else if (srcString && strlen(srcString) > 0) + AddAttribute(fte, ATTRTYPE_StringSrc, 1 + strlen(srcString), srcString); + + if (halignString && strlen(halignString) > 0) + AddAttribute(fte, ATTRTYPE_StringHAlign, 1 + strlen(halignString), halignString); + if (valignString && strlen(valignString) > 0) + AddAttribute(fte, ATTRTYPE_StringVAlign, 1 + strlen(valignString), valignString); + if (styleString && strlen(styleString) > 0) + AddAttribute(fte, ATTRTYPE_StringStyle, 1 + strlen(styleString), styleString); + + // font specification - format: "fontname.font/size" + if (fontString && strlen(fontString) > 0) + AddAttribute(fte, ATTRTYPE_StringFont, 1 + strlen(fontString), fontString); + + // TrueType Font Descriptor format: + // "style/weight/size/fontname" + if (ttFontDescString && strlen(ttFontDescString) > 0) + AddAttribute(fte, ATTRTYPE_StringTTFont, 1 + strlen(ttFontDescString), ttFontDescString); + + if (textpenString && strlen(textpenString) > 0) + AddAttribute(fte, ATTRTYPE_StringPen, 1 + strlen(textpenString), textpenString); + + fte->ftle_EntryType = ENTRYTYPE_ToolTip_String; + + return RETURN_OK; +} + + +static LONG FtSpace(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray) +{ + ULONG *Size = (ULONG *) ArgArray[0]; + struct MUI_NListtree_TreeNode *spaceTTd; + struct FileTypesListEntry *fte; + + d1(kprintf(__FILE__ "/%s/%ld: Size=%lu\n", __FUNC__, __LINE__, Size)); + + if (NULL == inst->fpb_CurrentTTItem) + return RETURN_ERROR; + + fte = (struct FileTypesListEntry *) inst->fpb_CurrentTTItem->tn_User; + + if (ENTRYTYPE_ToolTip_Member != fte->ftle_EntryType) + { + d1(kprintf(__FILE__ "/%s/%ld: RETURN_ERROR: SPACE outside MEMBER\n", __FUNC__, __LINE__)); + return RETURN_ERROR; + } + + spaceTTd = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, + GetNameFromEntryType(ENTRYTYPE_ToolTip_Space), NULL, + inst->fpb_CurrentTTItem, + MUIV_NListtree_Insert_PrevNode_Tail, + TNF_LIST); + + d1(kprintf(__FILE__ "/%s/%ld: spaceTTd=%08lx\n", __FUNC__, __LINE__, spaceTTd)); + + if (NULL == spaceTTd) + return RETURN_ERROR; + + fte = (struct FileTypesListEntry *) spaceTTd->tn_User; + + if (Size) + AddAttribute(fte, ATTRTYPE_SpaceSize, sizeof(*Size), Size); + + fte->ftle_EntryType = ENTRYTYPE_ToolTip_Space; + + return RETURN_OK; +} + + +static LONG FtImage(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray) +{ + STRPTR fileName = (STRPTR) ArgArray[0]; + struct MUI_NListtree_TreeNode *imageTTd; + struct FileTypesListEntry *fte; + + d1(kprintf(__FILE__ "/%s/%ld: fileName=<%s>\n", __FUNC__, __LINE__, fileName)); + + if (NULL == inst->fpb_CurrentTTItem) + return RETURN_ERROR; + + fte = (struct FileTypesListEntry *) inst->fpb_CurrentTTItem->tn_User; + + if (ENTRYTYPE_ToolTip_Member != fte->ftle_EntryType) + { + d1(kprintf(__FILE__ "/%s/%ld: RETURN_ERROR: HBAR outside MEMBER\n", __FUNC__, __LINE__)); + return RETURN_ERROR; + } + + imageTTd = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, + GetNameFromEntryType(ENTRYTYPE_ToolTip_DtImage), NULL, + inst->fpb_CurrentTTItem, + MUIV_NListtree_Insert_PrevNode_Tail, + TNF_LIST); + + d1(kprintf(__FILE__ "/%s/%ld: imageTTd=%08lx\n", __FUNC__, __LINE__, imageTTd)); + + if (NULL == imageTTd) + return RETURN_ERROR; + + fte = (struct FileTypesListEntry *) imageTTd->tn_User; + + AddAttribute(fte, ATTRTYPE_DtImageName, 1 + strlen(fileName), fileName); + + fte->ftle_EntryType = ENTRYTYPE_ToolTip_DtImage; + + return RETURN_OK; +} + +//---------------------------------------------------------------------------- + +static LONG FtBeginPopupMenu(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray) +{ + struct FileTypesListEntry *fte; + + d1(kprintf(__FILE__ "/%s/%ld: tn=%08lx\n", __FUNC__, __LINE__, tn)); + + inst->fpb_PopupMenu = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, + GetNameFromEntryType(ENTRYTYPE_PopupMenu), NULL, + tn, + MUIV_NListtree_Insert_PrevNode_Tail, + TNF_LIST); + + fte = (struct FileTypesListEntry *) inst->fpb_PopupMenu->tn_User; + fte->ftle_EntryType = ENTRYTYPE_PopupMenu; + + return RETURN_OK; +} + + +static LONG FtEndPopupMenu(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray) +{ + d1(kprintf(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + inst->fpb_PopupMenu = NULL; + + return RETURN_OK; +} + + +static LONG FtIncludeFile(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray) +{ + STRPTR fileName = (STRPTR) ArgArray[0]; + + d1(kprintf(__FILE__ "/%s/%ld: fileName=<%s>\n", __FUNC__, __LINE__, fileName)); + + if (inst->fpb_IncludeNesting + 1 >= MAX_INCLUDE_NESTING) + return RETURN_ERROR; + + inst->fpb_IncludeNesting++; + + return ReadFileTypeDefFile(inst, tn, fileName); +} + + +static LONG GetFtDescription(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray) +{ + struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User; + STRPTR descName = (STRPTR) ArgArray[0]; + + d1(kprintf(__FILE__ "/%s/%ld: descName=<%s>\n", __FUNC__, __LINE__, descName)); + + AddAttribute(fte, ATTRTYPE_FtDescription, 1 + strlen(descName), descName); + + return RETURN_OK; +} + + +static LONG GetFtPvPlugin(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray) +{ + struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User; + STRPTR pluginName = (STRPTR) ArgArray[0]; + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: pluginName=<%s>\n", __LINE__, pluginName)); + + AddAttribute(fte, ATTRTYPE_PvPluginName, 1 + strlen(pluginName), pluginName); + + return RETURN_OK; +} + + +static LONG AddFtMenuSeparator(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray) +{ + struct MUI_NListtree_TreeNode *ftmi; + struct FileTypesListEntry *fte; + + d1(kprintf(__FILE__ "/%s/%ld:\n", __FUNC__, __LINE__)); + + if (inst->fpb_CurrentMenuItem) + return RETURN_ERROR; // not allowed inside menu item + + ftmi = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, + GetNameFromEntryType(ENTRYTYPE_PopupMenu_MenuSeparator), NULL, + inst->fpb_PopupMenu, + MUIV_NListtree_Insert_PrevNode_Tail, + TNF_LIST); + + if (NULL == ftmi) + return RETURN_ERROR; + + fte = (struct FileTypesListEntry *) ftmi->tn_User; + fte->ftle_EntryType = ENTRYTYPE_PopupMenu_MenuSeparator; + + return RETURN_OK; +} + + +static LONG NewFtMenuEntry(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray) +{ + struct MUI_NListtree_TreeNode *ftmi; + struct FileTypesListEntry *fte; + STRPTR itemName = (STRPTR) ArgArray[0]; + STRPTR commKey = (STRPTR) ArgArray[1]; + BOOL defaultAction = (BOOL) ArgArray[2]; + STRPTR SelectedIconName = (STRPTR) ArgArray[3]; + STRPTR UnselectedIconName = (STRPTR) ArgArray[4]; + + d1(kprintf(__FILE__ "/%s/%ld: itemName=<%s> commKey=<%s>\n", __FUNC__, __LINE__, itemName, commKey)); + + if (NULL == inst->fpb_PopupMenu) + { + d1(kprintf(__FILE__ "/%s/%ld:\n", __FUNC__, __LINE__)); + return RETURN_ERROR; // not allowed outside popup menu + } + + if (inst->fpb_CurrentMenuItem) + { + d1(kprintf(__FILE__ "/%s/%ld:\n", __FUNC__, __LINE__)); + return RETURN_ERROR; // not allowed inside menu item + } + + d1(kprintf(__FILE__ "/%s/%ld:\n", __FUNC__, __LINE__)); + + if (defaultAction && inst->fpb_DefaultActionSet) + { + d1(kprintf(__FILE__ "/%s/%ld:\n", __FUNC__, __LINE__)); + return RETURN_ERROR; // only one DEFAULTACTION menu item allowed + } + + d1(kprintf(__FILE__ "/%s/%ld:\n", __FUNC__, __LINE__)); + + // Start new menu tree + inst->fpb_CurrentMenuItem = ftmi = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, + GetNameFromEntryType(ENTRYTYPE_PopupMenu_MenuItem), NULL, + inst->fpb_PopupMenu, + MUIV_NListtree_Insert_PrevNode_Tail, + TNF_LIST); + d1(kprintf(__FILE__ "/%s/%ld: ftmi=%08lx\n", __FUNC__, __LINE__, ftmi)); + if (NULL == ftmi) + return RETURN_ERROR; + + fte = (struct FileTypesListEntry *) ftmi->tn_User; + + d1(kprintf(__FILE__ "/%s/%ld:\n", __FUNC__, __LINE__)); + + if (defaultAction) + { + AddAttribute(fte, ATTRTYPE_MenuDefaultAction, 0, 0); + inst->fpb_DefaultActionSet = TRUE; + } + fte->ftle_EntryType = ENTRYTYPE_PopupMenu_MenuItem; + + if (itemName && strlen(itemName) > 0) + AddAttribute(fte, ATTRTYPE_MenuItemName, 1 + strlen(itemName), itemName); + if (commKey && strlen(commKey) > 0) + AddAttribute(fte, ATTRTYPE_MenuCommKey, 1 + strlen(commKey), commKey); + + if (UnselectedIconName) + AddAttribute(fte, ATTRTYPE_UnselIconName, 1 + strlen(UnselectedIconName), UnselectedIconName); + if (SelectedIconName) + AddAttribute(fte, ATTRTYPE_SelIconName, 1 + strlen(SelectedIconName), SelectedIconName); + + UpdateMenuImage(inst, OBJNDX_MainListTree, fte); + + DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Redraw, + ftmi, + 0); + + d1(kprintf(__FILE__ "/%s/%ld:\n", __FUNC__, __LINE__)); + + return RETURN_OK; +} + + +static LONG EndFtMenuEntry(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray) +{ + struct MUI_NListtree_TreeNode *ftmi = inst->fpb_CurrentMenuItem; + + d1(kprintf(__FILE__ "/%s/%ld: UserData=%08lx\n", __FUNC__, __LINE__, ftmi->ftmi_MenuTree)); + + if (NULL == ftmi) + return RETURN_ERROR; // only allowed if menu item pending + + inst->fpb_CurrentMenuItem = NULL; + + return RETURN_OK; +} + + +static LONG AddSubMenuEntry(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray) +{ + struct MUI_NListtree_TreeNode *ftmi; + struct FileTypesListEntry *fte; + STRPTR itemName = (STRPTR) ArgArray[0]; + STRPTR SelectedIconName = (STRPTR) ArgArray[1]; + STRPTR UnselectedIconName = (STRPTR) ArgArray[2]; + + d1(kprintf(__FILE__ "/%s/%ld: itemName=<%s>\n", __FUNC__, __LINE__, itemName)); + + if (inst->fpb_CurrentMenuItem) + return RETURN_ERROR; // not allowed inside menu item + + if (inst->fpb_ParentMenuItem) + return RETURN_ERROR; // only 1 level of submenus is allowed + + // Start new menu tree + inst->fpb_ParentMenuItem = inst->fpb_PopupMenu; + + inst->fpb_PopupMenu = ftmi = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, + GetNameFromEntryType(ENTRYTYPE_PopupMenu_SubMenu), NULL, + inst->fpb_PopupMenu, + MUIV_NListtree_Insert_PrevNode_Tail, + TNF_LIST); + + d1(kprintf(__FILE__ "/%s/%ld: ftmi=%08lx\n", __FUNC__, __LINE__, ftmi)); + if (NULL == ftmi) + return RETURN_ERROR; + + fte = (struct FileTypesListEntry *) ftmi->tn_User; + + fte->ftle_EntryType = ENTRYTYPE_PopupMenu_SubMenu; + + if (itemName && strlen(itemName) > 0) + AddAttribute(fte, ATTRTYPE_MenuItemName, 1 + strlen(itemName), itemName); + + if (UnselectedIconName) + AddAttribute(fte, ATTRTYPE_UnselIconName, 1 + strlen(UnselectedIconName), UnselectedIconName); + if (SelectedIconName) + AddAttribute(fte, ATTRTYPE_SelIconName, 1 + strlen(SelectedIconName), SelectedIconName); + + UpdateMenuImage(inst, OBJNDX_MainListTree, fte); + + return RETURN_OK; +} + + +static LONG EndSubMenuEntry(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray) +{ + struct MUI_NListtree_TreeNode *ftmi = inst->fpb_ParentMenuItem; + + d1(kprintf(__FILE__ "/%s/%ld:\n", __FUNC__, __LINE__)); + + if (NULL == inst->fpb_ParentMenuItem) + return RETURN_ERROR; // only allowed inside submenu + + if (inst->fpb_CurrentMenuItem) + return RETURN_ERROR; // not allowed inside menu item + + if (NULL == ftmi) + return RETURN_ERROR; // no submenu pending + + inst->fpb_PopupMenu = inst->fpb_ParentMenuItem; + + inst->fpb_ParentMenuItem = NULL; + + return RETURN_OK; +} + + +static LONG FtInternalCmd(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray) +{ + struct MUI_NListtree_TreeNode *ftmi = inst->fpb_CurrentMenuItem; + struct FileTypesListEntry *fte; + CONST_STRPTR cmdName = (CONST_STRPTR) ArgArray[0]; + + d1(kprintf(__FILE__ "/%s/%ld: cmdName=<%s>\n", __FUNC__, __LINE__, cmdName)); + + if (NULL == ftmi) + return RETURN_ERROR; + + ftmi = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, + GetNameFromEntryType(ENTRYTYPE_PopupMenu_InternalCmd), NULL, + ftmi, + MUIV_NListtree_Insert_PrevNode_Tail, + TNF_LIST); + + if (NULL == ftmi) + return RETURN_ERROR; + + fte = (struct FileTypesListEntry *) ftmi->tn_User; + + if (cmdName && strlen(cmdName) > 0) + AddAttribute(fte, ATTRTYPE_CommandName, 1 + strlen(cmdName), cmdName); + + fte->ftle_EntryType = ENTRYTYPE_PopupMenu_InternalCmd; + + return RETURN_OK; +} + + +static LONG FtWbCmd(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray) +{ + struct MUI_NListtree_TreeNode *ftmi = inst->fpb_CurrentMenuItem; + struct FileTypesListEntry *fte; + CONST_STRPTR cmdName = (CONST_STRPTR) ArgArray[0]; + ULONG *StackSize = (ULONG *) ArgArray[1]; + ULONG wbArgs = ArgArray[2]; + ULONG *Priority = (ULONG *) ArgArray[3]; + + d1(kprintf(__FILE__ "/%s/%ld: cmdName=<%s> StackSize=%08lx wbArgs=%ld\n", __FUNC__, __LINE__, cmdName, StackSize, wbArgs)); + + if (NULL == ftmi) + return RETURN_ERROR; + + ftmi = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, + GetNameFromEntryType(ENTRYTYPE_PopupMenu_WbCmd), NULL, + ftmi, + MUIV_NListtree_Insert_PrevNode_Tail, + TNF_LIST); + + if (NULL == ftmi) + return RETURN_ERROR; + + fte = (struct FileTypesListEntry *) ftmi->tn_User; + + if (cmdName && strlen(cmdName) > 0) + AddAttribute(fte, ATTRTYPE_CommandName, 1 + strlen(cmdName), cmdName); + if (StackSize) + AddAttribute(fte, ATTRTYPE_CommandStacksize, sizeof(*StackSize), StackSize); + if (Priority) + AddAttribute(fte, ATTRTYPE_CommandPriority, sizeof(*Priority), Priority); + AddAttribute(fte, ATTRTYPE_CommandWbArgs, sizeof(wbArgs), &wbArgs); + + fte->ftle_EntryType = ENTRYTYPE_PopupMenu_WbCmd; + + return RETURN_OK; +} + + +static LONG FtARexxCmd(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray) +{ + struct MUI_NListtree_TreeNode *ftmi = inst->fpb_CurrentMenuItem; + struct FileTypesListEntry *fte; + CONST_STRPTR cmdName = (CONST_STRPTR) ArgArray[0]; + ULONG *StackSize = (ULONG *) ArgArray[1]; + ULONG wbArgs = ArgArray[2]; + ULONG *Priority = (ULONG *) ArgArray[3]; + + d1(kprintf(__FILE__ "/%s/%ld: cmdName=<%s> StackSize=%08lx wbArgs=%ld\n", __FUNC__, __LINE__, cmdName, StackSize, wbArgs)); + + if (NULL == ftmi) + return RETURN_ERROR; + + ftmi = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, + GetNameFromEntryType(ENTRYTYPE_PopupMenu_ARexxCmd), NULL, + ftmi, + MUIV_NListtree_Insert_PrevNode_Tail, + TNF_LIST); + + if (NULL == ftmi) + return RETURN_ERROR; + + fte = (struct FileTypesListEntry *) ftmi->tn_User; + + if (cmdName && strlen(cmdName) > 0) + AddAttribute(fte, ATTRTYPE_CommandName, 1 + strlen(cmdName), cmdName); + if (StackSize) + AddAttribute(fte, ATTRTYPE_CommandStacksize, sizeof(*StackSize), StackSize); + if (Priority) + AddAttribute(fte, ATTRTYPE_CommandPriority, sizeof(*Priority), Priority); + AddAttribute(fte, ATTRTYPE_CommandWbArgs, sizeof(wbArgs), &wbArgs); + + fte->ftle_EntryType = ENTRYTYPE_PopupMenu_ARexxCmd; + + return RETURN_OK; +} + + +static LONG FtCliCmd(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray) +{ + struct MUI_NListtree_TreeNode *ftmi = inst->fpb_CurrentMenuItem; + struct FileTypesListEntry *fte; + CONST_STRPTR cmdName = (CONST_STRPTR) ArgArray[0]; + ULONG *StackSize = (ULONG *) ArgArray[1]; + ULONG wbArgs = ArgArray[2]; + ULONG *Priority = (ULONG *) ArgArray[3]; + + d1(kprintf(__FILE__ "/%s/%ld: cmdName=<%s> StackSize=%08lx\n", __FUNC__, __LINE__, cmdName, StackSize)); + + if (NULL == ftmi) + return RETURN_ERROR; + + ftmi = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, + GetNameFromEntryType(ENTRYTYPE_PopupMenu_CliCmd), NULL, + ftmi, + MUIV_NListtree_Insert_PrevNode_Tail, + TNF_LIST); + + if (NULL == ftmi) + return RETURN_ERROR; + + fte = (struct FileTypesListEntry *) ftmi->tn_User; + + if (cmdName && strlen(cmdName) > 0) + AddAttribute(fte, ATTRTYPE_CommandName, 1 + strlen(cmdName), cmdName); + if (StackSize) + AddAttribute(fte, ATTRTYPE_CommandStacksize, sizeof(*StackSize), StackSize); + if (Priority) + AddAttribute(fte, ATTRTYPE_CommandPriority, sizeof(*Priority), Priority); + AddAttribute(fte, ATTRTYPE_CommandWbArgs, sizeof(wbArgs), &wbArgs); + + fte->ftle_EntryType = ENTRYTYPE_PopupMenu_CliCmd; + + return RETURN_OK; +} + + +static LONG FtPluginCmd(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray) +{ + struct MUI_NListtree_TreeNode *ftmi = inst->fpb_CurrentMenuItem; + struct FileTypesListEntry *fte; + CONST_STRPTR cmdName = (CONST_STRPTR) ArgArray[0]; + + d1(kprintf(__FILE__ "/%s/%ld: cmdName=<%s>\n", __FUNC__, __LINE__, cmdName)); + + if (NULL == ftmi) + return RETURN_ERROR; + + ftmi = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, + GetNameFromEntryType(ENTRYTYPE_PopupMenu_PluginCmd), NULL, + ftmi, + MUIV_NListtree_Insert_PrevNode_Tail, + TNF_LIST); + + if (NULL == ftmi) + return RETURN_ERROR; + + fte = (struct FileTypesListEntry *) ftmi->tn_User; + + if (cmdName && strlen(cmdName) > 0) + AddAttribute(fte, ATTRTYPE_CommandName, 1 + strlen(cmdName), cmdName); + + fte->ftle_EntryType = ENTRYTYPE_PopupMenu_PluginCmd; + + return RETURN_OK; +} + + +static LONG FtIconWindowCmd(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, LONG *ArgArray) +{ + struct MUI_NListtree_TreeNode *ftmi = inst->fpb_CurrentMenuItem; + struct FileTypesListEntry *fte; + CONST_STRPTR cmdName = (CONST_STRPTR) ArgArray[0]; + + d1(kprintf(__FILE__ "/%s/%ld: cmdName=<%s>\n", __FUNC__, __LINE__, cmdName)); + + if (NULL == ftmi) + return RETURN_ERROR; + + ftmi = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, + GetNameFromEntryType(ENTRYTYPE_PopupMenu_IconWindowCmd), NULL, + ftmi, + MUIV_NListtree_Insert_PrevNode_Tail, + TNF_LIST); + + if (NULL == ftmi) + return RETURN_ERROR; + + fte = (struct FileTypesListEntry *) ftmi->tn_User; + + if (cmdName && strlen(cmdName) > 0) + AddAttribute(fte, ATTRTYPE_CommandName, 1 + strlen(cmdName), cmdName); + + fte->ftle_EntryType = ENTRYTYPE_PopupMenu_IconWindowCmd; + + return RETURN_OK; +} + + +void GenerateFileTypesNewEntry(struct FileTypesPrefsInst *inst, CONST_STRPTR Name) +{ + struct MUI_NListtree_TreeNode *ltn; + struct FileTypesListEntry *fte; + + + d1(kprintf(__FUNC__ "/%ld: filetype <%s> \n", __FUNC__, __LINE__, Name)); + + ltn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, + Name, NULL, + MUIV_NListtree_Insert_ListNode_Root, + MUIV_NListtree_Insert_PrevNode_Sorted, + TNF_LIST); + + d1(kprintf(__FUNC__ "/%ld: ltn=%08lx\n", __FUNC__, __LINE__, ltn)); + + fte = (struct FileTypesListEntry *) ltn->tn_User; + fte->ftle_EntryType = ENTRYTYPE_FileType; +} + + +#if !defined(__SASC) && !defined(__MORPHOS__) && !defined(__AROS__) +// Replacement for SAS/C library functions + +static char *stpblk(const char *q) +{ + while (q && *q && isspace((int) *q)) + q++; + + return (char *) q; +} + +#endif /* !defined(__SASC) && !defined(__MORPHOS__) */ diff --git a/scalos/Plugins/Prefs/FileTypes/WriteFtPrefs.c b/scalos/Plugins/Prefs/FileTypes/WriteFtPrefs.c new file mode 100644 index 000000000..5df72f588 --- /dev/null +++ b/scalos/Plugins/Prefs/FileTypes/WriteFtPrefs.c @@ -0,0 +1,513 @@ +// WriteFtPrefs.c +// $Date$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define NO_INLINE_STDARG +#include + +#include +#include + +#include + +#include "debug.h" +#include "FileTypesPrefs.h" +#include "FileTypesPrefs_proto.h" + +//---------------------------------------------------------------------------- + +static LONG WriteFileTypeDef(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, ULONG Flags); +static LONG WriteChild(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, + ULONG Level, ULONG Flags, BPTR fh); +static LONG WriteChildEntry(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, + ULONG Level, ULONG Flags, + BPTR fh, CONST_STRPTR NameStart, CONST_STRPTR NameEnd); +static LONG SaveIcon(struct FileTypesPrefsInst *inst, CONST_STRPTR IconName); + +//---------------------------------------------------------------------------- + +LONG WriteFileTypes(struct FileTypesPrefsInst *inst, CONST_STRPTR SaveName, ULONG Flags) +{ + BPTR OldDir; + struct MUI_NListtree_TreeNode *tn; + LONG Result = RETURN_OK; + + inst->fpb_FileTypesDirLock = Lock(SaveName, ACCESS_READ); + if ((BPTR)NULL == inst->fpb_FileTypesDirLock) + return IoErr(); + + OldDir = CurrentDir(inst->fpb_FileTypesDirLock); + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Root, + MUIV_NListtree_GetEntry_Position_Head, + 0); + d1(KPrintF(__FILE__ "/%s/%ld: tn=%08lx\n", __FUNC__, __LINE__, tn)); + + while (tn && RETURN_OK == Result) + { + d1(kprintf(__FILE__ "/%s/%ld: tn=%08lx\n", __FUNC__, __LINE__, tn)); + + Result = WriteFileTypeDef(inst, tn, Flags); + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + tn, + MUIV_NListtree_GetEntry_Position_Next, + MUIV_NListtree_GetEntry_Flag_SameLevel); + } + + CurrentDir(OldDir); + + return Result; +} + +//---------------------------------------------------------------------------- + +static LONG WriteFileTypeDef(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, ULONG Flags) +{ + LONG Result = RETURN_OK; + + do { + struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User; + struct MUI_NListtree_TreeNode *tnChild; + + d1(kprintf(__FILE__ "/%s/%ld: fte=%08lx\n", __FUNC__, __LINE__, fte)); + + tnChild = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + tn, + MUIV_NListtree_GetEntry_Position_Head, + 0); + + d1(kprintf(__FILE__ "/%s/%ld: tnChild=%08lx\n", __FUNC__, __LINE__, tnChild)); + + // Only save FileType descriptor if either children or attributes are present + if (tnChild || !IsListEmpty(&fte->ftle_AttributesList)) + { + if (!(Flags & FTWRITEFLAG_ONLY_SAVE_CHANGED) || fte->ftle_Changed) + { + char DateStr[80]; + struct tm *tm; + const struct FtAttribute *fta; + time_t now; + BPTR fLock; + + fLock = Open(tn->tn_Name, MODE_NEWFILE); + + if ((BPTR)NULL == fLock) + { + Result = IoErr(); + break; + } + + + if (EOF == SetFileSize(fLock, 0, OFFSET_BEGINNING)) + { + Result = IoErr(); + break; + } + + Seek(fLock, 0, OFFSET_BEGINNING); + + if (EOF == FPuts(fLock, "# Scalos filetype description\n")) + { + Result = IoErr(); + break; + } + + time(&now); + tm = localtime(&now); + strftime(DateStr, sizeof(DateStr), "# written %c\n", tm); + + if (EOF == FPuts(fLock, DateStr)) + { + Result = IoErr(); + break; + } + + if (EOF == FPuts(fLock, "\n")) + { + Result = IoErr(); + break; + } + + // Write Attributes + for (fta = (const struct FtAttribute *) fte->ftle_AttributesList.lh_Head; + RETURN_OK == Result && fta != (const struct FtAttribute *) &fte->ftle_AttributesList.lh_Tail; + fta = (const struct FtAttribute *) fta->fta_Node.ln_Succ) + { + char Line[120]; + char ValueString[120]; + + d1(kprintf(__FILE__ "/%s/%ld: fta=%08lx pred=%08lx succ=%08lx\n", __FUNC__, __LINE__, \ + fta, fta->fta_Node.ln_Pred, fta->fta_Node.ln_Succ)); + + sprintf(Line, "%s \"%s\"\n", GetAttributeName(fta->fta_Type), + GetAttributeValueString(fta, ValueString, sizeof(ValueString))); + + if (EOF == FPuts(fLock, Line)) + { + Result = IoErr(); + break; + } + } + + if (EOF == FPuts(fLock, "\n")) + { + Result = IoErr(); + break; + } + + // Write Children + while (tnChild && RETURN_OK == Result) + { + d1(kprintf(__FILE__ "/%s/%ld: tnChild=%08lx <%s>\n", __FUNC__, __LINE__, tnChild, tnChild->tn_Name)); + + Result = WriteChild(inst, tnChild, 0, Flags, fLock); + + tnChild = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + tnChild, + MUIV_NListtree_GetEntry_Position_Next, + 0); + } + + if (!Close(fLock)) + { + Result = IoErr(); + break; + } + + if (inst->fpb_fCreateIcons) + Result = SaveIcon(inst, tn->tn_Name); + } + } + else + { + // Filetype description is empty -> try to delete it! + if (fte->ftle_FileFound) + { + char FileName[MAX_FILENAME]; + + DeleteFile(tn->tn_Name); + + // Also delete associated icon + strcpy(FileName, tn->tn_Name); + strcat(FileName, ".info"); + DeleteFile(FileName); + } + } + } while (0); + + return Result; +} + +//---------------------------------------------------------------------------- + +static LONG WriteChild(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, + ULONG Level, ULONG Flags, BPTR fh) +{ + LONG Result = RETURN_OK; + const struct FileTypesListEntry *fte = (const struct FileTypesListEntry *) tn->tn_User; + + d1(kprintf(__FILE__ "/%s/%ld: ftle_EntryType=%ld\n", __FUNC__, __LINE__, fte->ftle_EntryType)); + + switch (fte->ftle_EntryType) + { + case ENTRYTYPE_PopupMenu: + Result = WriteChildEntry(inst, tn, Level, Flags, fh, "POPUPMENU", "ENDPOPUPMENU\n"); + break; + case ENTRYTYPE_PopupMenu_SubMenu: + Result = WriteChildEntry(inst, tn, Level, Flags, fh, "SUBMENU", "ENDSUBMENU"); + break; + case ENTRYTYPE_PopupMenu_MenuItem: + Result = WriteChildEntry(inst, tn, Level, Flags, fh, "MENUENTRY", "ENDMENUENTRY"); + break; + case ENTRYTYPE_PopupMenu_InternalCmd: + Result = WriteChildEntry(inst, tn, Level, Flags, fh, "INTERNALCMD", NULL); + break; + case ENTRYTYPE_PopupMenu_WbCmd: + Result = WriteChildEntry(inst, tn, Level, Flags, fh, "WBCMD", NULL); + break; + case ENTRYTYPE_PopupMenu_ARexxCmd: + Result = WriteChildEntry(inst, tn, Level, Flags, fh, "AREXXCMD", NULL); + break; + case ENTRYTYPE_PopupMenu_CliCmd: + Result = WriteChildEntry(inst, tn, Level, Flags, fh, "CLICMD", NULL); + break; + case ENTRYTYPE_PopupMenu_PluginCmd: + Result = WriteChildEntry(inst, tn, Level, Flags, fh, "PLUGINCMD", NULL); + break; + case ENTRYTYPE_PopupMenu_IconWindowCmd: + Result = WriteChildEntry(inst, tn, Level, Flags, fh, "ICONWINDOWCMD", NULL); + break; + case ENTRYTYPE_PopupMenu_MenuSeparator: + Result = WriteChildEntry(inst, tn, Level, Flags, fh, "MENUSEPARATOR", NULL); + break; + case ENTRYTYPE_ToolTip: + Result = WriteChildEntry(inst, tn, Level, Flags, fh, "TOOLTIP", "ENDTOOLTIP\n"); + break; + case ENTRYTYPE_ToolTip_Group: + Result = WriteChildEntry(inst, tn, Level, Flags, fh, "GROUP", "ENDGROUP"); + break; + case ENTRYTYPE_ToolTip_Member: + Result = WriteChildEntry(inst, tn, Level, Flags, fh, "MEMBER", "ENDMEMBER"); + break; + case ENTRYTYPE_ToolTip_HBar: + Result = WriteChildEntry(inst, tn, Level, Flags, fh, "HBAR", NULL); + break; + case ENTRYTYPE_ToolTip_String: + Result = WriteChildEntry(inst, tn, Level, Flags, fh, "STRING", NULL); + break; + case ENTRYTYPE_ToolTip_Space: + Result = WriteChildEntry(inst, tn, Level, Flags, fh, "SPACE", NULL); + break; + case ENTRYTYPE_ToolTip_DtImage: + Result = WriteChildEntry(inst, tn, Level, Flags, fh, "DTIMAGE", NULL); + break; + default: + break; + } + + return Result; +} + +//---------------------------------------------------------------------------- + +static LONG WriteChildEntry(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn, + ULONG Level, ULONG Flags, + BPTR fh, CONST_STRPTR NameStart, CONST_STRPTR NameEnd) +{ + struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User; + const struct FtAttribute *fta; + struct MUI_NListtree_TreeNode *tnChild; + LONG Result = RETURN_OK; + ULONG n; + char Line[80]; + + for (n = 0; n < Level; n++) + { + if (EOF == FPuts(fh, "\t")) + { + Result = IoErr(); + break; + } + } + + sprintf(Line, "%s", NameStart); + if (EOF == FPuts(fh, Line)) + Result = IoErr(); + + // Write Attributes + for (fta = (const struct FtAttribute *) fte->ftle_AttributesList.lh_Head; + RETURN_OK == Result && fta != (const struct FtAttribute *) &fte->ftle_AttributesList.lh_Tail; + fta = (const struct FtAttribute *) fta->fta_Node.ln_Succ) + { + char Line[120]; + char ValueString[120]; + + + GetAttributeValueString(fta, ValueString, sizeof(ValueString)); + + sprintf(Line, " %s", GetAttributeName(fta->fta_Type)); + + if (EOF == FPuts(fh, Line)) + { + Result = IoErr(); + break; + } + + if (strlen(ValueString) > 0) + { + sprintf(Line, " \"%s\"", ValueString); + if (EOF == FPuts(fh, Line)) + { + Result = IoErr(); + break; + } + } + } + // End Attribute list + if (EOF == FPuts(fh, "\n")) + Result = IoErr(); + + tnChild = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + tn, + MUIV_NListtree_GetEntry_Position_Head, + 0); + + // Write Children + while (tnChild && RETURN_OK == Result) + { + d1(kprintf(__FILE__ "/%s/%ld: tnChild=%08lx <%s>\n", __FUNC__, __LINE__, tnChild, tnChild->tn_Name)); + + Result = WriteChild(inst, tnChild, Level + 1, Flags, fh); + + tnChild = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + tnChild, + MUIV_NListtree_GetEntry_Position_Next, + 0); + } + + if (NameEnd) + { + for (n = 0; n < Level; n++) + { + if (EOF == FPuts(fh, "\t")) + { + Result = IoErr(); + break; + } + } + + sprintf(Line, "%s\n", NameEnd); + + if (EOF == FPuts(fh, Line)) + Result = IoErr(); + } + + if (RETURN_OK == Result && (Flags & FTWRITEFLAG_CLEAR_CHANGE_FLAG)) + fte->ftle_Changed = FALSE; + + return Result; +} + +//---------------------------------------------------------------------------- + +static LONG SaveIcon(struct FileTypesPrefsInst *inst, CONST_STRPTR IconName) +{ + struct DiskObject *icon, *allocIcon; + + static UBYTE ImageData[] = + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0x80, 0x00, 0x40, 0x00, 0x00, 0x00, 0x18, 0x00, 0x60, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x20, 0xFC, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x41, 0x02, 0x08, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x40, 0x82, 0x08, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x40, 0x82, 0x08, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x21, 0x04, 0x08, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x1E, 0x18, 0x10, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x20, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x02, 0x1C, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x0C, 0x00, + 0x40, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x0C, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, + 0xD5, 0x55, 0x55, 0x55, 0x55, 0x56, 0x00, 0x00, 0xD5, 0x55, 0x50, 0x00, 0x55, 0x55, 0x80, 0x00, + 0xD5, 0x55, 0x47, 0xFF, 0x95, 0x55, 0x60, 0x00, 0xD5, 0x55, 0x5F, 0x03, 0xE5, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x3E, 0x55, 0xF5, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x3F, 0x55, 0xF5, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x3F, 0x55, 0xF5, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x5E, 0x53, 0xF5, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x41, 0x47, 0xE5, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x55, 0x1F, 0xD5, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x55, 0x7F, 0x15, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x54, 0xFC, 0x55, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x55, 0xE1, 0x55, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x54, 0xF5, 0x55, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x55, 0x05, 0x55, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x54, 0xF5, 0x55, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x54, 0xF5, 0x55, 0x55, 0x50, 0x00, 0x35, 0x55, 0x55, 0x05, 0x55, 0x55, 0x50, 0x00, + 0x0D, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, 0x00, 0x03, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + static struct Image NormalImage = + { + 0, 0, 54, 23, + 2, + (UWORD *)ImageData, + 3, 0, + NULL + }; + + static STRPTR defToolTypes[] = + { + "ACTION=USE", + NULL + }; + + static struct DiskObject DefaultIcon = + { + WB_DISKMAGIC, WB_DISKVERSION, + + { + NULL, + 0, 0, 54, 24, + GFLG_GADGIMAGE | GFLG_GADGHBOX, + GACT_RELVERIFY | GACT_IMMEDIATE, + GTYP_BOOLGADGET, + &NormalImage, NULL, + NULL, + 0, + NULL, + 0, + NULL + }, + + WBPROJECT, + NULL, + defToolTypes, + NO_ICON_POSITION, NO_ICON_POSITION, + NULL, + NULL, + 8192 + }; + + icon = allocIcon = GetDiskObject("ENV:sys/def_ScaFileType"); + if (NULL == icon) + icon = allocIcon = GetDiskObject("ENV:sys/def_pref"); + if (NULL == icon) + icon = &DefaultIcon; + + if (icon) + { + STRPTR oldDefaultTool = icon->do_DefaultTool; + + icon->do_DefaultTool = (STRPTR) inst->fpb_ProgramName; + + PutDiskObject((STRPTR) IconName, icon); + + icon->do_DefaultTool = oldDefaultTool; + + if (allocIcon) + FreeDiskObject(allocIcon); + } + + return RETURN_OK; +} + +//---------------------------------------------------------------------------- diff --git a/scalos/Plugins/Prefs/FileTypes/config.mk b/scalos/Plugins/Prefs/FileTypes/config.mk new file mode 100755 index 000000000..45e35782b --- /dev/null +++ b/scalos/Plugins/Prefs/FileTypes/config.mk @@ -0,0 +1,88 @@ +# $Date: 2012-08-10 13:47:28 +0200 (Fr, 10. Aug 2012) $ +# $Revision: 915 $ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +FONTSAMPLE_DIR = $(TOPLEVEL)/common/FontSampleMCC +ICONOBJMCC_DIR = $(TOPLEVEL)/common/IconobjectMCC +DATATYPESMCC_DIR = $(TOPLEVEL)/common/DataTypesMCC +COMMON_DIR = $(TOPLEVEL)/common/Plugin + +INCLUDES += -I$(FONTSAMPLE_DIR) \ + -I$(ICONOBJMCC_DIR) \ + -I$(DATATYPESMCC_DIR) \ + -I$(COMMON_DIR) + +SCALOS_LOCALE = $(OBJDIR)/ScalosFileTypes_locale.h + +CFLAGS += -D SCALOSLOCALE=$(SCALOS_LOCALE) + +vpath %.c $(COMMON_DIR) + +############################################################################## + +include $(COMMON_DIR)/config.mk + + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += -nostartfiles \ + -lmempools +# --verbose + + +OPTIONS += -Wno-format-y2k + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += -nostartfiles \ +# + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +DEFINES += -DMUI_OBSOLETE +LFLAGS += -nostartfiles -lmui \ +# + + +else + +############################################################################### +# AmigaOS + +LFLAGS += -lscalos \ + -lpreferences \ + -liconobject \ + -lmempools \ + -ldebug \ + -lmui \ + -lstack \ + -lnix \ + -lnixmain \ + -lamiga21 \ + -lamiga \ + -lstubs \ + +endif +endif +endif diff --git a/scalos/Plugins/Prefs/FileTypes/debug.h b/scalos/Plugins/Prefs/FileTypes/debug.h new file mode 100644 index 000000000..aea559dac --- /dev/null +++ b/scalos/Plugins/Prefs/FileTypes/debug.h @@ -0,0 +1,19 @@ +// debug.h +// $Date$ +// $Revision$ + +#ifndef DEBUG_H +#define DEBUG_H + +//---------------------------------------------------------------------------- + +#define d1(x) ; +#define d2(x) x; + +// from debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +//---------------------------------------------------------------------------- + +#endif /* DEBUG_H */ diff --git a/scalos/Plugins/Prefs/FileTypes/makefile b/scalos/Plugins/Prefs/FileTypes/makefile new file mode 100644 index 000000000..1042b260a --- /dev/null +++ b/scalos/Plugins/Prefs/FileTypes/makefile @@ -0,0 +1,184 @@ +# makefile für Scalos FileTypesPrefs.prefsplugin +# $Date$ +# $Revision$ +############################################################# + +SDPATH = // + +SUBDIRMAKE = $(MAKE) -s -C +FLEXCAT = FlexCat +CATCOMP = CatComp +AS = phxAss +LD = slink +CC = sc +ECHO = echo +LIBS = LIB:scm.lib \ + LIB:sc.lib \ + LIB:mempools.lib \ + ///SAS-lib/snprintf.lib \ + LIB:debug.lib \ + LIB:amiga.lib +LDFLAGS = quiet batch noicons +PRECOMP = Include:all.gst +OBJDIR = .sasobj +BINDIR = .bin_os3 +PREFSPATH = ../../../Prefs/FileTypes +FONTSAMPLE_DIR = ../../../common/FontSampleMCC +ICONOBJMCC_DIR = ../../../common/IconobjectMCC +DATATYPESMCC_DIR = ../../../common/DataTypesMCC +COMMON_DIR = ../../../common/Plugin + +.SUFFIXES: .s .asm .plugin .plugin.debug + +############################################################# + +CSRCS = $(COMMON_DIR)/plugin-classic.c \ + FileTypesPrefs.c \ + ReadFtPrefs.c \ + WriteFtPrefs.c \ + DefIcons.c \ + DefIconsPrefs.c \ + DefaultDefIconsPrefs.c \ + $(FONTSAMPLE_DIR)/FontSampleMCC.c \ + $(ICONOBJMCC_DIR)/IconobjectMCC.c \ + $(DATATYPESMCC_DIR)/DataTypesMCC.c \ + +############################################################# + +CFLAGS = optimize nostackcheck nover dbg=s \ + data=FAR code=far \ + define SCALOSLOCALE=$(SCALOS_LOCALE) \ + idlen=64 idir=///include idir=///common/FontSampleMCC \ + idir=$(subst ../,/,$(PREFSPATH)) \ + idir=$(subst ../,/,$(ICONOBJMCC_DIR)) \ + idir=$(subst ../,/,$(DATATYPESMCC_DIR)) \ + idir=///common/Plugin +AFLAGS = QUIET DS opt=NRQB NOEXE linedebug I=SC:Assembler_Headers +#AFLAGS = -t -iINCLUDE: + +############################################################# + +PLUGIN = FileTypes.prefsplugin +PLUGINDBG = $(PLUGIN).debug +CAT_FILE = Scalos/ScalosFileTypes.catalog +DESTTOOL = Scalos:Prefs/ +DESTCAT = Locale:Catalogs +SRCCAT = $(subst ../,/,$(PREFSPATH)) +SCALOS_LOCALE = $(OBJDIR)/ScalosFileTypes_locale.h +CATCOMPHEADER = $(SCALOS_LOCALE) +CATS = deutsch \ + français + +ALLCATS = $(foreach cat,$(CATS),$(SRCCAT)/catalogs/$(cat)/$(CAT_FILE)) + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +XSRCS = $(notdir $(CSRCS)) +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(XSRCS:%.c=$(OBJDIR)/$(notdir %).o) + +############################################################# + +All: $(BINDIR)/$(PLUGIN) \ + $(BINDIR)/$(PLUGINDBG) \ + allcatalogs +# install +# clean + +############################################################# + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-classic.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/DataTypesMCC.o : $(DATATYPESMCC_DIR)/DataTypesMCC.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/FontSampleMCC.o : $(FONTSAMPLE_DIR)/FontSampleMCC.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/IconobjectMCC.o : $(ICONOBJMCC_DIR)/IconobjectMCC.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $< objectname $@ + +############################################################# + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-common.c \ + plugin_data.h $(COMMON_DIR)/plugin.h + +$(OBJDIR)/FileTypesPrefs.o : FileTypesPrefs.h FileTypesPrefs_proto.h \ + $(ICONOBJMCC_DIR)/IconobjectMCC.h \ + FileTypesPrefsImage.h plugin_data.h $(COMMON_DIR)/plugin.h \ + $(SCALOS_LOCALE) debug.h + +$(OBJDIR)/ReadFtPrefs.o : ReadFtPrefs.c FileTypesPrefs.h \ + FileTypesPrefs_proto.h debug.h + +$(OBJDIR)/WriteFtPrefs.o : WriteFtPrefs.c FileTypesPrefs.h \ + FileTypesPrefs_proto.h debug.h + +$(OBJDIR)/DefIcons.o : DefIcons.c FileTypesPrefs.h \ + FileTypesPrefs_proto.h debug.h + +$(OBJDIR)/DefIconsPrefs.o : DefIconsPrefs.c FileTypesPrefs.h \ + FileTypesPrefs_proto.h debug.h \ + $(SCALOS_LOCALE) + +$(OBJDIR)/DefaultDefIconsPrefs.o : DefaultDefIconsPrefs.c + +$(OBJDIR)/DataTypesMCC.o: $(DATATYPESMCC_DIR)/DataTypesMCC.c \ + $(DATATYPESMCC_DIR)/DataTypesMCC.h + +$(OBJDIR)/FontSampleMCC.o : $(FONTSAMPLE_DIR)/FontSampleMCC.c \ + $(FONTSAMPLE_DIR)/FontSampleMCC.h + +$(OBJDIR)/IconobjectMCC.o : $(ICONOBJMCC_DIR)/IconobjectMCC.c \ + $(ICONOBJMCC_DIR)/IconobjectMCC.h debug.h + +############################################################# + +$(CATCOMPHEADER) : $(PREFSPATH)/ScalosFileTypes.cd + @printf '\033[32mMake CatComp header: \033[31m\033[1m$@ \033[32mfrom \033[31m$<\033[0m\n' + $(FLEXCAT) $(subst ../,/,$<) $@=$(SDPATH)/CatComp_h.sd + +$(BINDIR)/$(PLUGIN) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) to $@ FROM $(OBJS) lib $(LIBS) $(LDFLAGS) STRIPDEBUG + +$(BINDIR)/$(PLUGINDBG) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) to $@ FROM $(OBJS) lib $(LIBS) $(LDFLAGS) ADDSYM + +############################################################# + +install: + @avail flush + @printf '\033[32mInstall: \033[31m\033[1m$(PLUGIN)\033[0m\n' + @copy $(BINDIR)/$(PLUGIN) "$(DESTTOOL)" + @printf '\033[32mInstall: \033[31m\033[1m$(CAT_FILE)\033[0m\n' + -@$(foreach cat,$(CATS),copy "$(SRCCAT)/catalogs/$(cat)/$(CAT_FILE)" "$(DESTCAT)/$(cat)/Scalos" clone;) + +############################################################# + +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + @delete $(BINDIR)/$(PLUGIN) $(BINDIR)/$(PLUGINDBG) $(OBJS) $(subst ../,/,$(CATCOMPHEADER)) $(ALLCATS) + @printf '\033[0m' + +############################################################# + +# make all Scalos preferences .catalogs +allcatalogs: + -@$(foreach cat,$(CATS),$(SUBDIRMAKE) $(PREFSPATH)/catalogs/$(cat)/Scalos;) + + +############################################################# + diff --git a/scalos/Plugins/Prefs/FileTypes/makefile-new b/scalos/Plugins/Prefs/FileTypes/makefile-new new file mode 100755 index 000000000..e4f1cc980 --- /dev/null +++ b/scalos/Plugins/Prefs/FileTypes/makefile-new @@ -0,0 +1,111 @@ +# $Date: 2011-08-09 11:15:58 +0200 (Di, 09. Aug 2011) $ +# $Revision: 828 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../../.. +endif + + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + PARENTDIR=/ + SDPATH=// +else + PARENTDIR=../ + SDPATH=../../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(BEGIN_OBJS) \ + $(OBJDIR)/FileTypesPrefs.o \ + $(OBJDIR)/ReadFtPrefs.o \ + $(OBJDIR)/WriteFtPrefs.o \ + $(OBJDIR)/DefIcons.o \ + $(OBJDIR)/DefIconsPrefs.o \ + $(OBJDIR)/DataTypesMCC.o \ + $(OBJDIR)/FontSampleMCC.o \ + $(OBJDIR)/IconobjectMCC.o \ + $(OBJDIR)/DefaultDefIconsPrefs.o \ + $(END_OBJS) + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Targets +# + +NAME = FileTypes.prefsplugin +NAME_DB = $(NAME).debug + +############################################################################## + +PREFSDIR = ../../../Prefs/FileTypes + +############################################################################## +# +# Some lame deps + +$(OBJDIR)/%.o: $(DATATYPESMCC_DIR)/%.c + @$(run-cc) + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) + +############################################################################## + +$(OBJDIR)/%.o: $(FONTSAMPLE_DIR)/%.c + @$(run-cc) + +$(OBJDIR)/%.o: $(ICONOBJMCC_DIR)/%.c + @$(run-cc) + +FileTypesPrefs.c DefIconsPrefs.c : $(SCALOS_LOCALE) + +$(SCALOS_LOCALE) : $(PREFSDIR)/ScalosFileTypes.cd + @$(ECHO) "FlexCat $@" + $(FLEXCAT) $(subst ../,$(PARENTDIR),$<) $@=$(SDPATH)/CatComp_h.sd + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + @$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) Scalos:Prefs/ clone + avail flush + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* \ + $(SCALOS_LOCALE) + +############################################################################## + diff --git a/scalos/Plugins/Prefs/FileTypes/plugin_data.h b/scalos/Plugins/Prefs/FileTypes/plugin_data.h new file mode 100644 index 000000000..e52c7fe06 --- /dev/null +++ b/scalos/Plugins/Prefs/FileTypes/plugin_data.h @@ -0,0 +1,27 @@ +// plugin_data.h +// $Date$ +// $Revision$ + +#ifndef PLUGIN_DATA_H_INCLUDED +#define PLUGIN_DATA_H_INCLUDED + +#include +#include + +#define PLUGIN_TYPE PREFS + +#define LIB_VERSION 40 +#define LIB_REVISION 25 + +#define LIB_NAME "FileTypes.prefsplugin" +#define LIB_VERSTRING "$VER: " LIB_NAME " " \ + STR(LIB_VERSION) "." STR(LIB_REVISION) \ + " " __DATE__ \ + COMPILER_STRING " ©2003" CURRENTYEAR \ + " The Scalos Team" + +//---------------------------------------------------------------------------- +// code and includes to define the structs and functions used above + +#endif /* PLUGUN_DATA_H_INCLUDED */ + diff --git a/scalos/Plugins/Prefs/Menu/DefaultMenu.c b/scalos/Plugins/Prefs/Menu/DefaultMenu.c new file mode 100644 index 000000000..4e6d8fbba --- /dev/null +++ b/scalos/Plugins/Prefs/Menu/DefaultMenu.c @@ -0,0 +1,646 @@ +// DefaultMenu.c +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include + +#define ScalosMenu_NUMBERS +#include STR(SCALOSLOCALE) + +#include "MenuPrefs.h" + +#define MSGID_MENU_SEPARATOR MSGID_DEFAULT_MENU_EMPTY_SHORT + +const struct DefaultMenuEntry DefaultMenu[] = + { + { SCAMENUTYPE_Menu, 0, MSGID_DEFAULT_MENU_SCALOS, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_MainMenu }, + { SCAMENUTYPE_MenuItem, 1, MSGID_COM_UNDO, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "undo", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_COM_REDO, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "redo", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_BACKDROP, MSGID_DEFAULT_MENU_BACKDROP_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "backdrop", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_EXECUTECOMMAND, MSGID_DEFAULT_MENU_EXECUTECOMMAND_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "executecommand", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_REDRAWALL, MSGID_DEFAULT_MENU_REDRAWALL_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "redrawall", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_UPDATEALL, MSGID_DEFAULT_MENU_UPDATEALL_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "updateall", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_LASTMESSAGE, MSGID_DEFAULT_MENU_UPDATEALL_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "lastmsg", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_ABOUT, MSGID_DEFAULT_MENU_ABOUT_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "about", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_QUIT, MSGID_DEFAULT_MENU_QUIT_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "quit", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_Menu, 0, MSGID_DEFAULT_MENU_WINDOW, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_MainMenu }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_NEWDRAWER, MSGID_DEFAULT_MENU_NEWDRAWER_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "makedir", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_OPENPARENT, MSGID_DEFAULT_MENU_OPENPARENT_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "parent", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_CLOSE, MSGID_DEFAULT_MENU_CLOSE_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "close", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_UPDATE, MSGID_DEFAULT_MENU_UPDATE_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "update", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_SELECTCONTENTS, MSGID_DEFAULT_MENU_SELECTCONTENTS_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "selectall", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_CLEARSELECTION, MSGID_DEFAULT_MENU_CLEARSELECTION_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "clearselection", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_Menu, 1, MSGID_DEFAULT_MENU_CLEANUPBY, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_CLEANUPBY_COLUMN, MSGID_DEFAULT_MENU_CLEANUPBY_COLUMN_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "Scalos:Plugins/Menu/sorted_cleanup.plugin", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Plugin }, + { SCAMENUTYPE_MenuItem, 2, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_CLEANUPBY_NAME, MSGID_DEFAULT_MENU_CLEANUPBY_NAME_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "cleanupbyname", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_CLEANUPBY_DATE, MSGID_DEFAULT_MENU_CLEANUPBY_DATE_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "cleanupbydate", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_CLEANUPBY_SIZE, MSGID_DEFAULT_MENU_CLEANUPBY_SIZE_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "cleanupbysize", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_CLEANUPBY_TYPE, MSGID_DEFAULT_MENU_CLEANUPBY_TYPE_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "cleanupbytype", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_RESIZETOFIT, MSGID_DEFAULT_MENU_RESIZETOFIT_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "sizetofit", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_Menu, 1, MSGID_DEFAULT_MENU_SNAPSHOT, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_SNAPSHOT_WINDOW, MSGID_DEFAULT_MENU_SNAPSHOT_WINDOW_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "snapshotwindow", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_SNAPSHOT_ALL, MSGID_DEFAULT_MENU_SNAPSHOT_ALL_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "snapshotall", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_Menu, 1, MSGID_DEFAULT_MENU_SHOW, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_SHOW_DEFAULT, MSGID_DEFAULT_MENU_SHOW_DEFAULT_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "showdefault", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_SHOW_ONLYICONS, MSGID_DEFAULT_MENU_SHOW_DEFAULT_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "showonlyicons", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_SHOW_ALLFILES, MSGID_DEFAULT_MENU_SHOW_ALLFILES_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "showallfiles", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_Menu, 1, MSGID_DEFAULT_MENU_VIEWBY, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_VIEWBY_DEFAULT, MSGID_DEFAULT_MENU_VIEWBY_DEFAULT_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "viewbydefault", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 2, 0, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_VIEWBY_ICON, MSGID_DEFAULT_MENU_VIEWBY_ICON_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "viewbyicon", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 2, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_VIEWBY_NAME, MSGID_DEFAULT_MENU_VIEWBY_NAME_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "viewbytext", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_VIEWBY_DATE, MSGID_DEFAULT_MENU_VIEWBY_DATE_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "viewbydate", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_VIEWBY_SIZE, MSGID_DEFAULT_MENU_VIEWBY_SIZE_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "viewbysize", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_VIEWBY_TYPE, MSGID_DEFAULT_MENU_VIEWBY_TYPE_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "viewbytype", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_FIND, MSGID_DEFAULT_MENU_FIND_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "System:System/Find", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, MCOMFLGF_Args, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_Menu, 0, MSGID_DEFAULT_MENU_ICONS, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_MainMenu }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_OPEN, MSGID_DEFAULT_MENU_OPEN_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "open", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_CLONE, MSGID_DEFAULT_MENU_CLONE_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "clone", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_RENAME, MSGID_DEFAULT_MENU_RENAME_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "rename", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_INFORMATION, MSGID_DEFAULT_MENU_INFORMATION_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "iconinfo", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_SNAPSHOT, MSGID_DEFAULT_MENU_SNAPSHOT_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "snapshot", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_UNSNAPSHOT, MSGID_DEFAULT_MENU_UNSNAPSHOT_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "unsnapshot", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_LEAVEOUT, MSGID_DEFAULT_MENU_LEAVEOUT_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "leaveout", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_PUTAWAY, MSGID_DEFAULT_MENU_PUTAWAY_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "putaway", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_DELETE, MSGID_DEFAULT_MENU_DELETE_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "delete", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_FORMAT, MSGID_DEFAULT_MENU_FORMAT_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "formatdisk", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_EMPTYTRASH, MSGID_DEFAULT_MENU_EMPTYTRASH_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "emptytrashcan", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_ToolsMenu, 0, MSGID_TOOLS_MENU, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_MainMenu }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_RESETSCALOS, MSGID_DEFAULT_MENU_RESETSCALOS_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "reset", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_LastInsertedMenu }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_NEWSHELL, MSGID_DEFAULT_MENU_NEWSHELL_SHORT, DEFAULTPARENTNODE_LastInsertedMenu }, +#if defined(__MORPHOS__) || defined(__AROS__) + { SCAMENUTYPE_Command, 2, (ULONG) "c:NewShell \"CON:190/295/700/412/Scalos Shell/CLOSE\"", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_AmigaDOS, 0, 0, DEFAULT_STACKSIZE }, +#else /* __MORPHOS__ */ + { SCAMENUTYPE_Command, 2, (ULONG) "SYS:System/CLI \"KCON:0/235/645/290/ToolManager Shell/C\"", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_AmigaDOS, 0, 0, DEFAULT_STACKSIZE }, +#endif /* __MORPHOS__ */ + { SCAMENUTYPE_Menu, 0, MSGID_DEFAULT_MENU_DRAWERS, MSGID_DEFAULT_MENU_EMPTY_SHORT, }, +#if defined(__MORPHOS__) + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_DRAWERS_VOYAGER, MSGID_DEFAULT_MENU_DRAWERS_VOYAGER_SHORT, DEFAULTPARENTNODE_MainMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "SYS:Apps/Voyager", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_IconWindow }, +#endif /* __MORPHOS__ */ + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_DRAWERS_ENVARC_SYS, MSGID_DEFAULT_MENU_DRAWERS_ENVARC_SYS_SHORT, DEFAULTPARENTNODE_MainMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "ENVARC:Sys/", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_IconWindow }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_DRAWERS_WBSTARTUP, MSGID_DEFAULT_MENU_DRAWERS_WBSTARTUP_SHORT, DEFAULTPARENTNODE_MainMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "SYS:WBStartup", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_IconWindow }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_MainMenu }, +#if !defined(__MORPHOS__) + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_DRAWERS_PREFS, MSGID_DEFAULT_MENU_DRAWERS_PREFS_SHORT, DEFAULTPARENTNODE_MainMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "SYS:Prefs/", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_IconWindow }, +#endif /* __MORPHOS__ */ + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_DRAWERS_SCALOSPREFS, MSGID_DEFAULT_MENU_DRAWERS_SCALOSPREFS_SHORT, DEFAULTPARENTNODE_MainMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "Scalos:Prefs", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_IconWindow }, +#if defined(__MORPHOS__) + { SCAMENUTYPE_Menu, 0, MSGID_DEFAULT_MENU_PREFS, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_MainMenu }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_PREFS_SYSTEM, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_MainMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "MOSSYS:Prefs/Preferences", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_PREFS_MUI, MSGID_DEFAULT_MENU_PREFS_MUI_SHORT, DEFAULTPARENTNODE_MainMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "MOSSYS:Prefs/MUI", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, +// { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_PREFS_AHI, MSGID_DEFAULT_MENU_PREFS_AHI_SHORT, DEFAULTPARENTNODE_MainMenu }, +// { SCAMENUTYPE_Command, 2, (ULONG) "MOSSYS:Prefs/AHI", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_MainMenu }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_PREFS_SCALOS, MSGID_DEFAULT_MENU_PREFS_SCALOS_SHORT, DEFAULTPARENTNODE_MainMenu }, + { SCAMENUTYPE_Command, 2, (ULONG) "Scalos:Prefs/Scalos Prefs", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, +#endif /* __MORPHOS__ */ + + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_OPEN, MSGID_DEFAULT_MENU_OPEN_SHORT, DEFAULTPARENTNODE_Popup_Disk }, + { SCAMENUTYPE_Command, 2, (ULONG) "open", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_INFORMATION, MSGID_DEFAULT_MENU_INFORMATION_SHORT, DEFAULTPARENTNODE_Popup_Disk }, + { SCAMENUTYPE_Command, 2, (ULONG) "iconinfo", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_Popup_Disk }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_BROWSE, MSGID_DEFAULT_MENU_BROWSE_SHORT, DEFAULTPARENTNODE_Popup_Disk }, + { SCAMENUTYPE_Command, 2, (ULONG) "Scalos:Tools/browse.script %%p", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_AmigaDOS, 0, MCOMFLGF_Args, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_FIND, MSGID_DEFAULT_MENU_FIND_SHORT, DEFAULTPARENTNODE_Popup_Disk }, + { SCAMENUTYPE_Command, 2, (ULONG) "System:System/Find", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, MCOMFLGF_Args, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_Popup_Disk }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_SNAPSHOT, MSGID_DEFAULT_MENU_SNAPSHOT_SHORT, DEFAULTPARENTNODE_Popup_Disk }, + { SCAMENUTYPE_Command, 2, (ULONG) "snapshot", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_UNSNAPSHOT, MSGID_DEFAULT_MENU_UNSNAPSHOT_SHORT, DEFAULTPARENTNODE_Popup_Disk }, + { SCAMENUTYPE_Command, 2, (ULONG) "unsnapshot", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_Popup_Disk }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_PASTE, MSGID_DEFAULT_MENU_PASTE_SHORT, DEFAULTPARENTNODE_Popup_Disk }, + { SCAMENUTYPE_Command, 2, (ULONG) "paste", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_Popup_Disk }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_DISKCOPY, MSGID_DEFAULT_MENU_DISKCOPY_SHORT, DEFAULTPARENTNODE_Popup_Disk }, + { SCAMENUTYPE_Command, 2, (ULONG) "sys:system/diskcopy", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_RELABEL, MSGID_DEFAULT_MENU_RELABEL_SHORT, DEFAULTPARENTNODE_Popup_Disk }, + { SCAMENUTYPE_Command, 2, (ULONG) "rename", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_Popup_Disk }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_FORMAT, MSGID_DEFAULT_MENU_FORMAT_SHORT, DEFAULTPARENTNODE_Popup_Disk }, + { SCAMENUTYPE_Command, 2, (ULONG) "formatdisk", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_Popup_Disk }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_PROPERTIES, MSGID_DEFAULT_MENU_PROPERTIES_SHORT, DEFAULTPARENTNODE_Popup_Disk }, + { SCAMENUTYPE_Command, 2, (ULONG) "iconproperties", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_OPEN, MSGID_DEFAULT_MENU_OPEN_SHORT, DEFAULTPARENTNODE_Popup_Drawer }, + { SCAMENUTYPE_Command, 2, (ULONG) "open", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_INFORMATION, MSGID_DEFAULT_MENU_INFORMATION_SHORT, DEFAULTPARENTNODE_Popup_Drawer }, + { SCAMENUTYPE_Command, 2, (ULONG) "iconinfo", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_Popup_Drawer }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_BROWSE, MSGID_DEFAULT_MENU_BROWSE_SHORT, DEFAULTPARENTNODE_Popup_Drawer }, + { SCAMENUTYPE_Command, 2, (ULONG) "Scalos:Tools/browse.script %%p", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_AmigaDOS, 0, MCOMFLGF_Args, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_FIND, MSGID_DEFAULT_MENU_FIND_SHORT, DEFAULTPARENTNODE_Popup_Drawer }, + { SCAMENUTYPE_Command, 2, (ULONG) "System:System/Find", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, MCOMFLGF_Args, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_Popup_Drawer }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_SNAPSHOT, MSGID_DEFAULT_MENU_SNAPSHOT_SHORT, DEFAULTPARENTNODE_Popup_Drawer }, + { SCAMENUTYPE_Command, 2, (ULONG) "snapshot", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_UNSNAPSHOT, MSGID_DEFAULT_MENU_UNSNAPSHOT_SHORT, DEFAULTPARENTNODE_Popup_Drawer }, + { SCAMENUTYPE_Command, 2, (ULONG) "unsnapshot", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_Popup_Drawer }, + { SCAMENUTYPE_Menu, 1, MSGID_DEFAULT_MENU_EDIT, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_Popup_Drawer }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_CUT, MSGID_DEFAULT_MENU_CUT_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "cut", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_COPY, MSGID_DEFAULT_MENU_COPY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "copy", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PASTE, MSGID_DEFAULT_MENU_PASTE_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "paste", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_RENAME, MSGID_DEFAULT_MENU_RENAME_SHORT, DEFAULTPARENTNODE_Popup_Drawer }, + { SCAMENUTYPE_Command, 2, (ULONG) "rename", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_LEAVEOUT, MSGID_DEFAULT_MENU_LEAVEOUT_SHORT, DEFAULTPARENTNODE_Popup_Drawer }, + { SCAMENUTYPE_Command, 2, (ULONG) "leaveout", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_PUTAWAY, MSGID_DEFAULT_MENU_PUTAWAY_SHORT, DEFAULTPARENTNODE_Popup_Drawer }, + { SCAMENUTYPE_Command, 2, (ULONG) "putaway", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_DELETE, MSGID_DEFAULT_MENU_DELETE_SHORT, DEFAULTPARENTNODE_Popup_Drawer }, + { SCAMENUTYPE_Command, 2, (ULONG) "delete", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_Popup_Drawer }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_PROPERTIES, MSGID_DEFAULT_MENU_PROPERTIES_SHORT, DEFAULTPARENTNODE_Popup_Drawer }, + { SCAMENUTYPE_Command, 2, (ULONG) "iconproperties", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_OPEN, MSGID_DEFAULT_MENU_OPEN_SHORT, DEFAULTPARENTNODE_Popup_ToolProject }, + { SCAMENUTYPE_Command, 2, (ULONG) "open", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_INFORMATION, MSGID_DEFAULT_MENU_INFORMATION_SHORT, DEFAULTPARENTNODE_Popup_ToolProject }, + { SCAMENUTYPE_Command, 2, (ULONG) "iconinfo", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_Popup_ToolProject }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_SNAPSHOT, MSGID_DEFAULT_MENU_SNAPSHOT_SHORT, DEFAULTPARENTNODE_Popup_ToolProject }, + { SCAMENUTYPE_Command, 2, (ULONG) "snapshot", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_UNSNAPSHOT, MSGID_DEFAULT_MENU_UNSNAPSHOT_SHORT, DEFAULTPARENTNODE_Popup_ToolProject }, + { SCAMENUTYPE_Command, 2, (ULONG) "unsnapshot", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_Popup_ToolProject }, + { SCAMENUTYPE_Menu, 1, MSGID_DEFAULT_MENU_EDIT, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_Popup_ToolProject }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_CUT, MSGID_DEFAULT_MENU_CUT_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "cut", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_COPY, MSGID_DEFAULT_MENU_COPY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "copy", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PASTE, MSGID_DEFAULT_MENU_PASTE_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "paste", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_RENAME, MSGID_DEFAULT_MENU_RENAME_SHORT, DEFAULTPARENTNODE_Popup_ToolProject }, + { SCAMENUTYPE_Command, 2, (ULONG) "rename", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_LEAVEOUT, MSGID_DEFAULT_MENU_LEAVEOUT_SHORT, DEFAULTPARENTNODE_Popup_ToolProject }, + { SCAMENUTYPE_Command, 2, (ULONG) "leaveout", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_PUTAWAY, MSGID_DEFAULT_MENU_PUTAWAY_SHORT, DEFAULTPARENTNODE_Popup_ToolProject }, + { SCAMENUTYPE_Command, 2, (ULONG) "putaway", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_DELETE, MSGID_DEFAULT_MENU_DELETE_SHORT, DEFAULTPARENTNODE_Popup_ToolProject }, + { SCAMENUTYPE_Command, 2, (ULONG) "delete", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_Popup_ToolProject }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_PROPERTIES, MSGID_DEFAULT_MENU_PROPERTIES_SHORT, DEFAULTPARENTNODE_Popup_ToolProject }, + { SCAMENUTYPE_Command, 2, (ULONG) "iconproperties", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_OPEN, MSGID_DEFAULT_MENU_OPEN_SHORT, DEFAULTPARENTNODE_Popup_Trashcan }, + { SCAMENUTYPE_Command, 2, (ULONG) "open", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_INFORMATION, MSGID_DEFAULT_MENU_INFORMATION_SHORT, DEFAULTPARENTNODE_Popup_Trashcan }, + { SCAMENUTYPE_Command, 2, (ULONG) "iconinfo", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_Popup_Trashcan }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_EMPTYTRASH, MSGID_DEFAULT_MENU_EMPTYTRASH_SHORT, DEFAULTPARENTNODE_Popup_Trashcan }, + { SCAMENUTYPE_Command, 2, (ULONG) "emptytrashcan", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_Popup_Trashcan }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_SNAPSHOT, MSGID_DEFAULT_MENU_SNAPSHOT_SHORT, DEFAULTPARENTNODE_Popup_Trashcan }, + { SCAMENUTYPE_Command, 2, (ULONG) "snapshot", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_UNSNAPSHOT, MSGID_DEFAULT_MENU_UNSNAPSHOT_SHORT, DEFAULTPARENTNODE_Popup_Trashcan }, + { SCAMENUTYPE_Command, 2, (ULONG) "unsnapshot", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_Popup_Trashcan }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_PROPERTIES, MSGID_DEFAULT_MENU_PROPERTIES_SHORT, DEFAULTPARENTNODE_Popup_Trashcan }, + { SCAMENUTYPE_Command, 2, (ULONG) "iconproperties", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_CLOSE, MSGID_DEFAULT_MENU_CLOSE_SHORT, DEFAULTPARENTNODE_Popup_Window }, + { SCAMENUTYPE_Command, 2, (ULONG) "close", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_OPENPARENT, MSGID_DEFAULT_MENU_OPENPARENT_SHORT, DEFAULTPARENTNODE_Popup_Window }, + { SCAMENUTYPE_Command, 2, (ULONG) "parent", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_Popup_Window }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_BROWSE, MSGID_DEFAULT_MENU_BROWSE_SHORT, DEFAULTPARENTNODE_Popup_Window }, + { SCAMENUTYPE_Command, 2, (ULONG) "Scalos:Tools/browse.script %%p", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_AmigaDOS, 0, MCOMFLGF_Args, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_FIND, MSGID_DEFAULT_MENU_FIND_SHORT, DEFAULTPARENTNODE_Popup_Window }, + { SCAMENUTYPE_Command, 2, (ULONG) "System:System/Find", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, MCOMFLGF_Args, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_Popup_Window }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_PASTE, MSGID_DEFAULT_MENU_PASTE_SHORT, DEFAULTPARENTNODE_Popup_Window }, + { SCAMENUTYPE_Command, 2, (ULONG) "paste", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_Popup_Window }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_UPDATE, MSGID_DEFAULT_MENU_UPDATE_SHORT, DEFAULTPARENTNODE_Popup_Window }, + { SCAMENUTYPE_Command, 2, (ULONG) "update", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_CLEANUP, MSGID_DEFAULT_MENU_CLEANUP_SHORT, DEFAULTPARENTNODE_Popup_Window }, + { SCAMENUTYPE_Command, 2, (ULONG) "Scalos:Plugins/Menu/sorted_cleanup.plugin", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Plugin }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_RESIZETOFIT, MSGID_DEFAULT_MENU_RESIZETOFIT_SHORT, DEFAULTPARENTNODE_Popup_Window }, + { SCAMENUTYPE_Command, 2, (ULONG) "sizetofit", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_Popup_Window }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_SELECTCONTENTS, MSGID_DEFAULT_MENU_SELECTCONTENTS_SHORT, DEFAULTPARENTNODE_Popup_Window }, + { SCAMENUTYPE_Command, 2, (ULONG) "selectall", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_CLEARSELECTION, MSGID_DEFAULT_MENU_CLEARSELECTION_SHORT, DEFAULTPARENTNODE_Popup_Window }, + { SCAMENUTYPE_Command, 2, (ULONG) "clearselection", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_Popup_Window }, + { SCAMENUTYPE_Menu, 1, MSGID_DEFAULT_MENU_SNAPSHOT, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_Popup_Window }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_SNAPSHOT_WINDOW, MSGID_DEFAULT_MENU_SNAPSHOT_WINDOW_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "snapshotwindow", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_SNAPSHOT_ALL, MSGID_DEFAULT_MENU_SNAPSHOT_ALL_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "snapshotall", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_Popup_Window }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_NEWDRAWER, MSGID_DEFAULT_MENU_NEWDRAWER_SHORT, DEFAULTPARENTNODE_Popup_Window }, + { SCAMENUTYPE_Command, 2, (ULONG) "makedir", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_Popup_Window }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_PROPERTIES, MSGID_DEFAULT_MENU_PROPERTIES_SHORT, DEFAULTPARENTNODE_Popup_Window }, + { SCAMENUTYPE_Command, 2, (ULONG) "windowproperties", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_OPEN, MSGID_DEFAULT_MENU_OPEN_SHORT, DEFAULTPARENTNODE_Popup_AppIcon }, + { SCAMENUTYPE_Command, 2, (ULONG) "open", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_INFORMATION, MSGID_DEFAULT_MENU_INFORMATION_SHORT, DEFAULTPARENTNODE_Popup_AppIcon }, + { SCAMENUTYPE_Command, 2, (ULONG) "iconinfo", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_CLONE, MSGID_DEFAULT_MENU_CLONE_SHORT, DEFAULTPARENTNODE_Popup_AppIcon }, + { SCAMENUTYPE_Command, 2, (ULONG) "clone", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_RENAME, MSGID_DEFAULT_MENU_RENAME_SHORT, DEFAULTPARENTNODE_Popup_AppIcon }, + { SCAMENUTYPE_Command, 2, (ULONG) "rename", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_Popup_AppIcon }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_SNAPSHOT, MSGID_DEFAULT_MENU_SNAPSHOT_SHORT, DEFAULTPARENTNODE_Popup_AppIcon }, + { SCAMENUTYPE_Command, 2, (ULONG) "snapshot", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_UNSNAPSHOT, MSGID_DEFAULT_MENU_UNSNAPSHOT_SHORT, DEFAULTPARENTNODE_Popup_AppIcon }, + { SCAMENUTYPE_Command, 2, (ULONG) "unsnapshot", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_Popup_AppIcon }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_LEAVEOUT, MSGID_DEFAULT_MENU_LEAVEOUT_SHORT, DEFAULTPARENTNODE_Popup_AppIcon }, + { SCAMENUTYPE_Command, 2, (ULONG) "leaveout", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_PUTAWAY, MSGID_DEFAULT_MENU_PUTAWAY_SHORT, DEFAULTPARENTNODE_Popup_AppIcon }, + { SCAMENUTYPE_Command, 2, (ULONG) "putaway", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_Popup_AppIcon }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_DELETE, MSGID_DEFAULT_MENU_DELETE_SHORT, DEFAULTPARENTNODE_Popup_AppIcon }, + { SCAMENUTYPE_Command, 2, (ULONG) "delete", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_FORMAT, MSGID_DEFAULT_MENU_FORMAT_SHORT, DEFAULTPARENTNODE_Popup_AppIcon }, + { SCAMENUTYPE_Command, 2, (ULONG) "formatdisk", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_EMPTYTRASH, MSGID_DEFAULT_MENU_EMPTYTRASH_SHORT, DEFAULTPARENTNODE_Popup_AppIcon }, + { SCAMENUTYPE_Command, 2, (ULONG) "emptytrashcan", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + + // Desktop popup + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_EXECUTECOMMAND, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_Popup_Desktop }, + { SCAMENUTYPE_Command, 2, (ULONG) "executecommand", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_BROWSE, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_Popup_Desktop }, + { SCAMENUTYPE_Command, 2, (ULONG) "Scalos:Tools/browse.script %%p", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_AmigaDOS, 0, MCOMFLGF_Args, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_Popup_Desktop }, + { SCAMENUTYPE_MenuItem, 1, MSGID_COM_UNDO, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_Popup_Desktop }, + { SCAMENUTYPE_Command, 2, (ULONG) "undo", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_COM_REDO, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_Popup_Desktop }, + { SCAMENUTYPE_Command, 2, (ULONG) "redo", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_Popup_Desktop }, +#if defined(__MORPHOS__) + { SCAMENUTYPE_Menu, 1, MSGID_DEFAULT_TOOLS, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_Popup_Desktop }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_TOOLS_MOUNTER, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Tools/Mounter", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_TOOLS_SCSICONFIG, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Tools/SCSIConfig", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_TOOLS_SNOOPIUM, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Tools/Snoopium", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_TOOLS_DEFRAG, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Tools/Defrag", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_TOOLS_FTMANAGER, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Tools/FTManager", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_TOOLS_MUISHELL, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Tools/MUIShell", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_TOOLS_SFSDOCTOR, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Tools/SFSDoctor", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_TOOLS_UNITCONTROL, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Tools/UnitControl", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_TOOLS_FILEIMAGECTRL, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Tools/FileImageCtrl", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_TOOLS_HDCONFIG, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Tools/HDConfig", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_TOOLS_REGTOOL, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Tools/RegTool", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_TOOLS_SHELL, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Tools/Shell", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_Menu, 1, MSGID_DEFAULT_UTILITIES, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_Popup_Desktop }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_EDITOR, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/Editor", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_FRAGMENT, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/Fragment", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_GRABBER, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/Grabber", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_GRAPHICBOARDS, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/GraphicBoards", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_KEYSTROKE, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/Keystroke", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_MINICALC, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/MiniCalc", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_MORE, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/More", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_MUIPROCALC, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/MUIProCalc", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_MULTIVIEW, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/Multiview", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_MYSTICVIEW, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/Mysticview", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_TASKMANAGER, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/TaskManager", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_TRANCESTATS, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/Trancestats", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_TIPS, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/Tips", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_ZOOM, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/Zoom", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_Menu, 1, MSGID_DEFAULT_PREFERENCES, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_Popup_Desktop }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_SYSTEM, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "MOSSYS:Prefs/Preferences", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_MUI, MSGID_DEFAULT_MENU_PREFS_MUI_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "MOSSYS:Prefs/MUI", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, +#elif defined(__amigaos4__) + { SCAMENUTYPE_Menu, 1, MSGID_DEFAULT_SYSTEM, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_Popup_Desktop }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_SYSTEM_FIND, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:System/Find", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_SYSTEM_FIXFONT, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:System/FixFonts", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_SYSTEM_FORMAT, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:System/Format", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_SYSTEM_FORMATCDRW, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:System/FormatCDRW", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_SYSTEM_MEDIATOOLBOX, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:System/Media Toolbox", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_SYSTEM_MOUNTER, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:System/Mounter", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_SYSTEM_TYPEMANAGER, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:System/TypeManager", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_SYSTEM_SHELL, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:System/Shell", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_SYSTEM_HELP, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:System/Help", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_Menu, 1, MSGID_DEFAULT_UTILITIES, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_Popup_Desktop }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_AMIGS, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/AmiGS/AmiGS", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_AMIPDF, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/AmiPDF/AmiPDF", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_SGRAB, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/SGrab/SGrab", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_CALCULATOR, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/Calculator", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_CLOCK, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/Clock", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_GRAPHICDUMP, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/GraphicDump", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_ICONEDIT, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/IconEdit", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_INITPRINTER, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/InitPrinter", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_KEYSHOW, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/KeyShow", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_MEMACS, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/Memacs", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_MULTIVIEW, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/Multiview", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_NOTEPAD, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/NotePad", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_PARTITIONWIZARD, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/PartitionWizard", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_PLAYCD, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/PlayCD", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_PREFSOBJECTSEDITOR, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/PrefsObjectsEditor", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_PRINTFILES, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/PrintFiles", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_RAWDISK, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/RawDisk", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_SHOWCONFIG, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/ShowConfig", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_UNARC, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/UnArc", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_USBINSPECTOR, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/USBInspector", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_Menu, 1, MSGID_DEFAULT_PREFERENCES, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_Popup_Desktop }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_AHI, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/AHI", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_AMIGAINPUT, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/AmigaInput", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_ASL, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/ASL", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_COMPATIBILITY, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/Compatibility", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_DEFICONS, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/DefIcons", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_DOS, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/DOS", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_FONT, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/Font", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_GUI, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/GUI", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_INPUT, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/Input", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_INTERNET, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/Internet", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_LOCALE, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/Locale", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_NOTIFICATIONS, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/Notifications", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_PALETTE, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/Palette", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_PICASSO96MODE, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/Picasso96Mode", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_POINTER, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/Pointer", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_POPUPMENU, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/PopupMenu", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_PRINTER, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/Printer", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_PRINTERGFX, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/PrinterGFX", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_PRINTERPS, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/PrinterPS", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_SCREENBLANKER, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/ScreenBlanker", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_SCREENMODE, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/ScreenMode", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_SCREENS, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/Screens", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_SERIAL, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/Serial", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_SOUND, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/Sound", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_TIME, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/Time", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_URL, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/URL", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_USB, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/USB", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_WBPATTERN, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/WBPattern", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_WBSTARTUP, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/WBStartup", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_WORKBENCH, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/Workbench", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, +#else + { SCAMENUTYPE_Menu, 1, MSGID_DEFAULT_SYSTEM, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_Popup_Desktop }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_SYSTEM_FIND, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:System/Find", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_SYSTEM_FIXFONT, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:System/FixFonts", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_SYSTEM_FORMAT, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:System/Format", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_SYSTEM_INTELLIFONT, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:System/Intellifont", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_SYSTEM_SHELL, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:System/Shell", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + + { SCAMENUTYPE_Menu, 1, MSGID_DEFAULT_TOOLS, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_Popup_Desktop }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_TOOLS_BENCHTRASH, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/BenchTrash", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_TOOLS_CALCULATOR, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Tools/Calculator", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_TOOLS_EDITPAD, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/EditPad", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_TOOLS_GRAPHICDUMP, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Tools/GraphicDump", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_TOOLS_HDTOOLBOX, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Tools/HDToolBox", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_TOOLS_ICONEDIT, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/IconEdit", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_TOOLS_INITPRINTER, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/InitPrinter", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_TOOLS_IOTOOLS, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/IoTools", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_TOOLS_KEYSHOW, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/KeyShow", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_TOOLS_LACER, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/Lacer", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_TOOLS_MEMACS, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/Memacs", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_TOOLS_MOUNTER, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Tools/Mounter", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_TOOLS_PREPCARD, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Tools/PrepCard", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_TOOLS_PRINTFILES, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/PrintFiles", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_TOOLS_SHOWCONFIG, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/ShowConfig", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_TOOLS_UNARC, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/UnArc", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + + { SCAMENUTYPE_Menu, 1, MSGID_DEFAULT_UTILITIES, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_Popup_Desktop }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_CLOCK, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/Clock", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_MULTIVIEW, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/Multiview", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_PLAYCD, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/PlayCD", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_UTILITIES_WBCLOCK, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Utilities/WBClock", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_Menu, 1, MSGID_DEFAULT_PREFERENCES, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_Popup_Desktop }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_AHI, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/AHI", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_ASL, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/ASL", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_CACHECDFS, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/CacheCDFS", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_DEFICONS, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/DefIcons", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_FONT, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/Font", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_ICONTROL, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/IControl", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_INPUT, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/Input", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_LOCALE, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/Locale", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_OVERSCAN, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/Overscan", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_PALETTE, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/Palette", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_POINTER, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/Pointer", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_PRINTER, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/Printer", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_PRINTERGFX, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/PrinterGFX", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_PRINTERPS, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/PrinterPS", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_REACTION, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/Reaction", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_SCREENMODE, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/ScreenMode", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_SERIAL, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/Serial", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_SOUND, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/Sound", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_TIME, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/Time", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_VINCED, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/ViNCDd", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_WARPOS, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/WarpOS", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_WBPATTERN, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/WBPattern", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 2, MSGID_DEFAULT_MENU_PREFS_WORKBENCH, MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem }, + { SCAMENUTYPE_Command, 3, (ULONG) "SYS:Prefs/Workbench", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, +#endif + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_Popup_Desktop }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_EXCHANGE, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_Popup_Desktop }, + { SCAMENUTYPE_Command, 2, (ULONG) "Scalos:Modules/Exchange.module", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Workbench, 0, 0, DEFAULT_STACKSIZE }, + { SCAMENUTYPE_MenuItem, 1, 0, MSGID_MENU_SEPARATOR, DEFAULTPARENTNODE_Popup_Desktop }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_REDRAWALL, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_Popup_Desktop }, + { SCAMENUTYPE_Command, 2, (ULONG) "redrawall", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_UPDATEALL, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_Popup_Desktop }, + { SCAMENUTYPE_Command, 2, (ULONG) "updateall", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_LASTMESSAGE, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_Popup_Desktop }, + { SCAMENUTYPE_Command, 2, (ULONG) "lastmsg", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + { SCAMENUTYPE_MenuItem, 1, MSGID_DEFAULT_MENU_OPEN, MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_Popup_Desktop }, + { SCAMENUTYPE_Command, 2, (ULONG) "about", MSGID_DEFAULT_MENU_EMPTY_SHORT, DEFAULTPARENTNODE_LastInsertedMenuItem, SCAMENUCMDTYPE_Command }, + }; + +const ULONG DefaultMenuEntries = Sizeof(DefaultMenu); + diff --git a/scalos/Plugins/Prefs/Menu/MenuPrefs.c b/scalos/Plugins/Prefs/Menu/MenuPrefs.c new file mode 100644 index 000000000..2f9acc3f2 --- /dev/null +++ b/scalos/Plugins/Prefs/Menu/MenuPrefs.c @@ -0,0 +1,5886 @@ +// MenuPrefs.c +// $Date$ +// $Revision$ + +#ifdef __AROS__ +#define MUIMASTER_YES_INLINE_STDARG +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef __AROS__ +#define NO_INLINE_STDARG +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "MenuPrefs.h" +#include "DataTypesMCC.h" + +#define ScalosMenu_NUMBERS +#define ScalosMenu_ARRAY +#define ScalosMenu_CODE +#include STR(SCALOSLOCALE) + +#include "plugin.h" + +//---------------------------------------------------------------------------- + +#ifdef __AROS__ +#define myNListTreeObject BOOPSIOBJMACRO_START(myNListTreeClass->mcc_Class) +//#define myNListObject BOOPSIOBJMACRO_START(myNListClass->mcc_Class) +//#define myFileTypesNListTreeObject BOOPSIOBJMACRO_START(myFileTypesNListTreeClass->mcc_Class) +#else +#define myNListTreeObject NewObject(myNListTreeClass->mcc_Class, 0 +#define myNListObject NewObject(myNListClass->mcc_Class, 0 +#define myFileTypesNListTreeObject NewObject(myFileTypesNListTreeClass->mcc_Class, 0 +#define myFileTypesActionsNListObject NewObject(myFileTypesActionsNListClass->mcc_Class, 0 +#endif + +//---------------------------------------------------------------------------- + +// Intuition limits for various menu entries +#define MAX_MENU (NOMENU + 1) +#define MAX_MENUITEM (NOITEM + 1) +#define MAX_SUBITEM (NOSUB + 1) + + +//---------------------------------------------------------------------------- + +#define IMG(prefix1,PREFIX2) \ + BodychunkObject,\ + MUIA_FixWidth , PREFIX2##_WIDTH ,\ + MUIA_FixHeight , PREFIX2##_HEIGHT,\ + MUIA_Bitmap_Width , PREFIX2##_WIDTH ,\ + MUIA_Bitmap_Height , PREFIX2##_HEIGHT,\ + MUIA_Bodychunk_Depth , PREFIX2##_DEPTH ,\ + MUIA_Bodychunk_Body , (UBYTE *) prefix1##_body,\ + MUIA_Bodychunk_Compression, PREFIX2##_COMPRESSION,\ + MUIA_Bodychunk_Masking , PREFIX2##_MASKING,\ + MUIA_Bitmap_SourceColors , (ULONG *) prefix1##_colors,\ + MUIA_Bitmap_Transparent , 0,\ + End + +//---------------------------------------------------------------------------- + +// defined in DefaultMenu.c + +extern const struct DefaultMenuEntry DefaultMenu[]; +extern const ULONG DefaultMenuEntries; + +//---------------------------------------------------------------------------- + +// local data structures + +#define KeyButtonHelp(name,key,HelpText)\ + TextObject,\ + ButtonFrame,\ + MUIA_CycleChain, TRUE, \ + MUIA_Font, MUIV_Font_Button,\ + MUIA_Text_Contents, (name),\ + MUIA_Text_PreParse, "\33c",\ + MUIA_Text_HiChar , (key),\ + MUIA_ControlChar , (key),\ + MUIA_InputMode , MUIV_InputMode_RelVerify,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShortHelp, HelpText,\ + End + + +#define Application_Return_EDIT 0 +#define Application_Return_USE 1001 +#define Application_Return_SAVE 1002 + +#define ID_MENU MAKE_ID('M','E','N','U') + +#define MAX_LINESIZE 500 // maximum length for command strings +#define MAX_NAMESIZE 100 // maximum length for menu names +#define MAX_COMMANDNAME 300 // maximum length for command names + +struct MenuListEntry + { + char llist_HotKey[2]; + UBYTE llist_EntryType; + UBYTE llist_Flags; + UBYTE llist_CommandType; + UBYTE llist_CommandFlags; + BYTE llist_Priority; + ULONG llist_Stack; + Object *llist_UnSelImageObj; // Popup menu image + ULONG llist_UnSelImageIndex; + char llist_name[MAX_LINESIZE]; + char llist_UnselectedIconName[MAX_COMMANDNAME]; + char llist_SelectedIconName[MAX_COMMANDNAME]; + char llist_MenuItemName[MAX_NAMESIZE + 10]; + }; + +struct MenuInsertEntry + { + struct ScalosMenuTree *mie_TreeEntry; + ULONG mie_MenuFlags; + }; + +// values in llist_Flags +#define LLISTFLGB_NotRemovable 0 +#define LLISTFLGB_NameNotSetable 1 +#define LLISTFLGB_MayNotHaveChildren 2 +#define LLISTFLGB_PopupMenu 3 +#define LLISTFLGF_NotRemovable (1 << LLISTFLGB_NotRemovable) +#define LLISTFLGF_NameNotSetable (1 << LLISTFLGB_NameNotSetable) +#define LLISTFLGF_MayNotHaveChildren (1 << LLISTFLGB_MayNotHaveChildren) +#define LLISTFLGF_PopupMenu (1 << LLISTFLGB_PopupMenu) + + +enum ScalosMenuChunkId + { + SCMID_MainMenu = 0, + SCMID_Popup_Disk, + SCMID_Popup_Drawer, + SCMID_Popup_Tool, + SCMID_Popup_Trashcan, + SCMID_Popup_Window, + SCMID_Popup_AppIcon, + SCMID_Popup_Desktop, + }; + +struct ScalosMenuChunk + { + UWORD smch_MenuID; // enum ScalosMenuChunkId + UWORD smch_Entries; // number of entries + struct ScalosMenuTree smch_Menu[1]; // (variable) the menu entries + }; + +struct CommandTableEntry + { + CONST_STRPTR cte_Command; + ULONG cte_NameMsgId; + }; + +enum MenuEntryType + { + MENUENTRY_Menu, + MENUENTRY_MenuItem, + MENUENTRY_SubItem, + MENUENTRY_Invalid, + }; + +//---------------------------------------------------------------------------- + +// aus mempools.lib +#ifndef __amigaos4__ +extern int _STI_240_InitMemFunctions(void); +extern void _STD_240_TerminateMemFunctions(void); +#endif + +//---------------------------------------------------------------------------- + +// local functions + +static BOOL OpenLibraries(void); +static void CloseLibraries(void); + +DISPATCHER_PROTO(MenuPrefs); +static Object *CreatePrefsGroup(struct MenuPrefsInst *inst); + +static SAVEDS(APTR) INTERRUPT CmdListConstructHookFunc(struct Hook *hook, APTR obj, struct NList_ConstructMessage *msg); +static SAVEDS(void) INTERRUPT CmdListDestructHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *msg); +static SAVEDS(ULONG) INTERRUPT CmdListDisplayHookFunc(struct Hook *hook, APTR obj, struct NList_DisplayMessage *ltdm); +static SAVEDS(LONG) INTERRUPT CmdListCompareHookFunc(struct Hook *hook, Object *obj, struct NList_CompareMessage *msg); +static SAVEDS(LONG) INTERRUPT CmdListPopupOpenHookFunc(struct Hook *hook, Object *list, Object *str); + +static SAVEDS(APTR) INTERRUPT TreeConstructFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_ConstructMessage *ltcm); +static SAVEDS(void) INTERRUPT TreeDestructFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_DestructMessage *ltdm); +static SAVEDS(ULONG) INTERRUPT TreeDisplayFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_DisplayMessage *ltdm); + +static SAVEDS(ULONG) INTERRUPT ImagePopAslFileStartHookFunc(struct Hook *hook, Object *o, Msg msg); + +static STRPTR GetLocString(ULONG MsgId); +static void TranslateStringArray(STRPTR *stringArray); +static void TranslateNewMenu(struct NewMenu *nm); + +static SAVEDS(APTR) INTERRUPT ResetToDefaultsHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT OpenHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT SaveAsHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT AboutHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT LastSavedHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT RestoreHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT MergeHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT ImportTDHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT ImportPHookFunc(struct Hook *hook, Object *o, Msg msg); + +static SAVEDS(APTR) INTERRUPT RenameEntryHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT ChangeEntry3HookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT ChangeUnselectedImageHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT ChangeSelectedImageHookFunc(struct Hook *hook, Object *o, Msg msg); + +static SAVEDS(APTR) INTERRUPT ChangeHotkeyHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT SelectEntryHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT PopButtonHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT AddMenuHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT AddCommandHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT AddMenuItemHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT RemoveEntryHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT CollapseSelectedHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT ExpandSelectedHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT CollapseAllHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT ExpandAllHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT CmdSelectedHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT ContextMenuTriggerHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT AppMessageHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT SettingsChangedHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT AslIntuiMsgHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT HideObsoleteHookFunc(struct Hook *hook, Object *o, Msg msg); + +static SAVEDS(void) INTERRUPT MenuCopyHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT MenuCutHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT MenuPasteHookFunc(struct Hook *hook, Object *o, Msg msg); + +static struct MUI_NListtree_TreeNode *MoveMenuTree(struct MenuPrefsInst *inst, + ULONG DestListtreeIndex, ULONG SrcListtreeIndex, ULONG EntryIndex); +static struct MUI_NListtree_TreeNode *CopyFileTypesEntry(struct MenuPrefsInst *inst, + struct MUI_NListtree_TreeNode *tnToListNode, struct MUI_NListtree_TreeNode *tnToPrevNode, + struct MUI_NListtree_TreeNode *tnFrom, ULONG destList, ULONG srcList); +static LONG CopyMenuTree(struct MenuPrefsInst *inst, + Object *ListTreeDest, Object *ListTreeSrc, + struct MUI_NListtree_TreeNode *Src, struct MUI_NListtree_TreeNode *DestParent); +static struct MUI_NListtree_TreeNode *CopyMenuEntry(struct MenuPrefsInst *inst, + Object *ListTreeDest, Object *ListTreeSrc, + struct MUI_NListtree_TreeNode *Src, struct MUI_NListtree_TreeNode *DestParent); +static LONG ReadPrefsFile(struct MenuPrefsInst *inst, CONST_STRPTR Filename, BOOL Quiet); +static LONG WritePrefsFile(struct MenuPrefsInst *inst, CONST_STRPTR Filename); +static LONG SaveMenuNode(struct MenuPrefsInst *inst, struct IFFHandle *iff, + const struct MenuPrefsPopMenuNode *TreeNode, enum ScalosMenuChunkId ChunkID); +static UWORD CountMenuEntries(struct MenuPrefsInst *inst, Object *ListTree, + const struct MUI_NListtree_TreeNode *TreeNode, size_t *StringSpace); +static LONG BuildMenuTree(struct MenuPrefsInst *inst, Object *ListTree, + const struct MUI_NListtree_TreeNode *TreeNode, + struct ScalosMenuTree **MenuSpace, STRPTR *StringSpace, + struct ScalosMenuTree **Parent); +static void RemoveAddresses(struct ScalosMenuTree *MenuTree, const UBYTE *baseAddr); +static LONG SaveIcon(struct MenuPrefsInst *inst, CONST_STRPTR IconName); +static void ClearMenuList(struct MenuPrefsInst *inst); +static STRPTR AddMenuString(CONST_STRPTR MenuString, STRPTR *StringSpace); +static void AddAddresses(struct ScalosMenuTree *MenuTree, const UBYTE *BaseAddr); +static void GenerateMenuList(struct MenuPrefsInst *inst, struct ScalosMenuTree *mTree, + Object *ListTree, struct MUI_NListtree_TreeNode *MenuNode); +static BOOL RequestTdFile(struct MenuPrefsInst *inst, char *FileName, size_t MaxLen); +static BOOL RequestParmFile(struct MenuPrefsInst *inst, char *FileName, size_t MaxLen); +static BOOL CmpWord(CONST_STRPTR Cmd, CONST_STRPTR Line); +static void StripLF(STRPTR Line); +static STRPTR NextWord(STRPTR lp); +static void CopyWord(STRPTR dest, CONST_STRPTR src, size_t MaxLen); +static struct MUI_NListtree_TreeNode *AppMessage_Menu(struct MenuPrefsInst *inst, + struct MUI_NListtree_TreeNode **TreeNode, + struct MUI_NListtree_TreeNode **ParentNode, const struct WBArg *wbArg, + CONST_STRPTR Path, CONST_STRPTR FileName); +static void EnableCommandArgumentGadgets(struct MenuPrefsInst *inst, const struct MenuListEntry *mle); +static BOOL IsPopupMenu(struct MenuPrefsInst *inst, struct MUI_NListtree_TreeNode *TreeNode); +static enum MenuEntryType GetMenuEntryType(struct MenuPrefsInst *inst, + struct MUI_NListtree_TreeNode *TreeNode); +static ULONG GetMaxCountForEntry(enum MenuEntryType type); +static void SwitchPopButton(struct MenuPrefsInst *inst, UBYTE CommandType); +DISPATCHER_PROTO(myNListTree); +static Object *CreatePrefsImage(void); +static void InitHooks(struct MenuPrefsInst *inst); +static void SetChangedFlag(struct MenuPrefsInst *inst, BOOL changed); +static void AddDefaultMenuContents(struct MenuPrefsInst *inst); +static void ParseToolTypes(struct MenuPrefsInst *inst, struct MUIP_ScalosPrefs_ParseToolTypes *ptt); +static void InsertMenuRootEntries(struct MenuPrefsInst *inst); +static Object *GetMenuEntryListtree(struct MenuPrefsInst *inst); +static struct MUI_NListtree_TreeNode *GetParentNodeForMenu(struct MenuPrefsInst *inst, struct MUI_NListtree_TreeNode **PrevNode); +static struct MUI_NListtree_TreeNode *GetParentNodeForMenuItem(struct MenuPrefsInst *inst, struct MUI_NListtree_TreeNode **PrevNode); +static BOOL MayPasteOnto(struct MenuPrefsInst *inst, + struct MUI_NListtree_TreeNode *tnTo, struct MUI_NListtree_TreeNode *tnFrom); +static struct MUI_NListtree_TreeNode *MayPasteBelow(struct MenuPrefsInst *inst, + struct MUI_NListtree_TreeNode *tnTo, struct MUI_NListtree_TreeNode *tnFrom); +#if !defined(__SASC) && !defined(__MORPHOS__) && !defined(__AROS__) +static char *stpblk(const char *q); +#if !defined(__amigaos4__) +static size_t stccpy(char *dest, const char *src, size_t MaxLen); +#endif /* !defined(__amigaos4__) */ +#endif /* !defined(__SASC) && !defined(__MORPHOS__) */ + +//---------------------------------------------------------------------------- + +// local data items + +struct Library *MUIMasterBase; +T_LOCALEBASE LocaleBase; +struct GfxBase *GfxBase; +struct Library *IconBase; +struct Library *IFFParseBase; +T_UTILITYBASE UtilityBase; +struct IntuitionBase *IntuitionBase; +struct Library *DataTypesBase; + +#ifdef __amigaos4__ +struct Library *DOSBase; +struct DOSIFace *IDOS; +struct LocaleIFace *ILocale; +struct MUIMasterIFace *IMUIMaster; +struct GraphicsIFace *IGraphics; +struct IconIFace *IIcon; +struct IFFParseIFace *IIFFParse; +struct DataTypesIFace *IDataTypes; +struct UtilityIFace *IUtility; +struct IntuitionIFace *IIntuition; +struct Library *NewlibBase; +struct Interface *INewlib; +#endif + +#ifdef __AROS__ +struct DosLibrary *DOSBase; +#endif + +static BOOL StaticsTranslated; + +static ULONG MajorVersion, MinorVersion; + +static const struct MUIP_ScalosPrefs_MCCList RequiredMccList[] = + { + { MUIC_Lamp, 11, 1 }, + { MUIC_NListtree, 18, 18 }, + { MUIC_NListview, 18, 0 }, + { NULL, 0, 0 } + }; + +static const struct Hook MenuPrefsHooks[] = +{ + { { NULL, NULL }, HOOKFUNC_DEF(TreeConstructFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(TreeDestructFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(TreeDisplayFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(CmdListConstructHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(CmdListDestructHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(CmdListDisplayHookFunc), }, + { { NULL, NULL }, HOOKFUNC_DEF(CmdListCompareHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(CmdListPopupOpenHookFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(ImagePopAslFileStartHookFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(ResetToDefaultsHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(OpenHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(LastSavedHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(RestoreHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(SaveAsHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(MergeHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ImportTDHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ImportPHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(RenameEntryHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ChangeHotkeyHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ChangeEntry3HookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ChangeUnselectedImageHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ChangeSelectedImageHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(SelectEntryHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(PopButtonHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(AddMenuHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(AddCommandHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(AddMenuItemHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(RemoveEntryHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(AboutHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(CollapseSelectedHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ExpandSelectedHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(CollapseAllHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ExpandAllHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(CmdSelectedHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ContextMenuTriggerHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(AppMessageHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(SettingsChangedHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(AslIntuiMsgHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(HideObsoleteHookFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(MenuCopyHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(MenuCutHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(MenuPasteHookFunc), NULL }, +}; + +static struct Locale *MenuPrefsLocale; +static struct Catalog *MenuPrefsCatalog; + +struct MUI_CustomClass *MenuPrefsClass; +struct MUI_CustomClass *myNListTreeClass; +struct MUI_CustomClass *DataTypesImageClass; + +static STRPTR CmdModeStrings[] = + { + (STRPTR) MSGID_COMMANDNAME, + (STRPTR) MSGID_WBNAME, + (STRPTR) MSGID_ADOSNAME, + (STRPTR) MSGID_ICONWINNAME, + (STRPTR) MSGID_AREXXNAME, + (STRPTR) MSGID_PLUGINNAME, + NULL + }; + +struct CommandTableEntry CommandsTable[] = + { + { "about", MSGID_COM5NAME }, + { "backdrop", MSGID_COM1NAME }, + { "cleanup", MSGID_COM12NAME }, + { "cleanupbydate", MSGID_COM44NAME }, + { "cleanupbyname", MSGID_COM43NAME }, + { "cleanupbysize", MSGID_COM45NAME }, + { "cleanupbytype", MSGID_COM46NAME }, + { "clearselection", MSGID_COM36NAME }, + { "clone", MSGID_COM28NAME }, + { "close", MSGID_COM9NAME }, + { "copy", MSGID_COM39NAME }, + { "copyto", MSGID_COM49NAME }, + { "createthumbnail", MSGID_COM51NAME }, + { "cut", MSGID_COM40NAME }, + { "delete", MSGID_COM27NAME }, + { "emptytrashcan", MSGID_COM29NAME }, + { "executecommand", MSGID_COM2NAME }, + { "find", MSGID_COM_FIND }, + { "formatdisk", MSGID_COM33NAME }, + { "iconify", MSGID_COM32NAME }, + { "iconinfo", MSGID_COM22NAME }, + { "iconproperties", MSGID_COM_ICONPROPERTIES }, + { "lastmsg", MSGID_COM30NAME }, + { "leaveout", MSGID_COM25NAME }, + { "makedir", MSGID_COM7NAME }, + { "moveto", MSGID_COM50NAME }, + { "open", MSGID_COM19NAME }, + { "openinbrowserwindow", MSGID_COM_OPENBROWSERWINDOW }, + { "openinnewwindow", MSGID_COM_OPENNEWWINDOW }, + { "parent", MSGID_COM8NAME }, + { "paste", MSGID_COM41NAME }, + { "putaway", MSGID_COM26NAME }, + { "quit", MSGID_COM6NAME }, + { "redo", MSGID_COM_REDO }, + { "redraw", MSGID_COM31NAME }, + { "redrawall", MSGID_COM3NAME }, + { "rename", MSGID_COM21NAME }, + { "reset", MSGID_COM20NAME }, + { "selectall", MSGID_COM11NAME }, + { "showallfiles", MSGID_COM16NAME }, + { "showdefault", MSGID_COM48NAME }, + { "showonlyicons", MSGID_COM15NAME }, + { "shutdown", MSGID_COM34NAME }, + { "sizetofit", MSGID_COM35NAME }, + { "snapshot", MSGID_COM23NAME }, + { "snapshotall", MSGID_COM14NAME }, + { "snapshotwindow", MSGID_COM13NAME }, + { "thumbnailcachecleanup", MSGID_COM_THUMBNAILCACHECLEANUP }, + { "undo", MSGID_COM_UNDO }, + { "unsnapshot", MSGID_COM24NAME }, + { "update", MSGID_COM10NAME }, + { "updateall", MSGID_COM4NAME }, + { "viewbydate", MSGID_COM38NAME }, + { "viewbydefault", MSGID_COM47NAME }, + { "viewbyicon", MSGID_COM17NAME }, + { "viewbysize", MSGID_COM37NAME }, + { "viewbytext", MSGID_COM18NAME }, + { "viewbytype", MSGID_COM42NAME }, + { "windowproperties", MSGID_COM_WINDOWPROPERTIES }, + }; + +struct CommandTableEntry *CommandsArray[1 + Sizeof(CommandsTable)]; + +static struct NewMenu ContextMenus[] = + { + { NM_TITLE, (STRPTR) MSGID_TITLENAME, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_OPEN, (STRPTR) MSGID_MENU_PROJECT_OPEN_SHORT, 0, 0, (APTR) HOOKNDX_Open }, + { NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_MERGE, (STRPTR) MSGID_MENU_PROJECT_MERGE_SHORT, 0, 0, (APTR) HOOKNDX_Merge }, + { NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_SAVEAS, (STRPTR) MSGID_MENU_PROJECT_SAVEAS_SHORT, 0, 0, (APTR) HOOKNDX_SaveAs }, + { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_IMPORT, NULL, 0, 0, NULL }, + { NM_SUB, (STRPTR) MSGID_MENU_PROJECT_IMPORT_TD, (STRPTR) MSGID_MENU_PROJECT_IMPORT_TD_SHORT, 0, 0, (APTR) HOOKNDX_ImportTD }, + { NM_SUB, (STRPTR) MSGID_MENU_PROJECT_IMPORT_P, (STRPTR) MSGID_MENU_PROJECT_IMPORT_P_SHORT, 0, 0, (APTR) HOOKNDX_ImportP }, + { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_EDIT_COLLAPSE, NULL, NM_ITEMDISABLED, 0, (APTR) HOOKNDX_CollapseSelected }, + { NM_ITEM, (STRPTR) MSGID_MENU_EDIT_EXPAND, NULL, NM_ITEMDISABLED, 0, (APTR) HOOKNDX_ExpandSelected }, + { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_EDIT_COLLAPSEALL, NULL, 0, 0, (APTR) HOOKNDX_CollapseAll }, + { NM_ITEM, (STRPTR) MSGID_MENU_EDIT_EXPANDALL, NULL, 0, 0, (APTR) HOOKNDX_ExpandAll }, + { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_EDIT_COPY, NULL, 0, 0, (APTR) HOOKNDX_MenuCopy }, + { NM_ITEM, (STRPTR) MSGID_MENU_EDIT_CUT, NULL, 0, 0, (APTR) HOOKNDX_MenuCut }, + { NM_ITEM, (STRPTR) MSGID_MENU_EDIT_PASTE, NULL, NM_ITEMDISABLED, 0, (APTR) HOOKNDX_MenuPaste }, + { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_SETTINGS_HIDEOBSOLETE, NULL, CHECKIT|MENUTOGGLE, 0, (APTR) HOOKNDX_HideObsolete }, + { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_ABOUT, NULL, 0, 0, (APTR) HOOKNDX_About }, + + { NM_END, NULL, NULL, 0, 0, 0,}, + }; + +static const LONG StopChunkList[] = + { + ID_PREF, ID_MENU, + }; + +#define ENTRYTYPE_MAX (1 + SCAMENUTYPE_ToolsMenu) + +// dest source +static const BOOL MayPasteAfterMatrix[ENTRYTYPE_MAX][ENTRYTYPE_MAX] = + { + // 0 1 2 3 4 + /* 0 SCAMENUTYPE_MainMenu */ + { FALSE, FALSE, FALSE, FALSE, FALSE, }, + /* 1 SCAMENUTYPE_Menu */ + { FALSE, TRUE, TRUE, FALSE, TRUE, }, + /* 2 SCAMENUTYPE_MenuItem */ + { FALSE, TRUE, TRUE, TRUE, FALSE, }, + /* 3 SCAMENUTYPE_Command */ + { FALSE, FALSE, FALSE, TRUE, FALSE, }, + /* 4 SCAMENUTYPE_ToolsMenu */ + { FALSE, TRUE, FALSE, FALSE, FALSE, }, + // 0 1 2 3 4 + }; +// dest source +static const BOOL MayPasteIntoMatrix[ENTRYTYPE_MAX][ENTRYTYPE_MAX] = + { + // 0 1 2 3 4 + /* 0 SCAMENUTYPE_MainMenu */ + { FALSE, TRUE, FALSE, FALSE, FALSE, }, + /* 1 SCAMENUTYPE_Menu */ + { FALSE, TRUE, TRUE, FALSE, FALSE, }, + /* 2 SCAMENUTYPE_MenuItem */ + { FALSE, FALSE, FALSE, TRUE, FALSE, }, + /* 3 SCAMENUTYPE_Command */ + { FALSE, FALSE, FALSE, TRUE, FALSE, }, + /* 4 SCAMENUTYPE_ToolsMenu */ + { FALSE, TRUE, TRUE, FALSE, FALSE, }, + // 0 1 2 3 4 + }; +//---------------------------------------------------------------------------- + +void closePlugin(struct PluginBase *PluginBase) +{ + d1(kprintf("%s/%s/%ld: start\n", __FILE__, __FUNC__, __LINE__)); + + if (DataTypesImageClass) + { + CleanupDtpicClass(DataTypesImageClass); + DataTypesImageClass = NULL; + } + if (myNListTreeClass) + { + MUI_DeleteCustomClass(myNListTreeClass); + myNListTreeClass = NULL; + } + if (MenuPrefsCatalog) + { + CloseCatalog(MenuPrefsCatalog); + MenuPrefsCatalog = NULL; + } + if (MenuPrefsLocale) + { + CloseLocale(MenuPrefsLocale); + MenuPrefsLocale = NULL; + } + + if (MenuPrefsClass) + { + MUI_DeleteCustomClass(MenuPrefsClass); + MenuPrefsClass = NULL; + } + + CloseLibraries(); + + d1(kprintf("%s/%s//%ld:\n", __FILE__, __FUNC__, __LINE__)); + +#if !defined(__amigaos4__) && !defined(__AROS__) + _STD_240_TerminateMemFunctions(); +#endif + + d1(kprintf("%s/%s//%ld: endt\n", __FILE__, __FUNC__, __LINE__)); +} + + +LIBFUNC_P2(ULONG, LIBSCAGetPrefsInfo, + D0, ULONG, which, + A6, struct PluginBase *, PluginBase); +{ + ULONG result; + + d1(kprintf("%s/%s/%ld: which=%ld\n", __FILE__, __FUNC__, __LINE__, which)); + + (void) PluginBase; + + switch(which) + { + case SCAPREFSINFO_GetClass: + result = (ULONG) MenuPrefsClass; + break; + + case SCAPREFSINFO_GetTitle: + result = (ULONG) GetLocString(MSGID_PLUGIN_LIST_TITLE); + break; + + case SCAPREFSINFO_GetTitleImage: + result = (ULONG) CreatePrefsImage(); + break; + + default: + result = (ULONG) NULL; + break; + } + + d1(kprintf("%s/%s/%ld: result=%lu\n", __FILE__, __FUNC__, __LINE__, result)); + + return result; +} +LIBFUNC_END + +//---------------------------------------------------------------------------- + +DISPATCHER(MenuPrefs) +{ + struct MenuPrefsInst *inst; + ULONG result = 0; + + switch(msg->MethodID) + { + case OM_NEW: + obj = (Object *) DoSuperMethodA(cl, obj, msg); + d1(kprintf("%s/%s/%ld: OM_NEW obj=%08lx\n", __FILE__, __FUNC__, __LINE__, obj)); + if (obj) + { + Object *prefsobject; + struct opSet *ops = (struct opSet *) msg; + + inst = (struct MenuPrefsInst *) INST_DATA(cl, obj); + + memset(inst, 0, sizeof(struct MenuPrefsInst)); + + inst->mpb_TreeImageIndex = 0; + inst->mpb_Changed = FALSE; + inst->mpb_WBScreen = LockPubScreen("Workbench"); + + InitHooks(inst); + + inst->mpb_fCreateIcons = GetTagData(MUIA_ScalosPrefs_CreateIcons, TRUE, ops->ops_AttrList); + inst->mpb_ProgramName = (CONST_STRPTR) GetTagData(MUIA_ScalosPrefs_ProgramName, (ULONG) "", ops->ops_AttrList); + inst->mpb_HideObsoletePopupMenus = GetTagData(MUIM_ScalosPrefs_MenuPrefs_HideObsolete, TRUE, ops->ops_AttrList); + inst->mpb_Objects[OBJNDX_WIN_Main] = (APTR) GetTagData(MUIA_ScalosPrefs_MainWindow, (ULONG) NULL, ops->ops_AttrList); + inst->mpb_Objects[OBJNDX_APP_Main] = (APTR) GetTagData(MUIA_ScalosPrefs_Application, (ULONG) NULL, ops->ops_AttrList); + + prefsobject = CreatePrefsGroup(inst); + d1(kprintf("%s/%s/%ld: prefsobject=%08lx\n", __FILE__, __FUNC__, __LINE__, prefsobject)); + if (prefsobject) + { + DoMethod(obj, OM_ADDMEMBER, prefsobject); + + result = (ULONG) obj; + } + else + { + CoerceMethod(cl, obj, OM_DISPOSE); + } + } + break; + + case OM_DISPOSE: + inst = (struct MenuPrefsInst *) INST_DATA(cl, obj); + d1(kprintf("%s/%s/%ld: OM_DISPOSE obj=%08lx\n", __FILE__, __FUNC__, __LINE__, obj)); + if (inst->mpb_WBScreen) + { + UnlockPubScreen(NULL, inst->mpb_WBScreen); + inst->mpb_WBScreen = NULL; + } + if (inst->mpb_Objects[OBJNDX_ContextMenu]) + { + MUI_DisposeObject(inst->mpb_Objects[OBJNDX_ContextMenu]); + inst->mpb_Objects[OBJNDX_ContextMenu] = NULL; + } + if (inst->mpb_SaveReq) + { + MUI_FreeAslRequest(inst->mpb_SaveReq); + inst->mpb_SaveReq = NULL; + } + if (inst->mpb_LoadReq) + { + MUI_FreeAslRequest(inst->mpb_LoadReq); + inst->mpb_LoadReq = NULL; + } + return DoSuperMethodA(cl, obj, msg); + break; + + case OM_SET: + { + struct opSet *ops = (struct opSet *) msg; + + inst = (struct MenuPrefsInst *) INST_DATA(cl, obj); + + if (FindTagItem(MUIM_ScalosPrefs_MenuPrefs_HideObsolete, ops->ops_AttrList)) + { + inst->mpb_HideObsoletePopupMenus = GetTagData(MUIM_ScalosPrefs_MenuPrefs_HideObsolete, inst->mpb_HideObsoletePopupMenus, ops->ops_AttrList); + set(inst->mpb_Objects[OBJNDX_Menu_HideObsolete], MUIA_Menuitem_Checked, inst->mpb_HideObsoletePopupMenus); + CallHookPkt(&inst->mpb_Hooks[HOOKNDX_HideObsolete], + inst->mpb_Objects[OBJNDX_APP_Main], 0); + } + inst->mpb_fCreateIcons = GetTagData(MUIA_ScalosPrefs_CreateIcons, inst->mpb_fCreateIcons, ops->ops_AttrList); + inst->mpb_ProgramName = (CONST_STRPTR) GetTagData(MUIA_ScalosPrefs_ProgramName, (ULONG) inst->mpb_ProgramName, ops->ops_AttrList); + inst->mpb_Objects[OBJNDX_WIN_Main] = (APTR) GetTagData(MUIA_ScalosPrefs_MainWindow, + (ULONG) inst->mpb_Objects[OBJNDX_WIN_Main], ops->ops_AttrList); + inst->mpb_Objects[OBJNDX_APP_Main] = (APTR) GetTagData(MUIA_ScalosPrefs_Application, + (ULONG) inst->mpb_Objects[OBJNDX_APP_Main], ops->ops_AttrList); + + return DoSuperMethodA(cl, obj, msg); + } + break; + + case OM_GET: + { + struct opGet *opg = (struct opGet *) msg; + + inst = (struct MenuPrefsInst *) INST_DATA(cl, obj); + switch (opg->opg_AttrID) + { + case MUIA_ScalosPrefs_CreateIcons: + *opg->opg_Storage = inst->mpb_fCreateIcons; + result = 0; + break; + default: + result = DoSuperMethodA(cl, obj, msg); + } + } + break; + + case MUIM_ScalosPrefs_ParseToolTypes: + inst = (struct MenuPrefsInst *) INST_DATA(cl, obj); + d1(kprintf(__FILE__ "/%s/%ld: before ParseToolTypes\n", __FUNC__, __LINE__)); + ParseToolTypes(inst, (struct MUIP_ScalosPrefs_ParseToolTypes *) msg); + d1(kprintf(__FILE__ "/%s/%ld: after ParseToolTypes\n", __FUNC__, __LINE__)); + break; + + case MUIM_ScalosPrefs_LoadConfig: + inst = (struct MenuPrefsInst *) INST_DATA(cl, obj); + if (RETURN_OK != ReadPrefsFile(inst, "ENV:Scalos/Menu13.prefs", TRUE)) + { + ClearMenuList(inst); + ReadPrefsFile(inst, "ENV:Scalos/Menu.prefs", FALSE); + } + SetChangedFlag(inst, FALSE); + break; + + case MUIM_ScalosPrefs_UseConfig: + inst = (struct MenuPrefsInst *) INST_DATA(cl, obj); + WritePrefsFile(inst, "ENV:Scalos/Menu13.prefs"); + SetChangedFlag(inst, FALSE); + break; + + case MUIM_ScalosPrefs_UseConfigIfChanged: + inst = (struct MenuPrefsInst *) INST_DATA(cl, obj); + if (inst->mpb_Changed) + { + WritePrefsFile(inst, "ENV:Scalos/Menu13.prefs"); + SetChangedFlag(inst, FALSE); + } + break; + + case MUIM_ScalosPrefs_SaveConfig: + inst = (struct MenuPrefsInst *) INST_DATA(cl, obj); + WritePrefsFile(inst, "ENVARC:Scalos/Menu13.prefs"); + WritePrefsFile(inst, "ENV:Scalos/Menu13.prefs"); + SetChangedFlag(inst, FALSE); + break; + + case MUIM_ScalosPrefs_SaveConfigIfChanged: + inst = (struct MenuPrefsInst *) INST_DATA(cl, obj); + if (inst->mpb_Changed) + { + WritePrefsFile(inst, "ENVARC:Scalos/Menu13.prefs"); + WritePrefsFile(inst, "ENV:Scalos/Menu13.prefs"); + SetChangedFlag(inst, FALSE); + } + break; + + case MUIM_ScalosPrefs_RestoreConfig: + inst = (struct MenuPrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_Restore], 0); + break; + + case MUIM_ScalosPrefs_ResetToDefaults: + inst = (struct MenuPrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_ResetToDefaults], 0); + break; + + case MUIM_ScalosPrefs_LastSavedConfig: + inst = (struct MenuPrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_LastSaved], 0); + break; + + case MUIM_ScalosPrefs_PageActive: + { + struct MUIP_ScalosPrefs_PageActive *spa = (struct MUIP_ScalosPrefs_PageActive *) msg; + + d1(kprintf("%s/%s/%ld: MUIM_ScalosPrefs_PageActive isActive=%08lx\n", __FILE__, __FUNC__, __LINE__, spa->isActive)); + inst = (struct MenuPrefsInst *) INST_DATA(cl, obj); + inst->mpb_PageIsActive = spa->isActive; + } + break; + + case MUIM_ScalosPrefs_OpenConfig: + inst = (struct MenuPrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_Open], 0); + break; + + case MUIM_ScalosPrefs_SaveConfigAs: + inst = (struct MenuPrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_SaveAs], 0); + break; + + case MUIM_ScalosPrefs_About: + inst = (struct MenuPrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_About], 0); + break; + + case MUIM_ScalosPrefs_LoadNamedConfig: + { + struct MUIP_ScalosPrefs_LoadNamedConfig *lnc = (struct MUIP_ScalosPrefs_LoadNamedConfig *) msg; + + inst = (struct MenuPrefsInst *) INST_DATA(cl, obj); + ClearMenuList(inst); + ReadPrefsFile(inst, lnc->ConfigFileName, FALSE); + } + break; + + case MUIM_ScalosPrefs_MenuPrefs_ImportTD: + inst = (struct MenuPrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_ImportTD], 0); + break; + + case MUIM_ScalosPrefs_MenuPrefs_ImportP: + inst = (struct MenuPrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_ImportP], 0); + break; + + case MUIM_ScalosPrefs_MenuPrefs_Merge: + inst = (struct MenuPrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_Merge], 0); + break; + + case MUIM_ScalosPrefs_MenuPrefs_CollapseAll: + inst = (struct MenuPrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_CollapseAll], 0); + break; + + case MUIM_ScalosPrefs_MenuPrefs_ExpandAll: + inst = (struct MenuPrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_ExpandAll], 0); + break; + + case MUIM_ScalosPrefs_CreateSubWindows: + result = (ULONG) NULL; + break; + + case MUIM_ScalosPrefs_GetListOfMCCs: + result = (ULONG) RequiredMccList; + break; + + default: + d1(kprintf("%s/%s/%ld: MethodID=%08lx\n", __FILE__, __FUNC__, __LINE__, msg->MethodID)); + result = DoSuperMethodA(cl, obj, msg); + break; + } + + return result; +} +DISPATCHER_END + +//---------------------------------------------------------------------------- + +static Object *CreatePrefsGroup(struct MenuPrefsInst *inst) +{ + d1(kprintf("%s/%s//%ld: inst=%08lx\n", __FILE__, __FUNC__, __LINE__, inst)); + + inst->mpb_Objects[OBJNDX_ContextMenu] = MUI_MakeObject(MUIO_MenustripNM, ContextMenus, 0); + + inst->mpb_Objects[OBJNDX_Menu_Copy] = (Object *) DoMethod(inst->mpb_Objects[OBJNDX_ContextMenu], + MUIM_FindUData, HOOKNDX_MenuCopy); + inst->mpb_Objects[OBJNDX_Menu_Cut] = (Object *) DoMethod(inst->mpb_Objects[OBJNDX_ContextMenu], + MUIM_FindUData, HOOKNDX_MenuCut); + inst->mpb_Objects[OBJNDX_Menu_Paste] = (Object *) DoMethod(inst->mpb_Objects[OBJNDX_ContextMenu], + MUIM_FindUData, HOOKNDX_MenuPaste); + inst->mpb_Objects[OBJNDX_Menu_HideObsolete] = (Object *) DoMethod(inst->mpb_Objects[OBJNDX_ContextMenu], + MUIM_FindUData, HOOKNDX_HideObsolete); + inst->mpb_Objects[OBJNDX_Menu_CollapseSelected] = (Object *) DoMethod(inst->mpb_Objects[OBJNDX_ContextMenu], + MUIM_FindUData, HOOKNDX_CollapseSelected); + inst->mpb_Objects[OBJNDX_Menu_ExpandSelected] = (Object *) DoMethod(inst->mpb_Objects[OBJNDX_ContextMenu], + MUIM_FindUData, HOOKNDX_ExpandSelected); + + inst->mpb_Objects[OBJNDX_Group_Main] = VGroup, + MUIA_Background, MUII_PageBack, + + Child, inst->mpb_Objects[OBJNDX_Group_List] = VGroup, + MUIA_Frame, MUIV_Frame_Group, + MUIA_FrameTitle, GetLocString(MSGID_FRAMETITLE), + + Child, HGroup, + Child, VGroup, + Child, inst->mpb_Objects[OBJNDX_MainListView] = NListviewObject, + MUIA_NListview_NList, inst->mpb_Objects[OBJNDX_MainListTree] = myNListTreeObject, + MUIA_CycleChain, TRUE, + MUIA_ContextMenu, inst->mpb_Objects[OBJNDX_ContextMenu], + MUIA_NList_PrivateData, inst, + MUIA_NList_Format, ",", + InputListFrame, + MUIA_Background, MUII_ListBack, + MUIA_NListtree_DisplayHook, &inst->mpb_Hooks[HOOKNDX_TreeDisplay], + MUIA_NListtree_ConstructHook, &inst->mpb_Hooks[HOOKNDX_TreeConstruct], + MUIA_NListtree_DestructHook, &inst->mpb_Hooks[HOOKNDX_TreeDestruct], + MUIA_NListtree_DragDropSort, TRUE, + MUIA_NList_ShowDropMarks, TRUE, + MUIA_NListtree_AutoVisible, MUIV_NListtree_AutoVisible_Expand, + End, + MUIA_ObjectID, MAKE_ID('M','T','R','E'), + MUIA_Listview_DragType, MUIV_Listview_DragType_Immediate, + End, + + Child, NListviewObject, + MUIA_ShowMe, FALSE, + MUIA_NListview_NList, inst->mpb_Objects[OBJNDX_HiddenListTree] = myNListTreeObject, + MUIA_CycleChain, TRUE, + MUIA_NList_PrivateData, inst, + MUIA_NList_Format, ",", + InputListFrame, + MUIA_Background, MUII_ListBack, + MUIA_NListtree_DisplayHook, &inst->mpb_Hooks[HOOKNDX_TreeDisplay], + MUIA_NListtree_ConstructHook, &inst->mpb_Hooks[HOOKNDX_TreeConstruct], + MUIA_NListtree_DestructHook, &inst->mpb_Hooks[HOOKNDX_TreeDestruct], + End, + MUIA_Listview_DragType, MUIV_Listview_DragType_None, + End, + + Child, NListviewObject, + MUIA_ShowMe, FALSE, + MUIA_NListview_NList, inst->mpb_Objects[OBJNDX_ListTreeClipboard] = myNListTreeObject, + MUIA_CycleChain, TRUE, + MUIA_NList_PrivateData, inst, + MUIA_NList_Format, ",", + InputListFrame, + MUIA_Background, MUII_ListBack, + MUIA_NListtree_DisplayHook, &inst->mpb_Hooks[HOOKNDX_TreeDisplay], + MUIA_NListtree_ConstructHook, &inst->mpb_Hooks[HOOKNDX_TreeConstruct], + MUIA_NListtree_DestructHook, &inst->mpb_Hooks[HOOKNDX_TreeDestruct], + End, + MUIA_Listview_DragType, MUIV_Listview_DragType_None, + End, + + End, //VGroup + + Child, BalanceObject, + End, //Balance + + Child, VGroup, + + Child, inst->mpb_Objects[OBJNDX_Group_Name] = VGroup, + Child, VGroup, + Child, LLabel(GetLocString(MSGID_ENTRY_STRING_NAME)), + Child, inst->mpb_Objects[OBJNDX_NameString] = StringObject, + MUIA_CycleChain, TRUE, + MUIA_Frame, MUIV_Frame_String, + MUIA_String_MaxLen, MAX_NAMESIZE, + End, + End, //VGroup + Child, HGroup, + MUIA_Weight, 0, + Child, Label(GetLocString(MSGID_HOTKEYNAME)), + Child, inst->mpb_Objects[OBJNDX_StringHotkey] = StringObject, + MUIA_CycleChain, TRUE, + MUIA_String_MaxLen, 2, + MUIA_Weight, 10, + MUIA_Frame, MUIV_Frame_String, + End, + End, + Child, HVSpace, + End, //VGroup + + Child, HVSpace, + + Child, ColGroup(2), + MUIA_FrameTitle, GetLocString(MSGID_ENTRY_GROUP_UNSELECTEDIMAGE), + MUIA_Background, MUII_GroupBack, + GroupFrame, + + Child, inst->mpb_Objects[OBJNDX_PopAsl_UnselectedImage] = PopaslObject, + MUIA_CycleChain, TRUE, + MUIA_ShortHelp, GetLocString(MSGID_POPASL_UNSELECTEDIMAGE_SHORTHELP), + MUIA_Popasl_Type, ASL_FileRequest, + MUIA_Popasl_StartHook, &inst->mpb_Hooks[HOOKNDX_ImagePopAslFileStart], + MUIA_Popstring_String, MUI_MakeObject(MUIO_String, NULL, MAX_COMMANDNAME), + MUIA_Popstring_Button, PopButton(MUII_PopFile), + End, //PopaslObject + + Child, inst->mpb_Objects[OBJNDX_DtImage_UnselectedImage] = DataTypesImageObject, + MUIA_ShortHelp, GetLocString(MSGID_SAMPLE_UNSELECTEDIMAGE_SHORTHELP), + MUIA_ScaDtpic_Name, (ULONG) "", + End, //DataTypesMCCObject + End, //ColGroup + + Child, ColGroup(2), + MUIA_FrameTitle, GetLocString(MSGID_ENTRY_GROUP_SELECTEDIMAGE), + MUIA_Background, MUII_GroupBack, + GroupFrame, + + Child, inst->mpb_Objects[OBJNDX_PopAsl_SelectedImage] = PopaslObject, + MUIA_CycleChain, TRUE, + MUIA_ShortHelp, GetLocString(MSGID_POPASL_SELECTEDIMAGE_SHORTHELP), + MUIA_Popasl_Type, ASL_FileRequest, + MUIA_Popasl_StartHook, &inst->mpb_Hooks[HOOKNDX_ImagePopAslFileStart], + MUIA_Popstring_String, MUI_MakeObject(MUIO_String, NULL, MAX_COMMANDNAME), + MUIA_Popstring_Button, PopButton(MUII_PopFile), + End, //PopaslObject + + Child, inst->mpb_Objects[OBJNDX_DtImage_SelectedImage] = DataTypesImageObject, + MUIA_ShortHelp, GetLocString(MSGID_SAMPLE_SELECTEDIMAGE_SHORTHELP), + MUIA_ScaDtpic_Name, (ULONG) "", + End, //DataTypesMCCObject + + End, //ColGroup + + Child, HVSpace, + + Child, inst->mpb_Objects[OBJNDX_Group_CmdProperties] = VGroup, + MUIA_FrameTitle, GetLocString(MSGID_MENU_GROUP_COMMAND_PROPERTIES), + MUIA_Background, MUII_GroupBack, + GroupFrame, + + Child, inst->mpb_Objects[OBJNDX_Group_String] = VGroup, + Child, inst->mpb_Objects[OBJNDX_CycleGad] = CycleObject, + MUIA_Cycle_Entries, CmdModeStrings, + MUIA_Weight, 5, + MUIA_CycleChain, TRUE, + End, + + Child, HGroup, + Child, inst->mpb_Objects[OBJNDX_PopObject] = PopobjectObject, + MUIA_ShowMe, FALSE, + MUIA_CycleChain, TRUE, + MUIA_Popstring_Button, PopButton(MUII_PopUp), + MUIA_Popobject_StrObjHook, &inst->mpb_Hooks[HOOKNDX_CmdListPopupOpen], + MUIA_Popobject_Object, inst->mpb_Objects[OBJNDX_CmdListView] = NListviewObject, + MUIA_NListview_NList, NListObject, + InputListFrame, + MUIA_Background, MUII_ListBack, + MUIA_NList_Format, ",", + MUIA_NList_ConstructHook2, &inst->mpb_Hooks[HOOKNDX_CmdListConstruct], + MUIA_NList_DestructHook2, &inst->mpb_Hooks[HOOKNDX_CmdListDestruct], + MUIA_NList_DisplayHook2, &inst->mpb_Hooks[HOOKNDX_CmdListDisplay], + MUIA_NList_CompareHook2, &inst->mpb_Hooks[HOOKNDX_CmdListCompare], + MUIA_NList_AdjustWidth, TRUE, + MUIA_NList_SortType, 1, + MUIA_NList_TitleMark, MUIV_NList_TitleMark_Down | 1, + MUIA_NList_SourceArray, CommandsArray, + End, //NListObject + End, //NListviewObject + End, //PopobjectObject + + Child, inst->mpb_Objects[OBJNDX_Popbutton] = PopButton(MUII_PopUp), + + Child, inst->mpb_Objects[OBJNDX_StringCmd] = StringObject, + MUIA_CycleChain, TRUE, + MUIA_String_MaxLen, MAX_LINESIZE, + MUIA_Frame, MUIV_Frame_String, + End, + End, //HGroup + End, //VGroup + + Child, HVSpace, + + Child, ColGroup(4), + Child, HVSpace, + + Child, Label(GetLocString(MSGID_ARGSNAME)), + Child, inst->mpb_Objects[OBJNDX_CheckArgs] = CheckMark(FALSE), + + Child, HVSpace, + End, //ColGroup + + Child, ColGroup(2), + Child, Label(GetLocString(MSGID_STACKNAME)), + Child, inst->mpb_Objects[OBJNDX_StringStack] = StringObject, + MUIA_CycleChain, TRUE, + MUIA_Frame, MUIV_Frame_String, + MUIA_Weight, 30, + MUIA_String_Accept, "0123456789", + MUIA_String_MaxLen, 10, + MUIA_String_Integer, DEFAULT_STACKSIZE, + End, + + Child, Label(GetLocString(MSGID_PRIORITY_SLIDER_NAME)), + Child, inst->mpb_Objects[OBJNDX_SliderPriority] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Group_Horiz, TRUE, + MUIA_Numeric_Min, -128, + MUIA_Numeric_Max, 127, + MUIA_Numeric_Value, 0, + MUIA_ShortHelp, GetLocString(MSGID_PRIORITY_SLIDER_BUBBLE), + End, + End, //ColGroup + End, //VGroup + Child, HVSpace, + End, //VGroup + End, //HGroup + + Child, HGroup, + Child, inst->mpb_Objects[OBJNDX_Lamp_Changed] = LampObject, + MUIA_Lamp_Type, MUIV_Lamp_Type_Huge, + MUIA_Lamp_Color, MUIV_Lamp_Color_Off, + MUIA_ShortHelp, GetLocString(MSGID_SHORTHELP_LAMP_CHANGED), + End, //LampObject + + Child, inst->mpb_Objects[OBJNDX_Group_Buttons1] = HGroup, + MUIA_Group_SameWidth, TRUE, + Child, inst->mpb_Objects[OBJNDX_NewMenuButton] = KeyButtonHelp(GetLocString(MSGID_NEWNAME), + 'm', GetLocString(MSGID_SHORTHELP_NEWMENUBUTTON)), + Child, inst->mpb_Objects[OBJNDX_NewItemButton] = KeyButtonHelp(GetLocString(MSGID_NEWINAME), + 'i', GetLocString(MSGID_SHORTHELP_NEWITEMBUTTON)), + Child, inst->mpb_Objects[OBJNDX_NewCommandButton] = KeyButtonHelp(GetLocString(MSGID_NEW2NAME), + 'c', GetLocString(MSGID_SHORTHELP_NEWCOMMANDBUTTON)), + Child, inst->mpb_Objects[OBJNDX_DelButton] = KeyButtonHelp(GetLocString(MSGID_DELNAME), + 'd', GetLocString(MSGID_SHORTHELP_DELBUTTON)), + End, //HGroup + End, //HGroup + End, //VGroup + + MUIA_ContextMenu, inst->mpb_Objects[OBJNDX_ContextMenu], + End; + + if (NULL == inst->mpb_Objects[OBJNDX_Group_Main]) + return NULL; + + d1(kprintf("%s/%s//%ld: ContextMenu=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->mpb_Objects[OBJNDX_ContextMenu])); + + set(inst->mpb_Objects[OBJNDX_Menu_HideObsolete], MUIA_Menuitem_Checked, inst->mpb_HideObsoletePopupMenus); + + DoMethod(inst->mpb_Objects[OBJNDX_CmdListView], MUIM_NList_Sort); + + DoMethod(inst->mpb_Objects[OBJNDX_CmdListView], MUIM_Notify, MUIA_Listview_DoubleClick, TRUE, + inst->mpb_Objects[OBJNDX_CmdListView], 2, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_CmdSelected]); + DoMethod(inst->mpb_Objects[OBJNDX_StringHotkey], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + inst->mpb_Objects[OBJNDX_MainListTree], 3, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_ChangeHotkey], MUIV_TriggerValue); + + DoMethod(inst->mpb_Objects[OBJNDX_PopAsl_UnselectedImage], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + inst->mpb_Objects[OBJNDX_MainListTree], 3, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_ChangeUnselectedImage], MUIV_TriggerValue); + + DoMethod(inst->mpb_Objects[OBJNDX_PopAsl_SelectedImage], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + inst->mpb_Objects[OBJNDX_MainListTree], 3, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_ChangeSelectedImage], MUIV_TriggerValue); + + DoMethod(inst->mpb_Objects[OBJNDX_NameString], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + inst->mpb_Objects[OBJNDX_MainListTree], 3, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_RenameEntry], MUIV_TriggerValue); + + DoMethod(inst->mpb_Objects[OBJNDX_SliderPriority], MUIM_Notify, MUIA_Numeric_Value, MUIV_EveryTime, + inst->mpb_Objects[OBJNDX_MainListTree], 2, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_ChangeEntry3]); + + DoMethod(inst->mpb_Objects[OBJNDX_StringStack], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + inst->mpb_Objects[OBJNDX_MainListTree], 2, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_ChangeEntry3]); + + DoMethod(inst->mpb_Objects[OBJNDX_StringCmd], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + inst->mpb_Objects[OBJNDX_MainListTree], 2, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_ChangeEntry3]); + + DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], MUIM_Notify, MUIA_NListtree_Active, MUIV_EveryTime, + inst->mpb_Objects[OBJNDX_MainListTree], 3, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_SelectEntry], MUIV_TriggerValue); + + DoMethod(inst->mpb_Objects[OBJNDX_CycleGad], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, + inst->mpb_Objects[OBJNDX_MainListTree], 2, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_ChangeEntry3]); + + DoMethod(inst->mpb_Objects[OBJNDX_Popbutton], MUIM_Notify, MUIA_Pressed, FALSE, + inst->mpb_Objects[OBJNDX_MainListTree], 2, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_PopButton]); + + DoMethod(inst->mpb_Objects[OBJNDX_NewMenuButton], MUIM_Notify, MUIA_Pressed, FALSE, + inst->mpb_Objects[OBJNDX_MainListTree], 2, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_AddMenu]); + + DoMethod(inst->mpb_Objects[OBJNDX_NewItemButton], MUIM_Notify, MUIA_Pressed, FALSE, + inst->mpb_Objects[OBJNDX_MainListTree], 2, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_AddMenuItem]); + + DoMethod(inst->mpb_Objects[OBJNDX_NewCommandButton], MUIM_Notify, MUIA_Pressed, FALSE, + inst->mpb_Objects[OBJNDX_MainListTree], 2, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_AddCommand]); + + DoMethod(inst->mpb_Objects[OBJNDX_DelButton], MUIM_Notify, MUIA_Pressed, FALSE, + inst->mpb_Objects[OBJNDX_MainListTree], 2, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_RemoveEntry]); + + + DoMethod(inst->mpb_Objects[OBJNDX_CheckArgs], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + inst->mpb_Objects[OBJNDX_MainListTree], 2, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_ChangeEntry3]); + + DoMethod(inst->mpb_Objects[OBJNDX_Group_Main], MUIM_Notify, MUIA_ContextMenuTrigger, MUIV_EveryTime, + inst->mpb_Objects[OBJNDX_Group_Main], 3, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_ContextMenuTrigger], MUIV_TriggerValue ); + + DoMethod(inst->mpb_Objects[OBJNDX_Group_Main], MUIM_Notify, MUIA_AppMessage, MUIV_EveryTime, + inst->mpb_Objects[OBJNDX_Group_Main], 3, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_AppMessage], MUIV_TriggerValue); + + d1(KPrintF("%s/%s//%ld: mpb_HideObsoletePopupMenus=%ld\n", __FILE__, __FUNC__, __LINE__, inst->mpb_HideObsoletePopupMenus)); + + InsertMenuRootEntries(inst); + + d1(kprintf("%s/%s//%ld:\n", __FILE__, __FUNC__, __LINE__)); + d1(kprintf("%s/%s//%ld: LocaleBase=%08lx IFFParseBase=%08lx\n", __FILE__, __FUNC__, __LINE__, LocaleBase, IFFParseBase)); + + return inst->mpb_Objects[OBJNDX_Group_Main]; +} + + +static BOOL OpenLibraries(void) +{ + d1(kprintf("%s/%s//%ld:\n", __FILE__, __FUNC__, __LINE__)); + + DOSBase = (APTR) OpenLibrary( "dos.library", 39 ); + if (NULL == DOSBase) + return FALSE; +#ifdef __amigaos4__ + IDOS = (struct DOSIFace *)GetInterface((struct Library *)DOSBase, "main", 1, NULL); + if (NULL == IDOS) + return FALSE; +#endif + + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + if (NULL == IntuitionBase) + return FALSE; +#ifdef __amigaos4__ + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + return FALSE; +#endif + + MUIMasterBase = OpenLibrary("zune.library", 0); + if (NULL == MUIMasterBase) + MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN-1); + if (NULL == MUIMasterBase) + return FALSE; +#ifdef __amigaos4__ + IMUIMaster = (struct MUIMasterIFace *)GetInterface((struct Library *)MUIMasterBase, "main", 1, NULL); + if (NULL == IMUIMaster) + return FALSE; +#endif + + IFFParseBase = OpenLibrary("iffparse.library", 36); + if (NULL == IFFParseBase) + return FALSE; +#ifdef __amigaos4__ + IIFFParse = (struct IFFParseIFace *)GetInterface((struct Library *)IFFParseBase, "main", 1, NULL); + if (NULL == IIFFParse) + return FALSE; +#endif + + IconBase = OpenLibrary("icon.library", 0); + if (NULL == IconBase) + return FALSE; +#ifdef __amigaos4__ + IIcon = (struct IconIFace *)GetInterface((struct Library *)IconBase, "main", 1, NULL); + if (NULL == IIcon) + return FALSE; +#endif + + GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 39); + if (NULL == GfxBase) + return FALSE; +#ifdef __amigaos4__ + IGraphics = (struct GraphicsIFace *)GetInterface((struct Library *)GfxBase, "main", 1, NULL); + if (NULL == IGraphics) + return FALSE; +#endif + + UtilityBase = (T_UTILITYBASE) OpenLibrary(UTILITYNAME, 39); + if (NULL == UtilityBase) + return FALSE; +#ifdef __amigaos4__ + IUtility = (struct UtilityIFace *)GetInterface((struct Library *)UtilityBase, "main", 1, NULL); + if (NULL == IUtility) + return FALSE; +#endif + + DataTypesBase = OpenLibrary("datatypes.library", 39); + if (NULL == DataTypesBase) + return FALSE; +#ifdef __amigaos4__ + IDataTypes = (struct DataTypesIFace *)GetInterface((struct Library *)DataTypesBase, "main", 1, NULL); + if (NULL == IDataTypes) + return FALSE; +#endif + +#ifdef __amigaos4__ + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + return FALSE; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + return FALSE; +#endif + + LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 39); +#ifdef __amigaos4__ + if (LocaleBase) + ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL); +#endif + + d1(kprintf("%s/%s//%ld: LocaleBase=%08lx IFFParseBase=%08lx\n", __FILE__, __FUNC__, __LINE__, LocaleBase, IFFParseBase)); + + return TRUE; +} + + +static void CloseLibraries(void) +{ + d1(kprintf("%s/%s//%ld:\n", __FILE__, __FUNC__, __LINE__)); + +#ifdef __amigaos4__ + if (ILocale) + { + DropInterface((struct Interface *)ILocale); + ILocale = NULL; + } +#endif + if (LocaleBase) + { + CloseLibrary((struct Library *) LocaleBase); + LocaleBase = NULL; + } +#ifdef __amigaos4__ + if (INewlib) + { + DropInterface(INewlib); + INewlib = NULL; + } + if (NewlibBase) + { + CloseLibrary(NewlibBase); + NewlibBase = NULL; + } + if (IDataTypes) + { + DropInterface((struct Interface *)IDataTypes); + IDataTypes = NULL; + } +#endif + if (DataTypesBase) + { + CloseLibrary(DataTypesBase); + DataTypesBase = NULL; + } +#ifdef __amigaos4__ + if (IUtility) + { + DropInterface((struct Interface *)IUtility); + IUtility = NULL; + } +#endif + if (UtilityBase) + { + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } +#ifdef __amigaos4__ + if (IGraphics) + { + DropInterface((struct Interface *)IGraphics); + IGraphics = NULL; + } +#endif + if (GfxBase) + { + CloseLibrary((struct Library *) GfxBase); + GfxBase = NULL; + } +#ifdef __amigaos4__ + if (IIcon) + { + DropInterface((struct Interface *)IIcon); + IIcon = NULL; + } +#endif + if (IconBase) + { + CloseLibrary(IconBase); + IconBase = NULL; + } +#ifdef __amigaos4__ + if (IIFFParse) + { + DropInterface((struct Interface *)IIFFParse); + IIFFParse = NULL; + } +#endif + if (IFFParseBase) + { + CloseLibrary(IFFParseBase); + IFFParseBase = NULL; + } +#ifdef __amigaos4__ + if (IMUIMaster) + { + DropInterface((struct Interface *)IMUIMaster); + IMUIMaster = NULL; + } +#endif + if (MUIMasterBase) + { + CloseLibrary(MUIMasterBase); + MUIMasterBase = NULL; + } +#ifdef __amigaos4__ + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } +#endif + if (IntuitionBase) + { + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } +#ifdef __amigaos4__ + if (IDOS) + { + DropInterface((struct Interface *)IDOS); + IDOS = NULL; + } +#endif + if (DOSBase) + { + CloseLibrary((struct Library *) DOSBase); + DOSBase = NULL; + } + +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT CmdListConstructHookFunc(struct Hook *hook, APTR obj, struct NList_ConstructMessage *msg) +{ + (void) hook; + (void) obj; + + return msg->entry; +} + +static SAVEDS(void) INTERRUPT CmdListDestructHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *msg) +{ + (void) hook; + (void) obj; + (void) msg; +} + + +static SAVEDS(ULONG) INTERRUPT CmdListDisplayHookFunc(struct Hook *hook, APTR obj, struct NList_DisplayMessage *ltdm) +{ + struct CommandTableEntry *cte = (struct CommandTableEntry *) ltdm->entry; + + d1(KPrintF(__FILE__ "/%s/%ld: cte=%08lx\n", __FUNC__, __LINE__, cte)); + + if (cte) + { + ltdm->preparses[0] = ""; + + ltdm->strings[0] = GetLocString(cte->cte_NameMsgId); + ltdm->strings[1] = (STRPTR) cte->cte_Command; + } + else + { + // display titles + ltdm->preparses[0] = ""; + ltdm->preparses[1] = ""; + + ltdm->strings[0] = ""; + ltdm->strings[1] = ""; + } + + return 0; +} + + +static SAVEDS(LONG) INTERRUPT CmdListCompareHookFunc(struct Hook *hook, Object *obj, struct NList_CompareMessage *ncm) +{ + const struct CommandTableEntry *cte1 = (const struct CommandTableEntry *) ncm->entry1; + const struct CommandTableEntry *cte2 = (const struct CommandTableEntry *) ncm->entry2; + LONG col1 = ncm->sort_type & MUIV_NList_TitleMark_ColMask; + LONG col2 = ncm->sort_type2 & MUIV_NList_TitleMark2_ColMask; + LONG Result = 0; + + if (ncm->sort_type != MUIV_NList_SortType_None) + { + // primary sorting + switch (col1) + { + case 0: // sort by full name + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = Stricmp(GetLocString(cte2->cte_NameMsgId), GetLocString(cte1->cte_NameMsgId)); + else + Result = Stricmp(GetLocString(cte1->cte_NameMsgId), GetLocString(cte2->cte_NameMsgId)); + break; + case 1: // sort by internal name + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = Stricmp(cte2->cte_Command, cte1->cte_Command); + else + Result = Stricmp(cte1->cte_Command, cte2->cte_Command); + break; + default: + break; + } + + if (0 == Result && col1 != col2) + { + // Secondary sorting + switch (col2) + { + case 0: // sort by full name + if (ncm->sort_type2 & MUIV_NList_TitleMark2_TypeMask) + Result = Stricmp(GetLocString(cte2->cte_NameMsgId), GetLocString(cte1->cte_NameMsgId)); + else + Result = Stricmp(GetLocString(cte1->cte_NameMsgId), GetLocString(cte2->cte_NameMsgId)); + break; + case 1: // sort by internal name + if (ncm->sort_type2 & MUIV_NList_TitleMark2_TypeMask) + Result = Stricmp(cte2->cte_Command, cte1->cte_Command); + else + Result = Stricmp(cte1->cte_Command, cte2->cte_Command); + break; + default: + break; + } + } + } + + return Result; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(LONG) INTERRUPT CmdListPopupOpenHookFunc(struct Hook *hook, Object *list, Object *str) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + ULONG entries = 0; + ULONG n; + CONST_STRPTR string = ""; + size_t length; + + get(list, MUIA_NList_Entries, &entries); + get(inst->mpb_Objects[OBJNDX_StringCmd], MUIA_String_Contents, &string); + + length = strlen(string); + + d1(KPrintF(__FILE__ "/%s/%ld: string=<%s> entries=%lu length=%lu\n", __FUNC__, __LINE__, string, entries, length)); + + for (n = 0; n < entries; n++) + { + struct CommandTableEntry *cte = NULL; + + DoMethod(list, MUIM_NList_GetEntry, n, &cte); + if (cte) + { + if (0 == Strnicmp(cte->cte_Command, string, length)) + { + d1(KPrintF(__FILE__ "/%s/%ld: found!\n", __FUNC__, __LINE__, cte)); + set(list, MUIA_NList_Active, n); + DoMethod(list, MUIM_NList_Jump, n); + break; + } + } + } + + return TRUE; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT TreeConstructFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_ConstructMessage *ltcm) +{ + struct MenuListEntry *mle = AllocPooled(ltcm->MemPool, sizeof(struct MenuListEntry)); + + d1(kprintf("%s/%s/%ld: obj=%08lx ltcm=%08lx memPool=%08lx UserData=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, obj, ltcm, ltcm->MemPool, ltcm->UserData)); + d1(kprintf("%s/%s/%ld: mle=%08lx\n", __FILE__, __FUNC__, __LINE__, mle)); + + if (mle) + { + const struct MenuInsertEntry *mie = (const struct MenuInsertEntry *) ltcm->UserData; + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + + if (ltcm->Name) + stccpy(mle->llist_name, ltcm->Name, sizeof(mle->llist_name)); + else + strcpy(mle->llist_name, ""); + + d1(KPrintF("%s/%s/%ld: llist_name=<%s> mtre_type=%ld\n", __FILE__, __FUNC__, __LINE__, mle->llist_name, mie->mie_TreeEntry->mtre_type)); + + d1(KPrintF("%s/%s/%ld: mtre_iconnames=%08lx\n", __FILE__, __FUNC__, __LINE__, mie->mie_TreeEntry->MenuCombo.MenuTree.mtre_iconnames)); + if ((mie->mie_TreeEntry->mtre_flags & MTREFLGF_IconNames) && + mie->mie_TreeEntry->MenuCombo.MenuTree.mtre_iconnames) + { + stccpy(mle->llist_UnselectedIconName, mie->mie_TreeEntry->MenuCombo.MenuTree.mtre_iconnames, + sizeof(mle->llist_UnselectedIconName)); + stccpy(mle->llist_SelectedIconName, + mie->mie_TreeEntry->MenuCombo.MenuTree.mtre_iconnames + 1 + strlen(mie->mie_TreeEntry->MenuCombo.MenuTree.mtre_iconnames), + sizeof(mle->llist_SelectedIconName)); + + d1(KPrintF("%s/%s/%ld: llist_UnselectedIconName=<%s> llist_SelectedIconName=<%s>\n", __FILE__, __FUNC__, __LINE__, mle->llist_UnselectedIconName, mle->llist_SelectedIconName)); + + mle->llist_UnSelImageIndex = ++inst->mpb_TreeImageIndex; + + mle->llist_UnSelImageObj = DataTypesImageObject, + MUIA_ScaDtpic_Name, (ULONG) mle->llist_UnselectedIconName, + End; + + d1(KPrintF("%s/%s/%ld: llist_UnSelImageObj=%08lx\n", __FILE__, __FUNC__, __LINE__, mle->llist_UnSelImageObj)); + + DoMethod(obj, MUIM_NList_UseImage, mle->llist_UnSelImageObj, mle->llist_UnSelImageIndex, 0); + } + else + { + mle->llist_UnSelImageIndex = 0; + strcpy(mle->llist_UnselectedIconName, ""); + strcpy(mle->llist_SelectedIconName, ""); + } + + ltcm->UserData = mle; + ltcm->Name = mle->llist_name; + mle->llist_EntryType = mie->mie_TreeEntry->mtre_type; + mle->llist_Flags = mie->mie_MenuFlags; + + d1(kprintf("%s/%s/%ld: EntryName=<%s> mie_MenuFlags=%02lx EntryType=%ld\n", \ + __FILE__, __FUNC__, __LINE__, ltcm->Name, mie->mie_MenuFlags, mie->mie_TreeEntry->mtre_type)); + + d1(kprintf("%s/%s/%ld: llist_HotKey=%08lx mtre_hotkey=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, mle->llist_HotKey, mie->mie_TreeEntry->MenuCombo.MenuTree.mtre_hotkey)); + + stccpy(mle->llist_HotKey, mie->mie_TreeEntry->MenuCombo.MenuTree.mtre_hotkey, sizeof(mle->llist_HotKey)); + + if (SCAMENUTYPE_Command == mle->llist_EntryType) + { + d1(kprintf("%s/%s/%ld: llist_name=%08lx mcom_name=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, mle->llist_name, mie->mie_TreeEntry->MenuCombo.MenuCommand.mcom_name)); + + stccpy(mle->llist_name, + mie->mie_TreeEntry->MenuCombo.MenuCommand.mcom_name ? mie->mie_TreeEntry->MenuCombo.MenuCommand.mcom_name : (STRPTR) "", + sizeof(mle->llist_name)); + + mle->llist_Priority = mie->mie_TreeEntry->MenuCombo.MenuCommand.mcom_pri; + mle->llist_CommandType = mie->mie_TreeEntry->MenuCombo.MenuCommand.mcom_type; + mle->llist_CommandFlags = mie->mie_TreeEntry->MenuCombo.MenuCommand.mcom_flags; + mle->llist_Stack = mie->mie_TreeEntry->MenuCombo.MenuCommand.mcom_stack; + } + } + + return mle; +} + +static SAVEDS(void) INTERRUPT TreeDestructFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_DestructMessage *ltdm) +{ + struct MenuListEntry *mle = (struct MenuListEntry *) ltdm->UserData; + + d1(kprintf("%s/%s/%ld: mle=%08lx\n", __FILE__, __FUNC__, __LINE__, mle)); + + if (mle) + { + if (mle->llist_UnSelImageObj) + { + DoMethod(obj, MUIM_NList_UseImage, NULL, mle->llist_UnSelImageIndex, 0); + + MUI_DisposeObject(mle->llist_UnSelImageObj); + mle->llist_UnSelImageObj = NULL; + } + FreePooled(ltdm->MemPool, mle, sizeof(struct MenuListEntry)); + } + + ltdm->UserData = NULL; +} + +static SAVEDS(ULONG) INTERRUPT TreeDisplayFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_DisplayMessage *ltdm) +{ + static CONST_STRPTR EntryTypeNames[] = + { + "\33b\33u", // MainMenu + "\33b", // Menu + "", // MenuItem + "\33i", // Command + "\33b\338" // ToolsMenu + }; + struct MenuListEntry *mle = (struct MenuListEntry *) ltdm->TreeNode->tn_User; + + d1(kprintf("%s/%s/%ld: mle=%08lx\n", __FILE__, __FUNC__, __LINE__, mle)); + + if (mle) + { + ltdm->Preparse[0] = (STRPTR) EntryTypeNames[mle->llist_EntryType]; + + d1(kprintf("%s/%s/%ld: EntryName=<%s> commandType=%ld\n", \ + __FILE__, __FUNC__, __LINE__, mle->llist_name, mle->llist_CommandType)); + + switch (mle->llist_EntryType) + { + case SCAMENUTYPE_Command: + ltdm->Array[0] = mle->llist_name; + ltdm->Array[1] = ""; + break; + case SCAMENUTYPE_MenuItem: + if (0 == strlen(ltdm->TreeNode->tn_Name)) + ltdm->Array[0] = GetLocString(MSGID_BARNAME); + else + { + if (mle->llist_UnSelImageObj) + { + snprintf(mle->llist_MenuItemName, sizeof(mle->llist_MenuItemName), + "\33o[%ld]%s", + (long)mle->llist_UnSelImageIndex, ltdm->TreeNode->tn_Name); + ltdm->Array[0] = mle->llist_MenuItemName; + } + else + { + ltdm->Array[0] = ltdm->TreeNode->tn_Name; + } + } + ltdm->Array[1] = mle->llist_HotKey; + break; + default: + ltdm->Array[0] = ltdm->TreeNode->tn_Name; + ltdm->Array[1] = ""; + break; + } + } + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(ULONG) INTERRUPT ImagePopAslFileStartHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct TagItem *TagList = (struct TagItem *) msg; +// struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + + d1(KPrintF("%s/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst)); + + while (TAG_END != TagList->ti_Tag) + TagList++; + + TagList->ti_Tag = ASLFR_DrawersOnly; + TagList->ti_Data = FALSE; + TagList++; + +// TagList->ti_Tag = ASLFR_InitialFile; +// TagList->ti_Data = (ULONG) inst->fpb_FileName; +// TagList++; + + TagList->ti_Tag = ASLFR_InitialDrawer; + TagList->ti_Data = (ULONG) "THEME:FileTypes/"; + TagList++; + + TagList->ti_Tag = TAG_END; + + return TRUE; +} + +//---------------------------------------------------------------------------- + +static STRPTR GetLocString(ULONG MsgId) +{ + struct ScalosMenu_LocaleInfo li; + + li.li_Catalog = MenuPrefsCatalog; +#ifndef __amigaos4__ + li.li_LocaleBase = LocaleBase; +#else + li.li_ILocale = ILocale; +#endif + + return (STRPTR) GetScalosMenuString(&li, MsgId); +} + +static void TranslateStringArray(STRPTR *stringArray) +{ + while (*stringArray) + { + *stringArray = GetLocString((ULONG) *stringArray); + stringArray++; + } +} + +static void TranslateNewMenu(struct NewMenu *nm) +{ + while (nm && NM_END != nm->nm_Type) + { + if (NM_BARLABEL != nm->nm_Label) + nm->nm_Label = GetLocString((ULONG) nm->nm_Label); + + if (nm->nm_CommKey) + nm->nm_CommKey = GetLocString((ULONG) nm->nm_CommKey); + + nm++; + } +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT ResetToDefaultsHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + + d1(KPrintF("%s/%s//%ld: START\n", __FILE__, __FUNC__, __LINE__)); + + set(inst->mpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Quiet, TRUE); + set(inst->mpb_Objects[OBJNDX_HiddenListTree], MUIA_NListtree_Quiet, TRUE); + d1(KPrintF("%s/%s//%ld: \n", __FILE__, __FUNC__, __LINE__)); + + // Remove main menu contents + ClearMenuList(inst); + d1(KPrintF("%s/%s//%ld: \n", __FILE__, __FUNC__, __LINE__)); + + set(inst->mpb_MainMenuNode.mpn_Listtree, + MUIA_NListtree_Active, (ULONG) inst->mpb_MainMenuNode.mpn_ListNode); + + d1(KPrintF("%s/%s//%ld: \n", __FILE__, __FUNC__, __LINE__)); + + AddDefaultMenuContents(inst); + + d1(KPrintF("%s/%s//%ld: \n", __FILE__, __FUNC__, __LINE__)); + + DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], MUIM_NListtree_Close, + MUIV_NListtree_Close_ListNode_Root, MUIV_NListtree_Close_TreeNode_All, 0); + + set(inst->mpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Quiet, FALSE); + set(inst->mpb_Objects[OBJNDX_HiddenListTree], MUIA_NListtree_Quiet, FALSE); + + d1(KPrintF("%s/%s//%ld: END\n", __FILE__, __FUNC__, __LINE__)); + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT OpenHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + + if (NULL == inst->mpb_LoadReq) + { + inst->mpb_LoadReq = MUI_AllocAslRequestTags(ASL_FileRequest, + ASLFR_InitialFile, "Menu.pre", + ASLFR_Flags1, FRF_DOPATTERNS, + ASLFR_InitialDrawer, "SYS:Prefs/presets", + ASLFR_InitialPattern, "#?.(pre|prefs)", + ASLFR_UserData, inst, + ASLFR_IntuiMsgFunc, &inst->mpb_Hooks[HOOKNDX_AslIntuiMsg], + TAG_END); + } + if (inst->mpb_LoadReq) + { + BOOL Result; + struct Window *win = NULL; + + get(inst->mpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Window, &win); + + //AslRequest( + Result = MUI_AslRequestTags(inst->mpb_LoadReq, + ASLFR_Window, win, + ASLFR_SleepWindow, TRUE, + ASLFR_TitleText, GetLocString(MSGID_MENU_PROJECT_OPEN), + TAG_END); + + if (Result) + { + BPTR dirLock = Lock(inst->mpb_LoadReq->fr_Drawer, ACCESS_READ); + + if (dirLock) + { + BPTR oldDir = CurrentDir(dirLock); + + ClearMenuList(inst); + ReadPrefsFile(inst, inst->mpb_LoadReq->fr_File, FALSE); + + CurrentDir(oldDir); + UnLock(dirLock); + } + } + } + + return 0; +} + + +static SAVEDS(APTR) INTERRUPT MergeHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + + if (NULL == inst->mpb_LoadReq) + { + inst->mpb_LoadReq = MUI_AllocAslRequestTags(ASL_FileRequest, + ASLFR_InitialFile, "Menu.pre", + ASLFR_Flags1, FRF_DOPATTERNS, + ASLFR_InitialDrawer, "SYS:Prefs/presets", + ASLFR_InitialPattern, "#?.(pre|prefs)", + ASLFR_UserData, inst, + ASLFR_IntuiMsgFunc, &inst->mpb_Hooks[HOOKNDX_AslIntuiMsg], + TAG_END); + } + if (inst->mpb_LoadReq) + { + BOOL Result; + struct Window *win = NULL; + + get(inst->mpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Window, &win); + + //AslRequest( + Result = MUI_AslRequestTags(inst->mpb_LoadReq, + ASLFR_Window, win, + ASLFR_SleepWindow, TRUE, + ASLFR_TitleText, GetLocString(MSGID_MENU_PROJECT_MERGE_ASLTITLE), + TAG_END); + + if (Result) + { + BPTR dirLock = Lock(inst->mpb_LoadReq->fr_Drawer, ACCESS_READ); + + if (dirLock) + { + BPTR oldDir = CurrentDir(dirLock); + + ReadPrefsFile(inst, inst->mpb_LoadReq->fr_File, FALSE); + + SetChangedFlag(inst, TRUE); + + CurrentDir(oldDir); + UnLock(dirLock); + } + } + } + + return 0; +} + +static SAVEDS(APTR) INTERRUPT LastSavedHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + + ClearMenuList(inst); + ReadPrefsFile(inst, "ENVARC:Scalos/Menu13.prefs", FALSE); + SetChangedFlag(inst, TRUE); + + return 0; +} + +static SAVEDS(APTR) INTERRUPT RestoreHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + + ClearMenuList(inst); + ReadPrefsFile(inst, "ENV:Scalos/Menu13.prefs", FALSE); + SetChangedFlag(inst, TRUE); + + return 0; +} + +static SAVEDS(APTR) INTERRUPT SaveAsHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + + if (NULL == inst->mpb_SaveReq) + { + CONST_STRPTR InitialDrawer; + CONST_STRPTR InitialFile; + + if (inst->mpb_LoadReq) + { + InitialDrawer = inst->mpb_LoadReq->fr_Drawer; + InitialFile = inst->mpb_LoadReq->fr_File; + } + else + { + InitialDrawer = "SYS:Prefs/presets"; + InitialFile = "Menu.pre"; + } + + inst->mpb_SaveReq = MUI_AllocAslRequestTags(ASL_FileRequest, + ASLFR_InitialFile, InitialFile, + ASLFR_DoSaveMode, TRUE, + ASLFR_InitialDrawer, InitialDrawer, + ASLFR_UserData, inst, + ASLFR_IntuiMsgFunc, &inst->mpb_Hooks[HOOKNDX_AslIntuiMsg], + TAG_END); + } + if (inst->mpb_SaveReq) + { + BOOL Result; + struct Window *win = NULL; + + get(inst->mpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Window, &win); + + //AslRequest( + Result = MUI_AslRequestTags(inst->mpb_SaveReq, + ASLFR_TitleText, GetLocString(MSGID_MENU_PROJECT_SAVEAS), + ASLFR_Window, win, + ASLFR_SleepWindow, TRUE, + TAG_END); + + if (Result) + { + BPTR dirLock = Lock(inst->mpb_SaveReq->fr_Drawer, ACCESS_READ); + + if (dirLock) + { + BPTR oldDir = CurrentDir(dirLock); + + WritePrefsFile(inst, inst->mpb_SaveReq->fr_File); + + CurrentDir(oldDir); + UnLock(dirLock); + } + } + } + + return 0; +} + + +static SAVEDS(APTR) INTERRUPT AboutHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + + MUI_Request(inst->mpb_Objects[OBJNDX_APP_Main], inst->mpb_Objects[OBJNDX_WIN_Main], 0, NULL, + GetLocString(MSGID_ABOUTREQOK), + GetLocString(MSGID_ABOUTREQFORMAT), + MajorVersion, MinorVersion, COMPILER_STRING, CURRENTYEAR); + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT RenameEntryHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + struct MUI_NListtree_TreeNode *TreeNode; + + if (inst->mpb_QuietFlag) + return 0; + + TreeNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, 0); + + if (TreeNode) + { + struct MenuListEntry *mle = (struct MenuListEntry *) TreeNode->tn_User; + STRPTR newName = ""; + BOOL MayAddCommand, MayHaveHotkey; + + SetChangedFlag(inst, TRUE); + + get(inst->mpb_Objects[OBJNDX_NameString], MUIA_String_Contents, &newName); + + set(inst->mpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Quiet, TRUE); + + stccpy(mle->llist_name, newName, sizeof(mle->llist_name)); + + if (0 == strlen(newName)) + { + // Remove all children from the new "=== Bar ===" + DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Remove, + TreeNode, + MUIV_NListtree_Remove_TreeNode_All); + + // BAR may not have a hotkey + strcpy(mle->llist_HotKey, ""); + + TreeNode->tn_Flags |= TNF_NOSIGN; + } + else + { + TreeNode->tn_Flags &= ~TNF_NOSIGN; + } + + DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Rename, + TreeNode, + newName, + 0); + + set(inst->mpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Quiet, FALSE); + + MayAddCommand = (strlen(mle->llist_name) > 0) && + ((SCAMENUTYPE_MenuItem == mle->llist_EntryType) + || (SCAMENUTYPE_Command == mle->llist_EntryType)); + + MayHaveHotkey = (strlen(mle->llist_name) > 0) + && SCAMENUTYPE_MenuItem == mle->llist_EntryType; + + set(inst->mpb_Objects[OBJNDX_StringHotkey], MUIA_Disabled, !MayHaveHotkey); + set(inst->mpb_Objects[OBJNDX_NewCommandButton], MUIA_Disabled, !MayAddCommand); + } + + return 0; +} + + +static SAVEDS(APTR) INTERRUPT ChangeHotkeyHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + STRPTR newHotKey = *(STRPTR *) msg; + struct MUI_NListtree_TreeNode *TreeNode; + + if (inst->mpb_QuietFlag) + return 0; + + TreeNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, 0); + + if (TreeNode) + { + struct MenuListEntry *mle = (struct MenuListEntry *) TreeNode->tn_User; + + SetChangedFlag(inst, TRUE); + + mle->llist_HotKey[0] = *newHotKey; + mle->llist_HotKey[1] = '\0'; + + DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Redraw, + TreeNode, + 0); + } + + return 0; +} + +static SAVEDS(APTR) INTERRUPT ChangeEntry3HookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + struct MUI_NListtree_TreeNode *TreeNode; + + if (inst->mpb_QuietFlag) + return 0; + + TreeNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, 0); + + if (TreeNode) + { + struct MenuListEntry *mle = (struct MenuListEntry *) TreeNode->tn_User; + + if (SCAMENUTYPE_Command == mle->llist_EntryType) + { + STRPTR string = NULL; + ULONG Value = 0; + LONG sValue = 0; + + SetChangedFlag(inst, TRUE); + + get(inst->mpb_Objects[OBJNDX_StringCmd], MUIA_String_Contents, &string); + stccpy(mle->llist_name, string, sizeof(mle->llist_name)); + + get(inst->mpb_Objects[OBJNDX_CycleGad], MUIA_Cycle_Active, &Value); + mle->llist_CommandType = Value; + + SwitchPopButton(inst, Value); + + get(inst->mpb_Objects[OBJNDX_CheckArgs], MUIA_Selected, &Value); + if (Value) + mle->llist_CommandFlags |= MCOMFLGF_Args; + else + mle->llist_CommandFlags &= ~MCOMFLGF_Args; + + EnableCommandArgumentGadgets(inst, mle); + + get(inst->mpb_Objects[OBJNDX_StringStack], MUIA_String_Integer, &mle->llist_Stack); + + get(inst->mpb_Objects[OBJNDX_SliderPriority], MUIA_Numeric_Value, &sValue); + mle->llist_Priority = sValue; + + DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], MUIM_NList_Redraw, MUIV_NList_Redraw_Active); + } + } + + return 0; +} + + +static SAVEDS(APTR) INTERRUPT ChangeUnselectedImageHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + STRPTR NewImage = *(STRPTR *) msg; + struct MUI_NListtree_TreeNode *TreeNode; + + if (inst->mpb_QuietFlag) + return 0; + + TreeNode = (struct MUI_NListtree_TreeNode *) DoMethod(o, + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, 0); + + if (TreeNode) + { + struct MenuListEntry *mle = (struct MenuListEntry *) TreeNode->tn_User; + + SetChangedFlag(inst, TRUE); + + stccpy(mle->llist_UnselectedIconName, NewImage, sizeof(mle->llist_UnselectedIconName)); + set(inst->mpb_Objects[OBJNDX_DtImage_UnselectedImage], MUIA_ScaDtpic_Name, (ULONG) mle->llist_UnselectedIconName); + + if (mle->llist_UnSelImageObj) + { + MUI_DisposeObject(mle->llist_UnSelImageObj); + mle->llist_UnSelImageObj = NULL; + + DoMethod(o, MUIM_NList_UseImage, mle->llist_UnSelImageObj, mle->llist_UnSelImageIndex, 0); + } + if (0 == mle->llist_UnSelImageIndex) + mle->llist_UnSelImageIndex = ++inst->mpb_TreeImageIndex; + + if (strlen(mle->llist_UnselectedIconName) > 0) + { + mle->llist_UnSelImageObj = DataTypesImageObject, + MUIA_ScaDtpic_Name, (ULONG) mle->llist_UnselectedIconName, + End; + DoMethod(o, MUIM_NList_UseImage, mle->llist_UnSelImageObj, mle->llist_UnSelImageIndex, 0); + } + + DoMethod(o, + MUIM_NListtree_Redraw, + TreeNode, + 0); + } + + return 0; +} + + +static SAVEDS(APTR) INTERRUPT ChangeSelectedImageHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + STRPTR NewImage = *(STRPTR *) msg; + struct MUI_NListtree_TreeNode *TreeNode; + + if (inst->mpb_QuietFlag) + return 0; + + TreeNode = (struct MUI_NListtree_TreeNode *) DoMethod(o, + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, 0); + + if (TreeNode) + { + struct MenuListEntry *mle = (struct MenuListEntry *) TreeNode->tn_User; + + SetChangedFlag(inst, TRUE); + + stccpy(mle->llist_SelectedIconName, NewImage, sizeof(mle->llist_SelectedIconName)); + set(inst->mpb_Objects[OBJNDX_DtImage_SelectedImage], MUIA_ScaDtpic_Name, (ULONG) mle->llist_SelectedIconName); + + DoMethod(o, + MUIM_NListtree_Redraw, + TreeNode, + 0); + } + + return 0; +} + + +static SAVEDS(APTR) INTERRUPT SelectEntryHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + struct MUI_NListtree_TreeNode *TreeNode = *(struct MUI_NListtree_TreeNode **) msg; + + if (inst->mpb_QuietFlag) + return 0; + + inst->mpb_QuietFlag = TRUE; + + if (TreeNode) + { + struct MenuListEntry *mle = (struct MenuListEntry *) TreeNode->tn_User; + + if (mle) + { + struct MUI_NListtree_TreeNode *tnShadow; + BOOL MayAddNewMenu, MayAddNewItem, MayAddCommand; + BOOL MayChangeName, MayDelete, MayHaveHotkey; + BOOL MayHaveImage; + enum MenuEntryType menuType; + ULONG Count, MaxCount; + + Count = DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], MUIM_NListtree_GetNr, + TreeNode, MUIV_NListtree_GetNr_Flag_CountLevel); + + menuType = GetMenuEntryType(inst, TreeNode); + MaxCount = GetMaxCountForEntry(menuType); + + MayAddNewMenu = (SCAMENUTYPE_Command != mle->llist_EntryType) && + Count < MaxCount && + menuType < MENUENTRY_SubItem; + + d1(kprintf("%s/%s/%ld: menuType=%lu EntryCount=%lu MaxCount=%lu\n", \ + __FILE__, __FUNC__, __LINE__, menuType, Count, MaxCount)); + + MayAddNewItem = ((SCAMENUTYPE_MainMenu != mle->llist_EntryType) || (mle->llist_Flags & LLISTFLGF_PopupMenu)) && + Count < MaxCount && + (!(mle->llist_Flags & LLISTFLGF_MayNotHaveChildren) || (mle->llist_Flags & LLISTFLGF_PopupMenu)); + + MayAddCommand = (mle->llist_name && strlen(mle->llist_name) > 0) && + ((SCAMENUTYPE_MenuItem == mle->llist_EntryType) + || (SCAMENUTYPE_Command == mle->llist_EntryType)); + + MayChangeName = (SCAMENUTYPE_Command != mle->llist_EntryType) + && (SCAMENUTYPE_MainMenu != mle->llist_EntryType) + && !(mle->llist_Flags & LLISTFLGF_NameNotSetable); + + MayDelete = !(mle->llist_Flags & LLISTFLGF_NotRemovable); + + MayHaveHotkey = (strlen(mle->llist_name) > 0) + && SCAMENUTYPE_MenuItem == mle->llist_EntryType; + + MayHaveImage = (mle->llist_name && strlen(mle->llist_name) > 0) && + IsPopupMenu(inst, TreeNode) && + (SCAMENUTYPE_Menu == mle->llist_EntryType + || SCAMENUTYPE_MenuItem == mle->llist_EntryType); + + if (SCAMENUTYPE_Command == mle->llist_EntryType) + { + TreeNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, TreeNode, MUIV_NListtree_GetEntry_Position_Parent, 0); + } + + // Cannot cut or copy entire main/tool/popup menus + if ((SCAMENUTYPE_MainMenu == mle->llist_EntryType) + || (SCAMENUTYPE_ToolsMenu == mle->llist_EntryType)) + { + set(inst->mpb_Objects[OBJNDX_Menu_Copy], MUIA_Menuitem_Enabled, FALSE); + set(inst->mpb_Objects[OBJNDX_Menu_Cut], MUIA_Menuitem_Enabled, FALSE); + } + else + { + set(inst->mpb_Objects[OBJNDX_Menu_Copy], MUIA_Menuitem_Enabled, TRUE); + set(inst->mpb_Objects[OBJNDX_Menu_Cut], MUIA_Menuitem_Enabled, TRUE); + } + + d1(kprintf("%s/%s/%ld: tn_Name=%08lx\n", __FILE__, __FUNC__, __LINE__, TreeNode->tn_Name)); + + set(inst->mpb_Objects[OBJNDX_NameString], MUIA_String_Contents, (ULONG) TreeNode->tn_Name); + set(inst->mpb_Objects[OBJNDX_StringHotkey], MUIA_String_Contents, (ULONG) mle->llist_HotKey); + set(inst->mpb_Objects[OBJNDX_PopAsl_UnselectedImage], MUIA_String_Contents, (ULONG) mle->llist_UnselectedIconName); + set(inst->mpb_Objects[OBJNDX_PopAsl_SelectedImage], MUIA_String_Contents, (ULONG) mle->llist_SelectedIconName); + set(inst->mpb_Objects[OBJNDX_DtImage_UnselectedImage], MUIA_ScaDtpic_Name, (ULONG) mle->llist_UnselectedIconName); + set(inst->mpb_Objects[OBJNDX_DtImage_SelectedImage], MUIA_ScaDtpic_Name, (ULONG) mle->llist_SelectedIconName); + + set(inst->mpb_Objects[OBJNDX_DelButton], MUIA_Disabled, !MayDelete); + set(inst->mpb_Objects[OBJNDX_NameString], MUIA_Disabled, !MayChangeName); + set(inst->mpb_Objects[OBJNDX_NewItemButton], MUIA_Disabled, !MayAddNewItem); + set(inst->mpb_Objects[OBJNDX_NewCommandButton], MUIA_Disabled, !MayAddCommand); + set(inst->mpb_Objects[OBJNDX_NewMenuButton], MUIA_Disabled, !MayAddNewMenu); + set(inst->mpb_Objects[OBJNDX_PopAsl_UnselectedImage], MUIA_Disabled, !MayHaveImage); + set(inst->mpb_Objects[OBJNDX_PopAsl_SelectedImage], MUIA_Disabled, !MayHaveImage); + + set(inst->mpb_Objects[OBJNDX_Menu_CollapseSelected], MUIA_Menuitem_Enabled, TRUE); + set(inst->mpb_Objects[OBJNDX_Menu_ExpandSelected], MUIA_Menuitem_Enabled, TRUE); + + set(inst->mpb_Objects[OBJNDX_StringHotkey], MUIA_Disabled, !MayHaveHotkey); + set(inst->mpb_Objects[OBJNDX_Group_String], MUIA_Disabled, (SCAMENUTYPE_Command != mle->llist_EntryType)); + set(inst->mpb_Objects[OBJNDX_Group_CmdProperties], MUIA_Disabled, (SCAMENUTYPE_Command != mle->llist_EntryType)); + + tnShadow = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_ListTreeClipboard], + MUIM_NListtree_GetEntry, + MUIV_NListtree_Insert_ListNode_Root, + MUIV_NListtree_GetEntry_Position_Head, + 0); + + if (tnShadow) + { + if (MayPasteBelow(inst, TreeNode, tnShadow)) + { + set(inst->mpb_Objects[OBJNDX_Menu_Paste], MUIA_Menuitem_Enabled, TRUE); + } + else if (MayPasteOnto(inst, TreeNode, tnShadow)) + { + set(inst->mpb_Objects[OBJNDX_Menu_Paste], MUIA_Menuitem_Enabled, TRUE); + } + else + { + set(inst->mpb_Objects[OBJNDX_Menu_Paste], MUIA_Menuitem_Enabled, FALSE); + } + } + else + { + set(inst->mpb_Objects[OBJNDX_Menu_Paste], MUIA_Menuitem_Enabled, FALSE); + } + + if (SCAMENUTYPE_Command == mle->llist_EntryType) + { + SwitchPopButton(inst, mle->llist_CommandType); + + set(inst->mpb_Objects[OBJNDX_StringCmd], MUIA_String_Contents, (ULONG) mle->llist_name); + set(inst->mpb_Objects[OBJNDX_StringStack], MUIA_String_Integer, (ULONG) mle->llist_Stack); + set(inst->mpb_Objects[OBJNDX_SliderPriority], MUIA_Numeric_Value, (LONG) mle->llist_Priority); + set(inst->mpb_Objects[OBJNDX_CycleGad], MUIA_Cycle_Active, (ULONG) mle->llist_CommandType); + + } + else + { + set(inst->mpb_Objects[OBJNDX_StringCmd], MUIA_String_Contents, (ULONG) ""); + } + + EnableCommandArgumentGadgets(inst, mle); + } + } + else + { + set(inst->mpb_Objects[OBJNDX_Menu_Copy], MUIA_Menuitem_Enabled, FALSE); + set(inst->mpb_Objects[OBJNDX_Menu_Cut], MUIA_Menuitem_Enabled, FALSE); + set(inst->mpb_Objects[OBJNDX_Menu_CollapseSelected], MUIA_Menuitem_Enabled, FALSE); + set(inst->mpb_Objects[OBJNDX_Menu_ExpandSelected], MUIA_Menuitem_Enabled, FALSE); + + set(inst->mpb_Objects[OBJNDX_NameString], MUIA_Disabled, TRUE); + set(inst->mpb_Objects[OBJNDX_StringHotkey], MUIA_Disabled, TRUE); + set(inst->mpb_Objects[OBJNDX_DelButton], MUIA_Disabled, TRUE); + set(inst->mpb_Objects[OBJNDX_Group_String], MUIA_Disabled, TRUE); + set(inst->mpb_Objects[OBJNDX_Group_CmdProperties], MUIA_Disabled, TRUE); + set(inst->mpb_Objects[OBJNDX_PopAsl_UnselectedImage], MUIA_Disabled, TRUE); + set(inst->mpb_Objects[OBJNDX_PopAsl_SelectedImage], MUIA_Disabled, TRUE); +#if 0 + set(inst->mpb_Objects[OBJNDX_Menu_Paste], MUIA_Menuitem_Enabled, FALSE); +#endif + } + + inst->mpb_QuietFlag = FALSE; + + return 0; +} + +static SAVEDS(APTR) INTERRUPT PopButtonHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + struct MenuListEntry *mle; + struct FileRequester *Req; + struct MUI_NListtree_TreeNode *TreeNode; + ULONG CommandType = 0; + + TreeNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, 0); + if (NULL == TreeNode) + return 0; + + get(inst->mpb_Objects[OBJNDX_CycleGad], MUIA_Cycle_Active, &CommandType); + + mle = (struct MenuListEntry *) TreeNode->tn_User; + Req = MUI_AllocAslRequest(ASL_FileRequest, NULL); + + if (Req) + { + char FileName[512]; + struct Window *win = NULL; + BOOL Result; + STRPTR p, path = NULL; + BOOL drawersOnly = FALSE; + ULONG AslTitle = MSGID_IMPORTNAME; + + get(inst->mpb_Objects[OBJNDX_StringCmd], MUIA_String_Contents, &path); + get(inst->mpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Window, &win); + + switch (CommandType) + { + case SCAMENUCMDTYPE_AmigaDOS: + AslTitle = MSGID_POPUP_ASLTITLE_AMIGADOS; + break; + case SCAMENUCMDTYPE_Workbench: + AslTitle = MSGID_POPUP_ASLTITLE_WORKBENCH; + break; + case SCAMENUCMDTYPE_IconWindow: + drawersOnly = TRUE; + AslTitle = MSGID_POPUP_ASLTITLE_ICONWINDOW; + break; + case SCAMENUCMDTYPE_ARexx: + AslTitle = MSGID_POPUP_ASLTITLE_AREXX; + break; + case SCAMENUCMDTYPE_Plugin: + AslTitle = MSGID_POPUP_ASLTITLE_MENUPLUGIN; + if (0 == strlen(path)) + strcpy(path, "scalos:Plugins/Menu/"); + break; + default: + break; + } + + if (drawersOnly) + strcpy(FileName, ""); + else + stccpy(FileName, FilePart(path), sizeof(FileName)); + + p = PathPart(path); + *p = '\0'; + + d1(kprintf("%s/%s//%ld: InitialFile=<%s> InitialDrawer=<%s>\n", __FILE__, __FUNC__, __LINE__, FileName, path)); + d1(kprintf("%s/%s//%ld: DrawersOnly=%ld\n", __FILE__, __FUNC__, __LINE__, drawersOnly)); + + Result = MUI_AslRequestTags(Req, + ASLFR_TitleText, GetLocString(MSGID_MENU_PROJECT_SAVEAS), + ASLFR_Window, win, + ASLFR_SleepWindow, TRUE, + ASLFR_TitleText, GetLocString(AslTitle), + ASLFR_Flags1, FRF_DOPATTERNS, + ASLFR_InitialFile, FileName, + ASLFR_InitialDrawer, path, + ASLFR_DrawersOnly, drawersOnly, + TAG_END); + + if (Result) + { + struct DiskObject *icon; + + SetChangedFlag(inst, TRUE); + + d1(kprintf("%s/%s//%ld: fr_Drawer=<%s> fr_File=<%s>\n", __FILE__, __FUNC__, __LINE__, Req->fr_Drawer, Req->fr_File)); + + stccpy(FileName, Req->fr_Drawer, sizeof(FileName)); + + if (!drawersOnly) + AddPart(FileName, Req->fr_File, sizeof(FileName)); + + d1(kprintf("%s/%s//%ld: FileName=<%s>\n", __FILE__, __FUNC__, __LINE__, FileName)); + + set(inst->mpb_Objects[OBJNDX_StringCmd], MUIA_String_Contents, (ULONG) FileName); + stccpy(mle->llist_name, FileName, sizeof(mle->llist_name)); + + icon = GetDiskObject(FileName); + if (icon) + { + STRPTR ToolString; + ULONG ToolPri = 0; + + get(inst->mpb_Objects[OBJNDX_SliderPriority], MUIA_Numeric_Value, &ToolPri); + set(inst->mpb_Objects[OBJNDX_StringStack], MUIA_String_Integer, icon->do_StackSize); + + ToolString = FindToolType(icon->do_ToolTypes, "TOOLPRI"); + if (ToolString) + { + long long1; + sscanf(ToolString, "%ld", &long1); + ToolPri = long1; + } + + set(inst->mpb_Objects[OBJNDX_SliderPriority], MUIA_Numeric_Value, (LONG) ToolPri); + + FreeDiskObject(icon); + } + + DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], MUIM_NList_Redraw, MUIV_NList_Redraw_Active); + } + } + + return 0; +} + + +static SAVEDS(APTR) INTERRUPT AddMenuHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + struct MUI_NListtree_TreeNode *ParentNode; + struct MUI_NListtree_TreeNode *PrevNode; + struct MenuInsertEntry mie; + struct ScalosMenuTree mTree; + + memset(&mTree, 0, sizeof(mTree)); + mTree.mtre_type = SCAMENUTYPE_Menu; + mie.mie_TreeEntry = &mTree; + mie.mie_MenuFlags = 0; + + SetChangedFlag(inst, TRUE); + + ParentNode = GetParentNodeForMenu(inst, &PrevNode); + + DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, GetLocString(MSGID_NEW_MENU), + &mie, + ParentNode, PrevNode, MUIV_NListtree_Insert_Flag_Active | TNF_OPEN | TNF_LIST); + + // try to activate menu name string gadget + set(inst->mpb_Objects[OBJNDX_WIN_Main], MUIA_Window_ActiveObject, + (ULONG) inst->mpb_Objects[OBJNDX_NameString]); + + return 0; +} + + +static SAVEDS(APTR) INTERRUPT AddCommandHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + struct MUI_NListtree_TreeNode *ParentNode; + struct MUI_NListtree_TreeNode *TreeNode; + + SetChangedFlag(inst, TRUE); + + TreeNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, 0, MUIV_NListtree_GetEntry_Position_Active, 0); + + if (TreeNode) + { + struct MenuListEntry *mle = (struct MenuListEntry *) TreeNode->tn_User; + struct MenuInsertEntry mie; + struct ScalosMenuTree mTree; + + memset(&mTree, 0, sizeof(mTree)); + mTree.mtre_type = SCAMENUTYPE_Command; + mie.mie_TreeEntry = &mTree; + mie.mie_MenuFlags = 0; + + switch (mle->llist_EntryType) + { + case SCAMENUTYPE_MainMenu: + case SCAMENUTYPE_Menu: + case SCAMENUTYPE_ToolsMenu: + break; + + case SCAMENUTYPE_MenuItem: + DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, "", + &mie, + TreeNode, MUIV_NListtree_Insert_PrevNode_Tail, + MUIV_NListtree_Insert_Flag_Active); + + // try to activate command name string gadget + set(inst->mpb_Objects[OBJNDX_WIN_Main], MUIA_Window_ActiveObject, + (ULONG) inst->mpb_Objects[OBJNDX_StringCmd]); + break; + + case SCAMENUTYPE_Command: + ParentNode = TreeNode; + + TreeNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, TreeNode, + MUIV_NListtree_GetEntry_Position_Parent, 0); + + DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, "", + &mie, + TreeNode, ParentNode, + MUIV_NListtree_Insert_Flag_Active); + + // try to activate command name string gadget + set(inst->mpb_Objects[OBJNDX_WIN_Main], MUIA_Window_ActiveObject, + (ULONG) inst->mpb_Objects[OBJNDX_StringCmd]); + break; + } + } + + return 0; +} + + +static SAVEDS(APTR) INTERRUPT AddMenuItemHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + struct MUI_NListtree_TreeNode *ParentNode; + struct MUI_NListtree_TreeNode *PrevNode; + + SetChangedFlag(inst, TRUE); + + ParentNode = GetParentNodeForMenuItem(inst, &PrevNode); + + if (ParentNode) + { + struct MUI_NListtree_TreeNode *newNode; + struct MenuInsertEntry mie; + struct ScalosMenuTree mTree; + + memset(&mTree, 0, sizeof(mTree)); + mTree.mtre_type = SCAMENUTYPE_MenuItem; + mie.mie_TreeEntry = &mTree; + mie.mie_MenuFlags = 0; + + newNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, GetLocString(MSGID_NEW_ITEM), + &mie, + ParentNode, PrevNode, + MUIV_NListtree_Insert_Flag_Active | TNF_OPEN | TNF_LIST); + + DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], MUIM_NListtree_GetNr, + newNode, MUIV_NListtree_GetNr_Flag_CountLevel); + + // try to activate menu name string gadget + set(inst->mpb_Objects[OBJNDX_WIN_Main], MUIA_Window_ActiveObject, + (ULONG) inst->mpb_Objects[OBJNDX_NameString]); + + d1(kprintf("%s/%s/%ld: Node Count=%ld\n", __FILE__, __FUNC__, __LINE__, Count)); + } + + return 0; +} + + +static SAVEDS(APTR) INTERRUPT RemoveEntryHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + + DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], MUIM_NListtree_Remove, MUIV_NListtree_Remove_ListNode_Active, + MUIV_NListtree_Remove_TreeNode_Active, 0); + + SetChangedFlag(inst, TRUE); + + return 0; +} + +//---------------------------------------------------------------------------- + +static LONG ReadPrefsFile(struct MenuPrefsInst *inst, CONST_STRPTR Filename, BOOL Quiet) +{ + LONG Result; + struct IFFHandle *iff; + BOOL iffOpened = FALSE; + struct ScalosMenuChunk *menuChunk = NULL; + + set(inst->mpb_Objects[OBJNDX_MainListView], MUIA_NListtree_Quiet, TRUE); + + d1(kprintf("%s/%s//%ld: LocaleBase=%08lx IFFParseBase=%08lx\n", __FILE__, __FUNC__, __LINE__, LocaleBase, IFFParseBase)); + + do { + iff = AllocIFF(); + if (NULL == iff) + { + Result = IoErr(); + break; + } + + InitIFFasDOS(iff); + + iff->iff_Stream = (IPTR)Open(Filename, MODE_OLDFILE); + if (0 == iff->iff_Stream) + { + Result = IoErr(); + break; + } + + Result = OpenIFF(iff, IFFF_READ); + if (RETURN_OK != Result) + break; + + iffOpened = TRUE; + + Result = StopChunks(iff, StopChunkList, 2); + if (RETURN_OK != Result) + break; + + while (1) + { + struct ContextNode *cn; + + Result = ParseIFF(iff, IFFPARSE_SCAN); + d1(kprintf("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + if (RETURN_OK != Result) + break; + + cn = CurrentChunk(iff); + + d1(kprintf("%s/%s//%ld: cn=%08lx\n", __FILE__, __FUNC__, __LINE__, cn)); + if (NULL == cn) + break; + + if (ID_MENU == cn->cn_ID) + { + LONG Actual; + + menuChunk = malloc(cn->cn_Size); + + d1(kprintf("%s/%s//%ld: menuChunk=%08lx\n", __FILE__, __FUNC__, __LINE__, menuChunk)); + if (NULL == menuChunk) + break; + + Actual = ReadChunkBytes(iff, menuChunk, cn->cn_Size); + if (Actual != cn->cn_Size) + break; + + menuChunk->smch_MenuID = SCA_BE2WORD(menuChunk->smch_MenuID); + menuChunk->smch_Entries = SCA_BE2WORD(menuChunk->smch_Entries); + + d1(kprintf("%s/%s/%ld: MenuID=%ld Entries=%ld\n", \ + __FILE__, __FUNC__, __LINE__, menuChunk->smch_MenuID, menuChunk->smch_Entries)); + + AddAddresses(menuChunk->smch_Menu, (UBYTE *) menuChunk); + + switch (menuChunk->smch_MenuID) + { + case SCMID_MainMenu: + GenerateMenuList(inst, menuChunk->smch_Menu, + inst->mpb_MainMenuNode.mpn_Listtree, + inst->mpb_MainMenuNode.mpn_ListNode); + break; + case SCMID_Popup_Disk: + GenerateMenuList(inst, menuChunk->smch_Menu, + inst->mpb_PopMenuNode[POPMENUINDEX_Disk].mpn_Listtree, + inst->mpb_PopMenuNode[POPMENUINDEX_Disk].mpn_ListNode); + break; + case SCMID_Popup_Drawer: + GenerateMenuList(inst, menuChunk->smch_Menu, + inst->mpb_PopMenuNode[POPMENUINDEX_Drawer].mpn_Listtree, + inst->mpb_PopMenuNode[POPMENUINDEX_Drawer].mpn_ListNode); + break; + case SCMID_Popup_Tool: + GenerateMenuList(inst, menuChunk->smch_Menu, + inst->mpb_PopMenuNode[POPMENUINDEX_ToolProject].mpn_Listtree, + inst->mpb_PopMenuNode[POPMENUINDEX_ToolProject].mpn_ListNode); + break; + case SCMID_Popup_Trashcan: + GenerateMenuList(inst, menuChunk->smch_Menu, + inst->mpb_PopMenuNode[POPMENUINDEX_Trashcan].mpn_Listtree, + inst->mpb_PopMenuNode[POPMENUINDEX_Trashcan].mpn_ListNode); + break; + case SCMID_Popup_Window: + GenerateMenuList(inst, menuChunk->smch_Menu, + inst->mpb_PopMenuNode[POPMENUINDEX_Window].mpn_Listtree, + inst->mpb_PopMenuNode[POPMENUINDEX_Window].mpn_ListNode); + break; + case SCMID_Popup_AppIcon: + GenerateMenuList(inst, menuChunk->smch_Menu, + inst->mpb_PopMenuNode[POPMENUINDEX_AppIcon].mpn_Listtree, + inst->mpb_PopMenuNode[POPMENUINDEX_AppIcon].mpn_ListNode); + break; + case SCMID_Popup_Desktop: + GenerateMenuList(inst, menuChunk->smch_Menu, + inst->mpb_PopMenuNode[POPMENUINDEX_Desktop].mpn_Listtree, + inst->mpb_PopMenuNode[POPMENUINDEX_Desktop].mpn_ListNode); + break; + } + + free(menuChunk); + menuChunk = NULL; + } + } + + d1(kprintf("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + if (IFFERR_EOF == Result) + Result = RETURN_OK; + } while (0); + + set(inst->mpb_Objects[OBJNDX_MainListView], MUIA_NListtree_Quiet, FALSE); + + if (menuChunk) + free(menuChunk); + + if (iff) + { + if (iffOpened) + CloseIFF(iff); + + if (iff->iff_Stream) + Close((BPTR)iff->iff_Stream); + + FreeIFF(iff); + } + + if (RETURN_OK != Result && !Quiet) + { + char Buffer[120]; + + Fault(Result, "", Buffer, sizeof(Buffer) - 1); + + // MUI_RequestA() + MUI_Request(inst->mpb_Objects[OBJNDX_APP_Main], inst->mpb_Objects[OBJNDX_WIN_Main], 0, NULL, + GetLocString(MSGID_ABOUTREQOK), + GetLocString(MSGID_REQTITLE_READERROR), + Filename, + Buffer); + } + +// DoMethod(ScalosPenList, MUIM_NList_Redraw, MUIV_NList_Redraw_All); + + d1(kprintf("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + + return Result; +} + + +static LONG WritePrefsFile(struct MenuPrefsInst *inst, CONST_STRPTR Filename) +{ + struct IFFHandle *iff; + LONG Result; + BOOL IffOpen = FALSE; + + do { + static const struct PrefHeader prefHeader = { 1, 0, 0L }; + + iff = AllocIFF(); + if (NULL == iff) + { + Result = IoErr(); + break; + } + + InitIFFasDOS(iff); + + iff->iff_Stream = (IPTR)Open(Filename, MODE_NEWFILE); + if (0 == iff->iff_Stream) + { + // ... try to create missing directories here + STRPTR FilenameCopy; + + Result = IoErr(); + d1(kprintf("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + + FilenameCopy = AllocVec(1 + strlen(Filename), MEMF_PUBLIC); + + if (FilenameCopy) + { + STRPTR lp; + + strcpy(FilenameCopy, Filename); + + lp = PathPart(FilenameCopy); + if (lp) + { + BPTR dirLock; + + *lp = '\0'; + dirLock = CreateDir(FilenameCopy); + + if (dirLock) + UnLock(dirLock); + + iff->iff_Stream = (IPTR)Open(Filename, MODE_NEWFILE); + if (0 == iff->iff_Stream) + Result = IoErr(); + else + Result = RETURN_OK; + } + + FreeVec(FilenameCopy); + } + + d1(kprintf("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + if (RETURN_OK != Result) + break; + } + + Result = OpenIFF(iff, IFFF_WRITE); + if (RETURN_OK != Result) + break; + + IffOpen = TRUE; + + Result = PushChunk(iff, ID_PREF, ID_FORM, IFFSIZE_UNKNOWN); + if (RETURN_OK != Result) + break; + + Result = PushChunk(iff, 0, ID_PRHD, IFFSIZE_UNKNOWN); + if (RETURN_OK != Result) + break; + + if (WriteChunkBytes(iff, (APTR) &prefHeader, sizeof(prefHeader)) < 0) + { + Result = IoErr(); + break; + } + + Result = PopChunk(iff); + if (RETURN_OK != Result) + break; + + Result = SaveMenuNode(inst, + iff, &inst->mpb_MainMenuNode, SCMID_MainMenu); + if (RETURN_OK != Result) + break; + + Result = SaveMenuNode(inst, + iff, &inst->mpb_PopMenuNode[POPMENUINDEX_Disk], SCMID_Popup_Disk); + if (RETURN_OK != Result) + break; + + Result = SaveMenuNode(inst, + iff, &inst->mpb_PopMenuNode[POPMENUINDEX_Drawer], SCMID_Popup_Drawer); + if (RETURN_OK != Result) + break; + + Result = SaveMenuNode(inst, + iff, &inst->mpb_PopMenuNode[POPMENUINDEX_ToolProject], SCMID_Popup_Tool); + if (RETURN_OK != Result) + break; + + Result = SaveMenuNode(inst, + iff, &inst->mpb_PopMenuNode[POPMENUINDEX_Trashcan], SCMID_Popup_Trashcan); + if (RETURN_OK != Result) + break; + + Result = SaveMenuNode(inst, + iff, &inst->mpb_PopMenuNode[POPMENUINDEX_Window], SCMID_Popup_Window); + if (RETURN_OK != Result) + break; + + Result = SaveMenuNode(inst, + iff, &inst->mpb_PopMenuNode[POPMENUINDEX_AppIcon], SCMID_Popup_AppIcon); + if (RETURN_OK != Result) + break; + + Result = SaveMenuNode(inst, + iff, &inst->mpb_PopMenuNode[POPMENUINDEX_Desktop], SCMID_Popup_Desktop); + if (RETURN_OK != Result) + break; + + Result = PopChunk(iff); + if (RETURN_OK != Result) + break; + + } while (0); + + if (iff) + { + if (IffOpen) + CloseIFF(iff); + + if (iff->iff_Stream) + { + Close((BPTR)iff->iff_Stream); + iff->iff_Stream = 0; + } + + FreeIFF(iff); + } + + if (RETURN_OK == Result) + { + if (inst->mpb_fCreateIcons) + SaveIcon(inst, Filename); + } + else + { + char Buffer[120]; + + Fault(Result, "", Buffer, sizeof(Buffer) - 1); + + // MUI_RequestA() + MUI_Request(inst->mpb_Objects[OBJNDX_APP_Main], inst->mpb_Objects[OBJNDX_WIN_Main], 0, NULL, + GetLocString(MSGID_ABOUTREQOK), + GetLocString(MSGID_REQTITLE_SAVEERROR), + Filename, + Buffer); + } + + return Result; +} + + +static LONG SaveMenuNode(struct MenuPrefsInst *inst, struct IFFHandle *iff, + const struct MenuPrefsPopMenuNode *TreeNode, enum ScalosMenuChunkId ChunkID) +{ + LONG Result; + struct ScalosMenuChunk *mChunk = NULL; + + do { + const struct MUI_NListtree_TreeNode *SubNode; + size_t StringSpaceSize = 0; + STRPTR StringSpace; + UWORD nodeCount; + size_t Length; + struct ScalosMenuTree *MenuTreeSpace; + + SubNode = (const struct MUI_NListtree_TreeNode *) DoMethod(TreeNode->mpn_Listtree, + MUIM_NListtree_GetEntry, TreeNode->mpn_ListNode, + MUIV_NListtree_GetEntry_Position_Head, + 0); + if(NULL == SubNode) + { + Result = RETURN_OK; + break; + } + + nodeCount = CountMenuEntries(inst, TreeNode->mpn_Listtree, SubNode, &StringSpaceSize); + + Length = sizeof(struct ScalosMenuChunk) + (nodeCount * sizeof(struct ScalosMenuChunk)) + StringSpaceSize; + + mChunk = calloc(1, Length); + if (NULL == mChunk) + { + Result = ERROR_NO_FREE_STORE; + break; + } + + d1(kprintf("%s/%s/%ld: mChunk=%08lx Length=%lu\n", __FILE__, __FUNC__, __LINE__, mChunk, Length)); + + StringSpace = (STRPTR) &mChunk->smch_Menu[nodeCount]; + + mChunk->smch_MenuID = SCA_WORD2BE(ChunkID); + mChunk->smch_Entries = SCA_WORD2BE(nodeCount); + + d1(kprintf("%s/%s/%ld: ChunkID=%ld Count=%ld StringSpaceSize=%lu\n", \ + __FILE__, __FUNC__, __LINE__, mChunk->smch_MenuID, mChunk->smch_Entries, StringSpaceSize)); + + MenuTreeSpace = mChunk->smch_Menu; + + Result = BuildMenuTree(inst, TreeNode->mpn_Listtree, SubNode, &MenuTreeSpace, &StringSpace, NULL); + if (RETURN_OK != Result) + break; + + RemoveAddresses(mChunk->smch_Menu, (UBYTE *) mChunk); + + Result = PushChunk(iff, 0, ID_MENU, IFFSIZE_UNKNOWN); + if (RETURN_OK != Result) + break; + + if (Length != WriteChunkBytes(iff, (APTR) mChunk, Length)) + { + Result = IoErr(); + break; + } + + Result = PopChunk(iff); + if (RETURN_OK != Result) + break; + } while (0); + + if (mChunk) + free(mChunk); + + return Result; +} + + +static UWORD CountMenuEntries(struct MenuPrefsInst *inst, Object *ListTree, + const struct MUI_NListtree_TreeNode *TreeNode, size_t *StringSpace) +{ + UWORD Count = 0; + + while (TreeNode) + { + const struct MUI_NListtree_TreeNode *SubNode; + const struct MenuListEntry *mle = (struct MenuListEntry *) TreeNode->tn_User; + + d1(kprintf("%s/%s/%ld: TreeNode=%08lx <%s>\n", \ + __FILE__, __FUNC__, __LINE__, TreeNode, TreeNode->tn_Name)); + + Count++; + + *StringSpace += 1 + strlen(mle->llist_name); + + if (strlen(mle->llist_UnselectedIconName) > 0 + || strlen(mle->llist_SelectedIconName) > 0) + { + *StringSpace += 1 + strlen(mle->llist_UnselectedIconName) + + 1 + strlen(mle->llist_SelectedIconName); + } + + SubNode = (const struct MUI_NListtree_TreeNode *) DoMethod(ListTree, + MUIM_NListtree_GetEntry, TreeNode, MUIV_NListtree_GetEntry_Position_Head, + 0); + + if (SubNode) + Count += CountMenuEntries(inst, ListTree, SubNode, StringSpace); + + TreeNode = (const struct MUI_NListtree_TreeNode *) DoMethod(ListTree, + MUIM_NListtree_GetEntry, TreeNode, MUIV_NListtree_GetEntry_Position_Next, + MUIV_NListtree_GetEntry_Flag_SameLevel); + } + + return Count; +} + + +static LONG BuildMenuTree(struct MenuPrefsInst *inst, Object *ListTree, + const struct MUI_NListtree_TreeNode *TreeNode, + struct ScalosMenuTree **MenuSpace, STRPTR *StringSpace, + struct ScalosMenuTree **Parent) +{ + LONG Result = RETURN_OK; + + while (TreeNode) + { + struct ScalosMenuTree *mTree = *(struct ScalosMenuTree **) MenuSpace; + const struct MUI_NListtree_TreeNode *SubNode; + const struct MenuListEntry *mle = (struct MenuListEntry *) TreeNode->tn_User; + STRPTR MenuName; + + d1(KPrintF("%s/%s/%ld: TreeNode=%08lx <%s> mTree=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, TreeNode, TreeNode->tn_Name ? TreeNode->tn_Name : (STRPTR) "===BAR===", mTree)); + + if (Parent) + *Parent = mTree; + + mTree->mtre_Next = NULL; + mTree->mtre_tree = NULL; + + mTree->mtre_type = mle->llist_EntryType; + mTree->mtre_flags = mle->llist_Flags; + + if (strlen(mle->llist_name) > 0) + { + MenuName = AddMenuString(mle->llist_name, StringSpace); + } + else + { + MenuName = NULL; + } + + *MenuSpace = mTree + 1; + + if (SCAMENUTYPE_Command == mTree->mtre_type) + { + mTree->MenuCombo.MenuCommand.mcom_flags = mle->llist_CommandFlags; + mTree->MenuCombo.MenuCommand.mcom_type = mle->llist_CommandType; + mTree->MenuCombo.MenuCommand.mcom_stack = mle->llist_Stack; + mTree->MenuCombo.MenuCommand.mcom_pri = mle->llist_Priority; + mTree->MenuCombo.MenuCommand.mcom_name = MenuName; + } + else + { + if (strlen(mle->llist_UnselectedIconName) > 0 + || strlen(mle->llist_SelectedIconName) > 0) + { + STRPTR IconName; + + IconName = AddMenuString(mle->llist_UnselectedIconName, StringSpace); + AddMenuString(mle->llist_SelectedIconName, StringSpace); + mTree->MenuCombo.MenuTree.mtre_iconnames = IconName; + + mTree->mtre_flags |= MTREFLGF_IconNames; + } + else + { + mTree->MenuCombo.MenuTree.mtre_iconnames = NULL; + mTree->mtre_flags &= ~MTREFLGF_IconNames; + } + + d1(KPrintF("%s/%s/%ld: mtre_name=<%s> mtre_flags=%02lx mtre_iconnames=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, mTree->MenuCombo.MenuTree.mtre_name, \ + mTree->mtre_flags, mTree->MenuCombo.MenuTree.mtre_iconnames)); + + stccpy(mTree->MenuCombo.MenuTree.mtre_hotkey, mle->llist_HotKey, + sizeof(mTree->MenuCombo.MenuTree.mtre_hotkey)); + mTree->MenuCombo.MenuTree.mtre_name = MenuName; + } + + SubNode = (const struct MUI_NListtree_TreeNode *) DoMethod(ListTree, + MUIM_NListtree_GetEntry, TreeNode, MUIV_NListtree_GetEntry_Position_Head, + 0); + + if (SubNode) + { + Result = BuildMenuTree(inst, ListTree, SubNode, MenuSpace, StringSpace, &mTree->mtre_tree); + if (RETURN_OK != Result) + break; + } + + TreeNode = (const struct MUI_NListtree_TreeNode *) DoMethod(ListTree, + MUIM_NListtree_GetEntry, TreeNode, MUIV_NListtree_GetEntry_Position_Next, + MUIV_NListtree_GetEntry_Flag_SameLevel); + + if (TreeNode) + Parent = &mTree->mtre_Next; + } + + return Result; +} + + +static STRPTR AddMenuString(CONST_STRPTR MenuString, STRPTR *StringSpace) +{ + STRPTR MenuName = *StringSpace; + + strcpy(MenuName, MenuString); + *StringSpace = (APTR) (MenuName + 1 + strlen(MenuName)); + + return MenuName; +} + + +static void RemoveAddresses(struct ScalosMenuTree *MenuTree, const UBYTE *BaseAddr) +{ + while (MenuTree) + { + struct ScalosMenuTree *MenuTreeNext = MenuTree->mtre_Next; + + if (SCAMENUTYPE_Command == MenuTree->mtre_type) + { + if (MenuTree->MenuCombo.MenuCommand.mcom_name) + { + MenuTree->MenuCombo.MenuCommand.mcom_name -= (ULONG) BaseAddr; + MenuTree->MenuCombo.MenuCommand.mcom_name = (APTR) SCA_LONG2BE(MenuTree->MenuCombo.MenuCommand.mcom_name); + } + MenuTree->MenuCombo.MenuCommand.mcom_stack = SCA_LONG2BE(MenuTree->MenuCombo.MenuCommand.mcom_stack); + } + else + { + if (MenuTree->MenuCombo.MenuTree.mtre_name) + { + MenuTree->MenuCombo.MenuTree.mtre_name -= (ULONG) BaseAddr; + MenuTree->MenuCombo.MenuTree.mtre_name = (APTR) SCA_LONG2BE(MenuTree->MenuCombo.MenuTree.mtre_name); + } + + if ((MenuTree->mtre_flags & MTREFLGF_IconNames) && MenuTree->MenuCombo.MenuTree.mtre_iconnames) + { + MenuTree->MenuCombo.MenuTree.mtre_iconnames -= (ULONG) BaseAddr; + MenuTree->MenuCombo.MenuTree.mtre_iconnames = (APTR) SCA_LONG2BE(MenuTree->MenuCombo.MenuTree.mtre_iconnames); + } + + d1(KPrintF("%s/%s/%ld: mtre_name=<%s> mtre_flags=%02lx mtre_iconnames=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, MenuTree->MenuCombo.MenuTree.mtre_name, \ + MenuTree->mtre_flags, MenuTree->MenuCombo.MenuTree.mtre_iconnames)); + } + if (MenuTree->mtre_tree) + { + RemoveAddresses(MenuTree->mtre_tree, BaseAddr); + MenuTree->mtre_tree = (struct ScalosMenuTree *) (((UBYTE *) MenuTree->mtre_tree) - (ULONG) BaseAddr); + MenuTree->mtre_tree = (APTR)SCA_LONG2BE(MenuTree->mtre_tree); + } + if (MenuTree->mtre_Next) + { + MenuTree->mtre_Next = (struct ScalosMenuTree *) (((UBYTE *) MenuTree->mtre_Next) - (ULONG) BaseAddr); + MenuTree->mtre_Next = (APTR)SCA_LONG2BE(MenuTree->mtre_Next); + } + + MenuTree = MenuTreeNext; + } +} + + +static LONG SaveIcon(struct MenuPrefsInst *inst, CONST_STRPTR IconName) +{ + struct DiskObject *icon, *allocIcon; + + static UBYTE ImageData[] = + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0x80, 0x00, 0x40, 0x00, 0x00, 0x00, 0x18, 0x00, 0x60, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x20, 0xFC, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x41, 0x02, 0x08, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x40, 0x82, 0x08, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x40, 0x82, 0x08, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x21, 0x04, 0x08, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x1E, 0x18, 0x10, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x20, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x02, 0x1C, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x0C, 0x00, + 0x40, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x0C, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, + 0xD5, 0x55, 0x55, 0x55, 0x55, 0x56, 0x00, 0x00, 0xD5, 0x55, 0x50, 0x00, 0x55, 0x55, 0x80, 0x00, + 0xD5, 0x55, 0x47, 0xFF, 0x95, 0x55, 0x60, 0x00, 0xD5, 0x55, 0x5F, 0x03, 0xE5, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x3E, 0x55, 0xF5, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x3F, 0x55, 0xF5, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x3F, 0x55, 0xF5, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x5E, 0x53, 0xF5, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x41, 0x47, 0xE5, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x55, 0x1F, 0xD5, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x55, 0x7F, 0x15, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x54, 0xFC, 0x55, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x55, 0xE1, 0x55, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x54, 0xF5, 0x55, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x55, 0x05, 0x55, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x54, 0xF5, 0x55, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x54, 0xF5, 0x55, 0x55, 0x50, 0x00, 0x35, 0x55, 0x55, 0x05, 0x55, 0x55, 0x50, 0x00, + 0x0D, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, 0x00, 0x03, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + static struct Image NormalImage = + { + 0, 0, 54, 23, + 2, + (UWORD *)ImageData, + 3, 0, + NULL + }; + + static STRPTR defToolTypes[] = + { + "ACTION=USE", + NULL + }; + + static struct DiskObject DefaultIcon = + { + WB_DISKMAGIC, WB_DISKVERSION, + + { + NULL, + 0, 0, 54, 24, + GFLG_GADGIMAGE | GFLG_GADGHBOX, + GACT_RELVERIFY | GACT_IMMEDIATE, + GTYP_BOOLGADGET, + &NormalImage, NULL, + NULL, + 0, + NULL, + 0, + NULL + }, + + WBPROJECT, + NULL, + defToolTypes, + NO_ICON_POSITION, NO_ICON_POSITION, + NULL, + NULL, + 8192 + }; + + icon = allocIcon = GetDiskObject("ENV:sys/def_ScaMenuPrefs"); + if (NULL == icon) + icon = allocIcon = GetDiskObject("ENV:sys/def_pref"); + if (NULL == icon) + icon = &DefaultIcon; + + if (icon) + { + STRPTR oldDefaultTool = icon->do_DefaultTool; + + icon->do_DefaultTool = (STRPTR) inst->mpb_ProgramName; + + PutDiskObject((STRPTR) IconName, icon); + + icon->do_DefaultTool = oldDefaultTool; + + if (allocIcon) + FreeDiskObject(allocIcon); + } + + return 0; +} + + +static void ClearMenuList(struct MenuPrefsInst *inst) +{ + short n; + + set(inst->mpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Quiet, TRUE); + + DoMethod(inst->mpb_MainMenuNode.mpn_Listtree, MUIM_NListtree_Remove, + inst->mpb_MainMenuNode.mpn_ListNode, MUIV_NListtree_Remove_TreeNode_All, 0); + + for (n=0; nmpb_PopMenuNode); n++) + { + DoMethod(inst->mpb_PopMenuNode[n].mpn_Listtree, MUIM_NListtree_Remove, + inst->mpb_PopMenuNode[n].mpn_ListNode, + MUIV_NListtree_Remove_TreeNode_All, 0); + } + + set(inst->mpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Quiet, FALSE); +} + + +static void AddAddresses(struct ScalosMenuTree *MenuTree, const UBYTE *BaseAddr) +{ + while (MenuTree) + { + if (SCAMENUTYPE_Command == MenuTree->mtre_type) + { + MenuTree->MenuCombo.MenuCommand.mcom_name = (APTR) SCA_BE2LONG(MenuTree->MenuCombo.MenuCommand.mcom_name); + if (MenuTree->MenuCombo.MenuCommand.mcom_name) + MenuTree->MenuCombo.MenuCommand.mcom_name += (ULONG) BaseAddr; + MenuTree->MenuCombo.MenuCommand.mcom_stack = SCA_BE2LONG(MenuTree->MenuCombo.MenuCommand.mcom_stack); + } + else + { + MenuTree->MenuCombo.MenuTree.mtre_name = (APTR) SCA_BE2LONG(MenuTree->MenuCombo.MenuTree.mtre_name); + if (MenuTree->MenuCombo.MenuTree.mtre_name) + MenuTree->MenuCombo.MenuTree.mtre_name += (ULONG) BaseAddr; + + if (MenuTree->mtre_flags & MTREFLGF_IconNames) + { + MenuTree->MenuCombo.MenuTree.mtre_iconnames = (APTR) SCA_BE2LONG(MenuTree->MenuCombo.MenuTree.mtre_iconnames); + if (MenuTree->MenuCombo.MenuTree.mtre_iconnames) + { + MenuTree->MenuCombo.MenuTree.mtre_iconnames += (ULONG) BaseAddr; + } + else + { + MenuTree->MenuCombo.MenuTree.mtre_iconnames = NULL; + } + } + else + { + MenuTree->MenuCombo.MenuTree.mtre_iconnames = NULL; + } + + d1(KPrintF("%s/%s/%ld: mtre_name=<%s> mtre_flags=%02lx mtre_iconnames=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, MenuTree->MenuCombo.MenuTree.mtre_name, \ + MenuTree->mtre_flags, MenuTree->MenuCombo.MenuTree.mtre_iconnames)); + d1(KPrintF("%s/%s/%ld: mtre_iconnames=<%s>\n", \ + __FILE__, __FUNC__, __LINE__, MenuTree->MenuCombo.MenuTree.mtre_iconnames \ + ? MenuTree->MenuCombo.MenuTree.mtre_iconnames : (STRPTR) "")); + } + MenuTree->mtre_tree = (APTR) SCA_BE2LONG(MenuTree->mtre_tree); + if (MenuTree->mtre_tree) + { + MenuTree->mtre_tree = (struct ScalosMenuTree *) (((UBYTE *) MenuTree->mtre_tree) + (ULONG) BaseAddr); + AddAddresses(MenuTree->mtre_tree, BaseAddr); + } + MenuTree->mtre_Next = SCA_BE2LONG(MenuTree->mtre_Next); + if (MenuTree->mtre_Next) + { + MenuTree->mtre_Next = (struct ScalosMenuTree *) (((UBYTE *) MenuTree->mtre_Next) + (ULONG) BaseAddr); + } + MenuTree = MenuTree->mtre_Next; + } +} + + +static void GenerateMenuList(struct MenuPrefsInst *inst, struct ScalosMenuTree *mTree, + Object *ListTree, struct MUI_NListtree_TreeNode *MenuNode) +{ + while (mTree) + { + struct MenuInsertEntry mie; + struct MUI_NListtree_TreeNode *TreeNode; + ULONG MenuType = mTree->mtre_type; + ULONG Flags = 0; + ULONG pos; + + mie.mie_TreeEntry = mTree; + mie.mie_MenuFlags = 0; + + d1(KPrintF("%s/%s/%ld: mTree=%08lx Type=%ld\n", __FILE__, __FUNC__, __LINE__, mTree, MenuType)); + + switch (MenuType) + { + case SCAMENUTYPE_Command: + d1(kprintf("%s/%s/%ld: Command name <%s> ListNode=<%s>\n", \ + __FILE__, __FUNC__, __LINE__, mTree->MenuCombo.MenuCommand.mcom_name, MenuNode->tn_Name)); + + DoMethod(ListTree, + MUIM_NListtree_Insert, "", + &mie, + MenuNode, MUIV_NListtree_Insert_PrevNode_Tail, 0); + break; + + default: + d1(KPrintF("%s/%s/%ld: Menu name <%s> ListNode=<%s>\n", \ + __FILE__, __FUNC__, __LINE__, mTree->MenuCombo.MenuTree.mtre_name, MenuNode->tn_Name)); + + if (SCAMENUTYPE_ToolsMenu == mTree->mtre_type) + mie.mie_MenuFlags |= LLISTFLGF_NotRemovable; + + Flags |= TNF_LIST; + + //.menu + if (NULL == mTree->MenuCombo.MenuTree.mtre_name || 0 == strlen(mTree->MenuCombo.MenuTree.mtre_name)) + Flags |= TNF_NOSIGN; + + if (SCAMENUTYPE_ToolsMenu != MenuType) + { + TreeNode = (struct MUI_NListtree_TreeNode *) DoMethod(ListTree, + MUIM_NListtree_Insert, mTree->MenuCombo.MenuTree.mtre_name ? mTree->MenuCombo.MenuTree.mtre_name : (STRPTR) "", + &mie, + MenuNode, MUIV_NListtree_Insert_PrevNode_Tail, Flags); + } + else + { + TreeNode = NULL; + + for (pos=0; ; pos++) + { + struct MenuListEntry *mle; + + TreeNode = (struct MUI_NListtree_TreeNode *) DoMethod(ListTree, + MUIM_NListtree_GetEntry, NULL, pos, 0); + + if (NULL == TreeNode) + break; + + mle = (struct MenuListEntry *) TreeNode->tn_User; + + if (SCAMENUTYPE_ToolsMenu == mle->llist_EntryType) + break; + } + + if (NULL == TreeNode) + { + TreeNode = (struct MUI_NListtree_TreeNode *) DoMethod(ListTree, + MUIM_NListtree_Insert, mTree->MenuCombo.MenuTree.mtre_name ? mTree->MenuCombo.MenuTree.mtre_name : (STRPTR) "", + &mie, + MenuNode, MUIV_NListtree_Insert_PrevNode_Tail, Flags); + } + } + + if (mTree->mtre_tree) + GenerateMenuList(inst, mTree->mtre_tree, ListTree, TreeNode); + break; + } + + mTree = mTree->mtre_Next; + } +} + + +static SAVEDS(APTR) INTERRUPT ImportTDHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + char FileName[1000]; + BPTR fd; + + if (!RequestTdFile(inst, FileName, sizeof(FileName))) + return NULL; + + fd = Open(FileName, MODE_OLDFILE); + if (fd) + { + char Line[512]; + struct MUI_NListtree_TreeNode *MenuNode = NULL; + struct MUI_NListtree_TreeNode *ItemNode = NULL; + struct MUI_NListtree_TreeNode *SubNode = NULL; + struct MUI_NListtree_TreeNode *CmdNode = NULL; + struct MenuInsertEntry mie; + struct ScalosMenuTree mTree; + + memset(&mTree, 0, sizeof(mTree)); + mie.mie_TreeEntry = &mTree; + mie.mie_MenuFlags = 0; + + ClearMenuList(inst); + + DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], MUIM_NListtree_Close, + MUIV_NListtree_Close_ListNode_Root, + MUIV_NListtree_Close_TreeNode_All, + 0); + + set(inst->mpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Quiet, TRUE); + inst->mpb_QuietFlag = TRUE; + + while (NULL != FGets(fd, Line, sizeof(Line) - 1)) + { + STRPTR lp; + + StripLF(Line); + lp = stpblk(Line); + + if (CmpWord("TITLE", lp)) + { + lp = NextWord(lp); + + CmdNode = SubNode = ItemNode = NULL; + mTree.mtre_type = SCAMENUTYPE_Menu; + + MenuNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, lp, + &mie, + &inst->mpb_MainMenuNode, + MenuNode ? MenuNode : (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_PrevNode_Tail, + MUIV_NListtree_Insert_Flag_Active | TNF_OPEN | TNF_LIST); + + continue; + } + if (CmpWord("ITEM", lp)) + { + lp = NextWord(lp); + + if (NULL == MenuNode) + break; + + CmdNode = SubNode = NULL; + mTree.mtre_type = SCAMENUTYPE_MenuItem; + + ItemNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, lp, + &mie, + MenuNode, + ItemNode ? ItemNode : (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_PrevNode_Tail, + MUIV_NListtree_Insert_Flag_Active | TNF_OPEN | TNF_LIST); + + continue; + } + if (CmpWord("ITEMBAR", lp)) + { + if (NULL == MenuNode) + break; + + CmdNode = SubNode = NULL; + mTree.mtre_type = SCAMENUTYPE_MenuItem; + + ItemNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, "", + &mie, + MenuNode, + ItemNode ? ItemNode : (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_PrevNode_Tail, + MUIV_NListtree_Insert_Flag_Active | TNF_OPEN | TNF_LIST | TNF_NOSIGN); + + continue; + } + if (CmpWord("(CLI)", lp)) + { + struct MUI_NListtree_TreeNode *ParentNode; + struct MenuListEntry *mle; + ULONG StackSize; + + if (SubNode) + ParentNode = SubNode; + else + ParentNode = ItemNode; + + if (NULL == ParentNode) + break; + + lp = NextWord(lp); + + StackSize = atoi(lp); + + lp = NextWord(lp); + + mTree.mtre_type = SCAMENUTYPE_Command; + + CmdNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, lp, + &mie, + ParentNode, + CmdNode ? CmdNode : (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_PrevNode_Tail, + MUIV_NListtree_Insert_Flag_Active); + + mle = (struct MenuListEntry *) CmdNode->tn_User; + + mle->llist_Stack = StackSize; + mle->llist_CommandType = SCAMENUCMDTYPE_AmigaDOS; + + continue; + } + if (CmpWord("(WB)", lp)) + { + struct MUI_NListtree_TreeNode *ParentNode; + struct MenuListEntry *mle; + + if (SubNode) + ParentNode = SubNode; + else + ParentNode = ItemNode; + + if (NULL == ParentNode) + break; + + lp = NextWord(lp); + + mTree.mtre_type = SCAMENUTYPE_Command; + + CmdNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, lp, + &mie, + ParentNode, + CmdNode ? CmdNode : (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_PrevNode_Tail, + MUIV_NListtree_Insert_Flag_Active); + + mle = (struct MenuListEntry *) CmdNode->tn_User; + + mle->llist_CommandType = SCAMENUCMDTYPE_Workbench; + mle->llist_Stack = DEFAULT_STACKSIZE; + + continue; + } + if (CmpWord("HOTKEY", lp)) + { + struct MUI_NListtree_TreeNode *ParentNode; + struct MenuListEntry *mle; + + if (SubNode) + ParentNode = SubNode; + else + ParentNode = ItemNode; + + if (NULL == ParentNode) + break; + + lp = NextWord(lp); + + mle = (struct MenuListEntry *) ParentNode->tn_User; + + stccpy(mle->llist_HotKey, lp, sizeof(mle->llist_HotKey)); + + continue; + } + if (CmpWord("SUB", lp)) + { + lp = NextWord(lp); + + if (NULL == ItemNode) + break; + + CmdNode = NULL; + mTree.mtre_type = SCAMENUTYPE_Menu; + + SubNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, lp, + &mie, + ItemNode, + SubNode ? SubNode : (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_PrevNode_Tail, + MUIV_NListtree_Insert_Flag_Active | TNF_OPEN | TNF_LIST); + + continue; + } + } + + Close(fd); + + inst->mpb_QuietFlag = FALSE; + set(inst->mpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Quiet, FALSE); + + DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], MUIM_NListtree_Open, + MUIV_NListtree_Open_ListNode_Root, + MUIV_NListtree_Open_TreeNode_All, + 0); + } + + SetChangedFlag(inst, TRUE); + + return NULL; +} + + +static BOOL RequestTdFile(struct MenuPrefsInst *inst, char *FileName, size_t MaxLen) +{ + struct FileRequester *Req = MUI_AllocAslRequest(ASL_FileRequest, NULL); + BOOL Result = FALSE; + + if (Req) + { + struct Window *win = NULL; + + get(inst->mpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Window, &win); + + // MUI_AslRequest() + Result = MUI_AslRequestTags(Req, + ASLFR_TitleText, GetLocString(MSGID_TITLE_IMPORTTD), + ASLFR_InitialFile, "ToolsDaemon.menu", + ASLFR_InitialDrawer, "S:", + ASLFR_Window, win, + ASLFR_SleepWindow, TRUE, + ASLFR_Flags1, FRF_DOPATTERNS, + TAG_END); + + if (Result) + { + stccpy(FileName, Req->fr_Drawer, MaxLen); + AddPart(FileName, Req->fr_File, MaxLen); + } + } + + return Result; +} + + +static BOOL RequestParmFile(struct MenuPrefsInst *inst, char *FileName, size_t MaxLen) +{ + struct FileRequester *Req = MUI_AllocAslRequest(ASL_FileRequest, NULL); + BOOL Result = FALSE; + + if (Req) + { + struct Window *win = NULL; + + get(inst->mpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Window, &win); + + // MUI_AslRequest() + Result = MUI_AslRequestTags(Req, + ASLFR_TitleText, GetLocString(MSGID_TITLE_IMPORTP), + ASLFR_InitialFile, "ParM.cfg", + ASLFR_InitialDrawer, "", + ASLFR_Window, win, + ASLFR_SleepWindow, TRUE, + ASLFR_Flags1, FRF_DOPATTERNS, + TAG_END); + + if (Result) + { + stccpy(FileName, Req->fr_Drawer, MaxLen); + AddPart(FileName, Req->fr_File, MaxLen); + } + } + + return Result; +} + + +static BOOL CmpWord(CONST_STRPTR Cmd, CONST_STRPTR Line) +{ + while (*Line && (tolower(*Cmd) == tolower(*Line))) + { + Cmd++; + Line++; + } + + return (BOOL) ('\0' == *Cmd && ('\0' == *Line || isspace(*Line))); +} + + +static void StripLF(STRPTR Line) +{ + size_t Len = strlen(Line); + + Line += Len - 1; + + if ('\n' == *Line) + *Line = '\0'; +} + + +static STRPTR NextWord(STRPTR lp) +{ + if ('"' == *lp) + { + lp++; // skip leading '"' + while (*lp && '"' != *lp) + lp++; + if ('"' == *lp) + lp++; // skip trailing '"' + } + else + { + while (*lp && !isspace(*lp)) + lp++; + } + + return stpblk(lp); +} + + +static void CopyWord(STRPTR dest, CONST_STRPTR src, size_t MaxLen) +{ + if ('"' == *src) + { + src++; // skip leading '"' + while (*src && '"' != *src && MaxLen > 1) + { + *dest++ = *src++; + MaxLen--; + } + } + else + { + while (*src && !isspace(*src) && MaxLen > 1) + { + *dest++ = *src++; + MaxLen--; + } + } + + *dest = '\0'; +} + + +static SAVEDS(APTR) INTERRUPT ImportPHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + char FileName[1000]; + BPTR fd; + + if (!RequestParmFile(inst, FileName, sizeof(FileName))) + return NULL; + + fd = Open(FileName, MODE_OLDFILE); +// fd = Open("ParM.cfg", MODE_OLDFILE); + if (fd) + { + struct MUI_NListtree_TreeNode *MenuNode = NULL; + struct MUI_NListtree_TreeNode *ItemNode = NULL; + struct MUI_NListtree_TreeNode *SubNode = NULL; + struct MUI_NListtree_TreeNode *CmdNode; + char Line[512]; + struct MenuInsertEntry mie; + struct ScalosMenuTree mTree; + + memset(&mTree, 0, sizeof(mTree)); + mie.mie_TreeEntry = &mTree; + mie.mie_MenuFlags = 0; + + ClearMenuList(inst); + + DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], MUIM_NListtree_Close, + MUIV_NListtree_Close_ListNode_Root, + MUIV_NListtree_Close_TreeNode_All, + 0); + + set(inst->mpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Quiet, TRUE); + inst->mpb_QuietFlag = TRUE; + + while (NULL != FGets(fd, Line, sizeof(Line) - 1)) + { + char ItemName[100]; + STRPTR lp; + + StripLF(Line); + lp = stpblk(Line); + + if ('#' == *lp || 0 == strlen(lp)) + continue; + + if (CmpWord("MENU", lp)) + { + lp = NextWord(lp); + + CopyWord(ItemName, lp, sizeof(ItemName)); + + d1(kprintf("%s/%s/%ld: ITEM <%s> Menu=%08lx Item=%08lx Sub=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, ItemName, MenuNode, ItemNode, SubNode)); + + SubNode = ItemNode = NULL; + mTree.mtre_type = SCAMENUTYPE_Menu; + + MenuNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, ItemName, + &mie, + &inst->mpb_MainMenuNode, + MenuNode ? MenuNode : (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_PrevNode_Head, + TNF_OPEN | TNF_LIST); + + continue; + } + if (CmpWord("ITEM", lp)) + { + struct MenuListEntry *mle; + char HotKey[2]; + + lp = NextWord(lp); + + if (NULL == MenuNode) + break; + + CmdNode = NULL; + strcpy(HotKey, ""); + + if ('{' == *lp) + { + HotKey[0] = lp[1]; + lp = NextWord(lp); + } + + CopyWord(ItemName, lp, sizeof(ItemName)); + + d1(kprintf("%s/%s/%ld: ITEM <%s> Menu=%08lx Item=%08lx Sub=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, ItemName, MenuNode, ItemNode, SubNode)); + + mTree.mtre_type = SCAMENUTYPE_MenuItem; + + ItemNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, ItemName, + &mie, + SubNode ? SubNode : MenuNode, + ItemNode ? ItemNode : (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_PrevNode_Tail, + TNF_OPEN | TNF_LIST); + + mle = (struct MenuListEntry *) ItemNode->tn_User; + + stccpy(mle->llist_HotKey, HotKey, sizeof(mle->llist_HotKey)); + + lp = NextWord(stpblk(lp)); + + if (CmpWord("WB", lp)) + { + lp = NextWord(lp); + mTree.mtre_type = SCAMENUTYPE_Command; + + CmdNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, lp, + &mie, + ItemNode, + CmdNode ? CmdNode : (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_PrevNode_Tail, + 0); + + mle = (struct MenuListEntry *) CmdNode->tn_User; + + mle->llist_CommandType = SCAMENUCMDTYPE_Workbench; + mle->llist_Stack = DEFAULT_STACKSIZE; + } + else if (CmpWord("RUN", lp) || CmpWord("SHELL", lp)) + { + lp = NextWord(lp); + mTree.mtre_type = SCAMENUTYPE_Command; + + CmdNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, lp, + &mie, + ItemNode, + CmdNode ? CmdNode : (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_PrevNode_Tail, + 0); + + mle = (struct MenuListEntry *) CmdNode->tn_User; + + mle->llist_Stack = DEFAULT_STACKSIZE; + mle->llist_CommandType = SCAMENUCMDTYPE_AmigaDOS; + } + + continue; + } + if (CmpWord("BARLABEL", lp)) + { + if (NULL == MenuNode) + break; + + SubNode = NULL; + mTree.mtre_type = SCAMENUTYPE_MenuItem; + + ItemNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, "", + &mie, + MenuNode, + ItemNode ? ItemNode : (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_PrevNode_Tail, + TNF_LIST | TNF_NOSIGN); + + continue; + } + if (CmpWord("SUBMENU", lp)) + { + lp = NextWord(lp); + + if (SubNode) + break; + + CopyWord(ItemName, lp, sizeof(ItemName)); + + d1(kprintf("%s/%s/%ld: SUBMENU <%s> Menu=%08lx Item=%08lx Sub=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, ItemName, MenuNode, ItemNode, SubNode)); + + mTree.mtre_type = SCAMENUTYPE_Menu; + + SubNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, ItemName, + &mie, + MenuNode, + ItemNode ? ItemNode : (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_PrevNode_Tail, + TNF_OPEN | TNF_LIST); + + continue; + } + if (CmpWord("ENDSUBMENU", lp)) + { + d1(kprintf("%s/%s/%ld: ENDSUBMENU Menu=%08lx Item=%08lx Sub=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, MenuNode, ItemNode, SubNode)); + + if (NULL == SubNode) + break; + + ItemNode = SubNode; + SubNode = NULL; + + continue; + } + } + + Close(fd); + + inst->mpb_QuietFlag = FALSE; + + set(inst->mpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Quiet, FALSE); + + DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], MUIM_NListtree_Open, + MUIV_NListtree_Open_ListNode_Root, + MUIV_NListtree_Open_TreeNode_All, + 0); + } + + SetChangedFlag(inst, TRUE); + + return NULL; +} + + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT CollapseSelectedHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + struct MUI_NListtree_TreeNode *tn; + + set(inst->mpb_Objects[OBJNDX_MainListTree], MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, + 0); + d1(kprintf("%s/%ld: active tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) "")); + + if (tn) + { + struct MUI_NListtree_TreeNode *tnChild; + + tnChild = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + tn, + MUIV_NListtree_GetEntry_Position_Head, + 0); + d1(kprintf("%s/%ld: Head tn=%08lx <%s>\n", __FUNC__, __LINE__, tnChild, tnChild ? tnChild->tn_Name : (STRPTR) "")); + + if (tnChild) + { + set(inst->mpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Active, (ULONG) tnChild); + + DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Close, + MUIV_NListtree_Close_ListNode_Active, + MUIV_NListtree_Close_TreeNode_All, + 0); + } + + set(inst->mpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Active, (ULONG) tn); + } + + DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Close, + MUIV_NListtree_Close_ListNode_Active, + tn, + 0); + + set(inst->mpb_Objects[OBJNDX_MainListTree], MUIA_NList_Quiet, MUIV_NList_Quiet_None); + + return NULL; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT ExpandSelectedHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + struct MUI_NListtree_TreeNode *tn; + + set(inst->mpb_Objects[OBJNDX_MainListTree], MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, + 0); + d1(kprintf("%s/%ld: active tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) "")); + + DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Open, + MUIV_NListtree_Open_ListNode_Active, + MUIV_NListtree_Open_TreeNode_Active, + 0); + + if (tn) + { + struct MUI_NListtree_TreeNode *tnChild; + + tnChild = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + tn, + MUIV_NListtree_GetEntry_Position_Head, + 0); + d1(kprintf("%s/%ld: Head tn=%08lx <%s>\n", __FUNC__, __LINE__, tnChild, tnChild ? tnChild->tn_Name : (STRPTR) "")); + + if (tnChild) + { + set(inst->mpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Active, (ULONG) tnChild); + + DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Open, + MUIV_NListtree_Open_ListNode_Active, + MUIV_NListtree_Open_TreeNode_All, + 0); + } + + set(inst->mpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Active, (ULONG) tn); + } + + set(inst->mpb_Objects[OBJNDX_MainListTree], MUIA_NList_Quiet, MUIV_NList_Quiet_None); + + return NULL; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT CollapseAllHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + + DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], MUIM_NListtree_Close, + MUIV_NListtree_Close_ListNode_Root, MUIV_NListtree_Close_TreeNode_All, 0); + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT ExpandAllHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + + DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], MUIM_NListtree_Open, + MUIV_NListtree_Open_ListNode_Root, MUIV_NListtree_Open_TreeNode_All, 0); + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT CmdSelectedHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + struct CommandTableEntry *cte = NULL; + + DoMethod(inst->mpb_Objects[OBJNDX_CmdListView], MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &cte); + if (cte) + { + set(inst->mpb_Objects[OBJNDX_StringCmd], MUIA_String_Contents, (ULONG) cte->cte_Command); + + DoMethod(inst->mpb_Objects[OBJNDX_PopObject], MUIM_Popstring_Close, 0); + + ChangeEntry3HookFunc(hook, o, msg); + } + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT ContextMenuTriggerHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + Object *MenuObj = *((Object **) msg); + ULONG MenuHookIndex = 0; + struct Hook *MenuHook = NULL; + + d1(kprintf("%s/%s//%ld: MenuObj=%08lx\n", __FILE__, __FUNC__, __LINE__, MenuObj)); + d1(kprintf("%s/%s//%ld: msg=%08lx *msg=%08lx\n", __FILE__, __FUNC__, __LINE__, msg, *((ULONG *) msg))); + + get(MenuObj, MUIA_UserData, &MenuHookIndex); + + if (MenuHookIndex > 0 && MenuHookIndex < HOOKNDX_MAX) + MenuHook = &inst->mpb_Hooks[MenuHookIndex]; + + d1(kprintf("%s/%s//%ld: MenuHook=%08lx\n", __FILE__, __FUNC__, __LINE__, MenuHook)); + if (MenuHook) + DoMethod(inst->mpb_Objects[OBJNDX_Group_Main], MUIM_CallHook, MenuHook, 0); + + return NULL; +} + + +static SAVEDS(APTR) INTERRUPT AppMessageHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + struct AppMessage *AppMsg = *(struct AppMessage **) msg; + struct MUI_NListtree_TreeNode *TreeNode = NULL; + + set(inst->mpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Quiet, TRUE); + + TreeNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, 0); + + if (TreeNode) + { + struct MUI_NListtree_TreeNode *ParentNode = (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_PrevNode_Tail; + LONG n; + + for (n=0; nam_NumArgs; ) + { + struct MenuListEntry *mle = (struct MenuListEntry *) TreeNode->tn_User; + char Buffer[1000]; + STRPTR FileName; + + if (!NameFromLock(AppMsg->am_ArgList[n].wa_Lock, Buffer, sizeof(Buffer))) + break; + if (AppMsg->am_ArgList[n].wa_Name && strlen(AppMsg->am_ArgList[n].wa_Name) > 0) + AddPart(Buffer, AppMsg->am_ArgList[n].wa_Name, sizeof(Buffer)); + + FileName = FilePart(Buffer); + + switch (mle->llist_EntryType) + { + case SCAMENUTYPE_MainMenu: + d1(kprintf("%s/%s/%ld: insert at SCAMENUTYPE_MainMenu\n", __FILE__, __FUNC__, __LINE__)); + if (mle->llist_Flags & LLISTFLGF_MayNotHaveChildren) + { + AppMessage_Menu(inst, &TreeNode, &ParentNode, &AppMsg->am_ArgList[n], Buffer, FileName); + n++; + } + else + { + struct MenuInsertEntry mie; + struct ScalosMenuTree mTree; + + memset(&mTree, 0, sizeof(mTree)); + mie.mie_TreeEntry = &mTree; + mie.mie_MenuFlags = 0; + mTree.mtre_type = SCAMENUTYPE_Menu; + + TreeNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, "DragIn Menu", + &mie, + TreeNode, ParentNode, TNF_OPEN | TNF_LIST); + } + break; + + case SCAMENUTYPE_Menu: + case SCAMENUTYPE_ToolsMenu: + d1(kprintf("%s/%s/%ld: insert at SCAMENUTYPE_Menu\n", __FILE__, __FUNC__, __LINE__)); + AppMessage_Menu(inst, &TreeNode, &ParentNode, &AppMsg->am_ArgList[n], Buffer, FileName); + n++; + break; + + case SCAMENUTYPE_MenuItem: + d1(kprintf("%s/%s/%ld: insert at SCAMENUTYPE_MenuItem\n", __FILE__, __FUNC__, __LINE__)); + ParentNode = TreeNode; + TreeNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, TreeNode, MUIV_NListtree_GetEntry_Position_Parent, 0); + + AppMessage_Menu(inst, &TreeNode, &ParentNode, &AppMsg->am_ArgList[n], Buffer, FileName); + n++; + break; + + case SCAMENUTYPE_Command: + d1(kprintf("%s/%s/%ld: insert at SCAMENUTYPE_Command\n", __FILE__, __FUNC__, __LINE__)); + TreeNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, TreeNode, MUIV_NListtree_GetEntry_Position_Parent, 0); + break; + + default: + break; + } + } + } + + set(inst->mpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Quiet, FALSE); + + return 0; +} + + +static struct MUI_NListtree_TreeNode *AppMessage_Menu(struct MenuPrefsInst *inst, + struct MUI_NListtree_TreeNode **TreeNode, + struct MUI_NListtree_TreeNode **ParentNode, const struct WBArg *wbArg, + CONST_STRPTR Path, CONST_STRPTR FileName) +{ + struct MUI_NListtree_TreeNode *NewTreeNode; + struct MenuListEntry *mle; + struct MenuInsertEntry mie; + struct ScalosMenuTree mTree; + + memset(&mTree, 0, sizeof(mTree)); + mie.mie_TreeEntry = &mTree; + mie.mie_MenuFlags = 0; + + d1(kprintf("%s/%s/%ld: listnode=%08lx <%s> prevtreenode=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, *TreeNode, (*TreeNode)->tn_Name, *ParentNode)); + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + SetChangedFlag(inst, TRUE); + + mTree.mtre_type = SCAMENUTYPE_MenuItem; + + *TreeNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, FileName, + &mie, + *TreeNode, *ParentNode, TNF_OPEN | TNF_LIST); + + d1(kprintf("%s/%s/%ld: listnode=%08lx <%s> prevtreenode=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, *TreeNode, (*TreeNode)->tn_Name, *ParentNode)); + + mTree.mtre_type = SCAMENUTYPE_Command; + + NewTreeNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, "", + &mie, + *TreeNode, MUIV_NListtree_Insert_PrevNode_Tail, 0); + if (NULL == NewTreeNode) + return NULL; + + mle = (struct MenuListEntry *) NewTreeNode->tn_User; + + stccpy(mle->llist_name, Path, sizeof(mle->llist_name)); + + mle->llist_Stack = DEFAULT_STACKSIZE; + mle->llist_Priority = 0; + + if (FileName && strlen(FileName) > 0) + mle->llist_CommandType = SCAMENUCMDTYPE_Workbench; + else + mle->llist_CommandType = SCAMENUCMDTYPE_IconWindow; + + return NewTreeNode; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT SettingsChangedHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + SetChangedFlag(inst, TRUE); + + return NULL; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT AslIntuiMsgHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + struct IntuiMessage *iMsg = (struct IntuiMessage *) msg; + + if (IDCMP_REFRESHWINDOW == iMsg->Class) + { + DoMethod(inst->mpb_Objects[OBJNDX_APP_Main], MUIM_Application_CheckRefresh); + } +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT HideObsoleteHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + ULONG HideObsolete = 0; + + //TODO + get(inst->mpb_Objects[OBJNDX_Menu_HideObsolete], MUIA_Menuitem_Checked, &HideObsolete); + inst->mpb_HideObsoletePopupMenus = HideObsolete; + + d1(KPrintF("%s/%s/%ld: mpb_HideObsoletePopupMenus=%ld\n", __FILE__, __FUNC__, __LINE__, inst->mpb_HideObsoletePopupMenus)); + + set(inst->mpb_Objects[OBJNDX_MainListView], MUIA_NListtree_Quiet, TRUE); + set(inst->mpb_Objects[OBJNDX_HiddenListTree], MUIA_NListtree_Quiet, TRUE); + + if (inst->mpb_HideObsoletePopupMenus) + { + // Move obsolete entries from OBJNDX_MainListTree to OBJNDX_HiddenListTree + MoveMenuTree(inst, OBJNDX_HiddenListTree, OBJNDX_MainListTree, POPMENUINDEX_Disk); + MoveMenuTree(inst, OBJNDX_HiddenListTree, OBJNDX_MainListTree, POPMENUINDEX_Drawer); + MoveMenuTree(inst, OBJNDX_HiddenListTree, OBJNDX_MainListTree, POPMENUINDEX_ToolProject); + MoveMenuTree(inst, OBJNDX_HiddenListTree, OBJNDX_MainListTree, POPMENUINDEX_Trashcan); + MoveMenuTree(inst, OBJNDX_HiddenListTree, OBJNDX_MainListTree, POPMENUINDEX_AppIcon); + } + else + { + // Move obsolete entries from OBJNDX_HiddenListTree to OBJNDX_MainListTree + MoveMenuTree(inst, OBJNDX_MainListTree, OBJNDX_HiddenListTree, POPMENUINDEX_Disk); + MoveMenuTree(inst, OBJNDX_MainListTree, OBJNDX_HiddenListTree, POPMENUINDEX_Drawer); + MoveMenuTree(inst, OBJNDX_MainListTree, OBJNDX_HiddenListTree, POPMENUINDEX_ToolProject); + MoveMenuTree(inst, OBJNDX_MainListTree, OBJNDX_HiddenListTree, POPMENUINDEX_Trashcan); + MoveMenuTree(inst, OBJNDX_MainListTree, OBJNDX_HiddenListTree, POPMENUINDEX_AppIcon); + } + + set(inst->mpb_Objects[OBJNDX_MainListView], MUIA_NListtree_Quiet, FALSE); + set(inst->mpb_Objects[OBJNDX_HiddenListTree], MUIA_NListtree_Quiet, FALSE); + + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT MenuCopyHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + struct MUI_NListtree_TreeNode *TreeNode; + + d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__)); + + if (inst->mpb_QuietFlag) + return; + + TreeNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, 0); + + if (TreeNode) + { + DoMethod(inst->mpb_Objects[OBJNDX_ListTreeClipboard], MUIM_NListtree_Clear); + + CopyFileTypesEntry(inst, + (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_ListNode_Root, + (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_PrevNode_Tail, + TreeNode, + OBJNDX_ListTreeClipboard, + OBJNDX_MainListTree); + } + + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT MenuCutHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + struct MUI_NListtree_TreeNode *TreeNode; + + d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__)); + + if (inst->mpb_QuietFlag) + return; + + TreeNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, 0); + + if (TreeNode) + { + DoMethod(inst->mpb_Objects[OBJNDX_ListTreeClipboard], MUIM_NListtree_Clear); + + CopyFileTypesEntry(inst, + (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_ListNode_Root, + (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_PrevNode_Tail, + TreeNode, + OBJNDX_ListTreeClipboard, + OBJNDX_MainListTree); + + DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], MUIM_NListtree_Remove, + MUIV_NListtree_Remove_ListNode_Active, + MUIV_NListtree_Remove_TreeNode_Active, 0); + } + + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT MenuPasteHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct MenuPrefsInst *inst = (struct MenuPrefsInst *) hook->h_Data; + struct MUI_NListtree_TreeNode *tn; + + d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__)); + + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, + 0); + d1(kprintf("%s/%ld: active tn=%08lx <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) "")); + + if (tn) + { + struct MUI_NListtree_TreeNode *tnParent; + struct MUI_NListtree_TreeNode *tnShadow; + + tnParent = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + tn, + MUIV_NListtree_GetEntry_Position_Parent, + 0); + + tnShadow = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_ListTreeClipboard], + MUIM_NListtree_GetEntry, + MUIV_NListtree_Insert_ListNode_Root, + MUIV_NListtree_GetEntry_Position_Head, + 0); + + set(inst->mpb_Objects[OBJNDX_MainListTree], MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + + if (MayPasteBelow(inst, tn, tnShadow)) + { + CopyFileTypesEntry(inst, + tnParent, tn, + tnShadow, + OBJNDX_MainListTree, OBJNDX_ListTreeClipboard); + +// EntryHasChanged(inst, tnParent); + } + else if (MayPasteOnto(inst, tn, tnShadow)) + { + CopyFileTypesEntry(inst, + tn, (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_PrevNode_Tail, + tnShadow, + OBJNDX_MainListTree, OBJNDX_ListTreeClipboard); + +// EntryHasChanged(inst, tn); + } + + set(inst->mpb_Objects[OBJNDX_MainListTree], MUIA_NList_Quiet, MUIV_NList_Quiet_None); + + DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Redraw, + tn, + 0); + } + + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); +} + +//---------------------------------------------------------------------------- + +static struct MUI_NListtree_TreeNode *MoveMenuTree(struct MenuPrefsInst *inst, + ULONG DestListtreeIndex, ULONG SrcListtreeIndex, ULONG EntryIndex) +{ + struct MUI_NListtree_TreeNode *NewNode = NULL; + + if (inst->mpb_PopMenuNode[EntryIndex].mpn_ListNode && + inst->mpb_PopMenuNode[EntryIndex].mpn_Listtree == inst->mpb_Objects[SrcListtreeIndex]) + { + // Create new entry in dest listtree + NewNode = CopyMenuEntry(inst, + inst->mpb_Objects[DestListtreeIndex], + inst->mpb_Objects[SrcListtreeIndex], + inst->mpb_PopMenuNode[EntryIndex].mpn_ListNode, + MUIV_NListtree_Insert_ListNode_Root); + if (NewNode) + { + // remove old entry (w/ subentries) from src listtree + DoMethod(inst->mpb_PopMenuNode[EntryIndex].mpn_Listtree, + MUIM_NListtree_Remove, + MUIV_NListtree_Remove_ListNode_Root, + inst->mpb_PopMenuNode[EntryIndex].mpn_ListNode, + 0); + + // remember new entry + inst->mpb_PopMenuNode[EntryIndex].mpn_Listtree = inst->mpb_Objects[DestListtreeIndex]; + inst->mpb_PopMenuNode[EntryIndex].mpn_ListNode = NewNode; + } + } + + return NewNode; +} + +//---------------------------------------------------------------------------- + +static struct MUI_NListtree_TreeNode *CopyFileTypesEntry(struct MenuPrefsInst *inst, + struct MUI_NListtree_TreeNode *tnToListNode, struct MUI_NListtree_TreeNode *tnToPrevNode, + struct MUI_NListtree_TreeNode *tnFrom, ULONG destList, ULONG srcList) +{ + struct MenuListEntry *mleFrom = (struct MenuListEntry *) tnFrom->tn_User; + struct MenuListEntry *mleTo; + struct MUI_NListtree_TreeNode *tnNew; + struct MUI_NListtree_TreeNode *tnChild; + struct MenuInsertEntry mie; + struct ScalosMenuTree mTree; + STRPTR IconNames = NULL; + + memset(&mTree, 0, sizeof(mTree)); + mie.mie_TreeEntry = &mTree; + + if (NULL == tnFrom) + return NULL; + + tnChild = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[srcList], + MUIM_NListtree_GetEntry, + tnFrom, + MUIV_NListtree_GetEntry_Position_Head, + 0); + + mTree.mtre_type = mleFrom->llist_EntryType; + mie.mie_MenuFlags = mleFrom->llist_Flags; + + switch (mleFrom->llist_EntryType) + { + case SCAMENUTYPE_Menu: + case SCAMENUTYPE_ToolsMenu: + case SCAMENUTYPE_MenuItem: + stccpy(mTree.MenuCombo.MenuTree.mtre_hotkey, mleFrom->llist_HotKey, + sizeof(mTree.MenuCombo.MenuTree.mtre_hotkey)); + + if (strlen(mleFrom->llist_UnselectedIconName) > 0 + || strlen(mleFrom->llist_SelectedIconName) > 0) + { + size_t len = 2 + strlen(mleFrom->llist_UnselectedIconName) + strlen(mleFrom->llist_SelectedIconName); + + IconNames = malloc(len); + if (IconNames) + { + strcpy(IconNames, mleFrom->llist_UnselectedIconName); + strcpy(IconNames + 1 + strlen(IconNames), mleFrom->llist_SelectedIconName); + + mTree.mtre_flags |= MTREFLGF_IconNames; + } + } + break; + case SCAMENUTYPE_Command: + mTree.MenuCombo.MenuCommand.mcom_type = mleFrom->llist_CommandType; + mTree.MenuCombo.MenuCommand.mcom_flags = mleFrom->llist_CommandFlags; + mTree.MenuCombo.MenuCommand.mcom_pri = mleFrom->llist_Priority; + mTree.MenuCombo.MenuCommand.mcom_stack = mleFrom->llist_Stack; + break; + default: + break; + } + + tnNew = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[destList], + MUIM_NListtree_Insert, + tnFrom->tn_Name, + &mie, + tnToListNode, + tnToPrevNode, + tnFrom->tn_Flags); + + if (IconNames) + free(IconNames); + + mleTo = (struct MenuListEntry *) tnNew->tn_User; + + *mleTo = *mleFrom; + + // Copy Children + while (tnChild) + { + d1(kprintf("%s/%ld: tnChild=%08lx <%s>\n", __FUNC__, __LINE__, tnChild, tnChild->tn_Name)); + + CopyFileTypesEntry(inst, + tnNew, (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_PrevNode_Tail, + tnChild, destList, srcList); + + tnChild = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[srcList], + MUIM_NListtree_GetEntry, + tnChild, + MUIV_NListtree_GetEntry_Position_Next, + 0); + } + + return tnNew; +} + +//---------------------------------------------------------------------------- + +static LONG CopyMenuTree(struct MenuPrefsInst *inst, + Object *ListTreeDest, Object *ListTreeSrc, + struct MUI_NListtree_TreeNode *Src, struct MUI_NListtree_TreeNode *DestParent) +{ + LONG Result = RETURN_OK; + + d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__)); + + while (Src) + { + CopyMenuEntry(inst, ListTreeDest, ListTreeSrc, Src, DestParent); + + Src = (struct MUI_NListtree_TreeNode *) DoMethod(ListTreeSrc, + MUIM_NListtree_GetEntry, + Src, + MUIV_NListtree_GetEntry_Position_Next, + MUIV_NListtree_GetEntry_Flag_SameLevel); + d1(KPrintF("%s/%s/%ld: Src=%08lx\n", __FILE__, __FUNC__, __LINE__, Src)); + } + + d1(KPrintF("%s/%s/%ld: END Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + + return Result; +} + +//---------------------------------------------------------------------------- + +static struct MUI_NListtree_TreeNode *CopyMenuEntry(struct MenuPrefsInst *inst, + Object *ListTreeDest, Object *ListTreeSrc, + struct MUI_NListtree_TreeNode *Src, struct MUI_NListtree_TreeNode *DestParent) +{ + const struct MenuListEntry *mleSrc = (struct MenuListEntry *) Src->tn_User; + struct MUI_NListtree_TreeNode *NewNode; + + d1(KPrintF("%s/%s/%ld: TreeNode=%08lx <%s> DestParent=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, Src, Src->tn_Name ? Src->tn_Name : (STRPTR) "===BAR===", DestParent)); + + NewNode = (struct MUI_NListtree_TreeNode *) DoMethod(ListTreeDest, + MUIM_NListtree_Insert, Src->tn_Name, + 0, + DestParent, + MUIV_NListtree_Insert_PrevNode_Tail, + Src->tn_Flags); + if (NewNode) + { + struct MenuListEntry *mleDest = (struct MenuListEntry *) NewNode->tn_User; + struct MUI_NListtree_TreeNode *SubNode; + + // Clone entry + *mleDest = *mleSrc; + + SubNode = (struct MUI_NListtree_TreeNode *) DoMethod(ListTreeSrc, + MUIM_NListtree_GetEntry, + Src, + MUIV_NListtree_GetEntry_Position_Head, + 0); + + d1(KPrintF("%s/%s/%ld: SubNode=%08lx\n", __FILE__, __FUNC__, __LINE__, SubNode)); + if (SubNode) + { + CopyMenuTree(inst, + ListTreeDest, + ListTreeSrc, + SubNode, + NewNode); + } + } + + return NewNode; +} + +//---------------------------------------------------------------------------- + +static void EnableCommandArgumentGadgets(struct MenuPrefsInst *inst, const struct MenuListEntry *mle) +{ + switch (mle->llist_CommandType) + { + case SCAMENUCMDTYPE_AmigaDOS: + case SCAMENUCMDTYPE_Workbench: + set(inst->mpb_Objects[OBJNDX_CheckArgs], MUIA_Disabled, FALSE); + set(inst->mpb_Objects[OBJNDX_CheckArgs], MUIA_Selected, (mle->llist_CommandFlags & MCOMFLGF_Args)); + set(inst->mpb_Objects[OBJNDX_SliderPriority], MUIA_Disabled, FALSE); + set(inst->mpb_Objects[OBJNDX_StringStack], MUIA_Disabled, FALSE); + break; + + case SCAMENUCMDTYPE_Command: + case SCAMENUCMDTYPE_IconWindow: + case SCAMENUCMDTYPE_ARexx: + case SCAMENUCMDTYPE_Plugin: + set(inst->mpb_Objects[OBJNDX_CheckArgs], MUIA_Disabled, TRUE); + set(inst->mpb_Objects[OBJNDX_CheckArgs], MUIA_Selected, FALSE); + set(inst->mpb_Objects[OBJNDX_SliderPriority], MUIA_Disabled, TRUE); + set(inst->mpb_Objects[OBJNDX_StringStack], MUIA_Disabled, TRUE); + break; + } +} + +//---------------------------------------------------------------------------- + +static BOOL IsPopupMenu(struct MenuPrefsInst *inst, struct MUI_NListtree_TreeNode *TreeNode) +{ + struct MUI_NListtree_TreeNode *ParentNode; + BOOL IsPopupMenu = FALSE; + + // find root of this TreeNode + ParentNode = TreeNode; + while (ParentNode) + { + if (inst->mpb_MainMenuNode.mpn_ListNode != ParentNode) + { + short n; + + for (n = 0; n < Sizeof(inst->mpb_PopMenuNode); n++) + { + if (inst->mpb_PopMenuNode[n].mpn_ListNode == ParentNode) + { + IsPopupMenu = TRUE; + break; + } + } + } + + ParentNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, ParentNode, MUIV_NListtree_GetEntry_Position_Parent, 0); + + d1(kprintf("%s/%s/%ld: Parent=%08lx\n", __FILE__, __FUNC__, __LINE__, ParentNode)); + } + + return IsPopupMenu; +} + +//---------------------------------------------------------------------------- + +static enum MenuEntryType GetMenuEntryType(struct MenuPrefsInst *inst, + struct MUI_NListtree_TreeNode *TreeNode) +{ + struct MenuListEntry *mle = (struct MenuListEntry *) TreeNode->tn_User; + struct MUI_NListtree_TreeNode *ParentNode; + BOOL IsMainMenu = FALSE; + BOOL IsPopupMenu = FALSE; + ULONG Level = 0; + + if (NULL == mle) + return MENUENTRY_Invalid; + + if (SCAMENUTYPE_Command == mle->llist_EntryType) + { + // Get parent menu entry for command + TreeNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, TreeNode, MUIV_NListtree_GetEntry_Position_Parent, 0); + + mle = (struct MenuListEntry *) TreeNode->tn_User; + } + + // find root of this TreeNode + ParentNode = TreeNode; + while (ParentNode) + { + if (inst->mpb_MainMenuNode.mpn_ListNode == ParentNode) + IsMainMenu = TRUE; + else + { + short n; + + for (n = 0; n < Sizeof(inst->mpb_PopMenuNode); n++) + { + if (inst->mpb_PopMenuNode[n].mpn_ListNode == ParentNode) + { + IsPopupMenu = TRUE; + break; + } + } + } + + Level++; + + ParentNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, ParentNode, MUIV_NListtree_GetEntry_Position_Parent, 0); + + d1(kprintf("%s/%s/%ld: Parent=%08lx\n", __FILE__, __FUNC__, __LINE__, ParentNode)); + } + + if (IsMainMenu) + { + Level -= 2; + // Level 0 = MainMenu + // Level 1 = Menu entry + // Level 2 = MenuItem + // Level 3 = SubItem + } + else if (IsPopupMenu) + { + Level--; + // Level 1 = Popup Menu + // Level 2 = MenuItem + // Level 3 = SubItem + } + else + return MENUENTRY_Invalid; + + d1(kprintf("%s/%s/%ld: IsMainMenu=%ld IsPopupMenu=%ld Level=%ld\n", \ + __FILE__, __FUNC__, __LINE__, IsMainMenu, IsPopupMenu, Level)); + + switch (mle->llist_EntryType) + { + case SCAMENUTYPE_Menu: + case SCAMENUTYPE_MainMenu: + case SCAMENUTYPE_ToolsMenu: + Level++; // Check applies to Menu children + break; + default: + break; + } + + switch (Level) + { + case 1: // Menu + return MENUENTRY_Menu; + break; + case 2: // MenuItem + return MENUENTRY_MenuItem; + break; + case 3: // SubItem + return MENUENTRY_SubItem; + break; + default: // should never occur + return MENUENTRY_Invalid; + break; + } +} + +//---------------------------------------------------------------------------- + +static ULONG GetMaxCountForEntry(enum MenuEntryType type) +{ + switch (type) + { + case MENUENTRY_Menu: + return MAX_MENU; + break; + case MENUENTRY_MenuItem: + return MAX_MENUITEM; + break; + case MENUENTRY_SubItem: + return MAX_SUBITEM; + break; + default: + return 0; + break; + } +} + +//---------------------------------------------------------------------------- + +void _XCEXIT(long x) +{ +} + +//---------------------------------------------------------------------------- + +static void SwitchPopButton(struct MenuPrefsInst *inst, UBYTE CommandType) +{ + if (SCAMENUCMDTYPE_Command == CommandType) + { + set(inst->mpb_Objects[OBJNDX_PopObject], MUIA_ShowMe, TRUE); + set(inst->mpb_Objects[OBJNDX_Popbutton], MUIA_ShowMe, FALSE); + } + else + { + set(inst->mpb_Objects[OBJNDX_PopObject], MUIA_ShowMe, FALSE); + set(inst->mpb_Objects[OBJNDX_Popbutton], MUIA_ShowMe, TRUE); + } + +} + +//---------------------------------------------------------------------------- + +DISPATCHER(myNListTree) +{ + struct MenuPrefsInst *inst = NULL; + ULONG Result; + + d1(kprintf("%s/%s/%ld: MethodID=%08lx\n", __FILE__, __FUNC__, __LINE__, msg->MethodID)); + + switch(msg->MethodID) + { + case MUIM_ContextMenuChoice: + { + struct MUIP_ContextMenuChoice *cmc = (struct MUIP_ContextMenuChoice *) msg; + Object *MenuObj; + ULONG MenuHookIndex = 0; + struct Hook *MenuHook = NULL; + + get(obj, MUIA_NList_PrivateData, &inst); + + d1(kprintf("%s/%s//%ld: MUIM_ContextMenuChoice item=%08lx\n", __FILE__, __FUNC__, __LINE__, cmc->item)); + + MenuObj = cmc->item; + + d1(kprintf("%s/%s//%ld: MenuObj=%08lx\n", __FILE__, __FUNC__, __LINE__, MenuObj)); + d1(kprintf("%s/%s//%ld: msg=%08lx *msg=%08lx\n", __FILE__, __FUNC__, __LINE__, msg, *((ULONG *) msg))); + + get(MenuObj, MUIA_UserData, &MenuHookIndex); + + if (MenuHookIndex > 0 && MenuHookIndex < HOOKNDX_MAX) + MenuHook = &inst->mpb_Hooks[MenuHookIndex]; + + d1(kprintf("%s/%s//%ld: MenuHook=%08lx\n", __FILE__, __FUNC__, __LINE__, MenuHook)); + if (MenuHook) + DoMethod(inst->mpb_Objects[OBJNDX_Group_Main], MUIM_CallHook, MenuHook, 0); + + Result = 0; + } + break; + + case MUIM_NList_TestPos: + { + struct TestPosArg + { + ULONG MethodID; + LONG x, y; + struct MUI_NList_TestPos_Result *res; + }; + struct TestPosArg *tpa = (struct TestPosArg *) msg; + + get(obj, MUIA_NList_PrivateData, &inst); + + if (inst->mpb_PageIsActive) + Result = DoSuperMethodA(cl, obj, msg); + else + { + Result = 0; + tpa->res->entry = tpa->res->column = -1; + } + + d1(kprintf("%s/%s//%ld: MUIM_NList_TestPos Result=%08lx x=%ld y=%ld tpr=%08lx entry=%ld column=%ld\n", \ + __FILE__, __FUNC__, __LINE__, Result, tpa->x, tpa->y, tpa->res, tpa->res->entry, tpa->res->column)); + } + break; + + case MUIM_DragDrop: + get(obj, MUIA_NList_PrivateData, &inst); + SetChangedFlag(inst, TRUE); + Result = DoSuperMethodA(cl, obj, msg); + break; + + case MUIM_NList_DropType: + { + struct MUIP_NList_DropType *dr = (struct MUIP_NList_DropType *)msg; + struct MUI_NListtree_TreeNode *tnTo, *tnFrom; + struct MUI_NListtree_TestPos_Result res; + + get(obj, MUIA_NList_PrivateData, &inst); + + inst->mpb_MenuTreeMayDrop = FALSE; + + Result = DoSuperMethodA(cl, obj, msg); + d1(KPrintF("%s/%ld: DropType=%ld pos=%ld\n", __FUNC__, __LINE__, *(dr->type), *(dr->pos))); + + DoMethod(obj, MUIM_NListtree_TestPos, dr->mousex, dr->mousey, &res); + + tnTo = res.tpr_TreeNode; + + tnFrom = MUIV_NListtree_Active_Off; + get(obj, MUIA_NListtree_Active, &tnFrom); + + d1(KPrintF("%s/%ld: tnFrom=%08lx tnTo=%08lx\n", __FUNC__, __LINE__, tnFrom, tnTo)); + + if (tnTo && tnFrom) + { + switch (*(dr->type)) + { + case MUIV_NListtree_DropType_None: + case MUIV_NListtree_DropType_Sorted: + default: + break; + case MUIV_NListtree_DropType_Above: + case MUIV_NListtree_DropType_Below: + if (MayPasteBelow(inst, tnTo, tnFrom)) + inst->mpb_MenuTreeMayDrop = TRUE; + break; + case MUIV_NListtree_DropType_Onto: + if (MayPasteOnto(inst, tnTo, tnFrom)) + inst->mpb_MenuTreeMayDrop = TRUE; + break; + } + d1(KPrintF("%s/%ld: DropType=%ld\n", __FUNC__, __LINE__, *(dr->type))); + } + } + break; + + // we catch MUIM_DragReport because we want to restrict some dragging for some special objects + case MUIM_DragReport: + { + get(obj, MUIA_NList_PrivateData, &inst); + + d1(KPrintF("%s/%ld: MUIM_DragReport\n", __FUNC__, __LINE__)); + + Result = DoSuperMethodA(cl, obj, msg); + if (!inst->mpb_MenuTreeMayDrop) + Result = MUIV_DragReport_Abort; + + d1(KPrintF("%s/%ld: MUIM_DragReport\n", __FUNC__, __LINE__)); + } + break; + default: + Result = DoSuperMethodA(cl, obj, msg); + } + + return Result; +} +DISPATCHER_END + + +static Object *CreatePrefsImage(void) +{ +#include "MenuPrefsImage.h" + Object *img; + + // First try to load datatypes image from THEME: tree + img = DataTypesImageObject, + MUIA_ScaDtpic_Name, (ULONG) "THEME:prefs/plugins/menu", + MUIA_ScaDtpic_FailIfUnavailable, TRUE, + End; //DataTypesMCCObject + + if (NULL == img) + img = IMG(MenuPrefs, MENUPREFS); // use built-in fallback image + + return img; +} + + +static void InitHooks(struct MenuPrefsInst *inst) +{ + ULONG n; + + for (n=0; nmpb_Hooks[n] = MenuPrefsHooks[n]; + inst->mpb_Hooks[n].h_Data = inst; + } +} + + +static void SetChangedFlag(struct MenuPrefsInst *inst, BOOL changed) +{ + if (changed != inst->mpb_Changed) + { + set(inst->mpb_Objects[OBJNDX_Lamp_Changed], + MUIA_Lamp_Color, changed ? MUIV_Lamp_Color_Ok : MUIV_Lamp_Color_Off); + inst->mpb_Changed = changed; + } +} + + +static void AddDefaultMenuContents(struct MenuPrefsInst *inst) +{ + ULONG n; + struct MUI_NListtree_TreeNode *LastNode[4]; + Object *Listtree = NULL; + struct MenuInsertEntry mie; + struct ScalosMenuTree mTree; + + mie.mie_TreeEntry = &mTree; + + inst->mpb_QuietFlag = TRUE; + + for (n = 0; n < DefaultMenuEntries; n++) + { + struct MUI_NListtree_TreeNode *ParentNode; + CONST_STRPTR MenuName; + struct MUI_NListtree_TreeNode *NewNode; + struct MenuListEntry *mle; + ULONG InsertFlags; + + memset(&mTree, 0, sizeof(mTree)); + + switch (DefaultMenu[n].dme_ParentNode) + { + case DEFAULTPARENTNODE_MainMenu: + Listtree = inst->mpb_MainMenuNode.mpn_Listtree; + ParentNode = inst->mpb_MainMenuNode.mpn_ListNode; + d1(KPrintF("%s/%s//%ld: DEFAULTPARENTNODE_MainMenu Listtree=%08lx\n", __FILE__, __FUNC__, __LINE__, Listtree)); + break; + case DEFAULTPARENTNODE_Popup_Disk: + Listtree = inst->mpb_PopMenuNode[POPMENUINDEX_Disk].mpn_Listtree; + ParentNode = inst->mpb_PopMenuNode[POPMENUINDEX_Disk].mpn_ListNode; + d1(KPrintF("%s/%s//%ld:DEFAULTPARENTNODE_Popup_Disk Listtree=%08lx\n", __FILE__, __FUNC__, __LINE__, Listtree)); + break; + case DEFAULTPARENTNODE_Popup_Drawer: + Listtree = inst->mpb_PopMenuNode[POPMENUINDEX_Drawer].mpn_Listtree; + ParentNode = inst->mpb_PopMenuNode[POPMENUINDEX_Drawer].mpn_ListNode; + d1(KPrintF("%s/%s//%ld: DEFAULTPARENTNODE_Popup_Drawer Listtree=%08lx\n", __FILE__, __FUNC__, __LINE__, Listtree)); + break; + case DEFAULTPARENTNODE_Popup_ToolProject: + Listtree = inst->mpb_PopMenuNode[POPMENUINDEX_ToolProject].mpn_Listtree; + ParentNode = inst->mpb_PopMenuNode[POPMENUINDEX_ToolProject].mpn_ListNode; + d1(KPrintF("%s/%s//%ld: DEFAULTPARENTNODE_Popup_ToolProject Listtree=%08lx\n", __FILE__, __FUNC__, __LINE__, Listtree)); + break; + case DEFAULTPARENTNODE_Popup_Trashcan: + Listtree = inst->mpb_PopMenuNode[POPMENUINDEX_ToolProject].mpn_Listtree; + ParentNode = inst->mpb_PopMenuNode[POPMENUINDEX_Trashcan].mpn_ListNode; + d1(KPrintF("%s/%s//%ld: DEFAULTPARENTNODE_Popup_Trashcan Listtree=%08lx\n", __FILE__, __FUNC__, __LINE__, Listtree)); + break; + case DEFAULTPARENTNODE_Popup_Window: + Listtree = inst->mpb_PopMenuNode[POPMENUINDEX_Window].mpn_Listtree; + ParentNode = inst->mpb_PopMenuNode[POPMENUINDEX_Window].mpn_ListNode; + d1(KPrintF("%s/%s//%ld: DEFAULTPARENTNODE_Popup_Window Listtree=%08lx\n", __FILE__, __FUNC__, __LINE__, Listtree)); + break; + case DEFAULTPARENTNODE_Popup_AppIcon: + Listtree = inst->mpb_PopMenuNode[POPMENUINDEX_AppIcon].mpn_Listtree; + ParentNode = inst->mpb_PopMenuNode[POPMENUINDEX_AppIcon].mpn_ListNode; + d1(KPrintF("%s/%s//%ld: DEFAULTPARENTNODE_Popup_AppIcon Listtree=%08lx\n", __FILE__, __FUNC__, __LINE__, Listtree)); + break; + case DEFAULTPARENTNODE_Popup_Desktop: + Listtree = inst->mpb_PopMenuNode[POPMENUINDEX_Desktop].mpn_Listtree; + ParentNode = inst->mpb_PopMenuNode[POPMENUINDEX_Desktop].mpn_ListNode; + d1(KPrintF("%s/%s//%ld: DEFAULTPARENTNODE_Popup_Desktop Listtree=%08lx\n", __FILE__, __FUNC__, __LINE__, Listtree)); + break; + case DEFAULTPARENTNODE_LastInsertedMenu: + case DEFAULTPARENTNODE_LastInsertedMenuItem: + ParentNode = LastNode[DefaultMenu[n].dme_Level - 1]; + break; + case DEFAULTPARENTNODE_LastInserted: + default: + ParentNode = (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_ListNode_LastInserted; + break; + } + + InsertFlags = MUIV_NListtree_Insert_Flag_Active; + + if (SCAMENUTYPE_Command == DefaultMenu[n].dme_EntryType) + { + MenuName = (CONST_STRPTR) DefaultMenu[n].dme_NameId; + mTree.MenuCombo.MenuCommand.mcom_name = (STRPTR) MenuName; + } + else + { + if (DefaultMenu[n].dme_NameId) + MenuName = GetLocString(DefaultMenu[n].dme_NameId); + else + MenuName = ""; + InsertFlags |= TNF_OPEN | TNF_LIST; + } + + d1(KPrintF("%s/%s//%ld: Listtree=%08lx ParentNode=%08lx\n", __FILE__, __FUNC__, __LINE__, Listtree, ParentNode)); + + mTree.mtre_type = DefaultMenu[n].dme_EntryType; + mie.mie_MenuFlags = 0; + + switch (DefaultMenu[n].dme_EntryType) + { + case SCAMENUTYPE_Menu: + case SCAMENUTYPE_ToolsMenu: + case SCAMENUTYPE_MenuItem: + stccpy(mTree.MenuCombo.MenuTree.mtre_hotkey, GetLocString(DefaultMenu[n].dme_MenuShortId), sizeof(mle->llist_HotKey)); + break; + case SCAMENUTYPE_Command: + mTree.MenuCombo.MenuCommand.mcom_type = DefaultMenu[n].dme_CmdType; + mTree.MenuCombo.MenuCommand.mcom_flags = DefaultMenu[n].dme_CmdFlags; + mTree.MenuCombo.MenuCommand.mcom_pri = DefaultMenu[n].dme_CmdPri; + mTree.MenuCombo.MenuCommand.mcom_stack = DefaultMenu[n].dme_CmdStackSize; + break; + default: + break; + } + + DoMethod(Listtree, + MUIM_NListtree_Insert, MenuName, + &mie, + ParentNode, + MUIV_NListtree_Insert_PrevNode_Tail, + InsertFlags); + + d1(KPrintF("%s/%s//%ld: Listtree=%08lx NewNode=%08lx\n", __FILE__, __FUNC__, __LINE__, Listtree, NewNode)); + NewNode = (struct MUI_NListtree_TreeNode *) DoMethod(Listtree, + MUIM_NListtree_GetEntry, + ParentNode, + MUIV_NListtree_GetEntry_Position_Tail, 0); + d1(KPrintF("%s/%s//%ld: Listtree=%08lx NewNode=%08lx\n", __FILE__, __FUNC__, __LINE__, Listtree, NewNode)); + if (NewNode) + mle = (struct MenuListEntry *) NewNode->tn_User; + else + mle = NULL; + + if (mle) + { + switch (DefaultMenu[n].dme_EntryType) + { + case SCAMENUTYPE_Menu: + case SCAMENUTYPE_ToolsMenu: + case SCAMENUTYPE_MenuItem: + LastNode[DefaultMenu[n].dme_Level] = NewNode; + break; + default: + break; + } + } + } + + inst->mpb_QuietFlag = FALSE; +} + +//----------------------------------------------------------------- + +static void ParseToolTypes(struct MenuPrefsInst *inst, struct MUIP_ScalosPrefs_ParseToolTypes *ptt) +{ + STRPTR tt; + + d1(kprintf("%s/%ld: start ptt=%08lx tooltypes=%08lx\n", __FUNC__, __LINE__, ptt, ptt->ToolTypes)); + d1(kprintf("%s/%ld: start tooltypes=%08lx %08lx %08lx\n", __FUNC__, __LINE__, ptt, ptt->ToolTypes[0], ptt->ToolTypes[1], ptt->ToolTypes[2])); + + tt = FindToolType(ptt->ToolTypes, "HIDEOBSOLETE"); + d1(kprintf("%s/%ld: tt=%08lx\n", __FUNC__, __LINE__, tt)); + if (tt) + { + d1(kprintf("%s/%ld:\n", __FUNC__, __LINE__)); + + if (MatchToolValue(tt, "YES")) + inst->mpb_HideObsoletePopupMenus = TRUE; + else if (MatchToolValue(tt, "NO")) + inst->mpb_HideObsoletePopupMenus = FALSE; + + d1(kprintf("%s/%ld:\n", __FUNC__, __LINE__)); + } + + if (inst->mpb_Objects[OBJNDX_Menu_HideObsolete]) + set(inst->mpb_Objects[OBJNDX_Menu_HideObsolete], MUIA_Menuitem_Checked, inst->mpb_HideObsoletePopupMenus); + + CallHookPkt(&inst->mpb_Hooks[HOOKNDX_HideObsolete], + inst->mpb_Objects[OBJNDX_APP_Main], 0); + + d1(kprintf("%s/%ld: end\n", __FUNC__, __LINE__)); +} + +//---------------------------------------------------------------------------- + +BOOL initPlugin(struct PluginBase *PluginBase) +{ + ULONG n; + + MajorVersion = PluginBase->pl_LibNode.lib_Version; + MinorVersion = PluginBase->pl_LibNode.lib_Revision; + + d1(kprintf("%s/%s//%ld:\n", __FILE__, __FUNC__, __LINE__)); + + d1(kprintf("%s/%s//%ld: MenuPrefsLibBase=%08lx procName=<%s>\n", __FILE__, __FUNC__, __LINE__, \ + PluginBase, FindTask(NULL)->tc_Node.ln_Name)); + + d1(kprintf("%s/%s//%ld:\n", __FILE__, __FUNC__, __LINE__)); + + if (!OpenLibraries()) + return FALSE; + + d1(kprintf("%s/%s//%ld:\n", __FILE__, __FUNC__, __LINE__)); + +#if !defined(__amigaos4__) && !defined(__AROS__) + if (_STI_240_InitMemFunctions()) + return FALSE; +#endif + + d1(kprintf("%s/%s//%ld:\n", __FILE__, __FUNC__, __LINE__)); + + MenuPrefsClass = MUI_CreateCustomClass(&PluginBase->pl_LibNode, MUIC_Group, + NULL, sizeof(struct MenuPrefsInst), DISPATCHER_REF(MenuPrefs)); + + d1(kprintf("%s/%s//%ld: MenuPrefsClass=%08lx\n", __FILE__, __FUNC__, __LINE__, MenuPrefsClass)); + if (NULL == MenuPrefsClass) + return FALSE; + + for (n=0; nmpb_MainMenuNode.mpn_Listtree = inst->mpb_Objects[OBJNDX_MainListTree]; + inst->mpb_MainMenuNode.mpn_ListNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_MainMenuNode.mpn_Listtree, + MUIM_NListtree_Insert, GetLocString(MSGID_MAINMENUNAME), + &mie, + MUIV_NListtree_Insert_ListNode_Root, MUIV_NListtree_Insert_PrevNode_Tail, + MUIV_NListtree_Insert_Flag_Active | TNF_OPEN | TNF_LIST); + + mie.mie_MenuFlags = LLISTFLGF_NotRemovable | LLISTFLGF_NameNotSetable | LLISTFLGF_MayNotHaveChildren | LLISTFLGF_PopupMenu; + inst->mpb_PopMenuNode[POPMENUINDEX_Disk].mpn_Listtree = GetMenuEntryListtree(inst); + inst->mpb_PopMenuNode[POPMENUINDEX_Disk].mpn_ListNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_PopMenuNode[POPMENUINDEX_Disk].mpn_Listtree, + MUIM_NListtree_Insert, GetLocString(MSGID_POPMENUNAME1), + &mie, + MUIV_NListtree_Insert_ListNode_Root, MUIV_NListtree_Insert_PrevNode_Tail, + TNF_OPEN | TNF_LIST); + + mie.mie_MenuFlags = LLISTFLGF_NotRemovable | LLISTFLGF_NameNotSetable | LLISTFLGF_MayNotHaveChildren | LLISTFLGF_PopupMenu; + inst->mpb_PopMenuNode[POPMENUINDEX_Drawer].mpn_Listtree = GetMenuEntryListtree(inst); + inst->mpb_PopMenuNode[POPMENUINDEX_Drawer].mpn_ListNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_PopMenuNode[POPMENUINDEX_Drawer].mpn_Listtree, + MUIM_NListtree_Insert, GetLocString(MSGID_POPMENUNAME2), + &mie, + MUIV_NListtree_Insert_ListNode_Root, MUIV_NListtree_Insert_PrevNode_Tail, + TNF_OPEN | TNF_LIST); + + mie.mie_MenuFlags = LLISTFLGF_NotRemovable | LLISTFLGF_NameNotSetable | LLISTFLGF_MayNotHaveChildren | LLISTFLGF_PopupMenu; + inst->mpb_PopMenuNode[POPMENUINDEX_ToolProject].mpn_Listtree = GetMenuEntryListtree(inst); + inst->mpb_PopMenuNode[POPMENUINDEX_ToolProject].mpn_ListNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_PopMenuNode[POPMENUINDEX_ToolProject].mpn_Listtree, + MUIM_NListtree_Insert, GetLocString(MSGID_POPMENUNAME3), + &mie, + MUIV_NListtree_Insert_ListNode_Root, MUIV_NListtree_Insert_PrevNode_Tail, + TNF_OPEN | TNF_LIST); + + mie.mie_MenuFlags = LLISTFLGF_NotRemovable | LLISTFLGF_NameNotSetable | LLISTFLGF_MayNotHaveChildren | LLISTFLGF_PopupMenu; + inst->mpb_PopMenuNode[POPMENUINDEX_Trashcan].mpn_Listtree = GetMenuEntryListtree(inst); + inst->mpb_PopMenuNode[POPMENUINDEX_Trashcan].mpn_ListNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_PopMenuNode[POPMENUINDEX_Trashcan].mpn_Listtree, + MUIM_NListtree_Insert, GetLocString(MSGID_POPMENUNAME4), + &mie, + MUIV_NListtree_Insert_ListNode_Root, MUIV_NListtree_Insert_PrevNode_Tail, + TNF_OPEN | TNF_LIST); + + mie.mie_MenuFlags = LLISTFLGF_NotRemovable | LLISTFLGF_NameNotSetable | LLISTFLGF_MayNotHaveChildren | LLISTFLGF_PopupMenu; + inst->mpb_PopMenuNode[POPMENUINDEX_Window].mpn_Listtree = inst->mpb_Objects[OBJNDX_MainListTree]; + inst->mpb_PopMenuNode[POPMENUINDEX_Window].mpn_ListNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_PopMenuNode[POPMENUINDEX_Window].mpn_Listtree, + MUIM_NListtree_Insert, GetLocString(MSGID_POPMENUNAME5), + &mie, + MUIV_NListtree_Insert_ListNode_Root, MUIV_NListtree_Insert_PrevNode_Tail, + TNF_OPEN | TNF_LIST); + + mie.mie_MenuFlags = LLISTFLGF_NotRemovable | LLISTFLGF_NameNotSetable | LLISTFLGF_MayNotHaveChildren | LLISTFLGF_PopupMenu; + inst->mpb_PopMenuNode[POPMENUINDEX_AppIcon].mpn_Listtree = GetMenuEntryListtree(inst); + inst->mpb_PopMenuNode[POPMENUINDEX_AppIcon].mpn_ListNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_PopMenuNode[POPMENUINDEX_AppIcon].mpn_Listtree, + MUIM_NListtree_Insert, GetLocString(MSGID_POPMENUNAME6), + &mie, + MUIV_NListtree_Insert_ListNode_Root, MUIV_NListtree_Insert_PrevNode_Tail, + TNF_OPEN | TNF_LIST); + + mie.mie_MenuFlags = LLISTFLGF_NotRemovable | LLISTFLGF_NameNotSetable | LLISTFLGF_MayNotHaveChildren | LLISTFLGF_PopupMenu; + inst->mpb_PopMenuNode[POPMENUINDEX_Desktop].mpn_Listtree = inst->mpb_Objects[OBJNDX_MainListTree]; + inst->mpb_PopMenuNode[POPMENUINDEX_Desktop].mpn_ListNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_PopMenuNode[POPMENUINDEX_Desktop].mpn_Listtree, + MUIM_NListtree_Insert, GetLocString(MSGID_POPMENUNAME7), + &mie, + MUIV_NListtree_Insert_ListNode_Root, MUIV_NListtree_Insert_PrevNode_Tail, + TNF_OPEN | TNF_LIST); +} + +//---------------------------------------------------------------------------- + +static Object *GetMenuEntryListtree(struct MenuPrefsInst *inst) +{ + return inst->mpb_Objects[inst->mpb_HideObsoletePopupMenus ? OBJNDX_HiddenListTree : OBJNDX_MainListTree]; +} + +//---------------------------------------------------------------------------- + +static struct MUI_NListtree_TreeNode *GetParentNodeForMenu(struct MenuPrefsInst *inst, struct MUI_NListtree_TreeNode **PrevNode) +{ + struct MUI_NListtree_TreeNode *ParentNode; + BOOL Finished = FALSE; + + *PrevNode = (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_PrevNode_Tail; + + ParentNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, 0, MUIV_NListtree_GetEntry_Position_Active, 0); + + while (ParentNode && !Finished) + { + struct MenuListEntry *mle = (struct MenuListEntry *) ParentNode->tn_User; + + switch (mle->llist_EntryType) + { + case SCAMENUTYPE_MainMenu: + case SCAMENUTYPE_Menu: + case SCAMENUTYPE_ToolsMenu: + Finished = TRUE; + break; + + case SCAMENUTYPE_MenuItem: + case SCAMENUTYPE_Command: + *PrevNode = ParentNode; + ParentNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, ParentNode, + MUIV_NListtree_GetEntry_Position_Parent, 0); + break; + } + } + + return ParentNode; +} + +//---------------------------------------------------------------------------- + +static struct MUI_NListtree_TreeNode *GetParentNodeForMenuItem(struct MenuPrefsInst *inst, struct MUI_NListtree_TreeNode **PrevNode) +{ + struct MUI_NListtree_TreeNode *ParentNode; + + *PrevNode = (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_PrevNode_Tail; + + ParentNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, 0, MUIV_NListtree_GetEntry_Position_Active, 0); + + while (ParentNode) + { + struct MenuListEntry *mle = (struct MenuListEntry *) ParentNode->tn_User; + + if ((SCAMENUTYPE_MainMenu == mle->llist_EntryType) + && (mle->llist_Flags & LLISTFLGF_MayNotHaveChildren)) + break; + + if (SCAMENUTYPE_Menu == mle->llist_EntryType) + break; + if (SCAMENUTYPE_ToolsMenu == mle->llist_EntryType) + break; + + *PrevNode = ParentNode; + ParentNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, ParentNode, + MUIV_NListtree_GetEntry_Position_Parent, 0); + } + + return ParentNode; +} + +//---------------------------------------------------------------------------- + +static BOOL MayPasteOnto(struct MenuPrefsInst *inst, + struct MUI_NListtree_TreeNode *tnTo, struct MUI_NListtree_TreeNode *tnFrom) +{ + const struct MenuListEntry *fteFrom = (const struct MenuListEntry *) tnFrom->tn_User; + const struct MenuListEntry *fteTo = (const struct MenuListEntry *) tnTo->tn_User; + BOOL MayPaste = FALSE; + + d1(kprintf("%s/%ld: fteTo=%08lx <%s> %ld fteFrom=%08lx <%s> %ld\n", __FUNC__, __LINE__, \ + fteTo, tnTo->tn_Name, fteTo->llist_EntryType, fteFrom, tnFrom->tn_Name, fteFrom->llist_EntryType)); + + if (fteTo->llist_EntryType >= ENTRYTYPE_MAX || fteFrom->llist_EntryType >= ENTRYTYPE_MAX) + return FALSE; + + d1(kprintf("%s/%ld: MayPaste=%ld\n", __FUNC__, __LINE__, \ + MayPasteIntoMatrix[fteTo->llist_EntryType][fteFrom->llist_EntryType])); + + if (MayPasteIntoMatrix[fteTo->llist_EntryType][fteFrom->llist_EntryType]) + { + MayPaste = TRUE; + + if ((SCAMENUTYPE_MainMenu == fteTo->llist_EntryType) + && (SCAMENUTYPE_Menu != fteFrom->llist_EntryType) + && !IsPopupMenu(inst, tnTo)) + { + // Only menus may be dropped onto Main menu + MayPaste = FALSE; + } + if ( 0 == strlen(tnTo->tn_Name) ) + { + // Nothing may be dropped onto a separator + MayPaste = FALSE; + } + } + + return MayPaste; +} + +//---------------------------------------------------------------------------- + +static struct MUI_NListtree_TreeNode *MayPasteBelow(struct MenuPrefsInst *inst, + struct MUI_NListtree_TreeNode *tnTo, struct MUI_NListtree_TreeNode *tnFrom) +{ + const struct MenuListEntry *fteFrom = (const struct MenuListEntry *) tnFrom->tn_User; + const struct MenuListEntry *fteTo = (const struct MenuListEntry *) tnTo->tn_User; + struct MUI_NListtree_TreeNode *tn; + BOOL Result = FALSE; + + d1(KPrintF("%s/%ld: START fteTo=%08lx <%s> %ld fteFrom=%08lx <%s> %ld\n", __FUNC__, __LINE__, \ + fteTo, tnTo->tn_Name, fteTo->llist_EntryType, fteFrom, tnFrom->tn_Name, fteFrom->llist_EntryType)); + + do { + if (fteTo->llist_EntryType >= ENTRYTYPE_MAX || fteFrom->llist_EntryType >= ENTRYTYPE_MAX) + break; + + if (tnTo->tn_Flags & TNF_OPEN) + { + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + tnTo, + MUIV_NListtree_GetEntry_Position_Head, + MUIV_NListtree_GetEntry_Flag_Visible); + d1(KPrintF("%s/%ld: tn=%08lx\n", __FUNC__, __LINE__, tn)); + + if (tn) + break; + } + + do { + tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + tnTo, + MUIV_NListtree_GetEntry_Position_Next, + MUIV_NListtree_GetEntry_Flag_SameLevel | MUIV_NListtree_GetEntry_Flag_Visible); + d1(KPrintF("%s/%ld: tn=%08lx\n", __FUNC__, __LINE__, tn)); + if (tn) + break; + + tnTo = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, + tnTo, + MUIV_NListtree_GetEntry_Position_Parent, + MUIV_NListtree_GetEntry_Flag_Visible); + d1(KPrintF("%s/%ld: tnTo=%08lx\n", __FUNC__, __LINE__, tnTo)); + + if (tnTo) + { + fteTo = (const struct MenuListEntry *) tnTo->tn_User; + + Result = MayPasteAfterMatrix[fteTo->llist_EntryType][fteFrom->llist_EntryType]; + } + } while (tnTo && !Result); + + if (NULL == tnTo) + break; + + Result = MayPasteAfterMatrix[fteTo->llist_EntryType][fteFrom->llist_EntryType]; + } while (0); + + d1(KPrintF("%s/%ld: END MayPaste=%ld\n", __FUNC__, __LINE__, Result)); + + return Result ? tnTo : NULL; +} + +//---------------------------------------------------------------------------- + +#ifdef __amigaos4__ + +static char *stpblk(const char *q) +{ + while (q && *q && isspace((int) *q)) + q++; + + return (char *) q; +} + +#elif !defined(__SASC) && !defined(__AROS__) +// Replacement for SAS/C library functions + +#if !defined(__MORPHOS__) + +static char *stpblk(const char *q) +{ + while (q && *q && isspace((int) *q)) + q++; + + return (char *) q; +} + +static size_t stccpy(char *dest, const char *src, size_t MaxLen) +{ + size_t Count = 0; + + while (*src && MaxLen > 1) + { + *dest++ = *src++; + MaxLen--; + Count++; + } + *dest = '\0'; + Count++; + + return Count; +} +#endif /*__MORPHOS__*/ + +void exit(int x) +{ + (void) x; + while (1) + ; +} + +APTR _WBenchMsg; + +#endif + diff --git a/scalos/Plugins/Prefs/Menu/MenuPrefs.h b/scalos/Plugins/Prefs/Menu/MenuPrefs.h new file mode 100644 index 000000000..7ce84c40f --- /dev/null +++ b/scalos/Plugins/Prefs/Menu/MenuPrefs.h @@ -0,0 +1,216 @@ +// MenuPrefs.h +// $Date$ +// $Revision$ + + +#ifndef SCALOS_MENUPREFS_H +#define SCALOS_MENUPREFS_H + +#include +#include +#include + + +#define DEFAULT_STACKSIZE 16384 // default stack size for new menu command entries + +enum HookIndex +{ + HOOKNDX_TreeConstruct, + HOOKNDX_TreeDestruct, + HOOKNDX_TreeDisplay, + + HOOKNDX_CmdListConstruct, + HOOKNDX_CmdListDestruct, + HOOKNDX_CmdListDisplay, + HOOKNDX_CmdListCompare, + HOOKNDX_CmdListPopupOpen, + + HOOKNDX_ImagePopAslFileStart, + + HOOKNDX_ResetToDefaults, + HOOKNDX_Open, + HOOKNDX_LastSaved, + HOOKNDX_Restore, + HOOKNDX_SaveAs, + HOOKNDX_Merge, + HOOKNDX_ImportTD, + HOOKNDX_ImportP, + HOOKNDX_RenameEntry, + HOOKNDX_ChangeHotkey, + HOOKNDX_ChangeEntry3, + HOOKNDX_ChangeUnselectedImage, + HOOKNDX_ChangeSelectedImage, + + HOOKNDX_SelectEntry, + HOOKNDX_PopButton, + HOOKNDX_AddMenu, + HOOKNDX_AddCommand, + HOOKNDX_AddMenuItem, + HOOKNDX_RemoveEntry, + HOOKNDX_About, + HOOKNDX_CollapseSelected, + HOOKNDX_ExpandSelected, + HOOKNDX_CollapseAll, + HOOKNDX_ExpandAll, + HOOKNDX_CmdSelected, + HOOKNDX_ContextMenuTrigger, + HOOKNDX_AppMessage, + HOOKNDX_SettingsChanged, + HOOKNDX_AslIntuiMsg, + HOOKNDX_HideObsolete, + + HOOKNDX_MenuCopy, + HOOKNDX_MenuCut, + HOOKNDX_MenuPaste, + + HOOKNDX_MAX +}; + +enum ObjectIndex +{ + OBJNDX_APP_Main, + OBJNDX_WIN_Main, + + OBJNDX_Group_Main, + OBJNDX_Group_List, + OBJNDX_Group_Buttons1, + OBJNDX_Group_Name, + OBJNDX_Group_String, + OBJNDX_Group_CmdProperties, + + OBJNDX_StringHotkey, + OBJNDX_CycleGad, + OBJNDX_NewCommandButton, + OBJNDX_MainListView, + OBJNDX_MainListTree, + OBJNDX_HiddenListTree, + OBJNDX_ListTreeClipboard, + OBJNDX_NameString, + OBJNDX_NewMenuButton, + OBJNDX_NewItemButton, + OBJNDX_DelButton, + OBJNDX_StringStack, + OBJNDX_CheckArgs, + OBJNDX_SliderPriority, + OBJNDX_StringCmd, + OBJNDX_PopObject, + OBJNDX_Popbutton, + OBJNDX_CmdListView, + OBJNDX_Lamp_Changed, + OBJNDX_PopAsl_UnselectedImage, + OBJNDX_PopAsl_SelectedImage, + OBJNDX_DtImage_UnselectedImage, + OBJNDX_DtImage_SelectedImage, + + OBJNDX_ContextMenu, + OBJNDX_Menu_HideObsolete, + OBJNDX_Menu_Copy, + OBJNDX_Menu_Cut, + OBJNDX_Menu_Paste, + OBJNDX_Menu_CollapseSelected, + OBJNDX_Menu_ExpandSelected, + + OBJNDX_MAX +}; + +enum PopupMenuNodeIndex +{ + POPMENUINDEX_Disk, + POPMENUINDEX_Drawer, + POPMENUINDEX_ToolProject, + POPMENUINDEX_Trashcan, + POPMENUINDEX_Window, + POPMENUINDEX_AppIcon, + POPMENUINDEX_Desktop, + POPMENUINDEX_MAX // MUST be last entry!! +}; + +enum DefaultMenuParentNode + { + DEFAULTPARENTNODE_MainMenu, + DEFAULTPARENTNODE_Popup_Disk, + DEFAULTPARENTNODE_Popup_Drawer, + DEFAULTPARENTNODE_Popup_ToolProject, + DEFAULTPARENTNODE_Popup_Trashcan, + DEFAULTPARENTNODE_Popup_Window, + DEFAULTPARENTNODE_Popup_AppIcon, + DEFAULTPARENTNODE_Popup_Desktop, + DEFAULTPARENTNODE_LastInsertedMenu, + DEFAULTPARENTNODE_LastInsertedMenuItem, + DEFAULTPARENTNODE_LastInserted, + }; + +struct DefaultMenuEntry + { + enum ScalosMenuType dme_EntryType; + ULONG dme_Level; + ULONG dme_NameId; + ULONG dme_MenuShortId; + enum DefaultMenuParentNode dme_ParentNode; + enum ScalosMenuCommandType dme_CmdType; + BYTE dme_CmdPri; + UBYTE dme_CmdFlags; + ULONG dme_CmdStackSize; + }; + +struct MenuPrefsPopMenuNode + { + Object *mpn_Listtree; + struct MUI_NListtree_TreeNode *mpn_ListNode; + }; + +struct MenuPrefsInst +{ + ULONG mpb_fCreateIcons; + CONST_STRPTR mpb_ProgramName; + + struct Hook mpb_Hooks[HOOKNDX_MAX]; + APTR mpb_Objects[OBJNDX_MAX]; + + ULONG mpb_TreeImageIndex; + ULONG mpb_PageIsActive; + BOOL mpb_Changed; + BOOL mpb_QuietFlag; + BOOL mpb_HideObsoletePopupMenus; + + BOOL mpb_MenuTreeMayDrop; + + struct Screen *mpb_WBScreen; + + struct FileRequester *mpb_LoadReq; + struct FileRequester *mpb_SaveReq; + + struct MenuPrefsPopMenuNode mpb_MainMenuNode; + struct MenuPrefsPopMenuNode mpb_PopMenuNode[POPMENUINDEX_MAX]; +}; + +//---------------------------------------------------------------------------- + +#ifndef Sizeof +#define Sizeof(array) (sizeof(array)/sizeof(array[0])) +#endif + +#if defined(__SASC) +int snprintf(char *, size_t, const char *, /*args*/ ...); +int vsnprintf(char *, size_t, const char *, va_list ap); +#endif /* __SASC */ + +//---------------------------------------------------------------------------- + +#define d1(x) ; +#define d2(x) x; + +// from debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +//---------------------------------------------------------------------------- + +struct ScalosMenu_LocaleInfo +{ + APTR li_LocaleBase; + APTR li_Catalog; + struct LocaleIFace *li_ILocale; +}; + +#endif /* SCALOS_MENUPREFS_H */ diff --git a/scalos/Plugins/Prefs/Menu/MenuPrefsImage.h b/scalos/Plugins/Prefs/Menu/MenuPrefsImage.h new file mode 100644 index 000000000..9f4de6e28 --- /dev/null +++ b/scalos/Plugins/Prefs/Menu/MenuPrefsImage.h @@ -0,0 +1,56 @@ +static const ULONG MenuPrefs_colors[48] = +{ + 0x66666666,0x66666666,0x66666666, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0x11111111,0x55555555,0xdddddddd, + 0x55555555,0xaaaaaaaa,0x55555555, + 0x66666666,0xcccccccc,0x44444444, + 0x77777777,0xaaaaaaaa,0xffffffff, + 0x44444444,0xcccccccc,0xffffffff, + 0xffffffff,0x00000000,0x34343434, + 0xffffffff,0xeeeeeeee,0x00000000, + 0xcacacaca,0xd9d9d9d9,0xffffffff, + 0x99999999,0xbbbbbbbb,0xeeeeeeee, + 0x88888888,0xdddddddd,0xffffffff, + 0xeeeeeeee,0xeeeeeeee,0x99999999, + 0xcccccccc,0xcccccccc,0xcccccccc, + 0xeeeeeeee,0xdddddddd,0xdddddddd, + 0xffffffff,0xffffffff,0xffffffff, +}; + +#define MENUPREFS_WIDTH 20 +#define MENUPREFS_HEIGHT 24 +#define MENUPREFS_DEPTH 4 +#define MENUPREFS_COMPRESSION 0 +#define MENUPREFS_MASKING 2 + +//static const struct BitMapHeader MenuPrefs_header = +//{ 20,24,0,0,4,2,0,0,0,44,44,320,256 }; + +static const UBYTE MenuPrefs_body[384] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x3f,0xff,0x00,0x00,0x3f,0xff,0x00,0x00,0x3f,0xff,0x00,0x00,0x3f, +0xff,0x00,0x00,0x3f,0xfc,0x00,0x00,0x37,0xff,0x00,0x00,0x3f,0xff,0x00,0x00, +0x37,0xff,0x00,0x00,0x36,0x0a,0x00,0x00,0x3f,0xfb,0x00,0x00,0x37,0xff,0x00, +0x00,0x3f,0xfb,0x00,0x00,0x3f,0xfe,0x00,0x00,0x3f,0xff,0x00,0x00,0x3f,0xff, +0x00,0x00,0x3f,0xff,0x00,0x00,0x33,0xae,0x00,0x00,0x37,0xff,0x00,0x00,0x3f, +0xff,0x00,0x00,0x3f,0xff,0x00,0x00,0x3f,0xcb,0x00,0x00,0x3e,0x3a,0x00,0x00, +0x37,0xff,0x00,0x00,0x37,0xfb,0x00,0x00,0x3f,0xff,0x00,0x00,0x3f,0xfe,0x00, +0x00,0x3f,0xff,0x00,0x00,0x3f,0xff,0x00,0x00,0x37,0x0f,0x00,0x00,0x3f,0xfe, +0x00,0x00,0x37,0xff,0x00,0x00,0x37,0xff,0x00,0x00,0x37,0xdb,0x00,0x00,0x3e, +0x2a,0x00,0x00,0x3f,0x7f,0x00,0x00,0x3f,0x7b,0x00,0x00,0x3f,0xff,0x00,0x00, +0x3f,0xff,0x00,0x00,0x3f,0xff,0x00,0x00,0x3f,0xf0,0x00,0x00,0x32,0x0f,0x00, +0x00,0x33,0xfe,0x00,0x00,0x33,0xff,0x00,0x00,0x3f,0xf1,0x00,0x00,0x37,0xff, +0x00,0x00,0x36,0x0e,0x00,0x00,0x37,0xff,0x00,0x00,0x37,0xf1,0x00,0x00,0x20, +0x09,0x00,0x00,0x3f,0xff,0x00,0x00,0x3f,0xff,0x00,0x00,0x3f,0xf6,0x00,0x00, +0x3f,0xff,0x80,0x00,0x3f,0xfe,0x80,0x00,0x3f,0xff,0x80,0x00,0x3f,0xff,0x00, +0x00,0x3e,0x01,0x40,0x00,0x37,0xfe,0x40,0x00,0x37,0xff,0x40,0x00,0x3f,0xff, +0x00,0x00,0x31,0xf1,0x00,0x00,0x3e,0x0e,0x00,0x00,0x37,0xff,0x00,0x00,0x3b, +0xff,0x00,0x00,0x3c,0x01,0x00,0x00,0x3f,0xfe,0x00,0x00,0x3f,0xff,0x00,0x00, +0x3f,0xff,0x00,0x00,0x38,0x41,0x00,0x00,0x3f,0xbe,0x00,0x00,0x3f,0xff,0x00, +0x00,0x3f,0xff,0x00,0x00,0x25,0xf1,0x00,0x00,0x32,0x0e,0x00,0x00,0x36,0x1f, +0x00,0x00,0x36,0x1f,0x00,0x00,0x3f,0xff,0x00,0x00,0x20,0x00,0x00,0x00,0x3f, +0xff,0x00,0x00,0x3f,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, }; diff --git a/scalos/Plugins/Prefs/Menu/NoDebug b/scalos/Plugins/Prefs/Menu/NoDebug new file mode 100755 index 000000000..49ed68d29 --- /dev/null +++ b/scalos/Plugins/Prefs/Menu/NoDebug @@ -0,0 +1,3 @@ +; NoDebug +; 23 Dec 2001 16:17:11 +splat -s -o "d2(" "d1(" #?.c diff --git a/scalos/Plugins/Prefs/Menu/config.mk b/scalos/Plugins/Prefs/Menu/config.mk new file mode 100755 index 000000000..49844979f --- /dev/null +++ b/scalos/Plugins/Prefs/Menu/config.mk @@ -0,0 +1,78 @@ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +DATATYPESMCC_DIR = $(TOPLEVEL)/common/DataTypesMCC +COMMON_DIR = $(TOPLEVEL)/common/Plugin + +INCLUDES += -I$(DATATYPESMCC_DIR) -I$(COMMON_DIR) + +SCALOS_LOCALE = $(OBJDIR)/ScalosMenu_locale.h + +CFLAGS += -D SCALOSLOCALE=$(SCALOS_LOCALE) + +vpath %.c $(COMMON_DIR) + +############################################################################## + +include $(COMMON_DIR)/config.mk + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += -nostartfiles \ + -lmempools +# --verbose + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += -nostartfiles \ +# + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +DEFINES += -DMUI_OBSOLETE + +LFLAGS += -nostartfiles \ +# + + +else + +############################################################################### +# AmigaOS + +LFLAGS += -lscalos \ + -lpreferences \ + -liconobject \ + -lmempools \ + -ldebug \ + -lmui \ + -lstack \ + -lnix \ + -lnixmain \ + -lamiga21 \ + -lamiga \ + -lstubs \ + +endif +endif +endif diff --git a/scalos/Plugins/Prefs/Menu/makefile b/scalos/Plugins/Prefs/Menu/makefile new file mode 100644 index 000000000..009b4fe27 --- /dev/null +++ b/scalos/Plugins/Prefs/Menu/makefile @@ -0,0 +1,152 @@ +# makefile für Scalos Menu.prefsplugin +# $Date$ +# $Revision$ +############################################################# + +SDPATH = // + +SUBDIRMAKE = $(MAKE) -s -C +FLEXCAT = FlexCat +CATCOMP = CatComp +FLEXCAT = FlexCat +AS = phxAss +LD = slink +CC = sc +ECHO = echo +LIBS = LIB:sc.lib \ + LIB:debug.lib \ + LIB:mempools.lib \ + ///SAS-lib/snprintf.lib \ + LIB:amiga.lib +LDFLAGS = quiet batch noicons +PRECOMP = Include:all.gst +OBJDIR = .sasobj +BINDIR = .bin_os3 +PREFSPATH = ../../../Prefs/Menu +DATATYPESMCC_DIR = ../../../common/DataTypesMCC +COMMON_DIR = ../../../common/Plugin + +.SUFFIXES: .asm + +############################################################# + +CSRCS = $(COMMON_DIR)/plugin-classic.c \ + MenuPrefs.c \ + DefaultMenu.c \ + $(DATATYPESMCC_DIR)/DataTypesMCC.c \ + +############################################################# + +PLUGIN = Menu.prefsplugin +PLUGINDBG = $(PLUGIN).debug +CAT_FILE = Scalos/ScalosMenu.catalog +DESTTOOL = Scalos:Prefs/ +DESTCAT = Locale:Catalogs +SRCCAT = $(subst ../,/,$(PREFSPATH)) +SCALOS_LOCALE = $(OBJDIR)/ScalosMenu_locale.h +CATCOMPHEADER = $(SCALOS_LOCALE) + +CATS = dansk \ + deutsch \ + español \ + français \ + italiano \ + svenska \ + ÃeÓtina + +ALLCATS = $(foreach cat,$(CATS),$(SRCCAT)/catalogs/$(cat)/$(CAT_FILE)) + +############################################################# + +CFLAGS = optimize nostackcheck nover dbg=s DATA=far \ + define SCALOSLOCALE=$(SCALOS_LOCALE) \ + idlen=64 idir=///include \ + idir=$(subst ../,/,$(DATATYPESMCC_DIR)) \ + idir=$(subst ../,/,$(PREFSPATH)) \ + idir=///common/Plugin +AFLAGS = quiet DS opt=NRQB NOEXE linedebug I=SC:Assembler_Headers +#AFLAGS = -t -iINCLUDE: + + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +XSRCS = $(notdir $(CSRCS)) +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(XSRCS:%.c=$(OBJDIR)/$(notdir %).o) + +############################################################# + +All: $(BINDIR)/$(PLUGIN) \ + $(BINDIR)/$(PLUGINDBG) \ + allcatalogs +# install +# clean + +############################################################# + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-classic.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/DataTypesMCC.o : $(DATATYPESMCC_DIR)/DataTypesMCC.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $*.c objectname $@ + +############################################################# + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-common.c \ + plugin_data.h $(COMMON_DIR)/plugin.h + +$(OBJDIR)/DataTypesMCC.o: $(DATATYPESMCC_DIR)/DataTypesMCC.c \ + $(DATATYPESMCC_DIR)/DataTypesMCC.h + +$(OBJDIR)/MenuPrefs.o : MenuPrefs.h MenuPrefsImage.h \ + $(SCALOS_LOCALE) plugin_data.h $(COMMON_DIR)/plugin.h + +$(OBJDIR)/DefaultMenu.o : DefaultMenu.c MenuPrefs.h \ + $(SCALOS_LOCALE) + +############################################################# + +$(CATCOMPHEADER) : $(PREFSPATH)/ScalosMenu.cd + @printf '\033[32mMake CatComp header: \033[31m\033[1m$@ \033[32mfrom \033[31m$<\033[0m\n' + $(FLEXCAT) $(subst ../,/,$<) $@=$(SDPATH)/CatComp_h.sd + +$(BINDIR)/$(PLUGIN) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) to $@ FROM $(OBJS) lib $(LIBS) $(LDFLAGS) STRIPDEBUG + +$(BINDIR)/$(PLUGINDBG) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) to $@ FROM $(OBJS) lib $(LIBS) $(LDFLAGS) ADDSYM + +############################################################# + +install: + @avail flush + @printf '\033[32mInstall: \033[31m\033[1m$(PLUGIN)\033[0m\n' + @copy $(BINDIR)/$(PLUGIN) $(DESTTOOL) + @printf '\033[32mInstall: \033[31m\033[1m$(CAT_FILE)\033[0m\n' + -@$(foreach cat,$(CATS),copy "$(SRCCAT)/catalogs/$(cat)/$(CAT_FILE)" "$(DESTCAT)/$(cat)/Scalos" clone;) + +############################################################# + +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + -@delete $(BINDIR)/$(PLUGIN) $(BINDIR)/$(PLUGINDBG) $(OBJS) $(subst ../,/,$(CATCOMPHEADER)) $(ALLCATS) + @printf '\033[0m' + +############################################################# + +# make all Scalos preferences .catalogs +allcatalogs: + -@$(foreach cat,$(CATS),$(SUBDIRMAKE) $(PREFSPATH)/catalogs/$(cat)/Scalos;) + +############################################################# + diff --git a/scalos/Plugins/Prefs/Menu/makefile-new b/scalos/Plugins/Prefs/Menu/makefile-new new file mode 100755 index 000000000..9fb295ff0 --- /dev/null +++ b/scalos/Plugins/Prefs/Menu/makefile-new @@ -0,0 +1,100 @@ +# $Date: 2011-08-04 18:43:49 +0200 (Do, 04. Aug 2011) $ +# $Revision: 818 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../../.. +endif + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + PARENTDIR=/ + SDPATH=// +else + PARENTDIR=../ + SDPATH=../../.. +endif + + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(BEGIN_OBJS) \ + $(OBJDIR)/MenuPrefs.o \ + $(OBJDIR)/DataTypesMCC.o \ + $(OBJDIR)/DefaultMenu.o \ + $(END_OBJS) + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Targets +# + +NAME = Menu.prefsplugin +NAME_DB = $(NAME).debug + +############################################################################## + +PREFSDIR = ../../../Prefs/Menu + +############################################################################## +# +# Some lame deps + +$(OBJDIR)/%.o: $(DATATYPESMCC_DIR)/%.c + @$(run-cc) + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) + +############################################################################## + +MenuPrefs.c DefaultMenu.c : $(SCALOS_LOCALE) + +$(SCALOS_LOCALE) : $(PREFSDIR)/ScalosMenu.cd + @$(ECHO) "FlexCat $@" + $(FLEXCAT) $(subst ../,$(PARENTDIR),$<) $@=$(SDPATH)/CatComp_h.sd + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + -@$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) Scalos:Prefs/ clone + @avail flush + + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* \ + $(SCALOS_LOCALE) + +############################################################################## + diff --git a/scalos/Plugins/Prefs/Menu/plugin_data.h b/scalos/Plugins/Prefs/Menu/plugin_data.h new file mode 100644 index 000000000..aeb381bcf --- /dev/null +++ b/scalos/Plugins/Prefs/Menu/plugin_data.h @@ -0,0 +1,27 @@ +// plugin_data.h +// $Date$ +// $Revision$ + +#ifndef PLUGIN_DATA_H_INCLUDED +#define PLUGIN_DATA_H_INCLUDED + +#include +#include + +#define PLUGIN_TYPE PREFS + +#define LIB_VERSION 40 +#define LIB_REVISION 20 + +#define LIB_NAME "Menu.prefsplugin" +#define LIB_VERSTRING "$VER: " LIB_NAME " " \ + STR(LIB_VERSION) "." STR(LIB_REVISION) \ + " " __DATE__ \ + COMPILER_STRING " ©2003" CURRENTYEAR \ + " The Scalos Team" + +//---------------------------------------------------------------------------- +// code and includes to define the structs and functions used above + +#endif /* PLUGUN_DATA_H_INCLUDED */ + diff --git a/scalos/Plugins/Prefs/Palette/NoDebug b/scalos/Plugins/Prefs/Palette/NoDebug new file mode 100755 index 000000000..49ed68d29 --- /dev/null +++ b/scalos/Plugins/Prefs/Palette/NoDebug @@ -0,0 +1,3 @@ +; NoDebug +; 23 Dec 2001 16:17:11 +splat -s -o "d2(" "d1(" #?.c diff --git a/scalos/Plugins/Prefs/Palette/PalettePrefs.c b/scalos/Plugins/Prefs/Palette/PalettePrefs.c new file mode 100644 index 000000000..5ce47aa03 --- /dev/null +++ b/scalos/Plugins/Prefs/Palette/PalettePrefs.c @@ -0,0 +1,3208 @@ +// PalettePrefs.c +// $Date$ +// $Revision$ + +#ifdef __AROS__ +#define MUIMASTER_YES_INLINE_STDARG +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef __AROS__ +#define NO_INLINE_STDARG +#endif +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "PalettePrefs.h" +#include "DataTypesMCC.h" + +#define ScalosPalette_NUMBERS +#define ScalosPalette_ARRAY +#define ScalosPalette_CODE +#include STR(SCALOSLOCALE) + +#include "plugin.h" + +//---------------------------------------------------------------------------- + +#ifdef __AROS__ +#define NewColorAdjustObject BOOPSIOBJMACRO_START(NewColorAdjustClass->mcc_Class) +#define NewPalettePenListObject BOOPSIOBJMACRO_START(NewPalettePenListClass->mcc_Class) +#define NewScalosPenListObject BOOPSIOBJMACRO_START(NewScalosPenListClass->mcc_Class) +#define myNListObject BOOPSIOBJMACRO_START(myNListClass->mcc_Class) +#define DataTypesImageObject BOOPSIOBJMACRO_START(DataTypesImageClass->mcc_Class) +#else +#define NewColorAdjustObject NewObject(NewColorAdjustClass->mcc_Class, 0 +#define NewPalettePenListObject NewObject(NewPalettePenListClass->mcc_Class, 0 +#define NewScalosPenListObject NewObject(NewScalosPenListClass->mcc_Class, 0 +#define myNListObject NewObject(myNListClass->mcc_Class, 0 +#define DataTypesImageObject NewObject(DataTypesImageClass->mcc_Class, 0 +#endif + +//---------------------------------------------------------------------------- + +#define IMG(prefix1,PREFIX2) \ + BodychunkObject,\ + MUIA_FixWidth , PREFIX2##_WIDTH ,\ + MUIA_FixHeight , PREFIX2##_HEIGHT,\ + MUIA_Bitmap_Width , PREFIX2##_WIDTH ,\ + MUIA_Bitmap_Height , PREFIX2##_HEIGHT,\ + MUIA_Bodychunk_Depth , PREFIX2##_DEPTH ,\ + MUIA_Bodychunk_Body , (UBYTE *) prefix1##_body,\ + MUIA_Bodychunk_Compression, PREFIX2##_COMPRESSION,\ + MUIA_Bodychunk_Masking , PREFIX2##_MASKING,\ + MUIA_Bitmap_SourceColors , (ULONG *) prefix1##_colors,\ + MUIA_Bitmap_Transparent , 0,\ + End + +//---------------------------------------------------------------------------- + +// from DoLoadDT.c +extern Object *DoLoadDT(STRPTR source, struct RastPort *rast, + struct ColorMap *cmap, + int x, int y, int w, int h, + ULONG FirstTag, ...); + +//---------------------------------------------------------------------------- + +// local data structures + +#define KeyButtonHelp(name,key,HelpText)\ + TextObject,\ + ButtonFrame,\ + MUIA_CycleChain, TRUE, \ + MUIA_Font, MUIV_Font_Button,\ + MUIA_Text_Contents, name,\ + MUIA_Text_PreParse, "\33c",\ + MUIA_Text_HiChar , key,\ + MUIA_ControlChar , key,\ + MUIA_InputMode , MUIV_InputMode_RelVerify,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShortHelp, HelpText,\ + End + +#define CheckMarkHelp(selected, HelpTextID)\ + ImageObject,\ + ImageButtonFrame,\ + MUIA_CycleChain , TRUE, \ + MUIA_InputMode , MUIV_InputMode_Toggle,\ + MUIA_Image_Spec , MUII_CheckMark,\ + MUIA_Image_FreeVert , TRUE,\ + MUIA_Selected , selected,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShowSelState , FALSE,\ + MUIA_ShortHelp , GetLocString(HelpTextID),\ + End + +#define Application_Return_EDIT 0 +#define Application_Return_USE 1001 +#define Application_Return_SAVE 1002 + +#define ID_SPAL MAKE_ID('S','P','A','L') +#define ID_PENS MAKE_ID('P','E','N','S') + + +#define PEN_UNDEFINED (-1) + + +struct NewScalosPenListInst + { + ULONG nspl_fDragging; + }; + +struct PensListConstruct + { + ULONG splc_Red; + ULONG splc_Green; + ULONG splc_Blue; + }; + +struct PensListEntry + { + // Red,Green,Blue MUST be the very first entries! + // (used for MUIA_Coloradjust_RGB) + ULONG sple_Red; + ULONG sple_Green; + ULONG sple_Blue; + + ULONG sple_Index; + }; + +struct ScalosPenListEntry + { + WORD snle_PenIndex; + WORD snle_PenNr; + CONST_STRPTR snle_PenName; + }; + +struct PenListInit + { + WORD pli_PenIndex; + WORD pli_PenNr; + ULONG pli_PenNameID; + }; + +struct RGB + { + ULONG rgb_Red; + ULONG rgb_Green; + ULONG rgb_Blue; + }; + +static const LONG StopChunkList[] = + { + ID_PREF, ID_SPAL, + ID_PREF, ID_PENS, + }; + +//---------------------------------------------------------------------------- + +// aus mempools.lib +#if !defined(__amigaos4__) && !defined(__AROS__) +extern int _STI_240_InitMemFunctions(void); +extern void _STD_240_TerminateMemFunctions(void); +#endif + +//---------------------------------------------------------------------------- + +// local functions + +DISPATCHER_PROTO(PalettePrefs); +static BOOL CreatePalettePrefsObject(struct PalettePrefsInst *inst, struct opSet *ops); +static void DisposePalettePrefsObject(struct PalettePrefsInst *inst); +static Object *CreatePrefsGroup(struct PalettePrefsInst *inst); +static Object *CreatePrefsImage(void); +static void InitHooks(struct PalettePrefsInst *inst); + +static BOOL OpenLibraries(void); +static void CloseLibraries(void); +static STRPTR GetLocString(ULONG MsgId); +static void TranslateNewMenu(struct NewMenu *nm); +//static void TranslateStringArray(STRPTR *stringArray); +DISPATCHER_PROTO(NewColorAdjust); +DISPATCHER_PROTO(NewPalettePenList); +DISPATCHER_PROTO(NewScalosPenList); +static APTR AllocatedPensListConstructFunc(struct Hook *hook, APTR memPool, struct PensListEntry *spleNew); +static void AllocatedPensListDestructFunc(struct Hook *hook, APTR memPool, APTR Entry); +static ULONG AllocatedPensListDisplayFunc(struct Hook *hook, Object *obj, struct NList_DisplayMessage *ndm); +static LONG AllocatedPensListCompareFunc(struct Hook *hook, Object *obj, struct NList_CompareMessage *ncm); +static APTR WBPensListConstructFunc(struct Hook *hook, APTR memPool, struct PensListEntry *spleNew); +static void WBPensListDestructFunc(struct Hook *hook, APTR memPool, APTR Entry); +static ULONG WBPensListDisplayFunc(struct Hook *hook, Object *obj, struct NList_DisplayMessage *ndm); +static LONG WBPensListCompareFunc(struct Hook *hook, Object *obj, struct NList_CompareMessage *ncm); +static APTR ScalosPenListConstructFunc(struct Hook *hook, APTR memPool, struct ScalosPenListEntry *msg); +static void ScalosPenListDestructFunc(struct Hook *hook, APTR memPool, APTR Entry); +static ULONG ScalosPenListDisplayFunc(struct Hook *hook, Object *obj, struct NList_DisplayMessage *ndm); +static LONG ScalosPenListCompareFunc(struct Hook *hook, Object *obj, struct NList_CompareMessage *ncm); +static STRPTR GetLocString(ULONG MsgId); +static void GetWBColorsFunc(struct Hook *hook, Object *pop, Object *win); +static APTR AddPenFunc(struct Hook *hook, Object *o, Msg msg); +static APTR SelectPalettePenFunc(struct Hook *hook, Object *o, Msg msg); +static APTR SelectScalosPenFunc(struct Hook *hook, Object *o, Msg msg); +static APTR ChangePenColorFunc(struct Hook *hook, Object *o, ULONG **msg); +static APTR ResetToDefaultsFunc(struct Hook *hook, Object *o, Msg msg); +static APTR AboutFunc(struct Hook *hook, Object *o, Msg msg); +static APTR OpenFunc(struct Hook *hook, Object *o, Msg msg); +static APTR LastSavedFunc(struct Hook *hook, Object *o, Msg msg); +static APTR RestoreFunc(struct Hook *hook, Object *o, Msg msg); +static APTR SaveAsFunc(struct Hook *hook, Object *o, Msg msg); +static APTR DeletePenFunc(struct Hook *hook, Object *o, Msg msg); +static APTR ContextMenuTriggerHookFunc(struct Hook *hook, Object *o, Msg msg); +static void AslIntuiMsgHookFunc(struct Hook *hook, Object *o, Msg msg); +static void InitPenList(struct PalettePrefsInst *inst); +static LONG ReadPrefsFile(struct PalettePrefsInst *inst, CONST_STRPTR Filename, BOOL Quiet); +static void SearchAndSetPen(struct PalettePrefsInst *inst, const struct ScalosPen *sPen); +static LONG WritePrefsFile(struct PalettePrefsInst *inst, CONST_STRPTR Filename); +static LONG SaveIcon(struct PalettePrefsInst *inst, CONST_STRPTR IconName); +static void UpdatePalettePenCount(struct PalettePrefsInst *inst); +static ULONG GetPenReferenceCount(struct PalettePrefsInst *inst, ULONG PenNr); +static void SetChangedFlag(struct PalettePrefsInst *inst, BOOL changed); +DISPATCHER_PROTO(myNList); +static LONG ColorComp(ULONG Color1, ULONG Color2); +static LONG RGBComp(const struct PensListEntry *sple1, const struct PensListEntry *sple2); + +//---------------------------------------------------------------------------- + +// local data items + +struct Library *MUIMasterBase; +T_LOCALEBASE LocaleBase; +struct GfxBase *GfxBase; +struct Library *IconBase; +struct Library *IFFParseBase; +T_UTILITYBASE UtilityBase; +struct IntuitionBase *IntuitionBase; +struct Library *DataTypesBase; + +#if defined(__GNUC__) && !defined(__amigaos4__) +extern T_UTILITYBASE __UtilityBase; +#endif /* __GNUC__ */ + +#ifdef __amigaos4__ +struct Library *DOSBase; +struct DOSIFace *IDOS; +struct MUIMasterIFace *IMUIMaster; +struct LocaleIFace *ILocale; +struct GraphicsIFace *IGraphics; +struct IconIFace *IIcon; +struct IFFParseIFace *IIFFParse; +struct UtilityIFace *IUtility; +struct IntuitionIFace *IIntuition; +struct DataTypesIFace *IDataTypes; +struct Library *NewlibBase; +struct Interface *INewlib; +#endif + +#ifdef __AROS__ +struct DosLibrary *DOSBase; +#endif + +struct MUI_CustomClass *NewColorAdjustClass; +struct MUI_CustomClass *NewPalettePenListClass; +struct MUI_CustomClass *NewScalosPenListClass; +struct MUI_CustomClass *myNListClass; +struct MUI_CustomClass *DataTypesImageClass; + +struct MUI_CustomClass *PalettePrefsClass; + +static struct Catalog *PalettePrefsCatalog; +static struct Locale *PalettePrefsLocale; + +static ULONG MajorVersion, MinorVersion; + +static ULONG Signature = 0x4711; + +static const struct MUIP_ScalosPrefs_MCCList RequiredMccList[] = + { + { MUIC_Lamp, 11, 1 }, + { MUIC_NListview, 18, 0 }, + { NULL, 0, 0 } + }; + +static const struct Hook PalettePrefsHooks[] = +{ + { { NULL, NULL }, HOOKFUNC_DEF(WBPensListConstructFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(WBPensListDestructFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(WBPensListDisplayFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(WBPensListCompareFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(AllocatedPensListConstructFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(AllocatedPensListDestructFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(AllocatedPensListDisplayFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(AllocatedPensListCompareFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(ScalosPenListConstructFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ScalosPenListDestructFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ScalosPenListDisplayFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ScalosPenListCompareFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(GetWBColorsFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(AddPenFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(SelectPalettePenFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(SelectScalosPenFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ChangePenColorFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ResetToDefaultsFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(AboutFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(OpenFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(LastSavedFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(RestoreFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(SaveAsFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(DeletePenFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ContextMenuTriggerHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(AslIntuiMsgHookFunc), NULL }, +}; + + +static struct NewMenu ContextMenus[] = + { + { NM_TITLE, (STRPTR) MSGID_TITLENAME, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_OPEN, (STRPTR) MSGID_MENU_PROJECT_OPEN_SHORT, 0, 0, (APTR) HOOKNDX_Open }, + { NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_SAVEAS, (STRPTR) MSGID_MENU_PROJECT_SAVEAS_SHORT, 0, 0, (APTR) HOOKNDX_SaveAs }, + { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_ABOUT, NULL, 0, 0, (APTR) HOOKNDX_About }, + + { NM_END, NULL, NULL, 0, 0, 0,}, + }; + +static const struct PenListInit PenListContents[] = + { + { TEXTPEN, 1, MSGID_TEXTPEN }, + { SHINEPEN, 2, MSGID_SHINEPEN }, + { SHADOWPEN, 1, MSGID_SHADOWPEN }, + { FILLPEN, 3, MSGID_HIFILLPEN }, + { FILLTEXTPEN, 1, MSGID_FILLTEXTPEN }, + { BACKGROUNDPEN, 0, MSGID_BGPEN }, + { HIGHLIGHTTEXTPEN, 2, MSGID_HITEXTPEN }, + { BARDETAILPEN, 1, MSGID_BARDETAILPEN }, + { BARBLOCKPEN, 2, MSGID_BARBLOCKPEN }, + { BARTRIMPEN, 1, MSGID_BARTRIMPEN }, + + { -1, 5, MSGID_HSHINEPEN }, + { -2, 4, MSGID_HSHADOWPEN }, + { -18, 1, MSGID_ICONTEXTPEN }, + { -19, 1, MSGID_ICONTEXTPENSEL }, + { -3, 1, MSGID_ICONTEXTOUTLINEPEN }, + { -20, 1, MSGID_ICONTEXTSHADOWPEN }, + { -23, 3, MSGID_ICONTEXTFILESELBG }, + { -4, 3, MSGID_DRAWERTEXT }, + { -5, 2, MSGID_DRAWERTEXTSEL }, + { -6, 3, MSGID_DRAWERBG }, + { -7, 1, MSGID_FILETEXT }, + { -8, 2, MSGID_FILETEXTSEL }, + { -9, 1, MSGID_FILEBG }, + { -10, 0, MSGID_BACKDROPDETAIL }, + { -11, 0, MSGID_BACKDROPBLOCK }, + { -12, 1, MSGID_TOOLTIP_TEXT }, + { -13, 2, MSGID_TOOLTIP_BG }, + { -14, 1, MSGID_DRAGINFO_TEXT }, + { -15, 2, MSGID_DRAGINFO_BG }, + { -16, 4, MSGID_STATUSBAR_BG }, + { -17, 1, MSGID_STATUSBAR_TEXT }, + { -21, 4, MSGID_THUMBNAIL_BG }, + { -22, 4, MSGID_THUMBNAIL_BG_SEL }, + { 0, 0, 0 } + }; + +static const struct PensListEntry DefaultPaletteEntries[] = + { + { 0x95959595, 0x95959595, 0x95959595, 0 }, + { 0x00000000, 0x00000000, 0x00000000, 1 }, + { 0xffffffff, 0xffffffff, 0xffffffff, 2 }, + { 0x56565656, 0x7e7e7e7e, 0xa2a2a2a2, 3 }, + { 0x7b7b7b7b, 0x7b7b7b7b, 0x7b7b7b7b, 4 }, + { 0xafafafaf, 0xafafafaf, 0xafafafaf, 5 }, + { 0xaaaaaaaa, 0x90909090, 0x7c7c7c7c, 6 }, + { 0xffffffff, 0xa9a9a9a9, 0x97979797, 7 }, + }; + +//--------------------------------------------------------------- + +VOID closePlugin(struct PluginBase *PluginBase) +{ + d1(kprintf(__FUNC__ "/%ld:\n", __LINE__)); + + if (DataTypesImageClass) + { + CleanupDtpicClass(DataTypesImageClass); + DataTypesImageClass = NULL; + } + if (myNListClass) + { + MUI_DeleteCustomClass(myNListClass); + myNListClass = NULL; + } + + if (NewColorAdjustClass) + { + MUI_DeleteCustomClass(NewColorAdjustClass); + NewColorAdjustClass = NULL; + } + if (NewScalosPenListClass) + { + MUI_DeleteCustomClass(NewScalosPenListClass); + NewScalosPenListClass = NULL; + } + if (NewPalettePenListClass) + { + MUI_DeleteCustomClass(NewPalettePenListClass); + NewPalettePenListClass = NULL; + } + + if (PalettePrefsCatalog) + { + CloseCatalog(PalettePrefsCatalog); + PalettePrefsCatalog = NULL; + } + if (PalettePrefsLocale) + { + CloseLocale(PalettePrefsLocale); + PalettePrefsLocale = NULL; + } + + if (PalettePrefsClass) + { + MUI_DeleteCustomClass(PalettePrefsClass); + PalettePrefsClass = NULL; + } + + CloseLibraries(); + +#if !defined(__amigaos4__) && !defined(__AROS__) + _STD_240_TerminateMemFunctions(); +#endif +} + + +LIBFUNC_P2(ULONG, LIBSCAGetPrefsInfo, + D0, ULONG, which, + A6, struct PluginBase *, PluginBase); +{ + ULONG result; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: which=%ld\n", __LINE__, which)); + + (void) PluginBase; + + switch(which) + { + case SCAPREFSINFO_GetClass: + result = (ULONG) PalettePrefsClass; + break; + + case SCAPREFSINFO_GetTitle: + result = (ULONG) GetLocString(MSGID_PLUGIN_LIST_TITLE); + break; + + case SCAPREFSINFO_GetTitleImage: + result = (ULONG) CreatePrefsImage(); + break; + + default: + result = 0; + break; + } + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: Result=%08lx\n", __LINE__, result)); + + return result; +} +LIBFUNC_END + +//---------------------------------------------------------------------------- + +DISPATCHER(PalettePrefs) +{ + struct PalettePrefsInst *inst; + ULONG result = 0; + + d1(kprintf("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__)); + + switch(msg->MethodID) + { + case OM_NEW: + obj = (Object *) DoSuperMethodA(cl, obj, msg); + d1(kprintf("%s/%s/%ld: obj=%08lx\n", __FILE__, __FUNC__, __LINE__, obj)); + if (obj) + { + Object *prefsobject = NULL; + + inst = (struct PalettePrefsInst *) INST_DATA(cl, obj); + + memset(inst, 0, sizeof(struct PalettePrefsInst)); + + if (CreatePalettePrefsObject(inst, (struct opSet *) msg)) + { + prefsobject = CreatePrefsGroup(inst); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: prefsobject=%08lx\n", __LINE__, prefsobject)); + } + if (prefsobject) + { + DoMethod(obj, OM_ADDMEMBER, prefsobject); + + result = (ULONG) obj; + } + else + { + CoerceMethod(cl, obj, OM_DISPOSE); + } + } + break; + + case OM_DISPOSE: + DisposePalettePrefsObject((struct PalettePrefsInst *) INST_DATA(cl, obj)); + d1(kprintf("%s/%d/%ld: PalettePrefsCatalog=%08lx\n", __FILE__, __FUNC__, __LINE__, PalettePrefsCatalog)); + return DoSuperMethodA(cl, obj, msg); + break; + + case OM_SET: + { + struct opSet *ops = (struct opSet *) msg; + + inst = (struct PalettePrefsInst *) INST_DATA(cl, obj); + inst->ppb_fCreateIcons = GetTagData(MUIA_ScalosPrefs_CreateIcons, inst->ppb_fCreateIcons, ops->ops_AttrList); + inst->ppb_ProgramName = (CONST_STRPTR) GetTagData(MUIA_ScalosPrefs_ProgramName, (ULONG) inst->ppb_ProgramName, ops->ops_AttrList); + inst->ppb_Objects[OBJNDX_WIN_Main] = (APTR) GetTagData(MUIA_ScalosPrefs_MainWindow, + (ULONG) inst->ppb_Objects[OBJNDX_WIN_Main], ops->ops_AttrList); + inst->ppb_Objects[OBJNDX_APP_Main] = (APTR) GetTagData(MUIA_ScalosPrefs_Application, + (ULONG) inst->ppb_Objects[OBJNDX_APP_Main], ops->ops_AttrList); + + return DoSuperMethodA(cl, obj, msg); + } + break; + + case OM_GET: + { + struct opGet *opg = (struct opGet *) msg; + + inst = (struct PalettePrefsInst *) INST_DATA(cl, obj); + switch (opg->opg_AttrID) + { + case MUIA_ScalosPrefs_CreateIcons: + *opg->opg_Storage = inst->ppb_fCreateIcons; + result = 0; + break; + default: + result = DoSuperMethodA(cl, obj, msg); + } + } + break; + + case MUIM_ScalosPrefs_LoadConfig: + inst = (struct PalettePrefsInst *) INST_DATA(cl, obj); + if (RETURN_OK != ReadPrefsFile(inst, "ENV:Scalos/Palette13.prefs", TRUE)) + ReadPrefsFile(inst, "ENV:Scalos/Palette13.prefs", FALSE); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: \n", __LINE__)); + SetChangedFlag(inst, FALSE); + break; + + case MUIM_ScalosPrefs_UseConfig: + inst = (struct PalettePrefsInst *) INST_DATA(cl, obj); + WritePrefsFile(inst, "ENV:Scalos/Palette13.prefs"); + break; + + case MUIM_ScalosPrefs_UseConfigIfChanged: + inst = (struct PalettePrefsInst *) INST_DATA(cl, obj); + if (inst->ppb_Changed) + { + WritePrefsFile(inst, "ENV:Scalos/Palette13.prefs"); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: \n", __LINE__)); + SetChangedFlag(inst, FALSE); + } + break; + + case MUIM_ScalosPrefs_SaveConfig: + inst = (struct PalettePrefsInst *) INST_DATA(cl, obj); + WritePrefsFile(inst, "ENVARC:Scalos/Palette13.prefs"); + WritePrefsFile(inst, "ENV:Scalos/Palette13.prefs"); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: \n", __LINE__)); + SetChangedFlag(inst, FALSE); + break; + + case MUIM_ScalosPrefs_SaveConfigIfChanged: + inst = (struct PalettePrefsInst *) INST_DATA(cl, obj); + if (inst->ppb_Changed) + { + WritePrefsFile(inst, "ENVARC:Scalos/Palette13.prefs"); + WritePrefsFile(inst, "ENV:Scalos/Palette13.prefs"); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: \n", __LINE__)); + SetChangedFlag(inst, FALSE); + } + break; + + case MUIM_ScalosPrefs_RestoreConfig: + inst = (struct PalettePrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_Restore], 0); + break; + + case MUIM_ScalosPrefs_ResetToDefaults: + inst = (struct PalettePrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_ResetToDefaults], 0); + break; + + case MUIM_ScalosPrefs_LastSavedConfig: + inst = (struct PalettePrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_LastSaved], 0); + break; + + case MUIM_ScalosPrefs_OpenConfig: + inst = (struct PalettePrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_Open], 0); + break; + + case MUIM_ScalosPrefs_SaveConfigAs: + inst = (struct PalettePrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_SaveAs], 0); + break; + + case MUIM_ScalosPrefs_About: + inst = (struct PalettePrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_About], 0); + break; + + case MUIM_ScalosPrefs_LoadNamedConfig: + { + struct MUIP_ScalosPrefs_LoadNamedConfig *lnc = (struct MUIP_ScalosPrefs_LoadNamedConfig *) msg; + + inst = (struct PalettePrefsInst *) INST_DATA(cl, obj); + ReadPrefsFile(inst, lnc->ConfigFileName, FALSE); + } + break; + + case MUIM_ScalosPrefs_CreateSubWindows: + result = 0; + break; + + case MUIM_ScalosPrefs_GetListOfMCCs: + result = (ULONG) RequiredMccList; + break; + + default: + d1(kprintf("%s/%s/%ld: MethodID=%08lx\n", __FILE__, __FUNC__, __LINE__, msg->MethodID)); + result = DoSuperMethodA(cl, obj, msg); + break; + } + + d1(kprintf("%s/%d/%ld/%ld: END result=%ld\n", __FILE__, __FUNC__, __LINE__, result)); + + return result; +} +DISPATCHER_END + +//---------------------------------------------------------------------------- + +static BOOL CreatePalettePrefsObject(struct PalettePrefsInst *inst, struct opSet *ops) +{ + BOOL Success = FALSE; + + do { + memset(inst, 0, sizeof(struct PalettePrefsInst)); + + inst->ppb_Changed = FALSE; + inst->ppb_fPreview = TRUE; + inst->ppb_fAutoPreview = FALSE; + inst->ppb_fDontChange = FALSE; + inst->ppb_PalettePrecision = PRECISION_IMAGE; + inst->ppb_PreviewWeight = 20; + inst->ppb_AllocatedPensListImageIndex = 1; + + InitHooks(inst); + + inst->ppb_fCreateIcons = GetTagData(MUIA_ScalosPrefs_CreateIcons, TRUE, ops->ops_AttrList); + inst->ppb_ProgramName = (CONST_STRPTR) GetTagData(MUIA_ScalosPrefs_ProgramName, (ULONG) "", ops->ops_AttrList); + inst->ppb_Objects[OBJNDX_WIN_Main] = (APTR) GetTagData(MUIA_ScalosPrefs_MainWindow, (ULONG) NULL, ops->ops_AttrList); + inst->ppb_Objects[OBJNDX_APP_Main] = (APTR) GetTagData(MUIA_ScalosPrefs_Application, (ULONG) NULL, ops->ops_AttrList); + + inst->ppb_WBScreen = LockPubScreen("Workbench"); + if (NULL == inst->ppb_WBScreen) + break; + + Success = TRUE; + } while (0); + + return Success; +} + + +static void DisposePalettePrefsObject(struct PalettePrefsInst *inst) +{ + if (inst->ppb_WBScreen) + { + UnlockPubScreen(NULL, inst->ppb_WBScreen); + inst->ppb_WBScreen = NULL; + } + if (inst->ppb_LoadReq) + { + MUI_FreeAslRequest(inst->ppb_LoadReq); + inst->ppb_LoadReq = NULL; + } + if (inst->ppb_SaveReq) + { + MUI_FreeAslRequest(inst->ppb_SaveReq); + inst->ppb_SaveReq = NULL; + } + if (inst->ppb_Objects[OBJNDX_ContextMenu]) + { + MUI_DisposeObject(inst->ppb_Objects[OBJNDX_ContextMenu]); + inst->ppb_Objects[OBJNDX_ContextMenu] = NULL; + } +} + + +static Object *CreatePrefsGroup(struct PalettePrefsInst *inst) +{ + d1(kprintf(__FUNC__ "/%ld: inst=%08lx\n", __LINE__, inst)); + + inst->ppb_Objects[OBJNDX_ContextMenu] = MUI_MakeObject(MUIO_MenustripNM, ContextMenus, 0); + + if (NULL == inst->ppb_Objects[OBJNDX_ContextMenu]) + return NULL; + + inst->ppb_Objects[OBJNDX_Group_Main] = VGroup, + MUIA_Background, MUII_PageBack, + + Child, HGroup, + Child, VGroup, + Child, TextObject, + MUIA_Font, MUIV_Font_Title, + TextFrame, + MUIA_Background, MUII_GroupBack, + MUIA_Text_PreParse, "\33c", + MUIA_Text_Contents, GetLocString(MSGID_TITLE_SCALOSPENLIST), + End, //NListviewObject + + Child, NListviewObject, + MUIA_CycleChain, TRUE, + MUIA_Listview_Input, TRUE, + MUIA_Listview_DragType, MUIV_Listview_DragType_Immediate, + MUIA_NListview_NList, inst->ppb_Objects[OBJNDX_ScalosPenList] = NewScalosPenListObject, + MUIA_NList_PrivateData, inst, + InputListFrame, + MUIA_Background, MUII_ListBack, + MUIA_NList_Format, "BAR D=8 P=\x1br,BAR D=8 P=\x1br,,", + MUIA_NList_DisplayHook2, &inst->ppb_Hooks[HOOKNDX_ScalosPenListDisplay], + MUIA_NList_ConstructHook, &inst->ppb_Hooks[HOOKNDX_ScalosPenListConstruct], + MUIA_NList_DestructHook, &inst->ppb_Hooks[HOOKNDX_ScalosPenListDestruct], + MUIA_NList_CompareHook2, &inst->ppb_Hooks[HOOKNDX_ScalosPenListCompare], + MUIA_NList_DragSortable, TRUE, + MUIA_NList_ShowDropMarks, TRUE, + MUIA_NList_AutoVisible, TRUE, + MUIA_NList_EntryValueDependent, TRUE, + MUIA_NList_Title, TRUE, + MUIA_NList_TitleSeparator, TRUE, + MUIA_NList_SortType, 2, + MUIA_NList_TitleMark, MUIV_NList_TitleMark_Down | 2, + MUIA_ContextMenu, inst->ppb_Objects[OBJNDX_ContextMenu], + End, + MUIA_ShortHelp, GetLocString(MSGID_SHORTHELP_SCALOSPENLIST), + End, //NListviewObject + End, //VGroup + + Child, BalanceObject, + End, //BalanceObject + + Child, VGroup, + Child, inst->ppb_Objects[OBJNDX_AllocatedPensListTitleObj] = TextObject, + MUIA_Font, MUIV_Font_Title, + TextFrame, + MUIA_Background, MUII_GroupBack, + MUIA_Text_PreParse, "\33c", + MUIA_Text_Contents, inst->ppb_PalettePenListTitle, + End, //TextObject + + Child, NListviewObject, + MUIA_Listview_Input, TRUE, + MUIA_CycleChain, TRUE, + MUIA_Listview_DragType, MUIV_Listview_DragType_Immediate, + MUIA_NListview_NList, inst->ppb_Objects[OBJNDX_AllocatedPensList] = NewPalettePenListObject, + MUIA_NList_PrivateData, inst, + MUIA_UserData, inst, + InputListFrame, + MUIA_Background, MUII_ListBack, + MUIA_NList_Format, "BAR D=8 P=\x1br,BAR D=8 P=\x1br,BAR P=\x1br,NOBAR D=8 P=\x1br,NOBAR D=8 P=\x1br,NOBAR D=8 P=\x1br", + MUIA_NList_DisplayHook2, &inst->ppb_Hooks[HOOKNDX_AllocatedPensListDisplay], + MUIA_NList_ConstructHook, &inst->ppb_Hooks[HOOKNDX_AllocatedPensListConstruct], + MUIA_NList_DestructHook, &inst->ppb_Hooks[HOOKNDX_AllocatedPensListDestruct], + MUIA_NList_CompareHook2, &inst->ppb_Hooks[HOOKNDX_AllocatedPensListCompare], + MUIA_NList_DragSortable, TRUE, + MUIA_NList_ShowDropMarks, TRUE, + MUIA_NList_AutoVisible, TRUE, + MUIA_NList_EntryValueDependent, TRUE, + MUIA_NList_Title, TRUE, + MUIA_NList_TitleSeparator, TRUE, + MUIA_NList_SortType, 0, + MUIA_NList_TitleMark, MUIV_NList_TitleMark_Down | 0, + MUIA_ContextMenu, inst->ppb_Objects[OBJNDX_ContextMenu], + End, //NewPalettePenListClass + MUIA_ShortHelp, GetLocString(MSGID_SHORTHELP_PALETTEPENLIST), + End, //NListviewObject + + Child, HGroup, + Child, inst->ppb_Objects[OBJNDX_Lamp_Changed] = LampObject, + MUIA_Lamp_Type, MUIV_Lamp_Type_Huge, + MUIA_Lamp_Color, MUIV_Lamp_Color_Off, + MUIA_ShortHelp, GetLocString(MSGID_SHORTHELP_LAMP_CHANGED), + End, //LampObject + + Child, HGroup, + MUIA_Group_SameSize, TRUE, + Child, inst->ppb_Objects[OBJNDX_NewButton] = KeyButtonHelp(GetLocString(MSGID_NEW), 'n', GetLocString(MSGID_SHORTHELP_NEWBUTTON)), + Child, inst->ppb_Objects[OBJNDX_DeleteButton] = KeyButtonHelp(GetLocString(MSGID_DELETE), 'd', GetLocString(MSGID_SHORTHELP_DELETEBUTTON)), + End, //HGroup + End, //HGroup + + Child, BalanceObject, + End, //BalanceObject + + Child, inst->ppb_Objects[OBJNDX_ColorAdjust] = NewColorAdjustObject, + MUIA_UserData, inst, + End, //NewColorAdjustClass + + Child, PopobjectObject, + MUIA_Popstring_String, TextObject, + MUIA_CycleChain, TRUE, + MUIA_Background, MUII_GroupBack, + TextFrame, + MUIA_Text_Contents, GetLocString(MSGID_IMPORTNAME), + MUIA_Text_PreParse, "\33c", + End, + MUIA_Popstring_Button, PopButton(MUII_PopUp), + MUIA_ShortHelp, GetLocString(MSGID_SHORTHELP_WBPENSBUTTON), + MUIA_Popobject_WindowHook, &inst->ppb_Hooks[HOOKNDX_GetWBColors], + MUIA_Popobject_Object, NListviewObject, + MUIA_Listview_Input, TRUE, + MUIA_Listview_DragType, MUIV_Listview_DragType_Immediate, + MUIA_Listview_MultiSelect, TRUE, + MUIA_CycleChain, TRUE, + MUIA_ShortHelp, GetLocString(MSGID_SHORTHELP_WBPENLIST), + MUIA_NListview_NList, inst->ppb_Objects[OBJNDX_WBColorsList] = myNListObject, + MUIA_NList_PrivateData, inst, + InputListFrame, + MUIA_Background, MUII_ListBack, + MUIA_NList_Format, "BAR D=8 P=\x1br,BAR D=8 P=\x1br,NOBAR D=8 P=\x1br,NOBAR D=8 P=\x1br,NOBAR D=8 P=\x1br", + MUIA_NList_DisplayHook2, &inst->ppb_Hooks[HOOKNDX_WBPensListDisplay], + MUIA_NList_ConstructHook, &inst->ppb_Hooks[HOOKNDX_WBPensListConstruct], + MUIA_NList_DestructHook, &inst->ppb_Hooks[HOOKNDX_WBPensListDestruct], + MUIA_NList_CompareHook2, &inst->ppb_Hooks[HOOKNDX_WBPensListCompare], + MUIA_NList_ShowDropMarks, TRUE, + MUIA_NList_AutoVisible, TRUE, + MUIA_NList_Title, TRUE, + MUIA_NList_TitleSeparator, TRUE, + MUIA_NList_SortType, 0, + MUIA_NList_TitleMark, MUIV_NList_TitleMark_Down | 0, + MUIA_NList_EntryValueDependent, TRUE, + MUIA_ContextMenu, inst->ppb_Objects[OBJNDX_ContextMenu], + End, //inst->ppb_myNListClass + End, //NListviewObject + End, //PopobjectObject + End, + End, //HGroup + + MUIA_ContextMenu, inst->ppb_Objects[OBJNDX_ContextMenu], + End; //VGroup + + if (NULL == inst->ppb_Objects[OBJNDX_Group_Main]) + return NULL; + + InitPenList(inst); + UpdatePalettePenCount(inst); + + set(inst->ppb_Objects[OBJNDX_DeleteButton], MUIA_Disabled, TRUE); + + // setup sorting hooks for OBJNDX_ScalosPenList list + DoMethod(inst->ppb_Objects[OBJNDX_ScalosPenList], MUIM_Notify, MUIA_NList_TitleClick, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_ScalosPenList], 4, MUIM_NList_Sort3, MUIV_TriggerValue, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_Both); + DoMethod(inst->ppb_Objects[OBJNDX_ScalosPenList], MUIM_Notify, MUIA_NList_TitleClick2, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_ScalosPenList], 4, MUIM_NList_Sort3, MUIV_TriggerValue, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_2); + DoMethod(inst->ppb_Objects[OBJNDX_ScalosPenList], MUIM_Notify, MUIA_NList_SortType, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_ScalosPenList], 3, MUIM_Set, MUIA_NList_TitleMark, MUIV_TriggerValue); + DoMethod(inst->ppb_Objects[OBJNDX_ScalosPenList], MUIM_Notify, MUIA_NList_SortType2, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_ScalosPenList], 3, MUIM_Set, MUIA_NList_TitleMark2, MUIV_TriggerValue); + + // setup sorting hooks for OBJNDX_AllocatedPensList list + DoMethod(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIM_Notify, MUIA_NList_TitleClick, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_AllocatedPensList], 4, MUIM_NList_Sort3, MUIV_TriggerValue, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_Both); + DoMethod(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIM_Notify, MUIA_NList_TitleClick2, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_AllocatedPensList], 4, MUIM_NList_Sort3, MUIV_TriggerValue, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_2); + DoMethod(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIM_Notify, MUIA_NList_SortType, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_AllocatedPensList], 3, MUIM_Set, MUIA_NList_TitleMark, MUIV_TriggerValue); + DoMethod(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIM_Notify, MUIA_NList_SortType2, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_AllocatedPensList], 3, MUIM_Set, MUIA_NList_TitleMark2, MUIV_TriggerValue); + + // setup sorting hooks for OBJNDX_WBColorsList list + DoMethod(inst->ppb_Objects[OBJNDX_WBColorsList], MUIM_Notify, MUIA_NList_TitleClick, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_WBColorsList], 4, MUIM_NList_Sort3, MUIV_TriggerValue, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_Both); + DoMethod(inst->ppb_Objects[OBJNDX_WBColorsList], MUIM_Notify, MUIA_NList_TitleClick2, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_WBColorsList], 4, MUIM_NList_Sort3, MUIV_TriggerValue, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_2); + DoMethod(inst->ppb_Objects[OBJNDX_WBColorsList], MUIM_Notify, MUIA_NList_SortType, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_WBColorsList], 3, MUIM_Set, MUIA_NList_TitleMark, MUIV_TriggerValue); + DoMethod(inst->ppb_Objects[OBJNDX_WBColorsList], MUIM_Notify, MUIA_NList_SortType2, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_WBColorsList], 3, MUIM_Set, MUIA_NList_TitleMark2, MUIV_TriggerValue); + + // notification on Contextmenu for all places except listviews + DoMethod(inst->ppb_Objects[OBJNDX_Group_Main], MUIM_Notify, MUIA_ContextMenuTrigger, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_Group_Main], 3, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_ContextMenuTrigger], MUIV_TriggerValue ); + + // Notification for "Add pen" button + DoMethod(inst->ppb_Objects[OBJNDX_NewButton], MUIM_Notify, MUIA_Pressed, FALSE, + inst->ppb_Objects[OBJNDX_AllocatedPensList], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_AddPen]); + + // Notification for "Delete pen" button + DoMethod(inst->ppb_Objects[OBJNDX_DeleteButton], MUIM_Notify, MUIA_Pressed, FALSE, + inst->ppb_Objects[OBJNDX_AllocatedPensList], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_DeletePen]); + + // Update ColorAdjust every time a new pen is selected + DoMethod(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIM_Notify, MUIA_NList_Active, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_ColorAdjust], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_SelectPalettePen]); + + DoMethod(inst->ppb_Objects[OBJNDX_ScalosPenList], MUIM_Notify, MUIA_NList_Active, MUIV_EveryTime, + MUIV_Notify_Window, 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_SelectScalosPen]); + + DoMethod(inst->ppb_Objects[OBJNDX_ColorAdjust], MUIM_Notify, MUIA_Coloradjust_RGB, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_AllocatedPensList], 3, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_ChangePenColor], MUIV_TriggerValue); + + return inst->ppb_Objects[OBJNDX_Group_Main]; +} + + +static Object *CreatePrefsImage(void) +{ +#include "PalettePrefsImage.h" + Object *img; + + // First try to load datatypes image from THEME: tree + img = DataTypesImageObject, + MUIA_ScaDtpic_Name, (ULONG) "THEME:prefs/plugins/palette", + MUIA_ScaDtpic_FailIfUnavailable, TRUE, + End; //DataTypesMCCObject + + if (NULL == img) + img = IMG(Palette, PALETTE); // use built-in fallback image + + return img; +} + + +static void InitHooks(struct PalettePrefsInst *inst) +{ + ULONG n; + + for (n=0; nppb_Hooks[n] = PalettePrefsHooks[n]; + inst->ppb_Hooks[n].h_Data = inst; + } +} + + +static BOOL OpenLibraries(void) +{ + DOSBase = (APTR) OpenLibrary( "dos.library", 39 ); + if (!DOSBase) + return FALSE; +#ifdef __amigaos4__ + IDOS = (struct DOSIFace *)GetInterface((struct Library *)DOSBase, "main", 1, NULL); + if (NULL == IDOS) + return FALSE; +#endif + + d1(kprintf(__FUNC__ "/%ld:\n", __LINE__)); + + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + if (NULL == IntuitionBase) + return FALSE; +#ifdef __amigaos4__ + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + return FALSE; +#endif + + MUIMasterBase = OpenLibrary("zune.library", 0); + if (NULL == MUIMasterBase) + MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN-1); + if (NULL == MUIMasterBase) + return FALSE; +#ifdef __amigaos4__ + IMUIMaster = (struct MUIMasterIFace *)GetInterface((struct Library *)MUIMasterBase, "main", 1, NULL); + if (NULL == IMUIMaster) + return FALSE; +#endif + + IFFParseBase = OpenLibrary("iffparse.library", 36); + if (NULL == IFFParseBase) + return FALSE; +#ifdef __amigaos4__ + IIFFParse = (struct IFFParseIFace *)GetInterface((struct Library *)IFFParseBase, "main", 1, NULL); + if (NULL == IIFFParse) + return FALSE; +#endif + + IconBase = OpenLibrary("icon.library", 0); + if (NULL == IconBase) + return FALSE; +#ifdef __amigaos4__ + IIcon = (struct IconIFace *)GetInterface((struct Library *)IconBase, "main", 1, NULL); + if (NULL == IIcon) + return FALSE; +#endif + + GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 39); + if (NULL == GfxBase) + return FALSE; +#ifdef __amigaos4__ + IGraphics = (struct GraphicsIFace *)GetInterface((struct Library *)GfxBase, "main", 1, NULL); + if (NULL == IGraphics) + return FALSE; +#endif + + UtilityBase = (T_UTILITYBASE) OpenLibrary(UTILITYNAME, 39); + if (NULL == UtilityBase) + return FALSE; +#ifdef __amigaos4__ + IUtility = (struct UtilityIFace *)GetInterface((struct Library *)UtilityBase, "main", 1, NULL); + if (NULL == IUtility) + return FALSE; +#endif + +#if defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) + __UtilityBase = UtilityBase; +#endif /* __GNUC__ && !__MORPHOS__ && ! __amigaos4__ */ + + DataTypesBase = OpenLibrary("datatypes.library", 39); + if (NULL == DataTypesBase) + return FALSE; +#ifdef __amigaos4__ + IDataTypes = (struct DataTypesIFace *)GetInterface((struct Library *)DataTypesBase, "main", 1, NULL); + if (NULL == IDataTypes) + return FALSE; +#endif + +#ifdef __amigaos4__ + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + return FALSE; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + return FALSE; +#endif + + LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 39); +#ifdef __amigaos4__ + if (LocaleBase) + ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL); +#endif + + return TRUE; +} + + +static void CloseLibraries(void) +{ +#ifdef __amigaos4__ + if (INewlib) + { + DropInterface(INewlib); + INewlib = NULL; + } + if (NewlibBase) + { + CloseLibrary(NewlibBase); + NewlibBase = NULL; + } + if (IDataTypes) + { + DropInterface((struct Interface *)IDataTypes); + IDataTypes = NULL; + } +#endif + if (DataTypesBase) + { + CloseLibrary(DataTypesBase); + DataTypesBase = NULL; + } +#ifdef __amigaos4__ + if (ILocale) + { + DropInterface((struct Interface *)ILocale); + ILocale = NULL; + } +#endif + if (LocaleBase) + { + CloseLibrary((struct Library *) LocaleBase); + LocaleBase = NULL; + } +#ifdef __amigaos4__ + if (IUtility) + { + DropInterface((struct Interface *)IUtility); + IUtility = NULL; + } +#endif + if (UtilityBase) + { + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } +#ifdef __amigaos4__ + if (IGraphics) + { + DropInterface((struct Interface *)IGraphics); + IGraphics = NULL; + } +#endif + if (GfxBase) + { + CloseLibrary((struct Library *) GfxBase); + GfxBase = NULL; + } +#ifdef __amigaos4__ + if (IIcon) + { + DropInterface((struct Interface *)IIcon); + IIcon = NULL; + } +#endif + if (IconBase) + { + CloseLibrary(IconBase); + IconBase = NULL; + } +#ifdef __amigaos4__ + if (IIFFParse) + { + DropInterface((struct Interface *)IIFFParse); + IIFFParse = NULL; + } +#endif + if (IFFParseBase) + { + CloseLibrary(IFFParseBase); + IFFParseBase = NULL; + } +#ifdef __amigaos4__ + if (IMUIMaster) + { + DropInterface((struct Interface *)IMUIMaster); + IMUIMaster = NULL; + } +#endif + if (MUIMasterBase) + { + CloseLibrary(MUIMasterBase); + MUIMasterBase = NULL; + } +#ifdef __amigaos4__ + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } +#endif + if (IntuitionBase) + { + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } +#ifdef __amigaos4__ + if (IDOS) + { + DropInterface((struct Interface *)IDOS); + IDOS = NULL; + } +#endif + if (DOSBase) + { + CloseLibrary((struct Library *) DOSBase); + DOSBase = NULL; + } + +} + +//---------------------------------------------------------------------------- + +static STRPTR GetLocString(ULONG MsgId) +{ + struct ScalosPalette_LocaleInfo li; + + li.li_Catalog = PalettePrefsCatalog; +#ifndef __amigaos4__ + li.li_LocaleBase = LocaleBase; +#else + li.li_ILocale = ILocale; +#endif + + return (STRPTR)GetScalosPaletteString(&li, MsgId); +} + + +static void TranslateNewMenu(struct NewMenu *nm) +{ + while (nm && NM_END != nm->nm_Type) + { + if (NM_BARLABEL != nm->nm_Label) + nm->nm_Label = GetLocString((ULONG) nm->nm_Label); + + if (nm->nm_CommKey) + nm->nm_CommKey = GetLocString((ULONG) nm->nm_CommKey); + + nm++; + } +} + +#if 0 +static void TranslateStringArray(STRPTR *stringArray) +{ + while (*stringArray) + { + *stringArray = GetLocString((ULONG) *stringArray); + stringArray++; + } +} +#endif + +//---------------------------------------------------------------------------- + +void _XCEXIT(long x) +{ +} + +//---------------------------------------------------------------------------- + +DISPATCHER(myNList) +{ + struct PalettePrefsInst *inst = NULL; + ULONG result; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: MethodID=%08lx\n", __LINE__, msg->MethodID)); + + switch(msg->MethodID) + { + case MUIM_ContextMenuChoice: + { + struct MUIP_ContextMenuChoice *cmc = (struct MUIP_ContextMenuChoice *) msg; + Object *MenuObj; + ULONG MenuHookIndex = 0; + struct Hook *MenuHook = NULL; + + get(obj, MUIA_NList_PrivateData, &inst); + + d1(kprintf(__FUNC__ "/%ld: MUIM_ContextMenuChoice item=%08lx\n", __LINE__, cmc->item)); + + MenuObj = cmc->item; + + d1(kprintf(__FUNC__ "/%ld: MenuObj=%08lx\n", __LINE__, MenuObj)); + d1(kprintf(__FUNC__ "/%ld: msg=%08lx *msg=%08lx\n", __LINE__, msg, *((ULONG *) msg))); + + get(MenuObj, MUIA_UserData, &MenuHookIndex); + + if (MenuHookIndex > 0 && MenuHookIndex < HOOKNDX_MAX) + MenuHook = &inst->ppb_Hooks[MenuHookIndex]; + + d1(kprintf(__FUNC__ "/%ld: MenuHook=%08lx\n", __LINE__, MenuHook)); + if (MenuHook) + DoMethod(inst->ppb_Objects[OBJNDX_Group_Main], MUIM_CallHook, MenuHook, MenuObj); + + result = 0; + } + break; + + default: + result = DoSuperMethodA(cl, obj, msg); + } + + return result; +} +DISPATCHER_END + +//---------------------------------------------------------------------------- + +DISPATCHER(NewColorAdjust) +{ + struct PalettePrefsInst *inst = NULL; + ULONG Result; + + d1(kprintf( "%s/%s/%ld: START MethodID=%08lx\n", __FILE__, __FUNC__, __LINE__, msg->MethodID)); + + switch (msg->MethodID) + { + case MUIM_DragQuery: + { + struct MUIP_DragQuery *dq = (struct MUIP_DragQuery *) msg; + + get(obj, MUIA_UserData, &inst); + + if (inst->ppb_Objects[OBJNDX_WBColorsList] == dq->obj) + Result = MUIV_DragQuery_Accept; + else + Result = MUIV_DragQuery_Refuse; + } + break; + + case MUIM_DragDrop: + { + struct MUIP_DragDrop *dd = (struct MUIP_DragDrop *) msg; + APTR activeEntry = NULL; + + get(obj, MUIA_UserData, &inst); + + DoMethod(dd->obj, MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &activeEntry); + + if (activeEntry) + set(inst->ppb_Objects[OBJNDX_ColorAdjust], MUIA_Coloradjust_RGB, (ULONG) activeEntry); + + Result = 0; + } + break; + + default: + Result = DoSuperMethodA(cl, obj, msg); + break; + } + + d1(kprintf( "%s/%s/%ld: END Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + + return Result; +} +DISPATCHER_END + + +DISPATCHER(NewPalettePenList) +{ + struct PalettePrefsInst *inst = NULL; + ULONG Result; + + switch (msg->MethodID) + { + case MUIM_DragQuery: + { + struct MUIP_DragQuery *dq = (struct MUIP_DragQuery *) msg; + + get(obj, MUIA_NList_PrivateData, &inst); + + if (inst->ppb_Objects[OBJNDX_WBColorsList] == dq->obj || inst->ppb_Objects[OBJNDX_AllocatedPensList] == dq->obj) + Result = MUIV_DragQuery_Accept; + else + Result = MUIV_DragQuery_Refuse; + } + break; + + case MUIM_DragDrop: + { + struct MUIP_DragDrop *dd = (struct MUIP_DragDrop *) msg; + + get(obj, MUIA_NList_PrivateData, &inst); + + if (inst->ppb_Objects[OBJNDX_AllocatedPensList] == dd->obj) + { + // Drag-sorting pen list + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: \n", __LINE__)); + SetChangedFlag(inst, TRUE); + Result = DoSuperMethodA(cl, obj, msg); + } + else + { + LONG DropMark = 0; + LONG Entry; + + get(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIA_NList_DropMark, &DropMark); + set(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIA_NList_Quiet, TRUE); + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: DropMark=%ld\n", __LINE__, DropMark)); + + Entry = MUIV_NList_NextSelected_Start; + + do { + DoMethod(dd->obj, MUIM_NList_NextSelected, &Entry); + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: DropMark=%ld\n", __LINE__, Entry)); + + if (Entry != MUIV_NList_NextSelected_End) + { + struct ScalosPenListEntry *snle; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: \n", __LINE__)); + SetChangedFlag(inst, TRUE); + + DoMethod(dd->obj, MUIM_NList_GetEntry, Entry, &snle); + DoMethod(inst->ppb_Objects[OBJNDX_AllocatedPensList], + MUIM_NList_InsertSingle, snle, DropMark); + + if (MUIV_NList_Insert_Bottom != DropMark) + DropMark++; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: DropMark=%ld\n", __LINE__, DropMark)); + } + } while (Entry != MUIV_NList_NextSelected_End); + + set(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIA_NList_Quiet, FALSE); + + Result = 0; + } + } + break; + + case MUIM_ContextMenuChoice: + { + struct MUIP_ContextMenuChoice *cmc = (struct MUIP_ContextMenuChoice *) msg; + Object *MenuObj; + ULONG MenuHookIndex = 0; + struct Hook *MenuHook = NULL; + + get(obj, MUIA_NList_PrivateData, &inst); + + d1(kprintf(__FUNC__ "/%ld: MUIM_ContextMenuChoice item=%08lx\n", __LINE__, cmc->item)); + + MenuObj = cmc->item; + + d1(kprintf(__FUNC__ "/%ld: MenuObj=%08lx\n", __LINE__, MenuObj)); + d1(kprintf(__FUNC__ "/%ld: msg=%08lx *msg=%08lx\n", __LINE__, msg, *((ULONG *) msg))); + + get(MenuObj, MUIA_UserData, &MenuHookIndex); + + if (MenuHookIndex > 0 && MenuHookIndex < HOOKNDX_MAX) + MenuHook = &inst->ppb_Hooks[MenuHookIndex]; + + d1(kprintf(__FUNC__ "/%ld: MenuHook=%08lx\n", __LINE__, MenuHook)); + if (MenuHook) + DoMethod(inst->ppb_Objects[OBJNDX_Group_Main], MUIM_CallHook, MenuHook, MenuObj); + + Result = 0; + } + break; + + default: + Result = DoSuperMethodA(cl, obj, msg); + break; + } + + return Result; +} +DISPATCHER_END + + +DISPATCHER(NewScalosPenList) +{ + struct PalettePrefsInst *inst = NULL; + ULONG Result; + + switch (msg->MethodID) + { + case MUIM_DragQuery: + { + struct MUIP_DragQuery *dq = (struct MUIP_DragQuery *) msg; + + get(obj, MUIA_NList_PrivateData, &inst); + + if (inst->ppb_Objects[OBJNDX_ScalosPenList] == dq->obj || inst->ppb_Objects[OBJNDX_AllocatedPensList] == dq->obj) + Result = MUIV_DragQuery_Accept; + else + Result = MUIV_DragQuery_Refuse; + } + break; + + case MUIM_DragDrop: + { + LONG DropMark = 0; + struct MUIP_DragDrop *dd = (struct MUIP_DragDrop *) msg; + + get(obj, MUIA_NList_PrivateData, &inst); + get(obj, MUIA_NList_DropMark, &DropMark); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: DropMark=%ld\n", __LINE__, DropMark)); + + if (DropMark >= 0) + { + if (inst->ppb_Objects[OBJNDX_AllocatedPensList] == dd->obj) + { + struct ScalosPenListEntry *snle; + LONG Entry = 0; + ULONG OldPenNr; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: \n", __LINE__)); + SetChangedFlag(inst, TRUE); + + get(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIA_NList_Active, &Entry); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: Entry=%ld DropMark=%ld\n", __LINE__, Entry, DropMark)); + + DoMethod(inst->ppb_Objects[OBJNDX_ScalosPenList], MUIM_NList_GetEntry, DropMark, &snle); + + OldPenNr = snle->snle_PenNr; + snle->snle_PenNr = Entry; + + DoMethod(inst->ppb_Objects[OBJNDX_ScalosPenList], MUIM_NList_Redraw, DropMark); + + // Redraw "allocated pens" entry of old and new pen, since reference counts have changed + DoMethod(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIM_NList_Redraw, OldPenNr); + DoMethod(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIM_NList_Redraw, snle->snle_PenNr); + } + else + { + struct ScalosPenListEntry *snleActive = NULL; + + DoMethod(inst->ppb_Objects[OBJNDX_ScalosPenList], MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &snleActive); + if (snleActive) + { + struct ScalosPenListEntry *snleDest; + ULONG OldPenNr; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: DropMark=%ld\n", __LINE__, DropMark)); + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: \n", __LINE__)); + SetChangedFlag(inst, TRUE); + + DoMethod(inst->ppb_Objects[OBJNDX_ScalosPenList], MUIM_NList_GetEntry, DropMark, &snleDest); + + OldPenNr = snleDest->snle_PenNr; + snleDest->snle_PenNr = snleActive->snle_PenNr; + + DoMethod(inst->ppb_Objects[OBJNDX_ScalosPenList], MUIM_NList_Redraw, DropMark); + + // Redraw "allocated pens" entry of old and new pen, since reference counts have changed + DoMethod(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIM_NList_Redraw, OldPenNr); + DoMethod(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIM_NList_Redraw, snleDest->snle_PenNr); + } + } + } + + Result = 0; + } + break; + + case MUIM_NList_DropType: + { + struct MUIP_NList_DropType *mdt = (struct MUIP_NList_DropType *) msg; + + Result = DoSuperMethodA(cl, obj, msg); + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: DropType=%ld\n", __LINE__, *mdt->type)); + + if (MUIV_NList_DropType_None != *mdt->type) + *mdt->type = MUIV_NList_DropType_Onto; + } + break; + + case MUIM_ContextMenuChoice: + { + struct MUIP_ContextMenuChoice *cmc = (struct MUIP_ContextMenuChoice *) msg; + Object *MenuObj; + ULONG MenuHookIndex = 0; + struct Hook *MenuHook = NULL; + + get(obj, MUIA_NList_PrivateData, &inst); + + d1(kprintf(__FUNC__ "/%ld: MUIM_ContextMenuChoice item=%08lx\n", __LINE__, cmc->item)); + + MenuObj = cmc->item; + + d1(kprintf(__FUNC__ "/%ld: MenuObj=%08lx\n", __LINE__, MenuObj)); + d1(kprintf(__FUNC__ "/%ld: msg=%08lx *msg=%08lx\n", __LINE__, msg, *((ULONG *) msg))); + + get(MenuObj, MUIA_UserData, &MenuHookIndex); + + if (MenuHookIndex > 0 && MenuHookIndex < HOOKNDX_MAX) + MenuHook = &inst->ppb_Hooks[MenuHookIndex]; + + d1(kprintf(__FUNC__ "/%ld: MenuHook=%08lx\n", __LINE__, MenuHook)); + if (MenuHook) + DoMethod(inst->ppb_Objects[OBJNDX_Group_Main], MUIM_CallHook, MenuHook, MenuObj); + + Result = 0; + } + break; + + default: + Result = DoSuperMethodA(cl, obj, msg); + break; + } + + return Result; +} +DISPATCHER_END + +//---------------------------------------------------------------------------- + +static APTR AllocatedPensListConstructFunc(struct Hook *hook, APTR memPool, + struct PensListEntry *spleNew) +{ + struct PensListEntry *sple = AllocPooled(memPool, sizeof(struct PensListEntry)); + + if (sple) + { +// struct PalettePrefsInst *inst = (struct PalettePrefsInst *) hook->h_Data; + + *sple = *spleNew; + } + + return sple; +} + +static void AllocatedPensListDestructFunc(struct Hook *hook, APTR memPool, APTR Entry) +{ + if (Entry) + { + FreePooled(memPool, Entry, sizeof(struct PensListEntry)); + } +} + +static ULONG AllocatedPensListDisplayFunc(struct Hook *hook, Object *obj, struct NList_DisplayMessage *ndm) +{ + if (ndm->entry) + { + struct PalettePrefsInst *inst = (struct PalettePrefsInst *) hook->h_Data; + struct PensListEntry *sple = (struct PensListEntry *) ndm->entry; + static char Buffer[80]; + STRPTR lp = Buffer; + + sprintf(lp, "%ld", (long)sple->sple_Index); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: lp=<%s>\n", __LINE__, lp)); + ndm->strings[0] = lp; + lp += 1 + strlen(lp); + + sprintf(lp, "\033I[2:%08lx %08lx %08lx]", + (long)sple->sple_Red, (long)sple->sple_Green, (long)sple->sple_Blue); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: lp=<%s>\n", __LINE__, lp)); + ndm->strings[1] = lp; + lp += 1 + strlen(lp); + + // Ref. Count + sprintf(lp, "%ld", (long)GetPenReferenceCount(inst, sple->sple_Index)); + ndm->strings[2] = lp; + lp += 1 + strlen(lp); + + sprintf(lp, "%ld", (long)(sple->sple_Red >> 24)); + ndm->strings[3] = lp; + lp += 1 + strlen(lp); + + sprintf(lp, "%ld", (long)(sple->sple_Green >> 24)); + ndm->strings[4] = lp; + lp += 1 + strlen(lp); + + sprintf(lp, "%ld", (long)(sple->sple_Blue >> 24)); + ndm->strings[5] = lp; + } + else + { + // display titles + ndm->strings[0] = GetLocString(MSGID_PEN); + ndm->strings[1] = ""; + ndm->strings[2] = GetLocString(MSGID_PEN_REFERENCE_COUNT); + ndm->strings[3] = GetLocString(MSGID_RED); + ndm->strings[4] = GetLocString(MSGID_GREEN); + ndm->strings[5] = GetLocString(MSGID_BLUE); + } + + return 0; +} + +static LONG AllocatedPensListCompareFunc(struct Hook *hook, Object *obj, struct NList_CompareMessage *ncm) +{ + struct PalettePrefsInst *inst = (struct PalettePrefsInst *) hook->h_Data; + const struct PensListEntry *sple1 = (const struct PensListEntry *) ncm->entry1; + const struct PensListEntry *sple2 = (const struct PensListEntry *) ncm->entry2; + LONG col1 = ncm->sort_type & MUIV_NList_TitleMark_ColMask; + LONG col2 = ncm->sort_type2 & MUIV_NList_TitleMark2_ColMask; + LONG Result = 0; + + if (ncm->sort_type != MUIV_NList_SortType_None) + { + // primary sorting + switch (col1) + { + case 0: // sort by index + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = sple2->sple_Index - sple1->sple_Index; + else + Result = sple1->sple_Index - sple2->sple_Index; + break; + case 1: // sort by RGB + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = RGBComp(sple2, sple1); + else + Result = RGBComp(sple1, sple2); + break; + case 2: // sort by reference count + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = GetPenReferenceCount(inst, sple2->sple_Index) - GetPenReferenceCount(inst, sple1->sple_Index); + else + Result = GetPenReferenceCount(inst, sple1->sple_Index) - GetPenReferenceCount(inst, sple2->sple_Index); + break; + case 3: // sort by Red + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = ColorComp(sple2->sple_Red, sple1->sple_Red); + else + Result = ColorComp(sple1->sple_Red, sple2->sple_Red); + break; + case 4: // sort by Green + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = ColorComp(sple2->sple_Green, sple1->sple_Green); + else + Result = ColorComp(sple1->sple_Green, sple2->sple_Green); + break; + case 5: // sort by Blue + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = ColorComp(sple2->sple_Blue, sple1->sple_Blue); + else + Result = ColorComp(sple1->sple_Blue, sple2->sple_Blue); + break; + default: + break; + } + + if (0 == Result && col1 != col2) + { + // Secondary sorting + switch (col2) + { + case 0: // sort by index + if (ncm->sort_type2 & MUIV_NList_TitleMark2_TypeMask) + Result = sple2->sple_Index - sple1->sple_Index; + else + Result = sple1->sple_Index - sple2->sple_Index; + break; + case 1: // sort by RGB + if (ncm->sort_type2 & MUIV_NList_TitleMark2_TypeMask) + Result = RGBComp(sple2, sple1); + else + Result = RGBComp(sple1, sple2); + break; + case 2: // sort by reference count + if (ncm->sort_type2 & MUIV_NList_TitleMark_TypeMask) + Result = GetPenReferenceCount(inst, sple2->sple_Index) - GetPenReferenceCount(inst, sple1->sple_Index); + else + Result = GetPenReferenceCount(inst, sple1->sple_Index) - GetPenReferenceCount(inst, sple2->sple_Index); + break; + case 3: // sort by Red + if (ncm->sort_type2 & MUIV_NList_TitleMark_TypeMask) + Result = ColorComp(sple2->sple_Red, sple1->sple_Red); + else + Result = ColorComp(sple1->sple_Red, sple2->sple_Red); + break; + case 4: // sort by Green + if (ncm->sort_type2 & MUIV_NList_TitleMark_TypeMask) + Result = ColorComp(sple2->sple_Green, sple1->sple_Green); + else + Result = ColorComp(sple1->sple_Green, sple2->sple_Green); + break; + case 5: // sort by Blue + if (ncm->sort_type2 & MUIV_NList_TitleMark_TypeMask) + Result = ColorComp(sple2->sple_Blue, sple1->sple_Blue); + else + Result = ColorComp(sple1->sple_Blue, sple2->sple_Blue); + break; + default: + break; + } + } + } + + return Result; +} + +//---------------------------------------------------------------------------- + +static APTR WBPensListConstructFunc(struct Hook *hook, APTR memPool, + struct PensListEntry *spleNew) +{ + struct PensListEntry *sple = AllocPooled(memPool, sizeof(struct PensListEntry)); + + if (sple) + { + *sple = *spleNew; + } + + return sple; +} + +static void WBPensListDestructFunc(struct Hook *hook, APTR memPool, APTR Entry) +{ + FreePooled(memPool, Entry, sizeof(struct PensListEntry)); +} + +static ULONG WBPensListDisplayFunc(struct Hook *hook, Object *obj, struct NList_DisplayMessage *ndm) +{ + if (ndm->entry) + { + struct PensListEntry *sple = (struct PensListEntry *) ndm->entry; + static char Buffer[80]; + STRPTR lp = Buffer; + + sprintf(lp, "%ld", (long)sple->sple_Index); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: lp=<%s>\n", __LINE__, lp)); + ndm->strings[0] = lp; + lp += 1 + strlen(lp); + + sprintf(lp, "\x1bI[2:%08lx %08lx %08lx]", + (long)sple->sple_Red, (long)sple->sple_Green, (long)sple->sple_Blue); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: lp=<%s>\n", __LINE__, lp)); + ndm->strings[1] = lp; + lp += 1 + strlen(lp); + + sprintf(lp, "%ld", (long)(sple->sple_Red >> 24)); + ndm->strings[2] = lp; + lp += 1 + strlen(lp); + + sprintf(lp, "%ld", (long)(sple->sple_Green >> 24)); + ndm->strings[3] = lp; + lp += 1 + strlen(lp); + + sprintf(lp, "%ld", (long)(sple->sple_Blue >> 24)); + ndm->strings[4] = lp; + } + else + { + // display titles + ndm->strings[0] = GetLocString(MSGID_PEN); + ndm->strings[1] = ""; + ndm->strings[2] = GetLocString(MSGID_RED); + ndm->strings[3] = GetLocString(MSGID_GREEN); + ndm->strings[4] = GetLocString(MSGID_BLUE); + } + + return 0; +} + +static LONG WBPensListCompareFunc(struct Hook *hook, Object *obj, struct NList_CompareMessage *ncm) +{ +// struct PalettePrefsInst *inst = (struct PalettePrefsInst *) hook->h_Data; + const struct PensListEntry *sple1 = (const struct PensListEntry *) ncm->entry1; + const struct PensListEntry *sple2 = (const struct PensListEntry *) ncm->entry2; + LONG col1 = ncm->sort_type & MUIV_NList_TitleMark_ColMask; + LONG col2 = ncm->sort_type2 & MUIV_NList_TitleMark2_ColMask; + LONG Result = 0; + + if (ncm->sort_type != MUIV_NList_SortType_None) + { + // primary sorting + switch (col1) + { + case 0: // sort by index + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = sple2->sple_Index - sple1->sple_Index; + else + Result = sple1->sple_Index - sple2->sple_Index; + break; + case 1: // sort by RGB + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = RGBComp(sple2, sple1); + else + Result = RGBComp(sple1, sple2); + break; + case 2: // sort by Red + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = ColorComp(sple2->sple_Red, sple1->sple_Red); + else + Result = ColorComp(sple1->sple_Red, sple2->sple_Red); + break; + case 3: // sort by Green + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = ColorComp(sple2->sple_Green, sple1->sple_Green); + else + Result = ColorComp(sple1->sple_Green, sple2->sple_Green); + break; + case 4: // sort by Blue + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = ColorComp(sple2->sple_Blue, sple1->sple_Blue); + else + Result = ColorComp(sple1->sple_Blue, sple2->sple_Blue); + break; + default: + break; + } + + if (0 == Result && col1 != col2) + { + // Secondary sorting + switch (col2) + { + case 0: // sort by index + if (ncm->sort_type2 & MUIV_NList_TitleMark2_TypeMask) + Result = sple2->sple_Index - sple1->sple_Index; + else + Result = sple1->sple_Index - sple2->sple_Index; + break; + case 1: // sort by RGB + if (ncm->sort_type2 & MUIV_NList_TitleMark2_TypeMask) + Result = RGBComp(sple2, sple1); + else + Result = RGBComp(sple1, sple2); + break; + case 2: // sort by Red + if (ncm->sort_type2 & MUIV_NList_TitleMark_TypeMask) + Result = ColorComp(sple2->sple_Red, sple1->sple_Red); + else + Result = ColorComp(sple1->sple_Red, sple2->sple_Red); + break; + case 3: // sort by Green + if (ncm->sort_type2 & MUIV_NList_TitleMark_TypeMask) + Result = ColorComp(sple2->sple_Green, sple1->sple_Green); + else + Result = ColorComp(sple1->sple_Green, sple2->sple_Green); + break; + case 4: // sort by Blue + if (ncm->sort_type2 & MUIV_NList_TitleMark_TypeMask) + Result = ColorComp(sple2->sple_Blue, sple1->sple_Blue); + else + Result = ColorComp(sple1->sple_Blue, sple2->sple_Blue); + break; + default: + break; + } + } + } + + return Result; +} + +//---------------------------------------------------------------------------- + +static APTR ScalosPenListConstructFunc(struct Hook *hook, APTR memPool, struct ScalosPenListEntry *msg) +{ + struct ScalosPenListEntry *snle = AllocPooled(memPool, sizeof(struct ScalosPenListEntry)); + + if (snle) + { + *snle = *msg; + } + + return snle; +} + +static void ScalosPenListDestructFunc(struct Hook *hook, APTR memPool, APTR Entry) +{ + FreePooled(memPool, Entry, sizeof(struct ScalosPenListEntry)); +} + +static ULONG ScalosPenListDisplayFunc(struct Hook *hook, Object *obj, struct NList_DisplayMessage *ndm) +{ + struct PalettePrefsInst *inst = (struct PalettePrefsInst *) hook->h_Data; + + if (ndm->entry) + { + struct PensListEntry *sple = NULL; + struct ScalosPenListEntry *snle = (struct ScalosPenListEntry *) ndm->entry; + static char Buffer[80]; + STRPTR lp = Buffer; + + + if (PEN_UNDEFINED != snle->snle_PenNr) + sprintf(lp, "%d", snle->snle_PenNr); + else + strcpy(lp, "??"); + ndm->strings[0] = lp; + lp += 1 + strlen(lp); + + if (PEN_UNDEFINED != snle->snle_PenNr) + DoMethod(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIM_NList_GetEntry, snle->snle_PenNr, &sple); + + if (sple) + { + sprintf(lp, "\x1bI[2:%08lx %08lx %08lx]", + (long)sple->sple_Red, (long)sple->sple_Green, (long)sple->sple_Blue); + } + else + { + strcpy(lp, ""); + } + ndm->strings[1] = lp; + + ndm->strings[2] = (STRPTR) snle->snle_PenName; + } + else + { + // display titles + ndm->strings[0] = GetLocString(MSGID_PEN); + ndm->strings[1] = ""; + ndm->strings[2] = GetLocString(MSGID_PENNAMENAME); + } + + return 0; +} + +static LONG ScalosPenListCompareFunc(struct Hook *hook, Object *obj, struct NList_CompareMessage *ncm) +{ + struct PalettePrefsInst *inst = (struct PalettePrefsInst *) hook->h_Data; + const struct ScalosPenListEntry *snle1 = (const struct ScalosPenListEntry *) ncm->entry1; + const struct ScalosPenListEntry *snle2 = (const struct ScalosPenListEntry *) ncm->entry2; + LONG col1 = ncm->sort_type & MUIV_NList_TitleMark_ColMask; + LONG col2 = ncm->sort_type2 & MUIV_NList_TitleMark2_ColMask; + LONG Result = 0; + + if (ncm->sort_type != MUIV_NList_SortType_None) + { + struct PensListEntry *sple1 = NULL; + struct PensListEntry *sple2 = NULL; + + if (PEN_UNDEFINED != snle1->snle_PenNr) + DoMethod(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIM_NList_GetEntry, snle1->snle_PenNr, &sple1); + if (PEN_UNDEFINED != snle2->snle_PenNr) + DoMethod(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIM_NList_GetEntry, snle2->snle_PenNr, &sple2); + + // primary sorting + switch (col1) + { + case 0: // sort by pen number + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = snle2->snle_PenNr - snle1->snle_PenNr; + else + Result = snle1->snle_PenNr - snle2->snle_PenNr; + break; + case 1: // sort by RGB + if (sple2 && sple1) + { + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = RGBComp(sple2, sple1); + else + Result = RGBComp(sple1, sple2); + } + break; + case 2: // sort by name + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = Stricmp(snle2->snle_PenName, snle1->snle_PenName); + else + Result = Stricmp(snle1->snle_PenName, snle2->snle_PenName); + break; + default: + break; + } + + if (0 == Result && col1 != col2) + { + // Secondary sorting + switch (col2) + { + case 0: // sort by pen number + if (ncm->sort_type2 & MUIV_NList_TitleMark2_TypeMask) + Result = snle1->snle_PenNr - snle2->snle_PenNr; + else + Result = snle2->snle_PenNr - snle1->snle_PenNr; + break; + case 1: // sort by RGB + if (sple1 && sple2) + { + if (ncm->sort_type2 & MUIV_NList_TitleMark2_TypeMask) + Result = RGBComp(sple2, sple1); + else + Result = RGBComp(sple1, sple2); + } + break; + case 2: // sort by name + if (ncm->sort_type2 & MUIV_NList_TitleMark2_TypeMask) + Result = Stricmp(snle2->snle_PenName, snle1->snle_PenName); + else + Result = Stricmp(snle1->snle_PenName, snle2->snle_PenName); + break; + default: + break; + } + } + } + + return Result; +} + +//---------------------------------------------------------------------------- + +static void GetWBColorsFunc(struct Hook *hook, Object *pop, Object *win) +{ + struct PalettePrefsInst *inst = (struct PalettePrefsInst *) hook->h_Data; + + if (inst->ppb_WBScreen) + { + ULONG nColors = inst->ppb_WBScreen->BitMap.Depth; + struct ColorMap *cm = inst->ppb_WBScreen->ViewPort.ColorMap; + struct RGB *RGBTable; + + if (nColors > 8) + nColors = cm->Count; + else + nColors = 1L << nColors; + + DoMethod(inst->ppb_Objects[OBJNDX_WBColorsList], MUIM_NList_Clear); + + RGBTable = AllocVec(nColors * sizeof(struct RGB), MEMF_PUBLIC); + if (RGBTable) + { + ULONG n; + + GetRGB32(cm, 0, nColors, (ULONG *) RGBTable); + + for (n=0; nppb_Objects[OBJNDX_WBColorsList], + MUIM_NList_InsertSingle, &sple, MUIV_NList_Insert_Sorted); + } + + FreeVec(RGBTable); + } + } +} + +//---------------------------------------------------------------------------- + +static APTR AddPenFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PalettePrefsInst *inst = (struct PalettePrefsInst *) hook->h_Data; + ULONG *rgb = NULL; + struct PensListEntry sple; + + sple.sple_Index = 0; + + get(inst->ppb_Objects[OBJNDX_ColorAdjust], MUIA_Coloradjust_RGB, &rgb); + get(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIA_NList_Entries, &sple.sple_Index ); + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: rgb=%08lx %08lx %08lx\n", __LINE__, rgb[0], rgb[1], rgb[2])); + + sple.sple_Red = rgb[0]; + sple.sple_Green = rgb[1]; + sple.sple_Blue = rgb[2]; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: \n", __LINE__)); + SetChangedFlag(inst, TRUE); + + DoMethod(inst->ppb_Objects[OBJNDX_AllocatedPensList], + MUIM_NList_InsertSingle, &sple, MUIV_NList_Insert_Bottom); + set(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIA_NList_Active, MUIV_NList_Active_Bottom); + + UpdatePalettePenCount(inst); + + return 0; +} + +static APTR SelectPalettePenFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PalettePrefsInst *inst = (struct PalettePrefsInst *) hook->h_Data; + struct PensListEntry *sple; + + DoMethod(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &sple); + + if (sple) + set(inst->ppb_Objects[OBJNDX_ColorAdjust], MUIA_Coloradjust_RGB, (ULONG) sple); + + set(inst->ppb_Objects[OBJNDX_DeleteButton], MUIA_Disabled, NULL == sple); + set(inst->ppb_Objects[OBJNDX_ScalosPenList], MUIA_NList_Active, MUIV_NList_Active_Off); + + return 0; +} + +static APTR SelectScalosPenFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PalettePrefsInst *inst = (struct PalettePrefsInst *) hook->h_Data; + struct ScalosPenListEntry *snle = NULL; + + DoMethod(inst->ppb_Objects[OBJNDX_ScalosPenList], MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &snle); + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: snle=%08lx\n", __LINE__, snle)); + + if (snle) + { + set(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIA_NList_Active, snle->snle_PenNr); + } + + return 0; +} + +static APTR ChangePenColorFunc(struct Hook *hook, Object *o, ULONG **msg) +{ + struct PalettePrefsInst *inst = (struct PalettePrefsInst *) hook->h_Data; + struct PensListEntry *sple = NULL; + ULONG *rgb = *msg; + LONG ActiveEntryNr = 0; + + DoMethod(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &sple); + get(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIA_NList_Active, &ActiveEntryNr); + + if (sple) + { + if (sple->sple_Red != rgb[0] || sple->sple_Green != rgb[1] || sple->sple_Blue != rgb[2]) + { + ULONG n, nEntries = 0; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: \n", __LINE__)); + SetChangedFlag(inst, TRUE); + + sple->sple_Red = rgb[0]; + sple->sple_Green = rgb[1]; + sple->sple_Blue = rgb[2]; + + DoMethod(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIM_NList_Redraw, MUIV_NList_Redraw_Active); + + get(inst->ppb_Objects[OBJNDX_ScalosPenList], MUIA_NList_Entries, &nEntries); + + for (n=0; nppb_Objects[OBJNDX_ScalosPenList], MUIM_NList_GetEntry, n, &snle); + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: snle_PenNr=%ld ActiveEntryNr=%ld\n", __LINE__, snle->snle_PenNr, ActiveEntryNr)); + + if (snle && snle->snle_PenNr == ActiveEntryNr) + DoMethod(inst->ppb_Objects[OBJNDX_ScalosPenList], MUIM_NList_Redraw, n); + } + } + } + + return 0; +} + +static APTR ResetToDefaultsFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PalettePrefsInst *inst = (struct PalettePrefsInst *) hook->h_Data; + ULONG n; + LONG EntryNr; + struct ScalosPenListEntry *snle; + const struct PenListInit *pli; + + DoMethod(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIM_NList_Clear); + + for (n=0; nppb_Objects[OBJNDX_AllocatedPensList], + MUIM_NList_InsertSingle, &DefaultPaletteEntries[n], MUIV_NList_Insert_Sorted); + } + + for (pli=PenListContents, EntryNr=0; pli->pli_PenIndex; pli++, EntryNr++) + { + DoMethod(inst->ppb_Objects[OBJNDX_ScalosPenList], MUIM_NList_GetEntry, EntryNr, &snle); + + if (NULL == snle) + break; + + snle->snle_PenIndex = pli->pli_PenIndex; + snle->snle_PenNr = pli->pli_PenNr; + snle->snle_PenName = GetLocString(pli->pli_PenNameID); + } + + DoMethod(inst->ppb_Objects[OBJNDX_ScalosPenList], MUIM_NList_Redraw, MUIV_NList_Redraw_All); + + SetChangedFlag(inst, TRUE); + + return NULL; +} + +static APTR AboutFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PalettePrefsInst *inst = (struct PalettePrefsInst *) hook->h_Data; + + MUI_Request(inst->ppb_Objects[OBJNDX_APP_Main], inst->ppb_Objects[OBJNDX_WIN_Main], 0, NULL, + GetLocString(MSGID_ABOUTREQOK), + GetLocString(MSGID_ABOUTREQFORMAT), + MajorVersion, MinorVersion, COMPILER_STRING, CURRENTYEAR); + + return 0; +} + +static APTR OpenFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PalettePrefsInst *inst = (struct PalettePrefsInst *) hook->h_Data; + + if (NULL == inst->ppb_LoadReq) + { + inst->ppb_LoadReq = MUI_AllocAslRequestTags(ASL_FileRequest, + ASLFR_InitialFile, "Palette.pre", + ASLFR_Flags1, FRF_DOPATTERNS, + ASLFR_InitialDrawer, "SYS:Prefs/presets", + ASLFR_InitialPattern, "#?.(pre|prefs)", + ASLFR_UserData, inst, + ASLFR_IntuiMsgFunc, &inst->ppb_Hooks[HOOKNDX_AslIntuiMsg], + TAG_END); + } + if (inst->ppb_LoadReq) + { + BOOL Result; + struct Window *win = NULL; + + get(inst->ppb_Objects[OBJNDX_WIN_Main], MUIA_Window_Window, &win); + + //AslRequest( + Result = MUI_AslRequestTags(inst->ppb_LoadReq, + ASLFR_Window, win, + ASLFR_SleepWindow, TRUE, + ASLFR_TitleText, GetLocString(MSGID_MENU_PROJECT_OPEN), + TAG_END); + + if (Result) + { + BPTR dirLock = Lock(inst->ppb_LoadReq->fr_Drawer, ACCESS_READ); + + if (dirLock) + { + BPTR oldDir = CurrentDir(dirLock); + + DoMethod(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIM_NList_Clear); + + ReadPrefsFile(inst, inst->ppb_LoadReq->fr_File, FALSE); + + CurrentDir(oldDir); + UnLock(dirLock); + } + } + } + + return 0; +} + +static APTR LastSavedFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PalettePrefsInst *inst = (struct PalettePrefsInst *) hook->h_Data; + + DoMethod(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIM_NList_Clear); + + ReadPrefsFile(inst, "ENVARC:Scalos/Palette13.prefs", FALSE); + + SetChangedFlag(inst, TRUE); + + return 0; +} + +static APTR RestoreFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PalettePrefsInst *inst = (struct PalettePrefsInst *) hook->h_Data; + + DoMethod(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIM_NList_Clear); + + ReadPrefsFile(inst, "ENV:Scalos/Palette13.prefs", FALSE); + + SetChangedFlag(inst, TRUE); + + return 0; +} + +static APTR SaveAsFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PalettePrefsInst *inst = (struct PalettePrefsInst *) hook->h_Data; + + if (NULL == inst->ppb_SaveReq) + { + inst->ppb_SaveReq = MUI_AllocAslRequestTags(ASL_FileRequest, + ASLFR_InitialFile, "Palette.pre", + ASLFR_DoSaveMode, TRUE, + ASLFR_InitialDrawer, "SYS:Prefs/presets", + ASLFR_UserData, inst, + ASLFR_IntuiMsgFunc, &inst->ppb_Hooks[HOOKNDX_AslIntuiMsg], + TAG_END); + } + if (inst->ppb_SaveReq) + { + BOOL Result; + struct Window *win = NULL; + + get(inst->ppb_Objects[OBJNDX_WIN_Main], MUIA_Window_Window, &win); + + //AslRequest( + Result = MUI_AslRequestTags(inst->ppb_SaveReq, + ASLFR_TitleText, GetLocString(MSGID_MENU_PROJECT_SAVEAS), + ASLFR_Window, win, + ASLFR_SleepWindow, TRUE, + TAG_END); + + if (Result) + { + BPTR dirLock = Lock(inst->ppb_SaveReq->fr_Drawer, ACCESS_READ); + + if (dirLock) + { + LONG Result; + BPTR oldDir = CurrentDir(dirLock); + + Result = WritePrefsFile(inst, inst->ppb_SaveReq->fr_File); + + if (RETURN_OK == Result) + { + if (inst->ppb_fCreateIcons) + SaveIcon(inst, inst->ppb_SaveReq->fr_File); + } + + CurrentDir(oldDir); + UnLock(dirLock); + } + } + } + + return 0; +} + +static APTR DeletePenFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PalettePrefsInst *inst = (struct PalettePrefsInst *) hook->h_Data; + LONG ActiveEntryNr = MUIV_NList_Active_Off; + LONG PenCount = 0; + + get(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIA_NList_Active, &ActiveEntryNr); + get(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIA_NList_Entries, &PenCount); + + if (MUIV_NList_Active_Off != ActiveEntryNr) + { + LONG n; + LONG Entries = 0; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: \n", __LINE__)); + SetChangedFlag(inst, TRUE); + + get(inst->ppb_Objects[OBJNDX_ScalosPenList], MUIA_NList_Entries, &Entries); + + // adjust all pen numbers in inst->ppb_Objects[OBJNDX_ScalosPenList] + + for (n=0; nppb_Objects[OBJNDX_ScalosPenList], MUIM_NList_GetEntry, n, &snle); + + if (snle->snle_PenNr == ActiveEntryNr) + snle->snle_PenNr = PEN_UNDEFINED; + if (snle->snle_PenNr > ActiveEntryNr) + snle->snle_PenNr--; + } + + DoMethod(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIM_NList_Remove, MUIV_NList_Remove_Active); + DoMethod(inst->ppb_Objects[OBJNDX_ScalosPenList], MUIM_NList_Redraw, MUIV_NList_Redraw_All); + } + + UpdatePalettePenCount(inst); + + return 0; +} + + +static APTR ContextMenuTriggerHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PalettePrefsInst *inst = (struct PalettePrefsInst *) hook->h_Data; + Object *MenuObj = *((Object **) msg); + ULONG MenuHookIndex = 0; + struct Hook *MenuHook = NULL; + + d1(kprintf(__FUNC__ "/%ld: MenuObj=%08lx\n", __LINE__, MenuObj)); + d1(kprintf(__FUNC__ "/%ld: msg=%08lx *msg=%08lx\n", __LINE__, msg, *((ULONG *) msg))); + + get(MenuObj, MUIA_UserData, &MenuHookIndex); + + if (MenuHookIndex > 0 && MenuHookIndex < HOOKNDX_MAX) + MenuHook = &inst->ppb_Hooks[MenuHookIndex]; + + d1(kprintf(__FUNC__ "/%ld: MenuHook=%08lx\n", __LINE__, MenuHook)); + if (MenuHook) + DoMethod(inst->ppb_Objects[OBJNDX_Group_Main], MUIM_CallHook, MenuHook, MenuObj); + + return NULL; +} + +//---------------------------------------------------------------------------- + +static void AslIntuiMsgHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PalettePrefsInst *inst = (struct PalettePrefsInst *) hook->h_Data; + struct IntuiMessage *iMsg = (struct IntuiMessage *) msg; + + if (IDCMP_REFRESHWINDOW == iMsg->Class) + { + DoMethod(inst->ppb_Objects[OBJNDX_APP_Main], MUIM_Application_CheckRefresh); + } +} + +//---------------------------------------------------------------------------- + +static void InitPenList(struct PalettePrefsInst *inst) +{ + const struct PenListInit *pli; + + for (pli=PenListContents; pli->pli_PenIndex; pli++) + { + struct ScalosPenListEntry snle; + + snle.snle_PenIndex = pli->pli_PenIndex; + snle.snle_PenNr = pli->pli_PenNr; + snle.snle_PenName = GetLocString(pli->pli_PenNameID); + + DoMethod(inst->ppb_Objects[OBJNDX_ScalosPenList], + MUIM_NList_InsertSingle, &snle, MUIV_NList_Insert_Sorted); + } +} + + +static LONG ReadPrefsFile(struct PalettePrefsInst *inst, CONST_STRPTR Filename, BOOL Quiet) +{ + LONG Result; + struct IFFHandle *iff; + BOOL iffOpened = FALSE; + + DoMethod(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIM_NList_Clear); + + do { + iff = AllocIFF(); + if (NULL == iff) + { + Result = IoErr(); + break; + } + + InitIFFasDOS(iff); + + iff->iff_Stream = (IPTR)Open(Filename, MODE_OLDFILE); + if (0 == iff->iff_Stream) + { + Result = IoErr(); + break; + } + + Result = OpenIFF(iff, IFFF_READ); + if (RETURN_OK != Result) + break; + + iffOpened = TRUE; + + Result = StopChunks(iff, StopChunkList, 2); + if (RETURN_OK != Result) + break; + + while (RETURN_OK == Result) + { + struct ContextNode *cn; + + Result = ParseIFF(iff, IFFPARSE_SCAN); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: Result=%ld\n", __LINE__, Result)); + if (RETURN_OK != Result) + break; + + cn = CurrentChunk(iff); + if (NULL == cn) + break; + + if (ID_PENS == cn->cn_ID) + { + LONG Actual; + WORD Pen, PenCount; + + Actual = ReadChunkBytes(iff, &PenCount, sizeof(PenCount)); + if (Actual < 0) + break; + + PenCount = SCA_BE2WORD(PenCount); + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: PenCount=%ld\n", __LINE__, PenCount)); + + if (PenCount < 2) + break; + + for (Pen=0; Pen= 0) + { + sPen.sp_pentype = SCA_BE2WORD(sPen.sp_pentype); + sPen.sp_pen = SCA_BE2WORD(sPen.sp_pen); + SearchAndSetPen(inst, &sPen); + } + } + } + else if (ID_SPAL == cn->cn_ID) + { + LONG n, ScreenColorListEntries; + LONG Actual; + + Actual = ReadChunkBytes(iff, &ScreenColorListEntries, sizeof(ScreenColorListEntries)); + if (Actual < 0) + break; + ScreenColorListEntries = SCA_BE2LONG(ScreenColorListEntries); + ScreenColorListEntries >>= 16; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: ScreenColorListEntries=%ld\n", __LINE__, ScreenColorListEntries)); + + for (n=0; ncn_Size, Actual)); + if (Actual < 0) + { + Result = IoErr(); + break; + } + + sple.sple_Index = n; + sple.sple_Red = SCA_BE2LONG(splc.splc_Red); + sple.sple_Green = SCA_BE2LONG(splc.splc_Green); + sple.sple_Blue = SCA_BE2LONG(splc.splc_Blue); + + DoMethod(inst->ppb_Objects[OBJNDX_AllocatedPensList], + MUIM_NList_InsertSingle, &sple, MUIV_NList_Insert_Sorted); + } + } + } + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: Result=%ld\n", __LINE__, Result)); + if (IFFERR_EOF == Result) + Result = RETURN_OK; + } while (0); + + if (iff) + { + if (iffOpened) + CloseIFF(iff); + + if (iff->iff_Stream) + Close((BPTR)iff->iff_Stream); + + FreeIFF(iff); + } + + if (RETURN_OK != Result && !Quiet) + { + char Buffer[120]; + + Fault(Result, "", Buffer, sizeof(Buffer) - 1); + + // MUI_RequestA() + MUI_Request(inst->ppb_Objects[OBJNDX_APP_Main], inst->ppb_Objects[OBJNDX_WIN_Main], 0, NULL, + GetLocString(MSGID_ABOUTREQOK), + GetLocString(MSGID_REQTITLE_READERROR), + Filename, + Buffer); + } + + DoMethod(inst->ppb_Objects[OBJNDX_ScalosPenList], MUIM_NList_Redraw, MUIV_NList_Redraw_All); + UpdatePalettePenCount(inst); + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: Result=%ld\n", __LINE__, Result)); + + return Result; +} + + +static void SearchAndSetPen(struct PalettePrefsInst *inst, const struct ScalosPen *sPen) +{ + ULONG n = 0; + + while (1) + { + struct ScalosPenListEntry *snle = NULL; + + DoMethod(inst->ppb_Objects[OBJNDX_ScalosPenList], MUIM_NList_GetEntry, n, &snle); + if (NULL == snle) + break; + + if (snle->snle_PenIndex == sPen->sp_pentype) + { + snle->snle_PenNr = sPen->sp_pen; + } + + n++; + } +} + + +static LONG WritePrefsFile(struct PalettePrefsInst *inst, CONST_STRPTR Filename) +{ + struct IFFHandle *iff; + LONG Result; + BOOL IffOpen = FALSE; + + do { + static const struct PrefHeader prefHeader = { 1, 0, 0L }; + ULONG n, Entries; + UWORD wEntries; + + iff = AllocIFF(); + if (NULL == iff) + { + Result = IoErr(); + break; + } + + InitIFFasDOS(iff); + + iff->iff_Stream = (IPTR)Open(Filename, MODE_NEWFILE); + if (0 == iff->iff_Stream) + { + // ... try to create missing directories here + STRPTR FilenameCopy; + + Result = IoErr(); + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: Result=%ld\n", __LINE__, Result)); + + FilenameCopy = AllocVec(1 + strlen(Filename), MEMF_PUBLIC); + + if (FilenameCopy) + { + STRPTR lp; + + strcpy(FilenameCopy, Filename); + + lp = PathPart(FilenameCopy); + if (lp) + { + BPTR dirLock; + + *lp = '\0'; + dirLock = CreateDir(FilenameCopy); + + if (dirLock) + UnLock(dirLock); + + iff->iff_Stream = (IPTR)Open(Filename, MODE_NEWFILE); + if (0 == iff->iff_Stream) + Result = IoErr(); + else + Result = RETURN_OK; + } + + FreeVec(FilenameCopy); + } + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: Result=%ld\n", __LINE__, Result)); + if (RETURN_OK != Result) + break; + } + + Result = OpenIFF(iff, IFFF_WRITE); + if (RETURN_OK != Result) + break; + + IffOpen = TRUE; + + Result = PushChunk(iff, ID_PREF, ID_FORM, IFFSIZE_UNKNOWN); + if (RETURN_OK != Result) + break; + + Result = PushChunk(iff, 0, ID_PRHD, IFFSIZE_UNKNOWN); + if (RETURN_OK != Result) + break; + + if (WriteChunkBytes(iff, (APTR) &prefHeader, sizeof(prefHeader)) < 0) + { + Result = IoErr(); + break; + } + + Result = PopChunk(iff); + if (RETURN_OK != Result) + break; + + Result = PushChunk(iff, 0, ID_SPAL, IFFSIZE_UNKNOWN); + if (RETURN_OK != Result) + break; + + get(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIA_List_Entries, &Entries); + + Entries <<= 16; + Entries = SCA_LONG2BE(Entries); + + if (WriteChunkBytes(iff, &Entries, sizeof(Entries)) < 0) + { + Result = IoErr(); + break; + } + + n = 0; + while (RETURN_OK == Result) + { + struct PensListConstruct splc; + struct PensListEntry *sple = NULL; + + DoMethod(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIM_List_GetEntry, n, &sple); + if (NULL == sple) + break; + + splc.splc_Red = SCA_LONG2BE(sple->sple_Red); + splc.splc_Green = SCA_LONG2BE(sple->sple_Green); + splc.splc_Blue = SCA_LONG2BE(sple->sple_Blue); + + if (WriteChunkBytes(iff, &splc, sizeof(struct PensListConstruct)) < 0) + { + Result = IoErr(); + break; + } + n++; + } + if (RETURN_OK != Result) + break; + + Result = PopChunk(iff); + if (RETURN_OK != Result) + break; + + Result = PushChunk(iff, 0, ID_PENS, IFFSIZE_UNKNOWN); + if (RETURN_OK != Result) + break; + + get(inst->ppb_Objects[OBJNDX_ScalosPenList], MUIA_List_Entries, &Entries); + + wEntries = Entries; + wEntries = SCA_WORD2BE(wEntries); + + if (WriteChunkBytes(iff, &wEntries, sizeof(wEntries)) < 0) + { + Result = IoErr(); + break; + } + + n = 0; + while (RETURN_OK == Result) + { + struct ScalosPen sPen; + struct ScalosPenListEntry *snle = NULL; + + DoMethod(inst->ppb_Objects[OBJNDX_ScalosPenList], MUIM_List_GetEntry, n, &snle); + if (NULL == snle) + break; + + sPen.sp_pentype = SCA_WORD2BE(snle->snle_PenIndex); + sPen.sp_pen = SCA_WORD2BE(snle->snle_PenNr); + + if (WriteChunkBytes(iff, &sPen, sizeof(sPen)) < 0) + { + Result = IoErr(); + break; + } + n++; + } + if (RETURN_OK != Result) + break; + + Result = PopChunk(iff); + if (RETURN_OK != Result) + break; + + Result = PopChunk(iff); + if (RETURN_OK != Result) + break; + + } while (0); + + if (iff) + { + if (IffOpen) + CloseIFF(iff); + + if (iff->iff_Stream) + { + Close((BPTR)iff->iff_Stream); + iff->iff_Stream = 0; + } + + FreeIFF(iff); + } + + if (RETURN_OK != Result) + { + char Buffer[120]; + + Fault(Result, "", Buffer, sizeof(Buffer) - 1); + + // MUI_RequestA() + MUI_Request(inst->ppb_Objects[OBJNDX_APP_Main], inst->ppb_Objects[OBJNDX_WIN_Main], 0, NULL, + GetLocString(MSGID_ABOUTREQOK), + GetLocString(MSGID_REQTITLE_SAVEERROR), + Filename, + Buffer); + } + + return Result; +} + + +static LONG SaveIcon(struct PalettePrefsInst *inst, CONST_STRPTR IconName) +{ + struct DiskObject *icon, *allocIcon; + + static UBYTE ImageData[] = + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0x80, 0x00, 0x40, 0x00, 0x00, 0x00, 0x18, 0x00, 0x60, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x20, 0xFC, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x41, 0x02, 0x08, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x40, 0x82, 0x08, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x40, 0x82, 0x08, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x21, 0x04, 0x08, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x1E, 0x18, 0x10, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x20, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x02, 0x1C, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x0C, 0x00, + 0x40, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x0C, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, + 0xD5, 0x55, 0x55, 0x55, 0x55, 0x56, 0x00, 0x00, 0xD5, 0x55, 0x50, 0x00, 0x55, 0x55, 0x80, 0x00, + 0xD5, 0x55, 0x47, 0xFF, 0x95, 0x55, 0x60, 0x00, 0xD5, 0x55, 0x5F, 0x03, 0xE5, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x3E, 0x55, 0xF5, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x3F, 0x55, 0xF5, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x3F, 0x55, 0xF5, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x5E, 0x53, 0xF5, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x41, 0x47, 0xE5, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x55, 0x1F, 0xD5, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x55, 0x7F, 0x15, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x54, 0xFC, 0x55, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x55, 0xE1, 0x55, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x54, 0xF5, 0x55, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x55, 0x05, 0x55, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x54, 0xF5, 0x55, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x54, 0xF5, 0x55, 0x55, 0x50, 0x00, 0x35, 0x55, 0x55, 0x05, 0x55, 0x55, 0x50, 0x00, + 0x0D, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, 0x00, 0x03, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + static struct Image NormalImage = + { + 0, 0, 54, 23, + 2, + (UWORD *)ImageData, + 3, 0, + NULL + }; + + static STRPTR defToolTypes[] = + { + "ACTION=USE", + NULL + }; + + static struct DiskObject DefaultIcon = + { + WB_DISKMAGIC, WB_DISKVERSION, + + { + NULL, + 0, 0, 54, 24, + GFLG_GADGIMAGE | GFLG_GADGHBOX, + GACT_RELVERIFY | GACT_IMMEDIATE, + GTYP_BOOLGADGET, + &NormalImage, NULL, + NULL, + 0, + NULL, + 0, + NULL + }, + + WBPROJECT, + NULL, + defToolTypes, + NO_ICON_POSITION, NO_ICON_POSITION, + NULL, + NULL, + 8192 + }; + + icon = allocIcon = GetDiskObject("ENV:sys/def_ScaPalettePrefs"); + if (NULL == icon) + icon = allocIcon = GetDiskObject("ENV:sys/def_pref"); + if (NULL == icon) + icon = &DefaultIcon; + + if (icon) + { + STRPTR oldDefaultTool = icon->do_DefaultTool; + + icon->do_DefaultTool = (STRPTR) inst->ppb_ProgramName; + + PutDiskObject((STRPTR) IconName, icon); + + icon->do_DefaultTool = oldDefaultTool; + + if (allocIcon) + FreeDiskObject(allocIcon); + } + + return 0; +} + + +static void UpdatePalettePenCount(struct PalettePrefsInst *inst) +{ + ULONG allocatedPens = 0; + UWORD availablePens; + + availablePens = 1 + inst->ppb_WBScreen->ViewPort.ColorMap->PalExtra->pe_SharableColors; + + if (inst->ppb_Objects[OBJNDX_AllocatedPensList]) + get(inst->ppb_Objects[OBJNDX_AllocatedPensList], MUIA_List_Entries, &allocatedPens); + else + allocatedPens = 0; + + sprintf(inst->ppb_PalettePenListTitle, GetLocString(MSGID_TITLE_PALETTEPENLIST), + allocatedPens, availablePens); + + if (inst->ppb_Objects[OBJNDX_AllocatedPensListTitleObj]) + set(inst->ppb_Objects[OBJNDX_AllocatedPensListTitleObj], MUIA_Text_Contents, (ULONG) inst->ppb_PalettePenListTitle); + + set(inst->ppb_Objects[OBJNDX_NewButton], MUIA_Disabled, allocatedPens >= availablePens); +} + +//---------------------------------------------------------------------------- + +static ULONG GetPenReferenceCount(struct PalettePrefsInst *inst, ULONG PenNr) +{ + ULONG Entries = 0; + ULONG References = 0; + ULONG n; + + get(inst->ppb_Objects[OBJNDX_ScalosPenList], MUIA_NList_Entries, &Entries); + + for (n=0; nppb_Objects[OBJNDX_ScalosPenList], MUIM_NList_GetEntry, n, &snle); + if (snle) + { + if (snle->snle_PenNr == PenNr) + References++; + } + } + + return References; +} + +//---------------------------------------------------------------------------- + +static void SetChangedFlag(struct PalettePrefsInst *inst, BOOL changed) +{ + if (changed != inst->ppb_Changed) + { + set(inst->ppb_Objects[OBJNDX_Lamp_Changed], + MUIA_Lamp_Color, changed ? MUIV_Lamp_Color_Ok : MUIV_Lamp_Color_Off); + inst->ppb_Changed = changed; + } +} + +//--------------------------------------------------------------- + +BOOL initPlugin(struct PluginBase *PluginBase) +{ + MajorVersion = PluginBase->pl_LibNode.lib_Version; + MinorVersion = PluginBase->pl_LibNode.lib_Revision; + + d1(kprintf("%s/%s/%ld: Signature=%08lx\n", __FILE__, __FUNC__, __LINE__, Signature)); + + if (0x4711 == Signature++) + { + d1(kprintf(__FUNC__ "/%ld: PluginBase=%08lx procName=<%s>\n", __LINE__, \ + PluginPrefsBase, FindTask(NULL)->tc_Node.ln_Name)); + + if (!OpenLibraries()) + return FALSE; + +#if !defined(__amigaos4__) && !defined(__AROS__) + if (_STI_240_InitMemFunctions()) + return FALSE; +#endif + + PalettePrefsClass = MUI_CreateCustomClass(&PluginBase->pl_LibNode, MUIC_Group, + NULL, sizeof(struct PalettePrefsInst), DISPATCHER_REF(PalettePrefs)); + + d1(kprintf(__FUNC__ "/%ld: PalettePrefsClass=%08lx\n", __LINE__, PalettePrefsClass)); + if (NULL == PalettePrefsClass) + return FALSE; + + d1(kprintf(__FUNC__ "/%ld: PalettePrefsCatalog=%08lx\n", __LINE__, PalettePrefsCatalog)); + d1(kprintf(__FUNC__ "/%ld: LocaleBase=%08lx\n", __LINE__, LocaleBase)); + + if (LocaleBase) + { + d1(kprintf(__FUNC__ "/%ld: PalettePrefsLocale=%08lx\n", __LINE__, PalettePrefsLocale)); + + if (NULL == PalettePrefsLocale) + PalettePrefsLocale = OpenLocale(NULL); + + d1(kprintf(__FUNC__ "/%ld: PalettePrefsLocale=%08lx\n", __LINE__, PalettePrefsLocale)); + + if (PalettePrefsLocale) + { + d1(kprintf(__FUNC__ "/%ld: PalettePrefsCatalog=%08lx\n", __LINE__, PalettePrefsCatalog)); + + if (NULL == PalettePrefsCatalog) + { + PalettePrefsCatalog = OpenCatalog(PalettePrefsLocale, + (STRPTR) "Scalos/ScalosPalette.catalog", NULL); + + d1(kprintf(__FUNC__ "/%ld: \n", __LINE__)); + } + } + } + + TranslateNewMenu(ContextMenus); + + NewColorAdjustClass = MUI_CreateCustomClass(NULL, MUIC_Coloradjust, NULL, + 4, DISPATCHER_REF(NewColorAdjust)); + d1(kprintf( "%s/%s/%ld: NewColorAdjustClass=%08lx\n", __FILE__, __FUNC__, __LINE__, NewColorAdjustClass)); + if (NULL == NewColorAdjustClass) + return FALSE; // Failure + + NewPalettePenListClass = MUI_CreateCustomClass(NULL, MUIC_NList, NULL, + 4, DISPATCHER_REF(NewPalettePenList)); + if (NULL == NewPalettePenListClass) + return FALSE; // Failure + + NewScalosPenListClass = MUI_CreateCustomClass(NULL, MUIC_NList, NULL, + sizeof(struct NewScalosPenListInst), DISPATCHER_REF(NewScalosPenList)); + if (NULL == NewScalosPenListClass) + return FALSE; // Failure + + myNListClass = MUI_CreateCustomClass(NULL, MUIC_NList, + NULL, 4, DISPATCHER_REF(myNList)); + if (NULL == myNListClass) + return FALSE; // Failure + + DataTypesImageClass = InitDtpicClass(); + d1(KPrintF(__FUNC__ "/%ld: DataTypesImageClass=%08lx\n", __LINE__, DataTypesImageClass)); + if (NULL == DataTypesImageClass) + return FALSE; // Failure + } + + d1(kprintf(__FUNC__ "/%ld: Success\n", __LINE__)); + + return TRUE; // Success +} + +//---------------------------------------------------------------------------- + +static LONG ColorComp(ULONG Color1, ULONG Color2) +{ + if (Color1 == Color2) + return 0; + if (Color1 > Color2) + return 1; + + return -1; +} + +static LONG RGBComp(const struct PensListEntry *sple1, const struct PensListEntry *sple2) +{ + LONG Result; + + Result = ColorComp(sple1->sple_Red, sple2->sple_Red); + if (0 == Result) + Result = ColorComp(sple1->sple_Green, sple2->sple_Green); + if (0 == Result) + Result = ColorComp(sple1->sple_Blue, sple2->sple_Blue); + + return Result; +} + +//---------------------------------------------------------------------------- + +#if !defined(__SASC) && ! defined(__amigaos4__) + +void exit(int x) +{ + (void) x; + while (1) + ; +} + +APTR _WBenchMsg; + +#endif /* !__SASC && !__amigaos4__ */ + +//---------------------------------------------------------------------------- diff --git a/scalos/Plugins/Prefs/Palette/PalettePrefs.h b/scalos/Plugins/Prefs/Palette/PalettePrefs.h new file mode 100644 index 000000000..ad2cc56c0 --- /dev/null +++ b/scalos/Plugins/Prefs/Palette/PalettePrefs.h @@ -0,0 +1,110 @@ +// PalettePrefs.h +// $Date$ +// $Revision$ + + +#ifndef SCALOS_PALETTEPREFS_H +#define SCALOS_PALETTEPREFS_H + +enum HookIndex +{ + HOOKNDX_WBPensListConstruct, + HOOKNDX_WBPensListDestruct, + HOOKNDX_WBPensListDisplay, + HOOKNDX_WBPensListCompare, + + HOOKNDX_AllocatedPensListConstruct, + HOOKNDX_AllocatedPensListDestruct, + HOOKNDX_AllocatedPensListDisplay, + HOOKNDX_AllocatedPensListCompare, + + HOOKNDX_ScalosPenListConstruct, + HOOKNDX_ScalosPenListDestruct, + HOOKNDX_ScalosPenListDisplay, + HOOKNDX_ScalosPenListCompare, + + HOOKNDX_GetWBColors, + + HOOKNDX_AddPen, + HOOKNDX_SelectPalettePen, + HOOKNDX_SelectScalosPen, + HOOKNDX_ChangePenColor, + HOOKNDX_ResetToDefaults, + HOOKNDX_About, + HOOKNDX_Open, + HOOKNDX_LastSaved, + HOOKNDX_Restore, + HOOKNDX_SaveAs, + HOOKNDX_DeletePen, + HOOKNDX_ContextMenuTrigger, + HOOKNDX_AslIntuiMsg, + + HOOKNDX_MAX +}; + +enum ObjectIndex +{ + OBJNDX_APP_Main, + OBJNDX_WIN_Main, + + OBJNDX_NewButton, + OBJNDX_DeleteButton, + OBJNDX_AllocatedPensList, + OBJNDX_ScalosPenList, + OBJNDX_ColorAdjust, + OBJNDX_WBColorsList, + OBJNDX_AllocatedPensListTitleObj, + OBJNDX_Lamp_Changed, + + OBJNDX_ContextMenu, + + OBJNDX_Group_Main, + + OBJNDX_MAX +}; + +struct PalettePrefsInst +{ + ULONG ppb_fCreateIcons; + ULONG ppb_fPreview; + ULONG ppb_fAutoPreview; + ULONG ppb_fDontChange; + + BYTE ppb_PalettePrecision; + ULONG ppb_PreviewWeight; + + BOOL ppb_Changed; + struct Screen *ppb_WBScreen; + + ULONG ppb_AllocatedPensListImageIndex; + + CONST_STRPTR ppb_ProgramName; + + struct Hook ppb_Hooks[HOOKNDX_MAX]; + Object *ppb_Objects[OBJNDX_MAX]; + + struct FileRequester *ppb_LoadReq; + struct FileRequester *ppb_SaveReq; + + char ppb_PalettePenListTitle[100]; +}; + +//---------------------------------------------------------------------------- + +#define d1(x) ; +#define d2(x) x; + +// from debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +//---------------------------------------------------------------------------- + +struct ScalosPalette_LocaleInfo +{ + APTR li_LocaleBase; + APTR li_Catalog; + struct LocaleIFace *li_ILocale; +}; + +#endif /* SCALOS_PALETTEPREFS_H */ diff --git a/scalos/Plugins/Prefs/Palette/PalettePrefsImage.h b/scalos/Plugins/Prefs/Palette/PalettePrefsImage.h new file mode 100644 index 000000000..6f5a78a80 --- /dev/null +++ b/scalos/Plugins/Prefs/Palette/PalettePrefsImage.h @@ -0,0 +1,55 @@ +static const ULONG Palette_colors[48] = +{ + 0x22222222,0x55555555,0x22222222, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0x55555555,0x55555555,0x55555555, + 0x22222222,0x22222222,0x99999999, + 0x00000000,0x66666666,0xffffffff, + 0x33333333,0x88888888,0x33333333, + 0x44444444,0x99999999,0x88888888, + 0x88888888,0x00000000,0x00000000, + 0xbbbbbbbb,0x00000000,0x77777777, + 0xdddddddd,0x33333333,0x33333333, + 0xdddddddd,0x66666666,0x33333333, + 0xbbbbbbbb,0x44444444,0xbbbbbbbb, + 0xdddddddd,0xaaaaaaaa,0x44444444, + 0xeeeeeeee,0xeeeeeeee,0x11111111, + 0x00000000,0x00000000,0x00000000, + 0xeeeeeeee,0xeeeeeeee,0xeeeeeeee, +}; + +#define PALETTE_WIDTH 21 +#define PALETTE_HEIGHT 21 +#define PALETTE_DEPTH 4 +#define PALETTE_COMPRESSION 0 +#define PALETTE_MASKING 2 + +#ifdef USE_PALETTE_HEADER +static const struct BitMapHeader Palette_header = +{ 21,21,0,0,4,2,0,0,0,44,44,320,256 }; +#endif + +static const UBYTE Palette_body[336] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x1e,0x00,0x00, +0x04,0x1e,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x0c,0x00,0x00,0x0f,0x1b,0x00, +0x00,0x0f,0x1b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x80,0x00,0x1f,0xb7, +0x00,0x00,0x1f,0xb7,0x00,0x00,0x20,0x04,0x00,0x00,0x03,0x08,0x00,0x00,0x1e, +0xfb,0x80,0x00,0x1f,0xfb,0x80,0x00,0x26,0x1c,0x00,0x00,0x01,0x9c,0x40,0x00, +0x19,0x83,0x80,0x00,0x1f,0xe3,0x80,0x00,0x07,0x1c,0x00,0x00,0x03,0xdc,0x40, +0x00,0x3b,0xc3,0x80,0x00,0x3c,0xe3,0x80,0x00,0x07,0x1c,0x00,0x00,0x03,0xfd, +0xc0,0x00,0x3b,0xe2,0x00,0x00,0x3c,0xe3,0x80,0x00,0x06,0x10,0x00,0x00,0x00, +0xe1,0xc0,0x00,0x3f,0xee,0x00,0x00,0x3f,0xe3,0x80,0x00,0x07,0x88,0x00,0x00, +0x00,0x73,0x80,0x00,0x3f,0xd4,0x00,0x00,0x3f,0x53,0x80,0x00,0x07,0xcc,0x00, +0x00,0x00,0x3a,0x00,0x00,0x1f,0xe9,0x00,0x00,0x1f,0x27,0x00,0x00,0x02,0x06, +0x00,0x00,0x02,0xe9,0x00,0x00,0x1f,0xe8,0x00,0x00,0x1f,0x1f,0x00,0x00,0x01, +0x13,0x00,0x00,0x01,0xf4,0x00,0x00,0x1f,0xe4,0x00,0x00,0x1f,0x1f,0x00,0x00, +0x02,0x19,0x80,0x00,0x03,0xfa,0x00,0x00,0x0e,0xe2,0x00,0x00,0x0f,0x1f,0x80, +0x00,0x00,0x84,0xc0,0x00,0x07,0xff,0x00,0x00,0x00,0x85,0x00,0x00,0x07,0xf9, +0xc0,0x00,0x00,0x90,0x60,0x00,0x01,0xf3,0x80,0x00,0x00,0x90,0x80,0x00,0x01, +0xe0,0xe0,0x00,0x00,0x00,0x20,0x00,0x00,0x01,0xc0,0x00,0x00,0x00,0x40,0x00, +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, }; diff --git a/scalos/Plugins/Prefs/Palette/config.mk b/scalos/Plugins/Prefs/Palette/config.mk new file mode 100755 index 000000000..90a31c4d3 --- /dev/null +++ b/scalos/Plugins/Prefs/Palette/config.mk @@ -0,0 +1,76 @@ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +DATATYPESMCC_DIR = $(TOPLEVEL)/common/DataTypesMCC +COMMON_DIR = $(TOPLEVEL)/common/Plugin + +INCLUDES += -I$(DATATYPESMCC_DIR) -I$(COMMON_DIR) + +SCALOS_LOCALE = $(OBJDIR)/ScalosPalette_locale.h + +CFLAGS += -D SCALOSLOCALE=$(SCALOS_LOCALE) + +vpath %.c $(COMMON_DIR) + +############################################################################## + +include $(COMMON_DIR)/config.mk + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += -nostartfiles \ + -lmempools +# --verbose + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += -nostartfiles \ +# + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +LFLAGS += -nostartfiles -lmui \ +# + + +else + +############################################################################### +# AmigaOS + +LFLAGS += -lscalos \ + -lpreferences \ + -liconobject \ + -lmempools \ + -ldebug \ + -lmui \ + -lstack \ + -lnix \ + -lnixmain \ + -lamiga21 \ + -lamiga \ + -lstubs \ + +endif +endif +endif diff --git a/scalos/Plugins/Prefs/Palette/makefile b/scalos/Plugins/Prefs/Palette/makefile new file mode 100644 index 000000000..e19a8c88f --- /dev/null +++ b/scalos/Plugins/Prefs/Palette/makefile @@ -0,0 +1,144 @@ +# makefile für Scalos Palette.prefsplugin +# $Date$ +# $Revision$ +############################################################# + +SDPATH = // + +SUBDIRMAKE = $(MAKE) -s -C +FLEXCAT = FlexCat +CATCOMP = CatComp +AS = phxAss +LD = slink +CC = sc +ECHO = echo +LIBS = LIB:scm.lib LIB:sc.lib LIB:mempools.lib \ + LIB:debug.lib LIB:amiga.lib +LDFLAGS = quiet batch noicons +PRECOMP = Include:all.gst +OBJDIR = .sasobj +BINDIR = .bin_os3 +PREFSPATH = ../../../Prefs/Palette +DATATYPESMCC_DIR = ../../../common/DataTypesMCC +COMMON_DIR = ../../../common/Plugin + +.SUFFIXES: .s .asm .plugin .plugin.debug + +############################################################# + +CSRCS = $(COMMON_DIR)/plugin-classic.c \ + PalettePrefs.c \ + $(DATATYPESMCC_DIR)/DataTypesMCC.c \ + +############################################################# + +CFLAGS = optimize nostackcheck nover dbg=s DATA=far \ + idlen=64 \ + define SCALOSLOCALE=$(SCALOS_LOCALE) \ + idir=///include \ + idir=$(subst ../,/,$(DATATYPESMCC_DIR)) \ + idir=$(subst ../,/,$(PREFSPATH)) \ + idir=///common/Plugin +AFLAGS = quiet DS opt=NRQB NOEXE linedebug I=SC:Assembler_Headers +#AFLAGS = -t -iINCLUDE: + +############################################################# + +PLUGIN = Palette.prefsplugin +PLUGINDBG = $(PLUGIN).debug +CAT_FILE = Scalos/ScalosPalette.catalog +DESTTOOL = Scalos:Prefs/ +DESTCAT = Locale:Catalogs +SRCCAT = $(subst ../,/,$(PREFSPATH)) +SCALOS_LOCALE = $(OBJDIR)/ScalosPalette_locale.h +CATCOMPHEADER = $(SCALOS_LOCALE) +CATS = dansk \ + deutsch \ + español \ + français \ + italiano \ + svenska \ + ÃeÓtina + +ALLCATS = $(foreach cat,$(CATS),$(SRCCAT)/catalogs/$(cat)/$(CAT_FILE)) + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +XSRCS = $(notdir $(CSRCS)) +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(XSRCS:%.c=$(OBJDIR)/$(notdir %).o) + +############################################################# + +All: $(BINDIR)/$(PLUGIN) \ + $(BINDIR)/$(PLUGINDBG) \ + allcatalogs +# install +# clean + +############################################################# + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-classic.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/DataTypesMCC.o : $(DATATYPESMCC_DIR)/DataTypesMCC.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $*.c objectname $@ + +############################################################# + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-common.c \ + plugin_data.h $(COMMON_DIR)/plugin.h + +$(OBJDIR)/DataTypesMCC.o: $(DATATYPESMCC_DIR)/DataTypesMCC.c \ + $(DATATYPESMCC_DIR)/DataTypesMCC.h + +$(OBJDIR)/PalettePrefs.o : PalettePrefs.h PalettePrefsImage.h \ + plugin_data.h $(COMMON_DIR)/plugin.h \ + $(SCALOS_LOCALE) + +############################################################# + +$(CATCOMPHEADER) : $(PREFSPATH)/ScalosPalette.cd + @printf '\033[32mMake CatComp header: \033[31m\033[1m$@ \033[32mfrom \033[31m$<\033[0m\n' + $(FLEXCAT) $(subst ../,/,$<) $@=$(SDPATH)/CatComp_h.sd + +$(BINDIR)/$(PLUGIN) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) to $@ FROM $(OBJS) lib $(LIBS) $(LDFLAGS) STRIPDEBUG + +$(BINDIR)/$(PLUGINDBG) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) to $@ FROM $(OBJS) lib $(LIBS) $(LDFLAGS) ADDSYM + +############################################################# + +install: + @avail flush + @printf '\033[32mInstall: \033[31m\033[1m$(PLUGIN)\033[0m\n' + @copy $(BINDIR)/$(PLUGIN) "$(DESTTOOL)" + @printf '\033[32mInstall: \033[31m\033[1m$(CAT_FILE)\033[0m\n' + -@$(foreach cat,$(CATS),copy "$(SRCCAT)/catalogs/$(cat)/$(CAT_FILE)" "$(DESTCAT)/$(cat)/Scalos" clone;) + +############################################################# + +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + -@delete $(BINDIR)/$(PLUGIN) $(BINDIR)/$(PLUGINDBG) $(OBJS) $(subst ../,/,$(CATCOMPHEADER)) $(ALLCATS) + @printf '\033[0m' + +############################################################# + +# make all Scalos preferences .catalogs +allcatalogs: + -@$(foreach cat,$(CATS),$(SUBDIRMAKE) $(PREFSPATH)/catalogs/$(cat)/Scalos;) + +############################################################# + diff --git a/scalos/Plugins/Prefs/Palette/makefile-new b/scalos/Plugins/Prefs/Palette/makefile-new new file mode 100755 index 000000000..714e1e762 --- /dev/null +++ b/scalos/Plugins/Prefs/Palette/makefile-new @@ -0,0 +1,97 @@ +# $Date: 2011-08-09 11:15:58 +0200 (Di, 09. Aug 2011) $ +# $Revision: 828 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../../.. +endif + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + PARENTDIR=/ + SDPATH=// +else + PARENTDIR=../ + SDPATH=../../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(BEGIN_OBJS) \ + $(OBJDIR)/PalettePrefs.o \ + $(OBJDIR)/DataTypesMCC.o \ + $(END_OBJS) + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Targets +# + +NAME = Palette.prefsplugin +NAME_DB = $(NAME).debug + +############################################################################## + +PREFSDIR = ../../../Prefs/Palette + +############################################################################## +# +# Some lame deps + +$(OBJDIR)/%.o: $(DATATYPESMCC_DIR)/%.c + @$(run-cc) + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) + +############################################################# + +PalettePrefs.c : $(SCALOS_LOCALE) + +$(SCALOS_LOCALE) : $(PREFSDIR)/ScalosPalette.cd + @$(ECHO) "FlexCat $@" + $(FLEXCAT) $(subst ../,$(PARENTDIR),$<) $@=$(SDPATH)/CatComp_h.sd + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + $(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) Scalos:Prefs/ clone + @avail flush + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* \ + $(SCALOS_LOCALE) + +############################################################################## + diff --git a/scalos/Plugins/Prefs/Palette/plugin_data.h b/scalos/Plugins/Prefs/Palette/plugin_data.h new file mode 100644 index 000000000..4fbf013ab --- /dev/null +++ b/scalos/Plugins/Prefs/Palette/plugin_data.h @@ -0,0 +1,27 @@ +// plugin_data.h +// $Date$ +// $Revision$ + +#ifndef PLUGIN_DATA_H_INCLUDED +#define PLUGIN_DATA_H_INCLUDED + +#include +#include + +#define PLUGIN_TYPE PREFS + +#define LIB_VERSION 40 +#define LIB_REVISION 11 + +#define LIB_NAME "Palette.prefsplugin" +#define LIB_VERSTRING "$VER: " LIB_NAME " " \ + STR(LIB_VERSION) "." STR(LIB_REVISION) \ + " (19.04.2006)" \ + COMPILER_STRING " ©2003" CURRENTYEAR \ + " The Scalos Team" + +//---------------------------------------------------------------------------- +// code and includes to define the structs and functions used above + +#endif /* PLUGUN_DATA_H_INCLUDED */ + diff --git a/scalos/Plugins/Prefs/Pattern/DoLoadDT.c b/scalos/Plugins/Prefs/Pattern/DoLoadDT.c new file mode 100755 index 000000000..2abba829b --- /dev/null +++ b/scalos/Plugins/Prefs/Pattern/DoLoadDT.c @@ -0,0 +1,234 @@ +// DoLoadDT.c +// datatype loading, scaling, remapping and dithering routine. +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "LoadDT.h" +#include "debug.h" + +//-------------------------------------------------------------------------------- + +static BOOL IsPictureDT43(Object *o); + +//-------------------------------------------------------------------------------- + +struct ScalosBitMapAndColor *DoLoadDT(STRPTR source, struct RastPort *rast, + ULONG ScaledWidth, ULONG ScaledHeight, + struct Screen *screen) +{ + Object *obj; + struct BitMap *bm = NULL; + struct BitMapHeader *bmhd = NULL; + struct ScalosBitMapAndColor *sac = NULL; + ULONG Success = FALSE; + struct ARGBHeader argbSrc = { 0, 0, NULL }; + struct ARGBHeader argbDest = { 0, 0, NULL }; + +// printf('\n Start AVAILMEM-\d\n',AvailMem(MEMF_ANY)) + + do { + PLANEPTR MaskPlane = NULL; + LONG Result; + ULONG ScreenDepth; + + ScreenDepth = GetBitMapAttr(screen->RastPort.BitMap, BMA_DEPTH); + + // NewDTObjectA( + obj = NewDTObject(source, + DTA_SourceType, DTST_FILE, + PDTA_DestMode, PMODE_V43, + DTA_GroupID, GID_PICTURE, + PDTA_Remap, FALSE, + OBP_Precision, PRECISION_EXACT, + TAG_END); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: obj=%08lx\n", __LINE__, obj)); + if (NULL == obj) + { + ShowError("NewDTObject(%s) failed\n", source); + break; + } + + if (IsPictureDT43(obj)) + { + d1(KPrintF(__FILE__ "/%s/%ld: IsPictureDT43\n", __FUNC__, __LINE__)); + SetDTAttrs(obj, NULL, NULL, + PDTA_Screen, (ULONG) screen, + PDTA_UseFriendBitMap, ScreenDepth <= 8, + TAG_END); + } + else + { + SetDTAttrs(obj, NULL, NULL, + PDTA_UseFriendBitMap, FALSE, + TAG_END); + } + + if (!DoDTMethod(obj, + NULL, + NULL, + DTM_PROCLAYOUT, + NULL, + TRUE)) + { + ShowError("%s: DTM_PROCLAYOUT failed\n", source); + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: DTM_PROCLAYOUT failed\n", __LINE__)); + break; + } + + sac = ScalosGfxCreateEmptySAC(); + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: sac=%08lx\n", __LINE__, sac)); + if (NULL == sac) + { + ShowError("%s: ScalosGfxCreateEmptySAC failed\n", source); + break; + } + + sac->sac_Flags |= SACFLAGF_NO_FREE_COLORTABLE; + + Result = GetDTAttrs(obj, + PDTA_NumColors, (ULONG) &sac->sac_NumColors, + PDTA_CRegs, (ULONG) &sac->sac_ColorTable, + PDTA_BitMapHeader, (ULONG) &bmhd, + PDTA_DestBitMap, (ULONG) &bm, + TAG_END); + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: Result=%08lx\n", __LINE__, Result)); + if (Result < 4) + { + ShowError("%s: GetDTAttrs failed\n", source); + break; + } + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: sac_NumColors=%lu\n", __LINE__, sac->sac_NumColors)); + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: bm=%08lx\n", __LINE__, bm)); + if (NULL == bm) + { + ShowError("%s: GetDTAttrs() bm == NULL\n", source); + break; + } + + ScalosGfxCalculateScaleAspect(bmhd->bmh_Width, bmhd->bmh_Height, + &ScaledWidth, &ScaledHeight); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: bmh_Depth=%lu\n", __LINE__, bmhd->bmh_Depth)); + + (void) GetDTAttrs(obj, + PDTA_MaskPlane, (ULONG) &MaskPlane, + TAG_END); + + argbSrc.argb_Width = bmhd->bmh_Width; + argbSrc.argb_Height = bmhd->bmh_Height; + + // Create ARGB from BitMap + argbSrc.argb_ImageData = ScalosGfxCreateARGBFromBitMap(bm, + bmhd->bmh_Width, + bmhd->bmh_Height, + sac->sac_NumColors, + sac->sac_ColorTable, + MaskPlane); + d1(KPrintF(__FILE__ "/%s/%ld: argb_ImageData=%08lx\n", __FUNC__, __LINE__, argbSrc.argb_ImageData)); + if (NULL == argbSrc.argb_ImageData) + break; + + argbDest.argb_Width = ScaledWidth; + argbDest.argb_Height = ScaledHeight; + + // Scale image + argbDest.argb_ImageData = ScalosGfxScaleARGBArrayTags(&argbSrc, + &argbDest.argb_Width, + &argbDest.argb_Height, + SCALOSGFX_ScaleARGBArrayFlags, SCALEFLAGF_BILINEAR | SCALEFLAGF_AVERAGE | SCALEFLAGF_DOUBLESIZE, + TAG_END); + d1(KPrintF(__FILE__ "/%s/%ld: argbDest.argb_ImageData=%08lx\n", __FUNC__, __LINE__, argbDest.argb_ImageData)); + if (NULL == argbDest.argb_ImageData) + break; + + // Free preliminary SAC previously created + ScalosGfxFreeSAC(sac); + + // Create dithered image from scaled image + sac = ScalosGfxMedianCutTags(&argbDest, 8, + SCALOSGFX_MedianCutFlags, SCALOSGFXFLAGF_MedianCut_FloydSteinberg, + SCALOSGFX_MedianCutFriendBitMap, NULL, + TAG_END); + d1(KPrintF(__FILE__ "/%s/%ld: sac=%08lx\n", __FUNC__, __LINE__, sac)); + if (NULL == sac) + break; + + Success = TRUE; + } while (0); + + ScalosGfxFreeARGB(&argbSrc.argb_ImageData); + ScalosGfxFreeARGB(&argbDest.argb_ImageData); + + if (obj) + DisposeDTObject(obj); + if (!Success) + { + ScalosGfxFreeSAC(sac); + sac = NULL; + } + + return sac; +} + +// ---------------------------------------------------------- + +// Work-around for OS3.0/3.1 and Picasso96 picture.datatype V43.41 +// This datatype seems to understand PMODE_V43, but in combination with +// PDTA_UseFriendBitMap and PDTA_Screen, returns a very weird BitMap +// that I was unable to deal with: Depth=16, but no CyberGfx BitMap +// Looks like an extended standard BitMap with 16 plane pointers. + +static BOOL IsPictureDT43(Object *o) +{ + const ULONG *MethodArray = NULL; + BOOL IsV43 = FALSE; + + GetDTAttrs(o, + DTA_Methods, (ULONG) &MethodArray, + TAG_END); + + while (MethodArray && ~0 != *MethodArray) + { + if (PDTM_SCALE == *MethodArray) + { + IsV43 = TRUE; + break; + } + MethodArray++; + } + + return IsV43; +} + +//----------------------------------------------------------------------------- + + diff --git a/scalos/Plugins/Prefs/Pattern/LoadDT.h b/scalos/Plugins/Prefs/Pattern/LoadDT.h new file mode 100755 index 000000000..2600f1476 --- /dev/null +++ b/scalos/Plugins/Prefs/Pattern/LoadDT.h @@ -0,0 +1,21 @@ +// loaddt.h +// $Date$ +// $Revision$ + +//-------------------------------------------------------------------------------- + +extern struct Library *DataTypesBase; + +//-------------------------------------------------------------------------------- + +struct ScalosBitMapAndColor *DoLoadDT(STRPTR source, struct RastPort *rast, + ULONG ScaledWidth, ULONG ScaledHeight, + struct Screen *screen); +void ShowError(const char *str, ...); + +//-------------------------------------------------------------------------------- + +extern int KPrintF(const char *fmt, ...); + +//-------------------------------------------------------------------------------- + diff --git a/scalos/Plugins/Prefs/Pattern/NoDebug b/scalos/Plugins/Prefs/Pattern/NoDebug new file mode 100755 index 000000000..49ed68d29 --- /dev/null +++ b/scalos/Plugins/Prefs/Pattern/NoDebug @@ -0,0 +1,3 @@ +; NoDebug +; 23 Dec 2001 16:17:11 +splat -s -o "d2(" "d1(" #?.c diff --git a/scalos/Plugins/Prefs/Pattern/PatternPrefs.c b/scalos/Plugins/Prefs/Pattern/PatternPrefs.c new file mode 100644 index 000000000..b5ab41d78 --- /dev/null +++ b/scalos/Plugins/Prefs/Pattern/PatternPrefs.c @@ -0,0 +1,4409 @@ +// PatternPrefs.c +// $Date$ +// $Revision$ + +#ifdef __AROS__ +#define MUIMASTER_YES_INLINE_STDARG +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef __AROS__ +#define NO_INLINE_STDARG +#endif +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "PatternPrefs.h" +#include "Backfill.h" +#include "BitMapMCC.h" +#include "DataTypesMCC.h" +#include "LoadDT.h" +#include "debug.h" +#include "plugin.h" + +#define ScalosPattern_NUMBERS +#define ScalosPattern_ARRAY +#define ScalosPattern_CODE +#include STR(SCALOSLOCALE) + +//---------------------------------------------------------------------------- + +#ifdef __AROS__ +#define myNListObject BOOPSIOBJMACRO_START(myNListClass->mcc_Class) +#define PrecSliderObject BOOPSIOBJMACRO_START(PrecSliderClass->mcc_Class) +#define PatternSliderObject BOOPSIOBJMACRO_START(PatternSliderClass->mcc_Class) +#else +#define myNListObject NewObject(myNListClass->mcc_Class, 0 +#define PrecSliderObject NewObject(PrecSliderClass->mcc_Class, 0 +#define PatternSliderObject NewObject(PatternSliderClass->mcc_Class, 0 +#endif + +//---------------------------------------------------------------------------- + +#define USE_THUMBNAILS 0 + +#define THUMBNAIL_WIDTH 50 +#define THUMBNAIL_HEIGHT 50 + +#define LISTFORMAT_THUMBNAILS "P=\33r BAR, BAR, BAR, BAR" +#define LISTFORMAT_STANDARD "P=\33r BAR, BAR, BAR" + +//---------------------------------------------------------------------------- + +#define IMG(prefix1,PREFIX2) \ + BodychunkObject,\ + MUIA_FixWidth , PREFIX2##_WIDTH ,\ + MUIA_FixHeight , PREFIX2##_HEIGHT,\ + MUIA_Bitmap_Width , PREFIX2##_WIDTH ,\ + MUIA_Bitmap_Height , PREFIX2##_HEIGHT,\ + MUIA_Bodychunk_Depth , PREFIX2##_DEPTH ,\ + MUIA_Bodychunk_Body , (UBYTE *) prefix1##_body,\ + MUIA_Bodychunk_Compression, PREFIX2##_COMPRESSION,\ + MUIA_Bodychunk_Masking , PREFIX2##_MASKING,\ + MUIA_Bitmap_SourceColors , (ULONG *) prefix1##_colors,\ + MUIA_Bitmap_Transparent , 0,\ + End + +//---------------------------------------------------------------------------- + +// from debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +//---------------------------------------------------------------------------- + +// local data structures + +#define KeyButtonHelp(name,key,HelpText)\ + TextObject,\ + ButtonFrame,\ + MUIA_CycleChain, TRUE, \ + MUIA_Font, MUIV_Font_Button,\ + MUIA_Text_Contents, name,\ + MUIA_Text_PreParse, "\33c",\ + MUIA_Text_HiChar , key,\ + MUIA_ControlChar , key,\ + MUIA_InputMode , MUIV_InputMode_RelVerify,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShortHelp, HelpText,\ + End + +#define CheckMarkHelp(selected, HelpTextID)\ + ImageObject,\ + ImageButtonFrame,\ + MUIA_CycleChain , TRUE, \ + MUIA_InputMode , MUIV_InputMode_Toggle,\ + MUIA_Image_Spec , MUII_CheckMark,\ + MUIA_Image_FreeVert , TRUE,\ + MUIA_Selected , selected,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShowSelState , FALSE,\ + MUIA_ShortHelp , GetLocString(HelpTextID),\ + End + + +#define Application_Return_EDIT 0 +#define Application_Return_USE 1001 +#define Application_Return_SAVE 1002 + +#define MAX_FILENAME 512 + + +struct RGBlong + { + ULONG Red; + ULONG Green; + ULONG Blue; + }; + +struct TempRastPort + { + struct RastPort trp_rp; + ULONG trp_Width; + }; +struct PatternListEntry + { + struct ScaExtPatternPrefs ple_PatternPrefs; + Object *ple_MUI_ImageObject; + ULONG ple_ThumbnailImageNr; + struct ScalosBitMapAndColor *ple_SAC; + UBYTE *ple_BitMapArray; + }; + +//---------------------------------------------------------------------------- + +// aus mempools.lib +#if !defined(__amigaos4__) && !defined(__AROS__) +extern int _STI_240_InitMemFunctions(void); +extern void _STD_240_TerminateMemFunctions(void); +#endif + +//---------------------------------------------------------------------------- + +// local functions + +DISPATCHER_PROTO(PatternPrefs); +static Object *CreatePrefsGroup(struct PatternPrefsInst *inst); +static void CreateSubWindows(struct PatternPrefsInst *inst); +static ULONG DoOmSet(Class *cl, Object *o, struct opSet *ops); +static Object *CreatePrefsImage(void); +static void InitHooks(struct PatternPrefsInst *inst); + +static BOOL OpenLibraries(void); +static void CloseLibraries(void); +static STRPTR GetLocString(ULONG MsgId); +static void TranslateStringArray(STRPTR *stringArray); +static void TranslateNewMenu(struct NewMenu *nm); +static SAVEDS(APTR) INTERRUPT ListConstructHookFunc(struct Hook *hook, Object *obj, struct NList_ConstructMessage *msg); +static SAVEDS(void) INTERRUPT ListDestructHookFunc(struct Hook *hook, Object *obj, struct NList_DestructMessage *msg); +static SAVEDS(ULONG) INTERRUPT ListDisplayHookFunc(struct Hook *hook, Object *obj, struct NList_DisplayMessage *ndm); +static SAVEDS(LONG) INTERRUPT ListCompareHookFunc(struct Hook *hook, Object *obj, struct NList_CompareMessage *msg); +static SAVEDS(APTR) INTERRUPT SettingsChangedHookFunc(struct Hook *hook, Object *o, Msg msg); +DISPATCHER_PROTO(PatternSlider); +DISPATCHER_PROTO(PrecSlider); +static LONG ReadPrefsFile(struct PatternPrefsInst *inst, CONST_STRPTR Filename, BOOL Quiet); +static LONG ReadPrefsBitMap(struct PatternPrefsInst *inst, struct IFFHandle *iff, + struct PatternListEntry *scp, struct TempRastPort *trp); +static LONG WritePrefsFile(struct PatternPrefsInst *inst, CONST_STRPTR Filename); +static LONG WritePrefsColorTable(struct IFFHandle *iff, const struct PatternListEntry *scp); +static LONG WritePrefsBitMap(struct IFFHandle *iff, + const struct PatternListEntry *scp, struct TempRastPort *trp); +static LONG SaveIcon(struct PatternPrefsInst *inst, CONST_STRPTR IconName); +static SAVEDS(void) INTERRUPT ListSelectEntryHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT ListChangeEntryHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT ListChangeEntry2HookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT ListChangeEntry3HookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT AddNewEntryHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT RemEntryHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT LastSavedHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT RestoreHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT ResetToDefaultsHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT AboutHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT OpenHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT SaveAsHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT PreviewSelectHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT ContextMenuTriggerHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT ShowPreviewHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT AutoPreviewHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT ThumbnailsHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT AppMsgInMainListHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT DesktopPatternChangedHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT ScreenPatternChangedHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT IconWindowPatternChangedHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT TextWindowPatternChangedHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT AslIntuiMsgHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT ReloadThumbnailsHookFunc(struct Hook *hook, Object *o, Msg msg); + +static void PreviewSelect(struct PatternPrefsInst *inst); +static void SetPrecision(struct PatternPrefsInst *inst, BYTE Precision); +static BYTE GetPrecision(struct PatternPrefsInst *inst); +static void SetChangedFlag(struct PatternPrefsInst *inst, BOOL changed); +static void ParseToolTypes(struct PatternPrefsInst *inst, struct MUIP_ScalosPrefs_ParseToolTypes *ptt); +static Object *CreateEmptyThumbnailImage(struct PatternPrefsInst *inst); +static void RemoveThumbnailImages(struct PatternPrefsInst *inst); +static void CreateThumbnailImages(struct PatternPrefsInst *inst); +static void CreateThumbnailImage(struct PatternPrefsInst *inst, struct PatternListEntry *scp); +static void UpdateUseThumbnails(struct PatternPrefsInst *inst); +static void DisableBackgroundColorGadgets(struct PatternPrefsInst *inst, UWORD RenderType, UWORD BgType); + +DISPATCHER_PROTO(myNList); + +#if !defined(__SASC) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) +static size_t stccpy(char *dest, const char *src, size_t MaxLen); +#endif /* !defined(__SASC) && !defined(__MORPHOS__) && !defined(__amigaos4__) */ + +//---------------------------------------------------------------------------- + +// local data items + +struct Library *MUIMasterBase; +T_LOCALEBASE LocaleBase; +struct GfxBase *GfxBase; +struct Library *IconBase; +struct Library *IFFParseBase; +T_UTILITYBASE UtilityBase; +struct IntuitionBase *IntuitionBase; +struct Library *DataTypesBase; +struct Library *GuiGFXBase; +struct ScalosGfxBase *ScalosGfxBase; +struct Library *CyberGfxBase; +T_TIMERBASE TimerBase; + +#if defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) +extern T_UTILITYBASE __UtilityBase; +#endif /* __GNUC__ && !__MORPHOS && !__amigaos4__ */ + +#ifdef __amigaos4__ +struct Library *DOSBase; +struct DOSIFace *IDOS; +struct MUIMasterIFace *IMUIMaster; +struct LocaleIFace *ILocale; +struct GraphicsIFace *IGraphics; +struct IconIFace *IIcon; +struct IFFParseIFace *IIFFParse; +struct UtilityIFace *IUtility; +struct IntuitionIFace *IIntuition; +struct DataTypesIFace *IDataTypes; +struct GuiGFXIFace *IGuiGFX; +struct ScalosGfxIFace *IScalosGfx; +struct CyberGfxIFace *ICyberGfx; +struct Library *NewlibBase; +struct Interface *INewlib; +struct TimerIFace *ITimer; +#endif + +#ifdef __AROS__ +struct DosLibrary *DOSBase; +#endif + +static ULONG Signature = 0x4711; + +static T_TIMEREQUEST *TimerIORequest; + +struct MUI_CustomClass *PrecSliderClass; +struct MUI_CustomClass *PatternSliderClass; +struct MUI_CustomClass *myNListClass; +struct MUI_CustomClass *PatternPrefsClass; +struct MUI_CustomClass *BitMapPicClass; +struct MUI_CustomClass *DataTypesImageClass; + +static struct Catalog *PatternPrefsCatalog; +static struct Locale *PatternPrefsLocale; + +static ULONG MajorVersion, MinorVersion; + +static const struct MUIP_ScalosPrefs_MCCList RequiredMccList[] = + { + { MUIC_Lamp, 11, 1 }, + { MUIC_NListview, 18, 0 }, + { NULL, 0, 0 } + }; +static const struct Hook PatternPrefsHooks[] = +{ + { { NULL, NULL }, HOOKFUNC_DEF(ListDisplayHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ListConstructHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ListDestructHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ListCompareHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ListSelectEntryHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ListChangeEntryHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ListChangeEntry2HookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ListChangeEntry3HookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(AddNewEntryHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(RemEntryHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(LastSavedHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(RestoreHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ResetToDefaultsHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(AboutHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(OpenHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(SaveAsHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(PreviewSelectHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ContextMenuTriggerHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ShowPreviewHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(AutoPreviewHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(AppMsgInMainListHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(SettingsChangedHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ThumbnailsHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(DesktopPatternChangedHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ScreenPatternChangedHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(IconWindowPatternChangedHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(TextWindowPatternChangedHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(AslIntuiMsgHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(ReloadThumbnailsHookFunc), NULL }, +}; + + +static struct NewMenu ContextMenus[] = + { + { NM_TITLE, (STRPTR) MSGID_TITLENAME, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_OPEN, (STRPTR) MSGID_MENU_PROJECT_OPEN_SHORT, 0, 0, (APTR) HOOKNDX_Open }, + { NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_SAVEAS, (STRPTR) MSGID_MENU_PROJECT_SAVEAS_SHORT, 0, 0, (APTR) HOOKNDX_SaveAs }, + { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_ENABLE_THUMBNAILS, NULL, CHECKIT|MENUTOGGLE, 0, (APTR) HOOKNDX_Thumbnails }, + { NM_ITEM, (STRPTR) MSGID_MENU_ENABLE_PREVIEW, NULL, CHECKIT|MENUTOGGLE, 0, (APTR) HOOKNDX_ShowPreview }, + { NM_ITEM, (STRPTR) MSGID_MENU_AUTO_PREVIEW, NULL, CHECKIT|MENUTOGGLE, 0, (APTR) HOOKNDX_AutoPreview }, + { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_RELOAD_THUMBNAILS, NULL, 0, 0, (APTR) HOOKNDX_ReloadThumbnails }, + { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL }, + { NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_ABOUT, NULL, 0, 0, (APTR) HOOKNDX_About }, + + { NM_END, NULL, NULL, 0, 0, 0,}, + }; + +static STRPTR dithermodecont[] = + { + (STRPTR) MSGID_DITHERMODE1NAME, // DITHERMODE_NONE + (STRPTR) MSGID_DITHERMODE2NAME, // DITHERMODE_FS + (STRPTR) MSGID_DITHERMODE3NAME, // DITHERMODE_RANDOM + NULL + }; + +// scp_RenderType values +static STRPTR patternmode[] = + { + (STRPTR) MSGID_RENDERTYPE_TILED, + (STRPTR) MSGID_RENDERTYPE_FITSIZE, + (STRPTR) MSGID_CENTEREDNAME, + (STRPTR) MSGID_SCALEDMINNAME, + (STRPTR) MSGID_SCALEDMAXNAME, + NULL + }; + +// title strings for the register pages +static STRPTR RegisterTitleStrings[] = + { + (STRPTR) MSGID_REGISTER_PATTERNLIST, + (STRPTR) MSGID_REGISTER_BACKGROUNDCOLORS, + (STRPTR) MSGID_REGISTER_DEFAULTS, + NULL + }; + +static STRPTR CycleBackgroundModeStrings[] = + { + (STRPTR) MSGID_BGTYPE_NONE, + (STRPTR) MSGID_BGTYPE_SINGLECOLOR, + (STRPTR) MSGID_BGTYPE_HOR_GRADIENT, + (STRPTR) MSGID_BGTYPE_VERT_GRADIENT, + NULL + }; + +//--------------------------------------------------------------- + +VOID closePlugin(struct PluginBase *PluginBase) +{ + d1(kprintf(__FUNC__ "/%ld:\n", __FILE__, __FUNC__, __LINE__)); + + if (DataTypesImageClass) + { + CleanupDtpicClass(DataTypesImageClass); + DataTypesImageClass = NULL; + } + if (BitMapPicClass) + { + CleanupBitMappicClass(BitMapPicClass); + BitMapPicClass = NULL; + } + if (myNListClass) + { + MUI_DeleteCustomClass(myNListClass); + myNListClass = NULL; + } + if (PrecSliderClass) + { + MUI_DeleteCustomClass(PrecSliderClass); + PrecSliderClass = NULL; + } + if (PatternSliderClass) + { + MUI_DeleteCustomClass(PatternSliderClass); + PatternSliderClass = NULL; + } + CleanupBackfillClass(); + + if (PatternPrefsCatalog) + { + CloseCatalog(PatternPrefsCatalog); + PatternPrefsCatalog = NULL; + } + if (PatternPrefsLocale) + { + CloseLocale(PatternPrefsLocale); + PatternPrefsLocale = NULL; + } + + if (PatternPrefsClass) + { + MUI_DeleteCustomClass(PatternPrefsClass); + PatternPrefsClass = NULL; + } + + CloseLibraries(); + +#if !defined(__amigaos4__) && !defined(__AROS__) + _STD_240_TerminateMemFunctions(); +#endif +} + + +LIBFUNC_P2(ULONG, LIBSCAGetPrefsInfo, + D0, ULONG, which, + A6, struct PluginBase *, PluginBase) +{ + ULONG result; + + (void) PluginBase; + + d1(kprintf("%s/%s/%ld: which=%ld\n", __FILE__, __FUNC__, __LINE__, which)); + + switch(which) + { + case SCAPREFSINFO_GetClass: + result = (ULONG) PatternPrefsClass; + break; + + case SCAPREFSINFO_GetTitle: + result = (ULONG) GetLocString(MSGID_PLUGIN_LIST_TITLE); + break; + + case SCAPREFSINFO_GetTitleImage: + result = (ULONG) CreatePrefsImage(); + break; + + default: + result = 0; + break; + } + + d1(kprintf("%s/%s/%ld: ResultString=<%s>\n", __FILE__, __FUNC__, __LINE__, ttshd->ttshd_Buffer)); + + return result; +} +LIBFUNC_END + +//---------------------------------------------------------------------------- + +DISPATCHER(PatternPrefs) +{ + struct PatternPrefsInst *inst; + ULONG result = 0; + + switch(msg->MethodID) + { + case OM_NEW: + obj = (Object *) DoSuperMethodA(cl, obj, msg); + d1(KPrintF("%s/%s/%ld: OM_NEW obj=%08lx\n", __FILE__, __FUNC__, __LINE__, obj)); + if (obj) + { + Object *prefsobject; + struct opSet *ops = (struct opSet *) msg; + + inst = (struct PatternPrefsInst *) INST_DATA(cl, obj); + + memset(inst, 0, sizeof(struct PatternPrefsInst)); + + inst->ppb_Changed = FALSE; + inst->ppb_fDontChange = FALSE; + inst->ppb_patternPrecision = PRECISION_IMAGE; + inst->ppb_fPreview = TRUE; + inst->ppb_fAutoPreview = FALSE; + inst->ppb_PreviewWeight = 20; + inst->ppb_WBScreen = LockPubScreen("Workbench"); + inst->ppb_ThumbnailWidth = THUMBNAIL_WIDTH; + inst->ppb_ThumbnailHeight = THUMBNAIL_HEIGHT; + inst->ppb_ThumbnailImageNumber = 0; + inst->ppb_UseSplashWindow = TRUE; + +#if USE_THUMBNAILS + inst->ppb_UseThumbNails = TRUE; +#else /* USE_THUMBNAILS */ + inst->ppb_UseThumbNails = FALSE; +#endif /* USE_THUMBNAILS */ + + InitHooks(inst); + + inst->ppb_fCreateIcons = GetTagData(MUIA_ScalosPrefs_CreateIcons, TRUE, ops->ops_AttrList); + inst->ppb_ProgramName = (CONST_STRPTR) GetTagData(MUIA_ScalosPrefs_ProgramName, (ULONG) "", ops->ops_AttrList); + inst->ppb_Objects[OBJNDX_WIN_Main] = (APTR) GetTagData(MUIA_ScalosPrefs_MainWindow, (ULONG) NULL, ops->ops_AttrList); + inst->ppb_Objects[OBJNDX_APP_Main] = (APTR) GetTagData(MUIA_ScalosPrefs_Application, (ULONG) NULL, ops->ops_AttrList); + inst->ppb_fPreview = GetTagData(MUIA_ScalosPrefs_PatternPrefs_Preview, TRUE, ops->ops_AttrList); + inst->ppb_fAutoPreview = GetTagData(MUIA_ScalosPrefs_PatternPrefs_AutoPreview, FALSE, ops->ops_AttrList); + inst->ppb_PreviewWeight = GetTagData(MUIA_ScalosPrefs_PatternPrefs_PreviewWeight, 20, ops->ops_AttrList); + inst->ppb_UseThumbNails = GetTagData(MUIA_ScalosPrefs_PatternPrefs_Thumbnails, inst->ppb_UseThumbNails, ops->ops_AttrList); + + prefsobject = CreatePrefsGroup(inst); + d1(kprintf("%s/%s/%ld: prefsobject=%08lx\n", __FILE__, __FUNC__, __LINE__, prefsobject)); + if (prefsobject) + { + DoMethod(obj, OM_ADDMEMBER, prefsobject); + + result = (ULONG) obj; + } + else + { + CoerceMethod(cl, obj, OM_DISPOSE); + } + } + break; + + case OM_DISPOSE: + d1(KPrintF("%s/%s/%ld: OM_DISPOSE obj=%08lx\n", __FILE__, __FUNC__, __LINE__, obj)); + inst = (struct PatternPrefsInst *) INST_DATA(cl, obj); + if (inst->ppb_WBScreen) + { + UnlockPubScreen(NULL, inst->ppb_WBScreen); + inst->ppb_WBScreen = NULL; + } + if (inst->ppb_LoadReq) + { + MUI_FreeAslRequest(inst->ppb_LoadReq); + inst->ppb_LoadReq = NULL; + } + if (inst->ppb_SaveReq) + { + MUI_FreeAslRequest(inst->ppb_SaveReq); + inst->ppb_SaveReq = NULL; + } + if (inst->ppb_Objects[OBJNDX_EmptyThumbnailBitmap]) + { + MUI_DisposeObject(inst->ppb_Objects[OBJNDX_EmptyThumbnailBitmap]); + inst->ppb_Objects[OBJNDX_EmptyThumbnailBitmap] = NULL; + } + if (inst->ppb_Objects[OBJNDX_ContextMenu]) + { + MUI_DisposeObject(inst->ppb_Objects[OBJNDX_ContextMenu]); + inst->ppb_Objects[OBJNDX_ContextMenu] = NULL; + } + return DoSuperMethodA(cl, obj, msg); + break; + + case OM_SET: + d1(KPrintF("%s/%s/%ld: OM_SET obj=%08lx\n", __FILE__, __FUNC__, __LINE__, obj)); + result = DoOmSet(cl, obj, (struct opSet *) msg); + break; + + case OM_GET: + d1(KPrintF("%s/%s/%ld: OM_GET obj=%08lx\n", __FILE__, __FUNC__, __LINE__, obj)); + { + struct opGet *opg = (struct opGet *) msg; + + inst = (struct PatternPrefsInst *) INST_DATA(cl, obj); + switch (opg->opg_AttrID) + { + case MUIA_ScalosPrefs_CreateIcons: + *opg->opg_Storage = inst->ppb_fCreateIcons; + result = 0; + break; + default: + result = DoSuperMethodA(cl, obj, msg); + } + } + break; + + case MUIM_ScalosPrefs_ParseToolTypes: + d1(KPrintF("%s/%s/%ld: MUIM_ScalosPrefs_ParseToolTypes obj=%08lx\n", __FILE__, __FUNC__, __LINE__, obj)); + inst = (struct PatternPrefsInst *) INST_DATA(cl, obj); + d1(kprintf("%s/%s/%ld: before ParseToolTypes\n", __FILE__, __FUNC__, __LINE__)); + ParseToolTypes(inst, (struct MUIP_ScalosPrefs_ParseToolTypes *) msg); + d1(kprintf("%s/%s/%ld: after ParseToolTypes\n", __FILE__, __FUNC__, __LINE__)); + break; + + case MUIM_ScalosPrefs_LoadConfig: + d1(KPrintF("%s/%s/%ld: MUIM_ScalosPrefs_LoadConfig obj=%08lx\n", __FILE__, __FUNC__, __LINE__, obj)); + inst = (struct PatternPrefsInst *) INST_DATA(cl, obj); + ReadPrefsFile(inst, "ENV:Scalos/Pattern.prefs", FALSE); + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + SetChangedFlag(inst, FALSE); + break; + + case MUIM_ScalosPrefs_UseConfig: + d1(KPrintF("%s/%s/%ld: MUIM_ScalosPrefs_UseConfig obj=%08lx\n", __FILE__, __FUNC__, __LINE__, obj)); + inst = (struct PatternPrefsInst *) INST_DATA(cl, obj); + WritePrefsFile(inst, "ENV:Scalos/Pattern.prefs"); + break; + + case MUIM_ScalosPrefs_UseConfigIfChanged: + d1(KPrintF("%s/%s/%ld: MUIM_ScalosPrefs_UseConfigIfChanged obj=%08lx\n", __FILE__, __FUNC__, __LINE__, obj)); + inst = (struct PatternPrefsInst *) INST_DATA(cl, obj); + d1(kprintf("%s/%s/%ld: MUIM_ScalosPrefs_UseConfigIfChanged changed=%ld\n", __FILE__, __FUNC__, __LINE__, inst->ppb_Changed)); + if (inst->ppb_Changed) + { + WritePrefsFile(inst, "ENV:Scalos/Pattern.prefs"); + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + SetChangedFlag(inst, FALSE); + } + break; + + case MUIM_ScalosPrefs_SaveConfig: + d1(KPrintF("%s/%s/%ld: MUIM_ScalosPrefs_SaveConfig obj=%08lx\n", __FILE__, __FUNC__, __LINE__, obj)); + inst = (struct PatternPrefsInst *) INST_DATA(cl, obj); + WritePrefsFile(inst, "ENVARC:Scalos/Pattern.prefs"); + WritePrefsFile(inst, "ENV:Scalos/Pattern.prefs"); + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + SetChangedFlag(inst, FALSE); + break; + + case MUIM_ScalosPrefs_SaveConfigIfChanged: + d1(KPrintF("%s/%s/%ld: MUIM_ScalosPrefs_SaveConfigIfChanged obj=%08lx\n", __FILE__, __FUNC__, __LINE__, obj)); + inst = (struct PatternPrefsInst *) INST_DATA(cl, obj); + d1(kprintf("%s/%s/%ld: MUIM_ScalosPrefs_UseConfigIfChanged changed=%ld\n", __FILE__, __FUNC__, __LINE__, inst->ppb_Changed)); + if (inst->ppb_Changed) + { + WritePrefsFile(inst, "ENVARC:Scalos/Pattern.prefs"); + WritePrefsFile(inst, "ENV:Scalos/Pattern.prefs"); + + d1(kprintf("%s/%s/%ld: \n")); + SetChangedFlag(inst, FALSE); + } + break; + + case MUIM_ScalosPrefs_RestoreConfig: + d1(KPrintF("%s/%s/%ld: MUIM_ScalosPrefs_RestoreConfig obj=%08lx\n", __FILE__, __FUNC__, __LINE__, obj)); + inst = (struct PatternPrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_Restore], 0); + break; + + case MUIM_ScalosPrefs_ResetToDefaults: + d1(KPrintF("%s/%s/%ld: MUIM_ScalosPrefs_ResetToDefaults obj=%08lx\n", __FILE__, __FUNC__, __LINE__, obj)); + inst = (struct PatternPrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_ResetToDefaults], 0); + break; + + case MUIM_ScalosPrefs_LastSavedConfig: + d1(KPrintF("%s/%s/%ld: MUIM_ScalosPrefs_LastSavedConfig obj=%08lx\n", __FILE__, __FUNC__, __LINE__, obj)); + inst = (struct PatternPrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_LastSaved], 0); + break; + + case MUIM_ScalosPrefs_OpenConfig: + d1(KPrintF("%s/%s/%ld: MUIM_ScalosPrefs_OpenConfig obj=%08lx\n", __FILE__, __FUNC__, __LINE__, obj)); + inst = (struct PatternPrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_Open], 0); + break; + + case MUIM_ScalosPrefs_SaveConfigAs: + d1(KPrintF("%s/%s/%ld: MUIM_ScalosPrefs_SaveConfigAs obj=%08lx\n", __FILE__, __FUNC__, __LINE__, obj)); + inst = (struct PatternPrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_SaveAs], 0); + break; + + case MUIM_ScalosPrefs_About: + d1(KPrintF("%s/%s/%ld: MUIM_ScalosPrefs_About obj=%08lx\n", __FILE__, __FUNC__, __LINE__, obj)); + inst = (struct PatternPrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_About], 0); + break; + + case MUIM_ScalosPrefs_LoadNamedConfig: + d1(KPrintF("%s/%s/%ld: MUIM_ScalosPrefs_LoadNamedConfig obj=%08lx\n", __FILE__, __FUNC__, __LINE__, obj)); + { + struct MUIP_ScalosPrefs_LoadNamedConfig *lnc = (struct MUIP_ScalosPrefs_LoadNamedConfig *) msg; + + inst = (struct PatternPrefsInst *) INST_DATA(cl, obj); + ReadPrefsFile(inst, lnc->ConfigFileName, FALSE); + } + break; + + case MUIM_ScalosPrefs_CreateSubWindows: + d1(KPrintF("%s/%s/%ld: MUIM_ScalosPrefs_CreateSubWindows obj=%08lx\n", __FILE__, __FUNC__, __LINE__, obj)); + inst = (struct PatternPrefsInst *) INST_DATA(cl, obj); + CreateSubWindows(inst); + result = (ULONG) inst->ppb_SubWindows; + break; + + case MUIM_ScalosPrefs_GetListOfMCCs: + d1(KPrintF("%s/%s/%ld: MUIM_ScalosPrefs_GetListOfMCCs obj=%08lx\n", __FILE__, __FUNC__, __LINE__, obj)); + result = (ULONG) RequiredMccList; + break; + + default: + d1(KPrintF("%s/%s/%ld: obj=%08lx MethodID=%08lx\n", __FILE__, __FUNC__, __LINE__, obj, msg->MethodID)); + result = DoSuperMethodA(cl, obj, msg); + break; + } + + return result; +} +DISPATCHER_END + +//---------------------------------------------------------------------------- + +static Object *CreatePrefsGroup(struct PatternPrefsInst *inst) +{ + CONST_STRPTR MainListFormat; + + d1(KPrintF(__FUNC__ "/%ld: inst=%08lx\n", __FILE__, __FUNC__, __LINE__, inst)); + + inst->ppb_Objects[OBJNDX_ContextMenu] = MUI_MakeObject(MUIO_MenustripNM, ContextMenus, 0); + + if (NULL == inst->ppb_Objects[OBJNDX_ContextMenu]) + return NULL; + + inst->ppb_Objects[OBJNDX_EmptyThumbnailBitmap] = CreateEmptyThumbnailImage(inst); + + if (inst->ppb_UseThumbNails) + MainListFormat = LISTFORMAT_THUMBNAILS; + else + MainListFormat = LISTFORMAT_STANDARD; + + inst->ppb_Objects[OBJNDX_Menu_ShowPreview] = (Object *) DoMethod(inst->ppb_Objects[OBJNDX_ContextMenu], + MUIM_FindUData, HOOKNDX_ShowPreview); + inst->ppb_Objects[OBJNDX_Menu_AutoPreview] = (Object *) DoMethod(inst->ppb_Objects[OBJNDX_ContextMenu], + MUIM_FindUData, HOOKNDX_AutoPreview); + inst->ppb_Objects[OBJNDX_Menu_Thumbnails] = (Object *) DoMethod(inst->ppb_Objects[OBJNDX_ContextMenu], + MUIM_FindUData, HOOKNDX_Thumbnails); + inst->ppb_Objects[OBJNDX_Menu_ReloadThumbnails] = (Object *) DoMethod(inst->ppb_Objects[OBJNDX_ContextMenu], + MUIM_FindUData, HOOKNDX_ReloadThumbnails); + + inst->ppb_Objects[OBJNDX_Group_Main] = VGroup, + MUIA_Background, MUII_PageBack, + + Child, RegisterObject, + MUIA_Register_Titles, RegisterTitleStrings, + +// Register page "Pattern List" + Child, VGroup, + GroupFrame, + Child, inst->ppb_Objects[OBJNDX_Group_MainList] = HGroup, + Child, inst->ppb_Objects[OBJNDX_MainListView] = NListviewObject, + MUIA_Listview_DragType, MUIV_Listview_DragType_Immediate, + MUIA_Listview_Input, TRUE, + MUIA_CycleChain, TRUE, + MUIA_Listview_List, inst->ppb_Objects[OBJNDX_MainList] = myNListObject, + InputListFrame, + MUIA_Background, MUII_ListBack, + MUIA_NList_Format, MainListFormat, + MUIA_NList_PrivateData, inst, + MUIA_NList_TitleSeparator, TRUE, + MUIA_NList_Title, TRUE, + MUIA_NList_DisplayHook2, &inst->ppb_Hooks[HOOKNDX_ListDisplay], + MUIA_NList_ConstructHook2, &inst->ppb_Hooks[HOOKNDX_ListConstruct], + MUIA_NList_DestructHook2, &inst->ppb_Hooks[HOOKNDX_ListDestruct], + MUIA_NList_CompareHook2, &inst->ppb_Hooks[HOOKNDX_ListCompare], + MUIA_NList_PoolPuddleSize, sizeof(struct PatternListEntry) * 128, + MUIA_NList_PoolThreshSize, sizeof(struct PatternListEntry), + MUIA_NList_DragSortable, TRUE, + MUIA_NList_ShowDropMarks, TRUE, + MUIA_NList_AutoVisible, TRUE, + MUIA_NList_SortType, 0, + MUIA_NList_TitleMark, MUIV_NList_TitleMark_Down | 0, + MUIA_NList_EntryValueDependent, TRUE, + MUIA_NList_DefaultObjectOnClick, TRUE, + MUIA_ContextMenu, inst->ppb_Objects[OBJNDX_ContextMenu], + End, //NListObject + MUIA_NListview_Horiz_ScrollBar, MUIV_NListview_HSB_FullAuto, + End, //NListviewObject + + Child, inst->ppb_Objects[OBJNDX_Balance] = BalanceObject, + MUIA_ShowMe, inst->ppb_fPreview && !inst->ppb_UseThumbNails, + End, //BalanceObject + + Child, inst->ppb_Objects[OBJNDX_Group_Preview] = VGroupV, + Child, HVSpace, + Child, inst->ppb_Objects[OBJNDX_PreviewImage] = DataTypesImageObject, + MUIA_ScaDtpic_Name, (ULONG) "", + MUIA_ScaDtpic_Tiled, FALSE, + MUIA_UserData, inst, + ButtonFrame, + MUIA_Background, MUII_ButtonBack, + MUIA_InputMode, MUIV_InputMode_RelVerify, + End, //DataTypesMCC + Child, HVSpace, + MUIA_ShowMe, inst->ppb_fPreview && !inst->ppb_UseThumbNails, + MUIA_Disabled, TRUE, + MUIA_ShortHelp, GetLocString(MSGID_PREVIEWIMAGEBUBBLE), + MUIA_Weight, inst->ppb_PreviewWeight, + End, //VGroupV + End, // HGroup + + Child, HGroup, + Child, inst->ppb_Objects[OBJNDX_Lamp_Changed] = LampObject, + MUIA_Lamp_Type, MUIV_Lamp_Type_Huge, + MUIA_Lamp_Color, MUIV_Lamp_Color_Off, + MUIA_ShortHelp, GetLocString(MSGID_SHORTHELP_LAMP_CHANGED), + End, //LampObject + + Child, ColGroup(2), + Child, inst->ppb_Objects[OBJNDX_NewButton] = KeyButtonHelp(GetLocString(MSGID_NEWNAME), 'w', GetLocString(MSGID_SHORTHELP_NEWBUTTON)), + Child, inst->ppb_Objects[OBJNDX_DelButton] = KeyButtonHelp(GetLocString(MSGID_DELNAME), 'd', GetLocString(MSGID_SHORTHELP_DELBUTTON)), + End, //ColGroup + End, //HGroup + + Child, VGroup, + MUIA_Background, MUII_GroupBack, + GroupFrame, + + Child, inst->ppb_Objects[OBJNDX_Group_String] = ColGroup(5), + MUIA_Disabled, TRUE, + Child, inst->ppb_Objects[OBJNDX_NumButton] = NumericbuttonObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 1, + MUIA_Numeric_Max, 300, + MUIA_ShortHelp, GetLocString(MSGID_NUMBUTTONBUBBLE), + End, + Child, inst->ppb_Objects[OBJNDX_Popasl] = PopaslObject, + MUIA_CycleChain, TRUE, + MUIA_Popasl_Type, ASL_FileRequest, + MUIA_Popstring_String, inst->ppb_Objects[OBJNDX_STR_PopAsl] = MUI_MakeObject(MUIO_String, NULL, MAX_FILENAME), + MUIA_Popstring_Button, PopButton(MUII_PopFile), + End, + Child, inst->ppb_Objects[OBJNDX_CyclePatternType] = CycleObject, + MUIA_CycleChain, TRUE, + MUIA_Cycle_Entries, patternmode, + MUIA_Weight, 5, + MUIA_ShortHelp, GetLocString(MSGID_CYCLEGADBUBBLE), + End, + Child, Label(GetLocString(MSGID_REMAPNAME)), + Child, inst->ppb_Objects[OBJNDX_CheckmarkGad] = CheckMarkHelp(FALSE, MSGID_CHECKMARKGADBUBBLE), + End, + Child, inst->ppb_Objects[OBJNDX_Group_Slider] = HGroup, + MUIA_Disabled, TRUE, + MUIA_CycleChain, TRUE, + + Child, HGroup, + MUIA_ShowMe, (NULL != GuiGFXBase), + Child, Label(GetLocString(MSGID_ENHANCNAME)), + Child, inst->ppb_Objects[OBJNDX_CheckmarkEnh] = CheckMarkHelp(FALSE, MSGID_CHECKMARKENHBUBBLE), + End, //HGroup + + Child, Label(GetLocString(MSGID_PRECNAME)), + Child, inst->ppb_Objects[OBJNDX_PrecSlider] = PrecSliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 3, + MUIA_Numeric_Value, 1, + MUIA_ShortHelp, GetLocString(MSGID_PRECSLIDERBUBBLE), + End, + End, + + End, //VGroup + + Child, inst->ppb_Objects[OBJNDX_Group_Enhanced] = VGroup, + MUIA_Background, MUII_GroupBack, + GroupFrame, + MUIA_FrameTitle, GetLocString(MSGID_ENHANCOPTSNAME), + MUIA_ShowMe, (NULL != GuiGFXBase), + MUIA_Disabled, TRUE, + + Child, ColGroup(4), + Child, Label(GetLocString(MSGID_AUTODITHERNAME)), + Child, inst->ppb_Objects[OBJNDX_CheckmarkAutoDither] = CheckMarkHelp(FALSE, MSGID_CHECKMARKAUTODITHERBUBBLE), + Child, Label(GetLocString(MSGID_NUMCOLSNAME)), + Child, inst->ppb_Objects[OBJNDX_SliderColours] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 1, + MUIA_Numeric_Max, 100, + MUIA_Numeric_Format, "%ld %%", + MUIA_Numeric_Value, 10, + MUIA_ShortHelp, GetLocString(MSGID_COLORSSLIDERBUBBLE), + End, + End, //ColGroup + Child, HGroup, + Child, Label(GetLocString(MSGID_DITHERMODENAME)), + Child, inst->ppb_Objects[OBJNDX_CycleDitherMode] = CycleObject, + MUIA_CycleChain, TRUE, + MUIA_Cycle_Entries, dithermodecont, + MUIA_ShortHelp, GetLocString(MSGID_CYCLEDITHERMODEBUBBLE), + End, + Child, Label(GetLocString(MSGID_DITHERAMOUNTNAME)), + Child, inst->ppb_Objects[OBJNDX_SliderDitherAmount] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Slider_Min, 1, + MUIA_Slider_Max, 20, + MUIA_ShortHelp, GetLocString(MSGID_SLIDERDITHERAMOUNTBUBBLE), + End, + End, //HGroup + + End, //VGroup + End, //VGroup + +// Register page "Background Colours" + Child, VGroup, + Child, VGroup, + Child, HGroup, + Child, Label(GetLocString(MSGID_LABEL_CYCLEBACKGROUND)), + Child, inst->ppb_Objects[OBJNDX_CycleBackgroundType] = CycleObject, + MUIA_Cycle_Entries, CycleBackgroundModeStrings, + MUIA_CycleChain, TRUE, + MUIA_Disabled, TRUE, + End, //CycleObject + MUIA_ShortHelp, GetLocString(MSGID_SHORTHELP_CYCLEBACKGROUND), + End, //HGroup + + Child, inst->ppb_Objects[OBJNDX_ColorAdjustBgColor1] = ColoradjustObject, + MUIA_CycleChain, TRUE, + MUIA_Disabled, TRUE, + MUIA_ShortHelp, GetLocString(MSGID_SHORTHELP_BACKGROUNDCOLOR1), + End, //ColoradjustObject + + Child, BalanceObject, + End, //BalanceObject + + Child, inst->ppb_Objects[OBJNDX_ColorAdjustBgColor2] = ColoradjustObject, + MUIA_CycleChain, TRUE, + MUIA_Disabled, TRUE, + MUIA_ShortHelp, GetLocString(MSGID_SHORTHELP_BACKGROUNDCOLOR2), + End, //ColoradjustObject + + End, //VGroup + End, //VGroup + + +// Register page "Defaults" + Child, VGroup, + Child, HVSpace, + + Child, VGroup, + MUIA_Background, MUII_GroupBack, + GroupFrame, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_GROUP_MISCELLANEOUS), + + Child, HVSpace, + + Child, ColGroup(7), + Child, HVSpace, + Child, Label(GetLocString(MSGID_ASYNCNAME)), + Child, inst->ppb_Objects[OBJNDX_CheckmarkAsync] = CheckMarkHelp(FALSE, MSGID_CHECKMARKASYNCBUBBLE), + Child, HVSpace, + Child, Label(GetLocString(MSGID_FRIENDNAME)), + Child, inst->ppb_Objects[OBJNDX_CheckmarkFriend] = CheckMarkHelp(FALSE, MSGID_CHECKMARKFRIENDBUBBLE), + Child, HVSpace, + Child, HVSpace, + Child, Label(GetLocString(MSGID_RELAYOUTNAME)), + Child, inst->ppb_Objects[OBJNDX_CheckmarkRelayout] = CheckMarkHelp(FALSE, MSGID_CHECKMARKRELAYOUTBUBBLE), + Child, HVSpace, + Child, Label(GetLocString(MSGID_RANDOMNAME)), + Child, inst->ppb_Objects[OBJNDX_CheckmarkRandom] = CheckMarkHelp(FALSE, MSGID_CHECKMARKRANDOMBUBBLE), + Child, HVSpace, + End, + + Child, ColGroup(2), + Child, Label(GetLocString(MSGID_TASKPRINAME)), + Child, inst->ppb_Objects[OBJNDX_SliderTaskPri] = PatternSliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, -128, + MUIA_Numeric_Max, 127, + MUIA_Numeric_Value, -3, + MUIA_Disabled, TRUE, + MUIA_ShortHelp, GetLocString(MSGID_SLIDERTASKPRIBUBBLE), + End, + End, //ColGroup + + Child, HVSpace, + + End, //VGroup + + Child, VGroup, + MUIA_Background, MUII_GroupBack, + GroupFrame, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_GROUP_PATTERNNUMBERS), + + Child, HVSpace, + + Child, HGroup, + Child, inst->ppb_Objects[OBJNDX_Group_PatternSliders] = ColGroup(2), + Child, VSpace(0), + Child, VSpace(0), + + Child, Label(GetLocString(MSGID_DEFWBNAME)), + Child, inst->ppb_Objects[OBJNDX_SliderWB] = PatternSliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 300, + MUIA_Numeric_Value, 0, + MUIA_ShortHelp, GetLocString(MSGID_SLIDERWBBUBBLE), + End, + + Child, VSpace(0), + Child, VSpace(0), + + Child, Label(GetLocString(MSGID_DEFSCREENNAME)), + Child, inst->ppb_Objects[OBJNDX_SliderScreen] = PatternSliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 300, + MUIA_Numeric_Value, 0, + MUIA_ShortHelp, GetLocString(MSGID_SLIDERSCREENBUBBLE), + End, + + Child, VSpace(0), + Child, VSpace(0), + + Child, Label(GetLocString(MSGID_DEFWINNAME)), + Child, inst->ppb_Objects[OBJNDX_SliderWin] = PatternSliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 300, + MUIA_Numeric_Value, 0, + MUIA_ShortHelp, GetLocString(MSGID_SLIDERWINBUBBLE), + End, + + Child, VSpace(0), + Child, VSpace(0), + + Child, Label(GetLocString(MSGID_TEXTNAME)), + Child, inst->ppb_Objects[OBJNDX_SliderText] = PatternSliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 300, + MUIA_Numeric_Value, 0, + MUIA_ShortHelp, GetLocString(MSGID_SLIDERTEXTBUBBLE), + End, + + Child, VSpace(0), + Child, VSpace(0), + + End, //ColGroup + + Child, inst->ppb_Objects[OBJNDX_Group_PatternPreviews] = VGroup, + MUIA_ShowMe, inst->ppb_UseThumbNails, + + Child, inst->ppb_Objects[OBJNDX_Image_DesktopPattern] = BackfillObject, + MUIA_UserData, inst, + ImageButtonFrame, + MUIA_Background, MUII_ButtonBack, + ImageButtonFrame, + MUIA_InputMode, MUIV_InputMode_None, + BFA_BitmapObject, inst->ppb_Objects[OBJNDX_EmptyThumbnailBitmap], + End, //BackfillClass + Child, inst->ppb_Objects[OBJNDX_Image_ScreenPattern] = BackfillObject, + MUIA_UserData, inst, + ImageButtonFrame, + MUIA_Background, MUII_ButtonBack, + ImageButtonFrame, + MUIA_InputMode, MUIV_InputMode_None, + BFA_BitmapObject, inst->ppb_Objects[OBJNDX_EmptyThumbnailBitmap], + End, //BackfillClass + Child, inst->ppb_Objects[OBJNDX_Image_IconWindowPattern] = BackfillObject, + MUIA_UserData, inst, + ImageButtonFrame, + MUIA_Background, MUII_ButtonBack, + ImageButtonFrame, + MUIA_InputMode, MUIV_InputMode_None, + BFA_BitmapObject, inst->ppb_Objects[OBJNDX_EmptyThumbnailBitmap], + End, //BackfillClass + Child, inst->ppb_Objects[OBJNDX_Image_TextWindowPattern] = BackfillObject, + MUIA_UserData, inst, + ImageButtonFrame, + MUIA_Background, MUII_ButtonBack, + ImageButtonFrame, + MUIA_InputMode, MUIV_InputMode_None, + BFA_BitmapObject, inst->ppb_Objects[OBJNDX_EmptyThumbnailBitmap], + End, //BackfillClass + + End, //VGroup + End, //HGroup + + Child, HVSpace, + + End, //VGroup + + Child, HVSpace, + + End, + End, + + MUIA_ContextMenu, inst->ppb_Objects[OBJNDX_ContextMenu], + End; + + if (NULL == inst->ppb_Objects[OBJNDX_Group_Main]) + return NULL; + + d1(KPrintF("%s/%s/%ld: fPreview=%ld ppb_UseThumbNails=%ld\n", __FILE__, __FUNC__, __LINE__, inst->ppb_fPreview, inst->ppb_UseThumbNails)); + + if (inst->ppb_UseThumbNails && inst->ppb_Objects[OBJNDX_EmptyThumbnailBitmap]) + { + d1(kprintf("%s/%s/%ld: BitMapObj=%08lx Nr=%lu\n", \ + __FILE__, __FUNC__, __LINE__, inst->ppb_Objects[OBJNDX_EmptyThumbnailBitmap], 1 + inst->ppb_ThumbnailImageNumber)); + + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_UseImage, + inst->ppb_Objects[OBJNDX_EmptyThumbnailBitmap], inst->ppb_ThumbnailImageNumber++, 0); + } + + set(inst->ppb_Objects[OBJNDX_Menu_Thumbnails], MUIA_Menuitem_Checked, inst->ppb_UseThumbNails); + set(inst->ppb_Objects[OBJNDX_Menu_ShowPreview], MUIA_Menuitem_Checked, inst->ppb_fPreview && !inst->ppb_UseThumbNails); + set(inst->ppb_Objects[OBJNDX_Menu_ShowPreview], MUIA_Menuitem_Enabled, !inst->ppb_UseThumbNails); + set(inst->ppb_Objects[OBJNDX_Menu_AutoPreview], MUIA_Menuitem_Checked, inst->ppb_fAutoPreview); + set(inst->ppb_Objects[OBJNDX_Menu_AutoPreview], MUIA_Menuitem_Enabled, inst->ppb_fPreview && !inst->ppb_UseThumbNails); + set(inst->ppb_Objects[OBJNDX_Menu_ReloadThumbnails], MUIA_Menuitem_Enabled, inst->ppb_UseThumbNails); + + set(inst->ppb_Objects[OBJNDX_DelButton], MUIA_Disabled, TRUE); + + set(inst->ppb_Objects[OBJNDX_Balance], MUIA_ShowMe, inst->ppb_fPreview && !inst->ppb_UseThumbNails); + set(inst->ppb_Objects[OBJNDX_Group_Preview], MUIA_ShowMe, inst->ppb_fPreview && !inst->ppb_UseThumbNails); + + DoMethod(inst->ppb_Objects[OBJNDX_Group_Main], MUIM_Notify, MUIA_ContextMenuTrigger, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_Group_Main], 3, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_ContextMenuTrigger], MUIV_TriggerValue ); + + DoMethod(inst->ppb_Objects[OBJNDX_PreviewImage], MUIM_Notify, MUIA_Pressed, FALSE, + inst->ppb_Objects[OBJNDX_PreviewImage], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_PreviewSelect]); + + DoMethod(inst->ppb_Objects[OBJNDX_STR_PopAsl], MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_MainList], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_ListChangeEntry]); + + // setup sorting hooks for plugin list + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_Notify, MUIA_NList_TitleClick, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_MainList], 4, MUIM_NList_Sort3, MUIV_TriggerValue, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_Both); + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_Notify, MUIA_NList_TitleClick2, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_MainList], 4, MUIM_NList_Sort3, MUIV_TriggerValue, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_2); + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_Notify, MUIA_NList_SortType, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_MainList], 3, MUIM_Set, MUIA_NList_TitleMark, MUIV_TriggerValue); + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_Notify, MUIA_NList_SortType2, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_MainList], 3, MUIM_Set, MUIA_NList_TitleMark2, MUIV_TriggerValue); + + /* Call the AppMsgHook when an icon is dropped on a listview */ + DoMethod(inst->ppb_Objects[OBJNDX_MainListView], MUIM_Notify, MUIA_AppMessage, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_MainListView], 3, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_AppMsgInMainList], MUIV_TriggerValue); + + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_Notify, MUIA_NList_Active, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_MainList], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_ListSelectEntry]); + + // Call hook whenever background type is modified + DoMethod(inst->ppb_Objects[OBJNDX_CycleBackgroundType], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_MainList], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_ListChangeEntry2]); + + // Call hook whenever back color 1 is modified + DoMethod(inst->ppb_Objects[OBJNDX_ColorAdjustBgColor1], MUIM_Notify, MUIA_Coloradjust_RGB, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_MainList], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_ListChangeEntry2]); + + // Call hook whenever back color 2 is modified + DoMethod(inst->ppb_Objects[OBJNDX_ColorAdjustBgColor2], MUIM_Notify, MUIA_Coloradjust_RGB, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_MainList], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_ListChangeEntry2]); + + // Call hook whenever pattern type is modified + DoMethod(inst->ppb_Objects[OBJNDX_CyclePatternType], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_MainList], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_ListChangeEntry2]); + + DoMethod(inst->ppb_Objects[OBJNDX_CheckmarkGad], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_MainList], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_ListChangeEntry2]); + + DoMethod(inst->ppb_Objects[OBJNDX_CheckmarkGad], MUIM_Notify, MUIA_Selected, TRUE, + inst->ppb_Objects[OBJNDX_CheckmarkEnh], 3, MUIM_Set, MUIA_Selected, FALSE); + + DoMethod(inst->ppb_Objects[OBJNDX_CheckmarkEnh], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_MainList], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_ListChangeEntry2]); + + DoMethod(inst->ppb_Objects[OBJNDX_CheckmarkEnh], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_Group_Enhanced], 3, MUIM_Set, MUIA_Disabled, MUIV_NotTriggerValue); + + DoMethod(inst->ppb_Objects[OBJNDX_CheckmarkAsync], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_SliderTaskPri], 3, MUIM_Set, MUIA_Disabled, MUIV_NotTriggerValue); + + DoMethod(inst->ppb_Objects[OBJNDX_DelButton], MUIM_Notify, MUIA_Pressed, FALSE, + inst->ppb_Objects[OBJNDX_MainList], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_RemEntry]); + + DoMethod(inst->ppb_Objects[OBJNDX_NewButton], MUIM_Notify, MUIA_Pressed, FALSE, + inst->ppb_Objects[OBJNDX_MainList], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_AddNewEntry]); + + DoMethod(inst->ppb_Objects[OBJNDX_NumButton], MUIM_Notify, MUIA_Numeric_Value, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_MainList], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_ListChangeEntry3]); + + DoMethod(inst->ppb_Objects[OBJNDX_PrecSlider], MUIM_Notify, MUIA_Numeric_Value, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_MainList], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_ListChangeEntry2]); + + DoMethod(inst->ppb_Objects[OBJNDX_SliderColours], MUIM_Notify, MUIA_Numeric_Value, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_MainList], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_ListChangeEntry2]); + + DoMethod(inst->ppb_Objects[OBJNDX_SliderDitherAmount], MUIM_Notify, MUIA_Numeric_Value, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_MainList], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_ListChangeEntry2]); + + DoMethod(inst->ppb_Objects[OBJNDX_CycleDitherMode], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_MainList], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_ListChangeEntry2]); + + DoMethod(inst->ppb_Objects[OBJNDX_CheckmarkAutoDither], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_MainList], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_ListChangeEntry2]); + + + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_Notify, MUIA_NList_InsertPosition, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_MainList], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_SettingsChanged]); + + DoMethod(inst->ppb_Objects[OBJNDX_SliderWB], MUIM_Notify, MUIA_Numeric_Value, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_Group_Main], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_SettingsChanged]); + + DoMethod(inst->ppb_Objects[OBJNDX_SliderScreen], MUIM_Notify, MUIA_Numeric_Value, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_Group_Main], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_SettingsChanged]); + + DoMethod(inst->ppb_Objects[OBJNDX_SliderWin], MUIM_Notify, MUIA_Numeric_Value, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_Group_Main], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_SettingsChanged]); + + DoMethod(inst->ppb_Objects[OBJNDX_SliderText], MUIM_Notify, MUIA_Numeric_Value, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_Group_Main], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_SettingsChanged]); + + DoMethod(inst->ppb_Objects[OBJNDX_CheckmarkAsync], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_Group_Main], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_SettingsChanged]); + + DoMethod(inst->ppb_Objects[OBJNDX_CheckmarkFriend], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_Group_Main], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_SettingsChanged]); + + DoMethod(inst->ppb_Objects[OBJNDX_CheckmarkRelayout], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_Group_Main], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_SettingsChanged]); + + DoMethod(inst->ppb_Objects[OBJNDX_CheckmarkRandom], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_Group_Main], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_SettingsChanged]); + + DoMethod(inst->ppb_Objects[OBJNDX_SliderTaskPri], MUIM_Notify, MUIA_Numeric_Value, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_Group_Main], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_SettingsChanged]); + + // Changing the default pattern numbers for desktop, screen, icon windows, + // and text windows updates the preview images + DoMethod(inst->ppb_Objects[OBJNDX_SliderWB], MUIM_Notify, MUIA_Slider_Level, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_Image_DesktopPattern], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_DesktopPatternChanged]); + DoMethod(inst->ppb_Objects[OBJNDX_SliderScreen], MUIM_Notify, MUIA_Slider_Level, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_Image_ScreenPattern], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_ScreenPatternChanged]); + DoMethod(inst->ppb_Objects[OBJNDX_SliderWin], MUIM_Notify, MUIA_Slider_Level, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_Image_IconWindowPattern], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_IconWindowPatternChanged]); + DoMethod(inst->ppb_Objects[OBJNDX_SliderText], MUIM_Notify, MUIA_Slider_Level, MUIV_EveryTime, + inst->ppb_Objects[OBJNDX_Image_TextWindowPattern], 2, MUIM_CallHook, &inst->ppb_Hooks[HOOKNDX_TextWindowPatternChanged]); + + return inst->ppb_Objects[OBJNDX_Group_Main]; +} + + +static void CreateSubWindows(struct PatternPrefsInst *inst) +{ + inst->ppb_SubWindows[0] = inst->ppb_Objects[OBJNDX_WIN_Message] = WindowObject, +// MUIA_Window_Borderless, TRUE, + MUIA_Window_Activate, FALSE, + MUIA_Window_NoMenus, TRUE, + MUIA_Window_Title, GetLocString(MSGID_WINDOW_STARTUP), + WindowContents, VGroup, + Child, inst->ppb_Objects[OBJNDX_MsgGauge] = GaugeObject, + MUIA_Gauge_Horiz, TRUE, + GaugeFrame, + MUIA_Gauge_InfoText, " ", + End, + Child, inst->ppb_Objects[OBJNDX_MsgText1] = TextObject, + MUIA_Text_PreParse, MUIX_C, + MUIA_Text_Contents, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + End, + Child, inst->ppb_Objects[OBJNDX_MsgText2] = TextObject, + MUIA_Text_PreParse, MUIX_C, + MUIA_Text_Contents, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + End, + End, + End; + + inst->ppb_SubWindows[1] = NULL; +} + + +static ULONG DoOmSet(Class *cl, Object *o, struct opSet *ops) +{ + struct PatternPrefsInst *inst = (struct PatternPrefsInst *) INST_DATA(cl, o); + struct TagItem *TagList = ops->ops_AttrList; + struct TagItem *ti; + ULONG result = 0; + + while ((ti = NextTagItem(&TagList))) + { + d1(kprintf(__FILE__ "/%s/%ld: ti=%08lx Tag=%08lx Data=%08lx\n", __FUNC__, __FILE__, __FUNC__, __LINE__, ti, ti->ti_Tag, ti->ti_Data)); + + switch (ti->ti_Tag) + { + case MUIA_ScalosPrefs_CreateIcons: + d1(KPrintF("%s/%s/%ld: MUIA_ScalosPrefs_CreateIcons obj=%08lx\n", __FILE__, __FUNC__, __LINE__, o)); + inst->ppb_fCreateIcons = ti->ti_Data; + break; + case MUIA_ScalosPrefs_ProgramName: + d1(KPrintF("%s/%s/%ld: MUIA_ScalosPrefs_ProgramName obj=%08lx\n", __FILE__, __FUNC__, __LINE__, o)); + inst->ppb_ProgramName = (CONST_STRPTR) ti->ti_Data; + break; + case MUIA_ScalosPrefs_MainWindow: + d1(KPrintF("%s/%s/%ld: MUIA_ScalosPrefs_MainWindow obj=%08lx\n", __FILE__, __FUNC__, __LINE__, o)); + inst->ppb_Objects[OBJNDX_WIN_Main] = (APTR) ti->ti_Data; + break; + case MUIA_ScalosPrefs_Application: + d1(KPrintF("%s/%s/%ld: MUIA_ScalosPrefs_Application obj=%08lx\n", __FILE__, __FUNC__, __LINE__, o)); + inst->ppb_Objects[OBJNDX_APP_Main] = (APTR) ti->ti_Data; + break; + case MUIA_ScalosPrefs_PatternPrefs_Preview: + d1(KPrintF("%s/%s/%ld: MUIA_ScalosPrefs_PatternPrefs_Preview obj=%08lx\n", __FILE__, __FUNC__, __LINE__, o)); + inst->ppb_fPreview = ti->ti_Data; + break; + case MUIA_ScalosPrefs_PatternPrefs_AutoPreview: + d1(KPrintF("%s/%s/%ld: MUIA_ScalosPrefs_PatternPrefs_AutoPreview obj=%08lx\n", __FILE__, __FUNC__, __LINE__, o)); + inst->ppb_fAutoPreview = ti->ti_Data; + break; + case MUIA_ScalosPrefs_PatternPrefs_PreviewWeight: + d1(KPrintF("%s/%s/%ld: MUIA_ScalosPrefs_PatternPrefs_PreviewWeight obj=%08lx\n", __FILE__, __FUNC__, __LINE__, o)); + inst->ppb_PreviewWeight = ti->ti_Data; + break; + case MUIA_ScalosPrefs_PatternPrefs_Thumbnails: + d1(KPrintF("%s/%s/%ld: MUIA_ScalosPrefs_PatternPrefs_Thumbnails obj=%08lx\n", __FILE__, __FUNC__, __LINE__, o)); + inst->ppb_UseThumbNails = ti->ti_Data; + set(inst->ppb_Objects[OBJNDX_MainList], MUIA_NList_Format, + (ULONG) (inst->ppb_UseThumbNails ? LISTFORMAT_THUMBNAILS : LISTFORMAT_STANDARD)); + break; + default: + d1(KPrintF(__FILE__ "/%s/%ld: unknown tag o=%08lx Tag=%08lx\n", __FUNC__, __FILE__, __FUNC__, __LINE__, o, ti->ti_Tag)); + result = DoSuperMethodA(cl, o, (Msg) ops); + break; + } + } + + return result; +} + + +static Object *CreatePrefsImage(void) +{ +#include "PatternPrefsImage.h" + Object *img; + + // First try to load datatypes image from THEME: tree + img = DataTypesImageObject, + MUIA_ScaDtpic_Name, (ULONG) "THEME:prefs/plugins/pattern", + MUIA_ScaDtpic_FailIfUnavailable, TRUE, + End; //DataTypesMCCObject + + if (NULL == img) + img = IMG(PatternPrefs, PATTERNPREFS); // use built-in fallback image + + return img; +} + + +static void InitHooks(struct PatternPrefsInst *inst) +{ + ULONG n; + + for (n=0; nppb_Hooks[n] = PatternPrefsHooks[n]; + inst->ppb_Hooks[n].h_Data = inst; + } +} + + +static BOOL OpenLibraries(void) +{ + DOSBase = (APTR) OpenLibrary( "dos.library", 39 ); + if (NULL == DOSBase) + return FALSE; +#ifdef __amigaos4__ + IDOS = (struct DOSIFace *) GetInterface((struct Library *) DOSBase, "main", 1, NULL); + if (NULL == IDOS) + return FALSE; +#endif + + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + if (NULL == IntuitionBase) + return FALSE; +#ifdef __amigaos4__ + IIntuition = (struct IntuitionIFace *) GetInterface((struct Library *) IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + return FALSE; +#endif + + MUIMasterBase = OpenLibrary("zune.library", 0); + if (NULL == MUIMasterBase) + MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN-1); + if (NULL == MUIMasterBase) + return FALSE; +#ifdef __amigaos4__ + IMUIMaster = (struct MUIMasterIFace *) GetInterface((struct Library *) MUIMasterBase, "main", 1, NULL); + if (NULL == IMUIMaster) + return FALSE; +#endif + + IFFParseBase = OpenLibrary("iffparse.library", 36); + if (NULL == IFFParseBase) + return FALSE; +#ifdef __amigaos4__ + IIFFParse = (struct IFFParseIFace *) GetInterface((struct Library *) IFFParseBase, "main", 1, NULL); + if (NULL == IIFFParse) + return FALSE; +#endif + + IconBase = OpenLibrary("icon.library", 0); + if (NULL == IconBase) + return FALSE; +#ifdef __amigaos4__ + IIcon = (struct IconIFace *) GetInterface((struct Library *) IconBase, "main", 1, NULL); + if (NULL == IIcon) + return FALSE; +#endif + + GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 39); + if (NULL == GfxBase) + return FALSE; +#ifdef __amigaos4__ + IGraphics = (struct GraphicsIFace *) GetInterface((struct Library *) GfxBase, "main", 1, NULL); + if (NULL == IGraphics) + return FALSE; +#endif + + DataTypesBase = OpenLibrary("datatypes.library", 39); + if (NULL == DataTypesBase) + return FALSE; +#ifdef __amigaos4__ + IDataTypes = (struct DataTypesIFace *) GetInterface((struct Library *) DataTypesBase, "main", 1, NULL); + if (NULL == IDataTypes) + return FALSE; +#endif + + UtilityBase = (T_UTILITYBASE) OpenLibrary(UTILITYNAME, 39); + if (NULL == UtilityBase) + return FALSE; +#ifdef __amigaos4__ + IUtility = (struct UtilityIFace *) GetInterface((struct Library *) UtilityBase, "main", 1, NULL); + if (NULL == IUtility) + return FALSE; +#endif + + ScalosGfxBase = (struct ScalosGfxBase *) OpenLibrary(SCALOSGFXNAME, 41); + if (NULL == ScalosGfxBase) + return FALSE; +#ifdef __amigaos4__ + IScalosGfx = (struct ScalosGfxIFace *) GetInterface((struct Library *) ScalosGfxBase, "main", 1, NULL); + if (NULL == IScalosGfx) + return FALSE; +#endif + + TimerIORequest = (T_TIMEREQUEST *) CreateIORequest(CreateMsgPort(), sizeof(T_TIMEREQUEST)); + if (NULL == TimerIORequest) + return FALSE; + if (0 != OpenDevice("timer.device", UNIT_VBLANK, &TimerIORequest->tr_node, 0)) + { + // OpenDevice failed + DeleteIORequest(&TimerIORequest->tr_node); + TimerIORequest = NULL; + return FALSE; + } + TimerBase = (T_TIMERBASE) TimerIORequest->tr_node.io_Device; + if (NULL == TimerBase) + return FALSE; +#ifdef __amigaos4__ + ITimer = (struct TimerIFace *)GetInterface((struct Library *)TimerBase, "main", 1, NULL); + if (NULL == ITimer) + return FALSE; +#endif /* __amigaos4__ */ + + + CyberGfxBase = (APTR) OpenLibrary( "cybergraphics.library", 40); +#ifdef __amigaos4__ + if (CyberGfxBase) + ICyberGfx = (struct CyberGfxIFace *) GetInterface((struct Library *) CyberGfxBase, "main", 1, NULL); +#endif + // CyberGfxBase may be NULL + +#if defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) + __UtilityBase = UtilityBase; +#endif /* defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__)*/ + +#ifdef __amigaos4__ + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + return FALSE; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + return FALSE; +#endif + + GuiGFXBase = OpenLibrary("guigfx.library", 1); +#ifdef __amigaos4__ + if (GuiGFXBase) + IGuiGFX = (struct GuiGFXIFace *) GetInterface((struct Library *) GuiGFXBase, "main", 1, NULL); +#endif + + LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 39); +#ifdef __amigaos4__ + if (LocaleBase) + ILocale = (struct LocaleIFace *) GetInterface((struct Library *) LocaleBase, "main", 1, NULL); +#endif + + return TRUE; +} + + +static void CloseLibraries(void) +{ + if (TimerIORequest) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)ITimer); +#endif + CloseDevice(&TimerIORequest->tr_node); + DeleteIORequest(&TimerIORequest->tr_node); + TimerIORequest = NULL; + } +#ifdef __amigaos4__ + if (INewlib) + { + DropInterface(INewlib); + INewlib = NULL; + } + if (NewlibBase) + { + CloseLibrary(NewlibBase); + NewlibBase = NULL; + } + if (ICyberGfx) + { + DropInterface((struct Interface *)ICyberGfx); + ICyberGfx = NULL; + } +#endif + if (CyberGfxBase) + { + CloseLibrary(CyberGfxBase); + CyberGfxBase = NULL; + } +#ifdef __amigaos4__ + if (IScalosGfx) + { + DropInterface((struct Interface *)IScalosGfx); + IScalosGfx = NULL; + } +#endif + if (ScalosGfxBase) + { + CloseLibrary((struct Library *) ScalosGfxBase); + ScalosGfxBase = NULL; + } +#ifdef __amigaos4__ + if (IGuiGFX) + { + DropInterface((struct Interface *)IGuiGFX); + IGuiGFX = NULL; + } +#endif + if (GuiGFXBase) + { + CloseLibrary(GuiGFXBase); + GuiGFXBase = NULL; + } +#ifdef __amigaos4__ + if (ILocale) + { + DropInterface((struct Interface *)ILocale); + ILocale = NULL; + } +#endif + if (LocaleBase) + { + CloseLibrary((struct Library *) LocaleBase); + LocaleBase = NULL; + } +#ifdef __amigaos4__ + if (IDataTypes) + { + DropInterface((struct Interface *)IDataTypes); + IDataTypes = NULL; + } +#endif + if (DataTypesBase) + { + CloseLibrary(DataTypesBase); + DataTypesBase = NULL; + } +#ifdef __amigaos4__ + if (IUtility) + { + DropInterface((struct Interface *)IUtility); + IUtility = NULL; + } +#endif + if (UtilityBase) + { + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } +#ifdef __amigaos4__ + if (IGraphics) + { + DropInterface((struct Interface *)IGraphics); + IGraphics = NULL; + } +#endif + if (GfxBase) + { + CloseLibrary((struct Library *) GfxBase); + GfxBase = NULL; + } +#ifdef __amigaos4__ + if (IIcon) + { + DropInterface((struct Interface *)IIcon); + IIcon = NULL; + } +#endif + if (IconBase) + { + CloseLibrary(IconBase); + IconBase = NULL; + } +#ifdef __amigaos4__ + if (IIFFParse) + { + DropInterface((struct Interface *)IIFFParse); + IIFFParse = NULL; + } +#endif + if (IFFParseBase) + { + CloseLibrary(IFFParseBase); + IFFParseBase = NULL; + } +#ifdef __amigaos4__ + if (IMUIMaster) + { + DropInterface((struct Interface *)IMUIMaster); + IMUIMaster = NULL; + } +#endif + if (MUIMasterBase) + { + CloseLibrary(MUIMasterBase); + MUIMasterBase = NULL; + } +#ifdef __amigaos4__ + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } +#endif + if (IntuitionBase) + { + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } +#ifdef __amigaos4__ + if (IDOS) + { + DropInterface((struct Interface *)IDOS); + IDOS = NULL; + } +#endif + if (DOSBase) + { + CloseLibrary((struct Library *) DOSBase); + DOSBase = NULL; + } +} + +//---------------------------------------------------------------------------- + +static STRPTR GetLocString(ULONG MsgId) +{ + struct ScalosPattern_LocaleInfo li; + + li.li_Catalog = PatternPrefsCatalog; +#ifndef __amigaos4__ + li.li_LocaleBase = LocaleBase; +#else + li.li_ILocale = ILocale; +#endif + + return (STRPTR)GetScalosPatternString(&li, MsgId); +} + + +static void TranslateStringArray(STRPTR *stringArray) +{ + while (*stringArray) + { + *stringArray = GetLocString((ULONG) *stringArray); + stringArray++; + } +} + +static void TranslateNewMenu(struct NewMenu *nm) +{ + while (nm && NM_END != nm->nm_Type) + { + if (NM_BARLABEL != nm->nm_Label) + nm->nm_Label = GetLocString((ULONG) nm->nm_Label); + + if (nm->nm_CommKey) + nm->nm_CommKey = GetLocString((ULONG) nm->nm_CommKey); + + nm++; + } +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT ListConstructHookFunc(struct Hook *hook, Object *obj, struct NList_ConstructMessage *msg) +{ + struct PatternListEntry *scp = AllocPooled(msg->pool, sizeof(struct PatternListEntry)); + + if (scp) + { + CONST_STRPTR FileName = (CONST_STRPTR) msg->entry; + + stccpy(scp->ple_PatternPrefs.scxp_Name, FileName, sizeof(scp->ple_PatternPrefs.scxp_Name)); + + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Number = 1; + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_RenderType = SCP_RenderType_Tiled; + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Flags = SCPF_ENHANCED | SCPF_AUTODITHER; + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_NumColors = 100; + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_DitherMode = DITHERMODE_FS; + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_DitherAmount = 1; + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Precision = PRECISION_IMAGE; + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Type = SCP_BgType_Picture; + + scp->ple_ThumbnailImageNr = 0; + scp->ple_SAC = NULL; + scp->ple_MUI_ImageObject = NULL; + scp->ple_BitMapArray = NULL; + } + + return scp; +} + +static SAVEDS(void) INTERRUPT ListDestructHookFunc(struct Hook *hook, Object *obj, struct NList_DestructMessage *msg) +{ + struct PatternListEntry *scp = (struct PatternListEntry *) msg->entry; + struct PatternPrefsInst *inst = (struct PatternPrefsInst *) hook->h_Data; + + if (scp->ple_BitMapArray) + { + free(scp->ple_BitMapArray); + scp->ple_BitMapArray = NULL; + } + if (scp->ple_MUI_ImageObject) + { + DoMethod(inst->ppb_Objects[OBJNDX_MainList], + MUIM_NList_UseImage, NULL, scp->ple_ThumbnailImageNr, 0); + + MUI_DisposeObject(scp->ple_MUI_ImageObject); + scp->ple_MUI_ImageObject = NULL; + } + if (scp->ple_SAC) + { + ScalosGfxFreeSAC(scp->ple_SAC); + scp->ple_SAC = NULL; + } + + FreePooled(msg->pool, scp, sizeof(struct PatternListEntry)); +} + + +static SAVEDS(ULONG) INTERRUPT ListDisplayHookFunc(struct Hook *hook, Object *obj, struct NList_DisplayMessage *ndm) +{ + struct PatternPrefsInst *inst = (struct PatternPrefsInst *) hook->h_Data; + ULONG n; + + if (ndm->entry) + { + struct PatternListEntry *scp = (struct PatternListEntry *) ndm->entry; + static char Buffer[MAX_FILENAME]; + STRPTR lp = Buffer; + ULONG DesktopPattern = 0; + ULONG ScreenPattern = 0; + ULONG IconWindowPattern = 0; + ULONG TextWindowPattern = 0; + + n = 0; + + // 1st column -- pattern number + ndm->preparses[n++] = "\033r"; + + // 2nd column -- select status + ndm->preparses[n++] = "\033r"; + + // 3rd column -- thumbnail + if (inst->ppb_UseThumbNails) + { + ndm->preparses[n++] = "\033c"; + } + + // last column -- file name + ndm->preparses[n] = "\033l"; + + // 1st column -- pattern number + n = 0; + sprintf(lp, "%d", scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Number); + ndm->strings[n++] = lp; + + // 2nd column -- select status + get(inst->ppb_Objects[OBJNDX_SliderWB], MUIA_Numeric_Value, &DesktopPattern); + get(inst->ppb_Objects[OBJNDX_SliderScreen], MUIA_Numeric_Value, &ScreenPattern); + get(inst->ppb_Objects[OBJNDX_SliderWin], MUIA_Numeric_Value, &IconWindowPattern); + get(inst->ppb_Objects[OBJNDX_SliderText], MUIA_Numeric_Value, &TextWindowPattern); + + if (DesktopPattern == scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Number) + ndm->strings[n++] = GetLocString(MSGID_PATTERNTYPE_DESKTOP); + else if (ScreenPattern == scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Number) + ndm->strings[n++] = GetLocString(MSGID_PATTERNTYPE_SCREEN); + else if (IconWindowPattern == scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Number) + ndm->strings[n++] = GetLocString(MSGID_PATTERNTYPE_ICONWINDOW); + else if (TextWindowPattern == scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Number) + ndm->strings[n++] = GetLocString(MSGID_PATTERNTYPE_TEXTWINDOW); + else + ndm->strings[n++] = GetLocString(MSGID_PATTERNTYPE_NONE); + + // 3rd column -- thumbnail + if (inst->ppb_UseThumbNails) + { + lp += 1 + strlen(lp); + sprintf(lp, "\33o[%ld]", (long)scp->ple_ThumbnailImageNr); + ndm->strings[n++] = lp; + + d1(kprintf("%s/%s/%ld: lp=<%s> ord=%ld scp=%08lx ImageObj=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, lp, ndm->entry_pos, scp, scp->ple_MUI_ImageObject)); + } + + // last column -- file name + + lp += 1 + strlen(lp); + strcpy(lp, scp->ple_PatternPrefs.scxp_Name); + ndm->strings[n] = lp; + } + else + { + // display titles + + n = 0; + + // 1st column -- pattern number + ndm->preparses[n++] = "\033c"; + + // 2nd column -- select status + ndm->preparses[n++] = "\033c"; + + // 3rd column -- thumbnail + if (inst->ppb_UseThumbNails) + { + ndm->preparses[n++] = "\033c"; + } + + ndm->preparses[n] = "\033c"; + + n = 0; + + // 1st column -- pattern number + ndm->strings[n++] = GetLocString(MSGID_COLUMNTITLE_1); + + // 2nd column -- select status + ndm->strings[n++] = GetLocString(MSGID_COLUMNTITLE_4); + + // 3rd column -- thumbnail + if (inst->ppb_UseThumbNails) + { + ndm->strings[n++] = GetLocString(MSGID_COLUMNTITLE_3); + } + + // last column -- file name + ndm->strings[n] = GetLocString(MSGID_COLUMNTITLE_2); + } + + return 0; +} + + +static SAVEDS(LONG) INTERRUPT ListCompareHookFunc(struct Hook *hook, Object *obj, struct NList_CompareMessage *ncm) +{ + struct PatternPrefsInst *inst = (struct PatternPrefsInst *) hook->h_Data; + const struct PatternListEntry *scp1 = (const struct PatternListEntry *) ncm->entry1; + const struct PatternListEntry *scp2 = (const struct PatternListEntry *) ncm->entry2; + LONG col1 = ncm->sort_type & MUIV_NList_TitleMark_ColMask; + LONG col2 = ncm->sort_type2 & MUIV_NList_TitleMark2_ColMask; + LONG Result = 0; + + if (ncm->sort_type != MUIV_NList_SortType_None) + { + // primary sorting + switch (col1) + { + case 0: // sort by number + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = scp2->ple_PatternPrefs.scxp_PatternPrefs.scp_Number - scp1->ple_PatternPrefs.scxp_PatternPrefs.scp_Number; + else + Result = scp1->ple_PatternPrefs.scxp_PatternPrefs.scp_Number - scp2->ple_PatternPrefs.scxp_PatternPrefs.scp_Number; + break; + case 2: + if (!inst->ppb_UseThumbNails) + { + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = Stricmp(scp2->ple_PatternPrefs.scxp_Name, scp1->ple_PatternPrefs.scxp_Name); + else + Result = Stricmp(scp1->ple_PatternPrefs.scxp_Name, scp2->ple_PatternPrefs.scxp_Name); + } + break; + case 3: // sort by filename + if (inst->ppb_UseThumbNails) + { + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = Stricmp(scp2->ple_PatternPrefs.scxp_Name, scp1->ple_PatternPrefs.scxp_Name); + else + Result = Stricmp(scp1->ple_PatternPrefs.scxp_Name, scp2->ple_PatternPrefs.scxp_Name); + } + break; + default: + break; + } + + if (0 == Result && col1 != col2) + { + // Secondary sorting + switch (col2) + { + case 0: // sort by number + if (ncm->sort_type2 & MUIV_NList_TitleMark2_TypeMask) + Result = scp1->ple_PatternPrefs.scxp_PatternPrefs.scp_Number - scp2->ple_PatternPrefs.scxp_PatternPrefs.scp_Number; + else + Result = scp2->ple_PatternPrefs.scxp_PatternPrefs.scp_Number - scp1->ple_PatternPrefs.scxp_PatternPrefs.scp_Number; + break; + case 2: // sort by filename + if (!inst->ppb_UseThumbNails) + { + if (ncm->sort_type2 & MUIV_NList_TitleMark2_TypeMask) + Result = Stricmp(scp2->ple_PatternPrefs.scxp_Name, scp1->ple_PatternPrefs.scxp_Name); + else + Result = Stricmp(scp1->ple_PatternPrefs.scxp_Name, scp2->ple_PatternPrefs.scxp_Name); + } + break; + case 3: // sort by filename + if (inst->ppb_UseThumbNails) + { + if (ncm->sort_type2 & MUIV_NList_TitleMark2_TypeMask) + Result = Stricmp(scp2->ple_PatternPrefs.scxp_Name, scp1->ple_PatternPrefs.scxp_Name); + else + Result = Stricmp(scp1->ple_PatternPrefs.scxp_Name, scp2->ple_PatternPrefs.scxp_Name); + } + break; + default: + break; + } + } + } + + return Result; +} + +//---------------------------------------------------------------------------- + +DISPATCHER(PatternSlider) +{ + struct MUIP_Numeric_Stringify *mstr = (struct MUIP_Numeric_Stringify *) msg; + ULONG Result; + + switch (msg->MethodID) + { + case MUIM_Numeric_Stringify: + if (0 == mstr->value) + Result = (ULONG) GetLocString(MSGID_NONE_PRIORITY); + else + Result = DoSuperMethodA(cl, obj, msg); + break; + + default: + Result = DoSuperMethodA(cl, obj, msg); + break; + } + + return Result; +} +DISPATCHER_END + +//---------------------------------------------------------------------------- + +DISPATCHER(PrecSlider) +{ + static ULONG PrecisionStrings[] = + { + MSGID_PRECEXACTNAME, + MSGID_PRECIMAGENAME, + MSGID_PRECICONNAME, + MSGID_PRECGUINAME + }; + struct MUIP_Numeric_Stringify *mstr = (struct MUIP_Numeric_Stringify *) msg; + ULONG Result; + + switch (msg->MethodID) + { + case MUIM_Numeric_Stringify: + Result = (ULONG) GetLocString(PrecisionStrings[mstr->value]); + break; + + default: + Result = DoSuperMethodA(cl, obj, msg); + break; + } + + return Result; +} +DISPATCHER_END + +//---------------------------------------------------------------------------- + +static LONG ReadPrefsFile(struct PatternPrefsInst *inst, CONST_STRPTR Filename, BOOL Quiet) +{ + static const LONG StopChunkList[] = + { + ID_PREF, ID_PATT, + ID_PREF, ID_PTRN, + ID_PREF, ID_DEFS, + ID_PREF, ID_TCOL, + ID_PREF, ID_TBMP + }; + struct TempRastPort trp; + LONG Result; + struct IFFHandle *iff; + BOOL iffOpened = FALSE; + + InitRastPort(&trp.trp_rp); + trp.trp_rp.BitMap = NULL; + trp.trp_rp.Layer = NULL; + trp.trp_Width = 0; + + inst->ppb_BitMapsRead = 0; + inst->ppb_ThumbnailImageNumber = 0; + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_Clear); + set(inst->ppb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, TRUE); + set(inst->ppb_Objects[OBJNDX_MainList], MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + + do { + struct PatternListEntry *scp = NULL; + + iff = AllocIFF(); + if (NULL == iff) + { + Result = IoErr(); + break; + } + + InitIFFasDOS(iff); + + iff->iff_Stream = (IPTR)Open(Filename, MODE_OLDFILE); + if (0 == iff->iff_Stream) + { + Result = IoErr(); + break; + } + + Result = OpenIFF(iff, IFFF_READ); + if (RETURN_OK != Result) + break; + + iffOpened = TRUE; + + Result = StopChunks(iff, StopChunkList, 5); + if (RETURN_OK != Result) + break; + + while (1) + { + struct ContextNode *cn; + + Result = ParseIFF(iff, IFFPARSE_SCAN); + d1(kprintf("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + if (RETURN_OK != Result) + break; + + cn = CurrentChunk(iff); + if (NULL == cn) + break; + + if (ID_PTRN == cn->cn_ID) + { + LONG Actual; + struct WBPatternPrefs ptrn; + + Actual = ReadChunkBytes(iff, &ptrn, sizeof(ptrn)); + if (sizeof(ptrn) != Actual) + { + Result = IoErr(); + break; + } + + ptrn.wbp_Which = SCA_BE2WORD(ptrn.wbp_Which); + ptrn.wbp_Flags = SCA_BE2WORD(ptrn.wbp_Flags); + ptrn.wbp_DataLength = SCA_BE2WORD(ptrn.wbp_DataLength); + + if (ptrn.wbp_Flags & WBPF_PATTERN) + { + ULONG nEntries = 0; + struct PatternListEntry *scp = NULL; + + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_InsertSingle, "", MUIV_NList_Insert_Bottom); + get(inst->ppb_Objects[OBJNDX_MainList], MUIA_NList_Entries, &nEntries); + + nEntries--; + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_GetEntry, nEntries, &scp); + + if (ptrn.wbp_Flags & WBPF_NOREMAP) + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Flags |= SCPF_NOREMAP; + } + } + else if (ID_DEFS == cn->cn_ID) + { + LONG Actual; + struct ScaPatternDefs pDefs; + + Actual = ReadChunkBytes(iff, &pDefs, sizeof(pDefs)); + if (sizeof(pDefs) != Actual) + { + Result = IoErr(); + break; + } + + pDefs.scd_Flags = SCA_BE2WORD(pDefs.scd_Flags); + pDefs.scd_WorkbenchPattern = SCA_BE2WORD(pDefs.scd_WorkbenchPattern); + pDefs.scd_ScreenPattern = SCA_BE2WORD(pDefs.scd_ScreenPattern); + pDefs.scd_WindowPattern = SCA_BE2WORD(pDefs.scd_WindowPattern); + pDefs.scd_TextModePattern = SCA_BE2WORD(pDefs.scd_TextModePattern); + + set(inst->ppb_Objects[OBJNDX_SliderWB], MUIA_Numeric_Value, (ULONG) pDefs.scd_WorkbenchPattern); + set(inst->ppb_Objects[OBJNDX_SliderScreen], MUIA_Numeric_Value, (ULONG) pDefs.scd_ScreenPattern); + set(inst->ppb_Objects[OBJNDX_SliderWin], MUIA_Numeric_Value, (ULONG) pDefs.scd_WindowPattern); + + if (Actual >= offsetof(struct ScaPatternDefs, scd_TextModePattern)) + { + set(inst->ppb_Objects[OBJNDX_SliderText], MUIA_Numeric_Value, (ULONG) pDefs.scd_TextModePattern); + set(inst->ppb_Objects[OBJNDX_SliderTaskPri], MUIA_Numeric_Value, (ULONG) pDefs.scd_TaskPriority); + } + + set(inst->ppb_Objects[OBJNDX_CheckmarkAsync], MUIA_Selected, (pDefs.scd_Flags & SCDF_ASYNCLAYOUT) ? TRUE : FALSE); + set(inst->ppb_Objects[OBJNDX_CheckmarkFriend], MUIA_Selected, (pDefs.scd_Flags & SCDF_USEFRIENDBM) ? TRUE : FALSE); + set(inst->ppb_Objects[OBJNDX_CheckmarkRelayout], MUIA_Selected, (pDefs.scd_Flags & SCDF_RELAYOUT) ? TRUE : FALSE); + set(inst->ppb_Objects[OBJNDX_CheckmarkRandom], MUIA_Selected, (pDefs.scd_Flags & SCDF_RANDOM) ? TRUE : FALSE); + } + else if (ID_PATT == cn->cn_ID) + { + ULONG nEntries = 0; + + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_InsertSingle, "", MUIV_NList_Insert_Bottom); + get(inst->ppb_Objects[OBJNDX_MainList], MUIA_NList_Entries, &nEntries); + + nEntries--; + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_GetEntry, nEntries, &scp); + + if (scp) + { + if (0 == ReadChunkBytes(iff, &scp->ple_PatternPrefs, sizeof(struct ScaExtPatternPrefs))) + { + Result = IoErr(); + break; + } + } + + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Number = SCA_BE2WORD(scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Number); + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_RenderType = SCA_BE2WORD(scp->ple_PatternPrefs.scxp_PatternPrefs.scp_RenderType); + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Flags = SCA_BE2WORD(scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Flags); + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_NumColors = SCA_BE2WORD(scp->ple_PatternPrefs.scxp_PatternPrefs.scp_NumColors); + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_DitherMode = SCA_BE2WORD(scp->ple_PatternPrefs.scxp_PatternPrefs.scp_DitherMode); + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_DitherAmount = SCA_BE2WORD(scp->ple_PatternPrefs.scxp_PatternPrefs.scp_DitherAmount); + + } + else if (ID_TCOL == cn->cn_ID) + { + // ID_TCOL must always be immediately preceeded by ID_PATT for the same pattern + d1(KPrintF("%s/%s/%ld: ID_TCOL scp=%08lx sac=%08lx\n", __FILE__, __FUNC__, __LINE__, scp, scp->ple_SAC)); + if (scp) + { + if (NULL == scp->ple_SAC) + { + // create preliminary SAC with sac_ColorTable + scp->ple_SAC = ScalosGfxCreateSAC(1, 1, 8, NULL, NULL); + } + d1(KPrintF("%s/%s/%ld: scp=%08lx sac=%08lx\n", __FILE__, __FUNC__, __LINE__, scp, scp->ple_SAC)); + if (scp->ple_SAC) + { + ULONG n; + LONG Length; + WORD NumColors; + UBYTE byteColorTable[3*256]; + + Length = sizeof(NumColors); + + if (Length != ReadChunkBytes(iff, &NumColors, Length)) + { + Result = IoErr(); + break; + } + + NumColors = SCA_BE2WORD(NumColors); + + d1(KPrintF("%s/%s/%ld: NumColors=%ld\n", __FILE__, __FUNC__, __LINE__, NumColors)); + Length = NumColors * 3; + if (Length != ReadChunkBytes(iff, byteColorTable, Length)) + { + Result = IoErr(); + break; + } + + for (n=0; n < NumColors * 3; n++) + { + UBYTE ch = byteColorTable[n]; + + scp->ple_SAC->sac_ColorTable[n] = (ch << 24) + (ch << 16) + (ch << 8) + ch; + d1(KPrintF("%s/%s/%ld: ColorTable[%ld]=%08lx\n", __FILE__, __FUNC__, __LINE__, n, scp->ple_SAC->sac_ColorTable[n])); + } + } + } + } + else if (ID_TBMP == cn->cn_ID) + { + // ID_TBMP must always be immediately preceeded by ID_PATT and ID_TCOL for the same pattern + d1(KPrintF("%s/%s/%ld: scp=%08lx sac=%08lx\n", __FILE__, __FUNC__, __LINE__, scp, scp->ple_SAC)); + if (scp) + { + Result = ReadPrefsBitMap(inst, iff, scp, &trp); + d1(KPrintF("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + if (RETURN_OK != Result) + break; + } + inst->ppb_BitMapsRead++; + } + } + + d1(kprintf("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + if (IFFERR_EOF == Result) + Result = RETURN_OK; + } while (0); + + if (iff) + { + if (iffOpened) + CloseIFF(iff); + + if (iff->iff_Stream) + Close((BPTR)iff->iff_Stream); + + FreeIFF(iff); + } + + if (RETURN_OK != Result && !Quiet) + { + char Buffer[120]; + + Fault(Result, "", Buffer, sizeof(Buffer) - 1); + + // MUI_RequestA() + MUI_Request(inst->ppb_Objects[OBJNDX_APP_Main], inst->ppb_Objects[OBJNDX_WIN_Main], 0, NULL, + GetLocString(MSGID_ABOUTREQOK), + GetLocString(MSGID_REQTITLE_READERROR), + Filename, + Buffer); + } + + if (trp.trp_rp.BitMap) + FreeBitMap(trp.trp_rp.BitMap); + + if (inst->ppb_UseThumbNails) + { + CreateThumbnailImages(inst); + } + + set(inst->ppb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, FALSE); + set(inst->ppb_Objects[OBJNDX_MainList], MUIA_NList_Quiet, MUIV_NList_Quiet_None); + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_Redraw, MUIV_NList_Redraw_All); + + d1(kprintf("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + + return Result; +} + + +static LONG ReadPrefsBitMap(struct PatternPrefsInst *inst, struct IFFHandle *iff, + struct PatternListEntry *scp, struct TempRastPort *trp) +{ + LONG Result = RETURN_OK; + struct ScalosBitMapAndColor *sac = NULL; + + do { + LONG Length; + struct RastPort rp; + struct ScaPatternPrefsBitMap spb; + + if (sizeof(spb) != ReadChunkBytes(iff, &spb, sizeof(spb))) + { + Result = IoErr(); + break; + } + + spb.spb_Width = SCA_BE2WORD(spb.spb_Width); + spb.spb_Height = SCA_BE2WORD(spb.spb_Height); + + d1(KPrintF("%s/%s/%ld: screen BitMap=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->ppb_WBScreen->RastPort.BitMap)); + + sac = ScalosGfxCreateSAC(spb.spb_Width, spb.spb_Height, + 8, /*inst->ppb_WBScreen->RastPort.BitMap*/ NULL, NULL); + d1(KPrintF("%s/%s/%ld: sac=%08lx\n", __FILE__, __FUNC__, __LINE__, sac)); + if (NULL == sac) + break; + + InitRastPort(&rp); + rp.BitMap = sac->sac_BitMap; + + if (NULL == trp->trp_rp.BitMap || trp->trp_Width != TEMPRP_WIDTH(spb.spb_Width)) + { + if (trp->trp_rp.BitMap) + FreeBitMap(trp->trp_rp.BitMap); + + trp->trp_Width = TEMPRP_WIDTH(spb.spb_Width); + trp->trp_rp.BitMap = AllocBitMap(trp->trp_Width, 1, 8, BMF_STANDARD, NULL); + if (NULL == trp->trp_rp.BitMap) + { + Result = ERROR_NO_FREE_STORE; + break; + } + } + + Length = PIXELARRAY8_BUFFERSIZE(spb.spb_Width, spb.spb_Height - 1); + + scp->ple_BitMapArray = malloc(Length); + if (NULL == scp->ple_BitMapArray) + { + Result = ERROR_NO_FREE_STORE; + break; + } + + if (Length != ReadChunkBytes(iff, scp->ple_BitMapArray, Length)) + { + Result = IoErr(); + break; + } + + // Blit image data to sac_BitMap + WritePixelArray8(&rp, 0, 0, + spb.spb_Width - 1, spb.spb_Height - 1, + scp->ple_BitMapArray, &trp->trp_rp); + + if (scp->ple_SAC) + { + size_t Length = scp->ple_SAC->sac_NumColors * 3 * sizeof(ULONG); + + // copy ColorTable from preliminary SAC + memcpy(sac->sac_ColorTable, scp->ple_SAC->sac_ColorTable, Length); + + // free preliminary SAC + ScalosGfxFreeSAC(scp->ple_SAC); + } + + scp->ple_SAC = sac; + sac = NULL; + } while (0); + + if (RETURN_OK != Result) + { + if (scp->ple_SAC) + { + ScalosGfxFreeSAC(scp->ple_SAC); + scp->ple_SAC = NULL; + } + } + if (sac) + ScalosGfxFreeSAC(sac); + + return Result; +} + +//---------------------------------------------------------------------------- + +static LONG WritePrefsFile(struct PatternPrefsInst *inst, CONST_STRPTR Filename) +{ + struct TempRastPort trp; + struct IFFHandle *iff; + LONG Result; + BOOL IffOpen = FALSE; + + d1(kprintf("%s/%s/%ld: inst=%08lx Filename=<%s>\n", __FILE__, __FUNC__, __LINE__, inst, Filename)); + + InitRastPort(&trp.trp_rp); + trp.trp_rp.BitMap = NULL; + trp.trp_rp.Layer = NULL; + trp.trp_Width = 0; + + do { + static const struct PrefHeader prefHeader = { 1, 0, 0L }; + struct ScaPatternDefs pDefs; + ULONG n, Value = 0; + + iff = AllocIFF(); + if (NULL == iff) + { + Result = IoErr(); + break; + } + + InitIFFasDOS(iff); + + iff->iff_Stream = (IPTR)Open(Filename, MODE_NEWFILE); + if (0 == iff->iff_Stream) + { + // ... try to create missing directories here + STRPTR FilenameCopy; + + Result = IoErr(); + d1(kprintf("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + + FilenameCopy = AllocVec(1 + strlen(Filename), MEMF_PUBLIC); + + if (FilenameCopy) + { + STRPTR lp; + + strcpy(FilenameCopy, Filename); + + lp = PathPart(FilenameCopy); + if (lp) + { + BPTR dirLock; + + *lp = '\0'; + dirLock = CreateDir(FilenameCopy); + + if (dirLock) + UnLock(dirLock); + + iff->iff_Stream = (IPTR)Open(Filename, MODE_NEWFILE); + if (0 == iff->iff_Stream) + Result = IoErr(); + else + Result = RETURN_OK; + } + + FreeVec(FilenameCopy); + } + + d1(kprintf("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + if (RETURN_OK != Result) + break; + } + + Result = OpenIFF(iff, IFFF_WRITE); + if (RETURN_OK != Result) + break; + + IffOpen = TRUE; + + Result = PushChunk(iff, ID_PREF, ID_FORM, IFFSIZE_UNKNOWN); + if (RETURN_OK != Result) + break; + + Result = PushChunk(iff, 0, ID_PRHD, IFFSIZE_UNKNOWN); + if (RETURN_OK != Result) + break; + + if (WriteChunkBytes(iff, (APTR) &prefHeader, sizeof(prefHeader)) < 0) + { + Result = IoErr(); + break; + } + + Result = PopChunk(iff); + if (RETURN_OK != Result) + break; + + Result = PushChunk(iff, 0, ID_DEFS, IFFSIZE_UNKNOWN); + if (RETURN_OK != Result) + break; + + pDefs.scd_Flags = 0; + memset(pDefs.scd_Reserved, 0, sizeof(pDefs.scd_Reserved)); + + get(inst->ppb_Objects[OBJNDX_CheckmarkAsync], MUIA_Selected, &Value); + if (Value) + pDefs.scd_Flags |= SCDF_ASYNCLAYOUT; + + get(inst->ppb_Objects[OBJNDX_CheckmarkFriend], MUIA_Selected, &Value); + if (Value) + pDefs.scd_Flags |= SCDF_USEFRIENDBM; + + get(inst->ppb_Objects[OBJNDX_CheckmarkRelayout], MUIA_Selected, &Value); + if (Value) + pDefs.scd_Flags |= SCDF_RELAYOUT; + + get(inst->ppb_Objects[OBJNDX_CheckmarkRandom], MUIA_Selected, &Value); + if (Value) + pDefs.scd_Flags |= SCDF_RANDOM; + + pDefs.scd_Flags = SCA_WORD2BE(pDefs.scd_Flags); + + get(inst->ppb_Objects[OBJNDX_SliderWB], MUIA_Numeric_Value, &Value); + pDefs.scd_WorkbenchPattern = SCA_WORD2BE(Value); + + get(inst->ppb_Objects[OBJNDX_SliderScreen], MUIA_Numeric_Value, &Value); + pDefs.scd_ScreenPattern = SCA_WORD2BE(Value); + + get(inst->ppb_Objects[OBJNDX_SliderWin], MUIA_Numeric_Value, &Value); + pDefs.scd_WindowPattern = SCA_WORD2BE(Value); + + get(inst->ppb_Objects[OBJNDX_SliderText], MUIA_Numeric_Value, &Value); + pDefs.scd_TextModePattern = SCA_WORD2BE(Value); + + get(inst->ppb_Objects[OBJNDX_SliderTaskPri], MUIA_Numeric_Value, &Value); + pDefs.scd_TaskPriority = Value; // BYTE + + if (WriteChunkBytes(iff, &pDefs, sizeof(pDefs)) != sizeof(pDefs)) + { + Result = IoErr(); + break; + } + + Result = PopChunk(iff); + if (RETURN_OK != Result) + break; + + n = 0; + while (RETURN_OK == Result) + { + size_t Length; + struct PatternListEntry *scp = NULL; + struct ScaExtPatternPrefs sepp; + + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_List_GetEntry, n, &scp); + if (NULL == scp) + break; + + Result = PushChunk(iff, 0, ID_PATT, IFFSIZE_UNKNOWN); + if (RETURN_OK != Result) + break; + + Length = offsetof(struct ScaExtPatternPrefs, scxp_Name) + strlen(scp->ple_PatternPrefs.scxp_Name) + 1; + + sepp = scp->ple_PatternPrefs; + + sepp.scxp_PatternPrefs.scp_Number = SCA_WORD2BE(sepp.scxp_PatternPrefs.scp_Number); + sepp.scxp_PatternPrefs.scp_RenderType = SCA_WORD2BE(sepp.scxp_PatternPrefs.scp_RenderType); + sepp.scxp_PatternPrefs.scp_Flags = SCA_WORD2BE(sepp.scxp_PatternPrefs.scp_Flags); + sepp.scxp_PatternPrefs.scp_NumColors = SCA_WORD2BE(sepp.scxp_PatternPrefs.scp_NumColors); + sepp.scxp_PatternPrefs.scp_DitherMode = SCA_WORD2BE(sepp.scxp_PatternPrefs.scp_DitherMode); + sepp.scxp_PatternPrefs.scp_DitherAmount = SCA_WORD2BE(sepp.scxp_PatternPrefs.scp_DitherAmount); + + if (WriteChunkBytes(iff, &sepp, Length) != Length) + { + Result = IoErr(); + break; + } + + Result = PopChunk(iff); + if (RETURN_OK != Result) + break; + + if (scp->ple_SAC) + { + if (scp->ple_SAC->sac_NumColors) + { + // Write Thumbnail color table + Result = WritePrefsColorTable(iff, scp); + if (RETURN_OK != Result) + break; + } + // Write Thumbnail BitMap + Result = WritePrefsBitMap(iff, scp, &trp); + if (RETURN_OK != Result) + break; + } + n++; + } + if (RETURN_OK != Result) + break; + + Result = PopChunk(iff); + if (RETURN_OK != Result) + break; + + } while (0); + + if (iff) + { + if (IffOpen) + CloseIFF(iff); + + if (iff->iff_Stream) + { + Close((BPTR)iff->iff_Stream); + iff->iff_Stream = 0; + } + + FreeIFF(iff); + } + + if (trp.trp_rp.BitMap) + FreeBitMap(trp.trp_rp.BitMap); + + if (RETURN_OK != Result) + { + char Buffer[120]; + + Fault(Result, "", Buffer, sizeof(Buffer) - 1); + + // MUI_RequestA() + MUI_Request(inst->ppb_Objects[OBJNDX_APP_Main], inst->ppb_Objects[OBJNDX_WIN_Main], 0, NULL, + GetLocString(MSGID_ABOUTREQOK), + GetLocString(MSGID_REQTITLE_SAVEERROR), + Filename, + Buffer); + } + + return Result; +} + + +static LONG WritePrefsColorTable(struct IFFHandle *iff, const struct PatternListEntry *scp) +{ + LONG Result; + + do { + UBYTE byteColorTable[3*256]; + LONG n, Length; + UWORD Value; + + Result = PushChunk(iff, 0, ID_TCOL, IFFSIZE_UNKNOWN); + if (RETURN_OK != Result) + break; + + Value = SCA_WORD2BE(scp->ple_SAC->sac_NumColors); + if (WriteChunkBytes(iff, &Value, sizeof(Value)) != sizeof(Value)) + { + Result = IoErr(); + break; + } + + for (n=0; n < 3 * scp->ple_SAC->sac_NumColors; n++) + { + byteColorTable[n] = (UBYTE) (scp->ple_SAC->sac_ColorTable[n] >> 24); + } + + Length = scp->ple_SAC->sac_NumColors * 3; + + if (WriteChunkBytes(iff, byteColorTable, Length) != Length) + { + Result = IoErr(); + break; + } + + Result = PopChunk(iff); + if (RETURN_OK != Result) + break; + } while (0); + + return Result; +} + + +static LONG WritePrefsBitMap(struct IFFHandle *iff, + const struct PatternListEntry *scp, struct TempRastPort *trp) +{ + LONG Result; + UBYTE *BitMapArray = NULL; + + do { + struct RastPort rp; + struct ScaPatternPrefsBitMap spb; + LONG Length; + size_t BitMapArrayLength; + + spb.spb_Width = scp->ple_SAC->sac_Width; + spb.spb_Height = scp->ple_SAC->sac_Height; + + InitRastPort(&rp); + rp.BitMap = scp->ple_SAC->sac_BitMap; + + if (NULL == trp->trp_rp.BitMap || trp->trp_Width != TEMPRP_WIDTH(spb.spb_Width)) + { + if (trp->trp_rp.BitMap) + FreeBitMap(trp->trp_rp.BitMap); + + trp->trp_Width = TEMPRP_WIDTH(spb.spb_Width); + trp->trp_rp.BitMap = AllocBitMap(trp->trp_Width, 1, 8, BMF_STANDARD, NULL); + if (NULL == trp->trp_rp.BitMap) + { + Result = ERROR_NO_FREE_STORE; + break; + } + } + + BitMapArrayLength = PIXELARRAY8_BUFFERSIZE(spb.spb_Width, spb.spb_Height - 1); + + BitMapArray = malloc(BitMapArrayLength); + if (NULL == BitMapArray) + { + Result = ERROR_NO_FREE_STORE; + break; + } + + ReadPixelArray8(&rp, 0, 0, + spb.spb_Width - 1, spb.spb_Height - 1, + BitMapArray, &trp->trp_rp); + + Result = PushChunk(iff, 0, ID_TBMP, IFFSIZE_UNKNOWN); + if (RETURN_OK != Result) + break; + + spb.spb_Width = SCA_WORD2BE(spb.spb_Width); + spb.spb_Height = SCA_WORD2BE(spb.spb_Height); + + Length = sizeof(struct ScaPatternPrefsBitMap); + + if (WriteChunkBytes(iff, &spb, Length) != Length) + { + Result = IoErr(); + break; + } + + if (WriteChunkBytes(iff, BitMapArray, BitMapArrayLength) != BitMapArrayLength) + { + Result = IoErr(); + break; + } + + Result = PopChunk(iff); + if (RETURN_OK != Result) + break; + } while (0); + + if (BitMapArray) + free(BitMapArray); + + return Result; +} + +//---------------------------------------------------------------------------- + +static LONG SaveIcon(struct PatternPrefsInst *inst, CONST_STRPTR IconName) +{ + struct DiskObject *icon, *allocIcon; + + static UBYTE ImageData[] = + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0x80, 0x00, 0x40, 0x00, 0x00, 0x00, 0x18, 0x00, 0x60, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x20, 0xFC, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x41, 0x02, 0x08, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x40, 0x82, 0x08, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x40, 0x82, 0x08, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x21, 0x04, 0x08, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x1E, 0x18, 0x10, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x20, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x02, 0x1C, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x0C, 0x00, + 0x40, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x0C, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, + 0xD5, 0x55, 0x55, 0x55, 0x55, 0x56, 0x00, 0x00, 0xD5, 0x55, 0x50, 0x00, 0x55, 0x55, 0x80, 0x00, + 0xD5, 0x55, 0x47, 0xFF, 0x95, 0x55, 0x60, 0x00, 0xD5, 0x55, 0x5F, 0x03, 0xE5, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x3E, 0x55, 0xF5, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x3F, 0x55, 0xF5, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x3F, 0x55, 0xF5, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x5E, 0x53, 0xF5, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x41, 0x47, 0xE5, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x55, 0x1F, 0xD5, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x55, 0x7F, 0x15, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x54, 0xFC, 0x55, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x55, 0xE1, 0x55, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x54, 0xF5, 0x55, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x55, 0x05, 0x55, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x54, 0xF5, 0x55, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x54, 0xF5, 0x55, 0x55, 0x50, 0x00, 0x35, 0x55, 0x55, 0x05, 0x55, 0x55, 0x50, 0x00, + 0x0D, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, 0x00, 0x03, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + static struct Image NormalImage = + { + 0, 0, 54, 23, + 2, + (UWORD *)ImageData, + 3, 0, + NULL + }; + + static STRPTR defToolTypes[] = + { + "ACTION=USE", + NULL + }; + + static struct DiskObject DefaultIcon = + { + WB_DISKMAGIC, WB_DISKVERSION, + + { + NULL, + 0, 0, 54, 24, + GFLG_GADGIMAGE | GFLG_GADGHBOX, + GACT_RELVERIFY | GACT_IMMEDIATE, + GTYP_BOOLGADGET, + &NormalImage, NULL, + NULL, + 0, + NULL, + 0, + NULL + }, + + WBPROJECT, + NULL, + defToolTypes, + NO_ICON_POSITION, NO_ICON_POSITION, + NULL, + NULL, + 32768 + }; + + icon = allocIcon = GetDiskObject("ENV:sys/def_ScaPatternPrefs"); + if (NULL == icon) + icon = allocIcon = GetDiskObject("ENV:sys/def_pref"); + if (NULL == icon) + icon = &DefaultIcon; + + if (icon) + { + STRPTR oldDefaultTool = icon->do_DefaultTool; + + icon->do_DefaultTool = (STRPTR) inst->ppb_ProgramName; + + PutDiskObject((STRPTR) IconName, icon); + + icon->do_DefaultTool = oldDefaultTool; + + if (allocIcon) + FreeDiskObject(allocIcon); + } + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT ListSelectEntryHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PatternPrefsInst *inst = (struct PatternPrefsInst *) hook->h_Data; + struct PatternListEntry *scp = NULL; + + inst->ppb_fDontChange = TRUE; + + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &scp); + if (scp) + { + set(inst->ppb_Objects[OBJNDX_DelButton], MUIA_Disabled, FALSE); + set(inst->ppb_Objects[OBJNDX_Group_String], MUIA_Disabled, FALSE); + + d1(kprintf("%s/%s/%ld: scp=%08lx type=%ld\n", __FILE__, __FUNC__, __LINE__, scp, scp->ple_PatternPrefs.scxp_PatternPrefs.scp_RenderType)); + + setcheckmark(inst->ppb_Objects[OBJNDX_CheckmarkGad], scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Flags & SCPF_NOREMAP); + setcheckmark(inst->ppb_Objects[OBJNDX_CheckmarkEnh], scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Flags & SCPF_ENHANCED); + setcheckmark(inst->ppb_Objects[OBJNDX_CheckmarkAutoDither], scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Flags & SCPF_AUTODITHER); + + setcycle(inst->ppb_Objects[OBJNDX_CyclePatternType], scp->ple_PatternPrefs.scxp_PatternPrefs.scp_RenderType); + set(inst->ppb_Objects[OBJNDX_NumButton], MUIA_Numeric_Value, scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Number); + + SetPrecision(inst, scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Precision); + + setslider(inst->ppb_Objects[OBJNDX_SliderColours], scp->ple_PatternPrefs.scxp_PatternPrefs.scp_NumColors); + setcycle(inst->ppb_Objects[OBJNDX_CycleDitherMode], scp->ple_PatternPrefs.scxp_PatternPrefs.scp_DitherMode); + set(inst->ppb_Objects[OBJNDX_SliderDitherAmount], MUIA_Numeric_Value, scp->ple_PatternPrefs.scxp_PatternPrefs.scp_DitherAmount); + + set(inst->ppb_Objects[OBJNDX_Group_Slider], MUIA_Disabled, scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Flags & SCPF_NOREMAP); + set(inst->ppb_Objects[OBJNDX_Group_Enhanced], MUIA_Disabled, !(scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Flags & SCPF_ENHANCED)); + set(inst->ppb_Objects[OBJNDX_Group_Preview], MUIA_Disabled, FALSE); + + set(inst->ppb_Objects[OBJNDX_STR_PopAsl], MUIA_String_Contents, (ULONG) scp->ple_PatternPrefs.scxp_Name); + + set(inst->ppb_Objects[OBJNDX_ColorAdjustBgColor1], MUIA_Coloradjust_Red, RGB_8_TO_32(scp->ple_PatternPrefs.scxp_PatternPrefs.scp_color1[0])); + set(inst->ppb_Objects[OBJNDX_ColorAdjustBgColor1], MUIA_Coloradjust_Green, RGB_8_TO_32(scp->ple_PatternPrefs.scxp_PatternPrefs.scp_color1[1])); + set(inst->ppb_Objects[OBJNDX_ColorAdjustBgColor1], MUIA_Coloradjust_Blue, RGB_8_TO_32(scp->ple_PatternPrefs.scxp_PatternPrefs.scp_color1[2])); + + set(inst->ppb_Objects[OBJNDX_ColorAdjustBgColor2], MUIA_Coloradjust_Red, RGB_8_TO_32(scp->ple_PatternPrefs.scxp_PatternPrefs.scp_color2[0])); + set(inst->ppb_Objects[OBJNDX_ColorAdjustBgColor2], MUIA_Coloradjust_Green, RGB_8_TO_32(scp->ple_PatternPrefs.scxp_PatternPrefs.scp_color2[1])); + set(inst->ppb_Objects[OBJNDX_ColorAdjustBgColor2], MUIA_Coloradjust_Blue, RGB_8_TO_32(scp->ple_PatternPrefs.scxp_PatternPrefs.scp_color2[2])); + + setcycle(inst->ppb_Objects[OBJNDX_CycleBackgroundType], scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Type); + + DisableBackgroundColorGadgets(inst, + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_RenderType, + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Type); + + if (inst->ppb_fPreview) + { + set(inst->ppb_Objects[OBJNDX_Group_Preview], MUIA_Disabled, FALSE); + + if (inst->ppb_fAutoPreview) + PreviewSelect(inst); + else + { + SetAttrs(inst->ppb_Objects[OBJNDX_PreviewImage], + MUIA_ScaDtpic_Name, "", + MUIA_ScaDtpic_Tiled, FALSE, + TAG_END); + set(inst->ppb_Objects[OBJNDX_Group_Preview], MUIA_Background, MUII_ButtonBack); + } + } + + } + else + { + set(inst->ppb_Objects[OBJNDX_DelButton], MUIA_Disabled, TRUE); + set(inst->ppb_Objects[OBJNDX_Group_String], MUIA_Disabled, TRUE); + set(inst->ppb_Objects[OBJNDX_Group_Slider], MUIA_Disabled, TRUE); + set(inst->ppb_Objects[OBJNDX_Group_Enhanced], MUIA_Disabled, TRUE); + set(inst->ppb_Objects[OBJNDX_Group_Preview], MUIA_Disabled, TRUE); + set(inst->ppb_Objects[OBJNDX_ColorAdjustBgColor1], MUIA_Disabled, TRUE); + set(inst->ppb_Objects[OBJNDX_ColorAdjustBgColor2], MUIA_Disabled, TRUE); + set(inst->ppb_Objects[OBJNDX_CycleBackgroundType], MUIA_Disabled, TRUE); + } + + inst->ppb_fDontChange = FALSE; +} + +//---------------------------------------------------------------------------- + +static void PreviewSelect(struct PatternPrefsInst *inst) +{ + struct PatternListEntry *scp = NULL; + + set(inst->ppb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, TRUE); + + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &scp); + if (scp) + { +// ULONG Value; +// ULONG DefsFlags = 0; +// +// get(inst->ppb_Objects[OBJNDX_CheckmarkFriend], MUIA_Selected, &Value); +// if (Value) +// DefsFlags |= SCDF_USEFRIENDBM; + + SetAttrs(inst->ppb_Objects[OBJNDX_PreviewImage], + MUIA_ScaDtpic_Name, scp->ple_PatternPrefs.scxp_Name, + MUIA_ScaDtpic_Tiled, SCP_RenderType_Tiled == scp->ple_PatternPrefs.scxp_PatternPrefs.scp_RenderType, + TAG_END); + } + + set(inst->ppb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, FALSE); +} + +//---------------------------------------------------------------------------- + +static BYTE PrecisionLookupTable[] = + { + PRECISION_EXACT, + PRECISION_IMAGE, + PRECISION_ICON, + PRECISION_GUI, + }; + +static void SetPrecision(struct PatternPrefsInst *inst, BYTE Precision) +{ + ULONG Value; + + inst->ppb_patternPrecision = Precision; + + for (Value=0; + PrecisionLookupTable[Value] != Precision + && Value < sizeof(PrecisionLookupTable)/sizeof(PrecisionLookupTable[0]); + Value++) + ; + + set(inst->ppb_Objects[OBJNDX_PrecSlider], MUIA_Numeric_Value, Value); +} + + +static BYTE GetPrecision(struct PatternPrefsInst *inst) +{ + ULONG Value = 0; + + get(inst->ppb_Objects[OBJNDX_PrecSlider], MUIA_Numeric_Value, &Value); + + return PrecisionLookupTable[Value]; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT ListChangeEntryHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PatternPrefsInst *inst = (struct PatternPrefsInst *) hook->h_Data; + + if (!inst->ppb_fDontChange) + { + struct PatternListEntry *scp = NULL; + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + SetChangedFlag(inst, TRUE); + + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &scp); + if (scp) + { + STRPTR String = NULL; + + get(inst->ppb_Objects[OBJNDX_STR_PopAsl], MUIA_String_Contents, &String); + if (NULL != String) + { + stccpy(scp->ple_PatternPrefs.scxp_Name, String, sizeof(scp->ple_PatternPrefs.scxp_Name)); + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + if (inst->ppb_UseThumbNails) + { + set(inst->ppb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, TRUE); + + // detach old image from nlist + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_UseImage, + inst->ppb_Objects[OBJNDX_EmptyThumbnailBitmap], scp->ple_ThumbnailImageNr, 0); + + d1(KPrintF("%s/%s/%ld: ImageNr=%ld\n", __FILE__, __FUNC__, __LINE__, scp->ple_ThumbnailImageNr)); + + // free old image + if (scp->ple_MUI_ImageObject) + { + MUI_DisposeObject(scp->ple_MUI_ImageObject); + scp->ple_MUI_ImageObject = NULL; + } + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + if (scp->ple_SAC) + { + ScalosGfxFreeSAC(scp->ple_SAC); + scp->ple_SAC = NULL; + } + + // create new image + CreateThumbnailImage(inst, scp); + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + set(inst->ppb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, FALSE); + } + + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_Redraw, MUIV_NList_Redraw_Active); + + if (inst->ppb_fAutoPreview) + PreviewSelect(inst); + } + } + } +} + +static SAVEDS(void) INTERRUPT ListChangeEntry2HookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PatternPrefsInst *inst = (struct PatternPrefsInst *) hook->h_Data; + + if (!inst->ppb_fDontChange) + { + struct PatternListEntry *scp = NULL; + + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &scp); + if (scp) + { + ULONG selected = 0; + ULONG Value = 0; + + d1(kprintf("%s/%s/%ld: \n")); + SetChangedFlag(inst, TRUE); + + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Flags = 0; + + get(inst->ppb_Objects[OBJNDX_CheckmarkGad], MUIA_Selected, &selected); + if (selected) + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Flags |= SCPF_NOREMAP; + + get(inst->ppb_Objects[OBJNDX_CheckmarkEnh], MUIA_Selected, &selected); + if (selected) + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Flags |= SCPF_ENHANCED; + + get(inst->ppb_Objects[OBJNDX_CheckmarkAutoDither], MUIA_Selected, &selected); + if (selected) + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Flags |= SCPF_AUTODITHER; + + get(inst->ppb_Objects[OBJNDX_CyclePatternType], MUIA_Cycle_Active, &Value); + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_RenderType = Value; + + d1(kprintf("%s/%s/%ld: scp=%08lx type=%ld\n", __FILE__, __FUNC__, __LINE__, scp, scp->ple_PatternPrefs.scxp_PatternPrefs.scp_RenderType)); + + get(inst->ppb_Objects[OBJNDX_CycleDitherMode], MUIA_Cycle_Active, &selected); + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_DitherMode = selected; + + get(inst->ppb_Objects[OBJNDX_SliderColours], MUIA_Numeric_Value, &selected); + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_NumColors = selected; + + get(inst->ppb_Objects[OBJNDX_SliderDitherAmount], MUIA_Numeric_Value, &selected); + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_DitherAmount = selected; + + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Precision = GetPrecision(inst); + + set(inst->ppb_Objects[OBJNDX_Group_Slider], MUIA_Disabled, scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Flags & SCPF_NOREMAP); + set(inst->ppb_Objects[OBJNDX_Group_Enhanced], MUIA_Disabled, !(scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Flags & SCPF_ENHANCED)); + + get(inst->ppb_Objects[OBJNDX_CycleBackgroundType], MUIA_Cycle_Active, &Value); + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Type = Value; + + get(inst->ppb_Objects[OBJNDX_ColorAdjustBgColor1], MUIA_Coloradjust_Red, &Value); + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_color1[0] = Value >> 24; + get(inst->ppb_Objects[OBJNDX_ColorAdjustBgColor1], MUIA_Coloradjust_Green, &Value); + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_color1[1] = Value >> 24; + get(inst->ppb_Objects[OBJNDX_ColorAdjustBgColor1], MUIA_Coloradjust_Blue, &Value); + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_color1[2] = Value >> 24; + + get(inst->ppb_Objects[OBJNDX_ColorAdjustBgColor2], MUIA_Coloradjust_Red, &Value); + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_color2[0] = Value >> 24; + get(inst->ppb_Objects[OBJNDX_ColorAdjustBgColor2], MUIA_Coloradjust_Green, &Value); + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_color2[1] = Value >> 24; + get(inst->ppb_Objects[OBJNDX_ColorAdjustBgColor2], MUIA_Coloradjust_Blue, &Value); + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_color2[2] = Value >> 24; + + DisableBackgroundColorGadgets(inst, + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_RenderType, + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Type); + } + } +} + +static SAVEDS(void) INTERRUPT ListChangeEntry3HookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PatternPrefsInst *inst = (struct PatternPrefsInst *) hook->h_Data; + + if (!inst->ppb_fDontChange) + { + struct PatternListEntry *scp = NULL; + + d1(kprintf("%s/%s/%ld: \n")); + SetChangedFlag(inst, TRUE); + + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &scp); + if (scp) + { + ULONG Value = 0; + + get(inst->ppb_Objects[OBJNDX_NumButton], MUIA_Numeric_Value, &Value); + + if (0 != Value) + { + scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Number = Value; + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_Redraw, MUIV_NList_Redraw_Active); + } + } + } +} + + +static SAVEDS(void) INTERRUPT AddNewEntryHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PatternPrefsInst *inst = (struct PatternPrefsInst *) hook->h_Data; + + d1(kprintf("%s/%s/%ld: \n")); + SetChangedFlag(inst, TRUE); + + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_InsertSingle, "SYS:Prefs/Patterns", MUIV_NList_Insert_Bottom); + set(inst->ppb_Objects[OBJNDX_MainList], MUIA_NList_Active, MUIV_NList_Active_Bottom); + + DoMethod(inst->ppb_Objects[OBJNDX_Popasl], MUIM_Popstring_Open); +} + + +static SAVEDS(void) INTERRUPT RemEntryHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PatternPrefsInst *inst = (struct PatternPrefsInst *) hook->h_Data; + + d1(kprintf("%s/%s/%ld: \n")); + SetChangedFlag(inst, TRUE); + + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_Remove, MUIV_NList_Remove_Active); +} + + +static SAVEDS(void) INTERRUPT AppMsgInMainListHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PatternPrefsInst *inst = (struct PatternPrefsInst *) hook->h_Data; + struct AppMessage *AppMsg = *((struct AppMessage **) msg); + ULONG n; + + for (n=0; nam_NumArgs; n++) + { + char Path[MAX_FILENAME]; + + if (NameFromLock(AppMsg->am_ArgList[n].wa_Lock, Path, sizeof(Path)) + && AddPart(Path, AppMsg->am_ArgList[n].wa_Name, sizeof(Path))) + { + DoMethod(inst->ppb_Objects[OBJNDX_MainList], + MUIM_NList_InsertSingle, Path, MUIV_NList_Insert_Bottom); + + set(inst->ppb_Objects[OBJNDX_MainList], MUIA_NList_Active, MUIV_NList_Active_Bottom); + + // create thumbnail for the new entry + CallHookPkt(&inst->ppb_Hooks[HOOKNDX_ListChangeEntry], NULL, NULL); + } + } + + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_Sort); + + d1(kprintf("%s/%s/%ld: \n")); + SetChangedFlag(inst, TRUE); +} + + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT LastSavedHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PatternPrefsInst *inst = (struct PatternPrefsInst *) hook->h_Data; + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + inst->ppb_ThumbnailImageNumber = 0; + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_Clear); + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + ReadPrefsFile(inst, "ENVARC:Scalos/Pattern.prefs", FALSE); + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + SetChangedFlag(inst, TRUE); +} + + +static SAVEDS(void) INTERRUPT RestoreHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PatternPrefsInst *inst = (struct PatternPrefsInst *) hook->h_Data; + + inst->ppb_ThumbnailImageNumber = 0; + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_Clear); + + ReadPrefsFile(inst, "ENV:Scalos/Pattern.prefs", FALSE); + d1(kprintf("%s/%s/%ld: \n")); + SetChangedFlag(inst, TRUE); +} + + +static SAVEDS(void) INTERRUPT ResetToDefaultsHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PatternPrefsInst *inst = (struct PatternPrefsInst *) hook->h_Data; + ULONG n; + static const struct ScaExtPatternPrefs DefaultPrefs[] = + { + { + { + 1, + SCP_RenderType_Tiled, + SCPF_ENHANCED, + 100, + DITHERMODE_FS, + 1, + PRECISION_IMAGE, + SCP_BgType_Picture, + }, + "THEME:Desktop/Background", + }, + { + { + 3, + SCP_RenderType_Tiled, + SCPF_ENHANCED, + 100, + DITHERMODE_FS, + 1, + PRECISION_IMAGE, + SCP_BgType_Picture, + }, + "THEME:Window/Background" + }, + { + { + 4, + SCP_RenderType_Tiled, + SCPF_ENHANCED, + 100, + DITHERMODE_FS, + 1, + PRECISION_IMAGE, + SCP_BgType_Picture, + }, + "THEME:Window/TextBackground" + }, + }; + + inst->ppb_ThumbnailImageNumber = 0; + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_Clear); + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + set(inst->ppb_Objects[OBJNDX_CheckmarkAsync], MUIA_Selected, TRUE); + set(inst->ppb_Objects[OBJNDX_CheckmarkFriend], MUIA_Selected, TRUE); + set(inst->ppb_Objects[OBJNDX_CheckmarkRelayout], MUIA_Selected, TRUE); + set(inst->ppb_Objects[OBJNDX_CheckmarkRandom], MUIA_Selected, TRUE); + set(inst->ppb_Objects[OBJNDX_SliderWB], MUIA_Numeric_Value, 1); + set(inst->ppb_Objects[OBJNDX_SliderScreen], MUIA_Numeric_Value, 0); + set(inst->ppb_Objects[OBJNDX_SliderWin], MUIA_Numeric_Value, 3); + set(inst->ppb_Objects[OBJNDX_SliderText], MUIA_Numeric_Value, 4); + set(inst->ppb_Objects[OBJNDX_SliderTaskPri], MUIA_Numeric_Value, -1); + + set(inst->ppb_Objects[OBJNDX_MainList], MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + + for (n = 0; n < Sizeof(DefaultPrefs); n++) + { + struct PatternListEntry *scp; + + DoMethod(inst->ppb_Objects[OBJNDX_MainList], + MUIM_NList_InsertSingle, DefaultPrefs[n].scxp_Name, MUIV_NList_Insert_Bottom); + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_GetEntry, n, &scp); + + scp->ple_PatternPrefs.scxp_PatternPrefs = DefaultPrefs[n].scxp_PatternPrefs; + } + + // Entries have been added unsorted. + // now sort listview according to current sorting type + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_Sort); + + set(inst->ppb_Objects[OBJNDX_MainList], MUIA_NList_Quiet, FALSE); + + if (inst->ppb_UseThumbNails) + CreateThumbnailImages(inst); + + SetChangedFlag(inst, TRUE); +} + + +static SAVEDS(APTR) INTERRUPT AboutHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PatternPrefsInst *inst = (struct PatternPrefsInst *) hook->h_Data; + + MUI_Request(inst->ppb_Objects[OBJNDX_APP_Main], inst->ppb_Objects[OBJNDX_WIN_Main], 0, NULL, + GetLocString(MSGID_ABOUTREQOK), + GetLocString(MSGID_ABOUTREQFORMAT), + MajorVersion, MinorVersion, COMPILER_STRING, CURRENTYEAR); + + return 0; +} + + +static SAVEDS(APTR) INTERRUPT OpenHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PatternPrefsInst *inst = (struct PatternPrefsInst *) hook->h_Data; + + if (NULL == inst->ppb_LoadReq) + { + inst->ppb_LoadReq = MUI_AllocAslRequestTags(ASL_FileRequest, + ASLFR_InitialFile, "Pattern.pre", + ASLFR_Flags1, FRF_DOPATTERNS, + ASLFR_InitialDrawer, "SYS:Prefs/presets", + ASLFR_InitialPattern, "#?.(pre|prefs)", + ASLFR_UserData, inst, + ASLFR_IntuiMsgFunc, &inst->ppb_Hooks[HOOKNDX_AslIntuiMsg], + TAG_END); + } + + if (inst->ppb_LoadReq) + { + BOOL Result; + struct Window *win = NULL; + + get(inst->ppb_Objects[OBJNDX_WIN_Main], MUIA_Window_Window, &win); + + //AslRequest( + Result = MUI_AslRequestTags(inst->ppb_LoadReq, + ASLFR_Window, win, + ASLFR_SleepWindow, TRUE, + ASLFR_TitleText, GetLocString(MSGID_MENU_PROJECT_OPEN), + TAG_END); + + if (Result) + { + BPTR dirLock = Lock(inst->ppb_LoadReq->fr_Drawer, ACCESS_READ); + + if (dirLock) + { + BPTR oldDir = CurrentDir(dirLock); + + inst->ppb_ThumbnailImageNumber = 0; + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_Clear); + + ReadPrefsFile(inst, inst->ppb_LoadReq->fr_File, FALSE); + + CurrentDir(oldDir); + UnLock(dirLock); + } + } + } + + return 0; +} + + +static SAVEDS(APTR) INTERRUPT SaveAsHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PatternPrefsInst *inst = (struct PatternPrefsInst *) hook->h_Data; + + if (NULL == inst->ppb_SaveReq) + { + inst->ppb_SaveReq = MUI_AllocAslRequestTags(ASL_FileRequest, + ASLFR_InitialFile, "Pattern.pre", + ASLFR_DoSaveMode, TRUE, + ASLFR_InitialDrawer, "SYS:Prefs/presets", + ASLFR_UserData, inst, + ASLFR_IntuiMsgFunc, &inst->ppb_Hooks[HOOKNDX_AslIntuiMsg], + TAG_END); + } + + if (inst->ppb_SaveReq) + { + BOOL Result; + struct Window *win = NULL; + + get(inst->ppb_Objects[OBJNDX_WIN_Main], MUIA_Window_Window, &win); + + //AslRequest( + Result = MUI_AslRequestTags(inst->ppb_SaveReq, + ASLFR_TitleText, GetLocString(MSGID_MENU_PROJECT_SAVEAS), + ASLFR_Window, win, + ASLFR_SleepWindow, TRUE, + TAG_END); + + if (Result) + { + BPTR dirLock = Lock(inst->ppb_SaveReq->fr_Drawer, ACCESS_READ); + + if (dirLock) + { + LONG Result; + BPTR oldDir = CurrentDir(dirLock); + + Result = WritePrefsFile(inst, inst->ppb_SaveReq->fr_File); + + if (RETURN_OK == Result) + { + if (inst->ppb_fCreateIcons) + SaveIcon(inst, inst->ppb_SaveReq->fr_File); + } + + CurrentDir(oldDir); + UnLock(dirLock); + } + } + } + + return 0; +} + + +static SAVEDS(APTR) INTERRUPT PreviewSelectHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PatternPrefsInst *inst = (struct PatternPrefsInst *) hook->h_Data; + + PreviewSelect(inst); + + return 0; +} + +static SAVEDS(APTR) INTERRUPT ContextMenuTriggerHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PatternPrefsInst *inst = (struct PatternPrefsInst *) hook->h_Data; + Object *MenuObj = *((Object **) msg); + ULONG MenuHookIndex = 0; + struct Hook *MenuHook = NULL; + + d1(kprintf(__FUNC__ "/%ld: MenuObj=%08lx\n", __FILE__, __FUNC__, __LINE__, MenuObj)); + d1(kprintf(__FUNC__ "/%ld: msg=%08lx *msg=%08lx\n", __FILE__, __FUNC__, __LINE__, msg, *((ULONG *) msg))); + + get(MenuObj, MUIA_UserData, &MenuHookIndex); + + if (MenuHookIndex > 0 && MenuHookIndex < HOOKNDX_MAX) + MenuHook = &inst->ppb_Hooks[MenuHookIndex]; + + d1(kprintf(__FUNC__ "/%ld: MenuHook=%08lx\n", __FILE__, __FUNC__, __LINE__, MenuHook)); + if (MenuHook) + DoMethod(inst->ppb_Objects[OBJNDX_Group_Main], MUIM_CallHook, MenuHook, MenuObj); + + return NULL; +} + + +static SAVEDS(APTR) INTERRUPT ShowPreviewHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PatternPrefsInst *inst = (struct PatternPrefsInst *) hook->h_Data; + Object *MenuObj = *((Object **) msg); + ULONG Checked = FALSE; + + get(MenuObj, MUIA_Menuitem_Checked, &Checked); + inst->ppb_fPreview = Checked; + + set(inst->ppb_Objects[OBJNDX_Balance], MUIA_ShowMe, inst->ppb_fPreview); + set(inst->ppb_Objects[OBJNDX_Group_Preview], MUIA_ShowMe, inst->ppb_fPreview); + + if (!inst->ppb_fPreview) + { + inst->ppb_fAutoPreview = FALSE; + set(inst->ppb_Objects[OBJNDX_Menu_AutoPreview], MUIA_Menuitem_Checked, inst->ppb_fAutoPreview); + } + + set(inst->ppb_Objects[OBJNDX_Menu_AutoPreview], MUIA_Menuitem_Enabled, inst->ppb_fPreview); + + return NULL; +} + +static SAVEDS(APTR) INTERRUPT AutoPreviewHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PatternPrefsInst *inst = (struct PatternPrefsInst *) hook->h_Data; + Object *MenuObj = *((Object **) msg); + ULONG Checked = FALSE; + + get(MenuObj, MUIA_Menuitem_Checked, &Checked); + inst->ppb_fAutoPreview = Checked; + + return NULL; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT ThumbnailsHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PatternPrefsInst *inst = (struct PatternPrefsInst *) hook->h_Data; + Object *MenuObj = *((Object **) msg); + ULONG Checked = FALSE; + + get(MenuObj, MUIA_Menuitem_Checked, &Checked); + inst->ppb_UseThumbNails = Checked; + + UpdateUseThumbnails(inst); + + if (inst->ppb_UseThumbNails) + { + CreateThumbnailImages(inst); + } + else + { + RemoveThumbnailImages(inst); + } + + return NULL; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT SettingsChangedHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PatternPrefsInst *inst = (struct PatternPrefsInst *) hook->h_Data; + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + SetChangedFlag(inst, TRUE); + + return NULL; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT DesktopPatternChangedHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PatternPrefsInst *inst = (struct PatternPrefsInst *) hook->h_Data; + ULONG Pattern = 0; + ULONG n, nEntries = 0; + BOOL Found; + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + get(inst->ppb_Objects[OBJNDX_SliderWB], MUIA_Numeric_Value, &Pattern); + get(inst->ppb_Objects[OBJNDX_MainList], MUIA_NList_Entries, &nEntries); + + d1(KPrintF("%s/%s/%ld: Pattern=%lu Entries=%lu\n", __FILE__, __FUNC__, __LINE__, Pattern, nEntries)); + + for (Found = FALSE, n = 0; !Found && n < nEntries; n++) + { + struct PatternListEntry *scp = NULL; + + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_GetEntry, n, &scp); + + if (scp && scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Number == Pattern + && scp->ple_MUI_ImageObject) + { + d1(KPrintF("%s/%s/%ld: BitMapObject=%08lx\n", __FILE__, __FUNC__, __LINE__, scp->ple_MUI_ImageObject)); + Found = TRUE; + set(inst->ppb_Objects[OBJNDX_Image_DesktopPattern], + BFA_BitmapObject, scp->ple_MUI_ImageObject); + } + } + + if (!Found) + { + set(inst->ppb_Objects[OBJNDX_Image_DesktopPattern], + BFA_BitmapObject, inst->ppb_Objects[OBJNDX_EmptyThumbnailBitmap]); + } +} + +static SAVEDS(void) INTERRUPT ScreenPatternChangedHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PatternPrefsInst *inst = (struct PatternPrefsInst *) hook->h_Data; + ULONG Pattern = 0; + ULONG n, nEntries = 0; + BOOL Found; + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + get(inst->ppb_Objects[OBJNDX_SliderScreen], MUIA_Numeric_Value, &Pattern); + get(inst->ppb_Objects[OBJNDX_MainList], MUIA_NList_Entries, &nEntries); + + d1(KPrintF("%s/%s/%ld: Pattern=%lu Entries=%lu\n", __FILE__, __FUNC__, __LINE__, Pattern, nEntries)); + + for (Found = FALSE, n = 0; !Found && n < nEntries; n++) + { + struct PatternListEntry *scp = NULL; + + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_GetEntry, n, &scp); + + if (scp && scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Number == Pattern + && scp->ple_MUI_ImageObject) + { + d1(KPrintF("%s/%s/%ld: BitMapObject=%08lx\n", __FILE__, __FUNC__, __LINE__, scp->ple_MUI_ImageObject)); + Found = TRUE; + set(inst->ppb_Objects[OBJNDX_Image_ScreenPattern], + BFA_BitmapObject, scp->ple_MUI_ImageObject); + } + } + + if (!Found) + { + set(inst->ppb_Objects[OBJNDX_Image_ScreenPattern], + BFA_BitmapObject, inst->ppb_Objects[OBJNDX_EmptyThumbnailBitmap]); + } +} + +static SAVEDS(void) INTERRUPT IconWindowPatternChangedHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PatternPrefsInst *inst = (struct PatternPrefsInst *) hook->h_Data; + ULONG Pattern = 0; + ULONG n, nEntries = 0; + BOOL Found; + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + get(inst->ppb_Objects[OBJNDX_SliderWin], MUIA_Numeric_Value, &Pattern); + get(inst->ppb_Objects[OBJNDX_MainList], MUIA_NList_Entries, &nEntries); + + d1(KPrintF("%s/%s/%ld: Pattern=%lu Entries=%lu\n", __FILE__, __FUNC__, __LINE__, Pattern, nEntries)); + + for (Found = FALSE, n = 0; !Found && n < nEntries; n++) + { + struct PatternListEntry *scp = NULL; + + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_GetEntry, n, &scp); + + if (scp && scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Number == Pattern + && scp->ple_MUI_ImageObject) + { + d1(KPrintF("%s/%s/%ld: BitMapObject=%08lx\n", __FILE__, __FUNC__, __LINE__, scp->ple_MUI_ImageObject)); + Found = TRUE; + set(inst->ppb_Objects[OBJNDX_Image_IconWindowPattern], + BFA_BitmapObject, scp->ple_MUI_ImageObject); + } + } + + if (!Found) + { + set(inst->ppb_Objects[OBJNDX_Image_IconWindowPattern], + BFA_BitmapObject, inst->ppb_Objects[OBJNDX_EmptyThumbnailBitmap]); + } +} + +static SAVEDS(void) INTERRUPT TextWindowPatternChangedHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PatternPrefsInst *inst = (struct PatternPrefsInst *) hook->h_Data; + ULONG Pattern = 0; + ULONG n, nEntries = 0; + BOOL Found; + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + get(inst->ppb_Objects[OBJNDX_SliderText], MUIA_Numeric_Value, &Pattern); + get(inst->ppb_Objects[OBJNDX_MainList], MUIA_NList_Entries, &nEntries); + + d1(KPrintF("%s/%s/%ld: Pattern=%lu Entries=%lu\n", __FILE__, __FUNC__, __LINE__, Pattern, nEntries)); + + for (Found = FALSE, n = 0; !Found && n < nEntries; n++) + { + struct PatternListEntry *scp = NULL; + + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_GetEntry, n, &scp); + + if (scp && scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Number == Pattern + && scp->ple_MUI_ImageObject) + { + d1(KPrintF("%s/%s/%ld: BitMapObject=%08lx\n", __FILE__, __FUNC__, __LINE__, scp->ple_MUI_ImageObject)); + Found = TRUE; + set(inst->ppb_Objects[OBJNDX_Image_TextWindowPattern], + BFA_BitmapObject, scp->ple_MUI_ImageObject); + } + } + + if (!Found) + { + set(inst->ppb_Objects[OBJNDX_Image_TextWindowPattern], + BFA_BitmapObject, inst->ppb_Objects[OBJNDX_EmptyThumbnailBitmap]); + } +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT AslIntuiMsgHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PatternPrefsInst *inst = (struct PatternPrefsInst *) hook->h_Data; + struct IntuiMessage *iMsg = (struct IntuiMessage *) msg; + + if (IDCMP_REFRESHWINDOW == iMsg->Class) + { + DoMethod(inst->ppb_Objects[OBJNDX_APP_Main], MUIM_Application_CheckRefresh); + } +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT ReloadThumbnailsHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PatternPrefsInst *inst = (struct PatternPrefsInst *) hook->h_Data; + ULONG n, nEntries = 0; + + set(inst->ppb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, TRUE); + get(inst->ppb_Objects[OBJNDX_MainList], MUIA_NList_Entries, &nEntries); + + SetChangedFlag(inst, TRUE); + + for (n = 0; n < nEntries; n++) + { + struct PatternListEntry *scp = NULL; + + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_GetEntry, n, &scp); + + if (scp) + { + d1(KPrintF("%s/%s/%ld: scp=%08lx ple_SAC=%08lx scp_Number=%lu\n", __FILE__, __FUNC__, __LINE__, \ + scp, scp->ple_SAC, scp->ple_PatternPrefs.scxp_PatternPrefs.scp_Number)); + if (scp->ple_SAC) + { + // delete thumbnail information + ScalosGfxFreeSAC(scp->ple_SAC); + scp->ple_SAC = NULL; + } + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + } + } + + CreateThumbnailImages(inst); + + set(inst->ppb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, FALSE); +} + +//---------------------------------------------------------------------------- + +static Object *CreateEmptyThumbnailImage(struct PatternPrefsInst *inst) +{ + static const ULONG ThumbnailImageColors[] = + { + 0xaaaaaaaa,0xaaaaaaaa,0xa0a0a0a0, + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, + 0x66666666,0x88888888,0xbbbbbbbb, + 0x99999999,0x99999999,0x99999999, + 0xbbbbbbbb,0xbbbbbbbb,0xbbbbbbbb, + 0xbbbbbbbb,0xaaaaaaaa,0x99999999, + 0xffffffff,0xbbbbbbbb,0xaaaaaaaa + }; + struct RastPort rp; + struct BitMap *bm; + Object *BitMapObj = NULL; + + rp.BitMap = NULL; + InitRastPort(&rp); + + do { + bm = rp.BitMap = AllocBitMap(inst->ppb_ThumbnailWidth, inst->ppb_ThumbnailHeight, 2, BMF_CLEAR, NULL); + d1(kprintf("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, bm)); + if (NULL == bm) + break; + + SetRast(&rp, 0); + SetAPen(&rp, 1); + + Move(&rp, 0, 0); + Draw(&rp, 0, inst->ppb_ThumbnailHeight - 1); + Draw(&rp, inst->ppb_ThumbnailWidth - 1, inst->ppb_ThumbnailHeight - 1); + Draw(&rp, inst->ppb_ThumbnailWidth - 1, 0); + Draw(&rp, 0, 0); + + Move(&rp, 0, 0); + Draw(&rp, inst->ppb_ThumbnailWidth - 1, inst->ppb_ThumbnailHeight - 1); + + Move(&rp, 0, inst->ppb_ThumbnailHeight - 1); + Draw(&rp, inst->ppb_ThumbnailWidth - 1, 0); + + BitMapObj = BitmapObject, + MUIA_Bitmap_Width, inst->ppb_ThumbnailWidth, + MUIA_Bitmap_Height, inst->ppb_ThumbnailHeight, + MUIA_Bitmap_Bitmap, (IPTR)bm, + MUIA_Bitmap_Transparent, 0, + MUIA_Bitmap_UseFriend, TRUE, + MUIA_Bitmap_Precision, PRECISION_ICON, + MUIA_Bitmap_SourceColors, (IPTR)ThumbnailImageColors, + End; + + d1(kprintf("%s/%s/%ld: BitMapObj=%08lx\n", __FILE__, __FUNC__, __LINE__, BitMapObj)); + + if (BitMapObj) + bm = NULL; // don't free bm + } while (0); + + if (bm) + FreeBitMap(bm); + + return BitMapObj; +} + +//---------------------------------------------------------------------------- + +static void RemoveThumbnailImages(struct PatternPrefsInst *inst) +{ + set(inst->ppb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, TRUE); + set(inst->ppb_Objects[OBJNDX_MainList], MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + + DoMethod(inst->ppb_Objects[OBJNDX_MainList], + MUIM_NList_UseImage, NULL, MUIV_NList_UseImage_All, 0); + + set(inst->ppb_Objects[OBJNDX_MainList], MUIA_NList_Quiet, MUIV_NList_Quiet_None); + set(inst->ppb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, FALSE); +} + +//---------------------------------------------------------------------------- + +static void CreateThumbnailImages(struct PatternPrefsInst *inst) +{ + T_TIMEVAL tvNow; + T_TIMEVAL tvStart; + ULONG n, nEntries = 0; + APTR prWindowPtr; + struct Process *MyProcess = (struct Process *) FindTask(NULL); + + prWindowPtr = MyProcess->pr_WindowPtr; + MyProcess->pr_WindowPtr = (APTR) ~0; // suppress error requesters + + set(inst->ppb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, TRUE); + + get(inst->ppb_Objects[OBJNDX_MainList], MUIA_NList_Entries, &nEntries); + set(inst->ppb_Objects[OBJNDX_MainList], MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + + for (n = 0; n < nEntries; n++) + { + struct PatternListEntry *scp = NULL; + + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_GetEntry, n, &scp); + + if (scp) + { + // replace image by empty thumbnail + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_UseImage, + inst->ppb_Objects[OBJNDX_EmptyThumbnailBitmap], + scp->ple_ThumbnailImageNr, 0); + + if (scp->ple_MUI_ImageObject) + { + MUI_DisposeObject(scp->ple_MUI_ImageObject); + scp->ple_MUI_ImageObject = NULL; + } + } + } + + inst->ppb_ThumbnailImageNumber = 0; + + // for performance reasons, GaugeProgress and TextMsgProgress + // are updated no faster than every 100ms + GetSysTime(&tvStart); + tvNow.tv_secs = 0; + tvNow.tv_micro = 100000; + AddTime(&tvStart, &tvNow); // +100ms + + set(inst->ppb_Objects[OBJNDX_MsgGauge], MUIA_Gauge_Max, nEntries); + + for (n = 0; n < nEntries; n++) + { + struct PatternListEntry *scp = NULL; + + DoMethod(inst->ppb_Objects[OBJNDX_APP_Main], MUIM_Application_InputBuffered); + + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_GetEntry, n, &scp); + + if (scp) + { + if (inst->ppb_UseSplashWindow) + { + GetSysTime(&tvNow); + + if (CmpTime(&tvStart, &tvNow) > 0) + { + // it's more than 100ms since initial start + ULONG WindowIsOpen = 0; + char TextLine[50]; + + tvNow.tv_secs = 0; + tvNow.tv_micro = 100000; + AddTime(&tvStart, &tvNow); // +100ms + + // make sure the progress display window is open + get(inst->ppb_Objects[OBJNDX_WIN_Message], MUIA_Window_Open, &WindowIsOpen); + if (!WindowIsOpen) + { + set(inst->ppb_Objects[OBJNDX_WIN_Message], MUIA_Window_Open, TRUE); + } + + set(inst->ppb_Objects[OBJNDX_MsgText1], MUIA_Text_Contents, + (ULONG) GetLocString(scp->ple_SAC ? MSGID_LOADING_THUMBNAIL : MSGID_CREATING_THUMBNAIL)); + set(inst->ppb_Objects[OBJNDX_MsgText2], MUIA_Text_Contents, (ULONG) scp->ple_PatternPrefs.scxp_Name); + + sprintf(TextLine, GetLocString(MSGID_PROGRESS_THUMBNAILS), n, nEntries); + set(inst->ppb_Objects[OBJNDX_MsgGauge], MUIA_Gauge_Current, n); + set(inst->ppb_Objects[OBJNDX_MsgGauge], MUIA_Gauge_InfoText, (ULONG) TextLine); + } + } + + CreateThumbnailImage(inst, scp); + } + } + + set(inst->ppb_Objects[OBJNDX_MainList], MUIA_NList_Quiet, MUIV_NList_Quiet_None); + + // Update pattern preview images + CallHookPkt(&inst->ppb_Hooks[HOOKNDX_DesktopPatternChanged], + inst->ppb_Objects[OBJNDX_Image_DesktopPattern], + NULL); + CallHookPkt(&inst->ppb_Hooks[HOOKNDX_ScreenPatternChanged], + inst->ppb_Objects[OBJNDX_Image_ScreenPattern], + NULL); + CallHookPkt(&inst->ppb_Hooks[HOOKNDX_IconWindowPatternChanged], + inst->ppb_Objects[OBJNDX_Image_IconWindowPattern], + NULL); + CallHookPkt(&inst->ppb_Hooks[HOOKNDX_TextWindowPatternChanged], + inst->ppb_Objects[OBJNDX_Image_TextWindowPattern], + NULL); + + set(inst->ppb_Objects[OBJNDX_WIN_Message], MUIA_Window_Open, FALSE); + set(inst->ppb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, FALSE); + + // restore pr_WindowPtr + MyProcess->pr_WindowPtr = prWindowPtr; +} + +//---------------------------------------------------------------------------- + +static void CreateThumbnailImage(struct PatternPrefsInst *inst, struct PatternListEntry *scp) +{ + Object *obj = NULL; + struct RastPort rp; + + rp.BitMap = NULL; + InitRastPort(&rp); + + do { + d1(KPrintF("%s/%s/%ld: ple_MUI_ImageObject=%08lx\n", __FILE__, __FUNC__, __LINE__, scp->ple_MUI_ImageObject)); + d1(KPrintF("%s/%s/%ld: Name=<%s>\n", __FILE__, __FUNC__, __LINE__, scp->ple_PatternPrefs.scxp_Name)); + + if (scp->ple_SAC) + { + // check if named image exists + BPTR fLock; + + fLock = Lock(scp->ple_PatternPrefs.scxp_Name, ACCESS_READ); + d1(KPrintF("%s/%s/%ld: fLock=%08lx\n", __FILE__, __FUNC__, __LINE__, fLock)); + if (fLock) + { + UnLock(fLock); + } + else + { + if (scp->ple_MUI_ImageObject) + { + MUI_DisposeObject(scp->ple_MUI_ImageObject); + scp->ple_MUI_ImageObject = NULL; + } + if (scp->ple_SAC) + { + ScalosGfxFreeSAC(scp->ple_SAC); + scp->ple_SAC = NULL; + } + } + } + + if (NULL == scp->ple_MUI_ImageObject) + { + UBYTE *BitMapArray; + ULONG ScreenDepth; + + ScreenDepth = GetBitMapAttr(inst->ppb_WBScreen->RastPort.BitMap, BMA_DEPTH); + + d1(KPrintF("%s/%s/%ld: sac=%08lx\n", __FILE__, __FUNC__, __LINE__, scp->ple_SAC)); + if (NULL == scp->ple_SAC) + { + BitMapArray = NULL; + scp->ple_SAC = DoLoadDT((STRPTR) scp->ple_PatternPrefs.scxp_Name, &rp, + inst->ppb_ThumbnailWidth, inst->ppb_ThumbnailHeight, + inst->ppb_WBScreen); + + d1(KPrintF("%s/%s/%ld: sac=%08lx\n", __FILE__, __FUNC__, __LINE__, scp->ple_SAC)); + if (NULL == scp->ple_SAC) + break; + } + else + { + BitMapArray = scp->ple_BitMapArray; + } + + if (CyberGfxBase && ScreenDepth > 8) + { + scp->ple_MUI_ImageObject = BitMapPicObject, + MUIA_ScaBitMappic_BitMap, (IPTR)scp->ple_SAC->sac_BitMap, + MUIA_ScaBitMappic_ColorTable, (IPTR)scp->ple_SAC->sac_ColorTable, + MUIA_ScaBitMappic_Width, scp->ple_SAC->sac_Width, + MUIA_ScaBitMappic_Height, scp->ple_SAC->sac_Height, + MUIA_ScaBitMappic_Screen, (IPTR)inst->ppb_WBScreen, + MUIA_ScaBitmappic_BitMapArray, (IPTR)BitMapArray, + End; + } + else + { + scp->ple_MUI_ImageObject = BitmapObject, + MUIA_Bitmap_Width, scp->ple_SAC->sac_Width, + MUIA_Bitmap_Height, scp->ple_SAC->sac_Height, + MUIA_Bitmap_Bitmap, (IPTR)scp->ple_SAC->sac_BitMap, + MUIA_Bitmap_SourceColors, (IPTR)scp->ple_SAC->sac_ColorTable, + MUIA_Bitmap_UseFriend, TRUE, + MUIA_Bitmap_Precision, PRECISION_ICON, + End; + } + + d1(KPrintF("%s/%s/%ld: ple_MUI_ImageObject=%08lx\n", __FILE__, __FUNC__, __LINE__, scp->ple_MUI_ImageObject)); + if (NULL == scp->ple_MUI_ImageObject) + break; + + // generate unique image number + scp->ple_ThumbnailImageNr = ++inst->ppb_ThumbnailImageNumber; + } + + rp.BitMap = NULL; // don't free rp.BitMap + } while (0); + + d1(KPrintF("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__)); + + if (obj) + DisposeDTObject(obj); + if (rp.BitMap) + FreeBitMap(rp.BitMap); + + d1(KPrintF("%s/%s/%ld: ImageNr=%ld\n", __FILE__, __FUNC__, __LINE__, scp->ple_ThumbnailImageNr)); + d1(KPrintF("%s/%s/%ld: ple_MUI_ImageObject=%08lx\n", __FILE__, __FUNC__, __LINE__, scp->ple_MUI_ImageObject)); + + if (scp->ple_MUI_ImageObject) + { + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_UseImage, + scp->ple_MUI_ImageObject, scp->ple_ThumbnailImageNr, 0); + } + else + { + DoMethod(inst->ppb_Objects[OBJNDX_MainList], MUIM_NList_UseImage, + inst->ppb_Objects[OBJNDX_EmptyThumbnailBitmap], scp->ple_ThumbnailImageNr, 0); + } + + d1(KPrintF("%s/%s/%ld: end\n", __FILE__, __FUNC__, __LINE__)); +} + +//---------------------------------------------------------------------------- + +void ShowError(const char *str, ...) +{ + (void) str; +} + +void _XCEXIT(long x) +{ +} + +//---------------------------------------------------------------------------- + +DISPATCHER(myNList) +{ + struct PatternPrefsInst *inst = NULL; + ULONG result; + + d1(kprintf("%s/%s/%ld: MethodID=%08lx\n", __FILE__, __FUNC__, __LINE__, msg->MethodID)); + + switch(msg->MethodID) + { + case MUIM_ContextMenuChoice: + { + struct MUIP_ContextMenuChoice *cmc = (struct MUIP_ContextMenuChoice *) msg; + Object *MenuObj; + ULONG MenuHookIndex = 0; + struct Hook *MenuHook = NULL; + + get(obj, MUIA_NList_PrivateData, &inst); + + d1(kprintf(__FUNC__ "/%ld: MUIM_ContextMenuChoice item=%08lx\n", __FILE__, __FUNC__, __LINE__, cmc->item)); + + MenuObj = cmc->item; + + d1(kprintf(__FUNC__ "/%ld: MenuObj=%08lx\n", __FILE__, __FUNC__, __LINE__, MenuObj)); + d1(kprintf(__FUNC__ "/%ld: msg=%08lx *msg=%08lx\n", __FILE__, __FUNC__, __LINE__, msg, *((ULONG *) msg))); + + get(MenuObj, MUIA_UserData, &MenuHookIndex); + + if (MenuHookIndex > 0 && MenuHookIndex < HOOKNDX_MAX) + MenuHook = &inst->ppb_Hooks[MenuHookIndex]; + + d1(kprintf(__FUNC__ "/%ld: MenuHook=%08lx\n", __FILE__, __FUNC__, __LINE__, MenuHook)); + if (MenuHook) + DoMethod(inst->ppb_Objects[OBJNDX_Group_Main], MUIM_CallHook, MenuHook, MenuObj); + + result = 0; + } + break; + + default: + result = DoSuperMethodA(cl, obj, msg); + } + + return result; +} +DISPATCHER_END + +//---------------------------------------------------------------------------- + +static void SetChangedFlag(struct PatternPrefsInst *inst, BOOL changed) +{ + if (changed != inst->ppb_Changed) + { + set(inst->ppb_Objects[OBJNDX_Lamp_Changed], + MUIA_Lamp_Color, changed ? MUIV_Lamp_Color_Ok : MUIV_Lamp_Color_Off); + inst->ppb_Changed = changed; + } +} + +//----------------------------------------------------------------- + +static void ParseToolTypes(struct PatternPrefsInst *inst, struct MUIP_ScalosPrefs_ParseToolTypes *ptt) +{ + STRPTR tt; + + d1(kprintf(__FUNC__ "/%ld: start ptt=%08lx tooltypes=%08lx\n", __FILE__, __FUNC__, __LINE__, ptt, ptt->ToolTypes)); + d1(kprintf(__FUNC__ "/%ld: start tooltypes=%08lx %08lx %08lx\n", __FILE__, __FUNC__, __LINE__, ptt, ptt->ToolTypes[0], ptt->ToolTypes[1], ptt->ToolTypes[2])); + + tt = FindToolType(ptt->ToolTypes, "NOSPLASHWINDOW"); + inst->ppb_UseSplashWindow = (NULL == tt); + + tt = FindToolType(ptt->ToolTypes, "THUMBNAILS"); + d1(kprintf(__FUNC__ "/%ld: tt=%08lx\n", __FILE__, __FUNC__, __LINE__, tt)); + if (tt) + { + inst->ppb_UseThumbNails = TRUE; + inst->ppb_fPreview = FALSE; + inst->ppb_fAutoPreview = FALSE; + } + else + { + tt = FindToolType(ptt->ToolTypes, "NOPREVIEW"); + d1(KPrintF(__FUNC__ "/%ld: tt=%08lx\n", __FILE__, __FUNC__, __LINE__, tt)); + if (tt) + { + inst->ppb_fPreview = FALSE; + } + else + { + tt = FindToolType(ptt->ToolTypes, "AUTOPREVIEW"); + d1(KPrintF(__FUNC__ "/%ld: tt=%08lx\n", __FILE__, __FUNC__, __LINE__, tt)); + if (tt) + inst->ppb_fAutoPreview = TRUE; + } + } + + if (inst->ppb_Objects[OBJNDX_MainList]) + UpdateUseThumbnails(inst); + + d1(kprintf(__FUNC__ "/%ld: end\n", __FILE__, __FUNC__, __LINE__)); +} + +//--------------------------------------------------------------- + +BOOL initPlugin(struct PluginBase *PluginBase) +{ + MajorVersion = PluginBase->pl_LibNode.lib_Version; + MinorVersion = PluginBase->pl_LibNode.lib_Revision; + + d1(kprintf(__FUNC__ "/%ld:\n", __FILE__, __FUNC__, __LINE__)); + + if (0x4711 == Signature++) + { + d1(kprintf(__FUNC__ "/%ld: PatternPrefsBase=%08lx procName=<%s>\n", __FILE__, __FUNC__, __LINE__, \ + PatternPrefsBase, FindTask(NULL)->tc_Node.ln_Name)); + + d1(kprintf(__FUNC__ "/%ld:\n", __FILE__, __FUNC__, __LINE__)); + + if (!OpenLibraries()) + return FALSE; + +#if !defined(__amigaos4__) && !defined(__AROS__) + if (_STI_240_InitMemFunctions()) + return FALSE; +#endif + + PatternPrefsClass = MUI_CreateCustomClass(&PluginBase->pl_LibNode, MUIC_Group, + NULL, sizeof(struct PatternPrefsInst), DISPATCHER_REF(PatternPrefs)); + + d1(kprintf(__FUNC__ "/%ld: PatternPrefsClass=%08lx\n", __FILE__, __FUNC__, __LINE__, PatternPrefsClass)); + if (NULL == PatternPrefsClass) + return FALSE; + + if (LocaleBase) + { + if (NULL == PatternPrefsLocale) + PatternPrefsLocale = OpenLocale(NULL); + + if (PatternPrefsLocale) + { + if (NULL == PatternPrefsCatalog) + { + PatternPrefsCatalog = OpenCatalog(PatternPrefsLocale, + (STRPTR) "Scalos/ScalosPattern.catalog", NULL); + } + } + } + + TranslateStringArray(dithermodecont); + TranslateStringArray(patternmode); + TranslateStringArray(RegisterTitleStrings); + TranslateStringArray(CycleBackgroundModeStrings); + + TranslateNewMenu(ContextMenus); + + DataTypesImageClass = InitDtpicClass(); + if (NULL == DataTypesImageClass) + return FALSE; // Failure + + BackfillClass = InitBackfillClass(); + if (NULL == BackfillClass) + return FALSE; // Failure + + PatternSliderClass = MUI_CreateCustomClass(NULL, MUIC_Slider, NULL, + 0, DISPATCHER_REF(PatternSlider)); + if (NULL == PatternSliderClass) + return FALSE; // Failure + + BitMapPicClass = InitBitMappicClass(); + if (NULL == BitMapPicClass) + return FALSE; // Failure + + PrecSliderClass = MUI_CreateCustomClass(NULL, MUIC_Slider, NULL, + 0, DISPATCHER_REF(PrecSlider)); + if (NULL == PrecSliderClass) + return FALSE; // Failure + + myNListClass = MUI_CreateCustomClass(NULL, MUIC_NList, + NULL, 0, DISPATCHER_REF(myNList)); + if (NULL == myNListClass) + return FALSE; // Failure + } + + return TRUE; // Success +} + +//---------------------------------------------------------------------------- + +static void UpdateUseThumbnails(struct PatternPrefsInst *inst) +{ + set(inst->ppb_Objects[OBJNDX_Balance], MUIA_ShowMe, inst->ppb_fPreview && !inst->ppb_UseThumbNails); + set(inst->ppb_Objects[OBJNDX_Group_Preview], MUIA_ShowMe, inst->ppb_fPreview && !inst->ppb_UseThumbNails); + + set(inst->ppb_Objects[OBJNDX_Menu_Thumbnails], MUIA_Menuitem_Checked, inst->ppb_UseThumbNails); + set(inst->ppb_Objects[OBJNDX_Menu_ShowPreview], MUIA_Menuitem_Checked, inst->ppb_fPreview && !inst->ppb_UseThumbNails); + set(inst->ppb_Objects[OBJNDX_Menu_ShowPreview], MUIA_Menuitem_Enabled, !inst->ppb_UseThumbNails); + set(inst->ppb_Objects[OBJNDX_Menu_AutoPreview], MUIA_Menuitem_Enabled, inst->ppb_fPreview && !inst->ppb_UseThumbNails); + set(inst->ppb_Objects[OBJNDX_Menu_ReloadThumbnails], MUIA_Menuitem_Enabled, inst->ppb_UseThumbNails); + + set(inst->ppb_Objects[OBJNDX_MainList], MUIA_NList_Format, + (ULONG) (inst->ppb_UseThumbNails ? LISTFORMAT_THUMBNAILS : LISTFORMAT_STANDARD)); + + // pattern previews are only enabled if thumbnails are enabled + set(inst->ppb_Objects[OBJNDX_Group_PatternPreviews], MUIA_ShowMe, inst->ppb_UseThumbNails); +} + +//---------------------------------------------------------------------------- + +static void DisableBackgroundColorGadgets(struct PatternPrefsInst *inst, UWORD RenderType, UWORD BgType) +{ + // Background type only changeable with SCP_RenderType_Centered and SCP_RenderType_ScaledMin + switch (RenderType) + { + case SCP_RenderType_FitSize: + case SCP_RenderType_Tiled: + set(inst->ppb_Objects[OBJNDX_CycleBackgroundType], MUIA_Disabled, TRUE); + setcycle(inst->ppb_Objects[OBJNDX_CycleBackgroundType], SCP_BgType_Picture); + BgType = SCP_BgType_Picture; + break; + case SCP_RenderType_Centered: + case SCP_RenderType_ScaledMin: + default: + set(inst->ppb_Objects[OBJNDX_CycleBackgroundType], MUIA_Disabled, FALSE); + break; + } + + switch (BgType) + { + case SCP_BgType_SingleColor: + set(inst->ppb_Objects[OBJNDX_ColorAdjustBgColor1], MUIA_Disabled, FALSE); + set(inst->ppb_Objects[OBJNDX_ColorAdjustBgColor2], MUIA_Disabled, TRUE); + break; + case SCP_BgType_HorizontalGradient: + case SCP_BGType_VerticalGradient: + set(inst->ppb_Objects[OBJNDX_ColorAdjustBgColor1], MUIA_Disabled, FALSE); + set(inst->ppb_Objects[OBJNDX_ColorAdjustBgColor2], MUIA_Disabled, FALSE); + break; + case SCP_BgType_Picture: + default: + set(inst->ppb_Objects[OBJNDX_ColorAdjustBgColor1], MUIA_Disabled, TRUE); + set(inst->ppb_Objects[OBJNDX_ColorAdjustBgColor2], MUIA_Disabled, TRUE); + break; + } +} + +//---------------------------------------------------------------------------- + +#if !defined(__SASC) && !defined(__amigaos4__) && !defined(__AROS__) +// Replacement for SAS/C library functions + +#if !defined(__MORPHOS__) + +static size_t stccpy(char *dest, const char *src, size_t MaxLen) +{ + size_t Count = 0; + + while (*src && MaxLen > 1) + { + *dest++ = *src++; + MaxLen--; + Count++; + } + *dest = '\0'; + Count++; + + return Count; +} +#endif /* __MORPHOS__ */ + +void exit(int x) +{ + (void) x; + while (1) + ; +} + +APTR _WBenchMsg; + +#endif /* __SASC */ + +//---------------------------------------------------------------------------- diff --git a/scalos/Plugins/Prefs/Pattern/PatternPrefs.h b/scalos/Plugins/Prefs/Pattern/PatternPrefs.h new file mode 100644 index 000000000..7354bd3c6 --- /dev/null +++ b/scalos/Plugins/Prefs/Pattern/PatternPrefs.h @@ -0,0 +1,154 @@ +// PatternPrefs.h +// $Date$ +// $Revision$ + + +#ifndef SCALOS_PATTERNPREFS_H +#define SCALOS_PATTERNPREFS_H + +#define Sizeof(array) (sizeof(array) / sizeof((array)[0])) + +enum HookIndex +{ + HOOKNDX_ListDisplay, + HOOKNDX_ListConstruct, + HOOKNDX_ListDestruct, + HOOKNDX_ListCompare, + HOOKNDX_ListSelectEntry, + HOOKNDX_ListChangeEntry, + HOOKNDX_ListChangeEntry2, + HOOKNDX_ListChangeEntry3, + HOOKNDX_AddNewEntry, + HOOKNDX_RemEntry, + HOOKNDX_LastSaved, + HOOKNDX_Restore, + HOOKNDX_ResetToDefaults, + HOOKNDX_About, + HOOKNDX_Open, + HOOKNDX_SaveAs, + HOOKNDX_PreviewSelect, + HOOKNDX_ContextMenuTrigger, + HOOKNDX_ShowPreview, + HOOKNDX_AutoPreview, + HOOKNDX_AppMsgInMainList, + HOOKNDX_SettingsChanged, + HOOKNDX_Thumbnails, + HOOKNDX_DesktopPatternChanged, + HOOKNDX_ScreenPatternChanged, + HOOKNDX_IconWindowPatternChanged, + HOOKNDX_TextWindowPatternChanged, + HOOKNDX_AslIntuiMsg, + HOOKNDX_ReloadThumbnails, + + HOOKNDX_MAX +}; + +enum ObjectIndex +{ + OBJNDX_APP_Main, + OBJNDX_WIN_Main, + OBJNDX_WIN_Message, + OBJNDX_MainListView, + OBJNDX_MainList, + OBJNDX_NewButton, + OBJNDX_DelButton, + OBJNDX_NumButton, + OBJNDX_Popasl, + OBJNDX_CyclePatternType, + OBJNDX_CheckmarkGad, + OBJNDX_CheckmarkEnh, + OBJNDX_PrecSlider, + OBJNDX_CheckmarkAutoDither, + OBJNDX_PreviewImage, + OBJNDX_SliderColours, + OBJNDX_CycleDitherMode, + OBJNDX_SliderDitherAmount, + OBJNDX_CheckmarkAsync, + OBJNDX_CheckmarkFriend, + OBJNDX_CheckmarkRelayout, + OBJNDX_CheckmarkRandom, + OBJNDX_MsgText1, + OBJNDX_MsgText2, + OBJNDX_MsgGauge, + OBJNDX_Group_Enhanced, + OBJNDX_Group_Preview, + OBJNDX_Group_String, + OBJNDX_Group_Slider, + OBJNDX_Group_MainList, + OBJNDX_Group_Main, + OBJNDX_Group_PatternSliders, + OBJNDX_Group_PatternPreviews, + OBJNDX_SliderTaskPri, + OBJNDX_STR_PopAsl, + OBJNDX_SliderWB, + OBJNDX_SliderScreen, + OBJNDX_SliderWin, + OBJNDX_SliderText, + OBJNDX_Balance, + OBJNDX_Menu_ShowPreview, + OBJNDX_Menu_AutoPreview, + OBJNDX_Menu_Thumbnails, + OBJNDX_Menu_ReloadThumbnails, + OBJNDX_Lamp_Changed, + OBJNDX_Image_DesktopPattern, + OBJNDX_Image_ScreenPattern, + OBJNDX_Image_IconWindowPattern, + OBJNDX_Image_TextWindowPattern, + + OBJNDX_CycleBackgroundType, + OBJNDX_ColorAdjustBgColor1, + OBJNDX_ColorAdjustBgColor2, + + OBJNDX_EmptyThumbnailBitmap, + + OBJNDX_ContextMenu, + + OBJNDX_MAX +}; + +struct PatternPrefsInst +{ + ULONG ppb_fCreateIcons; + ULONG ppb_fPreview; + ULONG ppb_fAutoPreview; + ULONG ppb_fDontChange; + + BYTE ppb_patternPrecision; + ULONG ppb_PreviewWeight; + + CONST_STRPTR ppb_ProgramName; + + BOOL ppb_UseSplashWindow; + BOOL ppb_UseThumbNails; + BOOL ppb_Changed; + ULONG ppb_BitMapsRead; + + ULONG ppb_ThumbnailWidth; // Dimensions of thumbnails + ULONG ppb_ThumbnailHeight; + + ULONG ppb_ThumbnailImageNumber; + + struct Screen *ppb_WBScreen; + + struct Hook ppb_Hooks[HOOKNDX_MAX]; + Object *ppb_Objects[OBJNDX_MAX]; + + struct MUI_NListtree_TreeNode *ppb_MainMenuNode; + struct MUI_NListtree_TreeNode *ppb_PopMenuNode[6]; + + struct FileRequester *ppb_LoadReq; + struct FileRequester *ppb_SaveReq; + + Object *ppb_SubWindows[2]; +}; + +//---------------------------------------------------------------------------- + +struct ScalosPattern_LocaleInfo +{ + APTR li_LocaleBase; + APTR li_Catalog; + struct LocaleIFace *li_ILocale; +}; + +#endif /* SCALOS_PATTERNPREFS_H */ diff --git a/scalos/Plugins/Prefs/Pattern/PatternPrefsImage.h b/scalos/Plugins/Prefs/Pattern/PatternPrefsImage.h new file mode 100644 index 000000000..c5f87718b --- /dev/null +++ b/scalos/Plugins/Prefs/Pattern/PatternPrefsImage.h @@ -0,0 +1,53 @@ +static const ULONG PatternPrefs_colors[48] = +{ + 0xdddddddd,0x66666666,0x33333333, + 0x99999999,0x99999999,0x99999999, + 0x11111111,0x55555555,0x33333333, + 0x22222222,0x44444444,0x44444444, + 0x55555555,0x55555555,0x55555555, + 0x33333333,0x44444444,0x99999999, + 0x33333333,0x99999999,0x44444444, + 0x11111111,0xcccccccc,0x22222222, + 0x44444444,0xaaaaaaaa,0x77777777, + 0x22222222,0x88888888,0x88888888, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0x66666666,0x99999999,0xcccccccc, + 0x33333333,0x33333333,0x44444444, + 0xcccccccc,0xaaaaaaaa,0x44444444, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0xeeeeeeee,0xeeeeeeee,0xeeeeeeee, +}; + +#define PATTERNPREFS_WIDTH 22 +#define PATTERNPREFS_HEIGHT 19 +#define PATTERNPREFS_DEPTH 4 +#define PATTERNPREFS_COMPRESSION 0 +#define PATTERNPREFS_MASKING 2 + +#ifdef USE_PATTERNPREFS_HEADER +static const struct BitMapHeader PatternPrefs_header = +{ 22,19,0,0,4,2,0,0,0,44,44,320,256 }; +#endif + +static const UBYTE PatternPrefs_body[304] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x05,0x2c,0x80,0x00,0x05,0x76,0x80,0x00,0x0a,0xf7,0xc0,0x00,0x07, +0xf6,0x80,0x00,0x0f,0xbc,0x80,0x00,0x01,0x3d,0x40,0x00,0x1e,0xff,0xe0,0x00, +0x01,0x7d,0xc0,0x00,0x1f,0xc3,0x00,0x00,0x04,0x1f,0x00,0x00,0x39,0x7f,0xe0, +0x00,0x06,0xbf,0xc0,0x00,0x3f,0xe9,0x00,0x00,0x11,0x0f,0x00,0x00,0x2e,0xff, +0xc0,0x00,0x11,0x1f,0x80,0x00,0x1f,0xe0,0x00,0x00,0x17,0xc6,0x00,0x00,0x28, +0x3f,0xe0,0x00,0x37,0xdf,0xc0,0x00,0x0f,0xc8,0x60,0x00,0x0b,0x00,0x00,0x00, +0x34,0xff,0xf0,0x00,0x1b,0x3f,0xe0,0x00,0x07,0x84,0xf0,0x00,0x02,0xb0,0x00, +0x00,0x1d,0x4f,0xf8,0x00,0x0a,0xcf,0xf0,0x00,0x03,0x03,0xf8,0x00,0x00,0x68, +0x00,0x00,0x0d,0x97,0xf8,0x00,0x06,0x97,0xf8,0x00,0x00,0x01,0xf8,0x00,0x00, +0xbe,0x00,0x00,0x07,0x43,0xf8,0x00,0x03,0x41,0xf8,0x00,0x00,0x00,0xf0,0x00, +0x01,0xb3,0x00,0x00,0x02,0x4c,0xf0,0x00,0x02,0x4c,0xf0,0x00,0x00,0x00,0x60, +0x00,0x03,0x26,0x00,0x00,0x00,0xd9,0xe0,0x00,0x00,0xd8,0x60,0x00,0x00,0x00, +0x00,0x00,0x01,0x68,0x00,0x00,0x07,0x97,0x00,0x00,0x02,0x94,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0xd0,0x00,0x00,0x03,0x2e,0x00,0x00,0x01,0x28,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x01,0xfc,0x00,0x00,0x00,0xb8,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,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, }; diff --git a/scalos/Plugins/Prefs/Pattern/config.mk b/scalos/Plugins/Prefs/Pattern/config.mk new file mode 100755 index 000000000..74782eb7a --- /dev/null +++ b/scalos/Plugins/Prefs/Pattern/config.mk @@ -0,0 +1,81 @@ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +COMMON_DIR = $(TOPLEVEL)/common/Plugin +BITMAPMCC_DIR = $(TOPLEVEL)/common/BitMapMCC +BACKFILLMCC_DIR = $(TOPLEVEL)/common/BackfillMCC +DATATYPESMCC_DIR = $(TOPLEVEL)/common/DataTypesMCC + +INCLUDES += -I$(COMMON_DIR) \ + -I$(BACKFILLMCC_DIR) \ + -I$(BITMAPMCC_DIR) \ + -I$(DATATYPESMCC_DIR) + +SCALOS_LOCALE = $(OBJDIR)/ScalosPattern_locale.h + +CFLAGS += -D SCALOSLOCALE=$(SCALOS_LOCALE) + +vpath %.c $(COMMON_DIR) $(BITMAPMCC_DIR) $(BACKFILLMCC_DIR) $(DATATYPESMCC_DIR) + +############################################################################## + +include $(COMMON_DIR)/config.mk + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += -nostartfiles \ + -lmempools +# --verbose + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += -nostartfiles \ +# + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +DEFINES += -DMUI_OBSOLETE +LFLAGS += -nostartfiles -lmui \ +# + + +else + +############################################################################### +# AmigaOS + +LFLAGS += -lscalos \ + -lpreferences \ + -liconobject \ + -lmempools \ + -ldebug \ + -lmui \ + -lstack \ + -lnix \ + -lnixmain \ + -lamiga21 \ + -lamiga \ + -lstubs \ + +endif +endif +endif diff --git a/scalos/Plugins/Prefs/Pattern/debug.h b/scalos/Plugins/Prefs/Pattern/debug.h new file mode 100644 index 000000000..aea559dac --- /dev/null +++ b/scalos/Plugins/Prefs/Pattern/debug.h @@ -0,0 +1,19 @@ +// debug.h +// $Date$ +// $Revision$ + +#ifndef DEBUG_H +#define DEBUG_H + +//---------------------------------------------------------------------------- + +#define d1(x) ; +#define d2(x) x; + +// from debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +//---------------------------------------------------------------------------- + +#endif /* DEBUG_H */ diff --git a/scalos/Plugins/Prefs/Pattern/makefile b/scalos/Plugins/Prefs/Pattern/makefile new file mode 100644 index 000000000..55ce3f175 --- /dev/null +++ b/scalos/Plugins/Prefs/Pattern/makefile @@ -0,0 +1,188 @@ +# makefile für Scalos Pattern.prefsplugin +# $Date$ +# $Revision$ +############################################################# + +SDPATH = // + +SUBDIRMAKE = $(MAKE) -s -C +FLEXCAT = FlexCat +CATCOMP = CatComp +LD = slink +CC = sc +SPLAT = sc:c/splat + +LIBS = LIB:scm.lib LIB:sc.lib LIB:mempools.lib \ + LIB:debug.lib LIB:amiga.lib +LDFLAGS = quiet batch noicons +PRECOMP = Include:all.gst +ECHO = echo +OBJDIR = .sasobj +BINDIR = .bin_os3 + +COMMON_DIR = ../../../common/Plugin +BITMAPMCC_DIR = ../../../common/BitMapMCC +BACKFILLMCC_DIR = ../../../common/BackfillMCC +DATATYPESMCC_DIR = ../../../common/DataTypesMCC + +# search ScalosPattern.cd for Prefs/Pattern/catalogs/ +PREFSPATH = ../../../Prefs/Pattern + +.SUFFIXES: .s .asm .plugin .plugin.debug + +############################################################# + +CSRCS = $(COMMON_DIR)/plugin-classic.c \ + PatternPrefs.c \ + $(BACKFILLMCC_DIR)/Backfill.c \ + $(BITMAPMCC_DIR)/BitMapMCC.c \ + $(DATATYPESMCC_DIR)/DataTypesMCC.c \ + DoLoadDT.c + +############################################################# + +.PHONY: clean install nodebug + +############################################################# + +CFLAGS = optimize nostackcheck nover dbg=s DATA=far \ + idlen=64 ignore=306 \ + define SCALOSLOCALE=$(SCALOS_LOCALE) \ + idir=///include \ + idir=$(subst ../,/,$(PREFSPATH)) \ + idir=$(subst ../,/,$(BACKFILLMCC_DIR)) \ + idir=$(subst ../,/,$(BITMAPMCC_DIR)) \ + idir=$(subst ../,/,$(DATATYPESMCC_DIR)) \ + idir=///common/Plugin +LNFLAGS = quiet batch noicons stripdebug SD +LNDBFLAGS = quiet batch noicons addsym SD + +############################################################# + +PLUGIN = Pattern.prefsplugin +PLUGINDBG = $(PLUGIN).debug +CAT_FILE = Scalos/ScalosPattern.catalog +DESTTOOL = Scalos:Prefs/ +DESTCAT = Locale:Catalogs +SRCCAT = $(subst ../,/,$(PREFSPATH)) +SCALOS_LOCALE = $(OBJDIR)/ScalosPattern_locale.h +CATCOMPHEADER = $(SCALOS_LOCALE) + +CATS = dansk \ + deutsch \ + español \ + français \ + italiano \ + svenska \ + ÃeÓtina + +ALLCATS = $(foreach cat,$(CATS),$(SRCCAT)/catalogs/$(cat)/$(CAT_FILE)) + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +XSRCS = $(notdir $(CSRCS)) +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(XSRCS:%.c=$(OBJDIR)/$(notdir %).o) + +############################################################# + +All: $(BINDIR)/$(PLUGIN) \ + $(BINDIR)/$(PLUGINDBG) \ + allcatalogs +# install +# clean + +############################################################# + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-classic.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/BitMapMCC.o : $(BITMAPMCC_DIR)/BitMapMCC.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/Backfill.o : $(BACKFILLMCC_DIR)/Backfill.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/DataTypesMCC.o : $(DATATYPESMCC_DIR)/DataTypesMCC.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $*.c objectname $@ + +############################################################# + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-common.c \ + plugin_data.h $(COMMON_DIR)/plugin.h + +$(OBJDIR)/BitMapMCC.o : $(BITMAPMCC_DIR)/BitMapMCC.c \ + $(BITMAPMCC_DIR)/BitMapMCC.h debug.h + +$(OBJDIR)/Backfill.o : $(BACKFILLMCC_DIR)/Backfill.c \ + $(BACKFILLMCC_DIR)/Backfill.h $(BITMAPMCC_DIR)/BitMapMCC.h + +$(OBJDIR)/DataTypesMCC.o : $(DATATYPESMCC_DIR)/DataTypesMCC.h + +$(OBJDIR)/PatternPrefs.o : PatternPrefs.h \ + PatternPrefsImage.h \ + plugin_data.h \ + $(COMMON_DIR)/plugin.h \ + $(BACKFILLMCC_DIR)/Backfill.h \ + $(BITMAPMCC_DIR)/BitMapMCC.h \ + $(DATATYPESMCC_DIR)/DataTypesMCC.h \ + $(CATCOMPHEADER) + +############################################################# + +PatternPrefs.c : $(SCALOS_LOCALE) + +$(CATCOMPHEADER) : $(PREFSPATH)/ScalosPattern.cd + @printf '\033[32mMake CatComp header: \033[31m\033[1m$@ \033[32mfrom \033[31m$<\033[0m\n' + $(FLEXCAT) $(subst ../,/,$<) $@=$(SDPATH)/CatComp_h.sd + +############################################################################## + +$(BINDIR)/$(PLUGIN) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) to $@ FROM $(OBJS) lib $(LIBS) $(LDFLAGS) STRIPDEBUG + +$(BINDIR)/$(PLUGINDBG) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) to $@ FROM $(OBJS) lib $(LIBS) $(LDFLAGS) ADDSYM + +############################################################# + +# copy all generated files to their final destinations +install: + @avail flush + @printf '\033[32mInstall: \033[31m\033[1m$(PLUGIN)\033[0m\n' + @copy $(BINDIR)/$(PLUGIN) "$(DESTTOOL)" + @printf '\033[32mInstall: \033[31m\033[1m$(CAT_FILE)\033[0m\n' + -@$(foreach cat,$(CATS),copy "$(SRCCAT)/catalogs/$(cat)/$(CAT_FILE)" "$(DESTCAT)/$(cat)/Scalos" clone;) + +############################################################# + +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + -@delete $(BINDIR)/$(PLUGIN) $(BINDIR)/$(PLUGINDBG) $(OBJS) $(subst ../,/,$(CATCOMPHEADER)) $(ALLCATS) + @printf '\033[0m' + +############################################################# + +# make all Scalos preferences .catalogs +allcatalogs: + -@$(foreach cat,$(CATS),$(SUBDIRMAKE) $(PREFSPATH)/catalogs/$(cat)/Scalos;) + +############################################################# + +nodebug: + -@$(SPLAT) -s -o "d2(" "d1(" "#?.c" + +############################################################# + diff --git a/scalos/Plugins/Prefs/Pattern/makefile-new b/scalos/Plugins/Prefs/Pattern/makefile-new new file mode 100755 index 000000000..149ed6729 --- /dev/null +++ b/scalos/Plugins/Prefs/Pattern/makefile-new @@ -0,0 +1,94 @@ +# $Date: 2011-08-09 11:15:58 +0200 (Di, 09. Aug 2011) $ +# $Revision: 828 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../../.. +endif + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + PARENTDIR=/ + SDPATH=// +else + PARENTDIR=../ + SDPATH=../../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(BEGIN_OBJS) \ + $(OBJDIR)/PatternPrefs.o \ + $(OBJDIR)/Backfill.o \ + $(OBJDIR)/BitMapMCC.o \ + $(OBJDIR)/DataTypesMCC.o \ + $(OBJDIR)/DoLoadDT.o \ + $(END_OBJS) + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Targets +# + +NAME = Pattern.prefsplugin +NAME_DB = $(NAME).debug + +############################################################################## + +PREFSDIR = ../../../Prefs/Pattern + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) + +############################################################################## + +PatternPrefs.c : $(SCALOS_LOCALE) + +$(SCALOS_LOCALE) : $(PREFSDIR)/ScalosPattern.cd + @$(ECHO) "FlexCat $@" + $(FLEXCAT) $(subst ../,$(PARENTDIR),$<) $@=$(SDPATH)/CatComp_h.sd + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + $(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) Scalos:Prefs/ clone + @avail flush + + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* \ + $(SCALOS_LOCALE) + +############################################################################## + diff --git a/scalos/Plugins/Prefs/Pattern/plugin_data.h b/scalos/Plugins/Prefs/Pattern/plugin_data.h new file mode 100644 index 000000000..2031c9580 --- /dev/null +++ b/scalos/Plugins/Prefs/Pattern/plugin_data.h @@ -0,0 +1,27 @@ +// plugin_data.h +// $Date$ +// $Revision$ + +#ifndef PLUGIN_DATA_H_INCLUDED +#define PLUGIN_DATA_H_INCLUDED + +#include +#include + +#define PLUGIN_TYPE PREFS + +#define LIB_VERSION 40 +#define LIB_REVISION 21 + +#define LIB_NAME "Pattern.prefsplugin" +#define LIB_VERSTRING "$VER: " LIB_NAME " " \ + STR(LIB_VERSION) "." STR(LIB_REVISION) \ + " " __DATE__ \ + COMPILER_STRING " ©2003" CURRENTYEAR \ + " The Scalos Team" + +//---------------------------------------------------------------------------- +// code and includes to define the structs and functions used above + +#endif /* PLUGUN_DATA_H_INCLUDED */ + diff --git a/scalos/Plugins/Prefs/Popupmenu/Catalogs/deutsch/Scalos/ScalosPopupMenu.ct b/scalos/Plugins/Prefs/Popupmenu/Catalogs/deutsch/Scalos/ScalosPopupMenu.ct new file mode 100644 index 000000000..8db21f73d --- /dev/null +++ b/scalos/Plugins/Prefs/Popupmenu/Catalogs/deutsch/Scalos/ScalosPopupMenu.ct @@ -0,0 +1,625 @@ +; ScalosPopupMenu.ct +; $Date$ +; $Revision$ +## version $VER: ScalosPopupMenu.catalog 40.2 (06 Jan 2010 14:31:25) +## codeset 0 +## language deutsch +; +;#arrayopts static __far +; +;--------------------------------------------- +; +MSGID_PLUGIN_LIST_TITLE +PopupMenü +;PopupMenu +; +; +MSGID_TITLENAME +Scalos PopupMenü Voreinsteller +;Scalos PopupMenu Prefs Plugin +; +;--------------------------------------------- +; +MSGID_MENU_PROJECT_OPEN +Öffnen... +;Open... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +O +;O +; +; +MSGID_MENU_PROJECT_SAVEAS +Speichern als... +;Save As... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +A +;A +; +; +MSGID_MENU_PROJECT_ABOUT +Über... +;About... +; +; +MSGID_MENU_PROJECT_QUIT +Beenden +;Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +;Q +; +; +MSGID_MENU_PROJECT +Projekt +;Project +; +; +MSGID_MENU_EDIT_LASTSAVED +auf zuletzt gespeichertes +;Last Saved +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +L +;L +; +; +MSGID_MENU_EDIT +Verändern +;Edit +; +; +MSGID_MENU_SETTINGS_CREATEICONS +Piktogramme erzeugen? +;Create Icons? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +I +;I +; +; +MSGID_MENU_SETTINGS +Einstellungen +;Settings +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +auf Vorgaben zurücksetzen +;Reset To Defaults +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +D +;D +; +; +MSGID_MENU_EDIT_RESTORE +auf vorherigen Stand +;Restore +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +R +;R +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Über MUI... +;About MUI... +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +_OK +;_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos PopupMenü Voreinsteller V%ld.%ld\033n\n\ +%s\n\ +;© 2006%s Das Scalos-Team +;\33c\033bScalos PopupMenu Preferences V%ld.%ld\033n\n\ +;%s\n\ +;© 2006%s The Scalos Team +; +;--------------------------------------------- +; +MSGID_SHORTHELP_SAVEBUTTON +Drücken Sie diesen Knopf, um alle\n\ +Einstellungen dauerhaft in\n\ +\"ENVARC:sys/PopupMenu.prefs\"\n\ +zu speichern. +;Press this button to save \n\ +;the current settings to\n\ +;\"ENVARC:sys/PopupMenu.prefs\"\n\ +;and make changes permanent. +; +; +MSGID_SHORTHELP_USEBUTTON +Drücken Sie diesen Knopf, um alle Einstellungen\n\ +bis zum nächsten Neustart in\n\ +\"ENV:sys/PopupMenu.prefs\"\n\ +zu speichern. +;Press this button to save \n\ +;the current settings to\n\ +;\"ENV:sys/PopupMenu.prefs\"\n\ +;and keep settings until reboot. +; +; +MSGID_SHORTHELP_CANCELBUTTON +Drücken Sie diesen Knopf, um das\n\ +Programm abzubrechen und alle\n\ +Änderungen zu verwerfen. +;Press this button to abort \n\ +;and forget all changes. +; +;--------------------------------------------- +; +MSGID_REQTITLE_SAVEERROR +Fehler beim Schreiben der Einstellungs-\n\ +Datei \"%s\"\n\ +%s +;Error writing PopupMenu preferences\n\ +;file \"%s\"\n\ +;%s +; +; +MSGID_REQTITLE_READERROR +Fehler beim Lesen der Einstellungs-\n\ +Datei \"%s\"\n\ +%s +;Error reading PopupMenu preferences\n\ +;file \"%s\"\n\ +;%s +; +;--------------------------------------------- +; +MSGID_POPUP_ASLTITLE_MENUPLUGIN +Scalos PopupMenü Einstellungen wählen +;Select Scalos PopupMenu prefs +; +; +MSGID_SHORTHELP_LAMP_CHANGED +Diese Anzeigelampe wechselt den Zustand von \033bAus\033n\n\ +nach \033bAn\033n wenn die Konfiguration seit\n\ +dem ersten Laden verändert wurde. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Scalos Menü Voreinsteller kann nicht gestartet werden +;Scalos PopupMenu Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Wiederholen|Beenden +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\ +Die Klasse ist nicht installiert. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Sie haben momentan Version v%lu.%lu installiert und\n\ +sollten die Klasse daher aktualisieren! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Version %lu.%lu wird momentan von einer anderen Anwendung\n\ +verwendet. Wenn sie die benötigte Version installiert haben,\n\ +schließen sie alle MUI Programme und probieren es erneut. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_PREFSPAGES_MISC +Verschiedenes +;Misc. +; +; +MSGID_PREFSPAGES_BORDERS +Rahmen +;Borders +; +; +MSGID_PREFSPAGES_SPACING +Abstände +;Spacing +; +; +MSGID_PREFSPAGES_TEXT +Text +;Text +; +; +MSGID_PREFSPAGES_TRANSPARENCY +Transparenz +;Transparency +; +;----------------------------------------------------------- +; +MSGID_MISCPAGE_TITLE +Verschiedenes +;Miscellaneous +; +; +MSGID_MISCPAGE_ANIMATION_TYPE +Typ: +;Type: +; +; +MSGID_MISCPAGE_ANIMATION_TYPE_SHORTHELP +Wählt aus, welcher Animationseffekt beim\n\ +Öffnen eines Popupmenüs benutzt wird. +;Select the type of animation\n\ +;used to open the popup menu. +; +; +MSGID_MISCPAGE_ANIMATION +Effekt: +;Animation +; +; +MSGID_MISCPAGE_DELAY_SUBMENUS +Wartezeit für Untermenüs: +;Delay for submenus: +; +; +MSGID_MISCPAGE_DELAY_SUBMENUS_SHORTHELP +Legt die Verzögerung fest, mit\n\ +angewählte Untermenüs geöffnet werden. +;Here you can adjust how long it will take\n\ +;until the submenu opens when you move the\n\ +;mouse of the submenu item. +; +; +MSGID_MISCPAGE_MENUSHADOWS +Schatten für Menüs? +;Menu Shadows? +; +; +MSGID_MISCPAGE_MENUSHADOWS_SHORTHELP +Wählt aus, ob Popupmenüs mit\n\ +Schatten geöffnet werden. +;Select here whether popup menus\n\ +;will have a drop-shadow. +; +; +MSGID_MISCPAGE_STICKY +Klebrig? +;Sticky? +; +; +MSGID_MISCPAGE_STICKY_SHORTHELP +Wenn ausgewählt, bleibt ein geöffnetes\n\ +Popupmenü auf dem Schirm \"kleben\", wenn die\n\ +rechte Maustaste losgelassen wird. +;Select here whether popup menus will behave sticky,\n\ +;i.e. will stay open after you release the right mouse\n\ +;button. +; +; +MSGID_MISCPAGE_REALSHADOWS +Echte Schatten? +;Real Shadows? +; +; +MSGID_MISCPAGE_REALSHADOWS_SHORTHELP +Wenn ausgewählt, wird der Schatten von Popupmenüs\n\ +realistisch mit durchscheinendem Hintergrund angezeigt\n\ +(Funktioniert nur mit Grafikkarte und mehr als\n\ +256 Farben auf dem Bildschirm). +;If selected, realistic and translucent dropshadows\n\ +;are drawn (required graphics board and hi-colour\n\ +;or true-colour screen). +; +; +MSGID_ANIMATION_NONE +Keine +;None +; +; +MSGID_ANIMATION_ZOOM +Zoom +;Zoom +; +; +MSGID_ANIMATION_FADE +Einblenden +;Fade +; +; +MSGID_ANIMATION_EXPLODE +Explodieren +;Explode +; +;----------------------------------------------------------- +; +MSGID_BORDERSPAGE_TITLE +Rahmen für Menüs +;Menu Border +; +; +MSGID_BORDERSPAGE_MENUBORDER +Rahmen für Menüs +;Menu Border +; +; +MSGID_BORDERSPAGE_SELECTEDITEM +Ausgewählter Menupunkt +;Selected Item +; +; +MSGID_BORDERSPAGE_SEPARATORS +Abstandshalter +;Separators +; +; +MSGID_BORDERSPAGE_NORMAL +Normal +;Normal +; +; +MSGID_BORDERSPAGE_RAISED +Erhöht +;Raised +; +; +MSGID_BORDERSPAGE_RECESSED +Versenkt +;Recessed +; +; +MSGID_BORDERSPAGE_NEW_LOOK +Neue Darstellung +;New Look +; +; +MSGID_BORDERSPAGE_OLD_LOOK +Alte Darstellung +;Old Look +; +;----------------------------------------------------------- +; +MSGID_SPACINGPAGE_TITLE +Abstände +;Spacing +; +; +MSGID_SPACINGPAGE_HORIZONTAL_SPACE +Horizontalabstand innen +;Horizontal inner spacing +; +; +MSGID_SPACINGPAGE_VERTICAL_SPACE +Zeilenabstand +;Vertical spacing +; +; +MSGID_SPACINGPAGE_HORIZONTAL +Horizontaler Rand +;Horizontal outer spacing +; +; +MSGID_SPACINGPAGE_VERTICAL_OFFSET +Vertikaler Rand +;Vertical offset +; +; +MSGID_SPACINGPAGE_INTERMEDIATE_SPACING +Zwischenraum +;Intermediate spacing +; +; +MSGID_SPACINGPAGE_TEXT_DISPLACEMENT +Textversatz +;Text displacement +; +;----------------------------------------------------------- +; +MSGID_TEXTPAGE_TITLE +Textauszeichnungen +;Text styles +; +; +MSGID_TEXTPAGE_MENU_TITLES +Menü-Titel +;Menu Titles +; +; +MSGID_TEXTPAGE_MENU_ITEMS +Menupunkte +;Menu Items +; +; +MSGID_TEXTPAGE_MENUTITLES_ITALIC +\033iKursiv?\033n +;\033iItalic?\033n +; +; +MSGID_TEXTPAGE_MENUTITLES_ITALIC_SHORTHELP +Bei Auswahl werden Menütitel \033ikursiv\033n angezeigt. +;If checked, menu titles will be drawn \033iitalic\033n. +; +; +MSGID_TEXTPAGE_MENUTITLES_SHADOWED +Schattiert? +;Shadowed? +; +; +MSGID_TEXTPAGE_MENUTITLES_SHADOWED_SHORTHELP +Bei Auswahl werden Menütitel schattiert angezeigt. +;If checked, menu titles will be drawn shadowed. +; +; +MSGID_TEXTPAGE_MENUTITLES_UNDERLINED +\033uUnterstrichen?\033n +;\033uUnderlined?\033n +; +; +MSGID_TEXTPAGE_MENUTITLES_UNDERLINED_SHORTHELP +Bei Auswahl werden Menütitel \033uunterstrichen\033n angezeigt. +;If checked, menu titles will be drawn \033uunderlined\033n. +; +; +MSGID_TEXTPAGE_MENUTITLES_OUTLINED +Umriß? +;Outlined? +; +; +MSGID_TEXTPAGE_MENUTITLES_OUTLINED_SHORTHELP +Bei Auswahl werden Menütitel als Umriß angezeigt. +;If checked, menu titles will be drawn outlined. +; +; +MSGID_TEXTPAGE_MENUTITLES_BOLD +\033bFett?\033n +;\033bBold?\033n +; +; +MSGID_TEXTPAGE_MENUTITLES_BOLD_SHORTHELP +Bei Auswahl werden Menütitel \033bfett\033n angezeigt. +;If checked, menu titles will be drawn \033bbold\033n. +; +; +MSGID_TEXTPAGE_MENUTITLES_EMBOSSED +Geprägt? +;Embossed? +; +; +MSGID_TEXTPAGE_MENUTITLES_EMBOSSED_SHORTHELP +Bei Auswahl werden Menütitel geprägt angezeigt. +;If checked, menu titles will be drawn embossed. +; +; +MSGID_TEXTPAGE_MENUITEMS_ITALIC +\033iKursiv?\033n +;\33iItalic?\033n +; +; +MSGID_TEXTPAGE_MENUITEMS_ITALIC_SHORTHELP +Bei Auswahl werden Menüpunkte \033ikursiv\033n angezeigt. +;If checked, menu items will be drawn \033iitalic\033n. +; +; +MSGID_TEXTPAGE_MENUITEMS_SHADOWED +Schattiert? +;Shadowed? +; +; +MSGID_TEXTPAGE_MENUITEMS_SHADOWED_SHORTHELP +Bei Auswahl werden Menüpunkte schattiert angezeigt. +;If checked, menu items will be drawn shadowed. +; +; +MSGID_TEXTPAGE_MENUITEMS_UNDERLINED +\033uUnterstrichen?\033n +;\033uUnderlined?\033n +; +; +MSGID_TEXTPAGE_MENUITEMS_UNDERLINED_SHORTHELP +Bei Auswahl werden Menüpunkte \033uunterstrichen\033n angezeigt. +;If checked, menu items will be drawn \033uunderlined\033n. +; +; +MSGID_TEXTPAGE_MENUITEMS_OUTLINED +Umriß? +;Outlined? +; +; +MSGID_TEXTPAGE_MENUITEMS_OUTLINED_SHORTHELP +Bei Auswahl werden Menüpunkte als Umriß angezeigt. +;If checked, menu items will be drawn outlined. +; +; +MSGID_TEXTPAGE_MENUITEMS_BOLD +\033bFett?\033n +;\033bBold?\033n +; +; +MSGID_TEXTPAGE_MENUITEMS_BOLD_SHORTHELP +Bei Auswahl werden Menüpunkte \033bfett\033n angezeigt. +;If checked, menu items will be drawn \033bbold\033n. +; +; +MSGID_TEXTPAGE_MENUITEMS_EMBOSSED +Geprägt? +;Embossed? +; +; +MSGID_TEXTPAGE_MENUITEMS_EMBOSSED_SHORTHELP +Bei Auswahl werden Menüpunkte geprägt angezeigt. +;If checked, menu items will be drawn embossed. +; +;----------------------------------------------------------- +; +MSGID_TRANSPARENCYPAGE_TITLE +Transparenz +;Transparency +; +; +MSGID_TRANSPARENCYPAGE_TRANSP_NUMERIC_FORMAT +%ld %% +;%ld %% +; +; +MSGID_TRANSPARENCYPAGE_TRANSPARENCY +Transparenz +;Transparency +; +; +MSGID_TRANSPARENCYPAGE_BLUR +Verwischen +;Blur +; +; +MSGID_TRANSPARENCYPAGE_BLUR_SHORTHELP +Hier wird eingestellt, wie stark der durchscheinende\n\ +Hintergrund bei transparenten Popupmenüs\n\ +verwaschen dargestellt wird. +;Here you can adjust the degree of blurring which is aplied\n\ +;to the background shining through transparent popup menus. +; +; +MSGID_TRANSPARENCYPAGE_BLUR_NUMERIC_FORMAT +%ld %% +;%ld %% +; +; +MSGID_TRANSPARENCYPAGE_ENABLE +Transparente Menüs? +;Transparent Menus? +; +; +MSGID_TRANSPARENCYPAGE_ENABLE_SHORTHELP +Wenn ausgewählt, werden Popupmenüs durchsichtig\n\ +mit durchscheinendem Hintergrund angezeigt. +;If checked, popup menus are transparent, with\n\ +;the contents behind shining through. +; +;----------------------------------------------------------- +; diff --git a/scalos/Plugins/Prefs/Popupmenu/Catalogs/deutsch/Scalos/config.mk b/scalos/Plugins/Prefs/Popupmenu/Catalogs/deutsch/Scalos/config.mk new file mode 100755 index 000000000..eea01119f --- /dev/null +++ b/scalos/Plugins/Prefs/Popupmenu/Catalogs/deutsch/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = deutsch + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = german + +else + +############################################################################### +# AmigaOS + +LANG = deutsch + +endif +endif diff --git a/scalos/Plugins/Prefs/Popupmenu/Catalogs/deutsch/Scalos/makefile b/scalos/Plugins/Prefs/Popupmenu/Catalogs/deutsch/Scalos/makefile new file mode 100644 index 000000000..771ba71f7 --- /dev/null +++ b/scalos/Plugins/Prefs/Popupmenu/Catalogs/deutsch/Scalos/makefile @@ -0,0 +1,13 @@ +# makefile for Scalos (translated Texts : deutsch) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mdeutsch\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +ScalosPopupMenu.catalog : ScalosPopupMenu.ct ../../../ScalosPopupMenu.cd + +All: ScalosPopupMenu.catalog diff --git a/scalos/Plugins/Prefs/Popupmenu/Catalogs/deutsch/Scalos/makefile-new b/scalos/Plugins/Prefs/Popupmenu/Catalogs/deutsch/Scalos/makefile-new new file mode 100755 index 000000000..1314c9ae9 --- /dev/null +++ b/scalos/Plugins/Prefs/Popupmenu/Catalogs/deutsch/Scalos/makefile-new @@ -0,0 +1,32 @@ +# makefile for ScalosMenu (translated Texts : deutsch) +# $Date: 2011-08-09 11:15:58 +0200 (Di, 09. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = ScalosPopupMenu + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git "a/scalos/Plugins/Prefs/Popupmenu/Catalogs/fran\303\247ais/Scalos/ScalosPopupMenu.ct" "b/scalos/Plugins/Prefs/Popupmenu/Catalogs/fran\303\247ais/Scalos/ScalosPopupMenu.ct" new file mode 100644 index 000000000..a3397a6e1 --- /dev/null +++ "b/scalos/Plugins/Prefs/Popupmenu/Catalogs/fran\303\247ais/Scalos/ScalosPopupMenu.ct" @@ -0,0 +1,619 @@ +; ScalosPopupMenu.ct +; $Date$ +; $Revision$ +; $Id$ +## version $VER: ScalosPopupMenu.catalog 40.1 (10 Jan 2010 14:32:34) +## codeset 0 +## language français +; +;#arrayopts static __far +; +; +;--------------------------------------------- +; +MSGID_PLUGIN_LIST_TITLE +Menu Popup +;PopupMenu +; +; +MSGID_TITLENAME +Scalos: PopupMenu Plugin Prefs +;Scalos PopupMenu Prefs Plugin +; +;--------------------------------------------- +; +MSGID_MENU_PROJECT_OPEN +Ouvrir... +;Open... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +O +;O +; +; +MSGID_MENU_PROJECT_SAVEAS +Sauver sous... +;Save As... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +S +;A +; +; +MSGID_MENU_PROJECT_ABOUT +A propos... +;About... +; +; +MSGID_MENU_PROJECT_QUIT +Quitter +;Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +;Q +; +; +MSGID_MENU_PROJECT +Projet +;Project +; +; +MSGID_MENU_EDIT_LASTSAVED +Dernière sauvegarde +;Last Saved +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +L +;L +; +; +MSGID_MENU_EDIT +Edition +;Edit +; +; +MSGID_MENU_SETTINGS_CREATEICONS +Créer une icône ? +;Create Icons? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +I +;I +; +; +MSGID_MENU_SETTINGS +Options +;Settings +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +Réglages par défaut +;Reset To Defaults +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +D +;D +; +; +MSGID_MENU_EDIT_RESTORE +Restaurer +;Restore +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +R +;R +; +; +MSGID_MENU_PROJECT_ABOUTMUI +A propos de MUI... +;About MUI... +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +_D'accord +;_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos PopupMenu: Préferences V%ld.%ld\033n\n\ +%s\n\ +;© 2006%s The Scalos Team +;\33c\033bScalos PopupMenu Preferences V%ld.%ld\033n\n\ +;%s\n\ +;© 2006%s The Scalos Team +; +;--------------------------------------------- +; +MSGID_SHORTHELP_SAVEBUTTON +Cliquez sur ce bouton pour sauvegarder \n\ +en permanence, les options courrantes dans\n\ +\"ENVARC:sys/PopupMenu.prefs\"\n\ +and make changes permanent. +;Press this button to save \n\ +;the current settings to\n\ +;\"ENVARC:sys/PopupMenu.prefs\"\n\ +;and make changes permanent. +; +MSGID_SHORTHELP_USEBUTTON +Cliquez sur ce bouton pour sauvegarder \n\ +les options courrantes dans\n\ +\"ENV:sys/PopupMenu.prefs\"\n\ +et préserver les options jusqu'au prochain démarrage. +;Press this button to save \n\ +;the current settings to\n\ +;\"ENV:sys/PopupMenu.prefs\"\n\ +;and keep settings until reboot. +; +MSGID_SHORTHELP_CANCELBUTTON +Cliquez sur ce bouton afin d'annuler \n\ +et oublier tout changement. +;Press this button to abort \n\ +;and forget all changes. +; +;--------------------------------------------- +; +MSGID_REQTITLE_SAVEERROR +Erreur durant l'écriture des préférences PopupMenu\n\ +fichier \"%s\"\n\ +%s +;Error writing PopupMenu preferences\n\ +;file \"%s\"\n\ +;%s +; +MSGID_REQTITLE_READERROR +Erreur de lecture des péférences PopupMenu\n\ +fichier \"%s\"\n\ +%s +;Error reading PopupMenu preferences\n\ +;file \"%s\"\n\ +;%s +; +;--------------------------------------------- +; +MSGID_POPUP_ASLTITLE_MENUPLUGIN +Sélection des préférences PopupMenu de Scalos +;Select Scalos PopupMenu prefs +; +MSGID_SHORTHELP_LAMP_CHANGED +Cette lampe indicatrice change de l'état \033bEteind\033n\n\ +en \033bAllumé\033n quand les options ont été\n\ +modifiées aprés le chargement initial. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Le démarrage des préférences PopupMenu de Scalos a échoué +;Scalos PopupMenu Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Recommencer|Quitter +;Try again|Quit +; +MSGID_STARTUP_MCC_NOT_FOUND +Impossible d'ouvrir la classe MUI '%s' V%lu.%lu.\n\ +La classe n'est pas installée. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +MSGID_STARTUP_OLD_MCC +Impossible d'ouvrir la classe MUI '%s' V%lu.%lu.\n\ +\n\ +Version actuellement installée : V%lu.%lu, mettez la à jour s'il vous plaît ! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +MSGID_STARTUP_MCC_IN_USE +Impossible d'ouvrir la classe MUI '%s' V%lu.%lu.\n\ +%lu.%lu est actuellement utilisée par une autre application.\n\ +\n\ +Une fois la version requise installée,\n\ +fermez tous les programmes MUI, soyez sûr que l'ancienne classe\n\ +ne soit plus en mémoire et recommencez. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_PREFSPAGES_MISC +Divers. +;Misc. +; +; +MSGID_PREFSPAGES_BORDERS +Bords +;Borders +; +; +MSGID_PREFSPAGES_SPACING +Espacement +;Spacing +; +; +MSGID_PREFSPAGES_TEXT +Texte +;Text +; +; +MSGID_PREFSPAGES_TRANSPARENCY +Transparence +;Transparency +; +;----------------------------------------------------------- +; +MSGID_MISCPAGE_TITLE +Divers +;Miscellaneous +; +; +MSGID_MISCPAGE_ANIMATION_TYPE +Type : +;Type: +; +; +MSGID_MISCPAGE_ANIMATION_TYPE_SHORTHELP +Choix du type d'animation. +;Select the type of animation\n\ +;used to open the popup menu. +; +; +MSGID_MISCPAGE_ANIMATION +Animation +;Animation +; +; +MSGID_MISCPAGE_DELAY_SUBMENUS +Délai des sous-menus : +;Delay for submenus: +; +;+++translateme+++ +MSGID_MISCPAGE_DELAY_SUBMENUS_SHORTHELP +Here you can adjust how long it will take\n\ +until the submenu opens when you move the\n\ +mouse of the submenu item. +;Here you can adjust how long it will take\n\ +;until the submenu opens when you move the\n\ +;mouse of the submenu item. +; +; +MSGID_MISCPAGE_MENUSHADOWS +Menu ombragés ? +;Menu Shadows? +; +;+++translateme+++ +MSGID_MISCPAGE_MENUSHADOWS_SHORTHELP +Select here whether popup menus\n\ +will have a drop-shadow. +;Select here whether popup menus\n\ +;will have a drop-shadow. +; +;+++translateme+++ +MSGID_MISCPAGE_STICKY +Sticky ? +;Sticky? +; +;+++translateme+++ +MSGID_MISCPAGE_STICKY_SHORTHELP +Select here whether popup menus will behave sticky,\n\ +i.e. will stay open after you release the right mouse\n\ +button. +;Select here whether popup menus will behave sticky,\n\ +;i.e. will stay open after you release the right mouse\n\ +;button. +; +; +MSGID_MISCPAGE_REALSHADOWS +Ombres réelles ? +;Real Shadows? +; +;+++translateme+++ +MSGID_MISCPAGE_REALSHADOWS_SHORTHELP +If selected, realistic and translucent dropshadows\n\ +are drawn (required graphics board and hi-colour\n\ +or true-colour screen). +;If selected, realistic and translucent dropshadows\n\ +;are drawn (required graphics board and hi-colour\n\ +;or true-colour screen). +; +; +MSGID_ANIMATION_NONE +Rien +;None +; +; +MSGID_ANIMATION_ZOOM +Zoom +;Zoom +; +; +MSGID_ANIMATION_FADE +Fondu +;Fade +; +; +MSGID_ANIMATION_EXPLODE +Explosion +;Explode +; +;----------------------------------------------------------- +; +MSGID_BORDERSPAGE_TITLE +Bords du menu +;Menu Border +; +; +MSGID_BORDERSPAGE_MENUBORDER +Bords du menu +;Menu Border +; +; +MSGID_BORDERSPAGE_SELECTEDITEM +Elément sélectionné +;Selected Item +; +; +MSGID_BORDERSPAGE_SEPARATORS +Séparateurs +;Separators +; +; +MSGID_BORDERSPAGE_NORMAL +Normal +;Normal +; +; +MSGID_BORDERSPAGE_RAISED +Soulevé +;Raised +; +; +MSGID_BORDERSPAGE_RECESSED +Enfoncé +;Recessed +; +; +MSGID_BORDERSPAGE_NEW_LOOK +Nouvel aspect +;New Look +; +; +MSGID_BORDERSPAGE_OLD_LOOK +Ancien aspect +;Old Look +; +;----------------------------------------------------------- +; +MSGID_SPACINGPAGE_TITLE +Espacement +;Spacing +; +;+++translateme+++ +MSGID_SPACINGPAGE_HORIZONTAL_SPACE +Horizontal inner spacing +;Horizontal inner spacing +; +;+++translateme+++ +MSGID_SPACINGPAGE_VERTICAL_SPACE +Vertical spacing +;Vertical spacing +; +;+++translateme+++ +MSGID_SPACINGPAGE_HORIZONTAL +Horizontal outer spacing +;Horizontal outer spacing +; +;+++translateme+++ +MSGID_SPACINGPAGE_VERTICAL_OFFSET +Vertical offset +;Vertical offset +; +;+++translateme+++ +MSGID_SPACINGPAGE_INTERMEDIATE_SPACING +Intermediate spacing +;Intermediate spacing +; +;+++translateme+++ +MSGID_SPACINGPAGE_TEXT_DISPLACEMENT +Text displacement +;Text displacement +; +;----------------------------------------------------------- +; +MSGID_TEXTPAGE_TITLE +Styles de texte +;Text styles +; +; +MSGID_TEXTPAGE_MENU_TITLES +Titres des menus +;Menu Titles +; +; +MSGID_TEXTPAGE_MENU_ITEMS +Eléments des menu +;Menu Items +; +; +MSGID_TEXTPAGE_MENUTITLES_ITALIC +\033iItalique ?\033n +;\033iItalic?\033n +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUTITLES_ITALIC_SHORTHELP +If checked, menu titles will be drawn \033iitalic\033n. +;If checked, menu titles will be drawn \033iitalic\033n. +; +; +MSGID_TEXTPAGE_MENUTITLES_SHADOWED +Ombré ? +;Shadowed? +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUTITLES_SHADOWED_SHORTHELP +If checked, menu titles will be drawn shadowed. +;If checked, menu titles will be drawn shadowed. +; +; +MSGID_TEXTPAGE_MENUTITLES_UNDERLINED +\033uSousligné ?\033n +;\033uUnderlined?\033n +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUTITLES_UNDERLINED_SHORTHELP +If checked, menu titles will be drawn \033uunderlined\033n. +;If checked, menu titles will be drawn \033uunderlined\033n. +; +; +MSGID_TEXTPAGE_MENUTITLES_OUTLINED +Entouré ? +;Outlined? +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUTITLES_OUTLINED_SHORTHELP +If checked, menu titles will be drawn outlined. +;If checked, menu titles will be drawn outlined. +; +; +MSGID_TEXTPAGE_MENUTITLES_BOLD +\033bGras ?\033n +;\033bBold?\033n +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUTITLES_BOLD_SHORTHELP +If checked, menu titles will be drawn \033bbold\033n. +;If checked, menu titles will be drawn \033bbold\033n. +; +; +MSGID_TEXTPAGE_MENUTITLES_EMBOSSED +En relief ? +;Embossed? +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUTITLES_EMBOSSED_SHORTHELP +If checked, menu titles will be drawn embossed. +;If checked, menu titles will be drawn embossed. +; +; +MSGID_TEXTPAGE_MENUITEMS_ITALIC +\033iItalique ?\033n +;\033iItalic?\033n +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUITEMS_ITALIC_SHORTHELP +If checked, menu items will be drawn \033iitalic\033n. +;If checked, menu items will be drawn \033iitalic\033n. +; +; +MSGID_TEXTPAGE_MENUITEMS_SHADOWED +Ombré ? +;Shadowed? +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUITEMS_SHADOWED_SHORTHELP +If checked, menu items will be drawn shadowed. +;If checked, menu items will be drawn shadowed. +; +; +MSGID_TEXTPAGE_MENUITEMS_UNDERLINED +\033uSousligné ?\033n +;\033uUnderlined?\033n +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUITEMS_UNDERLINED_SHORTHELP +If checked, menu items will be drawn \033uunderlined\033n. +;If checked, menu items will be drawn \033uunderlined\033n. +; +; +MSGID_TEXTPAGE_MENUITEMS_OUTLINED +Entouré ? +;Outlined? +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUITEMS_OUTLINED_SHORTHELP +If checked, menu items will be drawn outlined. +;If checked, menu items will be drawn outlined. +; +; +MSGID_TEXTPAGE_MENUITEMS_BOLD +\033bGras ?\033n +;\033bBold?\033n +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUITEMS_BOLD_SHORTHELP +If checked, menu items will be drawn \033bbold\033n. +;If checked, menu items will be drawn \033bbold\033n. +; +; +MSGID_TEXTPAGE_MENUITEMS_EMBOSSED +En relief ? +;Embossed? +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUITEMS_EMBOSSED_SHORTHELP +If checked, menu items will be drawn embossed. +;If checked, menu items will be drawn embossed. +; +;----------------------------------------------------------- +; +MSGID_TRANSPARENCYPAGE_TITLE +Transparence +;Transparency +; +; +MSGID_TRANSPARENCYPAGE_TRANSP_NUMERIC_FORMAT +%ld %% +;%ld %% +; +; +MSGID_TRANSPARENCYPAGE_TRANSPARENCY +Transparence +;Transparency +; +; +MSGID_TRANSPARENCYPAGE_BLUR +Estomper +;Blur +; +;+++translateme+++ +MSGID_TRANSPARENCYPAGE_BLUR_SHORTHELP +Here you can adjust the degree of blurring which is aplied\n\ +to the background shining through transparent popup menus. +;Here you can adjust the degree of blurring which is aplied\n\ +;to the background shining through transparent popup menus. +; +; +MSGID_TRANSPARENCYPAGE_BLUR_NUMERIC_FORMAT +%ld %% +;%ld %% +; +; +MSGID_TRANSPARENCYPAGE_ENABLE +Transparent Menus? +;Transparent Menus? +; +;+++translateme+++ +MSGID_TRANSPARENCYPAGE_ENABLE_SHORTHELP +If checked, popup menus are transparent, with\n\ +the contents behind shining through. +;If checked, popup menus are transparent, with\n\ +;the contents behind shining through. +; +;----------------------------------------------------------- +; diff --git "a/scalos/Plugins/Prefs/Popupmenu/Catalogs/fran\303\247ais/Scalos/config.mk" "b/scalos/Plugins/Prefs/Popupmenu/Catalogs/fran\303\247ais/Scalos/config.mk" new file mode 100755 index 000000000..1b4cabf68 --- /dev/null +++ "b/scalos/Plugins/Prefs/Popupmenu/Catalogs/fran\303\247ais/Scalos/config.mk" @@ -0,0 +1,40 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = français + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = french + +else + +############################################################################### +# AmigaOS and AROS + +LANG = français + +endif +endif diff --git "a/scalos/Plugins/Prefs/Popupmenu/Catalogs/fran\303\247ais/Scalos/makefile" "b/scalos/Plugins/Prefs/Popupmenu/Catalogs/fran\303\247ais/Scalos/makefile" new file mode 100644 index 000000000..adc564677 --- /dev/null +++ "b/scalos/Plugins/Prefs/Popupmenu/Catalogs/fran\303\247ais/Scalos/makefile" @@ -0,0 +1,13 @@ +# makefile for Scalos (translated Texts : français) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mfrançais\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +ScalosPopupMenu.catalog : ScalosPopupMenu.ct ../../../ScalosPopupMenu.cd + +All: ScalosPopupMenu.catalog diff --git "a/scalos/Plugins/Prefs/Popupmenu/Catalogs/fran\303\247ais/Scalos/makefile-new" "b/scalos/Plugins/Prefs/Popupmenu/Catalogs/fran\303\247ais/Scalos/makefile-new" new file mode 100755 index 000000000..6164bab51 --- /dev/null +++ "b/scalos/Plugins/Prefs/Popupmenu/Catalogs/fran\303\247ais/Scalos/makefile-new" @@ -0,0 +1,32 @@ +# makefile for ScalosMenu (translated Texts : dansk) +# $Date: 2011-08-09 11:15:58 +0200 (Di, 09. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = ScalosPopupMenu + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Plugins/Prefs/Popupmenu/Catalogs/sample/Scalos/ScalosPopupMenu.ct b/scalos/Plugins/Prefs/Popupmenu/Catalogs/sample/Scalos/ScalosPopupMenu.ct new file mode 100644 index 000000000..1553fc864 --- /dev/null +++ b/scalos/Plugins/Prefs/Popupmenu/Catalogs/sample/Scalos/ScalosPopupMenu.ct @@ -0,0 +1,626 @@ +; ScalosPopupMenu.ct +; $Date$ +; $Revision$ +## version $VER: ScalosPopupMenu.catalog 40.1 (10 Jan 2010 14:32:34) +## codeset 0s +## language xxxxxx +; +;#arrayopts static __far +; +; +;--------------------------------------------- +;+++translateme+++ +MSGID_PLUGIN_LIST_TITLE +PopupMenu +;PopupMenu +; +;+++translateme+++ +MSGID_TITLENAME +Scalos PopupMenu Prefs Plugin +;Scalos PopupMenu Prefs Plugin +; +;--------------------------------------------- +;+++translateme+++ +MSGID_MENU_PROJECT_OPEN +Open... +;Open... +; +;+++translateme+++ +MSGID_MENU_PROJECT_OPEN_SHORT +O +;O +; +;+++translateme+++ +MSGID_MENU_PROJECT_SAVEAS +Save As... +;Save As... +; +;+++translateme+++ +MSGID_MENU_PROJECT_SAVEAS_SHORT +A +;A +; +;+++translateme+++ +MSGID_MENU_PROJECT_ABOUT +About... +;About... +; +;+++translateme+++ +MSGID_MENU_PROJECT_QUIT +Quit +;Quit +; +;+++translateme+++ +MSGID_MENU_PROJECT_QUIT_SHORT +Q +;Q +; +;+++translateme+++ +MSGID_MENU_PROJECT +Project +;Project +; +;+++translateme+++ +MSGID_MENU_EDIT_LASTSAVED +Last Saved +;Last Saved +; +;+++translateme+++ +MSGID_MENU_EDIT_LASTSAVED_SHORT +L +;L +; +;+++translateme+++ +MSGID_MENU_EDIT +Edit +;Edit +; +;+++translateme+++ +MSGID_MENU_SETTINGS_CREATEICONS +Create Icons? +;Create Icons? +; +;+++translateme+++ +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +I +;I +; +;+++translateme+++ +MSGID_MENU_SETTINGS +Settings +;Settings +; +;+++translateme+++ +MSGID_MENU_EDIT_RESETTODEFAULTS +Reset To Defaults +;Reset To Defaults +; +;+++translateme+++ +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +D +;D +; +;+++translateme+++ +MSGID_MENU_EDIT_RESTORE +Restore +;Restore +; +;+++translateme+++ +MSGID_MENU_EDIT_RESTORE_SHORT +R +;R +; +;+++translateme+++ +MSGID_MENU_PROJECT_ABOUTMUI +About MUI... +;About MUI... +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_ABOUTREQOK +_OK +;_OK +; +;+++translateme+++ +MSGID_ABOUTREQFORMAT +\33c\033bScalos PopupMenu Preferences V%ld.%ld\033n\n\ +%s\n\ +;© 2006%s The Scalos Team +;\33c\033bScalos PopupMenu Preferences V%ld.%ld\033n\n\ +;%s\n\ +;© 2006%s The Scalos Team +; +;--------------------------------------------- +;+++translateme+++ +MSGID_SHORTHELP_SAVEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENVARC:sys/PopupMenu.prefs\"\n\ +and make changes permanent. +;Press this button to save \n\ +;the current settings to\n\ +;\"ENVARC:sys/PopupMenu.prefs\"\n\ +;and make changes permanent. +; +;+++translateme+++ +MSGID_SHORTHELP_USEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENV:sys/PopupMenu.prefs\"\n\ +and keep settings until reboot. +;Press this button to save \n\ +;the current settings to\n\ +;\"ENV:sys/PopupMenu.prefs\"\n\ +;and keep settings until reboot. +; +;+++translateme+++ +MSGID_SHORTHELP_CANCELBUTTON +Press this button to abort \n\ +and forget all changes. +;Press this button to abort \n\ +;and forget all changes. +; +;--------------------------------------------- +;+++translateme+++ +MSGID_REQTITLE_SAVEERROR +Error writing PopupMenu preferences\n\ +file \"%s\"\n\ +%s +;Error writing PopupMenu preferences\n\ +;file \"%s\"\n\ +;%s +; +;+++translateme+++ +MSGID_REQTITLE_READERROR +Error reading PopupMenu preferences\n\ +file \"%s\"\n\ +%s +;Error reading PopupMenu preferences\n\ +;file \"%s\"\n\ +;%s +; +;--------------------------------------------- +;+++translateme+++ +MSGID_POPUP_ASLTITLE_MENUPLUGIN +Select Scalos PopupMenu prefs +;Select Scalos PopupMenu prefs +; +;+++translateme+++ +MSGID_SHORTHELP_LAMP_CHANGED +This lamp indicator changes from \033bOff\033n\n\ +to \033bOk\033n when the settings have been\n\ +modified since initial loading. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_STARTUP_FAILURE +Scalos PopupMenu Prefs startup failed +;Scalos PopupMenu Prefs startup failed +; +;+++translateme+++ +MSGID_STARTUP_RETRY_QUIT_GAD +Try again|Quit +;Try again|Quit +; +;+++translateme+++ +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +;+++translateme+++ +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +;+++translateme+++ +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_PREFSPAGES_MISC +Misc. +;Misc. +; +;+++translateme+++ +MSGID_PREFSPAGES_BORDERS +Borders +;Borders +; +;+++translateme+++ +MSGID_PREFSPAGES_SPACING +Spacing +;Spacing +; +;+++translateme+++ +MSGID_PREFSPAGES_TEXT +Text +;Text +; +;+++translateme+++ +MSGID_PREFSPAGES_TRANSPARENCY +Transparency +;Transparency +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_MISCPAGE_TITLE +Miscellaneous +;Miscellaneous +; +;+++translateme+++ +MSGID_MISCPAGE_ANIMATION_TYPE +Type: +;Type: +; +;+++translateme+++ +MSGID_MISCPAGE_ANIMATION_TYPE_SHORTHELP +Select the type of animation\n\ +used to open the popup menu. +;Select the type of animation\n\ +;used to open the popup menu. +; +;+++translateme+++ +MSGID_MISCPAGE_ANIMATION +Animation +;Animation +; +;+++translateme+++ +MSGID_MISCPAGE_DELAY_SUBMENUS +Delay for submenus: +;Delay for submenus: +; +;+++translateme+++ +MSGID_MISCPAGE_DELAY_SUBMENUS_SHORTHELP +Here you can adjust how long it will take\n\ +until the submenu opens when you move the\n\ +mouse of the submenu item. +;Here you can adjust how long it will take\n\ +;until the submenu opens when you move the\n\ +;mouse of the submenu item. +; +;+++translateme+++ +MSGID_MISCPAGE_MENUSHADOWS +Menu Shadows? +;Menu Shadows? +; +;+++translateme+++ +MSGID_MISCPAGE_MENUSHADOWS_SHORTHELP +Select here whether popup menus\n\ +will have a drop-shadow. +;Select here whether popup menus\n\ +;will have a drop-shadow. +; +;+++translateme+++ +MSGID_MISCPAGE_STICKY +Sticky? +;Sticky? +; +;+++translateme+++ +MSGID_MISCPAGE_STICKY_SHORTHELP +Select here whether popup menus will behave sticky,\n\ +i.e. will stay open after you release the right mouse\n\ +button. +;Select here whether popup menus will behave sticky,\n\ +;i.e. will stay open after you release the right mouse\n\ +;button. +; +;+++translateme+++ +MSGID_MISCPAGE_REALSHADOWS +Real Shadows? +;Real Shadows? +; +;+++translateme+++ +MSGID_MISCPAGE_REALSHADOWS_SHORTHELP +If selected, realistic and translucent dropshadows\n\ +are drawn (required graphics board and hi-colour\n\ +or true-colour screen). +;If selected, realistic and translucent dropshadows\n\ +;are drawn (required graphics board and hi-colour\n\ +;or true-colour screen). +; +;+++translateme+++ +MSGID_ANIMATION_NONE +None +;None +; +;+++translateme+++ +MSGID_ANIMATION_ZOOM +Zoom +;Zoom +; +;+++translateme+++ +MSGID_ANIMATION_FADE +Fade +;Fade +; +;+++translateme+++ +MSGID_ANIMATION_EXPLODE +Explode +;Explode +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_BORDERSPAGE_TITLE +Menu Border +;Menu Border +; +;+++translateme+++ +MSGID_BORDERSPAGE_MENUBORDER +Menu Border +;Menu Border +; +;+++translateme+++ +MSGID_BORDERSPAGE_SELECTEDITEM +Selected Item +;Selected Item +; +;+++translateme+++ +MSGID_BORDERSPAGE_SEPARATORS +Separators +;Separators +; +;+++translateme+++ +MSGID_BORDERSPAGE_NORMAL +Normal +;Normal +; +;+++translateme+++ +MSGID_BORDERSPAGE_RAISED +Raised +;Raised +; +;+++translateme+++ +MSGID_BORDERSPAGE_RECESSED +Recessed +;Recessed +; +;+++translateme+++ +MSGID_BORDERSPAGE_NEW_LOOK +New Look +;New Look +; +;+++translateme+++ +MSGID_BORDERSPAGE_OLD_LOOK +Old Look +;Old Look +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_SPACINGPAGE_TITLE +Spacing +;Spacing +; +;+++translateme+++ +MSGID_SPACINGPAGE_HORIZONTAL_SPACE +Horizontal inner spacing +;Horizontal inner spacing +; +;+++translateme+++ +MSGID_SPACINGPAGE_VERTICAL_SPACE +Vertical spacing +;Vertical spacing +; +;+++translateme+++ +MSGID_SPACINGPAGE_HORIZONTAL +Horizontal outer spacing +;Horizontal outer spacing +; +;+++translateme+++ +MSGID_SPACINGPAGE_VERTICAL_OFFSET +Vertical offset +;Vertical offset +; +;+++translateme+++ +MSGID_SPACINGPAGE_INTERMEDIATE_SPACING +Intermediate spacing +;Intermediate spacing +; +;+++translateme+++ +MSGID_SPACINGPAGE_TEXT_DISPLACEMENT +Text displacement +;Text displacement +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_TEXTPAGE_TITLE +Text styles +;Text styles +; +;+++translateme+++ +MSGID_TEXTPAGE_MENU_TITLES +Menu Titles +;Menu Titles +; +;+++translateme+++ +MSGID_TEXTPAGE_MENU_ITEMS +Menu Items +;Menu Items +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUTITLES_ITALIC +\033iItalic?\033n +;\033iItalic?\033n +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUTITLES_ITALIC_SHORTHELP +If checked, menu titles will be drawn \033iitalic\033n. +;If checked, menu titles will be drawn \033iitalic\033n. +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUTITLES_SHADOWED +Shadowed? +;Shadowed? +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUTITLES_SHADOWED_SHORTHELP +If checked, menu titles will be drawn shadowed. +;If checked, menu titles will be drawn shadowed. +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUTITLES_UNDERLINED +\033uUnderlined?\033n +;\033uUnderlined?\033n +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUTITLES_UNDERLINED_SHORTHELP +If checked, menu titles will be drawn \033uunderlined\033n. +;If checked, menu titles will be drawn \033uunderlined\033n. +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUTITLES_OUTLINED +Outlined? +;Outlined? +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUTITLES_OUTLINED_SHORTHELP +If checked, menu titles will be drawn outlined. +;If checked, menu titles will be drawn outlined. +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUTITLES_BOLD +\033bBold?\033n +;\033bBold?\033n +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUTITLES_BOLD_SHORTHELP +If checked, menu titles will be drawn \033bbold\033n. +;If checked, menu titles will be drawn \033bbold\033n. +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUTITLES_EMBOSSED +Embossed? +;Embossed? +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUTITLES_EMBOSSED_SHORTHELP +If checked, menu titles will be drawn embossed. +;If checked, menu titles will be drawn embossed. +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUITEMS_ITALIC +\033iItalic?\033n +;\033iItalic?\033n +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUITEMS_ITALIC_SHORTHELP +If checked, menu items will be drawn \033iitalic\033n. +;If checked, menu items will be drawn \033iitalic\033n. +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUITEMS_SHADOWED +Shadowed? +;Shadowed? +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUITEMS_SHADOWED_SHORTHELP +If checked, menu items will be drawn shadowed. +;If checked, menu items will be drawn shadowed. +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUITEMS_UNDERLINED +\033uUnderlined?\033n +;\033uUnderlined?\033n +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUITEMS_UNDERLINED_SHORTHELP +If checked, menu items will be drawn \033uunderlined\033n. +;If checked, menu items will be drawn \033uunderlined\033n. +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUITEMS_OUTLINED +Outlined? +;Outlined? +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUITEMS_OUTLINED_SHORTHELP +If checked, menu items will be drawn outlined. +;If checked, menu items will be drawn outlined. +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUITEMS_BOLD +\033bBold?\033n +;\033bBold?\033n +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUITEMS_BOLD_SHORTHELP +If checked, menu items will be drawn \033bbold\033n. +;If checked, menu items will be drawn \033bbold\033n. +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUITEMS_EMBOSSED +Embossed? +;Embossed? +; +;+++translateme+++ +MSGID_TEXTPAGE_MENUITEMS_EMBOSSED_SHORTHELP +If checked, menu items will be drawn embossed. +;If checked, menu items will be drawn embossed. +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_TRANSPARENCYPAGE_TITLE +Transparency +;Transparency +; +;+++translateme+++ +MSGID_TRANSPARENCYPAGE_TRANSP_NUMERIC_FORMAT +%ld %% +;%ld %% +; +;+++translateme+++ +MSGID_TRANSPARENCYPAGE_TRANSPARENCY +Transparency +;Transparency +; +;+++translateme+++ +MSGID_TRANSPARENCYPAGE_BLUR +Blur +;Blur +; +;+++translateme+++ +MSGID_TRANSPARENCYPAGE_BLUR_SHORTHELP +Here you can adjust the degree of blurring which is aplied\n\ +to the background shining through transparent popup menus. +;Here you can adjust the degree of blurring which is aplied\n\ +;to the background shining through transparent popup menus. +; +;+++translateme+++ +MSGID_TRANSPARENCYPAGE_BLUR_NUMERIC_FORMAT +%ld %% +;%ld %% +; +;+++translateme+++ +MSGID_TRANSPARENCYPAGE_ENABLE +Transparent Menus? +;Transparent Menus? +; +;+++translateme+++ +MSGID_TRANSPARENCYPAGE_ENABLE_SHORTHELP +If checked, popup menus are transparent, with\n\ +the contents behind shining through. +;If checked, popup menus are transparent, with\n\ +;the contents behind shining through. +; +;----------------------------------------------------------- +; diff --git a/scalos/Plugins/Prefs/Popupmenu/FrameButtonMCC.c b/scalos/Plugins/Prefs/Popupmenu/FrameButtonMCC.c new file mode 100644 index 000000000..9914cfb71 --- /dev/null +++ b/scalos/Plugins/Prefs/Popupmenu/FrameButtonMCC.c @@ -0,0 +1,393 @@ +// FrameButtonMCC.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include +#include +#include +#include +#define NO_INLINE_STDARG +#include + +#include + +#include +#include +#include "PopupMenuPrefs.h" +#include "FrameButtonMCC.h" + +/* ------------------------------------------------------------------------- */ + +#define CLASS MUIC_FrameButton +#define SUPERCLASS MUIC_Text + +struct FrameButtonMCCInstance +{ + ULONG FrameType; + ULONG Selected; // show frame for selected menu entries + ULONG Raised; // draw raised selected frames +}; + +/* ------------------------------------------------------------------------- */ + +static ULONG mNew(struct IClass *cl,Object *obj,Msg msg); +static ULONG mDraw(struct IClass *cl,Object *obj,struct MUIP_Draw *msg); +static void DrawBoxMM2(struct RastPort *rp, int x1, int y1, int x2, int y2, + UBYTE shine, UBYTE shadow, UBYTE halfshine); +static void DrawXENBoxMM2(struct RastPort *rp, int x1, int y1, int x2, int y2, + UBYTE shine, UBYTE shadow, UBYTE bgplus, UBYTE bgminus, UBYTE halfshine); +static void DrawBox(struct RastPort *rp, int x1, int y1, int x2, int y2, UBYTE shine, UBYTE shadow); +static void DrawIBox(struct RastPort *rp, int x1, int y1, int x2, int y2, UBYTE shine, UBYTE shadow); +static void DrawXENBox(struct RastPort *rp, int x1, int y1, int x2, int y2, + UBYTE shine, UBYTE shadow, UBYTE bgplus, UBYTE bgminus); +static void DrawDBLBox(struct RastPort *rp, int x1, int y1, int x2, int y2, UBYTE shine, UBYTE shadow); +static void DrawDropBox(struct RastPort *rp, int x1, int y1, int x2, int y2, UBYTE shine, UBYTE shadow); +DISPATCHER_PROTO(FrameButtonClass); +static ULONG mGet(Class *cl, Object *o, struct opGet *opg); +static void ClearInstanceData(struct FrameButtonMCCInstance *inst); + +/* ------------------------------------------------------------------------- */ + +static ULONG mNew(struct IClass *cl,Object *obj,Msg msg) +{ + struct FrameButtonMCCInstance *inst; + struct opSet *ops; + BOOL Success = FALSE; + + do { + obj = (Object *) DoSuperMethodA(cl, obj, msg); + if (NULL == obj) + break; + + d1(kprintf(__FUNC__ "/%ld: obj=%08lx\n", __LINE__, obj)); + + inst = INST_DATA(cl,obj); + ClearInstanceData(inst); + + ops = (struct opSet *) msg; + + inst->FrameType = GetTagData(MUIA_ScaFrameButton_FrameType, PMP_MENUBORDER_THIN, ops->ops_AttrList); + inst->Selected = GetTagData(MUIA_ScaFrameButton_Selected, FALSE, ops->ops_AttrList); + inst->Raised = GetTagData(MUIA_ScaFrameButton_Raised, FALSE, ops->ops_AttrList); + + Success = TRUE; + } while (0); + + if (!Success) + { + d1(kprintf(__FUNC__ "/%ld: obj=%08lx\n", __LINE__, obj)); + if (obj) + { + DisposeObject(obj); + obj = NULL; + } + } + + return((ULONG)obj); +} + +/* ------------------------------------------------------------------------- */ + +static ULONG mDraw(struct IClass *cl,Object *obj,struct MUIP_Draw *msg) +{ + struct FrameButtonMCCInstance *inst = INST_DATA(cl,obj); + + DoSuperMethodA(cl, obj, (Msg) msg); + + if (msg->flags & MADF_DRAWOBJECT) + { + d1(KPrintF("%s/%ld: bitmap=%08lx\n", __FUNC__, __LINE__, inst->BitMap)); + + if(inst->Selected) + { + if (PMP_MENUBORDER_MM == inst->FrameType) + { + if (inst->Raised) + { + DrawBoxMM2(_rp(obj), _mleft(obj), _mtop(obj), + _mright(obj), _mbottom(obj), + _dri(obj)->dri_Pens[HALFSHINEPEN], _dri(obj)->dri_Pens[HALFSHADOWPEN], + _dri(obj)->dri_Pens[BACKGROUNDPEN]); + } + else + { + DrawBoxMM2(_rp(obj), _mleft(obj), _mtop(obj), + _mright(obj), _mbottom(obj), + _dri(obj)->dri_Pens[HALFSHADOWPEN], _dri(obj)->dri_Pens[HALFSHINEPEN], + _dri(obj)->dri_Pens[BACKGROUNDPEN]); + } + } + else if (PMP_MENUBORDER_NONE != inst->FrameType) + { + if (inst->Raised) + { + DrawBox(_rp(obj), _mleft(obj), _mtop(obj), + _mright(obj), _mbottom(obj), + _dri(obj)->dri_Pens[HALFSHINEPEN], _dri(obj)->dri_Pens[HALFSHADOWPEN]); + } + else + { + DrawBox(_rp(obj), _mleft(obj), _mtop(obj), + _mright(obj), _mbottom(obj), + _dri(obj)->dri_Pens[HALFSHADOWPEN], _dri(obj)->dri_Pens[HALFSHINEPEN]); + } + } + } + else + { + switch(inst->FrameType) + { + case PMP_MENUBORDER_NONE: + break; + case PMP_MENUBORDER_THIN: + DrawBox(_rp(obj), _mleft(obj), _mtop(obj), + _mright(obj), _mbottom(obj), + _dri(obj)->dri_Pens[HALFSHINEPEN], _dri(obj)->dri_Pens[HALFSHADOWPEN]); + break; + case PMP_MENUBORDER_MM: + DrawXENBoxMM2(_rp(obj), _mleft(obj), _mtop(obj), + _mright(obj), _mbottom(obj), + _dri(obj)->dri_Pens[HALFSHINEPEN], _dri(obj)->dri_Pens[HALFSHADOWPEN], + _dri(obj)->dri_Pens[HALFSHINEPEN], _dri(obj)->dri_Pens[HALFSHADOWPEN], + _dri(obj)->dri_Pens[BACKGROUNDPEN]); + break; + case PMP_MENUBORDER_THICK: + DrawXENBox(_rp(obj), _mleft(obj), _mtop(obj), + _mright(obj), _mbottom(obj), + _dri(obj)->dri_Pens[HALFSHINEPEN], _dri(obj)->dri_Pens[HALFSHADOWPEN], + _dri(obj)->dri_Pens[HALFSHINEPEN], _dri(obj)->dri_Pens[HALFSHADOWPEN]); + break; + case PMP_MENUBORDER_RIDGE: + DrawDBLBox(_rp(obj), _mleft(obj), _mtop(obj), + _mright(obj), _mbottom(obj), + _dri(obj)->dri_Pens[HALFSHINEPEN], _dri(obj)->dri_Pens[HALFSHADOWPEN]); + break; + case PMP_MENUBORDER_DROPBOX: + DrawDropBox(_rp(obj), _mleft(obj), _mtop(obj), + _mright(obj), _mbottom(obj), + _dri(obj)->dri_Pens[HALFSHINEPEN], _dri(obj)->dri_Pens[HALFSHADOWPEN]); + break; + case PMP_MENUBORDER_OLDSTYLE: + DrawIBox(_rp(obj), _mleft(obj), _mtop(obj), + _mright(obj), _mbottom(obj), + 0, _dri(obj)->dri_Pens[HALFSHADOWPEN]); + break; + } + } + } + + return(0); +} + +static void DrawBoxMM2(struct RastPort *rp, int x1, int y1, int x2, int y2, + UBYTE shine, UBYTE shadow, UBYTE halfshine) +{ + SetAPen(rp, halfshine); + WritePixel(rp, x1, y2); + WritePixel(rp, x2, y1); + SetAPen(rp, shine); + Move(rp, x1, y2-1); + Draw(rp, x1, y1); + Draw(rp, x2-1, y1); + SetAPen(rp, shadow); + Move(rp, x1+1, y2); + Draw(rp, x2, y2); + Draw(rp, x2, y1+1); +} + +static void DrawXENBoxMM2(struct RastPort *rp, int x1, int y1, int x2, int y2, + UBYTE shine, UBYTE shadow, UBYTE bgplus, UBYTE bgminus, UBYTE halfshine) +{ + SetAPen(rp, shine); + Move(rp, x1, y2); + Draw(rp, x1, y1); + Draw(rp, x2, y1); + SetAPen(rp, bgplus); + Move(rp, x1+1, y2-1); + Draw(rp, x1+1, y1+1); + Draw(rp, x2-1, y1+1); + SetAPen(rp, shadow); + Move(rp, x1, y2); + Draw(rp, x2, y2); + Draw(rp, x2, y1); + SetAPen(rp, bgminus); + Move(rp, x1+1, y2-1); + Draw(rp, x2-1, y2-1); + Draw(rp, x2-1, y1+1); + SetAPen(rp, halfshine); + WritePixel(rp, x1, y2); + WritePixel(rp, x2, y1); +} + +static void DrawBox(struct RastPort *rp, int x1, int y1, int x2, int y2, UBYTE shine, UBYTE shadow) +{ + SetAPen(rp, shine); + Move(rp, x1, y2-1); + Draw(rp, x1, y1); + Draw(rp, x2-1, y1); + SetAPen(rp, shadow); + Move(rp, x1, y2); + Draw(rp, x2, y2); + Draw(rp, x2, y1); + +} + +static void DrawIBox(struct RastPort *rp, int x1, int y1, int x2, int y2, UBYTE shine, UBYTE shadow) +{ + SetAPen(rp, shadow); + Move(rp, x1, y2); + Draw(rp, x1, y1); + Draw(rp, x2, y1); + + Move(rp, x1, y2); + Draw(rp, x2, y2); + Draw(rp, x2, y1); + + Move(rp, x1+1, y1); + Draw(rp, x1+1, y2); + + Move(rp, x2-1, y1); + Draw(rp, x2-1, y2); +} + +static void DrawXENBox(struct RastPort *rp, int x1, int y1, int x2, int y2, + UBYTE shine, UBYTE shadow, UBYTE bgplus, UBYTE bgminus) +{ + SetAPen(rp, shine); + Move(rp, x1, y2); + Draw(rp, x1, y1); + Draw(rp, x2, y1); + SetAPen(rp, bgplus); + Move(rp, x1+1, y2-1); + Draw(rp, x1+1, y1+1); + Draw(rp, x2-1, y1+1); + SetAPen(rp, shadow); + Move(rp, x1, y2); + Draw(rp, x2, y2); + Draw(rp, x2, y1); + SetAPen(rp, bgminus); + Move(rp, x1+1, y2-1); + Draw(rp, x2-1, y2-1); + Draw(rp, x2-1, y1+1); +} + +static void DrawDBLBox(struct RastPort *rp, int x1, int y1, int x2, int y2, UBYTE shine, UBYTE shadow) +{ + DrawBox(rp, x1, y1, x2, y2, shine, shadow); + DrawBox(rp, x1+1, y1+1, x2-1, y2-1, shine, shadow); +} + +static void DrawDropBox(struct RastPort *rp, int x1, int y1, int x2, int y2, UBYTE shine, UBYTE shadow) +{ + SetAPen(rp, shine); + Move(rp, x1, y2-1); + Draw(rp, x1, y1); + Draw(rp, x2-1, y1); + Move(rp, x1+4, y2-3); + Draw(rp, x2-3, y2-3); + Draw(rp, x2-3, y1+4); + SetAPen(rp, shadow); + Move(rp, x1+3, y2-3); + Draw(rp, x1+3, y1+3); + Draw(rp, x2-4, y1+3); + Move(rp, x1, y2); + Draw(rp, x2, y2); + Draw(rp, x2, y1); +} + +/* ------------------------------------------------------------------------- */ + +static ULONG mGet(Class *cl, Object *o, struct opGet *opg) +{ + struct FrameButtonMCCInstance *inst = INST_DATA(cl, o); + ULONG Result = 0; + + switch (opg->opg_AttrID) + { + case MUIA_ScaFrameButton_FrameType: + *(opg->opg_Storage) = (ULONG) inst->FrameType; + Result++; + break; + case MUIA_ScaFrameButton_Selected: + *(opg->opg_Storage) = (ULONG) inst->Selected; + Result++; + break; + case MUIA_ScaFrameButton_Raised: + *(opg->opg_Storage) = (ULONG) inst->Raised; + Result++; + break; + default: + Result = DoSuperMethodA(cl, o, (Msg) opg); + } + + return Result; +} + +/* ------------------------------------------------------------------------- */ + +DISPATCHER(FrameButtonClass) +{ + ULONG Result; + + switch (msg->MethodID) + { + case OM_NEW: + d1(KPrintF("%s/%ld: OM_NEW\n", __FUNC__, __LINE__)); + Result = mNew(cl,obj,(APTR)msg); + break; + + case OM_GET: + d1(KPrintF("%s/%ld: OM_GET\n", __FUNC__, __LINE__)); + Result = mGet(cl, obj, (struct opGet *) msg); + break; + + case MUIM_Draw: + d1(KPrintF("%s/%ld: MUIM_Draw\n", __FUNC__, __LINE__)); + Result = mDraw(cl,obj,(APTR)msg); + break; + + default: + d1(KPrintF("%s/%ld: MethodID=%08lx\n", __FUNC__, __LINE__, msg->MethodID)); + Result = DoSuperMethodA(cl,obj,msg); + break; + } + + return Result; +} +DISPATCHER_END + + +static void ClearInstanceData(struct FrameButtonMCCInstance *inst) +{ + memset(inst, 0, sizeof(struct FrameButtonMCCInstance)); +} + +/* ------------------------------------------------------------------------- */ + +struct MUI_CustomClass *InitFrameButtonClass(void) +{ + return MUI_CreateCustomClass(NULL, SUPERCLASS, NULL, + sizeof(struct FrameButtonMCCInstance), DISPATCHER_REF(FrameButtonClass)); +} + +void CleanupFrameButtonClass(struct MUI_CustomClass *mcc) +{ + MUI_DeleteCustomClass(mcc); +} + +/* ------------------------------------------------------------------------- */ + + diff --git a/scalos/Plugins/Prefs/Popupmenu/FrameButtonMCC.h b/scalos/Plugins/Prefs/Popupmenu/FrameButtonMCC.h new file mode 100644 index 000000000..855c1ddae --- /dev/null +++ b/scalos/Plugins/Prefs/Popupmenu/FrameButtonMCC.h @@ -0,0 +1,49 @@ +// FrameButtonMCC.h +// $Date$ +// $Revision$ + + +#ifndef FRAMEBUTTON_MCC_H +#define FRAMEBUTTON_MCC_H + +/* ------------------------------------------------------------------------- */ + +#include + +/* ------------------------------------------------------------------------- */ + +struct MUI_CustomClass *InitFrameButtonClass(void); +void CleanupFrameButtonClass(struct MUI_CustomClass *mcc); + +/* ------------------------------------------------------------------------- */ + +extern struct MUI_CustomClass *FrameButtonClass; + +#ifdef __AROS__ +#define FrameButtonObject BOOPSIOBJMACRO_START(FrameButtonClass->mcc_Class) +#else +#define FrameButtonObject NewObject(FrameButtonClass->mcc_Class, 0 +#endif + +/* ------------------------------------------------------------------------- */ + +#define PMP_MENUBORDER_NONE 999 + +/* ------------------------------------------------------------------------- */ + +#if !defined(HALFSHINEPEN) +#define HALFSHINEPEN SHINEPEN +#define HALFSHADOWPEN SHADOWPEN +#endif /* defined(HALFSHINEPEN) */ + +/* ------------------------------------------------------------------------- */ + +#define MUIA_FRAMEBUTTON_TAGBASE 0x8042a877 + +#define MUIA_ScaFrameButton_FrameType (MUIA_FRAMEBUTTON_TAGBASE+1) // [I.G] ULONG +#define MUIA_ScaFrameButton_Selected (MUIA_FRAMEBUTTON_TAGBASE+2) // [I.G] ULONG +#define MUIA_ScaFrameButton_Raised (MUIA_FRAMEBUTTON_TAGBASE+3) // [I.G] ULONG + +/* ------------------------------------------------------------------------- */ + +#endif /* FRAMEBUTTON_MCC_H */ diff --git a/scalos/Plugins/Prefs/Popupmenu/PopupMenuPrefs.c b/scalos/Plugins/Prefs/Popupmenu/PopupMenuPrefs.c new file mode 100644 index 000000000..75c48a984 --- /dev/null +++ b/scalos/Plugins/Prefs/Popupmenu/PopupMenuPrefs.c @@ -0,0 +1,2487 @@ +// PopupMenuPrefs.c +// $Date$ +// $Revision$ + +#ifdef __AROS__ +#define MUIMASTER_YES_INLINE_STDARG +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef __AROS__ +#include +#else +#include +#endif +#include +#include +#define NO_INLINE_STDARG +#include + +#include +#include +#include +#include +#include +#include + +#include "PopupMenuPrefs.h" +#include "DataTypesMCC.h" +#include "FrameButtonMCC.h" + +#define ScalosPopupMenu_NUMBERS +#define ScalosPopupMenu_ARRAY +#define ScalosPopupMenu_CODE +#include STR(SCALOSLOCALE) + +#include "plugin.h" + +//---------------------------------------------------------------------------- + +// local data structures + +#define CheckMarkHelp(selected, HelpTextID)\ + ImageObject,\ + ImageButtonFrame,\ + MUIA_InputMode , MUIV_InputMode_Toggle,\ + MUIA_Image_Spec , MUII_CheckMark,\ + MUIA_Image_FreeVert , TRUE,\ + MUIA_Selected , selected,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShowSelState , FALSE,\ + MUIA_CycleChain , TRUE,\ + MUIA_ShortHelp , GetLocString(HelpTextID), \ + End + +#define IMG(prefix1,PREFIX2) \ + BodychunkObject,\ + MUIA_FixWidth , PREFIX2##_WIDTH ,\ + MUIA_FixHeight , PREFIX2##_HEIGHT,\ + MUIA_Bitmap_Width , PREFIX2##_WIDTH ,\ + MUIA_Bitmap_Height , PREFIX2##_HEIGHT,\ + MUIA_Bodychunk_Depth , PREFIX2##_DEPTH ,\ + MUIA_Bodychunk_Body , (UBYTE *) prefix1##_body,\ + MUIA_Bodychunk_Compression, PREFIX2##_COMPRESSION,\ + MUIA_Bodychunk_Masking , PREFIX2##_MASKING,\ + MUIA_Bitmap_SourceColors , (ULONG *) prefix1##_colors,\ + MUIA_Bitmap_Transparent , 0,\ + End + +#define KeyButtonHelp(name,key,HelpText)\ + TextObject,\ + ButtonFrame,\ + MUIA_CycleChain, TRUE, \ + MUIA_Font, MUIV_Font_Button,\ + MUIA_Text_Contents, (name),\ + MUIA_Text_PreParse, "\33c",\ + MUIA_Text_HiChar , (key),\ + MUIA_ControlChar , (key),\ + MUIA_InputMode , MUIV_InputMode_RelVerify,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShortHelp, HelpText,\ + End + +#define FrameButton(objindex, frame, text, selected, raised)\ + VGroup, \ + MUIA_ShowSelState, FALSE, \ + Child, FrameButtonObject, \ + MUIA_Frame, MUIV_Frame_None, \ + MUIA_Text_Contents, (text),\ + MUIA_Text_PreParse, "\33c", \ + MUIA_Font, MUIV_Font_Button,\ + MUIA_InputMode, MUIV_InputMode_None,\ + MUIA_Background, MUII_ButtonBack,\ + MUIA_ScaFrameButton_FrameType, (frame),\ + MUIA_ScaFrameButton_Selected, (selected), \ + MUIA_ScaFrameButton_Raised, (raised), \ + End, \ + Child, HGroup, \ + Child, HVSpace, \ + Child, inst->mpb_Objects[objindex] = ImageObject,\ + ImageButtonFrame,\ + MUIA_InputMode , MUIV_InputMode_Immediate,\ + MUIA_Image_Spec , MUII_CheckMark,\ + MUIA_Image_FreeVert , TRUE,\ + MUIA_Selected , FALSE,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShowSelState , FALSE,\ + MUIA_CycleChain , TRUE,\ + End, /* ImageObject */ \ + Child, HVSpace, \ + End, /* HGroup */ \ + End /* VGroup */ + +#define Application_Return_EDIT 0 +#define Application_Return_USE 1001 +#define Application_Return_SAVE 1002 + +//---------------------------------------------------------------------------- + +// imported from mempools.lib + +extern int _STI_240_InitMemFunctions(void); +extern void _STD_240_TerminateMemFunctions(void); + +//---------------------------------------------------------------------------- + +// local functions + +static BOOL OpenLibraries(void); +static void CloseLibraries(void); + +DISPATCHER_PROTO(PopupMenuPrefs); +static Object *CreatePrefsGroup(struct PopupMenuPrefsInst *inst); + +static SAVEDS(ULONG) INTERRUPT ImagePopAslFileStartHookFunc(struct Hook *hook, Object *o, Msg msg); + +static STRPTR GetLocString(ULONG MsgId); +static void TranslateStringArray(STRPTR *stringArray); + +static SAVEDS(APTR) INTERRUPT ResetToDefaultsHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT OpenHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT SaveAsHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT AboutHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT LastSavedHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT RestoreHookFunc(struct Hook *hook, Object *o, Msg msg); + +static SAVEDS(APTR) INTERRUPT AppMessageHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(APTR) INTERRUPT SettingsChangedHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT AslIntuiMsgHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT FrameTypeSelectHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(void) INTERRUPT SelFrameTypeSelectHookFunc(struct Hook *hook, Object *o, Msg msg); + +static LONG ReadPrefsFile(struct PopupMenuPrefsInst *inst, CONST_STRPTR FilenameOld, CONST_STRPTR FilenameNew, BOOL Quiet); +static LONG WritePrefsFile(struct PopupMenuPrefsInst *inst, CONST_STRPTR Filename); +static LONG SaveIcon(struct PopupMenuPrefsInst *inst, CONST_STRPTR IconName); +static Object *CreatePrefsImage(void); +static void InitHooks(struct PopupMenuPrefsInst *inst); +static void SetChangedFlag(struct PopupMenuPrefsInst *inst, BOOL changed); +static void ParseToolTypes(struct PopupMenuPrefsInst *inst, struct MUIP_ScalosPrefs_ParseToolTypes *ptt); +static void PrefsToGUI(struct PopupMenuPrefsInst *inst, const struct PopupMenuPrefs *pmPrefs); +static void GUItoPrefs(struct PopupMenuPrefsInst *inst, struct PopupMenuPrefs *pmPrefs); +static IPTR getv(APTR obj, ULONG attr); +static LONG ReadOldPrefsFile(CONST_STRPTR Filename, struct oldPopupMenuPrefs *prefs, const struct oldPopupMenuPrefs *defaultPrefs); +static void ConvertPmPrefs(CONST_STRPTR prefsFileOld, CONST_STRPTR prefsFileNew); + +#if !defined(__SASC) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) +static size_t stccpy(char *dest, const char *src, size_t MaxLen); +#endif /* !defined(__SASC) && !defined(__MORPHOS__) && !defined(__amigaos4__) */ + +//---------------------------------------------------------------------------- + +// local data items + +struct Library *MUIMasterBase; +T_LOCALEBASE LocaleBase; +struct GfxBase *GfxBase; +struct Library *IconBase; +struct Library *IFFParseBase; +T_UTILITYBASE UtilityBase; +struct IntuitionBase *IntuitionBase; +struct PopupMenuBase *PopupMenuBase; +struct Library *DataTypesBase; +struct Library *PreferencesBase; + +#ifdef __amigaos4__ +struct Library *DOSBase; +struct DOSIFace *IDOS; +struct MUIMasterIFace *IMUIMaster; +struct LocaleIFace *ILocale; +struct GraphicsIFace *IGraphics; +struct IconIFace *IIcon; +struct IFFParseIFace *IIFFParse; +struct UtilityIFace *IUtility; +struct IntuitionIFace *IIntuition; +struct PopupMenuIFace *IPopupMenu; +struct DataTypesIFace *IDataTypes; +struct Library *NewlibBase; +struct Interface *INewlib; +struct PreferencesIFace *IPreferences; +#endif + +#ifdef __AROS__ +struct DosLibrary *DOSBase; +#endif + +#include "PopupMenuPrefsImage.h" + +static ULONG SIgnature = 0x4711; + +static ULONG MajorVersion, MinorVersion; + +static const struct MUIP_ScalosPrefs_MCCList RequiredMccList[] = + { + { MUIC_Lamp, 11, 1 }, + { MUIC_NListtree, 18, 18 }, + { MUIC_NListview, 18, 0 }, + { NULL, 0, 0 } + }; + +static const struct Hook PopupMenuPrefsHooks[] = +{ + { { NULL, NULL }, HOOKFUNC_DEF(ImagePopAslFileStartHookFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(ResetToDefaultsHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(OpenHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(LastSavedHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(RestoreHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(SaveAsHookFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(AboutHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(AppMessageHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(SettingsChangedHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(AslIntuiMsgHookFunc), NULL }, + + { { NULL, NULL }, HOOKFUNC_DEF(FrameTypeSelectHookFunc), NULL }, + { { NULL, NULL }, HOOKFUNC_DEF(SelFrameTypeSelectHookFunc), NULL }, +}; + +static struct Locale *PopupMenuPrefsLocale; +static struct Catalog *PopupMenuPrefsCatalog; + +struct MUI_CustomClass *PopupMenuPrefsClass; +struct MUI_CustomClass *FrameButtonClass; +struct MUI_CustomClass *DataTypesImageClass; + +static const LONG StopChunkList[] = + { + ID_PREF, ID_PMNU, + }; + +static STRPTR PrefsPageNames[] = + { + (STRPTR) MSGID_PREFSPAGES_MISC, + (STRPTR) MSGID_PREFSPAGES_BORDERS, + (STRPTR) MSGID_PREFSPAGES_SPACING, + (STRPTR) MSGID_PREFSPAGES_TEXT, + (STRPTR) MSGID_PREFSPAGES_TRANSPARENCY, + NULL + }; + +static STRPTR AnimationNames[] = + { + (STRPTR) MSGID_ANIMATION_NONE, + (STRPTR) MSGID_ANIMATION_ZOOM, + (STRPTR) MSGID_ANIMATION_FADE, + (STRPTR) MSGID_ANIMATION_EXPLODE, + NULL + }; + +static const struct PopupMenuPrefs DefaultPMPrefs = + { + 1, /* pmp_Flags */ + 0, /* pmp_SubMenuDelay */ + PMP_ANIM_NONE, /* pmp_Animation */ + PMP_PD_SCREENBAR, /* pmp_PulldownPos */ + FALSE, /* pmp_Sticky */ + 0, /* pmp_MenuBorder */ + 0, /* pmp_SelItemBorder */ + 0, /* pmp_SeparatorBar */ + 0, /* pmp_MenuTitles */ + 0, /* pmp_MenuItems */ + 2, /* pmp_XOffset */ + 2, /* pmp_YOffset */ + 2, /* pmp_XSpace */ + 2, /* pmp_YSpace */ + 2, /* pmp_Intermediate */ + 0, /* pmp_TextDisplace */ + 0, /* pmp_TransparencyBlur */ + }; + +//---------------------------------------------------------------------------- + +VOID closePlugin(struct PluginBase *PluginBase) +{ + d1(kprintf("%s/%s/%ld: start\n", __FILE__, __FUNC__, __LINE__)); + + if (DataTypesImageClass) + { + CleanupDtpicClass(DataTypesImageClass); + DataTypesImageClass = NULL; + } + if (FrameButtonClass) + { + CleanupFrameButtonClass(FrameButtonClass); + FrameButtonClass = NULL; + } + if (PopupMenuPrefsCatalog) + { + CloseCatalog(PopupMenuPrefsCatalog); + PopupMenuPrefsCatalog = NULL; + } + if (PopupMenuPrefsLocale) + { + CloseLocale(PopupMenuPrefsLocale); + PopupMenuPrefsLocale = NULL; + } + + if (PopupMenuPrefsClass) + { + MUI_DeleteCustomClass(PopupMenuPrefsClass); + PopupMenuPrefsClass = NULL; + } + + CloseLibraries(); + + d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__)); + +#if !defined(__amigaos4__) && !defined(__AROS__) + _STD_240_TerminateMemFunctions(); +#endif + + d1(kprintf("%s/%s/%ld: endt\n", __FILE__, __FUNC__, __LINE__)); +} + + +LIBFUNC_P2(ULONG, LIBSCAGetPrefsInfo, + D0, ULONG, which, + A6, struct PluginBase *, PluginBase); +{ + ULONG result; + + d1(kprintf("%s/%s/%ld: which=%ld\n", __FILE__, __FUNC__, __LINE__, which)); + + (void) PluginBase; + + switch(which) + { + case SCAPREFSINFO_GetClass: + result = (ULONG) PopupMenuPrefsClass; + break; + + case SCAPREFSINFO_GetTitle: + result = (ULONG) GetLocString(MSGID_PLUGIN_LIST_TITLE); + break; + + case SCAPREFSINFO_GetTitleImage: + result = (ULONG) CreatePrefsImage(); + break; + + default: + result = (ULONG) NULL; + break; + } + + d1(kprintf("%s/%s/%ld: result=%lu\n", __FILE__, __FUNC__, __LINE__, result)); + + return result; +} +LIBFUNC_END + +//---------------------------------------------------------------------------- + +DISPATCHER(PopupMenuPrefs) +{ + struct PopupMenuPrefsInst *inst; + ULONG result = 0; + + switch(msg->MethodID) + { + case OM_NEW: + obj = (Object *) DoSuperMethodA(cl, obj, msg); + d1(kprintf("%s/%s/%ld: OM_NEW obj=%08lx\n", __FILE__, __FUNC__, __LINE__, obj)); + if (obj) + { + Object *prefsobject; + struct opSet *ops = (struct opSet *) msg; + + inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj); + + memset(inst, 0, sizeof(struct PopupMenuPrefsInst)); + + inst->mpb_Changed = FALSE; + inst->mpb_PMPrefs = DefaultPMPrefs; + inst->mpb_WBScreen = LockPubScreen("Workbench"); + + InitHooks(inst); + + inst->mpb_fCreateIcons = GetTagData(MUIA_ScalosPrefs_CreateIcons, TRUE, ops->ops_AttrList); + inst->mpb_ProgramName = (CONST_STRPTR) GetTagData(MUIA_ScalosPrefs_ProgramName, (ULONG) "", ops->ops_AttrList); + inst->mpb_Objects[OBJNDX_WIN_Main] = (APTR) GetTagData(MUIA_ScalosPrefs_MainWindow, (ULONG) NULL, ops->ops_AttrList); + inst->mpb_Objects[OBJNDX_APP_Main] = (APTR) GetTagData(MUIA_ScalosPrefs_Application, (ULONG) NULL, ops->ops_AttrList); + + prefsobject = CreatePrefsGroup(inst); + d1(kprintf("%s/%s/%ld: prefsobject=%08lx\n", __FILE__, __FUNC__, __LINE__, prefsobject)); + if (prefsobject) + { + DoMethod(obj, OM_ADDMEMBER, prefsobject); + + result = (ULONG) obj; + } + else + { + CoerceMethod(cl, obj, OM_DISPOSE); + } + } + break; + + case OM_DISPOSE: + inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj); + d1(kprintf("%s/%s/%ld: OM_DISPOSE obj=%08lx\n", __FILE__, __FUNC__, __LINE__, obj)); + if (inst->mpb_WBScreen) + { + UnlockPubScreen(NULL, inst->mpb_WBScreen); + inst->mpb_WBScreen = NULL; + } + if (inst->mpb_SaveReq) + { + MUI_FreeAslRequest(inst->mpb_SaveReq); + inst->mpb_SaveReq = NULL; + } + if (inst->mpb_LoadReq) + { + MUI_FreeAslRequest(inst->mpb_LoadReq); + inst->mpb_LoadReq = NULL; + } + return DoSuperMethodA(cl, obj, msg); + break; + + case OM_SET: + { + struct opSet *ops = (struct opSet *) msg; + + inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj); + + inst->mpb_fCreateIcons = GetTagData(MUIA_ScalosPrefs_CreateIcons, inst->mpb_fCreateIcons, ops->ops_AttrList); + inst->mpb_ProgramName = (CONST_STRPTR) GetTagData(MUIA_ScalosPrefs_ProgramName, (ULONG) inst->mpb_ProgramName, ops->ops_AttrList); + inst->mpb_Objects[OBJNDX_WIN_Main] = (APTR) GetTagData(MUIA_ScalosPrefs_MainWindow, + (ULONG) inst->mpb_Objects[OBJNDX_WIN_Main], ops->ops_AttrList); + inst->mpb_Objects[OBJNDX_APP_Main] = (APTR) GetTagData(MUIA_ScalosPrefs_Application, + (ULONG) inst->mpb_Objects[OBJNDX_APP_Main], ops->ops_AttrList); + + return DoSuperMethodA(cl, obj, msg); + } + break; + + case OM_GET: + { + struct opGet *opg = (struct opGet *) msg; + + inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj); + switch (opg->opg_AttrID) + { + case MUIA_ScalosPrefs_CreateIcons: + *opg->opg_Storage = inst->mpb_fCreateIcons; + result = 0; + break; + default: + result = DoSuperMethodA(cl, obj, msg); + } + } + break; + + case MUIM_ScalosPrefs_ParseToolTypes: + inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj); + d1(kprintf(__FILE__ "/%s/%ld: before ParseToolTypes\n", __FUNC__, __LINE__)); + ParseToolTypes(inst, (struct MUIP_ScalosPrefs_ParseToolTypes *) msg); + d1(kprintf(__FILE__ "/%s/%ld: after ParseToolTypes\n", __FUNC__, __LINE__)); + break; + + case MUIM_ScalosPrefs_LoadConfig: + inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj); + ReadPrefsFile(inst, PMP_PATH_OLD, PMP_PATH_NEW, TRUE); + PrefsToGUI(inst, &inst->mpb_PMPrefs); + SetChangedFlag(inst, FALSE); + break; + + case MUIM_ScalosPrefs_UseConfig: + inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj); + WritePrefsFile(inst, PMP_PATH_NEW); + PM_ReloadPrefs(); + SetChangedFlag(inst, FALSE); + break; + + case MUIM_ScalosPrefs_UseConfigIfChanged: + inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj); + if (inst->mpb_Changed) + { + WritePrefsFile(inst, PMP_PATH_NEW); + PM_ReloadPrefs(); + SetChangedFlag(inst, FALSE); + } + break; + + case MUIM_ScalosPrefs_SaveConfig: + inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj); + WritePrefsFile(inst, PMP_S_PATH_NEW); + WritePrefsFile(inst, PMP_PATH_NEW); + PM_ReloadPrefs(); + SetChangedFlag(inst, FALSE); + break; + + case MUIM_ScalosPrefs_SaveConfigIfChanged: + inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj); + if (inst->mpb_Changed) + { + WritePrefsFile(inst, PMP_S_PATH_NEW); + WritePrefsFile(inst, PMP_PATH_NEW); + PM_ReloadPrefs(); + SetChangedFlag(inst, FALSE); + } + break; + + case MUIM_ScalosPrefs_RestoreConfig: + inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_Restore], 0); + break; + + case MUIM_ScalosPrefs_ResetToDefaults: + inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_ResetToDefaults], 0); + break; + + case MUIM_ScalosPrefs_LastSavedConfig: + inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_LastSaved], 0); + break; + + case MUIM_ScalosPrefs_PageActive: + { + struct MUIP_ScalosPrefs_PageActive *spa = (struct MUIP_ScalosPrefs_PageActive *) msg; + + d1(kprintf("%s/%s/%ld: MUIM_ScalosPrefs_PageActive isActive=%08lx\n", __FILE__, __FUNC__, __LINE__, spa->isActive)); + inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj); + inst->mpb_PageIsActive = spa->isActive; + } + break; + + case MUIM_ScalosPrefs_OpenConfig: + inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_Open], 0); + break; + + case MUIM_ScalosPrefs_SaveConfigAs: + inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_SaveAs], 0); + break; + + case MUIM_ScalosPrefs_About: + inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj); + DoMethod(obj, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_About], 0); + break; + + case MUIM_ScalosPrefs_LoadNamedConfig: + { + struct MUIP_ScalosPrefs_LoadNamedConfig *lnc = (struct MUIP_ScalosPrefs_LoadNamedConfig *) msg; + + inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj); + ReadPrefsFile(inst, "", lnc->ConfigFileName, FALSE); + PrefsToGUI(inst, &inst->mpb_PMPrefs); + } + break; + + case MUIM_ScalosPrefs_CreateSubWindows: + result = (ULONG) NULL; + break; + + case MUIM_ScalosPrefs_GetListOfMCCs: + result = (ULONG) RequiredMccList; + break; + + default: + d1(kprintf("%s/%s/%ld: MethodID=%08lx\n", __FILE__, __FUNC__, __LINE__, msg->MethodID)); + result = DoSuperMethodA(cl, obj, msg); + break; + } + + return result; +} +DISPATCHER_END + +//---------------------------------------------------------------------------- + +static Object *CreatePrefsGroup(struct PopupMenuPrefsInst *inst) +{ + d1(kprintf("%s/%s/%ld: inst=%08lx\n", __FILE__, __FUNC__, __LINE__, inst)); + + inst->mpb_Objects[OBJNDX_Group_Main] = VGroup, + MUIA_Background, MUII_PageBack, + + Child, RegisterObject, + MUIA_Register_Titles, PrefsPageNames, + MUIA_CycleChain, TRUE, + + //------ Misc. ---------------------- + Child, VGroup, + MUIA_Background, MUII_RegisterBack, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_MISCPAGE_TITLE), + + Child, HVSpace, + + Child, HGroup, + Child, Label1((ULONG) GetLocString(MSGID_MISCPAGE_DELAY_SUBMENUS)), + Child, inst->mpb_Objects[OBJNDX_Slider_DelaySubMenus] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Slider_Min, 0, + MUIA_Slider_Max, 10, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 0, + End, //SliderObject + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_MISCPAGE_DELAY_SUBMENUS_SHORTHELP), + End, //HGroup + + Child, HVSpace, + + Child, VGroup, + GroupFrame, + MUIA_Background, MUII_GroupBack, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_MISCPAGE_ANIMATION), + + Child, ColGroup(2), + Child, Label1((ULONG) GetLocString(MSGID_MISCPAGE_ANIMATION_TYPE)), + Child, inst->mpb_Objects[OBJNDX_Cycle_AnimationType] = CycleObject, + MUIA_CycleChain, TRUE, + MUIA_Cycle_Entries, AnimationNames, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_MISCPAGE_ANIMATION_TYPE_SHORTHELP), + End, //Cycle + End, //ColGroup + End, //VGroup + + Child, HVSpace, + + + Child, HVSpace, + + Child, ColGroup(4), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, inst->mpb_Objects[OBJNDX_CheckMark_MenuShadows] = CheckMarkHelp(TRUE, MSGID_MISCPAGE_MENUSHADOWS_SHORTHELP), + Child, LLabel1((ULONG) GetLocString(MSGID_MISCPAGE_MENUSHADOWS)), + + Child, HVSpace, + Child, HVSpace, + + Child, inst->mpb_Objects[OBJNDX_CheckMark_RealShadows] = CheckMarkHelp(TRUE, MSGID_MISCPAGE_REALSHADOWS_SHORTHELP), + Child, LLabel1((ULONG) GetLocString(MSGID_MISCPAGE_REALSHADOWS)), + + Child, HVSpace, + Child, HVSpace, + + Child, inst->mpb_Objects[OBJNDX_CheckMark_Sticky] = CheckMarkHelp(TRUE, MSGID_MISCPAGE_STICKY_SHORTHELP), + Child, LLabel1((ULONG) GetLocString(MSGID_MISCPAGE_STICKY)), + + Child, HVSpace, + End, //ColGroup + + Child, HVSpace, + End, //VGroup + + //------ Borders ---------------------- + Child, VGroup, + MUIA_Background, MUII_RegisterBack, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_BORDERSPAGE_TITLE), + + Child, HVSpace, + + Child, HGroup, + GroupFrame, + MUIA_Background, MUII_GroupBack, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_BORDERSPAGE_MENUBORDER), + + Child, FrameButton(OBJNDX_Button_FrameThin, PMP_MENUBORDER_THIN, "", FALSE, FALSE), + Child, FrameButton(OBJNDX_Button_FrameMM, PMP_MENUBORDER_MM, "", FALSE, FALSE), + Child, FrameButton(OBJNDX_Button_FrameThick, PMP_MENUBORDER_THICK, "", FALSE, FALSE), + Child, FrameButton(OBJNDX_Button_FrameRidge, PMP_MENUBORDER_RIDGE, "", FALSE, FALSE), + Child, FrameButton(OBJNDX_Button_FrameDropBox, PMP_MENUBORDER_DROPBOX, "", FALSE, FALSE), + Child, FrameButton(OBJNDX_Button_FrameOldStyle, PMP_MENUBORDER_OLDSTYLE, "", FALSE, FALSE), + End, //HGroup + + Child, HVSpace, + + Child, HGroup, + GroupFrame, + MUIA_Background, MUII_GroupBack, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_BORDERSPAGE_SELECTEDITEM), + + Child, FrameButton(OBJNDX_Button_Normal, PMP_MENUBORDER_NONE, GetLocString(MSGID_BORDERSPAGE_NORMAL), TRUE, FALSE), + Child, FrameButton(OBJNDX_Button_Raised, PMP_MENUBORDER_THIN, GetLocString(MSGID_BORDERSPAGE_RAISED), TRUE, TRUE), + Child, FrameButton(OBJNDX_Button_Recessed, PMP_MENUBORDER_THIN, GetLocString(MSGID_BORDERSPAGE_RECESSED), TRUE, FALSE), + End, //HGroup + + Child, HVSpace, + + Child, HGroup, + GroupFrame, + MUIA_Background, MUII_GroupBack, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_BORDERSPAGE_SEPARATORS), + + Child, HVSpace, + + Child, ColGroup(4), + Child, HGroup, + Child, HVSpace, + Child, IMG(NewStyle, NEWSTYLE), + Child, HVSpace, + End, //HGroup + Child, inst->mpb_Objects[OBJNDX_CheckMark_NewLook] = ImageObject, + ImageButtonFrame, + MUIA_InputMode, MUIV_InputMode_Toggle, + MUIA_Image_Spec, MUII_CheckMark, + MUIA_Image_FreeVert, TRUE, + MUIA_Background, MUII_ButtonBack, + MUIA_ShowSelState, FALSE, + MUIA_CycleChain, TRUE, + End, //ImageObject + Child, CLabel((ULONG) GetLocString(MSGID_BORDERSPAGE_NEW_LOOK)), + Child, HVSpace, + + Child, HGroup, + Child, HVSpace, + Child, IMG(OldStyle, OLDSTYLE), + Child, HVSpace, + End, //HGroup + Child, inst->mpb_Objects[OBJNDX_CheckMark_OldLook] = ImageObject, + ImageButtonFrame, + MUIA_InputMode, MUIV_InputMode_Toggle, + MUIA_Image_Spec, MUII_CheckMark, + MUIA_Image_FreeVert, TRUE, + MUIA_Background, MUII_ButtonBack, + MUIA_ShowSelState, FALSE, + MUIA_CycleChain, TRUE, + End, //ImageObject + Child, CLabel((ULONG) GetLocString(MSGID_BORDERSPAGE_OLD_LOOK)), + Child, HVSpace, + End, //ColGroup + + Child, HVSpace, + End, //HGroup + + Child, HVSpace, + End, //VGroup + + //------ Spacing ---------------------- + Child, VGroup, + MUIA_Background, MUII_RegisterBack, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_SPACINGPAGE_TITLE), + + Child, HVSpace, + + Child, ColGroup(5), + Child, HVSpace, + + Child, VGroup, + GroupFrame, + MUIA_Background, MUII_GroupBack, + Child, HVSpace, + Child, CLabel((ULONG) GetLocString(MSGID_SPACINGPAGE_HORIZONTAL_SPACE)), + Child, IMG(Horizontal_Space, HORIZONTAL_SPACE), + Child, inst->mpb_Objects[OBJNDX_Slider_HorizontalSpacing] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 10, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 2, + End, //SliderObject + Child, HVSpace, + End, //VGroup + + Child, HVSpace, + + Child, VGroup, + GroupFrame, + MUIA_Background, MUII_GroupBack, + Child, HVSpace, + Child, CLabel((ULONG) GetLocString(MSGID_SPACINGPAGE_VERTICAL_SPACE)), + Child, IMG(Vertical_Space, VERTICAL_SPACE), + Child, inst->mpb_Objects[OBJNDX_Slider_VerticalSpacing] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 10, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 1, + End, //SliderObject + Child, HVSpace, + End, //VGroup + + Child, HVSpace, + Child, HVSpace, + + Child, VGroup, + GroupFrame, + MUIA_Background, MUII_GroupBack, + Child, HVSpace, + Child, CLabel((ULONG) GetLocString(MSGID_SPACINGPAGE_HORIZONTAL)), + Child, IMG(Horizontal, HORIZONTAL), + Child, inst->mpb_Objects[OBJNDX_Slider_Horizontal] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 10, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 0, + End, //SliderObject + Child, HVSpace, + End, //VGroup + + Child, HVSpace, + + Child, VGroup, + GroupFrame, + MUIA_Background, MUII_GroupBack, + Child, HVSpace, + Child, CLabel((ULONG) GetLocString(MSGID_SPACINGPAGE_VERTICAL_OFFSET)), + Child, IMG(Vertical_Offset, VERTICAL_OFFSET), + Child, inst->mpb_Objects[OBJNDX_Slider_VerticalOffset] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 10, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 0, + End, //SliderObject + Child, HVSpace, + End, //VGroup + + Child, HVSpace, + Child, HVSpace, + + Child, VGroup, + GroupFrame, + MUIA_Background, MUII_GroupBack, + Child, HVSpace, + Child, CLabel((ULONG) GetLocString(MSGID_SPACINGPAGE_INTERMEDIATE_SPACING)), + Child, IMG(Intermediate_Spacing, INTERMEDIATE_SPACING), + Child, inst->mpb_Objects[OBJNDX_Slider_IntermediateSpacing] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 10, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 0, + End, //SliderObject + Child, HVSpace, + End, //VGroup + + Child, HVSpace, + + Child, VGroup, + GroupFrame, + MUIA_Background, MUII_GroupBack, + Child, HVSpace, + Child, CLabel((ULONG) GetLocString(MSGID_SPACINGPAGE_TEXT_DISPLACEMENT)), + Child, IMG(Text_Displacement, TEXT_DISPLACEMENT), + Child, inst->mpb_Objects[OBJNDX_Slider_TextDisplacement] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, -5, + MUIA_Numeric_Max, 5, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 0, + End, //SliderObject + Child, HVSpace, + End, //VGroup + + Child, HVSpace, + End, //ColGroup + + Child, HVSpace, + End, //VGroup + + //------ Text ---------------------- + Child, VGroup, + MUIA_Background, MUII_RegisterBack, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_TEXTPAGE_TITLE), + + Child, HVSpace, + + Child, ColGroup(4), + GroupFrame, + MUIA_Background, MUII_GroupBack, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_TEXTPAGE_MENU_TITLES), + + Child, ColGroup(2), + Child, inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Italic] = CheckMarkHelp(TRUE, MSGID_TEXTPAGE_MENUTITLES_ITALIC_SHORTHELP), + Child, LLabel1((ULONG) GetLocString(MSGID_TEXTPAGE_MENUTITLES_ITALIC)), + + Child, inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Underlined] = CheckMarkHelp(TRUE, MSGID_TEXTPAGE_MENUTITLES_UNDERLINED_SHORTHELP), + Child, LLabel1((ULONG) GetLocString(MSGID_TEXTPAGE_MENUTITLES_UNDERLINED)), + + Child, inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Bold] = CheckMarkHelp(TRUE, MSGID_TEXTPAGE_MENUTITLES_BOLD_SHORTHELP), + Child, LLabel1((ULONG) GetLocString(MSGID_TEXTPAGE_MENUTITLES_BOLD)), + + End, //ColGroup + + Child, HVSpace, + + Child, ColGroup(2), + Child, inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Shadowed] = CheckMarkHelp(TRUE, MSGID_TEXTPAGE_MENUTITLES_SHADOWED_SHORTHELP), + Child, LLabel1((ULONG) GetLocString(MSGID_TEXTPAGE_MENUTITLES_SHADOWED)), + + Child, inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Outlined] = CheckMarkHelp(TRUE, MSGID_TEXTPAGE_MENUTITLES_OUTLINED_SHORTHELP), + Child, LLabel1((ULONG) GetLocString(MSGID_TEXTPAGE_MENUTITLES_OUTLINED)), + + Child, inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Embossed] = CheckMarkHelp(TRUE, MSGID_TEXTPAGE_MENUTITLES_EMBOSSED_SHORTHELP), + Child, LLabel1((ULONG) GetLocString(MSGID_TEXTPAGE_MENUTITLES_EMBOSSED)), + + End, //ColGroup + + Child, HVSpace, + + End, //ColGroup + + Child, ColGroup(4), + GroupFrame, + MUIA_Background, MUII_GroupBack, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_TEXTPAGE_MENU_ITEMS), + + Child, ColGroup(2), + Child, inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Italic] = CheckMarkHelp(TRUE, MSGID_TEXTPAGE_MENUITEMS_ITALIC_SHORTHELP), + Child, LLabel1((ULONG) GetLocString(MSGID_TEXTPAGE_MENUITEMS_ITALIC)), + + Child, inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Underlined] = CheckMarkHelp(TRUE, MSGID_TEXTPAGE_MENUITEMS_UNDERLINED_SHORTHELP), + Child, LLabel1((ULONG) GetLocString(MSGID_TEXTPAGE_MENUITEMS_UNDERLINED)), + + Child, inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Bold] = CheckMarkHelp(TRUE, MSGID_TEXTPAGE_MENUITEMS_BOLD_SHORTHELP), + Child, LLabel1((ULONG) GetLocString(MSGID_TEXTPAGE_MENUITEMS_BOLD)), + + End, //ColGroup + + Child, HVSpace, + + Child, ColGroup(2), + Child, inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Shadowed] = CheckMarkHelp(TRUE, MSGID_TEXTPAGE_MENUITEMS_SHADOWED_SHORTHELP), + Child, LLabel1((ULONG) GetLocString(MSGID_TEXTPAGE_MENUITEMS_SHADOWED)), + + Child, inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Outlined] = CheckMarkHelp(TRUE, MSGID_TEXTPAGE_MENUITEMS_OUTLINED_SHORTHELP), + Child, LLabel1((ULONG) GetLocString(MSGID_TEXTPAGE_MENUITEMS_OUTLINED)), + + Child, inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Embossed] = CheckMarkHelp(TRUE, MSGID_TEXTPAGE_MENUITEMS_EMBOSSED_SHORTHELP), + Child, LLabel1((ULONG) GetLocString(MSGID_TEXTPAGE_MENUITEMS_EMBOSSED)), + + End, //ColGroup + + Child, HVSpace, + + End, //ColGroup + + Child, HVSpace, + + End, //VGroup + + //------ Transparency ---------------------- + Child, VGroup, + MUIA_Background, MUII_RegisterBack, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_TRANSPARENCYPAGE_TITLE), + + Child, HVSpace, + + Child, ColGroup(4), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, inst->mpb_Objects[OBJNDX_CheckMark_Transparency_Enable] = CheckMarkHelp(TRUE, MSGID_TRANSPARENCYPAGE_ENABLE_SHORTHELP), + Child, LLabel1((ULONG) GetLocString(MSGID_TRANSPARENCYPAGE_ENABLE)), + + Child, HVSpace, + End, //ColGroup + + Child, HVSpace, + + Child, inst->mpb_Objects[OBJNDX_Group_Transp_Blur] = ColGroup(2), + Child, Label1((ULONG) GetLocString(MSGID_TRANSPARENCYPAGE_BLUR)), + Child, inst->mpb_Objects[OBJNDX_Slider_Transp_Blur] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 100, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, -16, + MUIA_Numeric_Format, (ULONG) GetLocString(MSGID_TRANSPARENCYPAGE_BLUR_NUMERIC_FORMAT), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_TRANSPARENCYPAGE_BLUR_SHORTHELP), + End, //SliderObject + End, //ColGroup + + Child, HVSpace, + + End, //VGroup + + End, //RegisterObject + + End; //VGroup + + if (NULL == inst->mpb_Objects[OBJNDX_Group_Main]) + return NULL; + + PrefsToGUI(inst, &inst->mpb_PMPrefs); + + DoMethod(inst->mpb_Objects[OBJNDX_Group_Main], MUIM_Notify, MUIA_AppMessage, MUIV_EveryTime, + inst->mpb_Objects[OBJNDX_Group_Main], 3, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_AppMessage], MUIV_TriggerValue); + + DoMethod(inst->mpb_Objects[OBJNDX_Button_FrameThin], MUIM_Notify, MUIA_Selected, TRUE, + inst->mpb_Objects[OBJNDX_Button_FrameThin], 3, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_FrameSelected], MUIV_TriggerValue); + + // Mutual exclusion for frame type buttons + DoMethod(inst->mpb_Objects[OBJNDX_Button_FrameMM], MUIM_Notify, MUIA_Selected, TRUE, + inst->mpb_Objects[OBJNDX_Button_FrameMM], 3, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_FrameSelected], MUIV_TriggerValue); + DoMethod(inst->mpb_Objects[OBJNDX_Button_FrameThick], MUIM_Notify, MUIA_Selected, TRUE, + inst->mpb_Objects[OBJNDX_Button_FrameThick], 3, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_FrameSelected], MUIV_TriggerValue); + DoMethod(inst->mpb_Objects[OBJNDX_Button_FrameRidge], MUIM_Notify, MUIA_Selected, TRUE, + inst->mpb_Objects[OBJNDX_Button_FrameRidge], 3, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_FrameSelected], MUIV_TriggerValue); + DoMethod(inst->mpb_Objects[OBJNDX_Button_FrameDropBox], MUIM_Notify, MUIA_Selected, TRUE, + inst->mpb_Objects[OBJNDX_Button_FrameDropBox], 3, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_FrameSelected], MUIV_TriggerValue); + DoMethod(inst->mpb_Objects[OBJNDX_Button_FrameOldStyle], MUIM_Notify, MUIA_Selected, TRUE, + inst->mpb_Objects[OBJNDX_Button_FrameOldStyle], 3, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_FrameSelected], MUIV_TriggerValue); + + // Mutual exclusion for selected frame type buttons + DoMethod(inst->mpb_Objects[OBJNDX_Button_Normal], MUIM_Notify, MUIA_Selected, TRUE, + inst->mpb_Objects[OBJNDX_Button_Normal], 3, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_SelFrameSelected], MUIV_TriggerValue); + DoMethod(inst->mpb_Objects[OBJNDX_Button_Raised], MUIM_Notify, MUIA_Selected, TRUE, + inst->mpb_Objects[OBJNDX_Button_Raised], 3, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_SelFrameSelected], MUIV_TriggerValue); + DoMethod(inst->mpb_Objects[OBJNDX_Button_Recessed], MUIM_Notify, MUIA_Selected, TRUE, + inst->mpb_Objects[OBJNDX_Button_Recessed], 3, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_SelFrameSelected], MUIV_TriggerValue); + + // Mutual exclusion for separator style buttons + DoMethod(inst->mpb_Objects[OBJNDX_CheckMark_NewLook], MUIM_Notify, MUIA_Selected, TRUE, + inst->mpb_Objects[OBJNDX_CheckMark_OldLook], 3, MUIM_Set, MUIA_Selected, FALSE); + DoMethod(inst->mpb_Objects[OBJNDX_CheckMark_OldLook], MUIM_Notify, MUIA_Selected, TRUE, + inst->mpb_Objects[OBJNDX_CheckMark_NewLook], 3, MUIM_Set, MUIA_Selected, FALSE); + + // Disable transparency settings if transparency is disabled + DoMethod(inst->mpb_Objects[OBJNDX_CheckMark_Transparency_Enable], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + inst->mpb_Objects[OBJNDX_Group_Transp_Blur], 3, MUIM_Set, MUIA_Disabled, MUIV_NotTriggerValue); + + // Disable "real shadows" settings if shadow is disabled + DoMethod(inst->mpb_Objects[OBJNDX_CheckMark_MenuShadows], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + inst->mpb_Objects[OBJNDX_CheckMark_RealShadows], 3, MUIM_Set, MUIA_Disabled, MUIV_NotTriggerValue); + + d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__)); + d1(kprintf("%s/%s/%ld: LocaleBase=%08lx IFFParseBase=%08lx\n", __FILE__, __FUNC__, __LINE__, LocaleBase, IFFParseBase)); + + return inst->mpb_Objects[OBJNDX_Group_Main]; +} + + +static BOOL OpenLibraries(void) +{ + d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__)); + + DOSBase = (APTR) OpenLibrary( "dos.library", 39 ); + if (NULL == DOSBase) + return FALSE; +#ifdef __amigaos4__ + IDOS = (struct DOSIFace *)GetInterface((struct Library *)DOSBase, "main", 1, NULL); + if (NULL == IDOS) + return FALSE; +#endif + + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + if (NULL == IntuitionBase) + return FALSE; +#ifdef __amigaos4__ + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + return FALSE; +#endif + + MUIMasterBase = OpenLibrary("zune.library", 0); + if (NULL == MUIMasterBase) + MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN-1); + if (NULL == MUIMasterBase) + return FALSE; +#ifdef __amigaos4__ + IMUIMaster = (struct MUIMasterIFace *)GetInterface((struct Library *)MUIMasterBase, "main", 1, NULL); + if (NULL == IMUIMaster) + return FALSE; +#endif + + IFFParseBase = OpenLibrary("iffparse.library", 36); + if (NULL == IFFParseBase) + return FALSE; +#ifdef __amigaos4__ + IIFFParse = (struct IFFParseIFace *)GetInterface((struct Library *)IFFParseBase, "main", 1, NULL); + if (NULL == IIFFParse) + return FALSE; +#endif + + IconBase = OpenLibrary("icon.library", 0); + if (NULL == IconBase) + return FALSE; +#ifdef __amigaos4__ + IIcon = (struct IconIFace *)GetInterface((struct Library *)IconBase, "main", 1, NULL); + if (NULL == IIcon) + return FALSE; +#endif + + GfxBase = (struct GfxBase *) OpenLibrary(GRAPHICSNAME, 39); + if (NULL == GfxBase) + return FALSE; +#ifdef __amigaos4__ + IGraphics = (struct GraphicsIFace *)GetInterface((struct Library *)GfxBase, "main", 1, NULL); + if (NULL == IGraphics) + return FALSE; +#endif + + UtilityBase = (T_UTILITYBASE) OpenLibrary(UTILITYNAME, 39); + if (NULL == UtilityBase) + return FALSE; +#ifdef __amigaos4__ + IUtility = (struct UtilityIFace *)GetInterface((struct Library *)UtilityBase, "main", 1, NULL); + if (NULL == IUtility) + return FALSE; +#endif + + PreferencesBase = OpenLibrary("preferences.library", 39); + if (NULL == PreferencesBase) + return FALSE; + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld PreferencesBase=%08lx\n", __LINE__, PreferencesBase)); +#ifdef __amigaos4__ + IPreferences = (struct PreferencesIFace *) GetInterface(PreferencesBase, "main", 1, NULL); + if (NULL == IPreferences) + return FALSE; +#endif + + PopupMenuBase = (struct PopupMenuBase *) OpenLibrary(POPUPMENU_NAME, POPUPMENU_VERSION); + if (NULL == PopupMenuBase) + return FALSE; + + DataTypesBase = OpenLibrary("datatypes.library", 39); + if (NULL == DataTypesBase) + return FALSE; +#ifdef __amigaos4__ + IDataTypes = (struct DataTypesIFace *)GetInterface((struct Library *)DataTypesBase, "main", 1, NULL); + if (NULL == IDataTypes) + return FALSE; +#endif + +#ifdef __amigaos4__ + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + return FALSE; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + return FALSE; +#endif + + // LocaleBase is optional + LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 39); +#ifdef __amigaos4__ + if (LocaleBase) + ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL); +#endif + +#ifdef __amigaos4__ + if (PopupMenuBase) + IPopupMenu = (struct PopupMenuIFace *)GetInterface((struct Library *)PopupMenuBase, "main", 1, NULL); +#endif + + d1(kprintf("%s/%s/%ld: LocaleBase=%08lx IFFParseBase=%08lx\n", __FILE__, __FUNC__, __LINE__, LocaleBase, IFFParseBase)); + + return TRUE; +} + + +static void CloseLibraries(void) +{ + d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__)); + +#ifdef __amigaos4__ + if (INewlib) + { + DropInterface(INewlib); + INewlib = NULL; + } + if (NewlibBase) + { + CloseLibrary(NewlibBase); + NewlibBase = NULL; + } + if (IDOS) + { + DropInterface((struct Interface *)IDOS); + IDOS = NULL; + } +#endif + if (DOSBase) + { + CloseLibrary((struct Library *) DOSBase); + DOSBase = NULL; + } +#ifdef __amigaos4__ + if (PreferencesBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)IPreferences); +#endif + CloseLibrary(PreferencesBase); + } + if (IDataTypes) + { + DropInterface((struct Interface *)IDataTypes); + IDataTypes = NULL; + } +#endif + if (DataTypesBase) + { + CloseLibrary(DataTypesBase); + DataTypesBase = NULL; + } +#ifdef __amigaos4__ + if (ILocale) + { + DropInterface((struct Interface *)ILocale); + ILocale = NULL; + } +#endif + if (LocaleBase) + { + CloseLibrary((struct Library *) LocaleBase); + LocaleBase = NULL; + } +#ifdef __amigaos4__ + if (IUtility) + { + DropInterface((struct Interface *)IUtility); + IUtility = NULL; + } +#endif + if (UtilityBase) + { + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } +#ifdef __amigaos4__ + if (IGraphics) + { + DropInterface((struct Interface *)IGraphics); + IGraphics = NULL; + } +#endif + if (GfxBase) + { + CloseLibrary((struct Library *) GfxBase); + GfxBase = NULL; + } +#ifdef __amigaos4__ + if (IIcon) + { + DropInterface((struct Interface *)IIcon); + IIcon = NULL; + } +#endif + if (IconBase) + { + CloseLibrary(IconBase); + IconBase = NULL; + } +#ifdef __amigaos4__ + if (IIFFParse) + { + DropInterface((struct Interface *)IIFFParse); + IIFFParse = NULL; + } +#endif + if (IFFParseBase) + { + CloseLibrary(IFFParseBase); + IFFParseBase = NULL; + } +#ifdef __amigaos4__ + if (IMUIMaster) + { + DropInterface((struct Interface *)IMUIMaster); + IMUIMaster = NULL; + } +#endif + if (MUIMasterBase) + { + CloseLibrary(MUIMasterBase); + MUIMasterBase = NULL; + } +#ifdef __amigaos4__ + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } +#endif + if (IntuitionBase) + { + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } +#ifdef __amigaos4__ + if (IPopupMenu) + { + DropInterface((struct Interface *)IPopupMenu); + IPopupMenu = NULL; + } +#endif + if (PopupMenuBase) + { + CloseLibrary((struct Library *) PopupMenuBase); + PopupMenuBase = NULL; + } +} + +//---------------------------------------------------------------------------- + +static SAVEDS(ULONG) INTERRUPT ImagePopAslFileStartHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct TagItem *TagList = (struct TagItem *) msg; +// struct PopupMenuPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data; + + d1(KPrintF("%s/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst)); + + while (TAG_END != TagList->ti_Tag) + TagList++; + + TagList->ti_Tag = ASLFR_DrawersOnly; + TagList->ti_Data = FALSE; + TagList++; + +// TagList->ti_Tag = ASLFR_InitialFile; +// TagList->ti_Data = (ULONG) inst->fpb_FileName; +// TagList++; + + TagList->ti_Tag = ASLFR_InitialDrawer; + TagList->ti_Data = (ULONG) "THEME:FileTypes/"; + TagList++; + + TagList->ti_Tag = TAG_END; + + return TRUE; +} + +//---------------------------------------------------------------------------- + +static STRPTR GetLocString(ULONG MsgId) +{ + struct ScalosPopupMenu_LocaleInfo li; + + li.li_Catalog = PopupMenuPrefsCatalog; +#ifndef __amigaos4__ + li.li_LocaleBase = LocaleBase; +#else + li.li_ILocale = ILocale; +#endif + + return (STRPTR) GetScalosPopupMenuString(&li, MsgId); +} + +static void TranslateStringArray(STRPTR *stringArray) +{ + while (*stringArray) + { + *stringArray = GetLocString((ULONG) *stringArray); + stringArray++; + } +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT ResetToDefaultsHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PopupMenuPrefsInst *inst = (struct PopupMenuPrefsInst *) hook->h_Data; + + d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__)); + + inst->mpb_PMPrefs = DefaultPMPrefs; + PrefsToGUI(inst, &inst->mpb_PMPrefs); + + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT OpenHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PopupMenuPrefsInst *inst = (struct PopupMenuPrefsInst *) hook->h_Data; + + if (NULL == inst->mpb_LoadReq) + { + inst->mpb_LoadReq = MUI_AllocAslRequestTags(ASL_FileRequest, + ASLFR_InitialFile, "PopupMenu.pre", + ASLFR_Flags1, FRF_DOPATTERNS, + ASLFR_InitialDrawer, "SYS:Prefs/presets", + ASLFR_InitialPattern, "#?.(pre|prefs)", + ASLFR_UserData, inst, + ASLFR_IntuiMsgFunc, &inst->mpb_Hooks[HOOKNDX_AslIntuiMsg], + TAG_END); + } + if (inst->mpb_LoadReq) + { + BOOL Result; + struct Window *win = NULL; + + get(inst->mpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Window, &win); + + //AslRequest( + Result = MUI_AslRequestTags(inst->mpb_LoadReq, + ASLFR_Window, win, + ASLFR_SleepWindow, TRUE, + ASLFR_TitleText, GetLocString(MSGID_MENU_PROJECT_OPEN), + TAG_END); + + if (Result) + { + BPTR dirLock = Lock(inst->mpb_LoadReq->fr_Drawer, ACCESS_READ); + + if (dirLock) + { + BPTR oldDir = CurrentDir(dirLock); + + ReadPrefsFile(inst, "", inst->mpb_LoadReq->fr_File, FALSE); + PrefsToGUI(inst, &inst->mpb_PMPrefs); + + CurrentDir(oldDir); + UnLock(dirLock); + } + } + } + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT LastSavedHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PopupMenuPrefsInst *inst = (struct PopupMenuPrefsInst *) hook->h_Data; + + ReadPrefsFile(inst, PMP_S_PATH_OLD, PMP_S_PATH_NEW, FALSE); + PrefsToGUI(inst, &inst->mpb_PMPrefs); + SetChangedFlag(inst, TRUE); + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT RestoreHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PopupMenuPrefsInst *inst = (struct PopupMenuPrefsInst *) hook->h_Data; + + ReadPrefsFile(inst, PMP_PATH_OLD, PMP_PATH_NEW, FALSE); + PrefsToGUI(inst, &inst->mpb_PMPrefs); + SetChangedFlag(inst, TRUE); + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT SaveAsHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PopupMenuPrefsInst *inst = (struct PopupMenuPrefsInst *) hook->h_Data; + + if (NULL == inst->mpb_SaveReq) + { + inst->mpb_SaveReq = MUI_AllocAslRequestTags(ASL_FileRequest, + ASLFR_InitialFile, "PopupMenu.pre", + ASLFR_DoSaveMode, TRUE, + ASLFR_InitialDrawer, "SYS:Prefs/presets", + ASLFR_UserData, inst, + ASLFR_IntuiMsgFunc, &inst->mpb_Hooks[HOOKNDX_AslIntuiMsg], + TAG_END); + } + if (inst->mpb_SaveReq) + { + BOOL Result; + struct Window *win = NULL; + + get(inst->mpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Window, &win); + + //AslRequest( + Result = MUI_AslRequestTags(inst->mpb_SaveReq, + ASLFR_TitleText, GetLocString(MSGID_MENU_PROJECT_SAVEAS), + ASLFR_Window, win, + ASLFR_SleepWindow, TRUE, + TAG_END); + + if (Result) + { + BPTR dirLock = Lock(inst->mpb_SaveReq->fr_Drawer, ACCESS_READ); + + if (dirLock) + { + BPTR oldDir = CurrentDir(dirLock); + + WritePrefsFile(inst, inst->mpb_SaveReq->fr_File); + + CurrentDir(oldDir); + UnLock(dirLock); + } + } + } + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT AboutHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PopupMenuPrefsInst *inst = (struct PopupMenuPrefsInst *) hook->h_Data; + + MUI_Request(inst->mpb_Objects[OBJNDX_APP_Main], inst->mpb_Objects[OBJNDX_WIN_Main], 0, NULL, + GetLocString(MSGID_ABOUTREQOK), + GetLocString(MSGID_ABOUTREQFORMAT), + MajorVersion, MinorVersion, COMPILER_STRING, CURRENTYEAR); + + return 0; +} + +//---------------------------------------------------------------------------- + +static LONG ReadPrefsFile(struct PopupMenuPrefsInst *inst, CONST_STRPTR FilenameOld, CONST_STRPTR FilenameNew, BOOL Quiet) +{ + LONG Result = RETURN_OK; + APTR myPrefsHandle; + + d1(KPrintF("%s/%s/%ld: Filename=<%s> LocaleBase=%08lx IFFParseBase=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, Filename, LocaleBase, IFFParseBase)); + + ConvertPmPrefs(FilenameOld, FilenameNew); + + myPrefsHandle = AllocPrefsHandle("PopupMenuPrefs"); + if (myPrefsHandle) + { + LONG lID = MAKE_ID('M', 'A', 'I', 'N'); + + ReadPrefsHandle(myPrefsHandle, FilenameNew); + + GetPreferences(myPrefsHandle, lID, PMP_Flags, &inst->mpb_PMPrefs.pmp_Flags, sizeof(inst->mpb_PMPrefs.pmp_Flags) ); + GetPreferences(myPrefsHandle, lID, PMP_SubMenuDelay, &inst->mpb_PMPrefs.pmp_SubMenuDelay, sizeof(inst->mpb_PMPrefs.pmp_SubMenuDelay) ); + GetPreferences(myPrefsHandle, lID, PMP_AnimationType, &inst->mpb_PMPrefs.pmp_Animation, sizeof(inst->mpb_PMPrefs.pmp_Animation) ); + GetPreferences(myPrefsHandle, lID, PMP_PullDownMenuPos, &inst->mpb_PMPrefs.pmp_PulldownPos, sizeof(inst->mpb_PMPrefs.pmp_PulldownPos) ); + if (GetPreferences(myPrefsHandle, lID, PMP_Sticky, &inst->mpb_PMPrefs.pmp_Sticky, sizeof(inst->mpb_PMPrefs.pmp_Sticky) )) + { + inst->mpb_PMPrefs.pmp_Sticky = SCA_BE2WORD(inst->mpb_PMPrefs.pmp_Sticky); + } + GetPreferences(myPrefsHandle, lID, PMP_MenuBorderType, &inst->mpb_PMPrefs.pmp_MenuBorder, sizeof(inst->mpb_PMPrefs.pmp_MenuBorder) ); + GetPreferences(myPrefsHandle, lID, PMP_SelItemBorderType, &inst->mpb_PMPrefs.pmp_SelItemBorder, sizeof(inst->mpb_PMPrefs.pmp_SelItemBorder) ); + GetPreferences(myPrefsHandle, lID, PMP_SeparatorBarStyle, &inst->mpb_PMPrefs.pmp_SeparatorBar, sizeof(inst->mpb_PMPrefs.pmp_SeparatorBar) ); + GetPreferences(myPrefsHandle, lID, PMP_XOffset, &inst->mpb_PMPrefs.pmp_XOffset, sizeof(inst->mpb_PMPrefs.pmp_XOffset) ); + GetPreferences(myPrefsHandle, lID, PMP_YOffset, &inst->mpb_PMPrefs.pmp_YOffset, sizeof(inst->mpb_PMPrefs.pmp_YOffset) ); + GetPreferences(myPrefsHandle, lID, PMP_XSpace, &inst->mpb_PMPrefs.pmp_XSpace, sizeof(inst->mpb_PMPrefs.pmp_XSpace) ); + GetPreferences(myPrefsHandle, lID, PMP_YSpace, &inst->mpb_PMPrefs.pmp_YSpace, sizeof(inst->mpb_PMPrefs.pmp_YSpace) ); + GetPreferences(myPrefsHandle, lID, PMP_Intermediate, &inst->mpb_PMPrefs.pmp_Intermediate, sizeof(inst->mpb_PMPrefs.pmp_Intermediate) ); + GetPreferences(myPrefsHandle, lID, PMP_TransparencyBlur, &inst->mpb_PMPrefs.pmp_TransparencyBlur, sizeof(inst->mpb_PMPrefs.pmp_TransparencyBlur) ); + GetPreferences(myPrefsHandle, lID, PMP_TextDisplace, &inst->mpb_PMPrefs.pmp_TextDisplace, sizeof(inst->mpb_PMPrefs.pmp_TextDisplace) ); + GetPreferences(myPrefsHandle, lID, PMP_MenuTitleStyle, &inst->mpb_PMPrefs.pmp_MenuTitles, sizeof(inst->mpb_PMPrefs.pmp_MenuTitles) ); + GetPreferences(myPrefsHandle, lID, PMP_MenuItemStyle, &inst->mpb_PMPrefs.pmp_MenuItems, sizeof(inst->mpb_PMPrefs.pmp_MenuItems) ); + + FreePrefsHandle(myPrefsHandle); + } + + if (RETURN_OK == Result) + { + if (inst->mpb_fCreateIcons) + SaveIcon(inst, FilenameNew); + } + else + { + char Buffer[120]; + + Fault(Result, "", Buffer, sizeof(Buffer) - 1); + + // MUI_RequestA() + MUI_Request(inst->mpb_Objects[OBJNDX_APP_Main], inst->mpb_Objects[OBJNDX_WIN_Main], 0, NULL, + GetLocString(MSGID_ABOUTREQOK), + GetLocString(MSGID_REQTITLE_SAVEERROR), + FilenameNew, + Buffer); + } + + d1(KPrintF("%s/%s/%ld: pmp_MenuTitles=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->mpb_PMPrefs.pmp_MenuTitles)); + d1(KPrintF("%s/%s/%ld: pmp_MenuItems=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->mpb_PMPrefs.pmp_MenuItems)); + d1(KPrintF("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + + return Result; +} + + +static LONG WritePrefsFile(struct PopupMenuPrefsInst *inst, CONST_STRPTR Filename) +{ + APTR myPrefsHandle; + LONG Result = RETURN_OK; + WORD wValue; + + GUItoPrefs(inst, &inst->mpb_PMPrefs); + + myPrefsHandle = AllocPrefsHandle("PopupMenuPrefs"); + if (myPrefsHandle) + { + LONG lID = MAKE_ID('M', 'A', 'I', 'N'); + + SetPreferences(myPrefsHandle, lID, PMP_Flags, &inst->mpb_PMPrefs.pmp_Flags, sizeof(inst->mpb_PMPrefs.pmp_Flags) ); + SetPreferences(myPrefsHandle, lID, PMP_SubMenuDelay, &inst->mpb_PMPrefs.pmp_SubMenuDelay, sizeof(inst->mpb_PMPrefs.pmp_SubMenuDelay) ); + SetPreferences(myPrefsHandle, lID, PMP_AnimationType, &inst->mpb_PMPrefs.pmp_Animation, sizeof(inst->mpb_PMPrefs.pmp_Animation) ); + SetPreferences(myPrefsHandle, lID, PMP_PullDownMenuPos, &inst->mpb_PMPrefs.pmp_PulldownPos, sizeof(inst->mpb_PMPrefs.pmp_PulldownPos) ); + + wValue = SCA_WORD2BE(inst->mpb_PMPrefs.pmp_Sticky); + SetPreferences(myPrefsHandle, lID, PMP_Sticky, &wValue, sizeof(wValue) ); + + SetPreferences(myPrefsHandle, lID, PMP_MenuBorderType, &inst->mpb_PMPrefs.pmp_MenuBorder, sizeof(inst->mpb_PMPrefs.pmp_MenuBorder) ); + SetPreferences(myPrefsHandle, lID, PMP_SelItemBorderType, &inst->mpb_PMPrefs.pmp_SelItemBorder, sizeof(inst->mpb_PMPrefs.pmp_SelItemBorder) ); + SetPreferences(myPrefsHandle, lID, PMP_SeparatorBarStyle, &inst->mpb_PMPrefs.pmp_SeparatorBar, sizeof(inst->mpb_PMPrefs.pmp_SeparatorBar) ); + SetPreferences(myPrefsHandle, lID, PMP_XOffset, &inst->mpb_PMPrefs.pmp_XOffset, sizeof(inst->mpb_PMPrefs.pmp_XOffset) ); + SetPreferences(myPrefsHandle, lID, PMP_YOffset, &inst->mpb_PMPrefs.pmp_YOffset, sizeof(inst->mpb_PMPrefs.pmp_YOffset) ); + SetPreferences(myPrefsHandle, lID, PMP_XSpace, &inst->mpb_PMPrefs.pmp_XSpace, sizeof(inst->mpb_PMPrefs.pmp_XSpace) ); + SetPreferences(myPrefsHandle, lID, PMP_YSpace, &inst->mpb_PMPrefs.pmp_YSpace, sizeof(inst->mpb_PMPrefs.pmp_YSpace) ); + SetPreferences(myPrefsHandle, lID, PMP_Intermediate, &inst->mpb_PMPrefs.pmp_Intermediate, sizeof(inst->mpb_PMPrefs.pmp_Intermediate) ); + SetPreferences(myPrefsHandle, lID, PMP_TransparencyBlur, &inst->mpb_PMPrefs.pmp_TransparencyBlur, sizeof(inst->mpb_PMPrefs.pmp_TransparencyBlur) ); + SetPreferences(myPrefsHandle, lID, PMP_TextDisplace, &inst->mpb_PMPrefs.pmp_TextDisplace, sizeof(inst->mpb_PMPrefs.pmp_TextDisplace) ); + SetPreferences(myPrefsHandle, lID, PMP_MenuTitleStyle, &inst->mpb_PMPrefs.pmp_MenuTitles, sizeof(inst->mpb_PMPrefs.pmp_MenuTitles) ); + SetPreferences(myPrefsHandle, lID, PMP_MenuItemStyle, &inst->mpb_PMPrefs.pmp_MenuItems, sizeof(inst->mpb_PMPrefs.pmp_MenuItems) ); + + WritePrefsHandle(myPrefsHandle, Filename); + + FreePrefsHandle(myPrefsHandle); + } + + return Result; +} + + +static LONG SaveIcon(struct PopupMenuPrefsInst *inst, CONST_STRPTR IconName) +{ + struct DiskObject *icon, *allocIcon; + + static UBYTE ImageData[] = + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0x80, 0x00, 0x40, 0x00, 0x00, 0x00, 0x18, 0x00, 0x60, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x20, 0xFC, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x41, 0x02, 0x08, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x40, 0x82, 0x08, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x40, 0x82, 0x08, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x21, 0x04, 0x08, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x1E, 0x18, 0x10, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x20, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x02, 0x1C, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x0C, 0x00, + 0x40, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x0C, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, + 0xD5, 0x55, 0x55, 0x55, 0x55, 0x56, 0x00, 0x00, 0xD5, 0x55, 0x50, 0x00, 0x55, 0x55, 0x80, 0x00, + 0xD5, 0x55, 0x47, 0xFF, 0x95, 0x55, 0x60, 0x00, 0xD5, 0x55, 0x5F, 0x03, 0xE5, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x3E, 0x55, 0xF5, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x3F, 0x55, 0xF5, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x3F, 0x55, 0xF5, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x5E, 0x53, 0xF5, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x41, 0x47, 0xE5, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x55, 0x1F, 0xD5, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x55, 0x7F, 0x15, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x54, 0xFC, 0x55, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x55, 0xE1, 0x55, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x54, 0xF5, 0x55, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x55, 0x05, 0x55, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x54, 0xF5, 0x55, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x54, 0xF5, 0x55, 0x55, 0x50, 0x00, 0x35, 0x55, 0x55, 0x05, 0x55, 0x55, 0x50, 0x00, + 0x0D, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, 0x00, 0x03, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + static struct Image NormalImage = + { + 0, 0, 54, 23, + 2, + (UWORD *)ImageData, + 3, 0, + NULL + }; + + static STRPTR defToolTypes[] = + { + "ACTION=USE", + NULL + }; + + static struct DiskObject DefaultIcon = + { + WB_DISKMAGIC, WB_DISKVERSION, + + { + NULL, + 0, 0, 54, 24, + GFLG_GADGIMAGE | GFLG_GADGHBOX, + GACT_RELVERIFY | GACT_IMMEDIATE, + GTYP_BOOLGADGET, + &NormalImage, NULL, + NULL, + 0, + NULL, + 0, + NULL + }, + + WBPROJECT, + NULL, + defToolTypes, + NO_ICON_POSITION, NO_ICON_POSITION, + NULL, + NULL, + 8192 + }; + + icon = allocIcon = GetDiskObject("ENV:sys/def_ScaPopupMenuPrefs"); + if (NULL == icon) + icon = allocIcon = GetDiskObject("ENV:sys/def_pref"); + if (NULL == icon) + icon = &DefaultIcon; + + if (icon) + { + STRPTR oldDefaultTool = icon->do_DefaultTool; + + icon->do_DefaultTool = (STRPTR) inst->mpb_ProgramName; + + PutDiskObject((STRPTR) IconName, icon); + + icon->do_DefaultTool = oldDefaultTool; + + if (allocIcon) + FreeDiskObject(allocIcon); + } + + return 0; +} + + +static SAVEDS(APTR) INTERRUPT AppMessageHookFunc(struct Hook *hook, Object *o, Msg msg) +{ +#if 0 + struct PopupMenuPrefsInst *inst = (struct PopupMenuPrefsInst *) hook->h_Data; + struct AppMessage *AppMsg = *(struct AppMessage **) msg; + struct MUI_NListtree_TreeNode *TreeNode = NULL; + + set(inst->mpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Quiet, TRUE); + + TreeNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, MUIV_NListtree_GetEntry_ListNode_Active, + MUIV_NListtree_GetEntry_Position_Active, 0); + + if (TreeNode) + { + struct MUI_NListtree_TreeNode *ParentNode = (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_PrevNode_Tail; + LONG n; + + for (n=0; nam_NumArgs; ) + { + struct PopupMenuListEntry *mle = (struct PopupMenuListEntry *) TreeNode->tn_User; + char Buffer[1000]; + STRPTR FileName; + + if (!NameFromLock(AppMsg->am_ArgList[n].wa_Lock, Buffer, sizeof(Buffer))) + break; + if (AppMsg->am_ArgList[n].wa_Name && strlen(AppMsg->am_ArgList[n].wa_Name) > 0) + AddPart(Buffer, AppMsg->am_ArgList[n].wa_Name, sizeof(Buffer)); + + FileName = FilePart(Buffer); + + switch (mle->llist_EntryType) + { + case SCAPopupMenuTYPE_MainPopupMenu: + d1(kprintf("%s/%s/%ld: insert at SCAPopupMenuTYPE_MainPopupMenu\n", __FILE__, __FUNC__, __LINE__)); + if (mle->llist_Flags & LLISTFLGF_MayNotHaveChildren) + { + AppMessage_PopupMenu(inst, &TreeNode, &ParentNode, &AppMsg->am_ArgList[n], Buffer, FileName); + n++; + } + else + { + TreeNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_Insert, "DragIn PopupMenu", + CombineEntryTypeAndFlags(SCAPopupMenuTYPE_PopupMenu, 0), + TreeNode, ParentNode, TNF_OPEN | TNF_LIST); + } + break; + + case SCAPopupMenuTYPE_PopupMenu: + case SCAPopupMenuTYPE_ToolsPopupMenu: + d1(kprintf("%s/%s/%ld: insert at SCAPopupMenuTYPE_PopupMenu\n", __FILE__, __FUNC__, __LINE__)); + AppMessage_PopupMenu(inst, &TreeNode, &ParentNode, &AppMsg->am_ArgList[n], Buffer, FileName); + n++; + break; + + case SCAPopupMenuTYPE_PopupMenuItem: + d1(kprintf("%s/%s/%ld: insert at SCAPopupMenuTYPE_PopupMenuItem\n", __FILE__, __FUNC__, __LINE__)); + ParentNode = TreeNode; + TreeNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, TreeNode, MUIV_NListtree_GetEntry_Position_Parent, 0); + + AppMessage_PopupMenu(inst, &TreeNode, &ParentNode, &AppMsg->am_ArgList[n], Buffer, FileName); + n++; + break; + + case SCAPopupMenuTYPE_Command: + d1(kprintf("%s/%s/%ld: insert at SCAPopupMenuTYPE_Command\n", __FILE__, __FUNC__, __LINE__)); + TreeNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree], + MUIM_NListtree_GetEntry, TreeNode, MUIV_NListtree_GetEntry_Position_Parent, 0); + break; + + default: + break; + } + } + } + + set(inst->mpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Quiet, FALSE); +#endif + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT SettingsChangedHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PopupMenuPrefsInst *inst = (struct PopupMenuPrefsInst *) hook->h_Data; + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + SetChangedFlag(inst, TRUE); + + return NULL; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT AslIntuiMsgHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PopupMenuPrefsInst *inst = (struct PopupMenuPrefsInst *) hook->h_Data; + struct IntuiMessage *iMsg = (struct IntuiMessage *) msg; + + if (IDCMP_REFRESHWINDOW == iMsg->Class) + { + DoMethod(inst->mpb_Objects[OBJNDX_APP_Main], MUIM_Application_CheckRefresh); + } +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT FrameTypeSelectHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PopupMenuPrefsInst *inst = (struct PopupMenuPrefsInst *) hook->h_Data; + + set(o, MUIA_Selected, TRUE); + + // turn off selected state for all frame type buttons except + if (o != inst->mpb_Objects[OBJNDX_Button_FrameThin]) + set(inst->mpb_Objects[OBJNDX_Button_FrameThin], MUIA_Selected, FALSE); + if (o != inst->mpb_Objects[OBJNDX_Button_FrameMM]) + set(inst->mpb_Objects[OBJNDX_Button_FrameMM], MUIA_Selected, FALSE); + if (o != inst->mpb_Objects[OBJNDX_Button_FrameThick]) + set(inst->mpb_Objects[OBJNDX_Button_FrameThick], MUIA_Selected, FALSE); + if (o != inst->mpb_Objects[OBJNDX_Button_FrameRidge]) + set(inst->mpb_Objects[OBJNDX_Button_FrameRidge], MUIA_Selected, FALSE); + if (o != inst->mpb_Objects[OBJNDX_Button_FrameDropBox]) + set(inst->mpb_Objects[OBJNDX_Button_FrameDropBox], MUIA_Selected, FALSE); + if (o != inst->mpb_Objects[OBJNDX_Button_FrameOldStyle]) + set(inst->mpb_Objects[OBJNDX_Button_FrameOldStyle], MUIA_Selected, FALSE); +} + +//---------------------------------------------------------------------------- + +static SAVEDS(void) INTERRUPT SelFrameTypeSelectHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct PopupMenuPrefsInst *inst = (struct PopupMenuPrefsInst *) hook->h_Data; + + set(o, MUIA_Selected, TRUE); + + // turn off selected state for all selected frame type buttons except + if (o != inst->mpb_Objects[OBJNDX_Button_Raised]) + set(inst->mpb_Objects[OBJNDX_Button_Raised], MUIA_Selected, FALSE); + if (o != inst->mpb_Objects[OBJNDX_Button_Normal]) + set(inst->mpb_Objects[OBJNDX_Button_Normal], MUIA_Selected, FALSE); + if (o != inst->mpb_Objects[OBJNDX_Button_Recessed]) + set(inst->mpb_Objects[OBJNDX_Button_Recessed], MUIA_Selected, FALSE); +} + +//---------------------------------------------------------------------------- + +static void PrefsToGUI(struct PopupMenuPrefsInst *inst, const struct PopupMenuPrefs *pmPrefs) +{ + switch (pmPrefs->pmp_MenuBorder) + { + case PMP_MENUBORDER_THIN: + default: + set(inst->mpb_Objects[OBJNDX_Button_FrameThin], MUIA_Selected, TRUE); + break; + case PMP_MENUBORDER_MM: + set(inst->mpb_Objects[OBJNDX_Button_FrameMM], MUIA_Selected, TRUE); + break; + case PMP_MENUBORDER_THICK: + set(inst->mpb_Objects[OBJNDX_Button_FrameThick], MUIA_Selected, TRUE); + break; + case PMP_MENUBORDER_RIDGE: + set(inst->mpb_Objects[OBJNDX_Button_FrameRidge], MUIA_Selected, TRUE); + break; + case PMP_MENUBORDER_DROPBOX: + set(inst->mpb_Objects[OBJNDX_Button_FrameDropBox], MUIA_Selected, TRUE); + break; + case PMP_MENUBORDER_OLDSTYLE: + set(inst->mpb_Objects[OBJNDX_Button_FrameOldStyle], MUIA_Selected, TRUE); + break; + } + + switch (pmPrefs->pmp_SelItemBorder) + { + case PMP_SELITEM_NO_BORDER: + default: + set(inst->mpb_Objects[OBJNDX_Button_Normal], MUIA_Selected, TRUE); + break; + case PMP_SELITEM_RAISE: + set(inst->mpb_Objects[OBJNDX_Button_Raised], MUIA_Selected, TRUE); + break; + case PMP_SELITEM_RECESS: + set(inst->mpb_Objects[OBJNDX_Button_Recessed], MUIA_Selected, TRUE); + break; + } + + if (pmPrefs->pmp_SeparatorBar) + set(inst->mpb_Objects[OBJNDX_CheckMark_OldLook], MUIA_Selected, TRUE); + else + set(inst->mpb_Objects[OBJNDX_CheckMark_NewLook], MUIA_Selected, TRUE); + + setslider(inst->mpb_Objects[OBJNDX_Slider_DelaySubMenus], pmPrefs->pmp_SubMenuDelay); + + setslider(inst->mpb_Objects[OBJNDX_Slider_Horizontal], pmPrefs->pmp_XOffset); + setslider(inst->mpb_Objects[OBJNDX_Slider_VerticalOffset], pmPrefs->pmp_YOffset); + setslider(inst->mpb_Objects[OBJNDX_Slider_HorizontalSpacing], pmPrefs->pmp_XSpace); + setslider(inst->mpb_Objects[OBJNDX_Slider_VerticalSpacing], pmPrefs->pmp_YSpace); + setslider(inst->mpb_Objects[OBJNDX_Slider_IntermediateSpacing], pmPrefs->pmp_Intermediate); + setslider(inst->mpb_Objects[OBJNDX_Slider_TextDisplacement], pmPrefs->pmp_TextDisplace); + + setcycle(inst->mpb_Objects[OBJNDX_Cycle_AnimationType], pmPrefs->pmp_Animation); + + setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_Sticky], pmPrefs->pmp_Sticky); + + d1(KPrintF("%s/%s/%ld: pmp_MenuTitles=%08lx\n", __FILE__, __FUNC__, __LINE__, pmPrefs->pmp_MenuTitles)); + d1(KPrintF("%s/%s/%ld: pmp_MenuItems=%08lx\n", __FILE__, __FUNC__, __LINE__, pmPrefs->pmp_MenuItems)); + + setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Embossed], pmPrefs->pmp_MenuTitles & PMP_TITLE_EMBOSS); + setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Outlined], pmPrefs->pmp_MenuTitles & PMP_TEXT_OUTLINE); + setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Shadowed], pmPrefs->pmp_MenuTitles & PMP_TEXT_SHADOW); + setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Underlined], pmPrefs->pmp_MenuTitles & PMP_TEXT_UNDERLINE); + setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Bold], pmPrefs->pmp_MenuTitles & PMP_TEXT_BOLD); + setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Italic], pmPrefs->pmp_MenuTitles & PMP_TEXT_ITALIC); + + setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Embossed], pmPrefs->pmp_MenuItems & PMP_TEXT_EMBOSS); + setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Outlined], pmPrefs->pmp_MenuItems & PMP_TEXT_OUTLINE); + setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Shadowed], pmPrefs->pmp_MenuItems & PMP_TEXT_SHADOW); + setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Underlined], pmPrefs->pmp_MenuItems & PMP_TEXT_UNDERLINE); + setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Bold], pmPrefs->pmp_MenuItems & PMP_TEXT_BOLD); + setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Italic], pmPrefs->pmp_MenuItems & PMP_TEXT_ITALIC); + + setslider(inst->mpb_Objects[OBJNDX_Slider_Transp_Blur], pmPrefs->pmp_TransparencyBlur); + setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_Transparency_Enable], pmPrefs->pmp_Flags & PMP_FLAGS_TRANSPARENCY); + set(inst->mpb_Objects[OBJNDX_Group_Transp_Blur], MUIA_Disabled, !(pmPrefs->pmp_Flags & PMP_FLAGS_TRANSPARENCY)); + + setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_MenuShadows], pmPrefs->pmp_Flags & PMP_FLAGS_SHADOWS); + set(inst->mpb_Objects[OBJNDX_CheckMark_RealShadows], MUIA_Disabled, !(pmPrefs->pmp_Flags & PMP_FLAGS_SHADOWS)); +} + +//---------------------------------------------------------------------------- + +static void GUItoPrefs(struct PopupMenuPrefsInst *inst, struct PopupMenuPrefs *pmPrefs) +{ + if (getv(inst->mpb_Objects[OBJNDX_Button_FrameThin], MUIA_Selected)) + pmPrefs->pmp_MenuBorder = PMP_MENUBORDER_THIN; + else if (getv(inst->mpb_Objects[OBJNDX_Button_FrameMM], MUIA_Selected)) + pmPrefs->pmp_MenuBorder = PMP_MENUBORDER_MM; + else if (getv(inst->mpb_Objects[OBJNDX_Button_FrameThick], MUIA_Selected)) + pmPrefs->pmp_MenuBorder = PMP_MENUBORDER_THICK; + else if (getv(inst->mpb_Objects[OBJNDX_Button_FrameRidge], MUIA_Selected)) + pmPrefs->pmp_MenuBorder = PMP_MENUBORDER_RIDGE; + else if (getv(inst->mpb_Objects[OBJNDX_Button_FrameDropBox], MUIA_Selected)) + pmPrefs->pmp_MenuBorder = PMP_MENUBORDER_DROPBOX; + else if (getv(inst->mpb_Objects[OBJNDX_Button_FrameOldStyle], MUIA_Selected)) + pmPrefs->pmp_MenuBorder = PMP_MENUBORDER_OLDSTYLE; + else + pmPrefs->pmp_MenuBorder = PMP_MENUBORDER_THIN; + + if (getv(inst->mpb_Objects[OBJNDX_Button_Normal], MUIA_Selected)) + pmPrefs->pmp_SelItemBorder = PMP_SELITEM_NO_BORDER; + else if (getv(inst->mpb_Objects[OBJNDX_Button_Raised], MUIA_Selected)) + pmPrefs->pmp_SelItemBorder = PMP_SELITEM_RAISE; + else if (getv(inst->mpb_Objects[OBJNDX_Button_Recessed], MUIA_Selected)) + pmPrefs->pmp_SelItemBorder = PMP_SELITEM_RECESS; + else + pmPrefs->pmp_SelItemBorder = PMP_SELITEM_NO_BORDER; + + if (getv(inst->mpb_Objects[OBJNDX_CheckMark_OldLook], MUIA_Selected)) + pmPrefs->pmp_SeparatorBar = TRUE; + else + pmPrefs->pmp_SeparatorBar = FALSE; + + pmPrefs->pmp_SubMenuDelay = getv(inst->mpb_Objects[OBJNDX_Slider_DelaySubMenus], MUIA_Numeric_Value); + + pmPrefs->pmp_XOffset = getv(inst->mpb_Objects[OBJNDX_Slider_Horizontal], MUIA_Numeric_Value); + pmPrefs->pmp_YOffset = getv(inst->mpb_Objects[OBJNDX_Slider_VerticalOffset], MUIA_Numeric_Value); + pmPrefs->pmp_XSpace = getv(inst->mpb_Objects[OBJNDX_Slider_HorizontalSpacing], MUIA_Numeric_Value); + pmPrefs->pmp_YSpace = getv(inst->mpb_Objects[OBJNDX_Slider_VerticalSpacing], MUIA_Numeric_Value); + pmPrefs->pmp_Intermediate = getv(inst->mpb_Objects[OBJNDX_Slider_IntermediateSpacing], MUIA_Numeric_Value); + pmPrefs->pmp_TextDisplace = getv(inst->mpb_Objects[OBJNDX_Slider_TextDisplacement], MUIA_Numeric_Value); + + pmPrefs->pmp_Animation = getv(inst->mpb_Objects[OBJNDX_Cycle_AnimationType], MUIA_Cycle_Active); + + pmPrefs->pmp_Sticky = getv(inst->mpb_Objects[OBJNDX_CheckMark_Sticky], MUIA_Selected); + + if (getv(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Embossed], MUIA_Selected)) + pmPrefs->pmp_MenuTitles |= PMP_TITLE_EMBOSS; + else + pmPrefs->pmp_MenuTitles &= ~PMP_TITLE_EMBOSS; + if (getv(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Outlined], MUIA_Selected)) + pmPrefs->pmp_MenuTitles |= PMP_TEXT_OUTLINE; + else + pmPrefs->pmp_MenuTitles &= ~PMP_TEXT_OUTLINE; + if (getv(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Shadowed], MUIA_Selected)) + pmPrefs->pmp_MenuTitles |= PMP_TEXT_SHADOW; + else + pmPrefs->pmp_MenuTitles &= ~PMP_TEXT_SHADOW; + if (getv(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Underlined], MUIA_Selected)) + pmPrefs->pmp_MenuTitles |= PMP_TEXT_UNDERLINE; + else + pmPrefs->pmp_MenuTitles &= ~PMP_TEXT_UNDERLINE; + if (getv(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Bold], MUIA_Selected)) + pmPrefs->pmp_MenuTitles |= PMP_TEXT_BOLD; + else + pmPrefs->pmp_MenuTitles &= ~PMP_TEXT_BOLD; + if (getv(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Italic], MUIA_Selected)) + pmPrefs->pmp_MenuTitles |= PMP_TEXT_ITALIC; + else + pmPrefs->pmp_MenuTitles &= ~PMP_TEXT_ITALIC; + d1(KPrintF("%s/%s/%ld: pmp_MenuTitles=%08lx\n", __FILE__, __FUNC__, __LINE__, pmPrefs->pmp_MenuTitles)); + + if (getv(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Embossed], MUIA_Selected)) + pmPrefs->pmp_MenuItems |= PMP_TEXT_EMBOSS; + else + pmPrefs->pmp_MenuItems &= ~PMP_TEXT_EMBOSS; + if (getv(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Outlined], MUIA_Selected)) + pmPrefs->pmp_MenuItems |= PMP_TEXT_OUTLINE; + else + pmPrefs->pmp_MenuItems &= ~PMP_TEXT_OUTLINE; + if (getv(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Shadowed], MUIA_Selected)) + pmPrefs->pmp_MenuItems |= PMP_TEXT_SHADOW; + else + pmPrefs->pmp_MenuItems &= ~PMP_TEXT_SHADOW; + if (getv(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Underlined], MUIA_Selected)) + pmPrefs->pmp_MenuItems |= PMP_TEXT_UNDERLINE; + else + pmPrefs->pmp_MenuItems &= ~PMP_TEXT_UNDERLINE; + if (getv(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Bold], MUIA_Selected)) + pmPrefs->pmp_MenuItems |= PMP_TEXT_BOLD; + else + pmPrefs->pmp_MenuItems &= ~PMP_TEXT_BOLD; + if (getv(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Italic], MUIA_Selected)) + pmPrefs->pmp_MenuItems |= PMP_TEXT_ITALIC; + else + pmPrefs->pmp_MenuItems &= ~PMP_TEXT_ITALIC; + d1(KPrintF("%s/%s/%ld: pmp_MenuItems=%08lx\n", __FILE__, __FUNC__, __LINE__, pmPrefs->pmp_MenuItems)); + + pmPrefs->pmp_TransparencyBlur = getv(inst->mpb_Objects[OBJNDX_Slider_Transp_Blur], MUIA_Numeric_Value); + + if (getv(inst->mpb_Objects[OBJNDX_CheckMark_Transparency_Enable], MUIA_Selected)) + pmPrefs->pmp_Flags |= PMP_FLAGS_TRANSPARENCY; + else + pmPrefs->pmp_Flags &= ~PMP_FLAGS_TRANSPARENCY; +} + +//---------------------------------------------------------------------------- + +void _XCEXIT(long x) +{ +} + + +static Object *CreatePrefsImage(void) +{ + Object *img; + + // First try to load datatypes image from THEME: tree + img = DataTypesImageObject, + MUIA_ScaDtpic_Name, (ULONG) "THEME:prefs/plugins/popupmenu", + MUIA_ScaDtpic_FailIfUnavailable, TRUE, + End; //DataTypesMCCObject + + if (NULL == img) + img = IMG(PopupMenuPrefs, POPUPMENUPREFS); // use built-in fallback image + + return img; +} + + +static void InitHooks(struct PopupMenuPrefsInst *inst) +{ + ULONG n; + + for (n=0; nmpb_Hooks[n] = PopupMenuPrefsHooks[n]; + inst->mpb_Hooks[n].h_Data = inst; + } +} + + +static void SetChangedFlag(struct PopupMenuPrefsInst *inst, BOOL changed) +{ + if (changed != inst->mpb_Changed) + { + set(inst->mpb_Objects[OBJNDX_Lamp_Changed], + MUIA_Lamp_Color, changed ? MUIV_Lamp_Color_Ok : MUIV_Lamp_Color_Off); + inst->mpb_Changed = changed; + } +} + +//----------------------------------------------------------------- + +static void ParseToolTypes(struct PopupMenuPrefsInst *inst, struct MUIP_ScalosPrefs_ParseToolTypes *ptt) +{ +#if 0 + STRPTR tt; + + d1(kprintf("%s/%ld: start ptt=%08lx tooltypes=%08lx\n", __FUNC__, __LINE__, ptt, ptt->ToolTypes)); + d1(kprintf("%s/%ld: start tooltypes=%08lx %08lx %08lx\n", __FUNC__, __LINE__, ptt, ptt->ToolTypes[0], ptt->ToolTypes[1], ptt->ToolTypes[2])); + +#endif + d1(kprintf("%s/%ld: end\n", __FUNC__, __LINE__)); +} + +//---------------------------------------------------------------------------- + +BOOL initPlugin(struct PluginBase *PluginBase) +{ + MajorVersion = PluginBase->pl_LibNode.lib_Version; + MinorVersion = PluginBase->pl_LibNode.lib_Revision; + + d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__)); + + if (0x4711 == SIgnature++) + { + d1(kprintf("%s/%s/%ld: PluginBase=%08lx procName=<%s>\n", __FILE__, __FUNC__, __LINE__, \ + PluginBase, FindTask(NULL)->tc_Node.ln_Name)); + + d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__)); + + d1(kprintf("%s/%s/%ld: PopupMenuPrefsLibBase=%08lx procName=<%s>\n", __FILE__, __FUNC__, __LINE__, \ + PopupMenuPrefsLibBase, FindTask(NULL)->tc_Node.ln_Name)); + +#ifndef __amigaos4__ + DOSBase = (struct DosLibrary *) OpenLibrary(DOSNAME, 39 ); +#else + DOSBase = OpenLibrary(DOSNAME, 39); +#endif + + d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__)); + + if (!OpenLibraries()) + return FALSE; + + d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__)); + +#if !defined(__amigaos4__) && !defined(__AROS__) + if (_STI_240_InitMemFunctions()) + return FALSE; +#endif + + d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__)); + + PopupMenuPrefsClass = MUI_CreateCustomClass(&PluginBase->pl_LibNode, MUIC_Group, + NULL, sizeof(struct PopupMenuPrefsInst), DISPATCHER_REF(PopupMenuPrefs)); + + d1(kprintf("%s/%s/%ld: PopupMenuPrefsClass=%08lx\n", __FILE__, __FUNC__, __LINE__, PopupMenuPrefsClass)); + if (NULL == PopupMenuPrefsClass) + return FALSE; + + FrameButtonClass = InitFrameButtonClass(); + d1(KPrintF("%s/%s/%ld: FrameButtonClass=%08lx\n", __FILE__, __FUNC__, __LINE__, FrameButtonClass)); + if (NULL == FrameButtonClass) + return FALSE; + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + DataTypesImageClass = InitDtpicClass(); + d1(KPrintF(__FUNC__ "/%ld: DataTypesImageClass=%08lx\n", __LINE__, DataTypesImageClass)); + if (NULL == DataTypesImageClass) + return FALSE; // Failure + + if (LocaleBase) + { + if (NULL == PopupMenuPrefsLocale) + PopupMenuPrefsLocale = OpenLocale(NULL); + + if (PopupMenuPrefsLocale) + { + if (NULL == PopupMenuPrefsCatalog) + { + PopupMenuPrefsCatalog = OpenCatalog(PopupMenuPrefsLocale, + (STRPTR) "Scalos/ScalosPopupMenu.catalog", NULL); + } + } + } + + TranslateStringArray(PrefsPageNames); + TranslateStringArray(AnimationNames); + } + + d1(KPrintF("%s/%s/%ld: success\n", __FILE__, __FUNC__, __LINE__)); + + return TRUE; // Success +} + +//---------------------------------------------------------------------------- + +static IPTR getv(APTR obj, ULONG attr) +{ + IPTR v; + GetAttr(attr, obj, &v); + return (v); +} + +//---------------------------------------------------------------------------- + +static LONG ReadOldPrefsFile(CONST_STRPTR Filename, struct oldPopupMenuPrefs *prefs, const struct oldPopupMenuPrefs *defaultPrefs) +{ + LONG Result; + struct IFFHandle *iff; + BOOL iffOpened = FALSE; + + d1(KPrintF("%s/%s/%ld: Filename=<%s> LocaleBase=%08lx IFFParseBase=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, Filename, LocaleBase, IFFParseBase)); + + do { + *prefs = *defaultPrefs; + + iff = AllocIFF(); + if (NULL == iff) + { + Result = IoErr(); + break; + } + + InitIFFasDOS(iff); + + iff->iff_Stream = Open(Filename, MODE_OLDFILE); + if ((BPTR)NULL == iff->iff_Stream) + { + Result = IoErr(); + break; + } + + Result = OpenIFF(iff, IFFF_READ); + if (RETURN_OK != Result) + break; + + iffOpened = TRUE; + + Result = StopChunks(iff, StopChunkList, 2); + if (RETURN_OK != Result) + break; + + while (1) + { + struct ContextNode *cn; + + Result = ParseIFF(iff, IFFPARSE_SCAN); + d1(kprintf("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + if (RETURN_OK != Result) + break; + + cn = CurrentChunk(iff); + + d1(KPrintF("%s/%s/%ld: cn=%08lx\n", __FILE__, __FUNC__, __LINE__, cn)); + if (NULL == cn) + break; + + d1(KPrintF("%s/%s/%ld: cn=%08lx id=%08lx\n", __FILE__, __FUNC__, __LINE__, cn, cn->cn_ID)); + if (ID_PMNU == cn->cn_ID) + { + LONG Actual; + + d1(KPrintF("%s/%s/%ld: cn_Size=%lu\n", __FILE__, __FUNC__, __LINE__, cn->cn_Size)); + + if (cn->cn_Size != sizeof(struct oldPopupMenuPrefs)) + break; + + Actual = ReadChunkBytes(iff, prefs, cn->cn_Size); + d1(KPrintF("%s/%s/%ld: Actual=%lu\n", __FILE__, __FUNC__, __LINE__, Actual)); + if (Actual != cn->cn_Size) + break; + } + prefs->pmp_Sticky = SCA_BE2WORD(prefs->pmp_Sticky); + prefs->pmp_SameHeight = SCA_BE2WORD(prefs->pmp_SameHeight); + } + + d1(KPrintF(__FILE__ "%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + if (IFFERR_EOF == Result) + Result = RETURN_OK; + } while (0); + + if (iff) + { + if (iffOpened) + CloseIFF(iff); + + if (iff->iff_Stream) + Close((BPTR)iff->iff_Stream); + + FreeIFF(iff); + } + + d1(KPrintF("%s/%s/%ld: pmp_MenuTitles=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->mpb_PMPrefs.pmp_MenuTitles)); + d1(KPrintF("%s/%s/%ld: pmp_MenuItems=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->mpb_PMPrefs.pmp_MenuItems)); + d1(KPrintF("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + + return Result; +} + +//---------------------------------------------------------------------------- + +static void ConvertPmPrefs(CONST_STRPTR prefsFileOld, CONST_STRPTR prefsFileNew) +{ + BPTR fLock; + + fLock = Lock(prefsFileNew, ACCESS_READ); + if (fLock) + { + UnLock(fLock); + } + else + { + struct oldPopupMenuPrefs LoadedPrefs; + APTR myPrefsHandle; + static const struct oldPopupMenuPrefs DefaultPrefs = + { + PMP_FLAGS_SHADOWS, /* pmp_Flags */ + 0, /* pmp_SubMenuDelay */ + PMP_ANIM_NONE, /* pmp_Animation */ + PMP_PD_SCREENBAR, /* pmp_PulldownPos */ + FALSE, /* pmp_Sticky */ + FALSE, /* pmp_SameHeight unused */ + 0, /* pmp_MenuBorder */ + 0, /* pmp_SelItemBorder */ + 0, /* pmp_SeparatorBar */ + 0, /* pmp_MenuTitles */ + 0, /* pmp_MenuItems */ + 2, /* pmp_XOffset */ + 2, /* pmp_YOffset */ + 2, /* pmp_XSpace */ + 2, /* pmp_YSpace */ + 2, /* pmp_Intermediate */ + 0, /* pmp_TextDisplace */ + -30, /* pmp_ShadowR unused */ + -30, /* pmp_ShadowG unused */ + -30, /* pmp_ShadowB unused */ + 0, /* pmp_TransparencyR unused */ + 0, /* pmp_TransparencyG unused */ + 0, /* pmp_TransparencyB unused */ + 0, /* pmp_TransparencyBlur */ + 0, /* pmp_AnimationSpeed unused */ + + {0}, /* pmp_Reserved */ + }; + + ReadOldPrefsFile(prefsFileOld, &LoadedPrefs, &DefaultPrefs); + + d1(KPrintF("%s/%s/%ld: pmp_Animation=%ld\n", __FILE__, __FUNC__, __LINE__, LoadedPrefs.pmp_Animation)); + + myPrefsHandle = AllocPrefsHandle("PopupMenuPrefs"); + if (myPrefsHandle) + { + LONG lID = MAKE_ID('M', 'A', 'I', 'N'); + + SetPreferences(myPrefsHandle, lID, PMP_Flags, &LoadedPrefs.pmp_Flags, sizeof(LoadedPrefs.pmp_Flags) ); + SetPreferences(myPrefsHandle, lID, PMP_SubMenuDelay, &LoadedPrefs.pmp_SubMenuDelay, sizeof(LoadedPrefs.pmp_SubMenuDelay) ); + SetPreferences(myPrefsHandle, lID, PMP_AnimationType, &LoadedPrefs.pmp_Animation, sizeof(LoadedPrefs.pmp_Animation) ); + SetPreferences(myPrefsHandle, lID, PMP_PullDownMenuPos, &LoadedPrefs.pmp_PulldownPos, sizeof(LoadedPrefs.pmp_PulldownPos) ); + + LoadedPrefs.pmp_Sticky = SCA_WORD2BE(LoadedPrefs.pmp_Sticky); + SetPreferences(myPrefsHandle, lID, PMP_Sticky, &LoadedPrefs.pmp_Sticky, sizeof(LoadedPrefs.pmp_Sticky) ); + + SetPreferences(myPrefsHandle, lID, PMP_MenuBorderType, &LoadedPrefs.pmp_MenuBorder, sizeof(LoadedPrefs.pmp_MenuBorder) ); + SetPreferences(myPrefsHandle, lID, PMP_SelItemBorderType, &LoadedPrefs.pmp_SelItemBorder, sizeof(LoadedPrefs.pmp_SelItemBorder) ); + SetPreferences(myPrefsHandle, lID, PMP_SeparatorBarStyle, &LoadedPrefs.pmp_SeparatorBar, sizeof(LoadedPrefs.pmp_SeparatorBar) ); + SetPreferences(myPrefsHandle, lID, PMP_XOffset, &LoadedPrefs.pmp_XOffset, sizeof(LoadedPrefs.pmp_XOffset) ); + SetPreferences(myPrefsHandle, lID, PMP_YOffset, &LoadedPrefs.pmp_YOffset, sizeof(LoadedPrefs.pmp_YOffset) ); + SetPreferences(myPrefsHandle, lID, PMP_XSpace, &LoadedPrefs.pmp_XSpace, sizeof(LoadedPrefs.pmp_XSpace) ); + SetPreferences(myPrefsHandle, lID, PMP_YSpace, &LoadedPrefs.pmp_YSpace, sizeof(LoadedPrefs.pmp_YSpace) ); + SetPreferences(myPrefsHandle, lID, PMP_Intermediate, &LoadedPrefs.pmp_Intermediate, sizeof(LoadedPrefs.pmp_Intermediate) ); + SetPreferences(myPrefsHandle, lID, PMP_TransparencyBlur, &LoadedPrefs.pmp_TransparencyBlur, sizeof(LoadedPrefs.pmp_TransparencyBlur) ); + SetPreferences(myPrefsHandle, lID, PMP_TextDisplace, &LoadedPrefs.pmp_TextDisplace, sizeof(LoadedPrefs.pmp_TextDisplace) ); + SetPreferences(myPrefsHandle, lID, PMP_MenuTitleStyle, &LoadedPrefs.pmp_MenuTitles, sizeof(LoadedPrefs.pmp_MenuTitles) ); + SetPreferences(myPrefsHandle, lID, PMP_MenuItemStyle, &LoadedPrefs.pmp_MenuItems, sizeof(LoadedPrefs.pmp_MenuItems) ); + + WritePrefsHandle(myPrefsHandle, prefsFileNew); + + FreePrefsHandle(myPrefsHandle); + } + } +} + +//---------------------------------------------------------------------------- + +#if !defined(__SASC) && !defined(__amigaos4__) && !defined(__AROS__) +// Replacement for SAS/C library functions + +#if !defined(__MORPHOS__) + +static char *stpblk(const char *q) +{ + while (q && *q && isspace((int) *q)) + q++; + + return (char *) q; +} + +static size_t stccpy(char *dest, const char *src, size_t MaxLen) +{ + size_t Count = 0; + + while (*src && MaxLen > 1) + { + *dest++ = *src++; + MaxLen--; + Count++; + } + *dest = '\0'; + Count++; + + return Count; +} +#endif /*__MORPHOS__*/ + +void exit(int x) +{ + (void) x; + while (1) + ; +} + +APTR _WBenchMsg; + +#endif /* !defined(__SASC) && !defined(__amigaos4__) */ + diff --git a/scalos/Plugins/Prefs/Popupmenu/PopupMenuPrefs.h b/scalos/Plugins/Prefs/Popupmenu/PopupMenuPrefs.h new file mode 100644 index 000000000..940b3cc39 --- /dev/null +++ b/scalos/Plugins/Prefs/Popupmenu/PopupMenuPrefs.h @@ -0,0 +1,174 @@ +// PopupMenuPrefs.h +// $Date$ +// $Revision$ + + +#ifndef SCALOS_POPUPMENUPREFS_H +#define SCALOS_POPUPMENUPREFS_H + +#include + +//---------------------------------------------------------------------------- + +#define PMP_PATH_OLD "ENV:sys/PopupMenu.prefs" +#define PMP_PATH_NEW "ENV:sys/NewPopupMenu.prefs" +#define PMP_S_PATH_OLD "ENVARC:sys/PopupMenu.prefs" +#define PMP_S_PATH_NEW "ENVARC:sys/NewPopupMenu.prefs" + +//---------------------------------------------------------------------------- + +enum HookIndex +{ + HOOKNDX_ImagePopAslFileStart, + + HOOKNDX_ResetToDefaults, + HOOKNDX_Open, + HOOKNDX_LastSaved, + HOOKNDX_Restore, + HOOKNDX_SaveAs, + + HOOKNDX_About, + HOOKNDX_AppMessage, + HOOKNDX_SettingsChanged, + HOOKNDX_AslIntuiMsg, + + HOOKNDX_FrameSelected, + HOOKNDX_SelFrameSelected, + + HOOKNDX_MAX +}; + +enum ObjectIndex +{ + OBJNDX_APP_Main, + OBJNDX_WIN_Main, + + OBJNDX_Group_Main, + + OBJNDX_Lamp_Changed, + + OBJNDX_Listview_ColorNames, + OBJNDX_CheckMark_UseDrawInfoPens, + + OBJNDX_Slider_DelaySubMenus, + OBJNDX_Cycle_AnimationType, + OBJNDX_CheckMark_MenuShadows, + OBJNDX_CheckMark_Sticky, + + OBJNDX_Cycle_ImageSet, + OBJNDX_PopAsl_LoadImageSet, + + OBJNDX_Button_FrameThin, + OBJNDX_Button_FrameMM, + OBJNDX_Button_FrameThick, + OBJNDX_Button_FrameRidge, + OBJNDX_Button_FrameDropBox, + OBJNDX_Button_FrameOldStyle, + OBJNDX_Button_Normal, + OBJNDX_Button_Raised, + OBJNDX_Button_Recessed, + OBJNDX_CheckMark_NewLook, + OBJNDX_CheckMark_OldLook, + + OBJNDX_Slider_HorizontalSpacing, + OBJNDX_Slider_VerticalSpacing, + OBJNDX_Slider_Horizontal, + OBJNDX_Slider_VerticalOffset, + OBJNDX_Slider_IntermediateSpacing, + OBJNDX_Slider_TextDisplacement, + + OBJNDX_CheckMark_MenuTitles_Italic, + OBJNDX_CheckMark_MenuTitles_Underlined, + OBJNDX_CheckMark_MenuTitles_Bold, + OBJNDX_CheckMark_MenuTitles_Shadowed, + OBJNDX_CheckMark_MenuTitles_Outlined, + OBJNDX_CheckMark_MenuTitles_Embossed, + + OBJNDX_CheckMark_MenuItems_Italic, + OBJNDX_CheckMark_MenuItems_Underlined, + OBJNDX_CheckMark_MenuItems_Bold, + OBJNDX_CheckMark_MenuItems_Shadowed, + OBJNDX_CheckMark_MenuItems_Outlined, + OBJNDX_CheckMark_MenuItems_Embossed, + + OBJNDX_Cycle_PulldownMode, + OBJNDX_Cycle_PulldownLocation, + + OBJNDX_Cycle_ColourPrecision, + OBJNDX_CheckMark_UseWindows, + OBJNDX_CheckMark_RealShadows, + + OBJNDX_Slider_Transp_Blur, + OBJNDX_CheckMark_Transparency_Enable, + OBJNDX_Group_Transp_Blur, + + OBJNDX_MAX +}; + +struct PopupMenuPrefs +{ + UBYTE pmp_Flags; /* Enable shadows, transparency, etc. */ + UBYTE pmp_SubMenuDelay; /* Delay before opening submenus */ + UBYTE pmp_Animation; /* Animation, see below for defines */ + /* (Only one animation effect implemented currently) */ + UBYTE pmp_PulldownPos; /* Where to show pulldownmenus */ + WORD pmp_Sticky; /* Use 'sticky' mode */ + UBYTE pmp_MenuBorder; /* Menu border */ + UBYTE pmp_SelItemBorder; /* Border around selected item */ + UBYTE pmp_SeparatorBar; /* Separator bar style */ + UBYTE pmp_MenuTitles; /* Style flags for drawing menu texts */ + UBYTE pmp_MenuItems; /* Style flags for drawing menu item texts */ + UBYTE pmp_XOffset; + UBYTE pmp_YOffset; + UBYTE pmp_XSpace; + UBYTE pmp_YSpace; + UBYTE pmp_Intermediate; + BYTE pmp_TextDisplace; + UBYTE pmp_TransparencyBlur; +}; + +struct PopupMenuPrefsInst +{ + ULONG mpb_fCreateIcons; + CONST_STRPTR mpb_ProgramName; + + struct Hook mpb_Hooks[HOOKNDX_MAX]; + APTR mpb_Objects[OBJNDX_MAX]; + + ULONG mpb_PageIsActive; + BOOL mpb_Changed; + BOOL mpb_QuietFlag; + + struct Screen *mpb_WBScreen; + + struct FileRequester *mpb_LoadReq; + struct FileRequester *mpb_SaveReq; + + struct PopupMenuPrefs mpb_PMPrefs; +}; + +//---------------------------------------------------------------------------- + +#ifndef Sizeof +#define Sizeof(array) (sizeof(array)/sizeof(array[0])) +#endif + +//---------------------------------------------------------------------------- + +#define d1(x) ; +#define d2(x) x; + +// from debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +//---------------------------------------------------------------------------- + +struct ScalosPopupMenu_LocaleInfo +{ + APTR li_LocaleBase; + APTR li_Catalog; + struct LocaleIFace *li_ILocale; +}; + +#endif /* SCALOS_POPUPMENUPREFS_H */ diff --git a/scalos/Plugins/Prefs/Popupmenu/PopupMenuPrefsImage.h b/scalos/Plugins/Prefs/Popupmenu/PopupMenuPrefsImage.h new file mode 100644 index 000000000..da2df90b2 --- /dev/null +++ b/scalos/Plugins/Prefs/Popupmenu/PopupMenuPrefsImage.h @@ -0,0 +1,1049 @@ +// PopupMenuPrefsImage.c +// $Date$ +// $Revision$ + +//---------------------------------------------------------------------------- +// plugin icon image +//---------------------------------------------------------------------------- + +static const ULONG PopupMenuPrefs_colors[] = +{ + 0x00000000,0x00000000,0x00000000, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0x55555555,0x55555555,0x55555555, + 0xffffffff,0xffffffff,0xffffffff, + 0x88888888,0x00000000,0x88888888, + 0xffffffff,0x44444444,0xaaaaaaaa, + 0xeeeeeeee,0x00000000,0x00000000, + 0x66666666,0x22222222,0x00000000, + 0xffffffff,0x66666666,0x00000000, + 0xffffffff,0xaaaaaaaa,0x88888888, + 0xffffffff,0xeeeeeeee,0x00000000, + 0x00000000,0x88888888,0x00000000, + 0x00000000,0xdddddddd,0x00000000, + 0x00000000,0xcccccccc,0xcccccccc, + 0x00000000,0x66666666,0xffffffff, + 0x00000000,0x00000000,0xaaaaaaaa, +}; + +#define POPUPMENUPREFS_WIDTH 16 +#define POPUPMENUPREFS_HEIGHT 21 +#define POPUPMENUPREFS_DEPTH 4 +#define POPUPMENUPREFS_COMPRESSION 0 +#define POPUPMENUPREFS_MASKING 2 + +//static const struct BitMapHeader PopupMenuPrefs_header = +//{ 20,24,0,0,4,2,0,0,0,44,44,320,256 }; + +static const UBYTE PopupMenuPrefs_body[] = +{ +0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0x00,0x00,0x00,0x00, +0x00,0xff,0xff,0xb0,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa8,0x00,0x00,0x00, +0x00,0x00,0xff,0xff,0xb6,0xd6,0x00,0x00,0x00,0x00,0xff,0xff,0xa6,0xd6,0x00, +0x00,0x00,0x00,0xff,0xff,0x80,0x84,0x00,0x00,0x00,0x00,0x80,0x00,0xff,0xff, +0x00,0x00,0x00,0x00,0xff,0xfe,0x80,0x00,0x00,0x00,0x00,0x00,0x82,0x30,0xfd, +0xcf,0x01,0xce,0x00,0x30,0x81,0x10,0xde,0xef,0x00,0xec,0x00,0x10,0x80,0xa4, +0xd7,0x5b,0x00,0x58,0x00,0x20,0x80,0x68,0xd2,0x97,0x00,0x10,0x00,0x20,0x80, +0x30,0xd6,0x4f,0x00,0x00,0x00,0x00,0x80,0x00,0xff,0xff,0x00,0x00,0x00,0x00, +0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0xee,0xff,0x80,0x00,0x00,0x00,0x00, +0x00,0xde,0xff,0x80,0x02,0x00,0x00,0x00,0x00,0xea,0x7d,0x80,0x00,0x00,0x00, +0x00,0x00,0xda,0x7f,0x80,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0x00,0x00, +0x00,0x00,0x00 +}; + +//---------------------------------------------------------------------------- +// GUI image for horizontal spacing +//---------------------------------------------------------------------------- + +static const ULONG Horizontal_Space_colors[] = +{ + 0x66666666,0x66666666,0x55555555, + 0xaaaaaaaa,0x99999999,0x99999999, + 0x77777777,0x77777777,0x66666666, + 0x00000000,0x66666666,0xffffffff, + 0x88888888,0x77777777,0x77777777, + 0x88888888,0x99999999,0xaaaaaaaa, + 0x99999999,0xaaaaaaaa,0xbbbbbbbb, + 0xffffffff,0xffffffff,0xffffffff, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0x99999999,0xaaaaaaaa,0xcccccccc, + 0xaaaaaaaa,0xaaaaaaaa,0xcccccccc, + 0xbbbbbbbb,0xcccccccc,0xdddddddd, + 0xffffffff,0xaaaaaaaa,0x99999999, + 0xcccccccc,0xcccccccc,0xdddddddd, + 0x00000000,0x00000000,0x00000000, +}; + +#define HORIZONTAL_SPACE_WIDTH 149 +#define HORIZONTAL_SPACE_HEIGHT 40 +#define HORIZONTAL_SPACE_DEPTH 4 +#define HORIZONTAL_SPACE_COMPRESSION 1 +#define HORIZONTAL_SPACE_MASKING 2 + +//static const struct BitMapHeader Horizontal_Space_header = +//{ 149,40,0,0,4,2,1,0,0,44,22,320,512 }; + +static const UBYTE Horizontal_Space_body[] = +{ +0xed,0x00,0xed,0x00,0xed,0x00,0xed,0x00,0x01,0x00,0x3f,0xf3,0xff,0x00,0xc0, +0xfe,0x00,0x01,0x00,0x3f,0xf3,0xff,0x00,0xe0,0xfe,0x00,0x01,0x00,0x3f,0xf3, +0xff,0x00,0xe0,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xef, +0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00, +0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xef,0x00, +0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00, +0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xef,0x00,0x01, +0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20, +0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xef,0x00,0x01,0x00, +0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe, +0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xef,0x00,0x01,0x00,0x21, +0xf4,0xff,0x01,0xfc,0x20,0xfe,0x00,0x01,0x00,0x21,0xf4,0xff,0x01,0xfc,0x20, +0xfe,0x00,0x01,0x00,0x01,0xf4,0xff,0x01,0xfc,0x20,0xfe,0x00,0x01,0x00,0x20, +0xf4,0x00,0x00,0x04,0xfd,0x00,0x01,0x00,0x21,0xf4,0x00,0x01,0x04,0x20,0xfe, +0x00,0x01,0x00,0x21,0xf4,0x00,0x01,0x04,0x20,0xfe,0x00,0x01,0x00,0x01,0xf3, +0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x04,0xfd,0x00,0x01, +0x00,0x21,0xf6,0x00,0x03,0x02,0x00,0x04,0x20,0xfe,0x00,0x01,0x00,0x21,0xf6, +0x00,0x03,0x02,0x00,0x04,0x20,0xfe,0x00,0x01,0x00,0x01,0xf6,0x00,0x03,0x02, +0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x04,0xfd,0x00,0x01, +0x00,0x21,0xf6,0x00,0x03,0x03,0x00,0x04,0x20,0xfe,0x00,0x01,0x00,0x21,0xf6, +0x00,0x03,0x03,0x00,0x04,0x20,0xfe,0x00,0x01,0x00,0x01,0xf6,0x00,0x03,0x03, +0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x04,0xfd,0x00,0x05, +0x00,0x21,0x00,0x73,0x80,0x04,0xfe,0x00,0x00,0x18,0xfe,0x00,0x03,0x03,0x80, +0x04,0x20,0xfe,0x00,0x05,0x00,0x21,0x00,0x73,0x80,0x04,0xfe,0x00,0x00,0x18, +0xfe,0x00,0x03,0x03,0x80,0x04,0x20,0xfe,0x00,0x05,0x00,0x01,0x00,0x73,0x80, +0x04,0xfe,0x00,0x00,0x18,0xfe,0x00,0x03,0x03,0x80,0x00,0x20,0xfe,0x00,0x01, +0x00,0x20,0xf4,0x00,0x00,0x04,0xfd,0x00,0x03,0x00,0x21,0x00,0x21,0xfc,0x00, +0x00,0x08,0xfe,0x00,0x03,0x03,0xc0,0x04,0x20,0xfe,0x00,0x03,0x00,0x21,0x00, +0x21,0xfc,0x00,0x00,0x08,0xfe,0x00,0x03,0x03,0xc0,0x04,0x20,0xfe,0x00,0x03, +0x00,0x01,0x00,0x21,0xfc,0x00,0x00,0x08,0xfe,0x00,0x03,0x03,0xc0,0x00,0x20, +0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x04,0xfd,0x00,0x03,0x00,0x21,0x00, +0x21,0xfd,0x00,0x01,0x20,0x08,0xfe,0x00,0x03,0x03,0xe0,0x04,0x20,0xfe,0x00, +0x03,0x00,0x21,0x00,0x21,0xfd,0x00,0x01,0x20,0x08,0xfe,0x00,0x03,0x03,0xe0, +0x04,0x20,0xfe,0x00,0x03,0x00,0x01,0x00,0x21,0xfd,0x00,0x01,0x20,0x08,0xfe, +0x00,0x03,0x03,0xe0,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x04, +0xfd,0x00,0x09,0x00,0x21,0x00,0x21,0x0c,0xbc,0xf1,0x96,0x79,0x88,0xfe,0x00, +0x03,0x03,0xf0,0x04,0x20,0xfe,0x00,0x09,0x00,0x21,0x00,0x21,0x0c,0xbc,0xf1, +0x96,0x79,0x88,0xfe,0x00,0x03,0x03,0xf0,0x04,0x20,0xfe,0x00,0x09,0x00,0x01, +0x00,0x21,0x0c,0xbc,0xf1,0x96,0x79,0x88,0xfe,0x00,0x03,0x03,0xf0,0x00,0x20, +0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x04,0xfd,0x00,0x09,0x00,0x21,0x00, +0x3f,0x12,0x64,0x92,0x49,0x22,0x48,0xfe,0x00,0x03,0x03,0xf0,0x04,0x20,0xfe, +0x00,0x09,0x00,0x21,0x00,0x3f,0x12,0x64,0x92,0x49,0x22,0x48,0xfe,0x00,0x03, +0x03,0xf0,0x04,0x20,0xfe,0x00,0x09,0x00,0x01,0x00,0x3f,0x12,0x64,0x92,0x49, +0x22,0x48,0xfe,0x00,0x03,0x03,0xf0,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4, +0x00,0x00,0x04,0xfd,0x00,0x09,0x00,0x21,0x00,0x21,0x12,0x44,0x22,0x49,0x21, +0xc8,0xfe,0x00,0x03,0x03,0xe0,0x04,0x20,0xfe,0x00,0x09,0x00,0x21,0x00,0x21, +0x12,0x44,0x22,0x49,0x21,0xc8,0xfe,0x00,0x03,0x03,0xe0,0x04,0x20,0xfe,0x00, +0x09,0x00,0x01,0x00,0x21,0x12,0x44,0x22,0x49,0x21,0xc8,0xfe,0x00,0x03,0x03, +0xe0,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x04,0xfd,0x00,0x09, +0x00,0x21,0x00,0x21,0x12,0x44,0x42,0x49,0x22,0x48,0xfe,0x00,0x03,0x03,0xc0, +0x04,0x20,0xfe,0x00,0x09,0x00,0x21,0x00,0x21,0x12,0x44,0x42,0x49,0x22,0x48, +0xfe,0x00,0x03,0x03,0xc0,0x04,0x20,0xfe,0x00,0x09,0x00,0x01,0x00,0x21,0x12, +0x44,0x42,0x49,0x22,0x48,0xfe,0x00,0x03,0x03,0xc0,0x00,0x20,0xfe,0x00,0x01, +0x00,0x20,0xf4,0x00,0x00,0x04,0xfd,0x00,0x09,0x00,0x21,0x00,0x21,0x12,0x44, +0x92,0x49,0x22,0x48,0xfe,0x00,0x03,0x03,0x80,0x04,0x20,0xfe,0x00,0x09,0x00, +0x21,0x00,0x21,0x12,0x44,0x92,0x49,0x22,0x48,0xfe,0x00,0x03,0x03,0x80,0x04, +0x20,0xfe,0x00,0x09,0x00,0x01,0x00,0x21,0x12,0x44,0x92,0x49,0x22,0x48,0xfe, +0x00,0x03,0x03,0x80,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x04, +0xfd,0x00,0x09,0x00,0x21,0x00,0x73,0x8c,0xee,0xf1,0x9d,0x99,0xbc,0xfe,0x00, +0x03,0x03,0x00,0x04,0x20,0xfe,0x00,0x09,0x00,0x21,0x00,0x73,0x8c,0xee,0xf1, +0x9d,0x99,0xbc,0xfe,0x00,0x03,0x03,0x00,0x04,0x20,0xfe,0x00,0x09,0x00,0x01, +0x00,0x73,0x8c,0xee,0xf1,0x9d,0x99,0xbc,0xfe,0x00,0x03,0x03,0x00,0x00,0x20, +0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x04,0xfd,0x00,0x01,0x00,0x21,0xf6, +0x00,0x03,0x02,0x00,0x04,0x20,0xfe,0x00,0x01,0x00,0x21,0xf6,0x00,0x03,0x02, +0x00,0x04,0x20,0xfe,0x00,0x01,0x00,0x01,0xf6,0x00,0x03,0x02,0x00,0x00,0x20, +0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x04,0xfd,0x00,0x01,0x00,0x21,0xf4, +0x00,0x01,0x04,0x20,0xfe,0x00,0x01,0x00,0x21,0xf4,0x00,0x01,0x04,0x20,0xfe, +0x00,0x01,0x00,0x01,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0xff, +0x00,0xfc,0xfd,0x00,0x01,0x00,0x21,0xf4,0xff,0x01,0xfc,0x20,0xfe,0x00,0x01, +0x00,0x21,0xf4,0xff,0x01,0xfc,0x20,0xfe,0x00,0x01,0x00,0x01,0xf3,0x00,0x00, +0x20,0xfe,0x00,0x01,0x00,0x20,0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20, +0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20, +0xfe,0x00,0x03,0x00,0x20,0x80,0x80,0xf7,0x00,0xff,0x08,0xfd,0x00,0x03,0x00, +0x20,0x80,0x80,0xf7,0x00,0xff,0x08,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3, +0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x03,0x00,0x20,0x80, +0x80,0xf7,0x00,0xff,0x08,0xfd,0x00,0x03,0x00,0x20,0x80,0x80,0xf7,0x00,0xff, +0x08,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1, +0x00,0x00,0x20,0xfe,0x00,0x03,0x00,0x20,0x80,0x80,0xf7,0x00,0xff,0x08,0xfd, +0x00,0x03,0x00,0x20,0x80,0x80,0xf7,0x00,0xff,0x08,0x00,0x20,0xfe,0x00,0x01, +0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x03, +0x00,0x20,0x80,0x80,0xf7,0x00,0xff,0x08,0xfd,0x00,0x03,0x00,0x20,0x80,0x80, +0xf7,0x00,0xff,0x08,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20, +0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x03,0x00,0x20,0x80,0x80,0xf8,0x00, +0x03,0x02,0x08,0x08,0x20,0xfe,0x00,0x06,0x00,0x20,0x80,0xbb,0xc3,0x0c,0x60, +0xfb,0x00,0x03,0x02,0x08,0x08,0x20,0xfe,0x00,0xfe,0x00,0x03,0x3b,0xc3,0x0c, +0x60,0xf4,0x00,0xfe,0x00,0x03,0x3b,0xc3,0x0c,0x60,0xf4,0x00,0x03,0x00,0x30, +0x80,0x86,0xf8,0x00,0x03,0x03,0x08,0x08,0x60,0xfe,0x00,0x06,0x00,0x30,0x80, +0xcf,0x24,0x90,0x90,0xfb,0x00,0x03,0x03,0x08,0x08,0x60,0xfe,0x00,0xfe,0x00, +0x03,0x49,0x24,0x90,0x90,0xf4,0x00,0xfe,0x00,0x03,0x49,0x24,0x90,0x90,0xf4, +0x00,0x03,0x00,0x38,0x80,0x8e,0xf8,0x00,0x03,0x03,0x88,0x08,0xe0,0xfe,0x00, +0x06,0x00,0x38,0x80,0xef,0x23,0x90,0xf0,0xfb,0x00,0x03,0x03,0x88,0x08,0xe0, +0xfe,0x00,0xfe,0x00,0x03,0x61,0x23,0x90,0xf0,0xf4,0x00,0xfe,0x00,0x03,0x61, +0x23,0x90,0xf0,0xf4,0x00,0x03,0x00,0x3c,0x80,0x86,0xf8,0x00,0x03,0x03,0xc8, +0x09,0xe0,0xfe,0x00,0x06,0x00,0x3c,0x80,0x9f,0x24,0x90,0x80,0xfb,0x00,0x03, +0x03,0xc8,0x09,0xe0,0xfe,0x00,0xfe,0x00,0x03,0x19,0x24,0x90,0x80,0xf4,0x00, +0xfe,0x00,0x03,0x19,0x24,0x90,0x80,0xf4,0x00,0x03,0x00,0x3e,0x80,0xb6,0xf8, +0x00,0x03,0x03,0xe8,0x0b,0xe0,0xfe,0x00,0x06,0x00,0x3e,0x80,0xff,0x24,0x90, +0x80,0xfb,0x00,0x03,0x03,0xe8,0x0b,0xe0,0xfe,0x00,0xfe,0x00,0x03,0x49,0x24, +0x90,0x80,0xf4,0x00,0xfe,0x00,0x03,0x49,0x24,0x90,0x80,0xf4,0x00,0x04,0x0f, +0xff,0x80,0x8e,0x38,0xf9,0x00,0x06,0xff,0xf8,0x0f,0xff,0x80,0x00,0x00,0x06, +0x0f,0xff,0x80,0xff,0xfb,0x4c,0x70,0xfb,0x00,0x06,0xff,0xf8,0x0f,0xff,0x80, +0x00,0x00,0xfe,0x00,0x03,0x71,0xc3,0x4c,0x70,0xf4,0x00,0xfe,0x00,0x03,0x71, +0xc3,0x4c,0x70,0xf4,0x00,0x04,0x0f,0xff,0x80,0xfe,0xf8,0xf9,0x00,0x06,0xff, +0xf8,0x0f,0xff,0x80,0x00,0x00,0x04,0x0f,0xff,0x80,0xff,0xf8,0xf9,0x00,0x06, +0xff,0xf8,0x0f,0xff,0x80,0x00,0x00,0xfe,0x00,0x00,0x01,0xf1,0x00,0xfe,0x00, +0x00,0x01,0xf1,0x00,0x04,0x0f,0xff,0x80,0xfe,0xf8,0xf9,0x00,0x06,0xff,0xf8, +0x0f,0xff,0x80,0x00,0x00,0x04,0x0f,0xff,0x80,0xff,0xf8,0xf9,0x00,0x06,0xff, +0xf8,0x0f,0xff,0x80,0x00,0x00,0xfe,0x00,0x00,0x01,0xf1,0x00,0xfe,0x00,0x00, +0x01,0xf1,0x00,0x03,0x00,0x3e,0x80,0xbc,0xf8,0x00,0x03,0x03,0xe8,0x0b,0xe0, +0xfe,0x00,0x04,0x00,0x3e,0x80,0xbf,0x80,0xf9,0x00,0x03,0x03,0xe8,0x0b,0xe0, +0xfe,0x00,0xfe,0x00,0x01,0x03,0x80,0xf2,0x00,0xfe,0x00,0x01,0x03,0x80,0xf2, +0x00,0x03,0x00,0x3c,0x80,0x9e,0xf8,0x00,0x03,0x03,0xc8,0x09,0xe0,0xfe,0x00, +0x03,0x00,0x3c,0x80,0x9e,0xf8,0x00,0x03,0x03,0xc8,0x09,0xe0,0xfe,0x00,0xed, +0x00,0xed,0x00,0x03,0x00,0x38,0x80,0x8e,0xf8,0x00,0x03,0x03,0x88,0x08,0xe0, +0xfe,0x00,0x03,0x00,0x38,0x80,0x8e,0xf8,0x00,0x03,0x03,0x88,0x08,0xe0,0xfe, +0x00,0xed,0x00,0xed,0x00,0x03,0x00,0x30,0x80,0x86,0xf8,0x00,0x03,0x03,0x08, +0x08,0x60,0xfe,0x00,0x03,0x00,0x30,0x80,0x86,0xf8,0x00,0x03,0x03,0x08,0x08, +0x60,0xfe,0x00,0xed,0x00,0xed,0x00,0x03,0x00,0x20,0x80,0x82,0xf8,0x00,0x03, +0x02,0x08,0x08,0x20,0xfe,0x00,0x03,0x00,0x20,0x80,0x82,0xf8,0x00,0x03,0x02, +0x08,0x08,0x20,0xfe,0x00,0xed,0x00,0xed,0x00, +}; + +//---------------------------------------------------------------------------- +// GUI image for Horizontal +//---------------------------------------------------------------------------- + +static const ULONG Horizontal_colors[] = +{ + 0x66666666,0x66666666,0x55555555, + 0xaaaaaaaa,0x99999999,0x99999999, + 0x77777777,0x77777777,0x66666666, + 0x00000000,0x66666666,0xffffffff, + 0x88888888,0x77777777,0x77777777, + 0x88888888,0x99999999,0xaaaaaaaa, + 0x99999999,0xaaaaaaaa,0xbbbbbbbb, + 0xffffffff,0xffffffff,0xffffffff, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0x99999999,0xaaaaaaaa,0xcccccccc, + 0xaaaaaaaa,0xaaaaaaaa,0xcccccccc, + 0xbbbbbbbb,0xcccccccc,0xdddddddd, + 0xffffffff,0xaaaaaaaa,0x99999999, + 0xcccccccc,0xcccccccc,0xdddddddd, + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, +}; + +#define HORIZONTAL_WIDTH 149 +#define HORIZONTAL_HEIGHT 40 +#define HORIZONTAL_DEPTH 4 +#define HORIZONTAL_COMPRESSION 1 +#define HORIZONTAL_MASKING 2 + +//static const struct BitMapHeader Horizontal_header = +//{ 149,40,0,0,4,2,1,0,0,44,22,320,512 }; + +static const UBYTE Horizontal_body[] = +{ +0x01,0x00,0x3f,0xf3,0xff,0x00,0xc0,0xfe,0x00,0x01,0x00,0x3f,0xf3,0xff,0x00, +0xe0,0xfe,0x00,0x01,0x00,0x3f,0xf3,0xff,0x00,0xe0,0xfe,0x00,0xf1,0x00,0x00, +0x20,0xfe,0x00,0x01,0x00,0x20,0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20, +0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20, +0xfe,0x00,0x01,0x00,0x20,0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe, +0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe, +0x00,0x01,0x00,0x20,0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00, +0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00, +0x01,0x00,0x20,0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01, +0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01, +0x00,0x20,0xef,0x00,0x02,0x00,0x20,0x0f,0xf5,0xff,0x01,0xc0,0x20,0xfe,0x00, +0x02,0x00,0x20,0x0f,0xf5,0xff,0x01,0xc0,0x20,0xfe,0x00,0xff,0x00,0x00,0x0f, +0xf5,0xff,0x01,0xc0,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x40,0xfd, +0x00,0x02,0x00,0x20,0x08,0xf5,0x00,0x01,0x40,0x20,0xfe,0x00,0x02,0x00,0x20, +0x08,0xf5,0x00,0x01,0x40,0x20,0xfe,0x00,0xff,0x00,0x00,0x08,0xf4,0x00,0x00, +0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x40,0xfd,0x00,0x02,0x00,0x20, +0x08,0xf5,0x00,0x01,0x40,0x20,0xfe,0x00,0x02,0x00,0x20,0x08,0xf5,0x00,0x01, +0x40,0x20,0xfe,0x00,0xff,0x00,0x00,0x08,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01, +0x00,0x20,0xf4,0x00,0x00,0x40,0xfd,0x00,0x02,0x00,0x20,0x08,0xf5,0x00,0x01, +0x40,0x20,0xfe,0x00,0x02,0x00,0x20,0x08,0xf5,0x00,0x01,0x40,0x20,0xfe,0x00, +0xff,0x00,0x00,0x08,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00, +0x00,0x40,0xfd,0x00,0x05,0x00,0x20,0x08,0x73,0x80,0x04,0xfe,0x00,0x00,0x18, +0xfc,0x00,0x01,0x40,0x20,0xfe,0x00,0x05,0x00,0x20,0x08,0x73,0x80,0x04,0xfe, +0x00,0x00,0x18,0xfc,0x00,0x01,0x40,0x20,0xfe,0x00,0xff,0x00,0x03,0x08,0x73, +0x80,0x04,0xfe,0x00,0x00,0x18,0xfb,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20, +0xf4,0x00,0x00,0x40,0xfd,0x00,0x03,0x00,0x20,0x08,0x21,0xfc,0x00,0x00,0x08, +0xfc,0x00,0x01,0x40,0x20,0xfe,0x00,0x03,0x00,0x20,0x08,0x21,0xfc,0x00,0x00, +0x08,0xfc,0x00,0x01,0x40,0x20,0xfe,0x00,0xff,0x00,0x01,0x08,0x21,0xfc,0x00, +0x00,0x08,0xfb,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x40, +0xfd,0x00,0x03,0x00,0x20,0x08,0x21,0xfd,0x00,0x01,0x20,0x08,0xfc,0x00,0x01, +0x40,0x20,0xfe,0x00,0x03,0x00,0x20,0x08,0x21,0xfd,0x00,0x01,0x20,0x08,0xfc, +0x00,0x01,0x40,0x20,0xfe,0x00,0xff,0x00,0x01,0x08,0x21,0xfd,0x00,0x01,0x20, +0x08,0xfb,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x40,0xfd, +0x00,0x09,0x00,0x20,0x08,0x21,0x0c,0xbc,0xf1,0x96,0x79,0x88,0xfc,0x00,0x01, +0x40,0x20,0xfe,0x00,0x09,0x00,0x20,0x08,0x21,0x0c,0xbc,0xf1,0x96,0x79,0x88, +0xfc,0x00,0x01,0x40,0x20,0xfe,0x00,0xff,0x00,0x07,0x08,0x21,0x0c,0xbc,0xf1, +0x96,0x79,0x88,0xfb,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00, +0x40,0xfd,0x00,0x09,0x00,0x20,0x08,0x3f,0x12,0x64,0x92,0x49,0x22,0x48,0xfc, +0x00,0x01,0x40,0x20,0xfe,0x00,0x09,0x00,0x20,0x08,0x3f,0x12,0x64,0x92,0x49, +0x22,0x48,0xfc,0x00,0x01,0x40,0x20,0xfe,0x00,0xff,0x00,0x07,0x08,0x3f,0x12, +0x64,0x92,0x49,0x22,0x48,0xfb,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4, +0x00,0x00,0x40,0xfd,0x00,0x09,0x00,0x20,0x08,0x21,0x12,0x44,0x22,0x49,0x21, +0xc8,0xfc,0x00,0x01,0x40,0x20,0xfe,0x00,0x09,0x00,0x20,0x08,0x21,0x12,0x44, +0x22,0x49,0x21,0xc8,0xfc,0x00,0x01,0x40,0x20,0xfe,0x00,0xff,0x00,0x07,0x08, +0x21,0x12,0x44,0x22,0x49,0x21,0xc8,0xfb,0x00,0x00,0x20,0xfe,0x00,0x01,0x00, +0x20,0xf4,0x00,0x00,0x40,0xfd,0x00,0x09,0x00,0x20,0x08,0x21,0x12,0x44,0x42, +0x49,0x22,0x48,0xfc,0x00,0x01,0x40,0x20,0xfe,0x00,0x09,0x00,0x20,0x08,0x21, +0x12,0x44,0x42,0x49,0x22,0x48,0xfc,0x00,0x01,0x40,0x20,0xfe,0x00,0xff,0x00, +0x07,0x08,0x21,0x12,0x44,0x42,0x49,0x22,0x48,0xfb,0x00,0x00,0x20,0xfe,0x00, +0x01,0x00,0x20,0xf4,0x00,0x00,0x40,0xfd,0x00,0x09,0x00,0x20,0x08,0x21,0x12, +0x44,0x92,0x49,0x22,0x48,0xfc,0x00,0x01,0x40,0x20,0xfe,0x00,0x09,0x00,0x20, +0x08,0x21,0x12,0x44,0x92,0x49,0x22,0x48,0xfc,0x00,0x01,0x40,0x20,0xfe,0x00, +0xff,0x00,0x07,0x08,0x21,0x12,0x44,0x92,0x49,0x22,0x48,0xfb,0x00,0x00,0x20, +0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x40,0xfd,0x00,0x09,0x00,0x20,0x08, +0x73,0x8c,0xee,0xf1,0x9d,0x99,0xbc,0xfc,0x00,0x01,0x40,0x20,0xfe,0x00,0x09, +0x00,0x20,0x08,0x73,0x8c,0xee,0xf1,0x9d,0x99,0xbc,0xfc,0x00,0x01,0x40,0x20, +0xfe,0x00,0xff,0x00,0x07,0x08,0x73,0x8c,0xee,0xf1,0x9d,0x99,0xbc,0xfb,0x00, +0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x40,0xfd,0x00,0x02,0x00, +0x20,0x08,0xf5,0x00,0x01,0x40,0x20,0xfe,0x00,0x02,0x00,0x20,0x08,0xf5,0x00, +0x01,0x40,0x20,0xfe,0x00,0xff,0x00,0x00,0x08,0xf4,0x00,0x00,0x20,0xfe,0x00, +0x01,0x00,0x20,0xf4,0x00,0x00,0x40,0xfd,0x00,0x02,0x00,0x20,0x08,0xf5,0x00, +0x01,0x40,0x20,0xfe,0x00,0x02,0x00,0x20,0x08,0xf5,0x00,0x01,0x40,0x20,0xfe, +0x00,0xff,0x00,0x00,0x08,0xf4,0x00,0x00,0x20,0xfe,0x00,0x02,0x00,0x20,0x07, +0xf5,0xff,0x00,0xc0,0xfd,0x00,0x02,0x00,0x20,0x0f,0xf5,0xff,0x01,0xc0,0x20, +0xfe,0x00,0x02,0x00,0x20,0x0f,0xf5,0xff,0x01,0xc0,0x20,0xfe,0x00,0xff,0x00, +0x00,0x08,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xef,0x00,0x01,0x00, +0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe, +0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x02,0x00,0x30,0x10,0xf5,0x00,0xff,0x40, +0xfe,0x00,0x02,0x00,0x30,0x10,0xf5,0x00,0x01,0x40,0x60,0xfe,0x00,0x01,0x00, +0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x02,0x00, +0x30,0x10,0xf5,0x00,0xff,0x40,0xfe,0x00,0x02,0x00,0x30,0x10,0xf5,0x00,0x01, +0x40,0x60,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00, +0x00,0x20,0xfe,0x00,0x02,0x00,0x30,0x10,0xf5,0x00,0xff,0x40,0xfe,0x00,0x02, +0x00,0x30,0x10,0xf5,0x00,0x01,0x40,0x60,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00, +0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x02,0x00,0x30,0x10,0xf5, +0x00,0xff,0x40,0xfe,0x00,0x02,0x00,0x30,0x10,0xf5,0x00,0x01,0x40,0x60,0xfe, +0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe, +0x00,0x03,0x04,0x30,0x10,0x40,0xf7,0x00,0x02,0x10,0x40,0x41,0xfe,0x00,0x03, +0x04,0x30,0x10,0x40,0xf7,0x00,0x02,0x10,0x40,0x61,0xfe,0x00,0x01,0x00,0x20, +0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x03,0x06,0x30, +0x10,0xc0,0xf7,0x00,0x02,0x18,0x40,0x43,0xfe,0x00,0x03,0x06,0x30,0x10,0xc0, +0xf7,0x00,0x02,0x18,0x40,0x63,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20, +0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x03,0x07,0x30,0x11,0xc0,0xf7,0x00, +0x02,0x1c,0x40,0x47,0xfe,0x00,0x03,0x07,0x30,0x11,0xc0,0xf7,0x00,0x02,0x1c, +0x40,0x67,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00, +0x00,0x20,0xfe,0x00,0x03,0x07,0xb0,0x13,0xc0,0xf7,0x00,0x02,0x1e,0x40,0x4f, +0xfe,0x00,0x03,0x07,0xb0,0x13,0xc0,0xf7,0x00,0x02,0x1e,0x40,0x6f,0xfe,0x00, +0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00, +0x03,0x07,0xf0,0x17,0xc0,0xf7,0x00,0x02,0x1f,0x40,0x5f,0xfe,0x00,0x03,0x07, +0xf0,0x17,0xc0,0xf7,0x00,0x02,0x1f,0x40,0x7f,0xfe,0x00,0x01,0x00,0x20,0xf3, +0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x03,0xff,0xf0,0x1f, +0xff,0xf8,0x00,0x06,0x03,0xff,0xc0,0x7f,0xfc,0x00,0x00,0x03,0xff,0xf0,0x1f, +0xff,0xf8,0x00,0x06,0x03,0xff,0xc0,0x7f,0xfc,0x00,0x00,0xed,0x00,0xed,0x00, +0x03,0xff,0xf0,0x1f,0xff,0xf8,0x00,0x06,0x03,0xff,0xc0,0x7f,0xfc,0x00,0x00, +0x03,0xff,0xf0,0x1f,0xff,0xf8,0x00,0x06,0x03,0xff,0xc0,0x7f,0xfc,0x00,0x00, +0xed,0x00,0xed,0x00,0x03,0xff,0xf0,0x1f,0xff,0xf8,0x00,0x06,0x03,0xff,0xc0, +0x7f,0xfc,0x00,0x00,0x03,0xff,0xf0,0x1f,0xff,0xf8,0x00,0x06,0x03,0xff,0xc0, +0x7f,0xfc,0x00,0x00,0xed,0x00,0xed,0x00,0x03,0x07,0xf0,0x17,0xc0,0xf7,0x00, +0x02,0x1f,0x40,0x5f,0xfe,0x00,0x03,0x07,0xf0,0x17,0xc0,0xf7,0x00,0x02,0x1f, +0x40,0x7f,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00, +0x00,0x20,0xfe,0x00,0x03,0x07,0xb0,0x13,0xc0,0xf7,0x00,0x02,0x1e,0x40,0x4f, +0xfe,0x00,0x03,0x07,0xb0,0x13,0xc0,0xf7,0x00,0x02,0x1e,0x40,0x6f,0xfe,0x00, +0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00, +0x03,0x07,0x30,0x11,0xc0,0xf7,0x00,0x02,0x1c,0x40,0x47,0xfe,0x00,0x03,0x07, +0x30,0x11,0xc0,0xf7,0x00,0x02,0x1c,0x40,0x67,0xfe,0x00,0x01,0x00,0x20,0xf3, +0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x03,0x06,0x30,0x10, +0xc0,0xf7,0x00,0x02,0x18,0x40,0x43,0xfe,0x00,0x03,0x06,0x30,0x10,0xc0,0xf7, +0x00,0x02,0x18,0x40,0x63,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe, +0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x03,0x04,0x30,0x10,0x40,0xf7,0x00,0x02, +0x10,0x40,0x41,0xfe,0x00,0x03,0x04,0x30,0x10,0x40,0xf7,0x00,0x02,0x10,0x40, +0x61,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00, +0x20,0xfe,0x00,0xed,0x00,0xed,0x00,0xed,0x00,0xed,0x00, +}; + + +//---------------------------------------------------------------------------- +// GUI image for intermediate spacing +//---------------------------------------------------------------------------- + +static const ULONG Intermediate_Spacing_colors[] = +{ + 0x66666666,0x66666666,0x55555555, + 0xaaaaaaaa,0x99999999,0x99999999, + 0x77777777,0x77777777,0x66666666, + 0x00000000,0x66666666,0xffffffff, + 0x88888888,0x77777777,0x77777777, + 0x88888888,0x99999999,0xaaaaaaaa, + 0x99999999,0xaaaaaaaa,0xbbbbbbbb, + 0xffffffff,0xffffffff,0xffffffff, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0x99999999,0xaaaaaaaa,0xcccccccc, + 0xaaaaaaaa,0xaaaaaaaa,0xcccccccc, + 0xbbbbbbbb,0xcccccccc,0xdddddddd, + 0xffffffff,0xaaaaaaaa,0x99999999, + 0xcccccccc,0xcccccccc,0xdddddddd, + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, +}; + +#define INTERMEDIATE_SPACING_WIDTH 149 +#define INTERMEDIATE_SPACING_HEIGHT 40 +#define INTERMEDIATE_SPACING_DEPTH 4 +#define INTERMEDIATE_SPACING_COMPRESSION 1 +#define INTERMEDIATE_SPACING_MASKING 2 + +//static const struct BitMapHeader Intermediate_Spacing_header = +//{ 149,40,0,0,4,2,1,0,0,44,22,320,512 }; + +static const UBYTE Intermediate_Spacing_body[] = +{ +0xed,0x00,0xed,0x00,0xed,0x00,0xed,0x00,0x01,0x00,0x20,0xef,0x00,0x01,0x00, +0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe, +0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x06,0x00,0x20,0x00,0x00,0x10,0x00,0x80, +0xf4,0x00,0x06,0x00,0x20,0x00,0x00,0x10,0x00,0x80,0xf8,0x00,0x00,0x20,0xfe, +0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe, +0x00,0x06,0x00,0x20,0x00,0x00,0x10,0x00,0x80,0xf4,0x00,0x06,0x00,0x20,0x00, +0x00,0x10,0x00,0x80,0xf8,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00, +0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xfd,0x00, +0x00,0x80,0xf4,0x00,0x01,0x00,0x20,0xfd,0x00,0x00,0x80,0xf8,0x00,0x00,0x20, +0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20, +0xfe,0x00,0x01,0x00,0x20,0xfd,0x00,0x00,0x80,0xf4,0x00,0x06,0x00,0x20,0x00, +0x00,0x70,0x00,0x80,0xf8,0x00,0x00,0x20,0xfe,0x00,0x04,0x00,0x20,0x00,0x00, +0x70,0xf6,0x00,0x00,0x20,0xfe,0x00,0xfd,0x00,0x00,0x70,0xf6,0x00,0x00,0x20, +0xfe,0x00,0x01,0x00,0x20,0xef,0x00,0x04,0x00,0x20,0x00,0x00,0xe0,0xf6,0x00, +0x00,0x20,0xfe,0x00,0x04,0x00,0x20,0x00,0x00,0xe0,0xf6,0x00,0x00,0x20,0xfe, +0x00,0xfd,0x00,0x00,0xe0,0xf6,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xef, +0x00,0x06,0x00,0x20,0x00,0x01,0xc0,0x00,0xe0,0xfd,0x00,0x00,0x32,0xfd,0x00, +0x00,0x20,0xfe,0x00,0x06,0x00,0x20,0x00,0x01,0xc0,0x00,0xe0,0xfd,0x00,0x00, +0x32,0xfd,0x00,0x00,0x20,0xfe,0x00,0xfe,0x00,0x03,0x01,0xc0,0x00,0xe0,0xfd, +0x00,0x00,0x32,0xfd,0x00,0x00,0x20,0xfe,0x00,0x04,0x00,0x20,0x00,0x00,0x10, +0xf2,0x00,0x06,0x00,0x20,0x00,0x03,0x90,0x00,0x40,0xfd,0x00,0x00,0x10,0xfd, +0x00,0x00,0x20,0xfe,0x00,0x06,0x00,0x20,0x00,0x03,0x80,0x00,0x40,0xfd,0x00, +0x00,0x10,0xfd,0x00,0x00,0x20,0xfe,0x00,0xfe,0x00,0x03,0x03,0x80,0x00,0x40, +0xfd,0x00,0x00,0x10,0xfd,0x00,0x00,0x20,0xfe,0x00,0x04,0x00,0x20,0x00,0x00, +0x10,0xf2,0x00,0x07,0x00,0x20,0x00,0x07,0x10,0x00,0x40,0x10,0xfe,0x00,0x01, +0x10,0x01,0xfe,0x00,0x00,0x20,0xfe,0x00,0x07,0x00,0x20,0x00,0x07,0x00,0x00, +0x40,0x10,0xfe,0x00,0x01,0x10,0x01,0xfe,0x00,0x00,0x20,0xfe,0x00,0xfe,0x00, +0x04,0x07,0x00,0x00,0x40,0x10,0xfe,0x00,0x01,0x10,0x01,0xfe,0x00,0x00,0x20, +0xfe,0x00,0x04,0x00,0x20,0x00,0x00,0x10,0xf2,0x00,0x10,0x00,0x20,0x00,0x0e, +0x10,0x00,0x4b,0x3c,0xcb,0xb6,0x18,0x76,0x33,0xcc,0x00,0x00,0x20,0xfe,0x00, +0x10,0x00,0x20,0x00,0x0e,0x00,0x00,0x4b,0x3c,0xcb,0xb6,0x18,0x76,0x33,0xcc, +0x00,0x00,0x20,0xfe,0x00,0xfe,0x00,0x0d,0x0e,0x00,0x00,0x4b,0x3c,0xcb,0xb6, +0x18,0x76,0x33,0xcc,0x00,0x00,0x20,0xfe,0x00,0x04,0x00,0x20,0x00,0x00,0x10, +0xf2,0x00,0x10,0x00,0x20,0x70,0x1c,0x10,0x00,0x44,0x91,0x26,0x49,0x24,0x92, +0x49,0x12,0x00,0x00,0x20,0xfe,0x00,0x10,0x00,0x20,0x70,0x1c,0x00,0x00,0x44, +0x91,0x26,0x49,0x24,0x92,0x49,0x12,0x00,0x00,0x20,0xfe,0x00,0xff,0x00,0x0e, +0x70,0x1c,0x00,0x00,0x44,0x91,0x26,0x49,0x24,0x92,0x49,0x12,0x00,0x00,0x20, +0xfe,0x00,0x04,0x00,0x20,0x00,0x00,0x10,0xf2,0x00,0x10,0x00,0x20,0x38,0x38, +0x10,0x00,0x44,0x91,0xe4,0x49,0x3c,0x92,0x39,0x1e,0x00,0x00,0x20,0xfe,0x00, +0x10,0x00,0x20,0x38,0x38,0x00,0x00,0x44,0x91,0xe4,0x49,0x3c,0x92,0x39,0x1e, +0x00,0x00,0x20,0xfe,0x00,0xff,0x00,0xff,0x38,0xff,0x00,0x0a,0x44,0x91,0xe4, +0x49,0x3c,0x92,0x39,0x1e,0x00,0x00,0x20,0xfe,0x00,0x04,0x00,0x20,0x00,0x00, +0x10,0xf2,0x00,0x10,0x00,0x20,0x1c,0x70,0x10,0x00,0x44,0x91,0x04,0x49,0x20, +0x92,0x49,0x10,0x00,0x00,0x20,0xfe,0x00,0x10,0x00,0x20,0x1c,0x70,0x00,0x00, +0x44,0x91,0x04,0x49,0x20,0x92,0x49,0x10,0x00,0x00,0x20,0xfe,0x00,0xff,0x00, +0x0e,0x1c,0x70,0x00,0x00,0x44,0x91,0x04,0x49,0x20,0x92,0x49,0x10,0x00,0x00, +0x20,0xfe,0x00,0x04,0x00,0x20,0x00,0x00,0x10,0xf2,0x00,0x10,0x00,0x20,0x0e, +0xe0,0x10,0x00,0x44,0x91,0x94,0x49,0x32,0x92,0x49,0x19,0x00,0x00,0x20,0xfe, +0x00,0x10,0x00,0x20,0x0e,0xe0,0x00,0x00,0x44,0x91,0x94,0x49,0x32,0x92,0x49, +0x19,0x00,0x00,0x20,0xfe,0x00,0xff,0x00,0x0e,0x0e,0xe0,0x00,0x00,0x44,0x91, +0x94,0x49,0x32,0x92,0x49,0x19,0x00,0x00,0x20,0xfe,0x00,0x04,0x00,0x20,0x00, +0x00,0x10,0xf2,0x00,0x10,0x00,0x20,0x07,0xc0,0x10,0x00,0xee,0xcc,0xee,0xed, +0x9c,0x6f,0x34,0xce,0x00,0x00,0x20,0xfe,0x00,0x10,0x00,0x20,0x07,0xc0,0x00, +0x00,0xee,0xcc,0xee,0xed,0x9c,0x6f,0x34,0xce,0x00,0x00,0x20,0xfe,0x00,0xff, +0x00,0x0e,0x07,0xc0,0x00,0x00,0xee,0xcc,0xee,0xed,0x9c,0x6f,0x34,0xce,0x00, +0x00,0x20,0xfe,0x00,0x04,0x00,0x20,0x00,0x00,0x10,0xf2,0x00,0x04,0x00,0x20, +0x03,0x80,0x10,0xf6,0x00,0x00,0x20,0xfe,0x00,0x03,0x00,0x20,0x03,0x80,0xf5, +0x00,0x00,0x20,0xfe,0x00,0xff,0x00,0x01,0x03,0x80,0xf5,0x00,0x00,0x20,0xfe, +0x00,0x06,0x00,0x20,0x00,0x00,0x10,0x00,0x80,0xf4,0x00,0x06,0x00,0x20,0x01, +0x00,0x10,0x00,0x80,0xf8,0x00,0x00,0x20,0xfe,0x00,0x02,0x00,0x20,0x01,0xf4, +0x00,0x00,0x20,0xfe,0x00,0xff,0x00,0x00,0x01,0xf4,0x00,0x00,0x20,0xfe,0x00, +0x06,0x00,0x20,0x00,0x00,0x10,0x00,0x80,0xf4,0x00,0x06,0x00,0x20,0x00,0x00, +0x10,0x00,0x80,0xf8,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00, +0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x06,0x00,0x20,0x00,0x00,0x10, +0x00,0x80,0xf4,0x00,0x06,0x00,0x20,0x00,0x00,0x10,0x00,0x80,0xf8,0x00,0x00, +0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00, +0x20,0xfe,0x00,0x06,0x00,0x20,0x00,0x00,0x10,0x00,0x80,0xf4,0x00,0x06,0x00, +0x20,0x00,0x00,0x10,0x00,0x80,0xf8,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20, +0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x06,0x00,0x20, +0x00,0x00,0x10,0x00,0x80,0xf4,0x00,0x06,0x00,0x20,0x00,0x00,0x10,0x00,0x80, +0xf8,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00, +0xf1,0x00,0x00,0x20,0xfe,0x00,0x06,0x00,0x20,0x00,0x00,0x10,0x00,0x80,0xf4, +0x00,0x06,0x00,0x20,0x00,0x00,0x10,0x00,0x80,0xf8,0x00,0x00,0x20,0xfe,0x00, +0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00, +0x06,0x00,0x20,0x00,0x00,0x10,0x00,0x80,0xf4,0x00,0x06,0x00,0x20,0x00,0x00, +0x10,0x00,0x80,0xfc,0x00,0x00,0x20,0xfe,0x00,0x00,0x20,0xfe,0x00,0x01,0x00, +0x20,0xf7,0x00,0x00,0x20,0xfe,0x00,0x00,0x20,0xfe,0x00,0xf5,0x00,0x00,0x20, +0xfe,0x00,0x00,0x20,0xfe,0x00,0x06,0x00,0x20,0x00,0x04,0x10,0x00,0x82,0xf4, +0x00,0x06,0x00,0x20,0x00,0x04,0x10,0x00,0x82,0xf8,0x00,0x00,0x20,0xfe,0x00, +0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00, +0x06,0x00,0x20,0x00,0x06,0x10,0x00,0x86,0xf4,0x00,0x06,0x00,0x20,0x00,0x06, +0x10,0x00,0x86,0xf8,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00, +0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x06,0x00,0x20,0x00,0x07,0x10, +0x00,0x8e,0xf4,0x00,0x10,0x00,0x20,0x00,0x07,0x10,0x00,0x8e,0x00,0x00,0x0e, +0xf0,0xc3,0x6b,0x0f,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xfa,0x00,0x07, +0x0e,0xf0,0xc3,0x6b,0x0f,0x00,0x00,0x20,0xfe,0x00,0xf8,0x00,0x07,0x0e,0xf0, +0xc3,0x6b,0x0f,0x00,0x00,0x20,0xfe,0x00,0x06,0x00,0x20,0x00,0x07,0x90,0x00, +0x9e,0xf4,0x00,0x10,0x00,0x20,0x00,0x07,0x90,0x00,0x9e,0x00,0x00,0x12,0x49, +0x24,0xa4,0x92,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xfa,0x00,0x07,0x12, +0x49,0x24,0xa4,0x92,0x00,0x00,0x20,0xfe,0x00,0xf8,0x00,0x07,0x12,0x49,0x24, +0xa4,0x92,0x00,0x00,0x20,0xfe,0x00,0x06,0x00,0x20,0x00,0x07,0xd0,0x00,0xbe, +0xf4,0x00,0x10,0x00,0x20,0x00,0x07,0xd0,0x00,0xbe,0x00,0x00,0x18,0x48,0xe4, +0x24,0x92,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xfa,0x00,0x07,0x18,0x48, +0xe4,0x24,0x92,0x00,0x00,0x20,0xfe,0x00,0xf8,0x00,0x07,0x18,0x48,0xe4,0x24, +0x92,0x00,0x00,0x20,0xfe,0x00,0x07,0x00,0x20,0x01,0xff,0xf0,0x00,0xff,0xf8, +0xf5,0x00,0x10,0x00,0x20,0x01,0xff,0xf0,0x00,0xff,0xf8,0x00,0x06,0x49,0x24, +0x24,0x9c,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xfa,0x00,0x07,0x06,0x49, +0x24,0x24,0x9c,0x00,0x00,0x20,0xfe,0x00,0xf8,0x00,0x07,0x06,0x49,0x24,0x24, +0x9c,0x00,0x00,0x20,0xfe,0x00,0x07,0x00,0x20,0x01,0xff,0xf0,0x00,0xff,0xf8, +0xf5,0x00,0x10,0x00,0x20,0x01,0xff,0xf0,0x00,0xff,0xf8,0x00,0x12,0x49,0x24, +0xa4,0x88,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xfa,0x00,0x07,0x12,0x49, +0x24,0xa4,0x88,0x00,0x00,0x20,0xfe,0x00,0xf8,0x00,0x07,0x12,0x49,0x24,0xa4, +0x88,0x00,0x00,0x20,0xfe,0x00,0x07,0x00,0x20,0x01,0xff,0xf0,0x00,0xff,0xf8, +0xf5,0x00,0x10,0x00,0x20,0x01,0xff,0xf0,0x00,0xff,0xf8,0x00,0x1c,0x70,0xd3, +0x7e,0xce,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xfa,0x00,0x07,0x1c,0x70, +0xd3,0x7e,0xce,0x00,0x00,0x20,0xfe,0x00,0xf8,0x00,0x07,0x1c,0x70,0xd3,0x7e, +0xce,0x00,0x00,0x20,0xfe,0x00,0x06,0x00,0x20,0x00,0x07,0xd0,0x00,0xbe,0xf4, +0x00,0x06,0x00,0x20,0x00,0x07,0xd0,0x00,0xbe,0xfe,0x00,0x06,0x40,0x00,0x00, +0x11,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf9,0x00,0x06,0x40,0x00,0x00, +0x11,0x00,0x00,0x20,0xfe,0x00,0xf7,0x00,0x06,0x40,0x00,0x00,0x11,0x00,0x00, +0x20,0xfe,0x00,0x06,0x00,0x20,0x00,0x07,0x90,0x00,0x9e,0xf4,0x00,0x06,0x00, +0x20,0x00,0x07,0x90,0x00,0x9e,0xfe,0x00,0x06,0x40,0x00,0x00,0x11,0x00,0x00, +0x20,0xfe,0x00,0x01,0x00,0x20,0xf9,0x00,0x06,0x40,0x00,0x00,0x11,0x00,0x00, +0x20,0xfe,0x00,0xf7,0x00,0x06,0x40,0x00,0x00,0x11,0x00,0x00,0x20,0xfe,0x00, +0x06,0x00,0x20,0x00,0x07,0x10,0x00,0x8e,0xf4,0x00,0x06,0x00,0x20,0x00,0x07, +0x10,0x00,0x8e,0xfe,0x00,0x06,0xe0,0x00,0x00,0x0e,0x00,0x00,0x20,0xfe,0x00, +0x01,0x00,0x20,0xf9,0x00,0x06,0xe0,0x00,0x00,0x0e,0x00,0x00,0x20,0xfe,0x00, +0xf7,0x00,0x06,0xe0,0x00,0x00,0x0e,0x00,0x00,0x20,0xfe,0x00,0x06,0x00,0x20, +0x00,0x06,0x10,0x00,0x86,0xf4,0x00,0x06,0x00,0x20,0x00,0x06,0x10,0x00,0x86, +0xf8,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00, +0xf1,0x00,0x00,0x20,0xfe,0x00,0x06,0x00,0x20,0x00,0x04,0x10,0x00,0x82,0xf4, +0x00,0x06,0x00,0x20,0x00,0x04,0x10,0x00,0x82,0xf8,0x00,0x00,0x20,0xfe,0x00, +0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00, +0x01,0x00,0x20,0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01, +0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01, +0x00,0x20,0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00, +0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00, +0x20,0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20, +0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00, +}; + + +//---------------------------------------------------------------------------- +// GUI image for Text displacement +//---------------------------------------------------------------------------- + +static const ULONG Text_Displacement_colors[] = +{ + 0x66666666,0x66666666,0x55555555, + 0xaaaaaaaa,0x99999999,0x99999999, + 0x77777777,0x77777777,0x66666666, + 0x00000000,0x66666666,0xffffffff, + 0x88888888,0x77777777,0x77777777, + 0x88888888,0x99999999,0xaaaaaaaa, + 0x99999999,0xaaaaaaaa,0xbbbbbbbb, + 0xffffffff,0xffffffff,0xffffffff, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0x99999999,0xaaaaaaaa,0xcccccccc, + 0xaaaaaaaa,0xaaaaaaaa,0xcccccccc, + 0xbbbbbbbb,0xcccccccc,0xdddddddd, + 0xffffffff,0xaaaaaaaa,0x99999999, + 0xcccccccc,0xcccccccc,0xdddddddd, + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, +}; + +#define TEXT_DISPLACEMENT_WIDTH 149 +#define TEXT_DISPLACEMENT_HEIGHT 40 +#define TEXT_DISPLACEMENT_DEPTH 4 +#define TEXT_DISPLACEMENT_COMPRESSION 1 +#define TEXT_DISPLACEMENT_MASKING 2 + +//static const struct BitMapHeader Text_Displacement_header = +//{ 149,40,0,0,4,2,1,0,0,44,22,320,512 }; + +static const UBYTE Text_Displacement_body[] = +{ +0xed,0x00,0xed,0x00,0xed,0x00,0xed,0x00,0x01,0x00,0x20,0xf2,0x00,0x02,0x07, +0x00,0x00,0x01,0x00,0x20,0xf3,0x00,0x03,0x20,0x07,0x00,0x00,0x01,0x00,0x20, +0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20, +0xf2,0x00,0x02,0x07,0x00,0x00,0x01,0x00,0x20,0xf3,0x00,0x03,0x20,0x07,0x00, +0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe, +0x00,0x01,0x00,0x20,0xf2,0x00,0x02,0x07,0x00,0x00,0x01,0x00,0x20,0xf3,0x00, +0x03,0x20,0x07,0x00,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1, +0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf2,0x00,0x02,0x07,0x00,0x00,0x01, +0x00,0x20,0xf4,0xff,0x04,0xf8,0x20,0x07,0x00,0x00,0x01,0x00,0x20,0xf4,0xff, +0x01,0xf8,0x20,0xfe,0x00,0xff,0x00,0xf4,0xff,0x01,0xf8,0x20,0xfe,0x00,0x01, +0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x07,0x00,0x00,0x02,0x00,0x20,0x80,0xf5, +0x00,0x04,0x08,0x20,0x07,0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08, +0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00, +0x20,0xf4,0x00,0x04,0x08,0x00,0x07,0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00, +0x04,0x08,0x20,0x07,0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20, +0xfe,0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20, +0xf4,0x00,0x04,0x08,0x00,0xff,0xe0,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x04, +0x08,0x20,0xff,0xe0,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20,0xfe, +0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4, +0x00,0x04,0x08,0x00,0x7f,0xe0,0x00,0x08,0x00,0x20,0x87,0xf0,0x00,0x00,0x32, +0x00,0x0c,0xfb,0x00,0x04,0x08,0x20,0x7f,0xe0,0x00,0x08,0x00,0x20,0x87,0xf0, +0x00,0x00,0x32,0x00,0x0c,0xfb,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x06, +0x87,0xf0,0x00,0x00,0x32,0x00,0x0c,0xfa,0x00,0x00,0x20,0xfe,0x00,0x01,0x00, +0x20,0xf4,0x00,0x04,0x08,0x00,0x3f,0xe0,0x00,0x08,0x00,0x20,0x84,0x90,0x00, +0x00,0x10,0x00,0x04,0xfb,0x00,0x04,0x08,0x20,0x3f,0xe0,0x00,0x08,0x00,0x20, +0x84,0x90,0x00,0x00,0x10,0x00,0x04,0xfb,0x00,0x01,0x08,0x20,0xfe,0x00,0xff, +0x00,0x06,0x84,0x90,0x00,0x00,0x10,0x00,0x04,0xfa,0x00,0x00,0x20,0xfe,0x00, +0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x1f,0xc0,0x00,0x08,0x00,0x20,0x80, +0x80,0x00,0x40,0x10,0x00,0x04,0xfd,0x00,0x06,0x02,0x00,0x08,0x20,0x1f,0xc0, +0x00,0x08,0x00,0x20,0x80,0x80,0x00,0x40,0x10,0x00,0x04,0xfd,0x00,0x03,0x02, +0x00,0x08,0x20,0xfe,0x00,0xff,0x00,0xff,0x80,0x04,0x00,0x40,0x10,0x00,0x04, +0xfd,0x00,0x03,0x02,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04, +0x08,0x00,0x0f,0x80,0x00,0x13,0x00,0x20,0x80,0x83,0x1b,0xf0,0x76,0x3b,0xc4, +0x61,0x8c,0xb6,0x19,0x67,0x80,0x08,0x20,0x0f,0x80,0x00,0x10,0x00,0x20,0x80, +0x83,0x1b,0xf0,0x76,0x3b,0xc4,0x61,0x8c,0xb6,0x19,0x67,0x80,0x08,0x20,0xfe, +0x00,0xff,0x00,0x0e,0x80,0x83,0x1b,0xf0,0x76,0x3b,0xc4,0x61,0x8c,0xb6,0x19, +0x67,0x80,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x07, +0x00,0x00,0x13,0x00,0x20,0x80,0x84,0x8a,0x40,0x92,0x49,0x24,0x92,0x52,0x49, +0x24,0x92,0x00,0x08,0x20,0x07,0x00,0x00,0x10,0x00,0x20,0x80,0x84,0x8a,0x40, +0x92,0x49,0x24,0x92,0x52,0x49,0x24,0x92,0x00,0x08,0x20,0xfe,0x00,0xff,0x00, +0x0e,0x80,0x84,0x8a,0x40,0x92,0x49,0x24,0x92,0x52,0x49,0x24,0x92,0x00,0x00, +0x20,0xfe,0x00,0x13,0x00,0x20,0x1f,0x78,0x7b,0xbf,0x6d,0x9e,0xdb,0x8d,0xe1, +0xb6,0xc3,0x6d,0xff,0xff,0xdf,0xff,0xe0,0x00,0x02,0x00,0x20,0x9f,0xf2,0xff, +0x01,0xe0,0x00,0x10,0x00,0x20,0x80,0x87,0x84,0x40,0x92,0x61,0x24,0x72,0x1e, +0x49,0x3c,0x92,0x00,0x08,0x20,0xfe,0x00,0xff,0x00,0x0e,0x80,0x87,0x84,0x40, +0x92,0x61,0x24,0x72,0x1e,0x49,0x3c,0x92,0x00,0x00,0x20,0xfe,0x00,0x01,0x00, +0x20,0xf4,0x00,0x00,0x08,0xfd,0x00,0x10,0x00,0x20,0x80,0x84,0x04,0x40,0x92, +0x19,0x24,0x92,0x10,0x49,0x20,0x92,0x00,0x08,0x20,0xfe,0x00,0x10,0x00,0x20, +0x80,0x84,0x04,0x40,0x92,0x19,0x24,0x92,0x10,0x49,0x20,0x92,0x00,0x08,0x20, +0xfe,0x00,0xff,0x00,0x0e,0x80,0x84,0x04,0x40,0x92,0x19,0x24,0x92,0x10,0x49, +0x20,0x92,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x08,0xfd, +0x00,0x10,0x00,0x20,0x80,0x86,0x4a,0x40,0x92,0x49,0x24,0x92,0x59,0x49,0x32, +0x92,0x00,0x08,0x20,0xfe,0x00,0x10,0x00,0x20,0x80,0x86,0x4a,0x40,0x92,0x49, +0x24,0x92,0x59,0x49,0x32,0x92,0x00,0x08,0x20,0xfe,0x00,0xff,0x00,0x0e,0x80, +0x86,0x4a,0x40,0x92,0x49,0x24,0x92,0x59,0x49,0x32,0x92,0x00,0x00,0x20,0xfe, +0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x08,0xfd,0x00,0x10,0x00,0x20,0x81,0xc3, +0x9b,0x30,0x6f,0x71,0xce,0x69,0x8e,0xed,0x9d,0xd9,0x80,0x08,0x20,0xfe,0x00, +0x10,0x00,0x20,0x81,0xc3,0x9b,0x30,0x6f,0x71,0xce,0x69,0x8e,0xed,0x9d,0xd9, +0x80,0x08,0x20,0xfe,0x00,0xff,0x00,0x0e,0x81,0xc3,0x9b,0x30,0x6f,0x71,0xce, +0x69,0x8e,0xed,0x9d,0xd9,0x80,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00, +0x00,0x08,0xfd,0x00,0x02,0x00,0x20,0x80,0xfd,0x00,0x00,0x01,0xfa,0x00,0x01, +0x08,0x20,0xfe,0x00,0x02,0x00,0x20,0x80,0xfd,0x00,0x00,0x01,0xfa,0x00,0x01, +0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xfd,0x00,0x00,0x01,0xf9,0x00,0x00, +0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x08,0xfd,0x00,0x02,0x00,0x20, +0x80,0xfd,0x00,0x00,0x01,0xfa,0x00,0x01,0x08,0x20,0xfe,0x00,0x02,0x00,0x20, +0x80,0xfd,0x00,0x00,0x01,0xfa,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x00, +0x80,0xfd,0x00,0x00,0x01,0xf9,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4, +0x00,0x00,0x08,0xfd,0x00,0x02,0x00,0x20,0x80,0xfd,0x00,0x01,0x03,0x80,0xfb, +0x00,0x01,0x08,0x20,0xfe,0x00,0x02,0x00,0x20,0x80,0xfd,0x00,0x01,0x03,0x80, +0xfb,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xfd,0x00,0x01,0x03, +0x80,0xfa,0x00,0x00,0x20,0xfe,0x00,0x02,0x00,0x20,0x1f,0xf4,0xff,0x03,0xdf, +0xff,0xe0,0x00,0x02,0x00,0x20,0x9f,0xf2,0xff,0x01,0xe0,0x00,0x02,0x00,0x20, +0x80,0xf5,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00, +0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x07,0x00,0x00,0x02, +0x00,0x20,0x80,0xf5,0x00,0x04,0x08,0x20,0x07,0x00,0x00,0x02,0x00,0x20,0x80, +0xf5,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20, +0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x0f,0x80,0x00,0x02,0x00, +0x20,0x80,0xf5,0x00,0x04,0x08,0x20,0x0f,0x80,0x00,0x02,0x00,0x20,0x80,0xf5, +0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe, +0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x1f,0xc0,0x00,0x02,0x00,0x20, +0x80,0xf5,0x00,0x04,0x08,0x20,0x1f,0xc0,0x00,0x02,0x00,0x20,0x80,0xf5,0x00, +0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe,0x00, +0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x3f,0xe0,0x00,0x02,0x00,0x20,0x80, +0xf5,0x00,0x04,0x08,0x20,0x3f,0xe0,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01, +0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01, +0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x7f,0xe0,0x00,0x02,0x00,0x20,0x80,0xf5, +0x00,0x04,0x08,0x20,0x7f,0xe0,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08, +0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00, +0x20,0xf4,0x00,0x04,0x08,0x00,0xff,0xe0,0x00,0x02,0x00,0x20,0x80,0xf5,0x00, +0x04,0x08,0x20,0xff,0xe0,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20, +0xfe,0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20, +0xf4,0x00,0x04,0x08,0x00,0x07,0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x04, +0x08,0x20,0x07,0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20,0xfe, +0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4, +0x00,0x04,0x08,0x00,0x07,0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x04,0x08, +0x20,0x07,0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20,0xfe,0x00, +0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00, +0x04,0x08,0x00,0x07,0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x04,0x08,0x20, +0x07,0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20,0xfe,0x00,0xff, +0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04, +0x08,0x00,0x07,0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x04,0x08,0x20,0x07, +0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00, +0x00,0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08, +0x00,0x07,0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x04,0x08,0x20,0x07,0x00, +0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x00, +0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00, +0x07,0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x04,0x08,0x20,0x07,0x00,0x00, +0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80, +0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x07, +0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x04,0x08,0x20,0x07,0x00,0x00,0x02, +0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xf4, +0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x08,0xfd,0x00,0x02, +0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20,0xfe,0x00,0x02,0x00,0x20,0x80,0xf5, +0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe, +0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x08,0xfd,0x00,0x02,0x00,0x20,0x80,0xf5, +0x00,0x01,0x08,0x20,0xfe,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20, +0xfe,0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x02,0x00,0x20, +0x7f,0xf5,0xff,0x00,0xf8,0xfd,0x00,0x01,0x00,0x20,0xf4,0xff,0x01,0xf8,0x20, +0xfe,0x00,0x01,0x00,0x20,0xf4,0xff,0x01,0xf8,0x20,0xfe,0x00,0xff,0x00,0x00, +0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xef,0x00,0x01,0x00,0x20, +0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00, +0xf1,0x00,0x00,0x20,0xfe,0x00,0xed,0x00,0xed,0x00,0xed,0x00,0xed,0x00,0xed, +0x00,0xed,0x00,0xed,0x00,0xed,0x00, +}; + + +//---------------------------------------------------------------------------- +// GUI image for Vertical Offset +//---------------------------------------------------------------------------- + +static const ULONG Vertical_Offset_colors[] = +{ + 0x66666666,0x66666666,0x55555555, + 0xaaaaaaaa,0x99999999,0x99999999, + 0x77777777,0x77777777,0x66666666, + 0x00000000,0x66666666,0xffffffff, + 0x88888888,0x77777777,0x77777777, + 0x88888888,0x99999999,0xaaaaaaaa, + 0x99999999,0xaaaaaaaa,0xbbbbbbbb, + 0xffffffff,0xffffffff,0xffffffff, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0x99999999,0xaaaaaaaa,0xcccccccc, + 0xaaaaaaaa,0xaaaaaaaa,0xcccccccc, + 0xbbbbbbbb,0xcccccccc,0xdddddddd, + 0xffffffff,0xaaaaaaaa,0x99999999, + 0xcccccccc,0xcccccccc,0xdddddddd, + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, +}; + +#define VERTICAL_OFFSET_WIDTH 149 +#define VERTICAL_OFFSET_HEIGHT 40 +#define VERTICAL_OFFSET_DEPTH 4 +#define VERTICAL_OFFSET_COMPRESSION 1 +#define VERTICAL_OFFSET_MASKING 2 + +//static const struct BitMapHeader Vertical_Offset_header = +//{ 149,40,0,0,4,2,1,0,0,44,22,320,512 }; + +static const UBYTE Vertical_Offset_body[] = +{ +0xf0,0x00,0x02,0x07,0x00,0x00,0xf0,0x00,0x02,0x07,0x00,0x00,0xed,0x00,0xed, +0x00,0xf0,0x00,0x02,0x07,0x00,0x00,0xf0,0x00,0x02,0x07,0x00,0x00,0xed,0x00, +0xed,0x00,0xf0,0x00,0x02,0x07,0x00,0x00,0xf0,0x00,0x02,0x07,0x00,0x00,0xed, +0x00,0xed,0x00,0xf0,0x00,0x02,0x07,0x00,0x00,0xf0,0x00,0x02,0x07,0x00,0x00, +0xed,0x00,0xed,0x00,0xf0,0x00,0x02,0x07,0x00,0x00,0xf0,0x00,0x02,0x07,0x00, +0x00,0xed,0x00,0xed,0x00,0xf0,0x00,0x02,0x07,0x00,0x00,0xf0,0x00,0x02,0x07, +0x00,0x00,0xed,0x00,0xed,0x00,0xf0,0x00,0x02,0x07,0x00,0x00,0xf0,0x00,0x02, +0x07,0x00,0x00,0xed,0x00,0xed,0x00,0xf0,0x00,0x02,0xff,0xf8,0x00,0xf0,0x00, +0x02,0xff,0xf8,0x00,0xed,0x00,0xed,0x00,0xf0,0x00,0x02,0x7f,0xf0,0x00,0xf0, +0x00,0x02,0x7f,0xf0,0x00,0xed,0x00,0xed,0x00,0xf0,0x00,0x02,0x3f,0xe0,0x00, +0xf0,0x00,0x02,0x3f,0xe0,0x00,0xed,0x00,0xed,0x00,0xf0,0x00,0x02,0x1f,0xc0, +0x00,0xf0,0x00,0x02,0x1f,0xc0,0x00,0xed,0x00,0xed,0x00,0xf0,0x00,0x02,0x0f, +0x80,0x00,0xf0,0x00,0x02,0x0f,0x80,0x00,0xed,0x00,0xed,0x00,0xf0,0x00,0x02, +0x07,0x00,0x00,0xf0,0x00,0x02,0x07,0x00,0x00,0xed,0x00,0xed,0x00,0x01,0x00, +0x3f,0xf3,0xff,0x03,0xcf,0xff,0xf8,0x00,0x01,0x00,0x3f,0xf3,0xff,0x03,0xef, +0xff,0xf8,0x00,0x01,0x00,0x3f,0xf3,0xff,0x00,0xe0,0xfe,0x00,0xf1,0x00,0x00, +0x20,0xfe,0x00,0x01,0x00,0x20,0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20, +0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20, +0xfe,0x00,0x01,0x00,0x20,0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe, +0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe, +0x00,0x01,0x00,0x20,0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00, +0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00, +0x01,0x00,0x20,0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01, +0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01, +0x00,0x20,0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00, +0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00, +0x20,0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20, +0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20, +0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3, +0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3, +0x00,0x03,0x0f,0xff,0xf8,0x00,0x01,0x00,0x20,0xf4,0xff,0x04,0xf8,0x2f,0xff, +0xf8,0x00,0x01,0x00,0x20,0xf4,0xff,0x01,0xf8,0x20,0xfe,0x00,0xff,0x00,0xf4, +0xff,0x01,0xf8,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x07, +0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x04,0x08,0x20,0x07,0x00,0x00,0x02, +0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xf4, +0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x0f,0x80, +0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x04,0x08,0x20,0x0f,0x80,0x00,0x02,0x00, +0x20,0x80,0xf5,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xf4,0x00, +0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x1f,0xc0,0x00, +0x02,0x00,0x20,0x80,0xf5,0x00,0x04,0x08,0x20,0x1f,0xc0,0x00,0x02,0x00,0x20, +0x80,0xf5,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00, +0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x3f,0xe0,0x00,0x09, +0x00,0x20,0x87,0x1c,0x00,0x04,0x00,0x30,0x00,0xd8,0xfc,0x00,0x04,0x08,0x20, +0x3f,0xe0,0x00,0x09,0x00,0x20,0x87,0x1c,0x00,0x04,0x00,0x30,0x00,0xd8,0xfc, +0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x07,0x87,0x1c,0x00,0x04,0x00,0x30, +0x00,0xd8,0xfb,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08, +0x00,0x7f,0xf0,0x00,0x03,0x00,0x20,0x82,0x08,0xfe,0x00,0x02,0x10,0x01,0x20, +0xfc,0x00,0x04,0x08,0x20,0x7f,0xf0,0x00,0x03,0x00,0x20,0x82,0x08,0xfe,0x00, +0x02,0x10,0x01,0x20,0xfc,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x01,0x82, +0x08,0xfe,0x00,0x02,0x10,0x01,0x20,0xfb,0x00,0x00,0x20,0xfe,0x00,0x01,0x00, +0x20,0xf4,0x00,0x04,0x08,0x00,0xff,0xf8,0x00,0x0b,0x00,0x20,0x81,0x10,0x00, +0x40,0x00,0x10,0x01,0x20,0x00,0x40,0xfe,0x00,0x04,0x08,0x20,0xff,0xf8,0x00, +0x0b,0x00,0x20,0x81,0x10,0x00,0x40,0x00,0x10,0x01,0x20,0x00,0x40,0xfe,0x00, +0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x09,0x81,0x10,0x00,0x40,0x00,0x10,0x01, +0x20,0x00,0x40,0xfd,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04, +0x08,0x00,0x07,0x00,0x00,0x0b,0x00,0x20,0x81,0x10,0xcb,0xfc,0x63,0x10,0x33, +0xf3,0x8c,0xf0,0xfe,0x00,0x04,0x08,0x20,0x07,0x00,0x00,0x0b,0x00,0x20,0x81, +0x10,0xcb,0xfc,0x63,0x10,0x33,0xf3,0x8c,0xf0,0xfe,0x00,0x01,0x08,0x20,0xfe, +0x00,0xff,0x00,0x09,0x81,0x10,0xcb,0xfc,0x63,0x10,0x33,0xf3,0x8c,0xf0,0xfd, +0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x07,0x00, +0x00,0x0b,0x00,0x20,0x80,0xa1,0x26,0x44,0x94,0x90,0x49,0x24,0x92,0x40,0xfe, +0x00,0x04,0x08,0x20,0x07,0x00,0x00,0x0b,0x00,0x20,0x80,0xa1,0x26,0x44,0x94, +0x90,0x49,0x24,0x92,0x40,0xfe,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x09, +0x80,0xa1,0x26,0x44,0x94,0x90,0x49,0x24,0x92,0x40,0xfd,0x00,0x00,0x20,0xfe, +0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x07,0x00,0x00,0x0b,0x00,0x20, +0x80,0xa1,0xe4,0x44,0x83,0x90,0x49,0x26,0x1e,0x40,0xfe,0x00,0x04,0x08,0x20, +0x07,0x00,0x00,0x0b,0x00,0x20,0x80,0xa1,0xe4,0x44,0x83,0x90,0x49,0x26,0x1e, +0x40,0xfe,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x09,0x80,0xa1,0xe4,0x44, +0x83,0x90,0x49,0x26,0x1e,0x40,0xfd,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20, +0xf4,0x00,0x04,0x08,0x00,0x07,0x00,0x00,0x0b,0x00,0x20,0x80,0xe1,0x04,0x44, +0x84,0x90,0x49,0x21,0x90,0x40,0xfe,0x00,0x04,0x08,0x20,0x07,0x00,0x00,0x0b, +0x00,0x20,0x80,0xe1,0x04,0x44,0x84,0x90,0x49,0x21,0x90,0x40,0xfe,0x00,0x01, +0x08,0x20,0xfe,0x00,0xff,0x00,0x09,0x80,0xe1,0x04,0x44,0x84,0x90,0x49,0x21, +0x90,0x40,0xfd,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08, +0x00,0x07,0x00,0x00,0x0b,0x00,0x20,0x80,0x41,0x94,0x44,0x94,0x90,0x49,0x24, +0x99,0x40,0xfe,0x00,0x04,0x08,0x20,0x07,0x00,0x00,0x0b,0x00,0x20,0x80,0x41, +0x94,0x44,0x94,0x90,0x49,0x24,0x99,0x40,0xfe,0x00,0x01,0x08,0x20,0xfe,0x00, +0xff,0x00,0x09,0x80,0x41,0x94,0x44,0x94,0x90,0x49,0x24,0x99,0x40,0xfd,0x00, +0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x07,0x00,0x00, +0x0b,0x00,0x20,0x80,0x40,0xee,0x3e,0x63,0x78,0x31,0x27,0x0e,0x30,0xfe,0x00, +0x04,0x08,0x20,0x07,0x00,0x00,0x0b,0x00,0x20,0x80,0x40,0xee,0x3e,0x63,0x78, +0x31,0x27,0x0e,0x30,0xfe,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x09,0x80, +0x40,0xee,0x3e,0x63,0x78,0x31,0x27,0x0e,0x30,0xfd,0x00,0x00,0x20,0xfe,0x00, +0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x07,0x00,0x00,0x02,0x00,0x20,0x80, +0xf5,0x00,0x04,0x08,0x20,0x07,0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01, +0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01, +0x00,0x20,0xf4,0x00,0x00,0x08,0xfd,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01, +0x08,0x20,0xfe,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20,0xfe,0x00, +0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00, +0x00,0x08,0xfd,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20,0xfe,0x00, +0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80, +0xf4,0x00,0x00,0x20,0xfe,0x00,0xed,0x00,0xed,0x00,0xed,0x00,0xed,0x00,0xed, +0x00,0xed,0x00,0xed,0x00,0xed,0x00,0xed,0x00,0xed,0x00,0xed,0x00,0xed,0x00, +}; + + +//---------------------------------------------------------------------------- +// GUI image for Vertical Spacing +//---------------------------------------------------------------------------- + +static const ULONG Vertical_Space_colors[] = +{ + 0x66666666,0x66666666,0x55555555, + 0xaaaaaaaa,0x99999999,0x99999999, + 0x77777777,0x77777777,0x66666666, + 0x00000000,0x66666666,0xffffffff, + 0x88888888,0x77777777,0x77777777, + 0x88888888,0x99999999,0xaaaaaaaa, + 0x99999999,0xaaaaaaaa,0xbbbbbbbb, + 0xffffffff,0xffffffff,0xffffffff, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0x99999999,0xaaaaaaaa,0xcccccccc, + 0xaaaaaaaa,0xaaaaaaaa,0xcccccccc, + 0xbbbbbbbb,0xcccccccc,0xdddddddd, + 0xffffffff,0xaaaaaaaa,0x99999999, + 0xcccccccc,0xcccccccc,0xdddddddd, + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, +}; + +#define VERTICAL_SPACE_WIDTH 149 +#define VERTICAL_SPACE_HEIGHT 40 +#define VERTICAL_SPACE_DEPTH 4 +#define VERTICAL_SPACE_COMPRESSION 1 +#define VERTICAL_SPACE_MASKING 2 + +//static const struct BitMapHeader Vertical_Space_header = +//{ 149,40,0,0,4,2,1,0,0,44,22,320,512 }; + +static const UBYTE Vertical_Space_body[] = +{ +0xed,0x00,0xed,0x00,0xed,0x00,0xed,0x00,0x01,0x00,0x20,0xef,0x00,0x01,0x00, +0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe, +0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xef,0x00,0x01,0x00,0x20, +0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00, +0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf2,0x00,0x02,0x07,0x00,0x00, +0x01,0x00,0x20,0xf3,0x00,0x03,0x20,0x07,0x00,0x00,0x01,0x00,0x20,0xf3,0x00, +0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf2,0x00, +0x02,0x07,0x00,0x00,0x01,0x00,0x20,0xf3,0x00,0x03,0x20,0x07,0x00,0x00,0x01, +0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01, +0x00,0x20,0xf2,0x00,0x02,0x07,0x00,0x00,0x01,0x00,0x20,0xf3,0x00,0x03,0x20, +0x07,0x00,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00, +0x20,0xfe,0x00,0x01,0x00,0x20,0xf2,0x00,0x02,0x07,0x00,0x00,0x01,0x00,0x20, +0xf3,0x00,0x03,0x20,0x07,0x00,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe, +0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf2,0x00,0x02,0x07,0x00, +0x00,0x01,0x00,0x20,0xf3,0x00,0x03,0x20,0x07,0x00,0x00,0x01,0x00,0x20,0xf3, +0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf2, +0x00,0x02,0x07,0x00,0x00,0x07,0x00,0x20,0x07,0x1c,0x00,0x04,0x00,0x30,0xf9, +0x00,0x03,0x20,0x07,0x00,0x00,0x07,0x00,0x20,0x07,0x1c,0x00,0x04,0x00,0x30, +0xf9,0x00,0x00,0x20,0xfe,0x00,0xff,0x00,0x05,0x07,0x1c,0x00,0x04,0x00,0x30, +0xf9,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf2,0x00,0x02,0x07,0x00,0x00, +0x03,0x00,0x20,0x02,0x08,0xfe,0x00,0x00,0x10,0xf9,0x00,0x03,0x20,0x07,0x00, +0x00,0x03,0x00,0x20,0x02,0x08,0xfe,0x00,0x00,0x10,0xf9,0x00,0x00,0x20,0xfe, +0x00,0xff,0x00,0x01,0x02,0x08,0xfe,0x00,0x00,0x10,0xf9,0x00,0x00,0x20,0xfe, +0x00,0x01,0x00,0x20,0xf2,0x00,0x02,0xff,0xf8,0x00,0x07,0x00,0x20,0x01,0x10, +0x00,0x40,0x00,0x10,0xf9,0x00,0x03,0x20,0xff,0xf8,0x00,0x07,0x00,0x20,0x01, +0x10,0x00,0x40,0x00,0x10,0xf9,0x00,0x00,0x20,0xfe,0x00,0xff,0x00,0x05,0x01, +0x10,0x00,0x40,0x00,0x10,0xf9,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf2, +0x00,0x02,0x7f,0xf0,0x00,0x07,0x00,0x20,0x01,0x10,0xcb,0xfc,0x63,0x10,0xf9, +0x00,0x03,0x20,0x7f,0xf0,0x00,0x07,0x00,0x20,0x01,0x10,0xcb,0xfc,0x63,0x10, +0xf9,0x00,0x00,0x20,0xfe,0x00,0xff,0x00,0x05,0x01,0x10,0xcb,0xfc,0x63,0x10, +0xf9,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf2,0x00,0x02,0x3f,0xe0,0x00, +0x07,0x00,0x20,0x00,0xa1,0x26,0x44,0x94,0x90,0xf9,0x00,0x03,0x20,0x3f,0xe0, +0x00,0x07,0x00,0x20,0x00,0xa1,0x26,0x44,0x94,0x90,0xf9,0x00,0x00,0x20,0xfe, +0x00,0xfe,0x00,0x04,0xa1,0x26,0x44,0x94,0x90,0xf9,0x00,0x00,0x20,0xfe,0x00, +0x01,0x00,0x20,0xf2,0x00,0x02,0x1f,0xc0,0x00,0x07,0x00,0x20,0x00,0xa1,0xe4, +0x44,0x83,0x90,0xf9,0x00,0x03,0x20,0x1f,0xc0,0x00,0x07,0x00,0x20,0x00,0xa1, +0xe4,0x44,0x83,0x90,0xf9,0x00,0x00,0x20,0xfe,0x00,0xfe,0x00,0x04,0xa1,0xe4, +0x44,0x83,0x90,0xf9,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf2,0x00,0x02, +0x0f,0x80,0x00,0x07,0x00,0x20,0x00,0xe1,0x04,0x44,0x84,0x90,0xf9,0x00,0x03, +0x20,0x0f,0x80,0x00,0x07,0x00,0x20,0x00,0xe1,0x04,0x44,0x84,0x90,0xf9,0x00, +0x00,0x20,0xfe,0x00,0xfe,0x00,0x04,0xe1,0x04,0x44,0x84,0x90,0xf9,0x00,0x00, +0x20,0xfe,0x00,0x01,0x00,0x20,0xf2,0x00,0x02,0x07,0x00,0x00,0x07,0x00,0x20, +0x00,0x41,0x94,0x44,0x94,0x90,0xf9,0x00,0x03,0x20,0x07,0x00,0x00,0x07,0x00, +0x20,0x00,0x41,0x94,0x44,0x94,0x90,0xf9,0x00,0x00,0x20,0xfe,0x00,0xfe,0x00, +0x04,0x41,0x94,0x44,0x94,0x90,0xf9,0x00,0x00,0x20,0xfe,0x00,0x03,0x00,0x23, +0xff,0x1c,0xfe,0x00,0x00,0x01,0xf9,0xff,0x03,0x8f,0xff,0xf8,0x00,0x07,0x00, +0x23,0xff,0x5c,0xee,0x3e,0x63,0x79,0xf9,0xff,0x03,0xaf,0xff,0xf8,0x00,0x07, +0x00,0x20,0x00,0x40,0xee,0x3e,0x63,0x78,0xf9,0x00,0x00,0x20,0xfe,0x00,0xfe, +0x00,0x04,0x40,0xee,0x3e,0x63,0x78,0xf9,0x00,0x00,0x20,0xfe,0x00,0x01,0x00, +0x20,0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20, +0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20, +0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3, +0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xef, +0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00, +0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xef,0x00, +0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00, +0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xef,0x00,0x01, +0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20, +0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xef,0x00,0x01,0x00, +0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe, +0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xef,0x00,0x01,0x00,0x20, +0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00, +0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x23,0xfe,0xff,0x00,0xe1,0xf7,0xff, +0x03,0x8f,0xff,0xf8,0x00,0x01,0x00,0x23,0xfe,0xff,0x00,0xe9,0xf7,0xff,0x03, +0xaf,0xff,0xf8,0x00,0x01,0x00,0x20,0xfe,0x00,0x00,0x08,0xf7,0x00,0x00,0x20, +0xfe,0x00,0xfc,0x00,0x00,0x08,0xf7,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20, +0xf2,0x00,0x02,0x07,0x00,0x00,0x01,0x00,0x20,0xf3,0x00,0x03,0x20,0x07,0x00, +0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe, +0x00,0x01,0x00,0x20,0xf2,0x00,0x02,0x0f,0x80,0x00,0x01,0x00,0x20,0xf3,0x00, +0x03,0x20,0x0f,0x80,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1, +0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf2,0x00,0x02,0x1f,0xc0,0x00,0x07, +0x00,0x20,0x03,0xbc,0x30,0xda,0xc3,0xc0,0xf9,0x00,0x03,0x20,0x1f,0xc0,0x00, +0x07,0x00,0x20,0x03,0xbc,0x30,0xda,0xc3,0xc0,0xf9,0x00,0x00,0x20,0xfe,0x00, +0xff,0x00,0x05,0x03,0xbc,0x30,0xda,0xc3,0xc0,0xf9,0x00,0x00,0x20,0xfe,0x00, +0x01,0x00,0x20,0xf2,0x00,0x02,0x3f,0xe0,0x00,0x07,0x00,0x20,0x04,0x92,0x49, +0x29,0x24,0x80,0xf9,0x00,0x03,0x20,0x3f,0xe0,0x00,0x07,0x00,0x20,0x04,0x92, +0x49,0x29,0x24,0x80,0xf9,0x00,0x00,0x20,0xfe,0x00,0xff,0x00,0x05,0x04,0x92, +0x49,0x29,0x24,0x80,0xf9,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf2,0x00, +0x02,0x7f,0xf0,0x00,0x07,0x00,0x20,0x06,0x12,0x39,0x09,0x24,0x80,0xf9,0x00, +0x03,0x20,0x7f,0xf0,0x00,0x07,0x00,0x20,0x06,0x12,0x39,0x09,0x24,0x80,0xf9, +0x00,0x00,0x20,0xfe,0x00,0xff,0x00,0x05,0x06,0x12,0x39,0x09,0x24,0x80,0xf9, +0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf2,0x00,0x02,0xff,0xf8,0x00,0x06, +0x00,0x20,0x01,0x92,0x49,0x09,0x27,0xf8,0x00,0x03,0x20,0xff,0xf8,0x00,0x06, +0x00,0x20,0x01,0x92,0x49,0x09,0x27,0xf8,0x00,0x00,0x20,0xfe,0x00,0xff,0x00, +0x04,0x01,0x92,0x49,0x09,0x27,0xf8,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20, +0xf2,0x00,0x02,0x07,0x00,0x00,0x06,0x00,0x20,0x04,0x92,0x49,0x29,0x22,0xf8, +0x00,0x03,0x20,0x07,0x00,0x00,0x06,0x00,0x20,0x04,0x92,0x49,0x29,0x22,0xf8, +0x00,0x00,0x20,0xfe,0x00,0xff,0x00,0x04,0x04,0x92,0x49,0x29,0x22,0xf8,0x00, +0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf2,0x00,0x02,0x07,0x00,0x00,0x07,0x00, +0x20,0x07,0x1c,0x34,0xdf,0xb3,0x80,0xf9,0x00,0x03,0x20,0x07,0x00,0x00,0x07, +0x00,0x20,0x07,0x1c,0x34,0xdf,0xb3,0x80,0xf9,0x00,0x00,0x20,0xfe,0x00,0xff, +0x00,0x05,0x07,0x1c,0x34,0xdf,0xb3,0x80,0xf9,0x00,0x00,0x20,0xfe,0x00,0x01, +0x00,0x20,0xf2,0x00,0x02,0x07,0x00,0x00,0x07,0x00,0x20,0x00,0x10,0x00,0x00, +0x04,0x40,0xf9,0x00,0x03,0x20,0x07,0x00,0x00,0x07,0x00,0x20,0x00,0x10,0x00, +0x00,0x04,0x40,0xf9,0x00,0x00,0x20,0xfe,0x00,0xfe,0x00,0x04,0x10,0x00,0x00, +0x04,0x40,0xf9,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf2,0x00,0x02,0x07, +0x00,0x00,0x07,0x00,0x20,0x00,0x10,0x00,0x00,0x04,0x40,0xf9,0x00,0x03,0x20, +0x07,0x00,0x00,0x07,0x00,0x20,0x00,0x10,0x00,0x00,0x04,0x40,0xf9,0x00,0x00, +0x20,0xfe,0x00,0xfe,0x00,0x04,0x10,0x00,0x00,0x04,0x40,0xf9,0x00,0x00,0x20, +0xfe,0x00,0x01,0x00,0x20,0xf2,0x00,0x02,0x07,0x00,0x00,0x07,0x00,0x20,0x00, +0x38,0x00,0x00,0x03,0x80,0xf9,0x00,0x03,0x20,0x07,0x00,0x00,0x07,0x00,0x20, +0x00,0x38,0x00,0x00,0x03,0x80,0xf9,0x00,0x00,0x20,0xfe,0x00,0xfe,0x00,0x04, +0x38,0x00,0x00,0x03,0x80,0xf9,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf2, +0x00,0x02,0x07,0x00,0x00,0x01,0x00,0x20,0xf3,0x00,0x03,0x20,0x07,0x00,0x00, +0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00, +0x01,0x00,0x20,0xf2,0x00,0x02,0x07,0x00,0x00,0x01,0x00,0x20,0xf3,0x00,0x03, +0x20,0x07,0x00,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00, +0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00, +0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00, +0x20,0xfe,0x00,0x01,0x00,0x20,0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20, +0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20, +0xfe,0x00, +}; + + +//---------------------------------------------------------------------------- +// GUI example for old-style spacers +//---------------------------------------------------------------------------- +static const ULONG OldStyle_colors[] = +{ + 0xffffffff,0x66666666,0x00000000, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0xeeeeeeee,0xeeeeeeee,0xeeeeeeee, + 0xbbbbbbbb,0x00000000,0x00000000, + 0x88888888,0x00000000,0x88888888, + 0xffffffff,0x44444444,0xaaaaaaaa, + 0xeeeeeeee,0x00000000,0x00000000, + 0x66666666,0x22222222,0x00000000, + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xaaaaaaaa,0x88888888, + 0xffffffff,0xeeeeeeee,0x00000000, + 0x00000000,0x88888888,0x00000000, + 0x00000000,0xdddddddd,0x00000000, + 0x00000000,0xcccccccc,0xcccccccc, + 0x00000000,0x66666666,0xffffffff, + 0x00000000,0x00000000,0xaaaaaaaa, +}; + +#define OLDSTYLE_WIDTH 127 +#define OLDSTYLE_HEIGHT 7 +#define OLDSTYLE_DEPTH 4 +#define OLDSTYLE_COMPRESSION 1 +#define OLDSTYLE_MASKING 2 + +//const struct BitMapHeader OldStyle_header = +//{ 127,7,0,0,4,2,1,0,0,44,22,320,512 }; + +static const UBYTE OldStyle_body[] = { +0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1, +0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0x00,0x5d,0xf3,0xdd,0x00,0xdc,0xf1,0x00, +0xf1,0x00,0xf1,0x00,0xf2,0x77,0x00,0x74,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1, +0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00, +0xf1,0x00, }; + +//---------------------------------------------------------------------------- +// GUI example for new-style spacers +//---------------------------------------------------------------------------- +static const ULONG NewStyle_colors[] = +{ + 0xffffffff,0x66666666,0x00000000, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0xeeeeeeee,0xeeeeeeee,0xeeeeeeee, + 0xbbbbbbbb,0x00000000,0x00000000, + 0x88888888,0x00000000,0x88888888, + 0xffffffff,0x44444444,0xaaaaaaaa, + 0xeeeeeeee,0x00000000,0x00000000, + 0x66666666,0x22222222,0x00000000, + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xaaaaaaaa,0x88888888, + 0xffffffff,0xeeeeeeee,0x00000000, + 0x00000000,0x88888888,0x00000000, + 0x00000000,0xdddddddd,0x00000000, + 0x00000000,0xcccccccc,0xcccccccc, + 0x00000000,0x66666666,0xffffffff, + 0x00000000,0x00000000,0xaaaaaaaa, +}; + +#define NEWSTYLE_WIDTH 127 +#define NEWSTYLE_HEIGHT 7 +#define NEWSTYLE_DEPTH 4 +#define NEWSTYLE_COMPRESSION 1 +#define NEWSTYLE_MASKING 2 + +//const struct BitMapHeader NewStyle_header = +//{ 127,7,0,0,4,2,1,0,0,44,22,320,512 }; + +static const UBYTE NewStyle_body[] = { +0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1, +0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0x00,0x3f,0xf3,0xff,0x00,0xf8,0xf1,0x00, +0x00,0x1f,0xf3,0xff,0x00,0xfc,0xf1,0x00,0x00,0x60,0xf2,0x00,0xf1,0x00,0xf1, +0x00,0xf1,0x00,0x00,0x40,0xf2,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00, +0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00, }; + +//---------------------------------------------------------------------------- + + diff --git a/scalos/Plugins/Prefs/Popupmenu/ScalosPopupMenu.cd b/scalos/Plugins/Prefs/Popupmenu/ScalosPopupMenu.cd new file mode 100755 index 000000000..42bc4b354 --- /dev/null +++ b/scalos/Plugins/Prefs/Popupmenu/ScalosPopupMenu.cd @@ -0,0 +1,483 @@ +; ScalosPopupMenu.cd +; version $VER: ScalosPopupMenu.catalog 40.1 (10 Jan 2010 14:32:34) +; codeset 0s +; language english +; +;#arrayopts static __far +; +;--------------------------------------------- +; +MSGID_PLUGIN_LIST_TITLE (//) +PopupMenu +; +; +MSGID_TITLENAME (//) +Scalos PopupMenu Prefs Plugin +; +;--------------------------------------------- +; +MSGID_MENU_PROJECT_OPEN (5000//) +Open... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT (/1/1) +O +; +; +MSGID_MENU_PROJECT_SAVEAS (//) +Save As... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT (/1/1) +A +; +; +MSGID_MENU_PROJECT_ABOUT (//) +About... +; +; +MSGID_MENU_PROJECT_QUIT (//) +Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT (/1/1) +Q +; +; +MSGID_MENU_PROJECT (//) +Project +; +; +MSGID_MENU_EDIT_LASTSAVED (//) +Last Saved +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT (/1/1) +L +; +; +MSGID_MENU_EDIT (//) +Edit +; +; +MSGID_MENU_SETTINGS_CREATEICONS (//) +Create Icons? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT (/1/1) +I +; +; +MSGID_MENU_SETTINGS (//) +Settings +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS (//) +Reset To Defaults +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT (/1/1) +D +; +; +MSGID_MENU_EDIT_RESTORE (//) +Restore +; +; +MSGID_MENU_EDIT_RESTORE_SHORT (/1/1) +R +; +; +MSGID_MENU_PROJECT_ABOUTMUI (//) +About MUI... +; +;--------------------------------------------- +; +MSGID_ABOUTREQOK (6000//) +_OK +; +; +MSGID_ABOUTREQFORMAT (//) +\33c\033bScalos PopupMenu Preferences V%ld.%ld\033n\n\ +%s\n\ +© 2006%s The Scalos Team +; +;--------------------------------------------- +; +MSGID_SHORTHELP_SAVEBUTTON (7000//) +Press this button to save \n\ +the current settings to\n\ +\"ENVARC:sys/PopupMenu.prefs\"\n\ +and make changes permanent. +; +; +MSGID_SHORTHELP_USEBUTTON (//) +Press this button to save \n\ +the current settings to\n\ +\"ENV:sys/PopupMenu.prefs\"\n\ +and keep settings until reboot. +; +; +MSGID_SHORTHELP_CANCELBUTTON (//) +Press this button to abort \n\ +and forget all changes. +; +;--------------------------------------------- +; +MSGID_REQTITLE_SAVEERROR (7500//) +Error writing PopupMenu preferences\n\ +file \"%s\"\n\ +%s +; +; +MSGID_REQTITLE_READERROR (//) +Error reading PopupMenu preferences\n\ +file \"%s\"\n\ +%s +; +;--------------------------------------------- +; +MSGID_POPUP_ASLTITLE_MENUPLUGIN (8000//) +Select Scalos PopupMenu prefs +; +; +MSGID_SHORTHELP_LAMP_CHANGED (//) +This lamp indicator changes from \033bOff\033n\n\ +to \033bOk\033n when the settings have been\n\ +modified since initial loading. +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE (8500//) +Scalos PopupMenu Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD (//) +Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_PREFSPAGES_MISC (9000//) +Misc. +; +; +MSGID_PREFSPAGES_BORDERS (//) +Borders +; +; +MSGID_PREFSPAGES_SPACING (//) +Spacing +; +; +MSGID_PREFSPAGES_TEXT (//) +Text +; +; +MSGID_PREFSPAGES_TRANSPARENCY (//) +Transparency +; +;----------------------------------------------------------- +; +MSGID_MISCPAGE_TITLE (9600//) +Miscellaneous +; +; +MSGID_MISCPAGE_ANIMATION_TYPE (//) +Type: +; +; +MSGID_MISCPAGE_ANIMATION_TYPE_SHORTHELP (//) +Select the type of animation\n\ +used to open the popup menu. +; +; +MSGID_MISCPAGE_ANIMATION (//) +Animation +; +; +MSGID_MISCPAGE_DELAY_SUBMENUS (//) +Delay for submenus: +; +; +MSGID_MISCPAGE_DELAY_SUBMENUS_SHORTHELP (//) +Here you can adjust how long it will take\n\ +until the submenu opens when you move the\n\ +mouse of the submenu item. +; +; +MSGID_MISCPAGE_MENUSHADOWS (//) +Menu Shadows? +; +; +MSGID_MISCPAGE_MENUSHADOWS_SHORTHELP (//) +Select here whether popup menus\n\ +will have a drop-shadow. +; +; +MSGID_MISCPAGE_STICKY (//) +Sticky? +; +; +MSGID_MISCPAGE_STICKY_SHORTHELP (//) +Select here whether popup menus will behave sticky,\n\ +i.e. will stay open after you release the right mouse\n\ +button. +; +; +MSGID_MISCPAGE_REALSHADOWS (//) +Real Shadows? +; +; +MSGID_MISCPAGE_REALSHADOWS_SHORTHELP (//) +If selected, realistic and translucent dropshadows\n\ +are drawn (required graphics board and hi-colour\n\ +or true-colour screen). +; +; +MSGID_ANIMATION_NONE (//) +None +; +; +MSGID_ANIMATION_ZOOM (//) +Zoom +; +; +MSGID_ANIMATION_FADE (//) +Fade +; +; +MSGID_ANIMATION_EXPLODE (//) +Explode +; +;----------------------------------------------------------- +; +MSGID_BORDERSPAGE_TITLE (9800//) +Menu Border +; +; +MSGID_BORDERSPAGE_MENUBORDER (//) +Menu Border +; +; +MSGID_BORDERSPAGE_SELECTEDITEM (//) +Selected Item +; +; +MSGID_BORDERSPAGE_SEPARATORS (//) +Separators +; +; +MSGID_BORDERSPAGE_NORMAL (//) +Normal +; +; +MSGID_BORDERSPAGE_RAISED (//) +Raised +; +; +MSGID_BORDERSPAGE_RECESSED (//) +Recessed +; +; +MSGID_BORDERSPAGE_NEW_LOOK (//) +New Look +; +; +MSGID_BORDERSPAGE_OLD_LOOK (//) +Old Look +; +;----------------------------------------------------------- +; +MSGID_SPACINGPAGE_TITLE (9900//) +Spacing +; +; +MSGID_SPACINGPAGE_HORIZONTAL_SPACE (//) +Horizontal inner spacing +; +; +MSGID_SPACINGPAGE_VERTICAL_SPACE (//) +Vertical spacing +; +; +MSGID_SPACINGPAGE_HORIZONTAL (//) +Horizontal outer spacing +; +; +MSGID_SPACINGPAGE_VERTICAL_OFFSET (//) +Vertical offset +; +; +MSGID_SPACINGPAGE_INTERMEDIATE_SPACING (//) +Intermediate spacing +; +; +MSGID_SPACINGPAGE_TEXT_DISPLACEMENT (//) +Text displacement +; +;----------------------------------------------------------- +; +MSGID_TEXTPAGE_TITLE (10000//) +Text styles +; +; +MSGID_TEXTPAGE_MENU_TITLES (//) +Menu Titles +; +; +MSGID_TEXTPAGE_MENU_ITEMS (//) +Menu Items +; +; +MSGID_TEXTPAGE_MENUTITLES_ITALIC (//) +\033iItalic?\033n +; +; +MSGID_TEXTPAGE_MENUTITLES_ITALIC_SHORTHELP (//) +If checked, menu titles will be drawn \033iitalic\033n. +; +; +MSGID_TEXTPAGE_MENUTITLES_SHADOWED (//) +Shadowed? +; +; +MSGID_TEXTPAGE_MENUTITLES_SHADOWED_SHORTHELP (//) +If checked, menu titles will be drawn shadowed. +; +; +MSGID_TEXTPAGE_MENUTITLES_UNDERLINED (//) +\033uUnderlined?\033n +; +; +MSGID_TEXTPAGE_MENUTITLES_UNDERLINED_SHORTHELP (//) +If checked, menu titles will be drawn \033uunderlined\033n. +; +; +MSGID_TEXTPAGE_MENUTITLES_OUTLINED (//) +Outlined? +; +; +MSGID_TEXTPAGE_MENUTITLES_OUTLINED_SHORTHELP (//) +If checked, menu titles will be drawn outlined. +; +; +MSGID_TEXTPAGE_MENUTITLES_BOLD (//) +\033bBold?\033n +; +; +MSGID_TEXTPAGE_MENUTITLES_BOLD_SHORTHELP (//) +If checked, menu titles will be drawn \033bbold\033n. +; +; +MSGID_TEXTPAGE_MENUTITLES_EMBOSSED (//) +Embossed? +; +; +MSGID_TEXTPAGE_MENUTITLES_EMBOSSED_SHORTHELP (//) +If checked, menu titles will be drawn embossed. +; +; +MSGID_TEXTPAGE_MENUITEMS_ITALIC (//) +\033iItalic?\033n +; +; +MSGID_TEXTPAGE_MENUITEMS_ITALIC_SHORTHELP (//) +If checked, menu items will be drawn \033iitalic\033n. +; +; +MSGID_TEXTPAGE_MENUITEMS_SHADOWED (//) +Shadowed? +; +; +MSGID_TEXTPAGE_MENUITEMS_SHADOWED_SHORTHELP (//) +If checked, menu items will be drawn shadowed. +; +; +MSGID_TEXTPAGE_MENUITEMS_UNDERLINED (//) +\033uUnderlined?\033n +; +; +MSGID_TEXTPAGE_MENUITEMS_UNDERLINED_SHORTHELP (//) +If checked, menu items will be drawn \033uunderlined\033n. +; +; +MSGID_TEXTPAGE_MENUITEMS_OUTLINED (//) +Outlined? +; +; +MSGID_TEXTPAGE_MENUITEMS_OUTLINED_SHORTHELP (//) +If checked, menu items will be drawn outlined. +; +; +MSGID_TEXTPAGE_MENUITEMS_BOLD (//) +\033bBold?\033n +; +; +MSGID_TEXTPAGE_MENUITEMS_BOLD_SHORTHELP (//) +If checked, menu items will be drawn \033bbold\033n. +; +; +MSGID_TEXTPAGE_MENUITEMS_EMBOSSED (//) +Embossed? +; +; +MSGID_TEXTPAGE_MENUITEMS_EMBOSSED_SHORTHELP (//) +If checked, menu items will be drawn embossed. +; +;----------------------------------------------------------- +; +MSGID_TRANSPARENCYPAGE_TITLE (10400//) +Transparency +; +; +MSGID_TRANSPARENCYPAGE_TRANSP_NUMERIC_FORMAT (//) +%ld %% +; +; +MSGID_TRANSPARENCYPAGE_TRANSPARENCY (//) +Transparency +; +; +MSGID_TRANSPARENCYPAGE_BLUR (//) +Blur +; +; +MSGID_TRANSPARENCYPAGE_BLUR_SHORTHELP (//) +Here you can adjust the degree of blurring which is aplied\n\ +to the background shining through transparent popup menus. +; +; +MSGID_TRANSPARENCYPAGE_BLUR_NUMERIC_FORMAT (//) +%ld %% +; +; +MSGID_TRANSPARENCYPAGE_ENABLE (//) +Transparent Menus? +; +; +MSGID_TRANSPARENCYPAGE_ENABLE_SHORTHELP (//) +If checked, popup menus are transparent, with\n\ +the contents behind shining through. +; +;----------------------------------------------------------- +; diff --git a/scalos/Plugins/Prefs/Popupmenu/config.mk b/scalos/Plugins/Prefs/Popupmenu/config.mk new file mode 100755 index 000000000..4c50d844c --- /dev/null +++ b/scalos/Plugins/Prefs/Popupmenu/config.mk @@ -0,0 +1,77 @@ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +DATATYPESMCC_DIR = $(TOPLEVEL)/common/DataTypesMCC +COMMON_DIR = $(TOPLEVEL)/common/Plugin + +INCLUDES += -I$(DATATYPESMCC_DIR) -I$(COMMON_DIR) + +SCALOS_LOCALE = $(OBJDIR)/PopupMenu_locale.h + +CFLAGS += -D SCALOSLOCALE=$(SCALOS_LOCALE) + +vpath %.c $(COMMON_DIR) + +############################################################################## + +include $(COMMON_DIR)/config.mk + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += -nostartfiles \ + -lmempools +# --verbose + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += -nostartfiles \ +# + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +DEFINES += -DMUI_OBSOLETE + +LFLAGS += -nostartfiles -lmui \ +# + +else + +############################################################################### +# AmigaOS + +LFLAGS += -lscalos \ + -lpreferences \ + -liconobject \ + -lmempools \ + -ldebug \ + -lmui \ + -lstack \ + -lnix \ + -lnixmain \ + -lamiga21 \ + -lamiga \ + -lstubs \ + +endif +endif +endif diff --git a/scalos/Plugins/Prefs/Popupmenu/images/Horizontal b/scalos/Plugins/Prefs/Popupmenu/images/Horizontal new file mode 100755 index 0000000000000000000000000000000000000000..9b732fb29f3107f043b81d396ed1acbf61b312ed GIT binary patch literal 2886 zcwWU;O>YuG7=Cv_SU+O1Hrj)+OHVcNfHzNeScnuOVj4YovW*6hJ=BDF0*wa_O-xAC ztcibMPu`0OM-TjkCZ3yAAuSPFV0>q1rrl*1Swb7Lf%kczkC`22XT$ycY7XGyz3f9H zXXIAW05At1VF@dQRizAY`^9#xuPmyRq)plATvA%1!s z+U3+~s#J~(i0%;ea-W%wEATpv7S(FHipT*#fN{}(5BqlaH6K<25P-{H)+=0=00iLj zyIb$MECC20!?6Gw1oHIG`6EGdEEa?NFxQjMW z)eDoTcNrN{B^XxM7#We^@&qdFAUE@&ENd6Kfw^hs9kZe-eygsyz{scZ%@NsBV0oWH zeE=N%bbuCs&RYF9``VWs2WKy;pwG0aQfI3;ffV0t0;1~xfb^NHwLu}=DIq$w13BDT z8PB1*Sq={X=6l@aWhjIsbL38k&>QdZ4PwsWp5m6-yly= zo^;id9&zWJTfbUg&6*?aW>{JNoN(Kepe{^-MTGUVvvr9vXs21+DS$l8DP zgu;m!`GfywNYdG?dySDqtd80|NjaMrUSl+Ig=sfP#@W2`F@C$sw3{UFY&Lw1&Ff5C sAkUpm$!ny|1=@i~h}KJZbcfnKyiUat_;!LXFz8PfcoTwd>z=s&0^M#1{Qv*} literal 0 HcwPel00001 diff --git a/scalos/Plugins/Prefs/Popupmenu/images/Horizontal Space b/scalos/Plugins/Prefs/Popupmenu/images/Horizontal Space new file mode 100755 index 0000000000000000000000000000000000000000..f7ffd6e4e84f1fc611b6b8c0cbad7bce7df8c7e4 GIT binary patch literal 3008 zcwWs_&ubGw6n-uF@4#HE2&_ae125{mK8KrQ(G9K++1sCDq`LWW3#I!eawRq_|!c#B`(H5u&_BT0MS7y_g z1`r>>|AD`zg3|nDx(DZ4jg6;_5QPBUXrkEAq=1NR1NEcC(rw@v-Ca1_JrYs~A`4In z-1qa3gH}$Ba{TMxrxd{(*Z5__(=19C9SGA#hyB+p|)n9dQ0bBcJFkZa=U6`>^|Ph*J1w5Ma=p^UA>`8z3M zQ%;30ArBTep4}^p;JVPKbHw4=ikv%e>q+tGq*J7wBM#Tz$${~s#oYV2^K_0lTw0NW zo?*!N zdJr=99lt2s3H+~Qo46#tk6tHw3-5v(4MU*d4Eps1cre5sVuI)UH$=h^`!F~^-!KH~ zis;u9;K49^EE3B8ibxn{pO4M2Hw=Ngo9NdQ;K7KR;eD4(7-6pl=UKxLs5^{)Jpmr% z*=v!o+9MP4jOzqRs7_ct0h#@rJs#eIPQHl%?PUj1dd-GF}+h6aP%^O1qwl+gs;)Dju@?@mX*^ G5&sE!G$;-L literal 0 HcwPel00001 diff --git a/scalos/Plugins/Prefs/Popupmenu/images/Horizontal Space.c b/scalos/Plugins/Prefs/Popupmenu/images/Horizontal Space.c new file mode 100755 index 000000000..f86619fbd --- /dev/null +++ b/scalos/Plugins/Prefs/Popupmenu/images/Horizontal Space.c @@ -0,0 +1,156 @@ +#ifdef USE_HORIZONTAL SPACE_COLORS +const ULONG Horizontal Space_colors[48] = +{ + 0x66666666,0x66666666,0x55555555, + 0xaaaaaaaa,0x99999999,0x99999999, + 0x77777777,0x77777777,0x66666666, + 0x00000000,0x66666666,0xffffffff, + 0x88888888,0x77777777,0x77777777, + 0x88888888,0x99999999,0xaaaaaaaa, + 0x99999999,0xaaaaaaaa,0xbbbbbbbb, + 0xffffffff,0xffffffff,0xffffffff, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0x99999999,0xaaaaaaaa,0xcccccccc, + 0xaaaaaaaa,0xaaaaaaaa,0xcccccccc, + 0xbbbbbbbb,0xcccccccc,0xdddddddd, + 0xffffffff,0xaaaaaaaa,0x99999999, + 0xcccccccc,0xcccccccc,0xdddddddd, + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, +}; +#endif + +#define HORIZONTAL SPACE_WIDTH 149 +#define HORIZONTAL SPACE_HEIGHT 40 +#define HORIZONTAL SPACE_DEPTH 4 +#define HORIZONTAL SPACE_COMPRESSION 1 +#define HORIZONTAL SPACE_MASKING 2 + +#ifdef USE_HORIZONTAL SPACE_HEADER +const struct BitMapHeader Horizontal Space_header = +{ 149,40,0,0,4,2,1,0,0,44,22,320,512 }; +#endif + +#ifdef USE_HORIZONTAL SPACE_BODY +const UBYTE Horizontal Space_body[1794] = { +0xed,0x00,0xed,0x00,0xed,0x00,0xed,0x00,0x01,0x00,0x3f,0xf3,0xff,0x00,0xc0, +0xfe,0x00,0x01,0x00,0x3f,0xf3,0xff,0x00,0xe0,0xfe,0x00,0x01,0x00,0x3f,0xf3, +0xff,0x00,0xe0,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xef, +0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00, +0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xef,0x00, +0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00, +0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xef,0x00,0x01, +0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20, +0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xef,0x00,0x01,0x00, +0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe, +0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xef,0x00,0x01,0x00,0x21, +0xf4,0xff,0x01,0xfc,0x20,0xfe,0x00,0x01,0x00,0x21,0xf4,0xff,0x01,0xfc,0x20, +0xfe,0x00,0x01,0x00,0x01,0xf4,0xff,0x01,0xfc,0x20,0xfe,0x00,0x01,0x00,0x20, +0xf4,0x00,0x00,0x04,0xfd,0x00,0x01,0x00,0x21,0xf4,0x00,0x01,0x04,0x20,0xfe, +0x00,0x01,0x00,0x21,0xf4,0x00,0x01,0x04,0x20,0xfe,0x00,0x01,0x00,0x01,0xf3, +0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x04,0xfd,0x00,0x01, +0x00,0x21,0xf6,0x00,0x03,0x02,0x00,0x04,0x20,0xfe,0x00,0x01,0x00,0x21,0xf6, +0x00,0x03,0x02,0x00,0x04,0x20,0xfe,0x00,0x01,0x00,0x01,0xf6,0x00,0x03,0x02, +0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x04,0xfd,0x00,0x01, +0x00,0x21,0xf6,0x00,0x03,0x03,0x00,0x04,0x20,0xfe,0x00,0x01,0x00,0x21,0xf6, +0x00,0x03,0x03,0x00,0x04,0x20,0xfe,0x00,0x01,0x00,0x01,0xf6,0x00,0x03,0x03, +0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x04,0xfd,0x00,0x05, +0x00,0x21,0x00,0x73,0x80,0x04,0xfe,0x00,0x00,0x18,0xfe,0x00,0x03,0x03,0x80, +0x04,0x20,0xfe,0x00,0x05,0x00,0x21,0x00,0x73,0x80,0x04,0xfe,0x00,0x00,0x18, +0xfe,0x00,0x03,0x03,0x80,0x04,0x20,0xfe,0x00,0x05,0x00,0x01,0x00,0x73,0x80, +0x04,0xfe,0x00,0x00,0x18,0xfe,0x00,0x03,0x03,0x80,0x00,0x20,0xfe,0x00,0x01, +0x00,0x20,0xf4,0x00,0x00,0x04,0xfd,0x00,0x03,0x00,0x21,0x00,0x21,0xfc,0x00, +0x00,0x08,0xfe,0x00,0x03,0x03,0xc0,0x04,0x20,0xfe,0x00,0x03,0x00,0x21,0x00, +0x21,0xfc,0x00,0x00,0x08,0xfe,0x00,0x03,0x03,0xc0,0x04,0x20,0xfe,0x00,0x03, +0x00,0x01,0x00,0x21,0xfc,0x00,0x00,0x08,0xfe,0x00,0x03,0x03,0xc0,0x00,0x20, +0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x04,0xfd,0x00,0x03,0x00,0x21,0x00, +0x21,0xfd,0x00,0x01,0x20,0x08,0xfe,0x00,0x03,0x03,0xe0,0x04,0x20,0xfe,0x00, +0x03,0x00,0x21,0x00,0x21,0xfd,0x00,0x01,0x20,0x08,0xfe,0x00,0x03,0x03,0xe0, +0x04,0x20,0xfe,0x00,0x03,0x00,0x01,0x00,0x21,0xfd,0x00,0x01,0x20,0x08,0xfe, +0x00,0x03,0x03,0xe0,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x04, +0xfd,0x00,0x09,0x00,0x21,0x00,0x21,0x0c,0xbc,0xf1,0x96,0x79,0x88,0xfe,0x00, +0x03,0x03,0xf0,0x04,0x20,0xfe,0x00,0x09,0x00,0x21,0x00,0x21,0x0c,0xbc,0xf1, +0x96,0x79,0x88,0xfe,0x00,0x03,0x03,0xf0,0x04,0x20,0xfe,0x00,0x09,0x00,0x01, +0x00,0x21,0x0c,0xbc,0xf1,0x96,0x79,0x88,0xfe,0x00,0x03,0x03,0xf0,0x00,0x20, +0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x04,0xfd,0x00,0x09,0x00,0x21,0x00, +0x3f,0x12,0x64,0x92,0x49,0x22,0x48,0xfe,0x00,0x03,0x03,0xf0,0x04,0x20,0xfe, +0x00,0x09,0x00,0x21,0x00,0x3f,0x12,0x64,0x92,0x49,0x22,0x48,0xfe,0x00,0x03, +0x03,0xf0,0x04,0x20,0xfe,0x00,0x09,0x00,0x01,0x00,0x3f,0x12,0x64,0x92,0x49, +0x22,0x48,0xfe,0x00,0x03,0x03,0xf0,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4, +0x00,0x00,0x04,0xfd,0x00,0x09,0x00,0x21,0x00,0x21,0x12,0x44,0x22,0x49,0x21, +0xc8,0xfe,0x00,0x03,0x03,0xe0,0x04,0x20,0xfe,0x00,0x09,0x00,0x21,0x00,0x21, +0x12,0x44,0x22,0x49,0x21,0xc8,0xfe,0x00,0x03,0x03,0xe0,0x04,0x20,0xfe,0x00, +0x09,0x00,0x01,0x00,0x21,0x12,0x44,0x22,0x49,0x21,0xc8,0xfe,0x00,0x03,0x03, +0xe0,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x04,0xfd,0x00,0x09, +0x00,0x21,0x00,0x21,0x12,0x44,0x42,0x49,0x22,0x48,0xfe,0x00,0x03,0x03,0xc0, +0x04,0x20,0xfe,0x00,0x09,0x00,0x21,0x00,0x21,0x12,0x44,0x42,0x49,0x22,0x48, +0xfe,0x00,0x03,0x03,0xc0,0x04,0x20,0xfe,0x00,0x09,0x00,0x01,0x00,0x21,0x12, +0x44,0x42,0x49,0x22,0x48,0xfe,0x00,0x03,0x03,0xc0,0x00,0x20,0xfe,0x00,0x01, +0x00,0x20,0xf4,0x00,0x00,0x04,0xfd,0x00,0x09,0x00,0x21,0x00,0x21,0x12,0x44, +0x92,0x49,0x22,0x48,0xfe,0x00,0x03,0x03,0x80,0x04,0x20,0xfe,0x00,0x09,0x00, +0x21,0x00,0x21,0x12,0x44,0x92,0x49,0x22,0x48,0xfe,0x00,0x03,0x03,0x80,0x04, +0x20,0xfe,0x00,0x09,0x00,0x01,0x00,0x21,0x12,0x44,0x92,0x49,0x22,0x48,0xfe, +0x00,0x03,0x03,0x80,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x04, +0xfd,0x00,0x09,0x00,0x21,0x00,0x73,0x8c,0xee,0xf1,0x9d,0x99,0xbc,0xfe,0x00, +0x03,0x03,0x00,0x04,0x20,0xfe,0x00,0x09,0x00,0x21,0x00,0x73,0x8c,0xee,0xf1, +0x9d,0x99,0xbc,0xfe,0x00,0x03,0x03,0x00,0x04,0x20,0xfe,0x00,0x09,0x00,0x01, +0x00,0x73,0x8c,0xee,0xf1,0x9d,0x99,0xbc,0xfe,0x00,0x03,0x03,0x00,0x00,0x20, +0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x04,0xfd,0x00,0x01,0x00,0x21,0xf6, +0x00,0x03,0x02,0x00,0x04,0x20,0xfe,0x00,0x01,0x00,0x21,0xf6,0x00,0x03,0x02, +0x00,0x04,0x20,0xfe,0x00,0x01,0x00,0x01,0xf6,0x00,0x03,0x02,0x00,0x00,0x20, +0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x04,0xfd,0x00,0x01,0x00,0x21,0xf4, +0x00,0x01,0x04,0x20,0xfe,0x00,0x01,0x00,0x21,0xf4,0x00,0x01,0x04,0x20,0xfe, +0x00,0x01,0x00,0x01,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0xff, +0x00,0xfc,0xfd,0x00,0x01,0x00,0x21,0xf4,0xff,0x01,0xfc,0x20,0xfe,0x00,0x01, +0x00,0x21,0xf4,0xff,0x01,0xfc,0x20,0xfe,0x00,0x01,0x00,0x01,0xf3,0x00,0x00, +0x20,0xfe,0x00,0x01,0x00,0x20,0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20, +0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20, +0xfe,0x00,0x03,0x00,0x20,0x80,0x80,0xf7,0x00,0xff,0x08,0xfd,0x00,0x03,0x00, +0x20,0x80,0x80,0xf7,0x00,0xff,0x08,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3, +0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x03,0x00,0x20,0x80, +0x80,0xf7,0x00,0xff,0x08,0xfd,0x00,0x03,0x00,0x20,0x80,0x80,0xf7,0x00,0xff, +0x08,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1, +0x00,0x00,0x20,0xfe,0x00,0x03,0x00,0x20,0x80,0x80,0xf7,0x00,0xff,0x08,0xfd, +0x00,0x03,0x00,0x20,0x80,0x80,0xf7,0x00,0xff,0x08,0x00,0x20,0xfe,0x00,0x01, +0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x03, +0x00,0x20,0x80,0x80,0xf7,0x00,0xff,0x08,0xfd,0x00,0x03,0x00,0x20,0x80,0x80, +0xf7,0x00,0xff,0x08,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20, +0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x03,0x00,0x20,0x80,0x80,0xf8,0x00, +0x03,0x02,0x08,0x08,0x20,0xfe,0x00,0x06,0x00,0x20,0x80,0xbb,0xc3,0x0c,0x60, +0xfb,0x00,0x03,0x02,0x08,0x08,0x20,0xfe,0x00,0xfe,0x00,0x03,0x3b,0xc3,0x0c, +0x60,0xf4,0x00,0xfe,0x00,0x03,0x3b,0xc3,0x0c,0x60,0xf4,0x00,0x03,0x00,0x30, +0x80,0x86,0xf8,0x00,0x03,0x03,0x08,0x08,0x60,0xfe,0x00,0x06,0x00,0x30,0x80, +0xcf,0x24,0x90,0x90,0xfb,0x00,0x03,0x03,0x08,0x08,0x60,0xfe,0x00,0xfe,0x00, +0x03,0x49,0x24,0x90,0x90,0xf4,0x00,0xfe,0x00,0x03,0x49,0x24,0x90,0x90,0xf4, +0x00,0x03,0x00,0x38,0x80,0x8e,0xf8,0x00,0x03,0x03,0x88,0x08,0xe0,0xfe,0x00, +0x06,0x00,0x38,0x80,0xef,0x23,0x90,0xf0,0xfb,0x00,0x03,0x03,0x88,0x08,0xe0, +0xfe,0x00,0xfe,0x00,0x03,0x61,0x23,0x90,0xf0,0xf4,0x00,0xfe,0x00,0x03,0x61, +0x23,0x90,0xf0,0xf4,0x00,0x03,0x00,0x3c,0x80,0x86,0xf8,0x00,0x03,0x03,0xc8, +0x09,0xe0,0xfe,0x00,0x06,0x00,0x3c,0x80,0x9f,0x24,0x90,0x80,0xfb,0x00,0x03, +0x03,0xc8,0x09,0xe0,0xfe,0x00,0xfe,0x00,0x03,0x19,0x24,0x90,0x80,0xf4,0x00, +0xfe,0x00,0x03,0x19,0x24,0x90,0x80,0xf4,0x00,0x03,0x00,0x3e,0x80,0xb6,0xf8, +0x00,0x03,0x03,0xe8,0x0b,0xe0,0xfe,0x00,0x06,0x00,0x3e,0x80,0xff,0x24,0x90, +0x80,0xfb,0x00,0x03,0x03,0xe8,0x0b,0xe0,0xfe,0x00,0xfe,0x00,0x03,0x49,0x24, +0x90,0x80,0xf4,0x00,0xfe,0x00,0x03,0x49,0x24,0x90,0x80,0xf4,0x00,0x04,0x0f, +0xff,0x80,0x8e,0x38,0xf9,0x00,0x06,0xff,0xf8,0x0f,0xff,0x80,0x00,0x00,0x06, +0x0f,0xff,0x80,0xff,0xfb,0x4c,0x70,0xfb,0x00,0x06,0xff,0xf8,0x0f,0xff,0x80, +0x00,0x00,0xfe,0x00,0x03,0x71,0xc3,0x4c,0x70,0xf4,0x00,0xfe,0x00,0x03,0x71, +0xc3,0x4c,0x70,0xf4,0x00,0x04,0x0f,0xff,0x80,0xfe,0xf8,0xf9,0x00,0x06,0xff, +0xf8,0x0f,0xff,0x80,0x00,0x00,0x04,0x0f,0xff,0x80,0xff,0xf8,0xf9,0x00,0x06, +0xff,0xf8,0x0f,0xff,0x80,0x00,0x00,0xfe,0x00,0x00,0x01,0xf1,0x00,0xfe,0x00, +0x00,0x01,0xf1,0x00,0x04,0x0f,0xff,0x80,0xfe,0xf8,0xf9,0x00,0x06,0xff,0xf8, +0x0f,0xff,0x80,0x00,0x00,0x04,0x0f,0xff,0x80,0xff,0xf8,0xf9,0x00,0x06,0xff, +0xf8,0x0f,0xff,0x80,0x00,0x00,0xfe,0x00,0x00,0x01,0xf1,0x00,0xfe,0x00,0x00, +0x01,0xf1,0x00,0x03,0x00,0x3e,0x80,0xbc,0xf8,0x00,0x03,0x03,0xe8,0x0b,0xe0, +0xfe,0x00,0x04,0x00,0x3e,0x80,0xbf,0x80,0xf9,0x00,0x03,0x03,0xe8,0x0b,0xe0, +0xfe,0x00,0xfe,0x00,0x01,0x03,0x80,0xf2,0x00,0xfe,0x00,0x01,0x03,0x80,0xf2, +0x00,0x03,0x00,0x3c,0x80,0x9e,0xf8,0x00,0x03,0x03,0xc8,0x09,0xe0,0xfe,0x00, +0x03,0x00,0x3c,0x80,0x9e,0xf8,0x00,0x03,0x03,0xc8,0x09,0xe0,0xfe,0x00,0xed, +0x00,0xed,0x00,0x03,0x00,0x38,0x80,0x8e,0xf8,0x00,0x03,0x03,0x88,0x08,0xe0, +0xfe,0x00,0x03,0x00,0x38,0x80,0x8e,0xf8,0x00,0x03,0x03,0x88,0x08,0xe0,0xfe, +0x00,0xed,0x00,0xed,0x00,0x03,0x00,0x30,0x80,0x86,0xf8,0x00,0x03,0x03,0x08, +0x08,0x60,0xfe,0x00,0x03,0x00,0x30,0x80,0x86,0xf8,0x00,0x03,0x03,0x08,0x08, +0x60,0xfe,0x00,0xed,0x00,0xed,0x00,0x03,0x00,0x20,0x80,0x82,0xf8,0x00,0x03, +0x02,0x08,0x08,0x20,0xfe,0x00,0x03,0x00,0x20,0x80,0x82,0xf8,0x00,0x03,0x02, +0x08,0x08,0x20,0xfe,0x00,0xed,0x00,0xed,0x00, }; +#endif diff --git a/scalos/Plugins/Prefs/Popupmenu/images/Horizontal.c b/scalos/Plugins/Prefs/Popupmenu/images/Horizontal.c new file mode 100755 index 000000000..1c3b85cad --- /dev/null +++ b/scalos/Plugins/Prefs/Popupmenu/images/Horizontal.c @@ -0,0 +1,148 @@ +#ifdef USE_HORIZONTAL_COLORS +const ULONG Horizontal_colors[48] = +{ + 0x66666666,0x66666666,0x55555555, + 0xaaaaaaaa,0x99999999,0x99999999, + 0x77777777,0x77777777,0x66666666, + 0x00000000,0x66666666,0xffffffff, + 0x88888888,0x77777777,0x77777777, + 0x88888888,0x99999999,0xaaaaaaaa, + 0x99999999,0xaaaaaaaa,0xbbbbbbbb, + 0xffffffff,0xffffffff,0xffffffff, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0x99999999,0xaaaaaaaa,0xcccccccc, + 0xaaaaaaaa,0xaaaaaaaa,0xcccccccc, + 0xbbbbbbbb,0xcccccccc,0xdddddddd, + 0xffffffff,0xaaaaaaaa,0x99999999, + 0xcccccccc,0xcccccccc,0xdddddddd, + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, +}; +#endif + +#define HORIZONTAL_WIDTH 149 +#define HORIZONTAL_HEIGHT 40 +#define HORIZONTAL_DEPTH 4 +#define HORIZONTAL_COMPRESSION 1 +#define HORIZONTAL_MASKING 2 + +#ifdef USE_HORIZONTAL_HEADER +const struct BitMapHeader Horizontal_header = +{ 149,40,0,0,4,2,1,0,0,44,22,320,512 }; +#endif + +#ifdef USE_HORIZONTAL_BODY +const UBYTE Horizontal_body[1676] = { +0x01,0x00,0x3f,0xf3,0xff,0x00,0xc0,0xfe,0x00,0x01,0x00,0x3f,0xf3,0xff,0x00, +0xe0,0xfe,0x00,0x01,0x00,0x3f,0xf3,0xff,0x00,0xe0,0xfe,0x00,0xf1,0x00,0x00, +0x20,0xfe,0x00,0x01,0x00,0x20,0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20, +0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20, +0xfe,0x00,0x01,0x00,0x20,0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe, +0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe, +0x00,0x01,0x00,0x20,0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00, +0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00, +0x01,0x00,0x20,0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01, +0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01, +0x00,0x20,0xef,0x00,0x02,0x00,0x20,0x0f,0xf5,0xff,0x01,0xc0,0x20,0xfe,0x00, +0x02,0x00,0x20,0x0f,0xf5,0xff,0x01,0xc0,0x20,0xfe,0x00,0xff,0x00,0x00,0x0f, +0xf5,0xff,0x01,0xc0,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x40,0xfd, +0x00,0x02,0x00,0x20,0x08,0xf5,0x00,0x01,0x40,0x20,0xfe,0x00,0x02,0x00,0x20, +0x08,0xf5,0x00,0x01,0x40,0x20,0xfe,0x00,0xff,0x00,0x00,0x08,0xf4,0x00,0x00, +0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x40,0xfd,0x00,0x02,0x00,0x20, +0x08,0xf5,0x00,0x01,0x40,0x20,0xfe,0x00,0x02,0x00,0x20,0x08,0xf5,0x00,0x01, +0x40,0x20,0xfe,0x00,0xff,0x00,0x00,0x08,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01, +0x00,0x20,0xf4,0x00,0x00,0x40,0xfd,0x00,0x02,0x00,0x20,0x08,0xf5,0x00,0x01, +0x40,0x20,0xfe,0x00,0x02,0x00,0x20,0x08,0xf5,0x00,0x01,0x40,0x20,0xfe,0x00, +0xff,0x00,0x00,0x08,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00, +0x00,0x40,0xfd,0x00,0x05,0x00,0x20,0x08,0x73,0x80,0x04,0xfe,0x00,0x00,0x18, +0xfc,0x00,0x01,0x40,0x20,0xfe,0x00,0x05,0x00,0x20,0x08,0x73,0x80,0x04,0xfe, +0x00,0x00,0x18,0xfc,0x00,0x01,0x40,0x20,0xfe,0x00,0xff,0x00,0x03,0x08,0x73, +0x80,0x04,0xfe,0x00,0x00,0x18,0xfb,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20, +0xf4,0x00,0x00,0x40,0xfd,0x00,0x03,0x00,0x20,0x08,0x21,0xfc,0x00,0x00,0x08, +0xfc,0x00,0x01,0x40,0x20,0xfe,0x00,0x03,0x00,0x20,0x08,0x21,0xfc,0x00,0x00, +0x08,0xfc,0x00,0x01,0x40,0x20,0xfe,0x00,0xff,0x00,0x01,0x08,0x21,0xfc,0x00, +0x00,0x08,0xfb,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x40, +0xfd,0x00,0x03,0x00,0x20,0x08,0x21,0xfd,0x00,0x01,0x20,0x08,0xfc,0x00,0x01, +0x40,0x20,0xfe,0x00,0x03,0x00,0x20,0x08,0x21,0xfd,0x00,0x01,0x20,0x08,0xfc, +0x00,0x01,0x40,0x20,0xfe,0x00,0xff,0x00,0x01,0x08,0x21,0xfd,0x00,0x01,0x20, +0x08,0xfb,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x40,0xfd, +0x00,0x09,0x00,0x20,0x08,0x21,0x0c,0xbc,0xf1,0x96,0x79,0x88,0xfc,0x00,0x01, +0x40,0x20,0xfe,0x00,0x09,0x00,0x20,0x08,0x21,0x0c,0xbc,0xf1,0x96,0x79,0x88, +0xfc,0x00,0x01,0x40,0x20,0xfe,0x00,0xff,0x00,0x07,0x08,0x21,0x0c,0xbc,0xf1, +0x96,0x79,0x88,0xfb,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00, +0x40,0xfd,0x00,0x09,0x00,0x20,0x08,0x3f,0x12,0x64,0x92,0x49,0x22,0x48,0xfc, +0x00,0x01,0x40,0x20,0xfe,0x00,0x09,0x00,0x20,0x08,0x3f,0x12,0x64,0x92,0x49, +0x22,0x48,0xfc,0x00,0x01,0x40,0x20,0xfe,0x00,0xff,0x00,0x07,0x08,0x3f,0x12, +0x64,0x92,0x49,0x22,0x48,0xfb,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4, +0x00,0x00,0x40,0xfd,0x00,0x09,0x00,0x20,0x08,0x21,0x12,0x44,0x22,0x49,0x21, +0xc8,0xfc,0x00,0x01,0x40,0x20,0xfe,0x00,0x09,0x00,0x20,0x08,0x21,0x12,0x44, +0x22,0x49,0x21,0xc8,0xfc,0x00,0x01,0x40,0x20,0xfe,0x00,0xff,0x00,0x07,0x08, +0x21,0x12,0x44,0x22,0x49,0x21,0xc8,0xfb,0x00,0x00,0x20,0xfe,0x00,0x01,0x00, +0x20,0xf4,0x00,0x00,0x40,0xfd,0x00,0x09,0x00,0x20,0x08,0x21,0x12,0x44,0x42, +0x49,0x22,0x48,0xfc,0x00,0x01,0x40,0x20,0xfe,0x00,0x09,0x00,0x20,0x08,0x21, +0x12,0x44,0x42,0x49,0x22,0x48,0xfc,0x00,0x01,0x40,0x20,0xfe,0x00,0xff,0x00, +0x07,0x08,0x21,0x12,0x44,0x42,0x49,0x22,0x48,0xfb,0x00,0x00,0x20,0xfe,0x00, +0x01,0x00,0x20,0xf4,0x00,0x00,0x40,0xfd,0x00,0x09,0x00,0x20,0x08,0x21,0x12, +0x44,0x92,0x49,0x22,0x48,0xfc,0x00,0x01,0x40,0x20,0xfe,0x00,0x09,0x00,0x20, +0x08,0x21,0x12,0x44,0x92,0x49,0x22,0x48,0xfc,0x00,0x01,0x40,0x20,0xfe,0x00, +0xff,0x00,0x07,0x08,0x21,0x12,0x44,0x92,0x49,0x22,0x48,0xfb,0x00,0x00,0x20, +0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x40,0xfd,0x00,0x09,0x00,0x20,0x08, +0x73,0x8c,0xee,0xf1,0x9d,0x99,0xbc,0xfc,0x00,0x01,0x40,0x20,0xfe,0x00,0x09, +0x00,0x20,0x08,0x73,0x8c,0xee,0xf1,0x9d,0x99,0xbc,0xfc,0x00,0x01,0x40,0x20, +0xfe,0x00,0xff,0x00,0x07,0x08,0x73,0x8c,0xee,0xf1,0x9d,0x99,0xbc,0xfb,0x00, +0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x40,0xfd,0x00,0x02,0x00, +0x20,0x08,0xf5,0x00,0x01,0x40,0x20,0xfe,0x00,0x02,0x00,0x20,0x08,0xf5,0x00, +0x01,0x40,0x20,0xfe,0x00,0xff,0x00,0x00,0x08,0xf4,0x00,0x00,0x20,0xfe,0x00, +0x01,0x00,0x20,0xf4,0x00,0x00,0x40,0xfd,0x00,0x02,0x00,0x20,0x08,0xf5,0x00, +0x01,0x40,0x20,0xfe,0x00,0x02,0x00,0x20,0x08,0xf5,0x00,0x01,0x40,0x20,0xfe, +0x00,0xff,0x00,0x00,0x08,0xf4,0x00,0x00,0x20,0xfe,0x00,0x02,0x00,0x20,0x07, +0xf5,0xff,0x00,0xc0,0xfd,0x00,0x02,0x00,0x20,0x0f,0xf5,0xff,0x01,0xc0,0x20, +0xfe,0x00,0x02,0x00,0x20,0x0f,0xf5,0xff,0x01,0xc0,0x20,0xfe,0x00,0xff,0x00, +0x00,0x08,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xef,0x00,0x01,0x00, +0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe, +0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x02,0x00,0x30,0x10,0xf5,0x00,0xff,0x40, +0xfe,0x00,0x02,0x00,0x30,0x10,0xf5,0x00,0x01,0x40,0x60,0xfe,0x00,0x01,0x00, +0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x02,0x00, +0x30,0x10,0xf5,0x00,0xff,0x40,0xfe,0x00,0x02,0x00,0x30,0x10,0xf5,0x00,0x01, +0x40,0x60,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00, +0x00,0x20,0xfe,0x00,0x02,0x00,0x30,0x10,0xf5,0x00,0xff,0x40,0xfe,0x00,0x02, +0x00,0x30,0x10,0xf5,0x00,0x01,0x40,0x60,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00, +0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x02,0x00,0x30,0x10,0xf5, +0x00,0xff,0x40,0xfe,0x00,0x02,0x00,0x30,0x10,0xf5,0x00,0x01,0x40,0x60,0xfe, +0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe, +0x00,0x03,0x04,0x30,0x10,0x40,0xf7,0x00,0x02,0x10,0x40,0x41,0xfe,0x00,0x03, +0x04,0x30,0x10,0x40,0xf7,0x00,0x02,0x10,0x40,0x61,0xfe,0x00,0x01,0x00,0x20, +0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x03,0x06,0x30, +0x10,0xc0,0xf7,0x00,0x02,0x18,0x40,0x43,0xfe,0x00,0x03,0x06,0x30,0x10,0xc0, +0xf7,0x00,0x02,0x18,0x40,0x63,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20, +0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x03,0x07,0x30,0x11,0xc0,0xf7,0x00, +0x02,0x1c,0x40,0x47,0xfe,0x00,0x03,0x07,0x30,0x11,0xc0,0xf7,0x00,0x02,0x1c, +0x40,0x67,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00, +0x00,0x20,0xfe,0x00,0x03,0x07,0xb0,0x13,0xc0,0xf7,0x00,0x02,0x1e,0x40,0x4f, +0xfe,0x00,0x03,0x07,0xb0,0x13,0xc0,0xf7,0x00,0x02,0x1e,0x40,0x6f,0xfe,0x00, +0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00, +0x03,0x07,0xf0,0x17,0xc0,0xf7,0x00,0x02,0x1f,0x40,0x5f,0xfe,0x00,0x03,0x07, +0xf0,0x17,0xc0,0xf7,0x00,0x02,0x1f,0x40,0x7f,0xfe,0x00,0x01,0x00,0x20,0xf3, +0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x03,0xff,0xf0,0x1f, +0xff,0xf8,0x00,0x06,0x03,0xff,0xc0,0x7f,0xfc,0x00,0x00,0x03,0xff,0xf0,0x1f, +0xff,0xf8,0x00,0x06,0x03,0xff,0xc0,0x7f,0xfc,0x00,0x00,0xed,0x00,0xed,0x00, +0x03,0xff,0xf0,0x1f,0xff,0xf8,0x00,0x06,0x03,0xff,0xc0,0x7f,0xfc,0x00,0x00, +0x03,0xff,0xf0,0x1f,0xff,0xf8,0x00,0x06,0x03,0xff,0xc0,0x7f,0xfc,0x00,0x00, +0xed,0x00,0xed,0x00,0x03,0xff,0xf0,0x1f,0xff,0xf8,0x00,0x06,0x03,0xff,0xc0, +0x7f,0xfc,0x00,0x00,0x03,0xff,0xf0,0x1f,0xff,0xf8,0x00,0x06,0x03,0xff,0xc0, +0x7f,0xfc,0x00,0x00,0xed,0x00,0xed,0x00,0x03,0x07,0xf0,0x17,0xc0,0xf7,0x00, +0x02,0x1f,0x40,0x5f,0xfe,0x00,0x03,0x07,0xf0,0x17,0xc0,0xf7,0x00,0x02,0x1f, +0x40,0x7f,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00, +0x00,0x20,0xfe,0x00,0x03,0x07,0xb0,0x13,0xc0,0xf7,0x00,0x02,0x1e,0x40,0x4f, +0xfe,0x00,0x03,0x07,0xb0,0x13,0xc0,0xf7,0x00,0x02,0x1e,0x40,0x6f,0xfe,0x00, +0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00, +0x03,0x07,0x30,0x11,0xc0,0xf7,0x00,0x02,0x1c,0x40,0x47,0xfe,0x00,0x03,0x07, +0x30,0x11,0xc0,0xf7,0x00,0x02,0x1c,0x40,0x67,0xfe,0x00,0x01,0x00,0x20,0xf3, +0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x03,0x06,0x30,0x10, +0xc0,0xf7,0x00,0x02,0x18,0x40,0x43,0xfe,0x00,0x03,0x06,0x30,0x10,0xc0,0xf7, +0x00,0x02,0x18,0x40,0x63,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe, +0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x03,0x04,0x30,0x10,0x40,0xf7,0x00,0x02, +0x10,0x40,0x41,0xfe,0x00,0x03,0x04,0x30,0x10,0x40,0xf7,0x00,0x02,0x10,0x40, +0x61,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00, +0x20,0xfe,0x00,0xed,0x00,0xed,0x00,0xed,0x00,0xed,0x00, }; +#endif diff --git a/scalos/Plugins/Prefs/Popupmenu/images/Intermediate Spacing b/scalos/Plugins/Prefs/Popupmenu/images/Intermediate Spacing new file mode 100755 index 0000000000000000000000000000000000000000..ec7f3fd97df70fcf4f6de22c69fe112a2bfdfe1c GIT binary patch literal 3170 zcwW_3Plyv&9R6l9Zk{2|zAjQy2qlLgd+4E94=IRbvx_>dsYUFeJ*^)0(t|m5Z<1P& z97NWj(13XI6tFEl^dgi6F9m}XdKNeHpAZ@Qh%^70av z!q)O~tJCdtZ-!ym?Gos9yS)oYk;*Xq|tEnh_fxYu{^&=X)(mNS^^)10V zs+fI-=mqhd{x;wUQ(mZxBV1M8(YA#NL5eoxafPuf&0~!#yjaT$Pe8pA00z7apS^kZ z=FNSSnA1%tSQCks6}hQj#i9~-MIZ|ifk@vy199qSqIXLM4g>bLQCd{ASYZGLtp5(o zttkCB24KMYzmSpMX8;DQpWbuhmszDRG5`bKTa7nU<;_*?jql*8y{keld4RUyik!Eh z9-rsj`b)h%fCghkge!cl`<`1UM7jo~>q>fF>v>lgU9hfdMjV=Mj)*@r{bND$4HQr} zP}LeZSAe+#_zp-7{4{?*8ptR>1G*+l0HoU8h>oVfhQ222f2C+Pk5!?>F)|8_qB8MK zdy^x(1G;v6fxcC;7akybIVe3+m;Zs%H~~-ebqXcg8JdF_4c}sn+7Z+ggVzt~sD_#H zboW%_QH=EBwbXx_jP>KOzBQ)uoK^IR-am?$oo46}r3sxU|I?$H6?JYQ6LY3%Gh|K^ z#+;>^m8eQuiFC$V(;U(qIW|)!LQ?f5zC3vQkHQb1^|Yorq`5KnY^JP;Mp0tn(!QYF z4rWY5qlh#Y!r#JK8I_94xECC3fBvz_s8o>VLWGqNxfEw*6dNkT3rg)knv7xtX^z&h zg|jmJzRI{9>~9AjnGC;=G)Ea*I4dK&D)F%Q@WItH2kw}R>?+b6Wo+S02GvYcMjx__ z!fR}C3``vjCpj7}bpsv-qir6e_iJoJ^E|p9H)}CcgPz2>L5wCQPf45~#AxCeowbVt zeLNHb{KvPxpEkqve@fC1?M7QyaE+~mfSI6ty=_^OerPw^`ZxY$D~D!wbidu`UNSu~o1vBaT$ literal 0 HcwPel00001 diff --git a/scalos/Plugins/Prefs/Popupmenu/images/NewStyle.c b/scalos/Plugins/Prefs/Popupmenu/images/NewStyle.c new file mode 100755 index 000000000..ccb5015d2 --- /dev/null +++ b/scalos/Plugins/Prefs/Popupmenu/images/NewStyle.c @@ -0,0 +1,41 @@ +#ifdef USE_NEWSTYLE_COLORS +const ULONG NewStyle_colors[48] = +{ + 0xffffffff,0x66666666,0x00000000, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0xeeeeeeee,0xeeeeeeee,0xeeeeeeee, + 0xbbbbbbbb,0x00000000,0x00000000, + 0x88888888,0x00000000,0x88888888, + 0xffffffff,0x44444444,0xaaaaaaaa, + 0xeeeeeeee,0x00000000,0x00000000, + 0x66666666,0x22222222,0x00000000, + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xaaaaaaaa,0x88888888, + 0xffffffff,0xeeeeeeee,0x00000000, + 0x00000000,0x88888888,0x00000000, + 0x00000000,0xdddddddd,0x00000000, + 0x00000000,0xcccccccc,0xcccccccc, + 0x00000000,0x66666666,0xffffffff, + 0x00000000,0x00000000,0xaaaaaaaa, +}; +#endif + +#define NEWSTYLE_WIDTH 127 +#define NEWSTYLE_HEIGHT 7 +#define NEWSTYLE_DEPTH 4 +#define NEWSTYLE_COMPRESSION 1 +#define NEWSTYLE_MASKING 2 + +#ifdef USE_NEWSTYLE_HEADER +const struct BitMapHeader NewStyle_header = +{ 127,7,0,0,4,2,1,0,0,44,22,320,512 }; +#endif + +#ifdef USE_NEWSTYLE_BODY +const UBYTE NewStyle_body[68] = { +0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1, +0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0x00,0x3f,0xf3,0xff,0x00,0xf8,0xf1,0x00, +0x00,0x1f,0xf3,0xff,0x00,0xfc,0xf1,0x00,0x00,0x60,0xf2,0x00,0xf1,0x00,0xf1, +0x00,0xf1,0x00,0x00,0x40,0xf2,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00, +0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00, }; +#endif diff --git a/scalos/Plugins/Prefs/Popupmenu/images/OldStyle.brush b/scalos/Plugins/Prefs/Popupmenu/images/OldStyle.brush new file mode 100755 index 0000000000000000000000000000000000000000..f8e2b5c3f6bd7a066b991afadb7824eeca9c3c67 GIT binary patch literal 544 zcwWVju@1pd7)DP^Vl{}EO(F(QKzlW+iHkH0B-TEG#K_pk=zL$nEA$a~g_~f~9Gj7J7kSk;5lND0txpgW8&7G7 z+Qr497ic<`!j9lrz+^$!b!E6oI28YgrUqClg-&(d}`I-G6G57Kh TGq_R)+xvy{+i!bz<*O@CB*B%Q4~B> z5bOhp)VzR>vztw!sWk~rHvGH!W@jfe+1+b*d|zc?i< z$!{9R%JoU#Kg+nu>I$6Z_~QSY#%1G?)PDK;DVz-dC%zP(k{_?#kh2hjIQPuT&U>&r zu=+TT^xmqv(W-3C`6rrp?S4NOp5R_NlP`S2QFpIrI6+yRzud~%URLh7JvYy;H?=xp QRn+=%5slw2BaQ8T0n#|$7ytkO literal 0 HcwPel00001 diff --git a/scalos/Plugins/Prefs/Popupmenu/images/PopupMenu.c b/scalos/Plugins/Prefs/Popupmenu/images/PopupMenu.c new file mode 100755 index 000000000..9b809ca73 --- /dev/null +++ b/scalos/Plugins/Prefs/Popupmenu/images/PopupMenu.c @@ -0,0 +1,48 @@ +#ifdef USE_POPUPMENU_COLORS +const ULONG PopupMenu_colors[48] = +{ + 0x00000000,0x00000000,0x00000000, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0x55555555,0x55555555,0x55555555, + 0xffffffff,0xffffffff,0xffffffff, + 0x88888888,0x00000000,0x88888888, + 0xffffffff,0x44444444,0xaaaaaaaa, + 0xeeeeeeee,0x00000000,0x00000000, + 0x66666666,0x22222222,0x00000000, + 0xffffffff,0x66666666,0x00000000, + 0xffffffff,0xaaaaaaaa,0x88888888, + 0xffffffff,0xeeeeeeee,0x00000000, + 0x00000000,0x88888888,0x00000000, + 0x00000000,0xdddddddd,0x00000000, + 0x00000000,0xcccccccc,0xcccccccc, + 0x00000000,0x66666666,0xffffffff, + 0x00000000,0x00000000,0xaaaaaaaa, +}; +#endif + +#define POPUPMENU_WIDTH 16 +#define POPUPMENU_HEIGHT 21 +#define POPUPMENU_DEPTH 4 +#define POPUPMENU_COMPRESSION 0 +#define POPUPMENU_MASKING 2 + +#ifdef USE_POPUPMENU_HEADER +const struct BitMapHeader PopupMenu_header = +{ 16,21,0,0,4,2,0,0,15,44,44,320,256 }; +#endif + +#ifdef USE_POPUPMENU_BODY +const UBYTE PopupMenu_body[168] = { +0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0x00,0x00,0x00,0x00, +0x00,0xff,0xff,0xb0,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa8,0x00,0x00,0x00, +0x00,0x00,0xff,0xff,0xb6,0xd6,0x00,0x00,0x00,0x00,0xff,0xff,0xa6,0xd6,0x00, +0x00,0x00,0x00,0xff,0xff,0x80,0x84,0x00,0x00,0x00,0x00,0x80,0x00,0xff,0xff, +0x00,0x00,0x00,0x00,0xff,0xfe,0x80,0x00,0x00,0x00,0x00,0x00,0x82,0x30,0xfd, +0xcf,0x01,0xce,0x00,0x30,0x81,0x10,0xde,0xef,0x00,0xec,0x00,0x10,0x80,0xa4, +0xd7,0x5b,0x00,0x58,0x00,0x20,0x80,0x68,0xd2,0x97,0x00,0x10,0x00,0x20,0x80, +0x30,0xd6,0x4f,0x00,0x00,0x00,0x00,0x80,0x00,0xff,0xff,0x00,0x00,0x00,0x00, +0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0xee,0xff,0x80,0x00,0x00,0x00,0x00, +0x00,0xde,0xff,0x80,0x02,0x00,0x00,0x00,0x00,0xea,0x7d,0x80,0x00,0x00,0x00, +0x00,0x00,0xda,0x7f,0x80,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0x00,0x00, +0x00,0x00,0x00, }; +#endif diff --git a/scalos/Plugins/Prefs/Popupmenu/images/Text Displacement b/scalos/Plugins/Prefs/Popupmenu/images/Text Displacement new file mode 100755 index 0000000000000000000000000000000000000000..be82a8059ca0cb75205fa09b90a99918ca3506cb GIT binary patch literal 2988 zcwX&Q&ubGw7=5!@o2fqomSPd?9*Xp!QhHTrnigw{u~HQ5v6mDN;*Wz7JY>bv7EzIa zU=a1IzSmMGUfHpiwH;>RYVgjeyNmRo?qW?0ddXmYjRyLbTC6Qz^snkr?%35=b zG0Wm0Z&~@d{1UUW`TP=BbAD*FKPId&jJARP#E^}(h<+u0X$%Mz5k>bVK@Y8h@);0;ZdV5wr&K^4cIbz}{FL-!-;8ID5j|MumtjkGL|`h~QcO3oS4AXbmi$%TT$b^<>_wjLTxX%G!`icp$lK7> zy10RsH@>TNaRY6i?}GR3u->#!o8Cd&%pXTH`|w}uYtEwAm%A5oGF@cYD8qZd_}?@> Q!yn?Y=FI%BtL4DJZ*TMbR{#J2 literal 0 HcwPel00001 diff --git a/scalos/Plugins/Prefs/Popupmenu/images/Text Displacement.c b/scalos/Plugins/Prefs/Popupmenu/images/Text Displacement.c new file mode 100755 index 000000000..7c3c96206 --- /dev/null +++ b/scalos/Plugins/Prefs/Popupmenu/images/Text Displacement.c @@ -0,0 +1,159 @@ +#ifdef USE_TEXT DISPLACEMENT_COLORS +const ULONG Text Displacement_colors[48] = +{ + 0x66666666,0x66666666,0x55555555, + 0xaaaaaaaa,0x99999999,0x99999999, + 0x77777777,0x77777777,0x66666666, + 0x00000000,0x66666666,0xffffffff, + 0x88888888,0x77777777,0x77777777, + 0x88888888,0x99999999,0xaaaaaaaa, + 0x99999999,0xaaaaaaaa,0xbbbbbbbb, + 0xffffffff,0xffffffff,0xffffffff, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0x99999999,0xaaaaaaaa,0xcccccccc, + 0xaaaaaaaa,0xaaaaaaaa,0xcccccccc, + 0xbbbbbbbb,0xcccccccc,0xdddddddd, + 0xffffffff,0xaaaaaaaa,0x99999999, + 0xcccccccc,0xcccccccc,0xdddddddd, + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, +}; +#endif + +#define TEXT DISPLACEMENT_WIDTH 149 +#define TEXT DISPLACEMENT_HEIGHT 40 +#define TEXT DISPLACEMENT_DEPTH 4 +#define TEXT DISPLACEMENT_COMPRESSION 1 +#define TEXT DISPLACEMENT_MASKING 2 + +#ifdef USE_TEXT DISPLACEMENT_HEADER +const struct BitMapHeader Text Displacement_header = +{ 149,40,0,0,4,2,1,0,0,44,22,320,512 }; +#endif + +#ifdef USE_TEXT DISPLACEMENT_BODY +const UBYTE Text Displacement_body[1837] = { +0xed,0x00,0xed,0x00,0xed,0x00,0xed,0x00,0x01,0x00,0x20,0xf2,0x00,0x02,0x07, +0x00,0x00,0x01,0x00,0x20,0xf3,0x00,0x03,0x20,0x07,0x00,0x00,0x01,0x00,0x20, +0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20, +0xf2,0x00,0x02,0x07,0x00,0x00,0x01,0x00,0x20,0xf3,0x00,0x03,0x20,0x07,0x00, +0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe, +0x00,0x01,0x00,0x20,0xf2,0x00,0x02,0x07,0x00,0x00,0x01,0x00,0x20,0xf3,0x00, +0x03,0x20,0x07,0x00,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1, +0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf2,0x00,0x02,0x07,0x00,0x00,0x01, +0x00,0x20,0xf4,0xff,0x04,0xf8,0x20,0x07,0x00,0x00,0x01,0x00,0x20,0xf4,0xff, +0x01,0xf8,0x20,0xfe,0x00,0xff,0x00,0xf4,0xff,0x01,0xf8,0x20,0xfe,0x00,0x01, +0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x07,0x00,0x00,0x02,0x00,0x20,0x80,0xf5, +0x00,0x04,0x08,0x20,0x07,0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08, +0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00, +0x20,0xf4,0x00,0x04,0x08,0x00,0x07,0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00, +0x04,0x08,0x20,0x07,0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20, +0xfe,0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20, +0xf4,0x00,0x04,0x08,0x00,0xff,0xe0,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x04, +0x08,0x20,0xff,0xe0,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20,0xfe, +0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4, +0x00,0x04,0x08,0x00,0x7f,0xe0,0x00,0x08,0x00,0x20,0x87,0xf0,0x00,0x00,0x32, +0x00,0x0c,0xfb,0x00,0x04,0x08,0x20,0x7f,0xe0,0x00,0x08,0x00,0x20,0x87,0xf0, +0x00,0x00,0x32,0x00,0x0c,0xfb,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x06, +0x87,0xf0,0x00,0x00,0x32,0x00,0x0c,0xfa,0x00,0x00,0x20,0xfe,0x00,0x01,0x00, +0x20,0xf4,0x00,0x04,0x08,0x00,0x3f,0xe0,0x00,0x08,0x00,0x20,0x84,0x90,0x00, +0x00,0x10,0x00,0x04,0xfb,0x00,0x04,0x08,0x20,0x3f,0xe0,0x00,0x08,0x00,0x20, +0x84,0x90,0x00,0x00,0x10,0x00,0x04,0xfb,0x00,0x01,0x08,0x20,0xfe,0x00,0xff, +0x00,0x06,0x84,0x90,0x00,0x00,0x10,0x00,0x04,0xfa,0x00,0x00,0x20,0xfe,0x00, +0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x1f,0xc0,0x00,0x08,0x00,0x20,0x80, +0x80,0x00,0x40,0x10,0x00,0x04,0xfd,0x00,0x06,0x02,0x00,0x08,0x20,0x1f,0xc0, +0x00,0x08,0x00,0x20,0x80,0x80,0x00,0x40,0x10,0x00,0x04,0xfd,0x00,0x03,0x02, +0x00,0x08,0x20,0xfe,0x00,0xff,0x00,0xff,0x80,0x04,0x00,0x40,0x10,0x00,0x04, +0xfd,0x00,0x03,0x02,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04, +0x08,0x00,0x0f,0x80,0x00,0x13,0x00,0x20,0x80,0x83,0x1b,0xf0,0x76,0x3b,0xc4, +0x61,0x8c,0xb6,0x19,0x67,0x80,0x08,0x20,0x0f,0x80,0x00,0x10,0x00,0x20,0x80, +0x83,0x1b,0xf0,0x76,0x3b,0xc4,0x61,0x8c,0xb6,0x19,0x67,0x80,0x08,0x20,0xfe, +0x00,0xff,0x00,0x0e,0x80,0x83,0x1b,0xf0,0x76,0x3b,0xc4,0x61,0x8c,0xb6,0x19, +0x67,0x80,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x07, +0x00,0x00,0x13,0x00,0x20,0x80,0x84,0x8a,0x40,0x92,0x49,0x24,0x92,0x52,0x49, +0x24,0x92,0x00,0x08,0x20,0x07,0x00,0x00,0x10,0x00,0x20,0x80,0x84,0x8a,0x40, +0x92,0x49,0x24,0x92,0x52,0x49,0x24,0x92,0x00,0x08,0x20,0xfe,0x00,0xff,0x00, +0x0e,0x80,0x84,0x8a,0x40,0x92,0x49,0x24,0x92,0x52,0x49,0x24,0x92,0x00,0x00, +0x20,0xfe,0x00,0x13,0x00,0x20,0x1f,0x78,0x7b,0xbf,0x6d,0x9e,0xdb,0x8d,0xe1, +0xb6,0xc3,0x6d,0xff,0xff,0xdf,0xff,0xe0,0x00,0x02,0x00,0x20,0x9f,0xf2,0xff, +0x01,0xe0,0x00,0x10,0x00,0x20,0x80,0x87,0x84,0x40,0x92,0x61,0x24,0x72,0x1e, +0x49,0x3c,0x92,0x00,0x08,0x20,0xfe,0x00,0xff,0x00,0x0e,0x80,0x87,0x84,0x40, +0x92,0x61,0x24,0x72,0x1e,0x49,0x3c,0x92,0x00,0x00,0x20,0xfe,0x00,0x01,0x00, +0x20,0xf4,0x00,0x00,0x08,0xfd,0x00,0x10,0x00,0x20,0x80,0x84,0x04,0x40,0x92, +0x19,0x24,0x92,0x10,0x49,0x20,0x92,0x00,0x08,0x20,0xfe,0x00,0x10,0x00,0x20, +0x80,0x84,0x04,0x40,0x92,0x19,0x24,0x92,0x10,0x49,0x20,0x92,0x00,0x08,0x20, +0xfe,0x00,0xff,0x00,0x0e,0x80,0x84,0x04,0x40,0x92,0x19,0x24,0x92,0x10,0x49, +0x20,0x92,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x08,0xfd, +0x00,0x10,0x00,0x20,0x80,0x86,0x4a,0x40,0x92,0x49,0x24,0x92,0x59,0x49,0x32, +0x92,0x00,0x08,0x20,0xfe,0x00,0x10,0x00,0x20,0x80,0x86,0x4a,0x40,0x92,0x49, +0x24,0x92,0x59,0x49,0x32,0x92,0x00,0x08,0x20,0xfe,0x00,0xff,0x00,0x0e,0x80, +0x86,0x4a,0x40,0x92,0x49,0x24,0x92,0x59,0x49,0x32,0x92,0x00,0x00,0x20,0xfe, +0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x08,0xfd,0x00,0x10,0x00,0x20,0x81,0xc3, +0x9b,0x30,0x6f,0x71,0xce,0x69,0x8e,0xed,0x9d,0xd9,0x80,0x08,0x20,0xfe,0x00, +0x10,0x00,0x20,0x81,0xc3,0x9b,0x30,0x6f,0x71,0xce,0x69,0x8e,0xed,0x9d,0xd9, +0x80,0x08,0x20,0xfe,0x00,0xff,0x00,0x0e,0x81,0xc3,0x9b,0x30,0x6f,0x71,0xce, +0x69,0x8e,0xed,0x9d,0xd9,0x80,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00, +0x00,0x08,0xfd,0x00,0x02,0x00,0x20,0x80,0xfd,0x00,0x00,0x01,0xfa,0x00,0x01, +0x08,0x20,0xfe,0x00,0x02,0x00,0x20,0x80,0xfd,0x00,0x00,0x01,0xfa,0x00,0x01, +0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xfd,0x00,0x00,0x01,0xf9,0x00,0x00, +0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x08,0xfd,0x00,0x02,0x00,0x20, +0x80,0xfd,0x00,0x00,0x01,0xfa,0x00,0x01,0x08,0x20,0xfe,0x00,0x02,0x00,0x20, +0x80,0xfd,0x00,0x00,0x01,0xfa,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x00, +0x80,0xfd,0x00,0x00,0x01,0xf9,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4, +0x00,0x00,0x08,0xfd,0x00,0x02,0x00,0x20,0x80,0xfd,0x00,0x01,0x03,0x80,0xfb, +0x00,0x01,0x08,0x20,0xfe,0x00,0x02,0x00,0x20,0x80,0xfd,0x00,0x01,0x03,0x80, +0xfb,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xfd,0x00,0x01,0x03, +0x80,0xfa,0x00,0x00,0x20,0xfe,0x00,0x02,0x00,0x20,0x1f,0xf4,0xff,0x03,0xdf, +0xff,0xe0,0x00,0x02,0x00,0x20,0x9f,0xf2,0xff,0x01,0xe0,0x00,0x02,0x00,0x20, +0x80,0xf5,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00, +0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x07,0x00,0x00,0x02, +0x00,0x20,0x80,0xf5,0x00,0x04,0x08,0x20,0x07,0x00,0x00,0x02,0x00,0x20,0x80, +0xf5,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20, +0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x0f,0x80,0x00,0x02,0x00, +0x20,0x80,0xf5,0x00,0x04,0x08,0x20,0x0f,0x80,0x00,0x02,0x00,0x20,0x80,0xf5, +0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe, +0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x1f,0xc0,0x00,0x02,0x00,0x20, +0x80,0xf5,0x00,0x04,0x08,0x20,0x1f,0xc0,0x00,0x02,0x00,0x20,0x80,0xf5,0x00, +0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe,0x00, +0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x3f,0xe0,0x00,0x02,0x00,0x20,0x80, +0xf5,0x00,0x04,0x08,0x20,0x3f,0xe0,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01, +0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01, +0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x7f,0xe0,0x00,0x02,0x00,0x20,0x80,0xf5, +0x00,0x04,0x08,0x20,0x7f,0xe0,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08, +0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00, +0x20,0xf4,0x00,0x04,0x08,0x00,0xff,0xe0,0x00,0x02,0x00,0x20,0x80,0xf5,0x00, +0x04,0x08,0x20,0xff,0xe0,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20, +0xfe,0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20, +0xf4,0x00,0x04,0x08,0x00,0x07,0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x04, +0x08,0x20,0x07,0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20,0xfe, +0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4, +0x00,0x04,0x08,0x00,0x07,0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x04,0x08, +0x20,0x07,0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20,0xfe,0x00, +0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00, +0x04,0x08,0x00,0x07,0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x04,0x08,0x20, +0x07,0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20,0xfe,0x00,0xff, +0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04, +0x08,0x00,0x07,0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x04,0x08,0x20,0x07, +0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00, +0x00,0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08, +0x00,0x07,0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x04,0x08,0x20,0x07,0x00, +0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x00, +0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00, +0x07,0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x04,0x08,0x20,0x07,0x00,0x00, +0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80, +0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x07, +0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x04,0x08,0x20,0x07,0x00,0x00,0x02, +0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xf4, +0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x08,0xfd,0x00,0x02, +0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20,0xfe,0x00,0x02,0x00,0x20,0x80,0xf5, +0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe, +0x00,0x01,0x00,0x20,0xf4,0x00,0x00,0x08,0xfd,0x00,0x02,0x00,0x20,0x80,0xf5, +0x00,0x01,0x08,0x20,0xfe,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20, +0xfe,0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x02,0x00,0x20, +0x7f,0xf5,0xff,0x00,0xf8,0xfd,0x00,0x01,0x00,0x20,0xf4,0xff,0x01,0xf8,0x20, +0xfe,0x00,0x01,0x00,0x20,0xf4,0xff,0x01,0xf8,0x20,0xfe,0x00,0xff,0x00,0x00, +0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xef,0x00,0x01,0x00,0x20, +0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00, +0xf1,0x00,0x00,0x20,0xfe,0x00,0xed,0x00,0xed,0x00,0xed,0x00,0xed,0x00,0xed, +0x00,0xed,0x00,0xed,0x00,0xed,0x00, }; +#endif diff --git a/scalos/Plugins/Prefs/Popupmenu/images/Vertical Offset b/scalos/Plugins/Prefs/Popupmenu/images/Vertical Offset new file mode 100755 index 0000000000000000000000000000000000000000..27ff684b062eb70ef2e85700f6649e4100b18ae5 GIT binary patch literal 2374 zcwW_&ziSg=9LAqFNzDbpWC%`D--xyy1S9V4B@Nbyv8CwXT*%_+5I5rwu!BRCI%IT{ z`xm-o6by8ADMWA*YEM!zH9yYpy}xpoTtrbsIqrR*@AG}$PcHA>C0ExsD?nQM@X2-BvDQu9HuU2n6&1S7uMb+D`)wY{X)7kYr&v8h!9jCq9 z-uIklyS-0o^4B&CMIVLh$gUPDYeL5|iCg8HcYt^qHkQ5twtpVu7=KFl!I&$C>54KP z|BTQr|D0qYJ@D997wNtSR}?*;XaN>Qtbvqb`sZxYNf#-)<~=#R0hpYuK7Bu#w!@34 z(UMMUs?m{7XS$KJHuwqBMj#0#M3}ksK|`>Vnk_KM*|amNol)(~(BSQ)mHjyX8kP}+ zS3(CE&(%dh3JNHp19RtcTm+<`fD$^8<6IJ?pnwuOu*h=_5s-ocO6b6ayU&+IKne;d z@q_*Tm0Nl|<3Mq}L~qpGJr}VgAjbnb{zC2b)TrtQt{PRn(ov(T&$iU4>U3R=QGAA# zt{2}Ux>Sc+p)&iGx3~ zM)c3XxByIA3c$1z2GAaz1b>*J_ltV4M?PZORFKrz8-_5nfnvqm!B*x<_nA9VyEb{ggLFYEv&Xll&Zi^hB?J#Lg2=EIn=ImT!&67xP$deSK88X-);G#KMW xVhTIrTALwEz%&@+MPlqv%Uky^FP_Q=F#*$Hj5me(xyK&XFxdUQ;K7Uo-vRtMdT9Uv literal 0 HcwPel00001 diff --git a/scalos/Plugins/Prefs/Popupmenu/images/Vertical Offset.c b/scalos/Plugins/Prefs/Popupmenu/images/Vertical Offset.c new file mode 100755 index 000000000..ccadce9ce --- /dev/null +++ b/scalos/Plugins/Prefs/Popupmenu/images/Vertical Offset.c @@ -0,0 +1,130 @@ +#ifdef USE_VERTICAL OFFSET_COLORS +const ULONG Vertical Offset_colors[48] = +{ + 0x66666666,0x66666666,0x55555555, + 0xaaaaaaaa,0x99999999,0x99999999, + 0x77777777,0x77777777,0x66666666, + 0x00000000,0x66666666,0xffffffff, + 0x88888888,0x77777777,0x77777777, + 0x88888888,0x99999999,0xaaaaaaaa, + 0x99999999,0xaaaaaaaa,0xbbbbbbbb, + 0xffffffff,0xffffffff,0xffffffff, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0x99999999,0xaaaaaaaa,0xcccccccc, + 0xaaaaaaaa,0xaaaaaaaa,0xcccccccc, + 0xbbbbbbbb,0xcccccccc,0xdddddddd, + 0xffffffff,0xaaaaaaaa,0x99999999, + 0xcccccccc,0xcccccccc,0xdddddddd, + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, +}; +#endif + +#define VERTICAL OFFSET_WIDTH 149 +#define VERTICAL OFFSET_HEIGHT 40 +#define VERTICAL OFFSET_DEPTH 4 +#define VERTICAL OFFSET_COMPRESSION 1 +#define VERTICAL OFFSET_MASKING 2 + +#ifdef USE_VERTICAL OFFSET_HEADER +const struct BitMapHeader Vertical Offset_header = +{ 149,40,0,0,4,2,1,0,0,44,22,320,512 }; +#endif + +#ifdef USE_VERTICAL OFFSET_BODY +const UBYTE Vertical Offset_body[1395] = { +0xf0,0x00,0x02,0x07,0x00,0x00,0xf0,0x00,0x02,0x07,0x00,0x00,0xed,0x00,0xed, +0x00,0xf0,0x00,0x02,0x07,0x00,0x00,0xf0,0x00,0x02,0x07,0x00,0x00,0xed,0x00, +0xed,0x00,0xf0,0x00,0x02,0x07,0x00,0x00,0xf0,0x00,0x02,0x07,0x00,0x00,0xed, +0x00,0xed,0x00,0xf0,0x00,0x02,0x07,0x00,0x00,0xf0,0x00,0x02,0x07,0x00,0x00, +0xed,0x00,0xed,0x00,0xf0,0x00,0x02,0x07,0x00,0x00,0xf0,0x00,0x02,0x07,0x00, +0x00,0xed,0x00,0xed,0x00,0xf0,0x00,0x02,0x07,0x00,0x00,0xf0,0x00,0x02,0x07, +0x00,0x00,0xed,0x00,0xed,0x00,0xf0,0x00,0x02,0x07,0x00,0x00,0xf0,0x00,0x02, +0x07,0x00,0x00,0xed,0x00,0xed,0x00,0xf0,0x00,0x02,0xff,0xf8,0x00,0xf0,0x00, +0x02,0xff,0xf8,0x00,0xed,0x00,0xed,0x00,0xf0,0x00,0x02,0x7f,0xf0,0x00,0xf0, +0x00,0x02,0x7f,0xf0,0x00,0xed,0x00,0xed,0x00,0xf0,0x00,0x02,0x3f,0xe0,0x00, +0xf0,0x00,0x02,0x3f,0xe0,0x00,0xed,0x00,0xed,0x00,0xf0,0x00,0x02,0x1f,0xc0, +0x00,0xf0,0x00,0x02,0x1f,0xc0,0x00,0xed,0x00,0xed,0x00,0xf0,0x00,0x02,0x0f, +0x80,0x00,0xf0,0x00,0x02,0x0f,0x80,0x00,0xed,0x00,0xed,0x00,0xf0,0x00,0x02, +0x07,0x00,0x00,0xf0,0x00,0x02,0x07,0x00,0x00,0xed,0x00,0xed,0x00,0x01,0x00, +0x3f,0xf3,0xff,0x03,0xcf,0xff,0xf8,0x00,0x01,0x00,0x3f,0xf3,0xff,0x03,0xef, +0xff,0xf8,0x00,0x01,0x00,0x3f,0xf3,0xff,0x00,0xe0,0xfe,0x00,0xf1,0x00,0x00, +0x20,0xfe,0x00,0x01,0x00,0x20,0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20, +0xfe,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20, +0xfe,0x00,0x01,0x00,0x20,0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe, +0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe, +0x00,0x01,0x00,0x20,0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00, +0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00, +0x01,0x00,0x20,0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01, +0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01, +0x00,0x20,0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00, +0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00, +0x20,0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20, +0xf3,0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20, +0xef,0x00,0x01,0x00,0x20,0xf3,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3, +0x00,0x00,0x20,0xfe,0x00,0xf1,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf3, +0x00,0x03,0x0f,0xff,0xf8,0x00,0x01,0x00,0x20,0xf4,0xff,0x04,0xf8,0x2f,0xff, +0xf8,0x00,0x01,0x00,0x20,0xf4,0xff,0x01,0xf8,0x20,0xfe,0x00,0xff,0x00,0xf4, +0xff,0x01,0xf8,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x07, +0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x04,0x08,0x20,0x07,0x00,0x00,0x02, +0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xf4, +0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x0f,0x80, +0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x04,0x08,0x20,0x0f,0x80,0x00,0x02,0x00, +0x20,0x80,0xf5,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xf4,0x00, +0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x1f,0xc0,0x00, +0x02,0x00,0x20,0x80,0xf5,0x00,0x04,0x08,0x20,0x1f,0xc0,0x00,0x02,0x00,0x20, +0x80,0xf5,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00, +0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x3f,0xe0,0x00,0x09, +0x00,0x20,0x87,0x1c,0x00,0x04,0x00,0x30,0x00,0xd8,0xfc,0x00,0x04,0x08,0x20, +0x3f,0xe0,0x00,0x09,0x00,0x20,0x87,0x1c,0x00,0x04,0x00,0x30,0x00,0xd8,0xfc, +0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x07,0x87,0x1c,0x00,0x04,0x00,0x30, +0x00,0xd8,0xfb,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08, +0x00,0x7f,0xf0,0x00,0x03,0x00,0x20,0x82,0x08,0xfe,0x00,0x02,0x10,0x01,0x20, +0xfc,0x00,0x04,0x08,0x20,0x7f,0xf0,0x00,0x03,0x00,0x20,0x82,0x08,0xfe,0x00, +0x02,0x10,0x01,0x20,0xfc,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x01,0x82, +0x08,0xfe,0x00,0x02,0x10,0x01,0x20,0xfb,0x00,0x00,0x20,0xfe,0x00,0x01,0x00, +0x20,0xf4,0x00,0x04,0x08,0x00,0xff,0xf8,0x00,0x0b,0x00,0x20,0x81,0x10,0x00, +0x40,0x00,0x10,0x01,0x20,0x00,0x40,0xfe,0x00,0x04,0x08,0x20,0xff,0xf8,0x00, +0x0b,0x00,0x20,0x81,0x10,0x00,0x40,0x00,0x10,0x01,0x20,0x00,0x40,0xfe,0x00, +0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x09,0x81,0x10,0x00,0x40,0x00,0x10,0x01, +0x20,0x00,0x40,0xfd,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04, +0x08,0x00,0x07,0x00,0x00,0x0b,0x00,0x20,0x81,0x10,0xcb,0xfc,0x63,0x10,0x33, +0xf3,0x8c,0xf0,0xfe,0x00,0x04,0x08,0x20,0x07,0x00,0x00,0x0b,0x00,0x20,0x81, +0x10,0xcb,0xfc,0x63,0x10,0x33,0xf3,0x8c,0xf0,0xfe,0x00,0x01,0x08,0x20,0xfe, +0x00,0xff,0x00,0x09,0x81,0x10,0xcb,0xfc,0x63,0x10,0x33,0xf3,0x8c,0xf0,0xfd, +0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x07,0x00, +0x00,0x0b,0x00,0x20,0x80,0xa1,0x26,0x44,0x94,0x90,0x49,0x24,0x92,0x40,0xfe, +0x00,0x04,0x08,0x20,0x07,0x00,0x00,0x0b,0x00,0x20,0x80,0xa1,0x26,0x44,0x94, +0x90,0x49,0x24,0x92,0x40,0xfe,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x09, +0x80,0xa1,0x26,0x44,0x94,0x90,0x49,0x24,0x92,0x40,0xfd,0x00,0x00,0x20,0xfe, +0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x07,0x00,0x00,0x0b,0x00,0x20, +0x80,0xa1,0xe4,0x44,0x83,0x90,0x49,0x26,0x1e,0x40,0xfe,0x00,0x04,0x08,0x20, +0x07,0x00,0x00,0x0b,0x00,0x20,0x80,0xa1,0xe4,0x44,0x83,0x90,0x49,0x26,0x1e, +0x40,0xfe,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x09,0x80,0xa1,0xe4,0x44, +0x83,0x90,0x49,0x26,0x1e,0x40,0xfd,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20, +0xf4,0x00,0x04,0x08,0x00,0x07,0x00,0x00,0x0b,0x00,0x20,0x80,0xe1,0x04,0x44, +0x84,0x90,0x49,0x21,0x90,0x40,0xfe,0x00,0x04,0x08,0x20,0x07,0x00,0x00,0x0b, +0x00,0x20,0x80,0xe1,0x04,0x44,0x84,0x90,0x49,0x21,0x90,0x40,0xfe,0x00,0x01, +0x08,0x20,0xfe,0x00,0xff,0x00,0x09,0x80,0xe1,0x04,0x44,0x84,0x90,0x49,0x21, +0x90,0x40,0xfd,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08, +0x00,0x07,0x00,0x00,0x0b,0x00,0x20,0x80,0x41,0x94,0x44,0x94,0x90,0x49,0x24, +0x99,0x40,0xfe,0x00,0x04,0x08,0x20,0x07,0x00,0x00,0x0b,0x00,0x20,0x80,0x41, +0x94,0x44,0x94,0x90,0x49,0x24,0x99,0x40,0xfe,0x00,0x01,0x08,0x20,0xfe,0x00, +0xff,0x00,0x09,0x80,0x41,0x94,0x44,0x94,0x90,0x49,0x24,0x99,0x40,0xfd,0x00, +0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x07,0x00,0x00, +0x0b,0x00,0x20,0x80,0x40,0xee,0x3e,0x63,0x78,0x31,0x27,0x0e,0x30,0xfe,0x00, +0x04,0x08,0x20,0x07,0x00,0x00,0x0b,0x00,0x20,0x80,0x40,0xee,0x3e,0x63,0x78, +0x31,0x27,0x0e,0x30,0xfe,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x09,0x80, +0x40,0xee,0x3e,0x63,0x78,0x31,0x27,0x0e,0x30,0xfd,0x00,0x00,0x20,0xfe,0x00, +0x01,0x00,0x20,0xf4,0x00,0x04,0x08,0x00,0x07,0x00,0x00,0x02,0x00,0x20,0x80, +0xf5,0x00,0x04,0x08,0x20,0x07,0x00,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01, +0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01, +0x00,0x20,0xf4,0x00,0x00,0x08,0xfd,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01, +0x08,0x20,0xfe,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20,0xfe,0x00, +0xff,0x00,0x00,0x80,0xf4,0x00,0x00,0x20,0xfe,0x00,0x01,0x00,0x20,0xf4,0x00, +0x00,0x08,0xfd,0x00,0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20,0xfe,0x00, +0x02,0x00,0x20,0x80,0xf5,0x00,0x01,0x08,0x20,0xfe,0x00,0xff,0x00,0x00,0x80, +0xf4,0x00,0x00,0x20,0xfe,0x00,0xed,0x00,0xed,0x00,0xed,0x00,0xed,0x00,0xed, +0x00,0xed,0x00,0xed,0x00,0xed,0x00,0xed,0x00,0xed,0x00,0xed,0x00,0xed,0x00, + }; +#endif diff --git a/scalos/Plugins/Prefs/Popupmenu/images/Vertical Space b/scalos/Plugins/Prefs/Popupmenu/images/Vertical Space new file mode 100755 index 0000000000000000000000000000000000000000..15b2b53bc54b633b2e90434da5ecfd34fa02e0b5 GIT binary patch literal 2918 zcwW_(&ubGw6vy98(qu~xE>fhFf@!O^f`=YF=*1>!uttn6RY8k*Ddf^WAbK)T54|a+ z9&+@$7Z2X7V8Ej}cos@q@S>nbMbg?d)Lp=Uf>oG@DY@ymsa*HF$t21Yi4KHz=9ZwrKH z4_l;vGQ0(tHY1t8Gahs*wwt_~|J35CQgHym_zgzmphh<8wwv}i$wAjXb*!%X^Xr%Vt1Xg=`p36=Gi^jqN zy;m6^fdGqe?`L{>?~Tv|i;(E;W5NitMqgy>XvxfvPC~$?#|)4_fQ1Eo!2k&aSnM5; z7LXQ@4zRz6Za+Jlo6O@ICNcjO=p!KgUjKXo(EV%02Wxkn{0K4$G#*P^^$!zCNGJR8 zO*^_toZ~g8pv$#kECy-mwE=vNIi6y|wG>kudUfIBmYG=8^VwWWvD*#8p0{RAEb7Bp z$5L!;O=IxjSbpiAjzzuZ+7Ndfr4HAKdX=9ysi?Q9j-%9pilNry`8y^R^_+5?TYbnb z@fAirryLi9A=QsX6`Lw{*A#C^U4M6G_7?hwR7}XAzZr%dw_D%-SCd2dH)Op@RUr4e zNi`4}0IzAlR;a>)i=7_`+&Ctz`j()Eh&>s7`K;Dy5bHIE-RN53bYpz6aQsN6(~Z`1 z%(cSl{lvl3-4u&@j=5IYCoO@G$YP;;c!M6aj-^oCaba;1bVY+3RH2ULjN^pU!O8xU ytB)$~`-41Ro@?D0`1o&K#%X-^n#108+;2#o!dH}YiPm$ /dev/null 2>&1 + +XSRCS = $(notdir $(CSRCS)) +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(XSRCS:%.c=$(OBJDIR)/$(notdir %).o) + +############################################################# + +All: $(BINDIR)/$(PLUGIN) \ + $(BINDIR)/$(PLUGINDBG) \ + allcatalogs +# install +# clean + +############################################################# + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-classic.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/DataTypesMCC.o : $(DATATYPESMCC_DIR)/DataTypesMCC.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $*.c objectname $@ + +############################################################# + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-common.c \ + plugin_data.h $(COMMON_DIR)/plugin.h + +$(OBJDIR)/FrameButtonMCC.o : FrameButtonMCC.c FrameButtonMCC.h \ + PopupMenuPrefs.h $(PREFS_DIR)/popupmenu.h + +$(OBJDIR)/DataTypesMCC.o: $(DATATYPESMCC_DIR)/DataTypesMCC.c \ + $(DATATYPESMCC_DIR)/DataTypesMCC.h + +$(OBJDIR)/PopupMenuPrefs.o : PopupMenuPrefs.h PopupMenuPrefsImage.h \ + plugin_data.h $(COMMON_DIR)/plugin.h $(SCALOS_LOCALE) \ + $(PREFS_DIR)/popupmenu.h FrameButtonMCC.h + +############################################################# + +$(CATCOMPHEADER) : ScalosPopupMenu.cd + @printf '\033[32mMake CatComp header: \033[31m\033[1m$@ \033[32mfrom \033[31m$<\033[0m\n' + $(FLEXCAT) $(subst ../,/,$<) $@=$(SDPATH)/CatComp_h.sd + +$(BINDIR)/$(PLUGIN) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) to $@ FROM $(OBJS) lib $(LIBS) $(LDFLAGS) STRIPDEBUG + +$(BINDIR)/$(PLUGINDBG) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) to $@ FROM $(OBJS) lib $(LIBS) $(LDFLAGS) ADDSYM + +############################################################# + +install: + @avail flush + @printf '\033[32mInstall: \033[31m\033[1m$(PLUGIN)\033[0m\n' + @copy $(BINDIR)/$(PLUGIN) $(DESTTOOL) + @printf '\033[32mInstall: \033[31m\033[1m$(CAT_FILE)\033[0m\n' + -@$(foreach cat,$(CATS),copy "Catalogs/$(cat)/$(CAT_FILE)" "$(DESTCAT)/$(cat)/Scalos" clone;) + +############################################################# + +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + -@delete $(BINDIR)/$(PLUGIN) $(BINDIR)/$(PLUGINDBG) $(OBJS) $(subst ../,/,$(CATCOMPHEADER)) $(ALLCATS) + @printf '\033[0m' + +############################################################# + +# make all Scalos preferences .catalogs +allcatalogs: + -@$(foreach cat,$(CATS),$(SUBDIRMAKE) Catalogs/$(cat)/Scalos;) + +############################################################# + diff --git a/scalos/Plugins/Prefs/Popupmenu/makefile-new b/scalos/Plugins/Prefs/Popupmenu/makefile-new new file mode 100755 index 000000000..b762c7397 --- /dev/null +++ b/scalos/Plugins/Prefs/Popupmenu/makefile-new @@ -0,0 +1,109 @@ +# $Date: 2011-08-03 02:03:07 +0200 (Mi, 03. Aug 2011) $ +# $Revision: 817 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../../.. +endif + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + SDPATH=// +else + SDPATH=../../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(BEGIN_OBJS) \ + $(OBJDIR)/PopupMenuPrefs.o \ + $(OBJDIR)/DataTypesMCC.o \ + $(OBJDIR)/FrameButtonMCC.o \ + $(END_OBJS) + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Targets +# + +NAME = PopupMenu.prefsplugin +NAME_DB = $(NAME).debug + +############################################################################## + +PREFSDIR = . + +############################################################################## +# +# Subdirs +# + +SUBDIRS = $(filter-out Catalogs/sample/Scalos, $(wildcard Catalogs/*/Scalos)) + +############################################################################## +# +# Some lame deps + +$(OBJDIR)/%.o: $(DATATYPESMCC_DIR)/%.c + @$(run-cc) + + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) \ + all_subdirs + +############################################################################## + +PopupMenuPrefs.c : $(SCALOS_LOCALE) + +$(SCALOS_LOCALE) : $(PREFSDIR)/ScalosPopupMenu.cd + @$(ECHO) "FlexCat $@" + $(FLEXCAT) $< $@=$(SDPATH)/CatComp_h.sd + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + $(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) Scalos:Prefs/ clone + @avail flush + +install: install_subdirs + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* \ + $(SCALOS_LOCALE) + +clean: clean_subdirs + +############################################################################## + diff --git a/scalos/Plugins/Prefs/Popupmenu/plugin_data.h b/scalos/Plugins/Prefs/Popupmenu/plugin_data.h new file mode 100644 index 000000000..b6fb71f6a --- /dev/null +++ b/scalos/Plugins/Prefs/Popupmenu/plugin_data.h @@ -0,0 +1,27 @@ +// plugin_data.h +// $Date$ +// $Revision$ + +#ifndef PLUGIN_DATA_H_INCLUDED +#define PLUGIN_DATA_H_INCLUDED + +#include +#include + +#define PLUGIN_TYPE PREFS + +#define LIB_VERSION 40 +#define LIB_REVISION 2 + +#define LIB_NAME "PopupMenu.prefsplugin" +#define LIB_VERSTRING "$VER: " LIB_NAME " " \ + STR(LIB_VERSION) "." STR(LIB_REVISION) \ + " " __DATE__ " " \ + COMPILER_STRING " ©2006" CURRENTYEAR \ + " The Scalos Team" + +//---------------------------------------------------------------------------- +// code and includes to define the structs and functions used above + +#endif /* PLUGUN_DATA_H_INCLUDED */ + diff --git a/scalos/Plugins/Prefs/config.mk b/scalos/Plugins/Prefs/config.mk new file mode 100755 index 000000000..58e611622 --- /dev/null +++ b/scalos/Plugins/Prefs/config.mk @@ -0,0 +1,34 @@ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += # + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += # + + +else + +############################################################################### +# AmigaOS + +LFLAGS += # + +endif +endif diff --git a/scalos/Plugins/Prefs/makefile b/scalos/Plugins/Prefs/makefile new file mode 100644 index 000000000..16589340f --- /dev/null +++ b/scalos/Plugins/Prefs/makefile @@ -0,0 +1,46 @@ +# makefile for Scalos prefs plugins +# $Date$ +# $Revision$ + +############################################################# + +SUBDIRS = FileTypes \ + Palette \ + Pattern \ + Menu \ + Popupmenu \ + +############################################################# + +.PHONY: All install clean + +############################################################# + +define build_subdir +$(MAKE) -s --directory=$(1); +endef + +define install_subdir +$(MAKE) -s install --directory=$(1); +endef + +define clean_subdir +$(MAKE) -s clean --directory=$(1); +endef + +############################################################# + +All: + @$(foreach subdir,$(SUBDIRS),$(call build_subdir,$(subdir))) + +############################################################# + +install: + @$(foreach subdir,$(SUBDIRS),$(call install_subdir,$(subdir))) + +############################################################# + +clean: + @$(foreach subdir,$(SUBDIRS),$(call clean_subdir,$(subdir))) + +############################################################# diff --git a/scalos/Plugins/Prefs/makefile-new b/scalos/Plugins/Prefs/makefile-new new file mode 100755 index 000000000..9fc229129 --- /dev/null +++ b/scalos/Plugins/Prefs/makefile-new @@ -0,0 +1,33 @@ +# $Date: 2006-11-26 16:13:59 +0200 (So, 26 Nov 2006) $ +# $Revision: 2043 $ +############################################################# +TOPLEVEL = $(shell pwd)/../.. + +include config.mk + +############################################################################## +# +# Project subdirectories +# + +SUBDIRS = Menu \ + Palette \ + FileTypes \ + Pattern \ + +ifneq ($(MACHINE), ppc-amigaos) +SUBDIRS += Popupmenu +endif + +############################################################################## + +.PHONY: all install clean + +all: all_subdirs + +clean: clean_subdirs + +install: install_subdirs + +nodebug: nodebug_subdirs + diff --git a/scalos/Plugins/Preview/DefPicture/DefPicture.c b/scalos/Plugins/Preview/DefPicture/DefPicture.c new file mode 100755 index 000000000..9847ec985 --- /dev/null +++ b/scalos/Plugins/Preview/DefPicture/DefPicture.c @@ -0,0 +1,878 @@ +// DefPicture.c +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "DefPicture.h" + +//--------------------------------------------------------------------------------------- + +// set BYTEDUMP to 1 if you need to use ByteDump() +#define BYTEDUMP 0 + +#if 1 +#define DUMP_ARGB_LINE(argbh, component, yy) +#else +#define DUMP_ARGB_LINE(argbh, component, yy) \ + { \ + int n; \ + const struct ARGB *argb = &(argbh)->argb_ImageData[(yy) * (argbh)->argb_Width]; \ + KPrintF(__FILE__ "/%s/%ld: w=%ld h=%ld yy=%ld #component:\n", __FUNC__, __LINE__, \ + (argbh)->argb_Width, (argbh)->argb_Height, yy); \ + KPrintF(__FILE__ "/%s/%ld: ", __FUNC__, __LINE__); \ + for (n = 0; n < (argbh)->argb_Width; n++, argb++) \ + { \ + if (n > 0 && 0 == n % 16) \ + KPrintF("\n" __FILE__ "/%s/%ld: ", __FUNC__, __LINE__); \ + KPrintF("%02lx ", argb->component); \ + } \ + KPrintF("\n"); \ + } +#endif + +//--------------------------------------------------------------------------------------- + +struct GfxBase *GfxBase; +T_UTILITYBASE UtilityBase; +struct Library *CyberGfxBase; +struct Library *DataTypesBase; +struct DosLibrary *DOSBase; +struct IntuitionBase *IntuitionBase; +struct ScalosGfxBase *ScalosGfxBase; +#ifdef __amigaos4__ +struct GraphicsIFace *IGraphics; +struct UtilityIFace *IUtility; +struct CyberGfxIFace *ICyberGfx; +struct DataTypesIFace *IDataTypes; +struct DOSIFace *IDOS; +struct IntuitionIFace *IIntuition; +struct ScalosGfxIFace *IScalosGfx; +struct Library *NewlibBase; +struct Interface *INewlib; +#endif + +#if defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__AROS__) +extern T_UTILITYBASE __UtilityBase; +#endif /* defined(__GNUC__) && !defined(__MORPHOS__) */ + +//--------------------------------------------------------------------------------------- + +static BOOL GenerateRemappedThumbnail(struct ScaWindowTask *wt, + CONST_STRPTR iconName, Object *ImageObj, + ULONG quality, ULONG ReservedColors, + ULONG ScaledWidth, ULONG ScaledHeight, + ULONG SupportedColors, struct Screen *WBScreen, + struct ScalosPreviewResult *PVResult); +static BOOL GenerateARGBThumbnail(struct ScaWindowTask *wt, + CONST_STRPTR iconName, Object *ImageObj, + ULONG quality, ULONG ReservedColors, + ULONG ScaledWidth, ULONG ScaledHeight, + ULONG SupportedColors, struct ScalosPreviewResult *PVResult); +static BOOL GenerateThumbnailFromARGB(struct ScaWindowTask *wt, + CONST_STRPTR iconName, struct ARGBHeader *argbDest, + ULONG SupportedColors, ULONG ReservedColors, + struct ScalosPreviewResult *PVResult); +static BOOL IsPictureDT43(Object *o); +#if BYTEDUMP +static void ByteDump(const unsigned char *Data, size_t Length); +#endif /* BYTEDUMP */ + +// #define KPrintF DebugPrintF + +//----------------------------------------------------------- + +BOOL initPlugin(struct PluginBase *PluginBase) +{ + d1(KPrintF("%s/%ld: PluginBase=%08lx procName=<%s>\n", __FUNC__, __LINE__, \ + PluginBase, FindTask(NULL)->tc_Node.ln_Name)); + + DOSBase = (APTR) OpenLibrary( "dos.library", 39 ); + if (NULL == DOSBase) + return FALSE; + + UtilityBase = (T_UTILITYBASE) OpenLibrary("utility.library", 39); + if (NULL == UtilityBase) + return FALSE; + + DataTypesBase = OpenLibrary("datatypes.library", 39); + if (NULL == DataTypesBase) + return FALSE; + + CyberGfxBase = OpenLibrary(CYBERGFXNAME, 0); + // CyberGfxBase may be NULL + + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + d1(kprintf("%s/%s/%ld: IntuitionBase=%08lx\n", __FILE__, __FUNC__, __LINE__, IntuitionBase)); + if (NULL == IntuitionBase) + return FALSE; + + GfxBase = (struct GfxBase *) OpenLibrary(GRAPHICSNAME, 39); + d1(kprintf("%s/%s/%ld: GfxBase=%08lx\n", __FILE__, __FUNC__, __LINE__, GfxBase)); + if (NULL == GfxBase) + return FALSE; + + ScalosGfxBase = (struct ScalosGfxBase *) OpenLibrary(SCALOSGFXNAME, 41); + d1(KPrintF("%s/%s/%ld: ScalosGfxBase=%08lx\n", __FILE__, __FUNC__, __LINE__, ScalosGfxBase)); + if (NULL == ScalosGfxBase) + return FALSE; + +#ifdef __amigaos4__ + IDOS = (struct DOSIFace *)GetInterface((struct Library *)DOSBase, "main", 1, NULL); + if (IDOS == NULL) + return FALSE; + IUtility = (struct UtilityIFace *)GetInterface((struct Library *)UtilityBase, "main", 1, NULL); + if (NULL == IUtility) + return FALSE; + IDataTypes = (struct DataTypesIFace *)GetInterface((struct Library *)DataTypesBase, "main", 1, NULL); + if (IDataTypes == NULL) + return FALSE; + if (CyberGfxBase != NULL) // CyberGfxBase may be NULL + { + ICyberGfx = (struct CyberGfxIFace *)GetInterface(CyberGfxBase, "main", 1, NULL); + if (ICyberGfx == NULL) + return FALSE; + } + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + return FALSE; + IGraphics = (struct GraphicsIFace *)GetInterface((struct Library *)GfxBase, "main", 1, NULL); + if (NULL == IGraphics) + return FALSE; + IScalosGfx = (struct ScalosGfxIFace *)GetInterface((struct Library *)ScalosGfxBase, "main", 1, NULL); + if (NULL == IScalosGfx) + return FALSE; + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + return FALSE; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + return FALSE; +#endif /* __amigaos4__ */ + + +#if defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) + __UtilityBase = UtilityBase; +#endif /* defined(__GNUC__) && !defined(__MORPHOS__) */ + + return TRUE; // Succes +} + + +VOID closePlugin(struct PluginBase *PluginBase) +{ + d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__)); + +#ifdef __amigaos4__ + if (INewlib) + { + DropInterface(INewlib); + INewlib = NULL; + } + if (NewlibBase) + { + CloseLibrary(NewlibBase); + NewlibBase = NULL; + } + if (ICyberGfx) + { + DropInterface((struct Interface *)ICyberGfx); + ICyberGfx = NULL; + } + if (IScalosGfx) + { + DropInterface((struct Interface *)IScalosGfx); + IScalosGfx = NULL; + } + if (IGraphics) + { + DropInterface((struct Interface *)IGraphics); + IGraphics = NULL; + } + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } + if (IUtility) + { + DropInterface((struct Interface *)IUtility); + IUtility = NULL; + } + if (IDataTypes) + { + DropInterface((struct Interface *)IDataTypes); + IDataTypes = NULL; + } + if (IDOS) + { + DropInterface((struct Interface *)IDOS); + IDOS = NULL; + } +#endif /* __amigaos4__ */ + + if (CyberGfxBase) + { + CloseLibrary(CyberGfxBase); + CyberGfxBase = NULL; + } + if (NULL != ScalosGfxBase) + { + CloseLibrary((struct Library *) ScalosGfxBase); + ScalosGfxBase = NULL; + } + if (NULL != GfxBase) + { + CloseLibrary((struct Library *) GfxBase); + GfxBase = NULL; + } + if (NULL != IntuitionBase) + { + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } + if (NULL != DataTypesBase) + { + CloseLibrary(DataTypesBase); + DataTypesBase = NULL; + } + + if (NULL != UtilityBase) + { + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } + if (NULL != DOSBase) + { + CloseLibrary((struct Library *) DOSBase); + DOSBase = NULL; + } +} + +//-------------------------------------------------------------------------- + +LIBFUNC_P5(LONG, LIBSCAPreviewGenerate, + A0, struct ScaWindowTask *, wt, + A1, BPTR, dirLock, + A2, CONST_STRPTR, iconName, + A3, struct TagItem *, tagList, + A6, struct PluginBase *, PluginBase) +{ + Object *ImageObj = NULL; + LONG Success = FALSE; + struct ScalosPreviewResult *PVResult = NULL; +#if defined(__MORPHOS__) + struct BitMap BitMapCopy; +#endif /* __MORPHOS__ */ + + (void) dirLock; + (void) PluginBase; + + d1(KPrintF(__FILE__ "/%s/%ld: tagList=%lx\n", __FUNC__, __LINE__, tagList)); + + do { + ULONG ThumbnailWidth; + ULONG ThumbnailHeight; + ULONG SupportedColors; + ULONG ScreenDepth; + struct Screen *WBScreen; + struct BitMapHeader *bmhdExternal; + struct BitMapHeader *bmhd = NULL; + ULONG quality; + ULONG ReservedColors; + +#if defined(__MORPHOS__) + memset(&BitMapCopy, 0, sizeof(BitMapCopy)); +#endif /* __MORPHOS__ */ + + PVResult = (struct ScalosPreviewResult *) GetTagData(SCALOSPREVIEW_ResultStruct, (ULONG)NULL, tagList); + d1(KPrintF(__FILE__ "/%s/%ld: PVResult=%08lx\n", __FUNC__, __LINE__, PVResult)); + if (NULL == PVResult) + break; + + // clear result + memset(PVResult, 0, sizeof(*PVResult)); + + ThumbnailWidth = GetTagData(SCALOSPREVIEW_ThumbnailWidth, 0, tagList); + if (0 == ThumbnailWidth) + break; + ThumbnailHeight = GetTagData(SCALOSPREVIEW_ThumbnailHeight, 0, tagList); + if (0 == ThumbnailHeight) + break; + + SupportedColors = GetTagData(SCALOSPREVIEW_SupportedColors, 0, tagList); + if (SupportedColors < 16) + break; + + ReservedColors = GetTagData(SCALOSPREVIEW_ReservedColors, 0, tagList); + if (SupportedColors < ReservedColors + 16) + break; + + bmhdExternal = (struct BitMapHeader *) GetTagData(SCALOSPREVIEW_ImgBitMapHeader, (ULONG)NULL, tagList); + quality = GetTagData(SCALOSPREVIEW_Quality, SCALOSPREVIEWA_Quality_Max, tagList); + + WBScreen = (struct Screen *) GetTagData(SCALOSPREVIEW_Screen, (ULONG)NULL, tagList); + if (NULL == WBScreen) + break; + + ScreenDepth = GetBitMapAttr(WBScreen->RastPort.BitMap, BMA_DEPTH); + + ImageObj = NewDTObject((STRPTR) iconName, + DTA_SourceType, DTST_FILE, + DTA_GroupID, GID_PICTURE, + PDTA_DestMode, PMODE_V43, + PDTA_Remap, FALSE, + OBP_Precision, PRECISION_EXACT, + TAG_END); + d1(KPrintF(__FILE__ "/%s/%ld: ImageObj=%08lx\n", __FUNC__, __LINE__, ImageObj)); + if (NULL == ImageObj) + break; + + if (IsPictureDT43(ImageObj)) + { + d1(KPrintF(__FILE__ "/%s/%ld: IsPictureDT43\n", __FUNC__, __LINE__)); + SetDTAttrs(ImageObj, NULL, NULL, + PDTA_Screen, (ULONG) WBScreen, + PDTA_UseFriendBitMap, ScreenDepth <= 8, /* +dm+ Do not use a friend bitmap for 8bit or less screens */ + TAG_END); + } + else + { + SetDTAttrs(ImageObj, NULL, NULL, + PDTA_UseFriendBitMap, FALSE, + TAG_END); + } + + if (GetDTAttrs(ImageObj, + PDTA_BitMapHeader, (ULONG) &bmhd, + TAG_END) < 1) + break; + + d1(KPrintF(__FILE__ "/%s/%ld: bmhd=%08lx\n", __FUNC__, __LINE__, bmhd)); + + if (NULL == bmhd) + break; + + if (bmhdExternal) + *bmhdExternal = *bmhd; + + ScalosGfxCalculateScaleAspect(bmhd->bmh_Width, bmhd->bmh_Height, + &ThumbnailWidth, &ThumbnailHeight); + + d1(KPrintF(__FILE__ "/%s/%ld: ImageWidth=%ld ImageHeight=%ld ImageDepth=%ld\n", __FUNC__, __LINE__, bmhd->bmh_Width, bmhd->bmh_Height, bmhd->bmh_Depth)); + d1(KPrintF(__FILE__ "/%s/%ld: ThumbnailWidth=%ld ThumbnailHeight=%ld\n", __FUNC__, __LINE__, ThumbnailWidth, ThumbnailHeight)); + + if ((ScreenDepth <= 8) || (NULL == CyberGfxBase)) + { + Success = GenerateRemappedThumbnail(wt, + iconName, ImageObj, + quality, ReservedColors, + ThumbnailWidth, ThumbnailHeight, + SupportedColors, WBScreen, PVResult); + } + else + { + Success = GenerateARGBThumbnail(wt, + iconName, ImageObj, + quality, ReservedColors, + ThumbnailWidth, ThumbnailHeight, + SupportedColors, PVResult); + } + +#if defined(__MORPHOS__) + if (PVResult && PVResult->spvr_sac && PVResult->spvr_sac->sac_BitMap) + { + BitMapCopy = *PVResult->spvr_sac->sac_BitMap; + } +#endif /* __MORPHOS__ */ + } while (0); + + if (ImageObj) + DisposeDTObject(ImageObj); + +#if defined(__MORPHOS__) + if (PVResult && PVResult->spvr_sac && PVResult->spvr_sac->sac_BitMap) + { + // *** work-around *** + // ATM (MorphOS 1.4.5), some datatypes (e.g. GIF and BMP) have a serous bug + // that causes the last byte of sac_BitMap to be decremented by 1 when the + // datatypes object is disposed. + + d1(KPrintF(__FILE__ "/%s/%ld: sac_BitMap=%08lx\n", __FUNC__, __LINE__, PVResult->spvr_sac->sac_BitMap)); + d1(ByteDump((unsigned char *) PVResult->spvr_sac->sac_BitMap, sizeof(struct BitMap))); + + if (0 != memcmp(&BitMapCopy, PVResult->spvr_sac->sac_BitMap, sizeof(struct BitMap))) + *PVResult->spvr_sac->sac_BitMap = BitMapCopy; + } +#endif /* __MORPHOS__ */ + + return Success; +} +LIBFUNC_END + +//---------------------------------------------------------------------------- + +#ifndef __amigaos4__ + +void _XCEXIT(long x) +{ +} + +//---------------------------------------------------------------------------- + +#ifndef __SASC +// Replacement for SAS/C library functions + +void exit(int x) +{ + (void) x; + while (1) + ; +} + +APTR _WBenchMsg; + +#endif /* __SASC */ + +#endif /* __amigaos4__ */ + +//----------------------------------------------------------------------------- + +static BOOL GenerateRemappedThumbnail(struct ScaWindowTask *wt, + CONST_STRPTR iconName, Object *ImageObj, + ULONG quality, ULONG ReservedColors, + ULONG ScaledWidth, ULONG ScaledHeight, + ULONG SupportedColors, struct Screen *WBScreen, + struct ScalosPreviewResult *PVResult) +{ + BOOL Success = FALSE; + struct ScalosBitMapAndColor *sac; + + d1(KPrintF(__FILE__ "/%s/%ld: START\n", __FUNC__, __LINE__)); + + do { + struct BitMapHeader *bmhd = NULL; + struct BitMap *bm = NULL; + ULONG Result; + struct ScaleBitMapArg sbma; + ULONG *ColorTable; + + sac = ScalosGfxCreateEmptySAC(); + if (NULL == sac) + break; + + // SetDTAttrsA() + SetDTAttrs(ImageObj, + wt->wt_Window, NULL, + PDTA_Remap, TRUE, + TAG_END); + + if (GetDTAttrs(ImageObj, + PDTA_DestBitMap, (ULONG) &bm, + PDTA_BitMapHeader, (ULONG) &bmhd, + PDTA_NumColors, (ULONG) &sac->sac_NumColors, + PDTA_CRegs, (ULONG) &ColorTable, + TAG_END) < 4) + break; + + d1(KPrintF(__FILE__ "/%s/%ld: bm=%08lx bmhd=%08lx\n", __FUNC__, __LINE__, bm, bmhd)); + if (NULL == bm) + break; + if (NULL == bmhd) + break; + if (sac->sac_NumColors > 256) + break; + if (NULL == sac->sac_ColorTable) + break; + + d1(KPrintF(__FILE__ "/%s/%ld: ImageWidth=%ld ImageHeight=%ld ImageDepth=%ld\n", __FUNC__, __LINE__, bmhd->bmh_Width, bmhd->bmh_Height, bmhd->bmh_Depth)); + d1(KPrintF(__FILE__ "/%s/%ld: sac_NumColors=%ld sac_ColorTable=%08lx\n", __FUNC__, __LINE__, sac->sac_NumColors, sac->sac_ColorTable)); + + if (!ScalosGfxNewColorMap(sac, ColorTable, sac->sac_NumColors + ReservedColors)) + break; + + // DoDTMethodA() + Result = DoDTMethod(ImageObj, + NULL, + NULL, + DTM_PROCLAYOUT, + NULL, + TRUE); + d1(KPrintF(__FILE__ "/%s/%ld: Result=%08lx\n", __FUNC__, __LINE__, Result)); + if (!Result) + break;; + + if (mskHasTransparentColor == bmhd->bmh_Masking) + sac->sac_TransparentColor = bmhd->bmh_Transparent; + else + sac->sac_TransparentColor = SAC_TRANSPARENT_NONE; + + d1(KPrintF(__FILE__ "/%s/%ld: bmh_Masking=%ld sac_TransparentColor=%ld bmh_Transparent=%ld\n", \ + __FUNC__, __LINE__, bmhd->bmh_Masking, sac->sac_TransparentColor, bmhd->bmh_Transparent)); + + sbma.sbma_SourceBM = bm; + sbma.sbma_SourceWidth = bmhd->bmh_Width; + sbma.sbma_SourceHeight = bmhd->bmh_Height; + sbma.sbma_DestWidth = &ScaledWidth; + sbma.sbma_DestHeight = &ScaledHeight; + sbma.sbma_NumberOfColors = sac->sac_NumColors; + sbma.sbma_ColorTable = sac->sac_ColorTable; + sbma.sbma_ScreenBM = WBScreen->RastPort.BitMap; + sbma.sbma_Flags = SCALEFLAGF_DOUBLESIZE | SCALEFLAGF_AVERAGE; + + if (quality >= (3 * SCALOSPREVIEWA_Quality_Max) / 4) + { + sbma.sbma_Flags |= SCALEFLAGF_BICUBIC; + } + else if (quality >= SCALOSPREVIEWA_Quality_Max / 2) + { + sbma.sbma_Flags |= SCALEFLAGF_BILINEAR; + } + + sac->sac_BitMap = ScalosGfxScaleBitMap(&sbma, NULL); + + d1(KPrintF(__FILE__ "/%s/%ld: sac_BitMap=%08lx\n", __FUNC__, __LINE__, sac->sac_BitMap)); + if (NULL == sac->sac_BitMap) + break; + + sac->sac_Width = ScaledWidth; + sac->sac_Height = ScaledHeight; + sac->sac_Depth = GetBitMapAttr(sac->sac_BitMap, BMA_DEPTH); + + PVResult->spvr_sac = sac; + sac = NULL; // do not free sac now + + Success = TRUE; + } while (0); + + ScalosGfxFreeSAC(sac); + + d1(KPrintF(__FILE__ "/%s/%ld: END Success=%08lx\n", __FUNC__, __LINE__, Success)); + + return Success; +} + +//----------------------------------------------------------------------------- + +static BOOL GenerateARGBThumbnail(struct ScaWindowTask *wt, + CONST_STRPTR iconName, Object *ImageObj, + ULONG quality, ULONG ReservedColors, + ULONG ScaledWidth, ULONG ScaledHeight, + ULONG SupportedColors, struct ScalosPreviewResult *PVResult) +{ + BOOL Success = FALSE; + struct ARGBHeader argbSrc = { 0, 0, NULL }; + struct ARGBHeader argbDest = { 0, 0, NULL }; + + d1(KPrintF(__FILE__ "/%s/%ld: START iconName=<%s>\n", __FUNC__, __LINE__, iconName)); + + do { + struct BitMapHeader *bmhd = NULL; + struct BitMap *bm = NULL; + PLANEPTR MaskPlane = NULL; + const ULONG *CRegs = NULL; + ULONG NumberOfColors; + ULONG Result; + ULONG ScaleFlags = SCALEFLAGF_DOUBLESIZE; + + if (quality >= (3 * SCALOSPREVIEWA_Quality_Max) / 4) + { + ScaleFlags |= SCALEFLAGF_BICUBIC; + } + else if (quality >= SCALOSPREVIEWA_Quality_Max / 2) + { + ScaleFlags |= SCALEFLAGF_BILINEAR; + } + else + { + ScaleFlags |= SCALEFLAGF_AVERAGE; + } + + // DoDTMethodA() + Result = DoDTMethod(ImageObj, + NULL, + NULL, + DTM_PROCLAYOUT, + NULL, + TRUE); + if (!Result) + break;; + + if (GetDTAttrs(ImageObj, + PDTA_DestBitMap, (ULONG) &bm, + PDTA_BitMapHeader, (ULONG) &bmhd, + TAG_END) < 2) + break; + + d1(KPrintF(__FILE__ "/%s/%ld: bm=%08lx bmhd=%08lx bmh_Depth=%ld\n", __FUNC__, __LINE__, bm, bmhd, bmhd->bmh_Depth)); + if (NULL == bm) + break; + if (NULL == bmhd) + break; + + argbSrc.argb_Width = bmhd->bmh_Width; + argbSrc.argb_Height = bmhd->bmh_Height; + + (void) GetDTAttrs(ImageObj, + PDTA_MaskPlane, (ULONG) &MaskPlane, + TAG_END); + + d1(KPrintF(__FILE__ "/%s/%ld: MaskPlane=%08lx\n", __FUNC__, __LINE__, MaskPlane)); + + if (GetDTAttrs(ImageObj, + PDTA_NumColors, (ULONG) &NumberOfColors, + PDTA_CRegs, (ULONG) &CRegs, + TAG_END) < 2) + break; + + d1(KPrintF(__FILE__ "/%s/%ld: NumberOfColors=%ld CRegs=%08lx\n", __FUNC__, __LINE__, NumberOfColors, CRegs)); + d1(ByteDump((unsigned char *) CRegs, 128)); + + if (bmhd->bmh_Depth <= 8) + { + argbSrc.argb_ImageData = ScalosGfxCreateARGBFromBitMap(bm, + bmhd->bmh_Width, bmhd->bmh_Height, + NumberOfColors, CRegs, MaskPlane); + + d1(KPrintF(__FILE__ "/%s/%ld: argb_ImageData=%08lx\n", __FUNC__, __LINE__, argbSrc.argb_ImageData)); + if (NULL == argbSrc.argb_ImageData) + break; + } + else + { + BOOL setAlphaOpaque = FALSE; + + argbSrc.argb_ImageData = ScalosGfxCreateARGB(bmhd->bmh_Width, bmhd->bmh_Height, NULL); + d1(KPrintF(__FILE__ "/%s/%ld: argb_ImageData=%08lx\n", __FUNC__, __LINE__, argbSrc.argb_ImageData)); + if (NULL == argbSrc.argb_ImageData) + break; + + d1(KPrintF(__FILE__ "/%s/%ld: bm=%08lx Width=%ld Height=%ld Depth=%ld\n", \ + __FUNC__, __LINE__, bm, GetBitMapAttr(bm, BMA_WIDTH), \ + GetBitMapAttr(bm, BMA_HEIGHT), GetBitMapAttr(bm, BMA_DEPTH))); + + if (CyberGfxBase + && GetBitMapAttr(bm, BMA_DEPTH) > 24 + && GetCyberMapAttr(bm, CYBRMATTR_ISCYBERGFX)) + { + d1(KPrintF(__FILE__ "/%s/%ld: MaskPlane=%08lx bmh_Depth=%ld\n", __FUNC__, __LINE__, MaskPlane, bmhd->bmh_Depth)); + + if (bmhd->bmh_Depth > 24) + { + // for ARGB formats, use Alpha from BitMap instead of MaskPlane + MaskPlane = NULL; + } + else + { + if (NULL == MaskPlane) + setAlphaOpaque = TRUE; + } + } + + if (mskHasAlpha == bmhd->bmh_Masking) + { + DoMethod(ImageObj, + PDTM_READPIXELARRAY, + argbSrc.argb_ImageData, + PBPAFMT_ARGB, + bmhd->bmh_Width * sizeof(struct ARGB), + 0, + 0, + bmhd->bmh_Width, + bmhd->bmh_Height + ); + } + else + { + ScalosGfxFillARGBFromBitMap(&argbSrc, bm, MaskPlane); + } + + if (setAlphaOpaque) + ScalosGfxARGBSetAlpha(&argbSrc, ~0); + } + + d1(ByteDump((unsigned char *) argbSrc.argb_ImageData, 128)); + d1(KPrintF(__FILE__ "/%s/%ld: Result=%08lx\n", __FUNC__, __LINE__, Result)); + + argbDest.argb_Width = ScaledWidth; + argbDest.argb_Height = ScaledHeight; + + DUMP_ARGB_LINE(&argbSrc, Alpha, argbSrc.argb_Height / 2); + + argbDest.argb_ImageData = ScalosGfxScaleARGBArrayTags(&argbSrc, + &argbDest.argb_Width, + &argbDest.argb_Height, + SCALOSGFX_ScaleARGBArrayFlags, ScaleFlags, + TAG_END); + d1(KPrintF(__FILE__ "/%s/%ld: argbDest.argb_ImageData=%08lx\n", __FUNC__, __LINE__, argbDest.argb_ImageData)); + if (NULL == argbDest.argb_ImageData) + break; + + if (!GenerateThumbnailFromARGB(wt, + iconName, &argbDest, + SupportedColors, ReservedColors, + PVResult)) + { + break; + } + + Success = TRUE; + } while (0); + + ScalosGfxFreeARGB(&argbDest.argb_ImageData); + ScalosGfxFreeARGB(&argbSrc.argb_ImageData); + + d1(KPrintF(__FILE__ "/%s/%ld: END Success=%ld\n", __FUNC__, __LINE__, Success)); + + return Success; +} + +//----------------------------------------------------------------------------- + +static BOOL GenerateThumbnailFromARGB(struct ScaWindowTask *wt, + CONST_STRPTR iconName, struct ARGBHeader *argbDest, + ULONG SupportedColors, ULONG ReservedColors, + struct ScalosPreviewResult *PVResult) +{ + d1(KPrintF(__FILE__ "/%s/%ld: START iconName=<%s>\n", __FUNC__, __LINE__, iconName)); + d1(KPrintF(__FILE__ "/%s/%ld: argb_Width=%ld argb_Height=%ld ImageData=%08lx\n", \ + __FUNC__, __LINE__, argbDest->argb_Width, argbDest->argb_Height,\ + argbDest->argb_ImageData)); + d1(KPrintF(__FILE__ "/%s/%ld: SupportedColors=%lu\n", __FUNC__, __LINE__, SupportedColors)); + + if (SupportedColors <= 256) + { + ULONG Depth; + + // Limit color depth to the number of colors supported by the icon + for (Depth = 0; Depth < 7 && (1 << Depth) < SupportedColors; Depth++) + ; + + d1(KPrintF(__FILE__ "/%s/%ld: argb_ImageData: a=%ld r=%ld g=%ld b=%ld\n", \ + __FUNC__, __LINE__, argbDest->argb_ImageData->Alpha, \ + argbDest->argb_ImageData->Red, argbDest->argb_ImageData->Green, \ + argbDest->argb_ImageData->Blue)); + + d1(KPrintF(__FILE__ "/%s/%ld: SupportedColors=%lu Depth=%lu ReservedColors=%lu\n", \ + __FUNC__, __LINE__, SupportedColors, Depth, ReservedColors)); + + PVResult->spvr_sac = ScalosGfxMedianCutTags(argbDest, Depth, + SCALOSGFX_MedianCutFlags, SCALOSGFXFLAGF_MedianCut_FloydSteinberg, + SCALOSGFX_MedianCutFriendBitMap, NULL, + SCALOSGFX_MedianCutReservedColors, ReservedColors, + TAG_END); + d1(KPrintF(__FILE__ "/%s/%ld: sac=%08lx\n", __FUNC__, __LINE__, PVResult->spvr_sac)); + + d1(KPrintF(__FILE__ "/%s/%ld: sac_BitMap=%08lx\n", __FUNC__, __LINE__, PVResult->spvr_sac->sac_BitMap)); + d1(ByteDump((unsigned char *) PVResult->spvr_sac->sac_BitMap, sizeof(struct BitMap))); + } + else + { + DUMP_ARGB_LINE(argbDest, Alpha, argbDest->argb_Height / 2) + PVResult->spvr_ARGBheader = *argbDest; + memset(argbDest, 0, sizeof(*argbDest)); + } + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + if (argbDest) + { + ScalosGfxFreeARGB(&argbDest->argb_ImageData); + } + + d1(KPrintF(__FILE__ "/%s/%ld: END\n", __FUNC__, __LINE__)); + + return TRUE; +} + +//----------------------------------------------------------------------------- + +// Work-around for OS3.0/3.1 and Picasso96 picture.datatype V43.41 +// This datatype seems to understand PMODE_V43, but in combination with +// PDTA_UseFriendBitMap and PDTA_Screen, returns a very weird BitMap +// that I was unable to deal with: Depth=16, but no CyberGfx BitMap +// Looks like an extended standard BitMap with 16 plane pointers. + +static BOOL IsPictureDT43(Object *o) +{ + const ULONG *MethodArray = NULL; + BOOL IsV43 = FALSE; + + GetDTAttrs(o, + DTA_Methods, (ULONG) &MethodArray, + TAG_END); + + while (MethodArray && ~0 != *MethodArray) + { + if (PDTM_SCALE == *MethodArray) + { + IsV43 = TRUE; + break; + } + MethodArray++; + } + + return IsV43; +} + +//----------------------------------------------------------------------------- + +#if BYTEDUMP +static void ByteDump(const unsigned char *Data, size_t Length) +{ + unsigned long count; + unsigned char Line[80], *lp; + + lp = Line; + for (count=0; count + +//--------------------------------------------------------------- + +// Debugging... +#define d(x) ; +#define d1(x) ; +#define d2(x) x; + +// aus debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +//--------------------------------------------------------------- + +#endif /* DEFPICTURE_H */ + diff --git a/scalos/Plugins/Preview/DefPicture/config.mk b/scalos/Plugins/Preview/DefPicture/config.mk new file mode 100755 index 000000000..13457d256 --- /dev/null +++ b/scalos/Plugins/Preview/DefPicture/config.mk @@ -0,0 +1,68 @@ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +COMMON_DIR = $(TOPLEVEL)/common/Plugin + +INCLUDES += -I$(COMMON_DIR) + +vpath %.c $(COMMON_DIR) + +############################################################################## + +include $(COMMON_DIR)/config.mk + +############################################################################## + +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +INCLUDES += # + +LFLAGS += -nostartfiles \ + -ldebug \ + -lmempools +# --verbose + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += -nostartfiles \ +# + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +LFLAGS += -nostartfiles \ +# + +else + +############################################################################### +# AmigaOS + +INCLUDES += # + +LFLAGS += -lmempools \ + -ldebug \ + -lamiga21 \ + -lamiga \ + -lstubs + +endif +endif +endif diff --git a/scalos/Plugins/Preview/DefPicture/makefile b/scalos/Plugins/Preview/DefPicture/makefile new file mode 100755 index 000000000..af24b368f --- /dev/null +++ b/scalos/Plugins/Preview/DefPicture/makefile @@ -0,0 +1,125 @@ +# makefile für Scalos defpicture.pvplugin +# // $Date$ +# // $Revision$ + +############################################################# + +.SUFFIXES: .plugin .plugin.debug .cd + +############################################################# + +.PHONY: clean install nodebug + +############################################################# + +SUBDIRMAKE = $(MAKE) -s -C +#SUBDIRMAKE = smakedir + +PRECOMP = Include:all.gst + +CC = sc +CFLAGS = nostackcheck nochkabort strmer dbg=l nover streq data=far \ + idlen=64 idir=///include \ + idir=///common/Plugin + +############################################################# + +OPT_FLG = OPTIMIZE OPTINLOCAL OPTTIME OPTSCHED IGNORE=306 IGNORE=308 IGNORE=304 +COPTS = NOWVRET NOVERSION nostackcheck idlen=128 idir=///include +OPTIONS = $(OPT_FLG) Math=s DATA=FAR DEBUG=L $(COPTS) def=NDEBUG + +############################################################# + +AS = phxass +SPLAT = sc:c/splat +AFLAGS = quiet noexe m=68020 opt=NRQB i=sc:Assembler_Headers/ +LD = slink +LDFLAGS = quiet batch noicons sd +LDLIBS = LIB:sc.lib LIB:debug.lib LIB:amiga.lib +ASTARTUP = +#CSTARTUP = LIB:c.o + +OBJDIR = .sasobj +CATCOMP = CatComp + +############################################################# + +COMMON_DIR = ../../../common/Plugin + +############################################################# + +CSRCS = $(COMMON_DIR)/plugin-classic.c \ + DefPicture.c + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +XSRCS = $(notdir $(CSRCS)) +OBJS = $(XSRCS:%.c=$(OBJDIR)/$(notdir %).o) + +############################################################# + +PLUGIN = defpicture.pvplugin +DESTTOOL = Scalos:plugins/Preview/ + +############################################################# + +All: $(PLUGIN) \ + $(PLUGIN).debug \ + +############################################################# + +# commands generated a catalog (.catalog) from a catalog translation (.ct) file. +.ct.catalog: + $(CATCOMP) $*.cd $< CATALOG $*.catalog VB=1 + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-classic.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $*.c objectname $@ + +############################################################# + +$(OBJDIR)/plugin-classic.o : plugin_data.h \ + $(COMMON_DIR)/plugin.h $(COMMON_DIR)/plugin-common.c +$(OBJDIR)/DefPicture.o : DefPicture.h $(COMMON_DIR)/plugin.h + +############################################################# + +$(PLUGIN) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) to $@ FROM $(CSTARTUP) $(OBJS) lib $(LDLIBS) $(LDFLAGS) stripdebug + +$(PLUGIN).debug : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) to $@ FROM $(CSTARTUP) $(OBJS) lib $(LDLIBS) $(LDFLAGS) addsym + +############################################################# + +# A little something to clean it all up +clean: + @printf '\033[32mDelete: \033[31m\033[1m' + @delete $(OBJS) $(PLUGIN) $(PLUGIN).debug $(ALLCATS) $(CATCOMPHEADER) + @printf '\033[0m' + +############################################################# + +# copy all generated file to their final destinations +install: + @printf '\033[32mInstall: \033[31m\033[1m$(PLUGIN)\033[0m\n' + @copy $(PLUGIN) $(DESTTOOL) clone + @printf '\033[32mFlushing memory\033[0m\n' + @avail flush + +############################################################# + +nodebug: + -@$(SPLAT) -s -o "d2(" "d1(" "#?.c" + +############################################################# + diff --git a/scalos/Plugins/Preview/DefPicture/makefile-new b/scalos/Plugins/Preview/DefPicture/makefile-new new file mode 100755 index 000000000..6e6940c13 --- /dev/null +++ b/scalos/Plugins/Preview/DefPicture/makefile-new @@ -0,0 +1,73 @@ +# $Date: 2011-07-31 23:57:02 +0200 (So, 31. Jul 2011) $ +# $Revision: 814 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(BEGIN_OBJS) \ + $(OBJDIR)/DefPicture.o \ + $(END_OBJS) + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Targets +# + +NAME = defpicture.pvplugin +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) \ + all_subdirs + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + @$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) Scalos:Plugins/Preview/ clone + @avail flush + +install: install_subdirs + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* + +clean: clean_subdirs + +############################################################################## + + diff --git a/scalos/Plugins/Preview/DefPicture/plugin_data.h b/scalos/Plugins/Preview/DefPicture/plugin_data.h new file mode 100644 index 000000000..7f4c4fe52 --- /dev/null +++ b/scalos/Plugins/Preview/DefPicture/plugin_data.h @@ -0,0 +1,27 @@ +// plugin_data.h +// $Date$ +// $Revision$ + +#ifndef PLUGIN_DATA_H_INCLUDED +#define PLUGIN_DATA_H_INCLUDED + +#include +#include + +#define PLUGIN_TYPE PREVIEW + +#define LIB_VERSION 41 +#define LIB_REVISION 4 + +#define LIB_NAME "defpicture.pvplugin" +#define LIB_VERSTRING "\0$VER: defpicture.pvplugin " \ + STR(LIB_VERSION) "." STR(LIB_REVISION) \ + " (07.11.2009)" \ + COMPILER_STRING " ©2006" CURRENTYEAR \ + " The Scalos Team" + +//---------------------------------------------------------------------------- +// code and includes to define the structs and functions used above + +#endif /* PLUGUN_DATA_H_INCLUDED */ + diff --git a/scalos/Plugins/Preview/JpegPicture/JpegPicture.c b/scalos/Plugins/Preview/JpegPicture/JpegPicture.c new file mode 100755 index 000000000..40ac98bc1 --- /dev/null +++ b/scalos/Plugins/Preview/JpegPicture/JpegPicture.c @@ -0,0 +1,1001 @@ +// JpegPicture.c +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include + +//#define FILE void +#undef GLOBAL + +#include "jpeglib.h" +#include "jerror.h" + +#include "JpegPicture.h" + +//--------------------------------------------------------------------------------------- + +struct JpegErrorInfo +{ + struct jpeg_error_mgr pub; + jmp_buf setjmpbuf; +}; + +//--------------------------------------------------------------------------------------- + +struct GfxBase *GfxBase; +T_UTILITYBASE UtilityBase; +struct Library *CyberGfxBase; +struct DosLibrary *DOSBase; +struct IntuitionBase *IntuitionBase; +struct ScalosGfxBase *ScalosGfxBase; +#ifdef __amigaos4__ +struct GraphicsIFace *IGraphics; +struct UtilityIFace *IUtility; +struct ExecIFace *IExec; +struct CyberGfxIFace *ICyberGfx; +struct DOSIFace *IDOS; +struct IntuitionIFace *IIntuition; +struct ScalosGfxIFace *IScalosGfx; +struct Library *NewlibBase; +struct Interface *INewlib; +#endif /* __amigaos4__ */ + +#if defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__AROS__) +extern T_UTILITYBASE __UtilityBase; +#endif /* defined(__GNUC__) && !defined(__MORPHOS__) */ + +//--------------------------------------------------------------------------------------- + +static BOOL GenerateRemappedThumbnail(struct ScaWindowTask *wt, + CONST_STRPTR iconName, struct jpeg_decompress_struct *cinfo, + JSAMPARRAY buffer, ULONG quality, ULONG ReservedColors, + ULONG ScaledWidth, ULONG ScaledHeight, + struct Screen *WBScreen, struct ScalosPreviewResult *PVResult); +static BOOL GenerateARGBThumbnail(struct ScaWindowTask *wt, + CONST_STRPTR iconName, struct jpeg_decompress_struct *cinfo, + JSAMPARRAY buffer, ULONG quality, + ULONG ScaledWidth, ULONG ScaledHeight, + struct ScalosPreviewResult *PVResult); +static BOOL GenerateARGBFromJPG(struct ARGBHeader *argbSrc, + struct jpeg_decompress_struct *cinfo, JSAMPARRAY buffer); +METHODDEF(void) JpegErrorExit(j_common_ptr cinfo); +METHODDEF(void) JpegOutputDummy(j_common_ptr cinfo); + +//----------------------------------------------------------- + +BOOL initPlugin(struct PluginBase *PluginBase) +{ + BOOL result = FALSE; + + d1(KPrintF("%s/%ld: PluginBase=%08lx procName=<%s>\n", __FUNC__, __LINE__, \ + PluginBase, FindTask(NULL)->tc_Node.ln_Name)); + + do { +#if !defined(__amigaos4__) && !defined(__AROS__) + if (_STI_240_InitMemFunctions()) + break;; +#endif /* __amigaos4__ */ + DOSBase = (APTR) OpenLibrary( "dos.library", 39 ); + if (NULL == DOSBase) + break; + + + UtilityBase = (T_UTILITYBASE) OpenLibrary("utility.library", 39); + if (NULL == UtilityBase) + break; + + CyberGfxBase = OpenLibrary(CYBERGFXNAME, 0); + // CyberGfxBase may be NULL + + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + d1(kprintf("%s/%ld: IntuitionBase=%08lx\n", __FUNC__, __LINE__, IntuitionBase)); + if (NULL == IntuitionBase) + break; + + GfxBase = (struct GfxBase *) OpenLibrary(GRAPHICSNAME, 39); + d1(kprintf("%s/%ld: GfxBase=%08lx\n", __FUNC__, __LINE__, GfxBase)); + if (NULL == GfxBase) + break; + + ScalosGfxBase = (struct ScalosGfxBase *) OpenLibrary(SCALOSGFXNAME, 41); + d1(KPrintF("%s/%ld: ScalosGfxBase=%08lx\n", __FUNC__, __LINE__, ScalosGfxBase)); + if (NULL == ScalosGfxBase) + break; + +#ifdef __amigaos4__ + IDOS = (struct DOSIFace *) GetInterface((struct Library *)DOSBase, "main", 1, NULL); + if (IDOS == NULL) + break; + if (CyberGfxBase != NULL) // CyberGfxBase may be NULL + { + ICyberGfx = (struct CyberGfxIFace *) GetInterface((struct Library *) CyberGfxBase, "main", 1, NULL); + if (ICyberGfx == NULL) + break; + } + IUtility = (struct UtilityIFace *) GetInterface((struct Library *) UtilityBase, "main", 1, NULL); + if (NULL == IUtility) + break; + IIntuition = (struct IntuitionIFace *) GetInterface((struct Library *) IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + break; + IGraphics = (struct GraphicsIFace *) GetInterface((struct Library *) GfxBase, "main", 1, NULL); + if (NULL == IGraphics) + break; + IScalosGfx = (struct ScalosGfxIFace *) GetInterface((struct Library *) ScalosGfxBase, "main", 1, NULL); + if (NULL == IScalosGfx) + break; + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + break; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + break; +#endif /* __amigaos4__ */ + + +#if defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) + __UtilityBase = UtilityBase; +#endif /* defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) */ + + + result = TRUE; + d1(KPrintF("%s/%ld: Success\n", __FUNC__, __LINE__)); + } while (0); + + return result; +} + + +void closePlugin(struct PluginBase *PluginBase) +{ + d1(kprintf("%s/%ld:\n", __FUNC__, __LINE__)); + +#if !defined(__amigaos4__) && !defined(__AROS__) + _STD_240_TerminateMemFunctions(); +#endif + +#ifdef __amigaos4__ + if (INewlib) + { + DropInterface(INewlib); + INewlib = NULL; + } + if (NewlibBase) + { + CloseLibrary(NewlibBase); + NewlibBase = NULL; + } + if (ICyberGfx) + { + DropInterface((struct Interface *)ICyberGfx); + ICyberGfx = NULL; + } + if (IScalosGfx) + { + DropInterface((struct Interface *)IScalosGfx); + IScalosGfx = NULL; + } + if (IGraphics) + { + DropInterface((struct Interface *)IGraphics); + IGraphics = NULL; + } + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } + if (IUtility) + { + DropInterface((struct Interface *)IUtility); + IUtility = NULL; + } + if (IDOS) + { + DropInterface((struct Interface *)IDOS); + IDOS = NULL; + } +#endif /* __amigaos4__ */ + + if (CyberGfxBase) + { + CloseLibrary(CyberGfxBase); + CyberGfxBase = NULL; + } + if (NULL != ScalosGfxBase) + { + CloseLibrary((struct Library *) ScalosGfxBase); + ScalosGfxBase = NULL; + } + if (NULL != GfxBase) + { + CloseLibrary((struct Library *) GfxBase); + GfxBase = NULL; + } + if (NULL != IntuitionBase) + { + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } + + if (NULL != UtilityBase) + { + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } + if (NULL != DOSBase) + { + CloseLibrary((struct Library *) DOSBase); + DOSBase = NULL; + } +} + +//-------------------------------------------------------------------------- + +LIBFUNC_P5(LONG, LIBSCAPreviewGenerate, + A0, struct ScaWindowTask *, wt, + A1, BPTR, dirLock, + A2, CONST_STRPTR, iconName, + A3, struct TagItem *, tagList, + A6, struct PluginBase *, PluginBase) +{ + BPTR fh = (BPTR)NULL; // filehandle for reading of image file + LONG Success = FALSE; + struct jpeg_decompress_struct cinfo; + struct FileInfoBlock *fib = NULL; + BOOL DecompressStarted = FALSE; + APTR FileBuffer = NULL; + + (void) PluginBase; + + d1(KPrintF(__FILE__ "/%s/%ld: START iconName=<%s>\n", __FUNC__, __LINE__, iconName)); + + memset(&cinfo, 0, sizeof(cinfo)); + + do { + struct JpegErrorInfo jerr; + ULONG ThumbnailWidth; + ULONG ThumbnailHeight; + ULONG SupportedColors; + ULONG ScreenDepth; + struct Screen *WBScreen; + struct BitMapHeader *bmhdExternal; + BPTR oldDir; + struct ScalosPreviewResult *PVResult; + JSAMPARRAY buffer; /* Output row buffer */ + size_t BytesPerRow; + BOOL DoRemap; + ULONG quality; + ULONG ReservedColors; + size_t FileSize; + + memset(&jerr, 0, sizeof(jerr)); + + PVResult = (struct ScalosPreviewResult *) GetTagData(SCALOSPREVIEW_ResultStruct, (ULONG)NULL, tagList); + if (NULL == PVResult) + break; + + // clear result + memset(PVResult, 0, sizeof(*PVResult)); + + ThumbnailWidth = GetTagData(SCALOSPREVIEW_ThumbnailWidth, 0, tagList); + if (0 == ThumbnailWidth) + break; + ThumbnailHeight = GetTagData(SCALOSPREVIEW_ThumbnailHeight, 0, tagList); + if (0 == ThumbnailHeight) + break; + + SupportedColors = GetTagData(SCALOSPREVIEW_SupportedColors, 0, tagList); + if (SupportedColors < 16) + break; + + ReservedColors = GetTagData(SCALOSPREVIEW_ReservedColors, 0, tagList); + if (SupportedColors < ReservedColors + 16) + break; + + bmhdExternal = (struct BitMapHeader *) GetTagData(SCALOSPREVIEW_ImgBitMapHeader, (ULONG)NULL, tagList); + quality = GetTagData(SCALOSPREVIEW_Quality, SCALOSPREVIEWA_Quality_Max, tagList); + + WBScreen = (struct Screen *) GetTagData(SCALOSPREVIEW_Screen, (ULONG)NULL, tagList); + if (NULL == WBScreen) + break; + + oldDir = CurrentDir(dirLock); + fh = Open(iconName, MODE_OLDFILE); + CurrentDir(oldDir); + if ((BPTR)NULL == fh) + break; + + fib = AllocDosObject(DOS_FIB, NULL); + if (NULL == fib) + break; + + if (!ExamineFH(fh, fib)) + break; + + FileSize = fib->fib_Size; + + FileBuffer = malloc(FileSize); + if (NULL == FileBuffer) + break; + + // Read entire file into FileBuffer + if (FileSize != Read(fh, FileBuffer, FileSize)) + break; + + ScreenDepth = GetBitMapAttr(WBScreen->RastPort.BitMap, BMA_DEPTH); + + DoRemap = (ScreenDepth <= 8) || (NULL == CyberGfxBase) || SupportedColors <= 256; + + d1(KPrintF(__FILE__ "/%s/%ld: DoRemap=%ld\n", __FUNC__, __LINE__, DoRemap)); + + // Initialize the JPEG decompression object with default error handling. + cinfo.err = jpeg_std_error(&jerr.pub); + + // set out own error handler + jerr.pub.error_exit = JpegErrorExit; + jerr.pub.output_message = JpegOutputDummy; + + if(!setjmp(jerr.setjmpbuf)) + { + /* Here we are after setting the long jump */ + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + jpeg_create_decompress(&cinfo); + + // set memory as data source + jpeg_mem_src(&cinfo, FileBuffer, FileSize); + + // obtain image info + jpeg_read_header(&cinfo, TRUE); + +// cinfo.mem->max_memory_to_use = ???; + + d1(KPrintF(__FILE__ "/%s/%ld: ImageWidth=%ld ImageHeight=%ld jpeg_color_space=%ld\n", \ + __FUNC__, __LINE__, cinfo.image_width, cinfo.image_height, cinfo.jpeg_color_space)); + + if (bmhdExternal) + { + bmhdExternal->bmh_Width = cinfo.image_width; + bmhdExternal->bmh_Height = cinfo.image_height; + bmhdExternal->bmh_Depth = 24; + } + + cinfo.dct_method = JDCT_IFAST; + cinfo.do_fancy_upsampling = FALSE; + cinfo.do_block_smoothing = FALSE; + if (JCS_GRAYSCALE == cinfo.jpeg_color_space) + cinfo.out_color_space = JCS_GRAYSCALE; + else + cinfo.out_color_space = JCS_RGB; + + d1(KPrintF(__FILE__ "/%s/%ld: SupportedColors=%ld ReservedColors=%ld\n", __FUNC__, __LINE__, SupportedColors, ReservedColors)); + + if (DoRemap) + { + cinfo.desired_number_of_colors = SupportedColors; + if (cinfo.desired_number_of_colors > 128) + cinfo.desired_number_of_colors = 128; + cinfo.desired_number_of_colors += ReservedColors; + //cinfo.desired_number_of_colors = SupportedColors - ReservedColors; + + cinfo.quantize_colors = TRUE; + cinfo.dither_mode = JDITHER_FS; + cinfo.two_pass_quantize = (quality > 7) ? TRUE : FALSE; + } + + ScalosGfxCalculateScaleAspect(cinfo.image_width, cinfo.image_height, + &ThumbnailWidth, &ThumbnailHeight); + + // try to scale image as small as possible, + // but not smaller than thumbnail + if (cinfo.image_width >= 8 * ThumbnailWidth + && cinfo.image_height >= 8 * ThumbnailHeight) + { + cinfo.scale_num = 1; + cinfo.scale_denom = 8; + } + else if (cinfo.image_width >= 4 * ThumbnailWidth + && cinfo.image_height >= 4 * ThumbnailHeight) + { + cinfo.scale_num = 1; + cinfo.scale_denom = 4; + } + else if (cinfo.image_width >= 2 * ThumbnailWidth + && cinfo.image_height >= 2 * ThumbnailHeight) + { + cinfo.scale_num = 1; + cinfo.scale_denom = 2; + } + + d1(KPrintF(__FILE__ "/%s/%ld: ImageWidth=%ld ImageHeight=%ld\n", __FUNC__, __LINE__, cinfo.image_width, cinfo.image_height)); + d1(KPrintF(__FILE__ "/%s/%ld: ThumbnailWidth=%ld ThumbnailHeight=%ld\n", __FUNC__, __LINE__, ThumbnailWidth, ThumbnailHeight)); + + jpeg_start_decompress(&cinfo); + + d1(KPrintF(__FILE__ "/%s/%ld: after jpeg_start_decompress\n", __FUNC__, __LINE__)); + d1(KPrintF(__FILE__ "/%s/%ld: output_width=%ld output_height=%ld\n", __FUNC__, __LINE__, cinfo.output_width, cinfo.output_height)); + + /* JSAMPLEs per row in output buffer */ + BytesPerRow = cinfo.output_width * cinfo.output_components; + /* Make a one-row-high sample array that will go away when done with image */ + buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, BytesPerRow, 1); + + if (DoRemap) + { + d1(KPrintF(__FILE__ "/%s/%ld: colormap=%08lx actual_number_of_colors=%ld\n", \ + __FUNC__, __LINE__, cinfo.colormap, cinfo.actual_number_of_colors)); + + Success = GenerateRemappedThumbnail(wt, + iconName, &cinfo, buffer, quality, ReservedColors, + ThumbnailWidth, ThumbnailHeight, + WBScreen, PVResult); + } + else + { + Success = GenerateARGBThumbnail(wt, + iconName, &cinfo, buffer, quality, + ThumbnailWidth, ThumbnailHeight, + PVResult); + } + } + } while (0); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + if (DecompressStarted) + jpeg_finish_decompress(&cinfo); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + jpeg_destroy_decompress(&cinfo); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + if (fh) + Close(fh); + + if (fib) + FreeDosObject(DOS_FIB, fib); + + if (FileBuffer) + free(FileBuffer); + + d1(KPrintF(__FILE__ "/%s/%ld: END Success=%ld\n", __FUNC__, __LINE__, Success)); + + return Success; +} +LIBFUNC_END + +//---------------------------------------------------------------------------- + +#ifndef __amigaos4__ +void _XCEXIT(long x) +{ +} + +//---------------------------------------------------------------------------- + +#ifndef __SASC +// Replacement for SAS/C library functions + +void exit(int x) +{ + (void) x; + while (1) + ; +} + +APTR _WBenchMsg; + +#endif /* __SASC */ + +#endif /* __amigaos4__ */ + +//----------------------------------------------------------------------------- + +static BOOL GenerateRemappedThumbnail(struct ScaWindowTask *wt, + CONST_STRPTR iconName, struct jpeg_decompress_struct *cinfo, + JSAMPARRAY buffer, ULONG quality, ULONG ReservedColors, + ULONG ScaledWidth, ULONG ScaledHeight, + struct Screen *WBScreen, struct ScalosPreviewResult *PVResult) +{ + BOOL Success = FALSE; + struct ScalosBitMapAndColor *sacSrc = NULL; + struct ScalosBitMapAndColor *sacDest = NULL; + struct BitMap *TempBM = NULL; + + d1(KPrintF(__FILE__ "/%s/%ld: START\n", __FUNC__, __LINE__)); + + do { + ULONG n; + struct ScaleBitMapArg sbma; + struct RastPort rp; + struct RastPort TempRp; + ULONG y; + + if (cinfo->actual_number_of_colors > 256) + break; + if (NULL == cinfo->colormap) + break; + + sacSrc = ScalosGfxCreateSAC(cinfo->output_width, + cinfo->output_height, + 8, + NULL, //WBScreen->RastPort.BitMap, + NULL); + if (NULL == sacSrc) + break; + + // Fill sac->sac_ColorTable from cinfo->colormap + switch (cinfo->out_color_components) + { + case 3: // RGB + for (n = 0; n < cinfo->actual_number_of_colors; n++) + { + sacSrc->sac_ColorTable[3 * n + 0] = RGB_8_TO_32(cinfo->colormap[0][n]); // Red + sacSrc->sac_ColorTable[3 * n + 1] = RGB_8_TO_32(cinfo->colormap[1][n]); // Green + sacSrc->sac_ColorTable[3 * n + 2] = RGB_8_TO_32(cinfo->colormap[2][n]); // Blue + + d1(KPrintF(__FILE__ "/%s/%ld: n=%ld R=%08lx G=%08lx B=%08lx\n", \ + __FUNC__, __LINE__, n, sacSrc->sac_ColorTable[3 * n + 0], \ + sacSrc->sac_ColorTable[3 * n + 1], \ + sacSrc->sac_ColorTable[3 * n + 2])); + } + break; + case 1: // grayscale + for (n = 0; n < cinfo->actual_number_of_colors; n++) + { + sacSrc->sac_ColorTable[3 * n + 0] = + sacSrc->sac_ColorTable[3 * n + 1] = + sacSrc->sac_ColorTable[3 * n + 2] = RGB_8_TO_32(cinfo->colormap[0][n]); // Gray R/G/B + } + break; + default: + break; + } + + d1(KPrintF(__FILE__ "/%s/%ld: ImageWidth=%ld ImageHeight=%ld\n", __FUNC__, __LINE__, cinfo->output_width, cinfo->output_height)); + d1(KPrintF(__FILE__ "/%s/%ld: actual_number_of_colors=%ld sac_ColorTable=%08lx\n", __FUNC__, __LINE__, cinfo->actual_number_of_colors, sacSrc->sac_ColorTable)); + d1(KPrintF(__FILE__ "/%s/%ld: out_color_components=%ld output_components=%ld colormap=%08lx\n", __FUNC__, __LINE__, cinfo->out_color_components, cinfo->output_components, cinfo->colormap)); + + sacSrc->sac_TransparentColor = SAC_TRANSPARENT_NONE; + + InitRastPort(&rp); + rp.BitMap = sacSrc->sac_BitMap; + + InitRastPort(&TempRp); + TempRp = rp; + TempRp.Layer = NULL; + TempRp.BitMap = TempBM = AllocBitMap(TEMPRP_WIDTH(cinfo->output_width), 1, 8, 0, NULL); + if (NULL == TempBM) + break; + + y = 0; + + d1(KPrintF(__FILE__ "/%s/%ld: output_width=%ld output_height=%ld\n", __FUNC__, __LINE__, cinfo->output_width, cinfo->output_height)); + + /* Here we use the library's state variable cinfo.output_scanline as the + * loop counter, so that we don't have to keep track ourselves. + */ + while (cinfo->output_scanline < cinfo->output_height) + { + JDIMENSION num_scanlines; + + /* jpeg_read_scanlines expects an array of pointers to scanlines. + * Here the array is only one element long, but you could ask for + * more than one scanline at a time if that's more convenient. + */ + num_scanlines = jpeg_read_scanlines(cinfo, buffer, 1); + + while (num_scanlines--) + { + UBYTE *srcPtr = buffer[0]; + + WritePixelLine8(&rp, + 0, y, + cinfo->output_width, + srcPtr, + &TempRp); + y++; + } + } + + d1(KPrintF(__FILE__ "/%s/%ld: actual_number_of_colors=%ld\n", __FUNC__, __LINE__, cinfo->actual_number_of_colors)); + + sbma.sbma_SourceBM = sacSrc->sac_BitMap; + sbma.sbma_SourceWidth = cinfo->output_width; + sbma.sbma_SourceHeight = cinfo->output_height; + sbma.sbma_DestWidth = &ScaledWidth; + sbma.sbma_DestHeight = &ScaledHeight; + sbma.sbma_NumberOfColors = cinfo->actual_number_of_colors + ReservedColors; + sbma.sbma_ColorTable = sacSrc->sac_ColorTable; + sbma.sbma_ScreenBM = WBScreen->RastPort.BitMap; + sbma.sbma_Flags = SCALEFLAGF_DOUBLESIZE | SCALEFLAGF_AVERAGE; + + if (quality >= (3 * SCALOSPREVIEWA_Quality_Max) / 4) + { + sbma.sbma_Flags |= SCALEFLAGF_BICUBIC; + } + else if (quality >= SCALOSPREVIEWA_Quality_Max / 2) + { + sbma.sbma_Flags |= SCALEFLAGF_BILINEAR; + } + + sacDest = ScalosGfxCreateEmptySAC(); + if (NULL == sacDest) + break; + + sacDest->sac_BitMap = ScalosGfxScaleBitMap(&sbma, NULL); + d1(KPrintF(__FILE__ "/%s/%ld: sac_BitMap=%08lx\n", __FUNC__, __LINE__, sacDest->sac_BitMap)); + if (NULL == sacDest->sac_BitMap) + break; + + sacDest->sac_NumColors = cinfo->actual_number_of_colors + ReservedColors; + sacDest->sac_TransparentColor = sacSrc->sac_TransparentColor; + sacDest->sac_Width = ScaledWidth; + sacDest->sac_Height = ScaledHeight; + sacDest->sac_Depth = GetBitMapAttr(sacDest->sac_BitMap, BMA_DEPTH); + + // move sac_ColorTable from sacSrc to sacDest + // in order to avoid copying + sacDest->sac_ColorTable = sacSrc->sac_ColorTable; + sacSrc->sac_ColorTable = NULL; + + d1(KPrintF(__FILE__ "/%s/%ld: sac_NumColors=%lu sac_TransparentColor=%lu\n", \ + __FUNC__, __LINE__, sacDest->sac_NumColors, sacDest->sac_TransparentColor)); + + PVResult->spvr_sac = sacDest; + sacDest = NULL; // do not free sac now + + Success = TRUE; + } while (0); + + if (TempBM) + FreeBitMap(TempBM); + + ScalosGfxFreeSAC(sacSrc); + ScalosGfxFreeSAC(sacDest); + + d1(KPrintF(__FILE__ "/%s/%ld: END Success=%08lx\n", __FUNC__, __LINE__, Success)); + + return Success; +} + +//----------------------------------------------------------------------------- + +static BOOL GenerateARGBThumbnail(struct ScaWindowTask *wt, + CONST_STRPTR iconName, struct jpeg_decompress_struct *cinfo, + JSAMPARRAY buffer, ULONG quality, + ULONG ScaledWidth, ULONG ScaledHeight, + struct ScalosPreviewResult *PVResult) +{ + BOOL Success = FALSE; + struct ARGBHeader argbSrc = { 0, 0, NULL }; + struct ARGBHeader argbDest = { 0, 0, NULL }; + + d1(KPrintF(__FILE__ "/%s/%ld: START\n", __FUNC__, __LINE__)); + + do { + ULONG ScaleFlags = SCALEFLAGF_DOUBLESIZE; + + if (quality >= (3 * SCALOSPREVIEWA_Quality_Max) / 4) + { + ScaleFlags |= SCALEFLAGF_BICUBIC; + } + else if (quality >= SCALOSPREVIEWA_Quality_Max / 2) + { + ScaleFlags |= SCALEFLAGF_BILINEAR; + } + else + { + ScaleFlags |= SCALEFLAGF_AVERAGE; + } + + if (!GenerateARGBFromJPG(&argbSrc, cinfo, buffer)) + { + d1(KPrintF(__FILE__ "/%s/%ld: GenerateARGBFromJPG failed\n", __FUNC__, __LINE__)); + break; + } + + argbDest.argb_Width = ScaledWidth; + argbDest.argb_Height = ScaledHeight; + + argbDest.argb_ImageData = ScalosGfxScaleARGBArrayTags(&argbSrc, + &argbDest.argb_Width, + &argbDest.argb_Height, + SCALOSGFX_ScaleARGBArrayFlags, ScaleFlags, + TAG_END); + d1(KPrintF(__FILE__ "/%s/%ld: argbDest.argb_ImageData=%08lx\n", __FUNC__, __LINE__, argbDest.argb_ImageData)); + if (NULL == argbDest.argb_ImageData) + break; + + PVResult->spvr_ARGBheader = argbDest; + memset(&argbDest, 0, sizeof(argbDest)); + + Success = TRUE; + } while (0); + + ScalosGfxFreeARGB(&argbDest.argb_ImageData); + ScalosGfxFreeARGB(&argbSrc.argb_ImageData); + + d1(KPrintF(__FILE__ "/%s/%ld: END Success=%ld\n", __FUNC__, __LINE__, Success)); + + return Success; +} + +//----------------------------------------------------------------------------- + +static BOOL GenerateARGBFromJPG(struct ARGBHeader *argbSrc, + struct jpeg_decompress_struct *cinfo, JSAMPARRAY buffer) +{ + BOOL Success = FALSE; + + d1(KPrintF(__FILE__ "/%s/%ld: START\n", __FUNC__, __LINE__)); + + do { + struct ARGB *destPtr; + ULONG y; + + argbSrc->argb_Width = cinfo->output_width; + argbSrc->argb_Height = cinfo->output_height; + argbSrc->argb_ImageData = ScalosGfxCreateARGB(argbSrc->argb_Width, argbSrc->argb_Height, NULL); + d1(KPrintF(__FILE__ "/%s/%ld: argb_ImageData=%08lx\n", __FUNC__, __LINE__, argbSrc->argb_ImageData)); + if (NULL == argbSrc->argb_ImageData) + break; + + destPtr = argbSrc->argb_ImageData; + y = 0; + + d1(KPrintF(__FILE__ "/%s/%ld: output_width=%ld output_height=%ld\n", __FUNC__, __LINE__, cinfo->output_width, cinfo->output_height)); + + /* Here we use the library's state variable cinfo.output_scanline as the + * loop counter, so that we don't have to keep track ourselves. + */ + while (cinfo->output_scanline < cinfo->output_height) + { + JDIMENSION num_scanlines; + + /* jpeg_read_scanlines expects an array of pointers to scanlines. + * Here the array is only one element long, but you could ask for + * more than one scanline at a time if that's more convenient. + */ + num_scanlines = jpeg_read_scanlines(cinfo, buffer, 1); + + while (num_scanlines--) + { + ULONG x; + const UBYTE *srcPtr = buffer[0]; + + switch (cinfo->out_color_space) + { + case JCS_RGB: + for (x = 0; x < cinfo->output_width; x++) + { + destPtr->Alpha = 0xff; + destPtr->Red = *srcPtr++; + destPtr->Green = *srcPtr++; + destPtr->Blue = *srcPtr++; + + destPtr++; + } + break; + case JCS_GRAYSCALE: + for (x = 0; x < cinfo->output_width; x++) + { + destPtr->Alpha = 0xff; + destPtr->Red = *srcPtr; + destPtr->Green = *srcPtr; + destPtr->Blue = *srcPtr; + + srcPtr++; + destPtr++; + } + break; + default: + break; + } + y++; + } + } + + Success = TRUE; + } while (0); + + d1(KPrintF(__FILE__ "/%s/%ld: Success=%ld\n", __FUNC__, __LINE__, Success)); + + return Success; +} + +//----------------------------------------------------------------------------- +#if 1 +FILE *fopen(const char *name, const char *mode) +{ + LONG accessMode; + FILE *fh; + + d1(kprintf("%s/%ld: name=<%s> mode=<%s>\n", __FUNC__, __LINE__, name, mode)); + + errno = 0; + + if ('r' == *mode) + accessMode = MODE_OLDFILE; + else + accessMode = MODE_NEWFILE; + + fh = (FILE *) Open((STRPTR) name, accessMode); + + d1(kprintf("%s/%ld: name=<%s> mode=<%s> fh=%08lx\n", __FUNC__, __LINE__, name, mode, fh)); + if (NULL == fh) + { + LONG error = IoErr(); + + d1(kprintf("%s/%ld: error=%ld\n", __FUNC__, __LINE__, error)); + + if (ERROR_OBJECT_NOT_FOUND == error) + errno = ENOENT; + else + errno = EIO; + } + + return fh; +} +#endif +//----------------------------------------------------------------------------- +#if 1 +int fclose(FILE *fh) +{ + d1(kprintf("%s/%ld: fh=%08lx\n", __FUNC__, __LINE__, fh)); + + errno = 0; + + return Close((BPTR) fh) ? 0 : -1; +} +#endif +//----------------------------------------------------------------------------- +#if 1 +size_t fread(void *buf, size_t length, size_t nobj, FILE *fh) +{ + d1(KPrintF(__FILE__ "/%s/%ld: fh=%08lx buf=%08lx nobj=%lu length=%lu\n", \ + __FUNC__, __LINE__, fh, buf, nobj, length)); + + errno = 0; + + return (size_t) FRead((BPTR) fh, buf, length, nobj); +} +#endif +//----------------------------------------------------------------------------- +#if 1 +size_t fwrite(const void *buf, size_t length, size_t nobj, FILE *fh) +{ + d1(KPrintF(__FILE__ "/%s/%ld: fh=%08lx buf=%08lx nobj=%lu length=%lu\n", \ + __FUNC__, __LINE__, fh, buf, nobj, length)); + + return (size_t) FWrite((BPTR) fh, (STRPTR) buf, length, nobj); +} +#endif +//----------------------------------------------------------------------------- +#if 1 +int fseek(FILE *fh, long offset, int origin) +{ + LONG OldPos; + LONG mode; + + d1(KPrintF(__FILE__ "/%s/%ld: fh=%08lx offset=%ld origin=%ld\n", \ + __FUNC__, __LINE__, fh, offset, origin)); + + switch (origin) + { + case SEEK_SET: + mode = OFFSET_BEGINNING; + break; + case SEEK_CUR: + mode = OFFSET_CURRENT; + break; + case SEEK_END: + mode = OFFSET_END; + break; + default: + return -1; + break; + } + + errno = 0; + + OldPos = Seek((BPTR) fh, offset, mode); + d1(kprintf("%s/%ld: OldPos=%ld\n", __FUNC__, __LINE__, OldPos)); + + return OldPos >= 0 ? 0 : -1; +} +#endif +//----------------------------------------------------------------------------- + +int unlink(const char *FileName) +{ + d1(kprintf("%s/%ld: FileName=<%s>\n", __FUNC__, __LINE__, FileName)); + + errno = 0; + + return DeleteFile(FileName) ? 0 : -1; +} + +//----------------------------------------------------------------------------- + +int fprintf(FILE *fh, const char *fmt, ...) +{ + (void) fh; + (void) fmt; + + return 0; +} + +//----------------------------------------------------------------------------- + +// libjpeg Error manager, long jumps back to main to do the necessary cleanup +METHODDEF(void) JpegErrorExit(j_common_ptr cinfo) +{ + struct JpegErrorInfo *jerr = (struct JpegErrorInfo *) cinfo->err; + + d1(kprintf("%s/%ld: msg_code=%08lx\n", __FUNC__, __LINE__, cinfo->err->msg_code)); + + /* Always display the message */ + (*cinfo->err->output_message) (cinfo); + + /* Let the memory manager delete any temp files before we die */ + jpeg_destroy(cinfo); + + longjmp(jerr->setjmpbuf, 1); +} + +// libjpeg dummy error message output +METHODDEF(void) JpegOutputDummy(j_common_ptr cinfo) +{ + char buffer[JMSG_LENGTH_MAX]; + + (*cinfo->err->format_message) (cinfo, buffer); + + d1(kprintf("%s\n", buffer)); +} + +//----------------------------------------------------------------------------- + +#if !defined(__amigaos4__) && !defined(__AROS__) +int errno = 0; +#endif + +#if 1 +//int stderr = 0; + FILE **__sF; +#endif + +//----------------------------------------------------------------------------- + diff --git a/scalos/Plugins/Preview/JpegPicture/JpegPicture.h b/scalos/Plugins/Preview/JpegPicture/JpegPicture.h new file mode 100755 index 000000000..275203d71 --- /dev/null +++ b/scalos/Plugins/Preview/JpegPicture/JpegPicture.h @@ -0,0 +1,35 @@ +// JpegPicture.h +// $Date$ +// $Revision$ + +#ifndef JPEGPICTURE_H +#define JPEGPICTURE_H + +//--------------------------------------------------------------- + +#include "plugin.h" + +//--------------------------------------------------------------- + +// Debugging... +#define d(x) ; +#define d1(x) ; +#define d2(x) x; + +// aus debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +//--------------------------------------------------------------- + +// defined in mempools.lib + +#ifndef __amigaos4__ +extern int _STI_240_InitMemFunctions(void); +extern void _STD_240_TerminateMemFunctions(void); +#endif + +//---------------------------------------------------------------------------- + +#endif /* JPEGPICTURE_H */ + diff --git a/scalos/Plugins/Preview/JpegPicture/config.mk b/scalos/Plugins/Preview/JpegPicture/config.mk new file mode 100755 index 000000000..1484d8a06 --- /dev/null +++ b/scalos/Plugins/Preview/JpegPicture/config.mk @@ -0,0 +1,75 @@ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +COMMON_DIR = $(TOPLEVEL)/common/Plugin + +INCLUDES += -I$(COMMON_DIR) + +vpath %.c $(COMMON_DIR) + +############################################################################## + +include $(COMMON_DIR)/config.mk + +############################################################################## + +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +INCLUDES += # + +LFLAGS := -nostartfiles \ + -ljpeg \ + -lmempools \ + $(LFLAGS) \ +# -Wl,-Map,jpegpicture.map \ +# --verbose \ + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += -nostartfiles \ + -ljpeg8 \ +# + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +LFLAGS += -nostartfiles \ + -ljpeg \ +# + + +else + +############################################################################### +# AmigaOS + +INCLUDES += # + +LFLAGS += -lmempools \ + -ljpeg \ + -ldebug \ + -lamiga21 \ + -lamiga \ + -lstubs + +endif +endif +endif diff --git a/scalos/Plugins/Preview/JpegPicture/makefile b/scalos/Plugins/Preview/JpegPicture/makefile new file mode 100755 index 000000000..e0ea47810 --- /dev/null +++ b/scalos/Plugins/Preview/JpegPicture/makefile @@ -0,0 +1,131 @@ +# makefile für Scalos JpegPicture.pvplugin +# // $Date$ +# // $Revision$ + +############################################################# + +.SUFFIXES: .plugin .plugin.debug .cd + +############################################################# + +.PHONY: clean install nodebug + +############################################################# + +SUBDIRMAKE = $(MAKE) -s -C +#SUBDIRMAKE = smakedir + +PRECOMP = Include:all.gst + +CC = sc +CFLAGS = nostackcheck nochkabort strmer dbg=l nover streq data=far \ + idlen=64 idir=///include \ + idir=///common/Plugin + +############################################################# + +OPT_FLG = OPTIMIZE OPTINLOCAL OPTTIME OPTSCHED IGNORE=306 IGNORE=308 IGNORE=304 +COPTS = NOWVRET NOVERSION nostackcheck idlen=128 idir=///include +OPTIONS = $(OPT_FLG) Math=s DATA=FAR DEBUG=L $(COPTS) def=NDEBUG + +############################################################# + +AS = phxass +SPLAT = sc:c/splat +AFLAGS = quiet noexe m=68020 opt=NRQB i=sc:Assembler_Headers/ +LD = slink +LDFLAGS = quiet batch noicons sd +LDLIBS = ///SAS-lib/libjpeg.lib \ + LIB:mempools.lib \ + LIB:scm.lib \ + LIB:sc.lib \ + LIB:debug.lib \ + LIB:amiga.lib +ASTARTUP = +#CSTARTUP = LIB:c.o + +OBJDIR = .sasobj +CATCOMP = CatComp + +############################################################# + +COMMON_DIR = ../../../common/Plugin + +############################################################# + +CSRCS = $(COMMON_DIR)/plugin-classic.c \ + JpegPicture.c + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +XSRCS = $(notdir $(CSRCS)) +OBJS = $(XSRCS:%.c=$(OBJDIR)/$(notdir %).o) + +############################################################# + +PLUGIN = jpegpicture.pvplugin +DESTTOOL = Scalos:plugins/Preview/ + +############################################################# + +All: $(PLUGIN) \ + $(PLUGIN).debug \ + +############################################################# + +# commands generated a catalog (.catalog) from a catalog translation (.ct) file. +.ct.catalog: + $(CATCOMP) $*.cd $< CATALOG $*.catalog VB=1 + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-classic.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $*.c objectname $@ + +############################################################# + +$(OBJDIR)/plugin-classic.o : plugin_data.h \ + $(COMMON_DIR)/plugin.h $(COMMON_DIR)/plugin-common.c + +$(OBJDIR)/JpegPicture.o : JpegPicture.h $(COMMON_DIR)/plugin.h + +############################################################# + +$(PLUGIN) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) to $@ FROM $(CSTARTUP) $(OBJS) lib $(LDLIBS) $(LDFLAGS) stripdebug + +$(PLUGIN).debug : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) to $@ FROM $(CSTARTUP) $(OBJS) lib $(LDLIBS) $(LDFLAGS) addsym + +############################################################# + +# A little something to clean it all up +clean: + @printf '\033[32mDelete: \033[31m\033[1m' + @delete $(OBJS) $(PLUGIN) $(PLUGIN).debug $(ALLCATS) $(CATCOMPHEADER) + @printf '\033[0m' + +############################################################# + +# copy all generated file to their final destinations +install: + @printf '\033[32mInstall: \033[31m\033[1m$(PLUGIN)\033[0m\n' + @copy $(PLUGIN) $(DESTTOOL) clone + @printf '\033[32mFlushing memory\033[0m\n' + @avail flush + +############################################################# + +nodebug: + -@$(SPLAT) -s -o "d2(" "d1(" "#?.c" + +############################################################# + diff --git a/scalos/Plugins/Preview/JpegPicture/makefile-new b/scalos/Plugins/Preview/JpegPicture/makefile-new new file mode 100755 index 000000000..0457bc61c --- /dev/null +++ b/scalos/Plugins/Preview/JpegPicture/makefile-new @@ -0,0 +1,73 @@ +# $Date: 2011-07-31 23:57:02 +0200 (So, 31. Jul 2011) $ +# $Revision: 814 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(BEGIN_OBJS) \ + $(OBJDIR)/JpegPicture.o \ + $(END_OBJS) + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Targets +# + +NAME = jpegpicture.pvplugin +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) \ + all_subdirs + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + @$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) Scalos:Plugins/Preview/ clone + @avail flush + +install: install_subdirs + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* + +clean: clean_subdirs + +############################################################################## + + diff --git a/scalos/Plugins/Preview/JpegPicture/plugin_data.h b/scalos/Plugins/Preview/JpegPicture/plugin_data.h new file mode 100644 index 000000000..58936d559 --- /dev/null +++ b/scalos/Plugins/Preview/JpegPicture/plugin_data.h @@ -0,0 +1,27 @@ +// plugin_data.h +// $Date$ +// $Revision$ + +#ifndef PLUGIN_DATA_H_INCLUDED +#define PLUGIN_DATA_H_INCLUDED + +#include +#include + +#define PLUGIN_TYPE PREVIEW + +#define LIB_VERSION 41 +#define LIB_REVISION 2 + +#define LIB_NAME "jpegpicture.pvplugin" +#define LIB_VERSTRING "\0$VER: jpegpicture.pvplugin " \ + STR(LIB_VERSION) "." STR(LIB_REVISION) \ + " (07.11.2009)" \ + COMPILER_STRING " ©2006" CURRENTYEAR \ + " The Scalos Team" + +//---------------------------------------------------------------------------- +// code and includes to define the structs and functions used above + +#endif /* PLUGUN_DATA_H_INCLUDED */ + diff --git a/scalos/Plugins/Preview/PNGPicture/PNGPicture.c b/scalos/Plugins/Preview/PNGPicture/PNGPicture.c new file mode 100755 index 000000000..2fe4c9815 --- /dev/null +++ b/scalos/Plugins/Preview/PNGPicture/PNGPicture.c @@ -0,0 +1,785 @@ +// PNGPicture.c +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include + +//#define FILE void +#undef GLOBAL + +#include "png.h" + +#include "PNGPicture.h" + +//--------------------------------------------------------------------------------------- + +struct ImageInfo + { + LONG image_width; + LONG image_height; + }; + +//--------------------------------------------------------------------------------------- + +struct GfxBase *GfxBase; +T_UTILITYBASE UtilityBase; +struct Library *CyberGfxBase; +struct DosLibrary *DOSBase; +struct IntuitionBase *IntuitionBase; +struct ScalosGfxBase *ScalosGfxBase; +#ifdef __amigaos4__ +struct GraphicsIFace *IGraphics; +struct UtilityIFace *IUtility; +struct ExecIFace *IExec; +struct CyberGfxIFace *ICyberGfx; +struct DOSIFace *IDOS; +struct IntuitionIFace *IIntuition; +struct ScalosGfxIFace *IScalosGfx; +struct Library *NewlibBase; +struct Interface *INewlib; +#endif /* __amigaos4__ */ + +#if defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__AROS__) +extern T_UTILITYBASE __UtilityBase; +#endif /* defined(__GNUC__) && !defined(__MORPHOS__) */ + +//--------------------------------------------------------------------------------------- + +static void *PngMemPool; +static struct SignalSemaphore PngMemPoolSemaphore; + +//--------------------------------------------------------------------------------------- + +static BOOL GenerateThumbnailFromARGB(struct ScaWindowTask *wt, + struct ARGBHeader *argbDest, ULONG quality, + ULONG ScaledWidth, ULONG ScaledHeight, + ULONG SupportedColors, ULONG ReservedColors, + struct ScalosPreviewResult *PVResult); +static BOOL GenerateARGBThumbnail(struct ScaWindowTask *wt, + const struct ARGBHeader *argbh, ULONG quality, + ULONG ScaledWidth, ULONG ScaledHeight, + struct ScalosPreviewResult *PVResult); +static png_voidp PngAllocMem(png_structp png_ptr, png_size_t size); +static void PngFreeMem(png_structp png_ptr, png_voidp ptr); +static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length); +static void PngError(png_structp png_ptr, png_const_charp error_message); +static void PngWarning(png_structp png_ptr, png_const_charp warning_message); +static APTR MyAllocVecPooled(size_t Size); +static void MyFreeVecPooled(APTR mem); + +//----------------------------------------------------------- + +BOOL initPlugin(struct PluginBase *PluginBase) +{ + BOOL result = FALSE; + + d1(KPrintF("%s/%ld: PluginBase=%08lx procName=<%s>\n", __FUNC__, __LINE__, \ + PluginBase, FindTask(NULL)->tc_Node.ln_Name)); + + do { + InitSemaphore(&PngMemPoolSemaphore); + +#if !defined(__amigaos4__) && !defined(__AROS__) + if (_STI_240_InitMemFunctions()) + break;; +#endif /* __amigaos4__ */ + DOSBase = (APTR) OpenLibrary( "dos.library", 39 ); + if (NULL == DOSBase) + break; + + + UtilityBase = (T_UTILITYBASE) OpenLibrary("utility.library", 39); + if (NULL == UtilityBase) + break; + + CyberGfxBase = OpenLibrary(CYBERGFXNAME, 0); + // CyberGfxBase may be NULL + + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + d1(kprintf("%s/%ld: IntuitionBase=%08lx\n", __FUNC__, __LINE__, IntuitionBase)); + if (NULL == IntuitionBase) + break; + + GfxBase = (struct GfxBase *) OpenLibrary(GRAPHICSNAME, 39); + d1(kprintf("%s/%ld: GfxBase=%08lx\n", __FUNC__, __LINE__, GfxBase)); + if (NULL == GfxBase) + break; + + ScalosGfxBase = (struct ScalosGfxBase *) OpenLibrary(SCALOSGFXNAME, 41); + d1(KPrintF("%s/%ld: ScalosGfxBase=%08lx\n", __FUNC__, __LINE__, ScalosGfxBase)); + if (NULL == ScalosGfxBase) + break; + +#ifdef __amigaos4__ + IDOS = (struct DOSIFace *) GetInterface((struct Library *)DOSBase, "main", 1, NULL); + if (IDOS == NULL) + break; + if (CyberGfxBase != NULL) // CyberGfxBase may be NULL + { + ICyberGfx = (struct CyberGfxIFace *) GetInterface((struct Library *) CyberGfxBase, "main", 1, NULL); + if (ICyberGfx == NULL) + break; + } + IUtility = (struct UtilityIFace *) GetInterface((struct Library *) UtilityBase, "main", 1, NULL); + if (NULL == IUtility) + break; + IIntuition = (struct IntuitionIFace *) GetInterface((struct Library *) IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + break; + IGraphics = (struct GraphicsIFace *) GetInterface((struct Library *) GfxBase, "main", 1, NULL); + if (NULL == IGraphics) + break; + IScalosGfx = (struct ScalosGfxIFace *) GetInterface((struct Library *) ScalosGfxBase, "main", 1, NULL); + if (NULL == IScalosGfx) + break; + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + break; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + break; +#endif /* __amigaos4__ */ + + +#if defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) + __UtilityBase = UtilityBase; +#endif /* defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) */ + + PngMemPool = CreatePool(MEMPOOL_MEMFLAGS, MEMPOOL_PUDDLESIZE, MEMPOOL_THRESHSIZE); + if (NULL == PngMemPool) + break;; + + result = TRUE; + d1(KPrintF("%s/%ld: Success\n", __FUNC__, __LINE__)); + } while (0); + + return result; +} + + +void closePlugin(struct PluginBase *PluginBase) +{ + d1(kprintf("%s/%ld:\n", __FUNC__, __LINE__)); + +#if !defined(__amigaos4__) && !defined(__AROS__) + _STD_240_TerminateMemFunctions(); +#endif + + if (NULL != PngMemPool) + { + DeletePool(PngMemPool); + PngMemPool = NULL; + } + +#ifdef __amigaos4__ + if (INewlib) + { + DropInterface(INewlib); + INewlib = NULL; + } + if (NewlibBase) + { + CloseLibrary(NewlibBase); + NewlibBase = NULL; + } + if (ICyberGfx) + { + DropInterface((struct Interface *)ICyberGfx); + ICyberGfx = NULL; + } + if (IScalosGfx) + { + DropInterface((struct Interface *)IScalosGfx); + IScalosGfx = NULL; + } + if (IGraphics) + { + DropInterface((struct Interface *)IGraphics); + IGraphics = NULL; + } + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } + if (IUtility) + { + DropInterface((struct Interface *)IUtility); + IUtility = NULL; + } + if (IDOS) + { + DropInterface((struct Interface *)IDOS); + IDOS = NULL; + } +#endif /* __amigaos4__ */ + + if (CyberGfxBase) + { + CloseLibrary(CyberGfxBase); + CyberGfxBase = NULL; + } + if (NULL != ScalosGfxBase) + { + CloseLibrary((struct Library *) ScalosGfxBase); + ScalosGfxBase = NULL; + } + if (NULL != GfxBase) + { + CloseLibrary((struct Library *) GfxBase); + GfxBase = NULL; + } + if (NULL != IntuitionBase) + { + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } + + if (NULL != UtilityBase) + { + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } + if (NULL != DOSBase) + { + CloseLibrary((struct Library *) DOSBase); + DOSBase = NULL; + } +} + +//-------------------------------------------------------------------------- + +LIBFUNC_P5(LONG, LIBSCAPreviewGenerate, + A0, struct ScaWindowTask *, wt, + A1, BPTR, dirLock, + A2, CONST_STRPTR, iconName, + A3, struct TagItem *, tagList, + A6, struct PluginBase *, PluginBase) +{ + BPTR fh = (BPTR)NULL; // filehandle for reading of image file + struct ARGBHeader argbh; + LONG Success = FALSE; + png_structp png_ptr = NULL; + png_infop info_ptr = NULL; + struct ImageInfo cinfo; + + (void) PluginBase; + + d1(KPrintF(__FILE__ "/%s/%ld: START iconName=<%s>\n", __FUNC__, __LINE__, iconName)); + + memset(&cinfo, 0, sizeof(cinfo)); + memset(&argbh, 0, sizeof(argbh)); + + do { + UBYTE id[8]; + struct ARGB *argb; + ULONG ThumbnailWidth; + ULONG ThumbnailHeight; + ULONG SupportedColors; + ULONG ScreenDepth; + struct Screen *WBScreen; + struct BitMapHeader *bmhdExternal; + BPTR oldDir; + struct ScalosPreviewResult *PVResult; + size_t BytesPerRow; + BOOL DoRemap; + ULONG quality; + ULONG ReservedColors; + LONG Length; + png_bytepp row_pointers; + png_uint_32 width, height; + int bit_depth, color_type, interlace_type; + ULONG y; + + PVResult = (struct ScalosPreviewResult *) GetTagData(SCALOSPREVIEW_ResultStruct, (ULONG)NULL, tagList); + if (NULL == PVResult) + break; + + // clear result + memset(PVResult, 0, sizeof(*PVResult)); + + ThumbnailWidth = GetTagData(SCALOSPREVIEW_ThumbnailWidth, 0, tagList); + if (0 == ThumbnailWidth) + break; + ThumbnailHeight = GetTagData(SCALOSPREVIEW_ThumbnailHeight, 0, tagList); + if (0 == ThumbnailHeight) + break; + + SupportedColors = GetTagData(SCALOSPREVIEW_SupportedColors, 0, tagList); + if (SupportedColors < 16) + break; + + ReservedColors = GetTagData(SCALOSPREVIEW_ReservedColors, 0, tagList); + if (SupportedColors < ReservedColors + 16) + break; + + bmhdExternal = (struct BitMapHeader *) GetTagData(SCALOSPREVIEW_ImgBitMapHeader, (ULONG)NULL, tagList); + quality = GetTagData(SCALOSPREVIEW_Quality, SCALOSPREVIEWA_Quality_Max, tagList); + + WBScreen = (struct Screen *) GetTagData(SCALOSPREVIEW_Screen, (ULONG)NULL, tagList); + if (NULL == WBScreen) + break; + + oldDir = CurrentDir(dirLock); + fh = Open(iconName, MODE_OLDFILE); + CurrentDir(oldDir); + if ((BPTR)NULL == fh) + break; + + ScreenDepth = GetBitMapAttr(WBScreen->RastPort.BitMap, BMA_DEPTH); + + DoRemap = (ScreenDepth <= 8) || (NULL == CyberGfxBase) || SupportedColors <= 256; + + d1(KPrintF(__FILE__ "/%s/%ld: DoRemap=%ld\n", __FUNC__, __LINE__, DoRemap)); + + // Immediately Check if it's a PNG + + Length = FRead(fh, (APTR) id, 1, sizeof(id)); + d1(kprintf("%s/%s/%ld: Length=%ld\n", __FILE__, __FUNC__, __LINE__, Length)); + if (sizeof(id) != Length) + break; + + d1(kprintf("%s/%s/%ld: id=%02lx %02lx %02lx %02lx\n", __FILE__, __FUNC__, __LINE__, id[0], id[1], id[2], id[3])); + + /* Compare the first PNG_BYTES_TO_CHECK bytes of the signature. + break if they match */ + if (0 != png_sig_cmp((png_bytep) id, (png_size_t) 0, sizeof(id))) + { + d1(kprintf("%s/%s/%ld: png_sig_cmp failed\n", __FILE__, __FUNC__, __LINE__)); + break; + } + + png_ptr = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, + (png_voidp) NULL, PngError, PngWarning, NULL, PngAllocMem, PngFreeMem); + + d1(KPrintF("%s/%s/%ld: png_ptr=%08lx\n", __FILE__, __FUNC__, __LINE__, png_ptr)); + if (NULL == png_ptr) + break; + + /* Allocate/initialize the memory for image information. REQUIRED. */ + info_ptr = png_create_info_struct(png_ptr); + d1(KPrintF("%s/%s/%ld: info_ptr=%08lx\n", __FILE__, __FUNC__, __LINE__, info_ptr)); + if (NULL == info_ptr) + break; + + d1(KPrintF("%s/%s/%ld: png_ptr=%08lx\n", __FILE__, __FUNC__, __LINE__, png_ptr)); + d1(KPrintF("%s/%s/%ld: sizeof(jmp_buf)=%lu png_jmpbuf=%08lx\n", __FILE__, __FUNC__, __LINE__, sizeof(jmp_buf), png_jmpbuf(png_ptr))); + // safety check against jmp_buf size mismatch between libpng and Scalos + if (NULL == png_jmpbuf(png_ptr)) + break; + + if (setjmp(png_jmpbuf(png_ptr))) + { + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + Success = FALSE; + break; + } + + d1(KPrintF("%s/%s/%ld: png_ptr=%08lx\n", __FILE__, __FUNC__, __LINE__, png_ptr)); + + png_set_read_fn(png_ptr, (void *) fh, user_read_data); + + png_set_sig_bytes(png_ptr, sizeof(id)); + + png_set_keep_unknown_chunks(png_ptr, + PNG_HANDLE_CHUNK_IF_SAFE, NULL, 0); + + png_set_palette_to_rgb(png_ptr); + png_set_expand_gray_1_2_4_to_8(png_ptr); + png_set_tRNS_to_alpha(png_ptr); + png_set_gray_to_rgb(png_ptr); + png_set_add_alpha(png_ptr, ~0, PNG_FILLER_BEFORE); + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + png_read_png(png_ptr, info_ptr, + PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING + | PNG_TRANSFORM_SWAP_ALPHA | PNG_TRANSFORM_EXPAND, NULL); + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + png_get_IHDR(png_ptr, info_ptr, + &width, &height, &bit_depth, &color_type, + &interlace_type, NULL, NULL); + + d1(KPrintF("%s/%s/%ld: width=%ld height=%ld depth=%ld color_type=%ld\n", __FILE__, __FUNC__, __LINE__, width, height, bit_depth, color_type)); + + row_pointers = png_get_rows(png_ptr, info_ptr); + d1(KPrintF("%s/%s/%ld: row_pointers=%08lx\n", __FILE__, __FUNC__, __LINE__, row_pointers)); + if (NULL == row_pointers) + break; + + if (bmhdExternal) + { + bmhdExternal->bmh_Width = width; + bmhdExternal->bmh_Height = height; + bmhdExternal->bmh_Depth = 24; + } + + ScalosGfxCalculateScaleAspect(width, height, + &ThumbnailWidth, &ThumbnailHeight); + + d1(KPrintF(__FILE__ "/%s/%ld: ImageWidth=%ld ImageHeight=%ld\n", __FUNC__, __LINE__, cinfo.image_width, cinfo.image_height)); + d1(KPrintF(__FILE__ "/%s/%ld: ThumbnailWidth=%ld ThumbnailHeight=%ld\n", __FUNC__, __LINE__, ThumbnailWidth, ThumbnailHeight)); + + argbh.argb_Width = width; + argbh.argb_Height = height; + argbh.argb_ImageData = ScalosGfxCreateARGBTags(argbh.argb_Width, argbh.argb_Height, TAG_END); + + d1(KPrintF("%s/%s/%ld: argb_ImageData=%08lx\n", __FILE__, __FUNC__, __LINE__, argbh.argb_ImageData)); + if (NULL == argbh.argb_ImageData) + break; + + d1(KPrintF("%s/%s/%ld: width=%ld height=%ld depth=%ld color_type=%ld\n", __FILE__, __FUNC__, __LINE__, width, height, bit_depth, color_type)); + + BytesPerRow = png_get_rowbytes(png_ptr, info_ptr); + + d1(KPrintF("%s/%s/%ld: BytesPerRow=%lu\n", __FILE__, __FUNC__, __LINE__, BytesPerRow)); + + argb = argbh.argb_ImageData; + for (y = 0; y < height; y++) + { + memcpy(argb, row_pointers[y], BytesPerRow); + argb += width; + } + + if (DoRemap) + { + if ((SupportedColors + ReservedColors) >= 256) + SupportedColors = 256 - ReservedColors; + + Success = GenerateThumbnailFromARGB(wt, + &argbh, + quality, + ThumbnailWidth, + ThumbnailHeight, + SupportedColors, + ReservedColors, + PVResult); + } + else + { + Success = GenerateARGBThumbnail(wt, + &argbh, quality, + ThumbnailWidth, ThumbnailHeight, + PVResult); + } + } while (0); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + if (fh) + Close(fh); + + if (!Success) + ScalosGfxFreeARGB(&argbh.argb_ImageData); + + d1(KPrintF(__FILE__ "/%s/%ld: END Success=%ld\n", __FUNC__, __LINE__, Success)); + + return Success; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +static BOOL GenerateThumbnailFromARGB(struct ScaWindowTask *wt, + struct ARGBHeader *argbSrc, ULONG quality, + ULONG ScaledWidth, ULONG ScaledHeight, + ULONG SupportedColors, ULONG ReservedColors, + struct ScalosPreviewResult *PVResult) +{ + struct ARGBHeader argbDest = { 0, 0, NULL }; + ULONG ScaleFlags = SCALEFLAGF_DOUBLESIZE; + + if (quality >= (3 * SCALOSPREVIEWA_Quality_Max) / 4) + { + ScaleFlags |= SCALEFLAGF_BICUBIC; + } + else if (quality >= SCALOSPREVIEWA_Quality_Max / 2) + { + ScaleFlags |= SCALEFLAGF_BILINEAR; + } + else + { + ScaleFlags |= SCALEFLAGF_AVERAGE; + } + + d1(KPrintF(__FILE__ "/%s/%ld: argb_Width=%ld argb_Height=%ld ImageData=%08lx\n", \ + __FUNC__, __LINE__, argbSrc->argb_Width, argbSrc->argb_Height,\ + argbSrc->argb_ImageData)); + d1(KPrintF(__FILE__ "/%s/%ld: SupportedColors=%lu\n", __FUNC__, __LINE__, SupportedColors)); + + argbDest.argb_Width = ScaledWidth; + argbDest.argb_Height = ScaledHeight; + argbDest.argb_ImageData = ScalosGfxScaleARGBArrayTags(argbSrc, + &argbDest.argb_Width, + &argbDest.argb_Height, + SCALOSGFX_ScaleARGBArrayFlags, ScaleFlags, + TAG_END); + + if (SupportedColors <= 256) + { + ULONG Depth; + + // Limit color depth to the number of colors supported by the icon + for (Depth = 0; Depth < 7 && (1 << Depth) < SupportedColors; Depth++) + ; + + d1(KPrintF(__FILE__ "/%s/%ld: argb_ImageData: a=%ld r=%ld g=%ld b=%ld\n", \ + __FUNC__, __LINE__, argbDest->argb_ImageData->Alpha, \ + argbDest->argb_ImageData->Red, argbDest->argb_ImageData->Green, \ + argbDest->argb_ImageData->Blue)); + + d1(KPrintF(__FILE__ "/%s/%ld: SupportedColors=%lu Depth=%lu ReservedColors=%lu\n", \ + __FUNC__, __LINE__, SupportedColors, Depth, ReservedColors)); + + PVResult->spvr_sac = ScalosGfxMedianCutTags(&argbDest, Depth, + SCALOSGFX_MedianCutFlags, SCALOSGFXFLAGF_MedianCut_FloydSteinberg, + SCALOSGFX_MedianCutFriendBitMap, NULL, + SCALOSGFX_MedianCutReservedColors, ReservedColors, + TAG_END); + d1(KPrintF(__FILE__ "/%s/%ld: sac=%08lx\n", __FUNC__, __LINE__, PVResult->spvr_sac)); + + d1(KPrintF(__FILE__ "/%s/%ld: sac_BitMap=%08lx\n", __FUNC__, __LINE__, PVResult->spvr_sac->sac_BitMap)); + d1(ByteDump((unsigned char *) PVResult->spvr_sac->sac_BitMap, sizeof(struct BitMap))); + } + else + { + PVResult->spvr_ARGBheader = argbDest; + memset(&argbDest, 0, sizeof(argbDest)); + } + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + ScalosGfxFreeARGB(&argbDest.argb_ImageData); + + d1(KPrintF(__FILE__ "/%s/%ld: END\n", __FUNC__, __LINE__)); + + return TRUE; +} + +//----------------------------------------------------------------------------- + +static BOOL GenerateARGBThumbnail(struct ScaWindowTask *wt, + const struct ARGBHeader *argbh, ULONG quality, + ULONG ScaledWidth, ULONG ScaledHeight, + struct ScalosPreviewResult *PVResult) +{ + BOOL Success = FALSE; + struct ARGBHeader argbDest = { 0, 0, NULL }; + + d1(KPrintF(__FILE__ "/%s/%ld: START\n", __FUNC__, __LINE__)); + + do { + ULONG ScaleFlags = SCALEFLAGF_DOUBLESIZE; + + if (quality >= (3 * SCALOSPREVIEWA_Quality_Max) / 4) + { + ScaleFlags |= SCALEFLAGF_BICUBIC; + } + else if (quality >= SCALOSPREVIEWA_Quality_Max / 2) + { + ScaleFlags |= SCALEFLAGF_BILINEAR; + } + else + { + ScaleFlags |= SCALEFLAGF_AVERAGE; + } + + argbDest.argb_Width = ScaledWidth; + argbDest.argb_Height = ScaledHeight; + + argbDest.argb_ImageData = ScalosGfxScaleARGBArrayTags(argbh, + &argbDest.argb_Width, + &argbDest.argb_Height, + SCALOSGFX_ScaleARGBArrayFlags, ScaleFlags, + TAG_END); + d1(KPrintF(__FILE__ "/%s/%ld: argbDest.argb_ImageData=%08lx\n", __FUNC__, __LINE__, argbDest.argb_ImageData)); + if (NULL == argbDest.argb_ImageData) + break; + + PVResult->spvr_ARGBheader = argbDest; + memset(&argbDest, 0, sizeof(argbDest)); + + Success = TRUE; + } while (0); + + ScalosGfxFreeARGB(&argbDest.argb_ImageData); + + d1(KPrintF(__FILE__ "/%s/%ld: END Success=%ld\n", __FUNC__, __LINE__, Success)); + + return Success; +} + +//----------------------------------------------------------------------------- + +void abort(void) +{ + while (1) + ; +} + +//----------------------------------------------------------------------------- + +static png_voidp PngAllocMem(png_structp png_ptr, png_size_t size) +{ + (void) png_ptr; + + return MyAllocVecPooled(size); +} + +//----------------------------------------------------------------------------- + +static void PngFreeMem(png_structp png_ptr, png_voidp ptr) +{ + (void) png_ptr; + MyFreeVecPooled(ptr); +} + +//----------------------------------------------------------------------------- + +static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + BPTR fh = (BPTR) png_get_io_ptr(png_ptr); + + if (1 != FRead(fh, data, 1, length)) + { +// png_error(); + } +} + +//----------------------------------------------------------------------------- + +static void PngError(png_structp png_ptr, png_const_charp error_message) +{ + d1(KPrintF("%s/%s/%ld: png_ptr=%08lx message=<%s>\n", \ + __FILE__, __FUNC__, __LINE__, png_ptr, error_message)); + + longjmp(png_jmpbuf(png_ptr), 1); +} + +//----------------------------------------------------------------------------- + +static void PngWarning(png_structp png_ptr, png_const_charp warning_message) +{ + d1(KPrintF("%s/%s/%ld: png_ptr=%08lx message=<%s>\n", \ + __FILE__, __FUNC__, __LINE__, png_ptr, warning_message)); +// png_default_warning(png_ptr, warning_message); +} + +//----------------------------------------------------------------------------- + +static APTR MyAllocVecPooled(size_t Size) +{ + APTR ptr; + + if (PngMemPool) + { + ObtainSemaphore(&PngMemPoolSemaphore); + ptr = AllocPooled(PngMemPool, Size + sizeof(size_t)); + ReleaseSemaphore(&PngMemPoolSemaphore); + if (ptr) + { + size_t *sptr = (size_t *) ptr; + + sptr[0] = Size; + + d1(kprintf("%s/%s/%ld: MemPool=%08lx Size=%lu mem=%08lx\n", __FILE__, __FUNC__, __LINE__, PngMemPool, Size, &sptr[1])); + return (APTR)(&sptr[1]); + } + } + + d1(kprintf("%s/%s/%ld: MemPool=%08lx Size=%lu\n", __FILE__, __FUNC__, __LINE__, PngMemPool, Size)); + + return NULL; +} + + +static void MyFreeVecPooled(APTR mem) +{ + d1(kprintf("%s/%s/%ld: MemPool=%08lx mem=%08lx\n", __FILE__, __FUNC__, __LINE__, PngMemPool, mem)); + if (PngMemPool && mem) + { + size_t size; + size_t *sptr = (size_t *) mem; + + mem = &sptr[-1]; + size = sptr[-1]; + + ObtainSemaphore(&PngMemPoolSemaphore); + FreePooled(PngMemPool, mem, size + sizeof(size_t)); + ReleaseSemaphore(&PngMemPoolSemaphore); + } +} + +//---------------------------------------------------------------------------- + +#ifndef __amigaos4__ +void _XCEXIT(long x) +{ +} + +//---------------------------------------------------------------------------- + +#ifndef __SASC +// Replacement for SAS/C library functions + +void exit(int x) +{ + (void) x; + while (1) + ; +} + +APTR _WBenchMsg; + +#endif /* __SASC */ + +#endif /* __amigaos4__ */ + +//----------------------------------------------------------------------------- + +#if !defined(__amigaos4__) && !defined(__AROS__) +int errno = 0; +#endif + +#if 1 +//int stderr = 0; + FILE **__sF; +#endif + +//----------------------------------------------------------------------------- + diff --git a/scalos/Plugins/Preview/PNGPicture/PNGPicture.h b/scalos/Plugins/Preview/PNGPicture/PNGPicture.h new file mode 100755 index 000000000..6e6260571 --- /dev/null +++ b/scalos/Plugins/Preview/PNGPicture/PNGPicture.h @@ -0,0 +1,40 @@ +// PNGPicture.h +// $Date$ +// $Revision$ + +#ifndef PNGPICTURE_H +#define PNGPICTURE_H + +//--------------------------------------------------------------- + +#include "plugin.h" + +//--------------------------------------------------------------- + +// Debugging... +#define d(x) ; +#define d1(x) ; +#define d2(x) x; + +// aus debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +//--------------------------------------------------------------- + +#define MEMPOOL_MEMFLAGS MEMF_ANY +#define MEMPOOL_PUDDLESIZE 32768 +#define MEMPOOL_THRESHSIZE 8192 + +//----------------------------------------------------------------------------- +// defined in mempools.lib + +#ifndef __amigaos4__ +extern int _STI_240_InitMemFunctions(void); +extern void _STD_240_TerminateMemFunctions(void); +#endif + +//---------------------------------------------------------------------------- + +#endif /* PNGPICTURE_H */ + diff --git a/scalos/Plugins/Preview/PNGPicture/config.mk b/scalos/Plugins/Preview/PNGPicture/config.mk new file mode 100755 index 000000000..28be2f237 --- /dev/null +++ b/scalos/Plugins/Preview/PNGPicture/config.mk @@ -0,0 +1,83 @@ +# $Date: 2011-07-31 23:57:02 +0200 (So, 31. Jul 2011) $ +# $Revision: 814 $ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +COMMON_DIR = $(TOPLEVEL)/common/Plugin + +INCLUDES += -I$(COMMON_DIR) + +vpath %.c $(COMMON_DIR) + +############################################################################## + +include $(COMMON_DIR)/config.mk + +############################################################################## + +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +INCLUDES += # + +LFLAGS := -nostartfiles \ + -lpng \ + -lz \ + -lmempools \ + $(LFLAGS) \ +# -Wl,-Map,pngpicture.map \ +# --verbose + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += -nostartfiles \ + -lpng \ + -lz \ + -lm +# + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +LFLAGS += -nostartfiles \ + -lpng \ + -lz \ + -lm +# + + +else + +############################################################################### +# AmigaOS + +INCLUDES += # + +LFLAGS += -lmempools \ + -lpng \ + -lz \ + -ldebug \ + -lamiga21 \ + -lamiga \ + -lstubs + +endif +endif +endif diff --git a/scalos/Plugins/Preview/PNGPicture/makefile b/scalos/Plugins/Preview/PNGPicture/makefile new file mode 100755 index 000000000..0a48795dd --- /dev/null +++ b/scalos/Plugins/Preview/PNGPicture/makefile @@ -0,0 +1,134 @@ +# makefile für Scalos PNGPicture.pvplugin +# // $Date$ +# // $Revision$ + +############################################################# + +.SUFFIXES: .plugin .plugin.debug .cd + +############################################################# + +.PHONY: clean install nodebug + +############################################################# + +SUBDIRMAKE = $(MAKE) -s -C +#SUBDIRMAKE = smakedir + +PRECOMP = Include:all.gst + +CC = sc +CFLAGS = nostackcheck nochkabort strmer dbg=l nover streq data=far \ + IGNORE=73 idlen=64 \ + idir=///include \ + idir=///common/Plugin + +############################################################# + +OPT_FLG = OPTIMIZE OPTINLOCAL OPTTIME OPTSCHED IGNORE=306 IGNORE=308 IGNORE=304 +COPTS = NOWVRET NOVERSION nostackcheck idlen=128 idir=///include +OPTIONS = $(OPT_FLG) Math=s DATA=FAR DEBUG=L $(COPTS) def=NDEBUG + +############################################################# + +AS = phxass +SPLAT = sc:c/splat +AFLAGS = quiet noexe m=68020 opt=NRQB i=sc:Assembler_Headers/ +LD = slink +LDFLAGS = quiet batch noicons sd +LDLIBS = ///SAS-lib/png.lib \ + ///SAS-lib/z.lib \ + ///SAS-lib/snprintf.lib \ + LIB:mempools.lib \ + LIB:scm.lib \ + LIB:sc.lib \ + LIB:debug.lib \ + LIB:amiga.lib +ASTARTUP = +#CSTARTUP = LIB:c.o + +OBJDIR = .sasobj +CATCOMP = CatComp + +############################################################# + +COMMON_DIR = ../../../common/Plugin + +############################################################# + +CSRCS = $(COMMON_DIR)/plugin-classic.c \ + PNGPicture.c + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +XSRCS = $(notdir $(CSRCS)) +OBJS = $(XSRCS:%.c=$(OBJDIR)/$(notdir %).o) + +############################################################# + +PLUGIN = pngpicture.pvplugin +DESTTOOL = Scalos:plugins/Preview/ + +############################################################# + +All: $(PLUGIN) \ + $(PLUGIN).debug \ + +############################################################# + +# commands generated a catalog (.catalog) from a catalog translation (.ct) file. +.ct.catalog: + $(CATCOMP) $*.cd $< CATALOG $*.catalog VB=1 + +$(OBJDIR)/plugin-classic.o : $(COMMON_DIR)/plugin-classic.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $*.c objectname $@ + +############################################################# + +$(OBJDIR)/plugin-classic.o : plugin_data.h \ + $(COMMON_DIR)/plugin.h $(COMMON_DIR)/plugin-common.c + +$(OBJDIR)/PNGPicture.o : PNGPicture.h $(COMMON_DIR)/plugin.h + +############################################################# + +$(PLUGIN) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) to $@ FROM $(CSTARTUP) $(OBJS) lib $(LDLIBS) $(LDFLAGS) stripdebug + +$(PLUGIN).debug : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) to $@ FROM $(CSTARTUP) $(OBJS) lib $(LDLIBS) $(LDFLAGS) addsym + +############################################################# + +# A little something to clean it all up +clean: + @printf '\033[32mDelete: \033[31m\033[1m' + @delete $(OBJS) $(PLUGIN) $(PLUGIN).debug $(ALLCATS) $(CATCOMPHEADER) + @printf '\033[0m' + +############################################################# + +# copy all generated file to their final destinations +install: + @printf '\033[32mInstall: \033[31m\033[1m$(PLUGIN)\033[0m\n' + @copy $(PLUGIN) $(DESTTOOL) clone + @printf '\033[32mFlushing memory\033[0m\n' + @avail flush + +############################################################# + +nodebug: + -@$(SPLAT) -s -o "d2(" "d1(" "#?.c" + +############################################################# + diff --git a/scalos/Plugins/Preview/PNGPicture/makefile-new b/scalos/Plugins/Preview/PNGPicture/makefile-new new file mode 100755 index 000000000..b55097620 --- /dev/null +++ b/scalos/Plugins/Preview/PNGPicture/makefile-new @@ -0,0 +1,74 @@ +# $Date: 2011-07-31 23:57:02 +0200 (So, 31. Jul 2011) $ +# $Revision: 814 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(BEGIN_OBJS) \ + $(OBJDIR)/PNGPicture.o \ + $(END_OBJS) + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Targets +# + +NAME = pngpicture.pvplugin +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) \ + all_subdirs + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + @$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) Scalos:Plugins/Preview/ clone + @touch env:scalos/FileTypes/png + @avail flush + +install: install_subdirs + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* + +clean: clean_subdirs + +############################################################################## + + diff --git a/scalos/Plugins/Preview/PNGPicture/plugin_data.h b/scalos/Plugins/Preview/PNGPicture/plugin_data.h new file mode 100644 index 000000000..c74bf4ca8 --- /dev/null +++ b/scalos/Plugins/Preview/PNGPicture/plugin_data.h @@ -0,0 +1,27 @@ +// plugin_data.h +// $Date$ +// $Revision$ + +#ifndef PLUGIN_DATA_H_INCLUDED +#define PLUGIN_DATA_H_INCLUDED + +#include +#include + +#define PLUGIN_TYPE PREVIEW + +#define LIB_VERSION 41 +#define LIB_REVISION 1 + +#define LIB_NAME "pngpicture.pvplugin" +#define LIB_VERSTRING "\0$VER: pngpicture.pvplugin " \ + STR(LIB_VERSION) "." STR(LIB_REVISION) \ + " (16.04.2010)" \ + COMPILER_STRING " ©2010" CURRENTYEAR \ + " The Scalos Team" + +//---------------------------------------------------------------------------- +// code and includes to define the structs and functions used above + +#endif /* PLUGUN_DATA_H_INCLUDED */ + diff --git a/scalos/Plugins/Preview/Video/COPYING b/scalos/Plugins/Preview/Video/COPYING new file mode 100755 index 000000000..db6c98b98 --- /dev/null +++ b/scalos/Plugins/Preview/Video/COPYING @@ -0,0 +1,15 @@ +This code is linked to libraries that are distributed under the + +LESSER GENERAL PUBLIC LICENCE ("LGPL") : + +libavcodec +libavformat +libavutil + +The accompanying sources are provided to fulfill the LGPL requirements, +and are NOT subject to either GPL or LGPL. + +They are considered the "Corresponding Application Code" that permit +the user to recombine or relink the Application with a modified version of +the Linked Version to produce a modified Combined Work. + diff --git a/scalos/Plugins/Preview/Video/Video.c b/scalos/Plugins/Preview/Video/Video.c new file mode 100755 index 000000000..01f3aa9be --- /dev/null +++ b/scalos/Plugins/Preview/Video/Video.c @@ -0,0 +1,1286 @@ +// Video.c +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#undef GLOBAL + +#include +#include +#include +#include + +#include "Video.h" + +//--------------------------------------------------------------------------------------- + +// set BYTEDUMP to 1 if you need to use ByteDump() +#define BYTEDUMP 0 + +#if 1 +#define DUMP_ARGB_LINE(argbh, component, yy) +#else +#define DUMP_ARGB_LINE(argbh, component, yy) \ + { \ + int n; \ + const struct ARGB *argb = &(argbh)->argb_ImageData[(yy) * (argbh)->argb_Width]; \ + KPrintF(__FILE__ "/%s/%ld: w=%ld h=%ld yy=%ld #component:\n", __FUNC__, __LINE__, \ + (argbh)->argb_Width, (argbh)->argb_Height, yy); \ + KPrintF(__FILE__ "/%s/%ld: ", __FUNC__, __LINE__); \ + for (n = 0; n < (argbh)->argb_Width; n++, argb++) \ + { \ + if (n > 0 && 0 == n % 16) \ + KPrintF("\n" __FILE__ "/%s/%ld: ", __FUNC__, __LINE__); \ + KPrintF("%02lx ", argb->component); \ + } \ + KPrintF("\n"); \ + } +#endif + +//--------------------------------------------------------------------------------------- + +#define NO_STREAM -1 + +struct AVInfo + { + int avinf_VideoStream; + AVFormatContext *avinf_pFormatContext; + AVCodecContext *avinf_pCodecContext; + AVCodec *avinf_pVideoCodec; + AVStream *avinf_pVideoStream; + AVFrame *avinf_pFrame; // Video frame in native format + AVFrame *avinf_pRGBFrame; // Converted Video frame in RGB format + UBYTE *avinf_Buffer; // Buffer for RGB image data + BOOL avinf_CodecOpened; // Flag: av_codec_open() succeeded + }; + +struct VideoFrame +{ + int vfr_width; + int vfr_height; + int vfr_lineSize; +}; + +//--------------------------------------------------------------------------------------- + +struct GfxBase *GfxBase; +T_UTILITYBASE UtilityBase; +struct Library *CyberGfxBase; +struct DosLibrary *DOSBase; +struct IntuitionBase *IntuitionBase; +struct ScalosGfxBase *ScalosGfxBase; + +#ifdef __amigaos4__ +struct Library *NewlibBase; +struct Interface *INewlib; +struct GraphicsIFace *IGraphics; +struct UtilityIFace *IUtility; +struct ExecIFace *IExec; +struct CyberGfxIFace *ICyberGfx; +struct DOSIFace *IDOS; +struct IntuitionIFace *IIntuition; +struct ScalosGfxIFace *IScalosGfx; +#endif /* __amigaos4__ */ + +/* won't compile for me when defined as constants - mazze */ +#define FILMHOLE_WIDTH (12) +#define FILMHOLE_HEIGHT (10) + +STRPTR VersTag = LIB_VERSTRING; + +//--------------------------------------------------------------------------------------- + +static BOOL GenerateRemappedThumbnail(struct ScaWindowTask *wt, + CONST_STRPTR iconName, + struct AVInfo *avInfo, struct VideoFrame *vFrame, + ULONG quality, ULONG SupportedColors, ULONG ReservedColors, + ULONG ScaledWidth, ULONG ScaledHeight, + struct Screen *WBScreen, struct ScalosPreviewResult *PVResult); +static BOOL GenerateARGBThumbnail(struct ScaWindowTask *wt, + CONST_STRPTR iconName, + struct AVInfo *avInfo, struct VideoFrame *vFrame, + ULONG quality, + ULONG ScaledWidth, ULONG ScaledHeight, + struct ScalosPreviewResult *PVResult); +static void CleanupAVInfo(struct AVInfo *avInfo); +static BOOL InitializeVideo(struct AVInfo *avInfo); +static BOOL ReadVideoFrame(struct AVInfo *avInfo); +static BOOL GetScaledVideoFrame(struct AVInfo *avInfo, int scaledSize, + ULONG quality, struct VideoFrame *videoFrame); +static BOOL ConvertAndScaleFrame(struct AVInfo *avInfo, int format, int scaledSize, + int *scaledWidth, int *scaledHeight, ULONG quality); +static void CalculateDimensions(int srcWidth, int srcHeight, int squareSize, int *destWidth, int *destHeight); +static BOOL AllocFrameData(AVFrame **avFrame, int width, int height, int format); +static BOOL VideoSeekFrame(struct AVInfo *avInfo, float timeInSeconds); +static void OverlayFilmStrip(struct AVInfo *avInfo, struct VideoFrame *videoFrame); +static BOOL IsInterestingFrame(const struct AVInfo *avInfo); +static BOOL FindInterestingFrame(struct AVInfo *avInfo); +static void av_log_dummy_callback(void* ptr, int level, const char* fmt, va_list vl); + +#if BYTEDUMP +static void ByteDump(const unsigned char *Data, size_t Length); +#endif /* BYTEDUMP */ + +//----------------------------------------------------------- + +BOOL initPlugin(struct PluginBase *PluginBase) +{ + BOOL result = FALSE; + + d1(KPrintF("%s/%s/%ld: PluginBase=%08lx procName=<%s>\n", __FILE__, __FUNC__, __LINE__, \ + PluginBase, FindTask(NULL)->tc_Node.ln_Name)); + + do { +#ifndef __amigaos4__ + if (_STI_240_InitMemFunctions()) + break; +#endif /* __amigaos4__ */ + DOSBase = (APTR) OpenLibrary( "dos.library", 39 ); + if (NULL == DOSBase) + break; + + UtilityBase = (T_UTILITYBASE) OpenLibrary("utility.library", 39); + if (NULL == UtilityBase) + break; + + CyberGfxBase = OpenLibrary(CYBERGFXNAME, 0); + // CyberGfxBase may be NULL + + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + d1(kprintf("%s/%s/%ld: IntuitionBase=%08lx\n", __FILE__, __FUNC__, __LINE__, IntuitionBase)); + if (NULL == IntuitionBase) + break; + + GfxBase = (struct GfxBase *) OpenLibrary(GRAPHICSNAME, 39); + d1(kprintf("%s/%s/%ld: GfxBase=%08lx\n", __FILE__, __FUNC__, __LINE__, GfxBase)); + if (NULL == GfxBase) + break; + + ScalosGfxBase = (struct ScalosGfxBase *) OpenLibrary(SCALOSGFXNAME, 41); + d1(KPrintF("%s/%s/%ld: ScalosGfxBase=%08lx\n", __FILE__, __FUNC__, __LINE__, ScalosGfxBase)); + if (NULL == ScalosGfxBase) + break; + +#ifdef __amigaos4__ + IDOS = (struct DOSIFace *) GetInterface((struct Library *)DOSBase, "main", 1, NULL); + if (IDOS == NULL) + break; + if (CyberGfxBase != NULL) // CyberGfxBase may be NULL + { + ICyberGfx = (struct CyberGfxIFace *) GetInterface((struct Library *) CyberGfxBase, "main", 1, NULL); + if (ICyberGfx == NULL) + break; + } + IUtility = (struct UtilityIFace *) GetInterface((struct Library *) UtilityBase, "main", 1, NULL); + if (NULL == IUtility) + break; + IIntuition = (struct IntuitionIFace *) GetInterface((struct Library *) IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + break; + IGraphics = (struct GraphicsIFace *) GetInterface((struct Library *) GfxBase, "main", 1, NULL); + if (NULL == IGraphics) + break; + IScalosGfx = (struct ScalosGfxIFace *) GetInterface((struct Library *) ScalosGfxBase, "main", 1, NULL); + if (NULL == IScalosGfx) + break; + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + break; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + break; +#endif /* __amigaos4__ */ + + if (!InitExtra()) + break; + + av_register_all(); + + result = TRUE; + d1(KPrintF("%s/%s/%ld: Success\n", __FILE__, __FUNC__, __LINE__)); + } while (0); + + return result; +} + + +void closePlugin(struct PluginBase *PluginBase) +{ + d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__)); + + ExitExtra(); + +#ifndef __amigaos4__ + _STD_240_TerminateMemFunctions(); +#endif + +#ifdef __amigaos4__ + if (INewlib) + { + DropInterface(INewlib); + INewlib = NULL; + } + if (NewlibBase) + { + CloseLibrary(NewlibBase); + NewlibBase = NULL; + } + if (ICyberGfx) + { + DropInterface((struct Interface *)ICyberGfx); + ICyberGfx = NULL; + } + if (IScalosGfx) + { + DropInterface((struct Interface *)IScalosGfx); + IScalosGfx = NULL; + } + if (IGraphics) + { + DropInterface((struct Interface *)IGraphics); + IGraphics = NULL; + } + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } + if (IUtility) + { + DropInterface((struct Interface *)IUtility); + IUtility = NULL; + } + if (IDOS) + { + DropInterface((struct Interface *)IDOS); + IDOS = NULL; + } +#endif /* __amigaos4__ */ + + if (CyberGfxBase) + { + CloseLibrary(CyberGfxBase); + CyberGfxBase = NULL; + } + if (NULL != ScalosGfxBase) + { + CloseLibrary((struct Library *) ScalosGfxBase); + ScalosGfxBase = NULL; + } + if (NULL != GfxBase) + { + CloseLibrary((struct Library *) GfxBase); + GfxBase = NULL; + } + if (NULL != IntuitionBase) + { + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } + + if (NULL != UtilityBase) + { + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } + if (NULL != DOSBase) + { + CloseLibrary((struct Library *) DOSBase); + DOSBase = NULL; + } +} + +//-------------------------------------------------------------------------- + +LIBFUNC_P5(LONG, LIBSCAPreviewGenerate, + A0, struct ScaWindowTask *, wt, + A1, BPTR, dirLock, + A2, CONST_STRPTR, iconName, + A3, struct TagItem *, tagList, + A6, struct PluginBase *, PluginBase) +{ + LONG Success = FALSE; + + (void) PluginBase; + + if (InitInstance()) + { + BPTR oldDir = (BPTR)NULL; + struct AVInfo avInfo; + struct VideoFrame vFrame; + + memset(&vFrame, 0, sizeof(struct VideoFrame)); + + d1(KPrintF("%s/%s/%ld: START iconName=<%s>\n", __FILE__, __FUNC__, __LINE__, iconName)); + + do { + ULONG ThumbnailWidth; + ULONG ThumbnailHeight; + ULONG SupportedColors; + ULONG ScreenDepth; + struct Screen *WBScreen; + struct BitMapHeader *bmhdExternal; + struct ScalosPreviewResult *PVResult; + BOOL DoRemap; + ULONG quality; + ULONG ReservedColors; + int rc; + + memset(&avInfo, 0, sizeof(struct AVInfo)); + + av_log_set_callback(av_log_dummy_callback); + + d1(KPrintF("%s/%s/%ld: after av_log_set_callback\n", __FILE__, __FUNC__, __LINE__)); + + PVResult = (struct ScalosPreviewResult *) GetTagData(SCALOSPREVIEW_ResultStruct, (ULONG)NULL, tagList); + if (NULL == PVResult) + break; + + // clear result + memset(PVResult, 0, sizeof(*PVResult)); + + ThumbnailWidth = GetTagData(SCALOSPREVIEW_ThumbnailWidth, 0, tagList); + if (0 == ThumbnailWidth) + break; + ThumbnailHeight = GetTagData(SCALOSPREVIEW_ThumbnailHeight, 0, tagList); + if (0 == ThumbnailHeight) + break; + + SupportedColors = GetTagData(SCALOSPREVIEW_SupportedColors, 0, tagList); + if (SupportedColors < 16) + break; + + ReservedColors = GetTagData(SCALOSPREVIEW_ReservedColors, 0, tagList); + if (SupportedColors < ReservedColors + 16) + break; + + bmhdExternal = (struct BitMapHeader *) GetTagData(SCALOSPREVIEW_ImgBitMapHeader, (ULONG)NULL, tagList); + quality = GetTagData(SCALOSPREVIEW_Quality, SCALOSPREVIEWA_Quality_Max, tagList); + + WBScreen = (struct Screen *) GetTagData(SCALOSPREVIEW_Screen, (ULONG)NULL, tagList); + if (NULL == WBScreen) + break; + + oldDir = CurrentDir(dirLock); + + d1(KPrintF("%s/%s/%ld: before av_open_input_file\n", __FILE__, __FUNC__, __LINE__)); + + // Open video file + rc = av_open_input_file(&avInfo.avinf_pFormatContext, iconName, NULL, 0, NULL); + d1(KPrintF("%s/%s/%ld: rc=%d\n", __FILE__, __FUNC__, __LINE__, rc)); + if (0 != rc) + { + d1(KPrintF("%s/%s/%ld: av_open_input_file failed\n", __FILE__, __FUNC__, __LINE__)); + break; + } + + d1(KPrintF("%s/%s/%ld: before InitializeVideo\n", __FILE__, __FUNC__, __LINE__)); + + if (!InitializeVideo(&avInfo)) + break; + + d1(KPrintF("%s/%s/%ld: after InitializeVideo\n", __FILE__, __FUNC__, __LINE__)); + + if (!ReadVideoFrame(&avInfo)) //before seeking, a frame has to be decoded + break; + + d1(KPrintF(__FILE__ "%s/%s/%ld: ReadVideoFrame success\n", __FILE__, __FUNC__, __LINE__)); + + if (bmhdExternal) + { +#if 1 + bmhdExternal->bmh_Width = avInfo.avinf_pCodecContext->width; + bmhdExternal->bmh_Height = avInfo.avinf_pCodecContext->height; +#else + bmhdExternal->bmh_Width = 2; + bmhdExternal->bmh_Height = 2; +#endif + bmhdExternal->bmh_Depth = 24; + } + + if (!FindInterestingFrame(&avInfo)) + break; + + if (!GetScaledVideoFrame(&avInfo, ThumbnailWidth, quality, &vFrame)) + break; + + d1(KPrintF("%s/%s/%ld: vfr_width=%ld vfr_height=%ld vfr_lineSize=%ld\n", __FILE__, __FUNC__, __LINE__, vFrame.vfr_width, vFrame.vfr_height, vFrame.vfr_lineSize)); + + if (vFrame.vfr_width > FILMHOLE_WIDTH * 2) + { + OverlayFilmStrip(&avInfo, &vFrame); + } + + ScreenDepth = GetBitMapAttr(WBScreen->RastPort.BitMap, BMA_DEPTH); + + DoRemap = (ScreenDepth <= 8) || (NULL == CyberGfxBase) || SupportedColors <= 256; + + d1(KPrintF("%s/%s/%ld: DoRemap=%ld\n", __FILE__, __FUNC__, __LINE__, DoRemap)); + + if (DoRemap) + { + d1(KPrintF("%s/%s/%ld: SupportedColors=%lu ReservedColors=%ld\n", \ + __FILE__, __FUNC__, __LINE__, SupportedColors, ReservedColors)); + + Success = GenerateRemappedThumbnail(wt, + iconName, + &avInfo, &vFrame, + quality, SupportedColors, ReservedColors, + ThumbnailWidth, ThumbnailHeight, + WBScreen, PVResult); + } + else + { + Success = GenerateARGBThumbnail(wt, + iconName, + &avInfo, &vFrame, + quality, + ThumbnailWidth, ThumbnailHeight, + PVResult); + } + } while (0); + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + if (oldDir) + CurrentDir(oldDir); + + CleanupAVInfo(&avInfo); + + ExitInstance(); + } + + d1(KPrintF("%s/%s/%ld: END Success=%ld\n", __FILE__, __FUNC__, __LINE__, Success)); + + return Success; +} +LIBFUNC_END + +//---------------------------------------------------------------------------- + +#ifndef __amigaos4__ +void _XCEXIT(long x) +{ +} + +//---------------------------------------------------------------------------- + +#ifndef __SASC +// Replacement for SAS/C library functions + +void exit(int x) +{ + (void) x; + while (1) + ; +} + +APTR _WBenchMsg; + +#endif /* __SASC */ + +#endif /* __amigaos4__ */ + +//----------------------------------------------------------------------------- + +static BOOL GenerateRemappedThumbnail(struct ScaWindowTask *wt, + CONST_STRPTR iconName, + struct AVInfo *avInfo, struct VideoFrame *vFrame, + ULONG quality, ULONG SupportedColors, ULONG ReservedColors, + ULONG ScaledWidth, ULONG ScaledHeight, + struct Screen *WBScreen, struct ScalosPreviewResult *PVResult) +{ + BOOL Success = FALSE; + struct ARGBHeader argbTemp = { 0, 0, NULL }; + struct ScalosBitMapAndColor *sacSrc = NULL; + struct ScalosBitMapAndColor *sacDest = NULL; + struct BitMap *TempBM = NULL; + + d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__)); + + do { + struct ARGB *pLine; + const UBYTE *src; + ULONG Depth; + ULONG y; + + argbTemp.argb_Width = vFrame->vfr_width; + argbTemp.argb_Height = vFrame->vfr_height; + argbTemp.argb_ImageData = ScalosGfxCreateARGB(argbTemp.argb_Width, argbTemp.argb_Height, NULL); + d1(KPrintF("%s/%s/%ld: argb_ImageData=%08lx\n", __FILE__, __FUNC__, __LINE__, argbTemp.argb_ImageData)); + if (NULL == argbTemp.argb_ImageData) + break; + + // Fill argbSrc with image from vFrame + pLine = argbTemp.argb_ImageData; + src = avInfo->avinf_pFrame->data[0]; + for (y = 0; y < vFrame->vfr_height; y++) + { + ULONG x; + + for (x = 0; x < vFrame->vfr_width; x++) + { + pLine->Red = *src++; + pLine->Green = *src++; + pLine->Blue = *src++; + pLine->Alpha = (UBYTE) ~0; + + pLine++; + } + } + + // Limit color depth to the number of colors supported by the icon + for (Depth = 0; Depth < 7 && (1 << Depth) < SupportedColors; Depth++) + ; + + d1(KPrintF(__FILE__ "/%s/%ld: argb_ImageData: a=%ld r=%ld g=%ld b=%ld\n", \ + __FUNC__, __LINE__, argbTemp.argb_ImageData->Alpha, \ + argbTemp.argb_ImageData->Red, argbTemp.argb_ImageData->Green, \ + argbTemp.argb_ImageData->Blue)); + + d1(KPrintF(__FILE__ "/%s/%ld: SupportedColors=%lu Depth=%lu ReservedColors=%lu\n", \ + __FUNC__, __LINE__, SupportedColors, Depth, ReservedColors)); + + PVResult->spvr_sac = ScalosGfxMedianCutTags(&argbTemp, Depth, + SCALOSGFX_MedianCutFlags, SCALOSGFXFLAGF_MedianCut_FloydSteinberg, + SCALOSGFX_MedianCutFriendBitMap, NULL, + SCALOSGFX_MedianCutReservedColors, ReservedColors, + TAG_END); + d1(KPrintF(__FILE__ "/%s/%ld: sac=%08lx\n", __FUNC__, __LINE__, PVResult->spvr_sac)); + + d1(KPrintF(__FILE__ "/%s/%ld: sac_BitMap=%08lx\n", __FUNC__, __LINE__, PVResult->spvr_sac->sac_BitMap)); + d1(ByteDump((unsigned char *) PVResult->spvr_sac->sac_BitMap, sizeof(struct BitMap))); + + Success = TRUE; + } while (0); + + if (TempBM) + FreeBitMap(TempBM); + + ScalosGfxFreeARGB(&argbTemp.argb_ImageData); + ScalosGfxFreeSAC(sacSrc); + ScalosGfxFreeSAC(sacDest); + + d1(KPrintF("%s/%s/%ld: END Success=%08lx\n", __FILE__, __FUNC__, __LINE__, Success)); + + return Success; +} + +//----------------------------------------------------------------------------- + +static BOOL GenerateARGBThumbnail(struct ScaWindowTask *wt, + CONST_STRPTR iconName, + struct AVInfo *avInfo, struct VideoFrame *vFrame, + ULONG quality, + ULONG ScaledWidth, ULONG ScaledHeight, + struct ScalosPreviewResult *PVResult) +{ + BOOL Success = FALSE; + struct ARGBHeader argbSrc = { 0, 0, NULL }; + + d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__)); + + do { + struct ARGB *pLine; + const UBYTE *src; + ULONG y; + + argbSrc.argb_Width = vFrame->vfr_width; + argbSrc.argb_Height = vFrame->vfr_height; + argbSrc.argb_ImageData = ScalosGfxCreateARGB(argbSrc.argb_Width, argbSrc.argb_Height, NULL); + d1(KPrintF("%s/%s/%ld: argb_ImageData=%08lx\n", __FILE__, __FUNC__, __LINE__, argbSrc.argb_ImageData)); + if (NULL == argbSrc.argb_ImageData) + break; + + // Fill argbSrc with image from vFrame + pLine = argbSrc.argb_ImageData; + src = avInfo->avinf_pFrame->data[0]; + for (y = 0; y < vFrame->vfr_height; y++) + { + ULONG x; + + for (x = 0; x < vFrame->vfr_width; x++) + { + pLine->Red = *src++; + pLine->Green = *src++; + pLine->Blue = *src++; + pLine->Alpha = (UBYTE) ~0; + + pLine++; + } + } + + PVResult->spvr_ARGBheader = argbSrc; + memset(&argbSrc, 0, sizeof(argbSrc)); + + Success = TRUE; + } while (0); + + if (!Success) + ScalosGfxFreeARGB(&argbSrc.argb_ImageData); + + d1(KPrintF("%s/%s/%ld: END Success=%ld\n", __FILE__, __FUNC__, __LINE__, Success)); + + return Success; +} + +//----------------------------------------------------------------------------- + +static void CleanupAVInfo(struct AVInfo *avInfo) +{ + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); + + d1(KPrintF("%s/%s/%ld: avinf_pCodecContext=%08lx avinf_CodecOpened=%ld\n", __FILE__, __FUNC__, __LINE__, \ + avInfo->avinf_pCodecContext, avInfo->avinf_CodecOpened)); + if (avInfo->avinf_CodecOpened) + { + avcodec_close(avInfo->avinf_pCodecContext); + avInfo->avinf_pCodecContext = NULL; + avInfo->avinf_CodecOpened = FALSE; + } + d1(KPrintF("%s/%s/%ld: avinf_pFormatContext=%08lx\n", __FILE__, __FUNC__, __LINE__, avInfo->avinf_pFormatContext)); + if (avInfo->avinf_pFormatContext) + { + av_close_input_file(avInfo->avinf_pFormatContext); + avInfo->avinf_pFormatContext = NULL; + } + d1(KPrintF("%s/%s/%ld: avinf_pFrame=%08lx\n", __FILE__, __FUNC__, __LINE__, avInfo->avinf_pFrame)); + if (avInfo->avinf_pFrame) + { + av_free(avInfo->avinf_pFrame); + avInfo->avinf_pFrame = NULL; + } + d1(KPrintF("%s/%s/%ld: avinf_pRGBFrame=%08lx\n", __FILE__, __FUNC__, __LINE__, avInfo->avinf_pRGBFrame)); + if (avInfo->avinf_pRGBFrame) + { + av_free(avInfo->avinf_pRGBFrame); + avInfo->avinf_pRGBFrame = NULL; + } + d1(KPrintF("%s/%s/%ld: avinf_Buffer=%08lx\n", __FILE__, __FUNC__, __LINE__, avInfo->avinf_Buffer)); + if (avInfo->avinf_Buffer) + { + free(avInfo->avinf_Buffer); + avInfo->avinf_Buffer = NULL; + } + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); +} + +//----------------------------------------------------------------------------- + +static BOOL InitializeVideo(struct AVInfo *avInfo) +{ + BOOL Success = FALSE; + + do { + d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__)); + + // Retrieve stream information + if (av_find_stream_info(avInfo->avinf_pFormatContext) < 0) + { + d1(KPrintF("%s/%s/%ld: av_find_stream_info failed\n", __FILE__, __FUNC__, __LINE__)); + break; + } + + d1(KPrintF("%s/%s/%ld: nb_streams=%ld\n", __FILE__, __FUNC__, __LINE__, avInfo->avinf_pFormatContext->nb_streams)); + if (avInfo->avinf_pFormatContext->nb_streams < 1) + { + d1(KPrintF("%s/%s/%ld: no streams found\n", __FILE__, __FUNC__, __LINE__)); + break; + } + + // Find the first video stream + avInfo->avinf_VideoStream = av_find_default_stream_index(avInfo->avinf_pFormatContext); + + d1(KPrintF("%s/%s/%ld: avinf_VideoStream=%ld\n", __FILE__, __FUNC__, __LINE__, avInfo->avinf_VideoStream)); + if (NO_STREAM == avInfo->avinf_VideoStream) + { + d1(KPrintF("%s/%s/%ld: Could not find video stream\n", __FILE__, __FUNC__, __LINE__)); + break; + } + + avInfo->avinf_pVideoStream = avInfo->avinf_pFormatContext->streams[avInfo->avinf_VideoStream]; + + // Remember pointer to codec context for the video stream + avInfo->avinf_pCodecContext = avInfo->avinf_pVideoStream->codec; + + // Find decoder for the video stream + avInfo->avinf_pVideoCodec = avcodec_find_decoder(avInfo->avinf_pCodecContext->codec_id); + + d1(KPrintF("%s/%s/%ld: avinf_pCodecContext=%08lx avinf_pVideoCodec=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, avInfo->avinf_pCodecContext, avInfo->avinf_pVideoCodec)); + if (NULL == avInfo->avinf_pVideoCodec) + { + d1(KPrintF("%s/%s/%ld: Video Codec not found\n", __FILE__, __FUNC__, __LINE__)); + break; + } + + d1(KPrintF("%s/%s/%ld: Codec name=<%s>\n", __FILE__, __FUNC__, __LINE__, avInfo->avinf_pVideoCodec->name)); + + avInfo->avinf_pCodecContext->workaround_bugs = 1; + avInfo->avinf_pFormatContext->flags |= AVFMT_FLAG_GENPTS; + if(avInfo->avinf_pVideoCodec->capabilities & CODEC_CAP_TRUNCATED) + avInfo->avinf_pCodecContext->flags|= CODEC_FLAG_TRUNCATED; /* we dont send complete frames */ + +#if 1 + d1(KPrintF("%s/%s/%ld: width=%ld height=%ld pix_fmt=%ld\n", __FILE__, __FUNC__, __LINE__, \ + avInfo->avinf_pCodecContext->width, avInfo->avinf_pCodecContext->height, \ + avInfo->avinf_pCodecContext->pix_fmt)); + + if (0 == avInfo->avinf_pCodecContext->width) + { + break; + } +#endif + // Open codec + if (avcodec_open(avInfo->avinf_pCodecContext, avInfo->avinf_pVideoCodec) < 0) + { + d1(KPrintF("%s/%s/%ld: avcodec_open failed\n", __FILE__, __FUNC__, __LINE__)); + break; + } + avInfo->avinf_CodecOpened = TRUE; + + // Allocate video frame + avInfo->avinf_pFrame = avcodec_alloc_frame(); + d1(KPrintF("%s/%s/%ld: avinf_pFrame=%08lx\n", __FILE__, __FUNC__, __LINE__, avInfo->avinf_pFrame)); + if (NULL == avInfo->avinf_pFrame) + break; + + if (!AllocFrameData(&avInfo->avinf_pRGBFrame, + avInfo->avinf_pCodecContext->width, + avInfo->avinf_pCodecContext->height, + PIX_FMT_RGB24)) + { + break; + } + + Success = TRUE; + } while (0); + + d1(KPrintF("%s/%s/%ld: END Success=%ld\n", __FILE__, __FUNC__, __LINE__, Success)); + + return Success; +} + +//----------------------------------------------------------------------------- + +static BOOL ReadVideoFrame(struct AVInfo *avInfo) +{ + AVPacket packet; + int frameFinished = FALSE; + ULONG Tries = 0; + + d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__)); + + av_init_packet(&packet); + + while (av_read_frame(avInfo->avinf_pFormatContext, &packet) >= 0) + { + // Is this a packet from the video stream? + if (packet.stream_index == avInfo->avinf_VideoStream) + { + int size = packet.size; + UBYTE *buffer = packet.data; + + while ((size > 0) && !frameFinished) + { + int bytesDecoded; + + bytesDecoded = avcodec_decode_video(avInfo->avinf_pCodecContext, + avInfo->avinf_pFrame, + &frameFinished, + buffer, + size); + + d1(KPrintF("%s/%s/%ld: packet.size=%d frameFinished=%ld bytesDecoded=%ld\n", \ + __FILE__, __FUNC__, __LINE__, packet.size, frameFinished, bytesDecoded)); + d1(KPrintF("%s/%s/%ld: pix_fmt=%d width=%ld height=%ld\n", \ + __FILE__, __FUNC__, __LINE__, avInfo->avinf_pCodecContext->pix_fmt, \ + avInfo->avinf_pCodecContext->width, avInfo->avinf_pCodecContext->height)); + + if (bytesDecoded < 0) + break; // failure + + if (frameFinished && (bytesDecoded >= 0)) + { + struct SwsContext *ImgConvertContext; + int rc; + + d1( { \ + char buffer[80]; \ + sprintf(buffer, "pts=%llu dts=%llu", packet.pts, packet.dts); + KPrintF("%s/%s/%ld: %s\n", __FILE__, __FUNC__, __LINE__, buffer); \ + } ); + + // Convert frame image from native format to RGB + ImgConvertContext = sws_getContext(avInfo->avinf_pCodecContext->width, + avInfo->avinf_pCodecContext->height, + avInfo->avinf_pCodecContext->pix_fmt, + avInfo->avinf_pCodecContext->width, + avInfo->avinf_pCodecContext->height, + PIX_FMT_RGB24, + SWS_FAST_BILINEAR, + NULL, + NULL, + NULL); + + if (NULL == ImgConvertContext) + break; + + rc = sws_scale(ImgConvertContext, + avInfo->avinf_pFrame->data, + avInfo->avinf_pFrame->linesize, + 0, + avInfo->avinf_pCodecContext->height, + avInfo->avinf_pRGBFrame->data, + avInfo->avinf_pRGBFrame->linesize); + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + sws_freeContext(ImgConvertContext); + + if (-1 == rc) + break; // failure + break; + } + + buffer += bytesDecoded; + size -= bytesDecoded; + + if (Tries++ > 1000) + break; + } + } + + av_free_packet(&packet); + + if (Tries++ > 1000) + break; + } + + d1(KPrintF("%s/%s/%ld: frameFinished=%ld\n", __FILE__, __FUNC__, __LINE__, frameFinished)); + + av_free_packet(&packet); + + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); + + return (BOOL) frameFinished; +} + +//----------------------------------------------------------------------------- + +static BOOL GetScaledVideoFrame(struct AVInfo *avInfo, int scaledSize, + ULONG quality, struct VideoFrame *videoFrame) +{ + BOOL Success = FALSE; + + do { + int scaledWidth, scaledHeight; + + if (!ConvertAndScaleFrame(avInfo, PIX_FMT_RGB24, scaledSize, + &scaledWidth, &scaledHeight, quality)) + break; + + d1(KPrintF("%s/%s/%ld: ConvertAndScaleFrame success\n", __FILE__, __FUNC__, __LINE__)); + + videoFrame->vfr_width = scaledWidth; + videoFrame->vfr_height = scaledHeight; + videoFrame->vfr_lineSize = avInfo->avinf_pFrame->linesize[0]; + + d1(KPrintF("%s/%s/%ld: vfr_width=%ld vfr_height=%ld vfr_lineSize=%ld\n", __FILE__, __FUNC__, __LINE__, \ + videoFrame->vfr_width, videoFrame->vfr_height, videoFrame->vfr_lineSize)); + + Success = TRUE; + } while (0); + + return Success; +} + +//----------------------------------------------------------------------------- + +static BOOL ConvertAndScaleFrame(struct AVInfo *avInfo, int pixFormat, + int scaledSize, int *scaledWidth, int *scaledHeight, ULONG quality) +{ + AVFrame *convertedFrame = NULL; + struct SwsContext *scaleContext; + BOOL Success = FALSE; + + do { + int ScaleFlags; + + if (quality > 10) + ScaleFlags = SWS_BICUBIC; + else if (quality > 5) + ScaleFlags = SWS_BILINEAR; + else + ScaleFlags = SWS_FAST_BILINEAR; + + CalculateDimensions(avInfo->avinf_pCodecContext->width, + avInfo->avinf_pCodecContext->height, + scaledSize, + scaledWidth, + scaledHeight); + d1(KPrintF("%s/%s/%ld: width=%ld height=%ld\n", __FILE__, __FUNC__, __LINE__, + avInfo->avinf_pCodecContext->width, avInfo->avinf_pCodecContext->height)); + d1(KPrintF("%s/%s/%ld: scaledWidth=%ld scaledHeight=%ld\n", \ + __FILE__, __FUNC__, __LINE__, *scaledWidth, *scaledHeight)); + + d1({ \ + ULONG n; \ + const UBYTE *p = avInfo->avinf_pFrame->data[0]; \ + \ + for (n = 0; n < avInfo->avinf_pCodecContext->height; n++) \ + { \ + ByteDump(p, avInfo->avinf_pFrame->linesize[0]); \ + p += avInfo->avinf_pFrame->linesize[0]; \ + } \ + }); + + scaleContext = sws_getContext(avInfo->avinf_pCodecContext->width, + avInfo->avinf_pCodecContext->height, + avInfo->avinf_pCodecContext->pix_fmt, + *scaledWidth, + *scaledHeight, + pixFormat, + ScaleFlags, + NULL, + NULL, + NULL); + + d1(KPrintF("%s/%s/%ld: scaleContext=%08lx\n", __FILE__, __FUNC__, __LINE__, scaleContext)); + if (NULL == scaleContext) + break; + + if (!AllocFrameData(&convertedFrame, *scaledWidth, *scaledHeight, pixFormat)) + break; + + d1(KPrintF("%s/%s/%ld: convertedFrame=%08lx\n", __FILE__, __FUNC__, __LINE__, convertedFrame)); + if (NULL == convertedFrame) + break; + + sws_scale(scaleContext, + avInfo->avinf_pFrame->data, + avInfo->avinf_pFrame->linesize, + 0, + avInfo->avinf_pCodecContext->height, + convertedFrame->data, + convertedFrame->linesize); + + Success = TRUE; + } while (0); + + if (scaleContext) + sws_freeContext(scaleContext); + + if (Success) + { + av_free(avInfo->avinf_pFrame); + avInfo->avinf_pFrame = convertedFrame; + } + + return Success; +} + +//----------------------------------------------------------------------------- + +static void CalculateDimensions(int srcWidth, int srcHeight, int squareSize, int *destWidth, int *destHeight) +{ + if (srcWidth > srcHeight) + { + *destWidth = squareSize; + *destHeight = (int) ((float)(squareSize) / srcWidth * srcHeight); + } + else + { + *destWidth = (int)((float)(squareSize) / srcHeight * srcWidth); + *destHeight = squareSize; + } +} + +//----------------------------------------------------------------------------- + +static BOOL AllocFrameData(AVFrame **avFrame, int width, int height, int pixFormat) +{ + int numBytes; + + *avFrame = avcodec_alloc_frame(); + d1(KPrintF("%s/%s/%ld: *avFrame=%08lx\n", __FILE__, __FUNC__, __LINE__, *avFrame)); + if (NULL == *avFrame) + return FALSE; + + numBytes = avpicture_get_size(pixFormat, width, height); + d1(KPrintF("%s/%s/%ld: numBytes=%ld\n", __FILE__, __FUNC__, __LINE__, numBytes)); + + if (0 != avpicture_alloc((AVPicture *) *avFrame, pixFormat, width, height)) + { + d1(KPrintF("%s/%s/%ld: avpicture_alloc failed\n", __FILE__, __FUNC__, __LINE__)); + return FALSE; + } + + return TRUE; +} + +//----------------------------------------------------------------------------- + +static BOOL VideoSeekFrame(struct AVInfo *avInfo, float timeInSeconds) +{ + int rc; +// int64_t timestamp = (int64_t) (10 * AV_TIME_BASE * timeInSeconds); + int64_t timestamp = (int64_t) (AV_TIME_BASE * timeInSeconds); + + do { + int count = 0; + BOOL foundFrame; + + d1( { \ + char buffer[40]; \ + sprintf(buffer, "timeInSeconds=%f timestamp=%llu", timeInSeconds, timestamp); \ + KPrintF("%s/%s/%ld: %s\n", __FILE__, __FUNC__, __LINE__, buffer); \ + } ); + + rc = av_seek_frame(avInfo->avinf_pFormatContext, -1, timestamp, 0); + d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__, __FUNC__, __LINE__, rc)); + if (rc < 0) + break; + + do { + foundFrame = ReadVideoFrame(avInfo); + + d1(KPrintF("%s/%s/%ld: foundFrame=%ld count=%ld\n", __FILE__, __FUNC__, __LINE__, foundFrame, ++count)); + } while (!foundFrame /* && !avInfo->avinf_pFrame->key_frame */ && ++count < 20); + + d1( { \ + char buffer[80]; \ + + sprintf(buffer, "pts=%f coded_picture_number=%d display_picture_number=%d", \ + (float) (avInfo->avinf_pFrame->pts * avInfo->avinf_pCodecContext->time_base.num) \ + / (float) avInfo->avinf_pCodecContext->time_base.den, \ + avInfo->avinf_pFrame->coded_picture_number, \ + avInfo->avinf_pFrame->display_picture_number); \ + KPrintF("%s/%s/%ld: %s\n", __FILE__, __FUNC__, __LINE__, buffer); \ + } ); + } while (0); + + return TRUE; +} + +//----------------------------------------------------------------------------- + +static void OverlayFilmStrip(struct AVInfo *avInfo, struct VideoFrame *videoFrame) +{ + static const UBYTE filmHole[FILMHOLE_WIDTH * FILMHOLE_HEIGHT * 3] = + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x23, 0x23, 0x7a, 0x7a, 0x7a, 0x83, 0x83, 0x83, 0x8c, 0x8c, 0x8c, 0x90, 0x90, 0x90, 0x8e, 0x8e, 0x8e, 0x52, 0x52, 0x52, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e, 0x83, 0x83, 0x83, 0x93, 0x93, 0x93, 0xa3, 0xa3, 0xa3, 0xab, 0xab, 0xab, 0xa8, 0xa8, 0xa8, 0x9b, 0x9b, 0x9b, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x72, 0x72, 0x8e, 0x8e, 0x8e, 0xa4, 0xa4, 0xa4, 0xbb, 0xbb, 0xbb, 0xc4, 0xc4, 0xc4, 0xc1, 0xc1, 0xc1, 0xaf, 0xaf, 0xaf, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x3e, 0x3e, 0x90, 0x90, 0x90, 0xa6, 0xa6, 0xa6, 0xbe, 0xbe, 0xbe, 0xc8, 0xc8, 0xc8, 0xc4, 0xc4, 0xc4, 0x8e, 0x8e, 0x8e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + int frameIndex = 0; + int filmHoleIndex = 0; + int offset = (videoFrame->vfr_width * 3) - 3; + UBYTE *pRGB = avInfo->avinf_pFrame->data[0]; + ULONG i; + + for (i = 0; i < videoFrame->vfr_height; ++i) + { + ULONG j; + + for (j = 0; j < FILMHOLE_WIDTH * 3; j+=3) + { + int currentFilmHoleIndex = filmHoleIndex + j; + + pRGB[frameIndex + j] = filmHole[currentFilmHoleIndex]; + pRGB[frameIndex + j + 1] = filmHole[currentFilmHoleIndex + 1]; + pRGB[frameIndex + j + 2] = filmHole[currentFilmHoleIndex + 2]; + + pRGB[frameIndex + offset - j] = filmHole[currentFilmHoleIndex]; + pRGB[frameIndex + offset - j + 1] = filmHole[currentFilmHoleIndex + 1]; + pRGB[frameIndex + offset - j + 2] = filmHole[currentFilmHoleIndex + 2]; + } + frameIndex += videoFrame->vfr_lineSize; + filmHoleIndex = (i % FILMHOLE_HEIGHT) * FILMHOLE_WIDTH * 3; + } +} + +//----------------------------------------------------------------------------- + +#define BORING_IMAGE_VARIANCE 512.0 /* Tweak this if necessary */ + +/* This function attempts to detect images that are mostly solid images + * It does this by calculating the statistical variance of the + * black-and-white image */ +static BOOL IsInterestingFrame(const struct AVInfo *avInfo) +{ + /* We're gonna assume 8-bit samples. If anyone uses anything different, + * it doesn't really matter cause it's gonna be ugly anyways */ + float variance = 0.0f; + float average = 0.0f; + ULONG NumberOfSamples; + ULONG y; + + /* FIXME: If this proves to be a performance issue, this function + * can be modified to perhaps only check 3 rows. I doubt this'll + * be a problem though. */ + + NumberOfSamples = avInfo->avinf_pCodecContext->width * avInfo->avinf_pCodecContext->height; + NumberOfSamples /= 2; + + // Iterate through the RGB image to calculate average + for (y = 0; y < avInfo->avinf_pCodecContext->height; y += 2) + { + const UBYTE *pBuffer = avInfo->avinf_pRGBFrame->data[0] + y * avInfo->avinf_pRGBFrame->linesize[0]; + ULONG x; + + for (x = 0; x < avInfo->avinf_pCodecContext->width; x++) + { + average += (float) (pBuffer[0] + pBuffer[1] + pBuffer[2]); + pBuffer += 3; + } + } + average /= ((float) (3 * NumberOfSamples)); + + /* Calculate the variance */ + for (y = 0; y < avInfo->avinf_pCodecContext->height; y++) + { + const UBYTE *pBuffer = avInfo->avinf_pRGBFrame->data[0] + y * avInfo->avinf_pRGBFrame->linesize[0]; + ULONG x; + + for (x = 0; x < avInfo->avinf_pCodecContext->width; x++) + { + float tmp = (float) ((pBuffer[0] + pBuffer[1] + pBuffer[2]) / 3) - average; + + variance += tmp * tmp; + pBuffer += 3; + } + } + variance /= ((float) (NumberOfSamples - 1)); + + d1( { \ + char buffer[80]; \ + sprintf(buffer, "average=%f variance=%f", average, variance); \ + KPrintF("%s/%s/%ld: %s\n", __FILE__, __FUNC__, __LINE__, buffer); \ + } ); + + d1(KPrintF("%s/%s/%ld: IsInterestingFrame=%ld\n", __FILE__, __FUNC__, __LINE__, (variance > BORING_IMAGE_VARIANCE))); + + return (variance > BORING_IMAGE_VARIANCE); +} + +//----------------------------------------------------------------------------- + +static BOOL FindInterestingFrame(struct AVInfo *avInfo) +{ + ULONG n = 0; + float framePosition = 1.2; + float FramePositionStep = 0.25; + + for (n = 0; !IsInterestingFrame(avInfo) && n < 10; n++) + { + d1(KPrintF("%s/%s/%ld: n=%ld\n", __FILE__, __FUNC__, __LINE__, n)); + if (!VideoSeekFrame(avInfo, framePosition)) + { + d1(KPrintF("%s/%s/%ld: VideoSeekFrame failed n=%ld\n", __FILE__, __FUNC__, __LINE__, n)); + return FALSE; + } + framePosition += FramePositionStep; + FramePositionStep += FramePositionStep; // double step size on each loop + } + + d1(KPrintF("%s/%s/%ld: Success n=%ld\n", __FILE__, __FUNC__, __LINE__, n)); + + return TRUE; +} + +//----------------------------------------------------------------------------- + +static void av_log_dummy_callback(void* ptr, int level, const char* fmt, va_list vl) +{ +#if 0 + char buf[256]; + + d1(KPrintF("%s/%s/%ld: fmt=<%s> level=%ld\n", __FILE__, __FUNC__, __LINE__, fmt, level)); + + (void) ptr; + (void) fmt; + (void) vl; + + vsnprintf(buf, sizeof(buf), fmt, vl); + d1(KPrintF("%s/%s/%ld: %s\n", __FILE__, __FUNC__, __LINE__, buf)); +#endif +} + +//----------------------------------------------------------------------------- + +void abort(void) +{ + while (1) + ; +} + +//----------------------------------------------------------------------------- + +#if BYTEDUMP +static void ByteDump(const unsigned char *Data, size_t Length) +{ + unsigned long count; + unsigned char Line[80], *lp; + + lp = Line; + for (count=0; count +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#undef GLOBAL + +#include "Video.h" + +//--------------------------------------------------------------------------------------- + +static int infunc(const unsigned char **s); +static void unfunc(int c, const unsigned char **s); +static double mypow10(int n); +static int _scanfshared(int (*infunc)(void *inarg),void (*unfunc)(int c, void *inarg),void *inarg,const char *format,va_list args); + +//--------------------------------------------------------------------------------------- + +int fputc(int c, FILE *stream) +{ + d1(KPrintF("%s/%s/%ld: stream=%08lx c=%c\n", __FILE__, __FUNC__, __LINE__, stream, c)); + // Writing is not supported + return -1; +} + +//----------------------------------------------------------------------------- + +int fseek(FILE *fh, long offset, int origin) +{ + LONG OldPos; + LONG mode; + + d1(KPrintF("%s/%s/%ld: fh=%08lx offset=%ld origin=%ld\n", \ + __FILE__, __FUNC__, __LINE__, fh, offset, origin)); + + switch (origin) + { + case SEEK_SET: + mode = OFFSET_BEGINNING; + break; + case SEEK_CUR: + mode = OFFSET_CURRENT; + break; + case SEEK_END: + mode = OFFSET_END; + break; + default: + return -1; + break; + } + + errno = 0; + + OldPos = Seek((BPTR) fh, offset, mode); + d1(kprintf("%s/%s/%ld: OldPos=%ld\n", __FILE__, __FUNC__, __LINE__, OldPos)); + + return OldPos >= 0 ? 0 : -1; +} + +//----------------------------------------------------------------------------- + +int unlink(const char *FileName) +{ + // Deleting files is not supported + d1(KPrintF("%s/%s/%ld: FileName=<%s>\n", __FILE__, __FUNC__, __LINE__, FileName)); + + errno = 0; + + return -1; +} + +//----------------------------------------------------------------------------- + +int fprintf(FILE *fh, const char *fmt, ...) +{ +#if 1 + d1(KPrintF("%s/%s/%ld: fmt=<%s>\n", __FILE__, __FUNC__, __LINE__, fmt)); +#else + char buf[256]; + va_list ap; + + d1(KPrintF("%s/%s/%ld: fmt=<%s>\n", __FILE__, __FUNC__, __LINE__, fmt)); + + (void) fh; + (void) fmt; + + va_start(ap, fmt); + + vsnprintf(buf, sizeof(buf), fmt, ap); + d1(KPrintF("%s/%s/%ld: %s\n", __FILE__, __FUNC__, __LINE__, buf)); + + va_end(ap); +#endif + return 0; +} + +//----------------------------------------------------------------------------- + +int vfprintf(FILE *fh, const char *fmt, va_list ap) +{ +#if 1 + d1(KPrintF("%s/%s/%ld: fmt=<%s>\n", __FILE__, __FUNC__, __LINE__, fmt)); +#else + char buf[256]; + + d1(KPrintF("%s/%s/%ld: fmt=<%s>\n", __FILE__, __FUNC__, __LINE__, fmt)); + + (void) fh; + (void) fmt; + (void) ap; + + vsnprintf(buf, sizeof(buf), fmt, ap); + d1(KPrintF("%s/%s/%ld: %s\n", __FILE__, __FUNC__, __LINE__, buf)); +#endif + return 0; +} + +//----------------------------------------------------------------------------- + +/* +DESCRIPTION + + The mkstemp() function shall replace the contents of the string pointed to + by template by a unique filename, and return a file descriptor + for the file open for reading and writing. + The function thus prevents any possible race condition between testing + whether the file exists and opening it for use. + The string in template should look like a filename with six trailing 'X' s; + mkstemp() replaces each 'X' with a character from the portable filename + character set. The characters are chosen such that the resulting name + does not duplicate the name of an existing file + at the time of a call to mkstemp(). + +RETURN VALUE + + Upon successful completion, mkstemp() shall return an open file descriptor. + Otherwise, -1 shall be returned if no suitable file could be created. +*/ + +int mkstemp(char *template) +{ + return -1; +} + +//----------------------------------------------------------------------------- + +/* + These functions shall round their argument to the nearest integer value, + rounding according to the current rounding direction. + +RETURN VALUE + Upon successful completion, these functions shall return the rounded integer value. + [MX] [Option Start] If x is NaN, a domain error shall occur, and an unspecified value is returned. + If x is +Inf, a domain error shall occur and an unspecified value is returned. + If x is -Inf, a domain error shall occur and an unspecified value is returned. + If the correct value is positive and too large to represent as a long long, a domain error shall occur and an unspecified value is returned. + If the correct value is negative and too large to represent as a long long, a domain error shall occur and an unspecified value is returned. [Option End] +*/ + +long long int llrint(double x) +{ +#warning need some work here + return (long long) x; +} + +//----------------------------------------------------------------------------- + +int puts(const char *s) +{ + d1(KPrintF("%s/%s/%ld: s=<%s>\n", __FILE__, __FUNC__, __LINE__, s)); + return 0; +} + +//----------------------------------------------------------------------------- + +int fputs(const char *s, FILE *fp) +{ + (void) fp; + + d1(KPrintF("%s/%s/%ld: s=<%s>\n", __FILE__, __FUNC__, __LINE__, s)); + return 0; +} + +//----------------------------------------------------------------------------- + +void perror(const char *s) +{ + d1(KPrintF("%s/%s/%ld: s=<%s>\n", __FILE__, __FUNC__, __LINE__, s)); +} + +//----------------------------------------------------------------------------- + +/* +The memalign() function returns a block of memory of +size bytes aligned to blocksize. The blocksize must be given +as a power of two. It sets errno and returns a null pointer upon failure. + +Pointers returned by memalign() may be passed to free(). +Pointers passed to realloc() are checked and if not +aligned to the system, the realloc() fails and returns NULL. +*/ +void *memalign(size_t blocksize, size_t bytes) +{ + d1(KPrintF("%s/%s/%ld: blocksize=%lu bytes=%lu\n", __FILE__, __FUNC__, __LINE__, blocksize, bytes)); + (void) blocksize; + + return malloc(bytes); +} + +//----------------------------------------------------------------------------- + +int errno = 0; + +//int stderr = 0; + +//----------------------------------------------------------------------------- + +int sprintf(char *s, const char *fmt, ...) +{ + d1(KPrintF("%s/%s/%ld: fmt=<%s>\n", __FILE__, __FUNC__, __LINE__, fmt)); + *s = 0; + return 0; +} + +//----------------------------------------------------------------------------- + +int snprintf(char *s, size_t maxlen, const char *fmt, ...) +{ + d1(KPrintF("%s/%s/%ld: fmt=<%s>\n", __FILE__, __FUNC__, __LINE__, fmt)); + *s = 0; + return 0; +} + +//----------------------------------------------------------------------------- + +int sscanf(const char *ss, const char *fmt, ...) +{ + int retval; + va_list args; + + va_start(args, fmt); + retval = vsscanf(ss, fmt, args); + va_end(args); + + d1(KPrintF("%s/%s/%ld: ss=<%s> fmt=<%s> retval=%ld\n", __FILE__, __FUNC__, __LINE__, ss, fmt, retval)); + + return retval; +} + +static int infunc(const unsigned char **s) +{ + int c; + + c = (int)**s; + + if (c) (*s)++; + else c = EOF; + + return c; +} + +static void unfunc(int c, const unsigned char **s) +{ + (*s)--; +} + +int vsscanf(const char *s,const char *format,va_list args) +{ + return _scanfshared((int (*)(void *))infunc, (void (*)(int, void *))unfunc, &s, format, args); +} + +/* some macros to cut this short + * NEXT(c); read next character + * PREV(c); ungetc a character + * VAL(a) leads to 1 if a is true and valid + */ +#define NEXT(c) ((c)=infunc(inarg),size++,incount++) +#define PREV(c) do{if((c)!=EOF)unfunc((c),inarg);size--;incount--;}while(0) +#define VAL(a) ((a)&&size<=width) + +extern unsigned char *__decimalpoint; + +static unsigned char undef[3][sizeof(double)]= /* Undefined numeric values, IEEE */ +{ { 0x7f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00 }, /* +inf */ + { 0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00 }, /* -inf */ + { 0x7f,0xf1,0x00,0x00,0x00,0x00,0x00,0x00 } /* NaN */ +}; + +static double mypow10(int n) +{ + int neg=0; + double x=1.0; + double y=10.0; + if(n==0) + return 1.0; + if(n<0) + { neg=1; + n=-n; } + while(n) + { if(n&1) + x*=y; + y*=y; + n>>=1; } + if(neg) + x=1/x; + return x; +} + +static int _scanfshared(int (*infunc)(void *inarg),void (*unfunc)(int c, void *inarg),void *inarg,const char *format,va_list args) +{ + size_t blocks=0,incount=0; + int c=0; + + while(*format) + { + size_t size=0; + + if(*format=='%') + { + size_t width=ULONG_MAX; + char type,subtype='i',ignore=0; + const unsigned char *ptr=format+1; + size_t i; + + if(isdigit(*ptr)) + { width=0; + while(isdigit(*ptr)) + width=width*10+(*ptr++-'0'); } + + while(*ptr=='h'||*ptr=='L'||*ptr=='*'||*ptr=='l') + { if(*ptr=='*') + ignore=1; + else + { + if (*ptr=='l'&&subtype=='l') subtype='L'; + else subtype=*ptr; + } + ptr++; + } + + type=*ptr++; + + if(type&&type!='%'&&type!='c'&&type!='n'&&type!='[') + { do /* ignore leading whitespace characters */ + NEXT(c); + while(isspace(c)); + size=1; } /* The first non-whitespace character is already read */ + + switch(type) + { case 'c': + { unsigned char *bp; + + if(width==ULONG_MAX) /* Default */ + width=1; + + if(!ignore) + bp=va_arg(args,char *); + else + bp=NULL; /* Just to get the compiler happy */ + + NEXT(c); /* 'c' did not skip whitespace */ + while(VAL(c!=EOF)) + { if(!ignore) + *bp++=c; + NEXT(c); + } + PREV(c); + + if(!ignore&&size) + blocks++; + break; + } + case '[': + { unsigned char *bp; + unsigned char tab[32],a,b; + char circflag=0; + + if(*ptr=='^') + { circflag=1; + ptr++; } + for(i=0;i malformatted */ + { PREV(c); + c=__decimalpoint[0]; } + } + + if(min&&size==2) /* No number read till now -> malformatted */ + { PREV(c); + c=min; } + if(size==1) + break; + + if(VAL(tolower(c)=='e')) + { int d; + NEXT(d); + if(VAL(d=='-'||d=='+')) + { mine=d; + NEXT(d); } + + if(VAL(isdigit(d))) + { do + { ex=ex*10+(d-'0'); + NEXT(d); + }while(VAL(isdigit(d)&&ex<100)); + c=d; + }else + { PREV(d); + if(mine) + PREV(mine); + } + } + PREV(c); + + if(mine=='-') + v=v/mypow10(ex); + else + v=v*mypow10(ex); + + if(min=='-') + v=-v; + + }while(0); + + if(!ignore&&size) + { switch(subtype) + { case 'L': +#warning "FIXME: llf will be treated as Lf (double in current implementation) now!" + case 'l': + *va_arg(args,double *)=v; + break; + case 'i': + *va_arg(args,float *)=v; + break; + } + blocks++; + } + break; + } + case '%': + NEXT(c); + if(c!='%') + PREV(c); /* unget non-'%' character */ + break; + case 'n': + if(!ignore) + *va_arg(args,int *)=incount; + size=1; /* fake a valid argument */ + break; + default: + { unsigned long long v=0; + int base; + int min=0; + + if(!type) + ptr--; /* unparse NUL character */ + + if(type=='p') + { /*subtype='l';*/ /* This is the same as %lx */ + type='x'; } + + if(VAL((c=='-'&&type!='u')||c=='+')) + { min=c; + NEXT(c); } + + if(type=='i') /* which one to use ? */ + { if(VAL(c=='0')) /* Could be octal or sedecimal */ + { int d; + NEXT(d); /* Get a look at next character */ + if(VAL(tolower(d)=='x')) + { int e; + NEXT(e); /* And the next */ + if(VAL(isxdigit(c))) + type='x'; /* Is a valid x number with '0x?' */ + PREV(e); + }else + type='o'; + PREV(d); + }else if(VAL(!isdigit(c)&&isxdigit(c))) + type='x'; /* Is a valid x number without '0x' */ + } + + while(type=='x'&&VAL(c=='0')) /* sedecimal */ + { int d; + NEXT(d); + if(VAL(tolower(d)=='x')) + { int e; + NEXT(e); + if(VAL(isxdigit(e))) + { c=e; + break; } /* Used while just to do this ;-) */ + PREV(e); + } + PREV(d); + break; /* Need no loop */ + } + + base=type=='x'||type=='X'?16:(type=='o'?8:10); + while(VAL(isxdigit(c)&&(base!=10||isdigit(c))&&(base!=8||c<='7'))) + { v=v*base+(isdigit(c)?c-'0':0)+(isupper(c)?c-'A'+10:0)+(islower(c)?c-'a'+10:0); + NEXT(c); + } + + if(min&&size==2) /* If there is no valid character after sign, unget last */ + { PREV(c); + c=min; } + + PREV(c); + + if(ignore||!size) + break; + + if(type=='u') + switch(subtype) + { case 'L': + *va_arg(args,unsigned long long *)=v; + break; + case 'l': + case 'i': + *va_arg(args,unsigned int *)=v; + break; + case 'h': + *va_arg(args,unsigned short *)=v; + break; + } + else + { signed long long v2; + if(min=='-') + v2=-v; + else + v2=v; + switch(subtype) + { case 'L': + *va_arg(args,signed long long *)=v2; + break; + case 'l': + case 'i': + *va_arg(args,signed int *)=v2; + break; + case 'h': + *va_arg(args,signed short *)=v2; + break; + } + } + blocks++; + break; + } + } + format=ptr; + }else + { if(isspace(*format)) + { do + NEXT(c); + while(isspace(c)); + PREV(c); + size=1; } + else + { NEXT(c); + if(c!=*format) + PREV(c); } + format++; + } + if(!size) + break; + } + + if(c==EOF&&!blocks) + return c; + else + return blocks; +} + +//----------------------------------------------------------------------------- + +void __assertion_failure(const char *file_name,int line_number,const char * expression) +{ + d1(kprintf("ASSERT %s/%ld: %s\n", file_name, line_number, expression)); +} + +//----------------------------------------------------------------------------- + +#if 0 +struct InitListStruct + { + void (* FuncPtr)(void); + LONG Priority; + }; + +extern void *__INIT_LIST__[]; +extern void *__EXIT_LIST__[]; +#endif + +extern struct DosLibrary *__DOSBase; +extern struct Library *MathIeeeSingBasBase; +extern struct Library *MathIeeeDoubBasBase; +extern struct Library *MathIeeeDoubTransBase; +extern T_UTILITYBASE __UtilityBase; + +static struct Library *MathIeeeSingBasBaseClone; +static struct Library *MathIeeeDoubBasBaseClone; +static struct Library *MathIeeeDoubTransBaseClone; + +static struct SignalSemaphore VideoSema; + +BOOL InitExtra(void) +{ + BOOL Success = FALSE; + + do { + InitSemaphore(&VideoSema); + + __DOSBase = DOSBase; + + MathIeeeSingBasBase = MathIeeeSingBasBaseClone = OpenLibrary("mathieeesingbas.library", 39); + d1(kprintf("%s/%s/%ld: MathIeeeSingBasBase=%08lx\n", __FILE__, __FUNC__, __LINE__, MathIeeeSingBasBase)); + if (NULL == MathIeeeSingBasBase) + break; + + MathIeeeDoubBasBase = MathIeeeDoubBasBaseClone = OpenLibrary("mathieeedoubbas.library", 39); + d1(kprintf("%s/%s/%ld: MathIeeeDoubBasBase=%08lx\n", __FILE__, __FUNC__, __LINE__, MathIeeeDoubBasBase)); + if (NULL == MathIeeeDoubBasBase) + break; + + MathIeeeDoubTransBase = MathIeeeDoubTransBaseClone = OpenLibrary("mathieeedoubtrans.library", 39); + d1(kprintf("%s/%s/%ld: MathIeeeDoubTransBase=%08lx\n", __FILE__, __FUNC__, __LINE__, MathIeeeDoubTransBase)); + if (NULL == MathIeeeDoubTransBase) + break; + + __UtilityBase = UtilityBase; + Success = TRUE; + } while (0); + + d1(kprintf("%s/%s/%ld: MathIeeeSingBasBase=%08lx\n", __FILE__, __FUNC__, __LINE__, MathIeeeSingBasBase)); + + return Success; +} + + +void ExitExtra(void) +{ + if (MathIeeeSingBasBaseClone) + { + CloseLibrary(MathIeeeSingBasBaseClone); + MathIeeeSingBasBaseClone = NULL; + } + if (MathIeeeDoubBasBaseClone) + { + CloseLibrary(MathIeeeDoubBasBaseClone); + MathIeeeDoubBasBaseClone = NULL; + } + if (MathIeeeDoubTransBaseClone) + { + CloseLibrary(MathIeeeDoubTransBaseClone); + MathIeeeDoubTransBaseClone = NULL; + } +} + + +BOOL InitInstance(void) +{ + BOOL Success = FALSE; + + do { + ObtainSemaphore(&VideoSema); + + // Create private math library bases + + MathIeeeSingBasBase = OpenLibrary("mathieeesingbas.library", 39); + d1(kprintf("%s/%s/%ld: MathIeeeSingBasBase=%08lx\n", __FILE__, __FUNC__, __LINE__, MathIeeeSingBasBase)); + if (NULL == MathIeeeSingBasBase) + break; + + MathIeeeDoubBasBase = OpenLibrary("mathieeedoubbas.library", 39); + d1(kprintf("%s/%s/%ld: MathIeeeDoubBasBase=%08lx\n", __FILE__, __FUNC__, __LINE__, MathIeeeDoubBasBase)); + if (NULL == MathIeeeDoubBasBase) + break; + + MathIeeeDoubTransBase = OpenLibrary("mathieeedoubtrans.library", 39); + d1(kprintf("%s/%s/%ld: MathIeeeDoubTransBase=%08lx\n", __FILE__, __FUNC__, __LINE__, MathIeeeDoubTransBase)); + if (NULL == MathIeeeDoubTransBase) + break; + + Success = TRUE; + } while (0); + + d1(kprintf("%s/%s/%ld: MathIeeeSingBasBase=%08lx\n", __FILE__, __FUNC__, __LINE__, MathIeeeSingBasBase)); + + return Success; +} + + +void ExitInstance(void) +{ + // Fall back to global math library bases + if (MathIeeeSingBasBase) + { + CloseLibrary(MathIeeeSingBasBase); + MathIeeeSingBasBase = MathIeeeSingBasBaseClone; + } + if (MathIeeeDoubBasBase) + { + CloseLibrary(MathIeeeDoubBasBase); + MathIeeeDoubBasBase = MathIeeeDoubBasBaseClone; + } + if (MathIeeeDoubTransBase) + { + CloseLibrary(MathIeeeDoubTransBase); + MathIeeeDoubTransBase = MathIeeeDoubTransBaseClone; + } + + ReleaseSemaphore(&VideoSema); +} + +//----------------------------------------------------------------------------- + +struct iob ** __iob; // #define stderr (&__iob[2]) /* standard error file pointer */ +struct WBStartup *__WBenchMsg = NULL; + +//----------------------------------------------------------------------------- diff --git a/scalos/Plugins/Preview/Video/compat_mos.c b/scalos/Plugins/Preview/Video/compat_mos.c new file mode 100644 index 000000000..3799a3a9f --- /dev/null +++ b/scalos/Plugins/Preview/Video/compat_mos.c @@ -0,0 +1,559 @@ +// Video.c +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#include "Video.h" + +//--------------------------------------------------------------------------------------- + +BOOL InitExtra(void) +{ + return TRUE; +} + +void ExitExtra(void) +{ +} + +BOOL InitInstance(void) +{ + return TRUE; +} + +void ExitInstance(void) +{ +} + +//--------------------------------------------------------------------------------------- + +int open(const char *filename, int mode, int protection) +{ + BPTR fh; + + d1(KPrintF("%s/%s/%ld: name=<%s> mode=%d protection=%d\n", __FILE__, __FUNC__, __LINE__, filename, mode, protection)); + + fh = Open((STRPTR) filename, MODE_OLDFILE); + + return fh ? ((int) fh) : -1; +} + +//----------------------------------------------------------------------------- + +int close(int fh) +{ + d1(KPrintF("%s/%s/%ld: fh=%08lx\n", __FILE__, __FUNC__, __LINE__, fh)); + + return Close((BPTR) fh) ? 0 : -1; +} + +//----------------------------------------------------------------------------- + +int read(int fh, void *buffer, unsigned int length) +{ + LONG Result; + + d1(KPrintF("%s/%s/%ld: fh=%08lx length=%lu\n", __FILE__, __FUNC__, __LINE__, fh, length)); + + Result = Read((BPTR) fh, buffer, length); + d1(KPrintF("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + + return (int) Result; +} + +//----------------------------------------------------------------------------- + +int write(int fh, void *buffer, unsigned int length) +{ + // Writing is not supported + d1(KPrintF("%s/%s/%ld: fh=%08lx length=%lu\n", __FILE__, __FUNC__, __LINE__, fh, length)); + + return -1; +} + +//----------------------------------------------------------------------------- + +int lseek(int fd, int pos, int whence) +{ + int mode; + LONG Result; + + d1(KPrintF("%s/%s/%ld: fd=%08lx pos=%ld whence=%ld\n", __FILE__, __FUNC__, __LINE__, fd, pos, whence)); + + switch (whence) + { + case SEEK_SET: + mode = OFFSET_BEGINNING; + break; + case SEEK_CUR: + mode = OFFSET_CURRENT; + break; + case SEEK_END: + mode = OFFSET_END; + break; + default: + return -1; + break; + } + + Result = Seek((BPTR) fd, pos, mode); + d1(KPrintF("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + if (Result >= 0) + { + // if no error occurred, we return the current position + Result = Seek((BPTR) fd, 0, OFFSET_CURRENT); + d1(KPrintF("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + } + + return (int) Result; +} + +//----------------------------------------------------------------------------- + +int fclose(FILE *fh) +{ + d1(KPrintF("%s/%s/%ld: fh=%08lx\n", __FILE__, __FUNC__, __LINE__, fh)); + + errno = 0; + + return Close((BPTR) fh) ? 0 : -1; +} + +//----------------------------------------------------------------------------- + +FILE *fopen(const char *name, const char *mode) +{ + LONG accessMode; + FILE *fh; + + d1(KPrintF("%s/%s/%ld: name=<%s> mode=<%s>\n", __FILE__, __FUNC__, __LINE__, name, mode)); + + errno = 0; + + if ('r' == *mode) + accessMode = MODE_OLDFILE; + else + accessMode = MODE_NEWFILE; + + fh = (FILE *) Open((STRPTR) name, accessMode); + + d1(kprintf("%s/%s/%ld: name=<%s> mode=<%s> fh=%08lx\n", __FILE__, __FUNC__, __LINE__, name, mode, fh)); + if (NULL == fh) + { + LONG error = IoErr(); + + d1(kprintf("%s/%s/%ld: error=%ld\n", __FILE__, __FUNC__, __LINE__, error)); + + if (ERROR_OBJECT_NOT_FOUND == error) + errno = ENOENT; + else + errno = EIO; + } + + return fh; +} + +//----------------------------------------------------------------------------- + +int fflush(FILE *fh) +{ + d1(KPrintF("%s/%s/%ld: fh=%08lx\n", __FILE__, __FUNC__, __LINE__, fh)); + + return Flush((BPTR) fh) ? 0 : -1; +} + +//----------------------------------------------------------------------------- + +size_t fread(void *buf, size_t length, size_t nobj, FILE *fh) +{ + d1(KPrintF("%s/%s/%ld: fh=%08lx buf=%08lx nobj=%lu length=%lu\n", \ + __FILE__, __FUNC__, __LINE__, fh, buf, nobj, length)); + + errno = 0; + + return (size_t) FRead((BPTR) fh, buf, length, nobj); +} + +//----------------------------------------------------------------------------- + +size_t fwrite(const void *buf, size_t length, size_t nobj, FILE *fh) +{ + d1(KPrintF("%s/%s/%ld: fh=%08lx buf=%08lx nobj=%lu length=%lu\n", \ + __FILE__, __FUNC__, __LINE__, fh, buf, nobj, length)); + // Writing is not supported + + return 0; +} + +//----------------------------------------------------------------------------- + +int fputc(int c, FILE *stream) +{ + // Writing is not supported + return -1; +} + +//----------------------------------------------------------------------------- + +int fseek(FILE *fh, long offset, int origin) +{ + LONG OldPos; + LONG mode; + + d1(KPrintF("%s/%s/%ld: fh=%08lx offset=%ld origin=%ld\n", \ + __FILE__, __FUNC__, __LINE__, fh, offset, origin)); + + switch (origin) + { + case SEEK_SET: + mode = OFFSET_BEGINNING; + break; + case SEEK_CUR: + mode = OFFSET_CURRENT; + break; + case SEEK_END: + mode = OFFSET_END; + break; + default: + return -1; + break; + } + + errno = 0; + + OldPos = Seek((BPTR) fh, offset, mode); + d1(kprintf("%s/%s/%ld: OldPos=%ld\n", __FILE__, __FUNC__, __LINE__, OldPos)); + + return OldPos >= 0 ? 0 : -1; +} + +//----------------------------------------------------------------------------- + +int unlink(const char *FileName) +{ + // Deleting files is not supported + d1(KPrintF("%s/%s/%ld: FileName=<%s>\n", __FILE__, __FUNC__, __LINE__, FileName)); + + errno = 0; + + return -1; +} + +//----------------------------------------------------------------------------- + +int fprintf(FILE *fh, const char *fmt, ...) +{ +#if 1 + d1(KPrintF("%s/%s/%ld: fmt=<%s>\n", __FILE__, __FUNC__, __LINE__, fmt)); +#else + char buf[256]; + va_list ap; + + d1(KPrintF("%s/%s/%ld: fmt=<%s>\n", __FILE__, __FUNC__, __LINE__, fmt)); + + (void) fh; + (void) fmt; + + va_start(ap, fmt); + + vsnprintf(buf, sizeof(buf), fmt, ap); + d1(KPrintF("%s/%s/%ld: %s\n", __FILE__, __FUNC__, __LINE__, buf)); + + va_end(ap); +#endif + return 0; +} + +//----------------------------------------------------------------------------- + +int vfprintf(FILE *fh, const char *fmt, va_list ap) +{ +#if 1 + d1(KPrintF("%s/%s/%ld: fmt=<%s>\n", __FILE__, __FUNC__, __LINE__, fmt)); +#else + char buf[256]; + + d1(KPrintF("%s/%s/%ld: fmt=<%s>\n", __FILE__, __FUNC__, __LINE__, fmt)); + + (void) fh; + (void) fmt; + (void) ap; + + vsnprintf(buf, sizeof(buf), fmt, ap); + d1(KPrintF("%s/%s/%ld: %s\n", __FILE__, __FUNC__, __LINE__, buf)); +#endif + return 0; +} + +//----------------------------------------------------------------------------- + +int fcntl(int fd, int cmd, ...) +{ + d1(KPrintF("%s/%s/%ld: fd=%08lx cmd=%ld\n", __FILE__, __FUNC__, __LINE__, fd, cmd)); + + return -1; +} + +//----------------------------------------------------------------------------- + +#if (__GNUC__ < 4) || (__GNUC_MINOR__ < 4) +double trunc(double x) +{ + if (isinf(x)) + return x; + + if (x < 0.0) + return - floor (-x); + else + return floor (x); +} + +float truncf(float x) +{ + return (float) trunc (x); +} + +float cbrtf(float x) +{ + if( isinf(x) ) + return x; + else + { + if (x >= 0) + return powf (x, 1.0 / 3.0); + else + return -powf (-x, 1.0 / 3.0); + } +} +#endif // __VERSION__ + +//----------------------------------------------------------------------------- + +/* +DESCRIPTION + + The mkstemp() function shall replace the contents of the string pointed to + by template by a unique filename, and return a file descriptor + for the file open for reading and writing. + The function thus prevents any possible race condition between testing + whether the file exists and opening it for use. + The string in template should look like a filename with six trailing 'X' s; + mkstemp() replaces each 'X' with a character from the portable filename + character set. The characters are chosen such that the resulting name + does not duplicate the name of an existing file + at the time of a call to mkstemp(). + +RETURN VALUE + + Upon successful completion, mkstemp() shall return an open file descriptor. + Otherwise, -1 shall be returned if no suitable file could be created. +*/ + +int mkstemp(char *template) +{ + d1(KPrintF("%s/%s/%ld: template=<%s>\n", __FILE__, __FUNC__, __LINE__, template)); + return -1; +} + +//----------------------------------------------------------------------------- + +#if (__GNUC__ < 4) || (__GNUC_MINOR__ < 4) +/* + These functions shall round their argument to the nearest integer value, + rounding according to the current rounding direction. + +RETURN VALUE + Upon successful completion, these functions shall return the rounded integer value. + [MX] [Option Start] If x is NaN, a domain error shall occur, and an unspecified value is returned. + If x is +Inf, a domain error shall occur and an unspecified value is returned. + If x is -Inf, a domain error shall occur and an unspecified value is returned. + If the correct value is positive and too large to represent as a long long, a domain error shall occur and an unspecified value is returned. + If the correct value is negative and too large to represent as a long long, a domain error shall occur and an unspecified value is returned. [Option End] +*/ + +long long int llrint(double x) +{ +#warning need some work here + return (long long) x; +} +#endif // (__GNUC__ < 4) || (__GNUC_MINOR__ < 4) + +//----------------------------------------------------------------------------- + +struct stat; + +int fstat(int fd, struct stat *stat_buf) +{ + return -1; +} + +int please_use_av_log(void) +{ + return 0; +} + +int please_use_av_log_instead_of_printf(void) +{ + return 0; +} + +int usleep(int us) +{ + return 0; +} + +//----------------------------------------------------------------------------- + +/* + * PowerPC math library based in part on work by Sun Microsystems + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + */ + +typedef union +{ + double value; + struct + { + unsigned int msw; + unsigned int lsw; + } parts; +} ieee_double_shape_type; + +#define EXTRACT_WORDS(ix0,ix1,d) \ +do { \ + ieee_double_shape_type ew_u; \ + ew_u.value = (d); \ + (ix0) = ew_u.parts.msw; \ + (ix1) = ew_u.parts.lsw; \ +} while (0) + +#define INSERT_WORDS(d,ix0,ix1) \ +do { \ + ieee_double_shape_type iw_u; \ + iw_u.parts.msw = (ix0); \ + iw_u.parts.lsw = (ix1); \ + (d) = iw_u.value; \ +} while (0) + +double round(double x) +{ + /* Most significant word, least significant word. */ + LONG msw, exponent_less_1023; + ULONG lsw; + + EXTRACT_WORDS(msw, lsw, x); + + /* Extract exponent field. */ + exponent_less_1023 = ((msw & 0x7ff00000) >> 20) - 1023; + + if (exponent_less_1023 < 20) + { + if (exponent_less_1023 < 0) + { + msw &= 0x80000000; + if (exponent_less_1023 == -1) + /* Result is +1.0 or -1.0. */ + msw |= (1023 << 20); + lsw = 0; + } + else + { + ULONG exponent_mask = 0x000fffff >> exponent_less_1023; + if ((msw & exponent_mask) == 0 && lsw == 0) + /* x in an integral value. */ + return x; + + msw += 0x00080000 >> exponent_less_1023; + msw &= ~exponent_mask; + lsw = 0; + } + } + else if (exponent_less_1023 > 51) + { + if (exponent_less_1023 == 1024) + /* x is NaN or infinite. */ + return x + x; + else + return x; + } + else + { + ULONG exponent_mask = 0xffffffff >> (exponent_less_1023 - 20); + ULONG tmp; + + if ((lsw & exponent_mask) == 0) + /* x is an integral value. */ + return x; + + tmp = lsw + (1 << (51 - exponent_less_1023)); + if (tmp < lsw) + msw += 1; + lsw = tmp; + + lsw &= ~exponent_mask; + } + INSERT_WORDS(x, msw, lsw); + + return x; +} + +//----------------------------------------------------------------------------- +#if 1 +/* +The memalign() function returns a block of memory of +size bytes aligned to blocksize. The blocksize must be given +as a power of two. It sets errno and returns a null pointer upon failure. + +Pointers returned by memalign() may be passed to free(). +Pointers passed to realloc() are checked and if not +aligned to the system, the realloc() fails and returns NULL. +*/ +void *memalign(size_t blocksize, size_t bytes) +{ + d1(KPrintF("%s/%s/%ld: blocksize=%lu bytes=%lu\n", __FILE__, __FUNC__, __LINE__, blocksize, bytes)); + + bytes = (bytes + (blocksize - 1)) & ~(blocksize - 1); + + return malloc(bytes); +} +#endif +//----------------------------------------------------------------------------- + + FILE **__sF; + +char _ProgramName[] = "xx"; + +//----------------------------------------------------------------------------- + +clock_t clock(void) +{ + return 0; +} + +//----------------------------------------------------------------------------- + + diff --git a/scalos/Plugins/Preview/Video/compat_os4.c b/scalos/Plugins/Preview/Video/compat_os4.c new file mode 100644 index 000000000..83597b9da --- /dev/null +++ b/scalos/Plugins/Preview/Video/compat_os4.c @@ -0,0 +1,96 @@ +// Video.c +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#include "Video.h" + +//--------------------------------------------------------------------------------------- + +BOOL InitExtra(void) +{ + return TRUE; +} + +void ExitExtra(void) +{ +} + +BOOL InitInstance(void) +{ + return TRUE; +} + +void ExitInstance(void) +{ +} + +//--------------------------------------------------------------------------------------- + +/* +The memalign() function returns a block of memory of +size bytes aligned to blocksize. The blocksize must be given +as a power of two. It sets errno and returns a null pointer upon failure. + +Pointers returned by memalign() may be passed to free(). +Pointers passed to realloc() are checked and if not +aligned to the system, the realloc() fails and returns NULL. +*/ +void *memalign(size_t blocksize, size_t bytes) +{ + d1(KPrintF("%s/%s/%ld: blocksize=%lu bytes=%lu\n", __FILE__, __FUNC__, __LINE__, blocksize, bytes)); + (void) blocksize; + + return malloc(bytes); +} + +//----------------------------------------------------------------------------- + +void *gethostbyname(const char *s) +{ + (void)s; + + return NULL; +} + +//----------------------------------------------------------------------------- + +/* + These functions shall round their argument to the nearest integer value, + rounding according to the current rounding direction. + +RETURN VALUE + Upon successful completion, these functions shall return the rounded integer value. + [MX] [Option Start] If x is NaN, a domain error shall occur, and an unspecified value is returned. + If x is +Inf, a domain error shall occur and an unspecified value is returned. + If x is -Inf, a domain error shall occur and an unspecified value is returned. + If the correct value is positive and too large to represent as a long long, a domain error shall occur and an unspecified value is returned. + If the correct value is negative and too large to represent as a long long, a domain error shall occur and an unspecified value is returned. [Option End] +*/ + +long long int llrint(double x) +{ +#warning need some work here + return (long long) x; +} + +//----------------------------------------------------------------------------- + diff --git a/scalos/Plugins/Preview/Video/config.mk b/scalos/Plugins/Preview/Video/config.mk new file mode 100755 index 000000000..cede18cb2 --- /dev/null +++ b/scalos/Plugins/Preview/Video/config.mk @@ -0,0 +1,101 @@ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +COMMON_DIR = $(TOPLEVEL)/common/Plugin +FFMPEG_DIR = $(TOPLEVEL)/include/ffmpeg + +INCLUDES += -I$(COMMON_DIR) -I$(FFMPEG_DIR) + +vpath %.c $(COMMON_DIR) + +############################################################################## + +LFLAGS := \ + -lavcodec \ + -lavformat \ + -lavcodec \ + -lavutil \ + -lz \ + $(LFLAGS) \ + +############################################################################## + +include $(COMMON_DIR)/config.mk + +############################################################################## + +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +INCLUDES += # + +LFLAGS := -nostartfiles \ + $(LFLAGS) \ + -lmempools \ +# -Wl,-Map,video.map \ +# --verbose \ +# -nostdlib + + +COMPAT_OBJS = $(OBJDIR)/compat_mos.o + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += -nostartfiles \ + -lm +# + +COMPAT_OBJS = $(OBJDIR)/compat_os4.o + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +LFLAGS += -nostartfiles \ + -lm +# + +COMPAT_OBJS = $(OBJDIR)/compat_mos.o + + +else + +############################################################################### +# AmigaOS + +INCLUDES += # + +LFLAGS += -specs=gg:etc/specs -nostdlib\ + -lm2 \ + -lgcc \ + -lmempools \ + -lnix\ + -lc \ + -ldebug \ + -lamiga21 \ + -lamiga \ + -lstubs \ + -Wl,-Map,video.map \ +# --verbose \ + + +COMPAT_OBJS = $(OBJDIR)/compat_68k.o + +endif +endif +endif diff --git a/scalos/Plugins/Preview/Video/makefile b/scalos/Plugins/Preview/Video/makefile new file mode 100755 index 000000000..b3fed5c77 --- /dev/null +++ b/scalos/Plugins/Preview/Video/makefile @@ -0,0 +1,8 @@ +# makefile für Scalos JpegPicture.pvplugin +# // $Date$ +# // $Revision$ + +# video.pvplugin cannot be built with SAS/C due to lack of 64-bit integers. + +include makefile-new + diff --git a/scalos/Plugins/Preview/Video/makefile-new b/scalos/Plugins/Preview/Video/makefile-new new file mode 100755 index 000000000..44ee11ebc --- /dev/null +++ b/scalos/Plugins/Preview/Video/makefile-new @@ -0,0 +1,75 @@ +# $Date: 2011-07-31 23:57:02 +0200 (So, 31. Jul 2011) $ +# $Revision: 814 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(BEGIN_OBJS) \ + $(OBJDIR)/Video.o \ + $(COMPAT_OBJS) \ + $(END_OBJS) + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Targets +# + +NAME = video.pvplugin +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) \ + all_subdirs + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + @$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) Scalos:Plugins/Preview/ clone + @touch env:scalos/FileTypes/video + @avail flush + +install: install_subdirs + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* + +clean: clean_subdirs + +############################################################################## + + diff --git a/scalos/Plugins/Preview/Video/plugin_data.h b/scalos/Plugins/Preview/Video/plugin_data.h new file mode 100644 index 000000000..22036db24 --- /dev/null +++ b/scalos/Plugins/Preview/Video/plugin_data.h @@ -0,0 +1,27 @@ +// plugin_data.h +// $Date$ +// $Revision$ + +#ifndef PLUGIN_DATA_H_INCLUDED +#define PLUGIN_DATA_H_INCLUDED + +#include +#include + +#define PLUGIN_TYPE PREVIEW + +#define LIB_VERSION 41 +#define LIB_REVISION 2 + +#define LIB_NAME "video.pvplugin" +#define LIB_VERSTRING "\0$VER: video.pvplugin " \ + STR(LIB_VERSION) "." STR(LIB_REVISION) \ + " (07.11.2009)" \ + COMPILER_STRING " ©2007" CURRENTYEAR \ + " The Scalos Team" + +//---------------------------------------------------------------------------- +// code and includes to define the structs and functions used above + +#endif /* PLUGUN_DATA_H_INCLUDED */ + diff --git a/scalos/Plugins/Preview/config.mk b/scalos/Plugins/Preview/config.mk new file mode 100755 index 000000000..b41aef182 --- /dev/null +++ b/scalos/Plugins/Preview/config.mk @@ -0,0 +1,35 @@ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += # + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += # + + +else + +############################################################################### +# AmigaOS + +LFLAGS += # + +endif +endif + diff --git a/scalos/Plugins/Preview/makefile b/scalos/Plugins/Preview/makefile new file mode 100644 index 000000000..dea1b9b9d --- /dev/null +++ b/scalos/Plugins/Preview/makefile @@ -0,0 +1,45 @@ +# makefile for Scalos FileTypes plugins +# $Date$ +# $Revision$ + +############################################################# + +SUBDIRS = DefPicture \ + JpegPicture \ + PNGPicture \ + Video \ + +############################################################# + +.PHONY: All install clean + +############################################################# + +define build_subdir +$(MAKE) -s --directory=$(1); +endef + +define install_subdir +$(MAKE) -s install --directory=$(1); +endef + +define clean_subdir +$(MAKE) -s clean --directory=$(1); +endef + +############################################################# + +All: + @$(foreach subdir,$(SUBDIRS),$(call build_subdir,$(subdir))) + +############################################################# + +install: + @$(foreach subdir,$(SUBDIRS),$(call install_subdir,$(subdir))) + +############################################################# + +clean: + @$(foreach subdir,$(SUBDIRS),$(call clean_subdir,$(subdir))) + +############################################################# diff --git a/scalos/Plugins/Preview/makefile-new b/scalos/Plugins/Preview/makefile-new new file mode 100755 index 000000000..1f5e0ea67 --- /dev/null +++ b/scalos/Plugins/Preview/makefile-new @@ -0,0 +1,30 @@ +# $Date: 2010-04-16 22:49:51 +0200 (Fr, 16. Apr 2010) $ +# $Revision: 572 $ +############################################################# + +TOPLEVEL = $(shell pwd)/../.. + +include config.mk + +############################################################################## +# +# Project subdirectories +# + +SUBDIRS = DefPicture \ + JpegPicture \ + PNGPicture \ + Video + +############################################################################## + +.PHONY: all install clean + +all: all_subdirs + +clean: clean_subdirs + +install: install_subdirs + +nodebug: nodebug_subdirs + diff --git a/scalos/Plugins/config.mk b/scalos/Plugins/config.mk new file mode 100755 index 000000000..b41aef182 --- /dev/null +++ b/scalos/Plugins/config.mk @@ -0,0 +1,35 @@ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += # + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += # + + +else + +############################################################################### +# AmigaOS + +LFLAGS += # + +endif +endif + diff --git a/scalos/Plugins/makefile b/scalos/Plugins/makefile new file mode 100644 index 000000000..a36b21054 --- /dev/null +++ b/scalos/Plugins/makefile @@ -0,0 +1,46 @@ +# makefile for all Scalos plugins +# $Date$ +# $Revision$ + +############################################################# + +SUBDIRS = Prefs \ + OOP \ + Menu \ + FileTypes \ + Preview \ + +############################################################# + +.PHONY: All install clean + +############################################################# + +define build_subdir +$(MAKE) -s --directory=$(1); +endef + +define install_subdir +$(MAKE) -s install --directory=$(1); +endef + +define clean_subdir +$(MAKE) -s clean --directory=$(1); +endef + +############################################################# + +All: + @$(foreach subdir,$(SUBDIRS),$(call build_subdir,$(subdir))) + +############################################################# + +install: + @$(foreach subdir,$(SUBDIRS),$(call install_subdir,$(subdir))) + +############################################################# + +clean: + @$(foreach subdir,$(SUBDIRS),$(call clean_subdir,$(subdir))) + +############################################################# diff --git a/scalos/Plugins/makefile-new b/scalos/Plugins/makefile-new new file mode 100755 index 000000000..110090830 --- /dev/null +++ b/scalos/Plugins/makefile-new @@ -0,0 +1,30 @@ +# $Date: 2009-02-17 21:22:13 +0100 (Di, 17. Feb 2009) $ +# $Revision: 5 $ +############################################################# +TOPLEVEL = $(shell pwd)/.. + +include config.mk + +############################################################################## +# +# Project subdirectories +# + +SUBDIRS = OOP \ + Prefs \ + FileTypes \ + Preview \ +# Menu \ + +############################################################################## + +.PHONY: all install clean + +all: all_subdirs + +clean: clean_subdirs + +install: install_subdirs + +nodebug: nodebug_subdirs + diff --git a/scalos/Prefs/FileTypes/Catalogs/deutsch/Scalos/ScalosFileTypes.ct b/scalos/Prefs/FileTypes/Catalogs/deutsch/Scalos/ScalosFileTypes.ct new file mode 100755 index 000000000..93e310d53 --- /dev/null +++ b/scalos/Prefs/FileTypes/Catalogs/deutsch/Scalos/ScalosFileTypes.ct @@ -0,0 +1,1435 @@ +; ScalosFileTypes.ct +## version $VER: ScalosFileTypes.catalog 40.23 (11 Apr 2010 17:25:00) +## codeset 0 +## language deutsch +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Dateiarten Voreinsteller +;Scalos FileTypes Prefs Plugin +; +; +MSGID_SAVENAME +Speichern +;Save +; +; +MSGID_USENAME +Benutzen +;Use +; +; +MSGID_CANCELNAME +Abbrechen +;Cancel +; +;--------------------------------------------- +; +MSGID_MENU_PROJECT_OPEN +Öffnen... +;Open... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +O +;O +; +; +MSGID_MENU_PROJECT_SAVEAS +Speichern als... +;Save As... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +A +;A +; +; +MSGID_MENU_PROJECT_ABOUT +Über... +;About... +; +; +MSGID_MENU_PROJECT_QUIT +Beenden +;Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +;Q +; +; +MSGID_MENU_PROJECT +Projekt +;Project +; +; +MSGID_MENU_EDIT_LASTSAVED +auf zuletzt gespeichertes +;Last Saved +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +L +;L +; +; +MSGID_MENU_EDIT +Verändern +;Edit +; +; +MSGID_MENU_SETTINGS_CREATEICONS +Piktogramme erzeugen? +;Create Icons? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +I +;I +; +; +MSGID_MENU_SETTINGS +Einstellungen +;Settings +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +auf Vorgaben zurücksetzen +;Reset To Defaults +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +D +;D +; +; +MSGID_MENU_EDIT_RESTORE +auf vorigen Stand +;Restore +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +R +;R +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Über MUI... +;About MUI... +; +; +MSGID_MENU_EDIT_COLLAPSE +Auswahl zuklappen +;Collapse selected +; +; +MSGID_MENU_EDIT_EXPAND +Auswahl aufklappen +;Expand selected +; +; +MSGID_MENU_EDIT_COLLAPSEALL +Alles zuklappen +;Collapse all +; +; +MSGID_MENU_EDIT_EXPANDALL +Alles aufklappen +;Expand all +; +; +MSGID_MENU_EDIT_COPY +Kopieren +;Copy +; +; +MSGID_MENU_EDIT_CUT +Ausschneiden +;Cut +; +; +MSGID_MENU_EDIT_PASTE +Einfügen +;Paste +; +; +MSGID_MENU_HIDE_EMPTY_ENTRIES +Leere Einträge weglassen? +;Hide empty entries? +; +; +MSGID_MENU_EDIT_FIND +Suchen... +;Find... +; +;--------------------------------------------- +; +MSGID_ABOUTREQOK +_OK +;_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Dateiarten Voreinsteller V%ld.%ld\033n\n\ +%s\n\ +© 1999%s Das Scalos Team +;\33c\033bScalos FileTypes Preferences V%ld.%ld\033n\n\ +;%s\n\ +;© 1999-2003 The Scalos Team +; +; +MSGID_SHORTHELP_SAVEBUTTON +Drücken Sie diesen Knopf, um alle\n\ +Einstellungen dauerhaft in\n\ +\"ENVARC:Scalos/menu13.prefs\"\n\ +zu speichern. +;Press this button to save \n\ +;the current settings\n\ +;and make changes permanent. +; +; +MSGID_SHORTHELP_USEBUTTON +Drücken Sie diesen Knopf, um alle Einstellungen\n\ +bis zum nächsten Neustart in\n\ +\"ENV:Scalos/menu13.prefs\"\n\ +zu speichern. +;Press this button to save \n\ +;the current settings\n\ +;and keep settings until reboot. +; +; +MSGID_SHORTHELP_CANCELBUTTON +Drücken Sie diesen Knopf, um das\n\ +Programm abzubrechen und alle\n\ +Änderungen zu verwerfen. +;Press this button to abort \n\ +;and forget all changes. +; +; +MSGID_REQTITLE_SAVEERROR +Fehler beim Schreiben der Einstellungs-\n\ +Datei \"%s\"\n\ +%s +;Error writing filetypes preferences\n\ +;file \"%s\"\n\ +;%s +; +; +MSGID_REQTITLE_READERROR +Fehler beim Lesen der Einstellungs-\n\ +Datei \"%s\"\n\ +%s +;Error reading filetypes preferences\n\ +;file \"%s\"\n\ +;%s +; +; +MSGID_PLUGIN_LIST_TITLE +Dateiarten +;FileTypes +; +; +MSGID_SPLASHWINDOW_LOADING_FILETYPES_PREFS +\33c Dateiarten laden... +; \33c Loading FileTypes Prefs... +; +; +MSGID_SPLASHWINDOW_APPLYING_FILETYPES_PREFS +\33c Dateiarten anwenden... +; \33c Applying FileTypes Prefs... +; +; +MSGID_SPLASHWINDOW_SAVING_FILETYPES_PREFS +\33c Dateiarten speichern... +; \33c Saving FileTypes Prefs... +; +;--------------------------------------------- +; +MSGID_ATTRCOLUMNTITLE_NAME +Name +;Name +; +; +MSGID_ATTRCOLUMNTITLE_VALUE +Wert +;Value +; +;--------------------------------------------- +; +MSGID_BUTTON_ADD_ENTRY +Hinzufügen +;Add +; +MSGID_BUTTON_ADD_ENTRY_KEY +A +;A +; +; +MSGID_SHORTHELP_BUTTON_ADD_ENTRY +FÜgt eine neue Dateiarten-spezifische Aktion hinzu.\n\ +Das kann ein Eintrag für das Popup-Menü oder\n\ +für einen Tooltip sein. +;...Add... +; +; +MSGID_BUTTON_DELETE_ENTRY +Löschen +;Delete +; +; +MSGID_BUTTON_DELETE_ENTRY_KEY +D +;D +; +; +MSGID_SHORTHELP_BUTTON_DELETE_ENTRY +Löscht die ausgewählte Dateiarten-spezifische Aktion.\n\ +\033bVorsicht: Entfernen eines Listenknotens\n\ +löscht alle untergeordneten Einträge!\033n +;...Delete Entry... +; +; +MSGID_BUTTON_ADD_ATTRIBUTE +Hinzufügen +;Add +; +; +MSGID_BUTTON_ADD_ATTRIBUTE_KEY + +; +; +; +MSGID_SHORTHELP_BUTTON_ADD_ATTRIBUTE +Hinzufügen eines neuen Attributs für die\n\ +aktuelle Dateiarten-spezifische Aktion.\n\ +Typische Attribute sind Name, Schriftart\n\ +oder Ausrichtung eines Eintrags. +;...Add Attribute... +; +; +MSGID_BUTTON_EDIT_ATTRIBUTE +Ändern +;Edit +; +; +MSGID_SHORTHELP_BUTTON_EDIT_ATTRIBUTE +Ändern des Wertes eines Attributs für die\n\ +aktuelle Dateiarten-spezifische Aktion.\n\ +;...Edit Attribute... +; +; +MSGID_BUTTON_DELETE_ATTRIBUTE +Entfernen +;Remove +; +; +MSGID_BUTTON_DELETE_ATTRIBUTE_KEY +R +;R +; +; +MSGID_SHORTHELP_BUTTON_DELETE_ATTRIBUTE +Entfernen des aktuellen Attributs für die\n\ +aktuelle Dateiarten-spezifische Aktion.\n\ +;...Delete Attribute... +; +; new in 40.2 +; +MSGID_SHORTHELP_LAMP_CHANGED +Diese Anzeigelampe wechselt den Zustand von \033bAus\033n\n\ +nach \033bAn\033n wenn die Konfiguration seit\n\ +dem ersten Laden verändert wurde. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +; +MSGID_BUTTON_CREATE_ICON +Neues erzeugen +;Create New +; +; +MSGID_SHORTHELP_BUTTON_CREATE_ICON +Erzeugt ein neues eigenes Piktogramm für diesen Dateityp. +;Create a new dedicated icon for this filetype. +; +; +MSGID_BUTTON_FIND_NEXT_SHORTHELP +Nächsten Dateityp suchen, der zum angegebenen Suchtext paßt. +;Find next filetype that matches the given search string. +; +; +MSGID_BUTTON_FIND_HIDE_SHORTHELP +Schaltflächen zur Suche nach Dateityp ausblenden. +;Hide Find Filetype Dialog. +; +; +MSGID_STRING_FIND_SHORTHELP +In den Namen der Dateitypen wirf nach diesem Text gesucht.\n\ +Während der Eingabe wird immer der erste passende Eintrag gezeigt. +;This is the string to find in filetypes' name.\n\ +;While you type, the first matching entry is always shown. +; +; +MSGID_BUTTON_FIND_PREV_SHORTHELP +Vorigen Dateityp suchen, der zum angegebenen Suchtext paßt. +;Find previous filetype that matches the given search string. +; +;--------------------------------------------- +; +MSGID_ENTRYTYPE_FILETYPE +Dateiart +;Filetype +; +; +MSGID_ENTRYTYPE_POPUPMENU +Popup Menu +;Popup Menu +; +; +MSGID_ENTRYTYPE_SUBMENU +UnterMenu +;SubMenu +; +; +MSGID_ENTRYTYPE_MENUITEM +Menupunkt +;Menu Item +; +; +MSGID_ENTRYTYPE_INTERNALCMD +Interner Befehl +;Internal Command +; +; +MSGID_ENTRYTYPE_WBCMD +Workbench Befehl +;Workbench Command +; +; +MSGID_ENTRYTYPE_AREXXCMD +ARexx Befehl +;ARexx Command +; +; +MSGID_ENTRYTYPE_CLICMD +CLI Befehl +;CLI Command +; +; +MSGID_ENTRYTYPE_PLUGINCMD +Menu Plugin Befehl +;Menu Plugin Command +; +; +MSGID_ENTRYTYPE_ICONWINDOWCMD +Piktogrammfenster +;Icon Window Command +; +; +MSGID_ENTRYTYPE_MENUSEPARATOR +\033C +;\033C +; +; +MSGID_ENTRYTYPE_TOOLTIP +Tooltip +;Tooltip +; +; +MSGID_ENTRYTYPE_GROUP +Gruppe +;Group +; +; +MSGID_ENTRYTYPE_MEMBER +Mitglied +;Member +; +; +MSGID_ENTRYTYPE_HBAR +Horizontaler Strich +;Horizontal Bar +; +; +MSGID_ENTRYTYPE_STRING +Text +;String +; +; +MSGID_ENTRYTYPE_SPACE +Leerraum +;Space +; +; +MSGID_ENTRYTYPE_DTIMAGE +Datatypes Bild +;Datatypes Image +; +;--------------------------------------------- +; +MSGID_CHANGEME +Neuer Text +;Change me +; +;--------------------------------------------- +; +MSGID_BUTTON_CHANGE_ATTRIBUTE +Ändern +;Change +; +MSGID_SHORTHELP_BUTTON_CHANGE_ATTRIBUTE +Übernimmt die Änderungen des Attribut-Wertes. +;Commit changes to attribute and use changed values. +; +MSGID_BUTTON_KEEP_ATTRIBUTE +Abbrechen +;Cancel +; +MSGID_SHORTHELP_BUTTON_KEEP_ATTRIBUTE +Verwirft die Änderungen und behält den\n\ +originalen Wert des Attributes bei. +;Abort attribute changes and retain original values. +; +MSGID_EDITATTRIBUTE_WINDOWTITLE +Attributwert ändern +;Edit Attribute Value +; +MSGID_EDITATTRIBUTE_TITLE +Neuen Wert für Attribut auswählen +;Select new Value for Attribute +; +; +MSGID_EDITATTRIBUTE_TTFONT_ASLTITLE +TrueType Schrift wählen... +;Select TrueType Font... +; +; +MSGID_EDITATTRIBUTE_TTFONT_ASL_OKBUTTON +Ok +;Ok +; +; +MSGID_EDITATTRIBUTE_TTFONT_ASL_CANCELBUTTON +Abbruch +;Cancel +; +; +MSGID_TTFONTSPAGE_SAMPLETEXT +Franz jagt im komplett verwahrlosten Taxi quer durch Bayern +;The quick brown fox jumps over the lazy dog +; +; +MSGID_TTFONTSPAGE_SCREENFONT_SAMPLETEXT_SHORTHELP +Dies ist ein Beispiel für die\n\ +ausgewählte TrueType Bildschirmschrift. +;This is an example text to visualize what the\n\ +;selected TrueType screen font looks like. +; +;--------------------------------------------- +; +MSGID_STARTUP_FAILURE +Scalos Dateiarten Voreinsteller kann nicht gestartet werden +;Scalos Filetypes Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Wiederholen|Beenden +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\ +Die Klasse ist nicht installiert. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Sie haben momentan Version v%lu.%lu installiert und\n\ +sollten die Klasse daher aktualisieren! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Version %lu.%lu wird momentan von einer anderen Anwendung\n\ +verwendet. Wenn sie die benötigte Version installiert haben,\n\ +schließen sie alle MUI Programme und probieren es erneut. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_REGISTERTITLE_RECOGNITION +Erkennung +;Recognition +; +; +MSGID_REGISTERTITLE_ACTIONS +Aktionen +;Actions +; +;----------------------------------------------------------- +; +MSGID_BUTTON_ADD_FILETYPE +Hinzufügen +;Add +; +; +MSGID_SHORTHELP_BUTTON_ADD_FILETYPE +Fügt einen neuen Eintrag für eine Dateiart hinzu. +;Add a new entry with a filetypes description. +; +;----------------------------------------------------------- +; +MSGID_BUTTON_DELETE_FILETYPE +Entfernen +;Remove +; +; +MSGID_SHORTHELP_BUTTON_DELETE_FILETYPE +Entfernt den aktuellen Eintrag für eine Dateiart,\n\ +\033bVorsicht: Entfernen eines Listen-Knotens\n\ +löscht sämtliche untergeordneten Einträge!\033n +;Remove currently selected filetypes description.\n\ +;\033bNote that removing a tree node deletes\n\ +;all subordinate entries!\033n +; +; +MSGID_BUTTON_REMOVE_FILETYPEACTION +Entfernen +;Remove +; +; +MSGID_SHORTHELP_BUTTON_REMOVE_FILETYPEACTION +Entfernt die aktuelle Aktion zur Identifizierung einer Dateiart. +;Remove currently selected filetype identification action. +; +; +MSGID_BUTTON_ADD_FILETYPEACTION +Hinzufügen... +;Add... +; +; +MSGID_SHORTHELP_BUTTON_ADD_FILETYPEACTION +Fügt eine neue Aktion zur Identifizierung einer Dateiart hinzu. +;Add new filetype identification action. +; +; +MSGID_BUTTON_LEARN_FILETYPEACTION +Lernen... +;Learn... +; +; +MSGID_SHORTHELP_BUTTON_LEARN_FILETYPEACTION +Lernt die Identifizierung einer Dateiart durch\n\ +Angabe von zwei oder mehr Beispiel-Dateien. +;Learn about filetype by giving two or more example files. +; +; +MSGID_NEW_FILETYPE +«neu» +;«new» +; +;----------------------------------------------------------- +; +MSGID_FILETYPE_ADD_ACTION_MATCH +VERGLEICH +;MATCH +; +; +MSGID_FILETYPE_ADD_ACTION_SEARCH +SUCHEN +;SEARCH +; +; +MSGID_FILETYPE_ADD_ACTION_FILESIZE +DATEIGRÖSSE +;FILESIZE +; +; +MSGID_FILETYPE_ADD_ACTION_PATTERN +NAMENSMUSTER +;PATTERN +; +; +MSGID_FILETYPE_ADD_ACTION_PROTECTION +ZUGRIFF +;PROTECTION +; +; +MSGID_FILETYPE_ADD_ACTION_OR +ODER +;OR +; +; +MSGID_FILETYPE_ADD_ACTION_ISASCII +ISASCII +; +; +MSGID_FILETYPE_ADD_ACTION_MACROCLASS +MAKROKLASSE +;MACROCLASS +; +; +MSGID_FILETYPE_ADD_ACTION_DOSDEVICE +DOSDEVICE +; +; +MSGID_FILETYPE_ADD_ACTION_DEVICENAME +DEVICENAME +; +; +MSGID_FILETYPE_ADD_ACTION_CONTENTS +INHALT +; +; +MSGID_FILETYPE_ADD_ACTION_MINSIZEMB +MIN_GRÖßE_MB +; +; +MSGID_FILETYPE_ADD_ACTION_DOSTYPE +DOSTYP +;DOSTYPE +; +;----------------------------------------------------------- +; +MSGID_FILETYPEACTION_MATCH_OFFSET +Abstand: +;Offset: +; +; +MSGID_FILETYPEACTION_MATCH_CASE_SENSITIVE +GROSS/klein unterscheiden: +;Case sensitive: +; +; +MSGID_FILETYPEACTION_MATCH_MATCH +Vergleichen: +;Match: +; +; +MSGID_FILETYPEACTION_SEARCH_SKIP_SPACES +Leerzeichen ignorieren: +;Skip spaces: +; +; +MSGID_FILETYPEACTION_SEARCH_CASE_SENSITIVE +GROSS/klein unterscheiden: +;Case sensitive: +; +; +MSGID_FILETYPEACTION_SEARCH_SEARCH +Suchen: +;Search: +; +; +MSGID_FILETYPEACTION_FILESIZE_FILESIZE +Dateigröße: +;File size: +; +; +MSGID_FILETYPEACTION_PATTERN_PATTERN +Namensmuster: +;Pattern: +; +; +MSGID_FILETYPEACTION_PROTECTION_R +R +;R +; +; +MSGID_FILETYPEACTION_PROTECTION_W +W +;W +; +; +MSGID_FILETYPEACTION_PROTECTION_E +E +;E +; +; +MSGID_FILETYPEACTION_PROTECTION_D +D +;D +; +; +MSGID_FILETYPEACTION_PROTECTION_S +S +;S +; +; +MSGID_FILETYPEACTION_PROTECTION_P +P +;P +; +; +MSGID_FILETYPEACTION_PROTECTION_A +A +;A +; +; +MSGID_FILETYPEACTION_PROTECTION_H +H +;H +; +; +MSGID_GROUP_FILETYPES_FILETYPES +Dateiarten +;Filetypes +; +; +MSGID_GROUP_FILETYPES_METHODS +Methoden +;Methods +; +; +MSGID_FILETYPEACTION_MINSIZEMB_SIZE +Minimale Kapazität in Megabytes: +; +; +MSGID_FILETYPEACTION_DOSDEVICE_PATTERN +Muster für DOS-Gerätename: +;DOS device name pattern: +; +; +MSGID_FILETYPEACTION_DEVICENAME_PATTERN +Muster für Gerätename: +;Device name pattern: +; +; +MSGID_FILETYPEACTION_CONTENTS_PATTERN +Muster für Datenträgerinhalt: +;Volume contents pattern: +; +; +MSGID_FILETYPEACTION_DOSTYPE_PATTERN +Schablone für DOS-Typ: +;DOS type match string: +; +;----------------------------------------------------------- +; +MSGID_FILETYPE_PROTECTION_SET +Gesetzt +;Set +; +; +MSGID_FILETYPE_PROTECTION_UNSET +Gelöscht +;Unset +; +; +MSGID_FILETYPE_PROTECTION_IGNORE +Ignorieren +;Ignore +; +;----------------------------------------------------------- +; +MSGID_GROUP_FILETYPESACTION_MATCH +Werte für VERGLEICH +;MATCH attributes +; +; +MSGID_GROUP_FILETYPESACTION_SEARCH +Werte für SUCHEN +;SEARCH attributes +; +; +MSGID_GROUP_FILETYPESACTION_FILESIZE +Werte für DATEIGRÖSSE +;FILESIZE attributes +; +; +MSGID_GROUP_FILETYPESACTION_PATTERN +Werte für NAMENSMUSTER +;PATTERN attributes +; +; +MSGID_GROUP_FILETYPESACTION_PROTECTION +Werte für ZUGRIFF +;PROTECTION attributes +; +; +MSGID_GROUP_FILETYPESACTION_MINSIZEMB +Werte für MIN_GRÖßE_MB +;MINSIZEMB attributes +; +; +MSGID_GROUP_FILETYPESACTION_DOSDEVICE +Werte für DOSDEVICE +;DOSDEVICE attributes +; +; +MSGID_GROUP_FILETYPESACTION_DEVICENAME +Werte für DEVICENAME +;DEVICENAME attributes +; +; +MSGID_GROUP_FILETYPESACTION_CONTENTS +Werte für INHALT +;CONTENTS attributes +; +; +MSGID_GROUP_FILETYPESACTION_DOSTYPE +Werte für DOSTYPE +;DOSTYPE attributes +; +;----------------------------------------------------------- +; +MSGID_FILETYPESACTION_CASE_SENSITIVE + GROSS/klein unterscheiden +; case sensitive +; +; +MSGID_FILETYPESACTION_SKIP_SPACES + Leerzeichen ignorieren +; Skip spaces +; +; +MSGID_FILETYPESACTION_FILESIZE +%u Bytes +;%u bytes +; +; +MSGID_FILETYPESACTION_PROTECTION_IGNORE +- +;- +; +; +MSGID_FILETYPESACTION_PROTECTION_R_SET +R +;R +; +; +MSGID_FILETYPESACTION_PROTECTION_R_CLEARED +r +;r +; +; +MSGID_FILETYPESACTION_PROTECTION_W_SET +W +;W +; +; +MSGID_FILETYPESACTION_PROTECTION_W_CLEARED +w +;w +; +; +MSGID_FILETYPESACTION_PROTECTION_E_SET +E +;E +; +; +MSGID_FILETYPESACTION_PROTECTION_E_CLEARED +e +;e +; +; +MSGID_FILETYPESACTION_PROTECTION_D_SET +D +;D +; +; +MSGID_FILETYPESACTION_PROTECTION_D_CLEARED +d +;d +; +; +MSGID_FILETYPESACTION_PROTECTION_H_SET +H +;H +; +; +MSGID_FILETYPESACTION_PROTECTION_H_CLEARED +h +;h +; +; +MSGID_FILETYPESACTION_PROTECTION_A_SET +A +;A +; +; +MSGID_FILETYPESACTION_PROTECTION_A_CLEARED +a +;a +; +; +MSGID_FILETYPESACTION_PROTECTION_S_SET +S +;S +; +; +MSGID_FILETYPESACTION_PROTECTION_S_CLEARED +s +;s +; +; +MSGID_FILETYPESACTION_PROTECTION_P_SET +P +;P +; +; +MSGID_FILETYPESACTION_PROTECTION_P_CLEARED +p +;p +; +; +MSGID_FILETYPESACTION_MINSIZEMB +%u Megabytes +; +;----------------------------------------------------------- +; +MSGID_SHORTHELP_DEFAULTICON +Hier wird das Standardpiktogramm für die ausgewählte Dateiart angezeigt.\n\ +Ist kein genau passendes Standardpiktogramm vorhanden, wird nach dem\n\ +Vater dieser Dateiart gesucht und so weiter, bis als letzter Ausweg\n\ +das Standardpiktogramm für Projekte verwendet wird. +;This shows the default icon found for the selected\n\ +;filetype, and the associated name.\n\ +;If no default icon is found for the specific filetype,\n\ +;its parent is tried and so on, until as last\n\ +;resort the default project icon is used. +; +; +MSGID_SHORTHELP_LISTVIEW_FILETYPES +Dies ist die hierarchiche Ansicht aller definierten Dateiarten. +;This list shows a hierarchic view of all defined filetypes. +; +; +MSGID_SHORTHELP_STRING_FILETYPES +Dies ist der Name der aktuellen Dateiart.\n\ +Der Name wird verwendet, um ein passendes Standardpiktogramm zu\n\ +finden, z.B. für die Dateiart \"picture\" wird nach dem\n\ +Piktogramm \"def_picture.info"\" gesucht. +;This is the name of the currently selected filetype.\n\ +;The name is used to find an associated default icon,\n\ +;i.e, for the name \"picture\", a default icon\n\ +;named \"def_picture.info\" is being looked for. +; +; +MSGID_SHORTHELP_LISTVIEW_FILETYPE_ACTION +Dies ist die Liste aller Aktionen zur Identifizierung der aktuellen Dateiart.\n\ +Die Aktionen werden der Reihe nach abgearbeitet, und wenn alle\n\ +Bedingungen erfüllt sind, wird die geprüfte Datei als\n\ +dieser Art zugehörig erkannt. +;This list shows the actions to identify the currently selected filetype.\n\ +;The actions are processed sequentially from top to bottom,\n\ +;and if all actions match, the file in question is\n\ +;considered to be of this type. +; +; +MSGID_SHORTHELP_VIRTGROUP_FILETYPE_ACTION_ATTRIBUTES +Dieser Bereich enthält die Werte für die aktuelle\n\ +Aktionen zur Identifizierung der Dateiart.\n\ +Die angezeigten Werte variieren je nach Art der aktuellen Aktion. +;This area contains the attributes for the currently\n\ +;selected filetypes identification action.\n\ +;The available attributes vary depending on the\n\ +;type of the selected identification action. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_MATCH_OFFSET +Dies ist der Abstand vom Dateiabstand, ab dem verglichen wird. +;This is the file offset where matching shall start. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_MATCH +Mit dem Inhalt dieses Textes wird verglichen.\n\ +Nicht darstellbare Zeichen können als hexadezimaler Code eingeben werden, z.B. \\\\x00. +;This is the string that filetype is being compared to.\n\ +;Non-printable characters can be entered via their hexadecimal codes, e.g. \\x00. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_SEARCH +Nach diesem Text wird in der zu prüfenden Datei gesucht.\n\ +Nicht darstellbare Zeichen können als hexadezimaler Code eingeben werden, z.B. \\\\x00. +;This is the string the filetype is being searched for.\n\ +;Non-printable characters can be entered via their hexadecimal codes, e.g. \\x00. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_FILESIZE +Auf diese Dateigröße wird verglichen. +;This is the file size the filetype is checked for. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_PATTERN +Mit diesem Muster wird der Dateinamen verglichen.\n\ +Es können alle üblichen DOS-Musterzeichen wir z.B. ? order # verwendet werden. +;This is the file name pattern the filetype is being matched against.\n\ +;You may use all standard DOS patterns like ? or #. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_R +Hier wird festgelegt, ob die geprüfte Datei lesbar sein muß,\n\ +nicht lesbar sein darf, oder ob die Lesbarkeit keine Rolle spielt. +;Select here whether the filetype needs to be readable,\n\ +;or must not be readable, or if readability doesn't matter. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_W +Hier wird festgelegt, ob die geprüfte Datei beschreibbar sein muß,\n\ +nicht beschreibbar sein darf, oder ob die Beschreibbarkeit keine Rolle spielt. +;Select here whether the filetype needs to be writeable,\n\ +;or must not be writeable, or if writeability doesn't matter. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_E +Hier wird festgelegt, ob die geprüfte Datei ausführbar sein muß,\n\ +nicht ausführbar sein darf, oder ob die Ausführbarkeit keine Rolle spielt. +;Select here whether the filetype needs to be executable,\n\ +;or must not be executable, or if executability doesn't matter. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_D +Hier wird festgelegt, ob die geprüfte Datei löschbar sein muß,\n\ +nicht löschbar sein darf, oder ob die Löschbarkeit keine Rolle spielt. +;Select here whether the filetype needs to be deleteable,\n\ +;or must not be deleteable, or if deleteability doesn't matter. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_S +Hier wird festgelegt, ob die geprüfte Datei als Skript\n\ +ausführbar sein muß, nicht als Skript ausführbar sein\n\ +darf, oder ob die Ausführbarkeit als Skript keine Rolle spielt. +;Select here whether the filetype needs to be a script,\n\ +;or must be no script, or if the script attribute doesn't matter. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_P +Hier wird festgelegt, ob die geprüfte Datei resident\n\ +ausführbar sein muß, nicht resident ausführbar sein darf,\n\ +oder ob die residente Ausführbarkeit keine Rolle spielt. +;Select here whether the filetype needs to be pure,\n\ +;or must not be pure, or if the pure attribute doesn't matter. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_A +Hier wird festgelegt, ob die geprüfte Datei archiviert sein muß,\n\ +nicht archiviert sein darf, oder ob der Archiv-Zustand keine Rolle spielt. +;Select here whether the filetype needs to be archived,\n\ +;or must not be archived, or if archived state doesn't matter. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_H +Hier wird festgelegt, ob die geprüfte Datei unsichtbar sein muß,\n\ +nicht unsichtbar sein darf, oder ob die Sichtbarkeit keine Rolle spielt. +;Select here whether the filetype needs to be hidden,\n\ +;or must be visible, or if visibility doesn't matter. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_MINSIZEMB +Dies ist die minimale Kapazität des Datenträgers in Megabytes. +;This is the mimimum volume capacity to checked for. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_DOSDEVICE +Dies ist der DOS-Gerätename (wie z.B. \"DH0\") eines Datenträgers. +;This is the DOS device name (e.g. \"DH0\") for a volume. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_DEVICENAME +Das ist der Gerätename, (wie z.B. \"scsi.device\") der\n\ +für den Zugriff auf den Datenträger benutzt wird. +;This is the device name (e.g. \"scsi.device\") for a volume. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_CONTENTS +Dies ist ein Muster für den Inhalt (Datei(en) oder\n\ +Verzeichnis(se)) des Datenträgers. +;This is a matching pattern for the contents of a volume. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_DOSTYPE +Das ist der Vergleichstext für den DOS-Typ (z.B. \"SFS\\0\") eines Datenträgers.\n\ +Nichtdarstellbare Zeichen können als Hex \"\\\\x1f\" eingegeben werden. +;This is the match string for the DOS type (e.g. \"SFS\\0\") of a volume.\n\ +;Use hex notation like \"\\x1f\" for non-printable characters. +; +;----------------------------------------------------------- +; +MSGID_LEARN_OPEN +Zwei oder mehr Bespiel-Dateien zum Lernen auswählen +;Select two or more files to learn from +; +; +MSGID_SELECT_TWO_REQ_OK +_Ok +;_Ok +; +; +MSGID_SELECT_TWO_REQ_CONTENTS +Sie müssen mindestens zwei Beispiel-Dateien auswählen! +;You must select at least two sample files! +; +;----------------------------------------------------------- +; +MSGID_COM1NAME +Als Hintergrund +; +; +MSGID_COM2NAME +Programm ausführen +; +; +MSGID_COM3NAME +Alles neuzeichnen +; +; +MSGID_COM4NAME +Alles neu laden +; +; +MSGID_COM5NAME +Über Scalos +; +; +MSGID_COM6NAME +Beenden +; +; +MSGID_COM7NAME +Neue Schublade +; +; +MSGID_COM8NAME +Mutterverzeichnis öffnen +; +; +MSGID_COM9NAME +Fenster schließen +; +; +MSGID_COM10NAME +Neuladen +; +; +MSGID_COM11NAME +Inhalt anwählen +; +; +MSGID_COM12NAME +Inhalt aufräumen +; +; +MSGID_COM13NAME +Fenster fixieren +; +; +MSGID_COM14NAME +Alles fixieren +; +; +MSGID_COM15NAME +Nur Piktogramme anzeigen +; +; +MSGID_COM16NAME +Alle Dateien anzeigen +; +; +MSGID_COM17NAME +Als Piktogramm anzeigen +; +; +MSGID_COM18NAME +Mit Namen anzeigen +; +; +MSGID_COM19NAME +Öffnen +; +; +MSGID_COM20NAME +Scalos neustarten +; +; +MSGID_COM21NAME +Umbenennen +; +; +MSGID_COM22NAME +Information +; +; +MSGID_COM23NAME +Fixieren +; +; +MSGID_COM24NAME +Fixierung aufheben +; +; +MSGID_COM25NAME +Auslagern +; +; +MSGID_COM26NAME +Zurücklegen +; +; +MSGID_COM27NAME +Löschen +; +; +MSGID_COM28NAME +Duplizieren +; +; +MSGID_COM29NAME +Papierkorb leeren +; +; +MSGID_COM30NAME +Letzte Meldung +; +; +MSGID_COM31NAME +Neuzeichnen +; +; +MSGID_COM32NAME +Iconifizieren +; +; +MSGID_COM33NAME +Disk formatieren... +; +; +MSGID_COM34NAME +Herunterfahren... +; +; +MSGID_COM35NAME +Größe anpassen +; +; +MSGID_COM36NAME +Auswahl löschen +;Clear Selection +; +; +MSGID_COM37NAME +Inhalt auflisten nach Größe +; +; +MSGID_COM38NAME +Inhalt auflisten nach Datum +; +; +MSGID_COM39NAME +Datei kopieren +; +; +MSGID_COM40NAME +Datei ausschneiden +; +; +MSGID_COM41NAME +Datei einfügen +; +; +MSGID_COM42NAME +Inhalt auflisten nach Art +; +; +MSGID_COM43NAME +Inhalt aufräumen nach Namen +; +; +MSGID_COM44NAME +Inhalt aufräumen nach Datum +; +; +MSGID_COM45NAME +Inhalt aufräumen nach Größe +; +; +MSGID_COM46NAME +Inhalt aufräumen nach Art +; +; +MSGID_COM_ICONPROPERTIES +Piktogramm-Eigenschaften +;Icon properties +; +; +MSGID_COM_WINDOWPROPERTIES +Fenster-Eigenschaften +;Window properties +; +; +MSGID_COM47NAME +Inhalt auflisten nach Standard +;View By - Default +; +; +MSGID_COM48NAME +Anzeigen nach Standard +;Show - Default +; +; +MSGID_COM49NAME +Kopieren nach... +;Copy to... +; +; +MSGID_COM50NAME +Verschieben nach... +;Move to... +; +; +MSGID_COM51NAME +Vorschaubild erzeugen +;Create thumbnail +; +; +MSGID_COM_OPENNEWWINDOW +In neuem Fenster öffnen +;Open in new window +; +; +MSGID_COM_THUMBNAILCACHECLEANUP +Vorschaubilder-Zwischenspeicher aufräumen +;Cleanup thumbnail cache +; +; +MSGID_COM_FIND +Datei(en) suchen +;Find File(s) +; +; +MSGID_COM_UNDO +Rückgängig +;Undo +; +; +MSGID_COM_REDO +Wiederholen +;Redo +; +; +MSGID_FIND_HITCOUNT_FMT +%ld Treffer +;%ld Hits +; +; +MSGID_COM_OPENBROWSERWINDOW +In Browserfenster öffnen +;Open in Browser Window +; +;----------------------------------------------------------- +; diff --git a/scalos/Prefs/FileTypes/Catalogs/deutsch/Scalos/config.mk b/scalos/Prefs/FileTypes/Catalogs/deutsch/Scalos/config.mk new file mode 100755 index 000000000..8631b0623 --- /dev/null +++ b/scalos/Prefs/FileTypes/Catalogs/deutsch/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = deutsch + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = german + +else + +############################################################################### +# AmigaOS and AROS + +LANG = deutsch + +endif +endif diff --git a/scalos/Prefs/FileTypes/Catalogs/deutsch/Scalos/makefile b/scalos/Prefs/FileTypes/Catalogs/deutsch/Scalos/makefile new file mode 100644 index 000000000..926e323d4 --- /dev/null +++ b/scalos/Prefs/FileTypes/Catalogs/deutsch/Scalos/makefile @@ -0,0 +1,13 @@ +# makefile for Scalos (translated Texts : deutsch) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mdeutsch\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +ScalosFileTypes.catalog : ScalosFileTypes.ct ../../../ScalosFileTypes.cd + +All: ScalosFileTypes.catalog diff --git a/scalos/Prefs/FileTypes/Catalogs/deutsch/Scalos/makefile-new b/scalos/Prefs/FileTypes/Catalogs/deutsch/Scalos/makefile-new new file mode 100644 index 000000000..e93e99c29 --- /dev/null +++ b/scalos/Prefs/FileTypes/Catalogs/deutsch/Scalos/makefile-new @@ -0,0 +1,30 @@ +# makefile for FileTypes (translated Texts : deutsch) +# $Date: 2011-08-06 19:37:48 +0200 (Sa, 06. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = ScalosFileTypes + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git "a/scalos/Prefs/FileTypes/Catalogs/fran\303\247ais/Scalos/ScalosFileTypes.ct" "b/scalos/Prefs/FileTypes/Catalogs/fran\303\247ais/Scalos/ScalosFileTypes.ct" new file mode 100755 index 000000000..e8c5e648e --- /dev/null +++ "b/scalos/Prefs/FileTypes/Catalogs/fran\303\247ais/Scalos/ScalosFileTypes.ct" @@ -0,0 +1,1421 @@ +; ScalosFileTypes.ct +; $Date$ +; $Revision$ +## version $VER: ScalosFileTypes.catalog 40.23 (11 Apr 2010 17:24:19) +## codeset 0 +## language français +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Préferences : Types de fichiers +;Scalos FileTypes Prefs Plugin +; +; +MSGID_SAVENAME +Sauver +;Save +; +; +MSGID_USENAME +Utiliser +;Use +; +; +MSGID_CANCELNAME +Annuler +;Cancel +; +;--------------------------------------------- +; +MSGID_MENU_PROJECT_OPEN +Ouvrir... +;Open... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +O +;O +; +; +MSGID_MENU_PROJECT_SAVEAS +Sauver sous... +;Save As... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +A +;A +; +; +MSGID_MENU_PROJECT_ABOUT +A propos... +;About... +; +; +MSGID_MENU_PROJECT_QUIT +Quitter +;Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +;Q +; +; +MSGID_MENU_PROJECT +Projet +;Project +; +; +MSGID_MENU_EDIT_LASTSAVED +Dernière sauvegarde +;Last Saved +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +L +;L +; +; +MSGID_MENU_EDIT +Edition +;Edit +; +; +MSGID_MENU_SETTINGS_CREATEICONS +Créer les icônes ? +;Create Icons? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +I +;I +; +; +MSGID_MENU_SETTINGS +Options +;Settings +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +Réglages par défaut +;Reset To Defaults +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +D +;D +; +; +MSGID_MENU_EDIT_RESTORE +Restaurer +;Restore +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +R +;R +; +; +MSGID_MENU_PROJECT_ABOUTMUI +A propos de MUI... +;About MUI... +; +; +MSGID_MENU_EDIT_COLLAPSE +Plier l'entrée sélectionnée +;Collapse selected +; +; +MSGID_MENU_EDIT_EXPAND +Déplier l'entrée sélectionnée +;Expand selected +; +; +MSGID_MENU_EDIT_COLLAPSEALL +Tout plier +;Collapse all +; +; +MSGID_MENU_EDIT_EXPANDALL +Tout déplier +;Expand all +; +; +MSGID_MENU_EDIT_COPY +Copier +;Copy +; +; +MSGID_MENU_EDIT_CUT +Couper +;Cut +; +; +MSGID_MENU_EDIT_PASTE +Coller +;Paste +; +; +MSGID_MENU_HIDE_EMPTY_ENTRIES +Caher les entrées vides ? +;Hide empty entries? +; +; +MSGID_MENU_EDIT_FIND +Trouver... +;Find... +; +;--------------------------------------------- +; +MSGID_ABOUTREQOK +D'accord +;_OK +; +; +MSGID_ABOUTREQFORMAT +\33cPréferences : \033bTypes de fichiers V\0333%ld\0332.\0333%ld\033n\0332 de \033bScalos\033n\n\ +Compilé sous: \0333%s\0332\n\ +\033b© 1999%s \0333The Scalos Team\033n\0332 +;\33c\033bScalos FileTypes Preferences V%ld.%ld\033n\n\ +;%s\n\ +;© 1999-2004 The Scalos Team +; +; +MSGID_SHORTHELP_SAVEBUTTON +Pressez ce bouton afin de sauver \n\ +les options actuelles\n\ +afin de les rendre permanentes. +;Press this button to save \n\ +;the current settings\n\ +;and make changes permanent. +; +; +MSGID_SHORTHELP_USEBUTTON +Pressez ce bouton afin de sauver \n\ +les options actuelles et les\n\ +conserver jusqu'au prochain re-démarrage. +;Press this button to save \n\ +;the current settings\n\ +;and keep settings until reboot. +; +; +MSGID_SHORTHELP_CANCELBUTTON +Pressez ce bouton afin d'annuler \n\ +et d'oublier tout changement. +;Press this button to abort \n\ +;and forget all changes. +; +; +MSGID_REQTITLE_SAVEERROR +Erreur pendant l'écriture du fichier\n\ +des préférences des types de fichiers : "%s"\n\ +%s +;Error writing filetypes preferences\n\ +;file \"%s\"\n\ +;%s +; +; +MSGID_REQTITLE_READERROR +Erreur pendant le chargement du fichier\n\ +des préférences des types de fichiers : "%s"\n\ +%s +;Error reading filetypes preferences\n\ +;file \"%s\"\n\ +;%s +; +; +MSGID_PLUGIN_LIST_TITLE +Types de fichiers +;FileTypes +; +; +MSGID_SPLASHWINDOW_LOADING_FILETYPES_PREFS +\33c \033bChargement des préférences des \0333types de fichiers\0332... +; \33c Loading FileTypes Prefs... +; +; +MSGID_SPLASHWINDOW_APPLYING_FILETYPES_PREFS +\33c \033bApplication des préférences des \0333types de fichiers\0332... +; \33c Applying FileTypes Prefs... +; +; +MSGID_SPLASHWINDOW_SAVING_FILETYPES_PREFS +\33c \033bSauvegarde des préférences des \0333types de fichiers\0332... +; \33c Saving FileTypes Prefs... +; +;--------------------------------------------- +; +MSGID_ATTRCOLUMNTITLE_NAME +Nom +;Name +; +; +MSGID_ATTRCOLUMNTITLE_VALUE +Valeur +;Value +; +;--------------------------------------------- +; +MSGID_BUTTON_ADD_ENTRY +Ajouter +;Add +; +MSGID_BUTTON_ADD_ENTRY_KEY +A +;A +; +; +MSGID_SHORTHELP_BUTTON_ADD_ENTRY +...Ajouter... +;...Add... +; +; +MSGID_BUTTON_DELETE_ENTRY +Effacer +;Delete +; +; +MSGID_BUTTON_DELETE_ENTRY_KEY +D +;D +; +; +MSGID_SHORTHELP_BUTTON_DELETE_ENTRY +...Effacer l'entrée... +;...Delete Entry... +; +; +MSGID_BUTTON_ADD_ATTRIBUTE +Ajouter +;Add +; +; +MSGID_BUTTON_ADD_ATTRIBUTE_KEY +Raccourci clavier +; +; +; +MSGID_SHORTHELP_BUTTON_ADD_ATTRIBUTE +...Ajouter attribut... +;...Add Attribute... +; +; +MSGID_BUTTON_EDIT_ATTRIBUTE +Edition +;Edit +; +; +MSGID_SHORTHELP_BUTTON_EDIT_ATTRIBUTE +...Edition de l'attribut... +;...Edit Attribute... +; +; +MSGID_BUTTON_DELETE_ATTRIBUTE +Supprimer +;Remove +; +; +MSGID_BUTTON_DELETE_ATTRIBUTE_KEY +R +;R +; +; +MSGID_SHORTHELP_BUTTON_DELETE_ATTRIBUTE +...Effacer l'attribut... +;...Delete Attribute... +; +; New in 40.2 +; +MSGID_SHORTHELP_LAMP_CHANGED +Cet indicateur passe de l'état \033binactif\033n\n\ +à l'état \033bactif\033n, une fois que les options\n\ +ont été modifiées depuis le chargement initial. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +; +MSGID_BUTTON_CREATE_ICON +Créer une nouvelle icône +;Create New +; +; +MSGID_SHORTHELP_BUTTON_CREATE_ICON +Création d'une nouvelle icône\n\ +pour ce type de fichier. +;Create a new dedicated icon for this filetype. +; +; +MSGID_BUTTON_FIND_NEXT_SHORTHELP +Trouver le prochain type de fichier \n\ +correspondant à la recherche donnée. +;Find next filetype that matches the given search string. +; +; +MSGID_BUTTON_FIND_HIDE_SHORTHELP +Cacher le dialogue avec les types de fichiers. +;Hide Find Filetype Dialog. +; +; +MSGID_STRING_FIND_SHORTHELP +C'est la chaîne de recherche dans le nom des types de fichiers.\n\ +Pendant que vous tapez un charactère, la première entrée trouvée sera affichée. +;This is the string to find in filetypes' name.\n\ +;While you type, the first matching entry is always shown. +; +; +MSGID_BUTTON_FIND_PREV_SHORTHELP +Trouver le type de fichier correspondant à la chaine de caratères recherchée. +;Find previous filetype that matches the given search string. +; +;--------------------------------------------- +; +MSGID_ENTRYTYPE_FILETYPE +Type de fichier +;Filetype +; +; +MSGID_ENTRYTYPE_POPUPMENU +Menu popup +;Popup Menu +; +; +MSGID_ENTRYTYPE_SUBMENU +Sous-Menu +;SubMenu +; +; +MSGID_ENTRYTYPE_MENUITEM +Menu +;Menu Item +; +; +MSGID_ENTRYTYPE_INTERNALCMD +Commande interne +;Internal Command +; +; +MSGID_ENTRYTYPE_WBCMD +Commande Workbench +;Workbench Command +; +; +MSGID_ENTRYTYPE_AREXXCMD +Commande ARexx +;ARexx Command +; +; +MSGID_ENTRYTYPE_CLICMD +Commande CLI +;CLI Command +; +; +MSGID_ENTRYTYPE_PLUGINCMD +Commande Plugin pour menu +;Menu Plugin Command +; +; +MSGID_ENTRYTYPE_ICONWINDOWCMD +Commande fenêtre icônifiée +;Icon Window Command +; +; +MSGID_ENTRYTYPE_MENUSEPARATOR +Séparateur de menu +;Menu Separator +; +; +MSGID_ENTRYTYPE_TOOLTIP +Bulle d'informations(Tooltip) +;Tooltip +; +; +MSGID_ENTRYTYPE_GROUP +Groupe +;Group +; +; +MSGID_ENTRYTYPE_MEMBER +Membre +;Member +; +; +MSGID_ENTRYTYPE_HBAR +Barre horizontale +;Horizontal Bar +; +; +MSGID_ENTRYTYPE_STRING +Commande STRING +;String +; +; +MSGID_ENTRYTYPE_SPACE +Espace +;Space +; +; +MSGID_ENTRYTYPE_DTIMAGE +Image datatypes +;Datatypes Image +; +;--------------------------------------------- +; +MSGID_CHANGEME +Changez-moi +;Change me +; +;--------------------------------------------- +; +MSGID_BUTTON_CHANGE_ATTRIBUTE +Changer +;Change +; +; +MSGID_SHORTHELP_BUTTON_CHANGE_ATTRIBUTE +Permet d'attribuer des changements\n\ +et d'utiliser la valeur modifiée. +;Commit changes to attribute and use changed values. +; +; +MSGID_BUTTON_KEEP_ATTRIBUTE +Annuler +;Cancel +; +; +MSGID_SHORTHELP_BUTTON_KEEP_ATTRIBUTE +Annuler les changements attribués\n\ +en conservant la valeur initiale. +;Abort attribute changes and retain original values. +; +; +MSGID_EDITATTRIBUTE_WINDOWTITLE +Edition d'une valeur +;Edit Attribute Value +; +; +MSGID_EDITATTRIBUTE_TITLE +Nouvelle attribution d'une valeur +;Select new Value for Attribute +; +; +MSGID_EDITATTRIBUTE_TTFONT_ASLTITLE +Choix de la police TrueType ... +;Select TrueType Font... +; +; +MSGID_EDITATTRIBUTE_TTFONT_ASL_OKBUTTON +D'accord +;Ok +; +; +MSGID_EDITATTRIBUTE_TTFONT_ASL_CANCELBUTTON +Annuler +;Cancel +; +; +;MSGID_TTFONTSPAGE_ICONFONT_SAMPLETEXT_SHORTHELP +;Ceci est un aperçu de texte afin de visualiser\n\ +;la police TrueType choisie pour les icônes. +;This is an example text to visualize what the\n\ +;selected TrueType icon font looks like. +; +; +;MSGID_TTFONTSPAGE_TEXTWINDOWFONT_SAMPLETEXT_SHORTHELP +;Ceci est un aperçu de texte afin de visualiser\n\ +;la police TrueType choisie pour le texte des fenêtres. +;This is an example text to visualize what the\n\ +;selected TrueType text window font looks like. +; +; +MSGID_TTFONTSPAGE_SAMPLETEXT +The quick brown fox jumps over the lazy dog +;The quick brown fox jumps over the lazy dog +; +; +MSGID_TTFONTSPAGE_SCREENFONT_SAMPLETEXT_SHORTHELP +Ceci est un exemple de texte afin de visualiser\n\ +l'aspect de la police de caractères choisie. +;This is an example text to visualize what the\n\ +;selected TrueType screen font looks like. +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Le lancement de Scalos Prefs a échoué +;Scalos Filetypes Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Recommençer|Quitter +;Try again|Quit +; +MSGID_STARTUP_MCC_NOT_FOUND +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +Celle-ci n'est pas installée. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +MSGID_STARTUP_OLD_MCC +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +\n\ +La version installée est V%lu.%lu, installez-en une plus récente s'il vous plaît ! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +MSGID_STARTUP_MCC_IN_USE +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +%lu.%lu est actuellement utilisée par d'autres applications.\n\ +\n\ +Une fois la version requise installée,\n\ +fermez tous les programmes MUI, soyez sûr que l'ancienne classe\n\ +ne soit plus présente dans la mémoire puis, essayez de nouveau. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_REGISTERTITLE_RECOGNITION +Reconaissance +;Recognition +; +MSGID_REGISTERTITLE_ACTIONS +Actions +;Actions +; +;----------------------------------------------------------- +; +MSGID_BUTTON_ADD_FILETYPE +Ajouter +;Add +; +; +MSGID_SHORTHELP_BUTTON_ADD_FILETYPE +Ajouter une nouvelle entrée avec la\n\ +description du type du fichier.. +;Add a new entry with a filetypes description. +; +;----------------------------------------------------------- +; +MSGID_BUTTON_DELETE_FILETYPE +Supprimer +;Remove +; +; +MSGID_SHORTHELP_BUTTON_DELETE_FILETYPE +Supprime la description actuelle du type du fichier.\n\ +\033bAttention : La suppression d'une entrée principale d'un\n\ +"arbre", entraine également la suppression de son arborescence !\033n +;Remove currently selected filetypes description.\n\ +;\033bNote that removing a tree node deletes\n\ +;all subordinate entries!\033n +; +MSGID_BUTTON_REMOVE_FILETYPEACTION +Supprimer +;Remove +; +; +MSGID_SHORTHELP_BUTTON_REMOVE_FILETYPEACTION +Supprime l'action d'identification du\n\ +type du fichier actuelement sélectionné. +;Remove currently selected filetype identification action. +; +MSGID_BUTTON_ADD_FILETYPEACTION +Ajouter... +;Add... +; +; +MSGID_SHORTHELP_BUTTON_ADD_FILETYPEACTION +Ajoute une nouvelle action d'identification\n\ +au type du fichier. +;Add new filetype identification action. +; +MSGID_BUTTON_LEARN_FILETYPEACTION +Apprendre... +;Learn... +; +; +MSGID_SHORTHELP_BUTTON_LEARN_FILETYPEACTION +Apprend à reconnaître un type de fichier\n\ +en sélectionnant deux fichiers ou plus. +;Learn about filetype by giving two or more example files. +; +MSGID_NEW_FILETYPE +« Nouveau » +;«new» +; +;----------------------------------------------------------- +; +MSGID_FILETYPE_ADD_ACTION_MATCH +CORRESPONDANCE +;MATCH +; +MSGID_FILETYPE_ADD_ACTION_SEARCH +CHERCHER +;SEARCH +; +MSGID_FILETYPE_ADD_ACTION_FILESIZE +TAILLE DU FICHIER +;FILESIZE +; +MSGID_FILETYPE_ADD_ACTION_PATTERN +MOTIF +;PATTERN +; +MSGID_FILETYPE_ADD_ACTION_PROTECTION +PROTECTION +;PROTECTION +; +MSGID_FILETYPE_ADD_ACTION_OR +OU +;OR +; +MSGID_FILETYPE_ADD_ACTION_ISASCII +ASCII ? +;ISASCII +; +MSGID_FILETYPE_ADD_ACTION_MACROCLASS +MACROS +;MACROCLASS +; +; +MSGID_FILETYPE_ADD_ACTION_DOSDEVICE +UNITE DOS +;DOSDEVICE +; +; +MSGID_FILETYPE_ADD_ACTION_DEVICENAME +NOM UNITE +;DEVICENAME +; +; +MSGID_FILETYPE_ADD_ACTION_CONTENTS +CONTENU +;CONTENTS +; +; +MSGID_FILETYPE_ADD_ACTION_MINSIZEMB +MINITAILLE_MO +;MINSIZE_MB +; +; +MSGID_FILETYPE_ADD_ACTION_DOSTYPE +TYPE DOS +;DOSTYPE +; +;----------------------------------------------------------- +; +MSGID_FILETYPEACTION_MATCH_OFFSET +Décalage : +;Offset: +; +MSGID_FILETYPEACTION_MATCH_CASE_SENSITIVE +Sensible à la casse : +;Case sensitive: +; +MSGID_FILETYPEACTION_MATCH_MATCH +Correspondance : +;Match: +; +MSGID_FILETYPEACTION_SEARCH_SKIP_SPACES +Ignorer les espaces : +;Skip spaces: +; +MSGID_FILETYPEACTION_SEARCH_CASE_SENSITIVE +Sensible à la casse : +;Case sensitive: +; +MSGID_FILETYPEACTION_SEARCH_SEARCH +Chercher : +;Search: +; +MSGID_FILETYPEACTION_FILESIZE_FILESIZE +Taille du fichier : +;File size: +; +MSGID_FILETYPEACTION_PATTERN_PATTERN +Motif : +;Pattern: +; +MSGID_FILETYPEACTION_PROTECTION_R +R +;R +; +MSGID_FILETYPEACTION_PROTECTION_W +W +;W +; +MSGID_FILETYPEACTION_PROTECTION_E +E +;E +; +MSGID_FILETYPEACTION_PROTECTION_D +D +;D +; +MSGID_FILETYPEACTION_PROTECTION_S +S +;S +; +MSGID_FILETYPEACTION_PROTECTION_P +P +;P +; +MSGID_FILETYPEACTION_PROTECTION_A +A +;A +; +MSGID_FILETYPEACTION_PROTECTION_H +H +;H +; +MSGID_GROUP_FILETYPES_FILETYPES +Types de fichier +;Filetypes +; +MSGID_GROUP_FILETYPES_METHODS +Méthodes +;Methods +; +; +MSGID_FILETYPEACTION_MINSIZEMB_SIZE +Capacité minimum en MegaOctets : +;Minimum capacity in Megabytes: +; +; +MSGID_FILETYPEACTION_DOSDEVICE_PATTERN +Motif du nom de l'unité DOS : +;DOS device name pattern: +; +; +MSGID_FILETYPEACTION_DEVICENAME_PATTERN +Motif du nom de l'unité : +;Device name pattern: +; +; +MSGID_FILETYPEACTION_CONTENTS_PATTERN +Motif du contenu du volume : +;Volume contents pattern: +; +; +MSGID_FILETYPEACTION_DOSTYPE_PATTERN +Chaine de recherche de type DOS : +;DOS type match string: +; +;----------------------------------------------------------- +; +MSGID_FILETYPE_PROTECTION_SET +Saisir +;Set +; +MSGID_FILETYPE_PROTECTION_UNSET +Oublier +;Unset +; +MSGID_FILETYPE_PROTECTION_IGNORE +Ignorer +;Ignore +; +;----------------------------------------------------------- +; +; +MSGID_GROUP_FILETYPESACTION_MATCH +CORRESPONDACE : Attributs +;MATCH attributes +; +; +MSGID_GROUP_FILETYPESACTION_SEARCH +RECHERCHE Attributs +;SEARCH attributes +; +; +MSGID_GROUP_FILETYPESACTION_FILESIZE +TAILLE DU FICHIER : Attributs +;FILESIZE attributes +; +; +MSGID_GROUP_FILETYPESACTION_PATTERN +MOTIF : Attributs +;PATTERN attributes +; +; +MSGID_GROUP_FILETYPESACTION_PROTECTION +PROTECTION : Attributs +;PROTECTION attributes +; +; +MSGID_GROUP_FILETYPESACTION_MINSIZEMB +Atributs MINSIZEMO +;MINSIZEMB attributes +; +; +MSGID_GROUP_FILETYPESACTION_DOSDEVICE +Attributs UNITE DOS +;DOSDEVICE attributes +; +MSGID_GROUP_FILETYPESACTION_DEVICENAME +Attributs du NOM DE L'UNITE +;DEVICENAME attributes +; +; +MSGID_GROUP_FILETYPESACTION_CONTENTS +Attribut du CONTENU +;CONTENTS attributes +; +MSGID_GROUP_FILETYPESACTION_DOSTYPE +Attributs du type DOS +;DOSTYPE attributes +; +;----------------------------------------------------------- +; +; +MSGID_FILETYPESACTION_CASE_SENSITIVE + Casse sensible +; case sensitive +; +; +MSGID_FILETYPESACTION_SKIP_SPACES + Ignorer les espaces +; Skip spaces +; +MSGID_FILETYPESACTION_FILESIZE +%u octets +;%u bytes +; +MSGID_FILETYPESACTION_PROTECTION_IGNORE +- +;- +; +MSGID_FILETYPESACTION_PROTECTION_R_SET +R +;R +; +MSGID_FILETYPESACTION_PROTECTION_R_CLEARED +r +;r +; +MSGID_FILETYPESACTION_PROTECTION_W_SET +W +;W +; +MSGID_FILETYPESACTION_PROTECTION_W_CLEARED +w +;w +; +MSGID_FILETYPESACTION_PROTECTION_E_SET +E +;E +; +MSGID_FILETYPESACTION_PROTECTION_E_CLEARED +e +;e +; +MSGID_FILETYPESACTION_PROTECTION_D_SET +D +;D +; +MSGID_FILETYPESACTION_PROTECTION_D_CLEARED +d +;d +; +MSGID_FILETYPESACTION_PROTECTION_H_SET +H +;H +; +MSGID_FILETYPESACTION_PROTECTION_H_CLEARED +h +;h +; +MSGID_FILETYPESACTION_PROTECTION_A_SET +A +;A +; +MSGID_FILETYPESACTION_PROTECTION_A_CLEARED +a +;a +; +MSGID_FILETYPESACTION_PROTECTION_S_SET +S +;S +; +MSGID_FILETYPESACTION_PROTECTION_S_CLEARED +s +;s +; +MSGID_FILETYPESACTION_PROTECTION_P_SET +P +;P +; +MSGID_FILETYPESACTION_PROTECTION_P_CLEARED +p +;p +; +MSGID_FILETYPESACTION_MINSIZEMB +%u MegaOctets +;%u Megabytes +; +;----------------------------------------------------------- +; +MSGID_SHORTHELP_DEFAULTICON +Icône par défaut correspondant au\n\ +type de fichier sélectionné.\n\ +Si l'icône par défaut du type de fichier sélectionné n'est\n\ +pas localisée, la recherche s'éffectue à partir du groupe parent\n\ +le concernant jusqu'à ce qu'une icône soit localisée. +;This shows the default icon found for the selected\n\ +;filetype, and the associated name.\n\ +;If no default icon is found for the specific filetype,\n\ +;its parent is tried and so on, until as last\n\ +;resort the default project icon is used. +; +MSGID_SHORTHELP_LISTVIEW_FILETYPES +Vue hierarchique de tous les\n\ +types de fichiers définis. +;This list shows a hierarchic view of all defined filetypes. +; +MSGID_SHORTHELP_STRING_FILETYPES +Ceci est le nom du type de fichier actuellement sélectionné.\n\ +Le nom est utilisé afin de trouver son icône par défaut,\n\ +ex:\n\ + Pour le nom \"\033bpicture\033n\", une icône par défaut\n\ +nommée \"\033bdef_picture.info\033n\" sera recherchée. +;This is the name of the currently selected filetype.\n\ +;The name is used to find an associated default icon,\n\ +;i.e, for the name \"picture\", a default icon\n\ +;named \"def_picture.info\" is being looked for. +; +MSGID_SHORTHELP_LISTVIEW_FILETYPE_ACTION +Cette liste montre les actions servant à identifier\n\ +le type de fichier actuellement sélectionné.\n\ +Les actions sont prise en compte succèssivement du haut vers le bas,\n\ +et si toutes les actions correspondent, le fichier en question est\n\ +reconnu comme étant de ce type. +;This list shows the actions to identify the currently selected filetype.\n\ +;The actions are processed sequentially from top to bottom,\n\ +;and if all actions match, the file in question is\n\ +;considered to be of this type. +; +MSGID_SHORTHELP_VIRTGROUP_FILETYPE_ACTION_ATTRIBUTES +Cette zone contient les attributs de l'action\n\ +d'identification du type du fichier sélectionné.\n\ +Les attributs disponibles dépendent du type d'action\n\ +d'identification sélectioné. +;This area contains the attributes for the currently\n\ +;selected filetypes identification action.\n\ +;The available attributes vary depending on the\n\ +;type of the selected identification action. +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_MATCH_OFFSET +Ceci défini la position où le début de recherche doit\n\ +commencer à l'intérieur du fichier. +;This is the file offset where matching shall start. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_MATCH +C'est la chaîne de caractères qui est comparé\n\ +avec le type de fichier.\n\ +Les caractères non transcriptibles peuvent être\n\ +entrés via leurs codes hexadécimaux, ex: \\\\x00. +;This is the string that filetype is being compared to.\n\ +;Non-printable characters can be entered via their hexadecimal codes, e.g. \\x00. +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_SEARCH +Ceci est la chaîne de caractères à partir de laquelle\n\ +le type de fichier est recherché.\n\ +Les caractères non transcriptibles peuvent être entrés\n\ +via leur codes hexadecimaux, ex: \\\\x00. +;This is the string the filetype is being searched for.\n\ +;Non-printable characters can be entered via their hexadecimal codes, e.g. \\x00. +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_FILESIZE +Ceci est la recherche de la taille correspondant au fichier. +;This is the file size the filetype is checked for. +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_PATTERN +Ceci est le nom du motif correspondant au type de fichier. Tous les\n\ +motifs standard du DOS peuvent être utilisés comme, \033b?\033n ou \033b#\033n. +;This is the file name pattern the filetype is being matched against.\n\ +;You may use all standard DOS patterns like ? or #. +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_R +Définir si oui ou non, le fichier doit être lisible. +;Select here whether the filetype needs to be readable,\n\ +;or must not be readable, or if readability doesn't matter. +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_W +Définir si oui ou non, le fichier doit être protégé en écriture. +;Select here whether the filetype needs to be writeable,\n\ +;or must not be writeable, or if writeability doesn't matter. +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_E +Définir si oui ou non, le fichier doit être executable. +;Select here whether the filetype needs to be executable,\n\ +;or must not be executable, or if executability doesn't matter. +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_D +Définir si oui ou non, le fichier peut être éffacer. +;Select here whether the filetype needs to be deleteable,\n\ +;or must not be deleteable, or if deleteability doesn't matter. +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_S +Définir si oui ou non, le fichier doit être un script. +;Select here whether the filetype needs to be a script,\n\ +;or must be no script, or if the script attribute doesn't matter. +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_P +Définir si oui ou non, le fichier doit être pur. +;Select here whether the filetype needs to be pure,\n\ +;or must not be pure, or if the pure attribute doesn't matter. +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_A +Définir si oui ou non, le fichier doit être archivé. +;Select here whether the filetype needs to be archived,\n\ +;or must not be archived, or if archived state doesn't matter. +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_H +Définir si oui ou non, le fichier doit être caché. +;Select here whether the filetype needs to be hidden,\n\ +;or must be visible, or if visibility doesn't matter. +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_MINSIZEMB +Ceci est la capacité minimum analysée d'un volume. +;This is the mimimum volume capacity to checked for. +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_DOSDEVICE +Ceci est le nom de l'unité DOS (ex : \"DH0\") pour un volume. +;This is the DOS device name (e.g. \"DH0\") for a volume. +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_DEVICENAME +Ceci est le nom du pilote (ex : \"scsi.device\") pour un volume. +;This is the device name (e.g. \"scsi.device\") for a volume. +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_CONTENTS +C'est le motif de recherche pour le contenu d'un volume. +;This is a matching pattern for the contents of a volume. +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_DOSTYPE +C'est la chaine de recherche pour le type DOS (ex : \"SFS\\0\") d'un volume.\n\ +UTilisez une notation hexadécimale comme \"\\\\x1f\" pour les charactères spéciaux. +;This is the match string for the DOS type (e.g. \"SFS\\0\") of a volume.\n\ +;Use hex notation like \"\\x1f\" for non-printable characters. +; +;----------------------------------------------------------- +; +MSGID_LEARN_OPEN +Analyser deux fichiers, ou plus. +;Select two or more files to learn from +; +MSGID_SELECT_TWO_REQ_OK +_D'accord +;_Ok +; +MSGID_SELECT_TWO_REQ_CONTENTS +Vous devez sélectionner au moins deux fichiers ! +;You must select at least two sample files! +; +;----------------------------------------------------------- +; +MSGID_COM1NAME +Mis en arrière-plan +; Backdrop +; +; +MSGID_COM2NAME +Executer une commande +; Execute Command +; +; +MSGID_COM3NAME +Tout retracer +; Redraw All +; +; +MSGID_COM4NAME +Tout mettre à jour +; Update All +; +; +MSGID_COM5NAME +A propos de Scalos +; About Scalos +; +; +MSGID_COM6NAME +Quitter +; Quit +; +; +MSGID_COM7NAME +Nouveau répertoire +; New Drawer +; +; +MSGID_COM8NAME +Ouvrir Parent +; Open Parent +; +; +MSGID_COM9NAME +Fermer fenêtre +; Close Window +; +; +MSGID_COM10NAME +Mettre à jour +; Update +; +; +MSGID_COM11NAME +Sélectionner le contenu +; Select Contents +; +; +MSGID_COM12NAME +Réorganiser +; Cleanup +; +; +MSGID_COM13NAME +Figer - Fenêtre +; Snapshot - Window +; +; +MSGID_COM14NAME +Figer - Tout +; Snapshot - All +; +; +MSGID_COM15NAME +Montrer - Seulement les icônes +; Show - Only Icons +; +; +MSGID_COM16NAME +Montrer - Tous les fichiers +; Show - All Files +; +; +MSGID_COM17NAME +Afficher par - Icône +; View By - Icon +; +; +MSGID_COM18NAME +Afficher par - Texte +; View By - Text +; +; +MSGID_COM19NAME +Ouvrir +; Open +; +; +MSGID_COM20NAME +Relancer Scalos +; Reset Scalos +; +; +MSGID_COM21NAME +Renommer +; Rename +; +; +MSGID_COM22NAME +Information +; Information +; +; +MSGID_COM23NAME +Figer +; Snapshot +; +; +MSGID_COM24NAME +Libérer +; UnSnapshot +; +; +MSGID_COM25NAME +Sortir +; Leave Out +; +; +MSGID_COM26NAME +Ranger +; Put Away +; +; +MSGID_COM27NAME +Effacer +; Delete +; +; +MSGID_COM28NAME +Copier +; Clone +; +; +MSGID_COM29NAME +Vider la corbeille +; Empty Trashcan +; +; +MSGID_COM30NAME +Dernier message +; Last Message +; +; +MSGID_COM31NAME +Retracer +; Redraw +; +; +MSGID_COM32NAME +Iconifier +; Iconify +; +; +MSGID_COM33NAME +Formater le Volume... +; Format Disk... +; +; +MSGID_COM34NAME +Désactiver... +; Shutdown... +; +; +MSGID_COM35NAME +Ajuster la taille +; Size to fit +; +; +MSGID_COM36NAME +Ne rien sélectionner +; Clear Selection +; +; +MSGID_COM37NAME +Afficher par - Taille +; View By - Size +; +; +MSGID_COM38NAME +Afficher par - Date +; View By - Date +; +; +MSGID_COM39NAME +Copier le fichier +; Copy file +; +; +MSGID_COM40NAME +Couper le fichier +; Cut file +; +; +MSGID_COM41NAME +Coller le fichier +; Paste file +; +; +MSGID_COM42NAME +Afficher par - Type +; View By - Type +; +; +MSGID_COM43NAME +Réorganiser par - Nom +; Cleanup By - Name +; +; +MSGID_COM44NAME +Réorganiser par - Date +; Cleanup By - Date +; +; +MSGID_COM45NAME +Réorganiser par - Taille +; Cleanup By - Size +; +; +MSGID_COM46NAME +Réorganiser par - Type +; Cleanup By - Type +; +; +MSGID_COM_ICONPROPERTIES +Propriété des icônes +;Icon properties +; +; +MSGID_COM_WINDOWPROPERTIES +Propriété des fenêtres +;Window properties +; +; +MSGID_COM47NAME +Afficher par - Défaut +;View By - Default +; +; +MSGID_COM48NAME +Montrer - Défaut +;Show - Default +; +; +MSGID_COM49NAME +Copier vers... +;Copy to... +; +; +MSGID_COM50NAME +Déplacer vers... +;Move to ... +; +; +MSGID_COM51NAME +Créer une vignette +; Create thumbnail +; +; +MSGID_COM_OPENNEWWINDOW +Ouvrir dans une nouvelle fenêtre +;Open in new window +; +; +MSGID_COM_THUMBNAILCACHECLEANUP +Nettoyer le cache des vignettes +;Cleanup thumbnail cache +; +MSGID_COM_FIND +Trouver un ou des fichiers +;Find File(s) +; +MSGID_COM_UNDO +Précédent +;Undo +; +MSGID_COM_REDO +Suivant +;Redo +; +MSGID_FIND_HITCOUNT_FMT +%ld Trouvés +;%ld Hits +; +MSGID_COM_OPENBROWSERWINDOW +Ouvrir dans une fenêtre en mode liste +;Open in Browser Window +; +;----------------------------------------------------------- +; diff --git "a/scalos/Prefs/FileTypes/Catalogs/fran\303\247ais/Scalos/config.mk" "b/scalos/Prefs/FileTypes/Catalogs/fran\303\247ais/Scalos/config.mk" new file mode 100755 index 000000000..8b7056423 --- /dev/null +++ "b/scalos/Prefs/FileTypes/Catalogs/fran\303\247ais/Scalos/config.mk" @@ -0,0 +1,40 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = français + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = french + +else + +############################################################################### +# AmigaOS and AROS + +LANG = français + +endif +endif diff --git "a/scalos/Prefs/FileTypes/Catalogs/fran\303\247ais/Scalos/makefile" "b/scalos/Prefs/FileTypes/Catalogs/fran\303\247ais/Scalos/makefile" new file mode 100644 index 000000000..a9d11436e --- /dev/null +++ "b/scalos/Prefs/FileTypes/Catalogs/fran\303\247ais/Scalos/makefile" @@ -0,0 +1,13 @@ +# makefile for Scalos (translated Texts : français) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mfrançais\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +ScalosFileTypes.catalog : ScalosFileTypes.ct ../../../ScalosFileTypes.cd + +All: ScalosFileTypes.catalog diff --git "a/scalos/Prefs/FileTypes/Catalogs/fran\303\247ais/Scalos/makefile-new" "b/scalos/Prefs/FileTypes/Catalogs/fran\303\247ais/Scalos/makefile-new" new file mode 100644 index 000000000..396083e6b --- /dev/null +++ "b/scalos/Prefs/FileTypes/Catalogs/fran\303\247ais/Scalos/makefile-new" @@ -0,0 +1,30 @@ +# makefile for FileTypes (translated Texts : français) +# $Date: 2011-08-06 19:37:48 +0200 (Sa, 06. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = ScalosFileTypes + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Prefs/FileTypes/Catalogs/sample/Scalos/ScalosFileTypes.ct b/scalos/Prefs/FileTypes/Catalogs/sample/Scalos/ScalosFileTypes.ct new file mode 100755 index 000000000..482427fae --- /dev/null +++ b/scalos/Prefs/FileTypes/Catalogs/sample/Scalos/ScalosFileTypes.ct @@ -0,0 +1,1438 @@ +; ScalosFileTypes.ct +## version $VER: ScalosFileTypes.catalog 40.23 (11 Apr 2010 17:25:39) +## codeset 0s +## language xxxxxx +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos FileTypes Prefs Plugin +;Scalos FileTypes Prefs Plugin +; +; +MSGID_SAVENAME +Save +;Save +; +; +MSGID_USENAME +Use +;Use +; +; +MSGID_CANCELNAME +Cancel +;Cancel +; +;--------------------------------------------- +; +MSGID_MENU_PROJECT_OPEN +Open... +;Open... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +O +;O +; +; +MSGID_MENU_PROJECT_SAVEAS +Save As... +;Save As... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +A +;A +; +; +MSGID_MENU_PROJECT_ABOUT +About... +;About... +; +; +MSGID_MENU_PROJECT_QUIT +Quit +;Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +;Q +; +; +MSGID_MENU_PROJECT +Project +;Project +; +; +MSGID_MENU_EDIT_LASTSAVED +Last Saved +;Last Saved +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +L +;L +; +; +MSGID_MENU_EDIT +Edit +;Edit +; +; +MSGID_MENU_SETTINGS_CREATEICONS +Create Icons? +;Create Icons? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +I +;I +; +; +MSGID_MENU_SETTINGS +Settings +;Settings +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +Reset To Defaults +;Reset To Defaults +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +D +;D +; +; +MSGID_MENU_EDIT_RESTORE +Restore +;Restore +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +R +;R +; +; +MSGID_MENU_PROJECT_ABOUTMUI +About MUI... +;About MUI... +; +; +MSGID_MENU_EDIT_COLLAPSE +Collapse selected +;Collapse selected +; +; +MSGID_MENU_EDIT_EXPAND +Expand selected +;Expand selected +; +; +MSGID_MENU_EDIT_COLLAPSEALL +Collapse all +;Collapse all +; +; +MSGID_MENU_EDIT_EXPANDALL +Expand all +;Expand all +; +; +MSGID_MENU_EDIT_COPY +Copy +;Copy +; +; +MSGID_MENU_EDIT_CUT +Cut +;Cut +; +; +MSGID_MENU_EDIT_PASTE +Paste +;Paste +; +;+++translateme+++ +MSGID_MENU_HIDE_EMPTY_ENTRIES +Hide empty entries? +;Hide empty entries? +; +;+++translateme+++ +MSGID_MENU_EDIT_FIND +Find... +;Find... +; +;--------------------------------------------- +; +MSGID_ABOUTREQOK +_OK +;_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos FileTypes Preferences V%ld.%ld\033n\n\ +%s\n\ +© 1999-2003 The Scalos Team +;\33c\033bScalos FileTypes Preferences V%ld.%ld\033n\n\ +;%s\n\ +;© 1999-2003 The Scalos Team +; +; +MSGID_SHORTHELP_SAVEBUTTON +Press this button to save \n\ +the current settings\n\ +and make changes permanent. +;Press this button to save \n\ +;the current settings\n\ +;and make changes permanent. +; +; +MSGID_SHORTHELP_USEBUTTON +Press this button to save \n\ +the current settings\n\ +and keep settings until reboot. +;Press this button to save \n\ +;the current settings\n\ +;and keep settings until reboot. +; +; +MSGID_SHORTHELP_CANCELBUTTON +Press this button to abort \n\ +and forget all changes. +;Press this button to abort \n\ +;and forget all changes. +; +; +MSGID_REQTITLE_SAVEERROR +Error writing filetypes preferences\n\ +file \"%s\"\n\ +%s +;Error writing filetypes preferences\n\ +;file \"%s\"\n\ +;%s +; +; +MSGID_REQTITLE_READERROR +Error reading filetypes preferences\n\ +file \"%s\"\n\ +%s +;Error reading filetypes preferences\n\ +;file \"%s\"\n\ +;%s +; +; +MSGID_PLUGIN_LIST_TITLE +FileTypes +;FileTypes +; +;--------------------------------------------- +; +MSGID_ATTRCOLUMNTITLE_NAME +Name +;Name +; +; +MSGID_ATTRCOLUMNTITLE_VALUE +Value +;Value +; +;--------------------------------------------- +; +MSGID_BUTTON_ADD_ENTRY +Add +;Add +; +MSGID_BUTTON_ADD_ENTRY_KEY +A +;A +; +; +MSGID_SHORTHELP_BUTTON_ADD_ENTRY +Add new filetypes action entry.\n\ +Add a new entry for a filetype's popup menu or tooltip. +;Add new filetypes action entry.\n\ +;Add a new entry for a filetype's popup menu or tooltip. +; +; +MSGID_BUTTON_DELETE_ENTRY +Delete +;Delete +; +; +MSGID_BUTTON_DELETE_ENTRY_KEY +D +;D +; +; +MSGID_SHORTHELP_BUTTON_DELETE_ENTRY +Delete currently selected filetype's\n\ +popup menu or tooltip entry. +\033bNote: removing a list node also\n\ +deletes every subordinate node!\033n +;Delete currently selected filetype's\n\ +;popup menu or tooltip entry. +;\033bNote: removing a list node also\n\ +;deletes every subordinate node!\033n +; +; +MSGID_BUTTON_ADD_ATTRIBUTE +Add +;Add +; +; +MSGID_BUTTON_ADD_ATTRIBUTE_KEY + +; +; +; +MSGID_SHORTHELP_BUTTON_ADD_ATTRIBUTE +Add Attribute for currently selected filetype's\n\ +popup menu or tooltip entry.\n\ +Attributes include an entry's name, font, or alignment. +;Add Attribute for currently selected filetype's\n\ +;popup menu or tooltip entry.\n\ +;Attributes include an entry's name, font, or alignment. +; +; +MSGID_BUTTON_EDIT_ATTRIBUTE +Edit +;Edit +; +; +MSGID_SHORTHELP_BUTTON_EDIT_ATTRIBUTE +Change value of a filetype's popup menu\n\ +or tooltip entry attribute. +;Change value of a filetype's popup menu\n\ +;or tooltip entry attribute. +; +; +MSGID_BUTTON_DELETE_ATTRIBUTE +Remove +;Remove +; +; +MSGID_BUTTON_DELETE_ATTRIBUTE_KEY +R +;R +; +; +MSGID_SHORTHELP_BUTTON_DELETE_ATTRIBUTE +Remove currently selected filetype's popup menu\n\ +or tooltip entry attribute.\n\ +Note that not all attributes can be removed\n\ +from specific entries. +;Remove currently selected filetype's popup menu\n\ +;or tooltip entry attribute.\n\ +;Note that not all attributes can be removed\n\ +;from specific entries. +; +; new in 40.2 +; +MSGID_SHORTHELP_LAMP_CHANGED +This lamp indicator changes from \033bOff\033n\n\ +to \033bOk\033n when the settings have been\n\ +modified since initial loading. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +;+++translateme+++ +MSGID_BUTTON_CREATE_ICON +Create New +;Create New +; +;+++translateme+++ +MSGID_SHORTHELP_BUTTON_CREATE_ICON +Create a new dedicated icon for this filetype. +;Create a new dedicated icon for this filetype. +; +;+++translateme+++ +MSGID_BUTTON_FIND_NEXT_SHORTHELP +Find next filetype that matches the given search string. +;Find next filetype that matches the given search string. +; +;+++translateme+++ +MSGID_BUTTON_FIND_HIDE_SHORTHELP +Hide Find Filetype Dialog. +;Hide Find Filetype Dialog. +; +;+++translateme+++ +MSGID_STRING_FIND_SHORTHELP +This is the string to find in filetypes' name.\n\ +While you type, the first matching entry is always shown. +;This is the string to find in filetypes' name.\n\ +;While you type, the first matching entry is always shown. +; +;+++translateme+++ +MSGID_BUTTON_FIND_PREV_SHORTHELP +Find previous filetype that matches the given search string. +;Find previous filetype that matches the given search string. +; +;--------------------------------------------- +; +MSGID_ENTRYTYPE_FILETYPE +Filetype +;Filetype +; +; +MSGID_ENTRYTYPE_POPUPMENU +Popup Menu +;Popup Menu +; +; +MSGID_ENTRYTYPE_SUBMENU +SubMenu +;SubMenu +; +; +MSGID_ENTRYTYPE_MENUITEM +Menu Item +;Menu Item +; +; +MSGID_ENTRYTYPE_INTERNALCMD +Internal Command +;Internal Command +; +; +MSGID_ENTRYTYPE_WBCMD +Workbench Command +;Workbench Command +; +; +MSGID_ENTRYTYPE_AREXXCMD +ARexx Command +;ARexx Command +; +; +MSGID_ENTRYTYPE_CLICMD +CLI Command +;CLI Command +; +; +MSGID_ENTRYTYPE_PLUGINCMD +Menu Plugin Command +;Menu Plugin Command +; +; +MSGID_ENTRYTYPE_ICONWINDOWCMD +Icon Window Command +;Icon Window Command +; +; +MSGID_ENTRYTYPE_MENUSEPARATOR +\033C +;\033C +; +; +MSGID_ENTRYTYPE_TOOLTIP +Tooltip +;Tooltip +; +; +MSGID_ENTRYTYPE_GROUP +Group +;Group +; +; +MSGID_ENTRYTYPE_MEMBER +Member +;Member +; +; +MSGID_ENTRYTYPE_HBAR +Horizontal Bar +;Horizontal Bar +; +; +MSGID_ENTRYTYPE_STRING +String +;String +; +; +MSGID_ENTRYTYPE_SPACE +Space +;Space +; +; +MSGID_ENTRYTYPE_DTIMAGE +Datatypes Image +;Datatypes Image +; +;--------------------------------------------- +; +MSGID_CHANGEME +Change me +;Change me +; +;--------------------------------------------- +; +MSGID_BUTTON_CHANGE_ATTRIBUTE +Change +;Change +; +MSGID_SHORTHELP_BUTTON_CHANGE_ATTRIBUTE +Commit changes to attribute and use changed values. +;Commit changes to attribute and use changed values. +; +MSGID_BUTTON_KEEP_ATTRIBUTE +Cancel +;Cancel +; +MSGID_SHORTHELP_BUTTON_KEEP_ATTRIBUTE +Abort attribute changes and retain original values. +;Abort attribute changes and retain original values. +; +MSGID_EDITATTRIBUTE_WINDOWTITLE +Edit Attribute Value +;Edit Attribute Value +; +MSGID_EDITATTRIBUTE_TITLE +Select new Value for Attribute +;Select new Value for Attribute +; +;+++translateme+++ +MSGID_EDITATTRIBUTE_TTFONT_ASLTITLE +Select TrueType Font... +;Select TrueType Font... +; +;+++translateme+++ +MSGID_EDITATTRIBUTE_TTFONT_ASL_OKBUTTON +Ok +;Ok +; +;+++translateme+++ +MSGID_EDITATTRIBUTE_TTFONT_ASL_CANCELBUTTON +Cancel +;Cancel +; +;+++translateme+++ +MSGID_TTFONTSPAGE_SAMPLETEXT +The quick brown fox jumps over the lazy dog +;The quick brown fox jumps over the lazy dog +; +; +;+++translateme+++ +MSGID_TTFONTSPAGE_SCREENFONT_SAMPLETEXT_SHORTHELP +This is an example text to visualize what the\n\ +selected TrueType screen font looks like. +;This is an example text to visualize what the\n\ +;selected TrueType screen font looks like. +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Scalos Filetypes Prefs startup failed +;Scalos Filetypes Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Try again|Quit +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +;+++translateme+++ +MSGID_REGISTERTITLE_RECOGNITION +Recognition +;Recognition +; +;+++translateme+++ +MSGID_REGISTERTITLE_ACTIONS +Actions +;Actions +; +;----------------------------------------------------------- +; +;+++translateme+++ +MSGID_BUTTON_ADD_FILETYPE +Add +;Add +; +;+++translateme+++ +MSGID_SHORTHELP_BUTTON_ADD_FILETYPE +Add a new entry with a filetypes description. +;Add a new entry with a filetypes description. +; +;----------------------------------------------------------- +; +;+++translateme+++ +MSGID_BUTTON_DELETE_FILETYPE +Remove +Remove +; +;+++translateme+++ +MSGID_SHORTHELP_BUTTON_DELETE_FILETYPE +Remove currently selected filetypes description.\n\ +\033bNote that removing a tree node deletes\n\ +all subordinate entries!\033n +;Remove currently selected filetypes description.\n\ +;\033bNote that removing a tree node deletes\n\ +;all subordinate entries!\033n +; +;+++translateme+++ +MSGID_BUTTON_REMOVE_FILETYPEACTION +Remove +;Remove +; +;+++translateme+++ +MSGID_SHORTHELP_BUTTON_REMOVE_FILETYPEACTION +Remove currently selected filetype identification action. +;Remove currently selected filetype identification action. +; +;+++translateme+++ +MSGID_BUTTON_ADD_FILETYPEACTION +Add... +;Add... +; +;+++translateme+++ +MSGID_SHORTHELP_BUTTON_ADD_FILETYPEACTION +Add new filetype identification action. +;Add new filetype identification action. +; +;+++translateme+++ +MSGID_BUTTON_LEARN_FILETYPEACTION +Learn... +;Learn... +; +;+++translateme+++ +MSGID_SHORTHELP_BUTTON_LEARN_FILETYPEACTION +Learn about filetype by giving two or more example files. +;Learn about filetype by giving two or more example files. +; +;+++translateme+++ +MSGID_NEW_FILETYPE +«new» +;«new» +; +;----------------------------------------------------------- +; +;+++translateme+++ +MSGID_FILETYPE_ADD_ACTION_MATCH +MATCH +;MATCH +; +;+++translateme+++ +MSGID_FILETYPE_ADD_ACTION_SEARCH +SEARCH +;SEARCH +; +;+++translateme+++ +MSGID_FILETYPE_ADD_ACTION_FILESIZE +FILESIZE +;FILESIZE +; +;+++translateme+++ +MSGID_FILETYPE_ADD_ACTION_PATTERN +PATTERN +;PATTERN +; +;+++translateme+++ +MSGID_FILETYPE_ADD_ACTION_PROTECTION +PROTECTION +;PROTECTION +; +;+++translateme+++ +MSGID_FILETYPE_ADD_ACTION_OR +OR +;OR +; +;+++translateme+++ +MSGID_FILETYPE_ADD_ACTION_ISASCII +ISASCII +;ISASCII +; +;+++translateme+++ +MSGID_FILETYPE_ADD_ACTION_MACROCLASS +MACROCLASS +;MACROCLASS +; +;+++translateme+++ +MSGID_FILETYPE_ADD_ACTION_DOSDEVICE +DOSDEVICE +;DOSDEVICE +; +;+++translateme+++ +MSGID_FILETYPE_ADD_ACTION_DEVICENAME +DEVICENAME +;DEVICENAME +; +;+++translateme+++ +MSGID_FILETYPE_ADD_ACTION_CONTENTS +CONTENTS +;CONTENTS +; +;+++translateme+++ +MSGID_FILETYPE_ADD_ACTION_MINSIZEMB +MINSIZE_MB +;MINSIZE_MB +; +;+++translateme+++ +MSGID_FILETYPE_ADD_ACTION_DOSTYPE +DOSTYPE +;DOSTYPE +; +;----------------------------------------------------------- +; +;+++translateme+++ +MSGID_FILETYPEACTION_MATCH_OFFSET +Offset: +;Offset: +; +;+++translateme+++ +MSGID_FILETYPEACTION_MATCH_CASE_SENSITIVE +Case sensitive: +;Case sensitive: +; +;+++translateme+++ +MSGID_FILETYPEACTION_MATCH_MATCH +Match: +;Match: +; +;+++translateme+++ +MSGID_FILETYPEACTION_SEARCH_SKIP_SPACES +Skip spaces: +;Skip spaces: +; +;+++translateme+++ +MSGID_FILETYPEACTION_SEARCH_CASE_SENSITIVE +Case sensitive: +;Case sensitive: +; +;+++translateme+++ +MSGID_FILETYPEACTION_SEARCH_SEARCH +Search: +;Search: +; +;+++translateme+++ +MSGID_FILETYPEACTION_FILESIZE_FILESIZE +File size: +;File size: +; +;+++translateme+++ +MSGID_FILETYPEACTION_PATTERN_PATTERN +Pattern: +;Pattern: +; +;+++translateme+++ +MSGID_FILETYPEACTION_PROTECTION_R +R +;R +; +;+++translateme+++ +MSGID_FILETYPEACTION_PROTECTION_W +W +;W +; +;+++translateme+++ +MSGID_FILETYPEACTION_PROTECTION_E +E +;E +; +;+++translateme+++ +MSGID_FILETYPEACTION_PROTECTION_D +D +;D +; +;+++translateme+++ +MSGID_FILETYPEACTION_PROTECTION_S +S +;S +; +;+++translateme+++ +MSGID_FILETYPEACTION_PROTECTION_P +P +;P +; +;+++translateme+++ +MSGID_FILETYPEACTION_PROTECTION_A +A +;A +; +;+++translateme+++ +MSGID_FILETYPEACTION_PROTECTION_H +H +;H +; +;+++translateme+++ +MSGID_GROUP_FILETYPES_FILETYPES +Filetypes +;Filetypes +; +;+++translateme+++ +MSGID_GROUP_FILETYPES_METHODS +Methods +;Methods +; +;+++translateme+++ +MSGID_FILETYPEACTION_MINSIZEMB_SIZE +Minimum capacity in Megabytes: +;Minimum capacity in Megabytes: +; +;+++translateme+++ +MSGID_FILETYPEACTION_DOSDEVICE_PATTERN +DOS device name pattern: +;DOS device name pattern: +; +;+++translateme+++ +MSGID_FILETYPEACTION_DEVICENAME_PATTERN +Device name pattern: +;Device name pattern: +; +;+++translateme+++ +MSGID_FILETYPEACTION_CONTENTS_PATTERN +Volume contents pattern: +;Volume contents pattern: +; +;+++translateme+++ +MSGID_FILETYPEACTION_DOSTYPE_PATTERN +DOS type match string: +;DOS type match string: +; +;----------------------------------------------------------- +; +MSGID_FILETYPE_PROTECTION_SET +Set +;Set +; +; +MSGID_FILETYPE_PROTECTION_UNSET +Unset +;Unset +; +; +MSGID_FILETYPE_PROTECTION_IGNORE +Ignore +;Ignore +; +;----------------------------------------------------------- +; +;+++translateme+++ +MSGID_GROUP_FILETYPESACTION_MATCH +MATCH attributes +;MATCH attributes +; +;+++translateme+++ +MSGID_GROUP_FILETYPESACTION_SEARCH +SEARCH attributes +;SEARCH attributes +; +;+++translateme+++ +MSGID_GROUP_FILETYPESACTION_FILESIZE +FILESIZE attributes +;FILESIZE attributes +; +;+++translateme+++ +MSGID_GROUP_FILETYPESACTION_PATTERN +PATTERN attributes +;PATTERN attributes +; +;+++translateme+++ +MSGID_GROUP_FILETYPESACTION_PROTECTION +PROTECTION attributes +;PROTECTION attributes +; +;+++translateme+++ +MSGID_GROUP_FILETYPESACTION_MINSIZEMB +MINSIZEMB attributes +;MINSIZEMB attributes +; +;+++translateme+++ +MSGID_GROUP_FILETYPESACTION_DOSDEVICE +DOSDEVICE attributes +;DOSDEVICE attributes +; +;+++translateme+++ +MSGID_GROUP_FILETYPESACTION_DEVICENAME +DEVICENAME attributes +;DEVICENAME attributes +; +;+++translateme+++ +MSGID_GROUP_FILETYPESACTION_CONTENTS +CONTENTS attributes +;CONTENTS attributes +; +;+++translateme+++ +MSGID_GROUP_FILETYPESACTION_DOSTYPE +DOSTYPE attributes +;DOSTYPE attributes +; +;----------------------------------------------------------- +; +;+++translateme+++ +MSGID_FILETYPESACTION_CASE_SENSITIVE + case sensitive +; case sensitive +; +;+++translateme+++ +MSGID_FILETYPESACTION_SKIP_SPACES + Skip spaces +; Skip spaces +; +;+++translateme+++ +MSGID_FILETYPESACTION_FILESIZE +%u bytes +;%u bytes +; +;+++translateme+++ +MSGID_FILETYPESACTION_PROTECTION_IGNORE +- +;- +; +;+++translateme+++ +MSGID_FILETYPESACTION_PROTECTION_R_SET +R +;R +; +;+++translateme+++ +MSGID_FILETYPESACTION_PROTECTION_R_CLEARED +r +;r +; +;+++translateme+++ +MSGID_FILETYPESACTION_PROTECTION_W_SET +W +;W +; +;+++translateme+++ +MSGID_FILETYPESACTION_PROTECTION_W_CLEARED +w +;w +; +;+++translateme+++ +MSGID_FILETYPESACTION_PROTECTION_E_SET +E +;E +; +;+++translateme+++ +MSGID_FILETYPESACTION_PROTECTION_E_CLEARED +e +;e +; +;+++translateme+++ +MSGID_FILETYPESACTION_PROTECTION_D_SET +D +;D +; +;+++translateme+++ +MSGID_FILETYPESACTION_PROTECTION_D_CLEARED +d +;d +; +;+++translateme+++ +MSGID_FILETYPESACTION_PROTECTION_H_SET +H +;H +; +;+++translateme+++ +MSGID_FILETYPESACTION_PROTECTION_H_CLEARED +h +;h +; +;+++translateme+++ +MSGID_FILETYPESACTION_PROTECTION_A_SET +A +;A +; +;+++translateme+++ +MSGID_FILETYPESACTION_PROTECTION_A_CLEARED +a +;a +; +;+++translateme+++ +MSGID_FILETYPESACTION_PROTECTION_S_SET +S +;S +; +;+++translateme+++ +MSGID_FILETYPESACTION_PROTECTION_S_CLEARED +s +;s +; +;+++translateme+++ +MSGID_FILETYPESACTION_PROTECTION_P_SET +P +;P +; +;+++translateme+++ +MSGID_FILETYPESACTION_PROTECTION_P_CLEARED +p +;p +; +;+++translateme+++ +MSGID_FILETYPESACTION_MINSIZEMB +%u Megabytes +; +;----------------------------------------------------------- +; +;+++translateme+++ +MSGID_SHORTHELP_DEFAULTICON +This shows the default icon found for the selected\n\ +filetype, and the associated name.\n\ +If no default icon is found for the specific filetype,\n\ +its parent is tried and so on, until as last\n\ +resort the default project icon is used. +;This shows the default icon found for the selected\n\ +;filetype, and the associated name.\n\ +;If no default icon is found for the specific filetype,\n\ +;its parent is tried and so on, until as last\n\ +;resort the default project icon is used. +; +;+++translateme+++ +MSGID_SHORTHELP_LISTVIEW_FILETYPES +This list shows a hierarchic view of all defined filetypes. +;This list shows a hierarchic view of all defined filetypes. +; +;+++translateme+++ +MSGID_SHORTHELP_STRING_FILETYPES +This is the name of the currently selected filetype.\n\ +The name is used to find an associated default icon,\n\ +i.e, for the name \"picture\", a default icon\n\ +named \"def_picture.info\" is being looked for. +;This is the name of the currently selected filetype.\n\ +;The name is used to find an associated default icon,\n\ +;i.e, for the name \"picture\", a default icon\n\ +;named \"def_picture.info\" is being looked for. +; +;+++translateme+++ +MSGID_SHORTHELP_LISTVIEW_FILETYPE_ACTION +This list shows the actions to identify the currently selected filetype.\n\ +The actions are processed sequentially from top to bottom,\n\ +and if all actions match, the file in question is\n\ +considered to be of this type. +;This list shows the actions to identify the currently selected filetype.\n\ +;The actions are processed sequentially from top to bottom,\n\ +;and if all actions match, the file in question is\n\ +;considered to be of this type. +; +;+++translateme+++ +MSGID_SHORTHELP_VIRTGROUP_FILETYPE_ACTION_ATTRIBUTES +This area contains the attributes for the currently\n\ +selected filetypes identification action.\n\ +The available attributes vary depending on the\n\ +type of the selected identification action. +;This area contains the attributes for the currently\n\ +;selected filetypes identification action.\n\ +;The available attributes vary depending on the\n\ +;type of the selected identification action. +; +;+++translateme+++ +MSGID_SHORTHELP_STRING_FILETYPEACTION_MATCH_OFFSET +This is the file offset where matching shall start. +;This is the file offset where matching shall start. +; +;+++translateme+++ +MSGID_SHORTHELP_STRING_FILETYPEACTION_MATCH +This is the string that filetype is being compared to.\n\ +Non-printable characters can be entered via their hexadecimal codes, e.g. \\x00. +;This is the string that filetype is being compared to.\n\ +;Non-printable characters can be entered via their hexadecimal codes, e.g. \\x00. +; +;+++translateme+++ +MSGID_SHORTHELP_STRING_FILETYPEACTION_SEARCH +This is the string the filetype is being searched for.\n\ +Non-printable characters can be entered via their hexadecimal codes, e.g. \\x00. +;This is the string the filetype is being searched for.\n\ +;Non-printable characters can be entered via their hexadecimal codes, e.g. \\x00. +; +;+++translateme+++ +MSGID_SHORTHELP_STRING_FILETYPEACTION_FILESIZE +This is the file size the filetype is checked for. +;This is the file size the filetype is checked for. +; +;+++translateme+++ +MSGID_SHORTHELP_STRING_FILETYPEACTION_PATTERN +This is the file name pattern the filetype is being matched against.\n\ +You may use all standard DOS patterns like ? or #. +;This is the file name pattern the filetype is being matched against.\n\ +;You may use all standard DOS patterns like ? or #. +; +;+++translateme+++ +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_R +Select here whether the filetype needs to be readable,\n\ +or must not be readable, or if readability doesn't matter. +;Select here whether the filetype needs to be readable,\n\ +;or must not be readable, or if readability doesn't matter. +; +;+++translateme+++ +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_W +Select here whether the filetype needs to be writeable,\n\ +or must not be writeable, or if writeability doesn't matter. +;Select here whether the filetype needs to be writeable,\n\ +;or must not be writeable, or if writeability doesn't matter. +; +;+++translateme+++ +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_E +Select here whether the filetype needs to be executable,\n\ +or must not be executable, or if executability doesn't matter. +;Select here whether the filetype needs to be executable,\n\ +;or must not be executable, or if executability doesn't matter. +; +;+++translateme+++ +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_D +Select here whether the filetype needs to be deleteable,\n\ +or must not be deleteable, or if deleteability doesn't matter. +;Select here whether the filetype needs to be deleteable,\n\ +;or must not be deleteable, or if deleteability doesn't matter. +; +;+++translateme+++ +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_S +Select here whether the filetype needs to be a script,\n\ +or must be no script, or if the script attribute doesn't matter. +;Select here whether the filetype needs to be a script,\n\ +;or must be no script, or if the script attribute doesn't matter. +; +;+++translateme+++ +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_P +Select here whether the filetype needs to be pure,\n\ +or must not be pure, or if the pure attribute doesn't matter. +;Select here whether the filetype needs to be pure,\n\ +;or must not be pure, or if the pure attribute doesn't matter. +; +;+++translateme+++ +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_A +Select here whether the filetype needs to be archived,\n\ +or must not be archived, or if archived state doesn't matter. +;Select here whether the filetype needs to be archived,\n\ +;or must not be archived, or if archived state doesn't matter. +; +;+++translateme+++ +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_H +Select here whether the filetype needs to be hidden,\n\ +or must be visible, or if visibility doesn't matter. +;Select here whether the filetype needs to be hidden,\n\ +;or must be visible, or if visibility doesn't matter. +; +;+++translateme+++ +MSGID_SHORTHELP_STRING_FILETYPEACTION_MINSIZEMB +This is the mimimum volume capacity to checked for. +;This is the mimimum volume capacity to checked for. +; +;+++translateme+++ +MSGID_SHORTHELP_STRING_FILETYPEACTION_DOSDEVICE +This is the DOS device name (e.g. \"DH0\") for a volume. +;This is the DOS device name (e.g. \"DH0\") for a volume. +; +;+++translateme+++ +MSGID_SHORTHELP_STRING_FILETYPEACTION_DEVICENAME +This is the device name (e.g. \"scsi.device\") for a volume. +;This is the device name (e.g. \"scsi.device\") for a volume. +; +;+++translateme+++ +MSGID_SHORTHELP_STRING_FILETYPEACTION_CONTENTS +This is a matching pattern for the contents of a volume. +;This is a matching pattern for the contents of a volume. +; +;+++translateme+++ +MSGID_SHORTHELP_STRING_FILETYPEACTION_DOSTYPE +This is the match string for the DOS type (e.g. \"SFS\\0\") of a volume.\n\ +Use hex notation like \"\\x1f\" for non-printable characters. +;This is the match string for the DOS type (e.g. \"SFS\\0\") of a volume.\n\ +;Use hex notation like \"\\x1f\" for non-printable characters. +; +;----------------------------------------------------------- +; +;+++translateme+++ +MSGID_LEARN_OPEN +Select two or more files to learn from +;Select two or more files to learn from +; +;+++translateme+++ +MSGID_SELECT_TWO_REQ_OK +_Ok +;_Ok +; +;+++translateme+++ +MSGID_SELECT_TWO_REQ_CONTENTS +You must select at least two sample files! +;You must select at least two sample files! +; +;----------------------------------------------------------- +; +MSGID_COM1NAME +Backdrop +; +; +MSGID_COM2NAME +Execute Command +; +; +MSGID_COM3NAME +Redraw All +; +; +MSGID_COM4NAME +Update All +; +; +MSGID_COM5NAME +About Scalos +; +; +MSGID_COM6NAME +Quit +; +; +MSGID_COM7NAME +New Drawer +; +; +MSGID_COM8NAME +Open Parent +; +; +MSGID_COM9NAME +Close Window +; +; +MSGID_COM10NAME +Update +; +; +MSGID_COM11NAME +Select Contents +; +; +MSGID_COM12NAME +Cleanup +; +; +MSGID_COM13NAME +Snapshot - Window +; +; +MSGID_COM14NAME +Snapshot - All +; +; +MSGID_COM15NAME +Show - Only Icons +; +; +MSGID_COM16NAME +Show - All Files +; +; +MSGID_COM17NAME +View By - Icon +; +; +MSGID_COM18NAME +View By - Text +; +; +MSGID_COM19NAME +Open +; +; +MSGID_COM20NAME +Reset Scalos +; +; +MSGID_COM21NAME +Rename +; +; +MSGID_COM22NAME +Information +; +; +MSGID_COM23NAME +Snapshot +; +; +MSGID_COM24NAME +UnSnapshot +; +; +MSGID_COM25NAME +Leave Out +; +; +MSGID_COM26NAME +Put Away +; +; +MSGID_COM27NAME +Delete +; +MSGID_COM28NAME +Clone +; +; +MSGID_COM29NAME +Empty Trashcan +; +; +MSGID_COM30NAME +Last Message +; +; +MSGID_COM31NAME +Redraw +; +; +MSGID_COM32NAME +Iconify +; +; +MSGID_COM33NAME +Format Disk... +; +; +MSGID_COM34NAME +Shutdown... +; +; +MSGID_COM35NAME +Size To Fit +; +; +MSGID_COM36NAME +Clear Selection +; +; +MSGID_COM37NAME +View By - Size +; +; +MSGID_COM38NAME +View By - Date +; +; +MSGID_COM39NAME +Copy file +; +; +MSGID_COM40NAME +Cut file +; +; +MSGID_COM41NAME +Paste file +; +; +MSGID_COM42NAME +View By - Type +; +; +MSGID_COM43NAME +Cleanup By - Name +; +; +MSGID_COM44NAME +Cleanup By - Date +; +; +MSGID_COM45NAME +Cleanup By - Size +; +; +MSGID_COM46NAME +Cleanup By - Type +; +; +MSGID_COM_ICONPROPERTIES +Icon properties +; +; +MSGID_COM_WINDOWPROPERTIES +Window properties +; +; +;+++translateme+++ +MSGID_COM47NAME +View By - Default +; +;+++translateme+++ +MSGID_COM48NAME +Show - Default +; +;+++translateme+++ +MSGID_COM49NAME +Copy to... +;Copy to... +; +;+++translateme+++ +MSGID_COM50NAME +Move to... +;Move to... +; +;+++translateme+++ +MSGID_COM51NAME +Create thumbnail +;Create thumbnail +; +;+++translateme+++ +MSGID_COM_OPENNEWWINDOW +Open in new window +;Open in new window +; +;+++translateme+++ +MSGID_COM_THUMBNAILCACHECLEANUP +Cleanup thumbnail cache +;Cleanup thumbnail cache +; +;+++translateme+++ +MSGID_COM_FIND +Find File(s) +;Find File(s) +; +;+++translateme+++ +MSGID_COM_UNDO +Undo +;Undo +; +;+++translateme+++ +MSGID_COM_REDO +Redo +;Redo +; +;+++translateme+++ +MSGID_FIND_HITCOUNT_FMT +%ld Hits +;%ld Hits +; +;+++translateme+++ +MSGID_COM_OPENBROWSERWINDOW +Open in Browser Window +;Open in Browser Window +; +;----------------------------------------------------------- +; + diff --git a/scalos/Prefs/FileTypes/FileTypes.c b/scalos/Prefs/FileTypes/FileTypes.c new file mode 100644 index 000000000..760eec0ec --- /dev/null +++ b/scalos/Prefs/FileTypes/FileTypes.c @@ -0,0 +1,934 @@ +// FileTypes.c +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include // +jmc+ +#include + +#include + +struct ScalosFileTypes_LocaleInfo +{ + APTR li_LocaleBase; + APTR li_Catalog; + struct LocaleIFace *li_ILocale; +}; + +#define ScalosFileTypes_NUMBERS +#define ScalosFileTypes_ARRAY +#define ScalosFileTypes_CODE +#include STR(SCALOSLOCALE) + +//---------------------------------------------------------------------------- + +#define Sizeof(array) (sizeof(array) / sizeof((array)[0])) + +//---------------------------------------------------------------------------- + +#if !defined(__amigaos4__) && !defined(__AROS__) +#include + +long _stack = 16384; // minimum stack size, used by SAS/C startup code +#endif + +//---------------------------------------------------------------------------- + +// local data structures + +#define KeyButtonHelp(name,key,HelpText)\ + TextObject,\ + ButtonFrame,\ + MUIA_Font, MUIV_Font_Button,\ + MUIA_Text_Contents, name,\ + MUIA_Text_PreParse, "\33c",\ + MUIA_Text_HiChar , key,\ + MUIA_ControlChar , key,\ + MUIA_CycleChain , TRUE, \ + MUIA_InputMode , MUIV_InputMode_RelVerify,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShortHelp, HelpText,\ + End + + +#define Application_Return_EDIT 0 +#define Application_Return_USE 1001 +#define Application_Return_SAVE 1002 + +//---------------------------------------------------------------------------- + +// local functions + +static void init(void); +static void fail(APTR APP_Main, CONST_STRPTR str); +static BOOL OpenLibraries(void); +static void CloseLibraries(void); +static SAVEDS(APTR) INTERRUPT OpenAboutMUIFunc(struct Hook *hook, Object *o, Msg msg); +static STRPTR GetLocString(ULONG MsgId); +//static void TranslateStringArray(STRPTR *stringArray); +static struct MUI_CustomClass *OpenPrefsModule(CONST_STRPTR FileName); +static struct TagItem *CreatePluginSubWindowArray(void); +static void DisposePrefsPlugin(void); +static BOOL CheckMCCforPlugin(STRPTR *UsedClasses, size_t MaxUsedClasses); +static BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev); +#if !defined(__SASC) &&!defined(__MORPHOS__) +size_t stccpy(char *dest, const char *src, size_t MaxLen); +#endif /* !defined(__SASC) &&!defined(__MORPHOS__) */ + +//---------------------------------------------------------------------------- + +// local data items + +struct Library *MUIMasterBase; +T_LOCALEBASE LocaleBase; +struct Library *IconBase; +struct IntuitionBase *IntuitionBase; +struct Library *ScalosPrefsPluginBase; + +#ifdef __amigaos4__ +extern struct Library *SysBase; +struct MUIMasterIFace *IMUIMaster; +struct LocaleIFace *ILocale; +struct IconIFace *IIcon; +struct IntuitionIFace *IIntuition; +struct ScalosPrefsPluginIFace *IScalosPrefsPlugin; +#endif + +static struct Catalog *FileTypesCatalog; + +static struct Hook AboutMUIHook = { { NULL, NULL }, HOOKFUNC_DEF(OpenAboutMUIFunc), NULL }; + +static struct MUI_CustomClass *FileTypesPluginClass; + +static struct TagItem *SubWindowTagList; + +static APTR Group_Plugin; +static APTR Group_Buttons2; +static Object **PluginSubWindows; +static APTR APP_Main; +static APTR WIN_Main; +static APTR WIN_AboutMUI; +static APTR WIN_Splash; // +jmc+ +static APTR TEXT_Splash; // +jmc+ +static APTR SaveButton, UseButton, CancelButton; +static APTR MenuOpen, MenuSaveAs; +static APTR MenuAbout, MenuAboutMUI, MenuQuit; +static APTR MenuResetToDefaults, MenuLastSaved, MenuRestore; +static APTR MenuCreateIcons; + +//---------------------------------------------------------------------------- + +int main(int argc, char *argv[]) +{ + LONG Action = Application_Return_EDIT; + LONG win_opened = 0; + struct RDArgs *rdArgs = NULL; + CONST_STRPTR GivenFileName = NULL; + BPTR oldDir = (BPTR)NULL; + ULONG fCreateIcons = TRUE; + struct DiskObject *FileTypesDiskObject = NULL; + struct DiskObject *icon = NULL; + STRPTR ProgramName; + STRPTR UsedClasses[32]; + struct WBStartup *WBenchMsg = + (argc == 0) ? (struct WBStartup *)argv : NULL; + + init(); + + if (WBenchMsg && WBenchMsg->sm_ArgList) + { + static char PrgNamePath[512]; + struct WBArg *arg; + + if (WBenchMsg->sm_NumArgs > 1) + { + arg = &WBenchMsg->sm_ArgList[1]; + GivenFileName = arg->wa_Name; + } + else + { + arg = &WBenchMsg->sm_ArgList[0]; + } + + ProgramName = PrgNamePath; + + NameFromLock(WBenchMsg->sm_ArgList[0].wa_Lock, PrgNamePath, sizeof(PrgNamePath)); + AddPart(PrgNamePath, WBenchMsg->sm_ArgList[0].wa_Name, sizeof(PrgNamePath)); + + oldDir = CurrentDir(arg->wa_Lock); + icon = GetDiskObject(arg->wa_Name); + if (icon) + { + STRPTR tt; + + tt = FindToolType(icon->do_ToolTypes, "CREATEICONS"); + if (tt) + { + if (MatchToolValue(tt, "NO")) + fCreateIcons = FALSE; + } + + tt = FindToolType(icon->do_ToolTypes, "ACTION"); + if (tt) + { + if (MatchToolValue(tt, "EDIT")) + Action = Application_Return_EDIT; + if (MatchToolValue(tt, "USE")) + Action = Application_Return_USE; + if (MatchToolValue(tt, "SAVE")) + Action = Application_Return_SAVE; + } + } + } + else + { + SIPTR ArgArray[4]; + + ProgramName = argv[0]; + + memset(ArgArray, 0, sizeof(ArgArray)); + + rdArgs = ReadArgs("FROM,EDIT/S,USE/S,SAVE/S", ArgArray, NULL); + + if (ArgArray[0]) + GivenFileName = (CONST_STRPTR) ArgArray[0]; + if (ArgArray[1]) + Action = Application_Return_EDIT; + if (ArgArray[2]) + Action = Application_Return_USE; + if (ArgArray[3]) + Action = Application_Return_SAVE; + } + + if (NULL == FileTypesPluginClass) + fail(APP_Main, "Failed to open FileTypes Plugin."); + + Group_Plugin = NewObject(FileTypesPluginClass->mcc_Class, 0, + MUIA_ScalosPrefs_CreateIcons, fCreateIcons, + MUIA_ScalosPrefs_ProgramName, (ULONG) ProgramName, + TAG_END); + if (NULL == Group_Plugin) + fail(APP_Main, "Failed to create Group_Plugin."); + + if (!CheckMCCforPlugin(UsedClasses, Sizeof(UsedClasses))) + fail(APP_Main, "Required MCC missing."); + + FileTypesDiskObject = GetDiskObject(ProgramName); + + SubWindowTagList = CreatePluginSubWindowArray(); + + APP_Main = ApplicationObject, + MUIA_Application_Title, GetLocString(MSGID_TITLENAME), + MUIA_Application_Version, "$VER: Scalos FileTypes Prefs V40.24 (" __DATE__ ")" COMPILER_STRING, + MUIA_Application_Copyright, "The Scalos Team, 2000" CURRENTYEAR, + MUIA_Application_Author, "The Scalos Team", + MUIA_Application_Description, "Scalos FileTypes preferences editor", + MUIA_Application_Base, "SCALOS_FILETYPES", + FileTypesDiskObject ? MUIA_Application_DiskObject : TAG_IGNORE, FileTypesDiskObject, +#if defined(MUIA_Application_UsedClasses) + MUIA_Application_UsedClasses, UsedClasses, +#endif /* MUIA_Application_UsedClasses */ + + SubWindow, WIN_Main = WindowObject, + MUIA_Window_Title, GetLocString(MSGID_TITLENAME), + MUIA_Window_ID, MAKE_ID('M','A','I','N'), + MUIA_Window_AppWindow, TRUE, + WindowContents, VGroup, + Child, Group_Plugin, + + Child, Group_Buttons2 = HGroup, + MUIA_Group_SameWidth, TRUE, + Child, SaveButton = KeyButtonHelp(GetLocString(MSGID_SAVENAME), + 's', GetLocString(MSGID_SHORTHELP_SAVEBUTTON)), + Child, UseButton = KeyButtonHelp(GetLocString(MSGID_USENAME), + 'u', GetLocString(MSGID_SHORTHELP_USEBUTTON)), + Child, CancelButton = KeyButtonHelp(GetLocString(MSGID_CANCELNAME), + 'c', GetLocString(MSGID_SHORTHELP_CANCELBUTTON)), + End, //HGroup + End, //VGroup + End, //WindowObject + +// ----------------------------------------------------------------------------------------------- + + SubWindow, WIN_Splash = WindowObject, + MUIA_Window_AppWindow, FALSE, + MUIA_Window_CloseGadget, FALSE, + MUIA_Window_DepthGadget, FALSE, + MUIA_Window_DragBar, FALSE, + MUIA_Window_NoMenus, TRUE, + MUIA_Window_LeftEdge, MUIV_Window_LeftEdge_Centered, + MUIA_Window_TopEdge, MUIV_Window_TopEdge_Centered, + + WindowContents, VGroup, + Child, TEXT_Splash = TextObject, + MUIA_Weight, 0, + MUIA_Text_Contents, (ULONG) GetLocString(MSGID_SPLASHWINDOW_LOADING_FILETYPES_PREFS), + End, //TextObject + End, //VGroup + + End, //SubWindow + +// ----------------------------------------------------------------------------------------------- + + MUIA_Application_Menustrip, MenustripObject, + Child, MenuObjectT(GetLocString(MSGID_MENU_PROJECT)), + Child, MenuOpen = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_OPEN), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_PROJECT_OPEN_SHORT), + End, + Child, MenuSaveAs = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_SAVEAS), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_PROJECT_SAVEAS_SHORT), + End, + Child, MenuitemObject, + MUIA_Menuitem_Title, -1, + End, + Child, MenuAbout = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUT), + End, + Child, MenuAboutMUI = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUTMUI), + End, + Child, MenuitemObject, + MUIA_Menuitem_Title, -1, + End, + Child, MenuQuit = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_QUIT), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_PROJECT_QUIT_SHORT), + End, + + End, //MenuObjectT + Child, MenuObjectT(GetLocString(MSGID_MENU_EDIT)), + Child, MenuResetToDefaults = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_EDIT_RESETTODEFAULTS), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT), + End, + Child, MenuLastSaved = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_EDIT_LASTSAVED), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_EDIT_LASTSAVED_SHORT), + End, + Child, MenuRestore = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_EDIT_RESTORE), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_EDIT_RESTORE_SHORT), + End, + End, //MenuObjectT + Child, MenuObjectT(GetLocString(MSGID_MENU_SETTINGS)), + Child, MenuCreateIcons = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_SETTINGS_CREATEICONS), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_SETTINGS_CREATEICONS_SHORT), + MUIA_Menuitem_Checkit, TRUE, + MUIA_Menuitem_Checked, fCreateIcons, + End, + End, //MenuObjectT + End, //MenuStripObject + + SubWindowTagList ? TAG_MORE : TAG_IGNORE, SubWindowTagList, + End; //ApplicationObject + + if (NULL == APP_Main) + { + MUI_DisposeObject(Group_Plugin); + Group_Plugin = NULL; + fail(APP_Main, "Failed to create Application."); + } + + // +jmc+ open Splash window + set(WIN_Splash, MUIA_Window_Open, TRUE); + + set(Group_Plugin, MUIA_ScalosPrefs_MainWindow, (ULONG) WIN_Main); + set(Group_Plugin, MUIA_ScalosPrefs_Application, (ULONG) APP_Main); + + DoMethod(Group_Plugin, MUIM_ScalosPrefs_PageActive, TRUE); + + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + WIN_Main, 3, MUIM_Set, MUIA_Window_Open, FALSE); + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + DoMethod(CancelButton, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + DoMethod(MenuQuit, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + DoMethod(SaveButton, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_Application_ReturnID, Application_Return_SAVE); + + DoMethod(UseButton, MUIM_Notify,MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_Application_ReturnID, Application_Return_USE); + + DoMethod(MenuOpen, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + Group_Plugin, 1, MUIM_ScalosPrefs_OpenConfig); + + DoMethod(MenuSaveAs, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + Group_Plugin, 1, MUIM_ScalosPrefs_SaveConfigAs); + + DoMethod(MenuResetToDefaults, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + Group_Plugin, 1, MUIM_ScalosPrefs_ResetToDefaults); + + DoMethod(MenuLastSaved, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + Group_Plugin, 1, MUIM_ScalosPrefs_LastSavedConfig); + + DoMethod(MenuRestore, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + Group_Plugin, 1, MUIM_ScalosPrefs_RestoreConfig); + + DoMethod(MenuAbout, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + Group_Plugin, 1, MUIM_ScalosPrefs_About); + + DoMethod(MenuAboutMUI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &AboutMUIHook); + + DoMethod(MenuCreateIcons, MUIM_Notify, MUIA_Menuitem_Checked, MUIV_EveryTime, + Group_Plugin, 3, MUIM_Set, MUIA_ScalosPrefs_CreateIcons, MUIV_TriggerValue); + + d1(kprintf(__FUNC__ "/%ld: \n", __LINE__)); + + if (icon) + { + DoMethod(Group_Plugin, MUIM_ScalosPrefs_ParseToolTypes, icon->do_ToolTypes); + } + + if (GivenFileName) + { + DoMethod(Group_Plugin, MUIM_ScalosPrefs_LoadNamedConfig, GivenFileName); + } + else + { + DoMethod(Group_Plugin, MUIM_ScalosPrefs_LoadConfig); + } + + if (Application_Return_EDIT == Action) + { + set(WIN_Main, MUIA_Window_Open, TRUE); + + get(WIN_Main, MUIA_Window_Open, &win_opened); + + // +jmc+ close Splash window + set(WIN_Splash, MUIA_Window_Open, FALSE); + + if (win_opened) + { + ULONG sigs = 0; + BOOL Run = TRUE; + + while (Run) + { + Action = DoMethod(APP_Main, MUIM_Application_NewInput, &sigs); + + switch (Action) + { + case MUIV_Application_ReturnID_Quit: + case Application_Return_SAVE: + case Application_Return_USE: + Run = FALSE; + break; + } + + if (Run && sigs) + { + sigs = Wait(sigs | SIGBREAKF_CTRL_C); + + if (sigs & SIGBREAKF_CTRL_C) + { + Run = FALSE; + break; + } + } + } + } + else + { + printf("failed to open main window !\n"); + } + } + + switch (Action) + { + case Application_Return_SAVE: + set(TEXT_Splash, MUIA_Text_Contents, (ULONG) GetLocString(MSGID_SPLASHWINDOW_SAVING_FILETYPES_PREFS)); // +jmc+ + set(WIN_Splash, MUIA_Window_Open, TRUE); // +jmc+ + DoMethod(Group_Plugin, MUIM_ScalosPrefs_SaveConfig); + break; + case Application_Return_USE: + set(TEXT_Splash, MUIA_Text_Contents, (ULONG) GetLocString(MSGID_SPLASHWINDOW_APPLYING_FILETYPES_PREFS)); // +jmc+ + set(WIN_Splash, MUIA_Window_Open, TRUE); // +jmc+ + DoMethod(Group_Plugin, MUIM_ScalosPrefs_UseConfig); + break; + } + + set(WIN_Main, MUIA_Window_Open, FALSE); + set(WIN_Splash, MUIA_Window_Open, FALSE); // +jmc+ + + if (FileTypesDiskObject) + FreeDiskObject(FileTypesDiskObject); + if (icon) + FreeDiskObject(icon); + if (oldDir) + CurrentDir(oldDir); + if (rdArgs) + FreeArgs(rdArgs); + + fail(APP_Main, NULL); + + return 0; +} + + +static VOID fail(APTR APP_Main, CONST_STRPTR str) +{ + if (APP_Main) + MUI_DisposeObject(APP_Main); + + DisposePrefsPlugin(); + + if (FileTypesCatalog) + { + CloseCatalog(FileTypesCatalog); + FileTypesCatalog = NULL; + } + + CloseLibraries(); + + if (str) + { + puts(str); + exit(20); + } + + exit(0); +} + + +static void init(void) +{ + if (!OpenLibraries()) + fail(NULL, "Failed to open "MUIMASTER_NAME"."); + + if (LocaleBase) + FileTypesCatalog = OpenCatalogA(NULL, "Scalos/ScalosFileTypes.catalog", NULL); + + FileTypesPluginClass = OpenPrefsModule("FileTypes.prefsplugin"); +} + + +static BOOL OpenLibraries(void) +{ + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + if (NULL == IntuitionBase) + return FALSE; +#ifdef __amigaos4__ + IIntuition = (struct IntuitionIFace *) GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + return FALSE; +#endif + + MUIMasterBase = OpenLibrary("zune.library", 0); + if (NULL == MUIMasterBase) + MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN-1); + if (NULL == MUIMasterBase) + return FALSE; +#ifdef __amigaos4__ + IMUIMaster = (struct MUIMasterIFace *) GetInterface((struct Library *)MUIMasterBase, "main", 1, NULL); + if (NULL == IMUIMaster) + return FALSE; +#endif + + IconBase = OpenLibrary("icon.library", 0); + if (NULL == IconBase) + return FALSE; +#ifdef __amigaos4__ + IIcon = (struct IconIFace *) GetInterface((struct Library *)IconBase, "main", 1, NULL); + if (NULL == IIcon) + return FALSE; +#endif + + LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 39); +#ifdef __amigaos4__ + if (LocaleBase) + ILocale = (struct LocaleIFace *) GetInterface((struct Library *)LocaleBase, "main", 1, NULL); +#endif + + return TRUE; +} + + +static void CloseLibraries(void) +{ +#ifdef __amigaos4__ + if (ILocale) + { + DropInterface((struct Interface *)ILocale); + ILocale = NULL; + } +#endif + if (LocaleBase) + { + CloseLibrary((struct Library *) LocaleBase); + LocaleBase = NULL; + } +#ifdef __amigaos4__ + if (IIcon) + { + DropInterface((struct Interface *)IIcon); + IIcon = NULL; + } +#endif + if (IconBase) + { + CloseLibrary(IconBase); + IconBase = NULL; + } +#ifdef __amigaos4__ + if (IMUIMaster) + { + DropInterface((struct Interface *)IMUIMaster); + IMUIMaster = NULL; + } +#endif + if (MUIMasterBase) + { + CloseLibrary(MUIMasterBase); + MUIMasterBase = NULL; + } +#ifdef __amigaos4__ + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } +#endif + if (IntuitionBase) + { + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } +} + +//---------------------------------------------------------------------------- + +static STRPTR GetLocString(ULONG MsgId) +{ + struct ScalosFileTypes_LocaleInfo li; + + li.li_Catalog = FileTypesCatalog; +#ifndef __amigaos4__ + li.li_LocaleBase = LocaleBase; +#else + li.li_ILocale = ILocale; +#endif + + return (STRPTR) GetScalosFileTypesString(&li, MsgId); +} +/* +static void TranslateStringArray(STRPTR *stringArray) +{ + while (*stringArray) + { + *stringArray = GetLocString((ULONG) *stringArray); + stringArray++; + } +} +*/ +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT OpenAboutMUIFunc(struct Hook *hook, Object *o, Msg msg) +{ + if (NULL == WIN_AboutMUI) + { + WIN_AboutMUI = MUI_NewObject(MUIC_Aboutmui, + MUIA_Window_RefWindow, WIN_Main, + MUIA_Aboutmui_Application, APP_Main, + End; + } + + if (WIN_AboutMUI) + set(WIN_AboutMUI, MUIA_Window_Open, TRUE); + + return 0; +} + +//---------------------------------------------------------------------------- + +static struct MUI_CustomClass *OpenPrefsModule(CONST_STRPTR FileName) +{ + struct MUI_CustomClass *pclass = NULL; + + d1(kprintf(__FUNC__ "/%ld: FileName=<%s>\n", __LINE__, FileName)); + + do { + ScalosPrefsPluginBase = OpenLibrary(FileName, 0); + d1(kprintf(__FUNC__ "/%ld: ScalosPrefsPluginBase=%08lx\n", __LINE__, ScalosPrefsPluginBase)); + if (NULL == ScalosPrefsPluginBase) + break; +#ifdef __amigaos4__ + IScalosPrefsPlugin = (struct ScalosPrefsPluginIFace *)GetInterface( + ScalosPrefsPluginBase, "main", 1, NULL + ); +#endif + + pclass = (struct MUI_CustomClass *) SCAGetPrefsInfo(SCAPREFSINFO_GetClass); + d1(kprintf(__FUNC__ "/%ld: PluginClass=%08lx\n", __LINE__, ppl->ppl_PluginClass)); + if (NULL == pclass) + break; + } while (0); + + if (NULL == pclass) + DisposePrefsPlugin(); + + return pclass; +} + + +static struct TagItem *CreatePluginSubWindowArray(void) +{ + struct TagItem *SubWindowTagList; + struct TagItem *ti; + ULONG SubWindowCount = 0; + ULONG n; + + PluginSubWindows = (Object **) DoMethod(Group_Plugin, MUIM_ScalosPrefs_CreateSubWindows); + + for (n=0; PluginSubWindows && PluginSubWindows[n]; n++) + SubWindowCount++; + + SubWindowTagList = ti = calloc(1 + SubWindowCount, sizeof(struct TagItem)); + if (NULL == SubWindowTagList) + return NULL; + + for (n=0; PluginSubWindows && PluginSubWindows[n]; n++) + { + ti->ti_Tag = MUIA_Application_Window; + ti->ti_Data = (ULONG) PluginSubWindows[n]; + ti++; + } + + ti->ti_Tag = TAG_END; + + return SubWindowTagList; +} + + +static void DisposePrefsPlugin(void) +{ +#ifdef __amigaos4__ + if (IScalosPrefsPlugin) + { + DropInterface((struct Interface *)IScalosPrefsPlugin); + IScalosPrefsPlugin = NULL; + } +#endif + if (ScalosPrefsPluginBase) + { + d1(kprintf(__FUNC__ "/%ld: Plugin=<%s> OpenCount=%ld\n", \ + __LINE__, ScalosPrefsPluginBase->lib_Node.ln_Name, ScalosPrefsPluginBase->lib_OpenCnt)); + + if (NULL == Group_Plugin) + CloseLibrary(ScalosPrefsPluginBase); + ScalosPrefsPluginBase = NULL; + } +} + +//---------------------------------------------------------------------------- + +static BOOL CheckMCCforPlugin(STRPTR *UsedClasses, size_t MaxUsedClasses) +{ + const struct MUIP_ScalosPrefs_MCCList *RequiredMccList = NULL; + + RequiredMccList = (const struct MUIP_ScalosPrefs_MCCList *) DoMethod(Group_Plugin, MUIM_ScalosPrefs_GetListOfMCCs); + + while (RequiredMccList && RequiredMccList->MccName) + { + if (!CheckMCCVersion(RequiredMccList->MccName, + RequiredMccList->MccMinVersion, + RequiredMccList->MccMinRevision)) + return FALSE; + + if (MaxUsedClasses > 1) + { + *UsedClasses++ = (STRPTR) RequiredMccList->MccName; + MaxUsedClasses--; + } + + RequiredMccList++; + } + + *UsedClasses = NULL; + + return TRUE; +} + +//---------------------------------------------------------------------------- + +// Checks if a certain version of a MCC is available +static BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev) +{ + BOOL flush = TRUE; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: %s ", name, __LINE__);) + + while (1) + { + ULONG ver = 0; + ULONG rev = 0; + struct Library *base; + char libname[256]; + + // First we attempt to acquire the version and revision through MUI + Object *obj = MUI_NewObject((STRPTR) name, TAG_DONE); + if (obj) + { + get(obj, MUIA_Version, &ver); + get(obj, MUIA_Revision, &rev); + + MUI_DisposeObject(obj); + + if(ver > minver || (ver == minver && rev >= minrev)) + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: v%ld.%ld found through MUIA_Version/Revision\n", __LINE__, ver, rev);) + return TRUE; + } + } + + // If we did't get the version we wanted, let's try to open the + // libraries ourselves and see what happens... + stccpy(libname, "PROGDIR:mui", sizeof(libname)); + AddPart(libname, name, sizeof(libname)); + + if ((base = OpenLibrary(&libname[8], 0)) || (base = OpenLibrary(&libname[0], 0))) + { + UWORD OpenCnt = base->lib_OpenCnt; + + ver = base->lib_Version; + rev = base->lib_Revision; + + CloseLibrary(base); + + // we add some additional check here so that eventual broken .mcc also have + // a chance to pass this test (i.e. Toolbar.mcc is broken) + if (ver > minver || (ver == minver && rev >= minrev)) + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: v%ld.%ld found through OpenLibrary()\n", __LINE__, ver, rev);) + return TRUE; + } + + if (OpenCnt > 1) + { + if (MUI_Request(NULL, NULL, 0L, GetLocString(MSGID_STARTUP_FAILURE), + GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), GetLocString(MSGID_STARTUP_MCC_IN_USE), + (ULONG) name, minver, minrev, ver, rev)) + { + flush = TRUE; + } + else + break; + } + + // Attempt to flush the library if open count is 0 or because the + // user wants to retry (meaning there's a chance that it's 0 now) + + if (flush) + { + struct Library *result; + + Forbid(); + if ((result = (struct Library *) FindName(&((struct ExecBase *)SysBase)->LibList, name))) + RemLibrary(result); + Permit(); + flush = FALSE; + } + else + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: couldn`t find minimum required version.\n", __LINE__);) + + // We're out of luck - open count is 0, we've tried to flush + // and still haven't got the version we want + if (MUI_Request(NULL, NULL, 0L, GetLocString(MSGID_STARTUP_FAILURE), + GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), GetLocString(MSGID_STARTUP_OLD_MCC), + (ULONG) name, minver, minrev, ver, rev)) + { + flush = TRUE; + } + else + break; + } + } + else + { + // No MCC at all - no need to attempt flush + flush = FALSE; + if (!MUI_Request(NULL, NULL, 0L, GetLocString(MSGID_STARTUP_FAILURE), + GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), GetLocString(MSGID_STARTUP_MCC_NOT_FOUND), + (ULONG) name, minver, minrev)) + { + break; + } + } + } + + return FALSE; +} + +//---------------------------------------------------------------------------- + +#if !defined(__SASC) && !defined(__amigaos4__) +// Replacement for SAS/C library functions + +#if !defined(__MORPHOS__) +// Replacement for SAS/C library functions + +size_t stccpy(char *dest, const char *src, size_t MaxLen) +{ + size_t Count = 0; + + while (*src && MaxLen > 1) + { + *dest++ = *src++; + MaxLen--; + Count++; + } + *dest = '\0'; + Count++; + + return Count; +} +#endif /*__MORPHOS__*/ + +#endif /* !defined(__SASC) && !defined(__amigaos4__) */ +//----------------------------------------------------------------------------- diff --git a/scalos/Prefs/FileTypes/ScalosFileTypes.cd b/scalos/Prefs/FileTypes/ScalosFileTypes.cd new file mode 100755 index 000000000..6da3b7d25 --- /dev/null +++ b/scalos/Prefs/FileTypes/ScalosFileTypes.cd @@ -0,0 +1,1164 @@ +; ScalosFileTypes.cd +; version $VER: ScalosFileTypes.catalog 40.23 (17 Oct 2009 15:25:39) +; codeset 0s +; language english +; +;#arrayopts static __far +; +; +MSGID_TITLENAME (//) +Scalos FileTypes Prefs Plugin +; +; +MSGID_SAVENAME (//) +Save +; +; +MSGID_USENAME (//) +Use +; +; +MSGID_CANCELNAME (//) +Cancel +; +;--------------------------------------------- +; +MSGID_MENU_PROJECT_OPEN (//) +Open... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT (/1/1) +O +; +; +MSGID_MENU_PROJECT_SAVEAS (//) +Save As... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT (/1/1) +A +; +; +MSGID_MENU_PROJECT_ABOUT (//) +About... +; +; +MSGID_MENU_PROJECT_QUIT (//) +Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT (/1/1) +Q +; +; +MSGID_MENU_PROJECT (//) +Project +; +; +MSGID_MENU_EDIT_LASTSAVED (//) +Last Saved +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT (/1/1) +L +; +; +MSGID_MENU_EDIT (//) +Edit +; +; +MSGID_MENU_SETTINGS_CREATEICONS (//) +Create Icons? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT (/1/1) +I +; +; +MSGID_MENU_SETTINGS (//) +Settings +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS (//) +Reset To Defaults +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT (/1/1) +D +; +; +MSGID_MENU_EDIT_RESTORE (//) +Restore +; +; +MSGID_MENU_EDIT_RESTORE_SHORT (/1/1) +R +; +; +MSGID_MENU_PROJECT_ABOUTMUI (//) +About MUI... +; +; +MSGID_MENU_EDIT_COLLAPSE (//) +Collapse selected +; +; +MSGID_MENU_EDIT_EXPAND (//) +Expand selected +; +; +MSGID_MENU_EDIT_COLLAPSEALL (//) +Collapse all +; +; +MSGID_MENU_EDIT_EXPANDALL (//) +Expand all +; +; +MSGID_MENU_EDIT_COPY (//) +Copy +; +; +MSGID_MENU_EDIT_CUT (//) +Cut +; +; +MSGID_MENU_EDIT_PASTE (//) +Paste +; +; +MSGID_MENU_HIDE_EMPTY_ENTRIES (//) +Hide empty entries? +; +; +MSGID_MENU_EDIT_FIND (//) +Find... +; +;--------------------------------------------- +; +MSGID_ABOUTREQOK (6000//) +_OK +; +; +MSGID_ABOUTREQFORMAT (//) +\33c\033bScalos FileTypes Preferences V%ld.%ld\033n\n\ +%s\n\ +© 1999%s The Scalos Team +; +; +MSGID_SHORTHELP_SAVEBUTTON (//) +Press this button to save \n\ +the current settings\n\ +and make changes permanent. +; +; +MSGID_SHORTHELP_USEBUTTON (//) +Press this button to save \n\ +the current settings\n\ +and keep settings until reboot. +; +; +MSGID_SHORTHELP_CANCELBUTTON (//) +Press this button to abort \n\ +and forget all changes. +; +; +MSGID_REQTITLE_SAVEERROR (//) +Error writing filetypes preferences\n\ +file \"%s\"\n\ +%s +; +; +MSGID_REQTITLE_READERROR (//) +Error reading filetypes preferences\n\ +file \"%s\"\n\ +%s +; +; +MSGID_PLUGIN_LIST_TITLE (//) +FileTypes +; +;--------------------------------------------- +; +MSGID_SPLASHWINDOW_LOADING_FILETYPES_PREFS (//) +\33c Loading FileTypes Prefs... +; +; +MSGID_SPLASHWINDOW_APPLYING_FILETYPES_PREFS (//) +\33c Applying FileTypes Prefs... +; +; +MSGID_SPLASHWINDOW_SAVING_FILETYPES_PREFS (//) +\33c Saving FileTypes Prefs... +; +;--------------------------------------------- +; +MSGID_ATTRCOLUMNTITLE_NAME (7000//) +Name +; +; +MSGID_ATTRCOLUMNTITLE_VALUE (//) +Value +; +;--------------------------------------------- +; +MSGID_BUTTON_ADD_ENTRY (8000//) +Add +; +MSGID_BUTTON_ADD_ENTRY_KEY (//) +A +; +; +MSGID_SHORTHELP_BUTTON_ADD_ENTRY (//) +Add new filetypes action entry.\n\ +Add a new entry for a filetype's popup menu or tooltip. +; +; +MSGID_BUTTON_DELETE_ENTRY (//) +Delete +; +; +MSGID_BUTTON_DELETE_ENTRY_KEY (//) +D +; +; +MSGID_SHORTHELP_BUTTON_DELETE_ENTRY (//) +Delete currently selected filetype's\n\ +popup menu or tooltip entry.\n\ +\033bNote: removing a list node also\n\ +deletes every subordinate node!\033n +; +; +MSGID_BUTTON_ADD_ATTRIBUTE (//) +Add +; +; +MSGID_BUTTON_ADD_ATTRIBUTE_KEY (//) + +; +; +MSGID_SHORTHELP_BUTTON_ADD_ATTRIBUTE (//) +Add Attribute for currently selected filetype's\n\ +popup menu or tooltip entry.\n\ +Attributes include an entry's name, font, or alignment. +; +; +MSGID_BUTTON_EDIT_ATTRIBUTE (//) +Edit +; +; +MSGID_SHORTHELP_BUTTON_EDIT_ATTRIBUTE (//) +Change value of a filetype's popup menu\n\ +or tooltip entry attribute. +; +; +MSGID_BUTTON_DELETE_ATTRIBUTE (//) +Remove +; +; +MSGID_BUTTON_DELETE_ATTRIBUTE_KEY (//) +R +; +; +MSGID_SHORTHELP_BUTTON_DELETE_ATTRIBUTE (//) +Remove currently selected filetype's popup menu\n\ +or tooltip entry attribute.\n\ +Note that not all attributes can be removed\n\ +from specific entries. +; +; new in 40.2 +; +MSGID_SHORTHELP_LAMP_CHANGED (//) +This lamp indicator changes from \033bOff\033n\n\ +to \033bOk\033n when the settings have been\n\ +modified since initial loading. +; +; +MSGID_BUTTON_CREATE_ICON (//) +Create New +; +; +MSGID_SHORTHELP_BUTTON_CREATE_ICON (//) +Create a new dedicated icon for this filetype. +; +; +MSGID_BUTTON_FIND_NEXT_SHORTHELP (+2//) +Find next filetype that matches the given search string. +; +; +MSGID_BUTTON_FIND_HIDE_SHORTHELP (//) +Hide Find Filetype Dialog. +; +; +MSGID_STRING_FIND_SHORTHELP (//) +This is the string to find in filetypes' name.\n\ +While you type, the first matching entry is always shown. +; +; +MSGID_BUTTON_FIND_PREV_SHORTHELP (//) +Find previous filetype that matches the given search string. +; +;--------------------------------------------- +; +MSGID_ENTRYTYPE_FILETYPE (9000//) +Filetype +; +; +MSGID_ENTRYTYPE_POPUPMENU (//) +Popup Menu +; +; +MSGID_ENTRYTYPE_SUBMENU (//) +SubMenu +; +; +MSGID_ENTRYTYPE_MENUITEM (//) +Menu Item +; +; +MSGID_ENTRYTYPE_INTERNALCMD (//) +Internal Command +; +; +MSGID_ENTRYTYPE_WBCMD (//) +Workbench Command +; +; +MSGID_ENTRYTYPE_AREXXCMD (//) +ARexx Command +; +; +MSGID_ENTRYTYPE_CLICMD (//) +CLI Command +; +; +MSGID_ENTRYTYPE_PLUGINCMD (//) +Menu Plugin Command +; +; +MSGID_ENTRYTYPE_ICONWINDOWCMD (//) +Icon Window Command +; +; +MSGID_ENTRYTYPE_MENUSEPARATOR (//) +\033C +; +; +MSGID_ENTRYTYPE_TOOLTIP (//) +Tooltip +; +; +MSGID_ENTRYTYPE_GROUP (//) +Group +; +; +MSGID_ENTRYTYPE_MEMBER (//) +Member +; +; +MSGID_ENTRYTYPE_HBAR (//) +Horizontal Bar +; +; +MSGID_ENTRYTYPE_STRING (//) +String +; +; +MSGID_ENTRYTYPE_SPACE (//) +Space +; +; +MSGID_ENTRYTYPE_DTIMAGE (//) +Datatypes Image +; +;--------------------------------------------- +; +MSGID_CHANGEME (10000//) +Change me +; +;--------------------------------------------- +; +MSGID_BUTTON_CHANGE_ATTRIBUTE (10100//) +Change +; +MSGID_SHORTHELP_BUTTON_CHANGE_ATTRIBUTE (//) +Commit changes to attribute and use changed values. +; +MSGID_BUTTON_KEEP_ATTRIBUTE (//) +Cancel +; +MSGID_SHORTHELP_BUTTON_KEEP_ATTRIBUTE (//) +Abort attribute changes and retain original values. +; +MSGID_EDITATTRIBUTE_WINDOWTITLE (//) +Edit Attribute Value +; +MSGID_EDITATTRIBUTE_TITLE (//) +Select new Value for Attribute +; +; +MSGID_EDITATTRIBUTE_TTFONT_ASLTITLE (//) +Select TrueType Font... +; +; +MSGID_EDITATTRIBUTE_TTFONT_ASL_OKBUTTON (//) +Ok +; +; +MSGID_EDITATTRIBUTE_TTFONT_ASL_CANCELBUTTON (//) +Cancel +; +; +MSGID_TTFONTSPAGE_SAMPLETEXT (//) +The quick brown fox jumps over the lazy dog +; +; +MSGID_TTFONTSPAGE_SCREENFONT_SAMPLETEXT_SHORTHELP (//) +This is an example text to visualize what the\n\ +selected TrueType screen font looks like. +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE (//) +Scalos Filetypes Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD (//) +Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_REGISTERTITLE_RECOGNITION (11000//) +Recognition +; +; +MSGID_REGISTERTITLE_ACTIONS (//) +Actions +; +;----------------------------------------------------------- +; +MSGID_BUTTON_ADD_FILETYPE (11100//) +Add +; +; +MSGID_SHORTHELP_BUTTON_ADD_FILETYPE (//) +Add a new entry with a filetypes description. +; +;----------------------------------------------------------- +; +MSGID_BUTTON_DELETE_FILETYPE (11200//) +Remove +; +; +MSGID_SHORTHELP_BUTTON_DELETE_FILETYPE (//) +Remove currently selected filetypes description.\n\ +\033bNote that removing a tree node deletes\n\ +all subordinate entries!\033n +; +; +MSGID_BUTTON_REMOVE_FILETYPEACTION (//) +Remove +; +; +MSGID_SHORTHELP_BUTTON_REMOVE_FILETYPEACTION (//) +Remove currently selected filetype identification action. +; +; +MSGID_BUTTON_ADD_FILETYPEACTION (//) +Add... +; +; +MSGID_SHORTHELP_BUTTON_ADD_FILETYPEACTION (//) +Add new filetype identification action. +; +; +MSGID_BUTTON_LEARN_FILETYPEACTION (//) +Learn... +; +; +MSGID_SHORTHELP_BUTTON_LEARN_FILETYPEACTION (//) +Learn about filetype by giving two or more example files. +; +; +MSGID_NEW_FILETYPE (//) +«new» +; +;----------------------------------------------------------- +; +MSGID_FILETYPE_ADD_ACTION_MATCH (11300//) +MATCH +; +; +MSGID_FILETYPE_ADD_ACTION_SEARCH (//) +SEARCH +; +; +MSGID_FILETYPE_ADD_ACTION_FILESIZE (//) +FILESIZE +; +; +MSGID_FILETYPE_ADD_ACTION_PATTERN (//) +PATTERN +; +; +MSGID_FILETYPE_ADD_ACTION_PROTECTION (//) +PROTECTION +; +; +MSGID_FILETYPE_ADD_ACTION_OR (//) +OR +; +; +MSGID_FILETYPE_ADD_ACTION_ISASCII (//) +ISASCII +; +; +MSGID_FILETYPE_ADD_ACTION_MACROCLASS (//) +MACROCLASS +; +; +MSGID_FILETYPE_ADD_ACTION_DOSDEVICE (//) +DOSDEVICE +; +; +MSGID_FILETYPE_ADD_ACTION_DEVICENAME (//) +DEVICENAME +; +; +MSGID_FILETYPE_ADD_ACTION_CONTENTS (//) +CONTENTS +; +; +MSGID_FILETYPE_ADD_ACTION_MINSIZEMB (//) +MINSIZE_MB +; +; +MSGID_FILETYPE_ADD_ACTION_DOSTYPE (//) +DOSTYPE +; +;----------------------------------------------------------- +; +MSGID_FILETYPEACTION_MATCH_OFFSET (11400//) +Offset: +; +; +MSGID_FILETYPEACTION_MATCH_CASE_SENSITIVE (//) +Case sensitive: +; +; +MSGID_FILETYPEACTION_MATCH_MATCH (//) +Match: +; +; +MSGID_FILETYPEACTION_SEARCH_SKIP_SPACES (//) +Skip spaces: +; +; +MSGID_FILETYPEACTION_SEARCH_CASE_SENSITIVE (//) +Case sensitive: +; +; +MSGID_FILETYPEACTION_SEARCH_SEARCH (//) +Search: +; +; +MSGID_FILETYPEACTION_FILESIZE_FILESIZE (//) +File size: +; +; +MSGID_FILETYPEACTION_PATTERN_PATTERN (//) +Pattern: +; +; +MSGID_FILETYPEACTION_PROTECTION_R (//) +R +; +; +MSGID_FILETYPEACTION_PROTECTION_W (//) +W +; +; +MSGID_FILETYPEACTION_PROTECTION_E (//) +E +; +; +MSGID_FILETYPEACTION_PROTECTION_D (//) +D +; +; +MSGID_FILETYPEACTION_PROTECTION_S (//) +S +; +; +MSGID_FILETYPEACTION_PROTECTION_P (//) +P +; +; +MSGID_FILETYPEACTION_PROTECTION_A (//) +A +; +; +MSGID_FILETYPEACTION_PROTECTION_H (//) +H +; +; +MSGID_GROUP_FILETYPES_FILETYPES (//) +Filetypes +; +; +MSGID_GROUP_FILETYPES_METHODS (//) +Methods +; +; +MSGID_FILETYPEACTION_MINSIZEMB_SIZE (//) +Minimum capacity in Megabytes: +; +; +MSGID_FILETYPEACTION_DOSDEVICE_PATTERN (//) +DOS device name pattern: +; +; +MSGID_FILETYPEACTION_DEVICENAME_PATTERN (//) +Device name pattern: +; +; +MSGID_FILETYPEACTION_CONTENTS_PATTERN (//) +Volume contents pattern: +; +; +MSGID_FILETYPEACTION_DOSTYPE_PATTERN (//) +DOS type match string: +; +;----------------------------------------------------------- +; +MSGID_FILETYPE_PROTECTION_SET (11500//) +Set +; +; +MSGID_FILETYPE_PROTECTION_UNSET (//) +Unset +; +; +MSGID_FILETYPE_PROTECTION_IGNORE (//) +Ignore +; +;----------------------------------------------------------- +; +MSGID_GROUP_FILETYPESACTION_MATCH (11600//) +MATCH attributes +; +; +MSGID_GROUP_FILETYPESACTION_SEARCH (//) +SEARCH attributes +; +; +MSGID_GROUP_FILETYPESACTION_FILESIZE (//) +FILESIZE attributes +; +; +MSGID_GROUP_FILETYPESACTION_PATTERN (//) +PATTERN attributes +; +; +MSGID_GROUP_FILETYPESACTION_PROTECTION (//) +PROTECTION attributes +; +; +MSGID_GROUP_FILETYPESACTION_MINSIZEMB (//) +MINSIZEMB attributes +; +; +MSGID_GROUP_FILETYPESACTION_DOSDEVICE (//) +DOSDEVICE attributes +; +; +MSGID_GROUP_FILETYPESACTION_DEVICENAME (//) +DEVICENAME attributes +; +; +MSGID_GROUP_FILETYPESACTION_CONTENTS (//) +CONTENTS attributes +; +; +MSGID_GROUP_FILETYPESACTION_DOSTYPE (//) +DOSTYPE attributes +; +;----------------------------------------------------------- +; +MSGID_FILETYPESACTION_CASE_SENSITIVE (11700//) + case sensitive +; +; +MSGID_FILETYPESACTION_SKIP_SPACES (//) + Skip spaces +; +; +MSGID_FILETYPESACTION_FILESIZE (//) +%u bytes +; +; +MSGID_FILETYPESACTION_PROTECTION_IGNORE (//) +- +; +; +MSGID_FILETYPESACTION_PROTECTION_R_SET (//) +R +; +; +MSGID_FILETYPESACTION_PROTECTION_R_CLEARED (//) +r +; +; +MSGID_FILETYPESACTION_PROTECTION_W_SET (//) +W +; +; +MSGID_FILETYPESACTION_PROTECTION_W_CLEARED (//) +w +; +; +MSGID_FILETYPESACTION_PROTECTION_E_SET (//) +E +; +; +MSGID_FILETYPESACTION_PROTECTION_E_CLEARED (//) +e +; +; +MSGID_FILETYPESACTION_PROTECTION_D_SET (//) +D +; +; +MSGID_FILETYPESACTION_PROTECTION_D_CLEARED (//) +d +; +; +MSGID_FILETYPESACTION_PROTECTION_H_SET (//) +H +; +; +MSGID_FILETYPESACTION_PROTECTION_H_CLEARED (//) +h +; +; +MSGID_FILETYPESACTION_PROTECTION_A_SET (//) +A +; +; +MSGID_FILETYPESACTION_PROTECTION_A_CLEARED (//) +a +; +; +MSGID_FILETYPESACTION_PROTECTION_S_SET (//) +S +; +; +MSGID_FILETYPESACTION_PROTECTION_S_CLEARED (//) +s +; +; +MSGID_FILETYPESACTION_PROTECTION_P_SET (//) +P +; +; +MSGID_FILETYPESACTION_PROTECTION_P_CLEARED (//) +p +; +; +MSGID_FILETYPESACTION_MINSIZEMB (//) +%u Megabytes +; +;----------------------------------------------------------- +; +MSGID_SHORTHELP_DEFAULTICON (11800//) +This shows the default icon found for the selected\n\ +filetype, and the associated name.\n\ +If no default icon is found for the specific filetype,\n\ +its parent is tried and so on, until as last\n\ +resort the default project icon is used. +; +; +MSGID_SHORTHELP_LISTVIEW_FILETYPES (//) +This list shows a hierarchic view of all defined filetypes. +; +; +MSGID_SHORTHELP_STRING_FILETYPES (//) +This is the name of the currently selected filetype.\n\ +The name is used to find an associated default icon,\n\ +i.e, for the name \"picture\", a default icon\n\ +named \"def_picture.info\" is being looked for. +; +; +MSGID_SHORTHELP_LISTVIEW_FILETYPE_ACTION (//) +This list shows the actions to identify the currently selected filetype.\n\ +The actions are processed sequentially from top to bottom,\n\ +and if all actions match, the file in question is\n\ +considered to be of this type. +; +; +MSGID_SHORTHELP_VIRTGROUP_FILETYPE_ACTION_ATTRIBUTES (//) +This area contains the attributes for the currently\n\ +selected filetypes identification action.\n\ +The available attributes vary depending on the\n\ +type of the selected identification action. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_MATCH_OFFSET (//) +This is the file offset where matching shall start. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_MATCH (//) +This is the string that filetype is being compared to.\n\ +Non-printable characters can be entered via their hexadecimal codes, e.g. \\\\x00. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_SEARCH (//) +This is the string the filetype is being searched for.\n\ +Non-printable characters can be entered via their hexadecimal codes, e.g. \\\\x00. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_FILESIZE (//) +This is the file size the filetype is checked for. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_PATTERN (//) +This is the file name pattern the filetype is being matched against.\n\ +You may use all standard DOS patterns like ? or #. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_R (//) +Select here whether the filetype needs to be readable,\n\ +or must not be readable, or if readability doesn't matter. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_W (//) +Select here whether the filetype needs to be writeable,\n\ +or must not be writeable, or if writeability doesn't matter. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_E (//) +Select here whether the filetype needs to be executable,\n\ +or must not be executable, or if executability doesn't matter. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_D (//) +Select here whether the filetype needs to be deleteable,\n\ +or must not be deleteable, or if deleteability doesn't matter. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_S (//) +Select here whether the filetype needs to be a script,\n\ +or must be no script, or if the script attribute doesn't matter. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_P (//) +Select here whether the filetype needs to be pure,\n\ +or must not be pure, or if the pure attribute doesn't matter. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_A (//) +Select here whether the filetype needs to be archived,\n\ +or must not be archived, or if archived state doesn't matter. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_H (//) +Select here whether the filetype needs to be hidden,\n\ +or must be visible, or if visibility doesn't matter. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_MINSIZEMB (//) +This is the mimimum volume capacity to checked for. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_DOSDEVICE (//) +This is the DOS device name (e.g. \"DH0\") for a volume. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_DEVICENAME (//) +This is the device name (e.g. \"scsi.device\") for a volume. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_CONTENTS (//) +This is a matching pattern for the contents of a volume. +; +; +MSGID_SHORTHELP_STRING_FILETYPEACTION_DOSTYPE (//) +This is the match string for the DOS type (e.g. \"SFS\\0\") of a volume.\n\ +Use hex notation like \"\\\\x1f\" for non-printable characters. +; +;----------------------------------------------------------- +; +MSGID_LEARN_OPEN (11900//) +Select two or more files to learn from +; +; +MSGID_SELECT_TWO_REQ_OK (//) +_Ok +; +; +MSGID_SELECT_TWO_REQ_CONTENTS (//) +You must select at least two sample files! +; +;----------------------------------------------------------- +; +MSGID_COM1NAME (12000//) +Backdrop +; +; +MSGID_COM2NAME (//) +Execute Command +; +; +MSGID_COM3NAME (//) +Redraw All +; +; +MSGID_COM4NAME (//) +Update All +; +; +MSGID_COM5NAME (//) +About Scalos +; +; +MSGID_COM6NAME (//) +Quit +; +; +MSGID_COM7NAME (//) +New Drawer +; +; +MSGID_COM8NAME (//) +Open Parent +; +; +MSGID_COM9NAME (//) +Close Window +; +; +MSGID_COM10NAME (//) +Update +; +; +MSGID_COM11NAME (//) +Select Contents +; +; +MSGID_COM12NAME (//) +Cleanup +; +; +MSGID_COM13NAME (//) +Snapshot - Window +; +; +MSGID_COM14NAME (//) +Snapshot - All +; +; +MSGID_COM15NAME (//) +Show - Only Icons +; +; +MSGID_COM16NAME (//) +Show - All Files +; +; +MSGID_COM17NAME (//) +View By - Icon +; +; +MSGID_COM18NAME (//) +View By - Name +; +; +MSGID_COM19NAME (//) +Open +; +; +MSGID_COM20NAME (//) +Reset Scalos +; +; +MSGID_COM21NAME (//) +Rename +; +; +MSGID_COM22NAME (//) +Information +; +; +MSGID_COM23NAME (//) +Snapshot +; +; +MSGID_COM24NAME (//) +UnSnapshot +; +; +MSGID_COM25NAME (//) +Leave Out +; +; +MSGID_COM26NAME (//) +Put Away +; +; +MSGID_COM27NAME (//) +Delete +; +; +MSGID_COM28NAME (//) +Clone +; +; +MSGID_COM29NAME (//) +Empty Trashcan +; +; +MSGID_COM30NAME (//) +Last Message +; +; +MSGID_COM31NAME (//) +Redraw +; +; +MSGID_COM32NAME (//) +Iconify +; +; +MSGID_COM33NAME (//) +Format Disk... +; +; +MSGID_COM34NAME (//) +Shutdown... +; +; +MSGID_COM35NAME (//) +Size To Fit +; +; +MSGID_COM36NAME (//) +Clear Selection +; +; +MSGID_COM37NAME (//) +View By - Size +; +; +MSGID_COM38NAME (//) +View By - Date +; +; +MSGID_COM39NAME (//) +Copy file +; +; +MSGID_COM40NAME (//) +Cut file +; +; +MSGID_COM41NAME (//) +Paste file +; +; +MSGID_COM42NAME (//) +View By - Type +; +; +MSGID_COM43NAME (//) +Cleanup By - Name +; +; +MSGID_COM44NAME (//) +Cleanup By - Date +; +; +MSGID_COM45NAME (//) +Cleanup By - Size +; +; +MSGID_COM46NAME (//) +Cleanup By - Type +; +; +MSGID_COM_ICONPROPERTIES (//) +Icon properties +; +; +MSGID_COM_WINDOWPROPERTIES (//) +Window properties +; +; +MSGID_COM47NAME (//) +View By - Default +; +; +MSGID_COM48NAME (//) +Show - Default +; +; +MSGID_COM49NAME (//) +Copy to... +; +; +MSGID_COM50NAME (//) +Move to... +; +; +MSGID_COM51NAME (//) +Create thumbnail +; +; +MSGID_COM_OPENNEWWINDOW (//) +Open in new window +; +; +MSGID_COM_THUMBNAILCACHECLEANUP (//) +Cleanup thumbnail cache +; +; +MSGID_COM_FIND (//) +Find File(s) +; +; +MSGID_COM_UNDO (//) +Undo +; +; +MSGID_COM_REDO (//) +Redo +; +; +MSGID_FIND_HITCOUNT_FMT (//) +%ld Hits +; +; +MSGID_COM_OPENBROWSERWINDOW (//) +Open in Browser Window +; +;--------------------------------------------- +; diff --git a/scalos/Prefs/FileTypes/Scalos_FileTypes.info b/scalos/Prefs/FileTypes/Scalos_FileTypes.info new file mode 100755 index 0000000000000000000000000000000000000000..c7e99b3be703b8acdca1b5ac947039474a9093b5 GIT binary patch literal 2577 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 MhXp!w8xWZP4Yszhy#N3J literal 0 HcwPel00001 diff --git a/scalos/Prefs/FileTypes/config.mk b/scalos/Prefs/FileTypes/config.mk new file mode 100755 index 000000000..a8c0b0b4d --- /dev/null +++ b/scalos/Prefs/FileTypes/config.mk @@ -0,0 +1,55 @@ +# $Date: 2011-08-06 19:37:48 +0200 (Sa, 06. Aug 2011) $ +# $Revision: 823 $ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +SCALOS_LOCALE = $(OBJDIR)/ScalosFileTypes_locale.h + +CFLAGS += -D SCALOSLOCALE=$(SCALOS_LOCALE) + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += # + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += # + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +LFLAGS += -lmui + + +else +############################################################################### +# AmigaOS + +LFLAGS += -lnix \ + -lnixmain \ + -lamiga21 \ + -lamiga \ + -lstubs + +endif +endif +endif diff --git a/scalos/Prefs/FileTypes/makefile b/scalos/Prefs/FileTypes/makefile new file mode 100644 index 000000000..fec4d5616 --- /dev/null +++ b/scalos/Prefs/FileTypes/makefile @@ -0,0 +1,132 @@ +# makefile for Scalos FileTypes preferences +# $Date$ +# $Revision$ +# using PhxAss andSAS/C + +############################################################# + +SUBDIRMAKE = $(MAKE) -s -C + +############################################################# + +.PHONY: clean install nodebug + +############################################################# + +SDPATH = / + +CC = sc +CFLAGS = nostkchk nochkabort strmer dbg=f nover streq data=far \ + define SCALOSLOCALE=$(SCALOS_LOCALE) \ + idlen=64 idir=//include +AS = phxass +AFLAGS = quiet noexe m=68020 opt=NRQB i=sc:Assembler_Headers/ +LD = slink +LDFLAGS = quiet batch noicons sd +LDLIBS = LIB:mempools.lib LIB:scm.lib LIB:sc.lib LIB:debug.lib LIB:amiga.lib +CSTARTUP = LIB:c.o +OBJDIR = .sasobj +CATCOMP = CatComp +FLEXCAT = FlexCat +SCALOS_LOCALE = $(OBJDIR)/ScalosFileTypes_locale.h + +############################################################# + +CSRCS = FileTypes.c + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(CSRCS:%.c=$(OBJDIR)/%.o) + +############################################################# + +NAME = .bin_os3/Scalos_FileTypes +DBGNAME = $(NAME).debug +DESTTOOL = Scalos:Prefs/Scalos FileTypes +CAT_FILE = Scalos/ScalosFileTypes.catalog +CATCOMPHEADER = $(SCALOS_LOCALE) +DESTCAT = Locale:Catalogs +CATS = deutsch \ + français + +ALLCATS = $(foreach cat,$(CATS),catalogs/$(cat)/$(CAT_FILE)) + +############################################################# + +# The default target (all) and what to really build +all: $(NAME) $(DBGNAME) allcatalogs +# install +# clean +# launch + +############################################################# + +$(CATCOMPHEADER) : ScalosFileTypes.cd + @printf '\033[32mCatcomp header: \033[31m\033[1m$@ \033[32mfrom \033[31m$<\033[0m\n' + $(FLEXCAT) $(subst ../,/,$<) $@=$(SDPATH)/CatComp_h.sd + +############################################################# + +$(OBJDIR)/FileTypes.o : FileTypes.c $(SCALOS_LOCALE) + +# CLI command used when linking the final executables +$(NAME) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LDLIBS) $(LDFLAGS) STRIPDEBUG + + +$(DBGNAME) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LDLIBS) $(LDFLAGS) ADDSYM + +############################################################# + +# commands generated a catalog (.catalog) from a catalog translation (.ct) file. +.ct.catalog: + $(CATCOMP) $*.cd $< CATALOG $*.catalog VB=1 + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $*.c objectname $@ + +$(OBJDIR)/%.o : %.s + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +$(OBJDIR)/%.o : %.asm + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +############################################################# + +# copy all generated file to their final destinations +install: + @printf '\033[32mInstall: \033[31m\033[1m$(DESTTOOL)\033[0m\n' + @copy $(NAME) "$(DESTTOOL)" clone + @printf '\033[32mInstall: \033[31m\033[1m$(CAT_FILE) \033[0m\n' + -@$(foreach cat,$(CATS),copy "catalogs/$(cat)/$(CAT_FILE)" "$(DESTCAT)/$(cat)/Scalos" clone;) + + +############################################################# + +# make all Scalos preferences .catalogs +allcatalogs: + -@$(foreach cat,$(CATS),$(SUBDIRMAKE) catalogs/$(cat)/Scalos;) + +############################################################# + +# A little something to clean it all up +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + @delete $(OBJS) $(NAME) $(DBGNAME) $(ALLCATS) $(CATCOMPHEADER) + @printf '\033[0m' + +############################################################# + +nodebug: + -@$(SPLAT) -s -o "d2(" "d1(" "#?.c" + +############################################################# diff --git a/scalos/Prefs/FileTypes/makefile-new b/scalos/Prefs/FileTypes/makefile-new new file mode 100755 index 000000000..5d2bfa5ee --- /dev/null +++ b/scalos/Prefs/FileTypes/makefile-new @@ -0,0 +1,96 @@ +# $Date: 2011-08-06 19:37:48 +0200 (Sa, 06. Aug 2011) $ +# $Revision: 823 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../.. +endif + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + SDPATH=/ +else + SDPATH=../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(OBJDIR)/FileTypes.o + + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Subdirs +# + +SUBDIRS = $(filter-out Catalogs/sample/Scalos, $(wildcard Catalogs/*/Scalos)) + +############################################################################## +# +# Some lame deps + +$(OBJDIR)/FileTypes.o $(OBJDIR)/FileTypes.d : $(OBJDIR)/ScalosFileTypes_locale.h + +$(OBJDIR)/ScalosFileTypes_locale.h : ScalosFileTypes.cd + @$(ECHO) "FlexCat $@" + $(FLEXCAT) $< $@=$(SDPATH)/CatComp_h.sd + +############################################################################## +# +# Targets +# + +NAME = Scalos_FileTypes +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) \ + all_subdirs + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + @$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) "Scalos:Prefs/Scalos FileTypes" clone + +install: install_subdirs + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* \ + $(OBJDIR)/ScalosFileTypes_locale.h + +clean: clean_subdirs + +############################################################################## + + diff --git a/scalos/Prefs/MainPrefs/Catalogs/deutsch/Scalos/Makefile b/scalos/Prefs/MainPrefs/Catalogs/deutsch/Scalos/Makefile new file mode 100644 index 000000000..564d53428 --- /dev/null +++ b/scalos/Prefs/MainPrefs/Catalogs/deutsch/Scalos/Makefile @@ -0,0 +1,13 @@ +# makefile for Scalos_Prefs (translated Texts : deutsch) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mdeutsch\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +Scalos_Prefs.catalog : Scalos_Prefs.ct ../../../Scalos_Prefs.cd + +All: Scalos_Prefs.catalog diff --git a/scalos/Prefs/MainPrefs/Catalogs/deutsch/Scalos/Scalos_Prefs.ct b/scalos/Prefs/MainPrefs/Catalogs/deutsch/Scalos/Scalos_Prefs.ct new file mode 100644 index 000000000..5a9749c8d --- /dev/null +++ b/scalos/Prefs/MainPrefs/Catalogs/deutsch/Scalos/Scalos_Prefs.ct @@ -0,0 +1,4212 @@ +; ScalosPrefs.ct +; $Date$ +; $Revision$ +; +## version $VER: Scalos_Prefs.catalog 40.28 (28 Mar 2010 19:20:49) +## codeset 0 +## language deutsch +; +;#arrayopts static const __far +; +;----------------------------------------------------------- +; +MSGID_MENU_PROJECT_OPEN +Öffnen... +;Open... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +O +; +; +MSGID_MENU_PROJECT_OPEN_ASLTITLE +Scalos Einstellungen öffnen... +;Open Scalos Prefs... +; +; +MSGID_MENU_PROJECT_SAVEAS +Speichern als... +;Save As... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +A +; +; +MSGID_MENU_PROJECT_SAVEAS_ASLTITLE +Scalos Einstellungen speichern als... +;Save Scalos Prefs As... +; +; +MSGID_MENU_PROJECT_ABOUT +Über... +;About... +; +; +MSGID_MENU_PROJECT_QUIT +Beenden +;Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +; +MSGID_MENU_PROJECT +Projekt +;Project +; +; +MSGID_MENU_EDIT_LASTSAVED +auf zuletzt gespeichertes +;Last Saved +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +L +; +; +MSGID_MENU_EDIT +Verändern +;Edit +; +; +MSGID_MENU_SETTINGS_CREATEICONS +Piktogramme erzeugen? +;Create Icons? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +I +; +; +MSGID_MENU_SETTINGS +Einstellungen +;Settings +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +auf Vorgaben zurücksetzen +;Reset To Defaults +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +D +; +; +MSGID_MENU_EDIT_RESTORE +auf vorherigen Stand +;Restore +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +R +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Über MUI... +;About MUI... +; +; +MSGID_MENU_PROJECT_ABOUTMORPHOS +Über MorphOS... +;About MorphOS... +; +;----------------------------------------------------------- +; +MSGID_FILEDISP_COLUMN_NAME +Name +; +; +MSGID_FILEDISP_COLUMN_SIZE +Größe +; +; +MSGID_FILEDISP_COLUMN_PROT +Zugriff +;Protection bits +; +; +MSGID_FILEDISP_COLUMN_DATE +Datum +;Date +; +; +MSGID_FILEDISP_COLUMN_TIME +Zeit +;Time +; +; +MSGID_FILEDISP_COLUMN_COMMENT +Kommentar +; +; +MSGID_FILEDISP_COLUMN_VERSION +Version +; +; +MSGID_FILEDISP_COLUMN_FILETYPE +Dateityp +;Filetype +; +; +MSGID_FILEDISP_COLUMN_OWNER +Besitzer +;Owner +; +; +MSGID_FILEDISP_COLUMN_GROUP +Gruppe +;Group +; +; +MSGID_FILEDISP_COLUMN_ICON +Piktogramm +;Icon +; +;----------------------------------------------------------- +; +MSGID_PRECISION_EXACT +Genau +;Exact +; +; +MSGID_PRECISION_IMAGE +Foto +;Image +; +; +MSGID_PRECISION_ICON +Piktogramm +;Icon +; +; +MSGID_PRECISION_GUI +GUI +; +;----------------------------------------------------------- +; +MSGID_THUMBNAILS_LIFETIME_FOREVER +niemals +;never +; +;----------------------------------------------------------- +; +MSGID_PREFGROUPS_SHORTHELP +Wählen Sie eine der angebotenen Kategorien\n\ +der Einstellungen von Scalos aus. +;Select one of the preferences categories +; +; +MSGID_PREFGROUPS_ABOUT +Über Scalos +;About Scalos +; +; +MSGID_PREFGROUPS_PATHS +Pfade +;Paths +; +; +MSGID_PREFGROUPS_STARTUP +Systemstart +;Startup +; +; +MSGID_PREFGROUPS_DESKTOP +Arbeitsfläche +;Desktop +; +; +MSGID_PREFGROUPS_ICONS +Piktogramme +;Icons +; +; +MSGID_PREFGROUPS_WINDOWS +Fenster +;Windows +; +; +MSGID_PREFGROUPS_MISC +Vermischtes +;Miscellaneous +; +; +MSGID_PREFGROUPS_PLUGINS +Erweiterungen +;Plugins +; +; +MSGID_PREFGROUPS_MODULES +Module +;Modules +; +; +MSGID_PREFGROUPS_DRAGNDROP +Ziehen/Ablegen +;Drag and Drop +; +; +MSGID_PREFGROUPS_TRUETYPEFONTS +TrueType Schriften +;TrueType Fonts +; +; +MSGID_PREFGROUPS_TEXTWINDOWS +Textfenster +;Text Windows +; +;----------------------------------------------------------- +; +MSGID_DESKTOPPAGES_SCREEN +Bildschirm +;Screen +; +; +MSGID_DESKTOPPAGES_ICONS +Piktogramme +;Icons +; +; +MSGID_ICONPAGES_MISC +Vermischtes +;Miscellaneous +; +; +MSGID_DESKTOPPAGES_LAYOUT +Layout +;Layout +; +;----------------------------------------------------------- +; +MSGID_ICONPAGES_BORDERS +Rahmen +;Borders +; +; +MSGID_ICONPAGES_LABELS +Beschriftung +;Labels +; +; +MSGID_ICONPAGES_ATRIBUTES +Eigenschaften +;Attributes +; +; +MSGID_ICONPAGES_TOOLTIPS +Tooltips +;Tooltips +; +; +MSGID_ICONPAGES_THUMBNAILS +Miniaturansicht +;Thumbnails +; +; +MSGID_ICONPAGES_SIZES +Größen +; +;----------------------------------------------------------- +; +MSGID_TITLEPLACEHOLDER_KICKSTART_RELEASE +%os|Kickstart Ausgabe (z.B. 3.1) +;%os|Kickstart release (e.g. 3.1) +; +; +MSGID_TITLEPLACEHOLDER_KICKSTART_VERSION +%ov|Kickstart Version (z.B. 40.68) +;%ov|Kickstart version (e.g. 40.68) +; +; +MSGID_TITLEPLACEHOLDER_SCALOS_RELEASE +%wb|Scalos Ausgabe (z.B.. 1.2d) +;%wb|Scalos release (e.g. 1.2d) +; +; +MSGID_TITLEPLACEHOLDER_SCALOS_VERSION +%wv|Scalos Version (z.B. 39.220) +;%wv|Scalos version (e.g. 39.220) +; +; +MSGID_TITLEPLACEHOLDER_FREE_CHIP_MEM +%fc|Freies Chip-RAM in Byte +;%fc|Free chip RAM in bytes +; +; +MSGID_TITLEPLACEHOLDER_FREE_FAST_MEM +%ff|Freies Fast-RAM in Byte +;%ff|Free fast RAM in bytes +; +; +MSGID_TITLEPLACEHOLDER_FREE_MEM +%ft|Gesamtes freies RAM in Byte +;%ft|Total free RAM in bytes +; +; +MSGID_TITLEPLACEHOLDER_WINDOW_PATH +%pa|Pfad dieses Fensters +;%pa|Windows directory path +; +; +MSGID_TITLEPLACEHOLDER_DISK_FREE +%df|Freier Platz auf Disk +;%df|Free disk space +; +; +MSGID_TITLEPLACEHOLDER_DISK_FREE_DIVIDE +%DF|Freier Platz auf Disk (in GByte/MByte) +;%DF|Free disk space (auto divide) +; +; +MSGID_TITLEPLACEHOLDER_DISK_USED +%du|Belegter Platz auf Disk +;%du|Used disk space +; +; +MSGID_TITLEPLACEHOLDER_DISK_USED_DIVIDE +%DU|Belegter Platz auf Disk (in GBytes/MByte) +;%DU|Used disk space (auto divide) +; +; +MSGID_TITLEPLACEHOLDER_START_NODISK +%d(|Beginn: unsichtbar wenn keine Diskette eingelegt +;%d(|Start: don't show if no disk inserted +; +; +MSGID_TITLEPLACEHOLDER_STOP_NODISK +%d)|Ende: unsichtbar wenn keine Diskette eingelegt +;%d)|Stop: don't show if no disk inserted +; +; +MSGID_TITLEPLACEHOLDER_DISK_PERCENT +%dp|Prozent belegter Diskettenplatz +;%dp|Percent of used disk space +; +; +MSGID_TITLEPLACEHOLDER_GFXCHIPS +%cs|Graphik-Chipsatz (z.B. AGA) +;%cs|Graphics chip set (e.g. AGA) +; +; +MSGID_TITLEPLACEHOLDER_CPU +%pr|68k Prozessor +;%pr|68k processor +; +; +MSGID_TITLEPLACEHOLDER_FPU +%cp|68k Koprozessor (FPU) +;%cp|68k co-processor (FPU) +; +; +MSGID_TITLEPLACEHOLDER_TASKS +%nt|Anzahl Tasks +;%nt|Number of tasks +; +; +MSGID_TITLEPLACEHOLDER_LIBRARIES +%nl|Anzahl Bibliotheken +;%nl|Number of libraries +; +; +MSGID_TITLEPLACEHOLDER_PORTS +%np|Anzahl Ports +;%np|Number of ports +; +; +MSGID_TITLEPLACEHOLDER_DEVICES +%nd|Anzahl Geräte +;%nd|Number of devices +; +; +MSGID_TITLEPLACEHOLDER_SCREENS +%ns|Anzahl Bildschirme +;%ns|Number of screens +; +; +;----------------------------------------------------------- +; +MSGID_WINDOWPAGES_GENERAL +Allgemein +;General +; +; +MSGID_WINDOWPAGES_SIZE +Standardgrößen +;Size +; +; +MSGID_WINDOWPAGES_LAYOUT +Layout +;Layout +; +; +MSGID_WINDOWPAGES_CONTROLBAR +Steuerleiste +;Control Bar +; +; +MSGID_WINDOWPAGES_CONTROLBAR_BROWSER +Steuerleiste für Browserfenser +;Browser Window Control Bar +; +; +MSGID_WINDOWPAGES_CONTROLBAR_NORMAL +Steuerleiste für normale Fenster +;Standard Window Control Bar +; +;----------------------------------------------------------- +; +MSGID_TEXTWINDOWPAGES_FONTS +Schrift +;Fonts +; +; +MSGID_TEXTWINDOWPAGES_COLUMNS +Angezeigte Spalten +;Columns +; +; +MSGID_TEXTWINDOWPAGES_SELECTIONMARKS +Auswahlmarkierung +;Selection marks +; +; +MSGID_TEXTWINDOWPAGES_MISC +Verschiedenes +;Miscellaneous +; +;----------------------------------------------------------- +; +MSGID_CREATELINKS_HARDLINKS +Feste Verknüpfungen +; +; +MSGID_CREATELINKS_SOFTLINKS +Weiche Verknüpfungen +; +;----------------------------------------------------------- +; +MSGID_WINDOWREFRESH_SIMPLE +Einfaches Neuzeichnen +;Simple Refresh +; +; +MSGID_WINDOWREFRESH_SMART +Intelligentes Neuzeichnen +;Smart Refresh +; +;----------------------------------------------------------- +; +MSGID_WINDOW_SHOWALL_DEFAULT_ICONS +Nur Piktogramme anzeigen +;Show - Only Icons +; +; +MSGID_WINDOW_SHOWALL_DEFAULT_ALL +Alle Dateien anzeigen +;Show - All Files +; +;----------------------------------------------------------- +; +MSGID_WINDOW_VIEWBY_DEFAULT_ICON +Inhalt anzeigen als Piktogramm +;View By - Icon +; +; +MSGID_WINDOW_VIEWBY_DEFAULT_NAME +Inhalt auflisten nach Name +;View By - Name +; +; +MSGID_WINDOW_VIEWBY_DEFAULT_SIZE +Inhalt auflisten nach Größe +;View By - Size +; +; +MSGID_WINDOW_VIEWBY_DEFAULT_DATE +Inhalt auflisten nach Datum +;View By - Date +; +; +MSGID_WINDOW_VIEWBY_DEFAULT_TIME +Inhalt auflisten nach Uhrzeit +;View By - Time +; +; +MSGID_WINDOW_VIEWBY_DEFAULT_COMMENT +Inhalt auflisten nach Kommentar +;View By - Comment +; +; +MSGID_WINDOW_VIEWBY_DEFAULT_PROTECTION +Inhalt auflisten nach Schutz +;View By - Comment +; +; +MGSID_WINDOW_VIEWBY_DEFAULT_OWNER +Inhalt auflisten nach Besitzer +;View By - Owner +; +; +MSGID_WINDOW_VIEWBY_DEFAULT_GROUP +Inhalt auflisten nach Gruppe +;View By - Group +; +;----------------------------------------------------------- +; +MSGID_FILEDISPLAYPAGES_TEXT +Text +;Text +; +;----------------------------------------------------------- +; +MSGID_ICONLAYOUT_COLUMNS +Spaltenweise (Oben nach unten, dann links nach rechts) +;Columns (top-down, then left-to-right) +; +; +MSGID_ICONLAYOUT_ROWS +Zeilenweise (links nach rechts, dann oben nach unten) +;Rows (left-to-right, then top-down) +; +;----------------------------------------------------------- +; +MSGID_ICONLABELSTYLES_NORMAL +Normal +; +; +MSGID_ICONLABELSTYLES_OUTLINE +Umriß +;Outline +; +; +MSGID_ICONLABELSTYLES_SHADOW +Schatten +;Shadow +; +;----------------------------------------------------------- +; +MSGID_ICONSIZES_16x16 +16 x 16 +;16 x 16 +; +; +MSGID_ICONSIZES_24x24 +24 x 24 +;24 x 24 +; +; +MSGID_ICONSIZES_32x32 +32 x 32 +;32 x 32 +; +; +MSGID_ICONSIZES_48x48 +48 x 48 +;48 x 48 +; +; +MSGID_ICONSIZES_64x64 +64 x 64 +;64 x 64 +; +; +MSGID_ICONSIZES_96x96 +96 x 96 +;96 x 96 +; +; +MSGID_ICONSIZES_128x128 +128 x 128 +;128 x 128 +; +; +MSGID_ICONSIZES_UNLIMITED +unbegrenzt +;unlimited +; +;----------------------------------------------------------- +; +MSGID_ICONDRAGSTYLES_IMAGEONLY +Nur Bild +;Image Only +; +; +MSGID_ICONDRAGSTYLES_IMAGEANDTEXT +Bild & Schrift +;Image & Text +; +;----------------------------------------------------------- +; +MSGID_THUMBNAILSIZES_16x16 +16 x 16 +;16 x 16 +; +; +MSGID_THUMBNAILSIZES_24x24 +24 x 24 +;16 x 16 +; +; +MSGID_THUMBNAILSIZES_32x32 +32 x 32 +;32 x 32 +; +; +MSGID_THUMBNAILSIZES_48x48 +48 x 48 +;48 x 48 +; +; +MSGID_THUMBNAILSIZES_64x64 +64 x 64 +;64 x 64 +; +; +MSGID_THUMBNAILSIZES_96x96 +96 x 96 +;96 x 96 +; +; +MSGID_THUMBNAILSIZES_128x128 +128 x 128 +;128 x 128 +; +;----------------------------------------------------------- +; +MSGID_ICONDRAGTRANSPARENCY_GHOSTED +Schattiert +;Ghosted +; +; +MSGID_ICONDRAGTRANSPARENCY_TRANSPARENT +Schattiert/Echt transparent +;Ghosted/Real Transparent +; +;----------------------------------------------------------- +; +MSGID_SHOWTHUMBNAILS_NEVER +Niemals +;Never +; +; +MSGID_SHOWTHUMBNAILS_AS_DEFAULT +Für Standardpiktogr. +;As default +; +; +MSGID_SHOWTHUMBNAILS_ALWAYS +Immer +;Always +; +;----------------------------------------------------------- +; +MSGID_ICONDRAGTROUTINES_SYSTEM +System +; +; +MSGID_ICONDRAGTROUTINES_CUSTOM +Spezial +;Custom +; +;----------------------------------------------------------- +; +MSGID_ICONDROPMARK_NEVER +Nie anzeigen +;Never show +; +; +MSGID_ICONDROPMARK_ALWAYS +Immer zeigen +;Always +; +; +MSGID_ICONDROPMARK_DRAWERSONLY +Nur in Schubladen-Fenstern +;Only in drawer windows +; +;----------------------------------------------------------- +; +MSGID_ICONDRAGLOOK_TRANSP_SOLID +Piktogramme \033bTransparent\033n beim Ziehen, \033bundurchsichtig\033n über Auslösern +;\033bTransparent\033n when dragging, \033bsolid\033n over triggers +; +; +MSGID_ICONDRAGLOOK_ALWAYS_SOLID +Piktogramme beim Ziehen immer \033bundurchsichtig\033n +;Always \033bsolid\033n icons when dragging +; +; +MSGID_ICONDRAGLOOK_ALWAYS_TRANSP +Piktogramme immer \033btransparent\033n beim Ziehen +;Always \033btransparent\033n icons when dragging +; +; +MSGID_ICONDRAGLOOK_SOLID_TRANSP +\033bUndurchsichtig\033n beim Ziehen, \033btransparent\033n über Auslösern +;\033bSolid\033n when dragging, \033btransparent\033n over triggers +; +;----------------------------------------------------------- +; +MSGID_VERSIONSTRING +Scalos Version %s (%d.%d) (Build %s) +;Scalos Version %s (%d.%d) (Build %s) +; +; +MSGID_COPYRIGHTSTRING +®2003%s Das Scalos-Team +;®2003%s The Scalos Team +; +; +MSGID_SPLASHWINDOW_LOADINGPREFS +\33c Scalos Voreinsteller wird geladen... +;\33c Loading Scalos Prefs... +; +; +MSGID_SPLASHWINDOW_APPLYINGPREFS +\33c Scalos Einstellungen anwenden... +;\33c Applying Scalos Prefs... +; +; +MSGID_SPLASHWINDOW_SAVINGPREFS +\33c Scalos Einstellungen werden gespeichert... +;\33c Saving Scalos Prefs... +; +;----------------------------------------------------------- +; +MSGID_ABOUTPAGE_COPYRIGHT +\033c\033bCopyright ©2003%s Das Scalos-Team +;\033c\033bCopyright ©2003%s The Scalos Team +; +; +MSGID_ABOUTPAGE_CONTACT1 +Sie erreichen uns mit email < +;contact us by email < +; +; +MSGID_ABOUTPAGE_CONTACT2 +> // web < +; +; +MSGID_ABOUTPAGE_CONTACT3 +> +; +; +MSGID_ABOUTPAGE_PREFSVERSION +Scalos Voreinsteller V%ld.%ld +;Scalos Main Preferences V%ld.%ld +; +;----------------------------------------------------------- +; +MSGID_PATHSPAGE_DEFAULTPATHS +Standardpfade +;Default Paths +; +; +MSGID_PATHSPAGE_SCALOS_HOME +Scalos Heimverzeichnis: +;Scalos Home: +; +; +MSGID_PATHSPAGE_SCALOS_HOME_ASLTITLE +Bitte wählen Sie ein Verzeichnis... +;Please select a drawer... +; +; +MSGID_PATHSPAGE_SCALOS_HOME_SHORTHELP +Eine Zuweisung SCALOS: wird\n\ +auf dieses Verzeichnis zeigen +;An assign called SCALOS:\n\ +;will point to this directory +; +; +MSGID_PATHSPAGE_THEMES +Themen: +;Themes: +; +; +MSGID_PATHSPAGE_THEMES_SHORTHELP +In diesem Verzeichnis liegen\n\ +alle Thema-spezifischen Dateien. +;This is the drawer where all the\n\ +;theme-specific files are located. +; +; +MSGID_PATHSPAGE_THEMES_ASLTITLE +Bitte wählen Sie ein Verzeichnis... +;Please select a drawer... +; +; +MSGID_PATHSPAGE_DEFAULTICONS +Standardpiktogramme: +;Default Icons: +; +; +MSGID_PATHSPAGE_DEFAULTICONS_SHORTHELP +In diesem Verzeichnis sucht Scalos\n\ +nach den Standardpiktogrammen. +;This is the drawer where Scalos\n\ +;looks for default icons. +; +; +MSGID_PATHSPAGE_DEFAULTICONS_ASLTITLE +Bitte wählen Sie ein Verzeichnis... +;Please select a drawer... +; +; +MSGID_PATHSPAGE_WBSTARTUP +WBStartup: +; +; +MSGID_PATHSPAGE_WBSTARTUP_SHORTHELP +Dieses Verzeichnis dient als WBStartup, d.h.\n\ +jedes Program darin wird beim Start\n\ +von Scalos ausgeführt. +;This drawer is used as WBStartup, i.e. any program\n\ +;located inside is executed upon Scalos startup. +; +; +MSGID_PATHSPAGE_WBSTARTUP_ASLTITLE +Bitte wählen Sie ein Verzeichnis... +;Please select a drawer... +; +; +MSGID_PATHSPAGE_DISKCOPY +DiskCopy: +; +; +MSGID_PATHSPAGE_DISKCOPY_SHORTHELP +Dies ist der vollständige Pfadname für\n\ +das Betriebssystemprogram \"Diskcopy\". +;This is the complete file name for\n\ +;the \"Diskcopy\" system program. +; +; +MSGID_PATHSPAGE_DISKCOPY_ASLTITLE +Bitte wählen Sie ein Verzeichnis... +;Please select a drawer... +; +; +MSGID_PATHSPAGE_FORMAT +Format: +; +; +MSGID_PATHSPAGE_FORMAT_SHORTHELP +Dies ist der vollständige Pfadname für\n\ +das Betriebssystemprogram \"Format\". +;This is the complete file name for\n\ +;the \"Format\" system program. +; +; +MSGID_PATHSPAGE_FORMAT_ASLTITLE +Bitte wählen Sie ein Verzeichnis... +;Please select a drawer... +; +; +MSGID_PATHSPAGE_THUMBNAILDB +Speicher für Miniaturansichten +;Thumbnail cache file +; +; +MSGID_PATHSPAGE_THUMBNAILDB_ASLTITLE +Bitte wählen Sie eine Datei... +;Please select thumbnail cache location... +; +; +MSGID_PATHSPAGE_THUMBNAILDB_SHORTHELP +Scalos benutzt eine Datenbank in einer Datei, \ +um Miniaturansichten zur schnelleren Anzeige zwischenzuspeichern.\n\ +Diese Datei erreicht schnell eine Größe von etlichen Megabytes.\n\ +Wählen Sie hier einen Platz aus, wo die Datei angelegt wird. +;Scalos uses a database file to cache thumbnail icon images.\n\ +;This file easily grows to several megabytes.\n\ +;Select here a place where this file should be kept. +; +; +MSGID_PATHSPAGE_IMAGECACHE +Speicher für Bilder: +;Image Cache: +; +; +MSGID_PATHSPAGE_IMAGECACHE_SHORTHELP +Scalos benutzt dieses Verzeichnis als Zwischenspeicher für Datatypes Bilder.\n\ +Da Datatypes benutzte Bilder gegen Überschreiben sperrt,\n\ +erzeugt Scalos für alle Bilder, die es benutzt, eine\n\ +temporäre Kopie in diesem Verzeichnis. +;This drawer is used to cache the datatypes images used by Scalos.\n\ +;Since datatypes prevents images from being updated,\n\ +;Scalos creates cached copies of the images used. +; +; +MSGID_PATHSPAGE_IMAGECACHE_ASLTITLE +Bitte wählen Sie ein Verzeichnis... +;Please select a drawer... +; +; +MSGID_PATHSPAGE_SQLITE3TEMPPATH +Verzeichnis für Hilfsdateien der Miniaturansichten: +;Thumbnail Database Temporary Files: +; +; +MSGID_PATHSPAGE_SQLITE3TEMPPATH_SHORTHELP +Dieses Verzeichnis wird von der Miniaturansichten-Datenbank\n\ +zum Zwischenspeichern temporärer Dateien genutzt. +;This drawer is used to store any temporary\n\ +;files for internal use by the thumbnail database. +; +; +MSGID_PATHSPAGE_SQLITE3TEMPPATH_ASLTITLE +Bitte wählen Sie ein Verzeichnis... +;Please select thumbnail cache temporary files location... +; +;----------------------------------------------------------- +; +MSGID_STARTUPPAGE_SPLASHWINDOW +Splash-Fenster +;Splash Window +; +; +MSGID_STARTUPPAGE_SHOWSPLASHWINDOW +Splash-Fenster anzeigen: +;Show splash window: +; +; +MSGID_STARTUPPAGE_SHOWSPLASHWINDOW_SHORTHELP +Hier entscheiden Sie, ob das Splash-Fenster\n\ +bei jedem Start von Scalos angezeigt werden soll. +;Enable this checkbox to display the\n\ +;splash window upon every Scalos startup. +; +; +MSGID_STARTUPPAGE_SPLASHCLOSEDELAY +Splash Haltezeit: +;Splash close delay: +; +; +MSGID_STARTUPPAGE_SPLASHCLOSEDELAY_SHORTHELP +Geben Sie hier an, wie lange das\n\ +Splash-Fenster nach dem Erscheinen\n\ +der letzten Meldung geöffnet bleibt. +;Specify here how long the Scalos splash window\n\ +;will stay open after the last startup message\n\ +;has been displayed. +; +; +MSGID_STARTUPPAGE_WBSTARTUP +WBStartup +; +; +MSGID_STARTUPPAGE_DOWAITDELAY +DoWait Wartezeit: +;DoWait delay +; +; +MSGID_STARTUPPAGE_DOWAITDELAY_SHORTHELP +Wenn ein Programm im \"WBStartup\" Verzeichnis\n\ +nicht innerhalb der spezifizierten Zeit beendet\n\ +wird, wird ein Dialogfenster angezeigt, das die\n\ +Möglichkeit anbietet, den Wartevorgang abzubrechen. +;If a tool in the WBStartup drawer doesn't\n\ +;finish within the specified delay a requester will be\n\ +;presented to choose wether to stop waiting. +; +; +MSGID_STARTUPPAGE_DOWAITDELAY_SECONDS +Sekunden +;seconds +; +;----------------------------------------------------------- +; +MSGID_DESKTOPPAGE_SCREENTITLEBAR +Bildschirm +;Screen +; +; +MSGID_DESKTOPPAGE_SCREEN +Titel +;Title +; +; +MSGID_DESKTOPPAGE_SCREEN_DESCRIPTION +|\033b\0338Beschreibung +;|\033b\0338Description +; +; +MSGID_DESKTOPPAGE_TITLEBAR_REFRESH +Anzeigerate Titel: +;Titlebar refresh rate: +; +; +MSGID_DESKTOPPAGE_TITLEBAR_REFRESH_SHORTHELP +Dies ist das Zeitintervall, in dem der\n\ +Bildschirmtitelbalken aktualisiert wird. +;This is the time interval between\n\ +;consecutive screen title bar refreshes. +; +; +MSGID_DESKTOPPAGE_TITLEBAR_REFRESH_SECONDS +Sekunden +;seconds +; +; +MSGID_DESKTOPPAGE_TITLEBAR_REFRESH_MEMCHANGE +Nur bei Änderung am Speicher aktualisieren: +;Refresh only on memory change: +; +; +MSGID_DESKTOPPAGE_TITLEBAR_REFRESH_MEMCHANGE_SHORTHELP +Wenn eingeschaltet, wird der Text am Bildschirmtitel\n\ +nur aktualisiert, wenn sich der freie Speicher\n\ +seit der letzten Prüfung geändert hat. +;When this item is checked, the screen title bar\n\ +;is only refreshed when the amount of available\n\ +;system memory has changed since last check.\n\ +;The memory is checked every \"Titlebar refresh rate\" seconds. +; +; +MSGID_DESKTOPPAGE_DESKTOP_REFRESH +Aktualisierung Arbeitsfläche +;Desktop Refresh +; +; +MSGID_DESKTOPPAGE_DISK_ICON_RATE +Disk Piktogramm-Update: +;Disk icon rate: +; +; +MSGID_DESKTOPPAGE_DISK_ICON_RATE_SHORTHELP +Dies legt das Zeitintervall fest, in dem\n\ +Scalos die Laufwerke prüft und\n\ +Datenträgerwechsel registriert. +;This is the time interval Scalos\n\ +;checks for changed disks and volumes. +; +; +MSGID_DESKTOPPAGE_DISK_ICON_RATE_SECONDS +Sekunden +;seconds +; +; +MSGID_DESKTOPPAGE_SCREENTITLE +Bildschirmtitel +;Screen Title +; +; +MSGID_DESKTOPPAGE_SCREENTITLE_MODE +Sichtbarkeit: +;Visibility: +; +; +MSGID_DESKTOPPAGE_SCREENTITLE_MODE_SHORTHELP +Hier können Sie festlegen, wann der Bildschirmtitel sichtbar sein soll:\n\ +- ständig sichtbar\n\ +- Titel klappt unter dem Mauszeiger auf\n\ +- Titel ist immer ausgeblendet +;Specifiy here whether you like the screen title\n\ +;- to be visible all the time\n\ +;- to pop up when the mouse pointer is positioned at the top of the screen\n\ +;- to be hidden all the time +; +; +MSGID_DESKTOPPAGE_MISCELLANEOUS +Vermischtes +;Miscellaneous +; +; +MSGID_DESKTOPPAGE_ALLOW_CLOSEWB +CloseWorkbench() zulassen: +;Allow CloseWorkbench(): +; +; +MSGID_DESKTOPPAGE_ALLOW_CLOSEWB_SHORTHELP +Durch Ausschalten dieses Schalters können Sie die\n\ +Funktion CloseWB() stillegen.\n\ +Das ist nützlich, um zu verhindern, dass\n\ +irgendwelche alten Programme die Workbench schließen. +;Disable this checkbox to make the CloseWB() function\n\ +;a no-op. This allows to work with some ancient\n\ +;programs and leave Scalos open all the time. +; +; +MSGID_DESKTOPPAGE_DROPSTART +Programmstart beim Ablegen: +;Drop-start: +; +; +MSGID_DESKTOPPAGE_DROPSTART_SHORTHELP +Ist dieser Schalter eingeschaltet, können Sie ein\n\ +Projekt-Piktogramm direkt auf ein Programm ziehen.\n\ +Beim Ablegen des Piktogramms wird dann das\n\ +Programm mit dem Projekt als Argument ausgefürt. +;Dropping a project icon on to another programs\n\ +;icon will automatically run the program and\n\ +;pass the project file as a parameter +; +; +MSGID_DESKTOPPAGE_CONSOLENAME +Konsolen-Name +;Console name +; +; +MSGID_DESKTOPPAGE_CONSOLENAME_SHORTHELP +Dies ist der vollständige Dateiname der\n\ +Konsole für CLI- und ARexx-Programme. +;Gives complete file specifier for CLI and ARexx console. +; +; +MSGID_DESKTOPPAGE_AUTOLEAVEOUT +Automatisch auslagern: +;Automatic leave-out +; +; +MSGID_DESKTOPPAGE_AUTOLEAVEOUT_SHORTHELP +Ist dieser Schalter eingeschaltet, wird ein\n\ +Piktogramm automatisch ausgelagert, wenn es\n\ +auf die Arbeitsfläche gezogen wird. +;If this switch is turned on, dragging icons\n\ +;onto the desktop remembers them permanently\n\ +;as left-out, just like selecting the\n\ +;\"leave out\" menu command. +; +; +MSGID_DESKTOPPAGE_WINTITLEBAR_REFRESH +Anzeigerate Titel: +; Titlebar refresh rate: +; +; +MSGID_DESKTOPPAGE_WINTITLEBAR_REFRESH_SHORTHELP +Dies ist das Zeitintervall, in dem der\n\ +Fenstertitel aktualisiert wird. +; This is the time interval between\n\ +; consecutive window title bar refreshes. +; +; +MSGID_DESKTOPPAGE_WINTITLEBAR_REFRESH_SECONDS +Sekunden +; seconds +; +; +MSGID_DESKTOPPAGE_WINTITLEBAR_REFRESH_MEMCHANGE +Nur bei Änderung am Speicher aktualisieren: +; Refresh only on memory change: +; +; +MSGID_DESKTOPPAGE_WINTITLEBAR_REFRESH_MEMCHANGE_SHORTHELP +Wenn eingeschaltet, werden die Fenstertitel nur aktualisiert,\n\ +wenn sich der verfügbare Speicher verändert hat.\n\ +Der verfügbare Speicher wird regelmäßig alle\n\ +\"Anzeigerate Titel\" Sekunden überprüft. +; When this item is checked, the window title bar\n\ +; is only refreshed when the amount of available\n\ +; system memory has changed since last check.\n\ +; The memory is checked every \"Titlebar refresh rate\" seconds. +; +; +MSGID_DESKTOPPAGE_LASSO +Lasso +;Lasso +; +; +MSGID_DESKTOPPAGE_SINGLEWINDOW_LASSO +Einzelfenster-Lasso +;Single-Window Lasso Mode +; +; +MSGID_DESKTOPPAGE_SINGLEWINDOW_LASSO_SHORTHELP +Mit dieser Tastenkombination wird der Ziehbereich des\n\ +Lassos auf ein einzelnes Fenster beschränkt.\n\ +Der Inhalt dieses Fensters rollt, sobald der Mauszeiger\n\ +den inneren Bereich des Fensters verläßt, und ermöglicht\n\ +so die Auswahl vorher verdeckter Piktogramme. +;Press this qualifier key to limit lasso operation to a single window.\n\ +;In this mode, the window contents scrolls to unveal hidden\n\ +;icons if the mouse leaves the inner window area. +; +;----------------------------------------------------------- +; +MSGID_ICONSPAGE_ICONFRAME +Rahmen um Piktogrammme +;Icon Frame +; +; +MSGID_ICONSPAGE_ICONFRAME_NORMAL +Normal +;Normal +; +; +MSGID_ICONSPAGE_ICONFRAME_NORMAL_SHORTHELP +Diese Art Rahmen wird um Piktogramme\n\ +gezeichnet, die nicht ausgewählt sind.\n\ +Rahmen um OS3.5-\033bGlowIcons\033n werden nur\n\ +gezeichnet, wenn diese nicht als \"rahmenlos\" markiert sind.\n\ +\033uHinweis:\033n Rahmen werden nur gezeichnet, wenn der\n\ +Randabstand zu den Piktogrammen überall größer als 0 ist! +;This type of border is drawn around unselected icons.\n\ +;\033bGlowIcons\033n which have been marked as\n\ +;\"borderless\" will not show this border.\n\ +;Please note that the icon borders below must\n\ +;be non-zero for the icon border to show. +; +; +MSGID_ICONSPAGE_ICONFRAME_SELECTED +Ausgewählt +;Selected +; +; +MSGID_ICONSPAGE_ICONFRAME_SELECTED_SHORTHELP +Diese Art Rahmen wird um ausgewählte\n\ +Piktogramme gezeichnet.\n\ +Rahmen um OS3.5-\033bGlowIcons\033n werden nur\n\ +gezeichnet, wenn diese nicht als \"rahmenlos\" markiert sind.\n\ +\033uHinweis:\033n Rahmen werden nur gezeichnet, wenn der\n\ +Randabstand zu den Piktogrammen überall größer als 0 ist! +;This type of border is drawn around selected icons.\n\ +;\033bGlowIcons\033n which have been marked as\n\ +;\"borderless\" will not show this border.\n\ +;Please note that the icon borders below must\n\ +;be non-zero for the icon border to show. +; +; +MSGID_ICONSPAGE_ICONBORDER_LEFT +Links: +;Left: +; +; +MSGID_ICONSPAGE_ICONBORDER_LEFT_SHORTHELP +Dies ist der Abstand zwischen der linken\n\ +Seite eines Piktogramms und seinem Rahmen.\n\ +Wenn der Abstand 0 ist, wird kein Rahmen gezeichnet! +;This is the space between the left side of an\n\ +;icon and the border. No icon borders will be\n\ +;drawn when this space is 0. +; +; +MSGID_ICONSPAGE_ICONBORDER_TOP +Oben: +;Top: +; +; +MSGID_ICONSPAGE_ICONBORDER_TOP_SHORTHELP +Dies ist der Abstand zwischen der Oberkante\n\ +eines Piktogramms und seinem Rahmen.\n\ +Wenn der Abstand 0 ist, wird kein Rahmen gezeichnet! +;This is the space between the top of an\n\ +;icon and the border. No icon borders will be\n\ +;drawn when this space is 0. +; +; +MSGID_ICONSPAGE_ICONBORDER_RIGHT +Rechts: +;Right: +; +; +MSGID_ICONSPAGE_ICONBORDER_RIGHT_SHORTHELP +Dies ist der Abstand zwischen der rechten Seite\n\ +eines Piktogramms und seinem Rahmen.\n\ +Wenn der Abstand 0 ist, wird kein Rahmen gezeichnet! +;This is the space between the right side of an\n\ +;icon and the border. No icon borders will be\n\ +;drawn when this space is 0. +; +; +MSGID_ICONSPAGE_ICONBORDER_BOTTOM +Unten: +;Bottom: +; +; +MSGID_ICONSPAGE_ICONBORDER_BOTTOM_SHORTHELP +Dies ist der Abstand zwischen der Unterkante\n\ +eines Piktogramms und seinem Rahmen.\n\ +Wenn der Abstand 0 ist, wird kein Rahmen gezeichnet! +;This is the space between the bottom of an\n\ +;icon and the border. No icon borders will be\n\ +;drawn when this space is 0. +; +; +MSGID_ICONSPAGE_LABELS +Beschriftung +;Labels +; +; +MSGID_ICONSPAGE_LABELS_TEXT +Textstil: +;Text style: +; +; +MSGID_ICONSPAGE_LABELS_TEXT_SHORTHELP +Hier können Sie das Aussehen der\n\ +Beschriftung für Piktogramme festlegen. +;Provides a choice of label font formatting\n\ +;which can be applied to the icons text label +; +; +MSGID_ICONSPAGE_LABELS_TEXTSPACE +Abstand zwischen Bild und Schrift: +;Image <-> Text Space +; +; +MSGID_ICONSPAGE_LABELS_TEXTSPACE_SHORTHELP +Hier wird der Abstand zwischen dem Bild eines\n\ +Piktogramms und seiner Beschriftung festgelegt. +;Adjusts the space between the\n\ +;icon imagery and its text label +; +; +MSGID_ICONSPAGE_LABELS_TEXTSPACE_PIXELS +Bildpunkte +;pixels +; +; +MSGID_ICONSPAGE_LABELS_SPLIT +Beschriftung umbrechen: +;Split into multiple lines: +; +; +MSGID_ICONSPAGE_LABELS_SPLIT_SHORTHELP +Hir können Sie festlegen, dass lange\n\ +Piktogrammbeschritungen in mehrere\n\ +Zeilen aufgeteilt werden. +;Allows filenames to be split\n\ +;over multiple lines +; +; +MSGID_ICONSPAGE_LABELS_UNDERLINE_LINKS +Namen für weiche Verknüpfungen \033uunterstreichen\033n: +;Display soft-link file names \033uunderlined\033n: +; +; +MSGID_ICONSPAGE_LABELS_UNDERLINE_LINKS_SHORTHELP +Wenn dieser Schalter eingeschaltet ist, werden die\n\ +Piktogramm-Beschriftungen für weiche Verknüpfungen \033uunterstrichen\033n. +;When this item is checked, icon names of\n\ +;soft-links are displayed \033uunderlined\033n. +; +; +MSGID_ICONSPAGE_LABELS_FONT +Schriftart +;Font +; +; +MSGID_ICONSPAGE_LABELS_FONT_NOTICE +Zum Ändern der Schriftart für die Piktogrammtitel \ +verwenden Sie bitte den Standard Schrift-Voreinsteller \ +des Betriebssystems. Mit dem Popup-Knopf auf der \ +rechten Seite führen Sie dieses Programm aus. +;To change the font used for icon labels you must use \ +;the standard \033bFont preferences\033n program installed on your \ +;system. Use the pop-up button on the right to launch \ +;the fonts preference program. +; +; +MSGID_ICONSPAGE_LABELS_FONT_SHORTHELP +Führt den Standard Schriftart Voreinsteller aus. +;Launch standard Font prefs program +; +; +MSGID_ICONSPAGE_GENERAL +Allgemein +;General +; +; +MSGID_ICONSPAGE_MASKED_CLICKAREA +Maskierter Klickbereich: +;Masked click area: +; +; +MSGID_ICONSPAGE_MASKED_CLICKAREA_SHORTHELP +Wenn dieser Schalter eingeschaltet ist, müssen Sie auf\n\ +den nicht durchsichtigen Teil eines Piktogramms klicken,\n\ +um es zu aktivieren. Wenn er ausgeschaltet ist, genügt\n\ +ein Klick irgendwo innerhalb des von Piktogramm\n\ +belegten Rechtecks. +;If this checkbox is checked, you have to click on the\n\ +;unmasked, visible area of an icon to activate it. If it\n\ +;is unchecked, a click anywhere inside the icon\n\ +;rectangle will be sufficient for activation. +; +; +MSGID_ICONSPAGE_MULTISELECTION +Mehrfachauswahl: +;Multi-Selection: +; +; +MSGID_ICONSPAGE_MULTISELECTION_SHORTHELP +Bietet eine verbesserte Art der Auswahl mehrerer Piktogramme,\n\ +bei der Sie nicht die Umschaltttaste drücken müssen, um\n\ +die ausgewählten Piktogramme zu ziehen. +;Provides an alternative multi-select method which\n\ +;does not require you to hold down the SHIFT key\n\ +;whilst dragging multiple icons. +; +; +MSGID_ICONSPAGE_NEWICONS +New Icons +; +; +MSGID_ICONSPAGE_NEWICONS_REMAP_PRECISION +Stiftgenauigkeit: +;Remap precision: +; +; +MSGID_ICONSPAGE_NEWICONS_REMAP_PRECISION_SHORTHELP +Legt den Grad der Genauigkeit fest, mit\n\ +dem Farben der NewIcons aus der\n\ +Bildschirmpalette gewählt werden. +;Specifies the precision to use when\n\ +;remapping NewIcon colors to the screen palette. +; +; +MSGID_ICONSPAGE_NEWICONS_TRANSPARENTBG +Durchsichtiger Hintergrund: +;Transparent background: +; +; +MSGID_ICONSPAGE_NEWICONS_TRANSPARENTBG_SHORTHELP +Macht den Hintergrund für NewIcons transparent. +;Makes the background of NewIcons transparent +; +; +MSGID_ICONSPAGE_DEFICONS +Standardpiktogramme +;Def Icons +; +; +MSGID_ICONSPAGE_DEFICONS_LOADFIRST +Lade Std. Disk. zuerst: +;Load first: +; +; +MSGID_ICONSPAGE_DEFICONS_LOADFIRST_SHORTHELP +Wenn eingeschaltet, werden die def_#?\n\ +Standardpiktogramme bevorzugt vor den\n\ +gerätespezifischen Piktogrammen benutzt. +;Your def_#? icons will get priority when\n\ +;loading over a specific icon for a device. +; +; +MSGID_ICONSPAGE_DEFICONS_SAVEABLE +Std. Piktogramme speichern: +;Icons saveable: +; +; +MSGID_ICONSPAGE_DEFICONS_SAVEABLE_SHORTHELP +Wenn eingeschaltet, können Standardpiktogramme\n\ +mit \033bfixieren\033n verändert werden.\n\ +Im ausgeschalteten Zustand werden die\n\ +Standardpiktogramme nicht verängert. +;When enabled, \033bsnapshot\033n saves changes\n\ +;to default icons.\n\ +;Uncheck this checkbox to prevent Scalos from\n\ +;changing any of your default icons. +; +; +MSGID_ICONSPAGE_TOOLTIPS_GENERAL +Allgemein +;General +; +; +MSGID_ICONSPAGE_TOOLTIPS_SHOW +Tooltips für Piktogramme anzeigen: +;Show toolips for icons: +; +; +MSGID_ICONSPAGE_TOOLTIPS_SHOW_SHORTHELP +Wenn eingeschaltet, zeigt Scalos \033bTooltips\033n\n\ +mit zusätzlichen Angaben an, wenn der Mauszeiger\n\ +länger über einem Piktogramm gehalten wird.\n\ +Der Tooltip verschwindet wieder, sobald die\n\ +Maus bewegt oder eine Taste gedrückt wird. +;When this checkbox is checked, Scalos pops up\n\ +;\033btooltips\033n with additional information\n\ +;when you keep the mouse pointer positioned over\n\ +;an icon for more than the tooltip delay time.\n\ +;The tooltip automatically disappears as soon as\n\ +;the mouse is moved or any key is pressed. +; +; +MSGID_ICONSPAGE_TOOLTIPS_SETTINGS +Einstellungen +;Settings +; +; +MSGID_ICONSPAGE_TOOLTIPS_DELAY +Wartezeit vor dem Anzeigen eines Tooltips: +;Delay before pop-up: +; +; +MSGID_ICONSPAGE_TOOLTIPS_DELAY_SHORTHELP +Diese Einstellung legt fest, wie lange der\n\ +Mauszeiger auf ein Piktogramm zeigen muß,\n\ +bevor ein Tooltip erscheint. +;Here you can select how long you have to\n\ +;keep the mouse pointer positioned over an\n\ +;icon until the tooltip pops up. +; +; +MSGID_ICONSPAGE_TOOLTIPS_DELAY_SECONDS +Sekunden +;seconds +; +; +MSGID_ICONSPAGE_TOOLTIPS_FONT +Schriftart +;Font: +; +; +MSGID_ICONSPAGE_TOOLTIPS_FONT_SHORTHELP +??? +; +; +MSGID_ICONSPAGE_TOOLTIPS_FONT_ASLTITLE +Bitte wählen Sie eine Schrift... +;Please select a font... +; +; +MSGID_ICONSPAGE_TOOLTIPS_DISPLAYFIELDS +Angezeigte Felder +;Display Fields +; +; +MSGID_ICONSPAGE_TOOLTIPS_AVAILABLEFIELDS +Verfügbare Felder +;Available Fields +; +; +MSGID_ICONSPAGE_TOOLTIPS_AVAILABLEFIELDS_SHORTHELP +??? +; +; +MSGID_ICONSPAGE_TOOLTIPS_FIELDSINUSE +Benutzte Felder +;Fields In Use +; +; +MSGID_ICONSPAGE_TOOLTIPS_FIELDSINUSE_SHORTHELP +??? +; +; +MSGID_ICONSPAGE_DRAGGING +Ziehen&Ablegen +;Dragging +; +; +MSGID_ICONSPAGE_ATTRIBUTES_TRANSPARENCY_DEFICONS +Transparenz +;Transparency +; +; +MSGID_ICONSPAGE_ATTRIBUTES_TRANSPARENCY_DEFICONS_SHORTHELP +Standardpiktogramme können durchscheinend gezeichnet werden.\n\ +Wählen Sie hier den Grad der Durchsichtigkeit\n\ +für Standardpiktogramme.\n\ +Echte Transparenz kann nur genutzt werden, wenn der\n\ +Workbench-Bildschirm mehr als 256 Farben darstellen kann. +;Default icons may be drawn transparent.\n\ +;Please select the degree of transparency you\n\ +;would like default icons to be draw with.\n\ +;Please note that real transparency is only available\n\ +;if your desktop screen has more than 256 colors. +; +; +MSGID_ICONSPAGE_LABELS_FONT_SAMPLETEXT_SHORTHELP +Dies ist ein Beispiel für\n\ +die ausgewählte Schrift. +;This is an example text to visualize\n\ +;what the selected font looks like +; +; +MSGID_ICONSPAGE_HILITE_UNDER_MOUSE +Piktogr unter Maus hervorheben: +;Mark icon under mouse: +; +; +MSGID_ICONSPAGE_HILITE_UNDER_MOUSE_SHORTHELP +Wenn dieser Schalter eingeschaltet ist,\n\ +werden Piktogramme optisch hervorgehoben,\n\ +solange der Mauszeiger über ihnen steht. +;If this switch is turned on, every\n\ +;icon is shown in a highlighted stated\n\ +;while the mouse pointer is over it. +; +; +MSGID_ICONSPAGE_ICONSCALING +Piktogramm-Skalierung +;Icon Scaling +; +; +MSGID_ICONSPAGE_SCALING_MINSIZE +Minimalgröße: +;Minimum Size: +; +; +MSGID_ICONSPAGE_SCALING_MINSIZE_SHORTHELP +Minimalgröße für die angezeigten Piktogramme.\n\ +Kleinere Piktogramme werden auf die\n\ +festgelegte Minimalgröße vergrößert. +;Minimum size for displayed icons.\n\ +;Smaller icons will be scaled to\n\ +;the specified minimum size. +; +; +MSGID_ICONSPAGE_SCALING_MAXSIZE +Maximalgröße: +;Maximum Size: +; +; +MSGID_ICONSPAGE_SCALING_MAXSIZE_SHORTHELP +Maximalgröße für die angezeigten Piktogramme.\n\ +Größere Piktogramme werden auf die\n\ +festgelegte Maximalgröße verkleinert. +;Maximum size for displayed icons.\n\ +;Larger icons will be scaled to\n\ +;the specified maximum size. +; +; +MSGID_ICONSPAGE_GROUP_ICONFONT +Standardschrift +;Standard Font +; +; +MSGID_ICONSPAGE_LABELS_ICONFONT_SHORTHELP +Auswahl der Schrift für die\n\ +Beschriftung von Piktogrammen.\n\ +Diese Auswahl is deaktiviert, solange\n\ +die Verwendung von TrueType Schriften\n\ +für Piktogramme eingeschaltet ist. +;Select font to display icon names.\n\ +;This selection is disabled while TrueType\n\ +;icon fonts are enabled. +; +; +MSGID_ICONSPAGE_ICONFONT_ASLTITLE +Schrift für Piktogramme wählen... +;Please select an icon font... +; +; +MSGID_ICONSPAGE_ICONTHUMBNAILS +Miniaturansicht +;Thumbnails +; +; +MSGID_ICONSPAGE_SHOWTHUMBNAILS +Miniaturansicht anzeigen: +;Display Thumbnails: +; +; +MSGID_ICONSPAGE_SHOWTHUMBNAILS_SHORTHELP +Hier wird festgelegt, wann Piktogramme als\n\ +Miniaturansicht angezeigt werden:\n\ +Nie - immer normale Piktgramme zeigen.\n\ +Für StandardPiktogr. - Standardpiktogramme\n\ + werden durch Miniaturansicht ersetzt.\n\ +Immer - Es wird immer Miniaturansicht angezeigt. +;Select if and when icons are displayed as image thumbnails:\n\ +;Never - don't show thumbnails\n\ +;As default - show thumbnails instead of default icons\n\ +;Always - always show thumbnails +; +; +MSGID_ICONSPAGE_SHOWTHUMBNAILS_AS_DEFAULT +\033bNur Piktogramme anzeigen\033n ignorieren: +;Ignore \033bShowOnlyIcons\033n mode: +; +; +MSGID_ICONSPAGE_SHOWTHUMBNAILS_AS_DEFAULT_SHORTHELP +Anzeigen von Miniaturansichten für Bilddateien ohne Piktogramm.\n\ +Diese Einstellung ist nurvon Bedeutung wenn\n\ +\033bMiniaturansicht anzeigen\033n\n\ auf\n\ +\033bFür Standardpiktogr.\033n eingestellt ist. +;Select it to allow the displaying of icons\n\ +;thumbnails images for default icons with windows\n\ +;using the \033bShow Only Icons\033n show mode.\n\ +;\n\ +;This option is only availlable if \033bAs default\033n\n\ +;option is set from \033bDisplay Thumbnails\033n setting. +; +; +MSGID_ICONSPAGE_THUMBNAILS_SIZE +Größe der Miniaturansicht: +;Thumbnail size: +; +; +MSGID_ICONSPAGE_THUMBNAILS_SIZE_SHORTHELP +Auswahl der Größe für die Miniaturansicht.\n\ +Je nach Seitenverhältnis der Originalbilder\n\ +kann die tatsächliche Größe etwas abweichen. +;Select desired size for thumbnail images.\n\ +;Actual size may vary, due to image aspect. +; +; +MSGID_ICONSPAGE_THUMBNAILS_MAXAGE +Aufräumen nach: +;Cleanup after +; +; +MSGID_ICONSPAGE_THUMBNAILS_MAXAGE_SHORTHELP +Um die Größe der Zwischenspeicherdatei in Grenzen\n\ +zu halten, werden die zwischengespeicherten Miniaturansichten\n\ +gelöscht, wenn sie länger als die eingestellte Anzahl\n\ +Tage nicht benutzt wurden. +;Cached thumbnail images will be removed from the cache\n\ +;if they have not been accessed for more than the\n\ +;specified number of days, in order to keep cache\n\ +;size as small as possible. +; +; +MSGID_ICONSPAGE_THUMBNAILS_MAXAGE_DAYS +Tagen +;days +; +; +MSGID_ICONSPAGE_THUMBNAILS_MINSIZE_LIMIT +Mindestgröße zum Zwischenspeichern: +;Minimum limit size: +; +; +MSGID_ICONSPAGE_THUMBNAILS_MINSIZE_LIMIT_SHORTHELP +Minimale Größe zum Zwischenspeichern der Miniaturansicht.\n\ +Kleinere Miniaturansichten werden nicht zwischengespeichert,\n\ +sondern immer direkt erzeugt und angezeigt. +;Select desired minimum dimensions for images to cache.\n\ +;Images with smallers dimensions than value specified here,\n\ +;will not be added to the cache. +; +; +MSGID_ICONSPAGE_TOOLTIPS_TRANSPARENCY +Transparenz +;Transparency +; +; +MSGID_ICONSPAGE_TOOLTIPS_TRANSPARENCY_SHORTHELP +Scalos kann Tooltips durchscheinend anzeigen.\n\ +Wählen Sie hier den Grad der\n\ +Durchsichtigkeit für Tooltips.\n\ +Durchsichtigkeit kann nur genutzt werden, wenn der\n\ +Workbench-Bildschirm mehr als 256 Farben darstellen kann. +;Tooltips can be drawn transparent.\n\ +;Please select the degree of\n\ +;transparency for the tooltips.\n\ +;Please note that transparency is only available\n\ +;if your desktop screen has more than 256 colors. +; +; +MSGID_ICONSPAGE_THUMBNAILS_SETTINGS +Einstellungen +;Settings +; +; +MSGID_ICONSPAGE_THUMBNAILS_CACHE +Zwischenspeicherung +;Caching +; +; +MSGID_ICONSPAGE_THUMBNAILS_QUALITY +Qualität +;Quality +; +; +MSGID_ICONSPAGE_THUMBNAILS_QUALITY_WORST +Niedrigste +;Low +; +; +MSGID_ICONSPAGE_THUMBNAILS_QUALITY_BEST +Höchste +;High +; +; +MSGID_ICONSPAGE_THUMBNAILS_QUALITY_SHORTHELP +Dieser Schieberegler wählt die Qualität der erzeugten Miniaturansicht.\n\ +Typischerweise braucht die Erzeugung von Miniaturansichten höherer Qualität mehr Zeit.\n\ +Der tatsächliche Einfluß dieser Einstellung hängt vom verwendeten Plugin ab. +;This slider selects the quality of the generated thumbnails.\n\ +;Usually, better quality thumbnails take longer to create.\n\ +;The actual effect of quality setting depends on the preview plugin used. +; +; +MSGID_ICONSPAGE_THUMBNAILS_SQUARE +Quadratische Miniaturansicht: +;Thumbnails always square: +; +; +MSGID_ICONSPAGE_THUMBNAILS_SQUARE_SHORTHELP +Standardmäßig wird die Miniaturansicht im selben\n\ +Seitenverhältnis wie das zugehörige Bild erzeugt.\n\ +Wenn dieser Schalter eingeschaltet ist, wird\n\ +immer eine quadratische Miniaturansicht erzeugt. +;By default, thumbnail image icons reflect the aspect ratio\n\ +;of their parent images, i.e. they can be wider than high or vice versa.\n\ +;If this checkbox is checked, thumbnail image icons are always square.\n\ +; +; +MSGID_ICONSPAGE_THUMBNAILS_ICONFRAME +Rahmen um Miniaturansicht: +;Thumbnail Icon Frames +; +; +MSGID_ICONSPAGE_THUMBNAILS_ICONFRAME_NORMAL_SHORTHELP +Diese Art Rahmen wird um Miniaturansichten\n\ +gezeichnet, die nicht ausgewählt sind.\n\ +Rahmen um OS3.5-\033bGlowIcons\033n werden nur\n\ +gezeichnet, wenn diese nicht als \"rahmenlos\" markiert sind.\n\ +\033uHinweis:\033n Rahmen werden nur gezeichnet, wenn der\n\ +Randabstand zu den Piktogrammen überall größer als 0 ist! +;This type of border is drawn around unselected thumbnail icons.\n\ +;\033bGlowIcons\033n which have been marked as\n\ +;\"borderless\" will not show this border.\n\ +;;Please note that the icon borders below must\n\ +;;be non-zero for the icon border to show. +; +; +MSGID_ICONSPAGE_THUMBNAILS_ICONFRAME_SELECTED_SHORTHELP +Diese Art Rahmen wird um ausgewählte\n\ +Miniaturansichten gezeichnet.\n\ +Rahmen um OS3.5-\033bGlowIcons\033n werden nur\n\ +gezeichnet, wenn diese nicht als \"rahmenlos\" markiert sind.\n\ +\033uHinweis:\033n Rahmen werden nur gezeichnet, wenn der\n\ +Randabstand zu den Piktogrammen überall größer als 0 ist! +;This type of border is drawn around selected thumbnail icons.\n\ +;\033bGlowIcons\033n which have been marked as\n\ +;\"borderless\" will not show this border.\n\ +;;Please note that the icon borders below must\n\ +;;be non-zero for the icon border to show. +; +; +MSGID_ICONSPAGE_THUMBNAILS_BACKFILL +Miniaturansicht mit gefülltem Hintergrund: +;Thumbnails background filled +; +; +MSGID_ICONSPAGE_THUMBNAILS_BACKFILL_SHORTHELP +Dieser Schalter legt fest, ob der Hintergrund von Miniaturansichten\n\ +mit der mit Scalos Palette festgelegten Farbe gefüllt werden soll.\n\ +Wenn der Schalter ausgeschaltet ist, bleibt der Hintergrund\n\ +von Miniaturansichten durchsichtig. +;Enable this attribute to draw all thumbnail icons with the\n\ +;backfill colors defined by Scalos palette prefs.\n\ +;If this switch is off, thumbnails have transparent background. +; +; +MSGID_ICONSPAGE_THUMBNAIL_BACKFILL_TRANSPARENCY +Transparenz des Hintergrunds für Miniaturansicht +;Thumbnail background transparency +; +; +MSGID_ICONSPAGE_THUMBNAIL_BACKFILL_TRANSPARENCY_SHORTHELP +Werden Miniaturansichten mit ausgefülltem Hintergrund gezeichnet,\n\ +kann für manche Piktogrammarten festgelegt werden, wie stark\n\ +der Hinterdrund durchscheint. +;True-color icons can be drawn with filled\n\ +;background of selectable transparency. +; +; +MSGID_ICONSPAGE_SEL_ICONTEXT_RECT_GROUP +Rechteck um Text für ausgewählte Piktogramme +;Selected Icon Text Rectangle +; +; +MSGID_ICONSPAGE_SEL_ICONTEXT_RECT +Zusätzliches Rechteck um Text ausgewählter Piktogramme +;Draw additional rectangle around selected icon text +; +; +MSGID_ICONSPAGE_SEL_ICONTEXT_RECT_SHORTHELP +Wenn diese Checkbox eingeschaltet ist, wird zur besseren\n\ +Hervorhebung ein zusätzliches Rechteck um die Beschriftung\n\ +der ausgewählten Piktogramme gezeichnet. +;Select this checkbox to draw a rectangle around the\n\ +;icon text of all selected icons, for improved visibility. +; +; +MSGID_ICONSPAGE_SEL_ICONTEXT_XBORDER +Zusätzlicher Abstand rechts und links +;Additional Horizontal border +; +; +MSGID_ICONSPAGE_SEL_ICONTEXT_XBORDER_SHORTHELP +Dies ist ein zuätzlicher horizontaler Abstand zum Text,\n\ +der beim Zeichnen der Rechtecke um die Beschriftung\n\ +der ausgewählten Piktogramme verwendet wird. +;Additional horizontal border which is used for\n\ +;drawing a rectangle around the icon text of selected icons. +; +; +MSGID_ICONSPAGE_SEL_ICONTEXT_YBORDER +Zusätzlicher Abstand oben und unten +;Additional Vertical border +; +; +MSGID_ICONSPAGE_SEL_ICONTEXT_YBORDER_SHORTHELP +Dies ist ein zuätzlicher vertikaler Abstand zum Text,\n\ +der beim Zeichnen der Rechtecke um die Beschriftung\n\ +der ausgewählten Piktogramme verwendet wird. +;Additional vertical border which is used for drawing\n\ +;a rectangle around the icon text of selected icons. +; +; +MSGID_ICONSPAGE_SEL_ICONTEXT_RADIUS +Eckradius +;Corner Radius +; +; +MSGID_ICONSPAGE_SEL_ICONTEXT_RADIUS_SHORTHELP +Dieser Radius wird für abgerundete Ecken beim\n\ +Zeichnen der Rechtecke um die Beschriftung\n\ +der ausgewählten Piktogramme verwendet. +;Corner radius of the rectangle drawn\n\ +;around the text of selected icons. +; +; +MSGID_ICONSPAGE_SCALING_NOMINALSIZE +Standardgröße: +;Nominal Size: +; +; +MSGID_ICONSPAGE_SCALING_NOMINALSIZE_SHORTHELP +Diese Skalierung wird auf alle Piktogramme angewandt. +;Standard size adjustment applied to all icons. +; +; +MSGID_ICONSPAGE_SCALING_PERCENT +% +;% +; +;----------------------------------------------------------- +; +MSGID_DRAGNDROPPAGE_STYLE +Stil: +;Style: +; +; +MSGID_DRAGNDROPPAGE_STYLE_SHORTHELP +Beim Ziehen und Ablegen kann der Text\n\ +zum Piktogramm mit angezeigt werden. +;The icon label may be displayed\n\ +;whilst the icon is being dragged. +; +; +MSGID_DRAGNDROPPAGE_BOBS +Bobs +; +; +MSGID_DRAGNDROPPAGE_ROUTINES +Bob-Methode: +;Bob Routines: +; +; +MSGID_DRAGNDROPPAGE_ROUTINES_SHORTHELP +Scalos bietet eigene Routinen zum\n\ +weichen Ziehen von Piktogrammen.\n\ +Diese eigenen Routinen können nur genutzt\n\ +werden, wenn der Workbench-Bildschirm mehr\n\ +als 256 Farben darstellen kann. +;Scalos provides custom fast smooth icon dragging routines.\n\ +;Those custom routines are only used if you are\n\ +;running a desktop with more than 256 colours. +; +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY +Aussehen: +;Transparency Method: +; +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY_SHORTHELP +Wenn \033bSchattiert/Echt transparent\033n ausgewählt\n\ +ist, werden Piktogramme beim Ziehen mit echter\n\ +Transparenz gezeichnet.\n\ +Ansonsten wird ein punktiertes \033bGeister\033n-Piktogramm\n\ +angezeigt.\n\ +Echte Transparenz ist nur verfügbar, wenn Ihr\n\ +Workbench-Bildschirm mehr als 256 Farben hat. +;When \"Ghosted/Real Transparent\" is selected, use\n\ +;real transparency to draw drag-drop icons. Otherwise,\n\ +;dotted \"ghosted\" display is used. Please note that\n\ +;real transparency is only available if your\n\ +;desktop screen has more than 256 colors. +; +; +MSGID_DRAGNDROPPAGE_DROPMARKMODE +Anzeige beim Ablegen: +;Drop mark mode: +; +; +MSGID_DRAGNDROPPAGE_DROPMARKMODE_SHORTHELP +Wählen Sie aus, welche Art von Ablagemarken Scalos\n\ +beim Ziegen und Ablegen von Piktogrammen anzeigt. +;Select which kind of drop-marks Scalos\n\ +;shows while you drag icons around. +; +; +MSGID_DRAGNDROPPAGE_LOOK +Aussehen: +;Look: +; +; +MSGID_DRAGNDROPPAGE_LOOK_SHORTHELP +Ein \033bAuslöser\033n schaltet die Darstellung der Piktogramme\n\ +beim Ziehen um, wenn ein Piktogramm über ihn bewegt wird.\n\ +Sie können auswählen, welche \033bAuslöser\033n Ihre Piktogramme\n\ +beeinflussen sollen. +;A Trigger can change the look of the icon\n\ +;currently being dragged. You can select what\n\ +;\033btriggers\033n should affect your icons below. +; +; +MSGID_DRAGNDROPPAGE_AUTOREMOVE +Entferne Piktogramme automatisch: +;Auto remove icons: +; +; +MSGID_DRAGNDROPPAGE_AUTOREMOVE_SHORTHELP +Wenn eingeschaltet, verschwinden die Piktogramme beim\n\ +Ziehen von ihrer ursprünglichen Stelle. Es wird dort\n\ +nur ein halbdurchsichtiger Rest angezeigt. +;If enabled, when you drag icons away from their\n\ +;original position, only a semi-transparent shadow\n\ +;of the icon remains at the original place. +; +; +MSGID_DRAGNDROPPAGE_GROUP_MULTIPLE +Mehrere Piktogramme zusammenfassen: +;Group multiple icons: +; +; +MSGID_DRAGNDROPPAGE_GROUP_MULTIPLE_SHORTHELP +Wenn eingeschaltet, werden mehrere Piktogramme\n\ +beim Ziehen unter dem Mauszeiger als Stapel angezeigt.\n\ +Damit wird kann die Anzeige beschleunigt werden. +;When dragging multiple icons\n\ +;they will appear as a pile\n\ +;to speed up OS. +; +; +MSGID_DRAGNDROPPAGE_DRAGGINGLABEL +Zusammenfassung beim Ziehen Anzeigen: +;Display dragging label: +; +; +MSGID_DRAGNDROPPAGE_DRAGGINGLABEL_SHORTHELP +Wenn eingeschaltet, fügt Scalos beim Ziehen mehrerer\n\ +Piktogramme eine Zusammenfassung mit der Anzahl\n\ +der gezogenen Dateien, Schubladen und Geräte hinzu. +;When dragging multiple icons Scalos will display\n\ +;a text line detailing number of files, drawers\n\ +;and devices being dragged. +; +; +MSGID_DRAGNDROPPAGE_FORCECOPY +Immer Kopieren: +;Force copy: +; +; +MSGID_DRAGNDROPPAGE_FORCECOPY_SHORTHELP +Legt die Tastenkombination fest, die beim Ziehen\n\ +und Ablegen von Piktogrammen das Kopieren aller\n\ +gezogenen Dateien und Schubladen erzwingt. +;Define the qualifier key that is used to\n\ +;force copying (instead of moving) any\n\ +;dragged files and drawers. +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS +Auslöser +;Triggers +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_SHORTHELP +Einschalten eines Auslösers wechselt das Aussehen\n\ +von Piktogrammen wie oben festegelegt, sobald das\n\ +Piktogramm über den Auslöser bewegt wird. +;Enabling a trigger will change the icons appearance\n\ +;to the \033bLook\033n configured above when the\n\ +;icon is above trigger. +; +; +MSGID_DRAGNDROPPAGE_QUALIFIERS +Qualifier +;Qualifiers +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_DISKICONS +Laufwerks-Piktogramme +;Disk icons +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_DRAWERICONS +Verzeichnis-Piktogramme +;Drawer icons +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_TOOLICONS +Werkzeug-Piktogramme +;Tool icons +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_PROJECTICONS +Projekt-Piktogramme +;Project icons +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_TRASHCANICONS +Mülleimer-Piktogramme +;Trashcan icons +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_KICKICONS +Kickstart-Piktogramme +;Kick icons +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_APPICONS +Anwendungs-Piktogramme +;Application icons +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_APPWINDOWS +Anwendungs-Fenster +;Application windows +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_ICONIFIED_WINDOWS +Ikonifizierte Fenster +;Iconified windows +; +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY_ICONDRAG +Piktogramme beim Ziehen +;Icon drag +; +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY_ICONDRAG_SHORTHELP +Legt den Grad der Durchsichtigkeit beim Ziehen von Piktogrammen fest.\n\ +Ein Wert 0%% bedeutet völlig durchsichtige (unsichtbare)\n\ +Piktogramme, 100%% zeigt die Piktogramme\n\ +vollkommen undurchsichtig.\n\ +Echte Transparenz kann nur genutzt werden, wenn der\n\ +Workbench-Bildschirm mehr als 256 Farben darstellen kann. +;Select degree of icon transparency when dragging icons.\n\ +;0%% means completely transparent (invisible!) icons.\n\ +;100%% means opaque icons.\n\ +;Please note that real transparency is only available\n\ +;if your desktop screen has more than 256 colors. +; +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY_ICONSHADOW +Schatten für Piktogramme +;Icon shadow +; +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY_ICONSHADOW_SHORTHELP +Legt den Grad der Durchsichtigkeit des Piktogramm-Schattens\n\ +fest, der beim Ziehen an der ursprünglichen\n\ +Stelle stehenbleibt.\n\ +Ein Wert 0%% bedeutet völlig durchsichtige (unsichtbare)\n\ +Piktogramme, 100%% zeigt die Piktogramme\n\ +vollkommen undurchsichtig.\n\ +Echte Transparenz kann nur genutzt werden, wenn der\n\ +Workbench-Bildschirm mehr als 256 Farben darstellen kann. +;Select degree of transparency of the icon shadow that\n\ +;remains at the original position when you start\n\ +;dragging the icon away.\n\ +;0% means completely transparent (invisible!) shadow.\n\ +;100% means opaque shadow. +;Please note that real transparency is only available\n\ +;if your desktop screen has more than 256 colors. +; +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY_OPAQUE +undurchsichtig +;opaque +; +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY_TRANSPARENT +Transparent +;transparent +; +; +MSGID_DRAGNDROPPAGE_EASY_MULTISELECT +Einfache Mehrfach-Auswahl: +;Easy Multiple Icon Selection: +; +; +MSGID_DRAGNDROPPAGE_EASY_MULTISELECT_SHORTHELP +Wenn eingeschaltet, können Sie mehrere Piktogramme\n\ +auswählen, ohne die Umschalttaste gedrückt zu halten. +;When enabled, you are not required to hold the\n\ +;\033bshift\033n key to select multiple icons. +; +; +MSGID_DRAGNDROPPAGE_EASY_MULTIDRAG +Einfaches Ziehen mehrerer Piktogr.: +;Easy Dragging of Multiple Icons: +; +; +MSGID_DRAGNDROPPAGE_EASY_MULTIDRAG_SHORTHELP +Wenn eingeschaltet, können Sie mehrere Piktogramme\n\ +ziehen, ohne die Umschalttaste gedrückt zu halten. +;When enabled, you are not required to hold the\n\ +;\033bshift\033n key when you begin to drag\n\ +;multiple selected icons. +; +; +MSGID_DRAGNDROPPAGE_FORCEMAKELINK +Verknüpfung erzeugen: +;Create Links: +; +; +MSGID_DRAGNDROPPAGE_FORCEMAKELINK_SHORTHELP +Legt die Tastenkombination fest, die beim Ziehen\n\ +und Ablegen von Piktogrammen das Erzeugen einer\n\ +Verknüpfung auf die gezogenen Dateien und Schubladen bewirkt. +;Define the qualifier key that is used to\n\ +;create links to (instead of copying) any\n\ +;dragged files and drawers. +; +; +MSGID_DRAGNDROPPAGE_FORCEMOVE +Immer verschieben: +;Force move: +; +; +MSGID_DRAGNDROPPAGE_FORCEMOVE_SHORTHELP +Legt die Tastenkombination fest, die beim Ziehen\n\ +und Ablegen von Piktogrammen das Verschieben aller\n\ +gezogenen Dateien und Schubladen erzwingt. +;Define the qualifier key that is used to\n\ +;force moving (instead of copying) any\n\ +;dragged files and drawers. +; +; +MSGID_DRAGNDROPPAGE_DROPMENU +Ablegen-Menü anzeigen: +;Show Drop Menu: +; +; +MSGID_DRAGNDROPPAGE_DROPMENU_SHORTHELP +Wenn eingeschaltet, wird beim Ablegen gezogener Piktogramme ein\n\ +Menü angezeigt, das die Auswahl zwischen \033bKopieren\033n,\n\ +\033bVerschieben\033n, Erzeugen einer \033bVerknüpfung\033n\n\ +oder dem Abbruch des Ablegens erlaubt. +;When enabled, a popup menu is displayed on each drag-drop\n\ +;operation that allows easy selection whether to \033bcopy\033n or\n\ +;\033bmove\033n item, \033bcreate link\033n to item, or entirely cancel drag-drop. +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_SCALOS_WINDOWS +Scalos-Fenster +;Scalos Windows +; +; +MSGID_DRAGNDROPPAGE_POPOPENWINDOWS +Aufspringende Fenster +;Pop-Open Windows +; +; +MSGID_DRAGNDROPPAGE_SLIDER_POPOPWINDOW_DELAY +Wartezeit fürs Aufspringen: +;Pop-Open Delay: +; +; +MSGID_DRAGNDROPPAGE_SLIDER_POPOPWINDOW_DELAY_SHORTHELP +Die ist die Anzahl Sekunden, die der Mauszeiger während des\n\ +Ziehens und Ablegens stetig über einem Schubladen- oder\n\ +Datenträgerpiktogramm gehalten werden muß, damit sich\n\ +das zugehörige Fenster automatisch öffnet. +;During a drag&drop operation, this is the number of seconds\n\ +;you have to keep the mouse pointer steady over a drawer\n\ +;or volume icon before it pops open. +; +;----------------------------------------------------------- +; +MSGID_WINDOWPAGE_WINDOWTITLES +Fenstertitel +;Window Titles +; +; +MSGID_WINDOWPAGE_WINDOWTITLES_ROOTWINDOW +Wurzelfenster: +;Root Window: +; +; +MSGID_WINDOWPAGE_WINDOWTITLES_ROOTWINDOW_SHORTHELP +Dies ist die Einstellung für den Titel des Scalos Wurzelfensters.\n\ +Sie können diesen Titel nur sehen, wenn der\n\ +Menüpunkt "Scalos im Hintergrund" im Scalos Hauptmenü\n\ +ausgeschaltet ist. +;This is the title for the Scalos root window. You only\n\ +;see this window title when you have the \"Backdrop\"\n\ +;menu item in the Scalos main menu unchecked. +; +; +MSGID_WINDOWPAGE_WINDOWTITLES_ROOTWINDOW_DESCRIPTION +|\033b\0338Beschreibung +;|\033b\0338Description +; +; +MSGID_WINDOWPAGE_WINDOWTITLES_DIRECTORYWINDOW +Schubladenfenster: +;Directory Window: +; +; +MSGID_WINDOWPAGE_WINDOWTITLES_DIRECTORYWINDOW_SHORTHELP +Jedes normale Scalos Schubladenfenster\n\ +zeigt diesen Titel. +;This is the window title for any\n\ +;normal Scalos drawer window. +; +; +MSGID_WINDOWPAGE_WINDOWTITLES_DIRECTORYWINDOW_DESCRIPTION +|\033b\0338Beschreibung +;|\033b\0338Description +; +; +MSGID_WINDOWPAGE_WINDOWTYPE +Auffrischen: +;Window type: +; +; +MSGID_WINDOWPAGE_WINDOWTYPE_SHORTHELP +Legt fest, ob die von Scalos erzeugten Fenster\n\ +\"einfach\" oder \"intelligent\" aufgefrischt\n\ +werden sollen. +;Select whether you would like to be all\n\ +;Scalos windows to be created as simple-refresh\n\ +;or smart-refresh window. +; +; +MSGID_WINDOWPAGE_CONTEXTMENU_DRAGBAR +Kontextmenu nur über Titel: +;Context menu on dragbar only: +; +; +MSGID_WINDOWPAGE_CONTEXTMENU_DRAGBAR_SHORTHELP +Wenn eingeschaltet, erscheint das\n\ +Fenster-Kontextmenü nur über dem\n\ +Titelbalken des Fensters. +;Only allows the windows pop-up menu\n\ +;to appear when the right mouse button\n\ +;is clicked over the\n\ +;windows dragbar +; +; +MSGID_WINDOWPAGE_MMB_MOVE +Mit MMB Bewegen: +;MMB Moves Contents: +; +; +MSGID_WINDOWPAGE_MMB_MOVE_SHORTHELP +Erlaubt das Verschieben des Fensterinhalts\n\ +mit gedrücktem mittleren Mausknopf. +;Allows the use of the middle mouse button\n\ +;to pan around the window contents +; +; +MSGID_WINDOWPAGE_SHOW_STATUSBAR +Statuszeile anzeigen: +;Show status bar: +; +; +MSGID_WINDOWPAGE_SHOW_STATUSBAR_SHORTHELP +Legt fest, ob alle Schubladenfenster eine\n\ +Statuszeile am unteren Rand haben. +;Globally sets wether directory windows\n\ +;display the status bar at the bottom. +; +; +MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE +Standardgrößen für Fenster +;Default Window Size +; +; +MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE_SHORTHELP +Dies sind die Standardwerte für Position\n\ +und Größe neuer Fenster.\n\ +Fenster für Schubladen ohne Piktogramme werden\n\ +mit diesen Werten geöffnet.\n\ +Sie können diese Fenster nach Wunsch verschieben\n\ +und in der Größe anpassen, und die Einstellung\n\ +dann mit \033bfixieren\033n dauerhaft speichern. +;These are the default dimensions for Scalos drawer\n\ +;windows. Windows for drawers without icons are opened\n\ +;at this position and in this size. You are free to\n\ +;move and resize the window any way you like, and\n\ +;use \"snapshot window\" to permanently store the\n\ +;changed values for that specific drawer window. +; +; +MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE_LEFT +Links: +;Left: +; +; +MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE_TOP +Oben: +;Top: +; +; +MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE_WIDTH +Breite: +;Width: +; +; +MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE_HEIGHT +Höhe: +;Height: +; +; +MSGID_WINDOWPAGE_CLEANUPSPACE +Zwischenräume beim Aufräumen +;Cleanup Spaces +; +; +MSGID_WINDOWPAGE_CLEANUPSPACE_SHORTHELP +Legt fest, wieviel Platz Scalos beim \033bcleanup\033n-Befehl\n\ +rings um Piktogramme frei läßt. +;This are the distances Scalos will leave around\n\ +;icons when they are positioned with\n\ +;the \"cleanup\" command. +; +; +MSGID_WINDOWPAGE_CLEANUPSPACE_LEFT +Links: +;Left: +; +; +MSGID_WINDOWPAGE_CLEANUPSPACE_TOP +Oben: +;Top: +; +; +MSGID_WINDOWPAGE_CLEANUPSPACE_XSKIP +horizontal: +;X-Skip: +; +; +MSGID_WINDOWPAGE_CLEANUPSPACE_YSKIP +vertikal: +;Y-Skip: +; +; +MSGID_WINDOWPAGE_CLEANUP_ONRESIZE +Größenänderung ordnet Piktogramme neu an +; Rearrange icons on resize +; +; +MSGID_WINDOWPAGE_CLEANUP_ONRESIZE_SHORTHELP +Wenn dieser Schalter eingeschaltet ist, werden\n\ +bei jeder Größenänderung des Fensters alle\n\ +Piktogramme ohne feste Position automatisch\n\ +neu angeordnet. +; If this switch is enabled, all icons\n\ +; without fixed position are automatically\n\ +; rearranged when window is resized. +; +; +MSGID_WINDOWPAGE_SHOWALL_DEFAULT +Standardwert für \033bInhalt anzeigen\033n: +;Default mode for \033bShow All\033n: +; +; +MSGID_WINDOWPAGE_SHOWALL_DEFAULT_SHORTHELP +Ist für eine Schublade für \"Inhalt anzeigen\"\n\ +der Wert \"Standard\" eingestellt, wird hier\n\ +festgelegt, ob \033bNur Piktogramme\033n oder\n\ +\033bAlle Dateien\033n angezeigt werden sollen. +;This setting selects how the value \"default\"\n\ +;is handled for \033bshow all\033n.\n\ +;You can select whether \"default\" shows\n\ +;\033bonly icons\033n, or \033ball files\033n. +; +; +MSGID_WINDOWPAGE_VIEWBY_DEFAULT +Standardwert für \033bInhalt auflisten\033n: +;Default \033bView By\033n Mode: +; +; +MSGID_WINDOWPAGE_WINDOWTYPE_VIEWBY_DEFAULT_SHORTHELP +Hier wird eingestellt, wir Schubladen angezeigt\n\ +werden bei denen der Wert \"Standard\" für\n\ +\033bInhalt auflisten\033 eingestellt ist. +;Selects which view mode is to be used for all\n\ +;drawers with their view mode set to \"default\". +; +; +MSGID_WINDOWPAGE_CONTROLBAR_BROWSER_GADGETS +Schaltfelder im Browserfenster +;Browser Window Gadgets +; +; +MSGID_WINDOWPAGE_CONTROLBAR_GADGETS_SHORTHELP +Wählen Sie hier aus, welche Schaltfelder in der\n\ +Steuerleiste eines Browser-Fensters enthalten sind. +;Select here which gadgets you would like to\n\ +;have in your browser window control bar. +; +; +MSGID_WINDOWPAGE_CONTROLBAR_AVAILABLE_GADGETS +Verfügbare Schaltfelder +;Available Gadgets +; +; +MSGID_WINDOWPAGE_CONTROLBAR_AVAILABLE_GADGETS_SHORTHELP +Wählen Sie eines oder mehrere Schaltfelder aus dieser\n\ +Liste und ziehen Sie mit der Maus in die Liste\n\ +der \033bverwendeten Schaltfelder\033n. +;Select one ore move gadgets from this list and drag\n\ +;them to the list of \033bActive Gadgets\00n. +; +; +MSGID_WINDOWPAGE_CONTROLBAR_ACTIVE_GADGETS +Verwendete Schaltfelder +;Active Gadgets +; +; +MSGID_WINDOWPAGE_CONTROLBAR_ACTIVE_GADGETS_SHORTHELP +Dies sind die Schaltfelder, die derzeit in der Steuerleiste enthalten sind.\n\ +Ändern Sie die Reihenfolge durch Sortieren mit Ziehen und Ablegen.\n\ +Zum Entfernen von Schaltfeldern ziehen Sie sie mit der Maus nach\n\ +links in die Liste der \033bverfügbaren Schaltfelder\033n.\n\ +Zusätzliche Schatfelder können aus der Liste der \033bverfügbaren\n\ +Schaltfelder\033n nach rechts in diese Liste an\n\ +die gewünschte Position gezogen werden. +;These are the gadgets currently on your control bar.\n\ +;Change the order of the gadgets by sorting them via drag-and-drop.\n\ +;To remove gadgets, drag them to the\n\ +;\033bAvailable Gadgets\033n on the left.\n\ +;To add new gadgets, drag new gadgets from the\n\ +;\033bAvailable Gadgets\033n to the position you want to see them. +; +; +MSGID_CONTROLBARGADGETLIST_TYPE +Schaltfeldart +;Gadget Type +; +; +MSGID_WINDOWPAGE_CONTROLBAR_NORMALIMAGE +Bild im Ruhezustand +;Unselected Image +; +; +MSGID_WINDOWPAGE_CONTROLBAR_NORMALIMAGE_ASLTITLE +Bildauswahl für Ruhezustand +;Select image for unselected state +; +; +MSGID_WINDOWPAGE_CONTROLBAR_NORMALIMAGE_SHORTHELP +Wählen Sie hier irgendein Datatypes-Bild für den\n\ +Ruhezustand (nicht ausgewählt) der Schaltfläche. +;Select here any datatypes image for the\n\ +;unselected state of a user-defined button. +; +; +MSGID_WINDOWPAGE_CONTROLBAR_SELECTEDIMAGE +Bild für betätigten Zustand +;Selected Image +; +; +MSGID_WINDOWPAGE_CONTROLBAR_SELECTEDIMAGE_ASLTITLE +Bilddatei für betätigten Zustand wählen... +;Select image for Selected state +; +; +MSGID_WINDOWPAGE_CONTROLBAR_SELECTEDIMAGE_SHORTHELP +Wählen Sie hier irgendein Datatypes-Bild für den\n\ +betätigten (ausgewählten) Zustand der Schaltfläche. +;Select here any datatypes image for the\n\ +;selected state of a user-defined button. +; +; +MSGID_WINDOWPAGE_CONTROLBAR_DISABLEDIMAGE +Bild für inaktiven Zustand +;Disabled Image +; +; +MSGID_WINDOWPAGE_CONTROLBAR_DISABLEDIMAGE_ASLTITLE +Bilddatei für inaktiven Zustand auswählen... +;Select image for Disabled state +; +; +MSGID_WINDOWPAGE_CONTROLBAR_DISABLEDIMAGE_SHORTHELP +Wählen Sie hier irgendein Datatypes-Bild für den\n\ +inaktiven (gesperrten) Zustand der Schaltfläche. +;Select here any datatypes image for the\n\ +;disabled state of a user-defined button. +; +; +MSGID_WINDOWPAGE_CONTROLBAR_ACTION +Befehl +;Button Action +; +; +MSGID_WINDOWPAGE_CONTROLBAR_ACTION_SHORTHELP +Für benutzerdefinierte Schaltflächen wählen Sie\n\ +hier eine Aktion aus der Liste der Scalos-Menübefehle. +;For user-defined buttons select here any action from\n\ +;the list of available Scalos menu commands. +; +; +MSGID_WINDOWPAGE_CONTROLBAR_GADGETHELPTEXT +Hilfetext +;Help Text +; +; +MSGID_WINDOWPAGE_CONTROLBAR_GADGETHELPTEXT_SHORTHELP +Für benutzerdefinierte Schaltflächen tragen\n\ +Sie hier den azuzeigenden Hilfetext ein.\n\ +Dieser Hilfetext wird angezeigt, wenn Sie den Mauszeiger\n\ +mehrere Sekunden über der Schaltfläche stillhalten. +;For user-defined buttons, enter your gadget help text here.\n\ +;This text is displayed when you keep your mouse\n\ +;steadily positioned on the gadgets for a few seconds. +; +; +MSGID_WINDOWPAGE_CHECK_OVERLAP +Piktogrammüberlappung vermeiden: +;Check for Overlapping Icons: +; +; +MSGID_WINDOWPAGE_CHECK_OVERLAP_SHORTHELP +Legt global fest, ob Piktogramme darauf überwacht werden,\n\ +ob sie sich gegenseitig überlappen.\n\ +Wenn eingeschaltet, werden überlappende Piktogramme beim\n\ +Lesen des Verzeichnisses verschoben. +;Globally sets whether verification is performed that icons do\n\ +;not overlap each other.\n\ +;If enabled, overlapping icons will be repositioned when read. +; +; +MSGID_WINDOWPAGE_TRANSPARENCY_WINDOW +Transparenz +;Transparency +; +; +MSGID_WINDOWPAGE_TRANSPARENCY_ACTIVEWINDOW +Aktives Fenster +;Active window +; +; +MSGID_WINDOWPAGE_TRANSPARENCY_INACTIVEWINDOW +Inaktive Fenster +;Inactive windows +; +; +MSGID_WINDOWPAGE_TRANSPARENCY_ACTIVEWINDOW_SHORTHELP +Hier wird der Grad der Durchsichtigkeit für\n\ +das aktive Scalos-Fenster eingestellt.\n\ +Diese Einstellung gilt für die Arbeitsfläche nur,\n\ +wenn "Scalos im Hintergrund" ausgeschaltet ist. +;Here you can select the degree of transparency\n\ +;for the active Scalos desktop, icon, or text window.\n\ +;The desktop will only get transparent if it is not a backdrop window. +; +; +MSGID_WINDOWPAGE_TRANSPARENCY_INACTIVEWINDOW_SHORTHELP +Hier wird der Grad der Durchsichtigkeit für\n\ +alle inaktiven Scalos-Fenster eingestellt.\n\ +Diese Einstellung gilt für die Arbeitsfläche nur,\n\ +wenn "Scalos im Hintergrund" ausgeschaltet ist. +;Here you can select the degree of transparency\n\ +;for all inactive Scalos desktop, icon, or text windows.\n\ +;The desktop will only get transparent if it is not a backdrop window. +; +; +MSGID_WINDOWPAGE_CONTROLBAR_NORMAL_GADGETS +Schaltfelder im normalen Fenster +;Standard Window Gadgets +; +;----------------------------------------------------------- +; +; +MSGID_TEXTWINDOWSPAGE_SELECTION_BORDER_TRANSPARENCY +Durchsichtigkeit Rahmen +;Border Transparency +; +; +MSGID_TEXTWINDOWSPAGE_SELECTION_FILL_TRANSPARENCY +Durchsichtigkeit Füllung +;Fill Transparency +; +; +MSGID_TEXTWINDOWSPAGE_GROUP_BASECOLOR +Grundfarbe +;Base Color +; +; +MSGID_TEXTWINDOWSPAGE_SELECTIONMARK_BASECOLOR_SHORTHELP +Hier wird die Grundfarbe der Auswahlmarkierung\n\ +in Textfenstern eingestellt. +;Here you can adjust the base color for the\n\ +;text window icon selection marker. +; +; +MSGID_TEXTWINDOWSPAGE_SELECTIONMARK_BORDER_TRANSPARENCY_SHORTHELP +Hier wird der Grad der Durchsichtigkeit für\n\ +den Rahmen der Auswahlmarkierung in\n\ +Textfenstern eingestellt. +;Adjust degree of transparency for the border\n\ +;of the text window icon selection marker. +; +; +MSGID_TEXTWINDOWSPAGE_SELECTIONMARK_FILL_TRANSPARENCY_SHORTHELP +Hier wird der Grad der Durchsichtigkeit für\n\ +die innere Füllung der Auswahlmarkierung in\n\ +Textfenstern eingestellt. +;Adjust degree of transparency for the interior\n\ +;fill of the text window icon selection marker. +; +; +MSGID_TEXTWINDOWPAGE_DRAWERSORT_TOP +vor Dateien +;Before Files +; +; +MSGID_TEXTWINDOWPAGE_DRAWERSORT_BOTTOM +nach Dateien +;After files +; +; +MSGID_TEXTWINDOWPAGE_DRAWERSORT_MIXED +zwischen Dateien +;With files +; +; +MSGID_TEXTWINDOWSPAGE_DRAWERSORT +Schubladen anzeigen: +;Drawer sorting: +; +; +MSGID_TEXTWINDOWSPAGE_DRAWERSORT_SHORTHELP +Wo sollen Schubladen in Textfenstern angezeigt werden?\n\ +Schubladen können vor allen Dateien, nach allen Dateien\n\ +oder zwischen den Dateien angezeigt werden. +;Select how drawers are sorted in text windows.\n\ +;Drawers can be displayed always on top, always\n\ +;on bottom, or mixed between files. +; +;----------------------------------------------------------- +; +MSGID_FILEDISPLAYPAGE_FONT +Schrift: +;Font: +; +; +MSGID_FILEDISPLAYPAGE_FONT_SHORTHELP +Auswahl der Schrift für Scalos Textfenster.\n\ +;Select font to display text window contents.\n\ +Diese Auswahl is deaktiviert, solange\n\ +die Verwendung von TrueType Schriften\n\ +in Textfenstern eingeschaltet ist. +;This selection is disabled while TrueType\n\ +;text window fonts are enabled. +; +; +MSGID_FILEDISPLAYPAGE_FONT_ASLTITLE +Bitte wählen Sie eine Schrift... +;Please select a font... +; +; +MSGID_FILEDISPLAYPAGE_FONT_EXAMPLE +Beispiel: +;Example: +; +; +MSGID_FILEDISPLAYPAGE_FONT_SAMPLETEXT +Dies ist ein Beispiel für\n\ +die ausgewählte Schrift. +;This is an example text to visualize\n\ +;what the selected font looks like +; +; +MSGID_FILEDISPLAYPAGE_SOFTLINKS_UNDERLINED +Namen für weiche Verknüpfungen \033uunterstreichen\033n: +;Display soft-link file names \033uunderlined\033n: +; +; +MSGID_FILEDISPLAYPAGE_SOFTLINKS_UNDERLINED_SHORTHELP +Wenn dieser Schalter eingeschaltet ist, werden\n\ +die Namen von weichen Verknüpfungen \033uunterstrichen\033n. +;When this item is checked, names of soft-links\n\ +;are displayed \033uunderlined\033n. +; +; +MSGID_FILEDISPLAYPAGE_HIDE_HIDDENFILES +Versteckte Dateien unterdrücken: +;Hide hidden files: +; +; +MSGID_FILEDISPLAYPAGE_HIDE_HIDDENFILES_SHORTHELP +Versteckt sind Dateien mit einem Namen, der mit \"\033b.\033n\"\n\ +anfängt, oder Piktogramme \"\033b#?.info\033n\" +;A hidden file is any filename beginning with\n\ +;a '\033b.\033n' or icon files '\033b#?.info\033n' +; +; +MSGID_FILEDISPLAYPAGE_AVAILABLE_COLUMNS +Verfügbare Spalten +;Available Columns +; +; +MSGID_FILEDISPLAYPAGE_AVAILABLE_COLUMNS_SHORTHELP +Diese Spalten werden momentan in Textfenstern\n\ +nicht angezeigt. Wenn Sie eine Spalte anzeigen\n\ +wollen, ziehen Sie sie einfach in die\n\ +Liste \"Angezeigte Spalten\". +;This are the columns currently not displayed\n\ +;in text windows. If you want some item to be\n\ +;displayed, drag it to the \"Displayed columns\" list. +; +; +MSGID_FILEDISPLAYPAGE_COLUMNS_INUSE +Angezeigte Spalten +;Displayed Columns +; +; +MSGID_FILEDISPLAYPAGE_COLUMNS_INUSE_SHORTHELP +Diese Spalten werden momentan in Textfenstern\n\ +angezeigt. Wenn Sie eine Spalte weglassen wollen,\n\ +ziehen Sie sie einfach in die\n\ +Liste \"Verfügbare Spalten\". +;This are the columns that will display in text\n\ +;windows. You may change the display order by\n\ +;drag-sorting the lines. If you want some item\n\ +;not to be displayed, drag it to\n\ +;the \"Available columns\" list. +; +; +MSGID_FILEDISPLAYPAGE_STRIPED +Gestreifte Anzeige: +;Striped Display +; +; +MSGID_FILEDISPLAYPAGE_STRIPED_SHORTHELP +Zur besseren Lesbarkeit wird jede zweite Zeile\n\ +in einem Textfenster in anderer Farbe angezeigt.\n\ +Diese Funktion kann nur genutzt werden, wenn der\n\ +Workbench-Bildschirm mehr als 256 Farben darstellen kann. +;Shows every other line in text window\n\ +;in different color, to improve readability.\n\ +;Please note that striped display is only available\n\ +;if your desktop screen has more than 256 colors. +; +; +MSGID_FILEDISPLAYPAGE_HIDE_PROTECTHIDDENFILES +Dateien mit \033bHidden\033n Statusbit unterdrücken: +; Hide files with protect bit hidden: +; +; +MSGID_FILEDISPLAYPAGE_HIDE_PROTECTHIDDENFILES_SHORTHELP +Wenn eingeschaltet, werden Dateien mit gesetztem\n\ +\"Hidden\" Statusbit (\033bH\033nSPARWED) nicht angezeigt. +; If checked, any file with the hidden protection\n\ +; bit(\033bH\033nSPARWED) activated, will be hidden. +; +; +MSGID_FILEDISPLAYPAGE_SELECTTEXTICONNAME +Textpiktogramme wählbar über Namen +; Name column selects text icons +; +; +MSGID_FILEDISPLAYPAGE_SELECTTEXTICONNAME_SHORTHELP +Wenn eingeschaltet, können Textpiktogramme nur\n\ +in der Spalte \033bNamen\033n ausgewählt werden.\n\ +Ist ausgeschaltet, kann die gesamte Zeile\n\ +zur Auswahl genutzt werden. +;If this checkmark is checked, text icons can\n\ +;only be selected within the \033bname\033n column.\n\ +;If unchecked, the entire row can be used\n\ +;to select the icon. +; +;----------------------------------------------------------- +; +MSGID_TTFONTSPAGE_SCREENFONT +TrueType Bildschirmschrift +;TrueType Screen Font +; +; +MSGID_TTFONTSPAGE_SCREENFONT_ENABLE +TT Bildschirm benutzen: +;Use TT Screen Font: +; +; +MSGID_TTFONTSPAGE_SCREENFONT_ENABLE_SHORTHELP +Wenn dieser Schalter eingeschaltet ist, benutzt\n\ +eine Scalos TT Schrift als Bildschirmschrift. +;??? +; +; +MSGID_TTFONTSPAGE_SCREENFONT_SHORTHELP +Dies ist die Beschreibung der TrueType-Schrift für\n\ +die Bildschirmschrift, bestehend aus (Stil/Gewicht/Größe/Name). +;??? +; +; +MSGID_TTFONTSPAGE_ICONFONT +TrueType Piktogrammschrift +;TrueType Icon Font +; +; +MSGID_TTFONTSPAGE_ICONFONT_ENABLE +TrueType-Schrift für Piktogramme benutzen: +;Use TT Icon Font: +; +; +MSGID_FONTSPAGE_TTFICONFONT_ENABLE_SHORTHELP +Wenn dieser Schalter eingeschaltet ist, benutzt\n\ +Scalos TT Schriften für alle Piktogramme. +;When this item is checked, Scalos\n\ +;uses TrueType fonts for icons. +; +; +MSGID_TTFONTSPAGE_ICONFONT_SHORTHELP +Dies ist die Beschreibung der TrueType-Schrift für\n\ +Piktogramme, bestehend aus (Stil/Gewicht/Größe/Name). +;This is the textual TrueType icon font\n\ +;specification (style/weight/size/name). +; +; +MSGID_TTFONTSPAGE_TEXTWINDOWFONT +TrueType Textfensterschrift +;TrueType Text Window Font +; +; +MSGID_TTFONTSPAGE_TTFTEXTWINDOWFONT_ENABLE +TT für Textfenster benutzen: +;Use TT Text Window Font: +; +; +MSGID_TTFONTSPAGE_TTFTEXTWINDOWFONT_ENABLE_SHORTHELP +When dieser Schalter eingeschaltet ist, benutzt\n\ +Scalos TT Schriften für alle Textfenster. +;When this item is checked, Scalos uses\n\ +;TrueType fonts for text windows. +; +; +MSGID_TTFONTSPAGE_TEXTWINDOWFONT_SHORTHELP +Dies ist die Beschreibung der TrueType-Schrift für\n\ +Textfenster, bestehend aus (Stil/Gewicht/Größe/Name). +;This is the textual TrueType text window\n\ +;font specification (style/weight/size/name). +; +; +MSGID_TTFONTSPAGE_SAMPLETEXT +Franz jagt im komplett verwahrlosten Taxi quer durch Bayern +;The quick brown fox jumps over the lazy dog +; +; +MSGID_TTFONTSPAGE_SCREENFONT_SAMPLETEXT_SHORTHELP +Dies ist ein Beispiel für die\n\ +ausgewählte TrueType Bildschirmschrift. +;This is an example text to visualize what the\n\ +;selected TrueType screen font looks like. +; +; +MSGID_TTFONTSPAGE_ICONFONT_SAMPLETEXT_SHORTHELP +Dies ist ein Beispiel für die ausgewählte\n\ +TrueType Piktogrammschrift. +;This is an example text to visualize what the\n\ +;selected TrueType icon font looks like. +; +; +MSGID_TTFONTSPAGE_TEXTWINDOWFONT_SAMPLETEXT_SHORTHELP +Dies ist ein Beispiel für die ausgewählte\n\ +TrueType Textfensterschrift. +;This is an example text to visualize what the\n\ +;selected TrueType text window font looks like. +; +; +MSGID_TTFONTSPAGE_SELECTSCREENFONT_ASLTITLE +TT Schrift für Bildschirm auswählen... +;Select Screen TT Font... +; +; +MSGID_TTFONTSPAGE_SELECTICONFONT_ASLTITLE +TT Schrift für Piktogramme auswählen... +;Select Icon TT Font... +; +; +MSGID_TTFONTSPAGE_SELECTTEXTWINDOWFONT_ASLTITLE +TT Schrift für Textfenster auswählen... +;Select Text Window TT Font... +; +; +MSGID_TTFONTSPAGE_SELECTFONT_ASL_OKBUTTON +Ok +;Ok +; +; +MSGID_TTFONTSPAGE_SELECTFONT_ASL_CANCELBUTTON +Abbruch +;Cancel +; +; +MSGID_TTFONTSPAGE_GLOBALS +Allgemeine Werte +;Globals +; +; +MSGID_TTFONTSPAGE_ANTIALIASING +Antialiasing: +;Antialiasing: +; +; +MSGID_TTFONTSPAGE_ANTIALIASING_SHORTHELP +Scahltet das Anti-Aliasing für die TrueType-Schriften\n\ +ein, aus, oder auf Automatikbetrieb.\n\ +Aus - Anti-Aliasing ist immer aus.\n\ +Ein - Anti-Aliasing ist immer an.\n\ +Auto (Standard) - Anti-Aliasing wird abhängig von\n\ +der Schriftgröße angewandt. Typischerweise werden\n\ +Schriften von mehr als 20 Punkt Größe mit Anti-Aliasing\n\ +dargestellt. Diese Schwellwerte können über der Voreinsteller\n\ +der TrueType-Schriften konfiguriert werden. +;Controls ttengine antialiasing (on, off or automatic):\n\ +;Off - turns antialias off\n\ +;On - turns antialias on\n\ +;Auto (default) - antialias state depends on font\n\ +;size. Typically sizes of 9 or less pixels are\n\ +;antialiased, sizes from 10 to 19 pixels are not\n\ +;antialiased, sizes of 20 of more pixels are\n\ +;antialiased. These settings can be changed in the\n\ +;ttengine font database separately for every font face. +; +; +MSGID_TTFONTSPAGE_ANTIALIASING_ON +Ein +;On +; +; +MSGID_TTFONTSPAGE_ANTIALIASING_OFF +Aus +;Off +; +; +MSGID_TTFONTSPAGE_ANTIALIASING_AUTO +Auto +;Auto +; +; +MSGID_TTFONTSPAGE_GAMMA +Gamma-Korrektur: +;Gamma correction: +; +; +MSGID_TTFONTSPAGE_GAMMA_SHORTHELP +Einstellbare Gammakorrektur für das Anti-Aliasing\n\ +der TrueType fonts. Nach dem RGB Alpha-Blending wird\n\ +die Gammakorrektur auf die resultierenden Pixel nach\n\ +der Formel x' = x ^ 1/Gamma angewandt, wobei x\n\ +eine RGB Komponente ist. +;Adjustable gamma correction used for ttengine\n\ +;antialiasing. After RGB alphablending gamma\n\ +;correction is applied to resulting pixel colour\n\ +;according to x' = x ^ 1/gamma, where x\n\ +;is a RGB component. +; +;----------------------------------------------------------- +; +MSGID_MISCPAGE_MENU_CURRENTDIR +Menü akt. Dir.: +;Menu CurrentDir: +; +; +MSGID_MISCPAGE_MENU_CURRENTDIR_SHORTHELP +Wenn eingeschaltet, wechselt Scalos beim Auswählen\n\ +eines Menüpunktes vor dem Ausführen eines\n\ +CLI-Programmes in das Verzeichnis dieses Programms. +;If enabled, Scalos changes to the directory of\n\ +;the CLI tool before running a CLI menu command. +; +; +MSGID_MISCPAGE_HARD_EMULATION +Harte Emulation: +;Hard emulation: +; +; +MSGID_MISCPAGE_HARD_EMULATION_SHORTHELP +Wenn eingeschaltet, hängt sich Scalos in einige\n\ +zusätzliche Workbench-Funktionsvektoren ein.\n\ +Normalerweise sollte es keinen Grund geben,\n\ +\033bHarte Emulation\033n auszuschalten. +;If this item is checked, some additional Workbench\n\ +;function vectors are patched by Scalos. In most\n\ +;cases, there shouldn't be any reason to\n\ +;turn off \"Hard emulation\". +; +; +MSGID_MISCPAGE_USE_EXALL +Benutze ExAll: +;Use ExAll(): +; +; +MSGID_MISCPAGE_USE_EXALL_SHORTHELP +Wenn eingeschaltet, versucht Scalos, die \033bExAll()\33n\n\ +Funktion zum Durchsuchen von Verzeichnissen zu verwenden.\n\ +Normalerweise erkennt Scalos automatisch, wenn ein\n\ +Dateisystem diese Funktion nicht unterstützt,\n\ +und benutzt dann eine langsamere Methode.\n\ +Es kann aber Dateisysteme geben, die \033bExAll()\33n\n\ +nicht vestehen, aber keinen Fehler melden\n\ +oder sogar abstürzen.\n\ +Wenn Sie das Pech haben, so ein Dateisystem zu haben,\n\ +sollten Sie \033bBenutze ExAll\033n abschalten. +;If this item is checked, Scalos will try to use\n\ +;the \"ExAll()\" function to scan directories.\n\ +;Usually, if a file system doesn't support ExAll(),\n\ +;there is a fully automatic fall-back to other\n\ +;functions. However, there might be some file systems\n\ +;that don't support ExAll() but don't return\n\ +;appropriate error codes either, or even crash.\n\ +;If you happen to have such a file system, try to\n\ +;turn \"Use ExAll()\" off. +; +; +MSGID_MISCPAGE_POPUPMENUS +Popup-Menüs +;Popup menus +; +; +MSGID_MISCPAGE_POPUP_SELECTED_HOTKEY +Auf alle ausgewählten Piktogr. anwenden: +;Apply to every selected icon: +; +; +MSGID_MISCPAGE_POPUP_SELECTED_HOTKEY_SHORTHELP +Legt die Tastenkombination fest, die bewirkt, daß\n\ +ein Popupmenübefehl auf alle ausgewählten Piktogramme\n\ +angewandt wird, anstatt nur auf das Piktogramm\n\ +unter dem Mauszeiger. +;Define the qualifier key that\n\ +;applies popup menu commands to\n\ +;every selected icon.\n\ +;Normally, popup menu commands only apply\n\ +;to the icon under the mouse pointer. +; +; +MSGID_MISCPAGE_DEFAULTSTACKSIZE +Standardgröße Stack: +;Default Stack size: +; +; +MSGID_MISCPAGE_DEFAULTSTACKSIZE_SHORTHELP +Legt die Größe des Stacks für diverse interne\n\ +Scalos-Prozesse und für vom Anwender gestartete\n\ +CLI- und ARexx-Programme fest. +;Sets the stack size for most internal Scalos\n\ +;processes and for CLI and ARexx processes\n\ +;started by Scalos. +; +; +MSGID_MISCPAGE_DEFAULTSTACKSIZE_OS35 +Ab AmigaOS 3.5 wird die Größe des Stacks mit dem \ +\033bWorkbench\033n Voreinsteller verändert. +;Starting with Workbench 3.5, the default stack size \ +;is changed with the standard \ +;\033bWorkbench Preferences\033n program. +; +; +MSGID_MISCPAGE_LABELS_STACK +Stack +; +; +MSGID_MISCPAGE_CREATE_LINKS +Verknüpfungen erzeugen: +;Create links: +; +; +MSGID_MISCPAGE_CREATE_LINKS_SHORTHELP +Legt fest, welche Art von Verknüpfungen Scalos beim Ablegen\n\ +gezogener Piktogramme erzeugt, wenn die\n\ +Qualifier-Taste für "Verknüpfung erzeugen" gedrückt ist. +;Select what kind of links Scalos tries to create\n\ +;when an object is dropped with the create-link\n\ +;qualifier key pressed. +; +; +MSGID_MISCPAGE_POP_WORKBENCHPREFS_SHORTHELP +Führt den Standard \033bWorkbench Voreinsteller\033n aus. +;Launch standard \033bWorkbench Preferences\033n program. +; +; +; +MSGID_MISCPAGE_POPUP_SELECTED_ALWAYS +Immer auf alle ausgewählten Piktogr. anwenden? +;Always apply to all selected icons? +; +; +MSGID_MISCPAGE_POPUP_SELECTED_ALWAYS_SHORTHELP +Wenn eingeschaltet, wirken Befehle eines Popup-Menüs\n\ +\033bimmer\033n auf alle ausgewählten Piktogramme, ohne\n\ +spezielle Tastenkombination. +;Select this checkbox to \033balways\033n apply popup menus\n\ +;to every selected icons, regardless of qualifier key +; +; +MSGID_MISCPAGE_COPYBUFFERSIZE +Puffergröße beim Kopieren: +;File Copy Buffer Size: +; +; +MSGID_MISCPAGE_COPYBUFFERSIZE_SHORTHELP +Legt die benutzte Puffergröße\n\ +beim Kopieren von Dateien fest. +;Sets the buffer size for file copying. +; +; +MSGID_MISCPAGE_LABELS_FILEOPERATIONS +Dateioperationen +;File Operations +; +; +MSGID_MISCPAGE_LABELS_UNDOSTEPS +Maximale Zahl widerrufbarer Arbeitsschritte +;Maximum Number of Undo Steps +; +; +MSGID_MISCPAGE_UNDOSTEPS +Max. Schritte: +;Max. Undo Steps: +; +; +MSGID_MISCPAGE_UNDOSTEPS_SHORTHELP +Dies ist die maximale Zahl der letzten Arbeitsschritte,\n\ +die rückgangig gemacht werden können. +;Here you can limit the number of\n\ +;available Undo/Redo steps. +; +;----------------------------------------------------------- +; +MSGID_PLUGINSPAGE_ACTIVEPLUGINS +Aktive Plugins +;Active Plugins +; +; +MSGID_PLUGINSPAGE_INSTALLEDPLUGINS +\033cInstallierte Plugins +;\033cInstalled Plugins +; +; +MSGID_PLUGINSPAGE_INSTALLEDPLUGINS_SHORTHELP +Dies ist die Liste aller OOP-Plugins, die beim Start\n\ +von Scalos geladen werden. OOP-Plugins verleihen\n\ +Scalos zusätzliche Fähigkeiten oder\n\ +verbessern vorhandene Fähigkeiten. +;This is a complete list of all OOP plugins that\n\ +;are loaded upon Scalos startup. OOP plugins add\n\ +;new features to Scalos or improve existing\n\ +;Scalos features. +; +; +MSGID_PLUGINSPAGE_ADD_NEW +\033cNeu hinzufügen +;\033cAdd New +; +; +MSGID_PLUGINSPAGE_ADD_NEW_SHORTHELP +Fügt ein neues Plugin zur Liste hinzu.\n\ +Das neue Plugin wird erst beim\n\ +nächsten Start von Scalos aktiv. +;Add a new OOP plugin to the list. This plugin\n\ +;will be activated upon next Scalos startup. +; +; +MSGID_PLUGINSPAGE_REMOVE_SELECTED +\033cAusgewähltes entfernen +;\033cRemove Selected +; +; +MSGID_PLUGINSPAGE_REMOVE_SELECTED_SHORTHELP +Entfernt das ausgewählte Plugin aus der Liste.\n\ +Scalos wird dieses Plugin beim\n\ +nächsten Start nicht mehr laden. +;Remove the currently selected plugin\n\ +;from the list. Scalos will not load the\n\ +;plugin again. This change will only become\n\ +;effective upon next Scalos startup. +; +; +MSGID_PLUGINSPAGE_NAME +\033lName: +;\033lName: +; +; +MSGID_PLUGINSPAGE_NAME_SHORTHELP +Dieser Name wurde dem Plugin\n\ +von seinem Entwickler gegeben. +;This is the name the selected plugin\n\ +;has been given by its creator. +; +; +MSGID_PLUGINSPAGE_FILENAME +\033lDatei: +;\033lFile: +; +; +MSGID_PLUGINSPAGE_FILENAME_SHORTHELP +Dies ist der vollständige Pfad und\n\ +Dateiname des ausgewählten Plugins. +;This is the complete filename and\n\ +;path for the selected plugin. +; +; +MSGID_PLUGINSPAGE_VERSION +\033lVersion: +;\033lVersion: +; +; +MSGID_PLUGINSPAGE_VERSION_SHORTHELP +Zeigt die Versionsnummer des\n\ +ausgewählten Plugins. +;This is the current version\n\ +;of the selected plugin. +; +; +MSGID_PLUGINSPAGE_DESCRIPTION +\033lBeschreibung: +;\033lDescription: +; +; +MSGID_PLUGINSPAGE_DESCRIPTION_SHORTHELP +Dies ist eine kurze Beschreibung, was\n\ +das ausgewählte Plugin bewirken soll. +;This is a description of what the\n\ +;selected plugin is supposed to do. +; +; +MSGID_PLUGINSPAGE_CREATOR +\033lEntwickler: +;\033lCreator: +; +; +MSGID_PLUGINSPAGE_CREATOR_SHORTHELP +Dies ist der Entwickler des\n\ +ausgewählten Plugins. +;This is the creator's name\n\ +;of the selected plugin. +; +; +MSGID_PLUGINSPAGE_EDIT_PREFERENCES +\033cEinstellungen ändern +;\033cEdit Preferences +; +; +MSGID_PLUGINSPAGE_EDIT_PREFERENCES_SHORTHELP +Einstellungen ändern +;\033cEdit Preferences +; +; +MSGID_ADD_PLUGIN_ASLTITLE +Neues OOP Plugin wählen... +;Select new OOP plugin... +; +;----------------------------------------------------------- +; +MSGID_MODULESPAGE_MODULE_PREFERENCES +Einstellungen für Module +;Module Preferences +; +; +MSGID_MODULESPAGE_MODULE_PREFERENCES_NOTICE +Zum Konfigurieren der Scalos module bitte auf das\n\ +Popup-Sybol rechts neben dem Namen des Moduls klicken.\n\ +Dann öffnet sich ein neues Fenster mit den\n\ +Modul-spezifischen Einstellungen.\n\ +\n\ +Wenn keine Konfiguration für ein Modul möglich ist,\n\ +ist das zugehörige Popup-Symbol gesperrt. +;To configure any Scalos modules' settings you must click on \ +;the pop-up image gadget to the right of the modules name. \ +;This will open a new window with specific settings in it.\n\ +;\n\ +;If no configuration is available for a certain module \ +;the pop-up gadget will be disabled. +; +; +MSGID_MODULESPAGE_DELETE +Delete +; +; +MSGID_MODULESPAGE_EMPTY_TRASHCAN +Empty Trashcan +; +; +MSGID_MODULESPAGE_EXECUTE_COMMAND +Execute Command +; +; +MSGID_MODULESPAGE_INFORMATION +Information +; +; +MSGID_MODULESPAGE_NEWDRAWER +New Drawer +; +; +MSGID_MODULESPAGE_REBOOT +Reboot +; +; +MSGID_MODULESPAGE_RENAME +Rename +; +; +MSGID_MODULESPAGE_SYSTEM_INFORMATION +System Information +; +;----------------------------------------------------------- +; +MSGID_SAVEBUTTON +\033cSpeichern +;\033cSave +; +; +MSGID_SAVEBUTTON_SHORTHELP +Drücken Sie diesen Knopf, um alle\n\ +Einstellungen dauerhaft in\n\ +\"ENVARC:Scalos/Scalos.prefs\"\n\ +zu speichern. +;Press this button to save \n\ +;the current settings to\n\ +;\"ENVARC:Scalos/Scalos.prefs\"\n\ +;and make changes permanent. +; +; +MSGID_USEBUTTON +\033cBenutzen +;\033cUse +; +; +MSGID_USEBUTTON_SHORTHELP +Drücken Sie diesen Knopf, um alle Einstellungen\n\ +bis zum nächsten Neustart in\n\ +\"ENV:Scalos/Scalos.prefs\"\n\ +zu speichern. +;Press this button to save \n\ +;the current settings to\n\ +;\"ENV:Scalos/menu13.prefs\"\n\ +;and keep settings until reboot. +; +; +MSGID_CANCELBUTTON +\033cAbbrechen +;\033cCancel +; +; +MSGID_CANCELBUTTON_SHORTHELP +Drücken Sie diesen Knopf, um das\n\ +Programm abzubrechen und alle\n\ +Änderungen zu verwerfen. +;Press this button to abort \n\ +;and forget all changes. +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Haupt-Voreinsteller V%ld.%ld\033n\n\ +%s\n\ +© 2003%s Das Scalos-Team +;\33c\033bScalos Main Preferences V%ld.%ld\033n\n\ +;%s\n\ +;© 2003%s The Scalos Team +; +;----------------------------------------------------------- +; +MSGID_DESKTOPPAGES_SCREENTITLE_ALWAYS +Immer anzeigen +;Always visible +; +; +MSGID_DESKTOPPAGES_SCREENTITLE_POP +Aufklappen unter Mauszeiger +;Pops up under mouse +; +; +MSGID_DESKTOPPAGES_SCREENTITLE_NEVER +Niemals anzeigen +;permanently hidden +; +;----------------------------------------------------------- +; +; +MSGID_ICONSPAGES_DRAGNDROP_DRAGGING +Ziehen/Ablegen +;Dragging +; +; +MSGID_ICONSPAGES_DRAGNDROP_TRANSPARENCY +Transparenz +;Transparency +; +; +MSGID_ICONSPAGES_DRAGNDROP_TRIGGERS +Auslöser +;Triggers +; +;----------------------------------------------------------- +; +MSGID_FRAMEWINDOW_TITLE +Verfügbare Rahmenarten +;Available Frames +; +;----------------------------------------------------------- +; +MSGID_PLUGINLIST_NAME +Name +;Name +; +; +MSGID_PLUGINLIST_PATH +Pfad +;Path +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Scalos Voreinsteller kann nicht gestartet werden +;Scalos Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Wiederholen|Beenden +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\ +Die Klasse ist nicht installiert. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Sie haben momentan Version v%lu.%lu installiert und\n\ +sollten die Klasse daher aktualisieren! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Version %lu.%lu wird momentan von einer anderen Anwendung\n\ +verwendet. Wenn sie die benötigte Version installiert haben,\n\ +schließen sie alle MUI Programme und probieren es erneut. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_ADDPLUGIN_FAILURE +Fehler beim Hinzufügen +;Add Plugin Failure +; +; +MSGID_ADDPLUGIN_OK_GAD +Ok +;Ok +; +; +MSGID_ADDPLUGIN_COULD_NOT_ADD +Plugin konnte nicht hinzugefügt werden.\n\ +Fehler beim öffnen des Plugin \"%s\". +;Could not add plugin.\n\ +;Opening the plugin failed. +; +;----------------------------------------------------------- +; +MSGID_DESKTOPPAGE_ICONS_HIDDENDEVICES +Versteckte Geräte +;Hidden Devices +; +; +MSGID_DESKTOPPAGE_HIDDENDEVICES_SHORTHELP +Hier können Sie Geräte verstecken.\n\ +Die markierten Geräte werden niemals\n\ +auf der Arbeitsfläche angezeigt.\n\ +Die gleiche Einstellung können Sie über\n\ +den OS3.9 Workbench Voreinsteller vornehmen. +;Here you can select which devices will never show up on desktop.\n\ +;This is the same setting as available in OS3.9 Workbench Prefs. +; +;----------------------------------------------------------- +; +MSGID_DESKTOPPAGE_LAYOUTPREFERENCES +Vorzugsanordnung für Piktogrammarten auf der Arbeitsfläche +;Desktop Layout Preferences by Icon Type +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBDISK +Datenträger-Piktogramme: +;Disk icons: +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBDISK_SHORTHELP +Wählen Sie hier die bevorzugte Richtung für die\n\ +automatische Anordnung von \033bDatenträger-Piktogrammen\033n\n\ +auf der Arbeitsfläche.\n\ +\033iSpaltenweise\033n ordnet Piktogramme in Spalten von\n\ +oben nach unten an. Beim Erreichen des unteren\n\ +Fensterrands wird eine neue Spalte begonnen.\n\ +\033iZeilenweise\033n ordnet Piktogramme in Zeilen von\n\ +links nach rechts an. Beim Erreichen des rechten\n\ +Fensterrands wird eine neue Zeile begonnen. +;Select preferred icon layout direction\n\ +;for \033bdisk icons\033n in desktop window.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBDRAWER +Schubladen-Piktogramme: +;Drawer icons: +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBDRAWER_SHORTHELP +Wählen Sie hier die bevorzugte Richtung für die\n\ +automatische Anordnung von \033bSchubladen-Piktogrammen\033n\n\ +auf der Arbeitsfläche.\n\ +\033iSpaltenweise\033n ordnet Piktogramme in Spalten von\n\ +oben nach unten an. Beim Erreichen des unteren\n\ +Fensterrands wird eine neue Spalte begonnen.\n\ +\033iZeilenweise\033n ordnet Piktogramme in Zeilen von\n\ +links nach rechts an. Beim Erreichen des rechten\n\ +Fensterrands wird eine neue Zeile begonnen. +;Select preferred icon layout direction\n\ +;for \033bdrawer icons\033n in desktop window.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBTOOL +Werkzeug-Piktogramme: +;Tool icons: +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBTOOL_SHORTHELP +Wählen Sie hier die bevorzugte Richtung für die\n\ +automatische Anordnung von \033bWerkzeug-Piktogrammen\033n\n\ +auf der Arbeitsfläche.\n\ +\033iSpaltenweise\033n ordnet Piktogramme in Spalten von\n\ +oben nach unten an. Beim Erreichen des unteren\n\ +Fensterrands wird eine neue Spalte begonnen.\n\ +\033iZeilenweise\033n ordnet Piktogramme in Zeilen von\n\ +links nach rechts an. Beim Erreichen des rechten\n\ +Fensterrands wird eine neue Zeile begonnen. +;Select preferred icon layout direction\n\ +;for \033btool icons\033n in desktop window.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBPROJECT +Projekt-Piktogramme: +;Project icons: +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBPROJECT_SHORTHELP +Wählen Sie hier die bevorzugte Richtung für die\n\ +automatische Anordnung von \033bProjekt-Piktogrammen\033n\n\ +auf der Arbeitsfläche.\n\ +\033iSpaltenweise\033n ordnet Piktogramme in Spalten von\n\ +oben nach unten an. Beim Erreichen des unteren\n\ +Fensterrands wird eine neue Spalte begonnen.\n\ +\033iZeilenweise\033n ordnet Piktogramme in Zeilen von\n\ +links nach rechts an. Beim Erreichen des rechten\n\ +Fensterrands wird eine neue Zeile begonnen. +;Select preferred icon layout direction\n\ +;for \033bproject icons\033n in desktop window.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBGARBAGE +Papierkorb-Piktogramme: +;Trashcan icons: +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBGARBAGE_SHORTHELP +Wählen Sie hier die bevorzugte Richtung für die\n\ +automatische Anordnung von \033bPapierkorb-Piktogrammen\033n\n\ +auf der Arbeitsfläche.\n\ +\033iSpaltenweise\033n ordnet Piktogramme in Spalten von\n\ +oben nach unten an. Beim Erreichen des unteren\n\ +Fensterrands wird eine neue Spalte begonnen.\n\ +\033iZeilenweise\033n ordnet Piktogramme in Zeilen von\n\ +links nach rechts an. Beim Erreichen des rechten\n\ +Fensterrands wird eine neue Zeile begonnen. +;Select preferred icon layout direction\n\ +;for \033btrashcan icons\033n in desktop window.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBDEVICE +Geräte-Piktogramme: +;Device icons: +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBDEVICE_SHORTHELP +Wählen Sie hier die bevorzugte Richtung für die\n\ +automatische Anordnung von \033bGeräte-Piktogrammen\033n\n\ +auf der Arbeitsfläche.\n\ +\033iSpaltenweise\033n ordnet Piktogramme in Spalten von\n\ +oben nach unten an. Beim Erreichen des unteren\n\ +Fensterrands wird eine neue Spalte begonnen.\n\ +\033iZeilenweise\033n ordnet Piktogramme in Zeilen von\n\ +links nach rechts an. Beim Erreichen des rechten\n\ +Fensterrands wird eine neue Zeile begonnen. +;Select preferred icon layout direction\n\ +;for \033bdevice icons\033n in desktop window.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBKICK +Kickstart-Disk-Piktogramme: +;Kickstart Disk icons: +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBKICK_SHORTHELP +Wählen Sie hier die bevorzugte Richtung für die\n\ +automatische Anordnung von \033bKickstart-Disk-Piktogrammen\033n\n\ +auf der Arbeitsfläche.\n\ +\033iSpaltenweise\033n ordnet Piktogramme in Spalten von\n\ +oben nach unten an. Beim Erreichen des unteren\n\ +Fensterrands wird eine neue Spalte begonnen.\n\ +\033iZeilenweise\033n ordnet Piktogramme in Zeilen von\n\ +links nach rechts an. Beim Erreichen des rechten\n\ +Fensterrands wird eine neue Zeile begonnen. +;Select preferred icon layout direction\n\ +;for \033bkickstart disk icons\033n in desktop window.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBAPPICON +Anwendungs-Piktogramme: +;Application icons: +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBAPPICON_SHORTHELP +Wählen Sie hier die bevorzugte Richtung für die\n\ +automatische Anordnung von \033bAnwendungs-Piktogrammen\033n\n\ +auf der Arbeitsfläche.\n\ +\033iSpaltenweise\033n ordnet Piktogramme in Spalten von\n\ +oben nach unten an. Beim Erreichen des unteren\n\ +Fensterrands wird eine neue Spalte begonnen.\n\ +\033iZeilenweise\033n ordnet Piktogramme in Zeilen von\n\ +links nach rechts an. Beim Erreichen des rechten\n\ +Fensterrands wird eine neue Zeile begonnen. +;Select preferred icon layout direction\n\ +;for \033bapplication icons\033n in desktop window.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +;----------------------------------------------------------- +; +MSGID_ICONSPAGE_LAYOUTPREFERENCES +Vorzugsanordnung für Piktogrammarten +;Layout Preferences by Icon Type +; +; +MSGID_ICONSPAGE_LAYOUT_WBDRAWER +Schubladen-Piktogramme: +;Drawer icons: +; +; +MSGID_ICONSPAGE_LAYOUT_WBDRAWER_SHORTHELP +Wählen Sie hier die bevorzugte Richtung für die\n\ +automatische Anordnung von \033bSchubladen-Piktogrammen\033n\n\ +in Standardfenstern.\n\ +\033iSpaltenweise\033n ordnet Piktogramme in Spalten von\n\ +oben nach unten an. Beim Erreichen des unteren\n\ +Fensterrands wird eine neue Spalte begonnen.\n\ +\033iZeilenweise\033n ordnet Piktogramme in Zeilen von\n\ +links nach rechts an. Beim Erreichen des rechten\n\ +Fensterrands wird eine neue Zeile begonnen. +;Select preferred icon layout direction\n\ +;for \033bdrawer icons\033n in icon windows.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +; +MSGID_ICONSPAGE_LAYOUT_WBTOOL +Werkzeug-Piktogramme: +;Tool icons: +; +; +MSGID_ICONSPAGE_LAYOUT_WBTOOL_SHORTHELP +Wählen Sie hier die bevorzugte Richtung für die\n\ +automatische Anordnung von \033bWerkzeug-Piktogrammen\033n\n\ +in Standardfenstern.\n\ +\033iSpaltenweise\033n ordnet Piktogramme in Spalten von\n\ +oben nach unten an. Beim Erreichen des unteren\n\ +Fensterrands wird eine neue Spalte begonnen.\n\ +\033iZeilenweise\033n ordnet Piktogramme in Zeilen von\n\ +links nach rechts an. Beim Erreichen des rechten\n\ +Fensterrands wird eine neue Zeile begonnen. +;Select preferred icon layout direction\n\ +;for \033btool icons\033n in icon windows.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +; +MSGID_ICONSPAGE_LAYOUT_WBPROJECT +Projekt-Piktogramme: +;Project icons: +; +; +MSGID_ICONSPAGE_LAYOUT_WBPROJECT_SHORTHELP +Wählen Sie hier die bevorzugte Richtung für die\n\ +automatische Anordnung von \033bProjekt-Piktogrammen\033n\n\ +in Standardfenstern.\n\ +\033iSpaltenweise\033n ordnet Piktogramme in Spalten von\n\ +oben nach unten an. Beim Erreichen des unteren\n\ +Fensterrands wird eine neue Spalte begonnen.\n\ +\033iZeilenweise\033n ordnet Piktogramme in Zeilen von\n\ +links nach rechts an. Beim Erreichen des rechten\n\ +Fensterrands wird eine neue Zeile begonnen. +;Select preferred icon layout direction\n\ +;for \033bproject icons\033n in icon windows.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +;----------------------------------------------------------- +; +; +MSGID_SCPGADGETTYPE_BACKBUTTON +Rückwärtsknopf +;Back Button +; +; +MSGID_SCPGADGETTYPE_FORWARDBUTTON +Vorwärtsknopf +;Forward Button +; +; +MSGID_SCPGADGETTYPE_UPBUTTON +Aufwärtsknopf +;Up Button +; +; +MSGID_SCPGADGETTYPE_HISTORY +Verlauf-Knopf +;History Button +; +; +MSGID_SCPGADGETTYPE_BROWSEBUTTON +Durchsuchen-Knopf +;Browse Button +; +; +MSGID_SCPGADGETTYPE_VIEWBY +Schalter für Anzeigeformen +;View By Cycle +; +; +MSGID_SCPGADGETTYPE_SHOWMODE +Schalter für Anzeigeart +;Show Mode Cycle +; +; +MSGID_SCPGADGETTYPE_SEPARATOR +(Zwischenraum) +;(Separator) +; +; +MSGID_SCPGADGETTYPE_ACTIONBUTTON +Benutzerdefiniert +;User-defined Button +; +; +MSGID_SCPGADGETTYPE_UNKNOWN +??unbekannt?? +;??unknown?? +; +;----------------------------------------------------------- +; +MSGID_COM1NAME +Als Hintergrund +; +; +MSGID_COM2NAME +Programm ausführen +; +; +MSGID_COM3NAME +Alles neuzeichnen +; +; +MSGID_COM4NAME +Alles neu laden +; +; +MSGID_COM5NAME +Über Scalos +; +; +MSGID_COM6NAME +Beenden +; +; +MSGID_COM7NAME +Neue Schublade +; +; +MSGID_COM8NAME +Mutterverzeichnis öffnen +; +; +MSGID_COM9NAME +Fenster schließen +; +; +MSGID_COM10NAME +Neuladen +; +; +MSGID_COM11NAME +Inhalt anwählen +; +; +MSGID_COM12NAME +Inhalt aufräumen +; +; +MSGID_COM13NAME +Fenster fixieren +; +; +MSGID_COM14NAME +Alles fixieren +; +; +MSGID_COM15NAME +Nur Piktogramme anzeigen +; +; +MSGID_COM16NAME +Alle Dateien anzeigen +; +; +MSGID_COM17NAME +Als Piktogramm anzeigen +; +; +MSGID_COM18NAME +Mit Namen anzeigen +; +; +MSGID_COM19NAME +Öffnen +; +; +MSGID_COM20NAME +Scalos neustarten +; +; +MSGID_COM21NAME +Umbenennen +; +; +MSGID_COM22NAME +Information +; +; +MSGID_COM23NAME +Fixieren +; +; +MSGID_COM24NAME +Fixierung aufheben +; +; +MSGID_COM25NAME +Auslagern +; +; +MSGID_COM26NAME +Zurücklegen +; +; +MSGID_COM27NAME +Löschen +; +; +MSGID_COM28NAME +Duplizieren +; +; +MSGID_COM29NAME +Papierkorb leeren +; +; +MSGID_COM30NAME +Letzte Meldung +; +; +MSGID_COM31NAME +Neuzeichnen +; +; +MSGID_COM32NAME +Iconifizieren +; +; +MSGID_COM33NAME +Disk formatieren... +; +; +MSGID_COM34NAME +Herunterfahren... +; +; +MSGID_COM35NAME +Größe anpassen +; +; +MSGID_COM36NAME +Auswahl löschen +;Clear Selection +; +; +MSGID_COM37NAME +Inhalt auflisten nach Größe +; +; +MSGID_COM38NAME +Inhalt auflisten nach Datum +; +; +MSGID_COM39NAME +Datei kopieren +; +; +MSGID_COM40NAME +Datei ausschneiden +; +; +MSGID_COM41NAME +Datei einfügen +; +; +MSGID_COM42NAME +Inhalt auflisten nach Art +; +; +MSGID_COM43NAME +Inhalt aufräumen nach Namen +; +; +MSGID_COM44NAME +Inhalt aufräumen nach Datum +; +; +MSGID_COM45NAME +Inhalt aufräumen nach Größe +; +; +MSGID_COM46NAME +Inhalt aufräumen nach Art +; +; +MSGID_COM_ICONPROPERTIES +Piktogramm-Eigenschaften +;Icon properties +; +; +MSGID_COM_WINDOWPROPERTIES +Fenster-Eigenschaften +;Window properties +; +; +MSGID_COM47NAME +Inhalt auflisten nach Standard +;View By - Default +; +; +MSGID_COM48NAME +Anzeigen nach Standard +;Show - Default +; +; +MSGID_COM49NAME +Kopieren nach... +;Copy to... +; +; +MSGID_COM50NAME +Verschieben nach... +;Move to... +; +; +MSGID_COM51NAME +Miniaturansicht erzeugen +;Create thumbnail +; +; +MSGID_COM_OPENNEWWINDOW +In neuem Fenster öffnen +;Open in new window +; +; +MSGID_COM_THUMBNAILCACHECLEANUP +Miniaturansicht-Zwischenspeicher aufräumen +;Cleanup thumbnail cache +; +;----------------------------------------------------------- +; diff --git a/scalos/Prefs/MainPrefs/Catalogs/deutsch/Scalos/config.mk b/scalos/Prefs/MainPrefs/Catalogs/deutsch/Scalos/config.mk new file mode 100755 index 000000000..33e6f409a --- /dev/null +++ b/scalos/Prefs/MainPrefs/Catalogs/deutsch/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2011-08-08 18:52:39 +0200 (Mo, 08. Aug 2011) $ +# $Revision: 826 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = deutsch + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = german + +else + +############################################################################### +# AmigaOS and AROS + +LANG = deutsch + +endif +endif diff --git a/scalos/Prefs/MainPrefs/Catalogs/deutsch/Scalos/makefile-new b/scalos/Prefs/MainPrefs/Catalogs/deutsch/Scalos/makefile-new new file mode 100755 index 000000000..9c64d6dc3 --- /dev/null +++ b/scalos/Prefs/MainPrefs/Catalogs/deutsch/Scalos/makefile-new @@ -0,0 +1,30 @@ +# makefile for FileTypes (translated Texts : deutsch) +# $Date: 2011-08-08 18:52:39 +0200 (Mo, 08. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = Scalos_Prefs + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git "a/scalos/Prefs/MainPrefs/Catalogs/fran\303\247ais/Scalos/Makefile" "b/scalos/Prefs/MainPrefs/Catalogs/fran\303\247ais/Scalos/Makefile" new file mode 100644 index 000000000..98beb99e9 --- /dev/null +++ "b/scalos/Prefs/MainPrefs/Catalogs/fran\303\247ais/Scalos/Makefile" @@ -0,0 +1,13 @@ +# makefile for Scalos_Prefs (translated Texts : français) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mfrançais\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +Scalos_Prefs.catalog : Scalos_Prefs.ct ../../../Scalos_Prefs.cd + +All: Scalos_Prefs.catalog diff --git "a/scalos/Prefs/MainPrefs/Catalogs/fran\303\247ais/Scalos/Scalos_Prefs.ct" "b/scalos/Prefs/MainPrefs/Catalogs/fran\303\247ais/Scalos/Scalos_Prefs.ct" new file mode 100755 index 000000000..4fd5ff437 --- /dev/null +++ "b/scalos/Prefs/MainPrefs/Catalogs/fran\303\247ais/Scalos/Scalos_Prefs.ct" @@ -0,0 +1,3677 @@ +; ScalosPrefs.ct +; $Date$ +; $Revision$ +; $Id$ +; +## version $VER: Scalos_Prefs.catalog 40.28 (28 Mar 2010 19:20:49) +## codeset 0 +## language français +; +MSGID_MENU_PROJECT_OPEN +Ouvrir... +; Open... +; +MSGID_MENU_PROJECT_OPEN_SHORT +O +; O +; +MSGID_MENU_PROJECT_OPEN_ASLTITLE +Ouvrir un fichier préferences... +; Open Scalos Prefs... +; +MSGID_MENU_PROJECT_SAVEAS +Sauver les préferences sous... +; Save As... +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +A +; A +; +MSGID_MENU_PROJECT_SAVEAS_ASLTITLE +Scalos Prefs : Sauver les préferences... +; Save Scalos Prefs As... +; +MSGID_MENU_PROJECT_ABOUT +A propos... +; About... +; +MSGID_MENU_PROJECT_QUIT +Quitter +; Quit +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; Q +; +MSGID_MENU_PROJECT +Projet +; Project +; +MSGID_MENU_EDIT_LASTSAVED +Dernière sauvegarde +; Last Saved +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +L +; L +; +MSGID_MENU_EDIT +Edition +; Edit +; +MSGID_MENU_SETTINGS_CREATEICONS +Créer les icônes ? +; Create Icons? +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +I +; I +; +MSGID_MENU_SETTINGS +Options +; Settings +; +MSGID_MENU_EDIT_RESETTODEFAULTS +Réglages par défaut +; Reset To Defaults +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +D +; D +; +MSGID_MENU_EDIT_RESTORE +Restaurer +; Restore +; +MSGID_MENU_EDIT_RESTORE_SHORT +R +; R +; +MSGID_MENU_PROJECT_ABOUTMUI +A propos de MUI... +; About MUI... +; +MSGID_MENU_PROJECT_ABOUTMORPHOS +A propos de MorphOS... +;About MorphOS... +; +MSGID_FILEDISP_COLUMN_NAME +Nom +; Name +; +MSGID_FILEDISP_COLUMN_SIZE +Taille +; Size +; +MSGID_FILEDISP_COLUMN_PROT +Droits d'accès +; Protection bits +; +MSGID_FILEDISP_COLUMN_DATE +Date +; Date +; +MSGID_FILEDISP_COLUMN_TIME +Heure +; Time +; +MSGID_FILEDISP_COLUMN_COMMENT +Commentaire +; Comment +; +MSGID_FILEDISP_COLUMN_VERSION +Version +; Version +; +MSGID_FILEDISP_COLUMN_FILETYPE +Type de fichier +; Filetype +; +MSGID_FILEDISP_COLUMN_OWNER +Propriètaire +; Owner +; +MSGID_FILEDISP_COLUMN_GROUP +Groupe +; Group +; +MSGID_FILEDISP_COLUMN_ICON +Icône +;Icon +; +;----------------------------------------------------------- +; +MSGID_PRECISION_EXACT +Exacte +; Exact +; +MSGID_PRECISION_IMAGE +Image +; Image +; +MSGID_PRECISION_ICON +Icône +; Icon +; +MSGID_PRECISION_GUI +GUI +; GUI +; +;----------------------------------------------------------- +; +MSGID_THUMBNAILS_LIFETIME_FOREVER +jamais +;never +; +;----------------------------------------------------------- +; +MSGID_PREFGROUPS_SHORTHELP +Sélectionnez une des catégories des préférences. +; Select one of the preferences categories +; +MSGID_PREFGROUPS_ABOUT +A propos de Scalos +;About Scalos +; +MSGID_PREFGROUPS_PATHS +Chemins +;Paths +; +MSGID_PREFGROUPS_STARTUP +Démarrage +;Startup +; +MSGID_PREFGROUPS_DESKTOP +Bureau +;Desktop +; +MSGID_PREFGROUPS_ICONS +Icônes +;Icons +; +MSGID_PREFGROUPS_WINDOWS +Fenêtres +;Windows +; +MSGID_PREFGROUPS_MISC +Divers +;Miscellaneous +; +MSGID_PREFGROUPS_PLUGINS +Plugins +;Plugins +; +MSGID_PREFGROUPS_MODULES +Modules +;Modules +; +MSGID_PREFGROUPS_DRAGNDROP +Déplacer et déposer +;Drag and Drop +; +; +MSGID_PREFGROUPS_TRUETYPEFONTS +Police TrueType +;TrueType Fonts +; +MSGID_PREFGROUPS_TEXTWINDOWS +Fenêtres en mode texte +;Text Windows +; +;----------------------------------------------------------- +; +MSGID_DESKTOPPAGES_SCREEN +Ecran +;Screen +; +MSGID_DESKTOPPAGES_ICONS +Icônes +;Icons +; +MSGID_ICONPAGES_MISC +Divers +;Miscellaneous +; +MSGID_DESKTOPPAGES_LAYOUT +Disposition +;Layout +; +;----------------------------------------------------------- +; +MSGID_ICONPAGES_BORDERS +Bords +; Borders +; +MSGID_ICONPAGES_LABELS +Etiquettes +; Labels +; +MSGID_ICONPAGES_ATRIBUTES +Attributs +; Attributes +; +MSGID_ICONPAGES_TOOLTIPS +Bulle d'informations +; Tooltips +; +MSGID_ICONPAGES_THUMBNAILS +Vignettes +;Thumbnails +; +MSGID_ICONPAGES_SIZES +Tailles +;Sizes +; +;----------------------------------------------------------- +; +MSGID_TITLEPLACEHOLDER_KICKSTART_RELEASE +%os|Kickstart(Ex: 3.1) +; %os|Kickstart release (e.g. 3.1) +; +MSGID_TITLEPLACEHOLDER_KICKSTART_VERSION +%ov|Version du Kickstart(Ex: 40.68) +; %ov|Kickstart version (e.g. 40.68) +; +MSGID_TITLEPLACEHOLDER_SCALOS_RELEASE +%wb|Scalos réalisation(Ex: 1.2d) +; %wb|Scalos release (e.g. 1.2d) +; +MSGID_TITLEPLACEHOLDER_SCALOS_VERSION +%wv|Version de Scalos(Ex: 39.220) +; %wv|Scalos version (e.g. 39.220) +; +MSGID_TITLEPLACEHOLDER_FREE_CHIP_MEM +%fc|Mémoire graphique libre en octets +; %fc|Free chip RAM in bytes +; +MSGID_TITLEPLACEHOLDER_FREE_FAST_MEM +%ff|Autre mémoire libre en octets +; %ff|Free fast RAM in bytes +; +MSGID_TITLEPLACEHOLDER_FREE_MEM +%ft|Mémoire globale libre en octets +; %ft|Total free RAM in bytes +; +MSGID_TITLEPLACEHOLDER_WINDOW_PATH +%pa|Nom du répertoire de la fenêtre +; %pa|Windows directory path +; +MSGID_TITLEPLACEHOLDER_DISK_FREE +%df|Espace disque libre +; %df|Free disk space +; +MSGID_TITLEPLACEHOLDER_DISK_FREE_DIVIDE +%DF|Espace disque libre(Division auto.) +; %DF|Free disk space (auto divide) +; +MSGID_TITLEPLACEHOLDER_DISK_USED +%du|Espace disque utilisé +; %du|Used disk space +; +MSGID_TITLEPLACEHOLDER_DISK_USED_DIVIDE +%DU|Espace disque utilisé(Division auto.) +; %DU|Used disk space (auto divide) +; +MSGID_TITLEPLACEHOLDER_START_NODISK +%d(|Début : Ne pas montrer si aucun disque n'est inséré +; %d(|Start: don't show if no disk inserted +; +MSGID_TITLEPLACEHOLDER_STOP_NODISK +%d)|Fin : Ne pas montrer si aucun disque n'est inséré +; %d)|Stop: don't show if no disk inserted +; +MSGID_TITLEPLACEHOLDER_DISK_PERCENT +%dp|Pourcentage disque utilisé +; %dp|Percent of used disk space +; +MSGID_TITLEPLACEHOLDER_GFXCHIPS +%cs|Type de Chipset graphique(Ex: AGA) +; %cs|Graphics chip set (e.g. AGA) +; +MSGID_TITLEPLACEHOLDER_CPU +%pr|Type de processeur 68k +; %pr|68k processor +; +MSGID_TITLEPLACEHOLDER_FPU +%cp|Type de co-processeur (FPU) +; %cp|68k co-processor (FPU) +; +MSGID_TITLEPLACEHOLDER_TASKS +%nt|Nombre de tâches +; %nt|Number of tasks +; +MSGID_TITLEPLACEHOLDER_LIBRARIES +%nl|Nombre de librairies +; %nl|Number of libraries +; +MSGID_TITLEPLACEHOLDER_PORTS +%np|Nombre de ports +; %np|Number of ports +; +MSGID_TITLEPLACEHOLDER_DEVICES +%nd|Nombre d'unités présentes +; %nd|Number of devices +; +MSGID_TITLEPLACEHOLDER_SCREENS +%ns|Nombre d'écrans +; %ns|Number of screens +; +;----------------------------------------------------------- +; +MSGID_WINDOWPAGES_GENERAL +Général +; General +; +MSGID_WINDOWPAGES_SIZE +Taille +; Size +; +MSGID_WINDOWPAGES_LAYOUT +Disposition +;Layout +; +; +MSGID_WINDOWPAGES_CONTROLBAR +Barre de navigation +;Control Bar +; +MSGID_WINDOWPAGES_CONTROLBAR_BROWSER +Barre de contrôle du navigateur +;Browser Window Control Bar +; +MSGID_WINDOWPAGES_CONTROLBAR_NORMAL +Barre de contrôle des fenêtres standards +;Standard Window Control Bar +; +;----------------------------------------------------------- +; +MSGID_TEXTWINDOWPAGES_FONTS +Polices de caractères +;Fonts +; +MSGID_TEXTWINDOWPAGES_COLUMNS +Colonnes +;Columns +; +MSGID_TEXTWINDOWPAGES_SELECTIONMARKS +Marquage +;Selection marks +; +MSGID_TEXTWINDOWPAGES_MISC +Divers +;Miscellaneous +; +;----------------------------------------------------------- +; +; ** New in 40.12 ** +MSGID_CREATELINKS_HARDLINKS +Liens matériels +; +; ** New in 40.12 ** +MSGID_CREATELINKS_SOFTLINKS +Liens logiciels +; +;----------------------------------------------------------- +; +MSGID_WINDOWREFRESH_SIMPLE +Rafraîchissement simple +; Simple Refresh +; +MSGID_WINDOWREFRESH_SMART +Rafraîchissement intelligent +; Smart Refresh +; +;----------------------------------------------------------- +; +MSGID_WINDOW_SHOWALL_DEFAULT_ICONS +Montrer - seulement les icônes +;Show - Only Icons +; +MSGID_WINDOW_SHOWALL_DEFAULT_ALL +Montrer - Tous les fichiers +;Show - All Files +;----------------------------------------------------------- +; +MSGID_WINDOW_VIEWBY_DEFAULT_ICON +Afficher par - Icône +;View By - Icon +; +MSGID_WINDOW_VIEWBY_DEFAULT_NAME +Afficher par - Nom +;View By - Name +; +MSGID_WINDOW_VIEWBY_DEFAULT_SIZE +Afficher par - Taille +;View By - Size +; +MSGID_WINDOW_VIEWBY_DEFAULT_DATE +Afficher par - Date +;View By - Date +; +MSGID_WINDOW_VIEWBY_DEFAULT_TIME +Afficher par - Heure +;View By - Time +; +MSGID_WINDOW_VIEWBY_DEFAULT_COMMENT +Afficher par - Commentaire +;View By - Comment +; +MSGID_WINDOW_VIEWBY_DEFAULT_PROTECTION +Afficher par - Protection +;View By - Comment +; +MGSID_WINDOW_VIEWBY_DEFAULT_OWNER +Afficher par - Propriètaire +;View By - Owner +; +MSGID_WINDOW_VIEWBY_DEFAULT_GROUP +Afficher par - Groupe +;View By - Group +; +;----------------------------------------------------------- +; +MSGID_FILEDISPLAYPAGES_TEXT +Texte +; Text +; +;----------------------------------------------------------- +; +MSGID_ICONLAYOUT_COLUMNS +Par colonnes +;Columns (top-down, then left-to-right) +; +MSGID_ICONLAYOUT_ROWS +Par rangées +;Rows (left-to-right, then top-down) +; +;----------------------------------------------------------- +; +MSGID_ICONLABELSTYLES_NORMAL +Normal +; Normal +; +MSGID_ICONLABELSTYLES_OUTLINE +Avec contour +; Outline +; +MSGID_ICONLABELSTYLES_SHADOW +Ombragé +; Shadow +; +;----------------------------------------------------------- +; +MSGID_ICONSIZES_16x16 +16 x 16 +;16 x 16 +; +; +MSGID_ICONSIZES_24x24 +24 x 24 +;24 x 24 +; +; +MSGID_ICONSIZES_32x32 +32 x 32 +;32 x 32 +; +; +MSGID_ICONSIZES_48x48 +48 x 48 +;48 x 48 +; +; +MSGID_ICONSIZES_64x64 +64 x 64 +;64 x 64 +; +; +MSGID_ICONSIZES_96x96 +96 x 96 +;96 x 96 +; +; +MSGID_ICONSIZES_128x128 +128 x 128 +;128 x 128 +; +; +MSGID_ICONSIZES_UNLIMITED +Illimité +;unlimited +; +;----------------------------------------------------------- +; +MSGID_ICONDRAGSTYLES_IMAGEONLY +Image seulement +; Image Only +; +MSGID_ICONDRAGSTYLES_IMAGEANDTEXT +Image et texte +; Image & Text +; +;----------------------------------------------------------- +; +MSGID_THUMBNAILSIZES_16x16 +16 x 16 +;16 x 16 +; +MSGID_THUMBNAILSIZES_24x24 +24 x 24 +;24 x 24 +; +MSGID_THUMBNAILSIZES_32x32 +32 x 32 +;32 x 32 +; +MSGID_THUMBNAILSIZES_48x48 +48 x 48 +;48 x 48 +; +MSGID_THUMBNAILSIZES_64x64 +64 x 64 +;64 x 64 +; +MSGID_THUMBNAILSIZES_96x96 +96 x 96 +;96 x 96 +; +MSGID_THUMBNAILSIZES_128x128 +128 x 128 +;128 x 128 +; +;----------------------------------------------------------- +; +MSGID_ICONDRAGTRANSPARENCY_GHOSTED +Fantôme +; Ghosted +; +MSGID_ICONDRAGTRANSPARENCY_TRANSPARENT +Fantôme/Réelle transparence +; Ghosted/Real Transparent +; +;----------------------------------------------------------- +; +MSGID_SHOWTHUMBNAILS_NEVER +Jamais +;Never +; +; +MSGID_SHOWTHUMBNAILS_AS_DEFAULT +Icônes par défaut +;As default +; +; +MSGID_SHOWTHUMBNAILS_ALWAYS +Toujours +;Always +; +;----------------------------------------------------------- +; +MSGID_ICONDRAGTROUTINES_SYSTEM +Système +; System +; +MSGID_ICONDRAGTROUTINES_CUSTOM +Personnaliser +; Custom +; +MSGID_ICONDROPMARK_NEVER +Ne jamais voir +; Never show +; +MSGID_ICONDROPMARK_ALWAYS +Toujours +; Always +; +MSGID_ICONDROPMARK_DRAWERSONLY +Seulement dans les fenêtres des répertoires +; Only in drawer windows +; +MSGID_ICONDRAGLOOK_TRANSP_SOLID +\033bTransparentes\033n pendant le déplacement, \033bsolide\033n au-dessus des éléments +; \033bTransparent\033n when dragging, \033bsolid\033n over triggers +; +MSGID_ICONDRAGLOOK_ALWAYS_SOLID +Toujours \033bsolides\033n pendant le déplacement +; Always \033bsolid\033n icons when dragging +; +MSGID_ICONDRAGLOOK_ALWAYS_TRANSP +Toujours \033btransparentes\033n pendant le déplacement +; Always \033btransparent\033n icons when dragging +; +MSGID_ICONDRAGLOOK_SOLID_TRANSP +\033bSolides\033n pendant le déplacement, \033btransparentes\033n au-dessus des éléments +; \033bSolid\033n when dragging, \033btransparent\033n over triggers +; +MSGID_VERSIONSTRING +Scalos Version %s (%d.%d) (Build %s) +; Scalos Version %s (%d.%d) (Build %s) +; +MSGID_COPYRIGHTSTRING +©2003%s The Scalos Team +; ®2003-2004 The Scalos Team +; +; ** new in 40.11 ** +; +MSGID_SPLASHWINDOW_LOADINGPREFS +\33c Chargement des préférences de Scalos... +;\33c Loading Scalos Prefs... +; +; +MSGID_SPLASHWINDOW_APPLYINGPREFS +\33c Application des préférences de Scalos... +;\33c Applying Scalos Prefs... +; +; +MSGID_SPLASHWINDOW_SAVINGPREFS +\33c Sauvegarde des préférences de Scalos... +;\33c Saving Scalos Prefs... +; +;----------------------------------------------------------- +; +MSGID_ABOUTPAGE_COPYRIGHT +\033c\033bTous droits réservés ©2003%s The Scalos Team +; \033c\033bCopyright ©2003-2004 The Scalos Team +; +MSGID_ABOUTPAGE_CONTACT1 +contactez-nous par email < +; contact us by email < +; +MSGID_ABOUTPAGE_CONTACT2 +> // web < +; > // web < +; +MSGID_ABOUTPAGE_CONTACT3 +> +; > +; +MSGID_ABOUTPAGE_PREFSVERSION +Préférences de Scalos V%ld.%ld +; Scalos Main Preferences V%ld.%ld +; +MSGID_PATHSPAGE_DEFAULTPATHS +Chemins par défaut +; Default Paths +; +MSGID_PATHSPAGE_SCALOS_HOME +Emplacement de Scalos : +; Scalos Home: +; +MSGID_PATHSPAGE_SCALOS_HOME_ASLTITLE +Scalos : Sélectionnez un répertoire, s'il vous plaît... +; Please select a drawer... +; +MSGID_PATHSPAGE_SCALOS_HOME_SHORTHELP +Ce répertoire sera assigné à SCALOS: +; An assign called SCALOS: will point to this directory +; +MSGID_PATHSPAGE_THEMES +Thèmes : +; Themes: +; +MSGID_PATHSPAGE_THEMES_SHORTHELP +C'est le répertoire où tous les\n\ +fichiers ; spécifiques des thèmes ; sont rangés. +; This is the drawer where all the\ntheme-specific files are located. +; +MSGID_PATHSPAGE_THEMES_ASLTITLE +Thèmes : Sélectionnez un répertoire, s'il vous plaît... +; Please select a drawer... +; +MSGID_PATHSPAGE_DEFAULTICONS +Icônes par défaut : +; Default Icons: +; +MSGID_PATHSPAGE_DEFAULTICONS_SHORTHELP +C'est à partir de ce répertoire que Scalos\n\ +charge les icônes par défaut. +; This is the drawer where Scalos\nlooks for default icons. +; +MSGID_PATHSPAGE_DEFAULTICONS_ASLTITLE +Icônes par défaut : Sélectionnez un répertoire, s'il vous plaît... +; Please select a drawer... +; +MSGID_PATHSPAGE_WBSTARTUP +WBStartup : +; WBStartup: +; +MSGID_PATHSPAGE_WBSTARTUP_SHORTHELP +Ce répertoire est utilisé pour le lancememnt des tâches\n\ +du Workbench (WBStartup), tous les programmes présents\n\ +dans celui-ci, seront éxecutés pendant le démarrage de Scalos. +; This drawer is used as WBStartup, i.e. any program\nlocated inside is executed upon Scalos startup. +; +MSGID_PATHSPAGE_WBSTARTUP_ASLTITLE +WBStartup : Sélectionnez un répertoire, s'il vous plaît... +; Please select a drawer... +; +MSGID_PATHSPAGE_DISKCOPY +Copie de disques : +; DiskCopy: +; +MSGID_PATHSPAGE_DISKCOPY_SHORTHELP +Chemin d'accès complet du\n\ +programme "DiskCopy". +; This is the complete file name for\nthe \"Diskcopy\" system program. +; +MSGID_PATHSPAGE_DISKCOPY_ASLTITLE +DiskCopy : Sélectionnez un répertoire, s'il vous plaît... +; Please select a drawer... +; +MSGID_PATHSPAGE_FORMAT +Formattage de disques : +; Format: +; +MSGID_PATHSPAGE_FORMAT_SHORTHELP +Chemin d'accès complet du\n\ +programme "Format". +; This is the complete file name for\nthe \"Format\" system program. +; +MSGID_PATHSPAGE_FORMAT_ASLTITLE +Format : Sélectionnez un répertoire, s'il vous plaît... +; Please select a drawer... +; +MSGID_PATHSPAGE_THUMBNAILDB +Fichier du cahe des vignettes : +;Thumbnail cache file: +; +MSGID_PATHSPAGE_THUMBNAILDB_ASLTITLE +Choix de l'emplacement du cache des vignettes... +;Please select thumbnail cache location... +; +MSGID_PATHSPAGE_THUMBNAILDB_SHORTHELP +Scalos utilise un fichier comme cache, pour les vignettes des images.\n\ +Ce fichier peut atteindre facilement plusieurs mega octets.\n\ +Choisissez ici l'emplacement où ce fichier devra être conservé. +;Scalos uses a database file to cache thumbnail icon images.\n\ +;This file easily grows to several megabytes.\n\ +;Select here a place where this file should be kept. +; +MSGID_PATHSPAGE_IMAGECACHE +Cache des images : +;Image Cache: +; +MSGID_PATHSPAGE_IMAGECACHE_SHORTHELP +Ce répertoire est utilisé pour mettre en cache les\n\ +images datatypes utilisées par Scalos.\n\ +Etant donné que les datatypes empêchent la mise à jour des images,\n\ +Scalos crée une copie des images utilisées, dans le répertoire cache. +;This drawer is used to cache the datatypes images used by Scalos.\n\ +;Since datatypes prevents images from being updated,\n\ +;Scalos creates cached copies of the images used. +; +MSGID_PATHSPAGE_IMAGECACHE_ASLTITLE +Sélectionnez un répertoire, s'il vous plaît... +;Please select a drawer... +; +MSGID_PATHSPAGE_SQLITE3TEMPPATH +Fichiers temporaires de la base\n\ +de donnée des vignettes : +;Thumbnail Database Temporary Files: +; +MSGID_PATHSPAGE_SQLITE3TEMPPATH_SHORTHELP +Ce répertoire est utilisé pour stocker des fichiers\n\ +temporaires pour l'utilisation interne de la base de\n\ +donnéesthe des vignettes. +;This drawer is used to store any temporary\n\ +;files for internal use by the thumbnail database. +; +MSGID_PATHSPAGE_SQLITE3TEMPPATH_ASLTITLE +Choisissez l'emplacement des fichiers temporaires du cache des vignettes... +;Please select thumbnail cache temporary files location... +; +;----------------------------------------------------------- +; +MSGID_STARTUPPAGE_SPLASHWINDOW +Fenêtre d'activités +; Splash Window +; +MSGID_STARTUPPAGE_SHOWSPLASHWINDOW +Voir la fenêtre d'activités : +; Show splash window: +; +MSGID_STARTUPPAGE_SHOWSPLASHWINDOW_SHORTHELP +Ce bouton activé permet d'afficher\n\ +la fenêtre d'activités de Scalos, durant le démarrage. +; Enable this checkbox to display the\nsplash window upon every Scalos startup. +; +MSGID_STARTUPPAGE_SPLASHCLOSEDELAY +Délai de fermeture de la fenêtre d'activités : +; Splash close delay: +; +MSGID_STARTUPPAGE_SPLASHCLOSEDELAY_SHORTHELP +Spécifie combien de temps la fenêtre d'activités\n\ +devra rester ouverte aprés l'affichage\n\ +du dernier message. +; Specify here how long the Scalos splash window\nwill stay open after the last startup message\nhas been displayed. +; +MSGID_STARTUPPAGE_WBSTARTUP +WBStartup +; WBStartup +; +MSGID_STARTUPPAGE_DOWAITDELAY +Délai d'attente : +; DoWait delay: +; +MSGID_STARTUPPAGE_DOWAITDELAY_SHORTHELP +Si un outil présent dans le répertoire WBStartup\n\ +est toujours en attente sans délai spécifié, une\n\ +requête s'ouvrira afin de savoir si vous désirez\n\ +ou non attendre d'avantage. +; If a tool in the WBStartup drawer doesn't\nfinish within the specified delay a requester will be\npresented to choose wether to stop waiting. +; +MSGID_STARTUPPAGE_DOWAITDELAY_SECONDS +secondes +; seconds +; +MSGID_DESKTOPPAGE_SCREENTITLEBAR +Titre de l'écran +; Screen +; +MSGID_DESKTOPPAGE_SCREEN +Ecran : +;Title +; +MSGID_DESKTOPPAGE_SCREEN_DESCRIPTION +|\033b\0338Description +; |\033b\0338Description +; +MSGID_DESKTOPPAGE_TITLEBAR_REFRESH +Taux de rafraîchissement : +; Titlebar refresh rate: +; +MSGID_DESKTOPPAGE_TITLEBAR_REFRESH_SHORTHELP +C'est le temps d'intervalle de rafraîchissement\n\ +de la barre du titre de l'écran. +; This is the time interval between\nconsecutive screen title bar refreshes. +; +MSGID_DESKTOPPAGE_TITLEBAR_REFRESH_SECONDS +secondes +; seconds +; +MSGID_DESKTOPPAGE_TITLEBAR_REFRESH_MEMCHANGE +Rafraîchir seulement si la mémoire change : +; Refresh only on memory change: +; +MSGID_DESKTOPPAGE_TITLEBAR_REFRESH_MEMCHANGE_SHORTHELP +Quand ce bouton est sélectionné, la barre du titre de l'écran\n\ +est rafraîchie si la taille de la mémoire a changée depuis la\n\ +dernière vérification. La mémoire est vérifiée toutes les\n\ +"x" secondes configurées avec le "Taux de rafraîchissement". +; When this item is checked, the screen title bar\nis only refreshed when the amount of available\nsystem memory has changed since last check.\nThe memory is checked every \"Titlebar refresh rate\" seconds. +; +MSGID_DESKTOPPAGE_DESKTOP_REFRESH +Rafraîchissement du bureau +; Desktop Refresh +; +MSGID_DESKTOPPAGE_DISK_ICON_RATE +Taux pour les icônes de disques : +; Disk icon rate: +; +MSGID_DESKTOPPAGE_DISK_ICON_RATE_SHORTHELP +C'est le temps d'intervalle que prendra Scalos\n\ +avant d'analyser tout changement de disques et de volumes. +; This is the time interval Scalos\nchecks for changed disks and volumes. +; +MSGID_DESKTOPPAGE_DISK_ICON_RATE_SECONDS +secondes +; seconds +; +MSGID_DESKTOPPAGE_SCREENTITLE +Titre d'écran +; Screen Title +; +MSGID_DESKTOPPAGE_SCREENTITLE_MODE +Mode du titre d'écran +;Visibility +; +MSGID_DESKTOPPAGE_SCREENTITLE_MODE_SHORTHELP +Spécifie ici si vous désirez que le titre de l'écran :\n\ +- Soit visible tout le temps.\n\ +- Apparaîsse quand le curseur de la souris est positionné en haut de l'écran.\n\ +- Soit toujours cacher. +; Specifiy here whether you like the screen title\n- to be visible all the time\n- to pop up when the mouse pointer is positioned at the top of the screen\n- to be hidden all the time +; +MSGID_DESKTOPPAGE_MISCELLANEOUS +Divers +; Miscellaneous +; +MSGID_DESKTOPPAGE_ALLOW_CLOSEWB +Permettre la fermeture du Workbench : +; Allow CloseWorkbench(): +; +MSGID_DESKTOPPAGE_ALLOW_CLOSEWB_SHORTHELP +Désactiver ce bouton afin que la fonction "Fermer le Workbench"\n\ +( CloseWB() ) ne soit pas opérationelle. Ceci permet de travailler\n\ +avec d'anciens programmes et laisse Scalos toujours ouvert. +; Disable this checkbox to make the CloseWB() function\na no-op. This allows to work with some ancient\nprograms and leave Scalos open all the time. +; +MSGID_DESKTOPPAGE_DROPSTART +Drop-start : +; Drop-start: +; +MSGID_DESKTOPPAGE_DROPSTART_SHORTHELP +Déposer une icône sur un autre(s) programme(s)\n\ +lancera automatiquement le(s) programme(s) et\n\ +considèrera le fichier comme un paramètre. +; Dropping a project icon on to another programs\nicon will automatically run the program and\npass the project file as a parameter +; +MSGID_DESKTOPPAGE_CONSOLENAME +Nom de la console +; Console name +; +MSGID_DESKTOPPAGE_CONSOLENAME_SHORTHELP +Inscrire les paramètres pour la\n\ +console de sortie CLI et ARexx. +; Gives complete file specifier for CLI and ARexx console. +; +MSGID_DESKTOPPAGE_AUTOLEAVEOUT +Raccourci automatique vers le bureau : +;Automatic leave-out +; +MSGID_DESKTOPPAGE_AUTOLEAVEOUT_SHORTHELP +Si activé, les icônes déposées sur le bureau\n\ +y seront plaçées en permanence, exactement comme\n\ +si la commande "Sortir" avait été sélectionnée. +;If this switch is turned on, dragging icons\n\ +;onto the desktop remembers them permanently\n\ +;as left-out, just like selecting the\n\ +;\"leave out\" menu command. +; +MSGID_DESKTOPPAGE_WINTITLEBAR_REFRESH +Taux de rafraîchissement : +; Titlebar refresh rate: +; +MSGID_DESKTOPPAGE_WINTITLEBAR_REFRESH_SHORTHELP +C'est le temps d'intervalle de rafraîchissement\n\ +de la barre du titre des fenêtres. +; This is the time interval between\n\ +; consecutive windows title bar refreshes. +; +MSGID_DESKTOPPAGE_WINTITLEBAR_REFRESH_SECONDS +secondes +; seconds +; +MSGID_DESKTOPPAGE_WINTITLEBAR_REFRESH_MEMCHANGE +Rafraîchir seulement si la mémoire change : +; Refresh only on memory change: +; +MSGID_DESKTOPPAGE_WINTITLEBAR_REFRESH_MEMCHANGE_SHORTHELP +Quand ce bouton est sélectionné, la barre du titre de la fenêtre\n\ +est rafraîchie si la taille de la mémoire a changée depuis la\n\ +dernière vérification. La mémoire est vérifiée toutes les\n\ +"x" secondes configurées avec le "Taux de rafraîchissement". +; When this item is checked, the window title bar\n\ +; is only refreshed when the amount of available\n\ +; system memory has changed since last check.\n\ +; The memory is checked every "Titlebar refresh rate" seconds. +; +MSGID_DESKTOPPAGE_LASSO +Lasso +;Lasso +; +MSGID_DESKTOPPAGE_SINGLEWINDOW_LASSO +Mode lasso pour une fenêtre +;Single-Window Lasso Mode +; +MSGID_DESKTOPPAGE_SINGLEWINDOW_LASSO_SHORTHELP +Presser ce racourci clavier afin de limiter l'oprération "lasso"\n\ +pour une seule fenêtre. Dans ce mode, le contenu de la fenêtre défile afin de\n\ +dévoiler les icônes cachées, si le curseur de la souris sort de la zone\n\ +interne de la fenêtre. +;Press this qualifier key to limit lasso operation to a single window.\n\ +;In this mode, the window contents scrolls to unveal hidden\n\ +;icons if the mouse leaves the inner window area. +; +;----------------------------------------------------------- +; +MSGID_ICONSPAGE_ICONFRAME +Bords des icônes +; Icon Frame +; +MSGID_ICONSPAGE_ICONFRAME_NORMAL +Normal +; Normal +; +MSGID_ICONSPAGE_ICONFRAME_NORMAL_SHORTHELP +Ce type de bord est traçé autour des icônes non sélectionnées.\n\ +Les \033bGlowIcons\033n qui ont été sauvegarder\n\ +avec l'option "sans bords" ne seront pas affectés par cette option.\n\ +Notez que les bords d'icônes ci-dessous ne doivent\n\ +pas être nul afin que que le bord de l'icône soit visible. +; This type of border is drawn around unselected icons.\n\033bGlowIcons\033n which have been marked as\n\"borderless\" will not show this border.\nPlease note that the icon borders below must\nbe non-zero for the icon border to show. +; +MSGID_ICONSPAGE_ICONFRAME_SELECTED +Sélectionné +; Selected +; +MSGID_ICONSPAGE_ICONFRAME_SELECTED_SHORTHELP +Ce type de bord est traçé autour des icônes sélectionnées.\n\ +Les \033bGlowIcons\033n qui ont été sauvegarder\n\ +avec l'option "sans bords" ne seront pas affectés par cette option.\n\ +Notez que les bords d'icônes ci-dessous ne doivent\n\ +pas être nul afin que que le bord de l'icône soit visible. +; This type of border is drawn around selected icons.\n\033bGlowIcons\033n which have been marked as\n\"borderless\" will not show this border.\nPlease note that the icon borders below must\nbe non-zero for the icon border to show. +; +MSGID_ICONSPAGE_ICONBORDER_LEFT +Gauche : +; Left: +; +MSGID_ICONSPAGE_ICONBORDER_LEFT_SHORTHELP +Ceci est l'espace entre le coté gauche d'une\n\ +icône et de son bord. Aucun bord ne sera\n\ +tracé si la valeur de cet espace est égal à 0. +; This is the space between the left side of an\nicon and the border. No icon borders will be\ndrawn when this space is 0. +; +MSGID_ICONSPAGE_ICONBORDER_TOP +Haut : +; Top: +; +MSGID_ICONSPAGE_ICONBORDER_TOP_SHORTHELP +Ceci est l'espace entre le haut d'une\n\ +icône et de son bord. Aucun bord ne sera\n\ +tracé si la valeur de cette espace est égal à 0. +; This is the space between the top of an\nicon and the border. No icon borders will be\ndrawn when this space is 0. +; +MSGID_ICONSPAGE_ICONBORDER_RIGHT +Droit : +; Right: +; +MSGID_ICONSPAGE_ICONBORDER_RIGHT_SHORTHELP +Ceci est l'espace entre le coté droit d'une\n\ +icône et de son bord. Aucun bord ne sera\n\ +tracé si la valeur de cette espace est égal à 0. +; This is the space between the right side of an\nicon and the border. No icon borders will be\ndrawn when this space is 0. +; +MSGID_ICONSPAGE_ICONBORDER_BOTTOM +Bas : +; Bottom: +; +MSGID_ICONSPAGE_ICONBORDER_BOTTOM_SHORTHELP +Ceci est l'espace entre le bas d'une\n\ +icône et de son bord. Aucun bord ne sera\n\ +tracé si la valeur de cette espace est égal à 0. +; This is the space between the bottom of an\nicon and the border. No icon borders will be\ndrawn when this space is 0. +; +MSGID_ICONSPAGE_LABELS +Etiquettes : +; Labels +; +MSGID_ICONSPAGE_LABELS_TEXT +Style de texte : +; Text style: +; +MSGID_ICONSPAGE_LABELS_TEXT_SHORTHELP +Offre un choix de formatage de fontes\n\ +qui peut être appliquer au texte des icônes. +; Provides a choice of label font formatting\nwhich can be applied to the icons text label +; +MSGID_ICONSPAGE_LABELS_TEXTSPACE +Espace entre l'image et le texte : +; Image <-> Text Space +; +MSGID_ICONSPAGE_LABELS_TEXTSPACE_SHORTHELP +Ajuste l'espace entre l'image\n\ +de l'icône et son texte. +; Adjusts the space between the\nicon imagery and its text label +; +MSGID_ICONSPAGE_LABELS_TEXTSPACE_PIXELS +pixels +; pixels +; +MSGID_ICONSPAGE_LABELS_SPLIT +Afficher sur plusieurs lignes : +; Split into multiple lines: +; +MSGID_ICONSPAGE_LABELS_SPLIT_SHORTHELP +Permet aux noms des fichiers d'être\n\ +afficher sur plusieurs lignes. +; Allows filenames to be split\nover multiple lines +; +MSGID_ICONSPAGE_LABELS_UNDERLINE_LINKS +Affichage des noms des fichiers liés"liens logiciels" \033usouslignés\033n : +; Display soft-link file names \033uunderlined\033n: +; +MSGID_ICONSPAGE_LABELS_UNDERLINE_LINKS_SHORTHELP +Quand ce bouton est coché, le nom des fichiers liés\n\ +"liens logiciels" sont \033usouslignés\033n. +; When this item is checked, icon names of\nsoft-links are displayed \033uunderlined\033n. +; +MSGID_ICONSPAGE_LABELS_FONT +Police de caractères +; Font +; +MSGID_ICONSPAGE_LABELS_FONT_NOTICE +Afin de changer la police de caractères des étiquettes des icônes vous devez utiliser\n\ +le programme standard "Font" des préférences installé sur votre\n\ +système. Utiliser le bouton "pop-up" situé à droite afin de lancer\n\ +le programme des préférences de la police de caractères. +;To change the font used for icon labels you must use \ +;the standard \033bFont preferences\033n program installed on your \ +;system. Use the pop-up button on the right to launch \ +;the fonts preference program. +; +MSGID_ICONSPAGE_LABELS_FONT_SHORTHELP +Lancement du programme standard des préférences\n\ +de la police de caractères(Font). +; Launch standard Font prefs program +; +MSGID_ICONSPAGE_GENERAL +Général +; General +; +MSGID_ICONSPAGE_MASKED_CLICKAREA +Zone de clic masquée : +; Masked click area: +; +MSGID_ICONSPAGE_MASKED_CLICKAREA_SHORTHELP +Si ce bouton est coché, vous devrez clicker sur la\n\ +zone non masquée de l'icône, pour l'activer. Si il\n\ +n'est pas coché, un click à l'intèrieur du rectangle\n\ +de l'icône suffira pour l'activer. +; If this checkbox is checked, you have to click on the\nunmasked, visible area of an icon to activate it. If it\nis unchecked, a click anywhere inside the icon\nrectangle will be sufficient for activation. +; +MSGID_ICONSPAGE_MULTISELECTION +Sélection multiple : +; Multi-Selection: +; +MSGID_ICONSPAGE_MULTISELECTION_SHORTHELP +Offre une méthode de sélection multiple qui\n\ +ne nécéssite pas la pression de la touche SHIFT\n\ +pendant le déplacement de plusieurs icônes. +; Provides an alternative multi-select method which\ndoes not require you to hold down the SHIFT key\nwhilst dragging multiple icons. +; +MSGID_ICONSPAGE_NEWICONS +Nouvelles icônes(NewIcons) +; New Icons +; +MSGID_ICONSPAGE_NEWICONS_REMAP_PRECISION +Précision re-coloriage : +; Remap precision: +; +MSGID_ICONSPAGE_NEWICONS_REMAP_PRECISION_SHORTHELP +Spécifie le type de précision à utiliser pendant la correction\n\ +des couleurs des NewIcons d'aprés la palette de l'écran. +; Specifies the precision to use when\nremapping NewIcon colors to the screen palette. +; +MSGID_ICONSPAGE_NEWICONS_TRANSPARENTBG +Arrière-plan transparent : +; Transparent background: +; +MSGID_ICONSPAGE_NEWICONS_TRANSPARENTBG_SHORTHELP +Rendre transparent, l'arrière-plan des NewIcons. +; Makes the background of NewIcons transparent +; +MSGID_ICONSPAGE_DEFICONS +Icônes par défaut +; Def Icons +; +MSGID_ICONSPAGE_DEFICONS_LOADFIRST +Charger en premier : +; Load first: +; +MSGID_ICONSPAGE_DEFICONS_LOADFIRST_SHORTHELP +Vos icônes "def_#?" seront prioritaires pendant\n\ +la lecture d'une icône spécifique à un volume. +; Your def_#? icons will get priority when\nloading over a specific icon for a device. +; +MSGID_ICONSPAGE_DEFICONS_SAVEABLE +Fixer les icônes par défault : +; Icons saveable: +; +MSGID_ICONSPAGE_DEFICONS_SAVEABLE_SHORTHELP +Si coché, la commande \033bfiger\033n sauvegardera\n\ +les changements des icônes par défaut. Sinon, Scalos\n\ +ne tiendra pas compte des changements éfféctués sur ces icônes. +; When enabled, \033bsnapshot\033n saves changes\nto default icons.\nUncheck this checkbox to prevent Scalos from\nchanging any ofyour default icons. +; +MSGID_ICONSPAGE_TOOLTIPS_GENERAL +Général +; General +; +MSGID_ICONSPAGE_TOOLTIPS_SHOW +Activer la bulle d'informations("tooltips") des icônes : +; Show tooltips for icons: +; +MSGID_ICONSPAGE_TOOLTIPS_SHOW_SHORTHELP +Si coché, Scalos ouvrira une bulle d'informations("\033btooltips\033n")\n\ +comprenant des informations complèmentaires d'une icône,\n\ +aprés un délai d'attente spécifié. La bulle disparaîtra si la\n\ +souris est déplacée ou si une touche est préssée. +; When this checkbox is checked, Scalos pops up\n\033btooltips\033n with additional information\nwhen you keep the mouse pointer positioned over\nan icon for more than the tooltip delay time.\nThe tooltip automatically disappears as soon as\nthe mouse is moved or any key is pressed. +; +MSGID_ICONSPAGE_TOOLTIPS_SETTINGS +Options +; Settings +; +MSGID_ICONSPAGE_TOOLTIPS_DELAY +Attente avant apparition : +; Delay before pop-up: +; +MSGID_ICONSPAGE_TOOLTIPS_DELAY_SHORTHELP +Ici, vous pouvez choisir le délai d'attente\n\ +avant l'ouverture de la bulle "tooltips"\n\ +quand la souris est positionnée au-dessus d'une icône. +; Here you can select how long you have to\nkeep the mouse pointer positioned over an\nicon until the tooltip pops up. +; +MSGID_ICONSPAGE_TOOLTIPS_DELAY_SECONDS +secondes +; seconds +; +MSGID_ICONSPAGE_TOOLTIPS_FONT +Polce de caractères : +; Font: +; +MSGID_ICONSPAGE_TOOLTIPS_FONT_SHORTHELP +??? +; ??? +; +MSGID_ICONSPAGE_TOOLTIPS_FONT_ASLTITLE +Choisissez une police de caractères, s'il vous plaît... +; Please select a font... +; +MSGID_ICONSPAGE_TOOLTIPS_DISPLAYFIELDS +Affichage des champs +; Display Fields +; +MSGID_ICONSPAGE_TOOLTIPS_AVAILABLEFIELDS +Champs disponibles +; Available Fields +; +MSGID_ICONSPAGE_TOOLTIPS_AVAILABLEFIELDS_SHORTHELP +??? +; ??? +; +MSGID_ICONSPAGE_TOOLTIPS_FIELDSINUSE +Champs utilisés +; Fields In Use +; +MSGID_ICONSPAGE_TOOLTIPS_FIELDSINUSE_SHORTHELP +??? +; ??? +; +MSGID_ICONSPAGE_DRAGGING +Déplacememt +; Dragging +; +MSGID_ICONSPAGE_ATTRIBUTES_TRANSPARENCY_DEFICONS +Transparence +; Transparency +; +MSGID_ICONSPAGE_ATTRIBUTES_TRANSPARENCY_DEFICONS_SHORTHELP +Les icônes par défaut peuvent être transparents.\n\ +Sélectionnez, s'il vous plaît, le degrès de transparence\n\ +que vous aimeriez appliquer aux icônes par défaut.\n\ +La transparence réelle est disponible seulement\n\ +si votre bureau posséde plus de 256 couleurs. +; Default icons may be drawn transparent.\nPlease select the degree of transparency you\nwould like default icons to be draw with.\nPlease note that real transparency is only available\nif your desktop screen has more than 256 colors. +; +; ** new in 40.12 ** +; +MSGID_ICONSPAGE_LABELS_FONT_SAMPLETEXT_SHORTHELP +Ceci est un exemple de texte afin de visualiser\n\ +l'aspect de la police de caractères choisie. +;This is an example text to visualize what the selected font looks like +; +; +MSGID_ICONSPAGE_HILITE_UNDER_MOUSE +Marquer l'icône sous la souris : +;Mark icon under mouse: +; +; +MSGID_ICONSPAGE_HILITE_UNDER_MOUSE_SHORTHELP +Si activé, les icônes se trouvant\n\ +sous le curseur de la souris seront\n\ +affichées en surbrillance. +;If this switch is turned on, every\n\ +;icon is shown in a highlighted stated\n\ +;while the mouse pointer is over it. +; +; +MSGID_ICONSPAGE_ICONSCALING +Dimensions des Icônes +;Icon Scaling +; +; +MSGID_ICONSPAGE_SCALING_MINSIZE +Taille Minimum : +;Minimum Size: +; +; +MSGID_ICONSPAGE_SCALING_MINSIZE_SHORTHELP +Taille d'affichage minimum des icônes.\n\ +Les icônes plus petites seront redimensionnées\n\ +d'après la taille minimum spécifiée ici. +;Minimum size for displayed icons.\n\ +;Smaller icons will be scaled to\n\ +;the specified minimum size. +; +; +MSGID_ICONSPAGE_SCALING_MAXSIZE +Taille Maximum : +;Maximum Size: +; +; +MSGID_ICONSPAGE_SCALING_MAXSIZE_SHORTHELP +Taille d'affichage maximum des icônes.\n\ +Les icônes plus grandes seront redimensionnées\n\ +d'après la taille maximum spécifiée ici. +;Maximum size for displayed icons.\n\ +;Larger icons will be scaled to\n\ +;the specified maximum size. +; +MSGID_ICONSPAGE_GROUP_ICONFONT +Police de caractère standard +;Standard Font +; +; +MSGID_ICONSPAGE_LABELS_ICONFONT_SHORTHELP +Cette police de caractères est utilisée pour\n\ +les étiquettes des icônes.\n\ +Cette option n'est pas disponible tant que\n\ +la police de caractères TrueType des icônes est activée. +;Select font to display icon names.\n\ +;This selection is disabled while TrueType\n\ +;icon fonts are enabled. +; +; +MSGID_ICONSPAGE_ICONFONT_ASLTITLE +Chosissez une police de caractères pour les icônes, s'il vou plaît... +;Please select an icon font... +; +; +MSGID_ICONSPAGE_ICONTHUMBNAILS +Vignettes +;Thumbnails +; +; +MSGID_ICONSPAGE_SHOWTHUMBNAILS +Affichage de vignettes : +;Display Thumbnails +; +; +MSGID_ICONSPAGE_SHOWTHUMBNAILS_SHORTHELP +Choisir si et quand, les icônes d'images doivent\n\ +être affichées sous forme de vignettes :\n\ +Jamais - Ne pas afficher de vignettes.\n\ +Par défaut - Afficher les vignettes à la place des\n\ +icônes par défaut.\n\ +Toujours - Toujours afficher les vignettes. +;Select if and when icons are displayed as image thumbnails:\n\ +;Never - don't show thumbnails\n\ +;As default - show thumbnails instead of default icons\n\ +;Always - always show thumbnails +; +; +MSGID_ICONSPAGE_SHOWTHUMBNAILS_AS_DEFAULT +Ignorer le mode d'affichage \033bVoir seulement les icônes\033n : +;Ignore \033bShowOnlyIcons\033n mode: +; +; +MSGID_ICONSPAGE_SHOWTHUMBNAILS_AS_DEFAULT_SHORTHELP +Sélectionnez cette option afin de permettre l'affichage des\n\ +des vignettes concernant les icônes par défaut, dont les fenêtres\n\ +utilisent le mode d'affichage \033bVoir seulement les icônes\033n.\n\ +\n\ +Cette option est disponible si l'option \033bIcônes par défaut\033n,\n\ +depuis les préférences \033bAffichage de vignettes\033n, est activée. +;Select it to allow the displaying of icons\n\ +;thumbnails images for default icons with windows\n\ +;using the \033bShow Only Icons\033n show mode.\n\ +;\n\ +;This option is only availlable if \033bAs default\033n\n\ +;option is set from \033bDisplay Thumbnails\033n setting. +; +; +MSGID_ICONSPAGE_THUMBNAILS_SIZE +Taille des vignettes : +;Thumbnail size +; +; +MSGID_ICONSPAGE_THUMBNAILS_SIZE_SHORTHELP +Selection de la taille désirée des vignettes.\n\ +La taille actuelle peut varier, dû à l'aspect de l'image. +;Select desired size for thumbnail images.\n\ +;Actual size may vary, due to image aspect. +; +MSGID_ICONSPAGE_THUMBNAILS_MAXAGE +Nettoyage aprés : +;Cleanup after +; +MSGID_ICONSPAGE_THUMBNAILS_MAXAGE_SHORTHELP +Les vignettes du cache seront supprimées\n\ +si elles n'ont pu être localisées aprés le\n\ +nombre de jours spécifié, afin de limiter autant\n\ +que possible la taille du cache. +;Cached thumbnail images will be removed from the cache\n\ +;if they have not been accessed for more than the\n\ +;specified number of days, in order to keep cache\n\ +;size as small as possible. +; +MSGID_ICONSPAGE_THUMBNAILS_MAXAGE_DAYS +jours +;days +; +MSGID_ICONSPAGE_THUMBNAILS_MINSIZE_LIMIT +Taille minimum pour mise en cache : +;Minimum caching size: +; +MSGID_ICONSPAGE_THUMBNAILS_MINSIZE_LIMIT_SHORTHELP +Choisissez les dimensions minimum des images à ajouter au cache.\n\ +Les images comportants des dimensions plus petites que la valeur\n\ +spécifiée ici, ne seront pas ajoutées au cache. +;Select desired minimum dimensions for images to cache.\n\ +;Images with smallers dimensions than value specified here,\n\ +;will not be added to the cache. +; +MSGID_ICONSPAGE_TOOLTIPS_TRANSPARENCY +Transparence +;Transparency +; +MSGID_ICONSPAGE_TOOLTIPS_TRANSPARENCY_SHORTHELP +La bulle d'information des types de fichiers peut prendre\n\ +un aspect transparent. Vous pouvez choisir ici le degrès\n\ +de transparence desirée.\n\ +\033bNOTE :\033n L'effet de transparence est disponible que si\n\ +l'écran de votre bureau possède plus de 256 couleurs. +;Tooltips can be drawn transparent.\n\ +;Please select the degree of\n\ +;transparency for the tooltips.\n\ +;Please note that transparency is only available\n\ +;if your desktop screen has more than 256 colors. +; +MSGID_ICONSPAGE_THUMBNAILS_SETTINGS +Options +;Settings +; +MSGID_ICONSPAGE_THUMBNAILS_CACHE +Cache +;Caching +; +MSGID_ICONSPAGE_THUMBNAILS_QUALITY +Qualité +;Quality +; +MSGID_ICONSPAGE_THUMBNAILS_QUALITY_WORST +Basse +;Low +; +MSGID_ICONSPAGE_THUMBNAILS_QUALITY_BEST +Haute +;High +; +MSGID_ICONSPAGE_THUMBNAILS_QUALITY_SHORTHELP +Selection de la qualité du rendu des vignettes.\n\ +En général, avec la meilleur qualité possible,\n\ +la créaton des vignettes est plus lente.\n\ +Cependant, tout dépend du plugin de prévisualisation\n\ +utilisé. Pour exemple, l'utilisation du plugin\n\ +"\033bjpegpicture.pvplugin\033n" pour des images au format JPEG,\n\ +permet une création rapide des vignettes, dans ce cas la meilleur\n\ +valeur de la qualité du rendu des vignettes est sûrement souhaitable. +;This slider selects the quality of the generated thumbnails.\n\ +;Usually, better quality thumbnails take longer to create.\n\ +;The actual effect of quality setting depends on the preview plugin used. +; +MSGID_ICONSPAGE_THUMBNAILS_SQUARE +Vignettes toujours carrées : +;Thumbnails always square: +; +MSGID_ICONSPAGE_THUMBNAILS_SQUARE_SHORTHELP +Par défaut, la taille des vignettes dépendent de celles\n\ +précédemment créées, ex :\n\ +Elles peuvent être plus large que haute et vice versa.\n\ +Si cette option est activée, les icônes des vignettes auront\n\ +toujours un aspect carré et la même taille. +;By default, thumbnail image icons reflect the aspect ratio\n\ +;of their parent images, i.e. they can be wider than high or vice versa.\n\ +;If this checkbox is checked, thumbnail image icons are always square.\n\ +; +MSGID_ICONSPAGE_THUMBNAILS_ICONFRAME +Bords des vignettes +;Thumbnail Icon Frames +; +MSGID_ICONSPAGE_THUMBNAILS_ICONFRAME_NORMAL_SHORTHELP +Ce type de bord est traçé autour des icônes des vignettes non sélectionnées.\n\ +Les icônes \033bGlowIcons\033n ayant l'option \"icône sans bords\"\n\ +n'afficheront pas de bords.\n\ +Notez-bien que la valeur(plus bas) des bords des icônes, ne doit pas être\n\ +égale à zéro afin que les bords des icônes puissent être visibles. +;This type of border is drawn around unselected thumbnail icons.\n\ +;\033bGlowIcons\033n which have been marked as\n\ +;\"borderless\" will not show this border.\n\ +;Please note that the icon borders below must\n\ +;be non-zero for the icon border to show. +; +MSGID_ICONSPAGE_THUMBNAILS_ICONFRAME_SELECTED_SHORTHELP +Ce type de bord est traçé autour des icônes des vignettes sélectionnées.\n\ +Les \033bGlowIcons\033n ayant l'option \"icône sans bords\"\n\ +n'afficheront pas de bords.\n\ +Notez-bien que la valeur(plus bas) des bords des icônes, ne doit pas être\n\ +égale à zéro afin que les bords des icônes puissent être visibles. +;This type of border is drawn around selected thumbnail icons.\n\ +;\033bGlowIcons\033n which have been marked as\n\ +;\"borderless\" will not show this border.\n\ +;Please note that the icon borders below must\n\ +;be non-zero for the icon border to show. +; +MSGID_ICONSPAGE_THUMBNAILS_BACKFILL +Arrière-plan des vignettes coloré : +;Thumbnails background filled +; +MSGID_ICONSPAGE_THUMBNAILS_BACKFILL_SHORTHELP +Activez cette attribut afin de colorer tous les fonds des icônes des vignettes\n\ +d'aprés les couleurs définies depuis les préférences de Scalos Palette.\n\ +Si cette option n'est pas activée, les vignettes auront un arrière-plan transparent. +;Enable this attribute to draw all thumbnail icons with the\n\ +;backfill colors defined by Scalos palette prefs.\n\ +;If this switch is off, thumbnails have transparent background. +; +MSGID_ICONSPAGE_THUMBNAIL_BACKFILL_TRANSPARENCY +Arrière-plan des vignettes transparent +;Thumbnail background transparency +; +MSGID_ICONSPAGE_THUMBNAIL_BACKFILL_TRANSPARENCY_SHORTHELP +L'arrière-plan des icônes peut être traçer avec\n\ +le degrès de transparence défini ici. +;True-color icons can be drawn with filled\n\ +;background of selectable transparency. +; +MSGID_ICONSPAGE_SEL_ICONTEXT_RECT_GROUP +Rectangle du texte de l'icône sélectionnée +;Selected Icon Text Rectangle +; +MSGID_ICONSPAGE_SEL_ICONTEXT_RECT +Déssine un rectangle additionnel autour du texte de l'icône sélectioné. +;Draw additional rectangle around selected icon text +; +MSGID_ICONSPAGE_SEL_ICONTEXT_RECT_SHORTHELP +Cochez ce gadget afin de dessiner un rectangle autour du\n\ +texte de l'icône pour toutes les icônes, afin d'amélirer la vsibilité. +;Select this checkbox to draw a rectangle around the\n\ +;icon text of all selected icons, for improved visibility. +; +MSGID_ICONSPAGE_SEL_ICONTEXT_XBORDER +Additionel bord horizontal +;Additional Horizontal border +; +MSGID_ICONSPAGE_SEL_ICONTEXT_XBORDER_SHORTHELP +Bord horizontal additionel lequel est utilsé pour\n\ +le tracé d'un rectangle autour du texte de l'icône des icônes sélectionnées. +;Additional horizontal border which is used for\n\ +;drawing a rectangle around the icon text of selected icons. +; +MSGID_ICONSPAGE_SEL_ICONTEXT_YBORDER +Additionel bord vertical +;Additional Vertical border +; +MSGID_ICONSPAGE_SEL_ICONTEXT_YBORDER_SHORTHELP +Bord vertical additionnel lequel est utilsé pour\n\ +le tracé d'un rectangle autour du texte de l'icône des icônes sélectionnées. +;Additional vertical border which is used for drawing\n\ +;a rectangle around the icon text of selected icons. +; +MSGID_ICONSPAGE_SEL_ICONTEXT_RADIUS +Rayon du coin +;Corner Radius +; +MSGID_ICONSPAGE_SEL_ICONTEXT_RADIUS_SHORTHELP +Rayon du coin du rectangle déssiné\n\ +autour du test des cônes sélectionnées. +;Corner radius of the rectangle drawn\n\ +;around the text of selected icons. +; +MSGID_ICONSPAGE_SCALING_NOMINALSIZE +Taille nominale : +;Nominal Size: +; +MSGID_ICONSPAGE_SCALING_NOMINALSIZE_SHORTHELP +Ajustement standard de la taille appliquée aux icônes. +;Standard size adjustment applied to all icons. +; +MSGID_ICONSPAGE_SCALING_PERCENT +% +;% +; +;----------------------------------------------------------- +; +MSGID_DRAGNDROPPAGE_STYLE +Style : +; Style: +; +MSGID_DRAGNDROPPAGE_STYLE_SHORTHELP +L'étiquétte de l'icône peut être afficher\n\ +durant le déplacement de l'icône. +; The icon label may be displayed\nwhilst the icon is being dragged. +; +MSGID_DRAGNDROPPAGE_BOBS +Bobs +; Bobs +; +MSGID_DRAGNDROPPAGE_ROUTINES +Bob routines : +; Bob Routines: +; +MSGID_DRAGNDROPPAGE_ROUTINES_SHORTHELP +Scalos offre des routines de lissage rapides des icônes.\n\ +Ces routines particulières sont disponibles seulement si\n\ +votre bureau posséde plus de 256 couleurs. +; Scalos provides custom fast smooth icon dragging routines.\nThose custom routines are only used if you are\nrunning a desktop with more than 256 colours. +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY +Méthode de tranparence : +; Transparency Method: +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY_SHORTHELP +Quand l'option "Fantôme/Vraie transparence" est sélectionnée, la\n\ +transparence réelle est utilisée pour le tracé des déplacememnts et\n\ +dépôts des icônes. Autrement, le tracé en pointillés "fantôme"\n\ +est utilisé. La transparence réelle est disponible seulement\n\ +si votre bureau posséde plus de 256 couleurs. +; When \"Ghosted/Real Transparent\" is selected, use\nreal transparency to draw drag-drop icons. Otherwise,\ndotted \"ghosted\" display is used. Please note that\nreal transparency is only available if your\ndesktop screen has more than 256 colors. +; +MSGID_DRAGNDROPPAGE_DROPMARKMODE +Mode passage visible : +; Drop mark mode: +; +MSGID_DRAGNDROPPAGE_DROPMARKMODE_SHORTHELP +Scalos entourera les éléments qui seront\n\ +rencontrés durant le déplacement des icônes. +; Select which kind of drop-marks Scalos\nshows while you drag icons around. +; +MSGID_DRAGNDROPPAGE_LOOK +Aspect : +; Look: +; +MSGID_DRAGNDROPPAGE_LOOK_SHORTHELP +Un déclencheur peut changer l'aspect d'une icône\n\ +en cours de déplacement. Vous pouvez choisir, ci-dessous,\n\ +les \033bdéclencheurs\033n qui affecteront vos icônes. +; A Trigger can change the look of the icon\ncurrently being dragged. You can select what\n\033btriggers\033n should affect your icons below. +; +MSGID_DRAGNDROPPAGE_AUTOREMOVE +Suppréssion automatique des icônes : +; Auto remove icons: +; +MSGID_DRAGNDROPPAGE_AUTOREMOVE_SHORTHELP +Si activé, quand vous déplaçez une icône depuis sa\n\ +position d'origine, un aspect semi-transparent\n\ +de l'icône sera affiché à sa place d'origine. +; If enabled, when you drag icons away from their\noriginal position, only a semi-transparent shadow\nof the icon remains at the original place. +; +MSGID_DRAGNDROPPAGE_GROUP_MULTIPLE +Groupe icônes multiples : +; Group multiple icons: +; +MSGID_DRAGNDROPPAGE_GROUP_MULTIPLE_SHORTHELP +Quand vous déplacez des icônes\n\ +il seront considérés comme une pile\n\ +afin d'accèlèrer le système d'exploitation. +; When dragging multiple icons\nthey will appear as a pile\nto speed up OS. +; +MSGID_DRAGNDROPPAGE_DRAGGINGLABEL +Affichage d'étiquèttes durant déplacement : +; Display dragging label: +; +MSGID_DRAGNDROPPAGE_DRAGGINGLABEL_SHORTHELP +Pendant le déplacement des icônes, Scalos affichera\n\ +une ligne de texte comportant le nombre de fichiers,\n\ +répertoires ou volumes. +; When dragging multiple icons Scalos will display\na text line detailing number of files, drawers\nand devices being dragged. +; +MSGID_DRAGNDROPPAGE_FORCECOPY +Forcer la copie : +; Force copy: +; +MSGID_DRAGNDROPPAGE_FORCECOPY_SHORTHELP +Définir le qualificateur qui doit être utiliser\n\ +pour forcer la duplication(éviter un déplacement)\n\ +des fichiers et des répertoires. +; Define the qualifier key that is used to\nforce copying (instead of moving) any\ndragged files and drawers. +; +MSGID_DRAGNDROPPAGE_TRIGGERS +Déclencheurs +; Triggers +; +MSGID_DRAGNDROPPAGE_TRIGGERS_SHORTHELP +Activer un déclencheur changera l'apparence des icônes\n\ +avec l'\033baspect\033n choisi vu plus haut. +; Enabling a trigger will change the icons appearance\nto the \033bLook\033n configured above when the\nicon is above trigger. +; +MSGID_DRAGNDROPPAGE_QUALIFIERS +Qualificateurs +; Qualifiers +; +MSGID_DRAGNDROPPAGE_TRIGGERS_DISKICONS +Icônes des volumes : +; Disk icons +; +MSGID_DRAGNDROPPAGE_TRIGGERS_DRAWERICONS +Icônes des répertoires : +; Drawer icons +; +MSGID_DRAGNDROPPAGE_TRIGGERS_TOOLICONS +Icônes des outils : +; Tool icons +; +MSGID_DRAGNDROPPAGE_TRIGGERS_PROJECTICONS +Icônes des projets : +; Project icons +; +MSGID_DRAGNDROPPAGE_TRIGGERS_TRASHCANICONS +Icônes des corbeilles : +; Trashcan icons +; +MSGID_DRAGNDROPPAGE_TRIGGERS_KICKICONS +Icônes Kickstart : +; Kick icons +; +MSGID_DRAGNDROPPAGE_TRIGGERS_APPICONS +App-Icônes : +; Application icons +; +MSGID_DRAGNDROPPAGE_TRIGGERS_APPWINDOWS +Fenêtres-App : +; Application windows +; +MSGID_DRAGNDROPPAGE_TRIGGERS_ICONIFIED_WINDOWS +Fenêtres icônifiées : +; Iconified windows +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY_ICONDRAG +Déplacement des icônes +; Dragged icons +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY_ICONDRAG_SHORTHELP +Choix du degrès de transparence de l'icône pendant son déplacement.\n\ +0% correspond à une transparence complète(invisible !) des icônes.\n\ +100% correspond aux icônes opaques.\n\ +La transparence réelle est disponible seulement\n\ +si votre bureau posséde plus de 256 couleurs. +; Select degree of icon transparency when dragging icons.\n0%% means completely transparent (invisible!) icons.\n100%% means opaque icons.\nPlease note that real transparency is only available\nif your desktop screen has more than 256 colors. +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY_ICONSHADOW +Ombre portée des icônes +; Icon shadow +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY_ICONSHADOW_SHORTHELP +Choix du degrès de transparence de l'ombre porté d'une icône\n\ +qui se réfère à la position d'origine lorsque vous commençez\n\ +à déplacer une icône away.\n\ +0% correspond à une ombre portée complètement transparence(invisible !).\n\ +100% correspond à une ombre portèe opaque.\n\ +La transparence réelle est disponible seulement\n\ +si votre bureau posséde plus de 256 couleurs. +; Select degree of transparency of the icon shadow that\nremains at the original position when you start\ndragging the icon away.\n0% means completely transparent (invisible!) shadow.\n100% means opaque shadow.\nPlease note that real transparency is only available\nif your desktop screen has more than 256 colors. +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY_OPAQUE + > Opacité +; opaque +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY_TRANSPARENT +Transparence < +; transparent +; +MSGID_DRAGNDROPPAGE_EASY_MULTISELECT +Sélection multiple rapide des icônes : +; Easy Multiple Icon Selection: +; +MSGID_DRAGNDROPPAGE_EASY_MULTISELECT_SHORTHELP +Si coché, vous n'avez pas besoin de maintenir la\n\ +touche \033bSHIFT\033n enfoncée pour choisir plusieurs icônes. +; When enabled, you are not required to hold the\n\033bshift\033n key to select multiple icons. +; +MSGID_DRAGNDROPPAGE_EASY_MULTIDRAG +Déplacement multiple rapide des icônes : +; Easy Dragging of Multiple Icons: +; +MSGID_DRAGNDROPPAGE_EASY_MULTIDRAG_SHORTHELP +Si coché, vous n'avez pas besoin de maintenir la\n\ +touche \033bSHIFT\033n enfoncée pour déplacer plusieurs icônes. +; When enabled, you are not required to hold the\n\033bshift\033n key when you begin to drag\nmultiple selected icons. +; +; ** new in 40.12 ** +; +MSGID_DRAGNDROPPAGE_FORCEMAKELINK +Créer des liens : +;Create Links: +; +; ** new in 40.12 ** +; +MSGID_DRAGNDROPPAGE_FORCEMAKELINK_SHORTHELP +Définir le qualificateur qui doit être utiliser\n\ +pour créer des liens(éviter de copier) des\n\ +fichiers et répertoires en cours de mouvement. +;Define the qualifier key that is used to\n\ +;create links to (instead of copying) any\n\ +;dragged files and drawers. +; +; ** new in 40.12 ** +; +MSGID_DRAGNDROPPAGE_FORCEMOVE +Forcer le déplaçement : +;Force move: +; +; ** new in 40.12 ** +; +MSGID_DRAGNDROPPAGE_FORCEMOVE_SHORTHELP +Définir le qualificateur qui doit être utiliser\n\ +pour forcer le déplaçement(éviter de copier) des\n\ +fichiers et répertoires en cours de mouvement. +;Define the qualifier key that is used to\n\ +;force moving (instead of copying) any\n\ +;dragged files and drawers. +; +MSGID_DRAGNDROPPAGE_DROPMENU +Montrer le menu déposer : +;Show Drop Menu: +; +; +MSGID_DRAGNDROPPAGE_DROPMENU_SHORTHELP +Lorsque cette option est activée, un menu "popup" est affiché sur chaque opération\n\ +"Drag&Drop"(Déplacer et déposer") proposant une sélection rapide, soit pour \033bcopier\033n ou\n\ +\033bdéplacer\033n un élément, \033bcréer un lien\033n vers un élément, ou annuler\n\ +entièrement l'opération "Drag&Drop". +;When enabled, a popup menu is displayed on each drag-drop\n\ +;operation that allows easy selection whether to \033bcopy\033n or\n\ +;\033bmove\033n item, \033bcreate link\033n to item, or entirely cancel drag-drop. +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_SCALOS_WINDOWS +Fenêtres de Scalos +;Scalos Windows +; +MSGID_DRAGNDROPPAGE_POPOPENWINDOWS +Ouverture automatique des fenêtres +;Pop-Open Windows +; +MSGID_DRAGNDROPPAGE_SLIDER_POPOPWINDOW_DELAY +Délai d'ouverture automatique : +;Pop-Open Delay: +; +MSGID_DRAGNDROPPAGE_SLIDER_POPOPWINDOW_DELAY_SHORTHELP +Pendant une opération de déplacement et de dépot (drag&drop),\n\ +ceci est le nombre de seconds que vous devez garder immobile\n\ +le curseur au-dessus d'un répertoire ou d'un volume\n\ +avant que ce dernier ouvre sa fenêtre. +;During a drag&drop operation, this is the number of seconds\n\ +;you have to keep the mouse pointer steady over a drawer\n\ +;or volume icon before it pops open. +; +;----------------------------------------------------------- +; +MSGID_WINDOWPAGE_WINDOWTITLES +Titres des fenêtres +; Window Titles +; +MSGID_WINDOWPAGE_WINDOWTITLES_ROOTWINDOW +Fenêtre principale : +; Root Window: +; +MSGID_WINDOWPAGE_WINDOWTITLES_ROOTWINDOW_SHORTHELP +Ceci est le titre de la fenêtre principale de Scalos. Vous pouvez\n\ +voir ce titre de fénêtre, seulement si l'option "Arrière-Plan"\n\ +du menu principal de Scalos est désactivée. +; This is the title for the Scalos root window. You only\nsee this window title when you have the \"Backdrop\"\nmenu item in the Scalos main menu unchecked. +; +MSGID_WINDOWPAGE_WINDOWTITLES_ROOTWINDOW_DESCRIPTION +|\033b\0338Description +; |\033b\0338Description +; +MSGID_WINDOWPAGE_WINDOWTITLES_DIRECTORYWINDOW +Fenêtre des répertoires : +; Directory Window: +; +MSGID_WINDOWPAGE_WINDOWTITLES_DIRECTORYWINDOW_SHORTHELP +Ceci est le titre des fenêtres de toutes\n\ +les fenêtres des répertoires de Scalos. +; This is the window title for any\nnormal Scalos drawer window. +; +MSGID_WINDOWPAGE_WINDOWTITLES_DIRECTORYWINDOW_DESCRIPTION +|\033b\0338Description +; |\033b\0338Description +; +MSGID_WINDOWPAGE_WINDOWTYPE +Type de fenêtre : +; Window type: +; +MSGID_WINDOWPAGE_WINDOWTYPE_SHORTHELP +Choix du mode de rafraîchissement ; simple\n\ +ou intelligent ; de toutes les fenêtres de Scalos. +; Select whether you would like to be all\nScalos windows to be created as simple-refresh\nor smart-refresh window. +; +MSGID_WINDOWPAGE_CONTEXTMENU_DRAGBAR +Menu de la fenêtre sur titre seulement : +; Context menu on dragbar only: +; +MSGID_WINDOWPAGE_CONTEXTMENU_DRAGBAR_SHORTHELP +Apparition du menu popup sur le titre\n\ +de la fenêtre seulement, quand le bouton\n\ +droit de la souris est préssé. +; Only allows the windows pop-up menu\nto appear when the right mouse button\nis clicked over the\nwindows dragbar +; +MSGID_WINDOWPAGE_MMB_MOVE +Déplacer avec le MMB : +; MMB Moves Contents: +; +MSGID_WINDOWPAGE_MMB_MOVE_SHORTHELP +Déplacement du contenu des fenêtres\n\ +grâce au bouton du milieu de la souris. +; Allows the use of the middle mouse button\nto pan around the window contents +; +MSGID_WINDOWPAGE_SHOW_STATUSBAR +Afficher la barre de statut : +; Show status bar: +; +MSGID_WINDOWPAGE_SHOW_STATUSBAR_SHORTHELP +Voir la barre de statut située en bas des\n\ +fenêtres des répertoires. +; Globally sets wether directory windows\ndisplay the status bar at the bottom. +; +MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE +Taille par défaut des fenêtres +; Default Window Size +; +MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE_SHORTHELP +Ce sont les dimensions par défaut des fenêtres\n\ +des répertoires de Scalos. Les fenêtres pour les\n\ +répertoires sans icônes sont ouvertes d'après cette\n\ +position et cette taille. Vous ètes libre de positionner\n\ +et de redimensionner la fenêtre comme vous le désirez,\n\ +et de "figer la fenêtre" afin de sauvegarder les nouvelles\n\ +valeurs de la fenêtre spécifiée. +; These are the default dimensions for Scalos drawer\nwindows. Windows for drawers without icons are opened\nat this position and in this size. You are free to\nmove and resize the window any way you like, and\nuse \"snapshot window\" to permanently store the\nchanged values for that specific drawer window. +; +MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE_LEFT +Gauche : +; Left: +; +MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE_TOP +Haut : +; Top: +; +MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE_WIDTH +Largeur : +; Width: +; +MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE_HEIGHT +Hauteur : +; Height: +; +MSGID_WINDOWPAGE_CLEANUPSPACE +Espaces de mise-à-jour +; Cleanup Spaces +; +MSGID_WINDOWPAGE_CLEANUPSPACE_SHORTHELP +Ceci est la distance que Scalos laissera entre\n\ +les icônes positionnées lors de l'execution de la\n\ +commande "Mettre à jour". +; This are the distances Scalos will leave around\nicons when they are positioned with\nthe \"cleanup\" command. +; +MSGID_WINDOWPAGE_CLEANUPSPACE_LEFT +Gauche : +; Left: +; +MSGID_WINDOWPAGE_CLEANUPSPACE_TOP +Haut : +; Top: +; +MSGID_WINDOWPAGE_CLEANUPSPACE_XSKIP +Distance-X : +; X-Skip: +; +MSGID_WINDOWPAGE_CLEANUPSPACE_YSKIP +Distance-Y : +; Y-Skip: +; +MSGID_WINDOWPAGE_CLEANUP_ONRESIZE +Réarrangement automatique des icônes : +; Rearrange icons on resize +; +MSGID_WINDOWPAGE_CLEANUP_ONRESIZE_SHORTHELP +Si cette option est activée, toutes les icônes\n\ +dont la position n'est pas fixée, seront automatiquements\n\ +réarrangés si la taille de la fenêtre est modifiée. +; If this switch is enabled, all icons\n\ +; without fixed position are automatically\n\ +; rearranged when window is resized. +; +MSGID_WINDOWPAGE_SHOWALL_DEFAULT +Mode de \033bvisualisation\033n par défaut: +;Default mode for \033bShow All\033n: +; +; +MSGID_WINDOWPAGE_SHOWALL_DEFAULT_SHORTHELP +Cette option définie la valeur "par défaut"\n\ +de l'affichage du \033bcontenu\033n des fenêtres.\n\ +Vous pouvez définir "par défaut" si,\n\ +\033bseulement les icônes\033n ou bien\n\ +\033btous les fichiers\033n doivent être affichés. +;This setting selects how the value \"default\"\n\ +;is handled for \033bshow all\033n.\n\ +;You can select whether \"default\" shows\n\ +;\033bonly icons\033n, or \033ball files\033n. +; +MSGID_WINDOWPAGE_VIEWBY_DEFAULT +Type d'\033baffichage\033n par défaut: +;Default \033bView By\033n Mode: +; +; +MSGID_WINDOWPAGE_WINDOWTYPE_VIEWBY_DEFAULT_SHORTHELP +Cette option définie le type de mode de\n\ +vue qui doit être utilisé, pour tous les\n\ +répertoires avec le mode de vue "par défaut". +;Selects which view mode is to be used for all\n\ +;drawers with their view mode set to \"default\". +; +MSGID_WINDOWPAGE_CONTROLBAR_BROWSER_GADGETS +Gadgets du navigateur +;Browser Window Gadgets +; +; +MSGID_WINDOWPAGE_CONTROLBAR_GADGETS_SHORTHELP +Selectionnez ici les gadgets que vous désirez\n\ +avoir dans votre navigatieur de votre fenêtre. +;Select here which gadgets you would like to\n\ +;have in your browser window control bar. +; +; +MSGID_WINDOWPAGE_CONTROLBAR_AVAILABLE_GADGETS +Gadgets disponibles +;Available Gadgets +; +; +MSGID_WINDOWPAGE_CONTROLBAR_AVAILABLE_GADGETS_SHORTHELP +Choisir un ou plusieurs gadgets depuis cette liste et les\n\ +déposer dans la liste des \033bGadgets actifs\00n. +;Select one ore move gadgets from this list and drag\n\ +;them to the list of \033bActive Gadgets\00n. +; +; +MSGID_WINDOWPAGE_CONTROLBAR_ACTIVE_GADGETS +Activer des gadgets +;Active Gadgets +; +; +MSGID_WINDOWPAGE_CONTROLBAR_ACTIVE_GADGETS_SHORTHELP +Ce sont les gadgets actuels sur votre bare de navigaion.\n\ +Vous avez la possibilité de changer l'ordre des gadgets par tri via le drag-and-drop.\n\ +Pour supprimer des gadgets, déplacez les vers les\n\ +\033bGadgets disponibles\033n sur la gauche.\n\ +pour ajouter de nouveaux gadgets, déplaçez les depuis\n\ +\033bGadgets disponibles\033n à la position désirée. +;These are the gadgets currently on your control bar.\n\ +;Change the order of the gadgets by sorting them via drag-and-drop.\n\ +;To remove gadgets, drag them to the\n\ +;\033bAvailable Gadgets\033n on the left.\n\ +;To add new gadgets, drag new gadgets from the\n\ +;\033bAvailable Gadgets\033n to the position you want to see them. +; +; +MSGID_CONTROLBARGADGETLIST_TYPE +Type de gadget +;Gadget Type +; +; +MSGID_WINDOWPAGE_CONTROLBAR_NORMALIMAGE +Image non sélectionnée +;Unselected Image +; +; +MSGID_WINDOWPAGE_CONTROLBAR_NORMALIMAGE_ASLTITLE +Choix d'une image pour état non sélectionné +;Select image for unselected state +; +; +MSGID_WINDOWPAGE_CONTROLBAR_NORMALIMAGE_SHORTHELP +Choix d'une image datatype pour\n\ +l'état non sélectionné défini par l'utilisateur. +;Select here any datatypes image for the\n\ +;unselected state of a user-defined button. +; +; +MSGID_WINDOWPAGE_CONTROLBAR_SELECTEDIMAGE +Image sélectionnée +;Selected Image +; +; +MSGID_WINDOWPAGE_CONTROLBAR_SELECTEDIMAGE_ASLTITLE +Choix d'une image pour état sélectioné +;Select image for Selected state +; +; +MSGID_WINDOWPAGE_CONTROLBAR_SELECTEDIMAGE_SHORTHELP +Choix d'une image datatype pour\n\ +l'état sélectionné défini par l'utilisateur. +;Select here any datatypes image for the\n\ +;selected state of a user-defined button. +; +; +MSGID_WINDOWPAGE_CONTROLBAR_DISABLEDIMAGE +Image inactive +;Disabled Image +; +; +MSGID_WINDOWPAGE_CONTROLBAR_DISABLEDIMAGE_ASLTITLE +Choix d'une image pour état inactif +;Select image for Disabled state +; +; +MSGID_WINDOWPAGE_CONTROLBAR_DISABLEDIMAGE_SHORTHELP +Choix d'une image datatype pour\n\ +l'état inactif du gadget défini par l'utilisateur. +;Select here any datatypes image for the\n\ +;disabled state of a user-defined button. +; +; +MSGID_WINDOWPAGE_CONTROLBAR_ACTION +Action du bouton +;Button Action +; +; +MSGID_WINDOWPAGE_CONTROLBAR_ACTION_SHORTHELP +Pour les boutons définis par l'utilisateur,\n\ +selectionnez ici une action associée depuis\n\ +la liste des commandes disponibles, des menus de Scalos. +;For user-defined buttons select here any action from\n\ +;the list of available Scalos menu commands. +; +; +MSGID_WINDOWPAGE_CONTROLBAR_GADGETHELPTEXT +Texte d'aide +;Help Text +; +; +MSGID_WINDOWPAGE_CONTROLBAR_GADGETHELPTEXT_SHORTHELP +Texte d'aide pour les gadgets définis par l'utilisateur.\n\ +Ce texte est affiché lorsque vous gardez votre souris\n\ +positionnée pendant quelques secondes sur les gadgets +;For user-defined buttons, enter your gadget help text here.\n\ +;This text is displayed when you keep your mouse\n\ +;steadily positioned on the gadgets for a few seconds. +; +; +MSGID_WINDOWPAGE_CHECK_OVERLAP +Analyse du chevauchement des icônes : +;Check for Overlapping Icons: +; +; +MSGID_WINDOWPAGE_CHECK_OVERLAP_SHORTHELP +Globalement la verification ne peut être éffective si les icônes\n\ +ne se chevauchent pas.\n\ +Si coché, les icônes se chevauchants seront repositionnées lors de leurs lectures. +;Globally sets whether verification is performed that icons do\n\ +;not overlap each other.\n\ +;If enabled, overlapping icons will be repositioned when read. +; +MSGID_WINDOWPAGE_TRANSPARENCY_WINDOW +Transparence +;Transparency +; +MSGID_WINDOWPAGE_TRANSPARENCY_ACTIVEWINDOW +Fenêtre active +;Active window +; +MSGID_WINDOWPAGE_TRANSPARENCY_INACTIVEWINDOW +IFenêtre inactive +;Inactive windows +; +MSGID_WINDOWPAGE_TRANSPARENCY_ACTIVEWINDOW_SHORTHELP +Ici, vous pouvez choisir le degrès de transparence\n\ +pour le bureau actif, les icônes, ou les listeurs.\n\ +Le bureau obtiendra la transparence si il nest pas en arrière-plan. +;Here you can select the degree of transparency\n\ +;for the active Scalos desktop, icon, or text window.\n\ +;The desktop will only get transparent if it is not a backdrop window. +; +MSGID_WINDOWPAGE_TRANSPARENCY_INACTIVEWINDOW_SHORTHELP +Ici, vous pouvez choisir le degrès de transparence\n\ +pour le bureau inactif, les icônes, ou les listeurs.\n\ +Le bureau obtiendra la transparence si il nest pas en arrière-plan. +;Here you can select the degree of transparency\n\ +;for all inactive Scalos desktop, icon, or text windows.\n\ +;The desktop will only get transparent if it is not a backdrop window. +; +MSGID_WINDOWPAGE_CONTROLBAR_NORMAL_GADGETS +Gadgets des fenêtres standards +;Standard Window Gadgets +; +;----------------------------------------------------------- +; +; +MSGID_TEXTWINDOWSPAGE_SELECTION_BORDER_TRANSPARENCY +Transparence du contour +;Border Transparency +; +MSGID_TEXTWINDOWSPAGE_SELECTION_FILL_TRANSPARENCY +Transparence du fond +;Fill Transparency +; +MSGID_TEXTWINDOWSPAGE_GROUP_BASECOLOR +Couleur de base +;Base Color +; +MSGID_TEXTWINDOWSPAGE_SELECTIONMARK_BASECOLOR_SHORTHELP +Ici, vous pouvez ajuster la couleur de base pour\n\ +le marquage des icônes en mode texte. +;Here you can adjust the base color for the\n\ +;text window icon selection marker. +; +MSGID_TEXTWINDOWSPAGE_SELECTIONMARK_BORDER_TRANSPARENCY_SHORTHELP +Adjustage du degré de transparence pour le contour\n\ +des icônes en mode texte. +;Adjust degree of transparency for the border\n\ +;of the text window icon selection marker. +; +MSGID_TEXTWINDOWSPAGE_SELECTIONMARK_FILL_TRANSPARENCY_SHORTHELP +Adjustage du degré de transparence pour le fond intérieur\n\ +des icônes en mode texte. +;Adjust degree of transparency for the interior\n\ +;fill of the text window icon selection marker. +; +MSGID_TEXTWINDOWPAGE_DRAWERSORT_TOP +Avant les fichiers +;Before files +; +MSGID_TEXTWINDOWPAGE_DRAWERSORT_BOTTOM +Après les fichiers +;After files +; +MSGID_TEXTWINDOWPAGE_DRAWERSORT_MIXED +Avec les fichiers +;With files +; +MSGID_TEXTWINDOWSPAGE_DRAWERSORT +Tri des répertoires +;Drawer sorting +; +MSGID_TEXTWINDOWSPAGE_DRAWERSORT_SHORTHELP +Choisir comment les répertoires sont triés dans\n\ +les fenêtres en mode texte.\n\ +Les répertoires peuvent être toujours affichés en premier, toujours\n\ +en dernier, ou mélangés avec les fichiers. +;Select how drawers are sorted in text windows.\n\ +;Drawers can be displayed always on top, always\n\ +;on bottom, or mixed between files. +; +;----------------------------------------------------------- +; +MSGID_FILEDISPLAYPAGE_FONT +Police de caractères : +; Font: +; +MSGID_FILEDISPLAYPAGE_FONT_SHORTHELP +Cette police de caractères est utilisée pour\n\ +le contenu du texte des fenêtres.\n\ +Cette option n'est pas disponible tant que\n\ +la police de caractères TrueType des fenêtres\n\ +en mode texte est activée. +;Select font to display text window contents.\n\ +;This selection is disabled while TrueType\n\ +;text window fonts are enabled. +; +MSGID_FILEDISPLAYPAGE_FONT_ASLTITLE +Choisissez une police de caractères,s'il vous plaît... +; Please select a font... +; +MSGID_FILEDISPLAYPAGE_FONT_EXAMPLE +Exemple : +; Example: +; +MSGID_FILEDISPLAYPAGE_FONT_SAMPLETEXT +Ceci est un exemple de texte afin de visualiser\n\ +l'aspect de la police de caractères choisie. +; This is an example text to visualize what the selected font looks like +; +MSGID_FILEDISPLAYPAGE_SOFTLINKS_UNDERLINED +Affichage des noms de fichiers liés "liens logiciels" \033usousligné\033n : +; Display soft-link file names \033uunderlined\033n: +; +MSGID_FILEDISPLAYPAGE_SOFTLINKS_UNDERLINED_SHORTHELP +Si coché, les noms des "liens logiciels" sont\n\ +affichés \033usouslignés\033n. +; When this item is checked, names of soft-links\n\ +; are displayed \033uunderlined\033n. +; +MSGID_FILEDISPLAYPAGE_HIDE_HIDDENFILES +Fichiers cachés(#?\033b.\033n) non affichés : +; Hide hidden files: +; +MSGID_FILEDISPLAYPAGE_HIDE_HIDDENFILES_SHORTHELP +Un fichier caché est un nom de fichier commençant par\n\ +un '\033b.\033n' ou des fichiers icônes '\033b#?.info\033n' +; A hidden file is any filename beginning with\n\ +; a '\033b.\033n' or icon files '\033b#?.info\033n' +; +MSGID_FILEDISPLAYPAGE_AVAILABLE_COLUMNS +Colonnes disponibles +; Available Columns +; +MSGID_FILEDISPLAYPAGE_AVAILABLE_COLUMNS_SHORTHELP +Ce sont les colonnes non affichées des\n\ +fenêtres en mode texte. Si vous désirez que\n\ +certaines catégories soient disponobles,\n\ +déposez-les dans la liste "Affichage des colonnes". +; This are the columns currently not displayed\n\ +; in text windows. If you want some item to be\n\ +; displayed, drag it to the \"Displayed columns\" list. +; +MSGID_FILEDISPLAYPAGE_COLUMNS_INUSE +Affichage des colonnes +; Displayed Columns +; +MSGID_FILEDISPLAYPAGE_COLUMNS_INUSE_SHORTHELP +Ce sont les colonnes qui seront affichées dans\n\ +les fenêtres en mode texte. Vous pouvez changer\n\ +l'ordre d'affichage en les déplaçant. Si vous désirez que\n\ +certaines catégories ne soient pas affichées,\n\ +déposez-les dans la liste "Colonnes disponibles". +; This are the columns that will display in text\n\ +; windows. You may change the display order by\n\ +; drag-sorting the lines. If you want some item\n\ +; not to be displayed, drag it to\n\ +; the \"Available columns\" list. +; +MSGID_FILEDISPLAYPAGE_STRIPED +Affichages alternés : +; Striped Display +; +MSGID_FILEDISPLAYPAGE_STRIPED_SHORTHELP +Afficher dans le texte des fenêtres, une ligne sur deux\n\ +dans une couleur différente, afin d'améliorer la lisibilité.\n\ +L'affichage hachuré est disponible seulement\n\ +si votre bureau posséde plus de 256 couleurs. +; Shows every other line in text window\n\ +; in different color, to improve readability.\n\ +; Please note that striped display is only available\n\ +; if your desktop screen has more than 256 colors. +; +; ** new in 40.13 ** +MSGID_FILEDISPLAYPAGE_HIDE_PROTECTHIDDENFILES +Fichiers cachés(protection "\033bH\033n" active) non affichés : +; Hide files with protect bit hidden: +; +; ** new in 40.13 ** +MSGID_FILEDISPLAYPAGE_HIDE_PROTECTHIDDENFILES_SHORTHELP +Si coché, tous les fichiers ayant le bit de protection\n\ +(\033bH\033nSPARWED) activé, ne seront pas visibles. +; If checked, any file with the hidden protection\n\ +; bit(\033bH\033nSPARWED) activated, will be hidden. +; +; +MSGID_FILEDISPLAYPAGE_SELECTTEXTICONNAME +Zone de sélection des fichiers restreinte : +; Name column selects text icons +; +; +MSGID_FILEDISPLAYPAGE_SELECTTEXTICONNAME_SHORTHELP +Si cette option est activée, les fichiers des fenêtres\n\ +(sous le mode de vue "Affichage par nom"), peuvent être\n\ +sélectionnés uniquement sur la zone de la colonne \033bnom\033n.\n\ +Si inactive, la rangée entière peut être utilisée\n\ +pour sélectionner un fichier. +;If this checkmark is checked, text icons can\n\ +;only be selected within the \033bname\033n column.\n\ +;If unchecked, the entire row can be used\n\ +;to select the icon. +; +;----------------------------------------------------------- +; ** new in 40.11 ** +; +MSGID_TTFONTSPAGE_SCREENFONT +Police TrueType de l'écran +;TrueType Screen Font +; +; ** new in 40.11 ** +; +MSGID_TTFONTSPAGE_SCREENFONT_ENABLE +Utiliser la police TT de l'écran : +;Use TT Screen Font +; +; ** new in 40.11 ** +; +MSGID_TTFONTSPAGE_SCREENFONT_ENABLE_SHORTHELP +Lorsque ce gadget est coché, Scalos utilise\n\ +les polices de caractères TrueType pour l'écran. +;When this item is checked, Scalos uses\n\ +;TrueType fonts for screen font. +; +; ** new in 40.11 ** +; +MSGID_TTFONTSPAGE_SCREENFONT_SHORTHELP +Caractèristiques de la police TrueType de\n\ +l'écran(Style/Graisse/Taille/Nom). +;This is the textual TrueType screen font\n\ +;specification (style/weight/size/name). +; +; ** new in 40.11 ** +; +MSGID_TTFONTSPAGE_ICONFONT +Police TrueType des icônes +;TrueType Icon Font +; +; ** new in 40.11 ** +; +MSGID_TTFONTSPAGE_ICONFONT_ENABLE +Utiliser la police TT des icônes : +;Use TT Icon Font +; +; ** new in 40.11 ** +; +MSGID_FONTSPAGE_TTFICONFONT_ENABLE_SHORTHELP +Lorsque ce gadget est coché, Scalos utilise\n\ +les polices de caractères TrueType pour les icônes. +;When this item is checked, Scalos\n\ +;uses TrueType fonts for icons. +; +; ** new in 40.11 ** +; +MSGID_TTFONTSPAGE_ICONFONT_SHORTHELP +Caractèristiques de la police TrueType des\n\ +icônes(Style/Graisse/Taille/Nom). +;This is the textual TrueType icon font\n\ +;specification (style/weight/size/name). +; +; ** new in 40.11 ** +; +MSGID_TTFONTSPAGE_TEXTWINDOWFONT +Police TrueType du texte des fenêtres +;TrueType Text Window Font +; +; ** new in 40.11 ** +; +MSGID_TTFONTSPAGE_TTFTEXTWINDOWFONT_ENABLE +Utiliser la police TT du texte des fenêtres : +;Use TT Text WIndow Font +; +; ** new in 40.11 ** +; +MSGID_TTFONTSPAGE_TTFTEXTWINDOWFONT_ENABLE_SHORTHELP +Lorsque ce gadget est coché, Scalos utilise les polices\n\ +de caractères TrueType pour le texte des fenêtres. +;When this item is checked, Scalos uses\n\ +;TrueType fonts for text windows. +; +; ** new in 40.11 ** +; +MSGID_TTFONTSPAGE_TEXTWINDOWFONT_SHORTHELP +Caractèristiques de la police TrueType du texte\n\ +des fenêtres(Style/Graisse/Taille/Nom). +;This is the textual TrueType text window\n\ +;font specification (style/weight/size/name). +; +; ** new in 40.11 ** +; +MSGID_TTFONTSPAGE_SAMPLETEXT +The quick brown fox jumps over the lazy dog +;The quick brown fox jumps over the lazy dog +; +; ** new in 40.11 ** +; +MSGID_TTFONTSPAGE_SCREENFONT_SAMPLETEXT_SHORTHELP +Ceci est un aperçu de texte afin de visualiser\n\ +la police TrueType choisie pour l'écran. +;This is an example text to visualize what the\n\ +;selected TrueType screen font looks like. +; +; ** new in 40.11 ** +; +MSGID_TTFONTSPAGE_ICONFONT_SAMPLETEXT_SHORTHELP +Ceci est un aperçu de texte afin de visualiser\n\ +la police TrueType choisie pour les icônes. +;This is an example text to visualize what the\n\ +;selected TrueType icon font looks like. +; +; ** new in 40.11 ** +; +MSGID_TTFONTSPAGE_TEXTWINDOWFONT_SAMPLETEXT_SHORTHELP +Ceci est un aperçu de texte afin de visualiser\n\ +la police TrueType choisie pour le texte des fenêtres. +;This is an example text to visualize what the\n\ +;selected TrueType text window font looks like. +; +; ** new in 40.11 ** +; +MSGID_TTFONTSPAGE_SELECTSCREENFONT_ASLTITLE +Choix de la police TT pour l'écran... +;Select Screen TT Font... +; +; ** new in 40.11 ** +; +MSGID_TTFONTSPAGE_SELECTICONFONT_ASLTITLE +Choix de la police TT pour les icônes... +;Select Icon TT Font... +; +; ** new in 40.11 ** +; +MSGID_TTFONTSPAGE_SELECTTEXTWINDOWFONT_ASLTITLE +Choix de la police TT pour le texte des fenêtres... +;Select Text Window TT Font... +; +; ** new in 40.11 ** +; +MSGID_TTFONTSPAGE_SELECTFONT_ASL_OKBUTTON +D'accord +;Ok +; +; ** new in 40.11 ** +; +MSGID_TTFONTSPAGE_SELECTFONT_ASL_CANCELBUTTON +Annuler +;Cancel +; +; ** new in 40.14 ** +; +MSGID_TTFONTSPAGE_GLOBALS +Généralité +;Globals +; +; +MSGID_TTFONTSPAGE_ANTIALIASING +Anticrénalage : +;Antialiasing +; +; +MSGID_TTFONTSPAGE_ANTIALIASING_SHORTHELP +Controle de l'anticrénelage de ttengine(Actif, inactif ou automatique):\n\ +\033bInactif\033n - Pas d'anticrénelage.\n\ +\033bActif\033n - Anticrénelage activé.\n\ +\033bAutomatique\033n (défaut) - L'anticrénelage dépend de la taille\n\ +de la police de caractères. Les tailles de 9 pixels ou moins sont\n\ +anticrénelées, les tailles de 10 à 19 pixels ne le sont pas,\n\ +celles comprises entre 20 et plus, le sont.\n\ +Ces options peuvent être modifiées séparement depuis\n\ +la base de données des polices de caractères de ttengine. +;Controls ttengine antialiasing (on, off or automatic):\n\ +;Off - turns antialias off\n\ +;On - turns antialias on\n\ +;Auto (default) - antialias state depends on font\n\ +;size. Typically sizes of 9 or less pixels are\n\ +;antialiased, sizes from 10 to 19 pixels are not\n\ +;antialiased, sizes of 20 of more pixels are\n\ +;antialiased. These settings can be changed in the\n\ +;ttengine font database separately for every font face. +; +; +MSGID_TTFONTSPAGE_ANTIALIASING_ON +Actif +;On +; +; +MSGID_TTFONTSPAGE_ANTIALIASING_OFF +Inactif +;Off +; +; +MSGID_TTFONTSPAGE_ANTIALIASING_AUTO +Automatique +;Auto +; +; +MSGID_TTFONTSPAGE_GAMMA +Correction gamma : +;Gamma correction +; +; +MSGID_TTFONTSPAGE_GAMMA_SHORTHELP +Correction gamma ajustable, utilisé par\n\ +l'anticrénalage de ttengine. +;Adjustable gamma correction used for ttengine\n\ +;antialiasing. After RGB alphablending gamma\n\ +;correction is applied to resulting pixel colour\n\ +;according to x' = x ^ 1/gamma, where x\n\ +;is a RGB component. +; +;----------------------------------------------------------- +; +MSGID_MISCPAGE_MENU_CURRENTDIR +Menu sur répertoire courant : +; Menu CurrentDir: +; +MSGID_MISCPAGE_MENU_CURRENTDIR_SHORTHELP +Si actif, Scalos change de répertoire vers celui\n\ +de l'outil CLI avant d'executer une commande menu CLI. +; If enabled, Scalos changes to the directory of\n\ +; the CLI tool before running a CLI menu command. +; +MSGID_MISCPAGE_HARD_EMULATION +Forte émulation : +; Hard emulation: +; +MSGID_MISCPAGE_HARD_EMULATION_SHORTHELP +Si coché, des fonctions additionnelles\n\ +des vecteurs du Workbench sont "patchées" par Scalos.\n\ +Dans tous les cas, il ne devrait y avoir aucune raison\n\ +de désactiver l'option "Forte émulation". +; If this item is checked, some additional Workbench\n\ +; function vectors are patched by Scalos. In most\n\ +; cases, there shouldn't be any reason to\n\ +; turn off \"Hard emulation\". +; +MSGID_MISCPAGE_USE_EXALL +Utiliser ExALL() : +; Use ExAll(): +; +MSGID_MISCPAGE_USE_EXALL_SHORTHELP +Si coché, Scalos essayera d'utiliser la fonction "ExAll()",\n\ +fonction d'analyse rapide des répertoires. Habituellement, si\n\ +un fichier système ne tolère pas ExAll(), il y a un retour entièrement\n\ +automatique vers d'autres fonctions. Toutefois, il se peut que certains\n\ +fichiers système ; qui ne tolère pas ExAll() ; ne retournent pas\n\ +le code d'erreur approprié ou crash souvent. Si c'est le cas, essayez\n\ +de désactiver l'option "ExAll()". +; If this item is checked, Scalos will try to use\n\ +; the "ExAll()" function to scan directories.\n\ +; Usually, if a file system doesn't support ExAll(),\n\ +; there is a fully automatic fall-back to other\n\ +; functions. However, there might be some file systems\n\ +; that don't support ExAll() but don't return\n\ +; appropriate error codes either, or even crash.\n\ +; If you happen to have such a file system, try to\n\ +; turn "Use ExAll()" off. +; +MSGID_MISCPAGE_POPUPMENUS +Menus popup +; Popup menus +; +MSGID_MISCPAGE_POPUP_SELECTED_HOTKEY +Appliquer aux icônes sélectionnées : +; Apply to every selected icon: +; +MSGID_MISCPAGE_POPUP_SELECTED_HOTKEY_SHORTHELP +Défini le raccourci clavier qui\n\ +permettra aux commandes du menu "popup"\n\ +de sélectionner toutes les icônes choisies.\n\ +Normalement, les commandes du menu "popup" s'appliquent\n\ +seulement à l'icône située sous le curseur de la souris. +; Define the qualifier key that\napplies popup menu commands to\n\ +; every selected icon.\n\ +; Normally, popup menu commands only apply\n\ +; to the icon under the mouse pointer. +; +MSGID_MISCPAGE_DEFAULTSTACKSIZE +Taille de la pile par défaut +; Default Stack size +; +MSGID_MISCPAGE_DEFAULTSTACKSIZE_SHORTHELP +Saisir la taille de la pile pour la plupart des processus\n\ +internes de Scalos et les processus CLI et ARexx\n\ +déclenchés par Scalos. +; Sets the stack size for most internal Scalos\n\ +; processes and for CLI and ARexx processes\n\ +; started by Scalos. +; +MSGID_MISCPAGE_DEFAULTSTACKSIZE_OS35 +A partir du Workbench 3.5, la taille de la pile par défaut\n\ +est modifiable à partir du programme standard\n\ +\033bWorkbench\033n des préférences du système. +; Starting with Workbench 3.5, the default stack size\n\ +; is changed with the standard\n\ +;\033bWorkbench Preferences\033n program. +; +MSGID_MISCPAGE_LABELS_STACK +Pile : +; Stack +; +; ** New in 40.12 ** +MSGID_MISCPAGE_CREATE_LINKS +Créations de liens : +;Create links: +; +; ** New in 40.12 ** +MSGID_MISCPAGE_CREATE_LINKS_SHORTHELP +Choix du type de liens(matériels ou logiciels) que Scalos\n\ +tentera de créer lorsque un objet est déposé et que la ou\n\ +les touches de fonctions, correspondant à la création de\n\ +liens, sont activées. +;Select what kind of links Scalos tries to create\n\ +;when an object is dropped with the create-link\n\ +;qualifier key pressed. +; +;---------------------------------------------------------- +; +MSGID_MISCPAGE_POP_WORKBENCHPREFS_SHORTHELP +Lancement du programme standard: \033bPréférences du Workbench\033n. +;Launch standard \033bWorkbench Preferences\033n program. +; +MSGID_MISCPAGE_POPUP_SELECTED_ALWAYS +Toujours appliquer à toutes les icônes sélectionnées ? +;Always apply to all selected icons? +; +MSGID_MISCPAGE_POPUP_SELECTED_ALWAYS_SHORTHELP +Cocher ce gadget afin de \033btoujours\033n appliquer les\n\ +commandes des menus popup à toutes les icônes sélectionnées,\n\ +sans tenir compte du raccourci clavier. +;Select this checkbox to \033balways\033n apply popup menus\n\ +;to every selected icons, regardless of qualifier key +; +MSGID_MISCPAGE_COPYBUFFERSIZE +Taille du tampon de copie des fichiers : +;File Copy Buffer Size: +; +MSGID_MISCPAGE_COPYBUFFERSIZE_SHORTHELP +Défini la taillle du tampon des copies des fichiers. +;Sets the buffer size for file copying. +; +; +MSGID_MISCPAGE_LABELS_FILEOPERATIONS +Opérations sur les fichiers +;File Operations +; +MSGID_MISCPAGE_LABELS_UNDOSTEPS +Nombre maximum de pas précédents +;Maximum Number of Undo Steps +; +MSGID_MISCPAGE_UNDOSTEPS +Max. de pas précédents : +;Max. Undo Steps: +; +MSGID_MISCPAGE_UNDOSTEPS_SHORTHELP +Ici, vous pouvez limiter le nombre de\n\ +pas Précédents/Suivants disponibles. +;Here you can limit the number of\n\ +;available Undo/Redo steps. +; +;----------------------------------------------------------- +; +MSGID_PLUGINSPAGE_ACTIVEPLUGINS +Plugins actifs +; Active Plugins +; +MSGID_PLUGINSPAGE_INSTALLEDPLUGINS +\033cPlugins installés +; \033cInstalled Plugins +; +MSGID_PLUGINSPAGE_INSTALLEDPLUGINS_SHORTHELP +Ceci est la liste complète de tous les plugins OOP qui\n\ +sont chargés avant le démarrage de Scalos. Les plugins\n\ +OOP ajoute de nouvelles caractèristiques à Scalos ou\n\ +ammèliorent celles dèjà existantes. +; This is a complete list of all OOP plugins that\n\ +; are loaded upon Scalos startup. OOP plugins add\n\ +; new features to Scalos or improve existing\n\ +; Scalos features. +; +MSGID_PLUGINSPAGE_ADD_NEW +\033cAjouter +; \033cAdd New +; +MSGID_PLUGINSPAGE_ADD_NEW_SHORTHELP +Ajouter un nouveau plugin OOP à la liste. Ce plugin\n\ +sera activé au prochain démarrage de Scalos. +; Add a new OOP plugin to the list. This plugin\n\ +; will be activated upon next Scalos startup. +; +MSGID_PLUGINSPAGE_REMOVE_SELECTED +\033cSupprimmer +; \033cRemove Selected +; +MSGID_PLUGINSPAGE_REMOVE_SELECTED_SHORTHELP +Supprime l'actuel plugin sélectionné\n\ +de la liste. Scalos ne chargera plus\n\ +celui-ci. Ce changement prendra effet\n\ +lors du prochain démarrage de Scalos. +; Remove the currently selected plugin\n\ +; from the list. Scalos will not load the\n\ +; plugin again. This change will only become\n\ +; effective upon next Scalos startup. +; +MSGID_PLUGINSPAGE_NAME +\033lNom : +; \033lName: +; +MSGID_PLUGINSPAGE_NAME_SHORTHELP +C'est le nom du plugin sélectionné\n\ +qui a été donner par son créateur. +; This is the name the selected plugin\n\ +; has been given by its creator. +; +MSGID_PLUGINSPAGE_FILENAME +\033lFichier : +; \033lFile: +; +MSGID_PLUGINSPAGE_FILENAME_SHORTHELP +C'est le chemin et le nom\n\ +du plugin sélectionné. +; This is the complete filename and\n\ +; path for the selected plugin. +; +MSGID_PLUGINSPAGE_VERSION +\033lVersion : +; \033lVersion: +; +MSGID_PLUGINSPAGE_VERSION_SHORTHELP +C'est la version actuelle\n\ +du plugin sélectionné. +; This is the current version\n\ +; of the selected plugin. +; +MSGID_PLUGINSPAGE_DESCRIPTION +\033lDescription : +; \033lDescription: +; +MSGID_PLUGINSPAGE_DESCRIPTION_SHORTHELP +Ceci est la description de ce que\n\ +le plugin sélectionné est supposé faire. +; This is a description of what the\n\ +; selected plugin is supposed to do. +; +MSGID_PLUGINSPAGE_CREATOR +\033lCréateur : +; \033lCreator: +; +MSGID_PLUGINSPAGE_CREATOR_SHORTHELP +C'est le nom du créateur\n\ +du plugin en question. +; This is the creator's name\n\ +; of the selected plugin. +; +MSGID_PLUGINSPAGE_EDIT_PREFERENCES +\033cEdition des préférences +; \033cEdit Preferences +; +MSGID_PLUGINSPAGE_EDIT_PREFERENCES_SHORTHELP +\033cEdition des préférences +; \033cEdit Preferences +; +MSGID_ADD_PLUGIN_ASLTITLE +Choix du nouveau plugin OOP... +; Select new OOP plugin... +; +MSGID_MODULESPAGE_MODULE_PREFERENCES +Préférences des modules +; Module Preferences +; +MSGID_MODULESPAGE_MODULE_PREFERENCES_NOTICE +Afin de configurer les options des modules de Scalos vous devez\n\ +clickez sur l'image du gadget pop-up se trouvant à droite du nom\n\ +des modules. Une nouvelle fenêtre souvrira avec les options spécifiques\n\ +du module choisi.\n\ +\n\ +Si aucune configuration n'est disponible pour certains modules,\n\ +l'image du gadget pop-up les concernants ne sera pas clickable. +; To configure any Scalos module's settings you must\n\ +; click on the pop-up image gadget to the right of the modules name.\n\ +; This will open a new window with specific settings in it.\n\ +; \n\ +; If no configuration is available for a certain module the pop-up gadget will be disabled. +; +MSGID_MODULESPAGE_DELETE +Effacer +; Delete +; +MSGID_MODULESPAGE_EMPTY_TRASHCAN +Vider la corbeille +; Empty Trashcan +; +MSGID_MODULESPAGE_EXECUTE_COMMAND +Executer une commande +; Execute Command +; +MSGID_MODULESPAGE_INFORMATION +Information +; Information +; +MSGID_MODULESPAGE_NEWDRAWER +Nouveau répertoire +; New Drawer +; +MSGID_MODULESPAGE_REBOOT +Initialisation +; Reboot +; +MSGID_MODULESPAGE_RENAME +Renommer +; Rename +; +MSGID_MODULESPAGE_SYSTEM_INFORMATION +Information sytème +; System Information +; +MSGID_SAVEBUTTON +\033cSauver +; \033cSave +; +MSGID_SAVEBUTTON_SHORTHELP +Pressez ce bouton afin de sauvegarder\n\ +les options vers "\033bENVARC:Scalos/Scalos.prefs\033n"\n\ +et les rendre permanentes. +; Press this button to save \n\ +; the current settings to\n\ +; "ENVARC:Scalos/Scalos.prefs"\n\ +; and make changes permanent. +; +MSGID_USEBUTTON +\033cUtiliser +; \033cUse +; +MSGID_USEBUTTON_SHORTHELP +Pressez ce bouton afin de sauvegarder\n\ +les options vers "\033bENV:Scalos/Scalos.prefs\033n"\n\ +et conserver les options jusqu'au prochain re-dèmarrage. +; Press this button to save \n\ +; the current settings to\n\ +; "ENV:Scalos/menu13.prefs"\n\ +; and keep settings until reboot. +; +MSGID_CANCELBUTTON +\033cAnnuler +; \033cCancel +; +MSGID_CANCELBUTTON_SHORTHELP +Pressez ce bouton afin d'annuler\n\ +et de perdre tout changement. +; Press this button to abort \nand forget all changes. +; +MSGID_ABOUTREQOK +_D'accord +; _OK +; +MSGID_ABOUTREQFORMAT +\33c\033bPréférences de Scalos V\0333%ld\0331.\0333%ld\033n\n\ +%s\n\ +\0331© 2003%s \033bThe Scalos Team\033n +; \33c\033bScalos Main Preferences V%ld.%ld\033n\n© 2003-2004 The Scalos Team +; +MSGID_DESKTOPPAGES_SCREENTITLE_ALWAYS +Toujours visible +; Always visible +; +MSGID_DESKTOPPAGES_SCREENTITLE_POP +Rendu visible par la souris +; Pops up under mouse +; +MSGID_DESKTOPPAGES_SCREENTITLE_NEVER +Caché en permanence +; permanently hidden +; +MSGID_ICONSPAGES_DRAGNDROP_DRAGGING +Déplacement +; Dragging +; +MSGID_ICONSPAGES_DRAGNDROP_TRANSPARENCY +Transparence +; Transparency +; +MSGID_ICONSPAGES_DRAGNDROP_TRIGGERS +Déclencheurs +; Triggers +; +MSGID_FRAMEWINDOW_TITLE +Bords disponibles +; Available Frames +; +MSGID_PLUGINLIST_NAME +Nom +; Name +; +MSGID_PLUGINLIST_PATH +Chemin +; Path +; +;----------------------------------------------------------- +; +; ** new in 40.11 ** +; +MSGID_STARTUP_FAILURE +Le lancement de Scalos Prefs a échoué +;Scalos Prefs startup failed +; +; ** new in 40.11 ** +; +MSGID_STARTUP_RETRY_QUIT_GAD +Recommençer|Quitter +;Try again|Quit +; +; ** new in 40.11 ** +; +MSGID_STARTUP_MCC_NOT_FOUND +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +Celle-ci n'est pas installée. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; ** new in 40.11 ** +; +MSGID_STARTUP_OLD_MCC +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +\n\ +La version installée est V%lu.%lu, installez-en une plus récente s'il vous plaît ! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; ** new in 40.11 ** +; +MSGID_STARTUP_MCC_IN_USE +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +%lu.%lu est actuellement utilisée par d'autres applications.\n\ +\n\ +Une fois la version requise installée,\n\ +fermez tous les programmes MUI, soyez sûr que l'ancienne classe\n\ +ne soit plus présente dans la mémoire puis, essayez de nouveau. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +; +MSGID_ADDPLUGIN_FAILURE +Défaillance - Ajoût d'un plugin +;Add Plugin Failure +; +; +; +MSGID_ADDPLUGIN_OK_GAD +D'accord +;Ok +; +; +; +MSGID_ADDPLUGIN_COULD_NOT_ADD +Impossible d'ajoûter le plugin.\n\ +Le chargement du plugin \"%s\" a échoué. +;Could not add plugin.\n\ +;Opening the plugin \"%s\" failed. +; +;----------------------------------------------------------- +; +MSGID_DESKTOPPAGE_ICONS_HIDDENDEVICES +Unités cachées +;Hidden Devices +; +MSGID_DESKTOPPAGE_HIDDENDEVICES_SHORTHELP +Ici you pouvez sélectionner les unités qui ne devront\n\ +pas apparaître sur le bureau.\n\ +Cette option est similaire à celle disponible depuis les\n\ +préferences du Workbench de l'OS3.9. +;Here you can select which devices will never show up on desktop.\n\ +;This is the same setting as available in OS3.9 Workbench Prefs. +; +;----------------------------------------------------------- +; +MSGID_DESKTOPPAGE_LAYOUTPREFERENCES +Disposition des icônes sur le bureau +;Desktop Layout Preferences by Icon Type +; +MSGID_DESKTOPPAGE_LAYOUT_WBDISK +Volumes : +;Disk icons: +; +MSGID_DESKTOPPAGE_LAYOUT_WBDISK_SHORTHELP +Choix de la disposition des icônes du bureau\n\ +pour les \033bicônes de volumes\033n.\n\ +\033iPar colonnes\033n, les icônes sont disposées en colonne\n\ +du haut vers le bas. Une nouvelle colonne est créée lorsque le\n\ +le bas de la fenêtre du bureau est atteint.\n\ +\033iPar rangées\033n, les icônes sont disposées en rangées\n\ +de la gauche vers la droite, une nouvelle rangée est créée lorsque le\n\ +bord droit de la fenêtre du bureau est atteint. +;Select preferred icon layout direction\n\ +;for \033bdisk icons\033n in desktop window.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +MSGID_DESKTOPPAGE_LAYOUT_WBDRAWER +Répertoires : +;Drawer icons: +; +MSGID_DESKTOPPAGE_LAYOUT_WBDRAWER_SHORTHELP +Choix de la disposition des icônes du bureau\n\ +pour les \033bicônes des répertoires\033n.\n\ +\033iPar colonnes\033n, les icônes sont disposées en colonne\n\ +du haut vers le bas. Une nouvelle colonne est créée lorsque le\n\ +le bas de la fenêtre du bureau est atteint.\n\ +\033iPar rangées\033n, les icônes sont disposées en rangées\n\ +de la gauche vers la droite, une nouvelle rangée est créée lorsque le\n\ +bord droit de la fenêtre du bureau est atteint. +;Select preferred icon layout direction\n\ +;for \033bdrawer icons\033n in desktop window.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +MSGID_DESKTOPPAGE_LAYOUT_WBTOOL +Outils : +;Tool icons: +; +MSGID_DESKTOPPAGE_LAYOUT_WBTOOL_SHORTHELP +Choix de la disposition des icônes du bureau\n\ +pour les \033bicônes des outils\033n.\n\ +\033iPar colonnes\033n, les icônes sont disposées en colonne\n\ +du haut vers le bas. Une nouvelle colonne est créée lorsque le\n\ +le bas de la fenêtre du bureau est atteint.\n\ +\033iPar rangées\033n, les icônes sont disposées en rangées\n\ +de la gauche vers la droite, une nouvelle rangée est créée lorsque le\n\ +bord droit de la fenêtre du bureau est atteint. +;Select preferred icon layout direction\n\ +;for \033btool icons\033n in desktop window.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +MSGID_DESKTOPPAGE_LAYOUT_WBPROJECT +Projets : +;Project icons: +; +MSGID_DESKTOPPAGE_LAYOUT_WBPROJECT_SHORTHELP +Choix de la disposition des icônes du bureau\n\ +pour les \033bicônes des projets\033n.\n\ +\033iPar colonnes\033n, les icônes sont disposées en colonne\n\ +du haut vers le bas. Une nouvelle colonne est créée lorsque le\n\ +le bas de la fenêtre du bureau est atteint.\n\ +\033iPar rangées\033n, les icônes sont disposées en rangées\n\ +de la gauche vers la droite, une nouvelle rangée est créée lorsque le\n\ +bord droit de la fenêtre du bureau est atteint. +;Select preferred icon layout direction\n\ +;for \033bproject icons\033n in desktop window.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +MSGID_DESKTOPPAGE_LAYOUT_WBGARBAGE +Corbeilles : +;Trashcan icons: +; +MSGID_DESKTOPPAGE_LAYOUT_WBGARBAGE_SHORTHELP +Choix de la disposition des icônes du bureau\n\ +pour les \033bicônes des corbeilles\033n.\n\ +\033iPar colonnes\033n, les icônes sont disposées en colonne\n\ +du haut vers le bas. Une nouvelle colonne est créée lorsque le\n\ +le bas de la fenêtre du bureau est atteint.\n\ +\033iPar rangées\033n, les icônes sont disposées en rangées\n\ +de la gauche vers la droite, une nouvelle rangée est créée lorsque le\n\ +bord droit de la fenêtre du bureau est atteint. +;Select preferred icon layout direction\n\ +;for \033btrashcan icons\033n in desktop window.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +MSGID_DESKTOPPAGE_LAYOUT_WBDEVICE +Unitées : +;Device icons: +; +MSGID_DESKTOPPAGE_LAYOUT_WBDEVICE_SHORTHELP +Choix de la disposition des icônes du bureau\n\ +pour les \033bicônes des unitées\033n.\n\ +\033iPar colonnes\033n, les icônes sont disposées en colonne\n\ +du haut vers le bas. Une nouvelle colonne est créée lorsque le\n\ +le bas de la fenêtre du bureau est atteint.\n\ +\033iPar rangées\033n, les icônes sont disposées en rangées\n\ +de la gauche vers la droite, une nouvelle rangée est créée lorsque le\n\ +bord droit de la fenêtre du bureau est atteint. +;Select preferred icon layout direction\n\ +;for \033bdevice icons\033n in desktop window.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +MSGID_DESKTOPPAGE_LAYOUT_WBKICK +Volumes Kickstart : +;Kickstart Disk icons: +; +MSGID_DESKTOPPAGE_LAYOUT_WBKICK_SHORTHELP +Choix de la disposition des icônes du bureau\n\ +pour les \033bicônes des volumes kickstarts\033n.\n\ +\033iPar colonnes\033n, les icônes sont disposées en colonne\n\ +du haut vers le bas. Une nouvelle colonne est créée lorsque le\n\ +le bas de la fenêtre du bureau est atteint.\n\ +\033iPar rangées\033n, les icônes sont disposées en rangées\n\ +de la gauche vers la droite, une nouvelle rangée est créée lorsque le\n\ +bord droit de la fenêtre du bureau est atteint. +;Select preferred icon layout direction\n\ +;for \033bkickstart disk icons\033n in desktop window.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +MSGID_DESKTOPPAGE_LAYOUT_WBAPPICON +Applications : +;Application icons: +; +MSGID_DESKTOPPAGE_LAYOUT_WBAPPICON_SHORTHELP +Choix de la disposition des icônes du bureau\n\ +pour les \033bicônes des applications\033n.\n\ +\033iPar colonnes\033n, les icônes sont disposées en colonne\n\ +du haut vers le bas. Une nouvelle colonne est créée lorsque le\n\ +le bas de la fenêtre du bureau est atteint.\n\ +\033iPar rangées\033n, les icônes sont disposées en rangées\n\ +de la gauche vers la droite, une nouvelle rangée est créée lorsque le\n\ +bord droit de la fenêtre du bureau est atteint. +;Select preferred icon layout direction\n\ +;for \033bapplication icons\033n in desktop window.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +;----------------------------------------------------------- +; +MSGID_ICONSPAGE_LAYOUTPREFERENCES +Disposition des icônes +;Layout Preferences by Icon Type +; +MSGID_ICONSPAGE_LAYOUT_WBDRAWER +Répertoires : +;Drawer icons: +; +MSGID_ICONSPAGE_LAYOUT_WBDRAWER_SHORTHELP +Choix de la disposition des icônes dans les fenêtres\n\ +pour les \033bicônes des répertoires\033n.\n\ +\033iPar colonnes\033n, les icônes sont disposées en colonne\n\ +du haut vers le bas. Une nouvelle colonne est créée lorsque le\n\ +le bas de la fenêtre est atteint.\n\ +\033iPar rangées\033n, les icônes sont disposées en rangées\n\ +de la gauche vers la droite, une nouvelle rangée est créée lorsque le\n\ +coté droit de la fenêtre est atteint. +;Select preferred icon layout direction\n\ +;for \033bdrawer icons\033n in icon windows.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +MSGID_ICONSPAGE_LAYOUT_WBTOOL +Outils : +;Tool icons: +; +MSGID_ICONSPAGE_LAYOUT_WBTOOL_SHORTHELP +Choix de la disposition des icônes dans les fenêtres\n\ +pour les \033bicônes des outils\033n.\n\ +\033iPar colonnes\033n, les icônes sont disposées en colonne\n\ +du haut vers le bas. Une nouvelle colonne est créée lorsque le\n\ +le bas de la fenêtre est atteint.\n\ +\033iPar rangées\033n, les icônes sont disposées en rangées\n\ +de la gauche vers la droite, une nouvelle rangée est créée lorsque le\n\ +coté droit de la fenêtre est atteint. +;Select preferred icon layout direction\n\ +;for \033btool icons\033n in icon windows.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +MSGID_ICONSPAGE_LAYOUT_WBPROJECT +Projets : +;Project icons: +; +MSGID_ICONSPAGE_LAYOUT_WBPROJECT_SHORTHELP +Choix de la disposition des icônes dans les fenêtres\n\ +pour les \033bicônes des projets\033n.\n\ +\033iPar colonnes\033n, les icônes sont disposées en colonne\n\ +du haut vers le bas. Une nouvelle colonne est créée lorsque le\n\ +le bas de la fenêtre est atteint.\n\ +\033iPar rangées\033n, les icônes sont disposées en rangées\n\ +de la gauche vers la droite, une nouvelle rangée est créée lorsque le\n\ +coté droit de la fenêtre est atteint. +;Select preferred icon layout direction\n\ +;for \033bproject icons\033n in icon windows.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +;----------------------------------------------------------- +; +; +MSGID_SCPGADGETTYPE_BACKBUTTON +Bouton précédent +;Back Button +; +; +MSGID_SCPGADGETTYPE_FORWARDBUTTON +Bouton suivant +;Forward Button +; +; +MSGID_SCPGADGETTYPE_UPBUTTON +Bouton parent +;Up Button +; +; +MSGID_SCPGADGETTYPE_HISTORY +Bouton de l'historique +;History Button +; +; +MSGID_SCPGADGETTYPE_BROWSEBUTTON +Bouton de navigation +;Browse Button +; +; +MSGID_SCPGADGETTYPE_VIEWBY +Vue par cycle +;View By Cycle +; +; +MSGID_SCPGADGETTYPE_SHOWMODE +Afficher le mode cycle +;Show Mode Cycle +; +; +MSGID_SCPGADGETTYPE_SEPARATOR +(Separateur) +;(Separator) +; +; +MSGID_SCPGADGETTYPE_ACTIONBUTTON +Bouton utilisateur +;User-defined Button +; +; +MSGID_SCPGADGETTYPE_UNKNOWN +??Inconnu?? +;??unknown?? +; +;----------------------------------------------------------- +; +MSGID_COM1NAME +Mis en arrière-plan +; Backdrop +; +; +MSGID_COM2NAME +Executer une commande +; Execute Command +; +; +MSGID_COM3NAME +Tout retracer +; Redraw All +; +; +MSGID_COM4NAME +Tout mettre à jour +; Update All +; +; +MSGID_COM5NAME +A propos de Scalos +; About Scalos +; +; +MSGID_COM6NAME +Quitter +; Quit +; +; +MSGID_COM7NAME +Nouveau répertoire +; New Drawer +; +; +MSGID_COM8NAME +Ouvrir Parent +; Open Parent +; +; +MSGID_COM9NAME +Fermer fenêtre +; Close Window +; +; +MSGID_COM10NAME +Mettre à jour +; Update +; +; +MSGID_COM11NAME +Sélectionner le contenu +; Select Contents +; +; +MSGID_COM12NAME +Réorganiser +; Cleanup +; +; +MSGID_COM13NAME +Figer - Fenêtre +; Snapshot - Window +; +; +MSGID_COM14NAME +Figer - Tout +; Snapshot - All +; +; +MSGID_COM15NAME +Montrer - Seulement les icônes +; Show - Only Icons +; +; +MSGID_COM16NAME +Montrer - Tous les fichiers +; Show - All Files +; +; +MSGID_COM17NAME +Afficher par - Icône +; View By - Icon +; +; +MSGID_COM18NAME +Afficher par - Texte +; View By - Text +; +; +MSGID_COM19NAME +Ouvrir +; Open +; +; +MSGID_COM20NAME +Relancer Scalos +; Reset Scalos +; +; +MSGID_COM21NAME +Renommer +; Rename +; +; +MSGID_COM22NAME +Information +; Information +; +; +MSGID_COM23NAME +Figer +; Snapshot +; +; +MSGID_COM24NAME +Libérer +; UnSnapshot +; +; +MSGID_COM25NAME +Sortir +; Leave Out +; +; +MSGID_COM26NAME +Ranger +; Put Away +; +; +MSGID_COM27NAME +Effacer +; Delete +; +; +MSGID_COM28NAME +Copier +; Clone +; +; +MSGID_COM29NAME +Vider la corbeille +; Empty Trashcan +; +; +MSGID_COM30NAME +Dernier message +; Last Message +; +; +MSGID_COM31NAME +Retracer +; Redraw +; +; +MSGID_COM32NAME +Iconifier +; Iconify +; +; +MSGID_COM33NAME +Formater le Volume... +; Format Disk... +; +; +MSGID_COM34NAME +Désactiver... +; Shutdown... +; +; +MSGID_COM35NAME +Ajuster la taille +; Size to fit +; +; +MSGID_COM36NAME +Ne rien sélectionner +; Clear Selection +; +; +MSGID_COM37NAME +Afficher par - Taille +; View By - Size +; +; +MSGID_COM38NAME +Afficher par - Date +; View By - Date +; +; +MSGID_COM39NAME +Copier le fichier +; Copy file +; +; +MSGID_COM40NAME +Couper le fichier +; Cut file +; +; +MSGID_COM41NAME +Coller le fichier +; Paste file +; +; +MSGID_COM42NAME +Afficher par - Type +; View By - Type +; +; +MSGID_COM43NAME +Réorganiser par - Nom +; Cleanup By - Name +; +; +MSGID_COM44NAME +Réorganiser par - Date +; Cleanup By - Date +; +; +MSGID_COM45NAME +Réorganiser par - Taille +; Cleanup By - Size +; +; +MSGID_COM46NAME +Réorganiser par - Type +; Cleanup By - Type +; +; +MSGID_COM_ICONPROPERTIES +Propriété des icônes +;Icon properties +; +; +MSGID_COM_WINDOWPROPERTIES +Propriété des fenêtres +;Window properties +; +; +MSGID_COM47NAME +Afficher par - Défaut +;View By - Default +; +; +MSGID_COM48NAME +Montrer - Défaut +;Show - Default +; +; +MSGID_COM49NAME +Copier vers... +;Copy to... +; +; +MSGID_COM50NAME +Déplacer vers... +;Move to ... +; +; +MSGID_COM51NAME +Créer une vignette +; +; +MSGID_COM_OPENNEWWINDOW +Ouvrir dans une nouvelle fenêtre +;Open in new window +; +; +MSGID_COM_THUMBNAILCACHECLEANUP +Nettoyer le cache des vignettes +;Cleanup thumbnail cache +; +;----------------------------------------------------------- +; diff --git "a/scalos/Prefs/MainPrefs/Catalogs/fran\303\247ais/Scalos/config.mk" "b/scalos/Prefs/MainPrefs/Catalogs/fran\303\247ais/Scalos/config.mk" new file mode 100755 index 000000000..523f82566 --- /dev/null +++ "b/scalos/Prefs/MainPrefs/Catalogs/fran\303\247ais/Scalos/config.mk" @@ -0,0 +1,41 @@ +# $Date: 2011-08-08 18:52:39 +0200 (Mo, 08. Aug 2011) $ +# $Revision: 826 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = français + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = french + +else + +############################################################################### +# AmigaOS and AROS + +LANG = français + +endif +endif diff --git "a/scalos/Prefs/MainPrefs/Catalogs/fran\303\247ais/Scalos/makefile-new" "b/scalos/Prefs/MainPrefs/Catalogs/fran\303\247ais/Scalos/makefile-new" new file mode 100755 index 000000000..626ead642 --- /dev/null +++ "b/scalos/Prefs/MainPrefs/Catalogs/fran\303\247ais/Scalos/makefile-new" @@ -0,0 +1,32 @@ +# makefile for FileTypes (translated Texts : français) +# $Date: 2011-08-08 18:52:39 +0200 (Mo, 08. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = Scalos_Prefs + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Prefs/MainPrefs/Catalogs/sample/Scalos/Scalos_Prefs.ct b/scalos/Prefs/MainPrefs/Catalogs/sample/Scalos/Scalos_Prefs.ct new file mode 100644 index 000000000..ce6b16665 --- /dev/null +++ b/scalos/Prefs/MainPrefs/Catalogs/sample/Scalos/Scalos_Prefs.ct @@ -0,0 +1,4172 @@ +; ScalosPrefs.ct +; $Date$ +; $Revision$ + +## version $VER: Scalos_Prefs.catalog 40.28 (28 Mar 2010 19:20:49) +## codeset 0s +## language xxxxxx +; +;#arrayopts static const __far +; +;----------------------------------------------------------- +; +MSGID_MENU_PROJECT_OPEN +Open... +;Open... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +O +;O +; +; +MSGID_MENU_PROJECT_OPEN_ASLTITLE +Open Scalos Prefs... +;Open Scalos Prefs... +; +; +MSGID_MENU_PROJECT_SAVEAS +Save As... +;Save As... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +A +;A +; +; +MSGID_MENU_PROJECT_SAVEAS_ASLTITLE +Save Scalos Prefs As... +;Save Scalos Prefs As... +; +; +MSGID_MENU_PROJECT_ABOUT +About... +;About... +; +; +MSGID_MENU_PROJECT_QUIT +Quit +;Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +;Q +; +; +MSGID_MENU_PROJECT +Project +;Project +; +; +MSGID_MENU_EDIT_LASTSAVED +Last Saved +;Last Saved +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +L +;L +; +; +MSGID_MENU_EDIT +Edit +;Edit +; +; +MSGID_MENU_SETTINGS_CREATEICONS +Create Icons? +;Create Icons? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +I +;I +; +; +MSGID_MENU_SETTINGS +Settings +;Settings +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +Reset To Defaults +;Reset To Defaults +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +D +;D +; +; +MSGID_MENU_EDIT_RESTORE +Restore +;Restore +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +R +;R +; +; +MSGID_MENU_PROJECT_ABOUTMUI +About MUI... +;About MUI... +; +;+++translateme+++ +MSGID_MENU_PROJECT_ABOUTMORPHOS +About MorphOS... +;About MorphOS... +; +;----------------------------------------------------------- +; +MSGID_FILEDISP_COLUMN_NAME +Name +;Name +; +; +MSGID_FILEDISP_COLUMN_SIZE +Size +;Size +; +; +MSGID_FILEDISP_COLUMN_PROT +Protection bits +;Protection bits +; +; +MSGID_FILEDISP_COLUMN_DATE +Date +;Date +; +; +MSGID_FILEDISP_COLUMN_TIME +Time +;Time +; +; +MSGID_FILEDISP_COLUMN_COMMENT +Comment +;Comment +; +; +MSGID_FILEDISP_COLUMN_VERSION +Version +;Version +; +; +MSGID_FILEDISP_COLUMN_FILETYPE +Filetype +;Filetype +; +; +MSGID_FILEDISP_COLUMN_OWNER +Owner +;Owner +; +; +MSGID_FILEDISP_COLUMN_GROUP +Group +;Group +; +; +MSGID_FILEDISP_COLUMN_ICON +Icon +;Icon +; +;----------------------------------------------------------- +; +MSGID_PRECISION_EXACT +Exact +;Exact +; +; +MSGID_PRECISION_IMAGE +Image +;Image +; +; +MSGID_PRECISION_ICON +Icon +;Icon +; +; +MSGID_PRECISION_GUI +GUI +;GUI +; +;----------------------------------------------------------- +; +;+++translateme+++ +MSGID_THUMBNAILS_LIFETIME_FOREVER +never +;never +; +;----------------------------------------------------------- +; +MSGID_PREFGROUPS_SHORTHELP +Select one of the preferences categories +;Select one of the preferences categories +; +; +MSGID_PREFGROUPS_ABOUT +About Scalos +;About Scalos +; +; +MSGID_PREFGROUPS_PATHS +Paths +;Paths +; +; +MSGID_PREFGROUPS_STARTUP +Startup +;Startup +; +; +MSGID_PREFGROUPS_DESKTOP +Desktop +;Desktop +; +; +MSGID_PREFGROUPS_ICONS +Icons +;Icons +; +; +MSGID_PREFGROUPS_WINDOWS +Windows +;Windows +; +; +MSGID_PREFGROUPS_MISC +Miscellaneous +;Miscellaneous +; +; +MSGID_PREFGROUPS_PLUGINS +Plugins +;Plugins +; +; +MSGID_PREFGROUPS_MODULES +Modules +;Modules +; +; +MSGID_PREFGROUPS_DRAGNDROP +Drag and Drop +;Drag and Drop +; +; +MSGID_PREFGROUPS_TRUETYPEFONTS +TrueType Fonts +;TrueType Fonts +; +;+++translateme+++ +MSGID_PREFGROUPS_TEXTWINDOWS +Text Windows +;Text Windows +; +;----------------------------------------------------------- +; +MSGID_DESKTOPPAGES_SCREEN +Screen +;Screen +; +; +MSGID_DESKTOPPAGES_ICONS +Icons +;Icons +; +; +MSGID_ICONPAGES_MISC +Miscellaneous +;Miscellaneous +; +;+++translateme+++ +MSGID_DESKTOPPAGES_LAYOUT +Layout +;Layout +; +;----------------------------------------------------------- +; +MSGID_ICONPAGES_BORDERS +Borders +;Borders +; +; +MSGID_ICONPAGES_LABELS +Labels +;Labels +; +; +MSGID_ICONPAGES_ATRIBUTES +Attributes +;Attributes +; +; +MSGID_ICONPAGES_TOOLTIPS +Tooltips +;Tooltips +; +;+++translateme+++ +MSGID_ICONPAGES_THUMBNAILS +Thumbnails +;Thumbnails +; +;+++translateme+++ +MSGID_ICONPAGES_SIZES +Sizes +; +;----------------------------------------------------------- +; +MSGID_TITLEPLACEHOLDER_KICKSTART_RELEASE +%os|Kickstart release (e.g. 3.1) +;%os|Kickstart release (e.g. 3.1) +; +; +MSGID_TITLEPLACEHOLDER_KICKSTART_VERSION +%ov|Kickstart version (e.g. 40.68) +;%ov|Kickstart version (e.g. 40.68) +; +; +MSGID_TITLEPLACEHOLDER_SCALOS_RELEASE +%wb|Scalos release (e.g. 1.2d) +;%wb|Scalos release (e.g. 1.2d) +; +; +MSGID_TITLEPLACEHOLDER_SCALOS_VERSION +%wv|Scalos version (e.g. 39.220) +;%wv|Scalos version (e.g. 39.220) +; +; +MSGID_TITLEPLACEHOLDER_FREE_CHIP_MEM +%fc|Free chip RAM in bytes +;%fc|Free chip RAM in bytes +; +; +MSGID_TITLEPLACEHOLDER_FREE_FAST_MEM +%ff|Free fast RAM in bytes +;%ff|Free fast RAM in bytes +; +; +MSGID_TITLEPLACEHOLDER_FREE_MEM +%ft|Total free RAM in bytes +;%ft|Total free RAM in bytes +; +; +MSGID_TITLEPLACEHOLDER_WINDOW_PATH +%pa|Windows directory path +;%pa|Windows directory path +; +; +MSGID_TITLEPLACEHOLDER_DISK_FREE +%df|Free disk space +;%df|Free disk space +; +; +MSGID_TITLEPLACEHOLDER_DISK_FREE_DIVIDE +%DF|Free disk space (auto divide) +;%DF|Free disk space (auto divide) +; +; +MSGID_TITLEPLACEHOLDER_DISK_USED +%du|Used disk space +;%du|Used disk space +; +; +MSGID_TITLEPLACEHOLDER_DISK_USED_DIVIDE +%DU|Used disk space (auto divide) +;%DU|Used disk space (auto divide) +; +; +MSGID_TITLEPLACEHOLDER_START_NODISK +%d(|Start: don't show if no disk inserted +;%d(|Start: don't show if no disk inserted +; +; +MSGID_TITLEPLACEHOLDER_STOP_NODISK +%d)|Stop: don't show if no disk inserted +;%d)|Stop: don't show if no disk inserted +; +; +MSGID_TITLEPLACEHOLDER_DISK_PERCENT +%dp|Percent of used disk space +;%dp|Percent of used disk space +; +; +MSGID_TITLEPLACEHOLDER_GFXCHIPS +%cs|Graphics chip set (e.g. AGA) +;%cs|Graphics chip set (e.g. AGA) +; +; +MSGID_TITLEPLACEHOLDER_CPU +%pr|68k processor +;%pr|68k processor +; +; +MSGID_TITLEPLACEHOLDER_FPU +%cp|68k co-processor (FPU) +;%cp|68k co-processor (FPU) +; +; +MSGID_TITLEPLACEHOLDER_TASKS +%nt|Number of tasks +;%nt|Number of tasks +; +; +MSGID_TITLEPLACEHOLDER_LIBRARIES +%nl|Number of libraries +;%nl|Number of libraries +; +; +MSGID_TITLEPLACEHOLDER_PORTS +%np|Number of ports +;%np|Number of ports +; +; +MSGID_TITLEPLACEHOLDER_DEVICES +%nd|Number of devices +;%nd|Number of devices +; +; +MSGID_TITLEPLACEHOLDER_SCREENS +%ns|Number of screens +;%ns|Number of screens +; +; +;----------------------------------------------------------- +; +MSGID_WINDOWPAGES_GENERAL +General +;General +; +; +MSGID_WINDOWPAGES_SIZE +Size +;Size +; +;+++translateme+++ +MSGID_WINDOWPAGES_LAYOUT +Layout +;Layout +; +;+++translateme+++ +MSGID_WINDOWPAGES_CONTROLBAR +Control Bar +;Control Bar +; +;+++translateme+++ +MSGID_WINDOWPAGES_CONTROLBAR_BROWSER +Browser Window Control Bar +;Browser Window Control Bar +; +;+++translateme+++ +MSGID_WINDOWPAGES_CONTROLBAR_NORMAL +Standard Window Control Bar +;Standard Window Control Bar +; +;----------------------------------------------------------- +; +;+++translateme+++ +MSGID_TEXTWINDOWPAGES_FONTS +Fonts +;Fonts +; +;+++translateme+++ +MSGID_TEXTWINDOWPAGES_COLUMNS +Columns +;Columns +; +;+++translateme+++ +MSGID_TEXTWINDOWPAGES_SELECTIONMARKS +Selection marks +;Selection marks +; +;+++translateme+++ +MSGID_TEXTWINDOWPAGES_MISC +Miscellaneous +;Miscellaneous +; +;----------------------------------------------------------- +; +;+++translateme+++ +MSGID_CREATELINKS_HARDLINKS +Hard links +; +;+++translateme+++ +MSGID_CREATELINKS_SOFTLINKS +Soft links +; +;----------------------------------------------------------- +; +MSGID_WINDOWREFRESH_SIMPLE +Simple Refresh +;Simple Refresh +; +; +MSGID_WINDOWREFRESH_SMART +Smart Refresh +;Smart Refresh +; +;----------------------------------------------------------- +; +MSGID_WINDOW_SHOWALL_DEFAULT_ICONS +Show - Only Icons +;Show - Only Icons +; +; +MSGID_WINDOW_SHOWALL_DEFAULT_ALL +Show - All Files +;Show - All Files +; +;----------------------------------------------------------- +; +MSGID_WINDOW_VIEWBY_DEFAULT_ICON +View By - Icon +;View By - Icon +; +; +MSGID_WINDOW_VIEWBY_DEFAULT_NAME +View By - Name +;View By - Name +; +; +MSGID_WINDOW_VIEWBY_DEFAULT_SIZE +View By - Size +;View By - Size +; +; +MSGID_WINDOW_VIEWBY_DEFAULT_DATE +View By - Date +;View By - Date +; +; +MSGID_WINDOW_VIEWBY_DEFAULT_TIME +View By - Time +;View By - Time +; +; +MSGID_WINDOW_VIEWBY_DEFAULT_COMMENT +View By - Comment +;View By - Comment +; +; +MSGID_WINDOW_VIEWBY_DEFAULT_PROTECTION +View By - Comment +;View By - Comment +; +; +MGSID_WINDOW_VIEWBY_DEFAULT_OWNER +View By - Owner +;View By - Owner +; +; +MSGID_WINDOW_VIEWBY_DEFAULT_GROUP +View By - Group +;View By - Group +; +;----------------------------------------------------------- +; +MSGID_FILEDISPLAYPAGES_TEXT +Text +;Text +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_ICONLAYOUT_COLUMNS +Columns (top-down, then left-to-right) +;Columns (top-down, then left-to-right) +; +;+++translateme+++ +MSGID_ICONLAYOUT_ROWS +Rows (left-to-right, then top-down) +;Rows (left-to-right, then top-down) +; +;----------------------------------------------------------- +; +MSGID_ICONLABELSTYLES_NORMAL +Normal +;Normal +; +; +MSGID_ICONLABELSTYLES_OUTLINE +Outline +;Outline +; +; +MSGID_ICONLABELSTYLES_SHADOW +Shadow +;Shadow +; +;----------------------------------------------------------- +; +MSGID_ICONSIZES_16x16 +16 x 16 +;16 x 16 +; +; +MSGID_ICONSIZES_24x24 +24 x 24 +;24 x 24 +; +; +MSGID_ICONSIZES_32x32 +32 x 32 +;32 x 32 +; +; +MSGID_ICONSIZES_48x48 +48 x 48 +;48 x 48 +; +; +MSGID_ICONSIZES_64x64 +64 x 64 +;64 x 64 +; +; +MSGID_ICONSIZES_96x96 +96 x 96 +;96 x 96 +; +; +MSGID_ICONSIZES_128x128 +128 x 128 +;128 x 128 +; +; +MSGID_ICONSIZES_UNLIMITED +unlimited +;unlimited +; +;----------------------------------------------------------- +; +MSGID_ICONDRAGSTYLES_IMAGEONLY +Image Only +;Image Only +; +; +MSGID_ICONDRAGSTYLES_IMAGEANDTEXT +Image & Text +;Image & Text +; +;----------------------------------------------------------- +; +MSGID_THUMBNAILSIZES_16x16 +16 x 16 +;16 x 16 +; +; +MSGID_THUMBNAILSIZES_24x24 +24 x 24 +;16 x 16 +; +; +MSGID_THUMBNAILSIZES_32x32 +32 x 32 +;32 x 32 +; +; +MSGID_THUMBNAILSIZES_48x48 +48 x 48 +;48 x 48 +; +; +MSGID_THUMBNAILSIZES_64x64 +64 x 64 +;64 x 64 +; +; +MSGID_THUMBNAILSIZES_96x96 +96 x 96 +;96 x 96 +; +; +MSGID_THUMBNAILSIZES_128x128 +128 x 128 +;128 x 128 +; +;----------------------------------------------------------- +; +MSGID_ICONDRAGTRANSPARENCY_GHOSTED +Ghosted +;Ghosted +; +; +MSGID_ICONDRAGTRANSPARENCY_TRANSPARENT +Ghosted/Real Transparent +;Ghosted/Real Transparent +; +;----------------------------------------------------------- +; +MSGID_SHOWTHUMBNAILS_NEVER +Never +;Never +; +; +MSGID_SHOWTHUMBNAILS_AS_DEFAULT +As default +;As default +; +; +MSGID_SHOWTHUMBNAILS_ALWAYS +Always +;Always +; +;----------------------------------------------------------- +; +MSGID_ICONDRAGTROUTINES_SYSTEM +System +;System +; +; +MSGID_ICONDRAGTROUTINES_CUSTOM +Custom +;Custom +; +;----------------------------------------------------------- +; +MSGID_ICONDROPMARK_NEVER +Never show +;Never show +; +; +MSGID_ICONDROPMARK_ALWAYS +Always +;Always +; +; +MSGID_ICONDROPMARK_DRAWERSONLY +Only in drawer windows +;Only in drawer windows +; +;----------------------------------------------------------- +; +MSGID_ICONDRAGLOOK_TRANSP_SOLID +\033bTransparent\033n when dragging, \033bsolid\033n over triggers +;\033bTransparent\033n when dragging, \033bsolid\033n over triggers +; +; +MSGID_ICONDRAGLOOK_ALWAYS_SOLID +Always \033bsolid\033n icons when dragging +;Always \033bsolid\033n icons when dragging +; +; +MSGID_ICONDRAGLOOK_ALWAYS_TRANSP +Always \033btransparent\033n icons when dragging +;Always \033btransparent\033n icons when dragging +; +; +MSGID_ICONDRAGLOOK_SOLID_TRANSP +\033bSolid\033n when dragging, \033btransparent\033n over triggers +;\033bSolid\033n when dragging, \033btransparent\033n over triggers +; +;----------------------------------------------------------- +; +MSGID_VERSIONSTRING +Scalos Version %s (%d.%d) (Build %s) +;Scalos Version %s (%d.%d) (Build %s) +; +; +MSGID_COPYRIGHTSTRING +®2003-2004 The Scalos Team +;®2003-2004 The Scalos Team +; +; +; +++translateme+++ +MSGID_SPLASHWINDOW_LOADINGPREFS +\33c Loading Scalos Prefs... +;\33c Loading Scalos Prefs... +; +; +MSGID_SPLASHWINDOW_APPLYINGPREFS +\33c Applying Scalos Prefs... +;\33c Applying Scalos Prefs... +; +; +MSGID_SPLASHWINDOW_SAVINGPREFS +\33c Saving Scalos Prefs... +;\33c Saving Scalos Prefs... +; +;----------------------------------------------------------- +; +MSGID_ABOUTPAGE_COPYRIGHT +\033c\033bCopyright ©2003-2004 The Scalos Team +;\033c\033bCopyright ©2003-2004 The Scalos Team +; +; +MSGID_ABOUTPAGE_CONTACT1 +contact us by email < +;contact us by email < +; +; +MSGID_ABOUTPAGE_CONTACT2 +> // web < +;> // web < +; +; +MSGID_ABOUTPAGE_CONTACT3 +> +;> +; +; +MSGID_ABOUTPAGE_PREFSVERSION +Scalos Main Preferences V%ld.%ld +;Scalos Main Preferences V%ld.%ld +; +;----------------------------------------------------------- +; +MSGID_PATHSPAGE_DEFAULTPATHS +Default Paths +;Default Paths +; +; +MSGID_PATHSPAGE_SCALOS_HOME +Scalos Home: +;Scalos Home: +; +; +MSGID_PATHSPAGE_SCALOS_HOME_ASLTITLE +Please select a drawer... +;Please select a drawer... +; +; +MSGID_PATHSPAGE_SCALOS_HOME_SHORTHELP +An assign called SCALOS: will point to this directory +;An assign called SCALOS: will point to this directory +; +; +MSGID_PATHSPAGE_THEMES +Themes: +;Themes: +; +; +MSGID_PATHSPAGE_THEMES_SHORTHELP +This is the drawer where all the\n\ +theme-specific files are located. +;This is the drawer where all the\n\ +;theme-specific files are located. +; +; +MSGID_PATHSPAGE_THEMES_ASLTITLE +Please select a drawer... +;Please select a drawer... +; +; +MSGID_PATHSPAGE_DEFAULTICONS +Default Icons: +;Default Icons: +; +; +MSGID_PATHSPAGE_DEFAULTICONS_SHORTHELP +This is the drawer where Scalos\n\ +looks for default icons. +;This is the drawer where Scalos\n\ +;looks for default icons. +; +; +MSGID_PATHSPAGE_DEFAULTICONS_ASLTITLE +Please select a drawer... +;Please select a drawer... +; +; +MSGID_PATHSPAGE_WBSTARTUP +WBStartup: +;WBStartup: +; +; +MSGID_PATHSPAGE_WBSTARTUP_SHORTHELP +This drawer is used as WBStartup, i.e. any program\n\ +located inside is executed upon Scalos startup. +;This drawer is used as WBStartup, i.e. any program\n\ +;located inside is executed upon Scalos startup. +; +; +MSGID_PATHSPAGE_WBSTARTUP_ASLTITLE +Please select a drawer... +;Please select a drawer... +; +; +MSGID_PATHSPAGE_DISKCOPY +DiskCopy: +;DiskCopy: +; +; +MSGID_PATHSPAGE_DISKCOPY_SHORTHELP +This is the complete file name for\n\ +the \"Diskcopy\" system program. +;This is the complete file name for\n\ +;the \"Diskcopy\" system program. +; +; +MSGID_PATHSPAGE_DISKCOPY_ASLTITLE +Please select a drawer... +;Please select a drawer... +; +; +MSGID_PATHSPAGE_FORMAT +Format: +;Format: +; +; +MSGID_PATHSPAGE_FORMAT_SHORTHELP +This is the complete file name for\n\ +the \"Format\" system program. +;This is the complete file name for\n\ +;the \"Format\" system program. +; +; +MSGID_PATHSPAGE_FORMAT_ASLTITLE +Please select a drawer... +;Please select a drawer... +; +;+++translateme+++ +MSGID_PATHSPAGE_THUMBNAILDB +Thumbnail cache file: +;Thumbnail cache file: +; +;+++translateme+++ +MSGID_PATHSPAGE_THUMBNAILDB_ASLTITLE +Please select thumbnail cache location... +;Please select thumbnail cache location... +; +;+++translateme+++ +MSGID_PATHSPAGE_THUMBNAILDB_SHORTHELP +Scalos uses a database file to cache thumbnail icon images.\n\ +This file easily grows to several megabytes.\n\ +Select here a place where this file should be kept. +;Scalos uses a database file to cache thumbnail icon images.\n\ +;This file easily grows to several megabytes.\n\ +;Select here a place where this file should be kept. +; +;+++translateme+++ +MSGID_PATHSPAGE_IMAGECACHE +Image Cache: +;Image Cache: +; +;+++translateme+++ +MSGID_PATHSPAGE_IMAGECACHE_SHORTHELP +This drawer is used to cache the datatypes images used by Scalos.\n\ +Since datatypes prevents images from being updated,\n\ +Scalos creates cached copies of the images used. +;This drawer is used to cache the datatypes images used by Scalos.\n\ +;Since datatypes prevents images from being updated,\n\ +;Scalos creates cached copies of the images used. +; +;+++translateme+++ +MSGID_PATHSPAGE_IMAGECACHE_ASLTITLE +Please select a drawer... +;Please select a drawer... +; +;+++translateme+++ +MSGID_PATHSPAGE_SQLITE3TEMPPATH +Thumbnail Database Temporary Files: +;Thumbnail Database Temporary Files: +; +;+++translateme+++ +MSGID_PATHSPAGE_SQLITE3TEMPPATH_SHORTHELP +This drawer is used to store any temporary\n\ +files for internal use by the thumbnail database. +;This drawer is used to store any temporary\n\ +;files for internal use by the thumbnail database. +; +;+++translateme+++ +MSGID_PATHSPAGE_SQLITE3TEMPPATH_ASLTITLE +Please select thumbnail cache temporary files location... +;Please select thumbnail cache temporary files location... +; +;----------------------------------------------------------- +; +MSGID_STARTUPPAGE_SPLASHWINDOW +Splash Window +;Splash Window +; +; +MSGID_STARTUPPAGE_SHOWSPLASHWINDOW +Show splash window: +;Show splash window: +; +; +MSGID_STARTUPPAGE_SHOWSPLASHWINDOW_SHORTHELP +Enable this checkbox to display the\n\ +splash window upon every Scalos startup. +;Enable this checkbox to display the\n\ +;splash window upon every Scalos startup. +; +; +MSGID_STARTUPPAGE_SPLASHCLOSEDELAY +Splash close delay: +;Splash close delay: +; +; +MSGID_STARTUPPAGE_SPLASHCLOSEDELAY_SHORTHELP +Specify here how long the Scalos splash window\n\ +will stay open after the last startup message\n\ +has been displayed. +;Specify here how long the Scalos splash window\n\ +;will stay open after the last startup message\n\ +;has been displayed. +; +; +MSGID_STARTUPPAGE_WBSTARTUP +WBStartup +;WBStartup +; +; +MSGID_STARTUPPAGE_DOWAITDELAY +DoWait delay: +;DoWait delay: +; +; +MSGID_STARTUPPAGE_DOWAITDELAY_SHORTHELP +If a tool in the WBStartup drawer doesn't\n\ +finish within the specified delay a requester will be\n\ +presented to choose wether to stop waiting. +;If a tool in the WBStartup drawer doesn't\n\ +;finish within the specified delay a requester will be\n\ +;presented to choose wether to stop waiting. +; +; +MSGID_STARTUPPAGE_DOWAITDELAY_SECONDS +seconds +;seconds +; +;----------------------------------------------------------- +; +MSGID_DESKTOPPAGE_SCREENTITLEBAR +Screen Title +;Screen Title +; +; +MSGID_DESKTOPPAGE_SCREEN +Title +;Title +; +; +MSGID_DESKTOPPAGE_SCREEN_DESCRIPTION +|\033b\0338Description +;|\033b\0338Description +; +; +MSGID_DESKTOPPAGE_TITLEBAR_REFRESH +Titlebar refresh rate: +;Titlebar refresh rate: +; +; +MSGID_DESKTOPPAGE_TITLEBAR_REFRESH_SHORTHELP +This is the time interval between\n\ +consecutive screen title bar refreshes. +;This is the time interval between\n\ +;consecutive screen title bar refreshes. +; +; +MSGID_DESKTOPPAGE_TITLEBAR_REFRESH_SECONDS +seconds +;seconds +; +; +MSGID_DESKTOPPAGE_TITLEBAR_REFRESH_MEMCHANGE +Refresh only on memory change: +;Refresh only on memory change: +; +; +MSGID_DESKTOPPAGE_TITLEBAR_REFRESH_MEMCHANGE_SHORTHELP +When this item is checked, the screen title bar\n\ +is only refreshed when the amount of available\n\ +system memory has changed since last check.\n\ +The memory is checked every \"Titlebar refresh rate\" seconds. +;When this item is checked, the screen title bar\n\ +;is only refreshed when the amount of available\n\ +;system memory has changed since last check.\n\ +;The memory is checked every \"Titlebar refresh rate\" seconds. +; +; +MSGID_DESKTOPPAGE_DESKTOP_REFRESH +Desktop Refresh +;Desktop Refresh +; +; +MSGID_DESKTOPPAGE_DISK_ICON_RATE +Disk icon rate: +;Disk icon rate: +; +; +MSGID_DESKTOPPAGE_DISK_ICON_RATE_SHORTHELP +This is the time interval Scalos\n\ +checks for changed disks and volumes. +;This is the time interval Scalos\n\ +;checks for changed disks and volumes. +; +; +MSGID_DESKTOPPAGE_DISK_ICON_RATE_SECONDS +seconds +;seconds +; +; +MSGID_DESKTOPPAGE_SCREENTITLE +Screen Title +;Screen Title +; +; +MSGID_DESKTOPPAGE_SCREENTITLE_MODE +Visibility +;Visibility +; +; +MSGID_DESKTOPPAGE_SCREENTITLE_MODE_SHORTHELP +Specifiy here whether you like the screen title\n\ +- to be visible all the time\n\ +- to pop up when the mouse pointer is positioned at the top of the screen\n\ +- to be hidden all the time +;Specifiy here whether you like the screen title\n\ +;- to be visible all the time\n\ +;- to pop up when the mouse pointer is positioned at the top of the screen\n\ +;- to be hidden all the time +; +; +MSGID_DESKTOPPAGE_MISCELLANEOUS +Miscellaneous +;Miscellaneous +; +; +MSGID_DESKTOPPAGE_ALLOW_CLOSEWB +Allow CloseWorkbench(): +;Allow CloseWorkbench(): +; +; +MSGID_DESKTOPPAGE_ALLOW_CLOSEWB_SHORTHELP +Disable this checkbox to make the CloseWB() function\n\ +a no-op. This allows to work with some ancient\n\ +programs and leave Scalos open all the time. +;Disable this checkbox to make the CloseWB() function\n\ +;a no-op. This allows to work with some ancient\n\ +;programs and leave Scalos open all the time. +; +; +MSGID_DESKTOPPAGE_DROPSTART +Drop-start: +;Drop-start: +; +; +MSGID_DESKTOPPAGE_DROPSTART_SHORTHELP +Dropping a project icon on to another programs\n\ +icon will automatically run the program and\n\ +pass the project file as a parameter +;Dropping a project icon on to another programs\n\ +;icon will automatically run the program and\n\ +;pass the project file as a parameter +; +; +MSGID_DESKTOPPAGE_CONSOLENAME +Console name +;Console name +; +; +MSGID_DESKTOPPAGE_CONSOLENAME_SHORTHELP +Gives complete file specifier for CLI and ARexx console. +;Gives complete file specifier for CLI and ARexx console. +; +; +MSGID_DESKTOPPAGE_AUTOLEAVEOUT +Automatic leave-out +;Automatic leave-out +; +; +MSGID_DESKTOPPAGE_AUTOLEAVEOUT_SHORTHELP +If this switch is turned on, dragging icons\n\ +onto the desktop remembers them permanently\n\ +as left-out, just like selecting the\n\ +\"leave out\" menu command. +;If this switch is turned on, dragging icons\n\ +;onto the desktop remembers them permanently\n\ +;as left-out, just like selecting the\n\ +;\"leave out\" menu command. +; +; +MSGID_DESKTOPPAGE_WINTITLEBAR_REFRESH +Titlebar refresh rate: +; Titlebar refresh rate: +; +; +MSGID_DESKTOPPAGE_WINTITLEBAR_REFRESH_SHORTHELP +This is the time interval between\n\ +consecutive window title bar refreshes. +; This is the time interval between\n\ +; consecutive window title bar refreshes. +; +; +MSGID_DESKTOPPAGE_WINTITLEBAR_REFRESH_SECONDS +seconds +; seconds +; +; +MSGID_DESKTOPPAGE_WINTITLEBAR_REFRESH_MEMCHANGE +Refresh only on memory change: +; Refresh only on memory change: +; +; +MSGID_DESKTOPPAGE_WINTITLEBAR_REFRESH_MEMCHANGE_SHORTHELP +When this item is checked, the window title bar\n\ +is only refreshed when the amount of available\n\ +system memory has changed since last check.\n\ +The memory is checked every \"Titlebar refresh rate\" seconds. +; When this item is checked, the window title bar\n\ +; is only refreshed when the amount of available\n\ +; system memory has changed since last check.\n\ +; The memory is checked every \"Titlebar refresh rate\" seconds. +; +;+++translateme+++ +MSGID_DESKTOPPAGE_LASSO +Lasso +;Lasso +; +;+++translateme+++ +MSGID_DESKTOPPAGE_SINGLEWINDOW_LASSO +Single-Window Lasso Mode +;Single-Window Lasso Mode +; +;+++translateme+++ +MSGID_DESKTOPPAGE_SINGLEWINDOW_LASSO_SHORTHELP +Press this qualifier key to limit lasso operation to a single window.\n\ +In this mode, the window contents scrolls to unveal hidden\n\ +icons if the mouse leaves the inner window area. +;Press this qualifier key to limit lasso operation to a single window.\n\ +;In this mode, the window contents scrolls to unveal hidden\n\ +;icons if the mouse leaves the inner window area. +; +;----------------------------------------------------------- +; +MSGID_ICONSPAGE_ICONFRAME +Icon Frame +;Icon Frame +; +; +MSGID_ICONSPAGE_ICONFRAME_NORMAL +Normal +;Normal +; +; +MSGID_ICONSPAGE_ICONFRAME_NORMAL_SHORTHELP +This type of border is drawn around unselected icons.\n\ +\033bGlowIcons\033n which have been marked as\n\ +\"borderless\" will not show this border.\n\ +Please note that the icon borders below must\n\ +be non-zero for the icon border to show. +;This type of border is drawn around unselected icons.\n\ +;\033bGlowIcons\033n which have been marked as\n\ +;\"borderless\" will not show this border.\n\ +;Please note that the icon borders below must\n\ +;be non-zero for the icon border to show. +; +; +MSGID_ICONSPAGE_ICONFRAME_SELECTED +Selected +;Selected +; +; +MSGID_ICONSPAGE_ICONFRAME_SELECTED_SHORTHELP +This type of border is drawn around selected icons.\n\ +\033bGlowIcons\033n which have been marked as\n\ +\"borderless\" will not show this border.\n\ +Please note that the icon borders below must\n\ +be non-zero for the icon border to show. +;This type of border is drawn around selected icons.\n\ +;\033bGlowIcons\033n which have been marked as\n\ +;\"borderless\" will not show this border.\n\ +;Please note that the icon borders below must\n\ +;be non-zero for the icon border to show. +; +; +MSGID_ICONSPAGE_ICONBORDER_LEFT +Left: +;Left: +; +; +MSGID_ICONSPAGE_ICONBORDER_LEFT_SHORTHELP +This is the space between the left side of an\n\ +icon and the border. No icon borders will be\n\ +drawn when this space is 0. +;This is the space between the left side of an\n\ +;icon and the border. No icon borders will be\n\ +;drawn when this space is 0. +; +; +MSGID_ICONSPAGE_ICONBORDER_TOP +Top: +;Top: +; +; +MSGID_ICONSPAGE_ICONBORDER_TOP_SHORTHELP +This is the space between the top of an\n\ +icon and the border. No icon borders will be\n\ +drawn when this space is 0. +;This is the space between the top of an\n\ +;icon and the border. No icon borders will be\n\ +;drawn when this space is 0. +; +; +MSGID_ICONSPAGE_ICONBORDER_RIGHT +Right: +;Right: +; +; +MSGID_ICONSPAGE_ICONBORDER_RIGHT_SHORTHELP +This is the space between the right side of an\n\ +icon and the border. No icon borders will be\n\ +drawn when this space is 0. +;This is the space between the right side of an\n\ +;icon and the border. No icon borders will be\n\ +;drawn when this space is 0. +; +; +MSGID_ICONSPAGE_ICONBORDER_BOTTOM +Bottom: +;Bottom: +; +; +MSGID_ICONSPAGE_ICONBORDER_BOTTOM_SHORTHELP +This is the space between the bottom of an\n\ +icon and the border. No icon borders will be\n\ +drawn when this space is 0. +;This is the space between the bottom of an\n\ +;icon and the border. No icon borders will be\n\ +;drawn when this space is 0. +; +; +MSGID_ICONSPAGE_LABELS +Labels +;Labels +; +; +MSGID_ICONSPAGE_LABELS_TEXT +Text style: +;Text style: +; +; +MSGID_ICONSPAGE_LABELS_TEXT_SHORTHELP +Provides a choice of label font formatting\n\ +which can be applied to the icons text label +;Provides a choice of label font formatting\n\ +;which can be applied to the icons text label +; +; +MSGID_ICONSPAGE_LABELS_TEXTSPACE +Image <-> Text Space +;Image <-> Text Space +; +; +MSGID_ICONSPAGE_LABELS_TEXTSPACE_SHORTHELP +Adjusts the space between the\n\ +icon imagery and its text label +;Adjusts the space between the\n\ +;icon imagery and its text label +; +; +MSGID_ICONSPAGE_LABELS_TEXTSPACE_PIXELS +pixels +;pixels +; +; +MSGID_ICONSPAGE_LABELS_SPLIT +Split into multiple lines: +;Split into multiple lines: +; +; +MSGID_ICONSPAGE_LABELS_SPLIT_SHORTHELP +Allows filenames to be split\n\ +over multiple lines +;Allows filenames to be split\n\ +;over multiple lines +; +; +MSGID_ICONSPAGE_LABELS_UNDERLINE_LINKS +Display soft-link file names \033uunderlined\033n: +;Display soft-link file names \033uunderlined\033n: +; +; +MSGID_ICONSPAGE_LABELS_UNDERLINE_LINKS_SHORTHELP +When this item is checked, icon names of\n\ +soft-links are displayed \033uunderlined\033n. +;When this item is checked, icon names of\n\ +;soft-links are displayed \033uunderlined\033n. +; +; +MSGID_ICONSPAGE_LABELS_FONT +Font +;Font +; +; +MSGID_ICONSPAGE_LABELS_FONT_NOTICE +To change the font used for icon labels you must use \ +the standard \033bFont preferences\033n program installed on your \ +system. Use the pop-up button on the right to launch \ +the fonts preference program. +;To change the font used for icon labels you must use \ +;the standard \033bFont preferences\033n program installed on your \ +;system. Use the pop-up button on the right to launch \ +;the fonts preference program. +; +; +MSGID_ICONSPAGE_LABELS_FONT_SHORTHELP +Launch standard Font prefs program +;Launch standard Font prefs program +; +; +MSGID_ICONSPAGE_GENERAL +General +;General +; +; +MSGID_ICONSPAGE_MASKED_CLICKAREA +Masked click area: +;Masked click area: +; +; +MSGID_ICONSPAGE_MASKED_CLICKAREA_SHORTHELP +If this checkbox is checked, you have to click on the\n\ +unmasked, visible area of an icon to activate it. If it\n\ +is unchecked, a click anywhere inside the icon\n\ +rectangle will be sufficient for activation. +;If this checkbox is checked, you have to click on the\n\ +;unmasked, visible area of an icon to activate it. If it\n\ +;is unchecked, a click anywhere inside the icon\n\ +;rectangle will be sufficient for activation. +; +; +MSGID_ICONSPAGE_MULTISELECTION +Multi-Selection: +;Multi-Selection: +; +; +MSGID_ICONSPAGE_MULTISELECTION_SHORTHELP +Provides an alternative multi-select method which\n\ +does not require you to hold down the SHIFT key\n\ +whilst dragging multiple icons. +;Provides an alternative multi-select method which\n\ +;does not require you to hold down the SHIFT key\n\ +;whilst dragging multiple icons. +; +; +MSGID_ICONSPAGE_NEWICONS +New Icons +;New Icons +; +; +MSGID_ICONSPAGE_NEWICONS_REMAP_PRECISION +Remap precision: +;Remap precision: +; +; +MSGID_ICONSPAGE_NEWICONS_REMAP_PRECISION_SHORTHELP +Specifies the precision to use when\n\ +remapping NewIcon colors to the screen palette. +;Specifies the precision to use when\n\ +;remapping NewIcon colors to the screen palette. +; +; +MSGID_ICONSPAGE_NEWICONS_TRANSPARENTBG +Transparent background: +;Transparent background: +; +; +MSGID_ICONSPAGE_NEWICONS_TRANSPARENTBG_SHORTHELP +Makes the background of NewIcons transparent +;Makes the background of NewIcons transparent +; +; +MSGID_ICONSPAGE_DEFICONS +Def Icons +;Def Icons +; +; +MSGID_ICONSPAGE_DEFICONS_LOADFIRST +Load first: +;Load first: +; +; +MSGID_ICONSPAGE_DEFICONS_LOADFIRST_SHORTHELP +Your def_#? icons will get priority when\n\ +loading over a specific icon for a device. +;Your def_#? icons will get priority when\n\ +;loading over a specific icon for a device. +; +; +MSGID_ICONSPAGE_DEFICONS_SAVEABLE +Icons saveable: +;Icons saveable: +; +; +MSGID_ICONSPAGE_DEFICONS_SAVEABLE_SHORTHELP +When enabled, \033bsnapshot\033n saves changes\n\ +to default icons.\n\ +Uncheck this checkbox to prevent Scalos from\n\ +changing any ofyour default icons. +;When enabled, \033bsnapshot\033n saves changes\n\ +;to default icons.\n\ +;Uncheck this checkbox to prevent Scalos from\n\ +;changing any ofyour default icons. +; +; +MSGID_ICONSPAGE_TOOLTIPS_GENERAL +General +;General +; +; +MSGID_ICONSPAGE_TOOLTIPS_SHOW +Show toolips for icons: +;Show toolips for icons: +; +; +MSGID_ICONSPAGE_TOOLTIPS_SHOW_SHORTHELP +When this checkbox is checked, Scalos pops up\n\ +\033btooltips\033n with additional information\n\ +when you keep the mouse pointer positioned over\n\ +an icon for more than the tooltip delay time.\n\ +The tooltip automatically disappears as soon as\n\ +the mouse is moved or any key is pressed. +;When this checkbox is checked, Scalos pops up\n\ +;\033btooltips\033n with additional information\n\ +;when you keep the mouse pointer positioned over\n\ +;an icon for more than the tooltip delay time.\n\ +;The tooltip automatically disappears as soon as\n\ +;the mouse is moved or any key is pressed. +; +; +MSGID_ICONSPAGE_TOOLTIPS_SETTINGS +Settings +;Settings +; +; +MSGID_ICONSPAGE_TOOLTIPS_DELAY +Delay before pop-up: +;Delay before pop-up: +; +; +MSGID_ICONSPAGE_TOOLTIPS_DELAY_SHORTHELP +Here you can select how long you have to\n\ +keep the mouse pointer positioned over an\n\ +icon until the tooltip pops up. +;Here you can select how long you have to\n\ +;keep the mouse pointer positioned over an\n\ +;icon until the tooltip pops up. +; +; +MSGID_ICONSPAGE_TOOLTIPS_DELAY_SECONDS +seconds +;seconds +; +; +MSGID_ICONSPAGE_TOOLTIPS_FONT +Font: +;Font: +; +; +MSGID_ICONSPAGE_TOOLTIPS_FONT_SHORTHELP +??? +;??? +; +; +MSGID_ICONSPAGE_TOOLTIPS_FONT_ASLTITLE +Please select a font... +;Please select a font... +; +; +MSGID_ICONSPAGE_TOOLTIPS_DISPLAYFIELDS +Display Fields +;Display Fields +; +; +MSGID_ICONSPAGE_TOOLTIPS_AVAILABLEFIELDS +Available Fields +;Available Fields +; +; +MSGID_ICONSPAGE_TOOLTIPS_AVAILABLEFIELDS_SHORTHELP +??? +;??? +; +; +MSGID_ICONSPAGE_TOOLTIPS_FIELDSINUSE +Fields In Use +;Fields In Use +; +; +MSGID_ICONSPAGE_TOOLTIPS_FIELDSINUSE_SHORTHELP +??? +;??? +; +; +MSGID_ICONSPAGE_DRAGGING +Dragging +;Dragging +; +; +MSGID_ICONSPAGE_ATTRIBUTES_TRANSPARENCY_DEFICONS +Transparency +;Transparency +; +; +MSGID_ICONSPAGE_ATTRIBUTES_TRANSPARENCY_DEFICONS_SHORTHELP +Default icons may be drawn transparent.\n\ +Please select the degree of transparency you\n\ +would like default icons to be draw with.\n\ +Please note that real transparency is only available\n\ +if your desktop screen has more than 256 colors. +;Default icons may be drawn transparent.\n\ +;Please select the degree of transparency you\n\ +;would like default icons to be draw with.\n\ +;Please note that real transparency is only available\n\ +;if your desktop screen has more than 256 colors. +; +; +++translateme+++ +MSGID_ICONSPAGE_LABELS_FONT_SAMPLETEXT_SHORTHELP +This is an example text to visualize what the selected font looks like +;This is an example text to visualize what the selected font looks like +; +; +++translateme+++ +MSGID_ICONSPAGE_HILITE_UNDER_MOUSE +Mark icon under mouse +;Mark icon under mouse +; +; +++translateme+++ +MSGID_ICONSPAGE_HILITE_UNDER_MOUSE_SHORTHELP +If this switch is turned on, every\n\ +icon is shown in a highlighted stated\n\ +while the mouse pointer is over it. +;If this switch is turned on, every\n\ +;icon is shown in a highlighted stated\n\ +;while the mouse pointer is over it. +; +;+++translateme+++ +MSGID_ICONSPAGE_ICONSCALING +Icon Scaling +;Icon Scaling +; +;+++translateme+++ +MSGID_ICONSPAGE_SCALING_MINSIZE +Minimum Size: +;Minimum Size: +; +;+++translateme+++ +MSGID_ICONSPAGE_SCALING_MINSIZE_SHORTHELP +Minimum size for displayed icons.\n\ +Smaller icons will be scaled to\n\ +the specified minimum size. +;Minimum size for displayed icons.\n\ +;Smaller icons will be scaled to\n\ +;the specified minimum size. +; +;+++translateme+++ +MSGID_ICONSPAGE_SCALING_MAXSIZE +Maximum Size: +;Maximum Size: +; +;+++translateme+++ +MSGID_ICONSPAGE_SCALING_MAXSIZE_SHORTHELP +Maximum size for displayed icons.\n\ +Larger icons will be scaled to\n\ +the specified maximum size. +;Maximum size for displayed icons.\n\ +;Larger icons will be scaled to\n\ +;the specified maximum size. +; +;+++translateme+++ +MSGID_ICONSPAGE_GROUP_ICONFONT +Standard Font +;Standard Font +; +;+++translateme+++ +MSGID_ICONSPAGE_LABELS_ICONFONT_SHORTHELP +Select font to display icon names.\n\ +This selection is disabled while TrueType\n\ +icon fonts are enabled. +;Select font to display icon names.\n\ +;This selection is disabled while TrueType\n\ +;icon fonts are enabled. +; +;+++translateme+++ +MSGID_ICONSPAGE_ICONFONT_ASLTITLE +Please select an icon font... +;Please select an icon font... +; +;+++translateme+++ +MSGID_ICONSPAGE_ICONTHUMBNAILS +Thumbnails +;Thumbnails +; +;+++translateme+++ +MSGID_ICONSPAGE_SHOWTHUMBNAILS +Display Thumbnails +;Display Thumbnails +; +;+++translateme+++ +MSGID_ICONSPAGE_SHOWTHUMBNAILS_SHORTHELP +Select if and when icons are displayed as image thumbnails:\n\ +Never - don't show thumbnails\n\ +As default - show thumbnails instead of default icons\n\ +Always - always show thumbnails +;Select if and when icons are displayed as image thumbnails:\n\ +:Never - don't show thumbnails\n\ +:As default - show thumbnails instead of default icons\n\ +:Always - always show thumbnails +; +;+++translateme+++ +MSGID_ICONSPAGE_SHOWTHUMBNAILS_AS_DEFAULT +Ignore \033bShowOnlyIcons\033n mode: +;Ignore \033bShowOnlyIcons\033n mode: +; +;+++translateme+++ +MSGID_ICONSPAGE_SHOWTHUMBNAILS_AS_DEFAULT_SHORTHELP +Select it to allow the displaying of icons\n\ +thumbnails images for default icons with windows\n\ +using the \033bShow Only Icons\033n show mode.\n\ +\n\ +This option is only availlable if \033bAs default\033n\n\ +option is set from \033bDisplay Thumbnails\033n setting. +;Select it to allow the displaying of icons\n\ +;thumbnails images for default icons with windows\n\ +;using the \033bShow Only Icons\033n show mode.\n\ +;\n\ +;This option is only availlable if \033bAs default\033n\n\ +;option is set from \033bDisplay Thumbnails\033n setting. +; +;+++translateme+++ +MSGID_ICONSPAGE_THUMBNAILS_SIZE +Thumbnail size +;Thumbnail size +; +;+++translateme+++ +MSGID_ICONSPAGE_THUMBNAILS_SIZE_SHORTHELP +Select desired size for thumbnail images.\n\ +Actual size may vary, due to image aspect. +;Select desired size for thumbnail images.\n\ +;Actual size may vary, due to image aspect. +; +;+++translateme+++ +MSGID_ICONSPAGE_THUMBNAILS_MAXAGE +Cleanup after +;Cleanup after +; +;+++translateme+++ +MSGID_ICONSPAGE_THUMBNAILS_MAXAGE_SHORTHELP +Cached thumbnail images will be removed from the cache\n\ +if they have not been accessed for more than the\n\ +specified number of days, in order to keep cache\n\ +size as small as possible. +;Cached thumbnail images will be removed from the cache\n\ +;if they have not been accessed for more than the\n\ +;specified number of days, in order to keep cache\n\ +;size as small as possible. +; +;+++translateme+++ +MSGID_ICONSPAGE_THUMBNAILS_MAXAGE_DAYS +days +;days +; +; +++translateme+++ +MSGID_ICONSPAGE_THUMBNAILS_MINSIZE_LIMIT +Minimum limit size +;Minimum limit size +; +; +++translateme+++ +MSGID_ICONSPAGE_THUMBNAILS_MINSIZE_LIMIT_SHORTHELP +Select desired minimum dimensions for images to cache.\n\ +Images with smallers dimensions than value specified here,\n\ +will not be added to the cache. +;Select desired minimum dimensions for images to cache.\n\ +;Images with smallers dimensions than value specified here,\n\ +;will not be added to the cache. +; +; +++translateme+++ +MSGID_ICONSPAGE_SHOWTHUMBNAILS_AS_DEFAULT_SHORTHELP +Select it to allow the displaying of icons\n\ +thumbnails images for default icons.\n\ +This option is only availlable if \033bAs default\033n\n\ +option is set from \033bDisplay Thumbnails\033n setting. +;Select it to allow the displaying of icons\n\ +;thumbnails images for default icons.\n\ +;This option is only availlable if \033bAs default\033n\n\ +;option is set from \033bDisplay Thumbnails\033n setting. +; +; +++translateme+++ +MSGID_ICONSPAGE_TOOLTIPS_TRANSPARENCY +Transparency +;Transparency +; +; +++translateme+++ +MSGID_ICONSPAGE_TOOLTIPS_TRANSPARENCY_SHORTHELP +Tooltips can be drawn transparent.\n\ +Please select the degree of\n\ +transparency for the tooltips.\n\ +Please note that transparency is only available\n\ +if your desktop screen has more than 256 colors. +;Tooltips can be drawn transparent.\n\ +;Please select the degree of\n\ +;transparency for the tooltips.\n\ +;Please note that transparency is only available\n\ +;if your desktop screen has more than 256 colors. +; +; +++translateme+++ +MSGID_ICONSPAGE_THUMBNAILS_SETTINGS +Settings +;Settings +; +; +++translateme+++ +MSGID_ICONSPAGE_THUMBNAILS_CACHE +Caching +;Caching +; +; +++translateme+++ +MSGID_ICONSPAGE_THUMBNAILS_QUALITY +Quality +;Quality +; +; +++translateme+++ +MSGID_ICONSPAGE_THUMBNAILS_QUALITY_WORST +Low +;Low +; +; +++translateme+++ +MSGID_ICONSPAGE_THUMBNAILS_QUALITY_BEST +High +;High +; +; +++translateme+++ +MSGID_ICONSPAGE_THUMBNAILS_QUALITY_SHORTHELP +This slider selects the quality of the generated thumbnails.\n\ +Usually, better quality thumbnails take longer to create.\n\ +The actual effect of quality setting depends on the preview plugin used. +;This slider selects the quality of the generated thumbnails.\n\ +;Usually, better quality thumbnails take longer to create.\n\ +;The actual effect of quality setting depends on the preview plugin used. +; +; +++translateme+++ +MSGID_ICONSPAGE_THUMBNAILS_SQUARE +Thumbnails always square: +;Thumbnails always square: +; +; +++translateme+++ +MSGID_ICONSPAGE_THUMBNAILS_SQUARE_SHORTHELP +By default, thumbnail image icons reflect the aspect ratio\n\ +of their parent images, i.e. they can be wider than high or vice versa.\n\ +If this checkbox is checked, thumbnail image icons are always square.\n\ +;By default, thumbnail image icons reflect the aspect ratio\n\ +;of their parent images, i.e. they can be wider than high or vice versa.\n\ +;If this checkbox is checked, thumbnail image icons are always square.\n\ +; +; +++translateme+++ +MSGID_ICONSPAGE_THUMBNAILS_ICONFRAME +Thumbnail Icon Frames +;Thumbnail Icon Frames +; +; +++translateme+++ +MSGID_ICONSPAGE_THUMBNAILS_ICONFRAME_NORMAL_SHORTHELP +This type of border is drawn around unselected thumbnail icons.\n\ +\033bGlowIcons\033n which have been marked as\n\ +\"borderless\" will not show this border.\n\ +;Please note that the icon borders below must\n\ +;be non-zero for the icon border to show. +;This type of border is drawn around unselected thumbnail icons.\n\ +;\033bGlowIcons\033n which have been marked as\n\ +;\"borderless\" will not show this border.\n\ +;;Please note that the icon borders below must\n\ +;;be non-zero for the icon border to show. +; +; +++translateme+++ +MSGID_ICONSPAGE_THUMBNAILS_ICONFRAME_SELECTED_SHORTHELP +This type of border is drawn around selected thumbnail icons.\n\ +\033bGlowIcons\033n which have been marked as\n\ +\"borderless\" will not show this border.\n\ +;Please note that the icon borders below must\n\ +;be non-zero for the icon border to show. +;This type of border is drawn around selected thumbnail icons.\n\ +;\033bGlowIcons\033n which have been marked as\n\ +;\"borderless\" will not show this border.\n\ +;;Please note that the icon borders below must\n\ +;;be non-zero for the icon border to show. +; +;+++translateme+++ +MSGID_ICONSPAGE_THUMBNAILS_BACKFILL +Thumbnails background filled +;Thumbnails background filled +; +;+++translateme+++ +MSGID_ICONSPAGE_THUMBNAILS_BACKFILL_SHORTHELP +Enable this attribute to draw all thumbnail icons with the\n\ +backfill colors defined by Scalos palette prefs.\n\ +If this switch is off, thumbnails have transparent background. +;Enable this attribute to draw all thumbnail icons with the\n\ +;backfill colors defined by Scalos palette prefs.\n\ +;If this switch is off, thumbnails have transparent background. +; +;+++translateme+++ +MSGID_ICONSPAGE_THUMBNAIL_BACKFILL_TRANSPARENCY +Thumbnail background transparency +;Thumbnail background transparency +; +;+++translateme+++ +MSGID_ICONSPAGE_THUMBNAIL_BACKFILL_TRANSPARENCY_SHORTHELP +True-color icons can be drawn with filled\n\ +background of selectable transparency. +;True-color icons can be drawn with filled\n\ +;background of selectable transparency. +; +;+++translateme+++ +MSGID_ICONSPAGE_SEL_ICONTEXT_RECT_GROUP +Selected Icon Text Rectangle +;Selected Icon Text Rectangle +; +;+++translateme+++ +MSGID_ICONSPAGE_SEL_ICONTEXT_RECT +Draw additional rectangle around selected icon text +;Draw additional rectangle around selected icon text +; +;+++translateme+++ +MSGID_ICONSPAGE_SEL_ICONTEXT_RECT_SHORTHELP +Select this checkbox to draw a rectangle around the\n\ +icon text of all selected icons, for improved visibility. +;Select this checkbox to draw a rectangle around the\n\ +;icon text of all selected icons, for improved visibility. +; +;+++translateme+++ +MSGID_ICONSPAGE_SEL_ICONTEXT_XBORDER +Additional Horizontal border +;Additional Horizontal border +; +;+++translateme+++ +MSGID_ICONSPAGE_SEL_ICONTEXT_XBORDER_SHORTHELP +Additional horizontal border which is used for\n\ +drawing a rectangle around the icon text of selected icons. +;Additional horizontal border which is used for\n\ +;drawing a rectangle around the icon text of selected icons. +; +;+++translateme+++ +MSGID_ICONSPAGE_SEL_ICONTEXT_YBORDER +Additional Vertical border +;Additional Vertical border +; +;+++translateme+++ +MSGID_ICONSPAGE_SEL_ICONTEXT_YBORDER_SHORTHELP +Additional vertical border which is used for drawing\n\ +a rectangle around the icon text of selected icons. +;Additional vertical border which is used for drawing\n\ +;a rectangle around the icon text of selected icons. +; +;+++translateme+++ +MSGID_ICONSPAGE_SEL_ICONTEXT_RADIUS +Corner Radius +;Corner Radius +; +;+++translateme+++ +MSGID_ICONSPAGE_SEL_ICONTEXT_RADIUS_SHORTHELP +Corner radius of the rectangle drawn\n\ +around the text of selected icons. +;Corner radius of the rectangle drawn\n\ +;around the text of selected icons. +; +;+++translateme+++ +MSGID_ICONSPAGE_SCALING_NOMINALSIZE +Nominal Size: +;Nominal Size: +; +;+++translateme+++ +MSGID_ICONSPAGE_SCALING_NOMINALSIZE_SHORTHELP +Standard size adjustment applied to all icons. +;Standard size adjustment applied to all icons. +; +;+++translateme+++ +MSGID_ICONSPAGE_SCALING_PERCENT +% +;% +; +;----------------------------------------------------------- +; +MSGID_DRAGNDROPPAGE_STYLE +Style: +;Style: +; +; +MSGID_DRAGNDROPPAGE_STYLE_SHORTHELP +The icon label may be displayed\n\ +whilst the icon is being dragged. +;The icon label may be displayed\n\ +;whilst the icon is being dragged. +; +; +MSGID_DRAGNDROPPAGE_BOBS +Bobs +;Bobs +; +; +MSGID_DRAGNDROPPAGE_ROUTINES +Bob Routines: +;Bob Routines: +; +; +MSGID_DRAGNDROPPAGE_ROUTINES_SHORTHELP +Scalos provides custom fast smooth icon dragging routines.\n\ +Those custom routines are only used if you are\n\ +running a desktop with more than 256 colours. +;Scalos provides custom fast smooth icon dragging routines.\n\ +;Those custom routines are only used if you are\n\ +;running a desktop with more than 256 colours. +; +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY +Transparency Method: +;Transparency Method: +; +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY_SHORTHELP +When \"Ghosted/Real Transparent\" is selected, use\n\ +real transparency to draw drag-drop icons. Otherwise,\n\ +dotted \"ghosted\" display is used. Please note that\n\ +real transparency is only available if your\n\ +desktop screen has more than 256 colors. +;When \"Ghosted/Real Transparent\" is selected, use\n\ +;real transparency to draw drag-drop icons. Otherwise,\n\ +;dotted \"ghosted\" display is used. Please note that\n\ +;real transparency is only available if your\n\ +;desktop screen has more than 256 colors. +; +; +MSGID_DRAGNDROPPAGE_DROPMARKMODE +Drop mark mode: +;Drop mark mode: +; +; +MSGID_DRAGNDROPPAGE_DROPMARKMODE_SHORTHELP +Select which kind of drap-marks Scalos\n\ +shows while you drag icons around. +;Select which kind of drap-marks Scalos\n\ +;shows while you drag icons around. +; +; +MSGID_DRAGNDROPPAGE_LOOK +Look: +;Look: +; +; +MSGID_DRAGNDROPPAGE_LOOK_SHORTHELP +A Trigger can change the look of the icon\n\ +currently being dragged. You can select what\n\ +\033btriggers\033n should affect your icons below. +;A Trigger can change the look of the icon\n\ +;currently being dragged. You can select what\n\ +;\033btriggers\033n should affect your icons below. +; +; +MSGID_DRAGNDROPPAGE_AUTOREMOVE +Auto remove icons: +;Auto remove icons: +; +; +MSGID_DRAGNDROPPAGE_AUTOREMOVE_SHORTHELP +If enabled, when you drag icons away from their\n\ +original position, only a semi-transparent shadow\n\ +of the icon remains at the original place. +;If enabled, when you drag icons away from their\n\ +;original position, only a semi-transparent shadow\n\ +;of the icon remains at the original place. +; +; +MSGID_DRAGNDROPPAGE_GROUP_MULTIPLE +Group multiple icons: +;Group multiple icons: +; +; +MSGID_DRAGNDROPPAGE_GROUP_MULTIPLE_SHORTHELP +When dragging multiple icons\n\ +they will appear as a pile\n\ +to speed up OS. +;When dragging multiple icons\n\ +;they will appear as a pile\n\ +;to speed up OS. +; +; +MSGID_DRAGNDROPPAGE_DRAGGINGLABEL +Display dragging label: +;Display dragging label: +; +; +MSGID_DRAGNDROPPAGE_DRAGGINGLABEL_SHORTHELP +When dragging multiple icons Scalos will display\n\ +a text line detailing number of files, drawers\n\ +and devices being dragged. +;When dragging multiple icons Scalos will display\n\ +;a text line detailing number of files, drawers\n\ +;and devices being dragged. +; +; +MSGID_DRAGNDROPPAGE_FORCECOPY +Force copy: +;Force copy: +; +; +MSGID_DRAGNDROPPAGE_FORCECOPY_SHORTHELP +Define the qualifier key that is used to\n\ +force copying (instead of moving) any\n\ +dragged files and drawers. +;Define the qualifier key that is used to\n\ +;force copying (instead of moving) any\n\ +;dragged files and drawers. +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS +Triggers +;Triggers +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_SHORTHELP +Enabling a trigger will change the icons appearance\n\ +to the \033bLook\033n configured above when the\n\ +icon is above trigger. +;Enabling a trigger will change the icons appearance\n\ +;to the \033bLook\033n configured above when the\n\ +;icon is above trigger. +; +; +MSGID_DRAGNDROPPAGE_QUALIFIERS +Qualifiers +;Qualifiers +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_DISKICONS +Disk icons +;Disk icons +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_DRAWERICONS +Drawer icons +;Drawer icons +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_TOOLICONS +Tool icons +;Tool icons +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_PROJECTICONS +Project icons +;Project icons +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_TRASHCANICONS +Trashcan icons +;Trashcan icons +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_KICKICONS +Kick icons +;Kick icons +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_APPICONS +Application icons +;Application icons +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_APPWINDOWS +Application windows +;Application windows +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_ICONIFIED_WINDOWS +Iconified windows +;Iconified windows +; +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY_ICONDRAG +Icon drag +;Icon drag +; +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY_ICONDRAG_SHORTHELP +Select degree of icon transparency when dragging icons.\n\ +0%% means completely transparent (invisible!) icons.\n\ +100%% means opaque icons.\n\ +Please note that real transparency is only available\n\ +if your desktop screen has more than 256 colors. +;Select degree of icon transparency when dragging icons.\n\ +;0%% means completely transparent (invisible!) icons.\n\ +;100%% means opaque icons.\n\ +;Please note that real transparency is only available\n\ +;if your desktop screen has more than 256 colors. +; +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY_ICONSHADOW +Icon shadow +;Icon shadow +; +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY_ICONSHADOW_SHORTHELP +Select degree of transparency of the icon shadow that\n\ +remains at the original position when you start\n\ +dragging the icon away.\n\ +0% means completely transparent (invisible!) shadow.\n\ +100% means opaque shadow. +;Select degree of transparency of the icon shadow that\n\ +;remains at the original position when you start\n\ +;dragging the icon away.\n\ +;0% means completely transparent (invisible!) shadow.\n\ +;100% means opaque shadow.\n\ +;Please note that real transparency is only available\n\ +;if your desktop screen has more than 256 colors. +; +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY_OPAQUE +opaque +;opaque +; +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY_TRANSPARENT +transparent +;transparent +; +; +MSGID_DRAGNDROPPAGE_EASY_MULTISELECT +Easy Multiple Icon Selection: +;Easy Multiple Icon Selection: +; +; +MSGID_DRAGNDROPPAGE_EASY_MULTISELECT_SHORTHELP +When enabled, you are not required to hold the\n\ +\033bshift\033n key to select multiple icons. +;When enabled, you are not required to hold the\n\ +;\033bshift\033n key to select multiple icons. +; +; +MSGID_DRAGNDROPPAGE_EASY_MULTIDRAG +Easy Dragging of Multiple Icons: +;Easy Dragging of Multiple Icons: +; +; +MSGID_DRAGNDROPPAGE_EASY_MULTIDRAG_SHORTHELP +When enabled, you are not required to hold the\n\ +\033bshift\033n key when you begin to drag\n\ +multiple selected icons. +;When enabled, you are not required to hold the\n\ +;\033bshift\033n key when you begin to drag\n\ +;multiple selected icons. +; +; +MSGID_DRAGNDROPPAGE_FORCEMAKELINK +Create Links: +;Create Links: +; +; +MSGID_DRAGNDROPPAGE_FORCEMAKELINK_SHORTHELP +Define the qualifier key that is used to\n\ +create links to (instead of copying) any\n\ +dragged files and drawers. +;Define the qualifier key that is used to\n\ +;create links to (instead of copying) any\n\ +;dragged files and drawers. +; +; +MSGID_DRAGNDROPPAGE_FORCEMOVE +Force move: +;Force move: +; +; +MSGID_DRAGNDROPPAGE_FORCEMOVE_SHORTHELP +Define the qualifier key that is used to\n\ +force moving (instead of copying) any\n\ +dragged files and drawers. +;Define the qualifier key that is used to\n\ +;force moving (instead of copying) any\n\ +;dragged files and drawers. +; +;+++translateme+++ +MSGID_DRAGNDROPPAGE_DROPMENU +Show Drop Menu: +;Show Drop Menu: +; +;+++translateme+++ +MSGID_DRAGNDROPPAGE_DROPMENU_SHORTHELP +When enabled, a popup menu is displayed on each drag-drop\n\ +operation that allows easy selection whether to \033bcopy\033n or\n\ +\033bmove\033n item, \033bcreate link\033n to item, or entirely cancel drag-drop. +;When enabled, a popup menu is displayed on each drag-drop\n\ +;operation that allows easy selection whether to \033bcopy\033n or\n\ +;\033bmove\033n item, \033bcreate link\033n to item, or entirely cancel drag-drop. +; +;+++translateme+++ +MSGID_DRAGNDROPPAGE_TRIGGERS_SCALOS_WINDOWS +Scalos Windows +;Scalos Windows +; +;+++translateme+++ +MSGID_DRAGNDROPPAGE_POPOPENWINDOWS +Pop-Open Windows +;Pop-Open Windows +; +;+++translateme+++ +MSGID_DRAGNDROPPAGE_SLIDER_POPOPWINDOW_DELAY +Pop-Open Delay: +;Pop-Open Delay: +; +;+++translateme+++ +MSGID_DRAGNDROPPAGE_SLIDER_POPOPWINDOW_DELAY_SHORTHELP +During a drag&drop operation, this is the number of seconds\n\ +you have to keep the mouse pointer steady over a drawer\n\ +or volume icon before it pops open. +;During a drag&drop operation, this is the number of seconds\n\ +;you have to keep the mouse pointer steady over a drawer\n\ +;or volume icon before it pops open. +; +;----------------------------------------------------------- +; +MSGID_WINDOWPAGE_WINDOWTITLES +Window Titles +;Window Titles +; +; +MSGID_WINDOWPAGE_WINDOWTITLES_ROOTWINDOW +Root Window: +;Root Window: +; +; +MSGID_WINDOWPAGE_WINDOWTITLES_ROOTWINDOW_SHORTHELP +This is the title for the Scalos root window. You only\n\ +see this window title when you have the \"Backdrop\"\n\ +menu item in the Scalos main menu unchecked. +;This is the title for the Scalos root window. You only\n\ +;see this window title when you have the \"Backdrop\"\n\ +;menu item in the Scalos main menu unchecked. +; +; +MSGID_WINDOWPAGE_WINDOWTITLES_ROOTWINDOW_DESCRIPTION +|\033b\0338Description +;|\033b\0338Description +; +; +MSGID_WINDOWPAGE_WINDOWTITLES_DIRECTORYWINDOW +Directory Window: +;Directory Window: +; +; +MSGID_WINDOWPAGE_WINDOWTITLES_DIRECTORYWINDOW_SHORTHELP +This is the window title for any\n\ +normal Scalos drawer window. +;This is the window title for any\n\ +;normal Scalos drawer window. +; +; +MSGID_WINDOWPAGE_WINDOWTITLES_DIRECTORYWINDOW_DESCRIPTION +|\033b\0338Description +;|\033b\0338Description +; +; +MSGID_WINDOWPAGE_WINDOWTYPE +Window type: +;Window type: +; +; +MSGID_WINDOWPAGE_WINDOWTYPE_SHORTHELP +Select whether you would like to be all\n\ +Scalos windows to be created as simple-refresh\n\ +or smart-refresh window. +;Select whether you would like to be all\n\ +;Scalos windows to be created as simple-refresh\n\ +;or smart-refresh window. +; +; +MSGID_WINDOWPAGE_CONTEXTMENU_DRAGBAR +Context menu on dragbar only: +;Context menu on dragbar only: +; +; +MSGID_WINDOWPAGE_CONTEXTMENU_DRAGBAR_SHORTHELP +Only allows the windows pop-up menu\n\ +to appear when the right mouse button\n\ +is clicked over the\nwindows dragbar +;Only allows the windows pop-up menu\n\ +;to appear when the right mouse button\n\ +;is clicked over the\nwindows dragbar +; +; +MSGID_WINDOWPAGE_MMB_MOVE +MMB Moves Contents: +;MMB Moves Contents: +; +; +MSGID_WINDOWPAGE_MMB_MOVE_SHORTHELP +Allows the use of the middle mouse button\n\ +to pan around the window contents +;Allows the use of the middle mouse button\n\ +;to pan around the window contents +; +; +MSGID_WINDOWPAGE_SHOW_STATUSBAR +Show status bar: +;Show status bar: +; +; +MSGID_WINDOWPAGE_SHOW_STATUSBAR_SHORTHELP +Globally sets wether directory windows\n\ +display the status bar at the bottom. +;Globally sets wether directory windows\n\ +;display the status bar at the bottom. +; +; +MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE +Default Window Size +;Default Window Size +; +; +MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE_SHORTHELP +These are the default dimensions for Scalos drawer\n\ +windows. Windows for drawers without icons are opened\n\ +at this position and in this size. You are free to\n\ +move and resize the window any way you like, and\n\ +use \"snapshot window\" to permanently store the\n\ +changed values for that specific drawer window. +;These are the default dimensions for Scalos drawer\n\ +;windows. Windows for drawers without icons are opened\n\ +;at this position and in this size. You are free to\n\ +;move and resize the window any way you like, and\n\ +;use \"snapshot window\" to permanently store the\n\ +;changed values for that specific drawer window. +; +; +MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE_LEFT +Left: +;Left: +; +; +MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE_TOP +Top: +;Top: +; +; +MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE_WIDTH +Width: +;Width: +; +; +MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE_HEIGHT +Height: +;Height: +; +; +MSGID_WINDOWPAGE_CLEANUPSPACE +Cleanup Spaces +;Cleanup Spaces +; +; +MSGID_WINDOWPAGE_CLEANUPSPACE_SHORTHELP +This are the distances Scalos will leave around\n\ +icons when they are positioned with\n\ +the \"cleanup\" command. +;This are the distances Scalos will leave around\n\ +;icons when they are positioned with\n\ +;the \"cleanup\" command. +; +; +MSGID_WINDOWPAGE_CLEANUPSPACE_LEFT +Left: +;Left: +; +; +MSGID_WINDOWPAGE_CLEANUPSPACE_TOP +Top: +;Top: +; +; +MSGID_WINDOWPAGE_CLEANUPSPACE_XSKIP +X-Skip: +;X-Skip: +; +; +MSGID_WINDOWPAGE_CLEANUPSPACE_YSKIP +Y-Skip: +;Y-Skip: +; +; +MSGID_WINDOWPAGE_CLEANUP_ONRESIZE +Rearrange icons on resize +; +; +MSGID_WINDOWPAGE_CLEANUP_ONRESIZE_SHORTHELP +If this switch is enabled, all icons\n\ +without fixed position are automatically\n\ +rearranged when window is resized. +; +; +MSGID_WINDOWPAGE_SHOWALL_DEFAULT +Default mode for \033bShow All\033n: +;Default mode for \033bShow All\033n: +; +; +MSGID_WINDOWPAGE_SHOWALL_DEFAULT_SHORTHELP +This setting selects how the value \"default\"\n\ +is handled for \033bshow all\033n.\n\ +You can select whether \"default\" shows\n\ +\033bonly icons\033n, or \033ball files\033n. +;This setting selects how the value \"default\"\n\ +;is handled for \033bshow all\033n.\n\ +;You can select whether \"default\" shows\n\ +;\033bonly icons\033n, or \033ball files\033n. +; +; +MSGID_WINDOWPAGE_VIEWBY_DEFAULT +Default \033bView By\033n Mode: +;Default \033bView By\033n Mode: +; +; +MSGID_WINDOWPAGE_WINDOWTYPE_VIEWBY_DEFAULT_SHORTHELP +Selects which view mode is to be used for all\n\ +drawers with their view mode set to \"default\". +;Selects which view mode is to be used for all\n\ +;drawers with their view mode set to \"default\". +; +;+++translateme+++ +MSGID_WINDOWPAGE_CONTROLBAR_BROWSER_GADGETS +Browser Window Gadgets +;Browser Window Gadgets +; +;+++translateme+++ +MSGID_WINDOWPAGE_CONTROLBAR_GADGETS_SHORTHELP +Select here which gadgets you would like to\n\ +have in your browser window control bar. +;Select here which gadgets you would like to\n\ +;have in your browser window control bar. +; +;+++translateme+++ +MSGID_WINDOWPAGE_CONTROLBAR_AVAILABLE_GADGETS +Available Gadgets +;Available Gadgets +; +; +MSGID_WINDOWPAGE_CONTROLBAR_AVAILABLE_GADGETS_SHORTHELP +Select one ore move gadgets from this list and drag\n\ +them to the list of \033bActive Gadgets\00n. +;Select one ore move gadgets from this list and drag\n\ +;them to the list of \033bActive Gadgets\00n. +; +;+++translateme+++ +MSGID_WINDOWPAGE_CONTROLBAR_ACTIVE_GADGETS +Active Gadgets +;Active Gadgets +; +;+++translateme+++ +MSGID_WINDOWPAGE_CONTROLBAR_ACTIVE_GADGETS_SHORTHELP +These are the gadgets currently on your control bar.\n\ +Change the order of the gadgets by sorting them via drag-and-drop.\n\ +To remove gadgets, drag them to the\n\ +\033bAvailable Gadgets\033n on the left.\n\ +To add new gadgets, drag new gadgets from the\n\ +\033bAvailable Gadgets\033n to the position you want to see them. +;These are the gadgets currently on your control bar.\n\ +;Change the order of the gadgets by sorting them via drag-and-drop.\n\ +;To remove gadgets, drag them to the\n\ +;\033bAvailable Gadgets\033n on the left.\n\ +;To add new gadgets, drag new gadgets from the\n\ +;\033bAvailable Gadgets\033n to the position you want to see them. +; +;+++translateme+++ +MSGID_CONTROLBARGADGETLIST_TYPE +Gadget Type +;Gadget Type +; +;+++translateme+++ +MSGID_WINDOWPAGE_CONTROLBAR_NORMALIMAGE +Unselected Image +;Unselected Image +; +;+++translateme+++ +MSGID_WINDOWPAGE_CONTROLBAR_NORMALIMAGE_ASLTITLE +Select image for unselected state +;Select image for unselected state +; +;+++translateme+++ +MSGID_WINDOWPAGE_CONTROLBAR_NORMALIMAGE_SHORTHELP +Select here any datatypes image for the\n\ +unselected state of a user-defined button. +;Select here any datatypes image for the\n\ +;unselected state of a user-defined button. +; +;+++translateme+++ +MSGID_WINDOWPAGE_CONTROLBAR_SELECTEDIMAGE +Selected Image +;Selected Image +; +;+++translateme+++ +MSGID_WINDOWPAGE_CONTROLBAR_SELECTEDIMAGE_ASLTITLE +Select image for Selected state +;Select image for Selected state +; +;+++translateme+++ +MSGID_WINDOWPAGE_CONTROLBAR_SELECTEDIMAGE_SHORTHELP +Select here any datatypes image for the\n\ +selected state of a user-defined button. +;Select here any datatypes image for the\n\ +;selected state of a user-defined button. +; +;+++translateme+++ +MSGID_WINDOWPAGE_CONTROLBAR_DISABLEDIMAGE +Disabled Image +;Disabled Image +; +;+++translateme+++ +MSGID_WINDOWPAGE_CONTROLBAR_DISABLEDIMAGE_ASLTITLE +Select image for Disabled state +;Select image for Disabled state +; +;+++translateme+++ +MSGID_WINDOWPAGE_CONTROLBAR_DISABLEDIMAGE_SHORTHELP +Select here any datatypes image for the\n\ +disabled state of a user-defined button. +;Select here any datatypes image for the\n\ +;disabled state of a user-defined button. +; +;+++translateme+++ +MSGID_WINDOWPAGE_CONTROLBAR_ACTION +Button Action +;Button Action +; +;+++translateme+++ +MSGID_WINDOWPAGE_CONTROLBAR_ACTION_SHORTHELP +For user-defined buttons select here any action from\n\ +the list of available Scalos menu commands. +;For user-defined buttons select here any action from\n\ +;the list of available Scalos menu commands. +; +;+++translateme+++ +MSGID_WINDOWPAGE_CONTROLBAR_GADGETHELPTEXT +Help Text +;Help Text +; +;+++translateme+++ +MSGID_WINDOWPAGE_CONTROLBAR_GADGETHELPTEXT_SHORTHELP +For user-defined buttons, enter your gadget help text here.\n\ +This text is displayed when you keep your mouse\n\ +steadily positioned on the gadgets for a few seconds. +;For user-defined buttons, enter your gadget help text here.\n\ +;This text is displayed when you keep your mouse\n\ +;steadily positioned on the gadgets for a few seconds. +; +;+++translateme+++ +MSGID_WINDOWPAGE_CHECK_OVERLAP +Check for Overlapping Icons: +;Check for Overlapping Icons: +; +;+++translateme+++ +MSGID_WINDOWPAGE_CHECK_OVERLAP_SHORTHELP +Globally sets whether verification is performed that icons do\n\ +not overlap each other.\n\ +If enabled, overlapping icons will be repositioned when read. +;Globally sets whether verification is performed that icons do\n\ +;not overlap each other.\n\ +;If enabled, overlapping icons will be repositioned when read. +; +;+++translateme+++ +MSGID_WINDOWPAGE_TRANSPARENCY_WINDOW +Transparency +;Transparency +; +;+++translateme+++ +MSGID_WINDOWPAGE_TRANSPARENCY_ACTIVEWINDOW +Active window +;Active window +; +;+++translateme+++ +MSGID_WINDOWPAGE_TRANSPARENCY_INACTIVEWINDOW +Inactive windows +;Inactive windows +; +;+++translateme+++ +MSGID_WINDOWPAGE_TRANSPARENCY_ACTIVEWINDOW_SHORTHELP +Here you can select the degree of transparency\n\ +for the active Scalos desktop, icon, or text window.\n\ +The desktop will only get transparent if it is not a backdrop window. +;Here you can select the degree of transparency\n\ +;for the active Scalos desktop, icon, or text window.\n\ +;The desktop will only get transparent if it is not a backdrop window. +; +;+++translateme+++ +MSGID_WINDOWPAGE_TRANSPARENCY_INACTIVEWINDOW_SHORTHELP +Here you can select the degree of transparency\n\ +for all inactive Scalos desktop, icon, or text windows.\n\ +The desktop will only get transparent if it is not a backdrop window. +;Here you can select the degree of transparency\n\ +;for all inactive Scalos desktop, icon, or text windows.\n\ +;The desktop will only get transparent if it is not a backdrop window. +; +;+++translateme+++ +MSGID_WINDOWPAGE_CONTROLBAR_NORMAL_GADGETS +Standard Window Gadgets +;Standard Window Gadgets +; +;----------------------------------------------------------- +; +;+++translateme+++ +MSGID_TEXTWINDOWSPAGE_SELECTION_BORDER_TRANSPARENCY +Border Transparency +;Border Transparency +; +;+++translateme+++ +MSGID_TEXTWINDOWSPAGE_SELECTION_FILL_TRANSPARENCY +Fill Transparency +;Fill Transparency +; +;+++translateme+++ +MSGID_TEXTWINDOWSPAGE_GROUP_BASECOLOR +Base Color +;Base Color +; +;+++translateme+++ +MSGID_TEXTWINDOWSPAGE_SELECTIONMARK_BASECOLOR_SHORTHELP +Here you can adjust the base color for the\n\ +text window icon selection marker. +;Here you can adjust the base color for the\n\ +;text window icon selection marker. +; +;+++translateme+++ +MSGID_TEXTWINDOWSPAGE_SELECTIONMARK_BORDER_TRANSPARENCY_SHORTHELP +Adjust degree of transparency for the border\n\ +of the text window icon selection marker. +;Adjust degree of transparency for the border\n\ +;of the text window icon selection marker. +; +;+++translateme+++ +MSGID_TEXTWINDOWSPAGE_SELECTIONMARK_FILL_TRANSPARENCY_SHORTHELP +Adjust degree of transparency for the interior\n\ +fill of the text window icon selection marker. +;Adjust degree of transparency for the interior\n\ +;fill of the text window icon selection marker. +; +;+++translateme+++ +MSGID_TEXTWINDOWPAGE_DRAWERSORT_TOP +Before files +;Before files +; +;+++translateme+++ +MSGID_TEXTWINDOWPAGE_DRAWERSORT_BOTTOM +After files +;After files +; +;+++translateme+++ +MSGID_TEXTWINDOWPAGE_DRAWERSORT_MIXED +With files +;With files +; +;+++translateme+++ +MSGID_TEXTWINDOWSPAGE_DRAWERSORT +Drawer sorting +;Drawer sorting +; +;+++translateme+++ +MSGID_TEXTWINDOWSPAGE_DRAWERSORT_SHORTHELP +Select how drawers are sorted in text windows.\n\ +Drawers can be displayed always on top, always\n\ +on bottom, or mixed between files. +;Select how drawers are sorted in text windows.\n\ +;Drawers can be displayed always on top, always\n\ +;on bottom, or mixed between files. +; +;----------------------------------------------------------- +; +MSGID_FILEDISPLAYPAGE_FONT +Font: +;Font: +; +; +MSGID_FILEDISPLAYPAGE_FONT_SHORTHELP +Select font to display text window contents.\n\ +This selection is disabled while TrueType\n\ +text window fonts are enabled. +;Select font to display text window contents.\n\ +;This selection is disabled while TrueType\n\ +;text window fonts are enabled. +; +; +MSGID_FILEDISPLAYPAGE_FONT_ASLTITLE +Please select a font... +;Please select a font... +; +; +MSGID_FILEDISPLAYPAGE_FONT_EXAMPLE +Example: +;Example: +; +; +MSGID_FILEDISPLAYPAGE_FONT_SAMPLETEXT +This is an example text to visualize what the selected font looks like +;This is an example text to visualize what the selected font looks like +; +; +MSGID_FILEDISPLAYPAGE_SOFTLINKS_UNDERLINED +Display soft-link file names \033uunderlined\033n: +;Display soft-link file names \033uunderlined\033n: +; +; +MSGID_FILEDISPLAYPAGE_SOFTLINKS_UNDERLINED_SHORTHELP +When this item is checked, names of soft-links\n\ +are displayed \033uunderlined\033n. +;When this item is checked, names of soft-links\n\ +;are displayed \033uunderlined\033n. +; +; +MSGID_FILEDISPLAYPAGE_HIDE_HIDDENFILES +Hide hidden files: +;Hide hidden files: +; +; +MSGID_FILEDISPLAYPAGE_HIDE_HIDDENFILES_SHORTHELP +A hidden file is any filename beginning with\n\ +a '\033b.\033n' or icon files '\033b#?.info\033n' +;A hidden file is any filename beginning with\n\ +;a '\033b.\033n' or icon files '\033b#?.info\033n' +; +; +MSGID_FILEDISPLAYPAGE_AVAILABLE_COLUMNS +Available Columns +;Available Columns +; +; +MSGID_FILEDISPLAYPAGE_AVAILABLE_COLUMNS_SHORTHELP +This are the columns currently not displayed\n\ +in text windows. If you want some item to be\n\ +displayed, drag it to the \"Displayed columns\" list. +;This are the columns currently not displayed\n\ +;in text windows. If you want some item to be\n\ +;displayed, drag it to the \"Displayed columns\" list. +; +; +MSGID_FILEDISPLAYPAGE_COLUMNS_INUSE +Displayed Columns +;Displayed Columns +; +; +MSGID_FILEDISPLAYPAGE_COLUMNS_INUSE_SHORTHELP +This are the columns that will display in text\n\ +windows. You may change the display order by\n\ +drag-sorting the lines. If you want some item\n\ +not to be displayed, drag it to\n\ +the \"Available columns\" list. +;This are the columns that will display in text\n\ +;windows. You may change the display order by\n\ +;drag-sorting the lines. If you want some item\n\ +;not to be displayed, drag it to\n\ +;the \"Available columns\" list. +; +; +MSGID_FILEDISPLAYPAGE_STRIPED +Striped Display +;Striped Display +; +; +MSGID_FILEDISPLAYPAGE_STRIPED_SHORTHELP +Shows every other line in text window\n\ +in different color, to improve readability.\n\ +Please note that real transparency is only available\n\ +if your desktop screen has more than 256 colors. +;Shows every other line in text window\n\ +;in different color, to improve readability.\n\ +;Please note that real transparency is only available\n\ +;if your desktop screen has more than 256 colors. +; +; +MSGID_FILEDISPLAYPAGE_SELECTTEXTICONNAME +Name column selects text icons +; Name column selects text icons +; +; +MSGID_FILEDISPLAYPAGE_SELECTTEXTICONNAME_SHORTHELP +If this checkmark is checked, text icons can\n\ +only be selected within the \033bname\033n column.\n\ +If unchecked, the entire row can be used\n\ +to select the icon. +;If this checkmark is checked, text icons can\n\ +;only be selected within the \033bname\033n column.\n\ +;If unchecked, the entire row can be used\n\ +;to select the icon. +; +;----------------------------------------------------------- +; +MSGID_TTFONTSPAGE_SCREENFONT +TrueType Screen Font +;TrueType Screen Font +; +; +MSGID_TTFONTSPAGE_SCREENFONT_ENABLE +Use TT Screen Font +;Use TT Screen Font +; +; +MSGID_TTFONTSPAGE_SCREENFONT_ENABLE_SHORTHELP +When this item is checked, Scalos uses\n\ +TrueType fonts for screen font. +;When this item is checked, Scalos uses\n\ +;TrueType fonts for screen font. +; +; +MSGID_TTFONTSPAGE_SCREENFONT_SHORTHELP +This is the textual TrueType screen font\n\ +specification (style/weight/size/name). +;This is the textual TrueType screen font\n\ +;specification (style/weight/size/name). +; +; +MSGID_TTFONTSPAGE_ICONFONT +TrueType Icon Font +;TrueType Icon Font +; +; +MSGID_TTFONTSPAGE_ICONFONT_ENABLE +Use TT Icon Font +;Use TT Icon Font +; +; +MSGID_FONTSPAGE_TTFICONFONT_ENABLE_SHORTHELP +When this item is checked, Scalos\n\ +uses TrueType fonts for icons. +;When this item is checked, Scalos\n\ +;uses TrueType fonts for icons. +; +; +MSGID_TTFONTSPAGE_ICONFONT_SHORTHELP +This is the textual TrueType icon font\n\ +specification (style/weight/size/name). +;This is the textual TrueType icon font\n\ +;specification (style/weight/size/name). +; +; +MSGID_TTFONTSPAGE_TEXTWINDOWFONT +TrueType Text Window Font +;TrueType Text Window Font +; +; +MSGID_TTFONTSPAGE_TTFTEXTWINDOWFONT_ENABLE +Use TT Text WIndow Font +;Use TT Text WIndow Font +; +; +MSGID_TTFONTSPAGE_TTFTEXTWINDOWFONT_ENABLE_SHORTHELP +When this item is checked, Scalos uses\n\ +TrueType fonts for text windows. +;When this item is checked, Scalos uses\n\ +;TrueType fonts for text windows. +; +; +MSGID_TTFONTSPAGE_TEXTWINDOWFONT_SHORTHELP +This is the textual TrueType text window\n\ +font specification (style/weight/size/name). +;This is the textual TrueType text window\n\ +;font specification (style/weight/size/name). +; +; +MSGID_TTFONTSPAGE_SAMPLETEXT +The quick brown fox jumps over the lazy dog +;The quick brown fox jumps over the lazy dog +; +; +MSGID_TTFONTSPAGE_SCREENFONT_SAMPLETEXT_SHORTHELP +This is an example text to visualize what the\n\ +selected TrueType screen font looks like. +;This is an example text to visualize what the\n\ +;selected TrueType screen font looks like. +; +; +MSGID_TTFONTSPAGE_ICONFONT_SAMPLETEXT_SHORTHELP +This is an example text to visualize what the\n\ +selected TrueType icon font looks like. +;This is an example text to visualize what the\n\ +;selected TrueType icon font looks like. +; +; +MSGID_TTFONTSPAGE_TEXTWINDOWFONT_SAMPLETEXT_SHORTHELP +This is an example text to visualize what the\n\ +selected TrueType text window font looks like. +;This is an example text to visualize what the\n\ +;selected TrueType text window font looks like. +; +; +MSGID_TTFONTSPAGE_SELECTSCREENFONT_ASLTITLE +Select Screen TT Font... +;Select Screen TT Font... +; +; +MSGID_TTFONTSPAGE_SELECTICONFONT_ASLTITLE +Select Icon TT Font... +;Select Icon TT Font... +; +; +MSGID_TTFONTSPAGE_SELECTTEXTWINDOWFONT_ASLTITLE +Select Text Window TT Font... +;Select Text Window TT Font... +; +; +MSGID_TTFONTSPAGE_SELECTFONT_ASL_OKBUTTON +Ok +;Ok +; +; +MSGID_TTFONTSPAGE_SELECTFONT_ASL_CANCELBUTTON +Cancel +;Cancel +; +; +MSGID_TTFONTSPAGE_GLOBALS +Globals +;Globals +; +; +MSGID_TTFONTSPAGE_ANTIALIASING +Antialiasing +;Antialiasing +; +; +MSGID_TTFONTSPAGE_ANTIALIASING_SHORTHELP +Controls ttengine antialiasing (on, off or automatic):\n\ +Off - turns antialias off\n\ +On - turns antialias on\n\ +Auto (default) - antialias state depends on font\n\ +size. Typically sizes of 9 or less pixels are\n\ +antialiased, sizes from 10 to 19 pixels are not\n\ +antialiased, sizes of 20 of more pixels are\n\ +antialiased. These settings can be changed in the\n\ +ttengine font database separately for every font face. +;Controls ttengine antialiasing (on, off or automatic):\n\ +;Off - turns antialias off\n\ +;On - turns antialias on\n\ +;Auto (default) - antialias state depends on font\n\ +;size. Typically sizes of 9 or less pixels are\n\ +;antialiased, sizes from 10 to 19 pixels are not\n\ +;antialiased, sizes of 20 of more pixels are\n\ +;antialiased. These settings can be changed in the\n\ +;ttengine font database separately for every font face. +; +; +MSGID_TTFONTSPAGE_ANTIALIASING_ON +On +;On +; +; +MSGID_TTFONTSPAGE_ANTIALIASING_OFF +Off +;Off +; +; +MSGID_TTFONTSPAGE_ANTIALIASING_AUTO +Auto +;Auto +; +; +MSGID_TTFONTSPAGE_GAMMA +Gamma correction +;Gamma correction +; +; +MSGID_TTFONTSPAGE_GAMMA_SHORTHELP +Adjustable gamma correction used for ttengine\n\ +antialiasing. After RGB alphablending gamma\n\ +correction is applied to resulting pixel colour\n\ +according to x' = x ^ 1/gamma, where x\n\ +is a RGB component. +;Adjustable gamma correction used for ttengine\n\ +;antialiasing. After RGB alphablending gamma\n\ +;correction is applied to resulting pixel colour\n\ +;according to x' = x ^ 1/gamma, where x\n\ +;is a RGB component. +; +;----------------------------------------------------------- +; +MSGID_MISCPAGE_MENU_CURRENTDIR +Menu CurrentDir: +;Menu CurrentDir: +; +; +MSGID_MISCPAGE_MENU_CURRENTDIR_SHORTHELP +If enabled, Scalos changes to the directory of\n\ +the CLI tool before running a CLI menu command. +;If enabled, Scalos changes to the directory of\n\ +;the CLI tool before running a CLI menu command. +; +; +MSGID_MISCPAGE_HARD_EMULATION +Hard emulation: +;Hard emulation: +; +; +MSGID_MISCPAGE_HARD_EMULATION_SHORTHELP +If this item is checked, some additional Workbench\n\ +function vectors are patched by Scalos. In most\n\ +cases, there shouldn't be any reason to\n\ +turn off \"Hard emulation\". +;If this item is checked, some additional Workbench\n\ +;function vectors are patched by Scalos. In most\n\ +;cases, there shouldn't be any reason to\n\ +;turn off \"Hard emulation\". +; +; +MSGID_MISCPAGE_USE_EXALL +Use ExAll(): +;Use ExAll(): +; +; +MSGID_MISCPAGE_USE_EXALL_SHORTHELP +If this item is checked, Scalos will try to use\n\ +the \"ExAll()\" function to scan directories.\n\ +Usually, if a file system doesn't support ExAll(),\n\ +there is a fully automatic fall-back to other\n\ +functions. However, there might be some file systems\n\ +that don't support ExAll() but don't return\n\ +appropriate error codes either, or even crash.\n\ +If you happen to have such a file system, try to\n\ +turn \"Use ExAll()\" off. +;If this item is checked, Scalos will try to use\n\ +;the \"ExAll()\" function to scan directories.\n\ +;Usually, if a file system doesn't support ExAll(),\n\ +;there is a fully automatic fall-back to other\n\ +;functions. However, there might be some file systems\n\ +;that don't support ExAll() but don't return\n\ +;appropriate error codes either, or even crash.\n\ +;If you happen to have such a file system, try to\n\ +;turn \"Use ExAll()\" off. +; +; +MSGID_MISCPAGE_POPUPMENUS +Popup menus +;Popup menus +; +; +MSGID_MISCPAGE_POPUP_SELECTED_HOTKEY +Apply to every selected icon: +;Apply to every selected icon: +; +; +MSGID_MISCPAGE_POPUP_SELECTED_HOTKEY_SHORTHELP +Define the qualifier key that\n\ +applies popup menu commands to\n\ +every selected icon.\n\ +Normally, popup menu commands only apply\n\ +to the icon under the mouse pointer. +;Define the qualifier key that\n\ +;applies popup menu commands to\n\ +;every selected icon.\n\ +;Normally, popup menu commands only apply\n\ +;to the icon under the mouse pointer. +; +; +MSGID_MISCPAGE_DEFAULTSTACKSIZE +Default Stack size +;Default Stack size +; +; +MSGID_MISCPAGE_DEFAULTSTACKSIZE_SHORTHELP +Sets the stack size for most internal Scalos\n\ +processes and for CLI and ARexx processes\n\ +started by Scalos. +;Sets the stack size for most internal Scalos\n\ +;processes and for CLI and ARexx processes\n\ +;started by Scalos. +; +; +MSGID_MISCPAGE_DEFAULTSTACKSIZE_OS35 +Starting with Workbench 3.5, the default stack size \ +is be changed with the standard \ +\033bWorkbench Preferences\033n program. +;Starting with Workbench 3.5, the default stack size \ +;is changed with the standard \ +;\033bWorkbench Preferences\033n program. +; +; +MSGID_MISCPAGE_LABELS_STACK +Stack +;Stack +; +; +MSGID_MISCPAGE_CREATE_LINKS +Create links: +;Create links: +; +; +MSGID_MISCPAGE_CREATE_LINKS_SHORTHELP +Select what kind of links Scalos tries to create\n\ +when an object is dropped with the create-link\n\ +qualifier key pressed. +;Select what kind of links Scalos tries to create\n\ +;when an object is dropped with the create-link\n\ +;qualifier key pressed. +; +;+++translateme+++ +MSGID_MISCPAGE_POP_WORKBENCHPREFS_SHORTHELP +Launch standard \033bWorkbench Preferences\033n program. +;Launch standard \033bWorkbench Preferences\033n program. +; +;+++translateme+++ +MSGID_MISCPAGE_POPUP_SELECTED_ALWAYS +Always apply to all selected icons? +;Always apply to all selected icons? +; +;+++translateme+++ +MSGID_MISCPAGE_POPUP_SELECTED_ALWAYS_SHORTHELP +Select this checkbox to \033balways\033n apply popup menus\n\ +to every selected icons, regardless of qualifier key +;Select this checkbox to \033balways\033n apply popup menus\n\ +;to every selected icons, regardless of qualifier key +; +;+++translateme+++ +MSGID_MISCPAGE_COPYBUFFERSIZE +File Copy Buffer Size: +;File Copy Buffer Size: +; +;+++translateme+++ +MSGID_MISCPAGE_COPYBUFFERSIZE_SHORTHELP +Sets the buffer size for file copying. +;Sets the buffer size for file copying. +; +;+++translateme+++ +MSGID_MISCPAGE_LABELS_FILEOPERATIONS +File Operations +;File Operations +; +;+++translateme+++ +MSGID_MISCPAGE_LABELS_UNDOSTEPS +Maximum Number of Undo Steps +;Maximum Number of Undo Steps +; +;+++translateme+++ +MSGID_MISCPAGE_UNDOSTEPS +Max. Undo Steps: +;Max. Undo Steps: +; +;+++translateme+++ +MSGID_MISCPAGE_UNDOSTEPS_SHORTHELP +Here you can limit the number of\n\ +available Undo/Redo steps. +;Here you can limit the number of\n\ +;available Undo/Redo steps. +; +;----------------------------------------------------------- +; +MSGID_PLUGINSPAGE_ACTIVEPLUGINS +Active Plugins +;Active Plugins +; +; +MSGID_PLUGINSPAGE_INSTALLEDPLUGINS +\033cInstalled Plugins +;\033cInstalled Plugins +; +; +MSGID_PLUGINSPAGE_INSTALLEDPLUGINS_SHORTHELP +This is a complete list of all OOP plugins that\n\ +are loaded upon Scalos startup. OOP plugins add\n\ +new features to Scalos or improve existing\n\ +Scalos features. +;This is a complete list of all OOP plugins that\n\ +;are loaded upon Scalos startup. OOP plugins add\n\ +;new features to Scalos or improve existing\n\ +;Scalos features. +; +; +MSGID_PLUGINSPAGE_ADD_NEW +\033cAdd New +;\033cAdd New +; +; +MSGID_PLUGINSPAGE_ADD_NEW_SHORTHELP +Add a new OOP plugin to the list. This plugin\n\ +will be activated upon next Scalos startup. +;Add a new OOP plugin to the list. This plugin\n\ +;will be activated upon next Scalos startup. +; +; +MSGID_PLUGINSPAGE_REMOVE_SELECTED +\033cRemove Selected +;\033cRemove Selected +; +; +MSGID_PLUGINSPAGE_REMOVE_SELECTED_SHORTHELP +Remove the currently selected plugin\n\ +from the list. Scalos will not load the\n\ +plugin again. This change will only become\n\ +effective upon next Scalos startup. +;Remove the currently selected plugin\n\ +;from the list. Scalos will not load the\n\ +;plugin again. This change will only become\n\ +;effective upon next Scalos startup. +; +; +MSGID_PLUGINSPAGE_NAME +\033lName: +;\033lName: +; +; +MSGID_PLUGINSPAGE_NAME_SHORTHELP +This is the name the selected plugin\n\ +has been given by its creator. +;This is the name the selected plugin\n\ +;has been given by its creator. +; +; +MSGID_PLUGINSPAGE_FILENAME +\033lFile: +;\033lFile: +; +; +MSGID_PLUGINSPAGE_FILENAME_SHORTHELP +This is the complete filename and\n\ +path for the selected plugin. +;This is the complete filename and\n\ +;path for the selected plugin. +; +; +MSGID_PLUGINSPAGE_VERSION +\033lVersion: +;\033lVersion: +; +; +MSGID_PLUGINSPAGE_VERSION_SHORTHELP +This is the current version\n\ +of the selected plugin. +;This is the current version\n\ +;of the selected plugin. +; +; +MSGID_PLUGINSPAGE_DESCRIPTION +\033lDescription: +;\033lDescription: +; +; +MSGID_PLUGINSPAGE_DESCRIPTION_SHORTHELP +This is a description of what the\n\ +selected plugin is supposed to do. +;This is a description of what the\n\ +;selected plugin is supposed to do. +; +; +MSGID_PLUGINSPAGE_CREATOR +\033lCreator: +;\033lCreator: +; +; +MSGID_PLUGINSPAGE_CREATOR_SHORTHELP +This is the creator's name\n\ +of the selected plugin. +;This is the creator's name\n\ +;of the selected plugin. +; +; +MSGID_PLUGINSPAGE_EDIT_PREFERENCES +\033cEdit Preferences +;\033cEdit Preferences +; +; +MSGID_PLUGINSPAGE_EDIT_PREFERENCES_SHORTHELP +\033cEdit Preferences +;\033cEdit Preferences +; +; +MSGID_ADD_PLUGIN_ASLTITLE +Select new OOP plugin... +;Select new OOP plugin... +; +;----------------------------------------------------------- +; +MSGID_MODULESPAGE_MODULE_PREFERENCES +Module Preferences +;Module Preferences +; +; +MSGID_MODULESPAGE_MODULE_PREFERENCES_NOTICE +To configure any Scalos modules' settings you must click on \ +the pop-up image gadget to the right of the modules name. \ +This will open a new window with specific settings in it.\n\ +\n\ +If no configuration is available for a certain module \ +the pop-up gadget will be disabled. +;To configure any Scalos modules' settings you must click on \ +;the pop-up image gadget to the right of the modules name. \ +;This will open a new window with specific settings in it.\n\ +;\n\ +;If no configuration is available for a certain module \ +;the pop-up gadget will be disabled. +; +; +MSGID_MODULESPAGE_DELETE +Delete +;Delete +; +; +MSGID_MODULESPAGE_EMPTY_TRASHCAN +Empty Trashcan +;Empty Trashcan +; +; +MSGID_MODULESPAGE_EXECUTE_COMMAND +Execute Command +;Execute Command +; +; +MSGID_MODULESPAGE_INFORMATION +Information +;Information +; +; +MSGID_MODULESPAGE_NEWDRAWER +New Drawer +;New Drawer +; +; +MSGID_MODULESPAGE_REBOOT +Reboot +;Reboot +; +; +MSGID_MODULESPAGE_RENAME +Rename +;Rename +; +; +MSGID_MODULESPAGE_SYSTEM_INFORMATION +System Information +;System Information +; +;----------------------------------------------------------- +; +MSGID_SAVEBUTTON +\033cSave +;\033cSave +; +; +MSGID_SAVEBUTTON_SHORTHELP +Press this button to save \n\ +the current settings to\n\ +\"ENVARC:Scalos/Scalos.prefs\"\n\ +and make changes permanent. +;Press this button to save \n\ +;the current settings to\n\ +;\"ENVARC:Scalos/Scalos.prefs\"\n\ +;and make changes permanent. +; +; +MSGID_USEBUTTON +\033cUse +;\033cUse +; +; +MSGID_USEBUTTON_SHORTHELP +Press this button to save \n\ +the current settings to\n\ +\"ENV:Scalos/menu13.prefs\"\n\ +and keep settings until reboot. +;Press this button to save \n\ +;the current settings to\n\ +;\"ENV:Scalos/menu13.prefs\"\n\ +;and keep settings until reboot. +; +; +MSGID_CANCELBUTTON +\033cCancel +;\033cCancel +; +; +MSGID_CANCELBUTTON_SHORTHELP +Press this button to abort \n\ +and forget all changes. +;Press this button to abort \n\ +;and forget all changes. +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK +_OK +;_OK +; +; +MSGID_ABOUTREQFORMAT +\33cScalos Main Preferences V%ld.%ld\n\ +%s\n\ +© 2003-2004 The Scalos Team +;\33cScalos Main Preferences V%ld.%ld\n\ +;%s\n\ +;© 2003-2004 The Scalos Team +; +;----------------------------------------------------------- +; +MSGID_DESKTOPPAGES_SCREENTITLE_ALWAYS +Always visible +;Always visible +; +; +MSGID_DESKTOPPAGES_SCREENTITLE_POP +Pops up under mouse +;Pops up under mouse +; +; +MSGID_DESKTOPPAGES_SCREENTITLE_NEVER +permanently hidden +;permanently hidden +; +;----------------------------------------------------------- +; +; +MSGID_ICONSPAGES_DRAGNDROP_DRAGGING +Dragging +;Dragging +; +; +MSGID_ICONSPAGES_DRAGNDROP_TRANSPARENCY +Transparency +;Transparency +; +; +MSGID_ICONSPAGES_DRAGNDROP_TRIGGERS +Triggers +;Triggers +; +;----------------------------------------------------------- +; +MSGID_FRAMEWINDOW_TITLE +Available Frames +;Available Frames +; +;----------------------------------------------------------- +; +MSGID_PLUGINLIST_NAME +Name +;Name +; +; +MSGID_PLUGINLIST_PATH +Path +;Path +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Scalos Prefs startup failed +;Scalos Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Try again|Quit +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_ADDPLUGIN_FAILURE +Add Plugin Failure +;Add Plugin Failure +; +; +MSGID_ADDPLUGIN_OK_GAD +Ok +;Ok +; +; +MSGID_ADDPLUGIN_COULD_NOT_ADD +Could not add plugin.\n\ +Opening the plugin failed. +;Could not add plugin.\n\ +;Opening the plugin failed. +; +;----------------------------------------------------------- +; +MSGID_DESKTOPPAGE_ICONS_HIDDENDEVICES +Hidden Devices +;Hidden Devices +; +; +MSGID_DESKTOPPAGE_HIDDENDEVICES_SHORTHELP +Here you can select which devices will never show up on desktop.\n\ +This is the same setting as available in OS3.9 Workbench Prefs. +;Here you can select which devices will never show up on desktop.\n\ +;This is the same setting as available in OS3.9 Workbench Prefs. +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_DESKTOPPAGE_LAYOUTPREFERENCES +Desktop Layout Preferences by Icon Type +;Desktop Layout Preferences by Icon Type +; +;+++translateme+++ +MSGID_DESKTOPPAGE_LAYOUT_WBDISK +Disk icons: +;Disk icons: +; +;+++translateme+++ +MSGID_DESKTOPPAGE_LAYOUT_WBDISK_SHORTHELP +Select preferred icon layout direction\n\ +for \033bdisk icons\033n in desktop window.\n\ +\033iColumns\033n layouts icons in columns from top\n\ +to bottom, starting a new column when the\n\ +bottom of the window is reached.\n\ +\033iRows\033n layouts icons in rows left to right,\n\ +starting a new row when the right\n\ +window border is reached. +;Select preferred icon layout direction\n\ +;for \033bdisk icons\033n in desktop window.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +;+++translateme+++ +MSGID_DESKTOPPAGE_LAYOUT_WBDRAWER +Drawer icons: +;Drawer icons: +; +;+++translateme+++ +MSGID_DESKTOPPAGE_LAYOUT_WBDRAWER_SHORTHELP +Select preferred icon layout direction\n\ +for \033bdrawer icons\033n in desktop window.\n\ +\033iColumns\033n layouts icons in columns from top\n\ +to bottom, starting a new column when the\n\ +bottom of the window is reached.\n\ +\033iRows\033n layouts icons in rows left to right,\n\ +starting a new row when the right\n\ +window border is reached. +;Select preferred icon layout direction\n\ +;for \033bdrawer icons\033n in desktop window.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +;+++translateme+++ +MSGID_DESKTOPPAGE_LAYOUT_WBTOOL +Tool icons: +;Tool icons: +; +;+++translateme+++ +MSGID_DESKTOPPAGE_LAYOUT_WBTOOL_SHORTHELP +Select preferred icon layout direction\n\ +for \033btool icons\033n in desktop window.\n\ +\033iColumns\033n layouts icons in columns from top\n\ +to bottom, starting a new column when the\n\ +bottom of the window is reached.\n\ +\033iRows\033n layouts icons in rows left to right,\n\ +starting a new row when the right\n\ +window border is reached. +;Select preferred icon layout direction\n\ +;for \033btool icons\033n in desktop window.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +;+++translateme+++ +MSGID_DESKTOPPAGE_LAYOUT_WBPROJECT +Project icons: +;Project icons: +; +;+++translateme+++ +MSGID_DESKTOPPAGE_LAYOUT_WBPROJECT_SHORTHELP +Select preferred icon layout direction\n\ +for \033bproject icons\033n in desktop window.\n\ +\033iColumns\033n layouts icons in columns from top\n\ +to bottom, starting a new column when the\n\ +bottom of the window is reached.\n\ +\033iRows\033n layouts icons in rows left to right,\n\ +starting a new row when the right\n\ +window border is reached. +;Select preferred icon layout direction\n\ +;for \033bproject icons\033n in desktop window.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +;+++translateme+++ +MSGID_DESKTOPPAGE_LAYOUT_WBGARBAGE +Trashcan icons: +;Trashcan icons: +; +;+++translateme+++ +MSGID_DESKTOPPAGE_LAYOUT_WBGARBAGE_SHORTHELP +Select preferred icon layout direction\n\ +for \033btrashcan icons\033n in desktop window.\n\ +\033iColumns\033n layouts icons in columns from top\n\ +to bottom, starting a new column when the\n\ +bottom of the window is reached.\n\ +\033iRows\033n layouts icons in rows left to right,\n\ +starting a new row when the right\n\ +window border is reached. +;Select preferred icon layout direction\n\ +;for \033btrashcan icons\033n in desktop window.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +;+++translateme+++ +MSGID_DESKTOPPAGE_LAYOUT_WBDEVICE +Device icons: +;Device icons: +; +;+++translateme+++ +MSGID_DESKTOPPAGE_LAYOUT_WBDEVICE_SHORTHELP +Select preferred icon layout direction\n\ +for \033bdevice icons\033n in desktop window.\n\ +\033iColumns\033n layouts icons in columns from top\n\ +to bottom, starting a new column when the\n\ +bottom of the window is reached.\n\ +\033iRows\033n layouts icons in rows left to right,\n\ +starting a new row when the right\n\ +window border is reached. +;Select preferred icon layout direction\n\ +;for \033bdevice icons\033n in desktop window.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +;+++translateme+++ +MSGID_DESKTOPPAGE_LAYOUT_WBKICK +Kickstart Disk icons: +;Kickstart Disk icons: +; +;+++translateme+++ +MSGID_DESKTOPPAGE_LAYOUT_WBKICK_SHORTHELP +Select preferred icon layout direction\n\ +for \033bkickstart disk icons\033n in desktop window.\n\ +\033iColumns\033n layouts icons in columns from top\n\ +to bottom, starting a new column when the\n\ +bottom of the window is reached.\n\ +\033iRows\033n layouts icons in rows left to right,\n\ +starting a new row when the right\n\ +window border is reached. +;Select preferred icon layout direction\n\ +;for \033bkickstart disk icons\033n in desktop window.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +;+++translateme+++ +MSGID_DESKTOPPAGE_LAYOUT_WBAPPICON +Application icons: +;Application icons: +; +;+++translateme+++ +MSGID_DESKTOPPAGE_LAYOUT_WBAPPICON_SHORTHELP +Select preferred icon layout direction\n\ +for \033bapplication icons\033n in desktop window.\n\ +\033iColumns\033n layouts icons in columns from top\n\ +to bottom, starting a new column when the\n\ +bottom of the window is reached.\n\ +\033iRows\033n layouts icons in rows left to right,\n\ +starting a new row when the right\n\ +window border is reached. +;Select preferred icon layout direction\n\ +;for \033bapplication icons\033n in desktop window.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_ICONSPAGE_LAYOUTPREFERENCES +Layout Preferences by Icon Type +;Layout Preferences by Icon Type +; +;+++translateme+++ +MSGID_ICONSPAGE_LAYOUT_WBDRAWER +Drawer icons: +;Drawer icons: +; +;+++translateme+++ +MSGID_ICONSPAGE_LAYOUT_WBDRAWER_SHORTHELP +Select preferred icon layout direction\n\ +for \033bdrawer icons\033n in icon windows.\n\ +\033iColumns\033n layouts icons in columns from top\n\ +to bottom, starting a new column when the\n\ +bottom of the window is reached.\n\ +\033iRows\033n layouts icons in rows left to right,\n\ +starting a new row when the right\n\ +window border is reached. +;Select preferred icon layout direction\n\ +;for \033bdrawer icons\033n in icon windows.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +;+++translateme+++ +MSGID_ICONSPAGE_LAYOUT_WBTOOL +Tool icons: +;Tool icons: +; +;+++translateme+++ +MSGID_ICONSPAGE_LAYOUT_WBTOOL_SHORTHELP +Select preferred icon layout direction\n\ +for \033btool icons\033n in icon windows.\n\ +\033iColumns\033n layouts icons in columns from top\n\ +to bottom, starting a new column when the\n\ +bottom of the window is reached.\n\ +\033iRows\033n layouts icons in rows left to right,\n\ +starting a new row when the right\n\ +window border is reached. +;Select preferred icon layout direction\n\ +;for \033btool icons\033n in icon windows.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +;+++translateme+++ +MSGID_ICONSPAGE_LAYOUT_WBPROJECT +Project icons: +;Project icons: +; +;+++translateme+++ +MSGID_ICONSPAGE_LAYOUT_WBPROJECT_SHORTHELP +Select preferred icon layout direction\n\ +for \033bproject icons\033n in icon windows.\n\ +\033iColumns\033n layouts icons in columns from top\n\ +to bottom, starting a new column when the\n\ +bottom of the window is reached.\n\ +\033iRows\033n layouts icons in rows left to right,\n\ +starting a new row when the right\n\ +window border is reached. +;Select preferred icon layout direction\n\ +;for \033bproject icons\033n in icon windows.\n\ +;\033iColumns\033n layouts icons in columns from top\n\ +;to bottom, starting a new column when the\n\ +;bottom of the window is reached.\n\ +;\033iRows\033n layouts icons in rows left to right,\n\ +;starting a new row when the right\n\ +;window border is reached. +; +;----------------------------------------------------------- +; +;+++translateme+++ +MSGID_SCPGADGETTYPE_BACKBUTTON +Back Button +;Back Button +; +;+++translateme+++ +MSGID_SCPGADGETTYPE_FORWARDBUTTON +Forward Button +;Forward Button +; +;+++translateme+++ +MSGID_SCPGADGETTYPE_UPBUTTON +Up Button +;Up Button +; +;+++translateme+++ +MSGID_SCPGADGETTYPE_HISTORY +History Button +;History Button +; +;+++translateme+++ +MSGID_SCPGADGETTYPE_BROWSEBUTTON +Browse Button +;Browse Button +; +;+++translateme+++ +MSGID_SCPGADGETTYPE_VIEWBY +View By Cycle +;View By Cycle +; +; +MSGID_SCPGADGETTYPE_SHOWMODE +Show Mode Cycle +;Show Mode Cycle +; +;+++translateme+++ +MSGID_SCPGADGETTYPE_SEPARATOR +(Separator) +;(Separator) +; +;+++translateme+++ +MSGID_SCPGADGETTYPE_ACTIONBUTTON +User-defined Button +;User-defined Button +; +;+++translateme+++ +MSGID_SCPGADGETTYPE_UNKNOWN +??unknown?? +;??unknown?? +; +;----------------------------------------------------------- +; +:+++translateme+++ +MSGID_COM1NAME +Backdrop +; +;+++translateme+++ +MSGID_COM2NAME +Execute Command +; +;+++translateme+++ +MSGID_COM3NAME +Redraw All +; +;+++translateme+++ +MSGID_COM4NAME +Update All +; +;+++translateme+++ +MSGID_COM5NAME +About Scalos +; +;+++translateme+++ +MSGID_COM6NAME +Quit +; +;+++translateme+++ +MSGID_COM7NAME +New Drawer +; +;+++translateme+++ +MSGID_COM8NAME +Open Parent +; +;+++translateme+++ +MSGID_COM9NAME +Close Window +; +;+++translateme+++ +MSGID_COM10NAME +Update +; +;+++translateme+++ +MSGID_COM11NAME +Select Contents +; +;+++translateme+++ +MSGID_COM12NAME +Cleanup +; +;+++translateme+++ +MSGID_COM13NAME +Snapshot - Window +; +;+++translateme+++ +MSGID_COM14NAME +Snapshot - All +; +;+++translateme+++ +MSGID_COM15NAME +Show - Only Icons +; +;+++translateme+++ +MSGID_COM16NAME +Show - All Files +; +;+++translateme+++ +MSGID_COM17NAME +View By - Icon +; +;+++translateme+++ +MSGID_COM18NAME +View By - Text +; +;+++translateme+++ +MSGID_COM19NAME +Open +; +;+++translateme+++ +MSGID_COM20NAME +Reset Scalos +; +;+++translateme+++ +MSGID_COM21NAME +Rename +; +;+++translateme+++ +MSGID_COM22NAME +Information +; +;+++translateme+++ +MSGID_COM23NAME +Snapshot +; +;+++translateme+++ +MSGID_COM24NAME +UnSnapshot +; +;+++translateme+++ +MSGID_COM25NAME +Leave Out +; +;+++translateme+++ +MSGID_COM26NAME +Put Away +; +;+++translateme+++ +MSGID_COM27NAME +Delete +; +;+++translateme+++ +MSGID_COM28NAME +Clone +; +;+++translateme+++ +MSGID_COM29NAME +Empty Trashcan +; +;+++translateme+++ +MSGID_COM30NAME +Last Message +; +;+++translateme+++ +MSGID_COM31NAME +Redraw +; +;+++translateme+++ +MSGID_COM32NAME +Iconify +; +;+++translateme+++ +MSGID_COM33NAME +Format Disk... +; +;+++translateme+++ +MSGID_COM34NAME +Shutdown... +; +;+++translateme+++ +MSGID_COM35NAME +Size To Fit +; +;+++translateme+++ +MSGID_COM36NAME +Clear Selection +; +;+++translateme+++ +MSGID_COM37NAME +View By - Size +; +;+++translateme+++ +MSGID_COM38NAME +View By - Date +; +;+++translateme+++ +MSGID_COM39NAME +Copy file +; +;+++translateme+++ +MSGID_COM40NAME +Cut file +; +;+++translateme+++ +MSGID_COM41NAME +Paste file +; +;+++translateme+++ +MSGID_COM42NAME +View By - Type +; +;+++translateme+++ +MSGID_COM43NAME +Cleanup By - Name +; +;+++translateme+++ +MSGID_COM44NAME +Cleanup By - Date +; +;+++translateme+++ +MSGID_COM45NAME +Cleanup By - Size +; +;+++translateme+++ +MSGID_COM46NAME +Cleanup By - Type +; +;+++translateme+++ +MSGID_COM_ICONPROPERTIES +Icon properties +; +;+++translateme+++ +MSGID_COM_WINDOWPROPERTIES +Window properties +; +;+++translateme+++ +MSGID_COM47NAME +View By - Default +; +;+++translateme+++ +MSGID_COM48NAME +Show - Default +; +;+++translateme+++ +MSGID_COM49NAME +Copy to... +;Copy to... +; +;+++translateme+++ +MSGID_COM50NAME +Move to... +;Move to... +; +;+++translateme+++ +MSGID_COM51NAME +Create thumbnail +;Create thumbnail +; +;+++translateme+++ +MSGID_COM_OPENNEWWINDOW +Open in new window +;Open in new window +; +;+++translateme+++ +MSGID_COM_THUMBNAILCACHECLEANUP +Cleanup thumbnail cache +;Cleanup thumbnail cache +; +;----------------------------------------------------------- +; diff --git a/scalos/Prefs/MainPrefs/General.h b/scalos/Prefs/MainPrefs/General.h new file mode 100644 index 000000000..472a5f5b5 --- /dev/null +++ b/scalos/Prefs/MainPrefs/General.h @@ -0,0 +1,18 @@ +// General.h +// $Date$ +// $Revision$ + +#ifndef GENERAL_H +#define GENERAL_H + +#ifndef EXEC_TYPES_H +#include +#endif + +#define PROGRAM "Scalos - Preferences" +#define VERSION_MAJOR 40 +#define VERSION_MINOR 28 +#define AUTHOR "ßudda " +#define VERSION STR(VERSION_MAJOR) "." STR(VERSION_MINOR) + +#endif diff --git a/scalos/Prefs/MainPrefs/HiddenDevices.c b/scalos/Prefs/MainPrefs/HiddenDevices.c new file mode 100644 index 000000000..acc2378c4 --- /dev/null +++ b/scalos/Prefs/MainPrefs/HiddenDevices.c @@ -0,0 +1,785 @@ +// HiddenDevices.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include +#include +#include +#include +#define NO_INLINE_STDARG +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "HiddenDevices.h" +#include "ScalosPrefs.h" + +//----------------------------------------------------------------- + +struct HiddenDevice + { + struct Node hd_Node; + char hd_Name[1]; // variable length + }; + +struct UnknownPrefsChunk + { + struct Node upc_Node; + LONG upc_ID; + LONG upc_Type; + LONG upc_Size; + UBYTE upc_Data[1]; // variable length + }; + +//----------------------------------------------------------------- + +static void HandleWBHD(const UBYTE *data, size_t length); +static LONG CollectUnknownPrefsChunks(struct List *ChunksList, CONST_STRPTR Filename); +static LONG AddUnknownChunk(struct List *ChunksList, struct IFFHandle *iff, const struct ContextNode *cn); +static void CleanupUnknownChunks(struct List *ChunksList); +static void AddHiddenDeviceFromDosList(struct SCAModule *app, struct DosList *dl, struct InfoData *id, BOOL Hidden); +static void BtoCString(BPTR bstring, STRPTR Buffer, size_t Length); +static BOOL FindHiddenDevice(CONST_STRPTR Name); +static void StripTrailingColon(STRPTR Line); + +//----------------------------------------------------------------- + +static struct List HiddenDevicesList; + +//----------------------------------------------------------------- + +BOOL HiddenDevicesInit(void) +{ + NewList(&HiddenDevicesList); + + return TRUE; +} + +//----------------------------------------------------------------- + +void HiddenDevicesCleanup(void) +{ + struct HiddenDevice *hd; + + while ((hd = (struct HiddenDevice *) RemHead(&HiddenDevicesList))) + { + free(hd); + } +} + +//----------------------------------------------------------------- + +// Read workbench.prefs and build list of hidden devices +BOOL ReadWorkbenchPrefs(CONST_STRPTR filename) +{ + struct IFFHandle *iff; + LONG error; + BOOL IffOpened = FALSE; + static const ULONG pairs[] = {ID_PREF, ID_PREF, ID_WBHD}; + + HiddenDevicesCleanup(); + + d1(KPrintF(__FILE__ "/%s/%ld: filename=<%s>\n", __FUNC__, __LINE__, filename)); + + do { + iff = AllocIFF(); + if (NULL == iff) + break; + + iff->iff_Stream = (ULONG) Open((STRPTR) filename, MODE_OLDFILE); + d1(KPrintF(__FILE__ "/%s/%ld: iff_Stream=%08lx\n", __FUNC__, __LINE__, iff->iff_Stream)); + if (0 == iff->iff_Stream) + break; + + InitIFFasDOS( iff ); + + error = OpenIFF( iff, IFFF_READ ); + if (RETURN_OK != error) + break; + + IffOpened = TRUE; + + error = CollectionChunks( iff, (LONG*) pairs, Sizeof(pairs) / 2); + if (RETURN_OK != error) + break; + + StopOnExit( iff, ID_PREF, ID_FORM ); + + while(TRUE) + { + if( ( error = ParseIFF( iff, IFFPARSE_SCAN ) ) == IFFERR_EOC ) + { + struct CollectionItem *ci; + + ci = FindCollection( iff, ID_PREF, ID_WBHD); + while( ci ) + { + HandleWBHD(ci->ci_Data, ci->ci_Size); + ci = ci->ci_Next; + } + + } + else + break; + } + } while (0); + + if (iff) + { + if (IffOpened) + CloseIFF( iff ); + if (iff->iff_Stream) + Close( (BPTR)iff->iff_Stream ); + FreeIFF( iff ); + } + + return TRUE; +} + +//----------------------------------------------------------------- + +static void HandleWBHD(const UBYTE *data, size_t length) +{ + d1(KPrintF(__FILE__ "/%s/%ld: data=<%s> length=%lu\n", __FUNC__, __LINE__, data, length)); + + if (!FindHiddenDevice((STRPTR)data)) // make sure we get no cuplicate entries + AddHiddenDevice((STRPTR)data); +} + +//----------------------------------------------------------------- + +// save workbench.prefs, including WBHD entries for each hidden device +LONG WriteWorkbenchPrefs(CONST_STRPTR Filename) +{ + struct IFFHandle *iff = NULL; + LONG Result; + BOOL IffOpen = FALSE; + struct List ChunksList; + + NewList(&ChunksList); + + do { + static const struct PrefHeader prefHeader = { 0, 0, 0L }; + struct HiddenDevice *hd; + struct UnknownPrefsChunk *upc; + + d1(KPrintF(__FILE__ "/%s/%ld: Filename=<%s>\n", __FUNC__, __LINE__, Filename)); + + Result = CollectUnknownPrefsChunks(&ChunksList, Filename); + d1(KPrintF(__FILE__ "/%s/%ld: Result=%ld\n", __FUNC__, __LINE__, Result)); + if (RETURN_OK != Result) + break; + + iff = AllocIFF(); + if (NULL == iff) + { + Result = IoErr(); + break; + } + + InitIFFasDOS(iff); + + iff->iff_Stream = (IPTR)Open(Filename, MODE_NEWFILE); + if (0 == iff->iff_Stream) + { + // ... try to create missing directories here + STRPTR FilenameCopy; + + Result = IoErr(); + d1(KPrintF(__FILE__ "/%s/%ld: Result=%ld\n", __FUNC__, __LINE__, Result)); + + FilenameCopy = AllocVec(1 + strlen(Filename), MEMF_PUBLIC); + + if (FilenameCopy) + { + STRPTR lp; + + strcpy(FilenameCopy, Filename); + + lp = PathPart(FilenameCopy); + if (lp) + { + BPTR dirLock; + + *lp = '\0'; + dirLock = CreateDir(FilenameCopy); + + if (dirLock) + UnLock(dirLock); + + iff->iff_Stream = (IPTR)Open(Filename, MODE_NEWFILE); + if (0 == iff->iff_Stream) + Result = IoErr(); + else + Result = RETURN_OK; + } + + FreeVec(FilenameCopy); + } + + d1(KPrintF(__FILE__ "/%s/%ld: Result=%ld\n", __FUNC__, __LINE__, Result)); + if (RETURN_OK != Result) + break; + } + + d1(KPrintF(__FILE__ "/%s/%ld: Result=%ld\n", __FUNC__, __LINE__, Result)); + + Result = OpenIFF(iff, IFFF_WRITE); + if (RETURN_OK != Result) + break; + + IffOpen = TRUE; + d1(KPrintF(__FILE__ "/%s/%ld: Result=%ld\n", __FUNC__, __LINE__, Result)); + + Result = PushChunk(iff, ID_PREF, ID_FORM, IFFSIZE_UNKNOWN); + if (RETURN_OK != Result) + break; + + Result = PushChunk(iff, 0, ID_PRHD, IFFSIZE_UNKNOWN); + if (RETURN_OK != Result) + break; + + if (WriteChunkBytes(iff, (APTR) &prefHeader, sizeof(prefHeader)) < 0) + { + Result = IoErr(); + break; + } + + Result = PopChunk(iff); // PRHD + if (RETURN_OK != Result) + break; + + d1(KPrintF(__FILE__ "/%s/%ld: Result=%ld\n", __FUNC__, __LINE__, Result)); + + for (hd = (struct HiddenDevice *) HiddenDevicesList.lh_Head; + hd != (struct HiddenDevice *) &HiddenDevicesList.lh_Tail; + hd = (struct HiddenDevice *) hd->hd_Node.ln_Succ) + { + size_t wbhdLength = 1 + strlen(hd->hd_Name); + + d1(KPrintF(__FILE__ "/%s/%ld: hd_Name=<%s>\n", __FUNC__, __LINE__, hd->hd_Name)); + + Result = PushChunk(iff, 0, ID_WBHD, IFFSIZE_UNKNOWN); + if (RETURN_OK != Result) + break; + + if (wbhdLength != WriteChunkBytes(iff, (APTR) hd->hd_Name, wbhdLength)) + { + Result = IoErr(); + break; + } + if (wbhdLength & 0x01) + { + // write dummy byte to get even chunk length + ULONG Dummy = 0; + + if (1 != WriteChunkBytes(iff, (APTR) &Dummy, 1)) + { + Result = IoErr(); + break; + } + } + + Result = PopChunk(iff); // WBHD + if (RETURN_OK != Result) + break; + } + + d1(KPrintF(__FILE__ "/%s/%ld: Result=%ld\n", __FUNC__, __LINE__, Result)); + + if (RETURN_OK != Result) + break; + + for (upc = (struct UnknownPrefsChunk *) ChunksList.lh_Head; + upc != (struct UnknownPrefsChunk *) &ChunksList.lh_Tail; + upc = (struct UnknownPrefsChunk *) upc->upc_Node.ln_Succ ) + { + d1(KPrintF("%s/%s/%ld: Write Chunk Type=%08lx, ID=%08lx Length=%lu\n", __FILE__, __FUNC__, __LINE__, \ + upc->upc_Type, upc->upc_ID, upc->upc_Size)); + + Result = PushChunk(iff, 0, upc->upc_ID, IFFSIZE_UNKNOWN); + if (RETURN_OK != Result) + break; + + if (upc->upc_Size != WriteChunkBytes(iff, (APTR) upc->upc_Data, upc->upc_Size)) + { + Result = IoErr(); + break; + } + + Result = PopChunk(iff); // upc->upc_ID + if (RETURN_OK != Result) + break; + } + + Result = PopChunk(iff); // FORM + if (RETURN_OK != Result) + break; + + } while (0); + + CleanupUnknownChunks(&ChunksList); + + if (iff) + { + if (IffOpen) + CloseIFF(iff); + + if (iff->iff_Stream) + { + Close((BPTR)iff->iff_Stream); + iff->iff_Stream = 0; + } + + FreeIFF(iff); + } + + d1(KPrintF(__FILE__ "/%s/%ld: Result=%ld\n", __FUNC__, __LINE__, Result)); + + if (RETURN_OK == Result && fCreateIcons) + SaveIcon(Filename); + + return Result; +} + +//----------------------------------------------------------------- + +static LONG CollectUnknownPrefsChunks(struct List *ChunksList, CONST_STRPTR Filename) +{ + LONG Result; + struct IFFHandle *iff; + BOOL iffOpened = FALSE; + + d1(KPrintF(__FILE__ "/%s/%ld: Filename=<%s>\n", __FUNC__, __LINE__, Filename)); + + do { + iff = AllocIFF(); + if (NULL == iff) + { + Result = IoErr(); + break; + } + + InitIFFasDOS(iff); + + iff->iff_Stream = (IPTR)Open(Filename, MODE_OLDFILE); + if (0 == iff->iff_Stream) + { + Result = IoErr(); + break; + } + + Result = OpenIFF(iff, IFFF_READ); + if (RETURN_OK != Result) + break; + + iffOpened = TRUE; + + while (RETURN_OK == Result) + { + struct ContextNode *cn; + + Result = ParseIFF(iff, IFFPARSE_RAWSTEP); + d1(KPrintF(__FILE__ "/%s/%ld: Result=%ld\n", __FUNC__, __LINE__, Result)); + if (IFFERR_EOC == Result) + { + Result = RETURN_OK; + continue; + } + if (IFFERR_EOF == Result) + { + Result = RETURN_OK; + break; + } + if (RETURN_OK != Result) + break; + + cn = CurrentChunk(iff); + if (NULL == cn) + continue; + + switch (cn->cn_ID) + { + case ID_FORM: + d1(KPrintF(__FILE__ "/%s/%ld: ID_FORM Size=%ld\n", __FUNC__, __LINE__, cn->cn_Size)); + break; + case ID_PREF: + d1(KPrintF(__FILE__ "/%s/%ld: ID_PREF Size=%ld\n", __FUNC__, __LINE__, cn->cn_Size)); + break; + case ID_PRHD: + d1(KPrintF(__FILE__ "/%s/%ld: ID_PRHD Size=%ld\n", __FUNC__, __LINE__, cn->cn_Size)); + break; + default: + d1(KPrintF("%s/%s/%ld: Found Chunk Type=%08lx, ID=%08lx Length=%lu\n", __FILE__, __FUNC__, __LINE__, \ + cn->cn_Type, cn->cn_ID, cn->cn_Size)); + Result = AddUnknownChunk(ChunksList, iff, cn); + break; + } + } + } while (0); + + if (iff) + { + if (iffOpened) + CloseIFF(iff); + + if (iff->iff_Stream) + Close((BPTR)iff->iff_Stream); + + FreeIFF(iff); + } + + return Result; +} + +//----------------------------------------------------------------- + +static LONG AddUnknownChunk(struct List *ChunksList, struct IFFHandle *iff, const struct ContextNode *cn) +{ + struct UnknownPrefsChunk *upc; + LONG Result = RETURN_OK; + + do { + LONG Length; + + upc = malloc(sizeof(struct UnknownPrefsChunk) + cn->cn_Size); + if (NULL == upc) + { + Result = ERROR_NO_FREE_STORE; + break; + } + + upc->upc_ID = cn->cn_ID; + upc->upc_Type = cn->cn_Type; + upc->upc_Size = cn->cn_Size; + + Length = ReadChunkBytes(iff, upc->upc_Data, upc->upc_Size); + if (Length != upc->upc_Size) + { + Result = IoErr(); + break; + } + + AddTail(ChunksList, &upc->upc_Node); + upc = NULL; + } while (0); + + if (upc) + { + free(upc); + } + + d1(KPrintF(__FILE__ "/%s/%ld: Result=%ld\n", __FUNC__, __LINE__, Result)); + + return Result; +} + +//----------------------------------------------------------------- + +static void CleanupUnknownChunks(struct List *ChunksList) +{ + struct UnknownPrefsChunk *upc; + + while ((upc = (struct UnknownPrefsChunk *) RemTail(ChunksList))) + { + free(upc); + } +} + +//----------------------------------------------------------------- + +// Traverse DosList for all devices, and build list of hideable devices +void FillHiddenDevicesList(struct SCAModule *app) +{ + ULONG LockDosListFlags = LDF_DEVICES | LDF_READ; + struct HiddenDevice *hd; + struct DosList *dl; + struct InfoData *id; + + set(app->Obj[NLIST_HIDDENDEVICES], MUIA_NList_Quiet, TRUE); + DoMethod(app->Obj[NLIST_HIDDENDEVICES], MUIM_NList_Clear); + DoMethod(app->Obj[NLIST_HIDDENDEVICES], MUIM_NList_UseImage, + NULL, MUIV_NList_UseImage_All, 0); + + id = malloc(sizeof(struct InfoData)); + if (id) + { + dl = LockDosList(LockDosListFlags); + + while (dl = NextDosEntry(dl, LockDosListFlags)) + { + AddHiddenDeviceFromDosList(app, dl, id, FALSE); + } + + UnLockDosList(LockDosListFlags); + free(id); + } + + // Now walk through the list of devices marked as hidden, + // and add all entries. + + dl = LockDosList(LockDosListFlags); + + for (hd = (struct HiddenDevice *) HiddenDevicesList.lh_Head; + hd != (struct HiddenDevice *) &HiddenDevicesList.lh_Tail; + hd = (struct HiddenDevice *) hd->hd_Node.ln_Succ) + { + char HiddenDevName[128]; + struct DosList *dlFound; + + // Name must not have trailing ":" to use with FindDosEntry() + stccpy(HiddenDevName, hd->hd_Name, sizeof(HiddenDevName)); + StripTrailingColon(HiddenDevName); + d1(KPrintF(__FILE__ "/%s/%ld: HiddenDevName=<%s>\n", __FUNC__, __LINE__, HiddenDevName)); + + dlFound = FindDosEntry(dl, HiddenDevName, LockDosListFlags); + d1(KPrintF(__FILE__ "/%s/%ld: dl=%08lx\n", __FUNC__, __LINE__, dlFound)); + if (dlFound) + { + AddHiddenDeviceFromDosList(app, dlFound, id, TRUE); + } + else + { + struct NewHiddenDevice nhd; + + nhd.nhd_DeviceName = hd->hd_Name; + nhd.nhd_VolumeName = ""; + nhd.nhd_Hidden = TRUE; + + d1(KPrintF(__FILE__ "/%s/%ld: DevName=<%s> VolName=<%s>\n", \ + __FUNC__, __LINE__, nhd.nhd_DeviceName, nhd.nhd_VolumeName)); + + DoMethod(app->Obj[NLIST_HIDDENDEVICES], + MUIM_NList_InsertSingle, + &nhd, + MUIV_NList_Insert_Sorted); + } + } + + UnLockDosList(LockDosListFlags); + + set(app->Obj[NLIST_HIDDENDEVICES], MUIA_NList_Quiet, FALSE); +} + +//----------------------------------------------------------------- + +static void AddHiddenDeviceFromDosList(struct SCAModule *app, struct DosList *dl, struct InfoData *id, BOOL Hidden) +{ + char DevName[128]; + char VolName[128]; + struct DosList *VolumeNode; + BOOL InfoDataValid = FALSE; + + strcpy(VolName, ""); + BtoCString(dl->dol_Name, DevName, sizeof(DevName)); + + d1(KPrintF(__FILE__ "/%s/%ld: START DevName=<%s>\n", __FUNC__, __LINE__, DevName)); + +#if defined(__amigaos4__) + if (0 != Stricmp(DevName, "ENV")) +#endif //!defined(__amigaos4__) + { + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + if (dl->dol_Task && + DoPkt(dl->dol_Task, ACTION_DISK_INFO, + (IPTR)MKBADDR(id), + 0, 0, 0, 0)) + { + InfoDataValid = TRUE; + } + d1(KPrintF(__FILE__ "/%s/%ld: InfoDataValid=%ld\n", __FUNC__, __LINE__, InfoDataValid)); + } + + if (!Hidden && !InfoDataValid) + return; + + if (InfoDataValid) + { + switch (id->id_DiskState) + { + case ID_WRITE_PROTECTED: + case ID_VALIDATING: + case ID_VALIDATED: + VolumeNode = BADDR(id->id_VolumeNode); + if (VolumeNode) + { + BtoCString(VolumeNode->dol_Name, VolName, sizeof(VolName)); + StripTrailingColon(VolName); + strcat(VolName, ":"); + } + break; + default: + break; + } + } + + StripTrailingColon(DevName); + strcat(DevName, ":"); + + // add only visible devices here + if (Hidden || !FindHiddenDevice(DevName)) + { + struct NewHiddenDevice nhd; + + nhd.nhd_DeviceName = DevName; + nhd.nhd_VolumeName = VolName; + nhd.nhd_Hidden = Hidden; + + d1(KPrintF(__FILE__ "/%s/%ld: DevName=<%s> VolName=<%s>\n", \ + __FUNC__, __LINE__, nhd.nhd_DeviceName, nhd.nhd_VolumeName)); + + DoMethod(app->Obj[NLIST_HIDDENDEVICES], + MUIM_NList_InsertSingle, + &nhd, + MUIV_NList_Insert_Sorted); + } +} + +//----------------------------------------------------------------- + +static void BtoCString(BPTR bstring, STRPTR Buffer, size_t Length) +{ +#ifdef __AROS__ + // AROS needs special handling because it uses NULL-terminated + // strings on some platforms. + size_t Len = AROS_BSTR_strlen(bstring); + if (Len >= Length) + Len = Length - 1; + strncpy(Buffer, AROS_BSTR_ADDR(bstring), Len); + Buffer[Len] = '\0'; +#else + CONST_STRPTR Src = BADDR(bstring); + size_t bLength; + + // get BSTRING length (1st octet) + bLength = *Src++; + + while (bLength-- && (Length-- > 1)) + *Buffer++ = *Src++; + + *Buffer = '\0'; +#endif +} + +//----------------------------------------------------------------- + +// Add entry to hidden devices list +BOOL AddHiddenDevice(CONST_STRPTR Name) +{ + struct HiddenDevice *hd; + BOOL Success = FALSE; + + hd = malloc(sizeof(struct HiddenDevice) + 1 + strlen(Name)); + if (hd) + { + strcpy(hd->hd_Name, Name); + + // make sure device name is terminated with exactly one ":" + StripTrailingColon(hd->hd_Name); + strcat(hd->hd_Name, ":"); + + AddHead(&HiddenDevicesList, &hd->hd_Node); + Success = TRUE; + } + + d1(KPrintF(__FILE__ "/%s/%ld: Name=<%s> hd=%08lx\n", __FUNC__, __LINE__, Name, hd)); + + return Success; +} + +//----------------------------------------------------------------- + +// Remove entry from hidden devices list +BOOL RemoveHiddenDevice(CONST_STRPTR Name) +{ + struct HiddenDevice *hd; + BOOL Found = FALSE; + + d1(KPrintF(__FILE__ "/%s/%ld: Name=<%s>", __FUNC__, __LINE__, Name)); + + for (hd = (struct HiddenDevice *) HiddenDevicesList.lh_Head; + hd != (struct HiddenDevice *) &HiddenDevicesList.lh_Tail; + hd = (struct HiddenDevice *) hd->hd_Node.ln_Succ) + { + if (0 == Stricmp(Name, hd->hd_Name)) + { + Found = TRUE; + Remove(&hd->hd_Node); + free(hd); + break; + } + } + + return Found; +} + +//----------------------------------------------------------------- + +// search for entry in hidden devices list +static BOOL FindHiddenDevice(CONST_STRPTR Name) +{ + const struct HiddenDevice *hd; + BOOL Found = FALSE; + + d1(KPrintF(__FILE__ "/%s/%ld: Name=<%s>", __FUNC__, __LINE__, Name)); + + for (hd = (struct HiddenDevice *) HiddenDevicesList.lh_Head; + hd != (struct HiddenDevice *) &HiddenDevicesList.lh_Tail; + hd = (struct HiddenDevice *) hd->hd_Node.ln_Succ) + { + if (0 == Stricmp(Name, hd->hd_Name)) + { + Found = TRUE; + break; + } + } + + return Found; +} + +//----------------------------------------------------------------- + +static void StripTrailingColon(STRPTR Line) +{ + size_t Len = strlen(Line); + + Line += Len - 1; + + if (':' == *Line) + *Line = '\0'; +} + +//----------------------------------------------------------------- + diff --git a/scalos/Prefs/MainPrefs/HiddenDevices.h b/scalos/Prefs/MainPrefs/HiddenDevices.h new file mode 100644 index 000000000..4e13dc28a --- /dev/null +++ b/scalos/Prefs/MainPrefs/HiddenDevices.h @@ -0,0 +1,29 @@ +// HiddenDevices.h +// $Date$ +// $Revision$ + + +#ifndef HIDDENDEVICES_H +#define HIDDENDEVICES_H + +//----------------------------------------------------------------- + +#include "ScalosPrefs.h" + +//----------------------------------------------------------------- + +BOOL HiddenDevicesInit(void); +void HiddenDevicesCleanup(void); +void FillHiddenDevicesList(struct SCAModule *app); +BOOL ReadWorkbenchPrefs(CONST_STRPTR filename); +LONG WriteWorkbenchPrefs(CONST_STRPTR filename); +BOOL AddHiddenDevice(CONST_STRPTR Name); +BOOL RemoveHiddenDevice(CONST_STRPTR Name); + +//----------------------------------------------------------------- + +#define getv(o,a) mui_getv(o,a) + +//----------------------------------------------------------------- + +#endif /* HIDDENDEVICES_H */ diff --git a/scalos/Prefs/MainPrefs/Hooks.c b/scalos/Prefs/MainPrefs/Hooks.c new file mode 100644 index 000000000..791becf08 --- /dev/null +++ b/scalos/Prefs/MainPrefs/Hooks.c @@ -0,0 +1,1529 @@ +// Hooks.c +// $Date$ +// $Revision$ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __amigaos4__ +#include +#endif + +#define __USE_SYSBASE + +#include +#include +#include +#include +#define USE_INLINE_STDARG +#include +#undef USE_INLINE_STDARG +#define NO_INLINE_STDARG +#include + +#include + +#include +#include // +jmc+ + +#include "General.h" +#include "ScalosPrefs.h" +#include "ReadWritePrefs.h" +#include "HiddenDevices.h" +#include "PrefsPlugins.h" +#include "FontSampleMCC.h" +#include +#include +#include "McpFrameMCC.h" +#include "DataTypesMCC.h" +#include "SelectMarkSampleClass.h" +#include "Hooks.h" +#include "locale.h" + +//----------------------------------------------------------------- + +static SAVEDS(LONG) INTERRUPT AddPluginAslFilterHookFunc(struct Hook *hook, Object *o, Msg msg); +static void BuildTTDescFromAttrList(char *buffer, size_t length, struct TagItem *AttrList); +static BOOL ParseTTFontFromDesc(CONST_STRPTR FontDesc, + ULONG *FontStyle, ULONG *FontWeight, ULONG *FontSize, + STRPTR FontName, size_t FontNameSize); +static LONG TTFontHeightFromDesc(CONST_STRPTR FontDesc); +static LONG DiskFontHeightFromDesc(CONST_STRPTR FontDesc); + +//----------------------------------------------------------------- + +static struct Hook AddPluginAslFilterHook = { { NULL, NULL }, HOOKFUNC_DEF(AddPluginAslFilterHookFunc), NULL }; + +//----------------------------------------------------------------- + +SAVEDS(void) INTERRUPT StartFontPrefs_Func(struct Hook *hook, Object *pPrefsWindow, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + + set(pPrefsWindow, MUIA_Window_Sleep, TRUE); + Execute(SYS_FONTPREFS_NAME, 0, 0); + + // Update (possibly changed) icon text + ReadIconFontPrefs(app); + + set(pPrefsWindow, MUIA_Window_Sleep, FALSE); +} + +//----------------------------------------------------------------- + +SAVEDS(void) INTERRUPT StartWorkbenchPrefs_Func(struct Hook *hook, Object *pPrefsWindow, Msg msg) +{ + set(pPrefsWindow, MUIA_Window_Sleep, TRUE); + Execute(SYS_WORKBENCHPREFS_NAME, 0, 0); + set(pPrefsWindow, MUIA_Window_Sleep, FALSE); +} + +//----------------------------------------------------------------- + +SAVEDS(void) INTERRUPT CheckPopTitleBarBox(struct Hook *hook, Object *pPrefsWindow, Msg msg) +{ +} + +//----------------------------------------------------------------- + +SAVEDS(void) INTERRUPT ControlBarGadgetListBrowserActiveHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + struct ControlBarGadgetEntry *cgy = NULL; + + DoMethod(app->Obj[NLIST_CONTROLBARGADGETS_BROWSER_ACTIVE], MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &cgy); + + if (cgy && SCPGadgetType_ActionButton == cgy->cgy_GadgetType) + { + set(app->Obj[STRING_CONTROLBARGADGETS_BROWSER_NORMALIMAGE], MUIA_Disabled, FALSE); + set(app->Obj[STRING_CONTROLBARGADGETS_BROWSER_SELECTEDIMAGE], MUIA_Disabled, FALSE); + set(app->Obj[STRING_CONTROLBARGADGETS_BROWSER_DISABLEDIMAGE], MUIA_Disabled, FALSE); + set(app->Obj[STRING_CONTROLBARGADGETS_BROWSER_ACTION], MUIA_Disabled, FALSE); + set(app->Obj[TEXTEDITOR_CONTROLBARGADGETS_BROWSER_HELPTEXT], MUIA_Disabled, FALSE); + set(app->Obj[POP_CONTROLBARGADGETS_BROWSER_ACTION], MUIA_Disabled, FALSE); + + // use nnset() here since notification would cause remaining strings to be set to + // empty value when first string is changed here. + nnset(app->Obj[STRING_CONTROLBARGADGETS_BROWSER_NORMALIMAGE], MUIA_String_Contents, + cgy->cgy_NormalImage ? cgy->cgy_NormalImage : (STRPTR) ""); + nnset(app->Obj[STRING_CONTROLBARGADGETS_BROWSER_SELECTEDIMAGE], MUIA_String_Contents, + cgy->cgy_SelectedImage ? cgy->cgy_SelectedImage : (STRPTR) ""); + nnset(app->Obj[STRING_CONTROLBARGADGETS_BROWSER_DISABLEDIMAGE], MUIA_String_Contents, + cgy->cgy_DisabledImage ? cgy->cgy_DisabledImage : (STRPTR) ""); + nnset(app->Obj[TEXTEDITOR_CONTROLBARGADGETS_BROWSER_HELPTEXT], MUIA_TextEditor_Contents, cgy->cgy_HelpText); + nnset(app->Obj[STRING_CONTROLBARGADGETS_BROWSER_ACTION], MUIA_String_Contents, cgy->cgy_Action); + } + else + { + set(app->Obj[STRING_CONTROLBARGADGETS_BROWSER_NORMALIMAGE], MUIA_Disabled, TRUE); + set(app->Obj[STRING_CONTROLBARGADGETS_BROWSER_SELECTEDIMAGE], MUIA_Disabled, TRUE); + set(app->Obj[STRING_CONTROLBARGADGETS_BROWSER_DISABLEDIMAGE], MUIA_Disabled, TRUE); + set(app->Obj[STRING_CONTROLBARGADGETS_BROWSER_ACTION], MUIA_Disabled, TRUE); + set(app->Obj[TEXTEDITOR_CONTROLBARGADGETS_BROWSER_HELPTEXT], MUIA_Disabled, TRUE); + set(app->Obj[POP_CONTROLBARGADGETS_BROWSER_ACTION], MUIA_Disabled, TRUE); + + nnset(app->Obj[STRING_CONTROLBARGADGETS_BROWSER_NORMALIMAGE], MUIA_String_Contents, ""); + nnset(app->Obj[STRING_CONTROLBARGADGETS_BROWSER_SELECTEDIMAGE], MUIA_String_Contents, ""); + nnset(app->Obj[STRING_CONTROLBARGADGETS_BROWSER_DISABLEDIMAGE], MUIA_String_Contents, ""); + nnset(app->Obj[TEXTEDITOR_CONTROLBARGADGETS_BROWSER_HELPTEXT], MUIA_TextEditor_Contents, ""); + nnset(app->Obj[STRING_CONTROLBARGADGETS_BROWSER_ACTION], MUIA_String_Contents, ""); + } + + set(app->Obj[DTIMG_CONTROLBARGADGETS_BROWSER_NORMALIMAGE], MUIA_ScaDtpic_Name, + cgy->cgy_NormalImage ? cgy->cgy_NormalImage : (STRPTR) ""); + set(app->Obj[DTIMG_CONTROLBARGADGETS_BROWSER_SELECTEDIMAGE], MUIA_ScaDtpic_Name, + cgy->cgy_SelectedImage ? cgy->cgy_SelectedImage : (STRPTR) ""); + set(app->Obj[DTIMG_CONTROLBARGADGETS_BROWSER_DISABLEDIMAGE], MUIA_ScaDtpic_Name, + cgy->cgy_DisabledImage ? cgy->cgy_DisabledImage : (STRPTR) ""); +} + +//----------------------------------------------------------------- + +SAVEDS(void) INTERRUPT ControlBarGadgetListNormalActiveHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + struct ControlBarGadgetEntry *cgy = NULL; + + DoMethod(app->Obj[NLIST_CONTROLBARGADGETS_NORMAL_ACTIVE], MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &cgy); + + if (cgy && SCPGadgetType_ActionButton == cgy->cgy_GadgetType) + { + set(app->Obj[STRING_CONTROLBARGADGETS_NORMAL_NORMALIMAGE], MUIA_Disabled, FALSE); + set(app->Obj[STRING_CONTROLBARGADGETS_NORMAL_SELECTEDIMAGE], MUIA_Disabled, FALSE); + set(app->Obj[STRING_CONTROLBARGADGETS_NORMAL_DISABLEDIMAGE], MUIA_Disabled, FALSE); + set(app->Obj[STRING_CONTROLBARGADGETS_NORMAL_ACTION], MUIA_Disabled, FALSE); + set(app->Obj[TEXTEDITOR_CONTROLBARGADGETS_NORMAL_HELPTEXT], MUIA_Disabled, FALSE); + set(app->Obj[POP_CONTROLBARGADGETS_NORMAL_ACTION], MUIA_Disabled, FALSE); + + // use nnset() here since notification would cause remaining strings to be set to + // empty value when first string is changed here. + nnset(app->Obj[STRING_CONTROLBARGADGETS_NORMAL_NORMALIMAGE], MUIA_String_Contents, + cgy->cgy_NormalImage ? cgy->cgy_NormalImage : (STRPTR) ""); + nnset(app->Obj[STRING_CONTROLBARGADGETS_NORMAL_SELECTEDIMAGE], MUIA_String_Contents, + cgy->cgy_SelectedImage ? cgy->cgy_SelectedImage : (STRPTR) ""); + nnset(app->Obj[STRING_CONTROLBARGADGETS_NORMAL_DISABLEDIMAGE], MUIA_String_Contents, + cgy->cgy_DisabledImage ? cgy->cgy_DisabledImage : (STRPTR) ""); + nnset(app->Obj[TEXTEDITOR_CONTROLBARGADGETS_NORMAL_HELPTEXT], MUIA_TextEditor_Contents, cgy->cgy_HelpText); + nnset(app->Obj[STRING_CONTROLBARGADGETS_NORMAL_ACTION], MUIA_String_Contents, cgy->cgy_Action); + } + else + { + set(app->Obj[STRING_CONTROLBARGADGETS_NORMAL_NORMALIMAGE], MUIA_Disabled, TRUE); + set(app->Obj[STRING_CONTROLBARGADGETS_NORMAL_SELECTEDIMAGE], MUIA_Disabled, TRUE); + set(app->Obj[STRING_CONTROLBARGADGETS_NORMAL_DISABLEDIMAGE], MUIA_Disabled, TRUE); + set(app->Obj[STRING_CONTROLBARGADGETS_NORMAL_ACTION], MUIA_Disabled, TRUE); + set(app->Obj[TEXTEDITOR_CONTROLBARGADGETS_NORMAL_HELPTEXT], MUIA_Disabled, TRUE); + set(app->Obj[POP_CONTROLBARGADGETS_NORMAL_ACTION], MUIA_Disabled, TRUE); + + nnset(app->Obj[STRING_CONTROLBARGADGETS_NORMAL_NORMALIMAGE], MUIA_String_Contents, ""); + nnset(app->Obj[STRING_CONTROLBARGADGETS_NORMAL_SELECTEDIMAGE], MUIA_String_Contents, ""); + nnset(app->Obj[STRING_CONTROLBARGADGETS_NORMAL_DISABLEDIMAGE], MUIA_String_Contents, ""); + nnset(app->Obj[TEXTEDITOR_CONTROLBARGADGETS_NORMAL_HELPTEXT], MUIA_TextEditor_Contents, ""); + nnset(app->Obj[STRING_CONTROLBARGADGETS_NORMAL_ACTION], MUIA_String_Contents, ""); + } + + set(app->Obj[DTIMG_CONTROLBARGADGETS_NORMAL_NORMALIMAGE], MUIA_ScaDtpic_Name, + cgy->cgy_NormalImage ? cgy->cgy_NormalImage : (STRPTR) ""); + set(app->Obj[DTIMG_CONTROLBARGADGETS_NORMAL_SELECTEDIMAGE], MUIA_ScaDtpic_Name, + cgy->cgy_SelectedImage ? cgy->cgy_SelectedImage : (STRPTR) ""); + set(app->Obj[DTIMG_CONTROLBARGADGETS_NORMAL_DISABLEDIMAGE], MUIA_ScaDtpic_Name, + cgy->cgy_DisabledImage ? cgy->cgy_DisabledImage : (STRPTR) ""); +} + +//----------------------------------------------------------------- + +SAVEDS(void) INTERRUPT PluginActive_Func(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + struct PluginDef *pd; + + DoMethod(app->Obj[PLUGIN_LIST], MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &pd); + + if (pd) + { + set(app->Obj[PLUGIN_DESCRIPTION], MUIA_Floattext_Text, pd->plug_Description); + set(app->Obj[PLUGIN_CREATOR], MUIA_Floattext_Text, pd->plug_Creator); + set(app->Obj[REMOVE_PLUGIN], MUIA_Disabled, FALSE); + set(app->Obj[PLUGIN_NAME], MUIA_Text_Contents, pd->plug_RealName); + set(app->Obj[PLUGIN_FILENAME], MUIA_Text_Contents, pd->plug_filename); + set(app->Obj[PLUGIN_VERSION], MUIA_Text_Contents, pd->plug_VersionString); + } + else + { + set(app->Obj[PLUGIN_DESCRIPTION], MUIA_Floattext_Text, ""); + set(app->Obj[PLUGIN_CREATOR], MUIA_Floattext_Text, ""); + set(app->Obj[REMOVE_PLUGIN], MUIA_Disabled, TRUE); + set(app->Obj[PLUGIN_NAME], MUIA_Text_Contents, ""); + set(app->Obj[PLUGIN_FILENAME], MUIA_Text_Contents, ""); + set(app->Obj[PLUGIN_VERSION], MUIA_Text_Contents, ""); + } +} + + +SAVEDS(void) INTERRUPT AddPlugin_Func(struct Hook *hook, Object *pPluginList, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + struct FileRequester *Req; + + AddPluginAslFilterHook.h_Data = app; + + Req = MUI_AllocAslRequestTags(ASL_FileRequest, + ASLFR_SleepWindow, TRUE, + ASLFR_Flags1, FRF_DOPATTERNS, + ASLFR_InitialFile, (ULONG) "", + ASLFR_InitialDrawer, (ULONG) "Scalos:Plugins/OOP", + ASLFR_InitialPattern, (ULONG) "#?.plugin", + ASLFR_UserData, app, + ASLFR_IntuiMsgFunc, &AslIntuiMsgHook, + ASLFR_FilterFunc, &AddPluginAslFilterHook, + TAG_END); + + if (Req) + { + BOOL Result; + struct Window *win = NULL; + + get(app->Obj[WINDOW_MAIN], MUIA_Window_Window, &win); + + //AslRequest( + Result = MUI_AslRequestTags(Req, + ASLFR_Window, (ULONG) win, + ASLFR_TitleText, (ULONG) GetLocString(MSGID_ADD_PLUGIN_ASLTITLE), + ASLFR_DoMultiSelect, TRUE, + TAG_END); + + if (Result) + { + ULONG n; + + for (n = 0; n < Req->fr_NumArgs; n++) + { + struct WBArg *arg = &Req->fr_ArgList[n]; + + BPTR oldDir = CurrentDir(arg->wa_Lock); + + if (!AddPlugin(app, arg->wa_Name)) + { + MUI_Request(app->Obj[APPLICATION], + NULL, + 0, + (STRPTR) GetLocString(MSGID_ADDPLUGIN_FAILURE), + (STRPTR) GetLocString(MSGID_ADDPLUGIN_OK_GAD), + (STRPTR) GetLocString(MSGID_ADDPLUGIN_COULD_NOT_ADD), + arg->wa_Name + ); + } + + CurrentDir(oldDir); + } + } + + MUI_FreeAslRequest(Req); + } +} + + +static SAVEDS(LONG) INTERRUPT AddPluginAslFilterHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + struct FileRequester *fr = (struct FileRequester *) o; + struct AnchorPath *ap = (struct AnchorPath *) msg; + LONG AcceptEntry = TRUE; + BPTR DirLock; + + (void) fr; + + d1(KPrintF("%s/%s/%ld: fib_FileName=<%s> ap_Strlen=%ld\n", __FILE__, __FUNC__, __LINE__, ap->ap_Info.fib_FileName, ap->ap_Strlen)); + d1(KPrintF("%s/%s/%ld: fr_Drawer=<%s>\n", __FILE__, __FUNC__, __LINE__, fr->fr_Drawer)); + + DirLock = Lock(fr->fr_Drawer, ACCESS_READ); + d1(KPrintF("%s/%s/%ld: DirLock=%08lx\n", __FILE__, __FUNC__, __LINE__, DirLock)); + if (DirLock) + { + BPTR OldDir; + BPTR fLock; + + OldDir = CurrentDir(DirLock); + + fLock = Lock(ap->ap_Info.fib_FileName, ACCESS_READ); + d1(KPrintF("%s/%s/%ld: fLock=%08lx\n", __FILE__, __FUNC__, __LINE__, fLock)); + if (fLock) + { + // exclude entry from file requester if already presebnt in plugin list + if (FindPlugin(app, fLock)) + AcceptEntry = FALSE; + + UnLock(fLock); + } + + CurrentDir(OldDir); + UnLock(DirLock); + } + + return AcceptEntry; +} + + +SAVEDS(void) INTERRUPT RemovePluginFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + struct PluginDef *pd; + + DoMethod(app->Obj[PLUGIN_LIST], MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &pd); + + if (pd) + { + RemovePlugin(app, pd); + } +} + +//----------------------------------------------------------------- + +SAVEDS(void) INTERRUPT OpenHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + struct FileRequester *Req; + + Req = MUI_AllocAslRequestTags(ASL_FileRequest, + ASLFR_SleepWindow, TRUE, + ASLFR_Flags1, FRF_DOPATTERNS, + ASLFR_InitialDrawer, (ULONG) "SYS:Prefs/presets", + ASLFR_InitialPattern, (ULONG) "#?.(pre|prefs)", + ASLFR_InitialFile, (ULONG) "Scalos.pre", + ASLFR_UserData, app, + ASLFR_IntuiMsgFunc, &AslIntuiMsgHook, + TAG_END); + + if (Req) + { + BOOL Result; + struct Window *win = NULL; + + get(app->Obj[WINDOW_MAIN], MUIA_Window_Window, &win); + + //AslRequest( + Result = MUI_AslRequestTags(Req, + ASLFR_Window, (ULONG) win, + ASLFR_TitleText, (ULONG) GetLocString(MSGID_MENU_PROJECT_OPEN_ASLTITLE), + TAG_END); + + if (Result) + { + BPTR dirLock = Lock(Req->fr_Drawer, ACCESS_READ); + + if (dirLock) + { + BPTR oldDir = CurrentDir(dirLock); + + ReadScalosPrefs(Req->fr_File); + UpdateGuiFromPrefs(app); + + CurrentDir(oldDir); + UnLock(dirLock); + } + } + + MUI_FreeAslRequest(Req); + } +} + +SAVEDS(void) INTERRUPT LastSavedFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + + DoMethodForAllPrefsPlugins(1, MUIM_ScalosPrefs_LastSavedConfig); + + ReadWorkbenchPrefs("ENVARC:sys/workbench.prefs"); + ReadScalosPrefs("ENVARC:Scalos/Scalos.prefs"); + UpdateGuiFromPrefs(app); +} + +SAVEDS(void) INTERRUPT SaveAsFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + struct FileRequester *Req; + + Req = MUI_AllocAslRequestTags(ASL_FileRequest, + ASLFR_InitialFile, (ULONG) "Scalos.pre", + ASLFR_SleepWindow, TRUE, + ASLFR_DoSaveMode, TRUE, + ASLFR_InitialDrawer, (ULONG) "SYS:Prefs/presets", + ASLFR_UserData, app, + ASLFR_IntuiMsgFunc, &AslIntuiMsgHook, + TAG_END); + + if (Req) + { + BOOL Result; + struct Window *win = NULL; + + get(app->Obj[WINDOW_MAIN], MUIA_Window_Window, &win); + + //AslRequest( + Result = MUI_AslRequestTags(Req, + ASLFR_TitleText, (ULONG) GetLocString(MSGID_MENU_PROJECT_SAVEAS_ASLTITLE), + ASLFR_Window, (ULONG) win, + TAG_END); + + if (Result) + { + BPTR dirLock = Lock(Req->fr_Drawer, ACCESS_READ); + + if (dirLock) + { + BPTR oldDir = CurrentDir(dirLock); + + WriteScalosPrefs(app, Req->fr_File); + + CurrentDir(oldDir); + UnLock(dirLock); + } + } + + MUI_FreeAslRequest(Req); + } +} + +SAVEDS(void) INTERRUPT ResetToDefaultsFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + + DoMethodForAllPrefsPlugins(1, MUIM_ScalosPrefs_ResetToDefaults); + HiddenDevicesCleanup(); + ResetToDefaults(app); +} + +SAVEDS(void) INTERRUPT OpenAboutFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + + MUI_Request(app->Obj[APPLICATION], app->Obj[WINDOW_MAIN], 0, NULL, + (STRPTR) GetLocString(MSGID_ABOUTREQOK), + (STRPTR) GetLocString(MSGID_ABOUTREQFORMAT), + VERSION_MAJOR, VERSION_MINOR, COMPILER_STRING, CURRENTYEAR); +} + +SAVEDS(void) INTERRUPT OpenAboutMorpOSFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + + set(app->Obj[WIN_ABOUT_MORPHOS], MUIA_Window_Open, TRUE); +} + + +SAVEDS(void) INTERRUPT OpenAboutMUIFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + + DoMethod(app->Obj[APPLICATION], MUIM_Application_AboutMUI, + app->Obj[WINDOW_MAIN]); +} + + +SAVEDS(void) INTERRUPT RestoreFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + + DoMethodForAllPrefsPlugins(1, MUIM_ScalosPrefs_RestoreConfig); + + ReadScalosPrefs("ENV:Scalos/Scalos.prefs"); + UpdateGuiFromPrefs(app); +} + +//----------------------------------------------------------------- + +SAVEDS(void) INTERRUPT ModulesPrefsPopupHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + struct ModuleListEntry *mdle = NULL; + ULONG ButtonClicked; + + ButtonClicked = getv(app->Obj[NLIST_MODULES], MUIA_NList_ButtonClick); + + DoMethod(app->Obj[NLIST_MODULES], MUIM_NList_GetEntry, ButtonClicked - 1, &mdle); + + d1(kprintf("%s/%s/%ld: Click %lu mdle=%08lx\n", __FILE__, __FUNC__, __LINE__, ButtonClicked, mdle)); + + if (mdle) + { + set(app->Obj[WINDOW_MAIN], MUIA_Window_Sleep, TRUE); + Execute(mdle->mdle_Filename, 0, 0); + set(app->Obj[WINDOW_MAIN], MUIA_Window_Sleep, FALSE); + } +} + +//----------------------------------------------------------------- + +SAVEDS(void) INTERRUPT DesktopHiddenDevicesHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + struct HiddenDeviceListEntry *hde = NULL; + ULONG ButtonClicked, EntryClicked; + + ButtonClicked = getv(app->Obj[NLIST_HIDDENDEVICES], MUIA_NList_ButtonClick); + EntryClicked = getv(app->Obj[NLIST_HIDDENDEVICES], MUIA_NList_EntryClick); + + DoMethod(app->Obj[NLIST_HIDDENDEVICES], MUIM_NList_GetEntry, + EntryClicked, &hde); + + d1(KPrintF("%s/%s/%ld: Click button=%lu entry=%lu hde=%08lx <%s>\n", \ + __FILE__, __FUNC__, __LINE__, ButtonClicked, EntryClicked, hde, hde->hde_DeviceName)); + + if (hde) + { + // toggle select state + hde->hde_Hidden = !hde->hde_Hidden; + set(hde->hde_CheckboxImage, MUIA_Selected, hde->hde_Hidden); + + if (hde->hde_Hidden) + AddHiddenDevice(hde->hde_DeviceName); + else + RemoveHiddenDevice(hde->hde_DeviceName); + + DoMethod(app->Obj[NLIST_HIDDENDEVICES], MUIM_NList_RedrawEntry, hde); + } +} + +//----------------------------------------------------------------- + +SAVEDS(void) INTERRUPT IconsSelectBobRoutineHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + ULONG BobMethod; + + BobMethod = getv(app->Obj[CYCLE_ROUTINE], MUIA_Cycle_Active); + + set(app->Obj[CYCLE_TRANSPMODE], MUIA_Disabled, DRAGMETHOD_GELS == BobMethod); + + if (DRAGMETHOD_GELS == BobMethod) + set(app->Obj[CYCLE_TRANSPMODE], MUIA_Cycle_Active, TRANSPTYPE_Ghosted); +} + +//----------------------------------------------------------------- + +SAVEDS(void) INTERRUPT CreateIconsHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + + get(app->Obj[MENU_CREATE_ICONS], MUIA_Menuitem_Checked, &fCreateIcons); + + SetAttributeForAllPrefsPlugins(MUIA_ScalosPrefs_CreateIcons, fCreateIcons); +} + +//----------------------------------------------------------------- + +SAVEDS(void) INTERRUPT PageChangeHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + ULONG ActivePage = ~0; + + get(app->Obj[GROUP], MUIA_Group_ActivePage, &ActivePage); + + NotifyPrefsPluginsPageChange(ActivePage); +} + +//----------------------------------------------------------------- + +SAVEDS(void) INTERRUPT PluginListAppMsgHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + struct AppMessage *AppMsg = *((struct AppMessage **) msg); + ULONG n; + + for (n=0; nam_NumArgs; n++) + { + char Path[MAX_FILENAME]; + + if (NameFromLock(AppMsg->am_ArgList[n].wa_Lock, Path, sizeof(Path)) + && AddPart(Path, AppMsg->am_ArgList[n].wa_Name, sizeof(Path))) + { + AddPlugin(app, Path); + } + } +} + +//----------------------------------------------------------------- + +SAVEDS(void) INTERRUPT ScreenTtfPopOpenHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + APTR ttRequest; + ULONG Success = 0; + + ttRequest = TT_AllocRequest(); + + if (ttRequest) + { + struct Window *PrefsWindow = NULL; + struct TagItem *AttrList; + char FontName[MAX_TTFONTDESC]; + ULONG FontStyle, FontWeight, FontSize; + STRPTR FontDesc = NULL; + + set(app->Obj[WINDOW_MAIN], MUIA_Window_Sleep, TRUE); + + get(app->Obj[WINDOW_MAIN], MUIA_Window_Window, &PrefsWindow); + get(o, MUIA_String_Contents, &FontDesc); + + ParseTTFontFromDesc(FontDesc, &FontStyle, &FontWeight, + &FontSize, FontName, sizeof(FontName)); + + //TT_RequestA() + AttrList = TT_Request(ttRequest, + TTRQ_Window, (ULONG) PrefsWindow, + TTRQ_TitleText, (ULONG) GetLocString(MSGID_TTFONTSPAGE_SELECTSCREENFONT_ASLTITLE), + TTRQ_PositiveText, (ULONG) GetLocString(MSGID_TTFONTSPAGE_SELECTFONT_ASL_OKBUTTON), + TTRQ_NegativeText, (ULONG) GetLocString(MSGID_TTFONTSPAGE_SELECTFONT_ASL_CANCELBUTTON), + TTRQ_DoSizes, TRUE, + TTRQ_DoStyle, TRUE, + TTRQ_DoWeight, TRUE, + TTRQ_Activate, TRUE, + TTRQ_DoPreview, TRUE, + TTRQ_InitialName, (ULONG) FontName, + TTRQ_InitialSize, FontSize, + TTRQ_InitialStyle, FontStyle, + TAG_END); + + d1(kprintf("%s/%s/%ld: AttrList=%08lx\n", __FILE__, __FUNC__, __LINE__, AttrList)); + + if (AttrList) + { + char buffer[MAX_TTFONTDESC]; + + BuildTTDescFromAttrList(buffer, sizeof(buffer), AttrList); + + d1(kprintf("%s/%s/%ld: FontDesc=<%s>\n", __FILE__, __FUNC__, __LINE__, buffer)); + + set(o, MUIA_String_Contents, buffer); + set(app->Obj[MCC_TTSCREENFONT_SAMPLE], MUIA_FontSample_TTFontDesc, buffer); + + Success = 1; + } + + TT_FreeRequest(ttRequest); + } + + DoMethod(o, MUIM_Popstring_Close, Success); +} + +SAVEDS(void) INTERRUPT ScreenTtfPopCloseHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + + set(app->Obj[WINDOW_MAIN], MUIA_Window_Sleep, FALSE); +} + +//----------------------------------------------------------------- + +SAVEDS(void) INTERRUPT IconTtfPopOpenHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + APTR ttRequest; + ULONG Success = 0; + + ttRequest = TT_AllocRequest(); + + if (ttRequest) + { + struct Window *PrefsWindow = NULL; + struct TagItem *AttrList; + char FontName[MAX_TTFONTDESC]; + ULONG FontStyle, FontWeight, FontSize; + STRPTR FontDesc = NULL; + + set(app->Obj[WINDOW_MAIN], MUIA_Window_Sleep, TRUE); + + get(app->Obj[WINDOW_MAIN], MUIA_Window_Window, &PrefsWindow); + get(o, MUIA_String_Contents, &FontDesc); + + ParseTTFontFromDesc(FontDesc, &FontStyle, &FontWeight, + &FontSize, FontName, sizeof(FontName)); + + //TT_RequestA() + AttrList = TT_Request(ttRequest, + TTRQ_Window, (ULONG) PrefsWindow, + TTRQ_TitleText, (ULONG) GetLocString(MSGID_TTFONTSPAGE_SELECTICONFONT_ASLTITLE), + TTRQ_PositiveText, (ULONG) GetLocString(MSGID_TTFONTSPAGE_SELECTFONT_ASL_OKBUTTON), + TTRQ_NegativeText, (ULONG) GetLocString(MSGID_TTFONTSPAGE_SELECTFONT_ASL_CANCELBUTTON), + TTRQ_DoSizes, TRUE, + TTRQ_DoStyle, TRUE, + TTRQ_DoWeight, TRUE, + TTRQ_Activate, TRUE, + TTRQ_DoPreview, TRUE, + TTRQ_InitialName, (ULONG) FontName, + TTRQ_InitialSize, FontSize, + TTRQ_InitialStyle, FontStyle, + TAG_END); + + d1(kprintf("%s/%s/%ld: AttrList=%08lx\n", __FILE__, __FUNC__, __LINE__, AttrList)); + + if (AttrList) + { + char buffer[MAX_TTFONTDESC]; + + BuildTTDescFromAttrList(buffer, sizeof(buffer), AttrList); + + d1(kprintf("%s/%s/%ld: FontDesc=<%s>\n", __FILE__, __FUNC__, __LINE__, buffer)); + + set(app->Obj[POPSTRING_TTICONFONT], MUIA_String_Contents, buffer); + set(app->Obj[POPSTRING_ICONSPAGE_TTICONFONT], MUIA_String_Contents, buffer); + + set(app->Obj[MCC_TTICONFONT_SAMPLE], MUIA_FontSample_TTFontDesc, buffer); + set(app->Obj[MCC_ICONSPAGE_TTICONFONT_SAMPLE], MUIA_FontSample_TTFontDesc, buffer); + + Success = 1; + } + + TT_FreeRequest(ttRequest); + } + + DoMethod(o, MUIM_Popstring_Close, Success); +} + +SAVEDS(void) INTERRUPT IconTtfPopCloseHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + + set(app->Obj[WINDOW_MAIN], MUIA_Window_Sleep, FALSE); +} + +//----------------------------------------------------------------- + +SAVEDS(void) INTERRUPT TextWindowTtfPopOpenHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + APTR ttRequest; + ULONG Success = 0; + + ttRequest = TT_AllocRequest(); + + if (ttRequest) + { + struct Window *PrefsWindow = NULL; + struct TagItem *AttrList; + char FontName[MAX_TTFONTDESC]; + ULONG FontStyle, FontWeight, FontSize; + STRPTR FontDesc = NULL; + + set(app->Obj[WINDOW_MAIN], MUIA_Window_Sleep, TRUE); + + get(app->Obj[WINDOW_MAIN], MUIA_Window_Window, &PrefsWindow); + get(o, MUIA_String_Contents, &FontDesc); + + ParseTTFontFromDesc(FontDesc, &FontStyle, &FontWeight, + &FontSize, FontName, sizeof(FontName)); + + //TT_RequestA() + AttrList = TT_Request(ttRequest, + TTRQ_Window, (ULONG) PrefsWindow, + TTRQ_TitleText, (ULONG) GetLocString(MSGID_TTFONTSPAGE_SELECTTEXTWINDOWFONT_ASLTITLE), + TTRQ_PositiveText, (ULONG) GetLocString(MSGID_TTFONTSPAGE_SELECTFONT_ASL_OKBUTTON), + TTRQ_NegativeText, (ULONG) GetLocString(MSGID_TTFONTSPAGE_SELECTFONT_ASL_CANCELBUTTON), + TTRQ_DoSizes, TRUE, + TTRQ_DoStyle, TRUE, + TTRQ_DoWeight, TRUE, + TTRQ_Activate, TRUE, + TTRQ_DoPreview, TRUE, + TTRQ_InitialName, (ULONG) FontName, + TTRQ_InitialSize, FontSize, + TTRQ_InitialStyle, FontStyle, + TAG_END); + + d1(kprintf("%s/%s/%ld: AttrList=%08lx\n", __FILE__, __FUNC__, __LINE__, AttrList)); + + if (AttrList) + { + char buffer[MAX_TTFONTDESC]; + + BuildTTDescFromAttrList(buffer, sizeof(buffer), AttrList); + + d1(kprintf("%s/%s/%ld: FontDesc=<%s>\n", __FILE__, __FUNC__, __LINE__, buffer)); + + set(app->Obj[POPSTRING_TTTEXTWINDOWFONT], MUIA_String_Contents, buffer); + set(app->Obj[POPSTRING_TEXTWINDOW_TTTEXTWINDOWFONT], MUIA_String_Contents, buffer); + + set(app->Obj[MCC_TTTEXTWINDOWFONT_SAMPLE], MUIA_FontSample_TTFontDesc, buffer); + set(app->Obj[MCC_TEXTWINDOW_TTTEXTWINDOWFONT_SAMPLE], MUIA_FontSample_TTFontDesc, buffer); + + Success = 1; + } + + TT_FreeRequest(ttRequest); + } + + DoMethod(o, MUIM_Popstring_Close, Success); +} + +SAVEDS(void) INTERRUPT TextWindowTtfPopCloseHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + + set(app->Obj[WINDOW_MAIN], MUIA_Window_Sleep, FALSE); +} + +//----------------------------------------------------------------- + +SAVEDS(void) INTERRUPT IconDragTransparencyHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + ULONG active = 0; + + // Disable DragnDrop Icon transparency if transparent dragging is not enabled + + get(app->Obj[CYCLE_TRANSPMODE], MUIA_Cycle_Active, &active); + set(app->Obj[SLIDER_ICONTRANSPARENCY_DRAG], MUIA_Disabled, TRANSPTYPE_Transparent != active); +} + +//----------------------------------------------------------------- + +static void BuildTTDescFromAttrList(char *buffer, size_t length, struct TagItem *AttrList) +{ + ULONG FontStyle; + ULONG FontWeight; + ULONG FontSize; + const STRPTR *FontFamilyTable; + + FontStyle = GetTagData(TT_FontStyle, TT_FontStyle_Regular, AttrList); + FontWeight = GetTagData(TT_FontWeight, TT_FontWeight_Normal, AttrList); + FontSize = GetTagData(TT_FontSize, 12, AttrList); + FontFamilyTable = (const STRPTR *) GetTagData(TT_FamilyTable, (ULONG) NULL, AttrList); + + sprintf(buffer, "%ld/%ld/%ld/%s", (long)FontStyle, (long)FontWeight, (long)FontSize, FontFamilyTable[0]); +} + +//----------------------------------------------------------------- + +static BOOL ParseTTFontFromDesc(CONST_STRPTR FontDesc, + ULONG *FontStyle, ULONG *FontWeight, ULONG *FontSize, + STRPTR FontName, size_t FontNameSize) +{ + CONST_STRPTR lp; + long long1,long2,long3; + + strcpy(FontName, ""); + *FontStyle = 0; + *FontWeight = 0; + *FontSize = 0; + + // Font Desc format: + // "style/weight/size/fontname" + + if (3 != sscanf(FontDesc, "%ld/%ld/%ld", &long1, &long2, &long3)) + return FALSE; + + *FontStyle = long1; + *FontWeight = long2; + *FontSize = long3; + + lp = strchr(FontDesc, '/'); // Find "/" between style and weight + if (NULL == lp) + return FALSE; + + lp = strchr(lp + 1, '/'); // Find "/" between weight and size + if (NULL == lp) + return FALSE; + + lp = strchr(lp + 1, '/'); // Find "/" between size and name + if (NULL == lp) + return FALSE; + + // copy font name + stccpy(FontName, 1 + lp, FontNameSize); + + return TRUE; +} + +//----------------------------------------------------------------- + +SAVEDS(void) INTERRUPT IconsMinSizeHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + struct Rectangle SizeConstraints; + + GetIconSizeConstraints(app, &SizeConstraints); + AdjustIconSizeSample(app, &SizeConstraints); + + if (SizeConstraints.MaxX < SizeConstraints.MinX) + { + // Adjust MaxSize if MaxSize is smaller than MinSize + SizeConstraints.MaxX = SizeConstraints.MaxY = SizeConstraints.MinX; + SetIconSizeConstraints(app, &SizeConstraints); + } +} + + +SAVEDS(void) INTERRUPT IconsMaxSizeHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + struct Rectangle SizeConstraints; + + GetIconSizeConstraints(app, &SizeConstraints); + AdjustIconSizeSample(app, &SizeConstraints); + + if (SizeConstraints.MaxX < SizeConstraints.MinX) + { + // Adjust MinSize if MaxSize is smaller than MinSize + SizeConstraints.MinX = SizeConstraints.MinY = SizeConstraints.MaxX; + SetIconSizeConstraints(app, &SizeConstraints); + } +} + +//----------------------------------------------------------------- +/*** Removed! *** +SAVEDS(void) INTERRUPT ThumbnailsShowModeHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + ULONG ShowMode; + + ShowMode = getv(app->Obj[CYCLE_SHOWTHUMBNAILS], MUIA_Cycle_Active); + + if (SHOWTHUMBNAILS_AS_DEFAULT != ShowMode) + // Disable checkmark allowing thumbnail + set(app->Obj[CHECK_SHOWTHUMBNAILS_AS_DEFAULT], MUIA_Disabled, TRUE); + else + set(app->Obj[CHECK_SHOWTHUMBNAILS_AS_DEFAULT], MUIA_Disabled, FALSE); +} +***/ +//----------------------------------------------------------------- + +SAVEDS(void) INTERRUPT IconFrameHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + ULONG FrameTypeNormal = 0; + ULONG FrameTypeSelected = 0; + BOOL RecessedNormal; + BOOL RecessedSelected; + const struct FrameSize *fs; + ULONG BorderLeft, BorderRight, BorderTop, BorderBottom; + ULONG Border = 0; + + get(app->Obj[FRAME_ICONNORMAL], MUIA_MCPFrame_FrameType, &FrameTypeNormal); + get(app->Obj[FRAME_ICONSELECTED], MUIA_MCPFrame_FrameType, &FrameTypeSelected); + + RecessedNormal = (FrameTypeNormal & MCP_FRAME_RECESSED) ? TRUE : FALSE; + FrameTypeNormal &= ~MCP_FRAME_RECESSED; + + RecessedSelected = (FrameTypeSelected & MCP_FRAME_RECESSED) ? TRUE : FALSE; + FrameTypeSelected &= ~MCP_FRAME_RECESSED; + + // find minimum icon borders + + BorderLeft = BorderRight = BorderTop = BorderBottom = 0; + + fs = McpGetFrameSize(FrameTypeNormal); + if (fs) + { + if (RecessedNormal) + { + BorderLeft = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_RELEFT]); + BorderRight = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_RERIGHT]); + BorderTop = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_RETOP]); + BorderBottom = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_REBOTTOM]); + } + else + { + BorderLeft = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_LEFT]); + BorderRight = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_RIGHT]); + BorderTop = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_TOP]); + BorderBottom = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_BOTTOM]); + } + } + + fs = McpGetFrameSize(FrameTypeSelected); + if (fs) + { + if (RecessedSelected) + { + BorderLeft = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_RELEFT]); + BorderRight = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_RERIGHT]); + BorderTop = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_RETOP]); + BorderBottom = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_REBOTTOM]); + } + else + { + BorderLeft = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_LEFT]); + BorderRight = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_RIGHT]); + BorderTop = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_TOP]); + BorderBottom = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_BOTTOM]); + } + } + + // now adjust icon borders if they are smaller than required + + get(app->Obj[ICONLEFT], MUIA_Numeric_Value, &Border); + if (Border < BorderLeft) + setslider(app->Obj[ICONLEFT], BorderLeft); + + get(app->Obj[ICONRIGHT], MUIA_Numeric_Value, &Border); + if (Border < BorderRight) + setslider(app->Obj[ICONRIGHT], BorderRight); + + get(app->Obj[ICONTOP], MUIA_Numeric_Value, &Border); + if (Border < BorderTop) + setslider(app->Obj[ICONTOP], BorderTop); + + get(app->Obj[ICONBOTTOM], MUIA_Numeric_Value, &Border); + if (Border < BorderBottom) + setslider(app->Obj[ICONBOTTOM], BorderBottom); + +} + +//----------------------------------------------------------------- + +SAVEDS(void) INTERRUPT ThumbnailFrameHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + ULONG FrameTypeNormal = 0; + ULONG FrameTypeSelected = 0; + BOOL RecessedNormal; + BOOL RecessedSelected; + const struct FrameSize *fs; + ULONG BorderLeft, BorderRight, BorderTop, BorderBottom; + ULONG Border = 0; + + get(app->Obj[FRAME_ICON_THUMBNAIL_NORMAL], MUIA_MCPFrame_FrameType, &FrameTypeNormal); + get(app->Obj[FRAME_ICON_THUMBNAIL_SELECTED], MUIA_MCPFrame_FrameType, &FrameTypeSelected); + + d1(KPrintF("%s/%s/%ld: START FrameTypeNormal=%ld FrameTypeSelected=%ld\n", \ + __FILE__, __FUNC__, __LINE__, FrameTypeNormal, FrameTypeSelected)); + + RecessedNormal = (FrameTypeNormal & MCP_FRAME_RECESSED) ? TRUE : FALSE; + FrameTypeNormal &= ~MCP_FRAME_RECESSED; + + RecessedSelected = (FrameTypeSelected & MCP_FRAME_RECESSED) ? TRUE : FALSE; + FrameTypeSelected &= ~MCP_FRAME_RECESSED; + + // find minimum thumbnail borders + + BorderLeft = BorderRight = BorderTop = BorderBottom = 0; + + fs = McpGetFrameSize(FrameTypeNormal); + if (fs) + { + if (RecessedNormal) + { + BorderLeft = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_RELEFT]); + BorderRight = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_RERIGHT]); + BorderTop = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_RETOP]); + BorderBottom = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_REBOTTOM]); + } + else + { + BorderLeft = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_LEFT]); + BorderRight = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_RIGHT]); + BorderTop = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_TOP]); + BorderBottom = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_BOTTOM]); + } + } + + fs = McpGetFrameSize(FrameTypeSelected); + if (fs) + { + if (RecessedSelected) + { + BorderLeft = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_RELEFT]); + BorderRight = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_RERIGHT]); + BorderTop = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_RETOP]); + BorderBottom = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_REBOTTOM]); + } + else + { + BorderLeft = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_LEFT]); + BorderRight = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_RIGHT]); + BorderTop = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_TOP]); + BorderBottom = max(BorderLeft, fs->fs_Sizes[FRAMESIZE_BOTTOM]); + } + } + + // now adjust thumbnail borders if they are smaller than required + + get(app->Obj[THUMBNAILS_LEFTBORDER], MUIA_Numeric_Value, &Border); + if (Border < BorderLeft) + setslider(app->Obj[THUMBNAILS_LEFTBORDER], BorderLeft); + + get(app->Obj[THUMBNAILS_RIGHTBORDER], MUIA_Numeric_Value, &Border); + if (Border < BorderRight) + setslider(app->Obj[THUMBNAILS_RIGHTBORDER], BorderRight); + + get(app->Obj[THUMBNAILS_TOPBORDER], MUIA_Numeric_Value, &Border); + if (Border < BorderTop) + setslider(app->Obj[THUMBNAILS_TOPBORDER], BorderTop); + + get(app->Obj[THUMBNAILS_BOTTOMBORDER], MUIA_Numeric_Value, &Border); + if (Border < BorderBottom) + setslider(app->Obj[THUMBNAILS_BOTTOMBORDER], BorderBottom); +} + +//---------------------------------------------------------------------------- + +SAVEDS(void) INTERRUPT AslIntuiMsgHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + struct IntuiMessage *iMsg = (struct IntuiMessage *) msg; + + if (IDCMP_REFRESHWINDOW == iMsg->Class) + { + DoMethod(app->Obj[APPLICATION], MUIM_Application_CheckRefresh); + } +} + +//---------------------------------------------------------------------------- + +SAVEDS(APTR) INTERRUPT BrowserCmdSelectedHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + struct CommandTableEntry *cte = NULL; + + DoMethod(o, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &cte); + if (cte) + { + setstring(app->Obj[STRING_CONTROLBARGADGETS_BROWSER_ACTION], (ULONG) cte->cte_Command); + + DoMethod(app->Obj[POP_CONTROLBARGADGETS_BROWSER_ACTION], MUIM_Popstring_Close, 0); + + ControlBarGadgetBrowserChangedHookFunc(hook, o, msg); + } + + return 0; +} + +//---------------------------------------------------------------------------- + +SAVEDS(APTR) INTERRUPT NormalCmdSelectedHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + struct CommandTableEntry *cte = NULL; + + DoMethod(o, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &cte); + if (cte) + { + setstring(app->Obj[STRING_CONTROLBARGADGETS_NORMAL_ACTION], (ULONG) cte->cte_Command); + + DoMethod(app->Obj[POP_CONTROLBARGADGETS_NORMAL_ACTION], MUIM_Popstring_Close, 0); + + ControlBarGadgetNormalChangedHookFunc(hook, o, msg); + } + + return 0; +} + +//---------------------------------------------------------------------------- + +SAVEDS(APTR) INTERRUPT ControlBarGadgetBrowserChangedHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + struct ControlBarGadgetEntry *cgy = NULL; + + DoMethod(app->Obj[NLISTVIEW_CONTROLBARGADGETS_BROWSER_ACTIVE], MUIM_NList_GetEntry, MUIV_List_GetEntry_Active, &cgy); + + d1(KPrintF("%s/%s/%ld: cgy=%08lx\n", __FILE__, __FUNC__, __LINE__, cgy)); + + if (cgy && SCPGadgetType_ActionButton == cgy->cgy_GadgetType) + { + STRPTR str = NULL; + ULONG Changed = 0; + + get(app->Obj[STRING_CONTROLBARGADGETS_BROWSER_NORMALIMAGE], MUIA_String_Contents, &str); + d1(KPrintF("%s/%s/%ld: str=%08lx\n", __FILE__, __FUNC__, __LINE__, str)); + if (0 != strcmp(str, cgy->cgy_NormalImage)) + { + Changed++; + + if (cgy->cgy_NormalImage) + free(cgy->cgy_NormalImage); + cgy->cgy_NormalImage = strdup(str); + + DoMethod(app->Obj[NLISTVIEW_CONTROLBARGADGETS_BROWSER_ACTIVE], MUIM_NList_UseImage, + NULL, cgy->cgy_ImageObjectIndex, 0); + MUI_DisposeObject(cgy->cgy_Image); + + if (ExistsObject(cgy->cgy_NormalImage)) + { + cgy->cgy_Image = NewObject(DataTypesImageClass->mcc_Class, 0, + MUIA_ScaDtpic_Name, (ULONG) cgy->cgy_NormalImage, + TAG_END); //DataTypesMCC + + set(app->Obj[DTIMG_CONTROLBARGADGETS_BROWSER_NORMALIMAGE], MUIA_ScaDtpic_Name, + cgy->cgy_NormalImage); + d1(KPrintF("%s/%s/%ld: <%s> cgy_Image=%08lx\n", __FILE__, __FUNC__, __LINE__, cgy->cgy_NormalImage, cgy->cgy_Image)); + } + else + { + set(app->Obj[DTIMG_CONTROLBARGADGETS_BROWSER_NORMALIMAGE], MUIA_ScaDtpic_Name, + (STRPTR) ""); + cgy->cgy_Image = NULL; + } + + DoMethod(app->Obj[NLISTVIEW_CONTROLBARGADGETS_BROWSER_ACTIVE], MUIM_NList_UseImage, + cgy->cgy_Image, cgy->cgy_ImageObjectIndex, 0); + } + + get(app->Obj[STRING_CONTROLBARGADGETS_BROWSER_SELECTEDIMAGE], MUIA_String_Contents, &str); + d1(KPrintF("%s/%s/%ld: str=%08lx\n", __FILE__, __FUNC__, __LINE__, str)); + if (0 != strcmp(str, cgy->cgy_SelectedImage)) + { + Changed++; + + if (cgy->cgy_SelectedImage) + free(cgy->cgy_SelectedImage); + cgy->cgy_SelectedImage = strdup(str); + + set(app->Obj[DTIMG_CONTROLBARGADGETS_BROWSER_SELECTEDIMAGE], MUIA_ScaDtpic_Name, + cgy->cgy_SelectedImage); + } + + get(app->Obj[STRING_CONTROLBARGADGETS_BROWSER_DISABLEDIMAGE], MUIA_String_Contents, &str); + d1(KPrintF("%s/%s/%ld: str=%08lx\n", __FILE__, __FUNC__, __LINE__, str)); + if (0 != strcmp(str, cgy->cgy_SelectedImage)) + { + Changed++; + + if (cgy->cgy_DisabledImage) + free(cgy->cgy_DisabledImage); + cgy->cgy_DisabledImage = strdup(str); + + set(app->Obj[DTIMG_CONTROLBARGADGETS_BROWSER_DISABLEDIMAGE], MUIA_ScaDtpic_Name, + cgy->cgy_DisabledImage); + } + + get(app->Obj[STRING_CONTROLBARGADGETS_BROWSER_ACTION], MUIA_String_Contents, &str); + d1(KPrintF("%s/%s/%ld: str=%08lx\n", __FILE__, __FUNC__, __LINE__, str)); + if (0 != strcmp(str, cgy->cgy_Action)) + { + Changed++; + + stccpy(cgy->cgy_Action, str, sizeof(cgy->cgy_Action)); + } + + set(app->Obj[TEXTEDITOR_CONTROLBARGADGETS_BROWSER_HELPTEXT],MUIA_TextEditor_HasChanged, FALSE); + str = (STRPTR) DoMethod(app->Obj[TEXTEDITOR_CONTROLBARGADGETS_BROWSER_HELPTEXT], MUIM_TextEditor_ExportText); + d1(KPrintF("%s/%s/%ld: str=%08lx cgy_HelpText=%08lx\n", __FILE__, __FUNC__, __LINE__, str, cgy->cgy_HelpText)); + if ((NULL == cgy->cgy_HelpText) || (0 != strcmp(str, cgy->cgy_HelpText))) + { + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + Changed++; + + if (cgy->cgy_HelpText) + free(cgy->cgy_HelpText); + cgy->cgy_HelpText = strdup(str); + } + + d1(KPrintF("%s/%s/%ld: Changed=%ld\n", __FILE__, __FUNC__, __LINE__, Changed)); + if (Changed) + DoMethod(app->Obj[NLISTVIEW_CONTROLBARGADGETS_BROWSER_ACTIVE], MUIM_NList_RedrawEntry, cgy); + } + + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); + + return 0; +} + +//---------------------------------------------------------------------------- + +SAVEDS(APTR) INTERRUPT ControlBarGadgetNormalChangedHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + struct ControlBarGadgetEntry *cgy = NULL; + + DoMethod(app->Obj[NLISTVIEW_CONTROLBARGADGETS_NORMAL_ACTIVE], MUIM_NList_GetEntry, MUIV_List_GetEntry_Active, &cgy); + + d1(KPrintF("%s/%s/%ld: cgy=%08lx\n", __FILE__, __FUNC__, __LINE__, cgy)); + + if (cgy && SCPGadgetType_ActionButton == cgy->cgy_GadgetType) + { + STRPTR str = NULL; + ULONG Changed = 0; + + get(app->Obj[STRING_CONTROLBARGADGETS_NORMAL_NORMALIMAGE], MUIA_String_Contents, &str); + d1(KPrintF("%s/%s/%ld: str=%08lx\n", __FILE__, __FUNC__, __LINE__, str)); + if (0 != strcmp(str, cgy->cgy_NormalImage)) + { + Changed++; + + if (cgy->cgy_NormalImage) + free(cgy->cgy_NormalImage); + cgy->cgy_NormalImage = strdup(str); + + DoMethod(app->Obj[NLISTVIEW_CONTROLBARGADGETS_NORMAL_ACTIVE], MUIM_NList_UseImage, + NULL, cgy->cgy_ImageObjectIndex, 0); + MUI_DisposeObject(cgy->cgy_Image); + + if (ExistsObject(cgy->cgy_NormalImage)) + { + cgy->cgy_Image = NewObject(DataTypesImageClass->mcc_Class, 0, + MUIA_ScaDtpic_Name, (ULONG) cgy->cgy_NormalImage, + TAG_END); //DataTypesMCC + + set(app->Obj[DTIMG_CONTROLBARGADGETS_NORMAL_NORMALIMAGE], MUIA_ScaDtpic_Name, + cgy->cgy_NormalImage); + + d1(KPrintF("%s/%s/%ld: <%s> cgy_Image=%08lx\n", __FILE__, __FUNC__, __LINE__, cgy->cgy_NormalImage, cgy->cgy_Image)); + } + else + { + set(app->Obj[DTIMG_CONTROLBARGADGETS_NORMAL_NORMALIMAGE], MUIA_ScaDtpic_Name, + (STRPTR) ""); + cgy->cgy_Image = NULL; + } + + DoMethod(app->Obj[NLISTVIEW_CONTROLBARGADGETS_NORMAL_ACTIVE], MUIM_NList_UseImage, + cgy->cgy_Image, cgy->cgy_ImageObjectIndex, 0); + } + + get(app->Obj[STRING_CONTROLBARGADGETS_NORMAL_SELECTEDIMAGE], MUIA_String_Contents, &str); + d1(KPrintF("%s/%s/%ld: str=%08lx\n", __FILE__, __FUNC__, __LINE__, str)); + if (0 != strcmp(str, cgy->cgy_SelectedImage)) + { + Changed++; + + if (cgy->cgy_SelectedImage) + free(cgy->cgy_SelectedImage); + cgy->cgy_SelectedImage = strdup(str); + + set(app->Obj[DTIMG_CONTROLBARGADGETS_NORMAL_SELECTEDIMAGE], MUIA_ScaDtpic_Name, + cgy->cgy_SelectedImage); + } + + get(app->Obj[STRING_CONTROLBARGADGETS_NORMAL_DISABLEDIMAGE], MUIA_String_Contents, &str); + d1(KPrintF("%s/%s/%ld: str=%08lx\n", __FILE__, __FUNC__, __LINE__, str)); + if (0 != strcmp(str, cgy->cgy_SelectedImage)) + { + Changed++; + + if (cgy->cgy_DisabledImage) + free(cgy->cgy_DisabledImage); + cgy->cgy_DisabledImage = strdup(str); + + set(app->Obj[DTIMG_CONTROLBARGADGETS_NORMAL_DISABLEDIMAGE], MUIA_ScaDtpic_Name, + cgy->cgy_DisabledImage); + } + + get(app->Obj[STRING_CONTROLBARGADGETS_NORMAL_ACTION], MUIA_String_Contents, &str); + d1(KPrintF("%s/%s/%ld: str=%08lx\n", __FILE__, __FUNC__, __LINE__, str)); + if (0 != strcmp(str, cgy->cgy_Action)) + { + Changed++; + + stccpy(cgy->cgy_Action, str, sizeof(cgy->cgy_Action)); + } + + set(app->Obj[TEXTEDITOR_CONTROLBARGADGETS_NORMAL_HELPTEXT],MUIA_TextEditor_HasChanged, FALSE); + str = (STRPTR) DoMethod(app->Obj[TEXTEDITOR_CONTROLBARGADGETS_NORMAL_HELPTEXT], MUIM_TextEditor_ExportText); + d1(KPrintF("%s/%s/%ld: str=%08lx cgy_HelpText=%08lx\n", __FILE__, __FUNC__, __LINE__, str, cgy->cgy_HelpText)); + if ((NULL == cgy->cgy_HelpText) || (0 != strcmp(str, cgy->cgy_HelpText))) + { + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + Changed++; + + if (cgy->cgy_HelpText) + free(cgy->cgy_HelpText); + cgy->cgy_HelpText = strdup(str); + } + + d1(KPrintF("%s/%s/%ld: Changed=%ld\n", __FILE__, __FUNC__, __LINE__, Changed)); + if (Changed) + DoMethod(app->Obj[NLISTVIEW_CONTROLBARGADGETS_NORMAL_ACTIVE], MUIM_NList_RedrawEntry, cgy); + } + + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); + + return 0; +} + +//----------------------------------------------------------------- + +SAVEDS(void) INTERRUPT CalculateMaxRadiusHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + BOOL useTT; + LONG YBorder; + LONG FontHeight; + LONG MaxRadius; + CONST_STRPTR lp; + + useTT = getv(app->Obj[CHECK_TTICONFONT_ENABLE], MUIA_Selected); + + if (useTT) + { + lp = (CONST_STRPTR) getv(app->Obj[POPSTRING_TTICONFONT], MUIA_String_Contents); + FontHeight = TTFontHeightFromDesc(lp); + } + else + { + lp = (CONST_STRPTR) getv(app->Obj[POP_ICONFONT], MUIA_String_Contents); + FontHeight = DiskFontHeightFromDesc(lp); + } + + + YBorder = getv(app->Obj[SLIDER_SEL_ICONTEXT_RECT_BORDERY], MUIA_Numeric_Value); + + MaxRadius = (YBorder + FontHeight) / 2; + + set(app->Obj[SLIDER_SEL_ICONTEXT_RECT_RADIUS], MUIA_Numeric_Max, MaxRadius); +} + +//----------------------------------------------------------------- + +static LONG TTFontHeightFromDesc(CONST_STRPTR FontDesc) +{ + // LONG FontStyle; + // LONG FontWeight; + LONG FontSize; + CONST_STRPTR lp; + long long1, long2, long3; + + // Font Desc format: + // "style/weight/size/fontname" + + if (NULL == FontDesc) + return 0; + + if (3 != sscanf(FontDesc, "%ld/%ld/%ld", &long1, &long2, &long3)) + return 0; + + // FontStyle = long1; + // FontWeight = long2; + FontSize = long3; + + lp = strchr(FontDesc, '/'); // Find "/" between style and weight + if (NULL == lp) + return 0; + + lp = strchr(lp + 1, '/'); // Find "/" between weight and size + if (NULL == lp) + return 0; + + lp = strchr(lp + 1, '/'); // Find "/" between size and name + if (NULL == lp) + return 0; + + return FontSize; +} + +//----------------------------------------------------------------- + +static LONG DiskFontHeightFromDesc(CONST_STRPTR FontDesc) +{ + // Font Desc format: + // "fontname/size" + struct TextAttr ta; + CONST_STRPTR fp; + size_t fnLen; + LONG l; + + for (fp=FontDesc, fnLen=0; *fp && '/' != *fp; fnLen++) + fp++; + + if ('/' == *fp) + fp++; + + if (StrToLong(fp, &l)) + ta.ta_YSize = l; + else + ta.ta_YSize = 8; + + return ta.ta_YSize; +} + +//----------------------------------------------------------------- + +SAVEDS(void) INTERRUPT UpdateSelectMarkerSampleHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + struct ARGB argb; + + argb.Alpha = getv(app->Obj[SLIDER_TEXTWINDOWS_SELECTBORDERTRANSPARENCY], MUIA_Numeric_Value); + + argb.Red = getv(app->Obj[COLORADJUST_TEXTWINDOWS_SELECTIONMARK], MUIA_Coloradjust_Red) >> 24; + argb.Green = getv(app->Obj[COLORADJUST_TEXTWINDOWS_SELECTIONMARK], MUIA_Coloradjust_Green) >> 24; + argb.Blue = getv(app->Obj[COLORADJUST_TEXTWINDOWS_SELECTIONMARK], MUIA_Coloradjust_Blue) >> 24; + + set(app->Obj[MCC_TEXTWINDOWS_SELECTMARKER_SAMPLE], TIHA_BaseColor, (ULONG) &argb); +} + +//----------------------------------------------------------------- + +SAVEDS(void) INTERRUPT ChangeThumbnailSizeHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + ULONG SizeIndex; + + SizeIndex = getv(app->Obj[CYCLE_THUMBNAILSIZE], MUIA_Cycle_Active); + + set(app->Obj[GROUP_THUMBNAILS_ICON_SAMPLE], MUIA_Group_ActivePage, SizeIndex); +} + +//----------------------------------------------------------------- + + diff --git a/scalos/Prefs/MainPrefs/Hooks.h b/scalos/Prefs/MainPrefs/Hooks.h new file mode 100644 index 000000000..546029543 --- /dev/null +++ b/scalos/Prefs/MainPrefs/Hooks.h @@ -0,0 +1,50 @@ +// Hooks.h +// $Date$ +// $Revision$ + + +#ifndef HOOKS_H +#define HOOKS_H + +SAVEDS(void) INTERRUPT StartFontPrefs_Func(struct Hook *hook, Object *pPrefsWindow, Msg msg); +SAVEDS(void) INTERRUPT StartWorkbenchPrefs_Func(struct Hook *hook, Object *pPrefsWindow, Msg msg); +SAVEDS(void) INTERRUPT CheckPopTitleBarBox(struct Hook *hook, Object *pPrefsWindow, Msg msg); +SAVEDS(void) INTERRUPT ControlBarGadgetListBrowserActiveHookFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT ControlBarGadgetListNormalActiveHookFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT AddPlugin_Func(struct Hook *hook, Object *pPluginList, Msg msg); +SAVEDS(void) INTERRUPT PluginActive_Func(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT OpenHookFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT LastSavedFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT SaveAsFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT ResetToDefaultsFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT RestoreFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT OpenAboutFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT OpenAboutMorpOSFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT OpenAboutMUIFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT RemovePluginFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT ModulesPrefsPopupHookFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT DesktopHiddenDevicesHookFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT IconsSelectBobRoutineHookFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT CreateIconsHookFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT PageChangeHookFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT PluginListAppMsgHookFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT ScreenTtfPopOpenHookFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT ScreenTtfPopCloseHookFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT IconTtfPopOpenHookFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT IconTtfPopCloseHookFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT TextWindowTtfPopOpenHookFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT TextWindowTtfPopCloseHookFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT IconDragTransparencyHookFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT IconsMinSizeHookFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT IconsMaxSizeHookFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT IconFrameHookFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT ThumbnailFrameHookFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT AslIntuiMsgHookFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(APTR) INTERRUPT BrowserCmdSelectedHookFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(APTR) INTERRUPT NormalCmdSelectedHookFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(APTR) INTERRUPT ControlBarGadgetBrowserChangedHookFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(APTR) INTERRUPT ControlBarGadgetNormalChangedHookFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT CalculateMaxRadiusHookFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT UpdateSelectMarkerSampleHookFunc(struct Hook *hook, Object *o, Msg msg); +SAVEDS(void) INTERRUPT ChangeThumbnailSizeHookFunc(struct Hook *hook, Object *o, Msg msg); +#endif /* HOOKS_H */ diff --git a/scalos/Prefs/MainPrefs/Images.c b/scalos/Prefs/MainPrefs/Images.c new file mode 100644 index 000000000..0f9204ba1 --- /dev/null +++ b/scalos/Prefs/MainPrefs/Images.c @@ -0,0 +1,2987 @@ +// Images.c +// $Date$ +// $Revision$ + + +#include +#include + +#include +#include +#include +#include + +#define __USE_SYSBASE +#define NO_INLINE_STDARG + +#include + +#include +#include + +#include "DataTypesMCC.h" +#include "General.h" +#include "ScalosPrefs.h" +#include "Images.h" + +//---------------------------------------------------------------------------- + +extern struct MUI_CustomClass *DataTypesImageClass; + +//---------------------------------------------------------------------------- + +static const ULONG icon128_colors[96] = +{ + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, + 0xc8c8c8c8,0xd5d5d5d5,0xe9e9e9e9, + 0xabababab,0xacacacac,0xefefefef, + 0x95959595,0x95959595,0x9b9b9b9b, + 0x92929292,0x99999999,0xd7d7d7d7, + 0x7b7b7b7b,0x87878787,0xbfbfbfbf, + 0x53535353,0x67676767,0x95959595, + 0xe8e8e8e8,0xeeeeeeee,0xfbfbfbfb, + 0xd3d3d3d3,0xdededede,0xf1f1f1f1, + 0xc1c1c1c1,0xcacacaca,0xdadadada, + 0xc9c9c9c9,0xd5d5d5d5,0xe9e9e9e9, + 0xcccccccc,0xdadadada,0xefefefef, + 0xc9c9c9c9,0xd7d7d7d7,0xecececec, + 0xd4d4d4d4,0xe4e4e4e4,0xfafafafa, + 0xa9a9a9a9,0xb1b1b1b1,0xbcbcbcbc, + 0x26262626,0x3f3f3f3f,0x5d5d5d5d, + 0x77777777,0x7c7c7c7c,0x82828282, + 0xefefefef,0xe7e7e7e7,0x15151515, + 0xf3f3f3f3,0xecececec,0x4d4d4d4d, + 0xf8f8f8f8,0xf3f3f3f3,0x83838383, + 0xfafafafa,0xf7f7f7f7,0xaeaeaeae, + 0xfcfcfcfc,0xfafafafa,0xd6d6d6d6, + 0xd0d0d0d0,0xc4c4c4c4,0x7e7e7e7e, + 0xe1e1e1e1,0xb4b4b4b4,0x42424242, + 0xdcdcdcdc,0x70707070,0x3f3f3f3f, + 0xb0b0b0b0,0x7a7a7a7a,0x69696969, + 0x60606060,0x56565656,0x55555555, + 0x8c8c8c8c,0x0a0a0a0a,0x0a0a0a0a, + 0xd9d9d9d9,0x34343434,0x32323232, + 0xc6c6c6c6,0xc4c4c4c4,0xc4c4c4c4, + 0xffffffff,0xffffffff,0xffffffff, +}; + +#define ICON128_WIDTH 128 +#define ICON128_HEIGHT 128 +#define ICON128_DEPTH 5 +#define ICON128_COMPRESSION 1 +#define ICON128_MASKING 0 + +static const struct BitMapHeader icon128_header = +{ 128,128,0,0,5,0,1,0,0,1,1,128,128 }; + +static const UBYTE icon128_body[6544] = { +0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1, +0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00, +0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1, +0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00, +0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1, +0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00, +0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1, +0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00, +0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1, +0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00, +0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1, +0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00, +0xfa,0x00,0x00,0xf8,0xf9,0x00,0xfa,0xff,0x00,0x07,0xf9,0xff,0xfa,0x00,0x00, +0xf8,0xf9,0x00,0xfa,0x00,0x00,0xf8,0xf9,0x00,0xf1,0x00,0xfa,0x00,0x00,0x08, +0xf9,0x00,0xfa,0xff,0x00,0xf7,0xf9,0xff,0xfa,0x00,0x00,0x08,0xf9,0x00,0xfa, +0x00,0x00,0x08,0xf9,0x00,0xf1,0x00,0xfb,0x00,0x02,0x1e,0x01,0xc0,0xfa,0x00, +0xfb,0xff,0x02,0xe1,0xfe,0x3f,0xfa,0xff,0xfb,0x00,0x02,0x1e,0x01,0xc0,0xfa, +0x00,0xfb,0x00,0x02,0x1e,0xe1,0xc0,0xfa,0x00,0xf1,0x00,0xfb,0x00,0x02,0x1a, +0x07,0xe0,0xfa,0x00,0xfb,0xff,0x02,0xe1,0xf8,0x1f,0xfa,0xff,0xfb,0x00,0x02, +0x1e,0x47,0xe0,0xfa,0x00,0xfb,0x00,0x02,0x1f,0xff,0xe0,0xfa,0x00,0xfa,0x00, +0x00,0x40,0xf9,0x00,0xfb,0x00,0x01,0x01,0x01,0xf9,0x00,0xfa,0xff,0x00,0xfe, +0xf9,0xff,0xfa,0x00,0x00,0x79,0xf9,0x00,0xfb,0x00,0x01,0x01,0xfd,0xf9,0x00, +0xfa,0x00,0x00,0x78,0xf9,0x00,0xfc,0x00,0x03,0x07,0xc0,0xb8,0x0f,0xfa,0x00, +0xfc,0xff,0x03,0xf8,0x3f,0x3f,0xf0,0xfa,0xff,0xfc,0x00,0x03,0x07,0xc0,0x2c, +0x0f,0xfa,0x00,0xfc,0x00,0x03,0x07,0xcf,0xc6,0xef,0xfa,0x00,0xfa,0x00,0x00, +0x3c,0xf9,0x00,0xfc,0x00,0x03,0x03,0xc1,0x14,0x0b,0xfa,0x00,0xfc,0xff,0x03, +0xfc,0x3f,0x5f,0xf0,0xfa,0xff,0xfc,0x00,0x03,0x03,0xc6,0x66,0x4f,0xfa,0x00, +0xfc,0x00,0x03,0x03,0xff,0x83,0xef,0xfa,0x00,0xfb,0x00,0x02,0x06,0x7e,0x40, +0xfa,0x00,0xfb,0x00,0x02,0x08,0x16,0x20,0xfa,0x00,0xfb,0xff,0x01,0xfe,0xdf, +0xf9,0xff,0xfb,0x00,0x02,0x3e,0xe7,0x80,0xfa,0x00,0xfc,0x00,0x03,0x02,0x37, +0x01,0xf0,0xfa,0x00,0xfb,0x00,0x02,0x3e,0xff,0x80,0xfa,0x00,0xfc,0x00,0x04, +0xc0,0x34,0x5f,0x20,0xf8,0xfb,0x00,0xfc,0xff,0x04,0x0f,0xf1,0x47,0x9f,0x07, +0xfb,0xff,0xfc,0x00,0x04,0xf0,0x25,0xb9,0x88,0xf8,0xfb,0x00,0xfc,0x00,0x04, +0xf7,0x4a,0x00,0x7e,0xf8,0xfb,0x00,0xfb,0x00,0x02,0x3d,0xff,0x88,0xfa,0x00, +0xfc,0x00,0x04,0x30,0x2c,0x85,0xc8,0x70,0xfb,0x00,0xfc,0xff,0x04,0xcf,0xf9, +0xdf,0x1f,0x8f,0xfb,0xff,0xfc,0x00,0x04,0x33,0x65,0x38,0x9e,0x70,0xfb,0x00, +0xfc,0x00,0x04,0x37,0xc2,0x00,0x3f,0x70,0xfb,0x00,0xfc,0x00,0x03,0x03,0x7d, +0xff,0x96,0xfa,0x00,0xfd,0x00,0x06,0x1e,0x06,0xfa,0xdb,0x57,0x01,0xc0,0xfc, +0x00,0xfd,0xff,0x06,0xe1,0xfd,0xf8,0xc3,0x2f,0xfe,0x3f,0xfc,0xff,0xfd,0x00, +0x06,0x1e,0x01,0xc7,0x3c,0xef,0x81,0xc0,0xfc,0x00,0xfd,0x00,0x06,0x1e,0x3f, +0x00,0x00,0x18,0x99,0xc0,0xfc,0x00,0xfc,0x00,0x04,0x01,0xff,0xff,0xef,0x80, +0xfb,0x00,0xfd,0x00,0x06,0x3e,0x00,0x83,0xbd,0xf0,0x22,0xe0,0xfc,0x00,0xfd, +0xff,0x06,0xc1,0xf9,0xdb,0x5a,0xc2,0xfc,0x1f,0xfc,0xff,0xfd,0x00,0x06,0x3e, +0x11,0x3c,0xe7,0x24,0x9b,0xe0,0xfc,0x00,0xfd,0x00,0x06,0x3e,0xfe,0x00,0x00, +0x09,0xdf,0xe0,0xfc,0x00,0xfc,0x00,0x04,0x11,0xff,0xff,0xe7,0x98,0xfb,0x00, +0xfd,0x00,0x05,0x06,0x03,0x81,0x4f,0x81,0x80,0xfb,0x00,0xfd,0xff,0x04,0xfb, +0xf8,0xdb,0x98,0xdb,0xfa,0xff,0xfd,0x00,0x05,0x04,0xf1,0x3c,0xa5,0x3c,0xf0, +0xfb,0x00,0xfd,0x00,0x01,0x07,0xfc,0xfe,0x00,0x00,0x7c,0xfb,0x00,0xfc,0x00, +0x04,0xf1,0xff,0xbd,0xff,0xf0,0xfb,0x00,0xfe,0x00,0x07,0x07,0x40,0xf4,0x00, +0x00,0x01,0xf4,0x1f,0xfc,0x00,0xfe,0xff,0x07,0xf8,0x3f,0xe0,0x00,0x00,0x01, +0xcf,0xe0,0xfc,0xff,0xfe,0x00,0x07,0x07,0xc1,0xa7,0xff,0xff,0xfe,0x68,0x1f, +0xfc,0x00,0xfe,0x00,0x02,0x07,0xf9,0x18,0xfe,0x00,0x01,0x1f,0x9f,0xfc,0x00, +0xfd,0x00,0x01,0x01,0xe7,0xfe,0xff,0x00,0xe0,0xfb,0x00,0xfe,0x00,0x07,0x06, +0x05,0x19,0xfc,0x81,0x0f,0x84,0x0f,0xfc,0x00,0xfe,0xff,0x07,0xf8,0x7f,0xc3, +0x1b,0xdb,0xd8,0xd3,0xf0,0xfc,0xff,0xfe,0x00,0x07,0x07,0x99,0x24,0xa7,0x3c, +0xe5,0x33,0x0f,0xfc,0x00,0xfe,0x00,0x01,0x07,0xba,0xfd,0x00,0x01,0x0f,0xcf, +0xfc,0x00,0xfd,0x00,0x05,0x19,0xe7,0xbf,0xff,0xfd,0xf3,0xfb,0x00,0xfe,0x00, +0x08,0x70,0x33,0xd9,0x19,0xc3,0x3d,0xd4,0xc8,0x30,0xfd,0x00,0xfe,0xff,0x08, +0x8f,0xff,0xc3,0xda,0xdb,0xda,0xcb,0xf7,0xcf,0xfd,0xff,0xfe,0x00,0x08,0x70, +0x0f,0x3c,0xe7,0x3c,0xe7,0x39,0xe8,0x30,0xfd,0x00,0xfe,0x00,0x01,0x73,0xbc, +0xfd,0x00,0x02,0x07,0x3a,0x30,0xfd,0x00,0xfd,0x00,0x00,0x0f,0xfd,0xff,0x01, +0xf9,0xe0,0xfc,0x00,0xfe,0x00,0x08,0xf0,0x27,0x5b,0x5a,0xcb,0x5a,0xd0,0xa0, +0x78,0xfd,0x00,0xfe,0xff,0x08,0x0f,0xcf,0x18,0x42,0x08,0x42,0x15,0xbf,0x87, +0xfd,0xff,0xfe,0x00,0x08,0xf1,0xcc,0xe7,0xbd,0xf7,0xbd,0xed,0x22,0x78,0xfd, +0x00,0xfe,0x00,0x01,0xf7,0xf0,0xfd,0x00,0x02,0x02,0x57,0x78,0xfd,0x00,0xfe, +0x00,0x01,0x01,0xcf,0xfd,0xff,0x01,0xfd,0xe2,0xfc,0x00,0xfe,0x00,0x08,0x30, +0x31,0x77,0x81,0x67,0x95,0x47,0xa0,0x60,0xfd,0x00,0xfe,0xff,0x08,0xcf,0xcb, +0x98,0xdb,0x98,0xcf,0x98,0xff,0x9f,0xfd,0xff,0xfe,0x00,0x08,0x33,0xcc,0xa5, +0x3c,0xa5,0x28,0xa5,0x12,0x60,0xfd,0x00,0xfe,0x00,0x01,0x37,0xe0,0xfc,0x00, +0x01,0x1f,0x60,0xfd,0x00,0xfe,0x00,0x07,0x03,0xcf,0xbd,0xff,0xbd,0xef,0xbd, +0xf2,0xfc,0x00,0x0b,0x00,0x00,0x04,0x07,0xd2,0xd3,0x5a,0xd3,0xda,0xca,0x7b, +0x80,0xfd,0x00,0x0a,0xff,0xff,0xfb,0xfc,0xa2,0x10,0x42,0x10,0xc2,0x08,0x7c, +0xfc,0xff,0x0a,0x00,0x00,0x04,0x00,0x3d,0xef,0xbd,0xef,0x3d,0xf7,0xbc,0xfc, +0x00,0x04,0x00,0x00,0x04,0x7f,0xc0,0xfc,0x00,0x01,0x07,0x80,0xfd,0x00,0xfd, +0x00,0x00,0x3f,0xfc,0xff,0x00,0xfc,0xfc,0x00,0x0b,0x00,0x00,0x06,0x05,0x99, +0xc3,0x9d,0xc3,0x1d,0xc7,0x9c,0x80,0xfd,0x00,0x0a,0xff,0xff,0xf9,0xf8,0x1a, +0xdb,0x5a,0xdb,0xda,0xdf,0x58,0xfc,0xff,0x0a,0x00,0x00,0x06,0x78,0x27,0x3c, +0xe7,0x3c,0xe7,0x38,0xe4,0xfc,0x00,0x04,0x00,0x00,0x06,0xfe,0x40,0xfc,0x00, +0x01,0x03,0xf0,0xfd,0x00,0xfe,0x00,0x01,0x78,0x3f,0xfc,0xff,0x00,0xfc,0xfc, +0x00,0x0c,0x00,0x00,0x06,0x00,0x86,0x81,0x57,0x85,0x4f,0x80,0x40,0x01,0x80, +0xfe,0x00,0x0c,0xff,0xff,0xf9,0xff,0x59,0xdb,0x98,0xdf,0x98,0xda,0x9a,0xfe, +0x7f,0xfe,0xff,0x0c,0x00,0x00,0x06,0xf7,0x65,0x3c,0xa5,0x38,0xa5,0x3d,0xa6, +0xf9,0x80,0xfe,0x00,0x03,0x00,0x00,0x07,0xf8,0xfb,0x00,0x02,0x01,0xfd,0x80, +0xfe,0x00,0xfe,0x00,0x08,0xf7,0x7d,0xff,0xbd,0xff,0xbd,0xff,0xbe,0xf8,0xfd, +0x00,0x04,0x00,0x00,0x06,0x16,0x05,0xfc,0x00,0x02,0xa6,0xe8,0x80,0xfe,0x00, +0x03,0xff,0xff,0xf9,0xe0,0xfb,0x00,0x02,0x3c,0xfe,0x7f,0xfe,0xff,0x03,0x00, +0x00,0x06,0xc7,0xfb,0xff,0x02,0xc3,0xed,0x80,0xfe,0x00,0x03,0x00,0x00,0x07, +0xf8,0xfa,0x00,0x01,0x15,0x80,0xfe,0x00,0xfe,0x00,0x00,0xc7,0xfa,0xff,0x00, +0xfc,0xfd,0x00,0x0c,0x00,0x00,0x06,0x22,0x53,0x6f,0x81,0x5f,0x95,0x5e,0x81, +0x32,0x80,0xfe,0x00,0x0c,0xff,0xff,0xf9,0xcb,0xcb,0x98,0xdb,0x98,0xcf,0x99, +0xff,0x0f,0x7f,0xfe,0xff,0x0c,0x00,0x00,0x06,0xcc,0x2c,0xa5,0x3c,0xa5,0x28, +0xa5,0x00,0x05,0x80,0xfe,0x00,0x03,0x00,0x00,0x07,0xf0,0xfa,0x00,0x01,0xff, +0x80,0xfe,0x00,0xfe,0x00,0x08,0xcf,0xef,0xbd,0xff,0xbd,0xef,0xbd,0xff,0xfc, +0xfd,0x00,0x0c,0x00,0x00,0x06,0x2c,0x04,0xb9,0xc3,0x99,0xc2,0x9d,0x80,0x38, +0x80,0xfe,0x00,0x0c,0xff,0xff,0xf9,0xd7,0xdf,0x5a,0xdb,0x5a,0xda,0x5a,0xff, +0x07,0x7f,0xfe,0xff,0x0c,0x00,0x00,0x06,0x58,0x38,0xe7,0x3c,0xe7,0x3d,0xe7, +0x00,0x05,0x80,0xfe,0x00,0x03,0x00,0x00,0x06,0xe0,0xfa,0x00,0x01,0xff,0x80, +0xfe,0x00,0xfe,0x00,0x00,0x5f,0xfa,0xff,0x00,0xfc,0xfd,0x00,0x0c,0x00,0x00, +0x06,0x28,0x34,0xba,0xdb,0x5a,0xdb,0x1d,0x00,0x1a,0x80,0xfe,0x00,0x0c,0xff, +0xff,0xfb,0xef,0xf7,0x82,0x18,0x42,0x18,0x01,0xf5,0x84,0x7f,0xfe,0xff,0x0c, +0x00,0x00,0x04,0x70,0x08,0x7d,0xe7,0xbd,0xe7,0xfe,0x00,0x07,0x80,0xfe,0x00, +0x03,0x00,0x00,0x07,0xc0,0xfb,0x00,0x02,0x0a,0x7f,0x80,0xfe,0x00,0xfe,0x00, +0x00,0x7f,0xfa,0xff,0x00,0xfc,0xfd,0x00,0x0c,0x00,0x00,0x04,0x20,0x00,0x11, +0x6f,0x91,0x6f,0x90,0x00,0x38,0x80,0xfe,0x00,0x0c,0xff,0xff,0xfb,0xff,0xff, +0xcb,0x98,0xcb,0x98,0xcb,0xc0,0x07,0x7f,0xfe,0xff,0x0c,0x00,0x00,0x04,0x60, +0x00,0x2c,0xa5,0x2c,0xa5,0x2c,0x00,0x05,0x80,0xfe,0x00,0x03,0x00,0x00,0x04, +0xc0,0xfb,0x00,0x02,0x3f,0xfd,0x80,0xfe,0x00,0xfe,0x00,0x08,0x7f,0xff,0xef, +0xbd,0xef,0xbd,0xef,0xff,0xfc,0xfd,0x00,0x0c,0x00,0x00,0x06,0x28,0x00,0x32, +0xeb,0x5a,0xd4,0x3c,0x00,0x30,0x80,0xfe,0x00,0x0c,0xff,0xff,0xfb,0xef,0xff, +0xea,0x08,0x42,0x12,0xe7,0xc0,0xc6,0x7f,0xfe,0xff,0x0c,0x00,0x00,0x04,0x70, +0x00,0x1d,0xf7,0xbd,0xef,0x18,0x00,0x05,0x80,0xfe,0x00,0x03,0x00,0x00,0x06, +0xc0,0xfb,0x00,0x02,0x3f,0xff,0x80,0xfe,0x00,0xfe,0x00,0x00,0x7f,0xfa,0xff, +0x00,0xfc,0xfd,0x00,0x0c,0x00,0x00,0x06,0x20,0x00,0x1d,0x43,0x9d,0xc2,0x18, +0x01,0xda,0x80,0xfe,0x00,0x0c,0xff,0xff,0xf9,0xcb,0xff,0xfa,0x5b,0x5a,0xdb, +0xf8,0x01,0x27,0x7f,0xfe,0xff,0x0c,0x00,0x00,0x06,0xcc,0x00,0x07,0xbc,0xe7, +0x3c,0x00,0x01,0x05,0x80,0xfe,0x00,0x03,0x00,0x00,0x07,0xf0,0xfc,0x00,0x03, +0x07,0xfe,0x3f,0x80,0xfe,0x00,0xfe,0x00,0x00,0xcf,0xfa,0xff,0x00,0xfc,0xfd, +0x00,0x0c,0x00,0x00,0x06,0x30,0x00,0x0f,0x01,0x67,0x80,0x00,0x00,0xf8,0x80, +0xfe,0x00,0x0c,0xff,0xff,0xf9,0xcb,0xff,0xf8,0xdb,0x98,0xdb,0xfc,0x01,0xe7, +0x7f,0xfe,0xff,0x0c,0x00,0x00,0x06,0xcc,0x00,0x05,0x3c,0xa5,0x3c,0x00,0x00, +0xc5,0x80,0xfe,0x00,0x03,0x00,0x00,0x07,0xe0,0xfc,0x00,0x03,0x03,0xff,0x3d, +0x80,0xfe,0x00,0xfe,0x00,0x04,0xcf,0xff,0xfd,0xff,0xbd,0xfe,0xff,0x00,0x3c, +0xfd,0x00,0x0b,0x00,0x00,0x04,0x04,0x00,0x06,0x0c,0x0b,0x30,0x00,0x05,0xe0, +0xfd,0x00,0x0c,0xff,0xff,0xfb,0xe7,0xff,0xfc,0xe0,0x00,0x07,0xb0,0x04,0xf5, +0x7f,0xfe,0xff,0x0c,0x00,0x00,0x04,0x78,0x00,0x03,0x1f,0xff,0xf8,0x00,0x06, +0xcf,0x80,0xfe,0x00,0x03,0x00,0x00,0x04,0xe0,0xfc,0x00,0x03,0x4f,0xf8,0x37, +0x80,0xfe,0x00,0xfe,0x00,0x00,0x7f,0xfb,0xff,0x01,0xfd,0x34,0xfd,0x00,0x0b, +0x00,0x00,0x06,0x30,0x00,0x02,0x0f,0x81,0x70,0x00,0x08,0xf4,0xfd,0x00,0x02, +0xff,0xff,0xfb,0xfe,0xff,0x06,0xf8,0xdb,0x9f,0x00,0x09,0xfd,0x7f,0xfe,0xff, +0x0c,0x00,0x00,0x04,0x60,0x00,0x00,0x05,0x3c,0xa0,0x00,0x0f,0xff,0x80,0xfe, +0x00,0x03,0x00,0x00,0x06,0xc0,0xfc,0x00,0x03,0xff,0xf0,0x07,0x80,0xfe,0x00, +0xfe,0x00,0x07,0x7f,0xff,0xff,0xfd,0xff,0xbf,0xff,0xf8,0xfc,0x00,0x03,0x00, +0x00,0x06,0x30,0xfe,0x00,0x05,0xc5,0x80,0x00,0x00,0xd9,0xe0,0xfe,0x00,0x02, +0xff,0xff,0xfb,0xfe,0xff,0x06,0xfb,0xdf,0x5e,0x00,0x23,0xdf,0x9f,0xfe,0xff, +0x0c,0x00,0x00,0x04,0x60,0x00,0x00,0x07,0x38,0xe0,0x00,0x07,0xdc,0x60,0xfe, +0x00,0x03,0x00,0x00,0x06,0xc0,0xfd,0x00,0x04,0x01,0xff,0xd8,0x03,0xe0,0xfe, +0x00,0xfe,0x00,0x00,0x7f,0xfb,0xff,0x01,0xf8,0x20,0xfd,0x00,0x0c,0x00,0x00, +0x06,0x0c,0x00,0x00,0x05,0xe8,0xa0,0x00,0x08,0xce,0x50,0xfe,0x00,0x0c,0xff, +0xff,0xfb,0xf7,0xff,0xff,0xfc,0x0f,0xb4,0x00,0x0b,0xcb,0x9f,0xfe,0xff,0x0c, +0x00,0x00,0x04,0x78,0x00,0x00,0x03,0xf0,0x40,0x00,0x0f,0xcb,0x60,0xfe,0x00, +0x03,0x00,0x00,0x07,0xe0,0xfd,0x00,0x04,0x0b,0xff,0xf0,0x03,0xf0,0xfe,0x00, +0xfe,0x00,0x00,0x7f,0xfb,0xff,0x01,0xf8,0x35,0xfd,0x00,0x07,0x00,0x00,0x06, +0x30,0x00,0x00,0x01,0x60,0xfe,0x00,0x01,0xc7,0x10,0xfe,0x00,0x03,0xff,0xff, +0xf9,0xcb,0xfe,0xff,0x05,0x9f,0xc0,0x00,0x03,0xc5,0x8f,0xfe,0xff,0x03,0x00, +0x00,0x06,0xcc,0xfe,0x00,0x05,0xa0,0x00,0x00,0x07,0xc1,0x70,0xfe,0x00,0x03, +0x00,0x00,0x07,0xe0,0xfd,0x00,0x04,0x3f,0xff,0xf8,0x05,0xf0,0xfe,0x00,0xfe, +0x00,0x00,0xcf,0xfe,0xff,0x04,0xbf,0xff,0xff,0xf8,0x3e,0xfd,0x00,0x0b,0x00, +0x00,0x09,0x28,0x00,0x00,0x01,0xc0,0x00,0x00,0x16,0x42,0xfd,0x00,0x0c,0xff, +0xff,0xf1,0xd1,0x00,0x17,0xff,0x1f,0xe0,0x00,0x15,0xc0,0xef,0xfe,0xff,0x03, +0x00,0x00,0x0e,0x5c,0xfe,0x00,0x05,0xe0,0x00,0x00,0x1f,0xc1,0x70,0xfe,0x00, +0x0c,0x00,0x00,0x0f,0xe2,0xff,0xe8,0x00,0x00,0x1f,0xff,0xe4,0x00,0xf0,0xfe, +0x00,0xfe,0x00,0x00,0x5f,0xfb,0xff,0x01,0xf0,0x3e,0xfd,0x00,0x0b,0x00,0x00, +0x02,0xb9,0xff,0xf3,0x00,0xc0,0x00,0x08,0xcf,0xa0,0xfd,0x00,0x0c,0xff,0xff, +0xf8,0xd8,0x00,0x03,0xff,0xfc,0x00,0x08,0x23,0x61,0xef,0xfe,0xff,0x05,0x00, +0x00,0x05,0x78,0x7f,0xa0,0xfd,0x00,0x02,0x1c,0xe1,0x70,0xfe,0x00,0x0c,0x00, +0x00,0x07,0xc7,0xff,0xfc,0x00,0x03,0xff,0xf7,0xe0,0x00,0xf0,0xfe,0x00,0xfe, +0x00,0x00,0x7f,0xfb,0xff,0x01,0xe0,0x1e,0xfd,0x00,0x05,0x00,0x00,0x38,0x67, +0xff,0xfe,0xfd,0x00,0x02,0xcf,0xa1,0xb0,0xfe,0x00,0x0c,0xff,0xff,0xc7,0xe0, +0x00,0x00,0xff,0xf8,0x00,0x00,0x37,0x61,0x8f,0xfe,0xff,0x05,0x00,0x00,0x38, +0x61,0xff,0xe0,0xfd,0x00,0x02,0x18,0xe1,0xd0,0xfe,0x00,0x0c,0x00,0x00,0x3b, +0xdf,0xff,0xff,0x00,0x07,0xff,0xff,0xe0,0x00,0xf0,0xfe,0x00,0xfe,0x00,0x00, +0x3f,0xfb,0xff,0x01,0xe0,0x1e,0xfd,0x00,0x0c,0x00,0x00,0x1a,0x1f,0xff,0xfe, +0x68,0x00,0x00,0x08,0x07,0xb1,0x1c,0xfe,0x00,0x0c,0xff,0xff,0xc6,0x20,0x00, +0x00,0x1f,0xf0,0x00,0x00,0x18,0x71,0x73,0xfe,0xff,0x06,0x00,0x00,0x2b,0xc7, +0xff,0xfd,0x80,0xfe,0x00,0x02,0x3f,0xf1,0xcc,0xfe,0x00,0x0c,0x00,0x00,0x3e, +0x3f,0xff,0xff,0xe0,0x0f,0xff,0xff,0xc0,0x00,0x7c,0xfe,0x00,0xfe,0x00,0x00, +0x3f,0xfb,0xff,0x02,0xc0,0x0e,0x40,0xfe,0x00,0x0c,0x00,0x00,0x05,0xff,0xff, +0xf8,0x28,0x00,0x00,0x38,0x00,0x10,0x80,0xfe,0x00,0x0c,0xff,0xff,0xdc,0x20, +0x00,0x00,0x0f,0xe0,0x00,0x00,0x3f,0xf0,0x33,0xfe,0xff,0x06,0x00,0x00,0x36, +0x1f,0xff,0xff,0xc0,0xfe,0x00,0x02,0x1f,0xf0,0x6c,0xfe,0x00,0x0c,0x00,0x00, +0x34,0x3f,0xff,0xff,0xf0,0x1f,0xff,0xff,0xe0,0x00,0x2c,0xfe,0x00,0x02,0x00, +0x00,0x01,0xfa,0xff,0x02,0xe0,0x0f,0xa0,0xfe,0x00,0x0c,0x00,0x01,0x2f,0xff, +0xff,0xf8,0x10,0x00,0x00,0x98,0x45,0x38,0xe4,0xfe,0x00,0x0c,0xff,0xfe,0x1c, +0xc0,0x00,0x00,0x03,0xc0,0x00,0x80,0x5a,0xf8,0xbb,0xfe,0xff,0x06,0x00,0x01, +0xec,0x3f,0xff,0xff,0xe0,0xfe,0x00,0x02,0x7f,0xf8,0x28,0xfe,0x00,0x02,0x00, +0x01,0xfc,0xfe,0xff,0x06,0xfc,0x3f,0xff,0x7f,0x80,0x00,0xac,0xfe,0x00,0x02, +0x00,0x00,0x03,0xfa,0xff,0x02,0xc0,0x07,0xc0,0xfe,0x00,0x0c,0x00,0x00,0x57, +0xff,0xff,0xfe,0xc4,0x40,0x00,0x01,0x07,0x98,0x40,0xfe,0x00,0x03,0xff,0xfe, +0xb1,0x80,0xfe,0x00,0x05,0x40,0x00,0x01,0x1a,0x78,0x5f,0xfe,0xff,0x0c,0x00, +0x01,0x98,0x67,0x1f,0xff,0xf8,0x00,0x00,0x01,0xfd,0xf8,0x6c,0xfe,0x00,0x02, +0x00,0x01,0xf1,0xfd,0xff,0x05,0xbf,0xff,0xfe,0x00,0x00,0x0c,0xfe,0x00,0x02, +0x00,0x00,0x07,0xfa,0xff,0x02,0x00,0x07,0x80,0xfe,0x00,0x02,0x00,0x07,0x2f, +0xfe,0xff,0x06,0xc2,0x00,0x00,0x01,0x0f,0xb8,0x04,0xfe,0x00,0x02,0xff,0xfe, +0x63,0xfb,0x00,0x03,0x01,0x77,0x78,0x3b,0xfe,0xff,0x0c,0x00,0x01,0xb0,0xc3, +0x1f,0xff,0xfc,0x00,0x00,0x01,0xf8,0xf8,0x28,0xfe,0x00,0x02,0x00,0x07,0xa3, +0xfb,0xff,0x03,0xfe,0x00,0x00,0x1c,0xfe,0x00,0x02,0x00,0x00,0x0f,0xfa,0xff, +0x02,0x00,0x07,0xc0,0xfe,0x00,0x02,0x00,0x06,0x5f,0xfe,0xff,0x06,0xc3,0x80, +0x00,0x00,0x1f,0x98,0x37,0xfe,0x00,0x02,0xff,0xf9,0xc6,0xfb,0x00,0x03,0x01, +0xe2,0x78,0x1e,0xfe,0xff,0x06,0x00,0x06,0x61,0xe6,0xaf,0xff,0xff,0xfe,0x00, +0x02,0xfd,0xf8,0x11,0xfe,0x00,0x02,0x00,0x07,0xc7,0xfa,0xff,0x02,0x00,0x00, +0x1f,0xfe,0x00,0x02,0x00,0x00,0x1f,0xfa,0xff,0x02,0x00,0x07,0xe0,0xfe,0x00, +0x02,0x00,0x08,0xbb,0xfe,0xff,0x09,0x18,0x88,0x08,0xc3,0x3c,0x38,0x2a,0x80, +0x00,0x00,0x02,0xff,0xf1,0x8c,0xfd,0x00,0x08,0x08,0x08,0x00,0xdb,0xf8,0x2e, +0x7f,0xff,0xff,0x06,0x00,0x0e,0xc3,0x18,0xc7,0xff,0xff,0xfe,0x00,0x05,0xe7, +0xf8,0x39,0x80,0x00,0x00,0x02,0x00,0x0f,0x8f,0xfd,0xff,0x08,0xf7,0xf7,0xff, +0x00,0x00,0x0f,0x80,0x00,0x00,0x02,0x00,0x00,0x3f,0xfa,0xff,0x02,0x00,0x07, +0xc0,0xfe,0x00,0x01,0x00,0x0e,0xfd,0xff,0x06,0x18,0xc0,0x00,0xe6,0x7c,0x1c, +0x31,0xfe,0x00,0x02,0xff,0xf1,0x98,0xfb,0x00,0x06,0x01,0x9b,0xfc,0x24,0x7f, +0xff,0xff,0x0f,0x00,0x0a,0x87,0x18,0x63,0xff,0xff,0x80,0x00,0x00,0xe7,0xfc, +0x0e,0x80,0x00,0x00,0x02,0x00,0x0f,0x9f,0xfa,0xff,0x05,0x00,0x00,0x27,0x80, +0x00,0x00,0x02,0x00,0x00,0x7f,0xfa,0xff,0x02,0x00,0x03,0xf4,0xfe,0x00,0x01, +0x00,0x08,0xfd,0xff,0x06,0xa5,0x30,0x08,0x08,0xf8,0x3a,0x0c,0xfe,0x00,0x02, +0xff,0xf7,0x90,0xfb,0x00,0x06,0x04,0x27,0xfa,0x07,0x7f,0xff,0xff,0x0f,0x00, +0x0e,0x8c,0x08,0x41,0xff,0xff,0xc0,0x00,0x03,0xdf,0xfa,0x07,0x80,0x00,0x00, +0x02,0x00,0x0f,0x9f,0xfb,0xff,0x06,0xfc,0x00,0x00,0x07,0x80,0x00,0x00,0x02, +0x00,0x00,0x7f,0xfb,0xff,0x03,0xfc,0x00,0x05,0xf8,0xfe,0x00,0x02,0x00,0x0c, +0xdf,0xfe,0xff,0x09,0xc7,0x31,0x38,0x31,0xe0,0x9f,0x0c,0x80,0x00,0x00,0x02, +0xff,0xf1,0xa0,0xfd,0x00,0x08,0x01,0x00,0x0e,0xdf,0x7f,0x0d,0x7f,0xff,0xff, +0x0c,0x00,0x0a,0x98,0x00,0x00,0xff,0xff,0xe0,0x00,0x03,0x3f,0xff,0x0f,0xfe, +0x00,0x02,0x00,0x0f,0xbf,0xfd,0xff,0x08,0xfe,0xff,0xfc,0x00,0x00,0x07,0x80, +0x00,0x00,0x02,0x00,0x00,0x7f,0xfb,0xff,0x03,0xfc,0x00,0x00,0xf0,0xfe,0x00, +0x02,0x00,0x31,0x3f,0xfe,0xff,0x09,0xe2,0x04,0x98,0x19,0xf0,0x1f,0x01,0xa0, +0x00,0x00,0x02,0xff,0xcf,0x40,0xfd,0x00,0x08,0x08,0x80,0x02,0x4f,0xff,0x07, +0xdf,0xff,0xff,0x0f,0x00,0x31,0xbc,0x00,0x00,0x7f,0xff,0xf0,0x00,0x07,0xbf, +0xff,0x04,0x20,0x00,0x00,0x02,0x00,0x33,0x7f,0xfc,0xff,0x07,0x7f,0xf8,0x00, +0x00,0x03,0xa0,0x00,0x00,0x02,0x00,0x00,0x7f,0xfb,0xff,0x03,0xf8,0x00,0x00, +0xf8,0xfe,0x00,0x0f,0x00,0x06,0x7f,0xf8,0xff,0xff,0xfc,0x09,0x00,0x60,0xfc, +0x02,0x0e,0x40,0x00,0x00,0x02,0xff,0xce,0x80,0xfd,0x00,0x08,0x0d,0x00,0x03, +0x03,0xfe,0x0b,0x9f,0xff,0xff,0x0f,0x00,0x37,0x43,0x00,0x03,0x1f,0xff,0xe0, +0x00,0x07,0xff,0xfe,0x0b,0x60,0x00,0x00,0x01,0x00,0x36,0xfc,0xff,0x08,0xee, +0xff,0xf8,0x00,0x00,0x03,0x60,0x00,0x00,0x01,0x00,0x00,0xfc,0xff,0x05,0xef, +0xff,0xf8,0x00,0x01,0xf5,0xfe,0x00,0x0f,0x00,0x46,0xff,0xf8,0x7f,0xff,0xf8, +0x05,0x00,0xc8,0x3c,0x07,0x07,0x30,0x00,0x00,0x01,0xff,0xcd,0xfc,0x00,0x08, +0x05,0x00,0x0b,0xdb,0xff,0x05,0x9f,0xff,0xff,0x0f,0x00,0x34,0xe7,0x00,0x07, +0x1f,0xff,0xc0,0x00,0x0f,0xe7,0xff,0x01,0x40,0x00,0x00,0x01,0x00,0x7d,0xfc, +0xff,0x08,0xc6,0xff,0xf0,0x00,0x00,0x05,0xf0,0x00,0x00,0x01,0x00,0x03,0xfc, +0xff,0x05,0xc7,0xff,0xf8,0x00,0x00,0xfe,0xfe,0x00,0x0f,0x00,0x47,0xff,0xe0, +0x5f,0xff,0xf4,0x04,0x01,0x80,0xfc,0x0f,0x02,0x10,0x00,0x00,0x01,0xff,0xdd, +0xfa,0x00,0x06,0x13,0x3b,0xff,0x00,0xef,0xff,0xff,0x0f,0x00,0x34,0xe2,0x00, +0x02,0x7f,0xff,0xc0,0x00,0x0f,0xc7,0xff,0x01,0x70,0x00,0x00,0x01,0x00,0x7d, +0xfc,0xff,0x02,0xc7,0xff,0xf0,0xfe,0x00,0x02,0xf0,0x00,0x00,0x01,0x00,0x03, +0xfc,0xff,0x05,0xc7,0xff,0xf0,0x00,0x00,0xfe,0xfe,0x00,0x0f,0x00,0x43,0xff, +0xe0,0x1f,0xff,0xe3,0x07,0xc3,0x21,0xfc,0x1f,0xc1,0x10,0x00,0x00,0x01,0xff, +0xd9,0xfc,0x00,0x05,0x04,0x00,0x2e,0x7b,0xff,0xc0,0xfe,0xff,0x0f,0x00,0x34, +0xf8,0x00,0x00,0xff,0xff,0xc0,0x00,0x3f,0x87,0xff,0xc0,0x60,0x00,0x00,0x01, +0x00,0x79,0xfc,0xff,0x02,0xc7,0xff,0xc0,0xfe,0x00,0x02,0xf0,0x00,0x00,0x01, +0x00,0x03,0xfc,0xff,0x05,0xc7,0xff,0xe0,0x00,0x00,0x3f,0xfe,0x00,0x0f,0x00, +0x43,0xff,0xe0,0x1f,0xff,0xc7,0x03,0xc7,0x01,0xfc,0x1f,0xe1,0xf8,0x00,0x00, +0x01,0xff,0xd9,0xfa,0x00,0x06,0x1e,0xfb,0xff,0xe1,0xd7,0xff,0xff,0x0f,0x00, +0x34,0xfc,0x00,0x00,0x7f,0xff,0xe4,0x00,0x3f,0x07,0xff,0xe1,0x88,0x00,0x00, +0x01,0x00,0x79,0xfc,0xff,0x02,0xe7,0xff,0xc0,0xfe,0x00,0x02,0xf8,0x00,0x00, +0x01,0x00,0x03,0xfc,0xff,0x05,0xe7,0xff,0xc0,0x00,0x00,0x1e,0xfe,0x00,0x0f, +0x00,0x23,0xff,0xd0,0x3f,0xff,0x94,0x07,0x18,0x0f,0xfc,0x0f,0xe1,0x0c,0x00, +0x00,0x01,0xff,0xdf,0xfa,0x00,0x06,0x32,0x3b,0xff,0xe1,0x73,0xff,0xff,0x0f, +0x00,0x14,0xf2,0x00,0x03,0x5f,0xff,0xec,0x00,0x1d,0xc7,0xff,0xe1,0xcc,0x00, +0x00,0x01,0x00,0x3b,0xfc,0xff,0x02,0xef,0xff,0xe0,0xfe,0x00,0x02,0x6c,0x00, +0x00,0x01,0x00,0x03,0xfc,0xff,0x08,0xef,0xff,0xe0,0x00,0x00,0x1e,0x40,0x00, +0x00,0x0f,0x00,0x65,0x7f,0xf8,0x7f,0xff,0x18,0x03,0x38,0xcf,0x3c,0x07,0xc0, +0x80,0x00,0x00,0x01,0xff,0x99,0xfa,0x00,0x06,0x33,0xdb,0xff,0xc0,0x33,0xff, +0xff,0x0f,0x00,0x50,0xc7,0x00,0x07,0x1f,0xff,0xfe,0x00,0x1c,0xe7,0xff,0xc0, +0x6c,0x00,0x00,0x01,0x00,0x79,0xfa,0xff,0x00,0xe0,0xfe,0x00,0x02,0x3c,0x00, +0x00,0x01,0x00,0x07,0xfa,0xff,0x06,0xe0,0x00,0x00,0x3f,0xa0,0x00,0x00,0x0f, +0x00,0x46,0x7f,0xf8,0xff,0xff,0x38,0x03,0x94,0x87,0xfc,0x03,0xe0,0xe4,0x00, +0x00,0x01,0xff,0xba,0xfa,0x00,0x06,0x5c,0x1b,0xff,0xe0,0xbb,0xff,0xff,0x0f, +0x00,0x71,0xe3,0x00,0x05,0x3f,0xff,0xff,0x00,0x3b,0xe7,0xff,0xe0,0x28,0x00, +0x00,0x01,0x00,0x7b,0xfa,0xff,0x00,0xc0,0xfe,0x00,0x02,0xac,0x00,0x00,0x01, +0x00,0x07,0xfa,0xff,0x06,0xc0,0x00,0x00,0x1f,0xc0,0x00,0x00,0x01,0x00,0x04, +0xfd,0xff,0x09,0xc6,0x01,0xc2,0x03,0xfc,0x18,0xc0,0x64,0x00,0x00,0x01,0xff, +0xf8,0xfb,0x00,0x07,0x01,0xbc,0x7b,0xff,0xc0,0x5b,0xff,0xff,0x0f,0x00,0x3b, +0xf8,0x00,0x1c,0x7f,0xff,0xff,0x00,0x7f,0x87,0xff,0xc0,0x68,0x00,0x00,0x01, +0x00,0x3b,0xfa,0xff,0x00,0x80,0xfe,0x00,0x02,0x0c,0x00,0x00,0x01,0x00,0x0f, +0xfa,0xff,0x06,0x80,0x00,0x00,0x3f,0x80,0x00,0x00,0x02,0x00,0x08,0x7f,0xfe, +0xff,0x09,0xc7,0x00,0xc6,0x01,0xfc,0x38,0xe0,0x0c,0x00,0x00,0x01,0xff,0xfc, +0xfb,0x00,0x07,0x01,0xfe,0xf3,0xff,0xe0,0x13,0xff,0xff,0x04,0x00,0x3b,0xfc, +0x00,0x38,0xfe,0xff,0x07,0x00,0xff,0x0f,0xff,0xe0,0x20,0x00,0x00,0x01,0x00, +0x3f,0xfa,0xff,0xfd,0x00,0x02,0x1c,0x00,0x00,0x01,0x00,0x07,0xfa,0xff,0xfe, +0x00,0x03,0x1f,0xc0,0x00,0x00,0x01,0x00,0x40,0xfd,0xff,0x09,0xa4,0x00,0x02, +0x03,0xf8,0x15,0xd0,0x37,0x80,0x00,0x01,0xff,0xbc,0xfb,0x00,0x07,0x81,0x7c, +0xe7,0xff,0xd0,0x3e,0xff,0xff,0x0f,0x00,0x73,0xfc,0x00,0x21,0xff,0xff,0xf9, +0x00,0xff,0x1f,0xff,0xd0,0x31,0x00,0x00,0x01,0x00,0x7f,0xfc,0xff,0x01,0xf9, +0xff,0xfd,0x00,0x02,0x1f,0x80,0x00,0x01,0x00,0x07,0xfc,0xff,0x01,0xf9,0xff, +0xfe,0x00,0x03,0x2f,0xc0,0x00,0x00,0x02,0x00,0x4c,0x7f,0xfe,0xff,0x09,0x18, +0x00,0x99,0x07,0xf0,0x07,0xf8,0x2a,0x80,0x00,0x01,0xff,0xbc,0xfb,0x00,0x07, +0x01,0x7b,0xcf,0xff,0xf8,0x0e,0x7f,0xff,0x0f,0x00,0x7b,0xfe,0x18,0xc7,0xff, +0xff,0xf8,0x01,0xfc,0x3f,0xff,0xf8,0x19,0x80,0x00,0x01,0x00,0x7f,0xfc,0xff, +0x01,0xf8,0xfe,0xfd,0x00,0x02,0x0f,0x80,0x00,0x01,0x00,0x07,0xfc,0xff,0x01, +0xf9,0xff,0xfe,0x00,0x03,0x07,0xe0,0x00,0x00,0x01,0x00,0x00,0xfd,0xff,0x09, +0x18,0x00,0x19,0x0f,0xf0,0x03,0xf8,0x30,0x80,0x00,0x01,0xff,0xfc,0xfb,0x00, +0x07,0x81,0xf7,0xcf,0xff,0xf8,0x25,0x7f,0xff,0x0f,0x00,0x33,0xff,0x1c,0xe3, +0xff,0xff,0xf8,0x01,0xf8,0x3f,0xff,0xf8,0x0f,0x80,0x00,0x01,0x00,0x3f,0xfc, +0xff,0x01,0xf8,0xfe,0xfd,0x00,0x02,0x27,0x80,0x00,0x01,0x00,0x07,0xfc,0xff, +0x01,0xf8,0xff,0xfe,0x00,0x03,0x07,0xf4,0x00,0x00,0x01,0x00,0x08,0xfe,0xff, +0x0a,0xfc,0x60,0x00,0x84,0x3f,0xfc,0x21,0xf8,0x1c,0x00,0x00,0x01,0xff,0xfc, +0xfb,0x00,0x07,0x04,0xcf,0xe3,0xdf,0xf8,0x17,0x7f,0xff,0x0f,0x00,0x3b,0xff, +0xe1,0x0f,0xff,0xff,0xfd,0x07,0xf0,0x1f,0xff,0xf8,0x07,0x80,0x00,0x01,0x00, +0x3f,0xfc,0xff,0x01,0xfd,0xf8,0xfd,0x00,0x02,0x17,0x80,0x00,0x01,0x00,0x07, +0xfc,0xff,0x01,0xfd,0xfc,0xfe,0x00,0x03,0x07,0xf8,0x00,0x00,0x0f,0x00,0x40, +0x7f,0xff,0xff,0xf8,0xe0,0x00,0xc0,0x3f,0xfc,0x00,0xf8,0x1c,0x00,0x00,0x01, +0xff,0xbc,0xfb,0x00,0x07,0x03,0xdf,0xfb,0xff,0xf8,0x15,0x7f,0xff,0x04,0x00, +0x73,0xff,0xc7,0x1f,0xfe,0xff,0x07,0x07,0xe0,0x07,0xff,0xf8,0x07,0x80,0x00, +0x01,0x00,0x7f,0xfb,0xff,0x00,0xf8,0xfd,0x00,0x02,0x17,0x80,0x00,0x01,0x00, +0x07,0xfb,0xff,0x00,0xf8,0xfe,0x00,0x03,0x07,0xf8,0x00,0x00,0x0f,0x00,0x4c, +0x7f,0xff,0xff,0xf8,0xc0,0x01,0xc0,0xff,0xf8,0x01,0x7c,0x0c,0xf0,0x00,0x01, +0xff,0xb8,0xfb,0x00,0x07,0x03,0x1f,0xf7,0xff,0xfc,0x0a,0x9f,0xff,0x04,0x00, +0x7b,0xff,0xe7,0x3f,0xfe,0xff,0x07,0x07,0xe0,0x0f,0xff,0xfc,0x01,0x60,0x00, +0x01,0x00,0x7b,0xfb,0xff,0x00,0xf8,0xfd,0x00,0x02,0x0b,0xf0,0x00,0x01,0x00, +0x07,0xfb,0xff,0x00,0xf8,0xfe,0x00,0x03,0x03,0xcc,0x00,0x00,0x02,0x00,0x04, +0x3f,0xfe,0xff,0x09,0x38,0x03,0x19,0xef,0xf0,0x07,0x1f,0x06,0x10,0x00,0x01, +0xff,0xf8,0xfb,0x00,0x07,0x02,0x53,0xcf,0xff,0xff,0x07,0x9f,0xff,0x01,0x00, +0x31,0xfb,0xff,0x07,0x07,0xbc,0x3f,0xff,0xff,0x02,0x60,0x00,0x01,0x00,0x39, +0xfb,0xff,0x00,0xf8,0xfd,0x00,0x02,0x07,0x70,0x00,0x01,0x00,0x07,0xfb,0xff, +0x00,0xf8,0xfd,0x00,0x02,0xec,0x00,0x00,0x0f,0x00,0x22,0x1f,0xff,0xff,0xfe, +0x18,0x07,0x15,0xe7,0xe0,0x27,0x3f,0x05,0x10,0x00,0x01,0xff,0xda,0xfb,0x00, +0x07,0x0a,0xdb,0xdf,0xdf,0xff,0x05,0x8f,0xff,0x01,0x00,0x14,0xfc,0xff,0x08, +0xfe,0x03,0x3c,0x3f,0xff,0xff,0x03,0x70,0x00,0x01,0x00,0x3a,0xfb,0xff,0x00, +0xf8,0xfd,0x00,0x02,0x05,0xf0,0x00,0x01,0x00,0x03,0xfb,0xff,0x00,0xfc,0xfd, +0x00,0x02,0xc4,0x00,0x00,0x0f,0x00,0x62,0x1f,0xff,0xff,0xbe,0xb0,0x03,0x21, +0xff,0xf8,0x00,0x7f,0x03,0x10,0x00,0x01,0xff,0xde,0xfb,0x00,0x07,0x1e,0x07, +0xe7,0xff,0xff,0x03,0xef,0xff,0x01,0x00,0x14,0xfc,0xff,0x08,0xce,0x07,0xf8, +0x1f,0xff,0xff,0x01,0x70,0x00,0x01,0x00,0x7a,0xfc,0xff,0x01,0xcf,0xf8,0xfd, +0x00,0x02,0x03,0xf0,0x00,0x01,0x00,0x03,0xfc,0xff,0x01,0xcf,0xf8,0xfd,0x00, +0x02,0xee,0x00,0x00,0x0f,0x00,0x63,0x1f,0xff,0xff,0x18,0xc0,0x07,0xc0,0x3f, +0xfc,0x01,0xff,0x02,0x50,0x00,0x01,0xff,0xd9,0xfc,0x00,0x08,0x04,0x2f,0xdf, +0xfb,0xff,0xff,0x02,0xaf,0xff,0x02,0x00,0x14,0x7f,0xfd,0xff,0x08,0xe0,0x1f, +0xe0,0x07,0xff,0xff,0x01,0x30,0x00,0x02,0x00,0x79,0x7f,0xfd,0xff,0x01,0xe7, +0xe0,0xfd,0x00,0x02,0x02,0xf0,0x00,0x02,0x00,0x03,0x7f,0xfd,0xff,0x01,0xe7, +0xe0,0xfd,0x00,0x02,0xfe,0x00,0x00,0x0f,0x00,0x47,0x1f,0xff,0xfe,0x18,0xe0, +0x07,0xc8,0x7f,0xfc,0x00,0xff,0x01,0xf0,0x00,0x01,0xff,0x8d,0xfc,0x00,0x08, +0x04,0x17,0x9f,0xf3,0xff,0xff,0x01,0xcf,0xff,0x01,0x00,0x74,0xfc,0xff,0x08, +0xc0,0x3f,0xe0,0x0f,0xff,0xff,0x00,0x90,0x00,0x01,0x00,0x7d,0xfc,0xff,0x01, +0xc7,0xc0,0xfd,0x00,0x02,0x01,0xf0,0x00,0x01,0x00,0x03,0xfc,0xff,0x01,0xc7, +0xc0,0xfd,0x00,0x02,0xfb,0x00,0x00,0x0f,0x00,0x47,0x3c,0xff,0x3c,0x63,0x80, +0x06,0xc0,0xff,0xf8,0x03,0x38,0x01,0x3c,0x00,0x01,0xff,0xdd,0xfb,0x00,0x07, +0x3f,0x3f,0xe7,0xff,0xf8,0x01,0x73,0xff,0x01,0x00,0x34,0xfc,0xff,0x08,0xc0, +0x1f,0xc0,0x1f,0xff,0xf8,0x00,0x8c,0x00,0x01,0x00,0x7d,0xfc,0xff,0x01,0xc7, +0xe0,0xfd,0x00,0x02,0x01,0x7c,0x00,0x01,0x00,0x03,0xfc,0xff,0x01,0xc7,0xe0, +0xfe,0x00,0x03,0x07,0xf9,0x00,0x00,0x0f,0x00,0x45,0x1c,0xff,0x18,0xc7,0x00, +0x07,0xc1,0xff,0xe0,0x26,0x18,0x00,0xc2,0x00,0x01,0xff,0xcd,0xfc,0x00,0x08, +0x04,0x3e,0xff,0xdf,0xdf,0xf8,0x00,0xf3,0xff,0x01,0x00,0x36,0xfc,0xff,0x08, +0xc0,0x1f,0x00,0x3f,0xff,0xf8,0x00,0x6c,0x00,0x01,0x00,0x75,0xfc,0xff,0x01, +0xc7,0xe0,0xfc,0x00,0x01,0xee,0x00,0x01,0x00,0x01,0xfc,0xff,0x01,0xc7,0xe0, +0xfe,0x00,0x03,0x07,0xf9,0xa0,0x00,0x0f,0x00,0x22,0x80,0x7e,0x19,0xe6,0x00, +0x03,0x8f,0xff,0xf0,0x07,0x3c,0x00,0x44,0x00,0x02,0xff,0xce,0x80,0xfc,0x00, +0x07,0x50,0x7f,0x8f,0xff,0xfc,0x00,0x5b,0xff,0x02,0x00,0x33,0x7f,0xfd,0xff, +0x08,0xbe,0x3f,0x80,0x7f,0xff,0xfc,0x00,0x28,0x00,0x01,0x00,0x36,0xfc,0xff, +0x01,0xbf,0xc0,0xfc,0x00,0x01,0x5c,0x00,0x01,0x00,0x00,0xfc,0xff,0x01,0xbf, +0xc0,0xfe,0x00,0x03,0x03,0xfc,0xc0,0x00,0x0f,0x00,0x20,0x63,0x3c,0xe3,0x18, +0x00,0x38,0xef,0xbf,0xbc,0x00,0xff,0x00,0x26,0x00,0x02,0xff,0xdf,0x20,0xfd, +0x00,0x08,0x30,0x13,0x5e,0x5b,0xff,0xff,0x00,0x13,0xff,0x02,0x00,0x21,0x87, +0xfd,0xff,0x05,0x07,0x7c,0xe1,0xe7,0xff,0xff,0xfe,0x00,0x02,0x00,0x23,0x27, +0xfd,0xff,0x00,0x3f,0xfb,0x00,0x01,0x1e,0x00,0x02,0x00,0x01,0x67,0xfd,0xff, +0x01,0x3f,0x80,0xfd,0x00,0x02,0xfe,0x60,0x00,0x0f,0x00,0x0c,0x03,0x18,0xc7, +0x18,0x00,0x3d,0x87,0x3f,0x3c,0x00,0xff,0x00,0x22,0x00,0x02,0xff,0xf1,0x80, +0xfd,0x00,0x08,0x21,0x7a,0xde,0xdb,0xff,0xff,0x00,0x15,0xff,0x02,0x00,0x0a, +0xc7,0xfe,0xff,0x09,0xfe,0x06,0x7d,0xe1,0xe7,0xff,0xff,0x00,0x06,0x00,0x02, +0x00,0x0f,0x87,0xfe,0xff,0x01,0xfe,0x3f,0xfb,0x00,0x01,0x1e,0x00,0x02,0x00, +0x00,0xa7,0xfe,0xff,0x02,0xfe,0x3f,0x80,0xfd,0x00,0x02,0xff,0x20,0x00,0x0f, +0x00,0x0a,0xe1,0xaa,0xaa,0x10,0x00,0x31,0x99,0xff,0xf8,0x01,0x7d,0x80,0x62, +0x00,0x02,0xff,0xf5,0xa0,0xfd,0x00,0x08,0x2e,0x7e,0x7b,0x07,0xff,0xfd,0x80, +0x5b,0xff,0x02,0x00,0x0c,0x87,0xfe,0xff,0x09,0xfd,0x00,0x7f,0x84,0xff,0xff, +0xfd,0x80,0x0c,0x00,0x02,0x00,0x0f,0xa7,0xfe,0xff,0x03,0xfd,0x3e,0x00,0x04, +0xfd,0x00,0x01,0x5e,0x00,0x02,0x00,0x00,0x7f,0xfe,0xff,0x02,0xfd,0x7f,0x80, +0xfe,0x00,0x03,0x02,0x78,0x60,0x00,0x0f,0x00,0x08,0xf8,0xe7,0x1c,0x00,0x00, +0xf7,0x7e,0xff,0xe0,0x27,0x18,0xc0,0xe0,0x00,0x02,0xff,0xf1,0x98,0xfd,0x00, +0x08,0xe7,0x3f,0x7f,0xdf,0xdf,0xf8,0xc0,0xbb,0xff,0x02,0x00,0x0e,0x87,0xfe, +0xff,0x09,0xfc,0x0f,0xbf,0x80,0x3f,0xff,0xf8,0xc0,0x2c,0x00,0x02,0x00,0x0f, +0x9f,0xfe,0xff,0x01,0xfc,0xe7,0xfb,0x00,0x01,0xac,0x00,0x02,0x00,0x00,0x7f, +0xfe,0xff,0x02,0xfd,0xf0,0x40,0xfe,0x00,0x03,0x07,0x31,0xc0,0x00,0x0f,0x00, +0x08,0xbc,0x43,0x18,0x00,0x00,0xe9,0xbf,0x7f,0xf2,0x03,0x30,0xe1,0x94,0x00, +0x02,0xff,0xf3,0x8c,0xfd,0x00,0x08,0x8f,0x8f,0xf7,0xcd,0xff,0xf0,0xe1,0x73, +0xff,0x02,0x00,0x0c,0xc3,0xfe,0xff,0x09,0xf8,0x1a,0xcf,0x88,0x3f,0xff,0xf0, +0xc0,0x4c,0x00,0x02,0x00,0x0d,0x8f,0xfe,0xff,0x02,0xf8,0x8b,0x80,0xfd,0x00, +0x02,0x21,0x7c,0x00,0x02,0x00,0x00,0x3f,0xfe,0xff,0x02,0xfb,0xe0,0x30,0xfe, +0x00,0x03,0x0f,0x3b,0xc0,0x00,0x0f,0x00,0x0e,0x6f,0x02,0x00,0x00,0x03,0x91, +0x7f,0xb3,0xfe,0xb0,0x61,0x3e,0x18,0x00,0x02,0xff,0xf9,0xe7,0xfe,0x00,0x09, +0x03,0x1a,0xf0,0xfc,0x39,0x4f,0xe1,0x38,0xf7,0xff,0x0f,0x00,0x06,0x70,0xbf, +0xff,0xff,0xe0,0x76,0x78,0xff,0xc7,0xff,0xe0,0x01,0x88,0x00,0x08,0x00,0x0f, +0xe7,0xbf,0xff,0xff,0xe3,0x1f,0xf0,0xfe,0x00,0x03,0x01,0x38,0xd8,0x00,0x08, +0x00,0x00,0x0f,0xbf,0xff,0xff,0xe7,0x80,0x07,0xfe,0x00,0x03,0x1f,0xfe,0x80, +0x00,0x02,0x00,0x00,0xae,0xfe,0x00,0x09,0x03,0xa0,0x67,0xf8,0x3c,0x00,0xc7, +0xf0,0x00,0x00,0x02,0xff,0xfe,0x62,0xfe,0x00,0x09,0x02,0x33,0x8c,0xff,0xdb, +0xff,0xc1,0xe5,0xff,0xff,0x0f,0x00,0x01,0x30,0x1f,0xff,0xff,0xc0,0x6c,0x54, +0xff,0xe7,0xff,0xc0,0x0f,0x00,0x00,0x08,0x00,0x01,0xa2,0x1f,0xff,0xff,0xc2, +0x3c,0x7c,0xfe,0x00,0x03,0x01,0xe7,0x00,0x00,0x08,0x00,0x00,0x0f,0x1f,0xff, +0xff,0xc7,0x80,0x03,0xfe,0x00,0x03,0x3f,0xf4,0x00,0x00,0x02,0x00,0x00,0x53, +0xfe,0x00,0x09,0x06,0x40,0x4a,0x45,0x87,0xbf,0xdd,0xc4,0x20,0x00,0x02,0xff, +0xfe,0xb1,0xfe,0x00,0x09,0x04,0x6b,0x3e,0xba,0xff,0xff,0xd8,0x08,0x9f,0xff, +0x0f,0x00,0x01,0x9c,0x0a,0xff,0xfd,0x41,0xfc,0xb7,0xba,0xff,0xff,0x92,0x30, +0xe0,0x00,0x08,0x00,0x01,0xf1,0x0a,0xff,0xfd,0x44,0x7c,0xfe,0xfe,0x00,0x03, +0x48,0x0f,0xe0,0x00,0x0f,0x00,0x00,0x03,0x8a,0xff,0xfd,0x5e,0x20,0x04,0x45, +0x00,0x00,0x6d,0xc0,0x00,0x00,0x0f,0x00,0x01,0x63,0xe0,0x00,0x00,0x1e,0x94, +0xc0,0xfb,0xfc,0xe0,0xfc,0xe6,0x40,0x00,0x0f,0xff,0xfe,0x38,0x60,0x00,0x00, +0x1c,0xe3,0x0f,0xf9,0xfc,0xe0,0xf7,0xf8,0x3f,0xff,0x0f,0x00,0x01,0xcc,0x00, +0xff,0xf8,0x01,0x9c,0xf2,0xbd,0xfc,0xe0,0x47,0xe5,0xc0,0x00,0x0f,0x00,0x01, +0xe8,0x60,0xff,0xf8,0x1c,0xdc,0xf7,0xb8,0x00,0x00,0xb7,0xff,0xc0,0x00,0x0c, +0x00,0x00,0x0b,0xe0,0xff,0xf8,0x1e,0x00,0x02,0x02,0x03,0x1f,0xbb,0xfe,0x00, +0x0f,0x00,0x00,0x44,0x20,0x00,0x00,0x21,0x30,0x06,0x05,0xf9,0xe1,0xe8,0x6c, +0x00,0x00,0x0f,0xff,0xff,0xcc,0x20,0x00,0x00,0x21,0x8f,0xf8,0x3c,0xf9,0xe1, +0x8d,0x83,0xff,0xff,0x0f,0x00,0x00,0x37,0xc0,0xff,0xfc,0x1f,0x50,0x07,0xf6, +0xf9,0xe1,0x1b,0x9c,0x00,0x00,0x0f,0x00,0x00,0x74,0x20,0xff,0xfc,0x21,0xf0, +0x07,0xfc,0x00,0x00,0x8f,0xfc,0x00,0x00,0xfe,0x00,0x09,0x30,0xff,0xfc,0x20, +0x00,0x00,0x01,0x06,0x1e,0xe0,0xfe,0x00,0x0f,0x00,0x00,0x4b,0x10,0x00,0x00, +0x72,0x50,0x0b,0x8b,0x50,0x04,0x70,0x14,0x00,0x00,0x0f,0xff,0xff,0xd7,0xd0, +0x00,0x00,0x5f,0x8f,0xf0,0x7f,0x2f,0xfe,0x7f,0xe3,0xff,0xff,0x0f,0x00,0x00, +0x3b,0xe0,0x40,0x10,0x1f,0x30,0x0c,0x77,0xff,0xff,0xfb,0xec,0x00,0x00,0x0f, +0x00,0x00,0x7f,0xd0,0x40,0x10,0x5f,0xf0,0x0f,0xff,0x00,0x00,0x7b,0xfc,0x00, +0x00,0xfe,0x00,0x09,0xdb,0x40,0x15,0xed,0x00,0x00,0x04,0x00,0x00,0x08,0xfe, +0x00,0x0f,0x00,0x00,0x39,0xbf,0x80,0x0f,0xcc,0x60,0x09,0xf8,0x00,0x00,0x01, +0xf0,0x00,0x00,0xfe,0xff,0x0c,0x67,0x80,0x0f,0x93,0x9f,0xfe,0x5f,0xff,0xff, +0xfe,0x1f,0xff,0xff,0xfe,0x00,0x0c,0xa0,0x20,0x00,0x2c,0x60,0x01,0xa0,0x00, +0x00,0x01,0xe0,0x00,0x00,0x0f,0x00,0x00,0x39,0xe7,0xa0,0x0f,0x9e,0x60,0x09, +0xfb,0xff,0xff,0xf1,0xf0,0x00,0x00,0xfe,0x00,0x03,0x1f,0xe0,0x1f,0xc0,0xf8, +0x00,0x0c,0x00,0x00,0x0c,0x11,0xc0,0x3c,0x43,0x80,0x00,0x01,0x7f,0xf0,0x74, +0xfe,0x00,0x0c,0xff,0xff,0xf9,0xb0,0x40,0x30,0x7c,0x7f,0xff,0xf8,0x80,0x0f, +0x83,0xfe,0xff,0x0c,0x00,0x00,0x07,0xde,0x00,0x03,0xcd,0x80,0x00,0x06,0x80, +0x0f,0x8c,0xfe,0x00,0x0c,0x00,0x00,0x0f,0xf0,0x40,0x30,0x6f,0x80,0x00,0x07, +0xff,0xff,0xfc,0xfe,0x00,0xfe,0x00,0x02,0x01,0xff,0xfc,0xf7,0x00,0x0c,0x00, +0x00,0x04,0x43,0xdf,0xcf,0x01,0x80,0x00,0x04,0x2f,0xfe,0x0c,0xfe,0x00,0x0c, +0xff,0xff,0xf8,0x3f,0xc0,0x0f,0xf0,0x7f,0xff,0xf8,0x00,0x00,0x03,0xfe,0xff, +0x0c,0x00,0x00,0x07,0xcf,0xe0,0x3f,0xcf,0x80,0x00,0x07,0xd0,0x01,0xfc,0xfe, +0x00,0x0c,0x00,0x00,0x07,0xdf,0xc0,0x0f,0xef,0x80,0x00,0x07,0xff,0xff,0xfc, +0xfe,0x00,0xfe,0x00,0x03,0x0c,0x1f,0xc0,0xc0,0xf8,0x00,0x0c,0x00,0x00,0x01, +0x2b,0x20,0x03,0xe3,0x00,0x00,0x01,0xfd,0x11,0xf0,0xfe,0x00,0x06,0xff,0xff, +0xfe,0xf4,0xcf,0xfc,0x1d,0xfe,0xff,0x02,0xfb,0xee,0x4f,0xfe,0xff,0x06,0x00, +0x00,0x01,0x0b,0x30,0x03,0xe2,0xfe,0x00,0x02,0x04,0x11,0xb0,0xfe,0x00,0x0c, +0x00,0x00,0x01,0x2b,0x30,0x03,0xe3,0x00,0x00,0x01,0xfd,0x11,0xf0,0xfe,0x00, +0xf1,0x00,0xfe,0x00,0x03,0x28,0x00,0x01,0x90,0xf8,0x00,0xfe,0xff,0x03,0xc7, +0xe0,0x7e,0x1f,0xf8,0xff,0xfe,0x00,0x03,0x37,0xe0,0x7e,0x60,0xf8,0x00,0xfe, +0x00,0x03,0x3f,0xff,0xff,0xf0,0xf8,0x00,0xf1,0x00,0xfe,0x00,0x03,0x3e,0x20, +0xb1,0x60,0xf8,0x00,0xfe,0xff,0x03,0xc0,0x00,0x40,0x1f,0xf8,0xff,0xfe,0x00, +0x03,0x3f,0xdf,0x4f,0xe0,0xf8,0x00,0xfe,0x00,0x03,0x3f,0xff,0xff,0xe0,0xf8, +0x00,0xf1,0x00,0xfd,0x00,0x00,0x0e,0xf6,0x00,0xfd,0xff,0x00,0xf1,0xf6,0xff, +0xfd,0x00,0x00,0x0e,0xf6,0x00,0xfd,0x00,0x00,0x0e,0xf6,0x00,0xf1,0x00,0xf1, +0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00, +0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1, +0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00, +0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1, +0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00, +0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1, +0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00, +0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1, +0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00, +0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1, +0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00, +0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1, +0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00, +0xf1,0x00,0xf1,0x00, }; + +//---------------------------------------------------------------------------- + +static const ULONG icon96_colors[96] = +{ + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, + 0xc8c8c8c8,0xd5d5d5d5,0xe9e9e9e9, + 0x66666666,0x60606060,0x61616161, + 0xa9a9a9a9,0xaaaaaaaa,0xedededed, + 0xe0e0e0e0,0xe0e0e0e0,0xe8e8e8e8, + 0x8c8c8c8c,0x95959595,0xd2d2d2d2, + 0x79797979,0x85858585,0xbcbcbcbc, + 0xc0c0c0c0,0xcacacaca,0xeaeaeaea, + 0xb9b9b9b9,0xbcbcbcbc,0xc5c5c5c5, + 0x4f4f4f4f,0x64646464,0x91919191, + 0x9c9c9c9c,0xa2a2a2a2,0xadadadad, + 0xcdcdcdcd,0xdadadada,0xefefefef, + 0xc2c2c2c2,0xcacacaca,0xd7d7d7d7, + 0x7e7e7e7e,0x81818181,0x86868686, + 0xc8c8c8c8,0xd6d6d6d6,0xebebebeb, + 0xc9c9c9c9,0xd8d8d8d8,0xedededed, + 0xd0d0d0d0,0xdfdfdfdf,0xf4f4f4f4, + 0x26262626,0x3e3e3e3e,0x59595959, + 0xd7d7d7d7,0xe8e8e8e8,0xfbfbfbfb, + 0xf5f5f5f5,0xf6f6f6f6,0xf3f3f3f3, + 0xf8f8f8f8,0xf4f4f4f4,0x87878787, + 0xf0f0f0f0,0xe8e8e8e8,0x24242424, + 0xfcfcfcfc,0xfafafafa,0xd1d1d1d1, + 0xd1d1d1d1,0xcacacaca,0x88888888, + 0xd4d4d4d4,0xd2d2d2d2,0xcccccccc, + 0xe1e1e1e1,0xb2b2b2b2,0x42424242, + 0xc2c2c2c2,0x8f8f8f8f,0x64646464, + 0xdbdbdbdb,0x6b6b6b6b,0x3d3d3d3d, + 0x8b8b8b8b,0x0a0a0a0a,0x0a0a0a0a, + 0xd8d8d8d8,0x32323232,0x32323232, + 0xffffffff,0xffffffff,0xffffffff, +}; + +#define ICON96_WIDTH 96 +#define ICON96_HEIGHT 96 +#define ICON96_DEPTH 5 +#define ICON96_COMPRESSION 1 +#define ICON96_MASKING 0 + +static const struct BitMapHeader icon96_header = +{ 96,96,0,0,5,0,1,0,0,1,1,96,96 }; + +static const UBYTE icon96_body[4226] = { +0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff,0xf5, +0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5,0x00, +0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff,0xf5, +0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5,0x00, +0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff,0xf5, +0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5,0x00, +0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff,0xf5, +0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5,0x00, +0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xfc,0x00,0x00,0x3c,0xfb, +0x00,0xf5,0xff,0xfc,0x00,0x00,0x3c,0xfb,0x00,0xfc,0x00,0x00,0x3c,0xfb,0x00, +0xf5,0x00,0xfc,0x00,0x00,0x3c,0xfb,0x00,0xf5,0xff,0xfc,0x00,0x00,0x3c,0xfb, +0x00,0xfc,0x00,0x00,0x3c,0xfb,0x00,0xf5,0x00,0xfd,0x00,0x02,0x02,0x36,0xc0, +0xfc,0x00,0xfd,0xff,0x01,0xfe,0x46,0xfb,0xff,0xfd,0x00,0x02,0x02,0x36,0xc0, +0xfc,0x00,0xfd,0x00,0x02,0x02,0x3e,0xc0,0xfc,0x00,0xfd,0x00,0x01,0x01,0x81, +0xfb,0x00,0xfd,0x00,0x02,0x01,0x3c,0x40,0xfc,0x00,0xfc,0xff,0x01,0x42,0x7f, +0xfc,0xff,0xfd,0x00,0x02,0x01,0x2c,0x40,0xfc,0x00,0xfd,0x00,0x02,0x01,0x3c, +0x40,0xfc,0x00,0xfc,0x00,0x01,0x81,0x80,0xfc,0x00,0xfd,0x00,0x02,0x24,0xf2, +0x44,0xfc,0x00,0xfd,0xff,0x02,0xe4,0x00,0x27,0xfc,0xff,0xfd,0x00,0x02,0x24, +0xe0,0x44,0xfc,0x00,0xfd,0x00,0x02,0x27,0xdf,0xc4,0xfc,0x00,0xfd,0x00,0x02, +0x18,0x1e,0x18,0xfc,0x00,0xfd,0x00,0x02,0x23,0x90,0xc4,0xfc,0x00,0xfd,0xff, +0x02,0xe4,0x5c,0x27,0xfc,0xff,0xfd,0x00,0x02,0x22,0x3c,0x44,0xfc,0x00,0xfd, +0x00,0x02,0x23,0x83,0xc4,0xfc,0x00,0xfd,0x00,0x02,0x18,0x3e,0x18,0xfc,0x00, +0xfe,0x00,0x04,0x02,0x24,0xfc,0xf2,0xc0,0xfd,0x00,0xfe,0xff,0x03,0xfe,0x40, +0x20,0x02,0xfc,0xff,0xfe,0x00,0x04,0x02,0x20,0x7c,0x72,0xc0,0xfd,0x00,0xfe, +0x00,0x04,0x02,0x3f,0x83,0xbe,0xc0,0xfd,0x00,0xfe,0x00,0x03,0x01,0x87,0xbf, +0x81,0xfc,0x00,0xfe,0x00,0x04,0x02,0x30,0x4c,0xbc,0x40,0xfd,0x00,0xfe,0xff, +0x04,0xfe,0x43,0x7f,0x82,0x7f,0xfd,0xff,0xfe,0x00,0x04,0x02,0x13,0xff,0xe4, +0x40,0xfd,0x00,0xfe,0x00,0x04,0x02,0x3c,0x00,0x3c,0x40,0xfd,0x00,0xfe,0x00, +0x04,0x01,0x87,0xff,0xc1,0x80,0xfd,0x00,0xfe,0x00,0x04,0x24,0xf3,0xff,0xf2, +0xc4,0xfd,0x00,0xfe,0xff,0x04,0xe4,0x04,0x00,0x40,0x27,0xfd,0xff,0xfe,0x00, +0x04,0x24,0xe3,0xff,0xe0,0xc4,0xfd,0x00,0xfe,0x00,0x04,0x27,0xdc,0x00,0x1f, +0xc4,0xfd,0x00,0xfe,0x00,0x04,0x18,0x1f,0xff,0xde,0x18,0xfd,0x00,0xfe,0x00, +0x04,0x33,0x93,0x33,0x11,0xc0,0xfd,0x00,0xfe,0xff,0x04,0xf4,0x5f,0xff,0xdc, +0x27,0xfd,0xff,0xfe,0x00,0x04,0x32,0x3f,0xff,0xfd,0xc0,0xfd,0x00,0xfe,0x00, +0x04,0x33,0x80,0x00,0x03,0xc0,0xfd,0x00,0xfe,0x00,0x04,0x08,0x3f,0xff,0xfe, +0x18,0xfd,0x00,0xfe,0x00,0x05,0x24,0xff,0xff,0xfc,0xf6,0x40,0xfe,0x00,0x08, +0xff,0xff,0xfc,0x40,0x22,0x00,0x00,0x06,0x7f,0xfe,0xff,0xfe,0x00,0x05,0x20, +0x7f,0xff,0xfc,0x36,0x40,0xfe,0x00,0xfe,0x00,0x05,0x3f,0x80,0x00,0x03,0xbe, +0x40,0xfe,0x00,0x08,0x00,0x00,0x03,0x87,0xbf,0xff,0xff,0xc1,0x80,0xfe,0x00, +0x07,0x00,0x00,0x02,0x30,0x4c,0xdd,0xc4,0x3c,0xfd,0x00,0x08,0xff,0xff,0xfe, +0x43,0x7f,0xee,0xf7,0x02,0x7f,0xfe,0xff,0x03,0x00,0x00,0x02,0x23,0xfe,0xff, +0x00,0xe4,0xfd,0x00,0x03,0x00,0x00,0x02,0x3c,0xfe,0x00,0x00,0x3c,0xfd,0x00, +0x03,0x00,0x00,0x01,0x87,0xfe,0xff,0x01,0xc1,0x80,0xfe,0x00,0x03,0x00,0x00, +0x23,0xf3,0xfe,0xff,0x01,0xf2,0xcc,0xfe,0x00,0x03,0xff,0xff,0xe4,0x04,0xfe, +0x00,0x01,0x40,0x2f,0xfe,0xff,0x03,0x00,0x00,0x23,0xe3,0xfe,0xff,0x01,0xe2, +0xcc,0xfe,0x00,0x03,0x00,0x00,0x23,0xdc,0xfe,0x00,0x01,0x1f,0xcc,0xfe,0x00, +0x03,0x00,0x00,0x18,0x1f,0xfe,0xff,0x01,0xdc,0x10,0xfe,0x00,0x03,0x00,0x00, +0x1b,0x93,0xfe,0x33,0x01,0x30,0xc8,0xfe,0x00,0x03,0xff,0xff,0xfc,0x5f,0xfe, +0xff,0x01,0xfc,0x2f,0xfe,0xff,0x03,0x00,0x00,0x1a,0x3f,0xfe,0xff,0x01,0xfc, +0x48,0xfe,0x00,0x03,0x00,0x00,0x1b,0x80,0xfe,0x00,0x01,0x03,0xc8,0xfe,0x00, +0xfe,0x00,0x00,0x3f,0xfe,0xff,0x01,0xfe,0x10,0xfe,0x00,0x02,0x00,0x00,0x9f, +0xfd,0xff,0x01,0xfc,0xc0,0xfe,0x00,0x08,0xff,0xff,0xe0,0x00,0x02,0x00,0x20, +0x00,0x2f,0xfe,0xff,0x02,0x00,0x00,0x9f,0xfd,0xff,0x01,0xfc,0x80,0xfe,0x00, +0x02,0x00,0x00,0x9c,0xfd,0x00,0x01,0x03,0x10,0xfe,0x00,0xfe,0x00,0x00,0x3f, +0xfd,0xff,0x00,0x40,0xfe,0x00,0x08,0x00,0x01,0x3d,0xcc,0x44,0x5d,0xc5,0xc4, +0x9d,0xfe,0x00,0x08,0xff,0xff,0x40,0x7f,0x77,0x6e,0xf6,0xf7,0xa3,0xfe,0xff, +0x03,0x00,0x01,0x22,0x7f,0xfd,0xff,0x00,0xcd,0xfe,0x00,0x02,0x00,0x01,0x3c, +0xfc,0x00,0x00,0x1d,0xfe,0x00,0x03,0x00,0x00,0x86,0x7f,0xfd,0xff,0x00,0xc0, +0xfe,0x00,0x02,0x00,0x01,0xf7,0xfd,0xff,0x04,0xfc,0xcb,0x80,0x00,0x00,0x03, +0xff,0xff,0x8a,0x04,0xfe,0x00,0x01,0x0b,0x08,0xfe,0xff,0x02,0x00,0x01,0xc7, +0xfc,0xff,0x03,0xc2,0x80,0x00,0x00,0x02,0x00,0x01,0xf0,0xfc,0x00,0x03,0x3e, +0x80,0x00,0x00,0x02,0x00,0x00,0x13,0xfc,0xff,0x00,0xfd,0xfe,0x00,0x03,0x00, +0x01,0x34,0x7b,0xfe,0x33,0x01,0x10,0x07,0xfe,0x00,0x03,0xff,0xff,0x47,0xb7, +0xfe,0xff,0x04,0xdf,0xf4,0x7f,0xff,0xff,0x02,0x00,0x01,0x0f,0xfc,0xff,0x00, +0xca,0xfe,0x00,0x02,0x00,0x01,0x30,0xfc,0x00,0x00,0x3e,0xfe,0x00,0x02,0x00, +0x00,0x9f,0xfc,0xff,0x03,0xfd,0x80,0x00,0x00,0x03,0x00,0x01,0x7c,0x33,0xfe, +0xff,0x01,0xf0,0x07,0xfe,0x00,0x0b,0xff,0xff,0x03,0xcd,0x00,0x00,0x02,0x2f, +0xf4,0x7f,0xff,0xff,0x02,0x00,0x01,0x6f,0xfc,0xff,0x00,0xea,0xfe,0x00,0x02, +0x00,0x01,0x70,0xfc,0x00,0x00,0x1e,0xfe,0x00,0x02,0x00,0x00,0x9f,0xfc,0xff, +0x03,0xfd,0x80,0x00,0x00,0x03,0x00,0x01,0x60,0x00,0xfe,0xdd,0x04,0xc0,0x07, +0x40,0x00,0x00,0x0b,0xff,0xff,0x4f,0xff,0x6e,0xee,0xee,0xff,0xf4,0x7f,0xff, +0xff,0x0b,0x00,0x01,0x67,0xff,0x7f,0xff,0xff,0xfc,0x08,0x40,0x00,0x00,0x02, +0x00,0x01,0x78,0xfd,0x00,0x04,0x03,0xfe,0x40,0x00,0x00,0x04,0x00,0x00,0x9f, +0xff,0x7f,0xfd,0xff,0x02,0x80,0x00,0x00,0x0b,0x00,0x01,0xb8,0x00,0xff,0xff, +0xfc,0xc0,0x36,0x40,0x00,0x00,0x0b,0xff,0xff,0x87,0xff,0x44,0x00,0x0b,0x3f, +0xf4,0x7f,0xff,0xff,0x02,0x00,0x01,0xaf,0xfd,0xff,0x04,0xf8,0x08,0x40,0x00, +0x00,0x02,0x00,0x01,0xf0,0xfd,0x00,0x04,0x07,0xfe,0x40,0x00,0x00,0x02,0x00, +0x00,0x1f,0xfb,0xff,0x02,0x80,0x00,0x00,0x08,0x00,0x01,0xb4,0x00,0x73,0x33, +0x30,0x00,0x57,0xfe,0x00,0x04,0xff,0xff,0xc7,0xff,0xbf,0xfe,0xff,0x03,0xf4, +0x7f,0xff,0xff,0x02,0x00,0x01,0x9f,0xfd,0xff,0x01,0xc0,0x0a,0xfe,0x00,0x02, +0x00,0x01,0xb0,0xfd,0x00,0x01,0x3f,0xee,0xfe,0x00,0x02,0x00,0x00,0x0f,0xfc, +0xff,0x03,0xcd,0x80,0x00,0x00,0x08,0x00,0x01,0xbc,0x00,0x33,0xff,0xf0,0x00, +0x07,0xfe,0x00,0x0b,0xff,0xff,0xcb,0xff,0xcd,0x02,0x2f,0xff,0x7d,0x7f,0xff, +0xff,0x02,0x00,0x01,0x8f,0xfd,0xff,0x01,0xc0,0x48,0xfe,0x00,0x02,0x00,0x01, +0xb0,0xfd,0x00,0x01,0x3f,0xfe,0xfe,0x00,0x02,0x00,0x00,0x1f,0xfc,0xff,0x03, +0x87,0x80,0x00,0x00,0x08,0x00,0x01,0xa0,0x00,0x00,0x44,0x40,0x00,0xc5,0xfe, +0x00,0x0b,0xff,0xff,0xcf,0xff,0xff,0x77,0x7f,0xfe,0xfd,0x7f,0xff,0xff,0x02, +0x00,0x01,0xaf,0xfe,0xff,0x02,0xfc,0x00,0x44,0xfe,0x00,0x02,0x00,0x01,0xb0, +0xfe,0x00,0x02,0x03,0xff,0xba,0xfe,0x00,0x02,0x00,0x00,0x1f,0xfc,0xff,0x03, +0x01,0x80,0x00,0x00,0x0b,0x00,0x01,0x38,0x00,0x00,0xfc,0xc0,0x01,0xc3,0x20, +0x00,0x00,0x0b,0xff,0xff,0x07,0xff,0xff,0x4b,0x3f,0xff,0xfe,0xbf,0xff,0xff, +0x02,0x00,0x01,0x2f,0xfe,0xff,0x05,0xf8,0x06,0xc1,0x20,0x00,0x00,0x02,0x00, +0x01,0x70,0xfe,0x00,0x05,0x07,0xf9,0x37,0x20,0x00,0x00,0x02,0x00,0x00,0x9f, +0xfc,0xff,0x03,0x08,0x40,0x00,0x00,0x0b,0x00,0x01,0xb4,0x00,0x00,0x40,0x00, +0x01,0xc1,0xc0,0x00,0x00,0x05,0xff,0xff,0xc7,0xff,0xff,0x8f,0xfe,0xff,0x02, +0x1f,0xff,0xff,0x02,0x00,0x01,0x9f,0xfe,0xff,0x05,0xc0,0x00,0xc2,0x80,0x00, +0x00,0x02,0x00,0x01,0xb0,0xfe,0x00,0x05,0x3f,0xff,0x33,0x80,0x00,0x00,0x02, +0x00,0x00,0x0f,0xfc,0xff,0x03,0x0c,0x60,0x00,0x00,0x0b,0x00,0x01,0xbc,0x00, +0x00,0x30,0x00,0x03,0x22,0x40,0x00,0x00,0x0b,0xff,0xff,0x0f,0xff,0xff,0xcf, +0xff,0xff,0x7f,0xdf,0xff,0xff,0x0b,0x00,0x01,0x4c,0x00,0x7f,0xff,0xc0,0x00, +0xe1,0x20,0x00,0x00,0x0b,0x00,0x01,0x73,0xff,0x80,0x00,0x3f,0xff,0x11,0x20, +0x00,0x00,0x02,0x00,0x00,0xbf,0xfd,0xff,0x04,0xfe,0x0c,0x40,0x00,0x00,0x02, +0x00,0x01,0x70,0xfd,0x00,0x04,0x06,0x00,0xc0,0x00,0x00,0x0b,0xff,0xff,0x46, +0xff,0x3f,0xff,0xff,0xf7,0x3f,0x5f,0xff,0xff,0x0b,0x00,0x01,0x61,0xff,0xdf, +0xfc,0x00,0x0b,0xe0,0xa0,0x00,0x00,0x0b,0x00,0x01,0x7f,0xff,0xe0,0x03,0xff, +0xfc,0x11,0xa0,0x00,0x00,0x02,0x00,0x00,0x9f,0xfd,0xff,0x04,0xfc,0x0e,0x40, +0x00,0x00,0x0b,0x00,0x03,0xe0,0x00,0x10,0x00,0x00,0x06,0x10,0xc8,0x00,0x00, +0x04,0xff,0xf9,0x73,0xff,0xa7,0xfd,0xff,0x02,0xaf,0xff,0xff,0x0b,0x00,0x01, +0x1f,0xff,0xfb,0xf8,0x00,0x03,0xf0,0x48,0x00,0x00,0x0b,0x00,0x01,0xff,0xff, +0xfc,0x07,0xff,0xfc,0x09,0xc8,0x00,0x00,0x02,0x00,0x06,0x0f,0xfd,0xff,0x04, +0xfc,0x06,0x10,0x00,0x00,0x0b,0x00,0x03,0x90,0x00,0x3c,0x00,0x00,0x07,0xb0, +0x70,0x00,0x00,0x0b,0xff,0xf8,0xff,0xff,0xc1,0xff,0xff,0x3f,0xff,0xc7,0xff, +0xff,0x0b,0x00,0x05,0x6f,0xff,0xff,0xf0,0x00,0xc3,0xf0,0xa0,0x00,0x00,0x0b, +0x00,0x05,0xef,0xff,0xfe,0x0f,0xff,0xfc,0x08,0xe0,0x00,0x00,0x02,0x00,0x02, +0x0f,0xfd,0xff,0x04,0xfc,0x07,0x18,0x00,0x00,0x0b,0x00,0x0b,0x60,0x00,0x3e, +0x00,0x00,0x06,0x10,0x90,0x00,0x00,0x04,0xff,0xe1,0xf7,0x7f,0xc0,0xfd,0xff, +0x02,0xf7,0xff,0xff,0x0b,0x00,0x02,0x9f,0xff,0xff,0x70,0x00,0x03,0xf0,0x48, +0x00,0x00,0x0b,0x00,0x03,0x9f,0xff,0xff,0x8f,0xff,0xfc,0x0c,0x48,0x00,0x00, +0x02,0x00,0x1c,0x1f,0xfd,0xff,0x04,0xf8,0x03,0x10,0x00,0x00,0x0b,0x00,0x0e, +0xc0,0x00,0x03,0x00,0x00,0x0e,0x10,0x30,0x00,0x00,0x0b,0xff,0xe3,0xf3,0x3f, +0xfc,0x3f,0xff,0xef,0x3f,0xd7,0xff,0xff,0x0b,0x00,0x05,0x3f,0xff,0xff,0xc0, +0x00,0x0f,0xf0,0x28,0x00,0x00,0x02,0x00,0x07,0x3f,0xfd,0xff,0x04,0xf0,0x0c, +0x68,0x00,0x00,0x02,0x00,0x18,0x3f,0xfd,0xff,0x04,0xf0,0x03,0x90,0x00,0x00, +0x0b,0x00,0x4d,0x80,0x00,0x07,0x80,0x00,0x1c,0x10,0x36,0x00,0x00,0x0b,0xff, +0xd7,0xd0,0x1f,0xf8,0x1f,0xff,0xfe,0x7f,0xef,0xff,0xff,0x0b,0x00,0x42,0x7f, +0xff,0xff,0xe0,0x00,0x0f,0xf0,0x16,0x00,0x00,0x02,0x00,0x4e,0x7f,0xfd,0xff, +0x04,0xf0,0x0c,0x76,0x00,0x00,0x02,0x00,0x20,0x7f,0xfd,0xff,0x04,0xf0,0x03, +0x80,0x00,0x00,0x0b,0x00,0x3b,0x00,0x00,0x0c,0xc0,0x00,0x08,0x70,0x1c,0x00, +0x00,0x0b,0xff,0x8f,0xcc,0xcf,0xf3,0x1f,0xfc,0xcc,0xff,0xe1,0xff,0xff,0x01, +0x00,0x54,0xfe,0xff,0x06,0xe0,0x03,0x3f,0xf0,0x28,0x00,0x00,0x01,0x00,0x5c, +0xfc,0xff,0x04,0xf0,0x0c,0x38,0x00,0x00,0x01,0x00,0x20,0xfc,0xff,0x04,0xf0, +0x03,0xc6,0x00,0x00,0x0b,0x00,0x2a,0x00,0x00,0x0d,0x60,0x00,0x30,0xf0,0x04, +0x00,0x00,0x0b,0xff,0xaf,0x80,0x87,0xf2,0x9f,0xff,0xb9,0xff,0xf5,0xff,0xff, +0x01,0x00,0x45,0xfe,0xff,0x06,0xf0,0x00,0x4f,0xf0,0x12,0x00,0x00,0x01,0x00, +0x5d,0xfc,0xff,0x04,0xf0,0x0e,0x1a,0x00,0x00,0x01,0x00,0x21,0xfc,0xff,0x04, +0xe0,0x01,0xe4,0x00,0x00,0x0b,0x00,0x38,0x00,0x00,0x03,0x30,0x00,0x63,0xd0, +0x0c,0x00,0x00,0x0b,0xff,0x8f,0x00,0x03,0xfc,0xc7,0xcf,0x73,0xff,0xf5,0xff, +0xff,0x01,0x00,0x17,0xfe,0xff,0x06,0xf8,0x30,0xbf,0xf0,0x0a,0x00,0x00,0x01, +0x00,0x1f,0xfc,0xff,0x04,0xc0,0x0f,0x1a,0x00,0x00,0x01,0x00,0x63,0xfc,0xff, +0x04,0xc0,0x00,0xe4,0x00,0x00,0x0b,0x01,0x38,0x00,0x00,0x01,0x7c,0x00,0x60, +0xf8,0x0c,0x80,0x00,0x0b,0xff,0x5c,0x03,0x00,0xfe,0x87,0xfe,0xff,0xff,0xfa, +0xff,0xff,0x0b,0x01,0x07,0xfc,0xff,0xff,0xf9,0x01,0x3f,0xf8,0x04,0x80,0x00, +0x01,0x01,0x3f,0xfe,0xff,0x06,0xfa,0xff,0xc0,0x07,0x1c,0x80,0x00,0x01,0x00, +0x8f,0xfe,0xff,0x06,0xfb,0xff,0xc0,0x00,0xe1,0x00,0x00,0x01,0x00,0xe0,0xfe, +0x00,0x06,0xf3,0x00,0x38,0x74,0x07,0x00,0x00,0x0b,0xfe,0x3c,0xc3,0x8c,0xff, +0x02,0xfc,0xfc,0xff,0xfc,0x7f,0xff,0x0b,0x01,0x5f,0xfc,0x7f,0xff,0xf1,0x03, +0x3f,0xfc,0x0a,0x00,0x00,0x01,0x01,0x7f,0xfe,0xff,0x06,0xf2,0xff,0xc0,0x03, +0x0e,0x00,0x00,0x01,0x00,0x8f,0xfe,0xff,0x06,0xf3,0xff,0xc0,0x00,0xf1,0x80, +0x00,0x01,0x00,0x90,0xfe,0x00,0x06,0xe0,0x00,0xf0,0x7c,0x09,0x00,0x00,0x0b, +0xfe,0x3e,0x0f,0xc0,0xff,0x01,0xfb,0xf8,0xff,0xff,0x7f,0xff,0x0b,0x01,0x2f, +0xf0,0x3f,0xff,0xe2,0x04,0x3f,0xfc,0x04,0x80,0x00,0x01,0x01,0x6f,0xfe,0xff, +0x06,0xe3,0xff,0xc0,0x03,0x84,0x80,0x00,0x01,0x00,0x8f,0xfe,0xff,0x06,0xe3, +0xff,0x80,0x00,0x71,0x00,0x00,0x0b,0x00,0xd0,0x00,0x00,0x03,0x30,0x01,0xe0, +0xd0,0x03,0x00,0x00,0x0b,0xfe,0xbf,0x0f,0xc3,0xfc,0xc4,0x33,0xf0,0xff,0xfd, +0x7f,0xff,0x0b,0x01,0x2f,0xf0,0x3f,0xff,0xf3,0xcc,0x7f,0xf0,0x02,0x80,0x00, +0x01,0x01,0x6f,0xfe,0xff,0x06,0xf3,0xff,0x80,0x0f,0xc6,0x80,0x00,0x01,0x00, +0x8f,0xfe,0xff,0x06,0xf7,0xff,0x00,0x00,0x39,0x00,0x00,0x0b,0x00,0xd0,0x00, +0x00,0x06,0xb4,0x11,0x80,0x78,0x03,0x20,0x00,0x0b,0xfe,0xbe,0x8f,0xc5,0xf9, +0x42,0xff,0xe8,0xff,0xfe,0xff,0xff,0x0b,0x01,0x4f,0xf0,0x3f,0xff,0xf7,0x00, +0xff,0xf8,0x01,0x20,0x00,0x01,0x01,0x6f,0xfe,0xff,0x06,0xf7,0xff,0x00,0x07, +0xc7,0x20,0x00,0x01,0x00,0x8f,0xfe,0xff,0x06,0xf7,0xff,0x00,0x00,0x38,0x00, +0x00,0x0b,0x00,0xe0,0x00,0x00,0x0c,0xfc,0x01,0x88,0x7c,0x01,0xe0,0x00,0x0b, +0xfe,0xbc,0xc3,0x0c,0xf3,0x02,0xcd,0xcc,0xff,0xff,0x3f,0xff,0x02,0x01,0x0f, +0xfc,0xfe,0xff,0x05,0x32,0xff,0xfc,0x02,0xa0,0x00,0x01,0x01,0x4f,0xfc,0xff, +0x04,0x00,0x03,0xc3,0xa0,0x00,0x01,0x00,0x9f,0xfc,0xff,0x04,0x00,0x00,0x3c, +0x40,0x00,0x0b,0x00,0xf0,0x00,0x80,0x0b,0x7e,0x02,0x80,0x7f,0x02,0x40,0x00, +0x0b,0xfe,0xac,0x03,0x90,0xf4,0x81,0x7b,0xf8,0xff,0xff,0xdf,0xff,0x0b,0x01, +0x1f,0xfc,0x7f,0xff,0xff,0x85,0xff,0xff,0x01,0x20,0x00,0x01,0x01,0x5f,0xfc, +0xff,0x04,0x00,0x00,0xc1,0x20,0x00,0x01,0x00,0x9f,0xfd,0xff,0x05,0xfe,0x00, +0x00,0x3c,0x40,0x00,0x0b,0x00,0xf8,0x00,0x00,0x03,0x3f,0x07,0xe0,0xd3,0x00, +0xc0,0x00,0x0b,0xfe,0x87,0x00,0x33,0xfc,0xc0,0x77,0xf0,0xff,0xff,0x5f,0xff, +0x01,0x01,0x3f,0xfd,0xff,0x05,0x8b,0xff,0xf3,0x00,0xa0,0x00,0x01,0x01,0x7f, +0xfd,0xff,0x05,0xfc,0x00,0x0c,0xc1,0xa0,0x00,0x01,0x00,0xbf,0xfd,0xff,0x05, +0xfc,0x00,0x00,0x3e,0x40,0x00,0x0b,0x01,0xf0,0x00,0x00,0x05,0x7d,0x87,0xc0, +0xfa,0x00,0xd8,0x00,0x0b,0xfe,0x8f,0x80,0x47,0xfa,0x80,0xef,0xe3,0xff,0xff, +0xbf,0xff,0x01,0x00,0x3f,0xfe,0xff,0x06,0xfd,0x11,0xff,0xfa,0x00,0x58,0x00, +0x01,0x00,0x7f,0xfe,0xff,0x06,0xfd,0xfe,0x00,0x05,0xe1,0xd8,0x00,0x01,0x01, +0xbf,0xfe,0xff,0x06,0xfd,0xfc,0x00,0x00,0x1e,0x00,0x00,0x0b,0x00,0xf0,0x00, +0x00,0x0c,0xfc,0x87,0x81,0xfc,0x00,0x70,0x00,0x0b,0xfe,0xaf,0x8c,0xcf,0xf3, +0x00,0xcf,0xc3,0xff,0xff,0xc7,0xff,0x01,0x00,0x1f,0xfe,0xff,0x06,0xfc,0x33, +0xff,0xfc,0x00,0xa0,0x00,0x01,0x00,0x5f,0xfe,0xff,0x06,0xfc,0xfc,0x00,0x03, +0xf0,0xe0,0x00,0x01,0x01,0x9f,0xfe,0xff,0x06,0xfc,0xfc,0x00,0x00,0x0f,0x18, +0x00,0x0b,0x01,0xf0,0x00,0x00,0x1d,0xfd,0x0e,0x00,0x76,0x00,0x90,0x00,0x0b, +0xfe,0x8f,0xe0,0x0f,0xe2,0x00,0x7f,0x83,0xff,0xff,0xf7,0xff,0x01,0x00,0x3f, +0xfe,0xff,0x06,0xfd,0x83,0xff,0xfe,0x00,0x48,0x00,0x01,0x00,0x7f,0xfe,0xff, +0x06,0xfd,0xfc,0x00,0x01,0xf0,0x48,0x00,0x01,0x01,0xbf,0xfe,0xff,0x06,0xfd, +0xf8,0x00,0x00,0x0f,0x10,0x00,0x0b,0x00,0xf0,0x00,0x00,0x33,0xff,0x1e,0x00, +0xed,0x00,0x30,0x00,0x0b,0xfe,0x8f,0xf3,0x3f,0xcc,0x00,0x7f,0x00,0xff,0xff, +0xd7,0xff,0x01,0x01,0x3f,0xfd,0xff,0x05,0x87,0xff,0xff,0x00,0x48,0x00,0x01, +0x01,0x7f,0xfd,0xff,0x05,0xf8,0x00,0x00,0xf0,0x68,0x00,0x01,0x00,0xbf,0xfd, +0xff,0x05,0xf0,0x00,0x00,0x0f,0x90,0x00,0x0b,0x01,0xf8,0x00,0x00,0x15,0xfe, +0x18,0x00,0xf6,0xc0,0x20,0x00,0x0b,0xfe,0xa7,0xf7,0xbf,0xea,0x01,0x7e,0x81, +0xff,0xff,0x7b,0xff,0x01,0x00,0x1f,0xfd,0xff,0x05,0x8f,0xff,0xfe,0xc0,0x00, +0x00,0x01,0x00,0x5f,0xfd,0xff,0x05,0xf0,0x00,0x01,0x38,0x20,0x00,0x01,0x01, +0x9f,0xfd,0xff,0x05,0xf0,0x00,0x00,0x07,0x44,0x00,0x0b,0x00,0xec,0x00,0x00, +0x0c,0xfc,0x08,0x43,0xfc,0xc0,0x34,0x00,0x0b,0xfe,0xb3,0xff,0xff,0xf3,0x02, +0xcc,0xc3,0xff,0xfe,0x29,0xff,0x01,0x01,0x4f,0xfd,0xff,0x05,0x3f,0xef,0xfc, +0xc0,0x00,0x00,0x01,0x01,0x4f,0xfd,0xff,0x05,0xf0,0x10,0x03,0x3e,0x10,0x00, +0x01,0x00,0x9f,0xfd,0xff,0x00,0xf0,0xfe,0x00,0x01,0x06,0x00,0x0b,0x00,0xcc, +0x00,0x02,0x1d,0xf4,0x68,0x00,0x6f,0x80,0x34,0x00,0x0b,0xfe,0xb3,0xff,0xfd, +0xe2,0x02,0xff,0xc1,0xff,0xff,0x7d,0xff,0x01,0x00,0x2f,0xfe,0xff,0x06,0xf7, +0x1f,0xff,0xff,0x80,0x02,0x00,0x01,0x00,0x6f,0xfe,0xff,0x06,0xf7,0xf0,0x00, +0x00,0x7c,0x12,0x00,0x01,0x01,0x9f,0xfe,0xff,0x06,0xf7,0xe0,0x00,0x00,0x03, +0x44,0x00,0x0b,0x00,0x9c,0x00,0x03,0x33,0xe0,0x6e,0x00,0xff,0x00,0x1c,0x00, +0x0b,0xfe,0x33,0xff,0xfc,0xcc,0x00,0x7f,0x00,0xff,0xff,0xf5,0xff,0x01,0x01, +0x2f,0xfe,0xff,0x06,0xe3,0xbf,0xff,0xff,0x00,0x02,0x00,0x01,0x01,0x6f,0xfe, +0xff,0x06,0xe3,0xc0,0x00,0x00,0xfc,0x0a,0x00,0x01,0x00,0x8f,0xfe,0xff,0x06, +0xe3,0xc0,0x00,0x00,0x03,0xe4,0x00,0x0b,0x00,0xfc,0x40,0x45,0xc7,0xf2,0x3c, +0x00,0xee,0x80,0x18,0x80,0x0b,0xfe,0x33,0xbf,0xba,0x38,0x03,0x3e,0x03,0xff, +0xff,0xde,0xff,0x01,0x01,0x4f,0xfe,0xff,0x06,0xf0,0xff,0xf7,0xfe,0x80,0x00, +0x80,0x01,0x01,0x6f,0xfe,0xff,0x06,0xf3,0xc0,0x08,0x01,0x78,0x88,0x80,0x01, +0x00,0x8f,0xfe,0xff,0x06,0xf3,0xc0,0x00,0x00,0x07,0x41,0x00,0x0b,0x00,0xfc, +0xc0,0xcc,0xcf,0xf0,0x68,0x01,0xec,0x80,0x0d,0x00,0x0b,0xfe,0x33,0x3f,0x33, +0x30,0x00,0x7c,0x03,0xff,0xff,0xce,0x7f,0x01,0x00,0x4f,0xfe,0xff,0x06,0xf3, +0xbf,0xff,0xfc,0xc0,0x00,0x00,0x01,0x00,0x6f,0xfe,0xff,0x06,0xf3,0xc0,0x00, +0x03,0x30,0x04,0x00,0x01,0x01,0x8f,0xfe,0xff,0x06,0xf3,0xc0,0x00,0x00,0x0f, +0xc1,0x80,0x0b,0x01,0x37,0xa1,0xb5,0x5f,0xcb,0xe0,0x00,0x7f,0x80,0x07,0x00, +0x0b,0xff,0x5c,0x5e,0x4a,0xa0,0x04,0xf2,0x0f,0xff,0xff,0xf5,0x7f,0x01,0x01, +0x2b,0xfe,0xff,0x06,0xcf,0x3f,0xff,0xff,0x80,0x02,0x80,0x01,0x01,0x3b,0xfe, +0xff,0x06,0xcf,0xc0,0x00,0x00,0x7c,0x02,0x80,0x01,0x00,0x83,0xfe,0xff,0x06, +0xcf,0x80,0x00,0x00,0x03,0xf1,0x00,0x0b,0x00,0x2c,0xb3,0x33,0x3f,0xc3,0xa1, +0x08,0x6b,0x00,0x03,0x80,0x0b,0xff,0x94,0x4c,0xcc,0xc0,0x10,0xf7,0x0c,0xff, +0xff,0xe5,0x7f,0x01,0x00,0x00,0xfe,0xff,0x03,0xcf,0xff,0xbf,0xff,0xfe,0x00, +0x01,0x00,0x08,0xfe,0xff,0x06,0xcf,0x00,0x40,0x00,0xfc,0x02,0x00,0x01,0x00, +0x60,0xfe,0xff,0x00,0xdf,0xfe,0x00,0x02,0x03,0xe5,0x80,0x0b,0x00,0x3c,0x8d, +0x57,0xbf,0x8e,0x48,0x00,0xfe,0xc0,0x07,0x00,0x0b,0xff,0x8f,0x72,0xa8,0x40, +0x3f,0xfe,0x07,0xff,0xff,0x8d,0x7f,0x01,0x00,0x50,0xfe,0xff,0x06,0x81,0xcf, +0xbf,0xfe,0xc0,0x02,0x80,0x01,0x00,0x58,0xfe,0xff,0x06,0x8f,0xb0,0x40,0x01, +0x3a,0x02,0x80,0x01,0x00,0x23,0xfe,0xff,0x00,0xbe,0xfe,0x00,0x02,0x05,0x89, +0x00,0x0b,0x00,0x3b,0xcc,0xcf,0xff,0x34,0x84,0x01,0xac,0xc0,0x0d,0x80,0x0b, +0xff,0x8f,0x33,0x30,0x00,0x7c,0xfc,0x03,0xff,0xff,0x9a,0xff,0x01,0x00,0x54, +0xfe,0xff,0x06,0x08,0x47,0xff,0xfc,0xc0,0x00,0x80,0x01,0x00,0x5c,0xfe,0xff, +0x06,0x0f,0xf8,0x00,0x03,0x27,0x04,0x80,0x01,0x00,0x20,0xfe,0xff,0x00,0x40, +0xfe,0x00,0x02,0x18,0x91,0x00,0x0b,0x00,0x6f,0xdd,0xff,0xfc,0x6b,0xf9,0xc0, +0x27,0x80,0xc8,0x00,0x0b,0xff,0xf7,0x82,0x00,0x00,0xfa,0x7f,0xf1,0xff,0xff, +0xf7,0xff,0x0b,0x00,0x68,0x5f,0xff,0xfc,0x10,0x11,0xff,0xff,0x80,0x30,0x00, +0x0b,0x00,0x6e,0x5f,0xff,0xfc,0x1c,0xe6,0x00,0x00,0x60,0x38,0x00,0x05,0x00, +0x00,0x5f,0xff,0xfc,0x83,0xfe,0x00,0x02,0x1f,0x00,0x00,0x0b,0x00,0x0e,0x4f, +0xff,0xfc,0x94,0x78,0x3c,0xff,0x07,0x58,0x00,0x0b,0xff,0xe3,0xc0,0x00,0x00, +0xf9,0x2f,0xfc,0xff,0xff,0xf7,0xff,0x0b,0x00,0x05,0x8f,0xff,0xfc,0x60,0x14, +0x3f,0xff,0x08,0x80,0x00,0x0b,0x00,0x07,0x8f,0xff,0xfc,0x70,0x1f,0xc0,0x00, +0xc8,0xc0,0x00,0x0b,0x00,0x18,0x0f,0xff,0xfc,0x06,0xe0,0x00,0x00,0x30,0x18, +0x00,0x0b,0x00,0x0b,0x60,0xff,0xc1,0xb6,0x6e,0x42,0x00,0xad,0xf8,0x00,0x06, +0xff,0xe1,0xf0,0x00,0x03,0xe3,0x17,0xfe,0xff,0x01,0x33,0xff,0x0b,0x00,0x02, +0x80,0xff,0xc0,0x52,0x81,0xb2,0x00,0x12,0x40,0x00,0x0b,0x00,0x03,0x80,0xff, +0xc0,0x72,0x8e,0x7d,0xfb,0x1f,0xc0,0x00,0x0b,0x00,0x1c,0x10,0xff,0xc2,0x0c, +0x60,0x00,0x04,0x40,0x3c,0x00,0x0b,0x00,0x03,0xb0,0xff,0xc3,0x70,0x00,0x60, +0x00,0x96,0x40,0x00,0x0b,0xff,0xf8,0xf8,0x00,0x07,0xc7,0xf0,0x3f,0xff,0xfd, +0xff,0xff,0x0b,0x00,0x01,0x40,0xff,0xc0,0xa8,0x0e,0xd0,0x00,0x60,0x40,0x00, +0x0b,0x00,0x01,0xe0,0xff,0xc1,0xe8,0x0e,0xff,0x30,0x70,0x40,0x00,0x0b,0x00, +0x06,0x08,0xff,0xc4,0x10,0x01,0x00,0xcf,0x06,0x00,0x00,0x0b,0x00,0x02,0xf8, +0x40,0x47,0xd8,0x17,0xb9,0xdf,0xf7,0x80,0x00,0x0b,0xff,0xf8,0x1f,0x80,0x3e, +0x2f,0xf1,0xdf,0xff,0xc6,0x3f,0xff,0x0b,0x00,0x01,0x20,0x40,0x41,0x48,0x18, +0x06,0xee,0x18,0x00,0x00,0x0b,0x00,0x01,0xf0,0x40,0x43,0xc8,0x18,0x39,0x11, +0xf8,0x00,0x00,0x0b,0x00,0x06,0x07,0xc0,0x78,0x10,0x07,0x80,0x00,0x07,0xc0, +0x00,0x0b,0x00,0x00,0x7b,0x80,0xf7,0x80,0x00,0x2c,0x48,0x30,0x00,0x00,0x0b, +0xff,0xff,0x0f,0xc1,0xfc,0x7f,0xff,0xe0,0x00,0x3f,0xff,0xff,0x0b,0x00,0x00, +0x14,0x00,0x08,0x00,0x00,0x32,0x90,0x70,0x00,0x00,0x0b,0x00,0x00,0x1c,0x00, +0x0e,0x00,0x00,0x32,0x90,0x70,0x00,0x00,0x0b,0x00,0x00,0xe0,0x41,0x03,0x80, +0x00,0x0d,0x6f,0x80,0x00,0x00,0x0b,0x00,0x01,0x6f,0xc1,0x7d,0x80,0x00,0x17, +0xff,0xe0,0x00,0x00,0x0b,0xff,0xff,0x01,0xff,0xc0,0x3f,0xff,0xc0,0x04,0x0f, +0xff,0xff,0x0b,0x00,0x01,0x98,0x3e,0x84,0x40,0x00,0x28,0x40,0x10,0x00,0x00, +0x0b,0x00,0x01,0x9f,0xfe,0xfc,0x40,0x00,0x28,0x00,0x10,0x00,0x00,0x0b,0x00, +0x00,0x60,0x00,0x03,0x80,0x00,0x17,0xbf,0xe0,0x00,0x00,0x0b,0x00,0x00,0xc1, +0x2b,0x82,0x00,0x00,0x20,0xc0,0x10,0x00,0x00,0x04,0xff,0xff,0xf0,0x00,0x13, +0xfa,0xff,0x0b,0x00,0x00,0xce,0x00,0x0a,0x00,0x00,0x20,0xc0,0x10,0x00,0x00, +0x0b,0x00,0x00,0xce,0x00,0x0a,0x00,0x00,0x20,0xc0,0x10,0x00,0x00,0x04,0x00, +0x00,0x01,0xff,0xe4,0xfa,0x00,0x04,0x00,0x00,0x13,0xff,0xf0,0xfa,0x00,0x04, +0xff,0xff,0xf0,0x7f,0x83,0xfa,0xff,0x04,0x00,0x00,0x14,0x00,0x0c,0xfa,0x00, +0x04,0x00,0x00,0x14,0x00,0x0c,0xfa,0x00,0x04,0x00,0x00,0x0b,0xff,0xf0,0xfa, +0x00,0xfe,0x00,0x01,0x7f,0xe0,0xfa,0x00,0xf5,0xff,0xfe,0x00,0x01,0x7f,0xe0, +0xfa,0x00,0xfe,0x00,0x01,0x7f,0xe0,0xfa,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff, +0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5, +0x00,0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff, +0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5, +0x00,0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff, +0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5, +0x00,0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff, +0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5, +0x00,0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff, +0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5, +0x00,0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5,0x00, }; + +//---------------------------------------------------------------------------- + +static const ULONG icon64_colors[96] = +{ + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, + 0xc8c8c8c8,0xd5d5d5d5,0xe9e9e9e9, + 0x66666666,0x63636363,0x64646464, + 0xacacacac,0xacacacac,0xefefefef, + 0x8b8b8b8b,0x8b8b8b8b,0x96969696, + 0x96969696,0x9c9c9c9c,0xdbdbdbdb, + 0x7b7b7b7b,0x87878787,0xc1c1c1c1, + 0x56565656,0x69696969,0x97979797, + 0xc9c9c9c9,0xcfcfcfcf,0xdcdcdcdc, + 0xc7c7c7c7,0xd6d6d6d6,0xf0f0f0f0, + 0xbfbfbfbf,0xc8c8c8c8,0xd9d9d9d9, + 0xcbcbcbcb,0xd8d8d8d8,0xedededed, + 0xd1d1d1d1,0xdfdfdfdf,0xf4f4f4f4, + 0xbdbdbdbd,0xc1c1c1c1,0xc7c7c7c7, + 0x2a2a2a2a,0x45454545,0x65656565, + 0xa3a3a3a3,0xaeaeaeae,0xbcbcbcbc, + 0xdbdbdbdb,0xe7e7e7e7,0xf6f6f6f6, + 0xefefefef,0xe8e8e8e8,0x0f0f0f0f, + 0xf2f2f2f2,0xecececec,0x46464646, + 0xf5f5f5f5,0xf0f0f0f0,0x73737373, + 0xf9f9f9f9,0xf6f6f6f6,0x9a9a9a9a, + 0xfbfbfbfb,0xf9f9f9f9,0xc4c4c4c4, + 0xe1e1e1e1,0xdededede,0xb9b9b9b9, + 0xe1e1e1e1,0xb8b8b8b8,0x42424242, + 0xd0d0d0d0,0xbfbfbfbf,0x91919191, + 0xb6b6b6b6,0x95959595,0x78787878, + 0xdcdcdcdc,0x78787878,0x3d3d3d3d, + 0x39393939,0x29292929,0x27272727, + 0x90909090,0x0b0b0b0b,0x0b0b0b0b, + 0xd8d8d8d8,0x35353535,0x32323232, + 0xffffffff,0xffffffff,0xffffffff, +}; + +#define ICON64_WIDTH 64 +#define ICON64_HEIGHT 64 +#define ICON64_DEPTH 5 +#define ICON64_COMPRESSION 1 +#define ICON64_MASKING 0 + +static const struct BitMapHeader icon64_header = +{ 64,64,0,0,5,0,1,0,0,1,1,64,64 }; + +static const UBYTE icon64_body[2096] = { +0xf9,0x00,0xf9,0xff,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0xff,0xf9, +0x00,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0xff,0xf9,0x00,0xf9,0x00,0xf9,0x00, +0xf9,0x00,0xf9,0xff,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0xff,0xf9, +0x00,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0xff,0xf9,0x00,0xf9,0x00,0xf9,0x00, +0xf9,0x00,0xf9,0xff,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0xff,0xf9, +0x00,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0xff,0xf9,0x00,0xf9,0x00,0xf9,0x00, +0xf9,0x00,0xf9,0xff,0xf9,0x00,0xfe,0x00,0x00,0x04,0xfd,0x00,0xf9,0x00,0xfe, +0x00,0x00,0x0c,0xfd,0x00,0xfe,0xff,0x01,0xfe,0x7f,0xfe,0xff,0xfe,0x00,0x01, +0x01,0x80,0xfe,0x00,0xfe,0x00,0x01,0x2f,0x80,0xfe,0x00,0xf9,0x00,0xfe,0x00, +0x01,0x1e,0x80,0xfe,0x00,0xfe,0xff,0x01,0xe1,0xdf,0xfe,0xff,0xfd,0x00,0x00, +0x20,0xfe,0x00,0xfe,0x00,0x01,0x5f,0xa0,0xfe,0x00,0xfe,0x00,0x00,0x06,0xfd, +0x00,0xfe,0x00,0x01,0x1e,0xc0,0xfe,0x00,0xfe,0xff,0x01,0xe7,0xbf,0xfe,0xff, +0xfe,0x00,0x00,0x61,0xfd,0x00,0xfe,0x00,0x01,0xf1,0xd0,0xfe,0x00,0xfe,0x00, +0x00,0x06,0xfd,0x00,0x04,0x00,0x00,0x03,0x8f,0x10,0xfe,0x00,0x04,0xff,0xff, +0xf5,0x99,0xbb,0xfe,0xff,0x04,0x00,0x00,0x08,0x36,0xe4,0xfe,0x00,0x04,0x00, +0x00,0x0f,0xc0,0x7c,0xfe,0x00,0xfe,0x00,0x01,0x7f,0x80,0xfe,0x00,0x04,0x00, +0x00,0x01,0xaf,0x2e,0xfe,0x00,0x07,0xff,0xff,0xdc,0x80,0x6c,0x7f,0xff,0xff, +0x07,0x00,0x00,0x27,0x7f,0xe1,0x80,0x00,0x00,0x07,0x00,0x00,0x37,0x00,0x1f, +0x80,0x00,0x00,0xfe,0x00,0x01,0xff,0xf0,0xfe,0x00,0x04,0x00,0x00,0x5f,0x61, +0x7d,0xfe,0x00,0x07,0xff,0xff,0x34,0x08,0x13,0xcf,0xff,0xff,0x07,0x00,0x00, +0x85,0xff,0xe0,0x30,0x00,0x00,0x07,0x00,0x01,0xd8,0x00,0x0d,0xf0,0x00,0x00, +0x04,0x00,0x00,0x0f,0xff,0xf8,0xfe,0x00,0x07,0x00,0x00,0x7f,0x0f,0x0e,0x40, +0x00,0x00,0x07,0xff,0xff,0xa9,0x99,0x99,0xbf,0xff,0xff,0x07,0x00,0x00,0x06, +0xf6,0xf5,0x80,0x00,0x00,0x07,0x00,0x00,0x70,0x00,0x01,0xe0,0x00,0x00,0x04, +0x00,0x00,0x1f,0xff,0xfe,0xfe,0x00,0x07,0x00,0x02,0x70,0xf0,0xf6,0xf0,0x00, +0x00,0x07,0xff,0xfd,0x99,0x99,0x9d,0xbf,0xff,0xff,0x04,0x00,0x01,0xaf,0x6f, +0x6b,0xfe,0x00,0x07,0x00,0x07,0x80,0x00,0x00,0x74,0x00,0x00,0x07,0x00,0x00, +0x7f,0xff,0xff,0xc0,0x00,0x00,0x07,0x00,0x0b,0xd6,0xb6,0xb4,0xb0,0x00,0x00, +0x01,0xff,0xf4,0xfe,0x00,0x02,0x2f,0xff,0xff,0x07,0x00,0x04,0x7f,0xff,0xff, +0xe0,0x00,0x00,0x01,0x00,0x0e,0xfb,0x00,0x01,0x00,0x01,0xfe,0xff,0x02,0xf0, +0x00,0x00,0x07,0x00,0x04,0x06,0x16,0x16,0x2c,0x00,0x00,0x07,0xff,0xdb,0x90, +0x80,0x80,0xf3,0x7f,0xff,0x01,0x00,0x2b,0xfe,0xff,0x02,0x92,0x80,0x00,0x01, +0x00,0x2c,0xfe,0x00,0x02,0x0f,0x80,0x00,0x01,0x00,0x03,0xfe,0xff,0x02,0xfc, +0x00,0x00,0x07,0x00,0x06,0x30,0xf0,0xf0,0x85,0x00,0x00,0x07,0xff,0xd9,0xd9, +0x99,0x99,0xf6,0xff,0xff,0x01,0x00,0x2a,0xfe,0x6f,0x02,0x01,0x00,0x00,0x01, +0x00,0x28,0xfe,0x00,0x02,0x0f,0x80,0x00,0x01,0x00,0x07,0xfe,0xff,0x02,0xfe, +0x00,0x00,0x07,0x00,0x08,0x6b,0x0f,0x05,0x05,0x00,0x00,0x07,0xff,0xfb,0xfd, +0x99,0x93,0xc6,0xff,0xff,0x07,0x00,0x04,0x06,0xf6,0xfe,0x01,0x00,0x00,0x01, +0x00,0x08,0xfe,0x00,0x02,0x3f,0x80,0x00,0x01,0x00,0x07,0xfe,0xff,0x02,0xfe, +0x00,0x00,0x07,0x00,0x04,0x07,0xeb,0x64,0x06,0x00,0x00,0x07,0xff,0xfd,0xfc, +0x00,0x0d,0x0d,0xff,0xff,0x04,0x00,0x0e,0x03,0xff,0xf2,0xfe,0x00,0x01,0x00, +0x08,0xfe,0x00,0x02,0xff,0x80,0x00,0x01,0x00,0x07,0xfe,0xff,0x02,0xfe,0x00, +0x00,0x07,0x00,0x1c,0x00,0x20,0x00,0x07,0x00,0x00,0x07,0xff,0xed,0xfd,0x89, +0x5c,0x14,0x7f,0xff,0x07,0x00,0x06,0x03,0x7f,0xe0,0x01,0x80,0x00,0x07,0x00, +0x38,0x00,0x00,0x03,0xfb,0x80,0x00,0x01,0x00,0x07,0xfe,0xff,0x02,0xf2,0x00, +0x00,0x07,0x00,0x08,0x00,0x0b,0x00,0x16,0x00,0x00,0x07,0xff,0xfb,0xff,0xdd, +0xb0,0x36,0x7f,0xff,0x07,0x00,0x04,0x00,0x36,0xc0,0x17,0x80,0x00,0x07,0x00, +0x08,0x00,0x00,0x0f,0xed,0x80,0x00,0x01,0x00,0x07,0xfe,0xff,0x02,0xe0,0x00, +0x00,0x07,0x00,0x06,0x00,0x04,0x80,0x14,0x00,0x00,0x07,0xff,0xd9,0xff,0xeb, +0x80,0x34,0xbf,0xff,0x07,0x00,0x2a,0x00,0x1c,0x00,0x14,0x40,0x00,0x07,0x00, +0x28,0x00,0x00,0x7f,0xee,0x40,0x00,0x01,0x00,0x07,0xfe,0xff,0x02,0xe1,0x00, +0x00,0x07,0x00,0x0c,0xf9,0x08,0x00,0x8f,0x40,0x00,0x07,0xff,0xc4,0xf9,0xf6, +0x80,0xdf,0x3f,0xff,0x07,0x00,0x36,0x00,0x08,0x00,0x1e,0xc0,0x00,0x07,0x00, +0x39,0xfe,0x01,0x7f,0xc6,0xc0,0x00,0x01,0x00,0x07,0xfe,0xff,0x02,0xe0,0x00, +0x00,0x07,0x00,0x06,0x03,0x80,0x00,0xcb,0x00,0x00,0x07,0xff,0xb7,0xff,0xfc, +0x00,0xbb,0xbf,0xff,0x07,0x00,0x51,0xfc,0x00,0x00,0x7b,0xc0,0x00,0x07,0x00, +0x57,0xff,0x83,0xff,0x87,0xc0,0x00,0x01,0x00,0x0f,0xfe,0xff,0x02,0x80,0x00, +0x00,0x07,0x00,0x18,0x01,0xc0,0x06,0x6b,0xa0,0x00,0x07,0xff,0x2f,0xfe,0x58, +0x06,0x3b,0x5f,0xff,0x07,0x00,0xf7,0xff,0x80,0x00,0x7b,0xe0,0x00,0x07,0x00, +0xe7,0xff,0xe7,0xff,0x87,0x60,0x00,0x01,0x00,0x07,0xfe,0xff,0x02,0x80,0x00, +0x00,0x07,0x00,0xb4,0x80,0xc0,0x00,0x49,0xa0,0x00,0x07,0xfe,0x1f,0xff,0x20, +0x00,0x79,0x9f,0xff,0x07,0x01,0xab,0x7f,0xe0,0x00,0x79,0x80,0x00,0x01,0x01, +0x8f,0xfe,0xff,0x02,0x07,0x80,0x00,0x01,0x00,0x4f,0xfe,0xff,0x02,0x80,0x60, +0x00,0x07,0x00,0x65,0x40,0x78,0x09,0x83,0xe0,0x00,0x07,0xfd,0x3f,0xff,0x88, +0x09,0xfb,0x8f,0xff,0x07,0x02,0x5a,0xbf,0xf0,0x00,0xfb,0xd0,0x00,0x01,0x02, +0x1f,0xfe,0xff,0x02,0x07,0xb0,0x00,0x01,0x00,0x9f,0xfe,0xff,0xfe,0x00,0x07, +0x02,0xcd,0x60,0xd0,0x0a,0x1b,0xd0,0x00,0x07,0xfd,0x7f,0xff,0x28,0x0b,0xfb, +0xc7,0xff,0x07,0x02,0xb2,0x9f,0xf8,0x00,0xfb,0xd8,0x00,0x01,0x03,0x3f,0xfe, +0xff,0x02,0x07,0xd8,0x00,0x01,0x00,0x3f,0xfe,0xff,0x02,0x00,0x20,0x00,0x07, +0x01,0x9f,0xf0,0x6c,0x65,0x38,0xd0,0x00,0x07,0xfd,0x7f,0xff,0x90,0x67,0x78, +0xc7,0xff,0x07,0x02,0xe0,0x0f,0xfc,0x01,0xf8,0xd8,0x00,0x07,0x03,0x7f,0xff, +0xff,0xfe,0x07,0xf8,0x00,0x04,0x00,0x7f,0xff,0xff,0xfe,0xfe,0x00,0x07,0x07, +0x6e,0xe8,0x1a,0x09,0x9e,0xe0,0x00,0x07,0xfa,0xfe,0xff,0xe2,0x0b,0xfe,0xeb, +0xff,0x07,0x05,0x90,0x17,0xf8,0x01,0xfe,0xc4,0x00,0x07,0x06,0xff,0xff,0xf9, +0xfe,0x01,0xc4,0x00,0x07,0x00,0xff,0xff,0xf9,0xfe,0x00,0x10,0x00,0x07,0x05, +0x1c,0x70,0x39,0x13,0x1c,0xe4,0x00,0x07,0xf9,0xfc,0x7f,0xc1,0x17,0xbc,0xe3, +0xff,0x07,0x04,0xe0,0x0f,0xfa,0x03,0xfc,0xec,0x00,0x07,0x04,0xff,0xff,0xfb, +0xfc,0x03,0xfc,0x00,0x04,0x02,0xff,0xff,0xfb,0xfc,0xfe,0x00,0x07,0x05,0x18, +0x70,0x6b,0xd6,0x18,0x70,0x00,0x07,0xf1,0xf8,0x7f,0x91,0xd3,0x38,0x7b,0xff, +0x07,0x0c,0xe0,0x0f,0xfe,0x07,0xf8,0x7c,0x00,0x00,0x0c,0xfe,0xff,0x03,0xf8, +0x07,0xfc,0x00,0x00,0x02,0xfe,0xff,0x00,0xf8,0xfe,0x00,0x07,0x04,0x6e,0xc8, +0x9e,0x2c,0x9e,0x7a,0x00,0x07,0xf8,0xfe,0xff,0x61,0x2a,0xbe,0x75,0xff,0x07, +0x01,0x90,0x37,0xff,0x07,0xfe,0x7e,0x00,0x00,0x01,0xfe,0xff,0x03,0xf8,0x01, +0xf6,0x00,0x00,0x07,0xfe,0xff,0x00,0xf8,0xfe,0x00,0x07,0x07,0x1f,0xb0,0x6f, +0x9f,0x19,0x7a,0x00,0x07,0xf8,0xff,0xff,0x90,0x9f,0x39,0x79,0xff,0x07,0x07, +0xe0,0x4f,0xff,0x0f,0xf9,0x78,0x00,0x00,0x05,0xfe,0xff,0x03,0xf0,0x06,0xf8, +0x00,0x00,0x01,0xfe,0xff,0x03,0xf0,0x00,0x06,0x00,0x07,0x07,0x0d,0xa0,0xdc, +0xae,0x3e,0x3e,0x00,0x07,0xf0,0xff,0xff,0x20,0xae,0x7e,0x3a,0xff,0x07,0x0b, +0xf2,0x5f,0xff,0x0f,0xfe,0x3d,0x00,0x00,0x09,0xfe,0xff,0x03,0xf0,0x01,0xfb, +0x00,0x00,0x05,0xfe,0xff,0x00,0xf0,0xfe,0x00,0x07,0x05,0x09,0x40,0xbc,0x4c, +0x3e,0x3d,0x00,0x07,0xfa,0xff,0xff,0x40,0x5c,0x7e,0x3c,0x7f,0x07,0x01,0xf6, +0xbf,0xfe,0x0f,0xfe,0x38,0x80,0x07,0x0b,0xff,0xff,0xfe,0xf0,0x01,0xf8,0x80, +0x07,0x07,0xff,0xff,0xfe,0xf0,0x00,0x03,0x00,0x07,0x07,0x86,0x81,0x7f,0x98, +0x1f,0x1b,0x00,0x07,0xf8,0x7f,0xfe,0x80,0xb8,0x3f,0x1a,0x7f,0x07,0x03,0xf9, +0x7f,0xff,0x1f,0xff,0x1d,0x80,0x00,0x01,0xfe,0xff,0x03,0xe0,0x00,0xfd,0x80, +0x00,0x05,0xfe,0xff,0x03,0xe0,0x00,0x04,0x00,0x07,0x04,0x80,0x00,0xbe,0x50, +0x3e,0x88,0x00,0x07,0xf8,0x7f,0xff,0x41,0x76,0x7e,0x88,0x3f,0x00,0x01,0xfe, +0xff,0x03,0x1f,0xfe,0x8a,0xc0,0x00,0x01,0xfe,0xff,0x03,0xe0,0x01,0x7a,0xc0, +0x00,0x07,0xfe,0xff,0x03,0xe0,0x00,0x03,0x00,0x07,0x05,0x80,0x09,0xbb,0xb8, +0x1f,0x0d,0x40,0x07,0xf1,0x7f,0xf6,0x41,0xfc,0x3f,0x0c,0x3f,0x07,0x0c,0xff, +0xff,0xfa,0x3f,0xff,0x0f,0xc0,0x07,0x0c,0xff,0xff,0xfb,0xc0,0x00,0xfe,0xc0, +0x07,0x02,0xff,0xff,0xfb,0xc0,0x00,0x02,0x00,0x07,0x05,0x80,0x0f,0x79,0xf0, +0x3f,0x1c,0x40,0x07,0xfb,0x7f,0xf0,0x81,0xb8,0x3f,0x1c,0xbf,0x07,0x06,0xff, +0xff,0xfa,0x7f,0xff,0x1f,0xc0,0x07,0x0e,0xff,0xff,0xfb,0x80,0x00,0xff,0xc0, +0x07,0x00,0xff,0xff,0xfb,0x80,0x00,0x03,0x00,0x07,0x07,0xf0,0xd4,0xfb,0xe0, +0x3e,0xbc,0xa0,0x07,0xfa,0x0f,0x2b,0x01,0xb8,0x7e,0xbc,0xdf,0x07,0x05,0xff, +0xff,0xfa,0x7f,0xfe,0xbe,0x60,0x07,0x06,0xff,0xff,0xfb,0x80,0x01,0x7e,0x60, +0x07,0x00,0xff,0xff,0xfb,0x80,0x00,0x02,0x00,0x07,0x00,0x89,0x6b,0xe5,0xc8, +0x9f,0x0f,0x20,0x07,0xff,0x16,0x94,0x06,0xe8,0xff,0x0f,0x1f,0x07,0x00,0xff, +0xff,0xf3,0xff,0xff,0x0f,0x00,0x07,0x02,0x7f,0xff,0xf3,0x00,0x00,0xff,0x00, +0x03,0x00,0x7f,0xff,0xf3,0xfe,0x00,0x00,0x60,0x07,0x02,0xd6,0x9f,0xe5,0x90, +0x3e,0x94,0xa0,0x07,0xfc,0x49,0x60,0x06,0x10,0xfe,0x94,0x9f,0x07,0x03,0xff, +0xff,0xf9,0x9f,0xfe,0x94,0x80,0x07,0x03,0x7f,0xff,0xfa,0x60,0x01,0x7c,0x80, +0x03,0x00,0x3f,0xff,0xfa,0xfe,0x00,0x00,0x60,0x07,0x00,0x7e,0xff,0x8d,0x0c, +0x0a,0xbd,0x00,0x07,0xfd,0xa1,0x00,0x02,0x0e,0x7e,0xbd,0x9f,0x07,0x02,0xdf, +0xff,0xfc,0x0f,0xfe,0xbe,0xe0,0x07,0x02,0x9f,0xff,0xf0,0x30,0x01,0x7e,0xe0, +0x07,0x00,0x1f,0xff,0xf1,0xc0,0x00,0x02,0x00,0x07,0x00,0x33,0xff,0x1e,0x51, +0xaa,0x7d,0x80,0x07,0xff,0x50,0x00,0x11,0x21,0xea,0x7a,0x7f,0x07,0x00,0xe7, +0xff,0xaa,0xf1,0xea,0x46,0x80,0x07,0x00,0xc7,0xff,0xa6,0xee,0x15,0xc2,0x80, +0x07,0x00,0x07,0xff,0xa0,0x00,0x00,0x01,0x00,0x07,0x00,0x18,0xfc,0x78,0x19, +0x17,0xcd,0x00,0x07,0xff,0x20,0x00,0x41,0x24,0x17,0xd8,0x7f,0x07,0x00,0xfc, +0xfc,0x36,0xc1,0x17,0x03,0x80,0x07,0x00,0xe4,0xfc,0x0e,0xd8,0xff,0x0f,0x80, +0x07,0x00,0x04,0xfc,0x00,0x02,0x00,0x20,0x00,0x07,0x00,0x0e,0x00,0xb0,0x1e, +0x00,0x1c,0x00,0x07,0xff,0xba,0x00,0x93,0xe0,0x40,0x61,0xff,0x07,0x00,0x57, +0x87,0x0c,0x1c,0x40,0x5e,0x00,0x07,0x00,0x5b,0x87,0x3c,0x1e,0x00,0x5e,0x00, +0x07,0x00,0x01,0x87,0x40,0x01,0xbf,0x80,0x00,0x07,0x00,0x18,0xfa,0x70,0x01, +0xff,0xc0,0x00,0x07,0xff,0xe4,0x78,0x4f,0xfc,0x00,0x1f,0xff,0x07,0x00,0x1c, +0x92,0x30,0x03,0xff,0xe0,0x00,0x07,0x00,0x1c,0x14,0x70,0x03,0xff,0xe0,0x00, +0x03,0x00,0x03,0x01,0x80,0xfd,0x00,0x03,0x00,0x02,0xff,0x80,0xfd,0x00,0x07, +0xff,0xf8,0x00,0x3f,0xff,0xe8,0x7f,0xff,0x07,0x00,0x07,0xed,0xc0,0x00,0x17, +0x80,0x00,0x07,0x00,0x07,0xed,0xc0,0x00,0x1f,0x80,0x00,0x02,0x00,0x00,0x12, +0xfc,0x00,0x02,0x00,0x00,0x78,0xfc,0x00,0x03,0xff,0xfc,0x00,0x7f,0xfd,0xff, +0x03,0x00,0x03,0xff,0x80,0xfd,0x00,0x03,0x00,0x03,0xff,0x80,0xfd,0x00,0xf9, +0x00,0xf9,0x00,0xf9,0xff,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0xff, +0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0xff,0xf9,0x00,0xf9,0x00,0xf9, +0x00,0xf9,0x00,0xf9,0xff,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0xff, +0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0xff,0xf9,0x00,0xf9,0x00,0xf9, +0x00,0xf9,0x00,0xf9,0xff,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0xff, +0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0xff,0xf9,0x00,0xf9,0x00,0xf9, +0x00,0xf9,0x00,0xf9,0xff,0xf9,0x00,0xf9,0x00,0xf9,0x00, }; + +//---------------------------------------------------------------------------- + +static const ULONG icon48_colors[96] = +{ + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, + 0xc8c8c8c8,0xd5d5d5d5,0xe9e9e9e9, + 0xaaaaaaaa,0xabababab,0xeeeeeeee, + 0xd2d2d2d2,0xd2d2d2d2,0xdcdcdcdc, + 0x92929292,0x99999999,0xd9d9d9d9, + 0x7a7a7a7a,0x86868686,0xbdbdbdbd, + 0xd0d0d0d0,0xd6d6d6d6,0xe6e6e6e6, + 0x62626262,0x6e6e6e6e,0x8c8c8c8c, + 0xc4c4c4c4,0xd1d1d1d1,0xefefefef, + 0x9e9e9e9e,0xa1a1a1a1,0xa7a7a7a7, + 0xc3c3c3c3,0xcececece,0xe2e2e2e2, + 0xc2c2c2c2,0xc6c6c6c6,0xcdcdcdcd, + 0xc9c9c9c9,0xd6d6d6d6,0xebebebeb, + 0xcdcdcdcd,0xdbdbdbdb,0xf0f0f0f0, + 0xc9c9c9c9,0xd7d7d7d7,0xecececec, + 0xc7c7c7c7,0xd4d4d4d4,0xe8e8e8e8, + 0xd0d0d0d0,0xdededede,0xf2f2f2f2, + 0xcccccccc,0xd9d9d9d9,0xedededed, + 0xd3d3d3d3,0xe2e2e2e2,0xf6f6f6f6, + 0xcfcfcfcf,0xdcdcdcdc,0xeeeeeeee, + 0x2d2d2d2d,0x42424242,0x5b5b5b5b, + 0xc7c7c7c7,0xdadadada,0xf0f0f0f0, + 0xbfbfbfbf,0xd4d4d4d4,0xe7e7e7e7, + 0xf5f5f5f5,0xf0f0f0f0,0x6f6f6f6f, + 0xf9f9f9f9,0xf6f6f6f6,0xa7a7a7a7, + 0xe8e8e8e8,0xd1d1d1d1,0x2d2d2d2d, + 0xc8c8c8c8,0xc0c0c0c0,0x8a8a8a8a, + 0xd9d9d9d9,0x8d8d8d8d,0x45454545, + 0xd6d6d6d6,0x3b3b3b3b,0x32323232, + 0x8a8a8a8a,0x0c0c0c0c,0x0c0c0c0c, + 0xffffffff,0xffffffff,0xffffffff, +}; + +#define ICON48_WIDTH 48 +#define ICON48_HEIGHT 48 +#define ICON48_DEPTH 5 +#define ICON48_COMPRESSION 1 +#define ICON48_MASKING 0 + +static const struct BitMapHeader icon48_header = +{ 48,48,0,0,5,0,1,0,0,1,1,48,48 }; + +static const UBYTE icon48_body[1333] = { +0xfb,0x00,0xfb,0xff,0xfb,0x00,0xfb,0x00,0xfb,0x00,0xfb,0x00,0xfb,0xff,0xfb, +0x00,0xfb,0x00,0xfb,0x00,0xfb,0x00,0xfb,0xff,0xfb,0x00,0xfb,0x00,0xfb,0x00, +0xfb,0x00,0xfb,0xff,0xfb,0x00,0xfb,0x00,0xfb,0x00,0xfb,0x00,0xfb,0xff,0xfb, +0x00,0xfb,0x00,0xfb,0x00,0xfb,0x00,0xfb,0xff,0xfb,0x00,0xfb,0x00,0xfb,0x00, +0x02,0x00,0x00,0x06,0xfe,0x00,0x02,0xff,0xff,0xf9,0xfe,0xff,0x02,0x00,0x00, +0x06,0xfe,0x00,0x02,0x00,0x00,0x06,0xfe,0x00,0xfb,0x00,0x05,0x00,0x00,0x17, +0x80,0x00,0x00,0x05,0xff,0xff,0xfd,0x7f,0xff,0xff,0x05,0x00,0x00,0x11,0x80, +0x00,0x00,0x05,0x00,0x00,0x17,0x80,0x00,0x00,0xfb,0x00,0x05,0x00,0x00,0x7b, +0xa0,0x00,0x00,0x05,0xff,0xff,0x8a,0xdf,0xff,0xff,0x05,0x00,0x00,0x64,0x20, +0x00,0x00,0x05,0x00,0x00,0x7b,0xa0,0x00,0x00,0x02,0x00,0x00,0x02,0xfe,0x00, +0x05,0x00,0x01,0x75,0x78,0x00,0x00,0x05,0xff,0xff,0xf1,0x47,0xff,0xff,0x05, +0x00,0x01,0x08,0x98,0x00,0x00,0x05,0x00,0x01,0x77,0x78,0x00,0x00,0x02,0x00, +0x00,0x17,0xfe,0x00,0x05,0x00,0x07,0xaa,0xba,0x00,0x00,0x05,0xff,0xf8,0xa0, +0x3d,0xff,0xff,0x05,0x00,0x06,0x40,0x42,0x00,0x00,0x05,0x00,0x07,0xbf,0xba, +0x00,0x00,0x05,0x00,0x00,0x3f,0xa0,0x00,0x00,0x05,0x00,0x17,0x55,0x5f,0x80, +0x00,0x05,0xff,0xfd,0x00,0x1d,0x7f,0xff,0x05,0x00,0x10,0x80,0x09,0x80,0x00, +0x05,0x00,0x17,0x7f,0xf7,0x80,0x00,0x05,0x00,0x01,0x7f,0xf0,0x00,0x00,0x05, +0x00,0x7a,0xaa,0xab,0xa0,0x00,0x05,0xff,0x9a,0x00,0x02,0xdf,0xff,0x05,0x00, +0x64,0x00,0x04,0x20,0x00,0x05,0x00,0x7b,0xff,0xfb,0xa0,0x00,0x05,0x00,0x03, +0xff,0xfa,0x00,0x00,0x05,0x00,0x6d,0x55,0x55,0xc0,0x00,0x05,0xff,0xe8,0x00, +0x01,0xbf,0xff,0x05,0x00,0x18,0x00,0x00,0xa0,0x00,0x05,0x00,0x67,0xff,0xff, +0x40,0x00,0x05,0x00,0x07,0xff,0xff,0x20,0x00,0x05,0x00,0x1a,0xaa,0xaa,0xc8, +0x00,0x05,0xff,0x00,0x00,0x01,0x47,0xff,0x05,0x00,0x60,0x00,0x00,0x28,0x00, +0x05,0x00,0x4f,0xff,0xff,0xe8,0x00,0x05,0x00,0x8f,0xff,0xff,0xd0,0x00,0x05, +0x00,0x25,0x55,0x54,0x10,0x00,0x05,0xff,0x1a,0x00,0x03,0x9f,0xff,0x05,0x00, +0x40,0x00,0x00,0x68,0x00,0x05,0x00,0x7f,0xff,0xff,0xf0,0x00,0x05,0x00,0xbf, +0xff,0xff,0xe8,0x00,0x05,0x01,0x00,0xaa,0xa8,0x10,0x00,0x05,0xfe,0x1f,0x00, +0x17,0x9f,0xff,0x05,0x01,0x40,0x00,0x00,0x68,0x00,0x05,0x01,0x7f,0xff,0xff, +0xf0,0x00,0x05,0x00,0xbf,0xff,0xff,0xe8,0x00,0x05,0x01,0x20,0x55,0x40,0x90, +0x00,0x05,0xfe,0x1f,0xa0,0x3e,0x8b,0xff,0x05,0x01,0x40,0x00,0x01,0x28,0x00, +0x05,0x01,0x7f,0xff,0xff,0xf8,0x00,0x05,0x00,0xbf,0xff,0xff,0xa4,0x00,0x05, +0x00,0x00,0x0a,0x80,0x00,0x00,0x05,0xff,0x1f,0xf1,0x7b,0x8f,0xff,0x05,0x00, +0x40,0x00,0x04,0x90,0x00,0x05,0x00,0x7f,0xff,0xff,0x70,0x00,0x05,0x00,0xbf, +0xff,0xff,0x08,0x00,0x05,0x01,0x20,0x04,0x01,0x20,0x00,0x05,0xfc,0x9f,0xfb, +0xf5,0x8d,0xff,0x05,0x01,0x40,0x00,0x0a,0xa8,0x00,0x05,0x01,0x3f,0xff,0xff, +0x58,0x00,0x05,0x02,0xbf,0xff,0xff,0x26,0x00,0x05,0x02,0x8f,0x80,0x00,0xb8, +0x00,0x05,0xfd,0xc0,0x7f,0x89,0xcb,0xff,0x05,0x03,0x3f,0x80,0x77,0x74,0x00, +0x05,0x03,0xff,0xff,0xfe,0x08,0x00,0x05,0x00,0x3f,0xff,0xfe,0x34,0x00,0x05, +0x06,0x3f,0x80,0x12,0x94,0x00,0x05,0xf8,0x00,0x6e,0xf7,0x43,0xff,0x05,0x05, +0x3f,0xf1,0x09,0xd0,0x00,0x05,0x05,0xff,0xff,0xfe,0x28,0x00,0x05,0x02,0x3f, +0xff,0xfe,0x16,0x00,0x05,0x0c,0xff,0xe8,0x41,0x98,0x00,0x05,0xf4,0x00,0x17, +0x6a,0x41,0xff,0x05,0x0e,0xff,0xf8,0x97,0xde,0x00,0x05,0x0f,0xff,0xff,0xfc, +0x24,0x00,0x05,0x00,0xff,0xff,0xfc,0x1a,0x00,0x05,0x04,0xab,0xc4,0x03,0x18, +0x00,0x05,0xee,0x00,0x39,0x40,0xc3,0x7f,0x05,0x04,0xff,0xfe,0xbf,0xda,0x00, +0x05,0x03,0xff,0xff,0xfc,0x26,0x00,0x05,0x1c,0xff,0xff,0xfc,0x19,0x80,0x05, +0x09,0x83,0xfa,0x03,0x0e,0x00,0x05,0xf8,0x00,0x05,0xa4,0xc3,0xff,0x05,0x0d, +0xff,0xfe,0x5f,0xcc,0x00,0x05,0x0f,0xff,0xff,0xf8,0x32,0x00,0x05,0x01,0xff, +0xff,0xf8,0x0d,0x00,0x05,0x0b,0x82,0xf0,0x0b,0x0d,0x00,0x05,0xfc,0x00,0x0c, +0x4d,0xe0,0xbf,0x05,0x0b,0xff,0xfd,0xb6,0xec,0x00,0x05,0x07,0xff,0xfd,0xf8, +0x12,0x00,0x05,0x1b,0xff,0xfd,0xf8,0x0d,0xc0,0x05,0x03,0x83,0xe0,0x07,0x86, +0x00,0x05,0xf0,0x10,0x1c,0x0b,0x40,0xff,0x05,0x1b,0xef,0xfd,0xfc,0xc7,0x00, +0x05,0x1f,0xff,0xfd,0xf0,0x39,0x00,0x05,0x03,0xff,0xfd,0xf0,0x06,0x80,0x05, +0x0a,0x83,0xd1,0x07,0x06,0x00,0x05,0xdc,0x00,0x2e,0x09,0xe0,0xdf,0x05,0x1f, +0xff,0xff,0xfe,0xe6,0x80,0x05,0x17,0xff,0xff,0xf0,0x19,0x80,0x05,0x2f,0xff, +0xff,0xf0,0x06,0x60,0x05,0x1b,0xad,0xe8,0x07,0x07,0x80,0x05,0xcc,0x00,0x17, +0x5a,0xd0,0xff,0x05,0x07,0xff,0xff,0xbd,0xd7,0x00,0x05,0x0f,0xff,0xff,0xe0, +0x28,0x80,0x05,0x37,0xff,0xff,0xe0,0x07,0x40,0x05,0x0b,0xef,0xd0,0x2f,0x03, +0x40,0x05,0xdc,0x00,0x2e,0x36,0xe0,0x6f,0x05,0x17,0xff,0xfe,0xd9,0xe3,0x00, +0x05,0x0f,0xff,0xfe,0xe0,0x1c,0x80,0x05,0x37,0xff,0xfe,0xe0,0x03,0x70,0x05, +0x1b,0xf7,0xa0,0x1f,0x03,0x80,0x05,0xcc,0x00,0x5f,0x2e,0xf0,0x3f,0x05,0x0f, +0xff,0xff,0xf1,0xf3,0xe0,0x05,0x07,0xff,0xff,0xc0,0x0c,0x60,0x05,0x3f,0xff, +0xff,0xc0,0x03,0x80,0x05,0x05,0xff,0xc1,0x1f,0x01,0x20,0x05,0xda,0x00,0x3e, +0x26,0xe8,0x17,0x05,0x17,0xff,0xff,0xf9,0xe9,0x00,0x05,0x13,0xff,0xff,0xc0, +0x16,0x40,0x05,0x27,0xff,0xff,0xc0,0x01,0x38,0x05,0x01,0xfe,0x20,0x1f,0x03, +0xc0,0x05,0xfa,0x01,0xdc,0x6e,0xf0,0x0f,0x05,0x03,0xff,0xfd,0xf1,0xf3,0xf0, +0x05,0x07,0xff,0xfd,0x80,0x0c,0x00,0x05,0x13,0xff,0xfd,0x80,0x03,0xd0,0x05, +0x18,0x71,0xc1,0x7f,0x03,0x80,0x05,0xef,0x8e,0x3a,0x0e,0xf8,0x0b,0x05,0x1b, +0xff,0xfb,0xf1,0xfb,0x98,0x05,0x1f,0xff,0xfb,0x80,0x04,0x28,0x05,0x03,0xff, +0xfb,0x80,0x03,0x84,0x05,0x04,0xaa,0x04,0x3f,0x01,0xa8,0x05,0xea,0x55,0xf8, +0x5c,0xf0,0x03,0x05,0x00,0xff,0xfe,0x63,0xf1,0xa0,0x05,0x02,0xff,0xfb,0x80, +0x0e,0x00,0x05,0x1c,0xff,0xfe,0x00,0x01,0xbc,0x05,0x0c,0x14,0x08,0x0f,0xc7, +0xd8,0x05,0xfe,0xeb,0xe2,0x96,0x28,0x37,0x05,0x0c,0xff,0xe9,0x19,0xef,0xd8, +0x05,0x0f,0xff,0xe6,0xe0,0x10,0x28,0x05,0x00,0xff,0xe8,0x00,0x07,0xc0,0x05, +0x04,0x00,0x12,0x80,0x08,0x60,0x05,0xf7,0x2f,0xc7,0x75,0x00,0xff,0x05,0x06, +0x2f,0xd3,0x55,0x08,0x00,0x05,0x07,0xaf,0xcc,0x6a,0xf7,0x80,0x05,0x08,0x2f, +0xd1,0x80,0x08,0x60,0x05,0x00,0x20,0x28,0xd8,0x03,0xe0,0x05,0xfb,0x4a,0x9a, +0x2f,0x4f,0xdf,0x05,0x00,0xaa,0xa0,0xcb,0x48,0x60,0x05,0x00,0xca,0x98,0xc4, +0xb4,0x20,0x05,0x07,0x2a,0xaf,0x30,0x03,0x80,0x05,0x00,0x07,0x14,0x09,0x05, +0x80,0x05,0xfc,0xf0,0x7b,0xf7,0xe3,0x7f,0x05,0x00,0x07,0x1c,0x09,0xf9,0x80, +0x05,0x00,0x38,0xec,0x09,0x00,0x80,0x05,0x03,0xc7,0x00,0x04,0xfe,0x00,0x05, +0x00,0x37,0x90,0x07,0xf8,0x00,0x05,0xff,0xc7,0x8f,0xfa,0x27,0xff,0x05,0x00, +0x08,0x70,0x07,0xf8,0x00,0x05,0x00,0x00,0x10,0x07,0xf8,0x00,0x02,0x00,0x3f, +0xe0,0xfe,0x00,0x02,0x00,0x02,0x80,0xfe,0x00,0x01,0xff,0xfa,0xfd,0xff,0x02, +0x00,0x07,0x80,0xfe,0x00,0xfb,0x00,0x01,0x00,0x0d,0xfd,0x00,0xfb,0x00,0x01, +0xff,0xf6,0xfd,0xff,0xfb,0x00,0xfb,0x00,0x01,0x00,0x09,0xfd,0x00,0xfb,0x00, +0xfb,0xff,0xfb,0x00,0xfb,0x00,0xfb,0x00,0xfb,0x00,0xfb,0xff,0xfb,0x00,0xfb, +0x00,0xfb,0x00,0xfb,0x00,0xfb,0xff,0xfb,0x00,0xfb,0x00,0xfb,0x00,0xfb,0x00, +0xfb,0xff,0xfb,0x00,0xfb,0x00,0xfb,0x00,0xfb,0x00,0xfb,0xff,0xfb,0x00,0xfb, +0x00,0xfb,0x00,0xfb,0x00,0xfb,0xff,0xfb,0x00,0xfb,0x00,0xfb,0x00, }; + +//---------------------------------------------------------------------------- + +static const ULONG icon32_colors[96] = +{ + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, + 0xc8c8c8c8,0xd5d5d5d5,0xe9e9e9e9, + 0x78787878,0x6e6e6e6e,0x6f6f6f6f, + 0xa6a6a6a6,0xa7a7a7a7,0xeaeaeaea, + 0x8d8d8d8d,0x96969696,0xd5d5d5d5, + 0x78787878,0x84848484,0xbabababa, + 0x8d8d8d8d,0x91919191,0x9d9d9d9d, + 0x51515151,0x65656565,0x94949494, + 0xc5c5c5c5,0xd1d1d1d1,0xecececec, + 0x35353535,0x40404040,0x56565656, + 0xcbcbcbcb,0xd4d4d4d4,0xe5e5e5e5, + 0xc9c9c9c9,0xd7d7d7d7,0xedededed, + 0xcccccccc,0xd9d9d9d9,0xeeeeeeee, + 0xd2d2d2d2,0xdfdfdfdf,0xf4f4f4f4, + 0xc5c5c5c5,0xcfcfcfcf,0xdfdfdfdf, + 0xc8c8c8c8,0xd6d6d6d6,0xeaeaeaea, + 0xcfcfcfcf,0xdcdcdcdc,0xefefefef, + 0xc6c6c6c6,0xd4d4d4d4,0xe7e7e7e7, + 0xb2b2b2b2,0xbfbfbfbf,0xd0d0d0d0, + 0xc9c9c9c9,0xcececece,0xd5d5d5d5, + 0xcacacaca,0xdededede,0xf3f3f3f3, + 0xcfcfcfcf,0xe3e3e3e3,0xf8f8f8f8, + 0xf6f6f6f6,0xf2f2f2f2,0x87878787, + 0xe5e5e5e5,0xe4e4e4e4,0xbfbfbfbf, + 0xefefefef,0xe6e6e6e6,0x25252525, + 0xcfcfcfcf,0xcdcdcdcd,0xbabababa, + 0xdcdcdcdc,0xa2a2a2a2,0x44444444, + 0xd7d7d7d7,0x43434343,0x36363636, + 0xc4c4c4c4,0xb5b5b5b5,0xb4b4b4b4, + 0x9c9c9c9c,0x13131313,0x12121212, + 0xffffffff,0xffffffff,0xffffffff, +}; + +#define ICON32_WIDTH 32 +#define ICON32_HEIGHT 32 +#define ICON32_DEPTH 5 +#define ICON32_COMPRESSION 1 +#define ICON32_MASKING 0 + +static const struct BitMapHeader icon32_header = +{ 32,32,0,0,5,0,1,0,0,1,1,32,32 }; + +static const UBYTE icon32_body[674] = { +0xfd,0x00,0xfd,0xff,0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfd,0xff,0xfd, +0x00,0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfd,0xff,0xfd,0x00,0xfd,0x00,0xfd,0x00, +0xfd,0x00,0xfd,0xff,0xfd,0x00,0xfd,0x00,0xfd,0x00,0x03,0x00,0x02,0x00,0x00, +0x03,0xff,0xfc,0xff,0xff,0x03,0x00,0x01,0x00,0x00,0x03,0x00,0x03,0x00,0x00, +0xfd,0x00,0x03,0x00,0x0c,0x80,0x00,0x03,0xff,0xe0,0x3f,0xff,0x03,0x00,0x03, +0x40,0x00,0x03,0x00,0x0c,0xc0,0x00,0x03,0x00,0x13,0x00,0x00,0x03,0x00,0x23, +0x60,0x00,0x03,0xff,0x9b,0x57,0xff,0x03,0x00,0x03,0xc0,0x00,0x03,0x00,0x2c, +0x60,0x00,0x03,0x00,0x5f,0x88,0x00,0x03,0x00,0x0f,0xd8,0x00,0x03,0xfe,0xef, +0xe3,0xff,0x03,0x00,0x0f,0xc4,0x00,0x03,0x00,0x30,0x3c,0x00,0x03,0x01,0x7f, +0xe0,0x00,0x03,0x01,0xff,0xe4,0x00,0x03,0xff,0xff,0xec,0xff,0x03,0x01,0x7f, +0xe7,0x00,0x03,0x01,0x80,0x1f,0x00,0x03,0x00,0x7f,0xf8,0x00,0x03,0x00,0x7f, +0xfd,0x00,0x03,0xfc,0x7f,0xff,0x7f,0x03,0x02,0x7f,0xfd,0x00,0x03,0x01,0x80, +0x03,0x00,0x03,0x07,0xff,0xfe,0x80,0x03,0x01,0xff,0xff,0x80,0x03,0xfc,0x3f, +0xf2,0x7f,0x03,0x02,0x3f,0xf1,0x80,0x03,0x01,0xc0,0x0f,0x00,0x03,0x03,0xff, +0xff,0x80,0x03,0x05,0xff,0xff,0x80,0x03,0xf8,0x1f,0xce,0x7f,0x03,0x00,0x1f, +0xc1,0x80,0x03,0x07,0xe0,0x3d,0x00,0x03,0x03,0xff,0xfd,0x80,0x03,0x05,0xff, +0xfd,0x00,0x03,0xf8,0x06,0xbd,0xff,0x03,0x00,0x06,0x85,0x80,0x03,0x07,0xf9, +0x7a,0x80,0x03,0x03,0xff,0xf8,0x00,0x03,0x0f,0x1f,0xfc,0x40,0x03,0xf1,0x10, +0xf9,0xbf,0x03,0x0a,0xe0,0x04,0x40,0x03,0x0f,0xff,0xfb,0x40,0x03,0x03,0xff, +0xf8,0x80,0x03,0x0c,0x07,0xfc,0x80,0x03,0xec,0x1d,0xbb,0xff,0x03,0x1f,0xf8, +0x0e,0xc0,0x03,0x1b,0xff,0xf1,0x40,0x03,0x03,0xff,0xf0,0x20,0x03,0x18,0x03, +0xfc,0x60,0x03,0xc8,0x0f,0xf3,0xdf,0x03,0x1f,0xfc,0x0e,0x60,0x03,0x07,0xff, +0xf1,0xe0,0x03,0x37,0xff,0xf0,0x00,0x03,0x33,0x81,0xf4,0x00,0x03,0xd3,0x87, +0xf2,0xff,0x03,0x2c,0x7e,0x1e,0x60,0x03,0x2f,0xff,0xe1,0xa0,0x03,0x1f,0xff, +0xe0,0x00,0x03,0x33,0x80,0xf4,0x10,0x03,0xd3,0x84,0xe2,0xef,0x03,0x3c,0x7d, +0x1e,0x10,0x03,0x0f,0xfd,0xe1,0xd0,0x03,0x2f,0xfd,0xe0,0x20,0x03,0x31,0x80, +0xf4,0x20,0x03,0xd1,0x8f,0xe3,0x7f,0x03,0x2e,0x7f,0x3f,0x30,0x03,0x0f,0xff, +0xc0,0xd0,0x03,0x2f,0xff,0xc0,0x00,0x03,0x22,0x00,0xc0,0x18,0x03,0x82,0x0e, +0xe6,0x77,0x03,0x3d,0xfe,0x3e,0x18,0x03,0x1f,0xfe,0xc1,0xf8,0x03,0x7f,0xfe, +0xc0,0x00,0x03,0x10,0x00,0xe4,0x18,0x03,0xf8,0x1f,0xc3,0x37,0x03,0x2f,0xff, +0x7f,0x10,0x03,0x0f,0xff,0x80,0xe0,0x03,0x2f,0xff,0x80,0x08,0x03,0x10,0x00, +0x80,0x0c,0x03,0xf8,0x2c,0xc7,0x3b,0x03,0x3f,0xfd,0x7f,0x0c,0x03,0x2f,0xfd, +0x80,0xfc,0x03,0x0f,0xfd,0x80,0x00,0x03,0x10,0x00,0xcc,0x08,0x03,0xde,0xff, +0x83,0xef,0x03,0x2f,0xff,0xff,0x84,0x03,0x2f,0xff,0x00,0x60,0x03,0x1f,0xff, +0x00,0x04,0x03,0x10,0x03,0x26,0x08,0x03,0xef,0xfa,0x81,0x7f,0x03,0x1f,0xf9, +0xbf,0x0c,0x03,0x07,0xf9,0x40,0xf4,0x03,0x37,0xf9,0x00,0x00,0x03,0x04,0x07, +0xf0,0x70,0x03,0xee,0xe6,0x58,0x5b,0x03,0x04,0xe3,0x38,0x68,0x03,0x02,0xe2, +0x07,0x90,0x03,0x18,0xe1,0xc0,0x0c,0x03,0x03,0x18,0x7f,0xc0,0x03,0xf5,0xf1, +0x1f,0xaf,0x03,0x02,0x08,0x10,0x20,0x03,0x02,0xe8,0x10,0x20,0x03,0x0e,0x0f, +0xef,0xd0,0x03,0x02,0xf0,0x0f,0x80,0x03,0xe1,0x43,0xe0,0x7f,0x03,0x07,0x0c, +0x0e,0x00,0x03,0x05,0x4c,0x0e,0x00,0x03,0x1a,0xb0,0x71,0xa0,0x03,0x00,0x40, +0x00,0x00,0x03,0xfe,0x6f,0xff,0xff,0xfd,0x00,0x03,0x00,0x40,0x00,0x00,0x03, +0x01,0x90,0x00,0x00,0xfd,0x00,0xfd,0xff,0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfd, +0x00,0xfd,0xff,0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfd,0xff,0xfd,0x00, +0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfd,0xff,0xfd,0x00,0xfd,0x00,0xfd,0x00, }; + +//---------------------------------------------------------------------------- + +static const ULONG icon24_colors[96] = +{ + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, + 0xc8c8c8c8,0xd5d5d5d5,0xe9e9e9e9, + 0x4d4d4d4d,0x15151515,0x17171717, + 0x9c9c9c9c,0xa1a1a1a1,0xe5e5e5e5, + 0x7e7e7e7e,0x88888888,0xbdbdbdbd, + 0xc6c6c6c6,0xd3d3d3d3,0xeeeeeeee, + 0x92929292,0x98989898,0xa4a4a4a4, + 0x4d4d4d4d,0x60606060,0x82828282, + 0xc8c8c8c8,0xd6d6d6d6,0xedededed, + 0xd0d0d0d0,0xdcdcdcdc,0xefefefef, + 0xc4c4c4c4,0xcfcfcfcf,0xe1e1e1e1, + 0xc9c9c9c9,0xd6d6d6d6,0xeaeaeaea, + 0xcccccccc,0xd9d9d9d9,0xecececec, + 0xc7c7c7c7,0xd8d8d8d8,0xefefefef, + 0xcdcdcdcd,0xdcdcdcdc,0xf1f1f1f1, + 0xcfcfcfcf,0xdededede,0xf3f3f3f3, + 0xd1d1d1d1,0xe2e2e2e2,0xf7f7f7f7, + 0xa8a8a8a8,0xb4b4b4b4,0xc3c3c3c3, + 0xb9b9b9b9,0xc5c5c5c5,0xd4d4d4d4, + 0xd4d4d4d4,0xd8d8d8d8,0xdcdcdcdc, + 0xd5d5d5d5,0xd7d7d7d7,0xc5c5c5c5, + 0xf5f5f5f5,0xf2f2f2f2,0x88888888, + 0xf0f0f0f0,0xe6e6e6e6,0x16161616, + 0xe7e7e7e7,0xcccccccc,0x47474747, + 0xd0d0d0d0,0xc1c1c1c1,0xa8a8a8a8, + 0xd9d9d9d9,0x98989898,0x3f3f3f3f, + 0xd4d4d4d4,0x57575757,0x3b3b3b3b, + 0xafafafaf,0x8b8b8b8b,0x83838383, + 0x9a9a9a9a,0x13131313,0x11111111, + 0xd5d5d5d5,0x2f2f2f2f,0x2e2e2e2e, + 0xffffffff,0xffffffff,0xffffffff, +}; + +#define ICON24_WIDTH 24 +#define ICON24_HEIGHT 24 +#define ICON24_DEPTH 5 +#define ICON24_COMPRESSION 1 +#define ICON24_MASKING 0 + +static const struct BitMapHeader icon24_header = +{ 24,24,0,0,5,0,1,0,0,1,1,24,24 }; + +static const UBYTE icon24_body[516] = { +0xfd,0x00,0xfe,0xff,0x00,0x00,0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfe, +0xff,0x00,0x00,0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfe,0xff,0x00,0x00, +0xfd,0x00,0xfd,0x00,0xfd,0x00,0x03,0x00,0x40,0x00,0x00,0x03,0xff,0xb7,0xff, +0x00,0x03,0x00,0x18,0x00,0x00,0x03,0x00,0x48,0x00,0x00,0xfd,0x00,0x03,0x01, +0x70,0x00,0x00,0x03,0xfe,0xcd,0xff,0x00,0x03,0x00,0xa6,0x00,0x00,0x03,0x01, +0x52,0x00,0x00,0x03,0x00,0x30,0x00,0x00,0x03,0x01,0x86,0x00,0x00,0x03,0xfb, +0x7b,0x7f,0x00,0x03,0x06,0xfd,0x80,0x00,0x03,0x05,0x02,0x80,0x00,0x03,0x00, +0xfc,0x00,0x00,0x03,0x00,0x01,0x00,0x00,0x03,0xfd,0xfe,0xff,0x00,0x03,0x07, +0xff,0xc0,0x00,0x03,0x00,0x00,0x40,0x00,0x03,0x03,0xff,0x00,0x00,0x03,0x18, +0x00,0x40,0x00,0x03,0xef,0xfe,0x3f,0x00,0x03,0x07,0xfe,0x20,0x00,0x03,0x18, +0x01,0xe0,0x00,0x03,0x07,0xff,0xc0,0x00,0x03,0x1b,0x00,0x40,0x00,0x03,0xeb, +0xfc,0xbf,0x00,0x03,0x03,0xfc,0x20,0x00,0x03,0x1c,0x03,0xc0,0x00,0x03,0x07, +0xff,0xc0,0x00,0x03,0x1b,0xc4,0x40,0x00,0x03,0xe7,0xf4,0x3f,0x00,0x03,0x0f, +0xf4,0x40,0x00,0x03,0x18,0x0b,0x80,0x00,0x03,0x07,0xff,0x00,0x00,0x03,0x1c, +0xb0,0x90,0x00,0x03,0xdf,0xf6,0x3f,0x00,0x03,0x3b,0x31,0x90,0x00,0x03,0x37, +0xcf,0x50,0x00,0x03,0x07,0xff,0x20,0x00,0x03,0x3e,0x60,0x80,0x00,0x03,0xff, +0xaa,0x1f,0x00,0x03,0x31,0xc1,0x80,0x00,0x03,0x2f,0xfe,0x70,0x00,0x03,0x0f, +0xfe,0x00,0x00,0x03,0x79,0x30,0x88,0x00,0x03,0xbf,0xd4,0x1f,0x00,0x03,0x40, +0xe3,0x88,0x00,0x03,0x5f,0xfe,0x68,0x00,0x03,0x3f,0xfe,0x10,0x00,0x03,0x29, +0x32,0xc0,0x00,0x03,0xbf,0xdc,0x0b,0x00,0x03,0x30,0xe3,0xc4,0x00,0x03,0x1f, +0xec,0x3c,0x00,0x03,0x5f,0xec,0x00,0x00,0x03,0x4f,0x70,0x84,0x00,0x03,0x9f, +0x88,0x0f,0x00,0x03,0x30,0xf7,0x84,0x00,0x03,0x3f,0xfc,0x74,0x00,0x03,0x7f, +0xfc,0x08,0x00,0x03,0x36,0x74,0xc0,0x00,0x03,0xaf,0x88,0x03,0x00,0x03,0x39, +0xf7,0xc0,0x00,0x03,0x1f,0xf8,0x38,0x00,0x03,0x5f,0xf8,0x04,0x00,0x03,0x50, +0xf0,0xc0,0x00,0x03,0xef,0x20,0x07,0x00,0x03,0x5f,0xdf,0xc0,0x00,0x03,0x5f, +0xd8,0x32,0x00,0x03,0x3f,0xd8,0x04,0x00,0x03,0x2f,0xec,0xcc,0x00,0x03,0xe0, +0x20,0x0d,0x00,0x03,0x2f,0xdf,0xc4,0x00,0x03,0x3f,0xd0,0x30,0x00,0x03,0x0f, +0xd0,0x02,0x00,0x03,0x07,0xeb,0xd8,0x00,0x03,0xe5,0xfe,0x0f,0x00,0x03,0x12, +0x33,0xd4,0x00,0x03,0x2a,0x18,0x24,0x00,0x03,0x12,0x04,0x08,0x00,0x03,0x13, +0xe5,0xf0,0x00,0x03,0xef,0xc7,0xcf,0x00,0x03,0x13,0x9e,0x28,0x00,0x03,0x18, +0x1f,0xa8,0x00,0x03,0x04,0x60,0x50,0x00,0x03,0x02,0x40,0x00,0x00,0x03,0xf7, +0xbf,0x9f,0x00,0x03,0x0b,0x40,0x60,0x00,0x03,0x0f,0xc0,0x60,0x00,0xfd,0x00, +0xfd,0x00,0xfe,0xff,0x00,0x00,0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfe, +0xff,0x00,0x00,0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfe,0xff,0x00,0x00, +0xfd,0x00,0xfd,0x00,0xfd,0x00, }; + +//---------------------------------------------------------------------------- + +static const ULONG icon16_colors[96] = +{ + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, + 0x62626262,0x46464646,0x4c4c4c4c, + 0x96969696,0x9b9b9b9b,0xdadadada, + 0x9b9b9b9b,0x9f9f9f9f,0xb5b5b5b5, + 0x78787878,0x85858585,0xb7b7b7b7, + 0x4b4b4b4b,0x61616161,0x8d8d8d8d, + 0xc6c6c6c6,0xd4d4d4d4,0xefefefef, + 0xb4b4b4b4,0xbebebebe,0xd1d1d1d1, + 0xcbcbcbcb,0xdadadada,0xf2f2f2f2, + 0xc9c9c9c9,0xd6d6d6d6,0xebebebeb, + 0xcacacaca,0xd7d7d7d7,0xecececec, + 0xc6c6c6c6,0xd5d5d5d5,0xebebebeb, + 0xc8c8c8c8,0xd5d5d5d5,0xe9e9e9e9, + 0xcacacaca,0xd7d7d7d7,0xebebebeb, + 0xd1d1d1d1,0xdededede,0xf2f2f2f2, + 0xcdcdcdcd,0xdbdbdbdb,0xeeeeeeee, + 0xc8c8c8c8,0xd5d5d5d5,0xe7e7e7e7, + 0xc6c6c6c6,0xd9d9d9d9,0xf0f0f0f0, + 0xc2c2c2c2,0xd2d2d2d2,0xe4e4e4e4, + 0xcccccccc,0xdfdfdfdf,0xf3f3f3f3, + 0xcdcdcdcd,0xd4d4d4d4,0xd9d9d9d9, + 0xf4f4f4f4,0xf0f0f0f0,0x48484848, + 0xf1f1f1f1,0xeeeeeeee,0x92929292, + 0xe3e3e3e3,0xb3b3b3b3,0x35353535, + 0xcececece,0xb2b2b2b2,0x83838383, + 0xdcdcdcdc,0x7c7c7c7c,0x41414141, + 0xa6a6a6a6,0x90909090,0x87878787, + 0xbbbbbbbb,0x4a4a4a4a,0x2d2d2d2d, + 0x9b9b9b9b,0x0e0e0e0e,0x0d0d0d0d, + 0xdadadada,0x34343434,0x33333333, + 0xffffffff,0xffffffff,0xffffffff, +}; + +#define ICON16_WIDTH 16 +#define ICON16_HEIGHT 16 +#define ICON16_DEPTH 5 +#define ICON16_COMPRESSION 1 +#define ICON16_MASKING 0 + +static const struct BitMapHeader icon16_header = +{ 16,16,0,0,5,0,1,0,0,1,1,16,16 }; + +static const UBYTE icon16_body[223] = { +0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x01,0xfe,0xff,0xff,0x00, +0xff,0xff,0xff,0xff,0xff,0x00,0x01,0xfd,0xbf,0x01,0x04,0x80,0xff,0xff,0x01, +0xfa,0x7f,0x01,0x01,0x00,0x01,0xe7,0xef,0x01,0x03,0xa0,0xff,0xff,0x01,0xf8, +0x1f,0x01,0x07,0xc0,0xff,0xff,0x01,0x0f,0xf0,0x01,0xff,0xef,0x01,0xe0,0x0f, +0x01,0x1f,0xf0,0x01,0xf3,0x9f,0x01,0x3f,0xc0,0x01,0xff,0xc7,0x01,0xc0,0x3f, +0x01,0x1f,0xf0,0x01,0xb0,0x2b,0x01,0x63,0x3c,0x01,0x83,0x17,0x01,0xdc,0xe7, +0x01,0x3f,0xe8,0x01,0xe0,0x27,0x01,0x2c,0x34,0x01,0x9e,0x1f,0x01,0xff,0xc7, +0x01,0x3f,0xc0,0x01,0x82,0x65,0x01,0x1c,0x7a,0x01,0x27,0x1b,0x01,0xff,0xc3, +0x01,0x3f,0xc4,0x01,0x03,0x71,0x01,0x3c,0xe8,0x01,0xe7,0x1d,0x01,0x3f,0x81, +0x01,0xbf,0x82,0x01,0x03,0xf3,0x01,0x3c,0xef,0x01,0x7f,0x18,0x01,0x3f,0x81, +0x01,0xbf,0x82,0x01,0x5e,0x71,0x01,0xa1,0x6d,0x01,0xde,0x9b,0x01,0x9e,0x01, +0x01,0x5e,0x00,0x01,0xc0,0x90,0x01,0x5e,0x82,0x01,0x82,0x39,0x01,0xe0,0x45, +0x01,0x01,0x82,0x01,0xbe,0x61,0x01,0x73,0x4c,0x01,0xbf,0xc3,0x01,0xf3,0xa3, +0x01,0x0c,0x1c,0x01,0xf3,0xff,0x01,0x04,0x00,0x01,0xf9,0xff,0x01,0xfd,0xff, +0x01,0x02,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0x00, }; + +//---------------------------------------------------------------------------- + +static const ULONG about_colors[48] = +{ + 0xffffffff,0x00000000,0x00000000, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0x33333333,0x77777777,0xaaaaaaaa, + 0x00000000,0x00000000,0x00000000, + 0xaaaaaaaa,0x88888888,0x77777777, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0xffffffff,0xaaaaaaaa,0x99999999, + 0xffffffff,0xffffffff,0xffffffff, + 0x77777777,0x77777777,0x77777777, + 0xeeeeeeee,0x00000000,0x99999999, + 0xffffffff,0xeeeeeeee,0x00000000, + 0x00000000,0x88888888,0x00000000, + 0x00000000,0xdddddddd,0x00000000, + 0x00000000,0xcccccccc,0xcccccccc, + 0x00000000,0x66666666,0xffffffff, + 0x00000000,0x00000000,0xaaaaaaaa, +}; + +#define ABOUT_WIDTH 12 +#define ABOUT_HEIGHT 16 +#define ABOUT_DEPTH 4 +#define ABOUT_COMPRESSION 0 +#define ABOUT_MASKING 2 + +static const struct BitMapHeader about_header = +{ 12,16,0,0,4,2,0,0,0,44,44,320,256 }; + +static const UBYTE about_body[128] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x10, +0x80,0x1e,0x00,0x1e,0x80,0x1f,0x00,0x20,0x40,0x10,0x80,0x3e,0x80,0x1f,0x00, +0x00,0x40,0x00,0x80,0x1c,0x80,0x1e,0x00,0x21,0x40,0x0f,0x00,0x7f,0x80,0x00, +0x00,0x80,0x40,0x7f,0x80,0xfe,0x80,0x7f,0x00,0x00,0x40,0x40,0x80,0xfe,0x80, +0x7f,0x00,0x00,0x40,0x10,0x80,0x1e,0x80,0x1f,0x00,0xe0,0x40,0xd0,0x80,0xfe, +0x80,0x1f,0x00,0x00,0x40,0x10,0x80,0x7e,0xe0,0x1f,0x00,0x80,0x00,0x60,0xa0, +0xff,0xa0,0x7f,0xc0,0x00,0x10,0x40,0x20,0xff,0x20,0x7f,0xc0,0x00,0x10,0x3f, +0xe0,0xff,0xe0,0x00,0x00,0x00,0x10,0x80,0x00,0x80,0x00,0x00,0x00,0x7f,0xf0, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, }; + +//---------------------------------------------------------------------------- + +static const ULONG desktop_colors[48] = +{ + 0xffffffff,0xaaaaaaaa,0x99999999, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0x44444444,0x44444444,0x44444444, + 0x66666666,0x66666666,0x66666666, + 0x77777777,0x77777777,0x77777777, + 0x00000000,0x66666666,0x99999999, + 0x33333333,0x77777777,0xaaaaaaaa, + 0x44444444,0x88888888,0x88888888, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0xbbbbbbbb,0xbbbbbbbb,0xbbbbbbbb, + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, + 0x00000000,0x22222222,0x44444444, + 0x88888888,0x88888888,0x88888888, + 0x00000000,0x66666666,0xffffffff, + 0x00000000,0x00000000,0xaaaaaaaa, +}; + +#define DESKTOP_WIDTH 24 +#define DESKTOP_HEIGHT 16 +#define DESKTOP_DEPTH 4 +#define DESKTOP_COMPRESSION 0 +#define DESKTOP_MASKING 2 + +static const struct BitMapHeader desktop_header = +{ 24,16,0,0,4,2,0,0,0,44,44,320,256 }; + +static const UBYTE desktop_body[256] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x0f,0xff,0xc0,0x00,0x00,0x00,0x20,0x00,0x07,0xff, +0xc0,0x00,0x03,0xfd,0x40,0x00,0x1b,0xa0,0x20,0x00,0x00,0x00,0x18,0x00,0x0f, +0xff,0xe0,0x00,0x14,0x00,0x00,0x00,0x1f,0xf4,0x30,0x00,0x00,0x0b,0x88,0x00, +0x0f,0xff,0xe0,0x00,0x05,0x50,0x00,0x00,0x1f,0x2f,0xa0,0x00,0x00,0x2f,0x18, +0x00,0x0f,0x80,0xe0,0x00,0x14,0x01,0x00,0x00,0x1c,0xfe,0x30,0x00,0x02,0xff, +0x88,0x00,0x0f,0x00,0xe0,0x00,0x04,0x0a,0x00,0x00,0x1b,0xf4,0xb0,0x00,0x01, +0xff,0x08,0x00,0x0e,0x01,0xe0,0x00,0x14,0x00,0x00,0x00,0x18,0x5f,0xb0,0x00, +0x03,0xa0,0x48,0x00,0x0f,0xff,0xa0,0x00,0x03,0xe8,0x00,0x00,0x19,0xe8,0x30, +0x00,0x00,0x01,0xc8,0x00,0x0f,0xfe,0x20,0x00,0x00,0x00,0x00,0x00,0x3f,0xff, +0xf8,0x00,0x00,0x00,0x04,0x00,0x1f,0xff,0xf0,0x00,0x0f,0xff,0xc0,0x00,0x62, +0xff,0xc8,0x00,0x0c,0x00,0x16,0x00,0x33,0xff,0xe8,0x00,0x5f,0xf8,0x00,0x00, +0x6f,0xff,0x9c,0x00,0x0c,0x00,0x22,0x00,0x33,0xff,0xc8,0x00,0x00,0x00,0x00, +0x00,0x6a,0xaa,0xac,0x00,0x15,0x55,0x52,0x00,0x2a,0xaa,0xa8,0x00,0x1f,0xfa, +0x00,0x00,0xd4,0x00,0x0c,0x00,0x0a,0xa8,0x53,0x00,0x7f,0xff,0xa4,0x00,0x80, +0x00,0x00,0x00,0xff,0xff,0xfe,0x00,0x00,0x00,0x01,0x00,0x7f,0xff,0xfc,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00, }; + +//---------------------------------------------------------------------------- + +static const ULONG filedisplay_colors[48] = +{ + 0xffffffff,0xaaaaaaaa,0x99999999, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0x44444444,0x44444444,0x44444444, + 0x66666666,0x66666666,0x66666666, + 0x77777777,0x77777777,0x77777777, + 0x44444444,0x88888888,0x88888888, + 0xbbbbbbbb,0x00000000,0x00000000, + 0xffffffff,0x11111111,0x11111111, + 0x88888888,0x88888888,0x88888888, + 0xbbbbbbbb,0xbbbbbbbb,0xbbbbbbbb, + 0x00000000,0x00000000,0x00000000, + 0xcccccccc,0xcccccccc,0xcccccccc, + 0xeeeeeeee,0xeeeeeeee,0xeeeeeeee, + 0xffffffff,0xffffffff,0xffffffff, + 0x00000000,0x55555555,0x77777777, + 0x88888888,0x88888888,0x88888888, +}; + +#define FILEDISPLAY_WIDTH 24 +#define FILEDISPLAY_HEIGHT 16 +#define FILEDISPLAY_DEPTH 4 +#define FILEDISPLAY_COMPRESSION 0 +#define FILEDISPLAY_MASKING 2 + +static const struct BitMapHeader filedisplay_header = +{ 24,16,0,0,4,2,0,0,0,44,44,320,256 }; + +static const UBYTE filedisplay_body[256] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff, +0x00,0x00,0x7f,0xfe,0x00,0x00,0xc0,0x03,0x00,0x00,0x3f,0xfc,0x00,0x00,0xff, +0xff,0x00,0x00,0x7f,0xfe,0x00,0x00,0x80,0x01,0x00,0x00,0x7f,0xfe,0x00,0x00, +0xff,0xf3,0x00,0x00,0x55,0x48,0x00,0x00,0xae,0x85,0x00,0x00,0x51,0x7e,0x00, +0x00,0xd1,0x77,0x00,0x00,0x7f,0x20,0x00,0x00,0x80,0x3f,0xff,0x00,0x7f,0xc0, +0x00,0x00,0xff,0xdf,0xff,0x00,0x54,0x53,0xfe,0x00,0xba,0x5c,0x01,0x00,0x45, +0x83,0x3c,0x00,0xc5,0x9b,0xff,0x00,0x7e,0x37,0xfa,0x00,0x80,0x78,0x11,0x00, +0x7f,0x02,0x6c,0x00,0xff,0xff,0xeb,0x00,0x7e,0x87,0x7e,0x00,0xc0,0xf8,0x01, +0x00,0x3f,0x03,0xbe,0x00,0xff,0x7f,0x7f,0x00,0x00,0x0f,0xde,0x00,0xff,0xf0, +0x15,0x00,0x00,0x02,0x6a,0x00,0xff,0xcf,0xcb,0x00,0x7f,0xbf,0x7e,0x00,0x7f, +0xd4,0x01,0x00,0x00,0x2b,0xbe,0x00,0x00,0x6b,0x7f,0x00,0x00,0x3f,0x72,0x00, +0x00,0x40,0x9d,0x00,0x3f,0xbe,0x7e,0x00,0x00,0x7f,0x63,0x00,0x00,0x27,0x76, +0x00,0x00,0x40,0x1d,0x00,0x00,0x3f,0xbe,0x00,0x00,0x67,0x63,0x00,0x00,0x3f, +0x7e,0x00,0x00,0x60,0x83,0x00,0x00,0x1e,0x7c,0x00,0x00,0x7f,0x7f,0x00,0x00, +0x00,0x00,0x00,0x00,0x7f,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00, }; + +//---------------------------------------------------------------------------- + +static const ULONG icons_colors[48] = +{ + 0xffffffff,0xaaaaaaaa,0x99999999, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0x44444444,0x55555555,0x99999999, + 0xffffffff,0x00000000,0x00000000, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0xaaaaaaaa,0xaaaaaaaa,0xbbbbbbbb, + 0xbbbbbbbb,0xbbbbbbbb,0xcccccccc, + 0x00000000,0x00000000,0x00000000, + 0xcccccccc,0xcccccccc,0xcccccccc, + 0xffffffff,0xffffffff,0xffffffff, + 0x77777777,0x77777777,0x77777777, + 0xeeeeeeee,0x00000000,0x99999999, + 0x00000000,0xdddddddd,0x00000000, + 0x00000000,0xcccccccc,0xcccccccc, + 0x00000000,0x66666666,0xffffffff, + 0x00000000,0x00000000,0xaaaaaaaa, +}; + +#define ICONS_WIDTH 23 +#define ICONS_HEIGHT 16 +#define ICONS_DEPTH 4 +#define ICONS_COMPRESSION 0 +#define ICONS_MASKING 2 + +static const struct BitMapHeader icons_header = +{ 23,16,0,0,4,2,0,0,0,44,44,320,256 }; + +static const UBYTE icons_body[256] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0xff,0xff,0xbc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0xff,0xff, +0xf8,0x00,0x81,0x50,0x20,0x00,0x01,0xf0,0x44,0x00,0x7f,0x5f,0x98,0x00,0x80, +0x00,0x20,0x00,0x82,0xd0,0x64,0x00,0x03,0xf4,0x46,0x00,0x7f,0xfb,0xdc,0x00, +0x81,0x20,0x22,0x00,0x87,0xfc,0x64,0x00,0x0f,0xfc,0x46,0x00,0x77,0xff,0xdc, +0x00,0x80,0x00,0x22,0x00,0xbd,0x6a,0x64,0x00,0x3f,0xfe,0x46,0x00,0x7d,0xff, +0xdc,0x00,0x82,0x94,0x22,0x00,0x85,0xbe,0x64,0x00,0x7f,0xbe,0x46,0x00,0x0f, +0xff,0xdc,0x00,0xba,0x00,0x22,0x00,0xb7,0x2b,0x4c,0x00,0x3f,0xaf,0x7e,0x00, +0x77,0x7f,0xcc,0x00,0x88,0x04,0x22,0x00,0x82,0x8e,0x7c,0x00,0x6b,0x8f,0xc2, +0x00,0x16,0xff,0x44,0x00,0xa1,0x01,0xba,0x00,0x80,0xc0,0x60,0x00,0x22,0xea, +0x44,0x00,0x5d,0xd5,0xd8,0x00,0xa2,0x22,0x20,0x00,0x80,0x80,0x4c,0x00,0x55, +0xd5,0x7e,0x00,0x2a,0xaa,0xcc,0x00,0xd5,0x55,0x22,0x00,0x89,0xd4,0x78,0x00, +0x7f,0xff,0xc6,0x00,0x09,0xd4,0x44,0x00,0xf6,0x2b,0xba,0x00,0xfd,0xff,0xe0, +0x00,0x7f,0xff,0xdc,0x00,0x7d,0xff,0xc0,0x00,0x82,0x00,0x38,0x00,0x3f,0xff, +0xec,0x00,0x7f,0xff,0xde,0x00,0x3f,0xff,0xec,0x00,0x00,0x00,0x02,0x00,0x00, +0x00,0x10,0x00,0x3f,0xff,0xee,0x00,0x00,0x00,0x10,0x00,0x3f,0xff,0xee,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00, }; + +//---------------------------------------------------------------------------- + +static const ULONG misc_colors[48] = +{ + 0xffffffff,0x66666666,0x00000000, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0xffffffff,0x00000000,0x00000000, + 0xbbbbbbbb,0xaaaaaaaa,0x99999999, + 0xffffffff,0xaaaaaaaa,0x99999999, + 0xffffffff,0xffffffff,0xffffffff, + 0x66666666,0x88888888,0xbbbbbbbb, + 0xeeeeeeee,0x00000000,0x99999999, + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xaaaaaaaa,0x88888888, + 0xffffffff,0xeeeeeeee,0x00000000, + 0x00000000,0x88888888,0x00000000, + 0x00000000,0xdddddddd,0x00000000, + 0x00000000,0xcccccccc,0xcccccccc, + 0x00000000,0x66666666,0xffffffff, + 0x00000000,0x00000000,0xaaaaaaaa, +}; + +#define MISC_WIDTH 23 +#define MISC_HEIGHT 9 +#define MISC_DEPTH 4 +#define MISC_COMPRESSION 0 +#define MISC_MASKING 2 + +static const struct BitMapHeader misc_header = +{ 23,9,0,0,4,2,0,0,0,44,44,320,256 }; + +static const UBYTE misc_body[144] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x38, +0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x38,0x00,0x00,0x38,0x00,0x38,0x00,0x44, +0x44,0x44,0x00,0x22,0x7e,0x22,0x00,0x5c,0x5c,0x00,0x00,0x7e,0x22,0x7e,0x00, +0x80,0x80,0x80,0x00,0x02,0x7e,0x02,0x00,0x7c,0x7c,0x00,0x00,0x7e,0x02,0x7e, +0x00,0x80,0x80,0x80,0x00,0x02,0x7e,0x02,0x00,0x7c,0x7c,0x00,0x00,0x7e,0x02, +0x7e,0x00,0x80,0x80,0x80,0x00,0x04,0x3c,0x04,0x00,0x38,0x38,0x00,0x00,0x3c, +0x04,0x3c,0x00,0x40,0x40,0x40,0x00,0x38,0x38,0x38,0x00,0x00,0x00,0x00,0x00, +0x38,0x38,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, }; + +//---------------------------------------------------------------------------- + +static const ULONG modules_colors[48] = +{ + 0xffffffff,0xaaaaaaaa,0x99999999, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0x00000000,0x55555555,0x77777777, + 0x77777777,0x77777777,0x77777777, + 0x00000000,0x66666666,0x99999999, + 0x33333333,0xcccccccc,0xcccccccc, + 0x44444444,0x88888888,0x88888888, + 0xbbbbbbbb,0x00000000,0x00000000, + 0xffffffff,0x11111111,0x11111111, + 0xaaaaaaaa,0x88888888,0x77777777, + 0xeeeeeeee,0xbbbbbbbb,0x00000000, + 0x88888888,0x88888888,0x88888888, + 0x88888888,0x88888888,0xffffffff, + 0xbbbbbbbb,0xcccccccc,0xdddddddd, + 0x00000000,0x22222222,0x44444444, + 0xeeeeeeee,0xeeeeeeee,0xeeeeeeee, +}; + +#define MODULES_WIDTH 24 +#define MODULES_HEIGHT 15 +#define MODULES_DEPTH 4 +#define MODULES_COMPRESSION 0 +#define MODULES_MASKING 2 + +static const struct BitMapHeader modules_header = +{ 24,15,0,0,4,2,0,0,0,44,44,320,256 }; + +static const UBYTE modules_body[240] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x24,0x00,0x00,0x00,0x3e,0x48,0x00,0x00,0x18,0x00,0x00,0x00,0x02,0x48, +0x00,0x00,0x5a,0x0b,0xa0,0x00,0x67,0x2d,0x60,0x00,0x3c,0x0d,0x40,0x00,0x05, +0x2d,0x40,0x00,0x21,0x14,0x48,0x00,0x47,0x92,0x78,0x00,0x7a,0x12,0x70,0x00, +0x02,0x97,0xb0,0x00,0x21,0x2e,0x12,0x00,0x4f,0x61,0x1e,0x00,0x72,0x21,0x1c, +0x00,0x02,0x6f,0xec,0x00,0x43,0xdf,0x05,0x00,0x7f,0x40,0xe7,0x00,0x24,0xc0, +0xe6,0x00,0x04,0xdf,0xfa,0x00,0x27,0x80,0x20,0x00,0x3f,0x7f,0xe1,0x00,0x18, +0xff,0xe1,0x00,0x18,0x7f,0xdf,0x00,0xfc,0xdc,0x24,0x00,0xfc,0x1f,0xe7,0x00, +0x00,0xff,0xe7,0x00,0x00,0x03,0xdb,0x00,0xf0,0x83,0x10,0x00,0xf4,0x53,0xdf, +0x00,0x7c,0xbb,0xdf,0x00,0x7c,0x04,0xef,0x00,0xc0,0x80,0x40,0x00,0xfc,0x74, +0x79,0x00,0x7c,0x8e,0x7f,0x00,0x4c,0x01,0xb9,0x00,0xc0,0x80,0x80,0x00,0xfc, +0x7d,0xe5,0x00,0x7c,0x9b,0xff,0x00,0x4c,0x18,0x65,0x00,0x82,0x80,0x00,0x00, +0xbe,0x7f,0xdd,0x00,0x7c,0xbc,0xff,0x00,0x7c,0x3c,0xdd,0x00,0x83,0x80,0x00, +0x00,0xff,0x7d,0xbd,0x00,0x7c,0xbe,0xff,0x00,0x7c,0x3c,0xbd,0x00,0x7f,0x00, +0x00,0x00,0x7f,0x7d,0xbd,0x00,0x00,0x3e,0xff,0x00,0x00,0x3c,0xbd,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + }; + +//---------------------------------------------------------------------------- + +static const ULONG paths_colors[48] = +{ + 0xffffffff,0xeeeeeeee,0x00000000, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0x33333333,0x77777777,0xaaaaaaaa, + 0xffffffff,0x00000000,0x00000000, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0xffffffff,0xaaaaaaaa,0x99999999, + 0xffffffff,0xffffffff,0xffffffff, + 0x77777777,0x77777777,0x77777777, + 0xeeeeeeee,0x00000000,0x99999999, + 0xffffffff,0xaaaaaaaa,0x88888888, + 0x00000000,0x00000000,0x00000000, + 0x00000000,0x88888888,0x00000000, + 0x00000000,0xdddddddd,0x00000000, + 0x00000000,0xcccccccc,0xcccccccc, + 0x00000000,0x66666666,0xffffffff, + 0x00000000,0x00000000,0xaaaaaaaa, +}; + +#define PATHS_WIDTH 23 +#define PATHS_HEIGHT 16 +#define PATHS_DEPTH 4 +#define PATHS_COMPRESSION 0 +#define PATHS_MASKING 2 + +static const struct BitMapHeader paths_header = +{ 23,16,0,0,4,2,0,0,0,44,44,320,256 }; + +static const UBYTE paths_body[256] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x21,0x08,0x00,0x03,0xef,0x78,0x00,0x00,0x21,0x08,0x00,0x00,0x00, +0x00,0x00,0x00,0x10,0x8c,0x00,0xfb,0xff,0xfc,0x00,0x01,0xde,0xfc,0x00,0x00, +0x00,0x00,0x00,0x00,0x42,0x10,0x00,0xff,0x39,0xcc,0x00,0x79,0xef,0x78,0x00, +0x00,0x00,0x00,0x00,0x08,0x00,0xd2,0x00,0xc7,0xff,0xe6,0x00,0x7c,0x00,0xfa, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xaa,0x00,0xff,0xff,0xc6,0x00,0x7f,0xff, +0xba,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x00,0xff,0xff,0x46,0x00,0x7f, +0xff,0xba,0x00,0x00,0x00,0x44,0x00,0x08,0x00,0x2a,0x00,0xe2,0xab,0x46,0x00, +0x7f,0xff,0xba,0x00,0x00,0x00,0x44,0x00,0x01,0x04,0x12,0x00,0xf4,0x53,0x46, +0x00,0x7f,0xff,0xba,0x00,0x00,0x00,0x44,0x00,0x10,0x00,0x2a,0x00,0xea,0xab, +0x46,0x00,0x7f,0xff,0xba,0x00,0x00,0x00,0x44,0x00,0x08,0x04,0x12,0x00,0xf5, +0x53,0x46,0x00,0x7f,0xff,0xba,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x02,0x00, +0xff,0xff,0x7e,0x00,0x7f,0xff,0x82,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x3e, +0x00,0x80,0x00,0x7e,0x00,0x7f,0xff,0xbe,0x00,0x00,0x00,0x40,0x00,0x00,0x00, +0x20,0x00,0xff,0xff,0xe0,0x00,0x00,0x00,0x20,0x00,0xff,0xff,0xc0,0x00,0x7f, +0xff,0xe0,0x00,0x7f,0xff,0xe0,0x00,0x7f,0xff,0xe0,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00, }; + +//---------------------------------------------------------------------------- + +static const ULONG plugins_colors[48] = +{ + 0x00000000,0xdddddddd,0x00000000, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0x33333333,0x77777777,0xaaaaaaaa, + 0xffffffff,0x00000000,0x00000000, + 0xaaaaaaaa,0x88888888,0x77777777, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0xaaaaaaaa,0xaaaaaaaa,0xbbbbbbbb, + 0xffffffff,0xaaaaaaaa,0x99999999, + 0xffffffff,0xffffffff,0xffffffff, + 0x77777777,0x77777777,0x77777777, + 0xeeeeeeee,0x00000000,0x99999999, + 0x00000000,0x88888888,0x00000000, + 0x00000000,0x00000000,0x00000000, + 0x00000000,0xcccccccc,0xcccccccc, + 0x00000000,0x66666666,0xffffffff, + 0x00000000,0x00000000,0xaaaaaaaa, +}; + +#define PLUGINS_WIDTH 23 +#define PLUGINS_HEIGHT 16 +#define PLUGINS_DEPTH 4 +#define PLUGINS_COMPRESSION 0 +#define PLUGINS_MASKING 2 + +static const struct BitMapHeader plugins_header = +{ 23,16,0,0,4,2,0,0,0,44,44,320,256 }; + +static const UBYTE plugins_body[256] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff, +0xfc,0x00,0x6a,0x82,0x00,0x00,0x2a,0x82,0x04,0x00,0x7f,0xdf,0xd8,0x00,0x80, +0x20,0x20,0x00,0x41,0xca,0x02,0x00,0x00,0x8e,0x00,0x00,0x61,0xfa,0xfc,0x00, +0x9e,0x31,0xb6,0x00,0x40,0x02,0x3a,0x00,0x00,0x40,0x08,0x00,0x6f,0xb3,0x3c, +0x00,0x9f,0x0c,0xc6,0x00,0x54,0xd0,0x02,0x00,0x02,0x80,0x10,0x00,0x79,0xd7, +0x6c,0x00,0x8d,0x2f,0xe6,0x00,0x10,0x40,0x22,0x00,0x04,0x40,0x10,0x00,0x7b, +0xd7,0x4c,0x00,0x8b,0x3f,0xe6,0x00,0x20,0xc8,0x02,0x00,0x20,0x60,0x10,0x00, +0x7e,0xdf,0x6c,0x00,0x8e,0x17,0xe6,0x00,0x08,0xc0,0xf2,0x00,0x04,0x80,0x10, +0x00,0x4f,0xf8,0xfc,0x00,0xb0,0x07,0x06,0x00,0x06,0x20,0x12,0x00,0x04,0x20, +0x30,0x00,0x5e,0xf7,0xdc,0x00,0xb9,0x8f,0xc6,0x00,0x04,0x01,0x52,0x00,0x05, +0x06,0xb0,0x00,0x5e,0xb0,0x1c,0x00,0xb8,0xe9,0x46,0x00,0x7e,0xaa,0xa2,0x00, +0x00,0xa8,0x20,0x00,0x01,0xff,0xfc,0x00,0xff,0x55,0x46,0x00,0x80,0x00,0x02, +0x00,0x40,0x55,0x40,0x00,0xbf,0x00,0x3c,0x00,0x3f,0xaa,0xbe,0x00,0x3e,0x00, +0x1e,0x00,0x01,0xaa,0xa0,0x00,0x00,0x55,0x40,0x00,0x3e,0x55,0x5e,0x00,0x00, +0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xe0,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00, }; + +//---------------------------------------------------------------------------- + +static const ULONG startup_colors[48] = +{ + 0x00000000,0xdddddddd,0x00000000, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0x33333333,0x77777777,0xaaaaaaaa, + 0xffffffff,0x00000000,0x00000000, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0xaaaaaaaa,0xbbbbbbbb,0xcccccccc, + 0xbbbbbbbb,0xbbbbbbbb,0xcccccccc, + 0xffffffff,0xaaaaaaaa,0x99999999, + 0xffffffff,0xffffffff,0xffffffff, + 0x77777777,0x77777777,0x77777777, + 0xeeeeeeee,0x00000000,0x99999999, + 0x00000000,0x88888888,0x00000000, + 0x00000000,0x00000000,0x00000000, + 0x00000000,0xcccccccc,0xcccccccc, + 0x00000000,0x66666666,0xffffffff, + 0x00000000,0x00000000,0xaaaaaaaa, +}; + +#define STARTUP_WIDTH 23 +#define STARTUP_HEIGHT 16 +#define STARTUP_DEPTH 4 +#define STARTUP_COMPRESSION 0 +#define STARTUP_MASKING 2 + +static const struct BitMapHeader startup_header = +{ 23,16,0,0,4,2,0,0,0,44,44,320,256 }; + +static const UBYTE startup_body[256] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x3e, +0x00,0x00,0x00,0x2a,0x00,0x00,0x00,0x2b,0x04,0x00,0x00,0xeb,0x80,0x00,0x00, +0x94,0x80,0x00,0x00,0xe0,0x82,0x00,0x00,0xe0,0x00,0x00,0x01,0xfe,0xcc,0x00, +0x01,0x01,0x4e,0x00,0x01,0x80,0x82,0x00,0x01,0xb0,0x90,0x00,0x03,0xcf,0xe4, +0x00,0x02,0x0f,0x2e,0x00,0x9f,0xfc,0x22,0x00,0x20,0x03,0x20,0x00,0x60,0x01, +0xa4,0x00,0x9f,0xfc,0xde,0x00,0x80,0x00,0x92,0x00,0x00,0x05,0x50,0x00,0x60, +0x03,0x14,0x00,0x9f,0xfa,0xae,0x00,0xa8,0x00,0x22,0x00,0x05,0x01,0x20,0x00, +0x42,0xaf,0xa4,0x00,0xb8,0x56,0xde,0x00,0xa0,0x00,0x02,0x00,0x00,0x01,0x00, +0x00,0x45,0x56,0xfc,0x00,0xba,0xae,0xfe,0x00,0xa0,0x01,0x7e,0x00,0x00,0x00, +0x00,0x00,0x4a,0xae,0x00,0x00,0xb5,0x57,0x7e,0x00,0xa0,0x01,0x00,0x00,0x00, +0x00,0x00,0x00,0x45,0x56,0x00,0x00,0xba,0xaf,0x00,0x00,0x9f,0xf9,0x00,0x00, +0x00,0x00,0x00,0x00,0x60,0x06,0x00,0x00,0x9f,0xff,0x00,0x00,0x80,0x01,0x00, +0x00,0x3f,0xf8,0x00,0x00,0x40,0x06,0x00,0x00,0x80,0x07,0x00,0x00,0x00,0x01, +0x00,0x00,0x55,0x54,0x00,0x00,0x2a,0xaa,0x00,0x00,0x2a,0xab,0x00,0x00,0x3f, +0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00, }; + +//---------------------------------------------------------------------------- + +static const ULONG windows_colors[48] = +{ + 0xffffffff,0xeeeeeeee,0x00000000, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0x33333333,0x77777777,0xaaaaaaaa, + 0xffffffff,0x00000000,0x00000000, + 0x99999999,0x99999999,0x99999999, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0xffffffff,0xaaaaaaaa,0x99999999, + 0xffffffff,0xffffffff,0xffffffff, + 0x77777777,0x77777777,0x77777777, + 0xeeeeeeee,0x00000000,0x99999999, + 0x00000000,0x00000000,0x00000000, + 0x00000000,0x88888888,0x00000000, + 0x00000000,0xdddddddd,0x00000000, + 0x00000000,0xcccccccc,0xcccccccc, + 0x00000000,0x66666666,0xffffffff, + 0x00000000,0x00000000,0xaaaaaaaa, +}; + +#define WINDOWS_WIDTH 23 +#define WINDOWS_HEIGHT 16 +#define WINDOWS_DEPTH 4 +#define WINDOWS_COMPRESSION 0 +#define WINDOWS_MASKING 2 + +static const struct BitMapHeader windows_header = +{ 23,16,0,0,4,2,0,0,0,44,44,320,256 }; + +static const UBYTE windows_body[256] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0xff,0xff,0xf8,0x00,0xff,0xff,0xf8,0x00,0xff,0xff,0xf8,0x00,0x00,0x00, +0x00,0x00,0x90,0x00,0x90,0x00,0xff,0xff,0xfc,0x00,0x90,0x00,0x90,0x00,0x00, +0x01,0x24,0x00,0x80,0x00,0x00,0x00,0x7f,0xff,0xfc,0x00,0x80,0x00,0x00,0x00, +0x7f,0xff,0xfe,0x00,0xbf,0xff,0xf8,0x00,0xc0,0x00,0x0c,0x00,0xbf,0xff,0xf8, +0x00,0x40,0x00,0x06,0x00,0xbe,0x03,0xf8,0x00,0xc1,0xfc,0x0c,0x00,0xbe,0x03, +0xf8,0x00,0x40,0x04,0x06,0x00,0xbe,0xc1,0xf8,0x00,0xc1,0xfc,0x0c,0x00,0xbe, +0xdb,0xf8,0x00,0x40,0x04,0x06,0x00,0xbe,0x01,0xf8,0x00,0xc1,0xfc,0x0c,0x00, +0xbe,0x01,0xf8,0x00,0x40,0x26,0x06,0x00,0xbe,0x19,0xf8,0x00,0xc1,0xfc,0x0c, +0x00,0xbe,0xd9,0xf8,0x00,0x40,0x06,0x06,0x00,0xbe,0x01,0xf8,0x00,0xc1,0xfc, +0x0c,0x00,0xbe,0x01,0xf8,0x00,0x41,0xfe,0x06,0x00,0xbf,0x01,0xf8,0x00,0xc0, +0x00,0x0c,0x00,0xbf,0x81,0xf8,0x00,0x40,0x7e,0x06,0x00,0xbf,0xff,0xf8,0x00, +0xff,0xff,0xfc,0x00,0xbf,0xff,0xf8,0x00,0x40,0x00,0x06,0x00,0x80,0x00,0x10, +0x00,0xff,0xff,0xfc,0x00,0x80,0x00,0x10,0x00,0x00,0x00,0x06,0x00,0x80,0x00, +0x00,0x00,0xff,0xff,0xfc,0x00,0x80,0x00,0x00,0x00,0x7f,0xff,0xfe,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xfe,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00, }; + +//---------------------------------------------------------------------------- + +static const ULONG textwindows_colors[] = +{ + 0x00000000,0x00000000,0x00000000, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0x33333333,0x77777777,0xaaaaaaaa, + 0xffffffff,0xeeeeeeee,0x00000000, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0xffffffff,0xffffffff,0xffffffff, + 0x77777777,0x77777777,0x77777777, + 0x66666666,0x22222222,0x00000000, + 0xffffffff,0x66666666,0x00000000, + 0xffffffff,0xaaaaaaaa,0x88888888, + 0xffffffff,0xeeeeeeee,0x00000000, + 0x00000000,0x88888888,0x00000000, + 0x00000000,0xdddddddd,0x00000000, + 0x00000000,0xcccccccc,0xcccccccc, + 0x00000000,0x66666666,0xffffffff, + 0x00000000,0x00000000,0xaaaaaaaa, +}; + +#define TEXTWINDOWS_WIDTH 23 +#define TEXTWINDOWS_HEIGHT 14 +#define TEXTWINDOWS_DEPTH 4 +#define TEXTWINDOWS_COMPRESSION 0 +#define TEXTWINDOWS_MASKING 2 + +static const struct BitMapHeader textwindows_header = +{ 23,14,0,0,4,2,0,0,8,22,22,640,512 }; + +static const UBYTE textwindows_body[] = { +0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xf8,0x00,0x00,0x00,0x07, +0xff,0x90,0x00,0x90,0x00,0x6f,0xfe,0x48,0x00,0x90,0x00,0x90,0x00,0x00,0x00, +0x03,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x80,0x00,0x02,0x00,0x00, +0x00,0x01,0xff,0x80,0x00,0x08,0x00,0x00,0x00,0x02,0x00,0xbf,0xff,0xfa,0x00, +0x00,0x00,0x01,0xff,0x80,0x00,0x08,0x00,0x00,0x00,0x02,0x00,0xa1,0x04,0x1a, +0x00,0x00,0x00,0x01,0xff,0x80,0x00,0x08,0x00,0x00,0x00,0x02,0x00,0xbf,0xff, +0xfa,0x00,0x00,0x00,0x01,0xff,0x80,0x00,0x08,0x00,0x00,0x00,0x02,0x00,0xa7, +0x0c,0x7a,0x00,0x00,0x00,0x01,0xff,0x80,0x00,0x08,0x00,0x00,0x00,0x02,0x00, +0xbf,0xff,0xfa,0x00,0x00,0x00,0x01,0xff,0x80,0x00,0x08,0x00,0x00,0x00,0x02, +0x00,0xa3,0x1c,0x3a,0x00,0x00,0x00,0x01,0xff,0x80,0x00,0x08,0x00,0x00,0x00, +0x02,0x00,0xbf,0xff,0xfa,0x00,0x00,0x00,0x01,0xff,0xbf,0xff,0xf8,0x00,0x00, +0x00,0x02,0x00,0xbf,0xff,0xfa,0x00,0x00,0x00,0x01,0xff,0x80,0x00,0x10,0x00, +0x7f,0xff,0xea,0x00,0x80,0x00,0x12,0x00,0x00,0x00,0x01,0xff,0x80,0x00,0x00, +0x00,0x00,0x00,0x02,0x00,0x80,0x00,0x02,0x00,0x00,0x00,0x01,0xff,0x00,0x00, +0x00,0x00,0x7f,0xff,0xfe,0x00,0x7f,0xff,0xfe,0x00,0x80,0x00,0x01,0xff, }; +//---------------------------------------------------------------------------- + +static const ULONG delete_colors[48] = +{ + 0xefefefef,0xe7e7e7e7,0x14141414, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0x44444444,0x44444444,0x44444444, + 0x66666666,0x66666666,0x66666666, + 0x00000000,0x66666666,0x99999999, + 0x33333333,0x77777777,0xaaaaaaaa, + 0x66666666,0x88888888,0xbbbbbbbb, + 0x88888888,0x88888888,0x88888888, + 0x99999999,0x99999999,0x99999999, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0xbbbbbbbb,0xbbbbbbbb,0xbbbbbbbb, + 0xcccccccc,0xcccccccc,0xcccccccc, + 0x33333333,0x33333333,0x33333333, + 0x00000000,0x00000000,0x00000000, + 0x00000000,0x66666666,0xffffffff, + 0x00000000,0x00000000,0xaaaaaaaa, +}; + +#define DELETE_WIDTH 26 +#define DELETE_HEIGHT 27 +#define DELETE_DEPTH 4 +#define DELETE_COMPRESSION 0 +#define DELETE_MASKING 2 + +static const struct BitMapHeader delete_header = +{ 26,27,0,0,4,2,0,0,0,44,44,320,256 }; + +static const UBYTE delete_body[432] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0xa2,0xc0,0x00,0x00,0x7d,0x40,0x00,0x00,0x00,0x40,0x00,0x00, +0xff,0x80,0x00,0x03,0xe0,0x78,0x00,0x04,0x9f,0xf8,0x00,0x00,0xe0,0x38,0x00, +0x07,0x60,0x00,0x00,0x1e,0x00,0xbe,0x00,0x15,0xff,0xfe,0x00,0x06,0x00,0x06, +0x00,0x1a,0x00,0x00,0x00,0x08,0x01,0x7f,0x00,0x37,0xff,0xfd,0x00,0x08,0x00, +0x09,0x00,0x28,0x00,0x02,0x00,0x20,0x02,0xfd,0x00,0x1f,0xff,0xff,0x00,0x00, +0x00,0x14,0x00,0x20,0x00,0x02,0x00,0x30,0x05,0xfc,0x00,0x3f,0xff,0xff,0x00, +0x20,0x00,0x28,0x00,0x00,0x00,0x02,0x00,0x10,0x0b,0xf8,0x00,0x1f,0xff,0xf6, +0x00,0x10,0x00,0x40,0x00,0x00,0x00,0x0c,0x00,0x0f,0x97,0xc0,0x00,0x0f,0xff, +0xfe,0x00,0x1e,0x00,0x80,0x00,0x00,0x00,0x30,0x00,0x03,0xff,0xc0,0x00,0x03, +0xfa,0x3a,0x00,0x1d,0xfa,0x04,0x00,0x00,0x05,0xc0,0x00,0x00,0xfd,0x00,0x00, +0x00,0xff,0xd4,0x00,0x0f,0x00,0x28,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, +0x00,0x08,0x00,0x2c,0x00,0x07,0xff,0xd0,0x00,0x00,0x00,0x00,0x00,0x02,0xff, +0x00,0x00,0x00,0x00,0x14,0x00,0x0f,0xff,0xe8,0x00,0x00,0x00,0x00,0x00,0x01, +0x02,0x00,0x00,0x04,0xfc,0x28,0x00,0x03,0xff,0xd0,0x00,0x00,0x00,0x00,0x00, +0x00,0x81,0x00,0x00,0x04,0x7e,0x58,0x00,0x03,0xef,0xa0,0x00,0x00,0x10,0x00, +0x00,0x01,0x42,0x00,0x00,0x00,0x3c,0x28,0x00,0x07,0xff,0xd0,0x00,0x00,0x00, +0x00,0x00,0x00,0x84,0x00,0x00,0x00,0x78,0x50,0x00,0x03,0xef,0xa0,0x00,0x00, +0x10,0x00,0x00,0x00,0x42,0x00,0x00,0x02,0x3c,0xb0,0x00,0x01,0xff,0x40,0x00, +0x00,0x00,0x00,0x00,0x00,0xa4,0x00,0x00,0x02,0x18,0x50,0x00,0x01,0xef,0xa0, +0x00,0x00,0x10,0x00,0x00,0x06,0x68,0x18,0x00,0x07,0x10,0xb8,0x00,0x04,0xff, +0x48,0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x3e,0x00,0x1f,0xc1,0xfe,0x00,0x18, +0x3e,0x06,0x00,0x00,0x00,0x00,0x00,0x0f,0xc0,0xfc,0x00,0x0f,0xff,0xfc,0x00, +0x0e,0x00,0x1c,0x00,0x00,0x00,0x00,0x00,0x03,0xff,0xf0,0x00,0x03,0xff,0xf0, +0x00,0x03,0x80,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc0,0x00,0x00,0xff, +0xc0,0x00,0x00,0xff,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, }; + +//---------------------------------------------------------------------------- + +static const ULONG empty_trashcan_colors[48] = +{ + 0xefefefef,0xe7e7e7e7,0x14141414, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0x44444444,0x44444444,0x44444444, + 0x66666666,0x66666666,0x66666666, + 0x00000000,0x66666666,0x99999999, + 0x33333333,0x77777777,0xaaaaaaaa, + 0x66666666,0x88888888,0xbbbbbbbb, + 0x88888888,0x88888888,0x88888888, + 0x99999999,0x99999999,0x99999999, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0xbbbbbbbb,0xbbbbbbbb,0xbbbbbbbb, + 0xcccccccc,0xcccccccc,0xcccccccc, + 0xdddddddd,0xdddddddd,0xdddddddd, + 0xffffffff,0xffffffff,0xffffffff, + 0x33333333,0x33333333,0x33333333, + 0x00000000,0x00000000,0x00000000, +}; + +#define EMPTY_TRASHCAN_WIDTH 26 +#define EMPTY_TRASHCAN_HEIGHT 29 +#define EMPTY_TRASHCAN_DEPTH 4 +#define EMPTY_TRASHCAN_COMPRESSION 0 +#define EMPTY_TRASHCAN_MASKING 2 + +static const struct BitMapHeader empty_trashcan_header = +{ 26,29,0,0,4,2,0,0,0,44,44,320,256 }; + +static const UBYTE empty_trashcan_body[464] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x00,0x00,0x00,0x00,0xc0,0x00,0x00, +0x00,0xc0,0x00,0x00,0x43,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x63,0xc0,0x00, +0x00,0x63,0xc0,0x00,0x01,0xec,0x40,0x00,0x00,0x70,0x40,0x00,0x01,0xaf,0xc0, +0x00,0x01,0xdf,0x80,0x00,0x07,0xf2,0x98,0x00,0x01,0xe2,0xb8,0x00,0x06,0x1d, +0x58,0x00,0x07,0xff,0xc0,0x00,0x1f,0xb7,0xde,0x00,0x07,0xb6,0xde,0x00,0x18, +0x59,0x36,0x00,0x1f,0xef,0xf0,0x00,0x1e,0x97,0x0f,0x00,0x2e,0x9d,0x0d,0x00, +0x11,0x62,0xf9,0x00,0x3f,0xf7,0xfa,0x00,0x3a,0x43,0x25,0x00,0x12,0x48,0x27, +0x00,0x0d,0xb7,0xdc,0x00,0x3f,0xf7,0xfe,0x00,0x31,0x35,0x88,0x00,0x31,0x05, +0x8f,0x00,0x2e,0xfa,0xf0,0x00,0x0f,0xff,0x7e,0x00,0x14,0xfa,0x28,0x00,0x1c, +0x3a,0x76,0x00,0x13,0xc5,0x80,0x00,0x07,0xff,0xbc,0x00,0x0f,0xd7,0x80,0x00, +0x0f,0xd7,0xfe,0x00,0x1e,0x28,0x00,0x00,0x00,0x7f,0xf0,0x00,0x03,0xff,0xc0, +0x00,0x03,0xfa,0x3a,0x00,0x1d,0xfa,0x04,0x00,0x00,0x05,0xc0,0x00,0x00,0xfd, +0x00,0x00,0x00,0xff,0xd4,0x00,0x0f,0x00,0x28,0x00,0x00,0x00,0x00,0x00,0x01, +0x00,0x00,0x00,0x08,0x00,0x2c,0x00,0x07,0xff,0xd0,0x00,0x00,0x00,0x00,0x00, +0x02,0xff,0x00,0x00,0x00,0x00,0x14,0x00,0x0f,0xff,0xe8,0x00,0x00,0x00,0x00, +0x00,0x01,0x02,0x00,0x00,0x04,0xfc,0x28,0x00,0x03,0xff,0xd0,0x00,0x00,0x00, +0x00,0x00,0x00,0x81,0x00,0x00,0x04,0x7e,0x58,0x00,0x03,0xef,0xa0,0x00,0x00, +0x10,0x00,0x00,0x01,0x42,0x00,0x00,0x00,0x3c,0x28,0x00,0x07,0xff,0xd0,0x00, +0x00,0x00,0x00,0x00,0x00,0x84,0x00,0x00,0x00,0x78,0x50,0x00,0x03,0xef,0xa0, +0x00,0x00,0x10,0x00,0x00,0x00,0x42,0x00,0x00,0x02,0x3c,0xb0,0x00,0x01,0xff, +0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa4,0x00,0x00,0x02,0x18,0x50,0x00,0x01, +0xef,0xa0,0x00,0x00,0x10,0x00,0x00,0x06,0x68,0x18,0x00,0x07,0x10,0xb8,0x00, +0x04,0xff,0x48,0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x3e,0x00,0x1f,0xc1,0xfe, +0x00,0x18,0x3e,0x06,0x00,0x00,0x00,0x00,0x00,0x0f,0xc0,0xfc,0x00,0x0f,0xff, +0xfc,0x00,0x0e,0x00,0x1c,0x00,0x00,0x00,0x00,0x00,0x03,0xff,0xf0,0x00,0x03, +0xff,0xf0,0x00,0x03,0x80,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc0,0x00, +0x00,0xff,0xc0,0x00,0x00,0xff,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, }; + +//---------------------------------------------------------------------------- + +static const ULONG execute_command_colors[48] = +{ + 0xf7f7f7f7,0x69696969,0xa2a2a2a2, + 0x31313131,0x31313131,0x31313131, + 0x61616161,0x65656565,0x61616161, + 0x00000000,0x00000000,0x00000000, + 0x49494949,0x4d4d4d4d,0x49494949, + 0xf7f7f7f7,0xaaaaaaaa,0x92929292, + 0x00000000,0x61616161,0x9a9a9a9a, + 0x39393939,0x65656565,0xa2a2a2a2, + 0x69696969,0x8a8a8a8a,0xb6b6b6b6, + 0x8a8a8a8a,0x8a8a8a8a,0x8a8a8a8a, + 0xaaaaaaaa,0xaaaaaaaa,0xa6a6a6a6, + 0xb6b6b6b6,0xb6b6b6b6,0xb2b2b2b2, + 0xcececece,0xbabababa,0xb6b6b6b6, + 0xc6c6c6c6,0xcacacaca,0xc6c6c6c6, + 0x92929292,0x92929292,0x92929292, + 0xf7f7f7f7,0xfbfbfbfb,0xf7f7f7f7, +}; + +#define EXECUTE_COMMAND_WIDTH 42 +#define EXECUTE_COMMAND_HEIGHT 37 +#define EXECUTE_COMMAND_DEPTH 4 +#define EXECUTE_COMMAND_COMPRESSION 0 +#define EXECUTE_COMMAND_MASKING 2 + +static const struct BitMapHeader execute_command_header = +{ 42,37,0,0,4,2,0,0,0,44,44,320,256 }; + +static const UBYTE execute_command_body[888] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,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,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00, +0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x04,0x80,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xff,0xff,0xff,0xff,0x00,0x01,0xff,0xff, +0xff,0xff,0x00,0x01,0xff,0xff,0xff,0xfe,0x00,0x01,0xff,0xff,0xff,0xfe,0x00, +0x01,0x19,0x5b,0xea,0xb1,0x00,0x01,0x19,0x5b,0xff,0xff,0x00,0x01,0x09,0x5b, +0xff,0xde,0x00,0x01,0xee,0xa4,0x02,0x10,0x00,0x01,0x18,0xae,0xf7,0x31,0x00, +0x01,0x18,0xae,0xff,0xff,0x00,0x01,0x08,0xae,0xff,0xde,0x00,0x01,0xef,0x51, +0x02,0x10,0x00,0x01,0x19,0x5b,0xea,0xb1,0x00,0x01,0x19,0x5b,0xff,0xff,0x00, +0x01,0x09,0x5b,0xff,0xde,0x00,0x01,0xee,0xa4,0x02,0x10,0x00,0x1d,0xff,0xff, +0xff,0xff,0x00,0x1d,0xff,0xff,0xff,0xff,0x00,0x01,0x00,0x00,0x00,0x00,0x00, +0x01,0x00,0x00,0x00,0x00,0x00,0x3f,0x71,0xff,0xff,0xfd,0x00,0x3f,0x6e,0xa0, +0x01,0x55,0x00,0x01,0x35,0xff,0xfe,0xac,0x00,0x01,0xbf,0xff,0xff,0xfe,0x00, +0x3f,0x61,0xff,0xff,0xfd,0x00,0x3f,0x7f,0x00,0x00,0xad,0x00,0x01,0x21,0xff, +0xff,0x54,0x00,0x01,0xbf,0xff,0xff,0xfe,0x00,0x3f,0x4b,0xff,0xff,0xfd,0x00, +0x3f,0x7e,0xf0,0x55,0x55,0x00,0x01,0x17,0x0f,0xaa,0xac,0x00,0x01,0xb7,0x0f, +0xff,0xfe,0x00,0x1f,0x47,0xff,0xff,0xfd,0x00,0x1f,0x7d,0xf0,0x02,0xbd,0x00, +0x01,0x2b,0x0f,0xfd,0x44,0x00,0x01,0xbb,0x0f,0xff,0xfe,0x00,0x03,0x43,0xff, +0xff,0xfd,0x00,0x03,0x7e,0xf1,0x55,0x55,0x00,0x01,0x15,0x0e,0xaa,0xac,0x00, +0x01,0xbd,0x0f,0xff,0xfe,0x00,0x03,0x44,0xff,0xff,0xfd,0x00,0x03,0x7f,0xf0, +0xaa,0xfd,0x00,0x01,0x2b,0x0f,0x55,0x04,0x00,0x01,0xbb,0x0f,0xff,0xfe,0x00, +0x07,0x48,0xff,0xff,0xfd,0x00,0x07,0x7f,0xf5,0x55,0x5d,0x00,0x01,0x15,0x0a, +0xaa,0xa4,0x00,0x01,0xb7,0x0f,0xff,0xfe,0x00,0x07,0x40,0x3f,0xff,0xfd,0x00, +0x07,0x7f,0xc2,0xbf,0xfd,0x00,0x01,0x3f,0xfd,0x40,0x04,0x00,0x01,0xbf,0xff, +0xff,0xfe,0x00,0x07,0x40,0x1f,0xff,0xed,0x00,0x0f,0x7f,0xf5,0x57,0xfd,0x00, +0x01,0x1f,0xea,0xa8,0x04,0x00,0x01,0xbf,0xff,0xff,0xfe,0x00,0x0f,0x40,0x0f, +0xff,0xfd,0x00,0x07,0x7f,0xf8,0xff,0xfd,0x00,0x01,0x3f,0x77,0x00,0x04,0x00, +0x01,0xbf,0x7f,0xff,0xfe,0x00,0x0f,0x60,0x1f,0xff,0xad,0x00,0x0f,0x5f,0xf5, +0x5f,0xfd,0x00,0x01,0x3a,0xaa,0xa0,0x04,0x00,0x01,0xba,0xbf,0xff,0xfe,0x00, +0x0f,0x70,0x0f,0xff,0xfd,0x00,0x0d,0x4f,0xfb,0xff,0xfd,0x00,0x01,0x3f,0xd4, +0x00,0x04,0x00,0x03,0xbf,0xdf,0xff,0xfe,0x00,0x07,0xf0,0x07,0xfa,0xad,0x00, +0x0f,0xff,0xfd,0x7f,0xfd,0x00,0x00,0x0a,0xaa,0x80,0x04,0x00,0x00,0x1a,0xaf, +0xff,0xfe,0x00,0x03,0xe0,0x03,0xff,0x55,0x00,0x07,0xff,0xff,0xff,0xfd,0x00, +0x00,0x15,0x10,0x00,0x04,0x00,0x00,0x15,0x13,0xff,0xfe,0x00,0x01,0x40,0x01, +0xba,0xad,0x00,0x01,0x7f,0xff,0xff,0xfd,0x00,0x01,0x2a,0xa2,0x00,0x04,0x00, +0x01,0xaa,0xa3,0xff,0xfe,0x00,0x01,0x70,0x41,0xf5,0x45,0x00,0x01,0x6f,0xff, +0xff,0xfd,0x00,0x01,0x14,0x00,0x00,0x04,0x00,0x01,0xb4,0x41,0xff,0xfe,0x00, +0x01,0x70,0xe0,0xaa,0x85,0x00,0x01,0x5f,0x7f,0xff,0xfd,0x00,0x01,0x2a,0x80, +0x00,0x04,0x00,0x01,0xba,0xe1,0xff,0xfe,0x00,0x01,0x7f,0xff,0xff,0xfd,0x00, +0x01,0x7f,0xff,0xff,0xfd,0x00,0x01,0x7f,0xff,0xff,0xfc,0x00,0x01,0xff,0xff, +0xff,0xfe,0x00,0x01,0xff,0xff,0xff,0xff,0x00,0x01,0xff,0xff,0xff,0xff,0x00, +0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x1e,0x07, +0x00,0x00,0x00,0x00,0x1e,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x07,0x00,0x00,0x00,0x00,0x3c,0x07, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x38,0x03,0x00,0x00,0x00,0x00,0x38,0x03,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x03,0xe0,0x00,0x00, +0x00,0x70,0x03,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0xf0,0x03,0xf0,0x00,0x00,0x00,0xf1,0xfb,0xf0,0x00,0x00, +0x00,0x01,0xe4,0x00,0x00,0x00,0x00,0x01,0xe0,0x00,0x00,0x00,0x01,0xf0,0x00, +0x00,0x00,0x00,0x01,0xf3,0xfc,0x00,0x00,0x00,0x00,0x0c,0x03,0x80,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xe0,0x00,0x00,0x00,0x00,0x01,0xe5,0x00, +0x00,0x00,0x00,0x00,0x1a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00, }; + +//---------------------------------------------------------------------------- + +static const ULONG format_disk_colors[96] = +{ + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0x7f7f7f7f,0x89898989,0xc2c2c2c2, + 0x24242424,0x42424242,0x66666666, + 0xadadadad,0xadadadad,0xf0f0f0f0, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0xe3e3e3e3,0xe3e3e3e3,0xe3e3e3e3, + 0xc6c6c6c6,0xc6c6c6c6,0xc6c6c6c6, + 0x6a6a6a6a,0x6a6a6a6a,0x6a6a6a6a, + 0xdbdbdbdb,0x75757575,0x41414141, + 0xdfdfdfdf,0xbabababa,0x45454545, + 0x52525252,0x66666666,0x94949494, + 0xffffffff,0xffffffff,0xffffffff, + 0xefefefef,0xe7e7e7e7,0x14141414, + 0xdfdfdfdf,0x35353535,0x35353535, + 0x00000000,0x00000000,0x00000000, + 0x8a8a8a8a,0x8a8a8a8a,0x8a8a8a8a, + 0x19191919,0x5e5e5e5e,0x32323232, + 0x38383838,0x88888888,0x46464646, + 0x56565656,0xb1b1b1b1,0x5a5a5a5a, + 0x75757575,0xdbdbdbdb,0x6e6e6e6e, + 0x29292929,0x29292929,0x29292929, + 0x49494949,0x49494949,0x49494949, + 0x82828282,0x00000000,0x00000000, + 0xc2c2c2c2,0x99999999,0xc2c2c2c2, + 0xaaaaaaaa,0x68686868,0xa2a2a2a2, + 0x91919191,0x36363636,0x82828282, + 0xadadadad,0x6d6d6d6d,0xb5b5b5b5, + 0xc7c7c7c7,0x2b2b2b2b,0xd9d9d9d9, + 0x6d6d6d6d,0x2b2b2b2b,0x5b5b5b5b, + 0x91919191,0x00000000,0x6a6a6a6a, + 0xb5b5b5b5,0x48484848,0x6f6f6f6f, + 0xd9d9d9d9,0x00000000,0x4c4c4c4c, +}; + +#define FORMAT_DISK_WIDTH 21 +#define FORMAT_DISK_HEIGHT 21 +#define FORMAT_DISK_DEPTH 5 +#define FORMAT_DISK_COMPRESSION 0 +#define FORMAT_DISK_MASKING 2 + +static const struct BitMapHeader format_disk_header = +{ 21,21,0,0,5,2,0,0,0,44,44,320,256 }; + +static const UBYTE format_disk_body[420] = { +0x00,0x00,0x01,0xf0,0x00,0x00,0x01,0xf0,0x00,0x00,0x01,0xf0,0x00,0x00,0x05, +0xf0,0x00,0x00,0x07,0x58,0x00,0x00,0x04,0x50,0x00,0x00,0x04,0xa8,0x00,0x00, +0x05,0x00,0x00,0x00,0x00,0x90,0x00,0x00,0x00,0xa0,0x0a,0xff,0x70,0x00,0x04, +0x00,0x10,0x00,0x01,0xff,0x10,0x00,0x00,0x00,0x0f,0xdf,0x00,0x00,0x00,0x7f, +0x10,0xe2,0xa8,0x00,0x0e,0x1d,0x60,0x00,0x01,0xf3,0x20,0x00,0x0e,0x00,0x5f, +0x9f,0x00,0x00,0x07,0xff,0x10,0xc2,0xd7,0xc0,0x0e,0x3c,0x40,0x00,0x01,0xf3, +0x48,0x00,0x0e,0x0c,0x3f,0xc0,0x00,0x00,0x00,0x00,0x10,0x82,0xa8,0x00,0x0e, +0x7c,0x88,0x00,0x01,0xf3,0x90,0x00,0x0e,0x0c,0x78,0x00,0x00,0x00,0x07,0x20, +0x10,0x03,0x50,0x00,0x0e,0xfd,0x10,0x00,0x01,0xf3,0x28,0x00,0x0e,0x0c,0xf8, +0x00,0x00,0x00,0x07,0xa0,0x10,0x02,0xaf,0xbf,0x0e,0xee,0x20,0x00,0x01,0xf2, +0x50,0x00,0x0e,0x01,0xf8,0x00,0x00,0x00,0x07,0x20,0x10,0x05,0x50,0x00,0x0f, +0xfc,0x40,0x00,0x00,0x04,0xa0,0x00,0x0f,0xfb,0xf8,0x00,0x00,0x00,0x07,0xc0, +0x17,0xfa,0xa0,0x00,0x0c,0x08,0x88,0x00,0x03,0xf9,0x48,0x00,0x08,0x07,0xf8, +0x00,0x00,0x00,0x00,0x00,0x17,0xf5,0x4f,0xff,0x0f,0xf1,0x18,0x00,0x00,0x12, +0x98,0x00,0x0f,0xef,0xf8,0x00,0x00,0x00,0x07,0x80,0x17,0xca,0x88,0x42,0x0f, +0xc2,0x38,0x00,0x00,0x05,0x28,0x00,0x0f,0xdf,0xe8,0x00,0x00,0x20,0x07,0x80, +0x17,0xd5,0x0c,0x00,0x0f,0x84,0x78,0x00,0x00,0x0a,0x48,0x00,0x0f,0x9f,0xe8, +0x00,0x00,0x60,0x00,0x00,0x17,0x4a,0x4f,0xfc,0x0f,0x08,0xb8,0x00,0x00,0x14, +0xc8,0x00,0x0f,0x1f,0xa8,0x00,0x00,0xe0,0x00,0x00,0x17,0x44,0xc8,0x0a,0x0e, +0x01,0x38,0x00,0x01,0x09,0xc8,0x00,0x0f,0x0f,0x28,0x00,0x00,0xf0,0x07,0x00, +0x16,0x21,0xc8,0x00,0x0c,0x70,0x38,0x00,0x02,0x11,0xc8,0x00,0x0f,0x10,0x28, +0x00,0x00,0xee,0x07,0x80,0x14,0x13,0xcf,0x00,0x08,0xa4,0x38,0x00,0x04,0x87, +0xc8,0x00,0x0f,0x84,0x28,0x00,0x00,0x78,0x07,0x00,0x10,0x87,0xc8,0x03,0x00, +0x47,0xdc,0x00,0x08,0xc7,0xe8,0x00,0x07,0xc0,0x08,0x00,0x08,0x3f,0xe0,0x00, +0x11,0xcf,0xd8,0x00,0x18,0x30,0x28,0x01,0x11,0xf0,0x18,0x00,0x17,0xcf,0xc8, +0x00,0x00,0x3f,0xd0,0x00,0x0f,0x8f,0xf7,0xfe,0x08,0x61,0xf0,0x00,0x0f,0xff, +0xf0,0x00,0x0f,0x80,0x70,0x00,0x00,0x7e,0x07,0x80,0x02,0x1f,0xf1,0xf0,0x01, +0xcf,0xf7,0x00,0x03,0xff,0xf0,0x00,0x02,0x03,0xf0,0x00,0x01,0xf0,0x07,0x80, + }; + +//---------------------------------------------------------------------------- + +static const ULONG Information_colors[48] = +{ + 0x00000000,0x66666666,0xffffffff, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0x44444444,0x44444444,0x44444444, + 0x66666666,0x66666666,0x66666666, + 0x88888888,0x88888888,0x88888888, + 0x99999999,0x99999999,0x99999999, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0xbbbbbbbb,0xbbbbbbbb,0xbbbbbbbb, + 0xcccccccc,0xcccccccc,0xcccccccc, + 0xdddddddd,0xdddddddd,0xdddddddd, + 0xffffffff,0xffffffff,0xffffffff, + 0x22222222,0x22222222,0x22222222, + 0x39393939,0x3d3d3d3d,0x41414141, + 0xefefefef,0xe7e7e7e7,0x14141414, + 0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0xaaaaaaaa, +}; + +#define INFORMATION_WIDTH 25 +#define INFORMATION_HEIGHT 25 +#define INFORMATION_DEPTH 4 +#define INFORMATION_COMPRESSION 0 +#define INFORMATION_MASKING 2 + +static const struct BitMapHeader Information_header = +{ 25,25,0,0,4,2,0,0,0,44,44,320,256 }; + +static const UBYTE Information_body[400] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x40,0x00,0x7f,0xff,0xa0,0x00,0x00,0x00,0x20,0x00,0x7f,0xff, +0xc0,0x00,0x00,0x02,0x80,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x7f, +0xff,0xc0,0x00,0x00,0x09,0x60,0x00,0x41,0xf0,0x20,0x00,0x01,0xf0,0x00,0x00, +0x7f,0xff,0xc0,0x00,0x00,0x02,0x80,0x00,0x41,0xf0,0x20,0x00,0x01,0xf0,0x00, +0x00,0x7f,0xff,0xc0,0x00,0x00,0x05,0xe0,0x00,0x41,0xf0,0x20,0x00,0x01,0xf0, +0x00,0x00,0x7f,0xff,0xe0,0x00,0x00,0x4b,0x40,0x00,0x40,0x00,0x20,0x00,0x00, +0x00,0x20,0x00,0x7f,0xff,0xe0,0x00,0x00,0x15,0xc0,0x00,0x40,0x00,0x20,0x00, +0x00,0x00,0x20,0x00,0x7f,0xff,0xe0,0x00,0x00,0x0f,0xc0,0x00,0x41,0xf0,0x20, +0x00,0x01,0xf0,0x20,0x00,0x7f,0xff,0xe0,0x00,0x02,0x0b,0xf8,0x00,0x41,0xf0, +0x88,0x00,0x01,0xf0,0xf8,0x00,0x7f,0xff,0x70,0x00,0x00,0x0f,0xfe,0x00,0x41, +0xf2,0x02,0x00,0x01,0xf3,0xfe,0x00,0x7f,0xfd,0xfc,0x00,0x04,0x0f,0x7f,0x00, +0x41,0xf4,0x81,0x00,0x01,0xf7,0x7f,0x00,0x7f,0xfb,0xfe,0x00,0x12,0x0e,0x3f, +0x00,0x41,0xf1,0xc0,0x00,0x01,0xf6,0x3f,0x00,0x7f,0xff,0xff,0x00,0x04,0x0f, +0x7f,0x00,0x41,0xf0,0x80,0x00,0x01,0xf7,0x7f,0x00,0x7f,0xff,0xff,0x00,0x2a, +0x07,0xff,0x00,0x41,0xfc,0x01,0x00,0x01,0xf7,0xff,0x00,0x7f,0xfb,0xfe,0x00, +0x16,0x0f,0xff,0x00,0x41,0xf4,0x01,0x00,0x01,0xf7,0xff,0x00,0x7f,0xfb,0xfe, +0x00,0x2a,0x03,0xfe,0x00,0x41,0xfe,0x02,0x00,0x01,0xf3,0xfe,0x00,0x7f,0xfd, +0xfc,0x00,0x1e,0x05,0xfc,0x00,0x41,0xfb,0x04,0x00,0x01,0xf1,0xfc,0x00,0x7f, +0xfe,0xf8,0x00,0x36,0x06,0xf8,0x00,0x41,0xf9,0x8c,0x00,0x01,0xf1,0xfc,0x00, +0x7f,0xfe,0x70,0x00,0x1e,0x04,0x70,0x00,0x41,0xf9,0xf0,0x00,0x01,0xf1,0xf8, +0x00,0x7f,0xfe,0x00,0x00,0x3d,0x54,0x40,0x00,0x42,0xaa,0x68,0x00,0x00,0x03, +0xf0,0x00,0x7f,0xfc,0x00,0x00,0x76,0xa8,0x10,0x00,0x09,0x53,0x58,0x00,0x00, +0x07,0xe0,0x00,0x7f,0xfb,0x00,0x00,0x14,0x00,0x10,0x00,0x5f,0xfc,0x58,0x00, +0x63,0xfc,0xe0,0x00,0x07,0xfc,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x30, +0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, }; + +//---------------------------------------------------------------------------- + +static const ULONG IconProperties_colors[48] = +{ + 0xa6a6a6a6,0xaaaaaaaa,0xaaaaaaaa, + 0xcacacaca,0xcacacaca,0xcacacaca, + 0x35353535,0x35353535,0x35353535, + 0xffffffff,0xffffffff,0xffffffff, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0x65656565,0x65656565,0x65656565, + 0x00000000,0x00000000,0x00000000, + 0xefefefef,0xe7e7e7e7,0x14141414, + 0xcacacaca,0x9a9a9a9a,0x75757575, + 0x0c0c0c0c,0xe3e3e3e3,0x00000000, + 0x35353535,0x8a8a8a8a,0x35353535, + 0x4d4d4d4d,0x4d4d4d4d,0x4d4d4d4d, + 0x65656565,0x8a8a8a8a,0xbabababa, + 0x8a8a8a8a,0x8a8a8a8a,0x8a8a8a8a, + 0x00000000,0x00000000,0xa6a6a6a6, + 0xa6a6a6a6,0xa6a6a6a6,0xa6a6a6a6, +}; + +#define ICONPROPERTIES_WIDTH 18 +#define ICONPROPERTIES_HEIGHT 22 +#define ICONPROPERTIES_DEPTH 4 +#define ICONPROPERTIES_COMPRESSION 0 +#define ICONPROPERTIES_MASKING 2 + +static const struct BitMapHeader IconProperties_header = +{ 18,22,0,0,4,2,0,0,0,44,44,320,256 }; + +static const UBYTE IconProperties_body[352] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x3f,0xfe,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x3d,0x16,0x00,0x00,0x1c,0xe7,0x00,0x00,0x03,0xf8,0x00,0x00, +0x00,0x00,0x00,0x00,0x3b,0xfa,0x00,0x00,0x1c,0x17,0x00,0x00,0x06,0x0c,0x00, +0x00,0x00,0x00,0x00,0x00,0x37,0xf8,0x00,0x00,0x19,0xfb,0x00,0x00,0x09,0xfa, +0x00,0x00,0x00,0x04,0x00,0x00,0x2e,0x0c,0x00,0x00,0x13,0xfd,0x00,0x00,0x1b, +0xfd,0x00,0x00,0x00,0x02,0x00,0x00,0x2d,0xf4,0x00,0x00,0x17,0xfd,0x00,0x00, +0x16,0x0d,0x00,0x00,0x00,0x02,0x00,0x00,0x2d,0xf4,0x00,0x00,0x17,0xfd,0x00, +0x00,0x16,0x0d,0x00,0x00,0x00,0x02,0x00,0x00,0x25,0xe4,0x00,0x00,0x17,0xed, +0x00,0x00,0x1e,0x1d,0x00,0x00,0x00,0x02,0x00,0x00,0x23,0x8c,0x00,0x00,0x0f, +0xb5,0x00,0x00,0x1c,0x75,0x00,0x00,0x00,0x02,0x00,0x00,0x3f,0x38,0x00,0x00, +0x1f,0x5b,0x00,0x00,0x00,0xdb,0x00,0x00,0x00,0x04,0x00,0x00,0x3f,0x60,0x00, +0x00,0x1f,0xaf,0x00,0x00,0x00,0xaf,0x00,0x00,0x00,0x10,0x00,0x00,0x3f,0x4f, +0x00,0x00,0x1f,0xdf,0x00,0x00,0x00,0xd0,0x00,0x00,0x00,0x21,0x00,0x00,0x3f, +0x4e,0x00,0x00,0x1f,0xdf,0x00,0x00,0x00,0xd0,0x00,0x00,0x00,0x20,0x00,0x00, +0x3f,0x9f,0x00,0x00,0x1f,0x6e,0x00,0x00,0x00,0xf1,0x00,0x00,0x00,0x90,0x00, +0x00,0x3f,0xfd,0x00,0x00,0x1f,0x9e,0x00,0x00,0x00,0x61,0x00,0x00,0x00,0x60, +0x00,0x00,0x3f,0x6b,0x00,0x00,0x1f,0xbc,0x00,0x00,0x00,0xb3,0x00,0x00,0x00, +0x01,0x00,0x00,0x3f,0x46,0x00,0x00,0x1f,0xd8,0x00,0x00,0x00,0xd6,0x00,0x00, +0x00,0x22,0x00,0x00,0x3f,0x9c,0x00,0x00,0x00,0x60,0x00,0x00,0x3f,0xfc,0x00, +0x00,0x3f,0x9c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00, }; + +//---------------------------------------------------------------------------- + +static const ULONG NewDrawer_colors[48] = +{ + 0x00000000,0x66666666,0xffffffff, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0x44444444,0x44444444,0x44444444, + 0x66666666,0x66666666,0x66666666, + 0xdddddddd,0xbbbbbbbb,0x44444444, + 0xeeeeeeee,0xeeeeeeee,0x11111111, + 0x88888888,0x88888888,0x88888888, + 0x99999999,0x99999999,0x99999999, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0xbbbbbbbb,0xbbbbbbbb,0xbbbbbbbb, + 0xcccccccc,0xcccccccc,0xcccccccc, + 0xffffffff,0xffffffff,0xffffffff, + 0x33333333,0x33333333,0x33333333, + 0xffffffff,0xffffffff,0xffffffff, + 0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0xaaaaaaaa, +}; + +#define NEWDRAWER_WIDTH 33 +#define NEWDRAWER_HEIGHT 29 +#define NEWDRAWER_DEPTH 4 +#define NEWDRAWER_COMPRESSION 0 +#define NEWDRAWER_MASKING 2 + +static const struct BitMapHeader NewDrawer_header = +{ 33,29,0,0,4,2,0,0,0,44,44,320,256 }; + +static const UBYTE NewDrawer_body[696] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0x02,0xe0, +0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x03,0xfc,0x00,0x00,0x00,0x00,0x0b,0xf8,0x00,0x00,0x00,0x00,0x04,0x00, +0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xff,0x00,0x00,0x00, +0x00,0x2f,0xec,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x02,0x00,0x00, +0x00,0x00,0x00,0x00,0x3f,0xff,0xc0,0x00,0x00,0x02,0xbf,0xfa,0x80,0x00,0x00, +0x00,0x40,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff, +0xf0,0x00,0x00,0x06,0xff,0xd5,0x40,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00, +0x0c,0x00,0x00,0x00,0x00,0x00,0x03,0xff,0xff,0xf8,0x00,0x00,0x0c,0xff,0x6a, +0x88,0x00,0x00,0x06,0x00,0x00,0x18,0x00,0x00,0x38,0x00,0x00,0x10,0x00,0x00, +0x07,0xff,0xff,0xf0,0x00,0x00,0x04,0x3f,0xd5,0x00,0x00,0x00,0x02,0x80,0x00, +0x78,0x00,0x00,0x0c,0x80,0x00,0x70,0x00,0x00,0x03,0xff,0xff,0xf0,0x00,0x00, +0x00,0x0e,0xa8,0x40,0x00,0x00,0x02,0x20,0x01,0x98,0x00,0x00,0x04,0x20,0x01, +0x90,0x00,0x00,0x03,0xff,0xff,0xf0,0x00,0x00,0x02,0x03,0x51,0x00,0x00,0x00, +0x00,0x08,0x06,0x18,0x00,0x00,0x04,0x08,0x06,0x10,0x00,0x00,0x03,0xff,0xff, +0xf0,0x00,0x00,0x00,0x00,0x84,0x00,0x00,0x00,0x02,0x02,0x18,0x18,0x00,0x00, +0x00,0x02,0x18,0x10,0x00,0x00,0x03,0xff,0xff,0xf0,0x00,0x00,0x02,0x00,0x10, +0x00,0x00,0x00,0x00,0x00,0xe0,0x18,0x00,0x00,0x00,0x00,0xe0,0x10,0x00,0x00, +0x03,0xff,0xff,0xf0,0x00,0x00,0x02,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x40, +0x18,0x00,0x00,0x00,0x00,0x40,0x10,0x00,0x00,0x03,0xff,0xff,0xf0,0x00,0x00, +0x02,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x44,0x58,0x00,0x00,0x00,0x00,0x44, +0x50,0x00,0x00,0x03,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x44,0x80,0x00,0x00, +0x00,0x00,0xc5,0x98,0x00,0x00,0x00,0x00,0x80,0x10,0x00,0x00,0x03,0xff,0xba, +0x70,0x00,0x00,0x02,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x46,0x18,0x00,0x00, +0x00,0x00,0x44,0x18,0x00,0x00,0x03,0xff,0xfd,0xf8,0x00,0x00,0x00,0x00,0x60, +0x20,0x00,0x00,0x00,0x02,0xc0,0x7c,0x00,0x00,0x00,0x02,0x80,0x4c,0x00,0x00, +0x03,0xff,0xbf,0xc8,0x00,0x00,0x01,0x00,0x20,0x88,0x00,0x00,0x01,0x81,0x41, +0xfe,0x00,0x00,0x00,0x81,0x01,0x06,0x00,0x00,0x02,0xff,0xbf,0x00,0x00,0x00, +0x00,0xc0,0x22,0x30,0x00,0x00,0x01,0xea,0xc7,0xfc,0x00,0x00,0x01,0x2a,0x84, +0x0c,0x00,0x00,0x00,0x3f,0xbc,0x00,0x00,0x00,0x00,0x60,0x08,0xc0,0x00,0x00, +0x00,0xfd,0x5f,0xf4,0x00,0x00,0x00,0x8d,0x10,0x34,0x00,0x00,0x00,0x0f,0xb0, +0x00,0x00,0x00,0x00,0x10,0x23,0x00,0x00,0x00,0x00,0x7e,0xff,0xd0,0x00,0x00, +0x00,0x62,0x80,0xd0,0x00,0x00,0x00,0x03,0x80,0x00,0x00,0x00,0x00,0x04,0x0c, +0x00,0x00,0x00,0x00,0x1f,0xff,0x40,0x00,0x00,0x00,0x18,0x83,0x40,0x00,0x00, +0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x01,0x30,0x00,0x00,0x00,0x00,0x07,0xfd, +0x00,0x00,0x00,0x00,0x06,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xf4,0x00,0x00,0x00,0x00,0x01,0xf4, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0xa0,0x00,0x00,0x00,0x00,0x00,0xa0,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00, }; + +//---------------------------------------------------------------------------- + +static const ULONG Reboot_colors[48] = +{ + 0x00000000,0x00000000,0xaaaaaaaa, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0x44444444,0x44444444,0x44444444, + 0x66666666,0x66666666,0x66666666, + 0x88888888,0x00000000,0x00000000, + 0xdddddddd,0x33333333,0x33333333, + 0xdddddddd,0x66666666,0x33333333, + 0xdddddddd,0x88888888,0x44444444, + 0x88888888,0x88888888,0x88888888, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0xbbbbbbbb,0xbbbbbbbb,0xbbbbbbbb, + 0xcccccccc,0xcccccccc,0xcccccccc, + 0xffffffff,0xffffffff,0xffffffff, + 0x33333333,0x33333333,0x33333333, + 0x48484848,0xb5b5b5b5,0x8d8d8d8d, + 0x00000000,0x00000000,0x00000000, +}; + +#define REBOOT_WIDTH 42 +#define REBOOT_HEIGHT 33 +#define REBOOT_DEPTH 4 +#define REBOOT_COMPRESSION 0 +#define REBOOT_MASKING 2 + +static const struct BitMapHeader Reboot_header = +{ 42,33,0,0,4,2,0,0,0,44,44,320,256 }; + +static const UBYTE Reboot_body[792] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x02,0x80,0x00,0x00,0x00,0x00,0x03,0xff,0x80,0x00,0x00, +0x00,0x03,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0xff, +0x80,0x00,0x00,0x00,0x3c,0x00,0x78,0x00,0x00,0x00,0x3f,0xff,0xf8,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xf8,0x00,0x00,0x00,0xc0,0x00, +0x06,0x00,0x00,0x00,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x01,0xfa,0xab,0xd5,0x00,0x00,0x01,0x00,0x00,0x2a,0x00,0x00,0x01,0xff,0xff, +0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd5,0x7f,0xaa,0x80,0x00, +0x02,0x00,0x00,0x55,0x00,0x00,0x03,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x07,0xaa,0xff,0x55,0x40,0x00,0x04,0x00,0x00,0xaa,0x80,0x00, +0x07,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x5f,0xfa, +0xa0,0x00,0x00,0x04,0x00,0x05,0x5f,0x80,0x00,0x07,0xff,0xff,0xff,0xc0,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xbf,0xf5,0x44,0x00,0x00,0x04,0x00,0x0a, +0xbf,0x80,0x00,0x07,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x01,0xdf,0xea,0x8a,0x40,0x00,0x04,0x00,0x15,0x7f,0x40,0x00,0x07,0xff,0xff, +0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x02,0xff,0xd5,0x15,0x80,0x00, +0x04,0x00,0x2a,0xff,0x80,0x00,0x07,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00, +0x01,0x80,0x00,0x03,0x3f,0xea,0x85,0x40,0x00,0x04,0x00,0x15,0x7d,0x40,0x00, +0x07,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x05,0x40,0x00,0x03,0x63,0xd0, +0x50,0x80,0x00,0x04,0x8c,0x2f,0xd0,0x80,0x00,0x07,0xff,0xff,0xff,0xc0,0x00, +0x00,0x00,0x00,0x50,0x80,0x00,0x03,0x8e,0x80,0x29,0x40,0x00,0x04,0x7c,0x00, +0x01,0x40,0x00,0x07,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x01,0x40,0x00, +0x03,0x4c,0x5e,0xd0,0x80,0x00,0x04,0xbf,0xa0,0x00,0x80,0x00,0x07,0xff,0xff, +0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x0b,0x8c,0xbf,0xa9,0x60,0x00, +0x0c,0x7f,0x40,0x01,0x60,0x00,0x07,0xff,0xff,0xff,0xe0,0x00,0x08,0x00,0x00, +0x01,0x60,0x00,0x13,0x4c,0x5e,0xd0,0xf0,0x00,0x1c,0xbf,0xa0,0x00,0xd0,0x00, +0x07,0xff,0xff,0xff,0xf0,0x00,0x18,0x00,0x00,0x00,0xf0,0x00,0x2b,0x8c,0xbf, +0xa9,0xf8,0x00,0x3a,0x7f,0x40,0x01,0xa8,0x00,0x0b,0xff,0xff,0xff,0xf8,0x00, +0x3e,0x00,0x00,0x01,0xf8,0x00,0x34,0x4c,0x5e,0xd1,0xf8,0x00,0x34,0xbf,0xa0, +0x01,0x18,0x00,0x14,0xff,0xff,0xff,0xf8,0x00,0x3f,0x00,0x00,0x01,0xf8,0x00, +0x2b,0x0c,0xbf,0xaf,0x78,0x00,0x2b,0x3f,0x40,0x00,0x88,0x00,0x0b,0x3f,0xff, +0xff,0x78,0x00,0x3f,0xc0,0x00,0x07,0x7c,0x00,0x07,0x00,0x5e,0x98,0xb0,0x00, +0x17,0xc3,0xa0,0x67,0x50,0x00,0x07,0x03,0xff,0x98,0xb0,0x00,0x0f,0xfc,0x00, +0x18,0xbe,0x00,0x0e,0x64,0x5a,0x74,0x74,0x00,0x0f,0xe4,0x5f,0xff,0xb4,0x00, +0x06,0x18,0x00,0x00,0x60,0x00,0x07,0xff,0xa0,0x00,0x6b,0x00,0x04,0xc3,0x38, +0xba,0x6a,0x00,0x07,0xc3,0xf8,0xbf,0xaa,0x00,0x00,0x3c,0x38,0x00,0x40,0x00, +0x03,0xff,0xff,0x40,0x55,0x00,0x00,0x67,0x1c,0x5f,0xd4,0x00,0x00,0x67,0xfc, +0x5c,0x54,0x00,0x00,0x18,0x1c,0x03,0x80,0x00,0x03,0xff,0xff,0xa3,0xab,0x00, +0x00,0x1b,0x0e,0x02,0xa8,0x00,0x00,0x1b,0xfe,0x3e,0xa8,0x00,0x00,0x04,0x0e, +0x00,0x00,0x00,0x00,0x1f,0xff,0xc1,0x56,0x00,0x00,0x04,0xf1,0xd5,0x50,0x00, +0x00,0x1f,0xf1,0xd5,0x50,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0x1f,0xfe, +0x2a,0xae,0x00,0x00,0x00,0x0a,0xaa,0xa0,0x00,0x00,0x00,0x0a,0xaa,0xa0,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x75,0x55,0x5d,0x00,0x00,0x00,0x00, +0x55,0x00,0x00,0x00,0x00,0x00,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x3f,0xaa,0xf4,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00, +0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x05,0xff,0xe0,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x17,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, }; + +//---------------------------------------------------------------------------- + +static const ULONG rename_colors[48] = +{ + 0x00000000,0x66666666,0xffffffff, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0x44444444,0x44444444,0x44444444, + 0x66666666,0x66666666,0x66666666, + 0xdddddddd,0xbbbbbbbb,0x44444444, + 0xeeeeeeee,0xeeeeeeee,0x11111111, + 0x88888888,0x88888888,0x88888888, + 0x99999999,0x99999999,0x99999999, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0xcccccccc,0xcccccccc,0xcccccccc, + 0xdddddddd,0xdddddddd,0xdddddddd, + 0xffffffff,0xffffffff,0xffffffff, + 0x22222222,0x22222222,0x22222222, + 0x39393939,0x3d3d3d3d,0x41414141, + 0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0xaaaaaaaa, +}; + +#define RENAME_WIDTH 26 +#define RENAME_HEIGHT 30 +#define RENAME_DEPTH 4 +#define RENAME_COMPRESSION 0 +#define RENAME_MASKING 2 + +static const struct BitMapHeader rename_header = +{ 26,30,0,0,4,2,0,0,0,44,44,320,256 }; + +static const UBYTE rename_body[480] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x10,0x00,0x00,0x00, +0xec,0x00,0x00,0x00,0x10,0x00,0x3f,0xff,0xcc,0x00,0x3f,0xff,0xe8,0x00,0x00, +0x00,0x07,0x00,0x3f,0xff,0xf8,0x00,0x3f,0xfe,0xa8,0x00,0x20,0x01,0x50,0x00, +0x00,0x00,0x1c,0x00,0x3f,0xff,0xe0,0x00,0x3f,0xfb,0x50,0x00,0x20,0x04,0xb0, +0x00,0x00,0x00,0x08,0x00,0x3f,0xff,0xe0,0x00,0x3f,0xfe,0xa0,0x00,0x20,0x01, +0x50,0x00,0x00,0x00,0x08,0x00,0x3f,0xff,0xe0,0x00,0x3f,0xf5,0x00,0x00,0x20, +0x0a,0xe0,0x00,0x00,0x00,0x10,0x00,0x3f,0xff,0xf0,0x00,0x3f,0xda,0x40,0x00, +0x20,0x25,0xb0,0x00,0x00,0x00,0x10,0x00,0x3f,0xff,0xf0,0x00,0x3f,0xf5,0x00, +0x00,0x20,0x0a,0xf0,0x00,0x00,0x00,0x10,0x00,0x3f,0xff,0xf0,0x00,0x3f,0xa8, +0x00,0x00,0x20,0x57,0xf0,0x00,0x00,0x00,0x10,0x00,0x3f,0xff,0xf0,0x00,0x3e, +0xd2,0x40,0x00,0x21,0x2d,0xf0,0x00,0x00,0x00,0x10,0x00,0x3f,0xff,0xf0,0x00, +0x3f,0xa8,0x00,0x00,0x20,0x57,0xf0,0x00,0x00,0x00,0x10,0x00,0x3f,0xff,0xf0, +0x00,0x3d,0x40,0xa0,0x00,0x22,0xbf,0xf0,0x00,0x00,0x00,0x10,0x00,0x3f,0xff, +0xf0,0x00,0x36,0x92,0x40,0x00,0x29,0x6f,0xf0,0x00,0x00,0x00,0x10,0x00,0x3f, +0xff,0xf0,0x00,0x3d,0x40,0xa0,0x00,0x22,0xbf,0xf0,0x00,0x00,0x00,0x10,0x00, +0x3f,0xff,0xf0,0x00,0x2a,0x05,0x40,0x00,0x35,0xff,0xf0,0x00,0x00,0x00,0x10, +0x00,0x3f,0xff,0xf0,0x00,0x34,0x92,0xa0,0x00,0x2b,0x7f,0xf0,0x00,0x00,0x00, +0x10,0x00,0x3f,0xff,0xf0,0x00,0x2a,0x07,0xc0,0x00,0x35,0xff,0xf0,0x00,0x00, +0x00,0x10,0x00,0x3f,0xff,0xf0,0x00,0x30,0x2d,0x40,0x00,0x2f,0xff,0xb0,0x00, +0x00,0x00,0x30,0x00,0x3f,0xff,0xd0,0x00,0x24,0x94,0x80,0x00,0x3b,0xff,0x20, +0x00,0x00,0x00,0x20,0x00,0x3f,0xff,0xe0,0x00,0x30,0x2d,0x00,0x00,0x2f,0xfe, +0x60,0x00,0x00,0x00,0x60,0x00,0x3f,0xff,0xa0,0x00,0x21,0x54,0x00,0x00,0x3f, +0xfe,0xc0,0x00,0x00,0x00,0xc0,0x00,0x3f,0xff,0x40,0x00,0x04,0xa8,0x00,0x00, +0x3f,0xff,0x80,0x00,0x00,0x03,0x80,0x00,0x3f,0xfd,0x80,0x00,0x08,0x00,0x00, +0x00,0x1d,0xfe,0x00,0x00,0x13,0xfe,0x00,0x00,0x23,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, + }; + +//---------------------------------------------------------------------------- + +static const ULONG systeminfo_colors[48] = +{ + 0x00000000,0xeeeeeeee,0x00000000, + 0x99999999,0x99999999,0x99999999, + 0x44444444,0x44444444,0x44444444, + 0x66666666,0x66666666,0x66666666, + 0x00000000,0x66666666,0x99999999, + 0x33333333,0x77777777,0xaaaaaaaa, + 0x33333333,0x88888888,0x33333333, + 0x33333333,0x33333333,0x33333333, + 0x66666666,0x88888888,0xbbbbbbbb, + 0x88888888,0x66666666,0x44444444, + 0xaaaaaaaa,0x77777777,0x66666666, + 0x88888888,0x88888888,0x88888888, + 0xefefefef,0xe7e7e7e7,0x14141414, + 0xbbbbbbbb,0xbbbbbbbb,0xbbbbbbbb, + 0xcccccccc,0xcccccccc,0xcccccccc, + 0xffffffff,0xffffffff,0xffffffff, +}; + +#define SYSTEMINFO_WIDTH 37 +#define SYSTEMINFO_HEIGHT 30 +#define SYSTEMINFO_DEPTH 4 +#define SYSTEMINFO_COMPRESSION 0 +#define SYSTEMINFO_MASKING 2 + +static const struct BitMapHeader systeminfo_header = +{ 37,30,0,0,4,2,0,0,0,44,44,320,256 }; + +static const UBYTE systeminfo_body[720] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x37,0xff,0xff,0x60,0x00,0x01,0xcf,0xff,0xff,0xe0,0x00, +0x01,0xff,0xff,0xff,0xa0,0x00,0x01,0xff,0xff,0xff,0xc0,0x00,0x02,0xd7,0xdd, +0x50,0x60,0x00,0x07,0xef,0xff,0xff,0xe0,0x00,0x07,0xff,0xff,0xff,0xa0,0x00, +0x07,0xff,0xff,0xff,0x80,0x00,0x04,0x1d,0xff,0xf0,0x20,0x00,0x0f,0xef,0xff, +0xff,0xe0,0x00,0x0f,0xfd,0xff,0xf0,0xa0,0x00,0x0f,0xfc,0x00,0x00,0x80,0x00, +0x08,0x1f,0x39,0x01,0x20,0x00,0x1f,0xee,0x00,0x5f,0xe0,0x00,0x1f,0xff,0xff, +0xa1,0xa0,0x00,0x1f,0xfc,0x00,0x01,0x80,0x00,0x10,0x1e,0xfe,0x01,0x60,0x00, +0x3f,0xee,0x00,0x1f,0xe0,0x00,0x3f,0xff,0xff,0xe1,0xe0,0x00,0x3f,0xfc,0x00, +0x01,0x80,0x00,0x23,0xf2,0xd6,0x81,0x60,0x00,0x3f,0xfe,0x00,0x2f,0xe0,0x00, +0x20,0x0f,0xd7,0xd1,0xe0,0x00,0x23,0xfc,0x28,0x01,0x80,0x00,0x2b,0x65,0xab, +0x01,0x60,0x00,0x34,0xfe,0x00,0x1f,0xe0,0x00,0x3f,0x01,0xab,0xe1,0xe0,0x00, +0x3f,0x40,0x54,0x01,0x80,0x00,0x27,0x00,0xc7,0x81,0x60,0x00,0x3f,0xff,0x00, +0x0f,0xe0,0x00,0x20,0x00,0xc7,0xf1,0xe0,0x00,0x24,0x00,0x38,0x01,0x80,0x00, +0x38,0x6a,0x2b,0x01,0x60,0x00,0x3f,0xf7,0x80,0x1f,0xe0,0x00,0x3e,0x08,0x2b, +0xe1,0xe0,0x00,0x3e,0x28,0x54,0x01,0x80,0x00,0x24,0x10,0x16,0x81,0x60,0x00, +0x3b,0xef,0xc0,0x2f,0xe0,0x00,0x3c,0x18,0x17,0xd1,0xe0,0x00,0x3c,0x18,0x28, +0x01,0x80,0x00,0x2d,0x3c,0xde,0x01,0x60,0x00,0x37,0xdb,0xc0,0x1f,0xe0,0x00, +0x38,0x3c,0x7f,0xe1,0xe0,0x00,0x3c,0x3c,0x00,0x01,0x80,0x00,0x25,0x54,0xb9, +0x01,0x60,0x00,0x3f,0xba,0xe0,0x5f,0xe0,0x00,0x38,0x5d,0x1f,0xa1,0xe0,0x00, +0x39,0x5c,0x00,0x01,0x80,0x00,0x29,0xb4,0x14,0x01,0x60,0x00,0x37,0x4e,0x60, +0x3f,0xe0,0x00,0x38,0xbd,0x9f,0xc1,0xe0,0x00,0x39,0xbc,0x00,0x01,0x80,0x00, +0x20,0x54,0x80,0x01,0x60,0x00,0x3f,0xab,0x61,0x7f,0xe0,0x00,0x38,0x5c,0x9e, +0x81,0xe0,0x00,0x38,0x5c,0x00,0x01,0x80,0x00,0x2d,0x15,0xa0,0x01,0x60,0x00, +0x37,0xeb,0xe4,0xff,0xe0,0x00,0x38,0x1c,0x1b,0x01,0xe0,0x00,0x39,0x1c,0x00, +0x01,0x80,0x00,0x25,0x10,0x9f,0xff,0x60,0x00,0x3f,0xef,0xff,0xff,0xe0,0x00, +0x38,0x1c,0x1f,0xff,0xe0,0x00,0x3c,0x1c,0x1f,0xfe,0x80,0x00,0x28,0x9c,0x00, +0x08,0xe0,0x00,0x37,0xe3,0xff,0xff,0x60,0x00,0x3c,0x1c,0x2f,0x2f,0xc0,0x00, +0x3c,0x1c,0x0f,0x27,0xa0,0x00,0x24,0x7e,0x60,0xd9,0xe0,0x00,0x3b,0xff,0xff, +0xfe,0xe0,0x00,0x3c,0x10,0x4e,0xdf,0x80,0x00,0x3c,0x2c,0x4e,0xdf,0x20,0x00, +0x2a,0x00,0x5d,0x2d,0xe0,0x00,0x35,0xff,0xfa,0xdf,0xe0,0x00,0x3e,0x00,0x85, +0x21,0x00,0x00,0x3e,0x00,0xad,0x28,0x60,0x00,0x20,0x66,0x28,0x01,0xe0,0x00, +0x3f,0xff,0xdf,0xff,0xe0,0x00,0x36,0x00,0x00,0x00,0x20,0x00,0x36,0x42,0x30, +0x00,0x40,0x00,0x18,0x39,0x17,0xf3,0xc0,0x00,0x3f,0xff,0xef,0xff,0xc0,0x00, +0x00,0x38,0x01,0x00,0x40,0x00,0x10,0x00,0x1a,0xe0,0x80,0x00,0x2f,0xa1,0x8b, +0xe7,0x80,0x00,0x3f,0xff,0xf7,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x80,0x00, +0x28,0x00,0x0d,0x81,0x00,0x00,0x17,0xff,0xe5,0xff,0x00,0x00,0x1f,0xff,0xfb, +0xff,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x16,0x80,0x86,0x06,0x00,0x00, +0x0b,0xff,0x7a,0xfc,0x00,0x00,0x0f,0xff,0xfd,0xfc,0x00,0x00,0x00,0x00,0x08, +0x04,0x00,0x00,0x0b,0xff,0x63,0x78,0x00,0x00,0x00,0x00,0x1d,0x00,0x00,0x00, +0x00,0x00,0x1e,0x80,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x19, +0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + }; + +//---------------------------------------------------------------------------- + +static const ULONG WindowProperties_colors[48] = +{ + 0xf3f3f3f3,0x11111111,0x11111111, + 0xaaaaaaaa,0xaaaaaaaa,0xbbbbbbbb, + 0x00000000,0x11111111,0x22222222, + 0x00000000,0x22222222,0x22222222, + 0x33333333,0x33333333,0x33333333, + 0x44444444,0x44444444,0x44444444, + 0x00000000,0x77777777,0x88888888, + 0x00000000,0x88888888,0x99999999, + 0x00000000,0xaaaaaaaa,0xbbbbbbbb, + 0x88888888,0x88888888,0x88888888, + 0x00000000,0x96969696,0x98989898, + 0xcccccccc,0xcccccccc,0x88888888, + 0xf5f5f5f5,0xf4f4f4f4,0x92929292, + 0xffffffff,0xffffffff,0xaaaaaaaa, + 0xcccccccc,0xcccccccc,0xcccccccc, + 0xffffffff,0xffffffff,0xffffffff, +}; + +#define WINDOWPROPERTIES_WIDTH 34 +#define WINDOWPROPERTIES_HEIGHT 34 +#define WINDOWPROPERTIES_DEPTH 4 +#define WINDOWPROPERTIES_COMPRESSION 0 +#define WINDOWPROPERTIES_MASKING 2 + +static const struct BitMapHeader WindowProperties_header = +{ 34,34,0,0,4,2,0,0,0,44,44,320,256 }; + +static const UBYTE WindowProperties_body[816] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xfe,0x00,0x00,0x00, +0x00,0xff,0xff,0x80,0x80,0x00,0x7f,0x00,0x00,0x7f,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x3f,0xc0,0x0c,0xff,0x00,0x00,0x3f,0xa0,0xff,0xff,0x00,0x00, +0x7f,0xc0,0x0e,0xff,0x80,0x00,0x3f,0x9f,0xf0,0xff,0x00,0x00,0x3f,0xc0,0x0c, +0xff,0x00,0x00,0x22,0x20,0xff,0x88,0x80,0x00,0x66,0x40,0x0e,0x99,0x00,0x00, +0x22,0x1f,0xf0,0x88,0x00,0x00,0x3f,0xc0,0x0c,0xff,0x00,0x00,0x22,0x20,0xff, +0x88,0x80,0x00,0x66,0x40,0x0e,0x99,0x00,0x00,0x22,0x1f,0xf0,0x88,0x00,0x00, +0x3f,0xc0,0x0c,0xff,0x00,0x00,0x40,0x20,0xff,0x00,0x80,0x00,0x3f,0xc0,0x0e, +0xff,0x00,0x00,0x00,0x1f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x7f,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0x80,0x00, +0x3f,0xff,0xff,0xff,0x00,0x00,0x3f,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0x80,0x00,0x3f,0xff,0xff,0xff,0x00,0x00, +0x3f,0xff,0xff,0xff,0x00,0x00,0x1f,0xff,0xff,0xff,0x00,0x00,0x60,0x00,0x00, +0x01,0x80,0x00,0x3f,0xff,0xff,0xf9,0x00,0x00,0x3f,0xff,0xff,0xf9,0x00,0x00, +0x1f,0xff,0xf7,0xff,0x00,0x00,0x60,0x00,0x0c,0x01,0x80,0x00,0x3f,0xff,0xf3, +0xf9,0x00,0x00,0x3f,0xff,0xf7,0xf9,0x00,0x00,0x1f,0xff,0x22,0x79,0x00,0x00, +0x60,0x00,0xdf,0xc7,0x80,0x00,0x3f,0xff,0x28,0x3f,0x00,0x00,0x3f,0xff,0x2a, +0x7f,0x00,0x00,0x1f,0xfe,0x55,0x39,0x00,0x00,0x60,0x01,0xeb,0xe7,0x80,0x00, +0x3f,0xfe,0xc9,0x9f,0x00,0x00,0x3f,0xfe,0xdd,0xbf,0x00,0x00,0x1f,0xfe,0x82, +0xb9,0x00,0x00,0x60,0x01,0x7f,0x67,0x80,0x00,0x3f,0xfe,0x7f,0x1f,0x00,0x00, +0x3f,0xfe,0xff,0xbf,0x00,0x00,0x1f,0xff,0xd9,0x79,0x00,0x00,0x60,0x00,0x26, +0xe7,0x80,0x00,0x3f,0xff,0xa6,0x1f,0x00,0x00,0x3f,0xff,0x27,0x7f,0x00,0x00, +0x1f,0xfe,0xb5,0xb9,0x00,0x00,0x60,0x01,0xca,0x47,0x80,0x00,0x3f,0xfe,0xd2, +0x3f,0x00,0x00,0x3f,0xfe,0xc2,0x3f,0x00,0x00,0x1f,0xdc,0x29,0x99,0x00,0x00, +0x60,0x23,0xd6,0x77,0x80,0x00,0x3f,0xdd,0xca,0x4f,0x00,0x00,0x3f,0xdd,0xca, +0x5f,0x00,0x00,0x1c,0x88,0x97,0xb9,0x00,0x00,0x63,0x77,0x7c,0x77,0x80,0x00, +0x3c,0xa8,0x74,0x0f,0x00,0x00,0x3c,0xa8,0xf4,0xbf,0x00,0x00,0x19,0x54,0x47, +0x7f,0x00,0x00,0x67,0xaf,0xf8,0xe1,0x80,0x00,0x3b,0x26,0x78,0x19,0x00,0x00, +0x3b,0x76,0x79,0x79,0x00,0x00,0x1a,0x0a,0xff,0xbf,0x00,0x00,0x65,0xfd,0x80, +0x61,0x80,0x00,0x39,0xfc,0x80,0x19,0x00,0x00,0x3b,0xfe,0x80,0xb9,0x00,0x00, +0x1f,0x64,0xdd,0xbf,0x00,0x00,0x64,0x9b,0x20,0x61,0x80,0x00,0x3a,0x98,0x02, +0x19,0x00,0x00,0x3c,0x9c,0x55,0x39,0x00,0x00,0x1a,0xd6,0x2a,0x7f,0x00,0x00, +0x67,0x29,0xf7,0xe1,0x80,0x00,0x3b,0x48,0x00,0x19,0x00,0x00,0x3b,0x08,0x22, +0x79,0x00,0x00,0x10,0xa6,0x77,0xf9,0x00,0x00,0x6f,0x59,0xff,0xc7,0x80,0x00, +0x37,0x29,0x00,0x3f,0x00,0x00,0x37,0x29,0x77,0xff,0x00,0x00,0x1a,0x5e,0xff, +0xe1,0x00,0x00,0x6d,0xf1,0xcc,0x07,0x80,0x00,0x31,0xd0,0x33,0xff,0x00,0x00, +0x3b,0xd2,0xff,0xff,0x00,0x00,0x1d,0x1d,0xff,0xe9,0x00,0x00,0x67,0xe3,0x80, +0x07,0x80,0x00,0x39,0xe0,0x7f,0xff,0x00,0x00,0x3d,0xe5,0xff,0xff,0x00,0x00, +0x1b,0xfe,0xff,0x81,0x00,0x00,0x66,0x01,0x80,0x07,0x80,0x00,0x3a,0x00,0x7f, +0xff,0x00,0x00,0x3a,0x02,0xff,0xff,0x00,0x00,0x1b,0x76,0xff,0xa1,0x00,0x00, +0x64,0x81,0x80,0x07,0x80,0x00,0x38,0x08,0x7f,0xff,0x00,0x00,0x39,0x54,0xff, +0xff,0x00,0x00,0x1c,0xa9,0xfe,0x81,0x00,0x00,0x67,0xdf,0x80,0x07,0x80,0x00, +0x38,0x00,0x7f,0xff,0x00,0x00,0x3c,0x89,0xff,0xff,0x00,0x00,0x1f,0xdf,0xfe, +0x01,0x00,0x00,0x63,0xff,0x00,0x07,0x80,0x00,0x3c,0x00,0xff,0xff,0x00,0x00, +0x3f,0xdf,0xff,0xff,0x00,0x00,0x1f,0xff,0xff,0x07,0x00,0x00,0x60,0x30,0x00, +0x01,0x80,0x00,0x3f,0xcf,0xff,0xf9,0x00,0x00,0x3f,0xff,0xff,0xf9,0x00,0x00, +0x1f,0xff,0xfc,0x07,0x00,0x00,0x60,0x00,0x00,0x01,0x80,0x00,0x3f,0xff,0xff, +0xf9,0x00,0x00,0x3f,0xff,0xff,0xf9,0x00,0x00,0x1f,0xff,0xff,0xff,0x00,0x00, +0x7f,0xff,0xff,0xff,0x80,0x00,0x3f,0xff,0xff,0xff,0x00,0x00,0x3f,0xff,0xff, +0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0x80,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00, }; + +//---------------------------------------------------------------------------- + +static const ULONG dragndrop_colors[48] = +{ + 0x95959595,0x95959595,0x95959595, + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, + 0x3b3b3b3b,0x67676767,0xa2a2a2a2, + 0x7b7b7b7b,0x7b7b7b7b,0x7b7b7b7b, + 0xafafafaf,0xafafafaf,0xafafafaf, + 0xaaaaaaaa,0x90909090,0x7c7c7c7c, + 0xffffffff,0xa9a9a9a9,0x97979797, + 0xffffffff,0x66666666,0x00000000, + 0xffffffff,0xaaaaaaaa,0x88888888, + 0xffffffff,0xeeeeeeee,0x00000000, + 0x00000000,0x88888888,0x00000000, + 0x00000000,0xdddddddd,0x00000000, + 0x00000000,0xcccccccc,0xcccccccc, + 0x00000000,0x66666666,0xffffffff, + 0x00000000,0x00000000,0xaaaaaaaa, +}; + +#define DRAGNDROP_WIDTH 25 +#define DRAGNDROP_HEIGHT 13 +#define DRAGNDROP_DEPTH 4 +#define DRAGNDROP_COMPRESSION 0 +#define DRAGNDROP_MASKING 2 + +static const struct BitMapHeader dragndrop_header = +{ 25,13,0,0,4,2,0,0,0,44,44,320,256 }; + +static const UBYTE dragndrop_body[208] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x1f,0x08,0x7c,0x00,0x0e,0x00,0x38,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x37,0x8e,0xde,0x00,0x1f,0x02,0x7c,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xfe,0x00,0x1f,0x00,0x7c,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0x8e,0xfe,0x00,0x1f,0x02,0x7c,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x88,0x7c,0x00,0x0e,0x00,0x38, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x00,0x38,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, }; + +//---------------------------------------------------------------------------- + +static const ULONG TrueTypeFonts_colors[48] = +{ + 0xffffffff,0xaaaaaaaa,0x99999999, + 0x93939393,0x93939393,0x93939393, + 0x66666666,0x66666666,0x66666666, + 0x77777777,0x77777777,0x77777777, + 0x00000000,0x66666666,0x99999999, + 0x33333333,0xcccccccc,0xcccccccc, + 0x44444444,0x88888888,0x88888888, + 0xffffffff,0x4e4e4e4e,0x14141414, + 0x00000000,0xffffffff,0x00000000, + 0x01010101,0xb3b3b3b3,0x00000000, + 0x00000000,0x00000000,0x00000000, + 0x00000000,0x55555555,0x77777777, + 0xbebebebe,0x00000000,0x00000000, + 0x00000000,0xcccccccc,0xcccccccc, + 0x00000000,0x66666666,0xffffffff, + 0x00000000,0x00000000,0xaaaaaaaa, +}; + +#define TRUETYPEFONTS_WIDTH 28 +#define TRUETYPEFONTS_HEIGHT 17 +#define TRUETYPEFONTS_DEPTH 4 +#define TRUETYPEFONTS_COMPRESSION 0 +#define TRUETYPEFONTS_MASKING 2 + +static const struct BitMapHeader TrueTypeFonts_header = +{ 28,17,0,0,4,2,0,0,0,44,44,320,256 }; + +static const UBYTE TrueTypeFonts_body[272] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x10,0x63,0x04,0x40,0x1f,0xff,0x07,0xc0,0x00,0x00,0x00,0x00,0x0f, +0x9c,0x03,0x80,0x20,0x9c,0xd2,0x80,0x30,0x7f,0xdd,0xc0,0x00,0x18,0x03,0x00, +0x1f,0xe6,0x0c,0xc0,0x0c,0x5c,0x29,0x80,0x23,0x3f,0xf5,0xc0,0x00,0x18,0x0e, +0x00,0x3f,0xe7,0x91,0xc0,0x0c,0x5f,0x12,0x00,0x23,0x3f,0x6b,0xc0,0x00,0x1f, +0x9c,0x00,0x3f,0xe0,0xe3,0x80,0x03,0x58,0x14,0x40,0x20,0x38,0x27,0xc0,0x00, +0x1f,0xd8,0x00,0x3f,0xe7,0xe6,0x00,0x00,0x58,0x04,0x80,0x20,0x3b,0x37,0x80, +0x00,0x1c,0xd8,0x00,0x3f,0xe7,0xe6,0x00,0x04,0x58,0x14,0x80,0x23,0x3b,0x27, +0x80,0x00,0x1c,0xd8,0x00,0x3f,0xe7,0xe6,0x00,0x04,0x58,0x04,0x80,0x23,0x3b, +0x37,0x80,0x00,0x1c,0xd8,0x00,0x3f,0xe7,0xe6,0x00,0x04,0x58,0x04,0x80,0x23, +0x3b,0x27,0x80,0x00,0x1c,0xd8,0x00,0x3f,0xe7,0xe6,0x00,0x04,0x58,0x12,0x40, +0x23,0x3b,0x33,0xc0,0x00,0x1c,0xcc,0x00,0x3f,0xe7,0xf3,0x80,0x04,0x5c,0x08, +0x80,0x23,0x3c,0x39,0x40,0x00,0x1f,0xc7,0x80,0x3f,0xe3,0xf8,0x40,0x1c,0xc0, +0x33,0x80,0x23,0x20,0x7f,0xc0,0x00,0x1f,0x80,0x00,0x3f,0xff,0xcf,0xc0,0x23, +0x20,0x4c,0x00,0x3f,0xff,0xcf,0x80,0x00,0x00,0x00,0x00,0x1c,0xdf,0x83,0x80, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00, }; + +//---------------------------------------------------------------------------- + +struct ImageDef +{ + ULONG id_ObjIndex; + + CONST_STRPTR id_ImgFileName; + + UBYTE *id_ImgBody; + ULONG id_Width; + ULONG id_Height; + ULONG id_Depth; + ULONG id_Compression; + ULONG id_Masking; + ULONG *id_Colors; +}; + +#define IMGDEF(index, fname, prefix1, PREFIX2) \ + { \ + (index), \ + (fname), (UBYTE *) prefix1##_body, \ + PREFIX2##_WIDTH, PREFIX2##_HEIGHT, PREFIX2##_DEPTH, \ + PREFIX2##_COMPRESSION, PREFIX2##_MASKING, \ + (ULONG *) prefix1##_colors \ + } + + +Object *CreatePrefsImage(void *UserData) +{ + static const struct ImageDef ImageDefs[] = + { + // Page images + IMGDEF(IMAGE_ABOUT, "THEME:prefs/pages/about", about, ABOUT), + IMGDEF(IMAGE_DESKTOP, "THEME:prefs/pages/desktop", desktop, DESKTOP), + IMGDEF(IMAGE_FILEDISPLAY, "THEME:prefs/pages/filedisplay", filedisplay, FILEDISPLAY), + IMGDEF(IMAGE_ICONS, "THEME:prefs/pages/icons", icons, ICONS), + IMGDEF(IMAGE_MISC, "THEME:prefs/pages/misc", misc, MISC), + IMGDEF(IMAGE_MODULES, "THEME:prefs/pages/modules", modules, MODULES), + IMGDEF(IMAGE_PATHS, "THEME:prefs/pages/paths", paths, PATHS), + IMGDEF(IMAGE_PLUGINS, "THEME:prefs/pages/plugins", plugins, PLUGINS), + IMGDEF(IMAGE_STARTUP, "THEME:prefs/pages/startup", startup, STARTUP), + IMGDEF(IMAGE_WINDOWS, "THEME:prefs/pages/windows", windows, WINDOWS), + IMGDEF(IMAGE_TEXTWINDOWS, "THEME:prefs/pages/textwindows", textwindows, TEXTWINDOWS), + IMGDEF(IMAGE_DRAGNDROP, "THEME:prefs/pages/dragndrop", dragndrop, DRAGNDROP), + IMGDEF(IMAGE_TTFONTS, "THEME:prefs/pages/truetypefonts", TrueTypeFonts, TRUETYPEFONTS), + + // Module images + IMGDEF(IMAGE_DELETE, "THEME:prefs/modules/delete", delete, DELETE), + IMGDEF(IMAGE_EMPTY_TRASHCAN, "THEME:prefs/modules/empty_trashcan", empty_trashcan, EMPTY_TRASHCAN), + IMGDEF(IMAGE_EXECUTE_COMMAND, "THEME:prefs/modules/execute_command", execute_command, EXECUTE_COMMAND), + IMGDEF(IMAGE_FORMAT_DISK, "THEME:prefs/modules/format_disk", format_disk, FORMAT_DISK), + IMGDEF(IMAGE_INFORMATION, "THEME:prefs/modules/Information", Information, INFORMATION), + IMGDEF(IMAGE_ICONPROPERTIES, "THEME:prefs/modules/iconproperties", IconProperties, ICONPROPERTIES), + IMGDEF(IMAGE_NEWDRAWER, "THEME:prefs/modules/newdrawer", NewDrawer, NEWDRAWER), + IMGDEF(IMAGE_REBOOT, "THEME:prefs/modules/reboot", Reboot, REBOOT), + IMGDEF(IMAGE_RENAME, "THEME:prefs/modules/rename", rename, RENAME), + IMGDEF(IMAGE_SYSTEMINFO, "THEME:prefs/modules/systeminfo", systeminfo, SYSTEMINFO), + IMGDEF(IMAGE_WINDOWPROPERTIES, "THEME:prefs/modules/windowproperties", WindowProperties, WINDOWPROPERTIES), + + // misc. images + IMGDEF(IMAGE_ICON128, "THEME:prefs/icon128", icon128, ICON128 ), + IMGDEF(IMAGE_ICON96 , "THEME:prefs/icon96", icon96, ICON96 ), + IMGDEF(IMAGE_ICON64, "THEME:prefs/icon64", icon64, ICON64 ), + IMGDEF(IMAGE_ICON48, "THEME:prefs/icon48", icon48, ICON48 ), + IMGDEF(IMAGE_ICON32, "THEME:prefs/icon32", icon32, ICON32 ), + IMGDEF(IMAGE_ICON24, "THEME:prefs/icon24", icon24, ICON24 ), + IMGDEF(IMAGE_ICON16, "THEME:prefs/icon16", icon16, ICON16 ), + + { 0, NULL, 0, 0, 0, 0, 0, 0 } + }; + const struct ImageDef *id; + Object *ImgObj = NULL; + ULONG Index = (ULONG) UserData; + + d1(KPrintF("%s/%s/%ld: START Index=%lu\n", __FILE__, __FUNC__, __LINE__, Index)); + + for (id = ImageDefs; id->id_ImgFileName; id++) + { + if (id->id_ObjIndex == Index) + { + // First try to load datatypes image from THEME: tree + ImgObj = NewObject(DataTypesImageClass->mcc_Class, 0, + MUIA_ScaDtpic_Name, (ULONG) id->id_ImgFileName, + MUIA_ScaDtpic_FailIfUnavailable, TRUE, + End; //DataTypesMCCObject + + d1(KPrintF("%s/%s/%ld: id=%08lx id_ImgFileName=<%s> ObjIndex=%lu ImgObj=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, id, id->id_ImgFileName, id->id_ObjIndex, ImgObj)); + + // Fallback to built-in images + if (NULL == ImgObj) + { + ImgObj = BodychunkObject, + MUIA_FixWidth, id->id_Width, + MUIA_FixHeight, id->id_Height, + MUIA_Bitmap_Width, id->id_Width, + MUIA_Bitmap_Height, id->id_Height, + MUIA_Bodychunk_Depth, id->id_Depth, + MUIA_Bodychunk_Body, (UBYTE *) id->id_ImgBody, + MUIA_Bodychunk_Compression, id->id_Compression, + MUIA_Bodychunk_Masking, id->id_Masking, + MUIA_Bitmap_SourceColors, (ULONG *) id->id_Colors, + MUIA_Bitmap_Transparent, 0, + End; + + d1(KPrintF("%s/%s/%ld: id=%08lx ObjIndex=%lu ImgObj=%08lx\n", __FILE__, __FUNC__, __LINE__, id, id->id_ObjIndex, ImgObj)); + } + break; + } + } + + d1(KPrintF("%s/%s/%ld: END ImgObj=%08lx\n", __FILE__, __FUNC__, __LINE__, ImgObj)); + + return ImgObj; +} + + diff --git a/scalos/Prefs/MainPrefs/Images.h b/scalos/Prefs/MainPrefs/Images.h new file mode 100644 index 000000000..240eb7b30 --- /dev/null +++ b/scalos/Prefs/MainPrefs/Images.h @@ -0,0 +1,9 @@ +// Images.h +// $Date$ + +#ifndef IMAGES_H +#define IMAGES_H + +Object *CreatePrefsImage(void *UserData); + +#endif /* IMAGES_H */ diff --git a/scalos/Prefs/MainPrefs/Images/FileTypesPrefs.brush b/scalos/Prefs/MainPrefs/Images/FileTypesPrefs.brush new file mode 100755 index 0000000000000000000000000000000000000000..1b4efb56cadc3540b5093ab4dc37721396cfe8b6 GIT binary patch literal 1756 zcwVKHzfTlF6vw~EoRE-_!9=Wx3y1O}xr5b>i3v+~IW8gz2ZTsrgV<1CC4~)*@k(17 zJX;$7fGgbO8jFobj4fgP3*2NYiQ5PEsEUgPsP_Y%F2T=cZU&eSt1`hCNDMrjz&SRu|+C)G;-Z@6vS#>aLM9*dZ3 z<@y|{PL*=o>xV^n5;C0)xJXe{#VS-cw5J(dQsj+J2*XTu5Bz%(>vQ5a(%X z`b)CDVrEpNMsqk->#O&}V#7(zxfU`h!c`l(AL5Boy*~tErvT3z_00y|g{7^ld7rLd z70C2C-4@<2U$aSiejqxqW+&)E1;)f7maG;QPFvd7EE~0v7G^%SFp53g9ofUsQVjMz z#={#C*ir;9f}nZc~&?5pKPTaPY~;iw$}ogTM^w%z1#Rw*kr&Lllc2 z0?bj+g@8#b!2E82=?(G?AJgkTs_q1;3msspgF7!fsJ#Pb7b2P;q4qw){m*Z3&x%o^ yaLy@Wf91Z-z^@u1?^_^2$wM-x%g_4*z+0#^kP4f5bBtSlG|C z`$2ako|(Fj{(;-)#_jW@BzNDMJ~@kL~ikKZ(BlnR=S1xqMb!q<`cKFixMRE-uhN z{1rILKovOu5twE@b@12v><;xi;KXs!XYO-Np7I{+qV*+U<`(PM(qFGpKW06M3FIwk^hxSR)OT5bU~EwH-ZKwb-)69vzC-<-^%L0l){E4ySifYPrhee&<*qIm F-vR6-5f%Ud literal 0 HcwPel00001 diff --git a/scalos/Prefs/MainPrefs/Images/IconProperties.c b/scalos/Prefs/MainPrefs/Images/IconProperties.c new file mode 100755 index 000000000..9dc101d71 --- /dev/null +++ b/scalos/Prefs/MainPrefs/Images/IconProperties.c @@ -0,0 +1,60 @@ +#ifdef USE_ICONPROPERTIES_COLORS +const ULONG IconProperties_colors[48] = +{ + 0xa6a6a6a6,0xaaaaaaaa,0xaaaaaaaa, + 0xcacacaca,0xcacacaca,0xcacacaca, + 0x35353535,0x35353535,0x35353535, + 0xffffffff,0xffffffff,0xffffffff, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0x65656565,0x65656565,0x65656565, + 0x00000000,0x00000000,0x00000000, + 0xefefefef,0xe7e7e7e7,0x14141414, + 0xcacacaca,0x9a9a9a9a,0x75757575, + 0x0c0c0c0c,0xe3e3e3e3,0x00000000, + 0x35353535,0x8a8a8a8a,0x35353535, + 0x4d4d4d4d,0x4d4d4d4d,0x4d4d4d4d, + 0x65656565,0x8a8a8a8a,0xbabababa, + 0x8a8a8a8a,0x8a8a8a8a,0x8a8a8a8a, + 0x00000000,0x00000000,0xa6a6a6a6, + 0xa6a6a6a6,0xa6a6a6a6,0xa6a6a6a6, +}; +#endif + +#define ICONPROPERTIES_WIDTH 18 +#define ICONPROPERTIES_HEIGHT 22 +#define ICONPROPERTIES_DEPTH 4 +#define ICONPROPERTIES_COMPRESSION 0 +#define ICONPROPERTIES_MASKING 2 + +#ifdef USE_ICONPROPERTIES_HEADER +const struct BitMapHeader IconProperties_header = +{ 18,22,0,0,4,2,0,0,0,44,44,320,256 }; +#endif + +#ifdef USE_ICONPROPERTIES_BODY +const UBYTE IconProperties_body[352] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x3f,0xfe,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x3d,0x16,0x00,0x00,0x1c,0xe7,0x00,0x00,0x03,0xf8,0x00,0x00, +0x00,0x00,0x00,0x00,0x3b,0xfa,0x00,0x00,0x1c,0x17,0x00,0x00,0x06,0x0c,0x00, +0x00,0x00,0x00,0x00,0x00,0x37,0xf8,0x00,0x00,0x19,0xfb,0x00,0x00,0x09,0xfa, +0x00,0x00,0x00,0x04,0x00,0x00,0x2e,0x0c,0x00,0x00,0x13,0xfd,0x00,0x00,0x1b, +0xfd,0x00,0x00,0x00,0x02,0x00,0x00,0x2d,0xf4,0x00,0x00,0x17,0xfd,0x00,0x00, +0x16,0x0d,0x00,0x00,0x00,0x02,0x00,0x00,0x2d,0xf4,0x00,0x00,0x17,0xfd,0x00, +0x00,0x16,0x0d,0x00,0x00,0x00,0x02,0x00,0x00,0x25,0xe4,0x00,0x00,0x17,0xed, +0x00,0x00,0x1e,0x1d,0x00,0x00,0x00,0x02,0x00,0x00,0x23,0x8c,0x00,0x00,0x0f, +0xb5,0x00,0x00,0x1c,0x75,0x00,0x00,0x00,0x02,0x00,0x00,0x3f,0x38,0x00,0x00, +0x1f,0x5b,0x00,0x00,0x00,0xdb,0x00,0x00,0x00,0x04,0x00,0x00,0x3f,0x60,0x00, +0x00,0x1f,0xaf,0x00,0x00,0x00,0xaf,0x00,0x00,0x00,0x10,0x00,0x00,0x3f,0x4f, +0x00,0x00,0x1f,0xdf,0x00,0x00,0x00,0xd0,0x00,0x00,0x00,0x21,0x00,0x00,0x3f, +0x4e,0x00,0x00,0x1f,0xdf,0x00,0x00,0x00,0xd0,0x00,0x00,0x00,0x20,0x00,0x00, +0x3f,0x9f,0x00,0x00,0x1f,0x6e,0x00,0x00,0x00,0xf1,0x00,0x00,0x00,0x90,0x00, +0x00,0x3f,0xfd,0x00,0x00,0x1f,0x9e,0x00,0x00,0x00,0x61,0x00,0x00,0x00,0x60, +0x00,0x00,0x3f,0x6b,0x00,0x00,0x1f,0xbc,0x00,0x00,0x00,0xb3,0x00,0x00,0x00, +0x01,0x00,0x00,0x3f,0x46,0x00,0x00,0x1f,0xd8,0x00,0x00,0x00,0xd6,0x00,0x00, +0x00,0x22,0x00,0x00,0x3f,0x9c,0x00,0x00,0x00,0x60,0x00,0x00,0x3f,0xfc,0x00, +0x00,0x3f,0x9c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00, }; +#endif diff --git a/scalos/Prefs/MainPrefs/Images/Information.brush b/scalos/Prefs/MainPrefs/Images/Information.brush new file mode 100755 index 0000000000000000000000000000000000000000..3fbbaab9ea414c7d76883862c7fb80577b878d44 GIT binary patch literal 1820 zcwViQ&ubG=5XZlpO$^1w4H5+}CFCTfhlK?}*s|F)Sc}F=?V+9&gy1nJuUl_9^x!qO z93}rkE(^IXBbUL+KtXH5dXm(x_sI`*4olKNyn{7`&`-| zyzdEaa`_yz;$~dszn;778qQL2XCP`9m!l`>jtgn4!F-HcOp}AUufb3S-=`@T41)~W}@o%Y{kiz;t^pfJ{7lO zaVvQOy+2>v-vig&`4>+4ZQUPsRe#oTlfe}$@qv5^s1HIDXJSsa2T#whA0^9N%x@j1 z{Ek=!=g>S-Tu6KDI`aLr;@Fc7glNCuNgD2Zu^cP*86FhOe^fL5zt%eJ@(pcBK84&fK1mZjqjlZW5m&_?Ce&o+A9kkhMbu=O1DG2oYXParcgo z;4Fgi-6wypcygjR>8(6Rzzot{`roH12Iq6VWm5j>JpX2nA-KrGIAaK>6Fj;__53{5 zx{1wflXOCw>YD;PM-^1N?`fC`LK@(Q&joC}I;PLti1LdMTLEv_G2XEe@=WznO{#*c F>^CK$`z-(f literal 0 HcwPel00001 diff --git a/scalos/Prefs/MainPrefs/Images/Information.c b/scalos/Prefs/MainPrefs/Images/Information.c new file mode 100755 index 000000000..2c76844b8 --- /dev/null +++ b/scalos/Prefs/MainPrefs/Images/Information.c @@ -0,0 +1,63 @@ +#ifdef USE_INFORMATION_COLORS +const ULONG Information_colors[48] = +{ + 0x00000000,0x66666666,0xffffffff, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0x44444444,0x44444444,0x44444444, + 0x66666666,0x66666666,0x66666666, + 0x88888888,0x88888888,0x88888888, + 0x99999999,0x99999999,0x99999999, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0xbbbbbbbb,0xbbbbbbbb,0xbbbbbbbb, + 0xcccccccc,0xcccccccc,0xcccccccc, + 0xdddddddd,0xdddddddd,0xdddddddd, + 0xffffffff,0xffffffff,0xffffffff, + 0x22222222,0x22222222,0x22222222, + 0x39393939,0x3d3d3d3d,0x41414141, + 0xefefefef,0xe7e7e7e7,0x14141414, + 0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0xaaaaaaaa, +}; +#endif + +#define INFORMATION_WIDTH 25 +#define INFORMATION_HEIGHT 25 +#define INFORMATION_DEPTH 4 +#define INFORMATION_COMPRESSION 0 +#define INFORMATION_MASKING 2 + +#ifdef USE_INFORMATION_HEADER +const struct BitMapHeader Information_header = +{ 25,25,0,0,4,2,0,0,0,44,44,320,256 }; +#endif + +#ifdef USE_INFORMATION_BODY +const UBYTE Information_body[400] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x40,0x00,0x7f,0xff,0xa0,0x00,0x00,0x00,0x20,0x00,0x7f,0xff, +0xc0,0x00,0x00,0x02,0x80,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x7f, +0xff,0xc0,0x00,0x00,0x09,0x60,0x00,0x41,0xf0,0x20,0x00,0x01,0xf0,0x00,0x00, +0x7f,0xff,0xc0,0x00,0x00,0x02,0x80,0x00,0x41,0xf0,0x20,0x00,0x01,0xf0,0x00, +0x00,0x7f,0xff,0xc0,0x00,0x00,0x05,0xe0,0x00,0x41,0xf0,0x20,0x00,0x01,0xf0, +0x00,0x00,0x7f,0xff,0xe0,0x00,0x00,0x4b,0x40,0x00,0x40,0x00,0x20,0x00,0x00, +0x00,0x20,0x00,0x7f,0xff,0xe0,0x00,0x00,0x15,0xc0,0x00,0x40,0x00,0x20,0x00, +0x00,0x00,0x20,0x00,0x7f,0xff,0xe0,0x00,0x00,0x0f,0xc0,0x00,0x41,0xf0,0x20, +0x00,0x01,0xf0,0x20,0x00,0x7f,0xff,0xe0,0x00,0x02,0x0b,0xf8,0x00,0x41,0xf0, +0x88,0x00,0x01,0xf0,0xf8,0x00,0x7f,0xff,0x70,0x00,0x00,0x0f,0xfe,0x00,0x41, +0xf2,0x02,0x00,0x01,0xf3,0xfe,0x00,0x7f,0xfd,0xfc,0x00,0x04,0x0f,0x7f,0x00, +0x41,0xf4,0x81,0x00,0x01,0xf7,0x7f,0x00,0x7f,0xfb,0xfe,0x00,0x12,0x0e,0x3f, +0x00,0x41,0xf1,0xc0,0x00,0x01,0xf6,0x3f,0x00,0x7f,0xff,0xff,0x00,0x04,0x0f, +0x7f,0x00,0x41,0xf0,0x80,0x00,0x01,0xf7,0x7f,0x00,0x7f,0xff,0xff,0x00,0x2a, +0x07,0xff,0x00,0x41,0xfc,0x01,0x00,0x01,0xf7,0xff,0x00,0x7f,0xfb,0xfe,0x00, +0x16,0x0f,0xff,0x00,0x41,0xf4,0x01,0x00,0x01,0xf7,0xff,0x00,0x7f,0xfb,0xfe, +0x00,0x2a,0x03,0xfe,0x00,0x41,0xfe,0x02,0x00,0x01,0xf3,0xfe,0x00,0x7f,0xfd, +0xfc,0x00,0x1e,0x05,0xfc,0x00,0x41,0xfb,0x04,0x00,0x01,0xf1,0xfc,0x00,0x7f, +0xfe,0xf8,0x00,0x36,0x06,0xf8,0x00,0x41,0xf9,0x8c,0x00,0x01,0xf1,0xfc,0x00, +0x7f,0xfe,0x70,0x00,0x1e,0x04,0x70,0x00,0x41,0xf9,0xf0,0x00,0x01,0xf1,0xf8, +0x00,0x7f,0xfe,0x00,0x00,0x3d,0x54,0x40,0x00,0x42,0xaa,0x68,0x00,0x00,0x03, +0xf0,0x00,0x7f,0xfc,0x00,0x00,0x76,0xa8,0x10,0x00,0x09,0x53,0x58,0x00,0x00, +0x07,0xe0,0x00,0x7f,0xfb,0x00,0x00,0x14,0x00,0x10,0x00,0x5f,0xfc,0x58,0x00, +0x63,0xfc,0xe0,0x00,0x07,0xfc,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x30, +0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, }; +#endif diff --git a/scalos/Prefs/MainPrefs/Images/MenuPrefs.brush b/scalos/Prefs/MainPrefs/Images/MenuPrefs.brush new file mode 100755 index 0000000000000000000000000000000000000000..08139588be4f391305bd04e058acfe05e4e5da7c GIT binary patch literal 1804 zcwWU+%Syvg5S=s?QHoI%bZ0k$NEfx0Mzl12VJ#Rd#V-7T{(=h^cIhwl7qajN1Sz=F zK-MDtg-{XP7&=aJr;mhcq9EQdoI7*QJaRAGqefE)n2*;_%6eHpt^&XseH(-jk3k0@ zm6D1QRP@prh0^VI+c1okR=;Jm+Gh3Az^aJ|duYSsGj{Lnn?Blh*ECJL-$%q+vs89V z!78j*N_x%P$Clx|etH2g7l$Hj!#^*D<_y7shgu-6Mdb5fa@-2&tVlefh^(=O_6Q`8V#L;B(SguUV1!ukRH+OmKgN`zvE!j>J#y zIXHhLJ^}E+^@8)|M}AMB)ARcniFZIwi+&CxrhmfA{2xwWev5GcGS4yl{=@iQntAJ2 zd?Gu(C&A}s^x;ScV$C?`Z~4DoLa7s`(=cH4w<_;l%q`OXgJXo+(67(lPV}BV z0Td2IO#R^4RF0|$U*-Dh3+Z<#c1?B_n1x=z4C%9^&$|9A&$Pt3pPmY4kV?UxAeC;k@cGo;UL3Ug!0sdEckpX{c-q5uE@ literal 0 HcwPel00001 diff --git a/scalos/Prefs/MainPrefs/Images/NewDrawer.brush b/scalos/Prefs/MainPrefs/Images/NewDrawer.brush new file mode 100755 index 0000000000000000000000000000000000000000..563b540b25da9cdfa8c753bc9d1d671003ee6b69 GIT binary patch literal 2116 zcwV(sJxmlq6n-;%9+$Z6tzfYQcndbhfL?-y1>t_!fFztCvCv9maRn8ng)vK{xW>d1 zx+~39mc}z-a>i(JAp}CFVPk2K7^E=9yK&x|J-9nG+>!W-@7w*pH*aR&?99~MLJlA{ zJ~NxmWplSY0JsQ4FsK+J9DIP05te2!naj*8DG7O5EEYY_%jff-%ijL}g+igQwzgI( zmCEIEwOW-@j*X2e#0pTFUdUvz6xd)*W^&W?%x$Uo;wT2rJ|+eW85@R>*CB*fM5b3wfj)U%d-rqj!UthxO|R z<9fUZ$6Mk2rlrT%>iS*S#Ql&W?t{yEy!_IM?}EVng=8<2La}W!+-uma>;H2ADg($9 z+i?D7l0!e1l4*UIg|MJspfpDnU;p1KS9>(la1hJQk#i--q^joSpnpp88L z6EQ+5TG#u1o!VhH=_&kA`1&tjJ*QFV(Ylmsf~ed{H*OJqFx5q+N}F=Apj-e4;3n1U zq5Mc{2P^yVSmpSzMEST->!qs0UAC%nT=t@&bK?#cjYU-rLA^$;e24}YPZ0fC)Ym^^ z<6YGUww%GkyUe0^!LMVw7)~nv>j$+N?CJ`(F7=km#Dv1ygF}VS?HdZ?uTZz?6hD>f q-i1d#qCpFcP}dVOt}85R|E_dsHrjlLkCOVs3j+9M5%;nRmi~Bss8{2t0h3n*tHUW zLH+@TEGK0}%F>ZY<;MVvWhpGcq2t}XxJoBGLWmbVfBoL)<<9rR=ZE`;2~a=Vd)!UB z$)g^Co47?kvXvTAU~9{3d)P@j2b2n0{nl_e?DzYv)+vrnI0$>Eg8?wY%V`)+kHb-K zG#&P`>^fCvS+;xF>Ds2Siq)M?vg__^Yk0QzhP5k{Mr$rF{;w4CnEN%efO%Mv=iEQ!dwZpEk6C?QpEB+vVlDDo zu?ka(3n5ueFz3Ni+@}?@Dvf(SXr4dXe@0c|P=Om@Y`8tB5FC&5N_@-%6o%)MVyE=_ z=t|t}VV9Xt^u?7Y?1~dZ?ik|Q#9Yf`6d+$ zYGdOU<;d^epDd)yeJsSMnzHb%Xpn-GAY@ww^-#q;XLDvY7&}6&iL2ya5_N6mW6` YZ$|l(6yEtcflX?F^7PRFj!OV literal 0 HcwPel00001 diff --git a/scalos/Prefs/MainPrefs/Images/Palette.c b/scalos/Prefs/MainPrefs/Images/Palette.c new file mode 100755 index 000000000..9daefb838 --- /dev/null +++ b/scalos/Prefs/MainPrefs/Images/Palette.c @@ -0,0 +1,59 @@ +#ifdef USE_PALETTE_COLORS +const ULONG Palette_colors[48] = +{ + 0x22222222,0x55555555,0x22222222, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0x55555555,0x55555555,0x55555555, + 0x22222222,0x22222222,0x99999999, + 0x00000000,0x66666666,0xffffffff, + 0x33333333,0x88888888,0x33333333, + 0x44444444,0x99999999,0x88888888, + 0x88888888,0x00000000,0x00000000, + 0xbbbbbbbb,0x00000000,0x77777777, + 0xdddddddd,0x33333333,0x33333333, + 0xdddddddd,0x66666666,0x33333333, + 0xbbbbbbbb,0x44444444,0xbbbbbbbb, + 0xdddddddd,0xaaaaaaaa,0x44444444, + 0xeeeeeeee,0xeeeeeeee,0x11111111, + 0x00000000,0x00000000,0x00000000, + 0xeeeeeeee,0xeeeeeeee,0xeeeeeeee, +}; +#endif + +#define PALETTE_WIDTH 21 +#define PALETTE_HEIGHT 21 +#define PALETTE_DEPTH 4 +#define PALETTE_COMPRESSION 0 +#define PALETTE_MASKING 2 + +#ifdef USE_PALETTE_HEADER +const struct BitMapHeader Palette_header = +{ 21,21,0,0,4,2,0,0,0,44,44,320,256 }; +#endif + +#ifdef USE_PALETTE_BODY +const UBYTE Palette_body[336] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x1e,0x00,0x00, +0x04,0x1e,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x0c,0x00,0x00,0x0f,0x1b,0x00, +0x00,0x0f,0x1b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x80,0x00,0x1f,0xb7, +0x00,0x00,0x1f,0xb7,0x00,0x00,0x20,0x04,0x00,0x00,0x03,0x08,0x00,0x00,0x1e, +0xfb,0x80,0x00,0x1f,0xfb,0x80,0x00,0x26,0x1c,0x00,0x00,0x01,0x9c,0x40,0x00, +0x19,0x83,0x80,0x00,0x1f,0xe3,0x80,0x00,0x07,0x1c,0x00,0x00,0x03,0xdc,0x40, +0x00,0x3b,0xc3,0x80,0x00,0x3c,0xe3,0x80,0x00,0x07,0x1c,0x00,0x00,0x03,0xfd, +0xc0,0x00,0x3b,0xe2,0x00,0x00,0x3c,0xe3,0x80,0x00,0x06,0x10,0x00,0x00,0x00, +0xe1,0xc0,0x00,0x3f,0xee,0x00,0x00,0x3f,0xe3,0x80,0x00,0x07,0x88,0x00,0x00, +0x00,0x73,0x80,0x00,0x3f,0xd4,0x00,0x00,0x3f,0x53,0x80,0x00,0x07,0xcc,0x00, +0x00,0x00,0x3a,0x00,0x00,0x1f,0xe9,0x00,0x00,0x1f,0x27,0x00,0x00,0x02,0x06, +0x00,0x00,0x02,0xe9,0x00,0x00,0x1f,0xe8,0x00,0x00,0x1f,0x1f,0x00,0x00,0x01, +0x13,0x00,0x00,0x01,0xf4,0x00,0x00,0x1f,0xe4,0x00,0x00,0x1f,0x1f,0x00,0x00, +0x02,0x19,0x80,0x00,0x03,0xfa,0x00,0x00,0x0e,0xe2,0x00,0x00,0x0f,0x1f,0x80, +0x00,0x00,0x84,0xc0,0x00,0x07,0xff,0x00,0x00,0x00,0x85,0x00,0x00,0x07,0xf9, +0xc0,0x00,0x00,0x90,0x60,0x00,0x01,0xf3,0x80,0x00,0x00,0x90,0x80,0x00,0x01, +0xe0,0xe0,0x00,0x00,0x00,0x20,0x00,0x00,0x01,0xc0,0x00,0x00,0x00,0x40,0x00, +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, }; +#endif diff --git a/scalos/Prefs/MainPrefs/Images/PatternPrefs.brush b/scalos/Prefs/MainPrefs/Images/PatternPrefs.brush new file mode 100755 index 0000000000000000000000000000000000000000..568adec790755f5c388cac89cd37919caa4ee903 GIT binary patch literal 1724 zcwWtvzl#$=6vw}tNiJ}%jPYk78b~2mgkxa^5mqKY7SDr=k;4>rsSZmkt;8)X?hg=- z{0pfBEi6O_0%8$ZOD)8-Hep~vQv}AhGaCph?jC~pVEDc_pSN#j-p=mL{(cYGc)7dR z>2-RyLI7uR9%o2VE+GP%O{e9c+iTyUDev=vKN^i{1HTc5gTcTLNB$_RO&j6(QRDD% zJRTp6roJCe$07Oi`Fv-;-APN~98P!Jy&dD1PT}tE?R!9_j25==znkwWX;cJ8r&_2~ zg|=}X*Rkb{CtfN`t(PVii7LRERy+;iF`WvZ2+M<57vWqlC#D>O;V#uT&oQQD0nThS z+Kvhgm)y*7k!0)tnL{gSKy1>$J+0G)SZwohxsaaSm`z{_B}j6n%H-v8PDe~**w=xC z8kBlLrhm)R78s3fBZO!3xyK4}+juzObD5|bp+=|3zzi_&SQx>eZ}QEaQ(>)8*e4VSD;2WW}A*%t4FBMfD7+{EiuEjFB1Iy z5GSbaRchx&nyWrlC_M)*^%vNT6@C8;;68BjXn_qHaA>>%s@(-xn|vrZFM!gXG6NWb sT_O2I3w<1#Jv;P#^@wtwWrz4cuWy^?SAYE$`RQ$VwRX_7^aJGD4|Q8S)c^nh literal 0 HcwPel00001 diff --git a/scalos/Prefs/MainPrefs/Images/PatternPrefs.c b/scalos/Prefs/MainPrefs/Images/PatternPrefs.c new file mode 100755 index 000000000..68e8f2f38 --- /dev/null +++ b/scalos/Prefs/MainPrefs/Images/PatternPrefs.c @@ -0,0 +1,57 @@ +#ifdef USE_PATTERNPREFS_COLORS +const ULONG PatternPrefs_colors[48] = +{ + 0xdddddddd,0x66666666,0x33333333, + 0x99999999,0x99999999,0x99999999, + 0x11111111,0x55555555,0x33333333, + 0x22222222,0x44444444,0x44444444, + 0x55555555,0x55555555,0x55555555, + 0x33333333,0x44444444,0x99999999, + 0x33333333,0x99999999,0x44444444, + 0x11111111,0xcccccccc,0x22222222, + 0x44444444,0xaaaaaaaa,0x77777777, + 0x22222222,0x88888888,0x88888888, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0x66666666,0x99999999,0xcccccccc, + 0x33333333,0x33333333,0x44444444, + 0xcccccccc,0xaaaaaaaa,0x44444444, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0xeeeeeeee,0xeeeeeeee,0xeeeeeeee, +}; +#endif + +#define PATTERNPREFS_WIDTH 22 +#define PATTERNPREFS_HEIGHT 19 +#define PATTERNPREFS_DEPTH 4 +#define PATTERNPREFS_COMPRESSION 0 +#define PATTERNPREFS_MASKING 2 + +#ifdef USE_PATTERNPREFS_HEADER +const struct BitMapHeader PatternPrefs_header = +{ 22,19,0,0,4,2,0,0,0,44,44,320,256 }; +#endif + +#ifdef USE_PATTERNPREFS_BODY +const UBYTE PatternPrefs_body[304] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x05,0x2c,0x80,0x00,0x05,0x76,0x80,0x00,0x0a,0xf7,0xc0,0x00,0x07, +0xf6,0x80,0x00,0x0f,0xbc,0x80,0x00,0x01,0x3d,0x40,0x00,0x1e,0xff,0xe0,0x00, +0x01,0x7d,0xc0,0x00,0x1f,0xc3,0x00,0x00,0x04,0x1f,0x00,0x00,0x39,0x7f,0xe0, +0x00,0x06,0xbf,0xc0,0x00,0x3f,0xe9,0x00,0x00,0x11,0x0f,0x00,0x00,0x2e,0xff, +0xc0,0x00,0x11,0x1f,0x80,0x00,0x1f,0xe0,0x00,0x00,0x17,0xc6,0x00,0x00,0x28, +0x3f,0xe0,0x00,0x37,0xdf,0xc0,0x00,0x0f,0xc8,0x60,0x00,0x0b,0x00,0x00,0x00, +0x34,0xff,0xf0,0x00,0x1b,0x3f,0xe0,0x00,0x07,0x84,0xf0,0x00,0x02,0xb0,0x00, +0x00,0x1d,0x4f,0xf8,0x00,0x0a,0xcf,0xf0,0x00,0x03,0x03,0xf8,0x00,0x00,0x68, +0x00,0x00,0x0d,0x97,0xf8,0x00,0x06,0x97,0xf8,0x00,0x00,0x01,0xf8,0x00,0x00, +0xbe,0x00,0x00,0x07,0x43,0xf8,0x00,0x03,0x41,0xf8,0x00,0x00,0x00,0xf0,0x00, +0x01,0xb3,0x00,0x00,0x02,0x4c,0xf0,0x00,0x02,0x4c,0xf0,0x00,0x00,0x00,0x60, +0x00,0x03,0x26,0x00,0x00,0x00,0xd9,0xe0,0x00,0x00,0xd8,0x60,0x00,0x00,0x00, +0x00,0x00,0x01,0x68,0x00,0x00,0x07,0x97,0x00,0x00,0x02,0x94,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0xd0,0x00,0x00,0x03,0x2e,0x00,0x00,0x01,0x28,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x01,0xfc,0x00,0x00,0x00,0xb8,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,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, }; +#endif diff --git a/scalos/Prefs/MainPrefs/Images/Reboot.brush b/scalos/Prefs/MainPrefs/Images/Reboot.brush new file mode 100755 index 0000000000000000000000000000000000000000..74b7ada9666e097f7c7a31b956139275d06a7f6f GIT binary patch literal 2212 zcwV(tPiP!f82`PUO}8}rk4-}ZZZo@hvB_>zyMjfM%p_fG3t1aVBUm&EC@JW*LJpPe zMOdVI_TXW_OWlHc(2D_gVy+>s6LU-4Y2&Hv+G(l~%66aMdoyfiH>C-JAI$gX_xry0 zX6DWJ&6`)R6@cSkU74CJOcpNZ0i47T(qs_~pa^6#OlP=Qn3yK$98fk4BcIPNEG(3O z?ObkqA-7%1mrA8_xxBo*ytcN+InU*Cmw)`63NBrnm=sH)AMuM5g-g;8#Bu$~Tkilp zLFjk||GOkSt8%l$dZK71Y7C4O8tc^yBEL{nKYsA|=ek{wa zDp}&PB9Cb9?9*&_gJ&~j$rpJ{@J(NRgYSxR;v*x@bNDB`k#_k+?Z5D2-1=or@>#9k z#fRyt@oeOr(MMBiYYy!I0&m4iT z-yfIj_O(oOtuNw$^MG4t>DXh>fU_P?2O1DO#bHse0x?m4+T%G86+GbyQLmX8{FUm@ zn+QnWglZB`_+k9%Fs(1FSU+tdqI$gT)!PsF#v`&jR3E4M9ik~#=^5A~8_Z_o>wR?i z%|Y|k24S|!MXbviQ70%`Sa+bd-z{QT(@{dN#`&UX?$B+7F#F~AIJIiroJL6DRzQxr+k6l7@dwzhjcSJ_dDt4yVrq%q*4_4*Y|*zqJg`l zTjQjI?$qKdZHmqxftkihzSBW_?b={=>T(43x($Ky0jN23walPJ#zM@MG21%t*rdkD`* z@9CT8NDXkhwcqPoS6IRFW-r+)=SxjI+unTv+;S1)KK^ra(B%k2IK~(V{S%l>gR6x( zL#7L+z#&XgSngOs`)6HfUCW^(%`)=CxiQh4&j4;_B6DuUjl)p#?zH4KGs`if{1)as zQV!M6s8}W{UZ^TQRZ!0nDTKC9e9DEgT>lXdt^czADf>$tbADa?oANsU*XGB<%0Dmr zr*+kTVQl{w=NhVvuXz?)ZZzdVoEsI^a`Fal-#KUWf~)(rRnTiRnsgnv>!JRkEvbyU zVATBFBK%)le{Vql!bY=hU-Ok4x6K`8=X~Nwe{wFv!;cF09JDW)Vh0aoAik1bf%x)P zv6rg|#A}821mg3BbcU_if4D~a1My2>=t{q{A>mcp9kyi9S-YZL(i^|%t9&&MI`lTZ uoOB`GgJl_XAH`^&NpbNl_EaPT|B&KIy4R@+{2e<=o4@zzjr>iirF{o~X0&_& literal 0 HcwPel00001 diff --git a/scalos/Prefs/MainPrefs/Images/TrueTypeFonts.c b/scalos/Prefs/MainPrefs/Images/TrueTypeFonts.c new file mode 100755 index 000000000..062e2c6c8 --- /dev/null +++ b/scalos/Prefs/MainPrefs/Images/TrueTypeFonts.c @@ -0,0 +1,55 @@ +#ifdef USE_TRUETYPEFONTS_COLORS +const ULONG TrueTypeFonts_colors[48] = +{ + 0xffffffff,0xaaaaaaaa,0x99999999, + 0x93939393,0x93939393,0x93939393, + 0x66666666,0x66666666,0x66666666, + 0x77777777,0x77777777,0x77777777, + 0x00000000,0x66666666,0x99999999, + 0x33333333,0xcccccccc,0xcccccccc, + 0x44444444,0x88888888,0x88888888, + 0xffffffff,0x4e4e4e4e,0x14141414, + 0x00000000,0xffffffff,0x00000000, + 0x01010101,0xb3b3b3b3,0x00000000, + 0x00000000,0x00000000,0x00000000, + 0x00000000,0x55555555,0x77777777, + 0xbebebebe,0x00000000,0x00000000, + 0x00000000,0xcccccccc,0xcccccccc, + 0x00000000,0x66666666,0xffffffff, + 0x00000000,0x00000000,0xaaaaaaaa, +}; +#endif + +#define TRUETYPEFONTS_WIDTH 28 +#define TRUETYPEFONTS_HEIGHT 17 +#define TRUETYPEFONTS_DEPTH 4 +#define TRUETYPEFONTS_COMPRESSION 0 +#define TRUETYPEFONTS_MASKING 2 + +#ifdef USE_TRUETYPEFONTS_HEADER +const struct BitMapHeader TrueTypeFonts_header = +{ 28,17,0,0,4,2,0,0,0,44,44,320,256 }; +#endif + +#ifdef USE_TRUETYPEFONTS_BODY +const UBYTE TrueTypeFonts_body[272] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x10,0x63,0x04,0x40,0x1f,0xff,0x07,0xc0,0x00,0x00,0x00,0x00,0x0f, +0x9c,0x03,0x80,0x20,0x9c,0xd2,0x80,0x30,0x7f,0xdd,0xc0,0x00,0x18,0x03,0x00, +0x1f,0xe6,0x0c,0xc0,0x0c,0x5c,0x29,0x80,0x23,0x3f,0xf5,0xc0,0x00,0x18,0x0e, +0x00,0x3f,0xe7,0x91,0xc0,0x0c,0x5f,0x12,0x00,0x23,0x3f,0x6b,0xc0,0x00,0x1f, +0x9c,0x00,0x3f,0xe0,0xe3,0x80,0x03,0x58,0x14,0x40,0x20,0x38,0x27,0xc0,0x00, +0x1f,0xd8,0x00,0x3f,0xe7,0xe6,0x00,0x00,0x58,0x04,0x80,0x20,0x3b,0x37,0x80, +0x00,0x1c,0xd8,0x00,0x3f,0xe7,0xe6,0x00,0x04,0x58,0x14,0x80,0x23,0x3b,0x27, +0x80,0x00,0x1c,0xd8,0x00,0x3f,0xe7,0xe6,0x00,0x04,0x58,0x04,0x80,0x23,0x3b, +0x37,0x80,0x00,0x1c,0xd8,0x00,0x3f,0xe7,0xe6,0x00,0x04,0x58,0x04,0x80,0x23, +0x3b,0x27,0x80,0x00,0x1c,0xd8,0x00,0x3f,0xe7,0xe6,0x00,0x04,0x58,0x12,0x40, +0x23,0x3b,0x33,0xc0,0x00,0x1c,0xcc,0x00,0x3f,0xe7,0xf3,0x80,0x04,0x5c,0x08, +0x80,0x23,0x3c,0x39,0x40,0x00,0x1f,0xc7,0x80,0x3f,0xe3,0xf8,0x40,0x1c,0xc0, +0x33,0x80,0x23,0x20,0x7f,0xc0,0x00,0x1f,0x80,0x00,0x3f,0xff,0xcf,0xc0,0x23, +0x20,0x4c,0x00,0x3f,0xff,0xcf,0x80,0x00,0x00,0x00,0x00,0x1c,0xdf,0x83,0x80, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00, }; +#endif diff --git a/scalos/Prefs/MainPrefs/Images/WindowProperties.brush b/scalos/Prefs/MainPrefs/Images/WindowProperties.brush new file mode 100755 index 0000000000000000000000000000000000000000..d5b08477523812de04244458d382530cfbe19fdb GIT binary patch literal 2236 zcwVKHO>7%g5XZ-MQ6d!l1(ybA*KwrMpoVzmL&=A;NotW+!UR>}&0teIs8*@NZZk(o4rAiHU93g~A>#w4KwBBK6-daH_CP6&gZ~Xqh zd9&}$ytgkbp3VaFe|_r3`Rsi5WCj49f&_i29rA+(aO{|G)(0oDb1##WY)2w1E7u`H zE{RksmC0lvSAfD5Sh-#(6yT%FrBdPdhaV!Ylu9K;TsS>9&!Hd!krQ*-1^Mp}!_ujj z&Hy}i2xj3Z{NENpSFDa`hXKs0`gNP`Kn!WDw*tu4bU?!fjhk2%-Q(e60E;x=D1o*X zr|~LQi*Rrr_XiNdGS+wuKI!-6-DXn0cwN0(m+Ne+dv-q_@@$fwl1g{udzN_J<1vqK zd%Ui=Q=Ex2513mL-&xlszO!Lg55k*cn()x=rto&8EWDkr2ygj+68;1l!kZXU92G}H z#fLRD-(6GODXaLc`)YnDI;`R+)brbZwxLe-7S}83*Plx>@6@9sRb|JShl}Gfzn*r4 zM^|?O%%k7$R1Uy{W5Xd{hta}DgBGdPj7E_BwYt&dbqDR+vJb<207>R%4TNJ0IBw{{ zh~&YD+_Qz>vi;2U$d=?SxS5nZ8ntp=;_ujMe$|$|4@3>AQ|f*hIsZeo67ar z`|;q-Ha3`>p_q?&EDhVNYn><6`5CTbi@4!xz+9X0sq-~6E;dMYvYFdK#cjnkTg?yF zQ@GAN>~UCCd~8I;kCt7T-*G+e#SfPi@6i1wouP56BNd0F>ecleD1?JTTcJ)LY z3l^N84PK%DdZVzPJ{w1R-J2ALLhF0m$kV2*N0!vpdC%bWy>wmrv-G|b{ZH_E9d|_^ z5WOw>uIP!2tXF+gTddVZPpyv{nZj&~)_ z5%$Mxtm88h=Ns|AvB3Tt9N#TcuiqP`oSYrGlOuie#v*Y48r_G&$K?M;?mg0{zj!AE z)IX&7hnE&8+VWR_Y*{dMI4ilCq4)t>t#PWt3! zKk3t-@{R`Y@a~pJcR9{UVE=y3K=@jYvhnsAq&yrS1zO?p(Hv!L@KxLbc&l0Jv%pwS zkutTx86FzKUn$PEMfyZFPfGe{)}MCq62N&M>yyCxq+j$4_&KfT66??Rvp%uJdhAP= x{Ff`Di~sZoQpbwxqdXvxJ`GaeidWx0%3D(ETmE}}oxXpryPVj6JwFF&e*whU__zQ7 literal 0 HcwPel00001 diff --git a/scalos/Prefs/MainPrefs/Images/WindowProperties.c b/scalos/Prefs/MainPrefs/Images/WindowProperties.c new file mode 100755 index 000000000..bf267197b --- /dev/null +++ b/scalos/Prefs/MainPrefs/Images/WindowProperties.c @@ -0,0 +1,91 @@ +#ifdef USE_WINDOWPROPERTIES_COLORS +const ULONG WindowProperties_colors[48] = +{ + 0xf3f3f3f3,0x11111111,0x11111111, + 0xaaaaaaaa,0xaaaaaaaa,0xbbbbbbbb, + 0x00000000,0x11111111,0x22222222, + 0x00000000,0x22222222,0x22222222, + 0x33333333,0x33333333,0x33333333, + 0x44444444,0x44444444,0x44444444, + 0x00000000,0x77777777,0x88888888, + 0x00000000,0x88888888,0x99999999, + 0x00000000,0xaaaaaaaa,0xbbbbbbbb, + 0x88888888,0x88888888,0x88888888, + 0x00000000,0x96969696,0x98989898, + 0xcccccccc,0xcccccccc,0x88888888, + 0xf5f5f5f5,0xf4f4f4f4,0x92929292, + 0xffffffff,0xffffffff,0xaaaaaaaa, + 0xcccccccc,0xcccccccc,0xcccccccc, + 0xffffffff,0xffffffff,0xffffffff, +}; +#endif + +#define WINDOWPROPERTIES_WIDTH 34 +#define WINDOWPROPERTIES_HEIGHT 34 +#define WINDOWPROPERTIES_DEPTH 4 +#define WINDOWPROPERTIES_COMPRESSION 0 +#define WINDOWPROPERTIES_MASKING 2 + +#ifdef USE_WINDOWPROPERTIES_HEADER +const struct BitMapHeader WindowProperties_header = +{ 34,34,0,0,4,2,0,0,0,44,44,320,256 }; +#endif + +#ifdef USE_WINDOWPROPERTIES_BODY +const UBYTE WindowProperties_body[816] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xfe,0x00,0x00,0x00, +0x00,0xff,0xff,0x80,0x80,0x00,0x7f,0x00,0x00,0x7f,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x3f,0xc0,0x0c,0xff,0x00,0x00,0x3f,0xa0,0xff,0xff,0x00,0x00, +0x7f,0xc0,0x0e,0xff,0x80,0x00,0x3f,0x9f,0xf0,0xff,0x00,0x00,0x3f,0xc0,0x0c, +0xff,0x00,0x00,0x22,0x20,0xff,0x88,0x80,0x00,0x66,0x40,0x0e,0x99,0x00,0x00, +0x22,0x1f,0xf0,0x88,0x00,0x00,0x3f,0xc0,0x0c,0xff,0x00,0x00,0x22,0x20,0xff, +0x88,0x80,0x00,0x66,0x40,0x0e,0x99,0x00,0x00,0x22,0x1f,0xf0,0x88,0x00,0x00, +0x3f,0xc0,0x0c,0xff,0x00,0x00,0x40,0x20,0xff,0x00,0x80,0x00,0x3f,0xc0,0x0e, +0xff,0x00,0x00,0x00,0x1f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x7f,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0x80,0x00, +0x3f,0xff,0xff,0xff,0x00,0x00,0x3f,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0x80,0x00,0x3f,0xff,0xff,0xff,0x00,0x00, +0x3f,0xff,0xff,0xff,0x00,0x00,0x1f,0xff,0xff,0xff,0x00,0x00,0x60,0x00,0x00, +0x01,0x80,0x00,0x3f,0xff,0xff,0xf9,0x00,0x00,0x3f,0xff,0xff,0xf9,0x00,0x00, +0x1f,0xff,0xf7,0xff,0x00,0x00,0x60,0x00,0x0c,0x01,0x80,0x00,0x3f,0xff,0xf3, +0xf9,0x00,0x00,0x3f,0xff,0xf7,0xf9,0x00,0x00,0x1f,0xff,0x22,0x79,0x00,0x00, +0x60,0x00,0xdf,0xc7,0x80,0x00,0x3f,0xff,0x28,0x3f,0x00,0x00,0x3f,0xff,0x2a, +0x7f,0x00,0x00,0x1f,0xfe,0x55,0x39,0x00,0x00,0x60,0x01,0xeb,0xe7,0x80,0x00, +0x3f,0xfe,0xc9,0x9f,0x00,0x00,0x3f,0xfe,0xdd,0xbf,0x00,0x00,0x1f,0xfe,0x82, +0xb9,0x00,0x00,0x60,0x01,0x7f,0x67,0x80,0x00,0x3f,0xfe,0x7f,0x1f,0x00,0x00, +0x3f,0xfe,0xff,0xbf,0x00,0x00,0x1f,0xff,0xd9,0x79,0x00,0x00,0x60,0x00,0x26, +0xe7,0x80,0x00,0x3f,0xff,0xa6,0x1f,0x00,0x00,0x3f,0xff,0x27,0x7f,0x00,0x00, +0x1f,0xfe,0xb5,0xb9,0x00,0x00,0x60,0x01,0xca,0x47,0x80,0x00,0x3f,0xfe,0xd2, +0x3f,0x00,0x00,0x3f,0xfe,0xc2,0x3f,0x00,0x00,0x1f,0xdc,0x29,0x99,0x00,0x00, +0x60,0x23,0xd6,0x77,0x80,0x00,0x3f,0xdd,0xca,0x4f,0x00,0x00,0x3f,0xdd,0xca, +0x5f,0x00,0x00,0x1c,0x88,0x97,0xb9,0x00,0x00,0x63,0x77,0x7c,0x77,0x80,0x00, +0x3c,0xa8,0x74,0x0f,0x00,0x00,0x3c,0xa8,0xf4,0xbf,0x00,0x00,0x19,0x54,0x47, +0x7f,0x00,0x00,0x67,0xaf,0xf8,0xe1,0x80,0x00,0x3b,0x26,0x78,0x19,0x00,0x00, +0x3b,0x76,0x79,0x79,0x00,0x00,0x1a,0x0a,0xff,0xbf,0x00,0x00,0x65,0xfd,0x80, +0x61,0x80,0x00,0x39,0xfc,0x80,0x19,0x00,0x00,0x3b,0xfe,0x80,0xb9,0x00,0x00, +0x1f,0x64,0xdd,0xbf,0x00,0x00,0x64,0x9b,0x20,0x61,0x80,0x00,0x3a,0x98,0x02, +0x19,0x00,0x00,0x3c,0x9c,0x55,0x39,0x00,0x00,0x1a,0xd6,0x2a,0x7f,0x00,0x00, +0x67,0x29,0xf7,0xe1,0x80,0x00,0x3b,0x48,0x00,0x19,0x00,0x00,0x3b,0x08,0x22, +0x79,0x00,0x00,0x10,0xa6,0x77,0xf9,0x00,0x00,0x6f,0x59,0xff,0xc7,0x80,0x00, +0x37,0x29,0x00,0x3f,0x00,0x00,0x37,0x29,0x77,0xff,0x00,0x00,0x1a,0x5e,0xff, +0xe1,0x00,0x00,0x6d,0xf1,0xcc,0x07,0x80,0x00,0x31,0xd0,0x33,0xff,0x00,0x00, +0x3b,0xd2,0xff,0xff,0x00,0x00,0x1d,0x1d,0xff,0xe9,0x00,0x00,0x67,0xe3,0x80, +0x07,0x80,0x00,0x39,0xe0,0x7f,0xff,0x00,0x00,0x3d,0xe5,0xff,0xff,0x00,0x00, +0x1b,0xfe,0xff,0x81,0x00,0x00,0x66,0x01,0x80,0x07,0x80,0x00,0x3a,0x00,0x7f, +0xff,0x00,0x00,0x3a,0x02,0xff,0xff,0x00,0x00,0x1b,0x76,0xff,0xa1,0x00,0x00, +0x64,0x81,0x80,0x07,0x80,0x00,0x38,0x08,0x7f,0xff,0x00,0x00,0x39,0x54,0xff, +0xff,0x00,0x00,0x1c,0xa9,0xfe,0x81,0x00,0x00,0x67,0xdf,0x80,0x07,0x80,0x00, +0x38,0x00,0x7f,0xff,0x00,0x00,0x3c,0x89,0xff,0xff,0x00,0x00,0x1f,0xdf,0xfe, +0x01,0x00,0x00,0x63,0xff,0x00,0x07,0x80,0x00,0x3c,0x00,0xff,0xff,0x00,0x00, +0x3f,0xdf,0xff,0xff,0x00,0x00,0x1f,0xff,0xff,0x07,0x00,0x00,0x60,0x30,0x00, +0x01,0x80,0x00,0x3f,0xcf,0xff,0xf9,0x00,0x00,0x3f,0xff,0xff,0xf9,0x00,0x00, +0x1f,0xff,0xfc,0x07,0x00,0x00,0x60,0x00,0x00,0x01,0x80,0x00,0x3f,0xff,0xff, +0xf9,0x00,0x00,0x3f,0xff,0xff,0xf9,0x00,0x00,0x1f,0xff,0xff,0xff,0x00,0x00, +0x7f,0xff,0xff,0xff,0x80,0x00,0x3f,0xff,0xff,0xff,0x00,0x00,0x3f,0xff,0xff, +0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0x80,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00, }; +#endif diff --git a/scalos/Prefs/MainPrefs/Images/about.brush b/scalos/Prefs/MainPrefs/Images/about.brush new file mode 100755 index 0000000000000000000000000000000000000000..8fca9a4732fb0fde3bf2b1e503e0e6499718fc5a GIT binary patch literal 1548 zcwW7fu};G<5QhI&g#{#MU_?#W7&;)agOgU2N)1I73mX%!kd1ikD|E~3r{DoP@B&DA zf+|nIaZa3)grQMe@N&NUF880$k?&^n5IF8lra>5l_agvjIEBL&y)G0m7<6O@!_a@^ z&=mnml3Yic9leOO)})t26h+Y*OIia9;1gJ_@XEP*Jof`r3MUXlKOE=#u7jt^!!vNy zgTy8NZ4uR60c35spdyW}^^3eLPdNa$I@I83$+79P-fsqR7+&bHELG=a_HB3>C)>aA z%bbI7tF-$L`&mdhNYQU2QXuABC1dra pVvb8|`3ufVl?JNY|j7y literal 0 HcwPel00001 diff --git a/scalos/Prefs/MainPrefs/Images/about.c b/scalos/Prefs/MainPrefs/Images/about.c new file mode 100755 index 000000000..9c6f4c3e0 --- /dev/null +++ b/scalos/Prefs/MainPrefs/Images/about.c @@ -0,0 +1,45 @@ +#ifdef USE_ABOUT_COLORS +const ULONG about_colors[48] = +{ + 0xffffffff,0x00000000,0x00000000, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0x33333333,0x77777777,0xaaaaaaaa, + 0x00000000,0x00000000,0x00000000, + 0xaaaaaaaa,0x88888888,0x77777777, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0xffffffff,0xaaaaaaaa,0x99999999, + 0xffffffff,0xffffffff,0xffffffff, + 0x77777777,0x77777777,0x77777777, + 0xeeeeeeee,0x00000000,0x99999999, + 0xffffffff,0xeeeeeeee,0x00000000, + 0x00000000,0x88888888,0x00000000, + 0x00000000,0xdddddddd,0x00000000, + 0x00000000,0xcccccccc,0xcccccccc, + 0x00000000,0x66666666,0xffffffff, + 0x00000000,0x00000000,0xaaaaaaaa, +}; +#endif + +#define ABOUT_WIDTH 12 +#define ABOUT_HEIGHT 16 +#define ABOUT_DEPTH 4 +#define ABOUT_COMPRESSION 0 +#define ABOUT_MASKING 2 + +#ifdef USE_ABOUT_HEADER +const struct BitMapHeader about_header = +{ 12,16,0,0,4,2,0,0,0,44,44,320,256 }; +#endif + +#ifdef USE_ABOUT_BODY +const UBYTE about_body[128] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x10, +0x80,0x1e,0x00,0x1e,0x80,0x1f,0x00,0x20,0x40,0x10,0x80,0x3e,0x80,0x1f,0x00, +0x00,0x40,0x00,0x80,0x1c,0x80,0x1e,0x00,0x21,0x40,0x0f,0x00,0x7f,0x80,0x00, +0x00,0x80,0x40,0x7f,0x80,0xfe,0x80,0x7f,0x00,0x00,0x40,0x40,0x80,0xfe,0x80, +0x7f,0x00,0x00,0x40,0x10,0x80,0x1e,0x80,0x1f,0x00,0xe0,0x40,0xd0,0x80,0xfe, +0x80,0x1f,0x00,0x00,0x40,0x10,0x80,0x7e,0xe0,0x1f,0x00,0x80,0x00,0x60,0xa0, +0xff,0xa0,0x7f,0xc0,0x00,0x10,0x40,0x20,0xff,0x20,0x7f,0xc0,0x00,0x10,0x3f, +0xe0,0xff,0xe0,0x00,0x00,0x00,0x10,0x80,0x00,0x80,0x00,0x00,0x00,0x7f,0xf0, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, }; +#endif diff --git a/scalos/Prefs/MainPrefs/Images/delete.brush b/scalos/Prefs/MainPrefs/Images/delete.brush new file mode 100755 index 0000000000000000000000000000000000000000..95093d2e8bc2a022fddac7a9334f4c64e395642f GIT binary patch literal 1852 zcwV(t&ubGw6#jN6Z7QZt4iQ5A(H?u~VPOSDmTsB`+k&yBc+i`t;L)4Cs1ZEmKaiXZ z;wh&dg@BCox=;`P0ln$13k4}>Yi^jaU&iCDM^Ay70%};se{V@CH8MU4oW)8al?Rs@ zVm$~BoFRkMGLFnFkpYL?MMy*}5!o&hvyghv`;~yCvqc|X)j)M+j6F;)&)8`%0OY=jNTA4^bvpAu|5rkb#*;nEcUNG~v(LVG=~=mzH`?`WLu#&tfbUVoWxdf0txl{NGxAyTP^4 z+n+WM9~JPb#sluuhB(?o;ln9#bPvU6z-@fNbsA!pKMOo-&U=HqbdEV(;Ueo}$v?-U zi9iKQtOqlhP9+}e66~XV^_1~nC~JOBY587p$cD_@hJNvai-0)0k6UL2F5SGBb2ig= ze&e=;dwNZ*ph(}0?wep&nB%9#eJ=jlGV@p*Z&`o+1md^{UKF1Gr-+uv{&>fIZ)c2y zaX;FJM>UIoV!gTp&*8Jrt0>6$wo%7B1_6y6W Ki`=N^Xukpa`fXkS literal 0 HcwPel00001 diff --git a/scalos/Prefs/MainPrefs/Images/delete.c b/scalos/Prefs/MainPrefs/Images/delete.c new file mode 100755 index 000000000..e15c4b7ea --- /dev/null +++ b/scalos/Prefs/MainPrefs/Images/delete.c @@ -0,0 +1,65 @@ +#ifdef USE_DELETE_COLORS +const ULONG delete_colors[48] = +{ + 0xefefefef,0xe7e7e7e7,0x14141414, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0x44444444,0x44444444,0x44444444, + 0x66666666,0x66666666,0x66666666, + 0x00000000,0x66666666,0x99999999, + 0x33333333,0x77777777,0xaaaaaaaa, + 0x66666666,0x88888888,0xbbbbbbbb, + 0x88888888,0x88888888,0x88888888, + 0x99999999,0x99999999,0x99999999, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0xbbbbbbbb,0xbbbbbbbb,0xbbbbbbbb, + 0xcccccccc,0xcccccccc,0xcccccccc, + 0x33333333,0x33333333,0x33333333, + 0x00000000,0x00000000,0x00000000, + 0x00000000,0x66666666,0xffffffff, + 0x00000000,0x00000000,0xaaaaaaaa, +}; +#endif + +#define DELETE_WIDTH 26 +#define DELETE_HEIGHT 27 +#define DELETE_DEPTH 4 +#define DELETE_COMPRESSION 0 +#define DELETE_MASKING 2 + +#ifdef USE_DELETE_HEADER +const struct BitMapHeader delete_header = +{ 26,27,0,0,4,2,0,0,0,44,44,320,256 }; +#endif + +#ifdef USE_DELETE_BODY +const UBYTE delete_body[432] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0xa2,0xc0,0x00,0x00,0x7d,0x40,0x00,0x00,0x00,0x40,0x00,0x00, +0xff,0x80,0x00,0x03,0xe0,0x78,0x00,0x04,0x9f,0xf8,0x00,0x00,0xe0,0x38,0x00, +0x07,0x60,0x00,0x00,0x1e,0x00,0xbe,0x00,0x15,0xff,0xfe,0x00,0x06,0x00,0x06, +0x00,0x1a,0x00,0x00,0x00,0x08,0x01,0x7f,0x00,0x37,0xff,0xfd,0x00,0x08,0x00, +0x09,0x00,0x28,0x00,0x02,0x00,0x20,0x02,0xfd,0x00,0x1f,0xff,0xff,0x00,0x00, +0x00,0x14,0x00,0x20,0x00,0x02,0x00,0x30,0x05,0xfc,0x00,0x3f,0xff,0xff,0x00, +0x20,0x00,0x28,0x00,0x00,0x00,0x02,0x00,0x10,0x0b,0xf8,0x00,0x1f,0xff,0xf6, +0x00,0x10,0x00,0x40,0x00,0x00,0x00,0x0c,0x00,0x0f,0x97,0xc0,0x00,0x0f,0xff, +0xfe,0x00,0x1e,0x00,0x80,0x00,0x00,0x00,0x30,0x00,0x03,0xff,0xc0,0x00,0x03, +0xfa,0x3a,0x00,0x1d,0xfa,0x04,0x00,0x00,0x05,0xc0,0x00,0x00,0xfd,0x00,0x00, +0x00,0xff,0xd4,0x00,0x0f,0x00,0x28,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, +0x00,0x08,0x00,0x2c,0x00,0x07,0xff,0xd0,0x00,0x00,0x00,0x00,0x00,0x02,0xff, +0x00,0x00,0x00,0x00,0x14,0x00,0x0f,0xff,0xe8,0x00,0x00,0x00,0x00,0x00,0x01, +0x02,0x00,0x00,0x04,0xfc,0x28,0x00,0x03,0xff,0xd0,0x00,0x00,0x00,0x00,0x00, +0x00,0x81,0x00,0x00,0x04,0x7e,0x58,0x00,0x03,0xef,0xa0,0x00,0x00,0x10,0x00, +0x00,0x01,0x42,0x00,0x00,0x00,0x3c,0x28,0x00,0x07,0xff,0xd0,0x00,0x00,0x00, +0x00,0x00,0x00,0x84,0x00,0x00,0x00,0x78,0x50,0x00,0x03,0xef,0xa0,0x00,0x00, +0x10,0x00,0x00,0x00,0x42,0x00,0x00,0x02,0x3c,0xb0,0x00,0x01,0xff,0x40,0x00, +0x00,0x00,0x00,0x00,0x00,0xa4,0x00,0x00,0x02,0x18,0x50,0x00,0x01,0xef,0xa0, +0x00,0x00,0x10,0x00,0x00,0x06,0x68,0x18,0x00,0x07,0x10,0xb8,0x00,0x04,0xff, +0x48,0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x3e,0x00,0x1f,0xc1,0xfe,0x00,0x18, +0x3e,0x06,0x00,0x00,0x00,0x00,0x00,0x0f,0xc0,0xfc,0x00,0x0f,0xff,0xfc,0x00, +0x0e,0x00,0x1c,0x00,0x00,0x00,0x00,0x00,0x03,0xff,0xf0,0x00,0x03,0xff,0xf0, +0x00,0x03,0x80,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc0,0x00,0x00,0xff, +0xc0,0x00,0x00,0xff,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, }; +#endif diff --git a/scalos/Prefs/MainPrefs/Images/desktop.brush b/scalos/Prefs/MainPrefs/Images/desktop.brush new file mode 100755 index 0000000000000000000000000000000000000000..c1a05edb5867d632d05db816aaf785eddc51e9b2 GIT binary patch literal 1676 zcwW7gF>ljQ5Xb+{ODQTA?m!`^NQpWjRH>G{Mrx8;w3RTe0t`%*7&5RhW^4zBe1%F3 z9vCW%p?elfT{2k8!UyP>F%lgRGCBV5J-1yD1jXWpyu16|yYpTAo}V9dBjC=*{TH36 z6YYfn9-xL*uBcXU0&H$NEeAVM`;abQlG8Yj!!Ydidi{PMz0;tdgo8nnB*Wp55h8*O zItJ(oknDEb9i0k~;O(@dU87f4@p}K|TVSb*7M|jN37>6RsILCmzP10zJ^AKyQRB?| zwVvAeyacZN!YAT;RvoARz!3xmcO^5LD>i?MGC1oi!>5va7K^Qqxj1~7v}!E=*cK9K zoH72ro;jY9`G4ov zCGn2KU-Lj8?Q`*=-oV&PhqSk1 zV2k{OoGG8od{l%Sm#D4)>sRM+>=NY366+9$S2wxv_~fXeewlsZ@PGvoT2^$_)5BR_6o=HS$|A8!x?n1 J$2Wt#m0!_}u&n?9 literal 0 HcwPel00001 diff --git a/scalos/Prefs/MainPrefs/Images/desktop.c b/scalos/Prefs/MainPrefs/Images/desktop.c new file mode 100755 index 000000000..69ba08721 --- /dev/null +++ b/scalos/Prefs/MainPrefs/Images/desktop.c @@ -0,0 +1,54 @@ +#ifdef USE_DESKTOP_COLORS +const ULONG desktop_colors[48] = +{ + 0xffffffff,0xaaaaaaaa,0x99999999, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0x44444444,0x44444444,0x44444444, + 0x66666666,0x66666666,0x66666666, + 0x77777777,0x77777777,0x77777777, + 0x00000000,0x66666666,0x99999999, + 0x33333333,0x77777777,0xaaaaaaaa, + 0x44444444,0x88888888,0x88888888, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0xbbbbbbbb,0xbbbbbbbb,0xbbbbbbbb, + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, + 0x00000000,0x22222222,0x44444444, + 0x88888888,0x88888888,0x88888888, + 0x00000000,0x66666666,0xffffffff, + 0x00000000,0x00000000,0xaaaaaaaa, +}; +#endif + +#define DESKTOP_WIDTH 24 +#define DESKTOP_HEIGHT 16 +#define DESKTOP_DEPTH 4 +#define DESKTOP_COMPRESSION 0 +#define DESKTOP_MASKING 2 + +#ifdef USE_DESKTOP_HEADER +const struct BitMapHeader desktop_header = +{ 24,16,0,0,4,2,0,0,0,44,44,320,256 }; +#endif + +#ifdef USE_DESKTOP_BODY +const UBYTE desktop_body[256] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x0f,0xff,0xc0,0x00,0x00,0x00,0x20,0x00,0x07,0xff, +0xc0,0x00,0x03,0xfd,0x40,0x00,0x1b,0xa0,0x20,0x00,0x00,0x00,0x18,0x00,0x0f, +0xff,0xe0,0x00,0x14,0x00,0x00,0x00,0x1f,0xf4,0x30,0x00,0x00,0x0b,0x88,0x00, +0x0f,0xff,0xe0,0x00,0x05,0x50,0x00,0x00,0x1f,0x2f,0xa0,0x00,0x00,0x2f,0x18, +0x00,0x0f,0x80,0xe0,0x00,0x14,0x01,0x00,0x00,0x1c,0xfe,0x30,0x00,0x02,0xff, +0x88,0x00,0x0f,0x00,0xe0,0x00,0x04,0x0a,0x00,0x00,0x1b,0xf4,0xb0,0x00,0x01, +0xff,0x08,0x00,0x0e,0x01,0xe0,0x00,0x14,0x00,0x00,0x00,0x18,0x5f,0xb0,0x00, +0x03,0xa0,0x48,0x00,0x0f,0xff,0xa0,0x00,0x03,0xe8,0x00,0x00,0x19,0xe8,0x30, +0x00,0x00,0x01,0xc8,0x00,0x0f,0xfe,0x20,0x00,0x00,0x00,0x00,0x00,0x3f,0xff, +0xf8,0x00,0x00,0x00,0x04,0x00,0x1f,0xff,0xf0,0x00,0x0f,0xff,0xc0,0x00,0x62, +0xff,0xc8,0x00,0x0c,0x00,0x16,0x00,0x33,0xff,0xe8,0x00,0x5f,0xf8,0x00,0x00, +0x6f,0xff,0x9c,0x00,0x0c,0x00,0x22,0x00,0x33,0xff,0xc8,0x00,0x00,0x00,0x00, +0x00,0x6a,0xaa,0xac,0x00,0x15,0x55,0x52,0x00,0x2a,0xaa,0xa8,0x00,0x1f,0xfa, +0x00,0x00,0xd4,0x00,0x0c,0x00,0x0a,0xa8,0x53,0x00,0x7f,0xff,0xa4,0x00,0x80, +0x00,0x00,0x00,0xff,0xff,0xfe,0x00,0x00,0x00,0x01,0x00,0x7f,0xff,0xfc,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00, }; +#endif diff --git a/scalos/Prefs/MainPrefs/Images/dragndrop.brush b/scalos/Prefs/MainPrefs/Images/dragndrop.brush new file mode 100755 index 0000000000000000000000000000000000000000..da91be5f5e84fa585cf390f6a2db0c0ec0a2260e GIT binary patch literal 1628 zcwTe!5AtPTU<>i|aq@NY^>ATeU=U%DWZ(tT3@l6x4GauAI*bmC49>oe0YD*xsZ*x{ zssI1~Tc5aQ_<$-uzM!r;K5!7vIa1AiD8_z%!dp7}q+0s9ZQ)ln+XZ-3y= z=RaU|JYaRymIo%+{}6cw+Q=XH^B=GMl*u#yKR_USDU&A@{}juQ0=&S<-vw9}GF%{} u4ju3@SfKFbIciYE%=_*!$TQWz`S$<+F~~C@@%#Rv$jf)2>PI)9Q~&_gUX`T) literal 0 HcwPel00001 diff --git a/scalos/Prefs/MainPrefs/Images/dragndrop.c b/scalos/Prefs/MainPrefs/Images/dragndrop.c new file mode 100755 index 000000000..bfe95fb19 --- /dev/null +++ b/scalos/Prefs/MainPrefs/Images/dragndrop.c @@ -0,0 +1,50 @@ +#ifdef USE_DRAGNDROP_COLORS +const ULONG dragndrop_colors[48] = +{ + 0x95959595,0x95959595,0x95959595, + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, + 0x3b3b3b3b,0x67676767,0xa2a2a2a2, + 0x7b7b7b7b,0x7b7b7b7b,0x7b7b7b7b, + 0xafafafaf,0xafafafaf,0xafafafaf, + 0xaaaaaaaa,0x90909090,0x7c7c7c7c, + 0xffffffff,0xa9a9a9a9,0x97979797, + 0xffffffff,0x66666666,0x00000000, + 0xffffffff,0xaaaaaaaa,0x88888888, + 0xffffffff,0xeeeeeeee,0x00000000, + 0x00000000,0x88888888,0x00000000, + 0x00000000,0xdddddddd,0x00000000, + 0x00000000,0xcccccccc,0xcccccccc, + 0x00000000,0x66666666,0xffffffff, + 0x00000000,0x00000000,0xaaaaaaaa, +}; +#endif + +#define DRAGNDROP_WIDTH 25 +#define DRAGNDROP_HEIGHT 13 +#define DRAGNDROP_DEPTH 4 +#define DRAGNDROP_COMPRESSION 0 +#define DRAGNDROP_MASKING 2 + +#ifdef USE_DRAGNDROP_HEADER +const struct BitMapHeader dragndrop_header = +{ 25,13,0,0,4,2,0,0,0,44,44,320,256 }; +#endif + +#ifdef USE_DRAGNDROP_BODY +const UBYTE dragndrop_body[208] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x1f,0x08,0x7c,0x00,0x0e,0x00,0x38,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x37,0x8e,0xde,0x00,0x1f,0x02,0x7c,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xfe,0x00,0x1f,0x00,0x7c,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0x8e,0xfe,0x00,0x1f,0x02,0x7c,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x88,0x7c,0x00,0x0e,0x00,0x38, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x00,0x38,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, }; +#endif diff --git a/scalos/Prefs/MainPrefs/Images/empty_trashcan.brush b/scalos/Prefs/MainPrefs/Images/empty_trashcan.brush new file mode 100755 index 0000000000000000000000000000000000000000..473a533d9e7e683447656cffa4a1649246db2953 GIT binary patch literal 1884 zcwW6#J!lkB5dQXFlC#+4MNM%?er&`PA#7N*2ut>o93}zJgpeX>6%NZ(Y86kgxXw~j z2q~=6Xk`Micyib+oP}UxBG_mlWN{1eSToLhZxfOeyolhy-0aLZGjDe0-R!mb#WIjz zn!7$#o+{6l0QBJk23Vpahbk~K;uIZBmnRq4)e1 z*Vi{UH+Ob+qA1$k-6bO5_c>r@adJwhLN|J*C(ASDIoFG&xf?4$X9tQH#(yByqQ@=r z&$uTK?XLL^WPDtTH1>=h!blO3wI`&EncTWEer`j{KqS60cI(#$7t{!oRO^jEOQHO_ z475EZGGX-){NSeb1PSXRaH$SRqL8BYxQsmM^00*KDL3SV37;2dIG-nl^p(;QzA||z z(&vJw9O`;Jid@D;ETd4@C1XE(Z)(KtaZnN(ouxjH+hA1VpoPr(Bq@@SX=`K~4d2dz z66;TtXuGa4%Yf71B9m-$bwWNiIUerXGK{NwNd*^(d1R^WxHX^c$u zSa4LB@N7J!jc={59S&u?g;4p%ttCIQcvr>^Vh5H=U3QA&ygazkZXa#s7__=1aT_ zowx1$px3b>WqDdZUj%L`!_LCWZVi3SVf2sR!TC3w zn_fY_uQDHCP;c=2G0#UqG{-T}?BLbTHT`5ey@SkFyu*A3BOGgAHD`v=$GN{)JjWl0 zbeQvGt$4ut+A_rc2GGm6{*na4NAY;bd~e|h2jjWm1sp0`{2A+o1vnYrb-RFk?>0JU n*1$uB2@JhHKw+ZG=u)LzONt)!8=dc)ebpMrh?ZSI+v literal 0 HcwPel00001 diff --git a/scalos/Prefs/MainPrefs/Images/empty_trashcan.c b/scalos/Prefs/MainPrefs/Images/empty_trashcan.c new file mode 100755 index 000000000..acb40c6f7 --- /dev/null +++ b/scalos/Prefs/MainPrefs/Images/empty_trashcan.c @@ -0,0 +1,67 @@ +#ifdef USE_EMPTY_TRASHCAN_COLORS +const ULONG empty_trashcan_colors[48] = +{ + 0xefefefef,0xe7e7e7e7,0x14141414, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0x44444444,0x44444444,0x44444444, + 0x66666666,0x66666666,0x66666666, + 0x00000000,0x66666666,0x99999999, + 0x33333333,0x77777777,0xaaaaaaaa, + 0x66666666,0x88888888,0xbbbbbbbb, + 0x88888888,0x88888888,0x88888888, + 0x99999999,0x99999999,0x99999999, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0xbbbbbbbb,0xbbbbbbbb,0xbbbbbbbb, + 0xcccccccc,0xcccccccc,0xcccccccc, + 0xdddddddd,0xdddddddd,0xdddddddd, + 0xffffffff,0xffffffff,0xffffffff, + 0x33333333,0x33333333,0x33333333, + 0x00000000,0x00000000,0x00000000, +}; +#endif + +#define EMPTY_TRASHCAN_WIDTH 26 +#define EMPTY_TRASHCAN_HEIGHT 29 +#define EMPTY_TRASHCAN_DEPTH 4 +#define EMPTY_TRASHCAN_COMPRESSION 0 +#define EMPTY_TRASHCAN_MASKING 2 + +#ifdef USE_EMPTY_TRASHCAN_HEADER +const struct BitMapHeader empty_trashcan_header = +{ 26,29,0,0,4,2,0,0,0,44,44,320,256 }; +#endif + +#ifdef USE_EMPTY_TRASHCAN_BODY +const UBYTE empty_trashcan_body[464] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x00,0x00,0x00,0x00,0xc0,0x00,0x00, +0x00,0xc0,0x00,0x00,0x43,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x63,0xc0,0x00, +0x00,0x63,0xc0,0x00,0x01,0xec,0x40,0x00,0x00,0x70,0x40,0x00,0x01,0xaf,0xc0, +0x00,0x01,0xdf,0x80,0x00,0x07,0xf2,0x98,0x00,0x01,0xe2,0xb8,0x00,0x06,0x1d, +0x58,0x00,0x07,0xff,0xc0,0x00,0x1f,0xb7,0xde,0x00,0x07,0xb6,0xde,0x00,0x18, +0x59,0x36,0x00,0x1f,0xef,0xf0,0x00,0x1e,0x97,0x0f,0x00,0x2e,0x9d,0x0d,0x00, +0x11,0x62,0xf9,0x00,0x3f,0xf7,0xfa,0x00,0x3a,0x43,0x25,0x00,0x12,0x48,0x27, +0x00,0x0d,0xb7,0xdc,0x00,0x3f,0xf7,0xfe,0x00,0x31,0x35,0x88,0x00,0x31,0x05, +0x8f,0x00,0x2e,0xfa,0xf0,0x00,0x0f,0xff,0x7e,0x00,0x14,0xfa,0x28,0x00,0x1c, +0x3a,0x76,0x00,0x13,0xc5,0x80,0x00,0x07,0xff,0xbc,0x00,0x0f,0xd7,0x80,0x00, +0x0f,0xd7,0xfe,0x00,0x1e,0x28,0x00,0x00,0x00,0x7f,0xf0,0x00,0x03,0xff,0xc0, +0x00,0x03,0xfa,0x3a,0x00,0x1d,0xfa,0x04,0x00,0x00,0x05,0xc0,0x00,0x00,0xfd, +0x00,0x00,0x00,0xff,0xd4,0x00,0x0f,0x00,0x28,0x00,0x00,0x00,0x00,0x00,0x01, +0x00,0x00,0x00,0x08,0x00,0x2c,0x00,0x07,0xff,0xd0,0x00,0x00,0x00,0x00,0x00, +0x02,0xff,0x00,0x00,0x00,0x00,0x14,0x00,0x0f,0xff,0xe8,0x00,0x00,0x00,0x00, +0x00,0x01,0x02,0x00,0x00,0x04,0xfc,0x28,0x00,0x03,0xff,0xd0,0x00,0x00,0x00, +0x00,0x00,0x00,0x81,0x00,0x00,0x04,0x7e,0x58,0x00,0x03,0xef,0xa0,0x00,0x00, +0x10,0x00,0x00,0x01,0x42,0x00,0x00,0x00,0x3c,0x28,0x00,0x07,0xff,0xd0,0x00, +0x00,0x00,0x00,0x00,0x00,0x84,0x00,0x00,0x00,0x78,0x50,0x00,0x03,0xef,0xa0, +0x00,0x00,0x10,0x00,0x00,0x00,0x42,0x00,0x00,0x02,0x3c,0xb0,0x00,0x01,0xff, +0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa4,0x00,0x00,0x02,0x18,0x50,0x00,0x01, +0xef,0xa0,0x00,0x00,0x10,0x00,0x00,0x06,0x68,0x18,0x00,0x07,0x10,0xb8,0x00, +0x04,0xff,0x48,0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x3e,0x00,0x1f,0xc1,0xfe, +0x00,0x18,0x3e,0x06,0x00,0x00,0x00,0x00,0x00,0x0f,0xc0,0xfc,0x00,0x0f,0xff, +0xfc,0x00,0x0e,0x00,0x1c,0x00,0x00,0x00,0x00,0x00,0x03,0xff,0xf0,0x00,0x03, +0xff,0xf0,0x00,0x03,0x80,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc0,0x00, +0x00,0xff,0xc0,0x00,0x00,0xff,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, }; +#endif diff --git a/scalos/Prefs/MainPrefs/Images/execute_command.brush b/scalos/Prefs/MainPrefs/Images/execute_command.brush new file mode 100755 index 0000000000000000000000000000000000000000..9bfd854a060ee6fe6a679cb1feef2a926cf99c9c GIT binary patch literal 2308 zcwW7gL1-Lh6vy9}S=m~mQ(}W!w6ohqkUDFOK~M>u-6Wa@-Nu$KB1K{jJ@lgSq!+t; z@seYXo=PktgRLkMAyTqUp$DlFCLT+6iuO`wGutd-#q8|od+(dso!wGfM0|($vj5-z z|9#)g&TQVCJyihM*P3~IqA*c7J_P^=;V3+Z6A}YZ1~5&L6EIoGzk||C&2!76qoea@ z=kdc#VWw#>!TcAmon1b+xU#soXxm?{tbG6L>dN(>uP-evHTRm+r}7iD6b!@AWWF%X ze-9jh(=#XD19&6>Id~raw|eFQdNhypVoPGR`ewa5)4z=EY!32dp28WRer)FkT*Z8P zeJl8Vkf-7}nFndb|2eOR`$iK|;km+T_&Vwy7~4A)$eI9|5h)!PU`(CQ*bcdm*&z=v z4?ovZUG7yw-f**&Pmdc8=f@4=x@R%hecy#m%HK4kN%@-(#lbU}gWtHN);ABU^}Ud1 zLM~mWs`A-XH!r+v%!My&*{nzTA;(E|&L=#G_&}A`$;coD-Rnbc$+ia?<%y@I zREP_w%GcjUR5Q^h)qN0j^N5=n=7_d14WuJ_FT(pP3i;bDb7%TO3xtrCmFv1poViVgTLYhrc^e+#uwALP4F-Fr{8SWlEYGCyCj z-j4dyXYPDQo%Bb~$Sn}t7x6b*JaxG_N}cq5mr3_el71imv%IqELhZ=i`WPR4us*yX ziXdK*?QcM=(Z1F^>m`6oAktEvj`X)!KVL7R|4H3O|BpKA#x&{1XZ3+AAYRaeDG)!A zu1%7zoxe-|;m65;h4m@cOLaRSe=!mIlgCL7iaiyb=Op$$!r^4M$7?*-KmpXl|#+tIn_Q-975!4^jkK1i#cmy}N^2IkGbZahpFJf`46q1N1({GXMYp literal 0 HcwPel00001 diff --git a/scalos/Prefs/MainPrefs/Images/execute_command.c b/scalos/Prefs/MainPrefs/Images/execute_command.c new file mode 100755 index 000000000..1c951ba02 --- /dev/null +++ b/scalos/Prefs/MainPrefs/Images/execute_command.c @@ -0,0 +1,96 @@ +#ifdef USE_EXECUTE_COMMAND_COLORS +const ULONG execute_command_colors[48] = +{ + 0xf7f7f7f7,0x69696969,0xa2a2a2a2, + 0x31313131,0x31313131,0x31313131, + 0x61616161,0x65656565,0x61616161, + 0x00000000,0x00000000,0x00000000, + 0x49494949,0x4d4d4d4d,0x49494949, + 0xf7f7f7f7,0xaaaaaaaa,0x92929292, + 0x00000000,0x61616161,0x9a9a9a9a, + 0x39393939,0x65656565,0xa2a2a2a2, + 0x69696969,0x8a8a8a8a,0xb6b6b6b6, + 0x8a8a8a8a,0x8a8a8a8a,0x8a8a8a8a, + 0xaaaaaaaa,0xaaaaaaaa,0xa6a6a6a6, + 0xb6b6b6b6,0xb6b6b6b6,0xb2b2b2b2, + 0xcececece,0xbabababa,0xb6b6b6b6, + 0xc6c6c6c6,0xcacacaca,0xc6c6c6c6, + 0x92929292,0x92929292,0x92929292, + 0xf7f7f7f7,0xfbfbfbfb,0xf7f7f7f7, +}; +#endif + +#define EXECUTE_COMMAND_WIDTH 42 +#define EXECUTE_COMMAND_HEIGHT 37 +#define EXECUTE_COMMAND_DEPTH 4 +#define EXECUTE_COMMAND_COMPRESSION 0 +#define EXECUTE_COMMAND_MASKING 2 + +#ifdef USE_EXECUTE_COMMAND_HEADER +const struct BitMapHeader execute_command_header = +{ 42,37,0,0,4,2,0,0,0,44,44,320,256 }; +#endif + +#ifdef USE_EXECUTE_COMMAND_BODY +const UBYTE execute_command_body[888] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,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,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00, +0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x04,0x80,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xff,0xff,0xff,0xff,0x00,0x01,0xff,0xff, +0xff,0xff,0x00,0x01,0xff,0xff,0xff,0xfe,0x00,0x01,0xff,0xff,0xff,0xfe,0x00, +0x01,0x19,0x5b,0xea,0xb1,0x00,0x01,0x19,0x5b,0xff,0xff,0x00,0x01,0x09,0x5b, +0xff,0xde,0x00,0x01,0xee,0xa4,0x02,0x10,0x00,0x01,0x18,0xae,0xf7,0x31,0x00, +0x01,0x18,0xae,0xff,0xff,0x00,0x01,0x08,0xae,0xff,0xde,0x00,0x01,0xef,0x51, +0x02,0x10,0x00,0x01,0x19,0x5b,0xea,0xb1,0x00,0x01,0x19,0x5b,0xff,0xff,0x00, +0x01,0x09,0x5b,0xff,0xde,0x00,0x01,0xee,0xa4,0x02,0x10,0x00,0x1d,0xff,0xff, +0xff,0xff,0x00,0x1d,0xff,0xff,0xff,0xff,0x00,0x01,0x00,0x00,0x00,0x00,0x00, +0x01,0x00,0x00,0x00,0x00,0x00,0x3f,0x71,0xff,0xff,0xfd,0x00,0x3f,0x6e,0xa0, +0x01,0x55,0x00,0x01,0x35,0xff,0xfe,0xac,0x00,0x01,0xbf,0xff,0xff,0xfe,0x00, +0x3f,0x61,0xff,0xff,0xfd,0x00,0x3f,0x7f,0x00,0x00,0xad,0x00,0x01,0x21,0xff, +0xff,0x54,0x00,0x01,0xbf,0xff,0xff,0xfe,0x00,0x3f,0x4b,0xff,0xff,0xfd,0x00, +0x3f,0x7e,0xf0,0x55,0x55,0x00,0x01,0x17,0x0f,0xaa,0xac,0x00,0x01,0xb7,0x0f, +0xff,0xfe,0x00,0x1f,0x47,0xff,0xff,0xfd,0x00,0x1f,0x7d,0xf0,0x02,0xbd,0x00, +0x01,0x2b,0x0f,0xfd,0x44,0x00,0x01,0xbb,0x0f,0xff,0xfe,0x00,0x03,0x43,0xff, +0xff,0xfd,0x00,0x03,0x7e,0xf1,0x55,0x55,0x00,0x01,0x15,0x0e,0xaa,0xac,0x00, +0x01,0xbd,0x0f,0xff,0xfe,0x00,0x03,0x44,0xff,0xff,0xfd,0x00,0x03,0x7f,0xf0, +0xaa,0xfd,0x00,0x01,0x2b,0x0f,0x55,0x04,0x00,0x01,0xbb,0x0f,0xff,0xfe,0x00, +0x07,0x48,0xff,0xff,0xfd,0x00,0x07,0x7f,0xf5,0x55,0x5d,0x00,0x01,0x15,0x0a, +0xaa,0xa4,0x00,0x01,0xb7,0x0f,0xff,0xfe,0x00,0x07,0x40,0x3f,0xff,0xfd,0x00, +0x07,0x7f,0xc2,0xbf,0xfd,0x00,0x01,0x3f,0xfd,0x40,0x04,0x00,0x01,0xbf,0xff, +0xff,0xfe,0x00,0x07,0x40,0x1f,0xff,0xed,0x00,0x0f,0x7f,0xf5,0x57,0xfd,0x00, +0x01,0x1f,0xea,0xa8,0x04,0x00,0x01,0xbf,0xff,0xff,0xfe,0x00,0x0f,0x40,0x0f, +0xff,0xfd,0x00,0x07,0x7f,0xf8,0xff,0xfd,0x00,0x01,0x3f,0x77,0x00,0x04,0x00, +0x01,0xbf,0x7f,0xff,0xfe,0x00,0x0f,0x60,0x1f,0xff,0xad,0x00,0x0f,0x5f,0xf5, +0x5f,0xfd,0x00,0x01,0x3a,0xaa,0xa0,0x04,0x00,0x01,0xba,0xbf,0xff,0xfe,0x00, +0x0f,0x70,0x0f,0xff,0xfd,0x00,0x0d,0x4f,0xfb,0xff,0xfd,0x00,0x01,0x3f,0xd4, +0x00,0x04,0x00,0x03,0xbf,0xdf,0xff,0xfe,0x00,0x07,0xf0,0x07,0xfa,0xad,0x00, +0x0f,0xff,0xfd,0x7f,0xfd,0x00,0x00,0x0a,0xaa,0x80,0x04,0x00,0x00,0x1a,0xaf, +0xff,0xfe,0x00,0x03,0xe0,0x03,0xff,0x55,0x00,0x07,0xff,0xff,0xff,0xfd,0x00, +0x00,0x15,0x10,0x00,0x04,0x00,0x00,0x15,0x13,0xff,0xfe,0x00,0x01,0x40,0x01, +0xba,0xad,0x00,0x01,0x7f,0xff,0xff,0xfd,0x00,0x01,0x2a,0xa2,0x00,0x04,0x00, +0x01,0xaa,0xa3,0xff,0xfe,0x00,0x01,0x70,0x41,0xf5,0x45,0x00,0x01,0x6f,0xff, +0xff,0xfd,0x00,0x01,0x14,0x00,0x00,0x04,0x00,0x01,0xb4,0x41,0xff,0xfe,0x00, +0x01,0x70,0xe0,0xaa,0x85,0x00,0x01,0x5f,0x7f,0xff,0xfd,0x00,0x01,0x2a,0x80, +0x00,0x04,0x00,0x01,0xba,0xe1,0xff,0xfe,0x00,0x01,0x7f,0xff,0xff,0xfd,0x00, +0x01,0x7f,0xff,0xff,0xfd,0x00,0x01,0x7f,0xff,0xff,0xfc,0x00,0x01,0xff,0xff, +0xff,0xfe,0x00,0x01,0xff,0xff,0xff,0xff,0x00,0x01,0xff,0xff,0xff,0xff,0x00, +0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x1e,0x07, +0x00,0x00,0x00,0x00,0x1e,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x07,0x00,0x00,0x00,0x00,0x3c,0x07, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x38,0x03,0x00,0x00,0x00,0x00,0x38,0x03,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x03,0xe0,0x00,0x00, +0x00,0x70,0x03,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0xf0,0x03,0xf0,0x00,0x00,0x00,0xf1,0xfb,0xf0,0x00,0x00, +0x00,0x01,0xe4,0x00,0x00,0x00,0x00,0x01,0xe0,0x00,0x00,0x00,0x01,0xf0,0x00, +0x00,0x00,0x00,0x01,0xf3,0xfc,0x00,0x00,0x00,0x00,0x0c,0x03,0x80,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xe0,0x00,0x00,0x00,0x00,0x01,0xe5,0x00, +0x00,0x00,0x00,0x00,0x1a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00, }; +#endif diff --git a/scalos/Prefs/MainPrefs/Images/filedisplay.brush b/scalos/Prefs/MainPrefs/Images/filedisplay.brush new file mode 100755 index 0000000000000000000000000000000000000000..d5f8e23e3b4689841ba3cb0f306230905e093ec9 GIT binary patch literal 1676 zcwW7f&uY|A6vn?ys<;T;4k)-$+$q>aAPYBvGc%3-1IB7?7lI2x7(rdRa9l_-P^I$< zBEqa)_y88hKyhW@BDmHE5QacDBB94~b6c$b*~o0#s%9X9v3`lg}9Ul+e>N1LZms=la76eY5UsgZ)RT1rH6fQnVp&M z`^@|O<~P5YIWarm0Q~FqQ`JVbQJV%Zgnjg*r@w$EaQLt{>ET#oYL29Z_4V~jU$x$; zp4r$?)ZX6S-rU?=TwHu~ZffiP@%b~~Xsw_9KD2e@2+^yntNTBFx3Y5LgYP~*_vnl9 z@$q`Sz6`W(wAMerb?xZ##@V|M4m~`3=#y($yj%P7Ax_QAPgQATA2T~siYJjGU8peQLOTvhXtnDBdgo+jH&RkMuI=oqNM=yP zb8rwgtf@}2xCkyCr(bb#9*)PltC6NDcN}-)sP&5DdAPFGwRUka+2H!!Jx=w`MLM>+ zg0yiFx^3euX|;AadU9~(koFn5}1Q{iED-oXyG{To}_l6f|Vl>MT^2W7_S$G%siL*sQ0W2SeL&&~`r5K$L@< z;LPeOg5@}4nO!(8O>JCynjaTI*Z5oGN4%E9V_fG9EXmMXIGHGA6B zQfL#Io;jv;LVYHM@tZL^OHF=JerRi-5;Dobk-u~R(x>HwJC(IbTC2mJi->Godgiz} zK4dQRB$>G1&!2K1lKWp%dJ9hTNFJ`rP zJ_5XP9pahgn!`V=R7I;o(-XbpaZ`1<9){%HkskBH_HaIx4d9DJ_4?n_!Gg#uHw HD#hl1%1LLG literal 0 HcwPel00001 diff --git a/scalos/Prefs/MainPrefs/Images/format_disk.c b/scalos/Prefs/MainPrefs/Images/format_disk.c new file mode 100755 index 000000000..2e662f043 --- /dev/null +++ b/scalos/Prefs/MainPrefs/Images/format_disk.c @@ -0,0 +1,81 @@ +#ifdef USE_FORMAT_DISK_COLORS +const ULONG format_disk_colors[96] = +{ + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0x7f7f7f7f,0x89898989,0xc2c2c2c2, + 0x24242424,0x42424242,0x66666666, + 0xadadadad,0xadadadad,0xf0f0f0f0, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0xe3e3e3e3,0xe3e3e3e3,0xe3e3e3e3, + 0xc6c6c6c6,0xc6c6c6c6,0xc6c6c6c6, + 0x6a6a6a6a,0x6a6a6a6a,0x6a6a6a6a, + 0xdbdbdbdb,0x75757575,0x41414141, + 0xdfdfdfdf,0xbabababa,0x45454545, + 0x52525252,0x66666666,0x94949494, + 0xffffffff,0xffffffff,0xffffffff, + 0xefefefef,0xe7e7e7e7,0x14141414, + 0xdfdfdfdf,0x35353535,0x35353535, + 0x00000000,0x00000000,0x00000000, + 0x8a8a8a8a,0x8a8a8a8a,0x8a8a8a8a, + 0x19191919,0x5e5e5e5e,0x32323232, + 0x38383838,0x88888888,0x46464646, + 0x56565656,0xb1b1b1b1,0x5a5a5a5a, + 0x75757575,0xdbdbdbdb,0x6e6e6e6e, + 0x29292929,0x29292929,0x29292929, + 0x49494949,0x49494949,0x49494949, + 0x82828282,0x00000000,0x00000000, + 0xc2c2c2c2,0x99999999,0xc2c2c2c2, + 0xaaaaaaaa,0x68686868,0xa2a2a2a2, + 0x91919191,0x36363636,0x82828282, + 0xadadadad,0x6d6d6d6d,0xb5b5b5b5, + 0xc7c7c7c7,0x2b2b2b2b,0xd9d9d9d9, + 0x6d6d6d6d,0x2b2b2b2b,0x5b5b5b5b, + 0x91919191,0x00000000,0x6a6a6a6a, + 0xb5b5b5b5,0x48484848,0x6f6f6f6f, + 0xd9d9d9d9,0x00000000,0x4c4c4c4c, +}; +#endif + +#define FORMAT_DISK_WIDTH 21 +#define FORMAT_DISK_HEIGHT 21 +#define FORMAT_DISK_DEPTH 5 +#define FORMAT_DISK_COMPRESSION 0 +#define FORMAT_DISK_MASKING 2 + +#ifdef USE_FORMAT_DISK_HEADER +const struct BitMapHeader format_disk_header = +{ 21,21,0,0,5,2,0,0,0,44,44,320,256 }; +#endif + +#ifdef USE_FORMAT_DISK_BODY +const UBYTE format_disk_body[420] = { +0x00,0x00,0x01,0xf0,0x00,0x00,0x01,0xf0,0x00,0x00,0x01,0xf0,0x00,0x00,0x05, +0xf0,0x00,0x00,0x07,0x58,0x00,0x00,0x04,0x50,0x00,0x00,0x04,0xa8,0x00,0x00, +0x05,0x00,0x00,0x00,0x00,0x90,0x00,0x00,0x00,0xa0,0x0a,0xff,0x70,0x00,0x04, +0x00,0x10,0x00,0x01,0xff,0x10,0x00,0x00,0x00,0x0f,0xdf,0x00,0x00,0x00,0x7f, +0x10,0xe2,0xa8,0x00,0x0e,0x1d,0x60,0x00,0x01,0xf3,0x20,0x00,0x0e,0x00,0x5f, +0x9f,0x00,0x00,0x07,0xff,0x10,0xc2,0xd7,0xc0,0x0e,0x3c,0x40,0x00,0x01,0xf3, +0x48,0x00,0x0e,0x0c,0x3f,0xc0,0x00,0x00,0x00,0x00,0x10,0x82,0xa8,0x00,0x0e, +0x7c,0x88,0x00,0x01,0xf3,0x90,0x00,0x0e,0x0c,0x78,0x00,0x00,0x00,0x07,0x20, +0x10,0x03,0x50,0x00,0x0e,0xfd,0x10,0x00,0x01,0xf3,0x28,0x00,0x0e,0x0c,0xf8, +0x00,0x00,0x00,0x07,0xa0,0x10,0x02,0xaf,0xbf,0x0e,0xee,0x20,0x00,0x01,0xf2, +0x50,0x00,0x0e,0x01,0xf8,0x00,0x00,0x00,0x07,0x20,0x10,0x05,0x50,0x00,0x0f, +0xfc,0x40,0x00,0x00,0x04,0xa0,0x00,0x0f,0xfb,0xf8,0x00,0x00,0x00,0x07,0xc0, +0x17,0xfa,0xa0,0x00,0x0c,0x08,0x88,0x00,0x03,0xf9,0x48,0x00,0x08,0x07,0xf8, +0x00,0x00,0x00,0x00,0x00,0x17,0xf5,0x4f,0xff,0x0f,0xf1,0x18,0x00,0x00,0x12, +0x98,0x00,0x0f,0xef,0xf8,0x00,0x00,0x00,0x07,0x80,0x17,0xca,0x88,0x42,0x0f, +0xc2,0x38,0x00,0x00,0x05,0x28,0x00,0x0f,0xdf,0xe8,0x00,0x00,0x20,0x07,0x80, +0x17,0xd5,0x0c,0x00,0x0f,0x84,0x78,0x00,0x00,0x0a,0x48,0x00,0x0f,0x9f,0xe8, +0x00,0x00,0x60,0x00,0x00,0x17,0x4a,0x4f,0xfc,0x0f,0x08,0xb8,0x00,0x00,0x14, +0xc8,0x00,0x0f,0x1f,0xa8,0x00,0x00,0xe0,0x00,0x00,0x17,0x44,0xc8,0x0a,0x0e, +0x01,0x38,0x00,0x01,0x09,0xc8,0x00,0x0f,0x0f,0x28,0x00,0x00,0xf0,0x07,0x00, +0x16,0x21,0xc8,0x00,0x0c,0x70,0x38,0x00,0x02,0x11,0xc8,0x00,0x0f,0x10,0x28, +0x00,0x00,0xee,0x07,0x80,0x14,0x13,0xcf,0x00,0x08,0xa4,0x38,0x00,0x04,0x87, +0xc8,0x00,0x0f,0x84,0x28,0x00,0x00,0x78,0x07,0x00,0x10,0x87,0xc8,0x03,0x00, +0x47,0xdc,0x00,0x08,0xc7,0xe8,0x00,0x07,0xc0,0x08,0x00,0x08,0x3f,0xe0,0x00, +0x11,0xcf,0xd8,0x00,0x18,0x30,0x28,0x01,0x11,0xf0,0x18,0x00,0x17,0xcf,0xc8, +0x00,0x00,0x3f,0xd0,0x00,0x0f,0x8f,0xf7,0xfe,0x08,0x61,0xf0,0x00,0x0f,0xff, +0xf0,0x00,0x0f,0x80,0x70,0x00,0x00,0x7e,0x07,0x80,0x02,0x1f,0xf1,0xf0,0x01, +0xcf,0xf7,0x00,0x03,0xff,0xf0,0x00,0x02,0x03,0xf0,0x00,0x01,0xf0,0x07,0x80, + }; +#endif diff --git a/scalos/Prefs/MainPrefs/Images/icon-128x128.iff b/scalos/Prefs/MainPrefs/Images/icon-128x128.iff new file mode 100755 index 0000000000000000000000000000000000000000..b0543b366249deca7db142f1b65096f2a7035a99 GIT binary patch literal 6696 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 literal 0 HcwPel00001 diff --git a/scalos/Prefs/MainPrefs/Images/icon-16x16.iff b/scalos/Prefs/MainPrefs/Images/icon-16x16.iff new file mode 100755 index 0000000000000000000000000000000000000000..d3d0ebb46131c904b44fe17f2cff35cc28990069 GIT binary patch literal 376 zcwR-1JxD@f6o$Vyjh4!WpdiE1p_;NG5H6aDm14BDNEVF|(h?C^SE4D9h897KpgH=X zA<#>PnPp&TqKOIx8ix1gZK%M$J|XZN&d&oc=f`ZHu@Qph39Hd&v{_7qkZ#h&oLMUY z%Rqz2Y=&tDb1W#O^JeRwFY61OuWnsTId>vS@hq6Q%hqn6DzWr?Bvpx~-eT!WB43L? zSEH#?BqLotzTOw)crx=TSw5<}FQ+39C!XB8;mEsvIXUF(?8xed*<_>LG|P4rSld{{ zGJczFJp|c;Vo| hkD@pZ@CZ7wVnrwn`4H`D$P`L~Z;Coa3u!(@{s0o%r>g(} literal 0 HcwPel00001 diff --git a/scalos/Prefs/MainPrefs/Images/icon-24x24.iff b/scalos/Prefs/MainPrefs/Images/icon-24x24.iff new file mode 100755 index 0000000000000000000000000000000000000000..4bec17ea437fd0044fe7787768c23bee13305197 GIT binary patch literal 668 zcwT*xT}V@57{{NpXKFCS%svJQ+l3e9MVkhFV06|LGw874O?2hC^l}&8M37Pu2fB&q zLLw3&WO!p2L3kmXG(UpLCY{+4Mzdr|x!g)^LTB&k|AImn;dwbPzvukk=i}w{M*1}( z*RvZp!&+GD>mj1!p0G0?wfYv)Qj=rJ!5A6!`9Q$SDJo* zapgxgUruE{zhC*DUM($H<)!@3%%|<;FV*;)chhsGY2|Yt=XQS?m9Hl^($}-I@zqh) zywx@J_`&m*=3L+$Du*LIw=s{qM#3Sg?XUkcQ;3M2w+;vcGxbTsN(?NPD3Uh;#M2Nb~Xv1DfWuZa{KSE_~|Hx@6Htht?*$}Oq zJP;{}jU8k(?SQOV literal 0 HcwPel00001 diff --git a/scalos/Prefs/MainPrefs/Images/icon-32x32.iff b/scalos/Prefs/MainPrefs/Images/icon-32x32.iff new file mode 100755 index 0000000000000000000000000000000000000000..71576170169fe02911925e39a2a84e765f7677f6 GIT binary patch literal 826 zcwU8)PfQa*6vn6f7223hw-FDGMz+!Di3my*6Twy>MiUy;gMZ?|UQ9fRo+Ku^gJSSP z#Kd?}6T(4{8lxACX^EhqNI^g}A+V+VQG#p>)ogX!@eLll=}z{```&Nny_wlP*mx|$ z7vh2)F673U1!AcR(ddXH)Gq?fm;#XJ#4%OpuENy-vpxeGUHi?V`=^z4dqUhIFr=dH(C~YWX zqDrJ0DqFG)qirh!Wmik1C>P02=z{eCF(s~BG*7gWuqf?{x#7olFRY&}2J~D^r7H<%QI(@F==P*9V0r%J zX}D8+&q0~-bRdw7t3ber<9kMb48`jYLis}C)2v}AX^kUUXBzORK8B(Ol8sL;c7lbe TUZF|I+h2=a9qd2<+u!IndqGPW literal 0 HcwPel00001 diff --git a/scalos/Prefs/MainPrefs/Images/icon-48x48.iff b/scalos/Prefs/MainPrefs/Images/icon-48x48.iff new file mode 100755 index 0000000000000000000000000000000000000000..913ed7377f790755e69bbf7e880cc01a3401b7eb GIT binary patch literal 1486 zcwUv1e`s4(6vxlY%gIZc^oO-9U0X^1&@BjC#!$N{E@?O26ibH~@E5e`KpEIoaBQr9 zBds(dNzIY_wni9 zuFbFhIJ>;1^`+E|p1A(YUH#D7>Y41sma$~t^ob`XAKTvN@o?nU_B}6f=7)<=B)-en z|9rCnI83k+t(o-KyY(#cioh#4JdqJ4;?X^FR5n`Po|xtBo3p$J{P4GtBiKy2BZrS# zL~gGn6z8C|O-GJegjW(;{G22TvBxFh2)9Z?OPsSpg=Bp2Mmhu|2HY2Aq(-=eG)D7M zl&CI|WAWh_BPYQ&$H)P&``Oq-MK*#;>k@e*5=kxOo9KwiC}m=qF0EJP>)VhLHwPPcae(c%6;BIXX+iA{B@aF=G0_%ZO4&lz$@r zNO(XZv0d+3h!Q9xg)(wluD!zAd0(!l-%4a3C@1PJBTgB`u5i_*Q^mU{tSA*jYzz@S z4`^d#6HC83owh&fP;gg$y)kLNHISNYypnZ5$tp{9&o#Bxv+R04JScytpL=($K zfv(^SJFW>ETcS01&pGffgPGiouxTLiq9eH+5KnMK)wis|>MNnBTEyYy1E?ai^KMpi=Qx`X`OmWo1{_PDmg415;`Si%*{nw$CBNW0&`_@%zEiFa4-Jcy=4t30j>C z1(x)l{H-XDnp|sa+_B^Wfoclu@^9Zfpz)VLss8oN{CPXO c&m>LA(@23zLkg`L*2$%S%lOZS+`qlSpIFIO!T_4A*d4FIJOrZ0W+K+shP9zQ+5ZUGG<^h3mBzy9^w ztIPK7yS{bn?%ki9S=-Y6{2L$sc=Bw|DK~NK^zpu{KlR@_+}%_4%<|9ocb>VBx_;5T zab?bJ_svY|<80>0!0+D;bkz4IwjcbU`E2v78IMe8EiCMN;xSULZ2*6I1BMPEo;Q6a)PVa{!gvxulJ65Xfo3(ZGcSPlu)Y z*zsLcsq7TA&v8E&MAIwI_tEWW$U5%`cVZE@vObVLX-d#tN|Nu{=!0Sxv^J&{PqoYvT1jHRjKva~4Ww=lt2Tj1YBq?9 zSznWza+%G=VxJQ0r-)WHvPaT{xAYte%wePO)WHMo6f)jY;G4p_esYnVfRZd-ghC%{ zfj=;M^kf!2(`wr{Efg?`Tsv%HCeu`t4TGL|3>Psd^@B)Ceg@(EU*co&ug zD~9tM&AdE@v$@#LqdJ5@N@+Ns;Lts=UtV4o(7Aa~T+F$Z7cdth7#6M=N@IlhU2XKEqZW> zl^0S)*D|~aH)0FJCc%2;#|S6T*hcUa^+MpOB?SLX6?vps}<6Hi074}=k7lnh{l7emC|70ag&!>zA3Gn_O%k?sR&(6&=D zO;u-ugyqVM;|lgr3_}Y4C{&kG=Czikg*pN48cG!fJ{d+@q<|}|Ss83!6(7qiVrzWHYLqhBfM%wd z+ApzgAU!u{1( zY3aA2YeDU1hOzFQ=;n}Sg6chI7#3?BPLE(x&a(>+bp(sUa?ncEd7+|^EJ7R#q3N)Z zbwD}Nrwt#&=4v-o9+p|l-Ov##Pw=7*Q6P>iA;t!Dc=gEOnB8Bp$=c2~Ib==}9nsEy zna8l|itwzgEuxV-Fe$^9#`DMGW~Ic@y8;){46^GcqDgzv!khG`Mv`Pu3y4VHsrdQU z+FfnZn;Qv?RJ-ERpe++uyKLTYLlLpgHXwvU8ipvoUo_${?at4@R}wuOm%e`VOx2Z? zzBszoBAS%cV+VDD@Hkd1+`HbExB%{Z=+YXC&)nX@OLJ@qJ^0172Yw(!VjH(HI;mds z*s>Eeu7tXW%lZiRyqfMZgP3z(NgtYI_&v~v1WKU2g4&71?_p;$yp)dhqL!la@GInc zxn*VrupwH)BEijR%uth{Rxa^ebAw0GQQO;5Z6No6^3of68jKmM=QKc;u7=Kufz literal 0 HcwPel00001 diff --git a/scalos/Prefs/MainPrefs/Images/icon-96x96.iff b/scalos/Prefs/MainPrefs/Images/icon-96x96.iff new file mode 100755 index 0000000000000000000000000000000000000000..3104210df0d77cb5248b898f1b2db71ba074625e GIT binary patch literal 4378 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 literal 0 HcwPel00001 diff --git a/scalos/Prefs/MainPrefs/Images/icon128.c b/scalos/Prefs/MainPrefs/Images/icon128.c new file mode 100755 index 000000000..00f00c2d0 --- /dev/null +++ b/scalos/Prefs/MainPrefs/Images/icon128.c @@ -0,0 +1,489 @@ +#ifdef USE_ICON-128X128_COLORS +const ULONG icon-128x128_colors[96] = +{ + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, + 0xc8c8c8c8,0xd5d5d5d5,0xe9e9e9e9, + 0xabababab,0xacacacac,0xefefefef, + 0x95959595,0x95959595,0x9b9b9b9b, + 0x92929292,0x99999999,0xd7d7d7d7, + 0x7b7b7b7b,0x87878787,0xbfbfbfbf, + 0x53535353,0x67676767,0x95959595, + 0xe8e8e8e8,0xeeeeeeee,0xfbfbfbfb, + 0xd3d3d3d3,0xdededede,0xf1f1f1f1, + 0xc1c1c1c1,0xcacacaca,0xdadadada, + 0xc9c9c9c9,0xd5d5d5d5,0xe9e9e9e9, + 0xcccccccc,0xdadadada,0xefefefef, + 0xc9c9c9c9,0xd7d7d7d7,0xecececec, + 0xd4d4d4d4,0xe4e4e4e4,0xfafafafa, + 0xa9a9a9a9,0xb1b1b1b1,0xbcbcbcbc, + 0x26262626,0x3f3f3f3f,0x5d5d5d5d, + 0x77777777,0x7c7c7c7c,0x82828282, + 0xefefefef,0xe7e7e7e7,0x15151515, + 0xf3f3f3f3,0xecececec,0x4d4d4d4d, + 0xf8f8f8f8,0xf3f3f3f3,0x83838383, + 0xfafafafa,0xf7f7f7f7,0xaeaeaeae, + 0xfcfcfcfc,0xfafafafa,0xd6d6d6d6, + 0xd0d0d0d0,0xc4c4c4c4,0x7e7e7e7e, + 0xe1e1e1e1,0xb4b4b4b4,0x42424242, + 0xdcdcdcdc,0x70707070,0x3f3f3f3f, + 0xb0b0b0b0,0x7a7a7a7a,0x69696969, + 0x60606060,0x56565656,0x55555555, + 0x8c8c8c8c,0x0a0a0a0a,0x0a0a0a0a, + 0xd9d9d9d9,0x34343434,0x32323232, + 0xc6c6c6c6,0xc4c4c4c4,0xc4c4c4c4, + 0xffffffff,0xffffffff,0xffffffff, +}; +#endif + +#define ICON-128X128_WIDTH 128 +#define ICON-128X128_HEIGHT 128 +#define ICON-128X128_DEPTH 5 +#define ICON-128X128_COMPRESSION 1 +#define ICON-128X128_MASKING 0 + +#ifdef USE_ICON-128X128_HEADER +const struct BitMapHeader icon-128x128_header = +{ 128,128,0,0,5,0,1,0,0,1,1,128,128 }; +#endif + +#ifdef USE_ICON-128X128_BODY +const UBYTE icon-128x128_body[6544] = { +0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1, +0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00, +0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1, +0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00, +0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1, +0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00, +0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1, +0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00, +0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1, +0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00, +0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1, +0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00, +0xfa,0x00,0x00,0xf8,0xf9,0x00,0xfa,0xff,0x00,0x07,0xf9,0xff,0xfa,0x00,0x00, +0xf8,0xf9,0x00,0xfa,0x00,0x00,0xf8,0xf9,0x00,0xf1,0x00,0xfa,0x00,0x00,0x08, +0xf9,0x00,0xfa,0xff,0x00,0xf7,0xf9,0xff,0xfa,0x00,0x00,0x08,0xf9,0x00,0xfa, +0x00,0x00,0x08,0xf9,0x00,0xf1,0x00,0xfb,0x00,0x02,0x1e,0x01,0xc0,0xfa,0x00, +0xfb,0xff,0x02,0xe1,0xfe,0x3f,0xfa,0xff,0xfb,0x00,0x02,0x1e,0x01,0xc0,0xfa, +0x00,0xfb,0x00,0x02,0x1e,0xe1,0xc0,0xfa,0x00,0xf1,0x00,0xfb,0x00,0x02,0x1a, +0x07,0xe0,0xfa,0x00,0xfb,0xff,0x02,0xe1,0xf8,0x1f,0xfa,0xff,0xfb,0x00,0x02, +0x1e,0x47,0xe0,0xfa,0x00,0xfb,0x00,0x02,0x1f,0xff,0xe0,0xfa,0x00,0xfa,0x00, +0x00,0x40,0xf9,0x00,0xfb,0x00,0x01,0x01,0x01,0xf9,0x00,0xfa,0xff,0x00,0xfe, +0xf9,0xff,0xfa,0x00,0x00,0x79,0xf9,0x00,0xfb,0x00,0x01,0x01,0xfd,0xf9,0x00, +0xfa,0x00,0x00,0x78,0xf9,0x00,0xfc,0x00,0x03,0x07,0xc0,0xb8,0x0f,0xfa,0x00, +0xfc,0xff,0x03,0xf8,0x3f,0x3f,0xf0,0xfa,0xff,0xfc,0x00,0x03,0x07,0xc0,0x2c, +0x0f,0xfa,0x00,0xfc,0x00,0x03,0x07,0xcf,0xc6,0xef,0xfa,0x00,0xfa,0x00,0x00, +0x3c,0xf9,0x00,0xfc,0x00,0x03,0x03,0xc1,0x14,0x0b,0xfa,0x00,0xfc,0xff,0x03, +0xfc,0x3f,0x5f,0xf0,0xfa,0xff,0xfc,0x00,0x03,0x03,0xc6,0x66,0x4f,0xfa,0x00, +0xfc,0x00,0x03,0x03,0xff,0x83,0xef,0xfa,0x00,0xfb,0x00,0x02,0x06,0x7e,0x40, +0xfa,0x00,0xfb,0x00,0x02,0x08,0x16,0x20,0xfa,0x00,0xfb,0xff,0x01,0xfe,0xdf, +0xf9,0xff,0xfb,0x00,0x02,0x3e,0xe7,0x80,0xfa,0x00,0xfc,0x00,0x03,0x02,0x37, +0x01,0xf0,0xfa,0x00,0xfb,0x00,0x02,0x3e,0xff,0x80,0xfa,0x00,0xfc,0x00,0x04, +0xc0,0x34,0x5f,0x20,0xf8,0xfb,0x00,0xfc,0xff,0x04,0x0f,0xf1,0x47,0x9f,0x07, +0xfb,0xff,0xfc,0x00,0x04,0xf0,0x25,0xb9,0x88,0xf8,0xfb,0x00,0xfc,0x00,0x04, +0xf7,0x4a,0x00,0x7e,0xf8,0xfb,0x00,0xfb,0x00,0x02,0x3d,0xff,0x88,0xfa,0x00, +0xfc,0x00,0x04,0x30,0x2c,0x85,0xc8,0x70,0xfb,0x00,0xfc,0xff,0x04,0xcf,0xf9, +0xdf,0x1f,0x8f,0xfb,0xff,0xfc,0x00,0x04,0x33,0x65,0x38,0x9e,0x70,0xfb,0x00, +0xfc,0x00,0x04,0x37,0xc2,0x00,0x3f,0x70,0xfb,0x00,0xfc,0x00,0x03,0x03,0x7d, +0xff,0x96,0xfa,0x00,0xfd,0x00,0x06,0x1e,0x06,0xfa,0xdb,0x57,0x01,0xc0,0xfc, +0x00,0xfd,0xff,0x06,0xe1,0xfd,0xf8,0xc3,0x2f,0xfe,0x3f,0xfc,0xff,0xfd,0x00, +0x06,0x1e,0x01,0xc7,0x3c,0xef,0x81,0xc0,0xfc,0x00,0xfd,0x00,0x06,0x1e,0x3f, +0x00,0x00,0x18,0x99,0xc0,0xfc,0x00,0xfc,0x00,0x04,0x01,0xff,0xff,0xef,0x80, +0xfb,0x00,0xfd,0x00,0x06,0x3e,0x00,0x83,0xbd,0xf0,0x22,0xe0,0xfc,0x00,0xfd, +0xff,0x06,0xc1,0xf9,0xdb,0x5a,0xc2,0xfc,0x1f,0xfc,0xff,0xfd,0x00,0x06,0x3e, +0x11,0x3c,0xe7,0x24,0x9b,0xe0,0xfc,0x00,0xfd,0x00,0x06,0x3e,0xfe,0x00,0x00, +0x09,0xdf,0xe0,0xfc,0x00,0xfc,0x00,0x04,0x11,0xff,0xff,0xe7,0x98,0xfb,0x00, +0xfd,0x00,0x05,0x06,0x03,0x81,0x4f,0x81,0x80,0xfb,0x00,0xfd,0xff,0x04,0xfb, +0xf8,0xdb,0x98,0xdb,0xfa,0xff,0xfd,0x00,0x05,0x04,0xf1,0x3c,0xa5,0x3c,0xf0, +0xfb,0x00,0xfd,0x00,0x01,0x07,0xfc,0xfe,0x00,0x00,0x7c,0xfb,0x00,0xfc,0x00, +0x04,0xf1,0xff,0xbd,0xff,0xf0,0xfb,0x00,0xfe,0x00,0x07,0x07,0x40,0xf4,0x00, +0x00,0x01,0xf4,0x1f,0xfc,0x00,0xfe,0xff,0x07,0xf8,0x3f,0xe0,0x00,0x00,0x01, +0xcf,0xe0,0xfc,0xff,0xfe,0x00,0x07,0x07,0xc1,0xa7,0xff,0xff,0xfe,0x68,0x1f, +0xfc,0x00,0xfe,0x00,0x02,0x07,0xf9,0x18,0xfe,0x00,0x01,0x1f,0x9f,0xfc,0x00, +0xfd,0x00,0x01,0x01,0xe7,0xfe,0xff,0x00,0xe0,0xfb,0x00,0xfe,0x00,0x07,0x06, +0x05,0x19,0xfc,0x81,0x0f,0x84,0x0f,0xfc,0x00,0xfe,0xff,0x07,0xf8,0x7f,0xc3, +0x1b,0xdb,0xd8,0xd3,0xf0,0xfc,0xff,0xfe,0x00,0x07,0x07,0x99,0x24,0xa7,0x3c, +0xe5,0x33,0x0f,0xfc,0x00,0xfe,0x00,0x01,0x07,0xba,0xfd,0x00,0x01,0x0f,0xcf, +0xfc,0x00,0xfd,0x00,0x05,0x19,0xe7,0xbf,0xff,0xfd,0xf3,0xfb,0x00,0xfe,0x00, +0x08,0x70,0x33,0xd9,0x19,0xc3,0x3d,0xd4,0xc8,0x30,0xfd,0x00,0xfe,0xff,0x08, +0x8f,0xff,0xc3,0xda,0xdb,0xda,0xcb,0xf7,0xcf,0xfd,0xff,0xfe,0x00,0x08,0x70, +0x0f,0x3c,0xe7,0x3c,0xe7,0x39,0xe8,0x30,0xfd,0x00,0xfe,0x00,0x01,0x73,0xbc, +0xfd,0x00,0x02,0x07,0x3a,0x30,0xfd,0x00,0xfd,0x00,0x00,0x0f,0xfd,0xff,0x01, +0xf9,0xe0,0xfc,0x00,0xfe,0x00,0x08,0xf0,0x27,0x5b,0x5a,0xcb,0x5a,0xd0,0xa0, +0x78,0xfd,0x00,0xfe,0xff,0x08,0x0f,0xcf,0x18,0x42,0x08,0x42,0x15,0xbf,0x87, +0xfd,0xff,0xfe,0x00,0x08,0xf1,0xcc,0xe7,0xbd,0xf7,0xbd,0xed,0x22,0x78,0xfd, +0x00,0xfe,0x00,0x01,0xf7,0xf0,0xfd,0x00,0x02,0x02,0x57,0x78,0xfd,0x00,0xfe, +0x00,0x01,0x01,0xcf,0xfd,0xff,0x01,0xfd,0xe2,0xfc,0x00,0xfe,0x00,0x08,0x30, +0x31,0x77,0x81,0x67,0x95,0x47,0xa0,0x60,0xfd,0x00,0xfe,0xff,0x08,0xcf,0xcb, +0x98,0xdb,0x98,0xcf,0x98,0xff,0x9f,0xfd,0xff,0xfe,0x00,0x08,0x33,0xcc,0xa5, +0x3c,0xa5,0x28,0xa5,0x12,0x60,0xfd,0x00,0xfe,0x00,0x01,0x37,0xe0,0xfc,0x00, +0x01,0x1f,0x60,0xfd,0x00,0xfe,0x00,0x07,0x03,0xcf,0xbd,0xff,0xbd,0xef,0xbd, +0xf2,0xfc,0x00,0x0b,0x00,0x00,0x04,0x07,0xd2,0xd3,0x5a,0xd3,0xda,0xca,0x7b, +0x80,0xfd,0x00,0x0a,0xff,0xff,0xfb,0xfc,0xa2,0x10,0x42,0x10,0xc2,0x08,0x7c, +0xfc,0xff,0x0a,0x00,0x00,0x04,0x00,0x3d,0xef,0xbd,0xef,0x3d,0xf7,0xbc,0xfc, +0x00,0x04,0x00,0x00,0x04,0x7f,0xc0,0xfc,0x00,0x01,0x07,0x80,0xfd,0x00,0xfd, +0x00,0x00,0x3f,0xfc,0xff,0x00,0xfc,0xfc,0x00,0x0b,0x00,0x00,0x06,0x05,0x99, +0xc3,0x9d,0xc3,0x1d,0xc7,0x9c,0x80,0xfd,0x00,0x0a,0xff,0xff,0xf9,0xf8,0x1a, +0xdb,0x5a,0xdb,0xda,0xdf,0x58,0xfc,0xff,0x0a,0x00,0x00,0x06,0x78,0x27,0x3c, +0xe7,0x3c,0xe7,0x38,0xe4,0xfc,0x00,0x04,0x00,0x00,0x06,0xfe,0x40,0xfc,0x00, +0x01,0x03,0xf0,0xfd,0x00,0xfe,0x00,0x01,0x78,0x3f,0xfc,0xff,0x00,0xfc,0xfc, +0x00,0x0c,0x00,0x00,0x06,0x00,0x86,0x81,0x57,0x85,0x4f,0x80,0x40,0x01,0x80, +0xfe,0x00,0x0c,0xff,0xff,0xf9,0xff,0x59,0xdb,0x98,0xdf,0x98,0xda,0x9a,0xfe, +0x7f,0xfe,0xff,0x0c,0x00,0x00,0x06,0xf7,0x65,0x3c,0xa5,0x38,0xa5,0x3d,0xa6, +0xf9,0x80,0xfe,0x00,0x03,0x00,0x00,0x07,0xf8,0xfb,0x00,0x02,0x01,0xfd,0x80, +0xfe,0x00,0xfe,0x00,0x08,0xf7,0x7d,0xff,0xbd,0xff,0xbd,0xff,0xbe,0xf8,0xfd, +0x00,0x04,0x00,0x00,0x06,0x16,0x05,0xfc,0x00,0x02,0xa6,0xe8,0x80,0xfe,0x00, +0x03,0xff,0xff,0xf9,0xe0,0xfb,0x00,0x02,0x3c,0xfe,0x7f,0xfe,0xff,0x03,0x00, +0x00,0x06,0xc7,0xfb,0xff,0x02,0xc3,0xed,0x80,0xfe,0x00,0x03,0x00,0x00,0x07, +0xf8,0xfa,0x00,0x01,0x15,0x80,0xfe,0x00,0xfe,0x00,0x00,0xc7,0xfa,0xff,0x00, +0xfc,0xfd,0x00,0x0c,0x00,0x00,0x06,0x22,0x53,0x6f,0x81,0x5f,0x95,0x5e,0x81, +0x32,0x80,0xfe,0x00,0x0c,0xff,0xff,0xf9,0xcb,0xcb,0x98,0xdb,0x98,0xcf,0x99, +0xff,0x0f,0x7f,0xfe,0xff,0x0c,0x00,0x00,0x06,0xcc,0x2c,0xa5,0x3c,0xa5,0x28, +0xa5,0x00,0x05,0x80,0xfe,0x00,0x03,0x00,0x00,0x07,0xf0,0xfa,0x00,0x01,0xff, +0x80,0xfe,0x00,0xfe,0x00,0x08,0xcf,0xef,0xbd,0xff,0xbd,0xef,0xbd,0xff,0xfc, +0xfd,0x00,0x0c,0x00,0x00,0x06,0x2c,0x04,0xb9,0xc3,0x99,0xc2,0x9d,0x80,0x38, +0x80,0xfe,0x00,0x0c,0xff,0xff,0xf9,0xd7,0xdf,0x5a,0xdb,0x5a,0xda,0x5a,0xff, +0x07,0x7f,0xfe,0xff,0x0c,0x00,0x00,0x06,0x58,0x38,0xe7,0x3c,0xe7,0x3d,0xe7, +0x00,0x05,0x80,0xfe,0x00,0x03,0x00,0x00,0x06,0xe0,0xfa,0x00,0x01,0xff,0x80, +0xfe,0x00,0xfe,0x00,0x00,0x5f,0xfa,0xff,0x00,0xfc,0xfd,0x00,0x0c,0x00,0x00, +0x06,0x28,0x34,0xba,0xdb,0x5a,0xdb,0x1d,0x00,0x1a,0x80,0xfe,0x00,0x0c,0xff, +0xff,0xfb,0xef,0xf7,0x82,0x18,0x42,0x18,0x01,0xf5,0x84,0x7f,0xfe,0xff,0x0c, +0x00,0x00,0x04,0x70,0x08,0x7d,0xe7,0xbd,0xe7,0xfe,0x00,0x07,0x80,0xfe,0x00, +0x03,0x00,0x00,0x07,0xc0,0xfb,0x00,0x02,0x0a,0x7f,0x80,0xfe,0x00,0xfe,0x00, +0x00,0x7f,0xfa,0xff,0x00,0xfc,0xfd,0x00,0x0c,0x00,0x00,0x04,0x20,0x00,0x11, +0x6f,0x91,0x6f,0x90,0x00,0x38,0x80,0xfe,0x00,0x0c,0xff,0xff,0xfb,0xff,0xff, +0xcb,0x98,0xcb,0x98,0xcb,0xc0,0x07,0x7f,0xfe,0xff,0x0c,0x00,0x00,0x04,0x60, +0x00,0x2c,0xa5,0x2c,0xa5,0x2c,0x00,0x05,0x80,0xfe,0x00,0x03,0x00,0x00,0x04, +0xc0,0xfb,0x00,0x02,0x3f,0xfd,0x80,0xfe,0x00,0xfe,0x00,0x08,0x7f,0xff,0xef, +0xbd,0xef,0xbd,0xef,0xff,0xfc,0xfd,0x00,0x0c,0x00,0x00,0x06,0x28,0x00,0x32, +0xeb,0x5a,0xd4,0x3c,0x00,0x30,0x80,0xfe,0x00,0x0c,0xff,0xff,0xfb,0xef,0xff, +0xea,0x08,0x42,0x12,0xe7,0xc0,0xc6,0x7f,0xfe,0xff,0x0c,0x00,0x00,0x04,0x70, +0x00,0x1d,0xf7,0xbd,0xef,0x18,0x00,0x05,0x80,0xfe,0x00,0x03,0x00,0x00,0x06, +0xc0,0xfb,0x00,0x02,0x3f,0xff,0x80,0xfe,0x00,0xfe,0x00,0x00,0x7f,0xfa,0xff, +0x00,0xfc,0xfd,0x00,0x0c,0x00,0x00,0x06,0x20,0x00,0x1d,0x43,0x9d,0xc2,0x18, +0x01,0xda,0x80,0xfe,0x00,0x0c,0xff,0xff,0xf9,0xcb,0xff,0xfa,0x5b,0x5a,0xdb, +0xf8,0x01,0x27,0x7f,0xfe,0xff,0x0c,0x00,0x00,0x06,0xcc,0x00,0x07,0xbc,0xe7, +0x3c,0x00,0x01,0x05,0x80,0xfe,0x00,0x03,0x00,0x00,0x07,0xf0,0xfc,0x00,0x03, +0x07,0xfe,0x3f,0x80,0xfe,0x00,0xfe,0x00,0x00,0xcf,0xfa,0xff,0x00,0xfc,0xfd, +0x00,0x0c,0x00,0x00,0x06,0x30,0x00,0x0f,0x01,0x67,0x80,0x00,0x00,0xf8,0x80, +0xfe,0x00,0x0c,0xff,0xff,0xf9,0xcb,0xff,0xf8,0xdb,0x98,0xdb,0xfc,0x01,0xe7, +0x7f,0xfe,0xff,0x0c,0x00,0x00,0x06,0xcc,0x00,0x05,0x3c,0xa5,0x3c,0x00,0x00, +0xc5,0x80,0xfe,0x00,0x03,0x00,0x00,0x07,0xe0,0xfc,0x00,0x03,0x03,0xff,0x3d, +0x80,0xfe,0x00,0xfe,0x00,0x04,0xcf,0xff,0xfd,0xff,0xbd,0xfe,0xff,0x00,0x3c, +0xfd,0x00,0x0b,0x00,0x00,0x04,0x04,0x00,0x06,0x0c,0x0b,0x30,0x00,0x05,0xe0, +0xfd,0x00,0x0c,0xff,0xff,0xfb,0xe7,0xff,0xfc,0xe0,0x00,0x07,0xb0,0x04,0xf5, +0x7f,0xfe,0xff,0x0c,0x00,0x00,0x04,0x78,0x00,0x03,0x1f,0xff,0xf8,0x00,0x06, +0xcf,0x80,0xfe,0x00,0x03,0x00,0x00,0x04,0xe0,0xfc,0x00,0x03,0x4f,0xf8,0x37, +0x80,0xfe,0x00,0xfe,0x00,0x00,0x7f,0xfb,0xff,0x01,0xfd,0x34,0xfd,0x00,0x0b, +0x00,0x00,0x06,0x30,0x00,0x02,0x0f,0x81,0x70,0x00,0x08,0xf4,0xfd,0x00,0x02, +0xff,0xff,0xfb,0xfe,0xff,0x06,0xf8,0xdb,0x9f,0x00,0x09,0xfd,0x7f,0xfe,0xff, +0x0c,0x00,0x00,0x04,0x60,0x00,0x00,0x05,0x3c,0xa0,0x00,0x0f,0xff,0x80,0xfe, +0x00,0x03,0x00,0x00,0x06,0xc0,0xfc,0x00,0x03,0xff,0xf0,0x07,0x80,0xfe,0x00, +0xfe,0x00,0x07,0x7f,0xff,0xff,0xfd,0xff,0xbf,0xff,0xf8,0xfc,0x00,0x03,0x00, +0x00,0x06,0x30,0xfe,0x00,0x05,0xc5,0x80,0x00,0x00,0xd9,0xe0,0xfe,0x00,0x02, +0xff,0xff,0xfb,0xfe,0xff,0x06,0xfb,0xdf,0x5e,0x00,0x23,0xdf,0x9f,0xfe,0xff, +0x0c,0x00,0x00,0x04,0x60,0x00,0x00,0x07,0x38,0xe0,0x00,0x07,0xdc,0x60,0xfe, +0x00,0x03,0x00,0x00,0x06,0xc0,0xfd,0x00,0x04,0x01,0xff,0xd8,0x03,0xe0,0xfe, +0x00,0xfe,0x00,0x00,0x7f,0xfb,0xff,0x01,0xf8,0x20,0xfd,0x00,0x0c,0x00,0x00, +0x06,0x0c,0x00,0x00,0x05,0xe8,0xa0,0x00,0x08,0xce,0x50,0xfe,0x00,0x0c,0xff, +0xff,0xfb,0xf7,0xff,0xff,0xfc,0x0f,0xb4,0x00,0x0b,0xcb,0x9f,0xfe,0xff,0x0c, +0x00,0x00,0x04,0x78,0x00,0x00,0x03,0xf0,0x40,0x00,0x0f,0xcb,0x60,0xfe,0x00, +0x03,0x00,0x00,0x07,0xe0,0xfd,0x00,0x04,0x0b,0xff,0xf0,0x03,0xf0,0xfe,0x00, +0xfe,0x00,0x00,0x7f,0xfb,0xff,0x01,0xf8,0x35,0xfd,0x00,0x07,0x00,0x00,0x06, +0x30,0x00,0x00,0x01,0x60,0xfe,0x00,0x01,0xc7,0x10,0xfe,0x00,0x03,0xff,0xff, +0xf9,0xcb,0xfe,0xff,0x05,0x9f,0xc0,0x00,0x03,0xc5,0x8f,0xfe,0xff,0x03,0x00, +0x00,0x06,0xcc,0xfe,0x00,0x05,0xa0,0x00,0x00,0x07,0xc1,0x70,0xfe,0x00,0x03, +0x00,0x00,0x07,0xe0,0xfd,0x00,0x04,0x3f,0xff,0xf8,0x05,0xf0,0xfe,0x00,0xfe, +0x00,0x00,0xcf,0xfe,0xff,0x04,0xbf,0xff,0xff,0xf8,0x3e,0xfd,0x00,0x0b,0x00, +0x00,0x09,0x28,0x00,0x00,0x01,0xc0,0x00,0x00,0x16,0x42,0xfd,0x00,0x0c,0xff, +0xff,0xf1,0xd1,0x00,0x17,0xff,0x1f,0xe0,0x00,0x15,0xc0,0xef,0xfe,0xff,0x03, +0x00,0x00,0x0e,0x5c,0xfe,0x00,0x05,0xe0,0x00,0x00,0x1f,0xc1,0x70,0xfe,0x00, +0x0c,0x00,0x00,0x0f,0xe2,0xff,0xe8,0x00,0x00,0x1f,0xff,0xe4,0x00,0xf0,0xfe, +0x00,0xfe,0x00,0x00,0x5f,0xfb,0xff,0x01,0xf0,0x3e,0xfd,0x00,0x0b,0x00,0x00, +0x02,0xb9,0xff,0xf3,0x00,0xc0,0x00,0x08,0xcf,0xa0,0xfd,0x00,0x0c,0xff,0xff, +0xf8,0xd8,0x00,0x03,0xff,0xfc,0x00,0x08,0x23,0x61,0xef,0xfe,0xff,0x05,0x00, +0x00,0x05,0x78,0x7f,0xa0,0xfd,0x00,0x02,0x1c,0xe1,0x70,0xfe,0x00,0x0c,0x00, +0x00,0x07,0xc7,0xff,0xfc,0x00,0x03,0xff,0xf7,0xe0,0x00,0xf0,0xfe,0x00,0xfe, +0x00,0x00,0x7f,0xfb,0xff,0x01,0xe0,0x1e,0xfd,0x00,0x05,0x00,0x00,0x38,0x67, +0xff,0xfe,0xfd,0x00,0x02,0xcf,0xa1,0xb0,0xfe,0x00,0x0c,0xff,0xff,0xc7,0xe0, +0x00,0x00,0xff,0xf8,0x00,0x00,0x37,0x61,0x8f,0xfe,0xff,0x05,0x00,0x00,0x38, +0x61,0xff,0xe0,0xfd,0x00,0x02,0x18,0xe1,0xd0,0xfe,0x00,0x0c,0x00,0x00,0x3b, +0xdf,0xff,0xff,0x00,0x07,0xff,0xff,0xe0,0x00,0xf0,0xfe,0x00,0xfe,0x00,0x00, +0x3f,0xfb,0xff,0x01,0xe0,0x1e,0xfd,0x00,0x0c,0x00,0x00,0x1a,0x1f,0xff,0xfe, +0x68,0x00,0x00,0x08,0x07,0xb1,0x1c,0xfe,0x00,0x0c,0xff,0xff,0xc6,0x20,0x00, +0x00,0x1f,0xf0,0x00,0x00,0x18,0x71,0x73,0xfe,0xff,0x06,0x00,0x00,0x2b,0xc7, +0xff,0xfd,0x80,0xfe,0x00,0x02,0x3f,0xf1,0xcc,0xfe,0x00,0x0c,0x00,0x00,0x3e, +0x3f,0xff,0xff,0xe0,0x0f,0xff,0xff,0xc0,0x00,0x7c,0xfe,0x00,0xfe,0x00,0x00, +0x3f,0xfb,0xff,0x02,0xc0,0x0e,0x40,0xfe,0x00,0x0c,0x00,0x00,0x05,0xff,0xff, +0xf8,0x28,0x00,0x00,0x38,0x00,0x10,0x80,0xfe,0x00,0x0c,0xff,0xff,0xdc,0x20, +0x00,0x00,0x0f,0xe0,0x00,0x00,0x3f,0xf0,0x33,0xfe,0xff,0x06,0x00,0x00,0x36, +0x1f,0xff,0xff,0xc0,0xfe,0x00,0x02,0x1f,0xf0,0x6c,0xfe,0x00,0x0c,0x00,0x00, +0x34,0x3f,0xff,0xff,0xf0,0x1f,0xff,0xff,0xe0,0x00,0x2c,0xfe,0x00,0x02,0x00, +0x00,0x01,0xfa,0xff,0x02,0xe0,0x0f,0xa0,0xfe,0x00,0x0c,0x00,0x01,0x2f,0xff, +0xff,0xf8,0x10,0x00,0x00,0x98,0x45,0x38,0xe4,0xfe,0x00,0x0c,0xff,0xfe,0x1c, +0xc0,0x00,0x00,0x03,0xc0,0x00,0x80,0x5a,0xf8,0xbb,0xfe,0xff,0x06,0x00,0x01, +0xec,0x3f,0xff,0xff,0xe0,0xfe,0x00,0x02,0x7f,0xf8,0x28,0xfe,0x00,0x02,0x00, +0x01,0xfc,0xfe,0xff,0x06,0xfc,0x3f,0xff,0x7f,0x80,0x00,0xac,0xfe,0x00,0x02, +0x00,0x00,0x03,0xfa,0xff,0x02,0xc0,0x07,0xc0,0xfe,0x00,0x0c,0x00,0x00,0x57, +0xff,0xff,0xfe,0xc4,0x40,0x00,0x01,0x07,0x98,0x40,0xfe,0x00,0x03,0xff,0xfe, +0xb1,0x80,0xfe,0x00,0x05,0x40,0x00,0x01,0x1a,0x78,0x5f,0xfe,0xff,0x0c,0x00, +0x01,0x98,0x67,0x1f,0xff,0xf8,0x00,0x00,0x01,0xfd,0xf8,0x6c,0xfe,0x00,0x02, +0x00,0x01,0xf1,0xfd,0xff,0x05,0xbf,0xff,0xfe,0x00,0x00,0x0c,0xfe,0x00,0x02, +0x00,0x00,0x07,0xfa,0xff,0x02,0x00,0x07,0x80,0xfe,0x00,0x02,0x00,0x07,0x2f, +0xfe,0xff,0x06,0xc2,0x00,0x00,0x01,0x0f,0xb8,0x04,0xfe,0x00,0x02,0xff,0xfe, +0x63,0xfb,0x00,0x03,0x01,0x77,0x78,0x3b,0xfe,0xff,0x0c,0x00,0x01,0xb0,0xc3, +0x1f,0xff,0xfc,0x00,0x00,0x01,0xf8,0xf8,0x28,0xfe,0x00,0x02,0x00,0x07,0xa3, +0xfb,0xff,0x03,0xfe,0x00,0x00,0x1c,0xfe,0x00,0x02,0x00,0x00,0x0f,0xfa,0xff, +0x02,0x00,0x07,0xc0,0xfe,0x00,0x02,0x00,0x06,0x5f,0xfe,0xff,0x06,0xc3,0x80, +0x00,0x00,0x1f,0x98,0x37,0xfe,0x00,0x02,0xff,0xf9,0xc6,0xfb,0x00,0x03,0x01, +0xe2,0x78,0x1e,0xfe,0xff,0x06,0x00,0x06,0x61,0xe6,0xaf,0xff,0xff,0xfe,0x00, +0x02,0xfd,0xf8,0x11,0xfe,0x00,0x02,0x00,0x07,0xc7,0xfa,0xff,0x02,0x00,0x00, +0x1f,0xfe,0x00,0x02,0x00,0x00,0x1f,0xfa,0xff,0x02,0x00,0x07,0xe0,0xfe,0x00, +0x02,0x00,0x08,0xbb,0xfe,0xff,0x09,0x18,0x88,0x08,0xc3,0x3c,0x38,0x2a,0x80, +0x00,0x00,0x02,0xff,0xf1,0x8c,0xfd,0x00,0x08,0x08,0x08,0x00,0xdb,0xf8,0x2e, +0x7f,0xff,0xff,0x06,0x00,0x0e,0xc3,0x18,0xc7,0xff,0xff,0xfe,0x00,0x05,0xe7, +0xf8,0x39,0x80,0x00,0x00,0x02,0x00,0x0f,0x8f,0xfd,0xff,0x08,0xf7,0xf7,0xff, +0x00,0x00,0x0f,0x80,0x00,0x00,0x02,0x00,0x00,0x3f,0xfa,0xff,0x02,0x00,0x07, +0xc0,0xfe,0x00,0x01,0x00,0x0e,0xfd,0xff,0x06,0x18,0xc0,0x00,0xe6,0x7c,0x1c, +0x31,0xfe,0x00,0x02,0xff,0xf1,0x98,0xfb,0x00,0x06,0x01,0x9b,0xfc,0x24,0x7f, +0xff,0xff,0x0f,0x00,0x0a,0x87,0x18,0x63,0xff,0xff,0x80,0x00,0x00,0xe7,0xfc, +0x0e,0x80,0x00,0x00,0x02,0x00,0x0f,0x9f,0xfa,0xff,0x05,0x00,0x00,0x27,0x80, +0x00,0x00,0x02,0x00,0x00,0x7f,0xfa,0xff,0x02,0x00,0x03,0xf4,0xfe,0x00,0x01, +0x00,0x08,0xfd,0xff,0x06,0xa5,0x30,0x08,0x08,0xf8,0x3a,0x0c,0xfe,0x00,0x02, +0xff,0xf7,0x90,0xfb,0x00,0x06,0x04,0x27,0xfa,0x07,0x7f,0xff,0xff,0x0f,0x00, +0x0e,0x8c,0x08,0x41,0xff,0xff,0xc0,0x00,0x03,0xdf,0xfa,0x07,0x80,0x00,0x00, +0x02,0x00,0x0f,0x9f,0xfb,0xff,0x06,0xfc,0x00,0x00,0x07,0x80,0x00,0x00,0x02, +0x00,0x00,0x7f,0xfb,0xff,0x03,0xfc,0x00,0x05,0xf8,0xfe,0x00,0x02,0x00,0x0c, +0xdf,0xfe,0xff,0x09,0xc7,0x31,0x38,0x31,0xe0,0x9f,0x0c,0x80,0x00,0x00,0x02, +0xff,0xf1,0xa0,0xfd,0x00,0x08,0x01,0x00,0x0e,0xdf,0x7f,0x0d,0x7f,0xff,0xff, +0x0c,0x00,0x0a,0x98,0x00,0x00,0xff,0xff,0xe0,0x00,0x03,0x3f,0xff,0x0f,0xfe, +0x00,0x02,0x00,0x0f,0xbf,0xfd,0xff,0x08,0xfe,0xff,0xfc,0x00,0x00,0x07,0x80, +0x00,0x00,0x02,0x00,0x00,0x7f,0xfb,0xff,0x03,0xfc,0x00,0x00,0xf0,0xfe,0x00, +0x02,0x00,0x31,0x3f,0xfe,0xff,0x09,0xe2,0x04,0x98,0x19,0xf0,0x1f,0x01,0xa0, +0x00,0x00,0x02,0xff,0xcf,0x40,0xfd,0x00,0x08,0x08,0x80,0x02,0x4f,0xff,0x07, +0xdf,0xff,0xff,0x0f,0x00,0x31,0xbc,0x00,0x00,0x7f,0xff,0xf0,0x00,0x07,0xbf, +0xff,0x04,0x20,0x00,0x00,0x02,0x00,0x33,0x7f,0xfc,0xff,0x07,0x7f,0xf8,0x00, +0x00,0x03,0xa0,0x00,0x00,0x02,0x00,0x00,0x7f,0xfb,0xff,0x03,0xf8,0x00,0x00, +0xf8,0xfe,0x00,0x0f,0x00,0x06,0x7f,0xf8,0xff,0xff,0xfc,0x09,0x00,0x60,0xfc, +0x02,0x0e,0x40,0x00,0x00,0x02,0xff,0xce,0x80,0xfd,0x00,0x08,0x0d,0x00,0x03, +0x03,0xfe,0x0b,0x9f,0xff,0xff,0x0f,0x00,0x37,0x43,0x00,0x03,0x1f,0xff,0xe0, +0x00,0x07,0xff,0xfe,0x0b,0x60,0x00,0x00,0x01,0x00,0x36,0xfc,0xff,0x08,0xee, +0xff,0xf8,0x00,0x00,0x03,0x60,0x00,0x00,0x01,0x00,0x00,0xfc,0xff,0x05,0xef, +0xff,0xf8,0x00,0x01,0xf5,0xfe,0x00,0x0f,0x00,0x46,0xff,0xf8,0x7f,0xff,0xf8, +0x05,0x00,0xc8,0x3c,0x07,0x07,0x30,0x00,0x00,0x01,0xff,0xcd,0xfc,0x00,0x08, +0x05,0x00,0x0b,0xdb,0xff,0x05,0x9f,0xff,0xff,0x0f,0x00,0x34,0xe7,0x00,0x07, +0x1f,0xff,0xc0,0x00,0x0f,0xe7,0xff,0x01,0x40,0x00,0x00,0x01,0x00,0x7d,0xfc, +0xff,0x08,0xc6,0xff,0xf0,0x00,0x00,0x05,0xf0,0x00,0x00,0x01,0x00,0x03,0xfc, +0xff,0x05,0xc7,0xff,0xf8,0x00,0x00,0xfe,0xfe,0x00,0x0f,0x00,0x47,0xff,0xe0, +0x5f,0xff,0xf4,0x04,0x01,0x80,0xfc,0x0f,0x02,0x10,0x00,0x00,0x01,0xff,0xdd, +0xfa,0x00,0x06,0x13,0x3b,0xff,0x00,0xef,0xff,0xff,0x0f,0x00,0x34,0xe2,0x00, +0x02,0x7f,0xff,0xc0,0x00,0x0f,0xc7,0xff,0x01,0x70,0x00,0x00,0x01,0x00,0x7d, +0xfc,0xff,0x02,0xc7,0xff,0xf0,0xfe,0x00,0x02,0xf0,0x00,0x00,0x01,0x00,0x03, +0xfc,0xff,0x05,0xc7,0xff,0xf0,0x00,0x00,0xfe,0xfe,0x00,0x0f,0x00,0x43,0xff, +0xe0,0x1f,0xff,0xe3,0x07,0xc3,0x21,0xfc,0x1f,0xc1,0x10,0x00,0x00,0x01,0xff, +0xd9,0xfc,0x00,0x05,0x04,0x00,0x2e,0x7b,0xff,0xc0,0xfe,0xff,0x0f,0x00,0x34, +0xf8,0x00,0x00,0xff,0xff,0xc0,0x00,0x3f,0x87,0xff,0xc0,0x60,0x00,0x00,0x01, +0x00,0x79,0xfc,0xff,0x02,0xc7,0xff,0xc0,0xfe,0x00,0x02,0xf0,0x00,0x00,0x01, +0x00,0x03,0xfc,0xff,0x05,0xc7,0xff,0xe0,0x00,0x00,0x3f,0xfe,0x00,0x0f,0x00, +0x43,0xff,0xe0,0x1f,0xff,0xc7,0x03,0xc7,0x01,0xfc,0x1f,0xe1,0xf8,0x00,0x00, +0x01,0xff,0xd9,0xfa,0x00,0x06,0x1e,0xfb,0xff,0xe1,0xd7,0xff,0xff,0x0f,0x00, +0x34,0xfc,0x00,0x00,0x7f,0xff,0xe4,0x00,0x3f,0x07,0xff,0xe1,0x88,0x00,0x00, +0x01,0x00,0x79,0xfc,0xff,0x02,0xe7,0xff,0xc0,0xfe,0x00,0x02,0xf8,0x00,0x00, +0x01,0x00,0x03,0xfc,0xff,0x05,0xe7,0xff,0xc0,0x00,0x00,0x1e,0xfe,0x00,0x0f, +0x00,0x23,0xff,0xd0,0x3f,0xff,0x94,0x07,0x18,0x0f,0xfc,0x0f,0xe1,0x0c,0x00, +0x00,0x01,0xff,0xdf,0xfa,0x00,0x06,0x32,0x3b,0xff,0xe1,0x73,0xff,0xff,0x0f, +0x00,0x14,0xf2,0x00,0x03,0x5f,0xff,0xec,0x00,0x1d,0xc7,0xff,0xe1,0xcc,0x00, +0x00,0x01,0x00,0x3b,0xfc,0xff,0x02,0xef,0xff,0xe0,0xfe,0x00,0x02,0x6c,0x00, +0x00,0x01,0x00,0x03,0xfc,0xff,0x08,0xef,0xff,0xe0,0x00,0x00,0x1e,0x40,0x00, +0x00,0x0f,0x00,0x65,0x7f,0xf8,0x7f,0xff,0x18,0x03,0x38,0xcf,0x3c,0x07,0xc0, +0x80,0x00,0x00,0x01,0xff,0x99,0xfa,0x00,0x06,0x33,0xdb,0xff,0xc0,0x33,0xff, +0xff,0x0f,0x00,0x50,0xc7,0x00,0x07,0x1f,0xff,0xfe,0x00,0x1c,0xe7,0xff,0xc0, +0x6c,0x00,0x00,0x01,0x00,0x79,0xfa,0xff,0x00,0xe0,0xfe,0x00,0x02,0x3c,0x00, +0x00,0x01,0x00,0x07,0xfa,0xff,0x06,0xe0,0x00,0x00,0x3f,0xa0,0x00,0x00,0x0f, +0x00,0x46,0x7f,0xf8,0xff,0xff,0x38,0x03,0x94,0x87,0xfc,0x03,0xe0,0xe4,0x00, +0x00,0x01,0xff,0xba,0xfa,0x00,0x06,0x5c,0x1b,0xff,0xe0,0xbb,0xff,0xff,0x0f, +0x00,0x71,0xe3,0x00,0x05,0x3f,0xff,0xff,0x00,0x3b,0xe7,0xff,0xe0,0x28,0x00, +0x00,0x01,0x00,0x7b,0xfa,0xff,0x00,0xc0,0xfe,0x00,0x02,0xac,0x00,0x00,0x01, +0x00,0x07,0xfa,0xff,0x06,0xc0,0x00,0x00,0x1f,0xc0,0x00,0x00,0x01,0x00,0x04, +0xfd,0xff,0x09,0xc6,0x01,0xc2,0x03,0xfc,0x18,0xc0,0x64,0x00,0x00,0x01,0xff, +0xf8,0xfb,0x00,0x07,0x01,0xbc,0x7b,0xff,0xc0,0x5b,0xff,0xff,0x0f,0x00,0x3b, +0xf8,0x00,0x1c,0x7f,0xff,0xff,0x00,0x7f,0x87,0xff,0xc0,0x68,0x00,0x00,0x01, +0x00,0x3b,0xfa,0xff,0x00,0x80,0xfe,0x00,0x02,0x0c,0x00,0x00,0x01,0x00,0x0f, +0xfa,0xff,0x06,0x80,0x00,0x00,0x3f,0x80,0x00,0x00,0x02,0x00,0x08,0x7f,0xfe, +0xff,0x09,0xc7,0x00,0xc6,0x01,0xfc,0x38,0xe0,0x0c,0x00,0x00,0x01,0xff,0xfc, +0xfb,0x00,0x07,0x01,0xfe,0xf3,0xff,0xe0,0x13,0xff,0xff,0x04,0x00,0x3b,0xfc, +0x00,0x38,0xfe,0xff,0x07,0x00,0xff,0x0f,0xff,0xe0,0x20,0x00,0x00,0x01,0x00, +0x3f,0xfa,0xff,0xfd,0x00,0x02,0x1c,0x00,0x00,0x01,0x00,0x07,0xfa,0xff,0xfe, +0x00,0x03,0x1f,0xc0,0x00,0x00,0x01,0x00,0x40,0xfd,0xff,0x09,0xa4,0x00,0x02, +0x03,0xf8,0x15,0xd0,0x37,0x80,0x00,0x01,0xff,0xbc,0xfb,0x00,0x07,0x81,0x7c, +0xe7,0xff,0xd0,0x3e,0xff,0xff,0x0f,0x00,0x73,0xfc,0x00,0x21,0xff,0xff,0xf9, +0x00,0xff,0x1f,0xff,0xd0,0x31,0x00,0x00,0x01,0x00,0x7f,0xfc,0xff,0x01,0xf9, +0xff,0xfd,0x00,0x02,0x1f,0x80,0x00,0x01,0x00,0x07,0xfc,0xff,0x01,0xf9,0xff, +0xfe,0x00,0x03,0x2f,0xc0,0x00,0x00,0x02,0x00,0x4c,0x7f,0xfe,0xff,0x09,0x18, +0x00,0x99,0x07,0xf0,0x07,0xf8,0x2a,0x80,0x00,0x01,0xff,0xbc,0xfb,0x00,0x07, +0x01,0x7b,0xcf,0xff,0xf8,0x0e,0x7f,0xff,0x0f,0x00,0x7b,0xfe,0x18,0xc7,0xff, +0xff,0xf8,0x01,0xfc,0x3f,0xff,0xf8,0x19,0x80,0x00,0x01,0x00,0x7f,0xfc,0xff, +0x01,0xf8,0xfe,0xfd,0x00,0x02,0x0f,0x80,0x00,0x01,0x00,0x07,0xfc,0xff,0x01, +0xf9,0xff,0xfe,0x00,0x03,0x07,0xe0,0x00,0x00,0x01,0x00,0x00,0xfd,0xff,0x09, +0x18,0x00,0x19,0x0f,0xf0,0x03,0xf8,0x30,0x80,0x00,0x01,0xff,0xfc,0xfb,0x00, +0x07,0x81,0xf7,0xcf,0xff,0xf8,0x25,0x7f,0xff,0x0f,0x00,0x33,0xff,0x1c,0xe3, +0xff,0xff,0xf8,0x01,0xf8,0x3f,0xff,0xf8,0x0f,0x80,0x00,0x01,0x00,0x3f,0xfc, +0xff,0x01,0xf8,0xfe,0xfd,0x00,0x02,0x27,0x80,0x00,0x01,0x00,0x07,0xfc,0xff, +0x01,0xf8,0xff,0xfe,0x00,0x03,0x07,0xf4,0x00,0x00,0x01,0x00,0x08,0xfe,0xff, +0x0a,0xfc,0x60,0x00,0x84,0x3f,0xfc,0x21,0xf8,0x1c,0x00,0x00,0x01,0xff,0xfc, +0xfb,0x00,0x07,0x04,0xcf,0xe3,0xdf,0xf8,0x17,0x7f,0xff,0x0f,0x00,0x3b,0xff, +0xe1,0x0f,0xff,0xff,0xfd,0x07,0xf0,0x1f,0xff,0xf8,0x07,0x80,0x00,0x01,0x00, +0x3f,0xfc,0xff,0x01,0xfd,0xf8,0xfd,0x00,0x02,0x17,0x80,0x00,0x01,0x00,0x07, +0xfc,0xff,0x01,0xfd,0xfc,0xfe,0x00,0x03,0x07,0xf8,0x00,0x00,0x0f,0x00,0x40, +0x7f,0xff,0xff,0xf8,0xe0,0x00,0xc0,0x3f,0xfc,0x00,0xf8,0x1c,0x00,0x00,0x01, +0xff,0xbc,0xfb,0x00,0x07,0x03,0xdf,0xfb,0xff,0xf8,0x15,0x7f,0xff,0x04,0x00, +0x73,0xff,0xc7,0x1f,0xfe,0xff,0x07,0x07,0xe0,0x07,0xff,0xf8,0x07,0x80,0x00, +0x01,0x00,0x7f,0xfb,0xff,0x00,0xf8,0xfd,0x00,0x02,0x17,0x80,0x00,0x01,0x00, +0x07,0xfb,0xff,0x00,0xf8,0xfe,0x00,0x03,0x07,0xf8,0x00,0x00,0x0f,0x00,0x4c, +0x7f,0xff,0xff,0xf8,0xc0,0x01,0xc0,0xff,0xf8,0x01,0x7c,0x0c,0xf0,0x00,0x01, +0xff,0xb8,0xfb,0x00,0x07,0x03,0x1f,0xf7,0xff,0xfc,0x0a,0x9f,0xff,0x04,0x00, +0x7b,0xff,0xe7,0x3f,0xfe,0xff,0x07,0x07,0xe0,0x0f,0xff,0xfc,0x01,0x60,0x00, +0x01,0x00,0x7b,0xfb,0xff,0x00,0xf8,0xfd,0x00,0x02,0x0b,0xf0,0x00,0x01,0x00, +0x07,0xfb,0xff,0x00,0xf8,0xfe,0x00,0x03,0x03,0xcc,0x00,0x00,0x02,0x00,0x04, +0x3f,0xfe,0xff,0x09,0x38,0x03,0x19,0xef,0xf0,0x07,0x1f,0x06,0x10,0x00,0x01, +0xff,0xf8,0xfb,0x00,0x07,0x02,0x53,0xcf,0xff,0xff,0x07,0x9f,0xff,0x01,0x00, +0x31,0xfb,0xff,0x07,0x07,0xbc,0x3f,0xff,0xff,0x02,0x60,0x00,0x01,0x00,0x39, +0xfb,0xff,0x00,0xf8,0xfd,0x00,0x02,0x07,0x70,0x00,0x01,0x00,0x07,0xfb,0xff, +0x00,0xf8,0xfd,0x00,0x02,0xec,0x00,0x00,0x0f,0x00,0x22,0x1f,0xff,0xff,0xfe, +0x18,0x07,0x15,0xe7,0xe0,0x27,0x3f,0x05,0x10,0x00,0x01,0xff,0xda,0xfb,0x00, +0x07,0x0a,0xdb,0xdf,0xdf,0xff,0x05,0x8f,0xff,0x01,0x00,0x14,0xfc,0xff,0x08, +0xfe,0x03,0x3c,0x3f,0xff,0xff,0x03,0x70,0x00,0x01,0x00,0x3a,0xfb,0xff,0x00, +0xf8,0xfd,0x00,0x02,0x05,0xf0,0x00,0x01,0x00,0x03,0xfb,0xff,0x00,0xfc,0xfd, +0x00,0x02,0xc4,0x00,0x00,0x0f,0x00,0x62,0x1f,0xff,0xff,0xbe,0xb0,0x03,0x21, +0xff,0xf8,0x00,0x7f,0x03,0x10,0x00,0x01,0xff,0xde,0xfb,0x00,0x07,0x1e,0x07, +0xe7,0xff,0xff,0x03,0xef,0xff,0x01,0x00,0x14,0xfc,0xff,0x08,0xce,0x07,0xf8, +0x1f,0xff,0xff,0x01,0x70,0x00,0x01,0x00,0x7a,0xfc,0xff,0x01,0xcf,0xf8,0xfd, +0x00,0x02,0x03,0xf0,0x00,0x01,0x00,0x03,0xfc,0xff,0x01,0xcf,0xf8,0xfd,0x00, +0x02,0xee,0x00,0x00,0x0f,0x00,0x63,0x1f,0xff,0xff,0x18,0xc0,0x07,0xc0,0x3f, +0xfc,0x01,0xff,0x02,0x50,0x00,0x01,0xff,0xd9,0xfc,0x00,0x08,0x04,0x2f,0xdf, +0xfb,0xff,0xff,0x02,0xaf,0xff,0x02,0x00,0x14,0x7f,0xfd,0xff,0x08,0xe0,0x1f, +0xe0,0x07,0xff,0xff,0x01,0x30,0x00,0x02,0x00,0x79,0x7f,0xfd,0xff,0x01,0xe7, +0xe0,0xfd,0x00,0x02,0x02,0xf0,0x00,0x02,0x00,0x03,0x7f,0xfd,0xff,0x01,0xe7, +0xe0,0xfd,0x00,0x02,0xfe,0x00,0x00,0x0f,0x00,0x47,0x1f,0xff,0xfe,0x18,0xe0, +0x07,0xc8,0x7f,0xfc,0x00,0xff,0x01,0xf0,0x00,0x01,0xff,0x8d,0xfc,0x00,0x08, +0x04,0x17,0x9f,0xf3,0xff,0xff,0x01,0xcf,0xff,0x01,0x00,0x74,0xfc,0xff,0x08, +0xc0,0x3f,0xe0,0x0f,0xff,0xff,0x00,0x90,0x00,0x01,0x00,0x7d,0xfc,0xff,0x01, +0xc7,0xc0,0xfd,0x00,0x02,0x01,0xf0,0x00,0x01,0x00,0x03,0xfc,0xff,0x01,0xc7, +0xc0,0xfd,0x00,0x02,0xfb,0x00,0x00,0x0f,0x00,0x47,0x3c,0xff,0x3c,0x63,0x80, +0x06,0xc0,0xff,0xf8,0x03,0x38,0x01,0x3c,0x00,0x01,0xff,0xdd,0xfb,0x00,0x07, +0x3f,0x3f,0xe7,0xff,0xf8,0x01,0x73,0xff,0x01,0x00,0x34,0xfc,0xff,0x08,0xc0, +0x1f,0xc0,0x1f,0xff,0xf8,0x00,0x8c,0x00,0x01,0x00,0x7d,0xfc,0xff,0x01,0xc7, +0xe0,0xfd,0x00,0x02,0x01,0x7c,0x00,0x01,0x00,0x03,0xfc,0xff,0x01,0xc7,0xe0, +0xfe,0x00,0x03,0x07,0xf9,0x00,0x00,0x0f,0x00,0x45,0x1c,0xff,0x18,0xc7,0x00, +0x07,0xc1,0xff,0xe0,0x26,0x18,0x00,0xc2,0x00,0x01,0xff,0xcd,0xfc,0x00,0x08, +0x04,0x3e,0xff,0xdf,0xdf,0xf8,0x00,0xf3,0xff,0x01,0x00,0x36,0xfc,0xff,0x08, +0xc0,0x1f,0x00,0x3f,0xff,0xf8,0x00,0x6c,0x00,0x01,0x00,0x75,0xfc,0xff,0x01, +0xc7,0xe0,0xfc,0x00,0x01,0xee,0x00,0x01,0x00,0x01,0xfc,0xff,0x01,0xc7,0xe0, +0xfe,0x00,0x03,0x07,0xf9,0xa0,0x00,0x0f,0x00,0x22,0x80,0x7e,0x19,0xe6,0x00, +0x03,0x8f,0xff,0xf0,0x07,0x3c,0x00,0x44,0x00,0x02,0xff,0xce,0x80,0xfc,0x00, +0x07,0x50,0x7f,0x8f,0xff,0xfc,0x00,0x5b,0xff,0x02,0x00,0x33,0x7f,0xfd,0xff, +0x08,0xbe,0x3f,0x80,0x7f,0xff,0xfc,0x00,0x28,0x00,0x01,0x00,0x36,0xfc,0xff, +0x01,0xbf,0xc0,0xfc,0x00,0x01,0x5c,0x00,0x01,0x00,0x00,0xfc,0xff,0x01,0xbf, +0xc0,0xfe,0x00,0x03,0x03,0xfc,0xc0,0x00,0x0f,0x00,0x20,0x63,0x3c,0xe3,0x18, +0x00,0x38,0xef,0xbf,0xbc,0x00,0xff,0x00,0x26,0x00,0x02,0xff,0xdf,0x20,0xfd, +0x00,0x08,0x30,0x13,0x5e,0x5b,0xff,0xff,0x00,0x13,0xff,0x02,0x00,0x21,0x87, +0xfd,0xff,0x05,0x07,0x7c,0xe1,0xe7,0xff,0xff,0xfe,0x00,0x02,0x00,0x23,0x27, +0xfd,0xff,0x00,0x3f,0xfb,0x00,0x01,0x1e,0x00,0x02,0x00,0x01,0x67,0xfd,0xff, +0x01,0x3f,0x80,0xfd,0x00,0x02,0xfe,0x60,0x00,0x0f,0x00,0x0c,0x03,0x18,0xc7, +0x18,0x00,0x3d,0x87,0x3f,0x3c,0x00,0xff,0x00,0x22,0x00,0x02,0xff,0xf1,0x80, +0xfd,0x00,0x08,0x21,0x7a,0xde,0xdb,0xff,0xff,0x00,0x15,0xff,0x02,0x00,0x0a, +0xc7,0xfe,0xff,0x09,0xfe,0x06,0x7d,0xe1,0xe7,0xff,0xff,0x00,0x06,0x00,0x02, +0x00,0x0f,0x87,0xfe,0xff,0x01,0xfe,0x3f,0xfb,0x00,0x01,0x1e,0x00,0x02,0x00, +0x00,0xa7,0xfe,0xff,0x02,0xfe,0x3f,0x80,0xfd,0x00,0x02,0xff,0x20,0x00,0x0f, +0x00,0x0a,0xe1,0xaa,0xaa,0x10,0x00,0x31,0x99,0xff,0xf8,0x01,0x7d,0x80,0x62, +0x00,0x02,0xff,0xf5,0xa0,0xfd,0x00,0x08,0x2e,0x7e,0x7b,0x07,0xff,0xfd,0x80, +0x5b,0xff,0x02,0x00,0x0c,0x87,0xfe,0xff,0x09,0xfd,0x00,0x7f,0x84,0xff,0xff, +0xfd,0x80,0x0c,0x00,0x02,0x00,0x0f,0xa7,0xfe,0xff,0x03,0xfd,0x3e,0x00,0x04, +0xfd,0x00,0x01,0x5e,0x00,0x02,0x00,0x00,0x7f,0xfe,0xff,0x02,0xfd,0x7f,0x80, +0xfe,0x00,0x03,0x02,0x78,0x60,0x00,0x0f,0x00,0x08,0xf8,0xe7,0x1c,0x00,0x00, +0xf7,0x7e,0xff,0xe0,0x27,0x18,0xc0,0xe0,0x00,0x02,0xff,0xf1,0x98,0xfd,0x00, +0x08,0xe7,0x3f,0x7f,0xdf,0xdf,0xf8,0xc0,0xbb,0xff,0x02,0x00,0x0e,0x87,0xfe, +0xff,0x09,0xfc,0x0f,0xbf,0x80,0x3f,0xff,0xf8,0xc0,0x2c,0x00,0x02,0x00,0x0f, +0x9f,0xfe,0xff,0x01,0xfc,0xe7,0xfb,0x00,0x01,0xac,0x00,0x02,0x00,0x00,0x7f, +0xfe,0xff,0x02,0xfd,0xf0,0x40,0xfe,0x00,0x03,0x07,0x31,0xc0,0x00,0x0f,0x00, +0x08,0xbc,0x43,0x18,0x00,0x00,0xe9,0xbf,0x7f,0xf2,0x03,0x30,0xe1,0x94,0x00, +0x02,0xff,0xf3,0x8c,0xfd,0x00,0x08,0x8f,0x8f,0xf7,0xcd,0xff,0xf0,0xe1,0x73, +0xff,0x02,0x00,0x0c,0xc3,0xfe,0xff,0x09,0xf8,0x1a,0xcf,0x88,0x3f,0xff,0xf0, +0xc0,0x4c,0x00,0x02,0x00,0x0d,0x8f,0xfe,0xff,0x02,0xf8,0x8b,0x80,0xfd,0x00, +0x02,0x21,0x7c,0x00,0x02,0x00,0x00,0x3f,0xfe,0xff,0x02,0xfb,0xe0,0x30,0xfe, +0x00,0x03,0x0f,0x3b,0xc0,0x00,0x0f,0x00,0x0e,0x6f,0x02,0x00,0x00,0x03,0x91, +0x7f,0xb3,0xfe,0xb0,0x61,0x3e,0x18,0x00,0x02,0xff,0xf9,0xe7,0xfe,0x00,0x09, +0x03,0x1a,0xf0,0xfc,0x39,0x4f,0xe1,0x38,0xf7,0xff,0x0f,0x00,0x06,0x70,0xbf, +0xff,0xff,0xe0,0x76,0x78,0xff,0xc7,0xff,0xe0,0x01,0x88,0x00,0x08,0x00,0x0f, +0xe7,0xbf,0xff,0xff,0xe3,0x1f,0xf0,0xfe,0x00,0x03,0x01,0x38,0xd8,0x00,0x08, +0x00,0x00,0x0f,0xbf,0xff,0xff,0xe7,0x80,0x07,0xfe,0x00,0x03,0x1f,0xfe,0x80, +0x00,0x02,0x00,0x00,0xae,0xfe,0x00,0x09,0x03,0xa0,0x67,0xf8,0x3c,0x00,0xc7, +0xf0,0x00,0x00,0x02,0xff,0xfe,0x62,0xfe,0x00,0x09,0x02,0x33,0x8c,0xff,0xdb, +0xff,0xc1,0xe5,0xff,0xff,0x0f,0x00,0x01,0x30,0x1f,0xff,0xff,0xc0,0x6c,0x54, +0xff,0xe7,0xff,0xc0,0x0f,0x00,0x00,0x08,0x00,0x01,0xa2,0x1f,0xff,0xff,0xc2, +0x3c,0x7c,0xfe,0x00,0x03,0x01,0xe7,0x00,0x00,0x08,0x00,0x00,0x0f,0x1f,0xff, +0xff,0xc7,0x80,0x03,0xfe,0x00,0x03,0x3f,0xf4,0x00,0x00,0x02,0x00,0x00,0x53, +0xfe,0x00,0x09,0x06,0x40,0x4a,0x45,0x87,0xbf,0xdd,0xc4,0x20,0x00,0x02,0xff, +0xfe,0xb1,0xfe,0x00,0x09,0x04,0x6b,0x3e,0xba,0xff,0xff,0xd8,0x08,0x9f,0xff, +0x0f,0x00,0x01,0x9c,0x0a,0xff,0xfd,0x41,0xfc,0xb7,0xba,0xff,0xff,0x92,0x30, +0xe0,0x00,0x08,0x00,0x01,0xf1,0x0a,0xff,0xfd,0x44,0x7c,0xfe,0xfe,0x00,0x03, +0x48,0x0f,0xe0,0x00,0x0f,0x00,0x00,0x03,0x8a,0xff,0xfd,0x5e,0x20,0x04,0x45, +0x00,0x00,0x6d,0xc0,0x00,0x00,0x0f,0x00,0x01,0x63,0xe0,0x00,0x00,0x1e,0x94, +0xc0,0xfb,0xfc,0xe0,0xfc,0xe6,0x40,0x00,0x0f,0xff,0xfe,0x38,0x60,0x00,0x00, +0x1c,0xe3,0x0f,0xf9,0xfc,0xe0,0xf7,0xf8,0x3f,0xff,0x0f,0x00,0x01,0xcc,0x00, +0xff,0xf8,0x01,0x9c,0xf2,0xbd,0xfc,0xe0,0x47,0xe5,0xc0,0x00,0x0f,0x00,0x01, +0xe8,0x60,0xff,0xf8,0x1c,0xdc,0xf7,0xb8,0x00,0x00,0xb7,0xff,0xc0,0x00,0x0c, +0x00,0x00,0x0b,0xe0,0xff,0xf8,0x1e,0x00,0x02,0x02,0x03,0x1f,0xbb,0xfe,0x00, +0x0f,0x00,0x00,0x44,0x20,0x00,0x00,0x21,0x30,0x06,0x05,0xf9,0xe1,0xe8,0x6c, +0x00,0x00,0x0f,0xff,0xff,0xcc,0x20,0x00,0x00,0x21,0x8f,0xf8,0x3c,0xf9,0xe1, +0x8d,0x83,0xff,0xff,0x0f,0x00,0x00,0x37,0xc0,0xff,0xfc,0x1f,0x50,0x07,0xf6, +0xf9,0xe1,0x1b,0x9c,0x00,0x00,0x0f,0x00,0x00,0x74,0x20,0xff,0xfc,0x21,0xf0, +0x07,0xfc,0x00,0x00,0x8f,0xfc,0x00,0x00,0xfe,0x00,0x09,0x30,0xff,0xfc,0x20, +0x00,0x00,0x01,0x06,0x1e,0xe0,0xfe,0x00,0x0f,0x00,0x00,0x4b,0x10,0x00,0x00, +0x72,0x50,0x0b,0x8b,0x50,0x04,0x70,0x14,0x00,0x00,0x0f,0xff,0xff,0xd7,0xd0, +0x00,0x00,0x5f,0x8f,0xf0,0x7f,0x2f,0xfe,0x7f,0xe3,0xff,0xff,0x0f,0x00,0x00, +0x3b,0xe0,0x40,0x10,0x1f,0x30,0x0c,0x77,0xff,0xff,0xfb,0xec,0x00,0x00,0x0f, +0x00,0x00,0x7f,0xd0,0x40,0x10,0x5f,0xf0,0x0f,0xff,0x00,0x00,0x7b,0xfc,0x00, +0x00,0xfe,0x00,0x09,0xdb,0x40,0x15,0xed,0x00,0x00,0x04,0x00,0x00,0x08,0xfe, +0x00,0x0f,0x00,0x00,0x39,0xbf,0x80,0x0f,0xcc,0x60,0x09,0xf8,0x00,0x00,0x01, +0xf0,0x00,0x00,0xfe,0xff,0x0c,0x67,0x80,0x0f,0x93,0x9f,0xfe,0x5f,0xff,0xff, +0xfe,0x1f,0xff,0xff,0xfe,0x00,0x0c,0xa0,0x20,0x00,0x2c,0x60,0x01,0xa0,0x00, +0x00,0x01,0xe0,0x00,0x00,0x0f,0x00,0x00,0x39,0xe7,0xa0,0x0f,0x9e,0x60,0x09, +0xfb,0xff,0xff,0xf1,0xf0,0x00,0x00,0xfe,0x00,0x03,0x1f,0xe0,0x1f,0xc0,0xf8, +0x00,0x0c,0x00,0x00,0x0c,0x11,0xc0,0x3c,0x43,0x80,0x00,0x01,0x7f,0xf0,0x74, +0xfe,0x00,0x0c,0xff,0xff,0xf9,0xb0,0x40,0x30,0x7c,0x7f,0xff,0xf8,0x80,0x0f, +0x83,0xfe,0xff,0x0c,0x00,0x00,0x07,0xde,0x00,0x03,0xcd,0x80,0x00,0x06,0x80, +0x0f,0x8c,0xfe,0x00,0x0c,0x00,0x00,0x0f,0xf0,0x40,0x30,0x6f,0x80,0x00,0x07, +0xff,0xff,0xfc,0xfe,0x00,0xfe,0x00,0x02,0x01,0xff,0xfc,0xf7,0x00,0x0c,0x00, +0x00,0x04,0x43,0xdf,0xcf,0x01,0x80,0x00,0x04,0x2f,0xfe,0x0c,0xfe,0x00,0x0c, +0xff,0xff,0xf8,0x3f,0xc0,0x0f,0xf0,0x7f,0xff,0xf8,0x00,0x00,0x03,0xfe,0xff, +0x0c,0x00,0x00,0x07,0xcf,0xe0,0x3f,0xcf,0x80,0x00,0x07,0xd0,0x01,0xfc,0xfe, +0x00,0x0c,0x00,0x00,0x07,0xdf,0xc0,0x0f,0xef,0x80,0x00,0x07,0xff,0xff,0xfc, +0xfe,0x00,0xfe,0x00,0x03,0x0c,0x1f,0xc0,0xc0,0xf8,0x00,0x0c,0x00,0x00,0x01, +0x2b,0x20,0x03,0xe3,0x00,0x00,0x01,0xfd,0x11,0xf0,0xfe,0x00,0x06,0xff,0xff, +0xfe,0xf4,0xcf,0xfc,0x1d,0xfe,0xff,0x02,0xfb,0xee,0x4f,0xfe,0xff,0x06,0x00, +0x00,0x01,0x0b,0x30,0x03,0xe2,0xfe,0x00,0x02,0x04,0x11,0xb0,0xfe,0x00,0x0c, +0x00,0x00,0x01,0x2b,0x30,0x03,0xe3,0x00,0x00,0x01,0xfd,0x11,0xf0,0xfe,0x00, +0xf1,0x00,0xfe,0x00,0x03,0x28,0x00,0x01,0x90,0xf8,0x00,0xfe,0xff,0x03,0xc7, +0xe0,0x7e,0x1f,0xf8,0xff,0xfe,0x00,0x03,0x37,0xe0,0x7e,0x60,0xf8,0x00,0xfe, +0x00,0x03,0x3f,0xff,0xff,0xf0,0xf8,0x00,0xf1,0x00,0xfe,0x00,0x03,0x3e,0x20, +0xb1,0x60,0xf8,0x00,0xfe,0xff,0x03,0xc0,0x00,0x40,0x1f,0xf8,0xff,0xfe,0x00, +0x03,0x3f,0xdf,0x4f,0xe0,0xf8,0x00,0xfe,0x00,0x03,0x3f,0xff,0xff,0xe0,0xf8, +0x00,0xf1,0x00,0xfd,0x00,0x00,0x0e,0xf6,0x00,0xfd,0xff,0x00,0xf1,0xf6,0xff, +0xfd,0x00,0x00,0x0e,0xf6,0x00,0xfd,0x00,0x00,0x0e,0xf6,0x00,0xf1,0x00,0xf1, +0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00, +0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1, +0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00, +0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1, +0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00, +0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1, +0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00, +0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1, +0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00, +0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1, +0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00, +0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1, +0x00,0xf1,0xff,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0x00,0xf1,0xff,0xf1,0x00, +0xf1,0x00,0xf1,0x00, }; +#endif diff --git a/scalos/Prefs/MainPrefs/Images/icon16.c b/scalos/Prefs/MainPrefs/Images/icon16.c new file mode 100755 index 000000000..f430bccfe --- /dev/null +++ b/scalos/Prefs/MainPrefs/Images/icon16.c @@ -0,0 +1,67 @@ +#ifdef USE_ICON-16X16_COLORS +const ULONG icon-16x16_colors[96] = +{ + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, + 0x62626262,0x46464646,0x4c4c4c4c, + 0x96969696,0x9b9b9b9b,0xdadadada, + 0x9b9b9b9b,0x9f9f9f9f,0xb5b5b5b5, + 0x78787878,0x85858585,0xb7b7b7b7, + 0x4b4b4b4b,0x61616161,0x8d8d8d8d, + 0xc6c6c6c6,0xd4d4d4d4,0xefefefef, + 0xb4b4b4b4,0xbebebebe,0xd1d1d1d1, + 0xcbcbcbcb,0xdadadada,0xf2f2f2f2, + 0xc9c9c9c9,0xd6d6d6d6,0xebebebeb, + 0xcacacaca,0xd7d7d7d7,0xecececec, + 0xc6c6c6c6,0xd5d5d5d5,0xebebebeb, + 0xc8c8c8c8,0xd5d5d5d5,0xe9e9e9e9, + 0xcacacaca,0xd7d7d7d7,0xebebebeb, + 0xd1d1d1d1,0xdededede,0xf2f2f2f2, + 0xcdcdcdcd,0xdbdbdbdb,0xeeeeeeee, + 0xc8c8c8c8,0xd5d5d5d5,0xe7e7e7e7, + 0xc6c6c6c6,0xd9d9d9d9,0xf0f0f0f0, + 0xc2c2c2c2,0xd2d2d2d2,0xe4e4e4e4, + 0xcccccccc,0xdfdfdfdf,0xf3f3f3f3, + 0xcdcdcdcd,0xd4d4d4d4,0xd9d9d9d9, + 0xf4f4f4f4,0xf0f0f0f0,0x48484848, + 0xf1f1f1f1,0xeeeeeeee,0x92929292, + 0xe3e3e3e3,0xb3b3b3b3,0x35353535, + 0xcececece,0xb2b2b2b2,0x83838383, + 0xdcdcdcdc,0x7c7c7c7c,0x41414141, + 0xa6a6a6a6,0x90909090,0x87878787, + 0xbbbbbbbb,0x4a4a4a4a,0x2d2d2d2d, + 0x9b9b9b9b,0x0e0e0e0e,0x0d0d0d0d, + 0xdadadada,0x34343434,0x33333333, + 0xffffffff,0xffffffff,0xffffffff, +}; +#endif + +#define ICON-16X16_WIDTH 16 +#define ICON-16X16_HEIGHT 16 +#define ICON-16X16_DEPTH 5 +#define ICON-16X16_COMPRESSION 1 +#define ICON-16X16_MASKING 0 + +#ifdef USE_ICON-16X16_HEADER +const struct BitMapHeader icon-16x16_header = +{ 16,16,0,0,5,0,1,0,0,1,1,16,16 }; +#endif + +#ifdef USE_ICON-16X16_BODY +const UBYTE icon-16x16_body[223] = { +0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x01,0xfe,0xff,0xff,0x00, +0xff,0xff,0xff,0xff,0xff,0x00,0x01,0xfd,0xbf,0x01,0x04,0x80,0xff,0xff,0x01, +0xfa,0x7f,0x01,0x01,0x00,0x01,0xe7,0xef,0x01,0x03,0xa0,0xff,0xff,0x01,0xf8, +0x1f,0x01,0x07,0xc0,0xff,0xff,0x01,0x0f,0xf0,0x01,0xff,0xef,0x01,0xe0,0x0f, +0x01,0x1f,0xf0,0x01,0xf3,0x9f,0x01,0x3f,0xc0,0x01,0xff,0xc7,0x01,0xc0,0x3f, +0x01,0x1f,0xf0,0x01,0xb0,0x2b,0x01,0x63,0x3c,0x01,0x83,0x17,0x01,0xdc,0xe7, +0x01,0x3f,0xe8,0x01,0xe0,0x27,0x01,0x2c,0x34,0x01,0x9e,0x1f,0x01,0xff,0xc7, +0x01,0x3f,0xc0,0x01,0x82,0x65,0x01,0x1c,0x7a,0x01,0x27,0x1b,0x01,0xff,0xc3, +0x01,0x3f,0xc4,0x01,0x03,0x71,0x01,0x3c,0xe8,0x01,0xe7,0x1d,0x01,0x3f,0x81, +0x01,0xbf,0x82,0x01,0x03,0xf3,0x01,0x3c,0xef,0x01,0x7f,0x18,0x01,0x3f,0x81, +0x01,0xbf,0x82,0x01,0x5e,0x71,0x01,0xa1,0x6d,0x01,0xde,0x9b,0x01,0x9e,0x01, +0x01,0x5e,0x00,0x01,0xc0,0x90,0x01,0x5e,0x82,0x01,0x82,0x39,0x01,0xe0,0x45, +0x01,0x01,0x82,0x01,0xbe,0x61,0x01,0x73,0x4c,0x01,0xbf,0xc3,0x01,0xf3,0xa3, +0x01,0x0c,0x1c,0x01,0xf3,0xff,0x01,0x04,0x00,0x01,0xf9,0xff,0x01,0xfd,0xff, +0x01,0x02,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0x00, }; +#endif diff --git a/scalos/Prefs/MainPrefs/Images/icon24.c b/scalos/Prefs/MainPrefs/Images/icon24.c new file mode 100755 index 000000000..c7b86791f --- /dev/null +++ b/scalos/Prefs/MainPrefs/Images/icon24.c @@ -0,0 +1,87 @@ +#ifdef USE_ICON-24X24_COLORS +const ULONG icon-24x24_colors[96] = +{ + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, + 0xc8c8c8c8,0xd5d5d5d5,0xe9e9e9e9, + 0x4d4d4d4d,0x15151515,0x17171717, + 0x9c9c9c9c,0xa1a1a1a1,0xe5e5e5e5, + 0x7e7e7e7e,0x88888888,0xbdbdbdbd, + 0xc6c6c6c6,0xd3d3d3d3,0xeeeeeeee, + 0x92929292,0x98989898,0xa4a4a4a4, + 0x4d4d4d4d,0x60606060,0x82828282, + 0xc8c8c8c8,0xd6d6d6d6,0xedededed, + 0xd0d0d0d0,0xdcdcdcdc,0xefefefef, + 0xc4c4c4c4,0xcfcfcfcf,0xe1e1e1e1, + 0xc9c9c9c9,0xd6d6d6d6,0xeaeaeaea, + 0xcccccccc,0xd9d9d9d9,0xecececec, + 0xc7c7c7c7,0xd8d8d8d8,0xefefefef, + 0xcdcdcdcd,0xdcdcdcdc,0xf1f1f1f1, + 0xcfcfcfcf,0xdededede,0xf3f3f3f3, + 0xd1d1d1d1,0xe2e2e2e2,0xf7f7f7f7, + 0xa8a8a8a8,0xb4b4b4b4,0xc3c3c3c3, + 0xb9b9b9b9,0xc5c5c5c5,0xd4d4d4d4, + 0xd4d4d4d4,0xd8d8d8d8,0xdcdcdcdc, + 0xd5d5d5d5,0xd7d7d7d7,0xc5c5c5c5, + 0xf5f5f5f5,0xf2f2f2f2,0x88888888, + 0xf0f0f0f0,0xe6e6e6e6,0x16161616, + 0xe7e7e7e7,0xcccccccc,0x47474747, + 0xd0d0d0d0,0xc1c1c1c1,0xa8a8a8a8, + 0xd9d9d9d9,0x98989898,0x3f3f3f3f, + 0xd4d4d4d4,0x57575757,0x3b3b3b3b, + 0xafafafaf,0x8b8b8b8b,0x83838383, + 0x9a9a9a9a,0x13131313,0x11111111, + 0xd5d5d5d5,0x2f2f2f2f,0x2e2e2e2e, + 0xffffffff,0xffffffff,0xffffffff, +}; +#endif + +#define ICON-24X24_WIDTH 24 +#define ICON-24X24_HEIGHT 24 +#define ICON-24X24_DEPTH 5 +#define ICON-24X24_COMPRESSION 1 +#define ICON-24X24_MASKING 0 + +#ifdef USE_ICON-24X24_HEADER +const struct BitMapHeader icon-24x24_header = +{ 24,24,0,0,5,0,1,0,0,1,1,24,24 }; +#endif + +#ifdef USE_ICON-24X24_BODY +const UBYTE icon-24x24_body[516] = { +0xfd,0x00,0xfe,0xff,0x00,0x00,0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfe, +0xff,0x00,0x00,0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfe,0xff,0x00,0x00, +0xfd,0x00,0xfd,0x00,0xfd,0x00,0x03,0x00,0x40,0x00,0x00,0x03,0xff,0xb7,0xff, +0x00,0x03,0x00,0x18,0x00,0x00,0x03,0x00,0x48,0x00,0x00,0xfd,0x00,0x03,0x01, +0x70,0x00,0x00,0x03,0xfe,0xcd,0xff,0x00,0x03,0x00,0xa6,0x00,0x00,0x03,0x01, +0x52,0x00,0x00,0x03,0x00,0x30,0x00,0x00,0x03,0x01,0x86,0x00,0x00,0x03,0xfb, +0x7b,0x7f,0x00,0x03,0x06,0xfd,0x80,0x00,0x03,0x05,0x02,0x80,0x00,0x03,0x00, +0xfc,0x00,0x00,0x03,0x00,0x01,0x00,0x00,0x03,0xfd,0xfe,0xff,0x00,0x03,0x07, +0xff,0xc0,0x00,0x03,0x00,0x00,0x40,0x00,0x03,0x03,0xff,0x00,0x00,0x03,0x18, +0x00,0x40,0x00,0x03,0xef,0xfe,0x3f,0x00,0x03,0x07,0xfe,0x20,0x00,0x03,0x18, +0x01,0xe0,0x00,0x03,0x07,0xff,0xc0,0x00,0x03,0x1b,0x00,0x40,0x00,0x03,0xeb, +0xfc,0xbf,0x00,0x03,0x03,0xfc,0x20,0x00,0x03,0x1c,0x03,0xc0,0x00,0x03,0x07, +0xff,0xc0,0x00,0x03,0x1b,0xc4,0x40,0x00,0x03,0xe7,0xf4,0x3f,0x00,0x03,0x0f, +0xf4,0x40,0x00,0x03,0x18,0x0b,0x80,0x00,0x03,0x07,0xff,0x00,0x00,0x03,0x1c, +0xb0,0x90,0x00,0x03,0xdf,0xf6,0x3f,0x00,0x03,0x3b,0x31,0x90,0x00,0x03,0x37, +0xcf,0x50,0x00,0x03,0x07,0xff,0x20,0x00,0x03,0x3e,0x60,0x80,0x00,0x03,0xff, +0xaa,0x1f,0x00,0x03,0x31,0xc1,0x80,0x00,0x03,0x2f,0xfe,0x70,0x00,0x03,0x0f, +0xfe,0x00,0x00,0x03,0x79,0x30,0x88,0x00,0x03,0xbf,0xd4,0x1f,0x00,0x03,0x40, +0xe3,0x88,0x00,0x03,0x5f,0xfe,0x68,0x00,0x03,0x3f,0xfe,0x10,0x00,0x03,0x29, +0x32,0xc0,0x00,0x03,0xbf,0xdc,0x0b,0x00,0x03,0x30,0xe3,0xc4,0x00,0x03,0x1f, +0xec,0x3c,0x00,0x03,0x5f,0xec,0x00,0x00,0x03,0x4f,0x70,0x84,0x00,0x03,0x9f, +0x88,0x0f,0x00,0x03,0x30,0xf7,0x84,0x00,0x03,0x3f,0xfc,0x74,0x00,0x03,0x7f, +0xfc,0x08,0x00,0x03,0x36,0x74,0xc0,0x00,0x03,0xaf,0x88,0x03,0x00,0x03,0x39, +0xf7,0xc0,0x00,0x03,0x1f,0xf8,0x38,0x00,0x03,0x5f,0xf8,0x04,0x00,0x03,0x50, +0xf0,0xc0,0x00,0x03,0xef,0x20,0x07,0x00,0x03,0x5f,0xdf,0xc0,0x00,0x03,0x5f, +0xd8,0x32,0x00,0x03,0x3f,0xd8,0x04,0x00,0x03,0x2f,0xec,0xcc,0x00,0x03,0xe0, +0x20,0x0d,0x00,0x03,0x2f,0xdf,0xc4,0x00,0x03,0x3f,0xd0,0x30,0x00,0x03,0x0f, +0xd0,0x02,0x00,0x03,0x07,0xeb,0xd8,0x00,0x03,0xe5,0xfe,0x0f,0x00,0x03,0x12, +0x33,0xd4,0x00,0x03,0x2a,0x18,0x24,0x00,0x03,0x12,0x04,0x08,0x00,0x03,0x13, +0xe5,0xf0,0x00,0x03,0xef,0xc7,0xcf,0x00,0x03,0x13,0x9e,0x28,0x00,0x03,0x18, +0x1f,0xa8,0x00,0x03,0x04,0x60,0x50,0x00,0x03,0x02,0x40,0x00,0x00,0x03,0xf7, +0xbf,0x9f,0x00,0x03,0x0b,0x40,0x60,0x00,0x03,0x0f,0xc0,0x60,0x00,0xfd,0x00, +0xfd,0x00,0xfe,0xff,0x00,0x00,0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfe, +0xff,0x00,0x00,0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfe,0xff,0x00,0x00, +0xfd,0x00,0xfd,0x00,0xfd,0x00, }; +#endif diff --git a/scalos/Prefs/MainPrefs/Images/icon32.c b/scalos/Prefs/MainPrefs/Images/icon32.c new file mode 100755 index 000000000..ea4619d97 --- /dev/null +++ b/scalos/Prefs/MainPrefs/Images/icon32.c @@ -0,0 +1,97 @@ +#ifdef USE_ICON-32X32_COLORS +const ULONG icon-32x32_colors[96] = +{ + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, + 0xc8c8c8c8,0xd5d5d5d5,0xe9e9e9e9, + 0x78787878,0x6e6e6e6e,0x6f6f6f6f, + 0xa6a6a6a6,0xa7a7a7a7,0xeaeaeaea, + 0x8d8d8d8d,0x96969696,0xd5d5d5d5, + 0x78787878,0x84848484,0xbabababa, + 0x8d8d8d8d,0x91919191,0x9d9d9d9d, + 0x51515151,0x65656565,0x94949494, + 0xc5c5c5c5,0xd1d1d1d1,0xecececec, + 0x35353535,0x40404040,0x56565656, + 0xcbcbcbcb,0xd4d4d4d4,0xe5e5e5e5, + 0xc9c9c9c9,0xd7d7d7d7,0xedededed, + 0xcccccccc,0xd9d9d9d9,0xeeeeeeee, + 0xd2d2d2d2,0xdfdfdfdf,0xf4f4f4f4, + 0xc5c5c5c5,0xcfcfcfcf,0xdfdfdfdf, + 0xc8c8c8c8,0xd6d6d6d6,0xeaeaeaea, + 0xcfcfcfcf,0xdcdcdcdc,0xefefefef, + 0xc6c6c6c6,0xd4d4d4d4,0xe7e7e7e7, + 0xb2b2b2b2,0xbfbfbfbf,0xd0d0d0d0, + 0xc9c9c9c9,0xcececece,0xd5d5d5d5, + 0xcacacaca,0xdededede,0xf3f3f3f3, + 0xcfcfcfcf,0xe3e3e3e3,0xf8f8f8f8, + 0xf6f6f6f6,0xf2f2f2f2,0x87878787, + 0xe5e5e5e5,0xe4e4e4e4,0xbfbfbfbf, + 0xefefefef,0xe6e6e6e6,0x25252525, + 0xcfcfcfcf,0xcdcdcdcd,0xbabababa, + 0xdcdcdcdc,0xa2a2a2a2,0x44444444, + 0xd7d7d7d7,0x43434343,0x36363636, + 0xc4c4c4c4,0xb5b5b5b5,0xb4b4b4b4, + 0x9c9c9c9c,0x13131313,0x12121212, + 0xffffffff,0xffffffff,0xffffffff, +}; +#endif + +#define ICON-32X32_WIDTH 32 +#define ICON-32X32_HEIGHT 32 +#define ICON-32X32_DEPTH 5 +#define ICON-32X32_COMPRESSION 1 +#define ICON-32X32_MASKING 0 + +#ifdef USE_ICON-32X32_HEADER +const struct BitMapHeader icon-32x32_header = +{ 32,32,0,0,5,0,1,0,0,1,1,32,32 }; +#endif + +#ifdef USE_ICON-32X32_BODY +const UBYTE icon-32x32_body[674] = { +0xfd,0x00,0xfd,0xff,0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfd,0xff,0xfd, +0x00,0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfd,0xff,0xfd,0x00,0xfd,0x00,0xfd,0x00, +0xfd,0x00,0xfd,0xff,0xfd,0x00,0xfd,0x00,0xfd,0x00,0x03,0x00,0x02,0x00,0x00, +0x03,0xff,0xfc,0xff,0xff,0x03,0x00,0x01,0x00,0x00,0x03,0x00,0x03,0x00,0x00, +0xfd,0x00,0x03,0x00,0x0c,0x80,0x00,0x03,0xff,0xe0,0x3f,0xff,0x03,0x00,0x03, +0x40,0x00,0x03,0x00,0x0c,0xc0,0x00,0x03,0x00,0x13,0x00,0x00,0x03,0x00,0x23, +0x60,0x00,0x03,0xff,0x9b,0x57,0xff,0x03,0x00,0x03,0xc0,0x00,0x03,0x00,0x2c, +0x60,0x00,0x03,0x00,0x5f,0x88,0x00,0x03,0x00,0x0f,0xd8,0x00,0x03,0xfe,0xef, +0xe3,0xff,0x03,0x00,0x0f,0xc4,0x00,0x03,0x00,0x30,0x3c,0x00,0x03,0x01,0x7f, +0xe0,0x00,0x03,0x01,0xff,0xe4,0x00,0x03,0xff,0xff,0xec,0xff,0x03,0x01,0x7f, +0xe7,0x00,0x03,0x01,0x80,0x1f,0x00,0x03,0x00,0x7f,0xf8,0x00,0x03,0x00,0x7f, +0xfd,0x00,0x03,0xfc,0x7f,0xff,0x7f,0x03,0x02,0x7f,0xfd,0x00,0x03,0x01,0x80, +0x03,0x00,0x03,0x07,0xff,0xfe,0x80,0x03,0x01,0xff,0xff,0x80,0x03,0xfc,0x3f, +0xf2,0x7f,0x03,0x02,0x3f,0xf1,0x80,0x03,0x01,0xc0,0x0f,0x00,0x03,0x03,0xff, +0xff,0x80,0x03,0x05,0xff,0xff,0x80,0x03,0xf8,0x1f,0xce,0x7f,0x03,0x00,0x1f, +0xc1,0x80,0x03,0x07,0xe0,0x3d,0x00,0x03,0x03,0xff,0xfd,0x80,0x03,0x05,0xff, +0xfd,0x00,0x03,0xf8,0x06,0xbd,0xff,0x03,0x00,0x06,0x85,0x80,0x03,0x07,0xf9, +0x7a,0x80,0x03,0x03,0xff,0xf8,0x00,0x03,0x0f,0x1f,0xfc,0x40,0x03,0xf1,0x10, +0xf9,0xbf,0x03,0x0a,0xe0,0x04,0x40,0x03,0x0f,0xff,0xfb,0x40,0x03,0x03,0xff, +0xf8,0x80,0x03,0x0c,0x07,0xfc,0x80,0x03,0xec,0x1d,0xbb,0xff,0x03,0x1f,0xf8, +0x0e,0xc0,0x03,0x1b,0xff,0xf1,0x40,0x03,0x03,0xff,0xf0,0x20,0x03,0x18,0x03, +0xfc,0x60,0x03,0xc8,0x0f,0xf3,0xdf,0x03,0x1f,0xfc,0x0e,0x60,0x03,0x07,0xff, +0xf1,0xe0,0x03,0x37,0xff,0xf0,0x00,0x03,0x33,0x81,0xf4,0x00,0x03,0xd3,0x87, +0xf2,0xff,0x03,0x2c,0x7e,0x1e,0x60,0x03,0x2f,0xff,0xe1,0xa0,0x03,0x1f,0xff, +0xe0,0x00,0x03,0x33,0x80,0xf4,0x10,0x03,0xd3,0x84,0xe2,0xef,0x03,0x3c,0x7d, +0x1e,0x10,0x03,0x0f,0xfd,0xe1,0xd0,0x03,0x2f,0xfd,0xe0,0x20,0x03,0x31,0x80, +0xf4,0x20,0x03,0xd1,0x8f,0xe3,0x7f,0x03,0x2e,0x7f,0x3f,0x30,0x03,0x0f,0xff, +0xc0,0xd0,0x03,0x2f,0xff,0xc0,0x00,0x03,0x22,0x00,0xc0,0x18,0x03,0x82,0x0e, +0xe6,0x77,0x03,0x3d,0xfe,0x3e,0x18,0x03,0x1f,0xfe,0xc1,0xf8,0x03,0x7f,0xfe, +0xc0,0x00,0x03,0x10,0x00,0xe4,0x18,0x03,0xf8,0x1f,0xc3,0x37,0x03,0x2f,0xff, +0x7f,0x10,0x03,0x0f,0xff,0x80,0xe0,0x03,0x2f,0xff,0x80,0x08,0x03,0x10,0x00, +0x80,0x0c,0x03,0xf8,0x2c,0xc7,0x3b,0x03,0x3f,0xfd,0x7f,0x0c,0x03,0x2f,0xfd, +0x80,0xfc,0x03,0x0f,0xfd,0x80,0x00,0x03,0x10,0x00,0xcc,0x08,0x03,0xde,0xff, +0x83,0xef,0x03,0x2f,0xff,0xff,0x84,0x03,0x2f,0xff,0x00,0x60,0x03,0x1f,0xff, +0x00,0x04,0x03,0x10,0x03,0x26,0x08,0x03,0xef,0xfa,0x81,0x7f,0x03,0x1f,0xf9, +0xbf,0x0c,0x03,0x07,0xf9,0x40,0xf4,0x03,0x37,0xf9,0x00,0x00,0x03,0x04,0x07, +0xf0,0x70,0x03,0xee,0xe6,0x58,0x5b,0x03,0x04,0xe3,0x38,0x68,0x03,0x02,0xe2, +0x07,0x90,0x03,0x18,0xe1,0xc0,0x0c,0x03,0x03,0x18,0x7f,0xc0,0x03,0xf5,0xf1, +0x1f,0xaf,0x03,0x02,0x08,0x10,0x20,0x03,0x02,0xe8,0x10,0x20,0x03,0x0e,0x0f, +0xef,0xd0,0x03,0x02,0xf0,0x0f,0x80,0x03,0xe1,0x43,0xe0,0x7f,0x03,0x07,0x0c, +0x0e,0x00,0x03,0x05,0x4c,0x0e,0x00,0x03,0x1a,0xb0,0x71,0xa0,0x03,0x00,0x40, +0x00,0x00,0x03,0xfe,0x6f,0xff,0xff,0xfd,0x00,0x03,0x00,0x40,0x00,0x00,0x03, +0x01,0x90,0x00,0x00,0xfd,0x00,0xfd,0xff,0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfd, +0x00,0xfd,0xff,0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfd,0xff,0xfd,0x00, +0xfd,0x00,0xfd,0x00,0xfd,0x00,0xfd,0xff,0xfd,0x00,0xfd,0x00,0xfd,0x00, }; +#endif diff --git a/scalos/Prefs/MainPrefs/Images/icon48.c b/scalos/Prefs/MainPrefs/Images/icon48.c new file mode 100755 index 000000000..b4c405b9c --- /dev/null +++ b/scalos/Prefs/MainPrefs/Images/icon48.c @@ -0,0 +1,141 @@ +#ifdef USE_ICON-48X48_COLORS +const ULONG icon-48x48_colors[96] = +{ + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, + 0xc8c8c8c8,0xd5d5d5d5,0xe9e9e9e9, + 0xaaaaaaaa,0xabababab,0xeeeeeeee, + 0xd2d2d2d2,0xd2d2d2d2,0xdcdcdcdc, + 0x92929292,0x99999999,0xd9d9d9d9, + 0x7a7a7a7a,0x86868686,0xbdbdbdbd, + 0xd0d0d0d0,0xd6d6d6d6,0xe6e6e6e6, + 0x62626262,0x6e6e6e6e,0x8c8c8c8c, + 0xc4c4c4c4,0xd1d1d1d1,0xefefefef, + 0x9e9e9e9e,0xa1a1a1a1,0xa7a7a7a7, + 0xc3c3c3c3,0xcececece,0xe2e2e2e2, + 0xc2c2c2c2,0xc6c6c6c6,0xcdcdcdcd, + 0xc9c9c9c9,0xd6d6d6d6,0xebebebeb, + 0xcdcdcdcd,0xdbdbdbdb,0xf0f0f0f0, + 0xc9c9c9c9,0xd7d7d7d7,0xecececec, + 0xc7c7c7c7,0xd4d4d4d4,0xe8e8e8e8, + 0xd0d0d0d0,0xdededede,0xf2f2f2f2, + 0xcccccccc,0xd9d9d9d9,0xedededed, + 0xd3d3d3d3,0xe2e2e2e2,0xf6f6f6f6, + 0xcfcfcfcf,0xdcdcdcdc,0xeeeeeeee, + 0x2d2d2d2d,0x42424242,0x5b5b5b5b, + 0xc7c7c7c7,0xdadadada,0xf0f0f0f0, + 0xbfbfbfbf,0xd4d4d4d4,0xe7e7e7e7, + 0xf5f5f5f5,0xf0f0f0f0,0x6f6f6f6f, + 0xf9f9f9f9,0xf6f6f6f6,0xa7a7a7a7, + 0xe8e8e8e8,0xd1d1d1d1,0x2d2d2d2d, + 0xc8c8c8c8,0xc0c0c0c0,0x8a8a8a8a, + 0xd9d9d9d9,0x8d8d8d8d,0x45454545, + 0xd6d6d6d6,0x3b3b3b3b,0x32323232, + 0x8a8a8a8a,0x0c0c0c0c,0x0c0c0c0c, + 0xffffffff,0xffffffff,0xffffffff, +}; +#endif + +#define ICON-48X48_WIDTH 48 +#define ICON-48X48_HEIGHT 48 +#define ICON-48X48_DEPTH 5 +#define ICON-48X48_COMPRESSION 1 +#define ICON-48X48_MASKING 0 + +#ifdef USE_ICON-48X48_HEADER +const struct BitMapHeader icon-48x48_header = +{ 48,48,0,0,5,0,1,0,0,1,1,48,48 }; +#endif + +#ifdef USE_ICON-48X48_BODY +const UBYTE icon-48x48_body[1333] = { +0xfb,0x00,0xfb,0xff,0xfb,0x00,0xfb,0x00,0xfb,0x00,0xfb,0x00,0xfb,0xff,0xfb, +0x00,0xfb,0x00,0xfb,0x00,0xfb,0x00,0xfb,0xff,0xfb,0x00,0xfb,0x00,0xfb,0x00, +0xfb,0x00,0xfb,0xff,0xfb,0x00,0xfb,0x00,0xfb,0x00,0xfb,0x00,0xfb,0xff,0xfb, +0x00,0xfb,0x00,0xfb,0x00,0xfb,0x00,0xfb,0xff,0xfb,0x00,0xfb,0x00,0xfb,0x00, +0x02,0x00,0x00,0x06,0xfe,0x00,0x02,0xff,0xff,0xf9,0xfe,0xff,0x02,0x00,0x00, +0x06,0xfe,0x00,0x02,0x00,0x00,0x06,0xfe,0x00,0xfb,0x00,0x05,0x00,0x00,0x17, +0x80,0x00,0x00,0x05,0xff,0xff,0xfd,0x7f,0xff,0xff,0x05,0x00,0x00,0x11,0x80, +0x00,0x00,0x05,0x00,0x00,0x17,0x80,0x00,0x00,0xfb,0x00,0x05,0x00,0x00,0x7b, +0xa0,0x00,0x00,0x05,0xff,0xff,0x8a,0xdf,0xff,0xff,0x05,0x00,0x00,0x64,0x20, +0x00,0x00,0x05,0x00,0x00,0x7b,0xa0,0x00,0x00,0x02,0x00,0x00,0x02,0xfe,0x00, +0x05,0x00,0x01,0x75,0x78,0x00,0x00,0x05,0xff,0xff,0xf1,0x47,0xff,0xff,0x05, +0x00,0x01,0x08,0x98,0x00,0x00,0x05,0x00,0x01,0x77,0x78,0x00,0x00,0x02,0x00, +0x00,0x17,0xfe,0x00,0x05,0x00,0x07,0xaa,0xba,0x00,0x00,0x05,0xff,0xf8,0xa0, +0x3d,0xff,0xff,0x05,0x00,0x06,0x40,0x42,0x00,0x00,0x05,0x00,0x07,0xbf,0xba, +0x00,0x00,0x05,0x00,0x00,0x3f,0xa0,0x00,0x00,0x05,0x00,0x17,0x55,0x5f,0x80, +0x00,0x05,0xff,0xfd,0x00,0x1d,0x7f,0xff,0x05,0x00,0x10,0x80,0x09,0x80,0x00, +0x05,0x00,0x17,0x7f,0xf7,0x80,0x00,0x05,0x00,0x01,0x7f,0xf0,0x00,0x00,0x05, +0x00,0x7a,0xaa,0xab,0xa0,0x00,0x05,0xff,0x9a,0x00,0x02,0xdf,0xff,0x05,0x00, +0x64,0x00,0x04,0x20,0x00,0x05,0x00,0x7b,0xff,0xfb,0xa0,0x00,0x05,0x00,0x03, +0xff,0xfa,0x00,0x00,0x05,0x00,0x6d,0x55,0x55,0xc0,0x00,0x05,0xff,0xe8,0x00, +0x01,0xbf,0xff,0x05,0x00,0x18,0x00,0x00,0xa0,0x00,0x05,0x00,0x67,0xff,0xff, +0x40,0x00,0x05,0x00,0x07,0xff,0xff,0x20,0x00,0x05,0x00,0x1a,0xaa,0xaa,0xc8, +0x00,0x05,0xff,0x00,0x00,0x01,0x47,0xff,0x05,0x00,0x60,0x00,0x00,0x28,0x00, +0x05,0x00,0x4f,0xff,0xff,0xe8,0x00,0x05,0x00,0x8f,0xff,0xff,0xd0,0x00,0x05, +0x00,0x25,0x55,0x54,0x10,0x00,0x05,0xff,0x1a,0x00,0x03,0x9f,0xff,0x05,0x00, +0x40,0x00,0x00,0x68,0x00,0x05,0x00,0x7f,0xff,0xff,0xf0,0x00,0x05,0x00,0xbf, +0xff,0xff,0xe8,0x00,0x05,0x01,0x00,0xaa,0xa8,0x10,0x00,0x05,0xfe,0x1f,0x00, +0x17,0x9f,0xff,0x05,0x01,0x40,0x00,0x00,0x68,0x00,0x05,0x01,0x7f,0xff,0xff, +0xf0,0x00,0x05,0x00,0xbf,0xff,0xff,0xe8,0x00,0x05,0x01,0x20,0x55,0x40,0x90, +0x00,0x05,0xfe,0x1f,0xa0,0x3e,0x8b,0xff,0x05,0x01,0x40,0x00,0x01,0x28,0x00, +0x05,0x01,0x7f,0xff,0xff,0xf8,0x00,0x05,0x00,0xbf,0xff,0xff,0xa4,0x00,0x05, +0x00,0x00,0x0a,0x80,0x00,0x00,0x05,0xff,0x1f,0xf1,0x7b,0x8f,0xff,0x05,0x00, +0x40,0x00,0x04,0x90,0x00,0x05,0x00,0x7f,0xff,0xff,0x70,0x00,0x05,0x00,0xbf, +0xff,0xff,0x08,0x00,0x05,0x01,0x20,0x04,0x01,0x20,0x00,0x05,0xfc,0x9f,0xfb, +0xf5,0x8d,0xff,0x05,0x01,0x40,0x00,0x0a,0xa8,0x00,0x05,0x01,0x3f,0xff,0xff, +0x58,0x00,0x05,0x02,0xbf,0xff,0xff,0x26,0x00,0x05,0x02,0x8f,0x80,0x00,0xb8, +0x00,0x05,0xfd,0xc0,0x7f,0x89,0xcb,0xff,0x05,0x03,0x3f,0x80,0x77,0x74,0x00, +0x05,0x03,0xff,0xff,0xfe,0x08,0x00,0x05,0x00,0x3f,0xff,0xfe,0x34,0x00,0x05, +0x06,0x3f,0x80,0x12,0x94,0x00,0x05,0xf8,0x00,0x6e,0xf7,0x43,0xff,0x05,0x05, +0x3f,0xf1,0x09,0xd0,0x00,0x05,0x05,0xff,0xff,0xfe,0x28,0x00,0x05,0x02,0x3f, +0xff,0xfe,0x16,0x00,0x05,0x0c,0xff,0xe8,0x41,0x98,0x00,0x05,0xf4,0x00,0x17, +0x6a,0x41,0xff,0x05,0x0e,0xff,0xf8,0x97,0xde,0x00,0x05,0x0f,0xff,0xff,0xfc, +0x24,0x00,0x05,0x00,0xff,0xff,0xfc,0x1a,0x00,0x05,0x04,0xab,0xc4,0x03,0x18, +0x00,0x05,0xee,0x00,0x39,0x40,0xc3,0x7f,0x05,0x04,0xff,0xfe,0xbf,0xda,0x00, +0x05,0x03,0xff,0xff,0xfc,0x26,0x00,0x05,0x1c,0xff,0xff,0xfc,0x19,0x80,0x05, +0x09,0x83,0xfa,0x03,0x0e,0x00,0x05,0xf8,0x00,0x05,0xa4,0xc3,0xff,0x05,0x0d, +0xff,0xfe,0x5f,0xcc,0x00,0x05,0x0f,0xff,0xff,0xf8,0x32,0x00,0x05,0x01,0xff, +0xff,0xf8,0x0d,0x00,0x05,0x0b,0x82,0xf0,0x0b,0x0d,0x00,0x05,0xfc,0x00,0x0c, +0x4d,0xe0,0xbf,0x05,0x0b,0xff,0xfd,0xb6,0xec,0x00,0x05,0x07,0xff,0xfd,0xf8, +0x12,0x00,0x05,0x1b,0xff,0xfd,0xf8,0x0d,0xc0,0x05,0x03,0x83,0xe0,0x07,0x86, +0x00,0x05,0xf0,0x10,0x1c,0x0b,0x40,0xff,0x05,0x1b,0xef,0xfd,0xfc,0xc7,0x00, +0x05,0x1f,0xff,0xfd,0xf0,0x39,0x00,0x05,0x03,0xff,0xfd,0xf0,0x06,0x80,0x05, +0x0a,0x83,0xd1,0x07,0x06,0x00,0x05,0xdc,0x00,0x2e,0x09,0xe0,0xdf,0x05,0x1f, +0xff,0xff,0xfe,0xe6,0x80,0x05,0x17,0xff,0xff,0xf0,0x19,0x80,0x05,0x2f,0xff, +0xff,0xf0,0x06,0x60,0x05,0x1b,0xad,0xe8,0x07,0x07,0x80,0x05,0xcc,0x00,0x17, +0x5a,0xd0,0xff,0x05,0x07,0xff,0xff,0xbd,0xd7,0x00,0x05,0x0f,0xff,0xff,0xe0, +0x28,0x80,0x05,0x37,0xff,0xff,0xe0,0x07,0x40,0x05,0x0b,0xef,0xd0,0x2f,0x03, +0x40,0x05,0xdc,0x00,0x2e,0x36,0xe0,0x6f,0x05,0x17,0xff,0xfe,0xd9,0xe3,0x00, +0x05,0x0f,0xff,0xfe,0xe0,0x1c,0x80,0x05,0x37,0xff,0xfe,0xe0,0x03,0x70,0x05, +0x1b,0xf7,0xa0,0x1f,0x03,0x80,0x05,0xcc,0x00,0x5f,0x2e,0xf0,0x3f,0x05,0x0f, +0xff,0xff,0xf1,0xf3,0xe0,0x05,0x07,0xff,0xff,0xc0,0x0c,0x60,0x05,0x3f,0xff, +0xff,0xc0,0x03,0x80,0x05,0x05,0xff,0xc1,0x1f,0x01,0x20,0x05,0xda,0x00,0x3e, +0x26,0xe8,0x17,0x05,0x17,0xff,0xff,0xf9,0xe9,0x00,0x05,0x13,0xff,0xff,0xc0, +0x16,0x40,0x05,0x27,0xff,0xff,0xc0,0x01,0x38,0x05,0x01,0xfe,0x20,0x1f,0x03, +0xc0,0x05,0xfa,0x01,0xdc,0x6e,0xf0,0x0f,0x05,0x03,0xff,0xfd,0xf1,0xf3,0xf0, +0x05,0x07,0xff,0xfd,0x80,0x0c,0x00,0x05,0x13,0xff,0xfd,0x80,0x03,0xd0,0x05, +0x18,0x71,0xc1,0x7f,0x03,0x80,0x05,0xef,0x8e,0x3a,0x0e,0xf8,0x0b,0x05,0x1b, +0xff,0xfb,0xf1,0xfb,0x98,0x05,0x1f,0xff,0xfb,0x80,0x04,0x28,0x05,0x03,0xff, +0xfb,0x80,0x03,0x84,0x05,0x04,0xaa,0x04,0x3f,0x01,0xa8,0x05,0xea,0x55,0xf8, +0x5c,0xf0,0x03,0x05,0x00,0xff,0xfe,0x63,0xf1,0xa0,0x05,0x02,0xff,0xfb,0x80, +0x0e,0x00,0x05,0x1c,0xff,0xfe,0x00,0x01,0xbc,0x05,0x0c,0x14,0x08,0x0f,0xc7, +0xd8,0x05,0xfe,0xeb,0xe2,0x96,0x28,0x37,0x05,0x0c,0xff,0xe9,0x19,0xef,0xd8, +0x05,0x0f,0xff,0xe6,0xe0,0x10,0x28,0x05,0x00,0xff,0xe8,0x00,0x07,0xc0,0x05, +0x04,0x00,0x12,0x80,0x08,0x60,0x05,0xf7,0x2f,0xc7,0x75,0x00,0xff,0x05,0x06, +0x2f,0xd3,0x55,0x08,0x00,0x05,0x07,0xaf,0xcc,0x6a,0xf7,0x80,0x05,0x08,0x2f, +0xd1,0x80,0x08,0x60,0x05,0x00,0x20,0x28,0xd8,0x03,0xe0,0x05,0xfb,0x4a,0x9a, +0x2f,0x4f,0xdf,0x05,0x00,0xaa,0xa0,0xcb,0x48,0x60,0x05,0x00,0xca,0x98,0xc4, +0xb4,0x20,0x05,0x07,0x2a,0xaf,0x30,0x03,0x80,0x05,0x00,0x07,0x14,0x09,0x05, +0x80,0x05,0xfc,0xf0,0x7b,0xf7,0xe3,0x7f,0x05,0x00,0x07,0x1c,0x09,0xf9,0x80, +0x05,0x00,0x38,0xec,0x09,0x00,0x80,0x05,0x03,0xc7,0x00,0x04,0xfe,0x00,0x05, +0x00,0x37,0x90,0x07,0xf8,0x00,0x05,0xff,0xc7,0x8f,0xfa,0x27,0xff,0x05,0x00, +0x08,0x70,0x07,0xf8,0x00,0x05,0x00,0x00,0x10,0x07,0xf8,0x00,0x02,0x00,0x3f, +0xe0,0xfe,0x00,0x02,0x00,0x02,0x80,0xfe,0x00,0x01,0xff,0xfa,0xfd,0xff,0x02, +0x00,0x07,0x80,0xfe,0x00,0xfb,0x00,0x01,0x00,0x0d,0xfd,0x00,0xfb,0x00,0x01, +0xff,0xf6,0xfd,0xff,0xfb,0x00,0xfb,0x00,0x01,0x00,0x09,0xfd,0x00,0xfb,0x00, +0xfb,0xff,0xfb,0x00,0xfb,0x00,0xfb,0x00,0xfb,0x00,0xfb,0xff,0xfb,0x00,0xfb, +0x00,0xfb,0x00,0xfb,0x00,0xfb,0xff,0xfb,0x00,0xfb,0x00,0xfb,0x00,0xfb,0x00, +0xfb,0xff,0xfb,0x00,0xfb,0x00,0xfb,0x00,0xfb,0x00,0xfb,0xff,0xfb,0x00,0xfb, +0x00,0xfb,0x00,0xfb,0x00,0xfb,0xff,0xfb,0x00,0xfb,0x00,0xfb,0x00, }; +#endif diff --git a/scalos/Prefs/MainPrefs/Images/icon64.c b/scalos/Prefs/MainPrefs/Images/icon64.c new file mode 100755 index 000000000..605a9309e --- /dev/null +++ b/scalos/Prefs/MainPrefs/Images/icon64.c @@ -0,0 +1,192 @@ +#ifdef USE_ICON-64X64_COLORS +const ULONG icon-64x64_colors[96] = +{ + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, + 0xc8c8c8c8,0xd5d5d5d5,0xe9e9e9e9, + 0x66666666,0x63636363,0x64646464, + 0xacacacac,0xacacacac,0xefefefef, + 0x8b8b8b8b,0x8b8b8b8b,0x96969696, + 0x96969696,0x9c9c9c9c,0xdbdbdbdb, + 0x7b7b7b7b,0x87878787,0xc1c1c1c1, + 0x56565656,0x69696969,0x97979797, + 0xc9c9c9c9,0xcfcfcfcf,0xdcdcdcdc, + 0xc7c7c7c7,0xd6d6d6d6,0xf0f0f0f0, + 0xbfbfbfbf,0xc8c8c8c8,0xd9d9d9d9, + 0xcbcbcbcb,0xd8d8d8d8,0xedededed, + 0xd1d1d1d1,0xdfdfdfdf,0xf4f4f4f4, + 0xbdbdbdbd,0xc1c1c1c1,0xc7c7c7c7, + 0x2a2a2a2a,0x45454545,0x65656565, + 0xa3a3a3a3,0xaeaeaeae,0xbcbcbcbc, + 0xdbdbdbdb,0xe7e7e7e7,0xf6f6f6f6, + 0xefefefef,0xe8e8e8e8,0x0f0f0f0f, + 0xf2f2f2f2,0xecececec,0x46464646, + 0xf5f5f5f5,0xf0f0f0f0,0x73737373, + 0xf9f9f9f9,0xf6f6f6f6,0x9a9a9a9a, + 0xfbfbfbfb,0xf9f9f9f9,0xc4c4c4c4, + 0xe1e1e1e1,0xdededede,0xb9b9b9b9, + 0xe1e1e1e1,0xb8b8b8b8,0x42424242, + 0xd0d0d0d0,0xbfbfbfbf,0x91919191, + 0xb6b6b6b6,0x95959595,0x78787878, + 0xdcdcdcdc,0x78787878,0x3d3d3d3d, + 0x39393939,0x29292929,0x27272727, + 0x90909090,0x0b0b0b0b,0x0b0b0b0b, + 0xd8d8d8d8,0x35353535,0x32323232, + 0xffffffff,0xffffffff,0xffffffff, +}; +#endif + +#define ICON-64X64_WIDTH 64 +#define ICON-64X64_HEIGHT 64 +#define ICON-64X64_DEPTH 5 +#define ICON-64X64_COMPRESSION 1 +#define ICON-64X64_MASKING 0 + +#ifdef USE_ICON-64X64_HEADER +const struct BitMapHeader icon-64x64_header = +{ 64,64,0,0,5,0,1,0,0,1,1,64,64 }; +#endif + +#ifdef USE_ICON-64X64_BODY +const UBYTE icon-64x64_body[2096] = { +0xf9,0x00,0xf9,0xff,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0xff,0xf9, +0x00,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0xff,0xf9,0x00,0xf9,0x00,0xf9,0x00, +0xf9,0x00,0xf9,0xff,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0xff,0xf9, +0x00,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0xff,0xf9,0x00,0xf9,0x00,0xf9,0x00, +0xf9,0x00,0xf9,0xff,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0xff,0xf9, +0x00,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0xff,0xf9,0x00,0xf9,0x00,0xf9,0x00, +0xf9,0x00,0xf9,0xff,0xf9,0x00,0xfe,0x00,0x00,0x04,0xfd,0x00,0xf9,0x00,0xfe, +0x00,0x00,0x0c,0xfd,0x00,0xfe,0xff,0x01,0xfe,0x7f,0xfe,0xff,0xfe,0x00,0x01, +0x01,0x80,0xfe,0x00,0xfe,0x00,0x01,0x2f,0x80,0xfe,0x00,0xf9,0x00,0xfe,0x00, +0x01,0x1e,0x80,0xfe,0x00,0xfe,0xff,0x01,0xe1,0xdf,0xfe,0xff,0xfd,0x00,0x00, +0x20,0xfe,0x00,0xfe,0x00,0x01,0x5f,0xa0,0xfe,0x00,0xfe,0x00,0x00,0x06,0xfd, +0x00,0xfe,0x00,0x01,0x1e,0xc0,0xfe,0x00,0xfe,0xff,0x01,0xe7,0xbf,0xfe,0xff, +0xfe,0x00,0x00,0x61,0xfd,0x00,0xfe,0x00,0x01,0xf1,0xd0,0xfe,0x00,0xfe,0x00, +0x00,0x06,0xfd,0x00,0x04,0x00,0x00,0x03,0x8f,0x10,0xfe,0x00,0x04,0xff,0xff, +0xf5,0x99,0xbb,0xfe,0xff,0x04,0x00,0x00,0x08,0x36,0xe4,0xfe,0x00,0x04,0x00, +0x00,0x0f,0xc0,0x7c,0xfe,0x00,0xfe,0x00,0x01,0x7f,0x80,0xfe,0x00,0x04,0x00, +0x00,0x01,0xaf,0x2e,0xfe,0x00,0x07,0xff,0xff,0xdc,0x80,0x6c,0x7f,0xff,0xff, +0x07,0x00,0x00,0x27,0x7f,0xe1,0x80,0x00,0x00,0x07,0x00,0x00,0x37,0x00,0x1f, +0x80,0x00,0x00,0xfe,0x00,0x01,0xff,0xf0,0xfe,0x00,0x04,0x00,0x00,0x5f,0x61, +0x7d,0xfe,0x00,0x07,0xff,0xff,0x34,0x08,0x13,0xcf,0xff,0xff,0x07,0x00,0x00, +0x85,0xff,0xe0,0x30,0x00,0x00,0x07,0x00,0x01,0xd8,0x00,0x0d,0xf0,0x00,0x00, +0x04,0x00,0x00,0x0f,0xff,0xf8,0xfe,0x00,0x07,0x00,0x00,0x7f,0x0f,0x0e,0x40, +0x00,0x00,0x07,0xff,0xff,0xa9,0x99,0x99,0xbf,0xff,0xff,0x07,0x00,0x00,0x06, +0xf6,0xf5,0x80,0x00,0x00,0x07,0x00,0x00,0x70,0x00,0x01,0xe0,0x00,0x00,0x04, +0x00,0x00,0x1f,0xff,0xfe,0xfe,0x00,0x07,0x00,0x02,0x70,0xf0,0xf6,0xf0,0x00, +0x00,0x07,0xff,0xfd,0x99,0x99,0x9d,0xbf,0xff,0xff,0x04,0x00,0x01,0xaf,0x6f, +0x6b,0xfe,0x00,0x07,0x00,0x07,0x80,0x00,0x00,0x74,0x00,0x00,0x07,0x00,0x00, +0x7f,0xff,0xff,0xc0,0x00,0x00,0x07,0x00,0x0b,0xd6,0xb6,0xb4,0xb0,0x00,0x00, +0x01,0xff,0xf4,0xfe,0x00,0x02,0x2f,0xff,0xff,0x07,0x00,0x04,0x7f,0xff,0xff, +0xe0,0x00,0x00,0x01,0x00,0x0e,0xfb,0x00,0x01,0x00,0x01,0xfe,0xff,0x02,0xf0, +0x00,0x00,0x07,0x00,0x04,0x06,0x16,0x16,0x2c,0x00,0x00,0x07,0xff,0xdb,0x90, +0x80,0x80,0xf3,0x7f,0xff,0x01,0x00,0x2b,0xfe,0xff,0x02,0x92,0x80,0x00,0x01, +0x00,0x2c,0xfe,0x00,0x02,0x0f,0x80,0x00,0x01,0x00,0x03,0xfe,0xff,0x02,0xfc, +0x00,0x00,0x07,0x00,0x06,0x30,0xf0,0xf0,0x85,0x00,0x00,0x07,0xff,0xd9,0xd9, +0x99,0x99,0xf6,0xff,0xff,0x01,0x00,0x2a,0xfe,0x6f,0x02,0x01,0x00,0x00,0x01, +0x00,0x28,0xfe,0x00,0x02,0x0f,0x80,0x00,0x01,0x00,0x07,0xfe,0xff,0x02,0xfe, +0x00,0x00,0x07,0x00,0x08,0x6b,0x0f,0x05,0x05,0x00,0x00,0x07,0xff,0xfb,0xfd, +0x99,0x93,0xc6,0xff,0xff,0x07,0x00,0x04,0x06,0xf6,0xfe,0x01,0x00,0x00,0x01, +0x00,0x08,0xfe,0x00,0x02,0x3f,0x80,0x00,0x01,0x00,0x07,0xfe,0xff,0x02,0xfe, +0x00,0x00,0x07,0x00,0x04,0x07,0xeb,0x64,0x06,0x00,0x00,0x07,0xff,0xfd,0xfc, +0x00,0x0d,0x0d,0xff,0xff,0x04,0x00,0x0e,0x03,0xff,0xf2,0xfe,0x00,0x01,0x00, +0x08,0xfe,0x00,0x02,0xff,0x80,0x00,0x01,0x00,0x07,0xfe,0xff,0x02,0xfe,0x00, +0x00,0x07,0x00,0x1c,0x00,0x20,0x00,0x07,0x00,0x00,0x07,0xff,0xed,0xfd,0x89, +0x5c,0x14,0x7f,0xff,0x07,0x00,0x06,0x03,0x7f,0xe0,0x01,0x80,0x00,0x07,0x00, +0x38,0x00,0x00,0x03,0xfb,0x80,0x00,0x01,0x00,0x07,0xfe,0xff,0x02,0xf2,0x00, +0x00,0x07,0x00,0x08,0x00,0x0b,0x00,0x16,0x00,0x00,0x07,0xff,0xfb,0xff,0xdd, +0xb0,0x36,0x7f,0xff,0x07,0x00,0x04,0x00,0x36,0xc0,0x17,0x80,0x00,0x07,0x00, +0x08,0x00,0x00,0x0f,0xed,0x80,0x00,0x01,0x00,0x07,0xfe,0xff,0x02,0xe0,0x00, +0x00,0x07,0x00,0x06,0x00,0x04,0x80,0x14,0x00,0x00,0x07,0xff,0xd9,0xff,0xeb, +0x80,0x34,0xbf,0xff,0x07,0x00,0x2a,0x00,0x1c,0x00,0x14,0x40,0x00,0x07,0x00, +0x28,0x00,0x00,0x7f,0xee,0x40,0x00,0x01,0x00,0x07,0xfe,0xff,0x02,0xe1,0x00, +0x00,0x07,0x00,0x0c,0xf9,0x08,0x00,0x8f,0x40,0x00,0x07,0xff,0xc4,0xf9,0xf6, +0x80,0xdf,0x3f,0xff,0x07,0x00,0x36,0x00,0x08,0x00,0x1e,0xc0,0x00,0x07,0x00, +0x39,0xfe,0x01,0x7f,0xc6,0xc0,0x00,0x01,0x00,0x07,0xfe,0xff,0x02,0xe0,0x00, +0x00,0x07,0x00,0x06,0x03,0x80,0x00,0xcb,0x00,0x00,0x07,0xff,0xb7,0xff,0xfc, +0x00,0xbb,0xbf,0xff,0x07,0x00,0x51,0xfc,0x00,0x00,0x7b,0xc0,0x00,0x07,0x00, +0x57,0xff,0x83,0xff,0x87,0xc0,0x00,0x01,0x00,0x0f,0xfe,0xff,0x02,0x80,0x00, +0x00,0x07,0x00,0x18,0x01,0xc0,0x06,0x6b,0xa0,0x00,0x07,0xff,0x2f,0xfe,0x58, +0x06,0x3b,0x5f,0xff,0x07,0x00,0xf7,0xff,0x80,0x00,0x7b,0xe0,0x00,0x07,0x00, +0xe7,0xff,0xe7,0xff,0x87,0x60,0x00,0x01,0x00,0x07,0xfe,0xff,0x02,0x80,0x00, +0x00,0x07,0x00,0xb4,0x80,0xc0,0x00,0x49,0xa0,0x00,0x07,0xfe,0x1f,0xff,0x20, +0x00,0x79,0x9f,0xff,0x07,0x01,0xab,0x7f,0xe0,0x00,0x79,0x80,0x00,0x01,0x01, +0x8f,0xfe,0xff,0x02,0x07,0x80,0x00,0x01,0x00,0x4f,0xfe,0xff,0x02,0x80,0x60, +0x00,0x07,0x00,0x65,0x40,0x78,0x09,0x83,0xe0,0x00,0x07,0xfd,0x3f,0xff,0x88, +0x09,0xfb,0x8f,0xff,0x07,0x02,0x5a,0xbf,0xf0,0x00,0xfb,0xd0,0x00,0x01,0x02, +0x1f,0xfe,0xff,0x02,0x07,0xb0,0x00,0x01,0x00,0x9f,0xfe,0xff,0xfe,0x00,0x07, +0x02,0xcd,0x60,0xd0,0x0a,0x1b,0xd0,0x00,0x07,0xfd,0x7f,0xff,0x28,0x0b,0xfb, +0xc7,0xff,0x07,0x02,0xb2,0x9f,0xf8,0x00,0xfb,0xd8,0x00,0x01,0x03,0x3f,0xfe, +0xff,0x02,0x07,0xd8,0x00,0x01,0x00,0x3f,0xfe,0xff,0x02,0x00,0x20,0x00,0x07, +0x01,0x9f,0xf0,0x6c,0x65,0x38,0xd0,0x00,0x07,0xfd,0x7f,0xff,0x90,0x67,0x78, +0xc7,0xff,0x07,0x02,0xe0,0x0f,0xfc,0x01,0xf8,0xd8,0x00,0x07,0x03,0x7f,0xff, +0xff,0xfe,0x07,0xf8,0x00,0x04,0x00,0x7f,0xff,0xff,0xfe,0xfe,0x00,0x07,0x07, +0x6e,0xe8,0x1a,0x09,0x9e,0xe0,0x00,0x07,0xfa,0xfe,0xff,0xe2,0x0b,0xfe,0xeb, +0xff,0x07,0x05,0x90,0x17,0xf8,0x01,0xfe,0xc4,0x00,0x07,0x06,0xff,0xff,0xf9, +0xfe,0x01,0xc4,0x00,0x07,0x00,0xff,0xff,0xf9,0xfe,0x00,0x10,0x00,0x07,0x05, +0x1c,0x70,0x39,0x13,0x1c,0xe4,0x00,0x07,0xf9,0xfc,0x7f,0xc1,0x17,0xbc,0xe3, +0xff,0x07,0x04,0xe0,0x0f,0xfa,0x03,0xfc,0xec,0x00,0x07,0x04,0xff,0xff,0xfb, +0xfc,0x03,0xfc,0x00,0x04,0x02,0xff,0xff,0xfb,0xfc,0xfe,0x00,0x07,0x05,0x18, +0x70,0x6b,0xd6,0x18,0x70,0x00,0x07,0xf1,0xf8,0x7f,0x91,0xd3,0x38,0x7b,0xff, +0x07,0x0c,0xe0,0x0f,0xfe,0x07,0xf8,0x7c,0x00,0x00,0x0c,0xfe,0xff,0x03,0xf8, +0x07,0xfc,0x00,0x00,0x02,0xfe,0xff,0x00,0xf8,0xfe,0x00,0x07,0x04,0x6e,0xc8, +0x9e,0x2c,0x9e,0x7a,0x00,0x07,0xf8,0xfe,0xff,0x61,0x2a,0xbe,0x75,0xff,0x07, +0x01,0x90,0x37,0xff,0x07,0xfe,0x7e,0x00,0x00,0x01,0xfe,0xff,0x03,0xf8,0x01, +0xf6,0x00,0x00,0x07,0xfe,0xff,0x00,0xf8,0xfe,0x00,0x07,0x07,0x1f,0xb0,0x6f, +0x9f,0x19,0x7a,0x00,0x07,0xf8,0xff,0xff,0x90,0x9f,0x39,0x79,0xff,0x07,0x07, +0xe0,0x4f,0xff,0x0f,0xf9,0x78,0x00,0x00,0x05,0xfe,0xff,0x03,0xf0,0x06,0xf8, +0x00,0x00,0x01,0xfe,0xff,0x03,0xf0,0x00,0x06,0x00,0x07,0x07,0x0d,0xa0,0xdc, +0xae,0x3e,0x3e,0x00,0x07,0xf0,0xff,0xff,0x20,0xae,0x7e,0x3a,0xff,0x07,0x0b, +0xf2,0x5f,0xff,0x0f,0xfe,0x3d,0x00,0x00,0x09,0xfe,0xff,0x03,0xf0,0x01,0xfb, +0x00,0x00,0x05,0xfe,0xff,0x00,0xf0,0xfe,0x00,0x07,0x05,0x09,0x40,0xbc,0x4c, +0x3e,0x3d,0x00,0x07,0xfa,0xff,0xff,0x40,0x5c,0x7e,0x3c,0x7f,0x07,0x01,0xf6, +0xbf,0xfe,0x0f,0xfe,0x38,0x80,0x07,0x0b,0xff,0xff,0xfe,0xf0,0x01,0xf8,0x80, +0x07,0x07,0xff,0xff,0xfe,0xf0,0x00,0x03,0x00,0x07,0x07,0x86,0x81,0x7f,0x98, +0x1f,0x1b,0x00,0x07,0xf8,0x7f,0xfe,0x80,0xb8,0x3f,0x1a,0x7f,0x07,0x03,0xf9, +0x7f,0xff,0x1f,0xff,0x1d,0x80,0x00,0x01,0xfe,0xff,0x03,0xe0,0x00,0xfd,0x80, +0x00,0x05,0xfe,0xff,0x03,0xe0,0x00,0x04,0x00,0x07,0x04,0x80,0x00,0xbe,0x50, +0x3e,0x88,0x00,0x07,0xf8,0x7f,0xff,0x41,0x76,0x7e,0x88,0x3f,0x00,0x01,0xfe, +0xff,0x03,0x1f,0xfe,0x8a,0xc0,0x00,0x01,0xfe,0xff,0x03,0xe0,0x01,0x7a,0xc0, +0x00,0x07,0xfe,0xff,0x03,0xe0,0x00,0x03,0x00,0x07,0x05,0x80,0x09,0xbb,0xb8, +0x1f,0x0d,0x40,0x07,0xf1,0x7f,0xf6,0x41,0xfc,0x3f,0x0c,0x3f,0x07,0x0c,0xff, +0xff,0xfa,0x3f,0xff,0x0f,0xc0,0x07,0x0c,0xff,0xff,0xfb,0xc0,0x00,0xfe,0xc0, +0x07,0x02,0xff,0xff,0xfb,0xc0,0x00,0x02,0x00,0x07,0x05,0x80,0x0f,0x79,0xf0, +0x3f,0x1c,0x40,0x07,0xfb,0x7f,0xf0,0x81,0xb8,0x3f,0x1c,0xbf,0x07,0x06,0xff, +0xff,0xfa,0x7f,0xff,0x1f,0xc0,0x07,0x0e,0xff,0xff,0xfb,0x80,0x00,0xff,0xc0, +0x07,0x00,0xff,0xff,0xfb,0x80,0x00,0x03,0x00,0x07,0x07,0xf0,0xd4,0xfb,0xe0, +0x3e,0xbc,0xa0,0x07,0xfa,0x0f,0x2b,0x01,0xb8,0x7e,0xbc,0xdf,0x07,0x05,0xff, +0xff,0xfa,0x7f,0xfe,0xbe,0x60,0x07,0x06,0xff,0xff,0xfb,0x80,0x01,0x7e,0x60, +0x07,0x00,0xff,0xff,0xfb,0x80,0x00,0x02,0x00,0x07,0x00,0x89,0x6b,0xe5,0xc8, +0x9f,0x0f,0x20,0x07,0xff,0x16,0x94,0x06,0xe8,0xff,0x0f,0x1f,0x07,0x00,0xff, +0xff,0xf3,0xff,0xff,0x0f,0x00,0x07,0x02,0x7f,0xff,0xf3,0x00,0x00,0xff,0x00, +0x03,0x00,0x7f,0xff,0xf3,0xfe,0x00,0x00,0x60,0x07,0x02,0xd6,0x9f,0xe5,0x90, +0x3e,0x94,0xa0,0x07,0xfc,0x49,0x60,0x06,0x10,0xfe,0x94,0x9f,0x07,0x03,0xff, +0xff,0xf9,0x9f,0xfe,0x94,0x80,0x07,0x03,0x7f,0xff,0xfa,0x60,0x01,0x7c,0x80, +0x03,0x00,0x3f,0xff,0xfa,0xfe,0x00,0x00,0x60,0x07,0x00,0x7e,0xff,0x8d,0x0c, +0x0a,0xbd,0x00,0x07,0xfd,0xa1,0x00,0x02,0x0e,0x7e,0xbd,0x9f,0x07,0x02,0xdf, +0xff,0xfc,0x0f,0xfe,0xbe,0xe0,0x07,0x02,0x9f,0xff,0xf0,0x30,0x01,0x7e,0xe0, +0x07,0x00,0x1f,0xff,0xf1,0xc0,0x00,0x02,0x00,0x07,0x00,0x33,0xff,0x1e,0x51, +0xaa,0x7d,0x80,0x07,0xff,0x50,0x00,0x11,0x21,0xea,0x7a,0x7f,0x07,0x00,0xe7, +0xff,0xaa,0xf1,0xea,0x46,0x80,0x07,0x00,0xc7,0xff,0xa6,0xee,0x15,0xc2,0x80, +0x07,0x00,0x07,0xff,0xa0,0x00,0x00,0x01,0x00,0x07,0x00,0x18,0xfc,0x78,0x19, +0x17,0xcd,0x00,0x07,0xff,0x20,0x00,0x41,0x24,0x17,0xd8,0x7f,0x07,0x00,0xfc, +0xfc,0x36,0xc1,0x17,0x03,0x80,0x07,0x00,0xe4,0xfc,0x0e,0xd8,0xff,0x0f,0x80, +0x07,0x00,0x04,0xfc,0x00,0x02,0x00,0x20,0x00,0x07,0x00,0x0e,0x00,0xb0,0x1e, +0x00,0x1c,0x00,0x07,0xff,0xba,0x00,0x93,0xe0,0x40,0x61,0xff,0x07,0x00,0x57, +0x87,0x0c,0x1c,0x40,0x5e,0x00,0x07,0x00,0x5b,0x87,0x3c,0x1e,0x00,0x5e,0x00, +0x07,0x00,0x01,0x87,0x40,0x01,0xbf,0x80,0x00,0x07,0x00,0x18,0xfa,0x70,0x01, +0xff,0xc0,0x00,0x07,0xff,0xe4,0x78,0x4f,0xfc,0x00,0x1f,0xff,0x07,0x00,0x1c, +0x92,0x30,0x03,0xff,0xe0,0x00,0x07,0x00,0x1c,0x14,0x70,0x03,0xff,0xe0,0x00, +0x03,0x00,0x03,0x01,0x80,0xfd,0x00,0x03,0x00,0x02,0xff,0x80,0xfd,0x00,0x07, +0xff,0xf8,0x00,0x3f,0xff,0xe8,0x7f,0xff,0x07,0x00,0x07,0xed,0xc0,0x00,0x17, +0x80,0x00,0x07,0x00,0x07,0xed,0xc0,0x00,0x1f,0x80,0x00,0x02,0x00,0x00,0x12, +0xfc,0x00,0x02,0x00,0x00,0x78,0xfc,0x00,0x03,0xff,0xfc,0x00,0x7f,0xfd,0xff, +0x03,0x00,0x03,0xff,0x80,0xfd,0x00,0x03,0x00,0x03,0xff,0x80,0xfd,0x00,0xf9, +0x00,0xf9,0x00,0xf9,0xff,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0xff, +0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0xff,0xf9,0x00,0xf9,0x00,0xf9, +0x00,0xf9,0x00,0xf9,0xff,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0xff, +0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0xff,0xf9,0x00,0xf9,0x00,0xf9, +0x00,0xf9,0x00,0xf9,0xff,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0xff, +0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0x00,0xf9,0xff,0xf9,0x00,0xf9,0x00,0xf9, +0x00,0xf9,0x00,0xf9,0xff,0xf9,0x00,0xf9,0x00,0xf9,0x00, }; +#endif diff --git a/scalos/Prefs/MainPrefs/Images/icon96.c b/scalos/Prefs/MainPrefs/Images/icon96.c new file mode 100755 index 000000000..8d469e561 --- /dev/null +++ b/scalos/Prefs/MainPrefs/Images/icon96.c @@ -0,0 +1,334 @@ +#ifdef USE_ICON-96X96_COLORS +const ULONG icon-96x96_colors[96] = +{ + 0x00000000,0x00000000,0x00000000, + 0xffffffff,0xffffffff,0xffffffff, + 0xc8c8c8c8,0xd5d5d5d5,0xe9e9e9e9, + 0x66666666,0x60606060,0x61616161, + 0xa9a9a9a9,0xaaaaaaaa,0xedededed, + 0xe0e0e0e0,0xe0e0e0e0,0xe8e8e8e8, + 0x8c8c8c8c,0x95959595,0xd2d2d2d2, + 0x79797979,0x85858585,0xbcbcbcbc, + 0xc0c0c0c0,0xcacacaca,0xeaeaeaea, + 0xb9b9b9b9,0xbcbcbcbc,0xc5c5c5c5, + 0x4f4f4f4f,0x64646464,0x91919191, + 0x9c9c9c9c,0xa2a2a2a2,0xadadadad, + 0xcdcdcdcd,0xdadadada,0xefefefef, + 0xc2c2c2c2,0xcacacaca,0xd7d7d7d7, + 0x7e7e7e7e,0x81818181,0x86868686, + 0xc8c8c8c8,0xd6d6d6d6,0xebebebeb, + 0xc9c9c9c9,0xd8d8d8d8,0xedededed, + 0xd0d0d0d0,0xdfdfdfdf,0xf4f4f4f4, + 0x26262626,0x3e3e3e3e,0x59595959, + 0xd7d7d7d7,0xe8e8e8e8,0xfbfbfbfb, + 0xf5f5f5f5,0xf6f6f6f6,0xf3f3f3f3, + 0xf8f8f8f8,0xf4f4f4f4,0x87878787, + 0xf0f0f0f0,0xe8e8e8e8,0x24242424, + 0xfcfcfcfc,0xfafafafa,0xd1d1d1d1, + 0xd1d1d1d1,0xcacacaca,0x88888888, + 0xd4d4d4d4,0xd2d2d2d2,0xcccccccc, + 0xe1e1e1e1,0xb2b2b2b2,0x42424242, + 0xc2c2c2c2,0x8f8f8f8f,0x64646464, + 0xdbdbdbdb,0x6b6b6b6b,0x3d3d3d3d, + 0x8b8b8b8b,0x0a0a0a0a,0x0a0a0a0a, + 0xd8d8d8d8,0x32323232,0x32323232, + 0xffffffff,0xffffffff,0xffffffff, +}; +#endif + +#define ICON-96X96_WIDTH 96 +#define ICON-96X96_HEIGHT 96 +#define ICON-96X96_DEPTH 5 +#define ICON-96X96_COMPRESSION 1 +#define ICON-96X96_MASKING 0 + +#ifdef USE_ICON-96X96_HEADER +const struct BitMapHeader icon-96x96_header = +{ 96,96,0,0,5,0,1,0,0,1,1,96,96 }; +#endif + +#ifdef USE_ICON-96X96_BODY +const UBYTE icon-96x96_body[4226] = { +0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff,0xf5, +0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5,0x00, +0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff,0xf5, +0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5,0x00, +0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff,0xf5, +0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5,0x00, +0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff,0xf5, +0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5,0x00, +0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xfc,0x00,0x00,0x3c,0xfb, +0x00,0xf5,0xff,0xfc,0x00,0x00,0x3c,0xfb,0x00,0xfc,0x00,0x00,0x3c,0xfb,0x00, +0xf5,0x00,0xfc,0x00,0x00,0x3c,0xfb,0x00,0xf5,0xff,0xfc,0x00,0x00,0x3c,0xfb, +0x00,0xfc,0x00,0x00,0x3c,0xfb,0x00,0xf5,0x00,0xfd,0x00,0x02,0x02,0x36,0xc0, +0xfc,0x00,0xfd,0xff,0x01,0xfe,0x46,0xfb,0xff,0xfd,0x00,0x02,0x02,0x36,0xc0, +0xfc,0x00,0xfd,0x00,0x02,0x02,0x3e,0xc0,0xfc,0x00,0xfd,0x00,0x01,0x01,0x81, +0xfb,0x00,0xfd,0x00,0x02,0x01,0x3c,0x40,0xfc,0x00,0xfc,0xff,0x01,0x42,0x7f, +0xfc,0xff,0xfd,0x00,0x02,0x01,0x2c,0x40,0xfc,0x00,0xfd,0x00,0x02,0x01,0x3c, +0x40,0xfc,0x00,0xfc,0x00,0x01,0x81,0x80,0xfc,0x00,0xfd,0x00,0x02,0x24,0xf2, +0x44,0xfc,0x00,0xfd,0xff,0x02,0xe4,0x00,0x27,0xfc,0xff,0xfd,0x00,0x02,0x24, +0xe0,0x44,0xfc,0x00,0xfd,0x00,0x02,0x27,0xdf,0xc4,0xfc,0x00,0xfd,0x00,0x02, +0x18,0x1e,0x18,0xfc,0x00,0xfd,0x00,0x02,0x23,0x90,0xc4,0xfc,0x00,0xfd,0xff, +0x02,0xe4,0x5c,0x27,0xfc,0xff,0xfd,0x00,0x02,0x22,0x3c,0x44,0xfc,0x00,0xfd, +0x00,0x02,0x23,0x83,0xc4,0xfc,0x00,0xfd,0x00,0x02,0x18,0x3e,0x18,0xfc,0x00, +0xfe,0x00,0x04,0x02,0x24,0xfc,0xf2,0xc0,0xfd,0x00,0xfe,0xff,0x03,0xfe,0x40, +0x20,0x02,0xfc,0xff,0xfe,0x00,0x04,0x02,0x20,0x7c,0x72,0xc0,0xfd,0x00,0xfe, +0x00,0x04,0x02,0x3f,0x83,0xbe,0xc0,0xfd,0x00,0xfe,0x00,0x03,0x01,0x87,0xbf, +0x81,0xfc,0x00,0xfe,0x00,0x04,0x02,0x30,0x4c,0xbc,0x40,0xfd,0x00,0xfe,0xff, +0x04,0xfe,0x43,0x7f,0x82,0x7f,0xfd,0xff,0xfe,0x00,0x04,0x02,0x13,0xff,0xe4, +0x40,0xfd,0x00,0xfe,0x00,0x04,0x02,0x3c,0x00,0x3c,0x40,0xfd,0x00,0xfe,0x00, +0x04,0x01,0x87,0xff,0xc1,0x80,0xfd,0x00,0xfe,0x00,0x04,0x24,0xf3,0xff,0xf2, +0xc4,0xfd,0x00,0xfe,0xff,0x04,0xe4,0x04,0x00,0x40,0x27,0xfd,0xff,0xfe,0x00, +0x04,0x24,0xe3,0xff,0xe0,0xc4,0xfd,0x00,0xfe,0x00,0x04,0x27,0xdc,0x00,0x1f, +0xc4,0xfd,0x00,0xfe,0x00,0x04,0x18,0x1f,0xff,0xde,0x18,0xfd,0x00,0xfe,0x00, +0x04,0x33,0x93,0x33,0x11,0xc0,0xfd,0x00,0xfe,0xff,0x04,0xf4,0x5f,0xff,0xdc, +0x27,0xfd,0xff,0xfe,0x00,0x04,0x32,0x3f,0xff,0xfd,0xc0,0xfd,0x00,0xfe,0x00, +0x04,0x33,0x80,0x00,0x03,0xc0,0xfd,0x00,0xfe,0x00,0x04,0x08,0x3f,0xff,0xfe, +0x18,0xfd,0x00,0xfe,0x00,0x05,0x24,0xff,0xff,0xfc,0xf6,0x40,0xfe,0x00,0x08, +0xff,0xff,0xfc,0x40,0x22,0x00,0x00,0x06,0x7f,0xfe,0xff,0xfe,0x00,0x05,0x20, +0x7f,0xff,0xfc,0x36,0x40,0xfe,0x00,0xfe,0x00,0x05,0x3f,0x80,0x00,0x03,0xbe, +0x40,0xfe,0x00,0x08,0x00,0x00,0x03,0x87,0xbf,0xff,0xff,0xc1,0x80,0xfe,0x00, +0x07,0x00,0x00,0x02,0x30,0x4c,0xdd,0xc4,0x3c,0xfd,0x00,0x08,0xff,0xff,0xfe, +0x43,0x7f,0xee,0xf7,0x02,0x7f,0xfe,0xff,0x03,0x00,0x00,0x02,0x23,0xfe,0xff, +0x00,0xe4,0xfd,0x00,0x03,0x00,0x00,0x02,0x3c,0xfe,0x00,0x00,0x3c,0xfd,0x00, +0x03,0x00,0x00,0x01,0x87,0xfe,0xff,0x01,0xc1,0x80,0xfe,0x00,0x03,0x00,0x00, +0x23,0xf3,0xfe,0xff,0x01,0xf2,0xcc,0xfe,0x00,0x03,0xff,0xff,0xe4,0x04,0xfe, +0x00,0x01,0x40,0x2f,0xfe,0xff,0x03,0x00,0x00,0x23,0xe3,0xfe,0xff,0x01,0xe2, +0xcc,0xfe,0x00,0x03,0x00,0x00,0x23,0xdc,0xfe,0x00,0x01,0x1f,0xcc,0xfe,0x00, +0x03,0x00,0x00,0x18,0x1f,0xfe,0xff,0x01,0xdc,0x10,0xfe,0x00,0x03,0x00,0x00, +0x1b,0x93,0xfe,0x33,0x01,0x30,0xc8,0xfe,0x00,0x03,0xff,0xff,0xfc,0x5f,0xfe, +0xff,0x01,0xfc,0x2f,0xfe,0xff,0x03,0x00,0x00,0x1a,0x3f,0xfe,0xff,0x01,0xfc, +0x48,0xfe,0x00,0x03,0x00,0x00,0x1b,0x80,0xfe,0x00,0x01,0x03,0xc8,0xfe,0x00, +0xfe,0x00,0x00,0x3f,0xfe,0xff,0x01,0xfe,0x10,0xfe,0x00,0x02,0x00,0x00,0x9f, +0xfd,0xff,0x01,0xfc,0xc0,0xfe,0x00,0x08,0xff,0xff,0xe0,0x00,0x02,0x00,0x20, +0x00,0x2f,0xfe,0xff,0x02,0x00,0x00,0x9f,0xfd,0xff,0x01,0xfc,0x80,0xfe,0x00, +0x02,0x00,0x00,0x9c,0xfd,0x00,0x01,0x03,0x10,0xfe,0x00,0xfe,0x00,0x00,0x3f, +0xfd,0xff,0x00,0x40,0xfe,0x00,0x08,0x00,0x01,0x3d,0xcc,0x44,0x5d,0xc5,0xc4, +0x9d,0xfe,0x00,0x08,0xff,0xff,0x40,0x7f,0x77,0x6e,0xf6,0xf7,0xa3,0xfe,0xff, +0x03,0x00,0x01,0x22,0x7f,0xfd,0xff,0x00,0xcd,0xfe,0x00,0x02,0x00,0x01,0x3c, +0xfc,0x00,0x00,0x1d,0xfe,0x00,0x03,0x00,0x00,0x86,0x7f,0xfd,0xff,0x00,0xc0, +0xfe,0x00,0x02,0x00,0x01,0xf7,0xfd,0xff,0x04,0xfc,0xcb,0x80,0x00,0x00,0x03, +0xff,0xff,0x8a,0x04,0xfe,0x00,0x01,0x0b,0x08,0xfe,0xff,0x02,0x00,0x01,0xc7, +0xfc,0xff,0x03,0xc2,0x80,0x00,0x00,0x02,0x00,0x01,0xf0,0xfc,0x00,0x03,0x3e, +0x80,0x00,0x00,0x02,0x00,0x00,0x13,0xfc,0xff,0x00,0xfd,0xfe,0x00,0x03,0x00, +0x01,0x34,0x7b,0xfe,0x33,0x01,0x10,0x07,0xfe,0x00,0x03,0xff,0xff,0x47,0xb7, +0xfe,0xff,0x04,0xdf,0xf4,0x7f,0xff,0xff,0x02,0x00,0x01,0x0f,0xfc,0xff,0x00, +0xca,0xfe,0x00,0x02,0x00,0x01,0x30,0xfc,0x00,0x00,0x3e,0xfe,0x00,0x02,0x00, +0x00,0x9f,0xfc,0xff,0x03,0xfd,0x80,0x00,0x00,0x03,0x00,0x01,0x7c,0x33,0xfe, +0xff,0x01,0xf0,0x07,0xfe,0x00,0x0b,0xff,0xff,0x03,0xcd,0x00,0x00,0x02,0x2f, +0xf4,0x7f,0xff,0xff,0x02,0x00,0x01,0x6f,0xfc,0xff,0x00,0xea,0xfe,0x00,0x02, +0x00,0x01,0x70,0xfc,0x00,0x00,0x1e,0xfe,0x00,0x02,0x00,0x00,0x9f,0xfc,0xff, +0x03,0xfd,0x80,0x00,0x00,0x03,0x00,0x01,0x60,0x00,0xfe,0xdd,0x04,0xc0,0x07, +0x40,0x00,0x00,0x0b,0xff,0xff,0x4f,0xff,0x6e,0xee,0xee,0xff,0xf4,0x7f,0xff, +0xff,0x0b,0x00,0x01,0x67,0xff,0x7f,0xff,0xff,0xfc,0x08,0x40,0x00,0x00,0x02, +0x00,0x01,0x78,0xfd,0x00,0x04,0x03,0xfe,0x40,0x00,0x00,0x04,0x00,0x00,0x9f, +0xff,0x7f,0xfd,0xff,0x02,0x80,0x00,0x00,0x0b,0x00,0x01,0xb8,0x00,0xff,0xff, +0xfc,0xc0,0x36,0x40,0x00,0x00,0x0b,0xff,0xff,0x87,0xff,0x44,0x00,0x0b,0x3f, +0xf4,0x7f,0xff,0xff,0x02,0x00,0x01,0xaf,0xfd,0xff,0x04,0xf8,0x08,0x40,0x00, +0x00,0x02,0x00,0x01,0xf0,0xfd,0x00,0x04,0x07,0xfe,0x40,0x00,0x00,0x02,0x00, +0x00,0x1f,0xfb,0xff,0x02,0x80,0x00,0x00,0x08,0x00,0x01,0xb4,0x00,0x73,0x33, +0x30,0x00,0x57,0xfe,0x00,0x04,0xff,0xff,0xc7,0xff,0xbf,0xfe,0xff,0x03,0xf4, +0x7f,0xff,0xff,0x02,0x00,0x01,0x9f,0xfd,0xff,0x01,0xc0,0x0a,0xfe,0x00,0x02, +0x00,0x01,0xb0,0xfd,0x00,0x01,0x3f,0xee,0xfe,0x00,0x02,0x00,0x00,0x0f,0xfc, +0xff,0x03,0xcd,0x80,0x00,0x00,0x08,0x00,0x01,0xbc,0x00,0x33,0xff,0xf0,0x00, +0x07,0xfe,0x00,0x0b,0xff,0xff,0xcb,0xff,0xcd,0x02,0x2f,0xff,0x7d,0x7f,0xff, +0xff,0x02,0x00,0x01,0x8f,0xfd,0xff,0x01,0xc0,0x48,0xfe,0x00,0x02,0x00,0x01, +0xb0,0xfd,0x00,0x01,0x3f,0xfe,0xfe,0x00,0x02,0x00,0x00,0x1f,0xfc,0xff,0x03, +0x87,0x80,0x00,0x00,0x08,0x00,0x01,0xa0,0x00,0x00,0x44,0x40,0x00,0xc5,0xfe, +0x00,0x0b,0xff,0xff,0xcf,0xff,0xff,0x77,0x7f,0xfe,0xfd,0x7f,0xff,0xff,0x02, +0x00,0x01,0xaf,0xfe,0xff,0x02,0xfc,0x00,0x44,0xfe,0x00,0x02,0x00,0x01,0xb0, +0xfe,0x00,0x02,0x03,0xff,0xba,0xfe,0x00,0x02,0x00,0x00,0x1f,0xfc,0xff,0x03, +0x01,0x80,0x00,0x00,0x0b,0x00,0x01,0x38,0x00,0x00,0xfc,0xc0,0x01,0xc3,0x20, +0x00,0x00,0x0b,0xff,0xff,0x07,0xff,0xff,0x4b,0x3f,0xff,0xfe,0xbf,0xff,0xff, +0x02,0x00,0x01,0x2f,0xfe,0xff,0x05,0xf8,0x06,0xc1,0x20,0x00,0x00,0x02,0x00, +0x01,0x70,0xfe,0x00,0x05,0x07,0xf9,0x37,0x20,0x00,0x00,0x02,0x00,0x00,0x9f, +0xfc,0xff,0x03,0x08,0x40,0x00,0x00,0x0b,0x00,0x01,0xb4,0x00,0x00,0x40,0x00, +0x01,0xc1,0xc0,0x00,0x00,0x05,0xff,0xff,0xc7,0xff,0xff,0x8f,0xfe,0xff,0x02, +0x1f,0xff,0xff,0x02,0x00,0x01,0x9f,0xfe,0xff,0x05,0xc0,0x00,0xc2,0x80,0x00, +0x00,0x02,0x00,0x01,0xb0,0xfe,0x00,0x05,0x3f,0xff,0x33,0x80,0x00,0x00,0x02, +0x00,0x00,0x0f,0xfc,0xff,0x03,0x0c,0x60,0x00,0x00,0x0b,0x00,0x01,0xbc,0x00, +0x00,0x30,0x00,0x03,0x22,0x40,0x00,0x00,0x0b,0xff,0xff,0x0f,0xff,0xff,0xcf, +0xff,0xff,0x7f,0xdf,0xff,0xff,0x0b,0x00,0x01,0x4c,0x00,0x7f,0xff,0xc0,0x00, +0xe1,0x20,0x00,0x00,0x0b,0x00,0x01,0x73,0xff,0x80,0x00,0x3f,0xff,0x11,0x20, +0x00,0x00,0x02,0x00,0x00,0xbf,0xfd,0xff,0x04,0xfe,0x0c,0x40,0x00,0x00,0x02, +0x00,0x01,0x70,0xfd,0x00,0x04,0x06,0x00,0xc0,0x00,0x00,0x0b,0xff,0xff,0x46, +0xff,0x3f,0xff,0xff,0xf7,0x3f,0x5f,0xff,0xff,0x0b,0x00,0x01,0x61,0xff,0xdf, +0xfc,0x00,0x0b,0xe0,0xa0,0x00,0x00,0x0b,0x00,0x01,0x7f,0xff,0xe0,0x03,0xff, +0xfc,0x11,0xa0,0x00,0x00,0x02,0x00,0x00,0x9f,0xfd,0xff,0x04,0xfc,0x0e,0x40, +0x00,0x00,0x0b,0x00,0x03,0xe0,0x00,0x10,0x00,0x00,0x06,0x10,0xc8,0x00,0x00, +0x04,0xff,0xf9,0x73,0xff,0xa7,0xfd,0xff,0x02,0xaf,0xff,0xff,0x0b,0x00,0x01, +0x1f,0xff,0xfb,0xf8,0x00,0x03,0xf0,0x48,0x00,0x00,0x0b,0x00,0x01,0xff,0xff, +0xfc,0x07,0xff,0xfc,0x09,0xc8,0x00,0x00,0x02,0x00,0x06,0x0f,0xfd,0xff,0x04, +0xfc,0x06,0x10,0x00,0x00,0x0b,0x00,0x03,0x90,0x00,0x3c,0x00,0x00,0x07,0xb0, +0x70,0x00,0x00,0x0b,0xff,0xf8,0xff,0xff,0xc1,0xff,0xff,0x3f,0xff,0xc7,0xff, +0xff,0x0b,0x00,0x05,0x6f,0xff,0xff,0xf0,0x00,0xc3,0xf0,0xa0,0x00,0x00,0x0b, +0x00,0x05,0xef,0xff,0xfe,0x0f,0xff,0xfc,0x08,0xe0,0x00,0x00,0x02,0x00,0x02, +0x0f,0xfd,0xff,0x04,0xfc,0x07,0x18,0x00,0x00,0x0b,0x00,0x0b,0x60,0x00,0x3e, +0x00,0x00,0x06,0x10,0x90,0x00,0x00,0x04,0xff,0xe1,0xf7,0x7f,0xc0,0xfd,0xff, +0x02,0xf7,0xff,0xff,0x0b,0x00,0x02,0x9f,0xff,0xff,0x70,0x00,0x03,0xf0,0x48, +0x00,0x00,0x0b,0x00,0x03,0x9f,0xff,0xff,0x8f,0xff,0xfc,0x0c,0x48,0x00,0x00, +0x02,0x00,0x1c,0x1f,0xfd,0xff,0x04,0xf8,0x03,0x10,0x00,0x00,0x0b,0x00,0x0e, +0xc0,0x00,0x03,0x00,0x00,0x0e,0x10,0x30,0x00,0x00,0x0b,0xff,0xe3,0xf3,0x3f, +0xfc,0x3f,0xff,0xef,0x3f,0xd7,0xff,0xff,0x0b,0x00,0x05,0x3f,0xff,0xff,0xc0, +0x00,0x0f,0xf0,0x28,0x00,0x00,0x02,0x00,0x07,0x3f,0xfd,0xff,0x04,0xf0,0x0c, +0x68,0x00,0x00,0x02,0x00,0x18,0x3f,0xfd,0xff,0x04,0xf0,0x03,0x90,0x00,0x00, +0x0b,0x00,0x4d,0x80,0x00,0x07,0x80,0x00,0x1c,0x10,0x36,0x00,0x00,0x0b,0xff, +0xd7,0xd0,0x1f,0xf8,0x1f,0xff,0xfe,0x7f,0xef,0xff,0xff,0x0b,0x00,0x42,0x7f, +0xff,0xff,0xe0,0x00,0x0f,0xf0,0x16,0x00,0x00,0x02,0x00,0x4e,0x7f,0xfd,0xff, +0x04,0xf0,0x0c,0x76,0x00,0x00,0x02,0x00,0x20,0x7f,0xfd,0xff,0x04,0xf0,0x03, +0x80,0x00,0x00,0x0b,0x00,0x3b,0x00,0x00,0x0c,0xc0,0x00,0x08,0x70,0x1c,0x00, +0x00,0x0b,0xff,0x8f,0xcc,0xcf,0xf3,0x1f,0xfc,0xcc,0xff,0xe1,0xff,0xff,0x01, +0x00,0x54,0xfe,0xff,0x06,0xe0,0x03,0x3f,0xf0,0x28,0x00,0x00,0x01,0x00,0x5c, +0xfc,0xff,0x04,0xf0,0x0c,0x38,0x00,0x00,0x01,0x00,0x20,0xfc,0xff,0x04,0xf0, +0x03,0xc6,0x00,0x00,0x0b,0x00,0x2a,0x00,0x00,0x0d,0x60,0x00,0x30,0xf0,0x04, +0x00,0x00,0x0b,0xff,0xaf,0x80,0x87,0xf2,0x9f,0xff,0xb9,0xff,0xf5,0xff,0xff, +0x01,0x00,0x45,0xfe,0xff,0x06,0xf0,0x00,0x4f,0xf0,0x12,0x00,0x00,0x01,0x00, +0x5d,0xfc,0xff,0x04,0xf0,0x0e,0x1a,0x00,0x00,0x01,0x00,0x21,0xfc,0xff,0x04, +0xe0,0x01,0xe4,0x00,0x00,0x0b,0x00,0x38,0x00,0x00,0x03,0x30,0x00,0x63,0xd0, +0x0c,0x00,0x00,0x0b,0xff,0x8f,0x00,0x03,0xfc,0xc7,0xcf,0x73,0xff,0xf5,0xff, +0xff,0x01,0x00,0x17,0xfe,0xff,0x06,0xf8,0x30,0xbf,0xf0,0x0a,0x00,0x00,0x01, +0x00,0x1f,0xfc,0xff,0x04,0xc0,0x0f,0x1a,0x00,0x00,0x01,0x00,0x63,0xfc,0xff, +0x04,0xc0,0x00,0xe4,0x00,0x00,0x0b,0x01,0x38,0x00,0x00,0x01,0x7c,0x00,0x60, +0xf8,0x0c,0x80,0x00,0x0b,0xff,0x5c,0x03,0x00,0xfe,0x87,0xfe,0xff,0xff,0xfa, +0xff,0xff,0x0b,0x01,0x07,0xfc,0xff,0xff,0xf9,0x01,0x3f,0xf8,0x04,0x80,0x00, +0x01,0x01,0x3f,0xfe,0xff,0x06,0xfa,0xff,0xc0,0x07,0x1c,0x80,0x00,0x01,0x00, +0x8f,0xfe,0xff,0x06,0xfb,0xff,0xc0,0x00,0xe1,0x00,0x00,0x01,0x00,0xe0,0xfe, +0x00,0x06,0xf3,0x00,0x38,0x74,0x07,0x00,0x00,0x0b,0xfe,0x3c,0xc3,0x8c,0xff, +0x02,0xfc,0xfc,0xff,0xfc,0x7f,0xff,0x0b,0x01,0x5f,0xfc,0x7f,0xff,0xf1,0x03, +0x3f,0xfc,0x0a,0x00,0x00,0x01,0x01,0x7f,0xfe,0xff,0x06,0xf2,0xff,0xc0,0x03, +0x0e,0x00,0x00,0x01,0x00,0x8f,0xfe,0xff,0x06,0xf3,0xff,0xc0,0x00,0xf1,0x80, +0x00,0x01,0x00,0x90,0xfe,0x00,0x06,0xe0,0x00,0xf0,0x7c,0x09,0x00,0x00,0x0b, +0xfe,0x3e,0x0f,0xc0,0xff,0x01,0xfb,0xf8,0xff,0xff,0x7f,0xff,0x0b,0x01,0x2f, +0xf0,0x3f,0xff,0xe2,0x04,0x3f,0xfc,0x04,0x80,0x00,0x01,0x01,0x6f,0xfe,0xff, +0x06,0xe3,0xff,0xc0,0x03,0x84,0x80,0x00,0x01,0x00,0x8f,0xfe,0xff,0x06,0xe3, +0xff,0x80,0x00,0x71,0x00,0x00,0x0b,0x00,0xd0,0x00,0x00,0x03,0x30,0x01,0xe0, +0xd0,0x03,0x00,0x00,0x0b,0xfe,0xbf,0x0f,0xc3,0xfc,0xc4,0x33,0xf0,0xff,0xfd, +0x7f,0xff,0x0b,0x01,0x2f,0xf0,0x3f,0xff,0xf3,0xcc,0x7f,0xf0,0x02,0x80,0x00, +0x01,0x01,0x6f,0xfe,0xff,0x06,0xf3,0xff,0x80,0x0f,0xc6,0x80,0x00,0x01,0x00, +0x8f,0xfe,0xff,0x06,0xf7,0xff,0x00,0x00,0x39,0x00,0x00,0x0b,0x00,0xd0,0x00, +0x00,0x06,0xb4,0x11,0x80,0x78,0x03,0x20,0x00,0x0b,0xfe,0xbe,0x8f,0xc5,0xf9, +0x42,0xff,0xe8,0xff,0xfe,0xff,0xff,0x0b,0x01,0x4f,0xf0,0x3f,0xff,0xf7,0x00, +0xff,0xf8,0x01,0x20,0x00,0x01,0x01,0x6f,0xfe,0xff,0x06,0xf7,0xff,0x00,0x07, +0xc7,0x20,0x00,0x01,0x00,0x8f,0xfe,0xff,0x06,0xf7,0xff,0x00,0x00,0x38,0x00, +0x00,0x0b,0x00,0xe0,0x00,0x00,0x0c,0xfc,0x01,0x88,0x7c,0x01,0xe0,0x00,0x0b, +0xfe,0xbc,0xc3,0x0c,0xf3,0x02,0xcd,0xcc,0xff,0xff,0x3f,0xff,0x02,0x01,0x0f, +0xfc,0xfe,0xff,0x05,0x32,0xff,0xfc,0x02,0xa0,0x00,0x01,0x01,0x4f,0xfc,0xff, +0x04,0x00,0x03,0xc3,0xa0,0x00,0x01,0x00,0x9f,0xfc,0xff,0x04,0x00,0x00,0x3c, +0x40,0x00,0x0b,0x00,0xf0,0x00,0x80,0x0b,0x7e,0x02,0x80,0x7f,0x02,0x40,0x00, +0x0b,0xfe,0xac,0x03,0x90,0xf4,0x81,0x7b,0xf8,0xff,0xff,0xdf,0xff,0x0b,0x01, +0x1f,0xfc,0x7f,0xff,0xff,0x85,0xff,0xff,0x01,0x20,0x00,0x01,0x01,0x5f,0xfc, +0xff,0x04,0x00,0x00,0xc1,0x20,0x00,0x01,0x00,0x9f,0xfd,0xff,0x05,0xfe,0x00, +0x00,0x3c,0x40,0x00,0x0b,0x00,0xf8,0x00,0x00,0x03,0x3f,0x07,0xe0,0xd3,0x00, +0xc0,0x00,0x0b,0xfe,0x87,0x00,0x33,0xfc,0xc0,0x77,0xf0,0xff,0xff,0x5f,0xff, +0x01,0x01,0x3f,0xfd,0xff,0x05,0x8b,0xff,0xf3,0x00,0xa0,0x00,0x01,0x01,0x7f, +0xfd,0xff,0x05,0xfc,0x00,0x0c,0xc1,0xa0,0x00,0x01,0x00,0xbf,0xfd,0xff,0x05, +0xfc,0x00,0x00,0x3e,0x40,0x00,0x0b,0x01,0xf0,0x00,0x00,0x05,0x7d,0x87,0xc0, +0xfa,0x00,0xd8,0x00,0x0b,0xfe,0x8f,0x80,0x47,0xfa,0x80,0xef,0xe3,0xff,0xff, +0xbf,0xff,0x01,0x00,0x3f,0xfe,0xff,0x06,0xfd,0x11,0xff,0xfa,0x00,0x58,0x00, +0x01,0x00,0x7f,0xfe,0xff,0x06,0xfd,0xfe,0x00,0x05,0xe1,0xd8,0x00,0x01,0x01, +0xbf,0xfe,0xff,0x06,0xfd,0xfc,0x00,0x00,0x1e,0x00,0x00,0x0b,0x00,0xf0,0x00, +0x00,0x0c,0xfc,0x87,0x81,0xfc,0x00,0x70,0x00,0x0b,0xfe,0xaf,0x8c,0xcf,0xf3, +0x00,0xcf,0xc3,0xff,0xff,0xc7,0xff,0x01,0x00,0x1f,0xfe,0xff,0x06,0xfc,0x33, +0xff,0xfc,0x00,0xa0,0x00,0x01,0x00,0x5f,0xfe,0xff,0x06,0xfc,0xfc,0x00,0x03, +0xf0,0xe0,0x00,0x01,0x01,0x9f,0xfe,0xff,0x06,0xfc,0xfc,0x00,0x00,0x0f,0x18, +0x00,0x0b,0x01,0xf0,0x00,0x00,0x1d,0xfd,0x0e,0x00,0x76,0x00,0x90,0x00,0x0b, +0xfe,0x8f,0xe0,0x0f,0xe2,0x00,0x7f,0x83,0xff,0xff,0xf7,0xff,0x01,0x00,0x3f, +0xfe,0xff,0x06,0xfd,0x83,0xff,0xfe,0x00,0x48,0x00,0x01,0x00,0x7f,0xfe,0xff, +0x06,0xfd,0xfc,0x00,0x01,0xf0,0x48,0x00,0x01,0x01,0xbf,0xfe,0xff,0x06,0xfd, +0xf8,0x00,0x00,0x0f,0x10,0x00,0x0b,0x00,0xf0,0x00,0x00,0x33,0xff,0x1e,0x00, +0xed,0x00,0x30,0x00,0x0b,0xfe,0x8f,0xf3,0x3f,0xcc,0x00,0x7f,0x00,0xff,0xff, +0xd7,0xff,0x01,0x01,0x3f,0xfd,0xff,0x05,0x87,0xff,0xff,0x00,0x48,0x00,0x01, +0x01,0x7f,0xfd,0xff,0x05,0xf8,0x00,0x00,0xf0,0x68,0x00,0x01,0x00,0xbf,0xfd, +0xff,0x05,0xf0,0x00,0x00,0x0f,0x90,0x00,0x0b,0x01,0xf8,0x00,0x00,0x15,0xfe, +0x18,0x00,0xf6,0xc0,0x20,0x00,0x0b,0xfe,0xa7,0xf7,0xbf,0xea,0x01,0x7e,0x81, +0xff,0xff,0x7b,0xff,0x01,0x00,0x1f,0xfd,0xff,0x05,0x8f,0xff,0xfe,0xc0,0x00, +0x00,0x01,0x00,0x5f,0xfd,0xff,0x05,0xf0,0x00,0x01,0x38,0x20,0x00,0x01,0x01, +0x9f,0xfd,0xff,0x05,0xf0,0x00,0x00,0x07,0x44,0x00,0x0b,0x00,0xec,0x00,0x00, +0x0c,0xfc,0x08,0x43,0xfc,0xc0,0x34,0x00,0x0b,0xfe,0xb3,0xff,0xff,0xf3,0x02, +0xcc,0xc3,0xff,0xfe,0x29,0xff,0x01,0x01,0x4f,0xfd,0xff,0x05,0x3f,0xef,0xfc, +0xc0,0x00,0x00,0x01,0x01,0x4f,0xfd,0xff,0x05,0xf0,0x10,0x03,0x3e,0x10,0x00, +0x01,0x00,0x9f,0xfd,0xff,0x00,0xf0,0xfe,0x00,0x01,0x06,0x00,0x0b,0x00,0xcc, +0x00,0x02,0x1d,0xf4,0x68,0x00,0x6f,0x80,0x34,0x00,0x0b,0xfe,0xb3,0xff,0xfd, +0xe2,0x02,0xff,0xc1,0xff,0xff,0x7d,0xff,0x01,0x00,0x2f,0xfe,0xff,0x06,0xf7, +0x1f,0xff,0xff,0x80,0x02,0x00,0x01,0x00,0x6f,0xfe,0xff,0x06,0xf7,0xf0,0x00, +0x00,0x7c,0x12,0x00,0x01,0x01,0x9f,0xfe,0xff,0x06,0xf7,0xe0,0x00,0x00,0x03, +0x44,0x00,0x0b,0x00,0x9c,0x00,0x03,0x33,0xe0,0x6e,0x00,0xff,0x00,0x1c,0x00, +0x0b,0xfe,0x33,0xff,0xfc,0xcc,0x00,0x7f,0x00,0xff,0xff,0xf5,0xff,0x01,0x01, +0x2f,0xfe,0xff,0x06,0xe3,0xbf,0xff,0xff,0x00,0x02,0x00,0x01,0x01,0x6f,0xfe, +0xff,0x06,0xe3,0xc0,0x00,0x00,0xfc,0x0a,0x00,0x01,0x00,0x8f,0xfe,0xff,0x06, +0xe3,0xc0,0x00,0x00,0x03,0xe4,0x00,0x0b,0x00,0xfc,0x40,0x45,0xc7,0xf2,0x3c, +0x00,0xee,0x80,0x18,0x80,0x0b,0xfe,0x33,0xbf,0xba,0x38,0x03,0x3e,0x03,0xff, +0xff,0xde,0xff,0x01,0x01,0x4f,0xfe,0xff,0x06,0xf0,0xff,0xf7,0xfe,0x80,0x00, +0x80,0x01,0x01,0x6f,0xfe,0xff,0x06,0xf3,0xc0,0x08,0x01,0x78,0x88,0x80,0x01, +0x00,0x8f,0xfe,0xff,0x06,0xf3,0xc0,0x00,0x00,0x07,0x41,0x00,0x0b,0x00,0xfc, +0xc0,0xcc,0xcf,0xf0,0x68,0x01,0xec,0x80,0x0d,0x00,0x0b,0xfe,0x33,0x3f,0x33, +0x30,0x00,0x7c,0x03,0xff,0xff,0xce,0x7f,0x01,0x00,0x4f,0xfe,0xff,0x06,0xf3, +0xbf,0xff,0xfc,0xc0,0x00,0x00,0x01,0x00,0x6f,0xfe,0xff,0x06,0xf3,0xc0,0x00, +0x03,0x30,0x04,0x00,0x01,0x01,0x8f,0xfe,0xff,0x06,0xf3,0xc0,0x00,0x00,0x0f, +0xc1,0x80,0x0b,0x01,0x37,0xa1,0xb5,0x5f,0xcb,0xe0,0x00,0x7f,0x80,0x07,0x00, +0x0b,0xff,0x5c,0x5e,0x4a,0xa0,0x04,0xf2,0x0f,0xff,0xff,0xf5,0x7f,0x01,0x01, +0x2b,0xfe,0xff,0x06,0xcf,0x3f,0xff,0xff,0x80,0x02,0x80,0x01,0x01,0x3b,0xfe, +0xff,0x06,0xcf,0xc0,0x00,0x00,0x7c,0x02,0x80,0x01,0x00,0x83,0xfe,0xff,0x06, +0xcf,0x80,0x00,0x00,0x03,0xf1,0x00,0x0b,0x00,0x2c,0xb3,0x33,0x3f,0xc3,0xa1, +0x08,0x6b,0x00,0x03,0x80,0x0b,0xff,0x94,0x4c,0xcc,0xc0,0x10,0xf7,0x0c,0xff, +0xff,0xe5,0x7f,0x01,0x00,0x00,0xfe,0xff,0x03,0xcf,0xff,0xbf,0xff,0xfe,0x00, +0x01,0x00,0x08,0xfe,0xff,0x06,0xcf,0x00,0x40,0x00,0xfc,0x02,0x00,0x01,0x00, +0x60,0xfe,0xff,0x00,0xdf,0xfe,0x00,0x02,0x03,0xe5,0x80,0x0b,0x00,0x3c,0x8d, +0x57,0xbf,0x8e,0x48,0x00,0xfe,0xc0,0x07,0x00,0x0b,0xff,0x8f,0x72,0xa8,0x40, +0x3f,0xfe,0x07,0xff,0xff,0x8d,0x7f,0x01,0x00,0x50,0xfe,0xff,0x06,0x81,0xcf, +0xbf,0xfe,0xc0,0x02,0x80,0x01,0x00,0x58,0xfe,0xff,0x06,0x8f,0xb0,0x40,0x01, +0x3a,0x02,0x80,0x01,0x00,0x23,0xfe,0xff,0x00,0xbe,0xfe,0x00,0x02,0x05,0x89, +0x00,0x0b,0x00,0x3b,0xcc,0xcf,0xff,0x34,0x84,0x01,0xac,0xc0,0x0d,0x80,0x0b, +0xff,0x8f,0x33,0x30,0x00,0x7c,0xfc,0x03,0xff,0xff,0x9a,0xff,0x01,0x00,0x54, +0xfe,0xff,0x06,0x08,0x47,0xff,0xfc,0xc0,0x00,0x80,0x01,0x00,0x5c,0xfe,0xff, +0x06,0x0f,0xf8,0x00,0x03,0x27,0x04,0x80,0x01,0x00,0x20,0xfe,0xff,0x00,0x40, +0xfe,0x00,0x02,0x18,0x91,0x00,0x0b,0x00,0x6f,0xdd,0xff,0xfc,0x6b,0xf9,0xc0, +0x27,0x80,0xc8,0x00,0x0b,0xff,0xf7,0x82,0x00,0x00,0xfa,0x7f,0xf1,0xff,0xff, +0xf7,0xff,0x0b,0x00,0x68,0x5f,0xff,0xfc,0x10,0x11,0xff,0xff,0x80,0x30,0x00, +0x0b,0x00,0x6e,0x5f,0xff,0xfc,0x1c,0xe6,0x00,0x00,0x60,0x38,0x00,0x05,0x00, +0x00,0x5f,0xff,0xfc,0x83,0xfe,0x00,0x02,0x1f,0x00,0x00,0x0b,0x00,0x0e,0x4f, +0xff,0xfc,0x94,0x78,0x3c,0xff,0x07,0x58,0x00,0x0b,0xff,0xe3,0xc0,0x00,0x00, +0xf9,0x2f,0xfc,0xff,0xff,0xf7,0xff,0x0b,0x00,0x05,0x8f,0xff,0xfc,0x60,0x14, +0x3f,0xff,0x08,0x80,0x00,0x0b,0x00,0x07,0x8f,0xff,0xfc,0x70,0x1f,0xc0,0x00, +0xc8,0xc0,0x00,0x0b,0x00,0x18,0x0f,0xff,0xfc,0x06,0xe0,0x00,0x00,0x30,0x18, +0x00,0x0b,0x00,0x0b,0x60,0xff,0xc1,0xb6,0x6e,0x42,0x00,0xad,0xf8,0x00,0x06, +0xff,0xe1,0xf0,0x00,0x03,0xe3,0x17,0xfe,0xff,0x01,0x33,0xff,0x0b,0x00,0x02, +0x80,0xff,0xc0,0x52,0x81,0xb2,0x00,0x12,0x40,0x00,0x0b,0x00,0x03,0x80,0xff, +0xc0,0x72,0x8e,0x7d,0xfb,0x1f,0xc0,0x00,0x0b,0x00,0x1c,0x10,0xff,0xc2,0x0c, +0x60,0x00,0x04,0x40,0x3c,0x00,0x0b,0x00,0x03,0xb0,0xff,0xc3,0x70,0x00,0x60, +0x00,0x96,0x40,0x00,0x0b,0xff,0xf8,0xf8,0x00,0x07,0xc7,0xf0,0x3f,0xff,0xfd, +0xff,0xff,0x0b,0x00,0x01,0x40,0xff,0xc0,0xa8,0x0e,0xd0,0x00,0x60,0x40,0x00, +0x0b,0x00,0x01,0xe0,0xff,0xc1,0xe8,0x0e,0xff,0x30,0x70,0x40,0x00,0x0b,0x00, +0x06,0x08,0xff,0xc4,0x10,0x01,0x00,0xcf,0x06,0x00,0x00,0x0b,0x00,0x02,0xf8, +0x40,0x47,0xd8,0x17,0xb9,0xdf,0xf7,0x80,0x00,0x0b,0xff,0xf8,0x1f,0x80,0x3e, +0x2f,0xf1,0xdf,0xff,0xc6,0x3f,0xff,0x0b,0x00,0x01,0x20,0x40,0x41,0x48,0x18, +0x06,0xee,0x18,0x00,0x00,0x0b,0x00,0x01,0xf0,0x40,0x43,0xc8,0x18,0x39,0x11, +0xf8,0x00,0x00,0x0b,0x00,0x06,0x07,0xc0,0x78,0x10,0x07,0x80,0x00,0x07,0xc0, +0x00,0x0b,0x00,0x00,0x7b,0x80,0xf7,0x80,0x00,0x2c,0x48,0x30,0x00,0x00,0x0b, +0xff,0xff,0x0f,0xc1,0xfc,0x7f,0xff,0xe0,0x00,0x3f,0xff,0xff,0x0b,0x00,0x00, +0x14,0x00,0x08,0x00,0x00,0x32,0x90,0x70,0x00,0x00,0x0b,0x00,0x00,0x1c,0x00, +0x0e,0x00,0x00,0x32,0x90,0x70,0x00,0x00,0x0b,0x00,0x00,0xe0,0x41,0x03,0x80, +0x00,0x0d,0x6f,0x80,0x00,0x00,0x0b,0x00,0x01,0x6f,0xc1,0x7d,0x80,0x00,0x17, +0xff,0xe0,0x00,0x00,0x0b,0xff,0xff,0x01,0xff,0xc0,0x3f,0xff,0xc0,0x04,0x0f, +0xff,0xff,0x0b,0x00,0x01,0x98,0x3e,0x84,0x40,0x00,0x28,0x40,0x10,0x00,0x00, +0x0b,0x00,0x01,0x9f,0xfe,0xfc,0x40,0x00,0x28,0x00,0x10,0x00,0x00,0x0b,0x00, +0x00,0x60,0x00,0x03,0x80,0x00,0x17,0xbf,0xe0,0x00,0x00,0x0b,0x00,0x00,0xc1, +0x2b,0x82,0x00,0x00,0x20,0xc0,0x10,0x00,0x00,0x04,0xff,0xff,0xf0,0x00,0x13, +0xfa,0xff,0x0b,0x00,0x00,0xce,0x00,0x0a,0x00,0x00,0x20,0xc0,0x10,0x00,0x00, +0x0b,0x00,0x00,0xce,0x00,0x0a,0x00,0x00,0x20,0xc0,0x10,0x00,0x00,0x04,0x00, +0x00,0x01,0xff,0xe4,0xfa,0x00,0x04,0x00,0x00,0x13,0xff,0xf0,0xfa,0x00,0x04, +0xff,0xff,0xf0,0x7f,0x83,0xfa,0xff,0x04,0x00,0x00,0x14,0x00,0x0c,0xfa,0x00, +0x04,0x00,0x00,0x14,0x00,0x0c,0xfa,0x00,0x04,0x00,0x00,0x0b,0xff,0xf0,0xfa, +0x00,0xfe,0x00,0x01,0x7f,0xe0,0xfa,0x00,0xf5,0xff,0xfe,0x00,0x01,0x7f,0xe0, +0xfa,0x00,0xfe,0x00,0x01,0x7f,0xe0,0xfa,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff, +0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5, +0x00,0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff, +0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5, +0x00,0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff, +0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5, +0x00,0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff, +0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5, +0x00,0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff, +0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5, +0x00,0xf5,0x00,0xf5,0xff,0xf5,0x00,0xf5,0x00,0xf5,0x00, }; +#endif diff --git a/scalos/Prefs/MainPrefs/Images/icons.brush b/scalos/Prefs/MainPrefs/Images/icons.brush new file mode 100755 index 0000000000000000000000000000000000000000..9e8883f429b8b2a0d81d4fc2fe2dfe0649c24615 GIT binary patch literal 1676 zcwV)Xzl#$=6vw~GMo}C{3eh%fCEgVa+gL2@CAZ`}NW9}Pg@tGlEc6eEgFwYY#q6l;-VVMPR2pYM$Ue-#PDd$7!Wzn|TCZ|BW!Wn-%b9KN+) zE!WDmvjKqPIEey}$Ys$6mX|Xt8LZYyn`}AM@Ai7Vpxz~*FEJbrH3O|R5jC65eRT0w zG_J@kYg?tVEQMn@vRbOGnR&K=^Xum>0Eco|!6_VYaA6e1f0@otpTgNZv|K3hEP}(n zPcDtbXG{Erxk})%k32b!C!C@rmgf|dnuGfk8%`7(&Nmn?>;DHHC7u?ZCrS-Zrd*Aj zd3fkXsb}6hGF&!Rc%-NK7vzzzA}5yon*3Di=NFRvA)I-5sKV4|?L{HQtSyg7`lKyb zl4D_x7@pb7REzH>iJS1|YNeFv|4hz>^7^iuxKh93k4@@NT-P=AFUm)W&4@j>8( ztfda}RAlO(!HN6L%Nj0yk^aZ#T=SlXi*r6#l*Ut@{?aDYY%XD8>Zb>z7m4yl!2iO` zKR(g(=`6?dFWA{EA`=H_U3$bn<{~<;8?ZiA(E2*TPSM7lw1IqDL6auTZM?YJfd9RM zo2)wzZQR~%ptW1!x+fSgf3{SG|8yJ8md4$jjn4fWxc1;BPEdfynE~42W!N7ATpYi_ z6T66ZyNddF8>jmk literal 0 HcwPel00001 diff --git a/scalos/Prefs/MainPrefs/Images/icons.c b/scalos/Prefs/MainPrefs/Images/icons.c new file mode 100755 index 000000000..f63899d65 --- /dev/null +++ b/scalos/Prefs/MainPrefs/Images/icons.c @@ -0,0 +1,54 @@ +#ifdef USE_ICONS_COLORS +const ULONG icons_colors[48] = +{ + 0xffffffff,0xaaaaaaaa,0x99999999, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0x44444444,0x55555555,0x99999999, + 0xffffffff,0x00000000,0x00000000, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0xaaaaaaaa,0xaaaaaaaa,0xbbbbbbbb, + 0xbbbbbbbb,0xbbbbbbbb,0xcccccccc, + 0x00000000,0x00000000,0x00000000, + 0xcccccccc,0xcccccccc,0xcccccccc, + 0xffffffff,0xffffffff,0xffffffff, + 0x77777777,0x77777777,0x77777777, + 0xeeeeeeee,0x00000000,0x99999999, + 0x00000000,0xdddddddd,0x00000000, + 0x00000000,0xcccccccc,0xcccccccc, + 0x00000000,0x66666666,0xffffffff, + 0x00000000,0x00000000,0xaaaaaaaa, +}; +#endif + +#define ICONS_WIDTH 23 +#define ICONS_HEIGHT 16 +#define ICONS_DEPTH 4 +#define ICONS_COMPRESSION 0 +#define ICONS_MASKING 2 + +#ifdef USE_ICONS_HEADER +const struct BitMapHeader icons_header = +{ 23,16,0,0,4,2,0,0,0,44,44,320,256 }; +#endif + +#ifdef USE_ICONS_BODY +const UBYTE icons_body[256] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0xff,0xff,0xbc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0xff,0xff, +0xf8,0x00,0x81,0x50,0x20,0x00,0x01,0xf0,0x44,0x00,0x7f,0x5f,0x98,0x00,0x80, +0x00,0x20,0x00,0x82,0xd0,0x64,0x00,0x03,0xf4,0x46,0x00,0x7f,0xfb,0xdc,0x00, +0x81,0x20,0x22,0x00,0x87,0xfc,0x64,0x00,0x0f,0xfc,0x46,0x00,0x77,0xff,0xdc, +0x00,0x80,0x00,0x22,0x00,0xbd,0x6a,0x64,0x00,0x3f,0xfe,0x46,0x00,0x7d,0xff, +0xdc,0x00,0x82,0x94,0x22,0x00,0x85,0xbe,0x64,0x00,0x7f,0xbe,0x46,0x00,0x0f, +0xff,0xdc,0x00,0xba,0x00,0x22,0x00,0xb7,0x2b,0x4c,0x00,0x3f,0xaf,0x7e,0x00, +0x77,0x7f,0xcc,0x00,0x88,0x04,0x22,0x00,0x82,0x8e,0x7c,0x00,0x6b,0x8f,0xc2, +0x00,0x16,0xff,0x44,0x00,0xa1,0x01,0xba,0x00,0x80,0xc0,0x60,0x00,0x22,0xea, +0x44,0x00,0x5d,0xd5,0xd8,0x00,0xa2,0x22,0x20,0x00,0x80,0x80,0x4c,0x00,0x55, +0xd5,0x7e,0x00,0x2a,0xaa,0xcc,0x00,0xd5,0x55,0x22,0x00,0x89,0xd4,0x78,0x00, +0x7f,0xff,0xc6,0x00,0x09,0xd4,0x44,0x00,0xf6,0x2b,0xba,0x00,0xfd,0xff,0xe0, +0x00,0x7f,0xff,0xdc,0x00,0x7d,0xff,0xc0,0x00,0x82,0x00,0x38,0x00,0x3f,0xff, +0xec,0x00,0x7f,0xff,0xde,0x00,0x3f,0xff,0xec,0x00,0x00,0x00,0x02,0x00,0x00, +0x00,0x10,0x00,0x3f,0xff,0xee,0x00,0x00,0x00,0x10,0x00,0x3f,0xff,0xee,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00, }; +#endif diff --git a/scalos/Prefs/MainPrefs/Images/img1 b/scalos/Prefs/MainPrefs/Images/img1 new file mode 100755 index 0000000000000000000000000000000000000000..f8dd96cabdbd5c924054e3e1dd6824e33af76aa2 GIT binary patch literal 14554 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 literal 0 HcwPel00001 diff --git a/scalos/Prefs/MainPrefs/Images/img2 b/scalos/Prefs/MainPrefs/Images/img2 new file mode 100755 index 0000000000000000000000000000000000000000..fdfad3005893861c5d2f33894e9a5483293d8977 GIT binary patch literal 15690 zcwX&$eRx#Wwf8=APDrR?l8OaHOrXVDY_C?l_u{pXfYG7_BbC&z0HP%y!Y5G2V21jQ5$DhM10>8$X3p8~`q&fVz3=n9 zeV^w(&-?yyfy0{F=Xcgxd+)W^T6?cE4`%;#x)2kmJTz^}^eNM)W(gsNYMI(fpkk2F zOd-DiefTc!pFa6fX!5|dcJ11^Ia%}O%^N?jIxA=G+~V4`)wOH0L~&M@cl`LnS>wBN za;l5xb=Qi+#q)~S*3L~$T{~ucZS~sfYPb$p!@t_YwfN6ld)O)S<`Z6O&cS!#*BG>#E7|LM$8*GE+^~0d9%datoyR2 z%^IJSG%a<+tej~%IdIL*fq%2+&cc7s&zk$ZGiTb|xzEpi9`v2(bUL#hee^Mq@w{+| z0e`e#!GBfaAhbRuGU0Rl`dj{J|L5=bPoDl`_+$u2iaGP4N1hZyp9cJI7u|h=u9a|| zh3jgch`=brr#*0e+Q*+irPdPo^gdkmaG7ugskL6U*l_LU3tD6FX9 zXgv*|s?~+souk&i|HPr5T6+ex!WbY*jagS8>r&m%7svKPxc;c5@%ZAneyTVW!}TV$ z;vBTH6ynxRt>y5kk};&ioBh2Qs0Z`is5o3zd|5Np>M&fLeLTmF{T$+RcWoThtn~M| zv44C$11_GoL-6Sjio?Es4%m87U5EHmqZ1!_itNJG6&f~^o5aMNWl@01srtr|Q!6}WF1tPMk$zb)?o!paA0NhtLEtWR0! z#!PKEG;|3qjc}e(O*m@hLW5EBnWGLcY}?TFLje{Wx}MnCVhG-F6dLOR)@r=>32Wy* zstw2c)=_3>JBARu!bg!^%TI?eJEJRW^c#3TmN|M9;RY4His}`LbO(s3bZks!U|{Ny zFanMwG5xe7{~Q9hCk;LTKI)!#CeSOczu(zw< zeGM8~tKYo|*;UM#xr}k*24pv5Cd<_id@$>;z%KB?tdl@uLPKeVLOVxV3z`~GZ+D6o z#OGrvS}WrwF-}9=J|5IlI9{SsJ$WmSpH^a$4G0Y$FomZ28IfE;}4?aGx(a9?HG32ceh`+P*DL@G?Mx2SK5RbTzdUqK zl<0UDt-}?`Z7o9gNm+#UX&e>edc5rsf-L2n5V#CP8OYoz#CT>_^|*aE-fbH;8(WNE z<_4sCS&p3!x`c0<{R0NBtg-QNW9yyuM1yALod_(hMxY)ZSD#K|mpyJz#QVF3%_dwp za|7Yb9LC)=dko>)YV3RIzTy{F{7m9!l#Q$ZE(L$$X1?CZ-2en07WbrmFR8;SW{)5KaOd960K1BoL-jc zq^UIpnn2~few%e`s9cB4h1VYF9Ko9O`e*z$jc-WGGsqigfJXz(5}lm~mz|WYG#aIk zK7ymz+hhL~(Y-wq1!^UFGiVX`fETr~N{HEbdy5cgw+5`{Y?N3D5^Y*I0NUb=J!#Ss z6hyn6v4>Fk)y^2$C7=h9#F8v=3rM_b2y#qkvuMF-qnSiPnj%kECktxU*H3~6Hp{5T+Jxr*QMS?tU z$t~Q+l3WM&QCqbLQ1&g3siggCA%=O0q#@DlY?#Ltu%v9wo=U3gmC%1Lk*Ap;r0`2J zwLuKo_j}KcFb2M8;u;j?lZmA`QiUQ6)9fyi>~f6~L1U!100mYM`;rG(O^_{@EuVb1 zThV$Ul5l!FU!unpi5#znPq+)1v^sye)r+g(G!RFdNCSz|uO#Y6+GYje?#Y0S+Ux^{FaM6~+VXUfi2==x5UMb6PDciCV%RH1aI zZaz)1!kmK(JyFu&dT0$vLl!csF<}L|FqgXucUli!ciFU341)YStCCan#xVUm$~Ee|PI zrPz6jnBB(-W)9xJtZ-3_J7FsABu|CD%W@t^pAvJn(1@7m!^{{NhGEA{74+&gS|571 z5Ri-L7c_x63T!|V5f|={d9_mZzzsjgM*R#2?J~ixEEdNZpCt%%F8U|37X4UBW zoRspaqOGV}4Mk4~x?Y0qm$Dge|1~F-g4BsW1yGLu9tT->PAZ4IBRx-{Cpz5o#0Z2n z^^L>8sBiCi3QSenjwjUeJF=wvQFv~JId=w-(jr-cp?OI+#v#Kt=fyMeu~{?W{_e3^ zBT&lg`}P2Ae?k_+iuNgPGVy^~a3iKaKwedD$~uBlixRUiU5PEuQn(!j20Fs+4udl1 zkC$ZO&P8u3FeXE@H7Jgg6=Cu<8z;EXFrzY?*j0o*2s@jhT$1|^&oONHUZ#u0-rT^r zJ3NHDH?xGNqUi2JlyX#zd6B{2#YyQ=(e5%+95@Vu*Mellwt@<1*gbLaB^n5(dWUDx4ZJSc*XRw! zBk}mbb!MR(ak4$i7ILeB*_1O5+c0L04LyWX_$b!0t&S8*>`;?^H(Fu z+IIhok9h5Mfwu=I7Eoo@&6vwU=D z<0wd>!-2?tm4^Nteq;1lq+q|@eFziYHbT11m9&zMzxOdF!JpiP=<(4$EJPl1ZHp<(= z0$&>$?Lk4GL}^HkKSf5M|J5(0-iT>yWaJe|0*gmp>4gWEN28QqUJMVXbUK)F<7J%D zkx?~lWj9_SKyx(Ohjd*y1rJ&Dwv>^ffk3@*bo)gRP-j_~=+?#3F;IEZCz2MiiSf~m zoR9AJ;+8YoiRutBiW>G)u<-lT%o|)xPE4kYn8fy5#8uQu)7~*LP`4-#Buzh)X-}TaZdBJS$r*T}ZEK&Lu zte)>cK&9-<9zgXrVW2vevsB4_{r*JEY?_@u+$HL6r<@I6+k_ZR_zq*=1Th+)RJhKsvWqL?EYxH5x*ZUlnh(m3$sUrY)E^FBde zqwUN_tB2GX9|PP!^3cKVw%JQ_ODR>0n9%CQ13F~{Vgd`+%f3^J;lvkn)ibdXrspCI zU7nA{=C3L&#|J;UbQ9_Kp8W#(sMcf*#L^jMqc_4y%YK3PH&w02O{lTneuFlnt!eXb zA=hZD#kQ^S0X)~;aoS7neMj?ta_wPWzh-EiCeuZu`KIXI7C=2hH|oRU#xPr+#t4~Z{V_$m-~X%wIPly0m`Vc2KaQ`V86b{PZQ z=P{@1!m$tC5200b2XRWJ*U^AupciCBaGANg=P}N)f2#}G+d({nl}+byb(g_&)`KWCFIg$-`{TyM=819#i%g#N@tDNdtffi%|A)35{Wgp3F-xePI4A| z!-`+?V_`g*-u_r2t?kzq30m9T(u4VhT)b0RO4sXu9z>HM?QbcHt5`1)T4X?-pd_(z zE#Ce}o<(nKT#;w7U-}9$;>7{5<3I2|gUw+p^b_dDB`bv8C~+j^n&hIhS-I99bsmM= zpU2KZZlPb1ehl|3#Bl1YjM;2X#^&o@qTy`2F4avm`E_26SAL7D(HG6DV}36GN56pv zf9NCZmEpIqB6XA{F2_|7s#RmMvh=|Z@VUT)Y@SvZn`iRR5EeM0az+2_Eqif{W^ZBG z!t)HP+yby>-&Yw7d$aCoSo%ia#HYzR?RlT$4M%?669DtOzhGlGb}abtL%bhb@F8^~ z7HFS?xWx;$f|)frx3XjG?EP&M-VQ2y$!AjdDe29{@KY&sRVUuPunHH?rVFcRKl+yY zCk^nm;)03N4X^xzvb^Z=u@vY!j*oo=2HEeNgXc%=Jk3RM?VJGUGMZ%E5TQ+eaxN;Cu>~j%&2dNoQ*M ziiI!XDR+Zgk{4^sAga4Ol+4P`cn%WgGfAUL9T~Q9dasw!S)=hq|B+9#?Zj=D(GjQ8 ziA6Mho$bWYj!LIW%lpI>^7sW}3O;HqmU(!`0qrdVaC+bT>_T|(^nz@12OZYG(d4|j zAlsx(P8|2)U-Awj?k{;wEcXRkW^YcN)ke5Hg^SLA`FT`i{>zlrMEB1@yk4;2gQ*^`-B&3r~!2Eei?wI9*+j`s1X9*36(GS z#8Avr@CexgTu26DfGZX$bR_BKObFQ3z2t6!;kL9jU9@Qopc5_-6A0!DoD4C$mWN|> zwgw7+!t`}2Pnu#;B0S*kjc=nMp}9n>?&KvF6u?o&=57k_CzY9O6e;LEc8in*#KGnf z&tzcJn1TxYXC- z_JKIqV#!VtI5~MU(d!)PEI1i+_E>r{kFx>WQao1#4IQ_$h6xIoc;`Tl;BC(EcDs{E z9&R$0NO=(-s_5T!uhu-Y3^xjs%Gn#VOr-ij&4ZPub0U6598B&)PXI&JMczurRy;x@ ztp|UIhHxdmTM8z4Xp&_2pOg84Ut|+dYr&Cq*={u@WiP(=^|JiSG$p1e`FdIYt#eb+ zVan)lx*4}X;ffF!o2Rxx#+CccC4Fda*Tk>f_e&_Vyq?Cw}xk~M$#z`ZjVkP z$|dcCoanW(*o}_-onAUdATRIlBfa%IPMt|LVCXs5Wo?N>H{Ze=(a*=9c76Ex-ZH z9n_?N-(!wPMl)@?eb7M!Zogd=;ee$ppuSs6ft*?|*TfrMtTX*|vPm{bHf^&b#vZpN zT_T%K>P2?0o<_>pJF5f+LOHZivD+ui?ZB=}m_?ZI#a{7y=>Ue5fUnAR)aA@PiqBg) zGqE0HZ?1lXag@n7Zmw3ACBJx|O6_q9YmPiFARG7r)!$f>*nohRqyi^xk2c(ZnZ1Gw^Re#Ki^6_o_q|E43WlMCjz;iG&`|qsH$18AGxCV_bJPnzx z_>#0uR69O-7;o-X+uQRhaj2kUW1~*erW1f~rHF4Lup@=boV|QUt4IMCZl#Fn3|o`S zHPRi5_8z5i(w1R;)5;W?Bz1XKF`Wa~W)%}EQhx|hjwMDhBo3BQJcVF>9v4IMC>qxB z_esfo7>)`d9%qq7?Dr8xg;#6!p?;LbWmZ5f{?DjY)p3*#sGrkvb$xRT)hX+#bcfRlRIssd>ke{BBT$hW64MBlbh1 z3^{7Zh-8R@7lFEe9pc2Tl#Kvx(M~Uh1Ke+cu77@ zp2EAa?zZk4Rt-mQZm)6t_Z zCPJd6hjX>Y0dK#AJzBgdf8iL0sPKhjxU;RBJ`RJa?jf@=!qdenhIyt6h$Y6#sT@Pg zU;90#Q}kwFIEBs=0n~X{(ysxu0tkZM6o%dpfuE^roYUFuHnEF!2Q-=K_(F1M2bNHlZdonk_51exzGL-9I1zTS3ROj48V*OvU(6 zgp2W^2pWyU6oYV2dm$}ejK9N^LHD`%5vSxB?c*69S}4o!?4eS8jige1011!((TsQ@ zKKnAh++o;FtsfJgCLb5#X>Yu1Yo02^3xNq;C__>jB;AxK60fx${UWR0XJS%;uZ`jQ z9{5&YzDHll^3IipX)T3iWSvQCB)X2|C5N#H-xOtMSG8;gy?+$k^*eHQ;o60x2sRbp z4f&$!;>}#Gc%%%A@Zm{c-b$noh-N+n-Y58z(<4}7xGCsh7Gc`9huvW=u20qR#SXLS zx>3Yy=QqZIfg8IPRugQO>|hI>->io)T9ncR&;djC%q^fxA` z*NBaZpx`>Zs_0j$iay4I)BOh~$BQIY;X{(D@L{2<@RT`ToG<>{tMEI5qqqux$(J#J z>ZQTq*w4VF=6Ds}4(!3eRn$fY{zgrQI`}tsgfs9ELSGZXvXSnJWMC=YA9j-^1R`n& z4+>@6voY3#Hr&zgkW*qV02#L zTD_%`+e2hXZ90gsr1o{;AcfTb2GZlF=Wl%hiYdIpn8Gx z2%f25U3s?>TPtOdh63M4P(&}__sji!{Dl6U_Wj0Hb*d|wl2^IVpPT)EUz7jqZ?;f1 z%e+IPD+}~P@|DV7A^LOB1@xK7v CbBf0R literal 0 HcwPel00001 diff --git a/scalos/Prefs/MainPrefs/Images/img3 b/scalos/Prefs/MainPrefs/Images/img3 new file mode 100755 index 0000000000000000000000000000000000000000..3206ac2a4cfd0b1a1f0b9d82c536c661d4571163 GIT binary patch literal 12628 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 I|L?E=2F_l*nE(I) literal 0 HcwPel00001 diff --git a/scalos/Prefs/MainPrefs/Images/misc.brush b/scalos/Prefs/MainPrefs/Images/misc.brush new file mode 100755 index 0000000000000000000000000000000000000000..8cdddc19a5f52aef295ee2a84fbbb59d4dda21f1 GIT binary patch literal 1564 zcwX(4ziPuU5Qo1QwNPS6hd_5v9WofQcrf@+Ow&Nsl+dM+*-sISM~_{zdG;%0$phpS z`U=4h5KtwzA)$nBjS2Kl(&=~K=@ub9OlK0V`;(_w#_}-%`rL7&Bf=tw!Jrd%7|G~G zr(Bg%mZgGKwN!d2l@_ZlOU+bOs4W!m0h*Mlu1S&g!Q;E{eRgJdzOy?wI$Lev%=Tuh z+OD>nbpWd3)hW-3@XTdTAi$#r%KcQ$X{1M)d|xQ726mNQjbJAqLV`~yK6yc{A5 zSzT$xuDMSkPKK1NMCWl!2*=Fi$dM&kWhg9}%s-M*D%{e-GMncLp_yAeLK)zaR*Q4T zjtOP%lLIY{EehH!)QO40`P{s;Wqct?S{Q$6rjmH%!kkpB%pQ^wq!VLkrm*8E1&+WL zrt6f=N+DGgO%;x&`CK7@`3^`)-a^w4wB$b9B%)C|JecxWn|)BDh!QRWx4bwHtROKX z;-|)OvOY!0`fO$Dx!j&|A{j?huK)5V1#Y}BA!pqD$&~cc;fqGKQ|Ge~>U6)vxzPk4 z$3T|#{<-&fvi<<>c@Oz@55?6c8gF*-a^)GaZ$F@TeFdF|7xBD!0okWNP#fprdnYIb z-;o>t#?{_sNdGGe#OaTrzm%Xaov?A7;xp9#5`NttqdVlx{Y237ptoP3``Sk<^O5Tw u^xijg-w|4cM|jl(j{IYEKM}g_G4{Epy+d@5OnnHS-`nRJ8*CQWr{fQhP3%tq literal 0 HcwPel00001 diff --git a/scalos/Prefs/MainPrefs/Images/modules.c b/scalos/Prefs/MainPrefs/Images/modules.c new file mode 100755 index 000000000..f296160b4 --- /dev/null +++ b/scalos/Prefs/MainPrefs/Images/modules.c @@ -0,0 +1,53 @@ +#ifdef USE_MODULES_COLORS +const ULONG modules_colors[48] = +{ + 0xffffffff,0xaaaaaaaa,0x99999999, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0x00000000,0x55555555,0x77777777, + 0x77777777,0x77777777,0x77777777, + 0x00000000,0x66666666,0x99999999, + 0x33333333,0xcccccccc,0xcccccccc, + 0x44444444,0x88888888,0x88888888, + 0xbbbbbbbb,0x00000000,0x00000000, + 0xffffffff,0x11111111,0x11111111, + 0xaaaaaaaa,0x88888888,0x77777777, + 0xeeeeeeee,0xbbbbbbbb,0x00000000, + 0x88888888,0x88888888,0x88888888, + 0x88888888,0x88888888,0xffffffff, + 0xbbbbbbbb,0xcccccccc,0xdddddddd, + 0x00000000,0x22222222,0x44444444, + 0xeeeeeeee,0xeeeeeeee,0xeeeeeeee, +}; +#endif + +#define MODULES_WIDTH 24 +#define MODULES_HEIGHT 15 +#define MODULES_DEPTH 4 +#define MODULES_COMPRESSION 0 +#define MODULES_MASKING 2 + +#ifdef USE_MODULES_HEADER +const struct BitMapHeader modules_header = +{ 24,15,0,0,4,2,0,0,0,44,44,320,256 }; +#endif + +#ifdef USE_MODULES_BODY +const UBYTE modules_body[240] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x24,0x00,0x00,0x00,0x3e,0x48,0x00,0x00,0x18,0x00,0x00,0x00,0x02,0x48, +0x00,0x00,0x5a,0x0b,0xa0,0x00,0x67,0x2d,0x60,0x00,0x3c,0x0d,0x40,0x00,0x05, +0x2d,0x40,0x00,0x21,0x14,0x48,0x00,0x47,0x92,0x78,0x00,0x7a,0x12,0x70,0x00, +0x02,0x97,0xb0,0x00,0x21,0x2e,0x12,0x00,0x4f,0x61,0x1e,0x00,0x72,0x21,0x1c, +0x00,0x02,0x6f,0xec,0x00,0x43,0xdf,0x05,0x00,0x7f,0x40,0xe7,0x00,0x24,0xc0, +0xe6,0x00,0x04,0xdf,0xfa,0x00,0x27,0x80,0x20,0x00,0x3f,0x7f,0xe1,0x00,0x18, +0xff,0xe1,0x00,0x18,0x7f,0xdf,0x00,0xfc,0xdc,0x24,0x00,0xfc,0x1f,0xe7,0x00, +0x00,0xff,0xe7,0x00,0x00,0x03,0xdb,0x00,0xf0,0x83,0x10,0x00,0xf4,0x53,0xdf, +0x00,0x7c,0xbb,0xdf,0x00,0x7c,0x04,0xef,0x00,0xc0,0x80,0x40,0x00,0xfc,0x74, +0x79,0x00,0x7c,0x8e,0x7f,0x00,0x4c,0x01,0xb9,0x00,0xc0,0x80,0x80,0x00,0xfc, +0x7d,0xe5,0x00,0x7c,0x9b,0xff,0x00,0x4c,0x18,0x65,0x00,0x82,0x80,0x00,0x00, +0xbe,0x7f,0xdd,0x00,0x7c,0xbc,0xff,0x00,0x7c,0x3c,0xdd,0x00,0x83,0x80,0x00, +0x00,0xff,0x7d,0xbd,0x00,0x7c,0xbe,0xff,0x00,0x7c,0x3c,0xbd,0x00,0x7f,0x00, +0x00,0x00,0x7f,0x7d,0xbd,0x00,0x00,0x3e,0xff,0x00,0x00,0x3c,0xbd,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + }; +#endif diff --git a/scalos/Prefs/MainPrefs/Images/paths.brush b/scalos/Prefs/MainPrefs/Images/paths.brush new file mode 100755 index 0000000000000000000000000000000000000000..e3b0b94a120192595c7470cbe0a21f164f7ac485 GIT binary patch literal 1676 zcwV)Yu}Z^G6o&t_RSE_gL~zwjq(h*SAf}B)Ef_1+#TW1uqEJ-C!NC`B>m1*}K>`I` z0tI)aI5;?HKwUI&{coDsQY$UC9=JXCKi}>7Z|@E1O1WYI<0qwc(=x5KB7iAOLt{oN zfg>QBRq_g!t->Ztx_CydR?FFr0362=&bbi6w(Vz}3+GgRiywD@=V4baS*;XI*$NX# zFBh!UaGubxUE0_I#!|>*4*wo%5-w9F5Qf{K2j-MMAR7FwzLc*)m`BES8j_1l-DlmX z$NLzNbN;FVz9B@gNG`p+5psn0Nq=r%a^^jZE?Me>!aWG66qq>&*R~ut(DXy-nQCWBY*1PY4Z0D4kXy`fclv8D#sH4 VFr>cXJkK#h-i)%#dh>hqiZ3(xue|^O literal 0 HcwPel00001 diff --git a/scalos/Prefs/MainPrefs/Images/paths.c b/scalos/Prefs/MainPrefs/Images/paths.c new file mode 100755 index 000000000..e8910f4da --- /dev/null +++ b/scalos/Prefs/MainPrefs/Images/paths.c @@ -0,0 +1,54 @@ +#ifdef USE_PATHS_COLORS +const ULONG paths_colors[48] = +{ + 0xffffffff,0xeeeeeeee,0x00000000, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0x33333333,0x77777777,0xaaaaaaaa, + 0xffffffff,0x00000000,0x00000000, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0xffffffff,0xaaaaaaaa,0x99999999, + 0xffffffff,0xffffffff,0xffffffff, + 0x77777777,0x77777777,0x77777777, + 0xeeeeeeee,0x00000000,0x99999999, + 0xffffffff,0xaaaaaaaa,0x88888888, + 0x00000000,0x00000000,0x00000000, + 0x00000000,0x88888888,0x00000000, + 0x00000000,0xdddddddd,0x00000000, + 0x00000000,0xcccccccc,0xcccccccc, + 0x00000000,0x66666666,0xffffffff, + 0x00000000,0x00000000,0xaaaaaaaa, +}; +#endif + +#define PATHS_WIDTH 23 +#define PATHS_HEIGHT 16 +#define PATHS_DEPTH 4 +#define PATHS_COMPRESSION 0 +#define PATHS_MASKING 2 + +#ifdef USE_PATHS_HEADER +const struct BitMapHeader paths_header = +{ 23,16,0,0,4,2,0,0,0,44,44,320,256 }; +#endif + +#ifdef USE_PATHS_BODY +const UBYTE paths_body[256] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x21,0x08,0x00,0x03,0xef,0x78,0x00,0x00,0x21,0x08,0x00,0x00,0x00, +0x00,0x00,0x00,0x10,0x8c,0x00,0xfb,0xff,0xfc,0x00,0x01,0xde,0xfc,0x00,0x00, +0x00,0x00,0x00,0x00,0x42,0x10,0x00,0xff,0x39,0xcc,0x00,0x79,0xef,0x78,0x00, +0x00,0x00,0x00,0x00,0x08,0x00,0xd2,0x00,0xc7,0xff,0xe6,0x00,0x7c,0x00,0xfa, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xaa,0x00,0xff,0xff,0xc6,0x00,0x7f,0xff, +0xba,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x00,0xff,0xff,0x46,0x00,0x7f, +0xff,0xba,0x00,0x00,0x00,0x44,0x00,0x08,0x00,0x2a,0x00,0xe2,0xab,0x46,0x00, +0x7f,0xff,0xba,0x00,0x00,0x00,0x44,0x00,0x01,0x04,0x12,0x00,0xf4,0x53,0x46, +0x00,0x7f,0xff,0xba,0x00,0x00,0x00,0x44,0x00,0x10,0x00,0x2a,0x00,0xea,0xab, +0x46,0x00,0x7f,0xff,0xba,0x00,0x00,0x00,0x44,0x00,0x08,0x04,0x12,0x00,0xf5, +0x53,0x46,0x00,0x7f,0xff,0xba,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x02,0x00, +0xff,0xff,0x7e,0x00,0x7f,0xff,0x82,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x3e, +0x00,0x80,0x00,0x7e,0x00,0x7f,0xff,0xbe,0x00,0x00,0x00,0x40,0x00,0x00,0x00, +0x20,0x00,0xff,0xff,0xe0,0x00,0x00,0x00,0x20,0x00,0xff,0xff,0xc0,0x00,0x7f, +0xff,0xe0,0x00,0x7f,0xff,0xe0,0x00,0x7f,0xff,0xe0,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00, }; +#endif diff --git a/scalos/Prefs/MainPrefs/Images/plugins.brush b/scalos/Prefs/MainPrefs/Images/plugins.brush new file mode 100755 index 0000000000000000000000000000000000000000..3b2aaee33de57c5792b24ec18af2c5fa52171e95 GIT binary patch literal 1676 zcwW7gO=#3m5Xb-d=(=DaL4;mJf+vxJk=!IS*=^Zc=(@6W4_+3%c#wj}AVOV=hk{to zz3Adea#|2X5j3z+L;~?v4@x~Pc#&WZiadDEWY-Uj%2n-`V=9LGE?($H1(fQ1DmP_WdjT_Tr*59s&%ZWu`*+72U@7c$zFQifsp8N1l# zN0B7B#vv>1TAfqjD5^`f=1O6!7S>lUUIylL1UQZVAzx0??@T*{-zX) zS#ZyQR&WC*DOX58XFjB`GMtv}GI!yn1y7+dkHyfL0ry3cB*lD922~r+y_Bw7hR5tP zxD4HsnbM2T^JB^+NyYTsq*LR`*QgJUoy3{Kb=?x2J1x{9`RSjQPbc-(GJOk`zYzVG z#g(pa0cW;!+&*}Ro^7M{Mg?|&tKS74oO_BuJr4v`+<4;Qp|OYcw<^@0g`4{uxOa90 zD>wx`uyAXC4R`$!?AI#nD;72nHn1~4LN)#Zo#I>H1O`VcsMyD#+YY*4-{blHJ?Kgs zbCm(QgA;i6se#St5%AcCLcPgOgMJn&f=+-}H1vM-5{ozqCF%p@TkLdc5g&gq?N56m FKLEc)ly3k4 literal 0 HcwPel00001 diff --git a/scalos/Prefs/MainPrefs/Images/plugins.c b/scalos/Prefs/MainPrefs/Images/plugins.c new file mode 100755 index 000000000..c8a5dcc7a --- /dev/null +++ b/scalos/Prefs/MainPrefs/Images/plugins.c @@ -0,0 +1,54 @@ +#ifdef USE_PLUGINS_COLORS +const ULONG plugins_colors[48] = +{ + 0x00000000,0xdddddddd,0x00000000, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0x33333333,0x77777777,0xaaaaaaaa, + 0xffffffff,0x00000000,0x00000000, + 0xaaaaaaaa,0x88888888,0x77777777, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0xaaaaaaaa,0xaaaaaaaa,0xbbbbbbbb, + 0xffffffff,0xaaaaaaaa,0x99999999, + 0xffffffff,0xffffffff,0xffffffff, + 0x77777777,0x77777777,0x77777777, + 0xeeeeeeee,0x00000000,0x99999999, + 0x00000000,0x88888888,0x00000000, + 0x00000000,0x00000000,0x00000000, + 0x00000000,0xcccccccc,0xcccccccc, + 0x00000000,0x66666666,0xffffffff, + 0x00000000,0x00000000,0xaaaaaaaa, +}; +#endif + +#define PLUGINS_WIDTH 23 +#define PLUGINS_HEIGHT 16 +#define PLUGINS_DEPTH 4 +#define PLUGINS_COMPRESSION 0 +#define PLUGINS_MASKING 2 + +#ifdef USE_PLUGINS_HEADER +const struct BitMapHeader plugins_header = +{ 23,16,0,0,4,2,0,0,0,44,44,320,256 }; +#endif + +#ifdef USE_PLUGINS_BODY +const UBYTE plugins_body[256] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff, +0xfc,0x00,0x6a,0x82,0x00,0x00,0x2a,0x82,0x04,0x00,0x7f,0xdf,0xd8,0x00,0x80, +0x20,0x20,0x00,0x41,0xca,0x02,0x00,0x00,0x8e,0x00,0x00,0x61,0xfa,0xfc,0x00, +0x9e,0x31,0xb6,0x00,0x40,0x02,0x3a,0x00,0x00,0x40,0x08,0x00,0x6f,0xb3,0x3c, +0x00,0x9f,0x0c,0xc6,0x00,0x54,0xd0,0x02,0x00,0x02,0x80,0x10,0x00,0x79,0xd7, +0x6c,0x00,0x8d,0x2f,0xe6,0x00,0x10,0x40,0x22,0x00,0x04,0x40,0x10,0x00,0x7b, +0xd7,0x4c,0x00,0x8b,0x3f,0xe6,0x00,0x20,0xc8,0x02,0x00,0x20,0x60,0x10,0x00, +0x7e,0xdf,0x6c,0x00,0x8e,0x17,0xe6,0x00,0x08,0xc0,0xf2,0x00,0x04,0x80,0x10, +0x00,0x4f,0xf8,0xfc,0x00,0xb0,0x07,0x06,0x00,0x06,0x20,0x12,0x00,0x04,0x20, +0x30,0x00,0x5e,0xf7,0xdc,0x00,0xb9,0x8f,0xc6,0x00,0x04,0x01,0x52,0x00,0x05, +0x06,0xb0,0x00,0x5e,0xb0,0x1c,0x00,0xb8,0xe9,0x46,0x00,0x7e,0xaa,0xa2,0x00, +0x00,0xa8,0x20,0x00,0x01,0xff,0xfc,0x00,0xff,0x55,0x46,0x00,0x80,0x00,0x02, +0x00,0x40,0x55,0x40,0x00,0xbf,0x00,0x3c,0x00,0x3f,0xaa,0xbe,0x00,0x3e,0x00, +0x1e,0x00,0x01,0xaa,0xa0,0x00,0x00,0x55,0x40,0x00,0x3e,0x55,0x5e,0x00,0x00, +0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xe0,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00, }; +#endif diff --git a/scalos/Prefs/MainPrefs/Images/rename.brush b/scalos/Prefs/MainPrefs/Images/rename.brush new file mode 100755 index 0000000000000000000000000000000000000000..bb16685e389dfc605bfe3bc32d5c26e38bfbb288 GIT binary patch literal 1900 zcwWVn&ui2`6vw~YY*~?!RP-b&>8jw5E)A@T;?~J-gSFt=QVQa&2idECf_vO^@v^rZ z%bt4oU|_F-6_3Kg9z9421VJ!nd^4FPUCEkS1qZ^*XFl^@W+sz7+1hCXl~x3A>xmUjmC|IJk-b(2RfVe`V9p=jpgO%-Ezo z3&S+V(>$KC@K5C9fFh%Eb*+u*__Y2=_LH|q+QXmmae&$UKlG}bd=P6rU6)WX3T)+B zeU$67d~qr-S1)~?=lVEe>iGtXPL*HeBO7Xe*hu91#xQ;Uu#xYJ@(Vl*P?z=1y2#JB zhfL*<_`G}`{wBZ3n_!VzAK~=1BgMMYh}3jom}z7>7W%(ztu2@Sg{4W+xU4PB;c0wuEXuww zDstK_E$5o z9}vID`0+;v%eDD_&GArupYi>D2e)3&_qP`v+!Gn!-S=?k%`so`XS`i=uqxzyZQ>8O z{qT$`AZt za}~e>o?xC7^%_E8d6~5sR)Y2}r35}9iXzz?Xkb7#QlpX5gA=WFuh;vA6TCBzLMgm4 zTQ>IEzA1&rc(l?EHtf1KkNvIf*T762EiB=`nc%s)*`N9^?x;djngCgr#x_nwTnWz* zJGolpIvbCTf{UyK=W)(?io|ettTS_t1MO766RpRNV?wxQTa$Jwk>~G9@R)Lm?H^L+ z+~qk}ssgTPgE=1(+=y_LHs`0YY~GdOu;0~~{r!cMO-=Jnsk*L)b8q6GCT!QlrS!a# z91~{hTdtHgIxVL;CX>8rKQ>>A$3=Zt>)5C$I0ar690iwB+PBA1N)?)x;cn6A-}XB{ zEuYr>omILE*~73+{-W@w?E})m2g^BxgfQ|2;l?&KoJMJ zIe;wj7eqodxi;d)1p?9r4!s!RDiRe!sW&aC2O|HRCasTCA(XgPlW*C`Mi)muWY+NFGNea8ZFb~1Cr)Zwhj;m zG~sq|641Ri(!}c|tDj-(@Qz|g9C(-pOyYIoO%9u9do(^QW79VCluXRyC1rX)&$v@( zKH8k#VgI<<^LIi!%70&^n2$IC-S>Ct8`wXfyTnI;_EC5vR9Ep$nfK${wjcl7Z9l$% z%Fpnm%Fh(G%8#tdFE;)lukt%=D1Rfc=YLl;ayb*JiH6z{rd_?cqO13xJnTwdR?0)! zi!Pw>@ACe9zUP&VZ#$; z6q@v4@Kd=*y~4-4Kdut)A?+Zc-@W5t+)WZb`R*p^U-6V)Y_fh~h49n3&3Xx)^tjz| zFo7)L+4m+n{v(U@`N2uj=aa0T2p=c?xt2}wb0b2-lE z)XJ9}=PQTu&t5Y(9L!y1{KYSZS-)H^5dO{0ZNk51Jh5W2e)H`cgkSw^m3zjgo?U1C zZ@2{tn0>&fkQ+^>ZR+*Y>zMek{F8%o zbk|84UT#>(rIs5Byo77?BE2eqZ_tLQArBk;RZ!M3oh-mOEdJxcw%nk zz$Uy!XG$AJNEpvM7SbD^JhTXZL}$v4GC^<^7?Hn9zGZ*-mw>LoaqHu!foJ3gF5jL* fzMB{vVC0?mc^p?lLxmYoM&-JQh0K3@7mQ-Xdw6U>w zVzo0UdBq#K<;d*ydZz)WcW};$C*c0gy%K%sx=3@>MHlyzDwL|i=oIxSTT(M5KWFXx^cnMy*@Kn**?w5b fpAOHy<$XQZa{V@1^d{%onfmyA%C%^svn~A>plYtz literal 0 HcwPel00001 diff --git a/scalos/Prefs/MainPrefs/Images/textwindows.c b/scalos/Prefs/MainPrefs/Images/textwindows.c new file mode 100755 index 000000000..3b53de834 --- /dev/null +++ b/scalos/Prefs/MainPrefs/Images/textwindows.c @@ -0,0 +1,51 @@ +#ifdef USE_TEXTWINDOWS_COLORS +const ULONG textwindows_colors[48] = +{ + 0x00000000,0x00000000,0x00000000, + 0xa0a0a0a0,0xa0a0a0a0,0xa0a0a0a0, + 0x33333333,0x77777777,0xaaaaaaaa, + 0xffffffff,0xeeeeeeee,0x00000000, + 0xaaaaaaaa,0xaaaaaaaa,0xaaaaaaaa, + 0xffffffff,0xffffffff,0xffffffff, + 0x77777777,0x77777777,0x77777777, + 0x66666666,0x22222222,0x00000000, + 0xffffffff,0x66666666,0x00000000, + 0xffffffff,0xaaaaaaaa,0x88888888, + 0xffffffff,0xeeeeeeee,0x00000000, + 0x00000000,0x88888888,0x00000000, + 0x00000000,0xdddddddd,0x00000000, + 0x00000000,0xcccccccc,0xcccccccc, + 0x00000000,0x66666666,0xffffffff, + 0x00000000,0x00000000,0xaaaaaaaa, +}; +#endif + +#define TEXTWINDOWS_WIDTH 23 +#define TEXTWINDOWS_HEIGHT 14 +#define TEXTWINDOWS_DEPTH 4 +#define TEXTWINDOWS_COMPRESSION 0 +#define TEXTWINDOWS_MASKING 2 + +#ifdef USE_TEXTWINDOWS_HEADER +const struct BitMapHeader textwindows_header = +{ 23,14,0,0,4,2,0,0,8,22,44,640,256 }; +#endif + +#ifdef USE_TEXTWINDOWS_BODY +const UBYTE textwindows_body[224] = { +0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xf8,0x00,0x00,0x00,0x07, +0xff,0x90,0x00,0x90,0x00,0x6f,0xfe,0x48,0x00,0x90,0x00,0x90,0x00,0x00,0x00, +0x03,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x80,0x00,0x02,0x00,0x00, +0x00,0x01,0xff,0x80,0x00,0x08,0x00,0x00,0x00,0x02,0x00,0xbf,0xff,0xfa,0x00, +0x00,0x00,0x01,0xff,0x80,0x00,0x08,0x00,0x00,0x00,0x02,0x00,0xa1,0x04,0x1a, +0x00,0x00,0x00,0x01,0xff,0x80,0x00,0x08,0x00,0x00,0x00,0x02,0x00,0xbf,0xff, +0xfa,0x00,0x00,0x00,0x01,0xff,0x80,0x00,0x08,0x00,0x00,0x00,0x02,0x00,0xa7, +0x0c,0x7a,0x00,0x00,0x00,0x01,0xff,0x80,0x00,0x08,0x00,0x00,0x00,0x02,0x00, +0xbf,0xff,0xfa,0x00,0x00,0x00,0x01,0xff,0x80,0x00,0x08,0x00,0x00,0x00,0x02, +0x00,0xa3,0x1c,0x3a,0x00,0x00,0x00,0x01,0xff,0x80,0x00,0x08,0x00,0x00,0x00, +0x02,0x00,0xbf,0xff,0xfa,0x00,0x00,0x00,0x01,0xff,0xbf,0xff,0xf8,0x00,0x00, +0x00,0x02,0x00,0xbf,0xff,0xfa,0x00,0x00,0x00,0x01,0xff,0x80,0x00,0x10,0x00, +0x7f,0xff,0xea,0x00,0x80,0x00,0x12,0x00,0x00,0x00,0x01,0xff,0x80,0x00,0x00, +0x00,0x00,0x00,0x02,0x00,0x80,0x00,0x02,0x00,0x00,0x00,0x01,0xff,0x00,0x00, +0x00,0x00,0x7f,0xff,0xfe,0x00,0x7f,0xff,0xfe,0x00,0x80,0x00,0x01,0xff, }; +#endif diff --git a/scalos/Prefs/MainPrefs/Images/windows.brush b/scalos/Prefs/MainPrefs/Images/windows.brush new file mode 100755 index 0000000000000000000000000000000000000000..bfb9248cf6c42c5c2dc6bdac85fa0e5616144853 GIT binary patch literal 1676 zcwV)Yv1-Cl6o&s88wwTbP$=C?>EICPDwss66`ES4i!abu$ktlu(6MVa=R8DJTm|P+ z`U(>0;t;$&=Xy07u?8A{4JY6I;yniv;&rp-0>*3O)^Q#8rUu{yrzlcIK8FraDruI6 zs%ziVk|`$WcDq+zAOPR@gCG!rFNE+sZvvlx^#*(cqY)nIlAzwQ9o`B@IIP-kU7qKP zcxc?UfrC6OTw>1=oc?A_>xb%)>tW0ky$Ih!by(|LWE*ng<@&&Y4-uhZR2ops_AttrList ) )) + { + return(0); + } + + DEBUGLOG(printf("OM_NEW, getting any tag values...\n");) + + // --- Set Any Tags Found At Creation Time + tags = msg->ops_AttrList; + data->iMouseOver = 0; + data->Item = (struct PanelItem *)GetTagData(MUIA_RollOver_ItemInfo, NULL, tags); + data->app = (struct MUIApp *)GetTagData(MUIA_RollOver_AppStruct, NULL, tags); + + return((ULONG)obj); +} + + + + +SAVEDS(ULONG) ASM RollOverImageDispatcher(REG(a0, struct IClass *cl), REG(a2, Object *obj), REG(a1, Msg msg)) +{ + switch (msg->MethodID) + { + case OM_NEW : return(mRollover_New (cl, obj, (APTR)msg)); + case OM_SET : return(mRollover_Set (cl, obj, (APTR)msg)); + case MUIM_RollOver_Execute : return(mRollover_Execute (cl, obj, (APTR)msg)); + case MUIM_Setup : return(mRollover_Setup (cl, obj, (APTR)msg)); + case MUIM_Cleanup : return(mRollover_Cleanup (cl, obj, (APTR)msg)); + case MUIM_HandleEvent : return(mRollover_HandleEvent (cl, obj, (APTR)msg)); + + // --- This sub-class doesn't support the method sent, so pass it up to + // its parent class. + default : return(DoSuperMethodA (cl, obj, msg)); + } +} \ No newline at end of file diff --git a/scalos/Prefs/MainPrefs/MCPFrame_mcc.h b/scalos/Prefs/MainPrefs/MCPFrame_mcc.h new file mode 100644 index 000000000..03ec5f947 --- /dev/null +++ b/scalos/Prefs/MainPrefs/MCPFrame_mcc.h @@ -0,0 +1,43 @@ +// MCPFrame_mcc.h +// $Date$ + + +#ifndef MUI_MCPFRAME_H +#define MUI_MCPFRAME_H + +#ifndef EXEC_TYPES_H +#include +#endif + +#ifndef UTILITY_TAGITEM_H +#include +#endif + +#define MUIC_MCPFrame "MCPFrame.mcc" + +#ifdef __AROS__ +#define McpFrameObject BOOPSIOBJMACRO_START(McpFrameClass->mcc_Class) +#else +#define McpFrameObject NewObject(McpFrameClass->mcc_Class, 0 +#endif + + +#define MUIA_MCPFrame_FrameType 0x804d0009 /* isg LONG */ +#define MUIA_MCPFrame_Unknown 0x804d0008 /* isg LONG */ + + +/* Types of frames available */ +#define MCP_FRAME_NONE 0 /* No frame */ +#define MCP_FRAME_BUTTON 1 /* Standard 3D frame used for buttons */ +#define MCP_FRAME_BORDER 2 /* Standard 2D frame used for */ +#define MCP_FRAME_STRING 3 /* String */ +#define MCP_FRAME_DROPBOX 4 /* Dropbox [String (with space)?] */ +#define MCP_FRAME_XEN 5 /* Standard XEN button */ +#define MCP_FRAME_MWB 6 /* Standard MWB */ +#define MCP_FRAME_THICK 7 /* Standard Thick */ +#define MCP_FRAME_XWIN 8 /* Standard XWIN */ +#define MCP_FRAME_MAXIMUM 9 /* Maximum number of frame types */ + +#define MCP_FRAME_RECESSED 0x8000 + +#endif /* MUI_MCPFRAME_H */ diff --git a/scalos/Prefs/MainPrefs/Makefile b/scalos/Prefs/MainPrefs/Makefile new file mode 100755 index 000000000..689da5dd3 --- /dev/null +++ b/scalos/Prefs/MainPrefs/Makefile @@ -0,0 +1,204 @@ +# makefile for Scalos main preferences +# $Date$ +# $Revision$ +# using SAS/C + +############################################################# + +SUBDIRMAKE = $(MAKE) -s -C + +############################################################# + +.PHONY: clean install nodebug + +############################################################# + +SDPATH = / + +SVNVERSION = $(shell svnversion -n) +CC = sc +CFLAGS = nostkchk nochkabort dbg=f nover streq \ + data=far code=far strmer stringsection=far \ + memorysize=huge \ + define SVN_VERSION=$(SVNVERSION) \ + define SCALOSLOCALE=$(SCALOS_LOCALE) \ + idlen=68 idir=//include \ + idir=$(subst ../,/,$(FONTSAMPLEMCC_DIR)) \ + idir=$(subst ../,/,$(DATATYPESMCC_DIR)) \ + idir=$(subst ../,/,$(MCPGFX_DIR)) + +SPLAT = sc:c/splat +AS = phxass +AFLAGS = quiet noexe m=68020 opt=NRQB i=sc:Assembler_Headers/ +LD = slink +LDFLAGS = quiet batch noicons +LDLIBS = LIB:mempools.lib \ + //SAS-lib/snprintf.lib \ + LIB:scm.lib \ + LIB:sc.lib \ + LIB:debug.lib \ + LIB:amiga.lib +CSTARTUP = LIB:c.o +OBJDIR = .sasobj +CATCOMP = CatComp +FLEXCAT = FlexCat +FONTSAMPLEMCC_DIR = ../../common/FontSampleMCC +DATATYPESMCC_DIR = ../../common/DataTypesMCC +MCPGFX_DIR = ../../common/McpGfx +SCALOSINCDIR = ../../include/scalos + +SCALOS_LOCALE = $(OBJDIR)/ScalosPrefs_locale.h + +############################################################# + +CSRCS = \ + Hooks.c \ + PrefsPlugins.c \ + ReadWritePrefs.c \ + HiddenDevices.c \ + $(DATATYPESMCC_DIR)/DataTypesMCC.c \ + $(FONTSAMPLEMCC_DIR)/FontSampleMCC.c \ + Images.c \ + McpFrameMCC.c \ + SelectMarkSampleClass.c \ + Scalos.c \ + PrefsVersion.c \ + $(MCPGFX_DIR)/ScalosMcpGfx.c \ + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +XSRCS = $(notdir $(CSRCS)) +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(XSRCS:%.c=$(OBJDIR)/$(notdir %).o) + +############################################################# + +NAME = .bin_os3/Scalos_Prefs +NAMEDBG = $(NAME).debug +CAT_FILE = Scalos/Scalos_Prefs.catalog +CATCOMPHEADER = $(SCALOS_LOCALE) +DESTTOOL = Scalos:Prefs/Scalos Prefs +DESTCAT = Locale:Catalogs +CATS = deutsch \ + français + +ALLCATS = $(foreach cat,$(CATS),catalogs/$(cat)/$(CAT_FILE)) + +############################################################# + +all: $(NAME) $(NAMEDBG) allcatalogs +# install +# clean +# launch + +############################################################# + +# commands generated a catalog (.catalog) from a catalog translation (.ct) file. +.ct.catalog: + $(CATCOMP) $*.cd $< CATALOG $*.catalog VB=1 + +$(OBJDIR)/DataTypesMCC.o : $(DATATYPESMCC_DIR)/DataTypesMCC.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/FontSampleMCC.o : $(FONTSAMPLEMCC_DIR)/FontSampleMCC.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/ScalosMcpGfx.o : $(MCPGFX_DIR)/ScalosMcpGfx.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $< objectname $@ + +############################################################# + +$(NAME) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LDLIBS) $(LDFLAGS) STRIPDEBUG + +$(NAMEDBG) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LDLIBS) $(LDFLAGS) ADDSYM + +############################################################# + +$(OBJDIR)/DataTypesMCC.o: $(DATATYPESMCC_DIR)/DataTypesMCC.c \ + $(DATATYPESMCC_DIR)/DataTypesMCC.h $(SCALOSINCDIR)/scalos.h + +$(OBJDIR)/McpFrameMCC.o : McpFrameMCC.c McpFrameMCC.h MCPFrame_mcc.h + +$(OBJDIR)/SelectMarkSampleClass.o : SelectMarkSampleClass.c SelectMarkSampleClass.h + +$(OBJDIR)/FontSampleMCC.o : $(FONTSAMPLEMCC_DIR)/FontSampleMCC.c \ + $(FONTSAMPLEMCC_DIR)/FontSampleMCC.h $(SCALOSINCDIR)/scalos.h + +$(OBJDIR)/Hooks.o: Hooks.c Hooks.h General.h ScalosPrefs.h $(SCALOS_LOCALE) \ + PrefsPlugins.h HiddenDevices.h $(DATATYPESMCC_DIR)/DataTypesMCC.h \ + $(FONTSAMPLEMCC_DIR)/FontSampleMCC.h $(SCALOSINCDIR)/scalos.h + +$(OBJDIR)/Images.o : Images.c Images.h General.h \ + $(DATATYPESMCC_DIR)/DataTypesMCC.h ScalosPrefs.h $(SCALOSINCDIR)/scalos.h + +$(OBJDIR)/PrefsPlugins.o : PrefsPlugins.c PrefsPlugins.h \ + ScalosPrefs.h $(SCALOSINCDIR)/scalos.h + +$(OBJDIR)/HiddenDevices.o : HiddenDevices.c HiddenDevices.h \ + ScalosPrefs.h $(SCALOSINCDIR)/scalos.h + +$(OBJDIR)/ReadWritePrefs.o: ReadWritePrefs.c ReadWritePrefs.h \ + ScalosPrefs.h HiddenDevices.h \ + $(FONTSAMPLEMCC_DIR)/FontSampleMCC.h $(SCALOSINCDIR)/scalos.h + +$(OBJDIR)/Scalos.o: Scalos.c General.h ScalosPrefs.h \ + ReadWritePrefs.h $(DATATYPESMCC_DIR)/DataTypesMCC.h \ + McpFrameMCC.h $(FONTSAMPLEMCC_DIR)/FontSampleMCC.h \ + $(SCALOSINCDIR)/scalos.h \ + HiddenDevices.h Hooks.h $(SCALOS_LOCALE) \ + SelectMarkSampleClass.h + + +$(OBJDIR)/PrefsVersion.o: PrefsVersion.c FORCE + +FORCE: + +############################################################# + +$(CATCOMPHEADER) : Scalos_Prefs.cd + @printf '\033[32mCatcomp header: \033[31m\033[1m$@ \033[32mfrom \033[31m$<\033[0m\n' + $(FLEXCAT) $(subst ../,/,$<) $@=$(SDPATH)/CatComp_h.sd + +############################################################# + +# copy all generated file to their final destinations +install: + @printf '\033[32mInstall: \033[31m\033[1m$(NAME)\033[0m\n' + @copy $(NAME) '$(DESTTOOL)' + @printf '\033[32mInstall: \033[31m\033[1m$(CAT_FILE)\033[0m\n' + -@$(foreach cat,$(CATS),copy "catalogs/$(cat)/$(CAT_FILE)" "$(DESTCAT)/$(cat)/Scalos" clone;) + +############################################################# + +# make all Scalos .catalogs +allcatalogs: + -@$(foreach cat,$(CATS),$(SUBDIRMAKE) catalogs/$(cat)/Scalos;) + +############################################################# + +# A little something to clean it all up +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + -@delete $(OBJS) $(NAME) $(NAMEDBG) $(CATCOMPHEADER) $(ALLCATS) + @printf '\033[0m' + +############################################################# + +nodebug: + -@$(SPLAT) -s -o "d2(" "d1(" "#?.c" + +############################################################# + diff --git a/scalos/Prefs/MainPrefs/McpFrameMCC.c b/scalos/Prefs/MainPrefs/McpFrameMCC.c new file mode 100644 index 000000000..bad8a942a --- /dev/null +++ b/scalos/Prefs/MainPrefs/McpFrameMCC.c @@ -0,0 +1,335 @@ +// McpFrameMCC.c +// $Date$ + + +#include +#include +#include +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include +#include +#define NO_INLINE_STDARG +#include + +#include +#include + +#include +#include "McpFrameMCC.h" +#include +#include "ScalosPrefs.h" + +#ifdef __AROS__ +// FIXME: temporary fix until we have figured out +// how to deal with these deprecated defines. +#define IA_ShadowPen (IA_Dummy + 0x09) +#define IA_HighlightPen (IA_Dummy + 0x0A) +#endif + +// ------------------------------------------------------------------------- + +#define CLASS MUIC_MCPFrame +#define SUPERCLASS MUIC_Area + +struct McpFrameMCCInstance +{ + struct Library *dtbase; + + UWORD FrameType; + BOOL Recessed; +}; + +// ------------------------------------------------------------------------- + +static ULONG mNew(Class *cl, Object *o, struct opSet *ops); +static ULONG mDispose(Class *cl, Object *o,Msg msg); +static ULONG mSet(Class *cl, Object *o, struct opSet *ops); +static ULONG mGet(Class *cl, Object *o, struct opGet *opg); +static ULONG mAskMinMax(Class *cl, Object *o,struct MUIP_AskMinMax *msg); +static ULONG mDraw(Class *cl, Object *o,struct MUIP_Draw *msg); +static ULONG mDragQuery(Class *cl, Object *o, struct MUIP_DragQuery *msg); +static ULONG mDragDrop(Class *cl, Object *o, struct MUIP_DragDrop *msg); +DISPATCHER_PROTO(McpFrameMCC); + +// ------------------------------------------------------------------------- + +static ULONG mNew(Class *cl, Object *o, struct opSet *ops) +{ + struct McpFrameMCCInstance *inst = NULL; + BOOL Success = FALSE; + + do { + o = (Object *) DoSuperMethodA(cl, o, (Msg) ops); + if (NULL == o) + break; + + inst = INST_DATA(cl,o); + + memset(inst, 0, sizeof(struct McpFrameMCCInstance)); + + inst->FrameType = GetTagData(MUIA_MCPFrame_FrameType, MCP_FRAME_NONE, ops->ops_AttrList); + + inst->Recessed = (inst->FrameType & MCP_FRAME_RECESSED) ? TRUE : FALSE; + inst->FrameType &= ~MCP_FRAME_RECESSED; + + d1(KPrintF(__FUNC__ "/%ld: FrameType=%ld Recessed=%ld\n", __LINE__, inst->FrameType, inst->Recessed)); + + Success = TRUE; + } while (0); + + if (!Success && o) + { + mDispose(cl, o, (Msg) ops); + o = NULL; + } + + return((ULONG)o); +} + +// ------------------------------------------------------------------------- + +static ULONG mDispose(Class *cl, Object *o, Msg msg) +{ +// struct McpFrameMCCInstance *inst = INST_DATA(cl,o); + + return DoSuperMethodA(cl, o, msg); +} + +// ------------------------------------------------------------------------- + +static ULONG mSet(Class *cl, Object *o, struct opSet *ops) +{ + struct McpFrameMCCInstance *inst = INST_DATA(cl,o); + + if (FindTagItem(MUIA_MCPFrame_FrameType, ops->ops_AttrList)) + { + inst->FrameType = GetTagData(MUIA_MCPFrame_FrameType, + inst->FrameType | (inst->Recessed ? MCP_FRAME_RECESSED : 0), + ops->ops_AttrList); + + inst->Recessed = (inst->FrameType & MCP_FRAME_RECESSED) ? TRUE : FALSE; + inst->FrameType &= ~MCP_FRAME_RECESSED; + + MUI_Redraw(o, MADF_DRAWOBJECT); + } + + return DoSuperMethodA(cl, o, (Msg) ops); +} + +// ------------------------------------------------------------------------- + +static ULONG mGet(Class *cl, Object *o, struct opGet *opg) +{ + struct McpFrameMCCInstance *inst = INST_DATA(cl,o); + ULONG Result; + + switch (opg->opg_AttrID) + { + case MUIA_MCPFrame_FrameType: + *opg->opg_Storage = inst->FrameType | (inst->Recessed ? MCP_FRAME_RECESSED : 0); + Result = 1; + break; + default: + Result = DoSuperMethodA(cl, o, (Msg) opg); + break; + } + + return Result; +} + +// ------------------------------------------------------------------------- + +static ULONG mAskMinMax(Class *cl, Object *o,struct MUIP_AskMinMax *msg) +{ + struct McpFrameMCCInstance *inst = INST_DATA(cl,o); + struct MUI_MinMax *mi; + const struct FrameSize *fs; + + d1(KPrintF(__FILE__ "/%s/%ld: START\n", __FUNC__, __LINE__)); + + DoSuperMethodA(cl, o, (Msg) msg); + + fs = McpGetFrameSize(inst->FrameType); + + mi = msg->MinMaxInfo; + + d1(KPrintF(__FUNC__ "/%ld: mi=%08lx fs=%08lx FrameType=%04lx\n", __LINE__, mi, fs, inst->FrameType)); + + if (fs) + { + LONG fsWidth; + LONG fsHeight; + + if (inst->Recessed) + { + fsWidth = fs->fs_Sizes[FRAMESIZE_RELEFT] + fs->fs_Sizes[FRAMESIZE_RERIGHT] + 6; + fsHeight = fs->fs_Sizes[FRAMESIZE_RETOP] + fs->fs_Sizes[FRAMESIZE_REBOTTOM] + 6; + } + else + { + fsWidth = fs->fs_Sizes[FRAMESIZE_LEFT] + fs->fs_Sizes[FRAMESIZE_RIGHT] + 6; + fsHeight = fs->fs_Sizes[FRAMESIZE_TOP] + fs->fs_Sizes[FRAMESIZE_BOTTOM] + 6; + } + + d1(KPrintF(__FUNC__ "/%ld: fsWidth=%ld fsHeight=%ld\n", __LINE__, fsWidth, fsHeight)); + + mi->MaxWidth = MUI_MAXMAX; + mi->MaxHeight = MUI_MAXMAX; + + mi->MinWidth += fsWidth; + mi->MaxWidth -= fsWidth; + mi->DefWidth += fsWidth; + + mi->MinHeight += fsHeight; + mi->MaxHeight -= fsHeight; + mi->DefHeight += fsHeight; + } + + d1(KPrintF(__FUNC__ "/%ld: fd=%08lx MinW=%ld MaxW=%ld MinH=%ld MaxH=%ld DefW=%ld DefH=%ld\n", \ + __LINE__, fs, mi->MinWidth, mi->MaxWidth, mi->MinHeight, mi->MaxHeight, mi->DefWidth, mi->DefHeight)); + d1(KPrintF(__FILE__ "/%s/%ld: END\n", __FUNC__, __LINE__)); + + return 0; +} + +// ------------------------------------------------------------------------- + +static ULONG mDraw(Class *cl, Object *o,struct MUIP_Draw *msg) +{ + struct McpFrameMCCInstance *inst = INST_DATA(cl,o); + + DoSuperMethodA(cl, o, (Msg) msg); + + if (msg->flags & MADF_DRAWOBJECT) + { + McpGfxDrawFrame(_rp(o), + _mleft(o), _mtop(o), + _mright(o), _mbottom(o), + IA_FrameType, inst->FrameType, + IA_Recessed, inst->Recessed, + IA_HighlightPen, _pens(o)[MPEN_SHINE], + IA_ShadowPen, _pens(o)[MPEN_SHADOW], + IA_BGPen, _pens(o)[MPEN_BACKGROUND], + IA_HalfShinePen, _pens(o)[MPEN_HALFSHINE], + IA_HalfShadowPen, _pens(o)[MPEN_HALFSHADOW], + TAG_END); + } + + return 0; +} + +// ------------------------------------------------------------------------- + +static ULONG mDragQuery(Class *cl, Object *o, struct MUIP_DragQuery *drq) +{ +// struct McpFrameMCCInstance *inst = INST_DATA(cl,o); + + if (drq->obj == o) + return DoSuperMethodA(cl, o, (Msg) drq); + + if (OCLASS(o) == cl) + { + return MUIV_DragQuery_Accept; + } + + return DoSuperMethodA(cl, o, (Msg) drq); +} + +// ------------------------------------------------------------------------- + +static ULONG mDragDrop(Class *cl, Object *o, struct MUIP_DragDrop *msg) +{ +// struct McpFrameMCCInstance *inst = INST_DATA(cl,o); + + if (msg->obj != o) + { + ULONG FrameType = 0; + + get(msg->obj, MUIA_MCPFrame_FrameType, &FrameType); + SetAttrs(o, + MUIA_MCPFrame_FrameType, FrameType, + TAG_END); + } + + return DoSuperMethodA(cl, o, (Msg) msg); +} + +// ------------------------------------------------------------------------- + +DISPATCHER(McpFrameMCC) +{ + ULONG Result; + + switch (msg->MethodID) + { + case OM_NEW: + d1(kprintf(__FUNC__ "/%ld: OM_NEW\n", __LINE__)); + Result = mNew(cl, obj, (struct opSet *) msg); + break; + + case OM_DISPOSE: + d1(kprintf(__FUNC__ "/%ld: OM_DISPOSE\n", __LINE__)); + Result = mDispose(cl, obj, msg); + break; + + case OM_SET: + d1(kprintf(__FUNC__ "/%ld: OM_SET\n", __LINE__)); + Result = mSet(cl, obj, (struct opSet *) msg); + break; + + case OM_GET: + d1(kprintf(__FUNC__ "/%ld: OM_GET\n", __LINE__)); + Result = mGet(cl, obj, (struct opGet *) msg); + break; + + case MUIM_AskMinMax: + d1(kprintf(__FUNC__ "/%ld: MUIM_AskMinMax\n", __LINE__)); + Result = mAskMinMax(cl, obj, (struct MUIP_AskMinMax *) msg); + break; + + case MUIM_Draw: + d1(kprintf(__FUNC__ "/%ld: MUIM_Draw\n", __LINE__)); + Result = mDraw(cl, obj, (struct MUIP_Draw *) msg); + break; + + case MUIM_DragQuery: + d1(KPrintF(__FUNC__ "/%ld: MUIM_DragQuery\n", __LINE__)); + Result = mDragQuery(cl, obj, (struct MUIP_DragQuery *) msg); + break; + + case MUIM_DragDrop: + d1(KPrintF(__FUNC__ "/%ld: MUIM_DragDrop\n", __LINE__)); + Result = mDragDrop(cl, obj, (struct MUIP_DragDrop *) msg); + break; + + default: + d1(KPrintF(__FUNC__ "/%ld: MethodID=%08lx\n", __LINE__, msg->MethodID)); + Result = DoSuperMethodA(cl, obj, msg); + break; + } + + return Result; +} +DISPATCHER_END + +/* ------------------------------------------------------------------------- */ + +struct MUI_CustomClass *InitMcpFrameClass(void) +{ + return MUI_CreateCustomClass(NULL, SUPERCLASS, NULL, sizeof(struct McpFrameMCCInstance), DISPATCHER_REF(McpFrameMCC)); +} + +void CleanupMcpFrameClass(struct MUI_CustomClass *mcc) +{ + MUI_DeleteCustomClass(mcc); +} + +// ------------------------------------------------------------------------- + diff --git a/scalos/Prefs/MainPrefs/McpFrameMCC.h b/scalos/Prefs/MainPrefs/McpFrameMCC.h new file mode 100644 index 000000000..5c83ebd2f --- /dev/null +++ b/scalos/Prefs/MainPrefs/McpFrameMCC.h @@ -0,0 +1,25 @@ +// McpFrameMCC.h +// $Date$ +// $Revision$ + + +#ifndef MCPFRAME_MCC_H +#define MCPFRAME_MCC_H + +/* ------------------------------------------------------------------------- */ + +#include +#include "MCPFrame_mcc.h" + +/* ------------------------------------------------------------------------- */ + +struct MUI_CustomClass *InitMcpFrameClass(void); +void CleanupMcpFrameClass(struct MUI_CustomClass *mcc); + +/* ------------------------------------------------------------------------- */ + +extern struct MUI_CustomClass *MccFrameClass; + +/* ------------------------------------------------------------------------- */ + +#endif /* MCPFRAME_MCC_H */ diff --git a/scalos/Prefs/MainPrefs/NoDebug b/scalos/Prefs/MainPrefs/NoDebug new file mode 100755 index 000000000..49ed68d29 --- /dev/null +++ b/scalos/Prefs/MainPrefs/NoDebug @@ -0,0 +1,3 @@ +; NoDebug +; 23 Dec 2001 16:17:11 +splat -s -o "d2(" "d1(" #?.c diff --git a/scalos/Prefs/MainPrefs/PrefsPlugins.c b/scalos/Prefs/MainPrefs/PrefsPlugins.c new file mode 100644 index 000000000..db1b228bd --- /dev/null +++ b/scalos/Prefs/MainPrefs/PrefsPlugins.c @@ -0,0 +1,508 @@ +// PrefsPlugins.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define NO_INLINE_STDARG +#include + +#include + +#include + +#include "General.h" +#include "ScalosPrefs.h" +#include "PrefsPlugins.h" + +//----------------------------------------------------------------- + +struct PrefsPlugin +{ + struct Node ppl_Node; + + struct Library *ppl_PluginBase; +#ifdef __amigaos4__ + struct Interface *ppl_IPlugin; +#endif + + struct MUI_CustomClass *ppl_PluginClass; + STRPTR ppl_TitleString; + + ULONG ppl_PageNumber; // Page ordinal number + + ULONG ppl_TitleImageIndex; + Object *ppl_TitleImage; + Object *ppl_GroupObject; // is disposed by us, since it is added as child... + + Object **ppl_SubWindows; // NULL terminated array of SubWindow objects +}; + +//---------------------------------------------------------------------------- + +static struct List PrefsPluginList; +static ULONG PrefsPluginCount; +struct TagItem *SubWindowTagList; + +//---------------------------------------------------------------------------- + +static struct MUI_CustomClass *OpenPrefsModule(struct SCAModule *app, CONST_STRPTR FileName); +static void DisposePrefsPlugin(struct PrefsPlugin *ppl); +static Object *CreatePrefsTitleImage(void *UserData); + +//---------------------------------------------------------------------------- + + +BOOL PrefsPluginsInit(void) +{ + NewList(&PrefsPluginList); + + return TRUE; +} + +void PrefsPluginsCleanup(void) +{ + struct PrefsPlugin *ppl; + + while ((ppl = (struct PrefsPlugin *) RemTail(&PrefsPluginList))) + { + DisposePrefsPlugin(ppl); + } + + if (SubWindowTagList) + { + free(SubWindowTagList); + SubWindowTagList = NULL; + } +} + + +ULONG DoMethodForAllPrefsPlugins(ULONG ArgsCount, ULONG MethodID, ...) +{ + va_list ap; + ULONG result = 0; + ULONG *ArgArray; + + ArgArray = calloc(sizeof(ULONG), ArgsCount); + if (ArgArray) + { + struct PrefsPlugin *ppl; + ULONG n; + + va_start(ap, MethodID); + + ArgArray[0] = MethodID; + for (n = 1; n < ArgsCount; n++) + { + ArgArray[n] = va_arg(ap, ULONG); + } + + for (ppl = (struct PrefsPlugin *) PrefsPluginList.lh_Head; + ppl != (struct PrefsPlugin *) &PrefsPluginList.lh_Tail; + ppl = (struct PrefsPlugin *) ppl->ppl_Node.ln_Succ) + { + DoMethodA(ppl->ppl_GroupObject, (Msg) ArgArray); + } + + free(ArgArray); + } + + va_end(ap); + + return result; +} + +void SetAttributeForAllPrefsPlugins(ULONG Attribute, ULONG Value) +{ + struct PrefsPlugin *ppl; + + for (ppl = (struct PrefsPlugin *) PrefsPluginList.lh_Head; + ppl != (struct PrefsPlugin *) &PrefsPluginList.lh_Tail; + ppl = (struct PrefsPlugin *) ppl->ppl_Node.ln_Succ) + { + set(ppl->ppl_GroupObject, Attribute, Value); + } +} + + +void NotifyPrefsPluginsPageChange(ULONG ActivePage) +{ + struct PrefsPlugin *ppl; + + for (ppl = (struct PrefsPlugin *) PrefsPluginList.lh_Head; + ppl != (struct PrefsPlugin *) &PrefsPluginList.lh_Tail; + ppl = (struct PrefsPlugin *) ppl->ppl_Node.ln_Succ) + { + DoMethod(ppl->ppl_GroupObject, MUIM_ScalosPrefs_PageActive, ActivePage == ppl->ppl_PageNumber); + } +} + + +BOOL CheckMCCsForAllPrefsPlugins(void) +{ + struct PrefsPlugin *ppl; + + for (ppl = (struct PrefsPlugin *) PrefsPluginList.lh_Head; + ppl != (struct PrefsPlugin *) &PrefsPluginList.lh_Tail; + ppl = (struct PrefsPlugin *) ppl->ppl_Node.ln_Succ) + { + const struct MUIP_ScalosPrefs_MCCList *RequiredMccList = NULL; + + RequiredMccList = (const struct MUIP_ScalosPrefs_MCCList *) DoMethod(ppl->ppl_GroupObject, MUIM_ScalosPrefs_GetListOfMCCs); + + while (RequiredMccList && RequiredMccList->MccName) + { + if (!CheckMCCVersion(RequiredMccList->MccName, + RequiredMccList->MccMinVersion, + RequiredMccList->MccMinRevision)) + return FALSE; + + RequiredMccList++; + } + } + + return TRUE; +} + + +void CollectPrefsPlugins(struct SCAModule *app, CONST_STRPTR Path, CONST_STRPTR Pattern) +{ + STRPTR PatternBuffer; + struct FileInfoBlock *fib = NULL; + BPTR DirLock = (BPTR)NULL; + + do { + size_t Length; + + Length = 1 + 2 + 2 * strlen(Pattern); + PatternBuffer = malloc(Length); + d1(kprintf(__FUNC__ "/%ld: PatternBuffer=%08lx\n", __LINE__, PatternBuffer)); + if (NULL == PatternBuffer) + break; + + if (ParsePatternNoCase(Pattern, PatternBuffer, Length) < 0) + break; + + d1(kprintf(__FUNC__ "/%ld: ParsePatternNoCase success Pattern=<%s> PatternBuffer=<%s>\n", \ + __LINE__, Pattern, PatternBuffer)); + + fib = AllocDosObject(DOS_FIB, NULL); + if (NULL == fib) + break; + + DirLock = Lock(Path, ACCESS_READ); + if ((BPTR)NULL== DirLock) + break; + + if (!Examine(DirLock, fib)) + break; + + while (ExNext(DirLock, fib)) + { + d1(kprintf(__FUNC__ "/%ld: filename=<%s>\n", __LINE__, fib->fib_FileName)); + + if (MatchPatternNoCase(PatternBuffer, fib->fib_FileName)) + { + d1(kprintf(__FUNC__ "/%ld: add prefs plugin <%s>\n", __LINE__, fib->fib_FileName)); + OpenPrefsModule(app, fib->fib_FileName); + } + } + } while (0); + + d1(kprintf(__FUNC__ "/%ld: finished\n", __LINE__)); + + if (DirLock) + UnLock(DirLock); + if (fib) + FreeDosObject(DOS_FIB, fib); + if (PatternBuffer) + free(PatternBuffer); +} + + +void CreatePrefsPlugins(struct SCAModule *app) +{ + struct PrefsPlugin *ppl; + + for (ppl = (struct PrefsPlugin *) PrefsPluginList.lh_Head; + ppl != (struct PrefsPlugin *) &PrefsPluginList.lh_Tail; + ppl = (struct PrefsPlugin *) ppl->ppl_Node.ln_Succ) + { + d1(kprintf(__FUNC__ "/%ld: fCreateIcons=%ld ProgramName=<%s>\n", __LINE__, fCreateIcons, ProgramName)); + + ppl->ppl_GroupObject = NewObject(ppl->ppl_PluginClass->mcc_Class, 0, + TAG_END); + + if (ppl->ppl_GroupObject) + { + PrefsPluginCount++; + + ppl->ppl_SubWindows = (Object **) DoMethod(ppl->ppl_GroupObject, MUIM_ScalosPrefs_CreateSubWindows); + } + + d1(kprintf(__FUNC__ "/%ld: obj=%08lx\n", __LINE__, ppl->ppl_GroupObject)); + } +} + + +void InsertPrefsPlugins(struct SCAModule *app, Object *pageGroup, Object *pageList) +{ + if (DoMethod(pageGroup, MUIM_Group_InitChange)) + { + struct PrefsPlugin *ppl; + + for (ppl = (struct PrefsPlugin *) PrefsPluginList.lh_Head; + ppl != (struct PrefsPlugin *) &PrefsPluginList.lh_Tail; + ppl = (struct PrefsPlugin *) ppl->ppl_Node.ln_Succ) + { + d1(kprintf(__FUNC__ "/%ld: fCreateIcons=%ld ProgramName=<%s>\n", __LINE__, fCreateIcons, ProgramName)); + + d1(kprintf(__FUNC__ "/%ld: obj=%08lx\n", __LINE__, ppl->ppl_GroupObject)); + + ppl->ppl_PageNumber = 0; + + if (ppl->ppl_GroupObject) + { + struct NewPageListEntry nple; + Object *NewPage; + + set(ppl->ppl_GroupObject, MUIA_ScalosPrefs_MainWindow, (ULONG) app->Obj[WINDOW_MAIN]); + set(ppl->ppl_GroupObject, MUIA_ScalosPrefs_Application, (ULONG) app->Obj[APPLICATION]); + set(ppl->ppl_GroupObject, MUIA_ScalosPrefs_CreateIcons, fCreateIcons); + set(ppl->ppl_GroupObject, MUIA_ScalosPrefs_ProgramName, (ULONG) ProgramName); +// set(ppl->ppl_GroupObject, MUIA_Background, MUII_PageBack); + + get(pageList, MUIA_NList_Entries, &ppl->ppl_PageNumber); + + nple.nple_TitleString = ppl->ppl_TitleString; + nple.nple_TitleImage = ppl->ppl_TitleImage; + nple.nple_ImageIndex = ppl->ppl_TitleImageIndex; + nple.nple_CreateTitleImage = CreatePrefsTitleImage; + nple.nple_UserData = ppl; + + NewPage = CreatePrefsPage(app, ppl->ppl_GroupObject, &nple); + if (NewPage) + DoMethod(pageGroup, OM_ADDMEMBER, NewPage); + } + } + DoMethod(pageGroup, MUIM_Group_ExitChange); + } +} + + +struct TagItem *GetPrefsPluginSubWindows(struct SCAModule *app) +{ + ULONG SubWindowCount = 0; + struct PrefsPlugin *ppl; + struct TagItem *ti; + + if (SubWindowTagList) + { + free(SubWindowTagList); + SubWindowTagList = NULL; + } + + for (ppl = (struct PrefsPlugin *) PrefsPluginList.lh_Head; + ppl != (struct PrefsPlugin *) &PrefsPluginList.lh_Tail; + ppl = (struct PrefsPlugin *) ppl->ppl_Node.ln_Succ) + { + ULONG n; + + for (n=0; ppl->ppl_SubWindows && ppl->ppl_SubWindows[n]; n++) + SubWindowCount++; + } + + SubWindowTagList = calloc(1 + SubWindowCount, sizeof(struct TagItem)); + + if (NULL == SubWindowTagList) + return NULL; + + ti = SubWindowTagList; + + for (ppl = (struct PrefsPlugin *) PrefsPluginList.lh_Head; + ppl != (struct PrefsPlugin *) &PrefsPluginList.lh_Tail; + ppl = (struct PrefsPlugin *) ppl->ppl_Node.ln_Succ) + { + ULONG n; + + for (n=0; ppl->ppl_SubWindows && ppl->ppl_SubWindows[n]; n++) + { + ti->ti_Tag = MUIA_Application_Window; + ti->ti_Data = (ULONG) ppl->ppl_SubWindows[n]; + ti++; + } + } + + ti->ti_Tag = TAG_END; + + return SubWindowTagList; +} + +//---------------------------------------------------------------------------- + +static struct MUI_CustomClass *OpenPrefsModule(struct SCAModule *app, CONST_STRPTR FileName) +{ + struct PrefsPlugin *ppl; + struct Library *ScalosPrefsPluginBase; +#ifdef __amigaos4__ + struct ScalosPrefsPluginIFace *IScalosPrefsPlugin; +#endif + struct MUI_CustomClass *pclass = NULL; + + d1(kprintf(__FUNC__ "/%ld: FileName=<%s>\n", __LINE__, FileName)); + + do { + char TitleBuffer[256]; + STRPTR Title; + + ppl = calloc(1, sizeof(struct PrefsPlugin)); + d1(kprintf(__FUNC__ "/%ld: ppl=%08lx\n", __LINE__, ppl)); + if (NULL == ppl) + break; + + ScalosPrefsPluginBase = ppl->ppl_PluginBase = OpenLibrary(FileName, 0); + d1(kprintf(__FUNC__ "/%ld: ScalosPrefsPluginBase=%08lx\n", __LINE__, ScalosPrefsPluginBase)); + if (NULL == ScalosPrefsPluginBase) + break; +#ifdef __amigaos4__ + IScalosPrefsPlugin = (struct ScalosPrefsPluginIFace *)(ppl->ppl_IPlugin = + GetInterface(ScalosPrefsPluginBase, "main", 1, NULL)); +#endif + + ppl->ppl_PluginClass = pclass = (struct MUI_CustomClass *) SCAGetPrefsInfo(SCAPREFSINFO_GetClass); + d1(kprintf(__FUNC__ "/%ld: PluginClass=%08lx\n", __LINE__, ppl->ppl_PluginClass)); + if (NULL == ppl->ppl_PluginClass) + break; + + Title = (STRPTR) SCAGetPrefsInfo(SCAPREFSINFO_GetTitle); + d1(kprintf(__FUNC__ "/%ld: Title=<%s>\n", __LINE__, Title)); + if (NULL == Title) + break; + + ppl->ppl_TitleImageIndex = ModuleImageIndex++; + sprintf(TitleBuffer, Title, ppl->ppl_TitleImageIndex); + + ppl->ppl_TitleString = strdup(TitleBuffer); + if (NULL == ppl->ppl_TitleString) + break; + + ppl->ppl_TitleImage = (Object *) SCAGetPrefsInfo(SCAPREFSINFO_GetTitleImage); + d1(kprintf(__FUNC__ "/%ld: ppl_TitleImage=%08lx\n", __LINE__, ppl->ppl_TitleImage)); + + // ppl_TitleImage may be NULL + + AddTail(&PrefsPluginList, &ppl->ppl_Node); + ppl = NULL; + } while (0); + + if (ppl) + DisposePrefsPlugin(ppl); + + return pclass; +} + +static void DisposePrefsPlugin(struct PrefsPlugin *ppl) +{ + if (ppl) + { + if (ppl->ppl_TitleImage) + { + MUI_DisposeObject(ppl->ppl_TitleImage); + ppl->ppl_TitleImage = NULL; + } + if (ppl->ppl_TitleString) + { + free(ppl->ppl_TitleString); + ppl->ppl_TitleString = NULL; + } +#ifdef __amigaos4__ + if (ppl->ppl_IPlugin && NULL == ppl->ppl_GroupObject) + { + DropInterface(ppl->ppl_IPlugin); + ppl->ppl_IPlugin = NULL; + } +#endif + if (ppl->ppl_PluginBase) + { + d1(kprintf(__FUNC__ "/%ld: Plugin=<%s> OpenCount=%ld\n", \ + __LINE__, ppl->ppl_PluginBase->lib_Node.ln_Name, ppl->ppl_PluginBase->lib_OpenCnt)); + + if (NULL == ppl->ppl_GroupObject) + CloseLibrary(ppl->ppl_PluginBase); + +//+++ RemLibrary(ppl->ppl_PluginBase); + ppl->ppl_PluginBase = NULL; + } + + free(ppl); + } +} + +//---------------------------------------------------------------------------- + +static Object *CreatePrefsTitleImage(void *UserData) +{ + struct PrefsPlugin *ppl = (struct PrefsPlugin *) UserData; + Object *TitleImage = NULL; + + do { + struct Library *ScalosPrefsPluginBase; +#ifdef __amigaos4__ + struct ScalosPrefsPluginIFace *IScalosPrefsPlugin; +#endif + + d1(KPrintF(__FUNC__ "/%ld: ppl=%08lx\n", __LINE__, ppl)); + if (NULL == ppl) + break; + + ScalosPrefsPluginBase = ppl->ppl_PluginBase; +#ifdef __amigaos4__ + IScalosPrefsPlugin = (struct ScalosPrefsPluginIFace *)GetInterface( + ScalosPrefsPluginBase, "main", 1, NULL + ); +#endif + d1(kprintf(__FUNC__ "/%ld: ScalosPrefsPluginBase=%08lx\n", __LINE__, ScalosPrefsPluginBase)); + if (NULL == ScalosPrefsPluginBase) + break; + + TitleImage = (Object *) SCAGetPrefsInfo(SCAPREFSINFO_GetTitleImage); + d1(KPrintF(__FUNC__ "/%ld: TitleImage=%08lx\n", __LINE__, TitleImage)); + + // ppl_TitleImage may be NULL + } while (0); + + return TitleImage; +} + +//---------------------------------------------------------------------------- + + diff --git a/scalos/Prefs/MainPrefs/PrefsPlugins.h b/scalos/Prefs/MainPrefs/PrefsPlugins.h new file mode 100644 index 000000000..c35bcedd4 --- /dev/null +++ b/scalos/Prefs/MainPrefs/PrefsPlugins.h @@ -0,0 +1,27 @@ +// PrefsPlugins.h +// $Date$ +// $Revision$ + + +#ifndef PREFSPLUGINS_H +#define PREFSPLUGINS_H + +#include +#include "ScalosPrefs.h" + +//---------------------------------------------------------------------------- + +BOOL PrefsPluginsInit(void); +void PrefsPluginsCleanup(void); +void CollectPrefsPlugins(struct SCAModule *app, CONST_STRPTR Path, CONST_STRPTR Pattern); +struct TagItem *GetPrefsPluginSubWindows(struct SCAModule *app); +void CreatePrefsPlugins(struct SCAModule *app); +void InsertPrefsPlugins(struct SCAModule *app, Object *pageGroup, Object *pageList); +ULONG DoMethodForAllPrefsPlugins(ULONG ArgCount, ULONG MethodID, ...); +void SetAttributeForAllPrefsPlugins(ULONG Attribute, ULONG Value); +void NotifyPrefsPluginsPageChange(ULONG ActivePage); +BOOL CheckMCCsForAllPrefsPlugins(void); + +//---------------------------------------------------------------------------- + +#endif /* PREFSPLUGINS_H */ diff --git a/scalos/Prefs/MainPrefs/PrefsVersion.c b/scalos/Prefs/MainPrefs/PrefsVersion.c new file mode 100644 index 000000000..7cb5b7002 --- /dev/null +++ b/scalos/Prefs/MainPrefs/PrefsVersion.c @@ -0,0 +1,31 @@ +// PrefsVersion.c +// $Date$ +// $Revision$ + +#include +#include + +//---------------------------------------------------------------------------- + +// local data structures + +#define BUILDNR STR(SVN_VERSION) + +//---------------------------------------------------------------------------- + +// local functions + +//---------------------------------------------------------------------------- + +// public Data + +CONST_STRPTR BuildNr = BUILDNR; // Build number aka SVN revision + + +//---------------------------------------------------------------------------- + +// local Data + +//---------------------------------------------------------------------------- + + diff --git a/scalos/Prefs/MainPrefs/ReadWritePrefs.c b/scalos/Prefs/MainPrefs/ReadWritePrefs.c new file mode 100644 index 000000000..1b5746b85 --- /dev/null +++ b/scalos/Prefs/MainPrefs/ReadWritePrefs.c @@ -0,0 +1,3236 @@ +// ReadWritePrefs.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "MCPFrame_mcc.h" + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define NO_INLINE_STDARG +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include "SelectMarkSampleClass.h" +#include "ReadWritePrefs.h" +#include "HiddenDevices.h" +#include "ScalosPrefs.h" + +//----------------------------------------------------------------- + +#define PS_DATA(prefsstruct) ((STRPTR) (prefsstruct)) + sizeof((prefsstruct)->ps_Size) + +//----------------------------------------------------------------- + +// defined in Scalos.c + +extern struct Library *PreferencesBase; +extern struct ScalosBase *ScalosBase; +extern struct Library *WorkbenchBase; + +extern struct List PluginList; +extern struct List ControlBarGadgetListNormal; +extern struct List ControlBarGadgetListBrowser; +extern CONST_STRPTR cTextWindowsColumns[]; + +//----------------------------------------------------------------- + +// from debug.lib +extern int kprintf(const char *fmt, ...); + +//----------------------------------------------------------------- + +static void FillPrefsStructures(struct SCAModule *app); +static void ReadPluginList(APTR p_MyPrefsHandle, LONG lID); +static void WritePluginList(APTR p_MyPrefsHandle, LONG lID); +static void CleanupPluginList(void); +static void ReadTextModeColumns(APTR p_MyPrefsHandle, LONG lID); +static void WriteTextModeColumns(APTR p_MyPrefsHandle, LONG lID); +static void RemoveFileDisplayEntry(Object *list, ULONG Index); +static void ReadNewIconsPrecision(APTR p_MyPrefsHandle, LONG lID); +static void WriteNewIconsPrecision(APTR p_MyPrefsHandle, LONG lID); +static void UpdateFileDisplayPrefsFromGUI(struct SCAModule *app); +static size_t TranslateQualifierToString(ULONG Qualifier, STRPTR line, size_t MaxLength); +static ULONG TranslateStringToQualifier(CONST_STRPTR line); +static void AdjustBobMethod(struct SCAModule *app); +static LONG WriteIconFontPrefs(struct SCAModule *app, struct IFFHandle *iff); +static size_t GetFontPrefsSize(const struct FontPrefs *FontChunk); +static void ReadControlBarGadgetList(APTR p_MyPrefsHandle, LONG lID, struct List *CbGadgetsList, + ULONG prefsIDGadgets, ULONG prefsIDStrings); +static void WriteControlBarGadgetList(struct SCAModule *app, APTR p_MyPrefsHandle, LONG lID, + ULONG ObjID, ULONG prefsIDGadgets, ULONG prefsIDStrings); +static void CleanupControlBarGadgetsList(struct List *CbGadgetsList); +static void CreateDefaultControlBarGadgets(void); +static ULONG GetLog2(ULONG value); +static void SetWordPreferences(APTR prefsHandle, ULONG iD, ULONG prefsTag, CONST UWORD *arg, ULONG struct_Size); +static void SetLongPreferences(APTR prefsHandle, ULONG iD, ULONG prefsTag, CONST ULONG *arg, ULONG struct_Size); + +//----------------------------------------------------------------- + +#define MAX_QUALIFIER_STRING 80 + +//----------------------------------------------------------------- + +struct InputEventName +{ + CONST_STRPTR ien_name; + ULONG ien_Qualifier; +}; + +// --- Structures To Hold Preferences +struct PathsGroup +{ + char pg_pDefaultIcons[MAX_FILENAME]; + char pg_pDiskCopy[MAX_FILENAME]; + char pg_pHome[MAX_FILENAME]; + char pg_pThemes[MAX_FILENAME]; + char pg_pImageCache[MAX_FILENAME]; + char pg_pThumbnailDb[MAX_FILENAME]; + char pg_pFormat[MAX_FILENAME]; + char pg_pWbStartup[MAX_FILENAME]; + char pg_SQLiteTempDir[MAX_FILENAME]; +}; + +struct StartupGroup +{ + BYTE sg_bShowSplash; + UWORD sg_bSplashCloseDelay; + BYTE sg_bWBStartupDelay; + char sg_pWBStartup[MAX_FILENAME]; +}; + +struct DesktopGroup +{ + char dg_pScreen[1000]; + BYTE dg_bTitleRefresh; + BYTE dg_bMemoryRefresh; + BYTE dg_bWinTitleRefresh; + BYTE dg_bWinMemoryRefresh; + BYTE dg_bDiskRefresh; + BYTE dg_bHideTitleBar; + BYTE dg_bPopTitleBar; + enum ScreenTitleModes dg_ScreenTitleMode; + BYTE dg_bDropStart; + BYTE dg_AutoLeaveOut; + BYTE dg_bAllowCloseWB; + char dg_ConsoleName[256]; + ULONG dg_SingleWindowLassoQualifier; + char dg_SingleWindowLassoQualifierString[MAX_QUALIFIER_STRING]; +}; + +struct IconGroup +{ + // --- General + struct IBox ig_IconOffsets; + WORD ig_wNormFrame; + WORD ig_wSelFrame; + + + // --- Attributes + BYTE ig_bClickAreaMask; + BYTE ig_bNewIconTransparent; + LONG ig_bNewIconPrecision; + BYTE ig_bLoadDefIconsFirst; + BYTE ig_bIconsSaveable; + UWORD ig_TransparencyDefaultIcons; + BYTE ig_wMultipleLines; + BYTE ig_HighlightUnderMouse; + char ig_IconFontDesc[MAX_FONTNAME]; + struct Rectangle ig_SizeConstraints; + UWORD ig_NominalSize; + UBYTE ig_ShowThumbnails; + BYTE ig_ShowThumbnailsAsDefault; + UWORD ig_ThumbnailSize; + UWORD ig_ThumbnailMaxAge; + UWORD ig_ThumbnailMinSizeLimit; + ULONG ig_ThumbnailQuality; + BYTE ig_bSquareThumbnails; + WORD ig_wNormThumbnailFrame; + WORD ig_wSelThumbnailFrame; + struct IBox ig_ThumbnailOffsets; + UBYTE ig_ThumbnailsBackfill; + UWORD ig_ThumbnailBackgroundTransparency; + UBYTE ig_SelectedTextRectangle; + UWORD ig_SelTextRectBorderX; + UWORD ig_SelTextRectBorderY; + UWORD ig_SelTextRectRadius; + + // --- Tooltips + BYTE ig_bShowTooltips; + ULONG ig_bTooltipDelay; + char ig_ToolTipFont[MAX_FONTNAME]; + LONG ig_lDisplayFields; + UWORD ig_TransparencyTooltips; + + // --- Layout + UBYTE ig_IconWindowLayoutModes[ICONTYPE_MAX]; + UBYTE ig_DeviceWindowLayoutModes[ICONTYPE_MAX]; +}; + +struct DragNDropGroup +{ + BYTE ddg_bBobStyle; + BYTE ddg_bBobMethod; + BYTE ddg_bBobLook; //transparentmode + BYTE ddg_bTranspType; + BYTE ddg_bAutoRemoveIcons; + BYTE ddg_bEasyMultiSelect; + BYTE ddg_bEasyMultiDrag; + BYTE ddg_bGroupDrag; + ULONG ddg_pCopyQualifier; + char ddg_CopyQualifierString[MAX_QUALIFIER_STRING]; + ULONG ddg_pMakeLinkQualifier; + char ddg_MakeLinkQualifierString[MAX_QUALIFIER_STRING]; + ULONG ddg_pMoveQualifier; + char ddg_MoveQualifierString[MAX_QUALIFIER_STRING]; + LONG ddg_lTriggers; + BYTE ddg_bShowObjectCount; + BYTE ddg_bDropMarkMode; + UWORD ddg_TransparencyIconDrag; + UWORD ddg_TransparencyIconShadow; + UBYTE ddg_bEnableDropMenu; + UWORD ddg_PopupWindowDelaySeconds; // Time in s before drawer window pops up during D&D +}; + +struct WindowsGroup +{ + char wg_pRootWin[600]; + char wg_pWindow[600]; + BYTE wg_bType; + BYTE wg_bPopTitleOnly; + BYTE wg_bMMBMove; + BYTE wg_bStatusBar; + BYTE wg_bCleanupOnResize; + BYTE wg_bHideHiddenFiles; + BYTE wg_bHideProtectHiddenFiles; // JMC + UBYTE wg_ShowAllByDefault; + UBYTE wg_ViewByDefault; + UBYTE wg_CheckOverlappingIcons; +// UWORD wg_WindowTransparency; + UWORD wg_TransparencyActiveWindow; + UWORD wg_wTransparencyInactiveWindow; + struct IBox wg_DefaultSize; + struct IBox wg_CleanupSpaces; +}; + +struct TextWindowGroup +{ + WORD fd_wLabelStyle; + WORD fd_wTextSkip; //spacing between image & text + BYTE fd_bShowSoftLinks; + char fd_TextWindowFontDescr[MAX_FONTNAME]; + BYTE fd_lDisplayFields[12]; + BYTE fd_bShowStripes; + UBYTE fd_SelectTextIconName; + struct ARGB fd_SelectMarkerBaseColor; + UBYTE fd_SelectMarkerTransparency; + enum ScalosDrawerSortType fd_DrawerSortMode; +}; + +struct TrueTypeFontsGroup +{ + BYTE ttg_Antialias; + WORD ttg_Gamma; // Gamma * 1000 + BYTE ttg_UseScreenTTFont; + BYTE ttg_UseIconTTFont; + BYTE ttg_UseTextWindowTTFont; + char ttg_ScreenTTFontDesc[MAX_TTFONTDESC]; + char ttg_IconTTFontDesc[MAX_TTFONTDESC]; + char ttg_TextWindowTTFontDesc[MAX_TTFONTDESC]; +}; + +struct MiscGroup +{ + BYTE mg_bMenuCurrentDir; + BYTE mg_bHardEmulation; + BYTE mg_bUseExAll; + BYTE mg_bCreateSoftLinks; + ULONG mg_PopupApplySelectedQualifier; + char mg_PopupApplySelectedQualifierString[MAX_QUALIFIER_STRING]; + BYTE mp_PopupApplySelectedAlways; + ULONG mg_DefaultStackSize; + ULONG mg_CopyBuffSize; + ULONG mg_MaxUndoSteps; +}; + +enum DisplayFieldsIndex +{ + DFIDX_Name, + DFIDX_Size, + DFIDX_Access, + DFIDX_Date, + DFIDX_Time, + DFIDX_Comment, +}; + + +struct ScalosPrefsContainer +{ + struct PathsGroup Paths; + struct StartupGroup Startup; + struct DesktopGroup Desktop; + struct IconGroup Icons; + struct DragNDropGroup DragNDrop; + struct WindowsGroup Windows; + struct TextWindowGroup TextWindows; + struct TrueTypeFontsGroup TrueTypeFonts; + struct MiscGroup Miscellaneous; +}; + +//----------------------------------------------------------------- + +static const struct ScalosPrefsContainer defaultPrefs = +{ + { + // Paths +#ifdef __AROS__ + "ENVARC:sys", // pg_pDefaultIcons[MAX_FILENAME]; +#else + "ENV:sys", // pg_pDefaultIcons[MAX_FILENAME]; +#endif + "Sys:System/DiskCopy", // pg_pDiskCopy[MAX_FILENAME]; + "Scalos:", // pg_pHome[MAX_FILENAME]; + "Scalos:Themes", // pg_pThemes[MAX_FILENAME]; + "t:", // pg_pImageCache + "Scalos:Thumbnails.db", // pg_pThumbnailDb[MAX_FILENAME]; + "Sys:System/Format", // pg_pFormat[MAX_FILENAME]; + "SYS:WBStartup", // pg_pWbStartup[MAX_FILENAME]; + "t:", // pg_SQLiteTempDir + }, + { + // Startup + TRUE, // sg_bShowSplash; + 5, // sg_bSplashCloseDelay; + 5, // sg_bWBStartupDelay; + "SYS:WBStartup", // sg_pWBStartup[MAX_FILENAME]; + }, + { + // Desktop + "Scalos V%wb %fc graphics mem %ff other mem", // dg_pScreen[512]; + 5, // dg_bTitleRefresh; + FALSE, // dg_bMemoryRefresh; + 5, // dg_bWinTitleRefresh; + FALSE, // dg_bWinMemoryRefresh; + 5, // dg_bDiskRefresh; + FALSE, // dg_bHideTitleBar; + FALSE, // dg_bPopTitleBar; + SCREENTITLE_Visible, // dg_ScreenTitleMode + FALSE, // dg_bDropStart; + FALSE, // dg_AutoLeaveOut + TRUE, // dg_bAllowCloseWB; + "CON:0/11//150/Scalos Output Window/AUTO/WAIT", // dg_ConsoleName + IEQUALIFIER_CONTROL, // dg_pSingleWindowQualifier + "", // dg_SingleWindowLassoQualifierString + }, + { + // Icons + { // ig_IconOffsets; + 2, 2, 2, 2, + }, + MF_FRAME_NONE, // ig_wNormFrame; + MF_FRAME_NONE | (WORD) MCP_FRAME_RECESSED, // ig_wSelFrame; + + // --- Attributes + TRUE, // ig_bClickAreaMask; + TRUE, // ig_bNewIconTransparent; + 4, // ig_bNewIconPrecision; + TRUE, // ig_bLoadDefIconsFirst; + TRUE, // ig_bIconsSaveable; + 70, // ig_TransparencyDefaultIcons; + 0, // ig_wMultipleLines; + FALSE, // ig_HighlightUnderMouse; + "Topaz/8", // ig_IconFontDesc + { // ig_SizeConstraints + 0, 0, SHRT_MAX, SHRT_MAX + }, + 100, // ig_NominalSize + THUMBNAILS_Never, // ig_ShowThumbnails; + TRUE, // ig_ShowThumbnailsAsDefault; + 48, // ig_ThumbnailSize; + 14, // ig_ThumbnailMaxAge; + 128, // ig_ThumbnailMinSizeLimit; + SCALOSPREVIEWA_Quality_Max, // ig_ThumbnailQuality; + FALSE, // ig_bSquareThumbnails + MF_FRAME_NONE, // ig_wNormThumbnailFrame; + MF_FRAME_NONE | (WORD) MCP_FRAME_RECESSED, // ig_wSelThumbnailFrame; + { // ig_ThumbnailOffsets; + 2, 2, 2, 2, + }, + FALSE, // ig_ThumbnailsBackfill; + 50, // ig_ThumbnailBackgroundTransparency; + FALSE, // ig_SelectedTextRectangle; + 4, // ig_SelTextRectBorderX; + 2, // ig_SelTextRectBorderY; + 5, // ig_SelTextRectRadius; + + // --- Tooltips + TRUE, // ig_bShowTooltips; + 2, // ig_bTooltipDelay; + "Topaz/8", // ig_ToolTipFont[MAX_FONTNAME]; + 0, // ig_lDisplayFields; + 100, // ig_TransparencyTooltips + + // --- Layout + { // ig_IconWindowLayoutModes[ICONTYPE_MAX]; + ICONLAYOUT_Columns, + ICONLAYOUT_Columns, //WBDISK + ICONLAYOUT_Columns, //WBDRAWER + ICONLAYOUT_Columns, //WBTOOL + ICONLAYOUT_Columns, //WBPROJECT + ICONLAYOUT_Columns, //WBGARBAGE + ICONLAYOUT_Columns, //WBDEVICE + ICONLAYOUT_Columns, //WBKICK + ICONLAYOUT_Columns, //WBAPPICON + }, + { // ig_DeviceWindowLayoutModes[ICONTYPE_MAX]; + ICONLAYOUT_Columns, + ICONLAYOUT_Columns, //WBDISK + ICONLAYOUT_Columns, //WBDRAWER + ICONLAYOUT_Rows, //WBTOOL + ICONLAYOUT_Rows, //WBPROJECT + ICONLAYOUT_Columns, //WBGARBAGE + ICONLAYOUT_Columns, //WBDEVICE + ICONLAYOUT_Columns, //WBKICK + ICONLAYOUT_Rows, //WBAPPICON + }, + }, + { + // --- Drag'n'Drop + DRAGTYPE_ImageAndText, // ddg_bBobStyle; + DRAGMETHOD_Custom, // ddg_bBobMethod; + DRAGTRANSPMODE_SolidAndTransp, // ddg_bBobLook; + TRANSPTYPE_Transparent, // ddg_bTranspType; + TRUE, // ddg_bAutoRemoveIcons; + FALSE, // ddg_bEasyMultiSelect; + FALSE, // ddg_bEasyMultiDrag; + FALSE, // ddg_bGroupDrag; + IEQUALIFIER_CONTROL, // ddg_pCopyQualifier + "", // ddg_CopyQualifierString + IEQUALIFIER_LALT, // ddg_pMakeLinkQualifier + "", // ddg_MakeLinkQualifierString + IEQUALIFIER_CONTROL | IEQUALIFIER_LSHIFT, // ddg_pMoveQualifier + "", // ddg_MoveQualifierString + + 0, // ddg_lTriggers; + TRUE, // ddg_bShowObjectCount; + IDTV_WinDropMark_WindowedOnly, // ddg_bDropMarkMode; + 50, // ddg_TransparencyIconDrag + 25, // ddg_TransparencyIconShadow + FALSE, // ddg_bEnableDropMenu + 3, // ddg_PopupWindowDelaySeconds - Time in s before drawer window pops up during D&D + }, + { + // Windows + "%pa %d( %dp%% full, %DF free, %DU in use %d)", // wg_pRootWin[256]; + "%pa", // wg_pWindow[256]; + FALSE, // wg_bType; FALSE=Simple, TRUE=Smart refresh + FALSE, // wg_bPopTitleOnly; + FALSE, // wg_bMMBMove; + TRUE, // wg_bStatusBar + TRUE, // wg_bCleanupOnResize + FALSE, // wg_bHideHiddenFiles; + FALSE, // wg_bHideProtectHiddenFiles; // JMC + FALSE, // wg_ShowAllByDefault + IDTV_ViewModes_Icon, // wg_ViewByDefault +#if defined(__MORPHOS__) + TRUE, // wg_CheckOverlappingIcons +#else /* __MORPHOS__ */ + FALSE, // wg_CheckOverlappingIcons +#endif /* __MORPHOS__ */ + 100, // wg_TransparencyActiveWindow; + 100, // wg_wTransparencyInactiveWindow + + { // wg_DefaultSize; + 100, 100, // Left, Top + 200, 100, // Width, Height + }, + { // wg_CleanupSpaces; + 5, 4, // Left, Top + 5, 3, // XSkip, YSkip + } + }, + { + // TextWindows + 0, // fd_wLabelStyle; 0=normal, 1=outline, 2=shadow + 1, // fd_wTextSkip; //spacing between image & text + TRUE, // fd_bShowSoftLinks; + "Topaz/8", // fd_TextWindowFontDescr[MAX_FONTNAME]; + { // fd_lDisplayFields[]; + 0, 1, 2, 3, 4, 5, -1 + }, + FALSE, // fd_bShowStripes; + FALSE, // fd_SelectTextIconName + { (UBYTE) ~0, 133, 195, 221 }, // fd_SelectMarkerBaseColor + 128, // fd_SelectMarkerTransparency + DRAWER_SORT_First, // fd_DrawerSortMode + }, + { + // TrueTypeFonts + TT_Antialias_Auto, // ttg_Antialias; + 2500, // ttg_Gamma; // Gamma * 1000 + FALSE, // ttg_UseScreenTTFont; + FALSE, // ttg_UseIconTTFont; + FALSE, // ttg_UseTextWindowTTFont; + "0/400/11/Arial", // ttg_ScreenTTFontDesc[MAX_TTFONTDESC]; + "0/400/11/Arial", // ttg_IconTTFontDesc[MAX_TTFONTDESC]; + "0/400/11/Arial", // ttg_TextWindowTTFontDesc[MAX_TTFONTDESC]; + }, + { + // Misc + FALSE, // mg_bMenuCurrentDir + TRUE, // mg_bHardEmulation + TRUE, // mg_bUseExAll + FALSE, // mg_bCreateSoftLinks + IEQUALIFIER_LSHIFT, // mg_PopupApplySelectedQualifier + "", // mg_PopupApplySelectedQualifierString + FALSE, // mp_PopupApplySelectedAlways + 16384, // mg_DefaultStackSize + 262144, // mg_CopyBuffSize + 10, // mg_MaxUndoSteps + } +}; + +static struct ScalosPrefsContainer currentPrefs; + +static struct FontPrefs IconFontPrefs; +static struct FontPrefs ScreenFontPrefs; +static struct FontPrefs SysFontPrefs; + +static const struct InputEventName QualifierTable[] = +{ + { "lshift", IEQUALIFIER_LSHIFT }, + { "rshift", IEQUALIFIER_RSHIFT }, + { "capslock", IEQUALIFIER_CAPSLOCK }, + { "control", IEQUALIFIER_CONTROL }, + { "lalt", IEQUALIFIER_LALT }, + { "ralt", IEQUALIFIER_RALT }, + { "lcommand", IEQUALIFIER_LCOMMAND }, + { "rcommand", IEQUALIFIER_RCOMMAND }, + { "shift", IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT }, + { "alt", IEQUALIFIER_LALT | IEQUALIFIER_RALT }, + { "command", IEQUALIFIER_LCOMMAND | IEQUALIFIER_RCOMMAND }, +}; + +// default control bar gadgets +static const struct ControlBarGadgetEntry DefaultControlBarGadgets[] = +{ + { + { NULL, NULL, }, // cgy_Node + SCPGadgetType_BackButton, // cgy_GadgetType; + 0, // cgy_ImageObjectIndex + NULL, // cgy_Image + "", // cgy_ImageString + "", // cgy_Action[40] + "", // cgy_NormalImage + "", // cgy_SelectedImage + "", // cgy_DisabledImage + "", // cgy_HelpText + }, + { + { NULL, NULL, }, // cgy_Node + SCPGadgetType_ForwardButton, // cgy_GadgetType; + 0, // cgy_ImageObjectIndex + NULL, // cgy_Image + "", // cgy_ImageString + "", // cgy_Action[40] + "", // cgy_NormalImage + "", // cgy_SelectedImage + "", // cgy_DisabledImage + "", // cgy_HelpText + }, + { + { NULL, NULL, }, // cgy_Node + SCPGadgetType_Separator, // cgy_GadgetType; + 0, // cgy_ImageObjectIndex + NULL, // cgy_Image + "", // cgy_ImageString + "", // cgy_Action[40] + "", // cgy_NormalImage + "", // cgy_SelectedImage + "", // cgy_DisabledImage + "", // cgy_HelpText + }, + { + { NULL, NULL, }, // cgy_Node + SCPGadgetType_UpButton, // cgy_GadgetType; + 0, // cgy_ImageObjectIndex + NULL, // cgy_Image + "", // cgy_ImageString + "", // cgy_Action[40] + "", // cgy_NormalImage + "", // cgy_SelectedImage + "", // cgy_DisabledImage + "", // cgy_HelpText + }, + { + { NULL, NULL, }, // cgy_Node + SCPGadgetType_History, // cgy_GadgetType; + 0, // cgy_ImageObjectIndex + NULL, // cgy_Image + "", // cgy_ImageString + "", // cgy_Action[40] + "", // cgy_NormalImage + "", // cgy_SelectedImage + "", // cgy_DisabledImage + "", // cgy_HelpText + }, + { + { NULL, NULL, }, // cgy_Node + SCPGadgetType_BrowseButton, // cgy_GadgetType; + 0, // cgy_ImageObjectIndex + NULL, // cgy_Image + "", // cgy_ImageString + "", // cgy_Action[40] + "", // cgy_NormalImage + "", // cgy_SelectedImage + "", // cgy_DisabledImage + "", // cgy_HelpText + }, +}; + +//----------------------------------------------------------------- + +BOOL ReadWritePrefsInit(void) +{ + if (!HiddenDevicesInit()) + return FALSE; + + return TRUE; +} + +//----------------------------------------------------------------- + +void ReadWritePrefsCleanup(void) +{ + HiddenDevicesCleanup(); + + CleanupPluginList(); + CleanupControlBarGadgetsList(&ControlBarGadgetListNormal); + CleanupControlBarGadgetsList(&ControlBarGadgetListBrowser); +} + +//----------------------------------------------------------------- + +void UpdateGuiFromPrefs(struct SCAModule *app) +{ + ULONG n; + + ReadIconFontPrefs(app); + + // --- Paths Page + + setstring(app->Obj[STRING_DISKCOPY], (ULONG) currentPrefs.Paths.pg_pDiskCopy); + setstring(app->Obj[STRING_SCALOSHOME], (ULONG) currentPrefs.Paths.pg_pHome); + setstring(app->Obj[STRING_THEMES], (ULONG) currentPrefs.Paths.pg_pThemes); + setstring(app->Obj[STRING_IMAGECACHE], (ULONG) currentPrefs.Paths.pg_pImageCache); + setstring(app->Obj[STRING_THUMBNAILDB], (ULONG) currentPrefs.Paths.pg_pThumbnailDb); + setstring(app->Obj[STRING_FORMAT], (ULONG) currentPrefs.Paths.pg_pFormat); + setstring(app->Obj[STRING_SQLITE3TEMPPATH], (ULONG) currentPrefs.Paths.pg_SQLiteTempDir); + + // --- Startup Page + + setcheckmark(app->Obj[CHECK_SHOWSPLASH], currentPrefs.Startup.sg_bShowSplash); + setslider(app->Obj[SLIDER_SPLASHCLOSE], currentPrefs.Startup.sg_bSplashCloseDelay); + setslider(app->Obj[SLIDER_WBSDELAY], currentPrefs.Startup.sg_bWBStartupDelay); + setstring(app->Obj[STRING_WBSTARTPATH], (ULONG) currentPrefs.Startup.sg_pWBStartup); + + // --- Desktop Page + + setstring(app->Obj[STRING_CONSOLENAME], (ULONG) currentPrefs.Desktop.dg_ConsoleName); + set(app->Obj[POPPH_SCREENTITLE], MUIA_Popph_Contents, (ULONG) currentPrefs.Desktop.dg_pScreen); + + setslider(app->Obj[SLIDER_TITLEREFRESH], currentPrefs.Desktop.dg_bTitleRefresh); + setcheckmark(app->Obj[CHECK_TITLEMEM], currentPrefs.Desktop.dg_bMemoryRefresh); + set(app->Obj[SLIDER_TITLEREFRESH], MUIA_Disabled, currentPrefs.Desktop.dg_bMemoryRefresh); + + setslider(app->Obj[SLIDER_WINTITLEREFRESH], currentPrefs.Desktop.dg_bWinTitleRefresh); + setcheckmark(app->Obj[CHECK_WINTITLEMEM], currentPrefs.Desktop.dg_bWinMemoryRefresh); + set(app->Obj[SLIDER_WINTITLEREFRESH], MUIA_Disabled, currentPrefs.Desktop.dg_bWinMemoryRefresh); + + setslider(app->Obj[SLIDER_DISKREFRESH], currentPrefs.Desktop.dg_bDiskRefresh); + + if (currentPrefs.Desktop.dg_bHideTitleBar) + { + if (currentPrefs.Desktop.dg_bPopTitleBar) + currentPrefs.Desktop.dg_ScreenTitleMode = SCREENTITLE_Popup; + else + currentPrefs.Desktop.dg_ScreenTitleMode = SCREENTITLE_Hidden; // always hidden + } + else + { + currentPrefs.Desktop.dg_ScreenTitleMode = SCREENTITLE_Visible; // always visible + } + setcycle(app->Obj[CYCLE_SCREENTITLEMODE], currentPrefs.Desktop.dg_ScreenTitleMode); + + setcheckmark(app->Obj[DROPSTART], currentPrefs.Desktop.dg_bDropStart); + setcheckmark(app->Obj[CHECK_AUTOLEAVEOUT], currentPrefs.Desktop.dg_AutoLeaveOut); + setcheckmark(app->Obj[CLOSEWB], currentPrefs.Desktop.dg_bAllowCloseWB); + + setcycle(app->Obj[CYCLE_DESKTOP_LAYOUT_WBDISK], currentPrefs.Icons.ig_DeviceWindowLayoutModes[WBDISK]); + setcycle(app->Obj[CYCLE_DESKTOP_LAYOUT_WBDRAWER], currentPrefs.Icons.ig_DeviceWindowLayoutModes[WBDRAWER]); + setcycle(app->Obj[CYCLE_DESKTOP_LAYOUT_WBTOOL], currentPrefs.Icons.ig_DeviceWindowLayoutModes[WBTOOL]); + setcycle(app->Obj[CYCLE_DESKTOP_LAYOUT_WBPROJECT], currentPrefs.Icons.ig_DeviceWindowLayoutModes[WBPROJECT]); + setcycle(app->Obj[CYCLE_DESKTOP_LAYOUT_WBGARBAGE], currentPrefs.Icons.ig_DeviceWindowLayoutModes[WBGARBAGE]); + setcycle(app->Obj[CYCLE_DESKTOP_LAYOUT_WBDEVICE], currentPrefs.Icons.ig_DeviceWindowLayoutModes[WBDEVICE]); + setcycle(app->Obj[CYCLE_DESKTOP_LAYOUT_WBKICK], currentPrefs.Icons.ig_DeviceWindowLayoutModes[WBKICK]); + setcycle(app->Obj[CYCLE_DESKTOP_LAYOUT_WBAPPICON], currentPrefs.Icons.ig_DeviceWindowLayoutModes[WBAPPICON]); + + // --- Icons Page + + AdjustBobMethod(app); + set(app->Obj[FRAME_ICONNORMAL], MUIA_MCPFrame_FrameType, currentPrefs.Icons.ig_wNormFrame); + set(app->Obj[FRAME_ICONSELECTED], MUIA_MCPFrame_FrameType, currentPrefs.Icons.ig_wSelFrame); + set(app->Obj[FRAME_ICON_THUMBNAIL_NORMAL], MUIA_MCPFrame_FrameType, currentPrefs.Icons.ig_wNormThumbnailFrame); + set(app->Obj[FRAME_ICON_THUMBNAIL_SELECTED], MUIA_MCPFrame_FrameType, currentPrefs.Icons.ig_wSelThumbnailFrame); + + // make sure to set icon borders AFTER frame type since changing frame type adjusts borders + set(app->Obj[ICONLEFT], MUIA_Numeric_Value, currentPrefs.Icons.ig_IconOffsets.Left); + set(app->Obj[ICONRIGHT], MUIA_Numeric_Value, currentPrefs.Icons.ig_IconOffsets.Top); + set(app->Obj[ICONTOP], MUIA_Numeric_Value, currentPrefs.Icons.ig_IconOffsets.Width); + set(app->Obj[ICONBOTTOM], MUIA_Numeric_Value, currentPrefs.Icons.ig_IconOffsets.Height); + + // make sure to set thumbnail borders AFTER frame type since changing frame type adjusts borders + set(app->Obj[THUMBNAILS_LEFTBORDER], MUIA_Numeric_Value, currentPrefs.Icons.ig_ThumbnailOffsets.Left); + set(app->Obj[THUMBNAILS_RIGHTBORDER], MUIA_Numeric_Value, currentPrefs.Icons.ig_ThumbnailOffsets.Top); + set(app->Obj[THUMBNAILS_TOPBORDER], MUIA_Numeric_Value, currentPrefs.Icons.ig_ThumbnailOffsets.Width); + set(app->Obj[THUMBNAILS_BOTTOMBORDER], MUIA_Numeric_Value, currentPrefs.Icons.ig_ThumbnailOffsets.Height); + + setcheckmark(app->Obj[CHECK_ICONMASK], currentPrefs.Icons.ig_bClickAreaMask); + setslider(app->Obj[SLIDER_ICONRMAP_PRECISION], currentPrefs.Icons.ig_bNewIconPrecision); + setcheckmark(app->Obj[CHECK_NIMASK], currentPrefs.Icons.ig_bNewIconTransparent); + setstring(app->Obj[STRING_DEFICONPATH], (ULONG) currentPrefs.Paths.pg_pDefaultIcons); + setcheckmark(app->Obj[CHECK_DEFFIRST], currentPrefs.Icons.ig_bLoadDefIconsFirst); + setcheckmark(app->Obj[CHECK_ICONSSAVE], currentPrefs.Icons.ig_bIconsSaveable); + setcheckmark(app->Obj[CHECK_TOOLTIPS], currentPrefs.Icons.ig_bShowTooltips); + setslider(app->Obj[SLIDER_TIPDELAY], currentPrefs.Icons.ig_bTooltipDelay); + setstring(app->Obj[STRING_TOOLTIPFONT], (ULONG) currentPrefs.Icons.ig_ToolTipFont); + setcheckmark(app->Obj[CHECK_MULTILINES], currentPrefs.Icons.ig_wMultipleLines); + setcheckmark(app->Obj[CHECK_HILITEUNDERMOUSE], currentPrefs.Icons.ig_HighlightUnderMouse); + setstring(app->Obj[POP_ICONFONT], (ULONG) currentPrefs.Icons.ig_IconFontDesc); + setslider(app->Obj[SLIDER_ICONTOOLTIPS_TRANSPARENCY], currentPrefs.Icons.ig_TransparencyTooltips); + + setcycle(app->Obj[CYCLE_SHOWTHUMBNAILS], currentPrefs.Icons.ig_ShowThumbnails); + + set(app->Obj[CHECK_SHOWTHUMBNAILS_AS_DEFAULT], MUIA_Selected, currentPrefs.Icons.ig_ShowThumbnailsAsDefault); + + setslider(app->Obj[SLIDER_THUMBNAILS_MAXAGE], currentPrefs.Icons.ig_ThumbnailMaxAge); + setslider(app->Obj[SLIDER_THUMBNAILS_MINSIZE_LIMIT], currentPrefs.Icons.ig_ThumbnailMinSizeLimit); + setslider(app->Obj[SLIDER_THUMBNAILS_QUALITY], currentPrefs.Icons.ig_ThumbnailQuality); + + setcheckmark(app->Obj[CHECK_THUMBNAILS_SQUARE], currentPrefs.Icons.ig_bSquareThumbnails); + setcheckmark(app->Obj[CHECK_THUMBNAILS_BACKFILL], currentPrefs.Icons.ig_ThumbnailsBackfill); + setslider(app->Obj[SLIDER_ICONTRANSPARENCY_THUMBNAILBACK], currentPrefs.Icons.ig_ThumbnailBackgroundTransparency); + + setcheckmark(app->Obj[CHECK_SEL_ICONTEXT_RECTANGLE], currentPrefs.Icons.ig_SelectedTextRectangle); + setslider(app->Obj[SLIDER_SEL_ICONTEXT_RECT_BORDERX], currentPrefs.Icons.ig_SelTextRectBorderX); + setslider(app->Obj[SLIDER_SEL_ICONTEXT_RECT_BORDERY], currentPrefs.Icons.ig_SelTextRectBorderY); + setslider(app->Obj[SLIDER_SEL_ICONTEXT_RECT_RADIUS], currentPrefs.Icons.ig_SelTextRectRadius); + set(app->Obj[SLIDER_SEL_ICONTEXT_RECT_BORDERX], MUIA_Disabled, !currentPrefs.Icons.ig_SelectedTextRectangle); + set(app->Obj[SLIDER_SEL_ICONTEXT_RECT_BORDERY], MUIA_Disabled, !currentPrefs.Icons.ig_SelectedTextRectangle); + set(app->Obj[SLIDER_SEL_ICONTEXT_RECT_RADIUS], MUIA_Disabled, !currentPrefs.Icons.ig_SelectedTextRectangle); + + set(app->Obj[GROUP_THUMBNAIL_BACKFILL_TRANSPARENCY], MUIA_Disabled, TRUE ? !currentPrefs.Icons.ig_ThumbnailsBackfill : FALSE); + + SetThumbNailSize(app, currentPrefs.Icons.ig_ThumbnailSize); + SetIconSizeConstraints(app, ¤tPrefs.Icons.ig_SizeConstraints); + setslider(app->Obj[SLIDER_ICONSPAGE_NOMINALSIZE], currentPrefs.Icons.ig_NominalSize); + + d1(KPrintF(__FUNC__ "/%ld: Icon offset left=%ld top=%ld right=%ld bottom=%ld\n", \ + __FUNC__, __LINE__, currentPrefs.Icons.ig_IconOffsets.Left, currentPrefs.Icons.ig_IconOffsets.Top, \ + currentPrefs.Icons.ig_IconOffsets.Width, currentPrefs.Icons.ig_IconOffsets.Height)); + + setcycle(app->Obj[CYCLE_ICONS_LAYOUT_WBDRAWER], currentPrefs.Icons.ig_IconWindowLayoutModes[WBDRAWER]); + setcycle(app->Obj[CYCLE_ICONS_LAYOUT_WBTOOL], currentPrefs.Icons.ig_IconWindowLayoutModes[WBTOOL]); + setcycle(app->Obj[CYCLE_ICONS_LAYOUT_WBPROJECT], currentPrefs.Icons.ig_IconWindowLayoutModes[WBPROJECT]); + + // --- Drag and Drop Page + + //tooltip display field + setcycle(app->Obj[CYCLE_STYLE], currentPrefs.DragNDrop.ddg_bBobStyle); + setcycle(app->Obj[CYCLE_ROUTINE], currentPrefs.DragNDrop.ddg_bBobMethod); + setmutex(app->Obj[RADIO_BOBLOOK], currentPrefs.DragNDrop.ddg_bBobLook); + setcycle(app->Obj[CYCLE_TRANSPMODE], currentPrefs.DragNDrop.ddg_bTranspType); + set(app->Obj[CYCLE_TRANSPMODE], MUIA_Disabled, DRAGMETHOD_GELS == currentPrefs.DragNDrop.ddg_bBobMethod); + setcycle(app->Obj[CYCLE_DROPMARK], currentPrefs.DragNDrop.ddg_bDropMarkMode); + set(app->Obj[SLIDER_ICONTRANSPARENCY_DRAG], MUIA_Disabled, TRANSPTYPE_Transparent != currentPrefs.DragNDrop.ddg_bTranspType); + setslider(app->Obj[SLIDER_ICONTRANSPARENCY_DRAG], currentPrefs.DragNDrop.ddg_TransparencyIconDrag); + setslider(app->Obj[SLIDER_ICONTRANSPARENCY_SHADOW], currentPrefs.DragNDrop.ddg_TransparencyIconShadow); + setcheckmark(app->Obj[CHECK_ENABLE_DROPMENU], currentPrefs.DragNDrop.ddg_bEnableDropMenu); + setslider(app->Obj[SLIDER_POPOPENWINDOW_DELAY], currentPrefs.DragNDrop.ddg_PopupWindowDelaySeconds); + setslider(app->Obj[SLIDER_ICONTRANSPARENCY_DEFICONS], currentPrefs.Icons.ig_TransparencyDefaultIcons); + setcheckmark(app->Obj[CHECK_AUTOREMOVE], currentPrefs.DragNDrop.ddg_bAutoRemoveIcons); + setcheckmark(app->Obj[CHECK_EASY_MULTISELECT], currentPrefs.DragNDrop.ddg_bEasyMultiSelect); + setcheckmark(app->Obj[CHECK_EASY_MULTIDRAG], currentPrefs.DragNDrop.ddg_bEasyMultiDrag); + setcheckmark(app->Obj[CHECK_GROUPDRAG], !currentPrefs.DragNDrop.ddg_bGroupDrag); + setcheckmark(app->Obj[CHECK_SHOWDRAG], currentPrefs.DragNDrop.ddg_bShowObjectCount); + //copy qualifier + TranslateQualifierToString(currentPrefs.DragNDrop.ddg_pCopyQualifier, + currentPrefs.DragNDrop.ddg_CopyQualifierString, + sizeof(currentPrefs.DragNDrop.ddg_CopyQualifierString)); + setstring(app->Obj[COPY_HOTKEY], (ULONG) currentPrefs.DragNDrop.ddg_CopyQualifierString); + //MakeLink qualifier + TranslateQualifierToString(currentPrefs.DragNDrop.ddg_pMakeLinkQualifier, + currentPrefs.DragNDrop.ddg_MakeLinkQualifierString, + sizeof(currentPrefs.DragNDrop.ddg_MakeLinkQualifierString)); + setstring(app->Obj[MAKELINK_HOTKEY], (ULONG) currentPrefs.DragNDrop.ddg_MakeLinkQualifierString); + //Move qualifier + TranslateQualifierToString(currentPrefs.DragNDrop.ddg_pMoveQualifier, + currentPrefs.DragNDrop.ddg_MoveQualifierString, + sizeof(currentPrefs.DragNDrop.ddg_MoveQualifierString)); + setstring(app->Obj[MOVE_HOTKEY], (ULONG) currentPrefs.DragNDrop.ddg_MoveQualifierString); + + // Single-Window Lasso qualifier + TranslateQualifierToString(currentPrefs.Desktop.dg_SingleWindowLassoQualifier, + currentPrefs.Desktop.dg_SingleWindowLassoQualifierString, + sizeof(currentPrefs.Desktop.dg_SingleWindowLassoQualifierString)); + setstring(app->Obj[SINGLE_WINDOW_LASSO_HOTKEY], (ULONG) currentPrefs.Desktop.dg_SingleWindowLassoQualifierString); + + //triggers + setcheckmark(app->Obj[CHECK_TRIG_DISK], currentPrefs.DragNDrop.ddg_lTriggers & DRAGTRANSPF_DiskIcons); + setcheckmark(app->Obj[CHECK_TRIG_DRAWER], currentPrefs.DragNDrop.ddg_lTriggers & DRAGTRANSPF_DrawerIcons); + setcheckmark(app->Obj[CHECK_TRIG_TOOL], currentPrefs.DragNDrop.ddg_lTriggers & DRAGTRANSPF_ToolIcons); + setcheckmark(app->Obj[CHECK_TRIG_PROJECT], currentPrefs.DragNDrop.ddg_lTriggers & DRAGTRANSPF_ProjectIcons); + setcheckmark(app->Obj[CHECK_TRIG_TRASHCAN], currentPrefs.DragNDrop.ddg_lTriggers & DRAGTRANSPF_TrashcanIcons); + setcheckmark(app->Obj[CHECK_TRIG_KICK], currentPrefs.DragNDrop.ddg_lTriggers & DRAGTRANSPF_KickIcons); + setcheckmark(app->Obj[CHECK_TRIG_APPICON], currentPrefs.DragNDrop.ddg_lTriggers & DRAGTRANSPF_AppIcons); + setcheckmark(app->Obj[CHECK_TRIG_APPWIN], currentPrefs.DragNDrop.ddg_lTriggers & DRAGTRANSPF_AppWindows); + setcheckmark(app->Obj[CHECK_TRIG_ICONIFIEDWIN], currentPrefs.DragNDrop.ddg_lTriggers & DRAGTRANSPF_IconifiedWinIcons); + setcheckmark(app->Obj[CHECK_TRIG_SCALOSWIN], currentPrefs.DragNDrop.ddg_lTriggers & DRAGTRANSPF_ScalosWindows); + + // --- Windows Page + + set(app->Obj[POPPH_ROOTWINDOWTITLE], MUIA_Popph_Contents, (ULONG) currentPrefs.Windows.wg_pRootWin); + set(app->Obj[POPPH_DIRWINDOWTITLE], MUIA_Popph_Contents, (ULONG) currentPrefs.Windows.wg_pWindow); + setcycle(app->Obj[CYCLE_WINDOWTYPE], currentPrefs.Windows.wg_bType); + set(app->Obj[CHECK_POPTITLEONLY], MUIA_Selected, currentPrefs.Windows.wg_bPopTitleOnly); + set(app->Obj[CHECK_MMBMOVE], MUIA_Selected, currentPrefs.Windows.wg_bMMBMove); + set(app->Obj[WINLEFT], MUIA_String_Integer, currentPrefs.Windows.wg_DefaultSize.Left); + set(app->Obj[WINTOP], MUIA_String_Integer, currentPrefs.Windows.wg_DefaultSize.Top); + set(app->Obj[WINWIDTH], MUIA_String_Integer, currentPrefs.Windows.wg_DefaultSize.Width); + set(app->Obj[WINHEIGHT], MUIA_String_Integer, currentPrefs.Windows.wg_DefaultSize.Height); + setslider(app->Obj[SLIDER_CLEANLEFT], currentPrefs.Windows.wg_CleanupSpaces.Left); + setslider(app->Obj[SLIDER_CLEANTOP], currentPrefs.Windows.wg_CleanupSpaces.Top); + setslider(app->Obj[SLIDER_CLEANXSKIP], currentPrefs.Windows.wg_CleanupSpaces.Width); + setslider(app->Obj[SLIDER_CLEANYSKIP], currentPrefs.Windows.wg_CleanupSpaces.Height); + setcheckmark(app->Obj[CHECK_STATUSBAR], currentPrefs.Windows.wg_bStatusBar); + setcheckmark(app->Obj[CHECK_CHECKOVERLAP], currentPrefs.Windows.wg_CheckOverlappingIcons); + setcheckmark(app->Obj[CHECK_CLEANUP_ONRESIZE], currentPrefs.Windows.wg_bCleanupOnResize); + setslider(app->Obj[SLIDER_TRANSPARENCY_ACTIVEWINDOW], currentPrefs.Windows.wg_TransparencyActiveWindow); + setslider(app->Obj[SLIDER_TRANSPARENCY_INACTIVEWINDOW], currentPrefs.Windows.wg_wTransparencyInactiveWindow); + + // --- File Display Page + + setcycle(app->Obj[CYCLE_LABELSTYLE], currentPrefs.TextWindows.fd_wLabelStyle); + setslider(app->Obj[SLIDER_LABELSPACE], currentPrefs.TextWindows.fd_wTextSkip); + setcheckmark(app->Obj[SOFTICONSLINK], currentPrefs.TextWindows.fd_bShowSoftLinks); + setcheckmark(app->Obj[SOFTTEXTSLINK], currentPrefs.TextWindows.fd_bShowSoftLinks); + setstring(app->Obj[POP_TEXTMODEFONT], (ULONG) currentPrefs.TextWindows.fd_TextWindowFontDescr); + set(app->Obj[STRING_TEXTMODEFONT_SAMPLE], MUIA_FontSample_StdFontDesc, (ULONG) currentPrefs.TextWindows.fd_TextWindowFontDescr); + + // first, put all entries into NLIST_STORAGE_FILEDISPLAY + DoMethod(app->Obj[NLIST_STORAGE_FILEDISPLAY], MUIM_NList_Clear); + + for (n=0; cTextWindowsColumns[n]; n++) + { + struct FileDisplayListEntry fdle; + + fdle.fdle_Index = n; + + DoMethod(app->Obj[NLIST_STORAGE_FILEDISPLAY], MUIM_NList_InsertSingle, &fdle, MUIV_NList_Insert_Bottom); + } + + // start with en empty "use" list + DoMethod(app->Obj[NLIST_USE_FILEDISPLAY], MUIM_NList_Clear); + + // then, remove all used entries from NLIST_STORAGE_FILEDISPLAY and insert them in NLIST_USE_FILEDISPLAY + for (n=0; ~0 != currentPrefs.TextWindows.fd_lDisplayFields[n] && n < Sizeof(currentPrefs.TextWindows.fd_lDisplayFields); n++) + { + struct FileDisplayListEntry fdle; + + fdle.fdle_Index = currentPrefs.TextWindows.fd_lDisplayFields[n]; + + RemoveFileDisplayEntry(app->Obj[NLIST_STORAGE_FILEDISPLAY], fdle.fdle_Index); + DoMethod(app->Obj[NLIST_USE_FILEDISPLAY], MUIM_NList_InsertSingle, &fdle, MUIV_NList_Insert_Bottom); + } + + set(app->Obj[HIDEHIDDENFILES], MUIA_Selected, currentPrefs.Windows.wg_bHideHiddenFiles); + set(app->Obj[HIDEPROTECTHIDDENFILES], MUIA_Selected, currentPrefs.Windows.wg_bHideProtectHiddenFiles); // JMC + + setcycle(app->Obj[CYCLE_SHOWALLDEFAULT], currentPrefs.Windows.wg_ShowAllByDefault); + setcycle(app->Obj[CYCLE_VIEWBYICONSDEFAULT], currentPrefs.Windows.wg_ViewByDefault - 1); + + set(app->Obj[CHECK_STRIPED_WINDOW], MUIA_Selected, currentPrefs.TextWindows.fd_bShowStripes); + set(app->Obj[CHECK_SELECTTEXTICONNAME], MUIA_Selected, currentPrefs.TextWindows.fd_SelectTextIconName); + + setcycle(app->Obj[CYCLE_DRAWERSORTMODE], currentPrefs.TextWindows.fd_DrawerSortMode); + + setslider(app->Obj[SLIDER_TEXTWINDOWS_SELECTFILLTRANSPARENCY], currentPrefs.TextWindows.fd_SelectMarkerTransparency); + setslider(app->Obj[SLIDER_TEXTWINDOWS_SELECTBORDERTRANSPARENCY], currentPrefs.TextWindows.fd_SelectMarkerBaseColor.Alpha); + + set(app->Obj[MCC_TEXTWINDOWS_SELECTMARKER_SAMPLE], TIHA_BaseColor, (ULONG) ¤tPrefs.TextWindows.fd_SelectMarkerBaseColor); + set(app->Obj[MCC_TEXTWINDOWS_SELECTMARKER_SAMPLE], TIHA_Transparency, currentPrefs.TextWindows.fd_SelectMarkerTransparency); + + SetAttrs(app->Obj[COLORADJUST_TEXTWINDOWS_SELECTIONMARK], + MUIA_Coloradjust_Red, currentPrefs.TextWindows.fd_SelectMarkerBaseColor.Red << 24, + MUIA_Coloradjust_Green, currentPrefs.TextWindows.fd_SelectMarkerBaseColor.Green << 24, + MUIA_Coloradjust_Blue, currentPrefs.TextWindows.fd_SelectMarkerBaseColor.Blue << 24, + TAG_END); + + // --- TrueType Font Page + + setcycle(app->Obj[CYCLE_TTANTIALIAS], currentPrefs.TrueTypeFonts.ttg_Antialias); + setslider(app->Obj[SLIDER_TTGAMMA], currentPrefs.TrueTypeFonts.ttg_Gamma); + setcheckmark(app->Obj[CHECK_TTSCREENFONT_ENABLE], currentPrefs.TrueTypeFonts.ttg_UseScreenTTFont); + setcheckmark(app->Obj[CHECK_TTICONFONT_ENABLE], currentPrefs.TrueTypeFonts.ttg_UseIconTTFont); + setcheckmark(app->Obj[CHECK_ICONSPAGE_TTICONFONT_ENABLE], currentPrefs.TrueTypeFonts.ttg_UseIconTTFont); + set(app->Obj[GROUP_ICONSPAGE_ICONFONT], MUIA_Disabled, currentPrefs.TrueTypeFonts.ttg_UseIconTTFont); + set(app->Obj[GROUP_ICONSPAGE_TTICONFONT], MUIA_Disabled, !currentPrefs.TrueTypeFonts.ttg_UseIconTTFont); + setcheckmark(app->Obj[CHECK_TTTEXTWINDOWFONT_ENABLE], currentPrefs.TrueTypeFonts.ttg_UseTextWindowTTFont); + setcheckmark(app->Obj[CHECK_TEXTWINDOW_TTTEXTWINDOWFONT_ENABLE], currentPrefs.TrueTypeFonts.ttg_UseTextWindowTTFont); + set(app->Obj[GROUP_TEXTWINDOW_FONT_SELECT], MUIA_Disabled, currentPrefs.TrueTypeFonts.ttg_UseTextWindowTTFont); + setstring(app->Obj[POPSTRING_TTSCREENFONT], (ULONG) currentPrefs.TrueTypeFonts.ttg_ScreenTTFontDesc); + setstring(app->Obj[POPSTRING_TTICONFONT], (ULONG) currentPrefs.TrueTypeFonts.ttg_IconTTFontDesc); + setstring(app->Obj[POPSTRING_ICONSPAGE_TTICONFONT], (ULONG) currentPrefs.TrueTypeFonts.ttg_IconTTFontDesc); + setstring(app->Obj[POPSTRING_TTTEXTWINDOWFONT], (ULONG) currentPrefs.TrueTypeFonts.ttg_TextWindowTTFontDesc); + setstring(app->Obj[POPSTRING_TEXTWINDOW_TTTEXTWINDOWFONT], (ULONG) currentPrefs.TrueTypeFonts.ttg_TextWindowTTFontDesc); + + SetAttrs(app->Obj[MCC_TTSCREENFONT_SAMPLE], + MUIA_FontSample_Antialias, currentPrefs.TrueTypeFonts.ttg_Antialias, + MUIA_FontSample_Gamma, currentPrefs.TrueTypeFonts.ttg_Gamma, + MUIA_FontSample_TTFontDesc, (ULONG) currentPrefs.TrueTypeFonts.ttg_ScreenTTFontDesc, + TAG_END); + SetAttrs(app->Obj[MCC_TTICONFONT_SAMPLE], + MUIA_FontSample_Antialias, currentPrefs.TrueTypeFonts.ttg_Antialias, + MUIA_FontSample_Gamma, currentPrefs.TrueTypeFonts.ttg_Gamma, + MUIA_FontSample_TTFontDesc, (ULONG) currentPrefs.TrueTypeFonts.ttg_IconTTFontDesc, + TAG_END); + SetAttrs(app->Obj[MCC_ICONSPAGE_TTICONFONT_SAMPLE], + MUIA_FontSample_Antialias, currentPrefs.TrueTypeFonts.ttg_Antialias, + MUIA_FontSample_Gamma, currentPrefs.TrueTypeFonts.ttg_Gamma, + MUIA_FontSample_TTFontDesc, (ULONG) currentPrefs.TrueTypeFonts.ttg_IconTTFontDesc, + TAG_END); + SetAttrs(app->Obj[MCC_TTTEXTWINDOWFONT_SAMPLE], + MUIA_FontSample_Antialias, currentPrefs.TrueTypeFonts.ttg_Antialias, + MUIA_FontSample_Gamma, currentPrefs.TrueTypeFonts.ttg_Gamma, + MUIA_FontSample_TTFontDesc, (ULONG) currentPrefs.TrueTypeFonts.ttg_TextWindowTTFontDesc, + TAG_END); + SetAttrs(app->Obj[MCC_TEXTWINDOW_TTTEXTWINDOWFONT_SAMPLE], + MUIA_FontSample_Antialias, currentPrefs.TrueTypeFonts.ttg_Antialias, + MUIA_FontSample_Gamma, currentPrefs.TrueTypeFonts.ttg_Gamma, + MUIA_FontSample_TTFontDesc, (ULONG) currentPrefs.TrueTypeFonts.ttg_TextWindowTTFontDesc, + TAG_END); + + // --- Misc Page + + setcheckmark(app->Obj[CHECK_MENUCURRENTDIR], currentPrefs.Miscellaneous.mg_bMenuCurrentDir); + setcheckmark(app->Obj[CHECK_HARDEMULATION], currentPrefs.Miscellaneous.mg_bHardEmulation); + setcheckmark(app->Obj[CHECK_USEEXALL], currentPrefs.Miscellaneous.mg_bUseExAll); + setcycle(app->Obj[CYCLE_CREATELINKS], currentPrefs.Miscellaneous.mg_bCreateSoftLinks); + setslider(app->Obj[SLIDER_DEFAULTSTACKSIZE], currentPrefs.Miscellaneous.mg_DefaultStackSize / 1024); + setslider(app->Obj[SLIDER_COPYBUFFERSIZE], GetLog2(currentPrefs.Miscellaneous.mg_CopyBuffSize)); + setslider(app->Obj[SLIDER_UNDOSTEPS], currentPrefs.Miscellaneous.mg_MaxUndoSteps); + + //Popup menu apply selected qualifier + TranslateQualifierToString(currentPrefs.Miscellaneous.mg_PopupApplySelectedQualifier, + currentPrefs.Miscellaneous.mg_PopupApplySelectedQualifierString, + sizeof(currentPrefs.Miscellaneous.mg_PopupApplySelectedQualifierString)); + setstring(app->Obj[POPUP_SELECTED_HOTKEY], (ULONG) currentPrefs.Miscellaneous.mg_PopupApplySelectedQualifierString); + + setcheckmark(app->Obj[CHECK_MISCPAGE_POPUP_SELECTED_ALWAYS], (ULONG) currentPrefs.Miscellaneous.mp_PopupApplySelectedAlways); + set(app->Obj[POPUP_SELECTED_HOTKEY], MUIA_Disabled, currentPrefs.Miscellaneous.mp_PopupApplySelectedAlways); + + // --- Plugins Page + + { + struct PluginDef *pd; + + set(app->Obj[PLUGIN_LIST], MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + + DoMethod(app->Obj[PLUGIN_LIST], MUIM_NList_Clear); + + for (pd = (struct PluginDef *) PluginList.lh_Head; + pd != (struct PluginDef *) &PluginList.lh_Tail; + pd = (struct PluginDef *) pd->plug_Node.mln_Succ) + { + DoMethod(app->Obj[PLUGIN_LIST], MUIM_NList_InsertSingle, + pd, + MUIV_NList_Insert_Sorted); + } + + set(app->Obj[PLUGIN_LIST], MUIA_NList_Quiet, MUIV_NList_Quiet_None); + DoMethod(app->Obj[PLUGIN_LIST], MUIM_NList_Redraw, MUIV_NList_Redraw_All); + } + + { + struct ControlBarGadgetEntry *cgy; + + set(app->Obj[NLIST_CONTROLBARGADGETS_BROWSER_ACTIVE], MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + + DoMethod(app->Obj[NLIST_CONTROLBARGADGETS_BROWSER_ACTIVE], MUIM_NList_Clear); + + // copy control bar gadgets to list + for (cgy = (struct ControlBarGadgetEntry *) ControlBarGadgetListBrowser.lh_Head; + cgy != (struct ControlBarGadgetEntry *) &ControlBarGadgetListBrowser.lh_Tail; + cgy = (struct ControlBarGadgetEntry *) cgy->cgy_Node.ln_Succ) + { + DoMethod(app->Obj[NLIST_CONTROLBARGADGETS_BROWSER_ACTIVE], + MUIM_NList_InsertSingle, + cgy, MUIV_NList_Insert_Bottom); + } + + set(app->Obj[NLIST_CONTROLBARGADGETS_BROWSER_ACTIVE], MUIA_NList_Quiet, MUIV_NList_Quiet_None); + DoMethod(app->Obj[NLIST_CONTROLBARGADGETS_BROWSER_ACTIVE], MUIM_NList_Redraw, MUIV_NList_Redraw_All); + } + + { + struct ControlBarGadgetEntry *cgy; + + set(app->Obj[NLIST_CONTROLBARGADGETS_NORMAL_ACTIVE], MUIA_NList_Quiet, MUIV_NList_Quiet_Full); + + DoMethod(app->Obj[NLIST_CONTROLBARGADGETS_NORMAL_ACTIVE], MUIM_NList_Clear); + + // copy control bar gadgets to list + for (cgy = (struct ControlBarGadgetEntry *) ControlBarGadgetListNormal.lh_Head; + cgy != (struct ControlBarGadgetEntry *) &ControlBarGadgetListNormal.lh_Tail; + cgy = (struct ControlBarGadgetEntry *) cgy->cgy_Node.ln_Succ) + { + DoMethod(app->Obj[NLIST_CONTROLBARGADGETS_NORMAL_ACTIVE], + MUIM_NList_InsertSingle, + cgy, MUIV_NList_Insert_Bottom); + } + + set(app->Obj[NLIST_CONTROLBARGADGETS_NORMAL_ACTIVE], MUIA_NList_Quiet, MUIV_NList_Quiet_None); + DoMethod(app->Obj[NLIST_CONTROLBARGADGETS_NORMAL_ACTIVE], MUIM_NList_Redraw, MUIV_NList_Redraw_All); + } + + FillHiddenDevicesList(app); + + DoMethod(app->Obj[APPLICATION], MUIM_CallHook, &CalculateMaxRadiusHook); +} + + +static void FillPrefsStructures(struct SCAModule *app) +{ + CONST_STRPTR lp; + ULONG x = 0; + + // --- Paths Page + lp = (CONST_STRPTR) getv(app->Obj[STRING_DISKCOPY], MUIA_String_Contents); + stccpy(currentPrefs.Paths.pg_pDiskCopy, lp, sizeof(currentPrefs.Paths.pg_pDiskCopy)); + lp = (CONST_STRPTR) getv(app->Obj[STRING_SCALOSHOME], MUIA_String_Contents); + stccpy(currentPrefs.Paths.pg_pHome, lp, sizeof(currentPrefs.Paths.pg_pHome)); + lp = (CONST_STRPTR) getv(app->Obj[STRING_THEMES], MUIA_String_Contents); + stccpy(currentPrefs.Paths.pg_pThemes, lp, sizeof(currentPrefs.Paths.pg_pThemes)); + lp = (CONST_STRPTR) getv(app->Obj[STRING_IMAGECACHE], MUIA_String_Contents); + stccpy(currentPrefs.Paths.pg_pImageCache, lp, sizeof(currentPrefs.Paths.pg_pImageCache)); + lp = (CONST_STRPTR) getv(app->Obj[STRING_THUMBNAILDB], MUIA_String_Contents); + stccpy(currentPrefs.Paths.pg_pThumbnailDb, lp, sizeof(currentPrefs.Paths.pg_pThumbnailDb)); + lp = (CONST_STRPTR) getv(app->Obj[STRING_FORMAT], MUIA_String_Contents); + stccpy(currentPrefs.Paths.pg_pFormat, lp, sizeof(currentPrefs.Paths.pg_pFormat)); + lp = (CONST_STRPTR) getv(app->Obj[STRING_SQLITE3TEMPPATH], MUIA_String_Contents); + stccpy(currentPrefs.Paths.pg_SQLiteTempDir, lp, sizeof(currentPrefs.Paths.pg_SQLiteTempDir)); + + // --- Startup Page + currentPrefs.Startup.sg_bShowSplash = getv(app->Obj[CHECK_SHOWSPLASH], MUIA_Selected); + currentPrefs.Startup.sg_bSplashCloseDelay = getv(app->Obj[SLIDER_SPLASHCLOSE], MUIA_Numeric_Value); + currentPrefs.Startup.sg_bWBStartupDelay = getv(app->Obj[SLIDER_WBSDELAY], MUIA_Numeric_Value); + lp = (CONST_STRPTR) getv(app->Obj[STRING_WBSTARTPATH], MUIA_String_Contents); + stccpy(currentPrefs.Startup.sg_pWBStartup, lp, sizeof(currentPrefs.Startup.sg_pWBStartup)); + + // --- Desktop Page + lp = (CONST_STRPTR) getv(app->Obj[POPPH_SCREENTITLE], MUIA_Popph_Contents); + stccpy(currentPrefs.Desktop.dg_pScreen, lp, sizeof(currentPrefs.Desktop.dg_pScreen)); + + lp = (CONST_STRPTR) getv(app->Obj[STRING_CONSOLENAME], MUIA_String_Contents); + stccpy(currentPrefs.Desktop.dg_ConsoleName, lp, sizeof(currentPrefs.Desktop.dg_ConsoleName)); + + + currentPrefs.Desktop.dg_bTitleRefresh = getv(app->Obj[SLIDER_TITLEREFRESH], MUIA_Numeric_Value); + currentPrefs.Desktop.dg_bMemoryRefresh = getv(app->Obj[CHECK_TITLEMEM], MUIA_Selected); + + currentPrefs.Desktop.dg_bWinTitleRefresh = getv(app->Obj[SLIDER_WINTITLEREFRESH], MUIA_Numeric_Value); + currentPrefs.Desktop.dg_bWinMemoryRefresh = getv(app->Obj[CHECK_WINTITLEMEM], MUIA_Selected); + + currentPrefs.Desktop.dg_bDiskRefresh = getv(app->Obj[SLIDER_DISKREFRESH], MUIA_Numeric_Value); + + currentPrefs.Desktop.dg_ScreenTitleMode = getv(app->Obj[CYCLE_SCREENTITLEMODE], MUIA_Cycle_Active); + switch (currentPrefs.Desktop.dg_ScreenTitleMode) + { + default: + case SCREENTITLE_Visible: + currentPrefs.Desktop.dg_bPopTitleBar = FALSE; + currentPrefs.Desktop.dg_bHideTitleBar = FALSE; + break; + case SCREENTITLE_Popup: + currentPrefs.Desktop.dg_bPopTitleBar = TRUE; + currentPrefs.Desktop.dg_bHideTitleBar = TRUE; + break; + case SCREENTITLE_Hidden: + currentPrefs.Desktop.dg_bPopTitleBar = FALSE; + currentPrefs.Desktop.dg_bHideTitleBar = TRUE; + break; + } + + currentPrefs.Desktop.dg_AutoLeaveOut = getv(app->Obj[CHECK_AUTOLEAVEOUT], MUIA_Selected); + currentPrefs.Desktop.dg_bDropStart = getv(app->Obj[DROPSTART], MUIA_Selected); + currentPrefs.Desktop.dg_bAllowCloseWB = getv(app->Obj[CLOSEWB], MUIA_Selected); + + // layout + currentPrefs.Icons.ig_DeviceWindowLayoutModes[WBDISK] = getv(app->Obj[CYCLE_DESKTOP_LAYOUT_WBDISK], MUIA_Cycle_Active); + currentPrefs.Icons.ig_DeviceWindowLayoutModes[WBDRAWER] = getv(app->Obj[CYCLE_DESKTOP_LAYOUT_WBDRAWER], MUIA_Cycle_Active); + currentPrefs.Icons.ig_DeviceWindowLayoutModes[WBTOOL] = getv(app->Obj[CYCLE_DESKTOP_LAYOUT_WBTOOL], MUIA_Cycle_Active); + currentPrefs.Icons.ig_DeviceWindowLayoutModes[WBPROJECT] = getv(app->Obj[CYCLE_DESKTOP_LAYOUT_WBPROJECT], MUIA_Cycle_Active); + currentPrefs.Icons.ig_DeviceWindowLayoutModes[WBGARBAGE] = getv(app->Obj[CYCLE_DESKTOP_LAYOUT_WBGARBAGE], MUIA_Cycle_Active); + currentPrefs.Icons.ig_DeviceWindowLayoutModes[WBDEVICE] = getv(app->Obj[CYCLE_DESKTOP_LAYOUT_WBDEVICE], MUIA_Cycle_Active); + currentPrefs.Icons.ig_DeviceWindowLayoutModes[WBKICK] = getv(app->Obj[CYCLE_DESKTOP_LAYOUT_WBKICK], MUIA_Cycle_Active); + currentPrefs.Icons.ig_DeviceWindowLayoutModes[WBAPPICON] = getv(app->Obj[CYCLE_DESKTOP_LAYOUT_WBAPPICON], MUIA_Cycle_Active); + + + // --- Icons Page + currentPrefs.Icons.ig_IconOffsets.Left = getv(app->Obj[ICONLEFT], MUIA_Numeric_Value); + currentPrefs.Icons.ig_IconOffsets.Top = getv(app->Obj[ICONRIGHT], MUIA_Numeric_Value); + currentPrefs.Icons.ig_IconOffsets.Width = getv(app->Obj[ICONTOP], MUIA_Numeric_Value); + currentPrefs.Icons.ig_IconOffsets.Height = getv(app->Obj[ICONBOTTOM], MUIA_Numeric_Value); + + currentPrefs.Icons.ig_wNormFrame = getv(app->Obj[FRAME_ICONNORMAL], MUIA_MCPFrame_FrameType); + currentPrefs.Icons.ig_wSelFrame = getv(app->Obj[FRAME_ICONSELECTED], MUIA_MCPFrame_FrameType); + currentPrefs.Icons.ig_wNormThumbnailFrame = getv(app->Obj[FRAME_ICON_THUMBNAIL_NORMAL], MUIA_MCPFrame_FrameType); + currentPrefs.Icons.ig_wSelThumbnailFrame = getv(app->Obj[FRAME_ICON_THUMBNAIL_SELECTED], MUIA_MCPFrame_FrameType); + + currentPrefs.Icons.ig_ThumbnailOffsets.Left = getv(app->Obj[THUMBNAILS_LEFTBORDER], MUIA_Numeric_Value); + currentPrefs.Icons.ig_ThumbnailOffsets.Top = getv(app->Obj[THUMBNAILS_RIGHTBORDER], MUIA_Numeric_Value); + currentPrefs.Icons.ig_ThumbnailOffsets.Width = getv(app->Obj[THUMBNAILS_TOPBORDER], MUIA_Numeric_Value); + currentPrefs.Icons.ig_ThumbnailOffsets.Height = getv(app->Obj[THUMBNAILS_BOTTOMBORDER], MUIA_Numeric_Value); + + currentPrefs.Icons.ig_bClickAreaMask = getv(app->Obj[CHECK_ICONMASK], MUIA_Selected); + currentPrefs.Icons.ig_bNewIconPrecision = getv(app->Obj[SLIDER_ICONRMAP_PRECISION], MUIA_Numeric_Value); + currentPrefs.Icons.ig_bNewIconTransparent = getv(app->Obj[CHECK_NIMASK], MUIA_Selected); + lp = (CONST_STRPTR) getv(app->Obj[STRING_DEFICONPATH], MUIA_String_Contents); + stccpy(currentPrefs.Paths.pg_pDefaultIcons, lp, sizeof(currentPrefs.Paths.pg_pDefaultIcons)); + + currentPrefs.Icons.ig_bLoadDefIconsFirst = getv(app->Obj[CHECK_DEFFIRST], MUIA_Selected); + currentPrefs.Icons.ig_bIconsSaveable = getv(app->Obj[CHECK_ICONSSAVE], MUIA_Selected); + currentPrefs.Icons.ig_bShowTooltips = getv(app->Obj[CHECK_TOOLTIPS], MUIA_Selected); + currentPrefs.Icons.ig_bTooltipDelay = getv(app->Obj[SLIDER_TIPDELAY], MUIA_Numeric_Value); + currentPrefs.Icons.ig_TransparencyTooltips = getv(app->Obj[SLIDER_ICONTOOLTIPS_TRANSPARENCY], MUIA_Numeric_Value); + lp = (CONST_STRPTR) getv(app->Obj[STRING_TOOLTIPFONT], MUIA_String_Contents); + stccpy(currentPrefs.Icons.ig_ToolTipFont, lp, sizeof(currentPrefs.Icons.ig_ToolTipFont)); + + lp = (CONST_STRPTR) getv(app->Obj[POP_ICONFONT], MUIA_String_Contents); + stccpy(currentPrefs.Icons.ig_IconFontDesc, lp, sizeof(currentPrefs.Icons.ig_IconFontDesc)); + + currentPrefs.Icons.ig_wMultipleLines = getv(app->Obj[CHECK_MULTILINES], MUIA_Selected); + currentPrefs.Icons.ig_HighlightUnderMouse = getv(app->Obj[CHECK_HILITEUNDERMOUSE], MUIA_Selected); + currentPrefs.Icons.ig_ShowThumbnails = getv(app->Obj[CYCLE_SHOWTHUMBNAILS], MUIA_Cycle_Active); + + currentPrefs.Icons.ig_ShowThumbnailsAsDefault = getv(app->Obj[CHECK_SHOWTHUMBNAILS_AS_DEFAULT], MUIA_Selected); + currentPrefs.Icons.ig_bSquareThumbnails = getv(app->Obj[CHECK_THUMBNAILS_SQUARE], MUIA_Selected); + currentPrefs.Icons.ig_ThumbnailsBackfill = getv(app->Obj[CHECK_THUMBNAILS_BACKFILL], MUIA_Selected); + currentPrefs.Icons.ig_ThumbnailBackgroundTransparency = getv(app->Obj[SLIDER_ICONTRANSPARENCY_THUMBNAILBACK], MUIA_Numeric_Value); + + currentPrefs.Icons.ig_SelectedTextRectangle = getv(app->Obj[CHECK_SEL_ICONTEXT_RECTANGLE], MUIA_Selected); + currentPrefs.Icons.ig_SelTextRectBorderX = getv(app->Obj[SLIDER_SEL_ICONTEXT_RECT_BORDERX], MUIA_Numeric_Value); + currentPrefs.Icons.ig_SelTextRectBorderY = getv(app->Obj[SLIDER_SEL_ICONTEXT_RECT_BORDERY], MUIA_Numeric_Value); + currentPrefs.Icons.ig_SelTextRectRadius = getv(app->Obj[SLIDER_SEL_ICONTEXT_RECT_RADIUS], MUIA_Numeric_Value); + + currentPrefs.Icons.ig_ThumbnailMaxAge = getv(app->Obj[SLIDER_THUMBNAILS_MAXAGE], MUIA_Numeric_Value); + currentPrefs.Icons.ig_ThumbnailMinSizeLimit = getv(app->Obj[SLIDER_THUMBNAILS_MINSIZE_LIMIT], MUIA_Numeric_Value); + currentPrefs.Icons.ig_ThumbnailQuality = getv(app->Obj[SLIDER_THUMBNAILS_QUALITY], MUIA_Numeric_Value); + + currentPrefs.Icons.ig_ThumbnailSize = GetThumbNailSize(app); + GetIconSizeConstraints(app, ¤tPrefs.Icons.ig_SizeConstraints); + + currentPrefs.Icons.ig_NominalSize = getv(app->Obj[SLIDER_ICONSPAGE_NOMINALSIZE], MUIA_Numeric_Value); + + // layout + currentPrefs.Icons.ig_IconWindowLayoutModes[WBDRAWER] = getv(app->Obj[CYCLE_ICONS_LAYOUT_WBDRAWER], MUIA_Cycle_Active); + currentPrefs.Icons.ig_IconWindowLayoutModes[WBTOOL] = getv(app->Obj[CYCLE_ICONS_LAYOUT_WBTOOL], MUIA_Cycle_Active); + currentPrefs.Icons.ig_IconWindowLayoutModes[WBPROJECT] = getv(app->Obj[CYCLE_ICONS_LAYOUT_WBPROJECT], MUIA_Cycle_Active); + + //tooltip display field + currentPrefs.DragNDrop.ddg_bBobStyle = getv(app->Obj[CYCLE_STYLE], MUIA_Cycle_Active); + currentPrefs.DragNDrop.ddg_bBobMethod = getv(app->Obj[CYCLE_ROUTINE], MUIA_Cycle_Active); + currentPrefs.DragNDrop.ddg_bBobLook = getv(app->Obj[RADIO_BOBLOOK], MUIA_Radio_Active); + currentPrefs.DragNDrop.ddg_bTranspType = getv(app->Obj[CYCLE_TRANSPMODE], MUIA_Cycle_Active); + currentPrefs.DragNDrop.ddg_bDropMarkMode = getv(app->Obj[CYCLE_DROPMARK], MUIA_Cycle_Active); + currentPrefs.DragNDrop.ddg_TransparencyIconDrag = getv(app->Obj[SLIDER_ICONTRANSPARENCY_DRAG], MUIA_Numeric_Value); + currentPrefs.DragNDrop.ddg_TransparencyIconShadow = getv(app->Obj[SLIDER_ICONTRANSPARENCY_SHADOW], MUIA_Numeric_Value); + currentPrefs.Icons.ig_TransparencyDefaultIcons = getv(app->Obj[SLIDER_ICONTRANSPARENCY_DEFICONS], MUIA_Numeric_Value); + + currentPrefs.DragNDrop.ddg_bAutoRemoveIcons = getv(app->Obj[CHECK_AUTOREMOVE], MUIA_Selected); + currentPrefs.DragNDrop.ddg_bEasyMultiSelect = getv(app->Obj[CHECK_EASY_MULTISELECT], MUIA_Selected); + currentPrefs.DragNDrop.ddg_bEasyMultiDrag = getv(app->Obj[CHECK_EASY_MULTIDRAG], MUIA_Selected); + currentPrefs.DragNDrop.ddg_bGroupDrag = !getv(app->Obj[CHECK_GROUPDRAG], MUIA_Selected); + currentPrefs.DragNDrop.ddg_bShowObjectCount = getv(app->Obj[CHECK_SHOWDRAG], MUIA_Selected); + currentPrefs.DragNDrop.ddg_bEnableDropMenu = getv(app->Obj[CHECK_ENABLE_DROPMENU], MUIA_Selected); + currentPrefs.DragNDrop.ddg_PopupWindowDelaySeconds = getv(app->Obj[SLIDER_POPOPENWINDOW_DELAY], MUIA_Numeric_Value); + + //copy qualifier + lp = (CONST_STRPTR) getv(app->Obj[COPY_HOTKEY], MUIA_String_Contents); + stccpy(currentPrefs.DragNDrop.ddg_CopyQualifierString, lp, sizeof(currentPrefs.DragNDrop.ddg_CopyQualifierString)); + currentPrefs.DragNDrop.ddg_pCopyQualifier = TranslateStringToQualifier(currentPrefs.DragNDrop.ddg_CopyQualifierString); + //MakeLink qualifier + lp = (CONST_STRPTR) getv(app->Obj[MAKELINK_HOTKEY], MUIA_String_Contents); + stccpy(currentPrefs.DragNDrop.ddg_MakeLinkQualifierString, lp, sizeof(currentPrefs.DragNDrop.ddg_MakeLinkQualifierString)); + currentPrefs.DragNDrop.ddg_pMakeLinkQualifier = TranslateStringToQualifier(currentPrefs.DragNDrop.ddg_MakeLinkQualifierString); + //Move qualifier + lp = (CONST_STRPTR) getv(app->Obj[MOVE_HOTKEY], MUIA_String_Contents); + stccpy(currentPrefs.DragNDrop.ddg_MoveQualifierString, lp, sizeof(currentPrefs.DragNDrop.ddg_MoveQualifierString)); + currentPrefs.DragNDrop.ddg_pMoveQualifier = TranslateStringToQualifier(currentPrefs.DragNDrop.ddg_MoveQualifierString); + + //Single-Window Lasso qualifier + lp = (CONST_STRPTR) getv(app->Obj[SINGLE_WINDOW_LASSO_HOTKEY], MUIA_String_Contents); + stccpy(currentPrefs.Desktop.dg_SingleWindowLassoQualifierString, lp, sizeof(currentPrefs.Desktop.dg_SingleWindowLassoQualifierString)); + currentPrefs.Desktop.dg_SingleWindowLassoQualifier = TranslateStringToQualifier(currentPrefs.Desktop.dg_SingleWindowLassoQualifierString); + + //triggers + currentPrefs.DragNDrop.ddg_lTriggers = 0; + get(app->Obj[CHECK_TRIG_DISK], MUIA_Selected, &x); + if (x) + currentPrefs.DragNDrop.ddg_lTriggers |= DRAGTRANSPF_DiskIcons; + get(app->Obj[CHECK_TRIG_DRAWER], MUIA_Selected, &x); + if (x) + currentPrefs.DragNDrop.ddg_lTriggers |= DRAGTRANSPF_DrawerIcons; + get(app->Obj[CHECK_TRIG_TOOL], MUIA_Selected, &x); + if (x) + currentPrefs.DragNDrop.ddg_lTriggers |= DRAGTRANSPF_ToolIcons; + get(app->Obj[CHECK_TRIG_PROJECT], MUIA_Selected, &x); + if (x) + currentPrefs.DragNDrop.ddg_lTriggers |= DRAGTRANSPF_ProjectIcons; + get(app->Obj[CHECK_TRIG_TRASHCAN], MUIA_Selected, &x); + if (x) + currentPrefs.DragNDrop.ddg_lTriggers |= DRAGTRANSPF_TrashcanIcons; + get(app->Obj[CHECK_TRIG_KICK], MUIA_Selected, &x); + if (x) + currentPrefs.DragNDrop.ddg_lTriggers |= DRAGTRANSPF_KickIcons; + get(app->Obj[CHECK_TRIG_APPICON], MUIA_Selected, &x); + if (x) + currentPrefs.DragNDrop.ddg_lTriggers |= DRAGTRANSPF_AppIcons; + get(app->Obj[CHECK_TRIG_APPWIN], MUIA_Selected, &x); + if (x) + currentPrefs.DragNDrop.ddg_lTriggers |= DRAGTRANSPF_AppWindows; + get(app->Obj[CHECK_TRIG_ICONIFIEDWIN], MUIA_Selected, &x); + if (x) + currentPrefs.DragNDrop.ddg_lTriggers |= DRAGTRANSPF_IconifiedWinIcons; + get(app->Obj[CHECK_TRIG_SCALOSWIN], MUIA_Selected, &x); + if (x) + currentPrefs.DragNDrop.ddg_lTriggers |= DRAGTRANSPF_ScalosWindows; + + // --- Windows Page + lp = (CONST_STRPTR) getv(app->Obj[POPPH_ROOTWINDOWTITLE], MUIA_Popph_Contents); + stccpy(currentPrefs.Windows.wg_pRootWin, lp, sizeof(currentPrefs.Windows.wg_pRootWin)); + lp = (CONST_STRPTR) getv(app->Obj[POPPH_DIRWINDOWTITLE], MUIA_Popph_Contents); + stccpy(currentPrefs.Windows.wg_pWindow, lp, sizeof(currentPrefs.Windows.wg_pWindow)); + + currentPrefs.Windows.wg_bType = getv(app->Obj[CYCLE_WINDOWTYPE], MUIA_Cycle_Active); + currentPrefs.Windows.wg_bPopTitleOnly = getv(app->Obj[CHECK_POPTITLEONLY], MUIA_Selected); + currentPrefs.Windows.wg_bMMBMove = getv(app->Obj[CHECK_MMBMOVE], MUIA_Selected); + currentPrefs.Windows.wg_DefaultSize.Left = getv(app->Obj[WINLEFT], MUIA_String_Integer); + currentPrefs.Windows.wg_DefaultSize.Top = getv(app->Obj[WINTOP], MUIA_String_Integer); + currentPrefs.Windows.wg_DefaultSize.Width = getv(app->Obj[WINWIDTH], MUIA_String_Integer); + currentPrefs.Windows.wg_DefaultSize.Height = getv(app->Obj[WINHEIGHT], MUIA_String_Integer); + currentPrefs.Windows.wg_CleanupSpaces.Left = getv(app->Obj[SLIDER_CLEANLEFT], MUIA_Numeric_Value); + currentPrefs.Windows.wg_CleanupSpaces.Top = getv(app->Obj[SLIDER_CLEANTOP], MUIA_Numeric_Value); + currentPrefs.Windows.wg_CleanupSpaces.Width = getv(app->Obj[SLIDER_CLEANXSKIP], MUIA_Numeric_Value); + currentPrefs.Windows.wg_CleanupSpaces.Height = getv(app->Obj[SLIDER_CLEANYSKIP], MUIA_Numeric_Value); + currentPrefs.Windows.wg_bStatusBar = getv(app->Obj[CHECK_STATUSBAR], MUIA_Selected); + currentPrefs.Windows.wg_CheckOverlappingIcons = getv(app->Obj[CHECK_CHECKOVERLAP], MUIA_Selected); + currentPrefs.Windows.wg_TransparencyActiveWindow = getv(app->Obj[SLIDER_TRANSPARENCY_ACTIVEWINDOW], MUIA_Numeric_Value); + currentPrefs.Windows.wg_wTransparencyInactiveWindow = getv(app->Obj[SLIDER_TRANSPARENCY_INACTIVEWINDOW], MUIA_Numeric_Value); + + currentPrefs.Windows.wg_bCleanupOnResize = getv(app->Obj[CHECK_CLEANUP_ONRESIZE], MUIA_Selected); + currentPrefs.Windows.wg_bHideProtectHiddenFiles = getv(app->Obj[HIDEPROTECTHIDDENFILES], MUIA_Selected); // JMC + currentPrefs.Windows.wg_bHideHiddenFiles = getv(app->Obj[HIDEHIDDENFILES], MUIA_Selected); + currentPrefs.Windows.wg_ShowAllByDefault = getv(app->Obj[CYCLE_SHOWALLDEFAULT], MUIA_Cycle_Active); + currentPrefs.Windows.wg_ViewByDefault = 1 + getv(app->Obj[CYCLE_VIEWBYICONSDEFAULT], MUIA_Cycle_Active); + + + // --- File Display Page + currentPrefs.TextWindows.fd_wLabelStyle = getv(app->Obj[CYCLE_LABELSTYLE], MUIA_Cycle_Active); + currentPrefs.TextWindows.fd_wTextSkip = getv(app->Obj[SLIDER_LABELSPACE], MUIA_Numeric_Value); + currentPrefs.TextWindows.fd_bShowSoftLinks = getv(app->Obj[SOFTICONSLINK], MUIA_Selected); + lp = (CONST_STRPTR) getv(app->Obj[POP_TEXTMODEFONT], MUIA_String_Contents); + stccpy(currentPrefs.TextWindows.fd_TextWindowFontDescr, lp, sizeof(currentPrefs.TextWindows.fd_TextWindowFontDescr)); + //currentPrefs.TextWindows.fd_lDisplayFields = getv(app->Obj[], MUIA_); + currentPrefs.TextWindows.fd_bShowStripes = getv(app->Obj[CHECK_STRIPED_WINDOW], MUIA_Selected); + currentPrefs.TextWindows.fd_SelectTextIconName = getv(app->Obj[CHECK_SELECTTEXTICONNAME], MUIA_Selected); + currentPrefs.TextWindows.fd_DrawerSortMode = getv(app->Obj[CYCLE_DRAWERSORTMODE], MUIA_Cycle_Active); + + currentPrefs.TextWindows.fd_SelectMarkerBaseColor.Red = getv(app->Obj[COLORADJUST_TEXTWINDOWS_SELECTIONMARK], MUIA_Coloradjust_Red) >> 24; + currentPrefs.TextWindows.fd_SelectMarkerBaseColor.Green = getv(app->Obj[COLORADJUST_TEXTWINDOWS_SELECTIONMARK], MUIA_Coloradjust_Green) >> 24; + currentPrefs.TextWindows.fd_SelectMarkerBaseColor.Blue = getv(app->Obj[COLORADJUST_TEXTWINDOWS_SELECTIONMARK], MUIA_Coloradjust_Blue) >> 24; + currentPrefs.TextWindows.fd_SelectMarkerTransparency = getv(app->Obj[SLIDER_TEXTWINDOWS_SELECTFILLTRANSPARENCY], MUIA_Numeric_Value); + currentPrefs.TextWindows.fd_SelectMarkerBaseColor.Alpha = getv(app->Obj[SLIDER_TEXTWINDOWS_SELECTBORDERTRANSPARENCY], MUIA_Numeric_Value); + + UpdateFileDisplayPrefsFromGUI(app); + + // --- TrueType Font Page + currentPrefs.TrueTypeFonts.ttg_Antialias = getv(app->Obj[CYCLE_TTANTIALIAS], MUIA_Cycle_Active); + currentPrefs.TrueTypeFonts.ttg_Gamma = getv(app->Obj[SLIDER_TTGAMMA], MUIA_Numeric_Value); + currentPrefs.TrueTypeFonts.ttg_UseScreenTTFont = getv(app->Obj[CHECK_TTSCREENFONT_ENABLE], MUIA_Selected); + currentPrefs.TrueTypeFonts.ttg_UseIconTTFont = getv(app->Obj[CHECK_TTICONFONT_ENABLE], MUIA_Selected); + currentPrefs.TrueTypeFonts.ttg_UseTextWindowTTFont = getv(app->Obj[CHECK_TTTEXTWINDOWFONT_ENABLE], MUIA_Selected); + lp = (CONST_STRPTR) getv(app->Obj[POPSTRING_TTSCREENFONT], MUIA_String_Contents); + stccpy(currentPrefs.TrueTypeFonts.ttg_ScreenTTFontDesc, lp, sizeof(currentPrefs.TrueTypeFonts.ttg_ScreenTTFontDesc)); + lp = (CONST_STRPTR) getv(app->Obj[POPSTRING_TTICONFONT], MUIA_String_Contents); + stccpy(currentPrefs.TrueTypeFonts.ttg_IconTTFontDesc, lp, sizeof(currentPrefs.TrueTypeFonts.ttg_IconTTFontDesc)); + lp = (CONST_STRPTR) getv(app->Obj[POPSTRING_TTTEXTWINDOWFONT], MUIA_String_Contents); + stccpy(currentPrefs.TrueTypeFonts.ttg_TextWindowTTFontDesc, lp, sizeof(currentPrefs.TrueTypeFonts.ttg_TextWindowTTFontDesc)); + + // --- Misc Page + currentPrefs.Miscellaneous.mg_bMenuCurrentDir = getv(app->Obj[CHECK_MENUCURRENTDIR], MUIA_Selected); + currentPrefs.Miscellaneous.mg_bHardEmulation = getv(app->Obj[CHECK_HARDEMULATION], MUIA_Selected); + currentPrefs.Miscellaneous.mg_bUseExAll = getv(app->Obj[CHECK_USEEXALL], MUIA_Selected); + currentPrefs.Miscellaneous.mg_bCreateSoftLinks = getv(app->Obj[CYCLE_CREATELINKS], MUIA_Cycle_Active); + currentPrefs.Miscellaneous.mg_DefaultStackSize = 1024 * getv(app->Obj[SLIDER_DEFAULTSTACKSIZE], MUIA_Slider_Level); + currentPrefs.Miscellaneous.mg_CopyBuffSize = 1 << getv(app->Obj[SLIDER_COPYBUFFERSIZE], MUIA_Slider_Level); + currentPrefs.Miscellaneous.mg_MaxUndoSteps = getv(app->Obj[SLIDER_UNDOSTEPS], MUIA_Slider_Level); + + //Popup menu apply selected qualifier + lp = (CONST_STRPTR) getv(app->Obj[POPUP_SELECTED_HOTKEY], MUIA_String_Contents); + stccpy(currentPrefs.Miscellaneous.mg_PopupApplySelectedQualifierString, + lp, sizeof(currentPrefs.Miscellaneous.mg_PopupApplySelectedQualifierString)); + currentPrefs.Miscellaneous.mg_PopupApplySelectedQualifier = + TranslateStringToQualifier(currentPrefs.Miscellaneous.mg_PopupApplySelectedQualifierString); + currentPrefs.Miscellaneous.mp_PopupApplySelectedAlways = getv(app->Obj[CHECK_MISCPAGE_POPUP_SELECTED_ALWAYS], MUIA_Selected); + + // --- Plugins Page +} + +LONG WriteScalosPrefs(struct SCAModule *app, CONST_STRPTR PrefsFileName) +{ + LONG lID; + APTR p_MyPrefsHandle; +// STRPTR PrefsFileName = "ram:scalos.prefs"; + + // temp variables for big endian writes + struct IBox ibox; + struct Rectangle rect; + + FillPrefsStructures(app); + + p_MyPrefsHandle = AllocPrefsHandle("ScalosPrefs"); + lID = MAKE_ID('M', 'A', 'I', 'N'); + + if(p_MyPrefsHandle) + { + ibox.Left = SCA_WORD2BE(currentPrefs.Icons.ig_IconOffsets.Left); + ibox.Top = SCA_WORD2BE(currentPrefs.Icons.ig_IconOffsets.Top); + ibox.Width = SCA_WORD2BE(currentPrefs.Icons.ig_IconOffsets.Width); + ibox.Height = SCA_WORD2BE(currentPrefs.Icons.ig_IconOffsets.Height); + SetPreferences(p_MyPrefsHandle, lID, SCP_IconOffsets, &ibox, sizeof(ibox) ); + + SetWordPreferences(p_MyPrefsHandle, lID, SCP_IconNormFrame, ¤tPrefs.Icons.ig_wNormFrame, sizeof(currentPrefs.Icons.ig_wNormFrame) ); + SetWordPreferences(p_MyPrefsHandle, lID, SCP_IconSelFrame, ¤tPrefs.Icons.ig_wSelFrame, sizeof(currentPrefs.Icons.ig_wSelFrame) ); + SetWordPreferences(p_MyPrefsHandle, lID, SCP_IconNormThumbnailFrame, ¤tPrefs.Icons.ig_wNormThumbnailFrame, sizeof(currentPrefs.Icons.ig_wNormThumbnailFrame) ); + SetWordPreferences(p_MyPrefsHandle, lID, SCP_IconSelThumbnailFrame, ¤tPrefs.Icons.ig_wSelThumbnailFrame, sizeof(currentPrefs.Icons.ig_wSelThumbnailFrame) ); + SetWordPreferences(p_MyPrefsHandle, lID, SCP_IconTextMode, ¤tPrefs.TextWindows.fd_wLabelStyle, sizeof(currentPrefs.TextWindows.fd_wLabelStyle) ); + + SetPreferences(p_MyPrefsHandle, lID, SCP_IconSecLine, ¤tPrefs.Icons.ig_wMultipleLines, sizeof(currentPrefs.Icons.ig_wMultipleLines) ); + // BYTE + + rect.MinX = SCA_WORD2BE(currentPrefs.Icons.ig_SizeConstraints.MinX); + rect.MinY = SCA_WORD2BE(currentPrefs.Icons.ig_SizeConstraints.MinY); + rect.MaxX = SCA_WORD2BE(currentPrefs.Icons.ig_SizeConstraints.MaxX); + rect.MaxY = SCA_WORD2BE(currentPrefs.Icons.ig_SizeConstraints.MaxY); + SetPreferences(p_MyPrefsHandle, lID, SCP_IconSizeConstraints, &rect, sizeof(rect) ); + + SetWordPreferences(p_MyPrefsHandle, lID, SCP_IconNominalSize, ¤tPrefs.Icons.ig_NominalSize, sizeof(currentPrefs.Icons.ig_NominalSize) ); + SetPreferences(p_MyPrefsHandle, lID, SCP_IconHiliteUnderMouse, ¤tPrefs.Icons.ig_HighlightUnderMouse, sizeof(currentPrefs.Icons.ig_HighlightUnderMouse) ); + // BYTE + + SetWordPreferences(p_MyPrefsHandle, lID, SCP_IconTextSkip, ¤tPrefs.TextWindows.fd_wTextSkip, sizeof(currentPrefs.TextWindows.fd_wTextSkip) ); + SetPreferences(p_MyPrefsHandle, lID, SCP_ShowThumbnails, ¤tPrefs.Icons.ig_ShowThumbnails, sizeof(currentPrefs.Icons.ig_ShowThumbnails) ); + // UBYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_ShowThumbnailsAsDefault, ¤tPrefs.Icons.ig_ShowThumbnailsAsDefault, sizeof(currentPrefs.Icons.ig_ShowThumbnailsAsDefault) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_ThumbnailsSquare, ¤tPrefs.Icons.ig_bSquareThumbnails, sizeof(currentPrefs.Icons.ig_bSquareThumbnails) ); + // BYTE + + SetWordPreferences(p_MyPrefsHandle, lID, SCP_ThumbnailSize, ¤tPrefs.Icons.ig_ThumbnailSize, sizeof(currentPrefs.Icons.ig_ThumbnailSize) ); + SetWordPreferences(p_MyPrefsHandle, lID, SCP_ThumbnailMaxAge, ¤tPrefs.Icons.ig_ThumbnailMaxAge, sizeof(currentPrefs.Icons.ig_ThumbnailMaxAge) ); + SetWordPreferences(p_MyPrefsHandle, lID, SCP_ThumbnailMinSizeLimit, ¤tPrefs.Icons.ig_ThumbnailMinSizeLimit, sizeof(currentPrefs.Icons.ig_ThumbnailMinSizeLimit) ); + + SetLongPreferences(p_MyPrefsHandle, lID, SCP_ThumbnailQuality, ¤tPrefs.Icons.ig_ThumbnailQuality, sizeof(currentPrefs.Icons.ig_ThumbnailQuality) ); + + ibox.Left = SCA_WORD2BE(currentPrefs.Icons.ig_ThumbnailOffsets.Left); + ibox.Top = SCA_WORD2BE(currentPrefs.Icons.ig_ThumbnailOffsets.Top); + ibox.Width = SCA_WORD2BE(currentPrefs.Icons.ig_ThumbnailOffsets.Width); + ibox.Height = SCA_WORD2BE(currentPrefs.Icons.ig_ThumbnailOffsets.Height); + SetPreferences(p_MyPrefsHandle, lID, SCP_ThumbnailOffsets, &ibox, sizeof(ibox) ); + + SetPreferences(p_MyPrefsHandle, lID, SCP_ThumbnailsFillBackground, ¤tPrefs.Icons.ig_ThumbnailsBackfill, sizeof(currentPrefs.Icons.ig_ThumbnailsBackfill) ); + // UBYTE + + SetWordPreferences(p_MyPrefsHandle, lID, SCP_TransparencyThumbnailsBack, ¤tPrefs.Icons.ig_ThumbnailBackgroundTransparency, sizeof(currentPrefs.Icons.ig_ThumbnailBackgroundTransparency) ); + + SetPreferences(p_MyPrefsHandle, lID, SCP_SelectedTextRectangle, ¤tPrefs.Icons.ig_SelectedTextRectangle, sizeof(currentPrefs.Icons.ig_SelectedTextRectangle) ); + // UBYTE + + SetWordPreferences(p_MyPrefsHandle, lID, SCP_SelTextRectBorderX, ¤tPrefs.Icons.ig_SelTextRectBorderX, sizeof(currentPrefs.Icons.ig_SelTextRectBorderX) ); + SetWordPreferences(p_MyPrefsHandle, lID, SCP_SelTextRectBorderY, ¤tPrefs.Icons.ig_SelTextRectBorderY, sizeof(currentPrefs.Icons.ig_SelTextRectBorderY) ); + SetWordPreferences(p_MyPrefsHandle, lID, SCP_SelTextRectRadius, ¤tPrefs.Icons.ig_SelTextRectRadius, sizeof(currentPrefs.Icons.ig_SelTextRectRadius) ); + + SetPreferences(p_MyPrefsHandle, lID, SCP_DeviceWinIconLayout, currentPrefs.Icons.ig_DeviceWindowLayoutModes, sizeof(currentPrefs.Icons.ig_DeviceWindowLayoutModes)); + // UBYTE[] + + SetPreferences(p_MyPrefsHandle, lID, SCP_IconWinIconLayout, currentPrefs.Icons.ig_IconWindowLayoutModes, sizeof(currentPrefs.Icons.ig_IconWindowLayoutModes)); + // UBYTE[] + + SetPreferences(p_MyPrefsHandle, lID, SCP_BobsType, ¤tPrefs.DragNDrop.ddg_bBobStyle, sizeof(currentPrefs.DragNDrop.ddg_bBobStyle) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_BobsMethod, ¤tPrefs.DragNDrop.ddg_bBobMethod, sizeof(currentPrefs.DragNDrop.ddg_bBobMethod) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_BobsTranspMode, ¤tPrefs.DragNDrop.ddg_bBobLook, sizeof(currentPrefs.DragNDrop.ddg_bBobLook) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_BobsTranspType, ¤tPrefs.DragNDrop.ddg_bTranspType, sizeof(currentPrefs.DragNDrop.ddg_bTranspType) ); + // BYTE + + SetLongPreferences(p_MyPrefsHandle, lID, SCP_BobsTransp, ¤tPrefs.DragNDrop.ddg_lTriggers, sizeof(currentPrefs.DragNDrop.ddg_lTriggers) ); + + SetPreferences(p_MyPrefsHandle, lID, SCP_ScreenTitle, currentPrefs.Desktop.dg_pScreen, 1 + strlen(currentPrefs.Desktop.dg_pScreen) ); + // char[] + + SetPreferences(p_MyPrefsHandle, lID, SCP_RootWinTitle, currentPrefs.Windows.wg_pRootWin, 1 + strlen(currentPrefs.Windows.wg_pRootWin) ); + // char[] + + SetPreferences(p_MyPrefsHandle, lID, SCP_WindowTitle, currentPrefs.Windows.wg_pWindow, 1 + strlen(currentPrefs.Windows.wg_pWindow) ); + // char[] + + SetPreferences(p_MyPrefsHandle, lID, SCP_TTfAntialiasing, ¤tPrefs.TrueTypeFonts.ttg_Antialias, sizeof(currentPrefs.TrueTypeFonts.ttg_Antialias) ); + // BYTE + + SetWordPreferences(p_MyPrefsHandle, lID, SCP_TTfGamma, ¤tPrefs.TrueTypeFonts.ttg_Gamma, sizeof(currentPrefs.TrueTypeFonts.ttg_Gamma) ); + SetPreferences(p_MyPrefsHandle, lID, SCP_TTScreenFontDesc, currentPrefs.TrueTypeFonts.ttg_ScreenTTFontDesc, 1 + strlen(currentPrefs.TrueTypeFonts.ttg_ScreenTTFontDesc) ); + // char[] + + SetPreferences(p_MyPrefsHandle, lID, SCP_TTIconFontDesc, currentPrefs.TrueTypeFonts.ttg_IconTTFontDesc, 1 + strlen(currentPrefs.TrueTypeFonts.ttg_IconTTFontDesc) ); + // char[] + + SetPreferences(p_MyPrefsHandle, lID, SCP_TTTextWindowFontDesc, currentPrefs.TrueTypeFonts.ttg_TextWindowTTFontDesc, 1 + strlen(currentPrefs.TrueTypeFonts.ttg_TextWindowTTFontDesc) ); + // char[] + + SetPreferences(p_MyPrefsHandle, lID, SCP_UseTTScreenFont, ¤tPrefs.TrueTypeFonts.ttg_UseScreenTTFont, sizeof(currentPrefs.TrueTypeFonts.ttg_UseScreenTTFont) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_UseTTIconFont, ¤tPrefs.TrueTypeFonts.ttg_UseIconTTFont, sizeof(currentPrefs.TrueTypeFonts.ttg_UseIconTTFont) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_UseTTTextWindowFont, ¤tPrefs.TrueTypeFonts.ttg_UseTextWindowTTFont, sizeof(currentPrefs.TrueTypeFonts.ttg_UseTextWindowTTFont) ); + // BYTE + + //SetPreferences(p_MyPrefsHandle, lID, SCP_Seperator, , sizeof() ); + + SetPreferences(p_MyPrefsHandle, lID, SCP_TitleRefresh, ¤tPrefs.Desktop.dg_bTitleRefresh, sizeof(currentPrefs.Desktop.dg_bTitleRefresh) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_RefreshOnMemoryChange, ¤tPrefs.Desktop.dg_bMemoryRefresh, sizeof(currentPrefs.Desktop.dg_bMemoryRefresh) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_WinTitleRefresh, ¤tPrefs.Desktop.dg_bWinTitleRefresh, sizeof(currentPrefs.Desktop.dg_bWinTitleRefresh) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_WinRefreshOnMemoryChange, ¤tPrefs.Desktop.dg_bWinMemoryRefresh, sizeof(currentPrefs.Desktop.dg_bWinMemoryRefresh) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_ConsoleName, currentPrefs.Desktop.dg_ConsoleName, 1 + strlen(currentPrefs.Desktop.dg_ConsoleName) ); + // char[] + + SetPreferences(p_MyPrefsHandle, lID, SCP_PathsDefIcons, ¤tPrefs.Paths.pg_pDefaultIcons, 1 + strlen(currentPrefs.Paths.pg_pDefaultIcons) ); + // char[] + + SetPreferences(p_MyPrefsHandle, lID, SCP_PathsDiskCopy, ¤tPrefs.Paths.pg_pDiskCopy, 1 + strlen(currentPrefs.Paths.pg_pDiskCopy) ); + // char[] + + SetPreferences(p_MyPrefsHandle, lID, SCP_PathsTheme, ¤tPrefs.Paths.pg_pThemes, 1 + strlen(currentPrefs.Paths.pg_pThemes) ); + // char[] + + SetPreferences(p_MyPrefsHandle, lID, SCP_PathsImagecache, ¤tPrefs.Paths.pg_pImageCache, 1 + strlen(currentPrefs.Paths.pg_pImageCache) ); + // char[] + + SetPreferences(p_MyPrefsHandle, lID, SCP_PathsThumbnailDb, ¤tPrefs.Paths.pg_pThumbnailDb, 1 + strlen(currentPrefs.Paths.pg_pThumbnailDb) ); + // char[] + + SetPreferences(p_MyPrefsHandle, lID, SCP_PathsWBStartup, ¤tPrefs.Startup.sg_pWBStartup, 1 + strlen(currentPrefs.Startup.sg_pWBStartup) ); + // char[] + + SetPreferences(p_MyPrefsHandle, lID, SCP_PathsHome, ¤tPrefs.Paths.pg_pHome, 1 + strlen(currentPrefs.Paths.pg_pHome) ); + // char[] + + SetPreferences(p_MyPrefsHandle, lID, SCP_PathsSQLiteTempDir, ¤tPrefs.Paths.pg_SQLiteTempDir, 1 + strlen(currentPrefs.Paths.pg_SQLiteTempDir) ); + // char[] + + SetPreferences(p_MyPrefsHandle, lID, SCP_MiscAutoRemove, ¤tPrefs.DragNDrop.ddg_bAutoRemoveIcons, sizeof(currentPrefs.DragNDrop.ddg_bAutoRemoveIcons) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_MiscClickTransp, ¤tPrefs.Icons.ig_bClickAreaMask, sizeof(currentPrefs.Icons.ig_bClickAreaMask) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_MiscHardEmulation, ¤tPrefs.Miscellaneous.mg_bHardEmulation, sizeof(currentPrefs.Miscellaneous.mg_bHardEmulation) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_MiscUseExAll, ¤tPrefs.Miscellaneous.mg_bUseExAll, sizeof(currentPrefs.Miscellaneous.mg_bUseExAll) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_CreateSoftLinks, ¤tPrefs.Miscellaneous.mg_bCreateSoftLinks, sizeof(currentPrefs.Miscellaneous.mg_bCreateSoftLinks) ); + // BYTE + + SetLongPreferences(p_MyPrefsHandle, lID, SCP_CopyBuffLen, ¤tPrefs.Miscellaneous.mg_CopyBuffSize, sizeof(currentPrefs.Miscellaneous.mg_CopyBuffSize) ); + SetLongPreferences(p_MyPrefsHandle, lID, SCP_MaxUndoSteps, ¤tPrefs.Miscellaneous.mg_MaxUndoSteps, sizeof(currentPrefs.Miscellaneous.mg_MaxUndoSteps) ); + + if (WorkbenchBase->lib_Version < 45) + SetLongPreferences(p_MyPrefsHandle, lID, SCP_DefaultStackSize, ¤tPrefs.Miscellaneous.mg_DefaultStackSize, sizeof(currentPrefs.Miscellaneous.mg_DefaultStackSize) ); + + SetPreferences(p_MyPrefsHandle, lID, SCP_MiscWindowType, ¤tPrefs.Windows.wg_bType, sizeof(currentPrefs.Windows.wg_bType) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_MiscDoWaitDelay, ¤tPrefs.Startup.sg_bWBStartupDelay, sizeof(currentPrefs.Startup.sg_bWBStartupDelay) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_MiscDiskiconsRefresh, ¤tPrefs.Desktop.dg_bDiskRefresh, sizeof(currentPrefs.Desktop.dg_bDiskRefresh) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_MiscMenuCurrentDir, ¤tPrefs.Miscellaneous.mg_bMenuCurrentDir, sizeof(currentPrefs.Miscellaneous.mg_bMenuCurrentDir) ); + // BYTE + + SetLongPreferences(p_MyPrefsHandle, lID, SCP_DragDropCopyQualifier, ¤tPrefs.DragNDrop.ddg_pCopyQualifier, sizeof(currentPrefs.DragNDrop.ddg_pCopyQualifier) ); + SetLongPreferences(p_MyPrefsHandle, lID, SCP_PopupApplySelectedQualifier, ¤tPrefs.Miscellaneous.mg_PopupApplySelectedQualifier, sizeof(currentPrefs.Miscellaneous.mg_PopupApplySelectedQualifier) ); + SetPreferences(p_MyPrefsHandle, lID, SCP_PopupApplySelectedAlways, ¤tPrefs.Miscellaneous.mp_PopupApplySelectedAlways, sizeof(currentPrefs.Miscellaneous.mp_PopupApplySelectedAlways) ); + // BYTE + + SetLongPreferences(p_MyPrefsHandle, lID, SCP_DragDropMakeLinkQualifier, ¤tPrefs.DragNDrop.ddg_pMakeLinkQualifier, sizeof(currentPrefs.DragNDrop.ddg_pMakeLinkQualifier) ); + SetLongPreferences(p_MyPrefsHandle, lID, SCP_DragDropMoveQualifier, ¤tPrefs.DragNDrop.ddg_pMoveQualifier, sizeof(currentPrefs.DragNDrop.ddg_pMoveQualifier) ); + SetLongPreferences(p_MyPrefsHandle, lID, SCP_SingleWindowLassoQualifier, ¤tPrefs.Desktop.dg_SingleWindowLassoQualifier, sizeof(currentPrefs.Desktop.dg_SingleWindowLassoQualifier) ); + + SetPreferences(p_MyPrefsHandle, lID, SCP_NewIconsTransparent, ¤tPrefs.Icons.ig_bNewIconTransparent, sizeof(currentPrefs.Icons.ig_bNewIconTransparent) ); + // BYTE + + WriteNewIconsPrecision(p_MyPrefsHandle, lID); + + //SetPreferences(p_MyPrefsHandle, lID, SCP_TextModeDateFormat, , sizeof() ); + WriteTextModeColumns(p_MyPrefsHandle, lID); + + WritePluginList(p_MyPrefsHandle, lID); + + WriteControlBarGadgetList(app, p_MyPrefsHandle, lID, + NLIST_CONTROLBARGADGETS_NORMAL_ACTIVE, SCP_ControlBarGadgetsStd, SCP_ControlBarGadgetStringsStd); + WriteControlBarGadgetList(app, p_MyPrefsHandle, lID, + NLIST_CONTROLBARGADGETS_BROWSER_ACTIVE, SCP_ControlBarGadgetsBr, SCP_ControlBarGadgetStringsBr); + + SetPreferences(p_MyPrefsHandle, lID, SCP_MMB_Move, ¤tPrefs.Windows.wg_bMMBMove, sizeof(currentPrefs.Windows.wg_bMMBMove) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_WindowPopupTitleOnly, ¤tPrefs.Windows.wg_bPopTitleOnly, sizeof(currentPrefs.Windows.wg_bPopTitleOnly) ); + // BYTE + + ibox.Left = SCA_WORD2BE(currentPrefs.Windows.wg_DefaultSize.Left); + ibox.Top = SCA_WORD2BE(currentPrefs.Windows.wg_DefaultSize.Top); + ibox.Width = SCA_WORD2BE(currentPrefs.Windows.wg_DefaultSize.Width); + ibox.Height = SCA_WORD2BE(currentPrefs.Windows.wg_DefaultSize.Height); + SetPreferences(p_MyPrefsHandle, lID, SCP_DefaultWindowSize, &ibox, sizeof(ibox) ); + + ibox.Left = SCA_WORD2BE(currentPrefs.Windows.wg_CleanupSpaces.Left); + ibox.Top = SCA_WORD2BE(currentPrefs.Windows.wg_CleanupSpaces.Top); + ibox.Width = SCA_WORD2BE(currentPrefs.Windows.wg_CleanupSpaces.Width); + ibox.Height = SCA_WORD2BE(currentPrefs.Windows.wg_CleanupSpaces.Height); + SetPreferences(p_MyPrefsHandle, lID, SCP_IconCleanupSpace, &ibox, sizeof(ibox) ); + + SetPreferences(p_MyPrefsHandle, lID, SCP_FullBench, ¤tPrefs.Desktop.dg_bHideTitleBar, sizeof(currentPrefs.Desktop.dg_bHideTitleBar) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_LoadDefIconsFirst, ¤tPrefs.Icons.ig_bLoadDefIconsFirst, sizeof(currentPrefs.Icons.ig_bLoadDefIconsFirst) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_DefaultIconsSaveable, ¤tPrefs.Icons.ig_bIconsSaveable, sizeof(currentPrefs.Icons.ig_bIconsSaveable) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_EasyMultiSelect, ¤tPrefs.DragNDrop.ddg_bEasyMultiSelect, sizeof(currentPrefs.DragNDrop.ddg_bEasyMultiSelect) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_EasyMultiDrag, ¤tPrefs.DragNDrop.ddg_bEasyMultiDrag, sizeof(currentPrefs.DragNDrop.ddg_bEasyMultiDrag) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_DropStart, ¤tPrefs.Desktop.dg_bDropStart, sizeof(currentPrefs.Desktop.dg_bDropStart) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_AutoLeaveOut, ¤tPrefs.Desktop.dg_AutoLeaveOut, sizeof(currentPrefs.Desktop.dg_AutoLeaveOut)); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_HideHiddenFiles, ¤tPrefs.Windows.wg_bHideHiddenFiles, sizeof(currentPrefs.Windows.wg_bHideHiddenFiles) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_HideProtectHiddenFiles, ¤tPrefs.Windows.wg_bHideProtectHiddenFiles, sizeof(currentPrefs.Windows.wg_bHideProtectHiddenFiles) ); // JMC + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_ShowAllDefault, ¤tPrefs.Windows.wg_ShowAllByDefault, sizeof(currentPrefs.Windows.wg_ShowAllByDefault) ); + // UBYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_ViewByDefault, ¤tPrefs.Windows.wg_ViewByDefault, sizeof(currentPrefs.Windows.wg_ViewByDefault) ); + // UBYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_CheckOverlappingIcons, ¤tPrefs.Windows.wg_CheckOverlappingIcons, sizeof(currentPrefs.Windows.wg_CheckOverlappingIcons) ); + // UBYTE + + SetWordPreferences(p_MyPrefsHandle, lID, SCP_ActiveWindowTransparency, ¤tPrefs.Windows.wg_TransparencyActiveWindow, sizeof(currentPrefs.Windows.wg_TransparencyActiveWindow) ); + SetWordPreferences(p_MyPrefsHandle, lID, SCP_InactiveWindowTransparency, ¤tPrefs.Windows.wg_wTransparencyInactiveWindow, sizeof(currentPrefs.Windows.wg_wTransparencyInactiveWindow) ); + + SetPreferences(p_MyPrefsHandle, lID, SCP_TextModeFont, ¤tPrefs.TextWindows.fd_TextWindowFontDescr, 1 + strlen(currentPrefs.TextWindows.fd_TextWindowFontDescr) ); + // char[] + + SetPreferences(p_MyPrefsHandle, lID, SCP_UnderSoftLinkNames, ¤tPrefs.TextWindows.fd_bShowSoftLinks, sizeof(currentPrefs.TextWindows.fd_bShowSoftLinks) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_PopScreenTitle, ¤tPrefs.Desktop.dg_bPopTitleBar, sizeof(currentPrefs.Desktop.dg_bPopTitleBar) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_SplashWindowEnable, ¤tPrefs.Startup.sg_bShowSplash, sizeof(currentPrefs.Startup.sg_bShowSplash) ); + // BYTE + + SetWordPreferences(p_MyPrefsHandle, lID, SCP_SplashWindowHoldTime, ¤tPrefs.Startup.sg_bSplashCloseDelay, sizeof(currentPrefs.Startup.sg_bSplashCloseDelay) ); + SetPreferences(p_MyPrefsHandle, lID, SCP_StatusBarEnable, ¤tPrefs.Windows.wg_bStatusBar, sizeof(currentPrefs.Windows.wg_bStatusBar) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_CleanupOnResize, ¤tPrefs.Windows.wg_bCleanupOnResize, sizeof(currentPrefs.Windows.wg_bCleanupOnResize) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_ToolTipsEnable, ¤tPrefs.Icons.ig_bShowTooltips, sizeof(currentPrefs.Icons.ig_bShowTooltips) ); + // BYTE + + SetLongPreferences(p_MyPrefsHandle, lID, SCP_ToolTipPopupDelay, ¤tPrefs.Icons.ig_bTooltipDelay, sizeof(currentPrefs.Icons.ig_bTooltipDelay) ); + SetWordPreferences(p_MyPrefsHandle, lID, SCP_ToolTipTransparency, ¤tPrefs.Icons.ig_TransparencyTooltips, sizeof(currentPrefs.Icons.ig_TransparencyTooltips) ); + + SetPreferences(p_MyPrefsHandle, lID, SCP_ShowDragDropObjCount, ¤tPrefs.DragNDrop.ddg_bShowObjectCount, sizeof(currentPrefs.DragNDrop.ddg_bShowObjectCount) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_DragDropIconsSingle, ¤tPrefs.DragNDrop.ddg_bGroupDrag, sizeof(currentPrefs.DragNDrop.ddg_bGroupDrag) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_DropMarkMode, ¤tPrefs.DragNDrop.ddg_bDropMarkMode, sizeof(currentPrefs.DragNDrop.ddg_bDropMarkMode) ); + // BYTE + + SetWordPreferences(p_MyPrefsHandle, lID, SCP_TransparencyIconDrag, ¤tPrefs.DragNDrop.ddg_TransparencyIconDrag, sizeof(currentPrefs.DragNDrop.ddg_TransparencyIconDrag) ); + SetWordPreferences(p_MyPrefsHandle, lID, SCP_TransparencyIconShadow, ¤tPrefs.DragNDrop.ddg_TransparencyIconShadow, sizeof(currentPrefs.DragNDrop.ddg_TransparencyIconShadow) ); + SetWordPreferences(p_MyPrefsHandle, lID, SCP_TransparencyDefaultIcon, ¤tPrefs.Icons.ig_TransparencyDefaultIcons, sizeof(currentPrefs.Icons.ig_TransparencyDefaultIcons) ); + SetPreferences(p_MyPrefsHandle, lID, SCP_EnableDropMenu, ¤tPrefs.DragNDrop.ddg_bEnableDropMenu, sizeof(currentPrefs.DragNDrop.ddg_bEnableDropMenu) ); + // UBYTE + + SetWordPreferences(p_MyPrefsHandle, lID, SCP_PopupWindowsDelay, ¤tPrefs.DragNDrop.ddg_PopupWindowDelaySeconds, sizeof(currentPrefs.DragNDrop.ddg_PopupWindowDelaySeconds) ); + + SetPreferences(p_MyPrefsHandle, lID, SCP_TextWindowsStriped, ¤tPrefs.TextWindows.fd_bShowStripes, sizeof(currentPrefs.TextWindows.fd_bShowStripes) ); + // BYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_SelectTextIconName, ¤tPrefs.TextWindows.fd_SelectTextIconName, sizeof(currentPrefs.TextWindows.fd_SelectTextIconName) ); + // UBYTE + + SetPreferences(p_MyPrefsHandle, lID, SCP_SelectMarkerBaseColor, ¤tPrefs.TextWindows.fd_SelectMarkerBaseColor, sizeof(currentPrefs.TextWindows.fd_SelectMarkerBaseColor) ); + // struct ARGB + + SetPreferences(p_MyPrefsHandle, lID, SCP_SelectMarkerTransparency, ¤tPrefs.TextWindows.fd_SelectMarkerTransparency, sizeof(currentPrefs.TextWindows.fd_SelectMarkerTransparency) ); + // UBYTE + + SetLongPreferences(p_MyPrefsHandle, lID, SCP_DrawerSortMode, (ULONG *) ¤tPrefs.TextWindows.fd_DrawerSortMode, sizeof(currentPrefs.TextWindows.fd_DrawerSortMode) ); + // enum + + WritePrefsHandle(p_MyPrefsHandle, PrefsFileName); + + FreePrefsHandle(p_MyPrefsHandle); + } + + if (fCreateIcons) + SaveIcon(PrefsFileName); + + return RETURN_OK; +} + +LONG ReadScalosPrefs(CONST_STRPTR PrefsFileName) +{ + LONG lID; + APTR p_MyPrefsHandle; + + CleanupPluginList(); + + currentPrefs = defaultPrefs; + + p_MyPrefsHandle = AllocPrefsHandle("ScalosPrefs"); + lID = MAKE_ID('M', 'A', 'I', 'N'); + + if(p_MyPrefsHandle) + { + ReadPrefsHandle(p_MyPrefsHandle, PrefsFileName); + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_IconOffsets, ¤tPrefs.Icons.ig_IconOffsets, sizeof(currentPrefs.Icons.ig_IconOffsets) )) + { + currentPrefs.Icons.ig_IconOffsets.Left = SCA_BE2WORD(currentPrefs.Icons.ig_IconOffsets.Left); + currentPrefs.Icons.ig_IconOffsets.Top = SCA_BE2WORD(currentPrefs.Icons.ig_IconOffsets.Left); + currentPrefs.Icons.ig_IconOffsets.Width = SCA_BE2WORD(currentPrefs.Icons.ig_IconOffsets.Left); + currentPrefs.Icons.ig_IconOffsets.Height = SCA_BE2WORD(currentPrefs.Icons.ig_IconOffsets.Left); + } + if (GetPreferences(p_MyPrefsHandle, lID, SCP_IconNormFrame, ¤tPrefs.Icons.ig_wNormFrame, sizeof(currentPrefs.Icons.ig_wNormFrame) )) + currentPrefs.Icons.ig_wNormFrame = SCA_BE2WORD(currentPrefs.Icons.ig_wNormFrame); + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_IconSelFrame, ¤tPrefs.Icons.ig_wSelFrame, sizeof(currentPrefs.Icons.ig_wSelFrame) )) + currentPrefs.Icons.ig_wSelFrame = SCA_BE2WORD(currentPrefs.Icons.ig_wSelFrame); + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_IconNormThumbnailFrame, ¤tPrefs.Icons.ig_wNormThumbnailFrame, sizeof(currentPrefs.Icons.ig_wNormThumbnailFrame) )) + currentPrefs.Icons.ig_wNormThumbnailFrame = SCA_BE2WORD(currentPrefs.Icons.ig_wNormThumbnailFrame); + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_IconSelThumbnailFrame, ¤tPrefs.Icons.ig_wSelThumbnailFrame, sizeof(currentPrefs.Icons.ig_wSelThumbnailFrame) )) + currentPrefs.Icons.ig_wSelThumbnailFrame = SCA_BE2WORD(currentPrefs.Icons.ig_wSelThumbnailFrame); + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_IconTextMode, ¤tPrefs.TextWindows.fd_wLabelStyle, sizeof(currentPrefs.TextWindows.fd_wLabelStyle) )) + currentPrefs.TextWindows.fd_wLabelStyle = SCA_BE2WORD(currentPrefs.TextWindows.fd_wLabelStyle); + + d1(KPrintF(__FUNC__ "/%ld: Icon offset left=%ld top=%ld right=%ld bottom=%ld\n", \ + __FUNC__, __LINE__, currentPrefs.Icons.ig_IconOffsets.Left, currentPrefs.Icons.ig_IconOffsets.Top, \ + currentPrefs.Icons.ig_IconOffsets.Width, currentPrefs.Icons.ig_IconOffsets.Height)); + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_IconSecLine, ¤tPrefs.Icons.ig_wMultipleLines, sizeof(currentPrefs.Icons.ig_wMultipleLines) )) + currentPrefs.Icons.ig_wMultipleLines = SCA_BE2WORD(currentPrefs.Icons.ig_wMultipleLines); + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_IconSizeConstraints, ¤tPrefs.Icons.ig_SizeConstraints, sizeof(currentPrefs.Icons.ig_SizeConstraints) )) + { + currentPrefs.Icons.ig_SizeConstraints.MinX = SCA_BE2WORD(currentPrefs.Icons.ig_SizeConstraints.MinX); + currentPrefs.Icons.ig_SizeConstraints.MinY = SCA_BE2WORD(currentPrefs.Icons.ig_SizeConstraints.MinY); + currentPrefs.Icons.ig_SizeConstraints.MaxX = SCA_BE2WORD(currentPrefs.Icons.ig_SizeConstraints.MaxX); + currentPrefs.Icons.ig_SizeConstraints.MaxY = SCA_BE2WORD(currentPrefs.Icons.ig_SizeConstraints.MaxY); + } + if (GetPreferences(p_MyPrefsHandle, lID, SCP_IconNominalSize, ¤tPrefs.Icons.ig_NominalSize, sizeof(currentPrefs.Icons.ig_NominalSize) )) + currentPrefs.Icons.ig_NominalSize = SCA_BE2WORD(currentPrefs.Icons.ig_NominalSize); + + GetPreferences(p_MyPrefsHandle, lID, SCP_IconHiliteUnderMouse, ¤tPrefs.Icons.ig_HighlightUnderMouse, sizeof(currentPrefs.Icons.ig_HighlightUnderMouse) ); + // BYTE + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_IconTextSkip, ¤tPrefs.TextWindows.fd_wTextSkip, sizeof(currentPrefs.TextWindows.fd_wTextSkip) )) + currentPrefs.TextWindows.fd_wTextSkip = SCA_BE2WORD(currentPrefs.TextWindows.fd_wTextSkip); + + GetPreferences(p_MyPrefsHandle, lID, SCP_ShowThumbnails, ¤tPrefs.Icons.ig_ShowThumbnails, sizeof(currentPrefs.Icons.ig_ShowThumbnails) ); + // UBYTE + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_ThumbnailOffsets, ¤tPrefs.Icons.ig_ThumbnailOffsets, sizeof(currentPrefs.Icons.ig_ThumbnailOffsets) )) + { + currentPrefs.Icons.ig_ThumbnailOffsets.Left = SCA_BE2WORD(currentPrefs.Icons.ig_ThumbnailOffsets.Left); + currentPrefs.Icons.ig_ThumbnailOffsets.Top = SCA_BE2WORD(currentPrefs.Icons.ig_ThumbnailOffsets.Top); + currentPrefs.Icons.ig_ThumbnailOffsets.Width = SCA_BE2WORD(currentPrefs.Icons.ig_ThumbnailOffsets.Width); + currentPrefs.Icons.ig_ThumbnailOffsets.Height = SCA_BE2WORD(currentPrefs.Icons.ig_ThumbnailOffsets.Height); + } + GetPreferences(p_MyPrefsHandle, lID, SCP_ThumbnailsFillBackground, ¤tPrefs.Icons.ig_ThumbnailsBackfill, sizeof(currentPrefs.Icons.ig_ThumbnailsBackfill) ); + // UBYTE + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_TransparencyThumbnailsBack, ¤tPrefs.Icons.ig_ThumbnailBackgroundTransparency, sizeof(currentPrefs.Icons.ig_ThumbnailBackgroundTransparency) )) + currentPrefs.Icons.ig_ThumbnailBackgroundTransparency = SCA_BE2WORD(currentPrefs.Icons.ig_ThumbnailBackgroundTransparency); + + GetPreferences(p_MyPrefsHandle, lID, SCP_SelectedTextRectangle, ¤tPrefs.Icons.ig_SelectedTextRectangle, sizeof(currentPrefs.Icons.ig_SelectedTextRectangle) ); + // UBYTE + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_SelTextRectBorderX, ¤tPrefs.Icons.ig_SelTextRectBorderX, sizeof(currentPrefs.Icons.ig_SelTextRectBorderX) )) + currentPrefs.Icons.ig_SelTextRectBorderX = SCA_BE2WORD(currentPrefs.Icons.ig_SelTextRectBorderX); + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_SelTextRectBorderY, ¤tPrefs.Icons.ig_SelTextRectBorderY, sizeof(currentPrefs.Icons.ig_SelTextRectBorderY) )) + currentPrefs.Icons.ig_SelTextRectBorderY = SCA_BE2WORD(currentPrefs.Icons.ig_SelTextRectBorderY); + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_SelTextRectRadius, ¤tPrefs.Icons.ig_SelTextRectRadius, sizeof(currentPrefs.Icons.ig_SelTextRectRadius) )) + currentPrefs.Icons.ig_SelTextRectRadius = SCA_BE2WORD(currentPrefs.Icons.ig_SelTextRectRadius); + + GetPreferences(p_MyPrefsHandle, lID, SCP_ShowThumbnailsAsDefault, ¤tPrefs.Icons.ig_ShowThumbnailsAsDefault, sizeof(currentPrefs.Icons.ig_ShowThumbnailsAsDefault) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_ThumbnailsSquare, ¤tPrefs.Icons.ig_bSquareThumbnails, sizeof(currentPrefs.Icons.ig_bSquareThumbnails) ); + // BYTE + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_ThumbnailSize, ¤tPrefs.Icons.ig_ThumbnailSize, sizeof(currentPrefs.Icons.ig_ThumbnailSize) )) + currentPrefs.Icons.ig_ThumbnailSize = SCA_BE2WORD(currentPrefs.Icons.ig_ThumbnailSize); + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_ThumbnailMaxAge, ¤tPrefs.Icons.ig_ThumbnailMaxAge, sizeof(currentPrefs.Icons.ig_ThumbnailMaxAge) )) + currentPrefs.Icons.ig_ThumbnailMaxAge = SCA_BE2WORD(currentPrefs.Icons.ig_ThumbnailMaxAge); + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_ThumbnailMinSizeLimit, ¤tPrefs.Icons.ig_ThumbnailMinSizeLimit, sizeof(currentPrefs.Icons.ig_ThumbnailMinSizeLimit) )) + currentPrefs.Icons.ig_ThumbnailMinSizeLimit = SCA_BE2WORD(currentPrefs.Icons.ig_ThumbnailMinSizeLimit); + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_ThumbnailQuality, ¤tPrefs.Icons.ig_ThumbnailQuality, sizeof(currentPrefs.Icons.ig_ThumbnailQuality) )) + currentPrefs.Icons.ig_ThumbnailQuality = SCA_BE2LONG(currentPrefs.Icons.ig_ThumbnailQuality); + + GetPreferences(p_MyPrefsHandle, lID, SCP_DeviceWinIconLayout, currentPrefs.Icons.ig_DeviceWindowLayoutModes, sizeof(currentPrefs.Icons.ig_DeviceWindowLayoutModes)); + // UBYTE * + + GetPreferences(p_MyPrefsHandle, lID, SCP_IconWinIconLayout, currentPrefs.Icons.ig_IconWindowLayoutModes, sizeof(currentPrefs.Icons.ig_IconWindowLayoutModes)); + // UBYTE * + + GetPreferences(p_MyPrefsHandle, lID, SCP_BobsType, ¤tPrefs.DragNDrop.ddg_bBobStyle, sizeof(currentPrefs.DragNDrop.ddg_bBobStyle) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_BobsMethod, ¤tPrefs.DragNDrop.ddg_bBobMethod, sizeof(currentPrefs.DragNDrop.ddg_bBobMethod) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_BobsTranspMode, ¤tPrefs.DragNDrop.ddg_bBobLook, sizeof(currentPrefs.DragNDrop.ddg_bBobLook) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_BobsTranspType, ¤tPrefs.DragNDrop.ddg_bTranspType, sizeof(currentPrefs.DragNDrop.ddg_bTranspType) ); + // BYTE + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_BobsTransp, ¤tPrefs.DragNDrop.ddg_lTriggers, sizeof(currentPrefs.DragNDrop.ddg_lTriggers) )) + currentPrefs.DragNDrop.ddg_lTriggers = SCA_BE2LONG(currentPrefs.DragNDrop.ddg_lTriggers); + + GetPreferences(p_MyPrefsHandle, lID, SCP_ScreenTitle, currentPrefs.Desktop.dg_pScreen, sizeof(currentPrefs.Desktop.dg_pScreen) ); + // char[] + + GetPreferences(p_MyPrefsHandle, lID, SCP_RootWinTitle, currentPrefs.Windows.wg_pRootWin, sizeof(currentPrefs.Windows.wg_pRootWin) ); + // char[] + + GetPreferences(p_MyPrefsHandle, lID, SCP_WindowTitle, currentPrefs.Windows.wg_pWindow, sizeof(currentPrefs.Windows.wg_pWindow) ); + // char[] + + GetPreferences(p_MyPrefsHandle, lID, SCP_TTfAntialiasing, ¤tPrefs.TrueTypeFonts.ttg_Antialias, sizeof(currentPrefs.TrueTypeFonts.ttg_Antialias) ); + // BYTE + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_TTfGamma, ¤tPrefs.TrueTypeFonts.ttg_Gamma, sizeof(currentPrefs.TrueTypeFonts.ttg_Gamma) )) + currentPrefs.TrueTypeFonts.ttg_Gamma = SCA_BE2WORD(currentPrefs.TrueTypeFonts.ttg_Gamma); + + GetPreferences(p_MyPrefsHandle, lID, SCP_TTScreenFontDesc, currentPrefs.TrueTypeFonts.ttg_ScreenTTFontDesc, sizeof(currentPrefs.TrueTypeFonts.ttg_ScreenTTFontDesc) ); + // char[] + + GetPreferences(p_MyPrefsHandle, lID, SCP_TTIconFontDesc, currentPrefs.TrueTypeFonts.ttg_IconTTFontDesc, sizeof(currentPrefs.TrueTypeFonts.ttg_IconTTFontDesc) ); + // char[] + + GetPreferences(p_MyPrefsHandle, lID, SCP_TTTextWindowFontDesc, currentPrefs.TrueTypeFonts.ttg_TextWindowTTFontDesc, sizeof(currentPrefs.TrueTypeFonts.ttg_TextWindowTTFontDesc) ); + // char[] + + GetPreferences(p_MyPrefsHandle, lID, SCP_UseTTScreenFont, ¤tPrefs.TrueTypeFonts.ttg_UseScreenTTFont, sizeof(currentPrefs.TrueTypeFonts.ttg_UseScreenTTFont) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_UseTTIconFont, ¤tPrefs.TrueTypeFonts.ttg_UseIconTTFont, sizeof(currentPrefs.TrueTypeFonts.ttg_UseIconTTFont) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_UseTTTextWindowFont, ¤tPrefs.TrueTypeFonts.ttg_UseTextWindowTTFont, sizeof(currentPrefs.TrueTypeFonts.ttg_UseTextWindowTTFont) ); + // BYTE + + //GetPreferences(p_MyPrefsHandle, lID, SCP_Seperator, , sizeof() ); + + GetPreferences(p_MyPrefsHandle, lID, SCP_TitleRefresh, ¤tPrefs.Desktop.dg_bTitleRefresh, sizeof(currentPrefs.Desktop.dg_bTitleRefresh) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_RefreshOnMemoryChange, ¤tPrefs.Desktop.dg_bMemoryRefresh, sizeof(currentPrefs.Desktop.dg_bMemoryRefresh) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_WinTitleRefresh, ¤tPrefs.Desktop.dg_bWinTitleRefresh, sizeof(currentPrefs.Desktop.dg_bWinTitleRefresh) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_WinRefreshOnMemoryChange, ¤tPrefs.Desktop.dg_bWinMemoryRefresh, sizeof(currentPrefs.Desktop.dg_bWinMemoryRefresh) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_ConsoleName, currentPrefs.Desktop.dg_ConsoleName, sizeof(currentPrefs.Desktop.dg_ConsoleName) ); + // char[] + + GetPreferences(p_MyPrefsHandle, lID, SCP_PathsDefIcons, ¤tPrefs.Paths.pg_pDefaultIcons, sizeof(currentPrefs.Paths.pg_pDefaultIcons) ); + // char[] + + GetPreferences(p_MyPrefsHandle, lID, SCP_PathsDiskCopy, ¤tPrefs.Paths.pg_pDiskCopy, sizeof(currentPrefs.Paths.pg_pDiskCopy) ); + // char[] + + GetPreferences(p_MyPrefsHandle, lID, SCP_PathsTheme, ¤tPrefs.Paths.pg_pThemes, sizeof(currentPrefs.Paths.pg_pThemes) ); + // char[] + + GetPreferences(p_MyPrefsHandle, lID, SCP_PathsImagecache, ¤tPrefs.Paths.pg_pImageCache, sizeof(currentPrefs.Paths.pg_pImageCache) ); + // char[] + + GetPreferences(p_MyPrefsHandle, lID, SCP_PathsThumbnailDb, ¤tPrefs.Paths.pg_pThumbnailDb, sizeof(currentPrefs.Paths.pg_pThumbnailDb) ); + // char[] + + GetPreferences(p_MyPrefsHandle, lID, SCP_PathsWBStartup, ¤tPrefs.Startup.sg_pWBStartup, sizeof(currentPrefs.Startup.sg_pWBStartup) ); + // char[] + + GetPreferences(p_MyPrefsHandle, lID, SCP_PathsHome, ¤tPrefs.Paths.pg_pHome, sizeof(currentPrefs.Paths.pg_pHome) ); + // char[] + + GetPreferences(p_MyPrefsHandle, lID, SCP_PathsSQLiteTempDir, ¤tPrefs.Paths.pg_SQLiteTempDir, sizeof(currentPrefs.Paths.pg_SQLiteTempDir) ); + // char[] + + GetPreferences(p_MyPrefsHandle, lID, SCP_MiscAutoRemove, ¤tPrefs.DragNDrop.ddg_bAutoRemoveIcons, sizeof(currentPrefs.DragNDrop.ddg_bAutoRemoveIcons) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_MiscClickTransp, ¤tPrefs.Icons.ig_bClickAreaMask, sizeof(currentPrefs.Icons.ig_bClickAreaMask) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_MiscHardEmulation, ¤tPrefs.Miscellaneous.mg_bHardEmulation, sizeof(currentPrefs.Miscellaneous.mg_bHardEmulation) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_MiscUseExAll, ¤tPrefs.Miscellaneous.mg_bUseExAll, sizeof(currentPrefs.Miscellaneous.mg_bUseExAll) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_CreateSoftLinks, ¤tPrefs.Miscellaneous.mg_bCreateSoftLinks, sizeof(currentPrefs.Miscellaneous.mg_bCreateSoftLinks) ); + // BYTE + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_CopyBuffLen, ¤tPrefs.Miscellaneous.mg_CopyBuffSize, sizeof(currentPrefs.Miscellaneous.mg_CopyBuffSize) )) + currentPrefs.Miscellaneous.mg_CopyBuffSize = SCA_BE2LONG(currentPrefs.Miscellaneous.mg_CopyBuffSize); + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_MaxUndoSteps, ¤tPrefs.Miscellaneous.mg_MaxUndoSteps, sizeof(currentPrefs.Miscellaneous.mg_MaxUndoSteps) )) + currentPrefs.Miscellaneous.mg_MaxUndoSteps = SCA_BE2LONG(currentPrefs.Miscellaneous.mg_MaxUndoSteps); + + if (WorkbenchBase->lib_Version < 45) + if (GetPreferences(p_MyPrefsHandle, lID, SCP_DefaultStackSize, ¤tPrefs.Miscellaneous.mg_DefaultStackSize, sizeof(currentPrefs.Miscellaneous.mg_DefaultStackSize) )) + currentPrefs.Miscellaneous.mg_DefaultStackSize = SCA_BE2LONG(currentPrefs.Miscellaneous.mg_DefaultStackSize); + else + { + // starting with WB 45, stack size is changed via "Workbench" prefs. + //WorkbenchControlA() + WorkbenchControl(NULL, + WBCTRLA_GetDefaultStackSize, (ULONG) ¤tPrefs.Miscellaneous.mg_DefaultStackSize, + TAG_END); + } + GetPreferences(p_MyPrefsHandle, lID, SCP_MiscWindowType, ¤tPrefs.Windows.wg_bType, sizeof(currentPrefs.Windows.wg_bType) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_MiscDoWaitDelay, ¤tPrefs.Startup.sg_bWBStartupDelay, sizeof(currentPrefs.Startup.sg_bWBStartupDelay) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_MiscDiskiconsRefresh, ¤tPrefs.Desktop.dg_bDiskRefresh, sizeof(currentPrefs.Desktop.dg_bDiskRefresh) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_MiscMenuCurrentDir, ¤tPrefs.Miscellaneous.mg_bMenuCurrentDir, sizeof(currentPrefs.Miscellaneous.mg_bMenuCurrentDir) ); + // BYTE + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_DragDropCopyQualifier, ¤tPrefs.DragNDrop.ddg_pCopyQualifier, sizeof(currentPrefs.DragNDrop.ddg_pCopyQualifier) )) + currentPrefs.DragNDrop.ddg_pCopyQualifier = SCA_BE2LONG(currentPrefs.DragNDrop.ddg_pCopyQualifier); + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_PopupApplySelectedQualifier, ¤tPrefs.Miscellaneous.mg_PopupApplySelectedQualifier, sizeof(currentPrefs.Miscellaneous.mg_PopupApplySelectedQualifier) )) + currentPrefs.Miscellaneous.mg_PopupApplySelectedQualifier = SCA_BE2LONG(currentPrefs.Miscellaneous.mg_PopupApplySelectedQualifier); + + GetPreferences(p_MyPrefsHandle, lID, SCP_PopupApplySelectedAlways, ¤tPrefs.Miscellaneous.mp_PopupApplySelectedAlways, sizeof(currentPrefs.Miscellaneous.mp_PopupApplySelectedAlways) ); + // BYTE + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_DragDropMakeLinkQualifier, ¤tPrefs.DragNDrop.ddg_pMakeLinkQualifier, sizeof(currentPrefs.DragNDrop.ddg_pMakeLinkQualifier) )) + currentPrefs.DragNDrop.ddg_pMakeLinkQualifier = SCA_BE2LONG(currentPrefs.DragNDrop.ddg_pMakeLinkQualifier); + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_DragDropMoveQualifier, ¤tPrefs.DragNDrop.ddg_pMoveQualifier, sizeof(currentPrefs.DragNDrop.ddg_pMoveQualifier) )) + currentPrefs.DragNDrop.ddg_pMoveQualifier = SCA_BE2LONG(currentPrefs.DragNDrop.ddg_pMoveQualifier); + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_SingleWindowLassoQualifier, ¤tPrefs.Desktop.dg_SingleWindowLassoQualifier, sizeof(currentPrefs.Desktop.dg_SingleWindowLassoQualifier) )) + currentPrefs.Desktop.dg_SingleWindowLassoQualifier = SCA_BE2LONG(currentPrefs.Desktop.dg_SingleWindowLassoQualifier); + + GetPreferences(p_MyPrefsHandle, lID, SCP_NewIconsTransparent, ¤tPrefs.Icons.ig_bNewIconTransparent, sizeof(currentPrefs.Icons.ig_bNewIconTransparent) ); + // BYTE + + ReadNewIconsPrecision(p_MyPrefsHandle, lID); + + //GetPreferences(p_MyPrefsHandle, lID, SCP_TextModeDateFormat, , sizeof() ); + ReadTextModeColumns(p_MyPrefsHandle, lID); + + ReadPluginList(p_MyPrefsHandle, lID); + ReadControlBarGadgetList(p_MyPrefsHandle, lID, + &ControlBarGadgetListNormal, SCP_ControlBarGadgetsStd, SCP_ControlBarGadgetStringsStd); + ReadControlBarGadgetList(p_MyPrefsHandle, lID, + &ControlBarGadgetListBrowser, SCP_ControlBarGadgetsBr, SCP_ControlBarGadgetStringsBr); + + GetPreferences(p_MyPrefsHandle, lID, SCP_MMB_Move, ¤tPrefs.Windows.wg_bMMBMove, sizeof(currentPrefs.Windows.wg_bMMBMove) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_WindowPopupTitleOnly, ¤tPrefs.Windows.wg_bPopTitleOnly, sizeof(currentPrefs.Windows.wg_bPopTitleOnly) ); + // BYTE + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_DefaultWindowSize, ¤tPrefs.Windows.wg_DefaultSize, sizeof(currentPrefs.Windows.wg_DefaultSize) )) + { + currentPrefs.Windows.wg_DefaultSize.Left = SCA_BE2WORD(currentPrefs.Windows.wg_DefaultSize.Left); + currentPrefs.Windows.wg_DefaultSize.Top = SCA_BE2WORD(currentPrefs.Windows.wg_DefaultSize.Top); + currentPrefs.Windows.wg_DefaultSize.Width = SCA_BE2WORD(currentPrefs.Windows.wg_DefaultSize.Width); + currentPrefs.Windows.wg_DefaultSize.Height = SCA_BE2WORD(currentPrefs.Windows.wg_DefaultSize.Height); + } + if (GetPreferences(p_MyPrefsHandle, lID, SCP_IconCleanupSpace, ¤tPrefs.Windows.wg_CleanupSpaces, sizeof(currentPrefs.Windows.wg_CleanupSpaces) )) + { + currentPrefs.Windows.wg_CleanupSpaces.Left = SCA_BE2WORD(currentPrefs.Windows.wg_CleanupSpaces.Left); + currentPrefs.Windows.wg_CleanupSpaces.Top = SCA_BE2WORD(currentPrefs.Windows.wg_CleanupSpaces.Top); + currentPrefs.Windows.wg_CleanupSpaces.Width = SCA_BE2WORD(currentPrefs.Windows.wg_CleanupSpaces.Width); + currentPrefs.Windows.wg_CleanupSpaces.Height = SCA_BE2WORD(currentPrefs.Windows.wg_CleanupSpaces.Height); + } + GetPreferences(p_MyPrefsHandle, lID, SCP_FullBench, ¤tPrefs.Desktop.dg_bHideTitleBar, sizeof(currentPrefs.Desktop.dg_bHideTitleBar) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_LoadDefIconsFirst, ¤tPrefs.Icons.ig_bLoadDefIconsFirst, sizeof(currentPrefs.Icons.ig_bLoadDefIconsFirst) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_DefaultIconsSaveable, ¤tPrefs.Icons.ig_bIconsSaveable, sizeof(currentPrefs.Icons.ig_bIconsSaveable) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_EasyMultiSelect, ¤tPrefs.DragNDrop.ddg_bEasyMultiSelect, sizeof(currentPrefs.DragNDrop.ddg_bEasyMultiSelect) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_EasyMultiDrag, ¤tPrefs.DragNDrop.ddg_bEasyMultiDrag, sizeof(currentPrefs.DragNDrop.ddg_bEasyMultiDrag) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_DropStart, ¤tPrefs.Desktop.dg_bDropStart, sizeof(currentPrefs.Desktop.dg_bDropStart) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_AutoLeaveOut, ¤tPrefs.Desktop.dg_AutoLeaveOut, sizeof(currentPrefs.Desktop.dg_AutoLeaveOut)); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_HideHiddenFiles, ¤tPrefs.Windows.wg_bHideHiddenFiles, sizeof(currentPrefs.Windows.wg_bHideHiddenFiles) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_HideProtectHiddenFiles, ¤tPrefs.Windows.wg_bHideProtectHiddenFiles, sizeof(currentPrefs.Windows.wg_bHideProtectHiddenFiles) ); // JMC + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_ShowAllDefault, ¤tPrefs.Windows.wg_ShowAllByDefault, sizeof(currentPrefs.Windows.wg_ShowAllByDefault) ); + // UBYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_ViewByDefault, ¤tPrefs.Windows.wg_ViewByDefault, sizeof(currentPrefs.Windows.wg_ViewByDefault) ); + // UBYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_CheckOverlappingIcons, ¤tPrefs.Windows.wg_CheckOverlappingIcons, sizeof(currentPrefs.Windows.wg_CheckOverlappingIcons) ); + // UBYTE + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_ActiveWindowTransparency, ¤tPrefs.Windows.wg_TransparencyActiveWindow, sizeof(currentPrefs.Windows.wg_TransparencyActiveWindow) )) + currentPrefs.Windows.wg_TransparencyActiveWindow = SCA_BE2WORD(currentPrefs.Windows.wg_TransparencyActiveWindow); + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_InactiveWindowTransparency, ¤tPrefs.Windows.wg_wTransparencyInactiveWindow, sizeof(currentPrefs.Windows.wg_wTransparencyInactiveWindow) )) + currentPrefs.Windows.wg_wTransparencyInactiveWindow = SCA_BE2WORD(currentPrefs.Windows.wg_wTransparencyInactiveWindow); + + GetPreferences(p_MyPrefsHandle, lID, SCP_TextModeFont, ¤tPrefs.TextWindows.fd_TextWindowFontDescr, sizeof(currentPrefs.TextWindows.fd_TextWindowFontDescr) ); + // char[] + + GetPreferences(p_MyPrefsHandle, lID, SCP_UnderSoftLinkNames, ¤tPrefs.TextWindows.fd_bShowSoftLinks, sizeof(currentPrefs.TextWindows.fd_bShowSoftLinks) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_PopScreenTitle, ¤tPrefs.Desktop.dg_bPopTitleBar, sizeof(currentPrefs.Desktop.dg_bPopTitleBar) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_SplashWindowEnable, ¤tPrefs.Startup.sg_bShowSplash, sizeof(currentPrefs.Startup.sg_bShowSplash) ); + // BYTE + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_SplashWindowHoldTime, ¤tPrefs.Startup.sg_bSplashCloseDelay, sizeof(currentPrefs.Startup.sg_bSplashCloseDelay) )) + currentPrefs.Startup.sg_bSplashCloseDelay = SCA_BE2WORD(currentPrefs.Startup.sg_bSplashCloseDelay); + + GetPreferences(p_MyPrefsHandle, lID, SCP_StatusBarEnable, ¤tPrefs.Windows.wg_bStatusBar, sizeof(currentPrefs.Windows.wg_bStatusBar) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_CleanupOnResize, ¤tPrefs.Windows.wg_bCleanupOnResize, sizeof(currentPrefs.Windows.wg_bCleanupOnResize) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_ToolTipsEnable, ¤tPrefs.Icons.ig_bShowTooltips, sizeof(currentPrefs.Icons.ig_bShowTooltips) ); + // BYTE + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_ToolTipPopupDelay, ¤tPrefs.Icons.ig_bTooltipDelay, sizeof(currentPrefs.Icons.ig_bTooltipDelay) )) + currentPrefs.Icons.ig_bTooltipDelay = SCA_BE2LONG(currentPrefs.Icons.ig_bTooltipDelay); + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_ToolTipTransparency, ¤tPrefs.Icons.ig_TransparencyTooltips, sizeof(currentPrefs.Icons.ig_TransparencyTooltips) )) + currentPrefs.Icons.ig_TransparencyTooltips = SCA_BE2WORD(currentPrefs.Icons.ig_TransparencyTooltips); + + GetPreferences(p_MyPrefsHandle, lID, SCP_ShowDragDropObjCount, ¤tPrefs.DragNDrop.ddg_bShowObjectCount, sizeof(currentPrefs.DragNDrop.ddg_bShowObjectCount) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_DragDropIconsSingle, ¤tPrefs.DragNDrop.ddg_bGroupDrag, sizeof(currentPrefs.DragNDrop.ddg_bGroupDrag) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_DropMarkMode, ¤tPrefs.DragNDrop.ddg_bDropMarkMode, sizeof(currentPrefs.DragNDrop.ddg_bDropMarkMode) ); + // BYTE + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_TransparencyIconDrag, ¤tPrefs.DragNDrop.ddg_TransparencyIconDrag, sizeof(currentPrefs.DragNDrop.ddg_TransparencyIconDrag) )) + currentPrefs.DragNDrop.ddg_TransparencyIconDrag = SCA_BE2WORD(currentPrefs.DragNDrop.ddg_TransparencyIconDrag); + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_TransparencyIconShadow, ¤tPrefs.DragNDrop.ddg_TransparencyIconShadow, sizeof(currentPrefs.DragNDrop.ddg_TransparencyIconShadow) )) + currentPrefs.DragNDrop.ddg_TransparencyIconShadow = SCA_BE2WORD(currentPrefs.DragNDrop.ddg_TransparencyIconShadow); + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_TransparencyDefaultIcon, ¤tPrefs.Icons.ig_TransparencyDefaultIcons, sizeof(currentPrefs.Icons.ig_TransparencyDefaultIcons) )) + currentPrefs.Icons.ig_TransparencyDefaultIcons = SCA_BE2WORD(currentPrefs.Icons.ig_TransparencyDefaultIcons); + + GetPreferences(p_MyPrefsHandle, lID, SCP_EnableDropMenu, ¤tPrefs.DragNDrop.ddg_bEnableDropMenu, sizeof(currentPrefs.DragNDrop.ddg_bEnableDropMenu) ); + // UBYTE + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_PopupWindowsDelay, ¤tPrefs.DragNDrop.ddg_PopupWindowDelaySeconds, sizeof(currentPrefs.DragNDrop.ddg_PopupWindowDelaySeconds) )) + currentPrefs.DragNDrop.ddg_PopupWindowDelaySeconds = SCA_BE2WORD(currentPrefs.DragNDrop.ddg_PopupWindowDelaySeconds); + + GetPreferences(p_MyPrefsHandle, lID, SCP_TextWindowsStriped, ¤tPrefs.TextWindows.fd_bShowStripes, sizeof(currentPrefs.TextWindows.fd_bShowStripes) ); + // BYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_SelectTextIconName, ¤tPrefs.TextWindows.fd_SelectTextIconName, sizeof(currentPrefs.TextWindows.fd_SelectTextIconName) ); + // UBYTE + + GetPreferences(p_MyPrefsHandle, lID, SCP_SelectMarkerBaseColor, ¤tPrefs.TextWindows.fd_SelectMarkerBaseColor, sizeof(currentPrefs.TextWindows.fd_SelectMarkerBaseColor) ); + // struct ARGB + + GetPreferences(p_MyPrefsHandle, lID, SCP_SelectMarkerTransparency, ¤tPrefs.TextWindows.fd_SelectMarkerTransparency, sizeof(currentPrefs.TextWindows.fd_SelectMarkerTransparency) ); + // UBYTE + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_DrawerSortMode, ¤tPrefs.TextWindows.fd_DrawerSortMode, sizeof(currentPrefs.TextWindows.fd_DrawerSortMode) )) + currentPrefs.TextWindows.fd_DrawerSortMode = SCA_BE2LONG(currentPrefs.TextWindows.fd_DrawerSortMode); + + FreePrefsHandle(p_MyPrefsHandle); + } + + return RETURN_OK; +} + + +IPTR mui_getv(APTR obj, ULONG attr) +{ + IPTR v; + GetAttr(attr, obj, &v); + return (v); +} + + +static void ReadPluginList(APTR p_MyPrefsHandle, LONG lID) +{ + WORD PluginArray[304]; + LONG Entry; + + Entry = 0; + + while (GetEntry(p_MyPrefsHandle, lID, SCP_PlugInList, PluginArray, sizeof(PluginArray), Entry) > 0) + { + STRPTR lp; + struct PluginDef *pd = (struct PluginDef *) calloc(1, sizeof(struct PluginDef)); + struct SCP_PluginEntry *pey = (struct SCP_PluginEntry *) PluginArray; + + d1(KPrintF(__FILE__ "/%s/%ld: MinVersion=%ld\n", __FUNC__, __LINE__, pey->pey_NeededVersion)); + + if (pd) + { + struct ScaOOPPluginBase *ScalosPluginBase; +#ifdef __amigaos4__ + struct ScalosPluginIFace *IScalosPlugin; +#endif + + pd->plug_priority = SCA_BE2WORD(pey->pey_Priority); + pd->plug_instsize = SCA_BE2WORD(pey->pey_InstSize); + pd->plug_NeededVersion = SCA_BE2WORD(pey->pey_NeededVersion); + + d1(KPrintF(__FILE__ "/%s/%ld: priority=%ld instsize=%ld\n", __FUNC__, __LINE__, pd->plug_priority, pd->plug_instsize)); + + lp = pey->pey_Path; + + stccpy(pd->plug_filename, lp, sizeof(pd->plug_filename)); + d1(KPrintF(__FILE__ "/%s/%ld: filename=<%s>\n", __FUNC__, __LINE__, pd->plug_filename)); + + lp += 1 + strlen(lp); + stccpy(pd->plug_classname, lp, sizeof(pd->plug_classname)); + d1(KPrintF(__FILE__ "/%s/%ld: classname=<%s>\n", __FUNC__, __LINE__, pd->plug_classname)); + + lp += 1 + strlen(lp); + stccpy(pd->plug_superclassname, lp, sizeof(pd->plug_superclassname)); + + d1(KPrintF(__FILE__ "/%s/%ld: superclassname=<%s>\n", __FUNC__, __LINE__, pd->plug_superclassname)); + + if (NULL == ScalosBase || pd->plug_NeededVersion <= ScalosBase->scb_LibNode.lib_Version) + { + ScalosPluginBase = (struct ScaOOPPluginBase *) OpenLibrary(pd->plug_filename, 0); + + d1(KPrintF(__FILE__ "/%s/%ld: ScalosPluginBase=%08lx\n", __FUNC__, __LINE__, ScalosPluginBase)); + if (ScalosPluginBase) + { + const struct ScaClassInfo *ci; + +#ifdef __amigaos4__ + IScalosPlugin = (struct ScalosPluginIFace *)GetInterface( + (struct Library *)ScalosPluginBase, "main", 1, NULL + ); +#endif + + do { + d1(kprintf(__FILE__ "/%s/%ld: signature=%08lx\n", __FUNC__, __LINE__, ScalosPluginBase->soob_Signature)); + + if (MAKE_ID('P','L','U','G') != ScalosPluginBase->soob_Signature) + break; + + pd->plug_libVersion = ScalosPluginBase->soob_Library.lib_Version; + pd->plug_libRevision = ScalosPluginBase->soob_Library.lib_Revision; + + sprintf(pd->plug_VersionString, "V%ld.%ld", (long) pd->plug_libVersion, (long) pd->plug_libRevision); + + d1(KPrintF(__FILE__ "/%s/%ld: VersionString=<%s>\n", __FUNC__, __LINE__, pd->plug_VersionString)); + + ci = SCAGetClassInfo(); + d1(kprintf(__FILE__ "/%s/%ld: ClassInfo=%08lx\n", __FUNC__, __LINE__, ci)); + if (NULL == ci) + break; + + d1(kprintf(__FILE__ "/%s/%ld: ClassInfo=%08lx NeededVersion=%ld\n", __FUNC__, __LINE__, ci, ci->ci_neededversion)); + + if (ScalosBase && ci->ci_neededversion > ScalosBase->scb_LibNode.lib_Version) + break; + + pd->plug_priority = ci->ci_priority; + pd->plug_instsize = ci->ci_instsize; + + stccpy(pd->plug_classname, ci->ci_classname, sizeof(pd->plug_classname)); + stccpy(pd->plug_superclassname, ci->ci_superclassname, sizeof(pd->plug_superclassname)); + stccpy(pd->plug_RealName, ci->ci_name, sizeof(pd->plug_RealName)); + stccpy(pd->plug_Description, ci->ci_description, sizeof(pd->plug_Description)); + stccpy(pd->plug_Creator, ci->ci_makername, sizeof(pd->plug_Creator)); + + d1(kprintf(__FILE__ "/%s/%ld: InstSize=%ld\n", __FUNC__, __LINE__, pd->plug_instsize)); + d1(kprintf(__FILE__ "/%s/%ld: Priority=%ld\n", __FUNC__, __LINE__, pd->plug_priority)); + d1(kprintf(__FILE__ "/%s/%ld: ClassName=<%s>\n", __FUNC__, __LINE__, pd->plug_classname)); + d1(kprintf(__FILE__ "/%s/%ld: SuperClassName=<%s>\n", __FUNC__, __LINE__, pd->plug_superclassname)); + d1(kprintf(__FILE__ "/%s/%ld: RealName=<%s>\n", __FUNC__, __LINE__, pd->plug_RealName)); + d1(kprintf(__FILE__ "/%s/%ld: Description=<%s>\n", __FUNC__, __LINE__, pd->plug_Description)); + d1(kprintf(__FILE__ "/%s/%ld: Creator=<%s>\n", __FUNC__, __LINE__, pd->plug_Creator)); + + pd->plug_SuccessfullyLoaded = TRUE; + } while (0); + +#ifdef __amigaos4__ + if (IScalosPlugin) + DropInterface((struct Interface *)IScalosPlugin); +#endif + CloseLibrary((struct Library *) ScalosPluginBase); + } + else if (NULL == ScalosBase) + { + // assume the plugin refused to open due to Scalos not running + pd->plug_SuccessfullyLoaded = TRUE; + } + } + + AddTail(&PluginList, (struct Node *) &pd->plug_Node); + } + Entry++; + } +} + + +static void WritePluginList(APTR p_MyPrefsHandle, LONG lID) +{ + WORD PluginArray[304]; + LONG Entry; + struct PluginDef *pd; + + Entry = 0; + + for (pd = (struct PluginDef *) PluginList.lh_Head; + pd != (struct PluginDef *) &PluginList.lh_Tail; + pd = (struct PluginDef *) pd->plug_Node.mln_Succ) + { + size_t Length = sizeof(struct SCP_PluginEntry); + STRPTR lp; + struct SCP_PluginEntry *pey = (struct SCP_PluginEntry *) PluginArray; + + memset(PluginArray, 0, sizeof(PluginArray)); + + pey->pey_Priority = SCA_WORD2BE(pd->plug_priority); + pey->pey_InstSize = SCA_WORD2BE(pd->plug_instsize); + pey->pey_NeededVersion = SCA_WORD2BE(pd->plug_NeededVersion); + pey->pey_unused = 0; + + d1(kprintf(__FILE__ "/%s/%ld: priority=%ld instsize=%ld\n", __FUNC__, __LINE__, pl->plug_priority, pl->plug_instsize)); + + lp = pey->pey_Path; + + strcpy(lp, pd->plug_filename); + d1(kprintf(__FILE__ "/%s/%ld: filename=<%s>\n", __FUNC__, __LINE__, pd->plug_filename)); + + Length += strlen(lp); + lp += 1 + strlen(lp); + + strcpy(lp, pd->plug_classname); + d1(kprintf(__FILE__ "/%s/%ld: classname=<%s>\n", __FUNC__, __LINE__, pd->plug_classname)); + + Length += 1 + strlen(lp); + lp += 1 + strlen(lp); + + strcpy(lp, pd->plug_superclassname); + + Length += 1 + strlen(lp); + + SetEntry(p_MyPrefsHandle, lID, SCP_PlugInList, PluginArray, Length, Entry++); + } +} + + +static void CleanupPluginList(void) +{ + struct PluginDef *pd; + + while ((pd = (struct PluginDef *) RemHead(&PluginList))) + { + free(pd); + } +} + + +struct PluginDef *FindPlugin(struct SCAModule *app, BPTR fLock) +{ + ULONG entries; + ULONG n; + struct PluginDef *pd; + + entries = getv(app->Obj[PLUGIN_LIST], MUIA_NList_Entries); + + for (n=0; nObj[PLUGIN_LIST], MUIM_NList_GetEntry, n, &pd); + + eLock = Lock(pd->plug_filename, ACCESS_READ); + if (eLock) + { + LONG same = SameLock(eLock, fLock); + UnLock(eLock); + + if (LOCK_SAME == same) + return pd; + } + } + + return NULL; +} + + +void RemovePlugin(struct SCAModule *app, const struct PluginDef *pdRemove) +{ + ULONG entries; + ULONG n; + struct PluginDef *pd; + + entries = getv(app->Obj[PLUGIN_LIST], MUIA_NList_Entries); + + // Remove from NList + for (n=0; nObj[PLUGIN_LIST], MUIM_NList_GetEntry, n, &pd); + + if (0 == strcmp(pdRemove->plug_RealName, pd->plug_RealName)) + { + DoMethod(app->Obj[PLUGIN_LIST], MUIM_NList_Remove, n); + break; + } + } + + // Remove from PluginList + for (pd = (struct PluginDef *) PluginList.lh_Head; + pd != (struct PluginDef *) &PluginList.lh_Tail; + pd = (struct PluginDef *) pd->plug_Node.mln_Succ) + { + if (0 == strcmp(pdRemove->plug_RealName, pd->plug_RealName)) + { + Remove((struct Node *) pd); + free(pd); + break; + } + } +} + + +BOOL AddPlugin(struct SCAModule *app, CONST_STRPTR FileName) +{ + BOOL Success = FALSE; + struct PluginDef *pd; + BPTR libLock = (BPTR)NULL; + struct ScaOOPPluginBase *ScalosPluginBase = NULL; +#ifdef __amigaos4__ + struct ScalosPluginIFace *IScalosPlugin = NULL; +#endif + + do { + const struct ScaClassInfo *ci; + + pd = (struct PluginDef *) calloc(1, sizeof(struct PluginDef)); + if (NULL == pd) + break; + + libLock = Lock(FileName, ACCESS_READ); + if ((BPTR)NULL == libLock) + break; + + NameFromLock(libLock, pd->plug_filename, sizeof(pd->plug_filename)); + + ScalosPluginBase = (struct ScaOOPPluginBase *) OpenLibrary(pd->plug_filename, 0); + + d1(KPrintF(__FILE__ "/%s/%ld: ScalosPluginBase=%08lx\n", __FUNC__, __LINE__, ScalosPluginBase)); + if (NULL == ScalosPluginBase) + break; +#ifdef __amigaos4__ + IScalosPlugin = (struct ScalosPluginIFace *)GetInterface( + (struct Library *)ScalosPluginBase, "main", 1, NULL + ); +#endif + if (MAKE_ID('P','L','U','G') != ScalosPluginBase->soob_Signature) + break; + + pd->plug_libVersion = ScalosPluginBase->soob_Library.lib_Version; + pd->plug_libRevision = ScalosPluginBase->soob_Library.lib_Revision; + + sprintf(pd->plug_VersionString, "V%ld.%ld", (long) pd->plug_libVersion, (long) pd->plug_libRevision); + + d1(KPrintF(__FILE__ "/%s/%ld: VersionString=<%s>\n", __FUNC__, __LINE__, pd->plug_VersionString)); + + ci = SCAGetClassInfo(); + if (NULL == ci) + break; + + d1(KPrintF(__FILE__ "/%s/%ld: ClassInfo=%08lx NeededVersion=%ld\n", __FUNC__, __LINE__, ci, ci->ci_neededversion)); + + if (ScalosBase && ci->ci_neededversion > ScalosBase->scb_LibNode.lib_Version) + break; + + pd->plug_priority = ci->ci_priority; + pd->plug_instsize = ci->ci_instsize; + pd->plug_NeededVersion = ci->ci_neededversion; + + stccpy(pd->plug_classname, ci->ci_classname, sizeof(pd->plug_classname)); + stccpy(pd->plug_superclassname, ci->ci_superclassname, sizeof(pd->plug_superclassname)); + stccpy(pd->plug_RealName, ci->ci_name, sizeof(pd->plug_RealName)); + stccpy(pd->plug_Description, ci->ci_description, sizeof(pd->plug_Description)); + stccpy(pd->plug_Creator, ci->ci_makername, sizeof(pd->plug_Creator)); + + d1(KPrintF(__FILE__ "/%s/%ld: InstSize=%ld\n", __FUNC__, __LINE__, pd->plug_instsize)); + d1(KPrintF(__FILE__ "/%s/%ld: Priority=%ld\n", __FUNC__, __LINE__, pd->plug_priority)); + d1(KPrintF(__FILE__ "/%s/%ld: ClassName=<%s>\n", __FUNC__, __LINE__, pd->plug_classname)); + d1(KPrintF(__FILE__ "/%s/%ld: SuperClassName=<%s>\n", __FUNC__, __LINE__, pd->plug_superclassname)); + d1(KPrintF(__FILE__ "/%s/%ld: RealName=<%s>\n", __FUNC__, __LINE__, pd->plug_RealName)); + d1(KPrintF(__FILE__ "/%s/%ld: Description=<%s>\n", __FUNC__, __LINE__, pd->plug_Description)); + d1(KPrintF(__FILE__ "/%s/%ld: Creator=<%s>\n", __FUNC__, __LINE__, pd->plug_Creator)); + + // make sure there are no duplicate plugin entries + RemovePlugin(app, pd); + + AddTail(&PluginList, (struct Node *) &pd->plug_Node); + + DoMethod(app->Obj[PLUGIN_LIST], + MUIM_NList_InsertSingle, + pd, + MUIV_NList_Insert_Sorted); + set(app->Obj[PLUGIN_LIST], MUIA_NList_Active, MUIV_NList_Active_Bottom); + + Success = TRUE; + + // do not free pd now! + pd = NULL; + } while (0); + +#ifdef __amigaos4__ + if (IScalosPlugin) + DropInterface((struct Interface *)IScalosPlugin); +#endif + if (ScalosPluginBase) + CloseLibrary((struct Library *) ScalosPluginBase); + if (libLock) + UnLock(libLock); + if (pd) + free(pd); + + return Success; +} + + +static void ReadTextModeColumns(APTR p_MyPrefsHandle, LONG lID) +{ + struct PrefsStruct *ps; + + ps = FindPreferences(p_MyPrefsHandle, lID, SCP_TextMode_ListColumns); + if (ps) + { + BYTE *pu = (BYTE *) PS_DATA(ps); + short n = 0; + + while (~0 != *pu && n < Sizeof(currentPrefs.TextWindows.fd_lDisplayFields)) + { + BYTE col = *pu++; + + d1(kprintf(__FILE__ "/%s/%ld: Column=%ld\n", __FUNC__, __LINE__, col)); + + if (!(col & 0x80)) + { + currentPrefs.TextWindows.fd_lDisplayFields[n++] = col; + d1(kprintf(__FILE__ "/%s/%ld: ColumnsArray[%ld]=%ld\n", __FUNC__, __LINE__, n-1, ColumnsArray[n-1])); + } + } + + currentPrefs.TextWindows.fd_lDisplayFields[n] = ~0; + } +} + + +static void WriteTextModeColumns(APTR p_MyPrefsHandle, LONG lID) +{ + SetPreferences(p_MyPrefsHandle, lID, SCP_TextMode_ListColumns, + currentPrefs.TextWindows.fd_lDisplayFields, sizeof(currentPrefs.TextWindows.fd_lDisplayFields)); +} + + +static void RemoveFileDisplayEntry(Object *list, ULONG Index) +{ + ULONG nEntries = 0; + ULONG n; + + get(list, MUIA_NList_Entries, &nEntries); + + for (n = 0; n < nEntries; n++) + { + struct FileDisplayListEntry *entry = NULL; + + DoMethod(list, MUIM_NList_GetEntry, n, &entry); + + if (entry) + { + if (entry->fdle_Index == Index) + { + DoMethod(list, MUIM_NList_Remove, n); + break; + } + } + } +} + + +void ResetToDefaults(struct SCAModule *app) +{ + CleanupPluginList(); + currentPrefs = defaultPrefs; + CreateDefaultControlBarGadgets(); + UpdateGuiFromPrefs(app); +} + + +static void ReadNewIconsPrecision(APTR p_MyPrefsHandle, LONG lID) +{ + LONG x = 0; + + if (GetPreferences(p_MyPrefsHandle, lID, SCP_NewIconsPrecision, &x, sizeof(x) )) + { + x = SCA_BE2LONG(x); + } + + switch (x) + { + case PRECISION_EXACT: + currentPrefs.Icons.ig_bNewIconPrecision = 1; + break; + case PRECISION_IMAGE: + currentPrefs.Icons.ig_bNewIconPrecision = 2; + break; + case PRECISION_ICON: + currentPrefs.Icons.ig_bNewIconPrecision = 3; + break; + case PRECISION_GUI: + default: + currentPrefs.Icons.ig_bNewIconPrecision = 4; + break; + } +} + + +static void WriteNewIconsPrecision(APTR p_MyPrefsHandle, LONG lID) +{ + LONG x; + + switch (currentPrefs.Icons.ig_bNewIconPrecision) + { + case 1: + x = PRECISION_EXACT; + break; + case 2: + x = PRECISION_IMAGE; + break; + case 3: + x = PRECISION_ICON; + break; + case 4: + default: + x = PRECISION_GUI; + break; + } + + x = SCA_LONG2BE(x); + + SetPreferences(p_MyPrefsHandle, lID, SCP_NewIconsPrecision, &x, sizeof(x) ); +} + + +static void UpdateFileDisplayPrefsFromGUI(struct SCAModule *app) +{ + ULONG nEntries = 0; + ULONG n; + + get(app->Obj[NLIST_USE_FILEDISPLAY], MUIA_NList_Entries, &nEntries); + + for (n = 0; n < nEntries; n++) + { + struct FileDisplayListEntry *entry = NULL; + + DoMethod(app->Obj[NLIST_USE_FILEDISPLAY], MUIM_NList_GetEntry, n, &entry); + + if (entry) + { + currentPrefs.TextWindows.fd_lDisplayFields[n] = entry->fdle_Index; + } + } + + currentPrefs.TextWindows.fd_lDisplayFields[n] = ~0; +} + + +static size_t TranslateQualifierToString(ULONG Qualifier, STRPTR line, size_t MaxLength) +{ + ULONG n; + + for (n=0; n 2 + strlen(QualifierTable[n].ien_name)) + { + strcat(line, " "); + strcat(line, QualifierTable[n].ien_name); + MaxLength -= strlen(QualifierTable[n].ien_name) + 1; + } + } + } + + return strlen(line); +} + + +static ULONG TranslateStringToQualifier(CONST_STRPTR line) +{ + ULONG Qualifier = 0L; + + while (*line) + { + size_t Length = 0; + ULONG n; + char QualString[20]; + STRPTR dlp = QualString; + + while (*line && !isspace(*line) && Length < sizeof(QualString) - 1) + *dlp++ = *line++; + *dlp = '\0'; + + // skip separating " " + while (*line && isspace(*line)) + line++; + + for (n=0; nRastPort.BitMap, BMA_DEPTH); + + // custom Bobs are only useable for Screen depths > 8 bit ! + if (ScreenDepth <= 8) + currentPrefs.DragNDrop.ddg_bBobMethod = DRAGMETHOD_GELS; + + UnlockPubScreen(NULL, WbScreen); + } + } +} + + +void ReadIconFontPrefs(struct SCAModule *app) +{ + struct IFFHandle *iff; + struct FontPrefs *FontChunk = NULL; + BOOL IffOpened = FALSE; + + do { + iff = AllocIFF(); + if (NULL == iff) + break; + + InitIFFasDOS(iff); + + iff->iff_Stream = (ULONG) Open("ENV:sys/font.prefs", MODE_OLDFILE); + + d1(kprintf(__FILE__ "/%s/%ld: iff_Stream=%08lx\n", __FUNC__, __LINE__, iff->iff_Stream)); + if (0 == iff->iff_Stream) + break; + + if (RETURN_OK != OpenIFF(iff, IFFF_READ)) + break; + + d1(kprintf(__FILE__ "/%s/%ld: OpenIFF() OK\n", __FUNC__, __LINE__)); + IffOpened = TRUE; + + if (RETURN_OK != StopChunk(iff, ID_PREF, ID_FONT)) + break; + + d1(kprintf(__FILE__ "/%s/%ld: StopChunk() OK\n", __FUNC__, __LINE__)); + + while (1) + { + struct ContextNode *cn; + + if (RETURN_OK != ParseIFF(iff, IFFPARSE_SCAN)) + break; + + d1(kprintf(__FILE__ "/%s/%ld: ParseIFF() OK\n", __FUNC__, __LINE__)); + + cn = CurrentChunk(iff); + + d1(kprintf(__FILE__ "/%s/%ld: CurrentChunk=%08lx\n", __FUNC__, __LINE__, cn)); + if (NULL == cn) + continue; + + d1(kprintf(__FILE__ "/%s/%ld: CurrentChunk=%08lx Size=%lu\n", __FUNC__, __LINE__, cn, cn->cn_Size)); + + FontChunk = malloc(cn->cn_Size); + d1(kprintf(__FILE__ "/%s/%ld: FontChunk=%08lx\n", __FUNC__, __LINE__, FontChunk)); + if (NULL == FontChunk) + break; + + if (ReadChunkBytes(iff, FontChunk, cn->cn_Size) < 0) + break; + + d1(kprintf(__FILE__ "/%s/%ld: ReadChunkBytes OK\n", __FUNC__, __LINE__)); + + FontChunk->fp_Type = SCA_BE2WORD(FontChunk->fp_Type); + FontChunk->fp_TextAttr.ta_YSize = SCA_BE2WORD(FontChunk->fp_TextAttr.ta_YSize); + + switch (FontChunk->fp_Type) + { + case FP_WBFONT: + sprintf(currentPrefs.Icons.ig_IconFontDesc, "%s/%d", + FontChunk->fp_Name, FontChunk->fp_TextAttr.ta_YSize); + set(app->Obj[MCC_ICONFONT_SAMPLE], + MUIA_FontSample_StdFontDesc, (ULONG) currentPrefs.Icons.ig_IconFontDesc); + set(app->Obj[POP_ICONFONT], + MUIA_String_Contents, (ULONG) currentPrefs.Icons.ig_IconFontDesc); + memset(&IconFontPrefs, 0, sizeof(IconFontPrefs)); + IconFontPrefs = *FontChunk; + break; + case FP_SCREENFONT: + memset(&ScreenFontPrefs, 0, sizeof(ScreenFontPrefs)); + ScreenFontPrefs = *FontChunk; + break; + case FP_SYSFONT: + memset(&SysFontPrefs, 0, sizeof(SysFontPrefs)); + SysFontPrefs = *FontChunk; + break; + default: + break; + } + + d1(KPrintF(__FILE__ "/%s/%ld: FontAttr.ta_Name=<%s> SIze=%ld\n", \ + __FUNC__, __LINE__, FontChunk->fp_Name, FontChunk->fp_TextAttr.ta_YSize)); + + free(FontChunk); + FontChunk = NULL; + } + } while (0); + + if (FontChunk) + free(FontChunk); + if (iff) + { + if (IffOpened) + CloseIFF(iff); + if (iff->iff_Stream) + Close((BPTR)iff->iff_Stream); + FreeIFF(iff); + } +} + + +void WriteFontPrefs(struct SCAModule *app, CONST_STRPTR FontPrefsName) +{ + struct IFFHandle *iff; + BOOL IffOpened = FALSE; + struct FontPrefs FontChunk; + + do { + size_t Length; + LONG Result; + static const struct PrefHeader prefHeader = { 0, 0, 0L }; + + iff = AllocIFF(); + if (NULL == iff) + break; + + InitIFFasDOS(iff); + + iff->iff_Stream = (IPTR) Open(FontPrefsName, MODE_NEWFILE); + + d1(kprintf(__FILE__ "/%s/%ld: iff_Stream=%08lx\n", __FUNC__, __LINE__, iff->iff_Stream)); + if (0 == iff->iff_Stream) + break; + + if (RETURN_OK != OpenIFF(iff, IFFF_WRITE)) + break; + + d1(kprintf(__FILE__ "/%s/%ld: OpenIFF() OK\n", __FUNC__, __LINE__)); + IffOpened = TRUE; + + Result = PushChunk(iff, ID_PREF, ID_FORM, IFFSIZE_UNKNOWN); + if (RETURN_OK != Result) + break; + + Result = PushChunk(iff, 0, ID_PRHD, IFFSIZE_UNKNOWN); + if (RETURN_OK != Result) + break; + + if (WriteChunkBytes(iff, (APTR) &prefHeader, sizeof(prefHeader)) < 0) + { + Result = IoErr(); + break; + } + + Result = PopChunk(iff); // PRHD + if (RETURN_OK != Result) + break; + + + Result = WriteIconFontPrefs(app, iff); + if (RETURN_OK != Result) + break; + + // Write Sys Font Prefs + Result = PushChunk(iff, 0, ID_FONT, IFFSIZE_UNKNOWN); + if (RETURN_OK != Result) + break; + + Length = GetFontPrefsSize(&SysFontPrefs); + FontChunk = SysFontPrefs; + FontChunk.fp_Type = SCA_WORD2BE(FontChunk.fp_Type); + FontChunk.fp_TextAttr.ta_YSize = SCA_WORD2BE(FontChunk.fp_TextAttr.ta_YSize); + if (Length != WriteChunkBytes(iff, (APTR) &FontChunk, Length)) + { + Result = IoErr(); + break; + } + + Result = PopChunk(iff); + if (RETURN_OK != Result) + break; + + // Write Screen font prefs + Result = PushChunk(iff, 0, ID_FONT, IFFSIZE_UNKNOWN); + if (RETURN_OK != Result) + break; + + Length = GetFontPrefsSize(&ScreenFontPrefs); + FontChunk = ScreenFontPrefs; + FontChunk.fp_Type = SCA_WORD2BE(FontChunk.fp_Type); + FontChunk.fp_TextAttr.ta_YSize = SCA_WORD2BE(FontChunk.fp_TextAttr.ta_YSize); + if (Length != WriteChunkBytes(iff, (APTR) &FontChunk, Length)) + { + Result = IoErr(); + break; + } + + Result = PopChunk(iff); + if (RETURN_OK != Result) + break; + + Result = PopChunk(iff); + if (RETURN_OK != Result) + break; + } while (0); + + if (iff) + { + if (IffOpened) + CloseIFF(iff); + if (iff->iff_Stream) + Close((BPTR)iff->iff_Stream); + FreeIFF(iff); + } +} + + + +static LONG WriteIconFontPrefs(struct SCAModule *app, struct IFFHandle *iff) +{ + LONG Result; + + do { + struct FontPrefs FontChunk; + CONST_STRPTR Separator; + size_t Length; + + Separator = strchr(currentPrefs.Icons.ig_IconFontDesc, '/'); + if (NULL == Separator) + { + Result = ERROR_BAD_TEMPLATE; + break; + } + + Length = Separator - (STRPTR) currentPrefs.Icons.ig_IconFontDesc; + + FontChunk = IconFontPrefs; + memset(&FontChunk.fp_Name, 0, sizeof(FontChunk.fp_Name)); +// FontChunk.fp_TextAttr.ta_Name = NULL; + stccpy(FontChunk.fp_Name, currentPrefs.Icons.ig_IconFontDesc, 1 + Length); + + // append ".font" if not already present + if (0 != strcmp(FontChunk.fp_Name + Length - 5, ".font")) + strcat(FontChunk.fp_Name, ".font"); + + sscanf(Separator, "/%hd", &FontChunk.fp_TextAttr.ta_YSize); + + Result = PushChunk(iff, 0, ID_FONT, IFFSIZE_UNKNOWN); + if (RETURN_OK != Result) + break; + + Length = GetFontPrefsSize(&FontChunk); + FontChunk.fp_Type = SCA_WORD2BE(FontChunk.fp_Type); + FontChunk.fp_TextAttr.ta_YSize = SCA_WORD2BE(FontChunk.fp_TextAttr.ta_YSize); + if (Length != WriteChunkBytes(iff, (APTR) &FontChunk, Length)) + { + Result = IoErr(); + break; + } + + Result = PopChunk(iff); + if (RETURN_OK != Result) + break; + } while (0); + + return Result; +} + + +static size_t GetFontPrefsSize(const struct FontPrefs *FontChunk) +{ + size_t Length; + + Length = sizeof(struct FontPrefs); +// Length = offsetof(struct FontPrefs, fp_Name) +// + strlen(FontChunk->fp_Name) +// + 1; + + return Length; +} + + +static void ReadControlBarGadgetList(APTR p_MyPrefsHandle, LONG lID, struct List *CbGadgetsList, + ULONG prefsIDGadgets, ULONG prefsIDStrings) +{ + struct SCP_GadgetStringEntry *gse = NULL; + + d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__)); + + do { + struct SCP_GadgetEntry sgy; + size_t size; + + size = GetEntry(p_MyPrefsHandle, lID, prefsIDGadgets, &sgy, sizeof(sgy), 0); + if (size > 0) + { + struct SCP_GadgetStringEntry gseTemp; + LONG Entry; + + CleanupControlBarGadgetsList(CbGadgetsList); + + memset(&gseTemp, 0, sizeof(gseTemp)); + Entry = 0; + + // first determine required size of prefsIDStrings + if (GetPreferences(p_MyPrefsHandle, lID, prefsIDStrings, &gseTemp, sizeof(gseTemp) )) + { + gseTemp.gse_Length = SCA_BE2LONG(gseTemp.gse_Length); + } + size = sizeof(struct SCP_GadgetStringEntry) + gseTemp.gse_Length; + d1(KPrintF("%s/%s/%ld: gse_Length=%lu size=%lu\n", __FILE__, __FUNC__, __LINE__, gseTemp.gse_Length, size)); + + gse = malloc(size); + d1(KPrintF("%s/%s/%ld: gse=%08lx\n", __FILE__, __FUNC__, __LINE__, gse)); + if (NULL == gse) + break; + + // now read complete prefsIDStrings + if (GetPreferences(p_MyPrefsHandle, lID, prefsIDStrings, gse, size )) + { + gse->gse_Length = SCA_BE2LONG(gse->gse_Length); + } + + // read array of SCP_ControlBarGadgets + while ((size = GetEntry(p_MyPrefsHandle, lID, prefsIDGadgets, &sgy, sizeof(sgy), Entry)) > 0) + { + struct ControlBarGadgetEntry *cgy; + + d1(KPrintF("%s/%s/%ld: size=%lu\n", __FILE__, __FUNC__, __LINE__, size)); + + d1(KPrintF("%s/%s/%ld: sgy_Action=<%s>\n", __FILE__, __FUNC__, __LINE__, sgy.sgy_Action)); + d1(KPrintF("%s/%s/%ld: sgy_NormalImageIndex=%lu sgy_SelectedImageIndex=%lu\n", __FILE__, __FUNC__, __LINE__, sgy.sgy_NormalImageIndex, sgy.sgy_SelectedImageIndex)); + d1(KPrintF("%s/%s/%ld: sgy_DisabledImageIndex=%lu sgy_HelpTextIndex=%lu\n", __FILE__, __FUNC__, __LINE__, sgy.sgy_DisabledImageIndex, sgy.sgy_HelpTextIndex)); + + cgy = calloc(sizeof(struct ControlBarGadgetEntry), 1); + d1(KPrintF("%s/%s/%ld: cgy=%08lx Entry=%ld sgy_GadgetType=%ld\n", __FILE__, __FUNC__, __LINE__, cgy, Entry, sgy.sgy_GadgetType)); + if (NULL == cgy) + break; + + // create ControlBarGadgetEntry from SCP_GadgetEntry + cgy->cgy_GadgetType = SCA_BE2WORD(sgy.sgy_GadgetType); + stccpy(cgy->cgy_Action, sgy.sgy_Action, sizeof(cgy->cgy_Action)); + cgy->cgy_NormalImage = strdup(&gse->gse_Strings[SCA_BE2LONG(sgy.sgy_NormalImageIndex)]); + cgy->cgy_SelectedImage = strdup(&gse->gse_Strings[SCA_BE2LONG(sgy.sgy_SelectedImageIndex)]); + cgy->cgy_DisabledImage = strdup(&gse->gse_Strings[SCA_BE2LONG(sgy.sgy_DisabledImageIndex)]); + cgy->cgy_HelpText = strdup(&gse->gse_Strings[SCA_BE2LONG(sgy.sgy_HelpTextIndex)]); + + // add new ControlBarGadgetEntry to CbGadgetsList + AddTail(CbGadgetsList, &cgy->cgy_Node); + + Entry++; + } + } + else + { + // no stored record for control bar gadgets + // create internal default setup + CreateDefaultControlBarGadgets(); + } + } while (0); + + if (gse) + free(gse); + + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); +} + + +static void WriteControlBarGadgetList(struct SCAModule *app, APTR p_MyPrefsHandle, LONG lID, + ULONG ObjID, ULONG prefsIDGadgets, ULONG prefsIDStrings) +{ + struct SCP_GadgetStringEntry *gse = NULL; + + do { + struct ControlBarGadgetEntry *cgy; + size_t StringLength = 0; + size_t gseLength; + ULONG StringIndex = 0; + ULONG entries, n; + LONG Entry; + + if (0 == ObjID) + break; + + entries = getv(app->Obj[ObjID], MUIA_NList_Entries); + + // count required length for SCP_ControlBarGadgetStrings + for (n=0; nObj[ObjID], MUIM_NList_GetEntry, n, &cgy); + + if (SCPGadgetType_ActionButton == cgy->cgy_GadgetType) + { + StringLength += 1 + strlen(cgy->cgy_NormalImage); + StringLength += 1 + strlen(cgy->cgy_SelectedImage); + StringLength += 1 + strlen(cgy->cgy_DisabledImage); + StringLength += 1 + strlen(cgy->cgy_HelpText); + } + } + + // allocate SCP_ControlBarGadgetStrings + gseLength = sizeof(struct SCP_GadgetStringEntry) + StringLength; + gse = calloc(gseLength, 1); + if (NULL == gse) + break; + + gse->gse_Length = SCA_LONG2BE(StringLength); + Entry = 0; + + // start with empty string + strcpy(gse->gse_Strings, ""); + StringIndex++; + + for (n=0; nObj[ObjID], MUIM_NList_GetEntry, n, &cgy); + + memset(&sgy, 0, sizeof(sgy)); + + sgy.sgy_GadgetType = SCA_WORD2BE(cgy->cgy_GadgetType); + stccpy(sgy.sgy_Action, cgy->cgy_Action, sizeof(sgy.sgy_Action)); + + if (SCPGadgetType_ActionButton == cgy->cgy_GadgetType) + { + sgy.sgy_NormalImageIndex = SCA_LONG2BE(StringIndex); + strcpy(gse->gse_Strings + StringIndex, cgy->cgy_NormalImage); + StringIndex += 1 + strlen(cgy->cgy_NormalImage); + + sgy.sgy_SelectedImageIndex = SCA_LONG2BE(StringIndex); + strcpy(gse->gse_Strings + StringIndex, cgy->cgy_SelectedImage); + StringIndex += 1 + strlen(cgy->cgy_SelectedImage); + + sgy.sgy_DisabledImageIndex = SCA_LONG2BE(StringIndex); + strcpy(gse->gse_Strings + StringIndex, cgy->cgy_DisabledImage); + StringIndex += 1 + strlen(cgy->cgy_DisabledImage); + + sgy.sgy_HelpTextIndex = SCA_LONG2BE(StringIndex); + strcpy(gse->gse_Strings + StringIndex, cgy->cgy_HelpText); + StringIndex += 1 + strlen(cgy->cgy_HelpText); + } + + d1(KPrintF("%s/%s/%ld: Entry=%ld sgy_GadgetType=%ld\n", __FILE__, __FUNC__, __LINE__, Entry, sgy.sgy_GadgetType)); + d1(KPrintF("%s/%s/%ld: sgy_Action=<%s>\n", __FILE__, __FUNC__, __LINE__, sgy.sgy_Action)); + d1(KPrintF("%s/%s/%ld: sgy_NormalImageIndex=%lu sgy_SelectedImageIndex=%lu\n", __FILE__, __FUNC__, __LINE__, sgy.sgy_NormalImageIndex, sgy.sgy_SelectedImageIndex)); + d1(KPrintF("%s/%s/%ld: sgy_DisabledImageIndex=%lu sgy_HelpTextIndex=%lu\n", __FILE__, __FUNC__, __LINE__, sgy.sgy_DisabledImageIndex, sgy.sgy_HelpTextIndex)); + + SetEntry(p_MyPrefsHandle, lID, prefsIDGadgets, &sgy, sizeof(sgy), Entry++); + } + + // now write complete SCP_ControlBarGadgetStrings + SetPreferences(p_MyPrefsHandle, lID, prefsIDStrings, gse, gseLength); + } while (0); + + if (gse) + free(gse); +} + + +static void CleanupControlBarGadgetsList(struct List *CbGadgetsList) +{ + struct ControlBarGadgetEntry *cgy; + + while ((cgy = (struct ControlBarGadgetEntry *) RemHead(CbGadgetsList))) + { + if (cgy->cgy_NormalImage) + { + free(cgy->cgy_NormalImage); + cgy->cgy_NormalImage = NULL; + } + if (cgy->cgy_SelectedImage) + { + free(cgy->cgy_SelectedImage); + cgy->cgy_SelectedImage = NULL; + } + if (cgy->cgy_DisabledImage) + { + free(cgy->cgy_DisabledImage); + cgy->cgy_DisabledImage = NULL; + } + free(cgy); + } +} + + +static void CreateDefaultControlBarGadgets(void) +{ + ULONG n; + + CleanupControlBarGadgetsList(&ControlBarGadgetListBrowser); + + for (n = 0; n < Sizeof(DefaultControlBarGadgets); n++) + { + struct ControlBarGadgetEntry *cgy; + + cgy = calloc(sizeof(struct ControlBarGadgetEntry), 1); + d1(KPrintF("%s/%s/%ld: cgy=%08lx sgy_GadgetType=%ld\n", __FILE__, __FUNC__, __LINE__, cgy, DefaultControlBarGadgets[n].cgy_GadgetType)); + if (NULL == cgy) + break; + + // create ControlBarGadgetEntry from SCP_GadgetEntry + cgy->cgy_GadgetType = DefaultControlBarGadgets[n].cgy_GadgetType; + stccpy(cgy->cgy_Action, DefaultControlBarGadgets[n].cgy_Action, sizeof(cgy->cgy_Action)); + cgy->cgy_NormalImage = strdup(DefaultControlBarGadgets[n].cgy_NormalImage); + cgy->cgy_SelectedImage = strdup(DefaultControlBarGadgets[n].cgy_SelectedImage); + cgy->cgy_DisabledImage = strdup(DefaultControlBarGadgets[n].cgy_DisabledImage); + cgy->cgy_HelpText = strdup(DefaultControlBarGadgets[n].cgy_HelpText); + + // add new ControlBarGadgetEntry to ControlBarGadgetList + AddTail(&ControlBarGadgetListBrowser, &cgy->cgy_Node); + } +} + + +static ULONG GetLog2(ULONG value) +{ + ULONG Result = 0; + + while (value > 1) + { + value = (value >> 1) & 0x7fffffff; + Result++; + } + + return Result; +} + + +// write WORD/UWORD in big endian +static void SetWordPreferences(APTR prefsHandle, ULONG iD, ULONG prefsTag, CONST UWORD *arg, ULONG struct_Size) +{ + if (struct_Size == 2) + { + UWORD value = SCA_WORD2BE(*arg); + SetPreferences(prefsHandle, iD, prefsTag, &value, struct_Size ); + } +} + + +// write LONG/ULONG in big endian +static void SetLongPreferences(APTR prefsHandle, ULONG iD, ULONG prefsTag, CONST ULONG *arg, ULONG struct_Size) +{ + if (struct_Size == 4) + { + ULONG value = SCA_LONG2BE(*arg); + SetPreferences(prefsHandle, iD, prefsTag, &value, struct_Size ); + } +} diff --git a/scalos/Prefs/MainPrefs/ReadWritePrefs.h b/scalos/Prefs/MainPrefs/ReadWritePrefs.h new file mode 100644 index 000000000..7452b323d --- /dev/null +++ b/scalos/Prefs/MainPrefs/ReadWritePrefs.h @@ -0,0 +1,34 @@ +// ReadWritePrefs.h +// $Date$ +// $Revision$ + + +#ifndef READWRITEPREFS_H +#define READWRITEPREFS_H + +//----------------------------------------------------------------- + +#include "ScalosPrefs.h" + +//----------------------------------------------------------------- + +BOOL ReadWritePrefsInit(void); +void ReadWritePrefsCleanup(void); +IPTR mui_getv(APTR, ULONG ); +LONG WriteScalosPrefs(struct SCAModule *, CONST_STRPTR PrefsFileName); +LONG ReadScalosPrefs(CONST_STRPTR PrefsFileName); +void UpdateGuiFromPrefs(struct SCAModule *app); +struct PluginDef *FindPlugin(struct SCAModule *app, BPTR fLock); +void RemovePlugin(struct SCAModule *app, const struct PluginDef *pdRemove); +BOOL AddPlugin(struct SCAModule *app, CONST_STRPTR FileName); +void ResetToDefaults(struct SCAModule *app); +void ReadIconFontPrefs(struct SCAModule *app); +void WriteFontPrefs(struct SCAModule *app, CONST_STRPTR FontPrefsName); + +//----------------------------------------------------------------- + +#define getv(o,a) mui_getv(o,a) + +//----------------------------------------------------------------- + +#endif /* READWRITEPREFS_H */ diff --git a/scalos/Prefs/MainPrefs/Scalos.c b/scalos/Prefs/MainPrefs/Scalos.c new file mode 100644 index 000000000..be5587883 --- /dev/null +++ b/scalos/Prefs/MainPrefs/Scalos.c @@ -0,0 +1,8090 @@ +// Scalos.c +// $Date$ +// $Revision$ + +// program: Scalos Main Preferences +// coded by: Budda [mike@scalos.com] +// started: 16/01/2001 +// completed: +// updated: + +#ifdef __AROS__ +#define MUIMASTER_YES_INLINE_STDARG +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef __AROS__ +#define NO_INLINE_STDARG +#endif +#include + +#include + +#include +#include //+jmc+ + +#include "General.h" +#include "ScalosPrefs.h" +#include "ReadWritePrefs.h" +#include "HiddenDevices.h" +#include "Hooks.h" +#include "DataTypesMCC.h" +#include "McpFrameMCC.h" +#include "SelectMarkSampleClass.h" +#include +#include "Images.h" +#include "PrefsPlugins.h" +#include "UrlSubject.h" // +jmc+ define url subject for mailer. + +#define Scalos_Prefs_ARRAY +#define Scalos_Prefs_CODE +#define Scalos_Prefs_ARRAY +#include "locale.h" + +//----------------------------------------------------------------- + +#if !defined(MUIA_Text_HiCharIdx) +#define MUIA_Text_HiCharIdx 0x804214f5 +#endif //!defined(MUIA_Text_HiCharIdx) + +#define CheckMarkHelp(selected, HelpTextID)\ + ImageObject,\ + ImageButtonFrame,\ + MUIA_InputMode , MUIV_InputMode_Toggle,\ + MUIA_Image_Spec , MUII_CheckMark,\ + MUIA_Image_FreeVert , TRUE,\ + MUIA_Selected , selected,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShowSelState , FALSE,\ + MUIA_CycleChain , TRUE,\ + MUIA_ShortHelp , GetLocString(HelpTextID), \ + End + +#define THEME_CONTROLBAR "THEME:Window/ControlBar/" + +#define ScanButton\ + MUI_NewObject(MUIC_Text,\ + ButtonFrame,\ + MUIA_Font, MUIV_Font_Button,\ + MUIA_Text_HiCharIdx, '_',\ + MUIA_Text_Contents, "Scan",\ + MUIA_Text_PreParse, "\33c",\ + MUIA_InputMode, MUIV_InputMode_Toggle,\ + MUIA_Background, MUII_ButtonBack,\ + MUIA_CycleChain, 1,\ + MUIA_Weight, 0,\ + TAG_DONE) + +//----------------------------------------------------------------- + +struct BufferSizeSliderData +{ + char buf[20]; +} +; +struct PrecisionSliderData +{ + char buf[20]; +}; + +struct TTGammaSliderData +{ + char buf[20]; +}; + +struct ThumbnailLifetimeSliderData +{ + char buf[20]; +}; + +struct PageListData +{ + char ImageSpec[30]; + CONST_STRPTR TextLine; +}; + +struct CgyInit + { + enum SCPGadgetTypes cyi_GadgetType; + CONST_STRPTR cyi_NormalImage; // file name of normal state image + CONST_STRPTR cyi_SelectedImage; // file name of selected state image + CONST_STRPTR cyi_DisabledImage; // file name of disabled state image + }; + +#if 0 +#ifdef __amigaos4__ +struct LocaleInfo +{ + struct LocaleIFace *li_ILocale; + struct Catalog *li_Catalog; +}; +#endif +#endif + +//----------------------------------------------------------------- + +#if !defined(__amigaos4__) && !defined(__AROS__) +#include + +long _stack = 16384; // minimum stack size, used by SAS/C startup code +#endif + +//---------------------------------------------------------------------------- + +static ULONG TextWindowColumnsListDragQuery(Class *cl, Object *obj, struct MUIP_DragQuery *msg); +static ULONG TextWindowColumnsListDragDrop(Class *cl,Object *obj,struct MUIP_DragDrop *msg); +DISPATCHER_PROTO(TextWindowColumnsList); +static ULONG ControlBarGadgetsListDragQuery(Class *cl, Object *obj, struct MUIP_DragQuery *msg); +static ULONG ControlBarGadgetsListDragDrop(Class *cl,Object *obj,struct MUIP_DragDrop *msg); +DISPATCHER_PROTO(ControlBarGadgetsList); +DISPATCHER_PROTO(PrecisionSlider); +DISPATCHER_PROTO(BufferSizeSlider); +DISPATCHER_PROTO(TTGammaSlider); +DISPATCHER_PROTO(ThumbnailLifetimeSlider); +static VOID Cleanup(struct SCAModule *app); +static BOOL Init(struct SCAModule *app); +static BOOL BuildApp(LONG Action, struct SCAModule *app, struct DiskObject *icon); +static LONG MainLoop(LONG Action, struct SCAModule *app); + +static SAVEDS(APTR) INTERRUPT FileDisplayConstructHookFunc(struct Hook *hook, APTR memPool, struct NList_ConstructMessage *nlcm); +static SAVEDS(void) INTERRUPT FileDisplayDestructHookFunc(struct Hook *hook, APTR memPool, struct NList_DestructMessage *nldm); +static SAVEDS(ULONG) INTERRUPT FileDisplayHookFunc(struct Hook *hook, APTR unused, struct NList_DisplayMessage *nldm); + +static SAVEDS(APTR) INTERRUPT PluginListConstructHookFunc(struct Hook *hook, APTR memPool, struct NList_ConstructMessage *nlcm); +static SAVEDS(void) INTERRUPT PluginListDestructHookFunc(struct Hook *hook, APTR memPool, struct NList_DestructMessage *nldm); +static SAVEDS(ULONG) INTERRUPT PluginListDisplayHookFunc(struct Hook *hook, APTR unused, struct NList_DisplayMessage *nldm); +static SAVEDS(LONG) INTERRUPT PluginListCompareHookFunc(struct Hook *hook, APTR unused, struct NList_CompareMessage *ncm); + +static SAVEDS(APTR) INTERRUPT PageListConstructHookFunc(struct Hook *hook, APTR unused, struct NList_ConstructMessage *nlcm); +static SAVEDS(void) INTERRUPT PageListDestructHookFunc(struct Hook *hook, APTR unused, struct NList_DestructMessage *nldm); +static SAVEDS(ULONG) INTERRUPT PageListDisplayHookFunc(struct Hook *hook, APTR unused, struct NList_DisplayMessage *nldm); + +static SAVEDS(APTR) INTERRUPT ModulesListConstructHookFunc(struct Hook *hook, Object *o, struct NList_ConstructMessage *nlcm); +static SAVEDS(void) INTERRUPT ModulesListDestructHookFunc(struct Hook *hook, Object *o, struct NList_DestructMessage *nldm); +static SAVEDS(ULONG) INTERRUPT ModulesListDisplayHookFunc(struct Hook *hook, Object *o, struct NList_DisplayMessage *nldm); + +static SAVEDS(APTR) INTERRUPT HiddenDevicesConstructHookFunc(struct Hook *hook, APTR memPool, struct NList_ConstructMessage *nlcm); +static SAVEDS(void) INTERRUPT HiddenDevicesDestructHookFunc(struct Hook *hook, APTR memPool, struct NList_DestructMessage *nldm); +static SAVEDS(ULONG) INTERRUPT HiddenDevicesDisplayHookFunc(struct Hook *hook, APTR unused, struct NList_DisplayMessage *nldm); +static SAVEDS(LONG) INTERRUPT HiddenDevicesCompareHookFunc(struct Hook *hook, APTR unused, struct NList_CompareMessage *ncm); + +static SAVEDS(APTR) INTERRUPT ControlBarGadgetListConstructHookFunc(struct Hook *hook, Object *o, struct NList_ConstructMessage *nlcm); +static SAVEDS(void) INTERRUPT ControlBarGadgetListDestructHookFunc(struct Hook *hook, Object *o, struct NList_DestructMessage *nldm); +static SAVEDS(ULONG) INTERRUPT ControlBarGadgetListDisplayHookFunc(struct Hook *hook, Object *o, struct NList_DisplayMessage *nldm); + +static SAVEDS(APTR) INTERRUPT CmdListConstructHookFunc(struct Hook *hook, APTR obj, struct NList_ConstructMessage *msg); +static SAVEDS(void) INTERRUPT CmdListDestructHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *msg); +static SAVEDS(ULONG) INTERRUPT CmdListDisplayHookFunc(struct Hook *hook, APTR obj, struct NList_DisplayMessage *ltdm); +static SAVEDS(LONG) INTERRUPT CmdListCompareHookFunc(struct Hook *hook, Object *obj, struct NList_CompareMessage *msg); + +CONST_STRPTR GetString(struct Scalos_Prefs_LocaleInfo *li, LONG stringNum); +static void TranslateStringArray(CONST_STRPTR *stringArray); +static void EnableIconFontPrefs(struct SCAModule *app); +static void SetupNewPrefsPages(struct SCAModule *app); +static void InitControlBarGadgets(struct SCAModule *app); +static void SetHotkeyNotifications(Object *hotkey, Object *scan); + +static Object *GenerateAboutPage(struct SCAModule *app, CONST_STRPTR cVersion, CONST_STRPTR urlSubject); +static Object *GeneratePathsPage(struct SCAModule *app); +static Object *GenerateStartupPage(struct SCAModule *app); +static Object *GenerateDesktopPage(struct SCAModule *app); +static Object *GenerateIconsPage(struct SCAModule *app); +static Object *GenerateDragNDropPage(struct SCAModule *app); +static Object *GenerateWindowPage(struct SCAModule *app); +static Object *GenerateTextWindowPage(struct SCAModule *app); +static Object *GenerateTrueTypeFontsPage(struct SCAModule *app); +static Object *GenerateMiscPage(struct SCAModule *app); +static Object *GeneratePluginsPage(struct SCAModule *app); +static Object *GenerateModulesPage(struct SCAModule *app); + +//----------------------------------------------------------------- + +// defined in PrefsVersion.c +extern CONST_STRPTR BuildNr; // Build number aka SVN revision + +//----------------------------------------------------------------- + +struct IntuitionBase *IntuitionBase = NULL; +struct Library *PreferencesBase = NULL; +struct Library *MUIMasterBase = NULL; +struct ScalosBase *ScalosBase = NULL; +struct Library *IFFParseBase = NULL; +struct GfxBase *GfxBase = NULL; +#ifndef __amigaos4__ +T_UTILITYBASE UtilityBase = NULL; +#endif +T_LOCALEBASE LocaleBase = NULL; +struct Library *IconBase = NULL; +struct Library *AslBase = NULL; +struct Library *WorkbenchBase = NULL; +struct Library *CyberGfxBase = NULL; +struct Library *TTEngineBase = NULL; +struct Library *ScalosGfxBase = NULL; +struct Library *DiskfontBase = NULL; + +extern struct DosLibrary * DOSBase; + +#ifdef __amigaos4__ +extern struct Library *SysBase; +struct IntuitionIFace *IIntuition; +struct PreferencesIFace *IPreferences; +struct MUIMasterIFace *IMUIMaster; +struct ScalosIFace *IScalos; +struct IFFParseIFace *IIFFParse; +struct GraphicsIFace *IGraphics; +struct LocaleIFace *ILocale; +struct IconIFace *IIcon; +struct AslIFace *IAsl; +struct WorkbenchIFace *IWorkbench; +struct CyberGfxIFace *ICyberGfx; +struct ScalosGfxIFace *IScalosGfx; +struct TTEngineIFace *ITTEngine; +struct DiskfontIFace *IDiskfont; +#endif + +struct List PluginList; +struct List ControlBarGadgetListNormal; +struct List ControlBarGadgetListBrowser; + +static struct Catalog *ScalosPrefsCatalog; + +ULONG fCreateIcons = TRUE; + +static struct Screen *WBScreen = NULL; +static ULONG WBScreenDepth; + +ULONG ModuleImageIndex = 15; +static ULONG ModuleEntryIndex = IMAGE_DELETE; + +static ULONG ControlBarGadgetImageIndex = 0; + +static ULONG HiddenDevicesImageIndex = 0; +static ULONG HiddenDevicesEntryIndex = 1; + +CONST_STRPTR cTextWindowsColumns[] = +{ + (CONST_STRPTR) MSGID_FILEDISP_COLUMN_NAME, + (CONST_STRPTR) MSGID_FILEDISP_COLUMN_SIZE, + (CONST_STRPTR) MSGID_FILEDISP_COLUMN_PROT, + (CONST_STRPTR) MSGID_FILEDISP_COLUMN_DATE, + (CONST_STRPTR) MSGID_FILEDISP_COLUMN_TIME, + (CONST_STRPTR) MSGID_FILEDISP_COLUMN_COMMENT, + (CONST_STRPTR) MSGID_FILEDISP_COLUMN_OWNER, + (CONST_STRPTR) MSGID_FILEDISP_COLUMN_GROUP, + (CONST_STRPTR) MSGID_FILEDISP_COLUMN_FILETYPE, + (CONST_STRPTR) MSGID_FILEDISP_COLUMN_VERSION, + (CONST_STRPTR) MSGID_FILEDISP_COLUMN_ICON, + NULL +}; + +//----------------------------------------------------------------- + +static struct MUI_CustomClass *BufferSizeSliderClass; +static struct MUI_CustomClass *PrecisionSliderClass; +static struct MUI_CustomClass *TTGammaSliderClass; +static struct MUI_CustomClass *ThumbnailLifetimeSliderClass; +struct MUI_CustomClass *DataTypesImageClass; +struct MUI_CustomClass *McpFrameClass; +struct MUI_CustomClass *FontSampleClass; +struct MUI_CustomClass *SelectMarkSampleClass; +static struct MUI_CustomClass *TextWindowColumnsListClass; +static struct MUI_CustomClass *ControlBarGadgetsListClass; + +#ifdef __AROS__ +#define PrecisionSliderObject BOOPSIOBJMACRO_START(PrecisionSliderClass->mcc_Class) +#define ThumbnailLifetimeSliderObject BOOPSIOBJMACRO_START(ThumbnailLifetimeSliderClass->mcc_Class) +#define ControlBarGadgetsListObject BOOPSIOBJMACRO_START(ControlBarGadgetsListClass->mcc_Class) +#define TextWindowColumnsListObject BOOPSIOBJMACRO_START(TextWindowColumnsListClass->mcc_Class) +#define SelectMarkSampleObject BOOPSIOBJMACRO_START(SelectMarkSampleClass->mcc_Class) +#define TTGammaSliderObject BOOPSIOBJMACRO_START(TTGammaSliderClass->mcc_Class) +#define BufferSizeSliderObject BOOPSIOBJMACRO_START(BufferSizeSliderClass->mcc_Class) +#else +#define PrecisionSliderObject NewObject(PrecisionSliderClass->mcc_Class, 0 +#define ThumbnailLifetimeSliderObject NewObject(ThumbnailLifetimeSliderClass->mcc_Class, 0 +#define ControlBarGadgetsListObject NewObject(ControlBarGadgetsListClass->mcc_Class, 0 +#define TextWindowColumnsListObject NewObject(TextWindowColumnsListClass->mcc_Class, 0 +#define SelectMarkSampleObject NewObject(SelectMarkSampleClass->mcc_Class, 0 +#define TTGammaSliderObject NewObject(TTGammaSliderClass->mcc_Class, 0 +#define BufferSizeSliderObject NewObject(BufferSizeSliderClass->mcc_Class, 0 +#endif + + +STRPTR ProgramName = ""; +static struct DiskObject *PrefsDiskObject = NULL; + +static BOOL ShowSplashWindow = TRUE; +static BOOL SkipPrefsPlugins = FALSE; + +static ULONG cPrefGroups[] = +{ + MSGID_PREFGROUPS_ABOUT, + MSGID_PREFGROUPS_PATHS, + MSGID_PREFGROUPS_STARTUP, + MSGID_PREFGROUPS_DESKTOP, + MSGID_PREFGROUPS_ICONS, + MSGID_PREFGROUPS_DRAGNDROP, + MSGID_PREFGROUPS_WINDOWS, + MSGID_PREFGROUPS_TEXTWINDOWS, + MSGID_PREFGROUPS_TRUETYPEFONTS, + MSGID_PREFGROUPS_MISC, + MSGID_PREFGROUPS_PLUGINS, + MSGID_PREFGROUPS_MODULES, +}; + +static struct NewPageListEntry NewPrefsPages[Sizeof(cPrefGroups)]; + + +static CONST_STRPTR cTitleph[] = +{ + (CONST_STRPTR) MSGID_TITLEPLACEHOLDER_KICKSTART_RELEASE, + (CONST_STRPTR) MSGID_TITLEPLACEHOLDER_KICKSTART_VERSION, + (CONST_STRPTR) MSGID_TITLEPLACEHOLDER_SCALOS_RELEASE, + (CONST_STRPTR) MSGID_TITLEPLACEHOLDER_SCALOS_VERSION, + (CONST_STRPTR) MSGID_TITLEPLACEHOLDER_FREE_CHIP_MEM, + (CONST_STRPTR) MSGID_TITLEPLACEHOLDER_FREE_FAST_MEM, + (CONST_STRPTR) MSGID_TITLEPLACEHOLDER_FREE_MEM, + (CONST_STRPTR) MSGID_TITLEPLACEHOLDER_WINDOW_PATH, + (CONST_STRPTR) MSGID_TITLEPLACEHOLDER_DISK_FREE, + (CONST_STRPTR) MSGID_TITLEPLACEHOLDER_DISK_FREE_DIVIDE, + (CONST_STRPTR) MSGID_TITLEPLACEHOLDER_DISK_USED, + (CONST_STRPTR) MSGID_TITLEPLACEHOLDER_DISK_USED_DIVIDE, + (CONST_STRPTR) MSGID_TITLEPLACEHOLDER_START_NODISK, + (CONST_STRPTR) MSGID_TITLEPLACEHOLDER_STOP_NODISK, + (CONST_STRPTR) MSGID_TITLEPLACEHOLDER_DISK_PERCENT, + (CONST_STRPTR) MSGID_TITLEPLACEHOLDER_GFXCHIPS, + (CONST_STRPTR) MSGID_TITLEPLACEHOLDER_CPU, + (CONST_STRPTR) MSGID_TITLEPLACEHOLDER_FPU, + (CONST_STRPTR) MSGID_TITLEPLACEHOLDER_TASKS, + (CONST_STRPTR) MSGID_TITLEPLACEHOLDER_LIBRARIES, + (CONST_STRPTR) MSGID_TITLEPLACEHOLDER_PORTS, + (CONST_STRPTR) MSGID_TITLEPLACEHOLDER_DEVICES, + (CONST_STRPTR) MSGID_TITLEPLACEHOLDER_SCREENS, + NULL +}; + +static const struct CgyInit DefaultControlBarGadgets[] = +{ + { + SCPGadgetType_BackButton, + THEME_CONTROLBAR "ButtonBackNormal", + THEME_CONTROLBAR "ButtonBackSelected", + THEME_CONTROLBAR "ButtonBackDisabled", + }, + { + SCPGadgetType_ForwardButton, + THEME_CONTROLBAR "ButtonForwardNormal", + THEME_CONTROLBAR "ButtonForwardSelected", + THEME_CONTROLBAR "ButtonForwardDisabled", + }, + { + SCPGadgetType_UpButton, + THEME_CONTROLBAR "ButtonUpNormal", + THEME_CONTROLBAR "ButtonUpSelected", + THEME_CONTROLBAR "ButtonUpDisabled", + }, + { + SCPGadgetType_History, + THEME_CONTROLBAR "HistoryNormal", + THEME_CONTROLBAR "HistorySelected", + THEME_CONTROLBAR "HistoryDisabled", + }, + { + SCPGadgetType_BrowseButton, + THEME_CONTROLBAR "BrowseNormal", + THEME_CONTROLBAR "BrowseSelected", + THEME_CONTROLBAR "BrowseDisabled", + }, + { + SCPGadgetType_ViewBy, + THEME_CONTROLBAR "ViewByNormal", + THEME_CONTROLBAR "ViewBySelected", + THEME_CONTROLBAR "ViewByDisabled", + }, + { + SCPGadgetType_ShowMode, + THEME_CONTROLBAR "ShowModeNormal", + THEME_CONTROLBAR "ShowModeSelected", + THEME_CONTROLBAR "ShowModeDisabled", + }, + { + SCPGadgetType_Separator, + THEME_CONTROLBAR "SeparatorNormal", + THEME_CONTROLBAR "SeparatorSelected", + THEME_CONTROLBAR "SeparatorDisabled", + }, + { + SCPGadgetType_ActionButton, + THEME_CONTROLBAR "ActionButtonNormal", + THEME_CONTROLBAR "ActionButtonSelected", + THEME_CONTROLBAR "ActionButtonDisabled", + }, +}; + +static STRPTR cIconToolTips[] = +{ + "Name", + "Type", + "Size", + "Last changed", + "Protection", + "Comment", + NULL +}; + +static CONST_STRPTR cDesktopPages[] = + { + (CONST_STRPTR) MSGID_DESKTOPPAGES_SCREEN, + (CONST_STRPTR) MSGID_DESKTOPPAGES_ICONS, + (CONST_STRPTR) MSGID_DESKTOPPAGES_LAYOUT, + (CONST_STRPTR) MSGID_ICONPAGES_MISC, + NULL + }; + +static CONST_STRPTR cIconPages[] = +{ + (CONST_STRPTR) MSGID_ICONPAGES_ATRIBUTES, + (CONST_STRPTR) MSGID_ICONPAGES_SIZES, + (CONST_STRPTR) MSGID_ICONPAGES_LABELS, + (CONST_STRPTR) MSGID_ICONPAGES_BORDERS, + (CONST_STRPTR) MSGID_ICONPAGES_TOOLTIPS, + (CONST_STRPTR) MSGID_ICONPAGES_THUMBNAILS, + NULL +}; + +static CONST_STRPTR cScreenTitleModes[] = +{ + (CONST_STRPTR) MSGID_DESKTOPPAGES_SCREENTITLE_ALWAYS, + (CONST_STRPTR) MSGID_DESKTOPPAGES_SCREENTITLE_POP, + (CONST_STRPTR) MSGID_DESKTOPPAGES_SCREENTITLE_NEVER, + NULL +}; + +static CONST_STRPTR cCreateLinkTypes[] = +{ + (CONST_STRPTR) MSGID_CREATELINKS_HARDLINKS, + (CONST_STRPTR) MSGID_CREATELINKS_SOFTLINKS, + NULL +}; + +static CONST_STRPTR cWindowPages[] = +{ + (CONST_STRPTR) MSGID_WINDOWPAGES_GENERAL, + (CONST_STRPTR) MSGID_WINDOWPAGES_SIZE, + (CONST_STRPTR) MSGID_WINDOWPAGES_CONTROLBAR, + (CONST_STRPTR) MSGID_WINDOWPAGES_LAYOUT, + NULL +}; + +static CONST_STRPTR cWindowControlBar[] = +{ + (CONST_STRPTR) MSGID_WINDOWPAGES_CONTROLBAR_BROWSER, + (CONST_STRPTR) MSGID_WINDOWPAGES_CONTROLBAR_NORMAL, + NULL +}; +static CONST_STRPTR cTextWindowPages[] = +{ + (CONST_STRPTR) MSGID_TEXTWINDOWPAGES_FONTS, + (CONST_STRPTR) MSGID_TEXTWINDOWPAGES_COLUMNS, + (CONST_STRPTR) MSGID_TEXTWINDOWPAGES_SELECTIONMARKS, + (CONST_STRPTR) MSGID_TEXTWINDOWPAGES_MISC, + NULL +}; + +static CONST_STRPTR cWindowRefresh[] = +{ + (CONST_STRPTR) MSGID_WINDOWREFRESH_SIMPLE, + (CONST_STRPTR) MSGID_WINDOWREFRESH_SMART, + NULL +}; + +static CONST_STRPTR cShowAllDefault[] = +{ + (CONST_STRPTR) MSGID_WINDOW_SHOWALL_DEFAULT_ICONS, + (CONST_STRPTR) MSGID_WINDOW_SHOWALL_DEFAULT_ALL, + NULL +}; + +static CONST_STRPTR cIconLayoutModes[] = +{ + (CONST_STRPTR) MSGID_ICONLAYOUT_COLUMNS, + (CONST_STRPTR) MSGID_ICONLAYOUT_ROWS, + NULL +}; + +static CONST_STRPTR cDrawerSortMode[] = +{ + (CONST_STRPTR) MSGID_TEXTWINDOWPAGE_DRAWERSORT_TOP, + (CONST_STRPTR) MSGID_TEXTWINDOWPAGE_DRAWERSORT_BOTTOM, + (CONST_STRPTR) MSGID_TEXTWINDOWPAGE_DRAWERSORT_MIXED, + NULL +}; + +static CONST_STRPTR cViewByDefault[] = +{ + (CONST_STRPTR) MSGID_WINDOW_VIEWBY_DEFAULT_ICON, + (CONST_STRPTR) MSGID_WINDOW_VIEWBY_DEFAULT_NAME, + (CONST_STRPTR) MSGID_WINDOW_VIEWBY_DEFAULT_SIZE, + (CONST_STRPTR) MSGID_WINDOW_VIEWBY_DEFAULT_DATE, + (CONST_STRPTR) MSGID_WINDOW_VIEWBY_DEFAULT_TIME, + (CONST_STRPTR) MSGID_WINDOW_VIEWBY_DEFAULT_COMMENT, + (CONST_STRPTR) MSGID_WINDOW_VIEWBY_DEFAULT_PROTECTION, + (CONST_STRPTR) MGSID_WINDOW_VIEWBY_DEFAULT_OWNER, + (CONST_STRPTR) MSGID_WINDOW_VIEWBY_DEFAULT_GROUP, + NULL +}; + +static CONST_STRPTR cFileDisplayPages[] = +{ + (CONST_STRPTR) MSGID_FILEDISPLAYPAGES_TEXT, + NULL +}; + +static CONST_STRPTR cIconSizesMin[] = +{ + (CONST_STRPTR) MSGID_ICONSIZES_UNLIMITED, + (CONST_STRPTR) MSGID_ICONSIZES_16x16, + (CONST_STRPTR) MSGID_ICONSIZES_24x24, + (CONST_STRPTR) MSGID_ICONSIZES_32x32, + (CONST_STRPTR) MSGID_ICONSIZES_48x48, + (CONST_STRPTR) MSGID_ICONSIZES_64x64, + (CONST_STRPTR) MSGID_ICONSIZES_96x96, + (CONST_STRPTR) MSGID_ICONSIZES_128x128, + NULL +}; + +static CONST_STRPTR cIconSizesMax[] = +{ + (CONST_STRPTR) MSGID_ICONSIZES_16x16, + (CONST_STRPTR) MSGID_ICONSIZES_24x24, + (CONST_STRPTR) MSGID_ICONSIZES_32x32, + (CONST_STRPTR) MSGID_ICONSIZES_48x48, + (CONST_STRPTR) MSGID_ICONSIZES_64x64, + (CONST_STRPTR) MSGID_ICONSIZES_96x96, + (CONST_STRPTR) MSGID_ICONSIZES_128x128, + (CONST_STRPTR) MSGID_ICONSIZES_UNLIMITED, + NULL +}; + +static CONST_STRPTR cShowThumbnails[] = +{ + (CONST_STRPTR) MSGID_SHOWTHUMBNAILS_NEVER, + (CONST_STRPTR) MSGID_SHOWTHUMBNAILS_AS_DEFAULT, + (CONST_STRPTR) MSGID_SHOWTHUMBNAILS_ALWAYS, + NULL +}; + +static CONST_STRPTR cThumbnailSizes[] = +{ + (CONST_STRPTR) MSGID_THUMBNAILSIZES_16x16, + (CONST_STRPTR) MSGID_THUMBNAILSIZES_24x24, + (CONST_STRPTR) MSGID_THUMBNAILSIZES_32x32, + (CONST_STRPTR) MSGID_THUMBNAILSIZES_48x48, + (CONST_STRPTR) MSGID_THUMBNAILSIZES_64x64, + (CONST_STRPTR) MSGID_THUMBNAILSIZES_96x96, + (CONST_STRPTR) MSGID_THUMBNAILSIZES_128x128, + NULL +}; + +static CONST_STRPTR cIconLabelStyles[] = +{ + (CONST_STRPTR) MSGID_ICONLABELSTYLES_NORMAL, + (CONST_STRPTR) MSGID_ICONLABELSTYLES_OUTLINE, + (CONST_STRPTR) MSGID_ICONLABELSTYLES_SHADOW, + NULL +}; + +static CONST_STRPTR cIconDragStyle[] = +{ + (CONST_STRPTR) MSGID_ICONDRAGSTYLES_IMAGEONLY, + (CONST_STRPTR) MSGID_ICONDRAGSTYLES_IMAGEANDTEXT, + NULL +}; + +static CONST_STRPTR cIconDragDropPages[] = +{ + (CONST_STRPTR) MSGID_ICONSPAGES_DRAGNDROP_DRAGGING, + (CONST_STRPTR) MSGID_ICONSPAGES_DRAGNDROP_TRANSPARENCY, + (CONST_STRPTR) MSGID_ICONSPAGES_DRAGNDROP_TRIGGERS, + NULL +}; + +static CONST_STRPTR cIconDragTransparents[] = +{ + (CONST_STRPTR) MSGID_ICONDRAGTRANSPARENCY_GHOSTED, + (CONST_STRPTR) MSGID_ICONDRAGTRANSPARENCY_TRANSPARENT, + NULL +}; + +static CONST_STRPTR cIconDragRoutines[] = +{ + (CONST_STRPTR) MSGID_ICONDRAGTROUTINES_SYSTEM, + (CONST_STRPTR) MSGID_ICONDRAGTROUTINES_CUSTOM, + NULL +}; + +static CONST_STRPTR cIconDropMark[] = +{ + (CONST_STRPTR) MSGID_ICONDROPMARK_NEVER, + (CONST_STRPTR) MSGID_ICONDROPMARK_DRAWERSONLY, + (CONST_STRPTR) MSGID_ICONDROPMARK_ALWAYS, + NULL +}; + +static CONST_STRPTR cIconDragLook[] = +{ + (CONST_STRPTR) MSGID_ICONDRAGLOOK_SOLID_TRANSP, + (CONST_STRPTR) MSGID_ICONDRAGLOOK_ALWAYS_SOLID, + (CONST_STRPTR) MSGID_ICONDRAGLOOK_ALWAYS_TRANSP, + (CONST_STRPTR) MSGID_ICONDRAGLOOK_TRANSP_SOLID, + NULL +}; + +static CONST_STRPTR cTTFontsAntiAliasing[] = +{ + (CONST_STRPTR) MSGID_TTFONTSPAGE_ANTIALIASING_AUTO, + (CONST_STRPTR) MSGID_TTFONTSPAGE_ANTIALIASING_OFF, + (CONST_STRPTR) MSGID_TTFONTSPAGE_ANTIALIASING_ON, + NULL +}; + +// order must correspond to "enum SCPGadgetTypes" +static CONST_STRPTR cControlBarGadgetTypes[] = +{ + (CONST_STRPTR) MSGID_SCPGADGETTYPE_BACKBUTTON, + (CONST_STRPTR) MSGID_SCPGADGETTYPE_FORWARDBUTTON, + (CONST_STRPTR) MSGID_SCPGADGETTYPE_UPBUTTON, + (CONST_STRPTR) MSGID_SCPGADGETTYPE_HISTORY, + (CONST_STRPTR) MSGID_SCPGADGETTYPE_BROWSEBUTTON, + (CONST_STRPTR) MSGID_SCPGADGETTYPE_VIEWBY, + (CONST_STRPTR) MSGID_SCPGADGETTYPE_SHOWMODE, + (CONST_STRPTR) MSGID_SCPGADGETTYPE_SEPARATOR, + (CONST_STRPTR) MSGID_SCPGADGETTYPE_ACTIONBUTTON, + NULL +}; + +static const struct CommandTableEntry CommandsTable[] = + { + { "backdrop", MSGID_COM1NAME }, + { "executecommand", MSGID_COM2NAME }, + { "redrawall", MSGID_COM3NAME }, + { "updateall", MSGID_COM4NAME }, + { "about", MSGID_COM5NAME }, + { "quit", MSGID_COM6NAME }, + { "makedir", MSGID_COM7NAME }, + { "parent", MSGID_COM8NAME }, + { "close", MSGID_COM9NAME }, + { "update", MSGID_COM10NAME }, + { "selectall", MSGID_COM11NAME }, + { "cleanup", MSGID_COM12NAME }, + { "snapshotwindow", MSGID_COM13NAME }, + { "snapshotall", MSGID_COM14NAME }, + { "showonlyicons", MSGID_COM15NAME }, + { "showallfiles", MSGID_COM16NAME }, + { "showdefault", MSGID_COM48NAME }, + { "open", MSGID_COM19NAME }, + { "openinnewwindow", MSGID_COM_OPENNEWWINDOW }, + { "reset", MSGID_COM20NAME }, + { "rename", MSGID_COM21NAME }, + { "iconinfo", MSGID_COM22NAME }, + { "iconproperties", MSGID_COM_ICONPROPERTIES }, + { "windowproperties", MSGID_COM_WINDOWPROPERTIES }, + { "snapshot", MSGID_COM23NAME }, + { "unsnapshot", MSGID_COM24NAME }, + { "leaveout", MSGID_COM25NAME }, + { "putaway", MSGID_COM26NAME }, + { "delete", MSGID_COM27NAME }, + { "clone", MSGID_COM28NAME }, + { "emptytrashcan", MSGID_COM29NAME }, + { "lastmsg", MSGID_COM30NAME }, + { "redraw", MSGID_COM31NAME }, + { "iconify", MSGID_COM32NAME }, + { "formatdisk", MSGID_COM33NAME }, + { "shutdown", MSGID_COM34NAME }, + { "sizetofit", MSGID_COM35NAME }, + { "thumbnailcachecleanup", MSGID_COM_THUMBNAILCACHECLEANUP }, + { "clearselection", MSGID_COM36NAME }, + { "viewbyicon", MSGID_COM17NAME }, + { "viewbytext", MSGID_COM18NAME }, + { "viewbysize", MSGID_COM37NAME }, + { "viewbydate", MSGID_COM38NAME }, + { "viewbytype", MSGID_COM42NAME }, + { "viewbydefault", MSGID_COM47NAME }, + { "copy", MSGID_COM39NAME }, + { "cut", MSGID_COM40NAME }, + { "copyto", MSGID_COM49NAME }, + { "moveto", MSGID_COM50NAME }, + { "paste", MSGID_COM41NAME }, + { "cleanupbyname", MSGID_COM43NAME }, + { "cleanupbydate", MSGID_COM44NAME }, + { "cleanupbysize", MSGID_COM45NAME }, + { "cleanupbytype", MSGID_COM46NAME }, + { "createthumbnail", MSGID_COM51NAME }, + + }; + +static const struct CommandTableEntry *CommandsArray[1 + Sizeof(CommandsTable)]; + +static STRPTR cModulePrefs[] = +{ + "delete.module", + "empty_trashcan.module", + "execute_command.module", + "format_disk.module", + "information.module", + "iconproperties.module", + "newdrawer.module", + "reboot.module", + "rename.module", + "systeminfo.module", + "windowproperties.module", + NULL +}; + + +static struct Hook IconsSelectBobRoutineHook = { { NULL, NULL }, HOOKFUNC_DEF(IconsSelectBobRoutineHookFunc), NULL }; + +static struct Hook IconsMinSizeHook = { { NULL, NULL }, HOOKFUNC_DEF(IconsMinSizeHookFunc), NULL }; +static struct Hook IconsMaxSizeHook = { { NULL, NULL }, HOOKFUNC_DEF(IconsMaxSizeHookFunc), NULL }; + +static struct Hook ModulesPrefsPopupHook = { { NULL, NULL }, HOOKFUNC_DEF(ModulesPrefsPopupHookFunc), NULL }; + +static struct Hook DesktopHiddenDevicesHook = { { NULL, NULL }, HOOKFUNC_DEF(DesktopHiddenDevicesHookFunc), NULL }; + +static struct Hook FileDisplayDisplayHook = { { NULL, NULL }, HOOKFUNC_DEF(FileDisplayHookFunc), NULL }; +static struct Hook FileDisplayConstructHook = { { NULL, NULL }, HOOKFUNC_DEF(FileDisplayConstructHookFunc), NULL }; +static struct Hook FileDisplayDestructHook = { { NULL, NULL }, HOOKFUNC_DEF(FileDisplayDestructHookFunc), NULL }; + +static struct Hook ModulesListDisplayHook = { { NULL, NULL }, HOOKFUNC_DEF(ModulesListDisplayHookFunc), NULL }; +static struct Hook ModulesListConstructHook = { { NULL, NULL }, HOOKFUNC_DEF(ModulesListConstructHookFunc), NULL }; +static struct Hook ModulesListDestructHook = { { NULL, NULL }, HOOKFUNC_DEF(ModulesListDestructHookFunc), NULL }; + +static struct Hook PageListDisplayHook = { { NULL, NULL }, HOOKFUNC_DEF(PageListDisplayHookFunc), NULL }; +static struct Hook PageListConstructHook = { { NULL, NULL }, HOOKFUNC_DEF(PageListConstructHookFunc), NULL }; +static struct Hook PageListDestructHook = { { NULL, NULL }, HOOKFUNC_DEF(PageListDestructHookFunc), NULL }; + +static struct Hook PluginListDisplayHook = { { NULL, NULL }, HOOKFUNC_DEF(PluginListDisplayHookFunc), NULL }; +static struct Hook PluginListConstructHook = { { NULL, NULL }, HOOKFUNC_DEF(PluginListConstructHookFunc), NULL }; +static struct Hook PluginListDestructHook = { { NULL, NULL }, HOOKFUNC_DEF(PluginListDestructHookFunc), NULL }; +static struct Hook PluginListCompareHook = { { NULL, NULL }, HOOKFUNC_DEF(PluginListCompareHookFunc), NULL }; + +static struct Hook HiddenDevicesDisplayHook = { { NULL, NULL }, HOOKFUNC_DEF(HiddenDevicesDisplayHookFunc), NULL }; +static struct Hook HiddenDevicesConstructHook = { { NULL, NULL }, HOOKFUNC_DEF(HiddenDevicesConstructHookFunc), NULL }; +static struct Hook HiddenDevicesDestructHook = { { NULL, NULL }, HOOKFUNC_DEF(HiddenDevicesDestructHookFunc), NULL }; +static struct Hook HiddenDevicesCompareHook = { { NULL, NULL }, HOOKFUNC_DEF(HiddenDevicesCompareHookFunc), NULL }; + +static struct Hook PluginListAppMsgHook = { { NULL, NULL }, HOOKFUNC_DEF(PluginListAppMsgHookFunc), NULL }; + +static struct Hook ControlBarGadgetListDisplayHook = { { NULL, NULL }, HOOKFUNC_DEF(ControlBarGadgetListDisplayHookFunc), NULL }; +static struct Hook ControlBarGadgetListConstructHook = { { NULL, NULL }, HOOKFUNC_DEF(ControlBarGadgetListConstructHookFunc), NULL }; +static struct Hook ControlBarGadgetListDestructHook = { { NULL, NULL }, HOOKFUNC_DEF(ControlBarGadgetListDestructHookFunc), NULL }; + +static struct Hook CmdListConstructHook = { { NULL, NULL }, HOOKFUNC_DEF(CmdListConstructHookFunc), NULL }; +static struct Hook CmdListDestructHook = { { NULL, NULL }, HOOKFUNC_DEF(CmdListDestructHookFunc), NULL }; +static struct Hook CmdListDisplayHook = { { NULL, NULL }, HOOKFUNC_DEF(CmdListDisplayHookFunc), }; +static struct Hook CmdListCompareHook = { { NULL, NULL }, HOOKFUNC_DEF(CmdListCompareHookFunc), NULL }; + +static struct Hook NormalCmdSelectedHook = { { NULL, NULL }, HOOKFUNC_DEF(NormalCmdSelectedHookFunc), NULL }; +static struct Hook BrowserCmdSelectedHook = { { NULL, NULL }, HOOKFUNC_DEF(BrowserCmdSelectedHookFunc), NULL }; +static struct Hook ControlBarGadgetBrowserChangedHook = { { NULL, NULL }, HOOKFUNC_DEF(ControlBarGadgetBrowserChangedHookFunc), NULL }; +static struct Hook ControlBarGadgetNormalChangedHook = { { NULL, NULL }, HOOKFUNC_DEF(ControlBarGadgetNormalChangedHookFunc), NULL }; + +static struct Hook ScreenTtfPopOpenHook = { { NULL, NULL }, HOOKFUNC_DEF(ScreenTtfPopOpenHookFunc), NULL }; +static struct Hook ScreenTtfPopCloseHook = { { NULL, NULL }, HOOKFUNC_DEF(ScreenTtfPopCloseHookFunc), NULL }; +static struct Hook IconTtfPopOpenHook = { { NULL, NULL }, HOOKFUNC_DEF(IconTtfPopOpenHookFunc), NULL }; +static struct Hook IconTtfPopCloseHook = { { NULL, NULL }, HOOKFUNC_DEF(IconTtfPopCloseHookFunc), NULL }; +static struct Hook TextWindowTtfPopOpenHook = { { NULL, NULL }, HOOKFUNC_DEF(TextWindowTtfPopOpenHookFunc), NULL }; +static struct Hook TextWindowTtfPopCloseHook = { { NULL, NULL }, HOOKFUNC_DEF(TextWindowTtfPopCloseHookFunc), NULL }; + +static struct Hook IconDragTransparencyHook = { { NULL, NULL }, HOOKFUNC_DEF(IconDragTransparencyHookFunc), NULL }; + +static struct Hook ChangeThumbnailSizeHook = { { NULL, NULL }, HOOKFUNC_DEF(ChangeThumbnailSizeHookFunc), NULL }; + + +static struct Hook OpenHook = { { NULL, NULL }, HOOKFUNC_DEF(OpenHookFunc), NULL }; +static struct Hook SaveAsHook = { { NULL, NULL }, HOOKFUNC_DEF(SaveAsFunc), NULL }; +static struct Hook LastSavedHook = { { NULL, NULL }, HOOKFUNC_DEF(LastSavedFunc), NULL }; +static struct Hook Pop_FontPrefs_Hook = {{NULL, NULL}, HOOKFUNC_DEF(StartFontPrefs_Func), NULL}; +static struct Hook Pop_WorkbenchPrefs_Hook = {{NULL, NULL}, HOOKFUNC_DEF(StartWorkbenchPrefs_Func), NULL}; +static struct Hook Add_Plugin_Hook = {{NULL, NULL}, HOOKFUNC_DEF(AddPlugin_Func), NULL}; +static struct Hook PluginListActiveHook = {{NULL, NULL}, HOOKFUNC_DEF(PluginActive_Func), NULL}; +static struct Hook ControlBarGadgetListNormalActiveHook = {{NULL, NULL}, HOOKFUNC_DEF(ControlBarGadgetListNormalActiveHookFunc), NULL}; +static struct Hook ControlBarGadgetListBrowserActiveHook = {{NULL, NULL}, HOOKFUNC_DEF(ControlBarGadgetListBrowserActiveHookFunc), NULL}; +static struct Hook ResetToDefaultsHook = { { NULL, NULL }, HOOKFUNC_DEF(ResetToDefaultsFunc), NULL }; +static struct Hook RestoreHook = { { NULL, NULL }, HOOKFUNC_DEF(RestoreFunc), NULL }; +static struct Hook AboutHook = { { NULL, NULL }, HOOKFUNC_DEF(OpenAboutFunc), NULL }; +static struct Hook AboutMorphosHook = { { NULL, NULL }, HOOKFUNC_DEF(OpenAboutMorpOSFunc), NULL }; +static struct Hook AboutMUIHook = { { NULL, NULL }, HOOKFUNC_DEF(OpenAboutMUIFunc), NULL }; +static struct Hook CreateIconsHook = { { NULL, NULL }, HOOKFUNC_DEF(CreateIconsHookFunc), NULL }; +static struct Hook RemovePluginHook = { { NULL, NULL }, HOOKFUNC_DEF(RemovePluginFunc), NULL }; +static struct Hook PageChangeHook = { { NULL, NULL }, HOOKFUNC_DEF(PageChangeHookFunc), NULL }; +static struct Hook IconFrame_NewBorder_Hook = { { NULL, NULL }, HOOKFUNC_DEF(IconFrameHookFunc), NULL }; +static struct Hook ThumbnailFrame_NewBorder_Hook = { { NULL, NULL }, HOOKFUNC_DEF(ThumbnailFrameHookFunc), NULL }; +static struct Hook UpdateSelectMarkerSampleHook = { { NULL, NULL }, HOOKFUNC_DEF(UpdateSelectMarkerSampleHookFunc), NULL }; + +struct Hook AslIntuiMsgHook = { { NULL, NULL }, HOOKFUNC_DEF(AslIntuiMsgHookFunc), NULL }; +struct Hook CalculateMaxRadiusHook = { { NULL, NULL }, HOOKFUNC_DEF(CalculateMaxRadiusHookFunc), NULL }; + +//----------------------------------------------------------------- + +// set notifications for a HotkeyString/ScanButton combo +static void SetHotkeyNotifications(Object *hotkey, Object *scan) +{ + DoMethod(scan, MUIM_Notify, MUIA_Selected, TRUE, + MUIV_Notify_Window, 3, MUIM_Set, MUIA_Window_ActiveObject, + hotkey); + + DoMethod(scan, MUIM_Notify, MUIA_Selected, MUIV_EveryTime, hotkey, + 3, MUIM_Set, MUIA_HotkeyString_Snoop, MUIV_TriggerValue); + + //DoMethod(hotkey, MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + // scan, 3, MUIM_Set, MUIA_Selected, FALSE); +} + +//----------------------------------------------------------------- + +static BOOL BuildApp(LONG Action, struct SCAModule *app, struct DiskObject *icon) +{ + static char cVersion[60] = ""; + static char urlSubject[sizeof(URLSUBJECT_SCAVERSION) + 40] = ""; + static char copyRightVersion[120] = ""; + ULONG n; + struct TagItem *PluginTagList; +#if defined(MUIA_Application_UsedClasses) + static STRPTR UsedClasses[] = + { + MUIC_BetterString, + MUIC_Lamp, + MUIC_NFloattext, + MUIC_HotkeyString, + MUIC_Popplaceholder, + MUIC_Urltext, + MUIC_NListview, + MUIC_NListtree, + MUIC_TextEditor, + NULL + }; +#endif /* MUIA_Application_UsedClasses */ + + d1(KPrintF(__FILE__ "/%s/%ld: START\n", __FUNC__, __LINE__)); + + if (!CheckMCCVersion(MUIC_BetterString, 11, 0) + || !CheckMCCVersion(MUIC_Lamp, 11, 0) + || !CheckMCCVersion(MUIC_NFloattext, 19, 48) + || !CheckMCCVersion(MUIC_HotkeyString, 12, 16) + || !CheckMCCVersion(MUIC_Popplaceholder, 15, 4) + || !CheckMCCVersion(MUIC_Urltext, 16, 1) + || !CheckMCCVersion(MUIC_NListview, 19, 66) + || !CheckMCCVersion(MUIC_NListtree, 18, 18) + || !CheckMCCVersion(MUIC_TextEditor, 15, 22)) + { + d1(KPrintF(__FILE__ "/%s/%ld: CheckMCCVersion failed\n", __FUNC__, __LINE__)); + return FALSE; + } + + IconFrame_NewBorder_Hook.h_Data = app; + ThumbnailFrame_NewBorder_Hook.h_Data = app; + Pop_FontPrefs_Hook.h_Data = app; + Pop_WorkbenchPrefs_Hook.h_Data = app; + Add_Plugin_Hook.h_Data = app; + PluginListAppMsgHook.h_Data = app; + PluginListActiveHook.h_Data = app; + ControlBarGadgetListBrowserActiveHook.h_Data = app; + ControlBarGadgetListNormalActiveHook.h_Data = app; + OpenHook.h_Data = app; + SaveAsHook.h_Data = app; + LastSavedHook.h_Data = app; + RestoreHook.h_Data = app; + ResetToDefaultsHook.h_Data = app; + AboutHook.h_Data = app; + AboutMorphosHook.h_Data = app; + AboutMUIHook.h_Data = app; + CreateIconsHook.h_Data = app; + RemovePluginHook.h_Data = app; + ModulesPrefsPopupHook.h_Data = app; + DesktopHiddenDevicesHook.h_Data = app; + IconsSelectBobRoutineHook.h_Data = app; + PageChangeHook.h_Data = app; + ModulesListConstructHook.h_Data = app; + ModulesListDestructHook.h_Data = app; + ScreenTtfPopOpenHook.h_Data = app; + ScreenTtfPopCloseHook.h_Data = app; + IconTtfPopOpenHook.h_Data = app; + IconTtfPopCloseHook.h_Data = app; + TextWindowTtfPopOpenHook.h_Data = app; + TextWindowTtfPopCloseHook.h_Data = app; + IconDragTransparencyHook.h_Data = app; + CalculateMaxRadiusHook.h_Data = app; + IconsMinSizeHook.h_Data = app; + IconsMaxSizeHook.h_Data = app; + HiddenDevicesDisplayHook.h_Data = app; + HiddenDevicesConstructHook.h_Data = app; + HiddenDevicesDestructHook.h_Data = app; + HiddenDevicesCompareHook.h_Data = app; + AslIntuiMsgHook.h_Data = app; + ControlBarGadgetListConstructHook.h_Data = app; + ControlBarGadgetListDestructHook.h_Data = app; + CmdListConstructHook.h_Data = app; + CmdListDestructHook.h_Data = app; + CmdListDisplayHook.h_Data = app; + CmdListCompareHook.h_Data = app; + NormalCmdSelectedHook.h_Data = app; + BrowserCmdSelectedHook.h_Data = app; + ControlBarGadgetBrowserChangedHook.h_Data = app; + ControlBarGadgetNormalChangedHook.h_Data = app; + AboutMUIHook.h_Data = app; + UpdateSelectMarkerSampleHook.h_Data = app; + ChangeThumbnailSizeHook.h_Data = app; + + TranslateStringArray(cTextWindowsColumns); + TranslateStringArray(cDesktopPages); + TranslateStringArray(cIconPages); + TranslateStringArray(cTitleph); + TranslateStringArray(cWindowPages); + TranslateStringArray(cWindowControlBar); + TranslateStringArray(cTextWindowPages); + TranslateStringArray(cScreenTitleModes); + TranslateStringArray(cCreateLinkTypes); + TranslateStringArray(cWindowRefresh); + TranslateStringArray(cShowAllDefault); + TranslateStringArray(cIconLayoutModes); + TranslateStringArray(cDrawerSortMode); + TranslateStringArray(cViewByDefault); + TranslateStringArray(cFileDisplayPages); + TranslateStringArray(cIconSizesMin); + TranslateStringArray(cIconSizesMax); + TranslateStringArray(cShowThumbnails); + TranslateStringArray(cThumbnailSizes); + TranslateStringArray(cIconLabelStyles); + TranslateStringArray(cIconDragStyle); + TranslateStringArray(cTTFontsAntiAliasing); + TranslateStringArray(cControlBarGadgetTypes); + TranslateStringArray(cIconDragTransparents); + TranslateStringArray(cIconDragRoutines); + TranslateStringArray(cIconDropMark); + TranslateStringArray(cIconDragLook); + TranslateStringArray(cIconDragDropPages); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + for (n = 0; n < Sizeof(CommandsTable); n++) + CommandsArray[n] = &CommandsTable[n]; + CommandsArray[Sizeof(CommandsTable)] = NULL; + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + // try to read V3.5+ workbench.prefs + ReadWorkbenchPrefs("ENV:sys/workbench.prefs"); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + if (!SkipPrefsPlugins) + CollectPrefsPlugins(app, "PROGDIR:", "#?.prefsplugin"); + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + CreatePrefsPlugins(app); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + if (!CheckMCCsForAllPrefsPlugins()) + { + d1(KPrintF(__FILE__ "/%s/%ld: CheckMCCsForAllPrefsPlugins failed\n", __FUNC__, __LINE__)); + return FALSE; + } + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + PluginTagList = GetPrefsPluginSubWindows(app); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + // --- Get The Scalos.library Version Number Currently Running + if (ScalosBase) + { + CONST_STRPTR ScalosRelease; + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + if (ScalosBase->scb_LibNode.lib_Version > 40 + || (40 == ScalosBase->scb_LibNode.lib_Version + && ScalosBase->scb_LibNode.lib_Revision >= 34)) + { + ScalosRelease = ScalosBase->scb_Revision; + } + else + { + ScalosRelease = "1.3"; + } + + snprintf(cVersion, sizeof(cVersion), GetLocString(MSGID_VERSIONSTRING), + ScalosRelease, + ScalosBase->scb_LibNode.lib_Version, + ScalosBase->scb_LibNode.lib_Revision, + BuildNr); + snprintf(urlSubject, sizeof(urlSubject), URLSUBJECT_SCAVERSION, + cVersion); + } + else + { + strcpy(cVersion, ""); + strcpy(urlSubject, "Scalos"); + } + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + snprintf(copyRightVersion, sizeof(copyRightVersion), GetLocString(MSGID_COPYRIGHTSTRING), CURRENTYEAR); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + SetupNewPrefsPages(app); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + +#if defined(__MORPHOS__) + app->Obj[WIN_ABOUT_MORPHOS] = MUI_NewObject("Pantheon.mcc", + MUIA_Window_ID, MAKE_ID('A','M','A','M'), + End; //Pantheon.mcc" +#endif //defined(__MORPHOS__) + + app->Obj[APPLICATION] = ApplicationObject, + + MUIA_Application_Author, AUTHOR, + MUIA_Application_Base, PROGRAM, + MUIA_Application_Copyright, (ULONG) copyRightVersion, + MUIA_Application_Description, PROGRAM, + MUIA_Application_Title, PROGRAM, + MUIA_Application_Version, "$VER: " PROGRAM " V" VERSION " (" __DATE__ ")" COMPILER_STRING, +#if defined(MUIA_Application_UsedClasses) + MUIA_Application_UsedClasses, UsedClasses, +#endif /* MUIA_Application_UsedClasses */ + PrefsDiskObject ? MUIA_Application_DiskObject : TAG_IGNORE, PrefsDiskObject, + MUIA_Application_SingleTask, TRUE, + +// ----------------------------------------------------------------------------------------------- + + SubWindow, app->Obj[WINDOW_MAIN] = WindowObject, + MUIA_Window_ID, MAKE_ID('S', 'C', 'S', 'P'), + MUIA_Window_Title, PROGRAM, + MUIA_Window_AppWindow, TRUE, + + WindowContents, app->Obj[GROUP_MAIN] = VGroup, + + Child, HGroup, + Child, app->Obj[LISTVIEW] = NListviewObject, + MUIA_NListview_NList, app->Obj[LIST] = NListObject, + InputListFrame, + MUIA_Background, MUII_ListBack, + MUIA_NList_DefaultObjectOnClick, TRUE, + MUIA_NList_MultiSelect, MUIV_NList_MultiSelect_None, + MUIA_NList_DisplayHook2, (ULONG) &PageListDisplayHook, + MUIA_NList_ConstructHook2, (ULONG) &PageListConstructHook, + MUIA_NList_DestructHook2, (ULONG) &PageListDestructHook, + MUIA_NList_Format, (ULONG) ",", + MUIA_NList_ShowDropMarks, FALSE, + MUIA_NList_AdjustWidth, TRUE, + MUIA_NList_AutoVisible, TRUE, + End, + MUIA_Listview_MultiSelect, MUIV_Listview_MultiSelect_None, + MUIA_Listview_DragType, MUIV_Listview_DragType_None, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_PREFGROUPS_SHORTHELP), + End, //NListview + + Child, BalanceObject, + End, //BalanceObject + + Child, app->Obj[GROUP] = PageGroup, + VirtualFrame, + MUIA_InnerBottom, 0, + MUIA_InnerLeft, 0, + MUIA_InnerRight, 0, + MUIA_InnerTop, 0, + + Child, GenerateAboutPage(app, cVersion, urlSubject), + Child, GeneratePathsPage(app), + Child, GenerateStartupPage(app), + Child, GenerateDesktopPage(app), + Child, GenerateIconsPage(app), + Child, GenerateDragNDropPage(app), + Child, GenerateWindowPage(app), + Child, GenerateTextWindowPage(app), + Child, GenerateTrueTypeFontsPage(app), + Child, GenerateMiscPage(app), + Child, GeneratePluginsPage(app), + Child, GenerateModulesPage(app), + + End, //PageGroup + End, //HGroup + +// ----------------------------------------------------------------------------------------------- + + Child, HGroup, + Child, app->Obj[SAVE] = TextObject, + ButtonFrame, + MUIA_Background, MUII_ButtonBack, + MUIA_Font, MUIV_Font_Button, + MUIA_InputMode, MUIV_InputMode_RelVerify, + MUIA_Text_HiChar, 's', + MUIA_ControlChar, 's', + MUIA_Text_Contents, (ULONG) GetLocString(MSGID_SAVEBUTTON), + MUIA_CycleChain, 1, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_SAVEBUTTON_SHORTHELP), + End, //TextObject + Child, app->Obj[USE] = TextObject, + ButtonFrame, + MUIA_Background, MUII_ButtonBack, + MUIA_Font, MUIV_Font_Button, + MUIA_InputMode, MUIV_InputMode_RelVerify, + MUIA_Text_HiChar, 'u', + MUIA_ControlChar, 'u', + MUIA_Text_Contents, (ULONG) GetLocString(MSGID_USEBUTTON), + MUIA_CycleChain, 1, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_USEBUTTON_SHORTHELP), + End, //TextObject + Child, app->Obj[CANCEL] = TextObject, + ButtonFrame, + MUIA_Background, MUII_ButtonBack, + MUIA_Font, MUIV_Font_Button, + MUIA_InputMode, MUIV_InputMode_RelVerify, + MUIA_Text_HiChar, 'c', + MUIA_ControlChar, 'c', + MUIA_Text_Contents, (ULONG) GetLocString(MSGID_CANCELBUTTON), + MUIA_CycleChain, 1, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_CANCELBUTTON_SHORTHELP), + End, //TextObject + End, //HGroup + + End, //VGroup + + End, //Window + +#if defined(__MORPHOS__) + (app->Obj[WIN_ABOUT_MORPHOS]) ? SubWindow : TAG_IGNORE, app->Obj[WIN_ABOUT_MORPHOS], +#endif //defined(__MORPHOS__) + +// ----------------------------------------------------------------------------------------------- +/// + // Icon frame selection window + SubWindow, app->Obj[WINDOW_ICONFRAMES] = WindowObject, + MUIA_Window_ID, MAKE_ID('F', 'R', 'A', 'M'), + MUIA_Window_Title, (ULONG) GetLocString(MSGID_FRAMEWINDOW_TITLE), + MUIA_Window_NoMenus, TRUE, + + WindowContents, RowGroup(2), + + Child, McpFrameObject, + ButtonFrame, + MUIA_InputMode, MUIV_InputMode_None, + MUIA_FixWidth, 12, + MUIA_FixHeight, 12, + MUIA_InnerBottom, 6, + MUIA_InnerLeft, 6, + MUIA_InnerRight, 6, + MUIA_InnerTop, 6, + MUIA_Background, MUII_ButtonBack, + MUIA_MCPFrame_FrameType, MCP_FRAME_NONE, + MUIA_Draggable, TRUE, + MUIA_Dropable, FALSE, + End, + + Child, McpFrameObject, + ButtonFrame, + MUIA_InputMode, MUIV_InputMode_None, + MUIA_FixWidth, 12, + MUIA_FixHeight, 12, + MUIA_InnerBottom, 6, + MUIA_InnerLeft, 6, + MUIA_InnerRight, 6, + MUIA_InnerTop, 6, + MUIA_Background, MUII_ButtonBack, + MUIA_MCPFrame_FrameType, MCP_FRAME_BUTTON, + MUIA_Draggable, TRUE, + MUIA_Dropable, FALSE, + End, + Child, McpFrameObject, + ButtonFrame, + MUIA_InputMode, MUIV_InputMode_None, + MUIA_FixWidth, 12, + MUIA_FixHeight, 12, + MUIA_InnerBottom, 6, + MUIA_InnerLeft, 6, + MUIA_InnerRight, 6, + MUIA_InnerTop, 6, + MUIA_Background, MUII_ButtonBack, + MUIA_MCPFrame_FrameType, MCP_FRAME_BORDER, + MUIA_Draggable, TRUE, + MUIA_Dropable, FALSE, + End, + Child, McpFrameObject, + ButtonFrame, + MUIA_InputMode, MUIV_InputMode_None, + MUIA_FixWidth, 12, + MUIA_FixHeight, 12, + MUIA_InnerBottom, 6, + MUIA_InnerLeft, 6, + MUIA_InnerRight, 6, + MUIA_InnerTop, 6, + MUIA_Background, MUII_ButtonBack, + MUIA_MCPFrame_FrameType, MCP_FRAME_STRING, + MUIA_Draggable, TRUE, + MUIA_Dropable, FALSE, + End, + Child, McpFrameObject, + ButtonFrame, + MUIA_InputMode, MUIV_InputMode_None, + MUIA_FixWidth, 12, + MUIA_FixHeight, 12, + MUIA_InnerBottom, 6, + MUIA_InnerLeft, 6, + MUIA_InnerRight, 6, + MUIA_InnerTop, 6, + MUIA_Background, MUII_ButtonBack, + MUIA_MCPFrame_FrameType, MCP_FRAME_DROPBOX, + MUIA_Draggable, TRUE, + MUIA_Dropable, FALSE, + End, + Child, McpFrameObject, + ButtonFrame, + MUIA_InputMode, MUIV_InputMode_None, + MUIA_FixWidth, 12, + MUIA_FixHeight, 12, + MUIA_InnerBottom, 6, + MUIA_InnerLeft, 6, + MUIA_InnerRight, 6, + MUIA_InnerTop, 6, + MUIA_Background, MUII_ButtonBack, + MUIA_MCPFrame_FrameType, MCP_FRAME_XEN, + MUIA_Draggable, TRUE, + MUIA_Dropable, FALSE, + End, + Child, McpFrameObject, + ButtonFrame, + MUIA_InputMode, MUIV_InputMode_None, + MUIA_FixWidth, 12, + MUIA_FixHeight, 12, + MUIA_InnerBottom, 6, + MUIA_InnerLeft, 6, + MUIA_InnerRight, 6, + MUIA_InnerTop, 6, + MUIA_Background, MUII_ButtonBack, + MUIA_MCPFrame_FrameType, MCP_FRAME_MWB, + MUIA_Draggable, TRUE, + MUIA_Dropable, FALSE, + End, + Child, McpFrameObject, + ButtonFrame, + MUIA_InputMode, MUIV_InputMode_None, + MUIA_FixWidth, 12, + MUIA_FixHeight, 12, + MUIA_InnerBottom, 6, + MUIA_InnerLeft, 6, + MUIA_InnerRight, 6, + MUIA_InnerTop, 6, + MUIA_Background, MUII_ButtonBack, + MUIA_MCPFrame_FrameType, MCP_FRAME_THICK, + MUIA_Draggable, TRUE, + MUIA_Dropable, FALSE, + End, + Child, McpFrameObject, + ButtonFrame, + MUIA_InputMode, MUIV_InputMode_None, + MUIA_FixWidth, 12, + MUIA_FixHeight, 12, + MUIA_InnerBottom, 6, + MUIA_InnerLeft, 6, + MUIA_InnerRight, 6, + MUIA_InnerTop, 6, + MUIA_Background, MUII_ButtonBack, + MUIA_MCPFrame_FrameType, MCP_FRAME_XWIN, + MUIA_Draggable, TRUE, + MUIA_Dropable, FALSE, + End, + Child, RectangleObject, + End, + + Child, McpFrameObject, + ButtonFrame, + MUIA_InputMode, MUIV_InputMode_None, + MUIA_FixWidth, 12, + MUIA_FixHeight, 12, + MUIA_InnerBottom, 6, + MUIA_InnerLeft, 6, + MUIA_InnerRight, 6, + MUIA_InnerTop, 6, + MUIA_Background, MUII_ButtonBack, + MUIA_MCPFrame_FrameType, MCP_FRAME_BUTTON | MCP_FRAME_RECESSED, + MUIA_Draggable, TRUE, + MUIA_Dropable, FALSE, + End, + Child, McpFrameObject, + ButtonFrame, + MUIA_InputMode, MUIV_InputMode_None, + MUIA_FixWidth, 12, + MUIA_FixHeight, 12, + MUIA_InnerBottom, 6, + MUIA_InnerLeft, 6, + MUIA_InnerRight, 6, + MUIA_InnerTop, 6, + MUIA_Background, MUII_ButtonBack, + MUIA_MCPFrame_FrameType, MCP_FRAME_BORDER | MCP_FRAME_RECESSED, + MUIA_Draggable, TRUE, + MUIA_Dropable, FALSE, + End, + Child, McpFrameObject, + ButtonFrame, + MUIA_InputMode, MUIV_InputMode_None, + MUIA_FixWidth, 12, + MUIA_FixHeight, 12, + MUIA_InnerBottom, 6, + MUIA_InnerLeft, 6, + MUIA_InnerRight, 6, + MUIA_InnerTop, 6, + MUIA_Background, MUII_ButtonBack, + MUIA_MCPFrame_FrameType, MCP_FRAME_STRING | MCP_FRAME_RECESSED, + MUIA_Draggable, TRUE, + MUIA_Dropable, FALSE, + End, + Child, McpFrameObject, + ButtonFrame, + MUIA_InputMode, MUIV_InputMode_None, + MUIA_FixWidth, 12, + MUIA_FixHeight, 12, + MUIA_InnerBottom, 6, + MUIA_InnerLeft, 6, + MUIA_InnerRight, 6, + MUIA_InnerTop, 6, + MUIA_Background, MUII_ButtonBack, + MUIA_MCPFrame_FrameType, MCP_FRAME_DROPBOX | MCP_FRAME_RECESSED, + MUIA_Draggable, TRUE, + MUIA_Dropable, FALSE, + End, + Child, McpFrameObject, + ButtonFrame, + MUIA_InputMode, MUIV_InputMode_None, + MUIA_FixWidth, 12, + MUIA_FixHeight, 12, + MUIA_InnerBottom, 6, + MUIA_InnerLeft, 6, + MUIA_InnerRight, 6, + MUIA_InnerTop, 6, + MUIA_Background, MUII_ButtonBack, + MUIA_MCPFrame_FrameType, MCP_FRAME_XEN | MCP_FRAME_RECESSED, + MUIA_Draggable, TRUE, + MUIA_Dropable, FALSE, + End, + Child, McpFrameObject, + ButtonFrame, + MUIA_InputMode, MUIV_InputMode_None, + MUIA_FixWidth, 12, + MUIA_FixHeight, 12, + MUIA_InnerBottom, 6, + MUIA_InnerLeft, 6, + MUIA_InnerRight, 6, + MUIA_InnerTop, 6, + MUIA_Background, MUII_ButtonBack, + MUIA_MCPFrame_FrameType, MCP_FRAME_MWB | MCP_FRAME_RECESSED, + MUIA_Draggable, TRUE, + MUIA_Dropable, FALSE, + End, + Child, McpFrameObject, + ButtonFrame, + MUIA_InputMode, MUIV_InputMode_None, + MUIA_FixWidth, 12, + MUIA_FixHeight, 12, + MUIA_InnerBottom, 6, + MUIA_InnerLeft, 6, + MUIA_InnerRight, 6, + MUIA_InnerTop, 6, + MUIA_Background, MUII_ButtonBack, + MUIA_MCPFrame_FrameType, MCP_FRAME_THICK | MCP_FRAME_RECESSED, + MUIA_Draggable, TRUE, + MUIA_Dropable, FALSE, + End, + Child, McpFrameObject, + ButtonFrame, + MUIA_InputMode, MUIV_InputMode_None, + MUIA_FixWidth, 12, + MUIA_FixHeight, 12, + MUIA_InnerBottom, 6, + MUIA_InnerLeft, 6, + MUIA_InnerRight, 6, + MUIA_InnerTop, 6, + MUIA_Background, MUII_ButtonBack, + MUIA_MCPFrame_FrameType, MCP_FRAME_XWIN | MCP_FRAME_RECESSED, + MUIA_Draggable, TRUE, + MUIA_Dropable, FALSE, + End, + + End, //RowGroup + End, //Window + +// ----------------------------------------------------------------------------------------------- + + SubWindow, app->Obj[WINDOW_SPLASH] = WindowObject, + MUIA_Window_AppWindow, FALSE, + MUIA_Window_CloseGadget, FALSE, + MUIA_Window_DepthGadget, FALSE, + MUIA_Window_NoMenus, TRUE, + MUIA_Window_DragBar, FALSE, + MUIA_Window_LeftEdge, MUIV_Window_LeftEdge_Centered, + MUIA_Window_TopEdge, MUIV_Window_TopEdge_Centered, + + WindowContents, VGroup, + Child, app->Obj[TEXT_SPLASHWINDOW] = TextObject, + MUIA_Weight, 0, + MUIA_Text_Contents, (ULONG) GetLocString(MSGID_SPLASHWINDOW_LOADINGPREFS), + End, //TextObject + End, //VGroup + + End, //SubWindow +/// +// ----------------------------------------------------------------------------------------------- + + MUIA_Application_Menustrip, MenustripObject, + Child, MenuObjectT(GetLocString(MSGID_MENU_PROJECT)), + Child, app->Obj[MENU_OPEN] = MenuitemObject, + MUIA_Menuitem_Title, (ULONG) GetLocString(MSGID_MENU_PROJECT_OPEN), + MUIA_Menuitem_Shortcut, (ULONG) GetLocString(MSGID_MENU_PROJECT_OPEN_SHORT), + End, + Child, app->Obj[MENU_SAVE_AS] = MenuitemObject, + MUIA_Menuitem_Title, (ULONG) GetLocString(MSGID_MENU_PROJECT_SAVEAS), + MUIA_Menuitem_Shortcut, (ULONG) GetLocString(MSGID_MENU_PROJECT_SAVEAS_SHORT), + End, + Child, MenuitemObject, + MUIA_Menuitem_Title, -1, + End, + Child, app->Obj[MENU_ABOUT] = MenuitemObject, + MUIA_Menuitem_Title, (ULONG) GetLocString(MSGID_MENU_PROJECT_ABOUT), + End, +#if defined(__MORPHOS__) + Child, app->Obj[MENU_ABOUT_MORPHOS] = MenuitemObject, + MUIA_Menuitem_Title, (ULONG) GetLocString(MSGID_MENU_PROJECT_ABOUTMORPHOS), + MUIA_Menuitem_Enabled, (NULL != app->Obj[WIN_ABOUT_MORPHOS]), + End, +#endif //defined(__MORPHOS__) + Child, app->Obj[MENU_ABOUT_MUI] = MenuitemObject, + MUIA_Menuitem_Title, (ULONG) GetLocString(MSGID_MENU_PROJECT_ABOUTMUI), + End, + Child, MenuitemObject, + MUIA_Menuitem_Title, -1, + End, + Child, app->Obj[MENU_QUIT] = MenuitemObject, + MUIA_Menuitem_Title, (ULONG) GetLocString(MSGID_MENU_PROJECT_QUIT), + MUIA_Menuitem_Shortcut, (ULONG) GetLocString(MSGID_MENU_PROJECT_QUIT_SHORT), + End, + + End,//MenuObjectT + Child, MenuObjectT(GetLocString(MSGID_MENU_EDIT)), + Child, app->Obj[MENU_RESET_TO_DEFAULTS] = MenuitemObject, + MUIA_Menuitem_Title, (ULONG) GetLocString(MSGID_MENU_EDIT_RESETTODEFAULTS), + MUIA_Menuitem_Shortcut, (ULONG) GetLocString(MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT), + End, + Child, app->Obj[MENU_LAST_SAVED] = MenuitemObject, + MUIA_Menuitem_Title, (ULONG) GetLocString(MSGID_MENU_EDIT_LASTSAVED), + MUIA_Menuitem_Shortcut, (ULONG) GetLocString(MSGID_MENU_EDIT_LASTSAVED_SHORT), + End, + Child, app->Obj[MENU_RESTORE] = MenuitemObject, + MUIA_Menuitem_Title, (ULONG) GetLocString(MSGID_MENU_EDIT_RESTORE), + MUIA_Menuitem_Shortcut, (ULONG) GetLocString(MSGID_MENU_EDIT_RESTORE_SHORT), + End, + End,//MenuObjectT + Child, MenuObjectT(GetLocString(MSGID_MENU_SETTINGS)), + Child, app->Obj[MENU_CREATE_ICONS] = MenuitemObject, + MUIA_Menuitem_Title, (ULONG) GetLocString(MSGID_MENU_SETTINGS_CREATEICONS), + MUIA_Menuitem_Shortcut, (ULONG) GetLocString(MSGID_MENU_SETTINGS_CREATEICONS_SHORT), + MUIA_Menuitem_Checkit, TRUE, + MUIA_Menuitem_Checked, fCreateIcons, + End, + End,//MenuObjectT + End,//MenuStrip + +// ----------------------------------------------------------------------------------------------- + + // additional taglist to add plugin subwindows + PluginTagList ? TAG_MORE : TAG_IGNORE, PluginTagList, + +// ----------------------------------------------------------------------------------------------- + + End //Application + ; + + d1(KPrintF(__FILE__ "/%s/%ld: app=%08lx\n", __FUNC__, __LINE__, app->Obj[APPLICATION])); + if (NULL == app->Obj[APPLICATION]) + return FALSE; + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + // add pages for prefs plugins + InsertPrefsPlugins(app, app->Obj[GROUP], app->Obj[LIST]); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + { STRPTR xxx = strdup("TestTestTest"); if (xxx) free(xxx); } + + // open Splash window + if (ShowSplashWindow) + set(app->Obj[WINDOW_SPLASH], MUIA_Window_Open, TRUE); + + if (icon) + DoMethodForAllPrefsPlugins(2, MUIM_ScalosPrefs_ParseToolTypes, icon->do_ToolTypes); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + { STRPTR xxx = strdup("TestTestTest"); if (xxx) free(xxx); } + + DoMethodForAllPrefsPlugins(1, MUIM_ScalosPrefs_LoadConfig); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + { STRPTR xxx = strdup("TestTestTest"); if (xxx) free(xxx); } + + InitControlBarGadgets(app); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + { STRPTR xxx = strdup("TestTestTest"); if (xxx) free(xxx); } + + UpdateGuiFromPrefs(app); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + { STRPTR xxx = strdup("TestTestTest"); if (xxx) free(xxx); } + +#if defined(__MORPHOS__) + set(app->Obj[GROUP2_DEFAULTSTACKSIZE], MUIA_ShowMe, FALSE); + set(app->Obj[GROUP_DEFAULTSTACKSIZE], MUIA_Disabled, FALSE); +#else /* __MORPHOS__ */ + set(app->Obj[GROUP2_DEFAULTSTACKSIZE], MUIA_ShowMe, WorkbenchBase->lib_Version >= 45); + set(app->Obj[GROUP_DEFAULTSTACKSIZE], MUIA_Disabled, WorkbenchBase->lib_Version >= 45); +#endif /* __MORPHOS__ */ + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + { STRPTR xxx = strdup("TestTestTest"); if (xxx) free(xxx); } + + EnableIconFontPrefs(app); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + { STRPTR xxx = strdup("TestTestTest"); if (xxx) free(xxx); } + + DoMethod(app->Obj[GROUP], MUIM_Notify, MUIA_Group_ActivePage, MUIV_EveryTime, + app->Obj[GROUP], 2, MUIM_CallHook, &PageChangeHook); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + { STRPTR xxx = strdup("TestTestTest"); if (xxx) free(xxx); } + + // --- Startup Page + DoMethod(app->Obj[CHECK_SHOWSPLASH], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + app->Obj[SLIDER_SPLASHCLOSE], 3, MUIM_Set, MUIA_Disabled, MUIV_NotTriggerValue); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + { STRPTR xxx = strdup("TestTestTest"); if (xxx) free(xxx); } + + // --- Desktop Page + DoMethod(app->Obj[CHECK_TITLEMEM], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + app->Obj[SLIDER_TITLEREFRESH], 3, MUIM_Set, MUIA_Disabled, MUIV_TriggerValue); + DoMethod(app->Obj[CHECK_WINTITLEMEM], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + app->Obj[SLIDER_WINTITLEREFRESH], 3, MUIM_Set, MUIA_Disabled, MUIV_TriggerValue); + DoMethod(app->Obj[NLIST_HIDDENDEVICES], MUIM_Notify, MUIA_NList_ButtonClick, MUIV_EveryTime, + app->Obj[WINDOW_MAIN], 2, MUIM_CallHook, &DesktopHiddenDevicesHook); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + { STRPTR xxx = strdup("TestTestTest"); if (xxx) free(xxx); } + + // --- Icons Page + + // Disable BorderX/BorderY/Radius sliders when CHECK_SEL_ICONTEXT_RECTANGLE is deselected + DoMethod(app->Obj[CHECK_SEL_ICONTEXT_RECTANGLE], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + app->Obj[SLIDER_SEL_ICONTEXT_RECT_BORDERX], 3, MUIM_Set, MUIA_Disabled, MUIV_NotTriggerValue); + DoMethod(app->Obj[CHECK_SEL_ICONTEXT_RECTANGLE], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + app->Obj[SLIDER_SEL_ICONTEXT_RECT_BORDERY], 3, MUIM_Set, MUIA_Disabled, MUIV_NotTriggerValue); + DoMethod(app->Obj[CHECK_SEL_ICONTEXT_RECTANGLE], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + app->Obj[SLIDER_SEL_ICONTEXT_RECT_RADIUS], 3, MUIM_Set, MUIA_Disabled, MUIV_NotTriggerValue); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + { STRPTR xxx = strdup("TestTestTest"); if (xxx) free(xxx); } + + // Click icon frame gadget opens frame selection window + DoMethod(app->Obj[FRAME_ICONNORMAL], MUIM_Notify,MUIA_Pressed, FALSE, + app->Obj[WINDOW_ICONFRAMES], 3, MUIM_Set, MUIA_Window_Open, TRUE); + DoMethod(app->Obj[FRAME_ICONSELECTED], MUIM_Notify,MUIA_Pressed, FALSE, + app->Obj[WINDOW_ICONFRAMES], 3, MUIM_Set, MUIA_Window_Open, TRUE); + DoMethod(app->Obj[FRAME_ICON_THUMBNAIL_NORMAL], MUIM_Notify,MUIA_Pressed, FALSE, + app->Obj[WINDOW_ICONFRAMES], 3, MUIM_Set, MUIA_Window_Open, TRUE); + DoMethod(app->Obj[FRAME_ICON_THUMBNAIL_SELECTED], MUIM_Notify,MUIA_Pressed, FALSE, + app->Obj[WINDOW_ICONFRAMES], 3, MUIM_Set, MUIA_Window_Open, TRUE); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + { STRPTR xxx = strdup("TestTestTest"); if (xxx) free(xxx); } + + // Disable thumbnail background transparency slider if thumbnail background is not filled + DoMethod(app->Obj[CHECK_THUMBNAILS_BACKFILL], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + app->Obj[GROUP_THUMBNAIL_BACKFILL_TRANSPARENCY], 3, MUIM_Set, MUIA_Disabled, MUIV_NotTriggerValue); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + { STRPTR xxx = strdup("TestTestTest"); if (xxx) free(xxx); } + + // dropping a new icon frame updates icon borders top/left/right/bottom + DoMethod(app->Obj[FRAME_ICONNORMAL], MUIM_Notify, MUIA_MCPFrame_FrameType, MUIV_EveryTime, + app->Obj[WINDOW_ICONFRAMES], 2, MUIM_CallHook, &IconFrame_NewBorder_Hook); + DoMethod(app->Obj[FRAME_ICONSELECTED], MUIM_Notify, MUIA_MCPFrame_FrameType, MUIV_EveryTime, + app->Obj[WINDOW_ICONFRAMES], 2, MUIM_CallHook, &IconFrame_NewBorder_Hook); + + // dropping a new thumbnail frame updates thumbnail borders top/left/right/bottom + DoMethod(app->Obj[FRAME_ICON_THUMBNAIL_NORMAL], MUIM_Notify, MUIA_MCPFrame_FrameType, MUIV_EveryTime, + app->Obj[WINDOW_ICONFRAMES], 2, MUIM_CallHook, &ThumbnailFrame_NewBorder_Hook); + DoMethod(app->Obj[FRAME_ICON_THUMBNAIL_SELECTED], MUIM_Notify, MUIA_MCPFrame_FrameType, MUIV_EveryTime, + app->Obj[WINDOW_ICONFRAMES], 2, MUIM_CallHook, &ThumbnailFrame_NewBorder_Hook); + + DoMethod(app->Obj[SOFTICONSLINK], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + app->Obj[SOFTTEXTSLINK], 3, MUIM_Set, MUIA_Selected, MUIV_TriggerValue); + DoMethod(app->Obj[SOFTTEXTSLINK], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + app->Obj[SOFTICONSLINK], 3, MUIM_Set, MUIA_Selected, MUIV_TriggerValue); + + DoMethod(app->Obj[CHECK_TOOLTIPS], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + app->Obj[TOOLTIP_SETTINGSGROUP], 3, MUIM_Set, MUIA_Disabled, MUIV_NotTriggerValue); + DoMethod(app->Obj[POP_FONTPREFS], MUIM_Notify, MUIA_Selected, FALSE, + app->Obj[WINDOW_MAIN], 2, MUIM_CallHook, &Pop_FontPrefs_Hook); + + DoMethod(app->Obj[CYCLE_ROUTINE], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, + app->Obj[WINDOW_MAIN], 2, MUIM_CallHook, &IconsSelectBobRoutineHook); + + DoMethod(app->Obj[CYCLE_ICONMINSIZE], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, + app->Obj[WINDOW_MAIN], 2, MUIM_CallHook, &IconsMinSizeHook); + DoMethod(app->Obj[CYCLE_ICONMAXSIZE], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, + app->Obj[WINDOW_MAIN], 2, MUIM_CallHook, &IconsMaxSizeHook); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + { STRPTR xxx = strdup("TestTestTest"); if (xxx) free(xxx); } + + // Selecting a new font updates font sample + DoMethod(app->Obj[POP_ICONFONT], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + app->Obj[MCC_ICONFONT_SAMPLE], 3, MUIM_Set, MUIA_FontSample_StdFontDesc, MUIV_TriggerValue); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + { STRPTR xxx = strdup("TestTestTest"); if (xxx) free(xxx); } + + // --- TrueType fonts page + // disable icon font selection if icon TT font enabled + DoMethod(app->Obj[CHECK_TTICONFONT_ENABLE], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + app->Obj[GROUP_ICONSPAGE_ICONFONT], 3, MUIM_Set, MUIA_Disabled, MUIV_TriggerValue); + // update TT icon font enable buttons + DoMethod(app->Obj[CHECK_ICONSPAGE_TTICONFONT_ENABLE], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + app->Obj[CHECK_TTICONFONT_ENABLE], 3, MUIM_Set, MUIA_Selected, MUIV_TriggerValue); + DoMethod(app->Obj[CHECK_TTICONFONT_ENABLE], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + app->Obj[CHECK_ICONSPAGE_TTICONFONT_ENABLE], 3, MUIM_Set, MUIA_Selected, MUIV_TriggerValue); + DoMethod(app->Obj[CHECK_TTICONFONT_ENABLE], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + app->Obj[GROUP_ICONSPAGE_TTICONFONT], 3, MUIM_Set, MUIA_Disabled, MUIV_NotTriggerValue); + // disable text window font selection if text window TT font enabled + DoMethod(app->Obj[CHECK_TTTEXTWINDOWFONT_ENABLE], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + app->Obj[GROUP_TEXTWINDOW_FONT_SELECT], 3, MUIM_Set, MUIA_Disabled, MUIV_TriggerValue); + DoMethod(app->Obj[CHECK_TTTEXTWINDOWFONT_ENABLE], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + app->Obj[GROUP_TEXTWINDOW_FONT_SELECT], 3, MUIM_Set, MUIA_Disabled, MUIV_TriggerValue); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + { STRPTR xxx = strdup("TestTestTest"); if (xxx) free(xxx); } + + // --- DragnDrop Page + DoMethod(app->Obj[CYCLE_TRANSPMODE], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, + app->Obj[WINDOW_MAIN], 2, MUIM_CallHook, &IconDragTransparencyHook); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + { STRPTR xxx = strdup("TestTestTest"); if (xxx) free(xxx); } + + // --- TextWindows Page + // Selecting a new font updates font sample + DoMethod(app->Obj[POP_TEXTMODEFONT], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + app->Obj[STRING_TEXTMODEFONT_SAMPLE], 3, MUIM_Set, MUIA_FontSample_StdFontDesc, MUIV_TriggerValue); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + { STRPTR xxx = strdup("TestTestTest"); if (xxx) free(xxx); } + + // --- Miscellaneous page + DoMethod(app->Obj[POP_WORKBENCHPREFS], MUIM_Notify, MUIA_Selected, FALSE, + app->Obj[WINDOW_MAIN], 2, MUIM_CallHook, &Pop_WorkbenchPrefs_Hook); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + { STRPTR xxx = strdup("TestTestTest"); if (xxx) free(xxx); } + + // --- Modules Page + DoMethod(app->Obj[NLIST_MODULES], MUIM_Notify, MUIA_NList_ButtonClick, MUIV_EveryTime, + app->Obj[WINDOW_MAIN], 2, MUIM_CallHook, &ModulesPrefsPopupHook); + DoMethod(app->Obj[NLIST_MODULES], MUIM_NList_Insert, cModulePrefs, -1, MUIV_NList_Insert_Bottom); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + { STRPTR xxx = strdup("TestTestTest"); if (xxx) free(xxx); } + + // --- Plugins Page + DoMethod(app->Obj[PLUGIN_LIST], MUIM_Notify, MUIA_NList_Active, MUIV_EveryTime, + MUIV_Notify_Window, 2, MUIM_CallHook, &PluginListActiveHook); + // call hook if "add plugin" button is clicked + DoMethod(app->Obj[ADD_PLUGIN], MUIM_Notify, MUIA_Selected, FALSE, + app->Obj[PLUGIN_LIST], 2, MUIM_CallHook, &Add_Plugin_Hook); + // call hook if "remove plugin" button is clicked + DoMethod(app->Obj[REMOVE_PLUGIN], MUIM_Notify, MUIA_Pressed, FALSE, + app->Obj[PLUGIN_LIST], 2, MUIM_CallHook, &RemovePluginHook); + /* Call the AppMsgHook when an icon is dropped on plugin listview */ + DoMethod(app->Obj[PLUGIN_LISTVIEW], MUIM_Notify, MUIA_AppMessage, MUIV_EveryTime, + app->Obj[PLUGIN_LISTVIEW], 3, MUIM_CallHook, &PluginListAppMsgHook, MUIV_TriggerValue); + // setup sorting hooks for plugin list + DoMethod(app->Obj[PLUGIN_LIST], MUIM_Notify, MUIA_NList_TitleClick, MUIV_EveryTime, + app->Obj[PLUGIN_LIST], 4, MUIM_NList_Sort3, MUIV_TriggerValue, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_Both); + DoMethod(app->Obj[PLUGIN_LIST], MUIM_Notify, MUIA_NList_TitleClick2, MUIV_EveryTime, + app->Obj[PLUGIN_LIST], 4, MUIM_NList_Sort3, MUIV_TriggerValue, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_2); + DoMethod(app->Obj[PLUGIN_LIST], MUIM_Notify, MUIA_NList_SortType, MUIV_EveryTime, + app->Obj[PLUGIN_LIST], 3, MUIM_Set, MUIA_NList_TitleMark, MUIV_TriggerValue); + DoMethod(app->Obj[PLUGIN_LIST], MUIM_Notify, MUIA_NList_SortType2, MUIV_EveryTime, + app->Obj[PLUGIN_LIST], 3, MUIM_Set, MUIA_NList_TitleMark2, MUIV_TriggerValue); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + // --- General Prefs GUI + DoMethod(app->Obj[WINDOW_MAIN], MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + MUIV_Notify_Application, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + DoMethod(app->Obj[LIST], MUIM_Notify, MUIA_List_Active, MUIV_EveryTime, + app->Obj[GROUP], 3, MUIM_Set, MUIA_Group_ActivePage, MUIV_TriggerValue); + DoMethod(app->Obj[CANCEL], MUIM_Notify, MUIA_Pressed, FALSE, + MUIV_Notify_Application, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + DoMethod(app->Obj[SAVE], MUIM_Notify, MUIA_Pressed, FALSE, + MUIV_Notify_Application, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_SAVE); + DoMethod(app->Obj[USE], MUIM_Notify, MUIA_Pressed, FALSE, + MUIV_Notify_Application, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_USE); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + // --- List Maintainance + DoMethod(app->Obj[STORAGE_TIPS], MUIM_NList_Insert, cIconToolTips, -1, MUIV_NList_Insert_Bottom); + + SetAttrs(app->Obj[LIST], MUIA_NList_Active, MUIV_NList_Active_Top, TAG_DONE); + + // set allowed drag/drop partners for text window columns + SetAttrs(app->Obj[NLIST_STORAGE_FILEDISPLAY], MUIA_UserData, (ULONG) app->Obj[NLIST_USE_FILEDISPLAY], TAG_DONE); + SetAttrs(app->Obj[NLIST_USE_FILEDISPLAY], MUIA_UserData, (ULONG) app->Obj[NLIST_STORAGE_FILEDISPLAY], TAG_DONE); + + // set allowed drag/drop partners for control bar gadgets + SetAttrs(app->Obj[NLIST_CONTROLBARGADGETS_BROWSER_AVAILABLE], MUIA_UserData, (ULONG) app->Obj[NLIST_CONTROLBARGADGETS_BROWSER_ACTIVE], TAG_DONE); + SetAttrs(app->Obj[NLIST_CONTROLBARGADGETS_BROWSER_ACTIVE], MUIA_UserData, (ULONG) app->Obj[NLIST_CONTROLBARGADGETS_BROWSER_AVAILABLE], TAG_DONE); + + // set allowed drag/drop partners for control bar gadgets + SetAttrs(app->Obj[NLIST_CONTROLBARGADGETS_NORMAL_AVAILABLE], MUIA_UserData, (ULONG) app->Obj[NLIST_CONTROLBARGADGETS_NORMAL_ACTIVE], TAG_DONE); + SetAttrs(app->Obj[NLIST_CONTROLBARGADGETS_NORMAL_ACTIVE], MUIA_UserData, (ULONG) app->Obj[NLIST_CONTROLBARGADGETS_NORMAL_AVAILABLE], TAG_DONE); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + // call hook if an active Control bar gadget is selected + DoMethod(app->Obj[NLIST_CONTROLBARGADGETS_BROWSER_ACTIVE], MUIM_Notify, MUIA_NList_Active, MUIV_EveryTime, + app->Obj[NLIST_CONTROLBARGADGETS_BROWSER_ACTIVE], 2, MUIM_CallHook, &ControlBarGadgetListBrowserActiveHook); + + // call hook if an active Control bar gadget is selected + DoMethod(app->Obj[NLIST_CONTROLBARGADGETS_NORMAL_ACTIVE], MUIM_Notify, MUIA_NList_Active, MUIV_EveryTime, + app->Obj[NLIST_CONTROLBARGADGETS_NORMAL_ACTIVE], 2, MUIM_CallHook, &ControlBarGadgetListNormalActiveHook); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + // Now disable several controls that are only allowed for screen depth > 8 + if ((NULL == CyberGfxBase) || (WBScreenDepth <= 8)) + { + SetAttrs(app->Obj[CHECK_STRIPED_WINDOW], + MUIA_Disabled, TRUE, + MUIA_Selected, FALSE, + TAG_END); + SetAttrs(app->Obj[SLIDER_ICONTRANSPARENCY_DRAG], + MUIA_Disabled, TRUE, + MUIA_Numeric_Value, 100, + TAG_END); + SetAttrs(app->Obj[SLIDER_ICONTRANSPARENCY_SHADOW], + MUIA_Disabled, TRUE, + MUIA_Numeric_Value, 100, + TAG_END); + SetAttrs(app->Obj[SLIDER_ICONTRANSPARENCY_DEFICONS], + MUIA_Disabled, TRUE, + MUIA_Numeric_Value, 100, + TAG_END); + SetAttrs(app->Obj[SLIDER_ICONTOOLTIPS_TRANSPARENCY], + MUIA_Disabled, TRUE, + MUIA_Numeric_Value, 100, + TAG_END); + SetAttrs(app->Obj[CYCLE_ROUTINE], + MUIA_Disabled, TRUE, + MUIA_Cycle_Active, TRANSPTYPE_Ghosted, + TAG_END); + SetAttrs(app->Obj[SLIDER_ICONTRANSPARENCY_THUMBNAILBACK], + MUIA_Disabled, TRUE, + MUIA_Cycle_Active, TRANSPTYPE_Ghosted, + TAG_END); + } + + if ((NULL == CyberGfxBase) || (WBScreenDepth <= 8) || (NULL == ScalosGfxBase)) + { + set(app->Obj[GROUP_TEXTWINDOWS_SELECTIONMARK], MUIA_Disabled, TRUE); + } + + // Enable TrueType controls if ttengine.library is available + if (TTEngineBase) + { + SetAttrs(app->Obj[GROUP_TTGLOBALS], + MUIA_Disabled, FALSE, + TAG_END); + SetAttrs(app->Obj[GROUP_TTSCREENFONT], + MUIA_Disabled, FALSE, + TAG_END); + SetAttrs(app->Obj[GROUP_TTICONFONT], + MUIA_Disabled, FALSE, + TAG_END); + SetAttrs(app->Obj[GROUP_ICONSPAGE_TTICONFONT], + MUIA_Disabled, FALSE, + TAG_END); + SetAttrs(app->Obj[GROUP_TTTEXTWINDOWFONT], + MUIA_Disabled, FALSE, + TAG_END); + SetAttrs(app->Obj[GROUP_TEXTWINDOW_TTTEXTWINDOWFONT], + MUIA_Disabled, FALSE, + TAG_END); + } + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + // After icon font change, recalculate maximum radius for selected icon text rectangle + DoMethod(app->Obj[SLIDER_SEL_ICONTEXT_RECT_BORDERY], MUIM_Notify, MUIA_Numeric_Value, MUIV_EveryTime, + app->Obj[GROUP], 2, MUIM_CallHook, &CalculateMaxRadiusHook); + DoMethod(app->Obj[CHECK_ICONSPAGE_TTICONFONT_ENABLE], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + app->Obj[GROUP], 2, MUIM_CallHook, &CalculateMaxRadiusHook); + DoMethod(app->Obj[CHECK_TTICONFONT_ENABLE], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + app->Obj[GROUP], 2, MUIM_CallHook, &CalculateMaxRadiusHook); + DoMethod(app->Obj[POP_ICONFONT], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + app->Obj[GROUP], 2, MUIM_CallHook, &CalculateMaxRadiusHook); + DoMethod(app->Obj[POPSTRING_TTICONFONT], MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, + app->Obj[GROUP], 2, MUIM_CallHook, &CalculateMaxRadiusHook); + DoMethod(app->Obj[POPSTRING_ICONSPAGE_TTICONFONT], MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, + app->Obj[GROUP], 2, MUIM_CallHook, &CalculateMaxRadiusHook); + + DoMethod(app->Obj[POPSTRING_TTSCREENFONT], MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, + app->Obj[MCC_TTSCREENFONT_SAMPLE], 3, MUIM_Set, MUIA_FontSample_TTFontDesc, MUIV_TriggerValue); + // update TT icon font samples + DoMethod(app->Obj[POPSTRING_TTICONFONT], MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, + app->Obj[MCC_TTICONFONT_SAMPLE], 3, MUIM_Set, MUIA_FontSample_TTFontDesc, MUIV_TriggerValue); + DoMethod(app->Obj[POPSTRING_TTICONFONT], MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, + app->Obj[MCC_ICONSPAGE_TTICONFONT_SAMPLE], 3, MUIM_Set, MUIA_FontSample_TTFontDesc, MUIV_TriggerValue); + + DoMethod(app->Obj[POPSTRING_ICONSPAGE_TTICONFONT], MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, + app->Obj[MCC_TTICONFONT_SAMPLE], 3, MUIM_Set, MUIA_FontSample_TTFontDesc, MUIV_TriggerValue); + DoMethod(app->Obj[POPSTRING_ICONSPAGE_TTICONFONT], MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, + app->Obj[MCC_ICONSPAGE_TTICONFONT_SAMPLE], 3, MUIM_Set, MUIA_FontSample_TTFontDesc, MUIV_TriggerValue); + + DoMethod(app->Obj[POPSTRING_ICONSPAGE_TTICONFONT], MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, + app->Obj[POPSTRING_TTICONFONT], 3, MUIM_Set, MUIA_String_Contents, MUIV_TriggerValue); + DoMethod(app->Obj[POPSTRING_TTICONFONT], MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, + app->Obj[POPSTRING_ICONSPAGE_TTICONFONT], 3, MUIM_Set, MUIA_String_Contents, MUIV_TriggerValue); + + DoMethod(app->Obj[POPSTRING_TTTEXTWINDOWFONT], MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, + app->Obj[MCC_TTTEXTWINDOWFONT_SAMPLE], 3, MUIM_Set, MUIA_FontSample_TTFontDesc, MUIV_TriggerValue); + DoMethod(app->Obj[POPSTRING_TTTEXTWINDOWFONT], MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, + app->Obj[MCC_TEXTWINDOW_TTTEXTWINDOWFONT_SAMPLE], 3, MUIM_Set, MUIA_FontSample_TTFontDesc, MUIV_TriggerValue); + + DoMethod(app->Obj[POPSTRING_TEXTWINDOW_TTTEXTWINDOWFONT], MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, + app->Obj[POPSTRING_TTTEXTWINDOWFONT], 3, MUIM_Set, MUIA_String_Contents, MUIV_TriggerValue); + DoMethod(app->Obj[POPSTRING_TTTEXTWINDOWFONT], MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, + app->Obj[POPSTRING_TEXTWINDOW_TTTEXTWINDOWFONT], 3, MUIM_Set, MUIA_String_Contents, MUIV_TriggerValue); + + // update TT icon font enable buttons + DoMethod(app->Obj[CHECK_TEXTWINDOW_TTTEXTWINDOWFONT_ENABLE], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + app->Obj[CHECK_TTTEXTWINDOWFONT_ENABLE], 3, MUIM_Set, MUIA_Selected, MUIV_TriggerValue); + DoMethod(app->Obj[CHECK_TTTEXTWINDOWFONT_ENABLE], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + app->Obj[CHECK_TEXTWINDOW_TTTEXTWINDOWFONT_ENABLE], 3, MUIM_Set, MUIA_Selected, MUIV_TriggerValue); + DoMethod(app->Obj[CHECK_TTTEXTWINDOWFONT_ENABLE], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + app->Obj[GROUP_TEXTWINDOW_TTTEXTWINDOWFONT], 3, MUIM_Set, MUIA_Disabled, MUIV_NotTriggerValue); + // disable text window font selection if text window TT font enabled + DoMethod(app->Obj[CHECK_TTTEXTWINDOWFONT_ENABLE], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + app->Obj[GROUP_TEXTWINDOW_FONT_SELECT], 3, MUIM_Set, MUIA_Disabled, MUIV_TriggerValue); + + // Update font samples if antialias is changed + DoMethod(app->Obj[CYCLE_TTANTIALIAS], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, + app->Obj[MCC_TTSCREENFONT_SAMPLE], 3, MUIM_Set, MUIA_FontSample_Antialias, MUIV_TriggerValue); + DoMethod(app->Obj[CYCLE_TTANTIALIAS], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, + app->Obj[MCC_TTICONFONT_SAMPLE], 3, MUIM_Set, MUIA_FontSample_Antialias, MUIV_TriggerValue); + DoMethod(app->Obj[CYCLE_TTANTIALIAS], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, + app->Obj[MCC_ICONSPAGE_TTICONFONT_SAMPLE], 3, MUIM_Set, MUIA_FontSample_Antialias, MUIV_TriggerValue); + DoMethod(app->Obj[CYCLE_TTANTIALIAS], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, + app->Obj[MCC_TTTEXTWINDOWFONT_SAMPLE], 3, MUIM_Set, MUIA_FontSample_Antialias, MUIV_TriggerValue); + DoMethod(app->Obj[CYCLE_TTANTIALIAS], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, + app->Obj[MCC_TEXTWINDOW_TTTEXTWINDOWFONT_SAMPLE], 3, MUIM_Set, MUIA_FontSample_Antialias, MUIV_TriggerValue); + + // Update font samples if gamma is changed + DoMethod(app->Obj[SLIDER_TTGAMMA], MUIM_Notify, MUIA_Numeric_Value, MUIV_EveryTime, + app->Obj[MCC_TTSCREENFONT_SAMPLE], 3, MUIM_Set, MUIA_FontSample_Gamma, MUIV_TriggerValue); + DoMethod(app->Obj[SLIDER_TTGAMMA], MUIM_Notify, MUIA_Numeric_Value, MUIV_EveryTime, + app->Obj[MCC_TTICONFONT_SAMPLE], 3, MUIM_Set, MUIA_FontSample_Gamma, MUIV_TriggerValue); + DoMethod(app->Obj[SLIDER_TTGAMMA], MUIM_Notify, MUIA_Numeric_Value, MUIV_EveryTime, + app->Obj[MCC_ICONSPAGE_TTICONFONT_SAMPLE], 3, MUIM_Set, MUIA_FontSample_Gamma, MUIV_TriggerValue); + DoMethod(app->Obj[SLIDER_TTGAMMA], MUIM_Notify, MUIA_Numeric_Value, MUIV_EveryTime, + app->Obj[MCC_TTTEXTWINDOWFONT_SAMPLE], 3, MUIM_Set, MUIA_FontSample_Gamma, MUIV_TriggerValue); + DoMethod(app->Obj[SLIDER_TTGAMMA], MUIM_Notify, MUIA_Numeric_Value, MUIV_EveryTime, + app->Obj[MCC_TEXTWINDOW_TTTEXTWINDOWFONT_SAMPLE], 3, MUIM_Set, MUIA_FontSample_Gamma, MUIV_TriggerValue); + + // Disable POPUP_SELECTED_HOTKEY if CHECK_MISCPAGE_POPUP_SELECTED_ALWAYS is enabled + DoMethod(app->Obj[CHECK_MISCPAGE_POPUP_SELECTED_ALWAYS], MUIM_Notify, MUIA_Selected, MUIV_EveryTime, + app->Obj[POPUP_SELECTED_HOTKEY], 3, MUIM_Set, MUIA_Disabled, MUIV_TriggerValue); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + // sort Action Button command list + DoMethod(app->Obj[NLISTVIEW_CONTROLBARGADGETS_BROWSER_ACTION], MUIM_NList_Sort); + + // use selected action command on double click into listview + DoMethod(app->Obj[NLISTVIEW_CONTROLBARGADGETS_BROWSER_ACTION], MUIM_Notify, MUIA_Listview_DoubleClick, TRUE, + app->Obj[NLISTVIEW_CONTROLBARGADGETS_BROWSER_ACTION], 2, MUIM_CallHook, &BrowserCmdSelectedHook); + + // use selected action command on double click into listview + DoMethod(app->Obj[NLISTVIEW_CONTROLBARGADGETS_NORMAL_ACTION], MUIM_Notify, MUIA_Listview_DoubleClick, TRUE, + app->Obj[NLISTVIEW_CONTROLBARGADGETS_NORMAL_ACTION], 2, MUIM_CallHook, &NormalCmdSelectedHook); + + // call ControlBarGadgetBrowserChangedHook to update the attributes of the selected control bar Gadget + // everytime any of the strings below is modified + DoMethod(app->Obj[STRING_CONTROLBARGADGETS_BROWSER_NORMALIMAGE], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + app->Obj[STRING_CONTROLBARGADGETS_BROWSER_NORMALIMAGE], 2, MUIM_CallHook, &ControlBarGadgetBrowserChangedHook); + DoMethod(app->Obj[STRING_CONTROLBARGADGETS_BROWSER_SELECTEDIMAGE], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + app->Obj[STRING_CONTROLBARGADGETS_BROWSER_SELECTEDIMAGE], 2, MUIM_CallHook, &ControlBarGadgetBrowserChangedHook); + DoMethod(app->Obj[STRING_CONTROLBARGADGETS_BROWSER_DISABLEDIMAGE], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + app->Obj[STRING_CONTROLBARGADGETS_BROWSER_DISABLEDIMAGE], 2, MUIM_CallHook, &ControlBarGadgetBrowserChangedHook); + DoMethod(app->Obj[STRING_CONTROLBARGADGETS_BROWSER_ACTION], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + app->Obj[STRING_CONTROLBARGADGETS_BROWSER_ACTION], 2, MUIM_CallHook, &ControlBarGadgetBrowserChangedHook); + DoMethod(app->Obj[TEXTEDITOR_CONTROLBARGADGETS_BROWSER_HELPTEXT], MUIM_Notify, MUIA_TextEditor_HasChanged, TRUE, + app->Obj[TEXTEDITOR_CONTROLBARGADGETS_BROWSER_HELPTEXT], 2, MUIM_CallHook, &ControlBarGadgetBrowserChangedHook); + + // call ControlBarGadgetNormalChangedHook to update the attributes of the selected control bar Gadget + // everytime any of the strings below is modified + DoMethod(app->Obj[STRING_CONTROLBARGADGETS_NORMAL_NORMALIMAGE], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + app->Obj[STRING_CONTROLBARGADGETS_NORMAL_NORMALIMAGE], 2, MUIM_CallHook, &ControlBarGadgetNormalChangedHook); + DoMethod(app->Obj[STRING_CONTROLBARGADGETS_NORMAL_SELECTEDIMAGE], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + app->Obj[STRING_CONTROLBARGADGETS_NORMAL_SELECTEDIMAGE], 2, MUIM_CallHook, &ControlBarGadgetNormalChangedHook); + DoMethod(app->Obj[STRING_CONTROLBARGADGETS_NORMAL_DISABLEDIMAGE], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + app->Obj[STRING_CONTROLBARGADGETS_NORMAL_DISABLEDIMAGE], 2, MUIM_CallHook, &ControlBarGadgetNormalChangedHook); + DoMethod(app->Obj[STRING_CONTROLBARGADGETS_NORMAL_ACTION], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, + app->Obj[STRING_CONTROLBARGADGETS_NORMAL_ACTION], 2, MUIM_CallHook, &ControlBarGadgetNormalChangedHook); + DoMethod(app->Obj[TEXTEDITOR_CONTROLBARGADGETS_NORMAL_HELPTEXT], MUIM_Notify, MUIA_TextEditor_HasChanged, TRUE, + app->Obj[TEXTEDITOR_CONTROLBARGADGETS_NORMAL_HELPTEXT], 2, MUIM_CallHook, &ControlBarGadgetNormalChangedHook); + + // Update sample icon whenever thumbnail size is changed + DoMethod(app->Obj[CYCLE_THUMBNAILSIZE], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, + app->Obj[CYCLE_THUMBNAILSIZE], 2, MUIM_CallHook, &ChangeThumbnailSizeHook); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + // Menu + DoMethod(app->Obj[MENU_QUIT], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + MUIV_Notify_Application, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + DoMethod(app->Obj[MENU_OPEN], MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime, + MUIV_Notify_Application, 2, MUIM_CallHook, &OpenHook); + + DoMethod(app->Obj[MENU_SAVE_AS], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + MUIV_Notify_Application, 2, MUIM_CallHook, &SaveAsHook); + + DoMethod(app->Obj[MENU_LAST_SAVED], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + MUIV_Notify_Application, 2, MUIM_CallHook, &LastSavedHook); + + DoMethod(app->Obj[MENU_RESET_TO_DEFAULTS], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + MUIV_Notify_Application, 2, MUIM_CallHook, &ResetToDefaultsHook); + + DoMethod(app->Obj[MENU_RESTORE], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + MUIV_Notify_Application, 2, MUIM_CallHook, &RestoreHook); + + DoMethod(app->Obj[MENU_ABOUT], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + MUIV_Notify_Application, 2, MUIM_CallHook, &AboutHook); + +#if defined(__MORPHOS__) + if (app->Obj[WIN_ABOUT_MORPHOS]) + { + DoMethod(app->Obj[MENU_ABOUT_MORPHOS], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + MUIV_Notify_Application, 2, MUIM_CallHook, &AboutMorphosHook); + + DoMethod(app->Obj[WIN_ABOUT_MORPHOS], MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + app->Obj[WIN_ABOUT_MORPHOS], 2, MUIA_Window_Open, FALSE); + } +#endif //defined(__MORPHOS__) + + DoMethod(app->Obj[MENU_ABOUT_MUI], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + MUIV_Notify_Application, 2, MUIM_CallHook, &AboutMUIHook); + + DoMethod(app->Obj[MENU_CREATE_ICONS], MUIM_Notify, MUIA_Menuitem_Checked, MUIV_EveryTime, + MUIV_Notify_Application, 2, MUIM_CallHook, &CreateIconsHook); + + //Icon border selection window + DoMethod(app->Obj[WINDOW_ICONFRAMES], MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + app->Obj[WINDOW_ICONFRAMES], 3, MUIM_Set, MUIA_Window_Open, FALSE); + + // Update select marker sample + DoMethod(app->Obj[SLIDER_TEXTWINDOWS_SELECTFILLTRANSPARENCY], MUIM_Notify, MUIA_Numeric_Value, MUIV_EveryTime, + app->Obj[MCC_TEXTWINDOWS_SELECTMARKER_SAMPLE], 3, MUIM_Set, TIHA_Transparency, MUIV_TriggerValue); + DoMethod(app->Obj[SLIDER_TEXTWINDOWS_SELECTBORDERTRANSPARENCY], MUIM_Notify, MUIA_Numeric_Value, MUIV_EveryTime, + MUIV_Notify_Application, 2, MUIM_CallHook, &UpdateSelectMarkerSampleHook); + DoMethod(app->Obj[COLORADJUST_TEXTWINDOWS_SELECTIONMARK], MUIM_Notify, MUIA_Coloradjust_RGB, MUIV_EveryTime, + MUIV_Notify_Application, 2, MUIM_CallHook, &UpdateSelectMarkerSampleHook); + + // Set notifications for HotkeyStrings + SetHotkeyNotifications(app->Obj[SINGLE_WINDOW_LASSO_HOTKEY], app->Obj[SINGLE_WINDOW_LASSO_HOTKEY_SCAN]); + SetHotkeyNotifications(app->Obj[POPUP_SELECTED_HOTKEY], app->Obj[POPUP_SELECTED_HOTKEY_SCAN]); + SetHotkeyNotifications(app->Obj[COPY_HOTKEY], app->Obj[COPY_HOTKEY_SCAN]); + SetHotkeyNotifications(app->Obj[MAKELINK_HOTKEY], app->Obj[MAKELINK_HOTKEY_SCAN]); + SetHotkeyNotifications(app->Obj[MOVE_HOTKEY], app->Obj[MOVE_HOTKEY_SCAN]); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + if (MUIV_Application_ReturnID_EDIT == Action) + { + // open main window + SetAttrs(app->Obj[WINDOW_MAIN], + MUIA_Window_DefaultObject, (ULONG) app->Obj[LISTVIEW], + MUIA_Window_Open, TRUE, + TAG_DONE); + + if (!getv(app->Obj[WINDOW_MAIN], MUIA_Window_Open)) + { + set(app->Obj[WINDOW_SPLASH], MUIA_Window_Open, FALSE); + return FALSE; + } + } + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + // close Splash window + set(app->Obj[WINDOW_SPLASH], MUIA_Window_Open, FALSE); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + +#if 0 + { + struct List *ChildList = NULL; + + GetAttr(MUIA_Group_ChildList, app->Obj[GROUP], (ULONG *) &ChildList); + if (ChildList) + { + Object *obj = (Object *) ChildList->lh_Head; + Object *child; + + while ((child = NextObject(&obj))) + { + d1(KPrintF(__FILE__ "/%s/%ld: child=%08lx MinWidth=%-4ld MinHeight=%-4ld MaxWidth=%-4ld MaxHeight=%-4ld DefWidth=%-4ld DefHeight=%-4ld\n", \ + __FUNC__, __LINE__, child, + _minwidth(child), _minheight(child), \ + _maxwidth(child), _maxheight(child), \ + _defwidth(child), _defheight(child))); + } + } + } +#endif + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + return (TRUE); +} + + +static LONG MainLoop(LONG Action, struct SCAModule *app) +{ + BOOL Running = TRUE; + + while (Running) + { + ULONG sigs = 0; + + Action = DoMethod(app->Obj[APPLICATION], MUIM_Application_NewInput, &sigs); + + switch(Action) + { + case MUIV_Application_ReturnID_Quit: + case MUIV_Application_ReturnID_SAVE: + case MUIV_Application_ReturnID_USE: + Running = FALSE; + break; + } + + if(sigs && (sigs = Wait(sigs | SIGBREAKF_CTRL_C)) & SIGBREAKF_CTRL_C) + { + Action = MUIV_Application_ReturnID_Quit; + Running = FALSE; + } + } + + return Action; +} + + +int main(int argc, char *argv[]) +{ + LONG Action = MUIV_Application_ReturnID_EDIT; + // CONST_STRPTR GivenFileName = NULL; // not used + struct SCAModule app; + BPTR oldDir = (BPTR)NULL; + struct RDArgs *rdArgs = NULL; + struct DiskObject *icon = NULL; + APTR prWindowPtr; + struct Process *MyProcess = (struct Process *) FindTask(NULL); + int Result = RETURN_FAIL; + struct WBStartup *WBenchMsg = + (argc == 0) ? (struct WBStartup *)argv : NULL; + + d1(KPrintF(__FILE__ "/%s/%ld: starting up\n", __FUNC__, __LINE__)); + + prWindowPtr = MyProcess->pr_WindowPtr; + MyProcess->pr_WindowPtr = (APTR) ~0; // suppress error requesters + + // --- Startup The Business + if(Init(&app)) + { + d1(KPrintF(__FILE__ "/%s/%ld: init done\n", __FUNC__, __LINE__)); + + if (WBenchMsg && WBenchMsg->sm_ArgList) + { + static char PrgNamePath[512]; + struct WBArg *arg; + + d1(KPrintF(__FILE__ "/%s/%ld: WBenchMsg\n", __FUNC__, __LINE__)); + + if (WBenchMsg->sm_NumArgs > 1) + { + arg = &WBenchMsg->sm_ArgList[1]; + // GivenFileName = arg->wa_Name; + } + else + { + arg = &WBenchMsg->sm_ArgList[0]; + } + + ProgramName = PrgNamePath; + + NameFromLock(WBenchMsg->sm_ArgList[0].wa_Lock, PrgNamePath, sizeof(PrgNamePath)); + AddPart(PrgNamePath, WBenchMsg->sm_ArgList[0].wa_Name, sizeof(PrgNamePath)); + + oldDir = CurrentDir(arg->wa_Lock); + + icon = GetDiskObject(arg->wa_Name); + if (icon) + { + STRPTR tt; + + tt = FindToolType(icon->do_ToolTypes, "NOPREFSPLUGINS"); + if (tt) + SkipPrefsPlugins = TRUE; + + tt = FindToolType(icon->do_ToolTypes, "CREATEICONS"); + if (tt) + { + if (MatchToolValue(tt, "NO")) + fCreateIcons = FALSE; + } + + tt = FindToolType(icon->do_ToolTypes, "ACTION"); + if (tt) + { + if (MatchToolValue(tt, "EDIT")) + Action = MUIV_Application_ReturnID_EDIT; + if (MatchToolValue(tt, "USE")) + Action = MUIV_Application_ReturnID_USE; + if (MatchToolValue(tt, "SAVE")) + Action = MUIV_Application_ReturnID_SAVE; + } + + tt = FindToolType(icon->do_ToolTypes, "NOSPLASHWINDOW"); + if (tt) + ShowSplashWindow = FALSE; + } + } + else + { + IPTR ArgArray[4]; + + d1(KPrintF(__FILE__ "/%s/%ld: CLI\n", __FUNC__, __LINE__)); + + ProgramName = argv[0]; + + memset(ArgArray, 0, sizeof(ArgArray)); + + rdArgs = ReadArgs("FROM,EDIT/S,USE/S,SAVE/S", ArgArray, NULL); + + if (ArgArray[0]) + { + // GivenFileName = (CONST_STRPTR) ArgArray[0]; + } + if (ArgArray[1]) + Action = MUIV_Application_ReturnID_EDIT; + if (ArgArray[2]) + Action = MUIV_Application_ReturnID_USE; + if (ArgArray[3]) + Action = MUIV_Application_ReturnID_SAVE; + } + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + ReadScalosPrefs("ENV:scalos/scalos.prefs"); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + PrefsDiskObject = GetDiskObject(ProgramName); + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + if (BuildApp(Action, &app, icon)) + { + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + // --- Display The GUI + if (MUIV_Application_ReturnID_EDIT == Action) + Action = MainLoop(Action, &app); + + switch (Action) + { + case MUIV_Application_ReturnID_SAVE: + set(app.Obj[TEXT_SPLASHWINDOW], MUIA_Text_Contents, (ULONG) GetLocString(MSGID_SPLASHWINDOW_SAVINGPREFS)); + if (ShowSplashWindow) + set(app.Obj[WINDOW_SPLASH], MUIA_Window_Open, TRUE); + + DoMethodForAllPrefsPlugins(1, MUIM_ScalosPrefs_SaveConfig); + WriteScalosPrefs(&app, "ENV:scalos/scalos.prefs"); + WriteScalosPrefs(&app, "ENVARC:scalos/scalos.prefs"); + WriteFontPrefs(&app, "ENVARC:sys/font.prefs"); + WriteFontPrefs(&app, "ENV:sys/font.prefs"); + WriteWorkbenchPrefs("ENVARC:sys/workbench.prefs"); + WriteWorkbenchPrefs("ENV:sys/workbench.prefs"); + break; + case MUIV_Application_ReturnID_USE: + set(app.Obj[TEXT_SPLASHWINDOW], MUIA_Text_Contents, (ULONG) GetLocString(MSGID_SPLASHWINDOW_APPLYINGPREFS)); + if (ShowSplashWindow) + set(app.Obj[WINDOW_SPLASH], MUIA_Window_Open, TRUE); + + DoMethodForAllPrefsPlugins(1, MUIM_ScalosPrefs_UseConfig); + WriteScalosPrefs(&app, "ENV:scalos/scalos.prefs"); + WriteFontPrefs(&app, "ENV:sys/font.prefs"); + WriteWorkbenchPrefs("ENV:sys/workbench.prefs"); + break; + } + } + + MUI_DisposeObject(app.Obj[APPLICATION]); + + memset(app.Obj, 0, sizeof(app.Obj)); + + d1(KPrintF(__FILE__ "/%s/%ld: just about to cleanup\n", __FUNC__, __LINE__)); + + // restore pr_WindowPtr + MyProcess->pr_WindowPtr = prWindowPtr; + } + + if (icon) + FreeDiskObject(icon); + if (oldDir) + CurrentDir(oldDir); + if (rdArgs) + FreeArgs(rdArgs); + + Cleanup(&app); + + // restore pr_WindowPtr + MyProcess->pr_WindowPtr = prWindowPtr; + + d1(KPrintF(__FILE__ "/%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + + return Result; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT PluginListConstructHookFunc(struct Hook *hook, APTR unused, struct NList_ConstructMessage *nlcm) +{ + struct PluginDef *dp = AllocPooled(nlcm->pool, sizeof(struct PluginDef)); + + (void) unused; + + if (dp) + { + *dp = *((struct PluginDef *) nlcm->entry); + } + + return (APTR) dp; +} + + +static SAVEDS(void) INTERRUPT PluginListDestructHookFunc(struct Hook *hook, APTR unused, struct NList_DestructMessage *nldm) +{ + (void) unused; + + FreePooled(nldm->pool, nldm->entry, sizeof(struct PluginDef)); +} + + +static SAVEDS(ULONG) INTERRUPT PluginListDisplayHookFunc(struct Hook *hook, APTR unused, struct NList_DisplayMessage *nldm) +{ + (void) unused; + + if (nldm->entry) + { + struct PluginDef *pd = (struct PluginDef *) nldm->entry; + + if (!pd->plug_SuccessfullyLoaded) + { + // plugin could not be opened + // display it italic in list! + nldm->preparses[0] = MUIX_I; + nldm->preparses[1] = MUIX_I; + } + + nldm->strings[0] = pd->plug_RealName; + nldm->strings[1] = pd->plug_filename; + } + else + { + // display titles + nldm->strings[0] = (STRPTR) GetLocString(MSGID_PLUGINLIST_NAME); + nldm->strings[1] = (STRPTR) GetLocString(MSGID_PLUGINLIST_PATH); + } + + return 0; +} + +static SAVEDS(LONG) INTERRUPT PluginListCompareHookFunc(struct Hook *hook, APTR unused, struct NList_CompareMessage *ncm) +{ + const struct PluginDef *pd1 = (struct PluginDef *) ncm->entry1; + const struct PluginDef *pd2 = (struct PluginDef *) ncm->entry2; + LONG col1 = ncm->sort_type & MUIV_NList_TitleMark_ColMask; + LONG col2 = ncm->sort_type2 & MUIV_NList_TitleMark2_ColMask; + LONG Result = 0; + + d1(KPrintF(__FUNC__ "/%ld: sort_type=%ld sort_type2=%ld\n", __LINE__, ncm->sort_type, ncm->sort_type2)); + + if (ncm->sort_type != MUIV_NList_SortType_None) + { + // primary sorting + switch (col1) + { + case 0: // sort by real name + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = Stricmp(pd2->plug_RealName, pd1->plug_RealName); + else + Result = Stricmp(pd1->plug_RealName, pd2->plug_RealName); + break; + case 1: // sort by filename + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = Stricmp(pd2->plug_filename, pd1->plug_filename); + else + Result = Stricmp(pd1->plug_filename, pd2->plug_filename); + break; + default: + break; + } + + if (0 == Result && col1 != col2) + { + // Secondary sorting + switch (col2) + { + case 0: // sort by realname + if (ncm->sort_type2 & MUIV_NList_TitleMark2_TypeMask) + Result = Stricmp(pd2->plug_RealName, pd1->plug_RealName); + else + Result = Stricmp(pd1->plug_RealName, pd2->plug_RealName); + break; + case 1: // sort by filename + if (ncm->sort_type2 & MUIV_NList_TitleMark2_TypeMask) + Result = Stricmp(pd2->plug_filename, pd1->plug_filename); + else + Result = Stricmp(pd1->plug_filename, pd2->plug_filename); + break; + default: + break; + } + } + } + + return Result; +} + + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT PageListConstructHookFunc(struct Hook *hook, APTR unused, struct NList_ConstructMessage *nlcm) +{ + struct PageListData *pld = AllocPooled(nlcm->pool, sizeof(struct PageListData)); + + (void) unused; + + if (pld) + { + const struct NewPageListEntry *nple = (const struct NewPageListEntry *) nlcm->entry; + + d1(KPrintF(__FILE__ "/%s/%ld: nple_ImageIndex=%lu nple_TitleString=<%s> nple_TitleImage=%08lx\n", \ + __FUNC__, __LINE__, nple->nple_ImageIndex, nple->nple_TitleString, nple->nple_TitleImage)); + + snprintf(pld->ImageSpec, sizeof(pld->ImageSpec), "\33o[%ld]", (long) nple->nple_ImageIndex); + pld->TextLine = nple->nple_TitleString; + } + + return (APTR) pld; +} + + +static SAVEDS(void) INTERRUPT PageListDestructHookFunc(struct Hook *hook, APTR unused, struct NList_DestructMessage *nldm) +{ + (void) unused; + + FreePooled(nldm->pool, nldm->entry, sizeof(struct PageListData)); +} + +static SAVEDS(ULONG) INTERRUPT PageListDisplayHookFunc(struct Hook *hook, APTR unused, struct NList_DisplayMessage *nldm) +{ + (void) unused; + + if (nldm->entry) + { + struct PageListData *pld = (struct PageListData *) nldm->entry; + + nldm->strings[0] = pld->ImageSpec; + nldm->strings[1] = (STRPTR) pld->TextLine; + nldm->preparses[0] = MUIX_C; + } + else + { + // display titles + nldm->strings[0] = ""; + nldm->strings[1] = ""; + } + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT FileDisplayConstructHookFunc(struct Hook *hook, APTR unused, struct NList_ConstructMessage *nlcm) +{ + struct FileDisplayListEntry *fdle = AllocPooled(nlcm->pool, sizeof(struct FileDisplayListEntry)); + + (void) unused; + + if (fdle) + { + struct FileDisplayListEntry *newFdle = (struct FileDisplayListEntry *) nlcm->entry; + + fdle->fdle_Index = newFdle->fdle_Index; + } + + return (APTR) fdle; +} + + +static SAVEDS(void) INTERRUPT FileDisplayDestructHookFunc(struct Hook *hook, APTR unused, struct NList_DestructMessage *nldm) +{ + (void) unused; + + FreePooled(nldm->pool, nldm->entry, sizeof(struct FileDisplayListEntry)); +} + + +static SAVEDS(ULONG) INTERRUPT FileDisplayHookFunc(struct Hook *hook, APTR unused, struct NList_DisplayMessage *nldm) +{ + (void) unused; + + if (nldm->entry) + { + struct FileDisplayListEntry *fdle = (struct FileDisplayListEntry *) nldm->entry; + + nldm->strings[0] = (STRPTR) cTextWindowsColumns[fdle->fdle_Index]; + } + else + { + // display titles + nldm->strings[0] = ""; + } + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT ControlBarGadgetListConstructHookFunc(struct Hook *hook, Object *o, struct NList_ConstructMessage *nlcm) +{ + struct ControlBarGadgetEntry *cgy = AllocPooled(nlcm->pool, sizeof(struct ControlBarGadgetEntry)); + + if (cgy) + { + const struct ControlBarGadgetEntry *cgyOrig = (struct ControlBarGadgetEntry *) nlcm->entry; + + *cgy = *cgyOrig; + + cgy->cgy_ImageObjectIndex = ControlBarGadgetImageIndex++; + + if (SCPGadgetType_ActionButton == cgy->cgy_GadgetType) + { + cgy->cgy_NormalImage = cgyOrig->cgy_NormalImage ? strdup(cgyOrig->cgy_NormalImage) : NULL; + cgy->cgy_SelectedImage = cgyOrig->cgy_SelectedImage ? strdup(cgyOrig->cgy_SelectedImage) : NULL; + cgy->cgy_DisabledImage = cgyOrig->cgy_DisabledImage ? strdup(cgyOrig->cgy_DisabledImage) : NULL; + cgy->cgy_HelpText = cgyOrig->cgy_HelpText ? strdup(cgyOrig->cgy_HelpText) : NULL; + } + else + { + // replace empty image names by strings from DefaultControlBarGadgets[] + ULONG n; + + for (n = 0; n < Sizeof(DefaultControlBarGadgets); n++) + { + if (DefaultControlBarGadgets[n].cyi_GadgetType == cgy->cgy_GadgetType) + { + if (cgyOrig->cgy_NormalImage && strlen(cgyOrig->cgy_NormalImage) > 0) + cgy->cgy_NormalImage = strdup(cgyOrig->cgy_NormalImage); + else + cgy->cgy_NormalImage = strdup(DefaultControlBarGadgets[n].cyi_NormalImage); + + if (cgyOrig->cgy_SelectedImage && strlen(cgyOrig->cgy_SelectedImage) > 0) + cgy->cgy_SelectedImage = strdup(cgyOrig->cgy_SelectedImage); + else + cgy->cgy_SelectedImage = strdup(DefaultControlBarGadgets[n].cyi_SelectedImage); + + if (cgyOrig->cgy_DisabledImage && strlen(cgyOrig->cgy_DisabledImage) > 0) + cgy->cgy_DisabledImage = strdup(cgyOrig->cgy_DisabledImage); + else + cgy->cgy_DisabledImage = strdup(DefaultControlBarGadgets[n].cyi_DisabledImage); + break; + } + } + } + + if (ExistsObject(cgy->cgy_NormalImage)) + { + d1(KPrintF("%s/%s/%ld: cgy_NormalImage=%08lx\n", __FILE__, __FUNC__, __LINE__, cgy->cgy_NormalImage)); + d1(KPrintF("%s/%s/%ld: cgy_NormalImage=<%s>\n", __FILE__, __FUNC__, __LINE__, cgy->cgy_NormalImage)); + + cgy->cgy_Image = DataTypesImageObject, + MUIA_ScaDtpic_Name, (ULONG) cgy->cgy_NormalImage, + End; //DataTypesMCC + + d1(KPrintF("%s/%s/%ld: <%s> cgy_Image=%08lx\n", __FILE__, __FUNC__, __LINE__, cgy->cgy_NormalImage, cgy->cgy_Image)); + } + else + { + cgy->cgy_Image = NULL; + } + + d1(KPrintF("%s/%s/%ld: <%s> cgy_Image=%08lx\n", __FILE__, __FUNC__, __LINE__, cgy->cgy_NormalImage, cgy->cgy_Image)); + + DoMethod(o, MUIM_NList_UseImage, cgy->cgy_Image, cgy->cgy_ImageObjectIndex, 0); + + d1(KPrintF("%s/%s/%ld: <%s> cgy_Image=%08lx\n", __FILE__, __FUNC__, __LINE__, cgy->cgy_NormalImage, cgy->cgy_Image)); + } + + d1(KPrintF("%s/%s/%ld: END cgy=%08lx\n", __FILE__, __FUNC__, __LINE__, cgy)); + + return (APTR) cgy; +} + + +static SAVEDS(void) INTERRUPT ControlBarGadgetListDestructHookFunc(struct Hook *hook, Object *o, struct NList_DestructMessage *nldm) +{ + struct ControlBarGadgetEntry *cgy = (struct ControlBarGadgetEntry *) nldm->entry; + + if (cgy) + { + if (cgy->cgy_Image) + { + DoMethod(o, MUIM_NList_UseImage, NULL, cgy->cgy_ImageObjectIndex, 0); + + MUI_DisposeObject(cgy->cgy_Image); + cgy->cgy_Image = NULL; + } + if (cgy->cgy_NormalImage) + { + free(cgy->cgy_NormalImage); + cgy->cgy_NormalImage = NULL; + } + if (cgy->cgy_SelectedImage) + { + free(cgy->cgy_SelectedImage); + cgy->cgy_SelectedImage = NULL; + } + if (cgy->cgy_DisabledImage) + { + free(cgy->cgy_DisabledImage); + cgy->cgy_DisabledImage = NULL; + } + if (cgy->cgy_HelpText) + { + free(cgy->cgy_HelpText); + cgy->cgy_HelpText = NULL; + } + + FreePooled(nldm->pool, cgy, sizeof(struct ControlBarGadgetEntry)); + } +} + + +static SAVEDS(ULONG) INTERRUPT ControlBarGadgetListDisplayHookFunc(struct Hook *hook, Object *o, struct NList_DisplayMessage *nldm) +{ + (void) o; + + if (nldm->entry) + { + struct ControlBarGadgetEntry *cgy = (struct ControlBarGadgetEntry *) nldm->entry; + + if (cgy->cgy_GadgetType < Sizeof(cControlBarGadgetTypes) - 1) + nldm->strings[0] = (STRPTR) cControlBarGadgetTypes[cgy->cgy_GadgetType]; + else + nldm->strings[0] = (STRPTR) GetLocString(MSGID_SCPGADGETTYPE_UNKNOWN); + + snprintf(cgy->cgy_ImageString, sizeof(cgy->cgy_ImageString), "\033o[%lu]", (unsigned long) cgy->cgy_ImageObjectIndex); + nldm->strings[1] = cgy->cgy_ImageString; + nldm->strings[2] = cgy->cgy_Action; + } + else + { + // display titles + nldm->strings[0] = (STRPTR) GetLocString(MSGID_CONTROLBARGADGETLIST_TYPE); +// nldm->strings[1] = (STRPTR) GetLocString(MSGID_CONTROLBARGADGETLIST_PATH); + } + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT CmdListConstructHookFunc(struct Hook *hook, APTR obj, struct NList_ConstructMessage *msg) +{ + (void) hook; + (void) obj; + + return msg->entry; +} + +static SAVEDS(void) INTERRUPT CmdListDestructHookFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *msg) +{ + (void) hook; + (void) obj; + (void) msg; +} + + +static SAVEDS(ULONG) INTERRUPT CmdListDisplayHookFunc(struct Hook *hook, APTR obj, struct NList_DisplayMessage *ltdm) +{ + struct CommandTableEntry *cte = (struct CommandTableEntry *) ltdm->entry; + + d1(KPrintF(__FILE__ "/%s/%ld: cte=%08lx\n", __FUNC__, __LINE__, cte)); + + if (cte) + { + ltdm->preparses[0] = ""; + + ltdm->strings[0] = (STRPTR) GetLocString(cte->cte_NameMsgId); + ltdm->strings[1] = (STRPTR) cte->cte_Command; + } + else + { + // display titles + ltdm->preparses[0] = ""; + ltdm->preparses[1] = ""; + + ltdm->strings[0] = ""; + ltdm->strings[1] = ""; + } + + return 0; +} + + +static SAVEDS(LONG) INTERRUPT CmdListCompareHookFunc(struct Hook *hook, Object *obj, struct NList_CompareMessage *ncm) +{ + const struct CommandTableEntry *cte1 = (const struct CommandTableEntry *) ncm->entry1; + const struct CommandTableEntry *cte2 = (const struct CommandTableEntry *) ncm->entry2; + LONG col1 = ncm->sort_type & MUIV_NList_TitleMark_ColMask; + LONG col2 = ncm->sort_type2 & MUIV_NList_TitleMark2_ColMask; + LONG Result = 0; + + if (ncm->sort_type != MUIV_NList_SortType_None) + { + // primary sorting + switch (col1) + { + case 0: // sort by full name + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = Stricmp(GetLocString(cte2->cte_NameMsgId), GetLocString(cte1->cte_NameMsgId)); + else + Result = Stricmp(GetLocString(cte1->cte_NameMsgId), GetLocString(cte2->cte_NameMsgId)); + break; + case 1: // sort by internal name + if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) + Result = Stricmp(cte2->cte_Command, cte1->cte_Command); + else + Result = Stricmp(cte1->cte_Command, cte2->cte_Command); + break; + default: + break; + } + + if (0 == Result && col1 != col2) + { + // Secondary sorting + switch (col2) + { + case 0: // sort by full name + if (ncm->sort_type2 & MUIV_NList_TitleMark2_TypeMask) + Result = Stricmp(GetLocString(cte2->cte_NameMsgId), GetLocString(cte1->cte_NameMsgId)); + else + Result = Stricmp(GetLocString(cte1->cte_NameMsgId), GetLocString(cte2->cte_NameMsgId)); + break; + case 1: // sort by internal name + if (ncm->sort_type2 & MUIV_NList_TitleMark2_TypeMask) + Result = Stricmp(cte2->cte_Command, cte1->cte_Command); + else + Result = Stricmp(cte1->cte_Command, cte2->cte_Command); + break; + default: + break; + } + } + } + + return Result; +} + +//---------------------------------------------------------------------------- + +CONST_STRPTR GetLocString(LONG MsgId) +{ + struct Scalos_Prefs_LocaleInfo li; + + li.li_Catalog = ScalosPrefsCatalog; +#ifndef __amigaos4__ + li.li_LocaleBase = LocaleBase; +#else + li.li_ILocale = ILocale; +#endif + + return GetScalos_PrefsString(&li, MsgId); +} + +static void TranslateStringArray(CONST_STRPTR *stringArray) +{ + while (*stringArray) + { + *stringArray = GetLocString((ULONG) *stringArray); + stringArray++; + } +} + +//---------------------------------------------------------------------------- + +LONG SaveIcon(CONST_STRPTR IconName) +{ + struct DiskObject *icon, *allocIcon; + + static UWORD ImageData[] = + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0x80, 0x00, 0x40, 0x00, 0x00, 0x00, 0x18, 0x00, 0x60, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x20, 0xFC, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x41, 0x02, 0x08, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x40, 0x82, 0x08, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x40, 0x82, 0x08, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x21, 0x04, 0x08, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x1E, 0x18, 0x10, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x20, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x02, 0x1C, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x0C, 0x00, + 0x40, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x0C, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, + 0xD5, 0x55, 0x55, 0x55, 0x55, 0x56, 0x00, 0x00, 0xD5, 0x55, 0x50, 0x00, 0x55, 0x55, 0x80, 0x00, + 0xD5, 0x55, 0x47, 0xFF, 0x95, 0x55, 0x60, 0x00, 0xD5, 0x55, 0x5F, 0x03, 0xE5, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x3E, 0x55, 0xF5, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x3F, 0x55, 0xF5, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x3F, 0x55, 0xF5, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x5E, 0x53, 0xF5, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x41, 0x47, 0xE5, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x55, 0x1F, 0xD5, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x55, 0x7F, 0x15, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x54, 0xFC, 0x55, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x55, 0xE1, 0x55, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x54, 0xF5, 0x55, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x55, 0x05, 0x55, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x54, 0xF5, 0x55, 0x55, 0x50, 0x00, + 0xD5, 0x55, 0x54, 0xF5, 0x55, 0x55, 0x50, 0x00, 0x35, 0x55, 0x55, 0x05, 0x55, 0x55, 0x50, 0x00, + 0x0D, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, 0x00, 0x03, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + static struct Image NormalImage = + { + 0, 0, 54, 23, + 2, + ImageData, + 3, 0, + NULL + }; + + static STRPTR defToolTypes[] = + { + "ACTION=USE", + NULL + }; + + static struct DiskObject DefaultIcon = + { + WB_DISKMAGIC, WB_DISKVERSION, + + { + NULL, + 0, 0, 54, 24, + GFLG_GADGIMAGE | GFLG_GADGHBOX, + GACT_RELVERIFY | GACT_IMMEDIATE, + GTYP_BOOLGADGET, + &NormalImage, NULL, + NULL, + 0, + NULL, + 0, + NULL + }, + + WBPROJECT, + NULL, + defToolTypes, + NO_ICON_POSITION, NO_ICON_POSITION, + NULL, + NULL, + 8192 + }; + + icon = allocIcon = GetDiskObject("ENV:sys/def_ScaMainPrefs"); + if (NULL == icon) + icon = allocIcon = GetDiskObject("ENV:sys/def_pref"); + if (NULL == icon) + icon = &DefaultIcon; + + if (icon) + { + STRPTR oldDefaultTool = icon->do_DefaultTool; + + icon->do_DefaultTool = ProgramName; + + PutDiskObject((STRPTR) IconName, icon); + + icon->do_DefaultTool = oldDefaultTool; + + if (allocIcon) + FreeDiskObject(allocIcon); + } + + return 0; +} + +//---------------------------------------------------------------------------- + +//static INLINE Object *PrecisionSliderMCCObject(Tag tags, ...) +//{ +// return NewObjectA(PrecisionSliderClass->mcc_Class, 0, (struct TagItem *) &tags); +//} + +//---------------------------------------------------------------------------- + +DISPATCHER(PrecisionSlider) +{ + if (msg->MethodID==MUIM_Numeric_Stringify) + { + struct PrecisionSliderData *data = INST_DATA(cl,obj); + struct MUIP_Numeric_Stringify *m = (APTR)msg; + + switch (m->value) + { + case 1: + strcpy(data->buf, GetLocString(MSGID_PRECISION_EXACT)); + break; + case 2: + strcpy(data->buf, GetLocString(MSGID_PRECISION_IMAGE)); + break; + case 3: + strcpy(data->buf, GetLocString(MSGID_PRECISION_ICON)); + break; + case 4: + default: + strcpy(data->buf, GetLocString(MSGID_PRECISION_GUI)); + break; + } + + return (ULONG) data->buf; + } + return(DoSuperMethodA(cl,obj,msg)); +} +DISPATCHER_END + +//---------------------------------------------------------------------------- + +DISPATCHER(BufferSizeSlider) +{ + if (msg->MethodID == MUIM_Numeric_Stringify) + { + struct PrecisionSliderData *data = INST_DATA(cl,obj); + struct MUIP_Numeric_Stringify *m = (APTR)msg; + ULONG size; + + if (m->value < 20) + { + size = 1 << (m->value - 10); // Convert to KBytes + snprintf(data->buf, sizeof(data->buf), "%ldK", (long) size); + } + else + { + size = 1 << (m->value - 20); // Convert to MBytes + snprintf(data->buf, sizeof(data->buf), "%ldM", (long) size); + } + + return (ULONG) data->buf; + } + + return DoSuperMethodA(cl, obj, msg); +} +DISPATCHER_END + +//---------------------------------------------------------------------------- + +//static INLINE Object *TTGammaSliderMCCObject(Tag tags, ...) +//{ +// return NewObjectA(TTGammaSliderClass->mcc_Class, 0, (struct TagItem *) &tags); +//} + +//---------------------------------------------------------------------------- + +DISPATCHER(TTGammaSlider) +{ + if (msg->MethodID==MUIM_Numeric_Stringify) + { + struct TTGammaSliderData *data = INST_DATA(cl,obj); + struct MUIP_Numeric_Stringify *m = (APTR)msg; + + snprintf(data->buf, sizeof(data->buf), "%ld.%03ld", (long) (m->value / 1000), (long) (m->value % 1000)); + + return (ULONG) data->buf; + } + return(DoSuperMethodA(cl,obj,msg)); +} +DISPATCHER_END + +//---------------------------------------------------------------------------- + +DISPATCHER(ThumbnailLifetimeSlider) +{ + ULONG Result; + + switch (msg->MethodID) + { + case MUIM_Numeric_Stringify: + { + struct ThumbnailLifetimeSliderData *data = INST_DATA(cl,obj); + struct MUIP_Numeric_Stringify *mstr = (struct MUIP_Numeric_Stringify *) msg; + + if (0 == mstr->value) + Result = (ULONG) GetLocString(MSGID_THUMBNAILS_LIFETIME_FOREVER); + else + { + snprintf(data->buf, sizeof(data->buf), MUIX_C "%lu %s", + (unsigned long) mstr->value, + GetLocString(MSGID_ICONSPAGE_THUMBNAILS_MAXAGE_DAYS)); + Result = (ULONG) data->buf; + } + } + break; + + default: + Result = DoSuperMethodA(cl, obj, msg); + break; + } + + return Result; +} +DISPATCHER_END + +//----------------------------------------------------------------- + +static ULONG TextWindowColumnsListDragQuery(struct IClass *cl,Object *obj,struct MUIP_DragQuery *msg) +{ + d1(kprintf(__FUNC__ "/%ld: src=%08lx obj=%08lx userdata=%08lx\n", __LINE__, msg->obj, obj, muiUserData(obj))); + + if (msg->obj == obj) + { + /* + ** If somebody tried to drag ourselves onto ourselves, we let our superclass + ** (the list class) handle the necessary actions. Depending on the state of + ** its MUIA_List_DragSortable attribute, it will either accept or refuse to become + ** the destination object. + */ + + return DoSuperMethodA(cl,obj, (Msg) msg); + } + else if (msg->obj == (Object *) muiUserData(obj)) + { + /* + ** If our predefined source object wants us to become active, + ** we politely accept it. + */ + + return MUIV_DragQuery_Accept; + } + else + { + /* + ** Otherwise, someone tried to feed us with something we don't like + ** very much. Just refuse it. + */ + + return MUIV_DragQuery_Refuse; + } + +} + + +static ULONG TextWindowColumnsListDragDrop(struct IClass *cl,Object *obj,struct MUIP_DragDrop *msg) +{ + if (msg->obj == obj) + { + return DoSuperMethodA(cl, obj, (Msg) msg); + } + else + { + /* + ** we can be sure that msg->obj is our predefined source object + ** since we wouldn't have accepted the MUIM_DragQuery and wouldn't + ** have become an active destination object otherwise. + */ + + LONG idArray[Sizeof(cTextWindowsColumns)]; + LONG dropmark = 0; + LONG sortable = 0; + LONG id = MUIV_NList_NextSelected_Start; + LONG ArrayIndex; + + get(obj, MUIA_NList_DragSortable, &sortable); + get(obj, MUIA_NList_DropMark, &dropmark); + + ArrayIndex = 0; + while (1) + { + APTR entry; + + DoMethod(msg->obj, MUIM_NList_NextSelected, &id); + + if (MUIV_NList_NextSelected_End == id) + break; + + idArray[ArrayIndex] = id; + + /* get source entry */ + DoMethod(msg->obj, MUIM_NList_GetEntry, id, &entry); + + if (sortable) + { + DoMethod(obj, MUIM_NList_InsertSingle, entry, dropmark); + dropmark++; + } + else + { + /* + ** we are about to return something to the available fields + ** listview which is always sorted. + */ + + DoMethod(obj, MUIM_NList_InsertSingle, entry, MUIV_NList_Insert_Sorted); + } + ArrayIndex++; + } + + while (ArrayIndex--) + { + set(msg->obj, MUIA_NList_Active, MUIV_NList_Active_Off); + + /* remove source entry */ + DoMethod(msg->obj, MUIM_NList_Remove, idArray[ArrayIndex]); + } + + /* + ** make the inserted object the active and make the source listviews + ** active object inactive to give some more visual feedback to the user. + */ + + get(obj, MUIA_NList_InsertPosition, &dropmark); + set(obj, MUIA_NList_Active, dropmark); + set(msg->obj, MUIA_NList_Active, MUIV_NList_Active_Off); + + return(0); + } +} + + +DISPATCHER(TextWindowColumnsList) +{ + switch (msg->MethodID) + { + case MUIM_DragQuery: + return TextWindowColumnsListDragQuery(cl,obj,(APTR)msg); + break; + case MUIM_DragDrop: + return TextWindowColumnsListDragDrop(cl,obj,(APTR)msg); + break; + } + return DoSuperMethodA(cl,obj,msg); +} +DISPATCHER_END + +//----------------------------------------------------------------- + +static ULONG ControlBarGadgetsListDragQuery(struct IClass *cl,Object *obj,struct MUIP_DragQuery *msg) +{ + d1(kprintf(__FUNC__ "/%ld: src=%08lx obj=%08lx userdata=%08lx\n", __LINE__, msg->obj, obj, muiUserData(obj))); + + if (msg->obj == obj) + { + /* + ** If somebody tried to drag ourselves onto ourselves, we let our superclass + ** (the list class) handle the necessary actions. Depending on the state of + ** its MUIA_List_DragSortable attribute, it will either accept or refuse to become + ** the destination object. + */ + + return DoSuperMethodA(cl,obj, (Msg) msg); + } + else if (msg->obj == (Object *) muiUserData(obj)) + { + /* + ** If our predefined source object wants us to become active, + ** we politely accept it. + */ + + return MUIV_DragQuery_Accept; + } + else + { + /* + ** Otherwise, someone tried to feed us with something we don't like + ** very much. Just refuse it. + */ + + return MUIV_DragQuery_Refuse; + } + +} + + +static ULONG ControlBarGadgetsListDragDrop(struct IClass *cl,Object *obj,struct MUIP_DragDrop *msg) +{ + d1(KPrintF(__FILE__ "/%s/%ld: START\n", __FUNC__, __LINE__)); + + if (msg->obj == obj) + { + return DoSuperMethodA(cl, obj, (Msg) msg); + } + else + { + /* + ** we can be sure that msg->obj is our predefined source object + ** since we wouldn't have accepted the MUIM_DragQuery and wouldn't + ** have become an active destination object otherwise. + */ + + LONG dropmark = 0; + LONG id = MUIV_NList_NextSelected_Start; + ULONG SourceIsDragSortable = FALSE; + ULONG DestIsDragSortable = FALSE; + + get(obj, MUIA_NList_DragSortable, &DestIsDragSortable); + get(msg->obj, MUIA_NList_DragSortable, &SourceIsDragSortable); + get(obj, MUIA_NList_DropMark, &dropmark); + + while (1) + { + APTR entry; + + DoMethod(msg->obj, MUIM_NList_NextSelected, &id); + + d1(KPrintF(__FILE__ "/%s/%ld: id=%ld\n", __FUNC__, __LINE__, id)); + + if (MUIV_NList_NextSelected_End == id) + break; + + /* get source entry */ + DoMethod(msg->obj, MUIM_NList_GetEntry, id, &entry); + + // add to destination -- only to active list + if (DestIsDragSortable) + { + DoMethod(obj, MUIM_NList_InsertSingle, entry, dropmark); + dropmark++; + } + } + + /* remove source entries -- only from active list */ + if (SourceIsDragSortable) + { + DoMethod(msg->obj, MUIM_NList_Remove, MUIV_NList_Remove_Selected); + } + + /* + ** make the inserted object the active and make the source listviews + ** active object inactive to give some more visual feedback to the user. + */ + + get(obj, MUIA_NList_InsertPosition, &dropmark); + set(obj, MUIA_NList_Active, dropmark); + + // deselect everything on source object + set(msg->obj, MUIA_NList_Active, MUIV_NList_Active_Off); + DoMethod(msg->obj,MUIM_NList_Select, MUIV_NList_Select_All, MUIV_NList_Select_Off, NULL); + + d1(KPrintF(__FILE__ "/%s/%ld: END\n", __FUNC__, __LINE__)); + + return(0); + } +} + + +DISPATCHER(ControlBarGadgetsList) +{ + switch (msg->MethodID) + { + case MUIM_DragQuery: + return ControlBarGadgetsListDragQuery(cl,obj,(APTR)msg); + break; + case MUIM_DragDrop: + return ControlBarGadgetsListDragDrop(cl,obj,(APTR)msg); + break; + } + return DoSuperMethodA(cl,obj,msg); +} +DISPATCHER_END + +//----------------------------------------------------------------- + +static VOID Cleanup(struct SCAModule *app) +{ + ReadWritePrefsCleanup(); + PrefsPluginsCleanup(); + + if (app->Obj[WIN_ABOUT_MORPHOS]) + { + MUI_DisposeObject(app->Obj[WIN_ABOUT_MORPHOS]); + app->Obj[WIN_ABOUT_MORPHOS] = NULL; + } + if (WBScreen) + { + UnlockPubScreen(NULL, WBScreen); + WBScreen = NULL; + } + + if (PrefsDiskObject) + { + FreeDiskObject(PrefsDiskObject); + PrefsDiskObject = NULL; + } + + if (ScalosPrefsCatalog) + { + CloseCatalog(ScalosPrefsCatalog); + ScalosPrefsCatalog = NULL; + } + + if (LocaleBase) + { + CloseLibrary((struct Library *) LocaleBase); + LocaleBase = NULL; + } + if (ControlBarGadgetsListClass) + { + MUI_DeleteCustomClass(ControlBarGadgetsListClass); + ControlBarGadgetsListClass = NULL; + } + if (TextWindowColumnsListClass) + { + MUI_DeleteCustomClass(TextWindowColumnsListClass); + TextWindowColumnsListClass = NULL; + } + if (SelectMarkSampleClass) + { + CleanupSelectMarkSampleClass(SelectMarkSampleClass); + SelectMarkSampleClass = NULL; + } + if (McpFrameClass) + { + CleanupMcpFrameClass(McpFrameClass); + McpFrameClass = NULL; + } + if (DataTypesImageClass) + { + CleanupDtpicClass(DataTypesImageClass); + DataTypesImageClass = NULL; + } + if (FontSampleClass) + { + CleanupFontSampleClass(FontSampleClass); + FontSampleClass = NULL; + } + if (PrecisionSliderClass) + { + MUI_DeleteCustomClass(PrecisionSliderClass); + PrecisionSliderClass = NULL; + } + if (BufferSizeSliderClass) + { + MUI_DeleteCustomClass(BufferSizeSliderClass); + BufferSizeSliderClass = NULL; + } + if (ThumbnailLifetimeSliderClass) + { + MUI_DeleteCustomClass(ThumbnailLifetimeSliderClass); + ThumbnailLifetimeSliderClass = NULL; + } + if (TTGammaSliderClass) + { + MUI_DeleteCustomClass(TTGammaSliderClass); + TTGammaSliderClass = NULL; + } + + // --- Close Libraries + +#ifdef __amigaos4__ + if (IPreferences) + { + DropInterface((struct Interface *)IPreferences); + IPreferences = NULL; + } +#endif //__amigaos4__ + if (PreferencesBase) + { + CloseLibrary(PreferencesBase); + PreferencesBase = NULL; + } +#ifdef __amigaos4__ + if (IWorkbench) + { + DropInterface((struct Interface *)IWorkbench); + IWorkbench = NULL; + } +#endif //__amigaos4__ + if (WorkbenchBase) + { + CloseLibrary(WorkbenchBase); + WorkbenchBase = NULL; + } +#ifdef __amigaos4__ + if (ICyberGfx) + { + DropInterface((struct Interface *)ICyberGfx); + ICyberGfx = NULL; + } +#endif //__amigaos4__ + if (CyberGfxBase) + { + CloseLibrary(CyberGfxBase); + CyberGfxBase = NULL; + } +#ifdef __amigaos4__ + if (ITTEngine) + { + DropInterface((struct Interface *)ITTEngine); + ITTEngine = NULL; + } +#endif //__amigaos4__ + if (TTEngineBase) + { + CloseLibrary(TTEngineBase); + TTEngineBase = NULL; + } +#ifdef __amigaos4__ + if (IScalosGfx) + { + DropInterface((struct Interface *)IScalosGfx); + IScalosGfx = NULL; + } +#endif //__amigaos4__ + if (ScalosGfxBase) + { + CloseLibrary(ScalosGfxBase); + ScalosGfxBase = NULL; + } +#ifdef __amigaos4__ + if (IScalos) + { + DropInterface((struct Interface *)IScalos); + IScalos = NULL; + } +#endif //__amigaos4__ + if (ScalosBase) + { + CloseLibrary(&ScalosBase->scb_LibNode); + ScalosBase = NULL; + } +#ifdef __amigaos4__ + if (IIFFParse) + { + DropInterface((struct Interface *)IIFFParse); + IIFFParse = NULL; + } +#endif //__amigaos4__ + if (IFFParseBase) + { + CloseLibrary(IFFParseBase); + IFFParseBase = NULL; + } +#ifdef __amigaos4__ + if (IMUIMaster) + { + DropInterface((struct Interface *)IMUIMaster); + IMUIMaster = NULL; + } +#endif //__amigaos4__ + if (MUIMasterBase) + { + CloseLibrary(MUIMasterBase); + MUIMasterBase = NULL; + } +#ifdef __amigaos4__ + if (IIcon) + { + DropInterface((struct Interface *)IIcon); + IIcon = NULL; + } +#endif //__amigaos4__ + if (IconBase) + { + CloseLibrary(IconBase); + IconBase = NULL; + } +#ifdef __amigaos4__ + if (IAsl) + { + DropInterface((struct Interface *)IAsl); + IAsl = NULL; + } +#endif //__amigaos4__ + if (AslBase) + { + CloseLibrary(AslBase); + AslBase = NULL; + } +#ifndef __amigaos4__ + if (UtilityBase) + { + CloseLibrary((struct Library *)UtilityBase); + UtilityBase = NULL; + } +#endif //__amigaos4__ +#ifdef __amigaos4__ + if (IGraphics) + { + DropInterface((struct Interface *)IGraphics); + IGraphics = NULL; + } +#endif //__amigaos4__ + if (GfxBase) + { + CloseLibrary((struct Library *)GfxBase); + GfxBase = NULL; + } +#ifdef __amigaos4__ + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } +#endif //__amigaos4__ + if (IntuitionBase) + { + CloseLibrary((struct Library *)IntuitionBase); + IntuitionBase = NULL; + } +#ifdef __amigaos4__ + if (IDiskfont) + { + DropInterface((struct Interface *)IDiskfont); + IDiskfont = NULL; + } +#endif //__amigaos4__ + if (DiskfontBase) + { + CloseLibrary(DiskfontBase); + DiskfontBase = NULL; + } +} + + +static BOOL Init(struct SCAModule *app) +{ + BOOL Success = FALSE; + + memset(app, 0, sizeof(struct SCAModule)); + + NewList(&PluginList); + NewList(&ControlBarGadgetListNormal); + NewList(&ControlBarGadgetListBrowser); + + d1(KPrintF(__FILE__ "/%s/%ld: START\n", __FUNC__, __LINE__)); + + do { + DiskfontBase = OpenLibrary("diskfont.library", 39); + if (NULL == DiskfontBase) + { + Printf("Error: Unable to open 'diskfont.library' v39\n"); + break; + } +#ifdef __amigaos4__ + IDiskfont = (struct DiskfontIFace *)GetInterface((struct Library *)DiskfontBase, "main", 1, NULL); + if (NULL == IDiskfont) + { + Printf("Error: Could not get 'diskfont.library' OS4 interface\n"); + break; + } +#endif //__amigaos4__ + if(! (IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",39) )) + { + Printf("Error: Unable to open 'Intuition.library' v39\n"); + break; + } +#ifdef __amigaos4__ + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + { + Printf("Error: Could not get 'intuition.library' OS4 interface\n"); + break; + } +#endif //__amigaos4__ + if(! (GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",39) )) + { + Printf("Error: Unable to open 'graphics.library' v39\n"); + break; + } +#ifdef __amigaos4__ + IGraphics = (struct GraphicsIFace *)GetInterface((struct Library *)GfxBase, "main", 1, NULL); + if (NULL == IGraphics) + { + Printf("Error: Could not get 'graphics.library' OS4 interface\n"); + break; + } +#endif //__amigaos4__ +#ifndef __amigaos4__ + if(! (UtilityBase = OpenLibrary("utility.library",39) )) + { + MsgBox("Unable to open 'utility.library v39", "Error", NULL); + break; + } +#endif //__amigaos4__ + IconBase = OpenLibrary("icon.library", 39); + if (NULL == IconBase) + { + MsgBox("Unable to open 'icon.library v39", "Error", NULL); + break; + } +#ifdef __amigaos4__ + IIcon = (struct IconIFace *)GetInterface((struct Library *)IconBase, "main", 1, NULL); + if (NULL == IIcon) + { + Printf("Error: Could not get 'icon.library' OS4 interface\n"); + break; + } +#endif //__amigaos4__ + AslBase = OpenLibrary("asl.library", 39); + if (NULL == AslBase) + { + MsgBox("Unable to open 'asl.library v39", "Error", NULL); + break; + } +#ifdef __amigaos4__ + IAsl = (struct AslIFace *)GetInterface((struct Library *)AslBase, "main", 1, NULL); + if (NULL == IAsl) + { + Printf("Error: Could not get 'asl.library' OS4 interface\n"); + break; + } +#endif //__amigaos4__ + IFFParseBase = OpenLibrary("iffparse.library", 39); + if (NULL == IFFParseBase) + { + MsgBox("Unable to open 'iffparse.library v39", "Error", NULL); + break; + } +#ifdef __amigaos4__ + IIFFParse = (struct IFFParseIFace *)GetInterface((struct Library *)IFFParseBase, "main", 1, NULL); + if (NULL == IIFFParse) + { + Printf("Error: Could not get 'iffparse.library' OS4 interface\n"); + break; + } +#endif //__amigaos4__ + MUIMasterBase = OpenLibrary("zune.library", 0); + if (NULL == MUIMasterBase) + MUIMasterBase = OpenLibrary(MUIMASTER_NAME, 19); + if (NULL == MUIMasterBase) + { + MsgBox("Unable to open 'muimaster.library v19", "Error", NULL); + break; + } +#ifdef __amigaos4__ + IMUIMaster = (struct MUIMasterIFace *)GetInterface((struct Library *)MUIMasterBase, "main", 1, NULL); + if (NULL == IMUIMaster) + { + Printf("Error: Could not get 'muimaster.library' OS4 interface\n"); + break; + } +#endif //__amigaos4__ + + PreferencesBase = OpenLibrary("preferences.library", 39); + if (NULL == PreferencesBase) + { + MsgBox("Unable to open 'preferences.library' v39", "Error", NULL); + break; + } +#ifdef __amigaos4__ + IPreferences = (struct PreferencesIFace *)GetInterface((struct Library *)PreferencesBase, "main", 1, NULL); + if (NULL == IPreferences) + { + Printf("Error: Could not get 'preferences.library' OS4 interface\n"); + break; + } +#endif //__amigaos4__ + + WorkbenchBase = OpenLibrary("workbench.library", 39); + if (NULL == WorkbenchBase) + { + MsgBox("Unable to open 'workbench.library' v39", "Error", NULL); + break; + } +#ifdef __amigaos4__ + IWorkbench = (struct WorkbenchIFace *)GetInterface((struct Library *)WorkbenchBase, "main", 1, NULL); + if (NULL == IWorkbench) + { + Printf("Error: Could not get 'diskfont.library' OS4 interface\n"); + break; + } +#endif //__amigaos4__ + + // TTEngineBase is optional + TTEngineBase = OpenLibrary(TTENGINENAME, 6); +#ifdef __amigaos4__ + if (TTEngineBase) + ITTEngine = (struct TTEngineIFace *)GetInterface((struct Library *)TTEngineBase, "main", 1, NULL); +#endif //__amigaos4__ + + // CyberGfxBase is optional + CyberGfxBase = OpenLibrary("cybergraphics.library", 40); +#ifdef __amigaos4__ + if (CyberGfxBase) + ICyberGfx = (struct CyberGfxIFace *)GetInterface((struct Library *)CyberGfxBase, "main", 1, NULL); +#endif //__amigaos4__ + + // ScalosBase is optional + ScalosBase = (struct ScalosBase *) OpenLibrary(SCALOSNAME, 39); +#ifdef __amigaos4__ + if (ScalosBase) + IScalos = (struct ScalosIFace *)GetInterface((struct Library *)ScalosBase, "main", 1, NULL); +#endif //__amigaos4__ + + // ScalosGfxBase is optional + ScalosGfxBase = OpenLibrary(SCALOSGFXNAME, 42); +#ifdef __amigaos4__ + if (ScalosGfxBase) + IScalosGfx = (struct ScalosGfxIFace *)GetInterface(ScalosGfxBase, "main", 1, NULL); +#endif //__amigaos4__ + + // LocaleBase is optional + LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 39); +#ifdef __amigaos4__ + if (LocaleBase) + ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL); +#endif //__amigaos4__ + if (LocaleBase) + ScalosPrefsCatalog = OpenCatalogA(NULL, "Scalos/Scalos_Prefs.catalog", NULL); + + PrecisionSliderClass = MUI_CreateCustomClass(NULL, MUIC_Slider, NULL, sizeof(struct PrecisionSliderData), DISPATCHER_REF(PrecisionSlider)); + if (NULL == PrecisionSliderClass) + { + MsgBox("Unable to create PrecisionSliderClass", "Error", NULL); + break; + } + + BufferSizeSliderClass = MUI_CreateCustomClass(NULL, MUIC_Slider, NULL, sizeof(struct PrecisionSliderData), DISPATCHER_REF(BufferSizeSlider)); + if (NULL == BufferSizeSliderClass) + { + MsgBox("Unable to create BufferSizeSliderClass", "Error", NULL); + break; + } + + ThumbnailLifetimeSliderClass = MUI_CreateCustomClass(NULL, MUIC_Numericbutton, + NULL, sizeof(struct ThumbnailLifetimeSliderData), DISPATCHER_REF(ThumbnailLifetimeSlider)); + if (NULL == ThumbnailLifetimeSliderClass) + { + MsgBox("Unable to create ThumbnailLifetimeSliderClass", "Error", NULL); + break; + } + + TTGammaSliderClass = MUI_CreateCustomClass(NULL, MUIC_Slider, NULL, sizeof(struct TTGammaSliderData), DISPATCHER_REF(TTGammaSlider)); + if (NULL == TTGammaSliderClass) + { + MsgBox("Unable to create TTGammaSliderClass", "Error", NULL); + break; + } + + TextWindowColumnsListClass = MUI_CreateCustomClass(NULL, MUIC_NList, NULL, 0, DISPATCHER_REF(TextWindowColumnsList)); + if (NULL == TextWindowColumnsListClass) + { + MsgBox("Unable to create TextWindowColumnsListClass", "Error", NULL); + break; + } + + ControlBarGadgetsListClass = MUI_CreateCustomClass(NULL, MUIC_NList, NULL, 0, DISPATCHER_REF(ControlBarGadgetsList)); + if (NULL == ControlBarGadgetsListClass) + { + MsgBox("Unable to create ControlBarGadgetsListClass", "Error", NULL); + break; + } + + FontSampleClass = InitFontSampleClass(); + if (NULL == FontSampleClass) + { + MsgBox("Unable to create FontSampleClass", "Error", NULL); + break; + } + + if (!PrefsPluginsInit()) + { + MsgBox("PrefsPluginsInit() failed", "Error", NULL); + break; + } + + WBScreen = LockPubScreen("Workbench"); + if (NULL == WBScreen) + { + MsgBox("Unable to lock workbench screen", "Error", NULL); + break; + } + + WBScreenDepth = GetBitMapAttr(WBScreen->RastPort.BitMap, BMA_DEPTH); + + DataTypesImageClass = InitDtpicClass(); + if (NULL == DataTypesImageClass) + { + MsgBox("Unable to create DataTypesImageClass", "Error", NULL); + break; + } + + McpFrameClass = InitMcpFrameClass(); + if (NULL == McpFrameClass) + { + MsgBox("Unable to create McpFrameClass", "Error", NULL); + break; + } + + SelectMarkSampleClass = InitSelectMarkSampleClass(); + if (NULL == SelectMarkSampleClass) + { + MsgBox("Unable to create SelectMarkSampleClass", "Error", NULL); + break; + } + + if (!ReadWritePrefsInit()) + { + MsgBox("ReadWritePrefsInit() failed.", "Error", NULL); + break; + } + + // --- Everything opened fine + Success = TRUE; + } while (0); + + d1(KPrintF(__FILE__ "/%s/%ld: END Success=%ld\n", __FUNC__, __LINE__, Success)); + + return Success; +} + + +// --- A Simple Message Requester +VOID MsgBox(char *message, char *title, struct SCAModule *app) +{ + if(MUIMasterBase && app->Obj[APPLICATION]) + { + MUI_Request(app->Obj[APPLICATION], + NULL, + 0, + title, + "Ok", + message + ); + } + else if (IntuitionBase) + { + struct EasyStruct ER = + { + sizeof(struct EasyStruct), + 0, + "", + "", + "Ok", + }; + + ER.es_Title = title; + ER.es_TextFormat = message; + + EasyRequest(NULL, &ER, NULL, NULL); + } + +} + +BOOL ExistsObject(CONST_STRPTR Name) +{ + BOOL Exists = FALSE; + BPTR fLock; + + d1(KPrintF("%s/%s/%ld: START Name=%08lx\n", __FILE__, __FUNC__, __LINE__, Name)); + + if (Name) + { + d1(KPrintF("%s/%s/%ld: Name=<%s>\n", __FILE__, __FUNC__, __LINE__, Name)); + + fLock = Lock(Name, ACCESS_READ); + if (fLock) + { + Exists = TRUE; + UnLock(fLock); + } + else + { + LONG Err = IoErr(); + + switch (Err) + { + case ERROR_OBJECT_IN_USE: + Exists = TRUE; + break; + } + } + } + + d1(KPrintF("%s/%s/%ld: END Exists=%ld\n", __FILE__, __FUNC__, __LINE__, Exists)); + + return Exists; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT ModulesListConstructHookFunc(struct Hook *hook, Object *o, struct NList_ConstructMessage *nlcm) +{ + struct ModuleListEntry *mdle = (struct ModuleListEntry *) AllocPooled(nlcm->pool, sizeof(struct ModuleListEntry)); + + d1(KPrintF("%s/%s/%ld: START mdle=%08lx\n", __FILE__, __FUNC__, __LINE__, mdle)); + + if (mdle) + { + CONST_STRPTR ModuleName = (CONST_STRPTR) nlcm->entry; + STRPTR dlp; + CONST_STRPTR lp; + STRPTR tempLine; + char tempName[108]; + BOOL EnablePrefs; + size_t len; + + d1(KPrintF("%s/%s/%ld: ModuleName=<%s>\n", __FILE__, __FUNC__, __LINE__, ModuleName)); + + stccpy(mdle->mdle_Modulename, ModuleName, sizeof(mdle->mdle_Modulename)); + snprintf(mdle->mdle_Filename, sizeof(mdle->mdle_Filename), "Scalos:Prefs/Modules/%s.prefs", ModuleName); + + for (dlp=tempName, lp=ModuleName; *lp && '.' != *lp; ) + *dlp++ = *lp++; + *dlp = '\0'; + + d1(KPrintF("%s/%s/%ld: mdle_Filename=<%s>\n", __FILE__, __FUNC__, __LINE__, mdle->mdle_Filename)); + + // --- Is the prefs executable accessible? +#if 1 + EnablePrefs = ExistsObject(mdle->mdle_Filename); +#else + EnablePrefs = TRUE; +#endif + + mdle->mdle_ImageObjectIndex = ModuleImageIndex++; + mdle->mdle_PopupObjectIndex = ModuleImageIndex++; + mdle->mdle_EntryIndex = ModuleEntryIndex++; + + d1(KPrintF("%s/%s/%ld: ModuleName=<%s> tempName=<%s>\n", __FILE__, __FUNC__, __LINE__, ModuleName, tempName)); + + len = 20 + strlen(ModuleName) + strlen(tempName) ; + tempLine = malloc(len); + if (tempLine) + { + snprintf(tempLine, len, "THEME:Modules/%s/%s", ModuleName, tempName); + d1(KPrintF("%s/%s/%ld: tempLine=<%s>\n", __FILE__, __FUNC__, __LINE__, tempLine)); + + if (ExistsObject(tempLine)) + { + d1(KPrintF("%s/%s/%ld: tempLine=%08lx\n", __FILE__, __FUNC__, __LINE__, tempLine)); + d1(KPrintF("%s/%s/%ld: tempLine=<%s>\n", __FILE__, __FUNC__, __LINE__, tempLine)); + + mdle->mdle_Image = DataTypesImageObject, + MUIA_ScaDtpic_Name, (ULONG) tempLine, + End; //DataTypesMCC + + d1(kprintf(__FUNC__ "/%ld: <%s> mdle_Image=%08lx\n", __LINE__, tempLine, mdle->mdle_Image)); + + DoMethod(o, MUIM_NList_UseImage, + mdle->mdle_Image, + mdle->mdle_ImageObjectIndex, + 0); + } + else + { + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + mdle->mdle_Image = NULL; + + DoMethod(o, MUIM_NList_UseImage, + app->Obj[mdle->mdle_EntryIndex], + mdle->mdle_ImageObjectIndex, + 0); + } + + free(tempLine); + } + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + if (EnablePrefs) + { + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + mdle->mdle_Popup = ImageObject, + MUIA_InputMode, MUIV_InputMode_RelVerify, + MUIA_Image_Spec, "6:18", //MUII_PopUp, + End; //Image + + DoMethod(o, MUIM_NList_UseImage, + mdle->mdle_Popup, mdle->mdle_PopupObjectIndex, ~0); + } + else + { + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + mdle->mdle_Popup = NULL; + } + } + + d1(KPrintF("%s/%s/%ld: END mdle=%08lx\n", __FILE__, __FUNC__, __LINE__, mdle)); + + return (APTR) mdle; +} + + +static SAVEDS(void) INTERRUPT ModulesListDestructHookFunc(struct Hook *hook, Object *o, struct NList_DestructMessage *nldm) +{ + struct ModuleListEntry *mdle = (struct ModuleListEntry *) nldm->entry; + + if (mdle) + { + if (mdle->mdle_Image) + { + DoMethod(o, MUIM_NList_UseImage, NULL, mdle->mdle_ImageObjectIndex, 0); + + MUI_DisposeObject(mdle->mdle_Image); + mdle->mdle_Image = NULL; + } + if (mdle->mdle_Popup) + { + DoMethod(o, MUIM_NList_UseImage, NULL, mdle->mdle_PopupObjectIndex, 0); + + MUI_DisposeObject(mdle->mdle_Popup); + mdle->mdle_Popup = NULL; + } + + FreePooled(nldm->pool, mdle, sizeof(struct ModuleListEntry)); + } +} + + +static SAVEDS(ULONG) INTERRUPT ModulesListDisplayHookFunc(struct Hook *hook, Object *o, struct NList_DisplayMessage *nldm) +{ + (void) o; + + if (nldm->entry) + { + struct ModuleListEntry *mdle = (struct ModuleListEntry *) nldm->entry; + + snprintf(mdle->mdle_ImageString, sizeof(mdle->mdle_ImageString), "\033o[%lu]", (unsigned long) mdle->mdle_ImageObjectIndex); + + if (mdle->mdle_Popup) + snprintf(mdle->mdle_PopupObjectString, sizeof(mdle->mdle_PopupObjectString), "\033o[%lu@%lu]", (unsigned long) mdle->mdle_PopupObjectIndex, (unsigned long) mdle->mdle_EntryIndex); + else + strcpy(mdle->mdle_PopupObjectString, ""); + + d1(kprintf(__FUNC__ "/%ld: PopupObj=<%s>\n", __LINE__, mdle->mdle_PopupObjectString)); + + nldm->strings[0] = mdle->mdle_ImageString; + nldm->strings[1] = mdle->mdle_Modulename; + nldm->strings[2] = mdle->mdle_PopupObjectString; + + nldm->preparses[0] = MUIX_C; + nldm->preparses[2] = MUIX_C; + } + else + { + // display titles + nldm->strings[0] = ""; + nldm->strings[1] = ""; + nldm->strings[2] = ""; + } + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT HiddenDevicesConstructHookFunc(struct Hook *hook, APTR unused, struct NList_ConstructMessage *nlcm) +{ + struct HiddenDeviceListEntry *hde = (struct HiddenDeviceListEntry *) AllocPooled(nlcm->pool, sizeof(struct HiddenDeviceListEntry)); + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + + (void) unused; + + if (hde) + { + const struct NewHiddenDevice *nhd = (const struct NewHiddenDevice *) nlcm->entry; + + stccpy(hde->hde_DeviceName, nhd->nhd_DeviceName, sizeof(hde->hde_DeviceName) - 1); + stccpy(hde->hde_VolumeName, nhd->nhd_VolumeName, sizeof(hde->hde_VolumeName) - 1); + + hde->hde_CheckboxObjectIndex = HiddenDevicesImageIndex++; + hde->hde_EntryIndex = HiddenDevicesEntryIndex++; + + hde->hde_Hidden = nhd->nhd_Hidden; + + hde->hde_CheckboxImage = ImageObject, + ImageButtonFrame, +// MUIA_InputMode, MUIV_InputMode_Toggle, + MUIA_InputMode, MUIV_InputMode_Immediate, + MUIA_Image_Spec, MUII_CheckMark, + MUIA_Image_FreeVert, TRUE, + MUIA_Selected, hde->hde_Hidden, + MUIA_Background, MUII_ButtonBack, + MUIA_ShowSelState, FALSE, + MUIA_CycleChain, TRUE, + End; + + d1(KPrintF(__FUNC__ "/%ld: <%s> hde_CheckboxImage=%08lx\n", __LINE__, hde->hde_DeviceName, hde->hde_CheckboxImage)); + + DoMethod(app->Obj[NLIST_HIDDENDEVICES], MUIM_NList_UseImage, + hde->hde_CheckboxImage, hde->hde_CheckboxObjectIndex, 0); + } + + return (APTR) hde; +} + + +static SAVEDS(void) INTERRUPT HiddenDevicesDestructHookFunc(struct Hook *hook, APTR unused, struct NList_DestructMessage *nldm) +{ + struct HiddenDeviceListEntry *hde = (struct HiddenDeviceListEntry *) nldm->entry; + struct SCAModule *app = (struct SCAModule *) hook->h_Data; + + (void) unused; + + if (hde) + { + if (hde->hde_CheckboxImage) + { + DoMethod(app->Obj[NLIST_HIDDENDEVICES], MUIM_NList_UseImage, NULL, hde->hde_CheckboxObjectIndex, 0); + + MUI_DisposeObject(hde->hde_CheckboxImage); + hde->hde_CheckboxImage = NULL; + } + + FreePooled(nldm->pool, hde, sizeof(struct HiddenDeviceListEntry)); + } +} + + +static SAVEDS(ULONG) INTERRUPT HiddenDevicesDisplayHookFunc(struct Hook *hook, APTR unused, struct NList_DisplayMessage *nldm) +{ + (void) unused; + + if (nldm->entry) + { + struct HiddenDeviceListEntry *hde = (struct HiddenDeviceListEntry *) nldm->entry; + + snprintf(hde->hde_CheckboxString, sizeof(hde->hde_CheckboxString), "\033o[%lu@%lu]", + (unsigned long) hde->hde_CheckboxObjectIndex, + (unsigned long) nldm->entry_pos); + + nldm->strings[0] = hde->hde_CheckboxString; + if (hde->hde_VolumeName[0]) + nldm->strings[1] = hde->hde_VolumeName; + else + nldm->strings[1] = hde->hde_DeviceName; + + nldm->preparses[0] = MUIX_C; + nldm->preparses[2] = MUIX_C; + } + else + { + // display titles + nldm->strings[0] = ""; + nldm->strings[1] = ""; + } + + return 0; +} + +//---------------------------------------------------------------------------- + +static SAVEDS(LONG) INTERRUPT HiddenDevicesCompareHookFunc(struct Hook *hook, APTR unused, struct NList_CompareMessage *ncm) +{ +// struct PatternPrefsInst *inst = (struct PatternPrefsInst *) hook->h_Data; + const struct HiddenDeviceListEntry *hde1 = (const struct HiddenDeviceListEntry *) ncm->entry1; + const struct HiddenDeviceListEntry *hde2 = (const struct HiddenDeviceListEntry *) ncm->entry2; + + return Stricmp(hde1->hde_DeviceName, hde2->hde_DeviceName); +} + +//---------------------------------------------------------------------------- + +void SetThumbNailSize(struct SCAModule *app, UWORD ThumbnailSize) +{ + ULONG SizeIndex; + + if (ThumbnailSize <= 16) + SizeIndex = THUMBNAILSIZE_16; + else if (ThumbnailSize <= 24) + SizeIndex = THUMBNAILSIZE_24; + else if (ThumbnailSize <= 32) + SizeIndex = THUMBNAILSIZE_32; + else if (ThumbnailSize <= 48) + SizeIndex = THUMBNAILSIZE_48; + else if (ThumbnailSize <= 64) + SizeIndex = THUMBNAILSIZE_64; + else if (ThumbnailSize <= 96) + SizeIndex = THUMBNAILSIZE_96; + else + SizeIndex = THUMBNAILSIZE_128; + + set(app->Obj[CYCLE_THUMBNAILSIZE], MUIA_Cycle_Active, SizeIndex); + + CallHookPkt(&ChangeThumbnailSizeHook, app->Obj[CYCLE_THUMBNAILSIZE], NULL); +} + +//---------------------------------------------------------------------------- + +UWORD GetThumbNailSize(struct SCAModule *app) +{ + ULONG SizeIndex; + UWORD Size; + + SizeIndex = getv(app->Obj[CYCLE_THUMBNAILSIZE], MUIA_Cycle_Active); + + switch (SizeIndex) + { + case THUMBNAILSIZE_16: + Size = 16; + break; + case THUMBNAILSIZE_24: + Size = 24; + break; + case THUMBNAILSIZE_32: + Size = 32; + break; + case THUMBNAILSIZE_48: + Size = 48; + break; + case THUMBNAILSIZE_64: + Size = 64; + break; + case THUMBNAILSIZE_96: + Size = 96; + break; + case THUMBNAILSIZE_128: + default: + Size = 128; + } + + return Size; +} + +//---------------------------------------------------------------------------- + +void SetIconSizeConstraints(struct SCAModule *app, const struct Rectangle *SizeConstraints) +{ + ULONG MinSize, MaxSize; + + if (SizeConstraints->MinX < 16) + MinSize = ICONSIZEMIN_Unlimited; + else if (SizeConstraints->MinX < 24) + MinSize = ICONSIZEMIN_16; + else if (SizeConstraints->MinX < 32) + MinSize = ICONSIZEMIN_24; + else if (SizeConstraints->MinX < 48) + MinSize = ICONSIZEMIN_32; + else if (SizeConstraints->MinX < 64) + MinSize = ICONSIZEMIN_48; + else if (SizeConstraints->MinX < 96) + MinSize = ICONSIZEMIN_64; + else if (SizeConstraints->MinX < 128) + MinSize = ICONSIZEMIN_96; + else + MinSize = ICONSIZEMIN_128; + + if (SizeConstraints->MaxX <= 16) + MaxSize = ICONSIZEMAX_16; + else if (SizeConstraints->MaxX <= 24) + MaxSize = ICONSIZEMAX_24; + else if (SizeConstraints->MaxX <= 32) + MaxSize = ICONSIZEMAX_32; + else if (SizeConstraints->MaxX <= 48) + MaxSize = ICONSIZEMAX_48; + else if (SizeConstraints->MaxX <= 64) + MaxSize = ICONSIZEMAX_64; + else if (SizeConstraints->MaxX <= 96) + MaxSize = ICONSIZEMAX_96; + else if (SizeConstraints->MaxX <= 128) + MaxSize = ICONSIZEMAX_128; + else + MaxSize = ICONSIZEMAX_Unlimited; + + set(app->Obj[CYCLE_ICONMINSIZE], MUIA_Cycle_Active, MinSize); + set(app->Obj[CYCLE_ICONMAXSIZE], MUIA_Cycle_Active, MaxSize); + + AdjustIconSizeSample(app, SizeConstraints); +} + +//---------------------------------------------------------------------------- + +void GetIconSizeConstraints(struct SCAModule *app, struct Rectangle *SizeConstraints) +{ + ULONG MinSize, MaxSize; + + MinSize = getv(app->Obj[CYCLE_ICONMINSIZE], MUIA_Cycle_Active); + MaxSize = getv(app->Obj[CYCLE_ICONMAXSIZE], MUIA_Cycle_Active); + + switch (MinSize) + { + case ICONSIZEMIN_16: + SizeConstraints->MinX = SizeConstraints->MinY = 16; + break; + case ICONSIZEMIN_24: + SizeConstraints->MinX = SizeConstraints->MinY = 24; + break; + case ICONSIZEMIN_32: + SizeConstraints->MinX = SizeConstraints->MinY = 32; + break; + case ICONSIZEMIN_48: + SizeConstraints->MinX = SizeConstraints->MinY = 48; + break; + case ICONSIZEMIN_64: + SizeConstraints->MinX = SizeConstraints->MinY = 64; + break; + case ICONSIZEMIN_96: + SizeConstraints->MinX = SizeConstraints->MinY = 96; + break; + case ICONSIZEMIN_128: + SizeConstraints->MinX = SizeConstraints->MinY = 128; + break; + case ICONSIZEMIN_Unlimited: + default: + SizeConstraints->MinX = SizeConstraints->MinY = 0; + break; + } + + switch (MaxSize) + { + case ICONSIZEMAX_16: + SizeConstraints->MaxX = SizeConstraints->MaxY = 16; + break; + case ICONSIZEMAX_24: + SizeConstraints->MaxX = SizeConstraints->MaxY = 24; + break; + case ICONSIZEMAX_32: + SizeConstraints->MaxX = SizeConstraints->MaxY = 32; + break; + case ICONSIZEMAX_48: + SizeConstraints->MaxX = SizeConstraints->MaxY = 48; + break; + case ICONSIZEMAX_64: + SizeConstraints->MaxX = SizeConstraints->MaxY = 64; + break; + case ICONSIZEMAX_96: + SizeConstraints->MaxX = SizeConstraints->MaxY = 96; + break; + case ICONSIZEMAX_128: + SizeConstraints->MaxX = SizeConstraints->MaxY = 128; + break; + case ICONSIZEMAX_Unlimited: + default: + SizeConstraints->MaxX = SizeConstraints->MaxY = SHRT_MAX; + break; + } +} + +//---------------------------------------------------------------------------- + +void AdjustIconSizeSample(struct SCAModule *app, const struct Rectangle *SizeConstraints) +{ + ULONG MinSampleIndex, MaxSampleIndex; + + if (SizeConstraints->MinX < 16) + MinSampleIndex = 0; + else if (SizeConstraints->MinX < 24) + MinSampleIndex = 1; + else if (SizeConstraints->MinX < 32) + MinSampleIndex = 2; + else if (SizeConstraints->MinX < 48) + MinSampleIndex = 3; + else if (SizeConstraints->MinX < 64) + MinSampleIndex = 4; + else if (SizeConstraints->MinX < 96) + MinSampleIndex = 5; + else if (SizeConstraints->MinX < 128) + MinSampleIndex = 6; + else + MinSampleIndex = 7; + + if (SizeConstraints->MaxX <= 16) + MaxSampleIndex = 1; + else if (SizeConstraints->MaxX <= 24) + MaxSampleIndex = 2; + else if (SizeConstraints->MaxX <= 32) + MaxSampleIndex = 3; + else if (SizeConstraints->MaxX <= 48) + MaxSampleIndex = 4; + else if (SizeConstraints->MaxX <= 64) + MaxSampleIndex = 5; + else if (SizeConstraints->MaxX <= 96) + MaxSampleIndex = 6; + else if (SizeConstraints->MaxX <= 128) + MaxSampleIndex = 7; + else + MaxSampleIndex = 0; + + set(app->Obj[GOUP_ICONSIZE_MIN_SAMPLE], MUIA_Group_ActivePage, MinSampleIndex); + set(app->Obj[GOUP_ICONSIZE_MAX_SAMPLE], MUIA_Group_ActivePage, MaxSampleIndex); + + d1(KPrintF("%s/%s/%ld: MinSampleIndex=%lu MaxSampleIndex=%lu", __FILE__, __FUNC__, __LINE__, MinSampleIndex, MaxSampleIndex);) +} + +//---------------------------------------------------------------------------- + +static void EnableIconFontPrefs(struct SCAModule *app) +{ + ULONG EnableFontSet; + BPTR fLock; + + // check if font prefs available + fLock = Lock(SYS_FONTPREFS_NAME, ACCESS_READ); + if (fLock) + { + EnableFontSet = FALSE; + UnLock(fLock); + } + else + { + EnableFontSet = TRUE; + } + set(app->Obj[GROUP_ICONFONT_NOTICE], MUIA_ShowMe, !EnableFontSet); + set(app->Obj[GROUP_ICONFONT_SELECT], MUIA_ShowMe, EnableFontSet); +} + +//---------------------------------------------------------------------------- + +// Checks if a certain version of a MCC is available +BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev) +{ + BOOL flush = TRUE; + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: %s ", __LINE__, name);) + + while (1) + { + ULONG ver = 0; + ULONG rev = 0; + struct Library *base; + char libname[256]; + + // First we attempt to acquire the version and revision through MUI + Object *obj = MUI_NewObject((STRPTR) name, TAG_DONE); + if (obj) + { + get(obj, MUIA_Version, &ver); + get(obj, MUIA_Revision, &rev); + + MUI_DisposeObject(obj); + + if(ver > minver || (ver == minver && rev >= minrev)) + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: v%ld.%ld found through MUIA_Version/Revision\n", __LINE__, ver, rev);) + return TRUE; + } + } + + // If we did't get the version we wanted, let's try to open the + // libraries ourselves and see what happens... + stccpy(libname, "PROGDIR:mui", sizeof(libname)); + AddPart(libname, name, sizeof(libname)); + + if ((base = OpenLibrary(&libname[8], 0)) || (base = OpenLibrary(&libname[0], 0))) + { + UWORD OpenCnt = base->lib_OpenCnt; + + ver = base->lib_Version; + rev = base->lib_Revision; + + CloseLibrary(base); + + // we add some additional check here so that eventual broken .mcc also have + // a chance to pass this test (i.e. Toolbar.mcc is broken) + if (ver > minver || (ver == minver && rev >= minrev)) + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: v%ld.%ld found through OpenLibrary()\n", __LINE__, ver, rev);) + return TRUE; + } + + if (OpenCnt > 1) + { + if (MUI_Request(NULL, NULL, 0L, + (STRPTR) GetLocString(MSGID_STARTUP_FAILURE), + (STRPTR) GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), + (STRPTR) GetLocString(MSGID_STARTUP_MCC_IN_USE), + name, minver, minrev, ver, rev)) + { + flush = TRUE; + } + else + break; + } + + // Attempt to flush the library if open count is 0 or because the + // user wants to retry (meaning there's a chance that it's 0 now) + + if (flush) + { + struct Library *result; + + Forbid(); + if ((result = (struct Library *) FindName(&((struct ExecBase *)SysBase)->LibList, name))) + RemLibrary(result); + Permit(); + flush = FALSE; + } + else + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: couldn`t find minimum required version.\n", __LINE__);) + + // We're out of luck - open count is 0, we've tried to flush + // and still haven't got the version we want + if (MUI_Request(NULL, NULL, 0L, + (STRPTR) GetLocString(MSGID_STARTUP_FAILURE), + (STRPTR) GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), + (STRPTR) GetLocString(MSGID_STARTUP_OLD_MCC), + name, minver, minrev, ver, rev)) + { + flush = TRUE; + } + else + break; + } + } + else + { + // No MCC at all - no need to attempt flush + flush = FALSE; + if (!MUI_Request(NULL, NULL, 0L, + (STRPTR) GetLocString(MSGID_STARTUP_FAILURE), + (STRPTR) GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), + (STRPTR) GetLocString(MSGID_STARTUP_MCC_NOT_FOUND), + name, minver, minrev)) + { + break; + } + } + } + + return FALSE; +} + +//----------------------------------------------------------------------------- + +struct TagItem *ScalosVTagList(ULONG FirstTag, va_list args) +{ + struct TagItem *ClonedTagList; + ULONG AllocatedSize = 10; + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: FirstTag=%08lx args=%08lx\n", __LINE__, FirstTag, args)); + + do { + ULONG NumberOfTags = 1; + BOOL Finished = FALSE; + struct TagItem *ti; + + ClonedTagList = ti = AllocateTagItems(AllocatedSize); + if (NULL == ClonedTagList) + break; + + ClonedTagList->ti_Tag = FirstTag; + while (!Finished) + { + switch (ti->ti_Tag) + { + case TAG_MORE: + ti->ti_Data = va_arg(args, ULONG); + Finished = TRUE; + break; + case TAG_END: + Finished = TRUE; + break; + default: + ti->ti_Data = va_arg(args, ULONG); + break; + } + + d1(KPrintF(__FUNC__ "/%ld ti=%08lx Tag=%08lx Data=%08lx\n", __LINE__, ti, ti->ti_Tag, ti->ti_Data)); + + if (!Finished) + { + if (++NumberOfTags >= AllocatedSize) + { + // we need to extend our allocated taglist + struct TagItem *ExtendedTagList; + ULONG ExtendedSize = 2 * AllocatedSize; + + ExtendedTagList = AllocateTagItems(ExtendedSize); + if (NULL == ExtendedTagList) + { + FreeTagItems(ClonedTagList); + ClonedTagList = NULL; + break; + } + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: ExtendedTagList=%08lx ClonedTagList=%08lx\n", __LINE__, ExtendedTagList, ClonedTagList)); + + // copy contents from old to extended taglist + memcpy(ExtendedTagList, ClonedTagList, sizeof(struct TagItem) * AllocatedSize); + + // free old taglist + FreeTagItems(ClonedTagList); + ClonedTagList = ExtendedTagList; + + ti = ClonedTagList + NumberOfTags - 1; + AllocatedSize = ExtendedSize; + } + else + { + ti++; + } + + ti->ti_Tag = va_arg(args, ULONG); + } + } + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: NumberOfTags=%lu AllocatedSize=%lu\n", __LINE__, NumberOfTags, AllocatedSize)); + } while (0); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: ClonedTagList=%08lx\n", __LINE__, ClonedTagList)); + + d1({ ULONG n; \ + for (n = 0; ClonedTagList; n++) \ + { \ + KPrintF(__FILE__ "/" __FUNC__ "/%ld: TagList[%ld]: Tag=%08lx Data=%08lx\n", \ + __LINE__, n, ClonedTagList[n].ti_Tag, ClonedTagList[n].ti_Data); \ + if (TAG_END == ClonedTagList[n].ti_Tag || TAG_MORE == ClonedTagList[n].ti_Tag) + break; + } \ + }) + + return ClonedTagList; +} + +//---------------------------------------------------------------------------- + +static void InitControlBarGadgets(struct SCAModule *app) +{ + ULONG n; + + d1(KPrintF(__FILE__ "/%s/%ld: START\n", __FUNC__, __LINE__)); + + // Initialize list of available control bar gadgets + for (n = 0; n < Sizeof(DefaultControlBarGadgets); n++) + { + struct ControlBarGadgetEntry cgy; + + memset(&cgy, 0, sizeof(cgy)); + + cgy.cgy_GadgetType = DefaultControlBarGadgets[n].cyi_GadgetType; + cgy.cgy_NormalImage = (STRPTR) DefaultControlBarGadgets[n].cyi_NormalImage; + cgy.cgy_SelectedImage = (STRPTR) DefaultControlBarGadgets[n].cyi_SelectedImage; + cgy.cgy_DisabledImage = (STRPTR) DefaultControlBarGadgets[n].cyi_DisabledImage; + + d1(KPrintF(__FILE__ "/%s/%ld: add image cgy_NormalImage=<%s>\n", __FUNC__, __LINE__, cgy.cgy_NormalImage)); + + DoMethod(app->Obj[NLIST_CONTROLBARGADGETS_BROWSER_AVAILABLE], MUIM_NList_InsertSingle, &cgy, MUIV_NList_Insert_Bottom); + DoMethod(app->Obj[NLIST_CONTROLBARGADGETS_NORMAL_AVAILABLE], MUIM_NList_InsertSingle, &cgy, MUIV_NList_Insert_Bottom); + } + + d1(KPrintF(__FILE__ "/%s/%ld: END\n", __FUNC__, __LINE__)); +} + +//---------------------------------------------------------------------------- + +static void SetupNewPrefsPages(struct SCAModule *app) +{ + struct NewPageListEntry *nple = NewPrefsPages; + ULONG n; + + d1(KPrintF(__FILE__ "/%s/%ld: START\n", __FUNC__, __LINE__)); + + for (n = 0; n < Sizeof(cPrefGroups); n++) + { + nple->nple_TitleString = GetLocString(cPrefGroups[n]); + nple->nple_TitleImage = app->Obj[n + IMAGE_ABOUT]; + nple->nple_ImageIndex = n; + nple->nple_CreateTitleImage = CreatePrefsImage; + nple->nple_UserData = (void *) (n + IMAGE_ABOUT); + + d1(KPrintF(__FILE__ "/%s/%ld: nple=%08lx nple_ImageIndex=%lu nple_TitleString=<%s> nple_TitleImage=%08lx\n", \ + __FUNC__, __LINE__, nple, nple->nple_ImageIndex, \ + nple->nple_TitleString, nple->nple_TitleImage)); + + nple++; + } + + d1(KPrintF(__FILE__ "/%s/%ld: END\n", __FUNC__, __LINE__)); +} + +//---------------------------------------------------------------------------- + +Object *CreatePrefsPage(struct SCAModule *app, Object *Page, struct NewPageListEntry *nple) +{ + Object *result = NULL; + + if (Page) + { + Object *nlistview; + +#if defined(MUIA_Scrollgroup_AutoBars) + result = ScrollgroupObject, + MUIA_Scrollgroup_AutoBars, TRUE, + MUIA_Scrollgroup_Contents, VGroupV, +#else //MUIA_Scrollgroup_AutoBars + result = VGroupV, +#endif //MUIA_Scrollgroup_AutoBars + MUIA_Group_VertSpacing, 0, + Child, nlistview = NListviewObject, + MUIA_VertWeight, 0, + MUIA_InputMode, MUIV_InputMode_None, + MUIA_NListview_Horiz_ScrollBar, MUIV_NListview_HSB_None, + MUIA_NListview_Vert_ScrollBar, MUIV_NListview_VSB_None, + MUIA_NListview_NList, NListObject, + ReadListFrame, + MUIA_VertWeight, 0, + MUIA_Font, MUIV_Font_Big, + MUIA_Background, MUII_ListBack, + MUIA_NList_DefaultObjectOnClick, FALSE, + MUIA_NList_DisplayHook2, (ULONG) &PageListDisplayHook, + MUIA_NList_ConstructHook2, (ULONG) &PageListConstructHook, + MUIA_NList_DestructHook2, (ULONG) &PageListDestructHook, + MUIA_NList_Format, (ULONG) ",", + MUIA_NList_ShowDropMarks, FALSE, + MUIA_NList_Input, FALSE, + MUIA_NList_AdjustHeight, TRUE, + MUIA_NList_MultiSelect, MUIV_NList_MultiSelect_None, + End, //NListObject + MUIA_Listview_MultiSelect, MUIV_Listview_MultiSelect_None, + MUIA_Listview_DragType, MUIV_Listview_DragType_None, +// MUIA_ShortHelp, (ULONG) GetLocString(MSGID_PREFGROUPS_SHORTHELP), + End, //NListviewObject + Child, Page, +#if defined(MUIA_Scrollgroup_AutoBars) + End, //VGroupV + End; //ScrollgroupObject +#else //defined(MUIA_Scrollgroup_AutoBars) + End; //VGroupV +#endif //defined(MUIA_Scrollgroup_AutoBars) + + + if (result) + { + DoMethod(app->Obj[LISTVIEW], MUIM_NList_InsertSingle, + nple, + MUIV_NList_Insert_Bottom); + DoMethod(nlistview, MUIM_NList_InsertSingle, + nple, + MUIV_NList_Insert_Bottom); + + if (nple->nple_CreateTitleImage) + { + DoMethod(app->Obj[LISTVIEW], MUIM_NList_UseImage, + nple->nple_CreateTitleImage(nple->nple_UserData), + nple->nple_ImageIndex, 0); + DoMethod(nlistview, MUIM_NList_UseImage, + nple->nple_CreateTitleImage(nple->nple_UserData), + nple->nple_ImageIndex, 0); + } + } + } + + return result; +} + +//---------------------------------------------------------------------------- + +#if !defined(__SASC) && !defined(__amigaos4__) +// Replacement for SAS/C library functions + +size_t stccpy(char *dest, const char *src, size_t MaxLen) +{ + size_t Count = 0; + + while (*src && MaxLen > 1) + { + *dest++ = *src++; + MaxLen--; + Count++; + } + *dest = '\0'; + Count++; + + return Count; +} + +#endif /* !__SASC && !__amigaos4__ */ + +//----------------------------------------------------------------- + +static Object *GenerateAboutPage(struct SCAModule *app, CONST_STRPTR cVersion, CONST_STRPTR urlSubject) +{ +/// + static char prefsVersion[60]; + static char aboutPageCopyRight[120] = ""; + + snprintf(prefsVersion, sizeof(prefsVersion), GetLocString(MSGID_ABOUTPAGE_PREFSVERSION), VERSION_MAJOR, VERSION_MINOR); + snprintf(aboutPageCopyRight, sizeof(aboutPageCopyRight), GetLocString(MSGID_ABOUTPAGE_COPYRIGHT), CURRENTYEAR); + + return CreatePrefsPage(app, + VGroup, +// MUIA_Background, MUII_PageBack, + MUIA_Background, "5:THEME:SplashBackground", + + Child, HVSpace, + + Child, HGroup, + Child, HVSpace, + + Child, VGroup, + Child, DataTypesImageObject, + MUIA_ScaDtpic_Name, (ULONG) "THEME:ScalosSplashLogo", + End, //DataTypesMCCObject + + Child, TextObject, + MUIA_Font, MUIV_Font_Big, + MUIA_Text_PreParse, MUIX_C, + MUIA_Text_Contents, (ULONG) cVersion, + End, //Text + + Child, HVSpace, + + Child, TextObject, + MUIA_Font, MUIV_Font_Title, + MUIA_Text_PreParse, MUIX_C, + MUIA_Text_Contents, (ULONG) prefsVersion, + End, //Text + + Child, TextObject, + MUIA_Font, MUIV_Font_Title, + MUIA_Text_PreParse, MUIX_C, + MUIA_Text_Contents, COMPILER_STRING, + End, //Text + + End, //VGroup + + Child, HVSpace, + End, //HGroup + + + Child, HVSpace, + + Child, VGroup, + TextFrame, + MUIA_InputMode, MUIV_InputMode_None, + MUIA_Background, MUII_TextBack, + + Child, TextObject, + MUIA_Text_SetMax, FALSE, + MUIA_Text_Contents, (ULONG) aboutPageCopyRight, + End, //Text + + Child, HGroup, + MUIA_Group_HorizSpacing, 0, + + Child, HVSpace, + + Child, HGroup, + MUIA_Group_HorizSpacing, 0, + + Child, TextObject, + MUIA_Text_Contents, (ULONG) GetLocString(MSGID_ABOUTPAGE_CONTACT1), + End, //Text + + Child, UrltextObject, + MUIA_Urltext_Text, "Scalos@VFEmail.net", + MUIA_Urltext_Url, (ULONG) urlSubject, // +jmc+ + MUIA_Urltext_SetMax, FALSE, + End, //URLText + + Child, TextObject, + MUIA_Text_Contents, (ULONG) GetLocString(MSGID_ABOUTPAGE_CONTACT2), + End, //Text + + Child, UrltextObject, + MUIA_Urltext_Text, "scalos.noname.fr", + MUIA_Urltext_Url, "http://scalos.noname.fr", + MUIA_Urltext_SetMax, FALSE, + End, //URLText + + Child, TextObject, + MUIA_Text_Contents, (ULONG) GetLocString(MSGID_ABOUTPAGE_CONTACT3), + End, //Text + End, //HGroup + + Child, HVSpace, + End, //HGroup + + End, //VGroup + + End, //VGroup + &NewPrefsPages[0]); +/// +} + +//----------------------------------------------------------------- + +static Object *GeneratePathsPage(struct SCAModule *app) +{ +/// + return CreatePrefsPage(app, + VGroup, + MUIA_Background, MUII_PageBack, + + Child, HVSpace, + + Child, VGroup, + MUIA_Background, MUII_GroupBack, + GroupFrame, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_PATHSPAGE_DEFAULTPATHS), + + Child, HVSpace, + + Child, ColGroup(2), + Child, Label2((ULONG) GetLocString(MSGID_PATHSPAGE_SCALOS_HOME)), + Child, app->Obj[STRING_SCALOSHOME] = PopaslObject, + MUIA_CycleChain, TRUE, + MUIA_Popstring_Button, PopButton(MUII_PopDrawer), + MUIA_Popstring_String, BetterStringObject, + StringFrame, + MUIA_String_Contents, "SYS:", + End, //BetterString + ASLFR_TitleText, (ULONG) GetLocString(MSGID_PATHSPAGE_SCALOS_HOME_ASLTITLE), + ASLFR_DrawersOnly, TRUE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_PATHSPAGE_SCALOS_HOME_SHORTHELP), + End, //Pop + + Child, Label2((ULONG) GetLocString(MSGID_PATHSPAGE_THEMES)), + Child, app->Obj[STRING_THEMES] = PopaslObject, + MUIA_CycleChain, TRUE, + MUIA_Popstring_Button, PopButton(MUII_PopDrawer), + MUIA_Popstring_String, BetterStringObject, + StringFrame, + MUIA_String_Contents, "SCALOS:Themes/", + End, //BetterString + ASLFR_TitleText, (ULONG) GetLocString(MSGID_PATHSPAGE_THEMES_ASLTITLE), + ASLFR_DrawersOnly, TRUE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_PATHSPAGE_THEMES_SHORTHELP), + End, //Pop + + Child, Label2((ULONG) GetLocString(MSGID_PATHSPAGE_DEFAULTICONS)), + Child, app->Obj[STRING_DEFICONPATH] = PopaslObject, + MUIA_CycleChain, TRUE, + MUIA_Popstring_Button, PopButton(MUII_PopDrawer), + MUIA_Popstring_String, BetterStringObject, + StringFrame, + MUIA_String_Contents, "ENV:Sys/", + End, //BetterString + ASLFR_TitleText, (ULONG) GetLocString(MSGID_PATHSPAGE_DEFAULTICONS_ASLTITLE), + ASLFR_DrawersOnly, TRUE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_PATHSPAGE_DEFAULTICONS_SHORTHELP), + End, //Pop + + Child, Label2((ULONG) GetLocString(MSGID_PATHSPAGE_WBSTARTUP)), + Child, app->Obj[STRING_WBSTARTPATH] = PopaslObject, + MUIA_CycleChain, TRUE, + MUIA_Popstring_Button, PopButton(MUII_PopDrawer), + MUIA_Popstring_String, BetterStringObject, + StringFrame, + MUIA_String_Contents, "SYS:WBStartup/", + End, //BetterString + ASLFR_TitleText, (ULONG) GetLocString(MSGID_PATHSPAGE_WBSTARTUP_ASLTITLE), + ASLFR_DrawersOnly, TRUE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_PATHSPAGE_WBSTARTUP_SHORTHELP), + End, //Pop + + Child, Label2((ULONG) GetLocString(MSGID_PATHSPAGE_IMAGECACHE)), + Child, app->Obj[STRING_IMAGECACHE] = PopaslObject, + MUIA_CycleChain, TRUE, + MUIA_Popstring_Button, PopButton(MUII_PopDrawer), + MUIA_Popstring_String, BetterStringObject, + StringFrame, + MUIA_String_Contents, "t:", + End, //BetterString + ASLFR_TitleText, (ULONG) GetLocString(MSGID_PATHSPAGE_IMAGECACHE_ASLTITLE), + ASLFR_DrawersOnly, TRUE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_PATHSPAGE_IMAGECACHE_SHORTHELP), + End, //Pop + + Child, Label2((ULONG) GetLocString(MSGID_PATHSPAGE_SQLITE3TEMPPATH)), + Child, app->Obj[STRING_SQLITE3TEMPPATH] = PopaslObject, + MUIA_CycleChain, TRUE, + MUIA_Popstring_Button, PopButton(MUII_PopDrawer), + MUIA_Popstring_String, BetterStringObject, + StringFrame, + MUIA_String_Contents, "t:", + End, //BetterString + ASLFR_TitleText, (ULONG) GetLocString(MSGID_PATHSPAGE_SQLITE3TEMPPATH_ASLTITLE), + ASLFR_DrawersOnly, TRUE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_PATHSPAGE_SQLITE3TEMPPATH_SHORTHELP), + End, //Pop + + Child, HVSpace, + Child, HVSpace, + + Child, Label2((ULONG) GetLocString(MSGID_PATHSPAGE_THUMBNAILDB)), + Child, app->Obj[STRING_THUMBNAILDB] = PopaslObject, + MUIA_CycleChain, TRUE, + MUIA_Popstring_Button, PopButton(MUII_PopFile), + MUIA_Popstring_String, BetterStringObject, + StringFrame, + MUIA_String_Contents, "Scalos:Thumbnails.db", + End, //BetterString + ASLFR_TitleText, (ULONG) GetLocString(MSGID_PATHSPAGE_THUMBNAILDB_ASLTITLE), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_PATHSPAGE_THUMBNAILDB_SHORTHELP), + End, //Pop + + Child, Label2((ULONG) GetLocString(MSGID_PATHSPAGE_DISKCOPY)), + Child, app->Obj[STRING_DISKCOPY] = PopaslObject, + MUIA_CycleChain, TRUE, + MUIA_Popstring_Button, PopButton(MUII_PopFile), + MUIA_Popstring_String, BetterStringObject, + StringFrame, + MUIA_String_Contents, "SYS:System/DiskCopy", + End, //BetterString + ASLFR_TitleText, (ULONG) GetLocString(MSGID_PATHSPAGE_DISKCOPY_ASLTITLE), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_PATHSPAGE_DISKCOPY_SHORTHELP), + End, //Pop + + Child, Label2((ULONG) GetLocString(MSGID_PATHSPAGE_FORMAT)), + Child, app->Obj[STRING_FORMAT] = PopaslObject, + MUIA_CycleChain, TRUE, + MUIA_Popstring_Button, PopButton(MUII_PopFile), + MUIA_Popstring_String, BetterStringObject, + StringFrame, + MUIA_String_Contents, "SYS:System/Format", + End, //BetterString + ASLFR_TitleText, (ULONG) GetLocString(MSGID_PATHSPAGE_FORMAT_ASLTITLE), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_PATHSPAGE_FORMAT_SHORTHELP), + End, //Pop + End, //ColumnGroup + + Child, HVSpace, + End, //VGroup + Child, HVSpace, + End, //VGroup + &NewPrefsPages[1]); +/// +} + +//----------------------------------------------------------------- + +static Object *GenerateStartupPage(struct SCAModule *app) +{ +/// + return CreatePrefsPage(app, + VGroup, + MUIA_Background, MUII_PageBack, + Child, HVSpace, + + Child, VGroup, + GroupFrame, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_STARTUPPAGE_SPLASHWINDOW), + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, HGroup, + Child, Label((ULONG) GetLocString(MSGID_STARTUPPAGE_SHOWSPLASHWINDOW)), + Child, app->Obj[CHECK_SHOWSPLASH] = CheckMarkHelp(TRUE, MSGID_STARTUPPAGE_SHOWSPLASHWINDOW_SHORTHELP), + Child, HVSpace, + End, //HGroup + + Child, HGroup, + Child, Label((ULONG) GetLocString(MSGID_STARTUPPAGE_SPLASHCLOSEDELAY)), + Child, app->Obj[SLIDER_SPLASHCLOSE] = SliderObject, + MUIA_CycleChain, 1, + MUIA_Numeric_Min, 1, + MUIA_Numeric_Max, 10, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 5, + End, //Slider + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_STARTUPPAGE_SPLASHCLOSEDELAY_SHORTHELP), + Child, Label((ULONG) GetLocString(MSGID_STARTUPPAGE_DOWAITDELAY_SECONDS)), + End, //HGroup + + Child, HVSpace, + + End, //VGroup + + Child, VGroup, + GroupFrame, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_STARTUPPAGE_WBSTARTUP), + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, HGroup, + Child, Label((ULONG) GetLocString(MSGID_STARTUPPAGE_DOWAITDELAY)), + Child, app->Obj[SLIDER_WBSDELAY] = SliderObject, + MUIA_CycleChain, 1, + MUIA_Weight, 500, + MUIA_Numeric_Min, 1, + MUIA_Numeric_Max, 10, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 2, + End, //Slider + Child, Label((ULONG) GetLocString(MSGID_STARTUPPAGE_DOWAITDELAY_SECONDS)), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_STARTUPPAGE_DOWAITDELAY_SHORTHELP), + End, //HGroup + + Child, HVSpace, + End, //VGroup + + Child, HVSpace, + + End, //VGroup + &NewPrefsPages[2]); +/// +} + +//----------------------------------------------------------------- + +static Object *GenerateDesktopPage(struct SCAModule *app) +{ +/// + return CreatePrefsPage(app, + VGroup, + MUIA_Background, MUII_PageBack, + + Child, RegisterObject, + MUIA_Register_Titles, cDesktopPages, + MUIA_CycleChain, TRUE, + + // --- Desktop-Screen + Child, app->Obj[GROUP_SCRTITLE] = VGroup, + Child, HVSpace, + + Child, VGroup, + GroupFrame, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_DESKTOPPAGE_SCREENTITLEBAR), + MUIA_Background, MUII_GroupBack, + + Child, HGroup, + Child, Label2((ULONG) GetLocString(MSGID_DESKTOPPAGE_SCREEN)), + Child, app->Obj[POPPH_SCREENTITLE] = PopplaceholderObject, + MUIA_Popph_Title, (ULONG) GetLocString(MSGID_DESKTOPPAGE_SCREEN_DESCRIPTION), + MUIA_Popph_Array, cTitleph, + MUIA_Popph_Avoid, MUIV_Popph_Avoid_Textinput, + MUIA_Popph_ReplaceMode, FALSE, + MUIA_Popph_Contents, "", + MUIA_Popph_StringMaxLen, 1000, + End, //Popplaceholder + End, //HGroup + + + Child, HGroup, + Child, Label2((ULONG) GetLocString(MSGID_DESKTOPPAGE_TITLEBAR_REFRESH)), + Child, app->Obj[SLIDER_TITLEREFRESH] = SliderObject, + MUIA_CycleChain, 1, + MUIA_Numeric_Min, 1, + MUIA_Numeric_Max, 10, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 5, + End, //Slider + Child, Label((ULONG) GetLocString(MSGID_DESKTOPPAGE_TITLEBAR_REFRESH_SECONDS)), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_DESKTOPPAGE_TITLEBAR_REFRESH_SHORTHELP), + End, //HGroup + + Child, HGroup, + Child, HVSpace, + Child, Label1((ULONG) GetLocString(MSGID_DESKTOPPAGE_TITLEBAR_REFRESH_MEMCHANGE)), + Child, app->Obj[CHECK_TITLEMEM] = CheckMarkHelp(FALSE, MSGID_DESKTOPPAGE_TITLEBAR_REFRESH_MEMCHANGE_SHORTHELP), + Child, HVSpace, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_DESKTOPPAGE_TITLEBAR_REFRESH_MEMCHANGE_SHORTHELP), + End, //HGroup + + Child, HVSpace, + + Child, HGroup, + Child, Label1((ULONG) GetLocString(MSGID_DESKTOPPAGE_SCREENTITLE_MODE)), + Child, app->Obj[CYCLE_SCREENTITLEMODE] = CycleObject, + MUIA_CycleChain, TRUE, + MUIA_Cycle_Entries, cScreenTitleModes, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_DESKTOPPAGE_SCREENTITLE_MODE_SHORTHELP), + End, //Cycle + End, //HGroup + End, //VGroup + + Child, HVSpace, + End, //VGroup + + // Desktop -- Icons + Child, VGroup, + Child, HVSpace, + + Child, VGroup, + GroupFrame, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_DESKTOPPAGE_DESKTOP_REFRESH), + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, HGroup, + Child, Label2((ULONG) GetLocString(MSGID_DESKTOPPAGE_DISK_ICON_RATE)), + Child, app->Obj[SLIDER_DISKREFRESH] = SliderObject, + MUIA_CycleChain, 1, + MUIA_Weight, 500, + MUIA_Numeric_Min, 1, + MUIA_Numeric_Max, 10, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 2, + End, //Slider + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_DESKTOPPAGE_DISK_ICON_RATE_SHORTHELP), + Child, Label((ULONG) GetLocString(MSGID_DESKTOPPAGE_DISK_ICON_RATE_SECONDS)), + End, //HGroup + + Child, HVSpace, + + End, //VGroup + + Child, HVSpace, + + Child, VGroup, + GroupFrame, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_DESKTOPPAGE_ICONS_HIDDENDEVICES), + MUIA_Background, MUII_GroupBack, + + // Child, HVSpace, + + Child, app->Obj[NLISTVIEW_HIDDENDEVICES] = NListviewObject, + MUIA_CycleChain, TRUE, + // MUIA_Listview_Input, TRUE, + MUIA_Listview_DragType, MUIV_Listview_DragType_None, + MUIA_Listview_MultiSelect, MUIV_Listview_MultiSelect_None, + MUIA_NListview_Vert_ScrollBar, MUIV_NListview_VSB_FullAuto, + MUIA_NListview_NList, app->Obj[NLIST_HIDDENDEVICES] = NListObject, + MUIA_NList_DefaultObjectOnClick, TRUE, + MUIA_NList_DragSortable, FALSE, + MUIA_Background, MUII_ListBack, + InputListFrame, + MUIA_NList_DisplayHook2, (ULONG) &HiddenDevicesDisplayHook, + MUIA_NList_ConstructHook2, (ULONG) &HiddenDevicesConstructHook, + MUIA_NList_DestructHook2, (ULONG) &HiddenDevicesDestructHook, + MUIA_NList_CompareHook2, &HiddenDevicesCompareHook, + MUIA_NList_SortType, 0, + MUIA_NList_TitleMark, MUIV_NList_TitleMark_Down | 0, + MUIA_NList_Format, (ULONG) ",", + MUIA_NList_ShowDropMarks, FALSE, + MUIA_NList_AdjustHeight, TRUE, + End, //NListObject + End, //NListviewObject + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_DESKTOPPAGE_HIDDENDEVICES_SHORTHELP), + End, //HGroup + + Child, HVSpace, + + End, //VGroup + + // Desktop -- Layout + Child, VGroup, + Child, HVSpace, + + Child, VGroup, + GroupFrame, + MUIA_Background, MUII_GroupBack, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_DESKTOPPAGE_LAYOUTPREFERENCES), + + Child, ColGroup(2), + Child, Label1((ULONG) GetLocString(MSGID_DESKTOPPAGE_LAYOUT_WBDISK)), + Child, app->Obj[CYCLE_DESKTOP_LAYOUT_WBDISK] = CycleObject, + MUIA_Cycle_Entries, cIconLayoutModes, + MUIA_CycleChain, TRUE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_DESKTOPPAGE_LAYOUT_WBDISK_SHORTHELP), + End, //Cycle + Child, Label1((ULONG) GetLocString(MSGID_DESKTOPPAGE_LAYOUT_WBDRAWER)), + Child, app->Obj[CYCLE_DESKTOP_LAYOUT_WBDRAWER] = CycleObject, + MUIA_Cycle_Entries, cIconLayoutModes, + MUIA_CycleChain, TRUE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_DESKTOPPAGE_LAYOUT_WBDRAWER_SHORTHELP), + End, //Cycle + Child, Label1((ULONG) GetLocString(MSGID_DESKTOPPAGE_LAYOUT_WBTOOL)), + Child, app->Obj[CYCLE_DESKTOP_LAYOUT_WBTOOL] = CycleObject, + MUIA_Cycle_Entries, cIconLayoutModes, + MUIA_CycleChain, TRUE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_DESKTOPPAGE_LAYOUT_WBTOOL_SHORTHELP), + End, //Cycle + Child, Label1((ULONG) GetLocString(MSGID_DESKTOPPAGE_LAYOUT_WBPROJECT)), + Child, app->Obj[CYCLE_DESKTOP_LAYOUT_WBPROJECT] = CycleObject, + MUIA_Cycle_Entries, cIconLayoutModes, + MUIA_CycleChain, TRUE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_DESKTOPPAGE_LAYOUT_WBPROJECT_SHORTHELP), + End, //Cycle + Child, Label1((ULONG) GetLocString(MSGID_DESKTOPPAGE_LAYOUT_WBGARBAGE)), + Child, app->Obj[CYCLE_DESKTOP_LAYOUT_WBGARBAGE] = CycleObject, + MUIA_Cycle_Entries, cIconLayoutModes, + MUIA_CycleChain, TRUE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_DESKTOPPAGE_LAYOUT_WBGARBAGE_SHORTHELP), + End, //Cycle + Child, Label1((ULONG) GetLocString(MSGID_DESKTOPPAGE_LAYOUT_WBDEVICE)), + Child, app->Obj[CYCLE_DESKTOP_LAYOUT_WBDEVICE] = CycleObject, + MUIA_Cycle_Entries, cIconLayoutModes, + MUIA_CycleChain, TRUE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_DESKTOPPAGE_LAYOUT_WBDEVICE_SHORTHELP), + End, //Cycle + Child, Label1((ULONG) GetLocString(MSGID_DESKTOPPAGE_LAYOUT_WBKICK)), + Child, app->Obj[CYCLE_DESKTOP_LAYOUT_WBKICK] = CycleObject, + MUIA_Cycle_Entries, cIconLayoutModes, + MUIA_CycleChain, TRUE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_DESKTOPPAGE_LAYOUT_WBKICK_SHORTHELP), + End, //Cycle + Child, Label1((ULONG) GetLocString(MSGID_DESKTOPPAGE_LAYOUT_WBAPPICON)), + Child, app->Obj[CYCLE_DESKTOP_LAYOUT_WBAPPICON] = CycleObject, + MUIA_Cycle_Entries, cIconLayoutModes, + MUIA_CycleChain, TRUE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_DESKTOPPAGE_LAYOUT_WBAPPICON_SHORTHELP), + End, //Cycle + End, //ColGroup + + Child, HVSpace, + + End, //VGroup + Child, HVSpace, + End, //VGroup + + // Desktop -- misc + Child, VGroup, + Child, HVSpace, + + Child, VGroup, + GroupFrame, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_DESKTOPPAGE_CONSOLENAME), + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, app->Obj[STRING_CONSOLENAME] = BetterStringObject, + MUIA_CycleChain, TRUE, + StringFrame, + MUIA_String_Contents, "", + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_DESKTOPPAGE_CONSOLENAME_SHORTHELP), + End, //BetterString + + Child, HVSpace, + End, //VGroup + + Child, VGroup, + GroupFrame, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_DESKTOPPAGE_MISCELLANEOUS), + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, HGroup, + Child, HVSpace, + + Child, ColGroup(2), + Child, Label1((ULONG) GetLocString(MSGID_DESKTOPPAGE_ALLOW_CLOSEWB)), + Child, app->Obj[CLOSEWB] = CheckMarkHelp(TRUE, MSGID_DESKTOPPAGE_ALLOW_CLOSEWB_SHORTHELP), + + Child, Label1((ULONG) GetLocString(MSGID_DESKTOPPAGE_DROPSTART)), + Child, app->Obj[DROPSTART] = CheckMarkHelp(TRUE, MSGID_DESKTOPPAGE_DROPSTART_SHORTHELP), + + Child, Label1((ULONG) GetLocString(MSGID_DESKTOPPAGE_AUTOLEAVEOUT)), + Child, app->Obj[CHECK_AUTOLEAVEOUT] = CheckMarkHelp(TRUE, MSGID_DESKTOPPAGE_AUTOLEAVEOUT_SHORTHELP), + End, //ColGroup + + Child, HVSpace, + End, //HGroup + + Child, HVSpace, + End, //VGroup + + Child, VGroup, + GroupFrame, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_DESKTOPPAGE_LASSO), + MUIA_Background, MUII_GroupBack, + + Child, ColGroup(2), + Child, Label1((ULONG) GetLocString(MSGID_DESKTOPPAGE_SINGLEWINDOW_LASSO)), + Child, HGroup, + Child, app->Obj[SINGLE_WINDOW_LASSO_HOTKEY] = HotkeyStringObject, + StringFrame, + MUIA_String_Contents, "", + MUIA_HotkeyString_Snoop, FALSE, + End, //HotkeyString + Child, app->Obj[SINGLE_WINDOW_LASSO_HOTKEY_SCAN] = ScanButton, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_DESKTOPPAGE_SINGLEWINDOW_LASSO_SHORTHELP), + End, //HGroup + End, //ColGroup + End, //VGroup + + Child, HVSpace, + End, //VGroup + End, //RegisterObject + End, //VGroup + &NewPrefsPages[3]); +/// +} + +//----------------------------------------------------------------- + +static Object *GenerateIconsPage(struct SCAModule *app) +{ +/// + return CreatePrefsPage(app, + VGroup, + MUIA_Background, MUII_PageBack, + + Child, RegisterObject, + MUIA_Register_Titles, cIconPages, + MUIA_CycleChain, TRUE, + + // --- Icons-Attributes + Child, VGroup, + + Child, HVSpace, + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_ICONSPAGE_GENERAL), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, HGroup, + Child, HVSpace, + + Child, ColGroup(2), + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_MASKED_CLICKAREA)), + Child, app->Obj[CHECK_ICONMASK] = CheckMarkHelp(FALSE, MSGID_ICONSPAGE_MASKED_CLICKAREA_SHORTHELP), + + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_HILITE_UNDER_MOUSE)), + Child, app->Obj[CHECK_HILITEUNDERMOUSE] = CheckMarkHelp(FALSE, MSGID_ICONSPAGE_HILITE_UNDER_MOUSE_SHORTHELP), +#if 0 + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_MULTISELECTION)), + Child, app->Obj[CHECK_MULTISELECT] = CheckMarkHelp(FALSE, MSGID_ICONSPAGE_MULTISELECTION_SHORTHELP), +#endif + End, //ColGroup + Child, HVSpace, + End, //HGroup + Child, HVSpace, + End, //VGroup + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_ICONSPAGE_NEWICONS), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, HGroup, + + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_NEWICONS_REMAP_PRECISION)), + Child, app->Obj[SLIDER_ICONRMAP_PRECISION] = PrecisionSliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 1, + MUIA_Numeric_Max, 4, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 1, + End, //Slider + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_NEWICONS_REMAP_PRECISION_SHORTHELP), + End, //HGroup + + Child, HGroup, + Child, HVSpace, + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_NEWICONS_TRANSPARENTBG)), + Child, app->Obj[CHECK_NIMASK] = CheckMarkHelp(FALSE, MSGID_ICONSPAGE_NEWICONS_TRANSPARENTBG_SHORTHELP), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_NEWICONS_TRANSPARENTBG_SHORTHELP), + Child, HVSpace, + + End, //HGroup + + Child, HVSpace, + + End, //VGroup + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_ICONSPAGE_DEFICONS), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, HGroup, + Child, HVSpace, + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_DEFICONS_LOADFIRST)), + Child, app->Obj[CHECK_DEFFIRST] = CheckMarkHelp(FALSE, MSGID_ICONSPAGE_DEFICONS_LOADFIRST_SHORTHELP), + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_DEFICONS_SAVEABLE)), + Child, app->Obj[CHECK_ICONSSAVE] = CheckMarkHelp(FALSE, MSGID_ICONSPAGE_DEFICONS_SAVEABLE_SHORTHELP), + Child, HVSpace, + End, //HGroup + + Child, HVSpace, + + Child, HGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_ICONSPAGE_ATTRIBUTES_TRANSPARENCY_DEFICONS), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRANSPARENCY_TRANSPARENT)), + + Child, app->Obj[SLIDER_ICONTRANSPARENCY_DEFICONS] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 100, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 50, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_ATTRIBUTES_TRANSPARENCY_DEFICONS_SHORTHELP), + End, //Slider + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRANSPARENCY_OPAQUE)), + End, //HGroup + + Child, HVSpace, + + End, //VGroup + + Child, HVSpace, + + End, //VGroup + + // --- Icons-Sizes + Child, VGroup, + + Child, HVSpace, + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_ICONSPAGE_ICONSCALING), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, HGroup, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_SCALING_NOMINALSIZE_SHORTHELP), + + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_SCALING_NOMINALSIZE)), + + Child, app->Obj[SLIDER_ICONSPAGE_NOMINALSIZE] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, IDTA_ScalePercentage_MIN, + MUIA_Numeric_Max, IDTA_ScalePercentage_MAX, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 100, + End, //Slider + + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_SCALING_PERCENT)), + End, //HGroup + + Child, HVSpace, + + Child, ColGroup(5), + Child, HVSpace, + + Child, HGroup, + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_SCALING_MINSIZE)), + Child, app->Obj[CYCLE_ICONMINSIZE] = CycleObject, + MUIA_CycleChain, TRUE, + MUIA_Cycle_Entries, cIconSizesMin, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_SCALING_MINSIZE_SHORTHELP), + End, //Cycle + End, //HGroup + + Child, HVSpace, + + Child, HGroup, + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_SCALING_MAXSIZE)), + Child, app->Obj[CYCLE_ICONMAXSIZE] = CycleObject, + MUIA_CycleChain, TRUE, + MUIA_Cycle_Entries, cIconSizesMax, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_SCALING_MAXSIZE_SHORTHELP), + End, //Cycle + End, //HGroup + + Child, HVSpace, + + Child, HVSpace, + + Child, app->Obj[GOUP_ICONSIZE_MIN_SAMPLE] = PageGroup, + MUIA_Frame, MUIV_Frame_Gauge, + Child, HVSpace, // empty + Child, app->Obj[IMAGE_ICON_SAMPLE_16] = CreatePrefsImage((void *) IMAGE_ICON16), + Child, app->Obj[IMAGE_ICON_SAMPLE_24] = CreatePrefsImage((void *) IMAGE_ICON24), + Child, app->Obj[IMAGE_ICON_SAMPLE_32] = CreatePrefsImage((void *) IMAGE_ICON32), + Child, app->Obj[IMAGE_ICON_SAMPLE_48] = CreatePrefsImage((void *) IMAGE_ICON48), + Child, app->Obj[IMAGE_ICON_SAMPLE_64] = CreatePrefsImage((void *) IMAGE_ICON64), + Child, app->Obj[IMAGE_ICON_SAMPLE_96] = CreatePrefsImage((void *) IMAGE_ICON96), + Child, app->Obj[IMAGE_ICON_SAMPLE_128] = CreatePrefsImage((void *) IMAGE_ICON128), + End, //PageGroup + + Child, HVSpace, + + Child, app->Obj[GOUP_ICONSIZE_MAX_SAMPLE] = PageGroup, + MUIA_Frame, MUIV_Frame_Gauge, + Child, HVSpace, // empty + Child, app->Obj[IMAGE_ICON_SAMPLE_16] = CreatePrefsImage((void *) IMAGE_ICON16), + Child, app->Obj[IMAGE_ICON_SAMPLE_24] = CreatePrefsImage((void *) IMAGE_ICON24), + Child, app->Obj[IMAGE_ICON_SAMPLE_32] = CreatePrefsImage((void *) IMAGE_ICON32), + Child, app->Obj[IMAGE_ICON_SAMPLE_48] = CreatePrefsImage((void *) IMAGE_ICON48), + Child, app->Obj[IMAGE_ICON_SAMPLE_64] = CreatePrefsImage((void *) IMAGE_ICON64), + Child, app->Obj[IMAGE_ICON_SAMPLE_96] = CreatePrefsImage((void *) IMAGE_ICON96), + Child, app->Obj[IMAGE_ICON_SAMPLE_128] = CreatePrefsImage((void *) IMAGE_ICON128), + End, //PageGroup + + Child, HVSpace, + End, //ColGroup + + Child, HVSpace, + End, //VGroup + Child, HVSpace, + + End, //VGroup + + // --- Icons-Labels + Child, VGroup, + + Child, HVSpace, + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_ICONSPAGE_LABELS), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, HGroup, + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_LABELS_TEXT)), + Child, app->Obj[CYCLE_LABELSTYLE] = CycleObject, + MUIA_CycleChain, TRUE, + MUIA_Cycle_Entries, cIconLabelStyles, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_LABELS_TEXT_SHORTHELP), + End, //Cycle + End, //HGroup + + Child, HGroup, + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_LABELS_TEXTSPACE)), + Child, app->Obj[SLIDER_LABELSPACE] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 10, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 0, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_LABELS_TEXTSPACE_SHORTHELP), + End, //Slider + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_LABELS_TEXTSPACE_PIXELS)), + End, //HGroup + + Child, HGroup, + Child, HVSpace, + Child, ColGroup(2), + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_LABELS_SPLIT)), + Child, app->Obj[CHECK_MULTILINES] = CheckMarkHelp(FALSE, MSGID_ICONSPAGE_LABELS_SPLIT_SHORTHELP), + + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_LABELS_UNDERLINE_LINKS)), + Child, app->Obj[SOFTICONSLINK] = CheckMarkHelp(FALSE, MSGID_ICONSPAGE_LABELS_UNDERLINE_LINKS_SHORTHELP), + + End, //ColGroup + Child, HVSpace, + End, //HGroup + + Child, HVSpace, + End, //VGroup + + Child, HVSpace, + + Child, VGroup, + Child, HVSpace, + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_ICONSPAGE_SEL_ICONTEXT_RECT_GROUP), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, HGroup, + Child, HVSpace, + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_SEL_ICONTEXT_RECT)), + Child, app->Obj[CHECK_SEL_ICONTEXT_RECTANGLE] = CheckMarkHelp(FALSE, MSGID_ICONSPAGE_SEL_ICONTEXT_RECT_SHORTHELP), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_SEL_ICONTEXT_RECT_SHORTHELP), + Child, HVSpace, + + End, //HGroup + + Child, HVSpace, + + Child, ColGroup(2), + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_SEL_ICONTEXT_XBORDER)), + Child, app->Obj[SLIDER_SEL_ICONTEXT_RECT_BORDERX] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 20, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 4, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_SEL_ICONTEXT_XBORDER_SHORTHELP), + End, //Cycle + + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_SEL_ICONTEXT_YBORDER)), + Child, app->Obj[SLIDER_SEL_ICONTEXT_RECT_BORDERY] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 20, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 2, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_SEL_ICONTEXT_YBORDER_SHORTHELP), + End, //Cycle + + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_SEL_ICONTEXT_RADIUS)), + Child, app->Obj[SLIDER_SEL_ICONTEXT_RECT_RADIUS] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 1, + MUIA_Numeric_Max, 20, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 5, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_SEL_ICONTEXT_RADIUS_SHORTHELP), + End, //Cycle + End, //ColGroup + + Child, HVSpace, + End, //VGroup + + End, //VGroup + + Child, HVSpace, + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_ICONSPAGE_LABELS_FONT), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, HGroup, + Child, HVSpace, + Child, Label1((ULONG) GetLocString(MSGID_TTFONTSPAGE_ICONFONT_ENABLE)), + Child, app->Obj[CHECK_ICONSPAGE_TTICONFONT_ENABLE] = CheckMarkHelp(FALSE, MSGID_FONTSPAGE_TTFICONFONT_ENABLE_SHORTHELP), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_FONTSPAGE_TTFICONFONT_ENABLE_SHORTHELP), + End, //HGroup + + Child, HVSpace, + + Child, app->Obj[GROUP_ICONSPAGE_ICONFONT] = VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_ICONSPAGE_GROUP_ICONFONT), + GroupFrame, + MUIA_Background, MUII_GroupBack, + Child, app->Obj[GROUP_ICONFONT_NOTICE] = HGroup, + Child, FloattextObject, + TextFrame, + MUIA_Floattext_Justify, FALSE, + MUIA_Floattext_Text, (ULONG) GetLocString(MSGID_ICONSPAGE_LABELS_FONT_NOTICE), + End, //Floattext + Child, app->Obj[POP_FONTPREFS] = ImageObject, + MUIA_InputMode, MUIV_InputMode_RelVerify, + MUIA_Image_Spec, "6:18", //MUII_PopUp, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_LABELS_FONT_SHORTHELP), + End, //Image + End, //HGroup + + Child, app->Obj[GROUP_ICONFONT_SELECT] = HGroup, + Child, app->Obj[POP_ICONFONT] = PopaslObject, + MUIA_CycleChain, TRUE, + MUIA_Popstring_Button, PopButton(MUII_PopUp), + MUIA_Popstring_String, BetterStringObject, + StringFrame, + MUIA_String_Contents, "Xen/8", + End, //BetterString + ASLFR_TitleText, (ULONG) GetLocString(MSGID_ICONSPAGE_ICONFONT_ASLTITLE), + MUIA_Popasl_Type , ASL_FontRequest, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_LABELS_ICONFONT_SHORTHELP), + End, //Pop + End, //HGroup + + Child, app->Obj[MCC_ICONFONT_SAMPLE] = FontSampleObject, + TextFrame, + MUIA_Background, MUII_TextBack, + MUIA_FontSample_DemoString, (ULONG) GetLocString(MSGID_TTFONTSPAGE_SAMPLETEXT), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_LABELS_FONT_SAMPLETEXT_SHORTHELP), + End, //FontSampleMCCObject + End, //VGroup + + Child, app->Obj[GROUP_ICONSPAGE_TTICONFONT] = HGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_TTFONTSPAGE_ICONFONT), + GroupFrame, + MUIA_Background, MUII_GroupBack, + MUIA_Disabled, TRUE, + + Child, VGroup, + Child, app->Obj[POPSTRING_ICONSPAGE_TTICONFONT] = PopstringObject, + MUIA_CycleChain, TRUE, + MUIA_Popstring_Button, PopButton(MUII_PopUp), + MUIA_Popstring_String, BetterStringObject, + StringFrame, + MUIA_String_Contents, " ", + End, //BetterString + MUIA_Popstring_OpenHook, &IconTtfPopOpenHook, + MUIA_Popstring_CloseHook, &IconTtfPopCloseHook, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_TTFONTSPAGE_ICONFONT_SHORTHELP), + End, //PopstringObject + + Child, app->Obj[MCC_ICONSPAGE_TTICONFONT_SAMPLE] = FontSampleObject, + TextFrame, + MUIA_Background, MUII_TextBack, + MUIA_FontSample_DemoString, (ULONG) GetLocString(MSGID_TTFONTSPAGE_SAMPLETEXT), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_TTFONTSPAGE_ICONFONT_SAMPLETEXT_SHORTHELP), + End, //FontSampleMCCObject + End, //VGroup + End, //HGroup + End, //VGroup + + + Child, HVSpace, + + End, //VGroup + + // --- Icons-Borders + Child, VGroup, + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_ICONSPAGE_ICONFRAME), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, ColGroup(2), + Child, app->Obj[FRAME_ICONNORMAL] = McpFrameObject, + MUIA_InputMode, MUIV_InputMode_RelVerify, + ButtonFrame, + MUIA_InnerBottom, 4, + MUIA_InnerLeft, 4, + MUIA_InnerRight, 4, + MUIA_InnerTop, 4, + MUIA_CycleChain, 1, + MUIA_Background, MUII_ButtonBack, + MUIA_CycleChain, 1, + MUIA_MCPFrame_FrameType, MCP_FRAME_BUTTON, + MUIA_Draggable, FALSE, + MUIA_Dropable, TRUE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_ICONFRAME_NORMAL_SHORTHELP), + End, + Child, app->Obj[FRAME_ICONSELECTED] = McpFrameObject, + MUIA_InputMode, MUIV_InputMode_RelVerify, + ButtonFrame, + MUIA_InnerBottom, 4, + MUIA_InnerLeft, 4, + MUIA_InnerRight, 4, + MUIA_InnerTop, 4, + MUIA_CycleChain, 1, + MUIA_Background, MUII_ButtonBack, + MUIA_MCPFrame_FrameType, MCP_FRAME_BUTTON | MCP_FRAME_RECESSED, + MUIA_Draggable, FALSE, + MUIA_Dropable, TRUE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_ICONFRAME_SELECTED_SHORTHELP), + End, + + Child, CLabel((ULONG) GetLocString(MSGID_ICONSPAGE_ICONFRAME_NORMAL)), + Child, CLabel((ULONG) GetLocString(MSGID_ICONSPAGE_ICONFRAME_SELECTED)), + End, //ColGroup + Child, ColGroup(4), + Child, Label((ULONG) GetLocString(MSGID_ICONSPAGE_ICONBORDER_LEFT)), + Child, app->Obj[ICONLEFT] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 10, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 4, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_ICONBORDER_LEFT_SHORTHELP), + End, // Slider + Child, Label((ULONG) GetLocString(MSGID_ICONSPAGE_ICONBORDER_TOP)), + Child, app->Obj[ICONTOP] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 10, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 3, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_ICONBORDER_TOP_SHORTHELP), + End, //Slider + Child, Label((ULONG) GetLocString(MSGID_ICONSPAGE_ICONBORDER_RIGHT)), + Child, app->Obj[ICONRIGHT] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 10, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 4, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_ICONBORDER_RIGHT_SHORTHELP), + End, //Slider + Child, Label((ULONG) GetLocString(MSGID_ICONSPAGE_ICONBORDER_BOTTOM)), + Child, app->Obj[ICONBOTTOM] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 10, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 3, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_ICONBORDER_BOTTOM_SHORTHELP), + End, //Slider + End, //ColGroup + End, //VGroup + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_ICONSPAGE_THUMBNAILS_ICONFRAME), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, ColGroup(2), + Child, app->Obj[FRAME_ICON_THUMBNAIL_NORMAL] = McpFrameObject, + MUIA_InputMode, MUIV_InputMode_RelVerify, + ButtonFrame, + MUIA_InnerBottom, 4, + MUIA_InnerLeft, 4, + MUIA_InnerRight, 4, + MUIA_InnerTop, 4, + MUIA_CycleChain, 1, + MUIA_Background, MUII_ButtonBack, + MUIA_CycleChain, 1, + MUIA_MCPFrame_FrameType, MCP_FRAME_BUTTON, + MUIA_Draggable, FALSE, + MUIA_Dropable, TRUE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_THUMBNAILS_ICONFRAME_NORMAL_SHORTHELP), + End, //McpFrameClass + + Child, app->Obj[FRAME_ICON_THUMBNAIL_SELECTED] = McpFrameObject, + MUIA_InputMode, MUIV_InputMode_RelVerify, + ButtonFrame, + MUIA_InnerBottom, 4, + MUIA_InnerLeft, 4, + MUIA_InnerRight, 4, + MUIA_InnerTop, 4, + MUIA_CycleChain, 1, + MUIA_Background, MUII_ButtonBack, + MUIA_CycleChain, 1, + MUIA_MCPFrame_FrameType, MCP_FRAME_BUTTON | MCP_FRAME_RECESSED, + MUIA_Draggable, FALSE, + MUIA_Dropable, TRUE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_THUMBNAILS_ICONFRAME_SELECTED_SHORTHELP), + End, //McpFrameClass + + Child, CLabel((ULONG) GetLocString(MSGID_ICONSPAGE_ICONFRAME_NORMAL)), + Child, CLabel((ULONG) GetLocString(MSGID_ICONSPAGE_ICONFRAME_SELECTED)), + + End, //ColGroup + Child, ColGroup(4), + Child, Label((ULONG) GetLocString(MSGID_ICONSPAGE_ICONBORDER_LEFT)), + Child, app->Obj[THUMBNAILS_LEFTBORDER] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 10, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 4, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_ICONBORDER_LEFT_SHORTHELP), + End, // Slider + Child, Label((ULONG) GetLocString(MSGID_ICONSPAGE_ICONBORDER_TOP)), + Child, app->Obj[THUMBNAILS_TOPBORDER] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 10, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 3, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_ICONBORDER_TOP_SHORTHELP), + End, //Slider + Child, Label((ULONG) GetLocString(MSGID_ICONSPAGE_ICONBORDER_RIGHT)), + Child, app->Obj[THUMBNAILS_RIGHTBORDER] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 10, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 4, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_ICONBORDER_RIGHT_SHORTHELP), + End, //Slider + Child, Label((ULONG) GetLocString(MSGID_ICONSPAGE_ICONBORDER_BOTTOM)), + Child, app->Obj[THUMBNAILS_BOTTOMBORDER] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 10, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 3, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_ICONBORDER_BOTTOM_SHORTHELP), + End, //Slider + End, //ColGroup + End, //VGroup + + End, //VGroup + + + // --- Icons--Tooltips + Child, VGroup, + + Child, HVSpace, + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_ICONSPAGE_TOOLTIPS_GENERAL), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, HGroup, + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_TOOLTIPS_SHOW)), + Child, app->Obj[CHECK_TOOLTIPS] = CheckMarkHelp(TRUE, MSGID_ICONSPAGE_TOOLTIPS_SHOW_SHORTHELP), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_TOOLTIPS_SHOW_SHORTHELP), + Child, HVSpace, + End, //HGroup + + Child, HVSpace, + + End, //VGroup + + Child, app->Obj[TOOLTIP_SETTINGSGROUP] = VGroup, + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_ICONSPAGE_TOOLTIPS_SETTINGS), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, HGroup, + Child, Label2((ULONG) GetLocString(MSGID_ICONSPAGE_TOOLTIPS_DELAY)), + Child, app->Obj[SLIDER_TIPDELAY] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 1, + MUIA_Numeric_Max, 10, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 5, + End, //Slider + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_TOOLTIPS_DELAY_SHORTHELP), + Child, Label((ULONG) GetLocString(MSGID_ICONSPAGE_TOOLTIPS_DELAY_SECONDS)), + End, //HGroup + + Child, HGroup, +/* currently unused */ MUIA_ShowMe, FALSE, + Child, Label2((ULONG) GetLocString(MSGID_ICONSPAGE_TOOLTIPS_FONT)), + Child, app->Obj[STRING_TOOLTIPFONT] = PopaslObject, + MUIA_CycleChain, TRUE, + MUIA_Popasl_Type, ASL_FontRequest, + MUIA_Popstring_Button, PopButton(MUII_PopUp), + MUIA_Popstring_String, BetterStringObject, + StringFrame, + MUIA_String_Contents, "Xen/8", + End, //BetterString + + ASLFO_TitleText, (ULONG) GetLocString(MSGID_ICONSPAGE_TOOLTIPS_FONT_ASLTITLE), + ASLFO_FixedWidthOnly, FALSE, + End, //Pop + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_TOOLTIPS_FONT_SHORTHELP), + End, //HGroup + + Child, HVSpace, + + Child, HGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_ICONSPAGE_TOOLTIPS_TRANSPARENCY), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRANSPARENCY_TRANSPARENT)), + + Child, app->Obj[SLIDER_ICONTOOLTIPS_TRANSPARENCY] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 100, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 50, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_TOOLTIPS_TRANSPARENCY_SHORTHELP), + End, //Slider + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRANSPARENCY_OPAQUE)), + End, //HGroup + Child, HVSpace, + + End, //VGroup + + Child, HGroup, +/* currently unused */ MUIA_ShowMe, FALSE, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_ICONSPAGE_TOOLTIPS_DISPLAYFIELDS), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, VGroup, + Child, CLabel2((ULONG) GetLocString(MSGID_ICONSPAGE_TOOLTIPS_AVAILABLEFIELDS)), + Child, NListviewObject, +/* currently unused */ MUIA_Disabled, TRUE, + MUIA_NListview_NList, app->Obj[STORAGE_TIPS] = NListObject, + InputListFrame, + MUIA_Background, MUII_ListBack, + //MUIA_List_Format, "", + MUIA_NList_ShowDropMarks, TRUE, + MUIA_NList_AdjustWidth, FALSE, + MUIA_NList_AutoVisible, TRUE, + MUIA_NList_DragSortable, FALSE, + End, //List + MUIA_Listview_MultiSelect, MUIV_Listview_MultiSelect_Shifted, + MUIA_Listview_DragType, MUIV_Listview_DragType_Immediate, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_TOOLTIPS_AVAILABLEFIELDS_SHORTHELP), + End, //Listview + End, //VGroup + + Child, VGroup, + Child, CLabel2((ULONG) GetLocString(MSGID_ICONSPAGE_TOOLTIPS_FIELDSINUSE)), + Child, NListviewObject, +/* currently unused */ MUIA_Disabled, TRUE, + MUIA_NListview_NList, app->Obj[USED_TIPS] = NListObject, + InputListFrame, + MUIA_Background, MUII_ListBack, + //MUIA_List_Format, "", + MUIA_NList_ShowDropMarks, TRUE, + MUIA_NList_AdjustWidth, FALSE, + MUIA_NList_AutoVisible, TRUE, + MUIA_NList_DragSortable, TRUE, + End, //List + MUIA_Listview_MultiSelect, MUIV_Listview_MultiSelect_Shifted, + MUIA_Listview_DragType, MUIV_Listview_DragType_Immediate, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_TOOLTIPS_FIELDSINUSE_SHORTHELP), + End, //Listview + End, //VGroup + End, //HGroup + + End, //VGroup + + Child, HVSpace, + + End, //VGroup + + // --- Icons-Thumbnails + Child, VGroup, + + Child, HVSpace, + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_ICONSPAGE_THUMBNAILS_SETTINGS), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HGroup, + Child, HVSpace, + + Child, ColGroup(2), + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_SHOWTHUMBNAILS)), + Child, app->Obj[CYCLE_SHOWTHUMBNAILS] = CycleObject, + MUIA_CycleChain, TRUE, + MUIA_Cycle_Entries, cShowThumbnails, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_SHOWTHUMBNAILS_SHORTHELP), + End, //Cycle + + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_THUMBNAILS_SIZE)), + Child, app->Obj[CYCLE_THUMBNAILSIZE] = CycleObject, + MUIA_CycleChain, TRUE, + MUIA_Cycle_Entries, cThumbnailSizes, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_THUMBNAILS_SIZE_SHORTHELP), + End, //Cycle + + Child, HVSpace, // always 2 HVSpace due to ColGroup(2) + Child, HVSpace, + + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_SHOWTHUMBNAILS_AS_DEFAULT)), + Child, app->Obj[CHECK_SHOWTHUMBNAILS_AS_DEFAULT] = CheckMarkHelp(FALSE, MSGID_ICONSPAGE_SHOWTHUMBNAILS_AS_DEFAULT_SHORTHELP), + + Child, HVSpace, // always 2 HVSpace due to ColGroup(2) + Child, HVSpace, + + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_THUMBNAILS_SQUARE)), + Child, app->Obj[CHECK_THUMBNAILS_SQUARE] = CheckMarkHelp(FALSE, MSGID_ICONSPAGE_THUMBNAILS_SQUARE_SHORTHELP), + + Child, HVSpace, // always 2 HVSpace due to ColGroup(2) + Child, HVSpace, + + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_THUMBNAILS_BACKFILL)), + Child, app->Obj[CHECK_THUMBNAILS_BACKFILL] = CheckMarkHelp(FALSE, MSGID_ICONSPAGE_THUMBNAILS_BACKFILL_SHORTHELP), + + End, // ColGroup + + Child, HVSpace, + + Child, VGroup, + Child, app->Obj[GROUP_THUMBNAILS_ICON_SAMPLE] = PageGroup, + MUIA_Frame, MUIV_Frame_Gauge, + Child, app->Obj[IMAGE_ICON_SAMPLE_16] = CreatePrefsImage((void *) IMAGE_ICON16), + Child, app->Obj[IMAGE_ICON_SAMPLE_24] = CreatePrefsImage((void *) IMAGE_ICON24), + Child, app->Obj[IMAGE_ICON_SAMPLE_32] = CreatePrefsImage((void *) IMAGE_ICON32), + Child, app->Obj[IMAGE_ICON_SAMPLE_48] = CreatePrefsImage((void *) IMAGE_ICON48), + Child, app->Obj[IMAGE_ICON_SAMPLE_64] = CreatePrefsImage((void *) IMAGE_ICON64), + Child, app->Obj[IMAGE_ICON_SAMPLE_96] = CreatePrefsImage((void *) IMAGE_ICON96), + Child, app->Obj[IMAGE_ICON_SAMPLE_128] = CreatePrefsImage((void *) IMAGE_ICON128), + End, //PageGroup + End, //VGroup + + Child, HVSpace, + + End, //HGroup + + Child, HGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_ICONSPAGE_THUMBNAILS_QUALITY), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_THUMBNAILS_QUALITY_WORST)), + + Child, app->Obj[SLIDER_THUMBNAILS_QUALITY] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, SCALOSPREVIEWA_Quality_Min, + MUIA_Numeric_Max, SCALOSPREVIEWA_Quality_Max, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, SCALOSPREVIEWA_Quality_Max, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_THUMBNAILS_QUALITY_SHORTHELP), + End, //Slider + + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_THUMBNAILS_QUALITY_BEST)), + End, //HGroup + + Child, HVSpace, + End, //HGroup + + Child, app->Obj[GROUP_THUMBNAIL_BACKFILL_TRANSPARENCY] = HGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_ICONSPAGE_THUMBNAIL_BACKFILL_TRANSPARENCY), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRANSPARENCY_TRANSPARENT)), + + Child, app->Obj[SLIDER_ICONTRANSPARENCY_THUMBNAILBACK] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 100, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 50, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_THUMBNAIL_BACKFILL_TRANSPARENCY_SHORTHELP), + End, //Slider + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRANSPARENCY_OPAQUE)), + End, //HGroup + + Child, HGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_ICONSPAGE_THUMBNAILS_CACHE), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, ColGroup(2), + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_THUMBNAILS_MAXAGE)), + Child, app->Obj[SLIDER_THUMBNAILS_MAXAGE] = ThumbnailLifetimeSliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 365, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 14, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_THUMBNAILS_MAXAGE_SHORTHELP), + End, //ThumbnailLifetimeSliderClass + + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_THUMBNAILS_MINSIZE_LIMIT)), + Child, app->Obj[SLIDER_THUMBNAILS_MINSIZE_LIMIT] = NumericbuttonObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 8, + MUIA_Numeric_Max, 256, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 128, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_THUMBNAILS_MINSIZE_LIMIT_SHORTHELP), + End, //Slider + + End, //ColGroup + + Child, HVSpace, + End, // HGroup + + Child, HVSpace, + + End, //VGroup + + + End, //Register + + End, //VGroup + &NewPrefsPages[4]); +/// +} + +//----------------------------------------------------------------- + +static Object *GenerateDragNDropPage(struct SCAModule *app) +{ +/// + return CreatePrefsPage(app, + VGroup, + MUIA_Background, MUII_PageBack, + + Child, RegisterObject, + MUIA_Register_Titles, cIconDragDropPages, + MUIA_CycleChain, TRUE, + + // Drag and drop + Child, VGroup, + Child, HVSpace, + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_DRAGNDROPPAGE_BOBS), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, HGroup, + Child, HVSpace, + + Child, ColGroup(2), + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_ROUTINES)), + Child, app->Obj[CYCLE_ROUTINE] = CycleObject, + MUIA_CycleChain, TRUE, + MUIA_Cycle_Entries, cIconDragRoutines, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_DRAGNDROPPAGE_ROUTINES_SHORTHELP), + End, //Cycle + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRANSPARENCY)), + Child, app->Obj[CYCLE_TRANSPMODE] = CycleObject, + MUIA_CycleChain, TRUE, + MUIA_Cycle_Entries, cIconDragTransparents, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRANSPARENCY_SHORTHELP), + End, //Cycle + + End, //ColGroup + + Child, HVSpace, + End, //HGroup + + Child, HVSpace, + End, //VGroup + + Child, HVSpace, + + Child, VGroup, + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, HGroup, + Child, HVSpace, + + Child, ColGroup(2), + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_STYLE)), + Child, app->Obj[CYCLE_STYLE] = CycleObject, + MUIA_CycleChain, TRUE, + MUIA_Cycle_Entries, cIconDragStyle, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_DRAGNDROPPAGE_STYLE_SHORTHELP), + End, //Cycle + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_DROPMARKMODE)), + Child, app->Obj[CYCLE_DROPMARK] = CycleObject, + MUIA_CycleChain, TRUE, + MUIA_Cycle_Entries, cIconDropMark, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_DRAGNDROPPAGE_DROPMARKMODE_SHORTHELP), + End, //Cycle + + End, //ColGroup + + Child, HVSpace, + End, //HGroup + + Child, HVSpace, + End, //VGroup + + Child, HVSpace, + + Child, VGroup, + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, HGroup, + Child, HVSpace, + + Child, ColGroup(4), + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_AUTOREMOVE)), + Child, app->Obj[CHECK_AUTOREMOVE] = CheckMarkHelp(FALSE, MSGID_DRAGNDROPPAGE_AUTOREMOVE_SHORTHELP), + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_EASY_MULTISELECT)), + Child, app->Obj[CHECK_EASY_MULTISELECT] = CheckMarkHelp(FALSE, MSGID_DRAGNDROPPAGE_EASY_MULTISELECT_SHORTHELP), + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_GROUP_MULTIPLE)), + Child, app->Obj[CHECK_GROUPDRAG] = CheckMarkHelp(FALSE,MSGID_DRAGNDROPPAGE_GROUP_MULTIPLE_SHORTHELP), + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_EASY_MULTIDRAG)), + Child, app->Obj[CHECK_EASY_MULTIDRAG] = CheckMarkHelp(FALSE, MSGID_DRAGNDROPPAGE_EASY_MULTIDRAG_SHORTHELP), + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_DRAGGINGLABEL)), + Child, app->Obj[CHECK_SHOWDRAG] = CheckMarkHelp(FALSE, MSGID_DRAGNDROPPAGE_DRAGGINGLABEL_SHORTHELP), + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_DROPMENU)), + Child, app->Obj[CHECK_ENABLE_DROPMENU] = CheckMarkHelp(FALSE, MSGID_DRAGNDROPPAGE_DROPMENU_SHORTHELP), + + End, //ColGroup + + Child, HVSpace, + End, //HGroup + + Child, HVSpace, + End, //VGroup + + Child, HVSpace, + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_DRAGNDROPPAGE_QUALIFIERS), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, ColGroup(2), + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_FORCECOPY)), + Child, HGroup, + Child, app->Obj[COPY_HOTKEY] = HotkeyStringObject, + StringFrame, + MUIA_String_Contents, "", + MUIA_HotkeyString_Snoop, FALSE, + End, //HotkeyString + Child, app->Obj[COPY_HOTKEY_SCAN] = ScanButton, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_DRAGNDROPPAGE_FORCECOPY_SHORTHELP), + End, //HGroup + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_FORCEMAKELINK)), + Child, HGroup, + Child, app->Obj[MAKELINK_HOTKEY] = HotkeyStringObject, + StringFrame, + MUIA_String_Contents, "", + MUIA_HotkeyString_Snoop, FALSE, + End, //HotkeyString + Child, app->Obj[MAKELINK_HOTKEY_SCAN] = ScanButton, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_DRAGNDROPPAGE_FORCEMAKELINK_SHORTHELP), + End, //HGroup + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_FORCEMOVE)), + Child, HGroup, + Child, app->Obj[MOVE_HOTKEY] = HotkeyStringObject, + StringFrame, + MUIA_String_Contents, "", + MUIA_HotkeyString_Snoop, FALSE, + End, //HotkeyString + Child, app->Obj[MOVE_HOTKEY_SCAN] = ScanButton, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_DRAGNDROPPAGE_FORCEMOVE_SHORTHELP), + End, //HGroup + End, //ColGroup + + Child, HVSpace, + End, //VGroup + + Child, HVSpace, + End, //VGroup + + // Transparency + Child, VGroup, + Child, HVSpace, + + Child, HGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRANSPARENCY_ICONDRAG), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRANSPARENCY_TRANSPARENT)), + + Child, app->Obj[SLIDER_ICONTRANSPARENCY_DRAG] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 100, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 50, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRANSPARENCY_ICONDRAG_SHORTHELP), + End, //Slider + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRANSPARENCY_OPAQUE)), + End, //HGroup + + Child, HGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRANSPARENCY_ICONSHADOW), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRANSPARENCY_TRANSPARENT)), + + Child, app->Obj[SLIDER_ICONTRANSPARENCY_SHADOW] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 100, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 50, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRANSPARENCY_ICONSHADOW_SHORTHELP), + End, //Slider + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRANSPARENCY_OPAQUE)), + End, //HGroup + + Child, HVSpace, + End, //VGroup + + // Triggers + Child, VGroup, + Child, HVSpace, + + Child, VGroup, + //MUIA_FrameTitle, "", + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, HGroup, + Child, HVSpace, + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_LOOK)), + Child, app->Obj[RADIO_BOBLOOK] = RadioObject, + MUIA_CycleChain, TRUE, + MUIA_Radio_Entries, cIconDragLook, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_DRAGNDROPPAGE_LOOK_SHORTHELP), + End, //Radio + + Child, HVSpace, + End, //HGroup + + Child, HVSpace, + End, //VGroup + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRIGGERS), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, HGroup, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRIGGERS_SHORTHELP), + + Child, HVSpace, + + Child, ColGroup(4), + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRIGGERS_DISKICONS)), + Child, app->Obj[CHECK_TRIG_DISK] = CheckMarkHelp(FALSE, MSGID_DRAGNDROPPAGE_TRIGGERS_SHORTHELP), + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRIGGERS_DRAWERICONS)), + Child, app->Obj[CHECK_TRIG_DRAWER] = CheckMarkHelp(FALSE, MSGID_DRAGNDROPPAGE_TRIGGERS_SHORTHELP), + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRIGGERS_TOOLICONS)), + Child, app->Obj[CHECK_TRIG_TOOL] = CheckMarkHelp(FALSE, MSGID_DRAGNDROPPAGE_TRIGGERS_SHORTHELP), + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRIGGERS_PROJECTICONS)), + Child, app->Obj[CHECK_TRIG_PROJECT] = CheckMarkHelp(FALSE, MSGID_DRAGNDROPPAGE_TRIGGERS_SHORTHELP), + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRIGGERS_TRASHCANICONS)), + Child, app->Obj[CHECK_TRIG_TRASHCAN] = CheckMarkHelp(FALSE, MSGID_DRAGNDROPPAGE_TRIGGERS_SHORTHELP), + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRIGGERS_KICKICONS)), + Child, app->Obj[CHECK_TRIG_KICK] = CheckMarkHelp(FALSE, MSGID_DRAGNDROPPAGE_TRIGGERS_SHORTHELP), + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRIGGERS_APPICONS)), + Child, app->Obj[CHECK_TRIG_APPICON] = CheckMarkHelp(FALSE, MSGID_DRAGNDROPPAGE_TRIGGERS_SHORTHELP), + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRIGGERS_APPWINDOWS)), + Child, app->Obj[CHECK_TRIG_APPWIN] = CheckMarkHelp(FALSE, MSGID_DRAGNDROPPAGE_TRIGGERS_SHORTHELP), + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRIGGERS_ICONIFIED_WINDOWS)), + Child, app->Obj[CHECK_TRIG_ICONIFIEDWIN] = CheckMarkHelp(FALSE, MSGID_DRAGNDROPPAGE_TRIGGERS_SHORTHELP), + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRIGGERS_SCALOS_WINDOWS)), + Child, app->Obj[CHECK_TRIG_SCALOSWIN] = CheckMarkHelp(FALSE, MSGID_DRAGNDROPPAGE_TRIGGERS_SHORTHELP), + End, //ColGroup + + Child, HVSpace, + End, //VGroup + + Child, HVSpace, + + End, //VGroup + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_DRAGNDROPPAGE_POPOPENWINDOWS), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, HGroup, + Child, Label((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_SLIDER_POPOPWINDOW_DELAY)), + Child, app->Obj[SLIDER_POPOPENWINDOW_DELAY] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 1, + MUIA_Numeric_Max, 20, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 3, + End, //Slider + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_DRAGNDROPPAGE_SLIDER_POPOPWINDOW_DELAY_SHORTHELP), + Child, Label((ULONG) GetLocString(MSGID_STARTUPPAGE_DOWAITDELAY_SECONDS)), + End, //HGroup + + Child, HVSpace, + + End, //VGroup + + Child, HVSpace, + + End, //VGroup, + End, //Register + + End, //VGroup + &NewPrefsPages[5]); +/// +} + +//----------------------------------------------------------------- + +static Object *GenerateWindowPage(struct SCAModule *app) +{ +/// + return CreatePrefsPage(app, + VGroup, + MUIA_Background, MUII_PageBack, + + Child, RegisterObject, + MUIA_Register_Titles, cWindowPages, + MUIA_CycleChain, TRUE, + + // --- Windows-General + Child, VGroup, + + Child, HVSpace, + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_WINDOWPAGE_WINDOWTITLES), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, ColGroup(2), + Child, Label2((ULONG) GetLocString(MSGID_WINDOWPAGE_WINDOWTITLES_ROOTWINDOW)), + Child, app->Obj[POPPH_ROOTWINDOWTITLE] = PopplaceholderObject, + MUIA_Popph_Title, (ULONG) GetLocString(MSGID_WINDOWPAGE_WINDOWTITLES_ROOTWINDOW_DESCRIPTION), + MUIA_Popph_Array, cTitleph, + MUIA_Popph_Avoid, MUIV_Popph_Avoid_Textinput, + MUIA_Popph_ReplaceMode, FALSE, + MUIA_Popph_Contents, "", + MUIA_Popph_StringMaxLen, 600, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_WINDOWPAGE_WINDOWTITLES_ROOTWINDOW_SHORTHELP), + End, //Popplaceholder + + Child, Label2((ULONG) GetLocString(MSGID_WINDOWPAGE_WINDOWTITLES_DIRECTORYWINDOW)), + Child, app->Obj[POPPH_DIRWINDOWTITLE] = PopplaceholderObject, + MUIA_Popph_Title, (ULONG) GetLocString(MSGID_WINDOWPAGE_WINDOWTITLES_DIRECTORYWINDOW_DESCRIPTION), + MUIA_Popph_Array, cTitleph, + MUIA_Popph_Avoid, MUIV_Popph_Avoid_Textinput, + MUIA_Popph_ReplaceMode, FALSE, + MUIA_Popph_Contents, "", + MUIA_Popph_StringMaxLen, 600, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_WINDOWPAGE_WINDOWTITLES_DIRECTORYWINDOW_SHORTHELP), + End, //Popplaceholder + + Child, Label2((ULONG) GetLocString(MSGID_DESKTOPPAGE_WINTITLEBAR_REFRESH)), + Child, HGroup, + Child, app->Obj[SLIDER_WINTITLEREFRESH] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 1, + MUIA_Numeric_Max, 10, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 5, + End, //Slider + Child, Label((ULONG) GetLocString(MSGID_DESKTOPPAGE_WINTITLEBAR_REFRESH_SECONDS)), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_DESKTOPPAGE_WINTITLEBAR_REFRESH_SHORTHELP), + End, //HGroup + End, //ColGroup + + Child, HGroup, + Child, HVSpace, + Child, Label1((ULONG) GetLocString(MSGID_DESKTOPPAGE_WINTITLEBAR_REFRESH_MEMCHANGE)), + Child, app->Obj[CHECK_WINTITLEMEM] = CheckMarkHelp(FALSE, MSGID_DESKTOPPAGE_WINTITLEBAR_REFRESH_MEMCHANGE_SHORTHELP), + Child, HVSpace, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_DESKTOPPAGE_WINTITLEBAR_REFRESH_MEMCHANGE_SHORTHELP), + End, //HGroup + + Child, HVSpace, + + End, //VGroup + + Child, VGroup, + //MUIA_FrameTitle, "", + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, ColGroup(4), + Child, HVSpace, + Child, Label1((ULONG) GetLocString(MSGID_WINDOWPAGE_WINDOWTYPE)), + Child, app->Obj[CYCLE_WINDOWTYPE] = CycleObject, + MUIA_CycleChain, TRUE, + MUIA_Cycle_Entries, cWindowRefresh, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_WINDOWPAGE_WINDOWTYPE_SHORTHELP), + End, //Cycle + Child, HVSpace, + + Child, HVSpace, + Child, Label1((ULONG) GetLocString(MSGID_WINDOWPAGE_SHOWALL_DEFAULT)), + Child, app->Obj[CYCLE_SHOWALLDEFAULT] = CycleObject, + MUIA_CycleChain, TRUE, + MUIA_Cycle_Entries, cShowAllDefault, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_WINDOWPAGE_SHOWALL_DEFAULT_SHORTHELP), + End, //Cycle + Child, HVSpace, + + Child, HVSpace, + Child, Label1((ULONG) GetLocString(MSGID_WINDOWPAGE_VIEWBY_DEFAULT)), + Child, app->Obj[CYCLE_VIEWBYICONSDEFAULT] = CycleObject, + MUIA_CycleChain, TRUE, + MUIA_Cycle_Entries, cViewByDefault, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_WINDOWPAGE_WINDOWTYPE_VIEWBY_DEFAULT_SHORTHELP), + End, //Cycle + Child, HVSpace, + End, //ColGroup + + Child, HVSpace, + + End, //VGroup + + Child, VGroup, + //MUIA_FrameTitle, "", + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, ColGroup(4), + Child, HVSpace, + Child, Label1((ULONG) GetLocString(MSGID_WINDOWPAGE_CONTEXTMENU_DRAGBAR)), + Child, app->Obj[CHECK_POPTITLEONLY] = CheckMarkHelp(FALSE, MSGID_WINDOWPAGE_CONTEXTMENU_DRAGBAR_SHORTHELP), + Child, HVSpace, + + Child, HVSpace, + Child, Label1((ULONG) GetLocString(MSGID_WINDOWPAGE_MMB_MOVE)), + Child, app->Obj[CHECK_MMBMOVE] = CheckMarkHelp(FALSE, MSGID_WINDOWPAGE_MMB_MOVE_SHORTHELP), + Child, HVSpace, + + Child, HVSpace, + Child, Label1((ULONG) GetLocString(MSGID_WINDOWPAGE_SHOW_STATUSBAR)), + Child, app->Obj[CHECK_STATUSBAR] = CheckMarkHelp(FALSE, MSGID_WINDOWPAGE_SHOW_STATUSBAR_SHORTHELP), + Child, HVSpace, + + Child, HVSpace, + Child, Label1((ULONG) GetLocString(MSGID_WINDOWPAGE_CHECK_OVERLAP)), + Child, app->Obj[CHECK_CHECKOVERLAP] = CheckMarkHelp(FALSE, MSGID_WINDOWPAGE_CHECK_OVERLAP_SHORTHELP), + Child, HVSpace, + + Child, HVSpace, + Child, Label1((ULONG) GetLocString(MSGID_WINDOWPAGE_CLEANUP_ONRESIZE)), + Child, app->Obj[CHECK_CLEANUP_ONRESIZE] = CheckMarkHelp(FALSE, MSGID_WINDOWPAGE_CLEANUP_ONRESIZE_SHORTHELP), + Child, HVSpace, + + Child, HVSpace, + Child, Label1((ULONG) GetLocString(MSGID_FILEDISPLAYPAGE_HIDE_HIDDENFILES)), + Child, app->Obj[HIDEHIDDENFILES] = CheckMarkHelp(FALSE, MSGID_FILEDISPLAYPAGE_HIDE_HIDDENFILES_SHORTHELP), + Child, HVSpace, + + Child, HVSpace, + Child, Label1((ULONG) GetLocString(MSGID_FILEDISPLAYPAGE_HIDE_PROTECTHIDDENFILES)), + Child, app->Obj[HIDEPROTECTHIDDENFILES] = CheckMarkHelp(FALSE, MSGID_FILEDISPLAYPAGE_HIDE_PROTECTHIDDENFILES_SHORTHELP), + Child, HVSpace, + + End, //ColGroup + + Child, HVSpace, + + End, //VGroup + + Child, HVSpace, + + End, //VGroup + + // --- Window-Sizes + Child, VGroup, + + Child, HVSpace, + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, ColGroup(4), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE_SHORTHELP), + + Child, Label((ULONG) GetLocString(MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE_LEFT)), + Child, app->Obj[WINLEFT] = BetterStringObject, + StringFrame, + MUIA_CycleChain, TRUE, + MUIA_String_Integer, 220, + MUIA_String_Accept, "0123456789", + MUIA_String_AdvanceOnCR, TRUE, + End, //BetterString + + Child, Label((ULONG) GetLocString(MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE_TOP)), + Child, app->Obj[WINTOP] = BetterStringObject, + StringFrame, + MUIA_CycleChain, TRUE, + MUIA_String_Integer, 100, + MUIA_String_Accept, "0123456789", + MUIA_String_AdvanceOnCR, TRUE, + End, //BetterString + + Child, Label((ULONG) GetLocString(MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE_WIDTH)), + Child, app->Obj[WINWIDTH] = BetterStringObject, + StringFrame, + MUIA_CycleChain, TRUE, + MUIA_String_Integer, 200, + MUIA_String_Accept, "0123456789", + MUIA_String_AdvanceOnCR, TRUE, + End, //BetterString + + Child, Label((ULONG) GetLocString(MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE_HEIGHT)), + Child, app->Obj[WINHEIGHT] = BetterStringObject, + StringFrame, + MUIA_CycleChain, TRUE, + MUIA_String_Integer, 300, + MUIA_String_Accept, "0123456789", + MUIA_String_AdvanceOnCR, TRUE, + End, //BetterString + End, //ColGroup + + Child, HVSpace, + End, //VGroup + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_WINDOWPAGE_CLEANUPSPACE), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, ColGroup(2), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_WINDOWPAGE_CLEANUPSPACE_SHORTHELP), + + Child, Label((ULONG) GetLocString(MSGID_WINDOWPAGE_CLEANUPSPACE_LEFT)), + Child, app->Obj[SLIDER_CLEANLEFT] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 20, + MUIA_Numeric_Value, 5, + MUIA_Slider_Horiz, TRUE, + End, //SliderObject + + Child, Label((ULONG) GetLocString(MSGID_WINDOWPAGE_CLEANUPSPACE_TOP)), + Child, app->Obj[SLIDER_CLEANTOP] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 20, + MUIA_Numeric_Value, 5, + MUIA_Slider_Horiz, TRUE, + End, //SliderObject + + Child, Label((ULONG) GetLocString(MSGID_WINDOWPAGE_CLEANUPSPACE_XSKIP)), + Child, app->Obj[SLIDER_CLEANXSKIP] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 20, + MUIA_Numeric_Value, 5, + MUIA_Slider_Horiz, TRUE, + End, //SliderObject + + Child, Label((ULONG) GetLocString(MSGID_WINDOWPAGE_CLEANUPSPACE_YSKIP)), + Child, app->Obj[SLIDER_CLEANYSKIP] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 20, + MUIA_Numeric_Value, 5, + MUIA_Slider_Horiz, TRUE, + End, //SliderObject + End, //ColGroup + + Child, HVSpace, + + End, //VGroup + + Child, HVSpace, + + End, //VGroup + + // --- Window-Control Bar Browser + Child, RegisterObject, + MUIA_Register_Titles, cWindowControlBar, + MUIA_CycleChain, TRUE, + + // --- Browser Window Control Bar + Child, VGroup, + + Child, VSpace(1), + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_BROWSER_GADGETS), + GroupFrame, + MUIA_Background, MUII_GroupBack, + MUIA_Weight, 500, + + Child, HGroup, + Child, VGroup, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_AVAILABLE_GADGETS_SHORTHELP), + Child, CLabel2((ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_AVAILABLE_GADGETS)), + Child, app->Obj[NLISTVIEW_CONTROLBARGADGETS_BROWSER_AVAILABLE] = NListviewObject, + MUIA_Weight, 500, + MUIA_Listview_Input, TRUE, + MUIA_Listview_MultiSelect, MUIV_Listview_MultiSelect_Shifted, + MUIA_Listview_DragType, MUIV_Listview_DragType_Immediate, + MUIA_NListview_NList, app->Obj[NLIST_CONTROLBARGADGETS_BROWSER_AVAILABLE] = ControlBarGadgetsListObject, + InputListFrame, + MUIA_Background, MUII_ListBack, + MUIA_NList_Format, "W=-1, W=-1 MICW=3, W=-1", + MUIA_NList_ShowDropMarks, FALSE, + MUIA_NList_AutoVisible, TRUE, + MUIA_NList_DisplayHook2, &ControlBarGadgetListDisplayHook, + MUIA_NList_ConstructHook2, &ControlBarGadgetListConstructHook, + MUIA_NList_DestructHook2, &ControlBarGadgetListDestructHook, + End, + End, //Listview + End, //VGroup + + Child, VGroup, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_ACTIVE_GADGETS_SHORTHELP), + Child, CLabel2((ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_ACTIVE_GADGETS)), + Child, app->Obj[NLISTVIEW_CONTROLBARGADGETS_BROWSER_ACTIVE] = NListviewObject, + MUIA_Weight, 500, + MUIA_Listview_Input, TRUE, + MUIA_Listview_MultiSelect, MUIV_Listview_MultiSelect_Shifted, + MUIA_Listview_DragType, MUIV_Listview_DragType_Immediate, + MUIA_NListview_NList, app->Obj[NLIST_CONTROLBARGADGETS_BROWSER_ACTIVE] = ControlBarGadgetsListObject, + InputListFrame, + MUIA_Background, MUII_ListBack, + MUIA_NList_Format, "W=-1, W=25 MICW=3, W=-1", + MUIA_NList_DragSortable, TRUE, + MUIA_NList_ShowDropMarks, TRUE, + MUIA_NList_AutoVisible, TRUE, + MUIA_NList_DisplayHook2, &ControlBarGadgetListDisplayHook, + MUIA_NList_ConstructHook2, &ControlBarGadgetListConstructHook, + MUIA_NList_DestructHook2, &ControlBarGadgetListDestructHook, + End, + End, //Listview + End, //VGroup + End, //HGroup + + Child, VSpace(1), + + Child, ColGroup(2), + + Child, Label2((ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_NORMALIMAGE)), + Child, HGroup, + Child, app->Obj[STRING_CONTROLBARGADGETS_BROWSER_NORMALIMAGE] = PopaslObject, + MUIA_CycleChain, TRUE, + MUIA_Disabled, TRUE, + MUIA_Popstring_Button, PopButton(MUII_PopFile), + MUIA_Popstring_String, StringObject, + StringFrame, + End, //String + ASLFR_TitleText, (ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_NORMALIMAGE_ASLTITLE), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_NORMALIMAGE_SHORTHELP), + End, //PopAsl + Child, app->Obj[DTIMG_CONTROLBARGADGETS_BROWSER_NORMALIMAGE] = DataTypesImageObject, + MUIA_ScaDtpic_Name, (ULONG) "", + MUIA_ScaDtpic_FailIfUnavailable, FALSE, + End, //DataTypesMCC + End, //HGroup + + Child, Label2((ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_SELECTEDIMAGE)), + Child, HGroup, + Child, app->Obj[STRING_CONTROLBARGADGETS_BROWSER_SELECTEDIMAGE] = PopaslObject, + MUIA_CycleChain, TRUE, + MUIA_Disabled, TRUE, + MUIA_Popstring_Button, PopButton(MUII_PopFile), + MUIA_Popstring_String, StringObject, + StringFrame, + End, //String + ASLFR_TitleText, (ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_SELECTEDIMAGE_ASLTITLE), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_SELECTEDIMAGE_SHORTHELP), + End, //PopAsl + Child, app->Obj[DTIMG_CONTROLBARGADGETS_BROWSER_SELECTEDIMAGE] = DataTypesImageObject, + MUIA_ScaDtpic_Name, (ULONG) "", + MUIA_ScaDtpic_FailIfUnavailable, FALSE, + End, //DataTypesMCC + End, //HGroup + + Child, Label2((ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_DISABLEDIMAGE)), + Child, HGroup, + Child, app->Obj[STRING_CONTROLBARGADGETS_BROWSER_DISABLEDIMAGE] = PopaslObject, + MUIA_CycleChain, TRUE, + MUIA_Disabled, TRUE, + MUIA_Popstring_Button, PopButton(MUII_PopFile), + MUIA_Popstring_String, StringObject, + StringFrame, + End, //String + ASLFR_TitleText, (ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_DISABLEDIMAGE_ASLTITLE), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_DISABLEDIMAGE_SHORTHELP), + End, //PopAsl + Child, app->Obj[DTIMG_CONTROLBARGADGETS_BROWSER_DISABLEDIMAGE] = DataTypesImageObject, + MUIA_ScaDtpic_Name, (ULONG) "", + MUIA_ScaDtpic_FailIfUnavailable, FALSE, + End, //DataTypesMCC + End, //HGroup + + Child, VGroup, + Child, Label1((ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_GADGETHELPTEXT)), + Child, HVSpace, + End, //VGroup + Child, app->Obj[TEXTEDITOR_CONTROLBARGADGETS_BROWSER_HELPTEXT] = TextEditorObject, + TextFrame, + MUIA_Background, MUII_TextBack, + MUIA_CycleChain, TRUE, + MUIA_Disabled, TRUE, + MUIA_TextEditor_Contents, "", + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_GADGETHELPTEXT_SHORTHELP), + End, //TextEditor + + Child, Label2((ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_ACTION)), + Child, HGroup, + Child, app->Obj[STRING_CONTROLBARGADGETS_BROWSER_ACTION] = StringObject, + MUIA_Disabled, TRUE, + StringFrame, + MUIA_String_Contents, "", + End, //String + Child, app->Obj[POP_CONTROLBARGADGETS_BROWSER_ACTION] = PopobjectObject, + MUIA_CycleChain, TRUE, + MUIA_Disabled, TRUE, + MUIA_Popstring_Button, PopButton(MUII_PopUp), + MUIA_Popobject_Object, app->Obj[NLISTVIEW_CONTROLBARGADGETS_BROWSER_ACTION] = NListviewObject, + MUIA_NListview_NList, NListObject, + InputListFrame, + MUIA_Background, MUII_ListBack, + MUIA_NList_Format, ",", + MUIA_NList_ConstructHook2, &CmdListConstructHook, + MUIA_NList_DestructHook2, &CmdListDestructHook, + MUIA_NList_DisplayHook2, &CmdListDisplayHook, + MUIA_NList_CompareHook2, &CmdListCompareHook, + MUIA_NList_AdjustWidth, TRUE, + MUIA_NList_SortType, 1, + MUIA_NList_TitleMark, MUIV_NList_TitleMark_Down | 1, + MUIA_NList_SourceArray, CommandsArray, + End, //NListObject + End, //NListviewObject + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_ACTION_SHORTHELP), + End, //PopobjectObject + Child, HVSpace, + End, //HGroup + End, //ColGroup + End, //VGroup + + Child, VSpace(1), + + End, //VGroup + + // --- Standard Window Control Bar + Child, VGroup, + + Child, VSpace(1), + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_NORMAL_GADGETS), + GroupFrame, + MUIA_Background, MUII_GroupBack, + MUIA_Weight, 500, + + Child, HGroup, + Child, VGroup, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_AVAILABLE_GADGETS_SHORTHELP), + Child, CLabel2((ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_AVAILABLE_GADGETS)), + Child, app->Obj[NLISTVIEW_CONTROLBARGADGETS_NORMAL_AVAILABLE] = NListviewObject, + MUIA_Weight, 500, + MUIA_Listview_Input, TRUE, + MUIA_Listview_MultiSelect, MUIV_Listview_MultiSelect_Shifted, + MUIA_Listview_DragType, MUIV_Listview_DragType_Immediate, + MUIA_NListview_NList, app->Obj[NLIST_CONTROLBARGADGETS_NORMAL_AVAILABLE] = ControlBarGadgetsListObject, + InputListFrame, + MUIA_Background, MUII_ListBack, + MUIA_NList_Format, "W=-1, W=-1 MICW=3, W=-1", + MUIA_NList_ShowDropMarks, FALSE, + MUIA_NList_AutoVisible, TRUE, + MUIA_NList_DisplayHook2, &ControlBarGadgetListDisplayHook, + MUIA_NList_ConstructHook2, &ControlBarGadgetListConstructHook, + MUIA_NList_DestructHook2, &ControlBarGadgetListDestructHook, + End, + End, //Listview + End, //VGroup + + Child, VGroup, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_ACTIVE_GADGETS_SHORTHELP), + Child, CLabel2((ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_ACTIVE_GADGETS)), + Child, app->Obj[NLISTVIEW_CONTROLBARGADGETS_NORMAL_ACTIVE] = NListviewObject, + MUIA_Weight, 500, + MUIA_Listview_Input, TRUE, + MUIA_Listview_MultiSelect, MUIV_Listview_MultiSelect_Shifted, + MUIA_Listview_DragType, MUIV_Listview_DragType_Immediate, + MUIA_NListview_NList, app->Obj[NLIST_CONTROLBARGADGETS_NORMAL_ACTIVE] = ControlBarGadgetsListObject, + InputListFrame, + MUIA_Background, MUII_ListBack, + MUIA_NList_Format, "W=-1, W=25 MICW=3, W=-1", + MUIA_NList_DragSortable, TRUE, + MUIA_NList_ShowDropMarks, TRUE, + MUIA_NList_AutoVisible, TRUE, + MUIA_NList_DisplayHook2, &ControlBarGadgetListDisplayHook, + MUIA_NList_ConstructHook2, &ControlBarGadgetListConstructHook, + MUIA_NList_DestructHook2, &ControlBarGadgetListDestructHook, + End, + End, //Listview + End, //VGroup + End, //HGroup + + Child, VSpace(1), + + Child, ColGroup(2), + + Child, Label2((ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_NORMALIMAGE)), + Child, HGroup, + Child, app->Obj[STRING_CONTROLBARGADGETS_NORMAL_NORMALIMAGE] = PopaslObject, + MUIA_CycleChain, TRUE, + MUIA_Disabled, TRUE, + MUIA_Popstring_Button, PopButton(MUII_PopFile), + MUIA_Popstring_String, StringObject, + StringFrame, + End, //String + ASLFR_TitleText, (ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_NORMALIMAGE_ASLTITLE), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_NORMALIMAGE_SHORTHELP), + End, //PopAsl + Child, app->Obj[DTIMG_CONTROLBARGADGETS_NORMAL_NORMALIMAGE] = DataTypesImageObject, + MUIA_ScaDtpic_Name, (ULONG) "", + MUIA_ScaDtpic_FailIfUnavailable, FALSE, + End, //DataTypesMCC + End, //HGroup + + Child, Label2((ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_SELECTEDIMAGE)), + Child, HGroup, + Child, app->Obj[STRING_CONTROLBARGADGETS_NORMAL_SELECTEDIMAGE] = PopaslObject, + MUIA_CycleChain, TRUE, + MUIA_Disabled, TRUE, + MUIA_Popstring_Button, PopButton(MUII_PopFile), + MUIA_Popstring_String, StringObject, + StringFrame, + End, //String + ASLFR_TitleText, (ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_SELECTEDIMAGE_ASLTITLE), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_SELECTEDIMAGE_SHORTHELP), + End, //PopAsl + Child, app->Obj[DTIMG_CONTROLBARGADGETS_NORMAL_SELECTEDIMAGE] = DataTypesImageObject, + MUIA_ScaDtpic_Name, (ULONG) "", + MUIA_ScaDtpic_FailIfUnavailable, FALSE, + End, //DataTypesMCC + End, //HGroup + + Child, Label2((ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_DISABLEDIMAGE)), + Child, HGroup, + Child, app->Obj[STRING_CONTROLBARGADGETS_NORMAL_DISABLEDIMAGE] = PopaslObject, + MUIA_CycleChain, TRUE, + MUIA_Disabled, TRUE, + MUIA_Popstring_Button, PopButton(MUII_PopFile), + MUIA_Popstring_String, StringObject, + StringFrame, + End, //String + ASLFR_TitleText, (ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_DISABLEDIMAGE_ASLTITLE), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_DISABLEDIMAGE_SHORTHELP), + End, //PopAsl + Child, app->Obj[DTIMG_CONTROLBARGADGETS_NORMAL_DISABLEDIMAGE] = DataTypesImageObject, + MUIA_ScaDtpic_Name, (ULONG) "", + MUIA_ScaDtpic_FailIfUnavailable, FALSE, + End, //DataTypesMCC + End, //HGroup + + Child, VGroup, + Child, Label1((ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_GADGETHELPTEXT)), + Child, HVSpace, + End, //VGroup + Child, app->Obj[TEXTEDITOR_CONTROLBARGADGETS_NORMAL_HELPTEXT] = TextEditorObject, + TextFrame, + MUIA_Background, MUII_TextBack, + MUIA_CycleChain, TRUE, + MUIA_Disabled, TRUE, + MUIA_TextEditor_Contents, "", + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_GADGETHELPTEXT_SHORTHELP), + End, //TextEditor + + Child, Label2((ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_ACTION)), + Child, HGroup, + Child, app->Obj[STRING_CONTROLBARGADGETS_NORMAL_ACTION] = StringObject, + MUIA_Disabled, TRUE, + StringFrame, + MUIA_String_Contents, "", + End, //String + Child, app->Obj[POP_CONTROLBARGADGETS_NORMAL_ACTION] = PopobjectObject, + MUIA_CycleChain, TRUE, + MUIA_Disabled, TRUE, + MUIA_Popstring_Button, PopButton(MUII_PopUp), + MUIA_Popobject_Object, app->Obj[NLISTVIEW_CONTROLBARGADGETS_NORMAL_ACTION] = NListviewObject, + MUIA_NListview_NList, NListObject, + InputListFrame, + MUIA_Background, MUII_ListBack, + MUIA_NList_Format, ",", + MUIA_NList_ConstructHook2, &CmdListConstructHook, + MUIA_NList_DestructHook2, &CmdListDestructHook, + MUIA_NList_DisplayHook2, &CmdListDisplayHook, + MUIA_NList_CompareHook2, &CmdListCompareHook, + MUIA_NList_AdjustWidth, TRUE, + MUIA_NList_SortType, 1, + MUIA_NList_TitleMark, MUIV_NList_TitleMark_Down | 1, + MUIA_NList_SourceArray, CommandsArray, + End, //NListObject + End, //NListviewObject + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_WINDOWPAGE_CONTROLBAR_ACTION_SHORTHELP), + End, //PopobjectObject + Child, HVSpace, + End, //HGroup + End, //ColGroup + End, //VGroup + + Child, VSpace(1), + + End, //VGroup + + End, //Register + + // Windows -- Layout + Child, VGroup, + Child, HVSpace, + + Child, VGroup, + GroupFrame, + MUIA_Background, MUII_GroupBack, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_ICONSPAGE_LAYOUTPREFERENCES), + + Child, ColGroup(2), + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_LAYOUT_WBDRAWER)), + Child, app->Obj[CYCLE_ICONS_LAYOUT_WBDRAWER] = CycleObject, + MUIA_Cycle_Entries, cIconLayoutModes, + MUIA_CycleChain, TRUE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_LAYOUT_WBDRAWER_SHORTHELP), + End, //Cycle + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_LAYOUT_WBTOOL)), + Child, app->Obj[CYCLE_ICONS_LAYOUT_WBTOOL] = CycleObject, + MUIA_Cycle_Entries, cIconLayoutModes, + MUIA_CycleChain, TRUE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_LAYOUT_WBTOOL_SHORTHELP), + End, //Cycle + Child, Label1((ULONG) GetLocString(MSGID_ICONSPAGE_LAYOUT_WBPROJECT)), + Child, app->Obj[CYCLE_ICONS_LAYOUT_WBPROJECT] = CycleObject, + MUIA_Cycle_Entries, cIconLayoutModes, + MUIA_CycleChain, TRUE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_ICONSPAGE_LAYOUT_WBPROJECT_SHORTHELP), + End, //Cycle + End, //ColGroup + + End, //VGroup + + Child, HVSpace, + + Child, VGroup, + MUIA_ShowMe, ((struct Library *) DOSBase)->lib_Version >= 51, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_WINDOWPAGE_TRANSPARENCY_WINDOW), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_WINDOWPAGE_TRANSPARENCY_ACTIVEWINDOW), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_WINDOWPAGE_TRANSPARENCY_ACTIVEWINDOW_SHORTHELP), + + Child, ColGroup(3), + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRANSPARENCY_TRANSPARENT)), + + Child, app->Obj[SLIDER_TRANSPARENCY_ACTIVEWINDOW] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 100, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 50, + End, //Slider + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRANSPARENCY_OPAQUE)), + + End, //ColGroup + + End, //VGroup + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_WINDOWPAGE_TRANSPARENCY_INACTIVEWINDOW), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_WINDOWPAGE_TRANSPARENCY_INACTIVEWINDOW_SHORTHELP), + + Child, ColGroup(3), + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRANSPARENCY_TRANSPARENT)), + + Child, app->Obj[SLIDER_TRANSPARENCY_INACTIVEWINDOW] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 100, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 50, + End, //Slider + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRANSPARENCY_OPAQUE)), + + End, //ColGroup + + End, //VGroup + + End, //VGroup + + Child, HVSpace, + End, //VGroup + + End, //Register + End, //VGroup + &NewPrefsPages[6]); +/// +} + +//----------------------------------------------------------------- + +static Object *GenerateTextWindowPage(struct SCAModule *app) +{ +/// + return CreatePrefsPage(app, + VGroup, + MUIA_Background, MUII_PageBack, + + Child, RegisterObject, + MUIA_Register_Titles, cTextWindowPages, + MUIA_CycleChain, TRUE, + + // Fonts + Child, VGroup, + MUIA_Background, MUII_RegisterBack, + + Child, HVSpace, + + Child, VGroup, + + Child, HVSpace, + + Child, HGroup, + Child, HVSpace, + Child, Label1((ULONG) GetLocString(MSGID_TTFONTSPAGE_TTFTEXTWINDOWFONT_ENABLE)), + Child, app->Obj[CHECK_TEXTWINDOW_TTTEXTWINDOWFONT_ENABLE] = CheckMarkHelp(FALSE, MSGID_TTFONTSPAGE_TTFTEXTWINDOWFONT_ENABLE_SHORTHELP), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_TTFONTSPAGE_TTFTEXTWINDOWFONT_ENABLE_SHORTHELP), + End, //HGroup + + Child, app->Obj[GROUP_TEXTWINDOW_FONT_SELECT] = VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_ICONSPAGE_GROUP_ICONFONT), + GroupFrame, + MUIA_Background, MUII_GroupBack, + Child, HGroup, +// Child, Label2((ULONG) GetLocString(MSGID_FILEDISPLAYPAGE_FONT)), + Child, app->Obj[POP_TEXTMODEFONT] = PopaslObject, + MUIA_CycleChain, TRUE, + MUIA_Popstring_Button, PopButton(MUII_PopUp), + MUIA_Popstring_String, BetterStringObject, + StringFrame, + MUIA_String_Contents, "Xen/8", + End, //BetterString + ASLFR_TitleText, (ULONG) GetLocString(MSGID_FILEDISPLAYPAGE_FONT_ASLTITLE), + MUIA_Popasl_Type , ASL_FontRequest, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_FILEDISPLAYPAGE_FONT_SHORTHELP), + End, //Pop + End, //HGroup + + Child, app->Obj[STRING_TEXTMODEFONT_SAMPLE] = FontSampleObject, + TextFrame, + MUIA_Background, MUII_TextBack, + MUIA_FontSample_DemoString, (ULONG) GetLocString(MSGID_TTFONTSPAGE_SAMPLETEXT), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_FILEDISPLAYPAGE_FONT_SAMPLETEXT), + End, //FontSampleMCCObject + End, //VGroup + + Child, app->Obj[GROUP_TEXTWINDOW_TTTEXTWINDOWFONT] = HGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_TTFONTSPAGE_TEXTWINDOWFONT), + GroupFrame, + MUIA_Background, MUII_GroupBack, + MUIA_Disabled, TRUE, + + Child, VGroup, + Child, app->Obj[POPSTRING_TEXTWINDOW_TTTEXTWINDOWFONT] = PopstringObject, + MUIA_CycleChain, TRUE, + MUIA_Popstring_Button, PopButton(MUII_PopUp), + MUIA_Popstring_String, BetterStringObject, + StringFrame, + MUIA_String_Contents, " ", + End, //BetterString + MUIA_Popstring_OpenHook, &TextWindowTtfPopOpenHook, + MUIA_Popstring_CloseHook, &TextWindowTtfPopCloseHook, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_TTFONTSPAGE_TEXTWINDOWFONT_SHORTHELP), + End, //PopstringObject + + Child, app->Obj[MCC_TEXTWINDOW_TTTEXTWINDOWFONT_SAMPLE] = FontSampleObject, + TextFrame, + MUIA_Background, MUII_TextBack, + MUIA_FontSample_DemoString, (ULONG) GetLocString(MSGID_TTFONTSPAGE_SAMPLETEXT), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_TTFONTSPAGE_TEXTWINDOWFONT_SAMPLETEXT_SHORTHELP), + End, //FontSampleMCCObject + End, //VGroup + End, //HGroup + End, //VGroup + + Child, HVSpace, + + End, //VGroup + + // Columns + Child, VGroup, + MUIA_Background, MUII_RegisterBack, + + Child, HVSpace, + + Child, HGroup, + MUIA_Weight, 500, + + Child, VGroup, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_FILEDISPLAYPAGE_AVAILABLE_COLUMNS_SHORTHELP), + Child, CLabel2((ULONG) GetLocString(MSGID_FILEDISPLAYPAGE_AVAILABLE_COLUMNS)), + Child, app->Obj[NLISTVIEW_STORAGE_FILEDISPLAY] = NListviewObject, + MUIA_Listview_Input, TRUE, + MUIA_Listview_MultiSelect, MUIV_Listview_MultiSelect_Shifted, + MUIA_Listview_DragType, MUIV_Listview_DragType_Immediate, + MUIA_NListview_NList, app->Obj[NLIST_STORAGE_FILEDISPLAY] = TextWindowColumnsListObject, + InputListFrame, + MUIA_Background, MUII_ListBack, + //MUIA_NList_Format, "", + MUIA_NList_DragSortable, FALSE, + MUIA_NList_ShowDropMarks, FALSE, + MUIA_NList_AutoVisible, TRUE, + MUIA_NList_DisplayHook2, &FileDisplayDisplayHook, + MUIA_NList_ConstructHook2, &FileDisplayConstructHook, + MUIA_NList_DestructHook2, &FileDisplayDestructHook, + End, + End, //Listview + End, //VGroup + + Child, VGroup, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_FILEDISPLAYPAGE_COLUMNS_INUSE_SHORTHELP), + Child, CLabel2((ULONG) GetLocString(MSGID_FILEDISPLAYPAGE_COLUMNS_INUSE)), + Child, app->Obj[NLISTVIEW_USE_FILEDISPLAY] = NListviewObject, + MUIA_Listview_Input, TRUE, + MUIA_Listview_MultiSelect, MUIV_Listview_MultiSelect_Shifted, + MUIA_Listview_DragType, MUIV_Listview_DragType_Immediate, + MUIA_NListview_NList, app->Obj[NLIST_USE_FILEDISPLAY] = TextWindowColumnsListObject, + InputListFrame, + MUIA_Background, MUII_ListBack, + //MUIA_NList_Format, "", + MUIA_NList_DragSortable, TRUE, + MUIA_NList_ShowDropMarks, TRUE, + MUIA_NList_AutoVisible, TRUE, + MUIA_NList_DisplayHook2, &FileDisplayDisplayHook, + MUIA_NList_ConstructHook2, &FileDisplayConstructHook, + MUIA_NList_DestructHook2, &FileDisplayDestructHook, + End, + End, //Listview + End, //VGroup + End, //HGroup + + Child, HVSpace, + End, //VGroup + + // Selection marks + Child, VGroup, + MUIA_Background, MUII_RegisterBack, + + Child, app->Obj[GROUP_TEXTWINDOWS_SELECTIONMARK] = VGroup, + +// Child, HVSpace, + + Child, HGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_TEXTWINDOWSPAGE_GROUP_BASECOLOR), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, app->Obj[COLORADJUST_TEXTWINDOWS_SELECTIONMARK] = ColoradjustObject, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_TEXTWINDOWSPAGE_SELECTIONMARK_BASECOLOR_SHORTHELP), + End, //ColoradjustObject + End, //HGroup + +// Child, HVSpace, + + Child, HGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_TEXTWINDOWSPAGE_SELECTION_BORDER_TRANSPARENCY), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRANSPARENCY_TRANSPARENT)), + + Child, app->Obj[SLIDER_TEXTWINDOWS_SELECTBORDERTRANSPARENCY] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 255, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 255, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_TEXTWINDOWSPAGE_SELECTIONMARK_BORDER_TRANSPARENCY_SHORTHELP), + End, //Slider + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRANSPARENCY_OPAQUE)), + End, //HGroup + + Child, HGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_TEXTWINDOWSPAGE_SELECTION_FILL_TRANSPARENCY), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRANSPARENCY_TRANSPARENT)), + + Child, app->Obj[SLIDER_TEXTWINDOWS_SELECTFILLTRANSPARENCY] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 0, + MUIA_Numeric_Max, 255, + MUIA_Slider_Horiz, TRUE, + MUIA_Numeric_Value, 128, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_TEXTWINDOWSPAGE_SELECTIONMARK_FILL_TRANSPARENCY_SHORTHELP), + End, //Slider + + Child, Label1((ULONG) GetLocString(MSGID_DRAGNDROPPAGE_TRANSPARENCY_OPAQUE)), + End, //HGroup + + Child, HVSpace, + + End, //VGroup + + Child, HGroup, + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, app->Obj[MCC_TEXTWINDOWS_SELECTMARKER_SAMPLE] = SelectMarkSampleObject, + TextFrame, + MUIA_Background, MUII_TextBack, + TIHA_DemoString, (ULONG) GetLocString(MSGID_TTFONTSPAGE_SAMPLETEXT), + End, // + End, //HGroup + + End, //VGroup + + // Miscellaneous + Child, VGroup, + MUIA_Background, MUII_RegisterBack, + + Child, HVSpace, + + Child, HGroup, + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, ColGroup(2), + Child, Label1((ULONG) GetLocString(MSGID_TEXTWINDOWSPAGE_DRAWERSORT)), + Child, app->Obj[CYCLE_DRAWERSORTMODE] = CycleObject, + MUIA_CycleChain, TRUE, + MUIA_Cycle_Entries, cDrawerSortMode, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_TEXTWINDOWSPAGE_DRAWERSORT_SHORTHELP), + End, //CycleObject + End, //ColGroup + Child, HVSpace, + + End, //HGroup + + Child, HGroup, + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, ColGroup(2), + + Child, Label1((ULONG) GetLocString(MSGID_FILEDISPLAYPAGE_SOFTLINKS_UNDERLINED)), + Child, app->Obj[SOFTTEXTSLINK] = CheckMarkHelp(FALSE, MSGID_FILEDISPLAYPAGE_SOFTLINKS_UNDERLINED_SHORTHELP), + + Child, Label1((ULONG) GetLocString(MSGID_FILEDISPLAYPAGE_STRIPED)), + Child, app->Obj[CHECK_STRIPED_WINDOW] = CheckMarkHelp(FALSE, MSGID_FILEDISPLAYPAGE_STRIPED_SHORTHELP), + + Child, Label1((ULONG) GetLocString(MSGID_FILEDISPLAYPAGE_SELECTTEXTICONNAME)), + Child, app->Obj[CHECK_SELECTTEXTICONNAME] = CheckMarkHelp(FALSE, MSGID_FILEDISPLAYPAGE_SELECTTEXTICONNAME_SHORTHELP), + End, //ColGroup + Child, HVSpace, + + End, //HGroup + Child, HVSpace, + + End, //VGroup + End, //Register + End, //VGroup + &NewPrefsPages[7]); +/// +} + +//----------------------------------------------------------------- + +static Object *GenerateTrueTypeFontsPage(struct SCAModule *app) +{ +/// + return CreatePrefsPage(app, + VGroup, + MUIA_Background, MUII_PageBack, + + Child, HVSpace, + + Child, app->Obj[GROUP_TTGLOBALS] = HGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_TTFONTSPAGE_GLOBALS), + GroupFrame, + MUIA_Background, MUII_GroupBack, + MUIA_Disabled, TRUE, + + Child, VGroup, + Child, HVSpace, + + Child, ColGroup(2), + Child, Label1((ULONG) GetLocString(MSGID_TTFONTSPAGE_ANTIALIASING)), + Child, app->Obj[CYCLE_TTANTIALIAS] = CycleObject, + MUIA_CycleChain, TRUE, + MUIA_Cycle_Entries, cTTFontsAntiAliasing, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_TTFONTSPAGE_ANTIALIASING_SHORTHELP), + End, //Radio + End, //ColGroup + + Child, HVSpace, + + Child, ColGroup(2), + Child, Label(GetLocString(MSGID_TTFONTSPAGE_GAMMA)), + Child, app->Obj[SLIDER_TTGAMMA] = TTGammaSliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Min, 100, + MUIA_Numeric_Max, 5000, + MUIA_Numeric_Value, 2500, + MUIA_ShortHelp, GetLocString(MSGID_TTFONTSPAGE_GAMMA_SHORTHELP), + End, + End, //ColGroup + + Child, HVSpace, + End, //HGroup + End, //HGroup + + Child, app->Obj[GROUP_TTSCREENFONT] = HGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_TTFONTSPAGE_SCREENFONT), + GroupFrame, + MUIA_Background, MUII_GroupBack, + MUIA_Disabled, TRUE, + + Child, VGroup, + Child, HGroup, + Child, HVSpace, + Child, Label1((ULONG) GetLocString(MSGID_TTFONTSPAGE_SCREENFONT_ENABLE)), + Child, app->Obj[CHECK_TTSCREENFONT_ENABLE] = CheckMarkHelp(FALSE, MSGID_TTFONTSPAGE_SCREENFONT_ENABLE_SHORTHELP), + + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_TTFONTSPAGE_SCREENFONT_ENABLE_SHORTHELP), + End, //HGroup + + Child, app->Obj[POPSTRING_TTSCREENFONT] = PopstringObject, + MUIA_CycleChain, TRUE, + MUIA_Popstring_Button, PopButton(MUII_PopUp), + MUIA_Popstring_String, BetterStringObject, + StringFrame, + MUIA_String_Contents, " ", + End, //BetterString + MUIA_Popstring_OpenHook, &ScreenTtfPopOpenHook, + MUIA_Popstring_CloseHook, &ScreenTtfPopCloseHook, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_TTFONTSPAGE_SCREENFONT_SHORTHELP), + End, //PopstringObject + + Child, app->Obj[MCC_TTSCREENFONT_SAMPLE] = FontSampleObject, + TextFrame, + MUIA_Background, MUII_TextBack, + MUIA_FontSample_DemoString, (ULONG) GetLocString(MSGID_TTFONTSPAGE_SAMPLETEXT), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_TTFONTSPAGE_SCREENFONT_SAMPLETEXT_SHORTHELP), + End, //FontSampleMCCObject + + End, //VGroup + + End, //HGroup + + Child, HVSpace, + + Child, app->Obj[GROUP_TTICONFONT] = HGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_TTFONTSPAGE_ICONFONT), + GroupFrame, + MUIA_Background, MUII_GroupBack, + MUIA_Disabled, TRUE, + + Child, VGroup, + Child, HGroup, + Child, HVSpace, + Child, Label1((ULONG) GetLocString(MSGID_TTFONTSPAGE_ICONFONT_ENABLE)), + Child, app->Obj[CHECK_TTICONFONT_ENABLE] = CheckMarkHelp(FALSE, MSGID_FONTSPAGE_TTFICONFONT_ENABLE_SHORTHELP), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_FONTSPAGE_TTFICONFONT_ENABLE_SHORTHELP), + End, //HGroup + + Child, app->Obj[POPSTRING_TTICONFONT] = PopstringObject, + MUIA_CycleChain, TRUE, + MUIA_Popstring_Button, PopButton(MUII_PopUp), + MUIA_Popstring_String, BetterStringObject, + StringFrame, + MUIA_String_Contents, " ", + End, //BetterString + MUIA_Popstring_OpenHook, &IconTtfPopOpenHook, + MUIA_Popstring_CloseHook, &IconTtfPopCloseHook, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_TTFONTSPAGE_ICONFONT_SHORTHELP), + End, //PopstringObject + + Child, app->Obj[MCC_TTICONFONT_SAMPLE] = FontSampleObject, + TextFrame, + MUIA_Background, MUII_TextBack, + MUIA_FontSample_DemoString, (ULONG) GetLocString(MSGID_TTFONTSPAGE_SAMPLETEXT), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_TTFONTSPAGE_ICONFONT_SAMPLETEXT_SHORTHELP), + End, //FontSampleMCCObject + End, //VGroup + + End, //HGroup + + Child, HVSpace, + + Child, app->Obj[GROUP_TTTEXTWINDOWFONT] = HGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_TTFONTSPAGE_TEXTWINDOWFONT), + GroupFrame, + MUIA_Background, MUII_GroupBack, + MUIA_Disabled, TRUE, + + Child, VGroup, + Child, HGroup, + Child, HVSpace, + Child, Label1((ULONG) GetLocString(MSGID_TTFONTSPAGE_TTFTEXTWINDOWFONT_ENABLE)), + Child, app->Obj[CHECK_TTTEXTWINDOWFONT_ENABLE] = CheckMarkHelp(FALSE, MSGID_TTFONTSPAGE_TTFTEXTWINDOWFONT_ENABLE_SHORTHELP), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_TTFONTSPAGE_TTFTEXTWINDOWFONT_ENABLE_SHORTHELP), + End, //HGroup + + Child, app->Obj[POPSTRING_TTTEXTWINDOWFONT] = PopstringObject, + MUIA_CycleChain, TRUE, + MUIA_Popstring_Button, PopButton(MUII_PopUp), + MUIA_Popstring_String, BetterStringObject, + StringFrame, + MUIA_String_Contents, " ", + End, //BetterString + MUIA_Popstring_OpenHook, &TextWindowTtfPopOpenHook, + MUIA_Popstring_CloseHook, &TextWindowTtfPopCloseHook, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_TTFONTSPAGE_TEXTWINDOWFONT_SHORTHELP), + End, //PopstringObject + + Child, app->Obj[MCC_TTTEXTWINDOWFONT_SAMPLE] = FontSampleObject, + TextFrame, + MUIA_Background, MUII_TextBack, + MUIA_FontSample_DemoString, (ULONG) GetLocString(MSGID_TTFONTSPAGE_SAMPLETEXT), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_TTFONTSPAGE_TEXTWINDOWFONT_SAMPLETEXT_SHORTHELP), + End, //FontSampleMCCObject + End, //VGroup + + End, //HGroup + + Child, HVSpace, + + End, //VGroup + &NewPrefsPages[8]); +/// +} + +//----------------------------------------------------------------- + +static Object *GenerateMiscPage(struct SCAModule *app) +{ +/// + return CreatePrefsPage(app, + VGroup, + MUIA_Background, MUII_PageBack, + + Child, HVSpace, + + Child, VGroup, + MUIA_FrameTitle, GetLocString(MSGID_MISCPAGE_POPUPMENUS), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, ColGroup(2), + Child, Label1((ULONG) GetLocString(MSGID_MISCPAGE_POPUP_SELECTED_ALWAYS)), + Child, HGroup, + Child, app->Obj[CHECK_MISCPAGE_POPUP_SELECTED_ALWAYS] = CheckMarkHelp(FALSE, MSGID_TTFONTSPAGE_TTFTEXTWINDOWFONT_ENABLE_SHORTHELP), + Child, HVSpace, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_MISCPAGE_POPUP_SELECTED_ALWAYS_SHORTHELP), + End, //HGroup + + Child, Label1((ULONG) GetLocString(MSGID_MISCPAGE_POPUP_SELECTED_HOTKEY)), + Child, HGroup, + Child, app->Obj[POPUP_SELECTED_HOTKEY] = HotkeyStringObject, + StringFrame, + MUIA_String_Contents, "", + MUIA_HotkeyString_Snoop, FALSE, + End, //HotkeyString + Child, app->Obj[POPUP_SELECTED_HOTKEY_SCAN] = ScanButton, + End, //HGroup + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_MISCPAGE_POPUP_SELECTED_HOTKEY_SHORTHELP), + End, //ColGroup + + Child, HVSpace, + End, //VGroup + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_MISCPAGE_LABELS_STACK), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, app->Obj[GROUP2_DEFAULTSTACKSIZE] = HGroup, + MUIA_Background, MUII_GroupBack, + + Child, FloattextObject, + TextFrame, + MUIA_Floattext_Justify, FALSE, + MUIA_Floattext_Text, (ULONG) GetLocString(MSGID_MISCPAGE_DEFAULTSTACKSIZE_OS35), + End, //Floattext + Child, app->Obj[POP_WORKBENCHPREFS] = ImageObject, + MUIA_InputMode, MUIV_InputMode_RelVerify, + MUIA_Image_Spec, "6:18", //MUII_PopUp, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_MISCPAGE_POP_WORKBENCHPREFS_SHORTHELP), + End, //Image + End, //HGroup + + Child, app->Obj[GROUP_DEFAULTSTACKSIZE] = ColGroup(2), + Child, Label1((ULONG) GetLocString(MSGID_MISCPAGE_DEFAULTSTACKSIZE)), + Child, app->Obj[SLIDER_DEFAULTSTACKSIZE] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Numeric_Format, "%luK", + MUIA_Slider_Horiz, TRUE, + MUIA_Slider_Level, 16, + MUIA_Slider_Min, 8, + MUIA_Slider_Max, 2048, + End, //Slider + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_MISCPAGE_DEFAULTSTACKSIZE_SHORTHELP), + End, //ColGroup + + Child, HVSpace, + End, //VGroup + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_MISCPAGE_LABELS_UNDOSTEPS), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, ColGroup(2), + Child, Label1((ULONG) GetLocString(MSGID_MISCPAGE_UNDOSTEPS)), + Child, app->Obj[SLIDER_UNDOSTEPS] = SliderObject, + MUIA_CycleChain, TRUE, + MUIA_Slider_Horiz, TRUE, + MUIA_Slider_Level, 10, + MUIA_Slider_Min, 1, + MUIA_Slider_Max, 100, + End, //Slider + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_MISCPAGE_UNDOSTEPS_SHORTHELP), + End, //ColGroup + + Child, HVSpace, + End, //VGroup + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_MISCPAGE_LABELS_FILEOPERATIONS), + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, app->Obj[GROUP_COPYBUFFERSIZE] = ColGroup(2), + Child, Label1((ULONG) GetLocString(MSGID_MISCPAGE_COPYBUFFERSIZE)), + Child, app->Obj[SLIDER_COPYBUFFERSIZE] = BufferSizeSliderObject, + MUIA_CycleChain, TRUE, + MUIA_Slider_Horiz, TRUE, + MUIA_Slider_Level, 28 - 15, + MUIA_Slider_Min, 15, + MUIA_Slider_Max, 28, + End, //Slider + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_MISCPAGE_COPYBUFFERSIZE_SHORTHELP), + End, //ColGroup + + Child, HVSpace, + End, //VGroup + + + Child, VGroup, + //MUIA_FrameTitle, "", + GroupFrame, + MUIA_Background, MUII_GroupBack, + + Child, HVSpace, + + Child, HGroup, + Child, HVSpace, + + Child, ColGroup(2), + Child, Label1((ULONG) GetLocString(MSGID_MISCPAGE_MENU_CURRENTDIR)), + Child, app->Obj[CHECK_MENUCURRENTDIR] = CheckMarkHelp(FALSE, MSGID_MISCPAGE_MENU_CURRENTDIR_SHORTHELP), + + Child, Label1((ULONG) GetLocString(MSGID_MISCPAGE_HARD_EMULATION)), + Child, app->Obj[CHECK_HARDEMULATION] = CheckMarkHelp(FALSE, MSGID_MISCPAGE_HARD_EMULATION_SHORTHELP), + + Child, Label1((ULONG) GetLocString(MSGID_MISCPAGE_USE_EXALL)), + Child, app->Obj[CHECK_USEEXALL] = CheckMarkHelp(FALSE, MSGID_MISCPAGE_USE_EXALL_SHORTHELP), + + Child, Label1((ULONG) GetLocString(MSGID_MISCPAGE_CREATE_LINKS)), + Child, app->Obj[CYCLE_CREATELINKS] = CycleObject, + MUIA_CycleChain, TRUE, + MUIA_Cycle_Entries, cCreateLinkTypes, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_MISCPAGE_CREATE_LINKS_SHORTHELP), + End, //Image + + + End, //ColGroup + + Child, HVSpace, + End, //HGroup + + Child, HVSpace, + + End, //VGroup + + Child, HVSpace, + + End, //VGroup + &NewPrefsPages[9]); +/// +} + +//----------------------------------------------------------------- + +static Object *GeneratePluginsPage(struct SCAModule *app) +{ +/// + return CreatePrefsPage(app, + VGroup, + MUIA_Background, MUII_PageBack, + + Child, VSpace(2), + + Child, VGroup, + Child, HGroup, + //Child, HVSpace, + Child, VGroup, + Child, Label((ULONG) GetLocString(MSGID_PLUGINSPAGE_INSTALLEDPLUGINS)), + Child, app->Obj[PLUGIN_LISTVIEW] = NListviewObject, + MUIA_NListview_NList, app->Obj[PLUGIN_LIST] = NListObject, + InputListFrame, + MUIA_CycleChain, TRUE, + MUIA_Background, MUII_ListBack, + MUIA_NList_Format, "W=-1, W=-1", + MUIA_NList_DefaultObjectOnClick, TRUE, + MUIA_NList_ShowDropMarks, FALSE, + //MUIA_NList_AdjustWidth, TRUE, + MUIA_NList_AutoVisible, TRUE, + MUIA_NList_Title, TRUE, + MUIA_NList_TitleSeparator, TRUE, + MUIA_NList_SortType, 0, + MUIA_NList_TitleMark, MUIV_NList_TitleMark_Down | 0, + MUIA_NList_MinColSortable, 0, + MUIA_NList_DisplayHook2, &PluginListDisplayHook, + MUIA_NList_ConstructHook2, &PluginListConstructHook, + MUIA_NList_DestructHook2, &PluginListDestructHook, + MUIA_NList_CompareHook2, &PluginListCompareHook, + End, //NList + MUIA_Listview_MultiSelect, MUIV_Listview_MultiSelect_None, + MUIA_Listview_DragType, MUIV_Listview_DragType_None, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_PLUGINSPAGE_INSTALLEDPLUGINS_SHORTHELP), + End, //Listview + + Child, BalanceObject, + End, //Balance + + Child, HGroup, + Child, HVSpace, + Child, app->Obj[ADD_PLUGIN] = TextObject, + MUIA_InputMode, MUIV_InputMode_RelVerify, + ButtonFrame, + MUIA_CycleChain, TRUE, + MUIA_Background, MUII_ButtonBack, + MUIA_Text_Contents, (ULONG) GetLocString(MSGID_PLUGINSPAGE_ADD_NEW), + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_PLUGINSPAGE_ADD_NEW_SHORTHELP), + End, //TextObject + + Child, HVSpace, + + Child, app->Obj[REMOVE_PLUGIN] = TextObject, + MUIA_InputMode, MUIV_InputMode_RelVerify, + ButtonFrame, + MUIA_CycleChain, TRUE, + MUIA_Background, MUII_ButtonBack, + MUIA_Text_Contents, (ULONG) GetLocString(MSGID_PLUGINSPAGE_REMOVE_SELECTED), + MUIA_Disabled, TRUE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_PLUGINSPAGE_REMOVE_SELECTED_SHORTHELP), + End, //TextObject + + Child, HVSpace, + + End, //HGroup + + End, //VGroup + + //Child, HVSpace, + End, //HGroup + + Child, ColGroup(2), + Child, VGroup, + Child, Label((ULONG) GetLocString(MSGID_PLUGINSPAGE_NAME)), + Child, app->Obj[PLUGIN_NAME] = TextObject, + TextFrame, + MUIA_Background, MUII_ReadListBack, + MUIA_Text_Contents,"", + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_PLUGINSPAGE_NAME_SHORTHELP), + End, + + Child, Label1((ULONG) GetLocString(MSGID_PLUGINSPAGE_FILENAME)), + Child, app->Obj[PLUGIN_FILENAME] = TextObject, + TextFrame, + MUIA_Background, MUII_ReadListBack, + MUIA_Text_Contents, "", + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_PLUGINSPAGE_FILENAME_SHORTHELP), + End, + + Child, Label1((ULONG) GetLocString(MSGID_PLUGINSPAGE_VERSION)), + Child, app->Obj[PLUGIN_VERSION] = TextObject, + TextFrame, + MUIA_Background, MUII_ReadListBack, + MUIA_Text_Contents, "", + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_PLUGINSPAGE_VERSION_SHORTHELP), + End, + + Child, HGroup, + MUIA_InputMode, MUIV_InputMode_RelVerify, + ButtonFrame, + MUIA_Background, MUII_ButtonBack, +/* currently unused */ MUIA_Disabled, TRUE, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_PLUGINSPAGE_EDIT_PREFERENCES_SHORTHELP), + + Child, TextObject, + MUIA_Text_Contents, (ULONG) GetLocString(MSGID_PLUGINSPAGE_EDIT_PREFERENCES), + End, + + Child, ImageObject, + MUIA_Image_Spec, "6:18", //MUII_PopUp, + End, //Image + End, //HGroup + End, //VGroup + + Child, VGroup, + Child, Label1((ULONG) GetLocString(MSGID_PLUGINSPAGE_DESCRIPTION)), + Child, app->Obj[PLUGIN_DESCRIPTION] = FloattextObject, + TextFrame, + MUIA_Background, MUII_ReadListBack, + MUIA_Floattext_Justify, FALSE, + MUIA_Floattext_Text, "", + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_PLUGINSPAGE_DESCRIPTION_SHORTHELP), + End, //FloattextObject + + Child, Label1((ULONG) GetLocString(MSGID_PLUGINSPAGE_CREATOR)), + Child, app->Obj[PLUGIN_CREATOR] = FloattextObject, + TextFrame, + MUIA_Background, MUII_ReadListBack, + MUIA_Floattext_Justify, FALSE, + MUIA_Floattext_Text, "", + MUIA_VertWeight, 20, + MUIA_ShortHelp, (ULONG) GetLocString(MSGID_PLUGINSPAGE_CREATOR_SHORTHELP), + End, //FloattextObject + + End, //VGroup + End, //ColGroup + End, //VGroup + Child, VSpace(2), + + End, //VGroup + &NewPrefsPages[10]); +/// +} + +//----------------------------------------------------------------- + +static Object *GenerateModulesPage(struct SCAModule *app) +{ +/// + return CreatePrefsPage(app, + VGroup, + MUIA_Background, MUII_PageBack, + + Child, HVSpace, + + Child, VGroup, + MUIA_FrameTitle, (ULONG) GetLocString(MSGID_MODULESPAGE_MODULE_PREFERENCES), + GroupFrame, + MUIA_Background, MUII_GroupBack, + MUIA_Weight, 500, + + Child, HGroup, + + Child, app->Obj[NLISTVIEW_MODULES] = NListviewObject, + MUIA_Listview_Input, FALSE, + MUIA_CycleChain, 1, + MUIA_Listview_MultiSelect, MUIV_Listview_MultiSelect_None, + MUIA_Listview_DragType, MUIV_Listview_DragType_None, + MUIA_NListview_NList, app->Obj[NLIST_MODULES] = NListObject, + MUIA_NList_DefaultObjectOnClick, TRUE, + MUIA_Background, MUII_ListBack, + InputListFrame, + MUIA_NList_Format, ",,", + MUIA_NList_DragSortable, FALSE, + MUIA_NList_ShowDropMarks, FALSE, + MUIA_NList_AutoVisible, TRUE, + MUIA_NList_DisplayHook2, &ModulesListDisplayHook, + MUIA_NList_ConstructHook2, &ModulesListConstructHook, + MUIA_NList_DestructHook2, &ModulesListDestructHook, + End, + End, //Listview + + End, //HGroup + End, //VGroup + + Child, HVSpace, + + End, //VGroup + &NewPrefsPages[11]); +/// +} + +//----------------------------------------------------------------- + + diff --git a/scalos/Prefs/MainPrefs/ScalosPrefs.h b/scalos/Prefs/MainPrefs/ScalosPrefs.h new file mode 100644 index 000000000..cf64690df --- /dev/null +++ b/scalos/Prefs/MainPrefs/ScalosPrefs.h @@ -0,0 +1,627 @@ +// ScalosPrefs.h +// $Date$ +// $Revision$ + + +#ifndef SCALOSPREFS_H +#define SCALOSPREFS_H + +#include +#include +#include +#include + +#define MAX_FILENAME 256 +#define MAX_FONTNAME 128 +#define MAX_TTFONTDESC 256 + +// Limits for plugin strings +#define MAX_PLUGIN_CLASSNAME 50 +#define MAX_PLUGIN_SUPERCLASSNAME 50 +#define MAX_PLUGIN_REALNAME 100 +#define MAX_PLUGIN_DESCRIPTION 200 +#define MAX_PLUGIN_CREATORNAME 50 + + +#define SYS_FONTPREFS_NAME "SYS:Prefs/Font" +#define SYS_WORKBENCHPREFS_NAME "SYS:Prefs/Workbench" + + +enum ObjIndex +{ + APPLICATION, + WINDOW_MAIN, + WINDOW_ICONFRAMES, + WINDOW_SPLASH, + GROUP_MAIN, + TEXT_SPLASHWINDOW, + LISTVIEW, + LIST, + SAVE, + USE, + CANCEL, + GROUP, + CYCLE_SCREENTITLEMODE, + STORAGE_TIPS, + USED_TIPS, + CHECK_TOOLTIPS, + SLIDER_TITLEREFRESH, + CHECK_TITLEMEM, + SLIDER_WINTITLEREFRESH, + CHECK_WINTITLEMEM, + SLIDER_TIPDELAY, + CHECK_MULTILINES, + CHECK_HILITEUNDERMOUSE, + SLIDER_LABELSPACE, + CYCLE_LABELSTYLE, + NLIST_STORAGE_FILEDISPLAY, + NLISTVIEW_STORAGE_FILEDISPLAY, + STRING_CONSOLENAME, + CLOSEWB, + DROPSTART, + CHECK_AUTOLEAVEOUT, + POP_TEXTMODEFONT, + GROUP_TEXTWINDOW_FONT_SELECT, + STRING_TEXTMODEFONT_SAMPLE, + GROUP_TEXTWINDOW_TTTEXTWINDOWFONT, + MCC_TEXTWINDOW_TTTEXTWINDOWFONT_SAMPLE, + CHECK_TEXTWINDOW_TTTEXTWINDOWFONT_ENABLE, + POPSTRING_TEXTWINDOW_TTTEXTWINDOWFONT, + CYCLE_DRAWERSORTMODE, + SOFTTEXTSLINK, + SOFTICONSLINK, + TOOLTIP_SETTINGSGROUP, + CHECK_SHOWSPLASH, + SLIDER_SPLASHCLOSE, + GROUP_SCRTITLE, + +// MOD_DELETE, +// MOD_TRASH, +// MOD_EXECOM, +// MOD_INFO, +// MOD_NEWDRAWER, +// MOD_REBOOT, +// MOD_RENAME, +// MOD_SYSINFO, +// MOD_DUMMY, +// MOD_DUMMY2, + + CYCLE_ROUTINE, + CYCLE_STYLE, + POP_FONTPREFS, + MCC_ICONFONT_SAMPLE, + POP_ICONFONT, + GROUP_ICONSPAGE_TTICONFONT, + CHECK_ICONSPAGE_TTICONFONT_ENABLE, + POPSTRING_ICONSPAGE_TTICONFONT, + MCC_ICONSPAGE_TTICONFONT_SAMPLE, + POP_WORKBENCHPREFS, + + GROUP_ICONFONT_NOTICE, + GROUP_ICONFONT_SELECT, + GROUP_ICONSPAGE_ICONFONT, + + ADD_PLUGIN, + REMOVE_PLUGIN, + PLUGIN_FILENAME, + PLUGIN_NAME, + PLUGIN_VERSION, + PLUGIN_LIST, + PLUGIN_LISTVIEW, + PLUGIN_DESCRIPTION, + PLUGIN_CREATOR, + + CYCLE_SHOWTHUMBNAILS, + CHECK_SHOWTHUMBNAILS_AS_DEFAULT, + CYCLE_THUMBNAILSIZE, + SLIDER_THUMBNAILS_MAXAGE, + SLIDER_THUMBNAILS_MINSIZE_LIMIT, + SLIDER_THUMBNAILS_QUALITY, + CHECK_THUMBNAILS_SQUARE, + CHECK_THUMBNAILS_BACKFILL, + SLIDER_ICONTRANSPARENCY_THUMBNAILBACK, + GROUP_THUMBNAIL_BACKFILL_TRANSPARENCY, + SLIDER_ICONSPAGE_NOMINALSIZE, + CYCLE_ICONMINSIZE, + CYCLE_ICONMAXSIZE, + GOUP_ICONSIZE_MIN_SAMPLE, + GOUP_ICONSIZE_MAX_SAMPLE, + CHECK_AUTOREMOVE, + CHECK_EASY_MULTISELECT, + CHECK_EASY_MULTIDRAG, + CHECK_GROUPDRAG, + CHECK_ENABLE_DROPMENU, + SLIDER_POPOPENWINDOW_DELAY, + COPY_HOTKEY, + COPY_HOTKEY_SCAN, + MAKELINK_HOTKEY, + MAKELINK_HOTKEY_SCAN, + MOVE_HOTKEY, + MOVE_HOTKEY_SCAN, + SINGLE_WINDOW_LASSO_HOTKEY, + SINGLE_WINDOW_LASSO_HOTKEY_SCAN, + SLIDER_WBSDELAY, + SLIDER_DISKREFRESH, + CHECK_ICONMASK, + CHECK_MULTISELECT, + SLIDER_ICONRMAP_PRECISION, + CHECK_NIMASK, + CHECK_DEFFIRST, + SLIDER_ICONTRANSPARENCY_DRAG, + SLIDER_ICONTRANSPARENCY_SHADOW, + SLIDER_ICONTRANSPARENCY_DEFICONS, + CHECK_MISCPAGE_POPUP_SELECTED_ALWAYS, + + ICONLEFT, + ICONTOP, + ICONRIGHT, + ICONBOTTOM, + CHECK_ICONSSAVE, + RADIO_BOBLOOK, + CYCLE_TRANSPMODE, + + CHECK_SEL_ICONTEXT_RECTANGLE, + SLIDER_SEL_ICONTEXT_RECT_BORDERX, + SLIDER_SEL_ICONTEXT_RECT_BORDERY, + SLIDER_SEL_ICONTEXT_RECT_RADIUS, + + NLISTVIEW_CONTROLBARGADGETS_NORMAL_AVAILABLE, + NLIST_CONTROLBARGADGETS_NORMAL_AVAILABLE, + NLISTVIEW_CONTROLBARGADGETS_NORMAL_ACTIVE, + NLIST_CONTROLBARGADGETS_NORMAL_ACTIVE, + STRING_CONTROLBARGADGETS_NORMAL_NORMALIMAGE, + STRING_CONTROLBARGADGETS_NORMAL_SELECTEDIMAGE, + STRING_CONTROLBARGADGETS_NORMAL_DISABLEDIMAGE, + POP_CONTROLBARGADGETS_NORMAL_ACTION, + NLISTVIEW_CONTROLBARGADGETS_NORMAL_ACTION, + STRING_CONTROLBARGADGETS_NORMAL_ACTION, + TEXTEDITOR_CONTROLBARGADGETS_NORMAL_HELPTEXT, + DTIMG_CONTROLBARGADGETS_NORMAL_NORMALIMAGE, + DTIMG_CONTROLBARGADGETS_NORMAL_SELECTEDIMAGE, + DTIMG_CONTROLBARGADGETS_NORMAL_DISABLEDIMAGE, + + NLISTVIEW_CONTROLBARGADGETS_BROWSER_AVAILABLE, + NLIST_CONTROLBARGADGETS_BROWSER_AVAILABLE, + NLISTVIEW_CONTROLBARGADGETS_BROWSER_ACTIVE, + NLIST_CONTROLBARGADGETS_BROWSER_ACTIVE, + STRING_CONTROLBARGADGETS_BROWSER_NORMALIMAGE, + STRING_CONTROLBARGADGETS_BROWSER_SELECTEDIMAGE, + STRING_CONTROLBARGADGETS_BROWSER_DISABLEDIMAGE, + POP_CONTROLBARGADGETS_BROWSER_ACTION, + NLISTVIEW_CONTROLBARGADGETS_BROWSER_ACTION, + STRING_CONTROLBARGADGETS_BROWSER_ACTION, + TEXTEDITOR_CONTROLBARGADGETS_BROWSER_HELPTEXT, + DTIMG_CONTROLBARGADGETS_BROWSER_NORMALIMAGE, + DTIMG_CONTROLBARGADGETS_BROWSER_SELECTEDIMAGE, + DTIMG_CONTROLBARGADGETS_BROWSER_DISABLEDIMAGE, + + THUMBNAILS_LEFTBORDER, + THUMBNAILS_TOPBORDER, + THUMBNAILS_RIGHTBORDER, + THUMBNAILS_BOTTOMBORDER, + + GROUP_THUMBNAILS_ICON_SAMPLE, + IMAGE_ICON_SAMPLE_128, + IMAGE_ICON_SAMPLE_96, + IMAGE_ICON_SAMPLE_64, + IMAGE_ICON_SAMPLE_48, + IMAGE_ICON_SAMPLE_32, + IMAGE_ICON_SAMPLE_24, + IMAGE_ICON_SAMPLE_16, + + CHECK_TRIG_DISK, + CHECK_TRIG_DRAWER, + CHECK_TRIG_TOOL, + CHECK_TRIG_PROJECT, + CHECK_TRIG_TRASHCAN, + CHECK_TRIG_KICK, + CHECK_TRIG_APPICON, + CHECK_TRIG_APPWIN, + CHECK_TRIG_ICONIFIEDWIN, + CHECK_TRIG_SCALOSWIN, + CHECK_TRIG_DUMMY, + + CYCLE_DESKTOP_LAYOUT_WBDISK, + CYCLE_DESKTOP_LAYOUT_WBDRAWER, + CYCLE_DESKTOP_LAYOUT_WBTOOL, + CYCLE_DESKTOP_LAYOUT_WBPROJECT, + CYCLE_DESKTOP_LAYOUT_WBGARBAGE, + CYCLE_DESKTOP_LAYOUT_WBDEVICE, + CYCLE_DESKTOP_LAYOUT_WBKICK, + CYCLE_DESKTOP_LAYOUT_WBAPPICON, + + CYCLE_ICONS_LAYOUT_WBDRAWER, + CYCLE_ICONS_LAYOUT_WBTOOL, + CYCLE_ICONS_LAYOUT_WBPROJECT, + + CYCLE_WINDOWTYPE, + CHECK_POPTITLEONLY, + CHECK_MMBMOVE, + WINLEFT, + WINTOP, + WINWIDTH, + WINHEIGHT, + SLIDER_CLEANLEFT, + SLIDER_CLEANTOP, + SLIDER_CLEANXSKIP, + SLIDER_CLEANYSKIP, + NLIST_USE_FILEDISPLAY, + NLISTVIEW_USE_FILEDISPLAY, + HIDEHIDDENFILES, + HIDEPROTECTHIDDENFILES, + CYCLE_SHOWALLDEFAULT, + CYCLE_VIEWBYICONSDEFAULT, + + SLIDER_TRANSPARENCY_ACTIVEWINDOW, + SLIDER_TRANSPARENCY_INACTIVEWINDOW, + + CHECK_STRIPED_WINDOW, + CHECK_SELECTTEXTICONNAME, + + GROUP_TTSCREENFONT, + GROUP_TTGLOBALS, + CYCLE_TTANTIALIAS, + SLIDER_TTGAMMA, + CHECK_TTSCREENFONT_ENABLE, + POPSTRING_TTSCREENFONT, + MCC_TTSCREENFONT_SAMPLE, + GROUP_TTICONFONT, + CHECK_TTICONFONT_ENABLE, + POPSTRING_TTICONFONT, + MCC_TTICONFONT_SAMPLE, + GROUP_TTTEXTWINDOWFONT, + CHECK_TTTEXTWINDOWFONT_ENABLE, + POPSTRING_TTTEXTWINDOWFONT, + MCC_TTTEXTWINDOWFONT_SAMPLE, + + CYCLE_CREATELINKS, + CHECK_USEEXALL, + CHECK_HARDEMULATION, + CHECK_MENUCURRENTDIR, + POPUP_SELECTED_HOTKEY, + POPUP_SELECTED_HOTKEY_SCAN, + GROUP_DEFAULTSTACKSIZE, + GROUP2_DEFAULTSTACKSIZE, + SLIDER_DEFAULTSTACKSIZE, + + POPPH_ROOTWINDOWTITLE, + POPPH_DIRWINDOWTITLE, + POPPH_SCREENTITLE, + STRING_TOOLTIPFONT, + SLIDER_ICONTOOLTIPS_TRANSPARENCY, + + SLIDER_TEXTWINDOWS_SELECTBORDERTRANSPARENCY, + SLIDER_TEXTWINDOWS_SELECTFILLTRANSPARENCY, + COLORADJUST_TEXTWINDOWS_SELECTIONMARK, + MCC_TEXTWINDOWS_SELECTMARKER_SAMPLE, + GROUP_TEXTWINDOWS_SELECTIONMARK, + + STRING_WBSTARTPATH, + STRING_SCALOSHOME, + STRING_THEMES, + STRING_IMAGECACHE, + STRING_THUMBNAILDB, + STRING_DISKCOPY, + STRING_FORMAT, + STRING_DEFICONPATH, + STRING_SQLITE3TEMPPATH, + + CHECK_SHOWDRAG, + CHECK_STATUSBAR, + CHECK_CHECKOVERLAP, + CYCLE_DROPMARK, + CHECK_CLEANUP_ONRESIZE, + + FRAME_ICONNORMAL, + FRAME_ICONSELECTED, + FRAME_ICON_THUMBNAIL_NORMAL, + FRAME_ICON_THUMBNAIL_SELECTED, + + NLISTVIEW_HIDDENDEVICES, + NLIST_HIDDENDEVICES, + + GROUP_COPYBUFFERSIZE, + SLIDER_COPYBUFFERSIZE, + + SLIDER_UNDOSTEPS, + + MENU_OPEN, + MENU_SAVE_AS, + MENU_ABOUT, + MENU_ABOUT_MORPHOS, + MENU_ABOUT_MUI, + MENU_QUIT, + MENU_RESET_TO_DEFAULTS, + MENU_LAST_SAVED, + MENU_RESTORE, + MENU_CREATE_ICONS, + + // ------------------------------ + + NLISTVIEW_MODULES, + NLIST_MODULES, + + WIN_ABOUT_MORPHOS, + + TOTAL +}; + +enum ImgIndex +{ + // prefs page images + IMAGE_ABOUT, + IMAGE_PATHS, + IMAGE_STARTUP, + IMAGE_DESKTOP, + IMAGE_ICONS, + IMAGE_DRAGNDROP, + IMAGE_WINDOWS, + IMAGE_TEXTWINDOWS, + IMAGE_TTFONTS, + IMAGE_MISC, + IMAGE_PLUGINS, + IMAGE_MODULES, + + IMAGE_FILEDISPLAY, + // ------------------------------ + + // modules images + IMAGE_DELETE, + IMAGE_EMPTY_TRASHCAN, + IMAGE_EXECUTE_COMMAND, + IMAGE_FORMAT_DISK, + IMAGE_INFORMATION, + IMAGE_ICONPROPERTIES, + IMAGE_NEWDRAWER, + IMAGE_REBOOT, + IMAGE_RENAME, + IMAGE_SYSTEMINFO, + IMAGE_WINDOWPROPERTIES, + + // misc. images + IMAGE_ICON128, + IMAGE_ICON96, + IMAGE_ICON64, + IMAGE_ICON48, + IMAGE_ICON32, + IMAGE_ICON24, + IMAGE_ICON16, +}; + +//-------------------------------------------------------------------- + +#define MUIV_Application_ReturnID_EDIT 1000 +#define MUIV_Application_ReturnID_USE 1001 +#define MUIV_Application_ReturnID_SAVE 1002 + +//-------------------------------------------------------------------- + +// Global Variables + +struct SCAModule +{ + Object *Obj[TOTAL]; // pointers to various objects in GUI +}; + +//-------------------------------------------------------------------- + +struct PluginDef +{ + struct MinNode plug_Node; + UWORD plug_libVersion; /* major */ + UWORD plug_libRevision; /* minor */ + WORD plug_priority; + UWORD plug_instsize; + UWORD plug_NeededVersion; + BOOL plug_SuccessfullyLoaded; + char plug_classname[MAX_PLUGIN_CLASSNAME]; + char plug_superclassname[MAX_PLUGIN_SUPERCLASSNAME]; + char plug_RealName[MAX_PLUGIN_REALNAME]; + char plug_Description[MAX_PLUGIN_DESCRIPTION]; + char plug_Creator[MAX_PLUGIN_CREATORNAME]; + char plug_filename[MAX_FILENAME]; //DiskPlugin filename + + char plug_VersionString[30]; +}; + +//-------------------------------------------------------------------- + +struct ControlBarGadgetEntry + { + struct Node cgy_Node; + + enum SCPGadgetTypes cgy_GadgetType; + ULONG cgy_ImageObjectIndex; // internal, only for list display + Object *cgy_Image; // Image object for normal image or NULL + char cgy_ImageString[20]; // internal, only for list display + char cgy_Action[40]; // Name of Menu Command + STRPTR cgy_NormalImage; // file name of normal state image + STRPTR cgy_SelectedImage; // file name of selected state image + STRPTR cgy_DisabledImage; // file name of disabled state image + STRPTR cgy_HelpText; // Bubble help text + }; + +//-------------------------------------------------------------------- + +struct NewPageListEntry +{ + CONST_STRPTR nple_TitleString; + Object *nple_TitleImage; + ULONG nple_ImageIndex; + Object *(*nple_CreateTitleImage)(void *UserData); + void *nple_UserData; +}; + +//-------------------------------------------------------------------- + +struct CommandTableEntry + { + CONST_STRPTR cte_Command; + ULONG cte_NameMsgId; + }; + +//-------------------------------------------------------------------- + +struct FileDisplayListEntry +{ + ULONG fdle_Index; // Index into cFileDisplayColumns[] +}; + +//-------------------------------------------------------------------- + +struct ModuleListEntry +{ + Object *mdle_Image; + Object *mdle_Popup; + + ULONG mdle_EntryIndex; // continuous index starting from 0, returned by MUIA_NList_ButtonClick + + ULONG mdle_ImageObjectIndex; // MUIM_NList_UseImage index for module logo + ULONG mdle_PopupObjectIndex; // MUIM_NList_UseImage index for popup button + + char mdle_Modulename[108]; // module name + char mdle_Filename[512]; // File name for module prefs executable + + char mdle_ImageString[20]; + char mdle_PopupObjectString[20]; +}; + +//-------------------------------------------------------------------- + +struct NewHiddenDevice + { + ULONG nhd_Hidden; + CONST_STRPTR nhd_DeviceName; + CONST_STRPTR nhd_VolumeName; + }; + +struct HiddenDeviceListEntry + { + Object *hde_CheckboxImage; + + ULONG hde_EntryIndex; // continuous index starting from 0, returned by MUIA_NList_ButtonClick + + ULONG hde_CheckboxObjectIndex; // MUIM_NList_UseImage index for checkbox + + ULONG hde_Hidden; + + char hde_CheckboxString[20]; + char hde_DeviceName[128]; // device name + char hde_VolumeName[128]; // volume name + }; + +//-------------------------------------------------------------------- + +enum ScalosDrawerSortType + { + DRAWER_SORT_First, + DRAWER_SORT_Last, + DRAWER_SORT_Inbetween, + }; + +//-------------------------------------------------------------------- + +// Values for Screen title bar cycle +enum ScreenTitleModes +{ + SCREENTITLE_Visible = 0, // always visible + SCREENTITLE_Popup, // popup under mouse + SCREENTITLE_Hidden, // always hidden +}; + +//-------------------------------------------------------------------- + +// Values for Icon min size limits +enum IconSizesMin +{ + ICONSIZEMIN_Unlimited = 0, + ICONSIZEMIN_16, + ICONSIZEMIN_24, + ICONSIZEMIN_32, + ICONSIZEMIN_48, + ICONSIZEMIN_64, + ICONSIZEMIN_96, + ICONSIZEMIN_128, +}; + +//-------------------------------------------------------------------- + +// Values for Icon max size limits +enum IconSizesMax +{ + ICONSIZEMAX_16 = 0, + ICONSIZEMAX_24, + ICONSIZEMAX_32, + ICONSIZEMAX_48, + ICONSIZEMAX_64, + ICONSIZEMAX_96, + ICONSIZEMAX_128, + ICONSIZEMAX_Unlimited, +}; + +//-------------------------------------------------------------------- + +// Values for Thumbnail sizes +enum ThumbnailSizes +{ + THUMBNAILSIZE_16 = 0, + THUMBNAILSIZE_24, + THUMBNAILSIZE_32, + THUMBNAILSIZE_48, + THUMBNAILSIZE_64, + THUMBNAILSIZE_96, + THUMBNAILSIZE_128, +}; + +//-------------------------------------------------------------------- + +VOID MsgBox(char *message, char *, struct SCAModule *); +LONG SaveIcon(CONST_STRPTR IconName); +BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev); +void SetThumbNailSize(struct SCAModule *app, UWORD ThumbnailSize); +UWORD GetThumbNailSize(struct SCAModule *app); +void SetIconSizeConstraints(struct SCAModule *app, const struct Rectangle *SizeConstraints); +void GetIconSizeConstraints(struct SCAModule *app, struct Rectangle *SizeConstraints); +void AdjustIconSizeSample(struct SCAModule *app, const struct Rectangle *SizeConstraints); +Object *CreatePrefsPage(struct SCAModule *app, Object *Page, struct NewPageListEntry *nple); +BOOL ExistsObject(CONST_STRPTR Name); + +//-------------------------------------------------------------------- + +#ifndef __SASC +// Replacement for SAS/C library functions +size_t stccpy(char *dest, const char *src, size_t MaxLen); +#endif /* __SASC */ + +#if defined(__SASC) +int snprintf(char *, size_t, const char *, /*args*/ ...); +int vsnprintf(char *, size_t, const char *, va_list ap); +#endif /* __SASC */ + +//-------------------------------------------------------------------- + +// from debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +//-------------------------------------------------------------------- + +#define d1(x) ; +#define d2(x) x; + +//-------------------------------------------------------------------- + +#define max(x, y) ((x) > (y) ? (x) : (y)) +#define min(x, y) ((x) > (y) ? (y) : (x)) + +#define Sizeof(array) (sizeof(array) / sizeof(array[0])) + +//-------------------------------------------------------------------- + +extern ULONG fCreateIcons; +extern ULONG ModuleImageIndex; +extern STRPTR ProgramName; +extern struct Hook AslIntuiMsgHook; +extern struct Hook CalculateMaxRadiusHook; + +#endif /* SCALOSPREFS_H */ diff --git a/scalos/Prefs/MainPrefs/Scalos_Prefs.cd b/scalos/Prefs/MainPrefs/Scalos_Prefs.cd new file mode 100644 index 000000000..feef8d6a2 --- /dev/null +++ b/scalos/Prefs/MainPrefs/Scalos_Prefs.cd @@ -0,0 +1,3157 @@ +; Scalos_Prefs.cd +; version $VER: Scalos_Prefs.catalog 40.28 (28 Mar 2010 19:20:49) +; $Date$ +; $Revision$ +; codeset 0s +; language english +; +;#arrayopts static const __far +; +;----------------------------------------------------------- +; +MSGID_MENU_PROJECT_OPEN (1000//) +Open... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT (/1/1) +O +; +; +MSGID_MENU_PROJECT_OPEN_ASLTITLE (//) +Open Scalos Prefs... +; +; +MSGID_MENU_PROJECT_SAVEAS (//) +Save As... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT (/1/1) +A +; +; +MSGID_MENU_PROJECT_SAVEAS_ASLTITLE (//) +Save Scalos Prefs As... +; +; +MSGID_MENU_PROJECT_ABOUT (//) +About... +; +; +MSGID_MENU_PROJECT_QUIT (//) +Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT (/1/1) +Q +; +; +MSGID_MENU_PROJECT (//) +Project +; +; +MSGID_MENU_EDIT_LASTSAVED (//) +Last Saved +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT (/1/1) +L +; +; +MSGID_MENU_EDIT (//) +Edit +; +; +MSGID_MENU_SETTINGS_CREATEICONS (//) +Create Icons? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT (/1/1) +I +; +; +MSGID_MENU_SETTINGS (//) +Settings +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS (//) +Reset To Defaults +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT (/1/1) +D +; +; +MSGID_MENU_EDIT_RESTORE (//) +Restore +; +; +MSGID_MENU_EDIT_RESTORE_SHORT (/1/1) +R +; +; +MSGID_MENU_PROJECT_ABOUTMUI (//) +About MUI... +; +; +MSGID_MENU_PROJECT_ABOUTMORPHOS (//) +About MorphOS... +; +;----------------------------------------------------------- +; +MSGID_FILEDISP_COLUMN_NAME (1100//) +Name +; +; +MSGID_FILEDISP_COLUMN_SIZE (//) +Size +; +; +MSGID_FILEDISP_COLUMN_PROT (//) +Protection bits +; +; +MSGID_FILEDISP_COLUMN_DATE (//) +Date +; +; +MSGID_FILEDISP_COLUMN_TIME (//) +Time +; +; +MSGID_FILEDISP_COLUMN_COMMENT (//) +Comment +; +; +MSGID_FILEDISP_COLUMN_VERSION (//) +Version +; +; +MSGID_FILEDISP_COLUMN_FILETYPE (//) +Filetype +; +; +MSGID_FILEDISP_COLUMN_OWNER (//) +Owner +; +; +MSGID_FILEDISP_COLUMN_GROUP (//) +Group +; +; +MSGID_FILEDISP_COLUMN_ICON (//) +Icon +; +;----------------------------------------------------------- +; +MSGID_PRECISION_EXACT (1200//) +Exact +; +; +MSGID_PRECISION_IMAGE (//) +Image +; +; +MSGID_PRECISION_ICON (//) +Icon +; +; +MSGID_PRECISION_GUI (//) +GUI +; +;----------------------------------------------------------- +; +MSGID_THUMBNAILS_LIFETIME_FOREVER (1250//) +never +; +;----------------------------------------------------------- +; +MSGID_PREFGROUPS_SHORTHELP (1300//) +Select one of the preferences categories +; +; +MSGID_PREFGROUPS_ABOUT (//) +About Scalos +; +; +MSGID_PREFGROUPS_PATHS (//) +Paths +; +; +MSGID_PREFGROUPS_STARTUP (//) +Startup +; +; +MSGID_PREFGROUPS_DESKTOP (//) +Desktop +; +; +MSGID_PREFGROUPS_ICONS (//) +Icons +; +; +MSGID_PREFGROUPS_WINDOWS (//) +Windows +; +; +MSGID_PREFGROUPS_MISC (+1//) +Miscellaneous +; +; +MSGID_PREFGROUPS_PLUGINS (//) +Plugins +; +; +MSGID_PREFGROUPS_MODULES (//) +Modules +; +; +MSGID_PREFGROUPS_DRAGNDROP (//) +Drag and Drop +; +; +MSGID_PREFGROUPS_TRUETYPEFONTS (//) +TrueType Fonts +; +; +MSGID_PREFGROUPS_TEXTWINDOWS (//) +Text Windows +; +;----------------------------------------------------------- +; +MSGID_DESKTOPPAGES_SCREEN (1350//) +Screen +; +; +MSGID_DESKTOPPAGES_ICONS (//) +Icons +; +; +MSGID_ICONPAGES_MISC (//) +Miscellaneous +; +; +MSGID_DESKTOPPAGES_LAYOUT (//) +Layout +; +;----------------------------------------------------------- +; +MSGID_ICONPAGES_BORDERS (1400//) +Borders +; +; +MSGID_ICONPAGES_LABELS (//) +Labels +; +; +MSGID_ICONPAGES_ATRIBUTES (//) +Attributes +; +; +MSGID_ICONPAGES_TOOLTIPS (//) +Tooltips +; +; +MSGID_ICONPAGES_THUMBNAILS (//) +Thumbnails +; +; +MSGID_ICONPAGES_SIZES (//) +Sizes +; +;----------------------------------------------------------- +; +MSGID_TITLEPLACEHOLDER_KICKSTART_RELEASE (+1//) +%os|Kickstart release (e.g. 3.1) +; +; +MSGID_TITLEPLACEHOLDER_KICKSTART_VERSION (//) +%ov|Kickstart version (e.g. 40.68) +; +; +MSGID_TITLEPLACEHOLDER_SCALOS_RELEASE (//) +%wb|Scalos release (e.g. 1.2d) +; +; +MSGID_TITLEPLACEHOLDER_SCALOS_VERSION (//) +%wv|Scalos version (e.g. 39.220) +; +; +MSGID_TITLEPLACEHOLDER_FREE_CHIP_MEM (//) +%fc|Free chip RAM in bytes +; +; +MSGID_TITLEPLACEHOLDER_FREE_FAST_MEM (//) +%ff|Free fast RAM in bytes +; +; +MSGID_TITLEPLACEHOLDER_FREE_MEM (//) +%ft|Total free RAM in bytes +; +; +MSGID_TITLEPLACEHOLDER_WINDOW_PATH (//) +%pa|Windows directory path +; +; +MSGID_TITLEPLACEHOLDER_DISK_FREE (//) +%df|Free disk space +; +; +MSGID_TITLEPLACEHOLDER_DISK_FREE_DIVIDE (//) +%DF|Free disk space (auto divide) +; +; +MSGID_TITLEPLACEHOLDER_DISK_USED (//) +%du|Used disk space +; +; +MSGID_TITLEPLACEHOLDER_DISK_USED_DIVIDE (//) +%DU|Used disk space (auto divide) +; +; +MSGID_TITLEPLACEHOLDER_START_NODISK (//) +%d(|Start: don't show if no disk inserted +; +; +MSGID_TITLEPLACEHOLDER_STOP_NODISK (//) +%d)|Stop: don't show if no disk inserted +; +; +MSGID_TITLEPLACEHOLDER_DISK_PERCENT (//) +%dp|Percent of used disk space +; +; +MSGID_TITLEPLACEHOLDER_GFXCHIPS (//) +%cs|Graphics chip set (e.g. AGA) +; +; +MSGID_TITLEPLACEHOLDER_CPU (//) +%pr|68k processor +; +; +MSGID_TITLEPLACEHOLDER_FPU (//) +%cp|68k co-processor (FPU) +; +; +MSGID_TITLEPLACEHOLDER_TASKS (//) +%nt|Number of tasks +; +; +MSGID_TITLEPLACEHOLDER_LIBRARIES (//) +%nl|Number of libraries +; +; +MSGID_TITLEPLACEHOLDER_PORTS (//) +%np|Number of ports +; +; +MSGID_TITLEPLACEHOLDER_DEVICES (//) +%nd|Number of devices +; +; +MSGID_TITLEPLACEHOLDER_SCREENS (//) +%ns|Number of screens +; +; +;----------------------------------------------------------- +; +MSGID_WINDOWPAGES_GENERAL (1500//) +General +; +; +MSGID_WINDOWPAGES_SIZE (//) +Size +; +MSGID_WINDOWPAGES_LAYOUT (+1//) +Layout +; +; +MSGID_WINDOWPAGES_CONTROLBAR (//) +Control Bar +; +; +MSGID_WINDOWPAGES_CONTROLBAR_BROWSER (//) +Browser Window Control Bar +; +; +MSGID_WINDOWPAGES_CONTROLBAR_NORMAL (//) +Standard Window Control Bar +; +;----------------------------------------------------------- +; +MSGID_TEXTWINDOWPAGES_FONTS (1530//) +Fonts +; +; +MSGID_TEXTWINDOWPAGES_COLUMNS (//) +Columns +; +; +MSGID_TEXTWINDOWPAGES_SELECTIONMARKS (//) +Selection marks +; +; +MSGID_TEXTWINDOWPAGES_MISC (//) +Miscellaneous +; +;----------------------------------------------------------- +; +MSGID_CREATELINKS_HARDLINKS (1550//) +Hard links +; +; +MSGID_CREATELINKS_SOFTLINKS (//) +Soft links +; +;----------------------------------------------------------- +; +MSGID_WINDOWREFRESH_SIMPLE (1600//) +Simple Refresh +; +; +MSGID_WINDOWREFRESH_SMART (//) +Smart Refresh +; +;----------------------------------------------------------- +; +MSGID_WINDOW_SHOWALL_DEFAULT_ICONS (1640//) +Show - Only Icons +; +; +MSGID_WINDOW_SHOWALL_DEFAULT_ALL (//) +Show - All Files +; +;----------------------------------------------------------- +; +MSGID_WINDOW_VIEWBY_DEFAULT_ICON (1670//) +View By - Icon +; +; +MSGID_WINDOW_VIEWBY_DEFAULT_NAME (//) +View By - Name +; +; +MSGID_WINDOW_VIEWBY_DEFAULT_SIZE (//) +View By - Size +; +; +MSGID_WINDOW_VIEWBY_DEFAULT_DATE (//) +View By - Date +; +; +MSGID_WINDOW_VIEWBY_DEFAULT_TIME (//) +View By - Time +; +; +MSGID_WINDOW_VIEWBY_DEFAULT_COMMENT (//) +View By - Comment +; +; +MSGID_WINDOW_VIEWBY_DEFAULT_PROTECTION (//) +View By - Comment +; +; +MGSID_WINDOW_VIEWBY_DEFAULT_OWNER (//) +View By - Owner +; +; +MSGID_WINDOW_VIEWBY_DEFAULT_GROUP (//) +View By - Group +; +;----------------------------------------------------------- +; +MSGID_FILEDISPLAYPAGES_TEXT (1700//) +Text +; +;----------------------------------------------------------- +; +MSGID_ICONLAYOUT_COLUMNS (1750//) +Columns (top-down, then left-to-right) +; +; +MSGID_ICONLAYOUT_ROWS (//) +Rows (left-to-right, then top-down) +; +;----------------------------------------------------------- +; +MSGID_ICONLABELSTYLES_NORMAL (1800//) +Normal +; +; +MSGID_ICONLABELSTYLES_OUTLINE (//) +Outline +; +; +MSGID_ICONLABELSTYLES_SHADOW (//) +Shadow +; +;----------------------------------------------------------- +; +MSGID_ICONSIZES_16x16 (1850//) +16 x 16 +; +; +MSGID_ICONSIZES_24x24 (//) +24 x 24 +; +; +MSGID_ICONSIZES_32x32 (//) +32 x 32 +; +; +MSGID_ICONSIZES_48x48 (//) +48 x 48 +; +; +MSGID_ICONSIZES_64x64 (//) +64 x 64 +; +; +MSGID_ICONSIZES_96x96 (//) +96 x 96 +; +; +MSGID_ICONSIZES_128x128 (//) +128 x 128 +; +; +MSGID_ICONSIZES_UNLIMITED (//) +unlimited +; +;----------------------------------------------------------- +; +MSGID_ICONDRAGSTYLES_IMAGEONLY (1900//) +Image Only +; +; +MSGID_ICONDRAGSTYLES_IMAGEANDTEXT (//) +Image & Text +; +;----------------------------------------------------------- +; +MSGID_THUMBNAILSIZES_16x16 (1950//) +16 x 16 +; +; +MSGID_THUMBNAILSIZES_24x24 (//) +24 x 24 +; +; +MSGID_THUMBNAILSIZES_32x32 (//) +32 x 32 +; +; +MSGID_THUMBNAILSIZES_48x48 (//) +48 x 48 +; +; +MSGID_THUMBNAILSIZES_64x64 (//) +64 x 64 +; +; +MSGID_THUMBNAILSIZES_96x96 (//) +96 x 96 +; +; +MSGID_THUMBNAILSIZES_128x128 (//) +128 x 128 +; +;----------------------------------------------------------- +; +MSGID_ICONDRAGTRANSPARENCY_GHOSTED (2000//) +Ghosted +; +; +MSGID_ICONDRAGTRANSPARENCY_TRANSPARENT (//) +Ghosted/Real Transparent +; +;----------------------------------------------------------- +; +MSGID_SHOWTHUMBNAILS_NEVER (2050//) +Never +; +; +MSGID_SHOWTHUMBNAILS_AS_DEFAULT (//) +As default +; +; +MSGID_SHOWTHUMBNAILS_ALWAYS (//) +Always +; +;----------------------------------------------------------- +; +MSGID_ICONDRAGTROUTINES_SYSTEM (2100//) +System +; +; +MSGID_ICONDRAGTROUTINES_CUSTOM (//) +Custom +; +;----------------------------------------------------------- +; +MSGID_ICONDROPMARK_NEVER (2200//) +Never show +; +; +MSGID_ICONDROPMARK_ALWAYS (//) +Always +; +; +MSGID_ICONDROPMARK_DRAWERSONLY (//) +Only in drawer windows +; +;----------------------------------------------------------- +; +MSGID_ICONDRAGLOOK_TRANSP_SOLID (2300//) +\033bTransparent\033n when dragging, \033bsolid\033n over triggers +; +; +MSGID_ICONDRAGLOOK_ALWAYS_SOLID (//) +Always \033bsolid\033n icons when dragging +; +; +MSGID_ICONDRAGLOOK_ALWAYS_TRANSP (//) +Always \033btransparent\033n icons when dragging +; +; +MSGID_ICONDRAGLOOK_SOLID_TRANSP (//) +\033bSolid\033n when dragging, \033btransparent\033n over triggers +; +;----------------------------------------------------------- +; +MSGID_COPYRIGHTSTRING (5001//) +®2003%s The Scalos Team +; +; +MSGID_SPLASHWINDOW_LOADINGPREFS (//) +\33c Loading Scalos Prefs... +; +; +MSGID_SPLASHWINDOW_APPLYINGPREFS (//) +\33c Applying Scalos Prefs... +; +; +MSGID_SPLASHWINDOW_SAVINGPREFS (//) +\33c Saving Scalos Prefs... +; +; +MSGID_VERSIONSTRING (//) +Scalos Version %s (%d.%d) (Build %s) +; +;----------------------------------------------------------- +; +MSGID_ABOUTPAGE_COPYRIGHT (5100//) +\033c\033bCopyright ©2003%s The Scalos Team +; +; +MSGID_ABOUTPAGE_CONTACT1 (//) +contact us by email < +; +; +MSGID_ABOUTPAGE_CONTACT2 (//) +> // web < +; +; +MSGID_ABOUTPAGE_CONTACT3 (//) +> +; +; +MSGID_ABOUTPAGE_PREFSVERSION (//) +Scalos Main Preferences V%ld.%ld +; +;----------------------------------------------------------- +; +MSGID_PATHSPAGE_DEFAULTPATHS (5200//) +Default Paths +; +; +MSGID_PATHSPAGE_SCALOS_HOME (//) +Scalos Home: +; +; +MSGID_PATHSPAGE_SCALOS_HOME_ASLTITLE (//) +Please select a drawer... +; +; +MSGID_PATHSPAGE_SCALOS_HOME_SHORTHELP (//) +An assign called SCALOS: will point to this directory +; +; +MSGID_PATHSPAGE_THEMES (//) +Themes: +; +; +MSGID_PATHSPAGE_THEMES_SHORTHELP (//) +This is the drawer where all the\n\ +theme-specific files are located. +; +; +MSGID_PATHSPAGE_THEMES_ASLTITLE (//) +Please select a drawer... +; +; +MSGID_PATHSPAGE_DEFAULTICONS (//) +Default Icons: +; +; +MSGID_PATHSPAGE_DEFAULTICONS_SHORTHELP (//) +This is the drawer where Scalos\n\ +looks for default icons. +; +; +MSGID_PATHSPAGE_DEFAULTICONS_ASLTITLE (//) +Please select a drawer... +; +; +MSGID_PATHSPAGE_WBSTARTUP (//) +WBStartup: +; +; +MSGID_PATHSPAGE_WBSTARTUP_SHORTHELP (//) +This drawer is used as WBStartup, i.e. any program\n\ +located inside is executed upon Scalos startup. +; +; +MSGID_PATHSPAGE_WBSTARTUP_ASLTITLE (//) +Please select a drawer... +; +; +MSGID_PATHSPAGE_DISKCOPY (//) +DiskCopy: +; +; +MSGID_PATHSPAGE_DISKCOPY_SHORTHELP (//) +This is the complete file name for\n\ +the \"Diskcopy\" system program. +; +; +MSGID_PATHSPAGE_DISKCOPY_ASLTITLE (//) +Please select a drawer... +; +; +MSGID_PATHSPAGE_FORMAT (//) +Format: +; +; +MSGID_PATHSPAGE_FORMAT_SHORTHELP (//) +This is the complete file name for\n\ +the \"Format\" system program. +; +; +MSGID_PATHSPAGE_FORMAT_ASLTITLE (//) +Please select a drawer... +; +; +MSGID_PATHSPAGE_THUMBNAILDB (//) +Thumbnail cache file: +; +; +MSGID_PATHSPAGE_THUMBNAILDB_ASLTITLE (//) +Please select thumbnail cache location... +; +; +MSGID_PATHSPAGE_THUMBNAILDB_SHORTHELP (//) +Scalos uses a database file to cache thumbnail icon images.\n\ +This file easily grows to several megabytes.\n\ +Select here a place where this file should be kept. +; +; +MSGID_PATHSPAGE_IMAGECACHE (//) +Image Cache: +; +; +MSGID_PATHSPAGE_IMAGECACHE_SHORTHELP (//) +This drawer is used to cache the datatypes images used by Scalos.\n\ +Since datatypes prevents images from being updated,\n\ +Scalos creates cached copies of the images used. +; +; +MSGID_PATHSPAGE_IMAGECACHE_ASLTITLE (//) +Please select a drawer... +; +; +MSGID_PATHSPAGE_SQLITE3TEMPPATH (//) +Thumbnail Database Temporary Files: +; +; +MSGID_PATHSPAGE_SQLITE3TEMPPATH_SHORTHELP (//) +This drawer is used to store any temporary\n\ +files for internal use by the thumbnail database. +; +; +MSGID_PATHSPAGE_SQLITE3TEMPPATH_ASLTITLE (//) +Please select thumbnail cache temporary files location... +; +;----------------------------------------------------------- +; +MSGID_STARTUPPAGE_SPLASHWINDOW (5300//) +Splash Window +; +; +MSGID_STARTUPPAGE_SHOWSPLASHWINDOW (//) +Show splash window: +; +; +MSGID_STARTUPPAGE_SHOWSPLASHWINDOW_SHORTHELP (//) +Enable this checkbox to display the\n\ +splash window upon every Scalos startup. +; +; +MSGID_STARTUPPAGE_SPLASHCLOSEDELAY (//) +Splash close delay: +; +; +MSGID_STARTUPPAGE_SPLASHCLOSEDELAY_SHORTHELP (//) +Specify here how long the Scalos splash window\n\ +will stay open after the last startup message\n\ +has been displayed. +; +; +MSGID_STARTUPPAGE_WBSTARTUP (//) +WBStartup +; +; +MSGID_STARTUPPAGE_DOWAITDELAY (//) +DoWait delay: +; +; +MSGID_STARTUPPAGE_DOWAITDELAY_SHORTHELP (//) +If a tool in the WBStartup drawer doesn't\n\ +finish within the specified delay a requester will be\n\ +presented to choose whether to stop waiting. +; +; +MSGID_STARTUPPAGE_DOWAITDELAY_SECONDS (//) +seconds +; +;----------------------------------------------------------- +; +MSGID_DESKTOPPAGE_SCREENTITLEBAR (5400//) +Screen Title +; +; +MSGID_DESKTOPPAGE_SCREEN (//) +Title +; +; +MSGID_DESKTOPPAGE_SCREEN_DESCRIPTION (//) +|\033b\0338Description +; +; +MSGID_DESKTOPPAGE_TITLEBAR_REFRESH (//) +Titlebar refresh rate: +; +; +MSGID_DESKTOPPAGE_TITLEBAR_REFRESH_SHORTHELP (//) +This is the time interval between\n\ +consecutive screen title bar refreshes. +; +; +MSGID_DESKTOPPAGE_TITLEBAR_REFRESH_SECONDS (//) +seconds +; +; +MSGID_DESKTOPPAGE_TITLEBAR_REFRESH_MEMCHANGE (//) +Refresh only on memory change: +; +; +MSGID_DESKTOPPAGE_TITLEBAR_REFRESH_MEMCHANGE_SHORTHELP (//) +When this item is checked, the screen title bar\n\ +is only refreshed when the amount of available\n\ +system memory has changed since last check.\n\ +The memory is checked every \"Titlebar refresh rate\" seconds. +; +; +MSGID_DESKTOPPAGE_DESKTOP_REFRESH (//) +Desktop Refresh +; +; +MSGID_DESKTOPPAGE_DISK_ICON_RATE (//) +Disk icon rate: +; +; +MSGID_DESKTOPPAGE_DISK_ICON_RATE_SHORTHELP (//) +This is the time interval Scalos\n\ +checks for changed disks and volumes. +; +; +MSGID_DESKTOPPAGE_DISK_ICON_RATE_SECONDS (//) +seconds +; +; +MSGID_DESKTOPPAGE_SCREENTITLE (//) +Screen Title +; +; +MSGID_DESKTOPPAGE_SCREENTITLE_MODE (//) +Visibility: +; +; +MSGID_DESKTOPPAGE_SCREENTITLE_MODE_SHORTHELP (//) +Specifiy here whether you like the screen title\n\ +- to be visible all the time\n\ +- to pop up when the mouse pointer is positioned at the top of the screen\n\ +- to be hidden all the time +; +; +MSGID_DESKTOPPAGE_MISCELLANEOUS (//) +Miscellaneous +; +; +MSGID_DESKTOPPAGE_ALLOW_CLOSEWB (//) +Allow CloseWorkbench(): +; +; +MSGID_DESKTOPPAGE_ALLOW_CLOSEWB_SHORTHELP (//) +Disable this checkbox to make the CloseWB() function\n\ +a no-op. This allows to work with some ancient\n\ +programs and leave Scalos open all the time. +; +; +MSGID_DESKTOPPAGE_DROPSTART (//) +Drop-start: +; +; +MSGID_DESKTOPPAGE_DROPSTART_SHORTHELP (//) +Dropping a project icon on to another programs\n\ +icon will automatically run the program and\n\ +pass the project file as a parameter +; +; +MSGID_DESKTOPPAGE_CONSOLENAME (//) +Console name +; +; +MSGID_DESKTOPPAGE_CONSOLENAME_SHORTHELP (//) +Gives complete file specifier for CLI and ARexx console. +; +; +MSGID_DESKTOPPAGE_AUTOLEAVEOUT (//) +Automatic leave-out +; +; +MSGID_DESKTOPPAGE_AUTOLEAVEOUT_SHORTHELP (//) +If this switch is turned on, dragging icons\n\ +onto the desktop remembers them permanently\n\ +as left-out, just like selecting the\n\ +\"leave out\" menu command. +; +; +MSGID_DESKTOPPAGE_WINTITLEBAR_REFRESH (//) +Titlebar refresh rate: +; +; +MSGID_DESKTOPPAGE_WINTITLEBAR_REFRESH_SHORTHELP (//) +This is the time interval between\n\ +consecutive window title bar refreshes. +; +; +MSGID_DESKTOPPAGE_WINTITLEBAR_REFRESH_SECONDS (//) +seconds +; +; +MSGID_DESKTOPPAGE_WINTITLEBAR_REFRESH_MEMCHANGE (//) +Refresh only on memory change: +; +; +MSGID_DESKTOPPAGE_WINTITLEBAR_REFRESH_MEMCHANGE_SHORTHELP (//) +When this item is checked, the window title bar\n\ +is only refreshed when the amount of available\n\ +system memory has changed since last check.\n\ +The memory is checked every \"Titlebar refresh rate\" seconds. +; +; +MSGID_DESKTOPPAGE_LASSO (//) +Lasso +; +; +MSGID_DESKTOPPAGE_SINGLEWINDOW_LASSO (//) +Single-Window Lasso Mode +; +; +MSGID_DESKTOPPAGE_SINGLEWINDOW_LASSO_SHORTHELP (//) +Press this qualifier key to limit lasso operation to a single window.\n\ +In this mode, the window contents scrolls to unveal hidden\n\ +icons if the mouse leaves the inner window area. +; +;----------------------------------------------------------- +; +MSGID_ICONSPAGE_ICONFRAME (5500//) +Icon Frame +; +; +MSGID_ICONSPAGE_ICONFRAME_NORMAL (//) +Normal +; +; +MSGID_ICONSPAGE_ICONFRAME_NORMAL_SHORTHELP (//) +This type of border is drawn around unselected icons.\n\ +\033bGlowIcons\033n which have been marked as\n\ +\"borderless\" will not show this border.\n\ +Please note that the icon borders below must\n\ +be non-zero for the icon border to show. +; +; +MSGID_ICONSPAGE_ICONFRAME_SELECTED (//) +Selected +; +; +MSGID_ICONSPAGE_ICONFRAME_SELECTED_SHORTHELP (//) +This type of border is drawn around selected icons.\n\ +\033bGlowIcons\033n which have been marked as\n\ +\"borderless\" will not show this border.\n\ +Please note that the icon borders below must\n\ +be non-zero for the icon border to show. +; +; +MSGID_ICONSPAGE_ICONBORDER_LEFT (//) +Left: +; +; +MSGID_ICONSPAGE_ICONBORDER_LEFT_SHORTHELP (//) +This is the space between the left side of an\n\ +icon and the border. No icon borders will be\n\ +drawn when this space is 0. +; +; +MSGID_ICONSPAGE_ICONBORDER_TOP (//) +Top: +; +; +MSGID_ICONSPAGE_ICONBORDER_TOP_SHORTHELP (//) +This is the space between the top of an\n\ +icon and the border. No icon borders will be\n\ +drawn when this space is 0. +; +; +MSGID_ICONSPAGE_ICONBORDER_RIGHT (//) +Right: +; +; +MSGID_ICONSPAGE_ICONBORDER_RIGHT_SHORTHELP (//) +This is the space between the right side of an\n\ +icon and the border. No icon borders will be\n\ +drawn when this space is 0. +; +; +MSGID_ICONSPAGE_ICONBORDER_BOTTOM (//) +Bottom: +; +; +MSGID_ICONSPAGE_ICONBORDER_BOTTOM_SHORTHELP (//) +This is the space between the bottom of an\n\ +icon and the border. No icon borders will be\n\ +drawn when this space is 0. +; +; +MSGID_ICONSPAGE_LABELS (//) +Labels +; +; +MSGID_ICONSPAGE_LABELS_TEXT (//) +Text style: +; +; +MSGID_ICONSPAGE_LABELS_TEXT_SHORTHELP (//) +Provides a choice of label font formatting\n\ +which can be applied to the icons text label +; +; +MSGID_ICONSPAGE_LABELS_TEXTSPACE (//) +Image <-> Text Space: +; +; +MSGID_ICONSPAGE_LABELS_TEXTSPACE_SHORTHELP (//) +Adjusts the space between the\n\ +icon imagery and its text label +; +; +MSGID_ICONSPAGE_LABELS_TEXTSPACE_PIXELS (//) +pixels +; +; +MSGID_ICONSPAGE_LABELS_SPLIT (//) +Split into multiple lines: +; +; +MSGID_ICONSPAGE_LABELS_SPLIT_SHORTHELP (//) +Allows filenames to be split\n\ +over multiple lines +; +; +MSGID_ICONSPAGE_LABELS_UNDERLINE_LINKS (//) +Display soft-link file names \033uunderlined\033n: +; +; +MSGID_ICONSPAGE_LABELS_UNDERLINE_LINKS_SHORTHELP (//) +When this item is checked, icon names of\n\ +soft-links are displayed \033uunderlined\033n. +; +; +MSGID_ICONSPAGE_LABELS_FONT (//) +Font +; +; +MSGID_ICONSPAGE_LABELS_FONT_NOTICE (//) +To change the font used for icon labels you must use \ +the standard \033bFont preferences\033n program installed on your \ +system. Use the pop-up button on the right to launch \ +the fonts preference program. +; +; +MSGID_ICONSPAGE_LABELS_FONT_SHORTHELP (//) +Launch standard \033bFont preferences\033n program +; +; +MSGID_ICONSPAGE_GENERAL (//) +General +; +; +MSGID_ICONSPAGE_MASKED_CLICKAREA (//) +Masked click area: +; +; +MSGID_ICONSPAGE_MASKED_CLICKAREA_SHORTHELP (//) +If this checkbox is checked, you have to click on the\n\ +unmasked, visible area of an icon to activate it. If it\n\ +is unchecked, a click anywhere inside the icon\n\ +rectangle will be sufficient for activation. +; +; +MSGID_ICONSPAGE_MULTISELECTION (//) +Multi-Selection: +; +; +MSGID_ICONSPAGE_MULTISELECTION_SHORTHELP (//) +Provides an alternative multi-select method which\n\ +does not require you to hold down the SHIFT key\n\ +whilst dragging multiple icons. +; +; +MSGID_ICONSPAGE_NEWICONS (//) +New Icons +; +; +MSGID_ICONSPAGE_NEWICONS_REMAP_PRECISION (//) +Remap precision: +; +; +MSGID_ICONSPAGE_NEWICONS_REMAP_PRECISION_SHORTHELP (//) +Specifies the precision to use when\n\ +remapping NewIcon colors to the screen palette. +; +; +MSGID_ICONSPAGE_NEWICONS_TRANSPARENTBG (//) +Transparent background: +; +; +MSGID_ICONSPAGE_NEWICONS_TRANSPARENTBG_SHORTHELP (//) +Makes the background of NewIcons transparent +; +; +MSGID_ICONSPAGE_DEFICONS (//) +Def Icons +; +; +MSGID_ICONSPAGE_DEFICONS_LOADFIRST (//) +Load first: +; +; +MSGID_ICONSPAGE_DEFICONS_LOADFIRST_SHORTHELP (//) +Your def_#? icons will get priority when\n\ +loading over a specific icon for a device. +; +; +MSGID_ICONSPAGE_DEFICONS_SAVEABLE (//) +Icons saveable: +; +; +MSGID_ICONSPAGE_DEFICONS_SAVEABLE_SHORTHELP (//) +When enabled, \033bsnapshot\033n saves changes\n\ +to default icons.\n\ +Uncheck this checkbox to prevent Scalos from\n\ +changing any ofyour default icons. +; +; +MSGID_ICONSPAGE_TOOLTIPS_GENERAL (//) +General +; +; +MSGID_ICONSPAGE_TOOLTIPS_SHOW (//) +Show tooltips for icons: +; +; +MSGID_ICONSPAGE_TOOLTIPS_SHOW_SHORTHELP (//) +When this checkbox is checked, Scalos pops up\n\ +\033btooltips\033n with additional information\n\ +when you keep the mouse pointer positioned over\n\ +an icon for more than the tooltip delay time.\n\ +The tooltip automatically disappears as soon as\n\ +the mouse is moved or any key is pressed. +; +; +MSGID_ICONSPAGE_TOOLTIPS_SETTINGS (//) +Settings +; +; +MSGID_ICONSPAGE_TOOLTIPS_DELAY (//) +Delay before pop-up: +; +; +MSGID_ICONSPAGE_TOOLTIPS_DELAY_SHORTHELP (//) +Here you can select how long you have to\n\ +keep the mouse pointer positioned over an\n\ +icon until the tooltip pops up. +; +; +MSGID_ICONSPAGE_TOOLTIPS_DELAY_SECONDS (//) +seconds +; +; +MSGID_ICONSPAGE_TOOLTIPS_FONT (//) +Font: +; +; +MSGID_ICONSPAGE_TOOLTIPS_FONT_SHORTHELP (//) +??? +; +; +MSGID_ICONSPAGE_TOOLTIPS_FONT_ASLTITLE (//) +Please select a font... +; +; +MSGID_ICONSPAGE_TOOLTIPS_DISPLAYFIELDS (//) +Display Fields +; +; +MSGID_ICONSPAGE_TOOLTIPS_AVAILABLEFIELDS (//) +Available Fields +; +; +MSGID_ICONSPAGE_TOOLTIPS_AVAILABLEFIELDS_SHORTHELP (//) +??? +; +; +MSGID_ICONSPAGE_TOOLTIPS_FIELDSINUSE (//) +Fields In Use +; +; +MSGID_ICONSPAGE_TOOLTIPS_FIELDSINUSE_SHORTHELP (//) +??? +; +; +MSGID_ICONSPAGE_DRAGGING (//) +Dragging +; +; +MSGID_ICONSPAGE_ATTRIBUTES_TRANSPARENCY_DEFICONS (+39//) +Transparency +; +; +MSGID_ICONSPAGE_ATTRIBUTES_TRANSPARENCY_DEFICONS_SHORTHELP (//) +Default icons may be drawn transparent.\n\ +Please select the degree of transparency you\n\ +would like default icons to be draw with.\n\ +Please note that real transparency is only available\n\ +if your desktop screen has more than 256 colors. +; +; +MSGID_ICONSPAGE_LABELS_FONT_SAMPLETEXT_SHORTHELP (//) +This is an example text to visualize what the selected font looks like +; +; +MSGID_ICONSPAGE_HILITE_UNDER_MOUSE (//) +Mark icon under mouse: +; +; +MSGID_ICONSPAGE_HILITE_UNDER_MOUSE_SHORTHELP (//) +If this switch is turned on, every\n\ +icon is shown in a highlighted stated\n\ +while the mouse pointer is over it. +; +; +MSGID_ICONSPAGE_ICONSCALING (//) +Icon Scaling +; +; +MSGID_ICONSPAGE_SCALING_MINSIZE (//) +Minimum Size: +; +; +MSGID_ICONSPAGE_SCALING_MINSIZE_SHORTHELP (//) +Minimum size for displayed icons.\n\ +Smaller icons will be scaled to\n\ +the specified minimum size. +; +; +MSGID_ICONSPAGE_SCALING_MAXSIZE (//) +Maximum Size: +; +; +MSGID_ICONSPAGE_SCALING_MAXSIZE_SHORTHELP (//) +Maximum size for displayed icons.\n\ +Larger icons will be scaled to\n\ +the specified maximum size. +; +; +MSGID_ICONSPAGE_GROUP_ICONFONT (//) +Standard Font +; +; +MSGID_ICONSPAGE_LABELS_ICONFONT_SHORTHELP (//) +Select font to display icon names.\n\ +This selection is disabled while TrueType\n\ +icon fonts are enabled. +; +; +MSGID_ICONSPAGE_ICONFONT_ASLTITLE (//) +Please select an icon font... +; +; +MSGID_ICONSPAGE_ICONTHUMBNAILS (//) +Thumbnails +; +; +MSGID_ICONSPAGE_SHOWTHUMBNAILS (//) +Display Thumbnails: +; +; +MSGID_ICONSPAGE_SHOWTHUMBNAILS_SHORTHELP (//) +Select if and when icons are displayed as image thumbnails:\n\ +Never - don't show thumbnails\n\ +As default - show thumbnails instead of default icons\n\ +Always - always show thumbnails +; +; +MSGID_ICONSPAGE_SHOWTHUMBNAILS_AS_DEFAULT (//) +Ignore \033bShowOnlyIcons\033n mode: +; +; +MSGID_ICONSPAGE_SHOWTHUMBNAILS_AS_DEFAULT_SHORTHELP (//) +Select it to allow the displaying of icons\n\ +thumbnails images for default icons with windows\n\ +using the \033bShow Only Icons\033n show mode.\n\ +\n\ +This option is only availlable if \033bAs default\033n\n\ +option is set from \033bDisplay Thumbnails\033n setting. +; +; +MSGID_ICONSPAGE_THUMBNAILS_SIZE (//) +Thumbnail size: +; +; +MSGID_ICONSPAGE_THUMBNAILS_SIZE_SHORTHELP (//) +Select desired size for thumbnail images.\n\ +Actual size may vary, due to image aspect. +; +; +MSGID_ICONSPAGE_THUMBNAILS_MAXAGE (//) +Cleanup after: +; +; +MSGID_ICONSPAGE_THUMBNAILS_MAXAGE_SHORTHELP (//) +Cached thumbnail images will be removed from the cache\n\ +if they have not been accessed for more than the\n\ +specified number of days, in order to keep cache\n\ +size as small as possible. +; +; +MSGID_ICONSPAGE_THUMBNAILS_MAXAGE_DAYS (//) +days +; +; +MSGID_ICONSPAGE_THUMBNAILS_MINSIZE_LIMIT (//) +Minimum caching size: +; +; +MSGID_ICONSPAGE_THUMBNAILS_MINSIZE_LIMIT_SHORTHELP (//) +Select desired minimum dimensions for images to cache.\n\ +Images with smallers dimensions than value specified here,\n\ +will not be added to the cache. +; +; +MSGID_ICONSPAGE_TOOLTIPS_TRANSPARENCY (//) +Transparency +; +; +MSGID_ICONSPAGE_TOOLTIPS_TRANSPARENCY_SHORTHELP (//) +Tooltips can be drawn transparent.\n\ +Please select the degree of\n\ +transparency for the tooltips.\n\ +Please note that transparency is only available\n\ +if your desktop screen has more than 256 colors. +; +; +MSGID_ICONSPAGE_THUMBNAILS_SETTINGS (//) +Settings +; +; +MSGID_ICONSPAGE_THUMBNAILS_CACHE (//) +Caching +; +; +MSGID_ICONSPAGE_THUMBNAILS_QUALITY (//) +Quality +; +; +MSGID_ICONSPAGE_THUMBNAILS_QUALITY_WORST (//) +Low +; +; +MSGID_ICONSPAGE_THUMBNAILS_QUALITY_BEST (//) +High +; +; +MSGID_ICONSPAGE_THUMBNAILS_QUALITY_SHORTHELP (//) +This slider selects the quality of the generated thumbnails.\n\ +Usually, better quality thumbnails take longer to create.\n\ +The actual effect of quality setting depends on the preview plugin used. +; +; +MSGID_ICONSPAGE_THUMBNAILS_SQUARE (//) +Thumbnails always square: +; +; +MSGID_ICONSPAGE_THUMBNAILS_SQUARE_SHORTHELP (//) +By default, thumbnail image icons reflect the aspect ratio\n\ +of their parent images, i.e. they can be wider than high or vice versa.\n\ +If this checkbox is checked, thumbnail image icons are always square.\n\ +; +; +MSGID_ICONSPAGE_THUMBNAILS_ICONFRAME (//) +Thumbnail Icon Frames +; +; +MSGID_ICONSPAGE_THUMBNAILS_ICONFRAME_NORMAL_SHORTHELP (//) +This type of border is drawn around unselected thumbnail icons.\n\ +\033bGlowIcons\033n which have been marked as\n\ +\"borderless\" will not show this border.\n\ +;Please note that the icon borders below must\n\ +;be non-zero for the icon border to show. +; +; +MSGID_ICONSPAGE_THUMBNAILS_ICONFRAME_SELECTED_SHORTHELP (//) +This type of border is drawn around selected thumbnail icons.\n\ +\033bGlowIcons\033n which have been marked as\n\ +\"borderless\" will not show this border.\n\ +;Please note that the icon borders below must\n\ +;be non-zero for the icon border to show. +; +; +MSGID_ICONSPAGE_THUMBNAILS_BACKFILL (//) +Thumbnails background filled +; +; +MSGID_ICONSPAGE_THUMBNAILS_BACKFILL_SHORTHELP (//) +Enable this attribute to draw all thumbnail icons with the\n\ +backfill colors defined by Scalos palette prefs.\n\ +If this switch is off, thumbnails have transparent background. +; +; +MSGID_ICONSPAGE_THUMBNAIL_BACKFILL_TRANSPARENCY (//) +Thumbnail background transparency +; +; +MSGID_ICONSPAGE_THUMBNAIL_BACKFILL_TRANSPARENCY_SHORTHELP (//) +True-color icons can be drawn with filled\n\ +background of selectable transparency. +; +; +MSGID_ICONSPAGE_SEL_ICONTEXT_RECT_GROUP (//) +Selected Icon Text Rectangle +; +; +MSGID_ICONSPAGE_SEL_ICONTEXT_RECT (//) +Draw additional rectangle around selected icon text +; +; +MSGID_ICONSPAGE_SEL_ICONTEXT_RECT_SHORTHELP (//) +Select this checkbox to draw a rectangle around the\n\ +icon text of all selected icons, for improved visibility. +; +; +MSGID_ICONSPAGE_SEL_ICONTEXT_XBORDER (//) +Additional Horizontal border +; +; +MSGID_ICONSPAGE_SEL_ICONTEXT_XBORDER_SHORTHELP (//) +Additional horizontal border which is used for\n\ +drawing a rectangle around the icon text of selected icons. +; +; +MSGID_ICONSPAGE_SEL_ICONTEXT_YBORDER (//) +Additional Vertical border +; +; +MSGID_ICONSPAGE_SEL_ICONTEXT_YBORDER_SHORTHELP (//) +Additional vertical border which is used for drawing\n\ +a rectangle around the icon text of selected icons. +; +; +MSGID_ICONSPAGE_SEL_ICONTEXT_RADIUS (//) +Corner Radius +; +; +MSGID_ICONSPAGE_SEL_ICONTEXT_RADIUS_SHORTHELP (//) +Corner radius of the rectangle drawn\n\ +around the text of selected icons. +; +; +MSGID_ICONSPAGE_SCALING_NOMINALSIZE (//) +Nominal Size: +; +; +MSGID_ICONSPAGE_SCALING_NOMINALSIZE_SHORTHELP (//) +Standard size adjustment applied to all icons. +; +; +MSGID_ICONSPAGE_SCALING_PERCENT (//) +% +; +;----------------------------------------------------------- +; +MSGID_DRAGNDROPPAGE_STYLE (25500//) +Style: +; +; +MSGID_DRAGNDROPPAGE_STYLE_SHORTHELP (//) +The icon label may be displayed\n\ +whilst the icon is being dragged. +; +; +MSGID_DRAGNDROPPAGE_BOBS (//) +Bobs +; +; +MSGID_DRAGNDROPPAGE_ROUTINES (//) +Bob Routines: +; +; +MSGID_DRAGNDROPPAGE_ROUTINES_SHORTHELP (//) +Scalos provides custom fast smooth icon dragging routines.\n\ +Those custom routines are only used if you are\n\ +running a desktop with more than 256 colours. +; +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY (//) +Transparency Method: +; +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY_SHORTHELP (//) +When \"Ghosted/Real Transparent\" is selected, use\n\ +real transparency to draw drag-drop icons. Otherwise,\n\ +dotted \"ghosted\" display is used. Please note that\n\ +real transparency is only available if your\n\ +desktop screen has more than 256 colors. +; +; +MSGID_DRAGNDROPPAGE_DROPMARKMODE (//) +Drop mark mode: +; +; +MSGID_DRAGNDROPPAGE_DROPMARKMODE_SHORTHELP (//) +Select which kind of drop-marks Scalos\n\ +shows while you drag icons around. +; +; +MSGID_DRAGNDROPPAGE_LOOK (//) +Look: +; +; +MSGID_DRAGNDROPPAGE_LOOK_SHORTHELP (//) +A Trigger can change the look of the icon\n\ +currently being dragged. You can select what\n\ +\033btriggers\033n should affect your icons below. +; +; +MSGID_DRAGNDROPPAGE_AUTOREMOVE (//) +Auto remove icons: +; +; +MSGID_DRAGNDROPPAGE_AUTOREMOVE_SHORTHELP (//) +If enabled, when you drag icons away from their\n\ +original position, only a semi-transparent shadow\n\ +of the icon remains at the original place. +; +; +MSGID_DRAGNDROPPAGE_GROUP_MULTIPLE (+2//) +Group multiple icons: +; +; +MSGID_DRAGNDROPPAGE_GROUP_MULTIPLE_SHORTHELP (//) +When dragging multiple icons\n\ +they will appear as a pile\n\ +to speed up OS. +; +; +MSGID_DRAGNDROPPAGE_DRAGGINGLABEL (//) +Display dragging label: +; +; +MSGID_DRAGNDROPPAGE_DRAGGINGLABEL_SHORTHELP (//) +When dragging multiple icons Scalos will display\n\ +a text line detailing number of files, drawers\n\ +and devices being dragged. +; +; +MSGID_DRAGNDROPPAGE_FORCECOPY (//) +Force copy: +; +; +MSGID_DRAGNDROPPAGE_FORCECOPY_SHORTHELP (//) +Define the qualifier key that is used to\n\ +force copying (instead of moving) any\n\ +dragged files and drawers. +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS (//) +Triggers +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_SHORTHELP (//) +Enabling a trigger will change the icons appearance\n\ +to the \033bLook\033n configured above when the\n\ +icon is above trigger. +; +; +MSGID_DRAGNDROPPAGE_QUALIFIERS (//) +Qualifiers +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_DISKICONS (//) +Disk icons +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_DRAWERICONS (//) +Drawer icons +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_TOOLICONS (//) +Tool icons +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_PROJECTICONS (//) +Project icons +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_TRASHCANICONS (//) +Trashcan icons +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_KICKICONS (//) +Kick icons +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_APPICONS (//) +Application icons +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_APPWINDOWS (//) +Application windows +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_ICONIFIED_WINDOWS (//) +Iconified windows +; +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY_ICONDRAG (//) +Dragged icons +; +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY_ICONDRAG_SHORTHELP (//) +Select degree of icon transparency when dragging icons.\n\ +0%% means completely transparent (invisible!) icons.\n\ +100%% means opaque icons.\n\ +Please note that real transparency is only available\n\ +if your desktop screen has more than 256 colors. +; +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY_ICONSHADOW (//) +Icon shadow +; +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY_ICONSHADOW_SHORTHELP (//) +Select degree of transparency of the icon shadow that\n\ +remains at the original position when you start\n\ +dragging the icon away.\n\ +0% means completely transparent (invisible!) shadow.\n\ +100% means opaque shadow.\n\ +Please note that real transparency is only available\n\ +if your desktop screen has more than 256 colors. +; +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY_OPAQUE (//) +opaque +; +; +MSGID_DRAGNDROPPAGE_TRANSPARENCY_TRANSPARENT (//) +transparent +; +; *** new in V40.10 *** +MSGID_DRAGNDROPPAGE_EASY_MULTISELECT (//) +Easy Multiple Icon Selection: +; +; +MSGID_DRAGNDROPPAGE_EASY_MULTISELECT_SHORTHELP (1//) +When enabled, you are not required to hold the\n\ +\033bshift\033n key to select multiple icons. +; +; +MSGID_DRAGNDROPPAGE_EASY_MULTIDRAG (//) +Easy Dragging of Multiple Icons: +; +; +MSGID_DRAGNDROPPAGE_EASY_MULTIDRAG_SHORTHELP (//) +When enabled, you are not required to hold the\n\ +\033bshift\033n key when you begin to drag\n\ +multiple selected icons. +; +; +MSGID_DRAGNDROPPAGE_FORCEMAKELINK (//) +Create Links: +; +; +MSGID_DRAGNDROPPAGE_FORCEMAKELINK_SHORTHELP (//) +Define the qualifier key that is used to\n\ +create links to (instead of copying or\n\ +moving) any dragged files and drawers. +; +; +MSGID_DRAGNDROPPAGE_FORCEMOVE (//) +Force move: +; +; +MSGID_DRAGNDROPPAGE_FORCEMOVE_SHORTHELP (//) +Define the qualifier key that is used to\n\ +force moving (instead of copying) any\n\ +dragged files and drawers. +; +; +MSGID_DRAGNDROPPAGE_DROPMENU (//) +Show Drop Menu: +; +; +MSGID_DRAGNDROPPAGE_DROPMENU_SHORTHELP (//) +When enabled, a popup menu is displayed on each drag-drop\n\ +operation that allows easy selection whether to \033bcopy\033n or\n\ +\033bmove\033n item, \033bcreate link\033n to item, or entirely cancel drag-drop. +; +; +MSGID_DRAGNDROPPAGE_TRIGGERS_SCALOS_WINDOWS (//) +Scalos Windows +; +; +MSGID_DRAGNDROPPAGE_POPOPENWINDOWS (//) +Pop-Open Windows +; +; +MSGID_DRAGNDROPPAGE_SLIDER_POPOPWINDOW_DELAY (//) +Pop-Open Delay: +; +; +MSGID_DRAGNDROPPAGE_SLIDER_POPOPWINDOW_DELAY_SHORTHELP (//) +During a drag&drop operation, this is the number of seconds\n\ +you have to keep the mouse pointer steady over a drawer\n\ +or volume icon before it pops open. +; +;----------------------------------------------------------- +; +MSGID_WINDOWPAGE_WINDOWTITLES (25600//) +Window Titles +; +; +MSGID_WINDOWPAGE_WINDOWTITLES_ROOTWINDOW (//) +Root Window: +; +; +MSGID_WINDOWPAGE_WINDOWTITLES_ROOTWINDOW_SHORTHELP (//) +This is the title for the Scalos root window. You only\n\ +see this window title when you have the \"Backdrop\"\n\ +menu item in the Scalos main menu unchecked. +; +; +MSGID_WINDOWPAGE_WINDOWTITLES_ROOTWINDOW_DESCRIPTION (//) +|\033b\0338Description +; +; +MSGID_WINDOWPAGE_WINDOWTITLES_DIRECTORYWINDOW (//) +Directory Window: +; +; +MSGID_WINDOWPAGE_WINDOWTITLES_DIRECTORYWINDOW_SHORTHELP (//) +This is the window title for any\n\ +normal Scalos drawer window. +; +; +MSGID_WINDOWPAGE_WINDOWTITLES_DIRECTORYWINDOW_DESCRIPTION (//) +|\033b\0338Description +; +; +MSGID_WINDOWPAGE_WINDOWTYPE (//) +Window type: +; +; +MSGID_WINDOWPAGE_WINDOWTYPE_SHORTHELP (//) +Select whether you would like to be all\n\ +Scalos windows to be created as simple-refresh\n\ +or smart-refresh window. +; +; +MSGID_WINDOWPAGE_CONTEXTMENU_DRAGBAR (//) +Context menu on dragbar only: +; +; +MSGID_WINDOWPAGE_CONTEXTMENU_DRAGBAR_SHORTHELP (//) +Only allows the windows pop-up menu\n\ +to appear when the right mouse button\n\ +is clicked over the\nwindows dragbar +; +; +MSGID_WINDOWPAGE_MMB_MOVE (//) +MMB Moves Contents: +; +; +MSGID_WINDOWPAGE_MMB_MOVE_SHORTHELP (//) +Allows the use of the middle mouse button\n\ +to pan around the window contents +; +; +MSGID_WINDOWPAGE_SHOW_STATUSBAR (//) +Show status bar: +; +; +MSGID_WINDOWPAGE_SHOW_STATUSBAR_SHORTHELP (//) +Globally sets whether directory windows\n\ +display the status bar at the bottom. +; +; +MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE (//) +Default Window Size +; +; +MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE_SHORTHELP (//) +These are the default dimensions for Scalos drawer\n\ +windows. Windows for drawers without icons are opened\n\ +at this position and in this size. You are free to\n\ +move and resize the window any way you like, and\n\ +use \"snapshot window\" to permanently store the\n\ +changed values for that specific drawer window. +; +; +MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE_LEFT (//) +Left: +; +; +MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE_TOP (//) +Top: +; +; +MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE_WIDTH (//) +Width: +; +; +MSGID_WINDOWPAGE_DEFAULT_WINDOWSIZE_HEIGHT (//) +Height: +; +; +MSGID_WINDOWPAGE_CLEANUPSPACE (//) +Cleanup Spaces +; +; +MSGID_WINDOWPAGE_CLEANUPSPACE_SHORTHELP (//) +This are the distances Scalos will leave around\n\ +icons when they are positioned with\n\ +the \"cleanup\" command. +; +; +MSGID_WINDOWPAGE_CLEANUPSPACE_LEFT (//) +Left: +; +; +MSGID_WINDOWPAGE_CLEANUPSPACE_TOP (//) +Top: +; +; +MSGID_WINDOWPAGE_CLEANUPSPACE_XSKIP (//) +X-Skip: +; +; +MSGID_WINDOWPAGE_CLEANUPSPACE_YSKIP (//) +Y-Skip: +; +; +MSGID_WINDOWPAGE_CLEANUP_ONRESIZE (//) +Rearrange icons on resize: +; +; +MSGID_WINDOWPAGE_CLEANUP_ONRESIZE_SHORTHELP (//) +If this switch is enabled, all icons\n\ +without fixed position are automatically\n\ +rearranged when window is resized. +; +; +MSGID_WINDOWPAGE_SHOWALL_DEFAULT (//) +Default mode for \033bShow All\033n: +; +; +MSGID_WINDOWPAGE_SHOWALL_DEFAULT_SHORTHELP (//) +This setting selects how the value \"default\"\n\ +is handled for \033bshow all\033n.\n\ +You can select whether \"default\" shows\n\ +\033bonly icons\033n, or \033ball files\033n. +; +; +MSGID_WINDOWPAGE_VIEWBY_DEFAULT (//) +Default mode for \033bView By\033n: +; +; +MSGID_WINDOWPAGE_WINDOWTYPE_VIEWBY_DEFAULT_SHORTHELP (//) +Selects which view mode is to be used for all\n\ +drawers with their view mode set to \"default\". +; +; +MSGID_WINDOWPAGE_CONTROLBAR_BROWSER_GADGETS (//) +Browser Window Gadgets +; +; +MSGID_WINDOWPAGE_CONTROLBAR_GADGETS_SHORTHELP (//) +Select here which gadgets you would like to\n\ +have in your browser window control bar. +; +; +MSGID_WINDOWPAGE_CONTROLBAR_AVAILABLE_GADGETS (//) +Available Gadgets +; +; +MSGID_WINDOWPAGE_CONTROLBAR_AVAILABLE_GADGETS_SHORTHELP (//) +Select one ore move gadgets from this list and drag\n\ +them to the list of \033bActive Gadgets\00n. +; +; +MSGID_WINDOWPAGE_CONTROLBAR_ACTIVE_GADGETS (//) +Active Gadgets +; +; +MSGID_WINDOWPAGE_CONTROLBAR_ACTIVE_GADGETS_SHORTHELP (//) +These are the gadgets currently on your control bar.\n\ +Change the order of the gadgets by sorting them via drag-and-drop.\n\ +To remove gadgets, drag them to the\n\ +\033bAvailable Gadgets\033n on the left.\n\ +To add new gadgets, drag new gadgets from the\n\ +\033bAvailable Gadgets\033n to the position you want to see them. +; +; +MSGID_CONTROLBARGADGETLIST_TYPE (//) +Gadget Type +; +; +MSGID_WINDOWPAGE_CONTROLBAR_NORMALIMAGE (//) +Unselected Image +; +; +MSGID_WINDOWPAGE_CONTROLBAR_NORMALIMAGE_ASLTITLE (//) +Select image for unselected state +; +; +MSGID_WINDOWPAGE_CONTROLBAR_NORMALIMAGE_SHORTHELP (//) +Select here any datatypes image for the\n\ +unselected state of a user-defined button. +; +; +MSGID_WINDOWPAGE_CONTROLBAR_SELECTEDIMAGE (//) +Selected Image +; +; +MSGID_WINDOWPAGE_CONTROLBAR_SELECTEDIMAGE_ASLTITLE (//) +Select image for Selected state +; +; +MSGID_WINDOWPAGE_CONTROLBAR_SELECTEDIMAGE_SHORTHELP (//) +Select here any datatypes image for the\n\ +selected state of a user-defined button. +; +; +MSGID_WINDOWPAGE_CONTROLBAR_DISABLEDIMAGE (//) +Disabled Image +; +; +MSGID_WINDOWPAGE_CONTROLBAR_DISABLEDIMAGE_ASLTITLE (//) +Select image for Disabled state +; +; +MSGID_WINDOWPAGE_CONTROLBAR_DISABLEDIMAGE_SHORTHELP (//) +Select here any datatypes image for the\n\ +disabled state of a user-defined button. +; +; +MSGID_WINDOWPAGE_CONTROLBAR_ACTION (//) +Button Action +; +; +MSGID_WINDOWPAGE_CONTROLBAR_ACTION_SHORTHELP (//) +For user-defined buttons select here any action from\n\ +the list of available Scalos menu commands. +; +; +MSGID_WINDOWPAGE_CONTROLBAR_GADGETHELPTEXT (//) +Help Text +; +; +MSGID_WINDOWPAGE_CONTROLBAR_GADGETHELPTEXT_SHORTHELP (//) +For user-defined buttons, enter your gadget help text here.\n\ +This text is displayed when you keep your mouse\n\ +steadily positioned on the gadgets for a few seconds. +; +; +MSGID_WINDOWPAGE_CHECK_OVERLAP (//) +Check for Overlapping Icons: +; +; +MSGID_WINDOWPAGE_CHECK_OVERLAP_SHORTHELP (//) +Globally sets whether verification is performed that icons do\n\ +not overlap each other.\n\ +If enabled, overlapping icons will be repositioned when read. +; +; +MSGID_WINDOWPAGE_TRANSPARENCY_WINDOW (//) +Transparency +; +; +MSGID_WINDOWPAGE_TRANSPARENCY_ACTIVEWINDOW (//) +Active window +; +; +MSGID_WINDOWPAGE_TRANSPARENCY_INACTIVEWINDOW (//) +Inactive windows +; +; +MSGID_WINDOWPAGE_TRANSPARENCY_ACTIVEWINDOW_SHORTHELP (//) +Here you can select the degree of transparency\n\ +for the active Scalos desktop, icon, or text window.\n\ +The desktop will only get transparent if it is not a backdrop window. +; +; +MSGID_WINDOWPAGE_TRANSPARENCY_INACTIVEWINDOW_SHORTHELP (//) +Here you can select the degree of transparency\n\ +for all inactive Scalos desktop, icon, or text windows.\n\ +The desktop will only get transparent if it is not a backdrop window. +; +; +MSGID_WINDOWPAGE_CONTROLBAR_NORMAL_GADGETS (//) +Standard Window Gadgets +; +;----------------------------------------------------------- +; +MSGID_TEXTWINDOWSPAGE_SELECTION_BORDER_TRANSPARENCY (15700//) +Border Transparency +; +; +MSGID_TEXTWINDOWSPAGE_SELECTION_FILL_TRANSPARENCY (//) +Fill Transparency +; +; +MSGID_TEXTWINDOWSPAGE_GROUP_BASECOLOR (//) +Base Color +; +; +MSGID_TEXTWINDOWSPAGE_SELECTIONMARK_BASECOLOR_SHORTHELP (//) +Here you can adjust the base color for the\n\ +text window icon selection marker. +; +; +MSGID_TEXTWINDOWSPAGE_SELECTIONMARK_BORDER_TRANSPARENCY_SHORTHELP (//) +Adjust degree of transparency for the border\n\ +of the text window icon selection marker. +; +; +MSGID_TEXTWINDOWSPAGE_SELECTIONMARK_FILL_TRANSPARENCY_SHORTHELP (//) +Adjust degree of transparency for the interior\n\ +fill of the text window icon selection marker. +; +; +MSGID_TEXTWINDOWPAGE_DRAWERSORT_TOP (//) +Before files +; +; +MSGID_TEXTWINDOWPAGE_DRAWERSORT_BOTTOM (//) +After files +; +; +MSGID_TEXTWINDOWPAGE_DRAWERSORT_MIXED (//) +With files +; +; +MSGID_TEXTWINDOWSPAGE_DRAWERSORT (//) +Drawer sorting: +; +; +MSGID_TEXTWINDOWSPAGE_DRAWERSORT_SHORTHELP (//) +Select how drawers are sorted in text windows.\n\ +Drawers can be displayed always on top, always\n\ +on bottom, or mixed between files. +; +;----------------------------------------------------------- +; +MSGID_FILEDISPLAYPAGE_FONT (5701//) +Font: +; +; +MSGID_FILEDISPLAYPAGE_FONT_SHORTHELP (//) +Select font to display text window contents.\n\ +This selection is disabled while TrueType\n\ +text window fonts are enabled. +; +; +MSGID_FILEDISPLAYPAGE_FONT_ASLTITLE (//) +Please select a font... +; +; +MSGID_FILEDISPLAYPAGE_FONT_EXAMPLE (//) +Example: +; +; +MSGID_FILEDISPLAYPAGE_FONT_SAMPLETEXT (//) +This is an example text to visualize what the selected font looks like +; +; +MSGID_FILEDISPLAYPAGE_SOFTLINKS_UNDERLINED (//) +Display soft-link file names \033uunderlined\033n: +; +; +MSGID_FILEDISPLAYPAGE_SOFTLINKS_UNDERLINED_SHORTHELP (//) +When this item is checked, names of soft-links\n\ +are displayed \033uunderlined\033n. +; +; +MSGID_FILEDISPLAYPAGE_HIDE_HIDDENFILES (//) +Hide hidden files: +; +; +MSGID_FILEDISPLAYPAGE_HIDE_HIDDENFILES_SHORTHELP (//) +A hidden file is any filename beginning with\n\ +a '\033b.\033n' or icon files '\033b#?.info\033n' +; +; +MSGID_FILEDISPLAYPAGE_AVAILABLE_COLUMNS (+1//) +Available Columns +; +; +MSGID_FILEDISPLAYPAGE_AVAILABLE_COLUMNS_SHORTHELP (//) +This are the columns currently not displayed\n\ +in text windows. If you want some item to be\n\ +displayed, drag it to the \"Displayed columns\" list. +; +; +MSGID_FILEDISPLAYPAGE_COLUMNS_INUSE (//) +Displayed Columns +; +; +MSGID_FILEDISPLAYPAGE_COLUMNS_INUSE_SHORTHELP (//) +This are the columns that will display in text\n\ +windows. You may change the display order by\n\ +drag-sorting the lines. If you want some item\n\ +not to be displayed, drag it to\n\ +the \"Available columns\" list. +; +; +MSGID_FILEDISPLAYPAGE_STRIPED (//) +Striped Display +; +; +MSGID_FILEDISPLAYPAGE_STRIPED_SHORTHELP (//) +Shows every other line in text window\n\ +in different color, to improve readability.\n\ +Please note that striped display is only available\n\ +if your desktop screen has more than 256 colors. +; +; +MSGID_FILEDISPLAYPAGE_HIDE_PROTECTHIDDENFILES (//) +Hide files with protect bit hidden: +; +; +MSGID_FILEDISPLAYPAGE_HIDE_PROTECTHIDDENFILES_SHORTHELP (//) +If checked, any file with the hidden protection\n\ +bit(\033bH\033nSPARWED) activated, will be hidden. +; +; +MSGID_FILEDISPLAYPAGE_SELECTTEXTICONNAME (//) +Name column selects text icons +; +; +MSGID_FILEDISPLAYPAGE_SELECTTEXTICONNAME_SHORTHELP (//) +If this checkmark is checked, text icons can\n\ +only be selected within the \033bname\033n column.\n\ +If unchecked, the entire row can be used\n\ +to select the icon. +; +;----------------------------------------------------------- +; +MSGID_TTFONTSPAGE_SCREENFONT (5750//) +TrueType Screen Font +; +; +MSGID_TTFONTSPAGE_SCREENFONT_ENABLE (//) +Use TT Screen Font: +; +; +MSGID_TTFONTSPAGE_SCREENFONT_ENABLE_SHORTHELP (//) +When this item is checked, Scalos uses\n\ +TrueType fonts for screen font. +; +; +MSGID_TTFONTSPAGE_SCREENFONT_SHORTHELP (//) +This is the textual TrueType screen font\n\ +specification (style/weight/size/name). +; +; +MSGID_TTFONTSPAGE_ICONFONT (//) +TrueType Icon Font +; +; +MSGID_TTFONTSPAGE_ICONFONT_ENABLE (//) +Use TT Icon Font: +; +; +MSGID_FONTSPAGE_TTFICONFONT_ENABLE_SHORTHELP (//) +When this item is checked, Scalos\n\ +uses TrueType fonts for icons. +; +; +MSGID_TTFONTSPAGE_ICONFONT_SHORTHELP (//) +This is the textual TrueType icon font\n\ +specification (style/weight/size/name). +; +; +MSGID_TTFONTSPAGE_TEXTWINDOWFONT (//) +TrueType Text Window Font +; +; +MSGID_TTFONTSPAGE_TTFTEXTWINDOWFONT_ENABLE (//) +Use TT Text Window Font: +; +; +MSGID_TTFONTSPAGE_TTFTEXTWINDOWFONT_ENABLE_SHORTHELP (//) +When this item is checked, Scalos uses\n\ +TrueType fonts for text windows. +; +; +MSGID_TTFONTSPAGE_TEXTWINDOWFONT_SHORTHELP (//) +This is the textual TrueType text window\n\ +font specification (style/weight/size/name). +; +; +MSGID_TTFONTSPAGE_SAMPLETEXT (//) +The quick brown fox jumps over the lazy dog +; +; +MSGID_TTFONTSPAGE_SCREENFONT_SAMPLETEXT_SHORTHELP (//) +This is an example text to visualize what the\n\ +selected TrueType screen font looks like. +; +; +MSGID_TTFONTSPAGE_ICONFONT_SAMPLETEXT_SHORTHELP (//) +This is an example text to visualize what the\n\ +selected TrueType icon font looks like. +; +; +MSGID_TTFONTSPAGE_TEXTWINDOWFONT_SAMPLETEXT_SHORTHELP (//) +This is an example text to visualize what the\n\ +selected TrueType text window font looks like. +; +; +MSGID_TTFONTSPAGE_SELECTSCREENFONT_ASLTITLE (//) +Select Screen TT Font... +; +; +MSGID_TTFONTSPAGE_SELECTICONFONT_ASLTITLE (//) +Select Icon TT Font... +; +; +MSGID_TTFONTSPAGE_SELECTTEXTWINDOWFONT_ASLTITLE (//) +Select Text Window TT Font... +; +; +MSGID_TTFONTSPAGE_SELECTFONT_ASL_OKBUTTON (//) +Ok +; +; +MSGID_TTFONTSPAGE_SELECTFONT_ASL_CANCELBUTTON (//) +Cancel +; +; +MSGID_TTFONTSPAGE_GLOBALS (//) +Globals +; +; +MSGID_TTFONTSPAGE_ANTIALIASING (//) +Antialiasing: +; +; +MSGID_TTFONTSPAGE_ANTIALIASING_SHORTHELP (//) +Controls ttengine antialiasing (on, off or automatic):\n\ +Off - turns antialias off\n\ +On - turns antialias on\n\ +Auto (default) - antialias state depends on font\n\ +size. Typically sizes of 9 or less pixels are\n\ +antialiased, sizes from 10 to 19 pixels are not\n\ +antialiased, sizes of 20 of more pixels are\n\ +antialiased. These settings can be changed in the\n\ +ttengine font database separately for every font face. +; +; +MSGID_TTFONTSPAGE_ANTIALIASING_ON (//) +On +; +; +MSGID_TTFONTSPAGE_ANTIALIASING_OFF (//) +Off +; +; +MSGID_TTFONTSPAGE_ANTIALIASING_AUTO (//) +Auto +; +; +MSGID_TTFONTSPAGE_GAMMA (//) +Gamma correction: +; +; +MSGID_TTFONTSPAGE_GAMMA_SHORTHELP (//) +Adjustable gamma correction used for ttengine\n\ +antialiasing. After RGB alphablending gamma\n\ +correction is applied to resulting pixel colour\n\ +according to x' = x ^ 1/gamma, where x\n\ +is a RGB component. +; +;----------------------------------------------------------- +; +MSGID_MISCPAGE_MENU_CURRENTDIR (5800//) +Menu CurrentDir: +; +; +MSGID_MISCPAGE_MENU_CURRENTDIR_SHORTHELP (//) +If enabled, Scalos changes to the directory of\n\ +the CLI tool before running a CLI menu command. +; +; +MSGID_MISCPAGE_HARD_EMULATION (//) +Hard emulation: +; +; +MSGID_MISCPAGE_HARD_EMULATION_SHORTHELP (//) +If this item is checked, some additional Workbench\n\ +function vectors are patched by Scalos. In most\n\ +cases, there shouldn't be any reason to\n\ +turn off \"Hard emulation\". +; +; +MSGID_MISCPAGE_USE_EXALL (//) +Use ExAll(): +; +; +MSGID_MISCPAGE_USE_EXALL_SHORTHELP (//) +If this item is checked, Scalos will try to use\n\ +the \"ExAll()\" function to scan directories.\n\ +Usually, if a file system doesn't support ExAll(),\n\ +there is a fully automatic fall-back to other\n\ +functions. However, there might be some file systems\n\ +that don't support ExAll() but don't return\n\ +appropriate error codes either, or even crash.\n\ +If you happen to have such a file system, try to\n\ +turn \"Use ExAll()\" off. +; +; +MSGID_MISCPAGE_POPUPMENUS (//) +Popup menus +; +; +MSGID_MISCPAGE_POPUP_SELECTED_HOTKEY (//) +Apply to every selected icon: +; +; +MSGID_MISCPAGE_POPUP_SELECTED_HOTKEY_SHORTHELP (//) +Define the qualifier key that\n\ +applies popup menu commands to\n\ +every selected icon.\n\ +Normally, popup menu commands only apply\n\ +to the icon under the mouse pointer. +; +; +MSGID_MISCPAGE_DEFAULTSTACKSIZE (//) +Default Stack size: +; +; +MSGID_MISCPAGE_DEFAULTSTACKSIZE_SHORTHELP (//) +Sets the stack size for most internal Scalos\n\ +processes and for CLI and ARexx processes\n\ +started by Scalos. +; +; +MSGID_MISCPAGE_DEFAULTSTACKSIZE_OS35 (//) +Starting with Workbench 3.5, the default stack size \ +is changed with the standard \ +\033bWorkbench Preferences\033n program. +; +; +MSGID_MISCPAGE_LABELS_STACK (//) +Stack +; +; +MSGID_MISCPAGE_CREATE_LINKS (//) +Create links: +; +; +MSGID_MISCPAGE_CREATE_LINKS_SHORTHELP (//) +Select what kind of links Scalos tries to create\n\ +when an object is dropped with the create-link\n\ +qualifier key pressed. +; +; +MSGID_MISCPAGE_POP_WORKBENCHPREFS_SHORTHELP (//) +Launch standard \033bWorkbench Preferences\033n program. +; +; +MSGID_MISCPAGE_POPUP_SELECTED_ALWAYS (//) +Always apply to all selected icons? +; +; +MSGID_MISCPAGE_POPUP_SELECTED_ALWAYS_SHORTHELP (//) +Select this checkbox to \033balways\033n apply popup menus\n\ +to every selected icons, regardless of qualifier key +; +; +MSGID_MISCPAGE_COPYBUFFERSIZE (//) +File Copy Buffer Size: +; +; +MSGID_MISCPAGE_COPYBUFFERSIZE_SHORTHELP (//) +Sets the buffer size for file copying. +; +; +MSGID_MISCPAGE_LABELS_FILEOPERATIONS (//) +File Operations +; +; +MSGID_MISCPAGE_LABELS_UNDOSTEPS (//) +Maximum Number of Undo Steps +; +; +MSGID_MISCPAGE_UNDOSTEPS (//) +Max. Undo Steps: +; +; +MSGID_MISCPAGE_UNDOSTEPS_SHORTHELP (//) +Here you can limit the number of\n\ +available Undo/Redo steps. +; +;----------------------------------------------------------- +; +MSGID_PLUGINSPAGE_ACTIVEPLUGINS (5900//) +Active Plugins +; +; +MSGID_PLUGINSPAGE_INSTALLEDPLUGINS (//) +\033cInstalled Plugins +; +; +MSGID_PLUGINSPAGE_INSTALLEDPLUGINS_SHORTHELP (//) +This is a complete list of all OOP plugins that\n\ +are loaded upon Scalos startup. OOP plugins add\n\ +new features to Scalos or improve existing\n\ +Scalos features. +; +; +MSGID_PLUGINSPAGE_ADD_NEW (//) +\033cAdd New +; +; +MSGID_PLUGINSPAGE_ADD_NEW_SHORTHELP (//) +Add a new OOP plugin to the list. This plugin\n\ +will be activated upon next Scalos startup. +; +; +MSGID_PLUGINSPAGE_REMOVE_SELECTED (//) +\033cRemove Selected +; +; +MSGID_PLUGINSPAGE_REMOVE_SELECTED_SHORTHELP (//) +Remove the currently selected plugin\n\ +from the list. Scalos will not load the\n\ +plugin again. This change will only become\n\ +effective upon next Scalos startup. +; +; +MSGID_PLUGINSPAGE_NAME (//) +\033lName: +; +; +MSGID_PLUGINSPAGE_NAME_SHORTHELP (//) +This is the name the selected plugin\n\ +has been given by its creator. +; +; +MSGID_PLUGINSPAGE_FILENAME (//) +\033lFile: +; +; +MSGID_PLUGINSPAGE_FILENAME_SHORTHELP (//) +This is the complete filename and\n\ +path for the selected plugin. +; +; +MSGID_PLUGINSPAGE_VERSION (//) +\033lVersion: +; +; +MSGID_PLUGINSPAGE_VERSION_SHORTHELP (//) +This is the current version\n\ +of the selected plugin. +; +; +MSGID_PLUGINSPAGE_DESCRIPTION (//) +\033lDescription: +; +; +MSGID_PLUGINSPAGE_DESCRIPTION_SHORTHELP (//) +This is a description of what the\n\ +selected plugin is supposed to do. +; +; +MSGID_PLUGINSPAGE_CREATOR (//) +\033lCreator: +; +; +MSGID_PLUGINSPAGE_CREATOR_SHORTHELP (//) +This is the creator's name\n\ +of the selected plugin. +; +; +MSGID_PLUGINSPAGE_EDIT_PREFERENCES (//) +\033cEdit Preferences +; +; +MSGID_PLUGINSPAGE_EDIT_PREFERENCES_SHORTHELP (//) +\033cEdit Preferences +; +; +MSGID_ADD_PLUGIN_ASLTITLE (//) +Select new OOP plugin... +; +;----------------------------------------------------------- +; +MSGID_MODULESPAGE_MODULE_PREFERENCES (6000//) +Module Preferences +; +; +MSGID_MODULESPAGE_MODULE_PREFERENCES_NOTICE (//) +To configure any Scalos modules' settings you must click on \ +the pop-up image gadget to the right of the modules name. \ +This will open a new window with specific settings in it.\n\ +\n\ +If no configuration is available for a certain module \ +the pop-up gadget will be disabled. +; +; +MSGID_MODULESPAGE_DELETE (//) +Delete +; +; +MSGID_MODULESPAGE_EMPTY_TRASHCAN (//) +Empty Trashcan +; +; +MSGID_MODULESPAGE_EXECUTE_COMMAND (//) +Execute Command +; +; +MSGID_MODULESPAGE_INFORMATION (//) +Information +; +; +MSGID_MODULESPAGE_NEWDRAWER (//) +New Drawer +; +; +MSGID_MODULESPAGE_REBOOT (//) +Reboot +; +; +MSGID_MODULESPAGE_RENAME (//) +Rename +; +; +MSGID_MODULESPAGE_SYSTEM_INFORMATION (//) +System Information +; +;----------------------------------------------------------- +; +MSGID_SAVEBUTTON (6100//) +\033cSave +; +; +MSGID_SAVEBUTTON_SHORTHELP (//) +Press this button to save \n\ +the current settings to\n\ +\"ENVARC:Scalos/Scalos.prefs\"\n\ +and make changes permanent. +; +; +MSGID_USEBUTTON (//) +\033cUse +; +; +MSGID_USEBUTTON_SHORTHELP (//) +Press this button to save \n\ +the current settings to\n\ +\"ENV:Scalos/menu13.prefs\"\n\ +and keep settings until reboot. +; +; +MSGID_CANCELBUTTON (//) +\033cCancel +; +; +MSGID_CANCELBUTTON_SHORTHELP (//) +Press this button to abort \n\ +and forget all changes. +; +;----------------------------------------------------------- +; +MSGID_ABOUTREQOK (6200//) +_OK +; +; +MSGID_ABOUTREQFORMAT (//) +\33c\033bScalos Main Preferences V%ld.%ld\033n\n\ +%s\n\ +© 2003%s The Scalos Team +; +;----------------------------------------------------------- +; +MSGID_DESKTOPPAGES_SCREENTITLE_ALWAYS (6300//) +Always visible +; +; +MSGID_DESKTOPPAGES_SCREENTITLE_POP (//) +Pops up under mouse +; +; +MSGID_DESKTOPPAGES_SCREENTITLE_NEVER (//) +permanently hidden +; +;----------------------------------------------------------- +; +; +MSGID_ICONSPAGES_DRAGNDROP_DRAGGING (6400//) +Dragging +; +; +MSGID_ICONSPAGES_DRAGNDROP_TRANSPARENCY (//) +Transparency +; +; +MSGID_ICONSPAGES_DRAGNDROP_TRIGGERS (//) +Triggers +; +;----------------------------------------------------------- +; +MSGID_FRAMEWINDOW_TITLE (6500//) +Available Frames +; +;----------------------------------------------------------- +; +MSGID_PLUGINLIST_NAME (6600//) +Name +; +; +MSGID_PLUGINLIST_PATH (//) +Path +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE (6700//) +Scalos Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD (//) +Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_ADDPLUGIN_FAILURE (6800//) +Add Plugin Failure +; +; +MSGID_ADDPLUGIN_OK_GAD (//) +Ok +; +MSGID_ADDPLUGIN_COULD_NOT_ADD (//) +Could not add plugin.\n\ +Opening the plugin \"%s\" failed. +; +;----------------------------------------------------------- +; +MSGID_DESKTOPPAGE_ICONS_HIDDENDEVICES (6900//) +Hidden Devices +; +; +MSGID_DESKTOPPAGE_HIDDENDEVICES_SHORTHELP (//) +Here you can select which devices will never show up on desktop.\n\ +This is the same setting as available in OS3.9 Workbench Prefs. +; +;----------------------------------------------------------- +; +MSGID_DESKTOPPAGE_LAYOUTPREFERENCES (7000//) +Desktop Layout Preferences by Icon Type +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBDISK (//) +Disk icons: +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBDISK_SHORTHELP (//) +Select preferred icon layout direction\n\ +for \033bdisk icons\033n in desktop window.\n\ +\033iColumns\033n layouts icons in columns from top\n\ +to bottom, starting a new column when the\n\ +bottom of the window is reached.\n\ +\033iRows\033n layouts icons in rows left to right,\n\ +starting a new row when the right\n\ +window border is reached. +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBDRAWER (//) +Drawer icons: +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBDRAWER_SHORTHELP (//) +Select preferred icon layout direction\n\ +for \033bdrawer icons\033n in desktop window.\n\ +\033iColumns\033n layouts icons in columns from top\n\ +to bottom, starting a new column when the\n\ +bottom of the window is reached.\n\ +\033iRows\033n layouts icons in rows left to right,\n\ +starting a new row when the right\n\ +window border is reached. +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBTOOL (//) +Tool icons: +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBTOOL_SHORTHELP (//) +Select preferred icon layout direction\n\ +for \033btool icons\033n in desktop window.\n\ +\033iColumns\033n layouts icons in columns from top\n\ +to bottom, starting a new column when the\n\ +bottom of the window is reached.\n\ +\033iRows\033n layouts icons in rows left to right,\n\ +starting a new row when the right\n\ +window border is reached. +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBPROJECT (//) +Project icons: +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBPROJECT_SHORTHELP (//) +Select preferred icon layout direction\n\ +for \033bproject icons\033n in desktop window.\n\ +\033iColumns\033n layouts icons in columns from top\n\ +to bottom, starting a new column when the\n\ +bottom of the window is reached.\n\ +\033iRows\033n layouts icons in rows left to right,\n\ +starting a new row when the right\n\ +window border is reached. +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBGARBAGE (//) +Trashcan icons: +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBGARBAGE_SHORTHELP (//) +Select preferred icon layout direction\n\ +for \033btrashcan icons\033n in desktop window.\n\ +\033iColumns\033n layouts icons in columns from top\n\ +to bottom, starting a new column when the\n\ +bottom of the window is reached.\n\ +\033iRows\033n layouts icons in rows left to right,\n\ +starting a new row when the right\n\ +window border is reached. +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBDEVICE (//) +Device icons: +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBDEVICE_SHORTHELP (//) +Select preferred icon layout direction\n\ +for \033bdevice icons\033n in desktop window.\n\ +\033iColumns\033n layouts icons in columns from top\n\ +to bottom, starting a new column when the\n\ +bottom of the window is reached.\n\ +\033iRows\033n layouts icons in rows left to right,\n\ +starting a new row when the right\n\ +window border is reached. +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBKICK (//) +Kickstart Disk icons: +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBKICK_SHORTHELP (//) +Select preferred icon layout direction\n\ +for \033bkickstart disk icons\033n in desktop window.\n\ +\033iColumns\033n layouts icons in columns from top\n\ +to bottom, starting a new column when the\n\ +bottom of the window is reached.\n\ +\033iRows\033n layouts icons in rows left to right,\n\ +starting a new row when the right\n\ +window border is reached. +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBAPPICON (//) +Application icons: +; +; +MSGID_DESKTOPPAGE_LAYOUT_WBAPPICON_SHORTHELP (//) +Select preferred icon layout direction\n\ +for \033bapplication icons\033n in desktop window.\n\ +\033iColumns\033n layouts icons in columns from top\n\ +to bottom, starting a new column when the\n\ +bottom of the window is reached.\n\ +\033iRows\033n layouts icons in rows left to right,\n\ +starting a new row when the right\n\ +window border is reached. +; +;----------------------------------------------------------- +; +MSGID_ICONSPAGE_LAYOUTPREFERENCES (7100//) +Layout Preferences by Icon Type +; +; +MSGID_ICONSPAGE_LAYOUT_WBDRAWER (//) +Drawer icons: +; +; +MSGID_ICONSPAGE_LAYOUT_WBDRAWER_SHORTHELP (//) +Select preferred icon layout direction\n\ +for \033bdrawer icons\033n in icon windows.\n\ +\033iColumns\033n layouts icons in columns from top\n\ +to bottom, starting a new column when the\n\ +bottom of the window is reached.\n\ +\033iRows\033n layouts icons in rows left to right,\n\ +starting a new row when the right\n\ +window border is reached. +; +; +MSGID_ICONSPAGE_LAYOUT_WBTOOL (//) +Tool icons: +; +; +MSGID_ICONSPAGE_LAYOUT_WBTOOL_SHORTHELP (//) +Select preferred icon layout direction\n\ +for \033btool icons\033n in icon windows.\n\ +\033iColumns\033n layouts icons in columns from top\n\ +to bottom, starting a new column when the\n\ +bottom of the window is reached.\n\ +\033iRows\033n layouts icons in rows left to right,\n\ +starting a new row when the right\n\ +window border is reached. +; +; +MSGID_ICONSPAGE_LAYOUT_WBPROJECT (//) +Project icons: +; +; +MSGID_ICONSPAGE_LAYOUT_WBPROJECT_SHORTHELP (//) +Select preferred icon layout direction\n\ +for \033bproject icons\033n in icon windows.\n\ +\033iColumns\033n layouts icons in columns from top\n\ +to bottom, starting a new column when the\n\ +bottom of the window is reached.\n\ +\033iRows\033n layouts icons in rows left to right,\n\ +starting a new row when the right\n\ +window border is reached. +; +;----------------------------------------------------------- +; +MSGID_SCPGADGETTYPE_BACKBUTTON (7200//) +Back Button +; +; +MSGID_SCPGADGETTYPE_FORWARDBUTTON (//) +Forward Button +; +; +MSGID_SCPGADGETTYPE_UPBUTTON (//) +Up Button +; +; +MSGID_SCPGADGETTYPE_HISTORY (//) +History Button +; +; +MSGID_SCPGADGETTYPE_BROWSEBUTTON (//) +Browse Button +; +; +MSGID_SCPGADGETTYPE_VIEWBY (//) +View By Cycle +; +; +MSGID_SCPGADGETTYPE_SHOWMODE (//) +Show Mode Cycle +; +; +MSGID_SCPGADGETTYPE_SEPARATOR (//) +(Separator) +; +; +MSGID_SCPGADGETTYPE_ACTIONBUTTON (//) +User-defined Button +; +; +MSGID_SCPGADGETTYPE_UNKNOWN (//) +??unknown?? +; +;----------------------------------------------------------- +; +MSGID_COM1NAME (7300//) +Backdrop +; +; +MSGID_COM2NAME (//) +Execute Command +; +; +MSGID_COM3NAME (//) +Redraw All +; +; +MSGID_COM4NAME (//) +Update All +; +; +MSGID_COM5NAME (//) +About Scalos +; +; +MSGID_COM6NAME (//) +Quit +; +; +MSGID_COM7NAME (//) +New Drawer +; +; +MSGID_COM8NAME (//) +Open Parent +; +; +MSGID_COM9NAME (//) +Close Window +; +; +MSGID_COM10NAME (//) +Update +; +; +MSGID_COM11NAME (//) +Select Contents +; +; +MSGID_COM12NAME (//) +Cleanup +; +; +MSGID_COM13NAME (//) +Snapshot - Window +; +; +MSGID_COM14NAME (//) +Snapshot - All +; +; +MSGID_COM15NAME (//) +Show - Only Icons +; +; +MSGID_COM16NAME (//) +Show - All Files +; +; +MSGID_COM17NAME (//) +View By - Icon +; +; +MSGID_COM18NAME (//) +View By - Name +; +; +MSGID_COM19NAME (//) +Open +; +; +MSGID_COM20NAME (//) +Reset Scalos +; +; +MSGID_COM21NAME (//) +Rename +; +; +MSGID_COM22NAME (//) +Information +; +; +MSGID_COM23NAME (//) +Snapshot +; +; +MSGID_COM24NAME (//) +UnSnapshot +; +; +MSGID_COM25NAME (//) +Leave Out +; +; +MSGID_COM26NAME (//) +Put Away +; +; +MSGID_COM27NAME (//) +Delete +; +; +MSGID_COM28NAME (//) +Clone +; +; +MSGID_COM29NAME (//) +Empty Trashcan +; +; +MSGID_COM30NAME (//) +Last Message +; +; +MSGID_COM31NAME (//) +Redraw +; +; +MSGID_COM32NAME (//) +Iconify +; +MSGID_COM33NAME (//) +Format Disk... +; +; +MSGID_COM34NAME (//) +Shutdown... +; +; +MSGID_COM35NAME (//) +Size To Fit +; +; +MSGID_COM36NAME (//) +Clear Selection +; +; +MSGID_COM37NAME (//) +View By - Size +; +; +MSGID_COM38NAME (//) +View By - Date +; +; +MSGID_COM39NAME (//) +Copy file +; +; +MSGID_COM40NAME (//) +Cut file +; +; +MSGID_COM41NAME (//) +Paste file +; +; +MSGID_COM42NAME (//) +View By - Type +; +; +MSGID_COM43NAME (//) +Cleanup By - Name +; +; +MSGID_COM44NAME (//) +Cleanup By - Date +; +; +MSGID_COM45NAME (//) +Cleanup By - Size +; +; +MSGID_COM46NAME (//) +Cleanup By - Type +; +; +MSGID_COM_ICONPROPERTIES (//) +Icon properties +; +; +MSGID_COM_WINDOWPROPERTIES (//) +Window properties +; +; +MSGID_COM47NAME (//) +View By - Default +; +; +MSGID_COM48NAME (//) +Show - Default +; +; +MSGID_COM49NAME (//) +Copy to... +; +; +MSGID_COM50NAME (//) +Move to... +; +; +MSGID_COM51NAME (//) +Create thumbnail +; +; +MSGID_COM_OPENNEWWINDOW (//) +Open in new window +; +; +MSGID_COM_THUMBNAILCACHECLEANUP (//) +Cleanup thumbnail cache +; +;----------------------------------------------------------- +; diff --git a/scalos/Prefs/MainPrefs/Scalos_Prefs.info b/scalos/Prefs/MainPrefs/Scalos_Prefs.info new file mode 100755 index 0000000000000000000000000000000000000000..f573ec7dd7ff8b10bf01ecd0f8f75255b937f253 GIT binary patch literal 2401 zcwTK)4NwzT9)G(@V8I{{&CGTT&Gt*=z-qHh>lk3$$D?Wn`?XbcJ}{v z-~Z$H`~Ua--%dh+0d9nW<$ynbVE{{N3bld%H!xlwHzj>MxX*=V*AJBHg=s!UQbUJ- zA@I!83k@l{6QmlQ)nLj`e@UNZu&yGDEP8Us>!d|fte0^%aZ;UGud(V4I#a$S{iTh1 z3#ZOEWz1`Tl4Hoy>+=e%8}<2Cvq5i3M+Tf?u~buJH5Hik#RmN=^QJ;+{tw<`(7UA| zS7XU}#gLz6`tKq#%0`N!mks%r`NeoChhoxNOu2fi{(m?uvgQ=!Y4bIPTnorHnezZ3 z;yAY18l4`g!%|XE;&%*rnwJ6KRe55F{2eM^e_MIlc&d;Qd-nGXYs`Ve!+eQM>qr=S zk*RDe7muV0hvT5T+gRR67|k@3LRUs~RxDs7Qv$Q~kK`hMFv7R%y)LKi&9-TUueOSW zr_BEePbFw8=wvTSxs({zSc5+u<_Wm)=G^Gi~%rPr2BaD!jb0 z(cN#{vjD5|?DkC}{w-U?jcX9>J9kKkU`I-cn=zqE5z2K1k*$q9+5NSeCo?8q1#Q>r zFvXKxy!Nej*lT%po{gdbu}Ptmi7CV;g3wq$f67L*Mah(+(7x0t9%5q~KZn>Dw3`u| zk;)zpGHQ_xy8H90IX3&llwoDQp_GwS(Uv%f*f?!ZNEqmjgf$U(3|%VHsu4zxHgfz- zhMFfgCN7!N-5pr*b|d)Adh`Y>A_BmJ+E+O{c${lpQ)i@RF( zxp4n?Qq8ENg;6<{p1eJhQGyxw8Odo?g9917);5)xvZw3zfLnC(&c*L)&yvd??p*a3 z)hJs6cDU4z%nLYSfA?JZ@4%lwzPgiHpT8?&y?UAW4}+pE75#1rMpUoF#ec7zNg+=I zyz@vC3k0@P#o!5G>)9v7+TEwh>OTQx@35EH-{RmbV9VH3Y#ys*XIOxqR=r?{Nh~xT=p9%DH7*s<(27W9O)vtw50BZ3q7jFiT^rjOSta61x@7@3|s=W_V zyqh0OvCK$d8gw@XsfgJEyebyfLftGVp>@=uN2Z~OMuzg~L^LNn>u&=OIR}JE;!Gi5 z7k~e_XA$MoLS$hY!r>&W1}JuQ09PECEyYD4h1UUTB&r${7>Xh5W5w-&C}9Lg>9Q#Wy;)-RL|K&;|ccYfk>R{ zAd<|1)_kS!g!Gc3X>-qI+t_&jB-Gu=y5XSV^EPa z&&J&TYi*?49|%5Yx;Y5H@28h=ezCzq^HaaxZQ00g+k&66eNuf%=?k>3G@L7jo)4o% z?!@+3{=8DQ%U`A*Rr>s`D}UD3+zXv{Mfi0A2FK_anK`#hoQ+akaZy=Z)?48$jqy^C zFtwJ;qN%A_FR$+mpu!aSyKQ3=>ylv=5XM9inoKhuV5I{2Tu$WGZ~JIXUt zW}&gOSt2tRtw3ch>aExoALGpg@q~va4;XX(zqzQ)JuF#iII`n&ItkJqvhJ1uBRn4R zfbHjh70Xk7hb3D!9+`gLnH3)))XZXPuGlv7X$gah$rZc5)oG)M96M3vDuCW?I-4SYD$5Ljb!W6Z zN$--D4>{`8x8Wt~kaFq0flwdnu`&F{_YZ&=VKprfg~+;J0u4MDMxfvDSAfvXk|{Ly zW%$@`7lF(k0s@^!*FMqTnT}ue``7zfROO=sP# XgpFi}(YfSiaY2+lN^G;S0XE~`IksF} literal 0 HcwPel00001 diff --git a/scalos/Prefs/MainPrefs/SelectMarkSampleClass.c b/scalos/Prefs/MainPrefs/SelectMarkSampleClass.c new file mode 100644 index 000000000..ac2cf0ab0 --- /dev/null +++ b/scalos/Prefs/MainPrefs/SelectMarkSampleClass.c @@ -0,0 +1,450 @@ +// SelectMarkSampleClass.c +// $Date$ + + +#include +#include +#include +#include +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include +#include +#include +#define NO_INLINE_STDARG +#include +#include + +#include +#include + +#include +#include +#include "SelectMarkSampleClass.h" +#include "ScalosPrefs.h" + +// ------------------------------------------------------------------------- + +#define SUPERCLASS MUIC_Area + +#define MIN_WIDTH 50 +#define MIN_HEIGHT 20 + +struct SelectMarkSampleInstance +{ + WORD smsi_FgPen; + UWORD smsi_Radius; + UBYTE smsi_Transparency; + struct ARGB smsi_BaseColor; + CONST_STRPTR smsi_SampleText; + struct TextExtent smsi_TextExtent; + struct ARGBHeader smsi_Background; + struct ARGBHeader smsi_Foreground; +}; + +// ------------------------------------------------------------------------- + +static ULONG mNew(Class *cl, Object *o, struct opSet *ops); +static ULONG mDispose(Class *cl, Object *o,Msg msg); +static ULONG mSet(Class *cl, Object *o, struct opSet *ops); +static ULONG mGet(Class *cl, Object *o, struct opGet *opg); +static ULONG mAskMinMax(Class *cl, Object *o,struct MUIP_AskMinMax *msg); +static ULONG mDraw(Class *cl, Object *o,struct MUIP_Draw *msg); +DISPATCHER_PROTO(SelectMarkSampleClass); + +// ------------------------------------------------------------------------- + +static ULONG mNew(Class *cl, Object *o, struct opSet *ops) +{ + struct SelectMarkSampleInstance *inst = NULL; + BOOL Success = FALSE; + + do { + static const struct ARGB DefaultBaseColor = { (UBYTE) ~0, 133, 195, 221 }; + + o = (Object *) DoSuperMethodA(cl, o, (Msg) ops); + if (NULL == o) + break; + + inst = INST_DATA(cl,o); + + memset(inst, 0, sizeof(struct SelectMarkSampleInstance)); + + inst->smsi_FgPen = GetTagData(IA_FGPen, 1, ops->ops_AttrList); + inst->smsi_BaseColor = *(const struct ARGB *) GetTagData(TIHA_BaseColor, (ULONG) &DefaultBaseColor, ops->ops_AttrList); + inst->smsi_Radius = GetTagData(TIHA_Radius, 3, ops->ops_AttrList); + inst->smsi_Transparency = GetTagData(TIHA_Transparency, 128, ops->ops_AttrList); + inst->smsi_SampleText = (CONST_STRPTR) GetTagData(TIHA_DemoString, (ULONG) "", ops->ops_AttrList); + + Success = TRUE; + } while (0); + + if (!Success && o) + { + mDispose(cl, o, (Msg) ops); + o = NULL; + } + + return((ULONG)o); +} + +// ------------------------------------------------------------------------- + +static ULONG mDispose(Class *cl, Object *o, Msg msg) +{ + struct SelectMarkSampleInstance *inst = INST_DATA(cl,o); + + ScalosGfxFreeARGB(&inst->smsi_Background.argb_ImageData); + ScalosGfxFreeARGB(&inst->smsi_Foreground.argb_ImageData); + + return DoSuperMethodA(cl, o, msg); +} + +// ------------------------------------------------------------------------- + +static ULONG mSet(Class *cl, Object *o, struct opSet *ops) +{ + struct SelectMarkSampleInstance *inst = INST_DATA(cl,o); + struct ARGB oldBaseColor = inst->smsi_BaseColor; + UWORD oldRadius = inst->smsi_Radius; + UBYTE oldTransparency = inst->smsi_Transparency; + + inst->smsi_FgPen = GetTagData(IA_FGPen, inst->smsi_FgPen, ops->ops_AttrList); + inst->smsi_BaseColor = *(const struct ARGB *) GetTagData(TIHA_BaseColor, (ULONG) &inst->smsi_BaseColor, ops->ops_AttrList); + inst->smsi_Radius = GetTagData(TIHA_Radius, inst->smsi_Radius, ops->ops_AttrList); + inst->smsi_Transparency = GetTagData(TIHA_Transparency, inst->smsi_Transparency, ops->ops_AttrList); + inst->smsi_SampleText = (CONST_STRPTR) GetTagData(TIHA_DemoString, (ULONG) inst->smsi_SampleText, ops->ops_AttrList); + + if (inst->smsi_Radius != oldRadius || inst->smsi_Transparency != oldTransparency + || 0 != memcmp(&oldBaseColor, &inst->smsi_BaseColor, sizeof(struct ARGB)) ) + { + MUI_Redraw(o, MADF_DRAWUPDATE); + } + + return DoSuperMethodA(cl, o, (Msg) ops); +} + +// ------------------------------------------------------------------------- + +static ULONG mGet(Class *cl, Object *o, struct opGet *opg) +{ + struct SelectMarkSampleInstance *inst = INST_DATA(cl,o); + ULONG Result = 1; + + switch (opg->opg_AttrID) + { + case TIHA_BaseColor: + *((struct ARGB *) opg->opg_Storage) = inst->smsi_BaseColor; + break; + case TIHA_Radius: + *(opg->opg_Storage) = inst->smsi_FgPen; + break; + case IA_FGPen: + *(opg->opg_Storage) = inst->smsi_Radius; + break; + case TIHA_Transparency: + *(opg->opg_Storage) = inst->smsi_Transparency; + break; + case TIHA_DemoString: + *(opg->opg_Storage) = (ULONG) inst->smsi_SampleText; + break; + default: + Result = DoSuperMethodA(cl, o, (Msg) opg); + break; + } + + return Result; +} + +// ------------------------------------------------------------------------- + +static ULONG mAskMinMax(Class *cl, Object *o,struct MUIP_AskMinMax *msg) +{ + struct SelectMarkSampleInstance *inst = INST_DATA(cl,o); + struct MUI_MinMax *mi; + struct TextFont *tf; + + DoSuperMethodA(cl, o, (Msg) msg); + + mi = msg->MinMaxInfo; + + tf = _font(o); + d1(kprintf("%s/%s/%ld: tf=%08lx\n", __FILE__, __FUNC__, __LINE__, tf)); + if (tf) + { + struct RastPort rp; + + InitRastPort(&rp); + SetFont(&rp, tf); + + TextExtent(&rp, inst->smsi_SampleText, strlen(inst->smsi_SampleText), &inst->smsi_TextExtent); + + mi->MinHeight += (2 + inst->smsi_TextExtent.te_Height) * 3; + mi->DefHeight += (2 + inst->smsi_TextExtent.te_Height) * 3; + + mi->DefWidth += inst->smsi_TextExtent.te_Width + 4; + } + else + { + mi->MinHeight += MIN_HEIGHT; + mi->DefHeight += MIN_HEIGHT; + + mi->DefWidth += MIN_WIDTH; + } + + mi = msg->MinMaxInfo; + + mi->MaxWidth = MUI_MAXMAX; + mi->MaxHeight = MUI_MAXMAX; + + d1(KPrintF("%s/%s/%ld: MinW=%ld MaxW=%ld MinH=%ld MaxH=%ld DefW=%ld DefH=%ld\n", \ + __FILE__, __FUNC__, __LINE__, mi->MinWidth, mi->MaxWidth, mi->MinHeight, mi->MaxHeight, mi->DefWidth, mi->DefHeight)); + + return 0; +} + +// ------------------------------------------------------------------------- + +static ULONG mDraw(Class *cl, Object *o,struct MUIP_Draw *msg) +{ + struct SelectMarkSampleInstance *inst = INST_DATA(cl,o); + + d1(kprintf("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__)); + + DoSuperMethodA(cl, o, (Msg) msg); + + d1(kprintf("%s/%s/%ld: flags=%08lx\n", __FILE__, __FUNC__, __LINE__, msg->flags)); + d1(KPrintF("%s/%s/%ld: o=%08lx Left=%ld Top=%ld\n", __FILE__, __FUNC__, __LINE__, o, _mleft(o), _mtop(o))); + d1(KPrintF("%s/%s/%ld: Width=%ld Height=%ld\n", __FILE__, __FUNC__, __LINE__, _mwidth(o), _mheight(o))); + + do { + WORD TextLeft = (_mwidth(o) - inst->smsi_TextExtent.te_Width) / 2; + WORD TextRight = TextLeft + inst->smsi_TextExtent.te_Width + 4; + WORD TextTop = (_mheight(o) - inst->smsi_TextExtent.te_Height) / 2; + WORD TextBottom = TextTop + inst->smsi_TextExtent.te_Height + 4; + struct ARGB Border, Top, Bottom; + + if (msg->flags & MADF_DRAWOBJECT) + { + ScalosGfxFreeARGB(&inst->smsi_Background.argb_ImageData); + + inst->smsi_Background.argb_Width = _mwidth(o); + inst->smsi_Background.argb_Height = _mheight(o); + + inst->smsi_Background.argb_ImageData = ScalosGfxCreateARGB(_mwidth(o), _mheight(o), NULL); + if (NULL == inst->smsi_Background.argb_ImageData) + break; + + SetFont(_rp(o), _font(o)); + SetDrMd(_rp(o), JAM1); + + Move(_rp(o), + _mleft(o) + TextLeft + 2, + _mtop(o) + TextTop + _font(o)->tf_Baseline + 2 ); + Text(_rp(o), inst->smsi_SampleText, strlen(inst->smsi_SampleText)); + + Move(_rp(o), + _mleft(o) + TextLeft + 2, + _mtop(o) + TextTop + _font(o)->tf_Baseline + 2 - (inst->smsi_TextExtent.te_Height + 2) ); + Text(_rp(o), inst->smsi_SampleText, strlen(inst->smsi_SampleText)); + + Move(_rp(o), + _mleft(o) + TextLeft + 2, + _mtop(o) + TextTop + _font(o)->tf_Baseline + 2 + (inst->smsi_TextExtent.te_Height + 2) ); + Text(_rp(o), inst->smsi_SampleText, strlen(inst->smsi_SampleText)); + + // Read background into inst->smsi_Background + ReadPixelArray(inst->smsi_Background.argb_ImageData, + 0, 0, + _mwidth(o) * sizeof(struct ARGB), + _rp(o), + _mleft(o), _mtop(o), + _mwidth(o), _mheight(o), + RECTFMT_ARGB); + } + + if (_mwidth(o) != inst->smsi_Foreground.argb_Width || _mheight(o) != inst->smsi_Foreground.argb_Height) + { + inst->smsi_Foreground.argb_Width = _mwidth(o); + inst->smsi_Foreground.argb_Height = _mheight(o); + ScalosGfxFreeARGB(&inst->smsi_Foreground.argb_ImageData); + } + + if (NULL == inst->smsi_Foreground.argb_ImageData) + inst->smsi_Foreground.argb_ImageData = ScalosGfxCreateARGB(_mwidth(o), _mheight(o), NULL); + if (NULL == inst->smsi_Foreground.argb_ImageData) + break; + + // Read background into inst->smsi_Foreground + ScalosGfxBlitARGB(&inst->smsi_Foreground, + &inst->smsi_Background, + 0, 0, + 0, 0, + inst->smsi_Foreground.argb_Width, inst->smsi_Foreground.argb_Height); + + Border = inst->smsi_BaseColor; + + // 1-----2 TextTop + // / \ . + // 8 3 . + // | | . + // 7 4 . + // \ / . + // 6---5 TextBottom + + ScalosGfxDrawLine(&inst->smsi_Foreground, + TextLeft + inst->smsi_Radius, TextTop, // 1 -> 2 + TextRight - inst->smsi_Radius,TextTop, + &Border); + ScalosGfxDrawLine(&inst->smsi_Foreground, + TextRight - inst->smsi_Radius,TextTop, // 2 -> 3 + TextRight, TextTop + inst->smsi_Radius, + &Border); + ScalosGfxDrawLine(&inst->smsi_Foreground, + TextRight, TextTop + inst->smsi_Radius, // 3 -> 4 + TextRight, TextBottom - inst->smsi_Radius, + &Border); + ScalosGfxDrawLine(&inst->smsi_Foreground, + TextRight, TextBottom - inst->smsi_Radius, // 4 -> 5 + TextRight - inst->smsi_Radius,TextBottom, + &Border); + ScalosGfxDrawLine(&inst->smsi_Foreground, + TextRight - inst->smsi_Radius,TextBottom, // 5 -> 6 + TextLeft + inst->smsi_Radius, TextBottom, + &Border); + ScalosGfxDrawLine(&inst->smsi_Foreground, + TextLeft + inst->smsi_Radius, TextBottom, // 6 -> 7 + TextLeft, TextBottom - inst->smsi_Radius, + &Border); + ScalosGfxDrawLine(&inst->smsi_Foreground, + TextLeft, TextBottom - inst->smsi_Radius, // 7 -> 8 + TextLeft, TextTop + inst->smsi_Radius, + &Border); + ScalosGfxDrawLine(&inst->smsi_Foreground, + TextLeft, TextTop + inst->smsi_Radius, // 8 -> 1 + TextLeft + inst->smsi_Radius, TextTop, + &Border); + + Top.Red = (inst->smsi_BaseColor.Red * 79) / 100; + Top.Green = (inst->smsi_BaseColor.Green * 79) / 100; + Top.Blue = (inst->smsi_BaseColor.Blue * 79) / 100; + Top.Alpha = inst->smsi_Transparency; + + Bottom.Red = (inst->smsi_BaseColor.Red * 41) / 100; + Bottom.Green = (inst->smsi_BaseColor.Green * 41) / 100; + Bottom.Blue = (inst->smsi_BaseColor.Blue * 41) / 100; + Bottom.Alpha = inst->smsi_Transparency; + + if (msg->flags & MADF_DRAWUPDATE) + { + // Restore drawing area background + ScalosGfxBlitARGBAlpha(_rp(o), &inst->smsi_Background, + _mleft(o) + TextLeft, _mtop(o) + TextTop, + TextLeft, TextTop, + 1 + TextRight - TextLeft, + 1 + TextBottom - TextTop); + } + if (!ScalosGfxDrawGradient(&inst->smsi_Foreground, + TextLeft + 2, + TextTop + 2, + (1+ TextRight - TextLeft) - 4, + (1 + TextBottom - TextTop) - 4, + &Top, &Bottom, + SCALOS_GRADIENT_VERTICAL)) + { + break; + } + + ScalosGfxBlitARGBAlpha(_rp(o), &inst->smsi_Foreground, + _mleft(o) + TextLeft, _mtop(o) + TextTop, + TextLeft, TextTop, + 1 + TextRight - TextLeft, + 1 + TextBottom - TextTop); + + SetFont(_rp(o), _font(o)); + SetDrMd(_rp(o), JAM1); + + Move(_rp(o), + _mleft(o) + TextLeft + 2, + _mtop(o) + TextTop + _font(o)->tf_Baseline + 2 ); + Text(_rp(o), inst->smsi_SampleText, strlen(inst->smsi_SampleText)); + + d1(KPrintF("%s/%s/%ld: iobj_TextPenBgSel=%ld\n", __FILE__, __FUNC__, __LINE__, inst->iobj_TextPenBgSel)); + } while (0); + + d1(kprintf("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); + return 0; +} + +// ------------------------------------------------------------------------- + +DISPATCHER(SelectMarkSampleClass) +{ + ULONG Result; + + switch (msg->MethodID) + { + case OM_NEW: + d1(kprintf("%s/%s/%ld: OM_NEW\n", __FILE__, __FUNC__, __LINE__)); + Result = mNew(cl, obj, (struct opSet *) msg); + break; + + case OM_DISPOSE: + d1(kprintf("%s/%s/%ld: OM_DISPOSE\n", __FILE__, __FUNC__, __LINE__)); + Result = mDispose(cl, obj, msg); + break; + + case OM_SET: + d1(kprintf("%s/%s/%ld: OM_SET\n", __FILE__, __FUNC__, __LINE__)); + Result = mSet(cl, obj, (struct opSet *) msg); + break; + + case OM_GET: + d1(kprintf("%s/%s/%ld: OM_GET\n", __FILE__, __FUNC__, __LINE__)); + Result = mGet(cl, obj, (struct opGet *) msg); + break; + + case MUIM_AskMinMax: + d1(kprintf("%s/%s/%ld: MUIM_AskMinMax\n", __FILE__, __FUNC__, __LINE__)); + Result = mAskMinMax(cl, obj, (struct MUIP_AskMinMax *) msg); + break; + + case MUIM_Draw: + d1(kprintf("%s/%s/%ld: MUIM_Draw\n", __FILE__, __FUNC__, __LINE__)); + Result = mDraw(cl, obj, (struct MUIP_Draw *) msg); + break; + + default: + d1(KPrintF("%s/%s/%ld: MethodID=%08lx\n", __FILE__, __FUNC__, __LINE__, msg->MethodID)); + Result = DoSuperMethodA(cl, obj, msg); + break; + } + + return Result; +} +DISPATCHER_END + +// ------------------------------------------------------------------------- + +struct MUI_CustomClass *InitSelectMarkSampleClass(void) +{ + return MUI_CreateCustomClass(NULL, + SUPERCLASS, + NULL, + sizeof(struct SelectMarkSampleInstance), + DISPATCHER_REF(SelectMarkSampleClass)); +} + +void CleanupSelectMarkSampleClass(struct MUI_CustomClass *mcc) +{ + MUI_DeleteCustomClass(mcc); +} + +// ------------------------------------------------------------------------- + diff --git a/scalos/Prefs/MainPrefs/SelectMarkSampleClass.h b/scalos/Prefs/MainPrefs/SelectMarkSampleClass.h new file mode 100644 index 000000000..601d955a5 --- /dev/null +++ b/scalos/Prefs/MainPrefs/SelectMarkSampleClass.h @@ -0,0 +1,33 @@ +// SelectMarkSampleClass.h +// $Date$ +// $Revision$ + + +#ifndef SELECTMARK_SAMPLECLASS_H +#define SELECTMARK_SAMPLECLASS_H + +//---------------------------------------------------------------------------- + +#include + +//---------------------------------------------------------------------------- + +struct MUI_CustomClass *InitSelectMarkSampleClass(void); +void CleanupSelectMarkSampleClass(struct MUI_CustomClass *mcc); + +//---------------------------------------------------------------------------- + +extern struct MUI_CustomClass *SelectMarkSampleClass; + +//---------------------------------------------------------------------------- + +#define TIH_TagBase (TAG_USER + 0x91c70) + +#define TIHA_BaseColor (TIH_TagBase + 1) // [ISG] (const struct ARGB *) Base color for ARGB highlight +#define TIHA_Radius (TIH_TagBase + 2) // [ISG] (ULONG) Radius of highlight corners +#define TIHA_Transparency (TIH_TagBase + 3) // [ISG] (ULONG) Transparency for selection marker +#define TIHA_DemoString (TIH_TagBase + 4) // [ISG] (CONST_STRPTR) sample string + +//---------------------------------------------------------------------------- + +#endif /* SELECTMARK_SAMPLECLASS_H */ diff --git a/scalos/Prefs/MainPrefs/UrlSubject.h b/scalos/Prefs/MainPrefs/UrlSubject.h new file mode 100644 index 000000000..604163967 --- /dev/null +++ b/scalos/Prefs/MainPrefs/UrlSubject.h @@ -0,0 +1,9 @@ +// UrlSubject.h +// $Date$ + +#ifndef URLSUBJECT_H +#define URLSUBJECT_H + +#define URLSUBJECT_SCAVERSION "mailto:info@scalos.noname.fr?subject=%s" + +#endif /* URLSUBJECT_H */ diff --git a/scalos/Prefs/MainPrefs/config.mk b/scalos/Prefs/MainPrefs/config.mk new file mode 100755 index 000000000..e1086cd93 --- /dev/null +++ b/scalos/Prefs/MainPrefs/config.mk @@ -0,0 +1,68 @@ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +FONTSAMPLE_DIR = $(TOPLEVEL)/common/FontSampleMCC +DATATYPESMCC_DIR = $(TOPLEVEL)/common/DataTypesMCC +MCPGFX_DIR = $(TOPLEVEL)/common/McpGfx + +INCLUDES += -I$(FONTSAMPLE_DIR)/ \ + -I$(MCPGFX_DIR)/ \ + -I$(DATATYPESMCC_DIR)/ \ + +SCALOS_LOCALE = $(OBJDIR)/ScalosPrefs_locale.h + +CFLAGS += -D SCALOSLOCALE=$(SCALOS_LOCALE) + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + + +LFLAGS += # + +CFLAGS += -D USE_HYPERLINK_MCC=1 + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += # + + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +DEFINES += -DMUI_OBSOLETE +LFLAGS += -lmui + +else + +############################################################################### +# AmigaOS + +# remove "-msmall-code" +OPTIMIZE = -O3 -fomit-frame-pointer + +LFLAGS += -lstack \ + -lnix \ + -lnixmain \ + -lamiga21 \ + -lamiga \ + -lstubs + +endif +endif +endif diff --git a/scalos/Prefs/MainPrefs/locale.h b/scalos/Prefs/MainPrefs/locale.h new file mode 100755 index 000000000..69742716d --- /dev/null +++ b/scalos/Prefs/MainPrefs/locale.h @@ -0,0 +1,22 @@ +// locale.h +// $Date$ +// $Revision$ + +#ifndef LOCALE_H +#define LOCALE_H + +struct Scalos_Prefs_LocaleInfo +{ + APTR li_LocaleBase; + APTR li_Catalog; + struct LocaleIFace *li_ILocale; +}; + +CONST_STRPTR GetLocString(LONG lStrnum); + +#define Scalos_Prefs_NUMBERS +#include STR(SCALOSLOCALE) + + +#endif + diff --git a/scalos/Prefs/MainPrefs/makefile-new b/scalos/Prefs/MainPrefs/makefile-new new file mode 100755 index 000000000..9290d70d4 --- /dev/null +++ b/scalos/Prefs/MainPrefs/makefile-new @@ -0,0 +1,116 @@ +# $Date: 2011-08-08 18:52:39 +0200 (Mo, 08. Aug 2011) $ +# $Revision: 826 $ + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../.. +endif + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + SDPATH=/ +else + SDPATH=../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(OBJDIR)/Hooks.o \ + $(OBJDIR)/ReadWritePrefs.o \ + $(OBJDIR)/HiddenDevices.o \ + $(OBJDIR)/DataTypesMCC.o \ + $(OBJDIR)/FontSampleMCC.o \ + $(OBJDIR)/Images.o \ + $(OBJDIR)/McpFrameMCC.o \ + $(OBJDIR)/PrefsPlugins.o \ + $(OBJDIR)/Scalos.o \ + $(OBJDIR)/PrefsVersion.o \ + $(OBJDIR)/ScalosMcpGfx.o \ + $(OBJDIR)/SelectMarkSampleClass.o \ + + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Subdirs +# + +SUBDIRS = $(filter-out Catalogs/sample/Scalos, $(wildcard Catalogs/*/Scalos)) + +############################################################################## +# +# Targets +# + +NAME = Scalos_Prefs +NAME_DB = $(NAME).debug + +############################################################################## +# +# Some lame deps + +$(OBJDIR)/%.o: $(FONTSAMPLE_DIR)/%.c + @$(run-cc) + +$(OBJDIR)/%.o: $(DATATYPESMCC_DIR)/%.c + @$(run-cc) + +$(OBJDIR)/%.o: $(MCPGFX_DIR)/%.c + @$(run-cc) + +$(OBJDIR)/Hooks.o $(OBJDIR)/Hooks.d $(OBJDIR)/Scalos.o $(OBJDIR)/Scalos.d : $(OBJDIR)/ScalosPrefs_locale.h + +$(OBJDIR)/ScalosPrefs_locale.h : Scalos_Prefs.cd + @$(ECHO) "FlexCat $@" + $(FLEXCAT) $< $@=$(SDPATH)/CatComp_h.sd + +$(OBJDIR)/PrefsVersion.o : FORCE + +FORCE: + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + all_subdirs + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + @$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) "Scalos:Prefs/Scalos Prefs" clone + +install: install_subdirs + + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.i \ + $(OBJDIR)/*.d.* $(OBJDIR)/*.s \ + @$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* \ + $(OBJDIR)/ScalosPrefs_locale.h + +clean: clean_subdirs + diff --git a/scalos/Prefs/Menu/Catalogs/dansk/Scalos/ScalosMenu.ct b/scalos/Prefs/Menu/Catalogs/dansk/Scalos/ScalosMenu.ct new file mode 100644 index 000000000..8068df86f --- /dev/null +++ b/scalos/Prefs/Menu/Catalogs/dansk/Scalos/ScalosMenu.ct @@ -0,0 +1,1934 @@ +; ScalosMenu.ct +## version $VER: ScalosMenu.catalog 40.18 (24 Aug 2008 10:21:32) +## codeset 0 +## language dansk +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Menu Prefs Plugin +; +; +MSGID_TITLENAME_CMDLIST +Scalos Internal Menu Commands +; +; +MSGID_FRAMETITLE +Menu liste +; +; +MSGID_NEWINAME +Ny punkt +; +; +MSGID_HOTKEYNAME +Taste: +; +; +MSGID_NEWNAME +Nyt menu +; +; +MSGID_DELNAME +Slet +; +; +MSGID_SAVENAME +Gem +; +; +MSGID_USENAME +Brug +; +; +MSGID_CANCELNAME +Afbryd +; +; +MSGID_NEW2NAME +Ny kommando +; +; +MSGID_COMMANDNAME +Kommando +; +; +MSGID_MENU_PROJECT_IMPORT +Importér +; +; +MSGID_MENU_PROJECT_IMPORT_SHORT +I +; +; +MSGID_MENU_PROJECT_OPEN +Åbn... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +O +; +; +MSGID_MENU_PROJECT_SAVEAS +Gem som... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +A +; +; +MSGID_MENU_PROJECT_QUIT +Afslut +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +; +MSGID_MENU_PROJECT +Projekt +; +; +MSGID_MENU_EDIT_LASTSAVED +Sidst gemt +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +L +; +; +MSGID_MENU_EDIT +Editér +; +; +MSGID_MENU_SETTINGS_CREATEICONS +Opret ikoner? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +I +; +; +MSGID_MENU_SETTINGS +Indstillinger +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +Standardindstillinger +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +D +; +; +MSGID_MENU_EDIT_RESTORE +Restaurer +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +R +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Om MUI... +; +; +MSGID_WBNAME +Workbench +; +; +MSGID_ADOSNAME +AmigaDOS +; +; +MSGID_STACKNAME +Stak +; +; +MSGID_MAINMENUNAME +Hovedmenu +; +; +MSGID_COM1NAME +Baggrund +; +; +MSGID_COM2NAME +Udfør kommando +; +; +MSGID_COM3NAME +Gentegn alt +; +; +MSGID_COM4NAME +Opdater alt +; +; +MSGID_COM5NAME +Om Scalos +; +; +MSGID_COM6NAME +Afslut +; +; +MSGID_COM7NAME +Ny folder +; +; +MSGID_COM8NAME +Åbn forælder +; +; +MSGID_COM9NAME +Luk vindue +; +; +MSGID_COM10NAME +Opdatér +; +; +MSGID_COM11NAME +Vælg indhold +; +; +MSGID_COM12NAME +Gør rent +; +; +MSGID_COM13NAME +Fiksér vindue +; +; +MSGID_COM14NAME +Fikser alt +; +; +MSGID_COM15NAME +Vis kun ikoner +; +; +MSGID_COM16NAME +Vis alle filer +; +; +MSGID_COM17NAME +Vis som ikon +; +; +MSGID_COM18NAME +Vis navn +; +; +MSGID_COM19NAME +Åbn +; +; +MSGID_COM20NAME +Genstart Scalos +; +; +MSGID_COM21NAME +Omdøb +; +; +MSGID_COM22NAME +Information +; +; +MSGID_COM23NAME +Fiksér +; +; +MSGID_COM24NAME +Glem fiksering +; +; +MSGID_COM25NAME +Tag ud +; +; +MSGID_COM26NAME +Læg tilbage +; +; +MSGID_COM27NAME +Slet +; +; +MSGID_BARNAME +\033C +; +MSGID_UPNAME +Op +; +; +MSGID_DOWNNAME +Ned +; +; +MSGID_MENU_PROJECT_IMPORT_TD +ToolsDaemon... +; +; +MSGID_MENU_PROJECT_IMPORT_TD_SHORT +T +; +; +MSGID_MENU_PROJECT_IMPORT_P +Parm... +; +; +MSGID_MENU_PROJECT_IMPORT_P_SHORT +P +; +; +MSGID_COM28NAME +Kopiér +; +; +MSGID_ICONWINNAME +Ikon vindue +; +; +MSGID_AREXXNAME +Arexx +; +;+++translateme+++ +MSGID_MENU_EDIT_COPY +Copy +;Copy +; +;+++translateme+++ +MSGID_MENU_EDIT_CUT +Cut +;Cut +; +;+++translateme+++ +MSGID_MENU_EDIT_PASTE +Paste +;Paste +; +;+++translateme+++ +MSGID_MENU_EDIT_COLLAPSE +Collapse Selected +;Collapse Selected +; +;+++translateme+++ +MSGID_MENU_EDIT_EXPAND +Expand Selected +;Expand Selected +; +;--------------------------------------------- +; +MSGID_POPMENUNAME1 +Popup Menu: Disk ikoner +; +; +MSGID_POPMENUNAME2 +Popup Menu: Folder ikoner +; +; +MSGID_POPMENUNAME3 +Popup Menu: Værktøjs/projekt ikoner +; +; +MSGID_POPMENUNAME4 +Popup Menu: skrældespand ikoner +; +; +MSGID_POPMENUNAME5 +Popup Menu: vinduer +; +; +MSGID_ARGSNAME +WB argumenter: +; +; +MSGID_COM29NAME +Tøm skrældespand +; +; +MSGID_COM30NAME +Sidste meddelelse +; +; +MSGID_COM31NAME +Gentegn +; +; +MSGID_COM32NAME +Ikonificér +; +; +MSGID_PLUGINNAME +PlugIn +; +; +MSGID_MENU_PROJECT_MERGE +Tilføj... +; +; +MSGID_MENU_PROJECT_MERGE_SHORT +M +; +; +MSGID_MENU_EDIT_COLLAPSEALL +Collapse All +; +; +MSGID_MENU_EDIT_EXPANDALL +Expand All +; +;+++translateme+++ +MSGID_MENU_SETTINGS_HIDEOBSOLETE +Hide Obsolete? +;Hide Obsolete? +; +;+++translateme+++ +MSGID_MENU_SETTINGS_HIDEOBSOLETE_SHORT +If checked, obsolete popup menus which are now\n\ +defined via filetypes prefs are not shown. +;If checked, obsolete popup menus which are now\n\ +;defined via filetypes prefs are not shown. +; +; +MSGID_COM33NAME +Format Disk... +; +; +MSGID_COM34NAME +Shutdown... +; +; +MSGID_COM35NAME +Size To Fit +; +; +MSGID_COM36NAME +Clear Selection +; +; +MSGID_POPMENUNAME6 +Popup Menu: AppIcons +; +;+++translateme+++ +MSGID_POPMENUNAME7 +Popup Menu: Desktop +;Popup Menu: Desktop +; +; +MSGID_COM37NAME +View By - Size +; +; +MSGID_COM38NAME +View By - Date +; +; +MSGID_MENU_PROJECT_ABOUT +About... +; +; +MSGID_ABOUTREQOK +_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Menu Preferences V%ld.%ld\033n\n\ +%s\n\ +© 1999%s The Scalos Team\n +; +; +;*** +jl+ 20011214 +MSGID_COM39NAME +Copy file +; +; +MSGID_COM40NAME +Cut file +; +; +MSGID_COM41NAME +Paste file +; +; +MSGID_COM42NAME +View By - Type +; +; +MSGID_COM43NAME +Cleanup By - Name +; +; +MSGID_COM44NAME +Cleanup By - Date +; +; +MSGID_COM45NAME +Cleanup By - Size +; +; +MSGID_COM46NAME +Cleanup By - Type +; +;+++translateme+++ +MSGID_COM_ICONPROPERTIES +Icon properties +;Icon properties +; +;+++translateme+++ +MSGID_COM_WINDOWPROPERTIES +Window properties +;Window properties +; +;+++translateme+++ +MSGID_COM47NAME +View By - Default +; +;+++translateme+++ +MSGID_COM48NAME +Show - Default +; +;+++translateme+++ +MSGID_COM49NAME +Copy to... +;Copy to... +; +;+++translateme+++ +MSGID_COM50NAME +Move to... +;Move to... +; +;+++translateme+++ +MSGID_COM51NAME +Create thumbnail +; +;+++translateme+++ +MSGID_COM_OPENNEWWINDOW +Open in new window +;Open in new window +; +;+++translateme+++ +MSGID_COM_THUMBNAILCACHECLEANUP +Cleanup thumbnail cache +; +;+++translateme+++ +MSGID_COM_FIND +Find File(s) +;Find File(s) +; +;+++translateme+++ +MSGID_COM_UNDO +Undo +;Undo +; +;+++translateme+++ +MSGID_COM_REDO +Redo +;Redo +; +;+++translateme+++ +MSGID_COM_OPENBROWSERWINDOW +Open in Browser Window +;Open in Browser Window +; +;--------------------------------------------- +; +MSGID_SHORTHELP_NEWMENUBUTTON +Press this button to create a new Menu or\n\ +Submenu entry at the currently selected position. +; +; +MSGID_SHORTHELP_NEWITEMBUTTON +Press this button to insert a new menu\n\ +item at the currently selected position. +; +; +MSGID_SHORTHELP_NEWCOMMANDBUTTON +Press this button to add a new\n\ +command to the currently menu item. +; +; +MSGID_SHORTHELP_DELBUTTON +Press this button to delete the currently\n\ +select command, menu item, or menu. +; +; +MSGID_SHORTHELP_SAVEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENVARC:Scalos/menu13.prefs\". +; +; +MSGID_SHORTHELP_USEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENV:Scalos/menu13.prefs\". +; +; +MSGID_SHORTHELP_CANCELBUTTON +Press this button to abort \n\ +and forget all changes. +; +; +MSGID_REQTITLE_SAVEERROR +Error writing palette preferences\n\ +file \"%s\"\n\ +%s +; +; +MSGID_REQTITLE_READERROR +Error reading palette preferences\n\ +file \"%s\"\n\ +%s +; +; +MSGID_IMPORTNAME +Import +; +; +MSGID_TITLE_IMPORTTD +Import ToolsDaemon Prefs +; +; +MSGID_TITLE_IMPORTP +Import ParM Prefs +; +; +MSGID_PRIORITY_SLIDER_NAME +Priority +; +; +MSGID_PRIORITY_SLIDER_BUBBLE +Use this slider to adjust the priority the command should run with. +; +; new in 40.7 +; +MSGID_PLUGIN_LIST_TITLE +Menu +; +; +MSGID_POPUP_ASLTITLE_AMIGADOS +Select AmigaDOS command +; +; +MSGID_POPUP_ASLTITLE_WORKBENCH +Select Workbench command +; +; +MSGID_POPUP_ASLTITLE_ICONWINDOW +Select directory for icon window +; +; +MSGID_POPUP_ASLTITLE_AREXX +Select ARexx program +; +; +MSGID_POPUP_ASLTITLE_MENUPLUGIN +Select Scalos Menu plugin +; +; +MSGID_MENU_PROJECT_MERGE_ASLTITLE +Select prefs to merge with +; +; +MSGID_MENU_GROUP_COMMAND_PROPERTIES +Command Properties +; +; new in 40.10 +; +; +++translateme+++ +MSGID_SHORTHELP_LAMP_CHANGED +This lamp indicator changes from \033bOff\033n\n\ +to \033bOk\033n when the settings have been\n\ +modified since initial loading. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +; new in 40.16 +; +; +++translateme+++ +MSGID_POPASL_UNSELECTEDIMAGE_SHORTHELP +Here you may select an iconic image that is shown left of\n\ +the menu item name, in unselected menu item state. +;Here you may select an iconic image that is shown left of\n\ +;the menu item name, in unselected menu item state. +; +; +++translateme+++ +MSGID_SAMPLE_UNSELECTEDIMAGE_SHORTHELP +This is a sample of the iconic image that will be shown\n\ +left of the menu item name, in unselected menu item state. +;This is a sample of the iconic image that will be shown\n\ +;left of the menu item name, in unselected menu item state. +; +; +++translateme+++ +MSGID_POPASL_SELECTEDIMAGE_SHORTHELP +Here you may select an iconic image that is shown left of\n\ +the menu item name, in selected menu item state. +;Here you may select an iconic image that is shown left of\n\ +;the menu item name, in selected menu item state. +; +; +; +++translateme+++ +MSGID_SAMPLE_SELECTEDIMAGE_SHORTHELP +This is a sample of the iconic image that will be shown\n\ +left of the menu item name, in selected menu item state. +;This is a sample of the iconic image that will be shown\n\ +;left of the menu item name, in selected menu item state. +; +;+++translateme+++ +MSGID_ENTRY_STRING_NAME +Name: +;Name: +; +;+++translateme+++ +MSGID_ENTRY_GROUP_UNSELECTEDIMAGE +Unselected State Image +;Unselected State Image +; +;+++translateme+++ +MSGID_ENTRY_GROUP_SELECTEDIMAGE +Selected State Image +;Selected State Image +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Scalos Menu Prefs startup failed +;Scalos Menu Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Try again|Quit +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_NEW_MENU +New Menu +;New Menu +; +;+++translateme+++ +MSGID_NEW_ITEM +New Item +;New Item +; +;+++translateme+++ +MSGID_TOOLS_MENU +Tools +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_DEFAULT_MENU_OPEN +Open +;Open +; +;+++translateme+++ +MSGID_DEFAULT_MENU_OPEN_SHORT +O +;O +; +;+++translateme+++ +MSGID_DEFAULT_MENU_INFORMATION +Information... +;Information... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_INFORMATION_SHORT +I +;I +; +;+++translateme+++ +MSGID_DEFAULT_MENU_BROWSE +Browse... +;Browse... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_BROWSE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_FIND +Find... +;Find... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_FIND_SHORT +F +;F +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT +Snapshot +;Snapshot +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT_SHORT +S +;S +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UNSNAPSHOT +Unsnapshot +;Unsnapshot +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UNSNAPSHOT_SHORT +U +;U +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLONE +Clone +;Clone +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLONE_SHORT +C +;C +; +;+++translateme+++ +MSGID_DEFAULT_MENU_COPY +Copy +;Copy +; +;+++translateme+++ +MSGID_DEFAULT_MENU_COPY_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CUT +Cut +;Cut +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CUT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PASTE +Paste +;Paste +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PASTE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DISKCOPY +Diskcopy... +;Diskcopy... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DISKCOPY_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RELABEL +Relabel... +;Relabel... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RELABEL_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_FORMAT +Format... +;Format... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_FORMAT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PROPERTIES +Properties... +;Properties... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PROPERTIES_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EDIT +Edit +;Edit +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RENAME +Rename +;Rename +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RENAME_SHORT +R +;R +; +;+++translateme+++ +MSGID_DEFAULT_MENU_LEAVEOUT +Leave Out +;Leave Out +; +;+++translateme+++ +MSGID_DEFAULT_MENU_LEAVEOUT_SHORT +L +;L +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PUTAWAY +Put Away +;Put Away +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PUTAWAY_SHORT +P +;P +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DELETE +Delete... +;Delete... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DELETE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EMPTYTRASH +Empty Trashcan... +;Empty Trashcan... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EMPTYTRASH_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLOSE +Close +;Close +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLOSE_SHORT +K +; +;+++translateme+++ +MSGID_DEFAULT_MENU_OPENPARENT +Open Parent +;Open Parent +; +;+++translateme+++ +MSGID_DEFAULT_MENU_OPENPARENT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UPDATE +Update +;Update +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UPDATE_SHORT +M +;M +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUP +Cleanup +;Cleanup +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUP_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RESIZETOFIT +Resize To Fit +;Resize To Fit +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RESIZETOFIT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SELECTCONTENTS +Select Contents +;Select Contents +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SELECTCONTENTS_SHORT +A +;A +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEARSELECTION +Clear Selection +;Clear Selection +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEARSELECTION_SHORT +Z +;Z +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT_ALL +All +;All +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT_ALL_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT_WINDOW +Window +;Window +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT_WINDOW_SHORT +W +;W +; +;+++translateme+++ +MSGID_DEFAULT_MENU_NEWDRAWER +New Drawer... +;New Drawer... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_NEWDRAWER_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SCALOS +Scalos +;Scalos +; +;+++translateme+++ +MSGID_DEFAULT_MENU_WINDOW +Window +;Window +; +;+++translateme+++ +MSGID_DEFAULT_MENU_ICONS +Icons +;Icons +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS +Drawers +;Drawers +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS +Prefs +;Prefs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_BACKDROP +Backdrop? +;Backdrop? +; +;+++translateme+++ +MSGID_DEFAULT_MENU_BACKDROP_SHORT +B +;B +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EXECUTECOMMAND +Execute Command... +;Execute Command... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EXECUTECOMMAND_SHORT +E +;E +; +;+++translateme+++ +MSGID_DEFAULT_MENU_REDRAWALL +Redraw All +;Redraw All +; +;+++translateme+++ +MSGID_DEFAULT_MENU_REDRAWALL_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UPDATEALL +Update All +;Update All +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UPDATEALL_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_LASTMESSAGE +Last Message +;Last Message +; +;+++translateme+++ +MSGID_DEFAULT_MENU_LASTMESSAGE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_ABOUT +About... +;About... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_ABOUT_SHORT +? +;? +; +;+++translateme+++ +MSGID_DEFAULT_MENU_QUIT +Quit... +;Quit... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_QUIT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY +Clean up by +;Clean up by +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_COLUMN +Column +;Column +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_COLUMN_SHORT +. +;. +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_NAME +Name +;Name +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_NAME_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_DATE +Date +;Date +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_DATE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_SIZE +Size +;Size +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_SIZE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_TYPE +Type +;Type +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_TYPE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW +Show +;Show +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_DEFAULT +Default +;Default +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_DEFAULT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_ONLYICONS +Only Icons +;Only Icons +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_ONLYICONS_SHOT +- +;- +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_ALLFILES +All Files +;All Files +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_ALLFILES_SHORT ++ +;+ +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY +View By +;View By +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_DEFAULT +Default +;Default +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_DEFAULT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_ICON +Icon +;Icon +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_ICON_SHORT +1 +;1 +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_NAME +Name +;Name +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_NAME_SHORT +2 +;2 +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_DATE +Date +;Date +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_DATE_SHORT +3 +;3 +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_SIZE +Size +;Size +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_SIZE_SHORT +4 +;4 +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_TYPE +Type +;Type +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_TYPE_SHORT +5 +;5 +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RESETSCALOS +Reset Scalos +;Reset Scalos +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RESETSCALOS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_NEWSHELL +New Shell +;New Shell +; +;+++translateme+++ +MSGID_DEFAULT_MENU_NEWSHELL_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_VOYAGER +Voyager +;Voyager +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_VOYAGER_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_ENVARC_SYS +ENVARC:Sys +;ENVARC:Sys +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_ENVARC_SYS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_WBSTARTUP +WBStartup +;WBStartup +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_WBSTARTUP_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_PREFS +Prefs +;Prefs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_PREFS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_SCALOSPREFS +Scalos Prefs +;Scalos Prefs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_SCALOSPREFS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SYSTEM +System... +;System... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_MUI +MUI... +;MUI... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_MUI_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_AHI +AHI... +;AHI... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_AHI_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCALOS +Scalos Prefs... +;Scalos Prefs... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCALOS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EMPTY_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_TOOLS +Tools +;Tools +; +;+++translateme+++ +MSGID_DEFAULT_UTILITIES +Utilities +;Utilities +; +;+++translateme+++ +MSGID_DEFAULT_PREFERENCES +Preferences +;Preferences +; +;+++translateme+++ +MSGID_DEFAULT_EXCHANGE +Exchange +;Exchange +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_MOUNTER +Mounter +;Mounter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SCSICONFIG +SCSIConfig +;SCSIConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SNOOPIUM +Snoopium +;Snoopium +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_DEFRAG +Defrag +;Defrag +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_FTMANAGER +FTManager +;FTManager +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_MUISHELL +MUIShell +;MUIShell +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SFSDOCTOR +SFSDoctor +;SFSDoctor +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_UNITCONTROL +UnitControl +;UnitControl +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_FILEIMAGECTRL +FileImageCtrl +;FileImageCtrl +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_HDCONFIG +HDConfig +;HDConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_REGTOOL +RegTool +;RegTool +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SHELL +Shell +;Shell +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_EDITOR +Editor +;Editor +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_FRAGMENT +Fragment +;Fragment +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_GRABBER +Grabber +;Grabber +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_GRAPHICBOARDS +GraphicBoards +;GraphicBoards +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_KEYSTROKE +Keystroke +;Keystroke +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MINICALC +MiniCalc +;MiniCalc +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MORE +More +;More +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MUIPROCALC +MUIProCalc +;MUIProCalc +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MULTIVIEW +Multiview +;Multiview +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MYSTICVIEW +MysticView +;MysticView +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_TASKMANAGER +TaskManager +;TaskManager +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_TRANCESTATS +Trancestats +;Trancestats +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_TIPS +Tips +;Tips +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_ZOOM +Zoom +;Zoom +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_AMIGS +AmiGS +;AmiGS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_AMIPDF +AmiPDF +;AmiPDF +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_SGRAB +SGrab +;SGrab +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_CALCULATOR +Calculator +;Calculator +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_CLOCK +Clock +;Clock +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_GRAPHICDUMP +GraphicDump +;GraphicDump +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_ICONEDIT +IconEdit +;IconEdit +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_INITPRINTER +InitPrinter +;InitPrinter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_KEYSHOW +KeyShow +;KeyShow +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MEMACS +MEmacs +;MEmacs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_NOTEPAD +Notepad +;Notepad +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PARTITIONWIZARD +Partition Wizard +;Partition Wizard +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PLAYCD +PlayCD +;PlayCD +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PREFSOBJECTSEDITOR +PrefsObjectsEditor +;PrefsObjectsEditor +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PRINTFILES +PrintFiles +;PrintFiles +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_RAWDISK +RawDisk +;RawDisk +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_SHOWCONFIG +ShowConfig +;ShowConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_UNARC +UnArc +;UnArc +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_USBINSPECTOR +USBInspector +;USBInspector +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_AMIGAINPUT +AmigaInput +;AmigaInput +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_ASL +ASL +;ASL +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_COMPATIBILITY +Compatibility +;Compatibility +; +; +MSGID_DEFAULT_MENU_PREFS_DEFICONS +DefIcons +;DefIcons +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_DOS +DOS +;DOS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_FONT +Font +;Font +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_GUI +GUI +;GUI +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_INPUT +Input +;Input +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_INTERNET +Internet +;Internet +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_LOCALE +Locale +;Locale +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_NOTIFICATIONS +Notifications +;Notifications +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PALETTE +Palette +;Palette +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PICASSO96MODE +Picasso96Mode +;Picasso96Mode +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_POINTER +Pointer +;Pointer +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_POPUPMENU +PopupMenu +;PopupMenu +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PRINTER +Printer +;Printer +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PRINTERGFX +PrinterGFX +;PrinterGFX +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PRINTERPS +PrinterPS +;PrinterPS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCREENBLANKER +ScreenBlanker +;ScreenBlanker +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCREENMODE +ScreenMode +;ScreenMode +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCREENS +Screens +;Screens +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SERIAL +Serial +;Serial +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SOUND +Sound +;Sound +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_TIME +Time +;Time +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_URL +URL +;URL +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_USB +USB +;USB +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WBPATTERN +WBPattern +;WBPattern +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WBSTARTUP +WBStartup +;WBStartup +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WORKBENCH +Workbench +;Workbench +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_INTELLIFONT +IntelliFont +;IntelliFont +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_GRAPHICDUMP +GraphicDump +;GraphicDump +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_WBCLOCK +WBClock +;WBClock +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_CACHECDFS +CacheCDFS +;CacheCDFS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_ICONTROL +IControl +;IControl +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_OVERSCAN +Overscan +;Overscan +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_REACTION +Reaction +;Reaction +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_VINCED +ViNCDe +;ViNCDe +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WARPOS +WarpOS +;WarpOS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_BENCHTRASH +BenchTrash +;BenchTrash +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_CALCULATOR +Calculator +;Calculator +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_EDITPAD +EditPad +;EditPad +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_HDTOOLBOX +HDToolBox +;HDToolBox +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_ICONEDIT +IconEdit +;IconEdit +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_INITPRINTER +InitPrinter +;InitPrinter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_IOTOOLS +IoTools +;IoTools +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_KEYSHOW +KeyShow +;KeyShow +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_LACER +Lacer +;Lacer +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_MEMACS +MEmacs +;MEmacs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_PREPCARD +PrepCard +;PrepCard +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_PRINTFILES +PrintFiles +;PrintFiles +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SHOWCONFIG +ShowConfig +;ShowConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_UNARC +Unarc +;Unarc +; +;+++translateme+++ +MSGID_DEFAULT_SYSTEM +System +;System +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_FIND +Find... +;Find... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_FIXFONT +FixFont +;FixFont +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_FORMAT +Format... +;Format... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_SHELL +Shell +;Shell +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_FORMATCDRW +FormatCDRW +;FormatCDRW +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_MEDIATOOLBOX +MediaToolBox +;MediaToolBox +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_MOUNTER +Mounter +;Mounter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_TYPEMANAGER +TypeManager +;TypeManager +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_HELP +Help +;Help +; +;----------------------------------------------------------- +; diff --git a/scalos/Prefs/Menu/Catalogs/dansk/Scalos/config.mk b/scalos/Prefs/Menu/Catalogs/dansk/Scalos/config.mk new file mode 100755 index 000000000..bb98f9e35 --- /dev/null +++ b/scalos/Prefs/Menu/Catalogs/dansk/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = dansk + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = danish + +else + +############################################################################### +# AmigaOS and AROS + +LANG = dansk + +endif +endif diff --git a/scalos/Prefs/Menu/Catalogs/dansk/Scalos/makefile b/scalos/Prefs/Menu/Catalogs/dansk/Scalos/makefile new file mode 100644 index 000000000..03a6ab726 --- /dev/null +++ b/scalos/Prefs/Menu/Catalogs/dansk/Scalos/makefile @@ -0,0 +1,13 @@ +# makefile for Scalos (translated Texts : dansk) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mdansk\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +ScalosMenu.catalog : ScalosMenu.ct ../../../ScalosMenu.cd + +All: ScalosMenu.catalog diff --git a/scalos/Prefs/Menu/Catalogs/dansk/Scalos/makefile-new b/scalos/Prefs/Menu/Catalogs/dansk/Scalos/makefile-new new file mode 100755 index 000000000..712548da1 --- /dev/null +++ b/scalos/Prefs/Menu/Catalogs/dansk/Scalos/makefile-new @@ -0,0 +1,32 @@ +# makefile for ScalosMenu (translated Texts : dansk) +# $Date: 2011-08-06 19:37:48 +0200 (Sa, 06. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = ScalosMenu + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Prefs/Menu/Catalogs/deutsch/Scalos/ScalosMenu.ct b/scalos/Prefs/Menu/Catalogs/deutsch/Scalos/ScalosMenu.ct new file mode 100644 index 000000000..c1bca375f --- /dev/null +++ b/scalos/Prefs/Menu/Catalogs/deutsch/Scalos/ScalosMenu.ct @@ -0,0 +1,1975 @@ +; ScalosMenu.ct +## version $VER: ScalosMenu.catalog 40.18 (24 Aug 2008 10:22:42) +## codeset 0 +## language deutsch +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Menü Prefs Plugin +; +; +MSGID_TITLENAME_CMDLIST +Eingebaute Scalos Menü-Befehle +;Scalos Internal Menu Commands +; +; +MSGID_FRAMETITLE +Menüliste +; +; +MSGID_NEWINAME +Neuer Menüeintrag +; +; +MSGID_HOTKEYNAME +Taste: +; +; +MSGID_NEWNAME +Neues Menü +; +; +MSGID_DELNAME +Löschen +; +; +MSGID_SAVENAME +Speichern +; +; +MSGID_USENAME +Benutzen +; +; +MSGID_CANCELNAME +Abbrechen +; +; +MSGID_NEW2NAME +Neues Kommando +; +; +MSGID_COMMANDNAME +Kommando +; +; +MSGID_MENU_PROJECT_IMPORT +Importieren +; +; +MSGID_MENU_PROJECT_IMPORT_SHORT +I +; +; +MSGID_MENU_PROJECT_OPEN +Öffnen... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +O +; +; +MSGID_MENU_PROJECT_SAVEAS +Speichern als... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +A +; +; +MSGID_MENU_PROJECT_QUIT +Beenden +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +; +MSGID_MENU_PROJECT +Projekt +; +; +MSGID_MENU_EDIT_LASTSAVED +auf zuletzt gespeichertes +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +L +; +; +MSGID_MENU_EDIT +Verändern +; +; +MSGID_MENU_SETTINGS_CREATEICONS +Piktogramme erzeugen? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +I +; +; +MSGID_MENU_SETTINGS +Einstellungen +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +auf Vorgaben zurücksetzen +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +D +; +; +MSGID_MENU_EDIT_RESTORE +auf vorherigen Stand +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +R +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Über MUI... +; +; +MSGID_WBNAME +Workbench +; +; +MSGID_ADOSNAME +AmigaDOS +; +; +MSGID_STACKNAME +Stapel: +; +; +MSGID_MAINMENUNAME +Hauptmenü +; +; +MSGID_COM1NAME +Als Hintergrund +; +; +MSGID_COM2NAME +Programm ausführen +; +; +MSGID_COM3NAME +Alles neuzeichnen +; +; +MSGID_COM4NAME +Alles neu laden +; +; +MSGID_COM5NAME +Über Scalos +; +; +MSGID_COM6NAME +Beenden +; +; +MSGID_COM7NAME +Neue Schublade +; +; +MSGID_COM8NAME +Mutterverzeichnis öffnen +; +; +MSGID_COM9NAME +Fenster schließen +; +; +MSGID_COM10NAME +Neuladen +; +; +MSGID_COM11NAME +Inhalt anwählen +; +; +MSGID_COM12NAME +Inhalt aufräumen +; +; +MSGID_COM13NAME +Fenster fixieren +; +; +MSGID_COM14NAME +Alles fixieren +; +; +MSGID_COM15NAME +Nur Piktogramme anzeigen +; +; +MSGID_COM16NAME +Alle Dateien anzeigen +; +; +MSGID_COM17NAME +Als Piktogramm anzeigen +; +; +MSGID_COM18NAME +Mit Namen anzeigen +; +; +MSGID_COM19NAME +Öffnen +; +; +MSGID_COM20NAME +Scalos neustarten +; +; +MSGID_COM21NAME +Umbenennen +; +; +MSGID_COM22NAME +Information +; +; +MSGID_COM23NAME +Fixieren +; +; +MSGID_COM24NAME +Fixierung aufheben +; +; +MSGID_COM25NAME +Auslagern +; +; +MSGID_COM26NAME +Zurücklegen +; +; +MSGID_COM27NAME +Löschen +; +; +MSGID_BARNAME +\033C +; +; +MSGID_UPNAME +Hoch +; +; +MSGID_DOWNNAME +Runter +; +; +MSGID_MENU_PROJECT_IMPORT_TD +ToolsDaemon... +; +; +MSGID_MENU_PROJECT_IMPORT_TD_SHORT +T +; +; +MSGID_MENU_PROJECT_IMPORT_P +Parm... +; +; +MSGID_MENU_PROJECT_IMPORT_P_SHORT +P +; +; +MSGID_COM28NAME +Duplizieren +; +; +MSGID_ICONWINNAME +Piktogrammfenster +; +; +MSGID_AREXXNAME +Arexx +; +; +MSGID_MENU_EDIT_COPY +Kopieren +;Copy +; +; +MSGID_MENU_EDIT_CUT +Ausschneiden +;Cut +; +; +MSGID_MENU_EDIT_PASTE +Einfügen +;Paste +; +; +MSGID_MENU_EDIT_COLLAPSE +Auswahl zuklappen +;Collapse Selected +; +; +MSGID_MENU_EDIT_EXPAND +Auswahl aufklappen +;Expand Selected +; +;--------------------------------------------- +; +MSGID_POPMENUNAME1 +Popup-Menü: Disk Piktogramme +; +; +MSGID_POPMENUNAME2 +Popup-Menü: Schubladen Piktogramme +; +; +MSGID_POPMENUNAME3 +Popup-Menü: Werkzeug/Projekt Piktogramme +; +; +MSGID_POPMENUNAME4 +Popup-Menü: Papierkorb Piktogramme +; +; +MSGID_POPMENUNAME5 +Popup-Menü: Fenster +; +; +MSGID_ARGSNAME +WB Args: +; +; +MSGID_COM29NAME +Papierkorb leeren +; +; +MSGID_COM30NAME +Letzte Meldung +; +; +MSGID_COM31NAME +Neuzeichnen +; +; +MSGID_COM32NAME +Iconifizieren +; +; +MSGID_PLUGINNAME +PlugIn +; +; +MSGID_MENU_PROJECT_MERGE +Anhängen... +; +; +MSGID_MENU_PROJECT_MERGE_SHORT +M +; +; +MSGID_MENU_EDIT_COLLAPSEALL +Alles zuklappen +;Collapse All +; +; +MSGID_MENU_EDIT_EXPANDALL +Alles aufklappen +;Expand All +; +; +MSGID_MENU_SETTINGS_HIDEOBSOLETE +Alte Einträge weglassen? +;Hide Obsolete? +; +; +MSGID_MENU_SETTINGS_HIDEOBSOLETE_SHORT +Dieser Menüeintrag unterdrückt alle veralteten\n\ +Popupmenüs, die mittlerweile über die Scalos\n\ +Dateitypen festgelegt werden. +;If checked, obsolete popup menus which are now\n\ +;defined via filetypes prefs are not shown. +; +; +MSGID_COM33NAME +Disk formatieren... +; +; +MSGID_COM34NAME +Herunterfahren... +; +; +MSGID_COM35NAME +Größe anpassen +; +; +MSGID_COM36NAME +Auswahl löschen +;Clear Selection +; +; +MSGID_POPMENUNAME6 +Popup-Menü: Anwendungspiktogramme +;Popup Menu: AppIcons +; +; +MSGID_POPMENUNAME7 +Popup-Menü: Arbeitsfläche +;Popup Menu: Desktop +; +; +MSGID_COM37NAME +Inhalt auflisten nach Größe +; +; +MSGID_COM38NAME +Inhalt auflisten nach Datum +; +; +MSGID_MENU_PROJECT_ABOUT +Über... +; +; +MSGID_ABOUTREQOK +_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Menu Voreinsteller V%ld.%ld\033n\n\ +%s\n\ +© 1999%s Das Scalos Team\n +; +; +;*** +jl+ 20011214 +MSGID_COM39NAME +Datei kopieren +; +; +MSGID_COM40NAME +Datei ausschneiden +; +; +MSGID_COM41NAME +Datei einfügen +; +; +MSGID_COM42NAME +Inhalt auflisten nach Art +; +; +MSGID_COM43NAME +Inhalt aufräumen nach Namen +; +; +MSGID_COM44NAME +Inhalt aufräumen nach Datum +; +; +MSGID_COM45NAME +Inhalt aufräumen nach Größe +; +; +MSGID_COM46NAME +Inhalt aufräumen nach Art +; +; +MSGID_COM_ICONPROPERTIES +Piktogramm-Eigenschaften +;Icon properties +; +; +MSGID_COM_WINDOWPROPERTIES +Fenster-Eigenschaften +;Window properties +; +; +MSGID_COM47NAME +Inhalt auflisten nach Standard +;View By - Default +; +; +MSGID_COM48NAME +Anzeigen nach Standard +;Show - Default +; +; +MSGID_COM49NAME +Kopieren nach... +;Copy to... +; +; +MSGID_COM50NAME +Verschieben nach... +;Move to... +; +; +MSGID_COM51NAME +Vorschaubild erzeugen +;Create thumbnail +; +; +MSGID_COM_OPENNEWWINDOW +In neuem Fenster öffnen +;Open in new window +; +; +MSGID_COM_THUMBNAILCACHECLEANUP +Vorschaubilder-Zwischenspeicher aufräumen +;Cleanup thumbnail cache +; +; +MSGID_COM_FIND +Datei(en) suchen +;Find File(s) +; +; +MSGID_COM_UNDO +Rückgängig +;Undo +; +; +MSGID_COM_REDO +Wiederholen +;Redo +; +; +MSGID_COM_OPENBROWSERWINDOW +Öffnen in Browserfenster +;Open in Browser Window +; +;--------------------------------------------- +; +MSGID_SHORTHELP_NEWMENUBUTTON +Mit diesem Knopf erzeugen Sie ein neues Menü\n\ +oder Untermenü an der aktuell markierten Stelle. +;Press this button to create a new Menu or\n\ +;Submenu entry at the currently selected position. +; +; +MSGID_SHORTHELP_NEWITEMBUTTON +Mit diesem Knopf erzeugen Sie einen neuen\n\ +Menüeintrag an der aktuell markierten Stelle. +;Press this button to insert a new menu\n\ +;item at the currently selected position. +; +; +MSGID_SHORTHELP_NEWCOMMANDBUTTON +Mit diesem Knopd erzeugen Sie ein neues\n\ +Kommando für den aktuell markierten Menüeintrag. +;Press this button to add a new\n\ +;command to the currently menu item. +; +; +MSGID_SHORTHELP_DELBUTTON +Mit diesem Kopf löschen Sie das aktuell\n\ +markierte Menü, den Menüeintrag oder das Kommando. +;Press this button to delete the currently\n\ +;select command, menu item, or menu. +; +; +MSGID_SHORTHELP_SAVEBUTTON +Drücken Sie diesen Knopf, um alle\n\ +Einstellungen dauerhaft in\n\ +\"ENVARC:Scalos/menu13.prefs\"\n\ +zu speichern. +;Press this button to save \n\ +;the current settings to\n\ +;\"ENVARC:Scalos/menu13.prefs\". +; +; +MSGID_SHORTHELP_USEBUTTON +Drücken Sie diesen Knopf, um alle Einstellungen\n\ +bis zum nächsten Neustart in\n\ +\"ENV:Scalos/menu13.prefs\"\n\ +zu speichern. +;Press this button to save \n\ +;the current settings to\n\ +;\"ENV:Scalos/menu13.prefs\". +; +; +MSGID_SHORTHELP_CANCELBUTTON +Drücken Sie diesen Knopf, um das\n\ +Programm abzubrechen und alle\n\ +Änderungen zu verwerfen. +;Press this button to abort \n\ +;and forget all changes. +; +; +MSGID_REQTITLE_SAVEERROR +Fehler beim Schreiben der Einstellungs-\n\ +Datei \"%s\"\n\ +%s +;Error writing palette preferences\n\ +;file \"%s\"\n\ +;%s +; +; +MSGID_REQTITLE_READERROR +Fehler beim Lesen der Einstellungs-\n\ +Datei \"%s\"\n\ +%s +;Error reading palette preferences\n\ +;file \"%s\"\n\ +;%s +; +; +MSGID_IMPORTNAME +Importieren +;Import +; +; +MSGID_TITLE_IMPORTTD +ToolsDaemon Einstellungen importieren +;Import ToolsDaemon Prefs +; +; +MSGID_TITLE_IMPORTP +ParM Einstellungen importieren +;Import ParM Prefs +; +; +MSGID_PRIORITY_SLIDER_NAME +Priorität: +; +; +MSGID_PRIORITY_SLIDER_BUBBLE +Mit diesem Schieber stellen Sie die\n\ +Laufzeit-Priorität für das Kommando ein. +; +; new in 40.7 +; +MSGID_PLUGIN_LIST_TITLE +Menüs +;Menu +; +; +MSGID_POPUP_ASLTITLE_AMIGADOS +AmigaDOS-Befehl auswählen +; +; +MSGID_POPUP_ASLTITLE_WORKBENCH +Workbench-Befehl auswählen +; +; +MSGID_POPUP_ASLTITLE_ICONWINDOW +Verzeichnis für Piktogrammfenster äuswählen +; +; +MSGID_POPUP_ASLTITLE_AREXX +ARexx-Programm auswählen +; +; +MSGID_POPUP_ASLTITLE_MENUPLUGIN +Scalos Menu-Plugin auswählen +; +; +MSGID_MENU_PROJECT_MERGE_ASLTITLE +Einstellungen zum Anhängen auswählen +;Select prefs to merge with +; +; +MSGID_MENU_GROUP_COMMAND_PROPERTIES +Eigenschaften des Befehls +;Command Properties +; +; new in 40.10 +; +MSGID_SHORTHELP_LAMP_CHANGED +Diese Anzeigelampe wechselt den Zustand von \033bAus\033n\n\ +nach \033bAn\033n wenn die Konfiguration seit\n\ +dem ersten Laden verändert wurde. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +; new in 40.16 +; +; +MSGID_POPASL_UNSELECTEDIMAGE_SHORTHELP +Hier kann man ein kleines Bild auswählen, das links neben\n\ +dem Menünamen im nicht ausgewählten Zustand angezeigt wird. +;Here you may select an iconic image that is shown left of\n\ +;the menu item name, in unselected menu item state. +; +; +MSGID_SAMPLE_UNSELECTEDIMAGE_SHORTHELP +Dies ist eine Vorschau des kleinen Bildes, das links neben\n\ +dem Menünamen im nicht ausgewählten Zustand angezeigt wird. +;This is a sample of the iconic image that will be shown\n\ +;left of the menu item name, in unselected menu item state. +; +; +MSGID_POPASL_SELECTEDIMAGE_SHORTHELP +Hier kann man ein kleines Bild auswählen, das links neben\n\ +dem Menünamen im ausgewählten Zustand angezeigt wird. +;Here you may select an iconic image that is shown left of\n\ +;the menu item name, in selected menu item state. +; +; +; +MSGID_SAMPLE_SELECTEDIMAGE_SHORTHELP +Dies ist eine Vorschau des kleinen Bildes, das links\n\ +neben dem Menünamen im ausgewählten Zustand angezeigt wird. +;This is a sample of the iconic image that will be shown\n\ +;left of the menu item name, in selected menu item state. +; +; +MSGID_ENTRY_STRING_NAME +Name: +;Name: +; +; +MSGID_ENTRY_GROUP_UNSELECTEDIMAGE +Bild für Menüpunkt +;Unselected State Image +; +; +MSGID_ENTRY_GROUP_SELECTEDIMAGE +Bild für ausgewählten Menüpunkt +;Selected State Image +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Scalos Menü Voreinsteller kann nicht gestartet werden +;Scalos Menu Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Wiederholen|Beenden +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\ +Die Klasse ist nicht installiert. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Sie haben momentan Version v%lu.%lu installiert und\n\ +sollten die Klasse daher aktualisieren! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Version %lu.%lu wird momentan von einer anderen Anwendung\n\ +verwendet. Wenn sie die benötigte Version installiert haben,\n\ +schließen sie alle MUI Programme und probieren es erneut. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_NEW_MENU +Neues Menü +;New Menu +; +; +MSGID_NEW_ITEM +Neuer Menüeintrag +;New Item +; +; +MSGID_TOOLS_MENU +Hilfsmittel +;Tools +; +;----------------------------------------------------------- +; +MSGID_DEFAULT_MENU_OPEN +Öffnen +;Open +; +; +MSGID_DEFAULT_MENU_OPEN_SHORT +O +;O +; +; +MSGID_DEFAULT_MENU_INFORMATION +Informationen anzeigen... +;Information... +; +; +MSGID_DEFAULT_MENU_INFORMATION_SHORT +I +;I +; +; +MSGID_DEFAULT_MENU_BROWSE +Durchsuchen... +;Browse... +; +; +MSGID_DEFAULT_MENU_BROWSE_SHORT + +; +; +MSGID_DEFAULT_MENU_FIND +Suchen... +;Find... +; +; +MSGID_DEFAULT_MENU_FIND_SHORT +F +;F +; +; +MSGID_DEFAULT_MENU_SNAPSHOT +Fixieren +;Snapshot +; +; +MSGID_DEFAULT_MENU_SNAPSHOT_SHORT +S +;S +; +; +MSGID_DEFAULT_MENU_UNSNAPSHOT +Position freigeben +;Unsnapshot +; +; +MSGID_DEFAULT_MENU_UNSNAPSHOT_SHORT +U +;U +; +; +MSGID_DEFAULT_MENU_CLONE +Kopieren +;Clone +; +; +MSGID_DEFAULT_MENU_CLONE_SHORT +C +;C +; +; +MSGID_DEFAULT_MENU_COPY +Kopieren in Zwischenablage +;Copy +; +; +MSGID_DEFAULT_MENU_COPY_SHORT + +; +; +MSGID_DEFAULT_MENU_CUT +Ausschneiden +;Cut +; +; +MSGID_DEFAULT_MENU_CUT_SHORT + +; +; +MSGID_DEFAULT_MENU_PASTE +Einfügen aus Zwischenablage +;Paste +; +; +MSGID_DEFAULT_MENU_PASTE_SHORT + +; +; +MSGID_DEFAULT_MENU_DISKCOPY +Disk kopieren... +;Diskcopy... +; +; +MSGID_DEFAULT_MENU_DISKCOPY_SHORT + +; +; +MSGID_DEFAULT_MENU_RELABEL +Umbenennen... +;Relabel... +; +; +MSGID_DEFAULT_MENU_RELABEL_SHORT + +; +; +MSGID_DEFAULT_MENU_FORMAT +Disk formatieren... +;Format... +; +; +MSGID_DEFAULT_MENU_FORMAT_SHORT + +; +; +MSGID_DEFAULT_MENU_PROPERTIES +Eigenschaften... +;Properties... +; +; +MSGID_DEFAULT_MENU_PROPERTIES_SHORT + +; +; +MSGID_DEFAULT_MENU_EDIT +Bearbeiten +;Edit +; +; +MSGID_DEFAULT_MENU_RENAME +Umbenennen... +;Rename +; +; +MSGID_DEFAULT_MENU_RENAME_SHORT +R +;R +; +; +MSGID_DEFAULT_MENU_LEAVEOUT +Auslagern +;Leave Out +; +; +MSGID_DEFAULT_MENU_LEAVEOUT_SHORT +L +;L +; +; +MSGID_DEFAULT_MENU_PUTAWAY +Zurücklegen +;Put Away +; +; +MSGID_DEFAULT_MENU_PUTAWAY_SHORT +P +;P +; +; +MSGID_DEFAULT_MENU_DELETE +Löschen... +;Delete... +; +; +MSGID_DEFAULT_MENU_DELETE_SHORT + +; +; +MSGID_DEFAULT_MENU_EMPTYTRASH +Papierkorb leeren... +;Empty Trashcan... +; +; +MSGID_DEFAULT_MENU_EMPTYTRASH_SHORT + +; +; +MSGID_DEFAULT_MENU_CLOSE +Schließen +;Close +; +; +MSGID_DEFAULT_MENU_CLOSE_SHORT +K +; +; +MSGID_DEFAULT_MENU_OPENPARENT +Übergeordnete Schublade öffnen +;Open Parent +; +; +MSGID_DEFAULT_MENU_OPENPARENT_SHORT + +; +; +MSGID_DEFAULT_MENU_UPDATE +Aktualisieren +;Update +; +; +MSGID_DEFAULT_MENU_UPDATE_SHORT +M +;M +; +; +MSGID_DEFAULT_MENU_CLEANUP +Inhalt aufräumen +;Cleanup +; +; +MSGID_DEFAULT_MENU_CLEANUP_SHORT + +; +; +MSGID_DEFAULT_MENU_RESIZETOFIT +Größe anpassen +;Resize To Fit +; +; +MSGID_DEFAULT_MENU_RESIZETOFIT_SHORT + +; +; +MSGID_DEFAULT_MENU_SELECTCONTENTS +Alles auswählen +;Select Contents +; +; +MSGID_DEFAULT_MENU_SELECTCONTENTS_SHORT +A +;A +; +; +MSGID_DEFAULT_MENU_CLEARSELECTION +Markierungen löschen +;Clear Selection +; +; +MSGID_DEFAULT_MENU_CLEARSELECTION_SHORT +Z +;Z +; +; +MSGID_DEFAULT_MENU_SNAPSHOT_ALL +alles +;All +; +; +MSGID_DEFAULT_MENU_SNAPSHOT_ALL_SHORT + +; +; +MSGID_DEFAULT_MENU_SNAPSHOT_WINDOW +des Fensters +;Window +; +; +MSGID_DEFAULT_MENU_SNAPSHOT_WINDOW_SHORT +W +;W +; +; +MSGID_DEFAULT_MENU_NEWDRAWER +Neue Schublade anlegen... +;New Drawer... +; +; +MSGID_DEFAULT_MENU_NEWDRAWER_SHORT + +; +; +MSGID_DEFAULT_MENU_SCALOS +Scalos +;Scalos +; +; +MSGID_DEFAULT_MENU_WINDOW +Fenster +;Window +; +; +MSGID_DEFAULT_MENU_ICONS +Piktogramm +;Icons +; +; +MSGID_DEFAULT_MENU_DRAWERS +Schubladen +;Drawers +; +; +MSGID_DEFAULT_MENU_PREFS +Voreinsteller +;Prefs +; +; +MSGID_DEFAULT_MENU_BACKDROP +Scalos als Hintergrund? +;Backdrop? +; +; +MSGID_DEFAULT_MENU_BACKDROP_SHORT +B +;B +; +; +MSGID_DEFAULT_MENU_EXECUTECOMMAND +Befehl ausführen... +;Execute Command... +; +; +MSGID_DEFAULT_MENU_EXECUTECOMMAND_SHORT +E +;E +; +; +MSGID_DEFAULT_MENU_REDRAWALL +Bild neu aufbauen +;Redraw All +; +; +MSGID_DEFAULT_MENU_REDRAWALL_SHORT + +; +; +MSGID_DEFAULT_MENU_UPDATEALL +Alles aktualisieren +;Update All +; +; +MSGID_DEFAULT_MENU_UPDATEALL_SHORT + +; +; +MSGID_DEFAULT_MENU_LASTMESSAGE +Letzte Meldung anzeigen +;Last Message +; +; +MSGID_DEFAULT_MENU_LASTMESSAGE_SHORT + +; +; +MSGID_DEFAULT_MENU_ABOUT +Version, Copyright... +;About... +; +; +MSGID_DEFAULT_MENU_ABOUT_SHORT +? +;? +; +; +MSGID_DEFAULT_MENU_QUIT +Scalos verlassen... +;Quit... +; +; +MSGID_DEFAULT_MENU_QUIT_SHORT + +; +; +MSGID_DEFAULT_MENU_CLEANUPBY +Inhalt aufräumen +;Clean up by +; +; +MSGID_DEFAULT_MENU_CLEANUPBY_COLUMN +nach Spalten +;Column +; +; +MSGID_DEFAULT_MENU_CLEANUPBY_COLUMN_SHORT +. +;. +; +; +MSGID_DEFAULT_MENU_CLEANUPBY_NAME +nach Namen +;Name +; +; +MSGID_DEFAULT_MENU_CLEANUPBY_NAME_SHORT + +; +; +MSGID_DEFAULT_MENU_CLEANUPBY_DATE +nach Datum +;Date +; +; +MSGID_DEFAULT_MENU_CLEANUPBY_DATE_SHORT + +; +; +MSGID_DEFAULT_MENU_CLEANUPBY_SIZE +nach Größe +;Size +; +; +MSGID_DEFAULT_MENU_CLEANUPBY_SIZE_SHORT + +; +; +MSGID_DEFAULT_MENU_CLEANUPBY_TYPE +nach Art +;Type +; +; +MSGID_DEFAULT_MENU_CLEANUPBY_TYPE_SHORT + +; +; +MSGID_DEFAULT_MENU_SHOW +Inhalt anzeigen +;Show +; +; +MSGID_DEFAULT_MENU_SHOW_DEFAULT +Standard +;Default +; +; +MSGID_DEFAULT_MENU_SHOW_DEFAULT_SHORT + +; +; +MSGID_DEFAULT_MENU_SHOW_ONLYICONS +nur Dateien mit Piktogramm +;Only Icons +; +; +MSGID_DEFAULT_MENU_SHOW_ONLYICONS_SHOT +- +;- +; +; +MSGID_DEFAULT_MENU_SHOW_ALLFILES +alle Dateien +;All Files +; +; +MSGID_DEFAULT_MENU_SHOW_ALLFILES_SHORT ++ +;+ +; +; +MSGID_DEFAULT_MENU_VIEWBY +Inhalt auflisten +;View By +; +; +MSGID_DEFAULT_MENU_VIEWBY_DEFAULT +Standard +;Default +; +; +MSGID_DEFAULT_MENU_VIEWBY_DEFAULT_SHORT + +; +; +MSGID_DEFAULT_MENU_VIEWBY_ICON +als Piktogramme +;Icon +; +; +MSGID_DEFAULT_MENU_VIEWBY_ICON_SHORT +1 +;1 +; +; +MSGID_DEFAULT_MENU_VIEWBY_NAME +nach Namen +;Name +; +; +MSGID_DEFAULT_MENU_VIEWBY_NAME_SHORT +2 +;2 +; +; +MSGID_DEFAULT_MENU_VIEWBY_DATE +nach Datum +;Date +; +; +MSGID_DEFAULT_MENU_VIEWBY_DATE_SHORT +3 +;3 +; +; +MSGID_DEFAULT_MENU_VIEWBY_SIZE +nach Größe +;Size +; +; +MSGID_DEFAULT_MENU_VIEWBY_SIZE_SHORT +4 +;4 +; +; +MSGID_DEFAULT_MENU_VIEWBY_TYPE +nach Art +;Type +; +; +MSGID_DEFAULT_MENU_VIEWBY_TYPE_SHORT +5 +;5 +; +; +MSGID_DEFAULT_MENU_RESETSCALOS +Scalos rücksetzen +;Reset Scalos +; +; +MSGID_DEFAULT_MENU_RESETSCALOS_SHORT + +; +; +MSGID_DEFAULT_MENU_NEWSHELL +Neue Konsole... +;New Shell +; +; +MSGID_DEFAULT_MENU_NEWSHELL_SHORT + +; +; +MSGID_DEFAULT_MENU_DRAWERS_VOYAGER +Voyager +;Voyager +; +; +MSGID_DEFAULT_MENU_DRAWERS_VOYAGER_SHORT + +; +; +MSGID_DEFAULT_MENU_DRAWERS_ENVARC_SYS +ENVARC:Sys +;ENVARC:Sys +; +; +MSGID_DEFAULT_MENU_DRAWERS_ENVARC_SYS_SHORT + +; +; +MSGID_DEFAULT_MENU_DRAWERS_WBSTARTUP +WBStartup +;WBStartup +; +; +MSGID_DEFAULT_MENU_DRAWERS_WBSTARTUP_SHORT + +; +; +MSGID_DEFAULT_MENU_DRAWERS_PREFS +Voreinsteller +;Prefs +; +; +MSGID_DEFAULT_MENU_DRAWERS_PREFS_SHORT + +; +; +MSGID_DEFAULT_MENU_DRAWERS_SCALOSPREFS +Scalos Voreinsteller +;Scalos Prefs +; +; +MSGID_DEFAULT_MENU_DRAWERS_SCALOSPREFS_SHORT + +; +; +MSGID_DEFAULT_MENU_PREFS_SYSTEM +System... +;System... +; +; +MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT + +; +; +MSGID_DEFAULT_MENU_PREFS_MUI +MUI... +;MUI... +; +; +MSGID_DEFAULT_MENU_PREFS_MUI_SHORT + +; +; +MSGID_DEFAULT_MENU_PREFS_AHI +AHI... +;AHI... +; +; +MSGID_DEFAULT_MENU_PREFS_AHI_SHORT + +; +; +MSGID_DEFAULT_MENU_PREFS_SCALOS +Scalos Voreinsteller... +;Scalos Prefs... +; +; +MSGID_DEFAULT_MENU_PREFS_SCALOS_SHORT + +; +; +MSGID_DEFAULT_MENU_EMPTY_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_TOOLS +Tools +;Tools +; +;+++translateme+++ +MSGID_DEFAULT_UTILITIES +Utilities +;Utilities +; +;+++translateme+++ +MSGID_DEFAULT_PREFERENCES +Preferences +;Preferences +; +;+++translateme+++ +MSGID_DEFAULT_EXCHANGE +Exchange +;Exchange +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SCSICONFIG +SCSIConfig +;SCSIConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SNOOPIUM +Snoopium +;Snoopium +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_DEFRAG +Defrag +;Defrag +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_FTMANAGER +FTManager +;FTManager +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_MUISHELL +MUIShell +;MUIShell +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SFSDOCTOR +SFSDoctor +;SFSDoctor +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_UNITCONTROL +UnitControl +;UnitControl +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_FILEIMAGECTRL +FileImageCtrl +;FileImageCtrl +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_HDCONFIG +HDConfig +;HDConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_REGTOOL +RegTool +;RegTool +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SHELL +Shell +;Shell +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_EDITOR +Editor +;Editor +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_FRAGMENT +Fragment +;Fragment +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_GRABBER +Grabber +;Grabber +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_GRAPHICBOARDS +GraphicBoards +;GraphicBoards +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_KEYSTROKE +Keystroke +;Keystroke +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MINICALC +MiniCalc +;MiniCalc +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MORE +More +;More +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MUIPROCALC +MUIProCalc +;MUIProCalc +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MULTIVIEW +Multiview +;Multiview +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MYSTICVIEW +MysticView +;MysticView +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_TASKMANAGER +TaskManager +;TaskManager +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_TRANCESTATS +Trancestats +;Trancestats +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_TIPS +Tips +;Tips +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_ZOOM +Zoom +;Zoom +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_AMIGS +AmiGS +;AmiGS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_AMIPDF +AmiPDF +;AmiPDF +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_SGRAB +SGrab +;SGrab +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_CALCULATOR +Calculator +;Calculator +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_CLOCK +Clock +;Clock +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_GRAPHICDUMP +GraphicDump +;GraphicDump +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_ICONEDIT +IconEdit +;IconEdit +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_INITPRINTER +InitPrinter +;InitPrinter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_KEYSHOW +KeyShow +;KeyShow +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MEMACS +MEmacs +;MEmacs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_NOTEPAD +Notepad +;Notepad +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PARTITIONWIZARD +Partition Wizard +;Partition Wizard +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PLAYCD +PlayCD +;PlayCD +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PREFSOBJECTSEDITOR +PrefsObjectsEditor +;PrefsObjectsEditor +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PRINTFILES +PrintFiles +;PrintFiles +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_RAWDISK +RawDisk +;RawDisk +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_SHOWCONFIG +ShowConfig +;ShowConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_UNARC +UnArc +;UnArc +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_USBINSPECTOR +USBInspector +;USBInspector +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_AMIGAINPUT +AmigaInput +;AmigaInput +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_ASL +ASL +;ASL +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_COMPATIBILITY +Compatibility +;Compatibility +; +; +MSGID_DEFAULT_MENU_PREFS_DEFICONS +DefIcons +;DefIcons +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_DOS +DOS +;DOS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_FONT +Font +;Font +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_GUI +GUI +;GUI +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_INPUT +Input +;Input +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_INTERNET +Internet +;Internet +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_LOCALE +Locale +;Locale +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_NOTIFICATIONS +Notifications +;Notifications +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PALETTE +Palette +;Palette +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PICASSO96MODE +Picasso96Mode +;Picasso96Mode +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_POINTER +Pointer +;Pointer +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_POPUPMENU +PopupMenu +;PopupMenu +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PRINTER +Printer +;Printer +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PRINTERGFX +PrinterGFX +;PrinterGFX +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PRINTERPS +PrinterPS +;PrinterPS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCREENBLANKER +ScreenBlanker +;ScreenBlanker +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCREENMODE +ScreenMode +;ScreenMode +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCREENS +Screens +;Screens +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SERIAL +Serial +;Serial +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SOUND +Sound +;Sound +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_TIME +Time +;Time +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_URL +URL +;URL +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_USB +USB +;USB +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WBPATTERN +WBPattern +;WBPattern +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WBSTARTUP +WBStartup +;WBStartup +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WORKBENCH +Workbench +;Workbench +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_INTELLIFONT +IntelliFont +;IntelliFont +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_GRAPHICDUMP +GraphicDump +;GraphicDump +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_WBCLOCK +WBClock +;WBClock +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_CACHECDFS +CacheCDFS +;CacheCDFS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_ICONTROL +IControl +;IControl +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_OVERSCAN +Overscan +;Overscan +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_REACTION +Reaction +;Reaction +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_VINCED +ViNCDe +;ViNCDe +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WARPOS +WarpOS +;WarpOS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_BENCHTRASH +BenchTrash +;BenchTrash +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_CALCULATOR +Calculator +;Calculator +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_EDITPAD +EditPad +;EditPad +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_HDTOOLBOX +HDToolBox +;HDToolBox +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_ICONEDIT +IconEdit +;IconEdit +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_INITPRINTER +InitPrinter +;InitPrinter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_IOTOOLS +IoTools +;IoTools +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_KEYSHOW +KeyShow +;KeyShow +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_LACER +Lacer +;Lacer +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_MEMACS +MEmacs +;MEmacs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_MOUNTER +Mounter +;Mounter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_PREPCARD +PrepCard +;PrepCard +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_PRINTFILES +PrintFiles +;PrintFiles +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SHOWCONFIG +ShowConfig +;ShowConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_UNARC +Unarc +;Unarc +; +;+++translateme+++ +MSGID_DEFAULT_SYSTEM +System +;System +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_FIND +Find... +;Find... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_FIXFONT +FixFont +;FixFont +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_FORMAT +Format... +;Format... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_SHELL +Shell +;Shell +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_FORMATCDRW +FormatCDRW +;FormatCDRW +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_MEDIATOOLBOX +MediaToolBox +;MediaToolBox +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_MOUNTER +Mounter +;Mounter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_TYPEMANAGER +TypeManager +;TypeManager +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_HELP +Help +;Help +; +;----------------------------------------------------------- +; diff --git a/scalos/Prefs/Menu/Catalogs/deutsch/Scalos/config.mk b/scalos/Prefs/Menu/Catalogs/deutsch/Scalos/config.mk new file mode 100755 index 000000000..8631b0623 --- /dev/null +++ b/scalos/Prefs/Menu/Catalogs/deutsch/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = deutsch + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = german + +else + +############################################################################### +# AmigaOS and AROS + +LANG = deutsch + +endif +endif diff --git a/scalos/Prefs/Menu/Catalogs/deutsch/Scalos/makefile b/scalos/Prefs/Menu/Catalogs/deutsch/Scalos/makefile new file mode 100644 index 000000000..61d344675 --- /dev/null +++ b/scalos/Prefs/Menu/Catalogs/deutsch/Scalos/makefile @@ -0,0 +1,13 @@ +# makefile for Scalos (translated Texts : deutsch) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mdeutsch\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +ScalosMenu.catalog : ScalosMenu.ct ../../../ScalosMenu.cd + +All: ScalosMenu.catalog diff --git a/scalos/Prefs/Menu/Catalogs/deutsch/Scalos/makefile-new b/scalos/Prefs/Menu/Catalogs/deutsch/Scalos/makefile-new new file mode 100755 index 000000000..e69bf2339 --- /dev/null +++ b/scalos/Prefs/Menu/Catalogs/deutsch/Scalos/makefile-new @@ -0,0 +1,32 @@ +# makefile for ScalosMenu (translated Texts : deutsch) +# $Date: 2011-08-06 19:37:48 +0200 (Sa, 06. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = ScalosMenu + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git "a/scalos/Prefs/Menu/Catalogs/espa\303\261ol/scalos/ScalosMenu.ct" "b/scalos/Prefs/Menu/Catalogs/espa\303\261ol/scalos/ScalosMenu.ct" new file mode 100644 index 000000000..aa3796181 --- /dev/null +++ "b/scalos/Prefs/Menu/Catalogs/espa\303\261ol/scalos/ScalosMenu.ct" @@ -0,0 +1,1989 @@ +; ScalosMenu.ct +## version $VER: ScalosMenu.catalog 40.18 (24 Aug 2008 10:22:01) +## codeset 0 +## language español +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Menú Plugin Scalos +; +; +MSGID_TITLENAME_CMDLIST +Interior comandos de menú +;Scalos Internal Menu Commands +; +; +MSGID_FRAMETITLE +Lista de menús +; +; +MSGID_NEWINAME +Nueva entrada +; +; +MSGID_HOTKEYNAME +Tecla +; +; +MSGID_NEWNAME +Nuevo menú +; +; +MSGID_DELNAME +Eliminar +; +; +MSGID_SAVENAME +Guardar +; +; +MSGID_USENAME +Usar +; +; +MSGID_CANCELNAME +Cancelar +; +; +MSGID_NEW2NAME +Nuevo comando +; +; +MSGID_COMMANDNAME +Comando +; +; +MSGID_MENU_PROJECT_IMPORT +Importar +; +; +MSGID_MENU_PROJECT_IMPORT_SHORT +I +; +; +MSGID_MENU_PROJECT_OPEN +Abrir... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +O +; +; +MSGID_MENU_PROJECT_SAVEAS +Guardar como... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +A +; +; +MSGID_MENU_PROJECT_QUIT +Salir +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +; +MSGID_MENU_PROJECT +Proyecto +; +; +MSGID_MENU_EDIT_LASTSAVED +Último guardado +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +L +; +; +MSGID_MENU_EDIT +Editar +; +; +MSGID_MENU_SETTINGS_CREATEICONS +¿Crear icono? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +I +; +; +MSGID_MENU_SETTINGS +Valores +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +Predeterminados +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +D +; +; +MSGID_MENU_EDIT_RESTORE +Recuperar +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +R +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Acerca de MUI... +; +; +MSGID_WBNAME +Workbench +; +; +MSGID_ADOSNAME +AmigaDOS +; +; +MSGID_STACKNAME +Pila +; +; +MSGID_MAINMENUNAME +Menú principal +; +; +MSGID_COM1NAME +Pantalla completa +; +; +MSGID_COM2NAME +Ejecutar comando +; +; +MSGID_COM3NAME +Redibujar todo +; +; +MSGID_COM4NAME +Actualizar todo +; +; +MSGID_COM5NAME +Acerca de Scalos +; +; +MSGID_COM6NAME +Salir +; +; +MSGID_COM7NAME +Nuevo cajón +; +; +MSGID_COM8NAME +Abrir cajón anterior +; +; +MSGID_COM9NAME +Cerrar ventana +; +; +MSGID_COM10NAME +Actualizar +; +; +MSGID_COM11NAME +Seleccionar contenido +; +; +MSGID_COM12NAME +Reorganizar +; +; +MSGID_COM13NAME +Congelar ventana +; +; +MSGID_COM14NAME +Congelar ventana y contenido +; +; +MSGID_COM15NAME +Mostrar sólo iconos +; +; +MSGID_COM16NAME +Mostrar todos los ficheros +; +; +MSGID_COM17NAME +Ver por icono +; +; +MSGID_COM18NAME +Ver por texto +; +; +MSGID_COM19NAME +Abrir +; +; +MSGID_COM20NAME +Reiniciar Scalos +; +; +MSGID_COM21NAME +Renombrar +; +; +MSGID_COM22NAME +Información +; +; +MSGID_COM23NAME +Congelar +; +; +MSGID_COM24NAME +Descongelar +; +; +MSGID_COM25NAME +Dejar fuera +; +; +MSGID_COM26NAME +Salir +; +; +MSGID_COM27NAME +Eliminar +; +; +MSGID_BARNAME +\033C +; +; +MSGID_UPNAME +Arriba +; +; +MSGID_DOWNNAME +Abajo +; +; +MSGID_MENU_PROJECT_IMPORT_TD +ToolsDaemon... +; +; +MSGID_MENU_PROJECT_IMPORT_TD_SHORT +T +; +; +MSGID_MENU_PROJECT_IMPORT_P +Parm... +; +; +MSGID_MENU_PROJECT_IMPORT_P_SHORT +P +; +; +MSGID_COM28NAME +Copiar +; +; +MSGID_ICONWINNAME +Icono ventana +; +; +MSGID_AREXXNAME +ARexx +; +; +MSGID_MENU_EDIT_COPY +Copiar +;Copy +; +; +MSGID_MENU_EDIT_CUT +Cortar +;Cut +; +; +MSGID_MENU_EDIT_PASTE +Pegar +;Paste +; +; +MSGID_MENU_EDIT_COLLAPSE +Cerrar seleccionados +;Collapse Selected +; +; +MSGID_MENU_EDIT_EXPAND +Ampliar seleccionados +;Expand Selected +; +;--------------------------------------------- +; +MSGID_POPMENUNAME1 +Menú PopUp: Discos +; +; +MSGID_POPMENUNAME2 +Menú PopUp: Cajones +; +; +MSGID_POPMENUNAME3 +Menú PopUp: Herramientas y proyectos +; +; +MSGID_POPMENUNAME4 +Menú PopUp: Papeleras +; +; +MSGID_POPMENUNAME5 +Menú PopUp: Ventanas +; +; +MSGID_ARGSNAME +Argumentos WB: +; +; +MSGID_COM29NAME +Vaciar papelera +; +; +MSGID_COM30NAME +Último mensaje +; +; +MSGID_COM31NAME +Redibujar +; +; +MSGID_COM32NAME +Iconificar +; +; +MSGID_PLUGINNAME +PlugIn +; +; +MSGID_MENU_PROJECT_MERGE +Mezclar... +; +; +MSGID_MENU_PROJECT_MERGE_SHORT +M +; +; +MSGID_MENU_EDIT_COLLAPSEALL +Se derrumban todos +;Collapse All +; +; +MSGID_MENU_EDIT_EXPANDALL +Amplíe todos +;Expand All +; +; +MSGID_MENU_SETTINGS_HIDEOBSOLETE +Piel obsoleta? +;Hide Obsolete? +; +; +MSGID_MENU_SETTINGS_HIDEOBSOLETE_SHORT +Si están comprobados, los menús móviles obsoletos\n\ +que ahora se definen vía prefs de los tipos de\n\ +archivo no se demuestran. +;If checked, obsolete popup menus which are now\n\ +;defined via filetypes prefs are not shown. +; +; +MSGID_COM33NAME +Formato de disco... +; +; +MSGID_COM34NAME +Parada... +;Shutdown... +; +; +MSGID_COM35NAME +Tamaño a caber +;Size to fit +; +; +MSGID_COM36NAME +Selección clara +;Clear Selection +; +;+++translateme+++ +MSGID_POPMENUNAME6 +Popup Menu: AppIcons +; +;+++translateme+++ +MSGID_POPMENUNAME7 +Popup Menu: Desktop +;Popup Menu: Desktop +; +; +MSGID_COM37NAME +Visión por tamaño +;View By - Size +; +; +MSGID_COM38NAME +Visión por la fecha +;View By - Date +; +; +MSGID_MENU_PROJECT_ABOUT +About... +; +; +MSGID_ABOUTREQOK +_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Menu Preferences V%ld.%ld\033n\n\ +%s\n\ +© 1999%s The Scalos Team\n +; +; +;*** +jl+ 20011214 +; +MSGID_COM39NAME +Copie el archivo +;Copy file +; +; +MSGID_COM40NAME +Corte el archivo +;Cut file +; +; +MSGID_COM41NAME +archivo de la goma +;Paste file +; +; +MSGID_COM42NAME +visión por el tipo +;View By - Type +; +; +MSGID_COM43NAME +limpieza por nombre +;Cleanup By - Name +; +; +MSGID_COM44NAME +limpieza por la fecha +;Cleanup By - Date +; +; +MSGID_COM45NAME +limpieza por tamaño +;Cleanup By - Size +; +; +MSGID_COM46NAME +limpieza por tipo +;Cleanup By - Type +; +; +MSGID_COM_ICONPROPERTIES +Icono de propiedades +;Icon properties +; +; +MSGID_COM_WINDOWPROPERTIES +Ventana de propiedades +;Window properties +; +; +MSGID_COM47NAME +Visión por - Predeterminado +;View By - Default +; +;+++translateme+++ +MSGID_COM48NAME +Show - Default +; +; +MSGID_COM49NAME +Copie a... +;Copy to... +; +; +MSGID_COM50NAME +Muévase a... +;Move to... +; +; +MSGID_COM51NAME +Crear miniatura +;Create thumbnail +; +; +MSGID_COM_OPENNEWWINDOW +Ábrase en nueva ventana +;Open in new window +; +; +MSGID_COM_THUMBNAILCACHECLEANUP +De caché miniatura de limpieza +;Cleanup thumbnail cache +; +; +MSGID_COM_FIND +archivo del hallazgo +;Find File(s) +; +; +MSGID_COM_UNDO +deshaga +;Undo +; +; +MSGID_COM_REDO +haga de nuevo +;Redo +; +;+++translateme+++ +MSGID_COM_OPENBROWSERWINDOW +Open in Browser Window +;Open in Browser Window +; +;--------------------------------------------- +; +; +MSGID_SHORTHELP_NEWMENUBUTTON +Presione este botón para crear un nuevo menú o\n\ +Entrada del submenú en la posición actualmente seleccionada. +;Press this button to create a new Menu or\n\ +;Submenu entry at the currently selected position. +; +; +; +MSGID_SHORTHELP_NEWITEMBUTTON +Presione este botón para insertar un nuevo artículo\n\ +de menú en la posición actualmente seleccionada. +;Press this button to insert a new menu\n\ +;item at the currently selected position. +; +; +; +MSGID_SHORTHELP_NEWCOMMANDBUTTON +Presione este botón para agregar un nuevo\n\ +ordene actualmente al artículo de menú. +;Press this button to add a new\n\ +;command to the currently menu item. +; +; +; +MSGID_SHORTHELP_DELBUTTON +Presione este botón para suprimir el comando,\n\ +el artículo de menú, o el menú actualmente selecto. +;Press this button to delete the currently\n\ +;select command, menu item, or menu. +; +; +; +MSGID_SHORTHELP_SAVEBUTTON +Presione este botón para ahorrar\n\ +los ajustes actuales a\n\ +\"ENVARC:Scalos/menu13.prefs\". +;Press this button to save \n\ +;the current settings to\n\ +;\"ENVARC:Scalos/menu13.prefs\". +; +; +; +MSGID_SHORTHELP_USEBUTTON +Presione este botón para ahorrar\n\ +los ajustes actuales a\n\ +\"ENV:Scalos/menu13.prefs\". +;Press this button to save \n\ +;the current settings to\n\ +;\"ENV:Scalos/menu13.prefs\". +; +; +; +MSGID_SHORTHELP_CANCELBUTTON +Presione este botón para abortar\n\ +y para olvidar todos los cambios. +;Press this button to abort\n\ +;and forget all changes. +; +; +;+++translateme+++ +MSGID_REQTITLE_SAVEERROR +Error writing palette preferences\n\ +file \"%s\"\n\ +%s +; +;+++translateme+++ +MSGID_REQTITLE_READERROR +Error reading palette preferences\n\ +file \"%s\"\n\ +%s +; +; +MSGID_IMPORTNAME +Importación +;Import +; +;+++translateme+++ +MSGID_TITLE_IMPORTTD +Import ToolsDaemon Prefs +; +;+++translateme+++ +MSGID_TITLE_IMPORTP +Import ParM Prefs +; +; +MSGID_PRIORITY_SLIDER_NAME +Prioridad +;Priority +; +; +MSGID_PRIORITY_SLIDER_BUBBLE +Utilice este resbalador para ajustar la\n\ +prioridad que el comando debe funcionar con +;Use this slider to adjust the priority the command should run with. +; +; new in 40.7 +;+++translateme+++ +MSGID_PLUGIN_LIST_TITLE +Menu +; +;+++translateme+++ +MSGID_POPUP_ASLTITLE_AMIGADOS +Select AmigaDOS command +; +;+++translateme+++ +MSGID_POPUP_ASLTITLE_WORKBENCH +Select Workbench command +; +; +MSGID_POPUP_ASLTITLE_ICONWINDOW +Selecciona directorio de icono de la ventana +;Select directory for icon window +; +;+++translateme+++ +MSGID_POPUP_ASLTITLE_AREXX +Select ARexx program +; +;+++translateme+++ +MSGID_POPUP_ASLTITLE_MENUPLUGIN +Select Scalos Menu plugin +; +;+++translateme+++ +MSGID_MENU_PROJECT_MERGE_ASLTITLE +Select prefs to merge with +; +; +MSGID_MENU_GROUP_COMMAND_PROPERTIES +Características del comando +;Command Properties +; +; new in 40.10 +; +; +MSGID_SHORTHELP_LAMP_CHANGED +Esta luz indicadora de los cambios de \033bOff\033n a \033bOK\033n\n\ +cuando los ajustes se han modificado desde la carga inicial. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +; new in 40.16 +; +; +MSGID_POPASL_UNSELECTEDIMAGE_SHORTHELP +Aquí usted puede seleccionar una imagen icónica que se\n\ +demuestre a la izquierda del nombre del artículo de\n\ +menú, en estado no seleccionado del artículo de menú. +;Here you may select an iconic image that is shown left of\n\ +;the menu item name, in unselected menu item state. +; +; +MSGID_SAMPLE_UNSELECTEDIMAGE_SHORTHELP +Esto es una muestra de la imagen icónica que será\n\ +demostrada a la izquierda del nombre del artículo de\n\ +menú, en estado no seleccionado del artículo de menú. +;This is a sample of the iconic image that will be shown\n\ +;left of the menu item name, in unselected menu item state. +; +; +MSGID_POPASL_SELECTEDIMAGE_SHORTHELP +Aquí usted puede seleccionar una imagen icónica que se\n\ +demuestre a la izquierda del nombre del artículo de\n\ +menú, en estado seleccionado del artículo de menú. +;Here you may select an iconic image that is shown left of\n\ +;the menu item name, in selected menu item state. +; +; +MSGID_SAMPLE_SELECTEDIMAGE_SHORTHELP +Esto es una muestra de la imagen icónica que será demostrada\n\ +a la izquierda del nombre del artículo de menú,\n\ +en estado seleccionado del artículo de menú. +;This is a sample of the iconic image that will be shown\n\ +;left of the menu item name, in selected menu item state. +; +; +MSGID_ENTRY_STRING_NAME +Nombre: +;Name: +; +; +MSGID_ENTRY_GROUP_UNSELECTEDIMAGE +Imagen de Estado no seleccionados +;Unselected State Image +; +; +MSGID_ENTRY_GROUP_SELECTEDIMAGE +Estado de la imagen seleccionada +;Selected State Image +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_STARTUP_FAILURE +Scalos Menu Prefs startup failed +;Scalos Menu Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Inténtelo de nuevo|Salir +;Try again|Quit +; +;+++translateme+++ +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +;+++translateme+++ +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +;+++translateme+++ +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_NEW_MENU +Nuevo menú +;New Menu +; +; +MSGID_NEW_ITEM +Nuevo artículo +;New Item +; +; +MSGID_TOOLS_MENU +Herramientas +;Tools +; +;----------------------------------------------------------- +; +MSGID_DEFAULT_MENU_OPEN +Abierto +;Open +; +; +MSGID_DEFAULT_MENU_OPEN_SHORT +A +;O +; +; +MSGID_DEFAULT_MENU_INFORMATION +Informatión... +;Information... +; +; +MSGID_DEFAULT_MENU_INFORMATION_SHORT +I +;I +; +; +MSGID_DEFAULT_MENU_BROWSE +Navegar... +;Browse... +; +; +MSGID_DEFAULT_MENU_BROWSE_SHORT +N +; +; +MSGID_DEFAULT_MENU_FIND +Hallar... +;Find... +; +; +MSGID_DEFAULT_MENU_FIND_SHORT +H +;F +; +; +MSGID_DEFAULT_MENU_SNAPSHOT +Instantánea +;Snapshot +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT_SHORT +S +;S +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UNSNAPSHOT +Unsnapshot +;Unsnapshot +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UNSNAPSHOT_SHORT +U +;U +; +; +MSGID_DEFAULT_MENU_CLONE +Clonar +;Clone +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLONE_SHORT +C +;C +; +; +MSGID_DEFAULT_MENU_COPY +Copiar +;Copy +; +;+++translateme+++ +MSGID_DEFAULT_MENU_COPY_SHORT + +; +; +MSGID_DEFAULT_MENU_CUT +Cortar +;Cut +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CUT_SHORT + +; +; +MSGID_DEFAULT_MENU_PASTE +Pegar +;Paste +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PASTE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DISKCOPY +Diskcopy... +;Diskcopy... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DISKCOPY_SHORT + +; +; +MSGID_DEFAULT_MENU_RELABEL +Reetiquetar... +;Relabel... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RELABEL_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_FORMAT +Format... +;Format... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_FORMAT_SHORT + +; +; +MSGID_DEFAULT_MENU_PROPERTIES +Propiedades... +;Properties... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PROPERTIES_SHORT + +; +; +MSGID_DEFAULT_MENU_EDIT +Editar +;Edit +; +; +MSGID_DEFAULT_MENU_RENAME +Cambiar el nombre +;Rename +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RENAME_SHORT +R +;R +; +; +MSGID_DEFAULT_MENU_LEAVEOUT +Váyase hacia fuera +;Leave Out +; +;+++translateme+++ +MSGID_DEFAULT_MENU_LEAVEOUT_SHORT +F +;L +; +; +MSGID_DEFAULT_MENU_PUTAWAY +Puesto de lado +;Put Away +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PUTAWAY_SHORT +P +;P +; +; +MSGID_DEFAULT_MENU_DELETE +Eliminar... +;Delete... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DELETE_SHORT + +; +; +MSGID_DEFAULT_MENU_EMPTYTRASH +Vaciar papelera... +;Empty Trashcan... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EMPTYTRASH_SHORT + +; +; +MSGID_DEFAULT_MENU_CLOSE +Cerrar +;Close +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLOSE_SHORT +K +; +; +MSGID_DEFAULT_MENU_OPENPARENT +Abra al padre +;Open Parent +; +;+++translateme+++ +MSGID_DEFAULT_MENU_OPENPARENT_SHORT + +; +; +MSGID_DEFAULT_MENU_UPDATE +Actualización +;Update +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UPDATE_SHORT +M +;M +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUP +Cleanup +;Cleanup +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUP_SHORT + +; +; +MSGID_DEFAULT_MENU_RESIZETOFIT +Tamaño a caber +;Resize To Fit +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RESIZETOFIT_SHORT + +; +; +MSGID_DEFAULT_MENU_SELECTCONTENTS +Seleccione el contenido +;Select Contents +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SELECTCONTENTS_SHORT +A +;A +; +; +MSGID_DEFAULT_MENU_CLEARSELECTION +Selección clara +;Clear Selection +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEARSELECTION_SHORT +Z +;Z +; +; +MSGID_DEFAULT_MENU_SNAPSHOT_ALL +Todo +;All +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT_ALL_SHORT + +; +; +MSGID_DEFAULT_MENU_SNAPSHOT_WINDOW +Ventana +;Window +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT_WINDOW_SHORT +W +;W +; +; +MSGID_DEFAULT_MENU_NEWDRAWER +Cajón de nuevo... +;New Drawer... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_NEWDRAWER_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SCALOS +Scalos +;Scalos +; +; +MSGID_DEFAULT_MENU_WINDOW +Ventana +;Window +; +;+++translateme+++ +MSGID_DEFAULT_MENU_ICONS +Icons +;Icons +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS +Drawers +;Drawers +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS +Prefs +;Prefs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_BACKDROP +Backdrop? +;Backdrop? +; +;+++translateme+++ +MSGID_DEFAULT_MENU_BACKDROP_SHORT +B +;B +; +; +MSGID_DEFAULT_MENU_EXECUTECOMMAND +Ejecute el comando... +;Execute Command... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EXECUTECOMMAND_SHORT +E +;E +; +; +MSGID_DEFAULT_MENU_REDRAWALL +Rediseñe todos +;Redraw All +; +;+++translateme+++ +MSGID_DEFAULT_MENU_REDRAWALL_SHORT + +; +; +MSGID_DEFAULT_MENU_UPDATEALL +Ponga al día todos +;Update All +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UPDATEALL_SHORT + +; +; +MSGID_DEFAULT_MENU_LASTMESSAGE +Mensaje pasado +;Last Message +; +;+++translateme+++ +MSGID_DEFAULT_MENU_LASTMESSAGE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_ABOUT +About... +;About... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_ABOUT_SHORT +? +;? +; +; +MSGID_DEFAULT_MENU_QUIT +Salir... +;Quit... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_QUIT_SHORT + +; +; +MSGID_DEFAULT_MENU_CLEANUPBY +Limpie cerca +;Clean up by +; +; +MSGID_DEFAULT_MENU_CLEANUPBY_COLUMN +Columna +;Column +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_COLUMN_SHORT +. +;. +; +; +MSGID_DEFAULT_MENU_CLEANUPBY_NAME +Nombre +;Name +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_NAME_SHORT + +; +; +MSGID_DEFAULT_MENU_CLEANUPBY_DATE +Fecha +;Date +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_DATE_SHORT + +; +; +MSGID_DEFAULT_MENU_CLEANUPBY_SIZE +Tamaño +;Size +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_SIZE_SHORT + +; +; +MSGID_DEFAULT_MENU_CLEANUPBY_TYPE +Tipo +;Type +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_TYPE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW +Show +;Show +; +; +MSGID_DEFAULT_MENU_SHOW_DEFAULT +Predeterminado +;Default +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_DEFAULT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_ONLYICONS +Only Icons +;Only Icons +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_ONLYICONS_SHOT +- +;- +; +; +MSGID_DEFAULT_MENU_SHOW_ALLFILES +Todos los archivos +;All Files +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_ALLFILES_SHORT ++ +;+ +; +; +MSGID_DEFAULT_MENU_VIEWBY +Ver por +;View By +; +; +MSGID_DEFAULT_MENU_VIEWBY_DEFAULT +Predeterminado +;Default +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_DEFAULT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_ICON +Icon +;Icon +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_ICON_SHORT +1 +;1 +; +; +MSGID_DEFAULT_MENU_VIEWBY_NAME +Nombre +;Name +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_NAME_SHORT +2 +;2 +; +; +MSGID_DEFAULT_MENU_VIEWBY_DATE +Fecha +;Date +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_DATE_SHORT +3 +;3 +; +; +MSGID_DEFAULT_MENU_VIEWBY_SIZE +Tamaño +;Size +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_SIZE_SHORT +4 +;4 +; +; +MSGID_DEFAULT_MENU_VIEWBY_TYPE +Tipo +;Type +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_TYPE_SHORT +5 +;5 +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RESETSCALOS +Reset Scalos +;Reset Scalos +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RESETSCALOS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_NEWSHELL +New Shell +;New Shell +; +;+++translateme+++ +MSGID_DEFAULT_MENU_NEWSHELL_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_VOYAGER +Voyager +;Voyager +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_VOYAGER_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_ENVARC_SYS +ENVARC:Sys +;ENVARC:Sys +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_ENVARC_SYS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_WBSTARTUP +WBStartup +;WBStartup +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_WBSTARTUP_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_PREFS +Prefs +;Prefs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_PREFS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_SCALOSPREFS +Scalos Prefs +;Scalos Prefs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_SCALOSPREFS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SYSTEM +System... +;System... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_MUI +MUI... +;MUI... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_MUI_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_AHI +AHI... +;AHI... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_AHI_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCALOS +Scalos Prefs... +;Scalos Prefs... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCALOS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EMPTY_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_TOOLS +Tools +;Tools +; +;+++translateme+++ +MSGID_DEFAULT_UTILITIES +Utilities +;Utilities +; +;+++translateme+++ +MSGID_DEFAULT_PREFERENCES +Preferences +;Preferences +; +;+++translateme+++ +MSGID_DEFAULT_EXCHANGE +Exchange +;Exchange +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_MOUNTER +Mounter +;Mounter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SCSICONFIG +SCSIConfig +;SCSIConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SNOOPIUM +Snoopium +;Snoopium +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_DEFRAG +Defrag +;Defrag +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_FTMANAGER +FTManager +;FTManager +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_MUISHELL +MUIShell +;MUIShell +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SFSDOCTOR +SFSDoctor +;SFSDoctor +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_UNITCONTROL +UnitControl +;UnitControl +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_FILEIMAGECTRL +FileImageCtrl +;FileImageCtrl +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_HDCONFIG +HDConfig +;HDConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_REGTOOL +RegTool +;RegTool +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SHELL +Shell +;Shell +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_EDITOR +Editor +;Editor +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_FRAGMENT +Fragment +;Fragment +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_GRABBER +Grabber +;Grabber +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_GRAPHICBOARDS +GraphicBoards +;GraphicBoards +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_KEYSTROKE +Keystroke +;Keystroke +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MINICALC +MiniCalc +;MiniCalc +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MORE +More +;More +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MUIPROCALC +MUIProCalc +;MUIProCalc +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MULTIVIEW +Multiview +;Multiview +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MYSTICVIEW +MysticView +;MysticView +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_TASKMANAGER +TaskManager +;TaskManager +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_TRANCESTATS +Trancestats +;Trancestats +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_TIPS +Tips +;Tips +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_ZOOM +Zoom +;Zoom +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_AMIGS +AmiGS +;AmiGS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_AMIPDF +AmiPDF +;AmiPDF +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_SGRAB +SGrab +;SGrab +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_CALCULATOR +Calculator +;Calculator +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_CLOCK +Clock +;Clock +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_GRAPHICDUMP +GraphicDump +;GraphicDump +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_ICONEDIT +IconEdit +;IconEdit +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_INITPRINTER +InitPrinter +;InitPrinter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_KEYSHOW +KeyShow +;KeyShow +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MEMACS +MEmacs +;MEmacs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_NOTEPAD +Notepad +;Notepad +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PARTITIONWIZARD +Partition Wizard +;Partition Wizard +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PLAYCD +PlayCD +;PlayCD +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PREFSOBJECTSEDITOR +PrefsObjectsEditor +;PrefsObjectsEditor +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PRINTFILES +PrintFiles +;PrintFiles +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_RAWDISK +RawDisk +;RawDisk +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_SHOWCONFIG +ShowConfig +;ShowConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_UNARC +UnArc +;UnArc +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_USBINSPECTOR +USBInspector +;USBInspector +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_AMIGAINPUT +AmigaInput +;AmigaInput +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_ASL +ASL +;ASL +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_COMPATIBILITY +Compatibility +;Compatibility +; +; +MSGID_DEFAULT_MENU_PREFS_DEFICONS +DefIcons +;DefIcons +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_DOS +DOS +;DOS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_FONT +Font +;Font +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_GUI +GUI +;GUI +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_INPUT +Input +;Input +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_INTERNET +Internet +;Internet +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_LOCALE +Locale +;Locale +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_NOTIFICATIONS +Notifications +;Notifications +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PALETTE +Palette +;Palette +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PICASSO96MODE +Picasso96Mode +;Picasso96Mode +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_POINTER +Pointer +;Pointer +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_POPUPMENU +PopupMenu +;PopupMenu +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PRINTER +Printer +;Printer +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PRINTERGFX +PrinterGFX +;PrinterGFX +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PRINTERPS +PrinterPS +;PrinterPS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCREENBLANKER +ScreenBlanker +;ScreenBlanker +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCREENMODE +ScreenMode +;ScreenMode +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCREENS +Screens +;Screens +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SERIAL +Serial +;Serial +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SOUND +Sound +;Sound +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_TIME +Time +;Time +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_URL +URL +;URL +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_USB +USB +;USB +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WBPATTERN +WBPattern +;WBPattern +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WBSTARTUP +WBStartup +;WBStartup +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WORKBENCH +Workbench +;Workbench +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_INTELLIFONT +IntelliFont +;IntelliFont +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_GRAPHICDUMP +GraphicDump +;GraphicDump +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_WBCLOCK +WBClock +;WBClock +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_CACHECDFS +CacheCDFS +;CacheCDFS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_ICONTROL +IControl +;IControl +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_OVERSCAN +Overscan +;Overscan +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_REACTION +Reaction +;Reaction +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_VINCED +ViNCDe +;ViNCDe +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WARPOS +WarpOS +;WarpOS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_BENCHTRASH +BenchTrash +;BenchTrash +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_CALCULATOR +Calculator +;Calculator +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_EDITPAD +EditPad +;EditPad +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_HDTOOLBOX +HDToolBox +;HDToolBox +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_ICONEDIT +IconEdit +;IconEdit +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_INITPRINTER +InitPrinter +;InitPrinter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_IOTOOLS +IoTools +;IoTools +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_KEYSHOW +KeyShow +;KeyShow +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_LACER +Lacer +;Lacer +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_MEMACS +MEmacs +;MEmacs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_PREPCARD +PrepCard +;PrepCard +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_PRINTFILES +PrintFiles +;PrintFiles +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SHOWCONFIG +ShowConfig +;ShowConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_UNARC +Unarc +;Unarc +; +;+++translateme+++ +MSGID_DEFAULT_SYSTEM +System +;System +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_FIND +Find... +;Find... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_FIXFONT +FixFont +;FixFont +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_FORMAT +Format... +;Format... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_SHELL +Shell +;Shell +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_FORMATCDRW +FormatCDRW +;FormatCDRW +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_MEDIATOOLBOX +MediaToolBox +;MediaToolBox +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_MOUNTER +Mounter +;Mounter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_TYPEMANAGER +TypeManager +;TypeManager +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_HELP +Help +;Help +; +;----------------------------------------------------------- +; diff --git "a/scalos/Prefs/Menu/Catalogs/espa\303\261ol/scalos/config.mk" "b/scalos/Prefs/Menu/Catalogs/espa\303\261ol/scalos/config.mk" new file mode 100755 index 000000000..d0133689f --- /dev/null +++ "b/scalos/Prefs/Menu/Catalogs/espa\303\261ol/scalos/config.mk" @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = español + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = spanish + +else + +############################################################################### +# AmigaOS and AROS + +LANG = español + +endif +endif diff --git "a/scalos/Prefs/Menu/Catalogs/espa\303\261ol/scalos/makefile" "b/scalos/Prefs/Menu/Catalogs/espa\303\261ol/scalos/makefile" new file mode 100644 index 000000000..54df6de77 --- /dev/null +++ "b/scalos/Prefs/Menu/Catalogs/espa\303\261ol/scalos/makefile" @@ -0,0 +1,12 @@ +# makefile für Scalos (translated Texts : español) +# 01 Jan 2004 12:40:23 + +.SUFFIXES: .ct .catalog + +.ct.catalog : + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +ScalosMenu.catalog : ScalosMenu.ct ../../../ScalosMenu.cd + +All: ScalosMenu.catalog diff --git "a/scalos/Prefs/Menu/Catalogs/espa\303\261ol/scalos/makefile-new" "b/scalos/Prefs/Menu/Catalogs/espa\303\261ol/scalos/makefile-new" new file mode 100755 index 000000000..44eb096fa --- /dev/null +++ "b/scalos/Prefs/Menu/Catalogs/espa\303\261ol/scalos/makefile-new" @@ -0,0 +1,32 @@ +# makefile for ScalosMenu (translated Texts : español) +# $Date: 2011-08-06 19:37:48 +0200 (Sa, 06. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = ScalosMenu + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git "a/scalos/Prefs/Menu/Catalogs/fran\303\247ais/Scalos/ScalosMenu.ct" "b/scalos/Prefs/Menu/Catalogs/fran\303\247ais/Scalos/ScalosMenu.ct" new file mode 100755 index 000000000..7e7baf4be --- /dev/null +++ "b/scalos/Prefs/Menu/Catalogs/fran\303\247ais/Scalos/ScalosMenu.ct" @@ -0,0 +1,1877 @@ +; ScalosMenu.ct +; $Date$ +; $Revision$ +; $Id$ +; +## version $VER: ScalosMenu.catalog 40.18 (24 Aug 2006 23:56:40) +## codeset 0 +## language français +; +;#arrayopts static __far +; +; Translation done +; +; By COAT Jean-Marie ALIAS JMC +; E-Mail : agalliance@free.fr +; +; +MSGID_TITLENAME +Menu Plugin Scalos +; Scalos Menu Prefs Plugin +; +; +MSGID_TITLENAME_CMDLIST +Commandes internes du menu de Scalos +; Scalos Internal Menu Commands +; +; +MSGID_FRAMETITLE +Liste des menus +; Menulist +; +; +MSGID_NEWINAME +Nouvelle entrée +; New Item +; +; +MSGID_HOTKEYNAME +Raccourci : +; Key: +; +; +MSGID_NEWNAME +Nouveau Menu +; New Menu +; +; +MSGID_DELNAME +Effacer +; Delete +; +; +MSGID_SAVENAME +Sauver +; Save +; +; +MSGID_USENAME +Utiliser +; Use +; +; +MSGID_CANCELNAME +Annuler +; Cancel +; +; +MSGID_NEW2NAME +Nouvelle Commande +; New Command +; +; +MSGID_COMMANDNAME +Commande +; Command +; +; +MSGID_WBNAME +Workbench +; +; +MSGID_ADOSNAME +AmigaDOS +; +; +MSGID_STACKNAME +Pile +; +; +MSGID_MAINMENUNAME +Menu principal +; +; +MSGID_BARNAME +\033C +;\033C +; +; +MSGID_UPNAME +Haut +; +; +MSGID_DOWNNAME +Bas +; +; +MSGID_ICONWINNAME +Ouvrir fenêtre +; +; +MSGID_AREXXNAME +Arexx +; +; +MSGID_ARGSNAME +Arguments WB : +; +;--------------------------------------------- +; +MSGID_MENU_PROJECT_IMPORT +Importer +; Import +; +; +MSGID_MENU_PROJECT_IMPORT_SHORT +I +; +; +MSGID_MENU_PROJECT_OPEN +Ouvrir... +; Open... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +O +; +; +MSGID_MENU_PROJECT_SAVEAS +Sauver en... +; Save As... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +A +; +; +MSGID_MENU_PROJECT_ABOUT +A propos... +; About... +; +; +MSGID_MENU_PROJECT_QUIT +Quitter +; Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +; +MSGID_MENU_PROJECT +Projet +; Project +; +; +MSGID_MENU_EDIT_LASTSAVED +Dernière sauvegarde +; Last Saved +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +L +; +; +MSGID_MENU_EDIT +Edition +; Edit +; +; +MSGID_MENU_SETTINGS_CREATEICONS +Créer une icône ? +; Create Icons? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +I +; +; +MSGID_MENU_SETTINGS +Options +; Option +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +Réglages par défaut +; Reset To Defaults +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +D +; +; +MSGID_MENU_EDIT_RESTORE +Restaurer +; Restore +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +R +; +; +MSGID_MENU_PROJECT_ABOUTMUI +A propos de MUI... +; About MUI... +; +MSGID_MENU_PROJECT_IMPORT_TD +ToolsDaemon... +; +; +MSGID_MENU_PROJECT_IMPORT_TD_SHORT +T +; +; +MSGID_MENU_PROJECT_IMPORT_P +Parm... +; +; +MSGID_MENU_PROJECT_IMPORT_P_SHORT +P +; +MSGID_MENU_PROJECT_MERGE +Fusionner... +; +; +MSGID_MENU_PROJECT_MERGE_SHORT +M +; +; +MSGID_MENU_EDIT_COLLAPSEALL +Tout réduire +; Collapse All +; +; +MSGID_MENU_EDIT_EXPANDALL +Tout étendre +; Expand All +; +MSGID_MENU_SETTINGS_HIDEOBSOLETE +Cacher les menus obsolètes ? +;Hide Obsolete? +; +MSGID_MENU_SETTINGS_HIDEOBSOLETE_SHORT +Si coché, les menus popup qui sont maintenant\n\ +définis via les préferences des types de fichiers,\n\ +ne seront pas visibles. +;If checked, obsolete popup menus which are now\n\ +;defined via filetypes prefs are not shown. +; +MSGID_MENU_EDIT_COPY +Copier +;Copy +; +MSGID_MENU_EDIT_CUT +Couper +;Cut +; +MSGID_MENU_EDIT_PASTE +Coller +;Paste +; +MSGID_MENU_EDIT_COLLAPSE +Plier l'entrée sélectionnée +;Collapse Selected +; +MSGID_MENU_EDIT_EXPAND +Déplier l'entrée sélectionnée +;Expand Selected +; +;--------------------------------------------- +; +MSGID_POPMENUNAME1 +Popup Menu : Icônes des Volumes +; Popup Menu: Disk icons +; +; +MSGID_POPMENUNAME2 +Popup Menu : Icônes des Répertoires +; Popup Menu: Drawer icons +; +; +MSGID_POPMENUNAME3 +Popup Menu: Icônes des Outils/Projets +; Popup Menu: Tool/Project icons +; +; +MSGID_POPMENUNAME4 +Popup Menu : Icônes des Corbeilles +; Popup Menu: Trashcan icons +; +; +MSGID_POPMENUNAME5 +Popup Menu : Fenêtres +; Popup_Menu: Windows +; +; +MSGID_POPMENUNAME6 +Popup Menu : Icônes App +; Popup Menu: AppIcons +; +MSGID_POPMENUNAME7 +Popup Menu : Bureau +;Popup Menu: Desktop +; +;--------------------------------------------- +; +MSGID_COM1NAME +Mis en arrière-plan +; Backdrop +; +; +MSGID_COM2NAME +Executer une commande +; Execute Command +; +; +MSGID_COM3NAME +Tout retracer +; Redraw All +; +; +MSGID_COM4NAME +Tout mettre à jour +; Update All +; +; +MSGID_COM5NAME +A propos de Scalos +; About Scalos +; +; +MSGID_COM6NAME +Quitter +; Quit +; +; +MSGID_COM7NAME +Nouveau répertoire +; New Drawer +; +; +MSGID_COM8NAME +Ouvrir Parent +; Open Parent +; +; +MSGID_COM9NAME +Fermer fenêtre +; Close Window +; +; +MSGID_COM10NAME +Mettre à jour +; Update +; +; +MSGID_COM11NAME +Sélectionner le contenu +; Select Contents +; +; +MSGID_COM12NAME +Réorganiser +; Cleanup +; +; +MSGID_COM13NAME +Figer - Fenêtre +; Snapshot - Window +; +; +MSGID_COM14NAME +Figer - Tout +; Snapshot - All +; +; +MSGID_COM15NAME +Montrer - Seulement les icônes +; Show - Only Icons +; +; +MSGID_COM16NAME +Montrer - Tous les fichiers +; Show - All Files +; +; +MSGID_COM17NAME +Afficher par - Icône +; View By - Icon +; +; +MSGID_COM18NAME +Afficher par - Texte +; View By - Text +; +; +MSGID_COM19NAME +Ouvrir +; Open +; +; +MSGID_COM20NAME +Relancer Scalos +; Reset Scalos +; +; +MSGID_COM21NAME +Renommer +; Rename +; +; +MSGID_COM22NAME +Information +; Information +; +; +MSGID_COM23NAME +Figer +; Snapshot +; +; +MSGID_COM24NAME +Libérer +; UnSnapshot +; +; +MSGID_COM25NAME +Sortir +; Leave Out +; +; +MSGID_COM26NAME +Ranger +; Put Away +; +; +MSGID_COM27NAME +Effacer +; Delete +; +; +MSGID_COM28NAME +Copier +; Clone +; +; +MSGID_COM29NAME +Vider la corbeille +; Empty Trashcan +; +; +MSGID_COM30NAME +Dernier message +; Last Message +; +; +MSGID_COM31NAME +Retracer +; Redraw +; +; +MSGID_COM32NAME +Iconifier +; Iconify +; +; +MSGID_PLUGINNAME +PlugIn +; PlugIn +; +; +MSGID_COM33NAME +Formater le Volume... +; Format Disk... +; +; +MSGID_COM34NAME +Désactiver... +; Shutdown... +; +; +MSGID_COM35NAME +Ajuster la taille +; Size to fit +; +; +MSGID_COM36NAME +Ne rien sélectionner +; Clear Selection +; +; +MSGID_COM37NAME +Afficher par - Taille +; View By - Size +; +; +MSGID_COM38NAME +Afficher par - Date +; View By - Date +; +; +MSGID_ABOUTREQOK +D'accord +; _OK +; +; +MSGID_ABOUTREQFORMAT +\033cPréférences : \033bScalos Menu V\0333%ld\0331.\0333%ld\033n\0331\n\ +Compilé sous: \0333%s\0331\n\ +© 1999%s \0333The Scalos Team\033n\0331\n\ +Inspiré du programme original créé par\n\ +\033bStefan Sommerfeld\033n de \033b\0333ALiENDESiGN!\033n\0331 +; \33cScalos Menu Preferences V40.7\n\ +; © 1999-2004 The Scalos Team\n\ +; Based on original code by Stefan Sommerfeld of ALiENDESiGN! +; +; +;*** +jl+ 20011214 +MSGID_COM39NAME +Copier le fichier +; Copy file +; +; +MSGID_COM40NAME +Couper le fichier +; Cut file +; +; +MSGID_COM41NAME +Coller le fichier +; Paste file +; +; +MSGID_COM42NAME +Afficher par - Type +; View By - Type +; +; +MSGID_COM43NAME +Réorganiser par - Nom +; Cleanup By - Name +; +; +MSGID_COM44NAME +Réorganiser par - Date +; Cleanup By - Date +; +; +MSGID_COM45NAME +Réorganiser par - Taille +; Cleanup By - Size +; +; +MSGID_COM46NAME +Réorganiser par - Type +; Cleanup By - Type +; +; +MSGID_COM_ICONPROPERTIES +Propriété des icônes +;Icon properties +; +; +MSGID_COM_WINDOWPROPERTIES +Propriété des fenêtres +;Window properties +; +; +MSGID_COM47NAME +Afficher par - Défaut +;View By - Default +; +; +MSGID_COM48NAME +Montrer - Défaut +;Show - Default +; +; +MSGID_COM49NAME +Copier vers... +;Copy to... +; +; +MSGID_COM50NAME +Déplacer vers... +;Move to ... +; +; +MSGID_COM51NAME +Créer une vignette +; +; +MSGID_COM_OPENNEWWINDOW +Ouvrir dans une nouvelle fenêtre +;Open in new window +; +; +MSGID_COM_THUMBNAILCACHECLEANUP +Nettoyer le cache des vignettes +;Cleanup thumbnail cache +; +MSGID_COM_FIND +Trouver des fichiers +;Find File(s) +; +MSGID_COM_UNDO +Précédent +;Undo +; +MSGID_COM_REDO +Suivant +;Redo +; +;+++translateme+++ +MSGID_COM_OPENBROWSERWINDOW +Open in Browser Window +;Open in Browser Window +; +;--------------------------------------------- +; +MSGID_SHORTHELP_NEWMENUBUTTON +Préssez ce bouton afin de créer un nouveau menu ou\n\ +sous-menu à la position actuellement choisie. +; Press this button to create a new Menu or\n\ +; Submenu entry at the currently selected position. +; +; +MSGID_SHORTHELP_NEWITEMBUTTON +Pressez ce bouton afin d'insèrer une nouvelle entrée\n\ +à la position actuellement choisie. +; Press this button to insert a new menu\n\ +; item at the currently selected position. +; +; +MSGID_SHORTHELP_NEWCOMMANDBUTTON +Pressez ce bouton pour ajouter une nouvelle\n\ +commande à l'entrée actuelle. +; Press this button to add a new\n\ +; command to the currently menu item. +; +; +MSGID_SHORTHELP_DELBUTTON +Pressez ce bouton pour éffacer une\n\ +commande, une entrée ou un menu. +; Press this button to delete the currently\n\ +; select command, menu item, or menu. +; +; +MSGID_SHORTHELP_SAVEBUTTON +Pressez ce bouton pour sauver \n\ +les options actuelles vers :\n\ +"\033bENVARC:Scalos/menu13.prefs\033n". +; Press this button to save \n\ +; the current settings to\n\ +; \"ENVARC:Scalos/menu13.prefs\". +; +; +MSGID_SHORTHELP_USEBUTTON +Pressez ce bouton pour sauver \n\ +les options actuelles vers :\n\ +"\033bENV:Scalos/menu13.prefs\033n". +; Press this button to save \n\ +; the current settings to\n\ +; \"ENV:Scalos/menu13.prefs\". +; +; +MSGID_SHORTHELP_CANCELBUTTON +Pressez ce bouton afin d'annuler \n\ +et d'oublier tout changement. +; Press this button to abort \n\ +; and forget all changes. +; +; +MSGID_REQTITLE_SAVEERROR +Erreur pendant l'écriture du fichier\n\ +des préférences : "%s"\n\ +%s +; Error writing palette preferences\n\ +; file \"%s\"\n\ +; %s +; +; +MSGID_REQTITLE_READERROR +Erreur pendant le chargement du fichier\n\ +des préférences : "%s"\n\ +%s +; Error reading palette preferences\n\ +; file \"%s\"\n\ +; %s +; +; +MSGID_IMPORTNAME +Importer +; Import +; +; +MSGID_TITLE_IMPORTTD +Importer ToolsDaemon Prefs +; Import ToolsDaemon Prefs +; +; +MSGID_TITLE_IMPORTP +Importer ParM Prefs +; Import ParM Prefs +; +; +MSGID_PRIORITY_SLIDER_NAME +Priorité : +; Priority +; +; +MSGID_PRIORITY_SLIDER_BUBBLE +Utiliser ce glisseur pour ajuster\n\ +la priorité de lancement de la commande. +; Use this slider to adjust the priority the command should run with. +; +; new in 40.7 +; +MSGID_PLUGIN_LIST_TITLE +Menu +;Menu +; +; +MSGID_POPUP_ASLTITLE_AMIGADOS +Choix d'une commande AmigaDOS +;Select AmigaDOS command +; +; +MSGID_POPUP_ASLTITLE_WORKBENCH +Choix d'une commande Workbench +;Select Workbench command +; +; +MSGID_POPUP_ASLTITLE_ICONWINDOW +Choix d'un répertoire à ouvrir +;Select directory for icon window +; +; +MSGID_POPUP_ASLTITLE_AREXX +Choix d'un programme ARexx +;Select ARexx program +; +; +MSGID_POPUP_ASLTITLE_MENUPLUGIN +Choix d'un plugin pour le menu de Scalos +;Select Scalos Menu plugin +; +; +MSGID_MENU_PROJECT_MERGE_ASLTITLE +Choix des préférences avec lesquelles fusionner +;Select prefs to merge with +; +; +MSGID_MENU_GROUP_COMMAND_PROPERTIES +Propriétés de la commande +;Command Properties +; +; New in 40.10 +; +MSGID_SHORTHELP_LAMP_CHANGED +Cet indicateur passe de l'état \033binactif\033n\n\ +à l'état \033bactif\033n, une fois que les options\n\ +ont été modifiées depuis le chargement initial. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +; new in 40.16 +; +MSGID_POPASL_UNSELECTEDIMAGE_SHORTHELP +\033bMenu non sélectionné \033n:\n\ +Ici vous pouvez choisir une image qui sera affichée à gauche du\n\ +nom du menu, lorsque le menu ne sera pas sélectionné. +;Here you may select an iconic image that is shown left of\n\ +;the menu item name, in unselected menu item state. +; +; +MSGID_SAMPLE_UNSELECTEDIMAGE_SHORTHELP +\033bMenu non sélectionné \033n:\n\ +Ceci est un aperçu de l'image qui sera affichée à gauche du\n\ +nom du menu, lorsque le menu ne sera n'est pas sélectionné. +;This is a sample of the iconic image that will be shown\n\ +;left of the menu item name, in unselected menu item state. +; +; +MSGID_POPASL_SELECTEDIMAGE_SHORTHELP +\033bMenu sélectionné \033n:\n\ +Ici vous pouvez choisir une image qui sera affichée à gauche du\n\ +nom du menu, lorsque le menu sera sélectionné. +;Here you may select an iconic image that is shown left of\n\ +;the menu item name, in selected menu item state. +; +; +MSGID_SAMPLE_SELECTEDIMAGE_SHORTHELP +\033bMenu sélectionné \033n:\n\ +Ceci est un aperçu de l'image qui sera affichée à gauche du\n\ +nom du menu, lorsque le menu sera sélectionné. +;This is a sample of the iconic image that will be shown\n\ +;left of the menu item name, in selected menu item state. +; +MSGID_ENTRY_STRING_NAME +Nom : +;Name: +; +MSGID_ENTRY_GROUP_UNSELECTEDIMAGE +Image pour l'état non sélectionné +;Unselected State Image +; +MSGID_ENTRY_GROUP_SELECTEDIMAGE +Image pour l'état sélectionné +;Selected State Image +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Le lancement de Scalos Prefs a échoué +;Scalos Menu Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Recommençer|Quitter +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +Celle-ci n'est pas installée. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +\n\ +La version installée est V%lu.%lu, installez-en une plus récente s'il vous plaît ! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +%lu.%lu est actuellement utilisée par d'autres applications.\n\ +\n\ +Une fois la version requise installée,\n\ +fermez tous les programmes MUI, soyez sûr que l'ancienne classe\n\ +ne soit plus présente dans la mémoire puis, essayez de nouveau. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_NEW_MENU +Nouveau menu +;New Menu +; +; +MSGID_NEW_ITEM +Nouvelle entrée +;New Item +; +MSGID_TOOLS_MENU +Outils +;Tools +; +;----------------------------------------------------------- +; +MSGID_DEFAULT_MENU_OPEN +Ouvrir +;Open +; +MSGID_DEFAULT_MENU_OPEN_SHORT +O +;O +; +MSGID_DEFAULT_MENU_INFORMATION +Information... +;Information... +; +MSGID_DEFAULT_MENU_INFORMATION_SHORT +I +;I +; +MSGID_DEFAULT_MENU_BROWSE +Naviguer... +;Browse... +; +MSGID_DEFAULT_MENU_BROWSE_SHORT + +; +MSGID_DEFAULT_MENU_FIND +Chercher... +;Find... +; +MSGID_DEFAULT_MENU_FIND_SHORT +F +;F +; +MSGID_DEFAULT_MENU_SNAPSHOT +Figer +;Snapshot +; +MSGID_DEFAULT_MENU_SNAPSHOT_SHORT +S +;S +; +MSGID_DEFAULT_MENU_UNSNAPSHOT +Libèrer +;Unsnapshot +; +MSGID_DEFAULT_MENU_UNSNAPSHOT_SHORT +L +;U +; +MSGID_DEFAULT_MENU_CLONE +Dupliquer +;Clone +; +MSGID_DEFAULT_MENU_CLONE_SHORT +D +;C +; +MSGID_DEFAULT_MENU_COPY +Copier +;Copy +; +MSGID_DEFAULT_MENU_COPY_SHORT +C +; +MSGID_DEFAULT_MENU_CUT +Couper +;Cut +; +MSGID_DEFAULT_MENU_CUT_SHORT +X +; +MSGID_DEFAULT_MENU_PASTE +Coller +;Paste +; +MSGID_DEFAULT_MENU_PASTE_SHORT +V +; +MSGID_DEFAULT_MENU_DISKCOPY +Duplquer le volume... +;Diskcopy... +; +MSGID_DEFAULT_MENU_DISKCOPY_SHORT + +; +MSGID_DEFAULT_MENU_RELABEL +Renommer le volume... +;Relabel... +; +MSGID_DEFAULT_MENU_RELABEL_SHORT + +; +MSGID_DEFAULT_MENU_FORMAT +Formatter le volume... +;Format... +; +MSGID_DEFAULT_MENU_FORMAT_SHORT +F +; +MSGID_DEFAULT_MENU_PROPERTIES +Propriètés... +;Properties... +; +MSGID_DEFAULT_MENU_PROPERTIES_SHORT + +; +MSGID_DEFAULT_MENU_EDIT +Edition +;Edit +; +MSGID_DEFAULT_MENU_RENAME +Renommer +;Rename +; +MSGID_DEFAULT_MENU_RENAME_SHORT +R +;R +; +MSGID_DEFAULT_MENU_LEAVEOUT +Sortir +;Leave Out +; +MSGID_DEFAULT_MENU_LEAVEOUT_SHORT +L +;L +; +MSGID_DEFAULT_MENU_PUTAWAY +Ranger +;Put Away +; +MSGID_DEFAULT_MENU_PUTAWAY_SHORT +P +;P +; +MSGID_DEFAULT_MENU_DELETE +Effacer... +;Delete... +; +MSGID_DEFAULT_MENU_DELETE_SHORT + +; +MSGID_DEFAULT_MENU_EMPTYTRASH +Vider la corbeille... +;Empty Trashcan... +; +MSGID_DEFAULT_MENU_EMPTYTRASH_SHORT + +; +MSGID_DEFAULT_MENU_CLOSE +Fermer +;Close +; +MSGID_DEFAULT_MENU_CLOSE_SHORT +K +; +MSGID_DEFAULT_MENU_OPENPARENT +Ouvrir parent +;Open Parent +; +MSGID_DEFAULT_MENU_OPENPARENT_SHORT + +; +MSGID_DEFAULT_MENU_UPDATE +Mettre à jour +;Update +; +MSGID_DEFAULT_MENU_UPDATE_SHORT +M +;M +; +MSGID_DEFAULT_MENU_CLEANUP +Nettoyer +;Cleanup +; +MSGID_DEFAULT_MENU_CLEANUP_SHORT + +; +MSGID_DEFAULT_MENU_RESIZETOFIT +Ajuster la taille +;Resize To Fit +; +MSGID_DEFAULT_MENU_RESIZETOFIT_SHORT + +; +MSGID_DEFAULT_MENU_SELECTCONTENTS +Saisir le contenu +;Select Contents +; +MSGID_DEFAULT_MENU_SELECTCONTENTS_SHORT +T +;A +; +MSGID_DEFAULT_MENU_CLEARSELECTION +Ne rien sélectionner +;Clear Selection +; +MSGID_DEFAULT_MENU_CLEARSELECTION_SHORT +Z +;Z +; +MSGID_DEFAULT_MENU_SNAPSHOT_ALL +Tout +;All +; +MSGID_DEFAULT_MENU_SNAPSHOT_ALL_SHORT + +; +MSGID_DEFAULT_MENU_SNAPSHOT_WINDOW +Fenêtre +;Window +; +MSGID_DEFAULT_MENU_SNAPSHOT_WINDOW_SHORT +W +;W +; +MSGID_DEFAULT_MENU_NEWDRAWER +Nouveau répertoire... +;New Drawer... +; +MSGID_DEFAULT_MENU_NEWDRAWER_SHORT +N +; +MSGID_DEFAULT_MENU_SCALOS +Scalos +;Scalos +; +MSGID_DEFAULT_MENU_WINDOW +Fenêtre +;Window +; +MSGID_DEFAULT_MENU_ICONS +Icônes +;Icons +; +MSGID_DEFAULT_MENU_DRAWERS +Répertoires +;Drawers +; +MSGID_DEFAULT_MENU_PREFS +Préferences +;Prefs +; +MSGID_DEFAULT_MENU_BACKDROP +Mis en arrière-plan +;Backdrop? +; +MSGID_DEFAULT_MENU_BACKDROP_SHORT +B +;B +; +MSGID_DEFAULT_MENU_EXECUTECOMMAND +Executer une commande... +;Execute Command... +; +MSGID_DEFAULT_MENU_EXECUTECOMMAND_SHORT +E +;E +; +MSGID_DEFAULT_MENU_REDRAWALL +Tout retracer +;Redraw All +; +MSGID_DEFAULT_MENU_REDRAWALL_SHORT + +; +MSGID_DEFAULT_MENU_UPDATEALL +Tout mettre à jourl +;Update All +; +MSGID_DEFAULT_MENU_UPDATEALL_SHORT + +; +MSGID_DEFAULT_MENU_LASTMESSAGE +Dernier message +;Last Message +; +MSGID_DEFAULT_MENU_LASTMESSAGE_SHORT + +; +MSGID_DEFAULT_MENU_ABOUT +A propos... +;About... +; +MSGID_DEFAULT_MENU_ABOUT_SHORT +? +;? +; +MSGID_DEFAULT_MENU_QUIT +Quitter... +;Quit... +; +MSGID_DEFAULT_MENU_QUIT_SHORT +Q +; +MSGID_DEFAULT_MENU_CLEANUPBY +Réorganiser par +;Clean up by +; +MSGID_DEFAULT_MENU_CLEANUPBY_COLUMN +Colonne +;Column +; +MSGID_DEFAULT_MENU_CLEANUPBY_COLUMN_SHORT +. +;. +; +MSGID_DEFAULT_MENU_CLEANUPBY_NAME +Non +;Name +; +MSGID_DEFAULT_MENU_CLEANUPBY_NAME_SHORT + +; +MSGID_DEFAULT_MENU_CLEANUPBY_DATE +Date +;Date +; +MSGID_DEFAULT_MENU_CLEANUPBY_DATE_SHORT + +; +MSGID_DEFAULT_MENU_CLEANUPBY_SIZE +Taille +;Size +; +MSGID_DEFAULT_MENU_CLEANUPBY_SIZE_SHORT + +; +MSGID_DEFAULT_MENU_CLEANUPBY_TYPE +Type +;Type +; +MSGID_DEFAULT_MENU_CLEANUPBY_TYPE_SHORT + +; +MSGID_DEFAULT_MENU_SHOW +Afficher +;Show +; +MSGID_DEFAULT_MENU_SHOW_DEFAULT +Defaut +;Default +; +MSGID_DEFAULT_MENU_SHOW_DEFAULT_SHORT + +; +MSGID_DEFAULT_MENU_SHOW_ONLYICONS +Icônes seulement +;Only Icons +; +MSGID_DEFAULT_MENU_SHOW_ONLYICONS_SHOT +- +;- +; +MSGID_DEFAULT_MENU_SHOW_ALLFILES +Tous les fichiers +;All Files +; +MSGID_DEFAULT_MENU_SHOW_ALLFILES_SHORT ++ +;+ +; +MSGID_DEFAULT_MENU_VIEWBY +Afficher par +;View By +; +MSGID_DEFAULT_MENU_VIEWBY_DEFAULT +Défaut +;Default +; +MSGID_DEFAULT_MENU_VIEWBY_DEFAULT_SHORT + +; +MSGID_DEFAULT_MENU_VIEWBY_ICON +Icônes +;Icon +; +MSGID_DEFAULT_MENU_VIEWBY_ICON_SHORT +1 +;1 +; +MSGID_DEFAULT_MENU_VIEWBY_NAME +Nom +;Name +; +MSGID_DEFAULT_MENU_VIEWBY_NAME_SHORT +2 +;2 +; +MSGID_DEFAULT_MENU_VIEWBY_DATE +Date +;Date +; +MSGID_DEFAULT_MENU_VIEWBY_DATE_SHORT +3 +;3 +; +MSGID_DEFAULT_MENU_VIEWBY_SIZE +Taille +;Size +; +MSGID_DEFAULT_MENU_VIEWBY_SIZE_SHORT +4 +;4 +; +MSGID_DEFAULT_MENU_VIEWBY_TYPE +Type +;Type +; +MSGID_DEFAULT_MENU_VIEWBY_TYPE_SHORT +5 +;5 +; +MSGID_DEFAULT_MENU_RESETSCALOS +Relancer Scalos +;Reset Scalos +; +MSGID_DEFAULT_MENU_RESETSCALOS_SHORT + +; +MSGID_DEFAULT_MENU_NEWSHELL +Nouveau Shell +;New Shell +; +MSGID_DEFAULT_MENU_NEWSHELL_SHORT + +; +MSGID_DEFAULT_MENU_DRAWERS_VOYAGER +Voyager +;Voyager +; +MSGID_DEFAULT_MENU_DRAWERS_VOYAGER_SHORT + +; +MSGID_DEFAULT_MENU_DRAWERS_ENVARC_SYS +ENVARC:Sys +;ENVARC:Sys +; +MSGID_DEFAULT_MENU_DRAWERS_ENVARC_SYS_SHORT + +; +MSGID_DEFAULT_MENU_DRAWERS_WBSTARTUP +WBStartup +;WBStartup +; +MSGID_DEFAULT_MENU_DRAWERS_WBSTARTUP_SHORT + +; +MSGID_DEFAULT_MENU_DRAWERS_PREFS +Prefs +;Prefs +; +MSGID_DEFAULT_MENU_DRAWERS_PREFS_SHORT + +; +MSGID_DEFAULT_MENU_DRAWERS_SCALOSPREFS +Scalos Prefs +;Scalos Prefs +; +MSGID_DEFAULT_MENU_DRAWERS_SCALOSPREFS_SHORT + +; +MSGID_DEFAULT_MENU_PREFS_SYSTEM +Système... +;System... +; +MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT + +; +MSGID_DEFAULT_MENU_PREFS_MUI +MUI... +;MUI... +; +MSGID_DEFAULT_MENU_PREFS_MUI_SHORT + +; +MSGID_DEFAULT_MENU_PREFS_AHI +AHI... +;AHI... +; +MSGID_DEFAULT_MENU_PREFS_AHI_SHORT + +; +MSGID_DEFAULT_MENU_PREFS_SCALOS +Scalos Prefs... +;Scalos Prefs... +; +MSGID_DEFAULT_MENU_PREFS_SCALOS_SHORT + +; +MSGID_DEFAULT_MENU_EMPTY_SHORT + +; +MSGID_DEFAULT_TOOLS +Outils +;Tools +; +MSGID_DEFAULT_UTILITIES +Utilités +;Utilities +; +MSGID_DEFAULT_PREFERENCES +Préférences +;Preferences +; +MSGID_DEFAULT_EXCHANGE +Commodité Exchange +;Exchange +; +MSGID_DEFAULT_MENU_TOOLS_MOUNTER +Monter +;Mounter +; +MSGID_DEFAULT_MENU_TOOLS_SCSICONFIG +Configuration avec SCSIConfig +;SCSIConfig +; +MSGID_DEFAULT_MENU_TOOLS_SNOOPIUM +Snoopium +;Snoopium +; +MSGID_DEFAULT_MENU_TOOLS_DEFRAG +Défragmentation +;Defrag +; +MSGID_DEFAULT_MENU_TOOLS_FTMANAGER +Configuration avec FTManager +;FTManager +; +MSGID_DEFAULT_MENU_TOOLS_MUISHELL +Shell MUI +;MUIShell +; +MSGID_DEFAULT_MENU_TOOLS_SFSDOCTOR +Gestion SFS sous SFSDoctor +;SFSDoctor +; +MSGID_DEFAULT_MENU_TOOLS_UNITCONTROL +Configuration avec UnitControl +;UnitControl +; +MSGID_DEFAULT_MENU_TOOLS_FILEIMAGECTRL +FileImageCtrl +;FileImageCtrl +; +MSGID_DEFAULT_MENU_TOOLS_HDCONFIG +Configuration avec HDConfig +;HDConfig +; +MSGID_DEFAULT_MENU_TOOLS_REGTOOL +Enregistement avec RegTool +;RegTool +; +MSGID_DEFAULT_MENU_TOOLS_SHELL +Shell +;Shell +; +MSGID_DEFAULT_MENU_UTILITIES_EDITOR +Editeur +;Editor +; +MSGID_DEFAULT_MENU_UTILITIES_FRAGMENT +Fragmentation +;Fragment +; +MSGID_DEFAULT_MENU_UTILITIES_GRABBER +Capture d'écran +;Grabber +; +MSGID_DEFAULT_MENU_UTILITIES_GRAPHICBOARDS +Carte graphique +;GraphicBoards +; +MSGID_DEFAULT_MENU_UTILITIES_KEYSTROKE +Keystroke +;Keystroke +; +MSGID_DEFAULT_MENU_UTILITIES_MINICALC +Mini Calculette +;MiniCalc +; +MSGID_DEFAULT_MENU_UTILITIES_MORE +Visionneur More +;More +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MUIPROCALC +MUIProCalc +;MUIProCalc +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MULTIVIEW +Multiview +;Multiview +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MYSTICVIEW +MysticView +;MysticView +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_TASKMANAGER +TaskManager +;TaskManager +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_TRANCESTATS +Trancestats +;Trancestats +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_TIPS +Tips +;Tips +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_ZOOM +Zoom +;Zoom +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_AMIGS +AmiGS +;AmiGS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_AMIPDF +AmiPDF +;AmiPDF +; +MSGID_DEFAULT_MENU_UTILITIES_SGRAB +capture d'écran avec SGrab +;SGrab +; +MSGID_DEFAULT_MENU_UTILITIES_CALCULATOR +Calculette +;Calculator +; +MSGID_DEFAULT_MENU_UTILITIES_CLOCK +Horloge +;Clock +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_GRAPHICDUMP +GraphicDump +;GraphicDump +; +MSGID_DEFAULT_MENU_UTILITIES_ICONEDIT +Editeur d'icônes +;IconEdit +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_INITPRINTER +InitPrinter +;InitPrinter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_KEYSHOW +KeyShow +;KeyShow +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MEMACS +MEmacs +;MEmacs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_NOTEPAD +Notepad +;Notepad +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PARTITIONWIZARD +Partition Wizard +;Partition Wizard +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PLAYCD +PlayCD +;PlayCD +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PREFSOBJECTSEDITOR +PrefsObjectsEditor +;PrefsObjectsEditor +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PRINTFILES +PrintFiles +;PrintFiles +; +MSGID_DEFAULT_MENU_UTILITIES_RAWDISK +Volume Raw +;RawDisk +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_SHOWCONFIG +ShowConfig +;ShowConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_UNARC +UnArc +;UnArc +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_USBINSPECTOR +USBInspector +;USBInspector +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_AMIGAINPUT +AmigaInput +;AmigaInput +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_ASL +ASL +;ASL +; +MSGID_DEFAULT_MENU_PREFS_COMPATIBILITY +Compatibilité +;Compatibility +; +; +MSGID_DEFAULT_MENU_PREFS_DEFICONS +Icônes par défaut +;DefIcons +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_DOS +DOS +;DOS +; +MSGID_DEFAULT_MENU_PREFS_FONT +Polices de caractères +;Font +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_GUI +GUI +;GUI +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_INPUT +Input +;Input +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_INTERNET +Internet +;Internet +; +MSGID_DEFAULT_MENU_PREFS_LOCALE +Localité +;Locale +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_NOTIFICATIONS +Notifications +;Notifications +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PALETTE +Palette +;Palette +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PICASSO96MODE +Picasso96Mode +;Picasso96Mode +; +MSGID_DEFAULT_MENU_PREFS_POINTER +Curseur +;Pointer +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_POPUPMENU +PopupMenu +;PopupMenu +; +MSGID_DEFAULT_MENU_PREFS_PRINTER +Imprimante +;Printer +; +MSGID_DEFAULT_MENU_PREFS_PRINTERGFX +Imprimante GFX +;PrinterGFX +; +MSGID_DEFAULT_MENU_PREFS_PRINTERPS +Imprimante PS +;PrinterPS +; +MSGID_DEFAULT_MENU_PREFS_SCREENBLANKER +Economiseur d'écran +;ScreenBlanker +; +MSGID_DEFAULT_MENU_PREFS_SCREENMODE +Modes d'écran +;ScreenMode +; +MSGID_DEFAULT_MENU_PREFS_SCREENS +Ecrans +;Screens +; +MSGID_DEFAULT_MENU_PREFS_SERIAL +Série +;Serial +; +MSGID_DEFAULT_MENU_PREFS_SOUND +Son +;Sound +; +MSGID_DEFAULT_MENU_PREFS_TIME +Heure +;Time +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_URL +URL +;URL +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_USB +USB +;USB +; +MSGID_DEFAULT_MENU_PREFS_WBPATTERN +Motifs de fonds +;WBPattern +; +MSGID_DEFAULT_MENU_PREFS_WBSTARTUP +Démarrage WB +;WBStartup +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WORKBENCH +Workbench +;Workbench +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_INTELLIFONT +IntelliFont +;IntelliFont +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_GRAPHICDUMP +GraphicDump +;GraphicDump +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_WBCLOCK +WBClock +;WBClock +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_CACHECDFS +CacheCDFS +;CacheCDFS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_ICONTROL +IControl +;IControl +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_OVERSCAN +Overscan +;Overscan +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_REACTION +Reaction +;Reaction +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_VINCED +ViNCDe +;ViNCDe +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WARPOS +WarpOS +;WarpOS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_BENCHTRASH +BenchTrash +;BenchTrash +; +MSGID_DEFAULT_MENU_TOOLS_CALCULATOR +Calculette +;Calculator +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_EDITPAD +EditPad +;EditPad +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_HDTOOLBOX +HDToolBox +;HDToolBox +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_ICONEDIT +IconEdit +;IconEdit +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_INITPRINTER +InitPrinter +;InitPrinter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_IOTOOLS +IoTools +;IoTools +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_KEYSHOW +KeyShow +;KeyShow +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_LACER +Lacer +;Lacer +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_MEMACS +MEmacs +;MEmacs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_PREPCARD +PrepCard +;PrepCard +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_PRINTFILES +PrintFiles +;PrintFiles +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SHOWCONFIG +ShowConfig +;ShowConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_UNARC +Unarc +;Unarc +; +MSGID_DEFAULT_SYSTEM +Système +;System +; +MSGID_DEFAULT_MENU_SYSTEM_FIND +Chercher... +;Find... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_FIXFONT +FixFont +;FixFont +; +MSGID_DEFAULT_MENU_SYSTEM_FORMAT +Formater... +;Format... +; +MSGID_DEFAULT_MENU_SYSTEM_SHELL +Nouveau Shell +;Shell +; +MSGID_DEFAULT_MENU_SYSTEM_FORMATCDRW +Formater le CDRW +;FormatCDRW +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_MEDIATOOLBOX +MediaToolBox +;MediaToolBox +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_MOUNTER +Mounter +;Mounter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_TYPEMANAGER +TypeManager +;TypeManager +; +MSGID_DEFAULT_MENU_SYSTEM_HELP +Aide +;Help +; +;----------------------------------------------------------- +; diff --git "a/scalos/Prefs/Menu/Catalogs/fran\303\247ais/Scalos/config.mk" "b/scalos/Prefs/Menu/Catalogs/fran\303\247ais/Scalos/config.mk" new file mode 100755 index 000000000..8b7056423 --- /dev/null +++ "b/scalos/Prefs/Menu/Catalogs/fran\303\247ais/Scalos/config.mk" @@ -0,0 +1,40 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = français + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = french + +else + +############################################################################### +# AmigaOS and AROS + +LANG = français + +endif +endif diff --git "a/scalos/Prefs/Menu/Catalogs/fran\303\247ais/Scalos/makefile" "b/scalos/Prefs/Menu/Catalogs/fran\303\247ais/Scalos/makefile" new file mode 100644 index 000000000..355e07b89 --- /dev/null +++ "b/scalos/Prefs/Menu/Catalogs/fran\303\247ais/Scalos/makefile" @@ -0,0 +1,13 @@ +# makefile for Scalos (translated Texts : français) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mfrançais\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +ScalosMenu.catalog : ScalosMenu.ct ../../../ScalosMenu.cd + +All: ScalosMenu.catalog diff --git "a/scalos/Prefs/Menu/Catalogs/fran\303\247ais/Scalos/makefile-new" "b/scalos/Prefs/Menu/Catalogs/fran\303\247ais/Scalos/makefile-new" new file mode 100755 index 000000000..b9b546cd7 --- /dev/null +++ "b/scalos/Prefs/Menu/Catalogs/fran\303\247ais/Scalos/makefile-new" @@ -0,0 +1,32 @@ +# makefile for ScalosMenu (translated Texts : français) +# $Date: 2011-08-06 19:37:48 +0200 (Sa, 06. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = ScalosMenu + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Prefs/Menu/Catalogs/italiano/Scalos/ScalosMenu.ct b/scalos/Prefs/Menu/Catalogs/italiano/Scalos/ScalosMenu.ct new file mode 100644 index 000000000..3f5ce8d76 --- /dev/null +++ b/scalos/Prefs/Menu/Catalogs/italiano/Scalos/ScalosMenu.ct @@ -0,0 +1,1936 @@ +; ScalosMenu.ct +## version $VER: ScalosMenu.catalog 40.18 (24 Aug 2006 10:22:50) +## codeset 0 +## language italiano +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Menu Plugin Scalos +; +; +MSGID_TITLENAME_CMDLIST +Scalos Internal Menu Commands +; +; +MSGID_FRAMETITLE +Lista dei menu +; +; +MSGID_NEWINAME +Nuova voce +; +; +MSGID_HOTKEYNAME +Tasto +; +; +MSGID_NEWNAME +Nuovo menu +; +; +MSGID_DELNAME +Cancella +; +; +MSGID_SAVENAME +Salva +; +; +MSGID_USENAME +Usa +; +; +MSGID_CANCELNAME +Annulla +; +; +MSGID_NEW2NAME +Nuovo comando +; +; +MSGID_COMMANDNAME +Comando +; +; +MSGID_MENU_PROJECT_IMPORT +Importa +; +; +MSGID_MENU_PROJECT_IMPORT_SHORT +I +; +; +MSGID_MENU_PROJECT_OPEN +Apri... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +O +; +; +MSGID_MENU_PROJECT_SAVEAS +Salva come... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +A +; +; +MSGID_MENU_PROJECT_QUIT +Fine +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +; +MSGID_MENU_PROJECT +Progetto +; +; +MSGID_MENU_EDIT_LASTSAVED +Ripristina ultimi valori +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +L +; +; +MSGID_MENU_EDIT +Modifica +; +; +MSGID_MENU_SETTINGS_CREATEICONS +Crea icone? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +I +; +; +MSGID_MENU_SETTINGS +Opzioni +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +Ripristina predefiniti +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +D +; +; +MSGID_MENU_EDIT_RESTORE +Annulla modifiche +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +R +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Info su MUI... +; +; +MSGID_WBNAME +Workbench +; +; +MSGID_ADOSNAME +AmigaDOS +; +; +MSGID_STACKNAME +Stack +; +; +MSGID_MAINMENUNAME +Menu principale +; +; +MSGID_COM1NAME +Pannello +; +; +MSGID_COM2NAME +Eseguire comando +; +; +MSGID_COM3NAME +Ridisegnare tutto +; +; +MSGID_COM4NAME +Aggiornare tutto +; +; +MSGID_COM5NAME +Info su Scalos +; +; +MSGID_COM6NAME +Fine +; +; +MSGID_COM7NAME +Nuovo cassetto +; +; +MSGID_COM8NAME +Aprire precedente +; +; +MSGID_COM9NAME +Chiudere +; +; +MSGID_COM10NAME +Aggiornare +; +; +MSGID_COM11NAME +Selezionare contenuto +; +; +MSGID_COM12NAME +Ridisporre icone +; +; +MSGID_COM13NAME +Fissare finestra +; +; +MSGID_COM14NAME +Fissare tutto +; +; +MSGID_COM15NAME +Mostrare solo le icone +; +; +MSGID_COM16NAME +Mostrare tutti i file +; +; +MSGID_COM17NAME +Mostrare per icona +; +; +MSGID_COM18NAME +Mostrare per testo +; +; +MSGID_COM19NAME +Aprire +; +; +MSGID_COM20NAME +Ripristinare Scalos +; +; +MSGID_COM21NAME +Rinominare +; +; +MSGID_COM22NAME +Informazioni +; +; +MSGID_COM23NAME +Fissare +; +; +MSGID_COM24NAME +Annullare fissaggio +; +; +MSGID_COM25NAME +Estrarre +; +; +MSGID_COM26NAME +Reinserire +; +; +MSGID_COM27NAME +Cancellare +; +; +MSGID_BARNAME +\033C +; +; +MSGID_UPNAME +Su +; +; +MSGID_DOWNNAME +Giù +; +; +MSGID_MENU_PROJECT_IMPORT_TD +ToolsDaemon... +; +; +MSGID_MENU_PROJECT_IMPORT_TD_SHORT +T +; +; +MSGID_MENU_PROJECT_IMPORT_P +Parm... +; +; +MSGID_MENU_PROJECT_IMPORT_P_SHORT +P +; +; +MSGID_COM28NAME +Copiare +; +; +MSGID_ICONWINNAME +Apri finestra +; +; +MSGID_AREXXNAME +Arexx +; +;+++translateme+++ +MSGID_MENU_EDIT_COPY +Copy +;Copy +; +;+++translateme+++ +MSGID_MENU_EDIT_CUT +Cut +;Cut +; +;+++translateme+++ +MSGID_MENU_EDIT_PASTE +Paste +;Paste +; +;+++translateme+++ +MSGID_MENU_EDIT_COLLAPSE +Collapse Selected +;Collapse Selected +; +;+++translateme+++ +MSGID_MENU_EDIT_EXPAND +Expand Selected +;Expand Selected +; +;--------------------------------------------- +; +MSGID_POPMENUNAME1 +Menu popup: Icone dischi +; +; +MSGID_POPMENUNAME2 +Menu popup: Icone cassetti +; +; +MSGID_POPMENUNAME3 +Menu popup: Icone tool/progetto +; +; +MSGID_POPMENUNAME4 +Menu popup: Icone cestino +; +; +MSGID_POPMENUNAME5 +Menu popup: Finestre +; +; +MSGID_ARGSNAME +Argomenti WB: +; +; +MSGID_COM29NAME +Svuotare cestino +; +; +MSGID_COM30NAME +Ultimo messaggio +; +; +MSGID_COM31NAME +Ridisegnare +; +; +MSGID_COM32NAME +Iconificare +; +; +MSGID_PLUGINNAME +PlugIn +; +; +MSGID_MENU_PROJECT_MERGE +Accoda... +; +; +MSGID_MENU_PROJECT_MERGE_SHORT +M +; +; +MSGID_MENU_EDIT_COLLAPSEALL +Collapse All +; +; +MSGID_MENU_EDIT_EXPANDALL +Expand All +; +;+++translateme+++ +MSGID_MENU_SETTINGS_HIDEOBSOLETE +Hide Obsolete? +;Hide Obsolete? +; +;+++translateme+++ +MSGID_MENU_SETTINGS_HIDEOBSOLETE_SHORT +If checked, obsolete popup menus which are now\n\ +defined via filetypes prefs are not shown. +;If checked, obsolete popup menus which are now\n\ +;defined via filetypes prefs are not shown. +; +; +MSGID_COM33NAME +Format Disk... +; +; +MSGID_COM34NAME +Shutdown... +; +; +MSGID_COM35NAME +Size to fit +; +; +MSGID_COM36NAME +Clear Selection +; +; +MSGID_POPMENUNAME6 +Popup Menu: AppIcons +; +;+++translateme+++ +MSGID_POPMENUNAME7 +Popup Menu: Desktop +;Popup Menu: Desktop +; +; +MSGID_COM37NAME +View By - Size +; +; +MSGID_COM38NAME +View By - Date +; +; +MSGID_MENU_PROJECT_ABOUT +About... +; +; +MSGID_ABOUTREQOK +_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Menu Preferences V%ld.%ld\033n\n\ +%s\n\ +© 1999%s The Scalos Team\n\ +Based on original code by Stefan Sommerfeld of ALiENDESiGN! +; +; +;*** +jl+ 20011214 +MSGID_COM39NAME +Copy file +; +; +MSGID_COM40NAME +Cut file +; +; +MSGID_COM41NAME +Paste file +; +; +MSGID_COM42NAME +View By - Type +; +; +MSGID_COM43NAME +Cleanup By - Name +; +; +MSGID_COM44NAME +Cleanup By - Date +; +; +MSGID_COM45NAME +Cleanup By - Size +; +; +MSGID_COM46NAME +Cleanup By - Type +; +;+++translateme+++ +MSGID_COM_ICONPROPERTIES +Icon properties +;Icon properties +; +;+++translateme+++ +MSGID_COM_WINDOWPROPERTIES +Window properties +;Window properties +; +;+++translateme+++ +MSGID_COM47NAME +View By - Default +; +;+++translateme+++ +MSGID_COM48NAME +Show - Default +; +;+++translateme+++ +MSGID_COM49NAME +Copy to... +;Copy to... +; +;+++translateme+++ +MSGID_COM50NAME +Move to... +;Move to... +; +;+++translateme+++ +MSGID_COM51NAME +Create thumbnail +; +;+++translateme+++ +MSGID_COM_OPENNEWWINDOW +Open in new window +;Open in new window +; +;+++translateme+++ +MSGID_COM_THUMBNAILCACHECLEANUP +Cleanup thumbnail cache +; +;+++translateme+++ +MSGID_COM_FIND +Find File(s) +;Find File(s) +; +;+++translateme+++ +MSGID_COM_UNDO +Undo +;Undo +; +;+++translateme+++ +MSGID_COM_REDO +Redo +;Redo +; +;+++translateme+++ +MSGID_COM_OPENBROWSERWINDOW +Open in Browser Window +;Open in Browser Window +; +;--------------------------------------------- +; +MSGID_SHORTHELP_NEWMENUBUTTON +Press this button to create a new Menu or\n\ +Submenu entry at the currently selected position. +; +; +MSGID_SHORTHELP_NEWITEMBUTTON +Press this button to insert a new menu\n\ +item at the currently selected position. +; +; +MSGID_SHORTHELP_NEWCOMMANDBUTTON +Press this button to add a new\n\ +command to the currently menu item. +; +; +MSGID_SHORTHELP_DELBUTTON +Press this button to delete the currently\n\ +select command, menu item, or menu. +; +; +MSGID_SHORTHELP_SAVEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENVARC:Scalos/menu13.prefs\". +; +; +MSGID_SHORTHELP_USEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENV:Scalos/menu13.prefs\". +; +; +MSGID_SHORTHELP_CANCELBUTTON +Press this button to abort \n\ +and forget all changes. +; +; +MSGID_REQTITLE_SAVEERROR +Error writing palette preferences\n\ +file \"%s\"\n\ +%s +; +; +MSGID_REQTITLE_READERROR +Error reading palette preferences\n\ +file \"%s\"\n\ +%s +; +; +MSGID_IMPORTNAME +Import +; +; +MSGID_TITLE_IMPORTTD +Import ToolsDaemon Prefs +; +; +MSGID_TITLE_IMPORTP +Import ParM Prefs +; +; +MSGID_PRIORITY_SLIDER_NAME +Priority +; +; +MSGID_PRIORITY_SLIDER_BUBBLE +Use this slider to adjust the priority the command should run with. +; +; new in 40.7 +; +MSGID_PLUGIN_LIST_TITLE +Menu +; +; +MSGID_POPUP_ASLTITLE_AMIGADOS +Select AmigaDOS command +; +; +MSGID_POPUP_ASLTITLE_WORKBENCH +Select Workbench command +; +; +MSGID_POPUP_ASLTITLE_ICONWINDOW +Select directory for icon window +; +; +MSGID_POPUP_ASLTITLE_AREXX +Select ARexx program +; +; +MSGID_POPUP_ASLTITLE_MENUPLUGIN +Select Scalos Menu plugin +; +; +MSGID_MENU_PROJECT_MERGE_ASLTITLE +Select prefs to merge with +; +; +MSGID_MENU_GROUP_COMMAND_PROPERTIES +Command Properties +; +; new in 40.10 +; +; +++translateme+++ +MSGID_SHORTHELP_LAMP_CHANGED +This lamp indicator changes from \033bOff\033n\n\ +to \033bOk\033n when the settings have been\n\ +modified since initial loading. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +; new in 40.16 +; +; +++translateme+++ +MSGID_POPASL_UNSELECTEDIMAGE_SHORTHELP +Here you may select an iconic image that is shown left of\n\ +the menu item name, in unselected menu item state. +;Here you may select an iconic image that is shown left of\n\ +;the menu item name, in unselected menu item state. +; +; +++translateme+++ +MSGID_SAMPLE_UNSELECTEDIMAGE_SHORTHELP +This is a sample of the iconic image that will be shown\n\ +left of the menu item name, in unselected menu item state. +;This is a sample of the iconic image that will be shown\n\ +;left of the menu item name, in unselected menu item state. +; +; +++translateme+++ +MSGID_POPASL_SELECTEDIMAGE_SHORTHELP +Here you may select an iconic image that is shown left of\n\ +the menu item name, in selected menu item state. +;Here you may select an iconic image that is shown left of\n\ +;the menu item name, in selected menu item state. +; +; +; +++translateme+++ +MSGID_SAMPLE_SELECTEDIMAGE_SHORTHELP +This is a sample of the iconic image that will be shown\n\ +left of the menu item name, in selected menu item state. +;This is a sample of the iconic image that will be shown\n\ +;left of the menu item name, in selected menu item state. +; +;+++translateme+++ +MSGID_ENTRY_STRING_NAME +Name: +;Name: +; +;+++translateme+++ +MSGID_ENTRY_GROUP_UNSELECTEDIMAGE +Unselected State Image +;Unselected State Image +; +;+++translateme+++ +MSGID_ENTRY_GROUP_SELECTEDIMAGE +Selected State Image +;Selected State Image +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Scalos Menu Prefs startup failed +;Scalos Menu Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Try again|Quit +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_NEW_MENU +New Menu +;New Menu +; +;+++translateme+++ +MSGID_NEW_ITEM +New Item +;New Item +; +;+++translateme+++ +MSGID_TOOLS_MENU +Tools +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_DEFAULT_MENU_OPEN +Open +;Open +; +;+++translateme+++ +MSGID_DEFAULT_MENU_OPEN_SHORT +O +;O +; +;+++translateme+++ +MSGID_DEFAULT_MENU_INFORMATION +Information... +;Information... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_INFORMATION_SHORT +I +;I +; +;+++translateme+++ +MSGID_DEFAULT_MENU_BROWSE +Browse... +;Browse... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_BROWSE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_FIND +Find... +;Find... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_FIND_SHORT +F +;F +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT +Snapshot +;Snapshot +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT_SHORT +S +;S +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UNSNAPSHOT +Unsnapshot +;Unsnapshot +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UNSNAPSHOT_SHORT +U +;U +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLONE +Clone +;Clone +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLONE_SHORT +C +;C +; +;+++translateme+++ +MSGID_DEFAULT_MENU_COPY +Copy +;Copy +; +;+++translateme+++ +MSGID_DEFAULT_MENU_COPY_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CUT +Cut +;Cut +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CUT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PASTE +Paste +;Paste +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PASTE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DISKCOPY +Diskcopy... +;Diskcopy... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DISKCOPY_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RELABEL +Relabel... +;Relabel... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RELABEL_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_FORMAT +Format... +;Format... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_FORMAT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PROPERTIES +Properties... +;Properties... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PROPERTIES_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EDIT +Edit +;Edit +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RENAME +Rename +;Rename +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RENAME_SHORT +R +;R +; +;+++translateme+++ +MSGID_DEFAULT_MENU_LEAVEOUT +Leave Out +;Leave Out +; +;+++translateme+++ +MSGID_DEFAULT_MENU_LEAVEOUT_SHORT +L +;L +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PUTAWAY +Put Away +;Put Away +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PUTAWAY_SHORT +P +;P +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DELETE +Delete... +;Delete... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DELETE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EMPTYTRASH +Empty Trashcan... +;Empty Trashcan... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EMPTYTRASH_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLOSE +Close +;Close +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLOSE_SHORT +K +; +;+++translateme+++ +MSGID_DEFAULT_MENU_OPENPARENT +Open Parent +;Open Parent +; +;+++translateme+++ +MSGID_DEFAULT_MENU_OPENPARENT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UPDATE +Update +;Update +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UPDATE_SHORT +M +;M +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUP +Cleanup +;Cleanup +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUP_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RESIZETOFIT +Resize To Fit +;Resize To Fit +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RESIZETOFIT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SELECTCONTENTS +Select Contents +;Select Contents +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SELECTCONTENTS_SHORT +A +;A +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEARSELECTION +Clear Selection +;Clear Selection +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEARSELECTION_SHORT +Z +;Z +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT_ALL +All +;All +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT_ALL_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT_WINDOW +Window +;Window +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT_WINDOW_SHORT +W +;W +; +;+++translateme+++ +MSGID_DEFAULT_MENU_NEWDRAWER +New Drawer... +;New Drawer... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_NEWDRAWER_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SCALOS +Scalos +;Scalos +; +;+++translateme+++ +MSGID_DEFAULT_MENU_WINDOW +Window +;Window +; +;+++translateme+++ +MSGID_DEFAULT_MENU_ICONS +Icons +;Icons +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS +Drawers +;Drawers +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS +Prefs +;Prefs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_BACKDROP +Backdrop? +;Backdrop? +; +;+++translateme+++ +MSGID_DEFAULT_MENU_BACKDROP_SHORT +B +;B +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EXECUTECOMMAND +Execute Command... +;Execute Command... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EXECUTECOMMAND_SHORT +E +;E +; +;+++translateme+++ +MSGID_DEFAULT_MENU_REDRAWALL +Redraw All +;Redraw All +; +;+++translateme+++ +MSGID_DEFAULT_MENU_REDRAWALL_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UPDATEALL +Update All +;Update All +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UPDATEALL_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_LASTMESSAGE +Last Message +;Last Message +; +;+++translateme+++ +MSGID_DEFAULT_MENU_LASTMESSAGE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_ABOUT +About... +;About... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_ABOUT_SHORT +? +;? +; +;+++translateme+++ +MSGID_DEFAULT_MENU_QUIT +Quit... +;Quit... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_QUIT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY +Clean up by +;Clean up by +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_COLUMN +Column +;Column +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_COLUMN_SHORT +. +;. +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_NAME +Name +;Name +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_NAME_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_DATE +Date +;Date +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_DATE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_SIZE +Size +;Size +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_SIZE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_TYPE +Type +;Type +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_TYPE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW +Show +;Show +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_DEFAULT +Default +;Default +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_DEFAULT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_ONLYICONS +Only Icons +;Only Icons +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_ONLYICONS_SHOT +- +;- +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_ALLFILES +All Files +;All Files +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_ALLFILES_SHORT ++ +;+ +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY +View By +;View By +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_DEFAULT +Default +;Default +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_DEFAULT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_ICON +Icon +;Icon +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_ICON_SHORT +1 +;1 +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_NAME +Name +;Name +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_NAME_SHORT +2 +;2 +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_DATE +Date +;Date +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_DATE_SHORT +3 +;3 +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_SIZE +Size +;Size +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_SIZE_SHORT +4 +;4 +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_TYPE +Type +;Type +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_TYPE_SHORT +5 +;5 +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RESETSCALOS +Reset Scalos +;Reset Scalos +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RESETSCALOS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_NEWSHELL +New Shell +;New Shell +; +;+++translateme+++ +MSGID_DEFAULT_MENU_NEWSHELL_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_VOYAGER +Voyager +;Voyager +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_VOYAGER_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_ENVARC_SYS +ENVARC:Sys +;ENVARC:Sys +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_ENVARC_SYS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_WBSTARTUP +WBStartup +;WBStartup +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_WBSTARTUP_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_PREFS +Prefs +;Prefs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_PREFS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_SCALOSPREFS +Scalos Prefs +;Scalos Prefs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_SCALOSPREFS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SYSTEM +System... +;System... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_MUI +MUI... +;MUI... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_MUI_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_AHI +AHI... +;AHI... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_AHI_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCALOS +Scalos Prefs... +;Scalos Prefs... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCALOS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EMPTY_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_TOOLS +Tools +;Tools +; +;+++translateme+++ +MSGID_DEFAULT_UTILITIES +Utilities +;Utilities +; +;+++translateme+++ +MSGID_DEFAULT_PREFERENCES +Preferences +;Preferences +; +;+++translateme+++ +MSGID_DEFAULT_EXCHANGE +Exchange +;Exchange +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_MOUNTER +Mounter +;Mounter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SCSICONFIG +SCSIConfig +;SCSIConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SNOOPIUM +Snoopium +;Snoopium +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_DEFRAG +Defrag +;Defrag +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_FTMANAGER +FTManager +;FTManager +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_MUISHELL +MUIShell +;MUIShell +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SFSDOCTOR +SFSDoctor +;SFSDoctor +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_UNITCONTROL +UnitControl +;UnitControl +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_FILEIMAGECTRL +FileImageCtrl +;FileImageCtrl +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_HDCONFIG +HDConfig +;HDConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_REGTOOL +RegTool +;RegTool +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SHELL +Shell +;Shell +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_EDITOR +Editor +;Editor +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_FRAGMENT +Fragment +;Fragment +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_GRABBER +Grabber +;Grabber +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_GRAPHICBOARDS +GraphicBoards +;GraphicBoards +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_KEYSTROKE +Keystroke +;Keystroke +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MINICALC +MiniCalc +;MiniCalc +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MORE +More +;More +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MUIPROCALC +MUIProCalc +;MUIProCalc +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MULTIVIEW +Multiview +;Multiview +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MYSTICVIEW +MysticView +;MysticView +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_TASKMANAGER +TaskManager +;TaskManager +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_TRANCESTATS +Trancestats +;Trancestats +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_TIPS +Tips +;Tips +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_ZOOM +Zoom +;Zoom +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_AMIGS +AmiGS +;AmiGS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_AMIPDF +AmiPDF +;AmiPDF +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_SGRAB +SGrab +;SGrab +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_CALCULATOR +Calculator +;Calculator +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_CLOCK +Clock +;Clock +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_GRAPHICDUMP +GraphicDump +;GraphicDump +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_ICONEDIT +IconEdit +;IconEdit +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_INITPRINTER +InitPrinter +;InitPrinter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_KEYSHOW +KeyShow +;KeyShow +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MEMACS +MEmacs +;MEmacs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_NOTEPAD +Notepad +;Notepad +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PARTITIONWIZARD +Partition Wizard +;Partition Wizard +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PLAYCD +PlayCD +;PlayCD +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PREFSOBJECTSEDITOR +PrefsObjectsEditor +;PrefsObjectsEditor +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PRINTFILES +PrintFiles +;PrintFiles +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_RAWDISK +RawDisk +;RawDisk +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_SHOWCONFIG +ShowConfig +;ShowConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_UNARC +UnArc +;UnArc +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_USBINSPECTOR +USBInspector +;USBInspector +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_AMIGAINPUT +AmigaInput +;AmigaInput +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_ASL +ASL +;ASL +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_COMPATIBILITY +Compatibility +;Compatibility +; +; +MSGID_DEFAULT_MENU_PREFS_DEFICONS +DefIcons +;DefIcons +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_DOS +DOS +;DOS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_FONT +Font +;Font +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_GUI +GUI +;GUI +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_INPUT +Input +;Input +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_INTERNET +Internet +;Internet +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_LOCALE +Locale +;Locale +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_NOTIFICATIONS +Notifications +;Notifications +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PALETTE +Palette +;Palette +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PICASSO96MODE +Picasso96Mode +;Picasso96Mode +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_POINTER +Pointer +;Pointer +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_POPUPMENU +PopupMenu +;PopupMenu +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PRINTER +Printer +;Printer +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PRINTERGFX +PrinterGFX +;PrinterGFX +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PRINTERPS +PrinterPS +;PrinterPS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCREENBLANKER +ScreenBlanker +;ScreenBlanker +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCREENMODE +ScreenMode +;ScreenMode +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCREENS +Screens +;Screens +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SERIAL +Serial +;Serial +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SOUND +Sound +;Sound +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_TIME +Time +;Time +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_URL +URL +;URL +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_USB +USB +;USB +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WBPATTERN +WBPattern +;WBPattern +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WBSTARTUP +WBStartup +;WBStartup +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WORKBENCH +Workbench +;Workbench +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_INTELLIFONT +IntelliFont +;IntelliFont +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_GRAPHICDUMP +GraphicDump +;GraphicDump +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_WBCLOCK +WBClock +;WBClock +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_CACHECDFS +CacheCDFS +;CacheCDFS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_ICONTROL +IControl +;IControl +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_OVERSCAN +Overscan +;Overscan +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_REACTION +Reaction +;Reaction +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_VINCED +ViNCDe +;ViNCDe +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WARPOS +WarpOS +;WarpOS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_BENCHTRASH +BenchTrash +;BenchTrash +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_CALCULATOR +Calculator +;Calculator +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_EDITPAD +EditPad +;EditPad +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_HDTOOLBOX +HDToolBox +;HDToolBox +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_ICONEDIT +IconEdit +;IconEdit +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_INITPRINTER +InitPrinter +;InitPrinter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_IOTOOLS +IoTools +;IoTools +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_KEYSHOW +KeyShow +;KeyShow +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_LACER +Lacer +;Lacer +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_MEMACS +MEmacs +;MEmacs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_PREPCARD +PrepCard +;PrepCard +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_PRINTFILES +PrintFiles +;PrintFiles +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SHOWCONFIG +ShowConfig +;ShowConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_UNARC +Unarc +;Unarc +; +;+++translateme+++ +MSGID_DEFAULT_SYSTEM +System +;System +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_FIND +Find... +;Find... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_FIXFONT +FixFont +;FixFont +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_FORMAT +Format... +;Format... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_SHELL +Shell +;Shell +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_FORMATCDRW +FormatCDRW +;FormatCDRW +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_MEDIATOOLBOX +MediaToolBox +;MediaToolBox +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_MOUNTER +Mounter +;Mounter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_TYPEMANAGER +TypeManager +;TypeManager +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_HELP +Help +;Help +; +;----------------------------------------------------------- +; diff --git a/scalos/Prefs/Menu/Catalogs/italiano/Scalos/config.mk b/scalos/Prefs/Menu/Catalogs/italiano/Scalos/config.mk new file mode 100755 index 000000000..8108491da --- /dev/null +++ b/scalos/Prefs/Menu/Catalogs/italiano/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = italiano + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = italian + +else + +############################################################################### +# AmigaOS and AROS + +LANG = italiano + +endif +endif diff --git a/scalos/Prefs/Menu/Catalogs/italiano/Scalos/makefile b/scalos/Prefs/Menu/Catalogs/italiano/Scalos/makefile new file mode 100644 index 000000000..13c44e471 --- /dev/null +++ b/scalos/Prefs/Menu/Catalogs/italiano/Scalos/makefile @@ -0,0 +1,13 @@ +# makefile for Scalos (translated Texts : italiano) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mitaliano\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +ScalosMenu.catalog : ScalosMenu.ct ../../../ScalosMenu.cd + +All: ScalosMenu.catalog diff --git a/scalos/Prefs/Menu/Catalogs/italiano/Scalos/makefile-new b/scalos/Prefs/Menu/Catalogs/italiano/Scalos/makefile-new new file mode 100755 index 000000000..ff99823a4 --- /dev/null +++ b/scalos/Prefs/Menu/Catalogs/italiano/Scalos/makefile-new @@ -0,0 +1,32 @@ +# makefile for ScalosMenu (translated Texts : italiano) +# $Date: 2011-08-06 19:37:48 +0200 (Sa, 06. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = ScalosMenu + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Prefs/Menu/Catalogs/sample/Scalos/ScalosMenu.ct b/scalos/Prefs/Menu/Catalogs/sample/Scalos/ScalosMenu.ct new file mode 100644 index 000000000..fae1b355a --- /dev/null +++ b/scalos/Prefs/Menu/Catalogs/sample/Scalos/ScalosMenu.ct @@ -0,0 +1,1944 @@ +; ScalosMenu.ct +## version $VER: ScalosMenu.catalog 40.18 (24 Aug 2008 10:09:08) +## codeset 0s +## language xxxxxx +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Menu Prefs Plugin +; +; +MSGID_TITLENAME_CMDLIST +Scalos Internal Menu Commands +; +; +MSGID_FRAMETITLE +Menulist +; +; +MSGID_NEWINAME +New Item +; +; +MSGID_HOTKEYNAME +Key: +; +; +MSGID_NEWNAME +New Menu +; +; +MSGID_DELNAME +Delete +; +; +MSGID_SAVENAME +Save +; +; +MSGID_USENAME +Use +; +; +MSGID_CANCELNAME +Cancel +; +; +MSGID_NEW2NAME +New Command +; +; +MSGID_COMMANDNAME +Command +; +; +MSGID_MENU_PROJECT_IMPORT +Import +; +; +MSGID_MENU_PROJECT_IMPORT_SHORT +I +; +; +MSGID_MENU_PROJECT_OPEN +Open... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +O +; +; +MSGID_MENU_PROJECT_SAVEAS +Save As... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +A +; +; +MSGID_MENU_PROJECT_QUIT +Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +; +MSGID_MENU_PROJECT +Project +; +; +MSGID_MENU_EDIT_LASTSAVED +Last Saved +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +L +; +; +MSGID_MENU_EDIT +Edit +; +; +MSGID_MENU_SETTINGS_CREATEICONS +Create Icons? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +I +; +; +MSGID_MENU_SETTINGS +Settings +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +Reset To Defaults +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +D +; +; +MSGID_MENU_EDIT_RESTORE +Restore +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +R +; +; +MSGID_MENU_PROJECT_ABOUTMUI +About MUI... +; +; +MSGID_WBNAME +Workbench +; +; +MSGID_ADOSNAME +AmigaDOS +; +; +MSGID_STACKNAME +Stack +; +; +MSGID_MAINMENUNAME +MainMenu +; +; +MSGID_COM1NAME +Backdrop +; +; +MSGID_COM2NAME +Execute Command +; +; +MSGID_COM3NAME +Redraw All +; +; +MSGID_COM4NAME +Update All +; +; +MSGID_COM5NAME +About Scalos +; +; +MSGID_COM6NAME +Quit +; +; +MSGID_COM7NAME +New Drawer +; +; +MSGID_COM8NAME +Open Parent +; +; +MSGID_COM9NAME +Close Window +; +; +MSGID_COM10NAME +Update +; +; +MSGID_COM11NAME +Select Contents +; +; +MSGID_COM12NAME +Cleanup +; +; +MSGID_COM13NAME +Snapshot - Window +; +; +MSGID_COM14NAME +Snapshot - All +; +; +MSGID_COM15NAME +Show - Only Icons +; +; +MSGID_COM16NAME +Show - All Files +; +; +MSGID_COM17NAME +View By - Icon +; +; +MSGID_COM18NAME +View By - Text +; +; +MSGID_COM19NAME +Open +; +; +MSGID_COM20NAME +Reset Scalos +; +; +MSGID_COM21NAME +Rename +; +; +MSGID_COM22NAME +Information +; +; +MSGID_COM23NAME +Snapshot +; +; +MSGID_COM24NAME +UnSnapshot +; +; +MSGID_COM25NAME +Leave Out +; +; +MSGID_COM26NAME +Put Away +; +; +MSGID_COM27NAME +Delete +; +; +MSGID_BARNAME +\033C +; +; +MSGID_UPNAME +Up +; +; +MSGID_DOWNNAME +Down +; +; +MSGID_MENU_PROJECT_IMPORT_TD +ToolsDaemon... +; +; +MSGID_MENU_PROJECT_IMPORT_TD_SHORT +T +; +; +MSGID_MENU_PROJECT_IMPORT_P +Parm... +; +; +MSGID_MENU_PROJECT_IMPORT_P_SHORT +P +; +; +MSGID_COM28NAME +Clone +; +; +MSGID_ICONWINNAME +IconWindow +; +; +MSGID_AREXXNAME +Arexx +; +;+++translateme+++ +MSGID_MENU_EDIT_COPY +Copy +;Copy +; +;+++translateme+++ +MSGID_MENU_EDIT_CUT +Cut +;Cut +; +;+++translateme+++ +MSGID_MENU_EDIT_PASTE +Paste +;Paste +; +;+++translateme+++ +MSGID_MENU_EDIT_COLLAPSE +Collapse Selected +;Collapse Selected +; +;+++translateme+++ +MSGID_MENU_EDIT_EXPAND +Expand Selected +;Expand Selected +; +;--------------------------------------------- +; +MSGID_POPMENUNAME1 +Popup Menu: Disk icons +; +; +MSGID_POPMENUNAME2 +Popup Menu: Drawer icons +; +; +MSGID_POPMENUNAME3 +Popup Menu: Tool/Project icons +; +; +MSGID_POPMENUNAME4 +Popup Menu: Trashcan icons +; +; +MSGID_POPMENUNAME5 +Popup_Menu: Windows +; +; +MSGID_ARGSNAME +WB Args: +; +; +MSGID_COM29NAME +Empty Trashcan +; +; +MSGID_COM30NAME +Last Message +; +; +MSGID_COM31NAME +Redraw +; +; +MSGID_COM32NAME +Iconify +; +; +MSGID_PLUGINNAME +PlugIn +; +; +MSGID_MENU_PROJECT_MERGE +Merge... +; +; +MSGID_MENU_PROJECT_MERGE_SHORT +M +; +; +MSGID_MENU_EDIT_COLLAPSEALL +Collapse All +; +; +MSGID_MENU_EDIT_EXPANDALL +Expand All +; +; +MSGID_MENU_SETTINGS_HIDEOBSOLETE +Hide Obsolete? +;Hide Obsolete? +; +; +MSGID_MENU_SETTINGS_HIDEOBSOLETE_SHORT +If checked, obsolete popup menus which are now\n\ +defined via filetypes prefs are not shown. +;If checked, obsolete popup menus which are now\n\ +;defined via filetypes prefs are not shown. +; +; +MSGID_COM33NAME +Format Disk... +; +; +MSGID_COM34NAME +Shutdown... +; +; +MSGID_COM35NAME +Size To Fit +; +; +MSGID_COM36NAME +Clear Selection +; +; +MSGID_POPMENUNAME6 +Popup Menu: AppIcons +; +;+++translateme+++ +MSGID_POPMENUNAME7 +Popup Menu: Desktop +;Popup Menu: Desktop +; +; +MSGID_COM37NAME +View By - Size +; +; +MSGID_COM38NAME +View By - Date +; +; +MSGID_MENU_PROJECT_ABOUT +About... +; +; +MSGID_ABOUTREQOK +_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Menu Preferences V%ld.%ld\033n\n\ +%s\n\ +© 1999%s The Scalos Team +; +; +;*** +jl+ 20011214 +MSGID_COM39NAME +Copy file +; +; +MSGID_COM40NAME +Cut file +; +; +MSGID_COM41NAME +Paste file +; +; +MSGID_COM42NAME +View By - Type +; +; +MSGID_COM43NAME +Cleanup By - Name +; +; +MSGID_COM44NAME +Cleanup By - Date +; +; +MSGID_COM45NAME +Cleanup By - Size +; +; +MSGID_COM46NAME +Cleanup By - Type +; +;+++translateme+++ +MSGID_COM_ICONPROPERTIES +Icon properties +; +;+++translateme+++ +MSGID_COM_WINDOWPROPERTIES +Window properties +; +;+++translateme+++ +MSGID_COM47NAME +View By - Default +; +;+++translateme+++ +MSGID_COM48NAME +Show - Default +; +;+++translateme+++ +MSGID_COM49NAME +Copy to... +;Copy to... +; +;+++translateme+++ +MSGID_COM50NAME +Move to... +;Move to... +; +;+++translateme+++ +MSGID_COM51NAME +Create thumbnail +;Create thumbnail +; +;+++translateme+++ +MSGID_COM_OPENNEWWINDOW +Open in new window +;Open in new window +; +;+++translateme+++ +MSGID_COM_THUMBNAILCACHECLEANUP +Cleanup thumbnail cache +; +;+++translateme+++ +MSGID_COM_FIND +Find File(s) +;Find File(s) +; +;+++translateme+++ +MSGID_COM_UNDO +Undo +;Undo +; +;+++translateme+++ +MSGID_COM_REDO +Redo +;Redo +; +;+++translateme+++ +MSGID_COM_OPENBROWSERWINDOW +Open in Browser Window +;Open in Browser Window +; +;--------------------------------------------- +; +MSGID_SHORTHELP_NEWMENUBUTTON +Press this button to create a new Menu or\n\ +Submenu entry at the currently selected position. +; +; +MSGID_SHORTHELP_NEWITEMBUTTON +Press this button to insert a new menu\n\ +item at the currently selected position. +; +; +MSGID_SHORTHELP_NEWCOMMANDBUTTON +Press this button to add a new\n\ +command to the currently menu item. +; +; +MSGID_SHORTHELP_DELBUTTON +Press this button to delete the currently\n\ +select command, menu item, or menu. +; +; +MSGID_SHORTHELP_SAVEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENVARC:Scalos/menu13.prefs\". +; +; +MSGID_SHORTHELP_USEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENV:Scalos/menu13.prefs\". +; +; +MSGID_SHORTHELP_CANCELBUTTON +Press this button to abort \n\ +and forget all changes. +; +; +MSGID_REQTITLE_SAVEERROR +Error writing palette preferences\n\ +file \"%s\"\n\ +%s +; +; +MSGID_REQTITLE_READERROR +Error reading palette preferences\n\ +file \"%s\"\n\ +%s +; +; +MSGID_IMPORTNAME +Import +; +; +MSGID_TITLE_IMPORTTD +Import ToolsDaemon Prefs +; +; +MSGID_TITLE_IMPORTP +Import ParM Prefs +; +; +MSGID_PRIORITY_SLIDER_NAME +Priority +; +; +MSGID_PRIORITY_SLIDER_BUBBLE +Use this slider to adjust the priority the command should run with. +; +; new in 40.7 +; +MSGID_PLUGIN_LIST_TITLE +Menu +; +; +MSGID_POPUP_ASLTITLE_AMIGADOS +Select AmigaDOS command +; +; +MSGID_POPUP_ASLTITLE_WORKBENCH +Select Workbench command +; +; +MSGID_POPUP_ASLTITLE_ICONWINDOW +Select directory for icon window +; +; +MSGID_POPUP_ASLTITLE_AREXX +Select ARexx program +; +; +MSGID_POPUP_ASLTITLE_MENUPLUGIN +Select Scalos Menu plugin +; +; +MSGID_MENU_PROJECT_MERGE_ASLTITLE +Select prefs to merge with +; +; +MSGID_MENU_GROUP_COMMAND_PROPERTIES +Command Properties +; +; new in 40.10 +; +; +++translateme+++ +MSGID_SHORTHELP_LAMP_CHANGED +This lamp indicator changes from \033bOff\033n\n\ +to \033bOk\033n when the settings have been\n\ +modified since initial loading. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +; new in 40.16 +; +; +++translateme+++ +MSGID_POPASL_UNSELECTEDIMAGE_SHORTHELP +Here you may select an iconic image that is shown left of\n\ +the menu item name, in unselected menu item state. +;Here you may select an iconic image that is shown left of\n\ +;the menu item name, in unselected menu item state. +; +; +++translateme+++ +MSGID_SAMPLE_UNSELECTEDIMAGE_SHORTHELP +This is a sample of the iconic image that will be shown\n\ +left of the menu item name, in unselected menu item state. +;This is a sample of the iconic image that will be shown\n\ +;left of the menu item name, in unselected menu item state. +; +; +++translateme+++ +MSGID_POPASL_SELECTEDIMAGE_SHORTHELP +Here you may select an iconic image that is shown left of\n\ +the menu item name, in selected menu item state. +;Here you may select an iconic image that is shown left of\n\ +;the menu item name, in selected menu item state. +; +; +; +++translateme+++ +MSGID_SAMPLE_SELECTEDIMAGE_SHORTHELP +This is a sample of the iconic image that will be shown\n\ +left of the menu item name, in selected menu item state. +;This is a sample of the iconic image that will be shown\n\ +;left of the menu item name, in selected menu item state. +; +;+++translateme+++ +MSGID_ENTRY_STRING_NAME +Name: +;Name: +; +;+++translateme+++ +MSGID_ENTRY_GROUP_UNSELECTEDIMAGE +Unselected State Image +;Unselected State Image +; +;+++translateme+++ +MSGID_ENTRY_GROUP_SELECTEDIMAGE +Selected State Image +;Selected State Image +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Scalos Menu Prefs startup failed +;Scalos Menu Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Try again|Quit +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_NEW_MENU +New Menu +;New Menu +; +;+++translateme+++ +MSGID_NEW_ITEM +New Item +;New Item +; +;+++translateme+++ +MSGID_TOOLS_MENU +Tools +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_DEFAULT_MENU_OPEN +Open +;Open +; +;+++translateme+++ +MSGID_DEFAULT_MENU_OPEN_SHORT +O +;O +; +;+++translateme+++ +MSGID_DEFAULT_MENU_INFORMATION +Information... +;Information... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_INFORMATION_SHORT +I +;I +; +;+++translateme+++ +MSGID_DEFAULT_MENU_BROWSE +Browse... +;Browse... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_BROWSE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_FIND +Find... +;Find... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_FIND_SHORT +F +;F +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT +Snapshot +;Snapshot +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT_SHORT +S +;S +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UNSNAPSHOT +Unsnapshot +;Unsnapshot +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UNSNAPSHOT_SHORT +U +;U +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLONE +Clone +;Clone +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLONE_SHORT +C +;C +; +;+++translateme+++ +MSGID_DEFAULT_MENU_COPY +Copy +;Copy +; +;+++translateme+++ +MSGID_DEFAULT_MENU_COPY_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CUT +Cut +;Cut +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CUT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PASTE +Paste +;Paste +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PASTE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DISKCOPY +Diskcopy... +;Diskcopy... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DISKCOPY_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RELABEL +Relabel... +;Relabel... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RELABEL_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_FORMAT +Format... +;Format... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_FORMAT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PROPERTIES +Properties... +;Properties... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PROPERTIES_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EDIT +Edit +;Edit +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RENAME +Rename +;Rename +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RENAME_SHORT +R +;R +; +;+++translateme+++ +MSGID_DEFAULT_MENU_LEAVEOUT +Leave Out +;Leave Out +; +;+++translateme+++ +MSGID_DEFAULT_MENU_LEAVEOUT_SHORT +L +;L +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PUTAWAY +Put Away +;Put Away +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PUTAWAY_SHORT +P +;P +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DELETE +Delete... +;Delete... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DELETE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EMPTYTRASH +Empty Trashcan... +;Empty Trashcan... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EMPTYTRASH_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLOSE +Close +;Close +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLOSE_SHORT +K +; +;+++translateme+++ +MSGID_DEFAULT_MENU_OPENPARENT +Open Parent +;Open Parent +; +;+++translateme+++ +MSGID_DEFAULT_MENU_OPENPARENT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UPDATE +Update +;Update +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UPDATE_SHORT +M +;M +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUP +Cleanup +;Cleanup +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUP_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RESIZETOFIT +Resize To Fit +;Resize To Fit +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RESIZETOFIT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SELECTCONTENTS +Select Contents +;Select Contents +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SELECTCONTENTS_SHORT +A +;A +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEARSELECTION +Clear Selection +;Clear Selection +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEARSELECTION_SHORT +Z +;Z +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT_ALL +All +;All +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT_ALL_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT_WINDOW +Window +;Window +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT_WINDOW_SHORT +W +;W +; +;+++translateme+++ +MSGID_DEFAULT_MENU_NEWDRAWER +New Drawer... +;New Drawer... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_NEWDRAWER_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SCALOS +Scalos +;Scalos +; +;+++translateme+++ +MSGID_DEFAULT_MENU_WINDOW +Window +;Window +; +;+++translateme+++ +MSGID_DEFAULT_MENU_ICONS +Icons +;Icons +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS +Drawers +;Drawers +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS +Prefs +;Prefs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_BACKDROP +Backdrop? +;Backdrop? +; +;+++translateme+++ +MSGID_DEFAULT_MENU_BACKDROP_SHORT +B +;B +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EXECUTECOMMAND +Execute Command... +;Execute Command... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EXECUTECOMMAND_SHORT +E +;E +; +;+++translateme+++ +MSGID_DEFAULT_MENU_REDRAWALL +Redraw All +;Redraw All +; +;+++translateme+++ +MSGID_DEFAULT_MENU_REDRAWALL_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UPDATEALL +Update All +;Update All +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UPDATEALL_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_LASTMESSAGE +Last Message +;Last Message +; +;+++translateme+++ +MSGID_DEFAULT_MENU_LASTMESSAGE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_ABOUT +About... +;About... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_ABOUT_SHORT +? +;? +; +;+++translateme+++ +MSGID_DEFAULT_MENU_QUIT +Quit... +;Quit... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_QUIT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY +Clean up by +;Clean up by +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_COLUMN +Column +;Column +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_COLUMN_SHORT +. +;. +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_NAME +Name +;Name +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_NAME_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_DATE +Date +;Date +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_DATE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_SIZE +Size +;Size +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_SIZE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_TYPE +Type +;Type +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_TYPE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW +Show +;Show +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_DEFAULT +Default +;Default +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_DEFAULT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_ONLYICONS +Only Icons +;Only Icons +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_ONLYICONS_SHOT +- +;- +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_ALLFILES +All Files +;All Files +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_ALLFILES_SHORT ++ +;+ +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY +View By +;View By +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_DEFAULT +Default +;Default +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_DEFAULT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_ICON +Icon +;Icon +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_ICON_SHORT +1 +;1 +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_NAME +Name +;Name +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_NAME_SHORT +2 +;2 +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_DATE +Date +;Date +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_DATE_SHORT +3 +;3 +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_SIZE +Size +;Size +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_SIZE_SHORT +4 +;4 +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_TYPE +Type +;Type +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_TYPE_SHORT +5 +;5 +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RESETSCALOS +Reset Scalos +;Reset Scalos +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RESETSCALOS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_NEWSHELL +New Shell +;New Shell +; +;+++translateme+++ +MSGID_DEFAULT_MENU_NEWSHELL_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_VOYAGER +Voyager +;Voyager +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_VOYAGER_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_ENVARC_SYS +ENVARC:Sys +;ENVARC:Sys +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_ENVARC_SYS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_WBSTARTUP +WBStartup +;WBStartup +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_WBSTARTUP_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_PREFS +Prefs +;Prefs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_PREFS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_SCALOSPREFS +Scalos Prefs +;Scalos Prefs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_SCALOSPREFS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SYSTEM +System... +;System... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_MUI +MUI... +;MUI... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_MUI_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_AHI +AHI... +;AHI... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_AHI_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCALOS +Scalos Prefs... +;Scalos Prefs... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCALOS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EMPTY_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_TOOLS +Tools +;Tools +; +;+++translateme+++ +MSGID_DEFAULT_UTILITIES +Utilities +;Utilities +; +;+++translateme+++ +MSGID_DEFAULT_PREFERENCES +Preferences +;Preferences +; +;+++translateme+++ +MSGID_DEFAULT_EXCHANGE +Exchange +;Exchange +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_MOUNTER +Mounter +;Mounter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SCSICONFIG +SCSIConfig +;SCSIConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SNOOPIUM +Snoopium +;Snoopium +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_DEFRAG +Defrag +;Defrag +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_FTMANAGER +FTManager +;FTManager +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_MUISHELL +MUIShell +;MUIShell +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SFSDOCTOR +SFSDoctor +;SFSDoctor +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_UNITCONTROL +UnitControl +;UnitControl +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_FILEIMAGECTRL +FileImageCtrl +;FileImageCtrl +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_HDCONFIG +HDConfig +;HDConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_REGTOOL +RegTool +;RegTool +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SHELL +Shell +;Shell +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_EDITOR +Editor +;Editor +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_FRAGMENT +Fragment +;Fragment +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_GRABBER +Grabber +;Grabber +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_GRAPHICBOARDS +GraphicBoards +;GraphicBoards +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_KEYSTROKE +Keystroke +;Keystroke +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MINICALC +MiniCalc +;MiniCalc +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MORE +More +;More +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MUIPROCALC +MUIProCalc +;MUIProCalc +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MULTIVIEW +Multiview +;Multiview +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MYSTICVIEW +MysticView +;MysticView +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_TASKMANAGER +TaskManager +;TaskManager +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_TRANCESTATS +Trancestats +;Trancestats +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_TIPS +Tips +;Tips +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_ZOOM +Zoom +;Zoom +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_AMIGS +AmiGS +;AmiGS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_AMIPDF +AmiPDF +;AmiPDF +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_SGRAB +SGrab +;SGrab +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_CALCULATOR +Calculator +;Calculator +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_CLOCK +Clock +;Clock +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_GRAPHICDUMP +GraphicDump +;GraphicDump +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_ICONEDIT +IconEdit +;IconEdit +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_INITPRINTER +InitPrinter +;InitPrinter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_KEYSHOW +KeyShow +;KeyShow +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MEMACS +MEmacs +;MEmacs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_NOTEPAD +Notepad +;Notepad +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PARTITIONWIZARD +Partition Wizard +;Partition Wizard +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PLAYCD +PlayCD +;PlayCD +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PREFSOBJECTSEDITOR +PrefsObjectsEditor +;PrefsObjectsEditor +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PRINTFILES +PrintFiles +;PrintFiles +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_RAWDISK +RawDisk +;RawDisk +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_SHOWCONFIG +ShowConfig +;ShowConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_UNARC +UnArc +;UnArc +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_USBINSPECTOR +USBInspector +;USBInspector +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_AMIGAINPUT +AmigaInput +;AmigaInput +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_ASL +ASL +;ASL +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_COMPATIBILITY +Compatibility +;Compatibility +; +; +MSGID_DEFAULT_MENU_PREFS_DEFICONS +DefIcons +;DefIcons +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_DOS +DOS +;DOS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_FONT +Font +;Font +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_GUI +GUI +;GUI +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_INPUT +Input +;Input +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_INTERNET +Internet +;Internet +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_LOCALE +Locale +;Locale +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_NOTIFICATIONS +Notifications +;Notifications +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PALETTE +Palette +;Palette +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PICASSO96MODE +Picasso96Mode +;Picasso96Mode +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_POINTER +Pointer +;Pointer +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_POPUPMENU +PopupMenu +;PopupMenu +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PRINTER +Printer +;Printer +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PRINTERGFX +PrinterGFX +;PrinterGFX +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PRINTERPS +PrinterPS +;PrinterPS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCREENBLANKER +ScreenBlanker +;ScreenBlanker +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCREENMODE +ScreenMode +;ScreenMode +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCREENS +Screens +;Screens +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SERIAL +Serial +;Serial +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SOUND +Sound +;Sound +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_TIME +Time +;Time +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_URL +URL +;URL +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_USB +USB +;USB +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WBPATTERN +WBPattern +;WBPattern +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WBSTARTUP +WBStartup +;WBStartup +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WORKBENCH +Workbench +;Workbench +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_INTELLIFONT +IntelliFont +;IntelliFont +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_GRAPHICDUMP +GraphicDump +;GraphicDump +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_WBCLOCK +WBClock +;WBClock +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_CACHECDFS +CacheCDFS +;CacheCDFS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_ICONTROL +IControl +;IControl +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_OVERSCAN +Overscan +;Overscan +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_REACTION +Reaction +;Reaction +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_VINCED +ViNCDe +;ViNCDe +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WARPOS +WarpOS +;WarpOS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_BENCHTRASH +BenchTrash +;BenchTrash +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_CALCULATOR +Calculator +;Calculator +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_EDITPAD +EditPad +;EditPad +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_GRAPHICDUMP +GraphicDump +;GraphicDump +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_HDTOOLBOX +HDToolBox +;HDToolBox +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_ICONEDIT +IconEdit +;IconEdit +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_INITPRINTER +InitPrinter +;InitPrinter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_IOTOOLS +IoTools +;IoTools +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_KEYSHOW +KeyShow +;KeyShow +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_LACER +Lacer +;Lacer +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_MEMACS +MEmacs +;MEmacs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_MOUNTER +Mounter +;Mounter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_PREPCARD +PrepCard +;PrepCard +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_PRINTFILES +PrintFiles +;PrintFiles +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SHOWCONFIG +ShowConfig +;ShowConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_UNARC +Unarc +;Unarc +; +;+++translateme+++ +MSGID_DEFAULT_SYSTEM +System +;System +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_FIND +Find... +;Find... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_FIXFONT +FixFont +;FixFont +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_FORMAT +Format... +;Format... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_SHELL +Shell +;Shell +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_FORMATCDRW +FormatCDRW +;FormatCDRW +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_MEDIATOOLBOX +MediaToolBox +;MediaToolBox +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_MOUNTER +Mounter +;Mounter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_TYPEMANAGER +TypeManager +;TypeManager +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_HELP +Help +;Help +; +;----------------------------------------------------------- +; diff --git a/scalos/Prefs/Menu/Catalogs/svenska/Scalos/ScalosMenu.ct b/scalos/Prefs/Menu/Catalogs/svenska/Scalos/ScalosMenu.ct new file mode 100644 index 000000000..20ac81390 --- /dev/null +++ b/scalos/Prefs/Menu/Catalogs/svenska/Scalos/ScalosMenu.ct @@ -0,0 +1,1935 @@ +; ScalosMenu.ct +## version $VER: ScalosMenu.catalog 40.18 (24 Aug 2008 10:22:22) +## codeset 0 +## language svenska +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Meny Plugin +; +; +MSGID_TITLENAME_CMDLIST +Scalos Internal Menu Commands +; +; +MSGID_FRAMETITLE +Menylista +; +; +MSGID_NEWINAME +Nytt menyval +; +; +MSGID_HOTKEYNAME +Tangent: +; +; +MSGID_NEWNAME +Ny meny +; +; +MSGID_DELNAME +Radera +; +; +MSGID_SAVENAME +Spara +; +; +MSGID_USENAME +Använd +; +; +MSGID_CANCELNAME +Avbryt +; +; +MSGID_NEW2NAME +Nytt kommando +; +; +MSGID_COMMANDNAME +Kommando +; +; +MSGID_MENU_PROJECT_IMPORT +Importera +; +; +MSGID_MENU_PROJECT_IMPORT_SHORT +I +; +; +MSGID_MENU_PROJECT_OPEN +Öppna... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +O +; +; +MSGID_MENU_PROJECT_SAVEAS +Spara som... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +A +; +; +MSGID_MENU_PROJECT_QUIT +Avsluta +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +; +MSGID_MENU_PROJECT +Arkiv +; +; +MSGID_MENU_EDIT_LASTSAVED +Senast sparade +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +L +; +; +MSGID_MENU_EDIT +Redigera +; +; +MSGID_MENU_SETTINGS_CREATEICONS +Skapa symboler? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +I +; +; +MSGID_MENU_SETTINGS +Inställningar +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +Förinställda värden +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +D +; +; +MSGID_MENU_EDIT_RESTORE +Återställ +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +R +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Om MUI... +; +; +MSGID_WBNAME +Workbench +; +; +MSGID_ADOSNAME +AmigaDOS +; +; +MSGID_STACKNAME +Stack +; +; +MSGID_MAINMENUNAME +Huvudmeny +; +; +MSGID_COM1NAME +Bakgrund +; +; +MSGID_COM2NAME +Exekvera kommando +; +; +MSGID_COM3NAME +Rita om allt +; +; +MSGID_COM4NAME +Uppdatera allt +; +; +MSGID_COM5NAME +Om Scalos +; +; +MSGID_COM6NAME +Avsluta +; +; +MSGID_COM7NAME +Ny låda +; +; +MSGID_COM8NAME +Öppna moderlåda +; +; +MSGID_COM9NAME +Stäng fönster +; +; +MSGID_COM10NAME +Uppdatera +; +; +MSGID_COM11NAME +Välj innehåll +; +; +MSGID_COM12NAME +Städa upp +; +; +MSGID_COM13NAME +Memorera plac. - Fönster +; +; +MSGID_COM14NAME +Memorera plac. - Allt +; +; +MSGID_COM15NAME +Visa - Enbart ikoner +; +; +MSGID_COM16NAME +Visa - Alla filer +; +; +MSGID_COM17NAME +Visa som - Ikoner +; +; +MSGID_COM18NAME +Visa som - Text +; +; +MSGID_COM19NAME +Öppna +; +; +MSGID_COM20NAME +Återställ Scalos +; +; +MSGID_COM21NAME +Byt namn +; +; +MSGID_COM22NAME +Information +; +; +MSGID_COM23NAME +Memorera placering +; +; +MSGID_COM24NAME +Glöm placering +; +; +MSGID_COM25NAME +Lämna utanför +; +; +MSGID_COM26NAME +Stoppa tillbaka +; +; +MSGID_COM27NAME +Radera +; +; +MSGID_BARNAME +\033C +; +; +MSGID_UPNAME +Upp +; +; +MSGID_DOWNNAME +Ner +; +; +MSGID_MENU_PROJECT_IMPORT_TD +ToolsDaemon... +; +; +MSGID_MENU_PROJECT_IMPORT_TD_SHORT +T +; +; +MSGID_MENU_PROJECT_IMPORT_P +Parm... +; +; +MSGID_MENU_PROJECT_IMPORT_P_SHORT +P +; +; +MSGID_COM28NAME +Kopiera +; +; +MSGID_ICONWINNAME +Symbolfönster +; +; +MSGID_AREXXNAME +ARexx +; +;+++translateme+++ +MSGID_MENU_EDIT_COPY +Copy +;Copy +; +;+++translateme+++ +MSGID_MENU_EDIT_CUT +Cut +;Cut +; +;+++translateme+++ +MSGID_MENU_EDIT_PASTE +Paste +;Paste +; +;+++translateme+++ +MSGID_MENU_EDIT_COLLAPSE +Collapse Selected +;Collapse Selected +; +;+++translateme+++ +MSGID_MENU_EDIT_EXPAND +Expand Selected +;Expand Selected +; +;--------------------------------------------- +; +MSGID_POPMENUNAME1 +Popup Menu: Disk +; +; +MSGID_POPMENUNAME2 +Popup Menu: Låda +; +; +MSGID_POPMENUNAME3 +Popup Menu: Verktyg/Projekt +; +; +MSGID_POPMENUNAME4 +Popup Menu: Papperskorg +; +; +MSGID_POPMENUNAME5 +Popup Menu: Fönster +; +; +MSGID_ARGSNAME +WB argument: +; +; +MSGID_COM29NAME +Töm papperskorg +; +; +MSGID_COM30NAME +Senaste meddelande +; +; +MSGID_COM31NAME +Rita om +; +; +MSGID_COM32NAME +Ikonifiera +; +; +MSGID_PLUGINNAME +PlugIn +; +; +MSGID_MENU_PROJECT_MERGE +Lägg till... +; +; +MSGID_MENU_PROJECT_MERGE_SHORT +M +; +; +MSGID_MENU_EDIT_COLLAPSEALL +Collapse All +; +; +MSGID_MENU_EDIT_EXPANDALL +Expand All +; +; +MSGID_MENU_SETTINGS_HIDEOBSOLETE +Hide Obsolete? +;Hide Obsolete? +; +; +MSGID_MENU_SETTINGS_HIDEOBSOLETE_SHORT +If checked, obsolete popup menus which are now\n\ +defined via filetypes prefs are not shown. +;If checked, obsolete popup menus which are now\n\ +;defined via filetypes prefs are not shown. +; +; +MSGID_COM33NAME +Format Disk... +; +; +MSGID_COM34NAME +Shutdown... +; +; +MSGID_COM35NAME +Size to fit +; +; +MSGID_COM36NAME +Clear Selection +; +; +MSGID_POPMENUNAME6 +Popup Menu: AppIcons +; +;+++translateme+++ +MSGID_POPMENUNAME7 +Popup Menu: Desktop +;Popup Menu: Desktop +; +; +MSGID_COM37NAME +View By - Size +; +; +MSGID_COM38NAME +View By - Date +; +; +MSGID_MENU_PROJECT_ABOUT +About... +; +; +MSGID_ABOUTREQOK +_OK +; +; +MSGID_ABOUTREQFORMAT +\\33c\033bScalos Menu Preferences V%ld.%ld\033n\n\ +%s\n\ +© 1999%s The Scalos Team +; +; +;*** +jl+ 20011214 +MSGID_COM39NAME +Copy file +; +; +MSGID_COM40NAME +Cut file +; +; +MSGID_COM41NAME +Paste file +; +; +MSGID_COM42NAME +View By - Type +; +; +MSGID_COM43NAME +Cleanup By - Name +; +; +MSGID_COM44NAME +Cleanup By - Date +; +; +MSGID_COM45NAME +Cleanup By - Size +; +; +MSGID_COM46NAME +Cleanup By - Type +; +;+++translateme+++ +MSGID_COM_ICONPROPERTIES +Icon properties +;Icon properties +; +;+++translateme+++ +MSGID_COM_WINDOWPROPERTIES +Window properties +;Window properties +; +;+++translateme+++ +MSGID_COM47NAME +View By - Default +; +;+++translateme+++ +MSGID_COM48NAME +Show - Default +; +;+++translateme+++ +MSGID_COM49NAME +Copy to... +;Copy to... +; +;+++translateme+++ +MSGID_COM50NAME +Move to... +;Move to... +; +;+++translateme+++ +MSGID_COM51NAME +Create thumbnail +; +;+++translateme+++ +MSGID_COM_OPENNEWWINDOW +Open in new window +;Open in new window +; +;+++translateme+++ +MSGID_COM_THUMBNAILCACHECLEANUP +Cleanup thumbnail cache +; +;+++translateme+++ +MSGID_COM_FIND +Find File(s) +;Find File(s) +; +;+++translateme+++ +MSGID_COM_UNDO +Undo +;Undo +; +;+++translateme+++ +MSGID_COM_REDO +Redo +;Redo +; +;+++translateme+++ +MSGID_COM_OPENBROWSERWINDOW +Open in Browser Window +;Open in Browser Window +; +;-------------------------------------------- +; +MSGID_SHORTHELP_NEWMENUBUTTON +Press this button to create a new Menu or\n\ +Submenu entry at the currently selected position. +; +; +MSGID_SHORTHELP_NEWITEMBUTTON +Press this button to insert a new menu\n\ +item at the currently selected position. +; +; +MSGID_SHORTHELP_NEWCOMMANDBUTTON +Press this button to add a new\n\ +command to the currently menu item. +; +; +MSGID_SHORTHELP_DELBUTTON +Press this button to delete the currently\n\ +select command, menu item, or menu. +; +; +MSGID_SHORTHELP_SAVEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENVARC:Scalos/menu13.prefs\". +; +; +MSGID_SHORTHELP_USEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENV:Scalos/menu13.prefs\". +; +; +MSGID_SHORTHELP_CANCELBUTTON +Press this button to abort \n\ +and forget all changes. +; +; +MSGID_REQTITLE_SAVEERROR +Error writing palette preferences\n\ +file \"%s\"\n\ +%s +; +; +MSGID_REQTITLE_READERROR +Error reading palette preferences\n\ +file \"%s\"\n\ +%s +; +; +MSGID_IMPORTNAME +Import +; +; +MSGID_TITLE_IMPORTTD +Import ToolsDaemon Prefs +; +; +MSGID_TITLE_IMPORTP +Import ParM Prefs +; +; +MSGID_PRIORITY_SLIDER_NAME +Priority +; +; +MSGID_PRIORITY_SLIDER_BUBBLE +Use this slider to adjust the priority the command should run with. +; +; new in 40.7 +; +MSGID_PLUGIN_LIST_TITLE +Menu +; +; +MSGID_POPUP_ASLTITLE_AMIGADOS +Select AmigaDOS command +; +; +MSGID_POPUP_ASLTITLE_WORKBENCH +Select Workbench command +; +; +MSGID_POPUP_ASLTITLE_ICONWINDOW +Select directory for icon window +; +; +MSGID_POPUP_ASLTITLE_AREXX +Select ARexx program +; +; +MSGID_POPUP_ASLTITLE_MENUPLUGIN +Select Scalos Menu plugin +; +; +MSGID_MENU_PROJECT_MERGE_ASLTITLE +Select prefs to merge with +; +; +MSGID_MENU_GROUP_COMMAND_PROPERTIES +Command Properties +; +; new in 40.10 +; +; +++translateme+++ +MSGID_SHORTHELP_LAMP_CHANGED +This lamp indicator changes from \033bOff\033n\n\ +to \033bOk\033n when the settings have been\n\ +modified since initial loading. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +; new in 40.16 +; +; +++translateme+++ +MSGID_POPASL_UNSELECTEDIMAGE_SHORTHELP +Here you may select an iconic image that is shown left of\n\ +the menu item name, in unselected menu item state. +;Here you may select an iconic image that is shown left of\n\ +;the menu item name, in unselected menu item state. +; +; +++translateme+++ +MSGID_SAMPLE_UNSELECTEDIMAGE_SHORTHELP +This is a sample of the iconic image that will be shown\n\ +left of the menu item name, in unselected menu item state. +;This is a sample of the iconic image that will be shown\n\ +;left of the menu item name, in unselected menu item state. +; +; +++translateme+++ +MSGID_POPASL_SELECTEDIMAGE_SHORTHELP +Here you may select an iconic image that is shown left of\n\ +the menu item name, in selected menu item state. +;Here you may select an iconic image that is shown left of\n\ +;the menu item name, in selected menu item state. +; +; +; +++translateme+++ +MSGID_SAMPLE_SELECTEDIMAGE_SHORTHELP +This is a sample of the iconic image that will be shown\n\ +left of the menu item name, in selected menu item state. +;This is a sample of the iconic image that will be shown\n\ +;left of the menu item name, in selected menu item state. +; +;+++translateme+++ +MSGID_ENTRY_STRING_NAME +Name: +;Name: +; +;+++translateme+++ +MSGID_ENTRY_GROUP_UNSELECTEDIMAGE +Unselected State Image +;Unselected State Image +; +;+++translateme+++ +MSGID_ENTRY_GROUP_SELECTEDIMAGE +Selected State Image +;Selected State Image +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Scalos Menu Prefs startup failed +;Scalos Menu Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Try again|Quit +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_NEW_MENU +New Menu +;New Menu +; +;+++translateme+++ +MSGID_NEW_ITEM +New Item +;New Item +; +;+++translateme+++ +MSGID_TOOLS_MENU +Tools +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_DEFAULT_MENU_OPEN +Open +;Open +; +;+++translateme+++ +MSGID_DEFAULT_MENU_OPEN_SHORT +O +;O +; +;+++translateme+++ +MSGID_DEFAULT_MENU_INFORMATION +Information... +;Information... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_INFORMATION_SHORT +I +;I +; +;+++translateme+++ +MSGID_DEFAULT_MENU_BROWSE +Browse... +;Browse... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_BROWSE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_FIND +Find... +;Find... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_FIND_SHORT +F +;F +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT +Snapshot +;Snapshot +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT_SHORT +S +;S +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UNSNAPSHOT +Unsnapshot +;Unsnapshot +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UNSNAPSHOT_SHORT +U +;U +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLONE +Clone +;Clone +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLONE_SHORT +C +;C +; +;+++translateme+++ +MSGID_DEFAULT_MENU_COPY +Copy +;Copy +; +;+++translateme+++ +MSGID_DEFAULT_MENU_COPY_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CUT +Cut +;Cut +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CUT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PASTE +Paste +;Paste +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PASTE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DISKCOPY +Diskcopy... +;Diskcopy... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DISKCOPY_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RELABEL +Relabel... +;Relabel... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RELABEL_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_FORMAT +Format... +;Format... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_FORMAT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PROPERTIES +Properties... +;Properties... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PROPERTIES_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EDIT +Edit +;Edit +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RENAME +Rename +;Rename +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RENAME_SHORT +R +;R +; +;+++translateme+++ +MSGID_DEFAULT_MENU_LEAVEOUT +Leave Out +;Leave Out +; +;+++translateme+++ +MSGID_DEFAULT_MENU_LEAVEOUT_SHORT +L +;L +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PUTAWAY +Put Away +;Put Away +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PUTAWAY_SHORT +P +;P +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DELETE +Delete... +;Delete... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DELETE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EMPTYTRASH +Empty Trashcan... +;Empty Trashcan... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EMPTYTRASH_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLOSE +Close +;Close +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLOSE_SHORT +K +; +;+++translateme+++ +MSGID_DEFAULT_MENU_OPENPARENT +Open Parent +;Open Parent +; +;+++translateme+++ +MSGID_DEFAULT_MENU_OPENPARENT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UPDATE +Update +;Update +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UPDATE_SHORT +M +;M +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUP +Cleanup +;Cleanup +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUP_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RESIZETOFIT +Resize To Fit +;Resize To Fit +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RESIZETOFIT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SELECTCONTENTS +Select Contents +;Select Contents +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SELECTCONTENTS_SHORT +A +;A +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEARSELECTION +Clear Selection +;Clear Selection +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEARSELECTION_SHORT +Z +;Z +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT_ALL +All +;All +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT_ALL_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT_WINDOW +Window +;Window +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT_WINDOW_SHORT +W +;W +; +;+++translateme+++ +MSGID_DEFAULT_MENU_NEWDRAWER +New Drawer... +;New Drawer... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_NEWDRAWER_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SCALOS +Scalos +;Scalos +; +;+++translateme+++ +MSGID_DEFAULT_MENU_WINDOW +Window +;Window +; +;+++translateme+++ +MSGID_DEFAULT_MENU_ICONS +Icons +;Icons +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS +Drawers +;Drawers +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS +Prefs +;Prefs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_BACKDROP +Backdrop? +;Backdrop? +; +;+++translateme+++ +MSGID_DEFAULT_MENU_BACKDROP_SHORT +B +;B +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EXECUTECOMMAND +Execute Command... +;Execute Command... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EXECUTECOMMAND_SHORT +E +;E +; +;+++translateme+++ +MSGID_DEFAULT_MENU_REDRAWALL +Redraw All +;Redraw All +; +;+++translateme+++ +MSGID_DEFAULT_MENU_REDRAWALL_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UPDATEALL +Update All +;Update All +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UPDATEALL_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_LASTMESSAGE +Last Message +;Last Message +; +;+++translateme+++ +MSGID_DEFAULT_MENU_LASTMESSAGE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_ABOUT +About... +;About... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_ABOUT_SHORT +? +;? +; +;+++translateme+++ +MSGID_DEFAULT_MENU_QUIT +Quit... +;Quit... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_QUIT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY +Clean up by +;Clean up by +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_COLUMN +Column +;Column +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_COLUMN_SHORT +. +;. +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_NAME +Name +;Name +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_NAME_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_DATE +Date +;Date +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_DATE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_SIZE +Size +;Size +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_SIZE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_TYPE +Type +;Type +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_TYPE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW +Show +;Show +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_DEFAULT +Default +;Default +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_DEFAULT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_ONLYICONS +Only Icons +;Only Icons +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_ONLYICONS_SHOT +- +;- +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_ALLFILES +All Files +;All Files +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_ALLFILES_SHORT ++ +;+ +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY +View By +;View By +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_DEFAULT +Default +;Default +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_DEFAULT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_ICON +Icon +;Icon +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_ICON_SHORT +1 +;1 +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_NAME +Name +;Name +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_NAME_SHORT +2 +;2 +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_DATE +Date +;Date +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_DATE_SHORT +3 +;3 +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_SIZE +Size +;Size +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_SIZE_SHORT +4 +;4 +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_TYPE +Type +;Type +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_TYPE_SHORT +5 +;5 +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RESETSCALOS +Reset Scalos +;Reset Scalos +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RESETSCALOS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_NEWSHELL +New Shell +;New Shell +; +;+++translateme+++ +MSGID_DEFAULT_MENU_NEWSHELL_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_VOYAGER +Voyager +;Voyager +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_VOYAGER_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_ENVARC_SYS +ENVARC:Sys +;ENVARC:Sys +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_ENVARC_SYS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_WBSTARTUP +WBStartup +;WBStartup +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_WBSTARTUP_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_PREFS +Prefs +;Prefs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_PREFS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_SCALOSPREFS +Scalos Prefs +;Scalos Prefs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_SCALOSPREFS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SYSTEM +System... +;System... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_MUI +MUI... +;MUI... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_MUI_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_AHI +AHI... +;AHI... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_AHI_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCALOS +Scalos Prefs... +;Scalos Prefs... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCALOS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EMPTY_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_TOOLS +Tools +;Tools +; +;+++translateme+++ +MSGID_DEFAULT_UTILITIES +Utilities +;Utilities +; +;+++translateme+++ +MSGID_DEFAULT_PREFERENCES +Preferences +;Preferences +; +;+++translateme+++ +MSGID_DEFAULT_EXCHANGE +Exchange +;Exchange +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_MOUNTER +Mounter +;Mounter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SCSICONFIG +SCSIConfig +;SCSIConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SNOOPIUM +Snoopium +;Snoopium +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_DEFRAG +Defrag +;Defrag +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_FTMANAGER +FTManager +;FTManager +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_MUISHELL +MUIShell +;MUIShell +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SFSDOCTOR +SFSDoctor +;SFSDoctor +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_UNITCONTROL +UnitControl +;UnitControl +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_FILEIMAGECTRL +FileImageCtrl +;FileImageCtrl +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_HDCONFIG +HDConfig +;HDConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_REGTOOL +RegTool +;RegTool +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SHELL +Shell +;Shell +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_EDITOR +Editor +;Editor +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_FRAGMENT +Fragment +;Fragment +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_GRABBER +Grabber +;Grabber +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_GRAPHICBOARDS +GraphicBoards +;GraphicBoards +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_KEYSTROKE +Keystroke +;Keystroke +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MINICALC +MiniCalc +;MiniCalc +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MORE +More +;More +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MUIPROCALC +MUIProCalc +;MUIProCalc +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MULTIVIEW +Multiview +;Multiview +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MYSTICVIEW +MysticView +;MysticView +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_TASKMANAGER +TaskManager +;TaskManager +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_TRANCESTATS +Trancestats +;Trancestats +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_TIPS +Tips +;Tips +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_ZOOM +Zoom +;Zoom +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_AMIGS +AmiGS +;AmiGS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_AMIPDF +AmiPDF +;AmiPDF +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_SGRAB +SGrab +;SGrab +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_CALCULATOR +Calculator +;Calculator +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_CLOCK +Clock +;Clock +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_GRAPHICDUMP +GraphicDump +;GraphicDump +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_ICONEDIT +IconEdit +;IconEdit +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_INITPRINTER +InitPrinter +;InitPrinter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_KEYSHOW +KeyShow +;KeyShow +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MEMACS +MEmacs +;MEmacs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_NOTEPAD +Notepad +;Notepad +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PARTITIONWIZARD +Partition Wizard +;Partition Wizard +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PLAYCD +PlayCD +;PlayCD +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PREFSOBJECTSEDITOR +PrefsObjectsEditor +;PrefsObjectsEditor +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PRINTFILES +PrintFiles +;PrintFiles +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_RAWDISK +RawDisk +;RawDisk +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_SHOWCONFIG +ShowConfig +;ShowConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_UNARC +UnArc +;UnArc +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_USBINSPECTOR +USBInspector +;USBInspector +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_AMIGAINPUT +AmigaInput +;AmigaInput +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_ASL +ASL +;ASL +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_COMPATIBILITY +Compatibility +;Compatibility +; +; +MSGID_DEFAULT_MENU_PREFS_DEFICONS +DefIcons +;DefIcons +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_DOS +DOS +;DOS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_FONT +Font +;Font +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_GUI +GUI +;GUI +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_INPUT +Input +;Input +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_INTERNET +Internet +;Internet +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_LOCALE +Locale +;Locale +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_NOTIFICATIONS +Notifications +;Notifications +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PALETTE +Palette +;Palette +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PICASSO96MODE +Picasso96Mode +;Picasso96Mode +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_POINTER +Pointer +;Pointer +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_POPUPMENU +PopupMenu +;PopupMenu +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PRINTER +Printer +;Printer +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PRINTERGFX +PrinterGFX +;PrinterGFX +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PRINTERPS +PrinterPS +;PrinterPS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCREENBLANKER +ScreenBlanker +;ScreenBlanker +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCREENMODE +ScreenMode +;ScreenMode +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCREENS +Screens +;Screens +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SERIAL +Serial +;Serial +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SOUND +Sound +;Sound +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_TIME +Time +;Time +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_URL +URL +;URL +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_USB +USB +;USB +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WBPATTERN +WBPattern +;WBPattern +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WBSTARTUP +WBStartup +;WBStartup +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WORKBENCH +Workbench +;Workbench +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_INTELLIFONT +IntelliFont +;IntelliFont +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_GRAPHICDUMP +GraphicDump +;GraphicDump +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_WBCLOCK +WBClock +;WBClock +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_CACHECDFS +CacheCDFS +;CacheCDFS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_ICONTROL +IControl +;IControl +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_OVERSCAN +Overscan +;Overscan +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_REACTION +Reaction +;Reaction +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_VINCED +ViNCDe +;ViNCDe +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WARPOS +WarpOS +;WarpOS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_BENCHTRASH +BenchTrash +;BenchTrash +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_CALCULATOR +Calculator +;Calculator +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_EDITPAD +EditPad +;EditPad +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_HDTOOLBOX +HDToolBox +;HDToolBox +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_ICONEDIT +IconEdit +;IconEdit +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_INITPRINTER +InitPrinter +;InitPrinter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_IOTOOLS +IoTools +;IoTools +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_KEYSHOW +KeyShow +;KeyShow +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_LACER +Lacer +;Lacer +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_MEMACS +MEmacs +;MEmacs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_PREPCARD +PrepCard +;PrepCard +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_PRINTFILES +PrintFiles +;PrintFiles +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SHOWCONFIG +ShowConfig +;ShowConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_UNARC +Unarc +;Unarc +; +;+++translateme+++ +MSGID_DEFAULT_SYSTEM +System +;System +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_FIND +Find... +;Find... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_FIXFONT +FixFont +;FixFont +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_FORMAT +Format... +;Format... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_SHELL +Shell +;Shell +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_FORMATCDRW +FormatCDRW +;FormatCDRW +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_MEDIATOOLBOX +MediaToolBox +;MediaToolBox +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_MOUNTER +Mounter +;Mounter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_TYPEMANAGER +TypeManager +;TypeManager +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_HELP +Help +;Help +; +;----------------------------------------------------------- +; diff --git a/scalos/Prefs/Menu/Catalogs/svenska/Scalos/config.mk b/scalos/Prefs/Menu/Catalogs/svenska/Scalos/config.mk new file mode 100755 index 000000000..ec05f9b34 --- /dev/null +++ b/scalos/Prefs/Menu/Catalogs/svenska/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = svenska + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = swedish + +else + +############################################################################### +# AmigaOS and AROS + +LANG = svenska + +endif +endif diff --git a/scalos/Prefs/Menu/Catalogs/svenska/Scalos/makefile b/scalos/Prefs/Menu/Catalogs/svenska/Scalos/makefile new file mode 100644 index 000000000..5c08f6325 --- /dev/null +++ b/scalos/Prefs/Menu/Catalogs/svenska/Scalos/makefile @@ -0,0 +1,13 @@ +# makefile for Scalos (translated Texts : svenska) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1msvenska\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +ScalosMenu.catalog : ScalosMenu.ct ../../../ScalosMenu.cd + +All: ScalosMenu.catalog diff --git a/scalos/Prefs/Menu/Catalogs/svenska/Scalos/makefile-new b/scalos/Prefs/Menu/Catalogs/svenska/Scalos/makefile-new new file mode 100755 index 000000000..4299c9c0e --- /dev/null +++ b/scalos/Prefs/Menu/Catalogs/svenska/Scalos/makefile-new @@ -0,0 +1,32 @@ +# makefile for ScalosMenu (translated Texts : svenska) +# $Date: 2011-08-06 19:37:48 +0200 (Sa, 06. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = ScalosMenu + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git "a/scalos/Prefs/Menu/Catalogs/\303\203e\303\223tina/Scalos/ScalosMenu.ct" "b/scalos/Prefs/Menu/Catalogs/\303\203e\303\223tina/Scalos/ScalosMenu.ct" new file mode 100644 index 000000000..21eab4316 --- /dev/null +++ "b/scalos/Prefs/Menu/Catalogs/\303\203e\303\223tina/Scalos/ScalosMenu.ct" @@ -0,0 +1,1934 @@ +; ScalosMenu.ct +## version $VER: ScalosMenu.catalog 40.18 (24 Aug 2008 10:22:35) +## codeset 0 +## language ÃeÓtina +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Menu Plugin +; +; +MSGID_TITLENAME_CMDLIST +Scalos Internal Menu Commands +; +; +MSGID_FRAMETITLE +Menu List +; +; +MSGID_NEWINAME +NovÁ poloÚka +; +; +MSGID_HOTKEYNAME +KlÁvesa: +; +; +MSGID_NEWNAME +Nov× menu +; +; +MSGID_DELNAME +Smazat +; +; +MSGID_SAVENAME +UloÚit +; +; +MSGID_USENAME +PouÚÉt +; +; +MSGID_CANCELNAME +ZruÓit +; +; +MSGID_NEW2NAME +NovÙ pÒÉkaz +; +; +MSGID_COMMANDNAME +PÒÉkaz +; +; +MSGID_MENU_PROJECT_IMPORT +Importovat +; +; +MSGID_MENU_PROJECT_IMPORT_SHORT +I +; +; +MSGID_MENU_PROJECT_OPEN +OtevÒÉt... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +O +; +; +MSGID_MENU_PROJECT_SAVEAS +UloÚit jako... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +A +; +; +MSGID_MENU_PROJECT_QUIT +Konec +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +; +MSGID_MENU_PROJECT +Projekt +; +; +MSGID_MENU_EDIT_LASTSAVED +PoslednÉ uloÚenÉ +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +L +; +; +MSGID_MENU_EDIT +Editovat +; +; +MSGID_MENU_SETTINGS_CREATEICONS +VytvÁÒet ikony? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +I +; +; +MSGID_MENU_SETTINGS +NastavenÉ +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +Nastavit pÒedvolen× +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +D +; +; +MSGID_MENU_EDIT_RESTORE +Obnovit +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +R +; +; +MSGID_MENU_PROJECT_ABOUTMUI +O MUI... +; +; +MSGID_WBNAME +Workbench +; +; +MSGID_ADOSNAME +AmigaDOS +; +; +MSGID_STACKNAME +ZÁsobnÉk +; +; +MSGID_MAINMENUNAME +HlavnÉ menu +; +; +MSGID_COM1NAME +Backdrop +; +; +MSGID_COM2NAME +Vykonat pÒÉkaz +; +; +MSGID_COM3NAME +PÒekreslit vÓe +; +; +MSGID_COM4NAME +Zaktualizovat vÓe +; +; +MSGID_COM5NAME +O Scalos +; +; +MSGID_COM6NAME +Konec +; +; +MSGID_COM7NAME +NovÙ adresÁÒ +; +; +MSGID_COM8NAME +VyÓÓÉ adresÁÒ +; +; +MSGID_COM9NAME +ZavÒÉt +; +; +MSGID_COM10NAME +Zaktualizovat +; +; +MSGID_COM11NAME +OznaÃit vÓe +; +; +MSGID_COM12NAME +Srovnat obsah +; +; +MSGID_COM13NAME +Zapsat umÉstÅnÉ okna +; +; +MSGID_COM14NAME +Zapsat umÉstnÅnÉ oken a ikon +; +; +MSGID_COM15NAME +Ukazovat pouze ikony +; +; +MSGID_COM16NAME +Ukazovat vÓechny soubory +; +; +MSGID_COM17NAME +Zobrazovat jako ikony +; +; +MSGID_COM18NAME +Zobrazovat jako text +; +; +MSGID_COM19NAME +OtevÒÉt +; +; +MSGID_COM20NAME +NovÙ start scalosu +; +; +MSGID_COM21NAME +PÒejmenovat +; +; +MSGID_COM22NAME +Informace +; +; +MSGID_COM23NAME +Zapsat umÉstnÅnÉ +; +; +MSGID_COM24NAME +ZruÓit umÉstnÅnÉ +; +; +MSGID_COM25NAME +PÒesunout ven +; +; +MSGID_COM26NAME +VrÁtit zpÁtky +; +; +MSGID_COM27NAME +Smazat +; +; +MSGID_BARNAME +\033C +; +; +MSGID_UPNAME +Nahoru +; +; +MSGID_DOWNNAME +Dolu +; +; +MSGID_MENU_PROJECT_IMPORT_TD +ToolsDaemon... +; +; +MSGID_MENU_PROJECT_IMPORT_TD_SHORT +T +; +; +MSGID_MENU_PROJECT_IMPORT_P +Parm... +; +; +MSGID_MENU_PROJECT_IMPORT_P_SHORT +P +; +; +MSGID_COM28NAME +KopÉrovat +; +; +MSGID_ICONWINNAME +Okno ikon +; +; +MSGID_AREXXNAME +Arexx +; +;+++translateme+++ +MSGID_MENU_EDIT_COPY +Copy +;Copy +; +;+++translateme+++ +MSGID_MENU_EDIT_CUT +Cut +;Cut +; +;+++translateme+++ +MSGID_MENU_EDIT_PASTE +Paste +;Paste +; +;+++translateme+++ +MSGID_MENU_EDIT_COLLAPSE +Collapse Selected +;Collapse Selected +; +;+++translateme+++ +MSGID_MENU_EDIT_EXPAND +Expand Selected +;Expand Selected +; +;--------------------------------------------- +; +MSGID_POPMENUNAME1 +Popup Menu: Ikony diskÊ +; +; +MSGID_POPMENUNAME2 +Popup Menu: Ikony adresÁÒÊ +; +; +MSGID_POPMENUNAME3 +Popup Menu: Ikony NastrojÊ/ProjektÊ +; +; +MSGID_POPMENUNAME4 +Popup Menu: Ikony koÓÊ +; +; +MSGID_POPMENUNAME5 +Popup Menu: Oken +; +; +MSGID_ARGSNAME +WB Argumenty: +; +; +MSGID_COM29NAME +Vysypat koÓ +; +; +MSGID_COM30NAME +Last Message +; +; +MSGID_COM31NAME +PÒekreslit +; +; +MSGID_COM32NAME +Ikonifikuj +; +; +MSGID_PLUGINNAME +RozÓÉÒenÉ +; +; +MSGID_MENU_PROJECT_MERGE +PÒipoj... +; +; +MSGID_MENU_PROJECT_MERGE_SHORT +M +; +; +MSGID_MENU_EDIT_COLLAPSEALL +Collapse All +; +; +MSGID_MENU_EDIT_EXPANDALL +Expand All +; +; +MSGID_MENU_SETTINGS_HIDEOBSOLETE +Hide Obsolete? +;Hide Obsolete? +; +; +MSGID_MENU_SETTINGS_HIDEOBSOLETE_SHORT +If checked, obsolete popup menus which are now\n\ +defined via filetypes prefs are not shown. +;If checked, obsolete popup menus which are now\n\ +;defined via filetypes prefs are not shown. +; +; +MSGID_COM33NAME +Format Disk... +; +; +MSGID_COM34NAME +Shutdown... +; +; +MSGID_COM35NAME +Size to fit +; +; +MSGID_COM36NAME +Clear Selection +; +; +MSGID_POPMENUNAME6 +Popup Menu: AppIcons +; +;+++translateme+++ +MSGID_POPMENUNAME7 +Popup Menu: Desktop +;Popup Menu: Desktop +; +; +MSGID_COM37NAME +View By - Size +; +; +MSGID_COM38NAME +View By - Date +; +; +MSGID_MENU_PROJECT_ABOUT +About... +; +; +MSGID_ABOUTREQOK +_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Menu Preferences V%ld.%ld\033n\n\ +%s\n\ +© 1999%s The Scalos Team\n\ +Based on original code by Stefan Sommerfeld of ALiENDESiGN! +; +; +;*** +jl+ 20011214 +MSGID_COM39NAME +Copy file +; +; +MSGID_COM40NAME +Cut file +; +; +MSGID_COM41NAME +Paste file +; +; +MSGID_COM42NAME +View By - Type +; +; +MSGID_COM43NAME +Cleanup By - Name +; +; +MSGID_COM44NAME +Cleanup By - Date +; +; +MSGID_COM45NAME +Cleanup By - Size +; +; +MSGID_COM46NAME +Cleanup By - Type +; +;+++translateme+++ +MSGID_COM_ICONPROPERTIES +Icon properties +; +;+++translateme+++ +MSGID_COM_WINDOWPROPERTIES +Window properties +; +;+++translateme+++ +MSGID_COM47NAME +View By - Default +; +;+++translateme+++ +MSGID_COM48NAME +Show - Default +; +;+++translateme+++ +MSGID_COM49NAME +Copy to... +;Copy to... +; +;+++translateme+++ +MSGID_COM50NAME +Move to... +;Move to... +; +;+++translateme+++ +MSGID_COM51NAME +Create thumbnail +; +;+++translateme+++ +MSGID_COM_OPENNEWWINDOW +Open in new window +;Open in new window +; +;+++translateme+++ +MSGID_COM_THUMBNAILCACHECLEANUP +Cleanup thumbnail cache +; +;+++translateme+++ +MSGID_COM_FIND +Find File(s) +;Find File(s) +; +;+++translateme+++ +MSGID_COM_UNDO +Undo +;Undo +; +;+++translateme+++ +MSGID_COM_REDO +Redo +;Redo +; +;+++translateme+++ +MSGID_COM_OPENBROWSERWINDOW +Open in Browser Window +;Open in Browser Window +; +;--------------------------------------------- +; +MSGID_SHORTHELP_NEWMENUBUTTON +Press this button to create a new Menu or\n\ +Submenu entry at the currently selected position. +; +; +MSGID_SHORTHELP_NEWITEMBUTTON +Press this button to insert a new menu\n\ +item at the currently selected position. +; +; +MSGID_SHORTHELP_NEWCOMMANDBUTTON +Press this button to add a new\n\ +command to the currently menu item. +; +; +MSGID_SHORTHELP_DELBUTTON +Press this button to delete the currently\n\ +select command, menu item, or menu. +; +; +MSGID_SHORTHELP_SAVEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENVARC:Scalos/menu13.prefs\". +; +; +MSGID_SHORTHELP_USEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENV:Scalos/menu13.prefs\". +; +; +MSGID_SHORTHELP_CANCELBUTTON +Press this button to abort \n\ +and forget all changes. +; +; +MSGID_REQTITLE_SAVEERROR +Error writing menu preferences\n\ +file \"%s\"\n\ +%s +; +; +MSGID_REQTITLE_READERROR +Error reading menu preferences\n\ +file \"%s\"\n\ +%s +; +; +MSGID_IMPORTNAME +Import +; +; +MSGID_TITLE_IMPORTTD +Import ToolsDaemon Prefs +; +; +MSGID_TITLE_IMPORTP +Import ParM Prefs +; +; +MSGID_PRIORITY_SLIDER_NAME +Priority +; +; +MSGID_PRIORITY_SLIDER_BUBBLE +Use this slider to adjust the priority the command should run with. +; +; new in 40.7 +; +MSGID_PLUGIN_LIST_TITLE +Menu +; +; +MSGID_POPUP_ASLTITLE_AMIGADOS +Select AmigaDOS command +; +; +MSGID_POPUP_ASLTITLE_WORKBENCH +Select Workbench command +; +; +MSGID_POPUP_ASLTITLE_ICONWINDOW +Select directory for icon window +; +; +MSGID_POPUP_ASLTITLE_AREXX +Select ARexx program +; +; +MSGID_POPUP_ASLTITLE_MENUPLUGIN +Select Scalos Menu plugin +; +; +MSGID_MENU_PROJECT_MERGE_ASLTITLE +Select prefs to merge with +; +; +MSGID_MENU_GROUP_COMMAND_PROPERTIES +Command Properties +; +; new in 40.10 +; +; +++translateme+++ +MSGID_SHORTHELP_LAMP_CHANGED +This lamp indicator changes from \033bOff\033n\n\ +to \033bOk\033n when the settings have been\n\ +modified since initial loading. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +; new in 40.16 +; +; +++translateme+++ +MSGID_POPASL_UNSELECTEDIMAGE_SHORTHELP +Here you may select an iconic image that is shown left of\n\ +the menu item name, in unselected menu item state. +;Here you may select an iconic image that is shown left of\n\ +;the menu item name, in unselected menu item state. +; +; +++translateme+++ +MSGID_SAMPLE_UNSELECTEDIMAGE_SHORTHELP +This is a sample of the iconic image that will be shown\n\ +left of the menu item name, in unselected menu item state. +;This is a sample of the iconic image that will be shown\n\ +;left of the menu item name, in unselected menu item state. +; +; +++translateme+++ +MSGID_POPASL_SELECTEDIMAGE_SHORTHELP +Here you may select an iconic image that is shown left of\n\ +the menu item name, in selected menu item state. +;Here you may select an iconic image that is shown left of\n\ +;the menu item name, in selected menu item state. +; +; +; +++translateme+++ +MSGID_SAMPLE_SELECTEDIMAGE_SHORTHELP +This is a sample of the iconic image that will be shown\n\ +left of the menu item name, in selected menu item state. +;This is a sample of the iconic image that will be shown\n\ +;left of the menu item name, in selected menu item state. +; +;+++translateme+++ +MSGID_ENTRY_STRING_NAME +Name: +;Name: +; +;+++translateme+++ +MSGID_ENTRY_GROUP_UNSELECTEDIMAGE +Unselected State Image +;Unselected State Image +; +;+++translateme+++ +MSGID_ENTRY_GROUP_SELECTEDIMAGE +Selected State Image +;Selected State Image +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Scalos Menu Prefs startup failed +;Scalos Menu Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Try again|Quit +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_NEW_MENU +New Menu +;New Menu +; +;+++translateme+++ +MSGID_NEW_ITEM +New Item +;New Item +; +;+++translateme+++ +MSGID_TOOLS_MENU +Tools +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_DEFAULT_MENU_OPEN +Open +;Open +; +;+++translateme+++ +MSGID_DEFAULT_MENU_OPEN_SHORT +O +;O +; +;+++translateme+++ +MSGID_DEFAULT_MENU_INFORMATION +Information... +;Information... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_INFORMATION_SHORT +I +;I +; +;+++translateme+++ +MSGID_DEFAULT_MENU_BROWSE +Browse... +;Browse... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_BROWSE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_FIND +Find... +;Find... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_FIND_SHORT +F +;F +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT +Snapshot +;Snapshot +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT_SHORT +S +;S +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UNSNAPSHOT +Unsnapshot +;Unsnapshot +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UNSNAPSHOT_SHORT +U +;U +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLONE +Clone +;Clone +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLONE_SHORT +C +;C +; +;+++translateme+++ +MSGID_DEFAULT_MENU_COPY +Copy +;Copy +; +;+++translateme+++ +MSGID_DEFAULT_MENU_COPY_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CUT +Cut +;Cut +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CUT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PASTE +Paste +;Paste +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PASTE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DISKCOPY +Diskcopy... +;Diskcopy... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DISKCOPY_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RELABEL +Relabel... +;Relabel... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RELABEL_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_FORMAT +Format... +;Format... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_FORMAT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PROPERTIES +Properties... +;Properties... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PROPERTIES_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EDIT +Edit +;Edit +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RENAME +Rename +;Rename +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RENAME_SHORT +R +;R +; +;+++translateme+++ +MSGID_DEFAULT_MENU_LEAVEOUT +Leave Out +;Leave Out +; +;+++translateme+++ +MSGID_DEFAULT_MENU_LEAVEOUT_SHORT +L +;L +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PUTAWAY +Put Away +;Put Away +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PUTAWAY_SHORT +P +;P +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DELETE +Delete... +;Delete... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DELETE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EMPTYTRASH +Empty Trashcan... +;Empty Trashcan... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EMPTYTRASH_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLOSE +Close +;Close +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLOSE_SHORT +K +; +;+++translateme+++ +MSGID_DEFAULT_MENU_OPENPARENT +Open Parent +;Open Parent +; +;+++translateme+++ +MSGID_DEFAULT_MENU_OPENPARENT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UPDATE +Update +;Update +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UPDATE_SHORT +M +;M +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUP +Cleanup +;Cleanup +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUP_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RESIZETOFIT +Resize To Fit +;Resize To Fit +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RESIZETOFIT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SELECTCONTENTS +Select Contents +;Select Contents +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SELECTCONTENTS_SHORT +A +;A +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEARSELECTION +Clear Selection +;Clear Selection +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEARSELECTION_SHORT +Z +;Z +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT_ALL +All +;All +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT_ALL_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT_WINDOW +Window +;Window +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SNAPSHOT_WINDOW_SHORT +W +;W +; +;+++translateme+++ +MSGID_DEFAULT_MENU_NEWDRAWER +New Drawer... +;New Drawer... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_NEWDRAWER_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SCALOS +Scalos +;Scalos +; +;+++translateme+++ +MSGID_DEFAULT_MENU_WINDOW +Window +;Window +; +;+++translateme+++ +MSGID_DEFAULT_MENU_ICONS +Icons +;Icons +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS +Drawers +;Drawers +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS +Prefs +;Prefs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_BACKDROP +Backdrop? +;Backdrop? +; +;+++translateme+++ +MSGID_DEFAULT_MENU_BACKDROP_SHORT +B +;B +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EXECUTECOMMAND +Execute Command... +;Execute Command... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EXECUTECOMMAND_SHORT +E +;E +; +;+++translateme+++ +MSGID_DEFAULT_MENU_REDRAWALL +Redraw All +;Redraw All +; +;+++translateme+++ +MSGID_DEFAULT_MENU_REDRAWALL_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UPDATEALL +Update All +;Update All +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UPDATEALL_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_LASTMESSAGE +Last Message +;Last Message +; +;+++translateme+++ +MSGID_DEFAULT_MENU_LASTMESSAGE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_ABOUT +About... +;About... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_ABOUT_SHORT +? +;? +; +;+++translateme+++ +MSGID_DEFAULT_MENU_QUIT +Quit... +;Quit... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_QUIT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY +Clean up by +;Clean up by +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_COLUMN +Column +;Column +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_COLUMN_SHORT +. +;. +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_NAME +Name +;Name +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_NAME_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_DATE +Date +;Date +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_DATE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_SIZE +Size +;Size +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_SIZE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_TYPE +Type +;Type +; +;+++translateme+++ +MSGID_DEFAULT_MENU_CLEANUPBY_TYPE_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW +Show +;Show +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_DEFAULT +Default +;Default +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_DEFAULT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_ONLYICONS +Only Icons +;Only Icons +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_ONLYICONS_SHOT +- +;- +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_ALLFILES +All Files +;All Files +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SHOW_ALLFILES_SHORT ++ +;+ +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY +View By +;View By +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_DEFAULT +Default +;Default +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_DEFAULT_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_ICON +Icon +;Icon +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_ICON_SHORT +1 +;1 +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_NAME +Name +;Name +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_NAME_SHORT +2 +;2 +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_DATE +Date +;Date +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_DATE_SHORT +3 +;3 +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_SIZE +Size +;Size +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_SIZE_SHORT +4 +;4 +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_TYPE +Type +;Type +; +;+++translateme+++ +MSGID_DEFAULT_MENU_VIEWBY_TYPE_SHORT +5 +;5 +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RESETSCALOS +Reset Scalos +;Reset Scalos +; +;+++translateme+++ +MSGID_DEFAULT_MENU_RESETSCALOS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_NEWSHELL +New Shell +;New Shell +; +;+++translateme+++ +MSGID_DEFAULT_MENU_NEWSHELL_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_VOYAGER +Voyager +;Voyager +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_VOYAGER_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_ENVARC_SYS +ENVARC:Sys +;ENVARC:Sys +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_ENVARC_SYS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_WBSTARTUP +WBStartup +;WBStartup +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_WBSTARTUP_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_PREFS +Prefs +;Prefs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_PREFS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_SCALOSPREFS +Scalos Prefs +;Scalos Prefs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_DRAWERS_SCALOSPREFS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SYSTEM +System... +;System... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_MUI +MUI... +;MUI... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_MUI_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_AHI +AHI... +;AHI... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_AHI_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCALOS +Scalos Prefs... +;Scalos Prefs... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCALOS_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_MENU_EMPTY_SHORT + +; +;+++translateme+++ +MSGID_DEFAULT_TOOLS +Tools +;Tools +; +;+++translateme+++ +MSGID_DEFAULT_UTILITIES +Utilities +;Utilities +; +;+++translateme+++ +MSGID_DEFAULT_PREFERENCES +Preferences +;Preferences +; +;+++translateme+++ +MSGID_DEFAULT_EXCHANGE +Exchange +;Exchange +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_MOUNTER +Mounter +;Mounter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SCSICONFIG +SCSIConfig +;SCSIConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SNOOPIUM +Snoopium +;Snoopium +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_DEFRAG +Defrag +;Defrag +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_FTMANAGER +FTManager +;FTManager +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_MUISHELL +MUIShell +;MUIShell +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SFSDOCTOR +SFSDoctor +;SFSDoctor +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_UNITCONTROL +UnitControl +;UnitControl +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_FILEIMAGECTRL +FileImageCtrl +;FileImageCtrl +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_HDCONFIG +HDConfig +;HDConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_REGTOOL +RegTool +;RegTool +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SHELL +Shell +;Shell +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_EDITOR +Editor +;Editor +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_FRAGMENT +Fragment +;Fragment +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_GRABBER +Grabber +;Grabber +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_GRAPHICBOARDS +GraphicBoards +;GraphicBoards +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_KEYSTROKE +Keystroke +;Keystroke +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MINICALC +MiniCalc +;MiniCalc +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MORE +More +;More +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MUIPROCALC +MUIProCalc +;MUIProCalc +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MULTIVIEW +Multiview +;Multiview +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MYSTICVIEW +MysticView +;MysticView +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_TASKMANAGER +TaskManager +;TaskManager +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_TRANCESTATS +Trancestats +;Trancestats +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_TIPS +Tips +;Tips +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_ZOOM +Zoom +;Zoom +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_AMIGS +AmiGS +;AmiGS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_AMIPDF +AmiPDF +;AmiPDF +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_SGRAB +SGrab +;SGrab +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_CALCULATOR +Calculator +;Calculator +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_CLOCK +Clock +;Clock +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_GRAPHICDUMP +GraphicDump +;GraphicDump +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_ICONEDIT +IconEdit +;IconEdit +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_INITPRINTER +InitPrinter +;InitPrinter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_KEYSHOW +KeyShow +;KeyShow +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_MEMACS +MEmacs +;MEmacs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_NOTEPAD +Notepad +;Notepad +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PARTITIONWIZARD +Partition Wizard +;Partition Wizard +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PLAYCD +PlayCD +;PlayCD +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PREFSOBJECTSEDITOR +PrefsObjectsEditor +;PrefsObjectsEditor +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_PRINTFILES +PrintFiles +;PrintFiles +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_RAWDISK +RawDisk +;RawDisk +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_SHOWCONFIG +ShowConfig +;ShowConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_UNARC +UnArc +;UnArc +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_USBINSPECTOR +USBInspector +;USBInspector +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_AMIGAINPUT +AmigaInput +;AmigaInput +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_ASL +ASL +;ASL +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_COMPATIBILITY +Compatibility +;Compatibility +; +; +MSGID_DEFAULT_MENU_PREFS_DEFICONS +DefIcons +;DefIcons +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_DOS +DOS +;DOS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_FONT +Font +;Font +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_GUI +GUI +;GUI +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_INPUT +Input +;Input +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_INTERNET +Internet +;Internet +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_LOCALE +Locale +;Locale +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_NOTIFICATIONS +Notifications +;Notifications +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PALETTE +Palette +;Palette +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PICASSO96MODE +Picasso96Mode +;Picasso96Mode +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_POINTER +Pointer +;Pointer +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_POPUPMENU +PopupMenu +;PopupMenu +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PRINTER +Printer +;Printer +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PRINTERGFX +PrinterGFX +;PrinterGFX +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_PRINTERPS +PrinterPS +;PrinterPS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCREENBLANKER +ScreenBlanker +;ScreenBlanker +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCREENMODE +ScreenMode +;ScreenMode +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SCREENS +Screens +;Screens +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SERIAL +Serial +;Serial +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_SOUND +Sound +;Sound +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_TIME +Time +;Time +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_URL +URL +;URL +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_USB +USB +;USB +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WBPATTERN +WBPattern +;WBPattern +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WBSTARTUP +WBStartup +;WBStartup +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WORKBENCH +Workbench +;Workbench +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_INTELLIFONT +IntelliFont +;IntelliFont +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_GRAPHICDUMP +GraphicDump +;GraphicDump +; +;+++translateme+++ +MSGID_DEFAULT_MENU_UTILITIES_WBCLOCK +WBClock +;WBClock +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_CACHECDFS +CacheCDFS +;CacheCDFS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_ICONTROL +IControl +;IControl +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_OVERSCAN +Overscan +;Overscan +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_REACTION +Reaction +;Reaction +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_VINCED +ViNCDe +;ViNCDe +; +;+++translateme+++ +MSGID_DEFAULT_MENU_PREFS_WARPOS +WarpOS +;WarpOS +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_BENCHTRASH +BenchTrash +;BenchTrash +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_CALCULATOR +Calculator +;Calculator +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_EDITPAD +EditPad +;EditPad +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_HDTOOLBOX +HDToolBox +;HDToolBox +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_ICONEDIT +IconEdit +;IconEdit +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_INITPRINTER +InitPrinter +;InitPrinter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_IOTOOLS +IoTools +;IoTools +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_KEYSHOW +KeyShow +;KeyShow +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_LACER +Lacer +;Lacer +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_MEMACS +MEmacs +;MEmacs +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_PREPCARD +PrepCard +;PrepCard +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_PRINTFILES +PrintFiles +;PrintFiles +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_SHOWCONFIG +ShowConfig +;ShowConfig +; +;+++translateme+++ +MSGID_DEFAULT_MENU_TOOLS_UNARC +Unarc +;Unarc +; +;+++translateme+++ +MSGID_DEFAULT_SYSTEM +System +;System +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_FIND +Find... +;Find... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_FIXFONT +FixFont +;FixFont +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_FORMAT +Format... +;Format... +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_SHELL +Shell +;Shell +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_FORMATCDRW +FormatCDRW +;FormatCDRW +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_MEDIATOOLBOX +MediaToolBox +;MediaToolBox +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_MOUNTER +Mounter +;Mounter +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_TYPEMANAGER +TypeManager +;TypeManager +; +;+++translateme+++ +MSGID_DEFAULT_MENU_SYSTEM_HELP +Help +;Help +; +;----------------------------------------------------------- +; diff --git "a/scalos/Prefs/Menu/Catalogs/\303\203e\303\223tina/Scalos/config.mk" "b/scalos/Prefs/Menu/Catalogs/\303\203e\303\223tina/Scalos/config.mk" new file mode 100755 index 000000000..7bfe8c7a6 --- /dev/null +++ "b/scalos/Prefs/Menu/Catalogs/\303\203e\303\223tina/Scalos/config.mk" @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = ÃeÓtina + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = czech + +else + +############################################################################### +# AmigaOS and AROS + +LANG = ÃeÓtina + +endif +endif diff --git "a/scalos/Prefs/Menu/Catalogs/\303\203e\303\223tina/Scalos/makefile" "b/scalos/Prefs/Menu/Catalogs/\303\203e\303\223tina/Scalos/makefile" new file mode 100644 index 000000000..74d57e93d --- /dev/null +++ "b/scalos/Prefs/Menu/Catalogs/\303\203e\303\223tina/Scalos/makefile" @@ -0,0 +1,12 @@ +# makefile für Scalos (translated Texts : ÃeÓtina) +# 01 Jan 2004 12:38:57 + +.SUFFIXES: .ct .catalog + +.ct.catalog : + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +ScalosMenu.catalog : ScalosMenu.ct ../../../ScalosMenu.cd + +All: ScalosMenu.catalog diff --git "a/scalos/Prefs/Menu/Catalogs/\303\203e\303\223tina/Scalos/makefile-new" "b/scalos/Prefs/Menu/Catalogs/\303\203e\303\223tina/Scalos/makefile-new" new file mode 100755 index 000000000..e1c08f25f --- /dev/null +++ "b/scalos/Prefs/Menu/Catalogs/\303\203e\303\223tina/Scalos/makefile-new" @@ -0,0 +1,32 @@ +# makefile for ScalosMenu (translated Texts : ÃeÓtina) +# $Date: 2011-08-06 19:37:48 +0200 (Sa, 06. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = ScalosMenu + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Prefs/Menu/Menu.c b/scalos/Prefs/Menu/Menu.c new file mode 100644 index 000000000..113345a6f --- /dev/null +++ b/scalos/Prefs/Menu/Menu.c @@ -0,0 +1,970 @@ +// Menu.c +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef __amigaos4__ +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include // +jmc+ +#include + +#include +#include + +struct ScalosMenu_LocaleInfo +{ + APTR li_LocaleBase; + APTR li_Catalog; + struct LocaleIFace *li_ILocale; +}; + +#define ScalosMenu_NUMBERS +#define ScalosMenu_ARRAY +#define ScalosMenu_CODE +#include STR(SCALOSLOCALE) + +//---------------------------------------------------------------------------- + +// limits for various menu entries +#define MAX_MENU (NOMENU + 1) +#define MAX_MENUITEM (NOITEM + 1) +#define MAX_SUBITEM (NOSUB + 1) + +#define Sizeof(array) (sizeof(array) / sizeof((array)[0])) + +//---------------------------------------------------------------------------- + +#if !defined(__amigaos4__) && !defined(__AROS__) +#include + +long _stack = 16384; // minimum stack size, used by SAS/C startup code +#endif + +//---------------------------------------------------------------------------- + +// local data structures + +#define KeyButtonHelp(name,key,HelpText)\ + TextObject,\ + ButtonFrame,\ + MUIA_Font, MUIV_Font_Button,\ + MUIA_Text_Contents, name,\ + MUIA_Text_PreParse, "\33c",\ + MUIA_Text_HiChar , key,\ + MUIA_ControlChar , key,\ + MUIA_CycleChain , TRUE, \ + MUIA_InputMode , MUIV_InputMode_RelVerify,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShortHelp, HelpText,\ + End + + +#define Application_Return_EDIT 0 +#define Application_Return_USE 1001 +#define Application_Return_SAVE 1002 + +//---------------------------------------------------------------------------- + +// local functions + +static void init(void); +static void fail(APTR APP_Main, CONST_STRPTR str); +static BOOL OpenLibraries(void); +static void CloseLibraries(void); +static SAVEDS(APTR) INTERRUPT OpenAboutMUIFunc(struct Hook *hook, Object *o, Msg msg); +static STRPTR GetLocString(ULONG MsgId); +//static void TranslateStringArray(STRPTR *stringArray); +static struct MUI_CustomClass *OpenPrefsModule(CONST_STRPTR FileName); +static struct TagItem *CreatePluginSubWindowArray(void); +static void DisposePrefsPlugin(void); +static BOOL CheckMCCforPlugin(STRPTR *UsedClasses, size_t MaxUsedClasses); +static BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev); +#if !defined(__SASC) &&!defined(__MORPHOS__) && !defined(__amigaos4__) +size_t stccpy(char *dest, const char *src, size_t MaxLen); +#endif /* !defined(__SASC) &&!defined(__MORPHOS__) */ + +//---------------------------------------------------------------------------- + +// local data items + +struct Library *MUIMasterBase; +T_LOCALEBASE LocaleBase; +struct Library *IconBase; +struct IntuitionBase *IntuitionBase; +struct Library *ScalosPrefsPluginBase; + +#ifdef __amigaos4__ +extern struct Library *SysBase; +struct MUIMasterIFace *IMUIMaster; +struct LocaleIFace *ILocale; +struct IconIFace *IIcon; +struct IntuitionIFace *IIntuition; +struct ScalosPrefsPluginIFace *IScalosPrefsPlugin; +#endif + +static struct Catalog *MenuCatalog; + +static struct Hook AboutMUIHook = { { NULL, NULL }, HOOKFUNC_DEF(OpenAboutMUIFunc), NULL }; + +static struct MUI_CustomClass *MenuPluginClass; + +static struct TagItem *SubWindowTagList; + +static APTR Group_Plugin; +static Object **PluginSubWindows; +static APTR APP_Main; +static APTR WIN_Main; +static APTR WIN_AboutMUI; +static APTR SaveButton, UseButton, CancelButton; +static APTR MenuOpen, MenuSaveAs, MenuAbout, MenuAboutMUI, MenuQuit; +static APTR MenuResetToDefaults, MenuLastSaved, MenuRestore; +static APTR MenuMerge, MenuImport, MenuImportTD, MenuImportP; +static APTR MenuCreateIcons; +static APTR MenuCollapseAll, MenuExpandAll; + +//---------------------------------------------------------------------------- + +int main(int argc, char *argv[]) +{ + LONG Action = Application_Return_EDIT; + LONG win_opened = 0; + struct RDArgs *rdArgs = NULL; + CONST_STRPTR GivenFileName = NULL; + BPTR oldDir = (BPTR)NULL; + ULONG fCreateIcons = TRUE; + struct DiskObject *MenuDiskObject = NULL; + struct DiskObject *icon = NULL; + STRPTR ProgramName; + STRPTR UsedClasses[32]; + struct WBStartup *WBenchMsg = + (argc == 0) ? (struct WBStartup *)argv : NULL; + + init(); + + d1(kprintf(__FUNC__ "/%ld: \n", __LINE__)); + + if (WBenchMsg && WBenchMsg->sm_ArgList) + { + static char PrgNamePath[512]; + struct WBArg *arg; + + if (WBenchMsg->sm_NumArgs > 1) + { + arg = &WBenchMsg->sm_ArgList[1]; + GivenFileName = arg->wa_Name; + } + else + { + arg = &WBenchMsg->sm_ArgList[0]; + } + + ProgramName = PrgNamePath; + + NameFromLock(WBenchMsg->sm_ArgList[0].wa_Lock, PrgNamePath, sizeof(PrgNamePath)); + AddPart(PrgNamePath, WBenchMsg->sm_ArgList[0].wa_Name, sizeof(PrgNamePath)); + + oldDir = CurrentDir(arg->wa_Lock); + + icon = GetDiskObject(arg->wa_Name); + if (icon) + { + STRPTR tt; + + tt = FindToolType(icon->do_ToolTypes, "CREATEICONS"); + if (tt) + { + if (MatchToolValue(tt, "NO")) + fCreateIcons = FALSE; + } + + tt = FindToolType(icon->do_ToolTypes, "ACTION"); + if (tt) + { + if (MatchToolValue(tt, "EDIT")) + Action = Application_Return_EDIT; + if (MatchToolValue(tt, "USE")) + Action = Application_Return_USE; + if (MatchToolValue(tt, "SAVE")) + Action = Application_Return_SAVE; + } + + } + } + else + { + SIPTR ArgArray[4]; + + ProgramName = argv[0]; + + memset(ArgArray, 0, sizeof(ArgArray)); + + rdArgs = ReadArgs("FROM,EDIT/S,USE/S,SAVE/S", ArgArray, NULL); + + if (ArgArray[0]) + GivenFileName = (CONST_STRPTR) ArgArray[0]; + if (ArgArray[1]) + Action = Application_Return_EDIT; + if (ArgArray[2]) + Action = Application_Return_USE; + if (ArgArray[3]) + Action = Application_Return_SAVE; + } + + d1(kprintf(__FUNC__ "/%ld: MenuPluginClass=%08lx\n", __LINE__, MenuPluginClass)); + + if (NULL == MenuPluginClass) + fail(APP_Main, "Failed to open Menu Plugin."); + + MenuDiskObject = GetDiskObject(ProgramName); + + Group_Plugin = NewObject(MenuPluginClass->mcc_Class, 0, + MUIA_ScalosPrefs_CreateIcons, fCreateIcons, + MUIA_ScalosPrefs_ProgramName, (ULONG) ProgramName, + TAG_END); + + d1(kprintf(__FUNC__ "/%ld: Group_Plugin=%08lx\n", __LINE__, Group_Plugin)); + if (NULL == Group_Plugin) + fail(APP_Main, "Failed to create Group_Plugin."); + + if (!CheckMCCforPlugin(UsedClasses, Sizeof(UsedClasses))) + fail(APP_Main, "Required MCC missing."); + + SubWindowTagList = CreatePluginSubWindowArray(); + + d1(kprintf(__FUNC__ "/%ld: \n", __LINE__)); + + APP_Main = ApplicationObject, + MUIA_Application_Title, GetLocString(MSGID_TITLENAME), + MUIA_Application_Version, "$VER: Scalos Menu V40.20 (" __DATE__ ")" COMPILER_STRING, + MUIA_Application_Copyright, "The Scalos Team, 2000" CURRENTYEAR, + MUIA_Application_Author, "The Scalos Team", + MUIA_Application_Description, "Scalos Menu preferences editor", + MUIA_Application_Base, "SCALOS_MENU", + MenuDiskObject ? MUIA_Application_DiskObject : TAG_IGNORE, MenuDiskObject, +#if defined(MUIA_Application_UsedClasses) + MUIA_Application_UsedClasses, UsedClasses, +#endif /* MUIA_Application_UsedClasses */ + + SubWindow, WIN_Main = WindowObject, + MUIA_Window_Title, GetLocString(MSGID_TITLENAME), + MUIA_Window_ID, MAKE_ID('M','A','I','N'), + MUIA_Window_AppWindow, TRUE, + WindowContents, VGroup, + Child, Group_Plugin, + + Child, ColGroup(3), + Child, SaveButton = KeyButtonHelp(GetLocString(MSGID_SAVENAME), + 's', GetLocString(MSGID_SHORTHELP_SAVEBUTTON)), + Child, UseButton = KeyButtonHelp(GetLocString(MSGID_USENAME), + 'u', GetLocString(MSGID_SHORTHELP_USEBUTTON)), + Child, CancelButton = KeyButtonHelp(GetLocString(MSGID_CANCELNAME), + 'c', GetLocString(MSGID_SHORTHELP_CANCELBUTTON)), + End, //ColGroup(3) + End, //VGroup + End, //WindowObject + + MUIA_Application_Menustrip, MenustripObject, + Child, MenuObjectT(GetLocString(MSGID_MENU_PROJECT)), + Child, MenuOpen = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_OPEN), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_PROJECT_OPEN_SHORT), + End, + Child, MenuMerge = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_MERGE), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_PROJECT_MERGE_SHORT), + End, + Child, MenuSaveAs = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_SAVEAS), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_PROJECT_SAVEAS_SHORT), + End, + Child, MenuitemObject, + MUIA_Menuitem_Title, -1, + End, + Child, MenuImport = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_IMPORT), + Child, MenuImportTD = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_IMPORT_TD), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_PROJECT_IMPORT_TD_SHORT), + End, + Child, MenuImportP = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_IMPORT_P), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_PROJECT_IMPORT_P_SHORT), + End, + End, + Child, MenuitemObject, + MUIA_Menuitem_Title, -1, + End, + Child, MenuAbout = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUT), + End, + Child, MenuAboutMUI = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUTMUI), + End, + Child, MenuitemObject, + MUIA_Menuitem_Title, -1, + End, + Child, MenuQuit = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_QUIT), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_PROJECT_QUIT_SHORT), + End, + + End, //MenuObjectT + Child, MenuObjectT(GetLocString(MSGID_MENU_EDIT)), + Child, MenuResetToDefaults = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_EDIT_RESETTODEFAULTS), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT), + End, + Child, MenuLastSaved = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_EDIT_LASTSAVED), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_EDIT_LASTSAVED_SHORT), + End, + Child, MenuRestore = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_EDIT_RESTORE), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_EDIT_RESTORE_SHORT), + End, + Child, MenuitemObject, + MUIA_Menuitem_Title, -1, + End, + Child, MenuCollapseAll = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_EDIT_COLLAPSEALL), + End, + Child, MenuExpandAll = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_EDIT_EXPANDALL), + End, + End, //MenuObjectT + Child, MenuObjectT(GetLocString(MSGID_MENU_SETTINGS)), + Child, MenuCreateIcons = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_SETTINGS_CREATEICONS), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_SETTINGS_CREATEICONS_SHORT), + MUIA_Menuitem_Checkit, TRUE, + MUIA_Menuitem_Checked, fCreateIcons, + End, + End, //MenuObjectT + End, //MenuStripObject + + SubWindowTagList ? TAG_MORE : TAG_IGNORE, SubWindowTagList, + End; //ApplicationObject + + d1(kprintf(__FUNC__ "/%ld: APP_Main=%08lx\n", __LINE__, APP_Main)); + + if (NULL == APP_Main) + { + MUI_DisposeObject(Group_Plugin); + Group_Plugin = NULL; + fail(APP_Main, "Failed to create Application."); + } + + set(Group_Plugin, MUIA_ScalosPrefs_MainWindow, (ULONG) WIN_Main); + set(Group_Plugin, MUIA_ScalosPrefs_Application, (ULONG) APP_Main); + + DoMethod(Group_Plugin, MUIM_ScalosPrefs_PageActive, TRUE); + + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + WIN_Main, 3, MUIM_Set, MUIA_Window_Open, FALSE); + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + DoMethod(CancelButton, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + DoMethod(MenuQuit, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + DoMethod(SaveButton, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_Application_ReturnID, Application_Return_SAVE); + + DoMethod(UseButton, MUIM_Notify,MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_Application_ReturnID, Application_Return_USE); + + DoMethod(MenuQuit, MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + DoMethod(MenuOpen, MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime, + Group_Plugin, 1, MUIM_ScalosPrefs_OpenConfig); + + DoMethod(MenuSaveAs, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + Group_Plugin, 1, MUIM_ScalosPrefs_SaveConfigAs); + + DoMethod(MenuResetToDefaults, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + Group_Plugin, 1, MUIM_ScalosPrefs_ResetToDefaults); + + DoMethod(MenuLastSaved, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + Group_Plugin, 1, MUIM_ScalosPrefs_LastSavedConfig); + + DoMethod(MenuRestore, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + Group_Plugin, 1, MUIM_ScalosPrefs_RestoreConfig); + + DoMethod(MenuAbout, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + Group_Plugin, 1, MUIM_ScalosPrefs_About); + + DoMethod(MenuAboutMUI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &AboutMUIHook); + + DoMethod(MenuImportTD, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + Group_Plugin, 1, MUIM_ScalosPrefs_MenuPrefs_ImportTD); + + DoMethod(MenuImportP, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + Group_Plugin, 1, MUIM_ScalosPrefs_MenuPrefs_ImportP); + + DoMethod(MenuMerge, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + Group_Plugin, 1, MUIM_ScalosPrefs_MenuPrefs_Merge); + + DoMethod(MenuCollapseAll, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + Group_Plugin, 1, MUIM_ScalosPrefs_MenuPrefs_CollapseAll); + + DoMethod(MenuExpandAll, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + Group_Plugin, 1, MUIM_ScalosPrefs_MenuPrefs_ExpandAll); + + DoMethod(MenuCreateIcons, MUIM_Notify, MUIA_Menuitem_Checked, MUIV_EveryTime, + Group_Plugin, 3, MUIM_Set, MUIA_ScalosPrefs_CreateIcons, MUIV_TriggerValue); + + if (icon) + { + DoMethod(Group_Plugin, MUIM_ScalosPrefs_ParseToolTypes, icon->do_ToolTypes); + } + + if (GivenFileName) + { + DoMethod(Group_Plugin, MUIM_ScalosPrefs_LoadNamedConfig, GivenFileName); + } + else + { + DoMethod(Group_Plugin, MUIM_ScalosPrefs_LoadConfig); + } + + if (Application_Return_EDIT == Action) + { + set(WIN_Main, MUIA_Window_Open, TRUE); + + get(WIN_Main, MUIA_Window_Open, &win_opened); + + if (win_opened) + { + ULONG sigs = 0; + BOOL Run = TRUE; + + while (Run) + { + Action = DoMethod(APP_Main, MUIM_Application_NewInput, &sigs); + + switch (Action) + { + case MUIV_Application_ReturnID_Quit: + case Application_Return_SAVE: + case Application_Return_USE: + Run = FALSE; + break; + } + + if (Run && sigs) + { + sigs = Wait(sigs | SIGBREAKF_CTRL_C); + + if (sigs & SIGBREAKF_CTRL_C) + { + Run = FALSE; + break; + } + } + } + } + else + { + printf("failed to open main window !\n"); + } + } + + switch (Action) + { + case Application_Return_SAVE: + DoMethod(Group_Plugin, MUIM_ScalosPrefs_SaveConfig); + break; + case Application_Return_USE: + DoMethod(Group_Plugin, MUIM_ScalosPrefs_UseConfig); + break; + } + + set(WIN_Main, MUIA_Window_Open, FALSE); + + if (MenuDiskObject) + FreeDiskObject(MenuDiskObject); + if (oldDir) + CurrentDir(oldDir); + if (rdArgs) + FreeArgs(rdArgs); + if (icon) + FreeDiskObject(icon); + + + fail(APP_Main, NULL); + + return 0; +} + + +static VOID fail(APTR APP_Main, CONST_STRPTR str) +{ + if (APP_Main) + MUI_DisposeObject(APP_Main); + + DisposePrefsPlugin(); + + if (MenuCatalog) + { + CloseCatalog(MenuCatalog); + MenuCatalog = NULL; + } + + CloseLibraries(); + + if (str) + { + puts(str); + exit(20); + } + + exit(0); +} + + +static void init(void) +{ + if (!OpenLibraries()) + fail(NULL, "Failed to open "MUIMASTER_NAME"."); + + if (LocaleBase) + MenuCatalog = OpenCatalogA(NULL, "Scalos/ScalosMenu.catalog", NULL); + + MenuPluginClass = OpenPrefsModule("Menu.prefsplugin"); +} + + +static BOOL OpenLibraries(void) +{ + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + if (NULL == IntuitionBase) + return FALSE; +#ifdef __amigaos4__ + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + return FALSE; +#endif + + MUIMasterBase = OpenLibrary("zune.library", 0); + if (NULL == MUIMasterBase) + MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN-1); + if (NULL == MUIMasterBase) + return FALSE; +#ifdef __amigaos4__ + IMUIMaster = (struct MUIMasterIFace *)GetInterface((struct Library *)MUIMasterBase, "main", 1, NULL); + if (NULL == IMUIMaster) + return FALSE; +#endif + + IconBase = OpenLibrary("icon.library", 0); + if (NULL == IconBase) + return FALSE; +#ifdef __amigaos4__ + IIcon = (struct IconIFace *)GetInterface((struct Library *)IconBase, "main", 1, NULL); + if (NULL == IIcon) + return FALSE; +#endif + + LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 39); +#ifdef __amigaos4__ + if (LocaleBase) + ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL); +#endif + + return TRUE; +} + + +static void CloseLibraries(void) +{ +#ifdef __amigaos4__ + if (ILocale) + { + DropInterface((struct Interface *)ILocale); + ILocale = NULL; + } +#endif + if (LocaleBase) + { + CloseLibrary((struct Library *) LocaleBase); + LocaleBase = NULL; + } +#ifdef __amigaos4__ + if (IIcon) + { + DropInterface((struct Interface *)IIcon); + IIcon = NULL; + } +#endif + if (IconBase) + { + CloseLibrary(IconBase); + IconBase = NULL; + } +#ifdef __amigaos4__ + if (IMUIMaster) + { + DropInterface((struct Interface *)IMUIMaster); + IMUIMaster = NULL; + } +#endif + if (MUIMasterBase) + { + CloseLibrary(MUIMasterBase); + MUIMasterBase = NULL; + } +#ifdef __amigaos4__ + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } +#endif + if (IntuitionBase) + { + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } +} + +//---------------------------------------------------------------------------- + +static STRPTR GetLocString(ULONG MsgId) +{ + struct ScalosMenu_LocaleInfo li; + + li.li_Catalog = MenuCatalog; +#ifndef __amigaos4__ + li.li_LocaleBase = LocaleBase; +#else + li.li_ILocale = ILocale; +#endif + + return (STRPTR) GetScalosMenuString(&li, MsgId); +} +/* +static void TranslateStringArray(STRPTR *stringArray) +{ + while (*stringArray) + { + *stringArray = GetLocString((ULONG) *stringArray); + stringArray++; + } +} +*/ +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT OpenAboutMUIFunc(struct Hook *hook, Object *o, Msg msg) +{ + if (NULL == WIN_AboutMUI) + { + WIN_AboutMUI = MUI_NewObject(MUIC_Aboutmui, + MUIA_Window_RefWindow, WIN_Main, + MUIA_Aboutmui_Application, APP_Main, + End; + } + + if (WIN_AboutMUI) + set(WIN_AboutMUI, MUIA_Window_Open, TRUE); + + return 0; +} + +//---------------------------------------------------------------------------- + +static struct MUI_CustomClass *OpenPrefsModule(CONST_STRPTR FileName) +{ + struct MUI_CustomClass *pclass = NULL; + + d1(kprintf(__FUNC__ "/%ld: FileName=<%s>\n", __LINE__, FileName)); + + do { + ScalosPrefsPluginBase = OpenLibrary(FileName, 0); + d1(kprintf(__FUNC__ "/%ld: ScalosPrefsPluginBase=%08lx\n", __LINE__, ScalosPrefsPluginBase)); + if (NULL == ScalosPrefsPluginBase) + break; +#ifdef __amigaos4__ + IScalosPrefsPlugin = (struct ScalosPrefsPluginIFace *)GetInterface( + ScalosPrefsPluginBase, "main", 1, NULL + ); +#endif + + pclass = (struct MUI_CustomClass *) SCAGetPrefsInfo(SCAPREFSINFO_GetClass); + d1(kprintf(__FUNC__ "/%ld: PluginClass=%08lx\n", __LINE__, pclass)); + if (NULL == pclass) + break; + } while (0); + + if (NULL == pclass) + DisposePrefsPlugin(); + + return pclass; +} + + +static struct TagItem *CreatePluginSubWindowArray(void) +{ + struct TagItem *SubWindowTagList; + struct TagItem *ti; + ULONG SubWindowCount = 0; + ULONG n; + + d1(kprintf(__FUNC__ "/%ld: \n", __LINE__)); + + PluginSubWindows = (Object **) DoMethod(Group_Plugin, MUIM_ScalosPrefs_CreateSubWindows); + + d1(kprintf(__FUNC__ "/%ld: PluginSubWindows=%08lx\n", __LINE__, PluginSubWindows)); + + for (n=0; PluginSubWindows && PluginSubWindows[n]; n++) + SubWindowCount++; + + d1(kprintf(__FUNC__ "/%ld: SubWindowCount=%lu\n", __LINE__, SubWindowCount)); + + SubWindowTagList = ti = calloc(1 + SubWindowCount, sizeof(struct TagItem)); + + d1(kprintf(__FUNC__ "/%ld: SubWindowTagList=%08lx\n", __LINE__, SubWindowTagList)); + if (NULL == SubWindowTagList) + return NULL; + + for (n=0; PluginSubWindows && PluginSubWindows[n]; n++) + { + ti->ti_Tag = MUIA_Application_Window; + ti->ti_Data = (ULONG) PluginSubWindows[n]; + ti++; + } + + ti->ti_Tag = TAG_END; + + d1(kprintf(__FUNC__ "/%ld: SubWindowTagList=%08lx\n", __LINE__, SubWindowTagList)); + + return SubWindowTagList; +} + + +static void DisposePrefsPlugin(void) +{ +#ifdef __amiagos4__ + if (IScalosPrefsPlugin) + { + DropInterface((struct Interface *)IScalosPrefsPlugin); + IScalosPrefsPlugin = NULL; + } +#endif + if (ScalosPrefsPluginBase) + { + d1(kprintf(__FUNC__ "/%ld: Plugin=<%s> OpenCount=%ld\n", \ + __LINE__, ScalosPrefsPluginBase->lib_Node.ln_Name, ScalosPrefsPluginBase->lib_OpenCnt)); + + if (NULL == Group_Plugin) + CloseLibrary(ScalosPrefsPluginBase); + ScalosPrefsPluginBase = NULL; + } +} + +static BOOL CheckMCCforPlugin(STRPTR *UsedClasses, size_t MaxUsedClasses) +{ + const struct MUIP_ScalosPrefs_MCCList *RequiredMccList = NULL; + + RequiredMccList = (const struct MUIP_ScalosPrefs_MCCList *) DoMethod(Group_Plugin, MUIM_ScalosPrefs_GetListOfMCCs); + + while (RequiredMccList && RequiredMccList->MccName) + { + if (!CheckMCCVersion(RequiredMccList->MccName, + RequiredMccList->MccMinVersion, + RequiredMccList->MccMinRevision)) + return FALSE; + + if (MaxUsedClasses > 1) + { + *UsedClasses++ = (STRPTR) RequiredMccList->MccName; + MaxUsedClasses--; + } + + RequiredMccList++; + } + + *UsedClasses = NULL; + + return TRUE; +} + +//---------------------------------------------------------------------------- + +// Checks if a certain version of a MCC is available +static BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev) +{ + BOOL flush = TRUE; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: %s ", name, __LINE__);) + + while (1) + { + ULONG ver = 0; + ULONG rev = 0; + struct Library *base; + char libname[256]; + + // First we attempt to acquire the version and revision through MUI + Object *obj = MUI_NewObject((STRPTR) name, TAG_DONE); + if (obj) + { + get(obj, MUIA_Version, &ver); + get(obj, MUIA_Revision, &rev); + + MUI_DisposeObject(obj); + + if(ver > minver || (ver == minver && rev >= minrev)) + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: v%ld.%ld found through MUIA_Version/Revision\n", __LINE__, ver, rev);) + return TRUE; + } + } + + // If we did't get the version we wanted, let's try to open the + // libraries ourselves and see what happens... + stccpy(libname, "PROGDIR:mui", sizeof(libname)); + AddPart(libname, name, sizeof(libname)); + + if ((base = OpenLibrary(&libname[8], 0)) || (base = OpenLibrary(&libname[0], 0))) + { + UWORD OpenCnt = base->lib_OpenCnt; + + ver = base->lib_Version; + rev = base->lib_Revision; + + CloseLibrary(base); + + // we add some additional check here so that eventual broken .mcc also have + // a chance to pass this test (i.e. Toolbar.mcc is broken) + if (ver > minver || (ver == minver && rev >= minrev)) + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: v%ld.%ld found through OpenLibrary()\n", __LINE__, ver, rev);) + return TRUE; + } + + if (OpenCnt > 1) + { + if (MUI_Request(NULL, NULL, 0L, GetLocString(MSGID_STARTUP_FAILURE), + GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), GetLocString(MSGID_STARTUP_MCC_IN_USE), + (ULONG) name, minver, minrev, ver, rev)) + { + flush = TRUE; + } + else + break; + } + + // Attempt to flush the library if open count is 0 or because the + // user wants to retry (meaning there's a chance that it's 0 now) + + if (flush) + { + struct Library *result; + + Forbid(); + if ((result = (struct Library *) FindName(&((struct ExecBase *)SysBase)->LibList, name))) + RemLibrary(result); + Permit(); + flush = FALSE; + } + else + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: couldn`t find minimum required version.\n", __LINE__);) + + // We're out of luck - open count is 0, we've tried to flush + // and still haven't got the version we want + // MUI_RequestA + if (MUI_Request(NULL, NULL, 0L, GetLocString(MSGID_STARTUP_FAILURE), + GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), GetLocString(MSGID_STARTUP_OLD_MCC), + (ULONG) name, minver, minrev, ver, rev)) + { + flush = TRUE; + } + else + break; + } + } + else + { + // No MCC at all - no need to attempt flush + flush = FALSE; + if (!MUI_Request(NULL, NULL, 0L, GetLocString(MSGID_STARTUP_FAILURE), + GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), GetLocString(MSGID_STARTUP_MCC_NOT_FOUND), + (ULONG) name, minver, minrev)) + { + break; + } + } + } + + return FALSE; +} + +//---------------------------------------------------------------------------- + +#if !defined(__SASC) && !defined(__amigaos4__) +// Replacement for SAS/C library functions + +#if !defined(__MORPHOS__) +// Replacement for SAS/C library functions + +size_t stccpy(char *dest, const char *src, size_t MaxLen) +{ + size_t Count = 0; + + while (*src && MaxLen > 1) + { + *dest++ = *src++; + MaxLen--; + Count++; + } + *dest = '\0'; + Count++; + + return Count; +} +#endif /*__MORPHOS__*/ + +#endif /* !defined(__SASC) && !defined(__amigaos4__) */ +//----------------------------------------------------------------------------- diff --git a/scalos/Prefs/Menu/ParM.cfg b/scalos/Prefs/Menu/ParM.cfg new file mode 100755 index 000000000..bfb016b44 --- /dev/null +++ b/scalos/Prefs/Menu/ParM.cfg @@ -0,0 +1,294 @@ +CMDWIN "CON:0/10/640/246/ParM:Your command.../WAIT/CLOSE" +SHELLWIN "CON:0/11/640/100/ParM Shell/AUTO/CLOSE/WAIT" +SHORTCUTQUAL "" + +COLOR 1 +MENU "Utilities" + SUBMENU "CED" + ITEM "ParM" RUN SYS:Utilities/Ed S:ParM.cfg + ITEM "BrowserII" RUN SYS:Utilities/Ed SYS:Utilities/BrowserII.menu + ITEM "FileTypes" RUN SYS:Utilities/Ed S:FileTypes + ITEM "StartUp-Sequence" RUN SYS:Utilities/Ed S:StartUp-Sequence + ITEM "MountList" RUN SYS:Utilities/Ed Devs:MountList + ITEM "Add" RUN SYS:Utilities/Ed Vrack:Bordel/Addresses + ITEM "ArcList" RUN SYS:Utilities/Ed Vrack:Bordel/ArcList + ITEM "Memo" RUN SYS:Utilities/Ed Vrack:Bordel/Memo + ITEM "Prg" RUN SYS:Utilities/Ed Vrack:Bordel/Notes_prg + ENDSUBMENU + ITEM "TxEd" WB SYS:Utilities/TxEd S:Startup.hd + ITEM {+} "iCalc" WB SYS:Tools/ICalc + ITEM "PP" WB PRG:Utils/PowerPacker + ITEM "Imploder" RUN PRG:Utils/Imploder/Imploder/Imploder SHORTROOT + ITEM "SetColors" RUN WB:Tools/SetColors DELAY 2 + ITEM PopUpMenu WB SYS:Tools/Commodities/MagicMenu + ITEM SetMouse WB SYS:Tools/SetMouse + ITEM QB WB PRI -1 PRG:Utils/QB/Quarterback + ITEM Diavolo WB PRG:Utils/Diavolo/Diavolo + ITEM Cx WB SYS:Tools/Commodities/Exchange + ITEM MultiFS WB SYS:Tools/Commodities/MFS + ITEM CrossDos WB SYS:Tools/Commodities/CrossDOS + ITEM ToolManager WB Sys:WBStartup/ToolManager QUIT + ITEM ToolAlias WB Sys:Tools/Commodities/ToolAlias + +MENU "Disk" + ITEM {B} "BrowserII" RUN Run Play8SVX WB:Sounds/AVosOrdres -w;SYS:Utilities/BrowserII + SUBMENU AddBuffers + ITEM "DF0: +200" RUN AddBuffers DF0: 200 + ITEM "DF0: -200" RUN AddBuffers DF0: -200 + ITEM "DF0: +1759" RUN AddBuffers DF0: 1759 + ITEM "DF0: -1759" RUN AddBuffers DF0: -1759 + ITEM "DF2: 1759" RUN AddBuffers DF2: 1759 + ITEM "DF2: +200" RUN AddBuffers DF2: 1759 + ENDSUBMENU + SUBMENU "FastCache" + ITEM "HD 1: Dflt" RUN SYS:System/FastCache -DEVICE=scsi.device -UNIT=1 -WRITE_RETENTION_TIME=30 -QUIET_WRITE_TIME=1 + ITEM "HD 1: Stat" RUN SYS:System/FastCacheStats -PORT=FastCache.scsi.device.1 + ITEM "DF0: 256Ko" RUN SYS:System/FastCache -DEVICE=trackdisk.device -UNIT=0 -NUM_LINES=32 -LINE_SIZE=8 -WRITE_RETENTION_TIME=240 -QUIET_WRITE_TIME=5 + ITEM "DF0: 880Ko" RUN SYS:System/FastCache -DEVICE=trackdisk.device -UNIT=0 -NUM_LINES=220 -LINE_SIZE=8 -WRITE_RETENTION_TIME=240 -QUIET_WRITE_TIME=5 + ITEM "DF0: 1.7Mo" RUN SYS:System/FastCache -DEVICE=trackdisk.device -UNIT=0 -NUM_LINES=440 -LINE_SIZE=8 -WRITE_RETENTION_TIME=240 -QUIET_WRITE_TIME=5 + ITEM "DF2: 256Ko" RUN SYS:System/FastCache -DEVICE=trackdisk.device -UNIT=2 -NUM_LINES=32 -LINE_SIZE=8 -WRITE_RETENTION_TIME=240 -QUIET_WRITE_TIME=5 + ITEM "DF2: 880Ko" RUN SYS:System/FastCache -DEVICE=trackdisk.device -UNIT=2 -NUM_LINES=220 -LINE_SIZE=8 -WRITE_RETENTION_TIME=240 -QUIET_WRITE_TIME=5 + ENDSUBMENU + SUBMENU "HyperCache" + ITEM "DF0: 512" RUN SYS:System/HyperCache -d trackdisk.device -u 0 -s 2 -l 16 -p 32 + ITEM "DF2: 512" RUN SYS:System/HyperCache -d trackdisk.device -u 2 -s 2 -l 32 -p 16 + ITEM "C. Info" SHELL WIN "CON://640/246/HyperCache Info:/AUTO/CLOSE/WAIT" SYS:System/CacheInfo + ENDSUBMENU + ITEM "PowerCache" WB SYS:Tools/Commodities/PowerCache/PowerCache + ITEM FixDisk RUN PRG:Utils/Disk/FixDisk/FixDisk DOOM + ITEM DiskSalv RUN PRG:Utils/Disk/DiskSalv/DiskSalv + ITEM ReOrg WB PRG:Utils/Disk/ReOrg/ReOrg + ITEM "Recovery" WB PRG:Utils/Disk/Recovery/Recovery + ITEM "DPU" WB PRG:Utils/Disk/DPU + ITEM "VBS" WB PRG:FileDisk/VBS/VBS + +MENU "SysExp" + ITEM "WB" RUN FailAt 21;Cd SYS:Storage/DOSDrivers/;MFSMount DF0;Cd SYS:Storage/DOSDrivers/;MFSMount DF2;LoadWB -DEBUG DELAY NEWPATH + ITEM "NewIcon" RUN Cd PRG:Pix/NewIcon;Icons + ITEM "ParM Zombie" RUN Wait 10;$ParM + ITEM "WBGlimps" RUN Run >NIL: MagicWB-Demon 4,8,85,9 5,37,81,96 6,11,93,88 7,100,110,0;Wait 1;Cd PRG:Pix/GlimpsPic/;WBGlimps + ITEM "PenCopy" RUN MagicWB-Demon 4,8,85,9 5,37,81,96 6,11,93,88 7,100,110,0 + ITEM "PenCopy MgWB 16" RUN MagicWB-Demon 4,123,123,123 5,175,175,175 6,170,144,124 7,255,169,151 8,0,0,255 9,40,62,91 10,96,128,96 11,226,209,119 + ITEM "HAM6 WB" RUN Copy WB:Prefs/Presets/HAM6-ScreenMode.prefs Env:Sys/ScreenMode.prefs + ITEM {X} "Xoper" WB SYS:System/Xoper -b + ITEM "Scout" WB SYS:System/Scout + ITEM "NoFastMem" WB SYS:System/NoFastMem + ITEM "Rexx" RUN SYS:System/RexxMast + ITEM "MUI" RUN MUI + ITEM "CPUSet" WB SYS:Tools/CPUSet + ITEM "PerfMon" RUN SYS:System/PM WIDTH 260 HEIGHT 120 RATE 20 MEMLINE 3 RMSLINE 6 + ITEM "PerfMon ?" REQUEST RUN SYS:System/PM WIDTH 260 HEIGHT 120 RATE 20 MEMLINE 3 RMSLINE 6 TASK "" + ITEM "Yaps" WB SYS:Tools/Yaps + ITEM "VirusTest" RUN WBe:CStartup/Virus_Checker -t0 -l229 -w200 + ITEM "SFragMem" WB WB:System/SFragMem + #it seem loadlib don't work with this library + ITEM "SwazInfo" RUN Cd PRG:Utils/SwazInfo;Assign Libs: "" ADD;SwazInfo CENTERED + ITEM "ShowPatch" SHELL WIN "CON:0/11/440/146/Patch list/AUTO/CLOSE/WAIT" WBe:CStartup/ShowPatch NOFD + SUBMENU "Envoy" + ITEM "SetUp" RUN CD SYS:Envoy;For *.library DO LoadLib "%%";WBRun "SYS:Envoy/Services/Services Manager";WBRun "SYS:Envoy/Accounts/Accounts Manager" + ITEM "Connect" RUN WBRun "SYS:Envoy/Configuration/Filesystem Imports" + ENDSUBMENU + SUBMENU "Lock" + ITEM {L} "ALL" RUN Lock wDH0: ON;Lock wDH1: ON;Lock wDH2: ON; + ITEM "UnLock" RUN Lock wDH0: OFF;Lock wDH1: OFF;Lock wDH2: OFF; + ENDSUBMENU + SUBMENU "GigaMem" + ITEM "On" RUN Avail FLUSH;WBRun SYS:System/GigaMem/GigaMem + ITEM "OFF" SHELL WIN "CON:0/11/640/246/GigaMem/AUTO/CLOSE/WAIT" SYS:System/GigaMem/GigaMem -q + ITEM {a} "Avail" SHELL WIN "CON:0/11/640/246/GigaMem/AUTO/CLOSE/WAIT" SYS:System/GigaMem/GigaMem -a;SYS:System/GigaMem/GigaMem + ITEM "Prefs" WB SYS:System/GigaMem/GigaMemPrefs + ENDSUBMENU + SUBMENU "VMM" + ITEM "On" RUN Avail FLUSH;WBRun SYS:System/VMM/VMM + ITEM "Off" RUN CLIExchange KILL "VMM" + ITEM "Stat" WB SYS:System/VMM/VMMStat + ITEM "Usage" WB SYS:System/VMM/VMMUsage + ENDSUBMENU + SUBMENU JobManager + ITEM "On" RUN Sys:System/JM -init + ITEM "Off" RUN SYS:System/JM -halt + ITEM "UpTime" SHELL WIN "CON:0/11/640/246/UpTime/AUTO/CLOSE/WAIT" UpTime + ITEM "Stat" SHELL WIN "CON:0/11/640/246/Stat/AUTO/CLOSE/WAIT" Stat + ITEM "ps" SHELL WIN "CON:0/11/640/246/ps/AUTO/CLOSE/WAIT" ps + ITEM "Pri" SHELL WIN "CON:0/11/640/246/Pri/AUTO/CLOSE/WAIT" Pri- + ITEM "TaskInfo" SHELL WIN "CON:0/11/640/246/TaskInfo/AUTO/CLOSE/WAIT" TaskInfo + ENDSUBMENU + BARLABEL + ITEM "MemMan" RUN GOD:MemMan + ITEM "SnoopDos" WB Sys:Tools/SnoopDos + ITEM "SnoopToolsTypes" WB PRG:Utils/IconTrace + ITEM "HyperBrowser" RUN GOD:HyperBrowser + ITEM "MeMeter" RUN GOD:MeMeter + ITEM "AMonitor" RUN God:Amonitor + ITEM "Fenster V2.2" RUN God:Fenster + ITEM "Enforcer" RUN GOD:Enforcer SHOWPC DEADLY VERBOSE PRIORITY 18 FILE "CON:////Enforcer/AUTO/CLOSE/WAIT" BUFFERSIZE 10000 + ITEM "Enforcer off" RUN GOD:Enforcer QUIT + ITEM "MungWall PAR" SHELL PRI 18 WIN "CON:0/11/640/100/MungWall PAR/AUTO/CLOSE" Avail FLUSH;GOD:mungwall.par INFO NAMETAG + ITEM "MungWall SER" SHELL PRI 18 WIN "CON:0/11/640/100/MungWall SER/AUTO/CLOSE" Avail FLUSH;GOD:mungwall INFO NAMETAG SHOWFAIL + ITEM "MW snoop" REQUEST SHELL PRI 18 WIN "CON:0/11/640/100/MungWall SER/AUTO/CLOSE" GOD:mungwall UPDATE SNOOP INFO NAMETAG SHOWFAIL TASK [] + ITEM "Sushi" RUN PRI 18 GOD:Sushi <>"CON:0/120/640/200/Sushi CTRL-C=Quit CTRL-E=Empty CTRL-F=File/AUTO/CLOSE/WAIT/" ON BUFK=128 NOPROMPT ASKEXIT ASKSAVE + ITEM "Lens" WB GOD:Lens + +MENU "CLI" + ITEM {S} "AmigaShell" RUN NewShell "CON:0/15//613/AmigaShell/AUTO/CLOSE/MINI/JUMP" + ITEM "AmigaShell" RUN NewShell "CON:0/15///AmigaShell/CLOSE" + ITEM "WShell" RUN C:WShell + +MENU "Devs" + ITEM Format WB SYS:System/Format + ITEM "Format DF0:PFS0" SHELL SYS:System/Format DRIVE DF0: NAME PFS0 FS=PFS\0 + ITEM "Format DF2:PFS0" SHELL SYS:System/Format DRIVE DF2: NAME PFS0 FS=PFS\0 + ITEM BFormat SHELL WIN "CON:0/11/640/100/Format Bad (FFS)/AUTO/CLOSE/WAIT" PRG:Utils/Disk/BFormat DRIVE DF0: NAME BFormat FFS SLOW;DiskChange DF0:;Echo >DF0:WarningBadFormat "This disk contain bad blocks/tracks.";FileNote DF0:WarningBadFormat "This disk containt bad blocks/tracks" + SUBMENU "EPU" + #whith NoEXNEXT I get epued size but is much faster + ITEM "Window" RUN SYS:Tools/DiskExpander WB + ITEM "Info" SHELL WIN "CON:0/11/440/300/EPU status/AUTO/CLOSE/WAIT" FailAt 21;Echo "wDH1:";SYS:Tools/DiskExpander Device wDH1: INFO;Echo "wDH2:";SYS:Tools/DiskExpander Device wDH2: INFO;Echo "VMEM:";SYS:Tools/DiskExpander Device VMEM: INFO;Echo "SDH0:";SYS:Tools/DiskExpander Device SDH0: INFO;Echo "DF0:";SYS:Tools/DiskExpander Device DF0: INFO + BARLABEL + ITEM "sDH0: ADD" RUN SYS:Tools/DiskExpander Device sDH0: Compressor RAKE PACK + ITEM "sDH0: RAKE" RUN SYS:Tools/DiskExpander Device sDH0: Compressor RAKE PACK CHANGE + ITEM "sDH0: FAST" RUN SYS:Tools/DiskExpander Device sDH0: Compressor FAST PACK CHANGE + BARLABEL + ITEM "wDH2: ADD ?" RUN Set Lib `RequestFile Libs:Compressors TITLE "Choose compress library" ACCEPTPATTERN "xpk????.library"`;Set Lib `BaseName $Lib`;Set Lib `Echo "$Lib" FIRST 4 LEN 4`;WB:Tools/DiskExpander DEVICE wDH2 COMPRESSOR $Lib BLOCK 32 + ITEM {0} "wDH2: NoS" RUN WB:Tools/DiskExpander DEVICE wDH2: !Pack CHANGE + ITEM {1} "wDH2: RAKE" RUN WB:Tools/DiskExpander DEVICE wDH2 COMPRESSOR RAKE BLOCK 32 PACK CHANGE + ITEM "wDH2: SQSH" RUN SYS:Tools/DiskExpander Device wDH2: Compressor SQSH BLOCK 32 PACK CHANGE + ITEM {2} "wDH2: FAST" RUN WB:Tools/DiskExpander DEVICE wDH2 COMPRESSOR FAST BLOCK 32 PACK CHANGE + ITEM "wDH2: REM" RUN WB:Tools/DiskExpander DEVICE wDH2: REMOVE + BARLABEL + ITEM "NBU: NoS" RUN WB:Tools/DiskExpander DEVICE NBU: !Pack CHANGE + ITEM "NBU: RAKE" RUN WB:Tools/DiskExpander DEVICE NBU COMPRESSOR RAKE BLOCK 32 PACK CHANGE + BARLABEL + ITEM "DF0: SHRI" RUN WB:Tools/DiskExpander DEVICE DF0 COMPRESSOR SHRI BLOCK 32 PACK + ITEM "DF0: RAKE" RUN WB:Tools/DiskExpander DEVICE DF0 COMPRESSOR RAKE BLOCK 32 PACK + ITEM "DF0: FAST" RUN WB:Tools/DiskExpander DEVICE DF0 COMPRESSOR FAST BLOCK 32 PACK CHANGE + ITEM "DF0: REM" RUN WB:Tools/DiskExpander DEVICE DF0 REMOVE + ITEM "DF2: RAKE" RUN WB:Tools/DiskExpander DEVICE DF2 COMPRESSOR RAKE BLOCK 32 PACK + ITEM "DF2: FAST" RUN WB:Tools/DiskExpander DEVICE DF2 COMPRESSOR FAST BLOCK 32 PACK CHANGE + ITEM "DF2: REM" RUN WB:Tools/DiskExpander DEVICE DF2 REMOVE + BARLABEL + ENDSUBMENU + ITEM "DF0:*" RUN Cd SYS:Storage/DOSDrivers/;MFSMount DF0 + ITEM "DF2:*" RUN Cd SYS:Storage/DOSDrivers/;MFSMount DF2 + ITEM "DEV:" RUN Mount DEV: + SUBMENU VD0: + ITEM Mount RUN Mount VD0: + ITEM Clean WB c:CleanVD0 + ITEM Kill WB c:KillVD0 + ENDSUBMENU + SUBMENU RAD: + ITEM Mount RUN Mount RAD: + ITEM Kill RUN RemRad + ENDSUBMENU + ITEM RRD: RUN Mount RRD: + ITEM PC0: RUN Mount PC0: + ITEM PC2: RUN Mount PC2: + SUBMENU FMS: + ITEM "Assign" RUN Assign FMS: Vrack:FMS/;Assign Devs: FMS: ADD + ITEM "Mount FS0:" RUN Mount FS0: + ITEM "Mount FS1:" RUN Mount FS1: + ITEM "Mount IBMC:" RUN Mount IBMC: + ENDSUBMENU + SUBMENU XD0: + ITEM "Assign" RUN Assign XPKD: Vrack:XPKD/;Assign Devs: XPKD: ADD + ITEM "Mount XD0:" RUN Mount XD0: + ITEM "Mount XD1:" RUN Mount XD1: + ENDSUBMENU + ITEM XH0: RUN Mount XH0: + ITEM wDH4: RUN RDBMount wDH4 ExecDev scsi.device UnitNr 0 FS L:ProfFileSystem9.5.4 +# ITEM wDH: SHELL WIN "CON:0/11/440/146/Mounting.../AUTO/CLOSE/WAIT" Set echo on;RDBMount wDH4 ExecDev scsi.device UnitNr 0 FS=L:MultiUserFileSystem;ValidWait wDH4:;LoadLib wDH4:MultiUser/Libs/multiuser.library;LoadLib SYS:Envoy/accounts.library;SRC:MultiUser/C/Login GUI GLOBAL;SRC:MultiUser/C/Login OWN PROCESS `Status COMMAND SYS:Tools/ParM`;SRC:MultiUser/C/Login TASK RexxMaster OWN +# ITEM wDH5: SHELL WIN "CON:0/11/440/146/Mounting.../AUTO/CLOSE/WAIT" Set echo on;RDBMount wDH5 ExecDev scsi.device UnitNr 0 FS=L:MultiUserFileSystem;ValidWait wDH5:;LoadLib wDH4:MultiUser/Libs/multiuser.library;LoadLib wDH5:MultiUser/Libs/accounts.library;SRC:MultiUser/C/Login Rougier GUI GLOBAL;SRC:MultiUser/C/Login OWN PROCESS `Status COMMAND SYS:Tools/ParM`;SRC:MultiUser/C/Login TASK RexxMaster OWN + ITEM wDH5: RUN RDBMount wDH5 ExecDev scsi.device UnitNr 0 + ITEM DM0: RUN Mount DM0: + ITEM PC: RUN RDBMount PC ExecDev scsi.device UnitNr 0;SYS:Tools/EPU DEVICE PC LIBRARY epu1 BLOCK 32 + ITEM VMEM:MAC RUN Assign VMEM: DISMOUNT;RDBMount VMEM: ExecDev scsi.device UnitNr 0 FS=L:CrossMACFileSystem + ITEM CD0: RUN Mount CD0: + ITEM "AMAX" RUN RDBMount AMAX0: ExecDev scsi.device UnitNr 0 FS=L:CrossMACFileSystem + ITEM ALL RUN BD SYS:Storage/DOSDrivers + +MENU "Copy" + ITEM "SD" WB Sys:Tools/SD + ITEM "Zoom" WB PRG:Utils/Arc/Zoom/Zoom + ITEM "DMS" WB PRG:Utils/Arc/DMSWin + ITEM "Cmp DF0 & DF2" RUN PRG:FileDisk/DiskCopy2 from df0: to df2: opt d + +MENU "Pix" + ITEM "DPaint" WB PRG:Pix/DPaint/DPaint + ITEM "Brilliance" WB PRG:Pix/Brilliance/Brilliance + ITEM "TrueBrilliance" WB PRG:Pix/Brilliance/TrueBrilliance + ITEM "IconPaint" WB PRG:Pix/Utils/IconWork/IconPaint + ITEM "Iconian" WB PRG:Pix/Iconian/Iconian + SUBMENU GrabbIt + ITEM "GrabbIt" RUN Execute S:Macro/GrabbIt + ITEM "AnyTime" WB PRG:Pix/Utils/Grabbit/AnyTime + ENDSUBMENU + #ITEM "Imagine" RUN PRI -1 Assign Imp: Vrack:Pix/Imp/;BD Imp:;Assign Im: PRG:Pix/Imagine/;Cd Im:;Imagine + ITEM "Imagine" RUN PRI -1 CD Vrack:;CD Pix;CD Imp; Assign Imp: "";BD Imp:;Assign Im: PRG:Pix/Imagine/;Cd Im:;Imagine + ITEM "ADPro 5.5" RUN CD Prg:Pix/ADPro/;SetUp;WBRun ADPro5.5Mo SYNC;UnSetup + ITEM "ADPro 8.5" RUN CD Prg:Pix/ADPro/;SetUp;WBRun ADPro8.5Mo SYNC;UnSetup + ITEM "ADPro +oo" RUN CD Prg:Pix/ADPro/;SetUp;WBRun ADPro SYNC;UnSetup +#this guru with GigaMem +# ITEM "ADPro" RUN STACK 20000 Assign FREDScripts: Rexx:FRED/;Assign ADProScripts: Rexx:ADPro/;CD Prg:Pix/ADPro;Assign ADPro: "";ADPro MAXMEM=6000000 FASTMEMONLY SHALLOW;Assign ADPro:;Assign FREDScripts:;Assign ADProScripts: + ITEM "Render24" WB PRG:Pix/Rend24 + ITEM "ImageFX" RUN CD Prg:Pix/ImageFX;Assign ImageFX: "";ImageFx + ITEM "VistaPro" WB PRI -1 PRG:Pix/VistaPro/VistaPro + ITEM "Real" RUN STACK 40000 PRI -1 cd PRG:Pix/r3d2;setup;real + ITEM "Make Cat" RUN rx PRG:Pix/CatMake.rexx + ITEM "MainActor" RUN CD PRG:Pix/MainActor;Assign MainActor: ""; WBRun MainActor SYNC;Assign MainActor: + ITEM "Photogenics" RUN Assign Photogenics: PRG:Pix/Photogenics; WBRun Photogenics:Photogenics SYNC;Assign Photogenics: + ITEM "PPaint" WB PRG:Pix/PPaint/PPaint + +MENU "Txt" + ITEM "FinalCopy" WB PRG:Txt/FinalCopy/FinalCopy + +MENU "Snd" + ITEM "Med" WB PRG:Music/OMed/OctaMED.V5 + ITEM "AS" RUN PRG:Music/SoundTracker/AS + ITEM "DeliTracker" WB SYS:Utilities/DeliTracker + ITEM "PlayCD" WB WB:Tools/PlayCD/PlayCD + +MENU "Pro" + ITEM "PPM" WB PRG:PAO/PPM/PPMasterF + ITEM "AMaxII" SHELL RDBMount AMAX0: ExecDev scsi.device UnitNr 0 FS=L:CrossMACFileSystem;Cd PRG:Emulator/A-MaxII/;Assign Devs: Devs/ ADD;"A-Max Startup" + ITEM "AMaxIV" SHELL Echo "Remove ALL floppy disk now";Say "Remove ALL floppy disk now";Assign >NIL: AMAX0: EXISTS;IF WARN;RDBMount AMAX0: ExecDev scsi.device UnitNr 0 FS=L:CrossMACFileSystem;ENDIF;Cd PRG:Emulator/A-MaxIV/;Assign Devs: Devs/ ADD;;WBRun A-MaxStartup SYNC;DiskChange AMAX0: +# ITEM "AMaxIV" SHELL Cd PRG:Emulator/A-MaxIV/;Assign Devs: Devs/ ADD;;WBRun A-MaxStartup SYNC + ITEM "ShapeShifter" WB PRI -1 PRG:Emulator/ShapeShifter/ShapeShifter + ITEM "PC-Task" WB PRG:Emulator/PC-Task/PC-Task68020_60 + +MENU Prefs + ITEM Font WB Sys:Prefs/Font + ITEM IControl WB Sys:Prefs/IControl + ITEM Input WB Sys:Prefs/Input + ITEM Locale WB Sys:Prefs/Locale + ITEM Overscan WB Sys:Prefs/Overscan + ITEM Palette WB Sys:Prefs/Palette + ITEM Pointer WB Sys:Prefs/Pointer + ITEM Printer WB Sys:Prefs/Printer + ITEM PrinterGfx WB Sys:Prefs/PrinterGfx + ITEM PrinterPS WB Sys:Prefs/PrinterPS + ITEM ScreenMode WB Sys:Prefs/ScreenMode + ITEM Serial WB Sys:Prefs/Serial + ITEM Sound WB Sys:Prefs/Sound + ITEM Time WB Sys:Prefs/Time + ITEM WBPattern WB Sys:Prefs/WBPattern + BARLABEL + ITEM ToolManager WB Sys:Prefs/ToolManager + ITEM MUI WB PRG:MUI/MUI + ITEM Promotion WB SYS:Prefs/Promotion + ITEM "NewMode" WB WBe:CStartup/NewMode + ITEM MonEd WB SYS:Prefs/MonEd + BARLABEL + ITEM Update RUN Copy ENVARC:Sys/ Env:Sys/ ALL QUIET +# ITEM VGAWide RUN Sys:Prefs/ScreenMode Sys:Prefs/Presets/VGAWide.ScreenMode USE;Sys:Prefs/Fonts Sys:Prefs/Presets/VGAWide.Fonts USE + ITEM VGAWide RUN WBRun Sys:Prefs/Presets/VGAWide.Fonts;WBRun Sys:Prefs/Presets/VGAWide.ScreenMode + ITEM "ALL" RUN BD SYS:Prefs/ + +MENU "Cfg" + ITEM "ReParM" RUN Wait 5;Run >Nil: SYS:Utilities/ParM LEFTEDGE 328 DETAILPEN 1 BLOCKPEN 0 MENUCOLOR 2 DRAGBAR OFF USENULL ON SHOWMEM ON SHOWTIME ON MTBLOCKPEN 1 MTDETAILPEN 0 + ITEM "ParM.DF0:S/" CFG DF0:S/ParM.cfg + ITEM "ParM.DF2:S/" CFG DF2:S/ParM.cfg + ITEM "HDToolBox" WB WB:Tools/HDToolBox + ITEM "Reg2.13" REQUEST SHELL WIN "CON:0/11/640/100/Reg 2.13/AUTO/CLOSE/WAIT" Set RegName "";CD DF0:BrowserII/;SRC:Reg "$RegName";list BrowserII.Key;Date >>SRC:Register.key;Echo >>SRC:Register.key "Register TO '$RegName', Version:2.13";Echo >>SRC:Register.key "-----";Type DF0:BrowserII/BrowserII.key HEX + ITEM "Reg3.03" REQUEST SHELL WIN "CON:0/11/640/100/Reg 3.03/AUTO/CLOSE/WAIT" Set RegName "";CD DF0:;SRC:Register/Reg "$RegName";list BrowserII.Key;Date >>SRC:Register/Register.key;Echo >>SRC:Register/Register.key "Register TO '$RegName', Version:3.03";Echo >>SRC:Register/Register.key "-----";Type DF0:BrowserII.key HEX + #ITEM "Reg3.03 Email" REQUEST SHELL WIN "CON:0/11/640/100/Reg 3.03/AUTO/CLOSE/WAIT" Set RegName "";CD SRC:Register/;MakeDir "$RegName";CD "$RegName";/Reg "$RegName";Type BrowserII.key HEX;Copy /Msg Msg;Echo >>Msg "L:BrowserII.key HEX dump:";Type >>Msg BrowserII.key HEX;Echo >>Msg "---- End of L:BrowserII.key HEX Dump ----";/s_encode -e BrowserII.key BrowserII.key.uu;Type >>Msg BrowserII.key.uu;CD /;Date >>Register.key;Echo >>Register.key "EMail Register TO '$RegName', Version:3.03";Echo >>Register.key "-----"; + ITEM "Reg Email" REQUEST SHELL WIN "CON:0/11/640/100/Reg EMail/AUTO/CLOSE/WAIT" Set RegName "";CD SRC:Register/;MakeDir "$RegName";CD "$RegName";/Reg "$RegName";Type BrowserII.key HEX;Copy /Msg Msg;Echo >>Msg "L:BrowserII.key HEX dump:";Type >>Msg BrowserII.key HEX;Echo >>Msg "---- End of L:BrowserII.key HEX Dump ----";CD /;Date >>Register.key;Echo >>Register.key "EMail Register TO '$RegName', Version:NONE";Echo >>Register.key "-----"; + ITEM "EliteII" SHELL run SYS:Tools/Commodities/Exchange;bd pack:games/eliteii diff --git a/scalos/Prefs/Menu/ScalosMenu.cd b/scalos/Prefs/Menu/ScalosMenu.cd new file mode 100755 index 000000000..c29e33778 --- /dev/null +++ b/scalos/Prefs/Menu/ScalosMenu.cd @@ -0,0 +1,1684 @@ +; ScalosMenu.cd +; version $VER: ScalosMenu.catalog 40.18 (24 Aug 2008 21:47:53) +; codeset 0s +; language english +; +;#arrayopts static __far +; +; +MSGID_TITLENAME (//) +Scalos Menu Prefs Plugin +; +; +MSGID_TITLENAME_CMDLIST (//) +Scalos Internal Menu Commands +; +; +MSGID_FRAMETITLE (//) +Menulist +; +; +MSGID_NEWINAME (//) +New Item +; +; +MSGID_HOTKEYNAME (//) +Key: +; +; +MSGID_NEWNAME (//) +New Menu +; +; +MSGID_DELNAME (//) +Delete +; +; +MSGID_SAVENAME (//) +Save +; +; +MSGID_USENAME (//) +Use +; +; +MSGID_CANCELNAME (//) +Cancel +; +; +MSGID_NEW2NAME (//) +New Command +; +; +MSGID_COMMANDNAME (//) +Command +; +; +MSGID_WBNAME (4300//) +Workbench +; +; +MSGID_ADOSNAME (//) +AmigaDOS +; +; +MSGID_STACKNAME (//) +Stack: +; +; +MSGID_MAINMENUNAME (//) +MainMenu +; +; +MSGID_BARNAME (//) +\033C +; +; +MSGID_UPNAME (//) +Up +; +; +MSGID_DOWNNAME (//) +Down +; +; +MSGID_ICONWINNAME (//) +IconWindow +; +; +MSGID_AREXXNAME (//) +Arexx +; +; +MSGID_ARGSNAME (//) +WB Args: +; +;--------------------------------------------- +; +MSGID_MENU_PROJECT_IMPORT (4000//) +Import +; +; +MSGID_MENU_PROJECT_IMPORT_SHORT (/1/1) +I +; +; +MSGID_MENU_PROJECT_OPEN (//) +Open... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT (/1/1) +O +; +; +MSGID_MENU_PROJECT_SAVEAS (//) +Save As... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT (/1/1) +A +; +; +MSGID_MENU_PROJECT_ABOUT (//) +About... +; +; +MSGID_MENU_PROJECT_QUIT (//) +Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT (/1/1) +Q +; +; +MSGID_MENU_PROJECT (//) +Project +; +; +MSGID_MENU_EDIT_LASTSAVED (//) +Last Saved +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT (/1/1) +L +; +; +MSGID_MENU_EDIT (//) +Edit +; +; +MSGID_MENU_SETTINGS_CREATEICONS (//) +Create Icons? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT (/1/1) +I +; +; +MSGID_MENU_SETTINGS (//) +Settings +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS (//) +Reset To Defaults +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT (/1/1) +D +; +; +MSGID_MENU_EDIT_RESTORE (//) +Restore +; +; +MSGID_MENU_EDIT_RESTORE_SHORT (/1/1) +R +; +; +MSGID_MENU_PROJECT_ABOUTMUI (//) +About MUI... +; +; +MSGID_MENU_PROJECT_IMPORT_TD (//) +ToolsDaemon... +; +; +MSGID_MENU_PROJECT_IMPORT_TD_SHORT (/1/1) +T +; +; +MSGID_MENU_PROJECT_IMPORT_P (//) +Parm... +; +; +MSGID_MENU_PROJECT_IMPORT_P_SHORT (/1/1) +P +; +; +MSGID_MENU_PROJECT_MERGE (//) +Merge... +; +; +MSGID_MENU_PROJECT_MERGE_SHORT (/1/1) +M +; +; +MSGID_MENU_EDIT_COLLAPSEALL (//) +Collapse All +; +; +MSGID_MENU_EDIT_EXPANDALL (//) +Expand All +; +; +MSGID_MENU_SETTINGS_HIDEOBSOLETE (//) +Hide Obsolete? +; +; +MSGID_MENU_SETTINGS_HIDEOBSOLETE_SHORT (//) +If checked, obsolete popup menus which are now\n\ +defined via filetypes prefs are not shown. +; +; +MSGID_MENU_EDIT_COPY (//) +Copy +; +; +MSGID_MENU_EDIT_CUT (//) +Cut +; +; +MSGID_MENU_EDIT_PASTE (//) +Paste +; +; +MSGID_MENU_EDIT_COLLAPSE (//) +Collapse Selected +; +; +MSGID_MENU_EDIT_EXPAND (//) +Expand Selected +; +;--------------------------------------------- +; +MSGID_POPMENUNAME1 (4500//) +Popup Menu: Disk icons +; +; +MSGID_POPMENUNAME2 (//) +Popup Menu: Drawer icons +; +; +MSGID_POPMENUNAME3 (//) +Popup Menu: Tool/Project icons +; +; +MSGID_POPMENUNAME4 (//) +Popup Menu: Trashcan icons +; +; +MSGID_POPMENUNAME5 (//) +Popup_Menu: Windows +; +; +MSGID_POPMENUNAME6 (//) +Popup Menu: AppIcons +; +; +MSGID_POPMENUNAME7 (//) +Popup Menu: Desktop +; +; +;--------------------------------------------- +; +MSGID_COM1NAME (5000//) +Backdrop +; +; +MSGID_COM2NAME (//) +Execute Command +; +; +MSGID_COM3NAME (//) +Redraw All +; +; +MSGID_COM4NAME (//) +Update All +; +; +MSGID_COM5NAME (//) +About Scalos +; +; +MSGID_COM6NAME (//) +Quit +; +; +MSGID_COM7NAME (//) +New Drawer +; +; +MSGID_COM8NAME (//) +Open Parent +; +; +MSGID_COM9NAME (//) +Close Window +; +; +MSGID_COM10NAME (//) +Update +; +; +MSGID_COM11NAME (//) +Select Contents +; +; +MSGID_COM12NAME (//) +Cleanup +; +; +MSGID_COM13NAME (//) +Snapshot - Window +; +; +MSGID_COM14NAME (//) +Snapshot - All +; +; +MSGID_COM15NAME (//) +Show - Only Icons +; +; +MSGID_COM16NAME (//) +Show - All Files +; +; +MSGID_COM17NAME (//) +View By - Icon +; +; +MSGID_COM18NAME (//) +View By - Name +; +; +MSGID_COM19NAME (//) +Open +; +; +MSGID_COM20NAME (//) +Reset Scalos +; +; +MSGID_COM21NAME (//) +Rename +; +; +MSGID_COM22NAME (//) +Information +; +; +MSGID_COM23NAME (//) +Snapshot +; +; +MSGID_COM24NAME (//) +UnSnapshot +; +; +MSGID_COM25NAME (//) +Leave Out +; +; +MSGID_COM26NAME (//) +Put Away +; +; +MSGID_COM27NAME (//) +Delete +; +; +MSGID_COM28NAME (//) +Clone +; +; +MSGID_COM29NAME (//) +Empty Trashcan +; +; +MSGID_COM30NAME (//) +Last Message +; +; +MSGID_COM31NAME (//) +Redraw +; +; +MSGID_COM32NAME (//) +Iconify +; +; +MSGID_PLUGINNAME (//) +PlugIn +; +; +MSGID_COM33NAME (//) +Format Disk... +; +; +MSGID_COM34NAME (//) +Shutdown... +; +; +MSGID_COM35NAME (//) +Size To Fit +; +; +MSGID_COM36NAME (//) +Clear Selection +; +; +MSGID_COM37NAME (//) +View By - Size +; +; +MSGID_COM38NAME (//) +View By - Date +; +; +MSGID_COM39NAME (//) +Copy file +; +; +MSGID_COM40NAME (//) +Cut file +; +; +MSGID_COM41NAME (//) +Paste file +; +; +MSGID_COM42NAME (//) +View By - Type +; +; +MSGID_COM43NAME (//) +Cleanup By - Name +; +; +MSGID_COM44NAME (//) +Cleanup By - Date +; +; +MSGID_COM45NAME (//) +Cleanup By - Size +; +; +MSGID_COM46NAME (//) +Cleanup By - Type +; +; +MSGID_COM_ICONPROPERTIES (//) +Icon properties +; +; +MSGID_COM_WINDOWPROPERTIES (//) +Window properties +; +; +MSGID_COM47NAME (//) +View By - Default +; +; +MSGID_COM48NAME (//) +Show - Default +; +; +MSGID_COM49NAME (//) +Copy to... +; +; +MSGID_COM50NAME (//) +Move to... +; +; +MSGID_COM51NAME (//) +Create thumbnail +; +; +MSGID_COM_OPENNEWWINDOW (//) +Open in new window +; +; +MSGID_COM_THUMBNAILCACHECLEANUP (//) +Cleanup thumbnail cache +; +; +MSGID_COM_FIND (//) +Find File(s) +; +; +MSGID_COM_UNDO (//) +Undo +; +; +MSGID_COM_REDO (//) +Redo +; +; +MSGID_COM_OPENBROWSERWINDOW (//) +Open in Browser Window +; +;--------------------------------------------- +; +MSGID_ABOUTREQOK (6000//) +_OK +; +; +MSGID_ABOUTREQFORMAT (//) +\33c\033bScalos Menu Preferences V%ld.%ld\033n\n\ +%s\n\ +© 1999%s The Scalos Team +; +; +MSGID_SHORTHELP_NEWMENUBUTTON (//) +Press this button to create a new Menu or\n\ +Submenu entry at the currently selected position. +; +; +MSGID_SHORTHELP_NEWITEMBUTTON (//) +Press this button to insert a new menu\n\ +item at the currently selected position. +; +; +MSGID_SHORTHELP_NEWCOMMANDBUTTON (//) +Press this button to add a new\n\ +command to the currently menu item. +; +; +MSGID_SHORTHELP_DELBUTTON (//) +Press this button to delete the currently\n\ +select command, menu item, or menu. +; +; +MSGID_SHORTHELP_SAVEBUTTON (//) +Press this button to save \n\ +the current settings to\n\ +\"ENVARC:Scalos/menu13.prefs\"\n\ +and make changes permanent. +; +; +MSGID_SHORTHELP_USEBUTTON (//) +Press this button to save \n\ +the current settings to\n\ +\"ENV:Scalos/menu13.prefs\"\n\ +and keep settings until reboot. +; +; +MSGID_SHORTHELP_CANCELBUTTON (//) +Press this button to abort \n\ +and forget all changes. +; +; +MSGID_REQTITLE_SAVEERROR (//) +Error writing menu preferences\n\ +file \"%s\"\n\ +%s +; +; +MSGID_REQTITLE_READERROR (//) +Error reading menu preferences\n\ +file \"%s\"\n\ +%s +; +; +MSGID_IMPORTNAME (//) +Import +; +; +MSGID_TITLE_IMPORTTD (//) +Import ToolsDaemon Prefs +; +; +MSGID_TITLE_IMPORTP (//) +Import ParM Prefs +; +; +MSGID_PRIORITY_SLIDER_NAME (//) +Priority: +; +; +MSGID_PRIORITY_SLIDER_BUBBLE (//) +Use this slider to adjust the priority the command should run with. +; +; new in 40.7 +; +MSGID_PLUGIN_LIST_TITLE (//) +Menu +; +; +MSGID_POPUP_ASLTITLE_AMIGADOS (//) +Select AmigaDOS command +; +; +MSGID_POPUP_ASLTITLE_WORKBENCH (//) +Select Workbench command +; +; +MSGID_POPUP_ASLTITLE_ICONWINDOW (//) +Select directory for icon window +; +; +MSGID_POPUP_ASLTITLE_AREXX (//) +Select ARexx program +; +; +MSGID_POPUP_ASLTITLE_MENUPLUGIN (//) +Select Scalos Menu plugin +; +; +MSGID_MENU_PROJECT_MERGE_ASLTITLE (//) +Select prefs to merge with +; +; +MSGID_MENU_GROUP_COMMAND_PROPERTIES (//) +Command Properties +; +; new in 40.10 +; +MSGID_SHORTHELP_LAMP_CHANGED (//) +This lamp indicator changes from \033bOff\033n\n\ +to \033bOk\033n when the settings have been\n\ +modified since initial loading. +; +; new in 40.16 +; +MSGID_POPASL_UNSELECTEDIMAGE_SHORTHELP (//) +Here you may select an iconic image that is shown left of\n\ +the menu item name, in unselected menu item state. +; +; +MSGID_SAMPLE_UNSELECTEDIMAGE_SHORTHELP (//) +This is a sample of the iconic image that will be shown\n\ +left of the menu item name, in unselected menu item state. +; +; +MSGID_POPASL_SELECTEDIMAGE_SHORTHELP (//) +Here you may select an iconic image that is shown left of\n\ +the menu item name, in selected menu item state. +; +; +MSGID_SAMPLE_SELECTEDIMAGE_SHORTHELP (//) +This is a sample of the iconic image that will be shown\n\ +left of the menu item name, in selected menu item state. +; +; +MSGID_ENTRY_STRING_NAME (//) +Name: +; +; +MSGID_ENTRY_GROUP_UNSELECTEDIMAGE (//) +Unselected State Image +; +; +MSGID_ENTRY_GROUP_SELECTEDIMAGE (//) +Selected State Image +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE (6500//) +Scalos Menu Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD (//) +Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_NEW_MENU (7000//) +New Menu +; +; +MSGID_NEW_ITEM (//) +New Item +; +; +MSGID_TOOLS_MENU (//) +Tools +; +;----------------------------------------------------------- +; +MSGID_DEFAULT_MENU_OPEN (7100//) +Open +; +; +MSGID_DEFAULT_MENU_OPEN_SHORT (/0/1) +O +; +; +MSGID_DEFAULT_MENU_INFORMATION (//) +Information... +; +; +MSGID_DEFAULT_MENU_INFORMATION_SHORT (/0/1) +I +; +; +MSGID_DEFAULT_MENU_BROWSE (//) +Browse... +; +; +MSGID_DEFAULT_MENU_BROWSE_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_FIND (//) +Find... +; +; +MSGID_DEFAULT_MENU_FIND_SHORT (/0/1) +F +; +; +MSGID_DEFAULT_MENU_SNAPSHOT (//) +Snapshot +; +; +MSGID_DEFAULT_MENU_SNAPSHOT_SHORT (/0/1) +S +; +; +MSGID_DEFAULT_MENU_UNSNAPSHOT (//) +Unsnapshot +; +; +MSGID_DEFAULT_MENU_UNSNAPSHOT_SHORT (/0/1) +U +; +; +MSGID_DEFAULT_MENU_CLONE (//) +Clone +; +; +MSGID_DEFAULT_MENU_CLONE_SHORT (/0/1) +C +; +; +MSGID_DEFAULT_MENU_COPY (//) +Copy +; +; +MSGID_DEFAULT_MENU_COPY_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_CUT (//) +Cut +; +; +MSGID_DEFAULT_MENU_CUT_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_PASTE (//) +Paste +; +; +MSGID_DEFAULT_MENU_PASTE_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_DISKCOPY (//) +Diskcopy... +; +; +MSGID_DEFAULT_MENU_DISKCOPY_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_RELABEL (//) +Relabel... +; +; +MSGID_DEFAULT_MENU_RELABEL_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_FORMAT (//) +Format... +; +; +MSGID_DEFAULT_MENU_FORMAT_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_PROPERTIES (//) +Properties... +; +; +MSGID_DEFAULT_MENU_PROPERTIES_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_EDIT (//) +Edit +; +; +MSGID_DEFAULT_MENU_RENAME (//) +Rename +; +; +MSGID_DEFAULT_MENU_RENAME_SHORT (/0/1) +R +; +; +MSGID_DEFAULT_MENU_LEAVEOUT (//) +Leave Out +; +; +MSGID_DEFAULT_MENU_LEAVEOUT_SHORT (/0/1) +L +; +; +MSGID_DEFAULT_MENU_PUTAWAY (//) +Put Away +; +; +MSGID_DEFAULT_MENU_PUTAWAY_SHORT (/0/1) +P +; +; +MSGID_DEFAULT_MENU_DELETE (//) +Delete... +; +; +MSGID_DEFAULT_MENU_DELETE_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_EMPTYTRASH (//) +Empty Trashcan... +; +; +MSGID_DEFAULT_MENU_EMPTYTRASH_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_CLOSE (//) +Close +; +; +MSGID_DEFAULT_MENU_CLOSE_SHORT (/0/1) +K +; +; +MSGID_DEFAULT_MENU_OPENPARENT (//) +Open Parent +; +; +MSGID_DEFAULT_MENU_OPENPARENT_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_UPDATE (//) +Update +; +; +MSGID_DEFAULT_MENU_UPDATE_SHORT (/0/1) +M +; +; +MSGID_DEFAULT_MENU_CLEANUP (//) +Cleanup +; +; +MSGID_DEFAULT_MENU_CLEANUP_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_RESIZETOFIT (//) +Resize To Fit +; +; +MSGID_DEFAULT_MENU_RESIZETOFIT_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_SELECTCONTENTS (//) +Select Contents +; +; +MSGID_DEFAULT_MENU_SELECTCONTENTS_SHORT (/0/1) +A +; +; +MSGID_DEFAULT_MENU_CLEARSELECTION (//) +Clear Selection +; +; +MSGID_DEFAULT_MENU_CLEARSELECTION_SHORT (/0/1) +Z +; +; +MSGID_DEFAULT_MENU_SNAPSHOT_ALL (//) +All +; +; +MSGID_DEFAULT_MENU_SNAPSHOT_ALL_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_SNAPSHOT_WINDOW (//) +Window +; +; +MSGID_DEFAULT_MENU_SNAPSHOT_WINDOW_SHORT (/0/1) +W +; +; +MSGID_DEFAULT_MENU_NEWDRAWER (//) +New Drawer... +; +; +MSGID_DEFAULT_MENU_NEWDRAWER_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_SCALOS (//) +Scalos +; +; +MSGID_DEFAULT_MENU_WINDOW (//) +Window +; +; +MSGID_DEFAULT_MENU_ICONS (//) +Icons +; +; +MSGID_DEFAULT_MENU_DRAWERS (//) +Drawers +; +; +MSGID_DEFAULT_MENU_PREFS (//) +Prefs +; +; +MSGID_DEFAULT_MENU_BACKDROP (//) +Backdrop? +; +; +MSGID_DEFAULT_MENU_BACKDROP_SHORT (/0/1) +B +; +; +MSGID_DEFAULT_MENU_EXECUTECOMMAND (//) +Execute Command... +; +; +MSGID_DEFAULT_MENU_EXECUTECOMMAND_SHORT (/0/1) +E +; +; +MSGID_DEFAULT_MENU_REDRAWALL (//) +Redraw All +; +; +MSGID_DEFAULT_MENU_REDRAWALL_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_UPDATEALL (//) +Update All +; +; +MSGID_DEFAULT_MENU_UPDATEALL_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_LASTMESSAGE (//) +Last Message +; +; +MSGID_DEFAULT_MENU_LASTMESSAGE_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_ABOUT (//) +About... +; +; +MSGID_DEFAULT_MENU_ABOUT_SHORT (/0/1) +? +; +; +MSGID_DEFAULT_MENU_QUIT (//) +Quit... +; +; +MSGID_DEFAULT_MENU_QUIT_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_CLEANUPBY (//) +Clean up by +; +; +MSGID_DEFAULT_MENU_CLEANUPBY_COLUMN (//) +Column +; +; +MSGID_DEFAULT_MENU_CLEANUPBY_COLUMN_SHORT (/0/1) +. +; +; +MSGID_DEFAULT_MENU_CLEANUPBY_NAME (//) +Name +; +; +MSGID_DEFAULT_MENU_CLEANUPBY_NAME_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_CLEANUPBY_DATE (//) +Date +; +; +MSGID_DEFAULT_MENU_CLEANUPBY_DATE_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_CLEANUPBY_SIZE (//) +Size +; +; +MSGID_DEFAULT_MENU_CLEANUPBY_SIZE_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_CLEANUPBY_TYPE (//) +Type +; +; +MSGID_DEFAULT_MENU_CLEANUPBY_TYPE_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_SHOW (//) +Show +; +; +MSGID_DEFAULT_MENU_SHOW_DEFAULT (//) +Default +; +; +MSGID_DEFAULT_MENU_SHOW_DEFAULT_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_SHOW_ONLYICONS (//) +Only Icons +; +; +MSGID_DEFAULT_MENU_SHOW_ONLYICONS_SHOT (/0/1) +- +; +; +MSGID_DEFAULT_MENU_SHOW_ALLFILES (//) +All Files +; +; +MSGID_DEFAULT_MENU_SHOW_ALLFILES_SHORT (/0/1) ++ +; +; +MSGID_DEFAULT_MENU_VIEWBY (//) +View By +; +; +MSGID_DEFAULT_MENU_VIEWBY_DEFAULT (//) +Default +; +; +MSGID_DEFAULT_MENU_VIEWBY_DEFAULT_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_VIEWBY_ICON (//) +Icon +; +; +MSGID_DEFAULT_MENU_VIEWBY_ICON_SHORT (/0/1) +1 +; +; +MSGID_DEFAULT_MENU_VIEWBY_NAME (//) +Name +; +; +MSGID_DEFAULT_MENU_VIEWBY_NAME_SHORT (/0/1) +2 +; +; +MSGID_DEFAULT_MENU_VIEWBY_DATE (//) +Date +; +; +MSGID_DEFAULT_MENU_VIEWBY_DATE_SHORT (/0/1) +3 +; +; +MSGID_DEFAULT_MENU_VIEWBY_SIZE (//) +Size +; +; +MSGID_DEFAULT_MENU_VIEWBY_SIZE_SHORT (/0/1) +4 +; +; +MSGID_DEFAULT_MENU_VIEWBY_TYPE (//) +Type +; +; +MSGID_DEFAULT_MENU_VIEWBY_TYPE_SHORT (/0/1) +5 +; +; +MSGID_DEFAULT_MENU_RESETSCALOS (//) +Reset Scalos +; +; +MSGID_DEFAULT_MENU_RESETSCALOS_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_NEWSHELL (//) +New Shell +; +; +MSGID_DEFAULT_MENU_NEWSHELL_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_DRAWERS_VOYAGER (//) +Voyager +; +; +MSGID_DEFAULT_MENU_DRAWERS_VOYAGER_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_DRAWERS_ENVARC_SYS (//) +ENVARC:Sys +; +; +MSGID_DEFAULT_MENU_DRAWERS_ENVARC_SYS_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_DRAWERS_WBSTARTUP (//) +WBStartup +; +; +MSGID_DEFAULT_MENU_DRAWERS_WBSTARTUP_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_DRAWERS_PREFS (//) +Prefs +; +; +MSGID_DEFAULT_MENU_DRAWERS_PREFS_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_DRAWERS_SCALOSPREFS (//) +Scalos Prefs +; +; +MSGID_DEFAULT_MENU_DRAWERS_SCALOSPREFS_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_PREFS_SYSTEM (//) +System... +; +; +MSGID_DEFAULT_MENU_PREFS_SYSTEM_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_PREFS_MUI (//) +MUI... +; +; +MSGID_DEFAULT_MENU_PREFS_MUI_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_PREFS_AHI (//) +AHI... +; +; +MSGID_DEFAULT_MENU_PREFS_AHI_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_PREFS_SCALOS (//) +Scalos Prefs... +; +; +MSGID_DEFAULT_MENU_PREFS_SCALOS_SHORT (/0/1) + +; +; +MSGID_DEFAULT_MENU_EMPTY_SHORT (/0/0) + +; +; +MSGID_DEFAULT_TOOLS (//) +Tools +; +; +MSGID_DEFAULT_UTILITIES (//) +Utilities +; +; +MSGID_DEFAULT_PREFERENCES (//) +Preferences +; +; +MSGID_DEFAULT_EXCHANGE (//) +Exchange +; +; +MSGID_DEFAULT_MENU_TOOLS_MOUNTER (//) +Mounter +; +; +MSGID_DEFAULT_MENU_TOOLS_SCSICONFIG (//) +SCSIConfig +; +; +MSGID_DEFAULT_MENU_TOOLS_SNOOPIUM (//) +Snoopium +; +; +MSGID_DEFAULT_MENU_TOOLS_DEFRAG (//) +Defrag +; +; +MSGID_DEFAULT_MENU_TOOLS_FTMANAGER (//) +FTManager +; +; +MSGID_DEFAULT_MENU_TOOLS_MUISHELL (//) +MUIShell +; +; +MSGID_DEFAULT_MENU_TOOLS_SFSDOCTOR (//) +SFSDoctor +; +; +MSGID_DEFAULT_MENU_TOOLS_UNITCONTROL (//) +UnitControl +; +; +MSGID_DEFAULT_MENU_TOOLS_FILEIMAGECTRL (//) +FileImageCtrl +; +; +MSGID_DEFAULT_MENU_TOOLS_HDCONFIG (//) +HDConfig +; +; +MSGID_DEFAULT_MENU_TOOLS_REGTOOL (//) +RegTool +; +; +MSGID_DEFAULT_MENU_TOOLS_SHELL (//) +Shell +; +; +MSGID_DEFAULT_MENU_UTILITIES_EDITOR (//) +Editor +; +; +MSGID_DEFAULT_MENU_UTILITIES_FRAGMENT (//) +Fragment +; +; +MSGID_DEFAULT_MENU_UTILITIES_GRABBER (//) +Grabber +; +; +MSGID_DEFAULT_MENU_UTILITIES_GRAPHICBOARDS (//) +GraphicBoards +; +; +MSGID_DEFAULT_MENU_UTILITIES_KEYSTROKE (//) +Keystroke +; +; +MSGID_DEFAULT_MENU_UTILITIES_MINICALC (//) +MiniCalc +; +; +MSGID_DEFAULT_MENU_UTILITIES_MORE (//) +More +; +; +MSGID_DEFAULT_MENU_UTILITIES_MUIPROCALC (//) +MUIProCalc +; +; +MSGID_DEFAULT_MENU_UTILITIES_MULTIVIEW (//) +Multiview +; +; +MSGID_DEFAULT_MENU_UTILITIES_MYSTICVIEW (//) +MysticView +; +; +MSGID_DEFAULT_MENU_UTILITIES_TASKMANAGER (//) +TaskManager +; +; +MSGID_DEFAULT_MENU_UTILITIES_TRANCESTATS (//) +Trancestats +; +; +MSGID_DEFAULT_MENU_UTILITIES_TIPS (//) +Tips +; +; +MSGID_DEFAULT_MENU_UTILITIES_ZOOM (//) +Zoom +; +; +MSGID_DEFAULT_MENU_UTILITIES_AMIGS (//) +AmiGS +; +; +MSGID_DEFAULT_MENU_UTILITIES_AMIPDF (//) +AmiPDF +; +; +MSGID_DEFAULT_MENU_UTILITIES_SGRAB (//) +SGrab +; +; +MSGID_DEFAULT_MENU_UTILITIES_CALCULATOR (//) +Calculator +; +; +MSGID_DEFAULT_MENU_UTILITIES_CLOCK (//) +Clock +; +; +MSGID_DEFAULT_MENU_UTILITIES_GRAPHICDUMP (//) +GraphicDump +; +; +MSGID_DEFAULT_MENU_UTILITIES_ICONEDIT (//) +IconEdit +; +; +MSGID_DEFAULT_MENU_UTILITIES_INITPRINTER (//) +InitPrinter +; +; +MSGID_DEFAULT_MENU_UTILITIES_KEYSHOW (//) +KeyShow +; +; +MSGID_DEFAULT_MENU_UTILITIES_MEMACS (//) +MEmacs +; +; +MSGID_DEFAULT_MENU_UTILITIES_NOTEPAD (//) +Notepad +; +; +MSGID_DEFAULT_MENU_UTILITIES_PARTITIONWIZARD (//) +Partition Wizard +; +; +MSGID_DEFAULT_MENU_UTILITIES_PLAYCD (//) +PlayCD +; +; +MSGID_DEFAULT_MENU_UTILITIES_PREFSOBJECTSEDITOR (//) +PrefsObjectsEditor +; +; +MSGID_DEFAULT_MENU_UTILITIES_PRINTFILES (//) +PrintFiles +; +; +MSGID_DEFAULT_MENU_UTILITIES_RAWDISK (//) +RawDisk +; +; +MSGID_DEFAULT_MENU_UTILITIES_SHOWCONFIG (//) +ShowConfig +; +; +MSGID_DEFAULT_MENU_UTILITIES_UNARC (//) +UnArc +; +; +MSGID_DEFAULT_MENU_UTILITIES_USBINSPECTOR (//) +USBInspector +; +; +MSGID_DEFAULT_MENU_PREFS_AMIGAINPUT (//) +AmigaInput +; +; +MSGID_DEFAULT_MENU_PREFS_ASL (//) +ASL +; +; +MSGID_DEFAULT_MENU_PREFS_COMPATIBILITY (//) +Compatibility +; +; +MSGID_DEFAULT_MENU_PREFS_DEFICONS (//) +DefIcons +; +; +MSGID_DEFAULT_MENU_PREFS_DOS (//) +DOS +; +; +MSGID_DEFAULT_MENU_PREFS_FONT (//) +Font +; +; +MSGID_DEFAULT_MENU_PREFS_GUI (//) +GUI +; +; +MSGID_DEFAULT_MENU_PREFS_INPUT (//) +Input +; +; +MSGID_DEFAULT_MENU_PREFS_INTERNET (//) +Internet +; +; +MSGID_DEFAULT_MENU_PREFS_LOCALE (//) +Locale +; +; +MSGID_DEFAULT_MENU_PREFS_NOTIFICATIONS (//) +Notifications +; +; +MSGID_DEFAULT_MENU_PREFS_PALETTE (//) +Palette +; +; +MSGID_DEFAULT_MENU_PREFS_PICASSO96MODE (//) +Picasso96Mode +; +; +MSGID_DEFAULT_MENU_PREFS_POINTER (//) +Pointer +; +; +MSGID_DEFAULT_MENU_PREFS_POPUPMENU (//) +PopupMenu +; +; +MSGID_DEFAULT_MENU_PREFS_PRINTER (//) +Printer +; +; +MSGID_DEFAULT_MENU_PREFS_PRINTERGFX (//) +PrinterGFX +; +; +MSGID_DEFAULT_MENU_PREFS_PRINTERPS (//) +PrinterPS +; +; +MSGID_DEFAULT_MENU_PREFS_SCREENBLANKER (//) +ScreenBlanker +; +; +MSGID_DEFAULT_MENU_PREFS_SCREENMODE (//) +ScreenMode +; +; +MSGID_DEFAULT_MENU_PREFS_SCREENS (//) +Screens +; +; +MSGID_DEFAULT_MENU_PREFS_SERIAL (//) +Serial +; +; +MSGID_DEFAULT_MENU_PREFS_SOUND (//) +Sound +; +; +MSGID_DEFAULT_MENU_PREFS_TIME (//) +Time +; +; +MSGID_DEFAULT_MENU_PREFS_URL (//) +URL +; +; +MSGID_DEFAULT_MENU_PREFS_USB (//) +USB +; +; +MSGID_DEFAULT_MENU_PREFS_WBPATTERN (//) +WBPattern +; +; +MSGID_DEFAULT_MENU_PREFS_WBSTARTUP (//) +WBStartup +; +; +MSGID_DEFAULT_MENU_PREFS_WORKBENCH (//) +Workbench +; +; +MSGID_DEFAULT_MENU_SYSTEM_INTELLIFONT (//) +IntelliFont +; +; +MSGID_DEFAULT_MENU_TOOLS_GRAPHICDUMP (//) +GraphicDump +; +; +MSGID_DEFAULT_MENU_UTILITIES_WBCLOCK (//) +WBClock +; +; +MSGID_DEFAULT_MENU_PREFS_CACHECDFS (//) +CacheCDFS +; +; +MSGID_DEFAULT_MENU_PREFS_ICONTROL (//) +IControl +; +; +MSGID_DEFAULT_MENU_PREFS_OVERSCAN (//) +Overscan +; +; +MSGID_DEFAULT_MENU_PREFS_REACTION (//) +Reaction +; +; +MSGID_DEFAULT_MENU_PREFS_VINCED (//) +ViNCDe +; +; +MSGID_DEFAULT_MENU_PREFS_WARPOS (//) +WarpOS +; +; +MSGID_DEFAULT_MENU_TOOLS_BENCHTRASH (//) +BenchTrash +; +; +MSGID_DEFAULT_MENU_TOOLS_CALCULATOR (//) +Calculator +; +; +MSGID_DEFAULT_MENU_TOOLS_EDITPAD (//) +EditPad +; +; +MSGID_DEFAULT_MENU_TOOLS_HDTOOLBOX (//) +HDToolBox +; +; +MSGID_DEFAULT_MENU_TOOLS_ICONEDIT (//) +IconEdit +; +; +MSGID_DEFAULT_MENU_TOOLS_INITPRINTER (//) +InitPrinter +; +; +MSGID_DEFAULT_MENU_TOOLS_IOTOOLS (//) +IoTools +; +; +MSGID_DEFAULT_MENU_TOOLS_KEYSHOW (//) +KeyShow +; +; +MSGID_DEFAULT_MENU_TOOLS_LACER (//) +Lacer +; +; +MSGID_DEFAULT_MENU_TOOLS_MEMACS (//) +MEmacs +; +; +MSGID_DEFAULT_MENU_TOOLS_PREPCARD (//) +PrepCard +; +; +MSGID_DEFAULT_MENU_TOOLS_PRINTFILES (//) +PrintFiles +; +; +MSGID_DEFAULT_MENU_TOOLS_SHOWCONFIG (//) +ShowConfig +; +; +MSGID_DEFAULT_MENU_TOOLS_UNARC (//) +Unarc +; +; +MSGID_DEFAULT_SYSTEM (//) +System +; +; +MSGID_DEFAULT_MENU_SYSTEM_FIND (//) +Find... +; +; +MSGID_DEFAULT_MENU_SYSTEM_FIXFONT (//) +FixFont +; +; +MSGID_DEFAULT_MENU_SYSTEM_FORMAT (//) +Format... +; +; +MSGID_DEFAULT_MENU_SYSTEM_SHELL (//) +Shell +; +; +MSGID_DEFAULT_MENU_SYSTEM_FORMATCDRW (//) +FormatCDRW +; +; +MSGID_DEFAULT_MENU_SYSTEM_MEDIATOOLBOX (//) +MediaToolBox +; +; +MSGID_DEFAULT_MENU_SYSTEM_MOUNTER (//) +Mounter +; +; +MSGID_DEFAULT_MENU_SYSTEM_TYPEMANAGER (//) +TypeManager +; +; +MSGID_DEFAULT_MENU_SYSTEM_HELP (//) +Help +; +;----------------------------------------------------------- +; diff --git a/scalos/Prefs/Menu/Scalos_Menu.info b/scalos/Prefs/Menu/Scalos_Menu.info new file mode 100755 index 0000000000000000000000000000000000000000..c6fa4a603d5c07bb669b438f606ed56724cd65e2 GIT binary patch literal 1809 zcwSvo4NOy46h5y%^jQjhjZ9xv*7u4?8)2a;QB+M-dXiL_#zChDNuG)^d` zg@P3UnPdLZ&DOsqa~hMW)2UdQIwsXPO%@|e88TxKfAANcyAO18J2&s#ckcbpch0%@ z+&ctdz)22_2Eow408?(K3*e35hqm8*`wtlZdu~!5d+l_g*#+;4c6b`%P}c5A9wzR4 zGmsGI8>iCg3rv>$jG0D*sUVq}XERc3iYc3JzERC##;EjGqprYc(p&Ov88a6eZQORg zC39$ZtSZN3Fj^R!CD&MB{O@+Q#hM2YmC1Q#>-0thk4i~FN&I5U)6D|lHNr?fh6#B# zNGp$0P1W}TusCG7LE2f)&;ojZfHDCn)?xz3ptLjGqVYKJR)SNqEl)B#5$udx!&dbb z7LqN5zmPolJQZG5JfZYtSrjGnCy?2x9;C7&<&wf@FvNA1FJN$w;tGiRv>4*wc=m*X zfRSwho#wbUj@c#B)!Lh%1azh$E6EfoQM|Qw?$gvd_6%EKVO|iBNsXZMD}p`Kv&>+b zR4!;=CZ^x#7d*Awj`kO=a;l0uJPXKv0DQ@gR1JdeTi4bETOC0*Kh6ycU(6UYh&XK z-r^-#=%TY~bVm0(HENGvB+n82fZx`UFCfCtO0)d$_X;=ce%9^>>A+g5 zGU>rak z*R3Nc)cD@Iar~rLEw+|6LbDf={$P9>0R;@*TZh}FJ>ZsY^aHzsr?lNmm5J^HE$wu- zI@K!|6*Nxlhh_Fz_bC{t=%d~8$X<2LqJ~4)c(Q8p)VW>^Tr_dnOPkCMAvQ3@pA#Og zKNa)nv$kWtuwN%#!DnQW9_zL9DYFN(YO>y!u{0X5bgCyVsylR)k9gegN1{;SkLJBwF-daQTG&Ci zQ6IuFhTiqvjM~Si?yj0stVtLh(Y{IKTis>-;RK>IEFh|`@i7!!v(kD!bYNvV?({RS zNYX>RbS*|1e36*T)CE;tbgX8}BkBMdCSJJ=T!ASyi{iZWtU(H6?a|{=QOCFhe*@7V z^|?dd)SB$z7B7r&zpa!ZidFT?RxHonn_M)s#cQE=iOtu86Z?5pb8la0Yul7yvreiD zE9(BK{WPH}X-(E_TF^RSO3>ify#UfM`9;90aZGT$SFb)GH|q)gQ_ylpE4V`*-kRc= zJZe%Sy5%l(%kAB|ob&Y#xxDFcW06vVLZTG+U2%WxUpOjzd2*55Y#=KhL8?dp*m6xL zwqMF>;FE4e9VSpdQk-NG<>vWhMK5|MZQ6t{yM_QqP`BQbQq{g /dev/null 2>&1 + +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(CSRCS:%.c=$(OBJDIR)/%.o) + +############################################################# + +NAME = .bin_os3/Scalos_Menu +NAMEDBG = $(NAME).debug +DESTTOOL = Scalos:Prefs/Scalos Menu +CAT_FILE = Scalos/ScalosMenu.catalog +CATCOMPHEADER = $(SCALOS_LOCALE) +DESTCAT = Locale:Catalogs +CATS = dansk \ + deutsch \ + español \ + français \ + italiano \ + svenska \ + ÃeÓtina + +ALLCATS = $(foreach cat,$(CATS),catalogs/$(cat)/$(CAT_FILE)) + +############################################################# + +# The default target (all) and what to really build +all: $(NAME) $(NAMEDBG) \ + allcatalogs +# install +# clean +# launch + +############################################################# + +$(OBJDIR)/Menu.o : Menu.c $(SCALOS_LOCALE) + +$(CATCOMPHEADER) : ScalosMenu.cd + @printf '\033[32mMake CatComp header: \033[31m\033[1m$@ \033[32mfrom \033[31m$<\033[0m\n' + $(FLEXCAT) $(subst ../,/,$<) $@=$(SDPATH)/CatComp_h.sd + +############################################################# + +# CLI command used when linking the final executables +$(NAME) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LDLIBS) $(LDFLAGS) STRIPDEBUG + +$(NAMEDBG) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LDLIBS) $(LDFLAGS) ADDSYM + +############################################################# + +# commands generated a catalog (.catalog) from a catalog translation (.ct) file. +.ct.catalog: + $(CATCOMP) $*.cd $< CATALOG $*.catalog VB=1 + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $*.c objectname $@ + +$(OBJDIR)/%.o : %.s + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +$(OBJDIR)/%.o : %.asm + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +############################################################# + +# copy all generated file to their final destinations +install: + @printf '\033[32mInstall: \033[31m\033[1m$(NAME)\033[0m\n' + @copy $(NAME) "$(DESTTOOL)" + @printf '\033[32mInstall: \033[31m\033[1m$(CAT_FILE)\033[0m\n' + -@$(foreach cat,$(CATS),copy "catalogs/$(cat)/$(CAT_FILE)" "$(DESTCAT)/$(cat)/Scalos" clone;) + +############################################################# + +# make all Scalos preferences .catalogs +allcatalogs: + -@$(foreach cat,$(CATS),$(SUBDIRMAKE) catalogs/$(cat)/Scalos;) + +############################################################# + +# A little something to clean it all up +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + -@delete $(NAME) $(NAMEDBG) $(OBJS) $(CATCOMPHEADER) $(ALLCATS) + @printf '\033[0m' + +############################################################# + +nodebug: + -@$(SPLAT) -s -o "d2(" "d1(" "#?.c" + +############################################################# diff --git a/scalos/Prefs/Menu/makefile-new b/scalos/Prefs/Menu/makefile-new new file mode 100755 index 000000000..b8082b746 --- /dev/null +++ b/scalos/Prefs/Menu/makefile-new @@ -0,0 +1,97 @@ +# $Date: 2011-08-06 19:37:48 +0200 (Sa, 06. Aug 2011) $ +# $Revision: 823 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../.. +endif + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + SDPATH=/ +else + SDPATH=../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(OBJDIR)/Menu.o + + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Subdirs +# + +SUBDIRS = $(filter-out Catalogs/sample/Scalos, $(wildcard Catalogs/*/Scalos)) + +############################################################################## +# +# Some lame deps + +$(OBJDIR)/Menu.o $(OBJDIR)/Menu.d : $(OBJDIR)/ScalosMenu_locale.h + +$(OBJDIR)/ScalosMenu_locale.h : ScalosMenu.cd + @$(ECHO) "FlexCat $@" + $(FLEXCAT) $< $@=$(SDPATH)/CatComp_h.sd + +############################################################################## +# +# Targets +# + +NAME = Scalos_Menu +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) \ + all_subdirs + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + @$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) "Scalos:Prefs/Scalos Menu" clone + +install: install_subdirs + + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* \ + $(OBJDIR)/ScalosMenu_locale.h + +clean: clean_subdirs + +############################################################################## + + diff --git a/scalos/Prefs/Palette/Catalogs/dansk/Scalos/ScalosPalette.ct b/scalos/Prefs/Palette/Catalogs/dansk/Scalos/ScalosPalette.ct new file mode 100644 index 000000000..6283eb67a --- /dev/null +++ b/scalos/Prefs/Palette/Catalogs/dansk/Scalos/ScalosPalette.ct @@ -0,0 +1,435 @@ +; ScalosPalette.ct +## version $VER: ScalosPalette.catalog 40.11 (25 Dec 2008 10:09:16) +## codeset 0 +## language dansk +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Palette Prefs Plugin +; +; +MSGID_NEW +Ny +; +; +MSGID_DELETE +Slet +; +; +MSGID_PEN +Pen +; +; +MSGID_RED +Rød +; +; +MSGID_GREEN +Grøn +; +; +MSGID_SAVENAME +Gem +; +; +MSGID_USENAME +Brug +; +; +MSGID_CANCELNAME +Afbryd +; +; +MSGID_BLUE +Blå +; +; +MSGID_COMMANDNAME +Palette +; +; +MSGID_IMPORTNAME +WB-farver +; +; +MSGID_MENU_PROJECT_OPEN +Åbn... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +O +; +; +MSGID_MENU_PROJECT_SAVEAS +Gem som... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +A +; +; +MSGID_MENU_PROJECT_QUIT +Afslut +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +; +MSGID_MENU_PROJECT +Projekt +; +; +MSGID_MENU_EDIT_LASTSAVED +Sidst gemt +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +L +; +; +MSGID_MENU_EDIT +Editér +; +; +MSGID_MENU_SETTINGS_CREATEICONS +Opret ikoner? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +I +; +; +MSGID_MENU_SETTINGS +Indstillinger +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +Standardindstillinger +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +D +; +; +MSGID_MENU_EDIT_RESTORE +Restaurer +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +R +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Om MUI... +; +; +MSGID_WBCOLORS +Workbench farver +; +; +MSGID_TEXTPEN +Tekst farve +; +; +MSGID_SHINEPEN +Lys kant +; +; +MSGID_SHADOWPEN +Mørk kant +; +; +MSGID_HIFILLPEN +Fyld farve; +; +; +MSGID_FILLTEXTPEN +Fyldt tekst +; +; +MSGID_BGPEN +Baggrund +; +; +MSGID_HITEXTPEN +Fremhævet tekst +; +; +MSGID_BARDETAILPEN +Skærmtitel tekst +; +; +MSGID_BARBLOCKPEN +Skærmtitel baggrund +; +; +MSGID_BARTRIMPEN +Skærmtitel margin +; +; +MSGID_HSHINEPEN +Halvlys kant +; +; +MSGID_HSHADOWPEN +Halvmørk kant +; +; +MSGID_ICONTEXTPEN +Icon Text Pen +; +; +MSGID_DRAWERTEXT +Folder tekst +; +; +MSGID_DRAWERTEXTSEL +Folder tekst udvalgt +; +; +MSGID_DRAWERBG +Folder baggrund udvalgt +; +; +MSGID_FILETEXT +Fil tekst +; +; +MSGID_FILETEXTSEL +Fil tekst udvalgt +; +; +MSGID_FILEBG +Fil baggrund udvalgt +; +; +MSGID_PENNAMENAME +Pen navn +; +; +MSGID_BACKDROPDETAIL +Baggrund detalje +; +; +MSGID_BACKDROPBLOCK +Baggrund block +; +; +MSGID_MAINMENUNAME +MainMenu +; +; +MSGID_MENU_PROJECT_ABOUT +About... +; +; +MSGID_ABOUTREQOK +_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Palette Preferences V%ld.%ld\033n\n\ +%s\n\ +© 1999%s The Scalos Team\n\ +Based on original code by Stefan Sommerfeld of ALiENDESiGN! +; +; +MSGID_TOOLTIP_TEXT +Tooltip Text Pen +; +; +MSGID_TOOLTIP_BG +Tooltip Background Pen +; +; +MSGID_DRAGINFO_TEXT +Dragging Infotext Text Pen +; +; +MSGID_DRAGINFO_BG +Dragging Infotext Background Pen +; +; +MSGID_STATUSBAR_BG +Status Bar Background Pen +; +; +MSGID_STATUSBAR_TEXT +Status Bar Text Pen +; +; +MSGID_REQTITLE_SAVEERROR +Error writing palette preferences\ +file \"%s\"\ +%s +; +; +MSGID_REQTITLE_READERROR +Error reading palette preferences\ +file \"%s\"\ +%s +; +; +MSGID_TITLE_SCALOSPENLIST +Scalos item pens +; +; +MSGID_TITLE_PALETTEPENLIST +Allocated Pens %ld/%ld +; +; +MSGID_SHORTHELP_SCALOSPENLIST +This is the Scalos pen list.\n\ +Change pen assignments by dragging pens \n\ +from the allocated pens list onto the \n\ +entry you want to change. +; +; +MSGID_SHORTHELP_PALETTEPENLIST +This is the list of all \n\ +pens allocated by Scalos.\n\ + \n\ +You can drag new pens from the \n\ +Workbench pen list into this list.\n\ + \n\ +Drag pens from here into the \n\ +Scalos pen list to assign colors \n\ +to specific Scalos items. +; +; +MSGID_SHORTHELP_WBPENLIST +This is a list of all currently \n\ +used pens on the WorkBench screen.\n\ +You may drag one or more pens into \n\ +the list of Scalos allocated pens. +; +; +MSGID_SHORTHELP_SAVEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENVARC:Scalos/Palette13.prefs\". +; +; +MSGID_SHORTHELP_USEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENV:Scalos/Palette13.prefs\". +; +; +MSGID_SHORTHELP_CANCELBUTTON +Press this button to abort \n\ +and forget all changes. +; +; +MSGID_SHORTHELP_NEWBUTTON +Press this button to allocate \n\ +a new palette pen. \n\ +The button gets disabled when you try \n\ +to allocated more pens than available \n\ +for the Workbench screen. +; +; +MSGID_SHORTHELP_DELETEBUTTON +Press this button to delete the \n\ +currently selected palette pen. +; +; +MSGID_SHORTHELP_WBPENSBUTTON +This button opens a new window \n\ +with a list of all currently \n\ +used WorkBench screen colors. +; +; +MSGID_ICONTEXTPENSEL +Selected Icon Text Pen +; +; +MSGID_ICONTEXTOUTLINEPEN +Icon Text Outline Pen +; +; +MSGID_ICONTEXTSHADOWPEN +Icon Text Shadow Pen +; +; new in 40.3 +; +MSGID_PLUGIN_LIST_TITLE +Palette +; +; +MSGID_PEN_REFERENCE_COUNT +Ref. +; +; new in 40.6 +; +; +++translateme+++ +MSGID_SHORTHELP_LAMP_CHANGED +This lamp indicator changes from \033bOff\033n\n\ +to \033bOk\033n when the settings have been\n\ +modified since initial loading. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +; +++translateme+++ +MSGID_ICONTEXTFILESELBG +Selected Icon Text Rectangle Pen +;Selected Icon Text Rectangle Pen +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Scalos Palette Prefs startup failed +;Scalos Palette Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Try again|Quit +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;+++translateme+++ +MSGID_THUMBNAIL_BG +Thumbnail background pen +;Thumbnail background pen +; +;+++translateme+++ +MSGID_THUMBNAIL_BG_SEL +Selected thumbnail background pen +;Selected thumbnail background pen +; +;----------------------------------------------------------- +; diff --git a/scalos/Prefs/Palette/Catalogs/dansk/Scalos/config.mk b/scalos/Prefs/Palette/Catalogs/dansk/Scalos/config.mk new file mode 100755 index 000000000..bb98f9e35 --- /dev/null +++ b/scalos/Prefs/Palette/Catalogs/dansk/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = dansk + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = danish + +else + +############################################################################### +# AmigaOS and AROS + +LANG = dansk + +endif +endif diff --git a/scalos/Prefs/Palette/Catalogs/dansk/Scalos/makefile b/scalos/Prefs/Palette/Catalogs/dansk/Scalos/makefile new file mode 100644 index 000000000..81a98b989 --- /dev/null +++ b/scalos/Prefs/Palette/Catalogs/dansk/Scalos/makefile @@ -0,0 +1,13 @@ +# makefile for Scalos (translated Texts : dansk) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mdansk\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +ScalosPalette.catalog : ScalosPalette.ct ../../../ScalosPalette.cd + +All: ScalosPalette.catalog diff --git a/scalos/Prefs/Palette/Catalogs/dansk/Scalos/makefile-new b/scalos/Prefs/Palette/Catalogs/dansk/Scalos/makefile-new new file mode 100755 index 000000000..e6a71f71c --- /dev/null +++ b/scalos/Prefs/Palette/Catalogs/dansk/Scalos/makefile-new @@ -0,0 +1,32 @@ +# makefile for ScalosPalette (translated Texts : dansk) +# $Date: 2011-08-06 19:37:48 +0200 (Sa, 06. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = ScalosPalette + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Prefs/Palette/Catalogs/deutsch/Scalos/ScalosPalette.ct b/scalos/Prefs/Palette/Catalogs/deutsch/Scalos/ScalosPalette.ct new file mode 100644 index 000000000..37412df2f --- /dev/null +++ b/scalos/Prefs/Palette/Catalogs/deutsch/Scalos/ScalosPalette.ct @@ -0,0 +1,462 @@ +; ScalosgPalette.ct +## version $VER: ScalosPalette.catalog 40.11 (25 Dec 2008 10:09:16) +## codeset 0 +## language deutsch +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Palette Prefs Plugin +; +; +MSGID_NEW +Neu +; +; +MSGID_DELETE +Löschen +; +; +MSGID_PEN +Stift +; +; +MSGID_RED +Rot +; +; +MSGID_GREEN +Grün +; +; +MSGID_SAVENAME +Speichern +; +; +MSGID_USENAME +Benutzen +; +; +MSGID_CANCELNAME +Abbrechen +; +; +MSGID_BLUE +Blau +; +; +MSGID_COMMANDNAME +Palette +; +; +MSGID_IMPORTNAME +WB-Farben +; +; +MSGID_MENU_PROJECT_OPEN +Öffnen... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +O +; +; +MSGID_MENU_PROJECT_SAVEAS +Speichern als... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +A +; +; +MSGID_MENU_PROJECT_QUIT +Beenden +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +; +MSGID_MENU_PROJECT +Projekt +; +; +MSGID_MENU_EDIT_LASTSAVED +auf zuletzt gespeichertes +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +L +; +; +MSGID_MENU_EDIT +Verändern +; +; +MSGID_MENU_SETTINGS_CREATEICONS +Piktogramme erzeugen? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +I +; +; +MSGID_MENU_SETTINGS +Einstellungen +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +auf Vorgaben zurücksetzen +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +D +; +; +MSGID_MENU_EDIT_RESTORE +auf vorherigen Stand +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +V +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Über MUI... +; +; +MSGID_WBCOLORS +Workbench Farben +; +; +MSGID_TEXTPEN +Text +; +; +MSGID_SHINEPEN +helle Kanten +; +; +MSGID_SHADOWPEN +dunkle Kanten +; +; +MSGID_HIFILLPEN +Titelbalken aktiver Fenster +; +; +MSGID_FILLTEXTPEN +Titeltexte aktiver Fenster +; +; +MSGID_BGPEN +Hintergrund +; +; +MSGID_HITEXTPEN +wichtiger Text +; +; +MSGID_BARDETAILPEN +Menü-Text +; +; +MSGID_BARBLOCKPEN +Menü-Hintergrund +; +; +MSGID_BARTRIMPEN +Bildschirmtitel Rand +; +; +MSGID_HSHINEPEN +halbhelle Kante +; +; +MSGID_HSHADOWPEN +halbdunkle Kante +; +; +MSGID_ICONTEXTPEN +Icontext +; +; +MSGID_DRAWERTEXT +Verzeichnistext +; +; +MSGID_DRAWERTEXTSEL +angewählter Verzeichnistext +; +; +MSGID_DRAWERBG +angewählter Verzeichnistext Hintergrund +; +; +MSGID_FILETEXT +Dateitext +; +; +MSGID_FILETEXTSEL +angewählter Dateitext +; +; +MSGID_FILEBG +angewählter Dateitext Hintergrund +; +; +MSGID_PENNAMENAME +Stiftname +; +; +MSGID_BACKDROPDETAIL +Hintergrund Detail +; +; +MSGID_BACKDROPBLOCK +Hintergrund Block +; +; +MSGID_MAINMENUNAME +MainMenu +; +; +MSGID_MENU_PROJECT_ABOUT +Über... +; +; +MSGID_ABOUTREQOK +_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Palette Voreinsteller V%ld.%ld\033n\n\ +%s\n\ +© 1999%s The Scalos Team\n\ +Basiert auf Code von Stefan Sommerfeld bei ALiENDESiGN! +; +; +MSGID_TOOLTIP_TEXT +Tooltip Schriftfarbe +; +; +MSGID_TOOLTIP_BG +Tooltip Hintergrundfarbe +; +; +MSGID_DRAGINFO_TEXT +Ziehen Infotext Schriftfarbe +; +; +MSGID_DRAGINFO_BG +Ziehen Infotext Hintergrundfarbe +; +; +MSGID_STATUSBAR_BG +Statusbalken Hintergrundfarbe +; +; +MSGID_STATUSBAR_TEXT +Statusbalken Schriftfarbe +; +; +MSGID_REQTITLE_SAVEERROR +Fehler beim Schreiben der Palette \ +Voreinstellungs-Datei \"%s\"\ +%s +; +; +MSGID_REQTITLE_READERROR +Fehler beim Lesen der Palette \ +Voreinstellungs-Datei \"%s\"\ +%s +; +; +MSGID_TITLE_SCALOSPENLIST +Farben für Scalos-Elemente +;Scalos item pens +; +; +MSGID_TITLE_PALETTEPENLIST +Reservierte Farben %ld/%ld +;Allocated Pens %ld/%ld +; +; +MSGID_SHORTHELP_SCALOSPENLIST +Dies ist die Liste der Farben für die\n\ +verschiedenen graphischen Elemente von Scalos.\n\ +\n\ +Ändern der Farbzuordnung durch Ziehen einer\n\ +Farbe von der Liste der reservierten Farben\n\ +auf das gewünschte Element. +;This is the Scalos pen list.\n\ +;Change pen assignments by dragging pens \n\ +;from the allocated pens list onto the \n\ +;entry you want to change. +; +; +MSGID_SHORTHELP_PALETTEPENLIST +Dies ist die Liste aller von Scalos reservierten Farben.\n\ +\n\ +Reservieren neuer Farben durch Ziehen von Farben\n\ +aus dem Fenster der Workbench-Farben in die Liste.\n\ +\n\ +Zum Ändern der Farbe einzelner Scalos-Elemente\n\ +ziehen Sie eine Farbe von hier auf das Element\n\ +in der Liste der Farben für die Scalos-Elemente. +;This is the list of all \n\ +;pens allocated by Scalos.\n\ +; \n\ +;You can drag new pens from the \n\ +;Workbench pen list into this list.\n\ +; \n\ +;Drag pens from here into the \n\ +;Scalos pen list to assign colors \n\ +;to specific Scalos items. +; +; +MSGID_SHORTHELP_WBPENLIST +Dies ist die Liste aller Farben auf dem Workbench-Bildschirm.\n\ +\n\ +Zum Reservieren zusätzlicher Farben ziehen\n\ +Sie einen Eintrag in die Liste der reservierten Farben. +;This is a list of all currently \n\ +;used pens on the WorkBench screen.\n\ +;You may drag one or more pens into \n\ +;the list of Scalos allocated pens. +; +; +MSGID_SHORTHELP_SAVEBUTTON +Drücken Sie diesen Knopf, um alle\n\ +Einstellungen dauerhaft in\n\ +\"ENVARC:Scalos/Palette13.prefs\"\n\ +zu speichern. +;Press this button to save \n\ +;the current settings to\n\ +;\"ENVARC:Scalos/Palette13.prefs\". +; +; +MSGID_SHORTHELP_USEBUTTON +Drücken Sie diesen Knopf, um alle Einstellungen\n\ +bis zum nächsten Neustart in\n\ +\"ENV:Scalos/Palette13.prefs\"\n\ +zu speichern. +;Press this button to save \n\ +;the current settings to\n\ +;\"ENV:Scalos/Palette13.prefs\". +; +; +MSGID_SHORTHELP_CANCELBUTTON +Dieser Knopf bricht das Programm ab.\n\ +Alle Änderungen werden verworfen. +; +; +MSGID_SHORTHELP_NEWBUTTON +Dieser Knopf belegt einen neuen Stift. \n\ +Er ist stillgelegt, wenn mehr Stifte belegt \n\ +werden sollen, als auf dem \n\ +Workbench-Bildschirm verfügbar sind. +; +; +MSGID_SHORTHELP_DELETEBUTTON +Dieser Knopf entfernt den \n\ +aktuell ausgewählten Stift. +; +; +MSGID_SHORTHELP_WBPENSBUTTON +Dieser Knopf öffnet ein neues Fenster mit der\n\ +Liste aller Farben auf dem Workbench-Bildschirm. +;This button opens a new window \n\ +;with a list of all currently \n\ +;used WorkBench screen colors. +; +; +MSGID_ICONTEXTPENSEL +Icontext ausgewählt +; +; +MSGID_ICONTEXTOUTLINEPEN +Icontext Umrandung (Outline) +; +; +MSGID_ICONTEXTSHADOWPEN +Icontext Schatten +; +; new in 40.3 +; +MSGID_PLUGIN_LIST_TITLE +Farbpalette +;Palette +; +; +MSGID_PEN_REFERENCE_COUNT +Ref. +; +; new in 40.6 +; +MSGID_SHORTHELP_LAMP_CHANGED +Diese Anzeigelampe wechselt den Zustand von \033bAus\033n\n\ +nach \033bAn\033n wenn die Konfiguration seit\n\ +dem ersten Laden verändert wurde. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +; +MSGID_ICONTEXTFILESELBG +Rechteck um ausgewählten Icontext +;Selected Icon Text Rectangle Pen +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Scalos Palettenvoreinsteller kann nicht gestartet werden +;Scalos Palette Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Wiederholen|Beenden +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\ +Die Klasse ist nicht installiert. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Sie haben momentan Version v%lu.%lu installiert und\n\ +sollten die Klasse daher aktualisieren! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Version %lu.%lu wird momentan von einer anderen Anwendung\n\ +verwendet. Wenn sie die benötigte Version installiert haben,\n\ +schließen sie alle MUI Programme und probieren es erneut. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +; +MSGID_THUMBNAIL_BG +Vorschaubilder Hintergrundfarbe +;Thumbnail background pen +; +; +MSGID_THUMBNAIL_BG_SEL +angewählte Vorchaubilder Hintergrundfarbe +;Selected thumbnail background pen +; +;----------------------------------------------------------- +; diff --git a/scalos/Prefs/Palette/Catalogs/deutsch/Scalos/config.mk b/scalos/Prefs/Palette/Catalogs/deutsch/Scalos/config.mk new file mode 100755 index 000000000..8631b0623 --- /dev/null +++ b/scalos/Prefs/Palette/Catalogs/deutsch/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = deutsch + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = german + +else + +############################################################################### +# AmigaOS and AROS + +LANG = deutsch + +endif +endif diff --git a/scalos/Prefs/Palette/Catalogs/deutsch/Scalos/makefile b/scalos/Prefs/Palette/Catalogs/deutsch/Scalos/makefile new file mode 100644 index 000000000..7eaa4d75f --- /dev/null +++ b/scalos/Prefs/Palette/Catalogs/deutsch/Scalos/makefile @@ -0,0 +1,13 @@ +# makefile for Scalos (translated Texts : deutsch) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mdeutsch\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +ScalosPalette.catalog : ScalosPalette.ct ../../../ScalosPalette.cd + +All: ScalosPalette.catalog diff --git a/scalos/Prefs/Palette/Catalogs/deutsch/Scalos/makefile-new b/scalos/Prefs/Palette/Catalogs/deutsch/Scalos/makefile-new new file mode 100755 index 000000000..ea175c447 --- /dev/null +++ b/scalos/Prefs/Palette/Catalogs/deutsch/Scalos/makefile-new @@ -0,0 +1,32 @@ +# makefile for ScalosPalette (translated Texts : deutsch) +# $Date: 2011-08-06 19:37:48 +0200 (Sa, 06. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = ScalosPalette + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git "a/scalos/Prefs/Palette/Catalogs/espa\303\261ol/scalos/ScalosPalette.ct" "b/scalos/Prefs/Palette/Catalogs/espa\303\261ol/scalos/ScalosPalette.ct" new file mode 100644 index 000000000..8df501731 --- /dev/null +++ "b/scalos/Prefs/Palette/Catalogs/espa\303\261ol/scalos/ScalosPalette.ct" @@ -0,0 +1,434 @@ +; ScalosPalette.ct +## version $VER: ScalosPalette.catalog 40.11 (25 Dec 2008 10:09:16) +## codeset 0 +## language español +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Plugin Paleta de Scalos +; +; +MSGID_NEW +Nuevo +; +; +MSGID_DELETE +Eliminar +; +; +MSGID_PEN +Lápiz +; +; +MSGID_RED +Rojo +; +; +MSGID_GREEN +Verde +; +; +MSGID_SAVENAME +Guardar +; +; +MSGID_USENAME +Usar +; +; +MSGID_CANCELNAME +Cancelar +; +; +MSGID_BLUE +Azul +; +; +MSGID_COMMANDNAME +Paleta +; +; +MSGID_IMPORTNAME +Color WB +; +; +MSGID_MENU_PROJECT_OPEN +Abrir... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +O +; +; +MSGID_MENU_PROJECT_SAVEAS +Guardar como... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +A +; +; +MSGID_MENU_PROJECT_QUIT +Salir +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +; +MSGID_MENU_PROJECT +Proyecto +; +; +MSGID_MENU_EDIT_LASTSAVED +Último guardado +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +L +; +; +MSGID_MENU_EDIT +Editar +; +; +MSGID_MENU_SETTINGS_CREATEICONS +¿Crear icono? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +I +; +; +MSGID_MENU_SETTINGS +Valores +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +Predeterminados +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +D +; +; +MSGID_MENU_EDIT_RESTORE +Recuperar +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +R +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Acerca de MUI... +; +; +MSGID_WBCOLORS +Colores de Workbench +; +; +MSGID_TEXTPEN +Texto +; +; +MSGID_SHINEPEN +Brillo +; +; +MSGID_SHADOWPEN +Sombra +; +; +MSGID_HIFILLPEN +Relleno +; +; +MSGID_FILLTEXTPEN +Texto relleno +; +; +MSGID_BGPEN +Fondo +; +; +MSGID_HITEXTPEN +Texto resaltado +; +; +MSGID_BARDETAILPEN +Detalle barra +; +; +MSGID_BARBLOCKPEN +Bloque barra +; +; +MSGID_BARTRIMPEN +Línea barra +; +; +MSGID_HSHINEPEN +Medio brillo +; +; +MSGID_HSHADOWPEN +Media sombra +; +; +MSGID_ICONTEXTPEN +Icon Text Pen +; +; +MSGID_DRAWERTEXT +Texto cajón +; +; +MSGID_DRAWERTEXTSEL +Texto cajón seleccionado +; +; +MSGID_DRAWERBG +Fondo cajón seleccionado +; +; +MSGID_FILETEXT +Texto fichero +; +; +MSGID_FILETEXTSEL +Texto fichero seleccionado +; +; +MSGID_FILEBG +Fondo fichero seleccionado +; +; +MSGID_PENNAMENAME +Nombre +; +; +MSGID_BACKDROPDETAIL +Detalle pantalla completa +; +; +MSGID_BACKDROPBLOCK +Bloque pantalla completa +; +; +MSGID_MAINMENUNAME +MainMenu +; +; +MSGID_MENU_PROJECT_ABOUT +About... +; +; +MSGID_ABOUTREQOK +_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Palette Preferences V%ld.%ld\033n\n\ +%s\n\ +© 1999%s The Scalos Team\n\ +Based on original code by Stefan Sommerfeld of ALiENDESiGN! +; +; +MSGID_TOOLTIP_TEXT +Tooltip Text Pen +; +; +MSGID_TOOLTIP_BG +Tooltip Background Pen +; +; +MSGID_DRAGINFO_TEXT +Dragging Infotext Text Pen +; +; +MSGID_DRAGINFO_BG +Dragging Infotext Background Pen +; +; +MSGID_STATUSBAR_BG +Status Bar Background Pen +; +; +MSGID_STATUSBAR_TEXT +Status Bar Text Pen +; +; +MSGID_REQTITLE_SAVEERROR +Error writing palette preferences\ +file \"%s\"\ +%s +; +; +MSGID_REQTITLE_READERROR +Error reading palette preferences\ +file \"%s\"\ +%s +; +; +MSGID_TITLE_SCALOSPENLIST +Scalos item pens +; +; +MSGID_TITLE_PALETTEPENLIST +Allocated Pens %ld/%ld +; +MSGID_SHORTHELP_SCALOSPENLIST +This is the Scalos pen list.\n\ +Change pen assignments by dragging pens \n\ +from the allocated pens list onto the \n\ +entry you want to change. +; +; +MSGID_SHORTHELP_PALETTEPENLIST +This is the list of all \n\ +pens allocated by Scalos.\n\ + \n\ +You can drag new pens from the \n\ +Workbench pen list into this list.\n\ + \n\ +Drag pens from here into the \n\ +Scalos pen list to assign colors \n\ +to specific Scalos items. +; +; +MSGID_SHORTHELP_WBPENLIST +This is a list of all currently \n\ +used pens on the WorkBench screen.\n\ +You may drag one or more pens into \n\ +the list of Scalos allocated pens. +; +; +MSGID_SHORTHELP_SAVEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENVARC:Scalos/Palette13.prefs\". +; +; +MSGID_SHORTHELP_USEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENV:Scalos/Palette13.prefs\". +; +; +MSGID_SHORTHELP_CANCELBUTTON +Press this button to abort \n\ +and forget all changes. +; +; +MSGID_SHORTHELP_NEWBUTTON +Press this button to allocate \n\ +a new palette pen. \n\ +The button gets disabled when you try \n\ +to allocated more pens than available \n\ +for the Workbench screen. +; +; +MSGID_SHORTHELP_DELETEBUTTON +Press this button to delete the \n\ +currently selected palette pen. +; +; +MSGID_SHORTHELP_WBPENSBUTTON +This button opens a new window \n\ +with a list of all currently \n\ +used WorkBench screen colors. +; +; +MSGID_ICONTEXTPENSEL +Selected Icon Text Pen +; +; +MSGID_ICONTEXTOUTLINEPEN +Contorno texto +; +; +MSGID_ICONTEXTSHADOWPEN +Icon Text Shadow Pen +; +; new in 40.3 +; +MSGID_PLUGIN_LIST_TITLE +Palette +; +; +MSGID_PEN_REFERENCE_COUNT +Ref. +; +; new in 40.6 +; +; +++translateme+++ +MSGID_SHORTHELP_LAMP_CHANGED +This lamp indicator changes from \033bOff\033n\n\ +to \033bOk\033n when the settings have been\n\ +modified since initial loading. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +; +++translateme+++ +MSGID_ICONTEXTFILESELBG +Selected Icon Text Rectangle Pen +;Selected Icon Text Rectangle Pen +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Scalos Palette Prefs startup failed +;Scalos Palette Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Try again|Quit +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;+++translateme+++ +MSGID_THUMBNAIL_BG +Thumbnail background pen +;Thumbnail background pen +; +;+++translateme+++ +MSGID_THUMBNAIL_BG_SEL +Selected thumbnail background pen +;Selected thumbnail background pen +; +;----------------------------------------------------------- +; diff --git "a/scalos/Prefs/Palette/Catalogs/espa\303\261ol/scalos/config.mk" "b/scalos/Prefs/Palette/Catalogs/espa\303\261ol/scalos/config.mk" new file mode 100755 index 000000000..d0133689f --- /dev/null +++ "b/scalos/Prefs/Palette/Catalogs/espa\303\261ol/scalos/config.mk" @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = español + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = spanish + +else + +############################################################################### +# AmigaOS and AROS + +LANG = español + +endif +endif diff --git "a/scalos/Prefs/Palette/Catalogs/espa\303\261ol/scalos/makefile" "b/scalos/Prefs/Palette/Catalogs/espa\303\261ol/scalos/makefile" new file mode 100644 index 000000000..e7e5676b3 --- /dev/null +++ "b/scalos/Prefs/Palette/Catalogs/espa\303\261ol/scalos/makefile" @@ -0,0 +1,12 @@ +# makefile für Scalos (translated Texts : español) +# 01 Jan 2004 12:43:17 + +.SUFFIXES: .ct .catalog + +.ct.catalog : + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +ScalosPalette.catalog : ScalosPalette.ct ../../../ScalosPalette.cd + +All: ScalosPalette.catalog diff --git "a/scalos/Prefs/Palette/Catalogs/espa\303\261ol/scalos/makefile-new" "b/scalos/Prefs/Palette/Catalogs/espa\303\261ol/scalos/makefile-new" new file mode 100755 index 000000000..9dca08d2d --- /dev/null +++ "b/scalos/Prefs/Palette/Catalogs/espa\303\261ol/scalos/makefile-new" @@ -0,0 +1,32 @@ +# makefile for ScalosPalette (translated Texts : español) +# $Date: 2011-08-06 19:37:48 +0200 (Sa, 06. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = ScalosPalette + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git "a/scalos/Prefs/Palette/Catalogs/fran\303\247ais/Scalos/ScalosPalette.ct" "b/scalos/Prefs/Palette/Catalogs/fran\303\247ais/Scalos/ScalosPalette.ct" new file mode 100755 index 000000000..57be4e000 --- /dev/null +++ "b/scalos/Prefs/Palette/Catalogs/fran\303\247ais/Scalos/ScalosPalette.ct" @@ -0,0 +1,537 @@ +; ScalosPalette.ct +## version $VER: ScalosPalette.catalog 40.11 (25 Dec 2008 10:09:16) +## codeset 0 +## language français +; +;#arrayopts static __far +; +; Translation done +; +; By COAT Jean-Marie ALIAS JMC +; E-Mail : agalliance@free.fr +; +; +MSGID_TITLENAME +Palette plugin de Scalos +; Scalos Palette +; +; +MSGID_NEW +Nouveau +; New +; +; +MSGID_DELETE +Effacer +; Delete +; +; +MSGID_PEN +Couleur +; Pen +; +; +MSGID_RED +Rouge +; Red +; +; +MSGID_GREEN +Vert +; Green +; +; +MSGID_SAVENAME +Sauver +; Save +; +; +MSGID_USENAME +Utiliser +; Use +; +; +MSGID_CANCELNAME +Annuler +; Cancel +; +; +MSGID_BLUE +Bleu +; Blue +; +; +MSGID_COMMANDNAME +Palette +; Palette +; +; +MSGID_IMPORTNAME +Couleurs actuelles du WB +; Current WB Colours +; +; +MSGID_MENU_PROJECT_OPEN +Ouvrir... +; Open... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +O +; +; +MSGID_MENU_PROJECT_SAVEAS +Sauver en... +; Save As... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +A +; +; +MSGID_MENU_PROJECT_QUIT +Quitter +; Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +; +MSGID_MENU_PROJECT +Projet +; Project +; +; +MSGID_MENU_EDIT_LASTSAVED +Dernière sauvegarde +; Last Saved +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +L +; +; +MSGID_MENU_EDIT +Edition +; Edit +; +; +MSGID_MENU_SETTINGS_CREATEICONS +Créer les icônes ? +; Create Icons? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +I +; +; +MSGID_MENU_SETTINGS +Options +; Settings +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +Réglages par défaut +; Reset To Defaults +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +D +; +; +MSGID_MENU_EDIT_RESTORE +Restaurer +; Restore +; +MSGID_MENU_EDIT_RESTORE_SHORT +R +; +MSGID_MENU_PROJECT_ABOUTMUI +A propos de MUI... +; About MUI... +; +MSGID_WBCOLORS +Couleurs du Workbench +; Workbench Colours +; +MSGID_TEXTPEN +Texte +; Text Pen +; +; +MSGID_SHINEPEN +Arêtes brillantes +; Bright Edges Pen +; +; +MSGID_SHADOWPEN +Arêtes sombres +; Dark Edges Pen +; +; +MSGID_HIFILLPEN +Barre de fenêtre active +; Active Window Title Bar Pen +; +; +MSGID_FILLTEXTPEN +Titre de la fenêtre active +; Active Window Titles Pen +; +; +MSGID_BGPEN +Arrière-plan +; Background Pen +; +; +MSGID_HITEXTPEN +Texte important +; Important Text Pen +; +; +MSGID_BARDETAILPEN +Texte des menus +; Menu Text Pen +; +; +MSGID_BARBLOCKPEN +Arrière-plan des menus +; Menu Background Pen +; +; +MSGID_BARTRIMPEN +Bords des menus +; Menu Border Pen +; +; +MSGID_HSHINEPEN +Arêtes demi-brillante +; Half-bright edges Pen +; +; +MSGID_HSHADOWPEN +Arêtes demi-sombre +; Half-dark edges Pen +; +; +MSGID_ICONTEXTPEN +Texte des icônes +; Icon Text Pen +; +; +MSGID_DRAWERTEXT +Texte des répertoires +; Drawer Text Pen +; +; +MSGID_DRAWERTEXTSEL +Texte des répertoires sélectionnés +; Drawer selected Text Pen +; +; +MSGID_DRAWERBG +Arrière-plan des répertoires sélectionnés +; Drawer selected Background +; +; +MSGID_FILETEXT +Texte des fichiers +; File Text Pen +; +; +MSGID_FILETEXTSEL +Texte des fichiers sélectionnés +; File selected Text Pen +; +; +MSGID_FILEBG +Arrière-plan des fichiers sélectionnés +; File selected Background +; +; +MSGID_PENNAMENAME +Désignation +; Pen Name +; +; +MSGID_BACKDROPDETAIL +Détail de l'arrière-plan +; Backdrop Detail Pen +; +; +MSGID_BACKDROPBLOCK +Bloc d'arrière-plan +; Backdrop Block Pen +; +; +MSGID_MAINMENUNAME +Menu principal +; MainMenu +; +; +MSGID_MENU_PROJECT_ABOUT +A propos... +; About... +; +; +MSGID_ABOUTREQOK +D'accord +; _OK +; +; +MSGID_ABOUTREQFORMAT +\033cPréférences : \033bPalette de Scalos V\0333%ld\0332.\0333%ld\033n\0332\n\ +Compilé sous: \0333%s\0332\n\ +\033b© 1999%s \0333The Scalos Team\033n\0332\n\ +Inspiré du programme original créé par\n\ +\033bStefan Sommerfeld\033n de \0333\033bALiENDESiGN!\033n\0332 +; \033cScalos Palette Preferences V40.1\n\ +; © 1999-2002 The Scalos Team\n\ +; Based on original code by Stefan Sommerfeld of ALiENDESiGN! +; +; +MSGID_TOOLTIP_TEXT +Texte du Tooltip +; Tooltip Text Pen +; +; +MSGID_TOOLTIP_BG +Arrière-plan du Tooltip +; Tooltip Background Pen +; +; +MSGID_DRAGINFO_TEXT +Fichiers en mouvement +; Dragging Infotext Text Pen +; +; +MSGID_DRAGINFO_BG +Arrière-plan des fichiers en mouvement +; Dragging Infotext Background Pen +; +; +MSGID_STATUSBAR_BG +Arrière-plan de la barre de statut +; Status Bar Background Pen +; +; +MSGID_STATUSBAR_TEXT +Texte de la barre de statut +; Status Bar Text Pen +; +; +MSGID_REQTITLE_SAVEERROR +Erreur durant l'écriture du fichier\n\ +des préférences : \"%s\"\n\ +%s +; Error writing palette preferences\ +; file \"%s\"\ +; %s +; +; +MSGID_REQTITLE_READERROR +Erreur durant le chargement du fichier\n\ +des préférences : \"%s\"\n\ +%s +; Error reading palette preferences\ +; file \"%s\"\ +; %s +; +; +MSGID_TITLE_SCALOSPENLIST +Couleurs des objets de Scalos +; Scalos item colors +; +; +MSGID_TITLE_PALETTEPENLIST +Couleurs allouées \033b\0333%ld\0331 / \0333%ld\0331\033n +; Allocated Pens +; +; +MSGID_SHORTHELP_SCALOSPENLIST +C'est la liste des couleurs des objets de Scalos.\n\ +Changez les assignements des couleurs par \n\ +déplacement des couleurs de la liste allouées\n\ +par Scalos sur l'entrée que vous désirez changer. +; This is the Scalos pen list.\n\ +; Change pen assignments by dragging pens \n\ +; from the allocated pens list onto the \n\ +; entry you want to change. +; +; +MSGID_SHORTHELP_PALETTEPENLIST +C'est la liste de toutes les \n\ +couleurs allouées par Scalos.\n\ +\n\ +Vous pouvez imorter de nouvelles couleurs depuis\n\ +la liste des couleurs du Workbench dans cette liste.\n\ +\n\ +Exporter des couleurs de cette liste vers\n\ +la liste des objets de Scalos afin de les\n\ +assigner aux couleurs des objets désirées. +; This is the list of all \n\ +; pens allocated by Scalos.\n\ +; \n\ +; You can drag new pens from the \n\ +; Workbench pen list into this list.\n\ +; \n\ +; Drag pens from here into the \n\ +; Scalos pen list to assign colors \n\ +; to specific Scalos items. +; +; +MSGID_SHORTHELP_WBPENLIST +C'est la liste de toutes les couleurs actuellement\n\ +utilisées par l'écran WorkBench.\n\ +Vous pouvez exporter une ou plusieurs couleurs\n\ +vers la liste des couleurs allouées par Scalos. +; This is a list of all currently \n\ +; used pens on the WorkBench screen.\n\ +; You may drag one or more pens into \n\ +; the list of Scalos allocated pens. +; +; +MSGID_SHORTHELP_SAVEBUTTON +Pressez ce bouton afin de sauvegarder \n\ +les changements actuels vers :\n\ +\"\033bENVARC:Scalos/Palette13.prefs\033n\". +; Press this button to save \n\ +; the current settings to\n\ +; \"ENVARC:Scalos/Palette13.prefs\". +; +; +MSGID_SHORTHELP_USEBUTTON +Pressez ce bouton afin de sauvegarder \n\ +les changements actuels vers :\n\ +\"\033bENV:Scalos/Palette13.prefs\033n\". +; Press this button to save \n\ +; the current settings to\n\ +; \"ENV:Scalos/Palette13.prefs\". +; +; +MSGID_SHORTHELP_CANCELBUTTON +Pressez ce bouton afin d'annuler \n\ +et d'oublier tous changements. +; Press this button to abort \n\ +; and forget all changes. +; +; +MSGID_SHORTHELP_NEWBUTTON +Pressez ce bouton afin d'allouer une nouvelle couleur.\n\ +Le bouton est innaccèssible lorsque vous essayez\n\ +d'allouer plus de couleurs que celles disponibles\n\ +depuis l'écran du Workbench. +; Press this button to allocate \n\ +; a new palette pen. \n\ +; The button gets disabled when you try \n\ +; to allocated more pens than available \n\ +; for the Workbench screen. +; +; +MSGID_SHORTHELP_DELETEBUTTON +Pressez ce bouton afin d'éffacer la\n\ +couleur actuellement sélectionnée. +; Press this button to delete the \n\ +; currently selected palette pen. +; +; +MSGID_SHORTHELP_WBPENSBUTTON +Ce bouton ouvre une nouvelle fenêtre \n\ +contenant les couleurs actuellement \n\ +utilisées par l'écran du WorkBench. +; This button opens a new window \n\ +; with a list of all currently \n\ +; used WorkBench screen colors. +; +; +MSGID_ICONTEXTPENSEL +Texte de l'icône sélectionnée +; Selected Icon Text Pen +; +; +MSGID_ICONTEXTOUTLINEPEN +Pourtour du texte +; Icon Text Outline Pen +; +; +MSGID_ICONTEXTSHADOWPEN +Arête demi-ombrée du texte de l'icône +; Icon Text Shadow Pen +; +; +MSGID_PLUGIN_LIST_TITLE +Palette +;Palette +; +; +MSGID_PEN_REFERENCE_COUNT +Réf. +;Ref. +; +; New in 40.6 +; +MSGID_SHORTHELP_LAMP_CHANGED +Cet indicateur passe de l'état \033binactif\033n\n\ +à l'état \033bactif\033n, une fois que les options\n\ +ont été modifiées depuis le chargement initial. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +MSGID_ICONTEXTFILESELBG +Pinceau du rectangle du texte de l'icône +;Selected Icon Text Rectangle Pen +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Le lancement de Scalos Prefs a échoué +;Scalos Palette Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Recommençer|Quitter +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +Celle-ci n'est pas installée. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +\n\ +La version installée est V%lu.%lu, installez-en une plus récente s'il vous plaît ! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +%lu.%lu est actuellement utilisée par d'autres applications.\n\ +\n\ +Une fois la version requise installée,\n\ +fermez tous les programmes MUI, soyez sûr que l'ancienne classe\n\ +ne soit plus présente dans la mémoire puis, essayez de nouveau. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +MSGID_THUMBNAIL_BG +Arrière-plan des vignettes +;Thumbnail background pen +; +MSGID_THUMBNAIL_BG_SEL +Arrière-plan des vignettes sélectionées +;Selected thumbnail background pen +; +;----------------------------------------------------------- +; diff --git "a/scalos/Prefs/Palette/Catalogs/fran\303\247ais/Scalos/config.mk" "b/scalos/Prefs/Palette/Catalogs/fran\303\247ais/Scalos/config.mk" new file mode 100755 index 000000000..8b7056423 --- /dev/null +++ "b/scalos/Prefs/Palette/Catalogs/fran\303\247ais/Scalos/config.mk" @@ -0,0 +1,40 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = français + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = french + +else + +############################################################################### +# AmigaOS and AROS + +LANG = français + +endif +endif diff --git "a/scalos/Prefs/Palette/Catalogs/fran\303\247ais/Scalos/makefile" "b/scalos/Prefs/Palette/Catalogs/fran\303\247ais/Scalos/makefile" new file mode 100644 index 000000000..510f2973b --- /dev/null +++ "b/scalos/Prefs/Palette/Catalogs/fran\303\247ais/Scalos/makefile" @@ -0,0 +1,13 @@ +# makefile for Scalos (translated Texts : français) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mfrançais\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +ScalosPalette.catalog : ScalosPalette.ct ../../../ScalosPalette.cd + +All: ScalosPalette.catalog diff --git "a/scalos/Prefs/Palette/Catalogs/fran\303\247ais/Scalos/makefile-new" "b/scalos/Prefs/Palette/Catalogs/fran\303\247ais/Scalos/makefile-new" new file mode 100755 index 000000000..ad9df8710 --- /dev/null +++ "b/scalos/Prefs/Palette/Catalogs/fran\303\247ais/Scalos/makefile-new" @@ -0,0 +1,32 @@ +# makefile for ScalosPalette (translated Texts : français) +# $Date: 2011-08-06 19:37:48 +0200 (Sa, 06. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = ScalosPalette + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Prefs/Palette/Catalogs/italiano/Scalos/ScalosPalette.ct b/scalos/Prefs/Palette/Catalogs/italiano/Scalos/ScalosPalette.ct new file mode 100644 index 000000000..c21679852 --- /dev/null +++ b/scalos/Prefs/Palette/Catalogs/italiano/Scalos/ScalosPalette.ct @@ -0,0 +1,434 @@ +; ScalosPalette.ct +## version $VER: ScalosPalette.catalog 40.11 (25 Dec 2008 10:09:16) +## codeset 0 +## language italiano +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Plugin Palette di Scalos +; +; +MSGID_NEW +Nuovo +; +; +MSGID_DELETE +Cancella +; +; +MSGID_PEN +Penna +; +; +MSGID_RED +Rosso +; +; +MSGID_GREEN +Verde +; +; +MSGID_SAVENAME +Salva +; +; +MSGID_USENAME +Usa +; +; +MSGID_CANCELNAME +Annulla +; +; +MSGID_BLUE +Blu +; +; +MSGID_COMMANDNAME +Palette +; +; +MSGID_IMPORTNAME +Colori WB +; +; +MSGID_MENU_PROJECT_OPEN +Apri... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +O +; +; +MSGID_MENU_PROJECT_SAVEAS +Salva come... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +A +; +; +MSGID_MENU_PROJECT_QUIT +Fine +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +; +MSGID_MENU_PROJECT +Progetto +; +; +MSGID_MENU_EDIT_LASTSAVED +Ripristina ultimi valori +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +L +; +; +MSGID_MENU_EDIT +Modifica +; +; +MSGID_MENU_SETTINGS_CREATEICONS +Crea icone? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +I +; +; +MSGID_MENU_SETTINGS +Opzioni +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +Ripristina predefiniti +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +D +; +; +MSGID_MENU_EDIT_RESTORE +Annulla modifiche +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +R +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Info su MUI... +; +; +MSGID_WBCOLORS +Colori Workbench +; +; +MSGID_TEXTPEN +Testo +; +; +MSGID_SHINEPEN +Brillante +; +; +MSGID_SHADOWPEN +Ombra +; +; +MSGID_HIFILLPEN +Riempimento +; +; +MSGID_FILLTEXTPEN +Riempimento testo +; +; +MSGID_BGPEN +Sfondo +; +; +MSGID_HITEXTPEN +Testo evidenziato +; +; +MSGID_BARDETAILPEN +Titolo schermo +; +; +MSGID_BARBLOCKPEN +Sfondo titolo schermo +; +; +MSGID_BARTRIMPEN +Bordo barra +; +; +MSGID_HSHINEPEN +Semi-brillante +; +; +MSGID_HSHADOWPEN +Semi-ombra +; +; +MSGID_ICONTEXTPEN +Icon Text Pen +; +; +MSGID_DRAWERTEXT +Testo cassetto +; +; +MSGID_DRAWERTEXTSEL +Cassetto selezionato +; +; +MSGID_DRAWERBG +Sfondo cassetto selezionato +; +; +MSGID_FILETEXT +Testo file +; +; +MSGID_FILETEXTSEL +Testo file selezionato +; +; +MSGID_FILEBG +Sfondo file selezionato +; +; +MSGID_PENNAMENAME +Nome penna +; +; +MSGID_BACKDROPDETAIL +Dettaglio posteriore +; +; +MSGID_BACKDROPBLOCK +Blocco posteriore +; +; +MSGID_MAINMENUNAME +MainMenu +; +; +MSGID_MENU_PROJECT_ABOUT +About... +; +; +MSGID_ABOUTREQOK +_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Palette Preferences V%ld.%ld\033n\n\ +%s\n\ +© 1999%s The Scalos Team\n\ +Based on original code by Stefan Sommerfeld of ALiENDESiGN! +; +; +MSGID_TOOLTIP_TEXT +Tooltip Text Pen +; +; +MSGID_TOOLTIP_BG +Tooltip Background Pen +; +; +MSGID_DRAGINFO_TEXT +Dragging Infotext Text Pen +; +; +MSGID_DRAGINFO_BG +Dragging Infotext Background Pen +; +; +MSGID_STATUSBAR_BG +Status Bar Background Pen +; +; +MSGID_STATUSBAR_TEXT +Status Bar Text Pen +; +; +MSGID_REQTITLE_SAVEERROR +Error writing palette preferences\ +file \"%s\"\ +%s +; +; +MSGID_REQTITLE_READERROR +Error reading palette preferences\ +file \"%s\"\ +%s +; +; +MSGID_TITLE_SCALOSPENLIST +Scalos item pens +; +; +MSGID_TITLE_PALETTEPENLIST +Allocated Pens %ld/%ld +; +MSGID_SHORTHELP_SCALOSPENLIST +This is the Scalos pen list.\n\ +Change pen assignments by dragging pens \n\ +from the allocated pens list onto the \n\ +entry you want to change. +; +; +MSGID_SHORTHELP_PALETTEPENLIST +This is the list of all \n\ +pens allocated by Scalos.\n\ + \n\ +You can drag new pens from the \n\ +Workbench pen list into this list.\n\ + \n\ +Drag pens from here into the \n\ +Scalos pen list to assign colors \n\ +to specific Scalos items. +; +; +MSGID_SHORTHELP_WBPENLIST +This is a list of all currently \n\ +used pens on the WorkBench screen.\n\ +You may drag one or more pens into \n\ +the list of Scalos allocated pens. +; +; +MSGID_SHORTHELP_SAVEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENVARC:Scalos/Palette13.prefs\". +; +; +MSGID_SHORTHELP_USEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENV:Scalos/Palette13.prefs\". +; +; +MSGID_SHORTHELP_CANCELBUTTON +Press this button to abort \n\ +and forget all changes. +; +; +MSGID_SHORTHELP_NEWBUTTON +Press this button to allocate \n\ +a new palette pen. \n\ +The button gets disabled when you try \n\ +to allocated more pens than available \n\ +for the Workbench screen. +; +; +MSGID_SHORTHELP_DELETEBUTTON +Press this button to delete the \n\ +currently selected palette pen. +; +; +MSGID_SHORTHELP_WBPENSBUTTON +This button opens a new window \n\ +with a list of all currently \n\ +used WorkBench screen colors. +; +; +MSGID_ICONTEXTPENSEL +Selected Icon Text Pen +; +; +MSGID_ICONTEXTOUTLINEPEN +Icon Text Outline Pen +; +; +MSGID_ICONTEXTSHADOWPEN +Icon Text Shadow Pen +; +; new in 40.3 +; +MSGID_PLUGIN_LIST_TITLE +Palette +; +; +MSGID_PEN_REFERENCE_COUNT +Ref. +; +; new in 40.6 +; +; +++translateme+++ +MSGID_SHORTHELP_LAMP_CHANGED +This lamp indicator changes from \033bOff\033n\n\ +to \033bOk\033n when the settings have been\n\ +modified since initial loading. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +; +++translateme+++ +MSGID_ICONTEXTFILESELBG +Selected Icon Text Rectangle Pen +;Selected Icon Text Rectangle Pen +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Scalos Palette Prefs startup failed +;Scalos Palette Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Try again|Quit +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;+++translateme+++ +MSGID_THUMBNAIL_BG +Thumbnail background pen +;Thumbnail background pen +; +;+++translateme+++ +MSGID_THUMBNAIL_BG_SEL +Selected thumbnail background pen +;Selected thumbnail background pen +; +;----------------------------------------------------------- +; diff --git a/scalos/Prefs/Palette/Catalogs/italiano/Scalos/config.mk b/scalos/Prefs/Palette/Catalogs/italiano/Scalos/config.mk new file mode 100755 index 000000000..8108491da --- /dev/null +++ b/scalos/Prefs/Palette/Catalogs/italiano/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = italiano + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = italian + +else + +############################################################################### +# AmigaOS and AROS + +LANG = italiano + +endif +endif diff --git a/scalos/Prefs/Palette/Catalogs/italiano/Scalos/makefile b/scalos/Prefs/Palette/Catalogs/italiano/Scalos/makefile new file mode 100644 index 000000000..a6d6ca3ec --- /dev/null +++ b/scalos/Prefs/Palette/Catalogs/italiano/Scalos/makefile @@ -0,0 +1,13 @@ +# makefile für Scalos (translated Texts : italiano) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mitaliano\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +ScalosPalette.catalog : ScalosPalette.ct ../../../ScalosPalette.cd + +All: ScalosPalette.catalog diff --git a/scalos/Prefs/Palette/Catalogs/italiano/Scalos/makefile-new b/scalos/Prefs/Palette/Catalogs/italiano/Scalos/makefile-new new file mode 100755 index 000000000..3464dada9 --- /dev/null +++ b/scalos/Prefs/Palette/Catalogs/italiano/Scalos/makefile-new @@ -0,0 +1,33 @@ +# makefile for ScalosPalette (translated Texts : italiano) +# $Date: 2011-08-06 19:37:48 +0200 (Sa, 06. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = ScalosPalette + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Prefs/Palette/Catalogs/sample/Scalos/ScalosPalette.ct b/scalos/Prefs/Palette/Catalogs/sample/Scalos/ScalosPalette.ct new file mode 100644 index 000000000..56abd7bd4 --- /dev/null +++ b/scalos/Prefs/Palette/Catalogs/sample/Scalos/ScalosPalette.ct @@ -0,0 +1,435 @@ +; ScalosPalette.ct +## version $VER: ScalosPalette.catalog 40.11 (25 Dec 2008 10:09:16) +## codeset 0s +## language xxxxxx +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Palette Prefs Plugin +; +; +MSGID_NEW +New +; +; +MSGID_DELETE +Delete +; +; +MSGID_PEN +Pen +; +; +MSGID_RED +Red +; +; +MSGID_GREEN +Green +; +; +MSGID_SAVENAME +Save +; +; +MSGID_USENAME +Use +; +; +MSGID_CANCELNAME +Cancel +; +; +MSGID_BLUE +Blue +; +; +MSGID_COMMANDNAME +Palette +; +; +MSGID_IMPORTNAME +Current WB Colors +; +; +MSGID_MENU_PROJECT_OPEN +Open... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +O +; +; +MSGID_MENU_PROJECT_SAVEAS +Save As... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +A +; +; +MSGID_MENU_PROJECT_QUIT +Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +; +MSGID_MENU_PROJECT +Project +; +; +MSGID_MENU_EDIT_LASTSAVED +Last Saved +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +L +; +; +MSGID_MENU_EDIT +Edit +; +; +MSGID_MENU_SETTINGS_CREATEICONS +Create Icons? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +I +; +; +MSGID_MENU_SETTINGS +Settings +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +Reset To Defaults +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +D +; +; +MSGID_MENU_EDIT_RESTORE +Restore +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +R +; +; +MSGID_MENU_PROJECT_ABOUTMUI +About MUI... +; +; +MSGID_WBCOLORS +Workbench Colors +; +; +MSGID_TEXTPEN +Text Pen +; +; +MSGID_SHINEPEN +Bright Edges Pen +; +; +MSGID_SHADOWPEN +Dark Edges Pen +; +; +MSGID_HIFILLPEN +Active Window Title Bar Pen +; +; +MSGID_FILLTEXTPEN +Active Window Titles Pen +; +; +MSGID_BGPEN +Background Pen +; +; +MSGID_HITEXTPEN +Important Text Pen +; +; +MSGID_BARDETAILPEN +Menu Text Pen +; +; +MSGID_BARBLOCKPEN +Menu Background Pen +; +; +MSGID_BARTRIMPEN +Menu Border Pen +; +; +MSGID_HSHINEPEN (//) +Half-bright edges Pen +; +; +MSGID_HSHADOWPEN (//) +Half-dark edges Pen +; +; +MSGID_ICONTEXTPEN +Icon Text Pen +; +; +MSGID_DRAWERTEXT +Drawer Text Pen +; +; +MSGID_DRAWERTEXTSEL +Drawer selected Text Pen +; +; +MSGID_DRAWERBG +Drawer selected Background +; +; +MSGID_FILETEXT +File Text Pen +; +; +MSGID_FILETEXTSEL +File selected Text Pen +; +; +MSGID_FILEBG +File selected Background +; +; +MSGID_PENNAMENAME +Pen Name +; +; +MSGID_BACKDROPDETAIL +Backdrop Detail Pen +; +; +MSGID_BACKDROPBLOCK +Backdrop Block Pen +; +; +MSGID_MAINMENUNAME +MainMenu +; +; +MSGID_MENU_PROJECT_ABOUT +About... +; +; +MSGID_ABOUTREQOK +_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Palette Preferences V%ld.%ld\033n\n\ +%s\n\ +© 1999-2004 The Scalos Team\n\ +Based on original code by Stefan Sommerfeld of ALiENDESiGN! +; +; +MSGID_TOOLTIP_TEXT +Tooltip Text Pen +; +; +MSGID_TOOLTIP_BG +Tooltip Background Pen +; +; +MSGID_DRAGINFO_TEXT +Dragging Infotext Text Pen +; +; +MSGID_DRAGINFO_BG +Dragging Infotext Background Pen +; +; +MSGID_STATUSBAR_BG +Status Bar Background Pen +; +; +MSGID_STATUSBAR_TEXT +Status Bar Text Pen +; +; +MSGID_REQTITLE_SAVEERROR +Error writing palette preferences\ +file \"%s\"\ +%s +; +; +MSGID_REQTITLE_READERROR +Error reading palette preferences\ +file \"%s\"\ +%s +; +; +MSGID_TITLE_SCALOSPENLIST +Scalos item pens +; +; +MSGID_TITLE_PALETTEPENLIST +Allocated Pens +; +; +MSGID_SHORTHELP_SCALOSPENLIST +This is the Scalos pen list.\n\ +Change pen assignments by dragging pens \n\ +from the allocated pens list onto the \n\ +entry you want to change. +; +; +MSGID_SHORTHELP_PALETTEPENLIST +This is the list of all \n\ +pens allocated by Scalos.\n\ + \n\ +You can drag new pens from the \n\ +Workbench pen list into this list.\n\ + \n\ +Drag pens from here into the \n\ +Scalos pen list to assign colors \n\ +to specific Scalos items. +; +; +MSGID_SHORTHELP_WBPENLIST +This is a list of all currently \n\ +used pens on the WorkBench screen.\n\ +You may drag one or more pens into \n\ +the list of Scalos allocated pens. +; +; +MSGID_SHORTHELP_SAVEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENVARC:Scalos/Palette13.prefs\". +; +; +MSGID_SHORTHELP_USEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENV:Scalos/Palette13.prefs\". +; +; +MSGID_SHORTHELP_CANCELBUTTON +Press this button to abort \n\ +and forget all changes. +; +; +MSGID_SHORTHELP_NEWBUTTON +Press this button to allocate \n\ +a new palette pen. \n\ +The button gets disabled when you try \n\ +to allocated more pens than available \n\ +for the Workbench screen. +; +; +MSGID_SHORTHELP_DELETEBUTTON +Press this button to delete the \n\ +currently selected palette pen. +; +; +MSGID_SHORTHELP_WBPENSBUTTON +This button opens a new window \n\ +with a list of all currently \n\ +used WorkBench screen colors. +; +; +MSGID_ICONTEXTPENSEL +Selected Icon Text Pen +; +; +MSGID_ICONTEXTOUTLINEPEN +Icon Text Outline Pen +; +; +MSGID_ICONTEXTSHADOWPEN +Icon Text Shadow Pen +; +; new in 40.3 +; +MSGID_PLUGIN_LIST_TITLE +Palette +; +; +MSGID_PEN_REFERENCE_COUNT +Ref. +; +; new in 40.6 +; +; +++translateme+++ +MSGID_SHORTHELP_LAMP_CHANGED +This lamp indicator changes from \033bOff\033n\n\ +to \033bOk\033n when the settings have been\n\ +modified since initial loading. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +; +++translateme+++ +MSGID_ICONTEXTFILESELBG +Selected Icon Text Rectangle Pen +;Selected Icon Text Rectangle Pen +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Scalos Palette Prefs startup failed +;Scalos Palette Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Try again|Quit +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;+++translateme+++ +MSGID_THUMBNAIL_BG +Thumbnail background pen +;Thumbnail background pen +; +;+++translateme+++ +MSGID_THUMBNAIL_BG_SEL +Selected thumbnail background pen +;Selected thumbnail background pen +; +;----------------------------------------------------------- +; diff --git a/scalos/Prefs/Palette/Catalogs/svenska/Scalos/ScalosPalette.ct b/scalos/Prefs/Palette/Catalogs/svenska/Scalos/ScalosPalette.ct new file mode 100644 index 000000000..43a1a564b --- /dev/null +++ b/scalos/Prefs/Palette/Catalogs/svenska/Scalos/ScalosPalette.ct @@ -0,0 +1,435 @@ +; ScalosPalette.ct +## version $VER: ScalosPalette.catalog 40.11 (25 Dec 2008 10:09:16) +## codeset 0 +## language svenska +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Plugin Scalos Färger +; +; +MSGID_NEW +Ny +; +; +MSGID_DELETE +Radera +; +; +MSGID_PEN +Penna +; +; +MSGID_RED +Röd +; +; +MSGID_GREEN +Grön +; +; +MSGID_SAVENAME +Spara +; +; +MSGID_USENAME +Använd +; +; +MSGID_CANCELNAME +Avbryt +; +; +MSGID_BLUE +Blå +; +; +MSGID_COMMANDNAME +Palett +; +; +MSGID_IMPORTNAME +WB-färger +; +; +MSGID_MENU_PROJECT_OPEN +Öppna... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +O +; +; +MSGID_MENU_PROJECT_SAVEAS +Spara som... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +A +; +; +MSGID_MENU_PROJECT_QUIT +Avsluta +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +; +MSGID_MENU_PROJECT +Arkiv +; +; +MSGID_MENU_EDIT_LASTSAVED +Senast sparade +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +L +; +; +MSGID_MENU_EDIT +Redigera +; +; +MSGID_MENU_SETTINGS_CREATEICONS +Skapa symboler? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +I +; +; +MSGID_MENU_SETTINGS +Inställningar +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +Förinställda värden +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +D +; +; +MSGID_MENU_EDIT_RESTORE +Återställ +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +R +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Om MUI... +; +; +MSGID_WBCOLORS +Workbench-färger +; +; +MSGID_TEXTPEN +Text +; +; +MSGID_SHINEPEN +Ljusa kanter +; +; +MSGID_SHADOWPEN +Mörka kanter +; +; +MSGID_HIFILLPEN +Fyllfärg +; +; +MSGID_FILLTEXTPEN +Fylld text +; +; +MSGID_BGPEN +Bakgrund +; +; +MSGID_HITEXTPEN +Viktig text +; +; +MSGID_BARDETAILPEN +Skärmtitel - Text +; +; +MSGID_BARBLOCKPEN +Skärmtitel - Bakgrund +; +; +MSGID_BARTRIMPEN +Skärmtitel - Ram +; +; +MSGID_HSHINEPEN +Halvljusa kanter +; +; +MSGID_HSHADOWPEN +Halvmörka kanter +; +; +MSGID_ICONTEXTPEN +Icon Text Pen +; +; +MSGID_DRAWERTEXT +Lådor - Text +; +; +MSGID_DRAWERTEXTSEL +Valda lådor - Text +; +; +MSGID_DRAWERBG +Valda lådor - Bakgrund +; +; +MSGID_FILETEXT +Fil - Text +; +; +MSGID_FILETEXTSEL +Vald fil - Text +; +; +MSGID_FILEBG +Vald fil - Bakgrund +; +; +MSGID_PENNAMENAME +Namn +; +; +MSGID_BACKDROPDETAIL +Bakgrund - detaljer +; +; +MSGID_BACKDROPBLOCK +Bakgrund - Block +; +; +MSGID_MAINMENUNAME +MainMenu +; +; +MSGID_MENU_PROJECT_ABOUT +About... +; +; +MSGID_ABOUTREQOK +_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Palette Prefs Plugin V%ld.%ld\033n\n\ +%s\n\ +© 1999%s The Scalos Team\n\ +Based on original code by Stefan Sommerfeld of ALiENDESiGN! +; +; +MSGID_TOOLTIP_TEXT +Tooltip Text Pen +; +; +MSGID_TOOLTIP_BG +Tooltip Background Pen +; +; +MSGID_DRAGINFO_TEXT +Dragging Infotext Text Pen +; +; +MSGID_DRAGINFO_BG +Dragging Infotext Background Pen +; +; +MSGID_STATUSBAR_BG +Status Bar Background Pen +; +; +MSGID_STATUSBAR_TEXT +Status Bar Text Pen +; +; +MSGID_REQTITLE_SAVEERROR +Error writing palette preferences\ +file \"%s\"\ +%s +; +; +MSGID_REQTITLE_READERROR +Error reading palette preferences\ +file \"%s\"\ +%s +; +; +MSGID_TITLE_SCALOSPENLIST +Scalos item pens +; +; +MSGID_TITLE_PALETTEPENLIST +Allocated Pens %ld/%ld +; +; +MSGID_SHORTHELP_SCALOSPENLIST +This is the Scalos pen list.\n\ +Change pen assignments by dragging pens \n\ +from the allocated pens list onto the \n\ +entry you want to change. +; +; +MSGID_SHORTHELP_PALETTEPENLIST +This is the list of all \n\ +pens allocated by Scalos.\n\ + \n\ +You can drag new pens from the \n\ +Workbench pen list into this list.\n\ + \n\ +Drag pens from here into the \n\ +Scalos pen list to assign colors \n\ +to specific Scalos items. +; +; +MSGID_SHORTHELP_WBPENLIST +This is a list of all currently \n\ +used pens on the WorkBench screen.\n\ +You may drag one or more pens into \n\ +the list of Scalos allocated pens. +; +; +MSGID_SHORTHELP_SAVEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENVARC:Scalos/Palette13.prefs\". +; +; +MSGID_SHORTHELP_USEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENV:Scalos/Palette13.prefs\". +; +; +MSGID_SHORTHELP_CANCELBUTTON +Press this button to abort \n\ +and forget all changes. +; +; +MSGID_SHORTHELP_NEWBUTTON +Press this button to allocate \n\ +a new palette pen. \n\ +The button gets disabled when you try \n\ +to allocated more pens than available \n\ +for the Workbench screen. +; +; +MSGID_SHORTHELP_DELETEBUTTON +Press this button to delete the \n\ +currently selected palette pen. +; +; +MSGID_SHORTHELP_WBPENSBUTTON +This button opens a new window \n\ +with a list of all currently \n\ +used WorkBench screen colors. +; +; +MSGID_ICONTEXTPENSEL +Selected Icon Text Pen +; +; +MSGID_ICONTEXTOUTLINEPEN +Icon Text Outline Pen +; +; +MSGID_ICONTEXTSHADOWPEN +Icon Text Shadow Pen +; +; new in 40.3 +; +MSGID_PLUGIN_LIST_TITLE +Palette +; +; +MSGID_PEN_REFERENCE_COUNT +Ref. +; +; new in 40.6 +; +; +++translateme+++ +MSGID_SHORTHELP_LAMP_CHANGED +This lamp indicator changes from \033bOff\033n\n\ +to \033bOk\033n when the settings have been\n\ +modified since initial loading. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +; +++translateme+++ +MSGID_ICONTEXTFILESELBG +Selected Icon Text Rectangle Pen +;Selected Icon Text Rectangle Pen +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Scalos Palette Prefs startup failed +;Scalos Palette Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Try again|Quit +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;+++translateme+++ +MSGID_THUMBNAIL_BG +Thumbnail background pen +;Thumbnail background pen +; +;+++translateme+++ +MSGID_THUMBNAIL_BG_SEL +Selected thumbnail background pen +;Selected thumbnail background pen +; +;----------------------------------------------------------- +; diff --git a/scalos/Prefs/Palette/Catalogs/svenska/Scalos/config.mk b/scalos/Prefs/Palette/Catalogs/svenska/Scalos/config.mk new file mode 100755 index 000000000..ec05f9b34 --- /dev/null +++ b/scalos/Prefs/Palette/Catalogs/svenska/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = svenska + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = swedish + +else + +############################################################################### +# AmigaOS and AROS + +LANG = svenska + +endif +endif diff --git a/scalos/Prefs/Palette/Catalogs/svenska/Scalos/makefile b/scalos/Prefs/Palette/Catalogs/svenska/Scalos/makefile new file mode 100644 index 000000000..00013803f --- /dev/null +++ b/scalos/Prefs/Palette/Catalogs/svenska/Scalos/makefile @@ -0,0 +1,13 @@ +# makefile for Scalos (translated Texts : svenska) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1msvenska\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +ScalosPalette.catalog : ScalosPalette.ct ../../../ScalosPalette.cd + +All: ScalosPalette.catalog diff --git a/scalos/Prefs/Palette/Catalogs/svenska/Scalos/makefile-new b/scalos/Prefs/Palette/Catalogs/svenska/Scalos/makefile-new new file mode 100755 index 000000000..9accb27c7 --- /dev/null +++ b/scalos/Prefs/Palette/Catalogs/svenska/Scalos/makefile-new @@ -0,0 +1,32 @@ +# makefile for ScalosPalette (translated Texts : svenska) +# $Date: 2011-08-06 19:37:48 +0200 (Sa, 06. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = ScalosPalette + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git "a/scalos/Prefs/Palette/Catalogs/\303\203e\303\223tina/Scalos/ScalosPalette.ct" "b/scalos/Prefs/Palette/Catalogs/\303\203e\303\223tina/Scalos/ScalosPalette.ct" new file mode 100644 index 000000000..2af2240a4 --- /dev/null +++ "b/scalos/Prefs/Palette/Catalogs/\303\203e\303\223tina/Scalos/ScalosPalette.ct" @@ -0,0 +1,435 @@ +; ScalosPalette.ct +## version $VER: ScalosPalette.catalog 40.11 (25 Dec 2008 10:09:16) +## codeset 0 +## language ÃeÓtina +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Palette Prefs Plugin +; +; +MSGID_NEW +Nov× +; +; +MSGID_DELETE +Smazat +; +; +MSGID_PEN +Pero +; +; +MSGID_RED +ãervenÁ +; +; +MSGID_GREEN +ZelenÁ +; +; +MSGID_SAVENAME +UloÚit +; +; +MSGID_USENAME +PouÚÉt +; +; +MSGID_CANCELNAME +ZruÓit +; +; +MSGID_BLUE +ModrÁ +; +; +MSGID_COMMANDNAME +Paleta +; +; +MSGID_IMPORTNAME +Barvy WB +; +; +MSGID_MENU_PROJECT_OPEN +OtevÒÉt... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +O +; +; +MSGID_MENU_PROJECT_SAVEAS +UloÚit jako... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +A +; +; +MSGID_MENU_PROJECT_QUIT +SkonÃit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +; +MSGID_MENU_PROJECT +Projekt +; +; +MSGID_MENU_EDIT_LASTSAVED +Naposledy uloÚen× +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +L +; +; +MSGID_MENU_EDIT +õpravy +; +; +MSGID_MENU_SETTINGS_CREATEICONS +VytvÁÒet ikony? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +I +; +; +MSGID_MENU_SETTINGS +NastavenÉ +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +Syst×mov× +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +D +; +; +MSGID_MENU_EDIT_RESTORE +PÒedchozÉ +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +R +; +; +MSGID_MENU_PROJECT_ABOUTMUI +O MUI... +; +; +MSGID_WBCOLORS +Workbench barvy +; +; +MSGID_TEXTPEN +Text +; +; +MSGID_SHINEPEN +SvÅtl× okraje +; +; +MSGID_SHADOWPEN +Tmav× okraje +; +; +MSGID_HIFILLPEN +VÙplÎ +; +; +MSGID_FILLTEXTPEN +Text na aktivnÉm poli +; +; +MSGID_BGPEN +PozadÉ +; +; +MSGID_HITEXTPEN +JasnÙ text +; +; +MSGID_BARDETAILPEN +Text na liÓtÅ obrazovky +; +; +MSGID_BARBLOCKPEN +LiÓta obrazovky +; +; +MSGID_BARTRIMPEN +Lem liÓty obrazovky +; +; +MSGID_HSHINEPEN +PolosvÅtl× okraje +; +; +MSGID_HSHADOWPEN +Polotmav× okraje +; +; +MSGID_ICONTEXTPEN +Icon Text Pen +; +; +MSGID_DRAWERTEXT +AdresÁÒ +; +; +MSGID_DRAWERTEXTSEL +OznaÃenÙ adresÁÒ +; +; +MSGID_DRAWERBG +PozadÉ oznaÃen×ho adresÁÒe +; +; +MSGID_FILETEXT +Soubor +; +; +MSGID_FILETEXTSEL +OznaÃenÙ soubor +; +; +MSGID_FILEBG +PozadÉ oznaÃen×ho souboru +; +; +MSGID_PENNAMENAME +Jm×no pera +; +; +MSGID_BACKDROPDETAIL +PozadÉ detail +; +; +MSGID_BACKDROPBLOCK +PozadÉ blok +; +; +MSGID_MAINMENUNAME +MainMenu +; +; +MSGID_MENU_PROJECT_ABOUT +About... +; +; +MSGID_ABOUTREQOK +_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Palette Preferences V%ld.%ld\033n\n\ +%s\n\ +© 1999%s The Scalos Team\n\ +Based on original code by Stefan Sommerfeld of ALiENDESiGN! +; +; +MSGID_TOOLTIP_TEXT +Tooltip Text Pen +; +; +MSGID_TOOLTIP_BG +Tooltip Background Pen +; +; +MSGID_DRAGINFO_TEXT +Dragging Infotext Text Pen +; +; +MSGID_DRAGINFO_BG +Dragging Infotext Background Pen +; +; +MSGID_STATUSBAR_BG +Status Bar Background Pen +; +; +MSGID_STATUSBAR_TEXT +Status Bar Text Pen +; +; +MSGID_REQTITLE_SAVEERROR +Error writing palette preferences\ +file \"%s\"\ +%s +; +; +MSGID_REQTITLE_READERROR +Error reading palette preferences\ +file \"%s\"\ +%s +; +; +MSGID_TITLE_SCALOSPENLIST +Scalos item pens +; +; +MSGID_TITLE_PALETTEPENLIST +Allocated Pens %ld/%ld +; +; +MSGID_SHORTHELP_SCALOSPENLIST +This is the Scalos pen list.\n\ +Change pen assignments by dragging pens \n\ +from the allocated pens list onto the \n\ +entry you want to change. +; +; +MSGID_SHORTHELP_PALETTEPENLIST +This is the list of all \n\ +pens allocated by Scalos.\n\ + \n\ +You can drag new pens from the \n\ +Workbench pen list into this list.\n\ + \n\ +Drag pens from here into the \n\ +Scalos pen list to assign colors \n\ +to specific Scalos items. +; +; +MSGID_SHORTHELP_WBPENLIST +This is a list of all currently \n\ +used pens on the WorkBench screen.\n\ +You may drag one or more pens into \n\ +the list of Scalos allocated pens. +; +; +MSGID_SHORTHELP_SAVEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENVARC:Scalos/Palette13.prefs\". +; +; +MSGID_SHORTHELP_USEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENV:Scalos/Palette13.prefs\". +; +; +MSGID_SHORTHELP_CANCELBUTTON +Press this button to abort \n\ +and forget all changes. +; +; +MSGID_SHORTHELP_NEWBUTTON +Press this button to allocate \n\ +a new palette pen. \n\ +The button gets disabled when you try \n\ +to allocated more pens than available \n\ +for the Workbench screen. +; +; +MSGID_SHORTHELP_DELETEBUTTON +Press this button to delete the \n\ +currently selected palette pen. +; +; +MSGID_SHORTHELP_WBPENSBUTTON +This button opens a new window \n\ +with a list of all currently \n\ +used WorkBench screen colors. +; +; +MSGID_ICONTEXTPENSEL +Selected Icon Text Pen +; +; +MSGID_ICONTEXTOUTLINEPEN +Icon Text Outline Pen +; +; +MSGID_ICONTEXTSHADOWPEN +Icon Text Shadow Pen +; +; new in 40.3 +; +MSGID_PLUGIN_LIST_TITLE +Palette +; +; +MSGID_PEN_REFERENCE_COUNT +Ref. +; +; new in 40.6 +; +; +++translateme+++ +MSGID_SHORTHELP_LAMP_CHANGED +This lamp indicator changes from \033bOff\033n\n\ +to \033bOk\033n when the settings have been\n\ +modified since initial loading. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +; +++translateme+++ +MSGID_ICONTEXTFILESELBG +Selected Icon Text Rectangle Pen +;Selected Icon Text Rectangle Pen +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Scalos Palette Prefs startup failed +;Scalos Palette Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Try again|Quit +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;+++translateme+++ +MSGID_THUMBNAIL_BG +Thumbnail background pen +;Thumbnail background pen +; +;+++translateme+++ +MSGID_THUMBNAIL_BG_SEL +Selected thumbnail background pen +;Selected thumbnail background pen +; +;----------------------------------------------------------- +; diff --git "a/scalos/Prefs/Palette/Catalogs/\303\203e\303\223tina/Scalos/config.mk" "b/scalos/Prefs/Palette/Catalogs/\303\203e\303\223tina/Scalos/config.mk" new file mode 100755 index 000000000..7bfe8c7a6 --- /dev/null +++ "b/scalos/Prefs/Palette/Catalogs/\303\203e\303\223tina/Scalos/config.mk" @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = ÃeÓtina + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = czech + +else + +############################################################################### +# AmigaOS and AROS + +LANG = ÃeÓtina + +endif +endif diff --git "a/scalos/Prefs/Palette/Catalogs/\303\203e\303\223tina/Scalos/makefile" "b/scalos/Prefs/Palette/Catalogs/\303\203e\303\223tina/Scalos/makefile" new file mode 100644 index 000000000..4a2c81f62 --- /dev/null +++ "b/scalos/Prefs/Palette/Catalogs/\303\203e\303\223tina/Scalos/makefile" @@ -0,0 +1,12 @@ +# makefile für Scalos (translated Texts : ÃeÓtina) +# 01 Jan 2004 12:43:59 + +.SUFFIXES: .ct .catalog + +.ct.catalog : + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +ScalosPalette.catalog : ScalosPalette.ct ../../../ScalosPalette.cd + +All: ScalosPalette.catalog diff --git "a/scalos/Prefs/Palette/Catalogs/\303\203e\303\223tina/Scalos/makefile-new" "b/scalos/Prefs/Palette/Catalogs/\303\203e\303\223tina/Scalos/makefile-new" new file mode 100755 index 000000000..a0e03c735 --- /dev/null +++ "b/scalos/Prefs/Palette/Catalogs/\303\203e\303\223tina/Scalos/makefile-new" @@ -0,0 +1,32 @@ +# makefile for ScalosPalette (translated Texts : ÃeÓtina) +# $Date: 2011-08-06 19:37:48 +0200 (Sa, 06. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = ScalosPalette + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Prefs/Palette/Palette.c b/scalos/Prefs/Palette/Palette.c new file mode 100644 index 000000000..4ec7686ed --- /dev/null +++ b/scalos/Prefs/Palette/Palette.c @@ -0,0 +1,878 @@ +// Palette.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include // +jmc+ +#include + +struct ScalosPalette_LocaleInfo +{ + APTR li_LocaleBase; + APTR li_Catalog; + struct LocaleIFace *li_ILocale; +}; + +#define ScalosPalette_NUMBERS +#define ScalosPalette_ARRAY +#define ScalosPalette_CODE +#include STR(SCALOSLOCALE) + +//---------------------------------------------------------------------------- + +#define Sizeof(array) (sizeof(array) / sizeof((array)[0])) + +//---------------------------------------------------------------------------- + +#if !defined(__amigaos4__) && !defined(__AROS__) +#include + +long _stack = 16384; // minimum stack size, used by SAS/C startup code +#endif + +//---------------------------------------------------------------------------- + +// local data structures + +#define KeyButtonHelp(name,key,HelpText)\ + TextObject,\ + ButtonFrame,\ + MUIA_Font, MUIV_Font_Button,\ + MUIA_Text_Contents, name,\ + MUIA_Text_PreParse, "\33c",\ + MUIA_Text_HiChar , key,\ + MUIA_ControlChar , key,\ + MUIA_CycleChain , TRUE, \ + MUIA_InputMode , MUIV_InputMode_RelVerify,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShortHelp, HelpText,\ + End + + +#define Application_Return_EDIT 0 +#define Application_Return_USE 1001 +#define Application_Return_SAVE 1002 + +//---------------------------------------------------------------------------- + +// local functions + +static void init(void); +static void fail(Object *APP_Main, CONST_STRPTR str); +static BOOL OpenLibraries(void); +static void CloseLibraries(void); +static STRPTR GetLocString(ULONG MsgId); +static SAVEDS(APTR) INTERRUPT OpenAboutMUIFunc(struct Hook *hook, Object *o, Msg msg); +static struct MUI_CustomClass *OpenPrefsModule(CONST_STRPTR FileName); +static struct TagItem *CreatePluginSubWindowArray(void); +static void DisposePrefsPlugin(void); +static BOOL CheckMCCforPlugin(STRPTR *UsedClasses, size_t MaxUsedClasses); +static BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev); +#if !defined(__SASC) &&!defined(__MORPHOS__) +size_t stccpy(char *dest, const char *src, size_t MaxLen); +#endif /* !defined(__SASC) &&!defined(__MORPHOS__) */ + +//---------------------------------------------------------------------------- + +// local data items + +struct Library *MUIMasterBase; +T_LOCALEBASE LocaleBase; +struct Library *IconBase; +struct IntuitionBase *IntuitionBase; +struct Library *ScalosPrefsPluginBase; + +#ifdef __amigaos4__ +extern struct Library *SysBase; +struct MUIMasterIFace *IMUIMaster; +struct LocaleIFace *ILocale; +struct IconIFace *IIcon; +struct IntuitionIFace *IIntuition; +struct ScalosPrefsPluginIFace *IScalosPrefsPlugin; +#endif + +static struct MUI_CustomClass *PalettePluginClass; + +static struct Hook OpenAboutMUIHook = { { NULL, NULL }, HOOKFUNC_DEF(OpenAboutMUIFunc), NULL }; + +static struct TagItem *SubWindowTagList; + +static struct Catalog *PaletteCatalog; + +static Object **PluginSubWindows; +static Object *APP_Main; +static Object *WIN_Main; +static Object *WIN_AboutMUI; +static Object *Group_Plugin; +static Object *SaveButton, *UseButton, *CancelButton; +static Object *MenuOpen, *MenuSaveAs, *MenuAbout, *MenuAboutMUI, *MenuQuit; +static Object *MenuResetToDefaults, *MenuLastSaved, *MenuRestore; +static Object *MenuCreateIcons; + +//---------------------------------------------------------------------------- + +int main(int argc, char *argv[]) +{ + LONG Action = Application_Return_EDIT; + LONG win_opened = 0; + struct RDArgs *rdArgs = NULL; + CONST_STRPTR GivenFileName = NULL; + BPTR oldDir = (BPTR)NULL; + ULONG fCreateIcons = TRUE; + struct DiskObject *PaletteDiskObject = NULL; + STRPTR ProgramName; + STRPTR UsedClasses[32]; + struct WBStartup *WBenchMsg = + (argc == 0) ? (struct WBStartup *)argv : NULL; + + init(); + + if (WBenchMsg && WBenchMsg->sm_ArgList) + { + static char PrgNamePath[512]; + struct WBArg *arg; + struct DiskObject *icon; + + if (WBenchMsg->sm_NumArgs > 1) + { + arg = &WBenchMsg->sm_ArgList[1]; + GivenFileName = arg->wa_Name; + } + else + { + arg = &WBenchMsg->sm_ArgList[0]; + } + + ProgramName = PrgNamePath; + + NameFromLock(WBenchMsg->sm_ArgList[0].wa_Lock, PrgNamePath, sizeof(PrgNamePath)); + AddPart(PrgNamePath, WBenchMsg->sm_ArgList[0].wa_Name, sizeof(PrgNamePath)); + + oldDir = CurrentDir(arg->wa_Lock); + + icon = GetDiskObject(arg->wa_Name); + if (icon) + { + STRPTR tt; + + tt = FindToolType(icon->do_ToolTypes, "CREATEICONS"); + if (tt) + { + if (MatchToolValue(tt, "NO")) + fCreateIcons = FALSE; + } + + tt = FindToolType(icon->do_ToolTypes, "ACTION"); + if (tt) + { + if (MatchToolValue(tt, "EDIT")) + Action = Application_Return_EDIT; + if (MatchToolValue(tt, "USE")) + Action = Application_Return_USE; + if (MatchToolValue(tt, "SAVE")) + Action = Application_Return_SAVE; + } + + FreeDiskObject(icon); + } + } + else + { + SIPTR ArgArray[4]; + + ProgramName = argv[0]; + + memset(ArgArray, 0, sizeof(ArgArray)); + + rdArgs = ReadArgs("FROM,EDIT/S,USE/S,SAVE/S", ArgArray, NULL); + + if (ArgArray[0]) + GivenFileName = (CONST_STRPTR) ArgArray[0]; + if (ArgArray[1]) + Action = Application_Return_EDIT; + if (ArgArray[2]) + Action = Application_Return_USE; + if (ArgArray[3]) + Action = Application_Return_SAVE; + } + + if (NULL == PalettePluginClass) + fail(APP_Main, "Failed to open Palette Plugin."); + + PaletteDiskObject = GetDiskObject(ProgramName); + + Group_Plugin = NewObject(PalettePluginClass->mcc_Class, 0, + MUIA_ScalosPrefs_CreateIcons, fCreateIcons, + MUIA_ScalosPrefs_ProgramName, (ULONG) ProgramName, + TAG_END); + if (NULL == Group_Plugin) + fail(APP_Main, "Failed to create Group_Plugin."); + + if (!CheckMCCforPlugin(UsedClasses, Sizeof(UsedClasses))) + fail(APP_Main, "Required MCC missing."); + + SubWindowTagList = CreatePluginSubWindowArray(); + + APP_Main = ApplicationObject, + MUIA_Application_Title, GetLocString(MSGID_TITLENAME), + MUIA_Application_Version, "$VER: Scalos Palette 40.11 (" __DATE__ ")" COMPILER_STRING, + MUIA_Application_Copyright, "The Scalos Team, 2000" CURRENTYEAR, + MUIA_Application_Author, "The Scalos Team", + MUIA_Application_Description, "Scalos Palette preferences editor", + MUIA_Application_Base, "SCALOS_PALETTE", + PaletteDiskObject ? MUIA_Application_DiskObject : TAG_IGNORE, PaletteDiskObject, +#if defined(MUIA_Application_UsedClasses) + MUIA_Application_UsedClasses, UsedClasses, +#endif /* MUIA_Application_UsedClasses */ + + SubWindow, WIN_Main = WindowObject, + MUIA_Window_Title, GetLocString(MSGID_TITLENAME), + MUIA_Window_ID, MAKE_ID('M','A','I','N'), + WindowContents, VGroup, + Child, Group_Plugin, + + Child, ColGroup(3), + Child, SaveButton = KeyButtonHelp(GetLocString(MSGID_SAVENAME), 's', GetLocString(MSGID_SHORTHELP_SAVEBUTTON)), + Child, UseButton = KeyButtonHelp(GetLocString(MSGID_USENAME), 'u', GetLocString(MSGID_SHORTHELP_USEBUTTON)), + Child, CancelButton = KeyButtonHelp(GetLocString(MSGID_CANCELNAME), 'c', GetLocString(MSGID_SHORTHELP_CANCELBUTTON)), + End, + End, + End, + + MUIA_Application_Menustrip, MenustripObject, + Child, MenuObjectT(GetLocString(MSGID_MENU_PROJECT)), + Child, MenuOpen = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_OPEN), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_PROJECT_OPEN_SHORT), + End, + Child, MenuSaveAs = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_SAVEAS), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_PROJECT_SAVEAS_SHORT), + End, + Child, MenuitemObject, + MUIA_Menuitem_Title, -1, + End, + Child, MenuAbout = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUT), + End, + Child, MenuAboutMUI = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUTMUI), + End, + Child, MenuitemObject, + MUIA_Menuitem_Title, -1, + End, + Child, MenuQuit = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_QUIT), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_PROJECT_QUIT_SHORT), + End, + + End, //MenuObjectT + Child, MenuObjectT(GetLocString(MSGID_MENU_EDIT)), + Child, MenuResetToDefaults = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_EDIT_RESETTODEFAULTS), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT), + End, + Child, MenuLastSaved = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_EDIT_LASTSAVED), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_EDIT_LASTSAVED_SHORT), + End, + Child, MenuRestore = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_EDIT_RESTORE), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_EDIT_RESTORE_SHORT), + End, + End, //MenuObjectT + Child, MenuObjectT(GetLocString(MSGID_MENU_SETTINGS)), + Child, MenuCreateIcons = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_SETTINGS_CREATEICONS), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_SETTINGS_CREATEICONS_SHORT), + MUIA_Menuitem_Checkit, TRUE, + MUIA_Menuitem_Checked, fCreateIcons, + End, + End, //MenuObjectT + End, + + SubWindowTagList ? TAG_MORE : TAG_IGNORE, SubWindowTagList, + End; //ApplicationObject + + if (NULL == APP_Main) + { + MUI_DisposeObject(Group_Plugin); + Group_Plugin = NULL; + fail(APP_Main, "Failed to create Application."); + } + + set(Group_Plugin, MUIA_ScalosPrefs_MainWindow, (ULONG) WIN_Main); + set(Group_Plugin, MUIA_ScalosPrefs_Application, (ULONG) APP_Main); + + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + WIN_Main, 3, MUIM_Set, MUIA_Window_Open, FALSE); + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + DoMethod(CancelButton, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + DoMethod(MenuQuit, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + DoMethod(SaveButton, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_Application_ReturnID, Application_Return_SAVE); + + DoMethod(UseButton, MUIM_Notify,MUIA_Pressed,FALSE, + APP_Main, 2, MUIM_Application_ReturnID, Application_Return_USE); + + DoMethod(MenuQuit, MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + DoMethod(MenuOpen, MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime, + Group_Plugin, 1, MUIM_ScalosPrefs_OpenConfig); + + DoMethod(MenuSaveAs, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + Group_Plugin, 1, MUIM_ScalosPrefs_SaveConfigAs); + + DoMethod(MenuResetToDefaults, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + Group_Plugin, 1, MUIM_ScalosPrefs_ResetToDefaults); + + DoMethod(MenuLastSaved, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + Group_Plugin, 1, MUIM_ScalosPrefs_LastSavedConfig); + + DoMethod(MenuRestore, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + Group_Plugin, 1, MUIM_ScalosPrefs_RestoreConfig); + + DoMethod(MenuAbout, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + Group_Plugin, 1, MUIM_ScalosPrefs_About); + + DoMethod(MenuAboutMUI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &OpenAboutMUIHook); + + DoMethod(MenuCreateIcons, MUIM_Notify, MUIA_Menuitem_Checked, MUIV_EveryTime, + Group_Plugin, 3, MUIM_Set, MUIA_ScalosPrefs_CreateIcons, MUIV_TriggerValue); + + if (GivenFileName) + { + DoMethod(Group_Plugin, MUIM_ScalosPrefs_LoadNamedConfig, GivenFileName); + } + else + { + DoMethod(Group_Plugin, MUIM_ScalosPrefs_LoadConfig); + } + + if (Application_Return_EDIT == Action) + { + set(WIN_Main, MUIA_Window_Open, TRUE); + + get(WIN_Main, MUIA_Window_Open, &win_opened); + + if (win_opened) + { + ULONG sigs = 0; + BOOL Run = TRUE; + + while (Run) + { + Action = DoMethod(APP_Main, MUIM_Application_NewInput, &sigs); + + switch (Action) + { + case MUIV_Application_ReturnID_Quit: + case Application_Return_SAVE: + case Application_Return_USE: + Run = FALSE; + break; + } + + if (Run && sigs) + { + sigs = Wait(sigs | SIGBREAKF_CTRL_C); + + if (sigs & SIGBREAKF_CTRL_C) + { + Run = FALSE; + break; + } + } + } + } + else + { + printf("failed to open main window !\n"); + } + } + + switch (Action) + { + case Application_Return_SAVE: + DoMethod(Group_Plugin, MUIM_ScalosPrefs_SaveConfig); + break; + case Application_Return_USE: + DoMethod(Group_Plugin, MUIM_ScalosPrefs_UseConfig); + break; + } + + set(WIN_Main, MUIA_Window_Open, FALSE); + + if (PaletteDiskObject) + FreeDiskObject(PaletteDiskObject); + if (oldDir) + CurrentDir(oldDir); + if (rdArgs) + FreeArgs(rdArgs); + + fail(APP_Main, NULL); + + return 0; +} + +//---------------------------------------------------------------------------- + +static VOID fail(Object * APP_Main, CONST_STRPTR str) +{ + if (APP_Main) + MUI_DisposeObject(APP_Main); + + DisposePrefsPlugin(); + + if (PaletteCatalog) + { + CloseCatalog(PaletteCatalog); + PaletteCatalog = NULL; + } + + CloseLibraries(); + + if (str) + { + puts(str); + exit(20); + } + + exit(0); +} + +static void init(void) +{ + APP_Main = NULL; + + if (!OpenLibraries()) + fail(NULL, "Failed to open "MUIMASTER_NAME"."); + + if (LocaleBase) + PaletteCatalog = OpenCatalogA(NULL, "Scalos/ScalosPalette.catalog", NULL); + + PalettePluginClass = OpenPrefsModule("Palette.prefsplugin"); +} + +//---------------------------------------------------------------------------- + +static BOOL OpenLibraries(void) +{ + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + if (NULL == IntuitionBase) + return FALSE; +#ifdef __amigaos4__ + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + return FALSE; +#endif + + MUIMasterBase = OpenLibrary("zune.library", 0); + if (NULL == MUIMasterBase) + MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN-1); + if (NULL == MUIMasterBase) + return FALSE; +#ifdef __amigaos4__ + IMUIMaster = (struct MUIMasterIFace *)GetInterface((struct Library *)MUIMasterBase, "main", 1, NULL); + if (NULL == IMUIMaster) + return FALSE; +#endif + + IconBase = OpenLibrary("icon.library", 0); + if (NULL == IconBase) + return FALSE; +#ifdef __amigaos4__ + IIcon = (struct IconIFace *)GetInterface((struct Library *)IconBase, "main", 1, NULL); + if (NULL == IIcon) + return FALSE; +#endif + + LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 39); +#ifdef __amigaos4__ + if (LocaleBase) + ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL); +#endif + + return TRUE; +} + + +static void CloseLibraries(void) +{ +#ifdef __amigaos4__ + if (ILocale) + { + DropInterface((struct Interface *)ILocale); + ILocale = NULL; + } +#endif + if (LocaleBase) + { + CloseLibrary((struct Library *) LocaleBase); + LocaleBase = NULL; + } +#ifdef __amigaos4__ + if (IIcon) + { + DropInterface((struct Interface *)IIcon); + IIcon = NULL; + } +#endif + if (IconBase) + { + CloseLibrary(IconBase); + IconBase = NULL; + } +#ifdef __amigaos4__ + if (IMUIMaster) + { + DropInterface((struct Interface *)IMUIMaster); + IMUIMaster = NULL; + } +#endif + if (MUIMasterBase) + { + CloseLibrary(MUIMasterBase); + MUIMasterBase = NULL; + } +#ifdef __amigaos4__ + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } +#endif + if (IntuitionBase) + { + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } +} + +//---------------------------------------------------------------------------- + +static STRPTR GetLocString(ULONG MsgId) +{ + struct ScalosPalette_LocaleInfo li; + + li.li_Catalog = PaletteCatalog; +#ifndef __amigaos4__ + li.li_LocaleBase = LocaleBase; +#else + li.li_ILocale = ILocale; +#endif + + return (STRPTR) GetScalosPaletteString(&li, MsgId); +} + +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT OpenAboutMUIFunc(struct Hook *hook, Object *o, Msg msg) +{ + if (NULL == WIN_AboutMUI) + { + WIN_AboutMUI = MUI_NewObject(MUIC_Aboutmui, + MUIA_Window_RefWindow, WIN_Main, + MUIA_Aboutmui_Application, APP_Main, + End; + } + + if (WIN_AboutMUI) + set(WIN_AboutMUI, MUIA_Window_Open, TRUE); + + return 0; +} + +//---------------------------------------------------------------------------- + +static struct MUI_CustomClass *OpenPrefsModule(CONST_STRPTR FileName) +{ + struct MUI_CustomClass *pclass = NULL; + + d1(kprintf(__FUNC__ "/%ld: FileName=<%s>\n", __LINE__, FileName)); + + do { + ScalosPrefsPluginBase = OpenLibrary(FileName, 0); + d1(kprintf(__FUNC__ "/%ld: ScalosPrefsPluginBase=%08lx\n", __LINE__, ScalosPrefsPluginBase)); + if (NULL == ScalosPrefsPluginBase) + break; +#ifdef __amigaos4__ + IScalosPrefsPlugin = (struct ScalosPrefsPluginIFace *)GetInterface( + ScalosPrefsPluginBase, "main", 1, NULL + ); +#endif + + pclass = (struct MUI_CustomClass *) SCAGetPrefsInfo(SCAPREFSINFO_GetClass); + d1(kprintf(__FUNC__ "/%ld: PluginClass=%08lx\n", __LINE__, ppl->ppl_PluginClass)); + if (NULL == pclass) + break; + } while (0); + + if (NULL == pclass) + DisposePrefsPlugin(); + + return pclass; +} + + +static struct TagItem *CreatePluginSubWindowArray(void) +{ + struct TagItem *SubWindowTagList; + struct TagItem *ti; + ULONG SubWindowCount = 0; + ULONG n; + + PluginSubWindows = (Object **) DoMethod(Group_Plugin, MUIM_ScalosPrefs_CreateSubWindows); + + for (n=0; PluginSubWindows && PluginSubWindows[n]; n++) + SubWindowCount++; + + SubWindowTagList = ti = calloc(1 + SubWindowCount, sizeof(struct TagItem)); + if (NULL == SubWindowTagList) + return NULL; + + for (n=0; PluginSubWindows && PluginSubWindows[n]; n++) + { + ti->ti_Tag = MUIA_Application_Window; + ti->ti_Data = (ULONG) PluginSubWindows[n]; + ti++; + } + + ti->ti_Tag = TAG_END; + + return SubWindowTagList; +} + + +static void DisposePrefsPlugin(void) +{ +#ifdef __amigaos4__ + if (IScalosPrefsPlugin) + { + DropInterface((struct Interface *)IScalosPrefsPlugin); + IScalosPrefsPlugin = NULL; + } +#endif + if (ScalosPrefsPluginBase) + { + d1(kprintf(__FUNC__ "/%ld: Plugin=<%s> OpenCount=%ld\n", \ + __LINE__, ScalosPrefsPluginBase->lib_Node.ln_Name, ScalosPrefsPluginBase->lib_OpenCnt)); + + if (NULL == Group_Plugin) + CloseLibrary(ScalosPrefsPluginBase); + ScalosPrefsPluginBase = NULL; + } +} + +static BOOL CheckMCCforPlugin(STRPTR *UsedClasses, size_t MaxUsedClasses) +{ + const struct MUIP_ScalosPrefs_MCCList *RequiredMccList = NULL; + + RequiredMccList = (const struct MUIP_ScalosPrefs_MCCList *) DoMethod(Group_Plugin, MUIM_ScalosPrefs_GetListOfMCCs); + + while (RequiredMccList && RequiredMccList->MccName) + { + if (!CheckMCCVersion(RequiredMccList->MccName, + RequiredMccList->MccMinVersion, + RequiredMccList->MccMinRevision)) + return FALSE; + + if (MaxUsedClasses > 1) + { + *UsedClasses++ = (STRPTR) RequiredMccList->MccName; + MaxUsedClasses--; + } + + RequiredMccList++; + } + + *UsedClasses = NULL; + + return TRUE; +} + +//---------------------------------------------------------------------------- + +// Checks if a certain version of a MCC is available +static BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev) +{ + BOOL flush = TRUE; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: %s ", name, __LINE__);) + + while (1) + { + ULONG ver = 0; + ULONG rev = 0; + struct Library *base; + char libname[256]; + + // First we attempt to acquire the version and revision through MUI + Object *obj = MUI_NewObject((STRPTR) name, TAG_DONE); + if (obj) + { + get(obj, MUIA_Version, &ver); + get(obj, MUIA_Revision, &rev); + + MUI_DisposeObject(obj); + + if(ver > minver || (ver == minver && rev >= minrev)) + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: v%ld.%ld found through MUIA_Version/Revision\n", __LINE__, ver, rev);) + return TRUE; + } + } + + // If we did't get the version we wanted, let's try to open the + // libraries ourselves and see what happens... + stccpy(libname, "PROGDIR:mui", sizeof(libname)); + AddPart(libname, name, sizeof(libname)); + + if ((base = OpenLibrary(&libname[8], 0)) || (base = OpenLibrary(&libname[0], 0))) + { + UWORD OpenCnt = base->lib_OpenCnt; + + ver = base->lib_Version; + rev = base->lib_Revision; + + CloseLibrary(base); + + // we add some additional check here so that eventual broken .mcc also have + // a chance to pass this test (i.e. Toolbar.mcc is broken) + if (ver > minver || (ver == minver && rev >= minrev)) + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: v%ld.%ld found through OpenLibrary()\n", __LINE__, ver, rev);) + return TRUE; + } + + if (OpenCnt > 1) + { + if (MUI_Request(NULL, NULL, 0L, GetLocString(MSGID_STARTUP_FAILURE), + GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), GetLocString(MSGID_STARTUP_MCC_IN_USE), + (ULONG) name, minver, minrev, ver, rev)) + { + flush = TRUE; + } + else + break; + } + + // Attempt to flush the library if open count is 0 or because the + // user wants to retry (meaning there's a chance that it's 0 now) + + if (flush) + { + struct Library *result; + + Forbid(); + if ((result = (struct Library *) FindName(&((struct ExecBase *)SysBase)->LibList, name))) + RemLibrary(result); + Permit(); + flush = FALSE; + } + else + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: couldn`t find minimum required version.\n", __LINE__);) + + // We're out of luck - open count is 0, we've tried to flush + // and still haven't got the version we want + if (MUI_Request(NULL, NULL, 0L, GetLocString(MSGID_STARTUP_FAILURE), + GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), GetLocString(MSGID_STARTUP_OLD_MCC), + (ULONG) name, minver, minrev, ver, rev)) + { + flush = TRUE; + } + else + break; + } + } + else + { + // No MCC at all - no need to attempt flush + flush = FALSE; + if (!MUI_Request(NULL, NULL, 0L, GetLocString(MSGID_STARTUP_FAILURE), + GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), GetLocString(MSGID_STARTUP_MCC_NOT_FOUND), + (ULONG) name, minver, minrev)) + { + break; + } + } + } + + return FALSE; +} + +//---------------------------------------------------------------------------- + +#if !defined(__SASC) && !defined(__amigaos4__) +// Replacement for SAS/C library functions + +#if !defined(__MORPHOS__) +// Replacement for SAS/C library functions + +size_t stccpy(char *dest, const char *src, size_t MaxLen) +{ + size_t Count = 0; + + while (*src && MaxLen > 1) + { + *dest++ = *src++; + MaxLen--; + Count++; + } + *dest = '\0'; + Count++; + + return Count; +} +#endif /*__MORPHOS__*/ + +#endif /* !defined(__SASC) && !defined(__amigaos4__) */ +//----------------------------------------------------------------------------- diff --git a/scalos/Prefs/Palette/ScalosPalette.cd b/scalos/Prefs/Palette/ScalosPalette.cd new file mode 100755 index 000000000..ea79ef929 --- /dev/null +++ b/scalos/Prefs/Palette/ScalosPalette.cd @@ -0,0 +1,418 @@ +; ScalosPalette.cd +; version $VER: ScalosPalette.catalog 40.11 (25 Dec 2008 10:09:16) +; codeset 0s +; language english +; +;#arrayopts static __far +; +; +; +MSGID_TITLENAME (//) +Scalos Palette Prefs Plugin +; +; +MSGID_NEW (//) +New +; +; +MSGID_DELETE (//) +Delete +; +; +MSGID_PEN (//) +Pen +; +; +MSGID_RED (//) +Red +; +; +MSGID_GREEN (//) +Green +; +; +MSGID_SAVENAME (//) +Save +; +; +MSGID_USENAME (//) +Use +; +; +MSGID_CANCELNAME (//) +Cancel +; +; +MSGID_BLUE (//) +Blue +; +; +MSGID_COMMANDNAME (//) +Palette +; +; +MSGID_IMPORTNAME (//) +Current WB Colours +; +; +MSGID_MENU_PROJECT_OPEN (//) +Open... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT (/1/1) +O +; +; +MSGID_MENU_PROJECT_SAVEAS (//) +Save As... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT (/1/1) +A +; +; +MSGID_MENU_PROJECT_QUIT (//) +Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT (/1/1) +Q +; +; +MSGID_MENU_PROJECT (//) +Project +; +; +MSGID_MENU_EDIT_LASTSAVED (//) +Last Saved +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT (/1/1) +L +; +; +MSGID_MENU_EDIT (//) +Edit +; +; +MSGID_MENU_SETTINGS_CREATEICONS (//) +Create Icons? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT (/1/1) +I +; +; +MSGID_MENU_SETTINGS (//) +Settings +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS (//) +Reset To Defaults +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT (/1/1) +D +; +; +MSGID_MENU_EDIT_RESTORE (//) +Restore +; +; +MSGID_MENU_EDIT_RESTORE_SHORT (/1/1) +R +; +; +MSGID_MENU_PROJECT_ABOUTMUI (//) +About MUI... +; +; +MSGID_WBCOLORS (+1//) +Workbench Colours +; +; +MSGID_TEXTPEN (+1//) +Text Pen +; +; +MSGID_SHINEPEN (//) +Bright Edges Pen +; +; +MSGID_SHADOWPEN (//) +Dark Edges Pen +; +; +MSGID_HIFILLPEN (//) +Active Window Title Bar Pen +; +; +MSGID_FILLTEXTPEN (//) +Active Window Titles Pen +; +; +MSGID_BGPEN (//) +Background Pen +; +; +MSGID_HITEXTPEN (//) +Important Text Pen +; +; +MSGID_BARDETAILPEN (//) +Menu Text Pen +; +; +MSGID_BARBLOCKPEN (//) +Menu Background Pen +; +; +MSGID_BARTRIMPEN (//) +Menu Border Pen +; +; +MSGID_HSHINEPEN (//) +Half-bright edges Pen +; +; +MSGID_HSHADOWPEN (//) +Half-dark edges Pen +; +; +MSGID_ICONTEXTPEN (//) +Icon Text Pen +; +; +MSGID_DRAWERTEXT (//) +Drawer Text Pen +; +; +MSGID_DRAWERTEXTSEL (//) +Drawer selected Text Pen +; +; +MSGID_DRAWERBG (//) +Drawer selected Background +; +; +MSGID_FILETEXT (//) +File Text Pen +; +; +MSGID_FILETEXTSEL (//) +File selected Text Pen +; +; +MSGID_FILEBG (//) +File selected Background +; +; +MSGID_PENNAMENAME (//) +Pen Name +; +; +MSGID_BACKDROPDETAIL (//) +Backdrop Detail Pen +; +; +MSGID_BACKDROPBLOCK (//) +Backdrop Block Pen +; +; +MSGID_MAINMENUNAME (//) +MainMenu +; +; +MSGID_MENU_PROJECT_ABOUT (+1//) +About... +; +; +MSGID_ABOUTREQOK (//) +_OK +; +; +MSGID_ABOUTREQFORMAT (//) +\033c\033bScalos Palette Preferences V%ld.%ld\033n\n\ +%s\n\ +© 1999%s The Scalos Team\n\ +Based on original code by Stefan Sommerfeld of ALiENDESiGN! +; +; +MSGID_TOOLTIP_TEXT (//) +Tooltip Text Pen +; +; +MSGID_TOOLTIP_BG (//) +Tooltip Background Pen +; +; +MSGID_DRAGINFO_TEXT (//) +Dragging Infotext Text Pen +; +; +MSGID_DRAGINFO_BG (//) +Dragging Infotext Background Pen +; +; +MSGID_STATUSBAR_BG (//) +Status Bar Background Pen +; +; +MSGID_STATUSBAR_TEXT (//) +Status Bar Text Pen +; +; +MSGID_REQTITLE_SAVEERROR (//) +Error writing palette preferences\n\ +file \"%s\"\n\ +%s +; +; +MSGID_REQTITLE_READERROR (//) +Error reading palette preferences\n\ +file \"%s\"\n\ +%s +; +; +MSGID_TITLE_SCALOSPENLIST (//) +Scalos item pens +; +; +MSGID_TITLE_PALETTEPENLIST (//) +Allocated Pens %ld/%ld +; +; +MSGID_SHORTHELP_SCALOSPENLIST (//) +This is the Scalos pen list.\n\ +Change pen assignments by dragging pens \n\ +from the allocated pens list onto the \n\ +entry you want to change. +; +; +MSGID_SHORTHELP_PALETTEPENLIST (//) +This is the list of all \n\ +pens allocated by Scalos.\n\ + \n\ +You can drag new pens from the \n\ +Workbench pen list into this list.\n\ + \n\ +Drag pens from here into the \n\ +Scalos pen list to assign colours \n\ +to specific Scalos items. +; +; +MSGID_SHORTHELP_WBPENLIST (//) +This is a list of all currently \n\ +used pens on the WorkBench screen.\n\ +You may drag one or more pens into \n\ +the list of Scalos allocated pens. +; +; +MSGID_SHORTHELP_SAVEBUTTON (//) +Press this button to save \n\ +the current settings to\n\ +\"ENVARC:Scalos/Palette13.prefs\"\n\ +and make changes permanent. +; +; +MSGID_SHORTHELP_USEBUTTON (//) +Press this button to save \n\ +the current settings to\n\ +\"ENV:Scalos/Palette13.prefs\"\n\ +and keep settings until reboot. +; +; +MSGID_SHORTHELP_CANCELBUTTON (//) +Press this button to abort \n\ +and forget all changes. +; +; +MSGID_SHORTHELP_NEWBUTTON (//) +Press this button to allocate \n\ +a new palette pen. \n\ +The button gets disabled when you try \n\ +to allocated more pens than available \n\ +for the Workbench screen. +; +; +MSGID_SHORTHELP_DELETEBUTTON (//) +Press this button to delete the \n\ +currently selected palette pen. +; +; +MSGID_SHORTHELP_WBPENSBUTTON (//) +This button opens a new window \n\ +with a list of all currently \n\ +used WorkBench screen colours. +; +; +MSGID_ICONTEXTPENSEL (//) +Selected Icon Text Pen +; +; +MSGID_ICONTEXTOUTLINEPEN (//) +Icon Text Outline Pen +; +; +MSGID_ICONTEXTSHADOWPEN (//) +Icon Text Shadow Pen +; +; new in 40.3 +; +MSGID_PLUGIN_LIST_TITLE (//) +Palette +; +; +MSGID_PEN_REFERENCE_COUNT (+2//) +Ref. +; +; new in 40.6 +; +MSGID_SHORTHELP_LAMP_CHANGED (//) +This lamp indicator changes from \033bOff\033n\n\ +to \033bOk\033n when the settings have been\n\ +modified since initial loading. +; +; +MSGID_ICONTEXTFILESELBG (//) +Selected Icon Text Rectangle Pen +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE (//) +Scalos Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD (//) +Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +; +; +MSGID_THUMBNAIL_BG (//) +Thumbnail background pen +; +; +MSGID_THUMBNAIL_BG_SEL (//) +Selected thumbnail background pen +; +;----------------------------------------------------------- +; diff --git a/scalos/Prefs/Palette/Scalos_Palette.info b/scalos/Prefs/Palette/Scalos_Palette.info new file mode 100755 index 0000000000000000000000000000000000000000..ddb3bbe225e9116699fb442a3e6c6697a589ef4e GIT binary patch literal 2399 zcwTi>Z%`9w8h42ifUavQ{;h**9 zteXT%X+Xg^a%b;GG|t@zXRhSp4EROz2Zb8{5UUov_DTeMcOU2kG|a@Z*}XSG=kCkB zyF2f@@9+0}o@bxu-De&L2uP1Vf%O2*TnIq0D*`omIk1^Wdol|fd=S1bvsY}IalqLD z{&x_oQ^p4N`Uk#M!;3F3IB@tV)Rb{g&92(2O4Ih5JsP5Zw~6?$mDo+aZTfkdvr%n) z%S7!l)fjix?yjnAFzrsmwYz?iK@qTH*IO1Cz+ck%4$5ePn_0!h(AE1j7U~TE_>X{! zk04q61K@opUoMT(;THfXgF%Fmq$j7u5Tp4(xTqtlbDsjjv_7E>RU>k%NuFb3g^V?` zNTDb-MnaZ#l|VY>2V(S1K3YdHaxAC&1wWx&A`wPTaa0#d zNnXBYgzb2aGs$OY4-heg-Xl_9U8APDapF`eAI%+u%7;$gPL*q?Dj~!Vc43UVyIyoUXwbwP}S;=<1^4UOs zvw2H2V+#8C^LN_r4g|45)q zSlTY6_*3i_CRp8|gCayRGzUa0ze$od*{ZR&4Ml@y-7tw*30Fhi*Xh!vuoET&=wK%UG=~M(HkZIy%`m9Ec(csk~yyS3Bc!W>jO_nF{?+{UISU^e6M6*;535%HD(AgdNg;$ z!DON0MZlw6E*4~e(?OZ8bj+5Ofmz@JfSngazPNCqyM=YLHSDi>vlPXu*(>Zsc1N5$ z65%?yxI4mq><+VB!I4O0aALNj$rS&W+--7y-cj#5Xz^pe&2K6J5x^c1)cYIC+-0l< ztp45T7oafxccYcy-4qzW5%B+R<-k_w3cpzyH8{T!Gs;DS6NuY&mjoD20=!zb*bKNV z04HK%Q_>J}@R@u`iAlVG>pB&5loMi-mT`rBQkgU?g^cM%LU(EBE3KV??}ktiQe)gC zA5s~Gq(lVOAYkMazz_=ap+-?M$;y~j@=|zQHQO14Ocm(|<-y=s3ix!8*>_E({X zK28s`F**owt@jhN+8a@)2@#F2AA24(Ca0b|c&spy)~2>B3?;~~EZgb4tSXQZ^Ylc( znc~Al1=g&n@`}zh%2)B2Ix(qI4<7zXSR zvuY6VoxH(G1m`%TNI%j5GnSENVb9ze|5#`R$F}ZGNjA4WE)hmh>-p=Ug8v=ro zO6h2DuXcH$=#Dt49593g*t3Xc*hizX#!GrSU@HSKNM3p417rA=q4^8KW>99_AnGO&yoor^}bQd6Hli^23(K zU^?+h{9<3aSpHt^axCv2b3#93Iey&I({ie*EmO7_>Cz2*x&6qt`1B1+*Nm`h#?tfA zsV2KKj9M64HP`vL2&&p z(m4Bl@E(SLOs)uHgn*Nx`7OUMU$zrY;T?dJ%c#8QZdn`sDS#G;-FJZHSg?LnD!ppiP~ftFQ82n;!#e /dev/null 2>&1 + +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(CSRCS:%.c=$(OBJDIR)/%.o) + +############################################################# + +NAME = .bin_os3/Scalos_Palette +NAMEDBG = $(NAME).debug +DESTTOOL = Scalos:Prefs/Scalos Palette +CAT_FILE = Scalos/ScalosPalette.catalog +CATCOMPHEADER = $(SCALOS_LOCALE) +DESTCAT = Locale:Catalogs +CATS = dansk \ + deutsch \ + español \ + français \ + italiano \ + svenska \ + ÃeÓtina + +ALLCATS = $(foreach cat,$(CATS),catalogs/$(cat)/$(CAT_FILE)) + +############################################################# + +# The default target (all) and what to really build + +all: $(NAME) $(NAMEDBG) \ + allcatalogs +# install +# clean +# launch + +############################################################# + +$(OBJDIR)/Palette.o : Palette.c $(SCALOS_LOCALE) + +$(CATCOMPHEADER) : ScalosPalette.cd + @printf '\033[32mMake CatComp header: \033[31m\033[1m$@ \033[32mfrom \033[31m$<\033[0m\n' + $(FLEXCAT) $(subst ../,/,$<) $@=$(SDPATH)/CatComp_h.sd + +############################################################# + +# CLI command used when linking the final executables +$(NAME) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LDLIBS) $(LDFLAGS) STRIPDEBUG + +$(NAMEDBG) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LDLIBS) $(LDFLAGS) ADDSYM + +############################################################# + +# commands generated a catalog (.catalog) from a catalog translation (.ct) file. +.ct.catalog: + $(CATCOMP) $*.cd $< CATALOG $*.catalog VB=1 + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $*.c objectname $@ + +$(OBJDIR)/%.o : %.s + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +$(OBJDIR)/%.o : %.asm + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +############################################################# + +# copy all generated file to their final destinations +install: + @printf '\033[32mInstall: \033[31m\033[1m$(NAME)\033[0m\n' + @copy $(NAME) "$(DESTTOOL)" + @printf '\033[32mInstall: \033[31m\033[1m$(CAT_FILE)\033[0m\n' + -@$(foreach cat,$(CATS),copy "catalogs/$(cat)/$(CAT_FILE)" "$(DESTCAT)/$(cat)/Scalos" clone;) + +############################################################ + +# make all Scalos preferences .catalogs +allcatalogs: + -@$(foreach cat,$(CATS),$(SUBDIRMAKE) catalogs/$(cat)/Scalos;) + +############################################################# + +# A little something to clean it all up +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + -@delete $(NAME) $(NAMEDBG) $(OBJS) $(CATCOMPHEADER) $(ALLCATS) + @printf '\033[0m' + +############################################################# + +nodebug: + -@$(SPLAT) -s -o "d2(" "d1(" "#?.c" + +############################################################# + diff --git a/scalos/Prefs/Palette/makefile-new b/scalos/Prefs/Palette/makefile-new new file mode 100755 index 000000000..5447bab99 --- /dev/null +++ b/scalos/Prefs/Palette/makefile-new @@ -0,0 +1,97 @@ +# $Date: 2011-08-06 19:37:48 +0200 (Sa, 06. Aug 2011) $ +# $Revision: 823 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../.. +endif + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + SDPATH=/ +else + SDPATH=../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(OBJDIR)/Palette.o + + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Subdirs +# + +SUBDIRS = $(filter-out Catalogs/sample/Scalos, $(wildcard Catalogs/*/Scalos)) + +############################################################################## +# +# Some lame deps + +$(OBJDIR)/Palette.o $(OBJDIR)/Palette.d : $(OBJDIR)/ScalosPalette_locale.h + +$(OBJDIR)/ScalosPalette_locale.h : ScalosPalette.cd + @$(ECHO) "FlexCat $@" + $(FLEXCAT) $< $@=$(SDPATH)/CatComp_h.sd + +############################################################################## +# +# Targets +# + +NAME = Scalos_Palette +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) \ + all_subdirs + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + @$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + copy $(BINDIR)/$(NAME) "Scalos:Prefs/Scalos Palette" clone + +install: install_subdirs + + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* \ + $(OBJDIR)/ScalosPalette_locale.h + +clean: clean_subdirs + +############################################################################## + + diff --git a/scalos/Prefs/Pattern/Catalogs/dansk/Scalos/ScalosPattern.ct b/scalos/Prefs/Pattern/Catalogs/dansk/Scalos/ScalosPattern.ct new file mode 100644 index 000000000..96f46e25d --- /dev/null +++ b/scalos/Prefs/Pattern/Catalogs/dansk/Scalos/ScalosPattern.ct @@ -0,0 +1,698 @@ +; ScalosPattern.ct +## version $VER: ScalosPattern.catalog 40.12 (15 May 2005 09:36:09) +## codeset 0 +## language dansk +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Pattern Prefs Plugin +; +; +MSGID_REGISTER_PATTERNLIST +Patternliste +; +; +MSGID_REMAPNAME +Ikke anpasse +; +; +MSGID_RENDERTYPE_TILED +Med fliser +; +; +MSGID_NEWNAME +Ny \033I[6:19] +; +; +MSGID_DELNAME +Slet +; +; +MSGID_SAVEBUTTON +Gem +; +; +MSGID_USEBUTTON +Brug +; +; +MSGID_CANCELBUTTON +Afbryd +; +; +MSGID_SCREENNAME +Workbench +; +; +MSGID_WINDOWNAME +Vindue +; +; +MSGID_MENU_PROJECT_OPEN +Åbn... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +Å +; +; +MSGID_MENU_PROJECT_SAVEAS +Gem som... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +G +; +; +MSGID_MENU_PROJECT_QUIT +Afslut +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +A +; +; +MSGID_MENU_PROJECT +Projekt +; +; +MSGID_MENU_EDIT_LASTSAVED +Sidst gemt +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +S +; +; +MSGID_MENU_EDIT +Editér +; +; +MSGID_MENU_SETTINGS_CREATEICONS +Opret ikoner? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +P +; +; +MSGID_MENU_SETTINGS +Indstillinger +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +Standardinstillinger +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +T +; +; +MSGID_MENU_EDIT_RESTORE +Restaurer +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +R +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Om MUI... +; +; +MSGID_RENDERTYPE_FITSIZE +Tilpas størrelse +; +; +MSGID_CENTEREDNAME +Centrer +; +; +MSGID_PRECEXACTNAME +Eksakt +; +; +MSGID_PRECIMAGENAME +Billede +; +; +MSGID_PRECICONNAME +Ikon +; +; +MSGID_PRECGUINAME +GUI +; +; +MSGID_PRECNAME +Pen præcision +; +; +MSGID_ENHANCNAME +brug GUIGfx +; +; +MSGID_NUMCOLSNAME +Farvevægtning +; +; +MSGID_ENHANCOPTSNAME +GUIGfx optioner +; +; +MSGID_AUTODITHERNAME +AutoDither +; +; +MSGID_DITHERMODENAME +Dithering: +; +; +MSGID_DITHERAMOUNTNAME +Dithermængde: +; +; +MSGID_DITHERMODE1NAME +Ingen +; +; +MSGID_DITHERMODE2NAME +Floyd-Steinberg +; +; +MSGID_DITHERMODE3NAME +Tilfældig +; +; +MSGID_PICTURENAME +Billede +; +; +MSGID_PATTERNNAME +Pattern +; +; +MSGID_REGISTER_DEFAULTS +Standardinstillinger +; +; +MSGID_DEFWBNAME +Desktop: +; +; +MSGID_DEFSCREENNAME +Skærm: +; +; +MSGID_DEFWINNAME +Vindue: +; +; +MSGID_ASYNCNAME +asynkron beregning: +; +; +MSGID_FRIENDNAME +brug friendbitmap; +; +; +MSGID_NONE_PRIORITY +ingen +; +; +MSGID_RELAYOUTNAME +altid beregnet på ny: +; +; +MSGID_RANDOMNAME +altid tilfældigt: +; +; +MSGID_TASKPRINAME +Prioritet af asynkron proces: +; +; +MSGID_TEXTNAME +Tekstmodus: +; +; +MSGID_CHECKMARKGADBUBBLE +Don't remap the colors\n\ +of the picture if set. +; +; +MSGID_CHECKMARKASYNCBUBBLE +Render the picture while reading\n\ +the icons instead of waiting for\n\ +the layout to finish before\n\ +opening the window if set. +; +; +MSGID_CHECKMARKFRIENDBUBBLE +Speed up the pattern refresh\n\ +by using a second bitmap if set.\n\ +This is ignored if you use\n\ +a V43 picture.datatype or\n\ +GUIGFX because they do it\n\ +themselves. +; +; +MSGID_CHECKMARKENHBUBBLE +The GUIGFX library gives you\n\ +some very fast routines e.g. for\n\ +colorreduction and dithering.\n\ +Use guigfx.library if set. +; +; +MSGID_CHECKMARKAUTODITHERBUBBLE +If set, dithering will be enabled\n\ +automatically if the picture would\n\ +loose too many pens. +; +; +MSGID_CHECKMARKRELAYOUTBUBBLE +Scales the picture again if you\n\ +change the window size if set. +; +; +MSGID_CHECKMARKRANDOMBUBBLE +Selects one of the random patterns\n\ +everytime you open a window instead\n\ +of randomizing the patterns only at\n\ +startup if set. +; +; +MSGID_SAVEBUTTONBUBBLE +Save settings and quit. +; +; +MSGID_USEBUTTONBUBBLE +Use settings and quit. +; +; +MSGID_CANCELBUTTONBUBBLE +Quit without saving. +; +; +MSGID_NUMBUTTONBUBBLE +The number assigns the pattern\n\ +to the Desktop, Screen, Window\n\ +and/or Textmode of the Defaults\n\ +page. +; +; +MSGID_PRECSLIDERBUBBLE +Select the precision of the\n\ +pens for the picture. +; +; +MSGID_COLORSSLIDERBUBBLE +How many free pens should\n\ +be used for the picture. +; +; +MSGID_CYCLEDITHERMODEBUBBLE +The routine that is used when\n\ +there is no free pen. In that\n\ +case a color is made of many\n\ +points with different colors\n\ +close to each other. +; +; +MSGID_SLIDERDITHERAMOUNTBUBBLE +A parameter for the dithering\n\ +routine. +; +; +MSGID_SLIDERWBBUBBLE +The number that should be used for\n\ +the Desktop pattern to get assigned.\n\ +A pattern with the assigned number\n\ +one and a one selected for Desktop\n\ +and Window means that the Window\n\ +and Desktop patterns should be that\n\ +pattern.\n\ +All patterns with the same\n\ +number are selected by random. +; +; +MSGID_SLIDERSCREENBUBBLE +The number that should be used for\n\ +the Screen pattern to get assigned.\n\ +A pattern with the assigned number\n\ +one and a one selected for Desktop\n\ +and Window means that the Window\n\ +and Desktop patterns should be that\n\ +pattern.\n\ +All patterns with the same\n\ +number are selected by random. +; +; +MSGID_SLIDERWINBUBBLE +The number that should be used for\n\ +the Window pattern to get assigned.\n\ +A pattern with the assigned number\n\ +one and a one selected for Desktop\n\ +and Window means that the Window\n\ +and Desktop patterns should be that\n\ +pattern.\n\ +All patterns with the same\n\ +number are selected by random. +; +; +MSGID_SLIDERTEXTBUBBLE +The number that should be used for\n\ +the Textmode pattern to get assigned.\n\ +A pattern with the assigned number\n\ +one and a one selected for Desktop\n\ +and Window means that the Window\n\ +and Desktop patterns should be that\n\ +pattern.\n\ +(Window Menu: View by >> Text)\n\ +All patterns with the same\n\ +number are selected by random. +; +; +MSGID_SLIDERTASKPRIBUBBLE +Task priority of the\n\ +asynclayout task. +; +; +MSGID_PREVIEWIMAGEBUBBLE +Click here to see\n\ +the selected picture. +; +; +MSGID_CYCLEGADBUBBLE +Do you want a pattern to be scaled\n\ +("Fit Size") or do you want a pattern\n\ +to be made of many instances of that\n\ +pattern put together like a mosiac\n\ +("Tiled") when resizing the window.\n\ +If you like to use "Fit Size" you have\n\ +to enable "use GUIGFX". +; +; +MSGID_MENU_PROJECT_ABOUT +Om... +; +; +MSGID_ABOUTREQOK +_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos pattern preferences V%ld.%ld\033n\n\ +%s\n\ +© 1999%s The Scalos Team\n\ +Based on original code by Stefan Sommerfeld of ALiENDESiGN!\n\ +Bubbles done by Crayor. +; +; +MSGID_COLUMNTITLE_1 +\33bNr. +; +; +MSGID_COLUMNTITLE_2 +\33bFile name +; +; +MSGID_SHORTHELP_NEWBUTTON +Press this button to create a \n\ +new pattern entry +; +; +MSGID_SHORTHELP_DELBUTTON +Press this button to delete the \n\ +currently selected pattern entry. +; +; +MSGID_SHORTHELP_SAVEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENVARC:Scalos/Pattern.prefs\". +; +; +MSGID_SHORTHELP_USEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENV:Scalos/Pattern.prefs\". +; +; +MSGID_SHORTHELP_CANCELBUTTON +Press this button to abort \n\ +and discard all changes. +; +; +MSGID_REQTITLE_SAVEERROR +Error writing pattern preferences\n\ +file \"%s\"\n\ +%s +; +; +MSGID_REQTITLE_READERROR +Error reading pattern preferences\n\ +file \"%s\"\n\ +%s +; +; new in 40.4 +; +MSGID_PLUGIN_LIST_TITLE +Pattern +; +; +MSGID_GROUP_MISCELLANEOUS +Vermischtes +;Miscellaneous +; +; +MSGID_GROUP_PATTERNNUMBERS +Hintergrundbilder-Nummern +;Pattern numbers +; +; +MSGID_MENU_ENABLE_PREVIEW +Show Preview? +; +; +MSGID_MENU_AUTO_PREVIEW +Auto Preview? +; +; new in 40.6 +; +; +++translateme+++ +MSGID_SHORTHELP_LAMP_CHANGED +This lamp indicator changes from \033bOff\033n\n\ +to \033bOk\033n when the settings have been\n\ +modified since initial loading. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +; new in 40.7 +; +MSGID_COLUMNTITLE_3 +\33bPreview +;\33bPreview +; +; +MSGID_CREATING_THUMBNAIL +\33cCreating Thumbnail for +;\33cCreating Thumbnail for +; +; +MSGID_LOADING_THUMBNAIL +\33cLoading Thumbnail for +;\33cLoading Thumbnail for +; +; +MSGID_PROGRESS_THUMBNAILS +\33c%ld/%ld +;\33c%ld/%ld +; +; +MSGID_WINDOW_STARTUP +Scalos PatternPrefs startup +;Scalos PatternPrefs startup +; +; +MSGID_STARTUP_CREATING +On initial start, thumbnails are created for every \ +pattern. Unfortunately this takes some time. \ +However, thumbnail bitmaps are saved together \ +with the standard pattern preferences.\n\ +After the thumbnails have been saved, \ +future startups will be \033bmuch faster\033n. +;On initial start, thumbnails are created for every \ +;pattern. Unfortunately this takes some time. \ +;However, thumbnail bitmaps are saved together \ +;with the standard pattern preferences.\n\ +;After the thumbnails have been saved, \ +;future startups will be \033bmuch faster\033n. +; +; +MSGID_MENU_ENABLE_THUMBNAILS +Display Thumbnails? +;Display Thumbnails? +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Scalos Pattern Prefs startup failed +;Scalos Pattern Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Try again|Quit +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_COLUMNTITLE_4 +\33bType +; +;----------------------------------------------------------- +; +MSGID_PATTERNTYPE_DESKTOP +DE +; +; +MSGID_PATTERNTYPE_SCREEN +SC +; +; +MSGID_PATTERNTYPE_ICONWINDOW +IW +; +; +MSGID_PATTERNTYPE_TEXTWINDOW +TW +; +; +MSGID_PATTERNTYPE_NONE + +; +;----------------------------------------------------------- +; +MSGID_MENU_RELOAD_THUMBNAILS +Reload Thumbnails +;Reload Thumbnails +; +; +MSGID_LOADING_THUMBNAILS +\033cLoading Thumbnails... +;\033cLoading Thumbnails... +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_REGISTER_BACKGROUNDCOLORS +Background Colours +;Background Colours +; +;+++translateme+++ +MSGID_BGTYPE_NONE +None +;None +; +;+++translateme+++ +MSGID_LABEL_CYCLEBACKGROUND +Background Type: +;Background Type: +; +;+++translateme+++ +MSGID_BGTYPE_SINGLECOLOR +Single Colour +;Single Colour +; +;+++translateme+++ +MSGID_BGTYPE_HOR_GRADIENT +Horizontal gradient +;Horizontal gradient +; +;+++translateme+++ +MSGID_BGTYPE_VERT_GRADIENT +Vertical gradient +;Vertical gradient +; +;+++translateme+++ +MSGID_SHORTHELP_BACKGROUNDCOLOR1 +Here you can adjust the window background color.\n\ +This is only possible with \033bcentered\033n and\n\ +\033bcolor-only\033n pattern type.\n\ +For \033bgradient\33n pattern types, you can\n\ +select the top (vertical gradient) or left (horizontal gradient) colour here. +;Here you can adjust the window background color.\n\ +;This is only possible with \033bcentered\033n and\n\ +;\033bcolor-only\033n pattern type.\n\ +;For \033bgradient\33n pattern types, you can\n\ +;select the top (vertical gradient) or left (horizontal gradient) colour here. +; +;+++translateme+++ +MSGID_SHORTHELP_BACKGROUNDCOLOR2 +Here you can adjust the secondary window background color.\n\ +For \033bgradient\33n pattern types, you can\n\ +select the bottom (vertical gradient) or right\n\ +(horizontal gradient) colour here. +;Here you can adjust the secondary window background color.\n\ +;For \033bgradient\33n pattern types, you can\n\ +;select the bottom (vertical gradient) or right\n\ +;(horizontal gradient) colour here. +; +;+++translateme+++ +MSGID_SHORTHELP_CYCLEBACKGROUND +This gadget selects the type of background that\n\ +is drawn besides the selected image.\n\ +It is selectable only in \033bCentered\033n mode because\n\ +in other modes, there is no room around the image where\n\ +the background color could be seen. +;This gadget selects the type of background that\n\ +;is drawn besides the selected image.\n\ +;It is selectable only in \033bCentered\033n mode because\n\ +;in other modes, there is no room around the image where\n\ +;the background color could be seen. +; +;+++translateme+++ +MSGID_SCALEDMINNAME +Proportionally Scaled (min) +;Proportionally Scaled (min) +; +;+++translateme+++ +MSGID_SCALEDMAXNAME +Proportionally Scaled (max) +;Proportionally Scaled (max) +; +;----------------------------------------------------------- +; diff --git a/scalos/Prefs/Pattern/Catalogs/dansk/Scalos/config.mk b/scalos/Prefs/Pattern/Catalogs/dansk/Scalos/config.mk new file mode 100755 index 000000000..bb98f9e35 --- /dev/null +++ b/scalos/Prefs/Pattern/Catalogs/dansk/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = dansk + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = danish + +else + +############################################################################### +# AmigaOS and AROS + +LANG = dansk + +endif +endif diff --git a/scalos/Prefs/Pattern/Catalogs/dansk/Scalos/makefile b/scalos/Prefs/Pattern/Catalogs/dansk/Scalos/makefile new file mode 100644 index 000000000..c8df747bc --- /dev/null +++ b/scalos/Prefs/Pattern/Catalogs/dansk/Scalos/makefile @@ -0,0 +1,13 @@ +# makefile for Scalos (translated Texts : dansk) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mdansk\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +ScalosPattern.catalog : ScalosPattern.ct ../../../ScalosPattern.cd + +All: ScalosPattern.catalog diff --git a/scalos/Prefs/Pattern/Catalogs/dansk/Scalos/makefile-new b/scalos/Prefs/Pattern/Catalogs/dansk/Scalos/makefile-new new file mode 100755 index 000000000..44b4a1ac1 --- /dev/null +++ b/scalos/Prefs/Pattern/Catalogs/dansk/Scalos/makefile-new @@ -0,0 +1,32 @@ +# makefile for ScalosPattern (translated Texts : dansk) +# $Date: 2011-08-06 19:37:48 +0200 (Sa, 06. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = ScalosPattern + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Prefs/Pattern/Catalogs/deutsch/Scalos/ScalosPattern.ct b/scalos/Prefs/Pattern/Catalogs/deutsch/Scalos/ScalosPattern.ct new file mode 100644 index 000000000..622826839 --- /dev/null +++ b/scalos/Prefs/Pattern/Catalogs/deutsch/Scalos/ScalosPattern.ct @@ -0,0 +1,718 @@ +; ScalosPattern.ct +## version $VER: ScalosPattern.catalog 40.12 (15 May 2005 09:36:09) +## codeset 0 +## language deutsch +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Muster Erweiterung +; +; +MSGID_REGISTER_PATTERNLIST +Hintergrundbilder-Liste +; +; +MSGID_REMAPNAME +Nicht optimieren: +; +; +MSGID_RENDERTYPE_TILED +gekachelt +; +; +MSGID_NEWNAME +Neu \033I[6:19] +; +; +MSGID_DELNAME +Löschen +; +; +MSGID_SAVEBUTTON +Speichern +; +; +MSGID_USEBUTTON +Benutzen +; +; +MSGID_CANCELBUTTON +Abbrechen +; +; +MSGID_SCREENNAME +Workbench +; +; +MSGID_WINDOWNAME +Fenster +; +; +MSGID_MENU_PROJECT_OPEN +Öffnen... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +Ö +; +; +MSGID_MENU_PROJECT_SAVEAS +Speichern als... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +S +; +; +MSGID_MENU_PROJECT_QUIT +Beenden +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +B +; +; +MSGID_MENU_PROJECT +Projekt +; +; +MSGID_MENU_EDIT_LASTSAVED +auf zuletzt gespeichertes +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +Z +; +; +MSGID_MENU_EDIT +Verändern +; +; +MSGID_MENU_SETTINGS_CREATEICONS +Piktogramme erzeugen? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +P +; +; +MSGID_MENU_SETTINGS +Einstellungen +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +auf Vorgaben zurücksetzen +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +Z +; +; +MSGID_MENU_EDIT_RESTORE +auf vorherigen Stand +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +V +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Über MUI... +; +; +MSGID_RENDERTYPE_FITSIZE +An Größe angepaßt +; +; +MSGID_CENTEREDNAME +zentriert +; +; +MSGID_PRECEXACTNAME +Exakt +; +; +MSGID_PRECIMAGENAME +Bild +; +; +MSGID_PRECICONNAME +Piktogramm +; +; +MSGID_PRECGUINAME +GUI +; +; +MSGID_PRECNAME +Stiftgenauigkeit: +; +; +MSGID_ENHANCNAME +benutze GUIGfx: +; +; +MSGID_NUMCOLSNAME +Farbgewichtung: +; +; +MSGID_ENHANCOPTSNAME +GUIGfx Optionen +; +; +MSGID_AUTODITHERNAME +Auto_Rasterung: +; +; +MSGID_DITHERMODENAME +Rasterung: +; +; +MSGID_DITHERAMOUNTNAME +Rasterungs-Stärke: +; +; +MSGID_DITHERMODE1NAME +Aus +; +; +MSGID_DITHERMODE2NAME +Floyd Steinberg +; +; +MSGID_DITHERMODE3NAME +Zufall +; +; +MSGID_PICTURENAME +Bild: +; +; +MSGID_PATTERNNAME +Pattern +; +; +MSGID_REGISTER_DEFAULTS +Voreinstellungen +; +; +MSGID_DEFWBNAME +Desktop: +; +; +MSGID_DEFSCREENNAME +Bildschirm: +; +; +MSGID_DEFWINNAME +Fenster: +; +; +MSGID_ASYNCNAME +asynchrones Berechnen: +; +; +MSGID_FRIENDNAME +benutze FriendBitMap: +; +; +MSGID_NONE_PRIORITY +aus +; +; +MSGID_RELAYOUTNAME +immer neuberechnen: +; +; +MSGID_RANDOMNAME +ständiger Zufall: +; +; +MSGID_TASKPRINAME +Priorität des asynchronen Tasks: +; +; +MSGID_TEXTNAME +Text-Modus: +; +; +MSGID_CHECKMARKGADBUBBLE +Wenn eingeschaltet, werden die Farben\n\ +des Bildes nicht angepaßt. +; +; +MSGID_CHECKMARKASYNCBUBBLE +Wenn eingeschaltet, wird das\n\ +Hintergrundbild während des Ladens\n\ +der Piktogramme gezeichnet, anstatt\n\ +zu warten, bis alle\n\ +Piktogramme geladen sind. +; +; +MSGID_CHECKMARKFRIENDBUBBLE +Beschleunigt das Neuzeichnen des\n\ +Hintergrundmusters durch Nutzung\n\ +einer zweiten BitMap.\n\ +Wird ignoriert, wenn ein V43 Datatype\n\ +oder GUIGFX genutzt werden. +; +; +MSGID_CHECKMARKENHBUBBLE +Die GUIGFX Bibliothek stellt einige sehr\n\ +schnelle Funktionen z.B. zur\n\ +Farbreduktion und zum Rastern zur\n\ +Verfügung.\n\ +Wenn eingeschaltet, wird\n\ +guigfx.library benutzt. +; +; +MSGID_CHECKMARKAUTODITHERBUBBLE +Wenn eingeschaltet, werden Bilder\n\ +automatisch gerastert, wenn nicht\n\ +genügend freie Stifte verfügbar sind. +; +; +MSGID_CHECKMARKRELAYOUTBUBBLE +Wenn eingeschaltet, wird bei\n\ +Größenänderung des Fensters das\n\ +Hintergrundbild neu skaliert. +; +; +MSGID_CHECKMARKRANDOMBUBBLE +Wenn eingeschaltet, wird jedesmal bei\n\ +Öffnen eines Fensters eines der\n\ +zufälligen Muster ausgewählt.\n\ +Wenn ausgeschaltet, werden die\n\ +zufällligen Muster einmal beim\n\ +Programmstart ausgewählt. +; +; +MSGID_SAVEBUTTONBUBBLE +Einstellungen speichern\n\ +und Programm beenden. +; +; +MSGID_USEBUTTONBUBBLE +Einstellungen benutzen\n\ +und Programm beenden. +; +; +MSGID_CANCELBUTTONBUBBLE +Drücken Sie diesen Knopf, um das\n\ +Programm abzubrechen und alle\n\ +Änderungen zu verwerfen. +; +; +MSGID_NUMBUTTONBUBBLE +Diese Nummer legt das Hintergrundbild\n\ +für die Arbeitsfläche, den Bildschirm\n\ +sowie Text-Fenster und\n\ +Piktogrammfenster auf der\n\ +Seite "Voreinstellungen" fest. +; +; +MSGID_PRECSLIDERBUBBLE +Legt die Genauigkeit der Stifte\n\ +für das Hintergrundbild fest. +; +; +MSGID_COLORSSLIDERBUBBLE +Wie viele Stifte sollen für das\n\ +Hintergrundbild maximal benutzt werden? +; +; +MSGID_CYCLEDITHERMODEBUBBLE +Die Methode, die benutzt wird, wenn\n\ +nicht genügend freie Stifte\n\ +vorhanden sind.\n\ +In diesem Fall wird das Bild gerastert,\n\ +d.h. eine Farbe wird durch mehrere\n\ +benachbarte Punkte angenähert. +; +; +MSGID_SLIDERDITHERAMOUNTBUBBLE +Ein Parameter für die\n\ +Raster-Routine. +; +; +MSGID_SLIDERWBBUBBLE +Diese Nummer legt das Hintergrundbild\n\ +für das Workbench Hintergrundfenster fest.\n\ +Aus mehreren Hintergrundbildern mit\n\ +derselben Nummer wird eines zufällig\n\ +ausgewählt. +; +; +MSGID_SLIDERSCREENBUBBLE +Diese Nummer legt das Hintergrundbild\n\ +für den Workbench-Bildschirm fest.\n\ +Aus mehreren Hintergrundbildern mit\n\ +derselben Nummer wird eines zufällig\n\ +ausgewählt. +; +; +MSGID_SLIDERWINBUBBLE +Diese Nummer legt das Hintergrundbild\n\ +für normale Workbench-Fenster mit\n\ +Piktogrammen fest.\n\ +Aus mehreren Hintergrundbildern mit\n\ +derselben Nummer wird eines zufällig\n\ +ausgewählt. +; +; +MSGID_SLIDERTEXTBUBBLE +Diese Nummer legt das Hintergrundbild\n\ +für normale Workbench-Fenster in\n\ +Textdarstellung fest.\n\ +Aus mehreren Hintergrundbildern mit\n\ +derselben Nummer wird eines zufällig\n\ +ausgewählt. +; +; +MSGID_SLIDERTASKPRIBUBBLE +Ausführungs-Priorität der\n\ +asynchronen Layout-Task. +; +; +MSGID_PREVIEWIMAGEBUBBLE +Hier klicken, um das\n\ +ausgewählte Bild zu sehen. +; +; +MSGID_CYCLEGADBUBBLE +Möchten Sie das Hintergrundbild auf die\n\ +volle Größe skalieren lassen ("Größe anpassen")\n\ +oder möchten Sie das Fenster mit\n\ +vielen "Kacheln" des Hintergrundbildes\n\ +neben- und untereinander füllen ("gekachelt") ?\n\ +\"Zentriert\" zeigt das gweählte Bild in Originalgröße\n\ +in Fenstermitte, umgeben von einem Rand mit\n\ +einstellbarer Farbe. +; +; +MSGID_MENU_PROJECT_ABOUT +Über... +; +; +MSGID_ABOUTREQOK +_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos Muster Voreinsteller V%ld.%ld\033n\n\ +%s\n\ +© 1999%s Das Scalos Team\n\ +Basiert auf Code von Stefan Sommerfeld bei ALiENDESiGN!\n\ +Hilfe-Blasen-Design von Crayor. +; +; +MSGID_COLUMNTITLE_1 +\33bNr. +; +; +MSGID_COLUMNTITLE_2 +\33bDateiname +; +; +MSGID_SHORTHELP_NEWBUTTON +Dieser Knopf legt einen neuen Eintrag\n\ +in der Liste der Hintergrundbilder an. +;Press this button to create a \n\ +;new pattern entry +; +; +MSGID_SHORTHELP_DELBUTTON +Dieser Knopf löscht den aktuell markierten\n\ +Eintrag in der Liste der Hintergrundbilder, +;Press this button to delete the \n\ +;currently selected pattern entry. +; +; +MSGID_SHORTHELP_SAVEBUTTON +Einstellungen dauerhaft\n\ +speichern und Programm beenden. +;Press this button to save \n\ +;the current settings to\n\ +;\"ENVARC:Scalos/Pattern.prefs\". +; +; +MSGID_SHORTHELP_USEBUTTON +Einstellungen benutzen\n\ +und Programm beenden. +;Press this button to save \n\ +;the current settings to\n\ +;\"ENV:Scalos/Pattern.prefs\". +; +; +MSGID_SHORTHELP_CANCELBUTTON +Drücken Sie diesen Knopf, um das\n\ +Programm abzubrechen und alle\n\ +Änderungen zu verwerfen. +;Press this button to abort \n\ +;and discard all changes. +; +; +MSGID_REQTITLE_SAVEERROR +Fehler beim Schreiben der Einstellungs-\n\ +Datei \"%s\"\n\ +%s +;Error writing pattern preferences\n\ +;file \"%s\"\n\ +;%s +; +; +MSGID_REQTITLE_READERROR +Fehler beim Lesen der Einstellungs-\n\ +Datei \"%s\"\n\ +%s +;Error reading pattern preferences\n\ +;file \"%s\"\n\ +;%s +; +; new in 40.4 +; +MSGID_PLUGIN_LIST_TITLE +Hintergrundbilder +;Pattern +; +; +MSGID_GROUP_MISCELLANEOUS +Vermischtes +;Miscellaneous +; +; +MSGID_GROUP_PATTERNNUMBERS +Hintergrundbilder-Nummern +;Pattern numbers +; +; +MSGID_MENU_ENABLE_PREVIEW +Vorschau zeigen? +;Show Preview? +; +; +MSGID_MENU_AUTO_PREVIEW +Automatische Vorschau? +;Auto Preview? +; +; new in 40.6 +; +MSGID_SHORTHELP_LAMP_CHANGED +Diese Anzeigelampe wechselt den Zustand von \033bAus\033n\n\ +nach \033bAn\033n, wenn die Konfiguration seit\n\ +dem ersten Laden verändert wurde. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +; new in 40.7 +; +MSGID_COLUMNTITLE_3 +\33bVorschau +;\33bPreview +; +; +MSGID_CREATING_THUMBNAIL +\33cErzeuge Miniatur-Vorschaubild für +;\33cCreating Thumbnail for +; +; +MSGID_LOADING_THUMBNAIL +\33cLade Miniatur-Vorschaubild für +;\33cLoading Thumbnail for +; +; +MSGID_PROGRESS_THUMBNAILS +\33c%ld/%ld +;\33c%ld/%ld +; +; +MSGID_WINDOW_STARTUP +Scalos Muster-Voreinsteller Start +;Scalos PatternPrefs startup +; +; +MSGID_STARTUP_CREATING +Beim ersten Programmstart wird eine Miniatur-Vorschau\n\ +for alle Hintergrundbilder berechnet.\n\ +Leider kann das auf langsameren Maschinen\n\ +eine Weile dauern.\n\ +Die berechneten Miniatur-Vorschaubilder werden\n\ +aber zusammen mit den anderen Einstellungen gespeichert.\n\ +Bei den nächsten Programmstarts werden die\n\ +gespeicherten Miniatur-Vorschaubilder geladen\n\ +und ermöglichen eine \033berheblich schnellere\033n Anzeige. +;On initial start, thumbnails are created for every \ +;pattern. Unfortunately this takes some time. \ +;However, thumbnail bitmaps are saved together \ +;with the standard pattern preferences.\n\ +;After the thumbnails have been saved, \ +;future startups will be \033bmuch faster\033n. +; +; +MSGID_MENU_ENABLE_THUMBNAILS +Miniaturvorschaubilder anzeigen? +;Display Thumbnails? +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Scalos Muster Voreinsteller kann nicht gestartet werden +;Scalos Pattern Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Wiederholen|Beenden +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\ +Die Klasse ist nicht installiert. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Sie haben momentan Version v%lu.%lu installiert und\n\ +sollten die Klasse daher aktualisieren! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Konnte die MUI Klasse '%s' v%lu.%lu nicht öffnen.\n\n\ +Version %lu.%lu wird momentan von einer anderen Anwendung\n\ +verwendet. Wenn sie die benötigte Version installiert haben,\n\ +schließen sie alle MUI Programme und probieren es erneut. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_COLUMNTITLE_4 +\33bTyp +; +;----------------------------------------------------------- +; +MSGID_PATTERNTYPE_DESKTOP +DE +; +; +MSGID_PATTERNTYPE_SCREEN +SC +; +; +MSGID_PATTERNTYPE_ICONWINDOW +IW +; +; +MSGID_PATTERNTYPE_TEXTWINDOW +TW +; +; +MSGID_PATTERNTYPE_NONE + +; +;----------------------------------------------------------- +; +MSGID_MENU_RELOAD_THUMBNAILS +Vorschaubilder neu laden +;Reload Thumbnails +; +; +MSGID_LOADING_THUMBNAILS +\033cVorschaubilder laden... +;\033cLoading Thumbnails... +; +;----------------------------------------------------------- +; +MSGID_REGISTER_BACKGROUNDCOLORS +Hintergrundfarben +;Background Colours +; +; +MSGID_BGTYPE_NONE +Keiner +;None +; +; +MSGID_LABEL_CYCLEBACKGROUND +Art des Hintergrunds +;Background Type: +; +; +MSGID_BGTYPE_SINGLECOLOR +Nur eine Farbe +;Single Colour +; +; +MSGID_BGTYPE_HOR_GRADIENT +Horizontaler Verlauf +;Horizontal gradient +; +; +MSGID_BGTYPE_VERT_GRADIENT +Vertikaler Verlauf +;Vertical gradient +; +; +; +MSGID_SHORTHELP_BACKGROUNDCOLOR1 +Hier wird die primäre Hintergrundfarbe eingestellt.\n\ +Das funktioniert nur bei \033bzentriertem\033n Bild sowie bei\n\ +den Varianten \033bNur Farbe\033n und den \033bFarbverläufen\033n.\n\ +Bei \033bhorizontalem Farbverlauf\033n wird hier die Farbe am linken\n\ +Fensterrand eingestellt, und bei \033bVertikalem Farbverlauf\033n\n\ + die Farbe am oberen Rand. +;Here you can adjust the window background color.\n\ +;This is only possible with \033bcentered\033n and\n\ +;\033bcolor-only\033n pattern type.\n\ +;For \033bgradient\33n pattern types, you can\n\ +;select the top (vertical gradient) or left (horizontal gradient) colour here. +; +; +MSGID_SHORTHELP_BACKGROUNDCOLOR2 +Hier wird die sekundäre Hintergrundfarbe eingestellt.\n\ +Das funktioniert nur bei den \033bFarbverläufen\033n.\n\ +Bei \033bhorizontalem Farbverlauf\033n wird hier die Farbe am rechten\n\ +Fensterrand eingestellt, und bei \033bVertikalem Farbverlauf\033n\n\ + die Farbe am unteren Rand. +;Here you can adjust the secondary window background color.\n\ +;For \033bgradient\33n pattern types, you can\n\ +;select the bottom (vertical gradient) or right\n\ +;(horizontal gradient) colour here. +; +; +MSGID_SHORTHELP_CYCLEBACKGROUND +Hier legen Sie fest, wie der Fensterhintergrund\n\ +rund um das gewählte Bild eingefärbt wird.\n\ +Es ist nur bei der Einstellung \033bzentriert\033n\n\ +wählbar, da in den anderen Modi kein sichtbarer Rand\n\ +rund um das Hintergrundbild vorhanden ist. +;This gadget selects the type of background that\n\ +;is drawn besides the selected image.\n\ +;It is selectable only in \033bCentered\033n mode because\n\ +;in other modes, there is no room around the image where\n\ +;the background color could be seen. +; +; +MSGID_SCALEDMINNAME +Proportional skaliert (min) +;Proportionally Scaled (min) +; +; +MSGID_SCALEDMAXNAME +Proportional skaliert (max) +;Proportionally Scaled (max) +; +;----------------------------------------------------------- +; diff --git a/scalos/Prefs/Pattern/Catalogs/deutsch/Scalos/config.mk b/scalos/Prefs/Pattern/Catalogs/deutsch/Scalos/config.mk new file mode 100755 index 000000000..8631b0623 --- /dev/null +++ b/scalos/Prefs/Pattern/Catalogs/deutsch/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = deutsch + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = german + +else + +############################################################################### +# AmigaOS and AROS + +LANG = deutsch + +endif +endif diff --git a/scalos/Prefs/Pattern/Catalogs/deutsch/Scalos/makefile b/scalos/Prefs/Pattern/Catalogs/deutsch/Scalos/makefile new file mode 100644 index 000000000..bfb5e3111 --- /dev/null +++ b/scalos/Prefs/Pattern/Catalogs/deutsch/Scalos/makefile @@ -0,0 +1,13 @@ +# makefile for Scalos (translated Texts : deutsch) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mdeutsch\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +ScalosPattern.catalog : ScalosPattern.ct ../../../ScalosPattern.cd + +All: ScalosPattern.catalog diff --git a/scalos/Prefs/Pattern/Catalogs/deutsch/Scalos/makefile-new b/scalos/Prefs/Pattern/Catalogs/deutsch/Scalos/makefile-new new file mode 100755 index 000000000..bad272576 --- /dev/null +++ b/scalos/Prefs/Pattern/Catalogs/deutsch/Scalos/makefile-new @@ -0,0 +1,32 @@ +# makefile for ScalosPattern (translated Texts : deutsch) +# $Date: 2011-08-06 19:37:48 +0200 (Sa, 06. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = ScalosPattern + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git "a/scalos/Prefs/Pattern/Catalogs/espa\303\261ol/scalos/ScalosPattern.ct" "b/scalos/Prefs/Pattern/Catalogs/espa\303\261ol/scalos/ScalosPattern.ct" new file mode 100644 index 000000000..c3d7dcdeb --- /dev/null +++ "b/scalos/Prefs/Pattern/Catalogs/espa\303\261ol/scalos/ScalosPattern.ct" @@ -0,0 +1,647 @@ +; ScalosPattern.ct +## version $VER: ScalosPattern.catalog 40.12 (15 May 2005 09:36:09) +## codeset 0 +## language español +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Plugin Patrones Scalos +; +; +MSGID_REGISTER_PATTERNLIST +Lista de patrones +; +; +MSGID_REMAPNAME +No remapear +; +; +MSGID_RENDERTYPE_TILED +Repetir +; +; +MSGID_NEWNAME +Nuevo \033I[6:19] +; +; +MSGID_DELNAME +Eliminar +; +; +MSGID_SAVEBUTTON +Guardar +; +; +MSGID_USEBUTTON +Usar +; +; +MSGID_CANCELBUTTON +Cancelar +; +; +MSGID_SCREENNAME +Workbench +; +; +MSGID_WINDOWNAME +Ventana +; +; +MSGID_MENU_PROJECT_OPEN +Abrir... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +B +; +; +MSGID_MENU_PROJECT_SAVEAS +Guardar como... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +G +; +; +MSGID_MENU_PROJECT_QUIT +Salir +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +S +; +; +MSGID_MENU_PROJECT +Proyecto +; +; +MSGID_MENU_EDIT_LASTSAVED +Último guardado +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +Ú +; +; +MSGID_MENU_EDIT +Editar +; +; +MSGID_MENU_SETTINGS_CREATEICONS +¿Crear icono? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +I +; +; +MSGID_MENU_SETTINGS +Valores +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +Predeterminados +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +P +; +; +MSGID_MENU_EDIT_RESTORE +Recuperar +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +C +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Acerca de MUI... +; +; +MSGID_RENDERTYPE_FITSIZE +Ajustar tamaño +; +; +MSGID_CENTEREDNAME +Centrado +; +; +MSGID_PRECEXACTNAME +Exacto +; +; +MSGID_PRECIMAGENAME +Imagen +; +; +MSGID_PRECICONNAME +Icono +; +; +MSGID_PRECGUINAME +GUI +; +; +MSGID_PRECNAME +Precisión de color: +; +; +MSGID_ENHANCNAME +Usar GUIGfx: +; +; +MSGID_NUMCOLSNAME +Peso de color: +; +; +MSGID_ENHANCOPTSNAME +Opciones GUIGfx +; +; +MSGID_AUTODITHERNAME +Autotramado +; +; +MSGID_DITHERMODENAME +Tramado: +; +; +MSGID_DITHERAMOUNTNAME +Cantidad de trama: +; +; +MSGID_DITHERMODE1NAME +Ninguno +; +; +MSGID_DITHERMODE2NAME +Floyd-Steinberg +; +; +MSGID_DITHERMODE3NAME +Aleatorio +; +; +MSGID_PICTURENAME +Imagen +; +; +MSGID_PATTERNNAME +Patrón +; +; +MSGID_REGISTER_DEFAULTS +Predeterminados +; +; +MSGID_DEFWBNAME +Escritorio: +; +; +MSGID_DEFSCREENNAME +Pantalla: +; +; +MSGID_DEFWINNAME +Ventana: +; +; +MSGID_ASYNCNAME +Cálculo asíncono: +; +; +MSGID_FRIENDNAME +Usar FriendBitmap: +; +; +MSGID_NONE_PRIORITY +Ninguno +; +; +MSGID_RELAYOUTNAME +Redibujar siempre: +; +; +MSGID_RANDOMNAME +Elegir cada vez: +; +; +MSGID_TASKPRINAME +Prioridad de la tarea: +; +; +MSGID_TEXTNAME +Modo texto: +; +; +MSGID_CHECKMARKGADBUBBLE +No remapear los colores +; +; +MSGID_CHECKMARKASYNCBUBBLE +Calcular la imagen mientras se leen los iconos\n\ +en lugar de esperar a que se muestren +; +; +MSGID_CHECKMARKFRIENDBUBBLE +Acelerar el refresco utilizando un segundo bitmap\n\ +Se ignora si utiliza picture.datatype V43\n\ +o GUIGfx, porque lo hacen automáticamente +; +; +MSGID_CHECKMARKENHBUBBLE +Usar la librería GUIGfx.\n\ +Proporciona rutinas muy rápidas para\n\ +reducción de color y tramado +; +; +MSGID_CHECKMARKAUTODITHERBUBBLE +Activar automáticamente el tramado si la\n\ +imagen va a perder muchos colores +; +; +MSGID_CHECKMARKRELAYOUTBUBBLE +Cambia el tamaño de la imagen cada vez\n\ +que se cambia el de la ventana +; +; +MSGID_CHECKMARKRANDOMBUBBLE +Para patrones con el mismo número,\n\ +elegirlos al azar cada vez que se abre\n\ +una ventana, en lugar de hacerlo sólo la\n\ +primera vez +; +; +MSGID_SAVEBUTTONBUBBLE +Guardar los valores y salir +; +; +MSGID_USEBUTTONBUBBLE +Usar los valores y salir +; +; +MSGID_CANCELBUTTONBUBBLE +Salir sin usar ni guardar los valores +; +; +MSGID_NUMBUTTONBUBBLE +El número asigna el patrón al escritorio, pantalla,\n\ +ventana y/o ventana en modo texto +; +; +MSGID_PRECSLIDERBUBBLE +Precisión del color para la imagen +; +; +MSGID_COLORSSLIDERBUBBLE +Cantidad de lápices libres que\n\ +deben utilizarse para la imagen +; +; +MSGID_CYCLEDITHERMODEBUBBLE +Rutina a seguir cuando no hay lápices\n\ +libres para la imagen. Entonces, se crea el color\n\ +con una trama de colores próximos +; +; +MSGID_SLIDERDITHERAMOUNTBUBBLE +Parámetro para la rutina de tramado +; +; +MSGID_SLIDERWBBUBBLE +El número del patrón para el escritorio. +; +; +MSGID_SLIDERSCREENBUBBLE +El número del patrón para la pantalla (no es visible\n\ +si Scalos está en pantalla completa) +; +; +MSGID_SLIDERWINBUBBLE +El número del patrón para las\n\ +ventanas que muestran iconos +; +; +MSGID_SLIDERTEXTBUBBLE +El número del patrón para las\n\ +ventanas que muestran texto +; +; +MSGID_SLIDERTASKPRIBUBBLE +Prioridad de la tarea asíncrona\n\ +que muestra los iconos +; +; +MSGID_PREVIEWIMAGEBUBBLE +Mostrar la imagen seleccionada +; +; +MSGID_CYCLEGADBUBBLE +El patrón puede repetirse en cuadrícula,\n\ +o estirarse, para que ocupe todo el\n\ +espacio disponible +; +; +MSGID_MENU_PROJECT_ABOUT +Acerca... +; +; +MSGID_ABOUTREQOK +_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos pattern preferences V%ld.%ld\033n\n\ +%s\n\ +© 1999%s The Scalos Team\n\ +Based on original code by Stefan Sommerfeld of ALiENDESiGN!\n\ +Bubbles done by Crayor. +; +; +MSGID_COLUMNTITLE_1 +\33bNr. +; +; +MSGID_COLUMNTITLE_2 +\33bFile name +; +; +MSGID_SHORTHELP_NEWBUTTON +Press this button to create a \n\ +new pattern entry +; +; +MSGID_SHORTHELP_DELBUTTON +Press this button to delete the \n\ +currently selected pattern entry. +; +; +MSGID_SHORTHELP_SAVEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENVARC:Scalos/Pattern.prefs\". +; +; +MSGID_SHORTHELP_USEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENV:Scalos/Pattern.prefs\". +; +; +MSGID_SHORTHELP_CANCELBUTTON +Press this button to abort \n\ +and discard all changes. +; +; +MSGID_REQTITLE_SAVEERROR +Error writing pattern preferences\n\ +file \"%s\"\n\ +%s +; +; +MSGID_REQTITLE_READERROR +Error reading pattern preferences\n\ +file \"%s\"\n\ +%s +; +; new in 40.4 +; +MSGID_PLUGIN_LIST_TITLE +Pattern +; +; +MSGID_GROUP_MISCELLANEOUS +Miscellaneous +; +; +MSGID_GROUP_PATTERNNUMBERS +Pattern numbers +; +; +MSGID_MENU_ENABLE_PREVIEW +Show Preview? +; +; +MSGID_MENU_AUTO_PREVIEW +Auto Preview? +; +; new in 40.6 +; +; +++translateme+++ +MSGID_SHORTHELP_LAMP_CHANGED +This lamp indicator changes from \033bOff\033n\n\ +to \033bOk\033n when the settings have been\n\ +modified since initial loading. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +; new in 40.7 +; +MSGID_COLUMNTITLE_3 +\33bPreview +;\33bPreview +; +; +MSGID_CREATING_THUMBNAIL +\33cCreating Thumbnail for +;\33cCreating Thumbnail for +; +; +MSGID_LOADING_THUMBNAIL +\33cLoading Thumbnail for +;\33cLoading Thumbnail for +; +; +MSGID_PROGRESS_THUMBNAILS +\33c%ld/%ld +;\33c%ld/%ld +; +; +MSGID_WINDOW_STARTUP +Scalos PatternPrefs startup +;Scalos PatternPrefs startup +; +; +MSGID_STARTUP_CREATING +On initial start, thumbnails are created for every \ +pattern. Unfortunately this takes some time. \ +However, thumbnail bitmaps are saved together \ +with the standard pattern preferences.\n\ +After the thumbnails have been saved, \ +future startups will be \033bmuch faster\033n. +;On initial start, thumbnails are created for every \ +;pattern. Unfortunately this takes some time. \ +;However, thumbnail bitmaps are saved together \ +;with the standard pattern preferences.\n\ +;After the thumbnails have been saved, \ +;future startups will be \033bmuch faster\033n. +; +; +MSGID_MENU_ENABLE_THUMBNAILS +Display Thumbnails? +;Display Thumbnails? +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Scalos Pattern Prefs startup failed +;Scalos Pattern Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Try again|Quit +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_COLUMNTITLE_4 +\33bType +; +;----------------------------------------------------------- +; +MSGID_PATTERNTYPE_DESKTOP +DE +; +; +MSGID_PATTERNTYPE_SCREEN +SC +; +; +MSGID_PATTERNTYPE_ICONWINDOW +IW +; +; +MSGID_PATTERNTYPE_TEXTWINDOW +TW +; +; +MSGID_PATTERNTYPE_NONE + +; +;----------------------------------------------------------- +; +MSGID_MENU_RELOAD_THUMBNAILS +Reload Thumbnails +;Reload Thumbnails +; +; +MSGID_LOADING_THUMBNAILS +\033cLoading Thumbnails... +;\033cLoading Thumbnails... +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_REGISTER_BACKGROUNDCOLORS +Background Colours +;Background Colours +; +;+++translateme+++ +MSGID_BGTYPE_NONE +None +;None +; +;+++translateme+++ +MSGID_LABEL_CYCLEBACKGROUND +Background Type: +;Background Type: +; +;+++translateme+++ +MSGID_BGTYPE_SINGLECOLOR +Single Colour +;Single Colour +; +;+++translateme+++ +MSGID_BGTYPE_HOR_GRADIENT +Horizontal gradient +;Horizontal gradient +; +;+++translateme+++ +MSGID_BGTYPE_VERT_GRADIENT +Vertical gradient +;Vertical gradient +; +;+++translateme+++ +MSGID_SHORTHELP_BACKGROUNDCOLOR1 +Here you can adjust the window background color.\n\ +This is only possible with \033bcentered\033n and\n\ +\033bcolor-only\033n pattern type.\n\ +For \033bgradient\33n pattern types, you can\n\ +select the top (vertical gradient) or left (horizontal gradient) colour here. +;Here you can adjust the window background color.\n\ +;This is only possible with \033bcentered\033n and\n\ +;\033bcolor-only\033n pattern type.\n\ +;For \033bgradient\33n pattern types, you can\n\ +;select the top (vertical gradient) or left (horizontal gradient) colour here. +; +;+++translateme+++ +MSGID_SHORTHELP_BACKGROUNDCOLOR2 +Here you can adjust the secondary window background color.\n\ +For \033bgradient\33n pattern types, you can\n\ +select the bottom (vertical gradient) or right\n\ +(horizontal gradient) colour here. +;Here you can adjust the secondary window background color.\n\ +;For \033bgradient\33n pattern types, you can\n\ +;select the bottom (vertical gradient) or right\n\ +;(horizontal gradient) colour here. +; +;+++translateme+++ +MSGID_SHORTHELP_CYCLEBACKGROUND +This gadget selects the type of background that\n\ +is drawn besides the selected image.\n\ +It is selectable only in \033bCentered\033n mode because\n\ +in other modes, there is no room around the image where\n\ +the background color could be seen. +;This gadget selects the type of background that\n\ +;is drawn besides the selected image.\n\ +;It is selectable only in \033bCentered\033n mode because\n\ +;in other modes, there is no room around the image where\n\ +;the background color could be seen. +; +;+++translateme+++ +MSGID_SCALEDMINNAME +Proportionally Scaled (min) +;Proportionally Scaled (min) +; +;+++translateme+++ +MSGID_SCALEDMAXNAME +Proportionally Scaled (max) +;Proportionally Scaled (max) +; +;----------------------------------------------------------- +; diff --git "a/scalos/Prefs/Pattern/Catalogs/espa\303\261ol/scalos/config.mk" "b/scalos/Prefs/Pattern/Catalogs/espa\303\261ol/scalos/config.mk" new file mode 100755 index 000000000..d0133689f --- /dev/null +++ "b/scalos/Prefs/Pattern/Catalogs/espa\303\261ol/scalos/config.mk" @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = español + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = spanish + +else + +############################################################################### +# AmigaOS and AROS + +LANG = español + +endif +endif diff --git "a/scalos/Prefs/Pattern/Catalogs/espa\303\261ol/scalos/makefile" "b/scalos/Prefs/Pattern/Catalogs/espa\303\261ol/scalos/makefile" new file mode 100644 index 000000000..f2524a266 --- /dev/null +++ "b/scalos/Prefs/Pattern/Catalogs/espa\303\261ol/scalos/makefile" @@ -0,0 +1,12 @@ +# makefile für Scalos (translated Texts : español) +# 01 Jan 2004 12:44:50 + +.SUFFIXES: .ct .catalog + +.ct.catalog : + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +ScalosPattern.catalog : ScalosPattern.ct ../../../ScalosPattern.cd + +All: ScalosPattern.catalog diff --git "a/scalos/Prefs/Pattern/Catalogs/espa\303\261ol/scalos/makefile-new" "b/scalos/Prefs/Pattern/Catalogs/espa\303\261ol/scalos/makefile-new" new file mode 100755 index 000000000..c5198b746 --- /dev/null +++ "b/scalos/Prefs/Pattern/Catalogs/espa\303\261ol/scalos/makefile-new" @@ -0,0 +1,32 @@ +# makefile for ScalosPattern (translated Texts : español) +# $Date: 2011-08-06 19:37:48 +0200 (Sa, 06. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = ScalosPattern + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git "a/scalos/Prefs/Pattern/Catalogs/fran\303\247ais/Scalos/ScalosPattern.ct" "b/scalos/Prefs/Pattern/Catalogs/fran\303\247ais/Scalos/ScalosPattern.ct" new file mode 100755 index 000000000..9593a7b88 --- /dev/null +++ "b/scalos/Prefs/Pattern/Catalogs/fran\303\247ais/Scalos/ScalosPattern.ct" @@ -0,0 +1,846 @@ +; ScalosPattern.ct +; $Date$ +; $Revision$ +; $Id$ +; +## version $VER: ScalosPattern.catalog 40.12 (08/02/06 23:59:19) +## codeset 0 +## language français +; +;#arrayopts static __far +; +; Translation done +; +; By COAT Jean-Marie ALIAS JMC +; E-Mail : agalliance@free.fr +; +; +MSGID_TITLENAME +Motif de Scalos +; Scalos Pattern +; +; +MSGID_REGISTER_PATTERNLIST +Liste des motifs +; Patternlist +; +; +MSGID_REMAPNAME +Ne pas recolorier : +; No remap: +; +; +MSGID_RENDERTYPE_TILED +Mosaïque +; Tiled +; +; +MSGID_NEWNAME +Nouveau \033I[6:19] +; New \033I[6:19] +; +; +MSGID_SHORTHELP_NEWBUTTON +Pressez ce bouton pour ajouter\n\ +un nouveau motif. +; Press this button to create a\n\ +; new pattern entry +; +; +MSGID_DELNAME +Effacer +; Delete +; +; +MSGID_SHORTHELP_DELBUTTON +Pressez ce bouton pour éffacer le\n\ +motif actuellement sélectionné. +; Press this button to delete the\n\ +; currently selected pattern entry. +; +; +MSGID_SAVEBUTTON +Sauver +; Save +; +; +MSGID_SHORTHELP_SAVEBUTTON +Pressez ce bouton afin de sauvegarder\n\ +les changements actuels vers\n\ +"\033bENVARC:Scalos/Pattern.prefs\033n". +; Press this button to save \n\ +; the current settings to\n\ +; \"ENVARC:Scalos/Pattern.prefs\". +; +; +MSGID_USEBUTTON +Utiliser +; Use +; +; +MSGID_SHORTHELP_USEBUTTON +Pressez ce bouton afin de sauvegarder\n\ +les changements actuels vers\n\ +"\033bENV:Scalos/Pattern.prefs\033n". +; Press this button to save \n\ +; the current settings to\n\ +; \"ENV:Scalos/Pattern.prefs\". +; +; +MSGID_CANCELBUTTON +Annuler +; Cancel +; +; +MSGID_SHORTHELP_CANCELBUTTON +Pressez ce bouton afin d'annuler\n\ +et d'oublier tous changements. +; Press this button to abort \n\ +; and discard all changes. +; +; +MSGID_SCREENNAME +Workbench +; Workbench +; +; +MSGID_WINDOWNAME +Fenêtre +; Window +; +; +MSGID_MENU_PROJECT_OPEN +Ouvrir... +; Open... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +O +; +; +MSGID_MENU_PROJECT_SAVEAS +Sauver en... +; Save As... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +S +; +; +MSGID_MENU_PROJECT_QUIT +Quitter +; Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +; +MSGID_MENU_PROJECT +Projet +; Project +; +; +MSGID_MENU_EDIT_LASTSAVED +Dernière sauvegarde +; Last Saved +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +D +; +; +MSGID_MENU_EDIT +Edition +; Edit +; +; +MSGID_MENU_SETTINGS_CREATEICONS +Créer une icône ? +; Create Icons? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +C +; +; +MSGID_MENU_SETTINGS +Options +; Settings +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +Réglages par défaut +; Reset To Defaults +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +A +; +; +MSGID_MENU_EDIT_RESTORE +Restaurer +; Restore +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +R +; +; +MSGID_MENU_PROJECT_ABOUTMUI +A propos de MUI... +; About MUI... +; +; +MSGID_RENDERTYPE_FITSIZE +Ajuster la taille +; Fit Size +; +; +MSGID_CENTEREDNAME +Centré +; Centered +; +; +MSGID_PRECEXACTNAME +Exacte +; Exact +; +; +MSGID_PRECIMAGENAME +Image +; Image +; +; +MSGID_PRECICONNAME +Icône +; Icon +; +; +MSGID_PRECGUINAME +GUI +; +; +MSGID_PRECNAME +Précision des couleurs : +; Pen Precision: +; +; +MSGID_ENHANCNAME +Utiliser GUIGfx : +; use GUIGfx: +; +; +MSGID_NUMCOLSNAME +Pourcentage: +; Color weight +; +; +MSGID_ENHANCOPTSNAME +Options GUIGfx +; GUIGfx Options +; +; +MSGID_AUTODITHERNAME +Filtre Auto : +; AutoDither +; +; +MSGID_DITHERMODENAME +Tramage : +; Dithering: +; +; +MSGID_DITHERAMOUNTNAME +Degré de tramage : +; Ditheramount: +; +; +MSGID_DITHERMODE1NAME +Aucun +; None +; +; +MSGID_DITHERMODE2NAME +Floyd Steinberg +; Floyd Steinberg +; +; +MSGID_DITHERMODE3NAME +Hasard +; Random +; +; +MSGID_PICTURENAME +Image : +; Picture: +; +; +MSGID_PATTERNNAME +Motif +; Pattern +; +; +MSGID_REGISTER_DEFAULTS +Configuration +; Defaults +; +; +MSGID_DEFWBNAME +Bureau : +; Desktop: +; +; +MSGID_DEFSCREENNAME +Ecran : +; Screen: +; +; +MSGID_DEFWINNAME +Fenêtre : +; Window: +; +; +MSGID_ASYNCNAME +Calculer en asyncrone : +; asynchronous layout: +; +; +MSGID_FRIENDNAME +Utiliser un second bitmap : +; use friend bitmap: +; +; +MSGID_NONE_PRIORITY +Aucune +; none +; +; +MSGID_RELAYOUTNAME +Toujours recalculer : +; always relayout: +; +; +MSGID_RANDOMNAME +Toujours au hasard : +; randomize everytime: +; +; +MSGID_TASKPRINAME +Priorité de la tâche asyncrone : +; Asynchronous Task priority: +; +; +MSGID_TEXTNAME +Mode texte : +; Text Mode: +; +; +MSGID_CHECKMARKGADBUBBLE +Ne retouche pas les couleurs\n\ +de l'image(si validé). +; Don't remap the colors\n\ +; of the picture if set. +; +; +MSGID_CHECKMARKASYNCBUBBLE +Affiche l'image de fond en même temps que\n\ +les icônes au lieu d'attendre la fin de leurs\n\ +tracés pour ouvrir la fenêtre(si validé). +; Render the picture while reading\n\ +; the icons instead of waiting for\n\ +; the layout to finish before\n\ +; opening the window if set. +; +; +MSGID_CHECKMARKFRIENDBUBBLE +Accélère le raffraichissement du motif\n\ +en utilisant un second bitmap(si validé).\n\ +Option ignorée si vous utilisez\n\ +le \033bpicture.datatype V43\033n ou \033bGuiGfx\033n,\n\ +car ils le font eux même. +; Speed up the pattern refresh\n\ +; by using a second bitmap if set.\n\ +; This is ignored if you use\n\ +; a V43 picture.datatype or\n\ +; GUIGFX because they do it\n\ +; themselves. +; +; +MSGID_CHECKMARKENHBUBBLE +La librairie \033bGuiGfx\033n vous offre des\n\ +routines trés rapides pour, par exemple,\n\ +la réduction de couleur et le tramage.\n\ +Utilise la \033bGuiGfx.library\033n(si validé). +; The GUIGFX library gives you\n\ +; some very fast routines e.g. for\n\ +; colorreduction and dithering.\n\ +; Use guigfx.library if set. +; +; +MSGID_CHECKMARKAUTODITHERBUBBLE +Le tramage sera utilisé\n\ +automatiquement si l'image doit\n\ +perdre trop de couleurs(si validé). +; If set, dithering will be enabled\n\ +; automatically if the picture would\n\ +; loose too many pens. +; +; +MSGID_CHECKMARKRELAYOUTBUBBLE +Remet à l'échelle l'image de fond si vous\n\ +changez la taille de la fenêtre(si validé). +; Scales the picture again if you\n\ +; change the window size if set. +; +; +MSGID_CHECKMARKRANDOMBUBBLE +Choisit au hasard un des motifs, chaque\n\ +fois que vous ouvrez une fenêtre, au\n\ +lieu de faire un choix unique\n\ +au départ(si validé). +; Selects one of the random patterns\n\ +; everytime you open a window instead\n\ +; of randomizing the patterns only at\n\ +; startup if set. +; +; +MSGID_SAVEBUTTONBUBBLE +Sauver les réglages et quitter. +; Save settings and quit. +; +; +MSGID_USEBUTTONBUBBLE +Utiliser les réglages et quitter. +; Use settings and quit. +; +; +MSGID_CANCELBUTTONBUBBLE +Quitter sans rien sauver. +; Quit without saving. +; +; +MSGID_NUMBUTTONBUBBLE +Le chiffre assigne le motif aux\n\ +bureau, écran, fenêtre et/ou au mode\n\ +de texte. Voir page "\033bConfiguration\033n". +; The number assigns the pattern\n\ +; to the Desktop, Screen, Window\n\ +; and/or Textmode of the Defaults\n\ +; page. +; +; +MSGID_PRECSLIDERBUBBLE +Choisissez la précision des\n\ +couleurs pour l'image. +; Select the precision of the\n\ +; pens for the picture. +; +; +MSGID_COLORSSLIDERBUBBLE +Pourcentage des couleurs pouvant\n\ +être utilisé pour l'image. +; How many free pens should\n\ +; be used for the picture. +; +; +MSGID_CYCLEDITHERMODEBUBBLE +Routine utilisée quand il n'y a plus\n\ +de couleur disponible. Dans ce cas, une\n\ +couleur est faite de plusieurs points de\n\ +différentes couleurs pour se rapprocher\n\ +au maximum du résultat voulu. +; The routine that is used when\n\ +; there is no free pen. In that\n\ +; case a color is made of many\n\ +; points with different colors\n\ +; close to each other. +; +; +MSGID_SLIDERDITHERAMOUNTBUBBLE +Paramètre pour la routine de tramage. +; A parameter for the dithering\n\ +; routine. +; +; +MSGID_SLIDERWBBUBBLE +Chiffre indiquant que le motif est assigné\n\ +au \033bbureau\033n. Un même motif peut\n\ +servir pour le bureau et les fenêtres.\n\ +Tous les motifs portant le même numéro\n\ +seront choisis aléatoirement. +; The number that should be used for\n\ +; the Desktop pattern to get assigned.\n\ +; A pattern with the assigned number\n\ +; one and a one selected for Desktop\n\ +; and Window means that the Window\n\ +; and Desktop patterns should be that\n\ +; pattern.\n\ +; All patterns with the same\n\ +; number are selected by random. +; +; +MSGID_SLIDERSCREENBUBBLE +Chiffre indiquant que le motif est assigné\n\ +à l'\033bécran\033n. Un même motif peut\n\ +servir pour le bureau et les fenêtres.\n\ +Tous les motifs portant le même numéro\n\ +seront choisis aléatoirement. +; The number that should be used for\n\ +; the Screen pattern to get assigned.\n\ +; A pattern with the assigned number\n\ +; one and a one selected for Desktop\n\ +; and Window means that the Window\n\ +; and Desktop patterns should be that\n\ +; pattern.\n\ +; All patterns with the same\n\ +; number are selected by random. +; +; +MSGID_SLIDERWINBUBBLE +Chiffre indiquant que le motif est assigné\n\ +aux fenêtres avec affichage \033bpar icônes\033n.\n\ +Un même motif peut servir pour le bureau et les fenêtres.\n\ +Tous les motifs portant le même numéro\n\ +seront choisis aléatoirement. +; The number that should be used for\n\ +; the Window pattern to get assigned.\n\ +; A pattern with the assigned number\n\ +; one and a one selected for Desktop\n\ +; and Window means that the Window\n\ +; and Desktop patterns should be that\n\ +; pattern.\n\ +; All patterns with the same\n\ +; number are selected by random. +; +; +MSGID_SLIDERTEXTBUBBLE +Chiffre indiquant que le motif est assigné\n\ +aux fenêtres avec affichage en \033bmode texte\033n.\n\ +Un même motif peut servir pour le bureau et les fenêtres.\n\ +Tous les motifs portant le même numéro\n\ +seront choisis aléatoirement. +; The number that should be used for\n\ +; the Textmode pattern to get assigned.\n\ +; A pattern with the assigned number\n\ +; one and a one selected for Desktop\n\ +; and Window means that the Window\n\ +; and Desktop patterns should be that\n\ +; pattern.\n\ +; (Window Menu: View by >> Text)\n\ +; All patterns with the same\n\ +; number are selected by random. +; +; +MSGID_SLIDERTASKPRIBUBBLE +Priorité de la tâche asyncrone. +; Task priority of the\n\ +; asynclayout task. +; +; +MSGID_PREVIEWIMAGEBUBBLE +Cliquez ici pour voir\n\ +l'image choisie. +; Click here to see\n\ +; the selected picture. +; +; +MSGID_CYCLEGADBUBBLE +\033bMosaïque\033n :\n\ +Création de l'image de la fenêtre\n\ +par assemblage multiple de ce motif.\n\ +\033bAjuster la taille\033n :\n\ +La taille du motif sera ajuster\n\ +en fonction de la taille de la fenêtre.\n\ +\033uNote\033n :\n\ +Si vous choisissez "Ajuster la taille",\n\ +vous devez activer "Utiliser GUIGfx". +; Do you want a pattern to be scaled\n\ +; (\"Fit Size\") or do you want a pattern\n\ +; to be made of many instances of that\n\ +; pattern put together like a mosiac\n\ +; (\"Tiled\") when resizing the window.\n\ +; If you like to use \"Fit Size\" you have\n\ +; to enable \"use GUIGFX\". +; +; +MSGID_MENU_PROJECT_ABOUT +A propos... +; About... +; +; +MSGID_ABOUTREQOK +D'accord +; _OK +; +; +MSGID_ABOUTREQFORMAT +\033cPréférences : \033bScalos Pattern V\0333%ld\0332.\0333%ld\0332\033n\n\ +Compilé sous: \0333%s\0332\n\ +\033b© 1999%s \0333The Scalos Team\033n\0332\n\ +Inspiré du programme original créé par\n\ +\033bStefan Sommerfeld\033n de \033b\0333ALiENDESiGN!\033n\0332\n\ +\033iBulles par \033bCrayor\033n. +; \33cScalos pattern preferences V40.2\n\ +; © 1999-2002 The Scalos Team\n\ +; Based on original code by Stefan Sommerfeld of ALiENDESiGN!\n\ +; Bubbles done by Crayor. +; +; +MSGID_COLUMNTITLE_1 +\033bN°. +; \33bNr. +; +; +MSGID_COLUMNTITLE_2 +\033bNom du fichier +; \33bFile name +; +; +MSGID_REQTITLE_SAVEERROR +Erreur durant l'écriture du fichier\n\ +des préférences : "%s"\n\ +%s +; Error writing pattern preferences\n\ +; file \"%s\"\n\ +; %s +; +; +MSGID_REQTITLE_READERROR +Erreur durant le chargement du fichier\n\ +des préférences : "%s"\n\ +%s +; Error reading pattern preferences\n\ +; file \"%s\"\n\ +; %s +; +; new in 40.4 +; +MSGID_PLUGIN_LIST_TITLE +Motifs de fond +;Pattern +; +; +MSGID_GROUP_MISCELLANEOUS +Divers +;Miscellaneous +; +; +MSGID_GROUP_PATTERNNUMBERS +Nombre de motifs +;Pattern numbers +; +; +MSGID_MENU_ENABLE_PREVIEW +Visualiser un aperçu ? +;Show Preview? +; +; +MSGID_MENU_AUTO_PREVIEW +Aperçu automatique ? +;Auto Preview? +; +; New in 40.6 +; +MSGID_SHORTHELP_LAMP_CHANGED +Cet indicateur passe de l'état \033binactif\033n\n\ +à l'état \033bactif\033n, une fois que les options\n\ +ont été modifiées depuis le chargement initial. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +; ** new in 40.7 +; +MSGID_COLUMNTITLE_3 +\33bAperçu +;\33bPreview +; +; +MSGID_CREATING_THUMBNAIL +\33cCréation d'une vignette pour +;\33cCreating Thumbnail for +; +; +MSGID_LOADING_THUMBNAIL +\33cChargement d'une vignette pour +;\33cLoading Thumbnail for +; +; +MSGID_PROGRESS_THUMBNAILS +\33c%ld/%ld +;\33c%ld/%ld +; +; +MSGID_WINDOW_STARTUP +Préférences des motifs de Scalos +;Scalos PatternPrefs startup +; +; +MSGID_STARTUP_CREATING +Au lancement, les vignettes sont créées pour tous \ +les motifs. Maleureusement cette opération prend du temps. \ +Toutefois, les données des vignettes sont sauvegardées \ +avec les préférences du programme.\n\ +Aprés que les vignettes soient sauvegardées, \ +les prochains lancement seront \033bplus rapides\033n. +;On initial start, thumbnails are created for every \ +;pattern. Unfortunately this takes some time. \ +;However, thumbnail bitmaps are saved together \ +;with the standard pattern preferences.\n\ +;After the thumbnails have been saved, \ +;future startups will be \033bmuch faster\033n. +; +; +MSGID_MENU_ENABLE_THUMBNAILS +Afficher les vignettes ? +;Display Thumbnails? +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Le lancement de Scalos Prefs a échoué +;Scalos Pattern Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Recommençer|Quitter +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +Celle-ci n'est pas installée. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +\n\ +La version installée est V%lu.%lu, installez-en une plus récente s'il vous plaît ! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Impossible de charger la classe MUI '%s' V%lu.%lu.\n\ +%lu.%lu est actuellement utilisée par d'autres applications.\n\ +\n\ +Une fois la version requise installée,\n\ +fermez tous les programmes MUI, soyez sûr que l'ancienne classe\n\ +ne soit plus présente dans la mémoire puis, essayez de nouveau. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_COLUMNTITLE_4 +\033bType +;\033bType +; +MSGID_PATTERNTYPE_DESKTOP +\0333BUREAU +;DE +; +MSGID_PATTERNTYPE_SCREEN +\0333ECRAN +;SC +; +MSGID_PATTERNTYPE_ICONWINDOW +\0333F-ICONE +;IW +; +MSGID_PATTERNTYPE_TEXTWINDOW +\0333F-TEXTE +;TW +; +MSGID_PATTERNTYPE_NONE +\0333\033c- +; +;----------------------------------------------------------- +; +MSGID_MENU_RELOAD_THUMBNAILS +Recharger les vignettes +;Reload Thumbnails +; +MSGID_LOADING_THUMBNAILS +\033cChargement des vignettes... +;\033cLoading Thumbnails... +; +;----------------------------------------------------------- +; +MSGID_REGISTER_BACKGROUNDCOLORS +Couleurs d'arrière-plan +;Background Colours +; +MSGID_BGTYPE_NONE +Rien +;None +; +MSGID_LABEL_CYCLEBACKGROUND +Type d'arrière plan : +;Background Type: +; +MSGID_BGTYPE_SINGLECOLOR +Simple couleur +;Single Colour +; +MSGID_BGTYPE_HOR_GRADIENT +Dégradé horizontal +;Horizontal gradient +; +MSGID_BGTYPE_VERT_GRADIENT +Dégradé vertical +;Vertical gradient +; +MSGID_SHORTHELP_BACKGROUNDCOLOR1 +Ici vous pouvez ajuster la couleur d'arrière-paln.\n\ +ceci n'est possible qu'avec le mode \033bCentré\033n et\n\ +le type de motif : \033bCouleur seulement\033n.\n\ +Pour les types de motif \033bdégradés\33n, vous pouvez\n\ +choisir ici, la couleur du haut(dégradé vertical) ou celle\n\ +de la gauche (dégradé horizontal). +;Here you can adjust the window background color.\n\ +;This is only possible with \033bcentered\033n and\n\ +;\033bcolor-only\033n pattern type.\n\ +;For \033bgradient\33n pattern types, you can\n\ +;select the top (vertical gradient) or left (horizontal gradient) colour here. +; +MSGID_SHORTHELP_BACKGROUNDCOLOR2 +Ici vous pouvez ajuster la seconde couleur de l'arrière-plan.\n\ +Pour les types de motif \033bdégradés\33n, vous pouvez\n\ +choisir ici, la couleur du bas(dégradé vertical) ou celle\n\ +de la droite(dégradé horizontal). +;Here you can adjust the secondary window background color.\n\ +;For \033bgradient\33n pattern types, you can\n\ +;select the bottom (vertical gradient) or right\n\ +;(horizontal gradient) colour here. +; +MSGID_SHORTHELP_CYCLEBACKGROUND +Ce gadget sélectionne le type d'arrière-plan\n\ +qui sera tracé autour de l'image choisie.\n\ +Cette option n'est disponible qu'avec le mode \033bCentré\033n car,\n\ +dans les autres modes, il n'y a aucun espace libre autour de l'image\n\ +où la couleur d'arrière-plan peut être visible. +;This gadget selects the type of background that\n\ +;is drawn besides the selected image.\n\ +;It is selectable only in \033bCentered\033n mode because\n\ +;in other modes, there is no room around the image where\n\ +;the background color could be seen. +; +MSGID_SCALEDMINNAME +Echelle proportionnelle (Min) +;Proportionally Scaled (min) +; +MSGID_SCALEDMAXNAME +Echelle proportionnelle (Max) +;Proportionally Scaled (max) +; +;----------------------------------------------------------- +; diff --git "a/scalos/Prefs/Pattern/Catalogs/fran\303\247ais/Scalos/config.mk" "b/scalos/Prefs/Pattern/Catalogs/fran\303\247ais/Scalos/config.mk" new file mode 100755 index 000000000..8b7056423 --- /dev/null +++ "b/scalos/Prefs/Pattern/Catalogs/fran\303\247ais/Scalos/config.mk" @@ -0,0 +1,40 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = français + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = french + +else + +############################################################################### +# AmigaOS and AROS + +LANG = français + +endif +endif diff --git "a/scalos/Prefs/Pattern/Catalogs/fran\303\247ais/Scalos/makefile" "b/scalos/Prefs/Pattern/Catalogs/fran\303\247ais/Scalos/makefile" new file mode 100644 index 000000000..dadc75299 --- /dev/null +++ "b/scalos/Prefs/Pattern/Catalogs/fran\303\247ais/Scalos/makefile" @@ -0,0 +1,13 @@ +# makefile for Scalos (translated Texts : français) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mfrançais\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +ScalosPattern.catalog : ScalosPattern.ct ../../../ScalosPattern.cd + +All: ScalosPattern.catalog diff --git "a/scalos/Prefs/Pattern/Catalogs/fran\303\247ais/Scalos/makefile-new" "b/scalos/Prefs/Pattern/Catalogs/fran\303\247ais/Scalos/makefile-new" new file mode 100755 index 000000000..11adfa594 --- /dev/null +++ "b/scalos/Prefs/Pattern/Catalogs/fran\303\247ais/Scalos/makefile-new" @@ -0,0 +1,32 @@ +# makefile for ScalosPattern (translated Texts : français) +# $Date: 2011-08-06 19:37:48 +0200 (Sa, 06. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = ScalosPattern + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Prefs/Pattern/Catalogs/italiano/Scalos/ScalosPattern.ct b/scalos/Prefs/Pattern/Catalogs/italiano/Scalos/ScalosPattern.ct new file mode 100644 index 000000000..1f27e06c6 --- /dev/null +++ b/scalos/Prefs/Pattern/Catalogs/italiano/Scalos/ScalosPattern.ct @@ -0,0 +1,684 @@ +; ScalosPattern.ct +## version $VER: ScalosPattern.catalog 40.12 (15 May 2005 09:36:09) +## codeset 0 +## language italiano +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos: scelta motivi Plugin +; +; +MSGID_REGISTER_PATTERNLIST +Lista dei motivi +; +; +MSGID_REMAPNAME +Non rimappare +; +; +MSGID_RENDERTYPE_TILED +Tessera +; +; +MSGID_NEWNAME +Nuovo \033I[6:19] +; +; +MSGID_DELNAME +Cancella +; +; +MSGID_SAVEBUTTON +Salva +; +; +MSGID_USEBUTTON +Usa +; +; +MSGID_CANCELBUTTON +Annulla +; +; +MSGID_SCREENNAME +Workbench +; +; +MSGID_WINDOWNAME +Finestra +; +; +MSGID_MENU_PROJECT_OPEN +Apri... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +A +; +; +MSGID_MENU_PROJECT_SAVEAS +Salva come... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +S +; +; +MSGID_MENU_PROJECT_QUIT +Fine +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +F +; +; +MSGID_MENU_PROJECT +Progetto +; +; +MSGID_MENU_EDIT_LASTSAVED +Ripristina ultimi valori +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +R +; +; +MSGID_MENU_EDIT +Modifica +; +; +MSGID_MENU_SETTINGS_CREATEICONS +Crea icone? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +C +; +; +MSGID_MENU_SETTINGS +Opzioni +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +Ripristina predefiniti +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +I +; +; +MSGID_MENU_EDIT_RESTORE +Annulla modifiche +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +N +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Info su MUI... +; +; +MSGID_RENDERTYPE_FITSIZE +Aggiusta dimensioni +; +; +MSGID_CENTEREDNAME +Centrato +; +; +MSGID_PRECEXACTNAME +Preciso +; +; +MSGID_PRECIMAGENAME +Immagine +; +; +MSGID_PRECICONNAME +Icona +; +; +MSGID_PRECGUINAME +GUI +; +; +MSGID_PRECNAME +Precisione colori: +; +; +MSGID_ENHANCNAME +Usa GUIGfx: +; +; +MSGID_NUMCOLSNAME +% colori +; +; +MSGID_ENHANCOPTSNAME +Opzioni GUIGfx +; +; +MSGID_AUTODITHERNAME +Retinatura automatica +; +; +MSGID_DITHERMODENAME +Retinatura: +; +; +MSGID_DITHERAMOUNTNAME +Densità retinatura +; +; +MSGID_DITHERMODE1NAME +Nessuna +; +; +MSGID_DITHERMODE2NAME +Floyd-Steinberg +; +; +MSGID_DITHERMODE3NAME +Casuale +; +; +MSGID_PICTURENAME +Immagine: +; +; +MSGID_PATTERNNAME +Motivo +; +; +MSGID_REGISTER_DEFAULTS +Impostazioni +; +; +MSGID_DEFWBNAME +Desktop: +; +; +MSGID_DEFSCREENNAME +Schermo: +; +; +MSGID_DEFWINNAME +Finestra: +; +; +MSGID_ASYNCNAME +Adattamento asincrono +; +; +MSGID_FRIENDNAME +Usa doppia bitmap: +; +; +MSGID_NONE_PRIORITY +nessuno +; +; +MSGID_RELAYOUTNAME +Riadatta sempre: +; +; +MSGID_RANDOMNAME +Sempre casuale: +; +; +MSGID_TASKPRINAME +Priorità task asincrono: +; +; +MSGID_TEXTNAME +Modo testo: +; +; +MSGID_CHECKMARKGADBUBBLE +Se settato, i colori dell'immagine\n\ +non vengono rimappati. +; +; +MSGID_CHECKMARKASYNCBUBBLE +Se settato, l'immagine viene tracciata alla\n\ +lettura delle icone e non quando ne è terminata\n\ +la disposizione prima di aprire la finestra. +; +; +MSGID_CHECKMARKFRIENDBUBBLE +Se settato, accelera il refresh del\n\ +motivo usando una seconda bitmap.\n\ + Viene ignorato se usi\n\ + un picture.datatype V43 o\n\ +GUIGfx poichè essi lo fanno già. +; +; +MSGID_CHECKMARKENHBUBBLE +La libreria GUIGfx mette a\n\ +disposizione delle routine molto veloci\n\ +es. per riduzione colori e retinatura.\n\ +Se settato usa GUIGfx. +; +; +MSGID_CHECKMARKAUTODITHERBUBBLE +Se settato, la retinatura viene\n\ +attivata automaticamente se l'immagine\n\ +dovesse perdere troppi colori. +; +; +MSGID_CHECKMARKRELAYOUTBUBBLE +Se settato, l'immagine viene\n\ +riscalata se modifichi\n\ +le dimensioni della finestra. +; +; +MSGID_CHECKMARKRANDOMBUBBLE +Se settato, viene utilizzato un motivo a caso\n\ +ogni volta che apri una finestra, invece\n\ +di scegliere casualmente un motivo solo al lancio. +; +; +MSGID_SAVEBUTTONBUBBLE +Salva le impostazioni ed esce. +; +; +MSGID_USEBUTTONBUBBLE +Usa le impostazioni ed esce. +; +; +MSGID_CANCELBUTTONBUBBLE +Esce senza salvare. +; +; +MSGID_NUMBUTTONBUBBLE +Il numero assegna il motivo\n\ +a desktop, schermo, finestra\n\ +e/o modo testo.\n\ +(Vedi pagina impostazioni). +; +; +MSGID_PRECSLIDERBUBBLE +Seleziona la precisione dei\n\ +colori per l'immagine. +; +; +MSGID_COLORSSLIDERBUBBLE +Percentuale di colori liberi\n\ +utilizzabili per l'immagine. +; +; +MSGID_CYCLEDITHERMODEBUBBLE +Routine utilizzata quando\n\ +non ci sono colori disponibili.\n\ +In questo caso un colore è\n\ +reso da un insieme di punti\n\ +vicini di diverso colore. +; +; +MSGID_SLIDERDITHERAMOUNTBUBBLE +Parametro per la routine di\n\ +retinatura. +; +; +MSGID_SLIDERWBBUBBLE +Numero indicante il motivo che deve\n\ +essere utilizzato per il desktop.\n\ +Finestre e desktop utilizzeranno il\n\ +motivo corrispondente al numero\n\ +selezionato per ognuno di essi.\n\ +Tutti i motivi con lo stesso numero\n\ +sono selezionati casualmente. +; +; +MSGID_SLIDERSCREENBUBBLE +Numero indicante il motivo che deve\n\ +essere utilizzato per lo schermo.\n\ +Finestre e desktop utilizzeranno il\n\ +motivo corrispondente al numero\n\ +selezionato per ognuno di essi.\n\ +Tutti i motivi con lo stesso numero\n\ +sono selezionati casualmente. +; +; +MSGID_SLIDERWINBUBBLE +Numero indicante il motivo che deve\n\ +essere utilizzato per le finestre.\n\ +Finestre e desktop utilizzeranno il\n\ +motivo corrispondente al numero\n\ +selezionato per ognuno di essi.\n\ +Tutti i motivi con lo stesso numero\n\ +sono selezionati casualmente. +; +; +MSGID_SLIDERTEXTBUBBLE +Numero indicante il motivo che deve\n\ +essere utilizzato per il modo testo.\n\ +Finestre e desktop utilizzeranno il\n\ +motivo corrispondente al numero\n\ +selezionato per ognuno di essi.\n\ +Tutti i motivi con lo stesso numero\n\ +sono selezionati casualmente. +; +; +MSGID_SLIDERTASKPRIBUBBLE +Priorità del task asincrono. +; +; +MSGID_PREVIEWIMAGEBUBBLE +Clicca qui per vedere\n\ +l'immagine selezionata. +; +; +MSGID_CYCLEGADBUBBLE +Vuoi che un motivo venga scalato\n\ +("Aggiusta dimensioni") o vuoi che che\n\ +sia ripetuto tante volte come tessera\n\ +di un mosaico ("Tessera") quando\n\ +modifichi una finestra? Per usare\n\ +"Aggiusta dimensioni" devi abilitare\n\ +"usa GUIGfx". +; +; +MSGID_MENU_PROJECT_ABOUT +Informazioni... +; +; +MSGID_ABOUTREQOK +_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos pattern preferences V%ld.%ld\033n\n\ +%s\n\ +© 1999%s The Scalos Team\n\ +Based on original code by Stefan Sommerfeld of ALiENDESiGN!\n\ +Bubbles done by Crayor. +; +; +MSGID_COLUMNTITLE_1 +\33bNr. +; +; +MSGID_COLUMNTITLE_2 +\33bFile name +; +; +MSGID_SHORTHELP_NEWBUTTON +Press this button to create a \n\ +new pattern entry +; +; +MSGID_SHORTHELP_DELBUTTON +Press this button to delete the \n\ +currently selected pattern entry. +; +; +MSGID_SHORTHELP_SAVEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENVARC:Scalos/Pattern.prefs\". +; +; +MSGID_SHORTHELP_USEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENV:Scalos/Pattern.prefs\". +; +; +MSGID_SHORTHELP_CANCELBUTTON +Press this button to abort \n\ +and discard all changes. +; +; +MSGID_REQTITLE_SAVEERROR +Error writing pattern preferences\n\ +file \"%s\"\n\ +%s +; +; +MSGID_REQTITLE_READERROR +Error reading pattern preferences\n\ +file \"%s\"\n\ +%s +; +; new in 40.4 +; +MSGID_PLUGIN_LIST_TITLE +Pattern +; +; +MSGID_GROUP_MISCELLANEOUS +Miscellaneous +; +; +MSGID_GROUP_PATTERNNUMBERS +Pattern numbers +; +; +MSGID_MENU_ENABLE_PREVIEW +Show Preview? +; +; +MSGID_MENU_AUTO_PREVIEW +Auto Preview? +; +; new in 40.6 +; +; +++translateme+++ +MSGID_SHORTHELP_LAMP_CHANGED +This lamp indicator changes from \033bOff\033n\n\ +to \033bOk\033n when the settings have been\n\ +modified since initial loading. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +; new in 40.7 +; +MSGID_COLUMNTITLE_3 +\33bPreview +;\33bPreview +; +; +MSGID_CREATING_THUMBNAIL +\33cCreating Thumbnail for +;\33cCreating Thumbnail for +; +; +MSGID_LOADING_THUMBNAIL +\33cLoading Thumbnail for +;\33cLoading Thumbnail for +; +; +MSGID_PROGRESS_THUMBNAILS +\33c%ld/%ld +;\33c%ld/%ld +; +; +MSGID_WINDOW_STARTUP +Scalos PatternPrefs startup +;Scalos PatternPrefs startup +; +; +MSGID_STARTUP_CREATING +On initial start, thumbnails are created for every \ +pattern. Unfortunately this takes some time. \ +However, thumbnail bitmaps are saved together \ +with the standard pattern preferences.\n\ +After the thumbnails have been saved, \ +future startups will be \033bmuch faster\033n. +;On initial start, thumbnails are created for every \ +;pattern. Unfortunately this takes some time. \ +;However, thumbnail bitmaps are saved together \ +;with the standard pattern preferences.\n\ +;After the thumbnails have been saved, \ +;future startups will be \033bmuch faster\033n. +; +; +MSGID_MENU_ENABLE_THUMBNAILS +Display Thumbnails? +;Display Thumbnails? +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Scalos Pattern Prefs startup failed +;Scalos Pattern Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Try again|Quit +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_COLUMNTITLE_4 +\33bType +; +;----------------------------------------------------------- +; +MSGID_PATTERNTYPE_DESKTOP +DE +; +; +MSGID_PATTERNTYPE_SCREEN +SC +; +; +MSGID_PATTERNTYPE_ICONWINDOW +IW +; +; +MSGID_PATTERNTYPE_TEXTWINDOW +TW +; +; +MSGID_PATTERNTYPE_NONE + +; +;----------------------------------------------------------- +; +MSGID_MENU_RELOAD_THUMBNAILS +Reload Thumbnails +;Reload Thumbnails +; +; +MSGID_LOADING_THUMBNAILS +\033cLoading Thumbnails... +;\033cLoading Thumbnails... +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_REGISTER_BACKGROUNDCOLORS +Background Colours +;Background Colours +; +;+++translateme+++ +MSGID_BGTYPE_NONE +None +;None +; +;+++translateme+++ +MSGID_LABEL_CYCLEBACKGROUND +Background Type: +;Background Type: +; +;+++translateme+++ +MSGID_BGTYPE_SINGLECOLOR +Single Colour +;Single Colour +; +;+++translateme+++ +MSGID_BGTYPE_HOR_GRADIENT +Horizontal gradient +;Horizontal gradient +; +;+++translateme+++ +MSGID_BGTYPE_VERT_GRADIENT +Vertical gradient +;Vertical gradient +; +;+++translateme+++ +MSGID_SHORTHELP_BACKGROUNDCOLOR1 +Here you can adjust the window background color.\n\ +This is only possible with \033bcentered\033n and\n\ +\033bcolor-only\033n pattern type.\n\ +For \033bgradient\33n pattern types, you can\n\ +select the top (vertical gradient) or left (horizontal gradient) colour here. +;Here you can adjust the window background color.\n\ +;This is only possible with \033bcentered\033n and\n\ +;\033bcolor-only\033n pattern type.\n\ +;For \033bgradient\33n pattern types, you can\n\ +;select the top (vertical gradient) or left (horizontal gradient) colour here. +; +;+++translateme+++ +MSGID_SHORTHELP_BACKGROUNDCOLOR2 +Here you can adjust the secondary window background color.\n\ +For \033bgradient\33n pattern types, you can\n\ +select the bottom (vertical gradient) or right\n\ +(horizontal gradient) colour here. +;Here you can adjust the secondary window background color.\n\ +;For \033bgradient\33n pattern types, you can\n\ +;select the bottom (vertical gradient) or right\n\ +;(horizontal gradient) colour here. +; +;+++translateme+++ +MSGID_SHORTHELP_CYCLEBACKGROUND +This gadget selects the type of background that\n\ +is drawn besides the selected image.\n\ +It is selectable only in \033bCentered\033n mode because\n\ +in other modes, there is no room around the image where\n\ +the background color could be seen. +;This gadget selects the type of background that\n\ +;is drawn besides the selected image.\n\ +;It is selectable only in \033bCentered\033n mode because\n\ +;in other modes, there is no room around the image where\n\ +;the background color could be seen. +; +;+++translateme+++ +MSGID_SCALEDMINNAME +Proportionally Scaled (min) +;Proportionally Scaled (min) +; +;+++translateme+++ +MSGID_SCALEDMAXNAME +Proportionally Scaled (max) +;Proportionally Scaled (max) +; +;----------------------------------------------------------- +; diff --git a/scalos/Prefs/Pattern/Catalogs/italiano/Scalos/config.mk b/scalos/Prefs/Pattern/Catalogs/italiano/Scalos/config.mk new file mode 100755 index 000000000..8108491da --- /dev/null +++ b/scalos/Prefs/Pattern/Catalogs/italiano/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = italiano + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = italian + +else + +############################################################################### +# AmigaOS and AROS + +LANG = italiano + +endif +endif diff --git a/scalos/Prefs/Pattern/Catalogs/italiano/Scalos/makefile b/scalos/Prefs/Pattern/Catalogs/italiano/Scalos/makefile new file mode 100644 index 000000000..9214cddbc --- /dev/null +++ b/scalos/Prefs/Pattern/Catalogs/italiano/Scalos/makefile @@ -0,0 +1,13 @@ +# makefile for Scalos (translated Texts : italiano) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1mitaliano\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +ScalosPattern.catalog : ScalosPattern.ct ../../../ScalosPattern.cd + +All: ScalosPattern.catalog diff --git a/scalos/Prefs/Pattern/Catalogs/italiano/Scalos/makefile-new b/scalos/Prefs/Pattern/Catalogs/italiano/Scalos/makefile-new new file mode 100755 index 000000000..2e8e45d0f --- /dev/null +++ b/scalos/Prefs/Pattern/Catalogs/italiano/Scalos/makefile-new @@ -0,0 +1,32 @@ +# makefile for ScalosPattern (translated Texts : italiano) +# $Date: 2011-08-06 19:37:48 +0200 (Sa, 06. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = ScalosPattern + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Prefs/Pattern/Catalogs/sample/Scalos/ScalosPattern.ct b/scalos/Prefs/Pattern/Catalogs/sample/Scalos/ScalosPattern.ct new file mode 100644 index 000000000..27bc5ad76 --- /dev/null +++ b/scalos/Prefs/Pattern/Catalogs/sample/Scalos/ScalosPattern.ct @@ -0,0 +1,696 @@ +; ScalosPattern.ct +## version $VER: ScalosPattern.catalog 40.12 (15 May 2005 09:36:09) +## codeset 0s +## language xxxxxx +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Pattern Prefs Plugin +; +; +MSGID_REGISTER_PATTERNLIST +Patternlist +; +; +MSGID_REMAPNAME +No remap +; +; +MSGID_RENDERTYPE_TILED +Tiled +; +; +MSGID_NEWNAME +New \033I[6:19] +; +; +MSGID_DELNAME +Delete +; +; +MSGID_SAVEBUTTON +Save +; +; +MSGID_USEBUTTON +Use +; +; +MSGID_CANCELBUTTON +Cancel +; +; +MSGID_SCREENNAME +Workbench +; +; +MSGID_WINDOWNAME +Window +; +; +MSGID_MENU_PROJECT_OPEN +Open... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +O +; +; +MSGID_MENU_PROJECT_SAVEAS +Save As... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +S +; +; +MSGID_MENU_PROJECT_QUIT +Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +Q +; +; +MSGID_MENU_PROJECT +Project +; +; +MSGID_MENU_EDIT_LASTSAVED +Last Saved +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +L +; +; +MSGID_MENU_EDIT +Edit +; +; +MSGID_MENU_SETTINGS_CREATEICONS +Create Icons? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +C +; +; +MSGID_MENU_SETTINGS +Settings +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +Reset To Defaults +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +R +; +; +MSGID_MENU_EDIT_RESTORE +Restore +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +E +; +; +MSGID_MENU_PROJECT_ABOUTMUI +About MUI... +; +; +MSGID_RENDERTYPE_FITSIZE +Fit Size +; +; +MSGID_CENTEREDNAME +Centered +; +; +MSGID_PRECEXACTNAME +Exact +; +; +MSGID_PRECIMAGENAME +Image +; +; +MSGID_PRECICONNAME +Icon +; +; +MSGID_PRECGUINAME +GUI +; +; +MSGID_PRECNAME +Pen Precision: +; +; +MSGID_ENHANCNAME +use GUIGfx: +; +; +MSGID_NUMCOLSNAME +Color weight +; +; +MSGID_ENHANCOPTSNAME +GUIGfx Options +; +; +MSGID_AUTODITHERNAME +AutoDither +; +; +MSGID_DITHERMODENAME +Dithering: +; +; +MSGID_DITHERAMOUNTNAME +Ditheramount: +; +; +MSGID_DITHERMODE1NAME +None +; +; +MSGID_DITHERMODE2NAME +Floyd Steinberg +; +; +MSGID_DITHERMODE3NAME +Random +; +; +MSGID_PICTURENAME +Picture: +; +; +MSGID_PATTERNNAME +Pattern +; +; +MSGID_REGISTER_DEFAULTS +Defaults +; +; +MSGID_DEFWBNAME +Desktop: +; +; +MSGID_DEFSCREENNAME +Screen: +; +; +MSGID_DEFWINNAME +Window: +; +; +MSGID_ASYNCNAME +asynchronous layout: +; +; +MSGID_FRIENDNAME +use friend bitmap: +; +; +MSGID_NONE_PRIORITY +none +; +; +MSGID_RELAYOUTNAME +always relayout: +; +; +MSGID_RANDOMNAME +randomize everytime: +; +; +MSGID_TASKPRINAME +Asynchronous Task priority: +; +; +MSGID_TEXTNAME +Text Mode: +; +; +MSGID_CHECKMARKGADBUBBLE +Don't remap the colors\n\ +of the picture if set. +; +; +MSGID_CHECKMARKASYNCBUBBLE +Render the picture while reading\n\ +the icons instead of waiting for\n\ +the layout to finish before\n\ +opening the window if set. +; +; +MSGID_CHECKMARKFRIENDBUBBLE +Speed up the pattern refresh\n\ +by using a second bitmap if set.\n\ +This is ignored if you use\n\ +a V43 picture.datatype or\n\ +GUIGFX because they do it\n\ +themselves. +; +; +MSGID_CHECKMARKENHBUBBLE +The GUIGFX library gives you\n\ +some very fast routines e.g. for\n\ +colorreduction and dithering.\n\ +Use guigfx.library if set. +; +; +MSGID_CHECKMARKAUTODITHERBUBBLE +If set, dithering will be enabled\n\ +automatically if the picture would\n\ +loose too many pens. +; +; +MSGID_CHECKMARKRELAYOUTBUBBLE +Scales the picture again if you\n\ +change the window size if set. +; +; +MSGID_CHECKMARKRANDOMBUBBLE +Selects one of the random patterns\n\ +everytime you open a window instead\n\ +of randomizing the patterns only at\n\ +startup if set. +; +; +MSGID_SAVEBUTTONBUBBLE +Save settings and quit. +; +; +MSGID_USEBUTTONBUBBLE +Use settings and quit. +; +; +MSGID_CANCELBUTTONBUBBLE +Quit without saving. +; +; +MSGID_NUMBUTTONBUBBLE +The number assigns the pattern\n\ +to the Desktop, Screen, Window\n\ +and/or Textmode of the Defaults\n\ +page. +; +; +MSGID_PRECSLIDERBUBBLE +Select the precision of the\n\ +pens for the picture. +; +; +MSGID_COLORSSLIDERBUBBLE +How many free pens should\n\ +be used for the picture. +; +; +MSGID_CYCLEDITHERMODEBUBBLE +The routine that is used when\n\ +there is no free pen. In that\n\ +case a color is made of many\n\ +points with different colors\n\ +close to each other. +; +; +MSGID_SLIDERDITHERAMOUNTBUBBLE +A parameter for the dithering\n\ +routine. +; +; +MSGID_SLIDERWBBUBBLE +The number that should be used for\n\ +the Desktop pattern to get assigned.\n\ +A pattern with the assigned number\n\ +one and a one selected for Desktop\n\ +and Window means that the Window\n\ +and Desktop patterns should be that\n\ +pattern.\n\ +All patterns with the same\n\ +number are selected by random. +; +; +MSGID_SLIDERSCREENBUBBLE +The number that should be used for\n\ +the Screen pattern to get assigned.\n\ +A pattern with the assigned number\n\ +one and a one selected for Desktop\n\ +and Window means that the Window\n\ +and Desktop patterns should be that\n\ +pattern.\n\ +All patterns with the same\n\ +number are selected by random. +; +; +MSGID_SLIDERWINBUBBLE +The number that should be used for\n\ +the Window pattern to get assigned.\n\ +A pattern with the assigned number\n\ +one and a one selected for Desktop\n\ +and Window means that the Window\n\ +and Desktop patterns should be that\n\ +pattern.\n\ +All patterns with the same\n\ +number are selected by random. +; +; +MSGID_SLIDERTEXTBUBBLE +The number that should be used for\n\ +the Textmode pattern to get assigned.\n\ +A pattern with the assigned number\n\ +one and a one selected for Desktop\n\ +and Window means that the Window\n\ +and Desktop patterns should be that\n\ +pattern.\n\ +(Window Menu: View by >> Text)\n\ +All patterns with the same\n\ +number are selected by random. +; +; +MSGID_SLIDERTASKPRIBUBBLE +Task priority of the\n\ +asynclayout task. +; +; +MSGID_PREVIEWIMAGEBUBBLE +Click here to see\n\ +the selected picture. +; +; +MSGID_CYCLEGADBUBBLE +Do you want a pattern to be scaled\n\ +("Fit Size") or do you want a pattern\n\ +to be made of many instances of that\n\ +pattern put together like a mosiac\n\ +("Tiled") when resizing the window.\n\ +If you like to use "Fit Size" you have\n\ +to enable "use GUIGFX". +; +; +MSGID_MENU_PROJECT_ABOUT +About... +; +; +MSGID_ABOUTREQOK +_OK +; +; +MSGID_ABOUTREQFORMAT +\33cScalos pattern preferences V%ld.%ld\n\ +%s\n\ +© 1999-2004 The Scalos Team\n\ +Based on original code by Stefan Sommerfeld of ALiENDESiGN!\n\ +Bubbles done by Crayor. +; +; +MSGID_COLUMNTITLE_1 +\33bNr. +; +; +MSGID_COLUMNTITLE_2 +\33bFile name +; +; +MSGID_SHORTHELP_NEWBUTTON +Press this button to create a \n\ +new pattern entry +; +; +MSGID_SHORTHELP_DELBUTTON +Press this button to delete the \n\ +currently selected pattern entry. +; +; +MSGID_SHORTHELP_SAVEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENVARC:Scalos/Pattern.prefs\". +; +; +MSGID_SHORTHELP_USEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENV:Scalos/Pattern.prefs\". +; +; +MSGID_SHORTHELP_CANCELBUTTON +Press this button to abort \n\ +and discard all changes. +; +; +MSGID_REQTITLE_SAVEERROR +Error writing pattern preferences\n\ +file \"%s\"\n\ +%s +; +; +MSGID_REQTITLE_READERROR +Error reading pattern preferences\n\ +file \"%s\"\n\ +%s +; +; new in 40.4 +; +MSGID_PLUGIN_LIST_TITLE +Pattern +; +; +MSGID_GROUP_MISCELLANEOUS +Miscellaneous +; +; +MSGID_GROUP_PATTERNNUMBERS +Pattern numbers +; +; +MSGID_MENU_ENABLE_PREVIEW +Show Preview? +; +; +MSGID_MENU_AUTO_PREVIEW +Auto Preview? +; +; new in 40.6 +; +; +++translateme+++ +MSGID_SHORTHELP_LAMP_CHANGED +This lamp indicator changes from \033bOff\033n\n\ +to \033bOk\033n when the settings have been\n\ +modified since initial loading. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +; new in 40.7 +; +MSGID_COLUMNTITLE_3 +\33bPreview +;\33bPreview +; +; +MSGID_CREATING_THUMBNAIL +\33cCreating Thumbnail for +;\33cCreating Thumbnail for +; +; +MSGID_LOADING_THUMBNAIL +\33cLoading Thumbnail for +;\33cLoading Thumbnail for +; +; +MSGID_PROGRESS_THUMBNAILS +\33c%ld/%ld +;\33c%ld/%ld +; +; +MSGID_WINDOW_STARTUP +Scalos PatternPrefs startup +;Scalos PatternPrefs startup +; +; +MSGID_STARTUP_CREATING +On initial start, thumbnails are created for every \ +pattern. Unfortunately this takes some time. \ +However, thumbnail bitmaps are saved together \ +with the standard pattern preferences.\n\ +After the thumbnails have been saved, \ +future startups will be \033bmuch faster\033n. +;On initial start, thumbnails are created for every \ +;pattern. Unfortunately this takes some time. \ +;However, thumbnail bitmaps are saved together \ +;with the standard pattern preferences.\n\ +;After the thumbnails have been saved, \ +;future startups will be \033bmuch faster\033n. +; +; +MSGID_MENU_ENABLE_THUMBNAILS +Display Thumbnails? +;Display Thumbnails? +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Scalos Pattern Prefs startup failed +;Scalos Pattern Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Try again|Quit +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_COLUMNTITLE_4 +\33bType +; +;----------------------------------------------------------- +; +MSGID_PATTERNTYPE_DESKTOP +DE +; +; +MSGID_PATTERNTYPE_SCREEN +SC +; +; +MSGID_PATTERNTYPE_ICONWINDOW +IW +; +; +MSGID_PATTERNTYPE_TEXTWINDOW +TW +; +; +MSGID_PATTERNTYPE_NONE + +; +;----------------------------------------------------------- +; +MSGID_MENU_RELOAD_THUMBNAILS +Reload Thumbnails +;Reload Thumbnails +; +; +MSGID_LOADING_THUMBNAILS +\033cLoading Thumbnails... +;\033cLoading Thumbnails... +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_REGISTER_BACKGROUNDCOLORS +Background Colours +;Background Colours +; +;+++translateme+++ +MSGID_BGTYPE_NONE +None +;None +; +;+++translateme+++ +MSGID_LABEL_CYCLEBACKGROUND +Background Type: +;Background Type: +; +;+++translateme+++ +MSGID_BGTYPE_SINGLECOLOR +Single Colour +;Single Colour +; +;+++translateme+++ +MSGID_BGTYPE_HOR_GRADIENT +Horizontal gradient +;Horizontal gradient +; +;+++translateme+++ +MSGID_BGTYPE_VERT_GRADIENT +Vertical gradient +;Vertical gradient +; +;+++translateme+++ +MSGID_SHORTHELP_BACKGROUNDCOLOR1 +Here you can adjust the window background color.\n\ +This is only possible with \033bcentered\033n and\n\ +\033bcolor-only\033n pattern type.\n\ +For \033bgradient\33n pattern types, you can\n\ +select the top (vertical gradient) or left (horizontal gradient) colour here. +;Here you can adjust the window background color.\n\ +;This is only possible with \033bcentered\033n and\n\ +;\033bcolor-only\033n pattern type.\n\ +;For \033bgradient\33n pattern types, you can\n\ +;select the top (vertical gradient) or left (horizontal gradient) colour here. +; +;+++translateme+++ +MSGID_SHORTHELP_BACKGROUNDCOLOR2 +Here you can adjust the secondary window background color.\n\ +For \033bgradient\33n pattern types, you can\n\ +select the bottom (vertical gradient) or right\n\ +(horizontal gradient) colour here. +;Here you can adjust the secondary window background color.\n\ +;For \033bgradient\33n pattern types, you can\n\ +;select the bottom (vertical gradient) or right\n\ +;(horizontal gradient) colour here. +; +;+++translateme+++ +MSGID_SHORTHELP_CYCLEBACKGROUND +This gadget selects the type of background that\n\ +is drawn besides the selected image.\n\ +It is selectable only in \033bCentered\033n mode because\n\ +in other modes, there is no room around the image where\n\ +the background color could be seen. +;This gadget selects the type of background that\n\ +;is drawn besides the selected image.\n\ +;It is selectable only in \033bCentered\033n mode because\n\ +;in other modes, there is no room around the image where\n\ +;the background color could be seen. +; +;+++translateme+++ +MSGID_SCALEDMINNAME +Proportionally Scaled (min) +;Proportionally Scaled (min) +; +;+++translateme+++ +MSGID_SCALEDMAXNAME +Proportionally Scaled (max) +;Proportionally Scaled (max) +; +;----------------------------------------------------------- +; diff --git a/scalos/Prefs/Pattern/Catalogs/svenska/Scalos/ScalosPattern.ct b/scalos/Prefs/Pattern/Catalogs/svenska/Scalos/ScalosPattern.ct new file mode 100644 index 000000000..3e167fdb5 --- /dev/null +++ b/scalos/Prefs/Pattern/Catalogs/svenska/Scalos/ScalosPattern.ct @@ -0,0 +1,659 @@ +; ScalosPattern.ct +## version $VER: ScalosPattern.catalog 40.12 (15 May 2005 09:36:09) +## codeset 0 +## language svenska +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Mönster Plugin +; +; +MSGID_REGISTER_PATTERNLIST +Lista över mönster +; +; +MSGID_REMAPNAME +Ingen färganpassning +; +; +MSGID_RENDERTYPE_TILED +Sida vid sida +; +; +MSGID_NEWNAME +Ny \033I[6:19] +; +; +MSGID_DELNAME +Ta bort +; +; +MSGID_SAVEBUTTON +Spara +; +; +MSGID_USEBUTTON +Använd +; +; +MSGID_CANCELBUTTON +Avbryt +; +; +MSGID_SCREENNAME +Workbench +; +; +MSGID_WINDOWNAME +Fönster +; +; +MSGID_MENU_PROJECT_OPEN +Öppna... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +Ö +; +; +MSGID_MENU_PROJECT_SAVEAS +Spara som... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +S +; +; +MSGID_MENU_PROJECT_QUIT +Avsluta +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +V +; +; +MSGID_MENU_PROJECT +Arkiv +; +; +MSGID_MENU_EDIT_LASTSAVED +Senast sparade +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +P +; +; +MSGID_MENU_EDIT +Redigera +; +; +MSGID_MENU_SETTINGS_CREATEICONS +Skapa symboler? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +S +; +; +MSGID_MENU_SETTINGS +Inställningar +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +Förinställda värden +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +F +; +; +MSGID_MENU_EDIT_RESTORE +Återställ +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +Å +; +; +MSGID_MENU_PROJECT_ABOUTMUI +Om MUI... +; +; +MSGID_RENDERTYPE_FITSIZE +Anpassa storlek +; +; +MSGID_CENTEREDNAME +Centrerad +; +; +MSGID_PRECEXACTNAME +Exakt +; +; +MSGID_PRECIMAGENAME +Bild +; +; +MSGID_PRECICONNAME +Symboler +; +; +MSGID_PRECGUINAME +GUI +; +; +MSGID_PRECNAME +Färgprecision: +; +; +MSGID_ENHANCNAME +Använd GUIGfx +; +; +MSGID_NUMCOLSNAME +Färgreducering: +; +; +MSGID_ENHANCOPTSNAME +GUIGfx Inställningar +; +; +MSGID_AUTODITHERNAME +Automatisk rastrering +; +; +MSGID_DITHERMODENAME +Rastrering: +; +; +MSGID_DITHERAMOUNTNAME +Rastermängd: +; +; +MSGID_DITHERMODE1NAME +Ingen +; +; +MSGID_DITHERMODE2NAME +Floyd-Steinberg +; +; +MSGID_DITHERMODE3NAME +Slumpad +; +; +MSGID_PICTURENAME +Bild: +; +; +MSGID_PATTERNNAME +Mönster +; +; +MSGID_REGISTER_DEFAULTS +Inställningar +; +; +MSGID_DEFWBNAME +Skrivbord: +; +; +MSGID_DEFSCREENNAME +Skärm: +; +; +MSGID_DEFWINNAME +Fönster: +; +; +MSGID_ASYNCNAME +Asynkron layout: +; +; +MSGID_FRIENDNAME +Använd FrienBitMap: +; +; +MSGID_NONE_PRIORITY +ingen +; +; +MSGID_RELAYOUTNAME +Alltid relayout: +; +; +MSGID_RANDOMNAME +Slumpa varje gång: +; +; +MSGID_TASKPRINAME +Asynkron prioritet: +; +; +MSGID_TEXTNAME +Textläge: +; +; +MSGID_CHECKMARKGADBUBBLE +Anpassa inte inte bildens färger. +; +; +MSGID_CHECKMARKASYNCBUBBLE +Rita ut bilden medan ikonerna\n\ +laddas, istället för att vänta på\n\ +att layouten ska bli klar\n\ +innan fönstret öppnas. +; +; +MSGID_CHECKMARKFRIENDBUBBLE +Snabbar upp uppritning av bilden\n\ +genom att använda en extra bitmap.\n\ +Denna inställning ignoreras om\n\ +du använder picture.datatype V43\n\ +eller GUIGFX därför att dem\n\ +använder det automatiskt. +; +; +MSGID_CHECKMARKENHBUBBLE +GUIGfx.library erbjuder några\n\ +mycket snabba rutiner för t.ex.\n\ +färgreducering och rastrering. +; +; +MSGID_CHECKMARKAUTODITHERBUBBLE +Slår på rastrering av bilden om\n\ +för få lediga pennor finns tillgängliga. +; +; +MSGID_CHECKMARKRELAYOUTBUBBLE +Skalar om bilden varje gång du\n\ +ändrar fönstrens storlek. +; +; +MSGID_CHECKMARKRANDOMBUBBLE +Väljer slumpmässigt ett mönster\n\ +varje gång du öppnar ett fönster i\n\ +stället för vid uppstart. +; +; +MSGID_SAVEBUTTONBUBBLE +Spara inställningarna och avsluta. +; +; +MSGID_USEBUTTONBUBBLE +Använd inställningarna och avsluta. +; +; +MSGID_CANCELBUTTONBUBBLE +Avsluta utan att spara. +; +; +MSGID_NUMBUTTONBUBBLE +The number assigns the pattern\n\ +to the Desktop, Screen, Window\n\ +and/or Textmode of the Defaults\n\ +page. +; +; +MSGID_PRECSLIDERBUBBLE +Anger färgprecision för bilden. +; +; +MSGID_COLORSSLIDERBUBBLE +Maximalt antal fria pennor som\n\ +får reserveras för bilden. +; +; +MSGID_CYCLEDITHERMODEBUBBLE +Vilken typ av rastrering som ska\n\ +användas om det inte finns\n\ +tillräckligt många fria pennor. +; +; +MSGID_SLIDERDITHERAMOUNTBUBBLE +En parameter för rastreringsrutinen. +; +; +MSGID_SLIDERWBBUBBLE +Numret på det/de mönster du vill\n\ +använda på skrivbordet. +; +; +MSGID_SLIDERSCREENBUBBLE +Numret på det/de mönster du vill\n\ +använda på skärmen. +; +; +MSGID_SLIDERWINBUBBLE +Numret på det/de mönster du vill\n\ +använda i fönster. +; +; +MSGID_SLIDERTEXTBUBBLE +Numret på det/de mönster du vill\n\ +använda i textläge. +; +; +MSGID_SLIDERTASKPRIBUBBLE +Priotiteten på en asynkrona\n\ +layout-processen. +; +; +MSGID_PREVIEWIMAGEBUBBLE +Klicka här för att se\n\ +den valda bilden. +; +; +MSGID_CYCLEGADBUBBLE +Anger om bildens storlek ska anpassas\n\ +till skärmen/fönstret, om den ska\n\ +upprepas sida vid sida som ett\n\ +mosaikmönster. För att kunna anpassa bilden\n\ +krävs GUIGfx. +; +; +MSGID_MENU_PROJECT_ABOUT +Om... +; +; +MSGID_ABOUTREQOK +_OK +; +; +MSGID_ABOUTREQFORMAT +\33cScalos pattern preferences VV%ld.%ld\n\ +© 1999%s The Scalos Team\n\ +%s\n\ +Based on original code by Stefan Sommerfeld of ALiENDESiGN!\n\ +Bubbles done by Crayor. +; +; +; +; +MSGID_COLUMNTITLE_1 +\33bNr. +; +; +MSGID_COLUMNTITLE_2 +\33bFile name +; +; +MSGID_SHORTHELP_NEWBUTTON +Press this button to create a \n\ +new pattern entry +; +; +MSGID_SHORTHELP_DELBUTTON +Press this button to delete the \n\ +currently selected pattern entry. +; +; +MSGID_SHORTHELP_SAVEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENVARC:Scalos/Pattern.prefs\". +; +; +MSGID_SHORTHELP_USEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENV:Scalos/Pattern.prefs\". +; +; +MSGID_SHORTHELP_CANCELBUTTON +Press this button to abort \n\ +and discard all changes. +; +; +MSGID_REQTITLE_SAVEERROR +Error writing pattern preferences\n\ +file \"%s\"\n\ +%s +; +; +MSGID_REQTITLE_READERROR +Error reading pattern preferences\n\ +file \"%s\"\n\ +%s +; +; new in 40.4 +; +MSGID_PLUGIN_LIST_TITLE +Pattern +; +; +MSGID_GROUP_MISCELLANEOUS +Miscellaneous +; +; +MSGID_GROUP_PATTERNNUMBERS +Pattern numbers +; +; +MSGID_MENU_ENABLE_PREVIEW +Show Preview? +; +; +MSGID_MENU_AUTO_PREVIEW +Auto Preview? +; +; new in 40.6 +; +; +++translateme+++ +MSGID_SHORTHELP_LAMP_CHANGED +This lamp indicator changes from \033bOff\033n\n\ +to \033bOk\033n when the settings have been\n\ +modified since initial loading. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +; new in 40.7 +; +MSGID_COLUMNTITLE_3 +\33bPreview +;\33bPreview +; +; +MSGID_CREATING_THUMBNAIL +\33cCreating Thumbnail for +;\33cCreating Thumbnail for +; +; +MSGID_LOADING_THUMBNAIL +\33cLoading Thumbnail for +;\33cLoading Thumbnail for +; +; +MSGID_PROGRESS_THUMBNAILS +\33c%ld/%ld +;\33c%ld/%ld +; +; +MSGID_WINDOW_STARTUP +Scalos PatternPrefs startup +;Scalos PatternPrefs startup +; +; +MSGID_STARTUP_CREATING +On initial start, thumbnails are created for every \ +pattern. Unfortunately this takes some time. \ +However, thumbnail bitmaps are saved together \ +with the standard pattern preferences.\n\ +After the thumbnails have been saved, \ +future startups will be \033bmuch faster\033n. +;On initial start, thumbnails are created for every \ +;pattern. Unfortunately this takes some time. \ +;However, thumbnail bitmaps are saved together \ +;with the standard pattern preferences.\n\ +;After the thumbnails have been saved, \ +;future startups will be \033bmuch faster\033n. +; +; +MSGID_MENU_ENABLE_THUMBNAILS +Display Thumbnails? +;Display Thumbnails? +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Scalos Pattern Prefs startup failed +;Scalos Pattern Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Try again|Quit +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_COLUMNTITLE_4 +\33bType +; +;----------------------------------------------------------- +; +MSGID_PATTERNTYPE_DESKTOP +DE +; +; +MSGID_PATTERNTYPE_SCREEN +SC +; +; +MSGID_PATTERNTYPE_ICONWINDOW +IW +; +; +MSGID_PATTERNTYPE_TEXTWINDOW +TW +; +; +MSGID_PATTERNTYPE_NONE + +; +;----------------------------------------------------------- +; +MSGID_MENU_RELOAD_THUMBNAILS +Reload Thumbnails +;Reload Thumbnails +; +; +MSGID_LOADING_THUMBNAILS +\033cLoading Thumbnails... +;\033cLoading Thumbnails... +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_REGISTER_BACKGROUNDCOLORS +Background Colours +;Background Colours +; +;+++translateme+++ +MSGID_BGTYPE_NONE +None +;None +; +;+++translateme+++ +MSGID_LABEL_CYCLEBACKGROUND +Background Type: +;Background Type: +; +;+++translateme+++ +MSGID_BGTYPE_SINGLECOLOR +Single Colour +;Single Colour +; +;+++translateme+++ +MSGID_BGTYPE_HOR_GRADIENT +Horizontal gradient +;Horizontal gradient +; +;+++translateme+++ +MSGID_BGTYPE_VERT_GRADIENT +Vertical gradient +;Vertical gradient +; +;+++translateme+++ +MSGID_SHORTHELP_BACKGROUNDCOLOR1 +Here you can adjust the window background color.\n\ +This is only possible with \033bcentered\033n and\n\ +\033bcolor-only\033n pattern type.\n\ +For \033bgradient\33n pattern types, you can\n\ +select the top (vertical gradient) or left (horizontal gradient) colour here. +;Here you can adjust the window background color.\n\ +;This is only possible with \033bcentered\033n and\n\ +;\033bcolor-only\033n pattern type.\n\ +;For \033bgradient\33n pattern types, you can\n\ +;select the top (vertical gradient) or left (horizontal gradient) colour here. +; +;+++translateme+++ +MSGID_SHORTHELP_BACKGROUNDCOLOR2 +Here you can adjust the secondary window background color.\n\ +For \033bgradient\33n pattern types, you can\n\ +select the bottom (vertical gradient) or right\n\ +(horizontal gradient) colour here. +;Here you can adjust the secondary window background color.\n\ +;For \033bgradient\33n pattern types, you can\n\ +;select the bottom (vertical gradient) or right\n\ +;(horizontal gradient) colour here. +; +;+++translateme+++ +MSGID_SHORTHELP_CYCLEBACKGROUND +This gadget selects the type of background that\n\ +is drawn besides the selected image.\n\ +It is selectable only in \033bCentered\033n mode because\n\ +in other modes, there is no room around the image where\n\ +the background color could be seen. +;This gadget selects the type of background that\n\ +;is drawn besides the selected image.\n\ +;It is selectable only in \033bCentered\033n mode because\n\ +;in other modes, there is no room around the image where\n\ +;the background color could be seen. +; +;+++translateme+++ +MSGID_SCALEDMINNAME +Proportionally Scaled (min) +;Proportionally Scaled (min) +; +;+++translateme+++ +MSGID_SCALEDMAXNAME +Proportionally Scaled (max) +;Proportionally Scaled (max) +; +;----------------------------------------------------------- +; diff --git a/scalos/Prefs/Pattern/Catalogs/svenska/Scalos/config.mk b/scalos/Prefs/Pattern/Catalogs/svenska/Scalos/config.mk new file mode 100755 index 000000000..ec05f9b34 --- /dev/null +++ b/scalos/Prefs/Pattern/Catalogs/svenska/Scalos/config.mk @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = svenska + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = swedish + +else + +############################################################################### +# AmigaOS and AROS + +LANG = svenska + +endif +endif diff --git a/scalos/Prefs/Pattern/Catalogs/svenska/Scalos/makefile b/scalos/Prefs/Pattern/Catalogs/svenska/Scalos/makefile new file mode 100644 index 000000000..7042d5664 --- /dev/null +++ b/scalos/Prefs/Pattern/Catalogs/svenska/Scalos/makefile @@ -0,0 +1,13 @@ +# makefile für Scalos (translated Texts : svenska) +# $Date$ + +.SUFFIXES: .ct .catalog + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1msvenska\033[0m\n' + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +ScalosPattern.catalog : ScalosPattern.ct ../../../ScalosPattern.cd + +All: ScalosPattern.catalog diff --git a/scalos/Prefs/Pattern/Catalogs/svenska/Scalos/makefile-new b/scalos/Prefs/Pattern/Catalogs/svenska/Scalos/makefile-new new file mode 100755 index 000000000..e92d9def9 --- /dev/null +++ b/scalos/Prefs/Pattern/Catalogs/svenska/Scalos/makefile-new @@ -0,0 +1,32 @@ +# makefile for ScalosPattern (translated Texts : svenska) +# $Date: 2011-08-06 19:37:48 +0200 (Sa, 06. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = ScalosPattern + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git "a/scalos/Prefs/Pattern/Catalogs/\303\203e\303\223tina/Scalos/ScalosPattern.ct" "b/scalos/Prefs/Pattern/Catalogs/\303\203e\303\223tina/Scalos/ScalosPattern.ct" new file mode 100644 index 000000000..ac319c17d --- /dev/null +++ "b/scalos/Prefs/Pattern/Catalogs/\303\203e\303\223tina/Scalos/ScalosPattern.ct" @@ -0,0 +1,696 @@ +; ScalosPattern.ct +## version $VER: ScalosPattern.catalog 40.12 (15 May 2005 09:36:09) +## codeset 0 +## language ÃeÓtina +; +;#arrayopts static __far +; +; +MSGID_TITLENAME +Scalos Pattern Prefs Plugin +; +; +MSGID_REGISTER_PATTERNLIST +Seznam vzorÊ +; +; +MSGID_REMAPNAME +NepÒemapovÁvat +; +; +MSGID_RENDERTYPE_TILED +vedle sebe +; +; +MSGID_NEWNAME +NovÙ \033I[6:19] +; +; +MSGID_DELNAME +Smazat +; +; +MSGID_SAVEBUTTON +UloÚit +; +; +MSGID_USEBUTTON +PouÚÉt +; +; +MSGID_CANCELBUTTON +ZruÓit +; +; +MSGID_SCREENNAME +Workbench +; +; +MSGID_WINDOWNAME +Okno +; +; +MSGID_MENU_PROJECT_OPEN +OtevÒÉt... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT +O +; +; +MSGID_MENU_PROJECT_SAVEAS +UloÚit jako... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT +U +; +; +MSGID_MENU_PROJECT_QUIT +SkonÃit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT +K +; +; +MSGID_MENU_PROJECT +Projekt +; +; +MSGID_MENU_EDIT_LASTSAVED +Naposledy uloÚen× +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT +N +; +; +MSGID_MENU_EDIT +õpravy +; +; +MSGID_MENU_SETTINGS_CREATEICONS +VytvÁÒet ikony? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT +V +; +; +MSGID_MENU_SETTINGS +NastavenÉ +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS +Syst×mov× +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT +Y +; +; +MSGID_MENU_EDIT_RESTORE +PÒedchozÉ +; +; +MSGID_MENU_EDIT_RESTORE_SHORT +P +; +; +MSGID_MENU_PROJECT_ABOUTMUI +O MUI... +; +; +MSGID_RENDERTYPE_FITSIZE +VhodnÁ velikost +; +; +MSGID_CENTEREDNAME +Vycentrovat +; +; +MSGID_PRECEXACTNAME +PÒesnÙ +; +; +MSGID_PRECIMAGENAME +ObrÁzek +; +; +MSGID_PRECICONNAME +Ikona +; +; +MSGID_PRECGUINAME +GUI +; +; +MSGID_PRECNAME +PÒesnost pera +; +; +MSGID_ENHANCNAME +pouÚÉt GUIGfx +; +; +MSGID_NUMCOLSNAME +ZatÉÚenÉ per: +; +; +MSGID_ENHANCOPTSNAME +NastavenÉ GUIGfx +; +; +MSGID_AUTODITHERNAME +AutoDither +; +; +MSGID_DITHERMODENAME +Dithering: +; +; +MSGID_DITHERAMOUNTNAME +Hustota +; +; +MSGID_DITHERMODE1NAME +VypnutÙ +; +; +MSGID_DITHERMODE2NAME +Floyd Steinberg +; +; +MSGID_DITHERMODE3NAME +NÁhodnÙ +; +; +MSGID_PICTURENAME +ObrÁzek: +; +; +MSGID_PATTERNNAME +Vzor +; +; +MSGID_REGISTER_DEFAULTS +StandardnÉ +; +; +MSGID_DEFWBNAME +Desktop: +; +; +MSGID_DEFSCREENNAME +Obrazovka: +; +; +MSGID_DEFWINNAME +Okno: +; +; +MSGID_ASYNCNAME +asynchronnÉ layout: +; +; +MSGID_FRIENDNAME +pouÚÉt blÉzkou bitmapu: +; +; +MSGID_NONE_PRIORITY +ÚÁdnÙ +; +; +MSGID_RELAYOUTNAME +vÚdy novÅ propoÃÉtat: +; +; +MSGID_RANDOMNAME +PokaÚd× nÁhodnÙ vÙbÅr: +; +; +MSGID_TASKPRINAME +Priorita asynchronnÉch Õloh +; +; +MSGID_TEXTNAME +TextovÙ reÚim: +; +; +MSGID_CHECKMARKGADBUBBLE +Don't remap the colors\n\ +of the picture if set. +; +; +MSGID_CHECKMARKASYNCBUBBLE +Render the picture while reading\n\ +the icons instead of waiting for\n\ +the layout to finish before\n\ +opening the window if set. +; +; +MSGID_CHECKMARKFRIENDBUBBLE +Speed up the pattern refresh\n\ +by using a second bitmap if set.\n\ +This is ignored if you use\n\ +a V43 picture.datatype or\n\ +GUIGFX because they do it\n\ +themselves. +; +; +MSGID_CHECKMARKENHBUBBLE +The GUIGFX library gives you\n\ +some very fast routines e.g. for\n\ +colorreduction and dithering.\n\ +Use guigfx.library if set. +; +; +MSGID_CHECKMARKAUTODITHERBUBBLE +If set, dithering will be enabled\n\ +automatically if the picture would\n\ +loose too many pens. +; +; +MSGID_CHECKMARKRELAYOUTBUBBLE +Scales the picture again if you\n\ +change the window size if set. +; +; +MSGID_CHECKMARKRANDOMBUBBLE +Selects one of the random patterns\n\ +everytime you open a window instead\n\ +of randomizing the patterns only at\n\ +startup if set. +; +; +MSGID_SAVEBUTTONBUBBLE +Save settings and quit. +; +; +MSGID_USEBUTTONBUBBLE +Use settings and quit. +; +; +MSGID_CANCELBUTTONBUBBLE +Quit without saving. +; +; +MSGID_NUMBUTTONBUBBLE +The number assigns the pattern\n\ +to the Desktop, Screen, Window\n\ +and/or Textmode of the Defaults\n\ +page. +; +; +MSGID_PRECSLIDERBUBBLE +Select the precision of the\n\ +pens for the picture. +; +; +MSGID_COLORSSLIDERBUBBLE +How many free pens should\n\ +be used for the picture. +; +; +MSGID_CYCLEDITHERMODEBUBBLE +The routine that is used when\n\ +there is no free pen. In that\n\ +case a color is made of many\n\ +points with different colors\n\ +close to each other. +; +; +MSGID_SLIDERDITHERAMOUNTBUBBLE +A parameter for the dithering\n\ +routine. +; +; +MSGID_SLIDERWBBUBBLE +The number that should be used for\n\ +the Desktop pattern to get assigned.\n\ +A pattern with the assigned number\n\ +one and a one selected for Desktop\n\ +and Window means that the Window\n\ +and Desktop patterns should be that\n\ +pattern.\n\ +All patterns with the same\n\ +number are selected by random. +; +; +MSGID_SLIDERSCREENBUBBLE +The number that should be used for\n\ +the Screen pattern to get assigned.\n\ +A pattern with the assigned number\n\ +one and a one selected for Desktop\n\ +and Window means that the Window\n\ +and Desktop patterns should be that\n\ +pattern.\n\ +All patterns with the same\n\ +number are selected by random. +; +; +MSGID_SLIDERWINBUBBLE +The number that should be used for\n\ +the Window pattern to get assigned.\n\ +A pattern with the assigned number\n\ +one and a one selected for Desktop\n\ +and Window means that the Window\n\ +and Desktop patterns should be that\n\ +pattern.\n\ +All patterns with the same\n\ +number are selected by random. +; +; +MSGID_SLIDERTEXTBUBBLE +The number that should be used for\n\ +the Textmode pattern to get assigned.\n\ +A pattern with the assigned number\n\ +one and a one selected for Desktop\n\ +and Window means that the Window\n\ +and Desktop patterns should be that\n\ +pattern.\n\ +(Window Menu: View by >> Text)\n\ +All patterns with the same\n\ +number are selected by random. +; +; +MSGID_SLIDERTASKPRIBUBBLE +Task priority of the\n\ +asynclayout task. +; +; +MSGID_PREVIEWIMAGEBUBBLE +Click here to see\n\ +the selected picture. +; +; +MSGID_CYCLEGADBUBBLE +Do you want a pattern to be scaled\n\ +("Fit Size") or do you want a pattern\n\ +to be made of many instances of that\n\ +pattern put together like a mosiac\n\ +("Tiled") when resizing the window.\n\ +If you like to use "Fit Size" you have\n\ +to enable "use GUIGFX". +; +; +MSGID_MENU_PROJECT_ABOUT +About... +; +; +MSGID_ABOUTREQOK +_OK +; +; +MSGID_ABOUTREQFORMAT +\33c\033bScalos pattern preferences V%ld.%ld\033n\n\ +%s\n\ +© 1999%s The Scalos Team\n\ +Based on original code by Stefan Sommerfeld of ALiENDESiGN!\n\ +Bubbles done by Crayor. +; +; +MSGID_COLUMNTITLE_1 +\33bNr. +; +; +MSGID_COLUMNTITLE_2 +\33bFile name +; +; +MSGID_SHORTHELP_NEWBUTTON +Press this button to create a \n\ +new pattern entry +; +; +MSGID_SHORTHELP_DELBUTTON +Press this button to delete the \n\ +currently selected pattern entry. +; +; +MSGID_SHORTHELP_SAVEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENVARC:Scalos/Pattern.prefs\". +; +; +MSGID_SHORTHELP_USEBUTTON +Press this button to save \n\ +the current settings to\n\ +\"ENV:Scalos/Pattern.prefs\". +; +; +MSGID_SHORTHELP_CANCELBUTTON +Press this button to abort \n\ +and discard all changes. +; +; +MSGID_REQTITLE_SAVEERROR +Error writing pattern preferences\n\ +file \"%s\"\n\ +%s +; +; +MSGID_REQTITLE_READERROR +Error reading pattern preferences\n\ +file \"%s\"\n\ +%s +; +; new in 40.4 +; +MSGID_PLUGIN_LIST_TITLE +Pattern +; +; +MSGID_GROUP_MISCELLANEOUS +Miscellaneous +; +; +MSGID_GROUP_PATTERNNUMBERS +Pattern numbers +; +; +MSGID_MENU_ENABLE_PREVIEW +Show Preview? +; +; +MSGID_MENU_AUTO_PREVIEW +Auto Preview? +; +; new in 40.6 +; +; +++translateme+++ +MSGID_SHORTHELP_LAMP_CHANGED +This lamp indicator changes from \033bOff\033n\n\ +to \033bOk\033n when the settings have been\n\ +modified since initial loading. +;This lamp indicator changes from \033bOff\033n\n\ +;to \033bOk\033n when the settings have been\n\ +;modified since initial loading. +; +; new in 40.7 +; +MSGID_COLUMNTITLE_3 +\33bPreview +;\33bPreview +; +; +MSGID_CREATING_THUMBNAIL +\33cCreating Thumbnail for +;\33cCreating Thumbnail for +; +; +MSGID_LOADING_THUMBNAIL +\33cLoading Thumbnail for +;\33cLoading Thumbnail for +; +; +MSGID_PROGRESS_THUMBNAILS +\33c%ld/%ld +;\33c%ld/%ld +; +; +MSGID_WINDOW_STARTUP +Scalos PatternPrefs startup +;Scalos PatternPrefs startup +; +; +MSGID_STARTUP_CREATING +On initial start, thumbnails are created for every \ +pattern. Unfortunately this takes some time. \ +However, thumbnail bitmaps are saved together \ +with the standard pattern preferences.\n\ +After the thumbnails have been saved, \ +future startups will be \033bmuch faster\033n. +;On initial start, thumbnails are created for every \ +;pattern. Unfortunately this takes some time. \ +;However, thumbnail bitmaps are saved together \ +;with the standard pattern preferences.\n\ +;After the thumbnails have been saved, \ +;future startups will be \033bmuch faster\033n. +; +; +MSGID_MENU_ENABLE_THUMBNAILS +Display Thumbnails? +;Display Thumbnails? +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE +Scalos Pattern Prefs startup failed +;Scalos Pattern Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD +Try again|Quit +;Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;\n\ +;Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +;Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +;%lu.%lu is currently in use by other applications.\n\ +;\n\ +;Once you have installed the required version,\n\ +;close all MUI programs, make sure the old class\n\ +;is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_COLUMNTITLE_4 +\33bType +; +;----------------------------------------------------------- +; +MSGID_PATTERNTYPE_DESKTOP +DE +; +; +MSGID_PATTERNTYPE_SCREEN +SC +; +; +MSGID_PATTERNTYPE_ICONWINDOW +IW +; +; +MSGID_PATTERNTYPE_TEXTWINDOW +TW +; +; +MSGID_PATTERNTYPE_NONE + +; +;----------------------------------------------------------- +; +MSGID_MENU_RELOAD_THUMBNAILS +Reload Thumbnails +;Reload Thumbnails +; +; +MSGID_LOADING_THUMBNAILS +\033cLoading Thumbnails... +;\033cLoading Thumbnails... +; +;----------------------------------------------------------- +;+++translateme+++ +MSGID_REGISTER_BACKGROUNDCOLORS +Background Colours +;Background Colours +; +;+++translateme+++ +MSGID_BGTYPE_NONE +None +;None +; +;+++translateme+++ +MSGID_LABEL_CYCLEBACKGROUND +Background Type: +;Background Type: +; +;+++translateme+++ +MSGID_BGTYPE_SINGLECOLOR +Single Colour +;Single Colour +; +;+++translateme+++ +MSGID_BGTYPE_HOR_GRADIENT +Horizontal gradient +;Horizontal gradient +; +;+++translateme+++ +MSGID_BGTYPE_VERT_GRADIENT +Vertical gradient +;Vertical gradient +; +;+++translateme+++ +MSGID_SHORTHELP_BACKGROUNDCOLOR1 +Here you can adjust the window background color.\n\ +This is only possible with \033bcentered\033n and\n\ +\033bcolor-only\033n pattern type.\n\ +For \033bgradient\33n pattern types, you can\n\ +select the top (vertical gradient) or left (horizontal gradient) colour here. +;Here you can adjust the window background color.\n\ +;This is only possible with \033bcentered\033n and\n\ +;\033bcolor-only\033n pattern type.\n\ +;For \033bgradient\33n pattern types, you can\n\ +;select the top (vertical gradient) or left (horizontal gradient) colour here. +; +;+++translateme+++ +MSGID_SHORTHELP_BACKGROUNDCOLOR2 +Here you can adjust the secondary window background color.\n\ +For \033bgradient\33n pattern types, you can\n\ +select the bottom (vertical gradient) or right\n\ +(horizontal gradient) colour here. +;Here you can adjust the secondary window background color.\n\ +;For \033bgradient\33n pattern types, you can\n\ +;select the bottom (vertical gradient) or right\n\ +;(horizontal gradient) colour here. +; +;+++translateme+++ +MSGID_SHORTHELP_CYCLEBACKGROUND +This gadget selects the type of background that\n\ +is drawn besides the selected image.\n\ +It is selectable only in \033bCentered\033n mode because\n\ +in other modes, there is no room around the image where\n\ +the background color could be seen. +;This gadget selects the type of background that\n\ +;is drawn besides the selected image.\n\ +;It is selectable only in \033bCentered\033n mode because\n\ +;in other modes, there is no room around the image where\n\ +;the background color could be seen. +; +;+++translateme+++ +MSGID_SCALEDMINNAME +Proportionally Scaled (min) +;Proportionally Scaled (min) +; +;+++translateme+++ +MSGID_SCALEDMAXNAME +Proportionally Scaled (max) +;Proportionally Scaled (max) +; +;----------------------------------------------------------- +; diff --git "a/scalos/Prefs/Pattern/Catalogs/\303\203e\303\223tina/Scalos/config.mk" "b/scalos/Prefs/Pattern/Catalogs/\303\203e\303\223tina/Scalos/config.mk" new file mode 100755 index 000000000..7bfe8c7a6 --- /dev/null +++ "b/scalos/Prefs/Pattern/Catalogs/\303\203e\303\223tina/Scalos/config.mk" @@ -0,0 +1,41 @@ +# $Date: 2009-02-17 21:22:13 +0200 (Di, 17 Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/../../../../../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LANG = ÃeÓtina + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigOS4 + +LANG = czech + +else + +############################################################################### +# AmigaOS and AROS + +LANG = ÃeÓtina + +endif +endif diff --git "a/scalos/Prefs/Pattern/Catalogs/\303\203e\303\223tina/Scalos/makefile" "b/scalos/Prefs/Pattern/Catalogs/\303\203e\303\223tina/Scalos/makefile" new file mode 100644 index 000000000..564cc41a7 --- /dev/null +++ "b/scalos/Prefs/Pattern/Catalogs/\303\203e\303\223tina/Scalos/makefile" @@ -0,0 +1,12 @@ +# makefile für Scalos (translated Texts : ÃeÓtina) +# 01 Jan 2004 12:45:33 + +.SUFFIXES: .ct .catalog + +.ct.catalog : + CatComp ///$*.cd $*.ct CATALOG $*.catalog VB=2 + avail flush + +ScalosPattern.catalog : ScalosPattern.ct ../../../ScalosPattern.cd + +All: ScalosPattern.catalog diff --git "a/scalos/Prefs/Pattern/Catalogs/\303\203e\303\223tina/Scalos/makefile-new" "b/scalos/Prefs/Pattern/Catalogs/\303\203e\303\223tina/Scalos/makefile-new" new file mode 100755 index 000000000..10e001fd6 --- /dev/null +++ "b/scalos/Prefs/Pattern/Catalogs/\303\203e\303\223tina/Scalos/makefile-new" @@ -0,0 +1,32 @@ +# makefile for ScalosPattern (translated Texts : ÃeÓtina) +# $Date: 2011-08-06 19:37:48 +0200 (Sa, 06. Aug 2011) $ + +.SUFFIXES: .ct .catalog +.PHONY: all install clean + +include config.mk + +CATNAME = ScalosPattern + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + CDPATH=// +else + CDPATH=../../.. +endif + +all: $(CATNAME).catalog + + +.ct.catalog : + @printf '\033[32mMake catalog: \033[31m\033[1m$(LANG)\033[0m\n' + $(FLEXCAT) $(CDPATH)/$*.cd $*.ct CATALOG $*.catalog + +$(CATNAME).catalog : $(CATNAME).ct ../../../$(CATNAME).cd + + +clean: + $(RM) -f $(CATNAME).catalog + +install: + -copy $(CATNAME).catalog Locale:catalogs/$(LANG)/Scalos/ clone diff --git a/scalos/Prefs/Pattern/Pattern.c b/scalos/Prefs/Pattern/Pattern.c new file mode 100644 index 000000000..9baded788 --- /dev/null +++ b/scalos/Prefs/Pattern/Pattern.c @@ -0,0 +1,923 @@ +// Pattern.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include // +jmc+ + +#include +#include +#include + +#include "Pattern.h" + +#define ScalosPattern_NUMBERS +#define ScalosPattern_ARRAY +#define ScalosPattern_CODE +#include STR(SCALOSLOCALE) + +//---------------------------------------------------------------------------- + +#define Sizeof(array) (sizeof(array) / sizeof((array)[0])) + +//---------------------------------------------------------------------------- + +#if !defined(__amigaos4__) && !defined(__AROS__) +#include + +long _stack = 32768; // minimum stack size, used by SAS/C startup code +#endif + +//---------------------------------------------------------------------------- + +// local data structures + +#define KeyButtonHelp(name,key,HelpText)\ + TextObject,\ + ButtonFrame,\ + MUIA_Font, MUIV_Font_Button,\ + MUIA_Text_Contents, name,\ + MUIA_Text_PreParse, "\33c",\ + MUIA_Text_HiChar , key,\ + MUIA_ControlChar , key,\ + MUIA_CycleChain , TRUE, \ + MUIA_InputMode , MUIV_InputMode_RelVerify,\ + MUIA_Background , MUII_ButtonBack,\ + MUIA_ShortHelp, HelpText,\ + End + +#define Application_Return_EDIT 0 +#define Application_Return_USE 1001 +#define Application_Return_SAVE 1002 + +//---------------------------------------------------------------------------- + +// local functions + +static void init(void); +static void fail(APTR APP_Main, CONST_STRPTR str); +static BOOL OpenLibraries(void); +static void CloseLibraries(void); +static SAVEDS(APTR) INTERRUPT OpenAboutMUIFunc(struct Hook *hook, Object *o, Msg msg); +static STRPTR GetLocString(ULONG MsgId); +//static void TranslateStringArray(STRPTR *stringArray); +static struct MUI_CustomClass *OpenPrefsModule(CONST_STRPTR FileName); +static struct TagItem *CreatePluginSubWindowArray(void); +static void DisposePrefsPlugin(void); +static BOOL CheckMCCforPlugin(STRPTR *UsedClasses, size_t MaxUsedClasses); +static BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev); +#if !defined(__SASC) && !defined(__MORPHOS__) && !defined(__amigaos4__) +size_t stccpy(char *dest, const char *src, size_t MaxLen); +#endif /* !defined(__SASC) && !defined(__MORPHOS__) && !defined(__amigaos4__) */ + +//---------------------------------------------------------------------------- + +// local data items + +struct Library *MUIMasterBase; +T_LOCALEBASE LocaleBase; +struct Library *IconBase; +struct IntuitionBase *IntuitionBase; +struct Library *ScalosPrefsPluginBase; + +#ifdef __amigaos4__ +extern struct Library *SysBase; +struct MUIMasterIFace *IMUIMaster; +struct LocaleIFace *ILocale; +struct IconIFace *IIcon; +struct IntuitionIFace *IIntuition; +struct ScalosPrefsPluginIFace *IScalosPrefsPlugin; +#endif + +static struct Catalog *PatternCatalog; + +static struct Hook OpenAboutMUIHook = { { NULL, NULL }, HOOKFUNC_DEF(OpenAboutMUIFunc), NULL }; + +static struct MUI_CustomClass *PatternPluginClass; + +static struct TagItem *SubWindowTagList; + +static Object **PluginSubWindows; +static Object *APP_Main; +static Object *WIN_Main; +static Object *WIN_AboutMUI; +static Object *Group_Plugin; +static Object *SaveButton, *UseButton, *CancelButton; +static Object *MenuOpen, *MenuSaveAs, *MenuAbout, *MenuAboutMUI, *MenuQuit; +static Object *MenuResetToDefaults, *MenuLastSaved, *MenuRestore; +static Object *MenuCreateIcons; + +//---------------------------------------------------------------------------- + +int main(int argc, char *argv[]) +{ + LONG Action = Application_Return_EDIT; + LONG win_opened = 0; + struct RDArgs *rdArgs = NULL; + CONST_STRPTR GivenFileName = NULL; + BPTR oldDir = (BPTR)NULL; + ULONG fCreateIcons = TRUE; + struct DiskObject *PatternDiskObject = NULL; + STRPTR ProgramName; + STRPTR UsedClasses[32]; + BOOL fAutoPreview = FALSE; + BOOL fPreview = TRUE; + BOOL fThumbnails = FALSE; + ULONG PreviewWeight = 20; + struct WBStartup *WBenchMsg = + (argc == 0) ? (struct WBStartup *)argv : NULL; + + init(); + + if (WBenchMsg && WBenchMsg->sm_ArgList) + { + static char PrgNamePath[512]; + struct WBArg *arg; + struct DiskObject *icon; + + if (WBenchMsg->sm_NumArgs > 1) + { + arg = &WBenchMsg->sm_ArgList[1]; + GivenFileName = arg->wa_Name; + } + else + { + arg = &WBenchMsg->sm_ArgList[0]; + } + + ProgramName = PrgNamePath; + + NameFromLock(WBenchMsg->sm_ArgList[0].wa_Lock, PrgNamePath, sizeof(PrgNamePath)); + AddPart(PrgNamePath, WBenchMsg->sm_ArgList[0].wa_Name, sizeof(PrgNamePath)); + + oldDir = CurrentDir(arg->wa_Lock); + + icon = GetDiskObject(arg->wa_Name); + if (icon) + { + STRPTR tt; + + tt = FindToolType(icon->do_ToolTypes, "CREATEICONS"); + if (tt) + { + if (MatchToolValue(tt, "NO")) + fCreateIcons = FALSE; + } + + tt = FindToolType(icon->do_ToolTypes, "ACTION"); + if (tt) + { + if (MatchToolValue(tt, "EDIT")) + Action = Application_Return_EDIT; + if (MatchToolValue(tt, "USE")) + Action = Application_Return_USE; + if (MatchToolValue(tt, "SAVE")) + Action = Application_Return_SAVE; + } + + tt = FindToolType(icon->do_ToolTypes, "THUMBNAILS"); + if (tt) + fThumbnails = TRUE; + + tt = FindToolType(icon->do_ToolTypes, "AUTOPREVIEW"); + if (tt) + fAutoPreview = TRUE; + + tt = FindToolType(icon->do_ToolTypes, "PREVIEWWEIGHT"); + if (tt) + StrToLong(tt, (LONG *) &PreviewWeight); + + tt = FindToolType(icon->do_ToolTypes, "NOPREVIEW"); + if (tt) + fPreview = FALSE; + + FreeDiskObject(icon); + } + } + else + { + SIPTR ArgArray[7]; + + ProgramName = argv[0]; + + memset(ArgArray, 0, sizeof(ArgArray)); + + rdArgs = ReadArgs("FROM,EDIT/S,USE/S,SAVE/S,NOPREVIEW/S,AUTOPREVIEW/S,PW=PREVIEWWEIGHT/N/K", ArgArray, NULL); + + if (ArgArray[0]) + GivenFileName = (CONST_STRPTR) ArgArray[0]; + if (ArgArray[1]) + Action = Application_Return_EDIT; + if (ArgArray[2]) + Action = Application_Return_USE; + if (ArgArray[3]) + Action = Application_Return_SAVE; + if (ArgArray[4]) + fPreview = FALSE; + if (ArgArray[5]) + fAutoPreview = TRUE; + if (ArgArray[6]) + PreviewWeight = *((ULONG *) ArgArray[6]); + } + + if (NULL == PatternPluginClass) + fail(APP_Main, "Failed to open Pattern Plugin."); + + PatternDiskObject = GetDiskObject(ProgramName); + + Group_Plugin = NewObject(PatternPluginClass->mcc_Class, 0, + MUIA_ScalosPrefs_CreateIcons, fCreateIcons, + MUIA_ScalosPrefs_ProgramName, (ULONG) ProgramName, + MUIA_ScalosPrefs_PatternPrefs_Preview, fPreview, + MUIA_ScalosPrefs_PatternPrefs_AutoPreview, fAutoPreview, + MUIA_ScalosPrefs_PatternPrefs_PreviewWeight, PreviewWeight, + MUIA_ScalosPrefs_PatternPrefs_Thumbnails, fThumbnails, + TAG_END); + if (NULL == Group_Plugin) + fail(APP_Main, "Failed to create Group_Plugin."); + + if (!CheckMCCforPlugin(UsedClasses, Sizeof(UsedClasses))) + fail(APP_Main, "Required MCC missing."); + + SubWindowTagList = CreatePluginSubWindowArray(); + + APP_Main = ApplicationObject, + MUIA_Application_Title, GetLocString(MSGID_TITLENAME), + MUIA_Application_Version, "$VER: Scalos Pattern 40.21 (" __DATE__ ")" COMPILER_STRING, + MUIA_Application_Copyright, "The Scalos Team, 2000" CURRENTYEAR, + MUIA_Application_Author, "The Scalos Team", + MUIA_Application_Description, "Scalos Pattern preferences editor", + MUIA_Application_Base, "SCALOS_PATTERN", + PatternDiskObject ? MUIA_Application_DiskObject : TAG_IGNORE, PatternDiskObject, +#if defined(MUIA_Application_UsedClasses) + MUIA_Application_UsedClasses, UsedClasses, +#endif /* MUIA_Application_UsedClasses */ + + SubWindow, WIN_Main = WindowObject, + MUIA_Window_Title, GetLocString(MSGID_TITLENAME), + MUIA_Window_ID, MAKE_ID('M','A','I','N'), + MUIA_Window_AppWindow, TRUE, + + WindowContents, VGroup, + Child, Group_Plugin, + Child, ColGroup(3), + Child, SaveButton = KeyButtonHelp(GetLocString(MSGID_SAVEBUTTON), + 's', GetLocString(MSGID_SHORTHELP_SAVEBUTTON)), + Child, UseButton = KeyButtonHelp(GetLocString(MSGID_USEBUTTON), + 'u', GetLocString(MSGID_SHORTHELP_USEBUTTON)), + Child, CancelButton = KeyButtonHelp(GetLocString(MSGID_CANCELBUTTON), + 'c', GetLocString(MSGID_SHORTHELP_CANCELBUTTON)), + End, + End, + End, + + MUIA_Application_Menustrip, MenustripObject, + Child, MenuObjectT(GetLocString(MSGID_MENU_PROJECT)), + Child, MenuOpen = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_OPEN), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_PROJECT_OPEN_SHORT), + End, + Child, MenuSaveAs = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_SAVEAS), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_PROJECT_SAVEAS_SHORT), + End, + Child, MenuitemObject, + MUIA_Menuitem_Title, -1, + End, + Child, MenuAbout = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUT), + End, + Child, MenuAboutMUI = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUTMUI), + End, + Child, MenuitemObject, + MUIA_Menuitem_Title, -1, + End, + Child, MenuQuit = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_QUIT), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_PROJECT_QUIT_SHORT), + End, + + End, //MenuObjectT + Child, MenuObjectT(GetLocString(MSGID_MENU_EDIT)), + Child, MenuResetToDefaults = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_EDIT_RESETTODEFAULTS), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT), + End, + Child, MenuLastSaved = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_EDIT_LASTSAVED), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_EDIT_LASTSAVED_SHORT), + End, + Child, MenuRestore = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_EDIT_RESTORE), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_EDIT_RESTORE_SHORT), + End, + End, //MenuObjectT + Child, MenuObjectT(GetLocString(MSGID_MENU_SETTINGS)), + Child, MenuCreateIcons = MenuitemObject, + MUIA_Menuitem_Title, GetLocString(MSGID_MENU_SETTINGS_CREATEICONS), + MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_SETTINGS_CREATEICONS_SHORT), + MUIA_Menuitem_Checkit, TRUE, + MUIA_Menuitem_Checked, fCreateIcons, + End, + End, //MenuObjectT + End, + + SubWindowTagList ? TAG_MORE : TAG_IGNORE, SubWindowTagList, + End; //ApplicationObject + + if (NULL == APP_Main) + { + MUI_DisposeObject(Group_Plugin); + Group_Plugin = NULL; + fail(APP_Main, "Failed to create Application."); + } + + set(Group_Plugin, MUIA_ScalosPrefs_MainWindow, (ULONG) WIN_Main); + set(Group_Plugin, MUIA_ScalosPrefs_Application, (ULONG) APP_Main); + + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + WIN_Main, 3, MUIM_Set, MUIA_Window_Open, FALSE); + DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + DoMethod(CancelButton, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + DoMethod(MenuQuit, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + DoMethod(SaveButton, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_Application_ReturnID, Application_Return_SAVE); + DoMethod(UseButton, MUIM_Notify, MUIA_Pressed, FALSE, + APP_Main, 2, MUIM_Application_ReturnID, Application_Return_USE); + + + DoMethod(MenuQuit, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); + + DoMethod(MenuOpen, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + Group_Plugin, 1, MUIM_ScalosPrefs_OpenConfig); + + DoMethod(MenuSaveAs, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + Group_Plugin, 1, MUIM_ScalosPrefs_SaveConfigAs); + + DoMethod(MenuResetToDefaults, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + Group_Plugin, 1, MUIM_ScalosPrefs_ResetToDefaults); + + DoMethod(MenuLastSaved, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + Group_Plugin, 1, MUIM_ScalosPrefs_LastSavedConfig); + + DoMethod(MenuRestore, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + Group_Plugin, 1, MUIM_ScalosPrefs_RestoreConfig); + + DoMethod(MenuAbout, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + Group_Plugin, 1, MUIM_ScalosPrefs_About); + + DoMethod(MenuAboutMUI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, + APP_Main, 2, MUIM_CallHook, &OpenAboutMUIHook); + + DoMethod(MenuCreateIcons, MUIM_Notify, MUIA_Menuitem_Checked, MUIV_EveryTime, + Group_Plugin, 3, MUIM_Set, MUIA_ScalosPrefs_CreateIcons, MUIV_TriggerValue); + + if (Application_Return_EDIT == Action) + set(WIN_Main, MUIA_Window_Open, TRUE); + + if (GivenFileName) + { + DoMethod(Group_Plugin, MUIM_ScalosPrefs_LoadNamedConfig, GivenFileName); + } + else + { + DoMethod(Group_Plugin, MUIM_ScalosPrefs_LoadConfig); + } + + if (Application_Return_EDIT == Action) + { + set(WIN_Main, MUIA_Window_Open, TRUE); + + get(WIN_Main, MUIA_Window_Open, &win_opened); + + if (win_opened) + { + ULONG sigs = 0; + BOOL Run = TRUE; + + while (Run) + { + Action = DoMethod(APP_Main, MUIM_Application_NewInput, &sigs); + + switch (Action) + { + case MUIV_Application_ReturnID_Quit: + case Application_Return_SAVE: + case Application_Return_USE: + Run = FALSE; + break; + } + + if (Run && sigs) + { + sigs = Wait(sigs | SIGBREAKF_CTRL_C); + + if (sigs & SIGBREAKF_CTRL_C) + { + Run = FALSE; + break; + } + } + } + } + else + { + printf("failed to open main window !\n"); + } + } + + switch (Action) + { + case Application_Return_SAVE: + DoMethod(Group_Plugin, MUIM_ScalosPrefs_SaveConfig); + break; + case Application_Return_USE: + DoMethod(Group_Plugin, MUIM_ScalosPrefs_UseConfig); + break; + } + + set(WIN_Main, MUIA_Window_Open, FALSE); + + if (PatternDiskObject) + FreeDiskObject(PatternDiskObject); + if (oldDir) + CurrentDir(oldDir); + if (rdArgs) + FreeArgs(rdArgs); + + fail(APP_Main, NULL); + + return 0; +} + + +static VOID fail(APTR APP_Main, CONST_STRPTR str) +{ + if (APP_Main) + MUI_DisposeObject(APP_Main); + + DisposePrefsPlugin(); + + if (PatternCatalog) + { + CloseCatalog(PatternCatalog); + PatternCatalog = NULL; + } + + CloseLibraries(); + + if (str) + { + puts(str); + exit(20); + } + + exit(0); +} + + +static void init(void) +{ + APP_Main = NULL; + + if (!OpenLibraries()) + fail(NULL, "Failed to open "MUIMASTER_NAME"."); + + if (LocaleBase) + PatternCatalog = OpenCatalogA(NULL, "Scalos/ScalosPattern.catalog", NULL); + + PatternPluginClass = OpenPrefsModule("Pattern.prefsplugin"); +} + + +static BOOL OpenLibraries(void) +{ + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + if (NULL == IntuitionBase) + return FALSE; +#ifdef __amigaos4__ + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + return FALSE; +#endif + + MUIMasterBase = OpenLibrary("zune.library", 0); + if (NULL == MUIMasterBase) + MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN-1); + if (NULL == MUIMasterBase) + return FALSE; +#ifdef __amigaos4__ + IMUIMaster = (struct MUIMasterIFace *)GetInterface((struct Library *)MUIMasterBase, "main", 1, NULL); + if (NULL == IMUIMaster) + return FALSE; +#endif + + IconBase = OpenLibrary("icon.library", 0); + if (NULL == IconBase) + return FALSE; +#ifdef __amigaos4__ + IIcon = (struct IconIFace *)GetInterface((struct Library *)IconBase, "main", 1, NULL); + if (NULL == IIcon) + return FALSE; +#endif + + LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 39); +#ifdef __amigaos4__ + if (LocaleBase) + ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL); +#endif + + return TRUE; +} + + +static void CloseLibraries(void) +{ +#ifdef __amigaos4__ + if (ILocale) + { + DropInterface((struct Interface *)ILocale); + ILocale = NULL; + } +#endif + if (LocaleBase) + { + CloseLibrary((struct Library *) LocaleBase); + LocaleBase = NULL; + } +#ifdef __amigaos4__ + if (IIcon) + { + DropInterface((struct Interface *)IIcon); + IIcon = NULL; + } +#endif + if (IconBase) + { + CloseLibrary(IconBase); + IconBase = NULL; + } +#ifdef __amigaos4__ + if (IMUIMaster) + { + DropInterface((struct Interface *)IMUIMaster); + IMUIMaster = NULL; + } +#endif + if (MUIMasterBase) + { + CloseLibrary(MUIMasterBase); + MUIMasterBase = NULL; + } +#ifdef __amigaos4__ + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } +#endif + if (IntuitionBase) + { + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } +} + +//---------------------------------------------------------------------------- + +static STRPTR GetLocString(ULONG MsgId) +{ + struct ScalosPattern_LocaleInfo li; + + li.li_Catalog = PatternCatalog; +#ifndef __amigaos4__ + li.li_LocaleBase = LocaleBase; +#else + li.li_ILocale = ILocale; +#endif + + return (STRPTR) GetScalosPatternString(&li, MsgId); +} + +/* +static void TranslateStringArray(STRPTR *stringArray) +{ + while (*stringArray) + { + *stringArray = GetLocString((ULONG) *stringArray); + stringArray++; + } +} +*/ +//---------------------------------------------------------------------------- + +static SAVEDS(APTR) INTERRUPT OpenAboutMUIFunc(struct Hook *hook, Object *o, Msg msg) +{ + if (NULL == WIN_AboutMUI) + { + WIN_AboutMUI = MUI_NewObject(MUIC_Aboutmui, + MUIA_Window_RefWindow, WIN_Main, + MUIA_Aboutmui_Application, APP_Main, + End; + } + + if (WIN_AboutMUI) + set(WIN_AboutMUI, MUIA_Window_Open, TRUE); + + return 0; +} + +//---------------------------------------------------------------------------- + +static struct MUI_CustomClass *OpenPrefsModule(CONST_STRPTR FileName) +{ + struct MUI_CustomClass *pclass = NULL; + + d1(kprintf(__FUNC__ "/%ld: FileName=<%s>\n", __LINE__, FileName)); + + do { + ScalosPrefsPluginBase = OpenLibrary(FileName, 0); + d1(kprintf(__FUNC__ "/%ld: ScalosPrefsPluginBase=%08lx\n", __LINE__, ScalosPrefsPluginBase)); + if (NULL == ScalosPrefsPluginBase) + break; +#ifdef __amigaos4__ + IScalosPrefsPlugin = (struct ScalosPrefsPluginIFace *)GetInterface( + ScalosPrefsPluginBase, "main", 1, NULL + ); +#endif + + pclass = (struct MUI_CustomClass *) SCAGetPrefsInfo(SCAPREFSINFO_GetClass); + d1(kprintf(__FUNC__ "/%ld: PluginClass=%08lx\n", __LINE__, ppl->ppl_PluginClass)); + if (NULL == pclass) + break; + } while (0); + + if (NULL == pclass) + DisposePrefsPlugin(); + + return pclass; +} + + +static struct TagItem *CreatePluginSubWindowArray(void) +{ + struct TagItem *SubWindowTagList; + struct TagItem *ti; + ULONG SubWindowCount = 0; + ULONG n; + + PluginSubWindows = (Object **) DoMethod(Group_Plugin, MUIM_ScalosPrefs_CreateSubWindows); + + for (n=0; PluginSubWindows && PluginSubWindows[n]; n++) + SubWindowCount++; + + SubWindowTagList = ti = calloc(1 + SubWindowCount, sizeof(struct TagItem)); + if (NULL == SubWindowTagList) + return NULL; + + for (n=0; PluginSubWindows && PluginSubWindows[n]; n++) + { + ti->ti_Tag = MUIA_Application_Window; + ti->ti_Data = (ULONG) PluginSubWindows[n]; + ti++; + } + + ti->ti_Tag = TAG_END; + + return SubWindowTagList; +} + + +static void DisposePrefsPlugin(void) +{ + if (SubWindowTagList) + { + free(SubWindowTagList); + SubWindowTagList = NULL; + } +#ifdef __amigaos4__ + if (IScalosPrefsPlugin) + { + DropInterface((struct Interface *)IScalosPrefsPlugin); + IScalosPrefsPlugin = NULL; + } +#endif + if (ScalosPrefsPluginBase) + { + d1(kprintf(__FUNC__ "/%ld: Plugin=<%s> OpenCount=%ld\n", \ + __LINE__, ScalosPrefsPluginBase->lib_Node.ln_Name, ScalosPrefsPluginBase->lib_OpenCnt)); + + if (NULL == Group_Plugin) + CloseLibrary(ScalosPrefsPluginBase); + ScalosPrefsPluginBase = NULL; + } +} + +static BOOL CheckMCCforPlugin(STRPTR *UsedClasses, size_t MaxUsedClasses) +{ + const struct MUIP_ScalosPrefs_MCCList *RequiredMccList = NULL; + + RequiredMccList = (const struct MUIP_ScalosPrefs_MCCList *) DoMethod(Group_Plugin, MUIM_ScalosPrefs_GetListOfMCCs); + + while (RequiredMccList && RequiredMccList->MccName) + { + if (!CheckMCCVersion(RequiredMccList->MccName, + RequiredMccList->MccMinVersion, + RequiredMccList->MccMinRevision)) + return FALSE; + + if (MaxUsedClasses > 1) + { + *UsedClasses++ = (STRPTR) RequiredMccList->MccName; + MaxUsedClasses--; + } + + RequiredMccList++; + } + + *UsedClasses = NULL; + + return TRUE; +} + +//---------------------------------------------------------------------------- + +// Checks if a certain version of a MCC is available +static BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev) +{ + BOOL flush = TRUE; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: %s ", name, __LINE__);) + + while (1) + { + ULONG ver = 0; + ULONG rev = 0; + struct Library *base; + char libname[256]; + + // First we attempt to acquire the version and revision through MUI + Object *obj = MUI_NewObject((STRPTR) name, TAG_DONE); + if (obj) + { + get(obj, MUIA_Version, &ver); + get(obj, MUIA_Revision, &rev); + + MUI_DisposeObject(obj); + + if(ver > minver || (ver == minver && rev >= minrev)) + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: v%ld.%ld found through MUIA_Version/Revision\n", __LINE__, ver, rev);) + return TRUE; + } + } + + // If we did't get the version we wanted, let's try to open the + // libraries ourselves and see what happens... + stccpy(libname, "PROGDIR:mui", sizeof(libname)); + AddPart(libname, name, sizeof(libname)); + + if ((base = OpenLibrary(&libname[8], 0)) || (base = OpenLibrary(&libname[0], 0))) + { + UWORD OpenCnt = base->lib_OpenCnt; + + ver = base->lib_Version; + rev = base->lib_Revision; + + CloseLibrary(base); + + // we add some additional check here so that eventual broken .mcc also have + // a chance to pass this test (i.e. Toolbar.mcc is broken) + if (ver > minver || (ver == minver && rev >= minrev)) + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: v%ld.%ld found through OpenLibrary()\n", __LINE__, ver, rev);) + return TRUE; + } + + if (OpenCnt > 1) + { + if (MUI_Request(NULL, NULL, 0L, GetLocString(MSGID_STARTUP_FAILURE), + GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), GetLocString(MSGID_STARTUP_MCC_IN_USE), + (ULONG) name, minver, minrev, ver, rev)) + { + flush = TRUE; + } + else + break; + } + + // Attempt to flush the library if open count is 0 or because the + // user wants to retry (meaning there's a chance that it's 0 now) + + if (flush) + { + struct Library *result; + + Forbid(); + if ((result = (struct Library *) FindName(&((struct ExecBase *)SysBase)->LibList, name))) + RemLibrary(result); + Permit(); + flush = FALSE; + } + else + { + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: couldn`t find minimum required version.\n", __LINE__);) + + // We're out of luck - open count is 0, we've tried to flush + // and still haven't got the version we want + if (MUI_Request(NULL, NULL, 0L, GetLocString(MSGID_STARTUP_FAILURE), + GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), GetLocString(MSGID_STARTUP_OLD_MCC), + (ULONG) name, minver, minrev, ver, rev)) + { + flush = TRUE; + } + else + break; + } + } + else + { + // No MCC at all - no need to attempt flush + flush = FALSE; + if (!MUI_Request(NULL, NULL, 0L, GetLocString(MSGID_STARTUP_FAILURE), + GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD), GetLocString(MSGID_STARTUP_MCC_NOT_FOUND), + (ULONG) name, minver, minrev)) + { + break; + } + } + } + + return FALSE; +} + +//---------------------------------------------------------------------------- + +#if !defined(__SASC) && !defined(__amigaos4__) +// Replacement for SAS/C library functions + +#if !defined(__MORPHOS__) +// Replacement for SAS/C library functions + +size_t stccpy(char *dest, const char *src, size_t MaxLen) +{ + size_t Count = 0; + + while (*src && MaxLen > 1) + { + *dest++ = *src++; + MaxLen--; + Count++; + } + *dest = '\0'; + Count++; + + return Count; +} +#endif /*__MORPHOS__*/ + +#endif /* !defined(__SASC) && !defined(__amigaos4__) */ +//----------------------------------------------------------------------------- diff --git a/scalos/Prefs/Pattern/Pattern.h b/scalos/Prefs/Pattern/Pattern.h new file mode 100755 index 000000000..f9e621416 --- /dev/null +++ b/scalos/Prefs/Pattern/Pattern.h @@ -0,0 +1,25 @@ +// Pattern.c +// $Date$ +// $Revision$ + +//---------------------------------------------------------------------------- + +#undef d1 +#undef d2 + +#define d1(x) ; +#define d2(x) x; + +// from debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +struct ScalosPattern_LocaleInfo +{ + APTR li_LocaleBase; + APTR li_Catalog; + struct LocaleIFace *li_ILocale; +}; + +//---------------------------------------------------------------------------- + diff --git a/scalos/Prefs/Pattern/ScalosPattern.cd b/scalos/Prefs/Pattern/ScalosPattern.cd new file mode 100755 index 000000000..fb46ea8c6 --- /dev/null +++ b/scalos/Prefs/Pattern/ScalosPattern.cd @@ -0,0 +1,648 @@ +; ScalosPattern.cd +; version $VER: ScalosPattern.catalog 40.12 (15 May 2005 09:34:29) +; codeset 0s +; language english +; +;#arrayopts static __far +; +; +; +; +MSGID_TITLENAME (//) +Scalos Pattern Prefs Plugin +; +; +MSGID_REGISTER_PATTERNLIST (//) +Pattern List +; +; +MSGID_REMAPNAME (//) +No remap: +; +; +MSGID_RENDERTYPE_TILED (//) +Tiled +; +; +MSGID_NEWNAME (//) +New \033I[6:19] +; +; +MSGID_SHORTHELP_NEWBUTTON (//) +Press this button to create a \n\ +new pattern entry +; +; +MSGID_DELNAME (//) +Delete +; +; +MSGID_SHORTHELP_DELBUTTON (//) +Press this button to delete the \n\ +currently selected pattern entry. +; +; +MSGID_SAVEBUTTON (//) +Save +; +; +MSGID_SHORTHELP_SAVEBUTTON (//) +Press this button to save \n\ +the current settings to\n\ +\"ENVARC:Scalos/Pattern.prefs\"\n\ +and make changes permanent. +; +; +MSGID_USEBUTTON (//) +Use +; +; +MSGID_SHORTHELP_USEBUTTON (//) +Press this button to save \n\ +the current settings to\n\ +\"ENV:Scalos/Pattern.prefs\"\n\ +and keep settings until reboot. +; +; +MSGID_CANCELBUTTON (//) +Cancel +; +; +MSGID_SHORTHELP_CANCELBUTTON (//) +Press this button to abort \n\ +and discard all changes. +; +; +MSGID_SCREENNAME (//) +Workbench +; +; +MSGID_WINDOWNAME (//) +Window +; +; +MSGID_MENU_PROJECT_OPEN (//) +Open... +; +; +MSGID_MENU_PROJECT_OPEN_SHORT (/1/1) +O +; +; +MSGID_MENU_PROJECT_SAVEAS (//) +Save As... +; +; +MSGID_MENU_PROJECT_SAVEAS_SHORT (/1/1) +A +; +; +MSGID_MENU_PROJECT_QUIT (//) +Quit +; +; +MSGID_MENU_PROJECT_QUIT_SHORT (/1/1) +Q +; +; +MSGID_MENU_PROJECT (//) +Project +; +; +MSGID_MENU_EDIT_LASTSAVED (//) +Last Saved +; +; +MSGID_MENU_EDIT_LASTSAVED_SHORT (/1/1) +L +; +; +MSGID_MENU_EDIT (//) +Edit +; +; +MSGID_MENU_SETTINGS_CREATEICONS (//) +Create Icons? +; +; +MSGID_MENU_SETTINGS_CREATEICONS_SHORT (/1/1) +I +; +; +MSGID_MENU_SETTINGS (//) +Settings +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS (//) +Reset To Defaults +; +; +MSGID_MENU_EDIT_RESETTODEFAULTS_SHORT (/1/1) +D +; +; +MSGID_MENU_EDIT_RESTORE (//) +Restore +; +; +MSGID_MENU_EDIT_RESTORE_SHORT (/1/1) +R +; +; +MSGID_MENU_PROJECT_ABOUTMUI (//) +About MUI... +; +; +MSGID_RENDERTYPE_FITSIZE (//) +Fit Size +; +; +MSGID_CENTEREDNAME (//) +Centered +; +; +MSGID_PRECEXACTNAME (//) +Exact +; +; +MSGID_PRECIMAGENAME (//) +Image +; +; +MSGID_PRECICONNAME (//) +Icon +; +; +MSGID_PRECGUINAME (//) +GUI +; +; +MSGID_PRECNAME (//) +Pen Precision: +; +; +MSGID_ENHANCNAME (//) +use GUIGfx: +; +; +MSGID_NUMCOLSNAME (//) +Color weight: +; +; +MSGID_ENHANCOPTSNAME (//) +GUIGfx Options +; +; +MSGID_AUTODITHERNAME (//) +AutoDither: +; +; +MSGID_DITHERMODENAME (//) +Dithering: +; +; +MSGID_DITHERAMOUNTNAME (//) +Ditheramount: +; +; +MSGID_DITHERMODE1NAME (//) +None +; +; +MSGID_DITHERMODE2NAME (//) +Floyd Steinberg +; +; +MSGID_DITHERMODE3NAME (//) +Random +; +; +MSGID_PICTURENAME (//) +Picture: +; +; +MSGID_PATTERNNAME (//) +Pattern +; +; +MSGID_REGISTER_DEFAULTS (//) +Defaults +; +; +MSGID_DEFWBNAME (//) +Desktop: +; +; +MSGID_DEFSCREENNAME (//) +Screen: +; +; +MSGID_DEFWINNAME (//) +Window: +; +; +MSGID_ASYNCNAME (//) +asynchronous layout: +; +; +MSGID_FRIENDNAME (//) +use friend bitmap: +; +; +MSGID_NONE_PRIORITY (//) +none +; +; +MSGID_RELAYOUTNAME (//) +always relayout: +; +; +MSGID_RANDOMNAME (//) +randomize everytime: +; +; +MSGID_TASKPRINAME (//) +Asynchronous Task priority: +; +; +MSGID_TEXTNAME (+2//) +Text Mode: +; +; +MSGID_CHECKMARKGADBUBBLE (//) +Don't remap the colors\n\ +of the picture if set. +; +; +MSGID_CHECKMARKASYNCBUBBLE (//) +Render the picture while reading\n\ +the icons instead of waiting for\n\ +the layout to finish before\n\ +opening the window if set. +; +; +MSGID_CHECKMARKFRIENDBUBBLE (//) +Speed up the pattern refresh\n\ +by using a second bitmap if set.\n\ +This is ignored if you use\n\ +a V43 picture.datatype or\n\ +GUIGFX because they do it\n\ +themselves. +; +; +MSGID_CHECKMARKENHBUBBLE (//) +The GUIGFX library gives you\n\ +some very fast routines e.g. for\n\ +colorreduction and dithering.\n\ +Use guigfx.library if set. +; +; +MSGID_CHECKMARKAUTODITHERBUBBLE (//) +If set, dithering will be enabled\n\ +automatically if the picture would\n\ +loose too many pens. +; +; +MSGID_CHECKMARKRELAYOUTBUBBLE (//) +Scales the picture again if you\n\ +change the window size if set. +; +; +MSGID_CHECKMARKRANDOMBUBBLE (//) +Selects one of the random patterns\n\ +everytime you open a window instead\n\ +of randomizing the patterns only at\n\ +startup if set. +; +; +MSGID_SAVEBUTTONBUBBLE (//) +Save settings and quit. +; +; +MSGID_USEBUTTONBUBBLE (//) +Use settings and quit. +; +; +MSGID_CANCELBUTTONBUBBLE (//) +Quit without saving. +; +; +MSGID_NUMBUTTONBUBBLE (//) +The number assigns the pattern\n\ +to the Desktop, Screen, Window\n\ +and/or Textmode of the Defaults\n\ +page. +; +; +MSGID_PRECSLIDERBUBBLE (//) +Select the precision of the\n\ +pens for the picture. +; +; +MSGID_COLORSSLIDERBUBBLE (//) +How many free pens should\n\ +be used for the picture. +; +; +MSGID_CYCLEDITHERMODEBUBBLE (//) +The routine that is used when\n\ +there is no free pen. In that\n\ +case a color is made of many\n\ +points with different colors\n\ +close to each other. +; +; +MSGID_SLIDERDITHERAMOUNTBUBBLE (//) +A parameter for the dithering\n\ +routine. +; +; +MSGID_SLIDERWBBUBBLE (//) +The number that should be used for\n\ +the Desktop pattern to get assigned.\n\ +A pattern with the assigned number\n\ +one and a one selected for Desktop\n\ +and Window means that the Window\n\ +and Desktop patterns should be that\n\ +pattern.\n\ +All patterns with the same\n\ +number are selected by random. +; +; +MSGID_SLIDERSCREENBUBBLE (//) +The number that should be used for\n\ +the Screen pattern to get assigned.\n\ +A pattern with the assigned number\n\ +one and a one selected for Desktop\n\ +and Window means that the Window\n\ +and Desktop patterns should be that\n\ +pattern.\n\ +All patterns with the same\n\ +number are selected by random. +; +; +MSGID_SLIDERWINBUBBLE (//) +The number that should be used for\n\ +the Window pattern to get assigned.\n\ +A pattern with the assigned number\n\ +one and a one selected for Desktop\n\ +and Window means that the Window\n\ +and Desktop patterns should be that\n\ +pattern.\n\ +All patterns with the same\n\ +number are selected by random. +; +; +MSGID_SLIDERTEXTBUBBLE (//) +The number that should be used for\n\ +the Textmode pattern to get assigned.\n\ +A pattern with the assigned number\n\ +one and a one selected for Desktop\n\ +and Window means that the Window\n\ +and Desktop patterns should be that\n\ +pattern.\n\ +(Window Menu: View by >> Text)\n\ +All patterns with the same\n\ +number are selected by random. +; +; +MSGID_SLIDERTASKPRIBUBBLE (//) +Task priority of the\n\ +asynclayout task. +; +; +MSGID_PREVIEWIMAGEBUBBLE (//) +Click here to see\n\ +the selected picture. +; +; +MSGID_CYCLEGADBUBBLE (//) +Do you want a pattern to be scaled\n\ +(\"Fit Size\") or do you want a pattern\n\ +to be made of many instances of that\n\ +pattern put together like a mosiac\n\ +(\"Tiled\") when resizing the window.\n\ +If you like to use \"Fit Size\" you have\n\ +to enable \"use GUIGFX\". +; +; +MSGID_MENU_PROJECT_ABOUT (//) +About... +; +; +MSGID_ABOUTREQOK (//) +_OK +; +; +MSGID_ABOUTREQFORMAT (//) +\33c\033bScalos pattern preferences V%ld.%ld\033n\n\ +%s\n\ +© 1999%s The Scalos Team\n\ +Based on original code by Stefan Sommerfeld of ALiENDESiGN!\n\ +Bubbles done by Crayor. +; +; +MSGID_COLUMNTITLE_1 (//) +\33bNr. +; +; +MSGID_COLUMNTITLE_2 (//) +\33bFile name +; +; +MSGID_REQTITLE_SAVEERROR (//) +Error writing pattern preferences\n\ +file \"%s\"\n\ +%s +; +; +MSGID_REQTITLE_READERROR (//) +Error reading pattern preferences\n\ +file \"%s\"\n\ +%s +; +; new in 40.4 +; +MSGID_PLUGIN_LIST_TITLE (//) +Pattern +; +; +MSGID_GROUP_MISCELLANEOUS (//) +Miscellaneous +; +; +MSGID_GROUP_PATTERNNUMBERS (//) +Pattern numbers +; +; +MSGID_MENU_ENABLE_PREVIEW (//) +Show Preview? +; +; +MSGID_MENU_AUTO_PREVIEW (//) +Auto Preview? +; +; new in 40.6 +; +MSGID_SHORTHELP_LAMP_CHANGED (//) +This lamp indicator changes from \033bOff\033n\n\ +to \033bOk\033n when the settings have been\n\ +modified since initial loading. +; +; new in 40.7 +; +MSGID_COLUMNTITLE_3 (//) +\33bPreview +; +; +MSGID_CREATING_THUMBNAIL (//) +\33cCreating Thumbnail for +; +; +MSGID_LOADING_THUMBNAIL (//) +\33cLoading Thumbnail for +; +; +MSGID_PROGRESS_THUMBNAILS (//) +\33c%ld/%ld +; +; +MSGID_WINDOW_STARTUP (//) +Scalos PatternPrefs startup +; +; +MSGID_STARTUP_CREATING (//) +On initial start, thumbnails are created for every \ +pattern. Unfortunately this takes some time. \ +However, thumbnail bitmaps are saved together \ +with the standard pattern preferences.\n\ +After the thumbnails have been saved, \ +future startups will be \033bmuch faster\033n. +; +; +MSGID_MENU_ENABLE_THUMBNAILS (//) +Display Thumbnails? +; +;----------------------------------------------------------- +; +MSGID_STARTUP_FAILURE (//) +Scalos Pattern Prefs startup failed +; +; +MSGID_STARTUP_RETRY_QUIT_GAD (//) +Try again|Quit +; +; +MSGID_STARTUP_MCC_NOT_FOUND (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +The class is not installed. +; +; +MSGID_STARTUP_OLD_MCC (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +\n\ +Currently installed is V%lu.%lu, please upgrade! +; +; +MSGID_STARTUP_MCC_IN_USE (//) +Couldn't open MUI custom class '%s' V%lu.%lu.\n\ +%lu.%lu is currently in use by other applications.\n\ +\n\ +Once you have installed the required version,\n\ +close all MUI programs, make sure the old class\n\ +is flushed from memory and try again. +; +;----------------------------------------------------------- +; +MSGID_COLUMNTITLE_4 (//) +\33bType +; +;----------------------------------------------------------- +; +MSGID_PATTERNTYPE_DESKTOP (//) +DE +; +; +MSGID_PATTERNTYPE_SCREEN (//) +SC +; +; +MSGID_PATTERNTYPE_ICONWINDOW (//) +IW +; +; +MSGID_PATTERNTYPE_TEXTWINDOW (//) +TW +; +; +MSGID_PATTERNTYPE_NONE (//) + +; +;----------------------------------------------------------- +; +MSGID_MENU_RELOAD_THUMBNAILS (1000//) +Reload Thumbnails +; +; +MSGID_LOADING_THUMBNAILS (//) +\033cLoading Thumbnails... +; +;----------------------------------------------------------- +; +MSGID_REGISTER_BACKGROUNDCOLORS (2000//) +Background Colours +; +; +MSGID_BGTYPE_NONE (//) +None +; +; +MSGID_LABEL_CYCLEBACKGROUND (//) +Background Type: +; +; +MSGID_BGTYPE_SINGLECOLOR (//) +Single Colour +; +; +MSGID_BGTYPE_HOR_GRADIENT (//) +Horizontal gradient +; +; +MSGID_BGTYPE_VERT_GRADIENT (//) +Vertical gradient +; +; +MSGID_SHORTHELP_BACKGROUNDCOLOR1 (//) +Here you can adjust the window background color.\n\ +This is only possible with \033bcentered\033n and\n\ +\033bcolor-only\033n pattern type.\n\ +For \033bgradient\33n pattern types, you can\n\ +select the top (vertical gradient) or\n\ +left (horizontal gradient) colour here. +; +; +MSGID_SHORTHELP_BACKGROUNDCOLOR2 (//) +Here you can adjust the secondary window background color.\n\ +For \033bgradient\33n pattern types, you can\n\ +select the bottom (vertical gradient) or\n\ +right (horizontal gradient) colour here. +; +; +MSGID_SHORTHELP_CYCLEBACKGROUND (//) +This gadget selects the type of background that\n\ +is drawn besides the selected image.\n\ +It is selectable only in \033bCentered\033n mode because\n\ +in other modes, there is no room around the image where\n\ +the background color could be seen. +; +; +MSGID_SCALEDMINNAME (//) +Proportionally Scaled (min) +; +; +MSGID_SCALEDMAXNAME (//) +Proportionally Scaled (max) +; +;----------------------------------------------------------- +; diff --git a/scalos/Prefs/Pattern/Scalos_Pattern.info b/scalos/Prefs/Pattern/Scalos_Pattern.info new file mode 100755 index 0000000000000000000000000000000000000000..ea76be827be0695ccb0aa35e3d9fc418105a3d82 GIT binary patch literal 2833 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 c3IF8ui!_L_rMrL^q /dev/null 2>&1 + +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(CSRCS:%.c=$(OBJDIR)/%.o) + +############################################################# + +NAME = .bin_os3/Scalos_Pattern +NAMEDBG = $(NAME).debug +DESTTOOL = Scalos:Prefs/Scalos Pattern +CAT_FILE = Scalos/ScalosPattern.catalog +CATCOMPHEADER = $(SCALOS_LOCALE) +DESTCAT = Locale:Catalogs + +CATS = dansk \ + deutsch \ + español \ + français \ + italiano \ + svenska \ + ÃeÓtina + +ALLCATS = $(foreach cat,$(CATS),catalogs/$(cat)/$(CAT_FILE)) + +############################################################# + +# The default target (all) and what to really build +all: $(NAME) $(NAMEDBG) allcatalogs +# install +# clean +# launch + +############################################################# + +$(OBJDIR)/Pattern.o : Pattern.c Pattern.h $(SCALOS_LOCALE) + +$(CATCOMPHEADER) : ScalosPattern.cd + @printf '\033[32mMake CatComp header: \033[31m\033[1m$@ \033[32mfrom \033[31m$<\033[0m\n' + $(FLEXCAT) $(subst ../,/,$<) $@=$(SDPATH)/CatComp_h.sd + +############################################################# + +# CLI command used when linking the final executables +$(NAME) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LDLIBS) $(LDFLAGS) STRIPDEBUG + +$(NAMEDBG) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(CSTARTUP) $(OBJS) TO $@ LIB $(LDLIBS) $(LDFLAGS) ADDSYM + +############################################################# + +# commands generated a catalog (.catalog) from a catalog translation (.ct) file. +.ct.catalog: + $(CATCOMP) $*.cd $< CATALOG $*.catalog VB=1 + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $*.c objectname $@ + +$(OBJDIR)/%.o : %.s + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +$(OBJDIR)/%.o : %.asm + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +############################################################# + +# copy all generated file to their final destinations +install: + @printf '\033[32mInstall: \033[31m\033[1m$(DESTTOOL)\033[0m\n' + @copy $(NAME) "$(DESTTOOL)" clone + @printf '\033[32mInstall: \033[31m\033[1m$(CAT_FILE)\033[0m\n' + -@$(foreach cat,$(CATS),copy "catalogs/$(cat)/$(CAT_FILE)" "$(DESTCAT)/$(cat)/Scalos" clone;) + +############################################################# + +# make all Scalos preferences .catalogs +allcatalogs: + -@$(foreach cat,$(CATS),$(SUBDIRMAKE) catalogs/$(cat)/Scalos;) + +############################################################# + +# A little something to clean it all up +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + -@delete $(NAME) $(NAMEDBG) $(OBJS) $(CATCOMPHEADER) $(ALLCATS) + @printf '\033[0m' + +############################################################# + +nodebug: + -@$(SPLAT) -s -o "d2(" "d1(" "#?.c" + +############################################################# diff --git a/scalos/Prefs/Pattern/makefile-new b/scalos/Prefs/Pattern/makefile-new new file mode 100755 index 000000000..d846f17ae --- /dev/null +++ b/scalos/Prefs/Pattern/makefile-new @@ -0,0 +1,97 @@ +# $Date: 2011-08-06 19:37:48 +0200 (Sa, 06. Aug 2011) $ +# $Revision: 823 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../.. +endif + +# Native FlexCat doesn't like Linux paths +ifeq ($(CROSS), ) + SDPATH=/ +else + SDPATH=../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(OBJDIR)/Pattern.o + + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Subdirs +# + +SUBDIRS = $(filter-out Catalogs/sample/Scalos, $(wildcard Catalogs/*/Scalos)) + +############################################################################## +# +# Some lame deps + +$(OBJDIR)/Pattern.o $(OBJDIR)/Pattern.d : $(OBJDIR)/ScalosPattern_locale.h + +$(OBJDIR)/ScalosPattern_locale.h : ScalosPattern.cd + @$(ECHO) "FlexCat $@" + $(FLEXCAT) $< $@=$(SDPATH)/CatComp_h.sd + +############################################################################## +# +# Targets +# + +NAME = Scalos_Pattern +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) \ + all_subdirs + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + $(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + -@copy $(BINDIR)/$(NAME) "Scalos:Prefs/Scalos Pattern" clone + +install: install_subdirs + + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* \ + $(OBJDIR)/ScalosPattern_locale.h + +clean: clean_subdirs + +############################################################################## + + diff --git a/scalos/Prefs/config.mk b/scalos/Prefs/config.mk new file mode 100755 index 000000000..0548f0e8c --- /dev/null +++ b/scalos/Prefs/config.mk @@ -0,0 +1,39 @@ +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += # + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += # + + +else + +############################################################################### +# AmigaOS + +LFLAGS += # + +endif +endif + diff --git a/scalos/Prefs/makefile b/scalos/Prefs/makefile new file mode 100644 index 000000000..485802505 --- /dev/null +++ b/scalos/Prefs/makefile @@ -0,0 +1,46 @@ +# makefile for all Scalos Prefs +# $Date$ +# $Revision$ + +############################################################# + +SUBDIRS = FileTypes \ + MainPrefs \ + Menu \ + Palette \ + Pattern \ + +############################################################# + +.PHONY: All install clean + +############################################################# + +define build_subdir +$(MAKE) -s --directory=$(1); +endef + +define install_subdir +$(MAKE) -s install --directory=$(1); +endef + +define clean_subdir +$(MAKE) -s clean --directory=$(1); +endef + +############################################################# + +All: + @$(foreach subdir,$(SUBDIRS),$(call build_subdir,$(subdir))) + +############################################################# + +install: + @$(foreach subdir,$(SUBDIRS),$(call install_subdir,$(subdir))) + +############################################################# + +clean: + @$(foreach subdir,$(SUBDIRS),$(call clean_subdir,$(subdir))) + +############################################################# diff --git a/scalos/Prefs/makefile-new b/scalos/Prefs/makefile-new new file mode 100755 index 000000000..e3e8cbd2f --- /dev/null +++ b/scalos/Prefs/makefile-new @@ -0,0 +1,31 @@ +# $Date: 2009-02-17 21:22:13 +0100 (Di, 17. Feb 2009) $ +# $Revision: 5 $ +############################################################# +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/.. +endif + +############################################################################### + +include config.mk + +############################################################################### + +SUBDIRS = Palette \ + Menu \ + FileTypes \ + Pattern \ + MainPrefs \ + +############################################################################### + +.PHONY: all install clean bump dump + +all: all_subdirs + +clean: clean_subdirs + +install: install_subdirs + +nodebug: nodebug_subdirs + diff --git a/scalos/Release b/scalos/Release new file mode 100755 index 000000000..c0b21f1f6 --- /dev/null +++ b/scalos/Release @@ -0,0 +1,286 @@ +/* Release */ +/* Scalos release package creation script */ +/* $Date: 2008-05-19 20:20:58 +0200 (Mo, 19 Mai 2008) $ */ +/* $Revision: 2819 $ */ + +LHAName = 'RAM:ScalosBeta' +tmpfname = "t:xyzzy" + +address command + +"version" + +os = GetOsName() + +/* system-specific language catalog names */ +select +when os = "AmigaOS4" then do + /* Amiga OS4 */ + LangGerman = "german"; + LangFrench = "french"; + BinDir = ".bin_os4/"; + end +when os = "AmigaOS3" then do + /* Amiga OS3 */ + LangGerman = "Deutsch"; + LangFrench = "français"; + BinDir = ".bin_os3/"; + end +otherwise do + /* MorphOS */ + LangGerman = "Deutsch"; + LangFrench = "français"; + BinDir = ".bin_mos/"; + end; +end + +say BinDir + +say "Deleting old directory tree..." +"delete RAM:ScalosBeta all QUIET" +say "Deleting old archive..." +"delete " || LHAName || ".lha quiet" + +/* "makedir RAM:ScalosBeta" */ +address workbench "newdrawer RAM:ScalosBeta" + +/* "copy ScalosBeta.info RAM: clone quiet" */ + +"makedir RAM:ScalosBeta/c" +"mkdir -p RAM:ScalosBeta/Icondatatypes/Datatypes" +"makedir RAM:ScalosBeta/libs" +"makedir RAM:ScalosBeta/libs/OS4" +"makedir RAM:ScalosBeta/Prefs" +"mkdir -p RAM:ScalosBeta/Themes/default" +"mkdir -p RAM:ScalosBeta/env-archive" +"makedir RAM:ScalosBeta/Tools" +"mkdir -p RAM:ScalosBeta/modules" +"mkdir -p RAM:ScalosBeta/Plugins/FileTypes" +"mkdir -p RAM:ScalosBeta/Plugins/Menu" +"mkdir -p RAM:ScalosBeta/Plugins/OOP" +"mkdir -p RAM:ScalosBeta/Plugins/Preview" + +"mkdir -p RAM:ScalosBeta/catalogs/" || LangGerman || "/Scalos" +"mkdir -p RAM:ScalosBeta/catalogs/" || LangFrench || "/Scalos" + + +say "Copying Installer..." + +"copy Installer/#? RAM:ScalosBeta/ all clone quiet" + +say "Copying History and Readme.txt..." + +"copy History RAM:ScalosBeta/ clone quiet" +"copy ReadMe#? RAM:ScalosBeta/ clone quiet" +"copy gpl#? RAM:ScalosBeta/ clone quiet" +"copy lgpl#? RAM:ScalosBeta/ clone quiet" + +say "Copying Scalos main executable..." + +"copy main/" || BinDir || "Scalos RAM:ScalosBeta/ clone quiet" +"copy main/Scalos.info RAM:ScalosBeta/ clone quiet" + +say "Copying Preferences..." + +'copy Prefs/Menu/' || BinDir || 'Scalos_Menu "RAM:ScalosBeta/Prefs/Scalos Menu" clone quiet' +'copy Prefs/Menu/Scalos_Menu.info "RAM:ScalosBeta/Prefs/Scalos Menu.info" clone quiet' + +'copy Prefs/Pattern/' || BinDir || 'Scalos_Pattern "RAM:ScalosBeta/Prefs/Scalos Pattern" clone quiet' +'copy Prefs/Pattern/Scalos_Pattern.info "RAM:ScalosBeta/Prefs/Scalos Pattern.info" clone quiet' + +'copy Prefs/Palette/' || BinDir || 'Scalos_Palette "RAM:ScalosBeta/Prefs/Scalos Palette" clone quiet' +'copy Prefs/Palette/Scalos_Palette.info "RAM:ScalosBeta/Prefs/Scalos Palette.info" clone quiet' + +'copy Prefs/FileTypes/' || BinDir || 'Scalos_FileTypes "RAM:ScalosBeta/Prefs/Scalos FileTypes" clone quiet' +'copy Prefs/FileTypes/Scalos_FileTypes.info "RAM:ScalosBeta/Prefs/Scalos FileTypes.info" clone quiet' + +'copy Prefs/MainPrefs/' || BinDir || 'Scalos_Prefs "RAM:ScalosBeta/Prefs/Scalos Prefs" clone quiet' +'copy Prefs/MainPrefs/Scalos_Prefs.info "RAM:ScalosBeta/Prefs/Scalos Prefs.info" clone quiet' + +'copy Plugins/Prefs/FileTypes/' || BinDir || '#?.prefsplugin "RAM:ScalosBeta/Prefs/" clone quiet' +'copy Plugins/Prefs/Palette/' || BinDir || '#?.prefsplugin "RAM:ScalosBeta/Prefs/" clone quiet' +'copy Plugins/Prefs/Pattern/' || BinDir || '#?.prefsplugin "RAM:ScalosBeta/Prefs/" clone quiet' +'copy Plugins/Prefs/Menu/' || BinDir || '#?.prefsplugin "RAM:ScalosBeta/Prefs/" clone quiet' +if os ~= "AmigaOS4" then do + 'copy Plugins/Prefs/Popupmenu/' || BinDir || '#?.prefsplugin "RAM:ScalosBeta/Prefs/" clone quiet' +end + + +say "Copying Modules..." + +'copy Modules/IconProperties.MUI/' || BinDir || 'IconProperties.module "RAM:ScalosBeta/modules/" clone quiet' +'copy Modules/WindowProperties.MUI/' || BinDir || 'WindowProperties.module "RAM:ScalosBeta/modules/" clone quiet' +'copy Modules/Delete.MUI/Source/' || BinDir || 'Delete.module "RAM:ScalosBeta/modules/" clone quiet' +'copy Modules/Empty_Trashcan.MUI/' || BinDir || 'Empty_Trashcan.module "RAM:ScalosBeta/modules/" clone quiet' +'copy Modules/Exchange.MUI/' || BinDir || 'Exchange.module "RAM:ScalosBeta/modules/" clone quiet' +'copy Modules/Find.MUI/' || BinDir || 'Find.module "RAM:ScalosBeta/modules/" clone quiet' +'copy Modules/FormatDisk.Gadtools/' || BinDir || 'Format_Disk.module "RAM:ScalosBeta/modules/" clone quiet' +'copy Modules/Execute_Command.MUI/' || BinDir || 'Execute_Command.module "RAM:ScalosBeta/modules/" clone quiet' +'copy Modules/Information.MUI/' || BinDir || 'Information.module "RAM:ScalosBeta/modules/" clone quiet' +'copy Modules/NewDrawer.MUI/' || BinDir || 'NewDrawer.module "RAM:ScalosBeta/modules/" clone quiet' +'copy Modules/Rename.MUI/' || BinDir || 'Rename.module "RAM:ScalosBeta/modules/" clone quiet' +'copy Modules/Updater.MUI/' || BinDir || 'Updater.module "RAM:ScalosBeta/modules/" clone quiet' + + +say "Copying Libraries..." + +'copy libraries/iconobject/' || BinDir || 'iconobject.library "RAM:ScalosBeta/libs/" clone quiet' +'copy libraries/preferences/' || BinDir || 'preferences.library "RAM:ScalosBeta/libs/" clone quiet' +'copy libraries/sqlite/' || BinDir || 'sqlite3.library "RAM:ScalosBeta/libs/" clone quiet' +'copy libraries/scalosgfx/' || BinDir || 'scalosgfx.library "RAM:ScalosBeta/libs/" clone quiet' +if os ~= "AmigaOS4" then do + 'copy libraries/popupmenu/' || BinDir || 'popupmenu.library "RAM:ScalosBeta/libs/" clone quiet' +end +'copy libs/#?.library#? "RAM:ScalosBeta/libs/" clone quiet' +'copy libs/OS4/#?.library "RAM:ScalosBeta/libs/OS4" clone quiet' + +say "Copying Datatypes..." + +'copy datatypes/AmigaIconObj3.5/' || BinDir || '#?.datatype "RAM:ScalosBeta/Icondatatypes/Datatypes/" clone quiet' +'copy datatypes/AmigaIconObject/' || BinDir || '#?.datatype "RAM:ScalosBeta/Icondatatypes/Datatypes/" clone quiet' +'copy datatypes/GlowIconObject/' || BinDir || '#?.datatype "RAM:ScalosBeta/Icondatatypes/Datatypes/" clone quiet' +'copy datatypes/IconObject/' || BinDir || '#?.datatype "RAM:ScalosBeta/Icondatatypes/Datatypes/" clone quiet' +'copy datatypes/PNGIcons/' || BinDir || '#?.datatype "RAM:ScalosBeta/Icondatatypes/Datatypes/" clone quiet' +if os ~= "AmigaOS4" then do + 'copy datatypes/NewIcons/' || BinDir || '#?.datatype "RAM:ScalosBeta/Icondatatypes/Datatypes/" clone quiet' +end + +'copy main/envarc/#? "RAM:ScalosBeta/env-archive/" all clone quiet' + +'copy Default_Theme/#? "RAM:ScalosBeta/Themes/default" all clone quiet' + +'copy main/tools/' || BinDir || 'LoadWB.Scalos "RAM:ScalosBeta/c/LoadWB" clone quiet' + +'copy main/tools/' || BinDir || 'ScalosCtrl "RAM:ScalosBeta/Tools/" clone quiet' + +say "Copying Extras..." + +'copy Extras/browse.script "RAM:ScalosBeta/Tools/" clone quiet' +'copy Extras/opendrawer#? "RAM:ScalosBeta/Tools/" clone quiet' +'copy Extras/PictIcon "RAM:ScalosBeta/Tools/" clone quiet' +'copy Extras/open_volume.rexx "RAM:ScalosBeta/Tools/" clone quiet' +'copy Extras/CreateTrash#? "RAM:ScalosBeta/Tools/" clone quiet' +'copy Extras/CreateDefaultIcon#? "RAM:ScalosBeta/Tools/" clone quiet' +'copy Extras/run.script "RAM:ScalosBeta/Tools/" clone quiet' +'copy Extras/NewIconUtil "RAM:ScalosBeta/Tools/" clone quiet' +'copy Extras/OpenLocation#? "RAM:ScalosBeta/Tools/" clone quiet' +'copy Extras/OpenShell "RAM:ScalosBeta/Tools/" clone quiet' +'copy Extras/Scalos_Comment#? "RAM:ScalosBeta/Tools/" all clone quiet' +'copy Extras/Scalos_GetHidden#? "RAM:ScalosBeta/Tools/" all clone quiet' + +say "Copying Plugins..." + +'copy Plugins/FileTypes/DrawerContents/#?.plugin "RAM:ScalosBeta/Plugins/FileTypes/" clone quiet' +'copy Plugins/FileTypes/Picture_Dimensions/#?.plugin "RAM:ScalosBeta/Plugins/FileTypes/" clone quiet' +'copy Plugins/FileTypes/ExifPicture/#?.plugin "RAM:ScalosBeta/Plugins/FileTypes/" clone quiet' + +'copy Plugins/OOP/DeviceFilter/#?.plugin "RAM:ScalosBeta/Plugins/OOP/" clone quiet' +'copy Plugins/OOP/title_freepens/#?.plugin "RAM:ScalosBeta/Plugins/OOP/" clone quiet' +'copy Plugins/OOP/TitleClock/#?.plugin "RAM:ScalosBeta/Plugins/OOP/" clone quiet' +'copy Plugins/OOP/wb39_plugin/#?.plugin "RAM:ScalosBeta/Plugins/OOP/" clone quiet' +'copy Plugins/OOP/wb39_plugin/wbrexx/#?.plugin "RAM:ScalosBeta/Plugins/OOP/" clone quiet' +'copy Plugins/OOP/wb39_plugin/persist/#?.plugin "RAM:ScalosBeta/Plugins/OOP/" clone quiet' +'copy Plugins/OOP/wb39_plugin/volumegauge/#?.plugin "RAM:ScalosBeta/Plugins/OOP/" clone quiet' +'copy Plugins/OOP/XTWindows/#?.plugin "RAM:ScalosBeta/Plugins/OOP/" clone quiet' + +'copy Plugins/Menu/Sorted_Cleanup/#?.plugin "RAM:ScalosBeta/Plugins/Menu/" clone quiet' + +'copy Plugins/Preview/DefPicture/#?.pvplugin "RAM:ScalosBeta/Plugins/Preview/" clone quiet' +'copy Plugins/Preview/JpegPicture/#?.pvplugin "RAM:ScalosBeta/Plugins/Preview/" clone quiet' +'copy Plugins/Preview/PNGPicture/#?.pvplugin "RAM:ScalosBeta/Plugins/Preview/" clone quiet' +'copy Plugins/Preview/Video/#?.pvplugin "RAM:ScalosBeta/Plugins/Preview/" clone quiet' + +say "Copying Language catalogs..." + +'copy main/catalogs/deutsch/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangGerman || '/Scalos/" clone quiet' +'copy Plugins/FileTypes/DrawerContents/Catalogs/deutsch/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangGerman || '/Scalos/" clone quiet' +'copy Plugins/FileTypes/Picture_Dimensions/Catalogs/deutsch/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangGerman || '/Scalos/" clone quiet' +'copy Prefs/MainPrefs/Catalogs/deutsch/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangGerman || '/Scalos/" clone quiet' +'copy Prefs/FileTypes/Catalogs/deutsch/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangGerman || '/Scalos/" clone quiet' +'copy Prefs/Menu/Catalogs/deutsch/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangGerman || '/Scalos/" clone quiet' +'copy Prefs/Palette/Catalogs/deutsch/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangGerman || '/Scalos/" clone quiet' +'copy Prefs/Pattern/Catalogs/deutsch/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangGerman || '/Scalos/" clone quiet' +'copy Plugins/FileTypes/ExifPicture/Catalogs/deutsch/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangGerman || '/Scalos/" clone quiet' +'copy Plugins/FileTypes/DrawerContents/Catalogs/deutsch/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangGerman || '/Scalos/" clone quiet' +'copy Plugins/Prefs/Popupmenu/Catalogs/deutsch/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangGerman || '/Scalos/" clone quiet' +'copy Modules/Delete.MUI/Source/Catalogs/deutsch/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangGerman || '/Scalos/" clone quiet' +'copy Modules/Execute_Command.MUI/Catalogs/deutsch/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangGerman || '/Scalos/" clone quiet' +'copy Modules/IconProperties.MUI/Catalogs/deutsch/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangGerman || '/Scalos/" clone quiet' +'copy Modules/Information.MUI/Catalogs/deutsch/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangGerman || '/Scalos/" clone quiet' +'copy Modules/NewDrawer.MUI/Catalogs/deutsch/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangGerman || '/Scalos/" clone quiet' +'copy Modules/Rename.MUI/Catalogs/deutsch/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangGerman || '/Scalos/" clone quiet' +'copy Modules/Empty_Trashcan.MUI/Catalogs/deutsch/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangGerman || '/Scalos/" clone quiet' +'copy Modules/Exchange.MUI/Catalogs/deutsch/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangGerman || '/Scalos/" clone quiet' +'copy Modules/Find.MUI/Catalogs/deutsch/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangGerman || '/Scalos/" clone quiet' +'copy Modules/WindowProperties.MUI/Catalogs/deutsch/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangGerman || '/Scalos/" clone quiet' +'copy Modules/Updater.MUI/Catalogs/deutsch/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangGerman || '/Scalos/" clone quiet' + +'copy main/catalogs/français/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangFrench || '/Scalos/" clone quiet' +'copy Plugins/FileTypes/DrawerContents/Catalogs/français/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangFrench || '/Scalos/" clone quiet' +'copy Plugins/FileTypes/Picture_Dimensions/Catalogs/français/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangFrench || '/Scalos/" clone quiet' +'copy Prefs/MainPrefs/Catalogs/français/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangFrench || '/Scalos/" clone quiet' +'copy Prefs/FileTypes/Catalogs/français/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangFrench || '/Scalos/" clone quiet' +'copy Prefs/Menu/Catalogs/français/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangFrench || '/Scalos/" clone quiet' +'copy Prefs/Palette/Catalogs/français/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangFrench || '/Scalos/" clone quiet' +'copy Prefs/Pattern/Catalogs/français/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangFrench || '/Scalos/" clone quiet' +'copy Plugins/FileTypes/ExifPicture/Catalogs/français/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangFrench || '/Scalos/" clone quiet' +'copy Plugins/FileTypes/DrawerContents/Catalogs/français/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangFrench || '/Scalos/" clone quiet' +'copy Plugins/Prefs/Popupmenu/Catalogs/français/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangFrench || '/Scalos/" clone quiet' +'copy Modules/Delete.MUI/Source/Catalogs/français/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangFrench || '/Scalos/" clone quiet' +'copy Modules/Execute_Command.MUI/Catalogs/français/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangFrench || '/Scalos/" clone quiet' +'copy Modules/IconProperties.MUI/Catalogs/français/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangFrench || '/Scalos/" clone quiet' +'copy Modules/Information.MUI/Catalogs/français/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangFrench || '/Scalos/" clone quiet' +'copy Modules/NewDrawer.MUI/Catalogs/français/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangFrench || '/Scalos/" clone quiet' +'copy Modules/Rename.MUI/Catalogs/français/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangFrench || '/Scalos/" clone quiet' +'copy Modules/Empty_Trashcan.MUI/Catalogs/français/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangFrench || '/Scalos/" clone quiet' +'copy Modules/Exchange.MUI/Catalogs/français/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangFrench || '/Scalos/" clone quiet' +'copy Modules/Find.MUI/Catalogs/français/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangFrench || '/Scalos/" clone quiet' +'copy Modules/WindowProperties.MUI/Catalogs/français/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangFrench || '/Scalos/" clone quiet' +'copy Modules/Updater.MUI/Catalogs/français/Scalos/#?.catalog "RAM:ScalosBeta/catalogs/' || LangFrench || '/Scalos/" clone quiet' + +say "Removing SVN directories..." + +TempName = 't:xx123' + +'list dir "RAM:ScalosBeta/" all pat ".svn" nohead lformat "delete *"%f%n*" all quiet" to ' || TempName +'execute ' || TempName +'delete ' || TempName || ' quiet' + +'list dir "RAM:ScalosBeta/" all pat ".subversion" nohead lformat "delete *"%f%n*" all quiet" to ' || TempName +'execute ' || TempName +'delete ' || TempName || ' quiet' + +'lha -r -e -x a ' || LHAName || ' RAM:ScalosBeta' +'lha -r -e -x a ' || LHAName || ' RAM:ScalosBeta.info ' + +lha t LHAName + +exit + +/* -------------------------------------------------------------------------------- */ + +GetOsName: procedure + +'version >' tmpfname +rc = open( 'tmpfile', tmpfname, 'R' ) +versionstring = readln( 'tmpfile' ) +rc = close( 'tmpfile' ) +'delete ' || tmpfname || ' quiet' +if index(versionstring, "MorphOS") > 0 then + do + os = "MorphOS" + end +else + do + versionstring = strip(subword(versionstring, 2, 1), 'B', ',') + if versionstring > 50 then + os = "AmigaOS4" + else + os = "AmigaOS3" + end + +return os + +END + +/* -------------------------------------------------------------------------------- */ diff --git a/scalos/ReleaseAROS b/scalos/ReleaseAROS new file mode 100644 index 000000000..d85d1ab1e --- /dev/null +++ b/scalos/ReleaseAROS @@ -0,0 +1,131 @@ +#!/bin/bash + +# $Id$ + +# AROS doesn't have a working installer, so we copy things such +# that we need only minimal additional installation after unpacking. + +targetdir=../Reserve/Scalos.i386-aros + +echo "Creating directories..." + +rm -rf $targetdir +mkdir -p $targetdir +mkdir -p $targetdir/IconDatatypes/datatypes +mkdir -p $targetdir/Libs +mkdir -p $targetdir/Modules +mkdir -p $targetdir/Prefs +mkdir -p $targetdir/Plugins/FileTypes +mkdir -p $targetdir/Plugins/OOP +mkdir -p $targetdir/Plugins/Preview +mkdir -p $targetdir/Tools +mkdir -p $targetdir/Themes +mkdir -p $targetdir/Env-Archive +mkdir -p $targetdir/S + +echo "Copying files..." + +cp gpl-3.0.txt GPLsrc History lgpl-3.0.txt readme.txt LEGAL $targetdir + +cp main/.bin_i386-aros/Scalos $targetdir +cp main/Scalos.info $targetdir + +cp datatypes/AmigaIconObject/.bin_i386-aros/amigaiconobject.datatype $targetdir/IconDatatypes/datatypes +cp datatypes/IconObject/.bin_i386-aros/iconobject.datatype $targetdir/IconDatatypes/datatypes +cp datatypes/PNGIcons/.bin_i386-aros/pngiconobject.datatype $targetdir/IconDatatypes/datatypes +cp datatypes/AmigaIconObj3.5/.bin_i386-aros/amigaiconobj35.datatype $targetdir/IconDatatypes/datatypes +cp datatypes/GlowIconObject/.bin_i386-aros/glowiconobject.datatype $targetdir/IconDatatypes/datatypes + +cp libraries/sqlite/.bin_i386-aros/sqlite3.library $targetdir/Libs +cp libraries/iconobject/.bin_i386-aros/iconobject.library $targetdir/Libs +cp libraries/preferences/.bin_i386-aros/preferences.library $targetdir/Libs +cp libraries/scalosgfx/.bin_i386-aros/scalosgfx.library $targetdir/Libs + +cp Modules/NewDrawer.MUI/.bin_i386-aros/NewDrawer.module $targetdir/Modules +cp Modules/Delete.MUI/Source/.bin_i386-aros/Delete.module $targetdir/Modules +cp Modules/Empty_Trashcan.MUI/.bin_i386-aros/Empty_Trashcan.module $targetdir/Modules +cp Modules/Exchange.MUI/.bin_i386-aros/Exchange.module $targetdir/Modules +cp Modules/Information.MUI/.bin_i386-aros/Information.module $targetdir/Modules +cp Modules/WindowProperties.MUI/.bin_i386-aros/WindowProperties.module $targetdir/Modules +cp Modules/Find.MUI/.bin_i386-aros/Find.module $targetdir/Modules +cp Modules/FormatDisk.Gadtools/.bin_i386-aros/Format_Disk.module $targetdir/Modules +# cp Modules/FormatDisk.MUI/.bin_i386-aros/FormatDisk.module $targetdir/Modules +cp Modules/Rename.MUI/.bin_i386-aros/Rename.module $targetdir/Modules +cp Modules/IconProperties.MUI/.bin_i386-aros/IconProperties.module $targetdir/Modules +cp Modules/Execute_Command.MUI/.bin_i386-aros/Execute_Command.module $targetdir/Modules +cp Modules/Updater.MUI/.bin_i386-aros/Updater.module $targetdir/Modules + +# prefsplugins must go into Prefs dir! +cp Plugins/Prefs/Pattern/.bin_i386-aros/Pattern.prefsplugin $targetdir/Prefs +cp Plugins/Prefs/Palette/.bin_i386-aros/Palette.prefsplugin $targetdir/Prefs +cp Plugins/Prefs/FileTypes/.bin_i386-aros/FileTypes.prefsplugin $targetdir/Prefs +cp Plugins/Prefs/Popupmenu/.bin_i386-aros/PopupMenu.prefsplugin $targetdir/Prefs +cp Plugins/Prefs/Menu/.bin_i386-aros/Menu.prefsplugin $targetdir/Prefs + +# TODO: add video.pvplugin when it builds +cp Plugins/Preview/PNGPicture/.bin_i386-aros/pngpicture.pvplugin $targetdir/Plugins/Preview +cp Plugins/Preview/JpegPicture/.bin_i386-aros/jpegpicture.pvplugin $targetdir/Plugins/Preview +cp Plugins/Preview/DefPicture/.bin_i386-aros/defpicture.pvplugin $targetdir/Plugins/Preview + +cp Plugins/OOP/title_freepens/.bin_i386-aros/title_freepens.plugin $targetdir/Plugins/OOP +cp Plugins/OOP/title_envvar/.bin_i386-aros/title_envvar.plugin $targetdir/Plugins/OOP +cp Plugins/OOP/XTWindows/.bin_i386-aros/xtwindows.plugin $targetdir/Plugins/OOP +cp Plugins/OOP/TitleClock/.bin_i386-aros/title_clock.plugin $targetdir/Plugins/OOP +cp Plugins/OOP/TitleClock/prefs/Title_Clock_Prefs $targetdir/Plugins/OOP +cp Plugins/OOP/wb39_plugin/.bin_i386-aros/test $targetdir/Plugins/OOP +cp Plugins/OOP/wb39_plugin/.bin_i386-aros/wb39.plugin $targetdir/Plugins/OOP +cp Plugins/OOP/wb39_plugin/wbrexx/.bin_i386-aros/wbrexx.plugin $targetdir/Plugins/OOP +cp Plugins/OOP/wb39_plugin/volumegauge/.bin_i386-aros/volumegauge.plugin $targetdir/Plugins/OOP +cp Plugins/OOP/wb39_plugin/persist/.bin_i386-aros/persist.plugin $targetdir/Plugins/OOP +cp Plugins/OOP/DeviceFilter/.bin_i386-aros/devicefilter.plugin $targetdir/Plugins/OOP + +cp Plugins/FileTypes/DrawerContents/.bin_i386-aros/drawercontents.plugin $targetdir/Plugins/FileTypes +cp Plugins/FileTypes/Picture_Dimensions/.bin_i386-aros/picturedimensions.plugin $targetdir/Plugins/FileTypes +cp Plugins/FileTypes/ExifPicture/.bin_i386-aros/exifpicture.plugin $targetdir/Plugins/FileTypes + +cp Prefs/Pattern/.bin_i386-aros/Scalos_Pattern $targetdir/Prefs +cp Prefs/MainPrefs/.bin_i386-aros/Scalos_Prefs $targetdir/Prefs +cp Prefs/Palette/.bin_i386-aros/Scalos_Palette $targetdir/Prefs +cp Prefs/FileTypes/.bin_i386-aros/Scalos_FileTypes $targetdir/Prefs +cp Prefs/Menu/.bin_i386-aros/Scalos_Menu $targetdir/Prefs + +cp main/Tools/.bin_i386-aros/LoadWB.Scalos $targetdir/Tools +cp main/Tools/.bin_i386-aros/ScalosSema $targetdir/Tools +cp main/Tools/.bin_i386-aros/GenMsgIdNames $targetdir/Tools +cp main/Tools/.bin_i386-aros/ScalosCtrl $targetdir/Tools + +cp main/Tools/OpenDrawer/.bin_i386-aros/OpenDrawer $targetdir/Tools +cp Extras/opendrawer.68k.info $targetdir/Tools/OpenDrawer.info + +# Don't copy non-AROS binaries! +cp Extras/run.script Extras/browse.script Extras/open_volume.rexx Extras/OpenShell Extras/Quit.rexx $targetdir/Tools + +echo "Exporting default theme and env archive..." +svn export -q Default_Theme $targetdir/Themes/Default_Theme +svn export -q main/envarc/scalos.AROS $targetdir/Env-Archive/Scalos +cp main/envarc/deficons.prefs $targetdir/Env-Archive + +echo "Copying catalogs..." +find -iname "*.catalog" >tmpcatalogs +while read LINE; do + target=$targetdir/Catalogs${LINE#*[C|c]atalogs} + mkdir -p "${target%/*}" + cp "$LINE" "$target" +done < tmpcatalogs +rm -f tmpcatalogs + +echo "Copying icons..." +# FIXME + +echo "Copying InstallAROS script..." +cp Installer/InstallAROS $targetdir +cp Installer/InstallAROS.info $targetdir + +echo "Creating startup package..." +echo 'assign Scalos: ""' >>$targetdir/S/Package-Startup +echo 'assign Theme: Scalos:Themes/Default_Theme ADD' >>$targetdir/S/Package-Startup + + +echo "Done" + +exit 0 diff --git a/scalos/ScalosBeta.info b/scalos/ScalosBeta.info new file mode 100755 index 0000000000000000000000000000000000000000..67b117a32eed108437bf7a839fbdf3078882aecc GIT binary patch literal 1912 zcwTLkeM}Q)7{H&qUTc+eEw)Zr>#SG-6ODCXrcr2*wrY*gLa9+p6vP51J)u@5WR4FN z1-H2(rVe#NHYLWtaC2aSk@EwHi;ixPX+uq_qRz$mg-VNXxA$6gar3>qUZ2nReV_OF z-CZeQ@OB8%MIad~>3k7_4-E{Dyh=KKH_@vTJ*JWi>pfAU6kr&#u_{KqBq?m~k^&&*_N!KRfC_cq5?Q(@^A)y4`{#@6jyN>!^13JVLimd@cFWmY}4 z%52?`Wwz#0xi)JCmBXuXz?PYFG66(8O?q?IGD>emTG6Z|^y@TbQp*7ZQ((3L!$f!s z6omz$89{B$14vd~0VxK$iw}WNakaR#KwFEEpSHj<*$WHC8FA^xB_I(WtetBWYjV1i z8?zpRA;GMsNS$ZDl&VSXKM$N5xI21roUFk#iz50DJOwEIAtQ4I$m065mz)Q|g?enE zHV6Z8cRLweezNi^PWZa2MV5RZv(tcB;J6a=$fL=Oo6lfE>FW4bFtz%I+|pIg5{o?4 zq97?>-9)#q9f5eSH&0~>6Y>G$n${`>xC4@>Ot-kds^)d-yx4V=Fw?!}xV^h1c(B4x-XtjidvcDxYG}y-5FN(&D7GbZ92so34YHM?R>` zj9Hv?bmy8GbcZqw;{F4#Qd5U=D%x*<*{k54aL0|VgQJGYNyp1ywiPS*bp~OXeScEr zkHn6|f#R24BicdC(Pz>6!cUuYsu2j=RoO*@cy2yQ@zF@nPqJp38Jccg?H8ce0;8w*gh}bK>vepgF2Mx&NjE;>O)dJi1J3Ab9(%Io^E*<=3O-&lCA_%!2PUk zUu5;hGzNFZSJi+l1Pc|ezWW!CMdB?GKSp4s3?@fKVBOs&J4+(qh zbs#=@>eOj~a)W`bV>?+crY-?&u~428i|Axev%ubxHv!ZEaCPO^iVWodMd(gRU~PDl z4cKe!W44?vVw>1ZHsvE*LV^w8R;S^~1Nq#w{q@peYytz=h5CsL)QqK&G<^CLuu(P9t*sX1=2K5Voa24177r6F#AjE- zO#KUx{&JHv|D@~F6litAO_uJ>l6-94#2TY4)O`1H{nBAEoH05?gOsEU^Eh@8OPd=n zt}@tu)jw;Skj8LgGMh{ZaX;g~PxUlW=tw%!brUvwE^Sv+Ax*N*zZsqAS>*`CwN_&T z4IzzMe#F)8qk7XAEY%zYn>E1f^Uwrp)-*=6vjMQP>7+n7BppYsQHJ%+F4*HtVprkD zA+3UQ2PJng^X!r9Rev!pIon0Sy@>%tB9?v)v_ni=PQ^LlUJ+_J59}po6bdL~($Ou+ zN>@AYq@Mmoc>W399~BR(>>^iWoj_1$`^*2u4|%A3Q+94=ezv>`5evS=_W z3tS!eXyaH5blD-Q5xP1A$@3q=SLFP5Mj1(SDUW7$lPxEvy=+@CvmVtF^!Lt`D_mu} zNX>pavcED=(vl!Z!%jrgob8vynm4<|O-0|Sfa+^SNv=#n7Jc~4G*npFn(a8Uu^OGk zm~(bdz(q`&vyICPj>=^XaV%k^MxD`$Wj_+KK8MKamfh( z9U9HYDs@8sSS4*BeFfr{8+Sm6NJ5zK7~wol|3m4Puqi?j3pgT +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include +#include +#define NO_INLINE_STDARG +#include + +#include + +#include + +#include "Backfill.h" +#include "BitMapMCC.h" +#include "debug.h" + +//---------------------------------------------------------------------------- + +#define max(x, y) ((x) > (y) ? (x) : (y)) +#define min(x, y) ((x) > (y) ? (y) : (x)) + +//---------------------------------------------------------------------------- + +struct BackFillInst + { + Object *bfi_BitMapObject; + UWORD bfi_Width; + UWORD bfi_Height; + BOOL bfi_GenericBitMapObject; + }; + +//---------------------------------------------------------------------------- + +struct MUI_CustomClass *BackfillClass; +static ULONG Signature = 0x4711; + +//---------------------------------------------------------------------------- + +DISPATCHER_PROTO(Backfill); +static ULONG BackFillNew(Class *cl, Object *o, Msg msg); +static ULONG BackFillDispose(Class *cl, Object *o, Msg msg); +static ULONG BackFillClassAskMinMax(Class *cl, Object *o, Msg msg); +static ULONG BackFillSet(Class *cl, Object *o, Msg msg); +static ULONG BackFillDraw(Class *cl, Object *o, Msg msg); +static void CloneBitMapObject(Class *cl, Object *o, Object *NewBitMapObj); +static void ForceRelayout(struct IClass *cl, Object *obj); + +//---------------------------------------------------------------------------- + +DISPATCHER(Backfill) +{ + ULONG Result; + + switch (msg->MethodID) + { + case OM_NEW: + Result = BackFillNew(cl, obj, msg); + break; + + case OM_DISPOSE: + Result = BackFillDispose(cl, obj, msg); + break; + + case OM_SET: + Result = BackFillSet(cl, obj, msg); + break; + + case MUIM_Draw: + Result = BackFillDraw(cl, obj, msg); + break; + + case MUIM_AskMinMax: + Result = BackFillClassAskMinMax(cl, obj, msg); + break; + + default: + Result = DoSuperMethodA(cl, obj, msg); + break; + } + + return Result; +} +DISPATCHER_END + +//---------------------------------------------------------------------------- + +static ULONG BackFillNew(Class *cl, Object *o, Msg msg) +{ + o = (Object *) DoSuperMethodA(cl, o, msg); + if (o) + { + struct opSet *ops = (struct opSet *) msg; +// struct BackFillInst *inst = INST_DATA(cl, o); + Object *NewBitMapObj; + + set(o, MUIA_FillArea, TRUE); + + NewBitMapObj = (Object *) GetTagData(BFA_BitmapObject, (ULONG) NULL, ops->ops_AttrList); + CloneBitMapObject(cl, o, NewBitMapObj); + } + + return (ULONG) o; +} + +//---------------------------------------------------------------------------- + +static ULONG BackFillDispose(Class *cl, Object *o, Msg msg) +{ +// struct BackFillInst *inst = INST_DATA(cl, o); + +// if (inst->bfi_BitMapObject) +// { +// MUI_DisposeObject(inst->bfi_BitMapObject); +// inst->bfi_BitMapObject = NULL; +// } + + return DoSuperMethodA(cl, o, msg); +} + +//---------------------------------------------------------------------------- + +static ULONG BackFillClassAskMinMax(Class *cl, Object *o, Msg msg) +{ + struct MUIP_AskMinMax *amm = (struct MUIP_AskMinMax *) msg; + struct BackFillInst *inst = INST_DATA(cl, o); + UWORD Size; + ULONG Result; + + Result = DoSuperMethodA(cl, o, msg); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: o=%08lx\n", __LINE__, o)); + + // our BitMap images are always square + Size = max(inst->bfi_Width, inst->bfi_Height); + + amm->MinMaxInfo->MinWidth = Size + _subwidth(o); + amm->MinMaxInfo->MinHeight = Size + _subheight(o); + amm->MinMaxInfo->MaxWidth = Size + _subwidth(o); + amm->MinMaxInfo->MaxHeight = Size + _subheight(o); + amm->MinMaxInfo->DefWidth = Size + _subwidth(o); + amm->MinMaxInfo->DefHeight = Size + _subheight(o); + + return Result; +} + +//---------------------------------------------------------------------------- + +static ULONG BackFillSet(Class *cl, Object *o, Msg msg) +{ + struct opSet *ops = (struct opSet *) msg; + struct BackFillInst *inst = INST_DATA(cl, o); + BOOL DoRedraw = FALSE; + BOOL DoRelayout = FALSE; + ULONG Result; + + if (FindTagItem(BFA_BitmapObject, ops->ops_AttrList)) + { + Object *NewBitMapObj; + + NewBitMapObj = (Object *) GetTagData(BFA_BitmapObject, (ULONG) inst->bfi_BitMapObject, ops->ops_AttrList); + + CloneBitMapObject(cl, o, NewBitMapObj); + DoRedraw = TRUE; + } + + Result = DoSuperMethodA(cl, o, msg); + + if (DoRelayout) + ForceRelayout(cl, o); + else if (DoRedraw) + MUI_Redraw(o, MADF_DRAWOBJECT); + + return Result; +} + +//---------------------------------------------------------------------------- + +static ULONG BackFillDraw(Class *cl, Object *o, Msg msg) +{ + struct BackFillInst *inst = INST_DATA(cl, o); + struct MUIP_Draw *mDraw = (struct MUIP_Draw *) msg; + ULONG ShowMe = 0; + + get(o, MUIA_ShowMe, &ShowMe); + + if (!ShowMe) + return 0; + + DoSuperMethodA(cl, o, msg); + + if (mDraw->flags & MADF_DRAWOBJECT) + { + if (inst->bfi_BitMapObject && inst->bfi_GenericBitMapObject) + { + struct BitMap *bm = NULL; + + get(inst->bfi_BitMapObject, MUIA_Bitmap_RemappedBitmap, &bm); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: BitMapObject=%08lx BitMap=%08lx\n", \ + __LINE__, inst->bfi_BitMapObject, inst->bfi_BitMap)); + + if (bm) + { + WORD Width, Height; + WORD MinX, MinY; + UWORD SizeX, SizeY; + + MinX = _left(o) + _addleft(o); + MinY = _top(o) + _addtop(o); + Width = _width(o) - _subwidth(o); + Height = _height(o) - _subheight(o); + + SizeX = min(Width, inst->bfi_Width); + SizeY = min(Height, inst->bfi_Height); + + MinX += (Width - inst->bfi_Width) / 2; + MinY += (Height - inst->bfi_Height) / 2; + + BltBitMapRastPort(bm, + 0, 0, + _rp(o), + MinX, MinY, + SizeX, SizeY, + 0xC0); + } + } + } + + return 0; +} + +//---------------------------------------------------------------------------- + +static void CloneBitMapObject(Class *cl, Object *o, Object *NewBitMapObj) +{ + struct BackFillInst *inst = INST_DATA(cl, o); + + if (inst->bfi_BitMapObject) + { + // delete existing bfi_BitMapObject + DoMethod(o, MUIM_Group_InitChange); + DoMethod(o, OM_REMMEMBER, inst->bfi_BitMapObject); + DoMethod(o, MUIM_Group_ExitChange); + + MUI_DisposeObject(inst->bfi_BitMapObject); + inst->bfi_BitMapObject = NULL; + } + + if (NewBitMapObj) + { + ULONG Width = 0; + + // check whether this is a BitmapObject by querying MUIA_Bitmap_Width + if (get(NewBitMapObj, MUIA_Bitmap_Width, &Width)) + { + ULONG Height = 0; + struct BitMap *NewBitMap = NULL; + ULONG *SourceColors = NULL; + + inst->bfi_GenericBitMapObject = TRUE; + + get(NewBitMapObj, MUIA_Bitmap_Width, &Width); + get(NewBitMapObj, MUIA_Bitmap_Height, &Height); + get(NewBitMapObj, MUIA_Bitmap_Bitmap, &NewBitMap); + get(NewBitMapObj, MUIA_Bitmap_SourceColors, &SourceColors); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: BitmapObject BitMap=%08lx SourceColors=%08lx\n", \ + __LINE__, NewBitMap, SourceColors)); + + // Remember image dimensions + inst->bfi_Width = Width; + inst->bfi_Height = Height; + + inst->bfi_BitMapObject = BitmapObject, + MUIA_Bitmap_Width, Width, + MUIA_Bitmap_Height, Height, + MUIA_Bitmap_Bitmap, (IPTR) NewBitMap, + MUIA_Bitmap_SourceColors, (IPTR) SourceColors, + MUIA_Bitmap_UseFriend, TRUE, + MUIA_Bitmap_Precision, PRECISION_ICON, + End; + } + else + { + // this is a BitMapPicClass object + struct BitMap *bm = NULL; + ULONG *ColorTable = NULL; + UBYTE *BitMapArray = NULL; + struct Screen *screen = NULL; + ULONG Height = 0; + + inst->bfi_GenericBitMapObject = FALSE; + + get(NewBitMapObj, MUIA_ScaBitMappic_BitMap, &bm); + get(NewBitMapObj, MUIA_ScaBitMappic_ColorTable, &ColorTable); + get(NewBitMapObj, MUIA_ScaBitMappic_Width, &Width); + get(NewBitMapObj, MUIA_ScaBitMappic_Height, &Height); + get(NewBitMapObj, MUIA_ScaBitmappic_BitMapArray, &BitMapArray); + get(NewBitMapObj, MUIA_ScaBitMappic_Screen, &screen); + + inst->bfi_BitMapObject = BitMapPicObject, + MUIA_ScaBitMappic_BitMap, (IPTR) bm, + MUIA_ScaBitMappic_ColorTable, (IPTR) ColorTable, + MUIA_ScaBitMappic_Width, Width, + MUIA_ScaBitMappic_Height, Height, + MUIA_ScaBitMappic_Screen, (IPTR) screen, + MUIA_ScaBitmappic_BitMapArray, (IPTR) BitMapArray, + End; + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: bfi_BitMapObject=%08lx\n", __LINE__, inst->bfi_BitMapObject)); + } + } + + if (inst->bfi_BitMapObject) + { + DoMethod(o, MUIM_Group_InitChange); + DoMethod(o, OM_ADDMEMBER, inst->bfi_BitMapObject); + DoMethod(o, MUIM_Group_ExitChange); + } +} + +//---------------------------------------------------------------------------- + +struct MUI_CustomClass *InitBackfillClass(void) +{ + if (0x4711 == Signature++) + { + BackfillClass = MUI_CreateCustomClass(NULL, MUIC_Group, NULL, + sizeof(struct BackFillInst), DISPATCHER_REF(Backfill)); + } + + return BackfillClass; +} + +void CleanupBackfillClass(void) +{ + if (BackfillClass) + { + MUI_DeleteCustomClass(BackfillClass); + BackfillClass = NULL; + Signature = 0x4711; + } +} + +//---------------------------------------------------------------------------- + +static void ForceRelayout(struct IClass *cl, Object *obj) +{ + Object *WindowObj; + Object *RootObj = NULL; + + if (muiRenderInfo(obj)) + { + WindowObj = _win(obj); + get(WindowObj, MUIA_Window_RootObject, &RootObj); + + if (RootObj) + { + // force relayout + DoMethod(RootObj, MUIM_Group_InitChange); + DoMethod(RootObj, MUIM_Group_ExitChange); + } + } +} + +//---------------------------------------------------------------------------- + diff --git a/scalos/common/BackfillMCC/Backfill.h b/scalos/common/BackfillMCC/Backfill.h new file mode 100644 index 000000000..9e050497b --- /dev/null +++ b/scalos/common/BackfillMCC/Backfill.h @@ -0,0 +1,47 @@ +// Backfill.h +// $Date$ +// $Revision$ + + +#ifndef SCALOS_BACKFILL_H +#define SCALOS_BACKFILL_H + +//---------------------------------------------------------------------------- + +#define BACKFILLBASE 0x80430100 + + +#define BFA_BitmapObject (BACKFILLBASE+1) // [IS.] Object * + +//---------------------------------------------------------------------------- + +struct SetBackFillMsg + { + ULONG sbf_MethodID; + CONST_STRPTR sbf_FileName; + ULONG sbf_PattFlags; + ULONG sbf_DefsFlags; + }; + +//---------------------------------------------------------------------------- + +extern struct MUI_CustomClass *BackfillClass; +extern struct MUI_CustomClass *BitMapPicClass; + +#ifdef __AROS__ +#define BackfillObject BOOPSIOBJMACRO_START(BackfillClass->mcc_Class) +#define BitMapPicObject BOOPSIOBJMACRO_START(BitMapPicClass->mcc_Class) +#else +#define BackfillObject NewObject(BackfillClass->mcc_Class, 0 +#define BitMapPicObject NewObject(BitMapPicClass->mcc_Class, 0 +#endif + +//---------------------------------------------------------------------------- + +struct MUI_CustomClass *InitBackfillClass(void); +void CleanupBackfillClass(void); + +//---------------------------------------------------------------------------- + +#endif /* SCALOS_BACKFILL_H */ + diff --git a/scalos/common/BitMapMCC/BitMapMCC.c b/scalos/common/BitMapMCC/BitMapMCC.c new file mode 100644 index 000000000..ab31d5ce7 --- /dev/null +++ b/scalos/common/BitMapMCC/BitMapMCC.c @@ -0,0 +1,456 @@ +// BitMapMCC.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define NO_INLINE_STDARG +#include + +#include + +#include +#include "debug.h" +#include "BitMapMCC.h" + + +#define CLASS MUIC_BitMappic +#define SUPERCLASS MUIC_Area + +struct BitMapMCCInstance +{ + struct BitMap *BitMap; + PLANEPTR MaskPlane; + struct Screen *Screen; + const ULONG *ColorTable; + ULONG Width; + ULONG Height; + const UBYTE *BitMapArray; + struct ARGB *PixelArray; + ULONG NumColors; // number of colors in ColorTable +}; + +/* ------------------------------------------------------------------------- */ + +static ULONG mNew(struct IClass *cl,Object *obj,Msg msg); +static ULONG mDispose(struct IClass *cl,Object *obj,Msg msg); +static ULONG mSetup(struct IClass *cl,Object *obj,Msg msg); +static ULONG mCleanup(struct IClass *cl,Object *obj,Msg msg); +static ULONG mAskMinMax(struct IClass *cl,Object *obj,struct MUIP_AskMinMax *msg); +static ULONG mDraw(struct IClass *cl,Object *obj,struct MUIP_Draw *msg); +DISPATCHER_PROTO(BitMapMCC); +static ULONG mGet(Class *cl, Object *o, struct opGet *opg); +static void ClearInstanceData(struct BitMapMCCInstance *inst); + +/* ------------------------------------------------------------------------- */ + +extern struct Library *CyberGfxBase; + +/* ------------------------------------------------------------------------- */ + +static ULONG mNew(struct IClass *cl,Object *obj,Msg msg) +{ + struct BitMapMCCInstance *inst; + struct opSet *ops; + struct BitMap *TempBM = NULL; + UBYTE *PixelLine = NULL; + BOOL Success = FALSE; + + do { + ULONG ScreenDepth; + + obj = (Object *) DoSuperMethodA(cl, obj, msg); + if (NULL == obj) + break; + + d1(kprintf(__FUNC__ "/%ld: obj=%08lx\n", __LINE__, obj)); + + inst = INST_DATA(cl,obj); + ClearInstanceData(inst); + + ops = (struct opSet *) msg; + + inst->NumColors = 256; + + inst->ColorTable = (ULONG *) GetTagData(MUIA_ScaBitMappic_ColorTable, (ULONG) NULL, ops->ops_AttrList); + inst->Screen = (struct Screen *) GetTagData(MUIA_ScaBitMappic_Screen, (ULONG) NULL, ops->ops_AttrList); + + inst->Width = (ULONG) GetTagData(MUIA_ScaBitMappic_Width, 0, ops->ops_AttrList); + inst->Height = (ULONG) GetTagData(MUIA_ScaBitMappic_Height, 0, ops->ops_AttrList); + + inst->BitMapArray = (UBYTE *) GetTagData(MUIA_ScaBitmappic_BitMapArray, (ULONG) NULL, ops->ops_AttrList); + d1(KPrintF(__FUNC__ "/%ld: inst->BitMapArray=%08lx\n", __LINE__, inst->BitMapArray)); + + inst->BitMap = (struct BitMap *) GetTagData(MUIA_ScaBitMappic_BitMap, (ULONG) NULL, ops->ops_AttrList); + if (NULL == inst->BitMap) + break; + + d1(KPrintF(__FUNC__ "/%ld: inst->BitMap=%08lx\n", __LINE__, inst->BitMap)); + + inst->PixelArray = ScalosGfxCreateARGB(inst->Width, inst->Height, NULL); + d1(KPrintF(__FUNC__ "/%ld: inst->PixelArray=%08lx\n", __LINE__, inst->PixelArray)); + if (NULL == inst->PixelArray) + break; + + ScreenDepth = GetBitMapAttr(inst->Screen->RastPort.BitMap, BMA_DEPTH); + + if (CyberGfxBase && ScreenDepth > 8) + { + if (GetCyberMapAttr(inst->BitMap, CYBRMATTR_ISCYBERGFX)) + { + d1(KPrintF("%s/%ld: CyberGfx BitMap\n", __FUNC__, __LINE__)); + } + else + { + struct ARGB *pPixelArray; + ULONG y; + + d1(KPrintF("%s/%ld: Standard BitMap\n", __FUNC__, __LINE__)); + d1(KPrintF("%s/%ld: ColorTable=%08lx\n", __FUNC__, __LINE__, inst->ColorTable)); + + // Translate pen numbers from BitMapArray into RGB values + if (inst->BitMapArray) + { + const UBYTE *pBitMapArray = inst->BitMapArray; + + for (y = 0, pPixelArray = inst->PixelArray; y < inst->Height; y++) + { + ULONG x; + const UBYTE *pLineArray = pBitMapArray; + + for (x = 0; x < inst->Width; x++) + { + ULONG PenIndex = 3 * *pLineArray++; + + pPixelArray->Alpha = 0; // AA + pPixelArray->Red = (UBYTE) (inst->ColorTable[PenIndex] >> 24); // RR + pPixelArray->Green = (UBYTE) (inst->ColorTable[PenIndex + 1] >> 24); // GG + pPixelArray->Blue = (UBYTE) (inst->ColorTable[PenIndex + 2] >> 24); // BB + + pPixelArray++; + } + + pBitMapArray += PIXELARRAY8_WIDTH(inst->Width); + } + } + else + { + struct RastPort rp; + struct RastPort TempRp; + + PixelLine = malloc(PIXELARRAY8_BUFFERSIZE(inst->Width, 1)); + if (NULL == PixelLine) + break; + + InitRastPort(&TempRp); + TempRp.Layer = NULL; + TempRp.BitMap = TempBM = AllocBitMap(TEMPRP_WIDTH(inst->Width), 1, 8, 0, NULL); + if (NULL == TempBM) + break; + + InitRastPort(&rp); + rp.BitMap = inst->BitMap; + + for (y = 0, pPixelArray = inst->PixelArray; y < inst->Height; y++) + { + ULONG x; + + ReadPixelLine8(&rp, + 0, y, + inst->Width, + PixelLine, + &TempRp); + + for (x = 0; x < inst->Width; x++) + { + ULONG PenIndex = 3 * PixelLine[x]; + + pPixelArray->Alpha = 0; // AA + pPixelArray->Red = (UBYTE) (inst->ColorTable[PenIndex] >> 24); // RR + pPixelArray->Green = (UBYTE) (inst->ColorTable[PenIndex + 1] >> 24); // GG + pPixelArray->Blue = (UBYTE) (inst->ColorTable[PenIndex + 2] >> 24); // BB + + pPixelArray++; + } + } + } + + d1(KPrintF("%s/%ld: PixelArray: %02lx/%02lx/%02lx %02lx/%02lx/%02lx\n", \ + __FUNC__, __LINE__, \ + inst->PixelArray[0].Red, inst->PixelArray[0].Green, inst->PixelArray[0].Blue, \ + inst->PixelArray[1].Red, inst->PixelArray[1].Green, inst->PixelArray[1].Blue, \ + inst->PixelArray[2].Red, inst->PixelArray[2].Green, inst->PixelArray[2].Blue)); + } + } + + Success = TRUE; + } while (0); + + if (TempBM) + FreeBitMap(TempBM); + if (PixelLine) + free(PixelLine); + + if (!Success) + { + d1(kprintf(__FUNC__ "/%ld: obj=%08lx\n", __LINE__, obj)); + if (obj) + { + DisposeObject(obj); + obj = NULL; + } + } + + return((ULONG)obj); +} + + +static ULONG mDispose(struct IClass *cl,Object *obj,Msg msg) +{ + struct BitMapMCCInstance *inst = INST_DATA(cl,obj); + + if (inst->PixelArray) + { + ScalosGfxFreeARGB(&inst->PixelArray); + } + + d1(kprintf(__FUNC__ "/%ld: \n", __LINE__)); + + return DoSuperMethodA(cl, obj, msg); +} + + +static ULONG mSetup(struct IClass *cl,Object *obj,Msg msg) +{ + struct BitMapMCCInstance *inst = INST_DATA(cl,obj); + BOOL Success = FALSE; + + do { + if (!DoSuperMethodA(cl,obj,msg)) + break; + + d1(KPrintF("%s/%ld: BitMap=%08lx\n", __FUNC__, __LINE__, inst->BitMap)); + + if (NULL == inst->BitMap) + break; + + if (NULL == inst->MaskPlane) + { + /* tell MUI not to care about filling our background during MUIM_Draw */ + set(obj, MUIA_FillArea, FALSE); + } + + Success = TRUE; + } while (0); + + return Success; +} + + +static ULONG mCleanup(struct IClass *cl,Object *obj,Msg msg) +{ +// struct BitMapMCCInstance *inst = INST_DATA(cl,obj); + + return DoSuperMethodA(cl,obj,msg); +} + + +static ULONG mAskMinMax(struct IClass *cl,Object *obj,struct MUIP_AskMinMax *msg) +{ + struct BitMapMCCInstance *inst = INST_DATA(cl,obj); + struct MUI_MinMax *mi; + + DoSuperMethodA(cl, obj, (Msg) msg); + + mi = msg->MinMaxInfo; + + if (inst->BitMap) + { + mi->MinWidth += inst->Width ; + mi->MinHeight += inst->Height; + mi->DefWidth += inst->Width ; + mi->DefHeight += inst->Height; +// mi->MaxWidth += inst->Width ; +// mi->MaxHeight += inst->Height; + mi->MaxWidth = 10000; + mi->MaxHeight = 10000; + } + + /* if we have no bitmap, our object's size will be 0 */ + + return(0); +} + + +static ULONG mDraw(struct IClass *cl,Object *obj,struct MUIP_Draw *msg) +{ + struct BitMapMCCInstance *inst = INST_DATA(cl,obj); + + DoSuperMethodA(cl, obj, (Msg) msg); + + if (msg->flags & MADF_DRAWOBJECT) + { + d1(KPrintF("%s/%ld: bitmap=%08lx\n", __FUNC__, __LINE__, inst->BitMap)); + if (inst->BitMap) + { + ULONG Left = _mleft(obj); + ULONG Top = _mtop(obj); + ULONG Width = _mwidth(obj); + ULONG Height = _mheight(obj); + + d1(KPrintF("%s/%ld: PixelArray: %02lx/%02lx/%02lx %02lx/%02lx/%02lx\n", \ + __FUNC__, __LINE__, \ + inst->PixelArray[0].Red, inst->PixelArray[0].Green, inst->PixelArray[0].Blue, \ + inst->PixelArray[1].Red, inst->PixelArray[1].Green, inst->PixelArray[1].Blue, \ + inst->PixelArray[2].Red, inst->PixelArray[2].Green, inst->PixelArray[2].Blue)); + + if (inst->Width < Width) + { + Left += (Width - inst->Width) / 2; + Width = inst->Width; + } + if (inst->Height < Height) + { + Top += (Height - inst->Height) / 2; + Height = inst->Height; + } + + WritePixelArray(inst->PixelArray, + 0, 0, + sizeof(struct ARGB) * inst->Width, + _rp(obj), + Left, Top, + Width, Height, + RECTFMT_ARGB); + } + } + + return(0); +} + + +static ULONG mGet(Class *cl, Object *o, struct opGet *opg) +{ + struct BitMapMCCInstance *inst = INST_DATA(cl, o); + ULONG Result = 0; + + switch (opg->opg_AttrID) + { + case MUIA_ScaBitMappic_ColorTable: + *(opg->opg_Storage) = (ULONG) inst->ColorTable; + Result++; + break; + case MUIA_ScaBitMappic_Screen: + *(opg->opg_Storage) = (ULONG) inst->Screen; + Result++; + break; + case MUIA_ScaBitMappic_Width: + *(opg->opg_Storage) = inst->Width; + Result++; + break; + case MUIA_ScaBitMappic_Height: + *(opg->opg_Storage) = inst->Height; + Result++; + break; + case MUIA_ScaBitmappic_BitMapArray: + *(opg->opg_Storage) = (ULONG) inst->BitMapArray; + Result++; + break; + case MUIA_ScaBitMappic_BitMap: + *(opg->opg_Storage) = (ULONG) inst->BitMap; + Result++; + break; + default: + Result = DoSuperMethodA(cl, o, (Msg) opg); + } + + return Result; +} + + +DISPATCHER(BitMapMCC) +{ + ULONG Result; + + switch (msg->MethodID) + { + case OM_NEW: + d1(KPrintF("%s/%ld: OM_NEW\n", __FUNC__, __LINE__)); + Result = mNew(cl,obj,(APTR)msg); + break; + + case OM_DISPOSE: + d1(KPrintF("%s/%ld: OM_DISPOSE\n", __FUNC__, __LINE__)); + Result = mDispose(cl,obj,(APTR)msg); + break; + + case OM_GET: + d1(KPrintF("%s/%ld: OM_GET\n", __FUNC__, __LINE__)); + Result = mGet(cl, obj, (struct opGet *) msg); + break; + + case MUIM_Setup: + d1(KPrintF("%s/%ld: MUIM_Setup\n", __FUNC__, __LINE__)); + Result = mSetup(cl,obj,(APTR)msg); + break; + + case MUIM_Cleanup: + d1(KPrintF("%s/%ld: MUIM_Cleanup\n", __FUNC__, __LINE__)); + Result = mCleanup(cl,obj,(APTR)msg); + break; + + case MUIM_AskMinMax: + d1(KPrintF("%s/%ld: MUIM_AskMinMax\n", __FUNC__, __LINE__)); + Result = mAskMinMax(cl,obj,(APTR)msg); + break; + + case MUIM_Draw: + d1(KPrintF("%s/%ld: MUIM_Draw\n", __FUNC__, __LINE__)); + Result = mDraw(cl,obj,(APTR)msg); + break; + + default: + d1(KPrintF("%s/%ld: MethodID=%08lx\n", __FUNC__, __LINE__, msg->MethodID)); + Result = DoSuperMethodA(cl,obj,msg); + break; + } + + return Result; +} +DISPATCHER_END + +static void ClearInstanceData(struct BitMapMCCInstance *inst) +{ + memset(inst, 0, sizeof(struct BitMapMCCInstance)); +} + +/* ------------------------------------------------------------------------- */ + +struct MUI_CustomClass *InitBitMappicClass(void) +{ + return MUI_CreateCustomClass(NULL, SUPERCLASS, NULL, sizeof(struct BitMapMCCInstance), DISPATCHER_REF(BitMapMCC)); +} + +void CleanupBitMappicClass(struct MUI_CustomClass *mcc) +{ + MUI_DeleteCustomClass(mcc); +} + + diff --git a/scalos/common/BitMapMCC/BitMapMCC.h b/scalos/common/BitMapMCC/BitMapMCC.h new file mode 100644 index 000000000..c3a8f5f65 --- /dev/null +++ b/scalos/common/BitMapMCC/BitMapMCC.h @@ -0,0 +1,41 @@ +// BitMapMCC.h +// $Date$ +// $Revision$ + + +#ifndef BITMAP_MCC_H +#define BITMAP_MCC_H + +/* ------------------------------------------------------------------------- */ + +#include + +/* ------------------------------------------------------------------------- */ + +struct MUI_CustomClass *InitBitMappicClass(void); +void CleanupBitMappicClass(struct MUI_CustomClass *mcc); + +/* ------------------------------------------------------------------------- */ + +extern struct MUI_CustomClass *DataTypesImageClass; + +#ifdef __AROS__ +#define DataTypesImageObject BOOPSIOBJMACRO_START(DataTypesImageClass->mcc_Class) +#else +#define DataTypesImageObject NewObject(DataTypesImageClass->mcc_Class, 0 +#endif + +/* ------------------------------------------------------------------------- */ + +#define MUIA_BITMAPPIC_TAGBASE 0x8042a875 + +#define MUIA_ScaBitMappic_BitMap (MUIA_BITMAPPIC_TAGBASE+1) // [I.G] struct BitMap * +#define MUIA_ScaBitMappic_ColorTable (MUIA_BITMAPPIC_TAGBASE+2) // [I.G] ULONG * +#define MUIA_ScaBitMappic_Width (MUIA_BITMAPPIC_TAGBASE+3) // [I.G] ULONG +#define MUIA_ScaBitMappic_Height (MUIA_BITMAPPIC_TAGBASE+4) // [I.G] ULONG +#define MUIA_ScaBitMappic_Screen (MUIA_BITMAPPIC_TAGBASE+5) // [I.G] struct Screen * +#define MUIA_ScaBitmappic_BitMapArray (MUIA_BITMAPPIC_TAGBASE+6) // [I.G] UBYTE * + +/* ------------------------------------------------------------------------- */ + +#endif /* BITMAP_MCC_H */ diff --git a/scalos/common/DataTypesMCC/DataTypesMCC.c b/scalos/common/DataTypesMCC/DataTypesMCC.c new file mode 100644 index 000000000..d27883d68 --- /dev/null +++ b/scalos/common/DataTypesMCC/DataTypesMCC.c @@ -0,0 +1,659 @@ +// DataTypesMCC.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include +#include +#include +#define NO_INLINE_STDARG +#include + +#include + +#include +#include "DataTypesMCC.h" + +/* +** Make sure to *always* use V43 datatype tags, even if you dont +** have a gfxboard yourself and still use older datatypes. +** If you don't, your program will annoy many gfxboard-users! +** Check aminet for developer material! +*/ + + +#define CLASS MUIC_Dtpic +#define SUPERCLASS MUIC_Area + +#define DataTypesBase (inst->dtbase) +#ifdef __amigaos4__ +#define IDataTypes (inst->dtiface) +#endif + +struct DtMCCInstance +{ + struct Library *dtbase; +#ifdef __amigaos4__ + struct DataTypesIFace *dtiface; +#endif + STRPTR name; + APTR dto; + struct BitMapHeader *bmhd; + struct BitMap *bitmap; + PLANEPTR MaskPlane; + BOOL FailIfUnavailable; + BOOL Tiled; +}; + +/* ------------------------------------------------------------------------- */ + +static ULONG mNew(struct IClass *cl,Object *obj,Msg msg); +static ULONG mDispose(struct IClass *cl,Object *obj,Msg msg); +static BOOL CreateDto(struct DtMCCInstance *inst); +static VOID freedto(struct DtMCCInstance *inst); +static BOOL SetupDto(Class *cl, Object *obj); +static ULONG mSet(struct IClass *cl, Object *obj, Msg msg); +static ULONG mSetup(struct IClass *cl,Object *obj,Msg msg); +static ULONG mCleanup(struct IClass *cl,Object *obj,Msg msg); +static ULONG mAskMinMax(struct IClass *cl,Object *obj,struct MUIP_AskMinMax *msg); +static ULONG mDraw(struct IClass *cl,Object *obj,struct MUIP_Draw *msg); +DISPATCHER_PROTO(MUI_DataTypesMCC); +static void ClearInstanceData(struct DtMCCInstance *inst); +static void ForceRelayout(struct IClass *cl, Object *obj); + +/* ------------------------------------------------------------------------- */ + +static ULONG mNew(struct IClass *cl,Object *obj,Msg msg) +{ + struct DtMCCInstance *inst; + struct opSet *ops; + CONST_STRPTR FileName; + BOOL Success = FALSE; + + do { + obj = (Object *) DoSuperMethodA(cl, obj, msg); + if (NULL == obj) + break; + + d1(kprintf(__FUNC__ "/%ld: obj=%08lx\n", __LINE__, obj)); + + inst = INST_DATA(cl,obj); + ClearInstanceData(inst); + + ops = (struct opSet *) msg; + + inst->dtbase = OpenLibrary("datatypes.library",39); + d1(KPrintF(__FUNC__ "/%ld: dtbase=%08lx", __LINE__, inst->dtbase)); + if (NULL == inst->dtbase) + break; +#ifdef __amigaos4__ + inst->dtiface = (struct DataTypesIFace *)GetInterface(inst->dtbase, "main", 1, NULL); + if (NULL == inst->dtiface) + break; +#endif + inst->FailIfUnavailable = GetTagData(MUIA_ScaDtpic_FailIfUnavailable, FALSE, ops->ops_AttrList); + inst->Tiled = GetTagData(MUIA_ScaDtpic_Tiled, FALSE, ops->ops_AttrList); + + FileName = (CONST_STRPTR) GetTagData(MUIA_ScaDtpic_Name, (ULONG) NULL, ops->ops_AttrList); + if (NULL == FileName) + break; + + inst->name = strdup(FileName); + if (NULL == inst->name) + break; + + d1(KPrintF(__FUNC__ "/%ld: inst->name=<%s>\n", __LINE__, inst->name)); + + if (!inst->FailIfUnavailable) + Success = TRUE; + + d1(KPrintF("%s/%ld: FileName=<%s> name=<%s>\n", __FUNC__, __LINE__, FileName, inst->name)); + d1(KPrintF(__FUNC__ "/%ld: DataTypesBase=%08lx", __LINE__, DataTypesBase)); + + // create the datatypes object + if (!CreateDto(inst)) + break; + + Success = TRUE; + } while (0); + + if (!Success) + { + d1(kprintf(__FUNC__ "/%ld: obj=%08lx\n", __LINE__, obj)); + if (obj) + { + DisposeObject(obj); + obj = NULL; + } + } + + return((ULONG)obj); +} + +/* ------------------------------------------------------------------------- */ + +static ULONG mDispose(struct IClass *cl,Object *obj,Msg msg) +{ + struct DtMCCInstance *inst = INST_DATA(cl,obj); + + d1(kprintf(__FUNC__ "/%ld: \n", __LINE__)); + + freedto(inst); + + d1(kprintf(__FUNC__ "/%ld: \n", __LINE__)); + + if (inst->name) + { + free(inst->name); + inst->name = NULL; + } + + d1(kprintf(__FUNC__ "/%ld: \n", __LINE__)); + +#ifdef __amigaos4__ + if (inst->dtiface) + { + DropInterface((struct Interface *)inst->dtiface); + inst->dtiface = NULL; + } +#endif + if (inst->dtbase) + { + CloseLibrary(inst->dtbase); + inst->dtbase = NULL; + } + + d1(kprintf(__FUNC__ "/%ld: \n", __LINE__)); + + return DoSuperMethodA(cl, obj, msg); +} + +/* ------------------------------------------------------------------------- */ + +static BOOL CreateDto(struct DtMCCInstance *inst) +{ + struct Process *myproc; + APTR oldwindowptr; + + /* tell DOS not to bother us with requesters */ + myproc = (struct Process *) FindTask(NULL); + oldwindowptr = myproc->pr_WindowPtr; + myproc->pr_WindowPtr = (APTR) -1; + + freedto(inst); // make sure any old datatypes object is freed + + // create the datatypes object + inst->dto = NewDTObject((APTR) inst->name, + DTA_GroupID, GID_PICTURE, + OBP_Precision, PRECISION_EXACT, + PDTA_FreeSourceBitMap, TRUE, + PDTA_DestMode, PMODE_V43, + PDTA_UseFriendBitMap, TRUE, + TAG_DONE); + + d1(KPrintF("%s/%ld: dto=%08lx\n", __FUNC__, __LINE__, inst->dto)); + + myproc->pr_WindowPtr = oldwindowptr; + + return (BOOL) (NULL != inst->dto); +} + +/* ------------------------------------------------------------------------- */ + +/* do all the setup/layout stuff that's necessary to get a bitmap from the dto */ +/* note that when using V43 datatypes, this might not be a real "struct BitMap *" */ + +static BOOL SetupDto(Class *cl, Object *obj) +{ + BOOL Success = FALSE; + + do { + struct FrameInfo fri = { 0 }; + struct DtMCCInstance *inst = INST_DATA(cl,obj); + + if (NULL == inst->dto) + break; + + d1(KPrintF("%s/%ld: muiRenderInfo=%08lx\n", __FUNC__, __LINE__, muiRenderInfo(obj))); + if (NULL == muiRenderInfo(obj)) + break; + + d1(KPrintF("%s/%ld: screen=%08lx\n", __FUNC__, __LINE__, _screen(obj))); + d1(KPrintF("%s/%ld: win=%08lx\n", __FUNC__, __LINE__, _win(obj))); + + SetAttrs(inst->dto, + PDTA_Screen, (ULONG) _screen(obj), + TAG_END); + + DoMethod(inst->dto, + DTM_FRAMEBOX, NULL, &fri, &fri, sizeof(struct FrameInfo), 0); + + d1(KPrintF("%s/%ld: Depth=%ld\n", __FUNC__, __LINE__, fri.fri_Dimensions.Depth)); + if (fri.fri_Dimensions.Depth <= 0) + break; + + if (!DoDTMethod(inst->dto, NULL, NULL, DTM_PROCLAYOUT, NULL, TRUE)) + break; + + get(inst->dto, PDTA_BitMapHeader, &inst->bmhd); + d1(KPrintF("%s/%ld: bmhd=%08lx\n", __FUNC__, __LINE__, inst->bmhd)); + if (NULL == inst->bmhd) + break; + + GetDTAttrs(inst->dto, PDTA_DestBitMap, (ULONG) &inst->bitmap, TAG_DONE); + d1(KPrintF("%s/%ld: bitmap=%08lx\n", __FUNC__, __LINE__, inst->bitmap)); + d1(KPrintF("%s/%ld: bmh_Masking=%ld\n", __FUNC__, __LINE__, inst->bmhd->bmh_Masking)); + + GetDTAttrs(inst->dto, + PDTA_MaskPlane, (ULONG) &inst->MaskPlane, + TAG_END); + d1(KPrintF("%s/%ld: MaskPlane=%08lx\n", __FUNC__, __LINE__, inst->MaskPlane)); + + if (NULL == inst->bitmap) + GetDTAttrs(inst->dto, PDTA_BitMap, (ULONG) &inst->bitmap, TAG_DONE); + + if (NULL == inst->bitmap) + break; + + /* tell MUI not to care about filling our background during MUIM_Draw */ + set(obj, MUIA_FillArea, NULL != inst->MaskPlane); + + Success = TRUE; + } while (0); + + d1(KPrintF("%s/%ld: Success=%ld\n", __FUNC__, __LINE__, Success)); + + return Success; +} + +/* ------------------------------------------------------------------------- */ + +/* +** free the datatypes object. +** called from cleanup method or when setup failed somehow +*/ + +static VOID freedto(struct DtMCCInstance *inst) +{ + inst->bitmap = NULL; + inst->bmhd = NULL; + + if (inst->dto) + { + DisposeDTObject(inst->dto); + inst->dto = NULL; + } +} + +/* ------------------------------------------------------------------------- */ + +static ULONG mSet(struct IClass *cl, Object *obj, Msg msg) +{ + struct DtMCCInstance *inst = INST_DATA(cl,obj); + struct opSet *ops = (struct opSet *) msg; + CONST_STRPTR FileName; + STRPTR NewFileName; + struct TagItem *ti; + + inst->FailIfUnavailable = GetTagData(MUIA_ScaDtpic_FailIfUnavailable, inst->FailIfUnavailable, ops->ops_AttrList); + FileName = (CONST_STRPTR) GetTagData(MUIA_ScaDtpic_Name, (ULONG) inst->name, ops->ops_AttrList); + + if (FileName) + NewFileName = strdup(FileName); + else + NewFileName = NULL; + + if (inst->name) + free(inst->name); + inst->name = NewFileName; + d1(KPrintF("%s/%ld: name=<%s>\n", __FUNC__, __LINE__, inst->name)); + + if (FindTagItem(MUIA_ScaDtpic_Name, ops->ops_AttrList)) + { + WORD OldWidth, OldHeight; + WORD NewWidth, NewHeight; + + d1(KPrintF("%s/%ld: name=<%s>\n", __FUNC__, __LINE__, inst->name)); + + OldWidth = inst->bmhd ? inst->bmhd->bmh_Width : 0; + OldHeight = inst->bmhd ? inst->bmhd->bmh_Height : 0; + + d1(KPrintF("%s/%ld: name=<%s>\n", __FUNC__, __LINE__, inst->name)); + + (void) CreateDto(inst); + d1(KPrintF("%s/%ld: name=<%s>\n", __FUNC__, __LINE__, inst->name)); + (void) SetupDto(cl, obj); + d1(KPrintF("%s/%ld: name=<%s>\n", __FUNC__, __LINE__, inst->name)); + + NewWidth = inst->bmhd ? inst->bmhd->bmh_Width : 0; + NewHeight = inst->bmhd ? inst->bmhd->bmh_Height : 0; + + d1(KPrintF("%s/%ld: OldWidth=%ld OldHeight=%ld\n", __FUNC__, __LINE__, OldWidth, OldHeight)); + d1(KPrintF("%s/%ld: NewWidth=%ld NewHeight=%ld\n", __FUNC__, __LINE__, NewWidth, NewHeight)); + + if (OldWidth != NewWidth || OldHeight != NewHeight) + { + // Setting an image with different size requires relayout + d1(KPrintF("%s/%ld: name=<%s>\n", __FUNC__, __LINE__, inst->name)); + ForceRelayout(cl, obj); + } + else + { + // Image has changed - redraw ourself + d1(KPrintF("%s/%ld: name=<%s>\n", __FUNC__, __LINE__, inst->name)); + MUI_Redraw(obj, MADF_DRAWOBJECT); + } + d1(KPrintF("%s/%ld: name=<%s>\n", __FUNC__, __LINE__, inst->name)); + } + ti = FindTagItem(MUIA_ScaDtpic_Tiled, ops->ops_AttrList); + if (ti) + { + if (inst->Tiled != ti->ti_Data) + { + inst->Tiled = ti->ti_Data; + ForceRelayout(cl, obj); + } + } + + + return DoSuperMethodA(cl, obj, msg); +} + +/* ------------------------------------------------------------------------- */ + +static ULONG mSetup(struct IClass *cl, Object *obj, Msg msg) +{ + struct DtMCCInstance *inst = INST_DATA(cl,obj); + BOOL Success = FALSE; + + do { + if (!DoSuperMethodA(cl, obj, msg)) + break; + + d1(KPrintF("%s/%ld: name=<%s>\n", __FUNC__, __LINE__, inst->name)); + + if (!inst->FailIfUnavailable) + Success = TRUE; + + // inst->dto can be NULL after mCleanup (e.g. window was iconified) + if (NULL == inst->dto) + { + // re-create the datatypes object + inst->dto = NewDTObject((APTR) inst->name, + DTA_GroupID, GID_PICTURE, + OBP_Precision, PRECISION_EXACT, + PDTA_FreeSourceBitMap, TRUE, + PDTA_DestMode, PMODE_V43, + PDTA_UseFriendBitMap, TRUE, + TAG_DONE); + + d1(KPrintF("%s/%ld: dto=%08lx\n", __FUNC__, __LINE__, inst->dto)); + } + + if (NULL == inst->dto) + break; + d1(KPrintF("%s/%ld: dto=%08lx\n", __FUNC__, __LINE__, inst->dto)); + + if (!SetupDto(cl, obj)) + break; + + Success = TRUE; + } while (0); + + return Success; +} + +/* ------------------------------------------------------------------------- */ + +static ULONG mCleanup(struct IClass *cl,Object *obj,Msg msg) +{ + struct DtMCCInstance *inst = INST_DATA(cl,obj); + + freedto(inst); + + return DoSuperMethodA(cl,obj,msg); +} + +/* ------------------------------------------------------------------------- */ + +static ULONG mAskMinMax(struct IClass *cl,Object *obj,struct MUIP_AskMinMax *msg) +{ + struct DtMCCInstance *inst = INST_DATA(cl,obj); + struct MUI_MinMax *mi; + + DoSuperMethodA(cl, obj, (Msg) msg); + + mi = msg->MinMaxInfo; + + if (inst->bmhd) + { + mi->MinWidth += inst->bmhd->bmh_Width ; + mi->MinHeight += inst->bmhd->bmh_Height; + mi->DefWidth += inst->bmhd->bmh_Width ; + mi->DefHeight += inst->bmhd->bmh_Height; + mi->MaxWidth += inst->bmhd->bmh_Width ; + mi->MaxHeight += inst->bmhd->bmh_Height; + } + + d1(KPrintF("%s/%ld: bmhd=%08lx\n", __FUNC__, __LINE__, inst->bmhd)); + d1(KPrintF("%s/%ld: DefWidth=%ld DefHeight=%ld\n", __FUNC__, __LINE__, mi->DefWidth, mi->DefHeight)); + + /* if we have no bitmap header, our object's size will be 0 */ + + return(0); +} + +/* ------------------------------------------------------------------------- */ + +static ULONG mDraw(struct IClass *cl,Object *obj,struct MUIP_Draw *msg) +{ + struct DtMCCInstance *inst = INST_DATA(cl,obj); + + DoSuperMethodA(cl, obj, (Msg) msg); + + if (msg->flags & MADF_DRAWOBJECT) + { + d1(KPrintF("%s/%ld: bitmap=%08lx\n", __FUNC__, __LINE__, inst->bitmap)); +#if 1 + if (inst->bitmap) + { + WORD Width, Height; + WORD MinX, MinY; + + MinX = _mleft(obj); + MinY = _mtop(obj); + Width = _mwidth(obj); + Height = _mheight(obj); + + if (inst->Tiled) + { + ULONG StartOffset; + WORD MaxX, MaxY; + + StartOffset = 0; + MaxX = MinX + Width - 1; + MaxY = MinY + Height - 1; + + while (MinY <= MaxY) + { + WORD SizeY; + WORD x; + + SizeY = MaxY - MinY + 1; + if (SizeY > inst->bmhd->bmh_Height) + SizeY = inst->bmhd->bmh_Height; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: MinY=%ld SizeY=%ld\n", __LINE__, MinY, SizeY)); + + for (x=MinX; x<=MaxX; ) + { + WORD SizeX = MaxX - x + 1; + + if (SizeX > inst->bmhd->bmh_Width) + SizeX = inst->bmhd->bmh_Width; + + d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: x=%ld SizeX=%ld\n", __LINE__, x, SizeX)); + + BltBitMapRastPort(inst->bitmap, + 0, StartOffset, + _rp(obj), + x, MinY, + SizeX, SizeY, + 0xC0); + + x += SizeX; + } + + MinY += SizeY; + } + } + else + { + if (inst->MaskPlane) + { + BltMaskBitMapRastPort(inst->bitmap, + 0, 0, + _rp(obj), + _mleft(obj),_mtop(obj), + _mwidth(obj),_mheight(obj), + ABC | ABNC | ANBC, + inst->MaskPlane); + } + else + { + BltBitMapRastPort(inst->bitmap, + 0, 0, + _rp(obj), + _mleft(obj),_mtop(obj), + _mwidth(obj),_mheight(obj), + 0xc0); + } + } + } +#else + if (inst->dto) + { + SetAttrs(inst->dto, + PDTA_Screen, (ULONG) _screen(obj), + TAG_END); + DoDTMethod(inst->dto, + _window(obj), NULL, + DTM_DRAW, + _rp(obj), + _mleft(obj), _mtop(obj), + _mwidth(obj),_mheight(obj), + 5, 5, + NULL + ); + } +#endif + } + + return(0); +} + +/* ------------------------------------------------------------------------- */ + +DISPATCHER(MUI_DataTypesMCC) +{ + ULONG Result; + + switch (msg->MethodID) + { + case OM_NEW: + d1(KPrintF("%s/%ld: OM_NEW\n", __FUNC__, __LINE__)); + Result = mNew(cl,obj,(APTR)msg); + break; + + case OM_DISPOSE: + d1(KPrintF("%s/%ld: OM_DISPOSE\n", __FUNC__, __LINE__)); + Result = mDispose(cl,obj,(APTR)msg); + break; + + case OM_SET: + d1(KPrintF("%s/%ld: OM_SET", __FUNC__, __LINE__)); + Result = mSet(cl,obj,(APTR)msg); + break; + + case MUIM_Setup: + d1(KPrintF("%s/%ld: MUIM_Setup\n", __FUNC__, __LINE__)); + Result = mSetup(cl,obj,(APTR)msg); + break; + + case MUIM_Cleanup: + d1(KPrintF("%s/%ld: MUIM_Cleanup\n", __FUNC__, __LINE__)); + Result = mCleanup(cl,obj,(APTR)msg); + break; + + case MUIM_AskMinMax: + d1(KPrintF("%s/%ld: MUIM_AskMinMax\n", __FUNC__, __LINE__)); + Result = mAskMinMax(cl,obj,(APTR)msg); + break; + + case MUIM_Draw: + d1(KPrintF("%s/%ld: MUIM_Draw\n", __FUNC__, __LINE__)); + Result = mDraw(cl,obj,(APTR)msg); + break; + + default: + d1(kprintf("%s/%ld: MethodID=%08lx\n", __FUNC__, __LINE__, msg->MethodID)); + Result = DoSuperMethodA(cl,obj,msg); + break; + } + + return Result; +} +DISPATCHER_END + +/* ------------------------------------------------------------------------- */ + +static void ClearInstanceData(struct DtMCCInstance *inst) +{ + memset(inst, 0, sizeof(struct DtMCCInstance)); +} + +/* ------------------------------------------------------------------------- */ + +struct MUI_CustomClass *InitDtpicClass(void) +{ + return MUI_CreateCustomClass(NULL, SUPERCLASS, NULL, sizeof(struct DtMCCInstance), DISPATCHER_REF(MUI_DataTypesMCC)); +} + +void CleanupDtpicClass(struct MUI_CustomClass *mcc) +{ + MUI_DeleteCustomClass(mcc); +} + +/* ------------------------------------------------------------------------- */ + +static void ForceRelayout(struct IClass *cl, Object *obj) +{ + Object *WindowObj; + Object *RootObj = NULL; + + if (muiRenderInfo(obj)) + { + WindowObj = _win(obj); + get(WindowObj, MUIA_Window_RootObject, &RootObj); + + if (RootObj) + { + // force relayout + DoMethod(RootObj, MUIM_Group_InitChange); + DoMethod(RootObj, MUIM_Group_ExitChange); + } + } +} + +/* ------------------------------------------------------------------------- */ diff --git a/scalos/common/DataTypesMCC/DataTypesMCC.h b/scalos/common/DataTypesMCC/DataTypesMCC.h new file mode 100644 index 000000000..478e88494 --- /dev/null +++ b/scalos/common/DataTypesMCC/DataTypesMCC.h @@ -0,0 +1,47 @@ +// DataTypesMCC.h +// $Date$ +// $Revision$ + + +#ifndef DATATYPES_MCC_H +#define DATATYPES_MCC_H + +/* ------------------------------------------------------------------------- */ + +#include + +/* ------------------------------------------------------------------------- */ + +struct MUI_CustomClass *InitDtpicClass(void); +void CleanupDtpicClass(struct MUI_CustomClass *mcc); + +/* ------------------------------------------------------------------------- */ + +extern struct MUI_CustomClass *DataTypesImageClass; + +#ifdef __AROS__ +#define DataTypesImageObject BOOPSIOBJMACRO_START(DataTypesImageClass->mcc_Class) +#else +#define DataTypesImageObject NewObject(DataTypesImageClass->mcc_Class, 0 +#endif + +/* ------------------------------------------------------------------------- */ + +#define MUIA_DTPIC_TAGBASE 0x80429875 + +#define MUIA_ScaDtpic_Name (MUIA_DTPIC_TAGBASE+1) // [IS.] CONST_STRPTR +#define MUIA_ScaDtpic_FailIfUnavailable (MUIA_DTPIC_TAGBASE+2) // [I..] ULONG +#define MUIA_ScaDtpic_Tiled (MUIA_DTPIC_TAGBASE+3) // [IS.] ULONG + +//---------------------------------------------------------------------------- + +#define d1(x) ; +#define d2(x) x; + +// from debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +/* ------------------------------------------------------------------------- */ + +#endif /* DATATYPES_MCC_H */ diff --git a/scalos/common/FontSampleMCC/FontSampleMCC.c b/scalos/common/FontSampleMCC/FontSampleMCC.c new file mode 100755 index 000000000..1603472e3 --- /dev/null +++ b/scalos/common/FontSampleMCC/FontSampleMCC.c @@ -0,0 +1,593 @@ +// FontSampleMCC.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include +#include +#include +#define USE_INLINE_STDARG +#include +#undef USE_INLINE_STDARG +#define NO_INLINE_STDARG +#include + +#include + +#include +#include "FontSampleMCC.h" + +/* ------------------------------------------------------------------------- */ + +struct FsMCCInstance + { + APTR fsm_TTFontHandle; // Font handle from TT_OpenFontA() + struct TextFont *fsm_StdFont; // Font handle from OpenDiskFont() + STRPTR fsm_String; // Demo text that displays in area + STRPTR fsm_TTFontDesc; // TT Font descriptor + STRPTR fsm_StdFontDesc; // Standard Font descriptor + ULONG fsm_FontBaseLine; + BYTE fsm_AntiAlias; + WORD fsm_Gamma; + BOOL fsm_NeedRelayout; + ULONG fsm_HAlign; // horizontal alignment + ULONG fsm_VAlign; // vertical alignment + struct TextExtent fsm_TextExtent; + }; + +/* ------------------------------------------------------------------------- */ + +extern struct Library *TTEngineBase; + +/* ------------------------------------------------------------------------- */ + +static ULONG mNew(struct IClass *cl,Object *obj,Msg msg); +static ULONG mDispose(struct IClass *cl, Object *obj, Msg msg); +static ULONG mAskMinMax(struct IClass *cl, Object *obj, struct MUIP_AskMinMax *msg); +static ULONG mDraw(struct IClass *cl, Object *obj, struct MUIP_Draw *msg); +static ULONG mSet(struct IClass *cl, Object *obj, struct opSet *ops); +DISPATCHER_PROTO(FontSampleMCC); +static void ClearInstanceData(struct FsMCCInstance *inst); +static BOOL SetInstanceData(struct FsMCCInstance *inst, struct TagItem *TagList); +static APTR OpenTTFontFromDesc(CONST_STRPTR FontDesc); +static struct TextFont *OpenDiskFontFromDesc(CONST_STRPTR FontDesc); +static void ForceRelayout(struct IClass *cl, Object *obj); +#if !defined(__SASC) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) +static size_t stccpy(char *dest, const char *src, size_t MaxLen); +#endif /* !__SASC && !__MORPHOS__ && !__amigaos4__ */ + +/* ------------------------------------------------------------------------- */ + +static ULONG mNew(struct IClass *cl,Object *obj,Msg msg) +{ + d1(KPrintF("%s/%ld: START obj=%08lx\n", __FUNC__, __LINE__, obj)); + + do { + struct FsMCCInstance *inst; + struct opSet *ops; + + d1(KPrintF("%s/%ld: cl=%08lx obj=%08lx msg=%08lx\n", __FUNC__, __LINE__, cl, obj, msg)); + + obj = (Object *) DoSuperMethodA(cl, obj, msg); + d1(KPrintF("%s/%ld: obj=%08lx\n", __FUNC__, __LINE__, obj)); + if (NULL == obj) + break; + + inst = INST_DATA(cl,obj); + ClearInstanceData(inst); + + inst->fsm_String = strdup("The quick brown fox jumps over the lazy dog"); + + set(obj, MUIA_FillArea, TRUE); + + ops = (struct opSet *) msg; + + SetInstanceData(inst, ops->ops_AttrList); + + inst->fsm_NeedRelayout = FALSE; + } while (0); + + d1(KPrintF("%s/%ld: END obj=%08lx\n", __FUNC__, __LINE__, obj)); + + return((ULONG)obj); +} + + +static ULONG mDispose(struct IClass *cl,Object *obj,Msg msg) +{ + struct FsMCCInstance *inst = INST_DATA(cl,obj); + + if (TTEngineBase && inst->fsm_TTFontHandle) + { + TT_CloseFont(inst->fsm_TTFontHandle); + inst->fsm_TTFontHandle = NULL; + } + if (inst->fsm_StdFont) + { + CloseFont(inst->fsm_StdFont); + inst->fsm_StdFont = NULL; + } + if (inst->fsm_TTFontDesc) + { + free(inst->fsm_TTFontDesc); + inst->fsm_TTFontDesc = NULL; + } + if (inst->fsm_StdFontDesc) + { + free(inst->fsm_StdFontDesc); + inst->fsm_StdFontDesc = NULL; + } + if (inst->fsm_String) + { + free(inst->fsm_String); + inst->fsm_String = NULL; + } + + return DoSuperMethodA(cl, obj, msg); +} + + +static ULONG mAskMinMax(struct IClass *cl,Object *obj,struct MUIP_AskMinMax *msg) +{ + struct FsMCCInstance *inst = INST_DATA(cl,obj); + struct MUI_MinMax *mi; + + DoSuperMethodA(cl, obj, (Msg) msg); + + mi = msg->MinMaxInfo; + + mi->MinWidth += 100; + mi->MinHeight += 4 + inst->fsm_TextExtent.te_Height; + mi->DefWidth += 120; + mi->DefHeight += 4 + inst->fsm_TextExtent.te_Height; + + mi->MaxWidth = MUI_MAXMAX; + mi->MaxHeight = MUI_MAXMAX; + + /* if we cannot show TT text, our minimal size will be 0 */ + + return(0); +} + + +static ULONG mDraw(struct IClass *cl,Object *obj,struct MUIP_Draw *msg) +{ + struct FsMCCInstance *inst = INST_DATA(cl,obj); + + DoSuperMethodA(cl, obj, (Msg) msg); + + if (msg->flags & MADF_DRAWOBJECT) + { + APTR ClipHandle; + LONG x, y; + + d1(kprintf("%s/%s/%ld: TTEngineBase=%08lx fsm_TTFontHandle=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, TTEngineBase, inst->fsm_TTFontHandle)); + d1(kprintf("%s/%s/%ld: width=%ld height=%ld\n", __FILE__, __FUNC__, __LINE__, _mwidth(obj), _mheight(obj))); + d1(kprintf("%s/%s/%ld: subwidth=%ld subheight=%ld\n", __FILE__, __FUNC__, __LINE__, _subwidth(obj), _subheight(obj))); + + ClipHandle = MUI_AddClipping(muiRenderInfo(obj), _mleft(obj), _mtop(obj), _mwidth(obj), _mheight(obj)); + + switch (inst->fsm_HAlign) + { + default: + case FONTSAMPLE_HALIGN_LEFT: + x = _mleft(obj) + 10; + break; + case FONTSAMPLE_HALIGN_CENTER: + x = _mleft(obj) + (_mwidth(obj) - inst->fsm_TextExtent.te_Width) / 2; + break; + case FONTSAMPLE_HALIGN_RIGHT: + x = _mright(obj) - 10 - inst->fsm_TextExtent.te_Width; + break; + } + + switch (inst->fsm_VAlign) + { + default: + case FONTSAMPLE_VALIGN_TOP: + y = _mtop(obj) + 2 + inst->fsm_FontBaseLine; + break; + case FONTSAMPLE_VALIGN_CENTER: + y = _mtop(obj) + (_mheight(obj) - inst->fsm_TextExtent.te_Height) / 2 + inst->fsm_FontBaseLine; + break; + case FONTSAMPLE_VALIGN_BOTTOM: + y = _mbottom(obj) - 2 - inst->fsm_TextExtent.te_Height + inst->fsm_FontBaseLine; + break; + } + + Move(_rp(obj), x, y); + SetAPen(_rp(obj), _pens(obj)[MPEN_TEXT]); + + if (TTEngineBase && inst->fsm_TTFontHandle) + { + TT_SetFont(_rp(obj), inst->fsm_TTFontHandle); + + TT_SetAttrs(_rp(obj), + TT_Window, (ULONG) _window(obj), + TT_Antialias, inst->fsm_AntiAlias, + TT_Gamma, inst->fsm_Gamma, + TAG_END); + + TT_Text(_rp(obj), (STRPTR) inst->fsm_String, strlen(inst->fsm_String)); + + TT_DoneRastPort(_rp(obj)); + } + else + { + if (inst->fsm_StdFont) + SetFont(_rp(obj), inst->fsm_StdFont); + + SetSoftStyle(_rp(obj), FS_NORMAL, FSF_BOLD | FSF_ITALIC | FSF_UNDERLINED | FSF_EXTENDED); + + Text(_rp(obj), (STRPTR) inst->fsm_String, strlen(inst->fsm_String)); + } + + MUI_RemoveClipping(muiRenderInfo(obj), ClipHandle); + } + + return(0); +} + + +static ULONG mSet(struct IClass *cl,Object *obj, struct opSet *ops) +{ + struct FsMCCInstance *inst = INST_DATA(cl,obj); + BOOL NeedRedraw; + + DoSuperMethodA(cl, obj, (Msg) ops); + + NeedRedraw = SetInstanceData(inst, ops->ops_AttrList); + + if (inst->fsm_NeedRelayout) + ForceRelayout(cl, obj); + + if (NeedRedraw) + MUI_Redraw(obj, MADF_DRAWOBJECT); + + return 1; +} + + +DISPATCHER(FontSampleMCC) +{ + ULONG Result; + + d1(KPrintF("%s/%ld: START MethodID=%08lx\n", __FUNC__, __LINE__, msg->MethodID)); + + switch (msg->MethodID) + { + case OM_NEW: + d1(kprintf("%s/%s/%ld: OM_NEW\n", __FILE__, __FUNC__, __LINE__)); + Result = mNew(cl, obj, (APTR)msg); + break; + + case OM_DISPOSE: + d1(kprintf("%s/%s/%ld: OM_DISPOSE\n", __FILE__, __FUNC__, __LINE__)); + Result = mDispose(cl,obj,(APTR)msg); + break; + + case OM_SET: + d1(kprintf("%s/%s/%ld: OM_SET\n", __FILE__, __FUNC__, __LINE__)); + Result = mSet(cl, obj, (struct opSet *) msg); + break; + + case MUIM_AskMinMax: + d1(kprintf("%s/%s/%ld: MUIM_AskMinMax\n", __FILE__, __FUNC__, __LINE__)); + Result = mAskMinMax(cl,obj,(APTR)msg); + break; + + case MUIM_Draw: + d1(kprintf("%s/%s/%ld: MUIM_Draw\n", __FILE__, __FUNC__, __LINE__)); + Result = mDraw(cl,obj,(APTR)msg); + break; + + default: + d1(kprintf("%s/%s/%ld: MethodID=%08lx\n", __FILE__, __FUNC__, __LINE__, msg->MethodID)); + Result = DoSuperMethodA(cl,obj,msg); + break; + } + + d1(KPrintF("%s/%ld: END Result=%08lx\n", __FUNC__, __LINE__, Result)); + + return Result; +} +DISPATCHER_END + + +static void ClearInstanceData(struct FsMCCInstance *inst) +{ + memset(inst, 0, sizeof(struct FsMCCInstance)); + + inst->fsm_AntiAlias = TT_Antialias_On; + inst->fsm_Gamma = 2500; + inst->fsm_HAlign = FONTSAMPLE_HALIGN_CENTER; + inst->fsm_VAlign = FONTSAMPLE_VALIGN_CENTER; +} + + +static BOOL SetInstanceData(struct FsMCCInstance *inst, struct TagItem *TagList) +{ + struct TagItem *tag; + BOOL Redraw = FALSE; + BYTE OldAntiAlias = inst->fsm_AntiAlias; + WORD OldGamma = inst->fsm_Gamma; + + inst->fsm_AntiAlias = (BYTE) GetTagData(MUIA_FontSample_Antialias, (ULONG) inst->fsm_AntiAlias, TagList); + inst->fsm_Gamma = (WORD) GetTagData(MUIA_FontSample_Gamma, (ULONG) inst->fsm_Gamma, TagList); + inst->fsm_HAlign = (WORD) GetTagData(MUIA_FontSample_HAlign, (ULONG) inst->fsm_HAlign, TagList); + inst->fsm_VAlign = (WORD) GetTagData(MUIA_FontSample_VAlign, (ULONG) inst->fsm_VAlign, TagList); + + tag = FindTagItem(MUIA_FontSample_DemoString, TagList); + if (tag) + { + if (inst->fsm_String) + free(inst->fsm_String); + inst->fsm_String = strdup((STRPTR) tag->ti_Data); + } + + tag = FindTagItem(MUIA_FontSample_TTFontDesc, TagList); + if (tag) + { + if (inst->fsm_TTFontDesc) + free(inst->fsm_TTFontDesc); + inst->fsm_TTFontDesc = strdup((STRPTR) tag->ti_Data); + } + + tag = FindTagItem(MUIA_FontSample_StdFontDesc, TagList); + if (tag) + { + if (inst->fsm_StdFontDesc) + free(inst->fsm_StdFontDesc); + inst->fsm_StdFontDesc = strdup((STRPTR) tag->ti_Data); + } + + if (TTEngineBase && inst->fsm_TTFontDesc) + { + if (inst->fsm_TTFontHandle) + TT_CloseFont(inst->fsm_TTFontHandle); + + inst->fsm_TTFontHandle = OpenTTFontFromDesc(inst->fsm_TTFontDesc); + + d1(kprintf("%s/%s/%ld: fsm_TTFontHandle = %08lx FontDesc=<%s>\n", \ + _ __FILE__, __FUNC__, _LINE__, inst->fsm_TTFontHandle, inst->fsm_TTFontDesc ? inst->fsm_TTFontDesc : (STRPTR) "")); + + // Force redraw if antialias or gamma has changed + if (OldGamma != inst->fsm_Gamma || OldAntiAlias != inst->fsm_AntiAlias) + Redraw = TRUE; + + if (inst->fsm_TTFontHandle) + { + struct RastPort rp; + WORD OldHeight; + + + OldHeight = inst->fsm_TextExtent.te_Height; + + InitRastPort(&rp); + + TT_SetFont(&rp, inst->fsm_TTFontHandle); + + TT_GetAttrs(&rp, TT_FontAccentedAscender, (ULONG) &inst->fsm_FontBaseLine, + TAG_END); + + TT_TextExtent(&rp, (STRPTR) inst->fsm_String, strlen(inst->fsm_String), &inst->fsm_TextExtent); + + d1(kprintf("%s/%s/%ld: fsm_TextExtent width=%ld height=%ld\n", \ + __FILE__, __FUNC__, __LINE__, inst->fsm_TextExtent.te_Width, inst->fsm_TextExtent.te_Height)); + + TT_DoneRastPort(&rp); + + Redraw = TRUE; + + if (OldHeight != inst->fsm_TextExtent.te_Height) + inst->fsm_NeedRelayout = TRUE; + } + } + else if (inst->fsm_StdFontDesc) + { + struct RastPort rp; + WORD OldHeight; + + if (inst->fsm_StdFont) + CloseFont(inst->fsm_StdFont); + + inst->fsm_StdFont = OpenDiskFontFromDesc(inst->fsm_StdFontDesc); + + d1(kprintf("%s/%s/%ld: fsm_StdFont=%08lx FontDesc=<%s>\n", \ + __FILE__, __FUNC__, __LINE__, inst->fsm_StdFont, inst->fsm_StdFontDesc ? inst->fsm_StdFontDesc : (STRPTR) "")); + + OldHeight = inst->fsm_TextExtent.te_Height; + + InitRastPort(&rp); + + if (inst->fsm_StdFont) + { + SetFont(&rp, inst->fsm_StdFont); + + inst->fsm_FontBaseLine = inst->fsm_StdFont->tf_Baseline; + } + + TextExtent(&rp, (STRPTR) inst->fsm_String, strlen(inst->fsm_String), &inst->fsm_TextExtent); + + d1(kprintf("%s/%s/%ld: fsm_TextExtent width=%ld height=%ld\n", \ + __FILE__, __FUNC__, __LINE__, inst->fsm_TextExtent.te_Width, inst->fsm_TextExtent.te_Height)); + + Redraw = TRUE; + + if (OldHeight != inst->fsm_TextExtent.te_Height) + inst->fsm_NeedRelayout = TRUE; + } + + return Redraw; +} + + +static APTR OpenTTFontFromDesc(CONST_STRPTR FontDesc) +{ + ULONG FontStyle; + ULONG FontWeight; + ULONG FontSize; + CONST_STRPTR lp; + char NameSpace[MAX_TTFONTDESC]; + STRPTR FamilyTable[2]; + APTR TTFont; + long long1, long2, long3; + + // Font Desc format: + // "style/weight/size/fontname" + + if (NULL == FontDesc) + return NULL; + + if (3 != sscanf(FontDesc, "%ld/%ld/%ld", &long1, &long2, &long3)) + return NULL; + + FontStyle = long1; + FontWeight = long2; + FontSize = long3; + + lp = strchr(FontDesc, '/'); // Find "/" between style and weight + if (NULL == lp) + return NULL; + + lp = strchr(lp + 1, '/'); // Find "/" between weight and size + if (NULL == lp) + return NULL; + + lp = strchr(lp + 1, '/'); // Find "/" between size and name + if (NULL == lp) + return NULL; + + // copy font name + stccpy(NameSpace, 1 + lp, sizeof(NameSpace)); + FamilyTable[0] = NameSpace; + FamilyTable[1] = NULL; + + //TT_OpenFontA() + TTFont = TT_OpenFont(TT_FamilyTable, (ULONG) FamilyTable, + TT_FontSize, FontSize, + TT_FontStyle, FontStyle, + TT_FontWeight, FontWeight, + TAG_END); + + return TTFont; +} + + +static struct TextFont *OpenDiskFontFromDesc(CONST_STRPTR FontDesc) +{ + // Font Desc format: + // "fontname/size" + struct TextFont *Font; + struct TextAttr ta; + CONST_STRPTR fp; + size_t fnLen; + STRPTR FontName; + LONG l; + + for (fp=FontDesc, fnLen=0; *fp && '/' != *fp; fnLen++) + fp++; + + ta.ta_Name = FontName = malloc(fnLen + 5 + 1); + if (NULL == FontName) + return NULL; + + stccpy(ta.ta_Name, FontDesc, 1 + fnLen); + if ((strlen(ta.ta_Name) < strlen(".font")) || + (0 != stricmp(ta.ta_Name + strlen(ta.ta_Name) - strlen(".font"), ".font"))) + { + strcat(ta.ta_Name, ".font"); + } + + if ('/' == *fp) + fp++; + + if (StrToLong(fp, &l)) + ta.ta_YSize = l; + else + ta.ta_YSize = 8; + + ta.ta_Style = FS_NORMAL; + ta.ta_Flags = 0; + + Font = OpenDiskFont(&ta); + + d1(kprintf("%s/%s/%ld: Font=%08lx FontName=<%s> Size=%ld\n", __FILE__, __FUNC__, __LINE__, Font, FontName, ta.ta_YSize)); + + free(FontName); + + return Font; +} + + +static void ForceRelayout(struct IClass *cl, Object *obj) +{ + struct FsMCCInstance *inst = INST_DATA(cl,obj); + Object *WindowObj; + Object *RootObj = NULL; + + inst->fsm_NeedRelayout = FALSE; + + if (muiRenderInfo(obj)) + { + WindowObj = _win(obj); + get(WindowObj, MUIA_Window_RootObject, &RootObj); + + if (RootObj) + { + // force relayout + DoMethod(RootObj, MUIM_Group_InitChange); + DoMethod(RootObj, MUIM_Group_ExitChange); + } + } +} + +/* ------------------------------------------------------------------------- */ + +struct MUI_CustomClass *InitFontSampleClass(void) +{ + return MUI_CreateCustomClass(NULL, MUIC_Area, NULL, sizeof(struct FsMCCInstance), DISPATCHER_REF(FontSampleMCC)); +} + +void CleanupFontSampleClass(struct MUI_CustomClass *mcc) +{ + MUI_DeleteCustomClass(mcc); +} + +/* ------------------------------------------------------------------------- */ + +#if !defined(__SASC) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) +// Replacement for SAS/C library functions + +static size_t stccpy(char *dest, const char *src, size_t MaxLen) +{ + size_t Count = 0; + + while (*src && MaxLen > 1) + { + *dest++ = *src++; + MaxLen--; + Count++; + } + *dest = '\0'; + Count++; + + return Count; +} + +#endif /* !defined(__SASC) && !defined(__MORPHOS__) && !defined(__amigaos4__) */ + diff --git a/scalos/common/FontSampleMCC/FontSampleMCC.h b/scalos/common/FontSampleMCC/FontSampleMCC.h new file mode 100755 index 000000000..2a5e5b40a --- /dev/null +++ b/scalos/common/FontSampleMCC/FontSampleMCC.h @@ -0,0 +1,63 @@ +// FontSampleMCC.h +// $Date$ +// $Revision$ + + +#ifndef FONTSAMPLE_MCC_H +#define FONTSAMPLE_MCC_H + +/* ------------------------------------------------------------------------- */ + +#include + +/* ------------------------------------------------------------------------- */ + +extern struct MUI_CustomClass *FontSampleClass; + +#ifdef __AROS__ +#define FontSampleObject BOOPSIOBJMACRO_START(FontSampleClass->mcc_Class) +#else +#define FontSampleObject NewObject(FontSampleClass->mcc_Class, 0 +#endif + +struct MUI_CustomClass *InitFontSampleClass(void); +void CleanupFontSampleClass(struct MUI_CustomClass *mcc); + +/* ------------------------------------------------------------------------- */ + +#define MAX_TTFONTDESC 256 + +/* ------------------------------------------------------------------------- */ + +#define MUIA_FontSample_TTFontDesc 0x82457651 /* CONST_STRPTR */ +#define MUIA_FontSample_DemoString 0x82457652 /* CONST_STRPTR */ +#define MUIA_FontSample_StdFontDesc 0x82457653 /* CONST_STRPTR */ +#define MUIA_FontSample_Antialias 0x82457654 /* ULONG */ +#define MUIA_FontSample_Gamma 0x82457655 /* ULONG */ +#define MUIA_FontSample_HAlign 0x82457656 /* ULONG */ +#define MUIA_FontSample_VAlign 0x82457657 /* ULONG */ + +//-------------------------------------------------------------------- + +#define FONTSAMPLE_HALIGN_LEFT 1 +#define FONTSAMPLE_HALIGN_CENTER 2 +#define FONTSAMPLE_HALIGN_RIGHT 3 + +#define FONTSAMPLE_VALIGN_TOP 1 +#define FONTSAMPLE_VALIGN_CENTER 2 +#define FONTSAMPLE_VALIGN_BOTTOM 3 + +//-------------------------------------------------------------------- + + +// from debug.lib +extern int kprintf(const char *fmt, ...); + +//-------------------------------------------------------------------- + +#define d1(x) ; +#define d2(x) x; + +/* ------------------------------------------------------------------------- */ + +#endif /* FONTSAMPLE_MCC_H */ diff --git a/scalos/common/Fs/FsAbstraction.c b/scalos/common/Fs/FsAbstraction.c new file mode 100644 index 000000000..58dd752eb --- /dev/null +++ b/scalos/common/Fs/FsAbstraction.c @@ -0,0 +1,588 @@ +// FsAbstraction.c.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include +#include "debug.h" +#include + +#include + +#include +#include + +#include +#include +#include + +#include "int64.h" +#include "FsAbstraction.h" + +//---------------------------------------------------------------------------- + +// local data definitions + +//---------------------------------------------------------------------------- + +// local functions + +//---------------------------------------------------------------------------- + +// local data + +//---------------------------------------------------------------------------- + +BOOL ScalosExamineBegin(T_ExamineData **exd) +{ +#ifdef __amigaos4__ + *exd = NULL; + return TRUE; +#else //__amigaos4__ + *exd = AllocDosObject(DOS_FIB, NULL); + return (BOOL) (NULL != *exd); +#endif //__amigaos4__ +} + +//---------------------------------------------------------------------------- + +void ScalosExamineEnd(T_ExamineData **exd) +{ +#ifdef __amigaos4__ + if (exd && *exd) + { + FreeDosObject(DOS_EXAMINEDATA, *exd); + *exd = NULL; + } +#else //__amigaos4__ + if (exd && *exd) + { + FreeDosObject(DOS_FIB, *exd); + *exd = NULL; + } +#endif //__amigaos4__ +} + +//---------------------------------------------------------------------------- + +BOOL ScalosExamineLock(BPTR lock, T_ExamineData **exd) +{ +#ifdef __amigaos4__ + *exd = ExamineObjectTags(EX_FileLockInput, lock, + TAG_END); + return (NULL != *exd); +#elif defined(__MORPHOS__) && defined(ACTION_EXAMINE_NEXT64) + if (DOSBase->dl_lib.lib_Version >= 51) + return Examine64(lock, *exd, NULL); + else + return Examine(lock, *exd); +#else //__amigaos4__ + return (BOOL) Examine(lock, *exd); +#endif //__amigaos4__ +} + +//---------------------------------------------------------------------------- + +BOOL ScalosExamineFH(BPTR fh, T_ExamineData **exd) +{ +#ifdef __amigaos4__ + *exd = ExamineObjectTags(EX_FileHandleInput, fh, + TAG_END); + return (NULL != *exd); +#elif defined(__MORPHOS__) && defined(ACTION_EXAMINE_NEXT64) + if (DOSBase->dl_lib.lib_Version >= 51) + return ExamineFH64(fh, *exd, NULL); + else + return ExamineFH(fh, *exd); +#else //__amigaos4__ + return ExamineFH(fh, *exd); +#endif //__amigaos4__ +} +//---------------------------------------------------------------------------- + +struct DateStamp *ScalosExamineGetDate(T_ExamineData *exd) +{ +#ifdef __amigaos4__ + return &exd->Date; +#else //__amigaos4__ + return &exd->fib_Date; +#endif //__amigaos4__ +} + +//---------------------------------------------------------------------------- + +ULONG ScalosExamineGetProtection(const T_ExamineData *exd) +{ +#ifdef __amigaos4__ + return exd->Protection; +#else //__amigaos4__ + return (ULONG) exd->fib_Protection; +#endif //__amigaos4__ +} + +//---------------------------------------------------------------------------- + +ULONG64 ScalosExamineGetSize(const T_ExamineData *exd) +{ +#ifdef __amigaos4__ + return exd->FileSize; +#elif defined(__MORPHOS__) && defined(ACTION_EXAMINE_NEXT64) + if (DOSBase->dl_lib.lib_Version >= 51) + { + ULONG64 Size = (ULONG64) exd->fib_un.fib_un_ext.fib_un_ext_Size64; + + // workaround for MorphOS 2.1 sign-extension bug: + // 64bit file size is negative for files with sizes between 2G and 4G + if (0xffffffff == ULONG64_HIGH(Size)) + Size = MakeU64(ULONG64_LOW(Size)); + + return Size; + } + else + { + return MakeU64(exd->fib_Size); + } +#else //__amigaos4__ + return MakeU64(exd->fib_Size); +#endif //__amigaos4__ +} + +//---------------------------------------------------------------------------- + +ULONG ScalosExamineGetBlockCount(const T_ExamineData *exd) +{ +#ifdef __amigaos4__ + if (exd->FileSize >= 0) + { + // Real block count is not available, so we calculate an estimation + return (511 + exd->FileSize) / 512; + } + else + return 1; +#elif defined(__MORPHOS__) + return exd->fib_NumBlocks; +#else //__amigaos4__ + return (ULONG) exd->fib_NumBlocks; +#endif //__amigaos4__ +} + +//---------------------------------------------------------------------------- + +CONST_STRPTR ScalosExamineGetName(const T_ExamineData *exd) +{ +#ifdef __amigaos4__ + return exd->Name; +#else //__amigaos4__ + return exd->fib_FileName; +#endif //__amigaos4__ +} + +//---------------------------------------------------------------------------- + +CONST_STRPTR ScalosExamineGetComment(const T_ExamineData *exd) +{ +#ifdef __amigaos4__ + return exd->Comment; +#else //__amigaos4__ + return exd->fib_Comment; +#endif //__amigaos4__ +} + +//---------------------------------------------------------------------------- + +LONG ScalosExamineGetDirEntryType(const T_ExamineData *exd) +{ + if (NULL == exd) + return ST_FILE; +#ifdef __amigaos4__ + if( EXD_IS_FILE(exd) ) + return ST_FILE; + else if ( EXD_IS_DIRECTORY(exd) ) + return ST_USERDIR; + else if (EXD_IS_SOFTLINK(exd)) + return ST_SOFTLINK; + else if (EXD_IS_PIPE(exd)) + return ST_PIPEFILE; + else + return ST_FILE; +#else //__amigaos4__ + return exd->fib_DirEntryType; +#endif //__amigaos4__ +} + +//---------------------------------------------------------------------------- + +LONG ScalosExamineGetDirEntryTypeRoot(const T_ExamineData *exd, BPTR fLock) +{ + if (NULL == exd) + return ST_FILE; +#ifdef __amigaos4__ + if( EXD_IS_FILE(exd) ) + return ST_FILE; + else if ( EXD_IS_DIRECTORY(exd) ) + { + // Special handling (expensive!) since AmigaOS4 ExamineObject() has no means to recognize volumes + BPTR parentLock = ParentDir(fLock); + if (parentLock) + { + UnLock(parentLock); + return ST_USERDIR; + } + else + { + return ST_ROOT; + } + } + else if (EXD_IS_SOFTLINK(exd)) + return ST_SOFTLINK; + else if (EXD_IS_PIPE(exd)) + return ST_PIPEFILE; + else + return ST_FILE; +#else //__amigaos4__ + return exd->fib_DirEntryType; +#endif //__amigaos4__ +} + +//---------------------------------------------------------------------------- + +LONG ScalosExamineIsDrawer(const T_ExamineData *exd) +{ +#ifdef __amigaos4__ + return EXD_IS_DIRECTORY(exd) ? TRUE : FALSE; +#else //__amigaos4__ + return exd->fib_DirEntryType > 0; +#endif //__amigaos4__ +} + +//---------------------------------------------------------------------------- + +ULONG ScalosExamineGetDirUID(const T_ExamineData *exd) +{ +#ifdef __amigaos4__ + return exd->OwnerUID; +#else //__amigaos4__ + return exd->fib_OwnerUID; +#endif //__amigaos4__ +} +//---------------------------------------------------------------------------- + +ULONG ScalosExamineGetDirGID(const T_ExamineData *exd) +{ +#ifdef __amigaos4__ + return exd->OwnerGID; +#else //__amigaos4__ + return exd->fib_OwnerGID; +#endif //__amigaos4__ +} +//---------------------------------------------------------------------------- + +SLONG64 ScalosSeek(BPTR fh, SLONG64 pos, LONG mode) +{ +#ifdef __amigaos4__ + int64 oldPos = GetFilePosition(fh); + + if (-1LL != oldPos && !ChangeFilePosition(fh, pos, mode)) + { + oldPos = -1LL; + } + return oldPos; +#elif defined(__MORPHOS__) && defined(ACTION_EXAMINE_NEXT64) + if (DOSBase->dl_lib.lib_Version >= 51) + return Seek64(fh, pos, mode); + else + return Seek(fh, ULONG64_LOW(pos), mode); +#else //__amigaos4__ + +#ifdef __GNUC__ + return (SLONG64) Seek(fh, ULONG64_LOW(pos), mode); +#else //__GNUC__ + + SLONG64 res64; + + SLONG64_HIGH(res64) = 0; + SLONG64_LOW(res64) = Seek(fh, ULONG64_LOW(pos), mode); + + return res64; +#endif //__GNUC__ + +#endif //__amigaos4__ +} + +//---------------------------------------------------------------------------- + +BOOL ScalosExamineDirBegin(BPTR lock, T_ExamineDirHandle *edh) +{ +#ifdef __amigaos4__ + *edh = ObtainDirContextTags(EX_FileLockInput, lock, + EX_DataFields, EXF_ALL, + TAG_END); + return (NULL != *edh); +#elif defined(__MORPHOS__) && defined(ACTION_EXAMINE_NEXT64) + *edh = AllocDosObject(DOS_FIB, NULL); + if (NULL == *edh) + return FALSE; + if (DOSBase->dl_lib.lib_Version >= 51) + { + if (!Examine64(lock, *edh, NULL)) + { + FreeDosObject(DOS_FIB, *edh); + *edh = NULL; + } + } + else + { + if (!Examine(lock, *edh)) + { + FreeDosObject(DOS_FIB, *edh); + *edh = NULL; + } + } + d1(KPrintF("%s/%s/%ld: fib=%08lx\n", __FILE__, __FUNC__, __LINE__, *edh)); + return (NULL != *edh); +#else //__amigaos4__ + *edh = AllocDosObject(DOS_FIB, NULL); + if (NULL == *edh) + return FALSE; + if (!Examine(lock, *edh)) + { + FreeDosObject(DOS_FIB, *edh); + *edh = NULL; + } + return (BOOL) (NULL != *edh); +#endif //__amigaos4__ +} + +//---------------------------------------------------------------------------- + +void ScalosExamineDirEnd(T_ExamineDirHandle *edh) +{ +#ifdef __amigaos4__ + if (edh && *edh) + { + ReleaseDirContext(*edh); + *edh = NULL; + } +#else //__amigaos4__ + if (edh && *edh) + { + FreeDosObject(DOS_FIB, *edh); + *edh = NULL; + } +#endif //__amigaos4__ +} + +//---------------------------------------------------------------------------- + +BOOL ScalosExamineDir(BPTR lock, T_ExamineDirHandle *edh, T_ExamineData **exd) +{ +#ifdef __amigaos4__ + (void) lock; + *exd = ExamineDir(*edh); + return (NULL != *exd); +#elif defined(__MORPHOS__) && defined(ACTION_EXAMINE_NEXT64) + if (DOSBase->dl_lib.lib_Version >= 51) + { + if (ExNext64(lock, *edh, NULL)) + { + *exd = *edh; + } + else + { + return FALSE; + } + } + else + { + if (ExNext(lock, *edh)) + { + *exd = *edh; + } + else + { + return FALSE; + } + } + return TRUE; +#else + if (ExNext(lock, *edh)) + { + *exd = *edh; + } + else + { + return FALSE; + } + return TRUE; +#endif //__amigaos4__ +} + +//---------------------------------------------------------------------------- + +BOOL ScalosReadLink(BPTR srcDirLock, CONST_STRPTR srcName, STRPTR Buffer, size_t BuffLen) +{ +#ifdef __amigaos4__ + BOOL Success = FALSE; + BPTR oldDir = CurrentDir(srcDirLock); + struct ExamineData *exd = NULL; + APTR dirContext= NULL; + + do { + if (ParsePatternNoCase(srcName, Buffer, BuffLen) < 0) + break; + + dirContext = ObtainDirContextTags(EX_FileLockInput, srcDirLock, + EX_DataFields, EXF_NAME | EXF_LINK | EXF_TYPE, + EX_MatchString, Buffer, + TAG_END); + if (NULL == dirContext) + break; + + exd = ExamineDir(dirContext); + if (NULL == exd) + break; + + if (!EXD_IS_LINK(exd)) + break; + + stccpy(Buffer, exd->Link, BuffLen); + Success = TRUE; + } while (0); + + if (dirContext) + ReleaseDirContext(dirContext); + + CurrentDir(oldDir); + + return Success; +#else //__amigaos4__ + BOOL Success = FALSE; + struct DevProc *devproc = NULL; + + do { + if (!NameFromLock(srcDirLock, Buffer, BuffLen)) + { + break; + } + + devproc = GetDeviceProc(Buffer, NULL); + if (NULL == devproc) + { + break; + } + + if (!ReadLink(devproc->dvp_Port, srcDirLock, (STRPTR) srcName, + Buffer, BuffLen)) + { + break; + } + Success = TRUE; + } while (0); + + if (devproc) + FreeDeviceProc(devproc); + + return Success; +#endif //__amigaos4__ +} + +//---------------------------------------------------------------------------- + +void ScalosDosPacketExamineDir(struct DosPacket *pkt, BPTR dirLock, T_ExamineDirHandle *edh) +{ +#ifdef __amigaos4__ + pkt->dp_Type = ACTION_EXAMINEDATA_DIR; + pkt->dp_Arg1 = MKBADDR(*edh); + +#elif defined(__MORPHOS__) && defined(ACTION_EXAMINE_NEXT64) + + if (DOSBase->dl_lib.lib_Version >= 51) + { + pkt->dp_Type = ACTION_EXAMINE_NEXT64; + pkt->dp_Arg1 = dirLock; + pkt->dp_Arg2 = MKBADDR(*edh); + pkt->dp_Arg3 = NULL; + } + else + { + pkt->dp_Type = ACTION_EXAMINE_NEXT; + pkt->dp_Arg1 = dirLock; + pkt->dp_Arg2 = MKBADDR(*edh); + } + return; +#else + pkt->dp_Type = ACTION_EXAMINE_NEXT; + pkt->dp_Arg1 = (IPTR) dirLock; + pkt->dp_Arg2 = (IPTR) MKBADDR(*edh); +#endif +} + +//---------------------------------------------------------------------------- + +BOOL ScalosDosPacketExamineDirResult(struct StandardPacket *pkt, T_ExamineData **exd, + T_ExamineDirHandle *edh) +{ +#ifdef __amigaos4__ + if (pkt->sp_Pkt.dp_Res1) + { + *exd = (T_ExamineData *) pkt->sp_Pkt.dp_Res1; + } + else + *exd = NULL; + + return 0 != pkt->sp_Pkt.dp_Res1; +#else + *exd = (T_ExamineData *) *edh; + + return (BOOL) (0 != pkt->sp_Pkt.dp_Res1); +#endif +} + +//---------------------------------------------------------------------------- + +BOOL ScalosSupportsExamineDir(struct MsgPort *fileSysPort, BPTR dirLock, T_ExamineDirHandle *edh) +{ +#ifdef __amigaos4__ + LONG rc; + + rc = DoPkt1(fileSysPort, + ACTION_EXAMINEDATA_DIR, + MKBADDR(edh)); + + d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__, __FUNC__, __LINE__, rc)); + return (BOOL) (0 != rc); +#elif defined(__MORPHOS__) && defined(ACTION_EXAMINE_NEXT64) + LONG rc; + + d1(KPrintF("%s/%s/%ld: fib=%08lx\n", __FILE__, __FUNC__, __LINE__, *edh)); + + rc = DoPkt3(fileSysPort, + ACTION_EXAMINE_OBJECT64, + dirLock, + MKBADDR(*edh), + NULL); + + d1(KPrintF("%s/%s/%ld: rc=%ld\n", __FILE__, __FUNC__, __LINE__, rc)); + return (BOOL) (0 != rc); +#else + return FALSE; +#endif /* __MORPHOS__ */ +} + +//---------------------------------------------------------------------------- + + diff --git a/scalos/common/Fs/FsAbstraction.h b/scalos/common/Fs/FsAbstraction.h new file mode 100755 index 000000000..bdc7b5afd --- /dev/null +++ b/scalos/common/Fs/FsAbstraction.h @@ -0,0 +1,54 @@ +// FsAbstraction.h +// $Date$ +// $Revision$ + +#ifndef SCALOS_FSABSTRACTION_H +#define SCALOS_FSABSTRACTION_H + +#include + +#ifdef __amigaos4__ + +typedef struct ExamineData T_ExamineData; +typedef APTR T_ExamineDirHandle; + +#else //__amigaos4__ + +typedef struct FileInfoBlock T_ExamineData; +typedef struct FileInfoBlock *T_ExamineDirHandle; + +#endif //__amigaos4__ + + +BOOL ScalosExamineBegin(T_ExamineData **exd); +void ScalosExamineEnd(T_ExamineData **exd); +BOOL ScalosExamineLock(BPTR lock, T_ExamineData **exd); +BOOL ScalosExamineFH(BPTR fh, T_ExamineData **exd); + +struct DateStamp *ScalosExamineGetDate(T_ExamineData *exd); +ULONG ScalosExamineGetProtection(const T_ExamineData *exd); +ULONG64 ScalosExamineGetSize(const T_ExamineData *exd); +ULONG ScalosExamineGetBlockCount(const T_ExamineData *exd); +CONST_STRPTR ScalosExamineGetName(const T_ExamineData *exd); +CONST_STRPTR ScalosExamineGetComment(const T_ExamineData *exd); +LONG ScalosExamineGetDirEntryType(const T_ExamineData *exd); +LONG ScalosExamineGetDirEntryTypeRoot(const T_ExamineData *exd, BPTR fLock); +LONG ScalosExamineIsDrawer(const T_ExamineData *exd); +ULONG ScalosExamineGetDirUID(const T_ExamineData *exd); +ULONG ScalosExamineGetDirGID(const T_ExamineData *exd); + +SLONG64 ScalosSeek(BPTR fh, SLONG64 pos, LONG mode); + +BOOL ScalosExamineDirBegin(BPTR lock, T_ExamineDirHandle *edh); +void ScalosExamineDirEnd(T_ExamineDirHandle *edh); +BOOL ScalosExamineDir(BPTR lock, T_ExamineDirHandle *edh, T_ExamineData **exd); + +BOOL ScalosReadLink(BPTR srcDirLock, CONST_STRPTR srcName, STRPTR Buffer, size_t BuffLen); + +void ScalosDosPacketExamineDir(struct DosPacket *pkt, BPTR dirLock, T_ExamineDirHandle *edh); +BOOL ScalosDosPacketExamineDirResult(struct StandardPacket *pkt, T_ExamineData **exd, + T_ExamineDirHandle *edh); +BOOL ScalosSupportsExamineDir(struct MsgPort *fileSysPort, BPTR dirLock, T_ExamineDirHandle *edh); + +#endif /* SCALOS_FSABSTRACTION_H */ + diff --git a/scalos/common/IconobjectMCC/IconobjectMCC.c b/scalos/common/IconobjectMCC/IconobjectMCC.c new file mode 100755 index 000000000..9098fd80d --- /dev/null +++ b/scalos/common/IconobjectMCC/IconobjectMCC.c @@ -0,0 +1,315 @@ +// IconobjectMCC.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "defs.h" +#include "IconobjectMCC.h" +#include "debug.h" + + +#define CLASS MUIC_Iconobject +#define SUPERCLASS MUIC_Area + + +struct DtMCCInstance +{ + Object *Iconobj; + ULONG Selected; +}; + +/* ------------------------------------------------------------------------- */ + +static ULONG mNew(struct IClass *cl,Object *obj,Msg msg); +static ULONG mDispose(struct IClass *cl,Object *obj,Msg msg); +static ULONG mSetup(struct IClass *cl,Object *obj,Msg msg); +static ULONG mCleanup(struct IClass *cl,Object *obj,Msg msg); +static ULONG mAskMinMax(struct IClass *cl,Object *obj, struct MUIP_AskMinMax *msg); +static ULONG mDraw(struct IClass *cl,Object *obj, struct MUIP_Draw *msg); +static ULONG mSet(struct IClass *cl, Object *obj, Msg msg); +static ULONG mGet(struct IClass *cl, Object *obj, Msg msg); + +DISPATCHER_PROTO(MUI); +static void ClearInstanceData(struct DtMCCInstance *inst); +static void ForceRelayout(struct IClass *cl, Object *obj); + +/* ------------------------------------------------------------------------- */ + +static ULONG mNew(struct IClass *cl,Object *obj,Msg msg) +{ + struct DtMCCInstance *inst; + struct opSet *ops; + + if (!(obj=(Object *) DoSuperMethodA(cl,obj,msg))) + return(0); + + inst = INST_DATA(cl,obj); + ClearInstanceData(inst); + + set(obj, MUIA_FillArea, TRUE); + + ops = (struct opSet *) msg; + + inst->Iconobj = (Object *) GetTagData(MUIA_Iconobj_Object, (ULONG)NULL, ops->ops_AttrList); + inst->Selected = GetTagData(MUIA_Selected, FALSE, ops->ops_AttrList); + + return (ULONG) obj; +} + + +static ULONG mDispose(struct IClass *cl,Object *obj,Msg msg) +{ +// struct DtMCCInstance *inst = INST_DATA(cl,obj); + + return DoSuperMethodA(cl, obj, msg); +} + + +static ULONG mSetup(struct IClass *cl,Object *obj,Msg msg) +{ +// struct DtMCCInstance *inst = INST_DATA(cl,obj); + + if (!DoSuperMethodA(cl,obj,msg)) + return(FALSE); + + return(TRUE); +} + + +static ULONG mCleanup(struct IClass *cl,Object *obj,Msg msg) +{ +// struct DtMCCInstance *inst = INST_DATA(cl,obj); + + return DoSuperMethodA(cl,obj,msg); +} + + +static ULONG mAskMinMax(struct IClass *cl,Object *obj,struct MUIP_AskMinMax *msg) +{ + struct DtMCCInstance *inst = INST_DATA(cl,obj); + struct MUI_MinMax *mi; + + DoSuperMethodA(cl, obj, (Msg) msg); + + mi = msg->MinMaxInfo; + + if (inst->Iconobj) + { + const struct ExtGadget *gg = (const struct ExtGadget *) inst->Iconobj; + + d1(KPrintF("%s/%s/%ld: Width=%ld Height=%ld\n", __FILE__, __FUNC__, __LINE__, gg->Width, gg->Height)); + + mi->MinWidth += gg->Width; + mi->MinHeight += gg->Height; + mi->DefWidth += gg->Width; + mi->DefHeight += gg->Height; + mi->MaxWidth += gg->Width; + mi->MaxHeight += gg->Height; + } + + /* if we have no Iconobject, our object's size will be 0 */ + + return(0); +} + + +static ULONG mDraw(struct IClass *cl,Object *obj,struct MUIP_Draw *msg) +{ + struct DtMCCInstance *inst = INST_DATA(cl,obj); + + d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__)); + + DoSuperMethodA(cl, obj, (Msg) msg); + + if (msg->flags & MADF_DRAWOBJECT) + { + if (inst->Iconobj) + { + struct ExtGadget *gg = (struct ExtGadget *) inst->Iconobj; + + if (inst->Selected) + { + gg->Flags |= GFLG_SELECTED; + + if (NULL == gg->SelectRender) + { + DoMethod(inst->Iconobj, IDTM_Layout, + _screen(obj), _window(obj), _rp(obj), _dri(obj), + IOLAYOUTF_SelectedImage); + } + } + else + { + gg->Flags &= ~GFLG_SELECTED; + + if (NULL == gg->GadgetRender) + { + DoMethod(inst->Iconobj, IDTM_Layout, + _screen(obj), _window(obj), _rp(obj), _dri(obj), + IOLAYOUTF_NormalImage); + } + } + + DoMethod(inst->Iconobj, IDTM_Draw, + _screen(obj), _window(obj), _rp(obj), _dri(obj), + _mleft(obj),_mtop(obj), + IODRAWF_AbsolutePos | IODRAWF_NoText | IODRAWF_NoEraseBg); + } + } + + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); + + return(0); +} + + +static ULONG mSet(struct IClass *cl, Object *obj, Msg msg) +{ + struct DtMCCInstance *inst = INST_DATA(cl,obj); + struct opSet *ops = (struct opSet *) msg; + + inst->Iconobj = (Object *) GetTagData(MUIA_Iconobj_Object, (ULONG) inst->Iconobj, ops->ops_AttrList); + inst->Selected = GetTagData(MUIA_Selected, inst->Selected, ops->ops_AttrList); + + // Setting a different IconObj requires relayout + if (FindTagItem(MUIA_Iconobj_Object, ops->ops_AttrList)) + ForceRelayout(cl, obj); + + return DoSuperMethodA(cl, obj, msg); +} + + +static ULONG mGet(struct IClass *cl, Object *obj, Msg msg) +{ + struct DtMCCInstance *inst = INST_DATA(cl,obj); + struct opGet *opg = (struct opGet *) msg; + + switch (opg->opg_AttrID) + { + case MUIA_Selected: + *(opg->opg_Storage) = inst->Selected; + break; + } + + return DoSuperMethodA(cl, obj, msg); +} + + +DISPATCHER(MUI) +{ + ULONG Result; + + switch (msg->MethodID) + { + case OM_NEW: + d1(KPrintF("%s/%s/%ld: OM_NEW\n", __FILE__, __FUNC__, __LINE__)); + Result = mNew(cl, obj, msg); + break; + + case OM_DISPOSE: + d1(KPrintF("%s/%s/%ld: OM_DISPOSE\n", __FILE__, __FUNC__, __LINE__)); + Result = mDispose(cl, obj, msg); + break; + + case OM_SET: + d1(KPrintF("%s/%s/%ld: OM_SET\n", __FILE__, __FUNC__, __LINE__)); + Result = mSet(cl,obj, msg); + break; + + case OM_GET: + d1(KPrintF("%s/%s/%ld: OM_GET\n", __FILE__, __FUNC__, __LINE__)); + Result = mGet(cl, obj, msg); + break; + + case MUIM_Setup: + d1(KPrintF("%s/%s/%ld: MUIM_Setup\n", __FILE__, __FUNC__, __LINE__)); + Result = mSetup(cl, obj, msg); + break; + + case MUIM_Cleanup: + d1(KPrintF("%s/%s/%ld: MUIM_Cleanup\n", __FILE__, __FUNC__, __LINE__)); + Result = mCleanup(cl, obj, msg); + break; + + case MUIM_AskMinMax: + d1(KPrintF("%s/%s/%ld: MUIM_AskMinMax\n", __FILE__, __FUNC__, __LINE__)); + Result = mAskMinMax(cl, obj, (struct MUIP_AskMinMax *) msg); + break; + + case MUIM_Draw: + d1(KPrintF("%s/%s/%ld: MUIM_Draw\n", __FILE__, __FUNC__, __LINE__)); + Result = mDraw(cl, obj, (struct MUIP_Draw *) msg); + break; + + default: + d1(KPrintF("%s/%s/%ld: MethodID=%08lx\n", __FILE__, __FUNC__, __LINE__, msg->MethodID)); + Result = DoSuperMethodA(cl, obj, msg); + break; + } + + return Result; +} +DISPATCHER_END + + +static void ClearInstanceData(struct DtMCCInstance *inst) +{ + memset(inst, 0, sizeof(struct DtMCCInstance)); +} + +/* ------------------------------------------------------------------------- */ + +struct MUI_CustomClass *InitIconobjectClass(void) +{ + return MUI_CreateCustomClass(NULL, SUPERCLASS, NULL, + sizeof(struct DtMCCInstance), DISPATCHER_REF(MUI)); +} + +void CleanupIconobjectClass(struct MUI_CustomClass *mcc) +{ + MUI_DeleteCustomClass(mcc); +} + +/* ------------------------------------------------------------------------- */ + +static void ForceRelayout(struct IClass *cl, Object *obj) +{ + Object *WindowObj; + Object *RootObj = NULL; + + if (muiRenderInfo(obj)) + { + WindowObj = _win(obj); + get(WindowObj, MUIA_Window_RootObject, &RootObj); + + if (RootObj) + { + // force relayout + DoMethod(RootObj, MUIM_Group_InitChange); + DoMethod(RootObj, MUIM_Group_ExitChange); + } + } +} + +/* ------------------------------------------------------------------------- */ + diff --git a/scalos/common/IconobjectMCC/IconobjectMCC.h b/scalos/common/IconobjectMCC/IconobjectMCC.h new file mode 100755 index 000000000..2c3fc7aaf --- /dev/null +++ b/scalos/common/IconobjectMCC/IconobjectMCC.h @@ -0,0 +1,28 @@ +// IconobjectMCC.h +// $Date$ +// $Revision$ + + +#ifndef ICONOBJECT_MCC_H +#define ICONOBJECT_MCC_H + +/* ------------------------------------------------------------------------- */ + +struct MUI_CustomClass *InitIconobjectClass(void); +void CleanupIconobjectClass(struct MUI_CustomClass *mcc); + +/* ------------------------------------------------------------------------- */ + +#ifdef __AROS__ +#define IconobjectMCCObject BOOPSIOBJMACRO_START(IconobjectClass->mcc_Class) +#else +#define IconobjectMCCObject NewObject(IconobjectClass->mcc_Class, 0 +#endif + +/* ------------------------------------------------------------------------- */ + +#define MUIA_Iconobj_Object 0x80429876 /* I.. Object * */ + +/* ------------------------------------------------------------------------- */ + +#endif /* ICONOBJECT_MCC_H */ diff --git a/scalos/common/Int64/Dos64.c b/scalos/common/Int64/Dos64.c new file mode 100644 index 000000000..29e03466c --- /dev/null +++ b/scalos/common/Int64/Dos64.c @@ -0,0 +1,38 @@ +// Dos64.c +// $Date$ + +/*********************************************************************** +* +* Function: +* 64-bit File operations +* +***********************************************************************/ + +#include +#include +#include +#include +#include +#include + +#define __USE_SYSBASE + +#include + +#include "int64.h" + +/*********************************************************************** +* Public Routines +***********************************************************************/ + +ULONG64 ScalosExAllSize64(const struct ExAllData *ead, ULONG edType) +{ +#if defined(__MORPHOS__) && defined(ACTION_EXAMINE_NEXT64) + if (DOSBase->dl_lib.lib_Version >= 51 && edType >= ED_SIZE64) + return ead->ed_Size64; +#endif /* __MORPHOS__ */ + + return MakeU64(ead->ed_Size); +} + + diff --git a/scalos/common/Int64/int64.c b/scalos/common/Int64/int64.c new file mode 100644 index 000000000..484b91066 --- /dev/null +++ b/scalos/common/Int64/int64.c @@ -0,0 +1,489 @@ +// int64.c +// $Date$ + +/*********************************************************************** +* +* Function: +* Operators on Large (64-bit) Integers +* +* Public Routines: +* MakeU64() +* MakeS64() +* Incr64() +* Decr64() +* Add64() +* Sub64() +* ShiftR64() +* ShiftL64() +* Mul64() +* Div64() +* +***********************************************************************/ + +/* Standard (ANSI) C library header files. */ +#include +#include +#include + +/* Application header files. */ +#include "int64.h" + +/*********************************************************************** +* Public Routines +***********************************************************************/ + +/*---------------------------------------------------------------------- +* Name: MakeU64() +* +* Action: Construct a 64-bit unsigned integer from a 32-bit unsigned integer. +* +* Input: n - 32 bit integer to be used to construct 64-bit unsigned integer. +* +* Return +* Value: Constructed 64-bit unsigned integer. +* +* Side +* Effects: None. +* +*---------------------------------------------------------------------*/ +ULONG64 MakeU64( ULONG n ) +{ +#ifdef __GNUC__ + return (ULONG64) n; +#else /* __GNUC__ */ + ULONG64 result; + + result.High = 0; + result.Low = n; + + return ( result ); +#endif /* __GNUC__ */ +} /* MakeU64() */ + +/*---------------------------------------------------------------------- +* Name: MakeS64() +* +* Action: Construct a 64-bit signed integer from a 32-bit signed integer. +* +* Input: n - 32 bit integer to be used to construct 64-bit signed integer. +* +* Return +* Value: Constructed 64-bit signed integer. +* +* Side +* Effects: None. +* +*---------------------------------------------------------------------*/ +SLONG64 MakeS64( LONG n ) +{ +#ifdef __GNUC__ + return (SLONG64) n; +#else /* __GNUC__ */ + SLONG64 result; + + result.High = (n < 0) ? -1 : 0; + result.Low = n; + + return ( result ); +#endif /* __GNUC__ */ +} /* MakeS64() */ + +/*---------------------------------------------------------------------- +* Name: Incr64() +* +* Action: Increment a 64-bit integer by some 32-bit integer. +* +* Input: x - 64-bit integer to be incremented. +* n - 32-bit increment. +* +* Return +* Value: Result of increment operation. +* +* Side +* Effects: None. +* +* Notes: Assume no overflow of sum. +* Rewritten for efficiency +*---------------------------------------------------------------------*/ +ULONG64 Incr64(ULONG64 x, ULONG n ) +{ +#ifdef __GNUC__ + return x + n; +#else /* __GNUC__ */ + x.Low += n; /* add lo order word */ + + if ( x.Low < n ) /* did the add cause an overflow? */ + x.High++; /* yes, adjust hi word for carry */ + + return ( x ); +#endif /* __GNUC__ */ +} /* Incr64() */ + +/*---------------------------------------------------------------------- +* Name: Decr64() +* +* Action: Decrement a 64-bit integer by some 32-bit integer. +* +* Input: x - 64-bit integer to be decremented. +* n - 32-bit decrement. +* +* Return +* Value: Result of decrement operation. +* +* Side +* Effects: largeIntP - replaced by the result of the decrement +* operation. +* +* Notes: Assume no underflow of difference. +* Rewritten for efficiency +*---------------------------------------------------------------------*/ +ULONG64 Decr64(ULONG64 x, ULONG n ) +{ +#ifdef __GNUC__ + return x - n; +#else /* __GNUC__ */ + if ( x.Low < n ) /* is a borrow required? */ + x.High--; /* yes, borrow from hi word */ + + x.Low -= n; /* subtract lo order word */ + + return ( x ); +#endif /* __GNUC__ */ +} /* Decr64() */ + +/*---------------------------------------------------------------------- +* Name: Add64() +* +* Action: Add two 64-bit integers. +* +* Input: x - first 64-bit integer. +* y - second 64-bit integer. +* +* Return +* Value: Result of addition operation. +* +* Side +* Effects: None. +* +* Notes: Assume no overflow of sum. +* Rewritten for efficiency +*---------------------------------------------------------------------*/ +ULONG64 Add64(ULONG64 x, ULONG64 y ) +{ +#ifdef __GNUC__ + return x + y; +#else /* __GNUC__ */ + x = Incr64( x, y.Low); + x.High += y.High; + + return ( x ); +#endif /* __GNUC__ */ +} /* Add64() */ + +/*---------------------------------------------------------------------- +* Name: Sub64() +* +* Action: Subtract two 64-bit integers. +* +* Input: x - first 64-bit integer. +* y - second 64-bit integer. +* +* Return +* Value: Result of subtracting second 64-bit integer from the first. +* +* Side +* Effects: None. +* +* Notes: Assume no underflow of difference (ie. x >= y) +* Rewritten for efficiency +*---------------------------------------------------------------------*/ +ULONG64 Sub64(ULONG64 x, ULONG64 y ) +{ +#ifdef __GNUC__ + return x - y; +#else /* __GNUC__ */ + x = Decr64( x, y.Low); + x.High -= y.High; + + return ( x ); +#endif /* __GNUC__ */ +} /* Sub64() */ + +/*---------------------------------------------------------------------- +* Name: ShiftR64() +* +* Action: Performs a logical shift right on an ULONG64 by b bits. +* +* Input: x - the address of the 64-bit integer. +* b - number bits to shift. +* +* Return +* Value: the value passed in is shifted +* +* Side +* Effects: None. +* +* Notes: As expected, bits shifted below bit 0 go into the bit bucket. +*---------------------------------------------------------------------*/ +void ShiftR64(ULONG64 *x, UBYTE b) +{ +#ifdef __GNUC__ + *x >>= b; +#else /* __GNUC__ */ + if (b >= 32) + { + x->Low = x->High; + x->High = 0; + b &= 0x1F; /* get rid of all bits above value 32 */ + } + x->Low >>= b; /* shift the low word into position */ + x->Low |= (x->High << (32-b)); /* OR in the bits remaining of hi word */ + x->High >>= b; /* shift the hi word by x bits */ +#endif /* __GNUC__ */ +} /* end ShiftR64() */ + +/*---------------------------------------------------------------------- +* Name: ShiftL64() +* +* Action: Performs a logical shift left on an ULONG64 by b bits. +* +* Input: x - the address of the 64-bit integer. +* b - number of bits to shift. +* +* Return +* Value: The value passed in is shifted +* +* Side +* Effects: None. +* +* Notes: As expected, bits shifted above bit 63 go into the bit bucket. +*---------------------------------------------------------------------*/ +void ShiftL64(ULONG64 *x, UBYTE b) +{ +#ifdef __GNUC__ + *x <<= b; +#else /* __GNUC__ */ + if (b >= 32) + { + x->High = x->Low; + x->Low = 0; + b &= 0x1F; /* get rid of all bits above value 32 */ + } + x->High <<= b; /* shift the hi word into position */ + x->High |= (x->Low >> (32-b)); /* OR in the bits remaining of lo word */ + x->Low <<= b; /* shift the lo word by x bits */ +#endif /* __GNUC__ */ +} /* end ShiftL64() */ + +/*---------------------------------------------------------------------- +* Name: Mul64() +* +* Action: Multiply two 64 bit integers. +* +* Input: x - first 64 bit integer +* y - second 64 bit integer +* overflow - address of an integer +* +* Return +* Values: 1) 64 bit Product (x * y) is returned +* 2) overflow set to 0 or 1 to indicate if Product exceeded +* 64 bits (1 indicates overflow) +* +* Side +* Effects: None. +* +* Notes: Any overflow above 64 bits will be lost. +*---------------------------------------------------------------------*/ +ULONG64 Mul64(ULONG64 x, ULONG64 y, BOOL *overflow) +{ +#ifdef __GNUC__ + if (overflow) + *overflow = FALSE; + return x * y; +#else /* __GNUC__ */ + ULONG64 Prod; + int bits_lost = 0; /* 1 = bits have been lost on hi end */ + + if (overflow) + *overflow = 0; /* start w/ no overflow */ + Prod.High = 0; /* initialize Product */ + Prod.Low = 0; + + do { + if (y.Low & 0x1) /* if bit 0 is 1, curr power of 2 will be added */ + { + /* now that we're adding again, if there have been any bits */ + /* lost from hi end of x, we know there's an overflow. */ + + if (bits_lost && overflow) + *overflow = 1; + + Prod = Add64(Prod,x); /* add shifted x to the product */ + } + + if (x.High & 0x80000000) /* if bit 63 of x is on before ShiftL, */ + bits_lost = 1; /* indicate bits have been lost */ + + ShiftL64(&x,1); /* double the value being multiplied */ + ShiftR64(&y,1); /* shift next test bit into position */ + } while (y.High || y.Low); /* until all y bits are 0 (ie.Mult done) */ + + return ( Prod ); +#endif /* __GNUC__ */ +} /* end Mul64() */ + +/*---------------------------------------------------------------------- +* Name: Div64() +* +* Action: Divide two 64 bit integers. +* +* Input: x - first 64 bit integer +* y - second 64 bit integer +* +* Return +* Values: 1) Quotient is returned +* 2) Remainder is stored in specified address address if not NULL +* +* Side +* Effects: None. +* +* Notes: As usual, bits shifted below bit 0 go into the bit bucket. +*---------------------------------------------------------------------*/ +ULONG64 Div64(ULONG64 x, ULONG64 y, ULONG64 *rmdrP) +{ +#ifdef __GNUC__ + if (rmdrP) + *rmdrP = x % y; + return x / y; +#else /* __GNUC__ */ + ULONG64 Quot, /* the final answer is accumulated here */ + tQuot, /* temp. quotient to find a single power of 2 */ + /* that fits into the dividend on each pass */ + divisor; + + Quot.High = 0; /* initialize Quotient */ + Quot.Low = 0; + + if (y.High==0 && y.Low==0) /* check for divide by zero */ + { + y.High = 1/y.Low; /* force a divide by zero so that error- */ + /* handling will be platform-specific */ + (void) y; + } + else /* do the division */ + { + while (Cmp64(x,y) >= 0) /* while x >= y */ + { + /* find largest Y (multiplied by powers of 2) that is less than X */ + divisor = y; /* copy Y so it is unchanged */ + tQuot.High = 0; /* init temp quotient (at least 1y goes into x) */ + tQuot.Low = 1; + + while (Cmp64(x,divisor) >= 0 && (divisor.High <= 0x7FFFFFFF)) + { + ShiftL64(&divisor,1); /* double divisor (2y 4y 8y...) */ + ShiftL64(&tQuot,1); /* count number of y's so far */ + } + + ShiftR64(&divisor,1); /* back up to a value that's less than X*/ + ShiftR64(&tQuot,1); + + Quot = Add64(Quot,tQuot); /* calc cumulative quotient */ + x = Sub64(x,divisor); /* deduct the multiples so far */ + } + + if (rmdrP) + *rmdrP = x; /* save remainder in specified address */ + } + return ( Quot ); +#endif /* __GNUC__ */ +} /* end Div64() */ + + +//---------------------------------------------------------------------- +// comparison of a and b +// returns +1 if a > b +// 0 if a == b +// -1 if a < b +int Cmp64(ULONG64 x, ULONG64 y) +{ +#ifdef __GNUC__ + if (x > y) + return 1; + else if (x < y) + return -1; +#else /* __GNUC__ */ + if (x.High > y.High) + return 1; + else if (x.High < y.High) + return -1; + else + { + if (x.Low > y.Low) + return 1; + else if (x.Low < y.Low) + return -1; + } +#endif /* __GNUC__ */ + + return 0; +} + +//---------------------------------------------------------------------- +// ASCII conversion of number + +void Convert64(const struct Locale *locale, ULONG64 Number, STRPTR Buffer, size_t MaxLen) +{ + char InternalBuffer[40]; + char *lp; + ULONG64 Ten = MakeU64(10); + size_t MaxLen2; + STRPTR Separator = NULL; + short grp, GroupSize = 0; + size_t SeparatorLength = 0; + BOOL NumberIsNotZero; + + if (locale) + { + Separator = locale->loc_GroupSeparator; + GroupSize = locale->loc_Grouping[0]; + SeparatorLength = strlen(Separator); + } + + MaxLen2 = sizeof(InternalBuffer) - 1; + lp = InternalBuffer + MaxLen2; + *lp-- = '\0'; + grp = 0; + + do { + ULONG64 Remainder; + + Number = Div64(Number, Ten, &Remainder); + + *lp-- = (char) ULONG64_LOW(Remainder) + '0'; + MaxLen2--; + + NumberIsNotZero = Cmp64(Number, MakeU64(0)) > 0; + + // insert separator + if (Separator && NumberIsNotZero && ++grp >= GroupSize && MaxLen2 > SeparatorLength) + { + lp -= SeparatorLength; + strncpy(1 + lp, Separator, SeparatorLength); + grp = 0; + MaxLen2 -= SeparatorLength; + } + } while (NumberIsNotZero && MaxLen2 > 0); + lp++; + + while (MaxLen > 1 && *lp) + { + *Buffer++ = *lp++; + MaxLen--; + } + *Buffer = '\0'; +} + +//---------------------------------------------------------------------- + + diff --git a/scalos/common/Int64/int64.h b/scalos/common/Int64/int64.h new file mode 100644 index 000000000..22d4e406b --- /dev/null +++ b/scalos/common/Int64/int64.h @@ -0,0 +1,42 @@ +// int64.h +// $Date$ +// $Revision$ + +#ifndef INT64_H +#define INT64_H + +#include +#include +#include +#include +#include +#include +#include + +// ------------------------------------------------------------------------ + +// defined in int64.c +/// +ULONG64 MakeU64( ULONG n ); +SLONG64 MakeS64( LONG n ); +ULONG64 Incr64(ULONG64 x, ULONG n ); +ULONG64 Decr64(ULONG64 x, ULONG n ); +ULONG64 Add64(ULONG64 x, ULONG64 y ); +ULONG64 Sub64(ULONG64 x, ULONG64 y ); +void ShiftR64(ULONG64 *x, UBYTE b); +void ShiftL64(ULONG64 *x, UBYTE b); +ULONG64 Mul64(ULONG64 x, ULONG64 y, BOOL *overflow); +ULONG64 Div64(ULONG64 x, ULONG64 y, ULONG64 *rmdrP); +int Cmp64(ULONG64 x, ULONG64 y); +void Convert64(const struct Locale *locale, ULONG64 Number, STRPTR Buffer, size_t MaxLen); +/// +/* ------------------------------------------------- */ + +// defined in Dos64.c +/// +ULONG64 ScalosExAllSize64(const struct ExAllData *ead, ULONG edType); + +/// +/* ------------------------------------------------- */ + +#endif // INT64_H diff --git a/scalos/common/McpGfx/ScalosMcpGfx.c b/scalos/common/McpGfx/ScalosMcpGfx.c new file mode 100644 index 000000000..5e87ca032 --- /dev/null +++ b/scalos/common/McpGfx/ScalosMcpGfx.c @@ -0,0 +1,427 @@ +// ScalosMcpGfx.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#ifdef __AROS__ +// FIXME: temporary fix until we have figured out +// how to deal with these deprecated defines. +#define IA_ShadowPen (IA_Dummy + 0x09) +#define IA_HighlightPen (IA_Dummy + 0x0A) +#endif + +//---------------------------------------------------------------------------- + +extern struct TagItem *ScalosVTagList(ULONG FirstTag, va_list args); + +//---------------------------------------------------------------------------- + +// local data structures + +struct McpGfxPens + { + ULONG BgPen; + ULONG ShadowPen; + ULONG ShinePen; + ULONG HalfShadowPen; + ULONG HalfShinePen; + }; + +//---------------------------------------------------------------------------- + +// local functions + +static void DrawFrameButton(struct RastPort *rp, const struct Rectangle *Rect, + BOOL Recessed, const struct McpGfxPens *Pens); +static void DrawFrameBorder(struct RastPort *rp, const struct Rectangle *Rect, + BOOL Recessed, const struct McpGfxPens *Pens); +static void DrawFrameString(struct RastPort *rp, const struct Rectangle *Rect, + BOOL Recessed, const struct McpGfxPens *Pens); +static void DrawFrameDropBox(struct RastPort *rp, const struct Rectangle *Rect, + BOOL Recessed, const struct McpGfxPens *Pens); +static void DrawFrameXEN(struct RastPort *rp, const struct Rectangle *Rect, + BOOL Recessed, const struct McpGfxPens *Pens); +static void DrawFrameMWB(struct RastPort *rp, const struct Rectangle *Rect, + BOOL Recessed, const struct McpGfxPens *Pens); +static void DrawFrameThick(struct RastPort *rp, const struct Rectangle *Rect, + BOOL Recessed, const struct McpGfxPens *Pens); +static void DrawFrameXWin(struct RastPort *rp, const struct Rectangle *Rect, + BOOL Recessed, const struct McpGfxPens *Pens); + +//---------------------------------------------------------------------------- + +// local data items + +static void (*DrawFrameTable[])(struct RastPort *, const struct Rectangle *, BOOL, const struct McpGfxPens *) = + { + NULL, //#define MF_FRAME_NONE 0 /* No frame */ + DrawFrameButton, //#define MF_FRAME_BUTTON 1 /* Standard 3D frame used for buttons */ + DrawFrameBorder, //#define MF_FRAME_BORDER 2 /* Standard 2D frame used for */ + DrawFrameString, //#define MF_FRAME_STRING 3 /* String */ + DrawFrameDropBox, //#define MF_FRAME_DROPBOX 4 /* Dropbox [String (with space)?] */ + DrawFrameXEN, //#define MF_FRAME_XEN 5 /* Standard XEN button */ + DrawFrameMWB, //#define MF_FRAME_MWB 6 /* Standard MWB */ + DrawFrameThick, //#define MF_FRAME_THICK 7 /* Standard Thick */ + DrawFrameXWin, //#define MF_FRAME_XWIN 8 /* Standard XWIN */ + }; + +static const struct FrameSize FrameSizeTable[] = + { + { { 0, 0, 0, 0, 0, 0, 0, 0 } }, //MF_FRAME_NONE + { { 1, 1, 1, 1, 1, 1, 1, 1 } }, //MF_FRAME_BUTTON + { { 1, 1, 1, 1, 1, 1, 1, 1 } }, //MF_FRAME_BORDER + { { 2, 2, 2, 2, 2, 2, 2, 2 } }, //MF_FRAME_STRING + { { 3, 3, 3, 3, 3, 3, 3, 3 } }, //MF_FRAME_DROPBOX + { { 2, 2, 2, 2, 3, 3, 1, 1 } }, //MF_FRAME_XEN + { { 2, 2, 2, 2, 2, 2, 2, 2 } }, //MF_FRAME_MWB + { { 2, 1, 2, 1, 2, 1, 2, 1 } }, //MF_FRAME_THICK + { { 2, 2, 2, 2, 2, 2, 2, 2 } }, //MF_FRAME_XWIN + }; + +//---------------------------------------------------------------------------- + +// public data items + +//---------------------------------------------------------------------------- + +void McpGfxRectFill(struct RastPort *rp, + UWORD MinX, WORD MinY, WORD MaxX, WORD MaxY, ULONG FirstTag, ...) +{ + va_list args; + struct TagItem *TagList; + struct RastPort rpClone = *rp; + + va_start(args, FirstTag); + + TagList = ScalosVTagList(FirstTag, args); + + va_end(args); + + if (TagList) + { + UWORD *Pattern; + ULONG PatSize; + + PatSize = GetTagData(IA_APatSize, 0, TagList); + Pattern = (UWORD *) GetTagData(IA_APattern, (ULONG) NULL, TagList); + + if (PatSize && Pattern) + { + SetAfPt(&rpClone, Pattern, PatSize); + } + + if (FindTagItem(IA_FGPen, TagList)) + { + WORD FgColor; + + FgColor = GetTagData(IA_FGPen, 0, TagList); + + SetAPen(&rpClone, FgColor); + } + } + + RectFill(&rpClone, MinX, MinY, MaxX, MaxY); + + if (TagList) + FreeTagItems(TagList); +} + +//---------------------------------------------------------------------------- + +void McpGfxDrawFrame(struct RastPort *rp, + UWORD MinX, WORD MinY, WORD MaxX, WORD MaxY, ULONG FirstTag, ...) +{ + va_list args; + struct TagItem *TagList; + ULONG FrameType; + ULONG Recessed; + struct Rectangle FrameRect; + struct McpGfxPens Pens; + struct RastPort rpClone = *rp; + + va_start(args, FirstTag); + + TagList = ScalosVTagList(FirstTag, args); + + va_end(args); + + SetDrMd(&rpClone, JAM1); + + Pens.BgPen = GetTagData(IA_BGPen, 0, TagList); + Pens.ShinePen = GetTagData(IA_ShinePen, 2, TagList); + Pens.ShadowPen = GetTagData(IA_ShadowPen, 1, TagList); + Pens.HalfShinePen = GetTagData(IA_HalfShinePen, 2, TagList); + Pens.HalfShadowPen = GetTagData(IA_HalfShadowPen, 1, TagList); + + FrameType = GetTagData(IA_FrameType, MF_FRAME_NONE, TagList); + Recessed = GetTagData(IA_Recessed, FALSE, TagList); + + FrameRect.MinX = MinX; + FrameRect.MaxX = MaxX; + FrameRect.MinY = MinY; + FrameRect.MaxY = MaxY; + + if (FrameType > 0 && FrameType < MF_FRAME_MAXIMUM) + { + if (DrawFrameTable[FrameType]) + { + DrawFrameTable[FrameType](&rpClone, + &FrameRect, + Recessed, + &Pens); + } + } + + if (TagList) + FreeTagItems(TagList); +} + +//---------------------------------------------------------------------------- + +static void DrawFrameButton(struct RastPort *rp, const struct Rectangle *Rect, + BOOL Recessed, const struct McpGfxPens *Pens) +{ + SetAPen(rp, Recessed ? Pens->ShinePen : Pens->ShadowPen); + + Move(rp, Rect->MinX + 1, Rect->MaxY); + Draw(rp, Rect->MaxX, Rect->MaxY); + Draw(rp, Rect->MaxX, Rect->MinY + 1); + + SetAPen(rp, Recessed ? Pens->ShadowPen : Pens->ShinePen); + Move(rp, Rect->MaxX - 1, Rect->MinY); + Draw(rp, Rect->MinX, Rect->MinY); + Draw(rp, Rect->MinX, Rect->MaxY - 1); +} + +//---------------------------------------------------------------------------- + +static void DrawFrameBorder(struct RastPort *rp, const struct Rectangle *Rect, + BOOL Recessed, const struct McpGfxPens *Pens) +{ + SetAPen(rp, Recessed ? Pens->ShinePen : Pens->ShadowPen); + + Move(rp, Rect->MinX, Rect->MinY); + Draw(rp, Rect->MinX, Rect->MaxY); + Draw(rp, Rect->MaxX, Rect->MaxY); + Draw(rp, Rect->MaxX, Rect->MinY); + Draw(rp, Rect->MinX, Rect->MinY); +} + +//---------------------------------------------------------------------------- + +static void DrawFrameString(struct RastPort *rp, const struct Rectangle *Rect, + BOOL Recessed, const struct McpGfxPens *Pens) +{ + SetAPen(rp, Recessed ? Pens->ShinePen : Pens->ShadowPen); + + Move(rp, Rect->MinX + 1, Rect->MinY + 1); + Draw(rp, Rect->MinX + 1, Rect->MaxY); + Draw(rp, Rect->MaxX, Rect->MaxY); + Draw(rp, Rect->MaxX, Rect->MinY + 1); + Draw(rp, Rect->MinX + 1, Rect->MinY + 1); + + SetAPen(rp, Recessed ? Pens->ShadowPen : Pens->ShinePen); + + Move(rp, Rect->MaxX, Rect->MinY); + Draw(rp, Rect->MinX, Rect->MinY); + Draw(rp, Rect->MinX, Rect->MaxY); + + Move(rp, Rect->MaxX - 1, Rect->MinY + 2); + Draw(rp, Rect->MaxX - 1, Rect->MaxY - 1); + Draw(rp, Rect->MinX + 1, Rect->MaxY - 1); +} + +//---------------------------------------------------------------------------- + +static void DrawFrameDropBox(struct RastPort *rp, const struct Rectangle *Rect, + BOOL Recessed, const struct McpGfxPens *Pens) +{ + SetAPen(rp, Recessed ? Pens->ShinePen : Pens->ShadowPen); + + Move(rp, Rect->MaxX - 2, Rect->MinY + 2); + Draw(rp, Rect->MinX + 2, Rect->MinY + 2); + Draw(rp, Rect->MinX + 2, Rect->MaxY - 2); + + Move(rp, Rect->MinX, Rect->MaxY); + Draw(rp, Rect->MaxX, Rect->MaxY); + Draw(rp, Rect->MaxX, Rect->MinY); + + SetAPen(rp, Recessed ? Pens->ShadowPen : Pens->ShinePen); + + Draw(rp, Rect->MinX, Rect->MinY); + Draw(rp, Rect->MinX, Rect->MaxY); + + Move(rp, Rect->MaxX - 2, Rect->MinY + 3); + Draw(rp, Rect->MaxX - 2, Rect->MaxY - 2); + Draw(rp, Rect->MinX + 3, Rect->MaxY - 2); + + SetAPen(rp, Pens->BgPen); + Move(rp, Rect->MinX + 1, Rect->MinY + 1); + Draw(rp, Rect->MinX + 1, Rect->MaxY - 1); + Draw(rp, Rect->MaxX - 1, Rect->MaxY - 1); + Draw(rp, Rect->MaxX - 1, Rect->MinY + 1); + Draw(rp, Rect->MinX + 1, Rect->MinY + 1); +} + +//---------------------------------------------------------------------------- + +static void DrawFrameXEN(struct RastPort *rp, const struct Rectangle *Rect, + BOOL Recessed, const struct McpGfxPens *Pens) +{ + SetAPen(rp, Pens->ShadowPen); + + Move(rp, Rect->MinX, Rect->MinY); + Draw(rp, Rect->MaxX, Rect->MinY); + Draw(rp, Rect->MaxX, Rect->MaxY); + Draw(rp, Rect->MinX, Rect->MaxY); + Draw(rp, Rect->MinX, Rect->MinY); + + if (Recessed) + { + SetAPen(rp, Pens->HalfShadowPen); + Move(rp, Rect->MinX + 1, Rect->MaxY - 1); + Draw(rp, Rect->MinX + 1, Rect->MinY + 1); + Draw(rp, Rect->MaxX - 1, Rect->MinY + 1); + + SetAPen(rp, Pens->BgPen); + Move(rp, Rect->MinX + 2, Rect->MaxY - 1); + Draw(rp, Rect->MinX + 2, Rect->MinY + 2); + Draw(rp, Rect->MaxX - 1, Rect->MinY + 2); + } + else + { + SetAPen(rp, Pens->HalfShadowPen); + Move(rp, Rect->MinX + 2, Rect->MaxY - 1); + Draw(rp, Rect->MaxX - 1, Rect->MaxY - 1); + Draw(rp, Rect->MaxX - 1, Rect->MinY + 2); + + SetAPen(rp, Pens->ShinePen); + Move(rp, Rect->MaxX - 2, Rect->MinY + 1); + Draw(rp, Rect->MinX + 1, Rect->MinY + 1); + Draw(rp, Rect->MinX + 1, Rect->MaxY - 2); + } +} + +//---------------------------------------------------------------------------- + +static void DrawFrameMWB(struct RastPort *rp, const struct Rectangle *Rect, + BOOL Recessed, const struct McpGfxPens *Pens) +{ + SetAPen(rp, Recessed ? Pens->ShinePen : Pens->ShadowPen); + + Move(rp, Rect->MinX + 1, Rect->MaxY); + Draw(rp, Rect->MaxX, Rect->MaxY); + Draw(rp, Rect->MaxX, Rect->MinY + 1); + + SetAPen(rp, Recessed ? Pens->ShadowPen : Pens->ShinePen); + + Move(rp, Rect->MaxX - 1, Rect->MinY); + Draw(rp, Rect->MinX, Rect->MinY); + Draw(rp, Rect->MinX, Rect->MaxY - 1); + + SetAPen(rp, Recessed ? Pens->HalfShinePen : Pens->HalfShadowPen); + + Move(rp, Rect->MinX + 2, Rect->MaxY - 1); + Draw(rp, Rect->MaxX - 1, Rect->MaxY - 1); + Draw(rp, Rect->MaxX - 1, Rect->MinY + 2); + + SetAPen(rp, Recessed ? Pens->HalfShadowPen : Pens->HalfShinePen); + + Move(rp, Rect->MaxX - 2, Rect->MinY + 1); + Draw(rp, Rect->MinX + 1, Rect->MinY + 1); + Draw(rp, Rect->MinX + 1, Rect->MaxY - 2); + + SetAPen(rp, Pens->BgPen); + WritePixel(rp, Rect->MaxX - 1, Rect->MinY + 1); + WritePixel(rp, Rect->MinX + 1, Rect->MaxY - 1); + + SetAPen(rp, Pens->HalfShadowPen); + WritePixel(rp, Rect->MaxX, Rect->MinY); + WritePixel(rp, Rect->MinX, Rect->MaxY); +} + +//---------------------------------------------------------------------------- + +static void DrawFrameThick(struct RastPort *rp, const struct Rectangle *Rect, + BOOL Recessed, const struct McpGfxPens *Pens) +{ + SetAPen(rp, Recessed ? Pens->ShinePen : Pens->ShadowPen); + + Move(rp, Rect->MinX + 1, Rect->MaxY); + Draw(rp, Rect->MaxX, Rect->MaxY); + Draw(rp, Rect->MaxX, Rect->MinY); + + Move(rp, Rect->MaxX - 1, Rect->MinY + 1); + Draw(rp, Rect->MaxX - 1, Rect->MaxY - 1); + + SetAPen(rp, Recessed ? Pens->ShadowPen : Pens->ShinePen); + + Move(rp, Rect->MinX, Rect->MaxY); + Draw(rp, Rect->MinX, Rect->MinY); + Draw(rp, Rect->MaxX - 1, Rect->MinY); + + Move(rp, Rect->MinX + 1, Rect->MinY + 1); + Draw(rp, Rect->MinX + 1, Rect->MaxY - 1); +} + +//---------------------------------------------------------------------------- + +static void DrawFrameXWin(struct RastPort *rp, const struct Rectangle *Rect, + BOOL Recessed, const struct McpGfxPens *Pens) +{ + SetAPen(rp, Recessed ? Pens->ShinePen : Pens->HalfShadowPen); + + Move(rp, Rect->MinX + 1, Rect->MaxY); + Draw(rp, Rect->MaxX, Rect->MaxY); + Draw(rp, Rect->MaxX, Rect->MinY); + + Move(rp, Rect->MaxX - 1, Rect->MinY + 1); + Draw(rp, Rect->MaxX - 1, Rect->MaxY - 1); + Draw(rp, Rect->MinX + 2, Rect->MaxY - 1); + + SetAPen(rp, Recessed ? Pens->HalfShadowPen : Pens->ShinePen); + + Move(rp, Rect->MinX, Rect->MaxY); + Draw(rp, Rect->MinX, Rect->MinY); + Draw(rp, Rect->MaxX - 1, Rect->MinY); + + Move(rp, Rect->MinX + 1, Rect->MaxY - 1); + Draw(rp, Rect->MinX + 1, Rect->MinY + 1); + Draw(rp, Rect->MaxX - 2, Rect->MinY + 1); +} + +//---------------------------------------------------------------------------- + +const struct FrameSize *McpGetFrameSize(UWORD frameType) +{ + if (frameType < MF_FRAME_MAXIMUM) + return &FrameSizeTable[frameType]; + + return NULL; +} diff --git a/scalos/common/McpGfx/ScalosMcpGfx.h b/scalos/common/McpGfx/ScalosMcpGfx.h new file mode 100644 index 000000000..7f1e7d75e --- /dev/null +++ b/scalos/common/McpGfx/ScalosMcpGfx.h @@ -0,0 +1,21 @@ +// ScalosMcpGfx.c +// $Date$ +// $Revision$ + + +#ifndef SCALOS_MCPGFX_H +#define SCALOS_MCPGFX_H + +#include + +/* ------------------------------------------------------------------------- */ + +void McpGfxRectFill(struct RastPort *rp, + UWORD MinX, WORD MinY, WORD MaxX, WORD MaxY, ULONG FirstTag, ...); +void McpGfxDrawFrame(struct RastPort *rp, + UWORD MinX, WORD MinY, WORD MaxX, WORD MaxY, ULONG FirstTag, ...); +const struct FrameSize *McpGetFrameSize(UWORD frameType); + +/* ------------------------------------------------------------------------- */ + +#endif /* SCALOS_MCPGFX_H */ diff --git a/scalos/common/Plugin/config.mk b/scalos/common/Plugin/config.mk new file mode 100755 index 000000000..2a6d7492f --- /dev/null +++ b/scalos/common/Plugin/config.mk @@ -0,0 +1,31 @@ +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +BEGIN_OBJS := /SDK/clib2/lib.threadsafe/crtbegin.o \ + $(OBJDIR)/plugin-aos4.o \ + $(OBJDIR)/plugin-aos4-68kstubs.o +END_OBJS := /SDK/clib2/lib.threadsafe/crtend.o + +else +ifeq ($(MACHINE), i386-aros) +############################################################################### +# i386-aros + +BEGIN_OBJS := $(OBJDIR)/plugin-aros.o +END_OBJS := + +else + +############################################################################### +# AmigaOS, MorphOS + +BEGIN_OBJS := $(OBJDIR)/plugin-classic.o +END_OBJS := + +endif +endif diff --git a/scalos/common/Plugin/plugin-aos4-68kstubs.c b/scalos/common/Plugin/plugin-aos4-68kstubs.c new file mode 100644 index 000000000..13626bf52 --- /dev/null +++ b/scalos/common/Plugin/plugin-aos4-68kstubs.c @@ -0,0 +1,18 @@ +// plugin-aos4-68kstubs.c +// $Date$ +// $Revision$ + +#include "plugin.h" + +#if PLUGIN_TYPE == OOP +#include "scalosplugin-aos4-68kstubs.c" +#elif PLUGIN_TYPE == FILETYPE +#include "scalosfiletypeplugin-aos4-68kstubs.c" +#elif PLUGIN_TYPE == PREVIEW +#include "scalospreviewplugin-aos4-68kstubs.c" +#elif PLUGIN_TYPE == PREFS +#include "scalosprefsplugin-aos4-68kstubs.c" +#else +#error Unsupported plugin type +#endif + diff --git a/scalos/common/Plugin/plugin-aos4.c b/scalos/common/Plugin/plugin-aos4.c new file mode 100644 index 000000000..b4b861220 --- /dev/null +++ b/scalos/common/Plugin/plugin-aos4.c @@ -0,0 +1,277 @@ +// plugin-aos4.c +// $Date$ +// $Revision$ + + +#include +#include +#include + +#include + +#include +#include + +#include +#include + +#include + +#include "plugin.h" + +#if PLUGIN_TYPE == PREVIEW +#include +#endif + +#ifndef d +#define d(x) +#endif +#ifndef d1 +#define d1(x) +#endif +#ifndef d2 +#define d2(x) x +#endif + +// from debug.lib +extern int kprintf(const char *fmt, ...); + +int _start(void) +{ + return -1; +} + +static struct Library *Initlib(struct Library *libbase, BPTR seglist, struct ExecIFace *pIExec); +static BPTR Expungelib(struct LibraryManagerInterface *Self); +static struct LibraryHeader *Openlib(struct LibraryManagerInterface *Self, ULONG version); +static BPTR Closelib(struct LibraryManagerInterface *Self); +static ULONG Obtainlib(struct Interface *Self); +static ULONG Releaselib(struct Interface *Self); + +#if PLUGIN_TYPE == PREVIEW +static LIBFUNC_P4VA_PROTO(ULONG, LIBSCAPreviewGenerateTags, + A0, struct ScaWindowTask *, wt, + A1, BPTR, dirLock, + A2, CONST_STRPTR, iconName, + A6, struct PluginBase *, PluginBase); +#endif + +extern CONST_APTR VecTable68K[]; + +struct ExecBase *SysBase; +struct ExecIFace *IExec; + +//---------------------------------------------------------------------------- + +#include "plugin-common.c" + +//---------------------------------------------------------------------------- + +/* OS4.0 Library */ + +/* ------------------- OS4 Manager Interface ------------------------ */ +static const APTR managerfunctable[] = + { + (APTR)Obtainlib, + (APTR)Releaselib, + (APTR)NULL, + (APTR)NULL, + (APTR)Openlib, + (APTR)Closelib, + (APTR)Expungelib, + (APTR)NULL, + (APTR)-1 + }; + +static const struct TagItem managertags[] = + { + {MIT_Name, (ULONG)"__library"}, + {MIT_VectorTable, (ULONG)managerfunctable}, + {MIT_Version, 1}, + {TAG_DONE, 0} + }; + +/* ---------------------- OS4 Main Interface ------------------------ */ +static APTR functable[] = + { + Obtainlib, + Releaselib, + NULL, + NULL, +#if PLUGIN_TYPE == OOP + GetClassInfo, +#endif +#if (PLUGIN_TYPE == FILETYPE) + FT_INFOSTRING, +#endif +#if PLUGIN_TYPE == PREVIEW + PV_GENERATE, + LIBSCAPreviewGenerateTags, +#endif +#if (PLUGIN_TYPE == PREFS) + LIBSCAGetPrefsInfo, +#endif + (APTR) -1 + }; + +static const struct TagItem maintags[] = + { + {MIT_Name, (ULONG)"main"}, + {MIT_VectorTable, (ULONG)functable}, + {MIT_Version, 1}, + {TAG_DONE, 0} + }; + +/* Init table used in library initialization. */ +static const ULONG interfaces[] = + { + (ULONG)managertags, + (ULONG)maintags, + (ULONG)0 + }; + +static const struct TagItem inittab[] = + { + {CLT_DataSize, (ULONG)sizeof(LIB_BASETYPE)}, + {CLT_Interfaces, (ULONG) interfaces}, + {CLT_Vector68K, (ULONG)VecTable68K}, + {CLT_InitFunc, (ULONG) Initlib}, + {TAG_DONE, 0} + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, + RTF_NATIVE | RTF_AUTOINIT, + LIB_VERSION, + NT_LIBRARY, + 0, + libName, +#ifdef LIB_IDSTRING + libIdString, +#else + &libVerString[6], +#endif + (APTR)inittab + }; + +/* ------------------- OS4 Manager Functions ------------------------ */ +static struct Library * Initlib(struct Library *libbase, BPTR seglist, struct ExecIFace *pIExec) +{ + struct PluginBase *PluginBase = (struct PluginBase *) libbase; + + SysBase = (struct ExecBase *)pIExec->Data.LibBase; + IExec = pIExec; + + (void)libVerString; + + PluginBase->pl_Initialized = FALSE; + + PluginBase->pl_LibNode.lib_Revision = LIB_REVISION; + PluginBase->pl_SegList = seglist; + +#if PLUGIN_TYPE == OOP + PluginBase->pl_PlugID = MAKE_ID('P','L','U','G'); +#endif + d1(kprintf(__FILE__ "/%s/%ld: pl_PlugID=%08lx\n", __FUNC__, __LINE__, PluginBase->pl_PlugID)); + + return (struct Library *)PluginBase; +} + +static BPTR Expungelib(struct LibraryManagerInterface *Self) +{ + struct PluginBase *PluginBase = (struct PluginBase *) Self->Data.LibBase; + + if (0 == PluginBase->pl_LibNode.lib_OpenCnt) + { + BPTR libseglist = PluginBase->pl_SegList; + + Remove((struct Node *) PluginBase); +#ifndef NOCLOSEPLUGIN + closePlugin(PluginBase); +#endif + DeleteLibrary((struct Library *)PluginBase); + + return libseglist; + } + + PluginBase->pl_LibNode.lib_Flags |= LIBF_DELEXP; + + return (BPTR)NULL; +} + +static struct LibraryHeader *Openlib(struct LibraryManagerInterface *Self, ULONG version) +{ + struct PluginBase *PluginBase = (struct PluginBase *) Self->Data.LibBase; + + PluginBase->pl_LibNode.lib_OpenCnt++; + PluginBase->pl_LibNode.lib_Flags &= ~LIBF_DELEXP; + +#ifndef NOINITPLUGIN + if (!PluginBase->pl_Initialized) + { + if (!initPlugin(PluginBase)) + { + Closelib(Self); + return NULL; + } + PluginBase->pl_Initialized = TRUE; + } +#endif + + return (struct LibraryHeader *)PluginBase; +} + +static BPTR Closelib(struct LibraryManagerInterface *Self) +{ + struct PluginBase *PluginBase = (struct PluginBase *) Self->Data.LibBase; + + PluginBase->pl_LibNode.lib_OpenCnt--; +/* + if (0 == PluginBase->pl_LibNode.lib_OpenCnt) + { + if (PluginBase->pl_LibNode.lib_Flags & LIBF_DELEXP) + { + return Expungelib(Self); + } + } +*/ + return (BPTR)NULL; +} + +static ULONG Obtainlib(struct Interface *Self) +{ + return(Self->Data.RefCount++); +} + +static ULONG Releaselib(struct Interface *Self) +{ + return(Self->Data.RefCount--); +} + +#if PLUGIN_TYPE == PREVIEW +static LIBFUNC_P4VA(ULONG, LIBSCAPreviewGenerateTags, + A0, struct ScaWindowTask *, wt, + A1, BPTR, dirLock, + A2, CONST_STRPTR, iconName, + A6, struct PluginBase *, PluginBase) +{ + BOOL ret; + va_list args; + va_startlinear(args, iconName); + + (void) PluginBase; + + ret = ((struct ScalosPreviewPluginIFace *)self)->SCAPreviewGenerate(wt, dirLock, iconName, va_getlinearva(args, struct TagItem *)); + + va_end(args); + + return(ret); +} +LIBFUNC_END +#endif + diff --git a/scalos/common/Plugin/plugin-aros.c b/scalos/common/Plugin/plugin-aros.c new file mode 100644 index 000000000..4874bc53b --- /dev/null +++ b/scalos/common/Plugin/plugin-aros.c @@ -0,0 +1,255 @@ +// plugin-classic.c +// $Date$ +// $Revision$ + + +#include +#include +#include + +#include +#include + +#include +#include + +#include + +#include + +#include + +#include + +#include "plugin.h" + +#ifndef d +#define d(x) +#endif +#ifndef d1 +#define d1(x) +#endif +#ifndef d2 +#define d2(x) x +#endif + +#define FUNCNAME(NAME) PluginBase_0##_##NAME + +// from debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +struct Library *aroscbase; + +//---------------------------------------------------------------------------- + +static AROS_UFP3 (struct Library *, Initlib, + AROS_UFPA(struct Library *, libbase, D0), + AROS_UFPA(BPTR, seglist, A0), + AROS_UFPA(struct ExecBase *, sysBase, A6) +); +static AROS_LD1 (struct Library *, Openlib, + AROS_LPA (__unused ULONG, version, D0), + struct Library *, base, 1, Plugin +); +static AROS_LD0 (struct SegList *, Closelib, + struct Library *, base, 2, Plugin +); +static AROS_LD1 (struct SegList *, Expungelib, + AROS_LPA(__unused struct Library *, __extrabase, D0), + struct Library *, base, 3, Plugin +); +static AROS_LD0 (ULONG, Extfunclib, + __unused struct Library *, libbase, 4, Plugin +); + +//---------------------------------------------------------------------------- + +SAVEDS(LONG) ASM Libstart(void) +{ + return -1; +} + +//---------------------------------------------------------------------------- + +#include "plugin-common.c" + +//---------------------------------------------------------------------------- + +/* OS3.x Library */ + +static APTR functable[] = + { + Plugin_1_Openlib, + Plugin_2_Closelib, + Plugin_3_Expungelib, + Plugin_4_Extfunclib, +#if PLUGIN_TYPE == OOP + Dummy_0_GetClassInfo, +#elif PLUGIN_TYPE == FILETYPE + FT_INFOSTRING_AROS, +#endif +#if PLUGIN_TYPE == PREVIEW + PV_GENERATE, +#endif +#if (PLUGIN_TYPE == PREFS) + PluginBase_0_LIBSCAGetPrefsInfo, +#endif + (APTR) -1 + }; + +/* Init table used in library initialization. */ +static ULONG inittab[] = + { + sizeof(LIB_BASETYPE), + (ULONG) functable, + 0, + (ULONG) Initlib + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, + RTF_AUTOINIT, + LIB_VERSION, + NT_LIBRARY, + 0, + libName, +#ifdef LIB_IDSTRING + libIdString, +#else /* LIB_IDSTRING */ + &libVerString[6], +#endif /* LIB_IDSTRING */ + inittab + }; + + +//---------------------------------------------------------------------------- + +static AROS_UFH3(struct Library *, Initlib, + AROS_UFHA(struct Library *, libbase, D0), + AROS_UFHA(BPTR, seglist, A0), + AROS_UFHA(struct ExecBase *, sysBase, A6) +) +{ + AROS_USERFUNC_INIT + + struct PluginBase *PluginBase = (struct PluginBase *) libbase; + + (void)libVerString; + SysBase = sysBase; + + PluginBase->pl_Initialized = FALSE; + + PluginBase->pl_LibNode.lib_Revision = LIB_REVISION; + PluginBase->pl_SegList = seglist; + + aroscbase = OpenLibrary("arosc.library" ,0 ); + +#if PLUGIN_TYPE == OOP + PluginBase->pl_PlugID = MAKE_ID('P','L','U','G'); +#endif + + return &PluginBase->pl_LibNode; + + AROS_USERFUNC_EXIT +} + + +static AROS_LH1(struct Library *, Openlib, + AROS_LHA(__unused ULONG, version, D0), + struct Library *, libbase, 1, Plugin +) +{ + AROS_LIBFUNC_INIT + + struct PluginBase *PluginBase = (struct PluginBase *) libbase; + + PluginBase->pl_LibNode.lib_OpenCnt++; + PluginBase->pl_LibNode.lib_Flags &= ~LIBF_DELEXP; + + if (!PluginBase->pl_Initialized) + { + if (!initPlugin(PluginBase)) + { + Plugin_2_Closelib(&PluginBase->pl_LibNode); + return NULL; + } + PluginBase->pl_Initialized = TRUE; + } + + return &PluginBase->pl_LibNode; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH0(struct SegList *, Closelib, + struct Library *, libbase, 2, Plugin +) +{ + AROS_LIBFUNC_INIT + + struct PluginBase *PluginBase = (struct PluginBase *) libbase; + + PluginBase->pl_LibNode.lib_OpenCnt--; + + if (0 == PluginBase->pl_LibNode.lib_OpenCnt) + { + if (PluginBase->pl_LibNode.lib_Flags & LIBF_DELEXP) + { + return Plugin_3_Expungelib(&PluginBase->pl_LibNode, &PluginBase->pl_LibNode); + } + } + + return (BPTR)NULL; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH1(struct SegList *, Expungelib, + AROS_LHA(__unused struct Library *, __extrabase, D0), + struct Library *, libbase, 3, Plugin +) +{ + AROS_LIBFUNC_INIT + + struct PluginBase *PluginBase = (struct PluginBase *) libbase; + + if (0 == PluginBase->pl_LibNode.lib_OpenCnt) + { + ULONG size = PluginBase->pl_LibNode.lib_NegSize + PluginBase->pl_LibNode.lib_PosSize; + UBYTE *ptr = (UBYTE *) PluginBase - PluginBase->pl_LibNode.lib_NegSize; + BPTR libseglist = PluginBase->pl_SegList; + + Remove((struct Node *) PluginBase); + closePlugin(PluginBase); + FreeMem(ptr,size); + + return libseglist; + } + + PluginBase->pl_LibNode.lib_Flags |= LIBF_DELEXP; + + return (BPTR)NULL; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH0(ULONG, Extfunclib, __unused struct Library *, libbase, 4, Plugin) +{ + AROS_LIBFUNC_INIT + + return 0; + + AROS_LIBFUNC_EXIT +} + + +//---------------------------------------------------------------------------- diff --git a/scalos/common/Plugin/plugin-classic.c b/scalos/common/Plugin/plugin-classic.c new file mode 100644 index 000000000..e197c5e64 --- /dev/null +++ b/scalos/common/Plugin/plugin-classic.c @@ -0,0 +1,221 @@ +// plugin-classic.c +// $Date$ +// $Revision$ + + +#include +#include +#include + +#include +#include + +#include +#include + +#include + +#include + +#include + +#include "plugin.h" + +#ifndef d +#define d(x) +#endif +#ifndef d1 +#define d1(x) +#endif +#ifndef d2 +#define d2(x) x +#endif + +// from debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +struct ExecBase *SysBase; + +//---------------------------------------------------------------------------- + +static LIB_SAVEDS(struct Library *) LIB_ASM LIB_INTERRUPT Initlib(LIB_REG(d0, struct Library *libbase), + LIB_REG(a0, BPTR seglist), LIB_REG(a6, struct ExecBase *sysBase)); + +static LIBFUNC_PROTO(Openlib, libbase, struct Library *); +static LIBFUNC_PROTO(Closelib, libbase, BPTR); +static LIBFUNC_PROTO(Expungelib, libbase, BPTR); +static LIBFUNC_PROTO(Extfunclib, libbase, ULONG); + +//---------------------------------------------------------------------------- + +SAVEDS(LONG) ASM Libstart(void) +{ + return -1; +} + +//---------------------------------------------------------------------------- + +#include "plugin-common.c" + +//---------------------------------------------------------------------------- + +/* OS3.x Library */ + +static APTR functable[] = + { +#ifdef __MORPHOS__ + (APTR) FUNCARRAY_32BIT_NATIVE, +#endif /* __MORPHOS__ */ + Openlib, + Closelib, + Expungelib, + Extfunclib, +#if PLUGIN_TYPE == OOP + GetClassInfo, +#elif PLUGIN_TYPE == FILETYPE + FT_INFOSTRING, +#endif +#if PLUGIN_TYPE == PREVIEW + PV_GENERATE, +#endif +#if (PLUGIN_TYPE == PREFS) + LIBSCAGetPrefsInfo, +#endif + (APTR) -1 + }; + +/* Init table used in library initialization. */ +static ULONG inittab[] = + { + sizeof(LIB_BASETYPE), + (ULONG) functable, + 0, + (ULONG) Initlib + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, +#ifdef __MORPHOS__ + RTF_PPC | RTF_AUTOINIT, +#else /* __MORPHOS__ */ + RTF_AUTOINIT, +#endif /* __MORPHOS__ */ + LIB_VERSION, + NT_LIBRARY, + 0, + libName, +#ifdef LIB_IDSTRING + libIdString, +#else /* LIB_IDSTRING */ + &libVerString[6], +#endif /* LIB_IDSTRING */ + inittab + }; + +#ifdef __MORPHOS__ +ULONG __abox__=1; +#endif /* __MORPHOS__ */ + +//---------------------------------------------------------------------------- + +static LIB_SAVEDS(struct Library *) LIB_ASM LIB_INTERRUPT Initlib(LIB_REG(d0, struct Library *libbase), + LIB_REG(a0, BPTR seglist), LIB_REG(a6, struct ExecBase *sysBase)) +{ + struct PluginBase *PluginBase = (struct PluginBase *) libbase; + + (void)libVerString; + SysBase = sysBase; + + PluginBase->pl_Initialized = FALSE; + + PluginBase->pl_LibNode.lib_Revision = LIB_REVISION; + PluginBase->pl_SegList = seglist; + +#if PLUGIN_TYPE == OOP + PluginBase->pl_PlugID = MAKE_ID('P','L','U','G'); +#endif + + return &PluginBase->pl_LibNode; +} + + +static LIBFUNC(Openlib, libbase, struct Library *) +{ + struct PluginBase *PluginBase = (struct PluginBase *) libbase; + + PluginBase->pl_LibNode.lib_OpenCnt++; + PluginBase->pl_LibNode.lib_Flags &= ~LIBF_DELEXP; + + if (!PluginBase->pl_Initialized) + { + if (!initPlugin(PluginBase)) + { + CALLLIBFUNC(Closelib, &PluginBase->pl_LibNode); + return NULL; + } + PluginBase->pl_Initialized = TRUE; + } + + return &PluginBase->pl_LibNode; +} +LIBFUNC_END + + +static LIBFUNC(Closelib, libbase, BPTR) +{ + struct PluginBase *PluginBase = (struct PluginBase *) libbase; + + PluginBase->pl_LibNode.lib_OpenCnt--; + + if (0 == PluginBase->pl_LibNode.lib_OpenCnt) + { + if (PluginBase->pl_LibNode.lib_Flags & LIBF_DELEXP) + { + return CALLLIBFUNC(Expungelib, &PluginBase->pl_LibNode); + } + } + + return (BPTR)NULL; +} +LIBFUNC_END + + +static LIBFUNC(Expungelib, libbase, BPTR) +{ + struct PluginBase *PluginBase = (struct PluginBase *) libbase; + + if (0 == PluginBase->pl_LibNode.lib_OpenCnt) + { + ULONG size = PluginBase->pl_LibNode.lib_NegSize + PluginBase->pl_LibNode.lib_PosSize; + UBYTE *ptr = (UBYTE *) PluginBase - PluginBase->pl_LibNode.lib_NegSize; + BPTR libseglist = PluginBase->pl_SegList; + + Remove((struct Node *) PluginBase); + closePlugin(PluginBase); + FreeMem(ptr,size); + + return libseglist; + } + + PluginBase->pl_LibNode.lib_Flags |= LIBF_DELEXP; + + return (BPTR)NULL; +} +LIBFUNC_END + + +static LIBFUNC(Extfunclib, libbase, ULONG) +{ + (void) libbase; + return 0; +} +LIBFUNC_END + + +//---------------------------------------------------------------------------- diff --git a/scalos/common/Plugin/plugin-common.c b/scalos/common/Plugin/plugin-common.c new file mode 100644 index 000000000..710d9b22f --- /dev/null +++ b/scalos/common/Plugin/plugin-common.c @@ -0,0 +1,106 @@ +// plugin-common.c +// $Date$ +// $Revision$ + +//---------------------------------------------------------------------------- +// Check the preprocessor symbols provided by plugin_data.h + +#if !defined(LIB_VERSION) || !defined(LIB_REVISION) || !defined(LIB_NAME) || !defined(LIB_VERSTRING) +#error Library version, revision, name or version string not defined +#endif + +#ifndef LIB_BASETYPE +#define LIB_BASETYPE struct PluginBase +#endif + +#if PLUGIN_TYPE == OOP + +#if !defined(CI_CLASSNAME) || !defined(CI_PLUGINNAME) || !defined(CI_DESCRIPTION) \ + || !defined(CI_AUTHOR) || !defined(CI_HOOKFUNC) +#error classname, pluginname, description, author or hookfunc not define for ClassInfo +#endif + +#ifndef CI_SUPERCLASSNAME +#define CI_SUPERCLASSNAME CI_CLASSNAME +#endif +#ifndef CI_PRIORITY +#define CI_PRIORITY 0 +#endif +#ifndef CI_NEEDEDVERSION +#define CI_NEEDEDVERSION 39 +#endif +#ifndef CI_INSTSIZE +#define CI_INSTSIZE 2*sizeof(ULONG) +#endif + +#elif PLUGIN_TYPE == FILETYPE + +#ifndef FT_INFOSTRING +#error FT_INFOSTRING not defined for FileType plugin +#endif + +#elif PLUGIN_TYPE == PREVIEW + +#ifndef PV_GENERATE +#ifdef __AROS__ +#define PV_GENERATE PluginBase_0_LIBSCAPreviewGenerate +#else +#define PV_GENERATE LIBSCAPreviewGenerate +#endif +#endif + +#elif PLUGIN_TYPE == PREFS + +// Nothing to do + +#else + +#error Unknown or undefined PLUGIN_TYPE + +#endif + +//---------------------------------------------------------------------------- +// Code common to plugin-aos4.c and plugin-classic.c + +static char ALIGNED libName[] = LIB_NAME; +static char ALIGNED libVerString[] = LIB_VERSTRING; +#ifdef LIB_IDSTRING +static char ALIGNED libIdString[] = LIB_IDSTRING; +#endif + +#if PLUGIN_TYPE == OOP + +STATIC_PATCHFUNC(CI_HOOKFUNC) + +/* structure which holds the data that Scalos needs for this class/plugin */ +static struct ScaClassInfo ClassInfo = +{ + /* Next three lines constitute the Hook structure within this structure */ + { + { 0,0 }, /* previous and successor pointers, set to NULL */ + (HOOKFUNC) PATCH_NEWFUNC(CI_HOOKFUNC), /* pointer to hook function which does the real work in this plugin */ + 0,0 /* h_SubEntry and h_Data are 0 by default */ + }, + + CI_PRIORITY, /* Priority of this class */ + CI_INSTSIZE, /* Instance size */ + CI_NEEDEDVERSION, /* Required version of Scalos */ + 0, /* Reserved */ + CI_CLASSNAME, /* name of this class */ + CI_SUPERCLASSNAME, /* name of the superclass */ + CI_PLUGINNAME, /* real name of the plugin */ + CI_DESCRIPTION, /* description of plugin */ + CI_AUTHOR /* name of author */ +}; + +static LIBFUNC(GetClassInfo, libbase, struct ScaClassInfo *) +{ + (void)libbase; + return &ClassInfo; +} +LIBFUNC_END + +#endif + +//---------------------------------------------------------------------------- + diff --git a/scalos/common/Plugin/plugin.h b/scalos/common/Plugin/plugin.h new file mode 100644 index 000000000..b3733dd51 --- /dev/null +++ b/scalos/common/Plugin/plugin.h @@ -0,0 +1,77 @@ +// plugin.h +// $Date$ +// $Revision$ + +// Include "plugin_data.h" without PLUGIN_H_INCLUDED defined to make it also work +// when "plugin.h" is (indirectly) included from "plugin_data.h" +#include "plugin_data.h" + +#ifndef PLUGIN_H_INCLUDED +#define PLUGIN_H_INCLUDED + +#include +#include + +#define OOP 1 +#define FILETYPE 2 +#define PREVIEW 3 +#define PREFS 4 + +#if defined(__GNUC__) && !defined(mc68000) +#pragma pack(2) +#endif /* __GNUC__ */ + +// DeviceFilter library base +struct PluginBase + { + struct Library pl_LibNode; +#if PLUGIN_TYPE == OOP + ULONG pl_PlugID; +#endif + BPTR pl_SegList; + UBYTE pl_Initialized; + }; + +#if defined(__GNUC__) && !defined(mc68000) +#pragma pack() +#endif /* __GNUC__ */ +#endif /* PLUGIN_H_INCLUDED */ + +BOOL initPlugin(struct PluginBase *pluginbase); +VOID closePlugin(struct PluginBase *pluginbase); + +#if PLUGIN_TYPE == OOP +#include + +M68KFUNC_P3_PROTO(ULONG, CI_HOOKFUNC, + A0, Class *, cl, + A2, Object *, obj, + A1, Msg, msg); +#endif // PLUGIN_TYPE == OOP + +#if PLUGIN_TYPE == FILETYPE +#include + +LIBFUNC_P3_PROTO(STRPTR, FT_INFOSTRING, + A0, struct ScaToolTipInfoHookData *, ttshd, + A1, CONST_STRPTR, args, + A6, struct PluginBase *, PluginBase); +#endif // PLUGIN_TYPE == FILETYPE + +#if PLUGIN_TYPE == PREVIEW +#include + +LIBFUNC_P5_PROTO(LONG, LIBSCAPreviewGenerate, + A0, struct ScaWindowTask *, wt, + A1, BPTR, dirLock, + A2, CONST_STRPTR, iconName, + A3, struct TagItem *, tagList, + A6, struct PluginBase *, PluginBase); +#endif // PLUGIN_TYPE == PREVIEW + +#if PLUGIN_TYPE == PREFS +LIBFUNC_P2_PROTO(ULONG, LIBSCAGetPrefsInfo, + D0, ULONG, which, + A6, struct PluginBase *, PluginBase); +#endif // PLUGIN_TYPE == PREFS + diff --git a/scalos/common/Plugin/scalosfiletypeplugin-aos4-68kstubs.c b/scalos/common/Plugin/scalosfiletypeplugin-aos4-68kstubs.c new file mode 100644 index 000000000..21b6b5c2a --- /dev/null +++ b/scalos/common/Plugin/scalosfiletypeplugin-aos4-68kstubs.c @@ -0,0 +1,79 @@ +/* +** This file was automatically generated by fdtrans 52.1. +** Do not edit it by hand. Instead, edit the sfd file +** that was used to generate this file +*/ + +#ifdef __USE_INLINE__ +#undef __USE_INLINE__ +#endif +#ifndef __NOGLOBALIFACE__ +#define __NOGLOBALIFACE__ +#endif + +#include +#include +#include +#include +#include +#include + + +static inline int8 convert_int8 (uint32 x) { return x; } +static inline int16 convert_int16(uint32 x) { return x; } + + +STATIC struct Library * stub_OpenPPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct LibraryManagerInterface *Self = (struct LibraryManagerInterface *) ExtLib->ILibrary; + + return Self->Open(0); +} +STATIC CONST struct EmuTrap stub_Open = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_OpenPPC }; + +STATIC APTR stub_ClosePPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct LibraryManagerInterface *Self = (struct LibraryManagerInterface *) ExtLib->ILibrary; + + return Self->Close(); +} +STATIC CONST struct EmuTrap stub_Close = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_ClosePPC }; + +STATIC APTR stub_ExpungePPC(ULONG *regarray __attribute__((unused))) +{ + return NULL; +} +STATIC CONST struct EmuTrap stub_Expunge = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_ExpungePPC }; + +STATIC ULONG stub_ReservedPPC(ULONG *regarray __attribute__((unused))) +{ + return 0UL; +} +STATIC CONST struct EmuTrap stub_Reserved = { TRAPINST, TRAPTYPE, stub_ReservedPPC }; + +static STRPTR stub_SCAToolTipInfoStringPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct ScalosFileTypePluginIFace *Self = (struct ScalosFileTypePluginIFace *) ExtLib->MainIFace; + + return Self->SCAToolTipInfoString( + (struct ScaToolTipInfoHookData *)regarray[8], + (CONST_STRPTR)regarray[9] + ); +} +STATIC CONST struct EmuTrap stub_SCAToolTipInfoString = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SCAToolTipInfoStringPPC }; + +CONST CONST_APTR VecTable68K[] = +{ + &stub_Open, + &stub_Close, + &stub_Expunge, + &stub_Reserved, + &stub_SCAToolTipInfoString, + (CONST_APTR)-1 +}; diff --git a/scalos/common/Plugin/scalosplugin-aos4-68kstubs.c b/scalos/common/Plugin/scalosplugin-aos4-68kstubs.c new file mode 100644 index 000000000..b5e005851 --- /dev/null +++ b/scalos/common/Plugin/scalosplugin-aos4-68kstubs.c @@ -0,0 +1,77 @@ +/* +** This file was automatically generated by fdtrans 52.1. +** Do not edit it by hand. Instead, edit the sfd file +** that was used to generate this file +*/ + +#ifdef __USE_INLINE__ +#undef __USE_INLINE__ +#endif +#ifndef __NOGLOBALIFACE__ +#define __NOGLOBALIFACE__ +#endif + +#include +#include +#include +#include +#include +#include + + +static inline int8 convert_int8 (uint32 x) { return x; } +static inline int16 convert_int16(uint32 x) { return x; } + + +STATIC struct Library * stub_OpenPPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct LibraryManagerInterface *Self = (struct LibraryManagerInterface *) ExtLib->ILibrary; + + return Self->Open(0); +} +STATIC CONST struct EmuTrap stub_Open = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_OpenPPC }; + +STATIC APTR stub_ClosePPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct LibraryManagerInterface *Self = (struct LibraryManagerInterface *) ExtLib->ILibrary; + + return Self->Close(); +} +STATIC CONST struct EmuTrap stub_Close = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_ClosePPC }; + +STATIC APTR stub_ExpungePPC(ULONG *regarray __attribute__((unused))) +{ + return NULL; +} +STATIC CONST struct EmuTrap stub_Expunge = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_ExpungePPC }; + +STATIC ULONG stub_ReservedPPC(ULONG *regarray __attribute__((unused))) +{ + return 0UL; +} +STATIC CONST struct EmuTrap stub_Reserved = { TRAPINST, TRAPTYPE, stub_ReservedPPC }; + +static const struct ScaClassInfo * stub_SCAGetClassInfoPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct ScalosPluginIFace *Self = (struct ScalosPluginIFace *) ExtLib->MainIFace; + + return Self->SCAGetClassInfo( + ); +} +STATIC CONST struct EmuTrap stub_SCAGetClassInfo = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SCAGetClassInfoPPC }; + +CONST CONST_APTR VecTable68K[] = +{ + &stub_Open, + &stub_Close, + &stub_Expunge, + &stub_Reserved, + &stub_SCAGetClassInfo, + (CONST_APTR)-1 +}; diff --git a/scalos/common/Plugin/scalosprefsplugin-aos4-68kstubs.c b/scalos/common/Plugin/scalosprefsplugin-aos4-68kstubs.c new file mode 100755 index 000000000..bf46378c5 --- /dev/null +++ b/scalos/common/Plugin/scalosprefsplugin-aos4-68kstubs.c @@ -0,0 +1,78 @@ +/* +** This file was automatically generated by fdtrans 52.1. +** Do not edit it by hand. Instead, edit the sfd file +** that was used to generate this file +*/ + +#ifdef __USE_INLINE__ +#undef __USE_INLINE__ +#endif +#ifndef __NOGLOBALIFACE__ +#define __NOGLOBALIFACE__ +#endif + +#include +#include +#include +#include +#include +#include + + +static inline int8 convert_int8 (uint32 x) { return x; } +static inline int16 convert_int16(uint32 x) { return x; } + + +STATIC struct Library * stub_OpenPPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct LibraryManagerInterface *Self = (struct LibraryManagerInterface *) ExtLib->ILibrary; + + return Self->Open(0); +} +STATIC CONST struct EmuTrap stub_Open = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_OpenPPC }; + +STATIC APTR stub_ClosePPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct LibraryManagerInterface *Self = (struct LibraryManagerInterface *) ExtLib->ILibrary; + + return Self->Close(); +} +STATIC CONST struct EmuTrap stub_Close = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_ClosePPC }; + +STATIC APTR stub_ExpungePPC(ULONG *regarray __attribute__((unused))) +{ + return NULL; +} +STATIC CONST struct EmuTrap stub_Expunge = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_ExpungePPC }; + +STATIC ULONG stub_ReservedPPC(ULONG *regarray __attribute__((unused))) +{ + return 0UL; +} +STATIC CONST struct EmuTrap stub_Reserved = { TRAPINST, TRAPTYPE, stub_ReservedPPC }; + +static ULONG stub_SCAGetPrefsInfoPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct ScalosPrefsPluginIFace *Self = (struct ScalosPrefsPluginIFace *) ExtLib->MainIFace; + + return Self->SCAGetPrefsInfo( + (LONG)regarray[0] + ); +} +STATIC CONST struct EmuTrap stub_SCAGetPrefsInfo = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SCAGetPrefsInfoPPC }; + +CONST CONST_APTR VecTable68K[] = +{ + &stub_Open, + &stub_Close, + &stub_Expunge, + &stub_Reserved, + &stub_SCAGetPrefsInfo, + (CONST_APTR)-1 +}; diff --git a/scalos/common/Plugin/scalospreviewplugin-aos4-68kstubs.c b/scalos/common/Plugin/scalospreviewplugin-aos4-68kstubs.c new file mode 100644 index 000000000..caa8f6d1f --- /dev/null +++ b/scalos/common/Plugin/scalospreviewplugin-aos4-68kstubs.c @@ -0,0 +1,81 @@ +/* +** This file was automatically generated by fdtrans 52.1. +** Do not edit it by hand. Instead, edit the sfd file +** that was used to generate this file +*/ + +#ifdef __USE_INLINE__ +#undef __USE_INLINE__ +#endif +#ifndef __NOGLOBALIFACE__ +#define __NOGLOBALIFACE__ +#endif + +#include +#include +#include +#include +#include +#include + + +static inline int8 convert_int8 (uint32 x) { return x; } +static inline int16 convert_int16(uint32 x) { return x; } + + +STATIC struct Library * stub_OpenPPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct LibraryManagerInterface *Self = (struct LibraryManagerInterface *) ExtLib->ILibrary; + + return Self->Open(0); +} +STATIC CONST struct EmuTrap stub_Open = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_OpenPPC }; + +STATIC APTR stub_ClosePPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct LibraryManagerInterface *Self = (struct LibraryManagerInterface *) ExtLib->ILibrary; + + return Self->Close(); +} +STATIC CONST struct EmuTrap stub_Close = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_ClosePPC }; + +STATIC APTR stub_ExpungePPC(ULONG *regarray __attribute__((unused))) +{ + return NULL; +} +STATIC CONST struct EmuTrap stub_Expunge = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_ExpungePPC }; + +STATIC ULONG stub_ReservedPPC(ULONG *regarray __attribute__((unused))) +{ + return 0UL; +} +STATIC CONST struct EmuTrap stub_Reserved = { TRAPINST, TRAPTYPE, stub_ReservedPPC }; + +static LONG stub_SCAPreviewGeneratePPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct ScalosPreviewPluginIFace *Self = (struct ScalosPreviewPluginIFace *) ExtLib->MainIFace; + + return Self->SCAPreviewGenerate( + (struct ScaWindowTask *)regarray[8], + (BPTR)regarray[9], + (CONST_STRPTR)regarray[10], + (struct TagItem *)regarray[11] + ); +} +STATIC CONST struct EmuTrap stub_SCAPreviewGenerate = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SCAPreviewGeneratePPC }; + +CONST CONST_APTR VecTable68K[] = +{ + &stub_Open, + &stub_Close, + &stub_Expunge, + &stub_Reserved, + &stub_SCAPreviewGenerate, + (CONST_APTR)-1 +}; diff --git a/scalos/common/malloc/malloc.c b/scalos/common/malloc/malloc.c new file mode 100755 index 000000000..dc0a1353f --- /dev/null +++ b/scalos/common/malloc/malloc.c @@ -0,0 +1,6321 @@ +// malloc.c +// $Date$ +// $Revision$ + +/* + This is a version (aka dlmalloc) of malloc/free/realloc written by + Doug Lea and released to the public domain, as explained at + http://creativecommons.org/publicdomain/zero/1.0/ Send questions, + comments, complaints, performance data, etc to dl@cs.oswego.edu + +* Version 2.8.5 Sun May 22 10:26:02 2011 Doug Lea (dl at gee) + + Note: There may be an updated version of this malloc obtainable at + ftp://gee.cs.oswego.edu/pub/misc/malloc.c + Check before installing! + +* Quickstart + + This library is all in one file to simplify the most common usage: + ftp it, compile it (-O3), and link it into another program. All of + the compile-time options default to reasonable values for use on + most platforms. You might later want to step through various + compile-time and dynamic tuning options. + + For convenience, an include file for code using this malloc is at: + ftp://gee.cs.oswego.edu/pub/misc/malloc-2.8.5.h + You don't really need this .h file unless you call functions not + defined in your system include files. The .h file contains only the + excerpts from this file needed for using this malloc on ANSI C/C++ + systems, so long as you haven't changed compile-time options about + naming and tuning parameters. If you do, then you can create your + own malloc.h that does include all settings by cutting at the point + indicated below. Note that you may already by default be using a C + library containing a malloc that is based on some version of this + malloc (for example in linux). You might still want to use the one + in this file to customize settings or to avoid overheads associated + with library versions. + +* Vital statistics: + + Supported pointer/size_t representation: 4 or 8 bytes + size_t MUST be an unsigned type of the same width as + pointers. (If you are using an ancient system that declares + size_t as a signed type, or need it to be a different width + than pointers, you can use a previous release of this malloc + (e.g. 2.7.2) supporting these.) + + Alignment: 8 bytes (default) + This suffices for nearly all current machines and C compilers. + However, you can define MALLOC_ALIGNMENT to be wider than this + if necessary (up to 128bytes), at the expense of using more space. + + Minimum overhead per allocated chunk: 4 or 8 bytes (if 4byte sizes) + 8 or 16 bytes (if 8byte sizes) + Each malloced chunk has a hidden word of overhead holding size + and status information, and additional cross-check word + if FOOTERS is defined. + + Minimum allocated size: 4-byte ptrs: 16 bytes (including overhead) + 8-byte ptrs: 32 bytes (including overhead) + + Even a request for zero bytes (i.e., malloc(0)) returns a + pointer to something of the minimum allocatable size. + The maximum overhead wastage (i.e., number of extra bytes + allocated than were requested in malloc) is less than or equal + to the minimum size, except for requests >= mmap_threshold that + are serviced via mmap(), where the worst case wastage is about + 32 bytes plus the remainder from a system page (the minimal + mmap unit); typically 4096 or 8192 bytes. + + Security: static-safe; optionally more or less + The "security" of malloc refers to the ability of malicious + code to accentuate the effects of errors (for example, freeing + space that is not currently malloc'ed or overwriting past the + ends of chunks) in code that calls malloc. This malloc + guarantees not to modify any memory locations below the base of + heap, i.e., static variables, even in the presence of usage + errors. The routines additionally detect most improper frees + and reallocs. All this holds as long as the static bookkeeping + for malloc itself is not corrupted by some other means. This + is only one aspect of security -- these checks do not, and + cannot, detect all possible programming errors. + + If FOOTERS is defined nonzero, then each allocated chunk + carries an additional check word to verify that it was malloced + from its space. These check words are the same within each + execution of a program using malloc, but differ across + executions, so externally crafted fake chunks cannot be + freed. This improves security by rejecting frees/reallocs that + could corrupt heap memory, in addition to the checks preventing + writes to statics that are always on. This may further improve + security at the expense of time and space overhead. (Note that + FOOTERS may also be worth using with MSPACES.) + + By default detected errors cause the program to abort (calling + "abort()"). You can override this to instead proceed past + errors by defining PROCEED_ON_ERROR. In this case, a bad free + has no effect, and a malloc that encounters a bad address + caused by user overwrites will ignore the bad address by + dropping pointers and indices to all known memory. This may + be appropriate for programs that should continue if at all + possible in the face of programming errors, although they may + run out of memory because dropped memory is never reclaimed. + + If you don't like either of these options, you can define + CORRUPTION_ERROR_ACTION and USAGE_ERROR_ACTION to do anything + else. And if if you are sure that your program using malloc has + no errors or vulnerabilities, you can define INSECURE to 1, + which might (or might not) provide a small performance improvement. + + It is also possible to limit the maximum total allocatable + space, using malloc_set_footprint_limit. This is not + designed as a security feature in itself (calls to set limits + are not screened or privileged), but may be useful as one + aspect of a secure implementation. + + Thread-safety: NOT thread-safe unless USE_LOCKS defined non-zero + When USE_LOCKS is defined, each public call to malloc, free, + etc is surrounded with a lock. By default, this uses a plain + pthread mutex, win32 critical section, or a spin-lock if if + available for the platform and not disabled by setting + USE_SPIN_LOCKS=0. However, if USE_RECURSIVE_LOCKS is defined, + recursive versions are used instead (which are not required for + base functionality but may be needed in layered extensions). + Using a global lock is not especially fast, and can be a major + bottleneck. It is designed only to provide minimal protection + in concurrent environments, and to provide a basis for + extensions. If you are using malloc in a concurrent program, + consider instead using nedmalloc + (http://www.nedprod.com/programs/portable/nedmalloc/) or + ptmalloc (See http://www.malloc.de), which are derived from + versions of this malloc. + + System requirements: Any combination of MORECORE and/or MMAP/MUNMAP + This malloc can use unix sbrk or any emulation (invoked using + the CALL_MORECORE macro) and/or mmap/munmap or any emulation + (invoked using CALL_MMAP/CALL_MUNMAP) to get and release system + memory. On most unix systems, it tends to work best if both + MORECORE and MMAP are enabled. On Win32, it uses emulations + based on VirtualAlloc. It also uses common C library functions + like memset. + + Compliance: I believe it is compliant with the Single Unix Specification + (See http://www.unix.org). Also SVID/XPG, ANSI C, and probably + others as well. + +* Overview of algorithms + + This is not the fastest, most space-conserving, most portable, or + most tunable malloc ever written. However it is among the fastest + while also being among the most space-conserving, portable and + tunable. Consistent balance across these factors results in a good + general-purpose allocator for malloc-intensive programs. + + In most ways, this malloc is a best-fit allocator. Generally, it + chooses the best-fitting existing chunk for a request, with ties + broken in approximately least-recently-used order. (This strategy + normally maintains low fragmentation.) However, for requests less + than 256bytes, it deviates from best-fit when there is not an + exactly fitting available chunk by preferring to use space adjacent + to that used for the previous small request, as well as by breaking + ties in approximately most-recently-used order. (These enhance + locality of series of small allocations.) And for very large requests + (>= 256Kb by default), it relies on system memory mapping + facilities, if supported. (This helps avoid carrying around and + possibly fragmenting memory used only for large chunks.) + + All operations (except malloc_stats and mallinfo) have execution + times that are bounded by a constant factor of the number of bits in + a size_t, not counting any clearing in calloc or copying in realloc, + or actions surrounding MORECORE and MMAP that have times + proportional to the number of non-contiguous regions returned by + system allocation routines, which is often just 1. In real-time + applications, you can optionally suppress segment traversals using + NO_SEGMENT_TRAVERSAL, which assures bounded execution even when + system allocators return non-contiguous spaces, at the typical + expense of carrying around more memory and increased fragmentation. + + The implementation is not very modular and seriously overuses + macros. Perhaps someday all C compilers will do as good a job + inlining modular code as can now be done by brute-force expansion, + but now, enough of them seem not to. + + Some compilers issue a lot of warnings about code that is + dead/unreachable only on some platforms, and also about intentional + uses of negation on unsigned types. All known cases of each can be + ignored. + + For a longer but out of date high-level description, see + http://gee.cs.oswego.edu/dl/html/malloc.html + +* MSPACES + If MSPACES is defined, then in addition to malloc, free, etc., + this file also defines mspace_malloc, mspace_free, etc. These + are versions of malloc routines that take an "mspace" argument + obtained using create_mspace, to control all internal bookkeeping. + If ONLY_MSPACES is defined, only these versions are compiled. + So if you would like to use this allocator for only some allocations, + and your system malloc for others, you can compile with + ONLY_MSPACES and then do something like... + static mspace mymspace = create_mspace(0,0); // for example + #define mymalloc(bytes) mspace_malloc(mymspace, bytes) + + (Note: If you only need one instance of an mspace, you can instead + use "USE_DL_PREFIX" to relabel the global malloc.) + + You can similarly create thread-local allocators by storing + mspaces as thread-locals. For example: + static __thread mspace tlms = 0; + void* tlmalloc(size_t bytes) { + if (tlms == 0) tlms = create_mspace(0, 0); + return mspace_malloc(tlms, bytes); + } + void tlfree(void* mem) { mspace_free(tlms, mem); } + + Unless FOOTERS is defined, each mspace is completely independent. + You cannot allocate from one and free to another (although + conformance is only weakly checked, so usage errors are not always + caught). If FOOTERS is defined, then each chunk carries around a tag + indicating its originating mspace, and frees are directed to their + originating spaces. Normally, this requires use of locks. + + ------------------------- Compile-time options --------------------------- + +Be careful in setting #define values for numerical constants of type +size_t. On some systems, literal values are not automatically extended +to size_t precision unless they are explicitly casted. You can also +use the symbolic values MAX_SIZE_T, SIZE_T_ONE, etc below. + +WIN32 default: defined if _WIN32 defined + Defining WIN32 sets up defaults for MS environment and compilers. + Otherwise defaults are for unix. Beware that there seem to be some + cases where this malloc might not be a pure drop-in replacement for + Win32 malloc: Random-looking failures from Win32 GDI API's (eg; + SetDIBits()) may be due to bugs in some video driver implementations + when pixel buffers are malloc()ed, and the region spans more than + one VirtualAlloc()ed region. Because dlmalloc uses a small (64Kb) + default granularity, pixel buffers may straddle virtual allocation + regions more often than when using the Microsoft allocator. You can + avoid this by using VirtualAlloc() and VirtualFree() for all pixel + buffers rather than using malloc(). If this is not possible, + recompile this malloc with a larger DEFAULT_GRANULARITY. Note: + in cases where MSC and gcc (cygwin) are known to differ on WIN32, + conditions use _MSC_VER to distinguish them. + +DLMALLOC_EXPORT default: extern + Defines how public APIs are declared. If you want to export via a + Windows DLL, you might define this as + #define DLMALLOC_EXPORT extern __declspace(dllexport) + If you want a POSIX ELF shared object, you might use + #define DLMALLOC_EXPORT extern __attribute__((visibility("default"))) + +MALLOC_ALIGNMENT default: (size_t)8 + Controls the minimum alignment for malloc'ed chunks. It must be a + power of two and at least 8, even on machines for which smaller + alignments would suffice. It may be defined as larger than this + though. Note however that code and data structures are optimized for + the case of 8-byte alignment. + +MSPACES default: 0 (false) + If true, compile in support for independent allocation spaces. + This is only supported if HAVE_MMAP is true. + +ONLY_MSPACES default: 0 (false) + If true, only compile in mspace versions, not regular versions. + +USE_LOCKS default: 0 (false) + Causes each call to each public routine to be surrounded with + pthread or WIN32 mutex lock/unlock. (If set true, this can be + overridden on a per-mspace basis for mspace versions.) If set to a + non-zero value other than 1, locks are used, but their + implementation is left out, so lock functions must be supplied manually, + as described below. + +USE_SPIN_LOCKS default: 1 iff USE_LOCKS and spin locks available + If true, uses custom spin locks for locking. This is currently + supported only gcc >= 4.1, older gccs on x86 platforms, and recent + MS compilers. Otherwise, posix locks or win32 critical sections are + used. + +USE_RECURSIVE_LOCKS default: not defined + If defined nonzero, uses recursive (aka reentrant) locks, otherwise + uses plain mutexes. This is not required for malloc proper, but may + be needed for layered allocators such as nedmalloc. + +FOOTERS default: 0 + If true, provide extra checking and dispatching by placing + information in the footers of allocated chunks. This adds + space and time overhead. + +INSECURE default: 0 + If true, omit checks for usage errors and heap space overwrites. + +USE_DL_PREFIX default: NOT defined + Causes compiler to prefix all public routines with the string 'dl'. + This can be useful when you only want to use this malloc in one part + of a program, using your regular system malloc elsewhere. + +MALLOC_INSPECT_ALL default: NOT defined + If defined, compiles malloc_inspect_all and mspace_inspect_all, that + perform traversal of all heap space. Unless access to these + functions is otherwise restricted, you probably do not want to + include them in secure implementations. + +ABORT default: defined as abort() + Defines how to abort on failed checks. On most systems, a failed + check cannot die with an "assert" or even print an informative + message, because the underlying print routines in turn call malloc, + which will fail again. Generally, the best policy is to simply call + abort(). It's not very useful to do more than this because many + errors due to overwriting will show up as address faults (null, odd + addresses etc) rather than malloc-triggered checks, so will also + abort. Also, most compilers know that abort() does not return, so + can better optimize code conditionally calling it. + +PROCEED_ON_ERROR default: defined as 0 (false) + Controls whether detected bad addresses cause them to bypassed + rather than aborting. If set, detected bad arguments to free and + realloc are ignored. And all bookkeeping information is zeroed out + upon a detected overwrite of freed heap space, thus losing the + ability to ever return it from malloc again, but enabling the + application to proceed. If PROCEED_ON_ERROR is defined, the + static variable malloc_corruption_error_count is compiled in + and can be examined to see if errors have occurred. This option + generates slower code than the default abort policy. + +DEBUG default: NOT defined + The DEBUG setting is mainly intended for people trying to modify + this code or diagnose problems when porting to new platforms. + However, it may also be able to better isolate user errors than just + using runtime checks. The assertions in the check routines spell + out in more detail the assumptions and invariants underlying the + algorithms. The checking is fairly extensive, and will slow down + execution noticeably. Calling malloc_stats or mallinfo with DEBUG + set will attempt to check every non-mmapped allocated and free chunk + in the course of computing the summaries. + +ABORT_ON_ASSERT_FAILURE default: defined as 1 (true) + Debugging assertion failures can be nearly impossible if your + version of the assert macro causes malloc to be called, which will + lead to a cascade of further failures, blowing the runtime stack. + ABORT_ON_ASSERT_FAILURE cause assertions failures to call abort(), + which will usually make debugging easier. + +MALLOC_FAILURE_ACTION default: sets errno to ENOMEM, or no-op on win32 + The action to take before "return 0" when malloc fails to be able to + return memory because there is none available. + +HAVE_MORECORE default: 1 (true) unless win32 or ONLY_MSPACES + True if this system supports sbrk or an emulation of it. + +MORECORE default: sbrk + The name of the sbrk-style system routine to call to obtain more + memory. See below for guidance on writing custom MORECORE + functions. The type of the argument to sbrk/MORECORE varies across + systems. It cannot be size_t, because it supports negative + arguments, so it is normally the signed type of the same width as + size_t (sometimes declared as "intptr_t"). It doesn't much matter + though. Internally, we only call it with arguments less than half + the max value of a size_t, which should work across all reasonable + possibilities, although sometimes generating compiler warnings. + +MORECORE_CONTIGUOUS default: 1 (true) if HAVE_MORECORE + If true, take advantage of fact that consecutive calls to MORECORE + with positive arguments always return contiguous increasing + addresses. This is true of unix sbrk. It does not hurt too much to + set it true anyway, since malloc copes with non-contiguities. + Setting it false when definitely non-contiguous saves time + and possibly wasted space it would take to discover this though. + +MORECORE_CANNOT_TRIM default: NOT defined + True if MORECORE cannot release space back to the system when given + negative arguments. This is generally necessary only if you are + using a hand-crafted MORECORE function that cannot handle negative + arguments. + +NO_SEGMENT_TRAVERSAL default: 0 + If non-zero, suppresses traversals of memory segments + returned by either MORECORE or CALL_MMAP. This disables + merging of segments that are contiguous, and selectively + releasing them to the OS if unused, but bounds execution times. + +HAVE_MMAP default: 1 (true) + True if this system supports mmap or an emulation of it. If so, and + HAVE_MORECORE is not true, MMAP is used for all system + allocation. If set and HAVE_MORECORE is true as well, MMAP is + primarily used to directly allocate very large blocks. It is also + used as a backup strategy in cases where MORECORE fails to provide + space from system. Note: A single call to MUNMAP is assumed to be + able to unmap memory that may have be allocated using multiple calls + to MMAP, so long as they are adjacent. + +HAVE_MREMAP default: 1 on linux, else 0 + If true realloc() uses mremap() to re-allocate large blocks and + extend or shrink allocation spaces. + +MMAP_CLEARS default: 1 except on WINCE. + True if mmap clears memory so calloc doesn't need to. This is true + for standard unix mmap using /dev/zero and on WIN32 except for WINCE. + +USE_BUILTIN_FFS default: 0 (i.e., not used) + Causes malloc to use the builtin ffs() function to compute indices. + Some compilers may recognize and intrinsify ffs to be faster than the + supplied C version. Also, the case of x86 using gcc is special-cased + to an asm instruction, so is already as fast as it can be, and so + this setting has no effect. Similarly for Win32 under recent MS compilers. + (On most x86s, the asm version is only slightly faster than the C version.) + +malloc_getpagesize default: derive from system includes, or 4096. + The system page size. To the extent possible, this malloc manages + memory from the system in page-size units. This may be (and + usually is) a function rather than a constant. This is ignored + if WIN32, where page size is determined using getSystemInfo during + initialization. + +USE_DEV_RANDOM default: 0 (i.e., not used) + Causes malloc to use /dev/random to initialize secure magic seed for + stamping footers. Otherwise, the current time is used. + +NO_MALLINFO default: 0 + If defined, don't compile "mallinfo". This can be a simple way + of dealing with mismatches between system declarations and + those in this file. + +MALLINFO_FIELD_TYPE default: size_t + The type of the fields in the mallinfo struct. This was originally + defined as "int" in SVID etc, but is more usefully defined as + size_t. The value is used only if HAVE_USR_INCLUDE_MALLOC_H is not set + +NO_MALLOC_STATS default: 0 + If defined, don't compile "malloc_stats". This avoids calls to + fprintf and bringing in stdio dependencies you might not want. + +REALLOC_ZERO_BYTES_FREES default: not defined + This should be set if a call to realloc with zero bytes should + be the same as a call to free. Some people think it should. Otherwise, + since this malloc returns a unique pointer for malloc(0), so does + realloc(p, 0). + +LACKS_UNISTD_H, LACKS_FCNTL_H, LACKS_SYS_PARAM_H, LACKS_SYS_MMAN_H +LACKS_STRINGS_H, LACKS_STRING_H, LACKS_SYS_TYPES_H, LACKS_ERRNO_H +LACKS_STDLIB_H LACKS_SCHED_H LACKS_TIME_H default: NOT defined unless on WIN32 + Define these if your system does not have these header files. + You might need to manually insert some of the declarations they provide. + +DEFAULT_GRANULARITY default: page size if MORECORE_CONTIGUOUS, + system_info.dwAllocationGranularity in WIN32, + otherwise 64K. + Also settable using mallopt(M_GRANULARITY, x) + The unit for allocating and deallocating memory from the system. On + most systems with contiguous MORECORE, there is no reason to + make this more than a page. However, systems with MMAP tend to + either require or encourage larger granularities. You can increase + this value to prevent system allocation functions to be called so + often, especially if they are slow. The value must be at least one + page and must be a power of two. Setting to 0 causes initialization + to either page size or win32 region size. (Note: In previous + versions of malloc, the equivalent of this option was called + "TOP_PAD") + +DEFAULT_TRIM_THRESHOLD default: 2MB + Also settable using mallopt(M_TRIM_THRESHOLD, x) + The maximum amount of unused top-most memory to keep before + releasing via malloc_trim in free(). Automatic trimming is mainly + useful in long-lived programs using contiguous MORECORE. Because + trimming via sbrk can be slow on some systems, and can sometimes be + wasteful (in cases where programs immediately afterward allocate + more large chunks) the value should be high enough so that your + overall system performance would improve by releasing this much + memory. As a rough guide, you might set to a value close to the + average size of a process (program) running on your system. + Releasing this much memory would allow such a process to run in + memory. Generally, it is worth tuning trim thresholds when a + program undergoes phases where several large chunks are allocated + and released in ways that can reuse each other's storage, perhaps + mixed with phases where there are no such chunks at all. The trim + value must be greater than page size to have any useful effect. To + disable trimming completely, you can set to MAX_SIZE_T. Note that the trick + some people use of mallocing a huge space and then freeing it at + program startup, in an attempt to reserve system memory, doesn't + have the intended effect under automatic trimming, since that memory + will immediately be returned to the system. + +DEFAULT_MMAP_THRESHOLD default: 256K + Also settable using mallopt(M_MMAP_THRESHOLD, x) + The request size threshold for using MMAP to directly service a + request. Requests of at least this size that cannot be allocated + using already-existing space will be serviced via mmap. (If enough + normal freed space already exists it is used instead.) Using mmap + segregates relatively large chunks of memory so that they can be + individually obtained and released from the host system. A request + serviced through mmap is never reused by any other request (at least + not directly; the system may just so happen to remap successive + requests to the same locations). Segregating space in this way has + the benefits that: Mmapped space can always be individually released + back to the system, which helps keep the system level memory demands + of a long-lived program low. Also, mapped memory doesn't become + `locked' between other chunks, as can happen with normally allocated + chunks, which means that even trimming via malloc_trim would not + release them. However, it has the disadvantage that the space + cannot be reclaimed, consolidated, and then used to service later + requests, as happens with normal chunks. The advantages of mmap + nearly always outweigh disadvantages for "large" chunks, but the + value of "large" may vary across systems. The default is an + empirically derived value that works well in most systems. You can + disable mmap by setting to MAX_SIZE_T. + +MAX_RELEASE_CHECK_RATE default: 4095 unless not HAVE_MMAP + The number of consolidated frees between checks to release + unused segments when freeing. When using non-contiguous segments, + especially with multiple mspaces, checking only for topmost space + doesn't always suffice to trigger trimming. To compensate for this, + free() will, with a period of MAX_RELEASE_CHECK_RATE (or the + current number of segments, if greater) try to release unused + segments to the OS when freeing chunks that result in + consolidation. The best value for this parameter is a compromise + between slowing down frees with relatively costly checks that + rarely trigger versus holding on to unused memory. To effectively + disable, set to MAX_SIZE_T. This may lead to a very slight speed + improvement at the expense of carrying around more memory. +*/ + +//---------------------------------------------------------------------------- +#if defined(AMIGA) +//#warning AMIGA + +#include + +#if defined(__SASC) +#include +#endif //__SASC + +#include "debug.h" + +#define LACKS_SYS_PARAM_H 1 +#define NEED_GLOBAL_LOCK_INIT 1 +#define USE_LOCKS 1 +#define USE_DL_PREFIX 1 +#define HAVE_MORECORE 0 +#define HAVE_MMAP 1 +#define MMAP_CLEARS 0 +#define SPIN_LOCKS_AVAILABLE 0 +#define LACKS_SCHED_H 1 +#define LACKS_SYS_MMAN_H 1 + +#define MUNMAP_DEFAULT(a, s) (FreeVec((a)), 0) +#define MMAP_DEFAULT(s) AllocVec((s), MEMF_PUBLIC) +#define DIRECT_MMAP_DEFAULT(s) AllocVec((s), MEMF_PUBLIC) + +#define MLOCK_T struct SignalSemaphore +#define CURRENT_THREAD FindTask(NULL) +#define INITIAL_LOCK(sl) (InitSemaphore(sl), 0) +#define ACQUIRE_LOCK(sl) (ObtainSemaphore(sl), 0) +#define RELEASE_LOCK(sl) (ReleaseSemaphore(sl), 0) +#define TRY_LOCK(sl) (!AttemptSemaphore(sl)) + +#if !defined(__SASC) +#define assert(x) if (!(x)) kprintf("%s/%s/%ld: assert(%s) failed.\n", __FILE__, __FUNCTION__, __LINE__, x); +#endif //__SASC + +static MLOCK_T malloc_global_mutex; +static volatile long malloc_global_mutex_status = 0; + +static void init_malloc_global_mutex(void); + +static void init_malloc_global_mutex(void) +{ + Forbid(); + while (1) + { + long stat = malloc_global_mutex_status; + if (stat > 0) + break; + InitSemaphore(&malloc_global_mutex); + malloc_global_mutex_status++; + } + Permit(); +} + +#endif //AMIGA +//---------------------------------------------------------------------------- + +/* Version identifier to allow people to support multiple versions */ +#ifndef DLMALLOC_VERSION +#define DLMALLOC_VERSION 20805 +#endif /* DLMALLOC_VERSION */ + +#ifndef DLMALLOC_EXPORT +#define DLMALLOC_EXPORT extern +#endif + +#ifndef WIN32 +#ifdef _WIN32 +#define WIN32 1 +#endif /* _WIN32 */ +#ifdef _WIN32_WCE +#define LACKS_FCNTL_H +#define WIN32 1 +#endif /* _WIN32_WCE */ +#endif /* WIN32 */ +#ifdef WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#include +#define HAVE_MMAP 1 +#define HAVE_MORECORE 0 +#define LACKS_UNISTD_H +#define LACKS_SYS_PARAM_H +#define LACKS_SYS_MMAN_H +#define LACKS_STRING_H +#define LACKS_STRINGS_H +#define LACKS_SYS_TYPES_H +#define LACKS_ERRNO_H +#define LACKS_SCHED_H +#ifndef MALLOC_FAILURE_ACTION +#define MALLOC_FAILURE_ACTION +#endif /* MALLOC_FAILURE_ACTION */ +#ifndef MMAP_CLEARS +#ifdef _WIN32_WCE /* WINCE reportedly does not clear */ +#define MMAP_CLEARS 0 +#else +#define MMAP_CLEARS 1 +#endif /* _WIN32_WCE */ +#endif /*MMAP_CLEARS */ +#endif /* WIN32 */ + +#if defined(DARWIN) || defined(_DARWIN) +/* Mac OSX docs advise not to use sbrk; it seems better to use mmap */ +#ifndef HAVE_MORECORE +#define HAVE_MORECORE 0 +#define HAVE_MMAP 1 +/* OSX allocators provide 16 byte alignment */ +#ifndef MALLOC_ALIGNMENT +#define MALLOC_ALIGNMENT ((size_t)16U) +#endif +#endif /* HAVE_MORECORE */ +#endif /* DARWIN */ + +#ifndef LACKS_SYS_TYPES_H +#include /* For size_t */ +#endif /* LACKS_SYS_TYPES_H */ + +/* The maximum possible size_t value has all bits set */ +#define MAX_SIZE_T (~(size_t)0) + +#ifndef USE_LOCKS /* ensure true if spin or recursive locks set */ +#define USE_LOCKS ((defined(USE_SPIN_LOCKS) && USE_SPIN_LOCKS != 0) || \ + (defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0)) +#endif /* USE_LOCKS */ + +#if USE_LOCKS /* Spin locks for gcc >= 4.1, older gcc on x86, MSC >= 1310 */ +#if ((defined(__GNUC__) && \ + ((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) || \ + defined(__i386__) || defined(__x86_64__))) || \ + (defined(_MSC_VER) && _MSC_VER>=1310)) +#ifndef USE_SPIN_LOCKS +#define USE_SPIN_LOCKS 1 +#endif /* USE_SPIN_LOCKS */ +#elif USE_SPIN_LOCKS +#error "USE_SPIN_LOCKS defined without implementation" +#endif /* ... locks available... */ +#elif !defined(USE_SPIN_LOCKS) +#define USE_SPIN_LOCKS 0 +#endif /* USE_LOCKS */ + +#ifndef ONLY_MSPACES +#define ONLY_MSPACES 0 +#endif /* ONLY_MSPACES */ +#ifndef MSPACES +#if ONLY_MSPACES +#define MSPACES 1 +#else /* ONLY_MSPACES */ +#define MSPACES 0 +#endif /* ONLY_MSPACES */ +#endif /* MSPACES */ +#ifndef MALLOC_ALIGNMENT +#define MALLOC_ALIGNMENT ((size_t)8U) +#endif /* MALLOC_ALIGNMENT */ +#ifndef FOOTERS +#define FOOTERS 0 +#endif /* FOOTERS */ +#ifndef ABORT +#define ABORT abort() +#endif /* ABORT */ +#ifndef ABORT_ON_ASSERT_FAILURE +#define ABORT_ON_ASSERT_FAILURE 1 +#endif /* ABORT_ON_ASSERT_FAILURE */ +#ifndef PROCEED_ON_ERROR +#define PROCEED_ON_ERROR 0 +#endif /* PROCEED_ON_ERROR */ + +#ifndef INSECURE +#define INSECURE 0 +#endif /* INSECURE */ +#ifndef MALLOC_INSPECT_ALL +#define MALLOC_INSPECT_ALL 0 +#endif /* MALLOC_INSPECT_ALL */ +#ifndef HAVE_MMAP +#define HAVE_MMAP 1 +#endif /* HAVE_MMAP */ +#ifndef MMAP_CLEARS +#define MMAP_CLEARS 1 +#endif /* MMAP_CLEARS */ +#ifndef HAVE_MREMAP +#ifdef linux +#define HAVE_MREMAP 1 +#define _GNU_SOURCE /* Turns on mremap() definition */ +#else /* linux */ +#define HAVE_MREMAP 0 +#endif /* linux */ +#endif /* HAVE_MREMAP */ +#ifndef MALLOC_FAILURE_ACTION +#define MALLOC_FAILURE_ACTION errno = ENOMEM; +#endif /* MALLOC_FAILURE_ACTION */ +#ifndef HAVE_MORECORE +#if ONLY_MSPACES +#define HAVE_MORECORE 0 +#else /* ONLY_MSPACES */ +#define HAVE_MORECORE 1 +#endif /* ONLY_MSPACES */ +#endif /* HAVE_MORECORE */ +#if !HAVE_MORECORE +#define MORECORE_CONTIGUOUS 0 +#else /* !HAVE_MORECORE */ +#define MORECORE_DEFAULT sbrk +#ifndef MORECORE_CONTIGUOUS +#define MORECORE_CONTIGUOUS 1 +#endif /* MORECORE_CONTIGUOUS */ +#endif /* HAVE_MORECORE */ +#ifndef DEFAULT_GRANULARITY +#if (MORECORE_CONTIGUOUS || defined(WIN32)) +#define DEFAULT_GRANULARITY (0) /* 0 means to compute in init_mparams */ +#else /* MORECORE_CONTIGUOUS */ +#define DEFAULT_GRANULARITY ((size_t)64U * (size_t)1024U) +#endif /* MORECORE_CONTIGUOUS */ +#endif /* DEFAULT_GRANULARITY */ +#ifndef DEFAULT_TRIM_THRESHOLD +#ifndef MORECORE_CANNOT_TRIM +#define DEFAULT_TRIM_THRESHOLD ((size_t)2U * (size_t)1024U * (size_t)1024U) +#else /* MORECORE_CANNOT_TRIM */ +#define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T +#endif /* MORECORE_CANNOT_TRIM */ +#endif /* DEFAULT_TRIM_THRESHOLD */ +#ifndef DEFAULT_MMAP_THRESHOLD +#if HAVE_MMAP +#define DEFAULT_MMAP_THRESHOLD ((size_t)256U * (size_t)1024U) +#else /* HAVE_MMAP */ +#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T +#endif /* HAVE_MMAP */ +#endif /* DEFAULT_MMAP_THRESHOLD */ +#ifndef MAX_RELEASE_CHECK_RATE +#if HAVE_MMAP +#define MAX_RELEASE_CHECK_RATE 4095 +#else +#define MAX_RELEASE_CHECK_RATE MAX_SIZE_T +#endif /* HAVE_MMAP */ +#endif /* MAX_RELEASE_CHECK_RATE */ +#ifndef USE_BUILTIN_FFS +#define USE_BUILTIN_FFS 0 +#endif /* USE_BUILTIN_FFS */ +#ifndef USE_DEV_RANDOM +#define USE_DEV_RANDOM 0 +#endif /* USE_DEV_RANDOM */ +#ifndef NO_MALLINFO +#define NO_MALLINFO 0 +#endif /* NO_MALLINFO */ +#ifndef MALLINFO_FIELD_TYPE +#define MALLINFO_FIELD_TYPE size_t +#endif /* MALLINFO_FIELD_TYPE */ +#ifndef NO_MALLOC_STATS +#define NO_MALLOC_STATS 0 +#endif /* NO_MALLOC_STATS */ +#ifndef NO_SEGMENT_TRAVERSAL +#define NO_SEGMENT_TRAVERSAL 0 +#endif /* NO_SEGMENT_TRAVERSAL */ + +/* + mallopt tuning options. SVID/XPG defines four standard parameter + numbers for mallopt, normally defined in malloc.h. None of these + are used in this malloc, so setting them has no effect. But this + malloc does support the following options. +*/ + +#define M_TRIM_THRESHOLD (-1) +#define M_GRANULARITY (-2) +#define M_MMAP_THRESHOLD (-3) + +/* ------------------------ Mallinfo declarations ------------------------ */ + +#if !NO_MALLINFO +/* + This version of malloc supports the standard SVID/XPG mallinfo + routine that returns a struct containing usage properties and + statistics. It should work on any system that has a + /usr/include/malloc.h defining struct mallinfo. The main + declaration needed is the mallinfo struct that is returned (by-copy) + by mallinfo(). The malloinfo struct contains a bunch of fields that + are not even meaningful in this version of malloc. These fields are + are instead filled by mallinfo() with other numbers that might be of + interest. + + HAVE_USR_INCLUDE_MALLOC_H should be set if you have a + /usr/include/malloc.h file that includes a declaration of struct + mallinfo. If so, it is included; else a compliant version is + declared below. These must be precisely the same for mallinfo() to + work. The original SVID version of this struct, defined on most + systems with mallinfo, declares all fields as ints. But some others + define as unsigned long. If your system defines the fields using a + type of different width than listed here, you MUST #include your + system version and #define HAVE_USR_INCLUDE_MALLOC_H. +*/ + +/* #define HAVE_USR_INCLUDE_MALLOC_H */ + +#ifdef HAVE_USR_INCLUDE_MALLOC_H +#include "/usr/include/malloc.h" +#else /* HAVE_USR_INCLUDE_MALLOC_H */ +#ifndef STRUCT_MALLINFO_DECLARED +/* HP-UX (and others?) redefines mallinfo unless _STRUCT_MALLINFO is defined */ +#define _STRUCT_MALLINFO +#define STRUCT_MALLINFO_DECLARED 1 +struct mallinfo { + MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */ + MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */ + MALLINFO_FIELD_TYPE smblks; /* always 0 */ + MALLINFO_FIELD_TYPE hblks; /* always 0 */ + MALLINFO_FIELD_TYPE hblkhd; /* space in mmapped regions */ + MALLINFO_FIELD_TYPE usmblks; /* maximum total allocated space */ + MALLINFO_FIELD_TYPE fsmblks; /* always 0 */ + MALLINFO_FIELD_TYPE uordblks; /* total allocated space */ + MALLINFO_FIELD_TYPE fordblks; /* total free space */ + MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */ +}; +#endif /* STRUCT_MALLINFO_DECLARED */ +#endif /* HAVE_USR_INCLUDE_MALLOC_H */ +#endif /* NO_MALLINFO */ + +/* + Try to persuade compilers to inline. The most critical functions for + inlining are defined as macros, so these aren't used for them. +*/ + +#ifndef FORCEINLINE + #if defined(__GNUC__) +#define FORCEINLINE __inline __attribute__ ((always_inline)) + #elif defined(_MSC_VER) + #define FORCEINLINE __forceinline + #endif +#endif +#ifndef NOINLINE + #if defined(__GNUC__) + #define NOINLINE __attribute__ ((noinline)) + #elif defined(_MSC_VER) + #define NOINLINE __declspec(noinline) + #else + #define NOINLINE + #endif +#endif + +#ifdef __cplusplus +extern "C" { +#ifndef FORCEINLINE + #define FORCEINLINE inline +#endif +#endif /* __cplusplus */ +#ifndef FORCEINLINE + #define FORCEINLINE +#endif + +#if !ONLY_MSPACES + +/* ------------------- Declarations of public routines ------------------- */ + +#ifndef USE_DL_PREFIX +#define dlcalloc calloc +#define dlfree free +#define dlmalloc malloc +#define dlmemalign memalign +#define dlposix_memalign posix_memalign +#define dlrealloc realloc +#define dlrealloc_in_place realloc_in_place +#define dlvalloc valloc +#define dlpvalloc pvalloc +#define dlmallinfo mallinfo +#define dlmallopt mallopt +#define dlmalloc_trim malloc_trim +#define dlmalloc_stats malloc_stats +#define dlmalloc_usable_size malloc_usable_size +#define dlmalloc_footprint malloc_footprint +#define dlmalloc_max_footprint malloc_max_footprint +#define dlmalloc_footprint_limit malloc_footprint_limit +#define dlmalloc_set_footprint_limit malloc_set_footprint_limit +#define dlmalloc_inspect_all malloc_inspect_all +#define dlindependent_calloc independent_calloc +#define dlindependent_comalloc independent_comalloc +#define dlbulk_free bulk_free +#endif /* USE_DL_PREFIX */ + +/* + malloc(size_t n) + Returns a pointer to a newly allocated chunk of at least n bytes, or + null if no space is available, in which case errno is set to ENOMEM + on ANSI C systems. + + If n is zero, malloc returns a minimum-sized chunk. (The minimum + size is 16 bytes on most 32bit systems, and 32 bytes on 64bit + systems.) Note that size_t is an unsigned type, so calls with + arguments that would be negative if signed are interpreted as + requests for huge amounts of space, which will often fail. The + maximum supported value of n differs across systems, but is in all + cases less than the maximum representable value of a size_t. +*/ +DLMALLOC_EXPORT void* dlmalloc(size_t); + +/* + free(void* p) + Releases the chunk of memory pointed to by p, that had been previously + allocated using malloc or a related routine such as realloc. + It has no effect if p is null. If p was not malloced or already + freed, free(p) will by default cause the current program to abort. +*/ +DLMALLOC_EXPORT void dlfree(void*); + +/* + calloc(size_t n_elements, size_t element_size); + Returns a pointer to n_elements * element_size bytes, with all locations + set to zero. +*/ +DLMALLOC_EXPORT void* dlcalloc(size_t, size_t); + +/* + realloc(void* p, size_t n) + Returns a pointer to a chunk of size n that contains the same data + as does chunk p up to the minimum of (n, p's size) bytes, or null + if no space is available. + + The returned pointer may or may not be the same as p. The algorithm + prefers extending p in most cases when possible, otherwise it + employs the equivalent of a malloc-copy-free sequence. + + If p is null, realloc is equivalent to malloc. + + If space is not available, realloc returns null, errno is set (if on + ANSI) and p is NOT freed. + + if n is for fewer bytes than already held by p, the newly unused + space is lopped off and freed if possible. realloc with a size + argument of zero (re)allocates a minimum-sized chunk. + + The old unix realloc convention of allowing the last-free'd chunk + to be used as an argument to realloc is not supported. +*/ +DLMALLOC_EXPORT void* dlrealloc(void*, size_t); + +/* + realloc_in_place(void* p, size_t n) + Resizes the space allocated for p to size n, only if this can be + done without moving p (i.e., only if there is adjacent space + available if n is greater than p's current allocated size, or n is + less than or equal to p's size). This may be used instead of plain + realloc if an alternative allocation strategy is needed upon failure + to expand space; for example, reallocation of a buffer that must be + memory-aligned or cleared. You can use realloc_in_place to trigger + these alternatives only when needed. + + Returns p if successful; otherwise null. +*/ +DLMALLOC_EXPORT void* dlrealloc_in_place(void*, size_t); + +/* + memalign(size_t alignment, size_t n); + Returns a pointer to a newly allocated chunk of n bytes, aligned + in accord with the alignment argument. + + The alignment argument should be a power of two. If the argument is + not a power of two, the nearest greater power is used. + 8-byte alignment is guaranteed by normal malloc calls, so don't + bother calling memalign with an argument of 8 or less. + + Overreliance on memalign is a sure way to fragment space. +*/ +DLMALLOC_EXPORT void* dlmemalign(size_t, size_t); + +/* + int posix_memalign(void** pp, size_t alignment, size_t n); + Allocates a chunk of n bytes, aligned in accord with the alignment + argument. Differs from memalign only in that it (1) assigns the + allocated memory to *pp rather than returning it, (2) fails and + returns EINVAL if the alignment is not a power of two (3) fails and + returns ENOMEM if memory cannot be allocated. +*/ +DLMALLOC_EXPORT int dlposix_memalign(void**, size_t, size_t); + +/* + valloc(size_t n); + Equivalent to memalign(pagesize, n), where pagesize is the page + size of the system. If the pagesize is unknown, 4096 is used. +*/ +DLMALLOC_EXPORT void* dlvalloc(size_t); + +/* + mallopt(int parameter_number, int parameter_value) + Sets tunable parameters The format is to provide a + (parameter-number, parameter-value) pair. mallopt then sets the + corresponding parameter to the argument value if it can (i.e., so + long as the value is meaningful), and returns 1 if successful else + 0. To workaround the fact that mallopt is specified to use int, + not size_t parameters, the value -1 is specially treated as the + maximum unsigned size_t value. + + SVID/XPG/ANSI defines four standard param numbers for mallopt, + normally defined in malloc.h. None of these are use in this malloc, + so setting them has no effect. But this malloc also supports other + options in mallopt. See below for details. Briefly, supported + parameters are as follows (listed defaults are for "typical" + configurations). + + Symbol param # default allowed param values + M_TRIM_THRESHOLD -1 2*1024*1024 any (-1 disables) + M_GRANULARITY -2 page size any power of 2 >= page size + M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support) +*/ +DLMALLOC_EXPORT int dlmallopt(int, int); + +/* + malloc_footprint(); + Returns the number of bytes obtained from the system. The total + number of bytes allocated by malloc, realloc etc., is less than this + value. Unlike mallinfo, this function returns only a precomputed + result, so can be called frequently to monitor memory consumption. + Even if locks are otherwise defined, this function does not use them, + so results might not be up to date. +*/ +DLMALLOC_EXPORT size_t dlmalloc_footprint(void); + +/* + malloc_max_footprint(); + Returns the maximum number of bytes obtained from the system. This + value will be greater than current footprint if deallocated space + has been reclaimed by the system. The peak number of bytes allocated + by malloc, realloc etc., is less than this value. Unlike mallinfo, + this function returns only a precomputed result, so can be called + frequently to monitor memory consumption. Even if locks are + otherwise defined, this function does not use them, so results might + not be up to date. +*/ +DLMALLOC_EXPORT size_t dlmalloc_max_footprint(void); + +/* + malloc_footprint_limit(); + Returns the number of bytes that the heap is allowed to obtain from + the system, returning the last value returned by + malloc_set_footprint_limit, or the maximum size_t value if + never set. The returned value reflects a permission. There is no + guarantee that this number of bytes can actually be obtained from + the system. +*/ +DLMALLOC_EXPORT size_t dlmalloc_footprint_limit(); + +/* + malloc_set_footprint_limit(); + Sets the maximum number of bytes to obtain from the system, causing + failure returns from malloc and related functions upon attempts to + exceed this value. The argument value may be subject to page + rounding to an enforceable limit; this actual value is returned. + Using an argument of the maximum possible size_t effectively + disables checks. If the argument is less than or equal to the + current malloc_footprint, then all future allocations that require + additional system memory will fail. However, invocation cannot + retroactively deallocate existing used memory. +*/ +DLMALLOC_EXPORT size_t dlmalloc_set_footprint_limit(size_t bytes); + +#if MALLOC_INSPECT_ALL +/* + malloc_inspect_all(void(*handler)(void *start, + void *end, + size_t used_bytes, + void* callback_arg), + void* arg); + Traverses the heap and calls the given handler for each managed + region, skipping all bytes that are (or may be) used for bookkeeping + purposes. Traversal does not include include chunks that have been + directly memory mapped. Each reported region begins at the start + address, and continues up to but not including the end address. The + first used_bytes of the region contain allocated data. If + used_bytes is zero, the region is unallocated. The handler is + invoked with the given callback argument. If locks are defined, they + are held during the entire traversal. It is a bad idea to invoke + other malloc functions from within the handler. + + For example, to count the number of in-use chunks with size greater + than 1000, you could write: + static int count = 0; + void count_chunks(void* start, void* end, size_t used, void* arg) { + if (used >= 1000) ++count; + } + then: + malloc_inspect_all(count_chunks, NULL); + + malloc_inspect_all is compiled only if MALLOC_INSPECT_ALL is defined. +*/ +DLMALLOC_EXPORT void dlmalloc_inspect_all(void(*handler)(void*, void *, size_t, void*), + void* arg); + +#endif /* MALLOC_INSPECT_ALL */ + +#if !NO_MALLINFO +/* + mallinfo() + Returns (by copy) a struct containing various summary statistics: + + arena: current total non-mmapped bytes allocated from system + ordblks: the number of free chunks + smblks: always zero. + hblks: current number of mmapped regions + hblkhd: total bytes held in mmapped regions + usmblks: the maximum total allocated space. This will be greater + than current total if trimming has occurred. + fsmblks: always zero + uordblks: current total allocated space (normal or mmapped) + fordblks: total free space + keepcost: the maximum number of bytes that could ideally be released + back to system via malloc_trim. ("ideally" means that + it ignores page restrictions etc.) + + Because these fields are ints, but internal bookkeeping may + be kept as longs, the reported values may wrap around zero and + thus be inaccurate. +*/ +DLMALLOC_EXPORT struct mallinfo dlmallinfo(void); +#endif /* NO_MALLINFO */ + +/* + independent_calloc(size_t n_elements, size_t element_size, void* chunks[]); + + independent_calloc is similar to calloc, but instead of returning a + single cleared space, it returns an array of pointers to n_elements + independent elements that can hold contents of size elem_size, each + of which starts out cleared, and can be independently freed, + realloc'ed etc. The elements are guaranteed to be adjacently + allocated (this is not guaranteed to occur with multiple callocs or + mallocs), which may also improve cache locality in some + applications. + + The "chunks" argument is optional (i.e., may be null, which is + probably the most typical usage). If it is null, the returned array + is itself dynamically allocated and should also be freed when it is + no longer needed. Otherwise, the chunks array must be of at least + n_elements in length. It is filled in with the pointers to the + chunks. + + In either case, independent_calloc returns this pointer array, or + null if the allocation failed. If n_elements is zero and "chunks" + is null, it returns a chunk representing an array with zero elements + (which should be freed if not wanted). + + Each element must be freed when it is no longer needed. This can be + done all at once using bulk_free. + + independent_calloc simplifies and speeds up implementations of many + kinds of pools. It may also be useful when constructing large data + structures that initially have a fixed number of fixed-sized nodes, + but the number is not known at compile time, and some of the nodes + may later need to be freed. For example: + + struct Node { int item; struct Node* next; }; + + struct Node* build_list() { + struct Node** pool; + int n = read_number_of_nodes_needed(); + if (n <= 0) return 0; + pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0); + if (pool == 0) die(); + // organize into a linked list... + struct Node* first = pool[0]; + for (i = 0; i < n-1; ++i) + pool[i]->next = pool[i+1]; + free(pool); // Can now free the array (or not, if it is needed later) + return first; + } +*/ +DLMALLOC_EXPORT void** dlindependent_calloc(size_t, size_t, void**); + +/* + independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]); + + independent_comalloc allocates, all at once, a set of n_elements + chunks with sizes indicated in the "sizes" array. It returns + an array of pointers to these elements, each of which can be + independently freed, realloc'ed etc. The elements are guaranteed to + be adjacently allocated (this is not guaranteed to occur with + multiple callocs or mallocs), which may also improve cache locality + in some applications. + + The "chunks" argument is optional (i.e., may be null). If it is null + the returned array is itself dynamically allocated and should also + be freed when it is no longer needed. Otherwise, the chunks array + must be of at least n_elements in length. It is filled in with the + pointers to the chunks. + + In either case, independent_comalloc returns this pointer array, or + null if the allocation failed. If n_elements is zero and chunks is + null, it returns a chunk representing an array with zero elements + (which should be freed if not wanted). + + Each element must be freed when it is no longer needed. This can be + done all at once using bulk_free. + + independent_comallac differs from independent_calloc in that each + element may have a different size, and also that it does not + automatically clear elements. + + independent_comalloc can be used to speed up allocation in cases + where several structs or objects must always be allocated at the + same time. For example: + + struct Head { ... } + struct Foot { ... } + + void send_message(char* msg) { + int msglen = strlen(msg); + size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) }; + void* chunks[3]; + if (independent_comalloc(3, sizes, chunks) == 0) + die(); + struct Head* head = (struct Head*)(chunks[0]); + char* body = (char*)(chunks[1]); + struct Foot* foot = (struct Foot*)(chunks[2]); + // ... + } + + In general though, independent_comalloc is worth using only for + larger values of n_elements. For small values, you probably won't + detect enough difference from series of malloc calls to bother. + + Overuse of independent_comalloc can increase overall memory usage, + since it cannot reuse existing noncontiguous small chunks that + might be available for some of the elements. +*/ +DLMALLOC_EXPORT void** dlindependent_comalloc(size_t, size_t*, void**); + +/* + bulk_free(void* array[], size_t n_elements) + Frees and clears (sets to null) each non-null pointer in the given + array. This is likely to be faster than freeing them one-by-one. + If footers are used, pointers that have been allocated in different + mspaces are not freed or cleared, and the count of all such pointers + is returned. For large arrays of pointers with poor locality, it + may be worthwhile to sort this array before calling bulk_free. +*/ +DLMALLOC_EXPORT size_t dlbulk_free(void**, size_t n_elements); + +/* + pvalloc(size_t n); + Equivalent to valloc(minimum-page-that-holds(n)), that is, + round up n to nearest pagesize. + */ +DLMALLOC_EXPORT void* dlpvalloc(size_t); + +/* + malloc_trim(size_t pad); + + If possible, gives memory back to the system (via negative arguments + to sbrk) if there is unused memory at the `high' end of the malloc + pool or in unused MMAP segments. You can call this after freeing + large blocks of memory to potentially reduce the system-level memory + requirements of a program. However, it cannot guarantee to reduce + memory. Under some allocation patterns, some large free blocks of + memory will be locked between two used chunks, so they cannot be + given back to the system. + + The `pad' argument to malloc_trim represents the amount of free + trailing space to leave untrimmed. If this argument is zero, only + the minimum amount of memory to maintain internal data structures + will be left. Non-zero arguments can be supplied to maintain enough + trailing space to service future expected allocations without having + to re-obtain memory from the system. + + Malloc_trim returns 1 if it actually released any memory, else 0. +*/ +DLMALLOC_EXPORT int dlmalloc_trim(size_t); + +/* + malloc_stats(); + Prints on stderr the amount of space obtained from the system (both + via sbrk and mmap), the maximum amount (which may be more than + current if malloc_trim and/or munmap got called), and the current + number of bytes allocated via malloc (or realloc, etc) but not yet + freed. Note that this is the number of bytes allocated, not the + number requested. It will be larger than the number requested + because of alignment and bookkeeping overhead. Because it includes + alignment wastage as being in use, this figure may be greater than + zero even when no user-level chunks are allocated. + + The reported current and maximum system memory can be inaccurate if + a program makes other calls to system memory allocation functions + (normally sbrk) outside of malloc. + + malloc_stats prints only the most commonly interesting statistics. + More information can be obtained by calling mallinfo. +*/ +DLMALLOC_EXPORT void dlmalloc_stats(void); + +#endif /* ONLY_MSPACES */ + +/* + malloc_usable_size(void* p); + + Returns the number of bytes you can actually use in + an allocated chunk, which may be more than you requested (although + often not) due to alignment and minimum size constraints. + You can use this many bytes without worrying about + overwriting other allocated objects. This is not a particularly great + programming practice. malloc_usable_size can be more useful in + debugging and assertions, for example: + + p = malloc(n); + assert(malloc_usable_size(p) >= 256); +*/ +size_t dlmalloc_usable_size(void*); + +#if MSPACES + +/* + mspace is an opaque type representing an independent + region of space that supports mspace_malloc, etc. +*/ +typedef void* mspace; + +/* + create_mspace creates and returns a new independent space with the + given initial capacity, or, if 0, the default granularity size. It + returns null if there is no system memory available to create the + space. If argument locked is non-zero, the space uses a separate + lock to control access. The capacity of the space will grow + dynamically as needed to service mspace_malloc requests. You can + control the sizes of incremental increases of this space by + compiling with a different DEFAULT_GRANULARITY or dynamically + setting with mallopt(M_GRANULARITY, value). +*/ +DLMALLOC_EXPORT mspace create_mspace(size_t capacity, int locked); + +/* + destroy_mspace destroys the given space, and attempts to return all + of its memory back to the system, returning the total number of + bytes freed. After destruction, the results of access to all memory + used by the space become undefined. +*/ +DLMALLOC_EXPORT size_t destroy_mspace(mspace msp); + +/* + create_mspace_with_base uses the memory supplied as the initial base + of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this + space is used for bookkeeping, so the capacity must be at least this + large. (Otherwise 0 is returned.) When this initial space is + exhausted, additional memory will be obtained from the system. + Destroying this space will deallocate all additionally allocated + space (if possible) but not the initial base. +*/ +DLMALLOC_EXPORT mspace create_mspace_with_base(void* base, size_t capacity, int locked); + +/* + mspace_track_large_chunks controls whether requests for large chunks + are allocated in their own untracked mmapped regions, separate from + others in this mspace. By default large chunks are not tracked, + which reduces fragmentation. However, such chunks are not + necessarily released to the system upon destroy_mspace. Enabling + tracking by setting to true may increase fragmentation, but avoids + leakage when relying on destroy_mspace to release all memory + allocated using this space. The function returns the previous + setting. +*/ +DLMALLOC_EXPORT int mspace_track_large_chunks(mspace msp, int enable); + + +/* + mspace_malloc behaves as malloc, but operates within + the given space. +*/ +DLMALLOC_EXPORT void* mspace_malloc(mspace msp, size_t bytes); + +/* + mspace_free behaves as free, but operates within + the given space. + + If compiled with FOOTERS==1, mspace_free is not actually needed. + free may be called instead of mspace_free because freed chunks from + any space are handled by their originating spaces. +*/ +DLMALLOC_EXPORT void mspace_free(mspace msp, void* mem); + +/* + mspace_realloc behaves as realloc, but operates within + the given space. + + If compiled with FOOTERS==1, mspace_realloc is not actually + needed. realloc may be called instead of mspace_realloc because + realloced chunks from any space are handled by their originating + spaces. +*/ +DLMALLOC_EXPORT void* mspace_realloc(mspace msp, void* mem, size_t newsize); + +/* + mspace_calloc behaves as calloc, but operates within + the given space. +*/ +DLMALLOC_EXPORT void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size); + +/* + mspace_memalign behaves as memalign, but operates within + the given space. +*/ +DLMALLOC_EXPORT void* mspace_memalign(mspace msp, size_t alignment, size_t bytes); + +/* + mspace_independent_calloc behaves as independent_calloc, but + operates within the given space. +*/ +DLMALLOC_EXPORT void** mspace_independent_calloc(mspace msp, size_t n_elements, + size_t elem_size, void* chunks[]); + +/* + mspace_independent_comalloc behaves as independent_comalloc, but + operates within the given space. +*/ +DLMALLOC_EXPORT void** mspace_independent_comalloc(mspace msp, size_t n_elements, + size_t sizes[], void* chunks[]); + +/* + mspace_footprint() returns the number of bytes obtained from the + system for this space. +*/ +DLMALLOC_EXPORT size_t mspace_footprint(mspace msp); + +/* + mspace_max_footprint() returns the peak number of bytes obtained from the + system for this space. +*/ +DLMALLOC_EXPORT size_t mspace_max_footprint(mspace msp); + + +#if !NO_MALLINFO +/* + mspace_mallinfo behaves as mallinfo, but reports properties of + the given space. +*/ +DLMALLOC_EXPORT struct mallinfo mspace_mallinfo(mspace msp); +#endif /* NO_MALLINFO */ + +/* + malloc_usable_size(void* p) behaves the same as malloc_usable_size; +*/ +DLMALLOC_EXPORT size_t mspace_usable_size(void* mem); + +/* + mspace_malloc_stats behaves as malloc_stats, but reports + properties of the given space. +*/ +DLMALLOC_EXPORT void mspace_malloc_stats(mspace msp); + +/* + mspace_trim behaves as malloc_trim, but + operates within the given space. +*/ +DLMALLOC_EXPORT int mspace_trim(mspace msp, size_t pad); + +/* + An alias for mallopt. +*/ +DLMALLOC_EXPORT int mspace_mallopt(int, int); + +#endif /* MSPACES */ + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif /* __cplusplus */ + +/* + ======================================================================== + To make a fully customizable malloc.h header file, cut everything + above this line, put into file malloc.h, edit to suit, and #include it + on the next line, as well as in programs that use this malloc. + ======================================================================== +*/ + +/* #include "malloc.h" */ + +/*------------------------------ internal #includes ---------------------- */ + +#ifdef _MSC_VER +#pragma warning( disable : 4146 ) /* no "unsigned" warnings */ +#endif /* _MSC_VER */ +#if !NO_MALLOC_STATS +#include /* for printing in malloc_stats */ +#endif /* NO_MALLOC_STATS */ +#ifndef LACKS_ERRNO_H +#include /* for MALLOC_FAILURE_ACTION */ +#endif /* LACKS_ERRNO_H */ +#ifdef DEBUG +#if ABORT_ON_ASSERT_FAILURE +#undef assert +#define assert(x) if(!(x)) ABORT +#else /* ABORT_ON_ASSERT_FAILURE */ +#include +#endif /* ABORT_ON_ASSERT_FAILURE */ +#else /* DEBUG */ +#ifndef assert +#define assert(x) +#endif +#define DEBUG 0 +#endif /* DEBUG */ +#if !defined(WIN32) && !defined(LACKS_TIME_H) +#include /* for magic initialization */ +#endif /* WIN32 */ +#ifndef LACKS_STDLIB_H +#include /* for abort() */ +#endif /* LACKS_STDLIB_H */ +#ifndef LACKS_STRING_H +#include /* for memset etc */ +#endif /* LACKS_STRING_H */ +#if USE_BUILTIN_FFS +#ifndef LACKS_STRINGS_H +#include /* for ffs */ +#endif /* LACKS_STRINGS_H */ +#endif /* USE_BUILTIN_FFS */ +#if HAVE_MMAP +#ifndef LACKS_SYS_MMAN_H +/* On some versions of linux, mremap decl in mman.h needs __USE_GNU set */ +#if (defined(linux) && !defined(__USE_GNU)) +#define __USE_GNU 1 +#include /* for mmap */ +#undef __USE_GNU +#else +#include /* for mmap */ +#endif /* linux */ +#endif /* LACKS_SYS_MMAN_H */ +#ifndef LACKS_FCNTL_H +#include +#endif /* LACKS_FCNTL_H */ +#endif /* HAVE_MMAP */ +#ifndef LACKS_UNISTD_H +#include /* for sbrk, sysconf */ +#else /* LACKS_UNISTD_H */ +#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) +extern void* sbrk(ptrdiff_t); +#endif /* FreeBSD etc */ +#endif /* LACKS_UNISTD_H */ + +/* Declarations for locking */ +#if USE_LOCKS +#if defined(AMIGA) +#elif !defined(WIN32) +#if defined (__SVR4) && defined (__sun) /* solaris */ +#include +#elif !defined(LACKS_SCHED_H) +#include +#endif /* solaris or LACKS_SCHED_H */ +#if (defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0) || !USE_SPIN_LOCKS +#include +#endif /* USE_RECURSIVE_LOCKS ... */ +#elif defined(_MSC_VER) +#ifndef _M_AMD64 +/* These are already defined on AMD64 builds */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +LONG __cdecl _InterlockedCompareExchange(LONG volatile *Dest, LONG Exchange, LONG Comp); +LONG __cdecl _InterlockedExchange(LONG volatile *Target, LONG Value); +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _M_AMD64 */ +#pragma intrinsic (_InterlockedCompareExchange) +#pragma intrinsic (_InterlockedExchange) +#define interlockedcompareexchange _InterlockedCompareExchange +#define interlockedexchange _InterlockedExchange +#elif defined(WIN32) && defined(__GNUC__) +#define interlockedcompareexchange(a, b, c) __sync_val_compare_and_swap(a, c, b) +#define interlockedexchange __sync_lock_test_and_set +#endif /* Win32 */ +#endif /* USE_LOCKS */ + +/* Declarations for bit scanning on win32 */ +#if defined(_MSC_VER) && _MSC_VER>=1300 +#ifndef BitScanForward /* Try to avoid pulling in WinNT.h */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +unsigned char _BitScanForward(unsigned long *index, unsigned long mask); +unsigned char _BitScanReverse(unsigned long *index, unsigned long mask); +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#define BitScanForward _BitScanForward +#define BitScanReverse _BitScanReverse +#pragma intrinsic(_BitScanForward) +#pragma intrinsic(_BitScanReverse) +#endif /* BitScanForward */ +#endif /* defined(_MSC_VER) && _MSC_VER>=1300 */ + +#ifndef WIN32 +#ifndef malloc_getpagesize +# ifdef _SC_PAGESIZE /* some SVR4 systems omit an underscore */ +# ifndef _SC_PAGE_SIZE +# define _SC_PAGE_SIZE _SC_PAGESIZE +# endif +# endif +# ifdef _SC_PAGE_SIZE +# define malloc_getpagesize sysconf(_SC_PAGE_SIZE) +# else +# if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE) + extern size_t getpagesize(); +# define malloc_getpagesize getpagesize() +# else +# ifdef WIN32 /* use supplied emulation of getpagesize */ +# define malloc_getpagesize getpagesize() +# else +# ifndef LACKS_SYS_PARAM_H +# include +# endif +# ifdef EXEC_PAGESIZE +# define malloc_getpagesize EXEC_PAGESIZE +# else +# ifdef NBPG +# ifndef CLSIZE +# define malloc_getpagesize NBPG +# else +# define malloc_getpagesize (NBPG * CLSIZE) +# endif +# else +# ifdef NBPC +# define malloc_getpagesize NBPC +# else +# ifdef PAGESIZE +# define malloc_getpagesize PAGESIZE +# else /* just guess */ +# define malloc_getpagesize ((size_t)4096U) +# endif +# endif +# endif +# endif +# endif +# endif +# endif +#endif +#endif + +/* ------------------- size_t and alignment properties -------------------- */ + +/* The byte and bit size of a size_t */ +#define SIZE_T_SIZE (sizeof(size_t)) +#define SIZE_T_BITSIZE (sizeof(size_t) << 3) + +/* Some constants coerced to size_t */ +/* Annoying but necessary to avoid errors on some platforms */ +#define SIZE_T_ZERO ((size_t)0) +#define SIZE_T_ONE ((size_t)1) +#define SIZE_T_TWO ((size_t)2) +#define SIZE_T_FOUR ((size_t)4) +#define TWO_SIZE_T_SIZES (SIZE_T_SIZE<<1) +#define FOUR_SIZE_T_SIZES (SIZE_T_SIZE<<2) +#define SIX_SIZE_T_SIZES (FOUR_SIZE_T_SIZES+TWO_SIZE_T_SIZES) +#define HALF_MAX_SIZE_T (MAX_SIZE_T / 2U) + +/* The bit mask value corresponding to MALLOC_ALIGNMENT */ +#define CHUNK_ALIGN_MASK (MALLOC_ALIGNMENT - SIZE_T_ONE) + +/* True if address a has acceptable alignment */ +#define is_aligned(A) (((size_t)((A)) & (CHUNK_ALIGN_MASK)) == 0) + +/* the number of bytes to offset an address to align it */ +#define align_offset(A)\ + ((((size_t)(A) & CHUNK_ALIGN_MASK) == 0)? 0 :\ + ((MALLOC_ALIGNMENT - ((size_t)(A) & CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK)) + +/* -------------------------- MMAP preliminaries ------------------------- */ + +/* + If HAVE_MORECORE or HAVE_MMAP are false, we just define calls and + checks to fail so compiler optimizer can delete code rather than + using so many "#if"s. +*/ + + +/* MORECORE and MMAP must return MFAIL on failure */ +#define MFAIL ((void*)(MAX_SIZE_T)) +#define CMFAIL ((char*)(MFAIL)) /* defined for convenience */ + +#if HAVE_MMAP + +#if defined(AMIGA) +#elif !defined(WIN32) +#define MUNMAP_DEFAULT(a, s) munmap((a), (s)) +#define MMAP_PROT (PROT_READ|PROT_WRITE) +#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) +#define MAP_ANONYMOUS MAP_ANON +#endif /* MAP_ANON */ +#ifdef MAP_ANONYMOUS +#define MMAP_FLAGS (MAP_PRIVATE|MAP_ANONYMOUS) +#define MMAP_DEFAULT(s) mmap(0, (s), MMAP_PROT, MMAP_FLAGS, -1, 0) +#else /* MAP_ANONYMOUS */ +/* + Nearly all versions of mmap support MAP_ANONYMOUS, so the following + is unlikely to be needed, but is supplied just in case. +*/ +#define MMAP_FLAGS (MAP_PRIVATE) +static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */ +#define MMAP_DEFAULT(s) ((dev_zero_fd < 0) ? \ + (dev_zero_fd = open("/dev/zero", O_RDWR), \ + mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) : \ + mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) +#endif /* MAP_ANONYMOUS */ + +#define DIRECT_MMAP_DEFAULT(s) MMAP_DEFAULT(s) + +#else /* WIN32 */ + +/* Win32 MMAP via VirtualAlloc */ +static FORCEINLINE void* win32mmap(size_t size) { + void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); + return (ptr != 0)? ptr: MFAIL; +} + +/* For direct MMAP, use MEM_TOP_DOWN to minimize interference */ +static FORCEINLINE void* win32direct_mmap(size_t size) { + void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, + PAGE_READWRITE); + return (ptr != 0)? ptr: MFAIL; +} + +/* This function supports releasing coalesed segments */ +static FORCEINLINE int win32munmap(void* ptr, size_t size) { + MEMORY_BASIC_INFORMATION minfo; + char* cptr = (char*)ptr; + while (size) { + if (VirtualQuery(cptr, &minfo, sizeof(minfo)) == 0) + return -1; + if (minfo.BaseAddress != cptr || minfo.AllocationBase != cptr || + minfo.State != MEM_COMMIT || minfo.RegionSize > size) + return -1; + if (VirtualFree(cptr, 0, MEM_RELEASE) == 0) + return -1; + cptr += minfo.RegionSize; + size -= minfo.RegionSize; + } + return 0; +} + +#define MMAP_DEFAULT(s) win32mmap(s) +#define MUNMAP_DEFAULT(a, s) win32munmap((a), (s)) +#define DIRECT_MMAP_DEFAULT(s) win32direct_mmap(s) +#endif /* WIN32 */ +#endif /* HAVE_MMAP */ + +#if HAVE_MREMAP +#ifndef WIN32 +#define MREMAP_DEFAULT(addr, osz, nsz, mv) mremap((addr), (osz), (nsz), (mv)) +#endif /* WIN32 */ +#endif /* HAVE_MREMAP */ + +/** + * Define CALL_MORECORE + */ +#if HAVE_MORECORE + #ifdef MORECORE + #define CALL_MORECORE(S) MORECORE(S) + #else /* MORECORE */ + #define CALL_MORECORE(S) MORECORE_DEFAULT(S) + #endif /* MORECORE */ +#else /* HAVE_MORECORE */ + #define CALL_MORECORE(S) MFAIL +#endif /* HAVE_MORECORE */ + +/** + * Define CALL_MMAP/CALL_MUNMAP/CALL_DIRECT_MMAP + */ +#if HAVE_MMAP + #define USE_MMAP_BIT (SIZE_T_ONE) + + #ifdef MMAP + #define CALL_MMAP(s) MMAP(s) + #else /* MMAP */ + #define CALL_MMAP(s) MMAP_DEFAULT(s) + #endif /* MMAP */ + #ifdef MUNMAP + #define CALL_MUNMAP(a, s) MUNMAP((a), (s)) + #else /* MUNMAP */ + #define CALL_MUNMAP(a, s) MUNMAP_DEFAULT((a), (s)) + #endif /* MUNMAP */ + #ifdef DIRECT_MMAP + #define CALL_DIRECT_MMAP(s) DIRECT_MMAP(s) + #else /* DIRECT_MMAP */ + #define CALL_DIRECT_MMAP(s) DIRECT_MMAP_DEFAULT(s) + #endif /* DIRECT_MMAP */ +#else /* HAVE_MMAP */ + #define USE_MMAP_BIT (SIZE_T_ZERO) + + #define MMAP(s) MFAIL + #define MUNMAP(a, s) (-1) + #define DIRECT_MMAP(s) MFAIL + #define CALL_DIRECT_MMAP(s) DIRECT_MMAP(s) + #define CALL_MMAP(s) MMAP(s) + #define CALL_MUNMAP(a, s) MUNMAP((a), (s)) +#endif /* HAVE_MMAP */ + +/** + * Define CALL_MREMAP + */ +#if HAVE_MMAP && HAVE_MREMAP + #ifdef MREMAP + #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP((addr), (osz), (nsz), (mv)) + #else /* MREMAP */ + #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP_DEFAULT((addr), (osz), (nsz), (mv)) + #endif /* MREMAP */ +#else /* HAVE_MMAP && HAVE_MREMAP */ + #define CALL_MREMAP(addr, osz, nsz, mv) MFAIL +#endif /* HAVE_MMAP && HAVE_MREMAP */ + +/* mstate bit set if continguous morecore disabled or failed */ +#define USE_NONCONTIGUOUS_BIT (4U) + +/* segment bit set in create_mspace_with_base */ +#define EXTERN_BIT (8U) + + +/* --------------------------- Lock preliminaries ------------------------ */ + +/* + When locks are defined, there is one global lock, plus + one per-mspace lock. + + The global lock_ensures that mparams.magic and other unique + mparams values are initialized only once. It also protects + sequences of calls to MORECORE. In many cases sys_alloc requires + two calls, that should not be interleaved with calls by other + threads. This does not protect against direct calls to MORECORE + by other threads not using this lock, so there is still code to + cope the best we can on interference. + + Per-mspace locks surround calls to malloc, free, etc. + By default, locks are simple non-reentrant mutexes. + + Because lock-protected regions generally have bounded times, it is + OK to use the supplied simple spinlocks. Spinlocks are likely to + improve performance for lightly contended applications, but worsen + performance under heavy contention. + + If USE_LOCKS is > 1, the definitions of lock routines here are + bypassed, in which case you will need to define the type MLOCK_T, + and at least INITIAL_LOCK, DESTROY_LOCK, ACQUIRE_LOCK, RELEASE_LOCK + and TRY_LOCK. You must also declare a + static MLOCK_T malloc_global_mutex = { initialization values };. + +*/ + +#if !USE_LOCKS +#define USE_LOCK_BIT (0U) +#define INITIAL_LOCK(l) (0) +#define DESTROY_LOCK(l) (0) +#define ACQUIRE_MALLOC_GLOBAL_LOCK() +#define RELEASE_MALLOC_GLOBAL_LOCK() + +#else +#if USE_LOCKS > 1 +/* ----------------------- User-defined locks ------------------------ */ +/* Define your own lock implementation here */ +/* #define INITIAL_LOCK(lk) ... */ +/* #define DESTROY_LOCK(lk) ... */ +/* #define ACQUIRE_LOCK(lk) ... */ +/* #define RELEASE_LOCK(lk) ... */ +/* #define TRY_LOCK(lk) ... */ +/* static MLOCK_T malloc_global_mutex = ... */ + +#elif USE_SPIN_LOCKS + +/* First, define CAS_LOCK and CLEAR_LOCK on ints */ +/* Note CAS_LOCK defined to return 0 on success */ + +#if defined(__GNUC__)&& (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) +#define CAS_LOCK(sl) __sync_lock_test_and_set(sl, 1) +#define CLEAR_LOCK(sl) __sync_lock_release(sl) + +#elif (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))) +/* Custom spin locks for older gcc on x86 */ +static FORCEINLINE int x86_cas_lock(int *sl) { + int ret; + int val = 1; + int cmp = 0; + __asm__ __volatile__ ("lock; cmpxchgl %1, %2" + : "=a" (ret) + : "r" (val), "m" (*(sl)), "0"(cmp) + : "memory", "cc"); + return ret; +} + +static FORCEINLINE void x86_clear_lock(int* sl) { + assert(*sl != 0); + int prev = 0; + int ret; + __asm__ __volatile__ ("lock; xchgl %0, %1" + : "=r" (ret) + : "m" (*(sl)), "0"(prev) + : "memory"); +} + +#define CAS_LOCK(sl) x86_cas_lock(sl) +#define CLEAR_LOCK(sl) x86_clear_lock(sl) + +#else /* Win32 MSC */ +#define CAS_LOCK(sl) interlockedexchange(sl, 1) +#define CLEAR_LOCK(sl) interlockedexchange (sl, 0) + +#endif /* ... gcc spins locks ... */ + +/* How to yield for a spin lock */ +#define SPINS_PER_YIELD 63 +#if defined(_MSC_VER) +#define SLEEP_EX_DURATION 50 /* delay for yield/sleep */ +#define SPIN_LOCK_YIELD SleepEx(SLEEP_EX_DURATION, FALSE) +#elif defined (__SVR4) && defined (__sun) /* solaris */ +#define SPIN_LOCK_YIELD thr_yield(); +#elif !defined(LACKS_SCHED_H) +#define SPIN_LOCK_YIELD sched_yield(); +#else +#define SPIN_LOCK_YIELD +#endif /* ... yield ... */ + +#if !defined(USE_RECURSIVE_LOCKS) || USE_RECURSIVE_LOCKS == 0 +/* Plain spin locks use single word (embedded in malloc_states) */ +static int spin_acquire_lock(int *sl) { + int spins = 0; + while (*(volatile int *)sl != 0 || CAS_LOCK(sl)) { + if ((++spins & SPINS_PER_YIELD) == 0) { + SPIN_LOCK_YIELD; + } + } + return 0; +} + +#if !defined(AMIGA) +#define MLOCK_T int +#define TRY_LOCK(sl) !CAS_LOCK(sl) +#define RELEASE_LOCK(sl) CLEAR_LOCK(sl) +#define ACQUIRE_LOCK(sl) (CAS_LOCK(sl)? spin_acquire_lock(sl) : 0) +#define INITIAL_LOCK(sl) (*sl = 0) +#define DESTROY_LOCK(sl) (0) +static MLOCK_T malloc_global_mutex = 0; +#endif //!defined(AMIGA) + +#else /* USE_RECURSIVE_LOCKS */ +/* types for lock owners */ +#ifdef WIN32 +#define THREAD_ID_T DWORD +#define CURRENT_THREAD GetCurrentThreadId() +#define EQ_OWNER(X,Y) ((X) == (Y)) +#else +/* + Note: the following assume that pthread_t is a type that can be + initialized to (casted) zero. If this is not the case, you will need to + somehow redefine these or not use spin locks. +*/ +#define THREAD_ID_T pthread_t +#define CURRENT_THREAD pthread_self() +#define EQ_OWNER(X,Y) pthread_equal(X, Y) +#endif + +struct malloc_recursive_lock { + int sl; + unsigned int c; + THREAD_ID_T threadid; +}; + +#define MLOCK_T struct malloc_recursive_lock +static MLOCK_T malloc_global_mutex = { 0, 0, (THREAD_ID_T)0}; + +static FORCEINLINE void recursive_release_lock(MLOCK_T *lk) { + assert(lk->sl != 0); + if (--lk->c == 0) { + CLEAR_LOCK(&lk->sl); + } +} + +static FORCEINLINE int recursive_acquire_lock(MLOCK_T *lk) { + THREAD_ID_T mythreadid = CURRENT_THREAD; + int spins = 0; + for (;;) { + if (*((volatile int *)(&lk->sl)) == 0) { + if (!CAS_LOCK(&lk->sl)) { + lk->threadid = mythreadid; + lk->c = 1; + return 0; + } + } + else if (EQ_OWNER(lk->threadid, mythreadid)) { + ++lk->c; + return 0; + } + if ((++spins & SPINS_PER_YIELD) == 0) { + SPIN_LOCK_YIELD; + } + } +} + +static FORCEINLINE int recursive_try_lock(MLOCK_T *lk) { + THREAD_ID_T mythreadid = CURRENT_THREAD; + if (*((volatile int *)(&lk->sl)) == 0) { + if (!CAS_LOCK(&lk->sl)) { + lk->threadid = mythreadid; + lk->c = 1; + return 1; + } + } + else if (EQ_OWNER(lk->threadid, mythreadid)) { + ++lk->c; + return 1; + } + return 0; +} + +#define RELEASE_LOCK(lk) recursive_release_lock(lk) +#define TRY_LOCK(lk) recursive_try_lock(lk) +#define ACQUIRE_LOCK(lk) recursive_acquire_lock(lk) +#define INITIAL_LOCK(lk) ((lk)->threadid = (THREAD_ID_T)0, (lk)->sl = 0, (lk)->c = 0) +#define DESTROY_LOCK(lk) (0) +#endif /* USE_RECURSIVE_LOCKS */ + +#elif defined(WIN32) /* Win32 critical sections */ +#define MLOCK_T CRITICAL_SECTION +#define ACQUIRE_LOCK(lk) (EnterCriticalSection(lk), 0) +#define RELEASE_LOCK(lk) LeaveCriticalSection(lk) +#define TRY_LOCK(lk) TryEnterCriticalSection(lk) +#define INITIAL_LOCK(lk) (!InitializeCriticalSectionAndSpinCount((lk), 0x80000000|4000)) +#define DESTROY_LOCK(lk) (DeleteCriticalSection(lk), 0) +#define NEED_GLOBAL_LOCK_INIT + +static MLOCK_T malloc_global_mutex; +static volatile long malloc_global_mutex_status; + +/* Use spin loop to initialize global lock */ +static void init_malloc_global_mutex() { + for (;;) { + long stat = malloc_global_mutex_status; + if (stat > 0) + return; + /* transition to < 0 while initializing, then to > 0) */ + if (stat == 0 && + interlockedcompareexchange(&malloc_global_mutex_status, -1, 0) == 0) { + InitializeCriticalSection(&malloc_global_mutex); + interlockedexchange(&malloc_global_mutex_status,1); + return; + } + SleepEx(0, FALSE); + } +} + +#elif defined(AMIGA) +#else /* pthreads-based locks */ +#define MLOCK_T pthread_mutex_t +#define ACQUIRE_LOCK(lk) pthread_mutex_lock(lk) +#define RELEASE_LOCK(lk) pthread_mutex_unlock(lk) +#define TRY_LOCK(lk) (!pthread_mutex_trylock(lk)) +#define INITIAL_LOCK(lk) pthread_init_lock(lk) +#define DESTROY_LOCK(lk) pthread_mutex_destroy(lk) + +#if defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0 && defined(linux) && !defined(PTHREAD_MUTEX_RECURSIVE) +/* Cope with old-style linux recursive lock initialization by adding */ +/* skipped internal declaration from pthread.h */ +extern int pthread_mutexattr_setkind_np __P ((pthread_mutexattr_t *__attr, + int __kind)); +#define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP +#define pthread_mutexattr_settype(x,y) pthread_mutexattr_setkind_np(x,y) +#endif /* USE_RECURSIVE_LOCKS ... */ + +static MLOCK_T malloc_global_mutex = PTHREAD_MUTEX_INITIALIZER; + +static int pthread_init_lock (MLOCK_T *lk) { + pthread_mutexattr_t attr; + if (pthread_mutexattr_init(&attr)) return 1; +#if defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0 + if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) return 1; +#endif + if (pthread_mutex_init(lk, &attr)) return 1; + if (pthread_mutexattr_destroy(&attr)) return 1; + return 0; +} + +#endif /* ... lock types ... */ + +/* Common code for all lock types */ +#define USE_LOCK_BIT (2U) + +#ifndef ACQUIRE_MALLOC_GLOBAL_LOCK +#define ACQUIRE_MALLOC_GLOBAL_LOCK() ACQUIRE_LOCK(&malloc_global_mutex); +#endif + +#ifndef RELEASE_MALLOC_GLOBAL_LOCK +#define RELEASE_MALLOC_GLOBAL_LOCK() RELEASE_LOCK(&malloc_global_mutex); +#endif + +#endif /* USE_LOCKS */ + +/* ----------------------- Chunk representations ------------------------ */ + +/* + (The following includes lightly edited explanations by Colin Plumb.) + + The malloc_chunk declaration below is misleading (but accurate and + necessary). It declares a "view" into memory allowing access to + necessary fields at known offsets from a given base. + + Chunks of memory are maintained using a `boundary tag' method as + originally described by Knuth. (See the paper by Paul Wilson + ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a survey of such + techniques.) Sizes of free chunks are stored both in the front of + each chunk and at the end. This makes consolidating fragmented + chunks into bigger chunks fast. The head fields also hold bits + representing whether chunks are free or in use. + + Here are some pictures to make it clearer. They are "exploded" to + show that the state of a chunk can be thought of as extending from + the high 31 bits of the head field of its header through the + prev_foot and PINUSE_BIT bit of the following chunk header. + + A chunk that's in use looks like: + + chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of previous chunk (if P = 0) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P| + | Size of this chunk 1| +-+ + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + +- -+ + | | + +- -+ + | : + +- size - sizeof(size_t) available payload bytes -+ + : | + chunk-> +- -+ + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |1| + | Size of next chunk (may or may not be in use) | +-+ + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + And if it's free, it looks like this: + + chunk-> +- -+ + | User payload (must be in use, or we would have merged!) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P| + | Size of this chunk 0| +-+ + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Next pointer | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Prev pointer | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | : + +- size - sizeof(struct chunk) unused bytes -+ + : | + chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of this chunk | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |0| + | Size of next chunk (must be in use, or we would have merged)| +-+ + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | : + +- User payload -+ + : | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |0| + +-+ + Note that since we always merge adjacent free chunks, the chunks + adjacent to a free chunk must be in use. + + Given a pointer to a chunk (which can be derived trivially from the + payload pointer) we can, in O(1) time, find out whether the adjacent + chunks are free, and if so, unlink them from the lists that they + are on and merge them with the current chunk. + + Chunks always begin on even word boundaries, so the mem portion + (which is returned to the user) is also on an even word boundary, and + thus at least double-word aligned. + + The P (PINUSE_BIT) bit, stored in the unused low-order bit of the + chunk size (which is always a multiple of two words), is an in-use + bit for the *previous* chunk. If that bit is *clear*, then the + word before the current chunk size contains the previous chunk + size, and can be used to find the front of the previous chunk. + The very first chunk allocated always has this bit set, preventing + access to non-existent (or non-owned) memory. If pinuse is set for + any given chunk, then you CANNOT determine the size of the + previous chunk, and might even get a memory addressing fault when + trying to do so. + + The C (CINUSE_BIT) bit, stored in the unused second-lowest bit of + the chunk size redundantly records whether the current chunk is + inuse (unless the chunk is mmapped). This redundancy enables usage + checks within free and realloc, and reduces indirection when freeing + and consolidating chunks. + + Each freshly allocated chunk must have both cinuse and pinuse set. + That is, each allocated chunk borders either a previously allocated + and still in-use chunk, or the base of its memory arena. This is + ensured by making all allocations from the `lowest' part of any + found chunk. Further, no free chunk physically borders another one, + so each free chunk is known to be preceded and followed by either + inuse chunks or the ends of memory. + + Note that the `foot' of the current chunk is actually represented + as the prev_foot of the NEXT chunk. This makes it easier to + deal with alignments etc but can be very confusing when trying + to extend or adapt this code. + + The exceptions to all this are + + 1. The special chunk `top' is the top-most available chunk (i.e., + the one bordering the end of available memory). It is treated + specially. Top is never included in any bin, is used only if + no other chunk is available, and is released back to the + system if it is very large (see M_TRIM_THRESHOLD). In effect, + the top chunk is treated as larger (and thus less well + fitting) than any other available chunk. The top chunk + doesn't update its trailing size field since there is no next + contiguous chunk that would have to index off it. However, + space is still allocated for it (TOP_FOOT_SIZE) to enable + separation or merging when space is extended. + + 3. Chunks allocated via mmap, have both cinuse and pinuse bits + cleared in their head fields. Because they are allocated + one-by-one, each must carry its own prev_foot field, which is + also used to hold the offset this chunk has within its mmapped + region, which is needed to preserve alignment. Each mmapped + chunk is trailed by the first two fields of a fake next-chunk + for sake of usage checks. + +*/ + +struct malloc_chunk { + size_t prev_foot; /* Size of previous chunk (if free). */ + size_t head; /* Size and inuse bits. */ + struct malloc_chunk* fd; /* double links -- used only if free. */ + struct malloc_chunk* bk; +}; + +typedef struct malloc_chunk mchunk; +typedef struct malloc_chunk* mchunkptr; +typedef struct malloc_chunk* sbinptr; /* The type of bins of chunks */ +typedef unsigned int bindex_t; /* Described below */ +typedef unsigned int binmap_t; /* Described below */ +typedef unsigned int flag_t; /* The type of various bit flag sets */ + +/* ------------------- Chunks sizes and alignments ----------------------- */ + +#define MCHUNK_SIZE (sizeof(mchunk)) + +#if FOOTERS +#define CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) +#else /* FOOTERS */ +#define CHUNK_OVERHEAD (SIZE_T_SIZE) +#endif /* FOOTERS */ + +/* MMapped chunks need a second word of overhead ... */ +#define MMAP_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) +/* ... and additional padding for fake next-chunk at foot */ +#define MMAP_FOOT_PAD (FOUR_SIZE_T_SIZES) + +/* The smallest size we can malloc is an aligned minimal chunk */ +#define MIN_CHUNK_SIZE\ + ((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) + +/* conversion from malloc headers to user pointers, and back */ +#define chunk2mem(p) ((void*)((char*)(p) + TWO_SIZE_T_SIZES)) +#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - TWO_SIZE_T_SIZES)) +/* chunk associated with aligned address A */ +#define align_as_chunk(A) (mchunkptr)((A) + align_offset(chunk2mem(A))) + +/* Bounds on request (not chunk) sizes. */ +#define MAX_REQUEST ((-MIN_CHUNK_SIZE) << 2) +#define MIN_REQUEST (MIN_CHUNK_SIZE - CHUNK_OVERHEAD - SIZE_T_ONE) + +/* pad request bytes into a usable size */ +#define pad_request(req) \ + (((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) + +/* pad request, checking for minimum (but not maximum) */ +#define request2size(req) \ + (((req) < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(req)) + + +/* ------------------ Operations on head and foot fields ----------------- */ + +/* + The head field of a chunk is or'ed with PINUSE_BIT when previous + adjacent chunk in use, and or'ed with CINUSE_BIT if this chunk is in + use, unless mmapped, in which case both bits are cleared. + + FLAG4_BIT is not used by this malloc, but might be useful in extensions. +*/ + +#define PINUSE_BIT (SIZE_T_ONE) +#define CINUSE_BIT (SIZE_T_TWO) +#define FLAG4_BIT (SIZE_T_FOUR) +#define INUSE_BITS (PINUSE_BIT|CINUSE_BIT) +#define FLAG_BITS (PINUSE_BIT|CINUSE_BIT|FLAG4_BIT) + +/* Head value for fenceposts */ +#define FENCEPOST_HEAD (INUSE_BITS|SIZE_T_SIZE) + +/* extraction of fields from head words */ +#define cinuse(p) ((p)->head & CINUSE_BIT) +#define pinuse(p) ((p)->head & PINUSE_BIT) +#define flag4inuse(p) ((p)->head & FLAG4_BIT) +#define is_inuse(p) (((p)->head & INUSE_BITS) != PINUSE_BIT) +#define is_mmapped(p) (((p)->head & INUSE_BITS) == 0) + +#define chunksize(p) ((p)->head & ~(FLAG_BITS)) + +#define clear_pinuse(p) ((p)->head &= ~PINUSE_BIT) +#define set_flag4(p) ((p)->head |= FLAG4_BIT) +#define clear_flag4(p) ((p)->head &= ~FLAG4_BIT) + +/* Treat space at ptr +/- offset as a chunk */ +#define chunk_plus_offset(p, s) ((mchunkptr)(((char*)(p)) + (s))) +#define chunk_minus_offset(p, s) ((mchunkptr)(((char*)(p)) - (s))) + +/* Ptr to next or previous physical malloc_chunk. */ +#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->head & ~FLAG_BITS))) +#define prev_chunk(p) ((mchunkptr)( ((char*)(p)) - ((p)->prev_foot) )) + +/* extract next chunk's pinuse bit */ +#define next_pinuse(p) ((next_chunk(p)->head) & PINUSE_BIT) + +/* Get/set size at footer */ +#define get_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot) +#define set_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot = (s)) + +/* Set size, pinuse bit, and foot */ +#define set_size_and_pinuse_of_free_chunk(p, s)\ + ((p)->head = (s|PINUSE_BIT), set_foot(p, s)) + +/* Set size, pinuse bit, foot, and clear next pinuse */ +#define set_free_with_pinuse(p, s, n)\ + (clear_pinuse(n), set_size_and_pinuse_of_free_chunk(p, s)) + +/* Get the internal overhead associated with chunk p */ +#define overhead_for(p)\ + (is_mmapped(p)? MMAP_CHUNK_OVERHEAD : CHUNK_OVERHEAD) + +/* Return true if malloced space is not necessarily cleared */ +#if MMAP_CLEARS +#define calloc_must_clear(p) (!is_mmapped(p)) +#else /* MMAP_CLEARS */ +#define calloc_must_clear(p) (1) +#endif /* MMAP_CLEARS */ + +/* ---------------------- Overlaid data structures ----------------------- */ + +/* + When chunks are not in use, they are treated as nodes of either + lists or trees. + + "Small" chunks are stored in circular doubly-linked lists, and look + like this: + + chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of previous chunk | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + `head:' | Size of chunk, in bytes |P| + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Forward pointer to next chunk in list | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Back pointer to previous chunk in list | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Unused space (may be 0 bytes long) . + . . + . | +nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + `foot:' | Size of chunk, in bytes | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Larger chunks are kept in a form of bitwise digital trees (aka + tries) keyed on chunksizes. Because malloc_tree_chunks are only for + free chunks greater than 256 bytes, their size doesn't impose any + constraints on user chunk sizes. Each node looks like: + + chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of previous chunk | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + `head:' | Size of chunk, in bytes |P| + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Forward pointer to next chunk of same size | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Back pointer to previous chunk of same size | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Pointer to left child (child[0]) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Pointer to right child (child[1]) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Pointer to parent | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | bin index of this chunk | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Unused space . + . | +nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + `foot:' | Size of chunk, in bytes | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Each tree holding treenodes is a tree of unique chunk sizes. Chunks + of the same size are arranged in a circularly-linked list, with only + the oldest chunk (the next to be used, in our FIFO ordering) + actually in the tree. (Tree members are distinguished by a non-null + parent pointer.) If a chunk with the same size an an existing node + is inserted, it is linked off the existing node using pointers that + work in the same way as fd/bk pointers of small chunks. + + Each tree contains a power of 2 sized range of chunk sizes (the + smallest is 0x100 <= x < 0x180), which is is divided in half at each + tree level, with the chunks in the smaller half of the range (0x100 + <= x < 0x140 for the top nose) in the left subtree and the larger + half (0x140 <= x < 0x180) in the right subtree. This is, of course, + done by inspecting individual bits. + + Using these rules, each node's left subtree contains all smaller + sizes than its right subtree. However, the node at the root of each + subtree has no particular ordering relationship to either. (The + dividing line between the subtree sizes is based on trie relation.) + If we remove the last chunk of a given size from the interior of the + tree, we need to replace it with a leaf node. The tree ordering + rules permit a node to be replaced by any leaf below it. + + The smallest chunk in a tree (a common operation in a best-fit + allocator) can be found by walking a path to the leftmost leaf in + the tree. Unlike a usual binary tree, where we follow left child + pointers until we reach a null, here we follow the right child + pointer any time the left one is null, until we reach a leaf with + both child pointers null. The smallest chunk in the tree will be + somewhere along that path. + + The worst case number of steps to add, find, or remove a node is + bounded by the number of bits differentiating chunks within + bins. Under current bin calculations, this ranges from 6 up to 21 + (for 32 bit sizes) or up to 53 (for 64 bit sizes). The typical case + is of course much better. +*/ + +struct malloc_tree_chunk { + /* The first four fields must be compatible with malloc_chunk */ + size_t prev_foot; + size_t head; + struct malloc_tree_chunk* fd; + struct malloc_tree_chunk* bk; + + struct malloc_tree_chunk* child[2]; + struct malloc_tree_chunk* parent; + bindex_t index; +}; + +typedef struct malloc_tree_chunk tchunk; +typedef struct malloc_tree_chunk* tchunkptr; +typedef struct malloc_tree_chunk* tbinptr; /* The type of bins of trees */ + +/* A little helper macro for trees */ +#define leftmost_child(t) ((t)->child[0] != 0? (t)->child[0] : (t)->child[1]) + +/* ----------------------------- Segments -------------------------------- */ + +/* + Each malloc space may include non-contiguous segments, held in a + list headed by an embedded malloc_segment record representing the + top-most space. Segments also include flags holding properties of + the space. Large chunks that are directly allocated by mmap are not + included in this list. They are instead independently created and + destroyed without otherwise keeping track of them. + + Segment management mainly comes into play for spaces allocated by + MMAP. Any call to MMAP might or might not return memory that is + adjacent to an existing segment. MORECORE normally contiguously + extends the current space, so this space is almost always adjacent, + which is simpler and faster to deal with. (This is why MORECORE is + used preferentially to MMAP when both are available -- see + sys_alloc.) When allocating using MMAP, we don't use any of the + hinting mechanisms (inconsistently) supported in various + implementations of unix mmap, or distinguish reserving from + committing memory. Instead, we just ask for space, and exploit + contiguity when we get it. It is probably possible to do + better than this on some systems, but no general scheme seems + to be significantly better. + + Management entails a simpler variant of the consolidation scheme + used for chunks to reduce fragmentation -- new adjacent memory is + normally prepended or appended to an existing segment. However, + there are limitations compared to chunk consolidation that mostly + reflect the fact that segment processing is relatively infrequent + (occurring only when getting memory from system) and that we + don't expect to have huge numbers of segments: + + * Segments are not indexed, so traversal requires linear scans. (It + would be possible to index these, but is not worth the extra + overhead and complexity for most programs on most platforms.) + * New segments are only appended to old ones when holding top-most + memory; if they cannot be prepended to others, they are held in + different segments. + + Except for the top-most segment of an mstate, each segment record + is kept at the tail of its segment. Segments are added by pushing + segment records onto the list headed by &mstate.seg for the + containing mstate. + + Segment flags control allocation/merge/deallocation policies: + * If EXTERN_BIT set, then we did not allocate this segment, + and so should not try to deallocate or merge with others. + (This currently holds only for the initial segment passed + into create_mspace_with_base.) + * If USE_MMAP_BIT set, the segment may be merged with + other surrounding mmapped segments and trimmed/de-allocated + using munmap. + * If neither bit is set, then the segment was obtained using + MORECORE so can be merged with surrounding MORECORE'd segments + and deallocated/trimmed using MORECORE with negative arguments. +*/ + +struct malloc_segment { + char* base; /* base address */ + size_t size; /* allocated size */ + struct malloc_segment* next; /* ptr to next segment */ + flag_t sflags; /* mmap and extern flag */ +}; + +#define is_mmapped_segment(S) ((S)->sflags & USE_MMAP_BIT) +#define is_extern_segment(S) ((S)->sflags & EXTERN_BIT) + +typedef struct malloc_segment msegment; +typedef struct malloc_segment* msegmentptr; + +/* ---------------------------- malloc_state ----------------------------- */ + +/* + A malloc_state holds all of the bookkeeping for a space. + The main fields are: + + Top + The topmost chunk of the currently active segment. Its size is + cached in topsize. The actual size of topmost space is + topsize+TOP_FOOT_SIZE, which includes space reserved for adding + fenceposts and segment records if necessary when getting more + space from the system. The size at which to autotrim top is + cached from mparams in trim_check, except that it is disabled if + an autotrim fails. + + Designated victim (dv) + This is the preferred chunk for servicing small requests that + don't have exact fits. It is normally the chunk split off most + recently to service another small request. Its size is cached in + dvsize. The link fields of this chunk are not maintained since it + is not kept in a bin. + + SmallBins + An array of bin headers for free chunks. These bins hold chunks + with sizes less than MIN_LARGE_SIZE bytes. Each bin contains + chunks of all the same size, spaced 8 bytes apart. To simplify + use in double-linked lists, each bin header acts as a malloc_chunk + pointing to the real first node, if it exists (else pointing to + itself). This avoids special-casing for headers. But to avoid + waste, we allocate only the fd/bk pointers of bins, and then use + repositioning tricks to treat these as the fields of a chunk. + + TreeBins + Treebins are pointers to the roots of trees holding a range of + sizes. There are 2 equally spaced treebins for each power of two + from TREE_SHIFT to TREE_SHIFT+16. The last bin holds anything + larger. + + Bin maps + There is one bit map for small bins ("smallmap") and one for + treebins ("treemap). Each bin sets its bit when non-empty, and + clears the bit when empty. Bit operations are then used to avoid + bin-by-bin searching -- nearly all "search" is done without ever + looking at bins that won't be selected. The bit maps + conservatively use 32 bits per map word, even if on 64bit system. + For a good description of some of the bit-based techniques used + here, see Henry S. Warren Jr's book "Hacker's Delight" (and + supplement at http://hackersdelight.org/). Many of these are + intended to reduce the branchiness of paths through malloc etc, as + well as to reduce the number of memory locations read or written. + + Segments + A list of segments headed by an embedded malloc_segment record + representing the initial space. + + Address check support + The least_addr field is the least address ever obtained from + MORECORE or MMAP. Attempted frees and reallocs of any address less + than this are trapped (unless INSECURE is defined). + + Magic tag + A cross-check field that should always hold same value as mparams.magic. + + Max allowed footprint + The maximum allowed bytes to allocate from system (zero means no limit) + + Flags + Bits recording whether to use MMAP, locks, or contiguous MORECORE + + Statistics + Each space keeps track of current and maximum system memory + obtained via MORECORE or MMAP. + + Trim support + Fields holding the amount of unused topmost memory that should trigger + trimming, and a counter to force periodic scanning to release unused + non-topmost segments. + + Locking + If USE_LOCKS is defined, the "mutex" lock is acquired and released + around every public call using this mspace. + + Extension support + A void* pointer and a size_t field that can be used to help implement + extensions to this malloc. +*/ + +/* Bin types, widths and sizes */ +#define NSMALLBINS (32U) +#define NTREEBINS (32U) +#define SMALLBIN_SHIFT (3U) +#define SMALLBIN_WIDTH (SIZE_T_ONE << SMALLBIN_SHIFT) +#define TREEBIN_SHIFT (8U) +#define MIN_LARGE_SIZE (SIZE_T_ONE << TREEBIN_SHIFT) +#define MAX_SMALL_SIZE (MIN_LARGE_SIZE - SIZE_T_ONE) +#define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - CHUNK_ALIGN_MASK - CHUNK_OVERHEAD) + +struct malloc_state { + binmap_t smallmap; + binmap_t treemap; + size_t dvsize; + size_t topsize; + char* least_addr; + mchunkptr dv; + mchunkptr top; + size_t trim_check; + size_t release_checks; + size_t magic; + mchunkptr smallbins[(NSMALLBINS+1)*2]; + tbinptr treebins[NTREEBINS]; + size_t footprint; + size_t max_footprint; + size_t footprint_limit; /* zero means no limit */ + flag_t mflags; +#if USE_LOCKS + MLOCK_T mutex; /* locate lock among fields that rarely change */ +#endif /* USE_LOCKS */ + msegment seg; + void* extp; /* Unused but available for extensions */ + size_t exts; +}; + +typedef struct malloc_state* mstate; + +/* ------------- Global malloc_state and malloc_params ------------------- */ + +/* + malloc_params holds global properties, including those that can be + dynamically set using mallopt. There is a single instance, mparams, + initialized in init_mparams. Note that the non-zeroness of "magic" + also serves as an initialization flag. +*/ + +struct malloc_params { + size_t magic; + size_t page_size; + size_t granularity; + size_t mmap_threshold; + size_t trim_threshold; + flag_t default_mflags; +}; + +static struct malloc_params mparams; + +/* Ensure mparams initialized */ +#define ensure_initialization() (void)(mparams.magic != 0 || init_mparams()) + +#if !ONLY_MSPACES + +/* The global malloc_state used for all non-"mspace" calls */ +static struct malloc_state _gm_; +#define gm (&_gm_) +#define is_global(M) ((M) == &_gm_) + +#endif /* !ONLY_MSPACES */ + +#define is_initialized(M) ((M)->top != 0) + +/* -------------------------- system alloc setup ------------------------- */ + +/* Operations on mflags */ + +#define use_lock(M) ((M)->mflags & USE_LOCK_BIT) +#define enable_lock(M) ((M)->mflags |= USE_LOCK_BIT) +#if USE_LOCKS +#define disable_lock(M) ((M)->mflags &= ~USE_LOCK_BIT) +#else +#define disable_lock(M) +#endif + +#define use_mmap(M) ((M)->mflags & USE_MMAP_BIT) +#define enable_mmap(M) ((M)->mflags |= USE_MMAP_BIT) +#if HAVE_MMAP +#define disable_mmap(M) ((M)->mflags &= ~USE_MMAP_BIT) +#else +#define disable_mmap(M) +#endif + +#define use_noncontiguous(M) ((M)->mflags & USE_NONCONTIGUOUS_BIT) +#define disable_contiguous(M) ((M)->mflags |= USE_NONCONTIGUOUS_BIT) + +#define set_lock(M,L)\ + ((M)->mflags = (L)?\ + ((M)->mflags | USE_LOCK_BIT) :\ + ((M)->mflags & ~USE_LOCK_BIT)) + +/* page-align a size */ +#define page_align(S)\ + (((S) + (mparams.page_size - SIZE_T_ONE)) & ~(mparams.page_size - SIZE_T_ONE)) + +/* granularity-align a size */ +#define granularity_align(S)\ + (((S) + (mparams.granularity - SIZE_T_ONE))\ + & ~(mparams.granularity - SIZE_T_ONE)) + + +/* For mmap, use granularity alignment on windows, else page-align */ +#ifdef WIN32 +#define mmap_align(S) granularity_align(S) +#else +#define mmap_align(S) page_align(S) +#endif + +/* For sys_alloc, enough padding to ensure can malloc request on success */ +#define SYS_ALLOC_PADDING (TOP_FOOT_SIZE + MALLOC_ALIGNMENT) + +#define is_page_aligned(S)\ + (((size_t)(S) & (mparams.page_size - SIZE_T_ONE)) == 0) +#define is_granularity_aligned(S)\ + (((size_t)(S) & (mparams.granularity - SIZE_T_ONE)) == 0) + +/* True if segment S holds address A */ +#define segment_holds(S, A)\ + ((char*)(A) >= S->base && (char*)(A) < S->base + S->size) + +/* Return segment holding given address */ +static msegmentptr segment_holding(mstate m, char* addr) { + msegmentptr sp = &m->seg; + for (;;) { + if (addr >= sp->base && addr < sp->base + sp->size) + return sp; + if ((sp = sp->next) == 0) + return 0; + } +} + +/* Return true if segment contains a segment link */ +static int has_segment_link(mstate m, msegmentptr ss) { + msegmentptr sp = &m->seg; + for (;;) { + if ((char*)sp >= ss->base && (char*)sp < ss->base + ss->size) + return 1; + if ((sp = sp->next) == 0) + return 0; + } +} + +#ifndef MORECORE_CANNOT_TRIM +#define should_trim(M,s) ((s) > (M)->trim_check) +#else /* MORECORE_CANNOT_TRIM */ +#define should_trim(M,s) (0) +#endif /* MORECORE_CANNOT_TRIM */ + +/* + TOP_FOOT_SIZE is padding at the end of a segment, including space + that may be needed to place segment records and fenceposts when new + noncontiguous segments are added. +*/ +#define TOP_FOOT_SIZE\ + (align_offset(chunk2mem(0))+pad_request(sizeof(struct malloc_segment))+MIN_CHUNK_SIZE) + + +/* ------------------------------- Hooks -------------------------------- */ + +/* + PREACTION should be defined to return 0 on success, and nonzero on + failure. If you are not using locking, you can redefine these to do + anything you like. +*/ + +#if USE_LOCKS +#define PREACTION(M) ((use_lock(M))? ACQUIRE_LOCK(&(M)->mutex) : 0) +#define POSTACTION(M) { if (use_lock(M)) RELEASE_LOCK(&(M)->mutex); } +#else /* USE_LOCKS */ + +#ifndef PREACTION +#define PREACTION(M) (0) +#endif /* PREACTION */ + +#ifndef POSTACTION +#define POSTACTION(M) +#endif /* POSTACTION */ + +#endif /* USE_LOCKS */ + +/* + CORRUPTION_ERROR_ACTION is triggered upon detected bad addresses. + USAGE_ERROR_ACTION is triggered on detected bad frees and + reallocs. The argument p is an address that might have triggered the + fault. It is ignored by the two predefined actions, but might be + useful in custom actions that try to help diagnose errors. +*/ + +#if PROCEED_ON_ERROR + +/* A count of the number of corruption errors causing resets */ +int malloc_corruption_error_count; + +/* default corruption action */ +static void reset_on_error(mstate m); + +#define CORRUPTION_ERROR_ACTION(m) reset_on_error(m) +#define USAGE_ERROR_ACTION(m, p) + +#else /* PROCEED_ON_ERROR */ + +#ifndef CORRUPTION_ERROR_ACTION +#define CORRUPTION_ERROR_ACTION(m) ABORT +#endif /* CORRUPTION_ERROR_ACTION */ + +#ifndef USAGE_ERROR_ACTION +#define USAGE_ERROR_ACTION(m,p) ABORT +#endif /* USAGE_ERROR_ACTION */ + +#endif /* PROCEED_ON_ERROR */ + + +/* -------------------------- Debugging setup ---------------------------- */ + +#if ! DEBUG + +#define check_free_chunk(M,P) +#define check_inuse_chunk(M,P) +#define check_malloced_chunk(M,P,N) +#define check_mmapped_chunk(M,P) +#define check_malloc_state(M) +#define check_top_chunk(M,P) + +#else /* DEBUG */ +#define check_free_chunk(M,P) do_check_free_chunk(M,P) +#define check_inuse_chunk(M,P) do_check_inuse_chunk(M,P) +#define check_top_chunk(M,P) do_check_top_chunk(M,P) +#define check_malloced_chunk(M,P,N) do_check_malloced_chunk(M,P,N) +#define check_mmapped_chunk(M,P) do_check_mmapped_chunk(M,P) +#define check_malloc_state(M) do_check_malloc_state(M) + +static void do_check_any_chunk(mstate m, mchunkptr p); +static void do_check_top_chunk(mstate m, mchunkptr p); +static void do_check_mmapped_chunk(mstate m, mchunkptr p); +static void do_check_inuse_chunk(mstate m, mchunkptr p); +static void do_check_free_chunk(mstate m, mchunkptr p); +static void do_check_malloced_chunk(mstate m, void* mem, size_t s); +static void do_check_tree(mstate m, tchunkptr t); +static void do_check_treebin(mstate m, bindex_t i); +static void do_check_smallbin(mstate m, bindex_t i); +static void do_check_malloc_state(mstate m); +static int bin_find(mstate m, mchunkptr x); +static size_t traverse_and_check(mstate m); +#endif /* DEBUG */ + +/* ---------------------------- Indexing Bins ---------------------------- */ + +#define is_small(s) (((s) >> SMALLBIN_SHIFT) < NSMALLBINS) +#define small_index(s) (bindex_t)((s) >> SMALLBIN_SHIFT) +#define small_index2size(i) ((i) << SMALLBIN_SHIFT) +#define MIN_SMALL_INDEX (small_index(MIN_CHUNK_SIZE)) + +/* addressing by index. See above about smallbin repositioning */ +#define smallbin_at(M, i) ((sbinptr)((char*)&((M)->smallbins[(i)<<1]))) +#define treebin_at(M,i) (&((M)->treebins[i])) + +/* assign tree index for size S to variable I. Use x86 asm if possible */ +#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) +#define compute_tree_index(S, I)\ +{\ + unsigned int X = S >> TREEBIN_SHIFT;\ + if (X == 0)\ + I = 0;\ + else if (X > 0xFFFF)\ + I = NTREEBINS-1;\ + else {\ + unsigned int K = (unsigned) sizeof(X)*__CHAR_BIT__ - 1 - (unsigned) __builtin_clz(X); \ + I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\ + }\ +} + +#elif defined (__INTEL_COMPILER) +#define compute_tree_index(S, I)\ +{\ + size_t X = S >> TREEBIN_SHIFT;\ + if (X == 0)\ + I = 0;\ + else if (X > 0xFFFF)\ + I = NTREEBINS-1;\ + else {\ + unsigned int K = _bit_scan_reverse (X); \ + I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\ + }\ +} + +#elif defined(_MSC_VER) && _MSC_VER>=1300 +#define compute_tree_index(S, I)\ +{\ + size_t X = S >> TREEBIN_SHIFT;\ + if (X == 0)\ + I = 0;\ + else if (X > 0xFFFF)\ + I = NTREEBINS-1;\ + else {\ + unsigned int K;\ + _BitScanReverse((DWORD *) &K, (DWORD) X);\ + I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\ + }\ +} + +#else /* GNUC */ +#define compute_tree_index(S, I)\ +{\ + size_t X = S >> TREEBIN_SHIFT;\ + if (X == 0)\ + I = 0;\ + else if (X > 0xFFFF)\ + I = NTREEBINS-1;\ + else {\ + unsigned int Y = (unsigned int)X;\ + unsigned int N = ((Y - 0x100) >> 16) & 8;\ + unsigned int K = (((Y <<= N) - 0x1000) >> 16) & 4;\ + N += K;\ + N += K = (((Y <<= K) - 0x4000) >> 16) & 2;\ + K = 14 - N + ((Y <<= K) >> 15);\ + I = (K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1));\ + }\ +} +#endif /* GNUC */ + +/* Bit representing maximum resolved size in a treebin at i */ +#define bit_for_tree_index(i) \ + (i == NTREEBINS-1)? (SIZE_T_BITSIZE-1) : (((i) >> 1) + TREEBIN_SHIFT - 2) + +/* Shift placing maximum resolved bit in a treebin at i as sign bit */ +#define leftshift_for_tree_index(i) \ + ((i == NTREEBINS-1)? 0 : \ + ((SIZE_T_BITSIZE-SIZE_T_ONE) - (((i) >> 1) + TREEBIN_SHIFT - 2))) + +/* The size of the smallest chunk held in bin with index i */ +#define minsize_for_tree_index(i) \ + ((SIZE_T_ONE << (((i) >> 1) + TREEBIN_SHIFT)) | \ + (((size_t)((i) & SIZE_T_ONE)) << (((i) >> 1) + TREEBIN_SHIFT - 1))) + + +/* ------------------------ Operations on bin maps ----------------------- */ + +/* bit corresponding to given index */ +#define idx2bit(i) ((binmap_t)(1) << (i)) + +/* Mark/Clear bits with given index */ +#define mark_smallmap(M,i) ((M)->smallmap |= idx2bit(i)) +#define clear_smallmap(M,i) ((M)->smallmap &= ~idx2bit(i)) +#define smallmap_is_marked(M,i) ((M)->smallmap & idx2bit(i)) + +#define mark_treemap(M,i) ((M)->treemap |= idx2bit(i)) +#define clear_treemap(M,i) ((M)->treemap &= ~idx2bit(i)) +#define treemap_is_marked(M,i) ((M)->treemap & idx2bit(i)) + +/* isolate the least set bit of a bitmap */ +#define least_bit(x) ((x) & -(x)) + +/* mask with all bits to left of least bit of x on */ +#define left_bits(x) ((x<<1) | -(x<<1)) + +/* mask with all bits to left of or equal to least bit of x on */ +#define same_or_left_bits(x) ((x) | -(x)) + +/* index corresponding to given bit. Use x86 asm if possible */ + +#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) +#define compute_bit2idx(X, I)\ +{\ + unsigned int J;\ + J = __builtin_ctz(X); \ + I = (bindex_t)J;\ +} + +#elif defined (__INTEL_COMPILER) +#define compute_bit2idx(X, I)\ +{\ + unsigned int J;\ + J = _bit_scan_forward (X); \ + I = (bindex_t)J;\ +} + +#elif defined(_MSC_VER) && _MSC_VER>=1300 +#define compute_bit2idx(X, I)\ +{\ + unsigned int J;\ + _BitScanForward((DWORD *) &J, X);\ + I = (bindex_t)J;\ +} + +#elif USE_BUILTIN_FFS +#define compute_bit2idx(X, I) I = ffs(X)-1 + +#else +#define compute_bit2idx(X, I)\ +{\ + unsigned int Y = X - 1;\ + unsigned int K = Y >> (16-4) & 16;\ + unsigned int N = K; Y >>= K;\ + N += K = Y >> (8-3) & 8; Y >>= K;\ + N += K = Y >> (4-2) & 4; Y >>= K;\ + N += K = Y >> (2-1) & 2; Y >>= K;\ + N += K = Y >> (1-0) & 1; Y >>= K;\ + I = (bindex_t)(N + Y);\ +} +#endif /* GNUC */ + + +/* ----------------------- Runtime Check Support ------------------------- */ + +/* + For security, the main invariant is that malloc/free/etc never + writes to a static address other than malloc_state, unless static + malloc_state itself has been corrupted, which cannot occur via + malloc (because of these checks). In essence this means that we + believe all pointers, sizes, maps etc held in malloc_state, but + check all of those linked or offsetted from other embedded data + structures. These checks are interspersed with main code in a way + that tends to minimize their run-time cost. + + When FOOTERS is defined, in addition to range checking, we also + verify footer fields of inuse chunks, which can be used guarantee + that the mstate controlling malloc/free is intact. This is a + streamlined version of the approach described by William Robertson + et al in "Run-time Detection of Heap-based Overflows" LISA'03 + http://www.usenix.org/events/lisa03/tech/robertson.html The footer + of an inuse chunk holds the xor of its mstate and a random seed, + that is checked upon calls to free() and realloc(). This is + (probabalistically) unguessable from outside the program, but can be + computed by any code successfully malloc'ing any chunk, so does not + itself provide protection against code that has already broken + security through some other means. Unlike Robertson et al, we + always dynamically check addresses of all offset chunks (previous, + next, etc). This turns out to be cheaper than relying on hashes. +*/ + +#if !INSECURE +/* Check if address a is at least as high as any from MORECORE or MMAP */ +#define ok_address(M, a) ((char*)(a) >= (M)->least_addr) +/* Check if address of next chunk n is higher than base chunk p */ +#define ok_next(p, n) ((char*)(p) < (char*)(n)) +/* Check if p has inuse status */ +#define ok_inuse(p) is_inuse(p) +/* Check if p has its pinuse bit on */ +#define ok_pinuse(p) pinuse(p) + +#else /* !INSECURE */ +#define ok_address(M, a) (1) +#define ok_next(b, n) (1) +#define ok_inuse(p) (1) +#define ok_pinuse(p) (1) +#endif /* !INSECURE */ + +#if (FOOTERS && !INSECURE) +/* Check if (alleged) mstate m has expected magic field */ +#define ok_magic(M) ((M)->magic == mparams.magic) +#else /* (FOOTERS && !INSECURE) */ +#define ok_magic(M) (1) +#endif /* (FOOTERS && !INSECURE) */ + +/* In gcc, use __builtin_expect to minimize impact of checks */ +#if !INSECURE +#if defined(__GNUC__) && __GNUC__ >= 3 +#define RTCHECK(e) __builtin_expect(e, 1) +#else /* GNUC */ +#define RTCHECK(e) (e) +#endif /* GNUC */ +#else /* !INSECURE */ +#define RTCHECK(e) (1) +#endif /* !INSECURE */ + +/* macros to set up inuse chunks with or without footers */ + +#if !FOOTERS + +#define mark_inuse_foot(M,p,s) + +/* Macros for setting head/foot of non-mmapped chunks */ + +/* Set cinuse bit and pinuse bit of next chunk */ +#define set_inuse(M,p,s)\ + ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\ + ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT) + +/* Set cinuse and pinuse of this chunk and pinuse of next chunk */ +#define set_inuse_and_pinuse(M,p,s)\ + ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ + ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT) + +/* Set size, cinuse and pinuse bit of this chunk */ +#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\ + ((p)->head = (s|PINUSE_BIT|CINUSE_BIT)) + +#else /* FOOTERS */ + +/* Set foot of inuse chunk to be xor of mstate and seed */ +#define mark_inuse_foot(M,p,s)\ + (((mchunkptr)((char*)(p) + (s)))->prev_foot = ((size_t)(M) ^ mparams.magic)) + +#define get_mstate_for(p)\ + ((mstate)(((mchunkptr)((char*)(p) +\ + (chunksize(p))))->prev_foot ^ mparams.magic)) + +#define set_inuse(M,p,s)\ + ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\ + (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT), \ + mark_inuse_foot(M,p,s)) + +#define set_inuse_and_pinuse(M,p,s)\ + ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ + (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT),\ + mark_inuse_foot(M,p,s)) + +#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\ + ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ + mark_inuse_foot(M, p, s)) + +#endif /* !FOOTERS */ + +/* ---------------------------- setting mparams -------------------------- */ + +/* Initialize mparams */ +static int init_mparams(void) { +#ifdef NEED_GLOBAL_LOCK_INIT + if (malloc_global_mutex_status <= 0) + init_malloc_global_mutex(); +#endif + + ACQUIRE_MALLOC_GLOBAL_LOCK(); + if (mparams.magic == 0) { + size_t magic; + size_t psize; + size_t gsize; + +#ifndef WIN32 + psize = malloc_getpagesize; + gsize = ((DEFAULT_GRANULARITY != 0)? DEFAULT_GRANULARITY : psize); +#else /* WIN32 */ + { + SYSTEM_INFO system_info; + GetSystemInfo(&system_info); + psize = system_info.dwPageSize; + gsize = ((DEFAULT_GRANULARITY != 0)? + DEFAULT_GRANULARITY : system_info.dwAllocationGranularity); + } +#endif /* WIN32 */ + + /* Sanity-check configuration: + size_t must be unsigned and as wide as pointer type. + ints must be at least 4 bytes. + alignment must be at least 8. + Alignment, min chunk size, and page size must all be powers of 2. + */ + if ((sizeof(size_t) != sizeof(char*)) || + (MAX_SIZE_T < MIN_CHUNK_SIZE) || + (sizeof(int) < 4) || + (MALLOC_ALIGNMENT < (size_t)8U) || + ((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT-SIZE_T_ONE)) != 0) || + ((MCHUNK_SIZE & (MCHUNK_SIZE-SIZE_T_ONE)) != 0) || + ((gsize & (gsize-SIZE_T_ONE)) != 0) || + ((psize & (psize-SIZE_T_ONE)) != 0)) + ABORT; + + mparams.granularity = gsize; + mparams.page_size = psize; + mparams.mmap_threshold = DEFAULT_MMAP_THRESHOLD; + mparams.trim_threshold = DEFAULT_TRIM_THRESHOLD; +#if MORECORE_CONTIGUOUS + mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT; +#else /* MORECORE_CONTIGUOUS */ + mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT|USE_NONCONTIGUOUS_BIT; +#endif /* MORECORE_CONTIGUOUS */ + +#if !ONLY_MSPACES + /* Set up lock for main malloc area */ + gm->mflags = mparams.default_mflags; + (void)INITIAL_LOCK(&gm->mutex); +#endif + + { +#if USE_DEV_RANDOM + int fd; + unsigned char buf[sizeof(size_t)]; + /* Try to use /dev/urandom, else fall back on using time */ + if ((fd = open("/dev/urandom", O_RDONLY)) >= 0 && + read(fd, buf, sizeof(buf)) == sizeof(buf)) { + magic = *((size_t *) buf); + close(fd); + } + else +#endif /* USE_DEV_RANDOM */ +#ifdef WIN32 + magic = (size_t)(GetTickCount() ^ (size_t)0x55555555U); +#elif defined(LACKS_TIME_H) + magic = (size_t)&magic ^ (size_t)0x55555555U; +#else + magic = (size_t)(time(0) ^ (size_t)0x55555555U); +#endif + magic |= (size_t)8U; /* ensure nonzero */ + magic &= ~(size_t)7U; /* improve chances of fault for bad values */ + /* Until memory modes commonly available, use volatile-write */ + (*(volatile size_t *)(&(mparams.magic))) = magic; + } + } + + RELEASE_MALLOC_GLOBAL_LOCK(); + return 1; +} + +/* support for mallopt */ +static int change_mparam(int param_number, int value) { + size_t val; + ensure_initialization(); + val = (value == -1)? MAX_SIZE_T : (size_t)value; + switch(param_number) { + case M_TRIM_THRESHOLD: + mparams.trim_threshold = val; + return 1; + case M_GRANULARITY: + if (val >= mparams.page_size && ((val & (val-1)) == 0)) { + mparams.granularity = val; + return 1; + } + else + return 0; + case M_MMAP_THRESHOLD: + mparams.mmap_threshold = val; + return 1; + default: + return 0; + } +} + +#if DEBUG +/* ------------------------- Debugging Support --------------------------- */ + +/* Check properties of any chunk, whether free, inuse, mmapped etc */ +static void do_check_any_chunk(mstate m, mchunkptr p) { + assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); + assert(ok_address(m, p)); +} + +/* Check properties of top chunk */ +static void do_check_top_chunk(mstate m, mchunkptr p) { + msegmentptr sp = segment_holding(m, (char*)p); + size_t sz = p->head & ~INUSE_BITS; /* third-lowest bit can be set! */ + assert(sp != 0); + assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); + assert(ok_address(m, p)); + assert(sz == m->topsize); + assert(sz > 0); + assert(sz == ((sp->base + sp->size) - (char*)p) - TOP_FOOT_SIZE); + assert(pinuse(p)); + assert(!pinuse(chunk_plus_offset(p, sz))); +} + +/* Check properties of (inuse) mmapped chunks */ +static void do_check_mmapped_chunk(mstate m, mchunkptr p) { + size_t sz = chunksize(p); + size_t len = (sz + (p->prev_foot) + MMAP_FOOT_PAD); + assert(is_mmapped(p)); + assert(use_mmap(m)); + assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); + assert(ok_address(m, p)); + assert(!is_small(sz)); + assert((len & (mparams.page_size-SIZE_T_ONE)) == 0); + assert(chunk_plus_offset(p, sz)->head == FENCEPOST_HEAD); + assert(chunk_plus_offset(p, sz+SIZE_T_SIZE)->head == 0); +} + +/* Check properties of inuse chunks */ +static void do_check_inuse_chunk(mstate m, mchunkptr p) { + do_check_any_chunk(m, p); + assert(is_inuse(p)); + assert(next_pinuse(p)); + /* If not pinuse and not mmapped, previous chunk has OK offset */ + assert(is_mmapped(p) || pinuse(p) || next_chunk(prev_chunk(p)) == p); + if (is_mmapped(p)) + do_check_mmapped_chunk(m, p); +} + +/* Check properties of free chunks */ +static void do_check_free_chunk(mstate m, mchunkptr p) { + size_t sz = chunksize(p); + mchunkptr next = chunk_plus_offset(p, sz); + do_check_any_chunk(m, p); + assert(!is_inuse(p)); + assert(!next_pinuse(p)); + assert (!is_mmapped(p)); + if (p != m->dv && p != m->top) { + if (sz >= MIN_CHUNK_SIZE) { + assert((sz & CHUNK_ALIGN_MASK) == 0); + assert(is_aligned(chunk2mem(p))); + assert(next->prev_foot == sz); + assert(pinuse(p)); + assert (next == m->top || is_inuse(next)); + assert(p->fd->bk == p); + assert(p->bk->fd == p); + } + else /* markers are always of size SIZE_T_SIZE */ + assert(sz == SIZE_T_SIZE); + } +} + +/* Check properties of malloced chunks at the point they are malloced */ +static void do_check_malloced_chunk(mstate m, void* mem, size_t s) { + if (mem != 0) { + mchunkptr p = mem2chunk(mem); + size_t sz = p->head & ~INUSE_BITS; + do_check_inuse_chunk(m, p); + assert((sz & CHUNK_ALIGN_MASK) == 0); + assert(sz >= MIN_CHUNK_SIZE); + assert(sz >= s); + /* unless mmapped, size is less than MIN_CHUNK_SIZE more than request */ + assert(is_mmapped(p) || sz < (s + MIN_CHUNK_SIZE)); + } +} + +/* Check a tree and its subtrees. */ +static void do_check_tree(mstate m, tchunkptr t) { + tchunkptr head = 0; + tchunkptr u = t; + bindex_t tindex = t->index; + size_t tsize = chunksize(t); + bindex_t idx; + compute_tree_index(tsize, idx); + assert(tindex == idx); + assert(tsize >= MIN_LARGE_SIZE); + assert(tsize >= minsize_for_tree_index(idx)); + assert((idx == NTREEBINS-1) || (tsize < minsize_for_tree_index((idx+1)))); + + do { /* traverse through chain of same-sized nodes */ + do_check_any_chunk(m, ((mchunkptr)u)); + assert(u->index == tindex); + assert(chunksize(u) == tsize); + assert(!is_inuse(u)); + assert(!next_pinuse(u)); + assert(u->fd->bk == u); + assert(u->bk->fd == u); + if (u->parent == 0) { + assert(u->child[0] == 0); + assert(u->child[1] == 0); + } + else { + assert(head == 0); /* only one node on chain has parent */ + head = u; + assert(u->parent != u); + assert (u->parent->child[0] == u || + u->parent->child[1] == u || + *((tbinptr*)(u->parent)) == u); + if (u->child[0] != 0) { + assert(u->child[0]->parent == u); + assert(u->child[0] != u); + do_check_tree(m, u->child[0]); + } + if (u->child[1] != 0) { + assert(u->child[1]->parent == u); + assert(u->child[1] != u); + do_check_tree(m, u->child[1]); + } + if (u->child[0] != 0 && u->child[1] != 0) { + assert(chunksize(u->child[0]) < chunksize(u->child[1])); + } + } + u = u->fd; + } while (u != t); + assert(head != 0); +} + +/* Check all the chunks in a treebin. */ +static void do_check_treebin(mstate m, bindex_t i) { + tbinptr* tb = treebin_at(m, i); + tchunkptr t = *tb; + int empty = (m->treemap & (1U << i)) == 0; + if (t == 0) + assert(empty); + if (!empty) + do_check_tree(m, t); +} + +/* Check all the chunks in a smallbin. */ +static void do_check_smallbin(mstate m, bindex_t i) { + sbinptr b = smallbin_at(m, i); + mchunkptr p = b->bk; + unsigned int empty = (m->smallmap & (1U << i)) == 0; + if (p == b) + assert(empty); + if (!empty) { + for (; p != b; p = p->bk) { + size_t size = chunksize(p); + mchunkptr q; + /* each chunk claims to be free */ + do_check_free_chunk(m, p); + /* chunk belongs in bin */ + assert(small_index(size) == i); + assert(p->bk == b || chunksize(p->bk) == chunksize(p)); + /* chunk is followed by an inuse chunk */ + q = next_chunk(p); + if (q->head != FENCEPOST_HEAD) + do_check_inuse_chunk(m, q); + } + } +} + +/* Find x in a bin. Used in other check functions. */ +static int bin_find(mstate m, mchunkptr x) { + size_t size = chunksize(x); + if (is_small(size)) { + bindex_t sidx = small_index(size); + sbinptr b = smallbin_at(m, sidx); + if (smallmap_is_marked(m, sidx)) { + mchunkptr p = b; + do { + if (p == x) + return 1; + } while ((p = p->fd) != b); + } + } + else { + bindex_t tidx; + compute_tree_index(size, tidx); + if (treemap_is_marked(m, tidx)) { + tchunkptr t = *treebin_at(m, tidx); + size_t sizebits = size << leftshift_for_tree_index(tidx); + while (t != 0 && chunksize(t) != size) { + t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]; + sizebits <<= 1; + } + if (t != 0) { + tchunkptr u = t; + do { + if (u == (tchunkptr)x) + return 1; + } while ((u = u->fd) != t); + } + } + } + return 0; +} + +/* Traverse each chunk and check it; return total */ +static size_t traverse_and_check(mstate m) { + size_t sum = 0; + if (is_initialized(m)) { + msegmentptr s = &m->seg; + sum += m->topsize + TOP_FOOT_SIZE; + while (s != 0) { + mchunkptr q = align_as_chunk(s->base); + mchunkptr lastq = 0; + assert(pinuse(q)); + while (segment_holds(s, q) && + q != m->top && q->head != FENCEPOST_HEAD) { + sum += chunksize(q); + if (is_inuse(q)) { + assert(!bin_find(m, q)); + do_check_inuse_chunk(m, q); + } + else { + assert(q == m->dv || bin_find(m, q)); + assert(lastq == 0 || is_inuse(lastq)); /* Not 2 consecutive free */ + do_check_free_chunk(m, q); + } + lastq = q; + q = next_chunk(q); + } + s = s->next; + } + } + return sum; +} + + +/* Check all properties of malloc_state. */ +static void do_check_malloc_state(mstate m) { + bindex_t i; + size_t total; + /* check bins */ + for (i = 0; i < NSMALLBINS; ++i) + do_check_smallbin(m, i); + for (i = 0; i < NTREEBINS; ++i) + do_check_treebin(m, i); + + if (m->dvsize != 0) { /* check dv chunk */ + do_check_any_chunk(m, m->dv); + assert(m->dvsize == chunksize(m->dv)); + assert(m->dvsize >= MIN_CHUNK_SIZE); + assert(bin_find(m, m->dv) == 0); + } + + if (m->top != 0) { /* check top chunk */ + do_check_top_chunk(m, m->top); + /*assert(m->topsize == chunksize(m->top)); redundant */ + assert(m->topsize > 0); + assert(bin_find(m, m->top) == 0); + } + + total = traverse_and_check(m); + assert(total <= m->footprint); + assert(m->footprint <= m->max_footprint); +} +#endif /* DEBUG */ + +/* ----------------------------- statistics ------------------------------ */ + +#if !NO_MALLINFO +static struct mallinfo internal_mallinfo(mstate m) { + struct mallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + ensure_initialization(); + if (!PREACTION(m)) { + check_malloc_state(m); + if (is_initialized(m)) { + size_t nfree = SIZE_T_ONE; /* top always free */ + size_t mfree = m->topsize + TOP_FOOT_SIZE; + size_t sum = mfree; + msegmentptr s = &m->seg; + while (s != 0) { + mchunkptr q = align_as_chunk(s->base); + while (segment_holds(s, q) && + q != m->top && q->head != FENCEPOST_HEAD) { + size_t sz = chunksize(q); + sum += sz; + if (!is_inuse(q)) { + mfree += sz; + ++nfree; + } + q = next_chunk(q); + } + s = s->next; + } + + nm.arena = sum; + nm.ordblks = nfree; + nm.hblkhd = m->footprint - sum; + nm.usmblks = m->max_footprint; + nm.uordblks = m->footprint - mfree; + nm.fordblks = mfree; + nm.keepcost = m->topsize; + } + + POSTACTION(m); + } + return nm; +} +#endif /* !NO_MALLINFO */ + +#if !NO_MALLOC_STATS +static void internal_malloc_stats(mstate m) { + ensure_initialization(); + if (!PREACTION(m)) { + size_t maxfp = 0; + size_t fp = 0; + size_t used = 0; + check_malloc_state(m); + if (is_initialized(m)) { + msegmentptr s = &m->seg; + maxfp = m->max_footprint; + fp = m->footprint; + used = fp - (m->topsize + TOP_FOOT_SIZE); + + while (s != 0) { + mchunkptr q = align_as_chunk(s->base); + while (segment_holds(s, q) && + q != m->top && q->head != FENCEPOST_HEAD) { + if (!is_inuse(q)) + used -= chunksize(q); + q = next_chunk(q); + } + s = s->next; + } + } + POSTACTION(m); /* drop lock */ + fprintf(stderr, "max system bytes = %10lu\n", (unsigned long)(maxfp)); + fprintf(stderr, "system bytes = %10lu\n", (unsigned long)(fp)); + fprintf(stderr, "in use bytes = %10lu\n", (unsigned long)(used)); + } +} +#endif /* NO_MALLOC_STATS */ + +/* ----------------------- Operations on smallbins ----------------------- */ + +/* + Various forms of linking and unlinking are defined as macros. Even + the ones for trees, which are very long but have very short typical + paths. This is ugly but reduces reliance on inlining support of + compilers. +*/ + +/* Link a free chunk into a smallbin */ +#define insert_small_chunk(M, P, S) {\ + bindex_t I = small_index(S);\ + mchunkptr B = smallbin_at(M, I);\ + mchunkptr F = B;\ + assert(S >= MIN_CHUNK_SIZE);\ + if (!smallmap_is_marked(M, I))\ + mark_smallmap(M, I);\ + else if (RTCHECK(ok_address(M, B->fd)))\ + F = B->fd;\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + B->fd = P;\ + F->bk = P;\ + P->fd = F;\ + P->bk = B;\ +} + +/* Unlink a chunk from a smallbin */ +#define unlink_small_chunk(M, P, S) {\ + mchunkptr F = P->fd;\ + mchunkptr B = P->bk;\ + bindex_t I = small_index(S);\ + assert(P != B);\ + assert(P != F);\ + assert(chunksize(P) == small_index2size(I));\ + if (RTCHECK(F == smallbin_at(M,I) || (ok_address(M, F) && F->bk == P))) { \ + if (B == F) {\ + clear_smallmap(M, I);\ + }\ + else if (RTCHECK(B == smallbin_at(M,I) ||\ + (ok_address(M, B) && B->fd == P))) {\ + F->bk = B;\ + B->fd = F;\ + }\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + }\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + }\ +} + +/* Unlink the first chunk from a smallbin */ +#define unlink_first_small_chunk(M, B, P, I) {\ + mchunkptr F = P->fd;\ + assert(P != B);\ + assert(P != F);\ + assert(chunksize(P) == small_index2size(I));\ + if (B == F) {\ + clear_smallmap(M, I);\ + }\ + else if (RTCHECK(ok_address(M, F) && F->bk == P)) {\ + F->bk = B;\ + B->fd = F;\ + }\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + }\ +} + +/* Replace dv node, binning the old one */ +/* Used only when dvsize known to be small */ +#define replace_dv(M, P, S) {\ + size_t DVS = M->dvsize;\ + assert(is_small(DVS));\ + if (DVS != 0) {\ + mchunkptr DV = M->dv;\ + insert_small_chunk(M, DV, DVS);\ + }\ + M->dvsize = S;\ + M->dv = P;\ +} + +/* ------------------------- Operations on trees ------------------------- */ + +/* Insert chunk into tree */ +#define insert_large_chunk(M, X, S) {\ + tbinptr* H;\ + bindex_t I;\ + compute_tree_index(S, I);\ + H = treebin_at(M, I);\ + X->index = I;\ + X->child[0] = X->child[1] = 0;\ + if (!treemap_is_marked(M, I)) {\ + mark_treemap(M, I);\ + *H = X;\ + X->parent = (tchunkptr)H;\ + X->fd = X->bk = X;\ + }\ + else {\ + tchunkptr T = *H;\ + size_t K = S << leftshift_for_tree_index(I);\ + for (;;) {\ + if (chunksize(T) != S) {\ + tchunkptr* C = &(T->child[(K >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]);\ + K <<= 1;\ + if (*C != 0)\ + T = *C;\ + else if (RTCHECK(ok_address(M, C))) {\ + *C = X;\ + X->parent = T;\ + X->fd = X->bk = X;\ + break;\ + }\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + break;\ + }\ + }\ + else {\ + tchunkptr F = T->fd;\ + if (RTCHECK(ok_address(M, T) && ok_address(M, F))) {\ + T->fd = F->bk = X;\ + X->fd = F;\ + X->bk = T;\ + X->parent = 0;\ + break;\ + }\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + break;\ + }\ + }\ + }\ + }\ +} + +/* + Unlink steps: + + 1. If x is a chained node, unlink it from its same-sized fd/bk links + and choose its bk node as its replacement. + 2. If x was the last node of its size, but not a leaf node, it must + be replaced with a leaf node (not merely one with an open left or + right), to make sure that lefts and rights of descendents + correspond properly to bit masks. We use the rightmost descendent + of x. We could use any other leaf, but this is easy to locate and + tends to counteract removal of leftmosts elsewhere, and so keeps + paths shorter than minimally guaranteed. This doesn't loop much + because on average a node in a tree is near the bottom. + 3. If x is the base of a chain (i.e., has parent links) relink + x's parent and children to x's replacement (or null if none). +*/ + +#define unlink_large_chunk(M, X) {\ + tchunkptr XP = X->parent;\ + tchunkptr R;\ + if (X->bk != X) {\ + tchunkptr F = X->fd;\ + R = X->bk;\ + if (RTCHECK(ok_address(M, F) && F->bk == X && R->fd == X)) {\ + F->bk = R;\ + R->fd = F;\ + }\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + }\ + else {\ + tchunkptr* RP;\ + if (((R = *(RP = &(X->child[1]))) != 0) ||\ + ((R = *(RP = &(X->child[0]))) != 0)) {\ + tchunkptr* CP;\ + while ((*(CP = &(R->child[1])) != 0) ||\ + (*(CP = &(R->child[0])) != 0)) {\ + R = *(RP = CP);\ + }\ + if (RTCHECK(ok_address(M, RP)))\ + *RP = 0;\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + }\ + }\ + if (XP != 0) {\ + tbinptr* H = treebin_at(M, X->index);\ + if (X == *H) {\ + if ((*H = R) == 0) \ + clear_treemap(M, X->index);\ + }\ + else if (RTCHECK(ok_address(M, XP))) {\ + if (XP->child[0] == X) \ + XP->child[0] = R;\ + else \ + XP->child[1] = R;\ + }\ + else\ + CORRUPTION_ERROR_ACTION(M);\ + if (R != 0) {\ + if (RTCHECK(ok_address(M, R))) {\ + tchunkptr C0, C1;\ + R->parent = XP;\ + if ((C0 = X->child[0]) != 0) {\ + if (RTCHECK(ok_address(M, C0))) {\ + R->child[0] = C0;\ + C0->parent = R;\ + }\ + else\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + if ((C1 = X->child[1]) != 0) {\ + if (RTCHECK(ok_address(M, C1))) {\ + R->child[1] = C1;\ + C1->parent = R;\ + }\ + else\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + }\ + else\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + }\ +} + +/* Relays to large vs small bin operations */ + +#define insert_chunk(M, P, S)\ + if (is_small(S)) insert_small_chunk(M, P, S)\ + else { tchunkptr TP = (tchunkptr)(P); insert_large_chunk(M, TP, S); } + +#define unlink_chunk(M, P, S)\ + if (is_small(S)) unlink_small_chunk(M, P, S)\ + else { tchunkptr TP = (tchunkptr)(P); unlink_large_chunk(M, TP); } + + +/* Relays to internal calls to malloc/free from realloc, memalign etc */ + +#if ONLY_MSPACES +#define internal_malloc(m, b) mspace_malloc(m, b) +#define internal_free(m, mem) mspace_free(m,mem); +#else /* ONLY_MSPACES */ +#if MSPACES +#define internal_malloc(m, b)\ + ((m == gm)? dlmalloc(b) : mspace_malloc(m, b)) +#define internal_free(m, mem)\ + if (m == gm) dlfree(mem); else mspace_free(m,mem); +#else /* MSPACES */ +#define internal_malloc(m, b) dlmalloc(b) +#define internal_free(m, mem) dlfree(mem) +#endif /* MSPACES */ +#endif /* ONLY_MSPACES */ + +/* ----------------------- Direct-mmapping chunks ----------------------- */ + +/* + Directly mmapped chunks are set up with an offset to the start of + the mmapped region stored in the prev_foot field of the chunk. This + allows reconstruction of the required argument to MUNMAP when freed, + and also allows adjustment of the returned chunk to meet alignment + requirements (especially in memalign). +*/ + +/* Malloc using mmap */ +static void* mmap_alloc(mstate m, size_t nb) { + size_t mmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); + if (m->footprint_limit != 0) { + size_t fp = m->footprint + mmsize; + if (fp <= m->footprint || fp > m->footprint_limit) + return 0; + } + if (mmsize > nb) { /* Check for wrap around 0 */ + char* mm = (char*)(CALL_DIRECT_MMAP(mmsize)); + if (mm != CMFAIL) { + size_t offset = align_offset(chunk2mem(mm)); + size_t psize = mmsize - offset - MMAP_FOOT_PAD; + mchunkptr p = (mchunkptr)(mm + offset); + p->prev_foot = offset; + p->head = psize; + mark_inuse_foot(m, p, psize); + chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD; + chunk_plus_offset(p, psize+SIZE_T_SIZE)->head = 0; + + if (m->least_addr == 0 || mm < m->least_addr) + m->least_addr = mm; + if ((m->footprint += mmsize) > m->max_footprint) + m->max_footprint = m->footprint; + assert(is_aligned(chunk2mem(p))); + check_mmapped_chunk(m, p); + return chunk2mem(p); + } + } + return 0; +} + +/* Realloc using mmap */ +static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb, int flags) { + size_t oldsize = chunksize(oldp); + flags = flags; /* placate people compiling -Wunused */ + if (is_small(nb)) /* Can't shrink mmap regions below small size */ + return 0; + /* Keep old chunk if big enough but not too big */ + if (oldsize >= nb + SIZE_T_SIZE && + (oldsize - nb) <= (mparams.granularity << 1)) + return oldp; + else { + size_t offset = oldp->prev_foot; + size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD; + size_t newmmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); + char* cp = (char*)CALL_MREMAP((char*)oldp - offset, + oldmmsize, newmmsize, flags); + if (cp != CMFAIL) { + mchunkptr newp = (mchunkptr)(cp + offset); + size_t psize = newmmsize - offset - MMAP_FOOT_PAD; + newp->head = psize; + mark_inuse_foot(m, newp, psize); + chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD; + chunk_plus_offset(newp, psize+SIZE_T_SIZE)->head = 0; + + if (cp < m->least_addr) + m->least_addr = cp; + if ((m->footprint += newmmsize - oldmmsize) > m->max_footprint) + m->max_footprint = m->footprint; + check_mmapped_chunk(m, newp); + return newp; + } + } + return 0; +} + + +/* -------------------------- mspace management -------------------------- */ + +/* Initialize top chunk and its size */ +static void init_top(mstate m, mchunkptr p, size_t psize) { + /* Ensure alignment */ + size_t offset = align_offset(chunk2mem(p)); + p = (mchunkptr)((char*)p + offset); + psize -= offset; + + m->top = p; + m->topsize = psize; + p->head = psize | PINUSE_BIT; + /* set size of fake trailing chunk holding overhead space only once */ + chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE; + m->trim_check = mparams.trim_threshold; /* reset on each update */ +} + +/* Initialize bins for a new mstate that is otherwise zeroed out */ +static void init_bins(mstate m) { + /* Establish circular links for smallbins */ + bindex_t i; + for (i = 0; i < NSMALLBINS; ++i) { + sbinptr bin = smallbin_at(m,i); + bin->fd = bin->bk = bin; + } +} + +#if PROCEED_ON_ERROR + +/* default corruption action */ +static void reset_on_error(mstate m) { + int i; + ++malloc_corruption_error_count; + /* Reinitialize fields to forget about all memory */ + m->smallmap = m->treemap = 0; + m->dvsize = m->topsize = 0; + m->seg.base = 0; + m->seg.size = 0; + m->seg.next = 0; + m->top = m->dv = 0; + for (i = 0; i < NTREEBINS; ++i) + *treebin_at(m, i) = 0; + init_bins(m); +} +#endif /* PROCEED_ON_ERROR */ + +/* Allocate chunk and prepend remainder with chunk in successor base. */ +static void* prepend_alloc(mstate m, char* newbase, char* oldbase, + size_t nb) { + mchunkptr p = align_as_chunk(newbase); + mchunkptr oldfirst = align_as_chunk(oldbase); + size_t psize = (char*)oldfirst - (char*)p; + mchunkptr q = chunk_plus_offset(p, nb); + size_t qsize = psize - nb; + set_size_and_pinuse_of_inuse_chunk(m, p, nb); + + assert((char*)oldfirst > (char*)q); + assert(pinuse(oldfirst)); + assert(qsize >= MIN_CHUNK_SIZE); + + /* consolidate remainder with first chunk of old base */ + if (oldfirst == m->top) { + size_t tsize = m->topsize += qsize; + m->top = q; + q->head = tsize | PINUSE_BIT; + check_top_chunk(m, q); + } + else if (oldfirst == m->dv) { + size_t dsize = m->dvsize += qsize; + m->dv = q; + set_size_and_pinuse_of_free_chunk(q, dsize); + } + else { + if (!is_inuse(oldfirst)) { + size_t nsize = chunksize(oldfirst); + unlink_chunk(m, oldfirst, nsize); + oldfirst = chunk_plus_offset(oldfirst, nsize); + qsize += nsize; + } + set_free_with_pinuse(q, qsize, oldfirst); + insert_chunk(m, q, qsize); + check_free_chunk(m, q); + } + + check_malloced_chunk(m, chunk2mem(p), nb); + return chunk2mem(p); +} + +/* Add a segment to hold a new noncontiguous region */ +static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) { + /* Determine locations and sizes of segment, fenceposts, old top */ + char* old_top = (char*)m->top; + msegmentptr oldsp = segment_holding(m, old_top); + char* old_end = oldsp->base + oldsp->size; + size_t ssize = pad_request(sizeof(struct malloc_segment)); + char* rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK); + size_t offset = align_offset(chunk2mem(rawsp)); + char* asp = rawsp + offset; + char* csp = (asp < (old_top + MIN_CHUNK_SIZE))? old_top : asp; + mchunkptr sp = (mchunkptr)csp; + msegmentptr ss = (msegmentptr)(chunk2mem(sp)); + mchunkptr tnext = chunk_plus_offset(sp, ssize); + mchunkptr p = tnext; + int nfences = 0; + + /* reset top to new space */ + init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); + + /* Set up segment record */ + assert(is_aligned(ss)); + set_size_and_pinuse_of_inuse_chunk(m, sp, ssize); + *ss = m->seg; /* Push current record */ + m->seg.base = tbase; + m->seg.size = tsize; + m->seg.sflags = mmapped; + m->seg.next = ss; + + /* Insert trailing fenceposts */ + for (;;) { + mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE); + p->head = FENCEPOST_HEAD; + ++nfences; + if ((char*)(&(nextp->head)) < old_end) + p = nextp; + else + break; + } + assert(nfences >= 2); + + /* Insert the rest of old top into a bin as an ordinary free chunk */ + if (csp != old_top) { + mchunkptr q = (mchunkptr)old_top; + size_t psize = csp - old_top; + mchunkptr tn = chunk_plus_offset(q, psize); + set_free_with_pinuse(q, psize, tn); + insert_chunk(m, q, psize); + } + + check_top_chunk(m, m->top); +} + +/* -------------------------- System allocation -------------------------- */ + +/* Get memory from system using MORECORE or MMAP */ +static void* sys_alloc(mstate m, size_t nb) { + char* tbase = CMFAIL; + size_t tsize = 0; + flag_t mmap_flag = 0; + size_t asize; /* allocation size */ + + ensure_initialization(); + + /* Directly map large chunks, but only if already initialized */ + if (use_mmap(m) && nb >= mparams.mmap_threshold && m->topsize != 0) { + void* mem = mmap_alloc(m, nb); + if (mem != 0) + return mem; + } + + asize = granularity_align(nb + SYS_ALLOC_PADDING); + if (asize <= nb) + return 0; /* wraparound */ + if (m->footprint_limit != 0) { + size_t fp = m->footprint + asize; + if (fp <= m->footprint || fp > m->footprint_limit) + return 0; + } + + /* + Try getting memory in any of three ways (in most-preferred to + least-preferred order): + 1. A call to MORECORE that can normally contiguously extend memory. + (disabled if not MORECORE_CONTIGUOUS or not HAVE_MORECORE or + or main space is mmapped or a previous contiguous call failed) + 2. A call to MMAP new space (disabled if not HAVE_MMAP). + Note that under the default settings, if MORECORE is unable to + fulfill a request, and HAVE_MMAP is true, then mmap is + used as a noncontiguous system allocator. This is a useful backup + strategy for systems with holes in address spaces -- in this case + sbrk cannot contiguously expand the heap, but mmap may be able to + find space. + 3. A call to MORECORE that cannot usually contiguously extend memory. + (disabled if not HAVE_MORECORE) + + In all cases, we need to request enough bytes from system to ensure + we can malloc nb bytes upon success, so pad with enough space for + top_foot, plus alignment-pad to make sure we don't lose bytes if + not on boundary, and round this up to a granularity unit. + */ + + if (MORECORE_CONTIGUOUS && !use_noncontiguous(m)) { + char* br = CMFAIL; + msegmentptr ss = (m->top == 0)? 0 : segment_holding(m, (char*)m->top); + ACQUIRE_MALLOC_GLOBAL_LOCK(); + + if (ss == 0) { /* First time through or recovery */ + char* base = (char*)CALL_MORECORE(0); + if (base != CMFAIL) { + size_t fp; + /* Adjust to end on a page boundary */ + if (!is_page_aligned(base)) + asize += (page_align((size_t)base) - (size_t)base); + fp = m->footprint + asize; /* recheck limits */ + if (asize > nb && asize < HALF_MAX_SIZE_T && + (m->footprint_limit == 0 || + (fp > m->footprint && fp <= m->footprint_limit)) && + (br = (char*)(CALL_MORECORE(asize))) == base) { + tbase = base; + tsize = asize; + } + } + } + else { + /* Subtract out existing available top space from MORECORE request. */ + asize = granularity_align(nb - m->topsize + SYS_ALLOC_PADDING); + /* Use mem here only if it did continuously extend old space */ + if (asize < HALF_MAX_SIZE_T && + (br = (char*)(CALL_MORECORE(asize))) == ss->base+ss->size) { + tbase = br; + tsize = asize; + } + } + + if (tbase == CMFAIL) { /* Cope with partial failure */ + if (br != CMFAIL) { /* Try to use/extend the space we did get */ + if (asize < HALF_MAX_SIZE_T && + asize < nb + SYS_ALLOC_PADDING) { + size_t esize = granularity_align(nb + SYS_ALLOC_PADDING - asize); + if (esize < HALF_MAX_SIZE_T) { + char* end = (char*)CALL_MORECORE(esize); + if (end != CMFAIL) + asize += esize; + else { /* Can't use; try to release */ + (void) CALL_MORECORE(-asize); + br = CMFAIL; + } + } + } + } + if (br != CMFAIL) { /* Use the space we did get */ + tbase = br; + tsize = asize; + } + else + disable_contiguous(m); /* Don't try contiguous path in the future */ + } + + RELEASE_MALLOC_GLOBAL_LOCK(); + } + + if (HAVE_MMAP && tbase == CMFAIL) { /* Try MMAP */ + char* mp = (char*)(CALL_MMAP(asize)); + if (mp != CMFAIL) { + tbase = mp; + tsize = asize; + mmap_flag = USE_MMAP_BIT; + } + } + + if (HAVE_MORECORE && tbase == CMFAIL) { /* Try noncontiguous MORECORE */ + if (asize < HALF_MAX_SIZE_T) { + char* br = CMFAIL; + char* end = CMFAIL; + ACQUIRE_MALLOC_GLOBAL_LOCK(); + br = (char*)(CALL_MORECORE(asize)); + end = (char*)(CALL_MORECORE(0)); + RELEASE_MALLOC_GLOBAL_LOCK(); + if (br != CMFAIL && end != CMFAIL && br < end) { + size_t ssize = end - br; + if (ssize > nb + TOP_FOOT_SIZE) { + tbase = br; + tsize = ssize; + } + } + } + } + + if (tbase != CMFAIL) { + + if ((m->footprint += tsize) > m->max_footprint) + m->max_footprint = m->footprint; + + if (!is_initialized(m)) { /* first-time initialization */ + if (m->least_addr == 0 || tbase < m->least_addr) + m->least_addr = tbase; + m->seg.base = tbase; + m->seg.size = tsize; + m->seg.sflags = mmap_flag; + m->magic = mparams.magic; + m->release_checks = MAX_RELEASE_CHECK_RATE; + init_bins(m); +#if !ONLY_MSPACES + if (is_global(m)) + init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); + else +#endif + { + /* Offset top by embedded malloc_state */ + mchunkptr mn = next_chunk(mem2chunk(m)); + init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) -TOP_FOOT_SIZE); + } + } + + else { + /* Try to merge with an existing segment */ + msegmentptr sp = &m->seg; + /* Only consider most recent segment if traversal suppressed */ + while (sp != 0 && tbase != sp->base + sp->size) + sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next; + if (sp != 0 && + !is_extern_segment(sp) && + (sp->sflags & USE_MMAP_BIT) == mmap_flag && + segment_holds(sp, m->top)) { /* append */ + sp->size += tsize; + init_top(m, m->top, m->topsize + tsize); + } + else { + if (tbase < m->least_addr) + m->least_addr = tbase; + sp = &m->seg; + while (sp != 0 && sp->base != tbase + tsize) + sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next; + if (sp != 0 && + !is_extern_segment(sp) && + (sp->sflags & USE_MMAP_BIT) == mmap_flag) { + char* oldbase = sp->base; + sp->base = tbase; + sp->size += tsize; + return prepend_alloc(m, tbase, oldbase, nb); + } + else + add_segment(m, tbase, tsize, mmap_flag); + } + } + + if (nb < m->topsize) { /* Allocate from new or extended top space */ + size_t rsize = m->topsize -= nb; + mchunkptr p = m->top; + mchunkptr r = m->top = chunk_plus_offset(p, nb); + r->head = rsize | PINUSE_BIT; + set_size_and_pinuse_of_inuse_chunk(m, p, nb); + check_top_chunk(m, m->top); + check_malloced_chunk(m, chunk2mem(p), nb); + return chunk2mem(p); + } + } + + MALLOC_FAILURE_ACTION; + return 0; +} + +/* ----------------------- system deallocation -------------------------- */ + +/* Unmap and unlink any mmapped segments that don't contain used chunks */ +static size_t release_unused_segments(mstate m) { + size_t released = 0; + int nsegs = 0; + msegmentptr pred = &m->seg; + msegmentptr sp = pred->next; + while (sp != 0) { + char* base = sp->base; + size_t size = sp->size; + msegmentptr next = sp->next; + ++nsegs; + if (is_mmapped_segment(sp) && !is_extern_segment(sp)) { + mchunkptr p = align_as_chunk(base); + size_t psize = chunksize(p); + /* Can unmap if first chunk holds entire segment and not pinned */ + if (!is_inuse(p) && (char*)p + psize >= base + size - TOP_FOOT_SIZE) { + tchunkptr tp = (tchunkptr)p; + assert(segment_holds(sp, (char*)sp)); + if (p == m->dv) { + m->dv = 0; + m->dvsize = 0; + } + else { + unlink_large_chunk(m, tp); + } + if (CALL_MUNMAP(base, size) == 0) { + released += size; + m->footprint -= size; + /* unlink obsoleted record */ + sp = pred; + sp->next = next; + } + else { /* back out if cannot unmap */ + insert_large_chunk(m, tp, psize); + } + } + } + if (NO_SEGMENT_TRAVERSAL) /* scan only first segment */ + break; + pred = sp; + sp = next; + } + /* Reset check counter */ + m->release_checks = ((nsegs > MAX_RELEASE_CHECK_RATE)? + nsegs : MAX_RELEASE_CHECK_RATE); + return released; +} + +static int sys_trim(mstate m, size_t pad) { + size_t released = 0; + ensure_initialization(); + if (pad < MAX_REQUEST && is_initialized(m)) { + pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */ + + if (m->topsize > pad) { + /* Shrink top space in granularity-size units, keeping at least one */ + size_t unit = mparams.granularity; + size_t extra = ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit - + SIZE_T_ONE) * unit; + msegmentptr sp = segment_holding(m, (char*)m->top); + + if (!is_extern_segment(sp)) { + if (is_mmapped_segment(sp)) { + if (HAVE_MMAP && + sp->size >= extra && + !has_segment_link(m, sp)) { /* can't shrink if pinned */ + size_t newsize = sp->size - extra; + /* Prefer mremap, fall back to munmap */ + if ((CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL) || + (CALL_MUNMAP(sp->base + newsize, extra) == 0)) { + released = extra; + } + } + } + else if (HAVE_MORECORE) { + if (extra >= HALF_MAX_SIZE_T) /* Avoid wrapping negative */ + extra = (HALF_MAX_SIZE_T) + SIZE_T_ONE - unit; + ACQUIRE_MALLOC_GLOBAL_LOCK(); + { + /* Make sure end of memory is where we last set it. */ + char* old_br = (char*)(CALL_MORECORE(0)); + if (old_br == sp->base + sp->size) { + char* rel_br = (char*)(CALL_MORECORE(-extra)); + char* new_br = (char*)(CALL_MORECORE(0)); + if (rel_br != CMFAIL && new_br < old_br) + released = old_br - new_br; + } + } + RELEASE_MALLOC_GLOBAL_LOCK(); + } + } + + if (released != 0) { + sp->size -= released; + m->footprint -= released; + init_top(m, m->top, m->topsize - released); + check_top_chunk(m, m->top); + } + } + + /* Unmap any unused mmapped segments */ + if (HAVE_MMAP) + released += release_unused_segments(m); + + /* On failure, disable autotrim to avoid repeated failed future calls */ + if (released == 0 && m->topsize > m->trim_check) + m->trim_check = MAX_SIZE_T; + } + + return (released != 0)? 1 : 0; +} + +/* Consolidate and bin a chunk. Differs from exported versions + of free mainly in that the chunk need not be marked as inuse. +*/ +static void dispose_chunk(mstate m, mchunkptr p, size_t psize) { + mchunkptr next = chunk_plus_offset(p, psize); + if (!pinuse(p)) { + mchunkptr prev; + size_t prevsize = p->prev_foot; + if (is_mmapped(p)) { + psize += prevsize + MMAP_FOOT_PAD; + if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) + m->footprint -= psize; + return; + } + prev = chunk_minus_offset(p, prevsize); + psize += prevsize; + p = prev; + if (RTCHECK(ok_address(m, prev))) { /* consolidate backward */ + if (p != m->dv) { + unlink_chunk(m, p, prevsize); + } + else if ((next->head & INUSE_BITS) == INUSE_BITS) { + m->dvsize = psize; + set_free_with_pinuse(p, psize, next); + return; + } + } + else { + CORRUPTION_ERROR_ACTION(m); + return; + } + } + if (RTCHECK(ok_address(m, next))) { + if (!cinuse(next)) { /* consolidate forward */ + if (next == m->top) { + size_t tsize = m->topsize += psize; + m->top = p; + p->head = tsize | PINUSE_BIT; + if (p == m->dv) { + m->dv = 0; + m->dvsize = 0; + } + return; + } + else if (next == m->dv) { + size_t dsize = m->dvsize += psize; + m->dv = p; + set_size_and_pinuse_of_free_chunk(p, dsize); + return; + } + else { + size_t nsize = chunksize(next); + psize += nsize; + unlink_chunk(m, next, nsize); + set_size_and_pinuse_of_free_chunk(p, psize); + if (p == m->dv) { + m->dvsize = psize; + return; + } + } + } + else { + set_free_with_pinuse(p, psize, next); + } + insert_chunk(m, p, psize); + } + else { + CORRUPTION_ERROR_ACTION(m); + } +} + +/* ---------------------------- malloc --------------------------- */ + +/* allocate a large request from the best fitting chunk in a treebin */ +static void* tmalloc_large(mstate m, size_t nb) { + tchunkptr v = 0; + size_t rsize = -nb; /* Unsigned negation */ + tchunkptr t; + bindex_t idx; + compute_tree_index(nb, idx); + if ((t = *treebin_at(m, idx)) != 0) { + /* Traverse tree for this bin looking for node with size == nb */ + size_t sizebits = nb << leftshift_for_tree_index(idx); + tchunkptr rst = 0; /* The deepest untaken right subtree */ + for (;;) { + tchunkptr rt; + size_t trem = chunksize(t) - nb; + if (trem < rsize) { + v = t; + if ((rsize = trem) == 0) + break; + } + rt = t->child[1]; + t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]; + if (rt != 0 && rt != t) + rst = rt; + if (t == 0) { + t = rst; /* set t to least subtree holding sizes > nb */ + break; + } + sizebits <<= 1; + } + } + if (t == 0 && v == 0) { /* set t to root of next non-empty treebin */ + binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap; + if (leftbits != 0) { + bindex_t i; + binmap_t leastbit = least_bit(leftbits); + compute_bit2idx(leastbit, i); + t = *treebin_at(m, i); + } + } + + while (t != 0) { /* find smallest of tree or subtree */ + size_t trem = chunksize(t) - nb; + if (trem < rsize) { + rsize = trem; + v = t; + } + t = leftmost_child(t); + } + + /* If dv is a better fit, return 0 so malloc will use it */ + if (v != 0 && rsize < (size_t)(m->dvsize - nb)) { + if (RTCHECK(ok_address(m, v))) { /* split */ + mchunkptr r = chunk_plus_offset(v, nb); + assert(chunksize(v) == rsize + nb); + if (RTCHECK(ok_next(v, r))) { + unlink_large_chunk(m, v); + if (rsize < MIN_CHUNK_SIZE) + set_inuse_and_pinuse(m, v, (rsize + nb)); + else { + set_size_and_pinuse_of_inuse_chunk(m, v, nb); + set_size_and_pinuse_of_free_chunk(r, rsize); + insert_chunk(m, r, rsize); + } + return chunk2mem(v); + } + } + CORRUPTION_ERROR_ACTION(m); + } + return 0; +} + +/* allocate a small request from the best fitting chunk in a treebin */ +static void* tmalloc_small(mstate m, size_t nb) { + tchunkptr t, v; + size_t rsize; + bindex_t i; + binmap_t leastbit = least_bit(m->treemap); + compute_bit2idx(leastbit, i); + v = t = *treebin_at(m, i); + rsize = chunksize(t) - nb; + + while ((t = leftmost_child(t)) != 0) { + size_t trem = chunksize(t) - nb; + if (trem < rsize) { + rsize = trem; + v = t; + } + } + + if (RTCHECK(ok_address(m, v))) { + mchunkptr r = chunk_plus_offset(v, nb); + assert(chunksize(v) == rsize + nb); + if (RTCHECK(ok_next(v, r))) { + unlink_large_chunk(m, v); + if (rsize < MIN_CHUNK_SIZE) + set_inuse_and_pinuse(m, v, (rsize + nb)); + else { + set_size_and_pinuse_of_inuse_chunk(m, v, nb); + set_size_and_pinuse_of_free_chunk(r, rsize); + replace_dv(m, r, rsize); + } + return chunk2mem(v); + } + } + + CORRUPTION_ERROR_ACTION(m); + return 0; +} + +#if !ONLY_MSPACES + +void* dlmalloc(size_t bytes) { + /* + Basic algorithm: + If a small request (< 256 bytes minus per-chunk overhead): + 1. If one exists, use a remainderless chunk in associated smallbin. + (Remainderless means that there are too few excess bytes to + represent as a chunk.) + 2. If it is big enough, use the dv chunk, which is normally the + chunk adjacent to the one used for the most recent small request. + 3. If one exists, split the smallest available chunk in a bin, + saving remainder in dv. + 4. If it is big enough, use the top chunk. + 5. If available, get memory from system and use it + Otherwise, for a large request: + 1. Find the smallest available binned chunk that fits, and use it + if it is better fitting than dv chunk, splitting if necessary. + 2. If better fitting than any binned chunk, use the dv chunk. + 3. If it is big enough, use the top chunk. + 4. If request size >= mmap threshold, try to directly mmap this chunk. + 5. If available, get memory from system and use it + + The ugly goto's here ensure that postaction occurs along all paths. + */ + +#if USE_LOCKS + ensure_initialization(); /* initialize in sys_alloc if not using locks */ +#endif + + if (!PREACTION(gm)) { + void* mem; + size_t nb; + if (bytes <= MAX_SMALL_REQUEST) { + bindex_t idx; + binmap_t smallbits; + nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes); + idx = small_index(nb); + smallbits = gm->smallmap >> idx; + + if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */ + mchunkptr b, p; + idx += ~smallbits & 1; /* Uses next bin if idx empty */ + b = smallbin_at(gm, idx); + p = b->fd; + assert(chunksize(p) == small_index2size(idx)); + unlink_first_small_chunk(gm, b, p, idx); + set_inuse_and_pinuse(gm, p, small_index2size(idx)); + mem = chunk2mem(p); + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + + else if (nb > gm->dvsize) { + if (smallbits != 0) { /* Use chunk in next nonempty smallbin */ + mchunkptr b, p, r; + size_t rsize; + bindex_t i; + binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx)); + binmap_t leastbit = least_bit(leftbits); + compute_bit2idx(leastbit, i); + b = smallbin_at(gm, i); + p = b->fd; + assert(chunksize(p) == small_index2size(i)); + unlink_first_small_chunk(gm, b, p, i); + rsize = small_index2size(i) - nb; + /* Fit here cannot be remainderless if 4byte sizes */ + if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) + set_inuse_and_pinuse(gm, p, small_index2size(i)); + else { + set_size_and_pinuse_of_inuse_chunk(gm, p, nb); + r = chunk_plus_offset(p, nb); + set_size_and_pinuse_of_free_chunk(r, rsize); + replace_dv(gm, r, rsize); + } + mem = chunk2mem(p); + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + + else if (gm->treemap != 0 && (mem = tmalloc_small(gm, nb)) != 0) { + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + } + } + else if (bytes >= MAX_REQUEST) + nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ + else { + nb = pad_request(bytes); + if (gm->treemap != 0 && (mem = tmalloc_large(gm, nb)) != 0) { + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + } + + if (nb <= gm->dvsize) { + size_t rsize = gm->dvsize - nb; + mchunkptr p = gm->dv; + if (rsize >= MIN_CHUNK_SIZE) { /* split dv */ + mchunkptr r = gm->dv = chunk_plus_offset(p, nb); + gm->dvsize = rsize; + set_size_and_pinuse_of_free_chunk(r, rsize); + set_size_and_pinuse_of_inuse_chunk(gm, p, nb); + } + else { /* exhaust dv */ + size_t dvs = gm->dvsize; + gm->dvsize = 0; + gm->dv = 0; + set_inuse_and_pinuse(gm, p, dvs); + } + mem = chunk2mem(p); + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + + else if (nb < gm->topsize) { /* Split top */ + size_t rsize = gm->topsize -= nb; + mchunkptr p = gm->top; + mchunkptr r = gm->top = chunk_plus_offset(p, nb); + r->head = rsize | PINUSE_BIT; + set_size_and_pinuse_of_inuse_chunk(gm, p, nb); + mem = chunk2mem(p); + check_top_chunk(gm, gm->top); + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + + mem = sys_alloc(gm, nb); + + postaction: + POSTACTION(gm); + return mem; + } + + return 0; +} + +/* ---------------------------- free --------------------------- */ + +void dlfree(void* mem) { + /* + Consolidate freed chunks with preceeding or succeeding bordering + free chunks, if they exist, and then place in a bin. Intermixed + with special cases for top, dv, mmapped chunks, and usage errors. + */ + + if (mem != 0) { + mchunkptr p = mem2chunk(mem); +#if FOOTERS + mstate fm = get_mstate_for(p); + if (!ok_magic(fm)) { + USAGE_ERROR_ACTION(fm, p); + return; + } +#else /* FOOTERS */ +#define fm gm +#endif /* FOOTERS */ + if (!PREACTION(fm)) { + check_inuse_chunk(fm, p); + if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) { + size_t psize = chunksize(p); + mchunkptr next = chunk_plus_offset(p, psize); + if (!pinuse(p)) { + size_t prevsize = p->prev_foot; + if (is_mmapped(p)) { + psize += prevsize + MMAP_FOOT_PAD; + if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) + fm->footprint -= psize; + goto postaction; + } + else { + mchunkptr prev = chunk_minus_offset(p, prevsize); + psize += prevsize; + p = prev; + if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ + if (p != fm->dv) { + unlink_chunk(fm, p, prevsize); + } + else if ((next->head & INUSE_BITS) == INUSE_BITS) { + fm->dvsize = psize; + set_free_with_pinuse(p, psize, next); + goto postaction; + } + } + else + goto erroraction; + } + } + + if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { + if (!cinuse(next)) { /* consolidate forward */ + if (next == fm->top) { + size_t tsize = fm->topsize += psize; + fm->top = p; + p->head = tsize | PINUSE_BIT; + if (p == fm->dv) { + fm->dv = 0; + fm->dvsize = 0; + } + if (should_trim(fm, tsize)) + sys_trim(fm, 0); + goto postaction; + } + else if (next == fm->dv) { + size_t dsize = fm->dvsize += psize; + fm->dv = p; + set_size_and_pinuse_of_free_chunk(p, dsize); + goto postaction; + } + else { + size_t nsize = chunksize(next); + psize += nsize; + unlink_chunk(fm, next, nsize); + set_size_and_pinuse_of_free_chunk(p, psize); + if (p == fm->dv) { + fm->dvsize = psize; + goto postaction; + } + } + } + else + set_free_with_pinuse(p, psize, next); + + if (is_small(psize)) { + insert_small_chunk(fm, p, psize); + check_free_chunk(fm, p); + } + else { + tchunkptr tp = (tchunkptr)p; + insert_large_chunk(fm, tp, psize); + check_free_chunk(fm, p); + if (--fm->release_checks == 0) + release_unused_segments(fm); + } + goto postaction; + } + } + erroraction: + USAGE_ERROR_ACTION(fm, p); + postaction: + POSTACTION(fm); + } + } +#if !FOOTERS +#undef fm +#endif /* FOOTERS */ +} + +void* dlcalloc(size_t n_elements, size_t elem_size) { + void* mem; + size_t req = 0; + if (n_elements != 0) { + req = n_elements * elem_size; + if (((n_elements | elem_size) & ~(size_t)0xffff) && + (req / n_elements != elem_size)) + req = MAX_SIZE_T; /* force downstream failure on overflow */ + } + mem = dlmalloc(req); + if (mem != 0 && calloc_must_clear(mem2chunk(mem))) + memset(mem, 0, req); + return mem; +} + +#endif /* !ONLY_MSPACES */ + +/* ------------ Internal support for realloc, memalign, etc -------------- */ + +/* Try to realloc; only in-place unless can_move true */ +static mchunkptr try_realloc_chunk(mstate m, mchunkptr p, size_t nb, + int can_move) { + mchunkptr newp = 0; + size_t oldsize = chunksize(p); + mchunkptr next = chunk_plus_offset(p, oldsize); + if (RTCHECK(ok_address(m, p) && ok_inuse(p) && + ok_next(p, next) && ok_pinuse(next))) { + if (is_mmapped(p)) { + newp = mmap_resize(m, p, nb, can_move); + } + else if (oldsize >= nb) { /* already big enough */ + size_t rsize = oldsize - nb; + if (rsize >= MIN_CHUNK_SIZE) { /* split off remainder */ + mchunkptr r = chunk_plus_offset(p, nb); + set_inuse(m, p, nb); + set_inuse(m, r, rsize); + dispose_chunk(m, r, rsize); + } + newp = p; + } + else if (next == m->top) { /* extend into top */ + if (oldsize + m->topsize > nb) { + size_t newsize = oldsize + m->topsize; + size_t newtopsize = newsize - nb; + mchunkptr newtop = chunk_plus_offset(p, nb); + set_inuse(m, p, nb); + newtop->head = newtopsize |PINUSE_BIT; + m->top = newtop; + m->topsize = newtopsize; + newp = p; + } + } + else if (next == m->dv) { /* extend into dv */ + size_t dvs = m->dvsize; + if (oldsize + dvs >= nb) { + size_t dsize = oldsize + dvs - nb; + if (dsize >= MIN_CHUNK_SIZE) { + mchunkptr r = chunk_plus_offset(p, nb); + mchunkptr n = chunk_plus_offset(r, dsize); + set_inuse(m, p, nb); + set_size_and_pinuse_of_free_chunk(r, dsize); + clear_pinuse(n); + m->dvsize = dsize; + m->dv = r; + } + else { /* exhaust dv */ + size_t newsize = oldsize + dvs; + set_inuse(m, p, newsize); + m->dvsize = 0; + m->dv = 0; + } + newp = p; + } + } + else if (!cinuse(next)) { /* extend into next free chunk */ + size_t nextsize = chunksize(next); + if (oldsize + nextsize >= nb) { + size_t rsize = oldsize + nextsize - nb; + unlink_chunk(m, next, nextsize); + if (rsize < MIN_CHUNK_SIZE) { + size_t newsize = oldsize + nextsize; + set_inuse(m, p, newsize); + } + else { + mchunkptr r = chunk_plus_offset(p, nb); + set_inuse(m, p, nb); + set_inuse(m, r, rsize); + dispose_chunk(m, r, rsize); + } + newp = p; + } + } + } + else { + USAGE_ERROR_ACTION(m, oldmem); + } + return newp; +} + +static void* internal_memalign(mstate m, size_t alignment, size_t bytes) { + void* mem = 0; + if (alignment < MIN_CHUNK_SIZE) /* must be at least a minimum chunk size */ + alignment = MIN_CHUNK_SIZE; + if ((alignment & (alignment-SIZE_T_ONE)) != 0) {/* Ensure a power of 2 */ + size_t a = MALLOC_ALIGNMENT << 1; + while (a < alignment) a <<= 1; + alignment = a; + } + if (bytes >= MAX_REQUEST - alignment) { + if (m != 0) { /* Test isn't needed but avoids compiler warning */ + MALLOC_FAILURE_ACTION; + } + } + else { + size_t nb = request2size(bytes); + size_t req = nb + alignment + MIN_CHUNK_SIZE - CHUNK_OVERHEAD; + mem = internal_malloc(m, req); + if (mem != 0) { + mchunkptr p = mem2chunk(mem); + if (PREACTION(m)) + return 0; + if ((((size_t)(mem)) & (alignment - 1)) != 0) { /* misaligned */ + /* + Find an aligned spot inside chunk. Since we need to give + back leading space in a chunk of at least MIN_CHUNK_SIZE, if + the first calculation places us at a spot with less than + MIN_CHUNK_SIZE leader, we can move to the next aligned spot. + We've allocated enough total room so that this is always + possible. + */ + char* br = (char*)mem2chunk((size_t)(((size_t)((char*)mem + alignment - + SIZE_T_ONE)) & + -alignment)); + char* pos = ((size_t)(br - (char*)(p)) >= MIN_CHUNK_SIZE)? + br : br+alignment; + mchunkptr newp = (mchunkptr)pos; + size_t leadsize = pos - (char*)(p); + size_t newsize = chunksize(p) - leadsize; + + if (is_mmapped(p)) { /* For mmapped chunks, just adjust offset */ + newp->prev_foot = p->prev_foot + leadsize; + newp->head = newsize; + } + else { /* Otherwise, give back leader, use the rest */ + set_inuse(m, newp, newsize); + set_inuse(m, p, leadsize); + dispose_chunk(m, p, leadsize); + } + p = newp; + } + + /* Give back spare room at the end */ + if (!is_mmapped(p)) { + size_t size = chunksize(p); + if (size > nb + MIN_CHUNK_SIZE) { + size_t remainder_size = size - nb; + mchunkptr remainder = chunk_plus_offset(p, nb); + set_inuse(m, p, nb); + set_inuse(m, remainder, remainder_size); + dispose_chunk(m, remainder, remainder_size); + } + } + + mem = chunk2mem(p); + assert (chunksize(p) >= nb); + assert(((size_t)mem & (alignment - 1)) == 0); + check_inuse_chunk(m, p); + POSTACTION(m); + } + } + return mem; +} + +/* + Common support for independent_X routines, handling + all of the combinations that can result. + The opts arg has: + bit 0 set if all elements are same size (using sizes[0]) + bit 1 set if elements should be zeroed +*/ +static void** ialloc(mstate m, + size_t n_elements, + size_t* sizes, + int opts, + void* chunks[]) { + + size_t element_size; /* chunksize of each element, if all same */ + size_t contents_size; /* total size of elements */ + size_t array_size; /* request size of pointer array */ + void* mem; /* malloced aggregate space */ + mchunkptr p; /* corresponding chunk */ + size_t remainder_size; /* remaining bytes while splitting */ + void** marray; /* either "chunks" or malloced ptr array */ + mchunkptr array_chunk; /* chunk for malloced ptr array */ + flag_t was_enabled; /* to disable mmap */ + size_t size; + size_t i; + + ensure_initialization(); + /* compute array length, if needed */ + if (chunks != 0) { + if (n_elements == 0) + return chunks; /* nothing to do */ + marray = chunks; + array_size = 0; + } + else { + /* if empty req, must still return chunk representing empty array */ + if (n_elements == 0) + return (void**)internal_malloc(m, 0); + marray = 0; + array_size = request2size(n_elements * (sizeof(void*))); + } + + /* compute total element size */ + if (opts & 0x1) { /* all-same-size */ + element_size = request2size(*sizes); + contents_size = n_elements * element_size; + } + else { /* add up all the sizes */ + element_size = 0; + contents_size = 0; + for (i = 0; i != n_elements; ++i) + contents_size += request2size(sizes[i]); + } + + size = contents_size + array_size; + + /* + Allocate the aggregate chunk. First disable direct-mmapping so + malloc won't use it, since we would not be able to later + free/realloc space internal to a segregated mmap region. + */ + was_enabled = use_mmap(m); + disable_mmap(m); + mem = internal_malloc(m, size - CHUNK_OVERHEAD); + if (was_enabled) + enable_mmap(m); + if (mem == 0) + return 0; + + if (PREACTION(m)) return 0; + p = mem2chunk(mem); + remainder_size = chunksize(p); + + assert(!is_mmapped(p)); + + if (opts & 0x2) { /* optionally clear the elements */ + memset((size_t*)mem, 0, remainder_size - SIZE_T_SIZE - array_size); + } + + /* If not provided, allocate the pointer array as final part of chunk */ + if (marray == 0) { + size_t array_chunk_size; + array_chunk = chunk_plus_offset(p, contents_size); + array_chunk_size = remainder_size - contents_size; + marray = (void**) (chunk2mem(array_chunk)); + set_size_and_pinuse_of_inuse_chunk(m, array_chunk, array_chunk_size); + remainder_size = contents_size; + } + + /* split out elements */ + for (i = 0; ; ++i) { + marray[i] = chunk2mem(p); + if (i != n_elements-1) { + if (element_size != 0) + size = element_size; + else + size = request2size(sizes[i]); + remainder_size -= size; + set_size_and_pinuse_of_inuse_chunk(m, p, size); + p = chunk_plus_offset(p, size); + } + else { /* the final element absorbs any overallocation slop */ + set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size); + break; + } + } + +#if DEBUG + if (marray != chunks) { + /* final element must have exactly exhausted chunk */ + if (element_size != 0) { + assert(remainder_size == element_size); + } + else { + assert(remainder_size == request2size(sizes[i])); + } + check_inuse_chunk(m, mem2chunk(marray)); + } + for (i = 0; i != n_elements; ++i) + check_inuse_chunk(m, mem2chunk(marray[i])); + +#endif /* DEBUG */ + + POSTACTION(m); + return marray; +} + +/* Try to free all pointers in the given array. + Note: this could be made faster, by delaying consolidation, + at the price of disabling some user integrity checks, We + still optimize some consolidations by combining adjacent + chunks before freeing, which will occur often if allocated + with ialloc or the array is sorted. +*/ +static size_t internal_bulk_free(mstate m, void* array[], size_t nelem) { + size_t unfreed = 0; + if (!PREACTION(m)) { + void** a; + void** fence = &(array[nelem]); + for (a = array; a != fence; ++a) { + void* mem = *a; + if (mem != 0) { + mchunkptr p = mem2chunk(mem); + size_t psize = chunksize(p); +#if FOOTERS + if (get_mstate_for(p) != m) { + ++unfreed; + continue; + } +#endif + check_inuse_chunk(m, p); + *a = 0; + if (RTCHECK(ok_address(m, p) && ok_inuse(p))) { + void ** b = a + 1; /* try to merge with next chunk */ + mchunkptr next = next_chunk(p); + if (b != fence && *b == chunk2mem(next)) { + size_t newsize = chunksize(next) + psize; + set_inuse(m, p, newsize); + *b = chunk2mem(p); + } + else + dispose_chunk(m, p, psize); + } + else { + CORRUPTION_ERROR_ACTION(m); + break; + } + } + } + if (should_trim(m, m->topsize)) + sys_trim(m, 0); + POSTACTION(m); + } + return unfreed; +} + +/* Traversal */ +#if MALLOC_INSPECT_ALL +static void internal_inspect_all(mstate m, + void(*handler)(void *start, + void *end, + size_t used_bytes, + void* callback_arg), + void* arg) { + if (is_initialized(m)) { + mchunkptr top = m->top; + msegmentptr s; + for (s = &m->seg; s != 0; s = s->next) { + mchunkptr q = align_as_chunk(s->base); + while (segment_holds(s, q) && q->head != FENCEPOST_HEAD) { + mchunkptr next = next_chunk(q); + size_t sz = chunksize(q); + size_t used; + void* start; + if (is_inuse(q)) { + used = sz - CHUNK_OVERHEAD; /* must not be mmapped */ + start = chunk2mem(q); + } + else { + used = 0; + if (is_small(sz)) { /* offset by possible bookkeeping */ + start = (void*)((char*)q + sizeof(malloc_chunk)); + } + else { + start = (void*)((char*)q + sizeof(malloc_tree_chunk)); + } + } + if (start < (void*)next) /* skip if all space is bookkeeping */ + handler(start, next, used, arg); + if (q == top) + break; + q = next; + } + } + } +} +#endif /* MALLOC_INSPECT_ALL */ + +/* ------------------ Exported realloc, memalign, etc -------------------- */ + +#if !ONLY_MSPACES + +void* dlrealloc(void* oldmem, size_t bytes) { + void* mem = 0; + if (oldmem == 0) { + mem = dlmalloc(bytes); + } + else if (bytes >= MAX_REQUEST) { + MALLOC_FAILURE_ACTION; + } +#ifdef REALLOC_ZERO_BYTES_FREES + else if (bytes == 0) { + dlfree(oldmem); + } +#endif /* REALLOC_ZERO_BYTES_FREES */ + else { + size_t nb = request2size(bytes); + mchunkptr oldp = mem2chunk(oldmem); +#if ! FOOTERS + mstate m = gm; +#else /* FOOTERS */ + mstate m = get_mstate_for(oldp); + if (!ok_magic(m)) { + USAGE_ERROR_ACTION(m, oldmem); + return 0; + } +#endif /* FOOTERS */ + if (!PREACTION(m)) { + mchunkptr newp = try_realloc_chunk(m, oldp, nb, 1); + POSTACTION(m); + if (newp != 0) { + check_inuse_chunk(m, newp); + mem = chunk2mem(newp); + } + else { + mem = internal_malloc(m, bytes); + if (mem != 0) { + size_t oc = chunksize(oldp) - overhead_for(oldp); + memcpy(mem, oldmem, (oc < bytes)? oc : bytes); + internal_free(m, oldmem); + } + } + } + } + return mem; +} + +void* dlrealloc_in_place(void* oldmem, size_t bytes) { + void* mem = 0; + if (oldmem != 0) { + if (bytes >= MAX_REQUEST) { + MALLOC_FAILURE_ACTION; + } + else { + size_t nb = request2size(bytes); + mchunkptr oldp = mem2chunk(oldmem); +#if ! FOOTERS + mstate m = gm; +#else /* FOOTERS */ + mstate m = get_mstate_for(oldp); + if (!ok_magic(m)) { + USAGE_ERROR_ACTION(m, oldmem); + return 0; + } +#endif /* FOOTERS */ + if (!PREACTION(m)) { + mchunkptr newp = try_realloc_chunk(m, oldp, nb, 0); + POSTACTION(m); + if (newp == oldp) { + check_inuse_chunk(m, newp); + mem = oldmem; + } + } + } + } + return mem; +} + +void* dlmemalign(size_t alignment, size_t bytes) { + if (alignment <= MALLOC_ALIGNMENT) { + return dlmalloc(bytes); + } + return internal_memalign(gm, alignment, bytes); +} + +int dlposix_memalign(void** pp, size_t alignment, size_t bytes) { + void* mem = 0; + if (alignment == MALLOC_ALIGNMENT) + mem = dlmalloc(bytes); + else { + size_t d = alignment / sizeof(void*); + size_t r = alignment % sizeof(void*); + if (r != 0 || d == 0 || (d & (d-SIZE_T_ONE)) != 0) + return EINVAL; + else if (bytes >= MAX_REQUEST - alignment) { + if (alignment < MIN_CHUNK_SIZE) + alignment = MIN_CHUNK_SIZE; + mem = internal_memalign(gm, alignment, bytes); + } + } + if (mem == 0) + return ENOMEM; + else { + *pp = mem; + return 0; + } +} + +void* dlvalloc(size_t bytes) { + size_t pagesz; + ensure_initialization(); + pagesz = mparams.page_size; + return dlmemalign(pagesz, bytes); +} + +void* dlpvalloc(size_t bytes) { + size_t pagesz; + ensure_initialization(); + pagesz = mparams.page_size; + return dlmemalign(pagesz, (bytes + pagesz - SIZE_T_ONE) & ~(pagesz - SIZE_T_ONE)); +} + +void** dlindependent_calloc(size_t n_elements, size_t elem_size, + void* chunks[]) { + size_t sz = elem_size; /* serves as 1-element array */ + return ialloc(gm, n_elements, &sz, 3, chunks); +} + +void** dlindependent_comalloc(size_t n_elements, size_t sizes[], + void* chunks[]) { + return ialloc(gm, n_elements, sizes, 0, chunks); +} + +size_t dlbulk_free(void* array[], size_t nelem) { + return internal_bulk_free(gm, array, nelem); +} + +#if MALLOC_INSPECT_ALL +void dlmalloc_inspect_all(void(*handler)(void *start, + void *end, + size_t used_bytes, + void* callback_arg), + void* arg) { + ensure_initialization(); + if (!PREACTION(gm)) { + internal_inspect_all(gm, handler, arg); + POSTACTION(gm); + } +} +#endif /* MALLOC_INSPECT_ALL */ + +int dlmalloc_trim(size_t pad) { + int result = 0; + ensure_initialization(); + if (!PREACTION(gm)) { + result = sys_trim(gm, pad); + POSTACTION(gm); + } + return result; +} + +size_t dlmalloc_footprint(void) { + return gm->footprint; +} + +size_t dlmalloc_max_footprint(void) { + return gm->max_footprint; +} + +size_t dlmalloc_footprint_limit(void) { + size_t maf = gm->footprint_limit; + return maf == 0 ? MAX_SIZE_T : maf; +} + +size_t dlmalloc_set_footprint_limit(size_t bytes) { + size_t result; /* invert sense of 0 */ + if (bytes == 0) + result = granularity_align(1); /* Use minimal size */ + if (bytes == MAX_SIZE_T) + result = 0; /* disable */ + else + result = granularity_align(bytes); + return gm->footprint_limit = result; +} + +#if !NO_MALLINFO +struct mallinfo dlmallinfo(void) { + return internal_mallinfo(gm); +} +#endif /* NO_MALLINFO */ + +#if !NO_MALLOC_STATS +void dlmalloc_stats() { + internal_malloc_stats(gm); +} +#endif /* NO_MALLOC_STATS */ + +int dlmallopt(int param_number, int value) { + return change_mparam(param_number, value); +} + +size_t dlmalloc_usable_size(void* mem) { + if (mem != 0) { + mchunkptr p = mem2chunk(mem); + if (is_inuse(p)) + return chunksize(p) - overhead_for(p); + } + return 0; +} + +#endif /* !ONLY_MSPACES */ + +/* ----------------------------- user mspaces ---------------------------- */ + +#if MSPACES + +static mstate init_user_mstate(char* tbase, size_t tsize) { + size_t msize = pad_request(sizeof(struct malloc_state)); + mchunkptr mn; + mchunkptr msp = align_as_chunk(tbase); + mstate m = (mstate)(chunk2mem(msp)); + memset(m, 0, msize); + (void)INITIAL_LOCK(&m->mutex); + msp->head = (msize|INUSE_BITS); + m->seg.base = m->least_addr = tbase; + m->seg.size = m->footprint = m->max_footprint = tsize; + m->magic = mparams.magic; + m->release_checks = MAX_RELEASE_CHECK_RATE; + m->mflags = mparams.default_mflags; + m->extp = 0; + m->exts = 0; + disable_contiguous(m); + init_bins(m); + mn = next_chunk(mem2chunk(m)); + init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) - TOP_FOOT_SIZE); + check_top_chunk(m, m->top); + return m; +} + +mspace create_mspace(size_t capacity, int locked) { + mstate m = 0; + size_t msize; + ensure_initialization(); + msize = pad_request(sizeof(struct malloc_state)); + if (capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) { + size_t rs = ((capacity == 0)? mparams.granularity : + (capacity + TOP_FOOT_SIZE + msize)); + size_t tsize = granularity_align(rs); + char* tbase = (char*)(CALL_MMAP(tsize)); + if (tbase != CMFAIL) { + m = init_user_mstate(tbase, tsize); + m->seg.sflags = USE_MMAP_BIT; + set_lock(m, locked); + } + } + return (mspace)m; +} + +mspace create_mspace_with_base(void* base, size_t capacity, int locked) { + mstate m = 0; + size_t msize; + ensure_initialization(); + msize = pad_request(sizeof(struct malloc_state)); + if (capacity > msize + TOP_FOOT_SIZE && + capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) { + m = init_user_mstate((char*)base, capacity); + m->seg.sflags = EXTERN_BIT; + set_lock(m, locked); + } + return (mspace)m; +} + +int mspace_track_large_chunks(mspace msp, int enable) { + int ret = 0; + mstate ms = (mstate)msp; + if (!PREACTION(ms)) { + if (!use_mmap(ms)) + ret = 1; + if (!enable) + enable_mmap(ms); + else + disable_mmap(ms); + POSTACTION(ms); + } + return ret; +} + +size_t destroy_mspace(mspace msp) { + size_t freed = 0; + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + msegmentptr sp = &ms->seg; + (void)DESTROY_LOCK(&ms->mutex); /* destroy before unmapped */ + while (sp != 0) { + char* base = sp->base; + size_t size = sp->size; + flag_t flag = sp->sflags; + sp = sp->next; + if ((flag & USE_MMAP_BIT) && !(flag & EXTERN_BIT) && + CALL_MUNMAP(base, size) == 0) + freed += size; + } + } + else { + USAGE_ERROR_ACTION(ms,ms); + } + return freed; +} + +/* + mspace versions of routines are near-clones of the global + versions. This is not so nice but better than the alternatives. +*/ + +void* mspace_malloc(mspace msp, size_t bytes) { + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + return 0; + } + if (!PREACTION(ms)) { + void* mem; + size_t nb; + if (bytes <= MAX_SMALL_REQUEST) { + bindex_t idx; + binmap_t smallbits; + nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes); + idx = small_index(nb); + smallbits = ms->smallmap >> idx; + + if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */ + mchunkptr b, p; + idx += ~smallbits & 1; /* Uses next bin if idx empty */ + b = smallbin_at(ms, idx); + p = b->fd; + assert(chunksize(p) == small_index2size(idx)); + unlink_first_small_chunk(ms, b, p, idx); + set_inuse_and_pinuse(ms, p, small_index2size(idx)); + mem = chunk2mem(p); + check_malloced_chunk(ms, mem, nb); + goto postaction; + } + + else if (nb > ms->dvsize) { + if (smallbits != 0) { /* Use chunk in next nonempty smallbin */ + mchunkptr b, p, r; + size_t rsize; + bindex_t i; + binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx)); + binmap_t leastbit = least_bit(leftbits); + compute_bit2idx(leastbit, i); + b = smallbin_at(ms, i); + p = b->fd; + assert(chunksize(p) == small_index2size(i)); + unlink_first_small_chunk(ms, b, p, i); + rsize = small_index2size(i) - nb; + /* Fit here cannot be remainderless if 4byte sizes */ + if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) + set_inuse_and_pinuse(ms, p, small_index2size(i)); + else { + set_size_and_pinuse_of_inuse_chunk(ms, p, nb); + r = chunk_plus_offset(p, nb); + set_size_and_pinuse_of_free_chunk(r, rsize); + replace_dv(ms, r, rsize); + } + mem = chunk2mem(p); + check_malloced_chunk(ms, mem, nb); + goto postaction; + } + + else if (ms->treemap != 0 && (mem = tmalloc_small(ms, nb)) != 0) { + check_malloced_chunk(ms, mem, nb); + goto postaction; + } + } + } + else if (bytes >= MAX_REQUEST) + nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ + else { + nb = pad_request(bytes); + if (ms->treemap != 0 && (mem = tmalloc_large(ms, nb)) != 0) { + check_malloced_chunk(ms, mem, nb); + goto postaction; + } + } + + if (nb <= ms->dvsize) { + size_t rsize = ms->dvsize - nb; + mchunkptr p = ms->dv; + if (rsize >= MIN_CHUNK_SIZE) { /* split dv */ + mchunkptr r = ms->dv = chunk_plus_offset(p, nb); + ms->dvsize = rsize; + set_size_and_pinuse_of_free_chunk(r, rsize); + set_size_and_pinuse_of_inuse_chunk(ms, p, nb); + } + else { /* exhaust dv */ + size_t dvs = ms->dvsize; + ms->dvsize = 0; + ms->dv = 0; + set_inuse_and_pinuse(ms, p, dvs); + } + mem = chunk2mem(p); + check_malloced_chunk(ms, mem, nb); + goto postaction; + } + + else if (nb < ms->topsize) { /* Split top */ + size_t rsize = ms->topsize -= nb; + mchunkptr p = ms->top; + mchunkptr r = ms->top = chunk_plus_offset(p, nb); + r->head = rsize | PINUSE_BIT; + set_size_and_pinuse_of_inuse_chunk(ms, p, nb); + mem = chunk2mem(p); + check_top_chunk(ms, ms->top); + check_malloced_chunk(ms, mem, nb); + goto postaction; + } + + mem = sys_alloc(ms, nb); + + postaction: + POSTACTION(ms); + return mem; + } + + return 0; +} + +void mspace_free(mspace msp, void* mem) { + if (mem != 0) { + mchunkptr p = mem2chunk(mem); +#if FOOTERS + mstate fm = get_mstate_for(p); + msp = msp; /* placate people compiling -Wunused */ +#else /* FOOTERS */ + mstate fm = (mstate)msp; +#endif /* FOOTERS */ + if (!ok_magic(fm)) { + USAGE_ERROR_ACTION(fm, p); + return; + } + if (!PREACTION(fm)) { + check_inuse_chunk(fm, p); + if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) { + size_t psize = chunksize(p); + mchunkptr next = chunk_plus_offset(p, psize); + if (!pinuse(p)) { + size_t prevsize = p->prev_foot; + if (is_mmapped(p)) { + psize += prevsize + MMAP_FOOT_PAD; + if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) + fm->footprint -= psize; + goto postaction; + } + else { + mchunkptr prev = chunk_minus_offset(p, prevsize); + psize += prevsize; + p = prev; + if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ + if (p != fm->dv) { + unlink_chunk(fm, p, prevsize); + } + else if ((next->head & INUSE_BITS) == INUSE_BITS) { + fm->dvsize = psize; + set_free_with_pinuse(p, psize, next); + goto postaction; + } + } + else + goto erroraction; + } + } + + if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { + if (!cinuse(next)) { /* consolidate forward */ + if (next == fm->top) { + size_t tsize = fm->topsize += psize; + fm->top = p; + p->head = tsize | PINUSE_BIT; + if (p == fm->dv) { + fm->dv = 0; + fm->dvsize = 0; + } + if (should_trim(fm, tsize)) + sys_trim(fm, 0); + goto postaction; + } + else if (next == fm->dv) { + size_t dsize = fm->dvsize += psize; + fm->dv = p; + set_size_and_pinuse_of_free_chunk(p, dsize); + goto postaction; + } + else { + size_t nsize = chunksize(next); + psize += nsize; + unlink_chunk(fm, next, nsize); + set_size_and_pinuse_of_free_chunk(p, psize); + if (p == fm->dv) { + fm->dvsize = psize; + goto postaction; + } + } + } + else + set_free_with_pinuse(p, psize, next); + + if (is_small(psize)) { + insert_small_chunk(fm, p, psize); + check_free_chunk(fm, p); + } + else { + tchunkptr tp = (tchunkptr)p; + insert_large_chunk(fm, tp, psize); + check_free_chunk(fm, p); + if (--fm->release_checks == 0) + release_unused_segments(fm); + } + goto postaction; + } + } + erroraction: + USAGE_ERROR_ACTION(fm, p); + postaction: + POSTACTION(fm); + } + } +} + +void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size) { + void* mem; + size_t req = 0; + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + return 0; + } + if (n_elements != 0) { + req = n_elements * elem_size; + if (((n_elements | elem_size) & ~(size_t)0xffff) && + (req / n_elements != elem_size)) + req = MAX_SIZE_T; /* force downstream failure on overflow */ + } + mem = internal_malloc(ms, req); + if (mem != 0 && calloc_must_clear(mem2chunk(mem))) + memset(mem, 0, req); + return mem; +} + +void* mspace_realloc(mspace msp, void* oldmem, size_t bytes) { + void* mem = 0; + if (oldmem == 0) { + mem = mspace_malloc(msp, bytes); + } + else if (bytes >= MAX_REQUEST) { + MALLOC_FAILURE_ACTION; + } +#ifdef REALLOC_ZERO_BYTES_FREES + else if (bytes == 0) { + mspace_free(msp, oldmem); + } +#endif /* REALLOC_ZERO_BYTES_FREES */ + else { + size_t nb = request2size(bytes); + mchunkptr oldp = mem2chunk(oldmem); +#if ! FOOTERS + mstate m = (mstate)msp; +#else /* FOOTERS */ + mstate m = get_mstate_for(oldp); + if (!ok_magic(m)) { + USAGE_ERROR_ACTION(m, oldmem); + return 0; + } +#endif /* FOOTERS */ + if (!PREACTION(m)) { + mchunkptr newp = try_realloc_chunk(m, oldp, nb, 1); + POSTACTION(m); + if (newp != 0) { + check_inuse_chunk(m, newp); + mem = chunk2mem(newp); + } + else { + mem = mspace_malloc(m, bytes); + if (mem != 0) { + size_t oc = chunksize(oldp) - overhead_for(oldp); + memcpy(mem, oldmem, (oc < bytes)? oc : bytes); + mspace_free(m, oldmem); + } + } + } + } + return mem; +} + +void* mspace_realloc_in_place(mspace msp, void* oldmem, size_t bytes) { + void* mem = 0; + if (oldmem != 0) { + if (bytes >= MAX_REQUEST) { + MALLOC_FAILURE_ACTION; + } + else { + size_t nb = request2size(bytes); + mchunkptr oldp = mem2chunk(oldmem); +#if ! FOOTERS + mstate m = (mstate)msp; +#else /* FOOTERS */ + mstate m = get_mstate_for(oldp); + msp = msp; /* placate people compiling -Wunused */ + if (!ok_magic(m)) { + USAGE_ERROR_ACTION(m, oldmem); + return 0; + } +#endif /* FOOTERS */ + if (!PREACTION(m)) { + mchunkptr newp = try_realloc_chunk(m, oldp, nb, 0); + POSTACTION(m); + if (newp == oldp) { + check_inuse_chunk(m, newp); + mem = oldmem; + } + } + } + } + return mem; +} + +void* mspace_memalign(mspace msp, size_t alignment, size_t bytes) { + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + return 0; + } + if (alignment <= MALLOC_ALIGNMENT) + return mspace_malloc(msp, bytes); + return internal_memalign(ms, alignment, bytes); +} + +void** mspace_independent_calloc(mspace msp, size_t n_elements, + size_t elem_size, void* chunks[]) { + size_t sz = elem_size; /* serves as 1-element array */ + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + return 0; + } + return ialloc(ms, n_elements, &sz, 3, chunks); +} + +void** mspace_independent_comalloc(mspace msp, size_t n_elements, + size_t sizes[], void* chunks[]) { + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + return 0; + } + return ialloc(ms, n_elements, sizes, 0, chunks); +} + +size_t mspace_bulk_free(mspace msp, void* array[], size_t nelem) { + return internal_bulk_free((mstate)msp, array, nelem); +} + +#if MALLOC_INSPECT_ALL +void mspace_inspect_all(mspace msp, + void(*handler)(void *start, + void *end, + size_t used_bytes, + void* callback_arg), + void* arg) { + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + if (!PREACTION(ms)) { + internal_inspect_all(ms, handler, arg); + POSTACTION(ms); + } + } + else { + USAGE_ERROR_ACTION(ms,ms); + } +} +#endif /* MALLOC_INSPECT_ALL */ + +int mspace_trim(mspace msp, size_t pad) { + int result = 0; + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + if (!PREACTION(ms)) { + result = sys_trim(ms, pad); + POSTACTION(ms); + } + } + else { + USAGE_ERROR_ACTION(ms,ms); + } + return result; +} + +#if !NO_MALLOC_STATS +void mspace_malloc_stats(mspace msp) { + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + internal_malloc_stats(ms); + } + else { + USAGE_ERROR_ACTION(ms,ms); + } +} +#endif /* NO_MALLOC_STATS */ + +size_t mspace_footprint(mspace msp) { + size_t result = 0; + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + result = ms->footprint; + } + else { + USAGE_ERROR_ACTION(ms,ms); + } + return result; +} + +size_t mspace_max_footprint(mspace msp) { + size_t result = 0; + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + result = ms->max_footprint; + } + else { + USAGE_ERROR_ACTION(ms,ms); + } + return result; +} + +size_t mspace_footprint_limit(mspace msp) { + size_t result = 0; + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + size_t maf = ms->footprint_limit; + result = (maf == 0) ? MAX_SIZE_T : maf; + } + else { + USAGE_ERROR_ACTION(ms,ms); + } + return result; +} + +size_t mspace_set_footprint_limit(mspace msp, size_t bytes) { + size_t result = 0; + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + if (bytes == 0) + result = granularity_align(1); /* Use minimal size */ + if (bytes == MAX_SIZE_T) + result = 0; /* disable */ + else + result = granularity_align(bytes); + ms->footprint_limit = result; + } + else { + USAGE_ERROR_ACTION(ms,ms); + } + return result; +} + +#if !NO_MALLINFO +struct mallinfo mspace_mallinfo(mspace msp) { + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + } + return internal_mallinfo(ms); +} +#endif /* NO_MALLINFO */ + +size_t mspace_usable_size(void* mem) { + if (mem != 0) { + mchunkptr p = mem2chunk(mem); + if (is_inuse(p)) + return chunksize(p) - overhead_for(p); + } + return 0; +} + +int mspace_mallopt(int param_number, int value) { + return change_mparam(param_number, value); +} + +#endif /* MSPACES */ + + +/* -------------------- Alternative MORECORE functions ------------------- */ + +/* + Guidelines for creating a custom version of MORECORE: + + * For best performance, MORECORE should allocate in multiples of pagesize. + * MORECORE may allocate more memory than requested. (Or even less, + but this will usually result in a malloc failure.) + * MORECORE must not allocate memory when given argument zero, but + instead return one past the end address of memory from previous + nonzero call. + * For best performance, consecutive calls to MORECORE with positive + arguments should return increasing addresses, indicating that + space has been contiguously extended. + * Even though consecutive calls to MORECORE need not return contiguous + addresses, it must be OK for malloc'ed chunks to span multiple + regions in those cases where they do happen to be contiguous. + * MORECORE need not handle negative arguments -- it may instead + just return MFAIL when given negative arguments. + Negative arguments are always multiples of pagesize. MORECORE + must not misinterpret negative args as large positive unsigned + args. You can suppress all such calls from even occurring by defining + MORECORE_CANNOT_TRIM, + + As an example alternative MORECORE, here is a custom allocator + kindly contributed for pre-OSX macOS. It uses virtually but not + necessarily physically contiguous non-paged memory (locked in, + present and won't get swapped out). You can use it by uncommenting + this section, adding some #includes, and setting up the appropriate + defines above: + + #define MORECORE osMoreCore + + There is also a shutdown routine that should somehow be called for + cleanup upon program exit. + + #define MAX_POOL_ENTRIES 100 + #define MINIMUM_MORECORE_SIZE (64 * 1024U) + static int next_os_pool; + void *our_os_pools[MAX_POOL_ENTRIES]; + + void *osMoreCore(int size) + { + void *ptr = 0; + static void *sbrk_top = 0; + + if (size > 0) + { + if (size < MINIMUM_MORECORE_SIZE) + size = MINIMUM_MORECORE_SIZE; + if (CurrentExecutionLevel() == kTaskLevel) + ptr = PoolAllocateResident(size + RM_PAGE_SIZE, 0); + if (ptr == 0) + { + return (void *) MFAIL; + } + // save ptrs so they can be freed during cleanup + our_os_pools[next_os_pool] = ptr; + next_os_pool++; + ptr = (void *) ((((size_t) ptr) + RM_PAGE_MASK) & ~RM_PAGE_MASK); + sbrk_top = (char *) ptr + size; + return ptr; + } + else if (size < 0) + { + // we don't currently support shrink behavior + return (void *) MFAIL; + } + else + { + return sbrk_top; + } + } + + // cleanup any allocated memory pools + // called as last thing before shutting down driver + + void osCleanupMem(void) + { + void **ptr; + + for (ptr = our_os_pools; ptr < &our_os_pools[MAX_POOL_ENTRIES]; ptr++) + if (*ptr) + { + PoolDeallocate(*ptr); + *ptr = 0; + } + } + +*/ + + +/* ----------------------------------------------------------------------- +History: + v2.8.5 Sun May 22 10:26:02 2011 Doug Lea (dl at gee) + * Always perform unlink checks unless INSECURE + * Add posix_memalign. + * Improve realloc to expand in more cases; expose realloc_in_place. + Thanks to Peter Buhr for the suggestion. + * Add footprint_limit, inspect_all, bulk_free. Thanks + to Barry Hayes and others for the suggestions. + * Internal refactorings to avoid calls while holding locks + * Use non-reentrant locks by default. Thanks to Roland McGrath + for the suggestion. + * Small fixes to mspace_destroy, reset_on_error. + * Various configuration extensions/changes. Thanks + to all who contributed these. + + V2.8.4a Thu Apr 28 14:39:43 2011 (dl at gee.cs.oswego.edu) + * Update Creative Commons URL + + V2.8.4 Wed May 27 09:56:23 2009 Doug Lea (dl at gee) + * Use zeros instead of prev foot for is_mmapped + * Add mspace_track_large_chunks; thanks to Jean Brouwers + * Fix set_inuse in internal_realloc; thanks to Jean Brouwers + * Fix insufficient sys_alloc padding when using 16byte alignment + * Fix bad error check in mspace_footprint + * Adaptations for ptmalloc; thanks to Wolfram Gloger. + * Reentrant spin locks; thanks to Earl Chew and others + * Win32 improvements; thanks to Niall Douglas and Earl Chew + * Add NO_SEGMENT_TRAVERSAL and MAX_RELEASE_CHECK_RATE options + * Extension hook in malloc_state + * Various small adjustments to reduce warnings on some compilers + * Various configuration extensions/changes for more platforms. Thanks + to all who contributed these. + + V2.8.3 Thu Sep 22 11:16:32 2005 Doug Lea (dl at gee) + * Add max_footprint functions + * Ensure all appropriate literals are size_t + * Fix conditional compilation problem for some #define settings + * Avoid concatenating segments with the one provided + in create_mspace_with_base + * Rename some variables to avoid compiler shadowing warnings + * Use explicit lock initialization. + * Better handling of sbrk interference. + * Simplify and fix segment insertion, trimming and mspace_destroy + * Reinstate REALLOC_ZERO_BYTES_FREES option from 2.7.x + * Thanks especially to Dennis Flanagan for help on these. + + V2.8.2 Sun Jun 12 16:01:10 2005 Doug Lea (dl at gee) + * Fix memalign brace error. + + V2.8.1 Wed Jun 8 16:11:46 2005 Doug Lea (dl at gee) + * Fix improper #endif nesting in C++ + * Add explicit casts needed for C++ + + V2.8.0 Mon May 30 14:09:02 2005 Doug Lea (dl at gee) + * Use trees for large bins + * Support mspaces + * Use segments to unify sbrk-based and mmap-based system allocation, + removing need for emulation on most platforms without sbrk. + * Default safety checks + * Optional footer checks. Thanks to William Robertson for the idea. + * Internal code refactoring + * Incorporate suggestions and platform-specific changes. + Thanks to Dennis Flanagan, Colin Plumb, Niall Douglas, + Aaron Bachmann, Emery Berger, and others. + * Speed up non-fastbin processing enough to remove fastbins. + * Remove useless cfree() to avoid conflicts with other apps. + * Remove internal memcpy, memset. Compilers handle builtins better. + * Remove some options that no one ever used and rename others. + + V2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee) + * Fix malloc_state bitmap array misdeclaration + + V2.7.1 Thu Jul 25 10:58:03 2002 Doug Lea (dl at gee) + * Allow tuning of FIRST_SORTED_BIN_SIZE + * Use PTR_UINT as type for all ptr->int casts. Thanks to John Belmonte. + * Better detection and support for non-contiguousness of MORECORE. + Thanks to Andreas Mueller, Conal Walsh, and Wolfram Gloger + * Bypass most of malloc if no frees. Thanks To Emery Berger. + * Fix freeing of old top non-contiguous chunk im sysmalloc. + * Raised default trim and map thresholds to 256K. + * Fix mmap-related #defines. Thanks to Lubos Lunak. + * Fix copy macros; added LACKS_FCNTL_H. Thanks to Neal Walfield. + * Branch-free bin calculation + * Default trim and mmap thresholds now 256K. + + V2.7.0 Sun Mar 11 14:14:06 2001 Doug Lea (dl at gee) + * Introduce independent_comalloc and independent_calloc. + Thanks to Michael Pachos for motivation and help. + * Make optional .h file available + * Allow > 2GB requests on 32bit systems. + * new WIN32 sbrk, mmap, munmap, lock code from . + Thanks also to Andreas Mueller , + and Anonymous. + * Allow override of MALLOC_ALIGNMENT (Thanks to Ruud Waij for + helping test this.) + * memalign: check alignment arg + * realloc: don't try to shift chunks backwards, since this + leads to more fragmentation in some programs and doesn't + seem to help in any others. + * Collect all cases in malloc requiring system memory into sysmalloc + * Use mmap as backup to sbrk + * Place all internal state in malloc_state + * Introduce fastbins (although similar to 2.5.1) + * Many minor tunings and cosmetic improvements + * Introduce USE_PUBLIC_MALLOC_WRAPPERS, USE_MALLOC_LOCK + * Introduce MALLOC_FAILURE_ACTION, MORECORE_CONTIGUOUS + Thanks to Tony E. Bennett and others. + * Include errno.h to support default failure action. + + V2.6.6 Sun Dec 5 07:42:19 1999 Doug Lea (dl at gee) + * return null for negative arguments + * Added Several WIN32 cleanups from Martin C. Fong + * Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h' + (e.g. WIN32 platforms) + * Cleanup header file inclusion for WIN32 platforms + * Cleanup code to avoid Microsoft Visual C++ compiler complaints + * Add 'USE_DL_PREFIX' to quickly allow co-existence with existing + memory allocation routines + * Set 'malloc_getpagesize' for WIN32 platforms (needs more work) + * Use 'assert' rather than 'ASSERT' in WIN32 code to conform to + usage of 'assert' in non-WIN32 code + * Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to + avoid infinite loop + * Always call 'fREe()' rather than 'free()' + + V2.6.5 Wed Jun 17 15:57:31 1998 Doug Lea (dl at gee) + * Fixed ordering problem with boundary-stamping + + V2.6.3 Sun May 19 08:17:58 1996 Doug Lea (dl at gee) + * Added pvalloc, as recommended by H.J. Liu + * Added 64bit pointer support mainly from Wolfram Gloger + * Added anonymously donated WIN32 sbrk emulation + * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen + * malloc_extend_top: fix mask error that caused wastage after + foreign sbrks + * Add linux mremap support code from HJ Liu + + V2.6.2 Tue Dec 5 06:52:55 1995 Doug Lea (dl at gee) + * Integrated most documentation with the code. + * Add support for mmap, with help from + Wolfram Gloger (Gloger@lrz.uni-muenchen.de). + * Use last_remainder in more cases. + * Pack bins using idea from colin@nyx10.cs.du.edu + * Use ordered bins instead of best-fit threshhold + * Eliminate block-local decls to simplify tracing and debugging. + * Support another case of realloc via move into top + * Fix error occuring when initial sbrk_base not word-aligned. + * Rely on page size for units instead of SBRK_UNIT to + avoid surprises about sbrk alignment conventions. + * Add mallinfo, mallopt. Thanks to Raymond Nijssen + (raymond@es.ele.tue.nl) for the suggestion. + * Add `pad' argument to malloc_trim and top_pad mallopt parameter. + * More precautions for cases where other routines call sbrk, + courtesy of Wolfram Gloger (Gloger@lrz.uni-muenchen.de). + * Added macros etc., allowing use in linux libc from + H.J. Lu (hjl@gnu.ai.mit.edu) + * Inverted this history list + + V2.6.1 Sat Dec 2 14:10:57 1995 Doug Lea (dl at gee) + * Re-tuned and fixed to behave more nicely with V2.6.0 changes. + * Removed all preallocation code since under current scheme + the work required to undo bad preallocations exceeds + the work saved in good cases for most test programs. + * No longer use return list or unconsolidated bins since + no scheme using them consistently outperforms those that don't + given above changes. + * Use best fit for very large chunks to prevent some worst-cases. + * Added some support for debugging + + V2.6.0 Sat Nov 4 07:05:23 1995 Doug Lea (dl at gee) + * Removed footers when chunks are in use. Thanks to + Paul Wilson (wilson@cs.texas.edu) for the suggestion. + + V2.5.4 Wed Nov 1 07:54:51 1995 Doug Lea (dl at gee) + * Added malloc_trim, with help from Wolfram Gloger + (wmglo@Dent.MED.Uni-Muenchen.DE). + + V2.5.3 Tue Apr 26 10:16:01 1994 Doug Lea (dl at g) + + V2.5.2 Tue Apr 5 16:20:40 1994 Doug Lea (dl at g) + * realloc: try to expand in both directions + * malloc: swap order of clean-bin strategy; + * realloc: only conditionally expand backwards + * Try not to scavenge used bins + * Use bin counts as a guide to preallocation + * Occasionally bin return list chunks in first scan + * Add a few optimizations from colin@nyx10.cs.du.edu + + V2.5.1 Sat Aug 14 15:40:43 1993 Doug Lea (dl at g) + * faster bin computation & slightly different binning + * merged all consolidations to one part of malloc proper + (eliminating old malloc_find_space & malloc_clean_bin) + * Scan 2 returns chunks (not just 1) + * Propagate failure in realloc if malloc returns 0 + * Add stuff to allow compilation on non-ANSI compilers + from kpv@research.att.com + + V2.5 Sat Aug 7 07:41:59 1993 Doug Lea (dl at g.oswego.edu) + * removed potential for odd address access in prev_chunk + * removed dependency on getpagesize.h + * misc cosmetics and a bit more internal documentation + * anticosmetics: mangled names in macros to evade debugger strangeness + * tested on sparc, hp-700, dec-mips, rs6000 + with gcc & native cc (hp, dec only) allowing + Detlefs & Zorn comparison study (in SIGPLAN Notices.) + + Trial version Fri Aug 28 13:14:29 1992 Doug Lea (dl at g.oswego.edu) + * Based loosely on libg++-1.2X malloc. (It retains some of the overall + structure of old version, but most details differ.) + +*/ + diff --git a/scalos/common/saslib/config.mk b/scalos/common/saslib/config.mk new file mode 100755 index 000000000..572580603 --- /dev/null +++ b/scalos/common/saslib/config.mk @@ -0,0 +1,41 @@ +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += # + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += # + + +else + +############################################################################### +# AmigaOS + +LFLAGS += -liconobject -lpm -lguigfx -lpreferences -lcybergraphics \ + -lscalos -lmcpgfx -lgcc -lnix -lnixmain \ + -lamiga21 -lamiga -lstubs + +endif +endif + diff --git a/scalos/common/saslib/makefile-new b/scalos/common/saslib/makefile-new new file mode 100755 index 000000000..eea92ca47 --- /dev/null +++ b/scalos/common/saslib/makefile-new @@ -0,0 +1,155 @@ +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/.. +endif + +############################################################################### + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(OBJDIR)/Scalos.o \ + $(OBJDIR)/MainWait.o \ + $(OBJDIR)/about.o \ + $(OBJDIR)/windowtask.o \ + $(OBJDIR)/Class.o \ + $(OBJDIR)/AppMenu.o \ + $(OBJDIR)/GaugeGadgetClass.o \ + $(OBJDIR)/FileCommands.o \ + $(OBJDIR)/LocaleStrings.o \ + $(OBJDIR)/CLIStart.o \ + $(OBJDIR)/IconWindow_MouseMove.o \ + $(OBJDIR)/DragDropBobs.o \ + $(OBJDIR)/Window.o \ + $(OBJDIR)/Messages.o \ + $(OBJDIR)/ScanDir.o \ + $(OBJDIR)/Splash.o \ + $(OBJDIR)/Prefs.o \ + $(OBJDIR)/wbl.o \ + $(OBJDIR)/ToolTip.o \ + $(OBJDIR)/Lasso.o \ + $(OBJDIR)/ScaLibrary.o \ + $(OBJDIR)/Gadgets.o \ + $(OBJDIR)/ToolTypes.o \ + $(OBJDIR)/Backdrop.o \ + $(OBJDIR)/Subroutines.o \ + $(OBJDIR)/MenuCommand.o \ + $(OBJDIR)/Functions.o \ + $(OBJDIR)/IconImageClass.o \ + $(OBJDIR)/ScalosInit.o \ + $(OBJDIR)/Pattern.o \ + $(OBJDIR)/PopupMenus.o \ + $(OBJDIR)/WindowClass.o \ + $(OBJDIR)/TextIconClass.o \ + $(OBJDIR)/TTLayout.o \ + $(OBJDIR)/IconWindowClass.o \ + $(OBJDIR)/TextWindowClass.o \ + $(OBJDIR)/DeviceWindowClass.o \ + $(OBJDIR)/FontUtil.o \ + $(OBJDIR)/RootClass.o \ + $(OBJDIR)/DevListClass.o \ + $(OBJDIR)/FileTransClass.o \ + $(OBJDIR)/TitleClass.o \ + $(OBJDIR)/Menu.o \ + $(OBJDIR)/GadgetBarClass.o \ + $(OBJDIR)/GadgetBarImageClass.o \ + $(OBJDIR)/GadgetBarTextClass.o \ + $(OBJDIR)/Request.o \ + $(OBJDIR)/Scalos_Cx.o \ + $(OBJDIR)/IconifyClass.o \ + $(OBJDIR)/WBStartup.o \ + $(OBJDIR)/filetypes.o \ + $(OBJDIR)/DefIcons.o \ + $(OBJDIR)/Patches.o \ + $(OBJDIR)/idcmp.o \ + $(OBJDIR)/int64.o \ + $(OBJDIR)/ButtonGadgetClass.o \ + $(OBJDIR)/cleanup.o \ + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Some lame deps +# + +Scalos_Locale.h : Scalos.cd + catcomp scalos.cd vb=1 cfile=Scalos_locale.h + + +MsgIdNames.h : Scalos_Locale.h + GenMsgIdNames Scalos_Locale.h MsgIdNames.h + + + +############################################################################## +# +# Target +# + +NAME = Scalos +NAME_DB = Scalos.debug + +############################################################################## +# +# Subdirs +# + +SUBDIRS = Tools \ +# std_includes/sfd \ +# Catalogs/dansk/Scalos \ +# Catalogs/español/Scalos \ +# Catalogs/français/Scalos \ +# Catalogs/ÃeÓtina/Scalos \ +# Catalogs/sample/Scalos \ +# Catalogs/deutsch/Scalos \ +# Catalogs/polski/Scalos \ + + +############################################################################## + +.PHONY: all install clean bump dump + +all: $(NAME) \ + $(NAME_DB) \ + all_subdirs \ + +############################################################################## + +$(NAME): $(OBJS) + $(ECHO) "Link $(NAME)" + $(CC) -s $(STARTUP) $(OBJS) $(LFLAGS) $(DEFINES) -o $(NAME) + + +$(NAME_DB): $(OBJS) + $(ECHO) "Link $(NAME_DB)" + $(CC) $(STARTUP) $(OBJS) $(LFLAGS) $(DEFINES) -o $(NAME_DB) + +############################################################################## + +install: + install_subdirs + copy Scalos Scalos: clone + copy "catalogs/deutsch/Scalos/Scalos.catalog" "Locale:Catalogs/Deutsch/Scalos/" clone + copy "catalogs/polski/Scalos/Scalos.catalog" "Locale:Catalogs/Polski/Scalos/" clone + copy "catalogs/français/Scalos/Scalos.catalog" "Locale:Catalogs/français/Scalos/" clone + copy "catalogs/ÃeÓtina/Scalos/Scalos.catalog" "Locale:Catalogs/ÃeÓtina/Scalos/" clone + copy "catalogs/dansk/Scalos/Scalos.catalog" "Locale:Catalogs/dansk/Scalos/" clone + copy "catalogs/español/Scalos/Scalos.catalog" "Locale:Catalogs/español/Scalos/" clone + +clean: + clean_subdirs + $(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(NAME) $(NAME_DB) *.dump *_str.* + $(RM) -fv $(BINDIR)/$(NAME) + +############################################################################## diff --git a/scalos/common/saslib/saslib.c b/scalos/common/saslib/saslib.c new file mode 100644 index 000000000..3f7119878 --- /dev/null +++ b/scalos/common/saslib/saslib.c @@ -0,0 +1,44 @@ +// saslib.c +// $Date$ + +#include +#include +#include "saslib.h" + + +#ifndef __SASC +// Replacement for SAS/C library functions + +char *stpblk(const char *q) +{ + while (q && *q && isspace((int) *q)) + q++; + + return (char *) q; +} + +int stccpy(char *dest, const char *src, int MaxLen) +{ + int Count = 0; + + while (*src && MaxLen > 1) + { + *dest++ = *src++; + MaxLen--; + Count++; + } + *dest = '\0'; + Count++; + + return Count; +} + +void strins(char *to, const char *from) +{ + size_t fromLength = strlen(from); + char *dest = to + fromLength; + + memmove(dest, to, 1 + strlen(to)); + strncpy(to, from, fromLength); +} +#endif /* __SASC */ diff --git a/scalos/common/saslib/saslib.h b/scalos/common/saslib/saslib.h new file mode 100644 index 000000000..7384e916b --- /dev/null +++ b/scalos/common/saslib/saslib.h @@ -0,0 +1,15 @@ +// saslib.h +// $Date$ + +#ifndef SASLIB_H_INCLUDED +#define SASLIB_H_INCLUDED + +#ifndef __SASC + +extern char *stpblk(const char *); +extern int stccpy(char *, const char *, int); +extern void strins(char *to, const char *from); + +#endif /* __SASC */ + +#endif /* SASLIB_H_INCLUDED */ diff --git a/scalos/config.mk b/scalos/config.mk new file mode 100755 index 000000000..3b52ddf6b --- /dev/null +++ b/scalos/config.mk @@ -0,0 +1,280 @@ +# $Date: 2012-08-10 13:47:28 +0200 (Fr, 10. Aug 2012) $ +# $Revision: 915 $ +############################################################# + +SHELL = /bin/sh +# On OS4 use gmake to build Scalos + +############################################################################## + +ifndef MACHINE + MACHINE := $(shell gcc $(CFLAGS) -dumpmachine) +endif + +ifeq ($(MAKECMDGOALS),install) + SVNVERSION := "0000" +endif +ifeq ($(MAKECMDGOALS),clean) + SVNVERSION := "0000" +endif +ifeq ($(MAKECMDGOALS),nodebug) + SVNVERSION := "0000" +endif +ifndef SVNVERSION + SVNVERSION := $(shell svnversion -n) +endif + +############################################################################## + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################## +# MorphOS +############################################################################## + +CC = gcc + +ifndef GCCVERSION + GCCVERSION := $(shell $(CC) $(CFLAGS) -dumpversion) +endif + +#ifneq ($(GCCVERSION), 4.4.4) +# CC = gcc4 +# GCCVERSION := $(shell $(CC) $(CFLAGS) -dumpversion) +#endif + +AS = ppc-morphos-as +LD = ppc-morphos-ld +AR = ppc-morphos-ar +RANLIB = ppc-morphos-ranlib +STRIP = ppc-morphos-strip +DUMP = ppc-morphos-objdump + +CODETYPE = PPC + +WARNINGS = -Wall -Wno-parentheses -Wunused -Wuninitialized -Winline + +ifeq ($(GCCVERSION), 4.4.5) + WARNINGS += -Wno-pointer-sign +endif +ifeq ($(GCCVERSION), 4.4.4) + WARNINGS += -Wno-pointer-sign +endif +ifeq ($(GCCVERSION), 4.0.4) + WARNINGS += -Wno-pointer-sign +endif +CPU = -mcpu=604e +#CPU += -maltivec + +OPTIONS = -noixemul -mregnames -mmultiple -mno-prototype -mfused-madd -funsigned-char + +OPTIMIZE = -O2 -fomit-frame-pointer -fschedule-insns2 -fbranch-count-reg -fno-strict-aliasing + +INCLUDES = -I$(TOPLEVEL)/ppc-mos-include -I$(TOPLEVEL)/include + +DEBUG = -g -gstabs + +LFLAGS = -L $(TOPLEVEL)/ppc-mos-gcc-lib \ + -noixemul -laboxstubs -ldebug + +CFLAGS = $(WARNINGS) $(OPTIMIZE) $(DEBUG) $(CPU) $(OPTIONS) $(INCLUDES) -I. + +SFLAGS = --remove-section .comment + +DFLAGS = --syms --reloc --disassemble-all + +OBJDIR = .obj_mos +BINDIR = .bin_mos + +############################################################################ + +DEFINES = -D$(CODETYPE) -D__MORPHOS__ -DAMIGA -DSVN_VERSION="$(SVNVERSION)" + +############################################################################## +# End of MorphOS +############################################################################## + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################## +# AmigaOS4 +############################################################################## + +CC = ppc-amigaos-gcc +AS = ppc-amigaos-as +LD = ppc-amigaos-ld +AR = ppc-amigaos-ar +RANLIB = ppc-amigaos-ranlib +STRIP = ppc-amigaos-strip +DUMP = ppc-amigaos-objdump + +CODETYPE = PPC + +WARNINGS = -Wall -Wno-parentheses -Wunused -Wuninitialized + +CPU = + +OS4_CRT = newlib + +OPTIONS = -mcrt=$(OS4_CRT) + +OPTIMIZE = -O2 -fomit-frame-pointer -fschedule-insns2 -fbranch-count-reg -fno-strict-aliasing + +INCLUDES = -I$(TOPLEVEL)/ppc-aos4-include -I$(TOPLEVEL)/include + +DEBUG = -g -gstabs + +LFLAGS = -mcrt=$(OS4_CRT) -L $(TOPLEVEL)/ppc-aos4-gcc-lib \ + -lm -ldebug + +CFLAGS = $(WARNINGS) $(OPTIMIZE) $(DEBUG) $(CPU) $(OPTIONS) $(INCLUDES) -I. + +SFLAGS = --remove-section .comment + +DFLAGS = --syms --reloc --disassemble-all + +OBJDIR = .obj_os4 +BINDIR = .bin_os4 + +############################################################################ + +OS4LIBBASE = -D__NOLIBBASE__ +DEFINES = -D$(CODETYPE) -D__USE_INLINE__ $(OS4LIBBASE) -Dstccpy=strlcpy \ + -DSVN_VERSION="$(SVNVERSION)" + +############################################################################## +# End of AmigaOS4 +############################################################################## + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################## +# i386-AROS +############################################################################## + +CC = i386-linux-aros-gcc +AS = i386-linux-aros-as +LD = i386-linux-aros-ld +AR = i386-linux-aros-ar +RANLIB = i386-linux-aros-ranlib +STRIP = i386-linux-aros-strip +DUMP = i386-linux-aros-objdump + +CODETYPE = + +WARNINGS = -Wall -Wno-parentheses -Wunused -Wuninitialized -Wno-pointer-sign + +CPU = + +OPTIONS = -D__USE_BASETYPE__ + +OPTIMIZE = -O2 -fomit-frame-pointer -fschedule-insns2 -fbranch-count-reg -fno-strict-aliasing + +INCLUDES = -I$(TOPLEVEL)/include + +DEBUG = -g -gstabs + +LFLAGS = -lm + +CFLAGS = $(WARNINGS) $(OPTIMIZE) $(DEBUG) $(CPU) $(OPTIONS) $(INCLUDES) -I. + +SFLAGS = --remove-section .comment --strip-unneeded + +DFLAGS = --syms --reloc --disassemble-all + +OBJDIR = .obj_i386-aros +BINDIR = .bin_i386-aros + +############################################################################ + +DEFINES = -DAMIGA -DSVN_VERSION="$(SVNVERSION)" + +############################################################################## +# End of i386-aros +############################################################################## + +else + +############################################################################## +# AmigaOS GCC +############################################################################## + +CC = m68k-amigaos-gcc +#AS = m68k-amigaos-as +AS = SYS:bin/PhxAss +LD = m68k-amigaos-ld +AR = m68k-amigaos-ar +RANLIB = m68k-amigaos-ranlib +STRIP = m68k-amigaos-strip +DUMP = m68k-amigaos-objdump + +CODETYPE = M68K + +WARNINGS = -Wall -Wno-parentheses -Wno-unused -Wno-missing-braces \ + -Wno-multichar + +CPU = -m68020-60 + +OPTIONS = -noixemul -msoft-float -fno-strict-aliasing + +OPTIMIZE = -O2 -fomit-frame-pointer + +INCLUDES = -I$(TOPLEVEL)/include -Igg:include -Iinclude: + +DEBUG = -g + +LFLAGS = -noixemul -L $(TOPLEVEL)/68k-gcc-lib \ + -Lgg:lib -Lgg:lib/libnix + +CFLAGS = $(WARNINGS) $(OPTIMIZE) $(DEBUG) $(CPU) $(OPTIONS) $(INCLUDES) -I. + +SFLAGS = --strip-all --strip-unneeded --remove-section .comment + +DFLAGS = --syms --reloc --disassemble-all + +ASFLAGS = quiet m=68020 linedebug opt=NRQB i=sc:Assembler_Headers/ + +LIBPATH = gg:lib + +STARTUP = $(LIBPATH)/libnix/ncrt0.o +#STARTUP = $(LIBPATH)/libnix/detach.o gg:lib/asm_debug.o + +OBJDIR = .obj_os3 +BINDIR = .bin_os3 + +############################################################################## + +DEFINES = -D$(CODETYPE) -DSVN_VERSION=$(SVNVERSION) + +############################################################################## +# End of AmigaOS GCC +############################################################################## + +endif +endif +endif + +############################################################################## + +#MAKE = make +CD = cd +CP = cp +RM = rm +ECHO = echo +MKDIR = mkdir +LN = ln +SED = sed +CATCOMP = CatComp +FLEXCAT = flexcat + +############################################################################## + +TOOLSDIR = $(TOPLEVEL)/tools + +############################################################################## + +FIXDEPS = $(TOOLSDIR)/fixdeps + +############################################################################## diff --git a/scalos/datatypes/AmigaIconObj3.5/AmigaIconObj35-aos4.c b/scalos/datatypes/AmigaIconObj3.5/AmigaIconObj35-aos4.c new file mode 100644 index 000000000..948f2ef21 --- /dev/null +++ b/scalos/datatypes/AmigaIconObj3.5/AmigaIconObj35-aos4.c @@ -0,0 +1,191 @@ +// AmigaIconObj35-aos4.c +// $Date$ +// $Revision$ + + +#include +#include +#include + +#include +#include + +#include + +#include "AmigaIconObj35.h" + +int _start(void) +{ + return -1; +} + +static struct Library *Initlib(struct Library *libbase, BPTR seglist, struct ExecIFace *pIExec); +static BPTR Expungelib(struct LibraryManagerInterface *Self); +static struct LibraryHeader *Openlib(struct LibraryManagerInterface *Self, ULONG version); +static BPTR Closelib(struct LibraryManagerInterface *Self); +static ULONG Obtainlib(struct LibraryManagerInterface *Self); +static ULONG Releaselib(struct LibraryManagerInterface *Self); + +extern struct ExecBase *SysBase; + +/* OS4.0 Library */ + +/* ------------------- OS4 Manager Interface ------------------------ */ +static const APTR managerfunctable[] = + { + (APTR)Obtainlib, + (APTR)Releaselib, + (APTR)NULL, + (APTR)NULL, + (APTR)Openlib, + (APTR)Closelib, + (APTR)Expungelib, + (APTR)NULL, + (APTR)-1 + }; + +static const struct TagItem managertags[] = + { + {MIT_Name, (ULONG)"__library"}, + {MIT_VectorTable, (ULONG)managerfunctable}, + {MIT_Version, 1}, + {TAG_DONE, 0} + }; + +/* ---------------------- OS4 Main Interface ------------------------ */ +static APTR functable[] = + { + Obtainlib, + Releaselib, + NULL, + NULL, + ObtainInfoEngine, + (APTR) -1 + }; + +static const struct TagItem maintags[] = + { + {MIT_Name, (ULONG)"main"}, + {MIT_VectorTable, (ULONG)functable}, + {MIT_Version, 1}, + {TAG_DONE, 0} + }; + +/* Init table used in library initialization. */ +static const ULONG interfaces[] = + { + (ULONG)managertags, + (ULONG)maintags, + (ULONG)0 + }; + +static const struct TagItem inittab[] = + { + {CLT_DataSize, (ULONG)sizeof(struct AmigaIconObj35DtLibBase)}, + {CLT_Interfaces, (ULONG) interfaces}, +// {CLT_Vector68K, (ULONG)VecTable68K}, + {CLT_InitFunc, (ULONG) Initlib}, + {TAG_DONE, 0} + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, + RTF_NATIVE | RTF_AUTOINIT, + LIB_VERSION, + NT_LIBRARY, + 0, + libName, + libIdString, + (struct TagItem *)inittab + }; + +/* ------------------- OS4 Manager Functions ------------------------ */ +static struct Library * Initlib(struct Library *libbase, BPTR seglist, struct ExecIFace *pIExec) +{ + struct AmigaIconObj35DtLibBase *IconObjLibBase = (struct AmigaIconObj35DtLibBase *) libbase; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)libbase + libbase->lib_PosSize); + struct LibraryManagerInterface *Self = (struct LibraryManagerInterface *) ExtLib->ILibrary; + + SysBase = (struct ExecBase *)pIExec->Data.LibBase; + IExec = pIExec; + IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_Revision = LIB_REVISION; + IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_Node.ln_Pri = 7; + IconObjLibBase->nib_SegList = (struct SegList *)seglist; + + if (!InitDatatype(IconObjLibBase)) + { + Expungelib(Self); + IconObjLibBase = NULL; + } + + return (struct Library *)IconObjLibBase; +} + +static BPTR Expungelib(struct LibraryManagerInterface *Self) +{ + struct AmigaIconObj35DtLibBase *IconObjLibBase = (struct AmigaIconObj35DtLibBase *) Self->Data.LibBase; + + if (0 == IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + struct SegList *libseglist = IconObjLibBase->nib_SegList; + + Remove((struct Node *) IconObjLibBase); + CloseDatatype(IconObjLibBase); + DeleteLibrary((struct Library *)IconObjLibBase); + + return (BPTR)libseglist; + } + + IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_Flags |= LIBF_DELEXP; + + return (BPTR)NULL; +} + +static struct LibraryHeader *Openlib(struct LibraryManagerInterface *Self, ULONG version) +{ + struct AmigaIconObj35DtLibBase *IconObjLibBase = (struct AmigaIconObj35DtLibBase *) Self->Data.LibBase; + + IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_OpenCnt++; + IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_Flags &= ~LIBF_DELEXP; + + if (!OpenDatatype(IconObjLibBase)) + { + Closelib(Self); + return NULL; + } + + return (struct LibraryHeader *)IconObjLibBase; +} + +static BPTR Closelib(struct LibraryManagerInterface *Self) +{ + struct AmigaIconObj35DtLibBase *IconObjLibBase = (struct AmigaIconObj35DtLibBase *) Self->Data.LibBase; + + IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_OpenCnt--; +/* + if (0 == IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + if (IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_Flags & LIBF_DELEXP) + { + return Expungelib(Self); + } + } +*/ + return (BPTR)NULL; +} + +static ULONG Obtainlib(struct LibraryManagerInterface *Self) +{ + return(Self->Data.RefCount++); +} + +static ULONG Releaselib(struct LibraryManagerInterface *Self) +{ + return(Self->Data.RefCount--); +} + diff --git a/scalos/datatypes/AmigaIconObj3.5/AmigaIconObj35-aros.c b/scalos/datatypes/AmigaIconObj3.5/AmigaIconObj35-aros.c new file mode 100644 index 000000000..0a9ec3cdb --- /dev/null +++ b/scalos/datatypes/AmigaIconObj3.5/AmigaIconObj35-aros.c @@ -0,0 +1,212 @@ +// amigaiconobj35-classic.c +// $Date$ +// $Revision$ + + +#include +#include + +#include + +#include + + +#include "AmigaIconObj35.h" + +//---------------------------------------------------------------------------- + +extern struct ExecBase *SysBase; + +struct Library *aroscbase; + +//---------------------------------------------------------------------------- + +// Standard library functions + +static AROS_UFP3 (struct Library *, Initlib, + AROS_UFPA(struct Library *, libbase, D0), + AROS_UFPA(struct SegList *, seglist, A0), + AROS_UFPA(struct ExecBase *, sysbase, A6) +); +static AROS_LD1 (struct Library *, Openlib, + AROS_LPA (__unused ULONG, version, D0), + struct Library *, libbase, 1, AmigaIconObject35 +); +static AROS_LD0 (struct SegList *, Closelib, + struct Library *, base, 2, AmigaIconObject35 +); +static AROS_LD1 (struct SegList *, Expungelib, + AROS_LPA(__unused struct Library *, __extrabase, D0), + struct Library *, libbase, 3, AmigaIconObject35 +); +static AROS_LD0 (ULONG, Extfunclib, + __unused struct Library *, libbase, 4, AmigaIconObject35 +); + +//---------------------------------------------------------------------------- + +SAVEDS(LONG) ASM Libstart(void) +{ + return -1; +} + +//---------------------------------------------------------------------------- + +/* OS3.x Library */ + +static APTR functable[] = + { + AmigaIconObject35_1_Openlib, + AmigaIconObject35_2_Closelib, + AmigaIconObject35_3_Expungelib, + AmigaIconObject35_4_Extfunclib, + Dummy_0_ObtainInfoEngine, + (APTR) -1 + }; + +/* Init table used in library initialization. */ +static ULONG inittab[] = + { + sizeof(struct AmigaIconObj35DtLibBase), + (ULONG) functable, + 0, + (ULONG) Initlib + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, + RTF_AUTOINIT, + LIB_VERSION, + NT_LIBRARY, + 0, + libName, + libIdString, + inittab + }; + +//---------------------------------------------------------------------------- + +static AROS_UFH3(struct Library *, Initlib, + AROS_UFHA(struct Library *, libbase, D0), + AROS_UFHA(struct SegList *, seglist, A0), + AROS_UFHA(struct ExecBase *, sysbase, A6) +) +{ + AROS_USERFUNC_INIT + + struct AmigaIconObj35DtLibBase *dtLib = (struct AmigaIconObj35DtLibBase *) libbase; + + SysBase = sysbase; + dtLib->nib_ClassLibrary.cl_Lib.lib_Revision = LIB_REVISION; + dtLib->nib_ClassLibrary.cl_Lib.lib_Node.ln_Pri = 7; + dtLib->nib_SegList = seglist; + + aroscbase = OpenLibrary("arosc.library", 0); + + if (!aroscbase || !InitDatatype(dtLib)) + { + AmigaIconObject35_3_Expungelib(&dtLib->nib_ClassLibrary.cl_Lib, &dtLib->nib_ClassLibrary.cl_Lib); + dtLib = NULL; + } + + return dtLib ? &dtLib->nib_ClassLibrary.cl_Lib : NULL; + + AROS_USERFUNC_EXIT +} + + +static AROS_LH1(struct Library *, Openlib, + AROS_LHA(__unused ULONG, version, D0), + struct Library *, libbase, 1, AmigaIconObject35 +) +{ + AROS_LIBFUNC_INIT + + struct AmigaIconObj35DtLibBase *dtLib = (struct AmigaIconObj35DtLibBase *) libbase; + + dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt++; + dtLib->nib_ClassLibrary.cl_Lib.lib_Flags &= ~LIBF_DELEXP; + + if (!OpenDatatype(dtLib)) + { + AmigaIconObject35_2_Closelib(&dtLib->nib_ClassLibrary.cl_Lib); + return NULL; + } + + return &dtLib->nib_ClassLibrary.cl_Lib; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH0(struct SegList *, Closelib, + struct Library *, libbase, 2, AmigaIconObject35 +) +{ + AROS_LIBFUNC_INIT + + struct AmigaIconObj35DtLibBase *dtLib = (struct AmigaIconObj35DtLibBase *) libbase; + + dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt--; + + if (0 == dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + if (dtLib->nib_ClassLibrary.cl_Lib.lib_Flags & LIBF_DELEXP) + { + return AmigaIconObject35_3_Expungelib(&dtLib->nib_ClassLibrary.cl_Lib, &dtLib->nib_ClassLibrary.cl_Lib); + } + } + + return NULL; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH1(struct SegList *, Expungelib, + AROS_LHA(__unused struct Library *, __extrabase, D0), + struct Library *, libbase, 3, AmigaIconObject35 +) +{ + AROS_LIBFUNC_INIT + + struct AmigaIconObj35DtLibBase *dtLib = (struct AmigaIconObj35DtLibBase *) libbase; + + if (0 == dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + ULONG size = dtLib->nib_ClassLibrary.cl_Lib.lib_NegSize + dtLib->nib_ClassLibrary.cl_Lib.lib_PosSize; + UBYTE *ptr = (UBYTE *) dtLib - dtLib->nib_ClassLibrary.cl_Lib.lib_NegSize; + struct SegList *libseglist = dtLib->nib_SegList; + + Remove((struct Node *) dtLib); + CloseDatatype(dtLib); + FreeMem(ptr,size); + + CloseLibrary(aroscbase); + + return libseglist; + } + + dtLib->nib_ClassLibrary.cl_Lib.lib_Flags |= LIBF_DELEXP; + + return NULL; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH0(ULONG, Extfunclib, + __unused struct Library *, libbase, 4, AmigaIconObject35 +) +{ + AROS_LIBFUNC_INIT + + return 0; + + AROS_LIBFUNC_EXIT +} diff --git a/scalos/datatypes/AmigaIconObj3.5/AmigaIconObj35-classic.c b/scalos/datatypes/AmigaIconObj3.5/AmigaIconObj35-classic.c new file mode 100644 index 000000000..9f5cc1480 --- /dev/null +++ b/scalos/datatypes/AmigaIconObj3.5/AmigaIconObj35-classic.c @@ -0,0 +1,172 @@ +// amigaiconobj35-classic.c +// $Date$ +// $Revision$ + + +#include +#include + +#include + +#include + + +#include "AmigaIconObj35.h" + +//---------------------------------------------------------------------------- + +extern struct ExecBase *SysBase; + +//---------------------------------------------------------------------------- + +static LIB_SAVEDS(struct Library *) LIB_ASM LIB_INTERRUPT Initlib(LIB_REG(d0, struct Library *libbase), + LIB_REG(a0, struct SegList *seglist), LIB_REG(a6, struct ExecBase *sysbase)); + +static LIBFUNC_PROTO(Openlib, libbase, struct Library *); +static LIBFUNC_PROTO(Closelib, libbase, struct SegList *); +static LIBFUNC_PROTO(Expungelib, libbase, struct SegList *); +static LIBFUNC_PROTO(Extfunclib, libbase, ULONG); + +//---------------------------------------------------------------------------- + +/* OS3.x Library */ + +static APTR functable[] = + { +#ifdef __MORPHOS__ + (APTR) FUNCARRAY_32BIT_NATIVE, +#endif + Openlib, + Closelib, + Expungelib, + Extfunclib, + ObtainInfoEngine, + (APTR) -1 + }; + +/* Init table used in library initialization. */ +static ULONG inittab[] = + { + sizeof(struct AmigaIconObj35DtLibBase), + (ULONG) functable, + 0, + (ULONG) Initlib + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, +#ifdef __MORPHOS__ + RTF_PPC | RTF_AUTOINIT, +#else + RTF_AUTOINIT, +#endif + LIB_VERSION, + NT_LIBRARY, + 0, + libName, + libIdString, + inittab + }; + +#ifdef __MORPHOS__ +ULONG __abox__=1; +#endif + +//---------------------------------------------------------------------------- + +static LIB_SAVEDS(struct Library *) LIB_ASM LIB_INTERRUPT Initlib(LIB_REG(d0, struct Library *libbase), + LIB_REG(a0, struct SegList *seglist), LIB_REG(a6, struct ExecBase *sysbase)) +{ + struct AmigaIconObj35DtLibBase *dtLib = (struct AmigaIconObj35DtLibBase *) libbase; + + SysBase = sysbase; + dtLib->nib_ClassLibrary.cl_Lib.lib_Revision = LIB_REVISION; + dtLib->nib_ClassLibrary.cl_Lib.lib_Node.ln_Pri = 7; + dtLib->nib_SegList = seglist; + + if (!InitDatatype(dtLib)) + { + CALLLIBFUNC(Expungelib, &dtLib->nib_ClassLibrary.cl_Lib); + dtLib = NULL; + } + + return dtLib ? &dtLib->nib_ClassLibrary.cl_Lib : NULL; +} + + +static LIBFUNC(Openlib, libbase, struct Library *) +{ + struct AmigaIconObj35DtLibBase *dtLib = (struct AmigaIconObj35DtLibBase *) libbase; + + dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt++; + dtLib->nib_ClassLibrary.cl_Lib.lib_Flags &= ~LIBF_DELEXP; + + if (!OpenDatatype(dtLib)) + { + CALLLIBFUNC(Closelib, &dtLib->nib_ClassLibrary.cl_Lib); + return NULL; + } + + return &dtLib->nib_ClassLibrary.cl_Lib; +} +LIBFUNC_END + + +static LIBFUNC(Closelib, libbase, struct SegList *) +{ + struct AmigaIconObj35DtLibBase *dtLib = (struct AmigaIconObj35DtLibBase *) libbase; + + dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt--; + + if (0 == dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + if (dtLib->nib_ClassLibrary.cl_Lib.lib_Flags & LIBF_DELEXP) + { + return CALLLIBFUNC(Expungelib, &dtLib->nib_ClassLibrary.cl_Lib); + } + } + + return NULL; +} +LIBFUNC_END + + +static LIBFUNC(Expungelib, libbase, struct SegList *) +{ + struct AmigaIconObj35DtLibBase *dtLib = (struct AmigaIconObj35DtLibBase *) libbase; + + if (0 == dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + ULONG size = dtLib->nib_ClassLibrary.cl_Lib.lib_NegSize + dtLib->nib_ClassLibrary.cl_Lib.lib_PosSize; + UBYTE *ptr = (UBYTE *) dtLib - dtLib->nib_ClassLibrary.cl_Lib.lib_NegSize; + struct SegList *libseglist = dtLib->nib_SegList; + + Remove((struct Node *) dtLib); + CloseDatatype(dtLib); + FreeMem(ptr,size); + + return libseglist; + } + + dtLib->nib_ClassLibrary.cl_Lib.lib_Flags |= LIBF_DELEXP; + + return NULL; +} +LIBFUNC_END + + +static LIBFUNC(Extfunclib, libbase, ULONG) +{ + (void) libbase; + + d1(kprintf(__FUNC__ "/%ld: libbase=%08lx\n", __LINE__, libbase)); + return 0; +} +LIBFUNC_END + + diff --git a/scalos/datatypes/AmigaIconObj3.5/AmigaIconObj35.c b/scalos/datatypes/AmigaIconObj3.5/AmigaIconObj35.c new file mode 100644 index 000000000..8614aa5ea --- /dev/null +++ b/scalos/datatypes/AmigaIconObj3.5/AmigaIconObj35.c @@ -0,0 +1,1868 @@ +// AmigaIconObj25.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define __USE_SYSBASE +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "AmigaIconObj35.h" + +#ifndef ICONCTRLA_GetARGBImageData1 +/* Define constants relative to ICONA_ErrorCode, which exists on all platforms */ +#define ICONCTRLA_GetARGBImageData1 (ICONA_ErrorCode+300) +#define ICONCTRLA_GetARGBImageData2 (ICONA_ErrorCode+302) +#endif + + +//---------------------------------------------------------------------------- + +#define max(a,b) ((a) > (b) ? (a) : (b)) +#define min(a,b) ((a) < (b) ? (a) : (b)) + + +#define NO_ICON_POSITION_WORD ((WORD) 0x8000) + +//---------------------------------------------------------------------------- + +struct GfxBase *GfxBase; +struct Library *LayersBase; +T_UTILITYBASE UtilityBase; +struct ExecBase *SysBase; +struct Library *IconBase; +struct Library *CyberGfxBase; +struct DosLibrary *DOSBase; +struct Library *IconObjectDTBase; +struct IntuitionBase *IntuitionBase; +#ifdef __amigaos4__ +struct Library *NewlibBase; +struct Interface *INewlib; +struct GraphicsIFace *IGraphics; +struct LayersIFace *ILayers; +struct UtilityIFace *IUtility; +struct ExecIFace *IExec; +struct IconIFace *IIcon; +struct CyberGfxIFace *ICyberGfx; +struct DOSIFace *IDOS; +struct IntuitionIFace *IIntuition; +#endif + +static void *MemPool; +static struct SignalSemaphore PubMemPoolSemaphore; + +static Class *AmigaIconObj35Class; + +//---------------------------------------------------------------------------- + +static SAVEDS(ULONG) INTERRUPT AmigaIconObj35Dispatcher(Class *cl, Object *o, Msg msg); + +//----------------------------------------------------------------------------- + +static BOOL DtNew(Class *cl, Object *o, struct opSet *ops); +static ULONG DtDispose(Class *cl, Object *o, Msg msg); +static ULONG DtSet(Class *cl, Object *o, struct opSet *ops); +static ULONG DtGet(Class *cl, Object *o, struct opGet *opg); +static ULONG DtLayout(Class *cl, Object *o, struct iopLayout *iopl); +static ULONG DtDraw(Class *cl, Object *o, struct iopDraw *iopd); +static ULONG DtWrite(Class *cl, Object *o, struct iopWrite *iopw); +static ULONG DtNewImage(Class *cl, Object *o, struct iopNewImage *iopw); +static ULONG DtFreeLayout(Class *cl, Object *o, struct iopFreeLayout *opf); +static ULONG DtClone(Class *cl, Object *o, struct iopCloneIconObject *iocio); + +//---------------------------------------------------------------------------- + +static void FreePenList(struct Screen *screen, UBYTE **PenList, ULONG PaletteSize); +static void ExchangeAttrs(struct DiskObject *DiskObj, struct WriteData *wd); +static void DrawMappedImage(struct InstanceData *inst, struct RastPort *rp, + struct MappedImage *img, UWORD Left, UWORD Top); +static void MyDrawIconState(struct InstanceData *inst, struct RastPort *rp, + struct DrawInfo *drawInfo, ULONG State); +static UBYTE *GenerateMask(struct InstanceData *inst, struct MappedImage *img); +static void SetSuperImgBorders(Class *cl, Object *o, struct opSet *ops); +static void WriteARGBArray(const struct ARGB *SrcImgData, + ULONG SrcX, ULONG SrcY, ULONG SrcBytesPerRow, + struct RastPort *DestRp, ULONG DestX, ULONG DestY, + ULONG SizeX, ULONG SizeY); +static BOOL MappedImageFromSAC(struct InstanceData *inst, + struct MappedImage *mi, struct ScalosBitMapAndColor *sac); +static void FreeMappedImage(struct InstanceData *inst, struct MappedImage *mi); +static BOOL SelectedImageFromNormalImage(struct InstanceData *inst); +static void MySetFont(Object *o, struct RastPort *rp); + +//---------------------------------------------------------------------------- + +static APTR MyAllocVecPooled(size_t Size); +static void MyFreeVecPooled(APTR mem); + +//---------------------------------------------------------------------------- + +char ALIGNED libName[] = "amigaiconobj35.datatype"; +char ALIGNED libIdString[] = "$VER: amigaiconobj35.datatype " + STR(LIB_VERSION) "." STR(LIB_REVISION) + " (23.05.2007) " + COMPILER_STRING + " ©1999" CURRENTYEAR " The Scalos Team"; + +//---------------------------------------------------------------------------- + +LIBFUNC(ObtainInfoEngine, libbase, ULONG) +{ + (void) libbase; + return (ULONG) AmigaIconObj35Class; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +// return 0 if error occurred +ULONG InitDatatype(struct AmigaIconObj35DtLibBase *dtLib) +{ + d1(kprintf("%s/%ld:\n", __FUNC__, __LINE__)); + + dtLib->nib_Initialized = FALSE; + + return 1; +} + +// return 0 if error occurred +ULONG OpenDatatype(struct AmigaIconObj35DtLibBase *dtLib) +{ + d1(kprintf("%s/%ld: OpenCnt=%ld\n", __FUNC__, __LINE__, dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt)); + + if (!dtLib->nib_Initialized) + { + d1(kprintf("%s/%ld: \n", __FUNC__, __LINE__)); + + dtLib->nib_Initialized = TRUE; + + InitSemaphore(&PubMemPoolSemaphore); + + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); +#ifdef __amigaos4__ + if (IntuitionBase != NULL) + { + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (IIntuition == NULL) + { + CloseLibrary((struct Library *)IntuitionBase); + IntuitionBase = NULL; + } + } +#endif + d1(kprintf("%s/%ld: IntuitionBase=%08lx\n", __FUNC__, __LINE__, IntuitionBase)); + if (NULL == IntuitionBase) + return 0; + + DOSBase = (struct DosLibrary *) OpenLibrary("dos.library", 39); +#ifdef __amigaos4__ + if (DOSBase != NULL) + { + IDOS = (struct DOSIFace *)GetInterface((struct Library *)DOSBase, "main", 1, NULL); + if (IDOS == NULL) + { + CloseLibrary((struct Library *)DOSBase); + DOSBase = NULL; + } + } +#endif + d1(kprintf("%s/%ld: DOSBase=%08lx\n", __FUNC__, __LINE__, DOSBase)); + if (NULL == DOSBase) + return 0; + + UtilityBase = (T_UTILITYBASE) OpenLibrary("utility.library", 39); +#ifdef __amigaos4__ + if (UtilityBase != NULL) + { + IUtility = (struct UtilityIFace *)GetInterface((struct Library *)UtilityBase, "main", 1, NULL); + if (IUtility == NULL) + { + CloseLibrary((struct Library *)UtilityBase); + UtilityBase = NULL; + } + } +#endif + d1(kprintf("%s/%ld: UtilityBase=%08lx\n", __FUNC__, __LINE__, UtilityBase)); + if (NULL == UtilityBase) + return 0; + + IconBase = OpenLibrary(ICONNAME, 44); +#ifdef __amigaos4__ + if (IconBase != NULL) + { + IIcon = (struct IconIFace *)GetInterface((struct Library *)IconBase, "main", 1, NULL); + if (IIcon == NULL) + { + CloseLibrary((struct Library *)IconBase); + IconBase = NULL; + } + } +#endif + d1(kprintf("%s/%ld: IconBase=%08lx\n", __FUNC__, __LINE__, IconBase)); + if (NULL == IconBase) + return 0; + + GfxBase = (struct GfxBase *) OpenLibrary(GRAPHICSNAME, 39); +#ifdef __amigaos4__ + if (GfxBase != NULL) + { + IGraphics = (struct GraphicsIFace *)GetInterface((struct Library *)GfxBase, "main", 1, NULL); + if (IGraphics == NULL) + { + CloseLibrary((struct Library *)GfxBase); + GfxBase = NULL; + } + } +#endif + d1(kprintf("%s/%ld: GfxBase=%08lx\n", __FUNC__, __LINE__, GfxBase)); + if (NULL == GfxBase) + return 0; + + LayersBase = OpenLibrary("layers.library", 39); +#ifdef __amigaos4__ + if (LayersBase != NULL) + { + ILayers = (struct LayersIFace *)GetInterface(LayersBase, "main", 1, NULL); + if (ILayers == NULL) + { + CloseLibrary(LayersBase); + LayersBase = NULL; + } + } +#endif + d1(kprintf("%s/%ld: LayersBase=%08lx\n", __FUNC__, __LINE__, LayersBase)); + if (NULL == LayersBase) + return 0; + + IconObjectDTBase = OpenLibrary("datatypes/iconobject.datatype", 39); + d1(kprintf("%s/%ld: IconObjectDTBase=%08lx\n", __FUNC__, __LINE__, IconObjectDTBase)); + if (NULL == IconObjectDTBase) + return 0; + + MemPool = CreatePool(MEMPOOL_MEMFLAGS, MEMPOOL_PUDDLESIZE, MEMPOOL_THRESHSIZE); + d1(kprintf("%s/%ld: MemPool=%08lx\n", __FUNC__, __LINE__, MemPool)); + if (NULL == MemPool) + return 0; + + AmigaIconObj35Class = dtLib->nib_ClassLibrary.cl_Class = MakeClass(libName, + "iconobject.datatype", NULL, sizeof(struct InstanceData), 0); + d1(kprintf("%s/%ld: AmigaIconObj35Class=%08lx\n", __FUNC__, __LINE__, AmigaIconObj35Class)); + if (NULL == AmigaIconObj35Class) + return 0; + + SETHOOKFUNC(AmigaIconObj35Class->cl_Dispatcher, AmigaIconObj35Dispatcher); + AmigaIconObj35Class->cl_Dispatcher.h_Data = dtLib; + + // Make class available for the public + AddClass(AmigaIconObj35Class); + + CyberGfxBase = OpenLibrary(CYBERGFXNAME, 0); +#ifdef __amigaos4__ + if (CyberGfxBase != NULL) + { + ICyberGfx = (struct CyberGfxIFace *)GetInterface((struct Library *)CyberGfxBase, "main", 1, NULL); + if (ICyberGfx == NULL) + { + CloseLibrary((struct Library *)CyberGfxBase); + CyberGfxBase = NULL; + } + } + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + return 0; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + return 0; +#endif + // CyberGfxBase may be NULL + } + + d1(kprintf("%s/%ld: Open Success!\n", __FUNC__, __LINE__)); + + return 1; +} + +void CloseDatatype(struct AmigaIconObj35DtLibBase *dtLib) +{ + d1(kprintf("%s/%ld: OpenCnt=%ld\n", __FUNC__, __LINE__, dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt)); + + if (dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt < 1) + { + if (AmigaIconObj35Class) + { + RemoveClass(AmigaIconObj35Class); + FreeClass(AmigaIconObj35Class); + AmigaIconObj35Class = dtLib->nib_ClassLibrary.cl_Class = NULL; + } + +#ifdef __amigaos4__ + if (INewlib) + { + DropInterface(INewlib); + INewlib = NULL; + } + if (NewlibBase) + { + CloseLibrary(NewlibBase); + NewlibBase = NULL; + } +#endif + if (NULL != IconObjectDTBase) + { + CloseLibrary(IconObjectDTBase); + IconObjectDTBase = NULL; + } + if (NULL != CyberGfxBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)ICyberGfx); +#endif + CloseLibrary(CyberGfxBase); + CyberGfxBase = NULL; + } + if (NULL != IconBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)IIcon); +#endif + CloseLibrary(IconBase); + IconBase = NULL; + } + + if (NULL != MemPool) + { + DeletePool(MemPool); + MemPool = NULL; + } + + if (NULL != LayersBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)ILayers); +#endif + CloseLibrary(LayersBase); + LayersBase = NULL; + } + if (NULL != GfxBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)IGraphics); +#endif + CloseLibrary((struct Library *) GfxBase); + GfxBase = NULL; + } + if (NULL != IntuitionBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)IIntuition); +#endif + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } + if (NULL != UtilityBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)IUtility); +#endif + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } + if (NULL != DOSBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)IDOS); +#endif + CloseLibrary((struct Library *)DOSBase); + DOSBase = NULL; + } + } + d1(kprintf("%s/%ld: Done!\n", __FUNC__, __LINE__)); +} + +//----------------------------------------------------------------------------- + +static SAVEDS(ULONG) INTERRUPT AmigaIconObj35Dispatcher(Class *cl, Object *o, Msg msg) +{ + ULONG Result; + + switch (msg->MethodID) + { + case OM_NEW: + o = (Object *) DoSuperMethodA(cl, o, msg); + d1(kprintf("%s/%ld: OM_NEW o=%08lx\n", __FUNC__, __LINE__, o)); + if (o) + { + d1(kprintf("%s/%ld: OM_NEW o=%08lx\n", __FUNC__, __LINE__, o)); + if (!DtNew(cl, o, (struct opSet *) msg)) + { + DoMethod(o, OM_DISPOSE); + o = NULL; + } + } + Result = (ULONG) o; + break; + + case OM_DISPOSE: + Result = DtDispose(cl, o, msg); + break; + + case OM_SET: + Result = DtSet(cl, o, (struct opSet *) msg); + break; + + case OM_GET: + Result = DtGet(cl, o, (struct opGet *) msg); + break; + + case IDTM_Layout: + Result = DtLayout(cl, o, (struct iopLayout *) msg); + break; + + case IDTM_Draw: + Result = DtDraw(cl, o, (struct iopDraw *) msg); + break; + + case IDTM_FreeLayout: + Result = DtFreeLayout(cl, o, (struct iopFreeLayout *) msg); + break; + + case IDTM_Write: + Result = DtWrite(cl, o, (struct iopWrite *) msg); + break; + + case IDTM_NewImage: + Result = DtNewImage(cl, o, (struct iopNewImage *) msg); + break; + + case IDTM_CloneIconObject: + Result = DtClone(cl, o, (struct iopCloneIconObject *) msg); + break; + + default: + Result = DoSuperMethodA(cl, o, msg); + break; + } + + return Result; +} + +//----------------------------------------------------------------------------- + +static BOOL DtNew(Class *cl, Object *o, struct opSet *ops) +{ + struct InstanceData *inst = INST_DATA(cl, o); + struct ExtGadget *gg = (struct ExtGadget *) o; + BOOL Success = FALSE; + + do { + STRPTR IconName; + ULONG SupportedIconTypes; + ULONG DefIconType; + struct Image *img; + struct tmp TempData; + + memset(inst, 0, sizeof(struct InstanceData)); + + SupportedIconTypes = GetTagData(IDTA_SupportedIconTypes, ~0, ops->ops_AttrList); + if (!(SupportedIconTypes & IDTV_IconType_ColorIcon)) + break; + + inst->aio_ImageLeft = GetTagData(IDTA_InnerLeft, 0, ops->ops_AttrList); + inst->aio_ImageTop = GetTagData(IDTA_InnerTop, 0, ops->ops_AttrList); + + inst->aio_RenderHook = (struct Hook *) GetTagData(IDTA_RenderHook, (ULONG) NULL, ops->ops_AttrList); + + if (FindTagItem(IDTA_CloneIconObject, ops->ops_AttrList)) + { + } + else + { + GetAttr(DTA_Name, o, (APTR) &IconName); + d1( + { + char buf[1024]; + GetCurrentDirName(buf, 1024); + kprintf("%s/%ld: CurrentDir=<%s>\n", __FUNC__, __LINE__, buf); + kprintf("%s/%ld: o=%08lx IconName=<%s>\n", __FUNC__, __LINE__, o, IconName ? IconName : (STRPTR) "NULL"); + } + ); + + DefIconType = GetTagData(IDTA_DefType, 0, ops->ops_AttrList); + d1(kprintf("%s/%ld: o=%08lx DefIconType=%lu\n", __FUNC__, __LINE__, o, DefIconType)); + + if (0 != DefIconType) + { + // Get default icon + d1(kprintf("%s/%ld: o=%08lx\n", __FUNC__, __LINE__, o)); + inst->aio_DiskObject = GetIconTags(IconName, + ICONGETA_RemapIcon, FALSE, + ICONGETA_GetDefaultType, DefIconType, + ICONGETA_FailIfUnavailable, FALSE, + TAG_END); + d1(kprintf("%s/%ld: o=%08lx aio_DiskObject=%08lx\n", __FUNC__, __LINE__, o, inst->aio_DiskObject)); + } + else + { + // Get named icon + if (NULL == IconName) + break; + + inst->aio_DiskObject = (struct DiskObject *) GetTagData(AIDTA_Icon, (ULONG) NULL, ops->ops_AttrList); + d1(kprintf("%s/%ld: o=%08lx aio_DiskObject=%08lx\n", __FUNC__, __LINE__, o, inst->aio_DiskObject)); + if (inst->aio_DiskObject) + { + inst->aio_DoNotFreeDiskObject = TRUE; + inst->aio_AlwaysUseDrawIconState = TRUE; + } + else + { + inst->aio_DiskObject = GetIconTags(IconName, + ICONGETA_RemapIcon, FALSE, + ICONGETA_FailIfUnavailable, TRUE, + TAG_END); + } + } + + d1(kprintf("%s/%ld: o=%08lx aio_DiskObject=%08lx\n", __FUNC__, __LINE__, o, inst->aio_DiskObject)); + if (NULL == inst->aio_DiskObject) + break; + + img = (struct Image *) inst->aio_DiskObject->do_Gadget.GadgetRender; + if (img) + { + SetAttrs(o, + GA_Width, img->Width, + GA_Height, img->Height, + IDTA_UnscaledWidth, img->Width, + IDTA_UnscaledHeight, img->Height, + TAG_END); + + d1(kprintf("%s/%ld: o=%08lx Width=%ld Height=%ld\n", __FUNC__, __LINE__, o, gg->Width, gg->Height)); + } + + // IconControlA() + IconControl(inst->aio_DiskObject, + ICONCTRLA_IsPaletteMapped, (ULONG) &TempData.tmp_ispalmapped, + TAG_END); + d1(kprintf("%s/%ld: o=%08lx ispalmapped=%ld\n", __FUNC__, __LINE__, o, TempData.tmp_ispalmapped)); + + if (TempData.tmp_ispalmapped) + { + IconControl(inst->aio_DiskObject, + ICONCTRLA_GetHeight, (ULONG) &TempData.tmp_height, + ICONCTRLA_GetWidth, (ULONG) &TempData.tmp_width, + + ICONCTRLA_GetFrameless, (ULONG) &inst->aio_Borderless, + + ICONCTRLA_GetImageData1, (ULONG) &inst->aio_Image1.aiomi_ImageData, + ICONCTRLA_GetPaletteSize1, (ULONG) &inst->aio_Image1.aiomi_PaletteSize, + ICONCTRLA_GetPalette1, (ULONG) &inst->aio_Image1.aiomi_Palette, + ICONCTRLA_GetTransparentColor1, (ULONG) &inst->aio_Image1.aiomi_TransparentColor, + + ICONCTRLA_GetImageData2, (ULONG) &inst->aio_Image2.aiomi_ImageData, + ICONCTRLA_GetPaletteSize2, (ULONG) &inst->aio_Image2.aiomi_PaletteSize, + ICONCTRLA_GetPalette2, (ULONG) &inst->aio_Image2.aiomi_Palette, + ICONCTRLA_GetTransparentColor2, (ULONG) &inst->aio_Image2.aiomi_TransparentColor, + TAG_END); + + inst->aio_fIsPaletteMapped = TRUE; + + inst->aio_MappedWidth = TempData.tmp_width; + inst->aio_MappedHeight = TempData.tmp_height; + + SetAttrs(o, + GA_Width, inst->aio_MappedWidth, + GA_Height, inst->aio_MappedHeight, + IDTA_UnscaledWidth, inst->aio_MappedWidth, + IDTA_UnscaledHeight, inst->aio_MappedHeight, + TAG_END); + + d1(kprintf("%s/%ld: o=%08lx Width=%ld Height=%ld\n", __FUNC__, __LINE__, o, gg->Width, gg->Height)); + + GenerateMask(inst, &inst->aio_Image1); + d1(KPrintF("%s/%ld: o=%08lx aio_ImageMask1=%08lx\n", __FUNC__, __LINE__, o, inst->aio_Image1.aiomi_Mask)); + + GenerateMask(inst, &inst->aio_Image2); + d1(KPrintF("%s/%ld: o=%08lx aio_ImageMask2=%08lx\n", __FUNC__, __LINE__, o, inst->aio_Image2.aiomi_Mask)); + } + else + { + ULONG BytesPerRow, MaskSize; + PLANEPTR Mask1 = NULL, Mask2 = NULL; + ULONG *ARGBData1 = NULL, *ARGBData2 = NULL; + + IconControl(inst->aio_DiskObject, + ICONCTRLA_GetHeight, (ULONG) &TempData.tmp_height, + ICONCTRLA_GetWidth, (ULONG) &TempData.tmp_width, + ICONCTRLA_GetImageMask1, (ULONG) &Mask1, + ICONCTRLA_GetImageMask2, (ULONG) &Mask2, + ICONCTRLA_GetARGBImageData1, (ULONG) &ARGBData1, + ICONCTRLA_GetARGBImageData2, (ULONG) &ARGBData2, + TAG_END); + d1(KPrintF("%s/%ld: o=%08lx Mask1=%08lx Mask2=%08lx\n", + __FUNC__, __LINE__, o, Mask1, Mask2)); + d1(KPrintF("%s/%ld: o=%08lx ARGBData1=%08lx ARGBData2=%08lx\n", + __FUNC__, __LINE__, o, ARGBData1, ARGBData2)); + inst->aio_MappedWidth = TempData.tmp_width; + inst->aio_MappedHeight = TempData.tmp_height; + + BytesPerRow = ((inst->aio_MappedWidth + 15) & 0xfff0) >> 3; + MaskSize = inst->aio_MappedHeight * BytesPerRow; + if (ARGBData1) + { + struct ARGBHeader argbh; + + argbh.argb_Width = TempData.tmp_width; + argbh.argb_Height = TempData.tmp_height; + argbh.argb_ImageData = (struct ARGB *)ARGBData1; + + SetAttrs(o, + IDTA_CopyARGBImageData, TRUE, + IDTA_ARGBImageData, (ULONG) &argbh, + TAG_END); + } + if (Mask1) + { + inst->aio_Image1.aiomi_Mask = MyAllocVecPooled(MaskSize); + CopyMem(Mask1, inst->aio_Image1.aiomi_Mask, MaskSize); + } + else + { + inst->aio_Image1.aiomi_Mask = NULL; + } + + if (ARGBData2) + { + struct ARGBHeader argbh; + + argbh.argb_Width = TempData.tmp_width; + argbh.argb_Height = TempData.tmp_height; + argbh.argb_ImageData = (struct ARGB *)ARGBData2; + + SetAttrs(o, + IDTA_CopySelARGBImageData, TRUE, + IDTA_SelARGBImageData, (ULONG) &argbh, + TAG_END); + } + if (Mask2) + { + inst->aio_Image2.aiomi_Mask = MyAllocVecPooled(MaskSize); + CopyMem(Mask2, inst->aio_Image2.aiomi_Mask, MaskSize); + } + else + { + inst->aio_Image2.aiomi_Mask = NULL; + } + } + + if (NO_ICON_POSITION == inst->aio_DiskObject->do_CurrentX) + { + gg->LeftEdge = gg->TopEdge = NO_ICON_POSITION_WORD; + } + else + { + gg->LeftEdge = inst->aio_DiskObject->do_CurrentX; + gg->TopEdge = inst->aio_DiskObject->do_CurrentY; + } + + d1(kprintf("%s/%ld: o=%08lx Left=%ld Top=%ld\n", __FUNC__, __LINE__, o, gg->LeftEdge, gg->TopEdge)); + + if (NULL == inst->aio_DiskObject->do_DrawerData) + { + inst->aio_myDrawerData = MyAllocVecPooled(sizeof(struct DrawerData)); + if (NULL == inst->aio_myDrawerData) + break; + + memset(inst->aio_myDrawerData, 0, sizeof(struct DrawerData)); + + switch (inst->aio_DiskObject->do_Type) + { + case WBTOOL: + case WBPROJECT: + case WBKICK: + break; + default: + inst->aio_DiskObject->do_DrawerData = inst->aio_myDrawerData; + break; + } + } + + if (inst->aio_DiskObject->do_DrawerData) + { + SetAttrs(o, + IDTA_ViewModes, inst->aio_DiskObject->do_DrawerData->dd_ViewModes, + IDTA_Flags, inst->aio_DiskObject->do_DrawerData->dd_Flags, + IDTA_WinCurrentX, inst->aio_DiskObject->do_DrawerData->dd_CurrentX, + IDTA_WinCurrentY, inst->aio_DiskObject->do_DrawerData->dd_CurrentY, + IDTA_WindowRect, (ULONG) &inst->aio_DiskObject->do_DrawerData->dd_NewWindow, + TAG_END); + } + + SetAttrs(o, + IDTA_Mask_Normal, (ULONG) inst->aio_Image1.aiomi_Mask, + IDTA_Mask_Selected, (ULONG) inst->aio_Image2.aiomi_Mask, + IDTA_Width_Mask_Normal, inst->aio_MappedWidth, + IDTA_Height_Mask_Normal, inst->aio_MappedHeight, + IDTA_Width_Mask_Selected, inst->aio_MappedWidth, + IDTA_Height_Mask_Selected, inst->aio_MappedHeight, + + IDTA_ToolTypes, (ULONG) inst->aio_DiskObject->do_ToolTypes, + IDTA_Stacksize, inst->aio_DiskObject->do_StackSize, + IDTA_DefaultTool, (ULONG) inst->aio_DiskObject->do_DefaultTool, + IDTA_Type, inst->aio_DiskObject->do_Type, + IDTA_Borderless, inst->aio_Borderless, + TAG_END); + + inst->aio_fLayoutOk = FALSE; + + SetSuperImgBorders(cl, o, ops); + } + + Success = TRUE; + } while (0); + + d1(kprintf("%s/%ld: o=%08lx Success=%ld\n", __FUNC__, __LINE__, o, Success)); + + return Success; +} + +//----------------------------------------------------------------------------- + +static ULONG DtDispose(Class *cl, Object *o, Msg msg) +{ + struct InstanceData *inst = INST_DATA(cl, o); +// struct ExtGadget *gg = (struct ExtGadget *) o; + + if (inst->aio_myDrawerData) + { + MyFreeVecPooled(inst->aio_myDrawerData); + inst->aio_myDrawerData = NULL; + } + if (inst->aio_DiskObject && !inst->aio_DoNotFreeDiskObject) + { + FreeDiskObject(inst->aio_DiskObject); + inst->aio_DiskObject = NULL; + } + FreeMappedImage(inst, &inst->aio_Image1); + FreeMappedImage(inst, &inst->aio_Image2); + + return DoSuperMethodA(cl, o, msg); +} + +//---------------------------------------------------------------------------------------- + +static ULONG DtSet(Class *cl, Object *o, struct opSet *ops) +{ + struct InstanceData *inst = INST_DATA(cl, o); + ULONG Result; + + inst->aio_RenderHook = (struct Hook *) GetTagData(IDTA_RenderHook, (ULONG) inst->aio_RenderHook, ops->ops_AttrList); + + if (inst->aio_DoNotFreeDiskObject) + { + if (0 == GetTagData(IDTA_DoFreeDiskObject, 0, ops->ops_AttrList)) + inst->aio_DoNotFreeDiskObject = TRUE; + } + + inst->aio_ImageLeft = GetTagData(IDTA_InnerLeft, inst->aio_ImageLeft, ops->ops_AttrList); + inst->aio_ImageTop = GetTagData(IDTA_InnerTop, inst->aio_ImageTop, ops->ops_AttrList); + + Result = DoSuperMethodA(cl, o, (Msg) ops); + + SetSuperImgBorders(cl, o, ops); + + return Result; +} + +//---------------------------------------------------------------------------------------- + +static ULONG DtGet(Class *cl, Object *o, struct opGet *opg) +{ + struct InstanceData *inst = INST_DATA(cl, o); + ULONG result = 1; + + switch (opg->opg_AttrID) + { + case IDTA_IconType: + *opg->opg_Storage = ioICONTYPE_GlowIcon; + break; + + case IDTA_NumberOfColorsSupported: + *opg->opg_Storage = 256; + break; + + case AIDTA_Icon: + *opg->opg_Storage = (ULONG) inst->aio_DiskObject; + break; + + case IDTA_Extention: + *opg->opg_Storage = (ULONG) ".info"; + break; + + default: + result = DoSuperMethodA(cl, o, (Msg) opg); + break; + } + + return result; +} + +//----------------------------------------------------------------------------- + +static ULONG DtLayout(Class *cl, Object *o, struct iopLayout *iopl) +{ + struct InstanceData *inst = INST_DATA(cl, o); + struct ExtGadget *gg = (struct ExtGadget *) o; + + d1(kprintf("%s/%ld: START o=%08lx inst=%08lx\n", __FUNC__, __LINE__, o, inst)); + + if (inst->aio_RenderHook) + { + SetAttrs(o, + IDTA_MultiLineText, FALSE, + TAG_END); + } + + DoSuperMethodA(cl, o, (Msg) iopl); + + d1(kprintf("%s/%ld: o=%08lx Screen=%08lx\n", __FUNC__, __LINE__, o, iopl->iopl_Screen)); + d1(kprintf("%s/%ld: o=%08lx Width=%ld Height=%ld\n", __FUNC__, __LINE__, o, gg->Width, gg->Height)); + d1(kprintf("%s/%ld: o=%08lx GadgetRender=%08lx SelectRender=%08lx Flags=%08lx\n", \ + __FUNC__, __LINE__, o, gg->GadgetRender, gg->SelectRender, iopl->iopl_Flags)); + + inst->aio_Screen = iopl->iopl_Screen; + + if (gg->GadgetRender && (iopl->iopl_Flags & IOLAYOUTF_NormalImage)) + { + if (inst->aio_AlwaysUseDrawIconState || !inst->aio_fIsPaletteMapped) + { + MyDrawIconState(inst, (struct RastPort *) gg->GadgetRender, + iopl->iopl_DrawInfo, IDS_NORMAL); + } + else + { + DrawMappedImage(inst, (struct RastPort *) gg->GadgetRender, &inst->aio_Image1, + inst->aio_ImageLeft, inst->aio_ImageTop); + } + } + if (gg->SelectRender && (iopl->iopl_Flags & IOLAYOUTF_SelectedImage)) + { + if (inst->aio_AlwaysUseDrawIconState || !inst->aio_fIsPaletteMapped) + { + MyDrawIconState(inst, (struct RastPort *) gg->SelectRender, + iopl->iopl_DrawInfo, IDS_SELECTED); + } + else + { + DrawMappedImage(inst, (struct RastPort *) gg->SelectRender, &inst->aio_Image2, + inst->aio_ImageLeft, inst->aio_ImageTop); + } + } + + d1(kprintf("%s/%ld: END o=%08lx inst=%08lx\n", __FUNC__, __LINE__, o, inst)); + + return 0; +} + +//----------------------------------------------------------------------------- + +static ULONG DtDraw(Class *cl, Object *o, struct iopDraw *iopd) +{ + struct InstanceData *inst = INST_DATA(cl, o); + struct ExtGadget *gg = (struct ExtGadget *) o; + + d1(kprintf("%s/%s/%ld: START o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, + o, inst)); + + // copy current position into DiskObject + inst->aio_DiskObject->do_CurrentX = gg->LeftEdge; + inst->aio_DiskObject->do_CurrentY = gg->TopEdge; + + // RenderHook NEEDS Layer ! + if (inst->aio_RenderHook && iopd->iopd_RastPort->Layer) + { + // Draw Icon via RenderHook + d1(kprintf("%s/%ld: RenderHook\n", __FUNC__, __LINE__)); + + if (!(iopd->iopd_DrawFlags & IODRAWF_NoImage)) + { + static struct TagItem EmptyTagList[] = { { TAG_END } }; + LONG x, y; + STRPTR IconText; + ULONG FgPen = 1; + struct AppIconRenderMsg arm; + struct Region *IconRegion; + struct Region *OldDamageList = NULL; + + d1(kprintf("%s/%s/%ld: Width=%ld Height=%ld\n", __FILE__, __FUNC__, __LINE__, gg->Width, gg->Height)); + d1(kprintf("%s/%s/%ld: BoundsWidth=%ld BoundsHeight=%ld\n", __FILE__, __FUNC__, __LINE__, gg->BoundsWidth, gg->BoundsHeight)); + + x = iopd->iopd_XOffset; + y = iopd->iopd_YOffset; + + if (!(iopd->iopd_DrawFlags & IODRAWF_AbsolutePos)) + { + x += gg->LeftEdge; + y += gg->TopEdge; + } + + GetAttr(IDTA_Text, o, (APTR) &IconText); + GetAttr(IDTA_TextPen, o, &FgPen); + + SetABPenDrMd(iopd->iopd_RastPort, FgPen, 0, JAM1); + MySetFont(o, iopd->iopd_RastPort); + + // Build AppIconRenderMsg + arm.arm_RastPort = iopd->iopd_RastPort; + arm.arm_Icon = inst->aio_DiskObject; + arm.arm_Label = IconText; + arm.arm_Tags = EmptyTagList; + arm.arm_Left = x; + arm.arm_Top = y; + arm.arm_Width = gg->Width; + arm.arm_Height = gg->Height; + arm.arm_State = (gg->Flags & GFLG_SELECTED) ? IDS_SELECTED : IDS_NORMAL; + + LockLayerInfo(iopd->iopd_RastPort->Layer->LayerInfo); + LockLayerRom(iopd->iopd_RastPort->Layer); + + d1(kprintf("%s/%ld: DamageList=%08lx\n", __FUNC__, __LINE__, iopd->iopd_RastPort->Layer->DamageList)); + + IconRegion = NewRegion(); + if (IconRegion) + { + struct Rectangle IconRect; + + d1(kprintf("%s/%ld: IconRegion=%08lx\n", __FUNC__, __LINE__, IconRegion)); + + IconRect.MinX = IconRect.MaxX = arm.arm_Left; + IconRect.MinY = IconRect.MaxY = arm.arm_Top; + IconRect.MaxX += arm.arm_Width - 1; + IconRect.MaxY += arm.arm_Height - 1; + + OldDamageList = iopd->iopd_RastPort->Layer->DamageList; + iopd->iopd_RastPort->Layer->DamageList = IconRegion; + + ClearRegion(iopd->iopd_RastPort->Layer->DamageList); + OrRectRegion(iopd->iopd_RastPort->Layer->DamageList, &IconRect); + + if (gg->Width != gg->BoundsWidth || gg->Height != gg->BoundsHeight) + { + IconRect.MinX = IconRect.MaxX = arm.arm_Left - (gg->LeftEdge - gg->BoundsLeftEdge); + IconRect.MinY = IconRect.MaxY = arm.arm_Top + gg->Height; + IconRect.MaxX += gg->BoundsWidth - 1; + IconRect.MaxY += gg->BoundsHeight - gg->Height; + + OrRectRegion(iopd->iopd_RastPort->Layer->DamageList, &IconRect); + } + } + + d1(kprintf("%s/%ld: o=%08lx AppIconRenderMsg=%08lx rp=%08lx Layer=%08lx x=%ld y=%ld w=%ld h=%ld\n",\ + __FUNC__, __LINE__, o, &arm, arm.arm_RastPort, arm.arm_RastPort->Layer, \ + arm.arm_Left, arm.arm_Top, arm.arm_Width, arm.arm_Height)); + + BeginUpdate(iopd->iopd_RastPort->Layer); + + if (CallHookPkt(inst->aio_RenderHook, NULL, &arm)) + DoSuperMethodA(cl, o, (Msg) iopd); + + if (OldDamageList) + { + iopd->iopd_RastPort->Layer->DamageList = OldDamageList; + EndUpdate(iopd->iopd_RastPort->Layer, FALSE); + } + else + { + iopd->iopd_RastPort->Layer->Flags &= ~0x0080; + EndUpdate(iopd->iopd_RastPort->Layer, TRUE); + } + + if (IconRegion) + DisposeRegion(IconRegion); + + UnlockLayerRom(iopd->iopd_RastPort->Layer); + UnlockLayerInfo(iopd->iopd_RastPort->Layer->LayerInfo); + } + } + else + { + d1(kprintf("%s/%s/%ld: standard icon\n", __FILE__, __FUNC__, __LINE__)); + // standard icon: let SuperClass do the drawing + DoSuperMethodA(cl, o, (Msg) iopd); + } + + d1(kprintf("%s/%ld: END o=%08lx inst=%08lx\n", __FUNC__, __LINE__, o, inst)); + + return 0; +} + +//----------------------------------------------------------------------------- + +static ULONG DtWrite(Class *cl, Object *o, struct iopWrite *iopw) +{ + struct InstanceData *inst = INST_DATA(cl, o); + struct ExtGadget *gg = (struct ExtGadget *) o; + struct WriteData wd; + struct DrawerData *OrigDrawerData; + LONG Result = RETURN_OK; + ULONG NeedUpdateWB; + + d1(kprintf("%s/%ld: o=%08lx inst=%08lx\n", __FUNC__, __LINE__, o, inst)); + + NeedUpdateWB = GetTagData(ICONA_NotifyWorkbench, FALSE, iopw->iopw_Tags); + + memset(&wd, 0, sizeof(wd)); + + GetAttr(IDTA_Type, o, &wd.aiowd_Type); + GetAttr(IDTA_ViewModes, o, &wd.aiowd_ViewModes); + GetAttr(IDTA_Flags, o, &wd.aiowd_Flags); + GetAttr(IDTA_WinCurrentX, o, &wd.aiowd_CurrentX); + GetAttr(IDTA_WinCurrentY, o, &wd.aiowd_CurrentY); + GetAttr(IDTA_WindowRect, o, (ULONG *) &wd.aiowd_WindowRect); + GetAttr(IDTA_Stacksize, o, &wd.aiowd_StackSize); + GetAttr(IDTA_ToolTypes, o, (ULONG *) &wd.aiowd_ToolTypes); + GetAttr(IDTA_DefaultTool, o, (ULONG *) &wd.aiowd_DefaultTool); + + ExchangeAttrs(inst->aio_DiskObject, &wd); + + OrigDrawerData = inst->aio_DiskObject->do_DrawerData; + inst->aio_DiskObject->do_DrawerData = NULL; + + switch (inst->aio_DiskObject->do_Type) + { + case WBTOOL: + case WBPROJECT: + case WBKICK: + break; + default: + if (OrigDrawerData) + inst->aio_DiskObject->do_DrawerData = OrigDrawerData; + else + inst->aio_DiskObject->do_DrawerData = inst->aio_myDrawerData; + + inst->aio_DiskObject->do_DrawerData->dd_CurrentX = wd.aiowd_CurrentX; + inst->aio_DiskObject->do_DrawerData->dd_CurrentY = wd.aiowd_CurrentY; + + if (wd.aiowd_WindowRect) + { + inst->aio_DiskObject->do_DrawerData->dd_NewWindow.LeftEdge = wd.aiowd_WindowRect->Left; + inst->aio_DiskObject->do_DrawerData->dd_NewWindow.TopEdge = wd.aiowd_WindowRect->Top; + inst->aio_DiskObject->do_DrawerData->dd_NewWindow.Width = wd.aiowd_WindowRect->Width; + inst->aio_DiskObject->do_DrawerData->dd_NewWindow.Height = wd.aiowd_WindowRect->Height; + inst->aio_DiskObject->do_DrawerData->dd_Flags = wd.aiowd_Flags; + inst->aio_DiskObject->do_DrawerData->dd_ViewModes = wd.aiowd_ViewModes; + } + break; + } + + if (GetTagData(ICONA_NoNewImage, 0, iopw->iopw_Tags)) + { + } + if (GetTagData(ICONA_NoPosition, 0, iopw->iopw_Tags)) + { + inst->aio_DiskObject->do_CurrentX = inst->aio_DiskObject->do_CurrentY = NO_ICON_POSITION; + } + else + { + if (NO_ICON_POSITION_WORD == gg->LeftEdge) + { + inst->aio_DiskObject->do_CurrentX = inst->aio_DiskObject->do_CurrentY = NO_ICON_POSITION; + } + else + { + inst->aio_DiskObject->do_CurrentX = gg->LeftEdge; + inst->aio_DiskObject->do_CurrentY = gg->TopEdge; + } + } + + d1(kprintf("%s/%ld: GadgetRender=%08lx\n", __FUNC__, __LINE__, inst->aio_DiskObject->do_Gadget.GadgetRender)); + + if (NULL == inst->aio_DiskObject->do_Gadget.GadgetRender) + { + // LayoutIconA() + LayoutIcon(inst->aio_DiskObject, NULL, TAG_END); + } + + d1(kprintf("%s/%ld: Image2Data=%08lx\n", __FUNC__, __LINE__, inst->aio_Image2.aiomi_ImageData)); + + if (inst->aio_Image2.aiomi_ImageData) + { + IconControl(inst->aio_DiskObject, + ICONCTRLA_SetImageData2, (ULONG) inst->aio_Image2.aiomi_ImageData, + ICONCTRLA_SetTransparentColor2, (ULONG) inst->aio_Image2.aiomi_TransparentColor, + TAG_END); + + d1(kprintf("%s/%ld: PaletteSize2=%lu\n", __FUNC__, __LINE__, inst->aio_Image2.aiomi_PaletteSize)); + + if (inst->aio_Image2.aiomi_PaletteSize) + { + IconControl(inst->aio_DiskObject, + ICONCTRLA_SetPaletteSize2, (ULONG) inst->aio_Image2.aiomi_PaletteSize, + ICONCTRLA_SetPalette2, (ULONG) inst->aio_Image2.aiomi_Palette, + TAG_END); + } + } + + d1(kprintf("%s/%ld: PaletteSize1=%lu\n", __FUNC__, __LINE__, inst->aio_Image1.aiomi_PaletteSize)); + d1(kprintf("%s/%ld: Width=%ld Height=%ld\n", __FUNC__, __LINE__, inst->aio_MappedWidth, inst->aio_MappedHeight)); + + // IconControlA() + IconControl(inst->aio_DiskObject, + ICONCTRLA_SetImageData1, (ULONG) inst->aio_Image1.aiomi_ImageData, + ICONCTRLA_SetPaletteSize1, (ULONG) inst->aio_Image1.aiomi_PaletteSize, + ICONCTRLA_SetPalette1, (ULONG) inst->aio_Image1.aiomi_Palette, + ICONCTRLA_SetTransparentColor1, (ULONG) inst->aio_Image1.aiomi_TransparentColor, + ICONCTRLA_SetWidth, inst->aio_MappedWidth, + ICONCTRLA_SetHeight, inst->aio_MappedHeight, + TAG_END); + + // PutIconTagList() + if (!PutIconTags(iopw->iopw_Path, inst->aio_DiskObject, + ICONPUTA_NotifyWorkbench, NeedUpdateWB, + TAG_END)) + { + Result = IoErr(); + } + + // Restore diskobject + inst->aio_DiskObject->do_DrawerData = OrigDrawerData; + ExchangeAttrs(inst->aio_DiskObject, &wd); + + return (ULONG) Result; +} + +//----------------------------------------------------------------------------- + +static ULONG DtNewImage(Class *cl, Object *o, struct iopNewImage *ioni) +{ + struct InstanceData *inst = INST_DATA(cl, o); + + d1(KPrintF("%s/%ld: START o=%08lx inst=%08lx\n", __FUNC__, __LINE__, o, inst)); + + do { + if (NULL == ioni->ioni_NormalImage) + break; + + if (!MappedImageFromSAC(inst, &inst->aio_Image1, ioni->ioni_NormalImage)) + break; + + if (ioni->ioni_SelectedImage) + { + if (!MappedImageFromSAC(inst, &inst->aio_Image2, ioni->ioni_SelectedImage)) + break; + } + else + { + if (!SelectedImageFromNormalImage(inst)) + break; + } + } while (0); + + d1(KPrintF("%s/%ld: \n", __FUNC__, __LINE__)); + + SetAttrs(o, + GA_Width, inst->aio_MappedWidth, + GA_Height, inst->aio_MappedHeight, + IDTA_UnscaledWidth, inst->aio_MappedWidth, + IDTA_UnscaledHeight, inst->aio_MappedHeight, + TAG_END); + + GenerateMask(inst, &inst->aio_Image1); + d1(KPrintF("%s/%ld: o=%08lx aio_ImageMask1=%08lx\n", __FUNC__, __LINE__, o, inst->aio_Image1.aiomi_Mask)); + + GenerateMask(inst, &inst->aio_Image2); + d1(KPrintF("%s/%ld: o=%08lx aio_ImageMask2=%08lx\n", __FUNC__, __LINE__, o, inst->aio_Image1.aiomi_Mask)); + + SetAttrs(o, + IDTA_Mask_Normal, (ULONG) inst->aio_Image1.aiomi_Mask, + IDTA_Mask_Selected, (ULONG) inst->aio_Image2.aiomi_Mask, + IDTA_Width_Mask_Normal, inst->aio_MappedWidth, + IDTA_Height_Mask_Normal, inst->aio_MappedHeight, + IDTA_Width_Mask_Selected, inst->aio_MappedWidth, + IDTA_Height_Mask_Selected, inst->aio_MappedHeight, + TAG_END); + + d1(KPrintF("%s/%ld: END o=%08lx inst=%08lx\n", __FUNC__, __LINE__, o, inst)); + + return 0; +} + +//----------------------------------------------------------------------------- + +static ULONG DtFreeLayout(Class *cl, Object *o, struct iopFreeLayout *opf) +{ + struct InstanceData *inst = INST_DATA(cl, o); +// struct ExtGadget *gg = (struct ExtGadget *) o; + + d1(kprintf("%s/%ld: o=%08lx inst=%08lx\n", __FUNC__, __LINE__, o, inst)); + + if (inst->aio_Screen && (opf->iopf_Flags & IOFREELAYOUTF_ScreenAvailable)) + { + if (inst->aio_Image1.aiomi_PenList) + { + FreePenList(inst->aio_Screen, &inst->aio_Image1.aiomi_PenList, + inst->aio_Image1.aiomi_PaletteSize); + } + if (inst->aio_Image2.aiomi_PenList) + { + FreePenList(inst->aio_Screen, &inst->aio_Image2.aiomi_PenList, + inst->aio_Image2.aiomi_PaletteSize); + } + } + else + { + if (inst->aio_Image1.aiomi_PenList) + { + MyFreeVecPooled(inst->aio_Image1.aiomi_PenList); + inst->aio_Image1.aiomi_PenList = NULL; + } + if (inst->aio_Image2.aiomi_PenList) + { + MyFreeVecPooled(inst->aio_Image2.aiomi_PenList); + inst->aio_Image2.aiomi_PenList = NULL; + } + } + + return DoSuperMethodA(cl, o, (Msg) opf); +} + +//----------------------------------------------------------------------------- + +static ULONG DtClone(Class *cl, Object *o, struct iopCloneIconObject *iocio) +{ +// struct InstanceData *inst = INST_DATA(cl, o); + + d1(KPrintF("%s/%ld: START o=%08lx\n", __FUNC__, __LINE__, o)); + + d1(KPrintF("%s/%ld: END o=%08lx\n", __FUNC__, __LINE__, o)); + + return 0; +} + +//---------------------------------------------------------------------------------------- + +static void FreePenList(struct Screen *screen, UBYTE **PenListPtr, ULONG PaletteSize) +{ + UBYTE *PenList = *PenListPtr; + + while (PaletteSize--) + { + ReleasePen(screen->ViewPort.ColorMap, *PenList++); + } + + MyFreeVecPooled(*PenListPtr); + *PenListPtr = NULL; +} + +//---------------------------------------------------------------------------------------- + +static void ExchangeAttrs(struct DiskObject *DiskObj, struct WriteData *wd) +{ + UBYTE TempUB; + ULONG TempUL; + void *TempPtr; + + TempPtr = wd->aiowd_DefaultTool; + wd->aiowd_DefaultTool = DiskObj->do_DefaultTool; + DiskObj->do_DefaultTool = TempPtr; + + TempPtr = wd->aiowd_ToolTypes; + wd->aiowd_ToolTypes = DiskObj->do_ToolTypes; + DiskObj->do_ToolTypes = TempPtr; + + TempUL = wd->aiowd_StackSize; + wd->aiowd_StackSize = DiskObj->do_StackSize; + DiskObj->do_StackSize = TempUL; + + TempUB = (UBYTE) wd->aiowd_Type; + wd->aiowd_Type = DiskObj->do_Type; + DiskObj->do_Type = TempUB; +} + +//---------------------------------------------------------------------------------------- + +static void DrawMappedImage(struct InstanceData *inst, struct RastPort *rp, + struct MappedImage *img, UWORD Left, UWORD Top) +{ + BOOL Success = FALSE; + UBYTE *MappedImage = NULL; + struct ARGB *ARGBArray = NULL; + struct ARGB *ARGBImgArray = NULL; + + do { + ULONG BmWidth, BmHeight; + ULONG Width, Height; + + BmWidth = GetBitMapAttr(rp->BitMap, BMA_WIDTH); + BmHeight = GetBitMapAttr(rp->BitMap, BMA_HEIGHT); + + Width = min(inst->aio_MappedWidth, BmWidth - Left); + Height = min(inst->aio_MappedHeight, BmHeight - Top); + + if (CyberGfxBase && GetBitMapAttr(rp->BitMap, BMA_DEPTH) > 8) + { + // True color + struct ARGB *ARGBPtr; + struct ARGB *ARGBImgDestPtr; + const struct ColorRegister *PalettePtr; + UBYTE *ImgSrcPtr; + ULONG n; + ULONG ImgSize; + + ImgSize = inst->aio_MappedWidth * inst->aio_MappedHeight; + ARGBImgArray = MyAllocVecPooled(ImgSize * sizeof(struct ARGB)); + d1(kprintf("%s/%ld: ARGBImgArray=%08lx\n", __FUNC__, __LINE__, ARGBImgArray)); + if (NULL == ARGBImgArray) + break; + + ARGBArray = MyAllocVecPooled(img->aiomi_PaletteSize * sizeof(struct ARGB)); + d1(kprintf("%s/%ld: ARGBArray=%08lx\n", __FUNC__, __LINE__, ARGBArray)); + if (NULL == ARGBArray) + break; + + PalettePtr = img->aiomi_Palette; + ARGBPtr = ARGBArray; + for (n = 0; n < img->aiomi_PaletteSize; n++, ARGBPtr++, PalettePtr++) + { + ARGBPtr->Alpha = 0xff; + ARGBPtr->Red = PalettePtr->red; + ARGBPtr->Green = PalettePtr->green; + ARGBPtr->Blue = PalettePtr->blue; + } + + ImgSrcPtr = img->aiomi_ImageData; + ARGBImgDestPtr = ARGBImgArray; + for (n = 0; n < ImgSize; n++) + { + *ARGBImgDestPtr++ = ARGBArray[*ImgSrcPtr++]; + } + + WriteARGBArray(ARGBImgArray, 0, 0, + inst->aio_MappedWidth * sizeof(struct ARGB), + rp, Left, Top, + Width, Height); + } + else + { + struct ColorRegister *PalettePtr; + UBYTE *PenListPtr; + UBYTE *ImgPtr; + UBYTE *ImgDestPtr; + ULONG Remainder; + ULONG n; + ULONG y; + + img->aiomi_PenList = MyAllocVecPooled(img->aiomi_PaletteSize); + if (NULL == img->aiomi_PenList) + break; + + MappedImage = MyAllocVecPooled(inst->aio_MappedHeight * ((inst->aio_MappedWidth + 15) & 0xfff0)); + if (NULL == MappedImage) + break; + + PalettePtr = img->aiomi_Palette; + PenListPtr = img->aiomi_PenList; + for (n = 0; n < img->aiomi_PaletteSize; n++) + { + *PenListPtr++ = ObtainBestPenA(inst->aio_Screen->ViewPort.ColorMap, + PalettePtr->red << 24, + PalettePtr->green << 24, + PalettePtr->blue << 24, + NULL); + PalettePtr++; + } + + Remainder = ((inst->aio_MappedWidth + 15) & 0xfff0) - inst->aio_MappedWidth; + ImgPtr = img->aiomi_ImageData; + ImgDestPtr = MappedImage; + for (y = 0; y < inst->aio_MappedHeight; y++) + { + ULONG x; + + for (x = 0; x < inst->aio_MappedWidth; x++) + { + *ImgDestPtr++ = img->aiomi_PenList[*ImgPtr++]; + } + ImgDestPtr += Remainder; + } + + if (CyberGfxBase && GetCyberMapAttr(rp->BitMap, CYBRMATTR_ISCYBERGFX)) + { + WritePixelArray(MappedImage, 0, 0, + (inst->aio_MappedWidth + 15) & 0xfff0, + rp, Left, Top, + Width, Height, + RECTFMT_LUT8); + } + else + { + struct RastPort rpTemp; + + InitRastPort(&rpTemp); + rpTemp.BitMap = AllocBitMap((inst->aio_MappedWidth + 15) & 0xfff0, + inst->aio_MappedHeight, 8, 0, rp->BitMap); + if (NULL == rpTemp.BitMap) + break; + + WritePixelArray8(rp, Left, Top, + Left + inst->aio_MappedWidth - 1, + Top + inst->aio_MappedHeight - 1, + MappedImage, &rpTemp); + + FreeBitMap(rpTemp.BitMap); + } + } + + Success = TRUE; + } while (0); + + if (ARGBImgArray) + MyFreeVecPooled(ARGBImgArray); + if (ARGBArray) + MyFreeVecPooled(ARGBArray); + if (MappedImage) + MyFreeVecPooled(MappedImage); + if (!Success && img->aiomi_PenList) + { + MyFreeVecPooled(img->aiomi_PenList); + img->aiomi_PenList = NULL; + } +} + +//---------------------------------------------------------------------------------------- + +static void MyDrawIconState(struct InstanceData *inst, struct RastPort *rp, + struct DrawInfo *drawInfo, ULONG State) +{ + d1(kprintf("%s/%ld: Screen=%08lx aio_fLayoutOk=%ld\n", \ + __FUNC__, __LINE__, inst->aio_Screen, inst->aio_fLayoutOk)); + + if (!inst->aio_fLayoutOk) + { + // LayoutIconA() + LayoutIcon(inst->aio_DiskObject, inst->aio_Screen, + TAG_END); + + inst->aio_fLayoutOk = TRUE; + } + + // DrawIconStateA() + DrawIconState(rp, inst->aio_DiskObject, NULL, + inst->aio_ImageLeft, inst->aio_ImageTop, State, + ICONDRAWA_DrawInfo, (ULONG) drawInfo, + ICONDRAWA_Frameless, TRUE, + ICONDRAWA_Borderless, TRUE, + ICONDRAWA_EraseBackground, FALSE, + TAG_END); +} + +//---------------------------------------------------------------------------------------- + +static UBYTE *GenerateMask(struct InstanceData *inst, struct MappedImage *img) +{ + UBYTE *MaskPlane = NULL; + + do { + ULONG BytesPerRow; + size_t MaskSize; + ULONG y; + UBYTE *MaskPtr; + UBYTE *ImgPtr; + + if (~0 == img->aiomi_TransparentColor) + break; + if (NULL == img->aiomi_ImageData) + break; + + BytesPerRow = ((inst->aio_MappedWidth + 15) & 0xfff0) >> 3; + MaskSize = inst->aio_MappedHeight * BytesPerRow; + + MaskPlane = MyAllocVecPooled(MaskSize); + if (NULL == MaskPlane) + break; + + memset(MaskPlane, 0, MaskSize); + + ImgPtr = img->aiomi_ImageData; + MaskPtr = MaskPlane; + for (y = 0; y < inst->aio_MappedHeight; y++) + { + ULONG x; + UBYTE *MaskPtr2 = MaskPtr; + UBYTE BitMask = 0x80; + + for (x = 0; x < inst->aio_MappedWidth; x++) + { + if (*ImgPtr++ != img->aiomi_TransparentColor) + { + *MaskPtr2 |= BitMask; + } + BitMask >>= 1; + if (0 == BitMask) + { + BitMask = 0x80; + MaskPtr2++; + } + } + + MaskPtr += BytesPerRow; + } + + img->aiomi_Mask = MaskPlane; + } while (0); + + return MaskPlane; +} + +//---------------------------------------------------------------------------------------- + +// set image borders of superclass to 0 +// for icons with Renderhook +static void SetSuperImgBorders(Class *cl, Object *o, struct opSet *ops) +{ + struct InstanceData *inst = INST_DATA(cl, o); + + if (inst->aio_RenderHook) + { + static struct TagItem AttrList[] = + { + { IDTA_InnerLeft, 0 }, + { IDTA_InnerTop, 0 }, + { IDTA_InnerRight, 0 }, + { IDTA_InnerBottom, 0 }, + { TAG_END, 0 }, + }; + + DoSuperMethod(cl, o, OM_SET, AttrList, ops->ops_GInfo); + } +} + +//---------------------------------------------------------------------------------------- + +static APTR MyAllocVecPooled(size_t Size) +{ + APTR ptr; + + if (MemPool) + { + ObtainSemaphore(&PubMemPoolSemaphore); + ptr = AllocPooled(MemPool, Size + sizeof(size_t)); + ReleaseSemaphore(&PubMemPoolSemaphore); + if (ptr) + { + size_t *sptr = (size_t *) ptr; + + sptr[0] = Size; + + d1(kprintf("%/%ld: MemPool=%08lx Size=%lu mem=%08lx\n", __FUNC__, __LINE__, MemPool, Size, &sptr[1])); + return (APTR)(&sptr[1]); + } + } + + d1(kprintf("%s/%ld: MemPool=%08lx Size=%lu\n", __FUNC__, __LINE__, MemPool, Size)); + + return NULL; +} + + +static void MyFreeVecPooled(APTR mem) +{ + d1(kprintf("%s/%ld: MemPool=%08lx mem=%08lx\n", __FUNC__, __LINE__, MemPool, mem)); + if (MemPool && mem) + { + size_t size; + size_t *sptr = (size_t *) mem; + + mem = &sptr[-1]; + size = sptr[-1]; + + ObtainSemaphore(&PubMemPoolSemaphore); + FreePooled(MemPool, mem, size + sizeof(size_t)); + ReleaseSemaphore(&PubMemPoolSemaphore); + } +} + +//---------------------------------------------------------------------------------------- + +static void WriteARGBArray(const struct ARGB *SrcImgData, + ULONG SrcX, ULONG SrcY, ULONG SrcBytesPerRow, + struct RastPort *DestRp, ULONG DestX, ULONG DestY, + ULONG SizeX, ULONG SizeY) +{ + struct BitMap *DestBM = DestRp->BitMap; + ULONG DestWidth; + ULONG DestHeight; + + DestWidth = GetCyberMapAttr(DestBM, CYBRMATTR_WIDTH); + DestHeight = GetCyberMapAttr(DestBM, CYBRMATTR_HEIGHT); + + d1(KPrintF("%s/%ld: DestX=%ld DestY=%ld SizeX=%ld SizeY=%ld\n", __FUNC__, __LINE__, DestX, DestY, SizeX, SizeY)); + d1(KPrintF("%s/%ld: SrcBytesPerRow=%ld\n", __FUNC__, __LINE__, SrcBytesPerRow)); + + if (DestX + SizeX > DestWidth) + SizeX = DestWidth - DestX; + if (DestY + SizeY > DestHeight) + SizeY = DestHeight - DestY; + + d1(KPrintF("%s/%ld: DestX=%ld DestY=%ld SizeX=%ld SizeY=%ld\n", __FUNC__, __LINE__, DestX, DestY, SizeX, SizeY)); + + WritePixelArray((APTR) SrcImgData, SrcX, SrcY, + SrcBytesPerRow, + DestRp, DestX, DestY, + SizeX, SizeY, + RECTFMT_ARGB); +} + +//---------------------------------------------------------------------------------------- + +static BOOL MappedImageFromSAC(struct InstanceData *inst, + struct MappedImage *mi, struct ScalosBitMapAndColor *sac) +{ + struct MappedImage MiNew; + struct BitMap *TempBM = NULL; + BOOL Success = FALSE; + + do { + ULONG n; + ULONG y; + const ULONG *PaletteSrcPtr; + struct ColorRegister *PaletteDestPtr; + struct RastPort rp; + struct RastPort TempRp; + UBYTE *ImagePtr; + ULONG NewWidth = sac->sac_Width; + ULONG NewHeight = sac->sac_Height; + + if (NULL == sac) + break; + + InitRastPort(&rp); + InitRastPort(&TempRp); + + rp.BitMap = sac->sac_BitMap; + d1(KPrintF(__FILE__ "/%s/%ld: rp.BitMap=%08lx\n", __FUNC__, __LINE__, rp.BitMap)); + + // setup temp. RastPort for use by WritePixelLine8() + TempRp.Layer = NULL; + TempRp.BitMap = TempBM = AllocBitMap(TEMPRP_WIDTH(NewWidth), 1, 8, 0, NULL); + + if (NULL == TempBM) + break; + + memset(&MiNew, 0, sizeof(MiNew)); + + MiNew.aiomi_ImageData = MiNew.aiomi_AllocatedImageData = MyAllocVecPooled(PIXELARRAY8_BUFFERSIZE(NewWidth, NewHeight)); + if (NULL == MiNew.aiomi_ImageData) + break; + + MiNew.aiomi_PaletteSize = sac->sac_NumColors; + MiNew.aiomi_Palette = MiNew.aiomi_AllocatedPalette = MyAllocVecPooled(sac->sac_NumColors * sizeof(struct ColorRegister)); + if (NULL == MiNew.aiomi_Palette) + break; + + if (SAC_TRANSPARENT_NONE != sac->sac_TransparentColor) + MiNew.aiomi_TransparentColor = sac->sac_TransparentColor; + else + MiNew.aiomi_TransparentColor = ~0; + + // nothing can go wrong from here on + Success = TRUE; + + d1(KPrintF("%s/%ld: NumColors=%lu\n", __FUNC__, __LINE__, sac->sac_NumColors)); + + // Fill nim_Palette fom sac_ColorTable + for (n = 0, PaletteSrcPtr = sac->sac_ColorTable, PaletteDestPtr = MiNew.aiomi_Palette; + n < sac->sac_NumColors; n++, PaletteDestPtr++) + { + PaletteDestPtr->red = *PaletteSrcPtr++ >> 24; // red + PaletteDestPtr->green = *PaletteSrcPtr++ >> 24; // green + PaletteDestPtr->blue = *PaletteSrcPtr++ >> 24; // blue + } + + d1(KPrintF("%s/%ld: \n", __FUNC__, __LINE__)); + + // copy image data from sac_BitMap into aiomi_ImageData + for (y = 0, ImagePtr = MiNew.aiomi_ImageData; y < NewHeight; y++) + { + d1(KPrintF("%s/%ld: y=%ld\n", __FUNC__, __LINE__, y)); + ReadPixelLine8(&rp, 0, y, NewWidth, + ImagePtr, &TempRp); + ImagePtr += NewWidth; + } + + d1(KPrintF("%s/%ld: \n", __FUNC__, __LINE__)); + + inst->aio_MappedWidth = NewWidth; + inst->aio_MappedHeight = NewHeight; + } while (0); + + if (Success) + { + FreeMappedImage(inst, mi); + *mi = MiNew; + } + else + { + FreeMappedImage(inst, &MiNew); + } + + if (TempBM) + FreeBitMap(TempBM); + + return Success; +} + +//---------------------------------------------------------------------------------------- + +static void FreeMappedImage(struct InstanceData *inst, struct MappedImage *mi) +{ + if (mi) + { + if (mi->aiomi_PenList) + { + FreePenList(inst->aio_Screen, &mi->aiomi_PenList, mi->aiomi_PaletteSize); + } + if (mi->aiomi_AllocatedImageData) + { + MyFreeVecPooled(mi->aiomi_AllocatedImageData); + mi->aiomi_AllocatedImageData = mi->aiomi_ImageData = NULL; + } + if (mi->aiomi_AllocatedPalette) + { + MyFreeVecPooled(mi->aiomi_AllocatedPalette); + mi->aiomi_AllocatedPalette = mi->aiomi_Palette = NULL; + mi->aiomi_PaletteSize = 0; + } + if (mi->aiomi_Mask) + { + MyFreeVecPooled(mi->aiomi_Mask); + mi->aiomi_Mask = NULL; + } + } +} + +//---------------------------------------------------------------------------------------- + +static BOOL SelectedImageFromNormalImage(struct InstanceData *inst) +{ + struct MappedImage MiNew; + + BOOL Success = FALSE; + + do { + ULONG n; + const struct ColorRegister *PaletteSrcPtr; + struct ColorRegister *PaletteDestPtr; + + + memset(&MiNew, 0, sizeof(MiNew)); + + // share aiomi_ImageData with normal image + MiNew.aiomi_ImageData = inst->aio_Image1.aiomi_ImageData; + + MiNew.aiomi_PaletteSize = inst->aio_Image1.aiomi_PaletteSize; + MiNew.aiomi_Palette = MiNew.aiomi_AllocatedPalette = MyAllocVecPooled(MiNew.aiomi_PaletteSize * sizeof(struct ColorRegister)); + if (NULL == MiNew.aiomi_Palette) + break; + + MiNew.aiomi_TransparentColor = inst->aio_Image1.aiomi_TransparentColor; + + // nothing can go wrong from here on + Success = TRUE; + + d1(KPrintF("%s/%ld: NumColors=%lu\n", __FUNC__, __LINE__, MiNew.aiomi_PaletteSize)); + + // copy palette from aio_Image1 and adjust colors + for (n = 0, PaletteSrcPtr = inst->aio_Image1.aiomi_Palette, PaletteDestPtr = MiNew.aiomi_Palette; + n < MiNew.aiomi_PaletteSize; n++) + { + *PaletteDestPtr = *PaletteSrcPtr++; + ChangeToSelectedIconColor(PaletteDestPtr++); + } + + d1(KPrintF("%s/%ld: \n", __FUNC__, __LINE__)); + } while (0); + + if (Success) + { + FreeMappedImage(inst, &inst->aio_Image2); + inst->aio_Image2 = MiNew; + } + else + { + FreeMappedImage(inst, &MiNew); + } + + return Success; +} + +//---------------------------------------------------------------------------------------- + +static void MySetFont(Object *o, struct RastPort *rp) +{ + struct Hook *FontHook = NULL; + struct TextFont *IconFont = NULL; + + GetAttr(IDTA_Font, o, (APTR) &IconFont); + GetAttr(IDTA_FontHook, o, (APTR) &FontHook); + + if (FontHook) + { + APTR FontHandle = NULL; + + GetAttr(IDTA_Fonthandle, o, (APTR) &FontHandle); + + if (FontHandle || IconFont) + { + struct ioFontMsg_SetFont iofsf; + + iofsf.MsgID = iofMsg_SETFONT; + iofsf.iofsf_RastPort = rp; + iofsf.iofsf_FontHandle = FontHandle; + iofsf.iofsf_TextFont = IconFont; + + CallHookPkt(FontHook, NULL, &iofsf); + + d1(KPrintF("%s/%ld: rp=%08lx FontHook=%08lx FontHandle=%08lx IconFont=%08lx\n", \ + __FUNC__, __LINE__, rp, FontHook, FontHandle, IconFont)); + } + } + else + { + if (IconFont) + SetFont(rp, IconFont); + } +} + +//---------------------------------------------------------------------------------------- diff --git a/scalos/datatypes/AmigaIconObj3.5/AmigaIconObj35.h b/scalos/datatypes/AmigaIconObj3.5/AmigaIconObj35.h new file mode 100644 index 000000000..7ea982f6e --- /dev/null +++ b/scalos/datatypes/AmigaIconObj3.5/AmigaIconObj35.h @@ -0,0 +1,143 @@ +// AmigaIconObj35.h +// $Date$ +// $Revision$ + + +#ifndef AMIGAICONOBJ35_H_INCLUDED +#define AMIGAICONOBJ35_H_INCLUDED + +#include +#include +#include +#include +#include + +#include + +//----------------------------------------------------------------------------- + +#define MEMPOOL_MEMFLAGS MEMF_PUBLIC +#define MEMPOOL_PUDDLESIZE 16384 +#define MEMPOOL_THRESHSIZE 16384 + +//----------------------------------------------------------------------------- + +#define LIB_VERSION 40 +#define LIB_REVISION 18 + +extern char ALIGNED libName[]; +extern char ALIGNED libIdString[]; + +//----------------------------------------------------------------------------- + +struct AmigaIconObj35DtLibBase + { + struct ClassLibrary nib_ClassLibrary; + + struct SegList *nib_SegList; + + UBYTE nib_Initialized; + }; + +//----------------------------------------------------------------------------- + +ULONG InitDatatype(struct AmigaIconObj35DtLibBase *dtLib); +ULONG OpenDatatype(struct AmigaIconObj35DtLibBase *dtLib); +void CloseDatatype(struct AmigaIconObj35DtLibBase *dtLib); + +LIBFUNC_PROTO(ObtainInfoEngine, libbase, ULONG); + +//----------------------------------------------------------------------------- + +struct MappedImage + { + UBYTE *aiomi_ImageData; // Image data, 1 byte per pixel + + struct ColorRegister *aiomi_Palette; + ULONG aiomi_PaletteSize; // number of entries in aiomi_Palette + + UBYTE *aiomi_PenList; // (allocated) array of used pens + + ULONG aiomi_TransparentColor; + + UBYTE *aiomi_Mask; + + UBYTE *aiomi_AllocatedImageData; + struct ColorRegister *aiomi_AllocatedPalette; + }; + + +struct InstanceData + { + struct DiskObject *aio_DiskObject; + struct DrawerData *aio_myDrawerData; + struct Screen *aio_Screen; + + struct MappedImage aio_Image1; + struct MappedImage aio_Image2; + + UWORD aio_ImageLeft; + UWORD aio_ImageTop; + UWORD aio_MappedWidth; + UWORD aio_MappedHeight; + + ULONG aio_Borderless; + + UBYTE aio_DoNotFreeDiskObject; //Flag: free icon on quit ? + UBYTE aio_AlwaysUseDrawIconState; //Flag: always use icon.library DrawIconStateA() + UBYTE aio_fIsPaletteMapped; //Flag: is palette mapped icon + UBYTE aio_fLayoutOk; + + struct Hook *aio_RenderHook; //new (struct Hook *) + }; + +//--------------------------------------------------------------- + +struct tmp + { + ULONG tmp_width; + ULONG tmp_height; + ULONG tmp_ispalmapped; + }; + +//--------------------------------------------------------------- + +// private and temporary Data during dtWrite + +struct WriteData + { + STRPTR aiowd_DefaultTool; + STRPTR *aiowd_ToolTypes; + ULONG aiowd_StackSize; + struct IBox *aiowd_WindowRect; + ULONG aiowd_CurrentX; + ULONG aiowd_CurrentY; + ULONG aiowd_Flags; + ULONG aiowd_ViewModes; + ULONG aiowd_Type; + }; + +/* ------------------------------------------------- */ + +#define Sizeof(x) (sizeof(x) / sizeof(x[0])) + +// Width for TempRp.BitMap for ReadPixelLine8() and WritePixelLine8() +#define TEMPRP_WIDTH(width) (8 * ((((width) + 15) >> 4) << 1)) + +/* ------------------------------------------------- */ + +// from debug.lib +#ifdef __AROS__ +#include +#define KPrintF kprintf +#else +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); +#endif + +#define d1(x) ; +#define d2(x) { Forbid(); x; Permit(); } + +/* ------------------------------------------------- */ + +#endif // AMIGAICONOBJ35_H_INCLUDED diff --git a/scalos/datatypes/AmigaIconObj3.5/config.mk b/scalos/datatypes/AmigaIconObj3.5/config.mk new file mode 100755 index 000000000..c9b9a7c12 --- /dev/null +++ b/scalos/datatypes/AmigaIconObj3.5/config.mk @@ -0,0 +1,51 @@ +# $Date: 2012-08-10 13:47:28 +0200 (Fr, 10. Aug 2012) $ +# $Revision: 915 $ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +MKDIR = mkdir -p #makedir force +DT_DIR = scalos:IconDatatypes/datatypes + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += -nostartfiles \ + -lmempools \ +# --verbose + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += -nostartfiles \ + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +LFLAGS += -nostartfiles -larossupport \ + +else + +############################################################################### +# AmigaOS + +LFLAGS += -lamiga21 -ldebug -lmcpgfx -lnix -lamiga -lstubs + +endif +endif +endif diff --git a/scalos/datatypes/AmigaIconObj3.5/makefile b/scalos/datatypes/AmigaIconObj3.5/makefile new file mode 100644 index 000000000..411326c74 --- /dev/null +++ b/scalos/datatypes/AmigaIconObj3.5/makefile @@ -0,0 +1,104 @@ +# makefile für Scalos IconObject datatypes stuff +# $Date$ +# $Revision$ +##################################################################### + +ASRCS = +CSRCS = AmigaIconObj35-classic.c AmigaIconObj35.c + +##################################################################### + +AS = phxAss +LD = slink +CC = sc +SPLAT = sc:c/splat +MKDIR = mkdir -p #makedir force +LIBS = LIB:debug.lib LIB:sc.lib LIB:amiga.lib +PRECOMP = Include:all.gst +DT_DIR = scalos:IconDatatypes/datatypes +OBJDIR = .sasobj + +.SUFFIXES: .asm + +##################################################################### + +CFLAGS = optimize nostackcheck nover math=standard data=far \ + dbg=f idir=//include +LNFLAGS = batch noicons stripdebug quiet +LNDBFLAGS = batch noicons addsym quiet + +ifdef L +AFLAGS = quiet DS NOEXE opt=NRQB LIST=* linedebug I=SC:Assembler_Headers +else +AFLAGS = quiet DS NOEXE opt=NRQB linedebug I=SC:Assembler_Headers +endif + +##################################################################### + +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(CSRCS:%.c=$(OBJDIR)/%.o) + +##################################################################### + +DTNAME = .bin_os3/amigaiconobj35.datatype +DTDBGNAME = $(DTNAME).debug + +##################################################################### + +all: $(DTNAME) \ + $(DTDBGNAME) + +##################################################################### + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +##################################################################### + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $* objectname $@ + +$(OBJDIR)/%.o : %.s + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +$(OBJDIR)/%.o : %.asm + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +##################################################################### + +$(DTNAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) from $(OBJS) to $(DTNAME) LIB $(LIBS) $(LNFLAGS) + +$(DTDBGNAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) from $(OBJS) to $(DTDBGNAME) LIB $(LIBS) $(LNDBFLAGS) + +##################################################################### + +$(OBJDIR)/AmigaIconObj35-classic.o : AmigaIconObj35.h +$(OBJDIR)/AmigaIconObj35.o : AmigaIconObj35.h + +##################################################################### + +install: + @printf '\033[32mFlushing memory...\033[0m\n' + avail flush + @printf '\033[32mInstall: \033[31m\033[1m$(DTNAME)\033[0m\n' + -@$(MKDIR) $(DT_DIR) + copy $(DTNAME) $(DT_DIR) + +##################################################################### + +clean: + -@delete $(DTNAME) $(DTDBGNAME) $(OBJS) + +############################################################# + +nodebug: + -@$(SPLAT) -s -o "d2(" "d1(" "#?.c" + +##################################################################### + diff --git a/scalos/datatypes/AmigaIconObj3.5/makefile-new b/scalos/datatypes/AmigaIconObj3.5/makefile-new new file mode 100755 index 000000000..0e7c581b4 --- /dev/null +++ b/scalos/datatypes/AmigaIconObj3.5/makefile-new @@ -0,0 +1,74 @@ +# $Date: 2011-07-09 20:50:13 +0200 (Sa, 09. Jul 2011) $ +# $Revision: 759 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +ifeq ($(MACHINE), ppc-amigaos) +OBJS = $(OBJDIR)/AmigaIconObj35-aos4.o $(OBJDIR)/AmigaIconObj35.o +else +ifeq ($(MACHINE), i386-aros) +OBJS = $(OBJDIR)/AmigaIconObj35-aros.o $(OBJDIR)/AmigaIconObj35.o +else +OBJS = $(OBJDIR)/AmigaIconObj35-classic.o $(OBJDIR)/AmigaIconObj35.o +endif +endif + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Targets +# + +NAME = amigaiconobj35.datatype +NAME_DB = amigaiconobj35.datatype.debug + +############################################################################## + +.PHONY: all install clean bump dump + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + @$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + -@$(MKDIR) $(DT_DIR) + @copy $(BINDIR)/$(NAME) $(DT_DIR) + @avail flush + + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* + +############################################################################## diff --git a/scalos/datatypes/AmigaIconObject/AmigaIconObject-aos4.c b/scalos/datatypes/AmigaIconObject/AmigaIconObject-aos4.c new file mode 100644 index 000000000..a7333c762 --- /dev/null +++ b/scalos/datatypes/AmigaIconObject/AmigaIconObject-aos4.c @@ -0,0 +1,190 @@ +// AmigaIconObject-aos4.c +// $Date$ +// $Revision$ + + +#include +#include +#include + +#include +#include + +#include + +#include "AmigaIconObject.h" + +int _start(void) +{ + return -1; +} + +static struct Library *Initlib(struct Library *libbase, BPTR seglist, struct ExecIFace *pIExec); +static BPTR Expungelib(struct LibraryManagerInterface *Self); +static struct LibraryHeader *Openlib(struct LibraryManagerInterface *Self, ULONG version); +static BPTR Closelib(struct LibraryManagerInterface *Self); +static ULONG Obtainlib(struct LibraryManagerInterface *Self); +static ULONG Releaselib(struct LibraryManagerInterface *Self); + +extern struct ExecBase *SysBase; + +/* OS4.0 Library */ + +/* ------------------- OS4 Manager Interface ------------------------ */ +static const APTR managerfunctable[] = + { + (APTR)Obtainlib, + (APTR)Releaselib, + (APTR)NULL, + (APTR)NULL, + (APTR)Openlib, + (APTR)Closelib, + (APTR)Expungelib, + (APTR)NULL, + (APTR)-1 + }; + +static const struct TagItem managertags[] = + { + {MIT_Name, (ULONG)"__library"}, + {MIT_VectorTable, (ULONG)managerfunctable}, + {MIT_Version, 1}, + {TAG_DONE, 0} + }; + +/* ---------------------- OS4 Main Interface ------------------------ */ +static APTR functable[] = + { + Obtainlib, + Releaselib, + NULL, + NULL, + ObtainInfoEngine, + (APTR) -1 + }; + +static const struct TagItem maintags[] = + { + {MIT_Name, (ULONG)"main"}, + {MIT_VectorTable, (ULONG)functable}, + {MIT_Version, 1}, + {TAG_DONE, 0} + }; + +/* Init table used in library initialization. */ +static const ULONG interfaces[] = + { + (ULONG)managertags, + (ULONG)maintags, + (ULONG)0 + }; + +static const struct TagItem inittab[] = + { + {CLT_DataSize, (ULONG)sizeof(struct AmigaIconObjectDtLibBase)}, + {CLT_Interfaces, (ULONG) interfaces}, +// {CLT_Vector68K, (ULONG)VecTable68K}, + {CLT_InitFunc, (ULONG) Initlib}, + {TAG_DONE, 0} + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, + RTF_NATIVE | RTF_AUTOINIT, + LIB_VERSION, + NT_LIBRARY, + 0, + libName, + libIdString, + (struct TagItem *)inittab + }; + +/* ------------------- OS4 Manager Functions ------------------------ */ +static struct Library * Initlib(struct Library *libbase, BPTR seglist, struct ExecIFace *pIExec) +{ + struct AmigaIconObjectDtLibBase *IconObjLibBase = (struct AmigaIconObjectDtLibBase *) libbase; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)libbase + libbase->lib_PosSize); + struct LibraryManagerInterface *Self = (struct LibraryManagerInterface *) ExtLib->ILibrary; + + SysBase = (struct ExecBase *)pIExec->Data.LibBase; + IExec = pIExec; + IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_Revision = LIB_REVISION; + IconObjLibBase->nib_SegList = (struct SegList *)seglist; + + if (!InitDatatype(IconObjLibBase)) + { + Expungelib(Self); + IconObjLibBase = NULL; + } + + return (struct Library *)IconObjLibBase; +} + +static BPTR Expungelib(struct LibraryManagerInterface *Self) +{ + struct AmigaIconObjectDtLibBase *IconObjLibBase = (struct AmigaIconObjectDtLibBase *) Self->Data.LibBase; + + if (0 == IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + struct SegList *libseglist = IconObjLibBase->nib_SegList; + + Remove((struct Node *) IconObjLibBase); + CloseDatatype(IconObjLibBase); + DeleteLibrary((struct Library *)IconObjLibBase); + + return (BPTR)libseglist; + } + + IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_Flags |= LIBF_DELEXP; + + return (BPTR)NULL; +} + +static struct LibraryHeader *Openlib(struct LibraryManagerInterface *Self, ULONG version) +{ + struct AmigaIconObjectDtLibBase *IconObjLibBase = (struct AmigaIconObjectDtLibBase *) Self->Data.LibBase; + + IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_OpenCnt++; + IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_Flags &= ~LIBF_DELEXP; + + if (!OpenDatatype(IconObjLibBase)) + { + Closelib(Self); + return NULL; + } + + return (struct LibraryHeader *)IconObjLibBase; +} + +static BPTR Closelib(struct LibraryManagerInterface *Self) +{ + struct AmigaIconObjectDtLibBase *IconObjLibBase = (struct AmigaIconObjectDtLibBase *) Self->Data.LibBase; + + IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_OpenCnt--; +/* + if (0 == IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + if (IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_Flags & LIBF_DELEXP) + { + return Expungelib(Self); + } + } +*/ + return (BPTR)NULL; +} + +static ULONG Obtainlib(struct LibraryManagerInterface *Self) +{ + return(Self->Data.RefCount++); +} + +static ULONG Releaselib(struct LibraryManagerInterface *Self) +{ + return(Self->Data.RefCount--); +} + diff --git a/scalos/datatypes/AmigaIconObject/AmigaIconObject-aros.c b/scalos/datatypes/AmigaIconObject/AmigaIconObject-aros.c new file mode 100644 index 000000000..e19c52a8d --- /dev/null +++ b/scalos/datatypes/AmigaIconObject/AmigaIconObject-aros.c @@ -0,0 +1,214 @@ +// amigaiconobject-classic.c +// $Date$ +// $Revision$ + + +#include +#include + +#include + +#include + + +#include "AmigaIconObject.h" + +//---------------------------------------------------------------------------- + +extern struct ExecBase *SysBase; + +struct Library *aroscbase; + +//---------------------------------------------------------------------------- + +// Standard library functions + +static AROS_UFP3 (struct Library *, Initlib, + AROS_UFPA(struct Library *, libbase, D0), + AROS_UFPA(struct SegList *, seglist, A0), + AROS_UFPA(struct ExecBase *, sysbase, A6) +); +static AROS_LD1 (struct Library *, Openlib, + AROS_LPA (__unused ULONG, version, D0), + struct Library *, libbase, 1, AmigaIconObject +); +static AROS_LD0 (struct SegList *, Closelib, + struct Library *, base, 2, AmigaIconObject +); +static AROS_LD1 (struct SegList *, Expungelib, + AROS_LPA(__unused struct Library *, __extrabase, D0), + struct Library *, libbase, 3, AmigaIconObject +); +static AROS_LD0 (ULONG, Extfunclib, + __unused struct Library *, libbase, 4, AmigaIconObject +); + +//---------------------------------------------------------------------------- + +SAVEDS(LONG) ASM Libstart(void) +{ + return -1; +} + +//---------------------------------------------------------------------------- +/* OS3.x Library */ + +static APTR functable[] = + { + AmigaIconObject_1_Openlib, + AmigaIconObject_2_Closelib, + AmigaIconObject_3_Expungelib, + AmigaIconObject_4_Extfunclib, + Dummy_0_ObtainInfoEngine, + (APTR) -1 + }; + +/* Init table used in library initialization. */ +static ULONG inittab[] = + { + sizeof(struct AmigaIconObjectDtLibBase), + (ULONG) functable, + 0, + (ULONG) Initlib + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, + RTF_AUTOINIT, + LIB_VERSION, + NT_LIBRARY, + 0, + libName, + libIdString, + inittab + }; + +//---------------------------------------------------------------------------- + +static AROS_UFH3(struct Library *, Initlib, + AROS_UFHA(struct Library *, libbase, D0), + AROS_UFHA(struct SegList *, seglist, A0), + AROS_UFHA(struct ExecBase *, sysbase, A6) +) +{ + AROS_USERFUNC_INIT + + struct AmigaIconObjectDtLibBase *dtLib = (struct AmigaIconObjectDtLibBase *) libbase; + + SysBase = sysbase; + dtLib->nib_ClassLibrary.cl_Lib.lib_Revision = LIB_REVISION; + dtLib->nib_SegList = seglist; + + aroscbase = OpenLibrary("arosc.library", 0); + + if (!aroscbase || !InitDatatype(dtLib)) + { + AmigaIconObject_3_Expungelib(&dtLib->nib_ClassLibrary.cl_Lib, &dtLib->nib_ClassLibrary.cl_Lib); + dtLib = NULL; + } + + return dtLib ? &dtLib->nib_ClassLibrary.cl_Lib : NULL; + + AROS_USERFUNC_EXIT +} + + +static AROS_LH1(struct Library *, Openlib, + AROS_LHA(__unused ULONG, version, D0), + struct Library *, libbase, 1, AmigaIconObject +) +{ + AROS_LIBFUNC_INIT + + struct AmigaIconObjectDtLibBase *dtLib = (struct AmigaIconObjectDtLibBase *) libbase; + + dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt++; + dtLib->nib_ClassLibrary.cl_Lib.lib_Flags &= ~LIBF_DELEXP; + + if (!OpenDatatype(dtLib)) + { + AmigaIconObject_2_Closelib(&dtLib->nib_ClassLibrary.cl_Lib); + return NULL; + } + + return &dtLib->nib_ClassLibrary.cl_Lib; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH0(struct SegList *, Closelib, + struct Library *, libbase, 2, AmigaIconObject +) +{ + AROS_LIBFUNC_INIT + + struct AmigaIconObjectDtLibBase *dtLib = (struct AmigaIconObjectDtLibBase *) libbase; + + dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt--; + + if (0 == dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + if (dtLib->nib_ClassLibrary.cl_Lib.lib_Flags & LIBF_DELEXP) + { + return AmigaIconObject_3_Expungelib(&dtLib->nib_ClassLibrary.cl_Lib, &dtLib->nib_ClassLibrary.cl_Lib); + } + } + + return NULL; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH1(struct SegList *, Expungelib, + AROS_LHA(__unused struct Library *, __extrabase, D0), + struct Library *, libbase, 3, AmigaIconObject +) +{ + AROS_LIBFUNC_INIT + + struct AmigaIconObjectDtLibBase *dtLib = (struct AmigaIconObjectDtLibBase *) libbase; + + if (0 == dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + ULONG size = dtLib->nib_ClassLibrary.cl_Lib.lib_NegSize + dtLib->nib_ClassLibrary.cl_Lib.lib_PosSize; + UBYTE *ptr = (UBYTE *) dtLib - dtLib->nib_ClassLibrary.cl_Lib.lib_NegSize; + struct SegList *libseglist = dtLib->nib_SegList; + + Remove((struct Node *) dtLib); + CloseDatatype(dtLib); + FreeMem(ptr,size); + + CloseLibrary(aroscbase); + + return libseglist; + } + + dtLib->nib_ClassLibrary.cl_Lib.lib_Flags |= LIBF_DELEXP; + + return NULL; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH0(ULONG, Extfunclib, + __unused struct Library *, libbase, 4, AmigaIconObject +) +{ + AROS_LIBFUNC_INIT + + return 0; + + AROS_LIBFUNC_EXIT +} + +//----------------------------------------------------------------------------- + + diff --git a/scalos/datatypes/AmigaIconObject/AmigaIconObject-classic.c b/scalos/datatypes/AmigaIconObject/AmigaIconObject-classic.c new file mode 100644 index 000000000..d55247baa --- /dev/null +++ b/scalos/datatypes/AmigaIconObject/AmigaIconObject-classic.c @@ -0,0 +1,181 @@ +// amigaiconobject-classic.c +// $Date$ +// $Revision$ + + +#include +#include + +#include + +#include + + +#include "AmigaIconObject.h" + +//---------------------------------------------------------------------------- + +extern struct ExecBase *SysBase; + +//---------------------------------------------------------------------------- + +// Standard library functions + +static LIB_SAVEDS(struct Library *) LIB_ASM LIB_INTERRUPT Initlib(LIB_REG(d0, struct Library *libbase), + LIB_REG(a0, struct SegList *seglist), LIB_REG(a6, struct ExecBase *sysbase)); + +static LIBFUNC_PROTO(Openlib, libbase, struct Library *); +static LIBFUNC_PROTO(Closelib, libbase, struct SegList *); +static LIBFUNC_PROTO(Expungelib, libbase, struct SegList *); +static LIBFUNC_PROTO(Extfunclib, libbase, ULONG); + + +//---------------------------------------------------------------------------- + +SAVEDS(LONG) ASM Libstart(void) +{ + return -1; +} + +//---------------------------------------------------------------------------- +/* OS3.x Library */ + +static APTR functable[] = + { +#ifdef __MORPHOS__ + (APTR) FUNCARRAY_32BIT_NATIVE, +#endif + Openlib, + Closelib, + Expungelib, + Extfunclib, + ObtainInfoEngine, + (APTR) -1 + }; + +/* Init table used in library initialization. */ +static ULONG inittab[] = + { + sizeof(struct AmigaIconObjectDtLibBase), + (ULONG) functable, + 0, + (ULONG) Initlib + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, +#ifdef __MORPHOS__ + RTF_PPC | RTF_AUTOINIT, +#else + RTF_AUTOINIT, +#endif + LIB_VERSION, + NT_LIBRARY, + 0, + libName, + libIdString, + inittab + }; + +#ifdef __MORPHOS__ +ULONG __abox__=1; +#endif + +//---------------------------------------------------------------------------- + +static LIB_SAVEDS(struct Library *) LIB_ASM LIB_INTERRUPT Initlib(LIB_REG(d0, struct Library *libbase), + LIB_REG(a0, struct SegList *seglist), LIB_REG(a6, struct ExecBase *sysbase)) +{ + struct AmigaIconObjectDtLibBase *dtLib = (struct AmigaIconObjectDtLibBase *) libbase; + + SysBase = sysbase; + dtLib->nib_ClassLibrary.cl_Lib.lib_Revision = LIB_REVISION; + dtLib->nib_SegList = seglist; + + if (!InitDatatype(dtLib)) + { + CALLLIBFUNC(Expungelib, &dtLib->nib_ClassLibrary.cl_Lib); + dtLib = NULL; + } + + return dtLib ? &dtLib->nib_ClassLibrary.cl_Lib : NULL; +} + + +static LIBFUNC(Openlib, libbase, struct Library *) +{ + struct AmigaIconObjectDtLibBase *dtLib = (struct AmigaIconObjectDtLibBase *) libbase; + + dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt++; + dtLib->nib_ClassLibrary.cl_Lib.lib_Flags &= ~LIBF_DELEXP; + + if (!OpenDatatype(dtLib)) + { + CALLLIBFUNC(Closelib, &dtLib->nib_ClassLibrary.cl_Lib); + return NULL; + } + + return &dtLib->nib_ClassLibrary.cl_Lib; +} +LIBFUNC_END + + +static LIBFUNC(Closelib, libbase, struct SegList *) +{ + struct AmigaIconObjectDtLibBase *dtLib = (struct AmigaIconObjectDtLibBase *) libbase; + + dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt--; + + if (0 == dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + if (dtLib->nib_ClassLibrary.cl_Lib.lib_Flags & LIBF_DELEXP) + { + return CALLLIBFUNC(Expungelib, &dtLib->nib_ClassLibrary.cl_Lib); + } + } + + return NULL; +} +LIBFUNC_END + + +static LIBFUNC(Expungelib, libbase, struct SegList *) +{ + struct AmigaIconObjectDtLibBase *dtLib = (struct AmigaIconObjectDtLibBase *) libbase; + + if (0 == dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + ULONG size = dtLib->nib_ClassLibrary.cl_Lib.lib_NegSize + dtLib->nib_ClassLibrary.cl_Lib.lib_PosSize; + UBYTE *ptr = (UBYTE *) dtLib - dtLib->nib_ClassLibrary.cl_Lib.lib_NegSize; + struct SegList *libseglist = dtLib->nib_SegList; + + Remove((struct Node *) dtLib); + CloseDatatype(dtLib); + FreeMem(ptr,size); + + return libseglist; + } + + dtLib->nib_ClassLibrary.cl_Lib.lib_Flags |= LIBF_DELEXP; + + return NULL; +} +LIBFUNC_END + + +static LIBFUNC(Extfunclib, libbase, ULONG) +{ + (void) libbase; + d1(kprintf(__FUNC__ "/%ld: libbase=%08lx\n", __LINE__, libbase)); + return 0; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + + diff --git a/scalos/datatypes/AmigaIconObject/AmigaIconObject.c b/scalos/datatypes/AmigaIconObject/AmigaIconObject.c new file mode 100644 index 000000000..25ac432dd --- /dev/null +++ b/scalos/datatypes/AmigaIconObject/AmigaIconObject.c @@ -0,0 +1,1025 @@ +// AmigaIconObject.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define __USE_SYSBASE +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "AmigaIconObject.h" + +//---------------------------------------------------------------------------- + +#define max(a,b) ((a) > (b) ? (a) : (b)) +#define min(a,b) ((a) < (b) ? (a) : (b)) + +#define NO_ICON_POSITION_WORD ((WORD) 0x8000) + +//---------------------------------------------------------------------------- + +struct argb + { + UBYTE a; // alpha + UBYTE r; // red + UBYTE g; // green + UBYTE b; // blue + }; + +//---------------------------------------------------------------------------- + +struct Library *WorkbenchBase; +struct GfxBase *GfxBase; +T_UTILITYBASE UtilityBase; +struct DosLibrary *DOSBase; +struct ExecBase *SysBase; +struct Library *IconBase; +struct Library *IconObjectDTBase; +struct IntuitionBase *IntuitionBase; +#ifdef __amigaos4__ +struct Library *NewlibBase; +struct Interface *INewlib; +struct WorkbenchIFace *IWorkbench; +struct GraphicsIFace *IGraphics; +struct UtilityIFace *IUtility; +struct ExecIFace *IExec; +struct IconIFace *IIcon; +struct DOSIFace *IDOS; +struct IntuitionIFace *IIntuition; +#endif /* __amigaos4__ */ + +static void *MemPool; +static struct SignalSemaphore PubMemPoolSemaphore; + +static Class *AmigaIconObjectClass; + +//---------------------------------------------------------------------------- + +static SAVEDS(ULONG) INTERRUPT AmigaIconObjectDispatcher(Class *cl, Object *o, Msg msg); + +//----------------------------------------------------------------------------- + +static BOOL DtNew(Class *cl, Object *o, struct opSet *ops); +static ULONG DtDispose(Class *cl, Object *o, Msg msg); +static ULONG DtSet(Class *cl, Object *o, struct opSet *ops); +static ULONG DtGet(Class *cl, Object *o, struct opGet *opg); +static ULONG DtLayout(Class *cl, Object *o, struct iopLayout *iopl); +static ULONG DtWrite(Class *cl, Object *o, struct iopWrite *iopw); +static ULONG DtNewImage(Class *cl, Object *o, struct iopNewImage *iopw); +static ULONG DtClone(Class *cl, Object *o, struct iopCloneIconObject *iocio); +static void DoUpdateWb(struct InstanceData *inst, CONST_STRPTR SavePath); + +//---------------------------------------------------------------------------- + +static void ExchangeAttrs(struct DiskObject *DiskObj, struct WriteData *wd); + +//---------------------------------------------------------------------------- + +static APTR MyAllocVecPooled(size_t Size); +static void MyFreeVecPooled(APTR mem); + +//---------------------------------------------------------------------------- + +char ALIGNED libName[] = "amigaiconobject.datatype"; +char ALIGNED libIdString[] = "$VER: amigaiconobject.datatype " + STR(LIB_VERSION) "." STR(LIB_REVISION) + " (22 Feb 2006 19:54:14) " + COMPILER_STRING + " ©1999" CURRENTYEAR " The Scalos Team"; + +//---------------------------------------------------------------------------- + +LIBFUNC(ObtainInfoEngine, libbase, ULONG) +{ + (void) libbase; + + return (ULONG) AmigaIconObjectClass; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +// return 0 if error occurred +ULONG InitDatatype(struct AmigaIconObjectDtLibBase *dtLib) +{ + d1(kprintf("%s/%ld:\n", __FUNC__, __LINE__)); + + dtLib->nib_Initialized = FALSE; + + return 1; +} + +// return 0 if error occurred +ULONG OpenDatatype(struct AmigaIconObjectDtLibBase *dtLib) +{ + d1(kprintf("%s/%ld: OpenCnt=%ld\n", __FUNC__, __LINE__, dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt)); + + if (!dtLib->nib_Initialized) + { + d1(kprintf("%s/%ld: \n", __FUNC__, __LINE__)); + + dtLib->nib_Initialized = TRUE; + + InitSemaphore(&PubMemPoolSemaphore); + + DOSBase = (struct DosLibrary *) OpenLibrary("dos.library", 39); +#ifdef __amigaos4__ + if (DOSBase != NULL) + { + IDOS = (struct DOSIFace *)GetInterface((struct Library *)DOSBase, "main", 1, NULL); + if (IDOS == NULL) + { + CloseLibrary((struct Library *)DOSBase); + DOSBase = NULL; + } + } +#endif /* __amigaos4__ */ + d1(KPrintF("%s/%ld: DOSBase=%08lx\n", __FUNC__, __LINE__, IntuitionBase)); + if (NULL == DOSBase) + return 0; + + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); +#ifdef __amigaos4__ + if (IntuitionBase != NULL) + { + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (IIntuition == NULL) + { + CloseLibrary((struct Library *)IntuitionBase); + IntuitionBase = NULL; + } + } +#endif /* __amigaos4__ */ + d1(kprintf("%s/%ld: IntuitionBase=%08lx\n", __FUNC__, __LINE__, IntuitionBase)); + if (NULL == IntuitionBase) + return 0; + + UtilityBase = (T_UTILITYBASE) OpenLibrary("utility.library", 39); +#ifdef __amigaos4__ + if (UtilityBase != NULL) + { + IUtility = (struct UtilityIFace *)GetInterface((struct Library *)UtilityBase, "main", 1, NULL); + if (IUtility == NULL) + { + CloseLibrary((struct Library *)UtilityBase); + UtilityBase = NULL; + } + } +#endif /* __amigaos4__ */ + d1(kprintf("%s/%ld: UtilityBase=%08lx\n", __FUNC__, __LINE__, UtilityBase)); + if (NULL == UtilityBase) + return 0; + + IconBase = OpenLibrary(ICONNAME, 39); +#ifdef __amigaos4__ + if (IconBase != NULL) + { + IIcon = (struct IconIFace *)GetInterface((struct Library *)IconBase, "main", 1, NULL); + if (IIcon == NULL) + { + CloseLibrary((struct Library *)IconBase); + IconBase = NULL; + } + } +#endif /* __amigaos4__ */ + d1(kprintf("%s/%ld: IconBase=%08lx\n", __FUNC__, __LINE__, IconBase)); + if (NULL == IconBase) + return 0; + + GfxBase = (struct GfxBase *) OpenLibrary(GRAPHICSNAME, 39); +#ifdef __amigaos4__ + if (GfxBase != NULL) + { + IGraphics = (struct GraphicsIFace *)GetInterface((struct Library *)GfxBase, "main", 1, NULL); + if (IGraphics == NULL) + { + CloseLibrary((struct Library *)GfxBase); + GfxBase = NULL; + } + } +#endif /* __amigaos4__ */ + d1(kprintf("%s/%ld: GfxBase=%08lx\n", __FUNC__, __LINE__, GfxBase)); + if (NULL == GfxBase) + return 0; + + WorkbenchBase = OpenLibrary("workbench.library", 39); + d1(KPrintF("%s/%s/%ld: WorkbenchBase=%08lx\n", __FILE__, __FUNC__, __LINE__, WorkbenchBase)); + if (NULL == WorkbenchBase) + return 0; +#ifdef __amigaos4__ + IWorkbench = (struct WorkbenchIFace *)GetInterface((struct Library *)WorkbenchBase, "main", 1, NULL); + if (NULL == IWorkbench) + return 0; + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + return 0; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + return 0; +#endif /* __amigaos4__ */ + + IconObjectDTBase = OpenLibrary("datatypes/iconobject.datatype", 39); + if (NULL == IconObjectDTBase) + return 0; + + MemPool = CreatePool(MEMPOOL_MEMFLAGS, MEMPOOL_PUDDLESIZE, MEMPOOL_THRESHSIZE); + d1(kprintf("%s/%ld: MemPool=%08lx\n", __FUNC__, __LINE__, MemPool)); + if (NULL == MemPool) + return 0; + + AmigaIconObjectClass = dtLib->nib_ClassLibrary.cl_Class = MakeClass(libName, + "iconobject.datatype", NULL, sizeof(struct InstanceData), 0); + d1(kprintf("%s/%ld: AmigaIconObjectClass=%08lx\n", __FUNC__, __LINE__, AmigaIconObjectClass)); + if (NULL == AmigaIconObjectClass) + return 0; + + SETHOOKFUNC(AmigaIconObjectClass->cl_Dispatcher, AmigaIconObjectDispatcher); + AmigaIconObjectClass->cl_Dispatcher.h_Data = dtLib; + + // Make class available for the public + AddClass(AmigaIconObjectClass); + } + + d1(kprintf("%s/%ld: Open Success!\n", __FUNC__, __LINE__)); + + return 1; +} + +void CloseDatatype(struct AmigaIconObjectDtLibBase *dtLib) +{ + d1(kprintf("%s/%s/%ld: OpenCnt=%ld\n", __FILE__, __FUNC__, __LINE__, dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt)); + + if (dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt < 1) + { +#ifdef __amigaos4__ + if (INewlib) + { + DropInterface(INewlib); + INewlib = NULL; + } + if (NewlibBase) + { + CloseLibrary(NewlibBase); + NewlibBase = NULL; + } +#endif + if (AmigaIconObjectClass) + { + RemoveClass(AmigaIconObjectClass); + FreeClass(AmigaIconObjectClass); + AmigaIconObjectClass = dtLib->nib_ClassLibrary.cl_Class = NULL; + } + + if (NULL != IconObjectDTBase) + { + CloseLibrary(IconObjectDTBase); + IconObjectDTBase = NULL; + } + if (NULL != IconBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)IIcon); +#endif /* __amigaos4__ */ + CloseLibrary(IconBase); + IconBase = NULL; + } + + if (NULL != MemPool) + { + DeletePool(MemPool); + MemPool = NULL; + } + + if (NULL != GfxBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)IGraphics); +#endif /* __amigaos4__ */ + CloseLibrary((struct Library *) GfxBase); + GfxBase = NULL; + } + if (NULL != DOSBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)IDOS); +#endif /* __amigaos4__ */ + CloseLibrary((struct Library *) DOSBase); + DOSBase = NULL; + } +#ifdef __amigaos4__ + if (NULL != IWorkbench) + { + DropInterface((struct Interface *)IWorkbench); + IWorkbench = NULL; + } +#endif /* __amigaos4__ */ + if (NULL != WorkbenchBase) + { + CloseLibrary(WorkbenchBase); + WorkbenchBase = NULL; + } + if (NULL != IntuitionBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)IIntuition); +#endif /* __amigaos4__ */ + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } + if (NULL != UtilityBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)IUtility); +#endif /* __amigaos4__ */ + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } + } + d1(kprintf("%s/%s/%ld: OpenCnt=%ld\n", __FILE__, __FUNC__, __LINE__, dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt)); +} + +//----------------------------------------------------------------------------- + +static SAVEDS(ULONG) INTERRUPT AmigaIconObjectDispatcher(Class *cl, Object *o, Msg msg) +{ + ULONG Result; + + switch (msg->MethodID) + { + case OM_NEW: + o = (Object *) DoSuperMethodA(cl, o, msg); + d1(kprintf("%s/%ld: OM_NEW o=%08lx\n", __FUNC__, __LINE__, o)); + if (o) + { + d1(kprintf("%s/%ld: OM_NEW o=%08lx\n", __FUNC__, __LINE__, o)); + if (!DtNew(cl, o, (struct opSet *) msg)) + { + DoMethod(o, OM_DISPOSE); + o = NULL; + } + } + Result = (ULONG) o; + break; + + case OM_DISPOSE: + Result = DtDispose(cl, o, msg); + break; + + case OM_SET: + Result = DtSet(cl, o, (struct opSet *) msg); + break; + + case OM_GET: + Result = DtGet(cl, o, (struct opGet *) msg); + break; + + case IDTM_Layout: + Result = DtLayout(cl, o, (struct iopLayout *) msg); + break; + + case IDTM_Write: + Result = DtWrite(cl, o, (struct iopWrite *) msg); + break; + + case IDTM_NewImage: + Result = DtNewImage(cl, o, (struct iopNewImage *) msg); + break; + + case IDTM_CloneIconObject: + Result = DtClone(cl, o, (struct iopCloneIconObject *) msg); + break; + + default: + Result = DoSuperMethodA(cl, o, msg); + break; + } + + return Result; +} + +//----------------------------------------------------------------------------- + +static BOOL DtNew(Class *cl, Object *o, struct opSet *ops) +{ + struct InstanceData *inst = INST_DATA(cl, o); + struct ExtGadget *gg = (struct ExtGadget *) o; + BOOL Success = FALSE; + + do { + memset(inst, 0, sizeof(struct InstanceData)); + + inst->aio_ImageLeft = GetTagData(IDTA_InnerLeft, 0, ops->ops_AttrList); + inst->aio_ImageTop = GetTagData(IDTA_InnerTop, 0, ops->ops_AttrList); + + if (FindTagItem(IDTA_CloneIconObject, ops->ops_AttrList)) + { + } + else + { + ULONG DefIconType; + struct Image *img; + + DefIconType = GetTagData(IDTA_DefType, 0, ops->ops_AttrList); + d1(kprintf("%s/%ld: o=%08lx DefIconType=%lu\n", __FUNC__, __LINE__, o, DefIconType)); + + if (0 != DefIconType) + { + // Get default icon + inst->aio_DiskObject = GetDefDiskObject(DefIconType); + d1(kprintf("%s/%ld: o=%08lx aio_DiskObject=%08lx\n", __FUNC__, __LINE__, o, inst->aio_DiskObject)); + } + else + { + STRPTR IconName; + + inst->aio_DiskObject = (struct DiskObject *) GetTagData(AIDTA_Icon, (ULONG) NULL, ops->ops_AttrList); + d1(kprintf("%s/%ld: o=%08lx aio_DiskObject=%08lx\n", __FUNC__, __LINE__, o, inst->aio_DiskObject)); + if (inst->aio_DiskObject) + { + inst->aio_DoNotFreeDiskObject = TRUE; + } + else + { + GetAttr(DTA_Name, o, (APTR) &IconName); + d1(kprintf("%s/%ld: o=%08lx IconName=<%s>\n", __FUNC__, __LINE__, o, IconName ? IconName : (STRPTR) "")); + + // Get named icon + if (NULL == IconName) + break; + + inst->aio_DiskObject = GetDiskObject(IconName); + d1(kprintf("%s/%ld: o=%08lx aio_DiskObject=%08lx\n", __FUNC__, __LINE__, o, inst->aio_DiskObject)); + } + } + + d1(KPrintF("%s/%ld: o=%08lx aio_DiskObject=%08lx\n", __FUNC__, __LINE__, o, inst->aio_DiskObject)); + if (NULL == inst->aio_DiskObject) + break; + + img = (struct Image *) inst->aio_DiskObject->do_Gadget.GadgetRender; + + if (NULL == img) + break; + + SetAttrs(o, + GA_Width, img->Width, + GA_Height, img->Height, + TAG_END); + d1(kprintf("%s/%ld: o=%08lx Width=%ld Height=%ld\n", __FUNC__, __LINE__, o, gg->Width, gg->Height)); + + if (NO_ICON_POSITION == inst->aio_DiskObject->do_CurrentX) + { + gg->LeftEdge = gg->TopEdge = NO_ICON_POSITION_WORD; + } + else + { + gg->LeftEdge = inst->aio_DiskObject->do_CurrentX; + gg->TopEdge = inst->aio_DiskObject->do_CurrentY; + } + + d1(kprintf("%s/%ld: o=%08lx Left=%ld Top=%ld\n", __FUNC__, __LINE__, o, gg->LeftEdge, gg->TopEdge)); + + if (WBDISK == inst->aio_DiskObject->do_Type + || WBDRAWER == inst->aio_DiskObject->do_Type) + { + if (NULL == inst->aio_DiskObject->do_DrawerData) + { + inst->aio_myDrawerData = MyAllocVecPooled(sizeof(struct DrawerData)); + if (NULL == inst->aio_myDrawerData) + break; + + memset(inst->aio_myDrawerData, 0, sizeof(struct DrawerData)); + + inst->aio_DiskObject->do_DrawerData = inst->aio_myDrawerData; + } + + SetAttrs(o, + IDTA_ViewModes, inst->aio_DiskObject->do_DrawerData->dd_ViewModes, + IDTA_Flags, inst->aio_DiskObject->do_DrawerData->dd_Flags, + IDTA_WinCurrentX, inst->aio_DiskObject->do_DrawerData->dd_CurrentX, + IDTA_WinCurrentY, inst->aio_DiskObject->do_DrawerData->dd_CurrentY, + IDTA_WindowRect, (ULONG) &inst->aio_DiskObject->do_DrawerData->dd_NewWindow, + TAG_END); + } + + SetAttrs(o, + IDTA_ToolTypes, (ULONG) inst->aio_DiskObject->do_ToolTypes, + IDTA_Stacksize, inst->aio_DiskObject->do_StackSize, + IDTA_DefaultTool, (ULONG) inst->aio_DiskObject->do_DefaultTool, + IDTA_Type, inst->aio_DiskObject->do_Type, + TAG_END); + } + + d1(kprintf("%s/%ld: o=%08lx GadgetRender=%08lx\n", __FUNC__, __LINE__, o, gg->GadgetRender)); + + Success = TRUE; + } while (0); + + d1(KPrintF("%s/%ld: o=%08lx aio_DiskObject=%08lx\n", __FUNC__, __LINE__, o, inst->aio_DiskObject)); + d1(KPrintF("%s/%ld: o=%08lx Success=%ld\n", __FUNC__, __LINE__, o, Success)); + + return Success; +} + +//----------------------------------------------------------------------------- + +static ULONG DtDispose(Class *cl, Object *o, Msg msg) +{ + struct InstanceData *inst = INST_DATA(cl, o); +// struct ExtGadget *gg = (struct ExtGadget *) o; + + d1(KPrintF("%s/%ld: o=%08lx inst=%08lx\n", __FUNC__, __LINE__, o, inst)); + d1(KPrintF("%s/%ld: o=%08lx aio_myDrawerData=%08lx\n", __FUNC__, __LINE__, o, inst->aio_myDrawerData)); + + if (inst->aio_myDrawerData) + { + MyFreeVecPooled(inst->aio_myDrawerData); + inst->aio_myDrawerData = NULL; + if (inst->aio_DiskObject) + inst->aio_DiskObject->do_DrawerData = NULL; + } + + d1(KPrintF("%s/%ld: o=%08lx aio_DiskObject=%08lx\n", __FUNC__, __LINE__, o, inst->aio_DiskObject)); + if (inst->aio_DiskObject) + { + if (!inst->aio_DoNotFreeDiskObject) + FreeDiskObject(inst->aio_DiskObject); + inst->aio_DiskObject = NULL; + } + + d1(KPrintF("%s/%ld: o=%08lx inst=%08lx\n", __FUNC__, __LINE__, o, inst)); + + return DoSuperMethodA(cl, o, msg); +} + +//---------------------------------------------------------------------------------------- + +static ULONG DtSet(Class *cl, Object *o, struct opSet *ops) +{ + struct InstanceData *inst = INST_DATA(cl, o); + + d1(kprintf("%s/%ld: o=%08lx inst=%08lx\n", __FUNC__, __LINE__, o, inst)); + + if (inst->aio_DoNotFreeDiskObject) + { + if (0 == GetTagData(IDTA_DoFreeDiskObject, 0, ops->ops_AttrList)) + inst->aio_DoNotFreeDiskObject = TRUE; + } + + inst->aio_ImageLeft = GetTagData(IDTA_InnerLeft, inst->aio_ImageLeft, ops->ops_AttrList); + inst->aio_ImageTop = GetTagData(IDTA_InnerTop, inst->aio_ImageTop, ops->ops_AttrList); + + return DoSuperMethodA(cl, o, (Msg) ops); +} + +//---------------------------------------------------------------------------------------- + +static ULONG DtGet(Class *cl, Object *o, struct opGet *opg) +{ + struct InstanceData *inst = INST_DATA(cl, o); + ULONG result = 1; + + d1(KPrintF("%s/%ld: o=%08lx inst=%08lx AttrID=%08lx\n", __FUNC__, __LINE__, o, inst, opg->opg_AttrID)); + + switch (opg->opg_AttrID) + { + case IDTA_IconType: + *opg->opg_Storage = ioICONTYPE_Standard; + break; + + case IDTA_NumberOfColorsSupported: + *opg->opg_Storage = 32; + break; + + case AIDTA_Icon: + *opg->opg_Storage = (ULONG) inst->aio_DiskObject; + break; + + case IDTA_Extention: + *opg->opg_Storage = (ULONG) ".info"; + break; + + default: + result = DoSuperMethodA(cl, o, (Msg) opg); + break; + } + + d1(kprintf("%s/%ld: o=%08lx GadgetRender=%08lx\n", __FUNC__, __LINE__, o, ((struct ExtGadget *) o)->GadgetRender)); + + return result; +} + +//--------------------------------------------- -------------------------------- + +static ULONG DtLayout(Class *cl, Object *o, struct iopLayout *iopl) +{ + struct InstanceData *inst = INST_DATA(cl, o); + struct ExtGadget *gg = (struct ExtGadget *) o; + struct Image *NormImg = (struct Image *) inst->aio_DiskObject->do_Gadget.GadgetRender; + struct Image *SelImg = (struct Image *) inst->aio_DiskObject->do_Gadget.SelectRender; + + d1(kprintf("%s/%ld: o=%08lx inst=%08lx\n", __FUNC__, __LINE__, o, inst)); + + DoSuperMethodA(cl, o, (Msg) iopl); + + d1(kprintf("%s/%ld: o=%08lx Screen=%08lx\n", __FUNC__, __LINE__, o, iopl->iopl_Screen)); + d1(kprintf("%s/%ld: o=%08lx Width=%ld Height=%ld\n", __FUNC__, __LINE__, o, gg->Width, gg->Height)); + d1(kprintf("%s/%ld: o=%08lx GadgetRender=%08lx SelectRender=%08lx Flags=%08lx\n", \ + __FUNC__, __LINE__, o, gg->GadgetRender, gg->SelectRender, iopl->iopl_Flags)); + + inst->aio_Screen = iopl->iopl_Screen; + + if (gg->GadgetRender && (iopl->iopl_Flags & IOLAYOUTF_NormalImage)) + { + struct RastPort *rp = (struct RastPort *) gg->GadgetRender; + + DrawImage(rp, NormImg, inst->aio_ImageLeft, inst->aio_ImageTop); + } + if (gg->SelectRender && (iopl->iopl_Flags & IOLAYOUTF_SelectedImage)) + { + struct RastPort *rp = (struct RastPort *) gg->SelectRender; + UWORD HighLight = inst->aio_DiskObject->do_Gadget.Flags & GFLG_GADGHIGHBITS; + + d1(kprintf("%s/%ld: o=%08lx Flags=%08lx\n", __FUNC__, __LINE__, o, inst->aio_DiskObject->do_Gadget.Flags)); + + if (GFLG_GADGHIMAGE == HighLight) + { + d1(kprintf("%s/%ld: o=%08lx GFLG_GADGHIMAGE\n", __FUNC__, __LINE__, o)); + DrawImage(rp, SelImg, inst->aio_ImageLeft, inst->aio_ImageTop); + } + else if (GFLG_GADGHNONE == HighLight) + { + d1(kprintf("%s/%ld: o=%08lx GFLG_GADGHNONE\n", __FUNC__, __LINE__, o)); + DrawImage(rp, NormImg, inst->aio_ImageLeft, inst->aio_ImageTop); + } + else if (GFLG_GADGHCOMP == HighLight) + { + d1(kprintf("%s/%ld: o=%08lx ?\n", __FUNC__, __LINE__, o)); + + DrawImage(rp, NormImg, inst->aio_ImageLeft, inst->aio_ImageTop); + + SetDrMd(rp, JAM1 | COMPLEMENT); + + BltPattern(rp, NULL, + inst->aio_ImageLeft, inst->aio_ImageTop, + inst->aio_ImageLeft + gg->Width - 1, + inst->aio_ImageTop + gg->Height - 1, + 0); + WaitBlit(); + } + else // GFLG_GADGBACKFILL + { + // GADGBACKFILL is similar to GADGHCOMP, but ensures that there is no + // "ring" around the selected image. It does this by first + // complementing the image, and then flooding all color 3 pixels that + // are on the border of the image to color 0. All other flag bits + ULONG OldWriteMask; + PLANEPTR BlitMask; + + DrawImage(rp, NormImg, inst->aio_ImageLeft, inst->aio_ImageTop); + + SetDrMd(rp, JAM1 | COMPLEMENT); + GetRPAttrs(rp, + RPTAG_WriteMask, (ULONG) &OldWriteMask, + TAG_END); + if (SelImg) + SetWriteMask(rp, SelImg->PlanePick); + + d1(kprintf("%s/%ld: o=%08lx GFLG_GADGHBOX\n", __FUNC__, __LINE__, o)); + + do { + struct RastPort TempRp; + struct TmpRas TempRas; + UWORD *MaskPtr; + UWORD *ImgSrcPtr; + WORD ByteCount; + ULONG ImgSize; + ULONG d, y; + + ByteCount = (((NormImg->Width + 15) & 0xfff0) >> 3) + 4; + ImgSize = (2 + NormImg->Height) * ByteCount * sizeof(UWORD); + + BlitMask = MyAllocVecPooled(ImgSize); + d1(kprintf("%s/%ld: BlitMask=%08lx\n", __FUNC__, __LINE__, BlitMask)); + if (NULL == BlitMask) + break; + + InitRastPort(&TempRp); + TempRp.TmpRas = &TempRas; + + InitTmpRas(&TempRas, BlitMask, ImgSize); + + TempRp.BitMap = AllocBitMap((NormImg->Width + 0x2f) & 0xfff0, + NormImg->Height + 2, 2, + BMF_STANDARD | BMF_CLEAR, NULL); + d1(kprintf("%s/%ld: TempRp.BitMap=%08lx\n", __FUNC__, __LINE__, TempRp.BitMap)); + if (NULL == TempRp.BitMap) + break; + + ImgSrcPtr = NormImg->ImageData; + for (d = 0; d < NormImg->Depth; d++) + { + if (NormImg->PlanePick & (1 << d)) + { + MaskPtr = (UWORD *) (TempRp.BitMap->Planes[0] + (2 + ByteCount)); + + for (y = 0; y < NormImg->Height; y++) + { + ULONG x; + + for (x = 0; x < (ByteCount >> 1) - 2; x++) + { + *MaskPtr++ |= *ImgSrcPtr++; + } + + MaskPtr += 2; + } + } + } + + SetAPen(&TempRp, 2); + Flood(&TempRp, 1, 0, 0); + WaitBlit(); + + ImgSrcPtr = (UWORD *) (TempRp.BitMap->Planes[1] + (2 + ByteCount)); + MaskPtr = (UWORD *) BlitMask; + for (y = 0; y < NormImg->Height; y++) + { + ULONG x; + + for (x = 0; x < (ByteCount >> 1) - 2; x++) + { + *MaskPtr++ = ~(*ImgSrcPtr++); + } + + ImgSrcPtr += 2; + } + + FreeBitMap(TempRp.BitMap); + + BltPattern(rp, BlitMask, + inst->aio_ImageLeft, inst->aio_ImageTop, + inst->aio_ImageLeft + NormImg->Width - 1, + inst->aio_ImageTop + NormImg->Height - 1, + ByteCount - 4); + WaitBlit(); + } while (0); + + if (BlitMask) + MyFreeVecPooled(BlitMask); + + // Restore original WriteMask + SetWriteMask(rp, OldWriteMask); + } + } + + return 0; +} + +//----------------------------------------------------------------------------- + +static ULONG DtWrite(Class *cl, Object *o, struct iopWrite *iopw) +{ + struct InstanceData *inst = INST_DATA(cl, o); + struct ExtGadget *gg = (struct ExtGadget *) o; + struct WriteData wd; + struct DrawerData *OrigDrawerData; + ULONG NeedUpdateWB; + LONG Result = RETURN_OK; + + d1(kprintf("%s/%ld: o=%08lx inst=%08lx\n", __FUNC__, __LINE__, o, inst)); + + memset(&wd, 0, sizeof(wd)); + + NeedUpdateWB = GetTagData(ICONA_NotifyWorkbench, FALSE, iopw->iopw_Tags); + + GetAttr(IDTA_Type, o, &wd.aiowd_Type); + GetAttr(IDTA_ViewModes, o, &wd.aiowd_ViewModes); + GetAttr(IDTA_Flags, o, &wd.aiowd_Flags); + GetAttr(IDTA_WinCurrentX, o, &wd.aiowd_CurrentX); + GetAttr(IDTA_WinCurrentY, o, &wd.aiowd_CurrentY); + GetAttr(IDTA_WindowRect, o, (ULONG *) &wd.aiowd_WindowRect); + GetAttr(IDTA_Stacksize, o, &wd.aiowd_StackSize); + GetAttr(IDTA_ToolTypes, o, (ULONG *) &wd.aiowd_ToolTypes); + GetAttr(IDTA_DefaultTool, o, (ULONG *) &wd.aiowd_DefaultTool); + + ExchangeAttrs(inst->aio_DiskObject, &wd); + + OrigDrawerData = inst->aio_DiskObject->do_DrawerData; + inst->aio_DiskObject->do_DrawerData = NULL; + + switch (inst->aio_DiskObject->do_Type) + { + case WBTOOL: + case WBPROJECT: + case WBKICK: + break; + default: + if (OrigDrawerData) + inst->aio_DiskObject->do_DrawerData = OrigDrawerData; + else + inst->aio_DiskObject->do_DrawerData = inst->aio_myDrawerData; + + inst->aio_DiskObject->do_DrawerData->dd_CurrentX = wd.aiowd_CurrentX; + inst->aio_DiskObject->do_DrawerData->dd_CurrentY = wd.aiowd_CurrentY; + + if (wd.aiowd_WindowRect) + { + inst->aio_DiskObject->do_DrawerData->dd_NewWindow.LeftEdge = wd.aiowd_WindowRect->Left; + inst->aio_DiskObject->do_DrawerData->dd_NewWindow.TopEdge = wd.aiowd_WindowRect->Top; + inst->aio_DiskObject->do_DrawerData->dd_NewWindow.Width = wd.aiowd_WindowRect->Width; + inst->aio_DiskObject->do_DrawerData->dd_NewWindow.Height = wd.aiowd_WindowRect->Height; + inst->aio_DiskObject->do_DrawerData->dd_Flags = wd.aiowd_Flags; + inst->aio_DiskObject->do_DrawerData->dd_ViewModes = wd.aiowd_ViewModes; + } + break; + } + + if (GetTagData(ICONA_NoNewImage, 0, iopw->iopw_Tags)) + { + } + if (GetTagData(ICONA_NoPosition, 0, iopw->iopw_Tags)) + { + inst->aio_DiskObject->do_CurrentX = inst->aio_DiskObject->do_CurrentY = NO_ICON_POSITION; + } + else + { + if (NO_ICON_POSITION_WORD == gg->LeftEdge) + { + inst->aio_DiskObject->do_CurrentX = inst->aio_DiskObject->do_CurrentY = NO_ICON_POSITION; + } + else + { + inst->aio_DiskObject->do_CurrentX = gg->LeftEdge; + inst->aio_DiskObject->do_CurrentY = gg->TopEdge; + } + } + + if (!PutDiskObject(iopw->iopw_Path, inst->aio_DiskObject)) + Result = IoErr(); + + // Restore diskobject + inst->aio_DiskObject->do_DrawerData = OrigDrawerData; + ExchangeAttrs(inst->aio_DiskObject, &wd); + + if ((RETURN_OK == Result) && NeedUpdateWB) + DoUpdateWb(inst, iopw->iopw_Path); + + return (ULONG) Result; +} + +//----------------------------------------------------------------------------- + +static ULONG DtNewImage(Class *cl, Object *o, struct iopNewImage *ioni) +{ +// struct InstanceData *inst = INST_DATA(cl, o); + + d1(KPrintF("%s/%ld: START o=%08lx\n", __FUNC__, __LINE__, o)); + + d1(KPrintF("%s/%ld: END o=%08lxlx\n", __FUNC__, __LINE__, o)); + + return 0; +} + +//----------------------------------------------------------------------------- + +static ULONG DtClone(Class *cl, Object *o, struct iopCloneIconObject *iocio) +{ + struct InstanceData *inst = INST_DATA(cl, o); + + d1(KPrintF("%s/%ld: START o=%08lx inst=%08lx\n", __FUNC__, __LINE__, o, inst)); + + d1(KPrintF("%s/%ld: END o=%08lx inst=%08lx\n", __FUNC__, __LINE__, o, inst)); + + return 0; +} + +//----------------------------------------------------------------------------- + +static void ExchangeAttrs(struct DiskObject *DiskObj, struct WriteData *wd) +{ + UBYTE TempUB; + ULONG TempUL; + void *TempPtr; + + TempPtr = wd->aiowd_DefaultTool; + wd->aiowd_DefaultTool = DiskObj->do_DefaultTool; + DiskObj->do_DefaultTool = TempPtr; + + TempPtr = wd->aiowd_ToolTypes; + wd->aiowd_ToolTypes = DiskObj->do_ToolTypes; + DiskObj->do_ToolTypes = TempPtr; + + TempUL = wd->aiowd_StackSize; + wd->aiowd_StackSize = DiskObj->do_StackSize; + DiskObj->do_StackSize = TempUL; + + TempUB = (UBYTE) wd->aiowd_Type; + wd->aiowd_Type = DiskObj->do_Type; + DiskObj->do_Type = TempUB; +} + +//---------------------------------------------------------------------------------------- + +static APTR MyAllocVecPooled(size_t Size) +{ + APTR ptr; + + if (MemPool) + { + ObtainSemaphore(&PubMemPoolSemaphore); + ptr = AllocPooled(MemPool, Size + sizeof(size_t)); + ReleaseSemaphore(&PubMemPoolSemaphore); + if (ptr) + { + size_t *sptr = (size_t *) ptr; + + sptr[0] = Size; + + d1(kprintf("%s/%ld: MemPool=%08lx Size=%lu mem=%08lx\n", __FUNC__, __LINE__, MemPool, Size, &sptr[1])); + return (APTR)(&sptr[1]); + } + } + + d1(kprintf("%s/%ld: MemPool=%08lx Size=%lu\n", __FUNC__, __LINE__, MemPool, Size)); + + return NULL; +} + + +static void MyFreeVecPooled(APTR mem) +{ + d1(kprintf("%s/%ld: MemPool=%08lx mem=%08lx\n", __FUNC__, __LINE__, MemPool, mem)); + if (MemPool && mem) + { + size_t size; + size_t *sptr = (size_t *) mem; + + mem = &sptr[-1]; + size = sptr[-1]; + + ObtainSemaphore(&PubMemPoolSemaphore); + FreePooled(MemPool, mem, size + sizeof(size_t)); + ReleaseSemaphore(&PubMemPoolSemaphore); + } +} + +//---------------------------------------------------------------------------------------- + +static void DoUpdateWb(struct InstanceData *inst, CONST_STRPTR SavePath) +{ + BPTR fLock; + BPTR pLock = (BPTR)NULL; + + do { + CONST_STRPTR fName; + + fLock = Lock(SavePath, ACCESS_READ); + if ((BPTR)NULL == fLock) + break; + + pLock = ParentDir(fLock); + if ((BPTR)NULL == pLock) + break; + + fName = FilePart(SavePath); + + UpdateWorkbench(fName, pLock, UPDATEWB_ObjectAdded); + } while (0); + + if (pLock) + UnLock(pLock); + if (fLock) + UnLock(fLock); +} + +//----------------------------------------------------------------------------- diff --git a/scalos/datatypes/AmigaIconObject/AmigaIconObject.h b/scalos/datatypes/AmigaIconObject/AmigaIconObject.h new file mode 100644 index 000000000..20687c46d --- /dev/null +++ b/scalos/datatypes/AmigaIconObject/AmigaIconObject.h @@ -0,0 +1,140 @@ +// AmigaIconObject.h +// $Date$ +// $Revision$ + + +#ifndef AMIGAICONOBJECT_H_INCLUDED +#define AMIGAICONOBJECT_H_INCLUDED + +#include +#include +#include +#include +#include + +#include + +//----------------------------------------------------------------------------- + +#define MEMPOOL_MEMFLAGS MEMF_PUBLIC +#define MEMPOOL_PUDDLESIZE 16384 +#define MEMPOOL_THRESHSIZE 16384 + +//----------------------------------------------------------------------------- + +#define LIB_VERSION 40 +#define LIB_REVISION 10 + +extern char ALIGNED libName[]; +extern char ALIGNED libIdString[]; + +//----------------------------------------------------------------------------- + +struct AmigaIconObjectDtLibBase + { + struct ClassLibrary nib_ClassLibrary; + + struct SegList *nib_SegList; + + UBYTE nib_Initialized; + }; + +//---------------------------------------------------------------------------- + +ULONG InitDatatype(struct AmigaIconObjectDtLibBase *dtLib); +ULONG OpenDatatype(struct AmigaIconObjectDtLibBase *dtLib); +void CloseDatatype(struct AmigaIconObjectDtLibBase *dtLib); + +LIBFUNC_PROTO(ObtainInfoEngine, libbase, ULONG); + +//----------------------------------------------------------------------------- + +struct InstanceData + { + struct DiskObject *aio_DiskObject; + struct DrawerData *aio_myDrawerData; + struct Screen *aio_Screen; + + UWORD aio_ImageLeft; + UWORD aio_ImageTop; + + UBYTE aio_DoNotFreeDiskObject; //Flag: free icon on quit ? + }; + +//--------------------------------------------------------------- + +// private and temporary Data during dtWrite + +struct WriteData + { + STRPTR aiowd_DefaultTool; + STRPTR *aiowd_ToolTypes; + ULONG aiowd_StackSize; + struct IBox *aiowd_WindowRect; + ULONG aiowd_CurrentX; + ULONG aiowd_CurrentY; + ULONG aiowd_Flags; + ULONG aiowd_ViewModes; + ULONG aiowd_Type; + }; + +/* ------------------------------------------------- */ + +#if !defined(__amigaos4__) && !defined(__AROS__) +VOID UpdateWorkbench(CONST_STRPTR name, BPTR parentlock, LONG action); + +#if defined(__MORPHOS__) + +#ifndef __PPCINLINE_MACROS_H +#include +#endif /* !__PPCINLINE_MACROS_H */ + +#define UpdateWorkbench(__p0, __p1, __p2) \ + LP3NR(30, UpdateWorkbench, \ + CONST_STRPTR , __p0, a0, \ + BPTR, __p1, a1, \ + LONG, __p2, d0, \ + , WB_BASE_NAME, 0, 0, 0, 0, 0, 0) + +#else + +#ifdef __SASC + +#ifdef __CLIB_PRAGMA_LIBCALL +#pragma libcall WorkbenchBase UpdateWorkbench 01e 09803 +#endif /* __CLIB_PRAGMA_LIBCALL */ + +#else + +#define WBInfo(lock, name, screen) \ + LP3NR(30, UpdateWorkbench, CONST_STRPTR, name, a0, BPTR, parentlock, a1, LONG, action, d0, \ + , WB_BASE_NAME) + +#endif /* __SASC */ + +#endif /* __MORPHOS__ */ + +#endif /* !__amigaos4__ */ + +/* ------------------------------------------------- */ + +#define Sizeof(x) (sizeof(x) / sizeof(x[0])) + +/* ------------------------------------------------- */ + +// from debug.lib +#ifdef __AROS__ +#include +#define KPrintF kprintf +#else +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); +#endif + + +#define d1(x) ; +#define d2(x) { Forbid(); x; Permit(); } + +/* ------------------------------------------------- */ + +#endif // AMIGAICONOBJECT_H_INCLUDED diff --git a/scalos/datatypes/AmigaIconObject/amigaiconobject.dt b/scalos/datatypes/AmigaIconObject/amigaiconobject.dt new file mode 100644 index 000000000..1e6fe65ea --- /dev/null +++ b/scalos/datatypes/AmigaIconObject/amigaiconobject.dt @@ -0,0 +1,6 @@ +# DataType file for Amiga Icons +Filename=amigaiconobject +DTName=Amiga IconObject,amigaiconobject +ID=icon,aico +Recog=#?.info +Flags=Binary,n,0 diff --git a/scalos/datatypes/AmigaIconObject/config.mk b/scalos/datatypes/AmigaIconObject/config.mk new file mode 100755 index 000000000..df1224f56 --- /dev/null +++ b/scalos/datatypes/AmigaIconObject/config.mk @@ -0,0 +1,51 @@ +# $Date: 2012-08-10 13:47:28 +0200 (Fr, 10. Aug 2012) $ +# $Revision: 915 $ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +MKDIR = mkdir -p #makedir force +DT_DIR = scalos:IconDatatypes/datatypes + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += -nostartfiles \ + -lmempools \ +# --verbose + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += -nostartfiles + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +LFLAGS += -nostartfiles -larossupport + +else + +############################################################################### +# AmigaOS + +LFLAGS += -ldebug -lmcpgfx -lnix -lamiga -lstubs + +endif +endif +endif diff --git a/scalos/datatypes/AmigaIconObject/makefile b/scalos/datatypes/AmigaIconObject/makefile new file mode 100644 index 000000000..ae4f2379b --- /dev/null +++ b/scalos/datatypes/AmigaIconObject/makefile @@ -0,0 +1,100 @@ +# makefile für Scalos IconObject datatypes stuff +# $Date$ +# $Revision$ +##################################################################### + +ASRCS = +CSRCS = \ + AmigaIconObject-classic.c \ + AmigaIconObject.c \ + + +##################################################################### + +AS = phxAss +LD = slink +CC = sc +MKDIR = mkdir -p #makedir force +LIBS = LIB:debug.lib LIB:sc.lib LIB:amiga.lib +PRECOMP = Include:all.gst +DT_DIR = scalos:IconDatatypes/datatypes +OBJDIR = .sasobj + +.SUFFIXES: .asm + +##################################################################### + +CFLAGS = optimize nostackcheck nover math=standard data=far \ + dbg=f idir=//include +LNFLAGS = batch noicons stripdebug quiet +LNDBFLAGS = batch noicons addsym quiet + +ifdef L +AFLAGS = QUIET DS NOEXE opt=NRQB LIST=* linedebug I=SC:Assembler_Headers +else +AFLAGS = QUIET DS NOEXE opt=NRQB linedebug I=SC:Assembler_Headers +endif + +##################################################################### + +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(CSRCS:%.c=$(OBJDIR)/%.o) + +##################################################################### + +DTNAME = .bin_os3/amigaiconobject.datatype +DTDBGNAME = $(DTNAME).debug + +##################################################################### + +all: $(DTNAME) \ + $(DTDBGNAME) + +##################################################################### + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +##################################################################### + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $* objectname $@ + +$(OBJDIR)/%.o : %.s + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +$(OBJDIR)/%.o : %.asm + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +##################################################################### + +$(DTNAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) from $(OBJS) to $(DTNAME) LIB $(LIBS) $(LNFLAGS) + +$(DTDBGNAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) from $(OBJS) to $(DTDBGNAME) LIB $(LIBS) $(LNDBFLAGS) + +##################################################################### + +$(OBJDIR)/AmigaIconObject.o $(OBJDIR)/AmigaIconObject-classic.o : AmigaIconObject.h + +##################################################################### + +install: + @printf '\033[32mFlushing memory...\033[0m\n' + avail flush + @printf '\033[32mInstall: \033[31m\033[1m$(DTNAME)\033[0m\n' + -@$(MKDIR) $(DT_DIR) + copy $(DTNAME) $(DT_DIR) + +##################################################################### + +clean: + -@delete $(DTNAME) $(DTDBGNAME) $(OBJS) + +##################################################################### + diff --git a/scalos/datatypes/AmigaIconObject/makefile-new b/scalos/datatypes/AmigaIconObject/makefile-new new file mode 100755 index 000000000..847be23d1 --- /dev/null +++ b/scalos/datatypes/AmigaIconObject/makefile-new @@ -0,0 +1,73 @@ +# $Date: 2011-07-09 20:50:13 +0200 (Sa, 09. Jul 2011) $ +# $Revision: 759 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +ifeq ($(MACHINE), ppc-amigaos) +OBJS = $(OBJDIR)/AmigaIconObject.o $(OBJDIR)/AmigaIconObject-aos4.o +else +ifeq ($(MACHINE), i386-aros) +OBJS = $(OBJDIR)/AmigaIconObject.o $(OBJDIR)/AmigaIconObject-aros.o +else +OBJS = $(OBJDIR)/AmigaIconObject.o $(OBJDIR)/AmigaIconObject-classic.o +endif +endif + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Targets +# + +NAME = amigaiconobject.datatype +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + $(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + -@$(MKDIR) $(DT_DIR) + @copy $(BINDIR)/$(NAME) $(DT_DIR) + @avail flush + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* + +############################################################################## diff --git a/scalos/datatypes/GlowIconObject/GlowIconObject-aos4.c b/scalos/datatypes/GlowIconObject/GlowIconObject-aos4.c new file mode 100644 index 000000000..3ee2abb91 --- /dev/null +++ b/scalos/datatypes/GlowIconObject/GlowIconObject-aos4.c @@ -0,0 +1,191 @@ +// GlowIconObject-aos4.c +// $Date$ +// $Revision$ + + +#include +#include +#include + +#include +#include + +#include + +#include "GlowIconObject.h" + +int _start(void) +{ + return -1; +} + +static struct Library *Initlib(struct Library *libbase, BPTR seglist, struct ExecIFace *pIExec); +static BPTR Expungelib(struct LibraryManagerInterface *Self); +static struct LibraryHeader *Openlib(struct LibraryManagerInterface *Self, ULONG version); +static BPTR Closelib(struct LibraryManagerInterface *Self); +static ULONG Obtainlib(struct LibraryManagerInterface *Self); +static ULONG Releaselib(struct LibraryManagerInterface *Self); + +extern struct ExecBase *SysBase; + +/* OS4.0 Library */ + +/* ------------------- OS4 Manager Interface ------------------------ */ +static const APTR managerfunctable[] = + { + (APTR)Obtainlib, + (APTR)Releaselib, + (APTR)NULL, + (APTR)NULL, + (APTR)Openlib, + (APTR)Closelib, + (APTR)Expungelib, + (APTR)NULL, + (APTR)-1 + }; + +static const struct TagItem managertags[] = + { + {MIT_Name, (ULONG)"__library"}, + {MIT_VectorTable, (ULONG)managerfunctable}, + {MIT_Version, 1}, + {TAG_DONE, 0} + }; + +/* ---------------------- OS4 Main Interface ------------------------ */ +static APTR functable[] = + { + Obtainlib, + Releaselib, + NULL, + NULL, + ObtainInfoEngine, + (APTR) -1 + }; + +static const struct TagItem maintags[] = + { + {MIT_Name, (ULONG)"main"}, + {MIT_VectorTable, (ULONG)functable}, + {MIT_Version, 1}, + {TAG_DONE, 0} + }; + +/* Init table used in library initialization. */ +static const ULONG interfaces[] = + { + (ULONG)managertags, + (ULONG)maintags, + (ULONG)0 + }; + +static const struct TagItem inittab[] = + { + {CLT_DataSize, (ULONG)sizeof(struct GlowIconObjectDtLibBase)}, + {CLT_Interfaces, (ULONG) interfaces}, +// {CLT_Vector68K, (ULONG)VecTable68K}, + {CLT_InitFunc, (ULONG) Initlib}, + {TAG_DONE, 0} + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, + RTF_NATIVE | RTF_AUTOINIT, + LIB_VERSION, + NT_LIBRARY, + 0, + libName, + libIdString, + (struct TagItem *)inittab + }; + +/* ------------------- OS4 Manager Functions ------------------------ */ +static struct Library * Initlib(struct Library *libbase, BPTR seglist, struct ExecIFace *pIExec) +{ + struct GlowIconObjectDtLibBase *IconObjLibBase = (struct GlowIconObjectDtLibBase *) libbase; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)libbase + libbase->lib_PosSize); + struct LibraryManagerInterface *Self = (struct LibraryManagerInterface *) ExtLib->ILibrary; + + SysBase = (struct ExecBase *)pIExec->Data.LibBase; + IExec = pIExec; + IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_Revision = LIB_REVISION; + IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_Node.ln_Pri = 10; + IconObjLibBase->nib_SegList = (struct SegList *)seglist; + + if (!InitDatatype(IconObjLibBase)) + { + Expungelib(Self); + IconObjLibBase = NULL; + } + + return (struct Library *)IconObjLibBase; +} + +static BPTR Expungelib(struct LibraryManagerInterface *Self) +{ + struct GlowIconObjectDtLibBase *IconObjLibBase = (struct GlowIconObjectDtLibBase *) Self->Data.LibBase; + + if (0 == IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + struct SegList *libseglist = IconObjLibBase->nib_SegList; + + Remove((struct Node *) IconObjLibBase); + CloseDatatype(IconObjLibBase); + DeleteLibrary((struct Library *)IconObjLibBase); + + return (BPTR)libseglist; + } + + IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_Flags |= LIBF_DELEXP; + + return (BPTR)NULL; +} + +static struct LibraryHeader *Openlib(struct LibraryManagerInterface *Self, ULONG version) +{ + struct GlowIconObjectDtLibBase *IconObjLibBase = (struct GlowIconObjectDtLibBase *) Self->Data.LibBase; + + IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_OpenCnt++; + IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_Flags &= ~LIBF_DELEXP; + + if (!OpenDatatype(IconObjLibBase)) + { + Closelib(Self); + return NULL; + } + + return (struct LibraryHeader *)IconObjLibBase; +} + +static BPTR Closelib(struct LibraryManagerInterface *Self) +{ + struct GlowIconObjectDtLibBase *IconObjLibBase = (struct GlowIconObjectDtLibBase *) Self->Data.LibBase; + + IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_OpenCnt--; +/* + if (0 == IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + if (IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_Flags & LIBF_DELEXP) + { + return Expungelib(Self); + } + } +*/ + return (BPTR)NULL; +} + +static ULONG Obtainlib(struct LibraryManagerInterface *Self) +{ + return(Self->Data.RefCount++); +} + +static ULONG Releaselib(struct LibraryManagerInterface *Self) +{ + return(Self->Data.RefCount--); +} + diff --git a/scalos/datatypes/GlowIconObject/GlowIconObject-aros.c b/scalos/datatypes/GlowIconObject/GlowIconObject-aros.c new file mode 100644 index 000000000..b15c95b48 --- /dev/null +++ b/scalos/datatypes/GlowIconObject/GlowIconObject-aros.c @@ -0,0 +1,212 @@ +// glowiconobject-classic.c +// $Date$ +// $Revision$ + + +#include +#include + +#include + +#include + + +#include "GlowIconObject.h" + +//---------------------------------------------------------------------------- + +extern struct ExecBase *SysBase; + +//---------------------------------------------------------------------------- + +struct Library *aroscbase; + +// Standard library functions + +static AROS_UFP3 (struct Library *, Initlib, + AROS_UFPA(struct Library *, libbase, D0), + AROS_UFPA(struct SegList *, seglist, A0), + AROS_UFPA(struct ExecBase *, sysbase, A6) +); +static AROS_LD1 (struct Library *, Openlib, + AROS_LPA (__unused ULONG, version, D0), + struct Library *, libbase, 1, GlowIconObject +); +static AROS_LD0 (struct SegList *, Closelib, + struct Library *, base, 2, GlowIconObject +); +static AROS_LD1 (struct SegList *, Expungelib, + AROS_LPA(__unused struct Library *, __extrabase, D0), + struct Library *, libbase, 3, GlowIconObject +); +static AROS_LD0 (ULONG, Extfunclib, + __unused struct Library *, libbase, 4, GlowIconObject +); + +//---------------------------------------------------------------------------- + +/* OS3.x Library */ + +static APTR functable[] = + { + GlowIconObject_1_Openlib, + GlowIconObject_2_Closelib, + GlowIconObject_3_Expungelib, + GlowIconObject_4_Extfunclib, + Dummy_0_ObtainInfoEngine, + (APTR) -1 + }; + +/* Init table used in library initialization. */ +static ULONG inittab[] = + { + sizeof(struct GlowIconObjectDtLibBase), + (ULONG) functable, + 0, + (ULONG) Initlib + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, + RTF_AUTOINIT, + LIB_VERSION, + NT_LIBRARY, + 0, + libName, + libIdString, + inittab + }; + +//---------------------------------------------------------------------------- + +SAVEDS(LONG) ASM Libstart(void) +{ + return -1; +} + +//---------------------------------------------------------------------------- + +static AROS_UFH3(struct Library *, Initlib, + AROS_UFHA(struct Library *, libbase, D0), + AROS_UFHA(struct SegList *, seglist, A0), + AROS_UFHA(struct ExecBase *, sysbase, A6) +) +{ + AROS_USERFUNC_INIT + + struct GlowIconObjectDtLibBase *dtLib = (struct GlowIconObjectDtLibBase *) libbase; + + SysBase = sysbase; + dtLib->nib_ClassLibrary.cl_Lib.lib_Revision = LIB_REVISION; + dtLib->nib_ClassLibrary.cl_Lib.lib_Node.ln_Pri = 10; + dtLib->nib_SegList = seglist; + + aroscbase = OpenLibrary("arosc.library", 0); + + if (!aroscbase || !InitDatatype(dtLib)) + { + GlowIconObject_3_Expungelib(&dtLib->nib_ClassLibrary.cl_Lib, &dtLib->nib_ClassLibrary.cl_Lib); + dtLib = NULL; + } + + return dtLib ? &dtLib->nib_ClassLibrary.cl_Lib : NULL; + + AROS_USERFUNC_EXIT +} + + +static AROS_LH1(struct Library *, Openlib, + AROS_LHA(__unused ULONG, version, D0), + struct Library *, libbase, 1, GlowIconObject +) +{ + AROS_LIBFUNC_INIT + + struct GlowIconObjectDtLibBase *dtLib = (struct GlowIconObjectDtLibBase *) libbase; + + dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt++; + dtLib->nib_ClassLibrary.cl_Lib.lib_Flags &= ~LIBF_DELEXP; + + if (!OpenDatatype(dtLib)) + { + GlowIconObject_2_Closelib(&dtLib->nib_ClassLibrary.cl_Lib); + return NULL; + } + + return &dtLib->nib_ClassLibrary.cl_Lib; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH0(struct SegList *, Closelib, + struct Library *, libbase, 2, GlowIconObject +) +{ + AROS_LIBFUNC_INIT + + struct GlowIconObjectDtLibBase *dtLib = (struct GlowIconObjectDtLibBase *) libbase; + + dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt--; + + if (0 == dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + if (dtLib->nib_ClassLibrary.cl_Lib.lib_Flags & LIBF_DELEXP) + { + return GlowIconObject_3_Expungelib(&dtLib->nib_ClassLibrary.cl_Lib, &dtLib->nib_ClassLibrary.cl_Lib); + } + } + + return NULL; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH1(struct SegList *, Expungelib, + AROS_LHA(__unused struct Library *, __extrabase, D0), + struct Library *, libbase, 3, GlowIconObject +) +{ + AROS_LIBFUNC_INIT + + struct GlowIconObjectDtLibBase *dtLib = (struct GlowIconObjectDtLibBase *) libbase; + + if (0 == dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + ULONG size = dtLib->nib_ClassLibrary.cl_Lib.lib_NegSize + dtLib->nib_ClassLibrary.cl_Lib.lib_PosSize; + UBYTE *ptr = (UBYTE *) dtLib - dtLib->nib_ClassLibrary.cl_Lib.lib_NegSize; + struct SegList *libseglist = dtLib->nib_SegList; + + Remove((struct Node *) dtLib); + CloseDatatype(dtLib); + FreeMem(ptr,size); + + CloseLibrary(aroscbase); + + return libseglist; + } + + dtLib->nib_ClassLibrary.cl_Lib.lib_Flags |= LIBF_DELEXP; + + return NULL; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH0(ULONG, Extfunclib, + __unused struct Library *, libbase, 4, GlowIconObject +) +{ + AROS_LIBFUNC_INIT + + return 0; + + AROS_LIBFUNC_EXIT +} diff --git a/scalos/datatypes/GlowIconObject/GlowIconObject-classic.c b/scalos/datatypes/GlowIconObject/GlowIconObject-classic.c new file mode 100644 index 000000000..840e2b667 --- /dev/null +++ b/scalos/datatypes/GlowIconObject/GlowIconObject-classic.c @@ -0,0 +1,172 @@ +// glowiconobject-classic.c +// $Date$ +// $Revision$ + + +#include +#include + +#include + +#include + + +#include "GlowIconObject.h" + +//---------------------------------------------------------------------------- + +extern struct ExecBase *SysBase; + +//---------------------------------------------------------------------------- + +static LIB_SAVEDS(struct Library *) LIB_ASM LIB_INTERRUPT Initlib(LIB_REG(d0, struct Library *libbase), + LIB_REG(a0, struct SegList *seglist), LIB_REG(a6, struct ExecBase *sysbase)); + +static LIBFUNC_PROTO(Openlib, libbase, struct Library *); +static LIBFUNC_PROTO(Closelib, libbase, struct SegList *); +static LIBFUNC_PROTO(Expungelib, libbase, struct SegList *); +static LIBFUNC_PROTO(Extfunclib, libbase, ULONG); + +//---------------------------------------------------------------------------- + +/* OS3.x Library */ + +static APTR functable[] = + { +#ifdef __MORPHOS__ + (APTR) FUNCARRAY_32BIT_NATIVE, +#endif + Openlib, + Closelib, + Expungelib, + Extfunclib, + ObtainInfoEngine, + (APTR) -1 + }; + +/* Init table used in library initialization. */ +static ULONG inittab[] = + { + sizeof(struct GlowIconObjectDtLibBase), + (ULONG) functable, + 0, + (ULONG) Initlib + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, +#ifdef __MORPHOS__ + RTF_PPC | RTF_AUTOINIT, +#else + RTF_AUTOINIT, +#endif + LIB_VERSION, + NT_LIBRARY, + 0, + libName, + libIdString, + inittab + }; + +#ifdef __MORPHOS__ +ULONG __abox__=1; +#endif + +//---------------------------------------------------------------------------- + +static LIB_SAVEDS(struct Library *) LIB_ASM LIB_INTERRUPT Initlib(LIB_REG(d0, struct Library *libbase), + LIB_REG(a0, struct SegList *seglist), LIB_REG(a6, struct ExecBase *sysbase)) +{ + struct GlowIconObjectDtLibBase *dtLib = (struct GlowIconObjectDtLibBase *) libbase; + + SysBase = sysbase; + dtLib->nib_ClassLibrary.cl_Lib.lib_Revision = LIB_REVISION; + dtLib->nib_ClassLibrary.cl_Lib.lib_Node.ln_Pri = 10; + dtLib->nib_SegList = seglist; + + if (!InitDatatype(dtLib)) + { + CALLLIBFUNC(Expungelib, &dtLib->nib_ClassLibrary.cl_Lib); + dtLib = NULL; + } + + return dtLib ? &dtLib->nib_ClassLibrary.cl_Lib : NULL; +} + + +static LIBFUNC(Openlib, libbase, struct Library *) +{ + struct GlowIconObjectDtLibBase *dtLib = (struct GlowIconObjectDtLibBase *) libbase; + + dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt++; + dtLib->nib_ClassLibrary.cl_Lib.lib_Flags &= ~LIBF_DELEXP; + + if (!OpenDatatype(dtLib)) + { + CALLLIBFUNC(Closelib, &dtLib->nib_ClassLibrary.cl_Lib); + return NULL; + } + + return &dtLib->nib_ClassLibrary.cl_Lib; +} +LIBFUNC_END + + +static LIBFUNC(Closelib, libbase, struct SegList *) +{ + struct GlowIconObjectDtLibBase *dtLib = (struct GlowIconObjectDtLibBase *) libbase; + + dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt--; + + if (0 == dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + if (dtLib->nib_ClassLibrary.cl_Lib.lib_Flags & LIBF_DELEXP) + { + return CALLLIBFUNC(Expungelib, &dtLib->nib_ClassLibrary.cl_Lib); + } + } + + return NULL; +} +LIBFUNC_END + + +static LIBFUNC(Expungelib, libbase, struct SegList *) +{ + struct GlowIconObjectDtLibBase *dtLib = (struct GlowIconObjectDtLibBase *) libbase; + + if (0 == dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + ULONG size = dtLib->nib_ClassLibrary.cl_Lib.lib_NegSize + dtLib->nib_ClassLibrary.cl_Lib.lib_PosSize; + UBYTE *ptr = (UBYTE *) dtLib - dtLib->nib_ClassLibrary.cl_Lib.lib_NegSize; + struct SegList *libseglist = dtLib->nib_SegList; + + Remove((struct Node *) dtLib); + CloseDatatype(dtLib); + FreeMem(ptr,size); + + return libseglist; + } + + dtLib->nib_ClassLibrary.cl_Lib.lib_Flags |= LIBF_DELEXP; + + return NULL; +} +LIBFUNC_END + + +static LIBFUNC(Extfunclib, libbase, ULONG) +{ + (void) libbase; + + d1(kprintf(__FUNC__ "/%ld: libbase=%08lx\n", __LINE__, libbase)); + return 0; +} +LIBFUNC_END + + diff --git a/scalos/datatypes/GlowIconObject/GlowIconObject.c b/scalos/datatypes/GlowIconObject/GlowIconObject.c new file mode 100644 index 000000000..6a738e8cf --- /dev/null +++ b/scalos/datatypes/GlowIconObject/GlowIconObject.c @@ -0,0 +1,4040 @@ +// GlowIconObject.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define __USE_SYSBASE +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "GlowIconObject.h" + +//---------------------------------------------------------------------------- + +#define max(a,b) ((a) > (b) ? (a) : (b)) +#define min(a,b) ((a) < (b) ? (a) : (b)) + + +#define NO_ICON_POSITION_WORD ((WORD) 0x8000) + +//---------------------------------------------------------------------------- + +struct ExecBase *SysBase; +struct GfxBase *GfxBase; +T_UTILITYBASE UtilityBase; +struct Library *WorkbenchBase; +struct Library *IconBase; +struct Library *IconObjectDTBase; +struct IntuitionBase *IntuitionBase; +struct Library *CyberGfxBase; +struct Library *IFFParseBase; +struct DosLibrary *DOSBase; +#ifdef TIMESTAMPS +T_TIMERBASE TimerBase; +#endif /* TIMESTAMPS */ +#ifdef __amigaos4__ +struct Library *NewlibBase; + +struct Interface *INewlib; +struct ExecIFace *IExec; +struct GraphicsIFace *IGraphics; +struct UtilityIFace *IUtility; +struct WorkbenchIFace *IWorkbench; +struct IconIFace *IIcon; +struct IntuitionIFace *IIntuition; +struct CyberGfxIFace *ICyberGfx; +struct IFFParseIFace *IIFFParse; +struct DOSIFace *IDOS; +#endif /* __amigaos4__ */ + +static void *MemPool; +static struct SignalSemaphore PubMemPoolSemaphore; + +static Class *GlowIconObjectClass; + +//---------------------------------------------------------------------------- +// Standard library functions + +static SAVEDS(ULONG) INTERRUPT GlowIconObjectDispatcher(Class *cl, Object *o, Msg msg); + +//----------------------------------------------------------------------------- + +static BOOL DtNew(Class *cl, Object *o, struct opSet *ops); +static ULONG DtDispose(Class *cl, Object *o, Msg msg); +static ULONG DtSet(Class *cl, Object *o, struct opSet *ops); +static ULONG DtGet(Class *cl, Object *o, struct opGet *opg); +static ULONG DtLayout(Class *cl, Object *o, struct iopLayout *iopl); +static ULONG DtFreeLayout(Class *cl, Object *o, struct iopFreeLayout *opf); +static ULONG DtWrite(Class *cl, Object *o, struct iopWrite *iopw); +static ULONG DtNewImage(Class *cl, Object *o, struct iopNewImage *iopw); +static ULONG DtClone(Class *cl, Object *o, struct iopCloneIconObject *iocio); + +//---------------------------------------------------------------------------- + +static void FreePenList(struct Screen *screen, struct NewImagePenList *PenList); +static BOOL DoClonePenList(struct Screen *scr, struct NewImagePenList *nipDest, + const struct NewImagePenList *nipSrc); +static struct Image *DoCloneDoImage(struct Image *imgDest, const struct Image *imgSrc); +static void DoUpdateWb(CONST_STRPTR SavePath); +static void INLINE WriteARGBArray(const struct ARGB *SrcImgData, + ULONG SrcX, ULONG SrcY, ULONG SrcBytesPerRow, + struct RastPort *DestRp, ULONG DestX, ULONG DestY, + ULONG SizeX, ULONG SizeY); +static BOOL INLINE DrawTrueColorImage(struct RastPort *rp, struct NewImage *img, + UWORD Left, UWORD Top, const struct ColorRegister *Palette, + BOOL DimmedImage); +static BOOL INLINE DrawRemappedImage(struct InstanceData *inst, struct RastPort *rp, + struct NewImagePenList *PenList, struct NewImage *img, + UWORD Left, UWORD Top, const struct ColorRegister *Palette, ULONG PaletteSize, + BOOL DimmedImage); +static void DrawColorImage(struct InstanceData *inst, struct RastPort *rp, + struct NewImagePenList *PenList, struct NewImage *img, + UWORD Left, UWORD Top, const struct ColorRegister *Palette, ULONG PaletteSize, + BOOL DimmedImage); +static void ReadIcon(struct InstanceData *inst, CONST_STRPTR Filename, BPTR IconFh); +static BOOL WriteIcon(Class *cl, Object *o, + const struct DiskObject *WriteDiskObject, CONST_STRPTR Filename); +static BOOL ReadStandardIcon(struct InstanceData *inst, BPTR fd); +static BOOL WriteStandardIcon(struct InstanceData *inst, + const struct DiskObject *WriteDiskObject, BPTR fd); +static struct NewImage *ReadNewImage(struct IFFHandle *iff, const struct FaceChunk *fc); +static struct NewImage *ReadARGBImage(struct IFFHandle *iff, const struct FaceChunk *fc); +static LONG WriteNewImage(struct IFFHandle *iff, const struct NewImage *ni); +static LONG WriteARGBImage(Class *cl, Object *o, struct IFFHandle *iff, + const struct NewImage *ni, ULONG ARGBImageTag); +static void FreeNewImage(struct NewImage **ni); +static BOOL CloneNewImage(struct NewImage **niClone, const struct NewImage *niSrc); +static UBYTE *EncodeData(ULONG Depth, UWORD *DestLength, + ULONG SrcLength, const UBYTE *SrcData); +static BOOL DecodeData(const UBYTE *src, UBYTE *dest, size_t SrcLength, + size_t DestLength, LONG BitsPerEntry); +static UBYTE INLINE GetNextDestByte(const UBYTE **src, size_t *SrcLength, short *srcBits, + UBYTE *srcByte, LONG BitsPerEntry); +static UBYTE *GenerateMask(struct NewImage *nim); +static struct NewImage *NewImageFromSAC(struct ScalosBitMapAndColor *sac); +static void GenerateNormalImageMask(Class *cl, Object *o); +static void GenerateSelectedImageMask(Class *cl, Object *o); +static struct NewImage *NewImageFromNormalImage(const struct InstanceData *inst, const struct NewImage *niNormal); +static SAVEDS(LONG) StreamHookDispatcher(struct Hook *hook, struct IFFHandle *iff, const struct IFFStreamCmd *cmd); +static void SetParentAttributes(Class *cl, Object *o); + +#if defined(__AROS__) +static BOOL ReadConvertStandardIcon(BPTR fd, struct DiskObject *dobj); +static BOOL WriteConvertStandardIcon(BPTR fd, struct DiskObject *dobj); +static BOOL ReadConvertDrawerData(BPTR fd, struct DrawerData *drawer); +static BOOL WriteConvertDrawerData(BPTR fd, struct DrawerData *drawer); +static BOOL ReadConvertImage(BPTR fd, struct Image *img); +static BOOL WriteConvertImage(BPTR fd, struct Image *img); +#endif + +//---------------------------------------------------------------------------- + +static APTR MyAllocVecPooled(size_t Size); +static void MyFreeVecPooled(APTR mem); +static void *ZLibAlloc(void *p, int items, int size); +static void ZLibFree(void *p, void *addr); + +//---------------------------------------------------------------------------- + +char ALIGNED libName[] = "glowiconobject.datatype"; +char ALIGNED libIdString[] = "$VER: glowiconobject.datatype " + STR(LIB_VERSION) "." STR(LIB_REVISION) + " (25 Jan 2008 22:31:59) " + COMPILER_STRING + " ©2004" CURRENTYEAR " The Scalos Team"; + +static struct Hook StreamHook = + { + { NULL, NULL }, + HOOKFUNC_DEF(StreamHookDispatcher), // h_Entry + h_SubEntry + NULL, // h_Data + }; + +//---------------------------------------------------------------------------- + +LIBFUNC(ObtainInfoEngine, libbase, ULONG) +{ + (void) libbase; + + d1(kprintf("%s/%s/%ld: libbase=%08lx\n", __FILE__, __FUNC__, __LINE__, libbase)); + + return (ULONG) GlowIconObjectClass; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +// return 0 if error occurred +ULONG InitDatatype(struct GlowIconObjectDtLibBase *dtLib) +{ + d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__)); + + dtLib->nib_Initialized = FALSE; + + return 1; +} + +// return 0 if error occurred +ULONG OpenDatatype(struct GlowIconObjectDtLibBase *dtLib) +{ + d1(kprintf("%s/%s/%ld: OpenCnt=%ld\n", __FILE__, __FUNC__, __LINE__, dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt)); + + if (!dtLib->nib_Initialized) + { + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + dtLib->nib_Initialized = TRUE; + + InitSemaphore(&PubMemPoolSemaphore); + + DOSBase = (struct DosLibrary *) OpenLibrary("dos.library", 39); + d1(kprintf("%s/%s/%ld: DOSBase=%08lx\n", __FILE__, __FUNC__, __LINE__, DOSBase)); + if (NULL == DOSBase) + return 0; +#ifdef __amigaos4__ + IDOS = (struct DOSIFace *)GetInterface((struct Library *)DOSBase, "main", 1, NULL); + if (NULL == IDOS) + return 0; +#endif /* __amigaos4__ */ + + IFFParseBase = OpenLibrary("iffparse.library", 39); + d1(kprintf("%s/%s/%ld: IFFParseBase=%08lx\n", __FILE__, __FUNC__, __LINE__, IFFParseBase)); + if (NULL == IFFParseBase) + return 0; +#ifdef __amigaos4__ + IIFFParse = (struct IFFParseIFace *)GetInterface((struct Library *)IFFParseBase, "main", 1, NULL); + if (NULL == IIFFParse) + return 0; +#endif /* __amigaos4__ */ + + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + d1(kprintf("%s/%s/%ld: IntuitionBase=%08lx\n", __FILE__, __FUNC__, __LINE__, IntuitionBase)); + if (NULL == IntuitionBase) + return 0; +#ifdef __amigaos4__ + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + return 0; +#endif /* __amigaos4__ */ + + UtilityBase = (T_UTILITYBASE) OpenLibrary("utility.library", 39); + d1(kprintf("%s/%s/%ld: UtilityBase=%08lx\n", __FILE__, __FUNC__, __LINE__, UtilityBase)); + if (NULL == UtilityBase) + return 0; +#ifdef __amigaos4__ + IUtility = (struct UtilityIFace *)GetInterface((struct Library *)UtilityBase, "main", 1, NULL); + if (NULL == IUtility) + return 0; +#endif /* __amigaos4__ */ + + IconBase = OpenLibrary(ICONNAME, 39); + d1(kprintf("%s/%s/%ld: IconBase=%08lx\n", __FILE__, __FUNC__, __LINE__, IconBase)); + if (NULL == IconBase) + return 0; +#ifdef __amigaos4__ + IIcon = (struct IconIFace *)GetInterface((struct Library *)IconBase, "main", 1, NULL); + if (NULL == IIcon) + return 0; +#endif /* __amigaos4__ */ + + GfxBase = (struct GfxBase *) OpenLibrary(GRAPHICSNAME, 39); + d1(kprintf("%s/%s/%ld: GfxBase=%08lx\n", __FILE__, __FUNC__, __LINE__, GfxBase)); + if (NULL == GfxBase) + return 0; +#ifdef __amigaos4__ + IGraphics = (struct GraphicsIFace *)GetInterface((struct Library *)GfxBase, "main", 1, NULL); + if (NULL == IGraphics) + return 0; +#endif /* __amigaos4__ */ + + WorkbenchBase = OpenLibrary("workbench.library", 39); + d1(KPrintF("%s/%s/%ld: WorkbenchBase=%08lx\n", __FILE__, __FUNC__, __LINE__, WorkbenchBase)); + if (NULL == WorkbenchBase) + return 0; +#ifdef __amigaos4__ + IWorkbench = (struct WorkbenchIFace *)GetInterface((struct Library *)WorkbenchBase, "main", 1, NULL); + if (NULL == IWorkbench) + return 0; +#endif /* __amigaos4__ */ + + IconObjectDTBase = OpenLibrary("datatypes/iconobject.datatype", 39); + if (NULL == IconObjectDTBase) + return 0; + +#ifdef TIMESTAMPS + { + struct timerequest *iorequest; + + iorequest = (struct timerequest *) CreateIORequest(CreateMsgPort(), sizeof(struct timerequest)); + OpenDevice("timer.device", UNIT_VBLANK, &iorequest->tr_node, 0); + TimerBase = (T_TIMERBASE) iorequest->tr_node.io_Device; + } +#endif /* TIMESTAMPS */ + +#if !defined(__amigaos4__) && !defined(__AROS__) + if (_STI_240_InitMemFunctions()) + return 0; +#endif /* __amigaos4__ */ + + MemPool = CreatePool(MEMPOOL_MEMFLAGS, MEMPOOL_PUDDLESIZE, MEMPOOL_THRESHSIZE); + d1(kprintf("%s/%s/%ld: MemPool=%08lx\n", __FILE__, __FUNC__, __LINE__, MemPool)); + if (NULL == MemPool) + return 0; + + GlowIconObjectClass = dtLib->nib_ClassLibrary.cl_Class = MakeClass(libName, + "iconobject.datatype", NULL, sizeof(struct InstanceData), 0); + d1(kprintf("%s/%s/%ld: GlowIconObjectClass=%08lx\n", __FILE__, __FUNC__, __LINE__, GlowIconObjectClass)); + if (NULL == GlowIconObjectClass) + return 0; + + SETHOOKFUNC(GlowIconObjectClass->cl_Dispatcher, GlowIconObjectDispatcher); + GlowIconObjectClass->cl_Dispatcher.h_Data = dtLib; + + // Make class available for the public + AddClass(GlowIconObjectClass); + + CyberGfxBase = OpenLibrary(CYBERGFXNAME, 0); + // CyberGfxBase may be NULL +#ifdef __amigaos4__ + if (NULL != CyberGfxBase) + { + ICyberGfx = (struct CyberGfxIFace *)GetInterface((struct Library *)CyberGfxBase, "main", 1, NULL); + if (NULL == ICyberGfx) + { + CloseLibrary(CyberGfxBase); + CyberGfxBase = NULL; + } + } + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + return 0; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + return 0; +#endif /* __amigaos4__ */ + } + + d1(kprintf("%s/%s/%ld: Open Success!\n", __FILE__, __FUNC__, __LINE__)); + + return 1; +} + +void CloseDatatype(struct GlowIconObjectDtLibBase *dtLib) +{ + d1(kprintf("%s/%s/%ld: OpenCnt=%ld\n", __FILE__, __FUNC__, __LINE__, dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt)); + + if (dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt < 1) + { + if (GlowIconObjectClass) + { + RemoveClass(GlowIconObjectClass); + FreeClass(GlowIconObjectClass); + GlowIconObjectClass = dtLib->nib_ClassLibrary.cl_Class = NULL; + } + + if (NULL != IconObjectDTBase) + { + CloseLibrary(IconObjectDTBase); + IconObjectDTBase = NULL; + } +#ifdef __amigaos4__ + if (INewlib) + { + DropInterface(INewlib); + INewlib = NULL; + } + if (NewlibBase) + { + CloseLibrary(NewlibBase); + NewlibBase = NULL; + } + if (NULL != IWorkbench) + { + DropInterface((struct Interface *)IWorkbench); + IWorkbench = NULL; + } +#endif /* __amigaos4__ */ + if (NULL != WorkbenchBase) + { + CloseLibrary(WorkbenchBase); + WorkbenchBase = NULL; + } +#ifdef __amigaos4__ + if (NULL != IIcon) + { + DropInterface((struct Interface *)IIcon); + IIcon = NULL; + } +#endif /* __amigaos4__ */ + if (NULL != IconBase) + { + CloseLibrary(IconBase); + IconBase = NULL; + } +#ifdef __amigaos4__ + if (NULL != ICyberGfx) + { + DropInterface((struct Interface *)ICyberGfx); + ICyberGfx = NULL; + } +#endif /* __amigaos4__ */ + if (NULL != CyberGfxBase) + { + CloseLibrary(CyberGfxBase); + CyberGfxBase = NULL; + } +#if !defined(__amigaos4__) && !defined(__AROS__) + _STD_240_TerminateMemFunctions(); +#endif /* __amigaos4__ */ + if (NULL != MemPool) + { + DeletePool(MemPool); + MemPool = NULL; + } + +#ifdef __amigaos4__ + if (NULL != IGraphics) + { + DropInterface((struct Interface *)IGraphics); + IGraphics = NULL; + } +#endif /* __amigaos4__ */ + if (NULL != GfxBase) + { + CloseLibrary((struct Library *) GfxBase); + GfxBase = NULL; + } +#ifdef __amigaos4__ + if (NULL != IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } +#endif /* __amigaos4__ */ + if (NULL != IntuitionBase) + { + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } +#ifdef __amigaos4__ + if (NULL != IIFFParse) + { + DropInterface((struct Interface *)IIFFParse); + IIFFParse = NULL; + } +#endif /* __amigaos4__ */ + if (IFFParseBase) + { + CloseLibrary(IFFParseBase); + IFFParseBase = NULL; + } +#ifdef __amigaos4__ + if (NULL != IUtility) + { + DropInterface((struct Interface *)IUtility); + IUtility = NULL; + } +#endif /* __amigaos4__ */ + if (NULL != UtilityBase) + { + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } +#ifdef __amigaos4__ + if (NULL != IDOS) + { + DropInterface((struct Interface *)IDOS); + IDOS = NULL; + } +#endif /* __amigaos4__ */ + if (NULL != DOSBase) + { + CloseLibrary((struct Library *)DOSBase); + DOSBase = NULL; + } + } +} + +//----------------------------------------------------------------------------- + +static SAVEDS(ULONG) INTERRUPT GlowIconObjectDispatcher(Class *cl, Object *o, Msg msg) +{ + ULONG Result; + + d1(kprintf("%s/%s/%ld: MethodID=%08lx o=%08lx\n", __FILE__, __FUNC__, __LINE__, msg->MethodID, o)); + + switch (msg->MethodID) + { + case OM_NEW: + o = (Object *) DoSuperMethodA(cl, o, msg); + d1(kprintf("%s/%s/%ld: OM_NEW o=%08lx\n", __FILE__, __FUNC__, __LINE__, o)); + if (o) + { + d1(kprintf("%s/%s/%ld: OM_NEW o=%08lx\n", __FILE__, __FUNC__, __LINE__, o)); + if (!DtNew(cl, o, (struct opSet *) msg)) + { + DoMethod(o, OM_DISPOSE); + o = NULL; + } + } + Result = (ULONG) o; + break; + + case OM_DISPOSE: + d1(kprintf("%s/%s/%ld: OM_DISPOSE o=%08lx\n", __FILE__, __FUNC__, __LINE__, o)); + Result = DtDispose(cl, o, msg); + break; + + case OM_SET: + Result = DtSet(cl, o, (struct opSet *) msg); + break; + + case OM_GET: + Result = DtGet(cl, o, (struct opGet *) msg); + break; + + case IDTM_Layout: + Result = DtLayout(cl, o, (struct iopLayout *) msg); + break; + + case IDTM_FreeLayout: + d1(kprintf("%s/%s/%ld: IDTM_FreeLayout o=%08lx\n", __FILE__, __FUNC__, __LINE__, o)); + Result = DtFreeLayout(cl, o, (struct iopFreeLayout *) msg); + break; + + case IDTM_Write: + Result = DtWrite(cl, o, (struct iopWrite *) msg); + break; + + case IDTM_NewImage: + Result = DtNewImage(cl, o, (struct iopNewImage *) msg); + break; + + case IDTM_CloneIconObject: + Result = DtClone(cl, o, (struct iopCloneIconObject *) msg); + break; + + default: + d1(kprintf("%s/%s/%ld: default o=%08lx\n", __FILE__, __FUNC__, __LINE__, o)); + Result = DoSuperMethodA(cl, o, msg); + break; + } + + d1(kprintf("%s/%s/%ld: MethodID=%08lx o=%08lx Result=%ld\n", __FILE__, __FUNC__, __LINE__, + msg->MethodID, o, Result)); + + return Result; +} + +//----------------------------------------------------------------------------- + +static BOOL DtNew(Class *cl, Object *o, struct opSet *ops) +{ + struct InstanceData *inst = INST_DATA(cl, o); + struct ExtGadget *gg = (struct ExtGadget *) o; + BOOL Success = FALSE; + + do { + ULONG DefIconType; + STRPTR IconName; + ULONG SupportedIconTypes; + BPTR IconFh; + + d1(kprintf("%s/%s/%ld: START o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + TIMESTAMP_d1(); + + memset(inst, 0, sizeof(struct InstanceData)); + + inst->aio_BackfillPenNorm = inst->aio_BackfillPenSel = IDTA_BACKFILL_NONE; + + SupportedIconTypes = GetTagData(IDTA_SupportedIconTypes, ~0, ops->ops_AttrList); + if (!(SupportedIconTypes & IDTV_IconType_ColorIcon)) + break; + + inst->aio_ImageLeft = GetTagData(IDTA_InnerLeft, 0, ops->ops_AttrList); + inst->aio_ImageTop = GetTagData(IDTA_InnerTop, 0, ops->ops_AttrList); + + DefIconType = GetTagData(IDTA_DefType, 0, ops->ops_AttrList); + d1(kprintf("%s/%s/%ld: o=%08lx DefIconType=%lu\n", __FILE__, __FUNC__, __LINE__, o, DefIconType)); + + if (0 != DefIconType) + break; + + if (NULL != (struct DiskObject *) GetTagData(AIDTA_Icon, (ULONG) NULL, ops->ops_AttrList)) + break; + + if (FindTagItem(IDTA_CloneIconObject, ops->ops_AttrList)) + { + d1(KPrintF("%s/%s/%ld: IDTA_CloneIconObject\n", __FILE__, __FUNC__, __LINE__)); + } + else + { + GetAttr(DTA_Name, o, (APTR) &IconName); + d1(KPrintF("%s/%s/%ld: o=%08lx IconName=<%s>\n", __FILE__, __FUNC__, __LINE__, o, IconName ? IconName : (STRPTR) "")); + + // Get named icon + if (NULL == IconName) + break; + + IconFh = (BPTR)GetTagData(DTA_Handle, 0, ops->ops_AttrList); + d1(KPrintF("%s/%s/%ld: IconFh=%08lx\n", __FILE__, __FUNC__, __LINE__, IconFh)); + + TIMESTAMP_d1(); + ReadIcon(inst, IconName, IconFh); + TIMESTAMP_d1(); + if (NULL == inst->aio_Image1) + break; // fall back to standard icon if no NewImage + + if (NULL == inst->aio_Image2) + { + // No selected image available. + // Generate darkened selected image from normal image + struct NewImage *ni; + + TIMESTAMP_d1(); + ni = NewImageFromNormalImage(inst, inst->aio_Image1); + d1(KPrintF("%s/%s/%ld: ni=%08lx\n", __FILE__, __FUNC__, __LINE__, ni)); + if (NULL == ni) + break; + + FreeNewImage(&inst->aio_Image2); + inst->aio_Image2 = ni; + } + + d1(kprintf("%s/%s/%ld: o=%08lx aio_DiskObject=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst->aio_DiskObject)); + if (NULL == inst->aio_DiskObject) + break; + + if (NO_ICON_POSITION == inst->aio_DiskObject->do_CurrentX) + { + gg->LeftEdge = gg->TopEdge = NO_ICON_POSITION_WORD; + } + else + { + gg->LeftEdge = inst->aio_DiskObject->do_CurrentX; + gg->TopEdge = inst->aio_DiskObject->do_CurrentY; + } + + if (NULL == inst->aio_DiskObject->do_DrawerData) + { + inst->aio_myDrawerData = MyAllocVecPooled(sizeof(struct DrawerData)); + if (NULL == inst->aio_myDrawerData) + break; + + memset(inst->aio_myDrawerData, 0, sizeof(struct DrawerData)); + + switch (inst->aio_DiskObject->do_Type) + { + case WBTOOL: + case WBPROJECT: + case WBKICK: + break; + default: + inst->aio_DiskObject->do_DrawerData = inst->aio_myDrawerData; + break; + } + } + + SetParentAttributes(cl, o); + TIMESTAMP_d1(); + } + + d1(kprintf("%s/%s/%ld: o=%08lx GadgetRender=%08lx\n", __FILE__, __FUNC__, __LINE__, o, gg->GadgetRender)); + TIMESTAMP_d1(); + + Success = TRUE; + } while (0); + + d1(kprintf("%s/%s/%ld: END o=%08lx Success=%ld\n", __FILE__, __FUNC__, __LINE__, o, Success)); + TIMESTAMP_d1(); + + return Success; +} + +//----------------------------------------------------------------------------- + +static ULONG DtDispose(Class *cl, Object *o, Msg msg) +{ + struct InstanceData *inst = INST_DATA(cl, o); +// struct ExtGadget *gg = (struct ExtGadget *) o; + + d1(kprintf("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + + d1(kprintf("%s/%s/%ld: o=%08lx aio_myDrawerData=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst->aio_myDrawerData)); + if (inst->aio_myDrawerData) + { + MyFreeVecPooled(inst->aio_myDrawerData); + inst->aio_myDrawerData = NULL; + if (inst->aio_DiskObject) + inst->aio_DiskObject->do_DrawerData = NULL; + } + + if (inst->aio_DefaultTool) + { + MyFreeVecPooled(inst->aio_DefaultTool); + inst->aio_DefaultTool = NULL; + } + if (inst->aio_ToolTypes) + { + STRPTR *ToolTypePtr = inst->aio_ToolTypes; + + d1(KPrintF("%s/%s/%ld: do_ToolTypes=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->aio_DiskObject->do_ToolTypes)); + + while (*ToolTypePtr) + { + d1(KPrintF("%s/%s/%ld: *ToolTypePtr=<%s>\n", __FILE__, __FUNC__, __LINE__, *ToolTypePtr)); + MyFreeVecPooled(*ToolTypePtr); + *ToolTypePtr = NULL; + ToolTypePtr++; + } + + MyFreeVecPooled(inst->aio_ToolTypes); + inst->aio_ToolTypes = NULL; + } + if (inst->aio_ToolWindow) + { + MyFreeVecPooled(inst->aio_ToolWindow); + inst->aio_ToolWindow = NULL; + } + + d1(kprintf("%s/%s/%ld: o=%08lx aio_DiskObject=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst->aio_DiskObject)); + + if (inst->aio_DiskObject) + { + MyFreeVecPooled(inst->aio_DiskObject); + inst->aio_DiskObject = NULL; + } + if (inst->aio_DoImage1.ImageData) + { + MyFreeVecPooled(inst->aio_DoImage1.ImageData); + inst->aio_DoImage1.ImageData = NULL; + } + if (inst->aio_DoImage2.ImageData) + { + MyFreeVecPooled(inst->aio_DoImage2.ImageData); + inst->aio_DoImage2.ImageData = NULL; + } + if (inst->aio_PenList1.nip_PenArray) + { + FreePenList(inst->aio_Screen, &inst->aio_PenList1); + } + if (inst->aio_PenList2.nip_PenArray) + { + FreePenList(inst->aio_Screen, &inst->aio_PenList2); + } + + FreeNewImage(&inst->aio_Image1); + FreeNewImage(&inst->aio_Image2); + + d1(kprintf("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + + return DoSuperMethodA(cl, o, msg); +} + +//---------------------------------------------------------------------------------------- + +static ULONG DtSet(Class *cl, Object *o, struct opSet *ops) +{ + struct InstanceData *inst = INST_DATA(cl, o); + + d1(kprintf("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + + inst->aio_ImageLeft = GetTagData(IDTA_InnerLeft, inst->aio_ImageLeft, ops->ops_AttrList); + inst->aio_ImageTop = GetTagData(IDTA_InnerTop, inst->aio_ImageTop, ops->ops_AttrList); + + inst->aio_BackfillPenNorm = GetTagData(IDTA_Backfill, inst->aio_BackfillPenNorm, ops->ops_AttrList); + inst->aio_BackfillPenSel = GetTagData(IDTA_BackfillSel, inst->aio_BackfillPenSel, ops->ops_AttrList); + + return DoSuperMethodA(cl, o, (Msg) ops); +} + +//---------------------------------------------------------------------------------------- + +static ULONG DtGet(Class *cl, Object *o, struct opGet *opg) +{ + struct InstanceData *inst = INST_DATA(cl, o); + ULONG result = 1; + + d1(kprintf("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + + switch (opg->opg_AttrID) + { + case IDTA_IconType: + *opg->opg_Storage = ioICONTYPE_GlowIcon; + break; + + case IDTA_NumberOfColorsSupported: + *opg->opg_Storage = inst->aio_Image1->nim_Palette ? 256 : (1 + 0x00ffffff); + d1(KPrintF("%s/%s/%ld: o=%08lx IDTA_NumberOfColorsSupported=%lu\n", __FILE__, __FUNC__, __LINE__, o, *opg->opg_Storage)); + break; + + case AIDTA_Icon: + *opg->opg_Storage = (ULONG) inst->aio_DiskObject; + break; + + case IDTA_Extention: + *opg->opg_Storage = (ULONG) ".info"; + break; + + default: + result = DoSuperMethodA(cl, o, (Msg) opg); + break; + } + + d1(kprintf("%s/%s/%ld: o=%08lx GadgetRender=%08lx\n", __FILE__, __FUNC__, __LINE__, o, ((struct ExtGadget *) o)->GadgetRender)); + + return result; +} + +//----------------------------------------------------------------------------- + +static ULONG DtLayout(Class *cl, Object *o, struct iopLayout *iopl) +{ + struct InstanceData *inst = INST_DATA(cl, o); + struct ExtGadget *gg = (struct ExtGadget *) o; + + d1(KPrintF("%s/%s/%ld: START o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + + TIMESTAMP_d1(); + DoSuperMethodA(cl, o, (Msg) iopl); + TIMESTAMP_d1(); + + d1(kprintf("%s/%s/%ld: o=%08lx Screen=%08lx\n", __FILE__, __FUNC__, __LINE__, o, iopl->iopl_Screen)); + d1(KPrintF("%s/%s/%ld: o=%08lx Width=%ld Height=%ld\n", __FILE__, __FUNC__, __LINE__, o, gg->Width, gg->Height)); + d1(kprintf("%s/%s/%ld: o=%08lx GadgetRender=%08lx SelectRender=%08lx Flags=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, o, gg->GadgetRender, gg->SelectRender, iopl->iopl_Flags)); + + // skip layout if ARGB image (no nim_Palette) + if (inst->aio_Image1->nim_Palette) + { + inst->aio_Screen = iopl->iopl_Screen; + + if (gg->GadgetRender && (iopl->iopl_Flags & IOLAYOUTF_NormalImage)) + { + d1(KPrintF("%s/%s/%ld: o=%08lx Image1 nim_Palette=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst->aio_Image1->nim_Palette)); + if (inst->aio_Image1->nim_Palette) + { + TIMESTAMP_d1(); + DrawColorImage(inst, (struct RastPort *) gg->GadgetRender, + &inst->aio_PenList1, inst->aio_Image1, + inst->aio_ImageLeft, inst->aio_ImageTop, + inst->aio_Image1->nim_Palette, inst->aio_Image1->nim_PaletteSize, + FALSE); + TIMESTAMP_d1(); + } + } + if (gg->SelectRender && (iopl->iopl_Flags & IOLAYOUTF_SelectedImage)) + { + BOOL DimImage; + const struct ColorRegister *Palette; + ULONG PaletteSize; + struct NewImage *nim; + + d1(KPrintF("%s/%s/%ld: o=%08lx Image2=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst->aio_Image2)); + TIMESTAMP_d1(); + + if (inst->aio_Image2) + { + nim = inst->aio_Image2; + + if (inst->aio_Image2->nim_ImageChunk.ic_Flags & ICF_HasPalette) + { + Palette = inst->aio_Image2->nim_Palette; + PaletteSize = inst->aio_Image2->nim_PaletteSize; + } + else + { + Palette = inst->aio_Image1->nim_Palette; + PaletteSize = inst->aio_Image1->nim_PaletteSize; + } + DimImage = FALSE; + } + else + { + nim = inst->aio_Image1; + Palette = inst->aio_Image1->nim_Palette; + PaletteSize = inst->aio_Image1->nim_PaletteSize; + DimImage = TRUE; + } + + d1(KPrintF("%s/%s/%ld: o=%08lx Palette=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst->aio_Image1->nim_Palette)); + DrawColorImage(inst, (struct RastPort *) gg->SelectRender, + &inst->aio_PenList2, nim, + inst->aio_ImageLeft, inst->aio_ImageTop, + Palette, PaletteSize, DimImage); + } + } + + d1(KPrintF("%s/%s/%ld: END o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + TIMESTAMP_d1(); + + return 0; +} + +//----------------------------------------------------------------------------- + +static ULONG DtFreeLayout(Class *cl, Object *o, struct iopFreeLayout *opf) +{ + struct InstanceData *inst = INST_DATA(cl, o); +// struct ExtGadget *gg = (struct ExtGadget *) o; + + d1(KPrintF("%s/%s/%ld: START o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + + if (inst->aio_Screen && (opf->iopf_Flags & IOFREELAYOUTF_ScreenAvailable)) + { + if (inst->aio_PenList1.nip_PenArray) + { + FreePenList(inst->aio_Screen, &inst->aio_PenList1); + } + if (inst->aio_PenList2.nip_PenArray) + { + FreePenList(inst->aio_Screen, &inst->aio_PenList2); + } + } + else + { + if (inst->aio_PenList1.nip_PenArray) + { + MyFreeVecPooled(inst->aio_PenList1.nip_PenArray); + inst->aio_PenList1.nip_PenArray = NULL; + } + if (inst->aio_PenList2.nip_PenArray) + { + MyFreeVecPooled(inst->aio_PenList2.nip_PenArray); + inst->aio_PenList2.nip_PenArray = NULL; + } + } + + d1(KPrintF("%s/%s/%ld: END o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + + return DoSuperMethodA(cl, o, (Msg) opf); +} + +//----------------------------------------------------------------------------- + +static ULONG DtWrite(Class *cl, Object *o, struct iopWrite *iopw) +{ + struct InstanceData *inst = INST_DATA(cl, o); + struct ExtGadget *gg = (struct ExtGadget *) o; + struct WriteData wd; + struct DiskObject *WriteDiskObject; + struct DiskObject DiskObjectCopy; + ULONG Result = RETURN_OK; + + d1(kprintf("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + + do { + ULONG NeedUpdateWB; + IPTR storage; + + memset(&DiskObjectCopy, 0, sizeof(DiskObjectCopy)); + + NeedUpdateWB = GetTagData(ICONA_NotifyWorkbench, FALSE, iopw->iopw_Tags); + + // Allocate empty DiskObject + WriteDiskObject = GetDiskObjectNew(NULL); + d1(kprintf("%s/%s/%ld: o=%08lx WriteDiskObject=%08lx\n", __FILE__, __FUNC__, __LINE__, o, WriteDiskObject)); + if (NULL == WriteDiskObject) + break; + + // Remember original contents of WriteDiskObject + DiskObjectCopy = *WriteDiskObject; + + memset(&wd, 0, sizeof(wd)); + + GetAttr(IDTA_Type, o, &storage); + wd.aiowd_Type = storage; + GetAttr(IDTA_ViewModes, o, &storage); + wd.aiowd_ViewModes = storage; + GetAttr(IDTA_Flags, o, &storage); + wd.aiowd_Flags = storage; + GetAttr(IDTA_WinCurrentX, o, &storage); + wd.aiowd_CurrentX = storage; + GetAttr(IDTA_WinCurrentY, o, &storage); + wd.aiowd_CurrentY = storage; + GetAttr(IDTA_WindowRect, o, &storage); + wd.aiowd_WindowRect = (struct IBox *)storage; + GetAttr(IDTA_Stacksize, o, &storage); + wd.aiowd_StackSize = storage; + GetAttr(IDTA_ToolTypes, o, &storage); + wd.aiowd_ToolTypes = (STRPTR *)storage; + GetAttr(IDTA_DefaultTool, o, &storage); + wd.aiowd_DefaultTool = (STRPTR)storage; + + *WriteDiskObject = *inst->aio_DiskObject; + + WriteDiskObject->do_DefaultTool = wd.aiowd_DefaultTool; + WriteDiskObject->do_ToolTypes = wd.aiowd_ToolTypes; + WriteDiskObject->do_StackSize = wd.aiowd_StackSize; + WriteDiskObject->do_Type = wd.aiowd_Type; + WriteDiskObject->do_DrawerData = NULL; + WriteDiskObject->do_Gadget = inst->aio_DiskObject->do_Gadget; + WriteDiskObject->do_ToolWindow = inst->aio_DiskObject->do_ToolWindow; + + switch (WriteDiskObject->do_Type) + { + case WBTOOL: + case WBPROJECT: + case WBKICK: + break; + default: + if (inst->aio_DiskObject->do_DrawerData) + WriteDiskObject->do_DrawerData = inst->aio_DiskObject->do_DrawerData; + else + WriteDiskObject->do_DrawerData = inst->aio_myDrawerData; + + WriteDiskObject->do_DrawerData->dd_CurrentX = wd.aiowd_CurrentX; + WriteDiskObject->do_DrawerData->dd_CurrentY = wd.aiowd_CurrentY; + + if (wd.aiowd_WindowRect) + { + WriteDiskObject->do_DrawerData->dd_NewWindow.LeftEdge = wd.aiowd_WindowRect->Left; + WriteDiskObject->do_DrawerData->dd_NewWindow.TopEdge = wd.aiowd_WindowRect->Top; + WriteDiskObject->do_DrawerData->dd_NewWindow.Width = wd.aiowd_WindowRect->Width; + WriteDiskObject->do_DrawerData->dd_NewWindow.Height = wd.aiowd_WindowRect->Height; + WriteDiskObject->do_DrawerData->dd_Flags = wd.aiowd_Flags; + WriteDiskObject->do_DrawerData->dd_ViewModes = wd.aiowd_ViewModes; + } + break; + } + + if (GetTagData(ICONA_NoPosition, 0, iopw->iopw_Tags)) + { + WriteDiskObject->do_CurrentX = WriteDiskObject->do_CurrentY = NO_ICON_POSITION; + } + else + { + if (NO_ICON_POSITION_WORD == gg->LeftEdge) + { + WriteDiskObject->do_CurrentX = WriteDiskObject->do_CurrentY = NO_ICON_POSITION; + } + else + { + WriteDiskObject->do_CurrentX = gg->LeftEdge; + WriteDiskObject->do_CurrentY = gg->TopEdge; + } + } + + d1(kprintf("%s/%s/%ld: o=%08lx inst=%08lx Path=<%s>\n", __FILE__, __FUNC__, __LINE__, o, inst, iopw->iopw_Path)); + + if (GetTagData(ICONA_NoNewImage, 0, iopw->iopw_Tags)) + { + } + + if (NULL == inst->aio_Image1->nim_Palette) + { + // Special check for ARGB icons: + // if no IDTA_SelARGBImageData is present (e.g. for created Thumbnails), + // then make sure inst->aio_Image2 is cleared. + struct ARGBHeader *argbh = NULL; + + GetAttr(IDTA_SelARGBImageData, o, (APTR) &argbh); + if (NULL == argbh || NULL == argbh->argb_ImageData) + FreeNewImage(&inst->aio_Image2); + } + + if (!WriteIcon(cl, o, WriteDiskObject, iopw->iopw_Path)) + { + Result = IoErr(); + break; + } + + if (NeedUpdateWB) + DoUpdateWb(iopw->iopw_Path); + } while (0); + + if (WriteDiskObject) + { + // Restore original contents of WriteDiskObject + *WriteDiskObject = DiskObjectCopy; + FreeDiskObject(WriteDiskObject); + } + + return Result; +} + +//----------------------------------------------------------------------------- + +static ULONG DtNewImage(Class *cl, Object *o, struct iopNewImage *ioni) +{ + struct InstanceData *inst = INST_DATA(cl, o); + + d1(KPrintF("%s/%s/%ld: START o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + + do { + struct NewImage *ni; + + if (NULL == ioni->ioni_NormalImage) + break; + + ni = NewImageFromSAC(ioni->ioni_NormalImage); + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__, ni)); + if (NULL == ni) + break; + + if (inst->aio_PenList1.nip_PenArray) + { + FreePenList(inst->aio_Screen, &inst->aio_PenList1); + } + + FreeNewImage(&inst->aio_Image1); + inst->aio_Image1 = ni; + + if (ioni->ioni_SelectedImage) + { + ni = NewImageFromSAC(ioni->ioni_SelectedImage); + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__, ni)); + if (NULL == ni) + break; + } + else + { + ni = NewImageFromNormalImage(inst, inst->aio_Image1); + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__, ni)); + if (NULL == ni) + break; + } + + if (inst->aio_PenList2.nip_PenArray) + { + FreePenList(inst->aio_Screen, &inst->aio_PenList2); + } + + FreeNewImage(&inst->aio_Image2); + inst->aio_Image2 = ni; + } while (0); + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + // update aio_FaceChunk + inst->aio_FaceChunk.fc_Width = inst->aio_Image1->nim_Width; + inst->aio_FaceChunk.fc_Height = inst->aio_Image1->nim_Height; + if (inst->aio_Image2) + { + if (inst->aio_Image2->nim_Width > inst->aio_Image1->nim_Width) + inst->aio_FaceChunk.fc_Width = inst->aio_Image2->nim_Width; + if (inst->aio_Image2->nim_Height > inst->aio_Image1->nim_Height) + inst->aio_FaceChunk.fc_Height = inst->aio_Image2->nim_Height; + } + inst->aio_FaceChunk.fc_Width--; + inst->aio_FaceChunk.fc_Height--; + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + SetAttrs(o, + GA_Width, inst->aio_Image1->nim_Width, + GA_Height, inst->aio_Image1->nim_Height, + IDTA_UnscaledWidth, inst->aio_Image1->nim_Width, + IDTA_UnscaledHeight, inst->aio_Image1->nim_Height, + TAG_END); + + GenerateNormalImageMask(cl, o); + GenerateSelectedImageMask(cl, o); + + d1(KPrintF("%s/%s/%ld: END o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + + return 0; +} + +//----------------------------------------------------------------------------- + +static ULONG DtClone(Class *cl, Object *o, struct iopCloneIconObject *iocio) +{ + struct InstanceData *inst = INST_DATA(cl, o); + Object *oClone; + BOOL Success = FALSE; + + d1(KPrintF("%s/%s/%ld: START o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + + do { + struct ExtGadget *gg = (struct ExtGadget *) o; + struct ARGBHeader *NrmARGBImage = &inst->aio_Image1->nim_ARGBheader; + struct ARGBHeader *SelARGBImage = &inst->aio_Image2->nim_ARGBheader; + struct InstanceData *instClone; + + oClone = (Object *) NewObject(cl, NULL, + DTA_Name, "cloned", // REQUIRED, otherwise NewObject() will fail + IDTA_CloneIconObject, o, + TAG_MORE, iocio->iocio_TagList, + TAG_END); + d1(KPrintF("%s/%ld: o=%08lx inst=%08lx oClone=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst, oClone)); + if (NULL == oClone) + break; + + instClone = INST_DATA(cl, oClone); + + *instClone = *inst; + + if (inst->aio_myDrawerData) + { + instClone->aio_myDrawerData = MyAllocVecPooled(sizeof(struct DrawerData)); + if (NULL == instClone->aio_myDrawerData) + break; + + *(instClone->aio_myDrawerData) = *(inst->aio_myDrawerData); + } + + if (inst->aio_DefaultTool) + { + // Clone Default Tool + instClone->aio_DefaultTool = MyAllocVecPooled(1 + strlen(inst->aio_DefaultTool)); + d1(KPrintF("%s/%s/%ld: aio_DefaultTool=%08lx\n", __FILE__, __FUNC__, __LINE__, instClone->aio_DefaultTool)); + if (NULL == instClone->aio_DefaultTool) + break; + + strcpy(instClone->aio_DefaultTool, inst->aio_DefaultTool); + } + if (inst->aio_ToolWindow) + { + // Clone Tool Window + instClone->aio_ToolWindow = MyAllocVecPooled(1 + strlen(inst->aio_ToolWindow)); + d1(KPrintF("%s/%s/%ld: aio_ToolWindow=%08lx\n", __FILE__, __FUNC__, __LINE__, instClone->aio_ToolWindow)); + if (NULL == instClone->aio_ToolWindow) + break; + + strcpy(instClone->aio_ToolWindow, inst->aio_ToolWindow); + } + + if (inst->aio_ToolTypes) + { + // Clone ToolTypes array + STRPTR *ToolTypeSrc = inst->aio_ToolTypes; + STRPTR *ToolTypeDest; + + instClone->aio_ToolTypes = instClone->aio_DiskObject->do_ToolTypes = (STRPTR *) MyAllocVecPooled(inst->aio_ToolTypesLength); + if (NULL == instClone->aio_DiskObject->do_ToolTypes) + break; + + d1(KPrintF("%s/%s/%ld: do_ToolTypes=%08lx\n", __FILE__, __FUNC__, __LINE__, instClone->aio_DiskObject->do_ToolTypes)); + + ToolTypeDest = instClone->aio_ToolTypes; + + while (*ToolTypeSrc) + { + d1(KPrintF("%s/%s/%ld: *ToolTypePtr=<%s>\n", __FILE__, __FUNC__, __LINE__, *ToolTypeSrc)); + *ToolTypeDest = MyAllocVecPooled(1 + strlen(*ToolTypeSrc)); + if (NULL == *ToolTypeDest) + break; + + strcpy(*ToolTypeDest, *ToolTypeSrc); + + ToolTypeSrc++; + ToolTypeDest++; + } + *ToolTypeDest = NULL; + } + if (inst->aio_DiskObject) + { + // Clone DiskObject + instClone->aio_DiskObject = MyAllocVecPooled(sizeof(struct DiskObject)); + d1(KPrintF("%s/%s/%ld: o=%08lx aio_DiskObject=%08lx\n", __FILE__, __FUNC__, __LINE__, o, instClone->aio_DiskObject)); + if (NULL == instClone->aio_DiskObject) + break; + + *(instClone->aio_DiskObject) = *(inst->aio_DiskObject); + } + + // Clone aio_DoImage1 + instClone->aio_DiskObject->do_Gadget.GadgetRender = DoCloneDoImage(&instClone->aio_DoImage1, &inst->aio_DoImage1); + + // Clone aio_DoImage2 + instClone->aio_DiskObject->do_Gadget.SelectRender = DoCloneDoImage(&instClone->aio_DoImage2, &inst->aio_DoImage2); + + // Clone Normal Image Pen list + if (!DoClonePenList(inst->aio_Screen, &instClone->aio_PenList1, &inst->aio_PenList1)) + break; + // Clone Selected Image Pen list + if (!DoClonePenList(inst->aio_Screen, &instClone->aio_PenList2, &inst->aio_PenList2)) + break; + + if (!CloneNewImage(&instClone->aio_Image1, inst->aio_Image1)) + break; + if (!CloneNewImage(&instClone->aio_Image2, inst->aio_Image2)) + break; + + SetAttrsA(oClone, iocio->iocio_TagList); + + SetParentAttributes(cl, oClone); + + d1(KPrintF("%s/%s/%ld: Width=%ld Height=%ld\n", __FILE__, __FUNC__, __LINE__, gg->Width, gg->Height)); + + d1(KPrintF("%s/%s/%ld: NrmARGBImage=%08lx argb_ImageData=%08lx w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \ + NrmARGBImage, NrmARGBImage->argb_ImageData, NrmARGBImage->argb_Width, NrmARGBImage->argb_Height)); + d1(KPrintF("%s/%s/%ld: SelARGBImage=%08lx argb_ImageData=%08lx w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \ + SelARGBImage, SelARGBImage->argb_ImageData, SelARGBImage->argb_Width, SelARGBImage->argb_Height)); + + GetAttr(IDTA_ARGBImageData, o, (APTR) &NrmARGBImage); + GetAttr(IDTA_SelARGBImageData, o, (APTR) &SelARGBImage); + + d1(KPrintF("%s/%s/%ld: NrmARGBImage=%08lx argb_ImageData=%08lx w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \ + NrmARGBImage, NrmARGBImage->argb_ImageData, NrmARGBImage->argb_Width, NrmARGBImage->argb_Height)); + d1(KPrintF("%s/%s/%ld: SelARGBImage=%08lx argb_ImageData=%08lx w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \ + SelARGBImage, SelARGBImage->argb_ImageData, SelARGBImage->argb_Width, SelARGBImage->argb_Height)); + + // clone size of original icon + SetAttrs(oClone, + GA_Width, gg->Width, + GA_Height, gg->Height, + TAG_END); + + if (NrmARGBImage != &inst->aio_Image1->nim_ARGBheader + && NrmARGBImage->argb_ImageData + && NrmARGBImage->argb_Width > 0 + && NrmARGBImage->argb_Height ) + { + if ((NrmARGBImage->argb_Width > gg->Width) || (NrmARGBImage->argb_Height > gg->Height)) + { + SetAttrs(oClone, + GA_Width, NrmARGBImage->argb_Width, + GA_Height, NrmARGBImage->argb_Height, + TAG_END); + } + // IDTA_ARGBImageData has been changed, clone it now! + SetAttrs(oClone, + IDTA_CopyARGBImageData, TRUE, + IDTA_ARGBImageData, (APTR) NrmARGBImage, + TAG_END); + } + + d1(KPrintF("%s/%s/%ld: NrmARGBImage=%08lx nim_ARGBheader=%08lx\n", __FILE__, __FUNC__, __LINE__, &inst->aio_Image1->nim_ARGBheader)); + if (SelARGBImage != &inst->aio_Image2->nim_ARGBheader + && SelARGBImage->argb_ImageData + && SelARGBImage->argb_Width > 0 + && SelARGBImage->argb_Height ) + { + if ((SelARGBImage->argb_Width > gg->Width) || (SelARGBImage->argb_Height > gg->Height)) + { + SetAttrs(oClone, + GA_Width, SelARGBImage->argb_Width, + GA_Height, SelARGBImage->argb_Height, + TAG_END); + } + // IDTA_SelARGBImageData has been changed, clone it now! + SetAttrs(oClone, + IDTA_CopySelARGBImageData, TRUE, + IDTA_SelARGBImageData, (APTR) SelARGBImage, + TAG_END); + } + + Success = TRUE; + } while (0); + + if (oClone && !Success) + { + DoMethod(oClone, OM_DISPOSE); + oClone = NULL; + } + + d1(KPrintF("%s/%ld: END o=%08lx inst=%08lx oClone=%08lx\n", __FUNC__, __LINE__, o, inst, oClone)); + + return (ULONG) oClone; +} + +//----------------------------------------------------------------------------- + +static BOOL DoClonePenList(struct Screen *scr, struct NewImagePenList *nipDest, + const struct NewImagePenList *nipSrc) +{ + BOOL Success = FALSE; + + if (nipSrc->nip_PenArray) + { + do { + const UBYTE *PenArraySrc = nipSrc->nip_PenArray; + UBYTE *PenArrayDest; + ULONG n; + + nipDest->nip_PenArray = MyAllocVecPooled(nipDest->nip_PaletteSize); + if (NULL == nipDest->nip_PenArray) + break; + + memcpy(nipDest->nip_PenArray, nipSrc->nip_PenArray, nipDest->nip_PaletteSize); + + PenArrayDest = nipDest->nip_PenArray; + for (n = 0; n < nipDest->nip_PaletteSize; n++) + { + *PenArrayDest++ = ObtainPen(scr->ViewPort.ColorMap, + *PenArraySrc++, + 0, 0, 0, + PEN_NO_SETCOLOR); + } + + Success = TRUE; + } while (0); + } + else + { + Success = TRUE; + } + + return Success; +} + +//----------------------------------------------------------------------------- + +static struct Image *DoCloneDoImage(struct Image *imgDest, const struct Image *imgSrc) +{ + if (imgSrc->ImageData) + { + do { + size_t len = RASSIZE(imgDest->Width, imgDest->Height) * imgDest->Depth; + + imgDest->ImageData = MyAllocVecPooled(len); + if (NULL == imgDest->ImageData) + break; + + memcpy(imgDest->ImageData, imgSrc->ImageData, len); + + return imgDest; + } while (0); + } + + return NULL; +} + +//----------------------------------------------------------------------------- + +static void DoUpdateWb(CONST_STRPTR SavePath) +{ + BPTR fLock; + BPTR pLock = (BPTR)NULL; + + do { + CONST_STRPTR fName; + + fLock = Lock(SavePath, ACCESS_READ); + if ((BPTR)NULL == fLock) + break; + + pLock = ParentDir(fLock); + if ((BPTR)NULL == pLock) + break; + + fName = FilePart(SavePath); + + UpdateWorkbench(fName, pLock, UPDATEWB_ObjectAdded); + } while (0); + + if (pLock) + UnLock(pLock); + if (fLock) + UnLock(fLock); +} + +//---------------------------------------------------------------------------------------- + +static void FreePenList(struct Screen *screen, struct NewImagePenList *PenList) +{ + UBYTE *PenArray = PenList->nip_PenArray; + + while (PenList->nip_PaletteSize--) + { + ReleasePen(screen->ViewPort.ColorMap, *PenArray++); + } + + MyFreeVecPooled(PenList->nip_PenArray); + PenList->nip_PenArray = NULL; +} + +//---------------------------------------------------------------------------------------- + +static void INLINE WriteARGBArray(const struct ARGB *SrcImgData, + ULONG SrcX, ULONG SrcY, ULONG SrcBytesPerRow, + struct RastPort *DestRp, ULONG DestX, ULONG DestY, + ULONG SizeX, ULONG SizeY) +{ + struct BitMap *DestBM = DestRp->BitMap; + ULONG DestWidth; + ULONG DestHeight; + + DestWidth = GetCyberMapAttr(DestBM, CYBRMATTR_WIDTH); + DestHeight = GetCyberMapAttr(DestBM, CYBRMATTR_HEIGHT); + + d1(KPrintF("%s/%s/%ld: DestX=%ld DestY=%ld SizeX=%ld SizeY=%ld\n", __FILE__, __FUNC__, __LINE__, DestX, DestY, SizeX, SizeY)); + + if (DestX + SizeX > DestWidth) + SizeX = DestWidth - DestX; + if (DestY + SizeY > DestHeight) + SizeY = DestHeight - DestY; + + d1(KPrintF("%s/%s/%ld: DestX=%ld DestY=%ld SizeX=%ld SizeY=%ld\n", __FILE__, __FUNC__, __LINE__, DestX, DestY, SizeX, SizeY)); + + WritePixelArray((APTR) SrcImgData, SrcX, SrcY, + SrcBytesPerRow, + DestRp, DestX, DestY, + SizeX, SizeY, + RECTFMT_ARGB); +} + +//---------------------------------------------------------------------------------------- + +// True color +static BOOL INLINE DrawTrueColorImage(struct RastPort *rp, struct NewImage *img, + UWORD Left, UWORD Top, const struct ColorRegister *Palette, + BOOL DimmedImage) +{ + struct ARGB *ARGBImgArray; + BOOL Success = FALSE; + + d1(kprintf("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__)); + + do { + ULONG BmWidth, BmHeight; + ULONG Width, Height; + const struct ColorRegister *PalettePtr; + size_t ARGBImgSize; + struct ARGB *ARGBImgDestPtr; + UBYTE *ImgSrcPtr; + ULONG n; + ULONG ImgSize; + + BmWidth = GetBitMapAttr(rp->BitMap, BMA_WIDTH); + BmHeight = GetBitMapAttr(rp->BitMap, BMA_HEIGHT); + + Width = min(img->nim_Width, BmWidth - Left); + Height = min(img->nim_Height, BmHeight - Top); + + ImgSize = img->nim_Width * img->nim_Height; + ARGBImgSize = ImgSize * sizeof(struct ARGB); + + ARGBImgArray = MyAllocVecPooled(ARGBImgSize); + d1(KPrintF("%s/%s/%ld: ARGBImgArray=%08lx\n", __FILE__, __FUNC__, __LINE__, ARGBImgArray)); + if (NULL == ARGBImgArray) + break; + + ImgSrcPtr = img->nim_ImageData; + ARGBImgDestPtr = ARGBImgArray; + PalettePtr = Palette; + + if (DimmedImage) + { + for (n = 0; n < ImgSize; n++, ARGBImgDestPtr++) + { + const struct ColorRegister *PaletteEntry; + + PaletteEntry = &PalettePtr[*ImgSrcPtr++]; + ARGBImgDestPtr->Alpha = 0xff; + ARGBImgDestPtr->Red = PaletteEntry->red / 2; + ARGBImgDestPtr->Green = PaletteEntry->green / 2; + ARGBImgDestPtr->Blue = PaletteEntry->blue / 2; + } + } + else + { + for (n = 0; n < ImgSize; n++, ARGBImgDestPtr++) + { + const struct ColorRegister *PaletteEntry; + + PaletteEntry = &PalettePtr[*ImgSrcPtr++]; + ARGBImgDestPtr->Alpha = 0xff; + ARGBImgDestPtr->Red = PaletteEntry->red; + ARGBImgDestPtr->Green = PaletteEntry->green; + ARGBImgDestPtr->Blue = PaletteEntry->blue; + } + } + + WriteARGBArray(ARGBImgArray, 0, 0, + img->nim_Width * sizeof(struct ARGB), + rp, Left, Top, + Width, Height); + + Success = TRUE; + } while (0); + + if (ARGBImgArray) + MyFreeVecPooled(ARGBImgArray); + + return Success; +} + +//---------------------------------------------------------------------------------------- + +static BOOL INLINE DrawRemappedImage(struct InstanceData *inst, struct RastPort *rp, + struct NewImagePenList *PenList, struct NewImage *img, + UWORD Left, UWORD Top, const struct ColorRegister *Palette, ULONG PaletteSize, + BOOL DimmedImage) +{ + UBYTE *MappedImage = NULL; + BOOL Success = FALSE; + + d1(kprintf("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__)); + + do { + const struct ColorRegister *PalettePtr; + UBYTE *PenListPtr; + UBYTE *ImgPtr; + UBYTE *ImgDestPtr; + ULONG Remainder; + ULONG n; + ULONG y; + + PenList->nip_PenArray = MyAllocVecPooled(PaletteSize); + if (NULL == PenList->nip_PenArray) + break; + + PalettePtr = Palette; + PenListPtr = PenList->nip_PenArray; + for (n = 0; n < PaletteSize; n++) + { + if (DimmedImage) + { + *PenListPtr++ = ObtainBestPenA(inst->aio_Screen->ViewPort.ColorMap, + PalettePtr->red << 23, + PalettePtr->green << 23, + PalettePtr->blue << 23, + NULL); + } + else + { + *PenListPtr++ = ObtainBestPenA(inst->aio_Screen->ViewPort.ColorMap, + PalettePtr->red << 24, + PalettePtr->green << 24, + PalettePtr->blue << 24, + NULL); + } + PalettePtr++; + } + + MappedImage = MyAllocVecPooled(img->nim_Height * ((img->nim_Width + 15) & 0xfff0)); + if (NULL == MappedImage) + break; + + Remainder = ((img->nim_Width + 15) & 0xfff0) - img->nim_Width; + ImgPtr = img->nim_ImageData; + ImgDestPtr = MappedImage; + for (y = 0; y < img->nim_Height; y++) + { + ULONG x; + + for (x = 0; x < img->nim_Width; x++) + { + *ImgDestPtr++ = PenList->nip_PenArray[*ImgPtr++]; + } + ImgDestPtr += Remainder; + } + + if (CyberGfxBase && GetCyberMapAttr(rp->BitMap, CYBRMATTR_ISCYBERGFX)) + { + WritePixelArray(MappedImage, 0, 0, + (img->nim_Width + 15) & 0xfff0, + rp, Left, Top, + img->nim_Width, img->nim_Height, + RECTFMT_LUT8); + } + else + { + struct RastPort rpTemp; + + InitRastPort(&rpTemp); + rpTemp.BitMap = AllocBitMap((img->nim_Width + 15) & 0xfff0, + img->nim_Height, 8, 0, rp->BitMap); + if (NULL == rpTemp.BitMap) + break; + + WritePixelArray8(rp, Left, Top, + Left + img->nim_Width - 1, + Top + img->nim_Height - 1, + MappedImage, &rpTemp); + + FreeBitMap(rpTemp.BitMap); + } + + Success = TRUE; + } while (0); + + if (MappedImage) + MyFreeVecPooled(MappedImage); + + return Success; +} + +//----------------------------------------------------------------------------- + +static void DrawColorImage(struct InstanceData *inst, struct RastPort *rp, + struct NewImagePenList *PenList, struct NewImage *img, + UWORD Left, UWORD Top, const struct ColorRegister *Palette, ULONG PaletteSize, + BOOL DimmedImage) +{ + BOOL Success; + + d1(kprintf("%s/%s/%ld: PaletteSize=%lu Palette=%08lx\n", __FILE__, __FUNC__, __LINE__, img->nim_PaletteSize, Palette)); + + if (PenList->nip_PenArray) + { + MyFreeVecPooled(PenList->nip_PenArray); + PenList->nip_PenArray = NULL; + } + + PenList->nip_PaletteSize = PaletteSize; + + if (CyberGfxBase && (GetBitMapAttr(rp->BitMap, BMA_DEPTH) > 8)) + { + Success = DrawTrueColorImage(rp, img, Left, Top, Palette, DimmedImage); + } + else + { + d1(KPrintF("%s/%s/%ld: CyberGfxBase=%08lx BMA_DEPTH=%ld\n", __FILE__, __FUNC__, __LINE__, CyberGfxBase, GetBitMapAttr(rp->BitMap, BMA_DEPTH))); + Success = DrawRemappedImage(inst, rp, PenList, img, + Left, Top, Palette, PaletteSize, DimmedImage); + } + + if (!Success && PenList->nip_PenArray) + { + MyFreeVecPooled(PenList->nip_PenArray); + PenList->nip_PenArray = NULL; + } +} + +//---------------------------------------------------------------------------------------- + +static void ReadIcon(struct InstanceData *inst, CONST_STRPTR Filename, BPTR IconFh) +{ + static const LONG StopChunkList[] = + { + ID_ICON, ID_FACE, + ID_ICON, ID_IMAG, + ID_ICON, ID_ARGB, + }; + STRPTR IconInfoName; // full filename of icon (including ".info") + BPTR fd = BNULL; + struct IFFHandle *iff = NULL; + BOOL iffOpened = FALSE; + + do { + BOOL FaceChunkOk = FALSE; + BOOL Image1Ok = FALSE; + LONG Result; + + IconInfoName = MyAllocVecPooled(1 + strlen(Filename) + strlen(".info")); + if (NULL == IconInfoName) + break; + + strcpy(IconInfoName, Filename); + strcat(IconInfoName, ".info"); + + if (IconFh) + fd = IconFh; + else + fd = Open(IconInfoName, MODE_OLDFILE); + d1(kprintf("%s/%s/%ld: fd=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, fd, IconInfoName)); + if (BNULL == fd) + break; + + if (!ReadStandardIcon(inst, fd)) + break; + + // ---- End of standard icon data ------------------ + + iff = AllocIFF(); + d1(kprintf(__FILE__ "/" "%s/%s/%ld: AlloCIFF Result=%ld\n", __FILE__, __FUNC__, __LINE__, IoErr())); + if (NULL == iff) + break; + + InitIFF(iff, IFFF_RSEEK | IFFF_READ, &StreamHook); + iff->iff_Stream = (IPTR)fd; + + Result = OpenIFF(iff, IFFF_READ); + d1(kprintf(__FILE__ "/" "%s/%s/%ld: OpenIFF Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + if (RETURN_OK != Result) + break; + + iffOpened = TRUE; + + Result = StopChunks(iff, StopChunkList, Sizeof(StopChunkList) / 2); + d1(kprintf(__FILE__ "/" "%s/%s/%ld: StopChunks Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + if (RETURN_OK != Result) + break; + + while (1) + { + struct ContextNode *cn; + + Result = ParseIFF(iff, IFFPARSE_SCAN); + if (RETURN_OK != Result) + { + d1(kprintf(__FILE__ "/" "%s/%s/%ld: ParseIFF Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + break; + } + + cn = CurrentChunk(iff); + + if (ID_FACE == cn->cn_ID) + { + LONG Actual; + + d1(kprintf("%s/%s/%ld: FACE Chunk len=%lu\n", __FILE__, __FUNC__, __LINE__, cn->cn_Size)); + if (cn->cn_Size != sizeof(struct FaceChunk)) + break; + + Actual = ReadChunkBytes(iff, &inst->aio_FaceChunk, sizeof(inst->aio_FaceChunk)); + if (Actual != sizeof(inst->aio_FaceChunk)) + break; + + inst->aio_FaceChunk.fc_MaxPaletteBytes = SCA_BE2WORD(inst->aio_FaceChunk.fc_MaxPaletteBytes); + + d1(kprintf("%s/%s/%ld: FACE id read OK.\n", __FILE__, __FUNC__, __LINE__)); + + d1(kprintf("%s/%s/%ld: FACE Width=%ld Height=%ld Aspect=%02lx Flags=%02lx MaxPaletteBytes=%lu\n", \ + __FILE__, __FUNC__, __LINE__, \ + inst->aio_FaceChunk.fc_Width+1, inst->aio_FaceChunk.fc_Height+1,\ + inst->aio_FaceChunk.fc_AspectRatio,\ + inst->aio_FaceChunk.fc_Flags,\ + inst->aio_FaceChunk.fc_MaxPaletteBytes)); + + inst->aio_Borderless = inst->aio_FaceChunk.fc_Flags & FCF_Borderless; + + FaceChunkOk = TRUE; + } + else if (ID_IMAG == cn->cn_ID && cn->cn_Size >= sizeof(struct ImageChunk) && FaceChunkOk) + { + d1(KPrintF("%s/%s/%ld: IMAG Chunk len=%lu\n", __FILE__, __FUNC__, __LINE__, cn->cn_Size)); + + if (Image1Ok) + { + inst->aio_Image2 = ReadNewImage(iff, &inst->aio_FaceChunk); + if (NULL == inst->aio_Image2) + break; + + d1(kprintf("%s/%s/%ld: Image 2 read Ok.\n", __FILE__, __FUNC__, __LINE__)); + } + else + { + inst->aio_Image1 = ReadNewImage(iff, &inst->aio_FaceChunk); + if (NULL == inst->aio_Image1) + break; + + d1(kprintf("%s/%s/%ld: Image 1 read Ok.\n", __FILE__, __FUNC__, __LINE__)); + Image1Ok = TRUE; + } + } + else if (ID_ARGB == cn->cn_ID && cn->cn_Size >= sizeof(struct ImageChunk) && FaceChunkOk) + { + d1(KPrintF("%s/%s/%ld: ARGB Chunk len=%lu\n", __FILE__, __FUNC__, __LINE__, cn->cn_Size)); + + if (Image1Ok) + { + inst->aio_Image2 = ReadARGBImage(iff, &inst->aio_FaceChunk); + if (NULL == inst->aio_Image2) + break; + + d1(KPrintF("%s/%s/%ld: Image 2 read Ok.\n", __FILE__, __FUNC__, __LINE__)); + } + else + { + inst->aio_Image1 = ReadARGBImage(iff, &inst->aio_FaceChunk); + if (NULL == inst->aio_Image1) + break; + + d1(KPrintF("%s/%s/%ld: Image 1 read Ok.\n", __FILE__, __FUNC__, __LINE__)); + Image1Ok = TRUE; + } + } + } + } while (0); + + if (iff) + { + if (iffOpened) + CloseIFF(iff); + + FreeIFF(iff); + } + if (fd && (BNULL == IconFh)) + Close(fd); + + if (IconInfoName) + MyFreeVecPooled(IconInfoName); +} + +//---------------------------------------------------------------------------------------- + +static BOOL WriteIcon(Class *cl, Object *o, + const struct DiskObject *WriteDiskObject, CONST_STRPTR Filename) +{ + struct InstanceData *inst = INST_DATA(cl, o); + STRPTR IconInfoName; // full filename of icon (including ".info") + BPTR fd = (BPTR)NULL; + struct IFFHandle *iff = NULL; + BOOL iffOpened = FALSE; + BOOL Success = FALSE; + + d1(KPrintF("%s/%s/%ld: START <%s>\n", __FILE__, __FUNC__, __LINE__, Filename)); + + do { + UWORD PaletteSize; + struct FaceChunk fc; + LONG Result; + + IconInfoName = MyAllocVecPooled(1 + strlen(Filename) + strlen(".info")); + if (NULL == IconInfoName) + { + SetIoErr(ERROR_NO_FREE_STORE); + break; + } + + strcpy(IconInfoName, Filename); + strcat(IconInfoName, ".info"); + + fd = Open(IconInfoName, MODE_NEWFILE); + d1(kprintf("%s/%s/%ld: fd=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, fd, IconInfoName)); + if ((BPTR)NULL == fd) + break; + + if (!WriteStandardIcon(inst, WriteDiskObject, fd)) + break; + + // ---- End of standard icon data ------------------ + + iff = AllocIFF(); + d1(kprintf(__FILE__ "/" "%s/%s/%ld: AlloCIFF Result=%ld\n", __FILE__, __FUNC__, __LINE__, IoErr())); + if (NULL == iff) + break; + + InitIFF(iff, IFFF_RSEEK | IFFF_WRITE, &StreamHook); + iff->iff_Stream = (IPTR)fd; + + Result = OpenIFF(iff, IFFF_WRITE); + d1(kprintf(__FILE__ "/" "%s/%s/%ld: OpenIFF Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + if (RETURN_OK != Result) + break; + + iffOpened = TRUE; + + Result = PushChunk(iff, ID_ICON, ID_FORM, IFFSIZE_UNKNOWN); + d1(KPrintF(__FILE__ "/" "%s/%s/%ld: PushChunk(ID_FORM) Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + if (RETURN_OK != Result) + break; + + Result = PushChunk(iff, ID_ICON, ID_FACE, sizeof(struct FaceChunk)); + d1(KPrintF(__FILE__ "/" "%s/%s/%ld: PushChunk(ID_FACE) Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + if (RETURN_OK != Result) + break; + + fc = inst->aio_FaceChunk; + + if (NULL == inst->aio_Image1->nim_Palette) + { + // make sure FaceChunk has correct size for ARGB image + struct ARGBHeader *argbh = NULL; + + GetAttr(IDTA_ARGBImageData, o, (APTR) &argbh); + if (argbh && argbh->argb_ImageData) + { + fc.fc_Width = argbh->argb_Width - 1; + fc.fc_Height = argbh->argb_Height - 1; + } + } + + PaletteSize = inst->aio_Image1->nim_PaletteSize; + + if (inst->aio_Image2 && inst->aio_Image2->nim_PaletteSize) + { + if (inst->aio_Image2->nim_PaletteSize > PaletteSize) + { + PaletteSize = inst->aio_Image2->nim_PaletteSize; + } + } + + PaletteSize = PaletteSize * 3 - 1; + fc.fc_MaxPaletteBytes = PaletteSize * sizeof(struct ColorRegister) - 1; + + fc.fc_MaxPaletteBytes = SCA_WORD2BE(fc.fc_MaxPaletteBytes); + + if (sizeof(struct FaceChunk) != WriteChunkBytes(iff, + &fc, sizeof(struct FaceChunk))) + break; + + Result = PopChunk(iff); // ID_FACE + d1(KPrintF(__FILE__ "/" "%s/%s/%ld: PopChunk Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + if (RETURN_OK != Result) + break; + + d1(KPrintF(__FILE__ "/" "%s/%s/%ld: nim_Palette=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->aio_Image1->nim_Palette)); + if (inst->aio_Image1->nim_Palette) + Result = WriteNewImage(iff, inst->aio_Image1); + else + Result = WriteARGBImage(cl, o, iff, inst->aio_Image1, IDTA_ARGBImageData); + d1(KPrintF(__FILE__ "/" "%s/%s/%ld: WriteNewImage(1) Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + if (RETURN_OK != Result) + break; + + if (inst->aio_Image2) + { + if (inst->aio_Image1->nim_Palette) + Result = WriteNewImage(iff, inst->aio_Image2); + else + Result = WriteARGBImage(cl, o, iff, inst->aio_Image2, IDTA_SelARGBImageData); + d1(KPrintF(__FILE__ "/" "%s/%s/%ld: WriteNewImage(2)Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + if (RETURN_OK != Result) + break; + } + + Result = PopChunk(iff); // ID_ICON + d1(KPrintF(__FILE__ "/" "%s/%s/%ld: PopChunk Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + if (RETURN_OK != Result) + break; + + Success = TRUE; + } while (0); + + if (iff) + { + if (iffOpened) + CloseIFF(iff); + + FreeIFF(iff); + } + if (fd) + Close(fd); + if (IconInfoName) + MyFreeVecPooled(IconInfoName); + + d1(KPrintF(__FILE__ "/" "%s/%s/%ld: END Success=%ld\n", __FILE__, __FUNC__, __LINE__, Success)); + + return Success; +} + +//---------------------------------------------------------------------------------------- + +static BOOL ReadStandardIcon(struct InstanceData *inst, BPTR fd) +{ + BOOL Success = FALSE; + + do { + UWORD FileFormatRevision; + ULONG len; + + inst->aio_DiskObject = MyAllocVecPooled(sizeof(struct DiskObject)); + if (NULL == inst->aio_DiskObject) + break; + +#if defined(__AROS__) + if (!ReadConvertStandardIcon(fd, inst->aio_DiskObject)) + break; +#else + if (sizeof(struct DiskObject) != FRead(fd, inst->aio_DiskObject, 1, sizeof(struct DiskObject))) + break; +#endif + + d1(kprintf("%s/%s/%ld: DiskObject read Ok, size=%ld.\n", __FILE__, __FUNC__, __LINE__, sizeof(struct DiskObject))); + + FileFormatRevision = ((ULONG) inst->aio_DiskObject->do_Gadget.UserData) & WB_DISKREVISIONMASK; + + d1(kprintf("%s/%s/%ld: do_Magic=%04lx Version=%04lx\n", __FILE__, __FUNC__, __LINE__, inst->aio_DiskObject->do_Magic, inst->aio_DiskObject->do_Version)); + + if (inst->aio_DiskObject->do_Magic == WB_DISKMAGIC) + { + d1(kprintf("%s/%s/%ld: do_Magic = %04lx Version=%ld Revision=%ld\n", __FILE__, __FUNC__, __LINE__,\ + inst->aio_DiskObject->do_Magic, inst->aio_DiskObject->do_Version, FileFormatRevision)); + } + else + break; + + d1(kprintf("%s/%s/%ld: File Position = %ld\n", __FILE__, __FUNC__, __LINE__, Seek(fd, 0, OFFSET_CURRENT))); + d1(kprintf("%s/%s/%ld: DrawerData = %08lx\n", __FILE__, __FUNC__, __LINE__, inst->aio_DiskObject->do_DrawerData)); + + if (inst->aio_DiskObject->do_DrawerData) + { + inst->aio_DiskObject->do_DrawerData = NULL; + + d1(kprintf("%s/%s/%ld: old-drawerdata expected, size=%ld.\n", __FILE__, __FUNC__, __LINE__, OLDDRAWERDATAFILESIZE)); + + inst->aio_DiskObject->do_DrawerData = inst->aio_myDrawerData = MyAllocVecPooled(sizeof(struct DrawerData)); + if (NULL == inst->aio_myDrawerData) + break; + +#if defined(__AROS__) + if (!ReadConvertDrawerData(fd, inst->aio_myDrawerData)) + break; +#else + if (OLDDRAWERDATAFILESIZE != FRead(fd, inst->aio_myDrawerData, 1, OLDDRAWERDATAFILESIZE)) + break; +#endif + + d1(kprintf("%s/%s/%ld: OldDrawerData read Ok.\n", __FILE__, __FUNC__, __LINE__)); + } + + d1(kprintf("%s/%s/%ld: Image 1 expected, size=%ld\n", __FILE__, __FUNC__, __LINE__, sizeof(inst->aio_DoImage1))); + +#if defined(__AROS__) + if (!ReadConvertImage(fd, &inst->aio_DoImage1)) + break; +#else + if (sizeof(inst->aio_DoImage1) != FRead(fd, &inst->aio_DoImage1, 1, sizeof(inst->aio_DoImage1))) + break; +#endif + + d1(kprintf("%s/%s/%ld: Image 1 read Ok.\n", __FILE__, __FUNC__, __LINE__)); + + d1(kprintf("%s/%s/%ld: Image 1: Left=%d Top=%d Width=%d Height=%d Depth=%d\n", \ + __FILE__, __FUNC__, __LINE__, \ + inst->aio_DoImage1.LeftEdge, inst->aio_DoImage1.TopEdge, \ + inst->aio_DoImage1.Width, inst->aio_DoImage1.Height, inst->aio_DoImage1.Depth)); + + len = RASSIZE(inst->aio_DoImage1.Width, inst->aio_DoImage1.Height) * inst->aio_DoImage1.Depth; + + d1(kprintf("%s/%s/%ld: ImageData 1 expected, size=%ld\n", __FILE__, __FUNC__, __LINE__, len)); + + inst->aio_DiskObject->do_Gadget.GadgetRender = &inst->aio_DoImage1; + + inst->aio_DoImage1.ImageData = MyAllocVecPooled(len); + if (NULL == inst->aio_DoImage1.ImageData) + break; + + if (len != FRead(fd, inst->aio_DoImage1.ImageData, 1, len)) + break; + + d1(kprintf("%s/%s/%ld: ImageData 1 skipped Ok.\n", __FILE__, __FUNC__, __LINE__)); + + inst->aio_DiskObject->do_Gadget.GadgetRender = &inst->aio_DoImage1; + + d1(kprintf("%s/%s/%ld: Gadget Flags = %08lx\n", __FILE__, __FUNC__, __LINE__, inst->aio_DiskObject->do_Gadget.Flags)); + + if (GFLG_GADGHIMAGE & inst->aio_DiskObject->do_Gadget.Flags) + { + d1(kprintf("%s/%s/%ld: Image 2 expected, size=%ld\n", __FILE__, __FUNC__, __LINE__, sizeof(inst->aio_DoImage2))); + + +#if defined(__AROS__) + if (!ReadConvertImage(fd, &inst->aio_DoImage2)) + break; +#else + if (sizeof(inst->aio_DoImage2) != FRead(fd, &inst->aio_DoImage2, 1, sizeof(inst->aio_DoImage2))) + break; +#endif + + d1(kprintf("%s/%s/%ld: Image 2 read Ok.\n", __FILE__, __FUNC__, __LINE__)); + + inst->aio_DiskObject->do_Gadget.SelectRender = &inst->aio_DoImage2; + + d1(kprintf("%s/%s/%ld: Image 2: Left=%d Top=%d Width=%d Height=%d Depth=%d\n", \ + __FILE__, __FUNC__, __LINE__, \ + inst->aio_DoImage2.LeftEdge, inst->aio_DoImage2.TopEdge, \ + inst->aio_DoImage2.Width, inst->aio_DoImage2.Height, inst->aio_DoImage2.Depth)); + + len = RASSIZE(inst->aio_DoImage2.Width, inst->aio_DoImage2.Height) * inst->aio_DoImage2.Depth; + + d1(kprintf("%s/%s/%ld: ImageData 2 expected, size=%ld\n", __FILE__, __FUNC__, __LINE__, len)); + + inst->aio_DoImage2.ImageData = MyAllocVecPooled(len); + if (NULL == inst->aio_DoImage2.ImageData) + break; + + if (len != FRead(fd, inst->aio_DoImage2.ImageData, 1, len)) + break; + + d1(kprintf("%s/%s/%ld: ImageData 2 read Ok.\n", __FILE__, __FUNC__, __LINE__)); + } + else + { + inst->aio_DiskObject->do_Gadget.SelectRender = NULL; + d1(kprintf("%s/%s/%ld: No alternate image.\n", __FILE__, __FUNC__, __LINE__)); + } + + if (inst->aio_DiskObject->do_DefaultTool) + { + inst->aio_DiskObject->do_DefaultTool = NULL; + + d1(kprintf("%s/%s/%ld: DefaultTool Length expected.\n", __FILE__, __FUNC__, __LINE__)); + if (sizeof(len) != FRead(fd, &len, 1, sizeof(len))) + break; + + len = SCA_BE2LONG(len); + + d1(kprintf("%s/%s/%ld: DefaultTool length read Ok, length=%lu.\n", __FILE__, __FUNC__, __LINE__, len)); + + if (len) + { + inst->aio_DefaultTool = inst->aio_DiskObject->do_DefaultTool = MyAllocVecPooled(len); + if (NULL == inst->aio_DiskObject->do_DefaultTool) + break; + + if (len != FRead(fd, inst->aio_DiskObject->do_DefaultTool, 1, len)) + break; + + d1(kprintf("%s/%s/%ld: DefaultTool read Ok, <%s>.\n", \ + __FILE__, __FUNC__, __LINE__, inst->aio_DiskObject->do_DefaultTool)); + } + } + else + { + d1(kprintf("%s/%s/%ld: No Default Tool.\n", __FILE__, __FUNC__, __LINE__)); + } + + if (inst->aio_DiskObject->do_ToolTypes) + { + inst->aio_DiskObject->do_ToolTypes = NULL; + + d1(kprintf("%s/%s/%ld: Expecting size of ToolTypes Array.\n", __FILE__, __FUNC__, __LINE__)); + if (sizeof(len) != FRead(fd, &len, 1, sizeof(len))) + break; + + len = SCA_BE2LONG(len); + + d1(KPrintF("%s/%s/%ld: Size of ToolTypes Array read Ok, %lu.\n", __FILE__, __FUNC__, __LINE__, len)); + inst->aio_ToolTypesLength = len; + if (len) + { + short n; + + inst->aio_ToolTypes = inst->aio_DiskObject->do_ToolTypes = (STRPTR *) MyAllocVecPooled(len); + if (NULL == inst->aio_DiskObject->do_ToolTypes) + break; + + memset(inst->aio_DiskObject->do_ToolTypes, 0, len); + + for (n=0; n<(len-1)/sizeof(STRPTR); n++) + { + ULONG sLen; + + if (sizeof(sLen) != FRead(fd, &sLen, 1, sizeof(sLen))) + break; + + sLen = SCA_BE2LONG(sLen); + + inst->aio_DiskObject->do_ToolTypes[n] = MyAllocVecPooled(sLen); + if (inst->aio_DiskObject->do_ToolTypes[n]) + FRead(fd, inst->aio_DiskObject->do_ToolTypes[n], 1, sLen); + else + Seek(fd, sLen, OFFSET_CURRENT); + + d1(kprintf("%s/%s/%ld: Read ToolType #%ld, len=%ld val=<%s>\n", \ + __FILE__, __FUNC__, __LINE__, n, sLen, inst->aio_DiskObject->do_ToolTypes[n])); + } + } + } + else + d1(kprintf("%s/%s/%ld: No ToolTypes.\n", __FILE__, __FUNC__, __LINE__)); + + if (inst->aio_DiskObject->do_ToolWindow) + { + inst->aio_DiskObject->do_ToolWindow = NULL; + + d1(kprintf("%s/%s/%ld: ToolWindow expected.\n", __FILE__, __FUNC__, __LINE__)); + + if (sizeof(len) != FRead(fd, &len, 1, sizeof(len))) + break; + + len = SCA_BE2LONG(len); + + inst->aio_ToolWindow = inst->aio_DiskObject->do_ToolWindow = MyAllocVecPooled(len); + if (NULL == inst->aio_DiskObject->do_ToolWindow) + break; + + if (len != FRead(fd, inst->aio_DiskObject->do_ToolWindow, 1, len)) + break; + + d1(kprintf("%s/%s/%ld: ToolWindow read ok, len=%ld\n", __FILE__, __FUNC__, __LINE__, len)); + } + else + d1(kprintf("%s/%s/%ld: No ToolWindow.\n", __FILE__, __FUNC__, __LINE__)); + + if (inst->aio_DiskObject->do_DrawerData && FileFormatRevision > 0 && FileFormatRevision <= WB_DISKREVISION) + { + UBYTE *RemainingDrawerData = ((UBYTE *) inst->aio_myDrawerData) + OLDDRAWERDATAFILESIZE; + + ULONG ddSize = 6; // size of structs can be different on AROS + // sizeof(struct DrawerData) - OLDDRAWERDATAFILESIZE + + d1(kprintf("%s/%s/%ld: remaining-drawerdata expected, size=%ld.\n", \ + __FILE__, __FUNC__, __LINE__, 6 /* sizeof(struct DrawerData) - OLDDRAWERDATAFILESIZE */)); + + if (ddSize != FRead(fd, RemainingDrawerData, 1, ddSize)) + break; + + d1(kprintf("%s/%s/%ld: remaining-DrawerData read Ok.\n", __FILE__, __FUNC__, __LINE__)); + } + + Success = TRUE; + } while (0); + + return Success; +} + +//---------------------------------------------------------------------------------------- + +static BOOL WriteStandardIcon(struct InstanceData *inst, + const struct DiskObject *WriteDiskObject, BPTR fd) +{ + BOOL Success = FALSE; + + do { + struct DiskObject wdo; + ULONG len; + ULONG val_be; // for storing values in BE order + + wdo = *WriteDiskObject; + + wdo.do_Gadget.UserData = (APTR) WB_DISKREVISION; + +#if defined(__AROS__) + if (!WriteConvertStandardIcon(fd, &wdo)) + break; +#else + if (sizeof(struct DiskObject) != FWrite(fd, &wdo, 1, sizeof(struct DiskObject))) + break; +#endif + + d1(KPrintF("%s/%s/%ld: DiskObject written Ok, size=%ld.\n", __FILE__, __FUNC__, __LINE__, sizeof(struct DiskObject))); + + if (wdo.do_DrawerData) + { + d1(KPrintF("%s/%s/%ld: write old-drawerdata, size=%ld.\n", __FILE__, __FUNC__, __LINE__, OLDDRAWERDATAFILESIZE)); + +#if defined(__AROS__) + if (!WriteConvertDrawerData(fd, inst->aio_myDrawerData)) + break; +#else + if (OLDDRAWERDATAFILESIZE != FWrite(fd, inst->aio_myDrawerData, 1, OLDDRAWERDATAFILESIZE)) + break; +#endif + + d1(KPrintF("%s/%s/%ld: OldDrawerData written Ok.\n", __FILE__, __FUNC__, __LINE__)); + } + + d1(KPrintF("%s/%s/%ld: write Image 1, size=%ld\n", __FILE__, __FUNC__, __LINE__, sizeof(inst->aio_DoImage1))); + +#if defined(__AROS__) + if (!WriteConvertImage(fd, &inst->aio_DoImage1)) + break; +#else + if (sizeof(inst->aio_DoImage1) != FWrite(fd, &inst->aio_DoImage1, 1, sizeof(inst->aio_DoImage1))) + break; +#endif + + d1(KPrintF("%s/%s/%ld: Image 1 written Ok.\n", __FILE__, __FUNC__, __LINE__)); + + len = RASSIZE(inst->aio_DoImage1.Width, inst->aio_DoImage1.Height) * inst->aio_DoImage1.Depth; + + d1(KPrintF("%s/%s/%ld: write ImageData 1, size=%ld\n", __FILE__, __FUNC__, __LINE__, len)); + + if (len != FWrite(fd, inst->aio_DoImage1.ImageData, 1, len)) + break; + + d1(KPrintF("%s/%s/%ld: ImageData 1 written Ok.\n", __FILE__, __FUNC__, __LINE__)); + + if (GFLG_GADGHIMAGE & wdo.do_Gadget.Flags) + { + d1(KPrintF("%s/%s/%ld: write Image 2, size=%ld\n", __FILE__, __FUNC__, __LINE__, sizeof(inst->aio_DoImage2))); + +#if defined(__AROS__) + if (!WriteConvertImage(fd, &inst->aio_DoImage2)) + break; +#else + if (sizeof(inst->aio_DoImage2) != FWrite(fd, &inst->aio_DoImage2, 1, sizeof(inst->aio_DoImage2))) + break; +#endif + + d1(KPrintF("%s/%s/%ld: Image 2 written Ok.\n", __FILE__, __FUNC__, __LINE__)); + + len = RASSIZE(inst->aio_DoImage2.Width, inst->aio_DoImage2.Height) * inst->aio_DoImage2.Depth; + + d1(KPrintF("%s/%s/%ld: write ImageData 2, size=%ld\n", __FILE__, __FUNC__, __LINE__, len)); + + if (len != FWrite(fd, inst->aio_DoImage2.ImageData, 1, len)) + break; + + d1(KPrintF("%s/%s/%ld: ImageData 2 written Ok.\n", __FILE__, __FUNC__, __LINE__)); + } + + if (wdo.do_DefaultTool) + { + len = 1 + strlen(wdo.do_DefaultTool); + + d1(KPrintF("%s/%s/%ld: write DefaultTool Length.\n", __FILE__, __FUNC__, __LINE__)); + val_be = SCA_LONG2BE(len); + if (sizeof(val_be) != FWrite(fd, &val_be, 1, sizeof(val_be))) + break; + + d1(KPrintF("%s/%s/%ld: DefaultTool length written Ok, length=%lu.\n", __FILE__, __FUNC__, __LINE__, val_be)); + + if (len) + { + if (len != FWrite(fd, wdo.do_DefaultTool, 1, len)) + break; + + d1(KPrintF("%s/%s/%ld: DefaultTool written Ok, <%s>.\n", \ + __FILE__, __FUNC__, __LINE__, wdo.do_DefaultTool)); + } + } + + if (wdo.do_ToolTypes) + { + short n; + + for (n = 0; wdo.do_ToolTypes[n]; n++) + ; + + len = (1 + n) * sizeof(STRPTR); + + d1(KPrintF("%s/%s/%ld: write size of ToolTypes Array = %ld.\n", __FILE__, __FUNC__, __LINE__, len)); + val_be = SCA_LONG2BE(len); + if (sizeof(val_be) != FWrite(fd, &val_be, 1, sizeof(val_be))) + break; + + d1(KPrintF("%s/%s/%ld: Size of ToolTypes Array written Ok, %lu.\n", __FILE__, __FUNC__, __LINE__, len)); + + + for (n=0; n<(len-1) / sizeof(STRPTR); n++) + { + ULONG sLen; + + sLen = 1 + strlen(wdo.do_ToolTypes[n]); + + val_be = SCA_LONG2BE(sLen); + if (sizeof(val_be) != FWrite(fd, &val_be, 1, sizeof(val_be))) + break; + + if (sLen != FWrite(fd, wdo.do_ToolTypes[n], 1, sLen)) + break; + + d1(KPrintF("%s/%s/%ld: ToolType #%ld written, len=%ld val=<%s>\n", \ + __FILE__, __FUNC__, __LINE__, n, sLen, wdo.do_ToolTypes[n])); + } + } + + if (wdo.do_ToolWindow) + { + len = 1 + strlen(wdo.do_ToolWindow); + + d1(KPrintF("%s/%s/%ld: write ToolWindow.\n", __FILE__, __FUNC__, __LINE__)); + + val_be = SCA_LONG2BE(len); + if (sizeof(val_be) != FWrite(fd, &val_be, 1, sizeof(val_be))) + break; + + if (len != FWrite(fd, wdo.do_ToolWindow, 1, len)) + break; + + d1(KPrintF("%s/%s/%ld: ToolWindow written ok, len=%ld\n", __FILE__, __FUNC__, __LINE__, len)); + } + + if (wdo.do_DrawerData) + { + UBYTE *RemainingDrawerData = ((UBYTE *) wdo.do_DrawerData) + OLDDRAWERDATAFILESIZE; + ULONG ddSize = 6; // size of structs can be different on AROS + // sizeof(struct DrawerData) - OLDDRAWERDATAFILESIZE; + + d1(KPrintF("%s/%s/%ld: write remaining-drawerdata, size=%ld.\n", \ + __FILE__, __FUNC__, __LINE__, 6 /* sizeof(struct DrawerData) - OLDDRAWERDATAFILESIZE */)); + + if (ddSize != FWrite(fd, RemainingDrawerData, 1, ddSize)) + break; + + d1(KPrintF("%s/%s/%ld: remaining-DrawerData written Ok.\n", __FILE__, __FUNC__, __LINE__)); + } + + Success = TRUE; + } while (0); + + return Success; +} + +//---------------------------------------------------------------------------------------- + +static struct NewImage *ReadNewImage(struct IFFHandle *iff, const struct FaceChunk *fc) +{ + struct NewImage *ni = NULL; + BOOL Success = FALSE; + UBYTE *UnCompressBuffer = NULL; + + do { + ULONG PaletteSize; + + ni = MyAllocVecPooled(sizeof(struct NewImage)); + if (NULL == ni) + break; + + memset(ni, 0, sizeof(struct NewImage)); + + if (sizeof(ni->nim_ImageChunk) != ReadChunkBytes(iff, &ni->nim_ImageChunk, sizeof(ni->nim_ImageChunk))) + break; + + ni->nim_ImageChunk.ic_NumImageBytes = SCA_BE2WORD(ni->nim_ImageChunk.ic_NumImageBytes); + ni->nim_ImageChunk.ic_NumPaletteBytes = SCA_BE2WORD(ni->nim_ImageChunk.ic_NumPaletteBytes); + + d1(kprintf("%s/%s/%ld: IMAG Chunk Read Ok.\n", __FILE__, __FUNC__, __LINE__)); + + d1(kprintf("%s/%s/%ld: Transparent=%ld ic_PaletteSize=%ld Flags=%02lx ImgComp=%02lx PalComp=%02lx BitsPerPixel=%ld NumImageBytes=%ld NumPaletteBytes=%ld\n",\ + __FILE__, __FUNC__, __LINE__, \ + (ULONG) ni->nim_ImageChunk.ic_TransparentColor,\ + (ULONG) ni->nim_ImageChunk.ic_PaletteSize, \ + (ULONG) ni->nim_ImageChunk.ic_Flags, \ + (ULONG) ni->nim_ImageChunk.ic_ImageCompressionType,\ + (ULONG) ni->nim_ImageChunk.ic_PaletteCompressionType, \ + (ULONG) ni->nim_ImageChunk.ic_BitsPerPixel,\ + (ULONG) ni->nim_ImageChunk.ic_NumImageBytes, + (ULONG) ni->nim_ImageChunk.ic_NumPaletteBytes)); + + ni->nim_Width = 1 + fc->fc_Width; + ni->nim_Height = 1 + fc->fc_Height; + ni->nim_PaletteSize = ni->nim_ImageChunk.ic_PaletteSize ? (1 + ni->nim_ImageChunk.ic_PaletteSize) : 0; + + PaletteSize = ni->nim_PaletteSize * sizeof(struct ColorRegister); + + ni->nim_Palette = MyAllocVecPooled(PaletteSize); + d1(kprintf("%s/%s/%ld: nim_Palette=%08lx\n", __FILE__, __FUNC__, __LINE__, ni->nim_Palette)); + if (NULL == ni->nim_Palette) + break; + + UnCompressBuffer = MyAllocVecPooled(1 + max(ni->nim_ImageChunk.ic_NumImageBytes, ni->nim_ImageChunk.ic_NumPaletteBytes)); + d1(kprintf("%s/%s/%ld: UnCompressBuffer=%08lx\n", __FILE__, __FUNC__, __LINE__, UnCompressBuffer)); + if (NULL == UnCompressBuffer) + break; + + ni->nim_ImageData = MyAllocVecPooled(ni->nim_Width * ni->nim_Height); + d1(kprintf("%s/%s/%ld: nim_ImageData=%08lx\n", __FILE__, __FUNC__, __LINE__, ni->nim_ImageData)); + if (NULL == ni->nim_ImageData) + break; + + if (1 + ni->nim_ImageChunk.ic_NumImageBytes != ReadChunkBytes(iff, UnCompressBuffer, 1 + ni->nim_ImageChunk.ic_NumImageBytes)) + break; + + d1(kprintf("%s/%s/%ld: Image Data Read Ok.\n", __FILE__, __FUNC__, __LINE__)); + + d1(kprintf("%s/%s/%ld: BufferData = %02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n",\ + __FILE__, __FUNC__, __LINE__, \ + UnCompressBuffer[0], UnCompressBuffer[1], UnCompressBuffer[2], UnCompressBuffer[3], \ + UnCompressBuffer[4], UnCompressBuffer[5], UnCompressBuffer[6], UnCompressBuffer[7])); + + if (cmpNone == ni->nim_ImageChunk.ic_ImageCompressionType) + { + d1(KPrintF("%s/%s/%ld: ic_NumImageBytes=%lu w*x=%lu\n", \ + __FILE__, __FUNC__, __LINE__, ni->nim_ImageChunk.ic_NumImageBytes, ni->nim_Width * ni->nim_Height)); + + CopyMem(UnCompressBuffer, ni->nim_ImageData, + min(ni->nim_ImageChunk.ic_NumImageBytes, ni->nim_Width * ni->nim_Height)); + } + else if (cmpByteRun1 == ni->nim_ImageChunk.ic_ImageCompressionType) + { + d1(KPrintF("%s/%s/%ld: decompressing Image Data.\n", __FILE__, __FUNC__, __LINE__)); + + if (!DecodeData(UnCompressBuffer, ni->nim_ImageData, + ni->nim_ImageChunk.ic_NumImageBytes, ni->nim_Width * ni->nim_Height, + ni->nim_ImageChunk.ic_BitsPerPixel)) + { + d1(KPrintF("%s/%s/%ld: Image Data decompression failed.\n", __FILE__, __FUNC__, __LINE__)); + break; + } + } + else + { + // unknown image compression type + d1(KPrintF("%s/%s/%ld: unknown Image Data decompression type.\n", __FILE__, __FUNC__, __LINE__)); + break; + } + + d1(KPrintF("%s/%s/%ld: Image Data Decoded Ok.\n", __FILE__, __FUNC__, __LINE__)); + +#if 0 + // Dump ImageData + if (ni->nim_ImageData) + { + short n; + + kprintf("-------ImageData1----------\n")); + for (n=0; nnim_Width * ni->nim_Height; n++) + { + if (0 == n % 16) + kprintf("\n%04lx: ", n); + printf("%02lx ", ni->nim_ImageData[n]); + } + kprintf("\n"); + } +#endif + + if (ni->nim_ImageChunk.ic_Flags & ICF_HasPalette) + { + if (1 + ni->nim_ImageChunk.ic_NumPaletteBytes != ReadChunkBytes(iff, UnCompressBuffer, 1 + ni->nim_ImageChunk.ic_NumPaletteBytes)) + break; + d1(kprintf("%s/%s/%ld: Palette Data Read Ok.\n", __FILE__, __FUNC__, __LINE__)); + + if (cmpNone == ni->nim_ImageChunk.ic_PaletteCompressionType) + { + if (1 + ni->nim_ImageChunk.ic_NumPaletteBytes != PaletteSize) + break; + + CopyMem(UnCompressBuffer, ni->nim_Palette, PaletteSize); + } + else if (cmpByteRun1 == ni->nim_ImageChunk.ic_PaletteCompressionType) + { + d1(KPrintF("%s/%s/%ld: decompressing Palette Data.\n", __FILE__, __FUNC__, __LINE__)); + + if (!DecodeData(UnCompressBuffer, (UBYTE *) ni->nim_Palette, + 1 + ni->nim_ImageChunk.ic_NumPaletteBytes, PaletteSize, + 8)) + { + d1(KPrintF("%s/%s/%ld: Palette Data decompression failed.\n", __FILE__, __FUNC__, __LINE__)); + break; + } + } + else + { + // unknown palette compression type + d1(KPrintF("%s/%s/%ld: unknown Palette Data decompression type.\n", __FILE__, __FUNC__, __LINE__)); + break; + } + + d1(kprintf("%s/%s/%ld: Palette Data Decoded Ok.\n", __FILE__, __FUNC__, __LINE__)); +#if 0 + kprintf("-------Palette----------\n"); + for (n=0; nnim_PaletteSize; n++) + { + kprintf("Palette : r=%02lx g=%02lx b=%02lx\n", + ni->nim_Palette[n].red, ni->nim_Palette[n].green, ni->nim_Palette[n].blue); + } +#endif + } + + Success = TRUE; + } while (0); + + d1(kprintf("%s/%s/%ld: END Success=%ld\n", __FILE__, __FUNC__, __LINE__, Success)); + + if (UnCompressBuffer) + MyFreeVecPooled(UnCompressBuffer); + + if (!Success) + FreeNewImage(&ni); + + return ni; +} + +//---------------------------------------------------------------------------------------- + +static struct NewImage *ReadARGBImage(struct IFFHandle *iff, const struct FaceChunk *fc) +{ + struct NewImage *ni = NULL; + BOOL Success = FALSE; + UBYTE *UnCompressBuffer = NULL; + + do { + ULONG ImageSize; + ULONG ReadLength; + ULONG BytesRead; + z_stream stream; + int zError; + + ni = MyAllocVecPooled(sizeof(struct NewImage)); + if (NULL == ni) + break; + + memset(ni, 0, sizeof(struct NewImage)); + + if (sizeof(ni->nim_ImageChunk) != ReadChunkBytes(iff, &ni->nim_ImageChunk, sizeof(ni->nim_ImageChunk))) + break; + + ni->nim_ImageChunk.ic_NumImageBytes = SCA_BE2WORD(ni->nim_ImageChunk.ic_NumImageBytes); + ni->nim_ImageChunk.ic_NumPaletteBytes = SCA_BE2WORD(ni->nim_ImageChunk.ic_NumPaletteBytes); + + d1(KPrintF("%s/%s/%ld: ARGB Chunk Read Ok.\n", __FILE__, __FUNC__, __LINE__)); + + d1(KPrintF("%s/%s/%ld: Transparent=%ld ic_PaletteSize=%ld Flags=%02lx ImgComp=%02lx PalComp=%02lx BitsPerPixel=%ld NumImageBytes=%ld NumPaletteBytes=%ld\n",\ + __FILE__, __FUNC__, __LINE__, \ + (ULONG) ni->nim_ImageChunk.ic_TransparentColor,\ + (ULONG) ni->nim_ImageChunk.ic_PaletteSize, \ + (ULONG) ni->nim_ImageChunk.ic_Flags, \ + (ULONG) ni->nim_ImageChunk.ic_ImageCompressionType,\ + (ULONG) ni->nim_ImageChunk.ic_PaletteCompressionType, \ + (ULONG) ni->nim_ImageChunk.ic_BitsPerPixel,\ + (ULONG) ni->nim_ImageChunk.ic_NumImageBytes, + (ULONG) ni->nim_ImageChunk.ic_NumPaletteBytes)); + + ni->nim_ARGBheader.argb_Width = ni->nim_Width = 1 + fc->fc_Width; + ni->nim_ARGBheader.argb_Height = ni->nim_Height = 1 + fc->fc_Height; + ni->nim_PaletteSize = 1 + ni->nim_ImageChunk.ic_PaletteSize; + + ImageSize = ni->nim_ImageChunk.ic_NumImageBytes + 1; + ReadLength = ((ImageSize + 1) >> 1) << 1; // round to next even number + + UnCompressBuffer = MyAllocVecPooled(ReadLength); + d1(KPrintF("%s/%s/%ld: UnCompressBuffer=%08lx\n", __FILE__, __FUNC__, __LINE__, UnCompressBuffer)); + if (NULL == UnCompressBuffer) + break; + + BytesRead = ReadChunkBytes(iff, UnCompressBuffer, ImageSize); + d1(KPrintF("%s/%s/%ld: ReadLength=%lu BytesRead=%lu\n", __FILE__, __FUNC__, __LINE__, ImageSize, BytesRead)); + if (BytesRead != ImageSize) + break; + + stream.avail_out = ni->nim_Width * ni->nim_Height * sizeof(struct ARGB); + + ni->nim_ImageData = MyAllocVecPooled(stream.avail_out); + d1(KPrintF("%s/%s/%ld: nim_ImageData=%08lx\n", __FILE__, __FUNC__, __LINE__, ni->nim_ImageData)); + if (NULL == ni->nim_ImageData) + break; + + ni->nim_ARGBheader.argb_ImageData = (struct ARGB *) ni->nim_ImageData; + + stream.next_in = UnCompressBuffer; + stream.avail_in = ImageSize; + stream.next_out = ni->nim_ImageData; + stream.zalloc = (alloc_func) ZLibAlloc; + stream.zfree = (free_func) ZLibFree; + + d1(KPrintF("%s/%s/%ld: avail_out=%ld\n", __FILE__, __FUNC__, __LINE__, stream.avail_out)); + + zError = inflateInit(&stream); + d1(KPrintF("%s/%s/%ld: zError=%ld\n", __FILE__, __FUNC__, __LINE__, zError)); + if (Z_OK != zError) + break; + + zError = inflate(&stream, Z_FINISH); + d1(KPrintF("%s/%s/%ld: zError=%ld\n", __FILE__, __FUNC__, __LINE__, zError)); + if (Z_STREAM_END != zError) + { + inflateEnd(&stream); + break; + } + + zError = inflateEnd(&stream); + d1(KPrintF("%s/%s/%ld: zError=%ld\n", __FILE__, __FUNC__, __LINE__, zError)); + if (Z_OK != zError) + break; + + Success = TRUE; + } while (0); + + d1(KPrintF("%s/%s/%ld: END Success=%ld\n", __FILE__, __FUNC__, __LINE__, Success)); + + if (UnCompressBuffer) + MyFreeVecPooled(UnCompressBuffer); + + if (!Success) + FreeNewImage(&ni); + + return ni; +} + +//---------------------------------------------------------------------------------------- + +static LONG WriteNewImage(struct IFFHandle *iff, const struct NewImage *ni) +{ + UBYTE *PaletteCompressed = NULL; + UBYTE *ImageDataCompressed = NULL; + LONG ErrorCode; + + d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__)); + + do { + struct ImageChunk SaveImageChunk; + ULONG Size; + UWORD NumImageBytesOld; + UWORD NumPaletteBytesOld; + + SaveImageChunk = ni->nim_ImageChunk; + + if (ni->nim_PaletteSize && ni->nim_Palette + && (ni->nim_ImageChunk.ic_Flags & ICF_HasPalette)) + { + SaveImageChunk.ic_Flags |= ICF_HasPalette; + + Size = ni->nim_PaletteSize * sizeof(struct ColorRegister); + PaletteCompressed = EncodeData(8, + &SaveImageChunk.ic_NumPaletteBytes, + Size, + (UBYTE *) ni->nim_Palette); + d1(KPrintF("%s/%s/%ld: PaletteCompressed=%08lx\n", __FILE__, __FUNC__, __LINE__, PaletteCompressed)); + if (NULL == PaletteCompressed) + { + SetIoErr(ErrorCode = ERROR_NO_FREE_STORE); + break; + } + + d1(KPrintF("%s/%s/%ld: Size=%lu ic_NumPaletteBytes=%lu\n", __FILE__, __FUNC__, __LINE__, Size, SaveImageChunk.ic_NumPaletteBytes)); + + if (Size == SaveImageChunk.ic_NumPaletteBytes) + SaveImageChunk.ic_PaletteCompressionType = cmpNone; + else + SaveImageChunk.ic_PaletteCompressionType = cmpByteRun1; + } + else + { + SaveImageChunk.ic_Flags &= ~ICF_HasPalette; + SaveImageChunk.ic_NumPaletteBytes = 0; + } + + Size = ni->nim_Width * ni->nim_Height; + ImageDataCompressed = EncodeData(SaveImageChunk.ic_BitsPerPixel, + &SaveImageChunk.ic_NumImageBytes, + Size, + ni->nim_ImageData); + d1(KPrintF("%s/%s/%ld: ImageDataCompressed=%08lx\n", __FILE__, __FUNC__, __LINE__, ImageDataCompressed)); + if (NULL == ImageDataCompressed) + { + SetIoErr(ErrorCode = ERROR_NO_FREE_STORE); + break; + } + + d1(KPrintF("%s/%s/%ld: Depth=%ld Size=%lu ic_NumImageBytes=%lu\n", __FILE__, __FUNC__, __LINE__, SaveImageChunk.ic_BitsPerPixel, Size, SaveImageChunk.ic_NumImageBytes)); + + d1(KPrintF("%s/%s/%ld: ImageData = %02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n",\ + __FILE__, __FUNC__, __LINE__, \ + ni->nim_ImageData[0], ni->nim_ImageData[1], ni->nim_ImageData[2], ni->nim_ImageData[3], \ + ni->nim_ImageData[4], ni->nim_ImageData[5], ni->nim_ImageData[6], ni->nim_ImageData[7])); + d1(KPrintF("%s/%s/%ld: ImageDataCompressed = %02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n",\ + __FILE__, __FUNC__, __LINE__, \ + ImageDataCompressed[0], ImageDataCompressed[1], ImageDataCompressed[2], ImageDataCompressed[3], \ + ImageDataCompressed[4], ImageDataCompressed[5], ImageDataCompressed[6], ImageDataCompressed[7])); + + if (Size == SaveImageChunk.ic_NumImageBytes) + SaveImageChunk.ic_ImageCompressionType = cmpNone; + else + SaveImageChunk.ic_ImageCompressionType = cmpByteRun1; + + SaveImageChunk.ic_NumImageBytes--; + if (SaveImageChunk.ic_NumPaletteBytes) + SaveImageChunk.ic_NumPaletteBytes--; + + ErrorCode = PushChunk(iff, ID_ICON, ID_IMAG, IFFSIZE_UNKNOWN); + d1(KPrintF("%s/%s/%ld: PushChunk(ID_IMAG) returned %ld\n", __FILE__, __FUNC__, __LINE__, ErrorCode)); + if (RETURN_OK != ErrorCode) + break; + + NumImageBytesOld = SaveImageChunk.ic_NumImageBytes; + NumPaletteBytesOld = SaveImageChunk.ic_NumPaletteBytes; + SaveImageChunk.ic_NumImageBytes = SCA_WORD2BE(SaveImageChunk.ic_NumImageBytes); + SaveImageChunk.ic_NumPaletteBytes = SCA_WORD2BE(SaveImageChunk.ic_NumPaletteBytes); + + if (sizeof(SaveImageChunk) != WriteChunkBytes(iff, + &SaveImageChunk, sizeof(SaveImageChunk))) + { + d1(KPrintF("%s/%s/%ld: WriteChunk(imagehunk) failed\n", __FILE__, __FUNC__, __LINE__)); + ErrorCode = IoErr(); + break; + } + + SaveImageChunk.ic_NumImageBytes = NumImageBytesOld; + SaveImageChunk.ic_NumPaletteBytes = NumPaletteBytesOld; + + Size = SaveImageChunk.ic_NumImageBytes + 1; + + if (Size != WriteChunkBytes(iff, ImageDataCompressed, Size)) + { + d1(KPrintF("%s/%s/%ld: WriteChunk(image) failed\n", __FILE__, __FUNC__, __LINE__)); + ErrorCode = IoErr(); + break; + } + + if (SaveImageChunk.ic_NumPaletteBytes) + { + Size = SaveImageChunk.ic_NumPaletteBytes + 1; + + if (Size != WriteChunkBytes(iff, PaletteCompressed, Size)) + { + d1(KPrintF("%s/%s/%ld: WriteChunk(palette) failed\n", __FILE__, __FUNC__, __LINE__)); + ErrorCode = IoErr(); + break; + } + } + + ErrorCode = PopChunk(iff); + d1(KPrintF("%s/%s/%ld: PopChunk returned %ld\n", __FILE__, __FUNC__, __LINE__, ErrorCode)); + if (RETURN_OK != ErrorCode) + break; + } while (0); + + if (ImageDataCompressed) + MyFreeVecPooled(ImageDataCompressed); + + if (PaletteCompressed) + MyFreeVecPooled(PaletteCompressed); + + d1(KPrintF("%s/%s/%ld: END ErrorCode=%ld\n", __FILE__, __FUNC__, __LINE__, ErrorCode)); + + return ErrorCode; +} + +//---------------------------------------------------------------------------------------- + +static LONG WriteARGBImage(Class *cl, Object *o, struct IFFHandle *iff, + const struct NewImage *ni, ULONG ARGBImageTag) +{ + UBYTE *ImageDataCompressed = NULL; + LONG ErrorCode; + z_stream stream; + + d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__)); + + memset(&stream, 0, sizeof(stream)); + + do { + struct ImageChunk SaveImageChunk; + struct ARGBHeader *argbh = NULL; + ULONG Size; + UWORD NumImageBytesOld; // remember size before endian conversion + int zError; + + memset(&argbh, 0, sizeof(argbh)); + + SaveImageChunk = ni->nim_ImageChunk; + + SaveImageChunk.ic_Flags &= ~ICF_HasPalette; + SaveImageChunk.ic_NumPaletteBytes = 0; + SaveImageChunk.ic_BitsPerPixel = 0; // MUST be 0 for OS4 to recognize icon! + + GetAttr(ARGBImageTag, o, (APTR) &argbh); + d1(KPrintF("%s/%s/%ld: argbh=%08lx argb_ImageData=%08lx\n", __FILE__, __FUNC__, __LINE__, argbh, argbh->argb_ImageData)); + if (NULL == argbh->argb_ImageData) + { + SetIoErr(ErrorCode = ERROR_OBJECT_WRONG_TYPE); + break; + } + + stream.avail_in = Size = argbh->argb_Width * argbh->argb_Height * sizeof(struct ARGB); + stream.next_in = (Bytef *) argbh->argb_ImageData; + + stream.avail_out = Size; + stream.next_out = ImageDataCompressed = MyAllocVecPooled(stream.avail_out); + d1(KPrintF("%s/%s/%ld: ImageDataCompressed=%08lx Size=%lu\n", __FILE__, __FUNC__, __LINE__, ImageDataCompressed, Size)); + if (NULL == ImageDataCompressed) + { + SetIoErr(ErrorCode = ERROR_NO_FREE_STORE); + break; + } + + stream.zalloc = (alloc_func) ZLibAlloc; + stream.zfree = (free_func) ZLibFree; + stream.opaque = Z_NULL; + + zError = deflateInit(&stream, Z_DEFAULT_COMPRESSION); + d1(KPrintF("%s/%s/%ld: zError=%ld\n", __FILE__, __FUNC__, __LINE__, zError)); + if (Z_OK != zError) + { + SetIoErr(ErrorCode = ERROR_NO_FREE_STORE); + break; + } + + zError = deflate(&stream, Z_FINISH); + d1(KPrintF("%s/%s/%ld: zError=%ld\n", __FILE__, __FUNC__, __LINE__, zError)); + if (Z_STREAM_END != zError) + { + SetIoErr(ErrorCode = ERROR_NO_FREE_STORE); + break; + } + + SaveImageChunk.ic_NumImageBytes = Size - stream.avail_out; + + d1(KPrintF("%s/%s/%ld: Depth=%ld Size=%lu ic_NumImageBytes=%lu\n", __FILE__, __FUNC__, __LINE__, SaveImageChunk.ic_BitsPerPixel, Size, SaveImageChunk.ic_NumImageBytes)); + + if (Size == SaveImageChunk.ic_NumImageBytes) + SaveImageChunk.ic_ImageCompressionType = cmpNone; + else + SaveImageChunk.ic_ImageCompressionType = cmpByteRun1; + + SaveImageChunk.ic_NumImageBytes--; + + ErrorCode = PushChunk(iff, ID_ICON, ID_ARGB, IFFSIZE_UNKNOWN); + d1(KPrintF("%s/%s/%ld: PushChunk(ID_ARGB) returned %ld\n", __FILE__, __FUNC__, __LINE__, ErrorCode)); + if (RETURN_OK != ErrorCode) + break; + + NumImageBytesOld = SaveImageChunk.ic_NumImageBytes; + SaveImageChunk.ic_NumImageBytes = SCA_WORD2BE(SaveImageChunk.ic_NumImageBytes); + + if (sizeof(SaveImageChunk) != WriteChunkBytes(iff, + &SaveImageChunk, sizeof(SaveImageChunk))) + { + d1(KPrintF("%s/%s/%ld: WriteChunk(imagehunk) failed\n", __FILE__, __FUNC__, __LINE__)); + ErrorCode = IoErr(); + break; + } + + SaveImageChunk.ic_NumImageBytes = NumImageBytesOld; + Size = SaveImageChunk.ic_NumImageBytes + 1; + + if (Size != WriteChunkBytes(iff, ImageDataCompressed, Size)) + { + d1(KPrintF("%s/%s/%ld: WriteChunk(image) failed\n", __FILE__, __FUNC__, __LINE__)); + ErrorCode = IoErr(); + break; + } + + ErrorCode = PopChunk(iff); + d1(KPrintF("%s/%s/%ld: PopChunk returned %ld\n", __FILE__, __FUNC__, __LINE__, ErrorCode)); + if (RETURN_OK != ErrorCode) + break; + } while (0); + + if (ImageDataCompressed) + MyFreeVecPooled(ImageDataCompressed); + + (void) deflateEnd(&stream); + + d1(KPrintF("%s/%s/%ld: END ErrorCode=%ld\n", __FILE__, __FUNC__, __LINE__, ErrorCode)); + + return ErrorCode; +} + +//---------------------------------------------------------------------------------------- + +static void FreeNewImage(struct NewImage **ni) +{ + if (*ni) + { + if ((*ni)->nim_ImageData) + { + MyFreeVecPooled((*ni)->nim_ImageData); + (*ni)->nim_ImageData = NULL; + } + if ((*ni)->nim_Palette) + { + MyFreeVecPooled((*ni)->nim_Palette); + (*ni)->nim_Palette = NULL; + } + MyFreeVecPooled(*ni); + *ni = NULL; + } +} + +//---------------------------------------------------------------------------------------- + +static BOOL CloneNewImage(struct NewImage **niClone, const struct NewImage *niSrc) +{ + BOOL Success = FALSE; + + do { + if (niSrc) + { + size_t len; + + *niClone = MyAllocVecPooled(sizeof(struct NewImage)); + if (NULL == *niClone) + break; + + if (niSrc->nim_ImageData) + { + // Clone nim_ImageData + **niClone = *niSrc; + len = (*niClone)->nim_Width * (*niClone)->nim_Height; + (*niClone)->nim_Palette = NULL; + + (*niClone)->nim_ImageData = MyAllocVecPooled(len); + d1(KPrintF("%s/%s/%ld: nim_ImageData=%08lx\n", __FILE__, __FUNC__, __LINE__, (*niClone)->nim_ImageData)); + if (NULL == (*niClone)->nim_ImageData) + break; + + memcpy((*niClone)->nim_ImageData, niSrc->nim_ImageData, len); + } + + if (niSrc->nim_Palette) + { + // Clone nim_Palette + len = niSrc->nim_PaletteSize * sizeof(struct ColorRegister); + + (*niClone)->nim_Palette = MyAllocVecPooled(len); + d1(KPrintF("%s/%s/%ld: nim_Palette=%08lx\n", __FILE__, __FUNC__, __LINE__, (*niClone)->nim_Palette)); + + if (NULL == (*niClone)->nim_Palette) + break; + + memcpy((*niClone)->nim_Palette, niSrc->nim_Palette, len); + } + + Success = TRUE; + } + else + { + *niClone = NULL; + Success = TRUE; + } + } while (0); + + if (*niClone && !Success) + { + // Free partially allocated clone + FreeNewImage(niClone); + } + + return Success; +} + +//---------------------------------------------------------------------------------------- +// EncodeData() based on ModifyIcon source by Dirk Stöcker +//---------------------------------------------------------------------------------------- + +static UBYTE *EncodeData(ULONG Depth, UWORD *DestLength, + ULONG SrcLength, const UBYTE *SrcData) +{ + int i, j, k; + ULONG bitbuf, numbits; + UBYTE *buf; + LONG ressize, numcopy, numequal; + + buf = MyAllocVecPooled(SrcLength * 2); + if (NULL == buf) + return NULL; + + numcopy = 0; + numequal = 1; + bitbuf = 0; + numbits = 0; + ressize = 0; + k = 0; /* the real output pointer */ + + for (i = 1; (numequal || numcopy) && (ressize < SrcLength);) + { + if (i < SrcLength && numequal && (SrcData[i-1] == SrcData[i])) + { + ++numequal; + ++i; + } + else if (i < SrcLength && numequal * Depth <= 16) + { + numcopy += numequal; + numequal = 1; + ++i; + } + else + { + /* care for end case, where it maybe better to join the two */ + if (i == SrcLength && numcopy + numequal <= 128 && (numequal-1) * Depth <= 8) + { + numcopy += numequal; + numequal = 0; + } + + if (numcopy) + { + if ((j = numcopy) > 128) + j = 128; + + bitbuf = (bitbuf<<8) | (j-1); + numcopy -= j; + } + else + { + if ((j = numequal) > 128) + j = 128; + + bitbuf = (bitbuf<<8) | (256-(j-1)); + numequal -= j; + k += j-1; + j = 1; + } + + buf[ressize++] = (bitbuf >> numbits); + + while (j--) + { + numbits += Depth; + bitbuf = (bitbuf << Depth) | SrcData[k++]; + + if (numbits >= 8) + { + numbits -= 8; + buf[ressize++] = (bitbuf >> numbits); + } + } + + if (i < SrcLength && !numcopy && !numequal) + { + numequal = 1; + ++i; + } + } + } + + if (numbits) + buf[ressize++] = bitbuf << (8-numbits); + + if (ressize >= SrcLength) + { + // no RLE + ressize = SrcLength; + CopyMem((APTR) SrcData, buf, SrcLength); + } + + *DestLength = ressize; + + return buf; +} + +//---------------------------------------------------------------------------------------- + +static UBYTE INLINE GetNextDestByte(const UBYTE **src, size_t *SrcLength, short *srcBits, + UBYTE *srcByte, LONG BitsPerEntry) +{ + UBYTE Mask; + short destBits; + short Shift; + UBYTE Result = 0; + + destBits = 0; + Mask = (1 << BitsPerEntry) - 1; + Shift = 8 - BitsPerEntry - *srcBits; + + d1(kprintf("%s/%s/%ld: Shift=%ld BitsPerEntry=%ld Mask=%02lx\n", \ + __FILE__, __FUNC__, __LINE__, Shift, BitsPerEntry, Mask)); + + while (destBits < BitsPerEntry) + { + if (Shift < 0) + { + d1(kprintf("%s/%s/%ld: (1) srcByte=%02lx sMask=%02lx Shift=%ld\n", \ + __FILE__, __FUNC__, __LINE__, *srcByte, (Mask >> -Shift), Shift)); + + Result |= (*srcByte & (Mask >> -Shift)) << -Shift; + destBits += BitsPerEntry + Shift; + *srcBits += BitsPerEntry + Shift; + Shift += 8; + } + else + { + d1(kprintf("%s/%s/%ld: (2) srcByte=%ld sMask=%02lx Shift=%ld\n", \ + __FILE__, __FUNC__, __LINE__, *srcByte, (Mask << Shift), Shift)); + + Result |= (*srcByte & (Mask << Shift)) >> Shift; + + if (Shift + BitsPerEntry > 8) + { + destBits += 8 - Shift; + *srcBits += 8 - Shift; + } + else + { + destBits += BitsPerEntry; + *srcBits += BitsPerEntry; + } + + Shift -= BitsPerEntry; + if (Shift <= -BitsPerEntry) + Shift += 8; + } + + d1(kprintf("%s/%s/%ld: Result = %02lx\n", __FILE__, __FUNC__, __LINE__, Result)); + + if (*SrcLength && *srcBits >= 8) + { + *srcBits %= 8; + (*src)++; + (*SrcLength)--; + *srcByte = **src; + } + } + + + d1(kprintf("%s/%s/%ld: srcBits=%ld destBits=%ld SrcByte=%02lx Result=%02lx\n", \ + __FILE__, __FUNC__, __LINE__, *srcBits, destBits, *srcByte, Result)); + + return Result; +} + +//---------------------------------------------------------------------------------------- + +static BOOL DecodeData(const UBYTE *src, UBYTE *dest, size_t SrcLength, size_t DestLength, LONG BitsPerEntry) +{ + short srcBits; + signed char Rep = 0; + short RepeatCount = 0; + UBYTE RepeatByte = 0; + UBYTE srcByte; + + srcByte = *src; + srcBits = 0; + + while (DestLength) + { + d1(KPrintF("%s/%s/%ld: DestLength=%ld in=%02lx out=%02lx\n",\ + __FILE__, __FUNC__, __LINE__, DestLength, srcByte, *dest)); + + if (0 == RepeatCount) + { + Rep = GetNextDestByte(&src, &SrcLength, &srcBits, &srcByte, 8); + + if (Rep < 0) + { + RepeatCount = 1 - Rep; + RepeatByte = GetNextDestByte(&src, &SrcLength, &srcBits, &srcByte, BitsPerEntry); + } + else + RepeatCount = 1 + Rep; + + d1(kprintf("%s/%s/%ld: Rep=%02lx RepeatCount=%ld RepeatByte=%02lx\n", \ + __FILE__, __FUNC__, __LINE__, Rep & 0xff, RepeatCount, RepeatByte)); + } + + if (Rep >= 0) + *dest++ = GetNextDestByte(&src, &SrcLength, &srcBits, &srcByte, BitsPerEntry); + else + *dest++ = RepeatByte; + + RepeatCount--; + DestLength--; + } + + d1(KPrintF("%s/%s/%ld: END SrcLength=%lu DestLength=%lu\n", __FILE__, __FUNC__, __LINE__, SrcLength, DestLength)); + + return (BOOL) (0 == DestLength && 0 == SrcLength); +} + +//---------------------------------------------------------------------------------------- + +static UBYTE *GenerateMask(struct NewImage *nim) +{ + ULONG Size; + UBYTE *MaskArray; + ULONG BytesPerRow; + + d1(KPrintF("%s/%s/%ld: ic_Flags=%02lx ic_TransparentColor=%ld\n", \ + __FILE__, __FUNC__, __LINE__, nim->nim_ImageChunk.ic_Flags, nim->nim_ImageChunk.ic_TransparentColor)); + + BytesPerRow = BYTESPERROW(nim->nim_Width); + Size = nim->nim_Height * BytesPerRow; + MaskArray = MyAllocVecPooled(Size); + if (MaskArray) + { + if (nim->nim_ImageChunk.ic_Flags & ICF_IsTransparent) + { + const UBYTE *ChunkyData = nim->nim_ImageData; + UBYTE *MaskPtr = MaskArray; + ULONG y; + + memset(MaskArray, 0, Size); + + for (y = 0; y < nim->nim_Height; y++) + { + ULONG x; + UBYTE BitMask = 0x80; + UBYTE *MaskPtr2 = MaskPtr; + + for (x = 0; x < nim->nim_Width; x++) + { + if (nim->nim_ImageChunk.ic_TransparentColor != *ChunkyData++) + *MaskPtr2 |= BitMask; + BitMask >>= 1; + if (0 == BitMask) + { + BitMask = 0x80; + MaskPtr2++; + } + } + + MaskPtr += BytesPerRow; + } + } + else + { + memset(MaskArray, ~0, Size); + } + } + + return MaskArray; +} + +//---------------------------------------------------------------------------------------- + +static APTR MyAllocVecPooled(size_t Size) +{ + APTR ptr; + + if (MemPool) + { + ObtainSemaphore(&PubMemPoolSemaphore); + ptr = AllocPooled(MemPool, Size + sizeof(size_t)); + ReleaseSemaphore(&PubMemPoolSemaphore); + if (ptr) + { + size_t *sptr = (size_t *) ptr; + + sptr[0] = Size; + + d1(kprintf("%s/%s/%ld: MemPool=%08lx Size=%lu mem=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, MemPool, Size, &sptr[1])); + return (APTR)(&sptr[1]); + } + } + + d1(kprintf("%s/%s/%ld: MemPool=%08lx Size=%lu\n", __FILE__, __FUNC__, __LINE__, MemPool, Size)); + + return NULL; +} + + +static void MyFreeVecPooled(APTR mem) +{ + d1(kprintf("%s/%s/%ld: MemPool=%08lx mem=%08lx\n", __FILE__, __FUNC__, __LINE__, MemPool, mem)); + if (MemPool && mem) + { + size_t size; + size_t *sptr = (size_t *) mem; + + mem = &sptr[-1]; + size = sptr[-1]; + + ObtainSemaphore(&PubMemPoolSemaphore); + FreePooled(MemPool, mem, size + sizeof(size_t)); + ReleaseSemaphore(&PubMemPoolSemaphore); + } +} + +//---------------------------------------------------------------------------------------- + +static struct NewImage *NewImageFromSAC(struct ScalosBitMapAndColor *sac) +{ + struct NewImage *ni = NULL; + struct BitMap *TempBM; + BOOL Success = FALSE; + + do { + ULONG n; + ULONG y; + const ULONG *PalettePtr; + struct RastPort rp; + struct RastPort TempRp; + UBYTE *ImagePtr; + ULONG NewWidth = sac->sac_Width; + ULONG NewHeight = sac->sac_Height; + + InitRastPort(&rp); + InitRastPort(&TempRp); + + rp.BitMap = sac->sac_BitMap; + d1(KPrintF(__FILE__ "/" "%s/%s/%ld: rp.BitMap=%08lx\n", __FILE__, __FUNC__, __LINE__, rp.BitMap)); + + // setup temp. RastPort for use by WritePixelLine8() + TempRp.Layer = NULL; + TempRp.BitMap = TempBM = AllocBitMap(TEMPRP_WIDTH(NewWidth), 1, 8, 0, NULL); + + if (NULL == TempBM) + break; + ni = MyAllocVecPooled(sizeof(struct NewImage)); + if (NULL == ni) + break; + + memset(ni, 0, sizeof(struct NewImage)); + + ni->nim_Width = NewWidth; + ni->nim_Height = NewHeight; + + ni->nim_ImageChunk.ic_TransparentColor = sac->sac_TransparentColor; + ni->nim_ImageChunk.ic_Flags |= ICF_HasPalette; + if (SAC_TRANSPARENT_NONE != sac->sac_TransparentColor) + ni->nim_ImageChunk.ic_Flags |= ICF_IsTransparent; + + d1(KPrintF(__FILE__ "/" "%s/%s/%ld: sac_TransparentColor=%ld\n", __FILE__, __FUNC__, __LINE__, sac->sac_TransparentColor)); + + ni->nim_ImageChunk.ic_PaletteSize = sac->sac_NumColors - 1; + ni->nim_ImageChunk.ic_BitsPerPixel = sac->sac_Depth; + + ni->nim_ImageData = MyAllocVecPooled(PIXELARRAY8_BUFFERSIZE(ni->nim_Width, ni->nim_Height)); + if (NULL == ni->nim_ImageData) + break; + + ni->nim_PaletteSize = sac->sac_NumColors; + ni->nim_Palette = MyAllocVecPooled(sac->sac_NumColors * sizeof(struct ColorRegister)); + if (NULL == ni->nim_Palette) + break; + + // nothing can go wrong from here on + Success = TRUE; + + d1(KPrintF("%s/%s/%ld: NumColors=%lu\n", __FILE__, __FUNC__, __LINE__, sac->sac_NumColors)); + + // Fill nim_Palette fom sac_ColorTable + for (n = 0, PalettePtr = sac->sac_ColorTable; n < sac->sac_NumColors; n++) + { + ni->nim_Palette[n].red = *PalettePtr++ >> 24; + ni->nim_Palette[n].green = *PalettePtr++ >> 24; + ni->nim_Palette[n].blue = *PalettePtr++ >> 24; + } + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + // copy image data from sac_BitMap into nim_ImageData + for (y = 0, ImagePtr = ni->nim_ImageData; y < NewHeight; y++) + { + d1(KPrintF("%s/%s/%ld: y=%ld\n", __FILE__, __FUNC__, __LINE__, y)); + ReadPixelLine8(&rp, 0, y, NewWidth, + ImagePtr, &TempRp); + ImagePtr += NewWidth; + } + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + } while (0); + + if (!Success) + FreeNewImage(&ni); + + if (TempBM) + FreeBitMap(TempBM); + + return ni; +} + +//---------------------------------------------------------------------------------------- + +static void GenerateNormalImageMask(Class *cl, Object *o) +{ + struct InstanceData *inst = INST_DATA(cl, o); + UBYTE *MaskNormal = NULL; + + if (inst->aio_Image1->nim_ImageChunk.ic_Flags & ICF_IsTransparent) + { + MaskNormal = GenerateMask(inst->aio_Image1); + } + + d1(KPrintF("%s/%s/%ld: MaskNormal=%08lx\n", __FILE__, __FUNC__, __LINE__, MaskNormal)); + + SetAttrs(o, IDTA_Mask_Normal, (ULONG) MaskNormal, + IDTA_Width_Mask_Normal, inst->aio_Image1->nim_Width, + IDTA_Height_Mask_Normal, inst->aio_Image1->nim_Height, + TAG_END); + + if (MaskNormal) + MyFreeVecPooled(MaskNormal); +} + +//---------------------------------------------------------------------------------------- + +static void GenerateSelectedImageMask(Class *cl, Object *o) +{ + struct InstanceData *inst = INST_DATA(cl, o); + UBYTE *MaskSelected = NULL; + + if (inst->aio_Image2 && (inst->aio_Image2->nim_ImageChunk.ic_Flags & ICF_IsTransparent)) + { + MaskSelected = GenerateMask(inst->aio_Image2); + } + + d1(KPrintF("%s/%s/%ld: MaskSelected=%08lx\n", __FILE__, __FUNC__, __LINE__, MaskSelected)); + + SetAttrs(o, IDTA_Mask_Selected, (ULONG) MaskSelected, + IDTA_Width_Mask_Selected, inst->aio_Image2->nim_Width, + IDTA_Height_Mask_Selected, inst->aio_Image2->nim_Height, + TAG_END); + + if (MaskSelected) + MyFreeVecPooled(MaskSelected); +} + +//---------------------------------------------------------------------------------------- + +static struct NewImage *NewImageFromNormalImage(const struct InstanceData *inst, const struct NewImage *niNormal) +{ + struct NewImage *ni = NULL; + BOOL Success = FALSE; + + d1(KPrintF("%s/%s/%ld: inst=%08lx, niNormal=%08lx\n", __FILE__, __FUNC__, __LINE__, inst, niNormal)); + + do { + ULONG n; + const struct ColorRegister *PaletteSrcPtr; + struct ColorRegister *PaletteDestPtr; + size_t ImgSize; + ULONG Backfill[2] = { IDTA_BACKFILL_NONE, IDTA_BACKFILL_NONE }; + ULONG BackfillCount = 0; + + ni = MyAllocVecPooled(sizeof(struct NewImage)); + if (NULL == ni) + break; + + memset(ni, 0, sizeof(struct NewImage)); + + ni->nim_Width = niNormal->nim_Width; + ni->nim_Height = niNormal->nim_Height; + + ImgSize = ni->nim_Width * ni->nim_Height; + + ni->nim_ImageChunk.ic_TransparentColor = niNormal->nim_ImageChunk.ic_TransparentColor; + ni->nim_ImageChunk.ic_Flags = niNormal->nim_ImageChunk.ic_Flags; + + d1(KPrintF("%s/%s/%ld: ic_TransparentColor=%ld\n", __FILE__, __FUNC__, __LINE__, ni->nim_ImageChunk.ic_TransparentColor)); + d1(KPrintF("%s/%s/%ld: ic_PaletteSize=%lu\n", __FILE__, __FUNC__, __LINE__, niNormal->nim_ImageChunk.ic_PaletteSize)); + + ni->nim_ImageChunk.ic_PaletteSize = niNormal->nim_ImageChunk.ic_PaletteSize; + ni->nim_ImageChunk.ic_BitsPerPixel = niNormal->nim_ImageChunk.ic_BitsPerPixel; + + ni->nim_ImageData = MyAllocVecPooled(ImgSize); + if (NULL == ni->nim_ImageData) + break; + + ni->nim_PaletteSize = niNormal->nim_PaletteSize; + + if (niNormal->nim_Palette) + { + ni->nim_Palette = MyAllocVecPooled(ni->nim_PaletteSize * sizeof(struct ColorRegister)); + if (NULL == ni->nim_Palette) + break; + + // nothing can go wrong from here on + Success = TRUE; + + // remember color table indices for backfill colors + if (IDTA_BACKFILL_NONE != inst->aio_BackfillPenSel) + Backfill[BackfillCount++] = ni->nim_PaletteSize - 1; + if (IDTA_BACKFILL_NONE != inst->aio_BackfillPenNorm) + Backfill[BackfillCount] = ni->nim_PaletteSize - 2; + + d1(KPrintF("%s/%s/%ld: nim_PaletteSize=%lu aio_BackfillPenNorm=%ld aio_BackfillPenSel=%ld\n", \ + __FILE__, __FUNC__, __LINE__, ni->nim_PaletteSize, inst->aio_BackfillPenNorm, inst->aio_BackfillPenSel)); + + // copy palette from niNormal and adjust colors + for (n = 0, PaletteSrcPtr = niNormal->nim_Palette, PaletteDestPtr = ni->nim_Palette; + n < ni->nim_PaletteSize; n++) + { + if (n == Backfill[0] || n == Backfill[1]) + { + // do not modify backfill colors + *PaletteDestPtr = *PaletteSrcPtr; + } + else + { + PaletteDestPtr->red = (2 * PaletteSrcPtr->red) / 3; + PaletteDestPtr->green = (2 * PaletteSrcPtr->green) / 3; + PaletteDestPtr->blue = (2 * PaletteSrcPtr->blue) / 3; + } + PaletteDestPtr++; + PaletteSrcPtr++; + } + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + // copy image data from niNormal into nim_ImageData + memcpy(ni->nim_ImageData, niNormal->nim_ImageData, ImgSize); + } + else + { + // we have no palette + // 32bit GlowIcon + size_t ISize = niNormal->nim_ARGBheader.argb_Width * niNormal->nim_ARGBheader.argb_Height; + const struct ARGB *Src; + struct ARGB *Dest; + + ni->nim_ARGBheader.argb_Width = niNormal->nim_ARGBheader.argb_Width; + ni->nim_ARGBheader.argb_Height = niNormal->nim_ARGBheader.argb_Height; + + ni->nim_ARGBheader.argb_ImageData = MyAllocVecPooled(ISize * sizeof(struct ARGB)); + + d1(KPrintF("%s/%s/%ld: ISize=%lu argb_ImageData=%08lx\n", __FILE__, __FUNC__, __LINE__, ISize, ni->nim_ARGBheader.argb_ImageData)); + if (NULL == ni->nim_ARGBheader.argb_ImageData) + break; + + // nothing can go wrong from here on + Success = TRUE; + + // Copy image data and adjust RGB values + Src = niNormal->nim_ARGBheader.argb_ImageData; + Dest = ni->nim_ARGBheader.argb_ImageData; + for (n = 0; n < ISize; n++, Src++, Dest++) + { + Dest->Red = (2 * Src->Red ) / 3; + Dest->Green = (2 * Src->Green) / 3; + Dest->Blue = (2 * Src->Blue ) / 3; + Dest->Alpha = Src->Alpha; + } + } + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + } while (0); + + if (!Success) + FreeNewImage(&ni); + + d1(KPrintF("%s/%s/%ld: ni=%08lx\n", __FILE__, __FUNC__, __LINE__, ni)); + + return ni; +} + +//---------------------------------------------------------------------------------------- + +static void *ZLibAlloc(void *p, int items, int size) +{ + return MyAllocVecPooled(items * size); +} + + +static void ZLibFree(void *p, void *addr) +{ + MyFreeVecPooled(addr); +} + +//---------------------------------------------------------------------------------------- + +static SAVEDS(LONG) StreamHookDispatcher(struct Hook *hook, struct IFFHandle *iff, const struct IFFStreamCmd *cmd) +{ + LONG Result = 0; + + switch (cmd->sc_Command) + { + case IFFCMD_INIT: + /* Prepare your stream for reading. This is used for certain + streams that can't be read immediately upon opening, and need + further preparation. (The clipboard.device is an example of + such a stream.) This operation is allowed to fail; any + error code will be returned directly to the client. sc_Buf + and sc_NBytes have no meaning here. */ + break; + case IFFCMD_CLEANUP: + /* Terminate the transaction with the associated stream. This + is used with streams that can't simply be closed. (Again, + the clipboard is an example of such a stream.) This + operation is not permitted to fail; any error returned will + be ignored (best to return 0, though). sc_Buf and sc_NBytes + have no meaning here. */ + break; + case IFFCMD_READ: + /* Read from the stream. You are to read sc_NBytes from the + stream and place them in the buffer pointed to by sc_Buf. + Any (non-zero) error returned will be remapped by the parser + into IFFERR_READ. */ + if (1 != FRead((BPTR)iff->iff_Stream, cmd->sc_Buf, cmd->sc_NBytes, 1)) + Result = IFFERR_READ; + break; + case IFFCMD_WRITE: + /* Write to the stream. You are to write sc_NBytes to the + stream from the buffer pointed to by sc_Buf. Any (non-zero) + error returned will be remapped by the parser into + IFFERR_WRITE. */ + if (1 != FWrite((BPTR)iff->iff_Stream, cmd->sc_Buf, cmd->sc_NBytes, 1)) + Result = IFFERR_WRITE; + d1(KPrintF("%s/%s/%ld: IFFCMD_WRITE Result=%ld sc_NBytes=%ld\n", __FILE__, __FUNC__, __LINE__, Result, cmd->sc_NBytes)); + break; + case IFFCMD_SEEK: + /* Seek on the stream. You are to perform a seek on the stream + relative to the current position. sc_NBytes is signed; + negative values mean seek backward, positive values mean seek + forward. sc_Buf has no meaning here. Any (non-zero) error + returned will be remapped by the parser into IFFERR_SEEK. */ + if (Seek((BPTR)iff->iff_Stream, cmd->sc_NBytes, OFFSET_CURRENT) < 0) + Result = IFFERR_SEEK; + d1(KPrintF("%s/%s/%ld: IFFCMD_SEEK Result=%ld sc_NBytes=%ld\n", __FILE__, __FUNC__, __LINE__, Result, cmd->sc_NBytes)); + break; + default: + break; + } + + return Result; +} + +//---------------------------------------------------------------------------------------- + +static void SetParentAttributes(Class *cl, Object *o) +{ + struct InstanceData *inst = INST_DATA(cl, o); + + TIMESTAMP_d1(); + SetAttrs(o, + GA_Width, inst->aio_Image1->nim_Width, + GA_Height, inst->aio_Image1->nim_Height, + TAG_END); + d1(KPrintF("%s/%s/%ld: o=%08lx Image1 nim_Palette=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst->aio_Image1->nim_Palette)); + + if (NULL == inst->aio_Image1->nim_Palette) + { + // 32bit GlowIcon + SetAttrs(o, + IDTA_CopyARGBImageData, FALSE, + IDTA_ARGBImageData, (ULONG) &inst->aio_Image1->nim_ARGBheader, + TAG_END); + } + TIMESTAMP_d1(); + if (inst->aio_Image2 && NULL == inst->aio_Image2->nim_Palette) + { + // 32bit GlowIcon + SetAttrs(o, + IDTA_CopySelARGBImageData, FALSE, + IDTA_SelARGBImageData, (ULONG) &inst->aio_Image2->nim_ARGBheader, + TAG_END); + } + + if (inst->aio_Image1->nim_Palette) + { + TIMESTAMP_d1(); + GenerateNormalImageMask(cl, o); + TIMESTAMP_d1(); + GenerateSelectedImageMask(cl, o); + TIMESTAMP_d1(); + } + + TIMESTAMP_d1(); + + if (inst->aio_DiskObject->do_DrawerData) + { + TIMESTAMP_d1(); + SetAttrs(o, + IDTA_ViewModes, inst->aio_DiskObject->do_DrawerData->dd_ViewModes, + IDTA_Flags, inst->aio_DiskObject->do_DrawerData->dd_Flags, + IDTA_WinCurrentX, inst->aio_DiskObject->do_DrawerData->dd_CurrentX, + IDTA_WinCurrentY, inst->aio_DiskObject->do_DrawerData->dd_CurrentY, + IDTA_WindowRect, (ULONG) &inst->aio_DiskObject->do_DrawerData->dd_NewWindow, + TAG_END); + } + TIMESTAMP_d1(); + SetAttrs(o, + IDTA_ToolTypes, (ULONG) inst->aio_DiskObject->do_ToolTypes, + IDTA_Stacksize, inst->aio_DiskObject->do_StackSize, + IDTA_DefaultTool, (ULONG) inst->aio_DiskObject->do_DefaultTool, + IDTA_Type, inst->aio_DiskObject->do_Type, + IDTA_Borderless, inst->aio_Borderless, + TAG_END); +} + +//---------------------------------------------------------------------------------------- + +#if defined(__AROS__) +static BOOL ReadConvertStandardIcon(BPTR fd, struct DiskObject *dobj) +{ + BOOL success = FALSE; + + APTR block = MyAllocVecPooled(78); // sizeof struct DiskObject on 68k + if (NULL != block) + { + if (78 == FRead(fd, block, 1, 78)) + { + dobj->do_Magic = SCA_BE2WORD(*(WORD *)block); + dobj->do_Version = SCA_BE2WORD(*(WORD *)(block + 2)); + // Ignore 4 + dobj->do_Gadget.LeftEdge = SCA_BE2WORD(*(WORD *)(block + 8)); + dobj->do_Gadget.TopEdge = SCA_BE2WORD(*(WORD *)(block + 10)); + dobj->do_Gadget.Width = SCA_BE2WORD(*(WORD *)(block + 12)); + dobj->do_Gadget.Height = SCA_BE2WORD(*(WORD *)(block + 14)); + dobj->do_Gadget.Flags = SCA_BE2WORD(*(WORD *)(block + 16)); + dobj->do_Gadget.Activation = SCA_BE2WORD(*(WORD *)(block + 18)); + dobj->do_Gadget.GadgetType = SCA_BE2WORD(*(WORD *)(block + 20)); + dobj->do_Gadget.GadgetRender = (APTR)SCA_BE2LONG(*(LONG *)(block + 22)); + dobj->do_Gadget.SelectRender = (APTR)SCA_BE2LONG(*(LONG *)(block + 26)); + dobj->do_Gadget.GadgetText = (APTR)SCA_BE2LONG(*(LONG *)(block + 30)); + dobj->do_Gadget.MutualExclude = SCA_BE2LONG(*(LONG *)(block + 34)); + dobj->do_Gadget.SpecialInfo = (APTR)SCA_BE2LONG(*(LONG *)(block + 38)); + dobj->do_Gadget.GadgetID = SCA_BE2WORD(*(WORD *)(block + 42)); + dobj->do_Gadget.UserData = (APTR)SCA_BE2LONG(*(LONG *)(block + 44)); + dobj->do_Type = *(BYTE *)(block + 48); + // Ignore 1 + dobj->do_DefaultTool = (APTR)SCA_BE2LONG(*(LONG *)(block + 50)); + dobj->do_ToolTypes = (APTR)SCA_BE2LONG(*(LONG *)(block + 54)); + dobj->do_CurrentX = SCA_BE2LONG(*(LONG *)(block + 58)); + dobj->do_CurrentY = SCA_BE2LONG(*(LONG *)(block + 62)); + dobj->do_DrawerData = (APTR)SCA_BE2LONG(*(LONG *)(block + 66)); + dobj->do_ToolWindow = (APTR)SCA_BE2LONG(*(LONG *)(block + 70)); + dobj->do_StackSize = SCA_BE2LONG(*(LONG *)(block + 74)); + + success = TRUE; + } + MyFreeVecPooled(block); + } + return success; +} + +//---------------------------------------------------------------------------------------- + +static BOOL WriteConvertStandardIcon(BPTR fd, struct DiskObject *dobj) +{ + BOOL success = FALSE; + + APTR block = MyAllocVecPooled(78); // sizeof struct DiskObject on 68k + if (NULL != block) + { + memset(block, 0, 78); + *(WORD *)block = SCA_WORD2BE(dobj->do_Magic); + *(WORD *)(block + 2) = SCA_WORD2BE(dobj->do_Version); + // Ignore 4 + *(WORD *)(block + 8) = SCA_WORD2BE(dobj->do_Gadget.LeftEdge); + *(WORD *)(block + 10) = SCA_WORD2BE(dobj->do_Gadget.TopEdge); + *(WORD *)(block + 12) = SCA_WORD2BE(dobj->do_Gadget.Width); + *(WORD *)(block + 14) = SCA_WORD2BE(dobj->do_Gadget.Height); + *(WORD *)(block + 16) = SCA_WORD2BE(dobj->do_Gadget.Flags); + *(WORD *)(block + 18) = SCA_WORD2BE(dobj->do_Gadget.Activation); + *(WORD *)(block + 20) = SCA_WORD2BE(dobj->do_Gadget.GadgetType); + *(LONG *)(block + 22) = SCA_LONG2BE((LONG)dobj->do_Gadget.GadgetRender); + *(LONG *)(block + 26) = SCA_LONG2BE((LONG)dobj->do_Gadget.SelectRender); + *(LONG *)(block + 30) = SCA_LONG2BE((LONG)dobj->do_Gadget.GadgetText); + *(LONG *)(block + 34) = SCA_LONG2BE(dobj->do_Gadget.MutualExclude); + *(LONG *)(block + 38) = SCA_LONG2BE((LONG)dobj->do_Gadget.SpecialInfo); + *(WORD *)(block + 42) = SCA_WORD2BE(dobj->do_Gadget.GadgetID); + *(LONG *)(block + 44) = SCA_LONG2BE((LONG)dobj->do_Gadget.UserData); + *(BYTE *)(block + 48) = dobj->do_Type; + // Ignore 1 + *(LONG *)(block + 50) = SCA_LONG2BE((LONG)dobj->do_DefaultTool); + *(LONG *)(block + 54) = SCA_LONG2BE((LONG)dobj->do_ToolTypes); + *(LONG *)(block + 58) = SCA_LONG2BE(dobj->do_CurrentX); + *(LONG *)(block + 62) = SCA_LONG2BE(dobj->do_CurrentY); + *(LONG *)(block + 66) = SCA_LONG2BE((LONG)dobj->do_DrawerData); + *(LONG *)(block + 70) = SCA_LONG2BE((LONG)dobj->do_ToolWindow); + *(LONG *)(block + 74) = SCA_LONG2BE(dobj->do_StackSize); + + if (78 == FWrite(fd, block, 1, 78)) + success = TRUE; + + MyFreeVecPooled(block); + } + return success; +} + +//---------------------------------------------------------------------------------------- + +static BOOL ReadConvertDrawerData(BPTR fd, struct DrawerData *drawer) +{ + BOOL success = FALSE; + + APTR block = MyAllocVecPooled(56); // sizeof struct OldDrawerData on 68k + if (NULL != block) + { + if (56 == FRead(fd, block, 1, 56)) + { + drawer->dd_NewWindow.LeftEdge = SCA_BE2WORD(*(WORD *)block); + drawer->dd_NewWindow.TopEdge = SCA_BE2WORD(*(WORD *)(block + 2)); + drawer->dd_NewWindow.Width = SCA_BE2WORD(*(WORD *)(block + 4)); + drawer->dd_NewWindow.Height = SCA_BE2WORD(*(WORD *)(block + 6)); + drawer->dd_NewWindow.DetailPen = *(BYTE *)(block + 8); + drawer->dd_NewWindow.BlockPen = *(BYTE *)(block + 9); + drawer->dd_NewWindow.IDCMPFlags = SCA_BE2LONG(*(LONG *)(block + 10)); + drawer->dd_NewWindow.Flags = SCA_BE2LONG(*(LONG *)(block + 14)); + // Ignore 20 + drawer->dd_NewWindow.MinWidth = SCA_BE2WORD(*(WORD *)(block + 38)); + drawer->dd_NewWindow.MinHeight = SCA_BE2WORD(*(WORD *)(block + 40)); + drawer->dd_NewWindow.MaxWidth = SCA_BE2WORD(*(WORD *)(block + 42)); + drawer->dd_NewWindow.MaxHeight = SCA_BE2WORD(*(WORD *)(block + 44)); + drawer->dd_NewWindow.Type = SCA_BE2WORD(*(WORD *)(block + 46)); + drawer->dd_CurrentX = SCA_BE2LONG(*(LONG *)(block + 48)); + drawer->dd_CurrentY = SCA_BE2LONG(*(LONG *)(block + 52)); + + success = TRUE; + } + MyFreeVecPooled(block); + } + return success; +} + +//---------------------------------------------------------------------------------------- + +static BOOL WriteConvertDrawerData(BPTR fd, struct DrawerData *drawer) +{ + BOOL success = FALSE; + + APTR block = MyAllocVecPooled(56); // sizeof struct OldDrawerData on 68k + if (NULL != block) + { + memset(block, 0, 56); + *(WORD *)block = SCA_WORD2BE(drawer->dd_NewWindow.LeftEdge); + *(WORD *)(block + 2) = SCA_WORD2BE(drawer->dd_NewWindow.TopEdge); + *(WORD *)(block + 4) = SCA_WORD2BE(drawer->dd_NewWindow.Width); + *(WORD *)(block + 6) = SCA_WORD2BE(drawer->dd_NewWindow.Height); + *(BYTE *)(block + 8) = drawer->dd_NewWindow.DetailPen; + *(BYTE *)(block + 9) = drawer->dd_NewWindow.BlockPen; + *(LONG *)(block + 10) = SCA_LONG2BE(drawer->dd_NewWindow.IDCMPFlags); + *(LONG *)(block + 14) = SCA_LONG2BE(drawer->dd_NewWindow.Flags); + // Ignore 20 + *(WORD *)(block + 38) = SCA_WORD2BE(drawer->dd_NewWindow.MinWidth); + *(WORD *)(block + 40) = SCA_WORD2BE(drawer->dd_NewWindow.MinHeight); + *(WORD *)(block + 42) = SCA_WORD2BE(drawer->dd_NewWindow.MaxWidth); + *(WORD *)(block + 44) = SCA_WORD2BE(drawer->dd_NewWindow.MaxHeight); + *(WORD *)(block + 46) = SCA_WORD2BE(drawer->dd_NewWindow.Type); + *(LONG *)(block + 48) = SCA_LONG2BE(drawer->dd_CurrentX); + *(LONG *)(block + 52) = SCA_LONG2BE(drawer->dd_CurrentY); + + if (56 == FWrite(fd, block, 1, 56)) + success = TRUE; + + MyFreeVecPooled(block); + } + return success; +} + +//---------------------------------------------------------------------------------------- + +static BOOL ReadConvertImage(BPTR fd, struct Image *img) +{ + BOOL success = FALSE; + + APTR block = MyAllocVecPooled(20); // sizeof struct Image on 68k + if (NULL != block) + { + if (20 == FRead(fd, block, 1, 20)) + { + img->LeftEdge = SCA_BE2WORD(*(WORD *)block); + img->TopEdge = SCA_BE2WORD(*(WORD *)(block + 2)); + img->Width = SCA_BE2WORD(*(WORD *)(block + 4)); + img->Height = SCA_BE2WORD(*(WORD *)(block + 6)); + img->Depth = SCA_BE2WORD(*(WORD *)(block + 8)); + img->ImageData = (APTR)SCA_BE2LONG(*(LONG *)(block + 10)); + img->PlanePick = *(BYTE *)(block + 14); + img->PlaneOnOff = *(BYTE *)(block + 15); + img->NextImage = (APTR)SCA_BE2LONG(*(LONG *)(block + 16)); + + success = TRUE; + } + + MyFreeVecPooled(block); + } + + return success; +} + +//---------------------------------------------------------------------------------------- + +static BOOL WriteConvertImage(BPTR fd, struct Image *img) +{ + BOOL success = FALSE; + + APTR block = MyAllocVecPooled(20); // sizeof struct Image on 68k + if (NULL != block) + { + memset(block, 0, 20); + *(WORD *)block = SCA_WORD2BE(img->LeftEdge); + *(WORD *)(block + 2) = SCA_WORD2BE(img->TopEdge) ; + *(WORD *)(block + 4) = SCA_WORD2BE(img->Width); + *(WORD *)(block + 6) = SCA_WORD2BE(img->Height); + *(WORD *)(block + 8) = SCA_WORD2BE(img->Depth); + *(LONG *)(block + 10) = SCA_LONG2BE((LONG)img->ImageData); + *(BYTE *)(block + 14) = img->PlanePick; + *(BYTE *)(block + 15) = img->PlaneOnOff; + *(LONG *)(block + 16) = SCA_LONG2BE((LONG)img->NextImage); + + if (20 == FWrite(fd, block, 1, 20)) + success = TRUE; + + MyFreeVecPooled(block); + } + return success; +} +#endif + +//---------------------------------------------------------------------------------------- + +#ifndef __amigaos4__ +void exit(int x) +{ + (void) x; + while (1) + ; +} +#endif /* __amigaos4__ */ + +//---------------------------------------------------------------------------------------- + diff --git a/scalos/datatypes/GlowIconObject/GlowIconObject.h b/scalos/datatypes/GlowIconObject/GlowIconObject.h new file mode 100644 index 000000000..091e49178 --- /dev/null +++ b/scalos/datatypes/GlowIconObject/GlowIconObject.h @@ -0,0 +1,270 @@ +// GlowIconObject.h +// $Date$ +// $Revision$ + + +#ifndef GLOWICONOBJECT_H_INCLUDED +#define GLOWICONOBJECT_H_INCLUDED + +#include +#include +#include +#include +#include +#include + +#include + +//----------------------------------------------------------------------------- + +#define MEMPOOL_MEMFLAGS MEMF_PUBLIC +#define MEMPOOL_PUDDLESIZE 16384 +#define MEMPOOL_THRESHSIZE 16384 + +//----------------------------------------------------------------------------- + +#define LIB_VERSION 40 +#define LIB_REVISION 14 + +extern char ALIGNED libName[]; +extern char ALIGNED libIdString[]; + +//----------------------------------------------------------------------------- + +#define BYTESPERROW(width) ((((width) + 15) & 0xfff0) >> 3) + +// Width for TempRp.BitMap for ReadPixelLine8() and WritePixelLine8() +#define TEMPRP_WIDTH(width) (8 * ((((width) + 15) >> 4) << 1)) + +//----------------------------------------------------------------------------- + +#ifndef __AROS__ +#define BNULL ((BPTR) NULL) +#endif + +//----------------------------------------------------------------------------- + +#define ID_ICON MAKE_ID('I','C','O','N') +#define ID_FACE MAKE_ID('F','A','C','E') +#define ID_IMAG MAKE_ID('I','M','A','G') +#define ID_ARGB MAKE_ID('A','R','G','B') + +//----------------------------------------------------------------------------- + +struct GlowIconObjectDtLibBase + { + struct ClassLibrary nib_ClassLibrary; + + struct SegList *nib_SegList; + + UBYTE nib_Initialized; + }; + +//---------------------------------------------------------------------------- + +LIBFUNC_PROTO(ObtainInfoEngine, libbase, ULONG); + +ULONG InitDatatype(struct GlowIconObjectDtLibBase *dtLib); +ULONG OpenDatatype(struct GlowIconObjectDtLibBase *dtLib); +void CloseDatatype(struct GlowIconObjectDtLibBase *dtLib); + +/* ------------------------------------------------- */ + +#if defined(__GNUC__) && !defined(mc68000) +#pragma pack(2) +#endif /* __GNUC__ */ + +struct FaceChunk /* 6 Bytes */ + { + UBYTE fc_Width; // Width - 1 + UBYTE fc_Height; // Height - 1 + UBYTE fc_Flags; + UBYTE fc_AspectRatio; + UWORD fc_MaxPaletteBytes; + }; + +// Values in fc_Flags +#define FCB_Borderless 0 +#define FCF_Borderless (1 << FCB_Borderless) + +/* ------------------------------------------------- */ + +struct ImageChunk /* 10 Bytes */ + { + UBYTE ic_TransparentColor; // index of transparent color + UBYTE ic_PaletteSize; // number of palette entries - 1 + UBYTE ic_Flags; // see below + UBYTE ic_ImageCompressionType; // compression type - imagedata ? + UBYTE ic_PaletteCompressionType; // compression type - palette ? + UBYTE ic_BitsPerPixel; // number of significant bits/pixel + UWORD ic_NumImageBytes; // number of compressed image bytes - 1 + UWORD ic_NumPaletteBytes; // number of compressed palette bytes - 1 + }; + +#define ICB_IsTransparent 0 +#define ICF_IsTransparent (1 << ICB_IsTransparent) +#define ICB_HasPalette 1 +#define ICF_HasPalette (1 << ICB_HasPalette) + +#if defined(__GNUC__) && !defined(mc68000) +#pragma pack(2) +#endif /* __GNUC__ */ + +/* ------------------------------------------------- */ + +struct NewImage + { + WORD nim_Width; + WORD nim_Height; + + struct ImageChunk nim_ImageChunk; + + UWORD nim_PaletteSize; // number of palette entries + + UBYTE *nim_ImageData; // (allocated) chunky image data, 1 byte per pixel + + struct ColorRegister *nim_Palette; // (allocated) palette data, NULL for 32bit GlowIcons + + struct ARGBHeader nim_ARGBheader; + }; + +//----------------------------------------------------------------------------- + +struct NewImagePenList + { + ULONG nip_PaletteSize; + UBYTE *nip_PenArray; // Array of allocated pens for Normal image, 1 byte per pen + }; + +//----------------------------------------------------------------------------- + +struct InstanceData + { + struct DiskObject *aio_DiskObject; + struct DrawerData *aio_myDrawerData; + struct Screen *aio_Screen; + + UWORD aio_ImageLeft; + UWORD aio_ImageTop; + + UBYTE aio_Borderless; //Flag: Don't draw border around icon! + + struct Image aio_DoImage1; //diskObj.do_Gadget.GadgetRender + struct Image aio_DoImage2; + + struct FaceChunk aio_FaceChunk; + + STRPTR aio_DefaultTool; + STRPTR aio_ToolWindow; + STRPTR *aio_ToolTypes; + ULONG aio_ToolTypesLength; // Allocated length for aio_ToolTypes + + struct NewImage *aio_Image1; // Normal image + struct NewImage *aio_Image2; // Selected image + + struct NewImagePenList aio_PenList1; // pen list for Normal image + struct NewImagePenList aio_PenList2; // pen list for selected image + + ULONG aio_BackfillPenNorm; // pen to use for unselected background fill or IDTA_BACKFILL_NONE + ULONG aio_BackfillPenSel; // pen to use for selected background fill or IDTA_BACKFILL_NONE + }; + +//--------------------------------------------------------------- + +// private and temporary Data during dtWrite + +struct WriteData + { + STRPTR aiowd_DefaultTool; + STRPTR *aiowd_ToolTypes; + ULONG aiowd_StackSize; + struct IBox *aiowd_WindowRect; + ULONG aiowd_CurrentX; + ULONG aiowd_CurrentY; + ULONG aiowd_Flags; + ULONG aiowd_ViewModes; + ULONG aiowd_Type; + }; + +/* ------------------------------------------------- */ + +#define UGetByte() (*source++) +#define UPutByte(c) (*dest++ = (c)) + +/* ------------------------------------------------- */ + +#define Sizeof(x) (sizeof(x) / sizeof(x[0])) + +//----------------------------------------------------------------------------- + +// defined in mempools.lib + +extern int _STI_240_InitMemFunctions(void); +extern void _STD_240_TerminateMemFunctions(void); + +/* ------------------------------------------------- */ + +// from debug.lib +#ifdef __AROS__ +#include +#define KPrintF kprintf +#else +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); +#endif + + +#define d1(x) ; +#define d2(x) { Forbid(); x; Permit(); } + +//#define TIMESTAMPS +#define TIMESTAMP_d1() ; +#define TIMESTAMP_d2() \ + { \ + struct EClockVal ev; \ + ULONG ticks; \ + ticks = ReadEClock(&ev); \ + KPrintF("%s/%s/%ld: ticks=%lu hi=%8lu lo=%8lu\n", __FILE__, __FUNC__, __LINE__, ticks, ev.ev_hi, ev.ev_lo); \ + } + +/* ------------------------------------------------- */ + +#if !defined(__amigaos4__) && !defined(__AROS__) +VOID UpdateWorkbench(CONST_STRPTR name, BPTR parentlock, LONG action); + +#if defined(__MORPHOS__) + +#ifndef __PPCINLINE_MACROS_H +#include +#endif /* !__PPCINLINE_MACROS_H */ + +#define UpdateWorkbench(__p0, __p1, __p2) \ + LP3NR(30, UpdateWorkbench, \ + CONST_STRPTR , __p0, a0, \ + BPTR, __p1, a1, \ + LONG, __p2, d0, \ + , WB_BASE_NAME, 0, 0, 0, 0, 0, 0) + +#else + +#ifdef __SASC + +#ifdef __CLIB_PRAGMA_LIBCALL +#pragma libcall WorkbenchBase UpdateWorkbench 01e 09803 +#endif /* __CLIB_PRAGMA_LIBCALL */ + +#else + +#define WBInfo(lock, name, screen) \ + LP3NR(30, UpdateWorkbench, CONST_STRPTR, name, a0, BPTR, parentlock, a1, LONG, action, d0, \ + , WB_BASE_NAME) + +#endif /* __SASC */ + +#endif /* __MORPHOS__ */ + +#endif /* !__amigaos4__ */ + +/* ------------------------------------------------- */ + +#endif // GLOWICONOBJECT_H_INCLUDED diff --git a/scalos/datatypes/GlowIconObject/config.mk b/scalos/datatypes/GlowIconObject/config.mk new file mode 100755 index 000000000..323ad18eb --- /dev/null +++ b/scalos/datatypes/GlowIconObject/config.mk @@ -0,0 +1,54 @@ +# $Date: 2012-08-10 13:47:28 +0200 (Fr, 10. Aug 2012) $ +# $Revision: 915 $ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +MKDIR = mkdir -p #makedir force +DT_DIR = scalos:IconDatatypes/datatypes + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS := -nostartfiles \ + -lz \ + -lmempools \ + $(LFLAGS) \ +# --verbose + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += -nostartfiles \ + -lz \ +# + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +LFLAGS += -nostartfiles -larossupport -lz + +else +############################################################################### +# AmigaOS + +LFLAGS += -ldebug -lmcpgfx -lnix -lamiga -lstubs + +endif +endif +endif diff --git a/scalos/datatypes/GlowIconObject/makefile b/scalos/datatypes/GlowIconObject/makefile new file mode 100644 index 000000000..8b2287bd0 --- /dev/null +++ b/scalos/datatypes/GlowIconObject/makefile @@ -0,0 +1,112 @@ +# makefile für Scalos IconObject datatypes stuff +# $Date$ +# $Revision$ +##################################################################### + +ASRCS = +CSRCS = GlowIconObject-classic.c GlowIconObject.c + +##################################################################### + +AS = phxAss +SPLAT = sc:c/splat +LD = slink +CC = sc +MKDIR = mkdir -p #makedir force +LIBS = LIB:debug.lib \ + //SAS-lib/z.lib \ + LIB:mempools.lib \ + LIB:sc.lib \ + LIB:amiga.lib +PRECOMP = Include:all.gst +DT_DIR = scalos:IconDatatypes/datatypes +OBJDIR = .sasobj + +.SUFFIXES: .asm + +############################################################# + +.PHONY: clean install nodebug + +##################################################################### + +CFLAGS = optimize nostackcheck nochkabort strcons nover \ + ignore=306 streq dbg=f idir=//include +LNFLAGS = batch noicons stripdebug quiet +LNDBFLAGS = batch noicons addsym quiet + +ifdef L +AFLAGS = QUIET DS NOEXE opt=NRQB LIST=* linedebug I=SC:Assembler_Headers +else +AFLAGS = QUIET DS NOEXE opt=NRQB linedebug I=SC:Assembler_Headers +endif + +##################################################################### + +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(CSRCS:%.c=$(OBJDIR)/%.o) + +##################################################################### + +DTNAME = .bin_os3/glowiconobject.datatype +DTDBGNAME = $(DTNAME).debug + +##################################################################### + +all: $(DTNAME) \ + $(DTDBGNAME) + +##################################################################### + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +##################################################################### + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $* objectname $@ + +$(OBJDIR)/%.o : %.s + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +$(OBJDIR)/%.o : %.asm + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +##################################################################### + +$(DTNAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) from $(OBJS) to $(DTNAME) LIB $(LIBS) $(LNFLAGS) + +$(DTDBGNAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) from $(OBJS) to $(DTDBGNAME) LIB $(LIBS) $(LNDBFLAGS) + +##################################################################### + +$(OBJDIR)/GlowIconObject-classic.o : GlowIconObject.h +$(OBJDIR)/GlowIconObject.o : GlowIconObject.h + +##################################################################### + +install: + @printf '\033[32mFlushing memory...\033[0m\n' + avail flush + @printf '\033[32mInstall: \033[31m\033[1m$(DTNAME)\033[0m\n' + -@$(MKDIR) $(DT_DIR) + copy $(DTNAME) $(DT_DIR) + +##################################################################### + +clean: + -@delete $(DTNAME) $(DTDBGNAME) $(OBJS) + +############################################################# + +nodebug: + -@$(SPLAT) -s -o "d2(" "d1(" "#?.c" + +##################################################################### + diff --git a/scalos/datatypes/GlowIconObject/makefile-new b/scalos/datatypes/GlowIconObject/makefile-new new file mode 100755 index 000000000..985c8ce9a --- /dev/null +++ b/scalos/datatypes/GlowIconObject/makefile-new @@ -0,0 +1,73 @@ +# $Date: 2011-07-09 20:50:13 +0200 (Sa, 09. Jul 2011) $ +# $Revision: 759 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +ifeq ($(MACHINE), ppc-amigaos) +OBJS = $(OBJDIR)/GlowIconObject-aos4.o $(OBJDIR)/GlowIconObject.o +else +ifeq ($(MACHINE), i386-aros) +OBJS = $(OBJDIR)/GlowIconObject-aros.o $(OBJDIR)/GlowIconObject.o +else +OBJS = $(OBJDIR)/GlowIconObject-classic.o $(OBJDIR)/GlowIconObject.o +endif +endif + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Targets +# + +NAME = glowiconobject.datatype +NAME_DB = glowiconobject.datatype.debug + +############################################################################## + +.PHONY: all install clean bump dump + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + @$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + -@$(MKDIR) $(DT_DIR) + @copy $(BINDIR)/$(NAME) $(DT_DIR) + @avail flush + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* + +############################################################################## diff --git a/scalos/datatypes/IconObject/argb.c b/scalos/datatypes/IconObject/argb.c new file mode 100644 index 000000000..e4b7d1ab0 --- /dev/null +++ b/scalos/datatypes/IconObject/argb.c @@ -0,0 +1,435 @@ +// argb.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#define __USE_SYSBASE +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include "iconobj.h" + +//---------------------------------------------------------------------------- + +#define min(a,b) ((a) < (b) ? (a) : (b)) + +//---------------------------------------------------------------------------- + +extern struct Library *CyberGfxBase; + +//----------------------------------------------------------------------------- + +static void WriteARGBArray(const struct ARGB *src, struct RastPort *dst, + ULONG dstx, ULONG dsty, ULONG width, ULONG height); +static void DrawFrame(Object *o, struct InstanceData *inst, struct RastPort *rp, + LONG x, LONG y, UWORD FrameType); +static BOOL GenMaskFromARGB(const struct IconObjectARGB *img, const struct IconObjectARGB *CloneImage, + struct IconObjectMask *Mask, const struct IconObjectMask *CloneMask); + +//----------------------------------------------------------------------------- + +void ARGB_Draw(Class *cl, Object *o, struct iopDraw *opd, LONG x, LONG y) +{ + struct InstanceData *inst = INST_DATA(cl, o); + struct ExtGadget *gg = (struct ExtGadget *) o; + struct ARGBHeader *ImgHeader; + struct IconObjectARGB *img; + + if ((gg->Flags & GFLG_SELECTED) && inst->iobj_SelectedARGB.iargb_ARGBimage.argb_ImageData) + { + img = &inst->iobj_SelectedARGB; + } + else + { + img = &inst->iobj_NormalARGB; + } + + if (img->iargb_ScaledARGBImage.argb_ImageData) + ImgHeader = &img->iargb_ScaledARGBImage; + else + ImgHeader = &img->iargb_ARGBimage; + + d1(KPrintF("%s/%s/%ld: x=%ld y=%ld w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, x, y, ImgHeader->argb_Width, ImgHeader->argb_Height)); + d1(KPrintF("%s/%s/%ld: o=%08lx ImgData=%08lx\n", __FILE__, __FUNC__, __LINE__, o, ImgHeader->argb_ImageData)); + d1(kprintf("%s/%s/%ld: ImgData[]=%08lx %08lx %08lx %08lx\n", __FILE__, __FUNC__, __LINE__, \ + ImgHeader->argb_ImageData[0], ImgHeader->argb_ImageData[1], ImgHeader->argb_ImageData[2], ImgHeader->argb_ImageData[3])); + + if (!(IODRAWF_NoImage & opd->iopd_DrawFlags)) + { + if (!(IODRAWF_NoEraseBg & opd->iopd_DrawFlags)) + EraseRect(opd->iopd_RastPort, x, y, x + gg->Width, y + gg->Height); + + if (NULL == CyberGfxBase) + { + Move(opd->iopd_RastPort, x + inst->iobj_imgleft, y + inst->iobj_imgtop); + + Draw(opd->iopd_RastPort, x + inst->iobj_imgleft + gg->Width, y + inst->iobj_imgtop); + Draw(opd->iopd_RastPort, x + inst->iobj_imgleft + gg->Width, y + inst->iobj_imgtop + gg->Height); + Draw(opd->iopd_RastPort, x + inst->iobj_imgleft, y + inst->iobj_imgtop + gg->Height); + Draw(opd->iopd_RastPort, x + inst->iobj_imgleft, y + inst->iobj_imgtop); + } + else + { + if (gg->Flags & GFLG_SELECTED) + { + struct ARGB K = { 0, 96, 96, 144 }; + + if (IODRAWF_NoAlpha & opd->iopd_DrawFlags) + { + if (img == &inst->iobj_SelectedARGB) + { + // draw selected image + WriteARGBArray(ImgHeader->argb_ImageData, opd->iopd_RastPort, + x + inst->iobj_imgleft, y + inst->iobj_imgtop, + ImgHeader->argb_Width, ImgHeader->argb_Height); + } + else + { + // draw highlighted variant of normal image + struct IBox SrcSize; + + SrcSize.Left = SrcSize.Top = 0; + SrcSize.Width = ImgHeader->argb_Width; + SrcSize.Height = ImgHeader->argb_Height; + + ScalosGfxBlitARGBAlphaTags(opd->iopd_RastPort, + ImgHeader, + x + inst->iobj_imgleft, y + inst->iobj_imgtop, + &SrcSize, + SCALOSGFX_BlitARGBHilight, (ULONG) &K, + SCALOSGFX_BlitARGBTransparency, 200, + SCALOSGFX_BlitARGBNoAlpha, TRUE, + TAG_END); + } + } + else + { + if (img == &inst->iobj_SelectedARGB) + { + // draw selected image + ScalosGfxBlitARGBAlpha(opd->iopd_RastPort, + ImgHeader, + x + inst->iobj_imgleft, y + inst->iobj_imgtop, + 0, 0, + ImgHeader->argb_Width, ImgHeader->argb_Height); + } + else + { + // draw highlighted variant of normal image + struct IBox SrcSize; + + SrcSize.Left = SrcSize.Top = 0; + SrcSize.Width = ImgHeader->argb_Width; + SrcSize.Height = ImgHeader->argb_Height; + + ScalosGfxBlitARGBAlphaTags(opd->iopd_RastPort, + ImgHeader, + x + inst->iobj_imgleft, y + inst->iobj_imgtop, + &SrcSize, + SCALOSGFX_BlitARGBHilight, (ULONG) &K, + SCALOSGFX_BlitARGBTransparency, 200, + TAG_END); + } + } + if (!inst->iobj_Borderless && inst->iobj_imgleft > 0 && inst->iobj_imgtop > 0) + DrawFrame(o, inst, opd->iopd_RastPort, x, y, inst->iobj_frametypesel); + } + else + { + if (IODRAWF_NoAlpha & opd->iopd_DrawFlags) + { + WriteARGBArray(ImgHeader->argb_ImageData, opd->iopd_RastPort, + x + inst->iobj_imgleft, y + inst->iobj_imgtop, + ImgHeader->argb_Width, ImgHeader->argb_Height); + } + else + { + ScalosGfxBlitARGBAlpha(opd->iopd_RastPort, + ImgHeader, + x + inst->iobj_imgleft, y + inst->iobj_imgtop, + 0, 0, + ImgHeader->argb_Width, ImgHeader->argb_Height); + } + if (!inst->iobj_Borderless && inst->iobj_imgleft > 0 && inst->iobj_imgtop > 0) + DrawFrame(o, inst, opd->iopd_RastPort, x, y, inst->iobj_frametype); + } + } + } +} + +//----------------------------------------------------------------------------- + +static void WriteARGBArray(const struct ARGB *src, struct RastPort *dst, + ULONG dstx, ULONG dsty, ULONG width, ULONG height) +{ + WritePixelArray((APTR) src, 0, 0, + width * sizeof(struct ARGB), + dst, dstx, dsty, + width, height, RECTFMT_ARGB); +} + +//----------------------------------------------------------------------------- + +static void DrawFrame(Object *o, struct InstanceData *inst, struct RastPort *rp, + LONG x, LONG y, UWORD FrameType) +{ + struct RastPort rpCopy; + struct ExtGadget *gg = (struct ExtGadget *) o; + + rpCopy = *rp; + + d1(kprintf("%s/%s/%ld: xMin=%ld yMin=%ld xMax=%ld yMax=%ld\n", \ + __FILE__, __FUNC__, __LINE__, x, y, x + gg->Width - 1, y + gg->Height - 1)); + + McpGfxDrawFrame(&rpCopy, x, y, x + gg->Width - 1, y + gg->Height - 1, + IA_HalfShinePen, inst->iobj_HalfShinePen, + IA_HalfShadowPen, inst->iobj_HalfShadowPen, + IA_FrameType, FrameType & 0x7fff, + IA_Recessed, (FrameType & 0x8000) ? 1 : 0, + TAG_END); +} + +//----------------------------------------------------------------------------- + +BOOL GenMasksFromARGB(Class *cl, Object *o) +{ + struct InstanceData *inst = INST_DATA(cl, o); + + d1(KPrintF("%s/%s/%ld: START o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + + if (!GenMaskFromARGB(&inst->iobj_NormalARGB, NULL, + &inst->iobj_NormalMask, NULL)) + return FALSE; + + d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + + return GenMaskFromARGB(&inst->iobj_SelectedARGB, &inst->iobj_NormalARGB, + &inst->iobj_SelectedMask, &inst->iobj_NormalMask); +} + +//----------------------------------------------------------------------------- + +static BOOL GenMaskFromARGB(const struct IconObjectARGB *img, const struct IconObjectARGB *CloneImage, + struct IconObjectMask *Mask, const struct IconObjectMask *CloneMask) +{ + const struct ARGBHeader *ImgHeader; + const struct ARGB *PicPtr; + ULONG BytesPerRow; + const struct IconObjectARGB *imgUsed; + size_t Size; + + d1(KPrintF( "%s/%s/%ld: img=%08lx CloneImage=%08lx\n", __FILE__, __FUNC__, __LINE__, img, CloneImage)); + d1(KPrintF( "%s/%s/%ld: Mask=%08lx CloneMask=%08lx\n", __FILE__, __FUNC__, __LINE__, Mask, CloneMask)); + + imgUsed = img->iargb_ARGBimage.argb_ImageData ? img : CloneImage; + + if (NULL == imgUsed) + return FALSE; + + d1(KPrintF( "%s/%s/%ld: iargb_ScaledARGBImage=%08lx w=%ld h=%ld ImageData=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + &imgUsed->iargb_ScaledARGBImage, \ + imgUsed->iargb_ScaledARGBImage.argb_Width, \ + imgUsed->iargb_ScaledARGBImage.argb_Height, \ + imgUsed->iargb_ScaledARGBImage.argb_ImageData)); + d1(KPrintF( "%s/%s/%ld: iargb_ARGBimage=%08lx w=%ld h=%ld ImageData=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + &imgUsed->iargb_ARGBimage, \ + imgUsed->iargb_ARGBimage.argb_Width, \ + imgUsed->iargb_ARGBimage.argb_Height, \ + imgUsed->iargb_ARGBimage.argb_ImageData)); + + if (imgUsed->iargb_ScaledARGBImage.argb_Width > 512 + || imgUsed->iargb_ScaledARGBImage.argb_Height > 512) + return FALSE; + + d1(KPrintF( "%s/%s/%ld: imgUsed=%08lx\n", __FILE__, __FUNC__, __LINE__, imgUsed)); + + if (imgUsed->iargb_ScaledARGBImage.argb_ImageData) + ImgHeader = &imgUsed->iargb_ScaledARGBImage; + else + ImgHeader = &imgUsed->iargb_ARGBimage; + + d1(KPrintF( "%s/%s/%ld: Width=%lu Height=%ld\n", __FILE__, __FUNC__, __LINE__, ImgHeader->argb_Width, ImgHeader->argb_Height)); + + Mask->iom_Width = ImgHeader->argb_Width; + Mask->iom_Height = ImgHeader->argb_Height; + + BytesPerRow = BYTESPERROW(ImgHeader->argb_Width); + Size = BytesPerRow * ImgHeader->argb_Height; + Size = ALIGN_LONG(Size); + + d1(KPrintF( "%s/%s/%ld: BytesPerRow=%ld\n", __FILE__, __FUNC__, __LINE__, BytesPerRow)); + + MyFreeVecPooled(ChipMemPool, (APTR *) &Mask->iom_Mask); + + Mask->iom_Mask = MyAllocVecPooled(ChipMemPool, Size); + if (NULL == Mask->iom_Mask) + return FALSE; + + memset(Mask->iom_Mask, 0, Size); + + PicPtr = ImgHeader->argb_ImageData; + + d1(KPrintF( "%s/%s/%ld: PicPtr=%08lx\n", __FILE__, __FUNC__, __LINE__, PicPtr)); + + if (PicPtr) + { + UBYTE *MaskPtr = Mask->iom_Mask; + LONG y; + ULONG Threshold = 0; + + d1(KPrintF( "%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + for (y = 0; y < ImgHeader->argb_Height; y++) + { + LONG x; + UWORD BitMask = 0x0080; + UBYTE *MaskPtr2 = MaskPtr; + + for (x = 0; x < ImgHeader->argb_Width; x++) + { + UBYTE alpha; + + alpha = PicPtr->Alpha; + PicPtr++; + + if (alpha > Threshold) + *MaskPtr2 |= BitMask; + + BitMask >>= 1; + if (0 == BitMask) + { + BitMask = 0x0080; + MaskPtr2++; + d1(if (MaskPtr2 > Mask->iom_Mask + Size)\ + { \ + kprintf("%s/%s/%ld: iobj_normmask overflow\n", __FILE__, __FUNC__, __LINE__); \ + break; \ + } ); + } + } + + MaskPtr += BytesPerRow; + } + } + else if (CloneImage && CloneMask) + { + d1(KPrintF( "%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + Mask->iom_Width = CloneMask->iom_Width; + Mask->iom_Height = CloneMask->iom_Height; + + CopyMem(Mask->iom_Mask, CloneMask->iom_Mask, Size); + } + + return TRUE; +} + +//----------------------------------------------------------------------------- + +BOOL GenAlphaFromARGB(Class *cl, Object *o, struct IconObjectARGB *img, struct ARGBHeader *ImgHeader) +{ + struct InstanceData *inst = INST_DATA(cl, o); + struct ExtGadget *gg = (struct ExtGadget *) o; + UBYTE *AlphaPtr; + const struct ARGB *PicPtr; + UWORD Left, BoundsLeft; + ULONG IconWidth, IconHeight; + WORD LeftOffset; + ULONG y; + size_t Size; + + + d1(KPrintF("%s/%s/%ld: START o=%08lx w=%lu h=%lu bw=%lu bh=%lu\n", \ + __FILE__, __FUNC__, __LINE__, o, gg->Width, gg->Height, gg->BoundsWidth, gg->BoundsHeight)); + + Left = (UWORD) gg->LeftEdge; + BoundsLeft = (UWORD) gg->BoundsLeftEdge; + + d1(KPrintF("%s/%s/%ld: Left=%lu BoundsLeft=%lu\n", __FILE__, __FUNC__, __LINE__, Left, BoundsLeft)); + + IconWidth = gg->BoundsWidth; + IconHeight = gg->BoundsHeight; + + d1(KPrintF("%s/%s/%ld: argb_Width=%lu BoundsWidth=%lu\n", __FILE__, __FUNC__, __LINE__, ImgHeader->argb_Width, gg->BoundsWidth)); + d1(KPrintF("%s/%s/%ld: argb_Height=%lu BoundsHeight=%lu\n", __FILE__, __FUNC__, __LINE__, ImgHeader->argb_Height, gg->BoundsHeight)); + + LeftOffset = inst->iobj_imgleft + (Left - BoundsLeft); + d1(KPrintF("%s/%s/%ld: iobj_imgleft=%lu iobj_imgtop=%lu LeftOffset=%ld\n", \ + __FILE__, __FUNC__, __LINE__, inst->iobj_imgleft, inst->iobj_imgtop, LeftOffset)); + + if ((LeftOffset + ImgHeader->argb_Width) > IconWidth) + { + IconWidth = LeftOffset + ImgHeader->argb_Width; + d1(KPrintF("%s/%s/%ld: Image does not fit - BoundsWidth too small or iobj_imgleft too large!!\n", __FILE__, __FUNC__, __LINE__)); + } + + Size = IconWidth * IconHeight; + + MyFreeVecPooled(PubMemPool, (APTR *) &img->iargb_AlphaChannel); + + img->iargb_AlphaChannel = MyAllocVecPooled(PubMemPool, Size); + d1(KPrintF("%s/%s/%ld: iobj_AlphaChannel=%08lx Size=%lu\n", __FILE__, __FUNC__, __LINE__, img->iargb_AlphaChannel, Size)); + if (NULL == img->iargb_AlphaChannel) + return FALSE; + + // make sure all parts outside the image area are visible (border + text) + memset(img->iargb_AlphaChannel, 0xff, Size); + + PicPtr = ImgHeader->argb_ImageData; + AlphaPtr = img->iargb_AlphaChannel + inst->iobj_imgtop * IconWidth; + + d1(KPrintF("%s/%s/%ld: argb_Width=%lu argb_Height=%lu\n", __FILE__, __FUNC__, __LINE__, \ + ImgHeader->argb_Width, ImgHeader->argb_Height)); + + for (y = 0; y < ImgHeader->argb_Height; y++) + { + ULONG x; + UBYTE *XAlphaPtr; + + for (x = 0, XAlphaPtr = AlphaPtr + LeftOffset; x < ImgHeader->argb_Width; x++) + { + d1(if (XAlphaPtr > img->iargb_AlphaChannel + Size)\ + {\ + kprintf("%s/%s/%ld: (x=%ld,y=%ld) XAlphaPtr overflow\n", __FILE__, __FUNC__, __LINE__, x, y);\ + break; \ + } ); + *XAlphaPtr++ = PicPtr->Alpha; + PicPtr++; + } + + AlphaPtr += IconWidth; + } + + d1(KPrintF("%s/%s/%ld: END o=%08lx\n", __FILE__, __FUNC__, __LINE__, o)); + + return TRUE; +} + +//----------------------------------------------------------------------------- + diff --git a/scalos/datatypes/IconObject/config.mk b/scalos/datatypes/IconObject/config.mk new file mode 100755 index 000000000..6c7def699 --- /dev/null +++ b/scalos/datatypes/IconObject/config.mk @@ -0,0 +1,59 @@ +# $Date: 2012-08-10 13:47:28 +0200 (Fr, 10. Aug 2012) $ +# $Revision: 915 $ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +MKDIR = mkdir -p #makedir force +DT_DIR = scalos:IconDatatypes/datatypes +MCPGFX_DIR = $(TOPLEVEL)/common/McpGfx + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +INCLUDES += -I$(MCPGFX_DIR)/ + +LFLAGS += -nostartfiles \ + -lmempools \ +# --verbose + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +INCLUDES += -I$(MCPGFX_DIR)/ + +LFLAGS += -nostartfiles \ + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +INCLUDES += -I$(MCPGFX_DIR)/ + +LFLAGS += -nostartfiles \ + +else +############################################################################### +# AmigaOS + +INCLUDES += -I$(MCPGFX_DIR)/ + +LFLAGS += -ldebug -lmcpgfx -lnix -lamiga -lstubs + +endif +endif +endif diff --git a/scalos/datatypes/IconObject/iconobj-aos4.c b/scalos/datatypes/IconObject/iconobj-aos4.c new file mode 100644 index 000000000..e9cd13326 --- /dev/null +++ b/scalos/datatypes/IconObject/iconobj-aos4.c @@ -0,0 +1,192 @@ +// iconobj-aos4.c +// $Date$ +// $Revision$ + + +#include +#include +#include + +#include +#include + +#include +#include + +#include "iconobj.h" + +int _start(void) +{ + return -1; +} + +static struct Library *Initlib(struct Library *libbase, BPTR seglist, struct ExecIFace *pIExec); +static BPTR Expungelib(struct LibraryManagerInterface *Self); +static struct LibraryHeader *Openlib(struct LibraryManagerInterface *Self, ULONG version); +static BPTR Closelib(struct LibraryManagerInterface *Self); +static ULONG Obtainlib(struct LibraryManagerInterface *Self); +static ULONG Releaselib(struct LibraryManagerInterface *Self); + +extern struct ExecBase *SysBase; + +/* OS4.0 Library */ + +/* ------------------- OS4 Manager Interface ------------------------ */ +static const APTR managerfunctable[] = + { + (APTR)Obtainlib, + (APTR)Releaselib, + (APTR)NULL, + (APTR)NULL, + (APTR)Openlib, + (APTR)Closelib, + (APTR)Expungelib, + (APTR)NULL, + (APTR)-1 + }; + +static const struct TagItem managertags[] = + { + {MIT_Name, (ULONG)"__library"}, + {MIT_VectorTable, (ULONG)managerfunctable}, + {MIT_Version, 1}, + {TAG_DONE, 0} + }; + +/* ---------------------- OS4 Main Interface ------------------------ */ +static APTR functable[] = + { + Obtainlib, + Releaselib, + NULL, + NULL, + ObtainInfoEngine, + (APTR) -1 + }; + +static const struct TagItem maintags[] = + { + {MIT_Name, (ULONG)"main"}, + {MIT_VectorTable, (ULONG)functable}, + {MIT_Version, 1}, + {TAG_DONE, 0} + }; + +/* Init table used in library initialization. */ +static const ULONG interfaces[] = + { + (ULONG)managertags, + (ULONG)maintags, + (ULONG)0 + }; + +static const struct TagItem inittab[] = + { + {CLT_DataSize, (ULONG)sizeof(struct IconObjectDtLibBase)}, + {CLT_Interfaces, (ULONG) interfaces}, +// {CLT_Vector68K, (ULONG)VecTable68K}, + {CLT_InitFunc, (ULONG) Initlib}, + {TAG_DONE, 0} + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, + RTF_NATIVE | RTF_AUTOINIT, + LIB_VERSION, + NT_LIBRARY, + 0, + libName, + libIdString, + (struct TagItem *)inittab + }; + +/* ------------------- OS4 Manager Functions ------------------------ */ +static struct Library * Initlib(struct Library *libbase, BPTR seglist, struct ExecIFace *pIExec) +{ + struct IconObjectDtLibBase *IconObjLibBase = (struct IconObjectDtLibBase *) libbase; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)libbase + libbase->lib_PosSize); + struct LibraryManagerInterface *Self = (struct LibraryManagerInterface *) ExtLib->ILibrary; + + SysBase = (struct ExecBase *)pIExec->Data.LibBase; + IExec = pIExec; + IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_Revision = LIB_REVISION; + IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_Node.ln_Pri = SCHAR_MIN; + IconObjLibBase->nib_SegList = (struct SegList *)seglist; + + if (!InitDatatype(IconObjLibBase)) + { + Expungelib(Self); + IconObjLibBase = NULL; + } + + return (struct Library *)IconObjLibBase; +} + +static BPTR Expungelib(struct LibraryManagerInterface *Self) +{ + struct IconObjectDtLibBase *IconObjLibBase = (struct IconObjectDtLibBase *) Self->Data.LibBase; + + if (0 == IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + struct SegList *libseglist = IconObjLibBase->nib_SegList; + + Remove((struct Node *) IconObjLibBase); + CloseDatatype(IconObjLibBase); + DeleteLibrary((struct Library *)IconObjLibBase); + + return (BPTR)libseglist; + } + + IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_Flags |= LIBF_DELEXP; + + return (BPTR)NULL; +} + +static struct LibraryHeader *Openlib(struct LibraryManagerInterface *Self, ULONG version) +{ + struct IconObjectDtLibBase *IconObjLibBase = (struct IconObjectDtLibBase *) Self->Data.LibBase; + + IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_OpenCnt++; + IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_Flags &= ~LIBF_DELEXP; + + if (!OpenDatatype(IconObjLibBase)) + { + Closelib(Self); + return NULL; + } + + return (struct LibraryHeader *)IconObjLibBase; +} + +static BPTR Closelib(struct LibraryManagerInterface *Self) +{ + struct IconObjectDtLibBase *IconObjLibBase = (struct IconObjectDtLibBase *) Self->Data.LibBase; + + IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_OpenCnt--; +/* + if (0 == IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + if (IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_Flags & LIBF_DELEXP) + { + return Expungelib(Self); + } + } +*/ + return (BPTR)NULL; +} + +static ULONG Obtainlib(struct LibraryManagerInterface *Self) +{ + return(Self->Data.RefCount++); +} + +static ULONG Releaselib(struct LibraryManagerInterface *Self) +{ + return(Self->Data.RefCount--); +} + diff --git a/scalos/datatypes/IconObject/iconobj-aros.c b/scalos/datatypes/IconObject/iconobj-aros.c new file mode 100644 index 000000000..7781eeedd --- /dev/null +++ b/scalos/datatypes/IconObject/iconobj-aros.c @@ -0,0 +1,199 @@ +// iconobj-classic.c +// $Date$ +// $Revision$ + + +#include +#include + +#include + +#include + +#include + + +#include "iconobj.h" + +//---------------------------------------------------------------------------- + +extern struct ExecBase *SysBase; + +//---------------------------------------------------------------------------- + +static AROS_UFP3 (struct Library *, Initlib, + AROS_UFPA(struct Library *, libbase, D0), + AROS_UFPA(struct SegList *, seglist, A0), + AROS_UFPA(struct ExecBase *, sysbase, A6) +); +static AROS_LD1 (struct Library *, Openlib, + AROS_LPA (__unused ULONG, version, D0), + struct Library *, libbase, 1, IconObj +); +static AROS_LD0 (struct SegList *, Closelib, + struct Library *, base, 2, IconObj +); +static AROS_LD1 (struct SegList *, Expungelib, + AROS_LPA(__unused struct Library *, __extrabase, D0), + struct Library *, libbase, 3, IconObj +); +static AROS_LD0 (ULONG, Extfunclib, + __unused struct Library *, libbase, 4, IconObj +); + +//---------------------------------------------------------------------------- + +/* OS3.x Library */ + +static APTR functable[] = + { + IconObj_1_Openlib, + IconObj_2_Closelib, + IconObj_3_Expungelib, + IconObj_4_Extfunclib, + Dummy_0_ObtainInfoEngine, + (APTR) -1 + }; + +/* Init table used in library initialization. */ +static ULONG inittab[] = + { + sizeof(struct IconObjectDtLibBase), + (ULONG) functable, + 0, + (ULONG) Initlib + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, + RTF_AUTOINIT, + LIB_VERSION, + NT_LIBRARY, + 0, + libName, + libIdString, + inittab + }; + +//---------------------------------------------------------------------------- + +static AROS_UFH3(struct Library *, Initlib, + AROS_UFHA(struct Library *, libbase, D0), + AROS_UFHA(struct SegList *, seglist, A0), + AROS_UFHA(struct ExecBase *, sysbase, A6) +) +{ + AROS_USERFUNC_INIT + + struct IconObjectDtLibBase *dtLib = (struct IconObjectDtLibBase *) libbase; + + SysBase = sysbase; + dtLib->nib_ClassLibrary.cl_Lib.lib_Revision = LIB_REVISION; + dtLib->nib_ClassLibrary.cl_Lib.lib_Node.ln_Pri = SCHAR_MIN; + dtLib->nib_SegList = seglist; + + if (!InitDatatype(dtLib)) + { + IconObj_3_Expungelib(&dtLib->nib_ClassLibrary.cl_Lib, &dtLib->nib_ClassLibrary.cl_Lib); + dtLib = NULL; + } + + return dtLib ? &dtLib->nib_ClassLibrary.cl_Lib : NULL; + + AROS_USERFUNC_EXIT +} + + +static AROS_LH1(struct Library *, Openlib, + AROS_LHA(__unused ULONG, version, D0), + struct Library *, libbase, 1, IconObj +) +{ + AROS_LIBFUNC_INIT + + struct IconObjectDtLibBase *dtLib = (struct IconObjectDtLibBase *) libbase; + + dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt++; + dtLib->nib_ClassLibrary.cl_Lib.lib_Flags &= ~LIBF_DELEXP; + + if (!OpenDatatype(dtLib)) + { + IconObj_2_Closelib(&dtLib->nib_ClassLibrary.cl_Lib); + return NULL; + } + + return &dtLib->nib_ClassLibrary.cl_Lib; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH0(struct SegList *, Closelib, + struct Library *, libbase, 2, IconObj +) +{ + AROS_LIBFUNC_INIT + + struct IconObjectDtLibBase *dtLib = (struct IconObjectDtLibBase *) libbase; + + dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt--; + + if (0 == dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + if (dtLib->nib_ClassLibrary.cl_Lib.lib_Flags & LIBF_DELEXP) + { + return IconObj_3_Expungelib(&dtLib->nib_ClassLibrary.cl_Lib, &dtLib->nib_ClassLibrary.cl_Lib); + } + } + + return NULL; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH1(struct SegList *, Expungelib, + AROS_LHA(__unused struct Library *, __extrabase, D0), + struct Library *, libbase, 3, IconObj +) +{ + AROS_LIBFUNC_INIT + + struct IconObjectDtLibBase *dtLib = (struct IconObjectDtLibBase *) libbase; + + if (0 == dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + ULONG size = dtLib->nib_ClassLibrary.cl_Lib.lib_NegSize + dtLib->nib_ClassLibrary.cl_Lib.lib_PosSize; + UBYTE *ptr = (UBYTE *) dtLib - dtLib->nib_ClassLibrary.cl_Lib.lib_NegSize; + struct SegList *libseglist = dtLib->nib_SegList; + + Remove((struct Node *) dtLib); + CloseDatatype(dtLib); + FreeMem(ptr,size); + + return libseglist; + } + + dtLib->nib_ClassLibrary.cl_Lib.lib_Flags |= LIBF_DELEXP; + + return NULL; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH0(ULONG, Extfunclib, + __unused struct Library *, libbase, 4, IconObj +) +{ + AROS_LIBFUNC_INIT + + return 0; + + AROS_LIBFUNC_EXIT +} diff --git a/scalos/datatypes/IconObject/iconobj-classic.c b/scalos/datatypes/IconObject/iconobj-classic.c new file mode 100644 index 000000000..4261fe1a7 --- /dev/null +++ b/scalos/datatypes/IconObject/iconobj-classic.c @@ -0,0 +1,174 @@ +// iconobj-classic.c +// $Date$ +// $Revision$ + + +#include +#include + +#include + +#include + +#include + + +#include "iconobj.h" + +//---------------------------------------------------------------------------- + +extern struct ExecBase *SysBase; + +//---------------------------------------------------------------------------- + +static LIB_SAVEDS(struct Library *) LIB_ASM LIB_INTERRUPT Initlib(LIB_REG(d0, struct Library *libbase), + LIB_REG(a0, struct SegList *seglist), LIB_REG(a6, struct ExecBase *sysbase)); + +static LIBFUNC_PROTO(Openlib, libbase, struct Library *); +static LIBFUNC_PROTO(Closelib, libbase, struct SegList *); +static LIBFUNC_PROTO(Expungelib, libbase, struct SegList *); +static LIBFUNC_PROTO(Extfunclib, libbase, ULONG); + +//---------------------------------------------------------------------------- + +/* OS3.x Library */ + +static APTR functable[] = + { +#ifdef __MORPHOS__ + (APTR) FUNCARRAY_32BIT_NATIVE, +#endif + Openlib, + Closelib, + Expungelib, + Extfunclib, + ObtainInfoEngine, + (APTR) -1 + }; + +/* Init table used in library initialization. */ +static ULONG inittab[] = + { + sizeof(struct IconObjectDtLibBase), + (ULONG) functable, + 0, + (ULONG) Initlib + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, +#ifdef __MORPHOS__ + RTF_PPC | RTF_AUTOINIT, +#else + RTF_AUTOINIT, +#endif + LIB_VERSION, + NT_LIBRARY, + 0, + libName, + libIdString, + inittab + }; + +#ifdef __MORPHOS__ +ULONG __abox__=1; +#endif + +//---------------------------------------------------------------------------- + +static LIB_SAVEDS(struct Library *) LIB_ASM LIB_INTERRUPT Initlib(LIB_REG(d0, struct Library *libbase), + LIB_REG(a0, struct SegList *seglist), LIB_REG(a6, struct ExecBase *sysbase)) +{ + struct IconObjectDtLibBase *dtLib = (struct IconObjectDtLibBase *) libbase; + + SysBase = sysbase; + dtLib->nib_ClassLibrary.cl_Lib.lib_Revision = LIB_REVISION; + dtLib->nib_ClassLibrary.cl_Lib.lib_Node.ln_Pri = SCHAR_MIN; + dtLib->nib_SegList = seglist; + + if (!InitDatatype(dtLib)) + { + CALLLIBFUNC(Expungelib, &dtLib->nib_ClassLibrary.cl_Lib); + dtLib = NULL; + } + + return dtLib ? &dtLib->nib_ClassLibrary.cl_Lib : NULL; +} + + +static LIBFUNC(Openlib, libbase, struct Library *) +{ + struct IconObjectDtLibBase *dtLib = (struct IconObjectDtLibBase *) libbase; + + dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt++; + dtLib->nib_ClassLibrary.cl_Lib.lib_Flags &= ~LIBF_DELEXP; + + if (!OpenDatatype(dtLib)) + { + CALLLIBFUNC(Closelib, &dtLib->nib_ClassLibrary.cl_Lib); + return NULL; + } + + return &dtLib->nib_ClassLibrary.cl_Lib; +} +LIBFUNC_END + + +static LIBFUNC(Closelib, libbase, struct SegList *) +{ + struct IconObjectDtLibBase *dtLib = (struct IconObjectDtLibBase *) libbase; + + dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt--; + + if (0 == dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + if (dtLib->nib_ClassLibrary.cl_Lib.lib_Flags & LIBF_DELEXP) + { + return CALLLIBFUNC(Expungelib, &dtLib->nib_ClassLibrary.cl_Lib); + } + } + + return NULL; +} +LIBFUNC_END + + +static LIBFUNC(Expungelib, libbase, struct SegList *) +{ + struct IconObjectDtLibBase *dtLib = (struct IconObjectDtLibBase *) libbase; + + if (0 == dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + ULONG size = dtLib->nib_ClassLibrary.cl_Lib.lib_NegSize + dtLib->nib_ClassLibrary.cl_Lib.lib_PosSize; + UBYTE *ptr = (UBYTE *) dtLib - dtLib->nib_ClassLibrary.cl_Lib.lib_NegSize; + struct SegList *libseglist = dtLib->nib_SegList; + + Remove((struct Node *) dtLib); + CloseDatatype(dtLib); + FreeMem(ptr,size); + + return libseglist; + } + + dtLib->nib_ClassLibrary.cl_Lib.lib_Flags |= LIBF_DELEXP; + + return NULL; +} +LIBFUNC_END + + +static LIBFUNC(Extfunclib, libbase, ULONG) +{ + (void) libbase; + + d1(kprintf(__FUNC__ "/%ld: libbase=%08lx\n", __LINE__, libbase)); + return 0; +} +LIBFUNC_END + + diff --git a/scalos/datatypes/IconObject/iconobj.c b/scalos/datatypes/IconObject/iconobj.c new file mode 100644 index 000000000..8c8ed87ed --- /dev/null +++ b/scalos/datatypes/IconObject/iconobj.c @@ -0,0 +1,3949 @@ +// iconobj.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define __USE_SYSBASE +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "iconobj.h" + +#ifdef __AROS__ +// FIXME: temporary fix until we have figured out +// how to deal with these deprecated defines. +#define IA_ShadowPen (IA_Dummy + 0x09) +#define IA_HighlightPen (IA_Dummy + 0x0A) +#endif + +//---------------------------------------------------------------------------- + +#define max(a,b) ((a) > (b) ? (a) : (b)) +#define min(a,b) ((a) < (b) ? (a) : (b)) + +#define IDTA_TAGBASE (IDTA_Type - 1) + +#define AREAMAX 30 + +#define TT_RADIUS 5 // default value for iobj_TextRectRadius + +#define TT_BORDER_X 4 // default value for iobj_TextRectBorderX +#define TT_BORDER_Y 2 // default value for iobj_TextRectBorderY + +//---------------------------------------------------------------------------- + +// Memory allocation + +#define SCALOS_MEM_START_MAGIC 0x5343414d +#define SCALOS_MEM_END_MAGIC 0xe34341cd + +#define SCALOS_MEM_TRAILER 20 + +struct AllocatedMemFromPoolDebug + { + size_t amp_Size; // Size of allocated memory + + ULONG amp_Line; // Line number of allocator + CONST_STRPTR amp_File; // File name of allocator + CONST_STRPTR amp_Function; // Name of allocating function + + ULONG amp_Magic; + + UBYTE amp_UserData[0]; // Start of user-visible memory + }; + +struct AllocatedMemFromPool + { + size_t amp_Size; // Size of allocated memory + UBYTE amp_UserData[0]; // Start of user-visible memory + }; + +//---------------------------------------------------------------------------- + +struct GfxBase *GfxBase; +T_UTILITYBASE UtilityBase; +struct ExecBase *SysBase; +struct Library *CyberGfxBase; +struct DosLibrary *DOSBase; +struct IntuitionBase *IntuitionBase; +struct ScalosGfxBase *ScalosGfxBase; +#ifdef TIMESTAMPS +T_TIMERBASE TimerBase; +#endif /* TIMESTAMPS */ +#ifdef __amigaos4__ +struct Library *NewlibBase; +struct Interface *INewlib; +struct GraphicsIFace *IGraphics; +struct UtilityIFace *IUtility; +struct ExecIFace *IExec; +struct CyberGfxIFace *ICyberGfx; +struct DOSIFace *IDOS; +struct IntuitionIFace *IIntuition; +struct ScalosGfxIFace *IScalosGfx; +#endif + +void *PubMemPool; +void *ChipMemPool; + +static struct SignalSemaphore MemPoolSemaphore; + +static Class *IconObjectClass; + +static const ULONG packTable[] = + { + PACK_STARTTABLE(IDTA_TAGBASE), + PACK_ENTRY(IDTA_TAGBASE, IDTA_UserFlags, InstanceData, iobj_UserFlags, PKCTRL_ULONG | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_OverlayType, InstanceData, iobj_OverlayType, PKCTRL_ULONG | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_TextStyle, InstanceData, iobj_TextStyle, PKCTRL_ULONG | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_Font, InstanceData, iobj_Font, PKCTRL_ULONG | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_Borderless, InstanceData, iobj_Borderless, PKCTRL_ULONG | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_Type, InstanceData, iobj_type, PKCTRL_UBYTE | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_FontHook, InstanceData, iobj_FontHook, PKCTRL_ULONG | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_Fonthandle, InstanceData, iobj_Fonthandle, PKCTRL_ULONG | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_Stacksize, InstanceData, iobj_stacksize, PKCTRL_ULONG | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_WinCurrentX, InstanceData, iobj_wincurx, PKCTRL_ULONG | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_WinCurrentY, InstanceData, iobj_wincury, PKCTRL_ULONG | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_FrameType, InstanceData, iobj_frametype, PKCTRL_UWORD | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_FrameTypeSel, InstanceData, iobj_frametypesel, PKCTRL_UWORD | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_HalfShadowPen, InstanceData, iobj_HalfShadowPen, PKCTRL_UWORD | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_HalfShinePen, InstanceData, iobj_HalfShinePen, PKCTRL_UWORD | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_Flags, InstanceData, iobj_ddflags, PKCTRL_ULONG | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_ViewModes, InstanceData, iobj_viewmodes, PKCTRL_UWORD | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_TextPen, InstanceData, iobj_TextPen, PKCTRL_UWORD | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_TextPenSel, InstanceData, iobj_TextPenSel, PKCTRL_UWORD | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_TextPenBgSel, InstanceData, iobj_TextPenBgSel, PKCTRL_UWORD | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_TextPenOutline, InstanceData, iobj_TextPenOutline, PKCTRL_UWORD | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_TextPenShadow, InstanceData, iobj_TextPenShadow, PKCTRL_UWORD | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_TextBackPen, InstanceData, iobj_TextBackPen, PKCTRL_UWORD | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_TextDrawMode, InstanceData, iobj_TextDrawMode, PKCTRL_UWORD | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_TextSkip, InstanceData, iobj_textskip, PKCTRL_UWORD | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_MultiLineText, InstanceData, iobj_MultiLineText, PKCTRL_UBYTE | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_TextMode, InstanceData, iobj_textmode, PKCTRL_UBYTE | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_Backfill, InstanceData, iobj_BackfillPenNorm, PKCTRL_ULONG | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_BackfillSel, InstanceData, iobj_BackfillPenSel, PKCTRL_ULONG | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_InnerLeft, InstanceData, iobj_imgleft, PKCTRL_UWORD | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_InnerTop, InstanceData, iobj_imgtop, PKCTRL_UWORD | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_InnerRight, InstanceData, iobj_imgright, PKCTRL_UWORD | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_InnerBottom, InstanceData, iobj_imgbottom, PKCTRL_UWORD | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_SelTextRectBorderX, InstanceData, iobj_TextRectBorderX, PKCTRL_UWORD | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_SelTextRectBorderY, InstanceData, iobj_TextRectBorderY, PKCTRL_UWORD | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_SelTextRectRadius, InstanceData, iobj_TextRectRadius, PKCTRL_UWORD | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_SelectedTextRectangle, InstanceData, iobj_SelectedTextRectangle, PKCTRL_UBYTE | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_Width_Mask_Normal, InstanceData, iobj_NormalMask.iom_Width, PKCTRL_ULONG | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_Height_Mask_Normal, InstanceData, iobj_NormalMask.iom_Height, PKCTRL_ULONG | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_Width_Mask_Selected, InstanceData, iobj_SelectedMask.iom_Width, PKCTRL_ULONG | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_Height_Mask_Selected, InstanceData, iobj_SelectedMask.iom_Height, PKCTRL_ULONG | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_CopyARGBImageData, InstanceData, iobj_NormalARGB.iargb_CopyARGBImageData, PKCTRL_ULONG | PKCTRL_PACKUNPACK), + PACK_ENTRY(IDTA_TAGBASE, IDTA_CopySelARGBImageData, InstanceData, iobj_SelectedARGB.iargb_CopyARGBImageData, PKCTRL_ULONG | PKCTRL_PACKUNPACK), + PACK_ENDTABLE + }; + +//---------------------------------------------------------------------------- + +static SAVEDS(ULONG) INTERRUPT IconObjectDispatcher(Class *cl, Object *o, Msg msg); + +//----------------------------------------------------------------------------- + +static BOOL DtNew(Class *cl, Object *o, struct opSet *ops); +static ULONG DtDispose(Class *cl, Object *o, Msg msg); +static ULONG DtHitTest(Class *cl, Object *o, struct gpHitTest *gpht); +static ULONG DtRender(Class *cl, Object *o, struct gpRender *gpr); +static ULONG DtErase(Class *cl, Object *o, struct iopErase *iope); +static ULONG DtFindToolType(Class *cl, Object *o, struct iopFindToolType *ioft); +static ULONG DtGetToolTypeValue(Class *cl, Object *o, struct iopGetToolTypeValue *iotv); +static ULONG DtDraw(Class *cl, Object *o, struct iopDraw *iopd); +static ULONG DtLayout(Class *cl, Object *o, struct iopLayout *iopl); +static ULONG DtFreeLayout(Class *cl, Object *o, struct iopFreeLayout *opf); +static ULONG DtSet(Class *cl, Object *o, struct opSet *ops); +static ULONG DtGet(Class *cl, Object *o, struct opGet *opg); +static ULONG DtScaleIcon(Class *cl, Object *o, struct iopScaleIcon *iops); + +static ULONG DoOmSet(Class *cl, Object *o, struct opSet *ops); +static void LayoutIconText(struct InstanceData *inst, struct RastPort *rp, struct ExtGadget *gg); +static void DrawIconText(Class *cl, Object *o, struct iopDraw *iopd); +static void GetPosition(struct iopDraw *iopd, struct ExtGadget *gg, WORD *x, WORD *y); +static void DrawTextAt(struct InstanceData *inst, struct RastPort *rp, ULONG x, ULONG y); +static void DoReLayout(struct InstanceData *inst, struct ExtGadget *gg, struct RastPort *rp); +static BOOL IsSeparator(char ch); +static ULONG MySetSoftStyle(struct InstanceData *inst, struct RastPort *rp, ULONG style, ULONG enable); +static void MyText(struct InstanceData *inst, struct RastPort *rp, CONST_STRPTR string, WORD Length); +static void MyTextExtent(struct InstanceData *inst, struct RastPort *rp, + CONST_STRPTR string, WORD Length, struct TextExtent *tExt); +static void MySetFont(struct InstanceData *inst, struct RastPort *rp, struct TextFont *tf); +static void MySetTransparency(struct InstanceData *inst, struct RastPort *rp, ULONG Transparency); +static void MyDoneRastPort(struct InstanceData *inst, struct RastPort *rp); +static UWORD MyGetFontBaseline(struct InstanceData *inst, struct RastPort *rp); +static void CalculateTextDimensions(struct InstanceData *inst, struct ExtGadget *gg, struct RastPort *rp); +static BOOL ToolTypeNameCmp(CONST_STRPTR ToolTypeName, CONST_STRPTR ToolTypeContents); +static void SetTags(Class *cl, Object *o, struct opSet *ops); +static void SetAllocTag(ULONG TagValue, STRPTR *DataPtr, struct TagItem *TagList); +static void SetAllocTagProtected(ULONG TagValue, STRPTR *DataPtr, + struct TagItem *TagList, struct SignalSemaphore *Sema); +static STRPTR AllocCopyString(CONST_STRPTR OrigString); +static void SetToolTypes(struct InstanceData *inst, const STRPTR *NewToolTypes); +static STRPTR *CloneToolTypes(const STRPTR *OrigToolTypes); +static void DrawFrame(Class *cl, Object *o, struct RastPort *rp, + ULONG Width, ULONG Height, UWORD FrameType); +static void DrawMaskFrame(struct InstanceData *inst, struct BitMap *DestBitMap, + ULONG Width, ULONG Height, UWORD FrameType); +static struct RastPort *InitRast(Class *cl, Object *o, struct iopLayout *iopl, struct RastPort *rp); +static struct BitMap *GenMask(Class *cl, Object *o, + ULONG BmWidth, ULONG BmHeight, ULONG BmDepth, ULONG BmFlags, + UBYTE *MaskPlane, + UWORD FrameType, ULONG MaskWidth, ULONG MaskHeight); +static struct BitMap *GenInvMask(Class *cl, Object *o, struct BitMap *SrcBitMap); +static BOOL ScaleRenderBitMapsNormal(Class *cl, Object *o, + ULONG NewWidth, ULONG NewHeight, struct Screen *screen); +static BOOL ScaleRenderBitMapsSelected(Class *cl, Object *o, + ULONG NewWidth, ULONG NewHeight, struct Screen *screen); +static void LayoutIconSize(Class *cl, Object *o, struct RastPort *rp); +static struct BitMap *ScaleMaskBitMap(struct BitMap *SourceBM, + ULONG SourceWidth, ULONG SourceHeight, + ULONG *NewWidth, ULONG *NewHeight, + ULONG ScaleFlags, struct BitMap *FriendBM); +static void CheckIfScalingRequired(Class *cl, Object *o); +static void ReplaceARGBImage(struct IconObjectARGB *img, struct ARGBHeader *argbh); +static void FreeARGBImage(struct IconObjectARGB *img); +static void FreeARGBImageLayout(struct IconObjectARGB *img); +static void FreeMask(struct IconObjectMask *Mask); +static void LayoutARGB(Class *cl, Object *o, struct IconObjectARGB *img); +static BOOL ScaleARGB(Class *cl, Object *o, struct IconObjectARGB *img, + struct IconObjectMask *Mask, ULONG NewWidth, ULONG NewHeight, ULONG ScaleFlags); +static void EraseIconText(Class *cl, Object *o, struct RastPort *rp, WORD x, WORD y); +static void DrawIconTextRect(Class *cl, Object *o, struct RastPort *rp, WORD x, WORD y); + +static void DumpMaskPlane(const struct IconObjectMask *Mask); +static void DumpMask(const struct IconObjectMask *Mask); +static void DumpMaskBM(const struct IconObjectMask *Mask); + +//---------------------------------------------------------------------------- + +SAVEDS(LONG) ASM Libstart(void) +{ + return -1; +} + +//---------------------------------------------------------------------------- + +char ALIGNED libName[] = "iconobject.datatype"; +char ALIGNED libIdString[] = "$VER: iconobject.datatype " + STR(LIB_VERSION) "." STR(LIB_REVISION) + " (02 Nov 2008 23:57:06) " + COMPILER_STRING + " ©1999" CURRENTYEAR " The Scalos Team"; + +//----------------------------------------------------------------------------- + +LIBFUNC(ObtainInfoEngine, libbase, ULONG) +{ + (void) libbase; + + return (ULONG) IconObjectClass; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +// return 0 if error occurred +ULONG InitDatatype(struct IconObjectDtLibBase *dtLib) +{ + d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__)); + + dtLib->nib_Initialized = FALSE; + + return 1; +} + +// return 0 if error occurred +ULONG OpenDatatype(struct IconObjectDtLibBase *dtLib) +{ + d1(kprintf("%s/%s/%ld: OpenCnt=%ld\n", __FILE__, __FUNC__, __LINE__, dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt)); + + if (!dtLib->nib_Initialized) + { + struct MsgPort *FBlitPort; + ULONG ChipMemPoolFlags; + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + dtLib->nib_Initialized = TRUE; + + InitSemaphore(&MemPoolSemaphore); + + CyberGfxBase = OpenLibrary(CYBERGFXNAME, 0); + // CyberGfxBase may be NULL + + FBlitPort = FindPort("FBlit"); + d1(kprintf("%s/%s/%ld: FBlitPort=%08lx\n", __FILE__, __FUNC__, __LINE__, FBlitPort)); + + + // don't use chip mem if CyberGfx library found or FBlit port found. + if (FBlitPort || CyberGfxBase) + { + ChipMemPoolFlags = PUBMEMPOOL_MEMFLAGS; + d1(kprintf("%s/%s/%ld: FBlitPort=%08lx CyberGfxBase=%08lx ChipMemPoolFlags = MEMF_PUBLIC\n", \ + __FILE__, __FUNC__, __LINE__, FBlitPort, CyberGfxBase)); + } + else + { + ChipMemPoolFlags = CHIPMEMPOOL_MEMFLAGS; + d1(kprintf("%s/%s/%ld: FBlitPort=%08lx CyberGfxBase=%08lx ChipMemPoolFlags = (MEMF_PUBLIC | MEMF_CHIP)\n", \ + __FILE__, __FUNC__, __LINE__, FBlitPort, CyberGfxBase)); + } + + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + d1(kprintf("%s/%s/%ld: IntuitionBase=%08lx\n", __FILE__, __FUNC__, __LINE__, IntuitionBase)); + if (NULL == IntuitionBase) + return 0; + + DOSBase = (struct DosLibrary *) OpenLibrary("dos.library", 39); + d1(kprintf("%s/%s/%ld: DOSBase=%08lx\n", __FILE__, __FUNC__, __LINE__, DOSBase)); + if (NULL == DOSBase) + return 0; + + UtilityBase = (T_UTILITYBASE) OpenLibrary("utility.library", 39); + d1(kprintf("%s/%s/%ld: UtilityBase=%08lx\n", __FILE__, __FUNC__, __LINE__, UtilityBase)); + if (NULL == UtilityBase) + return 0; + + GfxBase = (struct GfxBase *) OpenLibrary(GRAPHICSNAME, 39); + d1(kprintf("%s/%s/%ld: GfxBase=%08lx\n", __FILE__, __FUNC__, __LINE__, GfxBase)); + if (NULL == GfxBase) + return 0; + + ScalosGfxBase = (struct ScalosGfxBase *) OpenLibrary(SCALOSGFXNAME, 41); + d1(KPrintF("%s/%s/%ld: ScalosGfxBase=%08lx\n", __FILE__, __FUNC__, __LINE__, ScalosGfxBase)); + if (NULL == ScalosGfxBase) + return 0; + +#ifdef TIMESTAMPS + { + struct timerequest *iorequest; + + iorequest = (struct timerequest *) CreateIORequest(CreateMsgPort(), sizeof(struct timerequest)); + OpenDevice("timer.device", UNIT_VBLANK, &iorequest->tr_node, 0); + TimerBase = (T_TIMERBASE) iorequest->tr_node.io_Device; + } +#endif /* TIMESTAMPS */ + +#ifdef __amigaos4__ + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + return 0; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + return 0; + IDOS = (struct DOSIFace *) GetInterface((struct Library *) DOSBase, "main", 1, NULL); + if (IDOS == NULL) + return 0; + IUtility = (struct UtilityIFace *) GetInterface((struct Library *) UtilityBase, "main", 1, NULL); + if (NULL == IUtility) + return 0; + if (CyberGfxBase != NULL) // CyberGfxBase may be NULL + { + ICyberGfx = (struct CyberGfxIFace *) GetInterface((struct Library *) CyberGfxBase, "main", 1, NULL); + if (ICyberGfx == NULL) + return 0; + } + IIntuition = (struct IntuitionIFace *) GetInterface((struct Library *) IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + return 0; + IGraphics = (struct GraphicsIFace *) GetInterface((struct Library *) GfxBase, "main", 1, NULL); + if (NULL == IGraphics) + return 0; + IScalosGfx = (struct ScalosGfxIFace *) GetInterface((struct Library *) ScalosGfxBase, "main", 1, NULL); + if (NULL == IScalosGfx) + return 0; +#endif /* __amigaos4__ */ + + PubMemPool = CreatePool(PUBMEMPOOL_MEMFLAGS, PUBMEMPOOL_PUDDLESIZE, PUBMEMPOOL_THRESHSIZE); + d1(kprintf("%s/%s/%ld: PubMemPool=%08lx\n", __FILE__, __FUNC__, __LINE__, PubMemPool)); + if (NULL == PubMemPool) + return 0; + + ChipMemPool = CreatePool(ChipMemPoolFlags, CHIPMEMPOOL_PUDDLESIZE, CHIPMEMPOOL_THRESHSIZE); + d1(kprintf("%s/%s/%ld: ChipMemPool=%08lx\n", __FILE__, __FUNC__, __LINE__, ChipMemPool)); + if (NULL == ChipMemPool) + return 0; + + IconObjectClass = dtLib->nib_ClassLibrary.cl_Class = MakeClass(libName, + "datatypesclass", NULL, sizeof(struct InstanceData), 0); + d1(kprintf("%s/%s/%ld: IconObjectClass=%08lx\n", __FILE__, __FUNC__, __LINE__, IconObjectClass)); + if (NULL == IconObjectClass) + return 0; + + SETHOOKFUNC(IconObjectClass->cl_Dispatcher, IconObjectDispatcher); + IconObjectClass->cl_Dispatcher.h_Data = dtLib; + + // Make class available for the public + AddClass(IconObjectClass); + } + + d1(kprintf("%s/%s/%ld: Open Success!\n", __FILE__, __FUNC__, __LINE__)); + + return 1; +} + +void CloseDatatype(struct IconObjectDtLibBase *dtLib) +{ + d1(kprintf("%s/%s/%ld: OpenCnt=%ld\n", __FILE__, __FUNC__, __LINE__, dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt)); + + if (dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt < 1) + { + if (IconObjectClass) + { + RemoveClass(IconObjectClass); + FreeClass(IconObjectClass); + IconObjectClass = dtLib->nib_ClassLibrary.cl_Class = NULL; + } + + if (NULL != ChipMemPool) + { + DeletePool(ChipMemPool); + ChipMemPool = NULL; + } + if (NULL != PubMemPool) + { + DeletePool(PubMemPool); + PubMemPool = NULL; + } + +#ifdef __amigaos4__ + if (ICyberGfx) + { + DropInterface((struct Interface *)ICyberGfx); + ICyberGfx = NULL; + } + if (IScalosGfx) + { + DropInterface((struct Interface *)IScalosGfx); + IScalosGfx = NULL; + } + if (IGraphics) + { + DropInterface((struct Interface *)IGraphics); + IGraphics = NULL; + } + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } + if (IUtility) + { + DropInterface((struct Interface *)IUtility); + IUtility = NULL; + } + if (IDOS) + { + DropInterface((struct Interface *)IDOS); + IDOS = NULL; + } + if (INewlib) + { + DropInterface(INewlib); + INewlib = NULL; + } + if (NewlibBase) + { + CloseLibrary(NewlibBase); + NewlibBase = NULL; + } +#endif + + if (NULL != CyberGfxBase) + { + CloseLibrary(CyberGfxBase); + CyberGfxBase = NULL; + } + if (NULL != ScalosGfxBase) + { + CloseLibrary((struct Library *) ScalosGfxBase); + ScalosGfxBase = NULL; + } + if (NULL != GfxBase) + { + CloseLibrary((struct Library *) GfxBase); + GfxBase = NULL; + } + if (NULL != IntuitionBase) + { + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } + if (NULL != UtilityBase) + { + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } + if (NULL != DOSBase) + { + CloseLibrary((struct Library *) DOSBase); + DOSBase = NULL; + } + } + + d1(kprintf("%s/%s/%ld: OpenCnt=%ld\n", __FILE__, __FUNC__, __LINE__, dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt)); + +} + +//----------------------------------------------------------------------------- + +static SAVEDS(ULONG) INTERRUPT IconObjectDispatcher(Class *cl, Object *o, Msg msg) +{ + ULONG Result; + + d1(kprintf("%s/%s/%ld: cl=%08lx o=%08lx msg=%08lx MethodID=%08ld\n", __FILE__, __FUNC__, __LINE__, + cl, o, msg, msg->MethodID)); + + switch (msg->MethodID) + { + case OM_NEW: + o = (Object *) DoSuperMethodA(cl, o, msg); + d1(KPrintF("%s/%s/%ld: OM_NEW o=%08lx\n", __FILE__, __FUNC__, __LINE__, o)); + if (o) + { + d1(KPrintF("%s/%s/%ld: OM_NEW o=%08lx\n", __FILE__, __FUNC__, __LINE__, o)); + if (!DtNew(cl, o, (struct opSet *) msg)) + { + DoMethod(o, OM_DISPOSE); + o = NULL; + } + } + Result = (ULONG) o; + break; + + case OM_DISPOSE: + d1(kprintf("%s/%s/%ld: OM_DISPOSE cl=%08lx o=%08lx msg=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, msg)); + Result = DtDispose(cl, o, msg); + break; + + case OM_GET: + d1(kprintf("%s/%s/%ld: OM_GET cl=%08lx o=%08lx msg=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, msg)); + Result = DtGet(cl, o, (struct opGet *) msg); + break; + + case OM_SET: + d1(kprintf("%s/%s/%ld: OM_SET cl=%08lx o=%08lx msg=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, msg)); + Result = DtSet(cl, o, (struct opSet *) msg); + break; + + case GM_HITTEST: + d1(kprintf("%s/%s/%ld: GM_HITTEST cl=%08lx o=%08lx msg=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, msg)); + Result = DtHitTest(cl, o, (struct gpHitTest *) msg); + break; + + case GM_RENDER: + d1(kprintf("%s/%s/%ld: GM_RENDER cl=%08lx o=%08lx msg=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, msg)); + Result = DtRender(cl, o, (struct gpRender *) msg); + break; + + case GM_GOACTIVE: + d1(kprintf("%s/%s/%ld: GM_GOACTIVE cl=%08lx o=%08lx msg=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, msg)); + Result = DtRender(cl, o, (struct gpRender *) msg); + break; + + case GM_GOINACTIVE: + d1(kprintf("%s/%s/%ld: GM_GOINACTIVEclcl=%08lx o=%08lx msg=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, msg)); + Result = DtRender(cl, o, (struct gpRender *) msg); + break; + + case IDTM_Draw: + d1(kprintf("%s/%s/%ld: IDTM_Draw cl=%08lx o=%08lx msg=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, msg)); + Result = DtDraw(cl, o, (struct iopDraw *) msg); + break; + + case IDTM_Layout: + Result = DtLayout(cl, o, (struct iopLayout *) msg); + d1(KPrintF("%s/%s/%ld: IDTM_Layout cl=%08lx o=%08lx msg=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, msg)); + break; + + case IDTM_FreeLayout: + d1(kprintf("%s/%s/%ld: IDTM_FreeLayout cl=%08lx o=%08lx msg=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, msg)); + Result = DtFreeLayout(cl, o, (struct iopFreeLayout *) msg); + break; + + case IDTM_FindToolType: + d1(kprintf("%s/%s/%ld: IDTM_FindToolType cl=%08lx o=%08lx msg=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, msg)); + Result = DtFindToolType(cl, o, (struct iopFindToolType *) msg); + break; + + case IDTM_GetToolTypeValue: + d1(kprintf("%s/%s/%ld: IDTM_GetToolTypeValue cl=%08lx o=%08lx msg=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, msg)); + Result = DtGetToolTypeValue(cl, o, (struct iopGetToolTypeValue *) msg); + break; + + case IDTM_Erase: + d1(kprintf("%s/%s/%ld: IDTM_Erase cl=%08lx o=%08lx msg=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, msg)); + + Result = DtErase(cl, o, (struct iopErase *) msg); + break; + + case IDTM_ScaleIcon: + d1(KPrintF("%s/%s/%ld: IDTM_ScaleIcon cl=%08lx o=%08lx msg=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, msg)); + + Result = DtScaleIcon(cl, o, (struct iopScaleIcon *) msg); + break; + + default: + Result = DoSuperMethodA(cl, o, msg); + break; + } + + d1(kprintf("%s/%s/%ld: result=%08lx\n", __FILE__, __FUNC__, __LINE__, Result)); + + return Result; +} + +//----------------------------------------------------------------------------- + +static BOOL DtNew(Class *cl, Object *o, struct opSet *ops) +{ + struct InstanceData *inst = INST_DATA(cl, o); + BOOL Success = TRUE; + + memset(inst, 0, sizeof(struct InstanceData)); + + TIMESTAMP_d1(); + + InitSemaphore(&inst->iobj_TextSemaphore); + InitSemaphore(&inst->iobj_LayoutSemaphore); + + inst->iobj_TextPen = 1; + inst->iobj_TextPenSel = 1; + inst->iobj_TextPenOutline = 2; + inst->iobj_TextPenBgSel = 3; + inst->iobj_TextPenShadow = 1; + inst->iobj_TextDrawMode = JAM1; + inst->iobj_TextBackPen = 0; + inst->iobj_TextRectBorderX = TT_BORDER_X; + inst->iobj_TextRectBorderY = TT_BORDER_Y; + inst->iobj_TextRectRadius = TT_RADIUS; + + inst->iobj_SelectedTextRectangle = 1; + inst->iobj_textskip = 1; + inst->iobj_frametypesel = (UWORD) -1; + inst->iobj_TextStyle = FS_NORMAL; + inst->iobj_BackfillPenNorm = inst->iobj_BackfillPenSel = IDTA_BACKFILL_NONE; + + inst->iobj_ScalingPercentage = 100; + + inst->iobj_SizeConstraints.MinX = inst->iobj_SizeConstraints.MinY = 0; + inst->iobj_SizeConstraints.MaxX = inst->iobj_SizeConstraints.MaxY = SHRT_MAX; + + SetTags(cl, o, ops); + + d1(kprintf("%s/%s/%ld: o=%08lx\n", __FILE__, __FUNC__, __LINE__, o)); + TIMESTAMP_d1(); + + return Success; +} + +//----------------------------------------------------------------------------- + +static ULONG DtDispose(Class *cl, Object *o, Msg msg) +{ + struct InstanceData *inst = INST_DATA(cl, o); + struct ExtGadget *gg = (struct ExtGadget *) o; + + ObtainSemaphore(&inst->iobj_LayoutSemaphore); + + MyFreeVecPooled(PubMemPool, (APTR *) &inst->iobj_text); + MyFreeVecPooled(PubMemPool, (APTR *) &inst->iobj_defaulttool); + MyFreeVecPooled(PubMemPool, (APTR *) &inst->iobj_ToolWindow); + MyFreeVecPooled(PubMemPool, (APTR *) &inst->iobj_name); + MyFreeVecPooled(PubMemPool, (APTR *) &inst->iobj_tooltypes); + + FreeARGBImage(&inst->iobj_NormalARGB); + FreeARGBImage(&inst->iobj_SelectedARGB); + + if (gg->SelectRender) + { + struct RastPort *rp = (struct RastPort *) gg->SelectRender; + + d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, rp->BitMap)); + FreeBitMap(rp->BitMap); + gg->SelectRender = NULL; + } + if (gg->GadgetRender) + { + struct RastPort *rp = (struct RastPort *) gg->GadgetRender; + + d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, rp->BitMap)); + FreeBitMap(rp->BitMap); + gg->GadgetRender = NULL; + } + if (inst->iobj_BackfillRp) + { + if (inst->iobj_BackfillRp->BitMap) + { + d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_BackfillRp->BitMap)); + FreeBitMap(inst->iobj_BackfillRp->BitMap); + inst->iobj_BackfillRp->BitMap = NULL; + } + + inst->iobj_BackfillRp = NULL; + } + + FreeMask(&inst->iobj_NormalMask); + FreeMask(&inst->iobj_SelectedMask); + + ReleaseSemaphore(&inst->iobj_LayoutSemaphore); + + return DoSuperMethodA(cl, o, msg); +} + +//----------------------------------------------------------------------------- + +// For GM_HITTEST, return GMR_GADGETHIT if you were indeed hit, +// otherwise return zero. + +static ULONG DtHitTest(Class *cl, Object *o, struct gpHitTest *gpht) +{ + ULONG Result = 0; + + d1(kprintf("%s/%s/%ld: o=%08lx\n", __FILE__, __FUNC__, __LINE__, o)); + + Result = DoSuperMethodA(cl, o, (Msg) gpht); + if (GMR_GADGETHIT == Result) + { + struct InstanceData *inst = INST_DATA(cl, o); + struct ExtGadget *gg = (struct ExtGadget *) o; + struct BitMap *MaskBM; + LONG x, y; + ULONG BmWidth, BmHeight; + + if (gg->Flags & GFLG_SELECTED) + MaskBM = inst->iobj_SelectedMask.iom_MaskBM; + else + MaskBM = inst->iobj_NormalMask.iom_MaskBM; + + d1(kprintf("%s/%s/%ld: MaskBM=%08lx\n", __FILE__, __FUNC__, __LINE__, MaskBM)); + + if (NULL == MaskBM) + { + Result = GMR_GADGETHIT; + } + else + { + d1(kprintf("%s/%s/%ld: iobj_imgleft=%ld iobj_imgtop=%ld\n", __FILE__, __FUNC__, __LINE__, inst->iobj_imgleft, inst->iobj_imgtop)); + + x = gpht->gpht_Mouse.X - gg->LeftEdge - inst->iobj_imgleft; + y = gpht->gpht_Mouse.Y - gg->TopEdge - inst->iobj_imgtop; + + BmWidth = GetBitMapAttr(MaskBM, BMA_WIDTH); + BmHeight = GetBitMapAttr(MaskBM, BMA_HEIGHT); + + d1(kprintf("%s/%s/%ld: x=%ld y=%ld BmWidth=%lu BmHeight=%lu\n", __FILE__, __FUNC__, __LINE__, x, y, BmWidth, BmHeight)); + + if ( x >= 0 && y >= 0 && x < BmWidth && y < BmHeight) + { + struct RastPort rp; + + InitRastPort(&rp); + + rp.BitMap = MaskBM; + + d1(kprintf("%s/%s/%ld: ReadPixel()=%ld\n", __FILE__, __FUNC__, __LINE__, ReadPixel(&rp, x, y))); + + if (ReadPixel(&rp, x, y)) + Result = GMR_GADGETHIT; + else + Result = 0; + } + } + } + + d1(kprintf("%s/%s/%ld: o=%08lx Result=%ld\n", __FILE__, __FUNC__, __LINE__, o, Result)); + + return Result; +} + +//----------------------------------------------------------------------------- + +static ULONG DtRender(Class *cl, Object *o, struct gpRender *gpr) +{ + struct InstanceData *inst = INST_DATA(cl, o); + struct ExtGadget *gg = (struct ExtGadget *) o; + struct RastPort *rp; + + d1(kprintf("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + + DoSuperMethodA(cl, o, (Msg) gpr); + + if (GM_RENDER == gpr->MethodID) + rp = gpr->gpr_RPort; + else + rp = ObtainGIRPort(gpr->gpr_GInfo); + + if (rp) + { + if (GM_RENDER == gpr->MethodID && !gpr->gpr_Redraw) + gg->Flags ^= GFLG_SELECTED; + + if (((gg->Flags & GFLG_SELECTED) && !(inst->iobj_layoutflags & IOBLAYOUTF_SelectedImage)) + || (!(gg->Flags & GFLG_SELECTED) && !(inst->iobj_layoutflags & IOBLAYOUTF_NormalImage))) + { + DoMethod(o, IDTM_Layout, + gpr->gpr_GInfo->gi_Screen, + gpr->gpr_GInfo->gi_Window, + rp, + gpr->gpr_GInfo->gi_DrInfo, + (gg->Flags & GFLG_SELECTED) ? IOLAYOUTF_SelectedImage : IOLAYOUTF_NormalImage); + } + + DoMethod(o, IDTM_Draw, + gpr->gpr_GInfo->gi_Screen, + gpr->gpr_GInfo->gi_Window, + rp, + gpr->gpr_GInfo->gi_DrInfo, + -gpr->gpr_GInfo->gi_Domain.Left, + -gpr->gpr_GInfo->gi_Domain.Top, + 0); + + if (GM_RENDER != gpr->MethodID) + ReleaseGIRPort(rp); + } + + return 0; +} + +//----------------------------------------------------------------------------- + +static ULONG DtErase(Class *cl, Object *o, struct iopErase *iope) +{ + struct InstanceData *inst = INST_DATA(cl, o); + struct ExtGadget *gg = (struct ExtGadget *) o; + + d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + + // Erase icon image + EraseRect(iope->iope_RastPort, + iope->iope_XOffset + gg->LeftEdge, + iope->iope_YOffset + gg->TopEdge, + iope->iope_XOffset + gg->LeftEdge + gg->Width - 1, + iope->iope_YOffset + gg->TopEdge + gg->Height - 1); + + // Erase icon text + EraseIconText(cl, o, + iope->iope_RastPort, + iope->iope_YOffset + gg->TopEdge, + iope->iope_XOffset + gg->LeftEdge); + + return 0; +} + +//----------------------------------------------------------------------------- + +static ULONG DtFindToolType(Class *cl, Object *o, struct iopFindToolType *ioft) +{ + struct InstanceData *inst = INST_DATA(cl, o); + ULONG Result = 0; + + d1(kprintf("%s/%s/%ld: o=%08lx inst=%08lx Start=%08lx Name=<%s>\n", \ + __FILE__, __FUNC__, __LINE__, o, inst, *ioft->ioftt_ToolTypeValue, ioft->ioftt_ToolTypeName)); + + if (inst->iobj_tooltypes) + { + STRPTR *TTSearch = inst->iobj_tooltypes; + + if (*ioft->ioftt_ToolTypeValue) + { + // Start search from given position + TTSearch = ioft->ioftt_ToolTypeValue; + + // find starting point inf tooltypes array + while (*TTSearch) + { + if (*TTSearch == *ioft->ioftt_ToolTypeValue) + break; + TTSearch++; + } + + d1(kprintf("%s/%s/%ld: Start=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, TTSearch, *TTSearch)); + } + + while (*TTSearch) + { + d1(kprintf("%s/%s/%ld: Search=<%s>\n", __FILE__, __FUNC__, __LINE__, *TTSearch)); + + if (ToolTypeNameCmp(ioft->ioftt_ToolTypeName, *TTSearch)) + { + // Found! + Result = 1; + d1(kprintf("%s/%s/%ld: Found=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, TTSearch, *TTSearch)); + *ioft->ioftt_ToolTypeValue = *TTSearch; + break; + } + TTSearch++; + } + } + + d1(kprintf("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + + return Result; +} + +//----------------------------------------------------------------------------- + +static ULONG DtGetToolTypeValue(Class *cl, Object *o, struct iopGetToolTypeValue *iotv) +{ +// struct InstanceData *inst = INST_DATA(cl, o); + ULONG Result = 0; + STRPTR tt = iotv->iotv_ToolTypeValue; + + d1(kprintf("%s/%s/%ld: ToolType=<%s>\n", __FILE__, __FUNC__, __LINE__, tt, tt ? tt : (UBYTE *) "")); + + if (tt) + { + while (*tt && '=' != *tt) + tt++; + + if ('=' == *tt) + { + ++tt; // Skip "=" + + d1(kprintf("%s/%s/%ld: Value=<%s>\n", __FILE__, __FUNC__, __LINE__, tt)); + + if ('$' == *tt || (strlen(tt) > 2 && 0 == Stricmp(tt, "0x"))) + { + // Hex string recognized + LONG HexVal = 0; + + Result = 1; + + while (*tt) + { + UBYTE ch = ToUpper(*tt++); + + if (!isxdigit(ch)) + { + Result = 0; + break; + } + + if (ch <= '9') + HexVal = (HexVal << 4) + (ch - '0'); + else + HexVal = (HexVal << 4) + (ch - 55); + } + + if (Result) + *iotv->iotv_Value = HexVal; + } + else + { + // Decimal string expected + if (-1 != StrToLong(tt, iotv->iotv_Value)) + Result = 1; // Success! + } + } + } + + d1(kprintf("%s/%s/%ld: Result=%ld Value=%ld\n", __FILE__, __FUNC__, __LINE__, Result, *iotv->iotv_Value)); + + return Result; +} + +//----------------------------------------------------------------------------- + +static ULONG DtDraw(Class *cl, Object *o, struct iopDraw *iopd) +{ + struct InstanceData *inst = INST_DATA(cl, o); + struct ExtGadget *gg = (struct ExtGadget *) o; + struct RastPort *rp; + PLANEPTR MaskPlanePtr; + WORD Left, Top; + + d1(KPrintF("%s/%s/%ld: START o=%08lx <%s> inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst->iobj_text, inst)); + d1(KPrintF("%s/%s/%ld: iobj_selmaskbm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_SelectedMask.iom_MaskBM)); + + ObtainSemaphoreShared(&inst->iobj_LayoutSemaphore); + + if (inst->iobj_layoutflags & IOBLAYOUTF_ScaleNormal) + { + d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + ScaleRenderBitMapsNormal(cl, o, + inst->iobj_ScaledWidth, inst->iobj_ScaledHeight, + iopd->iopd_Screen); + } + if (inst->iobj_layoutflags & IOBLAYOUTF_ScaleSelected) + { + d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + ScaleRenderBitMapsSelected(cl, o, + inst->iobj_ScaledWidth, inst->iobj_ScaledHeight, + iopd->iopd_Screen); + } + + if (gg->Flags & GFLG_SELECTED) + { + d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx iobj_selmaskbm=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst, inst->iobj_SelectedMask.iom_MaskBM)); + rp = (struct RastPort *) gg->SelectRender; + MaskPlanePtr = inst->iobj_SelectedMask.iom_MaskBM ? inst->iobj_SelectedMask.iom_MaskBM->Planes[0] : NULL; + + d1(DumpMask(&inst->iobj_SelectedMask)); + + if (rp && (inst->iobj_layoutflags & IOBLAYOUTF_BackfillSelected)) + { + inst->iobj_layoutflags &= ~IOBLAYOUTF_BackfillSelected; + d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx iobj_BackfillPenSel=%ld\n", __FILE__, __FUNC__, __LINE__, o, inst, inst->iobj_BackfillPenSel)); + + if (IDTA_BACKFILL_NONE != inst->iobj_BackfillPenSel) + { + // Fill transparent parts of icon with backfill color via inverted mask + d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx rp=%08lx iobj_BackfillRp=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst, rp, inst->iobj_BackfillRp)); + + ASSERT_d1(gg->Width < GetBitMapAttr(rp->BitMap, BMA_WIDTH)); + ASSERT_d1(gg->Height < GetBitMapAttr(rp->BitMap, BMA_HEIGHT)); + + SetRast(inst->iobj_BackfillRp, inst->iobj_BackfillPenSel); + d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + BltMaskBitMapRastPort(inst->iobj_BackfillRp->BitMap, + 0, 0, + rp, 0, 0, + gg->Width, gg->Height, + ABC | ABNC | ANBC, + inst->iobj_SelectedMask.iom_MaskInvBM->Planes[0]); + + d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx iobj_BackfillRp=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst, inst->iobj_BackfillRp)); + } + } + } + else + { + rp = (struct RastPort *) gg->GadgetRender; + MaskPlanePtr = inst->iobj_NormalMask.iom_MaskBM ? inst->iobj_NormalMask.iom_MaskBM->Planes[0] : NULL; + + d1(DumpMask(&inst->iobj_NormalMask)); + + if (rp && (inst->iobj_layoutflags & IOBLAYOUTF_BackfillNormal)) + { + inst->iobj_layoutflags &= ~IOBLAYOUTF_BackfillNormal; + d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx iobj_BackfillPenNorm=%ld\n", __FILE__, __FUNC__, __LINE__, o, inst, inst->iobj_BackfillPenNorm)); + + if (IDTA_BACKFILL_NONE != inst->iobj_BackfillPenNorm) + { + // Fill transparent parts of icon with backfill color via inverted mask + ASSERT_d1(gg->Width < GetBitMapAttr(rp->BitMap, BMA_WIDTH)); + ASSERT_d1(gg->Height < GetBitMapAttr(rp->BitMap, BMA_HEIGHT)); + + SetRast(inst->iobj_BackfillRp, inst->iobj_BackfillPenNorm); + BltMaskBitMapRastPort(inst->iobj_BackfillRp->BitMap, + 0, 0, + rp, 0, 0, + gg->Width, gg->Height, + ABC | ABNC | ANBC, + inst->iobj_NormalMask.iom_MaskInvBM->Planes[0]); + } + } + } + + GetPosition(iopd, gg, &Left, &Top); + + if (rp && !(iopd->iopd_DrawFlags & IODRAWF_NoImage)) + { + d1(KPrintF("%s/%s/%ld: o=%08lx rp=%08lx BitMap=%08lx\n", __FILE__, __FUNC__, __LINE__, o, rp, rp->BitMap)); + d1(KPrintF("%s/%s/%ld: Bytes=%ld Rows=%ld Flags=%02lx Depth=%ld\n", \ + __FILE__, __FUNC__, __LINE__, rp->BitMap->BytesPerRow, rp->BitMap->Rows, rp->BitMap->Flags, rp->BitMap->Depth)); + + if (inst->iobj_NormalARGB.iargb_ARGBimage.argb_ImageData && CyberGfxBase + && GetCyberMapAttr(iopd->iopd_Screen->RastPort.BitMap, CYBRMATTR_ISCYBERGFX)) + { + LONG x, y; + + d1(KPrintF("%s/%s/%ld: draw via ARGB_Draw o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + + x = iopd->iopd_XOffset; + y = iopd->iopd_YOffset; + + if (IODRAWF_AbsolutePos & iopd->iopd_DrawFlags) + { + if (!(IODRAWF_NoText & iopd->iopd_DrawFlags)) + { + x += gg->LeftEdge - gg->BoundsLeftEdge; + y += gg->TopEdge - gg->BoundsTopEdge; + } + } + else + { + x += gg->LeftEdge; + y += gg->TopEdge; + } + + ARGB_Draw(cl, o, iopd, x, y); + } + else + { + ULONG BackfillPen = (gg->Flags & GFLG_SELECTED) ? inst->iobj_BackfillPenSel : inst->iobj_BackfillPenNorm; + + if (!(iopd->iopd_DrawFlags & IODRAWF_NoEraseBg)) + { + // Erase icon background + d1(KPrintF("%s/%s/%ld: erase background o=%08lx inst=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, o, inst)); + + EraseRect(iopd->iopd_RastPort, + Left, Top, + Left + gg->Width - 1, + Top + gg->Height - 1); + } + + d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx MaskPlanePtr=%08lx BackfillPen=%ld\n", __FILE__, __FUNC__, __LINE__, o, inst, MaskPlanePtr, BackfillPen)); + + if (MaskPlanePtr && (IDTA_BACKFILL_NONE == BackfillPen)) + { + ASSERT_d1(gg->Width < GetBitMapAttr(iopd->iopd_RastPort->BitMap, BMA_WIDTH)); + ASSERT_d1(gg->Height < GetBitMapAttr(iopd->iopd_RastPort->BitMap, BMA_HEIGHT)); + + d1(KPrintF("%s/%s/%ld: NormMaskWidth=%lu NormMaskHeight=%lu\n", __FILE__, __FUNC__, __LINE__, inst->iobj_NormalMask.iom_Width, inst->iobj_NormalMask.iom_Height)); + d1(KPrintF("%s/%s/%ld: SelMaskWidth=%lu SelMaskHeight=%lu\n", __FILE__, __FUNC__, __LINE__, inst->iobj_SelectedMask.iom_Width, inst->iobj_SelectedMask.iom_Height)); + d1(KPrintF("%s/%s/%ld: iom_MaskBM: Width=%lu Height=%lu Depth=%lu Flags=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + GetBitMapAttr(inst->iobj_NormalMask.iom_MaskBM, BMA_WIDTH), \ + GetBitMapAttr(inst->iobj_NormalMask.iom_MaskBM, BMA_HEIGHT), \ + GetBitMapAttr(inst->iobj_NormalMask.iom_MaskBM, BMA_DEPTH), \ + GetBitMapAttr(inst->iobj_NormalMask.iom_MaskBM, BMA_FLAGS))); + d1(KPrintF("%s/%s/%ld: gg->Width=%lu gg->Height=%lu\n", __FILE__, __FUNC__, __LINE__, gg->Width, gg->Height)); + d1(KPrintF("%s/%s/%ld: use BltMaskBitMapRastPort o=%08lx inst=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, o, inst)); + + d1(DumpMaskPlane(&inst->iobj_NormalMask)); + d1(DumpMaskPlane(&inst->iobj_SelectedMask)); + + BltMaskBitMapRastPort(rp->BitMap, + 0, 0, + iopd->iopd_RastPort, + Left, Top, + gg->Width, gg->Height, + ABC | ABNC | ANBC, + MaskPlanePtr); + } + else + { + ASSERT_d1(gg->Width < GetBitMapAttr(iopd->iopd_RastPort->BitMap, BMA_WIDTH)); + ASSERT_d1(gg->Height < GetBitMapAttr(iopd->iopd_RastPort->BitMap, BMA_HEIGHT)); + + d1(KPrintF("%s/%s/%ld: use ClipBlit o=%08lx inst=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, o, inst)); + ClipBlit(rp, 0, 0, + iopd->iopd_RastPort, + Left, Top, gg->Width, gg->Height, + ABC | ABNC); + } + } + } + + if (rp && !(iopd->iopd_DrawFlags & IODRAWF_NoText)) + { + d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + if (inst->iobj_text) + DrawIconText(cl, o, iopd); + } + + ReleaseSemaphore(&inst->iobj_LayoutSemaphore); + + d1(KPrintF("%s/%s/%ld: END o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + + return 0; +} + +//----------------------------------------------------------------------------- + +static ULONG DtLayout(Class *cl, Object *o, struct iopLayout *iopl) +{ + struct InstanceData *inst = INST_DATA(cl, o); + struct ExtGadget *gg = (struct ExtGadget *) o; + + d1(KPrintF("%s/%s/%ld: START o=%08lx <%s> inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst->iobj_text, inst)); + TIMESTAMP_d1(); + + ObtainSemaphore(&inst->iobj_LayoutSemaphore); + + d1(KPrintF("%s/%s/%ld: iargb_ARGBimage w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \ + inst->iobj_NormalARGB.iargb_ARGBimage.argb_Width, \ + inst->iobj_NormalARGB.iargb_ARGBimage.argb_Height)); + d1(KPrintF("%s/%s/%ld: iobj_layoutflags=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_layoutflags)); + + if (inst->iobj_UnscaledNakedWidth != inst->iobj_NakedWidth + || inst->iobj_UnscaledNakedHeight != inst->iobj_NakedHeight + || (inst->iobj_layoutflags & (IOBLAYOUTF_ScaleNormal | IOBLAYOUTF_ScaleSelected))) + { + // We need to scale the icon! + d1(KPrintF("%s/%s/%ld: UnscaledWidth=%lu UnscaledHeight=%lu\n", __FILE__, __FUNC__, __LINE__, inst->iobj_UnscaledWidth, inst->iobj_UnscaledHeight)); + d1(KPrintF("%s/%s/%ld: ScaledWidth=%lu ScaledHeight=%lu\n", __FILE__, __FUNC__, __LINE__, inst->iobj_ScaledWidth, inst->iobj_ScaledHeight)); + + DoMethod(o, IDTM_ScaleIcon, + inst->iobj_NakedWidth, inst->iobj_NakedHeight, + iopl->iopl_Flags); + } + + TIMESTAMP_d1(); + + d1(KPrintF("%s/%s/%ld: iargb_ARGBimage w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \ + inst->iobj_NormalARGB.iargb_ARGBimage.argb_Width, \ + inst->iobj_NormalARGB.iargb_ARGBimage.argb_Height)); + + LayoutIconSize(cl, o, iopl->iopl_RastPort); + + d1(KPrintF("%s/%s/%ld: iargb_ARGBimage w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \ + inst->iobj_NormalARGB.iargb_ARGBimage.argb_Width, \ + inst->iobj_NormalARGB.iargb_ARGBimage.argb_Height)); + + d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + TIMESTAMP_d1(); + + // If ARGB image data present, allocate auxiliary buffer for rendering + if (inst->iobj_NormalARGB.iargb_ARGBimage.argb_ImageData) + { + d1(KPrintF("%s/%s/%ld: iopl=%08lx iopl_Flags=%08lx\n", __FILE__, __FUNC__, __LINE__, iopl, iopl->iopl_Flags)); + + LayoutARGB(cl, o, &inst->iobj_NormalARGB); + + d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + + // If selected ARGB image data present, allocate auxiliary buffer for rendering + if (inst->iobj_SelectedARGB.iargb_ARGBimage.argb_ImageData) + { + d1(KPrintF("%s/%s/%ld: iopl=%08lx iopl_Flags=%08lx\n", __FILE__, __FUNC__, __LINE__, iopl, iopl->iopl_Flags)); + + LayoutARGB(cl, o, &inst->iobj_SelectedARGB); + + d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + } + } + + d1(KPrintF("%s/%s/%ld: iopl=%08lx iopl_Flags=%08lx\n", __FILE__, __FUNC__, __LINE__, iopl, iopl->iopl_Flags)); + TIMESTAMP_d1(); + + if (!(inst->iobj_layoutflags & (IOBLAYOUTF_NormalImage | IOBLAYOUTF_SelectedImage)) + && (iopl->iopl_Flags & (IOLAYOUTF_NormalImage | IOLAYOUTF_SelectedImage)) + && (IDTA_BACKFILL_NONE != inst->iobj_BackfillPenNorm)) + { + inst->iobj_BackfillRp = InitRast(cl, o, iopl, &inst->iobj_BackfillRastPort); + inst->iobj_layoutflags |= IOBLAYOUTF_BackfillNormal | IOBLAYOUTF_BackfillSelected; + } + + TIMESTAMP_d1(); + + if (!(inst->iobj_layoutflags & IOBLAYOUTF_NormalImage) + && (iopl->iopl_Flags & IOLAYOUTF_NormalImage) + && NULL == gg->GadgetRender) + { + gg->GadgetRender = InitRast(cl, o, iopl, &inst->iobj_RenderRastPort); + + d1(KPrintF("%s/%s/%ld: IOBLAYOUTF_NormalImage GadgetRender=%08lx\n", __FILE__, __FUNC__, __LINE__, gg->GadgetRender)); + TIMESTAMP_d1(); + + if (gg->GadgetRender) + { + struct RastPort *rp = (struct RastPort *) gg->GadgetRender; + ULONG BackfillPen = (gg->Flags & GFLG_SELECTED) ? inst->iobj_BackfillPenSel : inst->iobj_BackfillPenNorm; + + if (!(inst->iobj_layoutflags & IOBLAYOUTF_ScaleNormal)) + { + d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + DrawFrame(cl, o, rp, + inst->iobj_UnscaledWidth, + inst->iobj_UnscaledHeight, + inst->iobj_frametype); + } + + inst->iobj_layoutflags |= IOBLAYOUTF_NormalImage; + TIMESTAMP_d1(); + + d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx BackfillPen=%ld\n", __FILE__, __FUNC__, __LINE__, o, inst, BackfillPen)); + if (IDTA_BACKFILL_NONE != BackfillPen) + { + SetAPen(rp, BackfillPen); + RectFill(rp, + inst->iobj_imgleft, inst->iobj_imgtop, + gg->Width - inst->iobj_imgleft - inst->iobj_imgright - 1, + gg->Height - inst->iobj_imgtop - inst->iobj_imgbottom - 1); + } + + TIMESTAMP_d1(); + + // mask bitmap already generated? + if (NULL == inst->iobj_NormalMask.iom_MaskBM) + { + d1(KPrintF("%s/%s/%ld: NormMaskWidth=%lu NormMaskHeight=%lu\n", __FILE__, __FUNC__, __LINE__, \ + inst->iobj_NormalMask.iom_Width, inst->iobj_NormalMask.iom_Height)); + d1(KPrintF("%s/%s/%ld: iobj_NakedMaskWidth=%ld iobj_NakedMaskHeight=%ld\n", \ + __FILE__, __FUNC__, __LINE__, inst->iobj_NakedMaskWidth, inst->iobj_NakedMaskHeight)); + + inst->iobj_NormalMask.iom_MaskBM = GenMask(cl, o, + GetBitMapAttr(rp->BitMap, BMA_WIDTH), + GetBitMapAttr(rp->BitMap, BMA_HEIGHT), + GetBitMapAttr(rp->BitMap, BMA_DEPTH), + GetBitMapAttr(rp->BitMap, BMA_FLAGS), + inst->iobj_NormalMask.iom_Mask, + (inst->iobj_layoutflags & IOBLAYOUTF_ScaleNormal) ? FRAMETYPE_NONE : inst->iobj_frametype, + inst->iobj_NormalMask.iom_Width, + inst->iobj_NormalMask.iom_Height); + + d1(KPrintF("%s/%s/%ld: iom_Width=%ld iom_Height=%ld\n", \ + __FILE__, __FUNC__, __LINE__, inst->iobj_NormalMask.iom_Width, inst->iobj_NormalMask.iom_Height)); + + d1(DumpMaskBM(&inst->iobj_NormalMask)); + } + TIMESTAMP_d1(); + if (IDTA_BACKFILL_NONE != BackfillPen) + { + inst->iobj_NormalMask.iom_MaskInvBM = GenInvMask(cl, o, inst->iobj_NormalMask.iom_MaskBM); + } + } + } + + d1(KPrintF("%s/%s/%ld: iopl=%08lx iopl_Flags=%08lx\n", __FILE__, __FUNC__, __LINE__, iopl, iopl->iopl_Flags)); + TIMESTAMP_d1(); + + if (!(inst->iobj_layoutflags & IOBLAYOUTF_SelectedImage) + && (iopl->iopl_Flags & IOLAYOUTF_SelectedImage) + && NULL == gg->SelectRender) + { + gg->SelectRender = InitRast(cl, o, iopl, &inst->iobj_SelectRastPort); + + d1(KPrintF("%s/%s/%ld: IOBLAYOUTF_SelectedImage SelectRender=%08lx\n", __FILE__, __FUNC__, __LINE__, gg->SelectRender)); + + if (gg->SelectRender) + { + struct RastPort *rp = (struct RastPort *) gg->SelectRender; + ULONG BackfillPen = (gg->Flags & GFLG_SELECTED) ? inst->iobj_BackfillPenSel : inst->iobj_BackfillPenNorm; + + if (!(inst->iobj_layoutflags & IOBLAYOUTF_ScaleSelected)) + { + d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + DrawFrame(cl, o, rp, + inst->iobj_UnscaledWidth, + inst->iobj_UnscaledHeight, + inst->iobj_frametypesel); + } + + inst->iobj_layoutflags |= IOBLAYOUTF_SelectedImage; + + if (IDTA_BACKFILL_NONE != BackfillPen) + { + SetAPen(rp, BackfillPen); + RectFill(rp, + inst->iobj_imgleft, inst->iobj_imgtop, + gg->Width - inst->iobj_imgleft - inst->iobj_imgright - 1, + gg->Height - inst->iobj_imgtop - inst->iobj_imgbottom - 1); + } + + // mask bitmap already generated? + if (NULL == inst->iobj_SelectedMask.iom_MaskBM) + { + d1(KPrintF("%s/%s/%ld: SelMaskWidth=%lu SelMaskHeight=%lu\n", __FILE__, __FUNC__, __LINE__, inst->iobj_SelectedMask.iom_Width, inst->iobj_SelectedMask.iom_Height)); + + inst->iobj_SelectedMask.iom_MaskBM = GenMask(cl, o, + GetBitMapAttr(rp->BitMap, BMA_WIDTH), + GetBitMapAttr(rp->BitMap, BMA_HEIGHT), + GetBitMapAttr(rp->BitMap, BMA_DEPTH), + GetBitMapAttr(rp->BitMap, BMA_FLAGS), + inst->iobj_SelectedMask.iom_Mask, + (inst->iobj_layoutflags & IOBLAYOUTF_ScaleSelected) ? FRAMETYPE_NONE : inst->iobj_frametypesel, + inst->iobj_SelectedMask.iom_Width, + inst->iobj_SelectedMask.iom_Height); + + d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx iobj_selmask=%08lx iobj_selmaskbm=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, o, inst, inst->iobj_SelectedMask.iom_Mask, inst->iobj_SelectedMask.iom_MaskBM)); + } + if (IDTA_BACKFILL_NONE != BackfillPen) + { + inst->iobj_SelectedMask.iom_MaskInvBM = GenInvMask(cl, o, inst->iobj_SelectedMask.iom_MaskBM); + } + } + d1(KPrintF("%s/%s/%ld: iobj_selmaskbm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_SelectedMask.iom_MaskBM)); + } + + ReleaseSemaphore(&inst->iobj_LayoutSemaphore); + + d1(KPrintF("%s/%s/%ld: layoutflags=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_layoutflags)); + d1(KPrintF("%s/%s/%ld: END.\n", __FILE__, __FUNC__, __LINE__)); + TIMESTAMP_d1(); + + return 0; +} + +//----------------------------------------------------------------------------- + +static ULONG DtFreeLayout(Class *cl, Object *o, struct iopFreeLayout *opf) +{ + struct InstanceData *inst = INST_DATA(cl, o); + struct ExtGadget *gg = (struct ExtGadget *) o; + + d1(KPrintF("%s/%s/%ld: START o=%08lx <%s> inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst->iobj_text, inst)); + + ObtainSemaphore(&inst->iobj_LayoutSemaphore); + + FreeARGBImageLayout(&inst->iobj_NormalARGB); + FreeARGBImageLayout(&inst->iobj_SelectedARGB); + + if (inst->iobj_BackfillRp) + { + if (inst->iobj_BackfillRp->BitMap) + { + d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_BackfillRp->BitMap)); + FreeBitMap(inst->iobj_BackfillRp->BitMap); + inst->iobj_BackfillRp->BitMap = NULL; + } + + inst->iobj_BackfillRp = NULL; + } + if (gg->SelectRender) + { + struct RastPort *rp = (struct RastPort *) gg->SelectRender; + + if (rp->BitMap) + { + d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, rp->BitMap)); + FreeBitMap(rp->BitMap); + rp->BitMap = NULL; + } + + gg->SelectRender = NULL; + } + if (gg->GadgetRender) + { + struct RastPort *rp = (struct RastPort *) gg->GadgetRender; + + if (rp->BitMap) + { + d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, rp->BitMap)); + FreeBitMap(rp->BitMap); + rp->BitMap = NULL; + } + gg->GadgetRender = NULL; + } + if (inst->iobj_NormalMask.iom_MaskBM) + { + d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_NormalMask.iom_MaskBM)); + FreeBitMap(inst->iobj_NormalMask.iom_MaskBM); + inst->iobj_NormalMask.iom_MaskBM = NULL; + } + if (inst->iobj_SelectedMask.iom_MaskBM) + { + d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_SelectedMask.iom_MaskBM)); + FreeBitMap(inst->iobj_SelectedMask.iom_MaskBM); + inst->iobj_SelectedMask.iom_MaskBM = NULL; + } + if (inst->iobj_NormalMask.iom_MaskInvBM) + { + d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_NormalMask.iom_MaskInvBM)); + FreeBitMap(inst->iobj_NormalMask.iom_MaskInvBM); + inst->iobj_NormalMask.iom_MaskInvBM = NULL; + } + if (inst->iobj_SelectedMask.iom_MaskInvBM) + { + d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_SelectedMask.iom_MaskInvBM)); + FreeBitMap(inst->iobj_SelectedMask.iom_MaskInvBM); + inst->iobj_SelectedMask.iom_MaskInvBM = NULL; + } + + // Remove borders + gg->Width = inst->iobj_NakedWidth; + gg->Height = inst->iobj_NakedHeight; + + inst->iobj_UnscaledWidth = inst->iobj_UnscaledNakedWidth; + inst->iobj_UnscaledHeight = inst->iobj_UnscaledNakedHeight; + + d1(KPrintF("%s/%s/%ld: iobj_NakedMaskWidth=%ld iobj_NakedMaskHeight=%ld\n", \ + __FILE__, __FUNC__, __LINE__, inst->iobj_NakedMaskWidth, inst->iobj_NakedMaskHeight)); + d1(KPrintF("%s/%s/%ld: iobj_imgleft=%ld iobj_imgright=%ld\n", \ + __FILE__, __FUNC__, __LINE__, inst->iobj_imgleft, inst->iobj_imgright)); + d1(KPrintF("%s/%s/%ld: iobj_imgtop=%ld iobj_imgbottom=%ld\n", \ + __FILE__, __FUNC__, __LINE__, inst->iobj_imgtop, inst->iobj_imgbottom)); + + inst->iobj_layoutflags &= (IOBLAYOUTF_ScaleNormal | IOBLAYOUTF_ScaleSelected); + + d1(KPrintF("%s/%s/%ld: END layoutflags=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_layoutflags)); + + ReleaseSemaphore(&inst->iobj_LayoutSemaphore); + + return DoSuperMethodA(cl, o, (Msg) opf); +} + +//---------------------------------------------------------------------------------------- + +static ULONG DtSet(Class *cl, Object *o, struct opSet *ops) +{ + struct InstanceData *inst = INST_DATA(cl, o); + ULONG Result; + + d1(KPrintF("%s/%s/%ld: START o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, INST_DATA(cl, o))); + + // Make sure we have no pending layout when settings are changed! + ObtainSemaphore(&inst->iobj_LayoutSemaphore); + + Result = DoSuperMethodA(cl, o, (Msg) ops); + + SetTags(cl, o, ops); + + ReleaseSemaphore(&inst->iobj_LayoutSemaphore); + + d1(KPrintF("%s/%s/%ld: END o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, INST_DATA(cl, o))); + + return Result; +} + +//---------------------------------------------------------------------------------------- + +static ULONG DtGet(Class *cl, Object *o, struct opGet *opg) +{ + struct InstanceData *inst = INST_DATA(cl, o); + ULONG result = 1; + struct TagItem AttrList[2]; + + AttrList[0].ti_Tag = opg->opg_AttrID; + AttrList[0].ti_Data = (ULONG) opg->opg_Storage; + AttrList[1].ti_Tag = TAG_END; + UnpackStructureTags(inst, packTable, AttrList); + + switch (opg->opg_AttrID) + { + case IDTA_Text: + *opg->opg_Storage = (ULONG) inst->iobj_text; + break; + + case IDTA_LayoutFlags: + *opg->opg_Storage = inst->iobj_layoutflags; + break; + + case IDTA_DefaultTool: + *opg->opg_Storage = (ULONG) inst->iobj_defaulttool; + break; + + case IDTA_ToolWindow: + *opg->opg_Storage = (ULONG) inst->iobj_ToolWindow; + break; + + case IDTA_Mask_Normal: + *opg->opg_Storage = (ULONG) ((inst->iobj_NormalMask.iom_MaskBM && (IDTA_BACKFILL_NONE == inst->iobj_BackfillPenNorm)) + ? inst->iobj_NormalMask.iom_MaskBM->Planes[0] : NULL); + break; + + case IDTA_Mask_Selected: + *opg->opg_Storage = (ULONG) ((inst->iobj_SelectedMask.iom_MaskBM && (IDTA_BACKFILL_NONE == inst->iobj_BackfillPenSel)) + ? inst->iobj_SelectedMask.iom_MaskBM->Planes[0] : NULL); + break; + + case IDTA_MaskBM_Normal: + *opg->opg_Storage = (ULONG) ((IDTA_BACKFILL_NONE == inst->iobj_BackfillPenNorm) ? inst->iobj_NormalMask.iom_MaskBM : NULL); + break; + + case IDTA_MaskBM_Selected: + *opg->opg_Storage = (ULONG) ((IDTA_BACKFILL_NONE == inst->iobj_BackfillPenSel) ? inst->iobj_SelectedMask.iom_MaskBM : NULL); + break; + + case IDTA_AlphaChannel: + *opg->opg_Storage = (ULONG) inst->iobj_NormalARGB.iargb_AlphaChannel; + break; + + case IDTA_SelAlphaChannel: + *opg->opg_Storage = (ULONG) inst->iobj_SelectedARGB.iargb_AlphaChannel; + break; + + case IDTA_ARGBImageData: + *opg->opg_Storage = (ULONG) &inst->iobj_NormalARGB.iargb_ARGBimage; + d1(KPrintF("%s/%s/%ld: argbh=%08lx argb_ImageData=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, &inst->iobj_NormalARGB.iargb_ARGBimage, + inst->iobj_NormalARGB.iargb_ARGBimage.argb_ImageData)); + break; + + case IDTA_SelARGBImageData: + *opg->opg_Storage = (ULONG) &inst->iobj_SelectedARGB.iargb_ARGBimage; + d1(KPrintF("%s/%s/%ld: argbh=%08lx argb_ImageData=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, &inst->iobj_SelectedARGB.iargb_ARGBimage, + inst->iobj_SelectedARGB.iargb_ARGBimage.argb_ImageData)); + break; + + case IDTA_ToolTypes: + *opg->opg_Storage = (ULONG) inst->iobj_tooltypes; + break; + + case DTA_Name: + *opg->opg_Storage = (ULONG) inst->iobj_name; + break; + + case IDTA_UnscaledWidth: + *opg->opg_Storage = (ULONG) inst->iobj_UnscaledWidth; + break; + + case IDTA_UnscaledHeight: + *opg->opg_Storage = (ULONG) inst->iobj_UnscaledHeight; + break; + + case IDTA_WindowRect: + switch (inst->iobj_type) + { + case WBDISK: + case WBDRAWER: + case WBGARBAGE: + d1(kprintf("%s/%s/%ld: IDTA_WindowRect <%s> Left=%ld Top=%ld Width=%ld Height=%ld\n", __FILE__, __FUNC__, __LINE__, \ + inst->iobj_text, inst->iobj_winrect.Left, inst->iobj_winrect.Top, \ + inst->iobj_winrect.Width, inst->iobj_winrect.Height)); + + if (0 != inst->iobj_winrect.Width && 0 != inst->iobj_winrect.Height) + *opg->opg_Storage = (ULONG) &inst->iobj_winrect; + else + *opg->opg_Storage = (ULONG) NULL; + break; + default: + result = 0; + break; + } + break; + + default: + result = DoSuperMethodA(cl, o, (Msg) opg); + break; + } + + return result; +} + +//---------------------------------------------------------------------------------------- + +static ULONG DtScaleIcon(Class *cl, Object *o, struct iopScaleIcon *iops) +{ + struct InstanceData *inst = INST_DATA(cl, o); + ULONG NewWidth, NewHeight; + ULONG Success; + struct Hook *RenderHook = NULL; + + d1(KPrintF("%s/%s/%ld: START o=%08lx <%s> inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst->iobj_name, inst)); + + GetAttr(IDTA_RenderHook, o, (APTR) &RenderHook); + if (RenderHook) + return FALSE; // No scaling with RenderHook + + NewWidth = iops->iops_NewWidth; + NewHeight = iops->iops_NewHeight; + + d1(KPrintF("%s/%s/%ld: NewWidth=%lu NewHeight=%lu\n", __FILE__, __FUNC__, __LINE__, NewWidth, NewHeight)); + + ObtainSemaphore(&inst->iobj_LayoutSemaphore); + + if (inst->iobj_NormalARGB.iargb_ARGBimage.argb_ImageData) + { + // Scale ARGB icon + ULONG ScaleFlags = SCALEFLAGF_DOUBLESIZE | SCALEFLAGF_BILINEAR + | SCALEFLAGF_AVERAGE; + + Success = ScaleARGB(cl, o, &inst->iobj_NormalARGB, &inst->iobj_NormalMask, + NewWidth, NewHeight, ScaleFlags); + + if (Success && inst->iobj_SelectedARGB.iargb_ARGBimage.argb_ImageData) + { + ScaleARGB(cl, o, &inst->iobj_SelectedARGB, + &inst->iobj_SelectedMask, NewWidth, NewHeight, ScaleFlags); + } + + // Mask and Alpha are automatically recreated during IDTM_Layout + + if (Success) + { + // Mask will be generated in scaled size + inst->iobj_NakedMaskWidth = NewWidth; + inst->iobj_NakedMaskHeight = NewHeight; + d1(KPrintF("%s/%s/%ld: NormMaskWidth=%lu NormMaskHeight=%lu\n", __FILE__, __FUNC__, __LINE__, inst->iobj_NormalMask.iom_Width, inst->iobj_NormalMask.iom_Height)); + } + } + else + { + // Scaling is postponed until IDTM_Draw + d1(KPrintF("%s/%s/%ld: Scaling is postponed until IDTM_Draw\n", __FILE__, __FUNC__, __LINE__)); + + Success = TRUE; + + if (iops->iops_Flags & IOLAYOUTF_NormalImage) + inst->iobj_layoutflags |= IOBLAYOUTF_ScaleNormal; + if (iops->iops_Flags & IOLAYOUTF_SelectedImage) + inst->iobj_layoutflags |= IOBLAYOUTF_ScaleSelected; + } + + if (Success) + { + inst->iobj_NakedWidth = NewWidth; + inst->iobj_NakedHeight = NewHeight; + + inst->iobj_layoutflags &= ~IOBLAYOUTF_Size; + } + + ReleaseSemaphore(&inst->iobj_LayoutSemaphore); + + d1(KPrintF("%s/%s/%ld: END Success=%ld layoutflags=%08lx\n", __FILE__, __FUNC__, __LINE__, Success, inst->iobj_layoutflags)); + + return Success; +} + +//---------------------------------------------------------------------------------------- + +static ULONG DoOmSet(Class *cl, Object *o, struct opSet *ops) +{ + struct InstanceData *inst = INST_DATA(cl, o); + + PackStructureTags(inst, packTable, ops->ops_AttrList); + + return 0; +} + +//---------------------------------------------------------------------------------------- + +static void LayoutIconText(struct InstanceData *inst, struct RastPort *rp, struct ExtGadget *gg) +{ + TIMESTAMP_d1(); + MySetFont(inst, rp, inst->iobj_Font); + + inst->iobj_FontBaseLine = MyGetFontBaseline(inst, rp); + + TIMESTAMP_d1(); + MySetSoftStyle(inst, rp, + inst->iobj_TextStyle, FSF_ITALIC | FSF_UNDERLINED | FSF_BOLD | FSF_EXTENDED); + + TIMESTAMP_d1(); + DoReLayout(inst, gg, rp); + + TIMESTAMP_d1(); + MyDoneRastPort(inst, rp); + + TIMESTAMP_d1(); +} + +//---------------------------------------------------------------------------------------- + +static void DrawIconText(Class *cl, Object *o, struct iopDraw *iopd) +{ + struct InstanceData *inst = INST_DATA(cl, o); + struct ExtGadget *gg = (struct ExtGadget *) o; + WORD x, y; + WORD TextX, TextY; + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + ObtainSemaphoreShared(&inst->iobj_TextSemaphore); + + GetPosition(iopd, gg, &x, &y); + + MySetFont(inst, iopd->iopd_RastPort, inst->iobj_Font); + + MySetSoftStyle(inst, iopd->iopd_RastPort, + inst->iobj_TextStyle, FSF_ITALIC | FSF_UNDERLINED | FSF_BOLD | FSF_EXTENDED); + + TextX = x - inst->iobj_GlobalTextLeftOffset + 1; + TextY = y + gg->Height + inst->iobj_textskip + inst->iobj_FontBaseLine; + + if (inst->iobj_SelectedTextRectangle) + { + TextY += inst->iobj_TextRectBorderY; + //TextX += inst->iobj_TextRectBorderX; + } + + if (gg->Flags & GFLG_SELECTED) + { + DrawIconTextRect(cl, o, iopd->iopd_RastPort, x, y); + } + else + { + EraseIconText(cl, o, iopd->iopd_RastPort, x, y); + } + +#if 0 + { + // TEST: Draw frame around image part + WORD x0, y0; + WORD x1, y1; + + y0 = y; + y1 = y0 + gg->Height - 1; + x0 = x; + x1 = x0 + gg->Width - 1; + + Move(iopd->iopd_RastPort, x0, y0); + Draw(iopd->iopd_RastPort, x0, y1); + Draw(iopd->iopd_RastPort, x1, y1); + Draw(iopd->iopd_RastPort, x1, y0); + Draw(iopd->iopd_RastPort, x0, y0); + } +#endif + +#if 0 + { + // TEST: Draw frame around entire icon + WORD x0, y0; + WORD x1, y1; + + y0 = y; + y1 = y0 + gg->BoundsHeight; + x0 = x + (gg->BoundsLeftEdge - gg->LeftEdge); + x1 = x0 + gg->BoundsWidth; + + SetAPen(iopd->iopd_RastPort, 1); + + Move(iopd->iopd_RastPort, x0, y0); + Draw(iopd->iopd_RastPort, x0, y1); + Draw(iopd->iopd_RastPort, x1, y1); + Draw(iopd->iopd_RastPort, x1, y0); + Draw(iopd->iopd_RastPort, x0, y0); + } +#endif + +#if 0 + { + // TEST: Draw frame around text part + WORD x0, y0; + WORD x1, y1; + + SetAPen(iopd->iopd_RastPort, 1); + + y0 = TextY - inst->iobj_FontBaseLine; + y1 = y0 + inst->iobj_TextExtent.te_Height; + x0 = TextX; + if (inst->iobj_SelectedTextRectangle) + x0 += inst->iobj_TextRectBorderX; + x1 = x0 + inst->iobj_TextExtent.te_Width; + + d1(KPrintF("%s/%s/%ld: Width=%ld Height=%ld\n", __FILE__, __FUNC__, __LINE__, x1 - x0, y1 - y0)); + + Move(iopd->iopd_RastPort, x0, y0); + Draw(iopd->iopd_RastPort, x0, y1); + Draw(iopd->iopd_RastPort, x1, y1); + Draw(iopd->iopd_RastPort, x1, y0); + Draw(iopd->iopd_RastPort, x0, y0); + } +#endif + if (IDTV_TextMode_Outline == inst->iobj_textmode) + { + // draw outline text + ULONG OrigDrMd; + + OrigDrMd = GetDrMd(iopd->iopd_RastPort); + + MySetTransparency(inst, iopd->iopd_RastPort, 255 / 2); // 50% transparent + SetAPen(iopd->iopd_RastPort, inst->iobj_TextPenOutline); + + DrawTextAt(inst, iopd->iopd_RastPort, TextX, TextY + 1); + DrawTextAt(inst, iopd->iopd_RastPort, TextX + 1, TextY); + DrawTextAt(inst, iopd->iopd_RastPort, TextX + 1, TextY + 2); + DrawTextAt(inst, iopd->iopd_RastPort, TextX + 2, TextY + 1); + DrawTextAt(inst, iopd->iopd_RastPort, TextX, TextY); + + SetAPen(iopd->iopd_RastPort, + (gg->Flags & GFLG_SELECTED) ? inst->iobj_TextPenSel : inst->iobj_TextPen); + + MySetTransparency(inst, iopd->iopd_RastPort, 0); // opaque + SetDrMd(iopd->iopd_RastPort, JAM1); + + DrawTextAt(inst, iopd->iopd_RastPort, TextX + 1, TextY + 1); + + SetDrMd(iopd->iopd_RastPort, OrigDrMd); + } + else if (IDTV_TextMode_Shadow == inst->iobj_textmode) + { + // draw shadow + ULONG OrigDrMd; + + OrigDrMd = GetDrMd(iopd->iopd_RastPort); + + SetAPen(iopd->iopd_RastPort, inst->iobj_TextPenShadow); + MySetTransparency(inst, iopd->iopd_RastPort, 255 / 2); // 50% transparent + + DrawTextAt(inst, iopd->iopd_RastPort, TextX + 1, TextY + 1); + + SetAPen(iopd->iopd_RastPort, + (gg->Flags & GFLG_SELECTED) ? inst->iobj_TextPenSel : inst->iobj_TextPen); + + SetDrMd(iopd->iopd_RastPort, JAM1); + MySetTransparency(inst, iopd->iopd_RastPort, 0); // opaque + + DrawTextAt(inst, iopd->iopd_RastPort, TextX, TextY); + + SetDrMd(iopd->iopd_RastPort, OrigDrMd); + } + else + { + // standard icon text + + SetABPenDrMd(iopd->iopd_RastPort, + (gg->Flags & GFLG_SELECTED) ? inst->iobj_TextPenSel : inst->iobj_TextPen, + inst->iobj_TextBackPen, + inst->iobj_TextDrawMode); + DrawTextAt(inst, iopd->iopd_RastPort, TextX, TextY); + } + + MyDoneRastPort(inst, iopd->iopd_RastPort); + + ReleaseSemaphore(&inst->iobj_TextSemaphore); +} + +//---------------------------------------------------------------------------------------- + +static void GetPosition(struct iopDraw *iopd, struct ExtGadget *gg, WORD *x, WORD *y) +{ + *x = iopd->iopd_XOffset; + *y = iopd->iopd_YOffset; + + if (iopd->iopd_DrawFlags & IODRAWF_AbsolutePos) + { + if (!(iopd->iopd_DrawFlags & IODRAWF_NoText)) + { + *x += gg->LeftEdge - gg->BoundsLeftEdge; + *y += gg->TopEdge - gg->BoundsTopEdge; + } + } + else + { + *x += gg->LeftEdge; + *y += gg->TopEdge; + + if (iopd->iopd_DrawFlags & IODRAWF_NoText) + { + *x -= gg->LeftEdge - gg->BoundsLeftEdge; + *y -= gg->TopEdge - gg->BoundsTopEdge; + } + } +} + +//---------------------------------------------------------------------------------------- + +static void DrawTextAt(struct InstanceData *inst, struct RastPort *rp, ULONG x, ULONG y) +{ + struct IconObjectTextLine *iotl; + ULONG n; + + for (n = 0; n < Sizeof(inst->iobj_TextLines); n++) + { + iotl = &inst->iobj_TextLines[n]; + + if (0 == iotl->iotl_numchars) + break; + + Move(rp, x + iotl->iotl_TextLeft, y); + MyText(inst, rp, inst->iobj_text + iotl->iotl_TextStart, iotl->iotl_numchars); + y += iotl->iotl_TextExtent.te_Height; + } +} + +//---------------------------------------------------------------------------------------- + +static void DoReLayout(struct InstanceData *inst, struct ExtGadget *gg, struct RastPort *rp) +{ + ULONG n; + + d1(kprintf("%s/%s/%ld: iobj_text=<%s> %08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_text, inst->iobj_text)); + + ObtainSemaphoreShared(&inst->iobj_TextSemaphore); + + memset(inst->iobj_TextLines, 0, sizeof(inst->iobj_TextLines)); + memset(&inst->iobj_TextExtent, 0, sizeof(inst->iobj_TextExtent)); + + inst->iobj_numchars = strlen(inst->iobj_text); + + d1(kprintf("%s/%s/%ld: iobj_text=<%s> iobj_numchars=%lu\n", \ + __FILE__, __FUNC__, __LINE__, inst->iobj_text, inst->iobj_numchars)); + + for (n = 0; n < Sizeof(inst->iobj_TextLines); n++) + { + struct IconObjectTextLine *iotl; + + iotl = &inst->iobj_TextLines[n]; + + iotl->iotl_TextStart = 0; + iotl->iotl_numchars = 0; + } + + inst->iobj_TextLines[0].iotl_numchars = inst->iobj_numchars; + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + CalculateTextDimensions(inst, gg, rp); + + d1(kprintf("%s/%s/%ld: iobj_text=<%s> %08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_text, inst->iobj_text)); + d1(kprintf("%s/%s/%ld: Extent.w=%ld Extent.h=%ld\n", \ + __FILE__, __FUNC__, __LINE__, inst->iobj_TextExtent.te_Width, inst->iobj_TextExtent.te_Height)); + + if (inst->iobj_MultiLineText) + { + ULONG MaxUsedLineIndex = 0; + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + if (2 * gg->BoundsWidth > 3 * gg->Width) + { + struct IconObjectTextLine *iotl; + BOOL Split = FALSE; + LONG n1, n2; + + iotl = &inst->iobj_TextLines[MaxUsedLineIndex]; + if (iotl->iotl_numchars > 2 * 3) + { + // Start at center of text, and check characters left and right of + // center for suitable division point + // Move check points farther and farther from center, until front or back + // borders (3 characters left) are reached. + for (n1 = n2 = iotl->iotl_numchars / 2; !Split + && (n1 > iotl->iotl_TextStart + 3 || n2 < iotl->iotl_numchars - 3); ) + { + if ( IsSeparator(inst->iobj_text[n1]) ) + { + inst->iobj_TextLines[MaxUsedLineIndex + 1].iotl_numchars = iotl->iotl_numchars - n1 - 1; + iotl->iotl_numchars = n1 + 1; + inst->iobj_TextLines[MaxUsedLineIndex + 1].iotl_TextStart = n1 + 1; + Split = TRUE; + } + else if ( IsSeparator(inst->iobj_text[n2]) ) + { + inst->iobj_TextLines[MaxUsedLineIndex + 1].iotl_numchars = iotl->iotl_numchars - n2 - 1; + iotl->iotl_numchars = n2 + 1; + inst->iobj_TextLines[MaxUsedLineIndex + 1].iotl_TextStart = n2 + 1; + Split = TRUE; + } + + d1(if (Split) kprintf("%s/%s/%ld: SplitChar=%02lx n=%ld\n", \ + __FILE__, __FUNC__, __LINE__, inst->iobj_text[n], n)); + + if (n1 > iotl->iotl_TextStart + 3) + n1--; // move check point 1 left towards start of text + if (n2 < iotl->iotl_numchars - 3) + n2++; // move check point 2 right towards end of text + } + + d1(kprintf("%s/%s/%ld: iobj_text=<%s> %08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_text, inst->iobj_text)); + d1(kprintf("%s/%s/%ld: Split=%ld MaxLine=%ld numchars=%ld TextStart=%ld\n", \ + __FILE__, __FUNC__, __LINE__, Split, \ + MaxUsedLineIndex, inst->iobj_TextLines[MaxUsedLineIndex + 1].iotl_numchars,\ + inst->iobj_TextLines[MaxUsedLineIndex + 1].iotl_TextStart)); + + if (!Split && gg->BoundsWidth > 2 * gg->Width) + { + // No suitable division point found, + // and text more than twice as wide as icon. + // force division at arithmetic center of text (half of length). + n = iotl->iotl_numchars / 2; + + inst->iobj_TextLines[MaxUsedLineIndex + 1].iotl_numchars = iotl->iotl_numchars - n - 1; + iotl->iotl_numchars = n + 1; + inst->iobj_TextLines[MaxUsedLineIndex + 1].iotl_TextStart = n + 1; + Split = TRUE; + } + + if (Split) + CalculateTextDimensions(inst, gg, rp); + } + + d1(kprintf("%s/%s/%ld: Extent.w=%ld Extent.h=%ld\n", \ + __FILE__, __FUNC__, __LINE__, inst->iobj_TextExtent.te_Width, inst->iobj_TextExtent.te_Height)); + } + } + + inst->iobj_GlobalTextLeftOffset = inst->iobj_TextExtent.te_Width - gg->Width; + + d1(kprintf("%s/%s/%ld: Width=%ld BoundsWidth=%ld Left=%ld\n", \ + __FILE__, __FUNC__, __LINE__, gg->Width, gg->BoundsWidth, inst->iobj_GlobalTextLeftOffset)); + + inst->iobj_GlobalTextLeftOffset /= 2; + + if (inst->iobj_SelectedTextRectangle) + inst->iobj_GlobalTextLeftOffset += inst->iobj_TextRectBorderX; + + if (inst->iobj_GlobalTextLeftOffset > 0) + { + // Text is wider than image + gg->BoundsLeftEdge -= inst->iobj_GlobalTextLeftOffset; + } + else + { + // Image is wider than text + struct IconObjectTextLine *iotl; + ULONG n; + + for (n = 0; n < Sizeof(inst->iobj_TextLines); n++) + { + iotl = &inst->iobj_TextLines[n]; + + iotl->iotl_TextLeft += inst->iobj_GlobalTextLeftOffset; + } + } + + d1(kprintf("%s/%s/%ld: iobj_text=<%s> %08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_text, inst->iobj_text)); + + ReleaseSemaphore(&inst->iobj_TextSemaphore); +} + + +static BOOL IsSeparator(char ch) +{ + return (BOOL) ('-' == ch || '_' == ch || '=' == ch || isspace(ch)); +} + +static ULONG MySetSoftStyle(struct InstanceData *inst, struct RastPort *rp, ULONG style, ULONG enable) +{ + if (inst->iobj_FontHook) + { + struct ioFontMsg_SetFontStyle iofsfs; + + iofsfs.MsgID = iofMsg_SETFONTSTYLE; + iofsfs.iofsfs_RastPort = rp; + iofsfs.iofsfs_FontHandle = inst->iobj_Fonthandle; + iofsfs.iofsfs_Style = style; + iofsfs.iofsfs_Enable = enable; + + return (ULONG) CallHookPkt(inst->iobj_FontHook, NULL, &iofsfs); + } + else + { + return SetSoftStyle(rp, style, enable); + } +} + +static void MyText(struct InstanceData *inst, struct RastPort *rp, CONST_STRPTR string, WORD Length) +{ + if (inst->iobj_FontHook) + { + struct ioFontMsg_Text ioft; + + ioft.MsgID = iofMsg_TEXT; + ioft.ioft_RastPort = rp; + ioft.ioft_FontHandle = inst->iobj_Fonthandle; + ioft.ioft_String = string; + ioft.ioft_Length = Length; + + CallHookPkt(inst->iobj_FontHook, NULL, &ioft); + } + else + { + Text(rp, string, Length); + } +} + +static void MyTextExtent(struct InstanceData *inst, struct RastPort *rp, CONST_STRPTR string, WORD Length, struct TextExtent *tExt) +{ + if (inst->iobj_FontHook) + { + struct ioFontMsg_TextExtent iofte; + + iofte.MsgID = iofMsg_TEXTEXTENT; + iofte.iofte_RastPort = rp; + iofte.iofte_FontHandle = inst->iobj_Fonthandle; + iofte.iofte_String = string; + iofte.iofte_Length = Length; + iofte.iofte_TextExtent = tExt; + + CallHookPkt(inst->iobj_FontHook, NULL, &iofte); + } + else + { + TextExtent(rp, string, Length, tExt); + } +} + +static void MySetFont(struct InstanceData *inst, struct RastPort *rp, struct TextFont *tf) +{ + if (inst->iobj_FontHook) + { + struct ioFontMsg_SetFont iofsf; + + iofsf.MsgID = iofMsg_SETFONT; + iofsf.iofsf_RastPort = rp; + iofsf.iofsf_FontHandle = inst->iobj_Fonthandle; + iofsf.iofsf_TextFont = tf; + + CallHookPkt(inst->iobj_FontHook, NULL, &iofsf); + } + else + { + if (tf) + SetFont(rp, tf); + } +} + +static void MySetTransparency(struct InstanceData *inst, struct RastPort *rp, ULONG Transparency) +{ + if (inst->iobj_FontHook) + { + struct ioFontMsg_SetTransparency iofst; + + iofst.MsgID = iofMsg_SETTRANSPARENCY; + iofst.iofst_RastPort = rp; + iofst.iofst_FontHandle = inst->iobj_Fonthandle; + iofst.iofst_Transparency = Transparency; + + CallHookPkt(inst->iobj_FontHook, NULL, &iofst); + } + else + { + // not supported for standard fonts + } +} + +static void MyDoneRastPort(struct InstanceData *inst, struct RastPort *rp) +{ + if (inst->iobj_FontHook) + { + struct ioFontMsg_DoneRastPort iofdr; + + iofdr.MsgID = iofMsg_DONERASTPORT; + iofdr.iofdr_RastPort = rp; + iofdr.iofdr_FontHandle = inst->iobj_Fonthandle; + + CallHookPkt(inst->iobj_FontHook, NULL, &iofdr); + } +} + +static UWORD MyGetFontBaseline(struct InstanceData *inst, struct RastPort *rp) +{ + if (inst->iobj_FontHook) + { + struct ioFontMsg_GetFontBaseline iofgfb; + + iofgfb.MsgID = iofMsg_GETFONTBASELINE; + iofgfb.iofgfb_RastPort = rp; + iofgfb.iofgfb_FontHandle = inst->iobj_Fonthandle; + + return (UWORD) CallHookPkt(inst->iobj_FontHook, NULL, &iofgfb); + } + else + { + return (UWORD) rp->Font->tf_Baseline; + } +} + +//----------------------------------------------------------------------------- + +static void CalculateTextDimensions(struct InstanceData *inst, struct ExtGadget *gg, struct RastPort *rp) +{ + ULONG n; + + gg->BoundsWidth = gg->Width; + gg->BoundsHeight = gg->Height; + + if (inst->iobj_SelectedTextRectangle) + gg->BoundsHeight += 2 * TT_BORDER_Y; + + inst->iobj_TextExtent.te_Width = inst->iobj_TextExtent.te_Height = 0; + + for (n = 0; n < Sizeof(inst->iobj_TextLines); n++) + { + struct IconObjectTextLine *iotl; + + iotl = &inst->iobj_TextLines[n]; + + if (iotl->iotl_numchars) + { + d1(KPrintF("%s/%s/%ld: text=<%s> TextStart=%ld numchars=%ld\n", \ + __FILE__, __FUNC__, __LINE__, inst->iobj_text + iotl->iotl_TextStart, iotl->iotl_TextStart, iotl->iotl_numchars)); + + MyTextExtent(inst, rp, inst->iobj_text + iotl->iotl_TextStart, + iotl->iotl_numchars, &iotl->iotl_TextExtent); + + iotl->iotl_TextWidth = 1 + iotl->iotl_TextExtent.te_Extent.MaxX - iotl->iotl_TextExtent.te_Extent.MinX; + if (iotl->iotl_TextExtent.te_Width > iotl->iotl_TextWidth) + iotl->iotl_TextWidth = iotl->iotl_TextExtent.te_Width; + + iotl->iotl_TextHeight = 1 + iotl->iotl_TextExtent.te_Extent.MaxY - iotl->iotl_TextExtent.te_Extent.MinY; + if (iotl->iotl_TextExtent.te_Height > iotl->iotl_TextHeight) + iotl->iotl_TextHeight = iotl->iotl_TextExtent.te_Height; + + iotl->iotl_TextHeight += 1; + + switch (inst->iobj_textmode) + { + case IDTV_TextMode_Outline: + iotl->iotl_TextWidth += 2; + iotl->iotl_TextHeight += 2; + break; + case IDTV_TextMode_Shadow: + iotl->iotl_TextWidth += 1; + iotl->iotl_TextHeight += 1; + break; + default: + break; + } + + inst->iobj_TextExtent.te_Width = max(inst->iobj_TextExtent.te_Width, 2 + iotl->iotl_TextExtent.te_Width); + inst->iobj_TextExtent.te_Height += iotl->iotl_TextExtent.te_Height; + + d1(KPrintF("%s/%s/%ld: iotl_TextExtent: te_Width=%ld te_Height=%ld MinX=%ld MaxX=%ld\n", \ + __FILE__, __FUNC__, __LINE__, iotl->iotl_TextExtent.te_Width, \ + iotl->iotl_TextExtent.te_Height, + iotl->iotl_TextExtent.te_Extent.MinX, + iotl->iotl_TextExtent.te_Extent.MaxX)); + + if (inst->iobj_SelectedTextRectangle) + gg->BoundsWidth = max(gg->BoundsWidth, (2 * inst->iobj_TextRectBorderX + inst->iobj_TextExtent.te_Width + 1)); + else + gg->BoundsWidth = max(gg->BoundsWidth, inst->iobj_TextExtent.te_Width); + + gg->BoundsHeight += iotl->iotl_TextHeight + inst->iobj_textskip; + } + } + for (n = 0; n < Sizeof(inst->iobj_TextLines); n++) + { + struct IconObjectTextLine *iotl; + + iotl = &inst->iobj_TextLines[n]; + + if (iotl->iotl_numchars) + { + // Center text inside + iotl->iotl_TextLeft = (1 + gg->BoundsWidth - iotl->iotl_TextWidth) / 2; + + d1(kprintf("%s/%s/%ld: w=%ld h=%ld Extent.w=%ld Extent.h=%ld Left=%ld\n", \ + __FILE__, __FUNC__, __LINE__, iotl->iotl_TextWidth, iotl->iotl_TextHeight, iotl->iotl_TextExtent.te_Width, \ + iotl->iotl_TextExtent.te_Height, iotl->iotl_TextLeft)); + } + } +} + +//----------------------------------------------------------------------------- + +static BOOL ToolTypeNameCmp(CONST_STRPTR ToolTypeName, CONST_STRPTR ToolTypeContents) +{ +#if 0 + while (*ToolTypeName && *ToolTypeContents + && '=' != *ToolTypeContents + && ToLower(*ToolTypeName) == ToLower(*ToolTypeContents)) + { + ToolTypeName++; + ToolTypeContents++; + } +#else + while (*ToolTypeName && *ToolTypeContents) + { + UBYTE ch1; // Work-around for GCC compiler bug + + if ('=' == *ToolTypeContents) + break; + ch1 = ToLower(*ToolTypeName); + if (ch1 != ToLower(*ToolTypeContents)) + break; + + ToolTypeName++; + ToolTypeContents++; + } +#endif + + return (BOOL) ('\0' == *ToolTypeName && ('\0' == *ToolTypeContents || '=' == *ToolTypeContents)); +} + +//----------------------------------------------------------------------------- + +static void SetTags(Class *cl, Object *o, struct opSet *ops) +{ + struct InstanceData *inst = INST_DATA(cl, o); + struct ExtGadget *gg = (struct ExtGadget *) o; + struct TagItem *dTag; + BOOL SizeSet = FALSE; + BOOL NeedFreeLayout = FALSE; + + DoOmSet(cl, o, ops); + + SetAllocTagProtected(IDTA_Text, &inst->iobj_text, ops->ops_AttrList, &inst->iobj_TextSemaphore); + SetAllocTag(IDTA_DefaultTool, &inst->iobj_defaulttool, ops->ops_AttrList); + SetAllocTag(IDTA_ToolWindow, &inst->iobj_ToolWindow, ops->ops_AttrList); + + dTag = FindTagItem(IDTA_ARGBImageData, ops->ops_AttrList); + if (dTag) + { + d1(KPrintF("%s/%s/%ld: o=%08lx IDTA_ARGBImageData=%08lx\n", __FILE__, __FUNC__, __LINE__, o, dTag->ti_Data)); + NeedFreeLayout = TRUE; + ReplaceARGBImage(&inst->iobj_NormalARGB, (struct ARGBHeader *) dTag->ti_Data); + } + + dTag = FindTagItem(IDTA_SelARGBImageData, ops->ops_AttrList); + if (dTag) + { + d1(KPrintF("%s/%s/%ld: o=%08lx IDTA_SelARGBImageData=%08lx\n", __FILE__, __FUNC__, __LINE__, o, dTag->ti_Data)); + NeedFreeLayout = TRUE; + ReplaceARGBImage(&inst->iobj_SelectedARGB, (struct ARGBHeader *) dTag->ti_Data); + } + + dTag = FindTagItem(GA_Width, ops->ops_AttrList); + if (dTag) + { + d1(KPrintF("%s/%s/%ld: o=%08lx GA_Width=%ld\n", __FILE__, __FUNC__, __LINE__, o, dTag->ti_Data)); + SizeSet = TRUE; + NeedFreeLayout = TRUE; + gg->Width = inst->iobj_NakedMaskWidth + = inst->iobj_NakedWidth + = inst->iobj_ScaledWidth + = dTag->ti_Data; + + if (!(inst->iobj_layoutflags & (IOBLAYOUTF_ScaleNormal | IOBLAYOUTF_ScaleSelected))) + { + inst->iobj_UnscaledWidth = inst->iobj_UnscaledNakedWidth = dTag->ti_Data; + } + + d1(KPrintF("%s/%s/%ld: o=%08lx Width=%lu\n", __FILE__, __FUNC__, __LINE__, o, gg->Width)); + } + dTag = FindTagItem(GA_Height, ops->ops_AttrList); + if (dTag) + { + SizeSet = TRUE; + NeedFreeLayout = TRUE; + gg->Height = inst->iobj_NakedMaskHeight + = inst->iobj_NakedHeight + = inst->iobj_ScaledHeight + = dTag->ti_Data; + + if (!(inst->iobj_layoutflags & (IOBLAYOUTF_ScaleNormal | IOBLAYOUTF_ScaleSelected))) + { + inst->iobj_UnscaledHeight = inst->iobj_UnscaledNakedHeight = dTag->ti_Data; + } + + d1(KPrintF("%s/%s/%ld: o=%08lx Height=%lu\n", __FILE__, __FUNC__, __LINE__, o, gg->Height)); + } + + dTag = FindTagItem(IDTA_UnscaledWidth, ops->ops_AttrList); + if (dTag) + { + inst->iobj_UnscaledWidth = inst->iobj_UnscaledNakedWidth = dTag->ti_Data; + NeedFreeLayout = TRUE; + } + + dTag = FindTagItem(IDTA_UnscaledHeight, ops->ops_AttrList); + if (dTag) + { + inst->iobj_UnscaledHeight = inst->iobj_UnscaledNakedHeight = dTag->ti_Data; + NeedFreeLayout = TRUE; + } + + dTag = FindTagItem(IDTA_ToolTypes, ops->ops_AttrList); + if (dTag) + SetToolTypes(inst, (const STRPTR *) dTag->ti_Data); + + SetAllocTag(DTA_Name, &inst->iobj_name, ops->ops_AttrList); + + dTag = FindTagItem(IDTA_ScalePercentage, ops->ops_AttrList); + if (dTag) + { + inst->iobj_ScalingPercentage = dTag->ti_Data; + + if (inst->iobj_ScalingPercentage < IDTA_ScalePercentage_MIN) + inst->iobj_ScalingPercentage = IDTA_ScalePercentage_MIN; + else if (inst->iobj_ScalingPercentage > IDTA_ScalePercentage_MAX) + inst->iobj_ScalingPercentage = IDTA_ScalePercentage_MAX; + + d1(KPrintF("%s/%s/%ld: IDTA_ScalePercentage: %ld\n", \ + __FILE__, __FUNC__, __LINE__, inst->iobj_ScalingPercentage)); + } + + dTag = FindTagItem(IDTA_SizeConstraints, ops->ops_AttrList); + if (dTag) + { + struct Rectangle *NewConstraints = (struct Rectangle *) dTag->ti_Data; + + inst->iobj_SizeConstraints = *NewConstraints; + d1(KPrintF("%s/%s/%ld: iobj_SizeConstraint: MinX=%ld MinY=%ld MaxX=%ld MaxY=%ld\n", \ + __FILE__, __FUNC__, __LINE__, inst->iobj_SizeConstraints.MinX, \ + inst->iobj_SizeConstraints.MinY, inst->iobj_SizeConstraints.MaxX, \ + inst->iobj_SizeConstraints.MaxY)); + } + + dTag = FindTagItem(IDTA_Mask_Normal, ops->ops_AttrList); + if (dTag) + { + // dispose old normal mask + MyFreeVecPooled(ChipMemPool, (APTR *) &inst->iobj_NormalMask.iom_Mask); + if (inst->iobj_NormalMask.iom_MaskBM) + { + d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_NormalMask.iom_MaskBM)); + FreeBitMap(inst->iobj_NormalMask.iom_MaskBM); + inst->iobj_NormalMask.iom_MaskBM = NULL; + } + + d1(KPrintF("%s/%s/%ld: IDTA_Mask_Normal=%08lx iom_Width=%ld iom_Height=%ld\n", \ + __FILE__, __FUNC__, __LINE__, dTag->ti_Data, inst->iobj_NormalMask.iom_Width,\ + inst->iobj_NormalMask.iom_Height)); + + if (dTag->ti_Data) + { + // create new normal mask + size_t Size; + + Size = inst->iobj_NormalMask.iom_Height * BYTESPERROW(inst->iobj_NormalMask.iom_Width); + Size = ALIGN_LONG(Size); + + inst->iobj_NormalMask.iom_Mask = MyAllocVecPooled(ChipMemPool, Size); + + if (inst->iobj_NormalMask.iom_Mask) + CopyMemQuick((UBYTE *) dTag->ti_Data, inst->iobj_NormalMask.iom_Mask, Size); + + d1(DumpMask(&inst->iobj_NormalMask)); + } + } + + dTag = FindTagItem(IDTA_Mask_Selected, ops->ops_AttrList); + if (dTag) + { + // dispose old selected mask + MyFreeVecPooled(ChipMemPool, (APTR *) &inst->iobj_SelectedMask.iom_Mask); + if (inst->iobj_SelectedMask.iom_MaskBM) + { + d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_SelectedMask.iom_MaskBM)); + FreeBitMap(inst->iobj_SelectedMask.iom_MaskBM); + inst->iobj_SelectedMask.iom_MaskBM = NULL; + } + + d1(KPrintF("%s/%s/%ld: IDTA_Mask_Selected=%08lx iom_Width=%ld iom_Height=%ld\n", \ + __FILE__, __FUNC__, __LINE__, dTag->ti_Data, inst->iobj_NormalMask.iom_Width, \ + inst->iobj_NormalMask.iom_Height)); + d1(KPrintF("%s/%s/%ld: iobj_selmaskbm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_SelectedMask.iom_MaskBM)); + + if (dTag->ti_Data) + { + // create new selected mask + size_t Size; + + Size = inst->iobj_SelectedMask.iom_Height * BYTESPERROW(inst->iobj_SelectedMask.iom_Width); + Size = ALIGN_LONG(Size); + + inst->iobj_SelectedMask.iom_Mask = MyAllocVecPooled(ChipMemPool, Size); + + if (inst->iobj_SelectedMask.iom_Mask) + CopyMemQuick((UBYTE *) dTag->ti_Data, inst->iobj_SelectedMask.iom_Mask, Size); + } + } + + dTag = FindTagItem(IDTA_WindowRect, ops->ops_AttrList); + if (dTag && dTag->ti_Data) + { + struct IBox *WinRect = (struct IBox *) dTag->ti_Data; + + d1(kprintf("%s/%s/%ld: IDTA_WindowRect=%08lx <%s> Left=%ld Top=%ld Width=%ld Height=%ld\n", __FILE__, __FUNC__, __LINE__, \ + WinRect, inst->iobj_text, WinRect->Left, WinRect->Top, WinRect->Width, WinRect->Height)); + + inst->iobj_winrect = *WinRect; + } + + if (SizeSet) + CheckIfScalingRequired(cl, o); + + if (NeedFreeLayout) + { + d1(KPrintF("%s/%s/%ld: FreeLayout enforced\n", __FILE__, __FUNC__, __LINE__)); + DoMethod(o, IDTM_FreeLayout, IOFREELAYOUTF_ScreenAvailable); + } +} + +//----------------------------------------------------------------------------- + +static void SetAllocTag(ULONG TagValue, STRPTR *DataPtr, struct TagItem *TagList) +{ + struct TagItem *dTag; + + dTag = FindTagItem(TagValue, TagList); + if (dTag) + { + STRPTR OldData = *DataPtr; + + *DataPtr = AllocCopyString((CONST_STRPTR) dTag->ti_Data); + MyFreeVecPooled(PubMemPool, (APTR) &OldData); + } +} + +//----------------------------------------------------------------------------- + +static void SetAllocTagProtected(ULONG TagValue, STRPTR *DataPtr, + struct TagItem *TagList, struct SignalSemaphore *Sema) +{ + struct TagItem *dTag; + + dTag = FindTagItem(TagValue, TagList); + if (dTag) + { + STRPTR OldData = *DataPtr; + + ObtainSemaphore(Sema); + + *DataPtr = AllocCopyString((CONST_STRPTR) dTag->ti_Data); + MyFreeVecPooled(PubMemPool, (APTR) &OldData); + + ReleaseSemaphore(Sema); + } +} + +//----------------------------------------------------------------------------- + +static STRPTR AllocCopyString(CONST_STRPTR OrigString) +{ + STRPTR NewString; + + if (OrigString) + { + NewString = MyAllocVecPooled(PubMemPool, 1 + strlen(OrigString)); + if (NewString) + { + strcpy(NewString, OrigString); + } + } + else + { + NewString = NULL; + } + + return NewString; +} + +//----------------------------------------------------------------------------- + +static void SetToolTypes(struct InstanceData *inst, const STRPTR *NewToolTypes) +{ + // same ToolType array as before? + if (NewToolTypes != (const STRPTR *) inst->iobj_tooltypes) + { + STRPTR *OldToolTypes = inst->iobj_tooltypes; + + inst->iobj_tooltypes = CloneToolTypes(NewToolTypes); + + if (OldToolTypes) + MyFreeVecPooled(PubMemPool, (APTR) &OldToolTypes); + } +} + +//----------------------------------------------------------------------------- + +static STRPTR *CloneToolTypes(const STRPTR *OrigToolTypes) +{ + const STRPTR *TTPtr; + STRPTR *TTClone; + size_t AllocLen = sizeof(STRPTR); + size_t StringCount = 1; + + d1(kprintf("%s/%s/%ld: OrigToolTypes=%08lx\n", __FILE__, __FUNC__, __LINE__, OrigToolTypes)); + + for (TTPtr = OrigToolTypes; *TTPtr; TTPtr++) + { + d1(kprintf("%s/%s/%ld: *TTPtr=<%s>\n", __FILE__, __FUNC__, __LINE__, *TTPtr)); + StringCount++; + AllocLen += sizeof(STRPTR) + 1 + strlen(*TTPtr); + } + + d1(kprintf("%s/%s/%ld: StringCount=%lu AllocLen=%lu\n", __FILE__, __FUNC__, __LINE__, StringCount, AllocLen)); + + TTClone = MyAllocVecPooled(PubMemPool, AllocLen); + if (TTClone) + { + STRPTR *TTDestPtr; + STRPTR StringSpace; + + StringSpace = ((STRPTR) TTClone) + StringCount * sizeof(STRPTR); + TTPtr = OrigToolTypes; + TTDestPtr = TTClone; + + while (TTPtr && *TTPtr) + { + *TTDestPtr = StringSpace; + strcpy(*TTDestPtr, *TTPtr); + + StringSpace += 1 + strlen(*TTPtr); + TTDestPtr++; + TTPtr++; + } + *TTDestPtr = NULL; + } + + d1(kprintf("%s/%s/%ld: TTClone=%08lx\n", __FILE__, __FUNC__, __LINE__, TTClone)); + + return TTClone; +} + +//----------------------------------------------------------------------------- + +static void DrawFrame(Class *cl, Object *o, struct RastPort *rp, + ULONG Width, ULONG Height, UWORD FrameType) +{ + struct InstanceData *inst = INST_DATA(cl, o); + + if (!inst->iobj_Borderless + && 0 != inst->iobj_imgleft + && 0 != inst->iobj_imgtop + && FRAMETYPE_NONE != FrameType) + { + struct RastPort rpCopy; + struct InstanceData *inst = INST_DATA(cl, o); + + rpCopy = *rp; + + McpGfxDrawFrame(&rpCopy, 0, 0, + Width - 1, Height - 1, + IA_HalfShinePen, inst->iobj_HalfShinePen, + IA_HalfShadowPen, inst->iobj_HalfShadowPen, + IA_Recessed, (FrameType & 0x8000) ? TRUE : FALSE, + IA_FrameType, FrameType & 0x7fff, + TAG_END); + } +} + +//----------------------------------------------------------------------------- + +static void DrawMaskFrame(struct InstanceData *inst, struct BitMap *DestBitMap, + ULONG Width, ULONG Height, UWORD FrameType) +{ + if (!inst->iobj_Borderless + && FRAMETYPE_NONE != FrameType + && 0 != inst->iobj_imgleft + && 0 != inst->iobj_imgtop) + { + struct RastPort TempRp; + + InitRastPort(&TempRp); + TempRp.BitMap = DestBitMap; + + McpGfxDrawFrame(&TempRp, + 0, 0, Width - 1, Height - 1, + IA_ShinePen, 1, + IA_ShadowPen, 1, + IA_HalfShinePen, 1, + IA_HalfShadowPen, 1, + IA_Recessed, (FrameType & 0x8000) ? TRUE : FALSE, + IA_FrameType, FrameType & 0x7fff, + TAG_END); + } +} + +//----------------------------------------------------------------------------- + +static struct RastPort *InitRast(Class *cl, Object *o, struct iopLayout *iopl, struct RastPort *rp) +{ + struct InstanceData *inst = INST_DATA(cl, o); + ULONG BmDepth; + + memset(rp, 0, sizeof(struct RastPort)); + InitRastPort(rp); + + BmDepth = GetBitMapAttr(iopl->iopl_Screen->RastPort.BitMap, BMA_DEPTH); + + rp->BitMap = AllocBitMap(1 + inst->iobj_UnscaledWidth, 1 + inst->iobj_UnscaledHeight, + BmDepth, + BMF_MINPLANES | BMF_INTERLEAVED, + iopl->iopl_Screen->RastPort.BitMap); + + return rp; +} + +//----------------------------------------------------------------------------- + +static struct BitMap *GenMask(Class *cl, Object *o, + ULONG BmWidth, ULONG BmHeight, ULONG BmDepth, ULONG BmFlags, + UBYTE *MaskPlane, + UWORD FrameType, ULONG MaskWidth, ULONG MaskHeight) +{ + struct InstanceData *inst = INST_DATA(cl, o); + struct BitMap *DestBitMap; + LONG ImgMaskWidth, ImgMaskHeight; + + ImgMaskWidth = inst->iobj_NakedMaskWidth + + inst->iobj_imgleft + inst->iobj_imgright; + ImgMaskHeight = inst->iobj_NakedMaskHeight + + inst->iobj_imgtop + inst->iobj_imgbottom; + + // after ARGB scaling, SrcBitMap might be smaller than actual image + if (BmWidth < ImgMaskWidth) + BmWidth = (ImgMaskWidth + 15) & 0xfff0; + if (BmHeight < ImgMaskHeight) + BmHeight = ImgMaskHeight; + +#if !defined(__AROS__) + // XXX: is this really AROS specific? + // maybe it's better to remove BMF_INTERLEAVED at all + if (BmFlags & BMF_INTERLEAVED) + { + BmWidth *= BmDepth; + } +#endif + + d1(KPrintF("%s/%s/%ld: o=%08lx <%s> BmWidth=%lu BmHeight=%lu\n", __FILE__, __FUNC__, __LINE__, o, inst->iobj_name, BmWidth, BmHeight)); + d1(KPrintF("%s/%s/%ld: MaskPlane=%08lx\n", __FILE__, __FUNC__, __LINE__, MaskPlane)); + d1(KPrintF("%s/%s/%ld: MaskWidth=%lu MaskHeight=%lu\n", __FILE__, __FUNC__, __LINE__, MaskWidth, MaskHeight)); + d1(KPrintF("%s/%s/%ld: ImgMaskWidth=%lu ImgMaskHeight=%lu\n", __FILE__, __FUNC__, __LINE__, ImgMaskWidth, ImgMaskHeight)); + d1(KPrintF("%s/%s/%ld: iobj_imgleft=%ld iobj_imgright=%ld\n", \ + __FILE__, __FUNC__, __LINE__, inst->iobj_imgleft, inst->iobj_imgright)); + d1(KPrintF("%s/%s/%ld: iobj_imgtop=%ld iobj_imgbottom=%ld\n", \ + __FILE__, __FUNC__, __LINE__, inst->iobj_imgtop, inst->iobj_imgbottom)); + d1(KPrintF("%s/%s/%ld: iobj_NakedMaskWidth=%ld iobj_NakedMaskHeight=%ld\n", \ + __FILE__, __FUNC__, __LINE__, inst->iobj_NakedMaskWidth, inst->iobj_NakedMaskHeight)); + + DestBitMap = AllocBitMap(BmWidth, BmHeight, 1, BMF_CLEAR, NULL); + d1(KPrintF("%s/%s/%ld: DestBitMap=%08lx\n", __FILE__, __FUNC__, __LINE__, DestBitMap)); + if (DestBitMap) + { + ASSERT_d1(BmWidth >= MaskWidth); + ASSERT_d1(BmHeight >= MaskHeight); + + if (MaskPlane && (BmWidth >= MaskWidth) && (BmHeight >= MaskHeight)) + { + struct BitMap TempBM; + + d1(KPrintF("%s/%s/%ld: MaskWidth=%lu MaskHeight=%lu BytesPerRow=%ld\n", __FILE__, __FUNC__, __LINE__, MaskWidth, MaskHeight, BYTESPERROW(MaskWidth))); + d1(KPrintF("%s/%s/%ld: ImgMaskWidth=%lu ImgMaskHeight=%lu\n", __FILE__, __FUNC__, __LINE__, ImgMaskWidth, ImgMaskHeight)); + d1(KPrintF("%s/%s/%ld: BmWidth=%lu BmHeight=%lu\n", __FILE__, __FUNC__, __LINE__, BmWidth, BmHeight)); + + memset(&TempBM, 0, sizeof(TempBM)); + TempBM.BytesPerRow = BYTESPERROW(MaskWidth); + TempBM.Rows = MaskHeight; + TempBM.Flags = 0; + TempBM.Depth = 1; + TempBM.Planes[0] = MaskPlane; + +#if 0 + { + struct RastPort rp; + + InitRastPort(&rp); + rp.BitMap = &TempBM; + SetAPen(&rp, 1); + RectFill(&rp, + 0, 0, + MaskWidth - 1, + MaskHeight - 1); + } +#endif + + d1(KPrintF("%s/%s/%ld: BytesPerRow=%lu\n", __FILE__, __FUNC__, __LINE__, TempBM.BytesPerRow)); + + ASSERT_d1(MaskWidth <= GetBitMapAttr(DestBitMap, BMA_WIDTH)); + ASSERT_d1(MaskHeight <= GetBitMapAttr(DestBitMap, BMA_HEIGHT)); + + BltBitMap(&TempBM, 0, 0, + DestBitMap, + inst->iobj_imgleft, inst->iobj_imgtop, + MaskWidth, + MaskHeight, + ABC | ABNC, ~0, NULL); + } + else + { + struct ExtGadget *gg = (struct ExtGadget *) o; + struct RastPort rp; + WORD Right, Bottom; + + InitRastPort(&rp); + rp.BitMap = DestBitMap; + + Right = min(gg->Width - inst->iobj_imgright - 1, BmWidth - 1); + Bottom = min(gg->Height - inst->iobj_imgbottom - 1, BmHeight - 1); + + ASSERT_d1(Right < GetBitMapAttr(rp.BitMap, BMA_WIDTH)); + ASSERT_d1(Bottom < GetBitMapAttr(rp.BitMap, BMA_HEIGHT)); + + SetAPen(&rp, 1); + RectFill(&rp, + inst->iobj_imgleft, inst->iobj_imgtop, + Right, + Bottom); + } + WaitBlit(); + + ASSERT_d1(ImgMaskWidth <= GetBitMapAttr(DestBitMap, BMA_WIDTH)); + ASSERT_d1(ImgMaskHeight <= GetBitMapAttr(DestBitMap, BMA_HEIGHT)); + + DrawMaskFrame(inst, DestBitMap, + ImgMaskWidth, + ImgMaskHeight, + FrameType); + } + + d1(KPrintF("%s/%s/%ld: END DestBitMap=%08lx\n", __FILE__, __FUNC__, __LINE__, DestBitMap)); + + return DestBitMap; +} + +//----------------------------------------------------------------------------- + +static struct BitMap *GenInvMask(Class *cl, Object *o, struct BitMap *SrcBitMap) +{ +// struct InstanceData *inst = INST_DATA(cl, o); + struct BitMap *DestBitMap; + ULONG BmWidth, BmHeight; + ULONG BmFlags; + ULONG BmDepth; + + BmFlags = GetBitMapAttr(SrcBitMap, BMA_FLAGS); + BmWidth = GetBitMapAttr(SrcBitMap, BMA_WIDTH); + BmHeight = GetBitMapAttr(SrcBitMap, BMA_HEIGHT); + BmDepth = GetBitMapAttr(SrcBitMap, BMA_DEPTH); + + DestBitMap = AllocBitMap(BmWidth, BmHeight, BmDepth, BmFlags | BMF_CLEAR, NULL); + d1(KPrintF("%s/%s/%ld: DestBitMap=%08lx\n", __FILE__, __FUNC__, __LINE__, DestBitMap)); + if (DestBitMap) + { + // Blit inverted copy of SrcBitMap to DestBitMap + ASSERT_d1(BmWidth <= GetBitMapAttr(DestBitMap, BMA_WIDTH)); + ASSERT_d1(BmHeight <= GetBitMapAttr(DestBitMap, BMA_HEIGHT)); + + BltBitMap(SrcBitMap, + 0, 0, + DestBitMap, + 0, 0, + BmWidth, BmHeight, + ANBC | ANBNC, + ~0, + NULL); + } + + d1(KPrintF("%s/%s/%ld: END DestBitMap=%08lx\n", __FILE__, __FUNC__, __LINE__, DestBitMap)); + + return DestBitMap; +} + +//----------------------------------------------------------------------------- + +static BOOL ScaleRenderBitMapsNormal(Class *cl, Object *o, + ULONG NewWidth, ULONG NewHeight, struct Screen *screen) +{ + struct InstanceData *inst = INST_DATA(cl, o); + struct ExtGadget *gg = (struct ExtGadget *) o; + struct RastPort *rpNormal = (struct RastPort *) gg->GadgetRender; + struct BitMap *NormBM = NULL; + struct BitMap *NormMaskBM = NULL; + ULONG *ColorTable; + BOOL Success = FALSE; + + d1(KPrintF("%s/%s/%ld: START cl=%08lx o=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, cl, o, inst->iobj_name)); + d1(KPrintF("%s/%s/%ld: layoutflags=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_layoutflags)); + + do { + ULONG ScaleFlags = SCALEFLAGF_DOUBLESIZE | SCALEFLAGF_BILINEAR + | SCALEFLAGF_AVERAGE; + + d1(KPrintF("%s/%s/%ld: iobj_UnscaledWidth=%lu iobj_UnscaledHeight=%ld\n", __FILE__, __FUNC__, __LINE__, inst->iobj_UnscaledWidth, inst->iobj_UnscaledHeight)); + d1(KPrintF("%s/%s/%ld: iobj_UnscaledNakedWidth=%lu iobj_UnscaledNakedHeight=%ld\n", __FILE__, __FUNC__, __LINE__, inst->iobj_UnscaledNakedWidth, inst->iobj_UnscaledNakedHeight)); + d1(KPrintF("%s/%s/%ld: NewWidth=%lu NewHeight=%ld\n", __FILE__, __FUNC__, __LINE__, NewWidth, NewHeight)); + d1(KPrintF("%s/%s/%ld: layoutflags=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_layoutflags)); + + ColorTable = MyAllocVecPooled(PubMemPool, + screen->ViewPort.ColorMap->Count * sizeof(ULONG) * 3); + if (NULL == ColorTable) + break; + + GetRGB32(screen->ViewPort.ColorMap, + 0, screen->ViewPort.ColorMap->Count, ColorTable); + + if (rpNormal && (inst->iobj_layoutflags & IOBLAYOUTF_ScaleNormal)) + { + struct ScaleBitMapArg sbma; + + sbma.sbma_SourceBM = rpNormal->BitMap; + sbma.sbma_SourceWidth = inst->iobj_UnscaledWidth; + sbma.sbma_SourceHeight = inst->iobj_UnscaledHeight; + sbma.sbma_DestWidth = &NewWidth; + sbma.sbma_DestHeight = &NewHeight; + sbma.sbma_NumberOfColors = screen->ViewPort.ColorMap->Count; + sbma.sbma_ColorTable = ColorTable; + sbma.sbma_Flags = ScaleFlags; + sbma.sbma_ScreenBM = screen->RastPort.BitMap; + + NormBM = ScalosGfxScaleBitMap(&sbma, NULL); + d1(KPrintF("%s/%s/%ld: NormBM=%08lx\n", __FILE__, __FUNC__, __LINE__, NormBM)); + if (NULL == NormBM) + break; + + inst->iobj_layoutflags &= ~IOBLAYOUTF_ScaleNormal; + + d1(KPrintF("%s/%s/%ld: iom_MaskBM=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_NormalMask.iom_MaskBM)); + if (inst->iobj_NormalMask.iom_MaskBM) + { + d1(DumpMaskBM(&inst->iobj_NormalMask)); + + NormMaskBM = ScaleMaskBitMap(inst->iobj_NormalMask.iom_MaskBM, + inst->iobj_NormalMask.iom_Width, + inst->iobj_NormalMask.iom_Height, + &NewWidth, &NewHeight, + ScaleFlags, + screen->RastPort.BitMap); + d1(KPrintF("%s/%s/%ld: NormMaskBM=%08lx NewWidth=%ld NewHeight=%ld\n", \ + __FILE__, __FUNC__, __LINE__, NormMaskBM, NewWidth, NewHeight)); + if (NULL == NormMaskBM) + break; + + DrawMaskFrame(inst, NormMaskBM, + NewWidth, NewHeight, + inst->iobj_frametype); + } + + // Replace GadgetRender BitMap by scaled one + d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, rpNormal->BitMap)); + FreeBitMap(rpNormal->BitMap); + rpNormal->BitMap = NormBM; + NormBM = NULL; + + // optionally replace normal mask BitMap by scaled one + if (NormMaskBM) + { + d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_NormalMask.iom_MaskBM)); + if (inst->iobj_NormalMask.iom_MaskBM) + FreeBitMap(inst->iobj_NormalMask.iom_MaskBM); + inst->iobj_NormalMask.iom_MaskBM = NormMaskBM; + + NormMaskBM = NULL; + + d1(DumpMaskBM(&inst->iobj_NormalMask)); + } + + DrawFrame(cl, o, rpNormal, + NewWidth, + NewHeight, + inst->iobj_frametype); + } + + Success = TRUE; + } while (0); + + d1(KPrintF("%s/%s/%ld: NormMaskWidth=%lu NormMaskHeight=%lu\n", __FILE__, __FUNC__, __LINE__, inst->iobj_NormalMask.iom_Width, inst->iobj_NormalMask.iom_Height)); + d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, NormBM)); + if (NormBM) + FreeBitMap(NormBM); + d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, NormMaskBM)); + if (NormMaskBM) + FreeBitMap(NormMaskBM); + if (ColorTable) + MyFreeVecPooled(PubMemPool, (APTR) &ColorTable); + + d1(KPrintF("%s/%s/%ld: END cl=%08lx o=%08lx Success=%ld layoutflags=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, Success, inst->iobj_layoutflags)); + + return Success; +} + +//----------------------------------------------------------------------------- + +static BOOL ScaleRenderBitMapsSelected(Class *cl, Object *o, + ULONG NewWidth, ULONG NewHeight, struct Screen *screen) +{ + struct InstanceData *inst = INST_DATA(cl, o); + struct ExtGadget *gg = (struct ExtGadget *) o; + struct RastPort *rpSelect = (struct RastPort *) gg->SelectRender; + struct BitMap *SelBM = NULL; + struct BitMap *SelMaskBM = NULL; + ULONG *ColorTable; + BOOL Success = FALSE; + + d1(KPrintF("%s/%s/%ld: START cl=%08lx o=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o)); + d1(KPrintF("%s/%s/%ld: layoutflags=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_layoutflags)); + + do { + ULONG ScaleFlags = SCALEFLAGF_DOUBLESIZE | SCALEFLAGF_BILINEAR + | SCALEFLAGF_AVERAGE; + + d1(KPrintF("%s/%s/%ld: NewWidth=%lu NewHeight=%ld\n", __FILE__, __FUNC__, __LINE__, NewWidth, NewHeight)); + d1(KPrintF("%s/%s/%ld: layoutflags=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_layoutflags)); + d1(KPrintF("%s/%s/%ld: SelBM: Width=%lu Height=%ld\n", \ + __FILE__, __FUNC__, __LINE__, GetBitMapAttr(rpSelect->BitMap, BMA_WIDTH), \ + GetBitMapAttr(rpSelect->BitMap, BMA_HEIGHT))); + + ColorTable = MyAllocVecPooled(PubMemPool, + screen->ViewPort.ColorMap->Count * sizeof(ULONG) * 3); + if (NULL == ColorTable) + break; + + GetRGB32(screen->ViewPort.ColorMap, + 0, screen->ViewPort.ColorMap->Count, ColorTable); + + if (rpSelect && (inst->iobj_layoutflags & IOBLAYOUTF_ScaleSelected)) + { + struct ScaleBitMapArg sbma; + + sbma.sbma_SourceBM = rpSelect->BitMap; + sbma.sbma_SourceWidth = inst->iobj_UnscaledWidth; + sbma.sbma_SourceHeight = inst->iobj_UnscaledHeight; + sbma.sbma_DestWidth = &NewWidth; + sbma.sbma_DestHeight = &NewHeight; + sbma.sbma_NumberOfColors = screen->ViewPort.ColorMap->Count; + sbma.sbma_ColorTable = ColorTable; + sbma.sbma_Flags = ScaleFlags; + sbma.sbma_ScreenBM = screen->RastPort.BitMap; + + SelBM = ScalosGfxScaleBitMap(&sbma, NULL); + d1(KPrintF("%s/%s/%ld: SelBM=%08lx\n", __FILE__, __FUNC__, __LINE__, SelBM)); + if (NULL == SelBM) + break; + + inst->iobj_layoutflags &= ~IOBLAYOUTF_ScaleSelected; + + d1(KPrintF("%s/%s/%ld: iobj_selmaskbm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_SelectedMask.iom_MaskBM)); + if (inst->iobj_SelectedMask.iom_MaskBM) + { + SelMaskBM = ScaleMaskBitMap(inst->iobj_SelectedMask.iom_MaskBM, + inst->iobj_SelectedMask.iom_Width, + inst->iobj_SelectedMask.iom_Height, + &NewWidth, &NewHeight, + ScaleFlags, + screen->RastPort.BitMap); + d1(KPrintF("%s/%s/%ld: SelMaskBM=%08lx\n", __FILE__, __FUNC__, __LINE__, SelMaskBM)); + if (NULL == SelMaskBM) + break; + + DrawMaskFrame(inst, SelMaskBM, + NewWidth, NewHeight, + inst->iobj_frametypesel); + } + + // Replace SelectRender BitMap by scaled one + d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, rpSelect->BitMap)); + FreeBitMap(rpSelect->BitMap); + rpSelect->BitMap = SelBM; + SelBM = NULL; + + // optionally replace selected mask BitMap by scaled one + if (SelMaskBM) + { + d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_SelectedMask.iom_MaskBM)); + if (inst->iobj_SelectedMask.iom_MaskBM) + FreeBitMap(inst->iobj_SelectedMask.iom_MaskBM); + + inst->iobj_SelectedMask.iom_MaskBM = SelMaskBM; + + SelMaskBM = NULL; + } + + DrawFrame(cl, o, rpSelect, + NewWidth, + NewHeight, + inst->iobj_frametypesel); + } + Success = TRUE; + } while (0); + + d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, SelBM)); + d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, SelMaskBM)); + d1(KPrintF("%s/%s/%ld: iobj_selmaskbm=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_SelectedMask.iom_MaskBM)); + + if (SelBM) + FreeBitMap(SelBM); + if (SelMaskBM) + FreeBitMap(SelMaskBM); + if (ColorTable) + MyFreeVecPooled(PubMemPool, (APTR) &ColorTable); + + d1(KPrintF("%s/%s/%ld: END cl=%08lx o=%08lx Success=%ld layoutflags=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, Success, inst->iobj_layoutflags)); + + return Success; +} + +//----------------------------------------------------------------------------- + +static void LayoutIconSize(Class *cl, Object *o, struct RastPort *rp) +{ + struct InstanceData *inst = INST_DATA(cl, o); + + d1(KPrintF("%s/%s/%ld: START cl=%08lx o=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o)); + d1(KPrintF("%s/%s/%ld: layoutflags=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->iobj_layoutflags)); + TIMESTAMP_d1(); + + if (!(inst->iobj_layoutflags & IOBLAYOUTF_Size)) + { + struct ExtGadget *gg = (struct ExtGadget *) o; + + inst->iobj_layoutflags |= IOBLAYOUTF_Size; + + d1(KPrintF("%s/%s/%ld: NakedWidth=%lu NakedHeight=%lu\n", __FILE__, __FUNC__, __LINE__, inst->iobj_NakedWidth, inst->iobj_NakedHeight)); + d1(KPrintF("%s/%s/%ld: UnscalednakedWidth=%lu UnscalednakedHeight=%lu\n", __FILE__, __FUNC__, __LINE__, inst->iobj_UnscaledNakedWidth, inst->iobj_UnscaledNakedHeight)); + TIMESTAMP_d1(); + + // adjust icon dimensions (add border) + gg->Width = inst->iobj_NakedWidth + + inst->iobj_imgleft + inst->iobj_imgright; + gg->Height = inst->iobj_NakedHeight + + inst->iobj_imgtop + inst->iobj_imgbottom; + + d1(KPrintF("%s/%s/%ld: Width=%ld Height=%ld\n", __FILE__, __FUNC__, __LINE__, gg->Width, gg->Height)); + + inst->iobj_UnscaledWidth = inst->iobj_UnscaledNakedWidth + + inst->iobj_imgleft + inst->iobj_imgright; + inst->iobj_UnscaledHeight = inst->iobj_UnscaledNakedHeight + + inst->iobj_imgtop + inst->iobj_imgbottom; + + d1(KPrintF("%s/%s/%ld: UnscaledWidth=%lu UnscaledHeight=%lu\n", __FILE__, __FUNC__, __LINE__, inst->iobj_UnscaledWidth, inst->iobj_UnscaledHeight)); + + inst->iobj_ScaledWidth = inst->iobj_NakedWidth + + inst->iobj_imgleft + inst->iobj_imgright; + inst->iobj_ScaledHeight = inst->iobj_NakedHeight + + inst->iobj_imgtop + inst->iobj_imgbottom; + + d1(KPrintF("%s/%s/%ld: ScaledWidth=%lu ScaledHeight=%lu\n", __FILE__, __FUNC__, __LINE__, inst->iobj_ScaledWidth, inst->iobj_ScaledHeight)); + TIMESTAMP_d1(); + + // ExtGadget has valid bounds + gg->MoreFlags |= GMORE_BOUNDS; + + gg->BoundsLeftEdge = gg->LeftEdge; + gg->BoundsTopEdge = gg->TopEdge; + gg->BoundsWidth = gg->Width; + gg->BoundsHeight = gg->Height; + + TIMESTAMP_d1(); + + if (inst->iobj_text) + LayoutIconText(inst, rp, gg); + } + TIMESTAMP_d1(); +} + +//----------------------------------------------------------------------------- + +static struct BitMap *ScaleMaskBitMap(struct BitMap *SourceBM, + ULONG SourceWidth, ULONG SourceHeight, + ULONG *NewWidth, ULONG *NewHeight, + ULONG ScaleFlags, struct BitMap *FriendBM) +{ + struct BitMap *SourceBMFriend; + struct BitMap *NewMaskBM = NULL; + struct BitMap *ScaledBM = NULL; + + d1(KPrintF("%s/%s/%ld: START SourceWidth=%lu SourceHeight=%lu\n", __FILE__, __FUNC__, __LINE__, SourceWidth, SourceHeight)); + d1(KPrintF("%s/%s/%ld: DestWidth=%lu DestHeight=%lu\n", __FILE__, __FUNC__, __LINE__, *NewWidth, *NewHeight)); + d1(KPrintF("%s/%s/%ld: SourceBM: Width=%lu Height=%ld BytesPerRow=%ld\n", \ + __FILE__, __FUNC__, __LINE__, GetBitMapAttr(SourceBM, BMA_WIDTH), \ + GetBitMapAttr(SourceBM, BMA_HEIGHT), SourceBM->BytesPerRow)); + + do { + ULONG BmWidth; + struct ScaleBitMapArg sbma; + static ULONG ColorTable[] = + { + 0, 0, 0, // pen 0 = black + ~0, ~0, ~0, // pen 1 = white + }; + + SourceBMFriend = AllocBitMap(GetBitMapAttr(SourceBM, BMA_WIDTH), + GetBitMapAttr(SourceBM, BMA_HEIGHT), + 1, BMF_CLEAR, FriendBM); + if (NULL == SourceBMFriend) + break; + + d1(KPrintF("%s/%s/%ld: SourceBMFriend Planes=%08lx %08lx %08lx %08lx\n", + __FILE__, __FUNC__, __LINE__, SourceBMFriend->Planes[0], SourceBMFriend->Planes[1], SourceBMFriend->Planes[2], SourceBMFriend->Planes[3])); + + ASSERT_d1(SourceWidth <= GetBitMapAttr(SourceBMFriend, BMA_WIDTH)); + ASSERT_d1(SourceHeight <= GetBitMapAttr(SourceBMFriend, BMA_HEIGHT)); + + BltBitMap(SourceBM, 0, 0, + SourceBMFriend, 0, 0, + SourceWidth, SourceHeight, + ABC | ABNC, + ~0, + NULL); + WaitBlit(); + +#if 0 + { + struct RastPort rp; + + InitRastPort(&rp); + rp.BitMap = SourceBMFriend; + SetAPen(&rp, 1); + RectFill(&rp, + 0, 0, + GetBitMapAttr(SourceBMFriend, BMA_WIDTH) - 1, + GetBitMapAttr(SourceBMFriend, BMA_HEIGHT) - 1); + } +#endif + + sbma.sbma_SourceBM = SourceBMFriend; + sbma.sbma_SourceWidth = SourceWidth; + sbma.sbma_SourceHeight = SourceHeight; + sbma.sbma_DestWidth = NewWidth; + sbma.sbma_DestHeight = NewHeight; + sbma.sbma_NumberOfColors = 2; + sbma.sbma_ColorTable = ColorTable; + sbma.sbma_Flags = ScaleFlags; + sbma.sbma_ScreenBM = FriendBM; + + ScaledBM = ScalosGfxScaleBitMap(&sbma, NULL); + if (NULL == ScaledBM) + break; + + BmWidth = *NewWidth; + if (GetBitMapAttr(FriendBM, BMA_FLAGS) & BMF_INTERLEAVED) + BmWidth *= GetBitMapAttr(FriendBM, BMA_DEPTH); + + NewMaskBM = AllocBitMap(BmWidth, *NewHeight, + 1, BMF_CLEAR, NULL); + if (NULL == NewMaskBM) + break; + + ASSERT_d1(*NewWidth <= GetBitMapAttr(NewMaskBM, BMA_WIDTH)); + ASSERT_d1(*NewHeight <= GetBitMapAttr(NewMaskBM, BMA_HEIGHT)); + + BltBitMap(ScaledBM, 0, 0, + NewMaskBM, 0, 0, + *NewWidth, *NewHeight, + ABC | ABNC, + ~0, + NULL); + + d1(KPrintF("%s/%s/%ld: NewMaskBM: Width=%lu Height=%ld BytesPerRow=%ld\n", \ + __FILE__, __FUNC__, __LINE__, GetBitMapAttr(NewMaskBM, BMA_WIDTH), \ + GetBitMapAttr(NewMaskBM, BMA_HEIGHT), NewMaskBM->BytesPerRow)); + + WaitBlit(); + } while (0); + + d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, SourceBMFriend)); + d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, ScaledBM)); + + if (SourceBMFriend) + FreeBitMap(SourceBMFriend); + if (ScaledBM) + FreeBitMap(ScaledBM); + + d1(KPrintF("%s/%s/%ld: END NewMaskBM=%08lx\n", __FILE__, __FUNC__, __LINE__, NewMaskBM)); + + return NewMaskBM; +} + +//----------------------------------------------------------------------------- + +static void CheckIfScalingRequired(Class *cl, Object *o) +{ + struct InstanceData *inst = INST_DATA(cl, o); + struct ExtGadget *gg = (struct ExtGadget *) o; + + d1(KPrintF("%s/%s/%ld: START o=%08lx <%s> iobj_NakedWidth=%ld iobj_NakedHeight=%ld\n", \ + __FILE__, __FUNC__, __LINE__, o, inst->iobj_name, inst->iobj_NakedWidth, inst->iobj_NakedHeight)); + + if (inst->iobj_ScalingPercentage != 100 + || inst->iobj_NakedWidth < inst->iobj_SizeConstraints.MinX + || inst->iobj_NakedWidth > inst->iobj_SizeConstraints.MaxX + || inst->iobj_NakedHeight < inst->iobj_SizeConstraints.MinY + || inst->iobj_NakedHeight> inst->iobj_SizeConstraints.MaxY) + { + // We need to scale the icon! + d1(KPrintF("%s/%s/%ld: Need to scale icon <%s>\n", __FILE__, __FUNC__, __LINE__, inst->iobj_name)); + + inst->iobj_NakedWidth = (gg->Width * inst->iobj_ScalingPercentage) / 100; + inst->iobj_NakedHeight = (gg->Height * inst->iobj_ScalingPercentage) / 100; + + if (gg->Width < inst->iobj_SizeConstraints.MinX) + inst->iobj_NakedWidth = inst->iobj_SizeConstraints.MinX; + else if (gg->Width > inst->iobj_SizeConstraints.MaxX) + inst->iobj_NakedWidth = inst->iobj_SizeConstraints.MaxX; + + if (gg->Height < inst->iobj_SizeConstraints.MinY) + inst->iobj_NakedHeight = inst->iobj_SizeConstraints.MinY; + else if (gg->Height > inst->iobj_SizeConstraints.MaxY) + inst->iobj_NakedHeight = inst->iobj_SizeConstraints.MaxY; + + ScalosGfxCalculateScaleAspect(inst->iobj_UnscaledWidth, inst->iobj_UnscaledHeight, + &inst->iobj_NakedWidth, &inst->iobj_NakedHeight); + + if (inst->iobj_UnscaledNakedWidth != inst->iobj_NakedWidth + || inst->iobj_UnscaledNakedHeight != inst->iobj_NakedHeight) + { + gg->Width = inst->iobj_ScaledWidth = inst->iobj_NakedWidth; + gg->Height = inst->iobj_ScaledHeight = inst->iobj_NakedHeight; + + inst->iobj_layoutflags &= ~IOBLAYOUTF_Size; + } + + inst->iobj_layoutflags |= IOBLAYOUTF_ScaleNormal | IOBLAYOUTF_ScaleSelected; + } + + d1(KPrintF("%s/%s/%ld: END \n", __FILE__, __FUNC__, __LINE__)); +} + +//----------------------------------------------------------------------------- + +#if defined(DEBUG_MEMORY) + +APTR MyAllocVecPooled_Debug(void *MemPool, size_t Size, CONST_STRPTR CallingFile, + CONST_STRPTR CallingFunc, ULONG CallingLine) +{ + struct AllocatedMemFromPoolDebug *ptr; + + if (MemPool) + { + size_t AllocSize; + + AllocSize = Size + sizeof(struct AllocatedMemFromPoolDebug) + SCALOS_MEM_TRAILER * sizeof(ULONG); + + ObtainSemaphore(&MemPoolSemaphore); + ptr = AllocPooled(MemPool, AllocSize); + ReleaseSemaphore(&MemPoolSemaphore); + if (ptr) + { + ULONG n; + + ptr->amp_Size = AllocSize; + + ptr->amp_Line = CallingLine; + ptr->amp_File = CallingFile; + ptr->amp_Function = CallingFunc; + + ptr->amp_Magic = SCALOS_MEM_START_MAGIC; + + for (n = 0; n < SCALOS_MEM_TRAILER; n++) + *((ULONG *) &ptr->amp_UserData[Size + n * sizeof(ULONG)]) = SCALOS_MEM_END_MAGIC; + + return (APTR) &ptr->amp_UserData; + } + } + + return NULL; +} + + +void MyFreeVecPooled_Debug(void *MemPool, APTR *mem, CONST_STRPTR CallingFile, + CONST_STRPTR CallingFunc, ULONG CallingLine) +{ + if (MemPool && *mem) + { + ULONG n; + size_t OrigSize; + struct AllocatedMemFromPoolDebug *ptr; + + ptr = (struct AllocatedMemFromPoolDebug *) (((UBYTE *) *mem) - offsetof(struct AllocatedMemFromPoolDebug, amp_UserData)); + + if (ptr->amp_Magic != SCALOS_MEM_START_MAGIC) + { + kprintf("ScalosFreeVecPooled: %08lx START_MAGIC not found, called from %s/%s/%ld\n", + *mem, CallingFile, CallingFunc, CallingLine); + return; + } + + OrigSize = ptr->amp_Size - sizeof(struct AllocatedMemFromPoolDebug) - SCALOS_MEM_TRAILER * sizeof(ULONG); + + // Check if block trailer is OK + for (n = 0; n < SCALOS_MEM_TRAILER; n++) + { + if (*((ULONG *) &ptr->amp_UserData[OrigSize + n * sizeof(ULONG)]) != SCALOS_MEM_END_MAGIC) + { + kprintf("ScalosFreeVecPooled: %08lx trailer damaged, called from %s/%s/%ld\n", + *mem, CallingFile, CallingFunc, CallingLine); + kprintf(" original Length=%lu, allocated from %s/%s/%ld\n", + OrigSize, ptr->amp_File, ptr->amp_Function, ptr->amp_Line); + } + } + + ObtainSemaphore(&MemPoolSemaphore); + FreePooled(MemPool, ptr, ptr->amp_Size); + ReleaseSemaphore(&MemPoolSemaphore); + + *mem = NULL; + } +} + +#else /* DEBUG_MEMORY */ + +APTR MyAllocVecPooled(void *MemPool, size_t Size) +{ + APTR ptr; + + d1(kprintf("%s/%s/%ld: MemPool=%08lx Size=%lu\n", __FILE__, __FUNC__, __LINE__, MemPool, Size)); + + if (MemPool) + { + ObtainSemaphore(&MemPoolSemaphore); + ptr = AllocPooled(MemPool, Size + sizeof(size_t)); + ReleaseSemaphore(&MemPoolSemaphore); + if (ptr) + { + size_t *sptr = (size_t *) ptr; + + sptr[0] = Size; + + d1(kprintf("%s/%s/%ld: MemPool=%08lx Size=%lu mem=%08lx\n", __FILE__, __FUNC__, __LINE__, MemPool, Size, &sptr[1])); + return (APTR)(&sptr[1]); + } + } + + d1(kprintf("%s/%s/%ld: MemPool=%08lx Size=%lu\n", __FILE__, __FUNC__, __LINE__, MemPool, Size)); + + return NULL; +} + + +void MyFreeVecPooled(void *MemPool, APTR *mem) +{ + d1(KPrintF("%s/%s/%ld: MemPool=%08lx mem=%08lx\n", __FILE__, __FUNC__, __LINE__, MemPool, *mem)); + if (MemPool && *mem) + { + size_t size; + size_t *sptr = (size_t *) *mem; + APTR MemPtr; + + MemPtr = &sptr[-1]; + size = sptr[-1]; + + ObtainSemaphore(&MemPoolSemaphore); + FreePooled(MemPool, MemPtr, size + sizeof(size_t)); + ReleaseSemaphore(&MemPoolSemaphore); + } + + *mem = NULL; +} + + +#endif /* DEBUG_MEMORY */ + +//----------------------------------------------------------------------------- + +struct TagItem *ScalosVTagList(ULONG FirstTag, va_list args) +{ + struct TagItem *ClonedTagList; + ULONG AllocatedSize = 10; + + d1(KPrintF("%s/%s/%ld: FirstTag=%08lx args=%08lx\n", __FILE__, __FUNC__, __LINE__, FirstTag, args)); + + do { + ULONG NumberOfTags = 1; + BOOL Finished = FALSE; + struct TagItem *ti; + + ClonedTagList = ti = AllocateTagItems(AllocatedSize); + if (NULL == ClonedTagList) + break; + + ClonedTagList->ti_Tag = FirstTag; + while (!Finished) + { + switch (ti->ti_Tag) + { + case TAG_MORE: + ti->ti_Data = va_arg(args, ULONG); + Finished = TRUE; + break; + case TAG_END: + Finished = TRUE; + break; + default: + ti->ti_Data = va_arg(args, ULONG); + break; + } + + d1(KPrintF("%s/%s/%ld ti=%08lx Tag=%08lx Data=%08lx\n", __FILE__, __FUNC__, __LINE__, ti, ti->ti_Tag, ti->ti_Data)); + + if (!Finished) + { + if (++NumberOfTags >= AllocatedSize) + { + // we need to extend our allocated taglist + struct TagItem *ExtendedTagList; + ULONG ExtendedSize = 2 * AllocatedSize; + + ExtendedTagList = AllocateTagItems(ExtendedSize); + if (NULL == ExtendedTagList) + { + FreeTagItems(ClonedTagList); + ClonedTagList = NULL; + break; + } + + d1(KPrintF("%s/%s/%ld: ExtendedTagList=%08lx ClonedTagList=%08lx\n", __FILE__, __FUNC__, __LINE__, ExtendedTagList, ClonedTagList)); + + // copy contents from old to extended taglist + memcpy(ExtendedTagList, ClonedTagList, sizeof(struct TagItem) * AllocatedSize); + + // free old taglist + FreeTagItems(ClonedTagList); + ClonedTagList = ExtendedTagList; + + ti = ClonedTagList + NumberOfTags - 1; + AllocatedSize = ExtendedSize; + } + else + { + ti++; + } + + ti->ti_Tag = va_arg(args, ULONG); + } + } + + d1(KPrintF("%s/%s/%ld: NumberOfTags=%lu AllocatedSize=%lu\n", __FILE__, __FUNC__, __LINE__, NumberOfTags, AllocatedSize)); + } while (0); + + d1(KPrintF("%s/%s/%ld: ClonedTagList=%08lx\n", __FILE__, __FUNC__, __LINE__, ClonedTagList)); + + d1({ ULONG n; \ + for (n = 0; ClonedTagList; n++) \ + { \ + KPrintF("%s/%s/%ld: TagList[%ld]: Tag=%08lx Data=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, n, ClonedTagList[n].ti_Tag, ClonedTagList[n].ti_Data); \ + if (TAG_END == ClonedTagList[n].ti_Tag || TAG_MORE == ClonedTagList[n].ti_Tag) + break; + } \ + }) + + return ClonedTagList; +} + +//----------------------------------------------------------------------------- + +static void ReplaceARGBImage(struct IconObjectARGB *img, struct ARGBHeader *argbh) +{ + if (argbh) + img->iargb_ARGBimage = *argbh; + else + img->iargb_ARGBimage.argb_ImageData = NULL; + + d1(KPrintF("%s/%s/%ld: argb_Width=%ld argb_Height=%ld\n", __FILE__, __FUNC__, __LINE__, img->iargb_ARGBimage.argb_Width, img->iargb_ARGBimage.argb_Height)); + + if (img->iargb_CopyARGBImageData) + { + ScalosGfxFreeARGB(&img->iargb_ClonedARGBImage.argb_ImageData); + + if (img->iargb_ARGBimage.argb_ImageData) + { + ULONG Length = img->iargb_ARGBimage.argb_Width * img->iargb_ARGBimage.argb_Height * sizeof(struct ARGB); + + img->iargb_ClonedARGBImage = img->iargb_ARGBimage; + + img->iargb_ClonedARGBImage.argb_ImageData = ScalosGfxCreateARGB(img->iargb_ARGBimage.argb_Width, img->iargb_ARGBimage.argb_Height, NULL); + if (img->iargb_ClonedARGBImage.argb_ImageData) + { + memcpy(img->iargb_ClonedARGBImage.argb_ImageData, + img->iargb_ARGBimage.argb_ImageData, Length); + + img->iargb_ARGBimage = img->iargb_ClonedARGBImage; + d1(KPrintF("%s/%s/%ld: argbh=%08lx argb_ImageData=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, img->iargb_ARGBimage, img->iargb_ARGBimage.argb_ImageData)); + } + } + } +} + +//----------------------------------------------------------------------------- + +static void FreeARGBImage(struct IconObjectARGB *img) +{ + if (img) + { + ScalosGfxFreeARGB(&img->iargb_ScaledARGBImage.argb_ImageData); + ScalosGfxFreeARGB(&img->iargb_ClonedARGBImage.argb_ImageData); + MyFreeVecPooled(PubMemPool, (APTR *) &img->iargb_AlphaChannel); + d1(KPrintF("%s/%s/%ld: w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, img->iargb_ARGBimage.argb_Width, img->iargb_ARGBimage.argb_Height)); + } +} + +//----------------------------------------------------------------------------- + +static void FreeARGBImageLayout(struct IconObjectARGB *img) +{ + MyFreeVecPooled(PubMemPool, (APTR *) &img->iargb_AlphaChannel); +} + +//----------------------------------------------------------------------------- + +static void FreeMask(struct IconObjectMask *Mask) +{ + MyFreeVecPooled(ChipMemPool, (APTR *) &Mask->iom_Mask); + + if (Mask->iom_MaskBM) + { + d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, Mask->iom_MaskBM)); + FreeBitMap(Mask->iom_MaskBM); + Mask->iom_MaskBM = NULL; + } + if (Mask->iom_MaskInvBM) + { + d1(KPrintF("%s/%s/%ld: bm=%08lx\n", __FILE__, __FUNC__, __LINE__, Mask->iom_MaskInvBM)); + FreeBitMap(Mask->iom_MaskInvBM); + Mask->iom_MaskInvBM = NULL; + } +} + +//----------------------------------------------------------------------------- + +static void LayoutARGB(Class *cl, Object *o, struct IconObjectARGB *img) +{ + struct ExtGadget *gg = (struct ExtGadget *) o; + struct InstanceData *inst = INST_DATA(cl, o); + struct ARGBHeader *ImgHeader; + + d1(KPrintF("%s/%s/%ld: START o=%08lx\n", __FILE__, __FUNC__, __LINE__, o)); + d1(KPrintF("%s/%s/%ld: iargb_ARGBimage w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \ + img->iargb_ARGBimage.argb_Width, \ + img->iargb_ARGBimage.argb_Height)); + + if (img->iargb_ScaledARGBImage.argb_ImageData) + ImgHeader = &img->iargb_ScaledARGBImage; + else + ImgHeader = &img->iargb_ARGBimage; + + d1(KPrintF("%s/%s/%ld: o=%08lx\n", __FILE__, __FUNC__, __LINE__, o)); + + if ((inst->iobj_imgleft + ImgHeader->argb_Width) > gg->BoundsWidth) + { + d1(KPrintF("%s/%s/%ld: o=%08lx\n", __FILE__, __FUNC__, __LINE__, o)); + } + + // Generate iobj_normmaskbm+iobj_selmaskbm from ARGB image + GenMasksFromARGB(cl, o); + + d1(KPrintF("%s/%s/%ld: o=%08lx\n", __FILE__, __FUNC__, __LINE__, o)); + + // Extract alpha channel data from ARGB image + GenAlphaFromARGB(cl, o, img, ImgHeader); + + d1(KPrintF("%s/%s/%ld: END o=%08lx\n", __FILE__, __FUNC__, __LINE__, o)); +} + +//----------------------------------------------------------------------------- + +static BOOL ScaleARGB(Class *cl, Object *o, struct IconObjectARGB *img, + struct IconObjectMask *Mask, ULONG NewWidth, ULONG NewHeight, ULONG ScaleFlags) +{ + struct InstanceData *inst = INST_DATA(cl, o); + BOOL Success = FALSE; + + ScalosGfxFreeARGB(&img->iargb_ScaledARGBImage.argb_ImageData); + + img->iargb_ScaledARGBImage.argb_Width = NewWidth; + img->iargb_ScaledARGBImage.argb_Height = NewHeight; + + img->iargb_ScaledARGBImage.argb_ImageData = ScalosGfxScaleARGBArrayTags(&img->iargb_ARGBimage, + &img->iargb_ScaledARGBImage.argb_Width, + &img->iargb_ScaledARGBImage.argb_Height, + SCALOSGFX_ScaleARGBArrayFlags, ScaleFlags, + TAG_END); + + d1(KPrintF("%s/%s/%ld: NewWidth=%lu NewHeight=%lu\n", __FILE__, __FUNC__, __LINE__, img->iargb_ScaledARGBImage.argb_Width, img->iargb_ScaledARGBImage.argb_Height)); + d1(KPrintF("%s/%s/%ld: NewARGB=%08lx\n", __FILE__, __FUNC__, __LINE__, img->iargb_ScaledARGBImage.argb_ImageData)); + + // Mask and Alpha are automatically recreated during IDTM_Layout + + if (img->iargb_ScaledARGBImage.argb_ImageData) + { + Success = TRUE; + + Mask->iom_Width = inst->iobj_SelectedMask.iom_Width = img->iargb_ScaledARGBImage.argb_Width; + Mask->iom_Height = inst->iobj_SelectedMask.iom_Height = img->iargb_ScaledARGBImage.argb_Height; + d1(KPrintF("%s/%s/%ld: Mask->Width=%lu Mask->Height=%lu\n", __FILE__, __FUNC__, __LINE__, Mask->iom_Width, Mask->iom_Height)); + } + + return Success; +} + +//----------------------------------------------------------------------------- + +static void EraseIconText(Class *cl, Object *o, struct RastPort *rp, WORD x, WORD y) +{ + struct InstanceData *inst = INST_DATA(cl, o); + struct ExtGadget *gg = (struct ExtGadget *) o; + WORD TextLeft = x - inst->iobj_GlobalTextLeftOffset + 1; + WORD TextRight = TextLeft + inst->iobj_TextExtent.te_Width - 1; + WORD TextTop = y + gg->Height + inst->iobj_textskip; + WORD TextBottom = TextTop + inst->iobj_TextExtent.te_Height - 1; + + if (inst->iobj_SelectedTextRectangle) + { +// TextLeft -= inst->iobj_TextRectBorderX; + TextRight += 2 * inst->iobj_TextRectBorderX; + TextBottom += 2 * inst->iobj_TextRectBorderY; + } + + EraseRect(rp, + TextLeft, TextTop, + TextRight, TextBottom); +} + +//----------------------------------------------------------------------------- + +static void DrawIconTextRect(Class *cl, Object *o, struct RastPort *rp, WORD x, WORD y) +{ + struct InstanceData *inst = INST_DATA(cl, o); + + if (inst->iobj_SelectedTextRectangle) + { + PLANEPTR myPlanePtr; + LONG bmWidth = GetBitMapAttr(rp->BitMap, BMA_WIDTH); + LONG bmHeight = GetBitMapAttr(rp->BitMap, BMA_HEIGHT); + + do { + struct ExtGadget *gg = (struct ExtGadget *) o; + WORD AreaBuffer[AREAMAX]; + struct TmpRas myTmpRas; + struct AreaInfo AInfo; + struct RastPort myRp = *rp; + WORD TextLeft = x - inst->iobj_GlobalTextLeftOffset + 1; + WORD TextRight = TextLeft + inst->iobj_TextExtent.te_Width + (2 * inst->iobj_TextRectBorderX) - 1; + WORD TextTop = y + gg->Height + inst->iobj_textskip; + WORD TextBottom = TextTop + inst->iobj_TextExtent.te_Height + (2 * inst->iobj_TextRectBorderY) - 1; + UWORD Radius = inst->iobj_TextRectRadius; + + myPlanePtr = AllocRaster(bmWidth, bmHeight); + if (myPlanePtr == NULL) + break; + + InitTmpRas(&myTmpRas, myPlanePtr, RASSIZE(bmWidth, bmHeight)); + myRp.TmpRas = &myTmpRas; + + InitArea(&AInfo, AreaBuffer, (AREAMAX * sizeof(WORD)) / 5); + myRp.AreaInfo = &AInfo; + + SetABPenDrMd(&myRp, + inst->iobj_TextPenBgSel, + 0, + JAM1); + + // 1-----2 TextTop + // / \ . + // 8 3 . + // | | . + // 7 4 . + // \ / . + // 6---5 TextBottom + + AreaMove(&myRp, TextLeft + Radius, TextTop); // 1 + + AreaDraw(&myRp, TextRight - Radius, TextTop); // -> 2 + AreaDraw(&myRp, TextRight, TextTop + Radius); // -> 3 + AreaDraw(&myRp, TextRight, TextBottom - Radius); // -> 4 + AreaDraw(&myRp, TextRight - Radius, TextBottom); // -> 5 + + AreaDraw(&myRp, TextLeft + Radius, TextBottom); // -> 6 + AreaDraw(&myRp, TextLeft, TextBottom - Radius); // -> 7 + AreaDraw(&myRp, TextLeft, TextTop + Radius); // -> 8 + + AreaEnd(&myRp); + + InitArea(&AInfo, AreaBuffer, (AREAMAX * sizeof(WORD)) / 5); + + AreaCircle(&myRp, TextLeft + Radius, TextTop + Radius, Radius); // top left + AreaCircle(&myRp, TextRight - Radius, TextTop + Radius, Radius); // top right + AreaCircle(&myRp, TextLeft + Radius, TextBottom - Radius, Radius); // bottom left + AreaCircle(&myRp, TextRight - Radius, TextBottom - Radius, Radius); // bottom right + + AreaEnd(&myRp); + + d1(KPrintF("%s/%s/%ld: iobj_TextPenBgSel=%ld\n", __FILE__, __FUNC__, __LINE__, inst->iobj_TextPenBgSel)); + } while (0); + + if (myPlanePtr) + FreeRaster(myPlanePtr, bmWidth, bmHeight); + } + else + { + EraseIconText(cl, o, rp, x, y); + } +} + +//----------------------------------------------------------------------------- +static void DumpMaskPlane(const struct IconObjectMask *Mask) +{ + LONG x, y; + const UBYTE *mp; + + if (!Mask || !Mask->iom_MaskBM || !Mask->iom_MaskBM->Planes[0]) + return; + + mp = Mask->iom_MaskBM->Planes[0]; + + for (y = 0; y < Mask->iom_Height; y++) + { + KPrintF("%s/%s/%ld: ", __FILE__, __FUNC__, __LINE__); + + for (x = 0; x < Mask->iom_Width; x++) + { + UBYTE px = mp[x / 8] & (0x80 >> (x % 8)); + + KPrintF("%ld", (px ? 1 : 0)); + } + KPrintF("\n"); + + mp += BYTESPERROW(Mask->iom_Width); + } +} +//----------------------------------------------------------------------------- +static void DumpMask(const struct IconObjectMask *Mask) +{ + LONG x, y; + const UBYTE *mp; + + if (!Mask || !Mask->iom_Mask) + return; + + mp = Mask->iom_Mask; + + for (y = 0; y < Mask->iom_Height; y++) + { + KPrintF("%s/%s/%ld: ", __FILE__, __FUNC__, __LINE__); + + for (x = 0; x < Mask->iom_Width; x++) + { + UBYTE px = mp[x / 8] & (0x80 >> (x % 8)); + + KPrintF("%ld", (px ? 1 : 0)); + } + KPrintF("\n"); + + mp += BYTESPERROW(Mask->iom_Width); + } +} + +//----------------------------------------------------------------------------- + +static void DumpMaskBM(const struct IconObjectMask *Mask) +{ + LONG x, y; + const UBYTE *mp; + struct RastPort rp; + + if (!Mask || !Mask->iom_Mask) + return; + + mp = Mask->iom_Mask; + + InitRastPort(&rp); + rp.BitMap = Mask->iom_MaskBM; + + for (y = 0; y < Mask->iom_Height; y++) + { + KPrintF("%s/%s/%ld: ", __FILE__, __FUNC__, __LINE__); + + for (x = 0; x < Mask->iom_Width; x++) + { + UBYTE px = ReadPixel(&rp, x, y); + + KPrintF("%ld", (px ? 1 : 0)); + } + KPrintF("\n"); + + mp += BYTESPERROW(Mask->iom_Width); + } +} +//----------------------------------------------------------------------------- + +#if !defined(__SASC) +// Replacement for SAS/C library functions + +void exit(int x) +{ + (void) x; + while (1) + ; +} + +#endif /* !defined(__SASC) */ +//----------------------------------------------------------------------------- diff --git a/scalos/datatypes/IconObject/iconobj.h b/scalos/datatypes/IconObject/iconobj.h new file mode 100644 index 000000000..ffa985579 --- /dev/null +++ b/scalos/datatypes/IconObject/iconobj.h @@ -0,0 +1,319 @@ +// iconobject.h +// $Date$ +// $Revision$ + + +#ifndef ICONOBJECT_H_INCLUDED +#define ICONOBJECT_H_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +//----------------------------------------------------------------------------- + +#define NO_ICON_POSITION_SHORT ((UWORD) 0x8000) + +#define FRAMETYPE_NONE ((UWORD) -1) + +#define BYTESPERROW(width) ((((width) + 15) & 0xfff0) >> 3) +#define ALIGN_LONG(x) (((x) + 3) & 0xfffc) + +struct IconObjectDtLibBase; + +//----------------------------------------------------------------------------- + +LIBFUNC_PROTO(ObtainInfoEngine, libbase, ULONG); + +ULONG InitDatatype(struct IconObjectDtLibBase *dtLib); +ULONG OpenDatatype(struct IconObjectDtLibBase *dtLib); +void CloseDatatype(struct IconObjectDtLibBase *dtLib); + +//---------------------------------------------------------------------------- + +#define LIB_VERSION 40 +#define LIB_REVISION 27 + +extern char ALIGNED libName[]; +extern char ALIGNED libIdString[]; + +//----------------------------------------------------------------------------- + +//#define DEBUG_MEMORY + +#ifdef DEBUG_MEMORY +#define MyAllocVecPooled(mempool, size) \ + MyAllocVecPooled_Debug(mempool, size, __FILE__, __FUNC__, __LINE__) +#define MyFreeVecPooled(mempool, mem) \ + MyFreeVecPooled_Debug(mempool, mem, __FILE__, __FUNC__, __LINE__) +#endif /* DEBUG_MEMORY */ + +//----------------------------------------------------------------------------- + +#define PUBMEMPOOL_MEMFLAGS MEMF_PUBLIC +#define PUBMEMPOOL_PUDDLESIZE 16384 +#define PUBMEMPOOL_THRESHSIZE 16384 + +//----------------------------------------------------------------------------- + +#define CHIPMEMPOOL_MEMFLAGS (MEMF_PUBLIC | MEMF_CHIP) +#define CHIPMEMPOOL_PUDDLESIZE 8192 +#define CHIPMEMPOOL_THRESHSIZE 8192 + +//----------------------------------------------------------------------------- + +struct IconObjectDtLibBase + { + struct ClassLibrary nib_ClassLibrary; + + struct SegList *nib_SegList; + + UBYTE nib_Initialized; + }; + +//----------------------------------------------------------------------------- + +struct IconObjectTextLine + { + UWORD iotl_numchars; + UWORD iotl_TextStart; + WORD iotl_TextLeft; + WORD iotl_TextWidth; + WORD iotl_TextHeight; + struct TextExtent iotl_TextExtent; + }; + +struct IconObjectARGB + { + struct ARGBHeader iargb_ARGBimage; // optional ARGB image data, (gg->Width x gg->Height) + struct ARGBHeader iargb_ScaledARGBImage; + + struct ARGBHeader iargb_ClonedARGBImage; + ULONG iargb_CopyARGBImageData; // Flag: create a copy of + + UBYTE *iargb_AlphaChannel; // optional alpha channel data, (gg->Width x gg->Height) + }; + +struct IconObjectMask + { + UBYTE *iom_Mask; // unselected icon mask - raw BitMap plane with size of icon w/o borders + struct BitMap *iom_MaskBM; // BitMap with unselected icon mask - size includes borders, ready to be blitted to/from. + struct BitMap *iom_MaskInvBM; // BitMap with unselected icon inverted mask - size includes borders, ready to be blitted to/from. + + ULONG iom_Width; // Dimensions of iom_Mask + ULONG iom_Height; + }; + +struct InstanceData + { + STRPTR iobj_text; + ULONG iobj_stacksize; + STRPTR iobj_defaulttool; + STRPTR iobj_ToolWindow; + STRPTR *iobj_tooltypes; + + struct IBox iobj_winrect; + + STRPTR iobj_name; + UWORD iobj_numchars; // strlen(iobj_name) + + UWORD iobj_frametype; + UWORD iobj_frametypesel; + + struct Rectangle iobj_SizeConstraints; + UWORD iobj_ScalingPercentage; + + struct TextExtent iobj_TextExtent; + WORD iobj_GlobalTextLeftOffset; + + UWORD iobj_imgleft; // Inner offsets + UWORD iobj_imgright; + UWORD iobj_imgtop; + UWORD iobj_imgbottom; + + ULONG iobj_wincurx; // VR Offset + ULONG iobj_wincury; + + struct IconObjectMask iobj_NormalMask; + struct IconObjectMask iobj_SelectedMask; + + struct RastPort iobj_RenderRastPort; // statically allocated RastPort for gg->GadgetRender + struct RastPort iobj_SelectRastPort; // statically allocated RastPort for gg->SelectRender + + struct RastPort iobj_BackfillRastPort; // statically allocated RastPort for backfill + struct RastPort *iobj_BackfillRp; // allocated auxiliary RastPort for backfill + + struct IconObjectARGB iobj_NormalARGB; // unselected ARGB image + struct IconObjectARGB iobj_SelectedARGB; // selected ARGB image + + ULONG iobj_UnscaledWidth; // temporary storage for ITDM_ScaleIcon new width until used on next IDTM_Draw + ULONG iobj_UnscaledHeight; // temporary storage for ITDM_ScaleIcon new height until used on next IDTM_Draw + + ULONG iobj_ScaledWidth; // temporary storage for ITDM_ScaleIcon new width until used on next IDTM_Draw + ULONG iobj_ScaledHeight; // temporary storage for ITDM_ScaleIcon new height until used on next IDTM_Draw + + ULONG iobj_NakedMaskWidth; // Mask width without borders + ULONG iobj_NakedMaskHeight; // Mask height without borders + + struct Hook *iobj_FontHook; + + void *iobj_Fonthandle; // opaque font handle + struct TextFont *iobj_Font; // +jl+ 20010818 TextFont for the icon text or NULL + UWORD iobj_FontBaseLine; + + ULONG iobj_ddflags; // DrawerData Flags + ULONG iobj_UserFlags; // +jl+ 20020928 + ULONG iobj_OverlayType; // Type of overlay to draw aboe this icon + // not used by icon datatype - only for storage + + ULONG iobj_NakedWidth; // Width without borders + ULONG iobj_NakedHeight; // Height without borders + + ULONG iobj_UnscaledNakedWidth; // Width without borders + ULONG iobj_UnscaledNakedHeight; // Height without borders + + ULONG iobj_TextStyle; // +jl+ 20011231 + ULONG iobj_Borderless; // +jl+ 20030420 + + UWORD iobj_viewmodes; //DrawerData Viewmodes + + UWORD iobj_TextPen; //standard Text pen + UWORD iobj_TextPenSel; //selected Text pen + UWORD iobj_TextPenOutline; //Outline Text pen + UWORD iobj_TextPenShadow; //Shadow Text pen + UWORD iobj_textskip; //Space between image and text + UWORD iobj_TextDrawMode; // DrawMode for standard (no shadow, no outline) icon text + UWORD iobj_TextBackPen; // Background pen for icon text, for JAM2 iobj_TextDrawMode + UWORD iobj_TextPenBgSel; // Pen for rectangle around selected icon text + + ULONG iobj_BackfillPenNorm; // pen to use for unselected background fill or IDTA_BACKFILL_NONE + ULONG iobj_BackfillPenSel; // pen to use for selected background fill or IDTA_BACKFILL_NONE + + UWORD iobj_HalfShadowPen; + UWORD iobj_HalfShinePen; + + UWORD iobj_TextRectBorderX; // Additional horizontal border around selected icon text rectangle + UWORD iobj_TextRectBorderY; // Additional vertical border around selected icon text rectangle + UWORD iobj_TextRectRadius; // Radius for selected icon text rectangle corners + + struct SignalSemaphore iobj_LayoutSemaphore; + + UBYTE iobj_type; //IconType + UBYTE iobj_layoutflags; + UBYTE iobj_textmode; //IDTV_TextMode_Normal, IDTV_TextMode_Outline, IDTV_TextMode_Shadow + UBYTE iobj_MultiLineText; //Flag: Allow splitting of icon text into multiple lines + UBYTE iobj_SelectedTextRectangle; //Flag: draw rectangle around selected icon text + + struct SignalSemaphore iobj_TextSemaphore; //This semaphore protects iobj_text during IDTM_Layout and IDTM_Draw + + struct IconObjectTextLine iobj_TextLines[10]; + }; + +// Bits in iobj_layoutflags: + +#define IOBLAYOUTB_Size 0 +#define IOBLAYOUTB_NormalImage 1 +#define IOBLAYOUTB_SelectedImage 2 +#define IOBLAYOUTB_ScaleNormal 3 +#define IOBLAYOUTB_ScaleSelected 4 +#define IOBLAYOUTB_BackfillNormal 5 +#define IOBLAYOUTB_BackfillSelected 6 + +#define IOBLAYOUTF_Size (1 << IOBLAYOUTB_Size) +#define IOBLAYOUTF_NormalImage (1 << IOBLAYOUTB_NormalImage) +#define IOBLAYOUTF_SelectedImage (1 << IOBLAYOUTB_SelectedImage) +#define IOBLAYOUTF_ScaleNormal (1 << IOBLAYOUTB_ScaleNormal) +#define IOBLAYOUTF_ScaleSelected (1 << IOBLAYOUTB_ScaleSelected) +#define IOBLAYOUTF_BackfillNormal (1 << IOBLAYOUTB_BackfillNormal) +#define IOBLAYOUTF_BackfillSelected (1 << IOBLAYOUTB_BackfillSelected) + +/* ------------------------------------------------- */ + +// Flag values for ScaleBitMap() and ScaleARGBArray() + +#define SCALEFLAGB_BILINEAR 0 +#define SCALEFLAGB_AVERAGE 1 +#define SCALEFLAGB_DOUBLESIZE 2 +#define SCALEFLAGB_CORRECTASPECT 3 + +#define SCALEFLAGF_BILINEAR (1L << SCALEFLAGB_BILINEAR) +#define SCALEFLAGF_AVERAGE (1L << SCALEFLAGB_AVERAGE) +#define SCALEFLAGF_DOUBLESIZE (1L << SCALEFLAGB_DOUBLESIZE) +#define SCALEFLAGF_CORRECTASPECT (1L << SCALEFLAGB_CORRECTASPECT) + +// check equality of 2 ARGB variables +#define ARGB_EQ(a, b) (*((ULONG *) &(a)) == *((ULONG *) &(b))) + +/* ------------------------------------------------- */ + +#define Sizeof(x) (sizeof(x) / sizeof(x[0])) + +/* ------------------------------------------------- */ + +// from debug.lib +#if defined(__AROS__) +#include +#define KPrintF kprintf +#else +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); +#endif + +//#define TIMESTAMPS +#define TIMESTAMP_d1() ; +#define TIMESTAMP_d2() \ + { \ + struct EClockVal ev; \ + ULONG ticks; \ + ticks = ReadEClock(&ev); \ + KPrintF("%s/%s/%ld: ticks=%lu hi=%8lu lo=%8lu\n", __FILE__, __FUNC__, __LINE__, ticks, ev.ev_hi, ev.ev_lo); \ + } + +#define d1(x) ; +#define d2(x) { Forbid(); x; Permit(); } + + +#define ASSERT_d1(expression) ((void) 0) + +#define ASSERT_d2(expression) \ + ((void) ((expression) ? 0 : __assert (expression, __FILE__, __FUNC__, __LINE__))) + +#define __assert(expression, file, func, lineno) \ + ( KPrintF("%s/%s/%lu: !!! failed assertion `%s'\n", file, func, lineno, #expression), 0 ) + +/* ------------------------------------------------- */ + +// defined in argb.c + +void ARGB_Draw(Class *cl, Object *o, struct iopDraw *opd, LONG x, LONG y); +BOOL GenMasksFromARGB(Class *cl, Object *o); +BOOL GenAlphaFromARGB(Class *cl, Object *o, struct IconObjectARGB *img, struct ARGBHeader *ImgHeader); + +/* ------------------------------------------------- */ + +// defined in iconobj.c + +extern void *PubMemPool; +extern void *ChipMemPool; + +#ifdef DEBUG_MEMORY +APTR MyAllocVecPooled_Debug(void *MemPool, size_t Size, CONST_STRPTR CallingFile, + CONST_STRPTR CallingFunc, ULONG CallingLine); +void MyFreeVecPooled_Debug(void *MemPool, APTR *mem, CONST_STRPTR CallingFile, + CONST_STRPTR CallingFunc, ULONG CallingLine); +#else /* DEBUG_MEMORY */ +APTR MyAllocVecPooled(void *MemPool, size_t Size); +void MyFreeVecPooled(void *MemPool, APTR *mem); +#endif /* DEBUG_MEMORY */ + +/* ------------------------------------------------- */ + +#endif // ICONOBJECT_H_INCLUDED diff --git a/scalos/datatypes/IconObject/makefile b/scalos/datatypes/IconObject/makefile new file mode 100644 index 000000000..f83772642 --- /dev/null +++ b/scalos/datatypes/IconObject/makefile @@ -0,0 +1,113 @@ +# makefile für Scalos IconObject.datatype +# $Date$ +# $Revision$ +# $Id$ +##################################################################### + +CSRCS = \ + iconobj-classic.c \ + iconobj.c \ + argb.c \ + $(MCPGFX_DIR)/ScalosMcpGfx.c \ + +ASRCS = + +##################################################################### + +SPLAT = sc:c/splat +AS = phxAss +LD = slink +CC = sc +ECHO = echo +MKDIR = mkdir -p #makedir force +LIBS = LIB:debug.lib LIB:amiga.lib +PRECOMP = Include:all.gst +DT_DIR = scalos:IconDatatypes/datatypes +OBJDIR = .sasobj +MCPGFX_DIR = ../../common/McpGfx + +.SUFFIXES: .asm + +##################################################################### + +CFLAGS = optimize nostackcheck nover math=standard data=far \ + dbg=f idlen=64 ignore=306 \ + idir=//include idir=//common/McpGfx +LNFLAGS = quiet batch noicons stripdebug +LNDBFLAGS = quiet batch noicons addsym +LIBS = LIB:sc.lib LIB:debug.lib LIB:amiga.lib + +ifdef L +AFLAGS = QUIET DS NOEXE opt=NRQB LIST=* linedebug I=SC:Assembler_Headers +else +AFLAGS = QUIET DS NOEXE opt=NRQB linedebug I=SC:Assembler_Headers +endif + +##################################################################### + +XSRCS = $(notdir $(CSRCS)) +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(XSRCS:%.c=$(OBJDIR)/$(notdir %).o) + +##################################################################### + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +##################################################################### + +DTNAME = .bin_os3/iconobject.datatype +DTDBGNAME = $(DTNAME).debug + +##################################################################### + +all: $(DTNAME) \ + $(DTDBGNAME) + +##################################################################### + +$(OBJDIR)/ScalosMcpGfx.o: $(MCPGFX_DIR)/ScalosMcpGfx.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $(subst ../,/,$<) objectname $@ + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $* objectname $@ + +##################################################################### + +$(DTNAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) from $(OBJS) to $(DTNAME) LIB $(LIBS) $(LNFLAGS) + +$(DTDBGNAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) from $(OBJS) to $(DTDBGNAME) LIB $(LIBS) $(LNDBFLAGS) + +##################################################################### + +$(OBJDIR)/iconobj-classic.o : iconobj.h +$(OBJDIR)/iconobj.o : iconobj.h +$(OBJDIR)/argb.o : iconobj.h +$(OBJDIR)/ScalosMcpGfx.o : $(MCPGFX_DIR)/ScalosMcpGfx.c + +##################################################################### + +install: + @printf '\033[32mFlushing memory...\033[0m\n' + avail flush + @printf '\033[32mInstall: \033[31m\033[1m$(DTNAME)\033[0m\n' + -@$(MKDIR) $(DT_DIR) + copy $(DTNAME) $(DT_DIR) + +##################################################################### + +clean: + -@delete $(DTNAME) $(DTDBGNAME) $(OBJS) + +############################################################# + +nodebug: + -@$(SPLAT) -s -o "d2(" "d1(" "#?.c" + +##################################################################### + diff --git a/scalos/datatypes/IconObject/makefile-new b/scalos/datatypes/IconObject/makefile-new new file mode 100755 index 000000000..9ea14f466 --- /dev/null +++ b/scalos/datatypes/IconObject/makefile-new @@ -0,0 +1,85 @@ +# $Date: 2011-07-09 20:50:13 +0200 (Sa, 09. Jul 2011) $ +# $Revision: 759 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS := $(OBJDIR)/iconobj.o \ + $(OBJDIR)/argb.o \ + $(OBJDIR)/ScalosMcpGfx.o \ + +ifeq ($(MACHINE), ppc-amigaos) +OBJS := $(OBJDIR)/iconobj-aos4.o $(OBJS) +else +ifeq ($(MACHINE), i386-aros) +OBJS := $(OBJDIR)/iconobj-aros.o $(OBJS) +else +OBJS := $(OBJDIR)/iconobj-classic.o $(OBJS) +endif +endif + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Some lame deps +# + +$(OBJDIR)/%.o: $(MCPGFX_DIR)/%.c + @$(run-cc) + +############################################################################## +# +# Targets +# + +NAME = iconobject.datatype +NAME_DB = iconobject.datatype.debug + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + @$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + -@$(MKDIR) $(DT_DIR) + @copy $(BINDIR)/$(NAME) $(DT_DIR) + @avail flush + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* + +############################################################################## diff --git a/scalos/datatypes/New Icon Format Mail b/scalos/datatypes/New Icon Format Mail new file mode 100644 index 000000000..7d491bd79 --- /dev/null +++ b/scalos/datatypes/New Icon Format Mail @@ -0,0 +1,223 @@ +Return-Path: +Delivered-To: redhotant¬co¬uk-mike.carter@redhotant.co.uk +Received: (qmail 24928 invoked from network); 25 May 2000 16:15:05 -0000 +Received: from ef.egroups.com (207.138.41.172) + by mail.jakinternet.co.uk with SMTP; 25 May 2000 16:15:05 -0000 +X-eGroups-Return: sentto-365480-746-959272050-mike.carter=redhotant.co.uk@returns.onelist.com +Received: from [10.1.10.35] by ef.egroups.com with NNFMP; 25 May 2000 16:27:30 -0000 +Received: (qmail 20280 invoked from network); 25 May 2000 16:27:29 -0000 +Received: from unknown (10.1.10.27) by m1.onelist.org with QMQP; 25 May 2000 16:27:29 -0000 +Received: from unknown (HELO hudson.atuk.aspentec.com) (208.201.95.28) by mta2 with SMTP; 25 May 2000 16:27:28 -0000 +Received: by hudson.atuk.aspentec.com with Internet Mail Service (5.5.2650.21) id ; Thu, 25 May 2000 17:29:51 +0100 +Message-ID: <40A5DAC1F183D3119DF300805F8BDD32016EC3B4@hudson.atuk.aspentec.com> +To: "sdev (E-mail)" +X-Mailer: Internet Mail Service (5.5.2650.21) +From: Michael Carter +MIME-Version: 1.0 +Mailing-List: list scalos-dev@egroups.com; contact scalos-dev-owner@egroups.com +Delivered-To: mailing list scalos-dev@egroups.com +Precedence: bulk +List-Unsubscribe: +Date: Thu, 25 May 2000 17:29:50 +0100 +Reply-To: scalos-dev@egroups.com +Subject: [scalos-dev] FW: colourimage icon format +Content-Type: text/plain; charset=US-ASCII +Content-Transfer-Encoding: 7bit + +Heres a little gem for you Richard :) + +-----Original Message----- +From: Olaf Barthel [mailto:olsen@sourcery.han.de] +Sent: Thursday, May 25, 2000 3:57 PM +To: Michael Carter +Subject: Re: colourimage icon format + + +On May 25 Michael (Michael Carter) wrote: + +> Hi Olaf, +> +> I wounder if you would be willing to help? I'm project manager of Scalos +> and we're currently sorting out OS3.5 icon support. However the coder of +> the icon datatype has been trying to get everything working and compatible +> but is getting peeved with the mess the code is getting opening libaries +all +> over the place just to read the icon format. + + Hm... what's the problem? Opening icon.library and calling +GetIconTagList() +should do the trick, shouldn't it? + +> We know the new colouricon format is in a IFF structure tacked to the end +of +> the OS3.5 icons ... but have not tried to work out how to decode it. +Would +> you be willing to either make some sort of domcument detailing the chunky +> encoding or maybe a snippet of source to show how to get the data from the +> .info file to a image? + + Say, why do you need to know this? The icon file format has never been +officially documented, which may not have been a good idea, but judging +from how it works I can understand why they never documented it (it really +is +rather embarrassing). So far I didn't write a complete description of +the format, so the only way to explain how it works would be by sharing +code. Before I can hand out code, I need some sort of authorization. If +you can arrange for Amiga, Inc. to nod their heads, I'd be happy to share +the reader code with you. Until then, here are my notes on the icon +file format: + +/* The layout of an old icon file (format version 1.1) is as follows: + * + * ::= (struct DiskObject); 78 bytes + * ::= (struct OldDrawerData); 56 bytes + * ::= the last six bytes of a (struct DrawerData) + * ::= (struct Image); 20 bytes + * ::= UWORD[]; variable number of bytes, depending on image +size + * ::= LONG; 4 bytes + * ::= UBYTE[]; variable number of bytes, depending on string +length + * ::= LONG; 4 bytes + * ::= + * ::= + * ::= + * ::= + * ::= + * + * ::= [] +[] + * [] [ +] + * [] [] + * + * NOTES: + * + * - If the icon has drawer data attached, is + * mandatory; if the icon's do_Gadget.UserData member's lowest + * eight bits (which contain the file format revision number) + * are > 0 and <= WB_DISKREVISION, must + * be present, too. + * + * - The image data size is computed from the information stored + * in the preceding image header; exactly + * RASSIZE(image->Width,image->Height) * image->Depth bytes will + * be stored. RASSIZE(w,h) computes as ((((w + 15) / 8) & ~1) * h). + * + * - is actually the number of tool types plus + * one, multiplied by four, i.e. for six tool type strings to be + * stored, would be (6 + 1) * 4 = 28. In other + * words, there are exactly (-1)/4 tool + * type strings following . + * may never be 0. + * + * - always includes the trailing NUL byte. + * always includes this extra byte, i.e. the string "foo" would + * be stored as four bytes and its length would be stored as + * four bytes. + * + * - The contents of define whether and + * , , , + * and , will + * be stored in the file. If do_DrawerData==NULL, and + * will be omitted; if +do_Gadget.SelectRender==NULL + * will be omitted; if do_DefaultTool==NULL + + * will be omitted; if do_ToolTypes==NULL and + + * will be omitted; if do_ToolWindow==NULL, will be +omitted. + * + * + * The layout of a new icon file is as follows: + * + * ::= UBYTE[4]; four upper case 7 bit ASCII characters + * ::= ULONG; four bytes; contents must be an even number + * ::= UBYTE[]; variable number of bytes, depending on chunk +length; + * this must be an even number of bytes + * ::= + * ::= "FACE"; four bytes + * ::= (struct FaceChunk); 4 bytes + * ::= + * ::= "IMAG"; four bytes + * ::= (struct ImageChunk); 8 bytes + * ::= UBYTE[]; variable number of bytes, depending on + * palette size + * ::= UBYTE[]; variable number of bytes, depending on + * image size + * ::= +[] + * ::= "FORM"; four bytes + * ::= "ICON"; four bytes + * + * ::= + * [] * + * + * NOTES: + * + * - The new icon data structures immediately follow the old icon data + * structures; the new data is more or less stored in straight IFF + * format, the only difference being that the IFF structure need not + * begin at an even offset into the file. There are no version or revision + * indicators or magic numbers in the icon file to tell the reader that + * there is new data following the old icon format. The reader just tries + * to read the data and makes the best of what follows. + * + * - The chunk contents must always be an even number of bytes long. + * If necessary, pad bytes are added. + * + * - The of the initial "FORM" chunk contains the + * number of bytes to follow minus 8 bytes + * (used by and ). + * + * - The IMAG chunks contain both the header information and the + * pixel and palette data. Immediately following the header + * there will be ic_NumImageBytes+1 bytes of image data. If the + * ICF_HasPalette flag is set in the ic_Flags member, exactly + * ic_NumPaletteBytes+1 number of palette bytes will follow the + * pixel data, otherwise, there will be 0 bytes of palette + * information and the contents of ic_NumPaletteBytes will + * be ignored. + * + * - The first image stored in an IMAG chunk must have palette + * information. If the second image has no palette stored + * with it, it will use the palette of the first image. + * + * - Palette and image data may be stored in compressed format. + * The only compression algorithm supported so far is the run + * length encoding method known as "ByteRun1" as used by the + * IFF-ILBM format. Data may be stored in compressed format only + * if compression actually resulted in space savings. The + * ByteRun1 compression method operates on pixels with the number + * of significant bits taken into account. This means, for example, + * that if the pixel data contains only colours in the range 0..15 + * that there are four significant bits. The compressor will then + * pack the four bit pixel values into bytes. + * + * - In the FACE chunk, the image aspect ratio information is encoded + * into a single byte. The upper four bits contain the X aspect value, + * the lower bits contain the Y aspect value, i.e. a ratio of 1:2 would + * be encoded as 0x12. + * + * - The image size given in the FACE chunk need not agree with the + * data stored in the DiskObject do_Gadget.Width/do_Gadget.Height + * members since the loader will automatically adjust these values + * acording to the actual image size being used. If no new icon data + * is stored with a file, the loader will default to use the size of + * the first found. + */ + +-- +Home: Olaf Barthel, Brabeckstrasse 35, D-30559 Hannover + Net: olsen@sourcery.han.de (Home), olsen@logicalline.com (Work) + +------------------------------------------------------------------------ +Best friends, most artistic, class clown Find 'em here: +http://click.egroups.com/1/4054/0/_/647280/_/959272050/ +------------------------------------------------------------------------ + +.-----------------------------------------------. + http://scalos.satanicdreams.com + + diff --git a/scalos/datatypes/NewIcons/NewIconDt.c b/scalos/datatypes/NewIcons/NewIconDt.c new file mode 100644 index 000000000..273f5a255 --- /dev/null +++ b/scalos/datatypes/NewIcons/NewIconDt.c @@ -0,0 +1,1484 @@ +// NewIconDt.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include + +#include +#include + +#include "NewIconDt.h" + +//----------------------------------------------------------------------------- + +#define max(a,b) ((a) > (b) ? (a) : (b)) +#define min(a,b) ((a) < (b) ? (a) : (b)) + +//----------------------------------------------------------------------------- + +void *NewMemPool; + +Class *NewIconClass; + +const ULONG InstanceSize = sizeof(struct InstanceData); + +static struct SignalSemaphore NewMemPoolSemaphore; + +struct ExecBase *SysBase; +struct NewIconBase *NewIconBase; +static struct Library *IconObjectDTBase; +T_UTILITYBASE UtilityBase; +struct GfxBase *GfxBase; +struct IntuitionBase *IntuitionBase; +struct Library *PreferencesBase; +struct Library *CyberGfxBase; + +//---------------------------------------------------------------------------- +// Standard library functions + +static LIB_SAVEDS(struct Library *) LIB_ASM LIB_INTERRUPT Initlib(LIB_REG(d0, struct Library *libbase), + LIB_REG(a0, struct SegList *seglist), LIB_REG(a6, struct ExecBase *sysbase)); + +static LIBFUNC_PROTO(Openlib, libbase, struct Library *); +static LIBFUNC_PROTO(Closelib, libbase, struct SegList *); +static LIBFUNC_PROTO(Expungelib, libbase, struct SegList *); +static LIBFUNC_PROTO(Extfunclib, libbase, ULONG); + +static LIBFUNC_PROTO(ObtainInfoEngine, libbase, ULONG); + +//---------------------------------------------------------------------------- + +static ULONG InitDatatype(struct NewIconDtLibBase *dtLib); +static ULONG OpenDatatype(struct NewIconDtLibBase *dtLib); +static void CloseDatatype(struct NewIconDtLibBase *dtLib); + +static SAVEDS(ULONG) INTERRUPT NewIconDispatcher(Class *cl, Object *o, Msg msg); + +static BOOL DtNew(Class *cl, Object *o, struct opSet *ops); +static ULONG DtDispose(Class *cl, Object *o, Msg msg); +static ULONG DtSet(Class *cl, Object *o, struct opSet *ops); +static ULONG DtGet(Class *cl, Object *o, struct opGet *opg); +static ULONG DtLayout(Class *cl, Object *o, struct iopLayout *opl); +static ULONG DtFreeLayout(Class *cl, Object *o, struct iopFreeLayout *opf); +static ULONG DtWrite(Class *cl, Object *o, struct iopWrite *opw); +static ULONG DtNewImage(Class *cl, Object *o, struct iopNewImage *iopw); +static ULONG DtClone(Class *cl, Object *o, struct iopCloneIconObject *iocio); + +static void DoFreeLayout(Class *cl, Object *o, struct iopFreeLayout *opf); +static void ReadPrefs(struct NewIconDtLibBase *dtLib); +static UBYTE **CloneToolTypes(const UBYTE **OrigToolTypes); +static UBYTE *GenerateMask(struct ExtChunkyImage *ChImg); +static void DtDrawImage(LONG LeftEdge, LONG TopEdge, struct RastPort *rp, struct Image *img); +static UBYTE *DrawCyberImage(struct InstanceData *inst, LONG LeftEdge, LONG TopEdge, + struct RastPort *rp, struct ChunkyImage *cki); +static void WriteARGBArray(const struct ARGB *SrcImgData, + ULONG SrcX, ULONG SrcY, ULONG SrcBytesPerRow, + struct RastPort *DestRp, ULONG DestX, ULONG DestY, + ULONG SizeX, ULONG SizeY); +static struct ExtChunkyImage *ChunkyImageFromSAC(struct ScalosBitMapAndColor *sac); +static void FreeChunkyImage(struct ExtChunkyImage **ci); +static void GenerateMasks(Class *cl, Object *o); + +static APTR MyAllocVecPooled(size_t Size); +static void MyFreeVecPooled(APTR mem); + +//---------------------------------------------------------------------------- + +SAVEDS(LONG) ASM Libstart(void) +{ + return -1; +} + +//---------------------------------------------------------------------------- + +#define LIB_VERSION 40 +#define LIB_REVISION 11 + +static char ALIGNED libName[] = "newiconobject.datatype"; +static char ALIGNED libIdString[] = "$VER: newiconobject.datatype " + STR(LIB_VERSION) "." STR(LIB_REVISION) + " (21 Jan 2007 20:35:12) " + COMPILER_STRING + " ©1999" CURRENTYEAR " The Scalos Team"; + +//---------------------------------------------------------------------------- + +/* OS3.x Library */ + +static APTR functable[] = + { +#ifdef __MORPHOS__ + (APTR) FUNCARRAY_32BIT_NATIVE, +#endif + Openlib, + Closelib, + Expungelib, + Extfunclib, + ObtainInfoEngine, + (APTR) -1 + }; + +/* Init table used in library initialization. */ +static ULONG inittab[] = + { + sizeof(struct NewIconDtLibBase), + (ULONG) functable, + 0, + (ULONG) Initlib + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, +#ifdef __MORPHOS__ + RTF_PPC | RTF_AUTOINIT, +#else + RTF_AUTOINIT, +#endif + LIB_VERSION, + NT_LIBRARY, + 0, + libName, + libIdString, + inittab + }; + +#ifdef __MORPHOS__ +ULONG __abox__=1; +#endif + +//---------------------------------------------------------------------------- + +static LIB_SAVEDS(struct Library *) LIB_ASM LIB_INTERRUPT Initlib(LIB_REG(d0, struct Library *libbase), + LIB_REG(a0, struct SegList *seglist), LIB_REG(a6, struct ExecBase *sysbase)) +{ + struct NewIconDtLibBase *dtLib = (struct NewIconDtLibBase *) libbase; + + SysBase = sysbase; + dtLib->nib_ClassLibrary.cl_Lib.lib_Revision = LIB_REVISION; + dtLib->nib_ClassLibrary.cl_Lib.lib_Node.ln_Pri = 5; + dtLib->nib_SegList = seglist; + + if (!InitDatatype(dtLib)) + { + CALLLIBFUNC(Expungelib, &dtLib->nib_ClassLibrary.cl_Lib); + dtLib = NULL; + } + + return dtLib ? &dtLib->nib_ClassLibrary.cl_Lib : NULL; +} + + +static LIBFUNC(Openlib, libbase, struct Library *) +{ + struct NewIconDtLibBase *dtLib = (struct NewIconDtLibBase *) libbase; + + dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt++; + dtLib->nib_ClassLibrary.cl_Lib.lib_Flags &= ~LIBF_DELEXP; + + if (!OpenDatatype(dtLib)) + { + CALLLIBFUNC(Closelib, &dtLib->nib_ClassLibrary.cl_Lib); + return NULL; + } + + return &dtLib->nib_ClassLibrary.cl_Lib; +} +LIBFUNC_END + + +static LIBFUNC(Closelib, libbase, struct SegList *) +{ + struct NewIconDtLibBase *dtLib = (struct NewIconDtLibBase *) libbase; + + dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt--; + + if (0 == dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + if (dtLib->nib_ClassLibrary.cl_Lib.lib_Flags & LIBF_DELEXP) + { + return CALLLIBFUNC(Expungelib, &dtLib->nib_ClassLibrary.cl_Lib); + } + } + + return NULL; +} +LIBFUNC_END + + +static LIBFUNC(Expungelib, libbase, struct SegList *) +{ + struct NewIconDtLibBase *dtLib = (struct NewIconDtLibBase *) libbase; + + if (0 == dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + ULONG size = dtLib->nib_ClassLibrary.cl_Lib.lib_NegSize + dtLib->nib_ClassLibrary.cl_Lib.lib_PosSize; + UBYTE *ptr = (UBYTE *) dtLib - dtLib->nib_ClassLibrary.cl_Lib.lib_NegSize; + struct SegList *libseglist = dtLib->nib_SegList; + + Remove((struct Node *) dtLib); + CloseDatatype(dtLib); + FreeMem(ptr,size); + + return libseglist; + } + + dtLib->nib_ClassLibrary.cl_Lib.lib_Flags |= LIBF_DELEXP; + + return NULL; +} +LIBFUNC_END + + +static LIBFUNC(Extfunclib, libbase, ULONG) +{ + (void) libbase; + d1(kprintf("%s/%s/%ld: libbase=%08lx\n", __FILE__, __FUNC__, __LINE__, libbase)); + return 0; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +static LIBFUNC(ObtainInfoEngine, libbase, ULONG) +{ + (void) libbase; + + return (ULONG) NewIconClass; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +// return 0 if error occurred +static ULONG InitDatatype(struct NewIconDtLibBase *dtLib) +{ + d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__)); + + dtLib->nib_Initialized = FALSE; + + return 1; +} + +// return 0 if error occurred +static ULONG OpenDatatype(struct NewIconDtLibBase *dtLib) +{ + d1(kprintf("%s/%s/%ld: OpenCnt=%ld\n", __FILE__, __FUNC__, __LINE__, dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt)); + + if (!dtLib->nib_Initialized) + { + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + dtLib->nib_Initialized = TRUE; + + InitSemaphore(&NewMemPoolSemaphore); + + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); + if (NULL == IntuitionBase) + return 0; + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + UtilityBase = (T_UTILITYBASE) OpenLibrary("utility.library", 39); + if (NULL == UtilityBase) + return 0; + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + GfxBase = (struct GfxBase *) OpenLibrary(GRAPHICSNAME, 39); + if (NULL == GfxBase) + return 0; + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + NewIconBase = (struct NewIconBase *) OpenLibrary("newicon.library", 37); + d1(kprintf("%s/%s/%ld: NewIconBase=%08lx\n", __FILE__, __FUNC__, __LINE__, NewIconBase)); + if (NULL == NewIconBase) + return 0; + + CyberGfxBase = OpenLibrary(CYBERGFXNAME, 0); + // CyberGfxBase may be NULL + + // we explicitely need to open our parent datatype - otherwise MakeClass() will fail! + IconObjectDTBase = OpenLibrary("datatypes/amigaiconobject.datatype", 39); + if (NULL == IconObjectDTBase) + return 0; + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + NewMemPool = CreatePool(MEMPOOL_MEMFLAGS, MEMPOOL_PUDDLESIZE, MEMPOOL_THRESHSIZE); + if (NULL == NewMemPool) + return 0; + + NewIconClass = dtLib->nib_ClassLibrary.cl_Class = MakeClass(libName, + "amigaiconobject.datatype", NULL, sizeof(struct InstanceData), 0); + d1(kprintf("%s/%s/%ld: NewIconClass=%08lx\n", __FILE__, __FUNC__, __LINE__, NewIconClass)); + if (NULL == NewIconClass) + return 0; + + NewIconClass->cl_Dispatcher.h_Entry = (HOOKFUNC) HookEntry; + NewIconClass->cl_Dispatcher.h_SubEntry = (HOOKFUNC) NewIconDispatcher; + NewIconClass->cl_Dispatcher.h_Data = dtLib; + + // Make class available for the public + AddClass(NewIconClass); + + ReadPrefs(dtLib); + } + + d1(kprintf("%s/%s/%ld: Open Success!\n", __FILE__, __FUNC__, __LINE__)); + + return 1; +} + + +static void CloseDatatype(struct NewIconDtLibBase *dtLib) +{ + d1(kprintf("%s/%s/%ld: OpenCnt=%ld\n", __FILE__, __FUNC__, __LINE__, dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt)); + + if (dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt < 1) + { + if (NewIconClass) + { + RemoveClass(NewIconClass); + FreeClass(NewIconClass); + NewIconClass = dtLib->nib_ClassLibrary.cl_Class = NULL; + } + + if (NULL != NewMemPool) + { + DeletePool(NewMemPool); + NewMemPool = NULL; + } + + if (NULL != PreferencesBase) + { + CloseLibrary(PreferencesBase); + PreferencesBase = NULL; + } + if (NULL != GfxBase) + { + CloseLibrary((struct Library *) GfxBase); + GfxBase = NULL; + } + if (NULL != IconObjectDTBase) + { + CloseLibrary(IconObjectDTBase); + IconObjectDTBase = NULL; + } + if (NULL != CyberGfxBase) + { + CloseLibrary(CyberGfxBase); + CyberGfxBase = NULL; + } + if (NULL != NewIconBase) + { + CloseLibrary(&NewIconBase->nib_Lib); + NewIconBase = NULL; + } + if (NULL != IntuitionBase) + { + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } + if (NULL != UtilityBase) + { + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } + } +} + +//----------------------------------------------------------------------------- + +void _XCEXIT(long x) +{ +} + +//---------------------------------------------------------------------------- + +static SAVEDS(ULONG) INTERRUPT NewIconDispatcher(Class *cl, Object *o, Msg msg) +{ + ULONG Result; + + switch (msg->MethodID) + { + case OM_NEW: + o = (Object *) DoSuperMethodA(cl, o, msg); + d1(kprintf("%s/%s/%ld: OM_NEW o=%08lx\n", __FILE__, __FUNC__, __LINE__, o)); + if (o) + { + d1(kprintf("%s/%s/%ld: OM_NEW o=%08lx\n", __FILE__, __FUNC__, __LINE__, o)); + if (!DtNew(cl, o, (struct opSet *) msg)) + { + DoMethod(o, OM_DISPOSE); + o = NULL; + } + } + Result = (ULONG) o; + break; + + case OM_DISPOSE: + Result = DtDispose(cl, o, msg); + break; + + case IDTM_Layout: + Result = DtLayout(cl, o, (struct iopLayout *) msg); + break; + + case IDTM_FreeLayout: + Result = DtFreeLayout(cl, o, (struct iopFreeLayout *) msg); + break; + + case IDTM_Write: + Result = DtWrite(cl, o, (struct iopWrite *) msg); + break; + + case IDTM_NewImage: + Result = DtNewImage(cl, o, (struct iopNewImage *) msg); + break; + + case IDTM_CloneIconObject: + Result = DtClone(cl, o, (struct iopCloneIconObject *) msg); + break; + + case OM_SET: + Result = DtSet(cl, o, (struct opSet *) msg); + break; + + case OM_GET: + Result = DtGet(cl, o, (struct opGet *) msg); + break; + + default: + Result = DoSuperMethodA(cl, o, msg); + break; + } + + return Result; +} + +//----------------------------------------------------------------------------- + +static BOOL DtNew(Class *cl, Object *o, struct opSet *ops) +{ + struct InstanceData *inst = INST_DATA(cl, o); +// struct ExtGadget *gg = (struct ExtGadget *) o; + BOOL Success = FALSE; + + do { + ULONG SupportedIconTypes; + ULONG DefIconType; + + memset(inst, 0, sizeof(struct InstanceData)); + + SupportedIconTypes = GetTagData(IDTA_SupportedIconTypes, ~0, ops->ops_AttrList); + if (!(SupportedIconTypes & IDTV_IconType_NewIcon)) + break; + + if (FindTagItem(IDTA_CloneIconObject, ops->ops_AttrList)) + { + } + else + { + DefIconType = GetTagData(IDTA_DefType, 0, ops->ops_AttrList); + d1(KPrintF("%s/%s/%ld: DefIconType=%ld\n", __FILE__, __FUNC__, __LINE__, DefIconType)); + if (DefIconType) + { + if (NewIconBase->nib_Lib.lib_Version < 40) + break; + + inst->nio_newicon = GetDefNewDiskObject(DefIconType); + if (NULL == inst->nio_newicon) + break; + } + else + { + CONST_STRPTR IconName; + + IconName = (CONST_STRPTR) GetTagData(DTA_Name, NULL, ops->ops_AttrList); + d1(KPrintF("%s/%s/%ld: IconName=<%s>\n", __FILE__, __FUNC__, __LINE__, IconName ? IconName : (STRPTR) "")); + if (NULL == IconName) + break; + + inst->nio_newicon = GetNewDiskObject((STRPTR) IconName); + if (NULL == inst->nio_newicon) + break; + } + + inst->nio_icon = inst->nio_newicon->ndo_StdObject; + inst->nio_normchunky.eci_Chunky = inst->nio_newicon->ndo_NormalImage; + inst->nio_selchunky.eci_Chunky = inst->nio_newicon->ndo_SelectedImage; + inst->nio_normchunky.eci_TransparentColor = inst->nio_selchunky.eci_TransparentColor = 0; + + d1(KPrintF("%s/%s/%ld: icon=%08lx normchunky=%08lx selchunky=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, inst->nio_icon, inst->nio_normchunky.eci_Chunky, inst->nio_selchunky.eci_Chunky)); + + if (inst->nio_normchunky.eci_Chunky) + { + SetAttrs(o, + GA_Width, inst->nio_normchunky.eci_Chunky->Width, + GA_Height, inst->nio_normchunky.eci_Chunky->Height, + IDTA_UnscaledWidth, inst->nio_normchunky.eci_Chunky->Width, + IDTA_UnscaledHeight, inst->nio_normchunky.eci_Chunky->Height, + TAG_END); + + d1(kprintf("%s/%s/%ld: nio_normchunky.eci_Chunky->Flags=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, inst->nio_normchunky.eci_Chunky->Flags)); + + GenerateMasks(cl, o); + } + } + + Success = TRUE; + } while (0); + + d1(kprintf("%s/%s/%ld: o=%08lx Success=%ld\n", __FILE__, __FUNC__, __LINE__, o, Success)); + + return Success; +} + +//----------------------------------------------------------------------------- + +static ULONG DtDispose(Class *cl, Object *o, Msg msg) +{ + struct InstanceData *inst = INST_DATA(cl, o); + struct iopFreeLayout opf; + + d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + d1(KPrintF("%s/%s/%ld: o=%08lx nio_DoNotFreeDiskObject=%ld\n", \ + __FILE__, __FUNC__, __LINE__, o, inst->nio_DoNotFreeDiskObject)); + + opf.MethodID = IDTM_FreeLayout; + opf.iopf_Flags = IOFREELAYOUTF_ScreenAvailable; + + DoFreeLayout(cl, o, &opf); + + FreeChunkyImage(&inst->nio_AllocNormChunky); + FreeChunkyImage(&inst->nio_AllocSelChunky); + + if (inst->nio_newicon) + { + FreeNewDiskObject(inst->nio_newicon); + inst->nio_newicon = NULL; + } +// else +// { +// if (!inst->nio_DoNotFreeDiskObject) +// newiconPrivate3(inst->nio_icon); +// } + + return DoSuperMethodA(cl, o, msg); +} + +//----------------------------------------------------------------------------- + +static ULONG DtSet(Class *cl, Object *o, struct opSet *ops) +{ + struct InstanceData *inst = INST_DATA(cl, o); + + inst->nio_DoNotFreeDiskObject = !GetTagData(IDTA_DoFreeDiskObject, + !inst->nio_DoNotFreeDiskObject, ops->ops_AttrList); + + d1(kprintf("%s/%s/%ld: o=%08lx nio_DoNotFreeDiskObject=%ld\n", \ + __FILE__, __FUNC__, __LINE__, o, inst->nio_DoNotFreeDiskObject)); + + return DoSuperMethodA(cl, o, (Msg) ops); +} + +//----------------------------------------------------------------------------- + +static ULONG DtGet(Class *cl, Object *o, struct opGet *opg) +{ + ULONG result = 1; + + switch (opg->opg_AttrID) + { + case IDTA_IconType: + *opg->opg_Storage = ioICONTYPE_NewIcon; + break; + + case IDTA_NumberOfColorsSupported: + *opg->opg_Storage = 256; + break; + + default: + result = DoSuperMethodA(cl, o, (Msg) opg); + break; + } + + return result; +} + +//----------------------------------------------------------------------------- + +static ULONG DtLayout(Class *cl, Object *o, struct iopLayout *opl) +{ + struct InstanceData *inst = INST_DATA(cl, o); + ULONG Result; + + d1(KPrintF("%s/%s/%ld: START o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + d1({ ULONG xxx; DoSuperMethod(cl, o, IDTA_Type, &xxx); }); + + // DoSuperSuperMethodA() + Result = DoSuperMethodA(cl->cl_Super, o, (Msg) opl); + + if (inst->nio_normchunky.eci_Chunky) + { + struct ExtGadget *gg = (struct ExtGadget *) o; + LONG LeftEdge; + LONG TopEdge; + + GetAttr(IDTA_InnerLeft, o, (ULONG *) &LeftEdge); + GetAttr(IDTA_InnerTop, o, (ULONG *) &TopEdge); + + d1(KPrintF("%s/%s/%ld: Left=%ld Top=%ld Flags=%08lx\n", __FILE__, __FUNC__, __LINE__, LeftEdge, TopEdge, opl->iopl_Flags)); + + if (gg->GadgetRender && (opl->iopl_Flags & IOLAYOUTF_NormalImage)) + { + struct RastPort *rp = (struct RastPort *) gg->GadgetRender; + + if (inst->nio_normimage) + { + DtDrawImage(LeftEdge, TopEdge, rp, inst->nio_normimage); + } + else + { + if (CyberGfxBase && 0 != GetCyberMapAttr(rp->BitMap, CYBRMATTR_ISCYBERGFX)) + { + inst->nio_imgscreen = opl->iopl_Screen; + inst->nio_normpens = DrawCyberImage(inst, LeftEdge, TopEdge, + rp, inst->nio_normchunky.eci_Chunky); + } + else + { + inst->nio_normimage = RemapChunkyImage(inst->nio_normchunky.eci_Chunky, opl->iopl_Screen); + DtDrawImage(LeftEdge, TopEdge, rp, inst->nio_normimage); + } + } + } + if (gg->SelectRender && (IOLAYOUTF_SelectedImage & opl->iopl_Flags)) + { + struct RastPort *rp = (struct RastPort *) gg->SelectRender; + + d1(KPrintF("%s/%s/%ld: nio_selimage=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->nio_selimage)); + + if (inst->nio_selimage) + { + DtDrawImage(LeftEdge, TopEdge, rp, inst->nio_selimage); + } + else + { + if (CyberGfxBase && 0 != GetCyberMapAttr(rp->BitMap, CYBRMATTR_ISCYBERGFX)) + { + d1(KPrintF("%s/%s/%ld: nio_selchunky.eci_Chunky=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->nio_selchunky.eci_Chunky)); + inst->nio_imgscreen = opl->iopl_Screen; + inst->nio_selpens = DrawCyberImage(inst, LeftEdge, TopEdge, rp, + inst->nio_selchunky.eci_Chunky ? inst->nio_selchunky.eci_Chunky : inst->nio_normchunky.eci_Chunky); + } + else + { + inst->nio_selimage = RemapChunkyImage(inst->nio_selchunky.eci_Chunky ? inst->nio_selchunky.eci_Chunky : inst->nio_normchunky.eci_Chunky, + opl->iopl_Screen); + DtDrawImage(LeftEdge, TopEdge, rp, inst->nio_selimage); + } + } + } + } + else + { + Result = DoSuperMethodA(cl, o, (Msg) opl); + } + + d1(KPrintF("%s/%s/%ld: END o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + d1({ ULONG xxx; DoSuperMethod(cl, o, IDTA_Type, &xxx); }); + + return Result; +} + +//----------------------------------------------------------------------------- + +static ULONG DtFreeLayout(Class *cl, Object *o, struct iopFreeLayout *opf) +{ + d1(KPrintF("%s/%s/%ld: START o=%08lx\n", __FILE__, __FUNC__, __LINE__, o)); + d1({ ULONG xxx; DoSuperMethod(cl, o, IDTA_Type, &xxx); }); + + DoFreeLayout(cl, o, opf); + + d1(KPrintF("%s/%s/%ld: o=%08lx \n", __FILE__, __FUNC__, __LINE__, o)); + d1({ ULONG xxx; DoSuperMethod(cl, o, IDTA_Type, &xxx); }); + + return DoSuperMethodA(cl, o, (Msg) opf); +} + +//----------------------------------------------------------------------------- + +static ULONG DtWrite(Class *cl, Object *o, struct iopWrite *opw) +{ + struct InstanceData *inst = INST_DATA(cl, o); + ULONG Result; + + d1(kprintf("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + + if (inst->nio_normchunky.eci_Chunky) + { + struct NewDiskObject SaveNewDiskObj; + UBYTE **ToolTypesClone; + UBYTE **OrigToolTypes; + const UBYTE **ToolTypes = NULL; + + SaveNewDiskObj.ndo_StdObject = inst->nio_newicon->ndo_StdObject; + SaveNewDiskObj.ndo_NormalImage = inst->nio_normchunky.eci_Chunky; + SaveNewDiskObj.ndo_SelectedImage = inst->nio_selchunky.eci_Chunky; + + GetAttr(IDTA_ToolTypes, o, (ULONG *) &ToolTypes); + ToolTypesClone = CloneToolTypes(ToolTypes); + + OrigToolTypes = inst->nio_icon->do_ToolTypes; + inst->nio_icon->do_ToolTypes = ToolTypesClone; + + SetAttrs(o, IDTA_ToolTypes, (ULONG) newiconPrivate2(&SaveNewDiskObj), TAG_END); + + Result = DoSuperMethodA(cl, o, (Msg) opw); + + // restore original ToolTypes + inst->nio_icon->do_ToolTypes = OrigToolTypes; + SetAttrs(o, IDTA_ToolTypes, (ULONG) ToolTypesClone, TAG_END); + + // free ToolType array clone + MyFreeVecPooled(ToolTypesClone); + } + else + { + Result = DoSuperMethodA(cl, o, (Msg) opw); + } + + return Result; +} + +//----------------------------------------------------------------------------- + +static ULONG DtNewImage(Class *cl, Object *o, struct iopNewImage *ioni) +{ + struct InstanceData *inst = INST_DATA(cl, o); + + do { + struct ExtChunkyImage *ci; + + if (NULL == ioni->ioni_NormalImage) + break; + + ci = ChunkyImageFromSAC(ioni->ioni_NormalImage); + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__, ci)); + if (NULL == ci) + break; + + if (inst->nio_normimage) + { + FreeRemappedImage(inst->nio_normimage, inst->nio_imgscreen); + inst->nio_normimage = NULL; + } + if (inst->nio_normpens) + { + ULONG n; + + for (n = 0; n < inst->nio_normchunky.eci_Chunky->NumColors; n++) + { + ReleasePen(inst->nio_imgscreen->ViewPort.ColorMap, inst->nio_normpens[n]); + } + + MyFreeVecPooled(inst->nio_normpens); + inst->nio_normpens = NULL; + } + + inst->nio_normchunky = *ci; + FreeChunkyImage(&inst->nio_AllocNormChunky); + inst->nio_AllocNormChunky = ci; + + if (ioni->ioni_SelectedImage) + { + ci = ChunkyImageFromSAC(ioni->ioni_SelectedImage); + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__, ci)); + if (NULL == ci) + break; + } + else + { + ci = NULL; + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + } + + if (inst->nio_selpens) + { + ULONG NumColors; + ULONG n; + + if (inst->nio_selchunky.eci_Chunky) + NumColors = inst->nio_selchunky.eci_Chunky->NumColors; + else + NumColors = inst->nio_normchunky.eci_Chunky->NumColors; + + for (n = 0; n < NumColors; n++) + { + ReleasePen(inst->nio_imgscreen->ViewPort.ColorMap, inst->nio_selpens[n]); + } + + MyFreeVecPooled(inst->nio_selpens); + inst->nio_selpens = NULL; + } + if (inst->nio_selimage) + { + FreeRemappedImage(inst->nio_selimage, inst->nio_imgscreen); + inst->nio_selimage = NULL; + } + + d1(KPrintF("%s/%s/%ld: ci=%08lx\n", __FILE__, __FUNC__, __LINE__, ci)); + if (ci) + inst->nio_selchunky = *ci; + else + memset(&inst->nio_selchunky, 0, sizeof(inst->nio_selchunky)); + + FreeChunkyImage(&inst->nio_AllocSelChunky); + inst->nio_AllocSelChunky = ci; + } while (0); + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + SetAttrs(o, + GA_Width, inst->nio_normchunky.eci_Chunky->Width, + GA_Height, inst->nio_normchunky.eci_Chunky->Height, + TAG_END); + + GenerateMasks(cl, o); + + d1(KPrintF("%s/%s/%ld: END o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + + return 0; +} + +//----------------------------------------------------------------------------- + +static void DoFreeLayout(Class *cl, Object *o, struct iopFreeLayout *opf) +{ + struct InstanceData *inst = INST_DATA(cl, o); + + d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx nio_normchunky.eci_Chunky=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst, inst->nio_normchunky.eci_Chunky)); + + if (inst->nio_normchunky.eci_Chunky) + { + struct Screen *RemapScreen; + + if (inst->nio_imgscreen && (opf->iopf_Flags & IOFREELAYOUTF_ScreenAvailable)) + RemapScreen = inst->nio_imgscreen; + else + RemapScreen = NULL; + + d1(kprintf("%s/%s/%ld: normpens=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->nio_normpens)); + + if (inst->nio_normpens) + { + if (RemapScreen) + { + ULONG n; + + d1(kprintf("%s/%s/%ld: normchunky.eci_Chunky=%08lx NumColors=%ld\n", \ + __FILE__, __FUNC__, __LINE__, inst->nio_normchunky.eci_Chunky, inst->nio_normchunky.eci_Chunky->NumColors)); + + for (n = 0; n < inst->nio_normchunky.eci_Chunky->NumColors; n++) + { + ReleasePen(inst->nio_imgscreen->ViewPort.ColorMap, inst->nio_normpens[n]); + } + } + + MyFreeVecPooled(inst->nio_normpens); + inst->nio_normpens = NULL; + } + if (inst->nio_selpens) + { + if (RemapScreen) + { + ULONG NumColors; + ULONG n; + + if (inst->nio_selchunky.eci_Chunky) + NumColors = inst->nio_selchunky.eci_Chunky->NumColors; + else + NumColors = inst->nio_normchunky.eci_Chunky->NumColors; + + for (n = 0; n < NumColors; n++) + { + ReleasePen(inst->nio_imgscreen->ViewPort.ColorMap, inst->nio_selpens[n]); + } + } + + MyFreeVecPooled(inst->nio_selpens); + inst->nio_selpens = NULL; + } + if (inst->nio_normimage) + { + FreeRemappedImage(inst->nio_normimage, RemapScreen); + inst->nio_normimage = NULL; + } + if (inst->nio_selimage) + { + FreeRemappedImage(inst->nio_selimage, RemapScreen); + inst->nio_selimage = NULL; + } + } + d1(KPrintF("%s/%s/%ld: END o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); +} + +//----------------------------------------------------------------------------- + +static ULONG DtClone(Class *cl, Object *o, struct iopCloneIconObject *iocio) +{ + //struct InstanceData *inst = INST_DATA(cl, o); + + d1(KPrintF("%s/%ld: START o=%08lx inst=%08lx\n", __FUNC__, __LINE__, o, inst)); + + d1(KPrintF("%s/%ld: END o=%08lx inst=%08lx\n", __FUNC__, __LINE__, o, inst)); + + return 0; +} + +//----------------------------------------------------------------------------- + +static void ReadPrefs(struct NewIconDtLibBase *dtLib) +{ + APTR PrefsHandle = NULL; + + // set default values for preferences settings + dtLib->nib_NewIconsTransparent = TRUE; + dtLib->nib_NewIconsPrecision = 4; + + do { + PreferencesBase = OpenLibrary("preferences.library", 39); + if (NULL == PreferencesBase) + break; + + PrefsHandle = AllocPrefsHandle("Scalos"); + if (NULL == PrefsHandle) + break; + ReadPrefsHandle(PrefsHandle, "ENV:Scalos/Scalos.prefs"); + + GetPreferences(PrefsHandle, MAKE_ID('M','A','I','N'), SCP_NewIconsTransparent, + &dtLib->nib_NewIconsTransparent, sizeof(dtLib->nib_NewIconsTransparent)); + GetPreferences(PrefsHandle, MAKE_ID('M','A','I','N'), SCP_NewIconsPrecision, + &dtLib->nib_NewIconsPrecision, sizeof(dtLib->nib_NewIconsPrecision)); + + d1(kprintf("%s/%s/%ld: Transparent=%ld Precision=%ld\n", \ + __FILE__, __FUNC__, __LINE__, dtLib->nib_NewIconsTransparent, dtLib->nib_NewIconsPrecision)); + } while (0); + + if (PrefsHandle) + FreePrefsHandle(PrefsHandle); + if (PreferencesBase) + { + CloseLibrary(PreferencesBase); + PreferencesBase = NULL; + } +} + +//----------------------------------------------------------------------------- + +static UBYTE **CloneToolTypes(const UBYTE **OrigToolTypes) +{ + const UBYTE **TTPtr; + UBYTE **TTClone; + size_t AllocLen = sizeof(UBYTE *); + size_t StringCount = 1; + + d1(kprintf("%s/%s/%ld: OrigToolTypes=%08lx\n", __FILE__, __FUNC__, __LINE__, OrigToolTypes)); + + for (TTPtr = OrigToolTypes; *TTPtr; TTPtr++) + { + d1(kprintf("%s/%s/%ld: *TTPtr=<%s>\n", __FILE__, __FUNC__, __LINE__, *TTPtr)); + StringCount++; + AllocLen += sizeof(UBYTE *) + 1 + strlen(*TTPtr); + } + + d1(kprintf("%s/%s/%ld: StringCount=%lu AllocLen=%lu\n", __FILE__, __FUNC__, __LINE__, StringCount, AllocLen)); + + TTClone = MyAllocVecPooled(AllocLen); + if (TTClone) + { + UBYTE **TTDestPtr; + UBYTE *StringSpace; + + StringSpace = ((UBYTE *) TTClone) + StringCount * sizeof(UBYTE *); + TTPtr = OrigToolTypes; + TTDestPtr = TTClone; + + while (*TTPtr) + { + *TTDestPtr = StringSpace; + strcpy(*TTDestPtr, *TTPtr); + + StringSpace += 1 + strlen(*TTPtr); + TTDestPtr++; + TTPtr++; + } + *TTDestPtr = NULL; + } + + d1(kprintf("%s/%s/%ld: TTClone=%08lx\n", __FILE__, __FUNC__, __LINE__, TTClone)); + + return TTClone; +} + +//----------------------------------------------------------------------------- + +static UBYTE *GenerateMask(struct ExtChunkyImage *eci) +{ + ULONG Size; + UBYTE *MaskArray; + ULONG BytesPerRow; + + d1(KPrintF("%s/%s/%ld: START eci=%08lx\n", __FILE__, __FUNC__, __LINE__, eci)); + d1(KPrintF("%s/%s/%ld: eci_Chunky=%08lx\n", __FILE__, __FUNC__, __LINE__, eci->eci_Chunky)); + + BytesPerRow = ((eci->eci_Chunky->Width + 15) & 0xfff0) >> 3; + Size = eci->eci_Chunky->Height * BytesPerRow; + MaskArray = MyAllocVecPooled(Size); + d1(KPrintF("%s/%s/%ld: MaskArray=%08lx\n", __FILE__, __FUNC__, __LINE__, MaskArray)); + if (MaskArray) + { + const UBYTE *ChunkyData = eci->eci_Chunky->ChunkyData; + UBYTE *MaskPtr = MaskArray; + ULONG y; + + d1(KPrintF("%s/%s/%ld: ChunkyDat=%08lx\n", __FILE__, __FUNC__, __LINE__, eci->eci_Chunky->ChunkyData)); + memset(MaskArray, 0, Size); + + for (y = 0; y < eci->eci_Chunky->Height; y++) + { + ULONG x; + UBYTE BitMask = 0x80; + UBYTE *MaskPtr2 = MaskPtr; + + for (x = 0; x < eci->eci_Chunky->Width; x++) + { + if (*ChunkyData++ != eci->eci_TransparentColor) + *MaskPtr2 |= BitMask; + BitMask >>= 1; + if (0 == BitMask) + { + BitMask = 0x80; + MaskPtr2++; + } + } + + MaskPtr += BytesPerRow; + } + } + + d1(KPrintF("%s/%s/%ld: END eci=%08lx MaskArray=%08lx\n", __FILE__, __FUNC__, __LINE__, eci, MaskArray)); + + return MaskArray; +} + +//----------------------------------------------------------------------------- + +static void DtDrawImage(LONG LeftEdge, LONG TopEdge, struct RastPort *rp, struct Image *img) +{ + DrawImage(rp, img, LeftEdge, TopEdge); +} + +//----------------------------------------------------------------------------- + +static UBYTE *DrawCyberImage(struct InstanceData *inst, LONG LeftEdge, LONG TopEdge, + struct RastPort *rp, struct ChunkyImage *cki) +{ + UBYTE *PenArray = NULL; + ULONG BmDepth; + ULONG ImgSize; + ULONG n; + UBYTE *PalettePtr; + const UBYTE *ImgSrcPtr; + ULONG BmWidth, BmHeight; + ULONG Width, Height; + + BmWidth = GetBitMapAttr(rp->BitMap, BMA_WIDTH); + BmHeight = GetBitMapAttr(rp->BitMap, BMA_HEIGHT); + + Width = min(cki->Width, BmWidth - LeftEdge); + Height = min(cki->Height, BmHeight - TopEdge); + + ImgSize = cki->Width * cki->Height; + + BmDepth = GetBitMapAttr(rp->BitMap, BMA_DEPTH); + + d1(KPrintF("%s/%s/%ld: inst=%08lx Left=%ld Top=%ld Size=%lu Depth=%ld\n", \ + __FILE__, __FUNC__, __LINE__, inst, LeftEdge, TopEdge, ImgSize, BmDepth)); + d1(kprintf("%s/%s/%ld: Width=%lu Height=%lu\n", __FILE__, __FUNC__, __LINE__, cki->Width, cki->Height)); + + if (BmDepth > 8) + { + // True color + struct ARGB *ARGBArray = NULL; + struct ARGB *ARGBImgArray; + struct ARGB *ARGBPtr; + struct ARGB *ARGBImgDestPtr; + + do { + ARGBImgArray = MyAllocVecPooled(ImgSize * sizeof(struct ARGB)); + d1(kprintf("%s/%s/%ld: ARGBImgArray=%08lx\n", __FILE__, __FUNC__, __LINE__, ARGBImgArray)); + if (NULL == ARGBImgArray) + break; + + ARGBArray = MyAllocVecPooled(cki->NumColors * sizeof(struct ARGB)); + d1(kprintf("%s/%s/%ld: ARGBArray=%08lx\n", __FILE__, __FUNC__, __LINE__, ARGBArray)); + if (NULL == ARGBArray) + break; + + PalettePtr = cki->Palette; + ARGBPtr = ARGBArray; + for (n = 0; n < cki->NumColors; n++, ARGBPtr++) + { + ARGBPtr->Alpha = 0; + ARGBPtr->Red = *PalettePtr++; + ARGBPtr->Green = *PalettePtr++; + ARGBPtr->Blue = *PalettePtr++; + } + + ImgSrcPtr = cki->ChunkyData; + ARGBImgDestPtr = ARGBImgArray; + for (n = 0; n < ImgSize; n++) + { + *ARGBImgDestPtr++ = ARGBArray[*ImgSrcPtr++]; + } + + d1(kprintf("%s/%s/%ld: ARGBImgArray=%08lx\n", __FILE__, __FUNC__, __LINE__, ARGBImgArray)); + + WriteARGBArray(ARGBImgArray, 0, 0, + cki->Width * sizeof(struct ARGB), + rp, LeftEdge, TopEdge, + Width, Height); + } while (0); + + if (ARGBArray) + MyFreeVecPooled(ARGBArray); + if (ARGBImgArray) + MyFreeVecPooled(ARGBImgArray); + } + else + { + UBYTE *ImgArray; + UBYTE *PenArrayPtr; + UBYTE *ImgDestPtr; + + do { + ImgArray = MyAllocVecPooled(ImgSize); + d1(kprintf("%s/%s/%ld: ImgArray=%08lx\n", __FILE__, __FUNC__, __LINE__, ImgArray)); + if (NULL == ImgArray) + break; + + PenArray = MyAllocVecPooled(cki->NumColors); + if (NULL == PenArray) + break; + + PalettePtr = cki->Palette; + PenArrayPtr = PenArray; + for (n = 0; n < cki->NumColors; n++, PalettePtr += 3) + { + *PenArrayPtr++ = ObtainBestPen(inst->nio_imgscreen->ViewPort.ColorMap, + PalettePtr[0] << 24, + PalettePtr[1] << 24, + PalettePtr[2] << 24, + OBP_Precision, NewIconBase->nib_Precision, + TAG_END); + } + + ImgSrcPtr = cki->ChunkyData; + ImgDestPtr = ImgArray; + for (n = 0; n < ImgSize; n++) + { + *ImgDestPtr++ = PenArray[*ImgSrcPtr++]; + } + + WritePixelArray(ImgArray, 0, 0, cki->Width, + rp, LeftEdge, TopEdge, + Width, Height, + RECTFMT_LUT8); + } while (0); + + if (ImgArray) + MyFreeVecPooled(ImgArray); + } + + + return PenArray; +} + +//----------------------------------------------------------------------------- + +static APTR MyAllocVecPooled(size_t Size) +{ + APTR ptr; + + if (NewMemPool) + { + ObtainSemaphore(&NewMemPoolSemaphore); + ptr = AllocPooled(NewMemPool, Size + sizeof(size_t)); + ReleaseSemaphore(&NewMemPoolSemaphore); + if (ptr) + { + size_t *sptr = (size_t *) ptr; + + sptr[0] = Size; + + d1(KPrintF("%s/%s/%ld: MemPool=%08lx Size=%lu mem=%08lx\n", __FILE__, __FUNC__, __LINE__, NewMemPool, Size, &sptr[1])); + return (APTR)(&sptr[1]); + } + } + + d1(KPrintF("%s/%s/%ld: MemPool=%08lx Size=%lu\n", __FILE__, __FUNC__, __LINE__, NewMemPool, Size)); + + return NULL; +} + + +static void MyFreeVecPooled(APTR mem) +{ + d1(KPrintF("%s/%s/%ld: MemPool=%08lx mem=%08lx\n", __FILE__, __FUNC__, __LINE__, NewMemPool, mem)); + if (NewMemPool && mem) + { + size_t size; + size_t *sptr = (size_t *) mem; + + mem = &sptr[-1]; + size = sptr[-1]; + + ObtainSemaphore(&NewMemPoolSemaphore); + FreePooled(NewMemPool, mem, size + sizeof(size_t)); + ReleaseSemaphore(&NewMemPoolSemaphore); + } +} + +//---------------------------------------------------------------------------------------- + +static void WriteARGBArray(const struct ARGB *SrcImgData, + ULONG SrcX, ULONG SrcY, ULONG SrcBytesPerRow, + struct RastPort *DestRp, ULONG DestX, ULONG DestY, + ULONG SizeX, ULONG SizeY) +{ + struct BitMap *DestBM = DestRp->BitMap; + ULONG DestWidth; + ULONG DestHeight; + + DestWidth = GetCyberMapAttr(DestBM, CYBRMATTR_WIDTH); + DestHeight = GetCyberMapAttr(DestBM, CYBRMATTR_HEIGHT); + + d1(KPrintF("%s/%s/%ld: DestX=%ld DestY=%ld SizeX=%ld SizeY=%ld\n", __FILE__, __FUNC__, __LINE__, DestX, DestY, SizeX, SizeY)); + d1(KPrintF("%s/%s/%ld: SrcBytesPerRow=%ld\n", __FILE__, __FUNC__, __LINE__, SrcBytesPerRow, DestPixelFormat)); + + if (DestX + SizeX > DestWidth) + SizeX = DestWidth - DestX; + if (DestY + SizeY > DestHeight) + SizeY = DestHeight - DestY; + + d1(KPrintF("%s/%s/%ld: DestX=%ld DestY=%ld SizeX=%ld SizeY=%ld\n", __FILE__, __FUNC__, __LINE__, DestX, DestY, SizeX, SizeY)); + + WritePixelArray((APTR) SrcImgData, SrcX, SrcY, + SrcBytesPerRow, + DestRp, DestX, DestY, + SizeX, SizeY, + RECTFMT_ARGB); +} + +//---------------------------------------------------------------------------------------- + +static struct ExtChunkyImage *ChunkyImageFromSAC(struct ScalosBitMapAndColor *sac) +{ + struct ExtChunkyImage *ci = NULL; + struct BitMap *TempBM; + BOOL Success = FALSE; + + do { + ULONG n; + ULONG y; + const ULONG *PaletteSrcPtr; + UBYTE *PaletteDestPtr; + struct RastPort rp; + struct RastPort TempRp; + UBYTE *ImagePtr; + ULONG NewWidth = sac->sac_Width; + ULONG NewHeight = sac->sac_Height; + + InitRastPort(&rp); + InitRastPort(&TempRp); + + rp.BitMap = sac->sac_BitMap; + d1(KPrintF(__FILE__ "/" "%s/%s/%ld: rp.BitMap=%08lx\n", __FILE__, __FUNC__, __LINE__, rp.BitMap)); + + // setup temp. RastPort for use by WritePixelLine8() + TempRp.Layer = NULL; + TempRp.BitMap = TempBM = AllocBitMap(TEMPRP_WIDTH(NewWidth), 1, 8, 0, NULL); + + if (NULL == TempBM) + break; + ci = MyAllocVecPooled(sizeof(struct ExtChunkyImage) + sizeof(struct ChunkyImage)); + if (NULL == ci) + break; + + memset(ci, 0, sizeof(struct ExtChunkyImage)); + ci->eci_Chunky = (struct ChunkyImage *) (ci + 1); + memset(ci->eci_Chunky, 0, sizeof(struct ChunkyImage)); + + if (SAC_TRANSPARENT_NONE != sac->sac_TransparentColor) + ci->eci_Chunky->Flags |= CIF_COLOR_0_TRANSP; + + ci->eci_Chunky->Width = NewWidth; + ci->eci_Chunky->Height = NewHeight; + + ci->eci_Chunky->ChunkyData = MyAllocVecPooled(PIXELARRAY8_BUFFERSIZE(ci->eci_Chunky->Width, ci->eci_Chunky->Height)); + if (NULL == ci->eci_Chunky->ChunkyData) + break; + + ci->eci_Chunky->NumColors = sac->sac_NumColors; + ci->eci_Chunky->Palette = MyAllocVecPooled(sac->sac_NumColors * 3); + if (NULL == ci->eci_Chunky->Palette) + break; + + ci->eci_TransparentColor = sac->sac_TransparentColor; + + // nothing can go wrong from here on + Success = TRUE; + + d1(KPrintF("%s/%s/%ld: NumColors=%lu\n", __FILE__, __FUNC__, __LINE__, sac->sac_NumColors)); + + // Fill nim_Palette fom sac_ColorTable + for (n = 0, PaletteSrcPtr = sac->sac_ColorTable, PaletteDestPtr = ci->eci_Chunky->Palette; + n < sac->sac_NumColors; n++) + { + *PaletteDestPtr++ = *PaletteSrcPtr++ >> 24; // red + *PaletteDestPtr++ = *PaletteSrcPtr++ >> 24; // green + *PaletteDestPtr++ = *PaletteSrcPtr++ >> 24; // blue + } + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + // copy image data from sac_BitMap into nim_ImageData + for (y = 0, ImagePtr = ci->eci_Chunky->ChunkyData; y < NewHeight; y++) + { + d1(KPrintF("%s/%s/%ld: y=%ld\n", __FILE__, __FUNC__, __LINE__, y)); + ReadPixelLine8(&rp, 0, y, NewWidth, + ImagePtr, &TempRp); + ImagePtr += NewWidth; + } + + d1(KPrintF("%s/%s/%ld: ci=%08lx eci_Chunky=%08lx\n", __FILE__, __FUNC__, __LINE__, ci, ci->eci_Chunky)); + } while (0); + + if (!Success) + FreeChunkyImage(&ci); + + if (TempBM) + FreeBitMap(TempBM); + + return ci; +} + +//---------------------------------------------------------------------------------------- + +static void FreeChunkyImage(struct ExtChunkyImage **ci) +{ + if (*ci && (*ci)->eci_Chunky) + { + if ((*ci)->eci_Chunky->Palette) + { + MyFreeVecPooled((*ci)->eci_Chunky->Palette); + (*ci)->eci_Chunky->Palette = NULL; + } + if ((*ci)->eci_Chunky->ChunkyData) + { + MyFreeVecPooled((*ci)->eci_Chunky->ChunkyData); + (*ci)->eci_Chunky->ChunkyData = NULL; + } + MyFreeVecPooled(*ci); + *ci = NULL; + } +} + +//---------------------------------------------------------------------------------------- + +static void GenerateMasks(Class *cl, Object *o) +{ + struct InstanceData *inst = INST_DATA(cl, o); + UBYTE *MaskNormal = NULL; + UBYTE *MaskSelected = NULL; + UBYTE *AllocMaskNormal = NULL; + UBYTE *AllocMaskSelected = NULL; + + d1(KPrintF("%s/%s/%ld: START o=%08lx\n", __FILE__, __FUNC__, __LINE__, o)); + + if (inst->nio_normchunky.eci_Chunky->Flags & CIF_COLOR_0_TRANSP) + { + d1(KPrintF("%s/%s/%ld: Generate Normal Mask\n", __FILE__, __FUNC__, __LINE__)); + MaskNormal = MaskSelected = AllocMaskNormal= GenerateMask(&inst->nio_normchunky); + if (inst->nio_selchunky.eci_Chunky) + { + d1(KPrintF("%s/%s/%ld: Generate Selected Mask\n", __FILE__, __FUNC__, __LINE__)); + MaskSelected = AllocMaskSelected = GenerateMask(&inst->nio_selchunky); + } + } + + d1(KPrintF("%s/%s/%ld: MaskNormal=%08lx MaskSelected=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, MaskNormal, MaskSelected)); + + SetAttrs(o, IDTA_Mask_Normal, (ULONG) MaskNormal, + IDTA_Mask_Selected, (ULONG) MaskSelected, + IDTA_Width_Mask_Normal, inst->nio_normchunky.eci_Chunky->Width, + IDTA_Height_Mask_Normal, inst->nio_normchunky.eci_Chunky->Height, + IDTA_Width_Mask_Selected, inst->nio_selchunky.eci_Chunky + ? inst->nio_selchunky.eci_Chunky->Width : inst->nio_normchunky.eci_Chunky->Width, + IDTA_Height_Mask_Selected, inst->nio_selchunky.eci_Chunky + ? inst->nio_selchunky.eci_Chunky->Height : inst->nio_normchunky.eci_Chunky->Height, + TAG_END); + + d1(KPrintF("%s/%s/%ld: MaskNormel=%08lx MaskSelected=%08lx\n", __FILE__, __FUNC__, __LINE__, MaskNormal, MaskSelected)); + + if (AllocMaskNormal) + MyFreeVecPooled(AllocMaskNormal); + if (AllocMaskSelected) + MyFreeVecPooled(AllocMaskSelected); + + d1(KPrintF("%s/%s/%ld: END o=%08lx\n", __FILE__, __FUNC__, __LINE__, o)); +} + +//---------------------------------------------------------------------------------------- + diff --git a/scalos/datatypes/NewIcons/NewIconDt.h b/scalos/datatypes/NewIcons/NewIconDt.h new file mode 100644 index 000000000..df64f5d8c --- /dev/null +++ b/scalos/datatypes/NewIcons/NewIconDt.h @@ -0,0 +1,84 @@ +// NewIconDt.h +// $Date$ +// $Revision$ + + +#ifndef NEWICONDT_H +#define NEWICONDT_H + +//----------------------------------------------------------------------------- + +#include +#include + +//----------------------------------------------------------------------------- + +#define MEMPOOL_MEMFLAGS MEMF_PUBLIC +#define MEMPOOL_PUDDLESIZE 16384 +#define MEMPOOL_THRESHSIZE 16384 + +//----------------------------------------------------------------------------- + +struct NewIconDtLibBase + { + struct ClassLibrary nib_ClassLibrary; + + struct SegList *nib_SegList; + + UBYTE nib_Initialized; + UBYTE nib_NewIconsTransparent; + ULONG nib_NewIconsPrecision; + }; + +//----------------------------------------------------------------------------- + +struct ExtChunkyImage +{ + struct ChunkyImage *eci_Chunky; // original ChunkyImage + ULONG eci_TransparentColor; // Index of transparent color - always 0 for standard newicons +}; + +//----------------------------------------------------------------------------- + +struct InstanceData + { + struct DiskObject *nio_icon; + + struct ExtChunkyImage nio_normchunky; + struct ExtChunkyImage nio_selchunky; + + struct ExtChunkyImage *nio_AllocNormChunky; // optional self-allocated normal ChunkyImage + struct ExtChunkyImage *nio_AllocSelChunky; // optional self-allocated selected ChunkyImage + + struct Image *nio_normimage; // Remapped normal image + struct Image *nio_selimage; // Remapped selected image + + struct Screen *nio_imgscreen; + + UBYTE *nio_normpens; // Pen array for remapped normal image + UBYTE *nio_selpens; // Pen array for remapped selected image + + struct NewDiskObject *nio_newicon; + + BOOL nio_DoNotFreeDiskObject; + }; + +//----------------------------------------------------------------------------- + +#define Sizeof(array) (sizeof(array) / sizeof((array)[0])) + +// Width for TempRp.BitMap for ReadPixelLine8() and WritePixelLine8() +#define TEMPRP_WIDTH(width) (8 * ((((width) + 15) >> 4) << 1)) + +//----------------------------------------------------------------------------- + +#define d1(x) ; +#define d2(x) { Forbid(); x; Permit(); } + +// from debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +//----------------------------------------------------------------------------- + +#endif /* NEWICONDT_H */ diff --git a/scalos/datatypes/NewIcons/config.mk b/scalos/datatypes/NewIcons/config.mk new file mode 100755 index 000000000..9d7272ab9 --- /dev/null +++ b/scalos/datatypes/NewIcons/config.mk @@ -0,0 +1,33 @@ +# $Date: 2010-04-14 18:00:07 +0200 (Mi, 14. Apr 2010) $ +# $Revision: 563 $ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +MKDIR = mkdir -p #makedir force +DT_DIR = scalos:IconDatatypes/datatypes + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += -nostartfiles \ + -lmempools \ +# --verbose + + +else + +############################################################################### +# AmigaOS + +LFLAGS += -ldebug -lamiga -lpreferences -lcybergraphics -lnix + +endif diff --git a/scalos/datatypes/NewIcons/makefile b/scalos/datatypes/NewIcons/makefile new file mode 100644 index 000000000..0322b43f1 --- /dev/null +++ b/scalos/datatypes/NewIcons/makefile @@ -0,0 +1,97 @@ +# makefile für Scalos IconObject datatypes stuff +# $Date$ +# $Revision$ +##################################################################### + +CSRCS = NewIconDt.c +ASRCS = #newiconobject.asm + +##################################################################### + +AS = phxAss +LD = slink +CC = sc +MKDIR = mkdir -p #makedir force +LIBS = LIB:debug.lib LIB:sc.lib LIB:amiga.lib +PRECOMP = Include:all.gst +DT_DIR = scalos:IconDatatypes/datatypes +OBJDIR = .sasobj + +.SUFFIXES: .asm + +##################################################################### + +CFLAGS = optimize nostackcheck nochkabort strcons debug=s \ + strmer nover streq idir=sc:include/ idir=include: idir=//include +LNFLAGS = batch noicons stripdebug quiet +LNDBFLAGS = batch noicons addsym quiet + +ifdef L +AFLAGS = QUIET DS NOEXE opt=NRQB LIST=* linedebug I=SC:Assembler_Headers +else +AFLAGS = QUIET DS NOEXE opt=NRQB linedebug I=SC:Assembler_Headers +endif + +##################################################################### + +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(CSRCS:%.c=$(OBJDIR)/%.o) + +##################################################################### + +DTNAME = .bin_os3/newiconobject.datatype +DTDBGNAME = $(DTNAME).debug + +##################################################################### + +all: $(DTNAME) \ + $(DTDBGNAME) + +##################################################################### + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +##################################################################### + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $< objectname $@ + +$(OBJDIR)/%.o : %.s + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +$(OBJDIR)/%.o : %.asm + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +##################################################################### + +$(OBJDIR)/NewIconDt.o : NewIconDt.h + +##################################################################### + +$(DTNAME) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) from $(OBJS) to $(DTNAME) LIB $(LIBS) $(LNFLAGS) + +$(DTDBGNAME) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) from $(OBJS) to $(DTDBGNAME) LIB $(LIBS) $(LNDBFLAGS) + +##################################################################### + +install: + @printf '\033[32mFlushing memory...\033[0m\n' + avail flush + @printf '\033[32mInstall: \033[31m\033[1m$(DTNAME)\033[0m\n' + -@$(MKDIR) $(DT_DIR) + copy $(DTNAME) $(DT_DIR) + +##################################################################### + +clean: + -@delete $(DTNAME) $(DTDBGNAME) $(OBJS) + +##################################################################### + diff --git a/scalos/datatypes/NewIcons/makefile-new b/scalos/datatypes/NewIcons/makefile-new new file mode 100755 index 000000000..98a9d8116 --- /dev/null +++ b/scalos/datatypes/NewIcons/makefile-new @@ -0,0 +1,66 @@ +# $Date: 2010-05-02 20:34:59 +0200 (So, 02. Mai 2010) $ +# $Revision: 599 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(OBJDIR)/NewIconDt.o + + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Targets +# + +NAME = newiconobject.datatype +NAME_DB = newiconobject.datatype.debug + +############################################################################## + +.PHONY: all install clean bump dump + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + $(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @protect $@ +e + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + -@$(MKDIR) $(DT_DIR) + @copy $(BINDIR)/$(NAME) $(DT_DIR) + @avail flush + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* + +############################################################################## diff --git a/scalos/datatypes/NewIcons/newiconobject.dt b/scalos/datatypes/NewIcons/newiconobject.dt new file mode 100644 index 000000000..b81bec17d --- /dev/null +++ b/scalos/datatypes/NewIcons/newiconobject.dt @@ -0,0 +1,6 @@ +# DataType file for Amiga-NewIconObjects +Filename=newiconobject +DTName=NewIconObject,newiconobject +ID=icon,newi +Recog=#?.info +Flags=Binary,n,0 diff --git a/scalos/datatypes/PNGIcons/GetPNGPicture.c b/scalos/datatypes/PNGIcons/GetPNGPicture.c new file mode 100644 index 000000000..fd2099ee8 --- /dev/null +++ b/scalos/datatypes/PNGIcons/GetPNGPicture.c @@ -0,0 +1,227 @@ +// GetPNGPicture.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "png.h" +#include +#include "PNGIconDt.h" +#include "PNGIconProto.h" + +//----------------------------------------------------------------------------- + +static png_voidp PngAllocMem(png_structp png_ptr, png_size_t size); +static void PngFreeMem(png_structp png_ptr, png_voidp ptr); +static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length); +static int read_chunk_callback(png_structp png_ptr, png_unknown_chunkp chunk); +static void PngError(png_structp png_ptr, png_const_charp error_message); +static void PngWarning(png_structp png_ptr, png_const_charp warning_message); + +//----------------------------------------------------------------------------- + +// Given a PNG file buffer decompress the image data and returns an ARGB image array. +// Width and height are filled in with the image dimensions. +// Only 24bit image formats (with or without alpha channel) are supported by choice. +// Since the output buffer is intended for usage with ARGB alpha blit functions, +// if no alpha is present it will be filled with 255. + + +BOOL GetPngPicture(struct InstanceData *inst, BPTR file, + ULONG SigBytesRead, struct ARGBHeader *argbh) +{ + png_structp png_ptr = NULL; + png_infop info_ptr = NULL; + BOOL success = FALSE; + + + d1(KPrintF("%s/%s/%ld: inst=%08lx file=%08lx SigBytesRead=%lu\n", __FILE__, __FUNC__, __LINE__, inst, file, SigBytesRead)); + + do { + png_bytepp row_pointers; + png_uint_32 width, height; + int bit_depth, color_type, interlace_type; + struct ARGB *argb; + ULONG BytesPerRow; + ULONG y; + + png_ptr = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, + (png_voidp) inst, PngError, PngWarning, NULL, PngAllocMem, PngFreeMem); + + d1(KPrintF("%s/%s/%ld: png_ptr=%08lx\n", __FILE__, __FUNC__, __LINE__, png_ptr)); + if (NULL == png_ptr) + break; + + /* Allocate/initialize the memory for image information. REQUIRED. */ + info_ptr = png_create_info_struct(png_ptr); + d1(KPrintF("%s/%s/%ld: info_ptr=%08lx\n", __FILE__, __FUNC__, __LINE__, info_ptr)); + if (NULL == info_ptr) + break; + + d1(KPrintF("%s/%s/%ld: png_ptr=%08lx\n", __FILE__, __FUNC__, __LINE__, png_ptr)); + d1(KPrintF("%s/%s/%ld: sizeof(jmp_buf)=%lu png_jmpbuf=%08lx\n", __FILE__, __FUNC__, __LINE__, sizeof(jmp_buf), png_jmpbuf(png_ptr))); + // safety check against jmp_buf size mismatch between libpng and Scalos + if (NULL == png_jmpbuf(png_ptr)) + break; + + if (setjmp(png_jmpbuf(png_ptr))) + { + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + success = FALSE; + break; + } + + d1(KPrintF("%s/%s/%ld: png_ptr=%08lx\n", __FILE__, __FUNC__, __LINE__, png_ptr)); + + png_set_read_fn(png_ptr, (void *) file, user_read_data); + + png_set_sig_bytes(png_ptr, SigBytesRead); + + png_set_read_user_chunk_fn(png_ptr, inst, read_chunk_callback); + + png_set_keep_unknown_chunks(png_ptr, + PNG_HANDLE_CHUNK_IF_SAFE, NULL, 0); + + png_set_palette_to_rgb(png_ptr); + png_set_expand_gray_1_2_4_to_8(png_ptr); + png_set_tRNS_to_alpha(png_ptr); + png_set_gray_to_rgb(png_ptr); + png_set_add_alpha(png_ptr, ~0, PNG_FILLER_BEFORE); + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + png_read_png(png_ptr, info_ptr, + PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING + | PNG_TRANSFORM_SWAP_ALPHA | PNG_TRANSFORM_EXPAND, NULL); + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + png_get_IHDR(png_ptr, info_ptr, + &width, &height, &bit_depth, &color_type, + &interlace_type, NULL, NULL); + + d1(KPrintF("%s/%s/%ld: width=%ld height=%ld depth=%ld color_type=%ld\n", __FILE__, __FUNC__, __LINE__, width, height, bit_depth, color_type)); + + row_pointers = png_get_rows(png_ptr, info_ptr); + d1(KPrintF("%s/%s/%ld: row_pointers=%08lx\n", __FILE__, __FUNC__, __LINE__, row_pointers)); + if (NULL == row_pointers) + break; + + argbh->argb_Width = width; + argbh->argb_Height = height; + argbh->argb_ImageData = MyAllocVecPooled(width * height * sizeof(struct ARGB)); + + d1(KPrintF("%s/%s/%ld: argb_ImageData=%08lx\n", __FILE__, __FUNC__, __LINE__, argbh->argb_ImageData)); + if (NULL == argbh->argb_ImageData) + break; + + d1(KPrintF("%s/%s/%ld: width=%ld height=%ld depth=%ld color_type=%ld\n", __FILE__, __FUNC__, __LINE__, width, height, bit_depth, color_type)); + + BytesPerRow = png_get_rowbytes(png_ptr, info_ptr); + + d1(KPrintF("%s/%s/%ld: BytesPerRow=%lu\n", __FILE__, __FUNC__, __LINE__, BytesPerRow)); + + argb = argbh->argb_ImageData; + for (y = 0; y < height; y++) + { + memcpy(argb, row_pointers[y], BytesPerRow); + argb += width; + } + + success = TRUE; + } while (0); + + d1(KPrintF("%s/%s/%ld: success=%ld\n", __FILE__, __FUNC__, __LINE__, success)); + + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + + return success; +} + + +static png_voidp PngAllocMem(png_structp png_ptr, png_size_t size) +{ + (void) png_ptr; + + return MyAllocVecPooled(size); +} + +static void PngFreeMem(png_structp png_ptr, png_voidp ptr) +{ + (void) png_ptr; + MyFreeVecPooled(ptr); +} + + +static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + BPTR fh = (BPTR) png_get_io_ptr(png_ptr); + + if (1 != FRead(fh, data, 1, length)) + { +// png_error(); + } +} + + +static int read_chunk_callback(png_structp png_ptr, png_unknown_chunkp chunk) +{ + struct InstanceData *inst = png_get_user_chunk_ptr(png_ptr); + + d1(KPrintF("%s/%s/%ld: inst=%08lx name=%c%c%c%c\n", __FILE__, __FUNC__, __LINE__, inst, chunk->name[0], chunk->name[1], chunk->name[2], chunk->name[3])); + + if (chunk->name[0] == 'i' + && chunk->name[1] == 'c' + && chunk->name[2] == 'O' + && chunk->name[3] == 'n' + ) + { + HandleIconHunk(inst, chunk->data, chunk->size); + return 1; + } + else + { + return 0; + } +} + +void abort(void) +{ + while (1) + ; +} + +static void PngError(png_structp png_ptr, png_const_charp error_message) +{ + d1(KPrintF("%s/%s/%ld: png_ptr=%08lx message=<%s>\n", \ + __FILE__, __FUNC__, __LINE__, png_ptr, error_message)); + + longjmp(png_jmpbuf(png_ptr), 1); +} + + +static void PngWarning(png_structp png_ptr, png_const_charp warning_message) +{ + d1(KPrintF("%s/%s/%ld: png_ptr=%08lx message=<%s>\n", \ + __FILE__, __FUNC__, __LINE__, png_ptr, warning_message)); +// png_default_warning(png_ptr, warning_message); +} + diff --git a/scalos/datatypes/PNGIcons/LoadPngIcon.c b/scalos/datatypes/PNGIcons/LoadPngIcon.c new file mode 100644 index 000000000..8b6c79565 --- /dev/null +++ b/scalos/datatypes/PNGIcons/LoadPngIcon.c @@ -0,0 +1,500 @@ +// LoadPngIcon.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "png.h" +#include +#include "PNGIconDt.h" +#include "PNGIconProto.h" + +//----------------------------------------------------------------------------- + +static void DetermineIconType(struct InstanceData *inst, CONST_STRPTR filename, + const struct WBArg *ObjectLocation, struct FileInfoBlock *fib); +static void GuessWbDrawer(struct InstanceData *inst); + +//----------------------------------------------------------------------------- + +BOOL LoadPngIcon(struct InstanceData *inst, CONST_STRPTR filename, BPTR IconFh, const struct WBArg *ObjectLocation) +{ + STRPTR namedotinfo = NULL; + BPTR file = BNULL; + struct FileInfoBlock *fib = NULL; + struct DiskObject *DiskObj = NULL; + BOOL success = FALSE; + + + d1(kprintf("%s/%s/%ld: inst=%08lx ObjectLocation=%08lx\n", __FILE__, __FUNC__, __LINE__, inst, ObjectLocation)); + + do { + UBYTE id[8]; + LONG Length; + + // mark DrawerData as invalid + inst->id_DrawerData.dd_NewWindow.Width = inst->id_DrawerData.dd_NewWindow.Height = 0; + + if (IconFh) + { + d1(kprintf("%s/%s/%ld: IconFh=%08lx\n", __FILE__, __FUNC__, __LINE__, IconFh)); + file = IconFh; + } + else + { + // Build "filename.info" + + namedotinfo = MyAllocVecPooled(1 + 5 + strlen(filename)); + d1(kprintf("%s/%s/%ld: namedotinfo=%08lx\n", __FILE__, __FUNC__, __LINE__, namedotinfo)); + if (NULL == namedotinfo) + break; + + strcpy(namedotinfo, filename); + strcat(namedotinfo, ".info"); + + d1(kprintf("%s/%s/%ld: <%s>\n", __FILE__, __FUNC__, __LINE__, namedotinfo)); + + // Try to open the icon file + + file = Open(namedotinfo, MODE_OLDFILE); + + d1(KPrintF("%s/%s/%ld: <%s>\n", __FILE__, __FUNC__, __LINE__, namedotinfo)); + MyFreeVecPooled(namedotinfo); + namedotinfo = NULL; + } + + d1(kprintf("%s/%s/%ld: file=%08lx\n", __FILE__, __FUNC__, __LINE__, file)); + if (BNULL == file) + break; + + // Immediately Check if it's a PNG + + Length = FRead(file, (APTR) id, 1, sizeof(id)); + d1(kprintf("%s/%s/%ld: Length=%ld\n", __FILE__, __FUNC__, __LINE__, Length)); + if (sizeof(id) != Length) + break; + + d1(kprintf("%s/%s/%ld: id=%02lx %02lx %02lx %02lx\n", __FILE__, __FUNC__, __LINE__, id[0], id[1], id[2], id[3])); + + /* Compare the first PNG_BYTES_TO_CHECK bytes of the signature. + break if they match */ + if (0 != png_sig_cmp((png_bytep) id, (png_size_t) 0, sizeof(id))) + { + d1(kprintf("%s/%s/%ld: png_sig_cmp failed\n", __FILE__, __FUNC__, __LINE__)); + break; + } + + fib = AllocDosObject(DOS_FIB, NULL); + d1(kprintf("%s/%s/%ld: fib=%08lx\n", __FILE__, __FUNC__, __LINE__, fib)); + if (NULL == fib) + break; + + DetermineIconType(inst, filename, ObjectLocation, fib); + + d1(KPrintF("%s/%s/%ld: id_Type=%ld\n", __FILE__, __FUNC__, __LINE__, inst->id_Type)); + + if (!GetPngPicture(inst, file, sizeof(id), &inst->id_NormalImage)) + { + d1(KPrintF("%s/%s/%ld: GetPngPicture failed\n", __FILE__, __FUNC__, __LINE__)); + break; + } + + d1(KPrintF("%s/%s/%ld: Normal Width=%ld Height=%ld\n", + __FILE__, __FUNC__, __LINE__, inst->id_NormalImage.argb_Width, inst->id_NormalImage.argb_Height)); + + // check if second PNG image is present + do { + Length = FRead(file, (APTR) id, 1, sizeof(id)); + d1(KPrintF("%s/%s/%ld: Length=%ld\n", __FILE__, __FUNC__, __LINE__, Length)); + if (sizeof(id) != Length) + break; + + d1(KPrintF("%s/%s/%ld: id=%08lx %08lx\n", __FILE__, __FUNC__, __LINE__, id[0], id[1])); + + /* Compare the first PNG_BYTES_TO_CHECK bytes of the signature. + break if they don't match */ + if (0 != png_sig_cmp((png_bytep) id, (png_size_t) 0, sizeof(id))) + break; + + if (!GetPngPicture(inst, file, sizeof(id), &inst->id_SelectedImage)) + break; + + d1(KPrintF("%s/%s/%ld: Selected Width=%ld Height=%ld\n", + __FILE__, __FUNC__, __LINE__, inst->id_SelectedImage.argb_Width, inst->id_SelectedImage.argb_Height)); + } while (0); + + switch (inst->id_Type) + { + case WBDISK: + case WBDRAWER: + case WBGARBAGE: + if (0 == inst->id_DrawerData.dd_NewWindow.Width + || 0 == inst->id_DrawerData.dd_NewWindow.Height) + { + // if we have no valid DrawerData + DiskObj = GetDefDiskObject(inst->id_Type); + d1(kprintf("%s/%s/%ld: DiskObj=%08lx\n", __FILE__, __FUNC__, __LINE__, DiskObj)); + if (DiskObj && DiskObj->do_DrawerData) + { + // use icon.library defaults for our DrawerData + d1(kprintf("%s/%s/%ld: do_DrawerData=%08lx\n", __FILE__, __FUNC__, __LINE__, DiskObj->do_DrawerData)); + inst->id_DrawerData = *DiskObj->do_DrawerData; + } + } + d1(kprintf("%s/%s/%ld: CurrentX=%ld\n", __FILE__, __FUNC__, __LINE__, inst->id_DrawerData.dd_CurrentX)); + d1(kprintf("%s/%s/%ld: CurrentY=%ld\n", __FILE__, __FUNC__, __LINE__, inst->id_DrawerData.dd_CurrentY)); + d1(kprintf("%s/%s/%ld: Flags=%ld\n", __FILE__, __FUNC__, __LINE__, inst->id_DrawerData.dd_Flags)); + d1(KPrintF("%s/%s/%ld: ViewModes=%ld\n", __FILE__, __FUNC__, __LINE__, inst->id_DrawerData.dd_ViewModes)); + break; + default: + break; + } + + success = TRUE; + } while (0); + + d1(kprintf("%s/%s/%ld: success=%ld\n", __FILE__, __FUNC__, __LINE__, success)); + + if (DiskObj) + FreeDiskObject(DiskObj); + if (fib) + FreeDosObject(DOS_FIB, fib); + if (file && (BNULL == IconFh)) + Close(file); + if (namedotinfo) + MyFreeVecPooled(namedotinfo); + + return success; +} + + +void HandleIconHunk(struct InstanceData *inst, const UBYTE *Data, size_t Length) +{ + if (!inst->id_IconHunkLoaded) + { + ULONG ttlength, dtlength; + ULONG ttTotalLength; + ULONG ttCount; + const ULONG *dataptr = (const ULONG *) Data; + + ttTotalLength = 0; + ttCount = 0; + + // Begin scanning the tags + + inst->id_ToolTypesCount = 0; // Set ToolType counter to zero + d1(KPrintF("%s/%s/%ld: dd_ViewModes=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->id_DrawerData.dd_ViewModes)); + + while (Length >= 2 * sizeof(ULONG)) + { + ULONG tag = SCA_BE2LONG(*dataptr); + + d1(KPrintF("%s/%s/%ld: dataptr=%08lx Length=%ld\n", __FILE__, __FUNC__, __LINE__, dataptr, Length)); + dataptr++; + Length -= sizeof(ULONG); + + switch (tag) + { + case PNGICONA_XPOS: + inst->id_CurrentX = SCA_BE2LONG(*dataptr); + d1(kprintf("%s/%s/%ld: CurrentX=%ld\n", __FILE__, __FUNC__, __LINE__, inst->id_CurrentX)); + dataptr++; + Length -= sizeof(ULONG); + break; + case PNGICONA_YPOS: + inst->id_CurrentY = SCA_BE2LONG(*dataptr); + d1(kprintf("%s/%s/%ld: CurrentY=%ld\n", __FILE__, __FUNC__, __LINE__, inst->id_CurrentY)); + dataptr++; + Length -= sizeof(ULONG); + break; + + // One of the following five tags identifies a WBDISK or WBDRAWER icon + case PNGICONA_DRAWERXPOS: + inst->id_DrawerData.dd_NewWindow.LeftEdge = SCA_BE2WORD(*dataptr); + d1(KPrintF("%s/%s/%ld: LeftEdge=%ld\n", __FILE__, __FUNC__, __LINE__, inst->id_DrawerData.dd_NewWindow.LeftEdge)); + dataptr++; + Length -= sizeof(ULONG); + GuessWbDrawer(inst); + break; + case PNGICONA_DRAWERYPOS: + inst->id_DrawerData.dd_NewWindow.TopEdge = SCA_BE2LONG(*dataptr); + d1(KPrintF("%s/%s/%ld: TopEdge=%ld\n", __FILE__, __FUNC__, __LINE__, inst->id_DrawerData.dd_NewWindow.TopEdge)); + dataptr++; + Length -= sizeof(ULONG); + GuessWbDrawer(inst); + break; + case PNGICONA_DRAWERWIDTH: + inst->id_DrawerData.dd_NewWindow.Width = SCA_BE2LONG(*dataptr); + d1(KPrintF("%s/%s/%ld: Width=%ld\n", __FILE__, __FUNC__, __LINE__, inst->id_DrawerData.dd_NewWindow.Width)); + dataptr++; + Length -= sizeof(ULONG); + GuessWbDrawer(inst); + break; + case PNGICONA_DRAWERHEIGHT: + inst->id_DrawerData.dd_NewWindow.Height = SCA_BE2LONG(*dataptr); + d1(KPrintF("%s/%s/%ld: Height=%ld\n", __FILE__, __FUNC__, __LINE__, inst->id_DrawerData.dd_NewWindow.Height)); + dataptr++; + Length -= sizeof(ULONG); + GuessWbDrawer(inst); + break; + case PNGICONA_DRAWERVIEWMODE: + { + ULONG vm = SCA_BE2LONG(*dataptr); + + d1(KPrintF("%s/%s/%ld: PNGICONA_DRAWERVIEWMODE ViewModes=%08lx\n", __FILE__, __FUNC__, __LINE__, vm)); + + inst->id_DrawerData.dd_Flags = (vm & PNGDM_SHOWALLFILES) ? (DDFLAGS_SHOWALL) : (DDFLAGS_SHOWICONS); + inst->id_DrawerData.dd_ViewModes = (vm & PNGDM_VIEWBYICON) ? (DDVM_BYICON) : + (((vm & PNGDM_SORTMODEMASK)>>2)+DDVM_BYNAME); + d1(KPrintF("%s/%s/%ld: dd_Flags=%08lx dd_ViewModes=%08lx\n", __FILE__, __FUNC__, + __LINE__, inst->id_DrawerData.dd_Flags, inst->id_DrawerData.dd_ViewModes)); + dataptr++; + Length -= sizeof(ULONG); + GuessWbDrawer(inst); + } + break; + + case PNGICONA_STACKSIZE: + inst->id_StackSize = SCA_BE2LONG(*dataptr); + if (inst->id_StackSize < MINSTACKSIZE) + inst->id_StackSize = MINSTACKSIZE; + d1(kprintf("%s/%s/%ld: StackSize=%ld\n", __FILE__, __FUNC__, __LINE__, inst->id_StackSize)); + dataptr++; + Length -= sizeof(ULONG); + break; + + case PNGICONA_DEFTOOL: + // This identifies unequivocally a project icon - may be NULL! + dtlength = 1 + strlen((STRPTR) dataptr); + + d1(kprintf("%s/%s/%ld: DefaultTool=<%s>\n", __FILE__, __FUNC__, __LINE__, dataptr)); + + if (dtlength > 1) + { + inst->id_DefaultTool = MyAllocVecPooled(1 + strlen((STRPTR) dataptr)); + if (inst->id_DefaultTool) + strcpy(inst->id_DefaultTool, (STRPTR) dataptr); + } + + dataptr = (ULONG *) ((UBYTE *) dataptr + dtlength); + Length -= dtlength; + if (!inst->id_TypeSet) + inst->id_Type = WBPROJECT; + break; + + case PNGICONA_TOOLWINDOW: + dtlength = 1 + strlen((STRPTR) dataptr); + + d1(KPrintF("%s/%s/%ld: do_ToolWindow=<%s>\n", __FILE__, __FUNC__, __LINE__, dataptr)); + + if (dtlength > 1) + { + inst->id_ToolWindow = MyAllocVecPooled(1 + strlen((STRPTR) dataptr)); + if (inst->id_ToolWindow) + strcpy(inst->id_ToolWindow, (STRPTR) dataptr); + } + + dataptr = (ULONG *) ((UBYTE *) dataptr + dtlength); + Length -= dtlength; + if (!inst->id_TypeSet) + inst->id_Type = WBPROJECT; + break; + + case PNGICONA_TOOLTYPE: + ttlength = 1 + strlen((STRPTR) dataptr); + if (ttlength > 1) + { + struct TTNode *ttnode; + + d1(kprintf("%s/%s/%ld: ToolType=<%s>\n", __FILE__, __FUNC__, __LINE__, dataptr)); + + ttnode = MyAllocVecPooled(sizeof(struct TTNode) + 1 + ttlength); + if (ttnode) + { + ttTotalLength += ttlength; + ttCount++; + + AddTail(&inst->id_ToolTypesList, &ttnode->Node); + ttnode->Length = ttlength; + strcpy(ttnode->ToolType, (STRPTR) dataptr); + inst->id_ToolTypesCount++; + } + } + dataptr = (ULONG *) ((UBYTE *) dataptr + ttlength); + Length -= ttlength; + break; + + case PNGICONA_TYPE: + inst->id_Type = SCA_BE2LONG(*dataptr); + inst->id_TypeSet = TRUE; + d1(KPrintF("%s/%s/%ld: Icon type=%ld\n", __FILE__, __FUNC__, __LINE__, inst->id_Type)); + dataptr++; + Length -= sizeof(ULONG); + break; + + case PNGICONA_SORTMODE: + // only change dd_ViewMode if not set by PNGICONA_DRAWERVIEWMODE + d1(KPrintF("%s/%s/%ld: PNGICONA_SORTMODE=%08lx\n", __FILE__, __FUNC__, __LINE__, *dataptr)); + if (DDVM_BYDEFAULT == inst->id_DrawerData.dd_ViewModes) + inst->id_DrawerData.dd_ViewModes = DDVM_BYNAME + SCA_BE2LONG(*dataptr); + d1(KPrintF("%s/%s/%ld: dd_ViewModes=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->id_DrawerData.dd_ViewModes)); + dataptr++; + Length -= sizeof(ULONG); + GuessWbDrawer(inst); + break; + + case PNGICONA_OFFSETX: + inst->id_DrawerData.dd_CurrentX = SCA_BE2LONG(*dataptr); + d1(KPrintF("%s/%s/%ld: dd_CurrentX=%ld\n", __FILE__, __FUNC__, __LINE__, inst->id_DrawerData.dd_CurrentX)); + dataptr++; + Length -= sizeof(ULONG); + GuessWbDrawer(inst); + break; + + case PNGICONA_OFFSETY: + inst->id_DrawerData.dd_CurrentY = SCA_BE2LONG(*dataptr); + d1(KPrintF("%s/%s/%ld: dd_CurrentY=%ld\n", __FILE__, __FUNC__, __LINE__, inst->id_DrawerData.dd_CurrentY)); + dataptr++; + Length -= sizeof(ULONG); + GuessWbDrawer(inst); + break; + + default: + // Let's assume that all still unknown tags have ULONG data... + d1(KPrintF("%s/%s/%ld: tag=%08lx dataptr=%08lx Length=%ld\n", __FILE__, __FUNC__, __LINE__, tag, dataptr, Length)); + dataptr++; + Length -= sizeof(ULONG); + break; + } + } + + // Build ToolTypes array from ttlist. We'll put STRPTRS and strings in the same block. + inst->id_ToolTypesLength = 0; + if (ttTotalLength) + { + inst->id_ToolTypesLength = (ttCount + 1) * sizeof(STRPTR) + ttTotalLength; + inst->id_ToolTypes = (STRPTR *) MyAllocVecPooled(inst->id_ToolTypesLength); + if (inst->id_ToolTypes) + { + struct TTNode *ttnode; + char *tts; + + inst->id_ToolTypes[ttCount] = NULL; + tts = (char *) (&inst->id_ToolTypes[ttCount + 1]); + + while (ttnode = (struct TTNode *) RemTail(&inst->id_ToolTypesList)) + { + inst->id_ToolTypes[--ttCount] = tts; + + strcpy(tts, ttnode->ToolType); + tts += 1 + strlen(ttnode->ToolType); + + MyFreeVecPooled(ttnode); + } + } + } + + inst->id_IconHunkLoaded = TRUE; + } + + d1(KPrintF("%s/%s/%ld: id_Type=%lu\n", __FILE__, __FUNC__, __LINE__, inst->id_Type)); + d1(KPrintF("%s/%s/%ld: dd_ViewModes=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->id_DrawerData.dd_ViewModes)); +} + + +static void DetermineIconType(struct InstanceData *inst, CONST_STRPTR filename, + const struct WBArg *ObjectLocation, struct FileInfoBlock *fib) +{ + if (!inst->id_TypeSet) + { + BPTR fLock; + + d1(KPrintF("%s/%s/%ld: filename=<%s>\n", __FILE__, __FUNC__, __LINE__, filename)); + + inst->id_Type = WBTOOL; + inst->id_DirEntryType = 0; + + if (ObjectLocation) + { + BPTR oldDir = CurrentDir(ObjectLocation->wa_Lock); + + d1(KPrintF("%s/%s/%ld: ObjectLocation=%08lx Lock=%08lx Name=<%s>\n", \ + __FILE__, __FUNC__, __LINE__, ObjectLocation, ObjectLocation->wa_Lock, ObjectLocation->wa_Name)); + + fLock = Lock(ObjectLocation->wa_Name, ACCESS_READ); + CurrentDir(oldDir); + } + else + { + d1(KPrintF("%s/%s/%ld: filename=<%s>\n", __FILE__, __FUNC__, __LINE__, filename)); + fLock = Lock(filename, ACCESS_READ); + + if ((BPTR)NULL == fLock && ERROR_OBJECT_IN_USE == IoErr()) + { + Delay(10); + fLock = Lock(filename, ACCESS_READ); + } + } + + + d1(KPrintF("%s/%s/%ld: fLock=%08lx\n", __FILE__, __FUNC__, __LINE__, fLock)); + if (fLock) + { + if (Examine(fLock, fib)) + { + d1(KPrintF("%s/%s/%ld: Examine() success <%s> DirEntryType=%ld Protection=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, fib->fib_FileName, \ + fib->fib_DirEntryType, fib->fib_Protection)); + + if (fib->fib_DirEntryType > 0) + inst->id_Type = WBDRAWER; + else if (!(fib->fib_Protection & FIBF_EXECUTE)) + inst->id_Type = WBTOOL; // RWED are 0=on 1=off ! + else + inst->id_Type = WBPROJECT; + } + UnLock(fLock); + } + else + { + // No object associated. May be a "disk.info" ? + d1(KPrintF("%s/%s/%ld: IoErr=%ld\n", __FILE__, __FUNC__, __LINE__, IoErr())); + + if (0 == Stricmp(filename, "disk")) + inst->id_Type = WBDISK; + } + } + + d1(KPrintF("%s/%s/%ld: id_Type=%ld\n", __FILE__, __FUNC__, __LINE__, inst->id_Type)); +} + + +static void GuessWbDrawer(struct InstanceData *inst) +{ + if (!inst->id_TypeSet && inst->id_Type != WBDISK && inst->id_DirEntryType >= 0) + inst->id_Type = WBDRAWER; +} + + + diff --git a/scalos/datatypes/PNGIcons/PNGIconDt-aos4.c b/scalos/datatypes/PNGIcons/PNGIconDt-aos4.c new file mode 100644 index 000000000..e07153a60 --- /dev/null +++ b/scalos/datatypes/PNGIcons/PNGIconDt-aos4.c @@ -0,0 +1,191 @@ +// PNGIconDt-aos4.c +// $Date$ +// $Revision$ + + +#include +#include +#include + +#include +#include + +#include + +#include "PNGIconDt.h" + +int _start(void) +{ + return -1; +} + +static struct Library *Initlib(struct Library *libbase, BPTR seglist, struct ExecIFace *pIExec); +static BPTR Expungelib(struct LibraryManagerInterface *Self); +static struct LibraryHeader *Openlib(struct LibraryManagerInterface *Self, ULONG version); +static BPTR Closelib(struct LibraryManagerInterface *Self); +static ULONG Obtainlib(struct LibraryManagerInterface *Self); +static ULONG Releaselib(struct LibraryManagerInterface *Self); + +extern struct ExecBase *SysBase; + +/* OS4.0 Library */ + +/* ------------------- OS4 Manager Interface ------------------------ */ +static const APTR managerfunctable[] = + { + (APTR)Obtainlib, + (APTR)Releaselib, + (APTR)NULL, + (APTR)NULL, + (APTR)Openlib, + (APTR)Closelib, + (APTR)Expungelib, + (APTR)NULL, + (APTR)-1 + }; + +static const struct TagItem managertags[] = + { + {MIT_Name, (ULONG)"__library"}, + {MIT_VectorTable, (ULONG)managerfunctable}, + {MIT_Version, 1}, + {TAG_DONE, 0} + }; + +/* ---------------------- OS4 Main Interface ------------------------ */ +static APTR functable[] = + { + Obtainlib, + Releaselib, + NULL, + NULL, + ObtainInfoEngine, + (APTR) -1 + }; + +static const struct TagItem maintags[] = + { + {MIT_Name, (ULONG)"main"}, + {MIT_VectorTable, (ULONG)functable}, + {MIT_Version, 1}, + {TAG_DONE, 0} + }; + +/* Init table used in library initialization. */ +static const ULONG interfaces[] = + { + (ULONG)managertags, + (ULONG)maintags, + (ULONG)0 + }; + +static const struct TagItem inittab[] = + { + {CLT_DataSize, (ULONG)sizeof(struct PngIconObjectDtLibBase)}, + {CLT_Interfaces, (ULONG) interfaces}, +// {CLT_Vector68K, (ULONG)VecTable68K}, + {CLT_InitFunc, (ULONG) Initlib}, + {TAG_DONE, 0} + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, + RTF_NATIVE | RTF_AUTOINIT, + LIB_VERSION, + NT_LIBRARY, + 12, + libName, + libIdString, + (struct TagItem *)inittab + }; + +/* ------------------- OS4 Manager Functions ------------------------ */ +static struct Library * Initlib(struct Library *libbase, BPTR seglist, struct ExecIFace *pIExec) +{ + struct PngIconObjectDtLibBase *IconObjLibBase = (struct PngIconObjectDtLibBase *) libbase; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)libbase + libbase->lib_PosSize); + struct LibraryManagerInterface *Self = (struct LibraryManagerInterface *) ExtLib->ILibrary; + + SysBase = (struct ExecBase *)pIExec->Data.LibBase; + IExec = pIExec; + IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_Revision = LIB_REVISION; + IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_Node.ln_Pri = 12; + IconObjLibBase->nib_SegList = (struct SegList *)seglist; + + if (!InitDatatype(IconObjLibBase)) + { + Expungelib(Self); + IconObjLibBase = NULL; + } + + return (struct Library *)IconObjLibBase; +} + +static BPTR Expungelib(struct LibraryManagerInterface *Self) +{ + struct PngIconObjectDtLibBase *IconObjLibBase = (struct PngIconObjectDtLibBase *) Self->Data.LibBase; + + if (0 == IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + struct SegList *libseglist = IconObjLibBase->nib_SegList; + + Remove((struct Node *) IconObjLibBase); + CloseDatatype(IconObjLibBase); + DeleteLibrary((struct Library *)IconObjLibBase); + + return (BPTR)libseglist; + } + + IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_Flags |= LIBF_DELEXP; + + return (BPTR)NULL; +} + +static struct LibraryHeader *Openlib(struct LibraryManagerInterface *Self, ULONG version) +{ + struct PngIconObjectDtLibBase *IconObjLibBase = (struct PngIconObjectDtLibBase *) Self->Data.LibBase; + + IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_OpenCnt++; + IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_Flags &= ~LIBF_DELEXP; + + if (!OpenDatatype(IconObjLibBase)) + { + Closelib(Self); + return NULL; + } + + return (struct LibraryHeader *)IconObjLibBase; +} + +static BPTR Closelib(struct LibraryManagerInterface *Self) +{ + struct PngIconObjectDtLibBase *IconObjLibBase = (struct PngIconObjectDtLibBase *) Self->Data.LibBase; + + IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_OpenCnt--; +/* + if (0 == IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + if (IconObjLibBase->nib_ClassLibrary.cl_Lib.lib_Flags & LIBF_DELEXP) + { + return Expungelib(Self); + } + } +*/ + return (BPTR)NULL; +} + +static ULONG Obtainlib(struct LibraryManagerInterface *Self) +{ + return(Self->Data.RefCount++); +} + +static ULONG Releaselib(struct LibraryManagerInterface *Self) +{ + return(Self->Data.RefCount--); +} + diff --git a/scalos/datatypes/PNGIcons/PNGIconDt-aros.c b/scalos/datatypes/PNGIcons/PNGIconDt-aros.c new file mode 100644 index 000000000..bed46b11d --- /dev/null +++ b/scalos/datatypes/PNGIcons/PNGIconDt-aros.c @@ -0,0 +1,225 @@ +// pngicondt-classic.c +// $Date$ +// $Revision$ + + +#include + +#include +#include +#include + +#include + + +#include "PNGIconDt.h" + +//---------------------------------------------------------------------------- + +extern struct ExecBase *SysBase; + +//---------------------------------------------------------------------------- + +struct Library *aroscbase; + +//---------------------------------------------------------------------------- + +// Standard library functions + +static AROS_UFP3 (struct Library *, Initlib, + AROS_UFPA(struct Library *, libbase, D0), + AROS_UFPA(struct SegList *, seglist, A0), + AROS_UFPA(struct ExecBase *, sysbase, A6) +); +static AROS_LD1 (struct Library *, Openlib, + AROS_LPA (__unused ULONG, version, D0), + struct Library *, libbase, 1, PNGIconObject +); +static AROS_LD0 (struct SegList *, Closelib, + struct Library *, base, 2, PNGIconObject +); +static AROS_LD1 (struct SegList *, Expungelib, + AROS_LPA(__unused struct Library *, __extrabase, D0), + struct Library *, libbase, 3, PNGIconObject +); +static AROS_LD0 (ULONG, Extfunclib, + __unused struct Library *, libbase, 4, PNGIconObject +); + +//---------------------------------------------------------------------------- + +SAVEDS(LONG) ASM Libstart(void) +{ + return -1; +} + +//---------------------------------------------------------------------------- + +/* OS3.x Library */ + +static APTR functable[] = + { + PNGIconObject_1_Openlib, + PNGIconObject_2_Closelib, + PNGIconObject_3_Expungelib, + PNGIconObject_4_Extfunclib, + Dummy_0_ObtainInfoEngine, + (APTR) -1 + }; + +/* Init table used in library initialization. */ +static ULONG inittab[] = + { + sizeof(struct PngIconObjectDtLibBase), + (ULONG) functable, + 0, + (ULONG) Initlib + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, + RTF_AUTOINIT, + LIB_VERSION, + NT_LIBRARY, + 12, + libName, + libIdString, + inittab + }; + +//---------------------------------------------------------------------------- + +static AROS_UFH3(struct Library *, Initlib, + AROS_UFHA(struct Library *, libbase, D0), + AROS_UFHA(struct SegList *, seglist, A0), + AROS_UFHA(struct ExecBase *, sysbase, A6) +) +{ + AROS_USERFUNC_INIT + + struct PngIconObjectDtLibBase *PngDtLibBase = (struct PngIconObjectDtLibBase *) libbase; + + SysBase = sysbase; + PngDtLibBase->nib_ClassLibrary.cl_Lib.lib_Revision = LIB_REVISION; + PngDtLibBase->nib_ClassLibrary.cl_Lib.lib_Node.ln_Pri = 12; + PngDtLibBase->nib_SegList = seglist; + + aroscbase = OpenLibrary("arosc.library", 0); + + d1(kprintf("%s/%s/%ld: libbase=%08lx\n", __FILE__, __FUNC__, __LINE__, libbase)); + + if (!aroscbase || !InitDatatype(PngDtLibBase)) + { + PNGIconObject_3_Expungelib(&PngDtLibBase->nib_ClassLibrary.cl_Lib, &PngDtLibBase->nib_ClassLibrary.cl_Lib); + PngDtLibBase = NULL; + } + + return PngDtLibBase ? &PngDtLibBase->nib_ClassLibrary.cl_Lib : NULL; + + AROS_USERFUNC_EXIT +} + + +static AROS_LH1(struct Library *, Openlib, + AROS_LHA(__unused ULONG, version, D0), + struct Library *, libbase, 1, PNGIconObject +) +{ + AROS_LIBFUNC_INIT + + struct PngIconObjectDtLibBase *PngDtLibBase = (struct PngIconObjectDtLibBase *) libbase; + + d1(kprintf("%s/%s/%ld: libbase=%08lx\n", __FILE__, __FUNC__, __LINE__, libbase)); + + PngDtLibBase->nib_ClassLibrary.cl_Lib.lib_OpenCnt++; + PngDtLibBase->nib_ClassLibrary.cl_Lib.lib_Flags &= ~LIBF_DELEXP; + + if (!OpenDatatype(PngDtLibBase)) + { + PNGIconObject_2_Closelib(&PngDtLibBase->nib_ClassLibrary.cl_Lib); + return NULL; + } + + return &PngDtLibBase->nib_ClassLibrary.cl_Lib; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH0(struct SegList *, Closelib, + struct Library *, libbase, 2, PNGIconObject +) +{ + AROS_LIBFUNC_INIT + + struct PngIconObjectDtLibBase *PngDtLibBase = (struct PngIconObjectDtLibBase *) libbase; + + d1(kprintf("%s/%s/%ld: libbase=%08lx\n", __FILE__, __FUNC__, __LINE__, libbase)); + + PngDtLibBase->nib_ClassLibrary.cl_Lib.lib_OpenCnt--; + + if (0 == PngDtLibBase->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + if (PngDtLibBase->nib_ClassLibrary.cl_Lib.lib_Flags & LIBF_DELEXP) + { + return PNGIconObject_3_Expungelib(&PngDtLibBase->nib_ClassLibrary.cl_Lib, &PngDtLibBase->nib_ClassLibrary.cl_Lib); + } + } + + return NULL; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH1(struct SegList *, Expungelib, + AROS_LHA(__unused struct Library *, __extrabase, D0), + struct Library *, libbase, 3, PNGIconObject +) +{ + AROS_LIBFUNC_INIT + + struct PngIconObjectDtLibBase *PngDtLibBase = (struct PngIconObjectDtLibBase *) libbase; + + d1(kprintf("%s/%s/%ld: libbase=%08lx\n", __FILE__, __FUNC__, __LINE__, libbase)); + + if (0 == PngDtLibBase->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + ULONG size = PngDtLibBase->nib_ClassLibrary.cl_Lib.lib_NegSize + PngDtLibBase->nib_ClassLibrary.cl_Lib.lib_PosSize; + UBYTE *ptr = (UBYTE *) PngDtLibBase - PngDtLibBase->nib_ClassLibrary.cl_Lib.lib_NegSize; + struct SegList *libseglist = PngDtLibBase->nib_SegList; + + Remove((struct Node *) PngDtLibBase); + CloseDatatype(PngDtLibBase); + FreeMem(ptr,size); + + CloseLibrary(aroscbase); + + return libseglist; + } + + PngDtLibBase->nib_ClassLibrary.cl_Lib.lib_Flags |= LIBF_DELEXP; + + return NULL; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH0(ULONG, Extfunclib, + __unused struct Library *, libbase, 4, PNGIconObject +) +{ + AROS_LIBFUNC_INIT + + return 0; + + AROS_LIBFUNC_EXIT +} + +//----------------------------------------------------------------------------- diff --git a/scalos/datatypes/PNGIcons/PNGIconDt-classic.c b/scalos/datatypes/PNGIcons/PNGIconDt-classic.c new file mode 100644 index 000000000..aee570e2a --- /dev/null +++ b/scalos/datatypes/PNGIcons/PNGIconDt-classic.c @@ -0,0 +1,189 @@ +// pngicondt-classic.c +// $Date$ +// $Revision$ + + +#include +#include + +#include + +#include + + +#include "PNGIconDt.h" + +//---------------------------------------------------------------------------- + +extern struct ExecBase *SysBase; + +//---------------------------------------------------------------------------- + +// Standard library functions + +static LIB_SAVEDS(struct Library *) LIB_ASM LIB_INTERRUPT Initlib(LIB_REG(d0, struct Library *libbase), + LIB_REG(a0, struct SegList *seglist), LIB_REG(a6, struct ExecBase *sysbase)); + +static LIBFUNC_PROTO(Openlib, libbase, struct Library *); +static LIBFUNC_PROTO(Closelib, libbase, struct SegList *); +static LIBFUNC_PROTO(Expungelib, libbase, struct SegList *); +static LIBFUNC_PROTO(Extfunclib, libbase, ULONG); + +//---------------------------------------------------------------------------- + +SAVEDS(LONG) ASM Libstart(void) +{ + return -1; +} + +//---------------------------------------------------------------------------- + +/* OS3.x Library */ + +static APTR functable[] = + { +#ifdef __MORPHOS__ + (APTR) FUNCARRAY_32BIT_NATIVE, +#endif + Openlib, + Closelib, + Expungelib, + Extfunclib, + ObtainInfoEngine, + (APTR) -1 + }; + +/* Init table used in library initialization. */ +static ULONG inittab[] = + { + sizeof(struct PngIconObjectDtLibBase), + (ULONG) functable, + 0, + (ULONG) Initlib + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, +#ifdef __MORPHOS__ + RTF_PPC | RTF_AUTOINIT, +#else + RTF_AUTOINIT, +#endif + LIB_VERSION, + NT_LIBRARY, + 12, + libName, + libIdString, + inittab + }; + +#ifdef __MORPHOS__ +ULONG __abox__=1; +#endif + +//---------------------------------------------------------------------------- + +static LIB_SAVEDS(struct Library *) LIB_ASM LIB_INTERRUPT Initlib(LIB_REG(d0, struct Library *libbase), + LIB_REG(a0, struct SegList *seglist), LIB_REG(a6, struct ExecBase *sysbase)) +{ + struct PngIconObjectDtLibBase *PngDtLibBase = (struct PngIconObjectDtLibBase *) libbase; + + d1(kprintf("%s/%s/%ld: libbase=%08lx\n", __FILE__, __FUNC__, __LINE__, libbase)); + + SysBase = sysbase; + PngDtLibBase->nib_ClassLibrary.cl_Lib.lib_Revision = LIB_REVISION; + PngDtLibBase->nib_ClassLibrary.cl_Lib.lib_Node.ln_Pri = 12; + PngDtLibBase->nib_SegList = seglist; + + if (!InitDatatype(PngDtLibBase)) + { + CALLLIBFUNC(Expungelib, &PngDtLibBase->nib_ClassLibrary.cl_Lib); + PngDtLibBase = NULL; + } + + return PngDtLibBase ? &PngDtLibBase->nib_ClassLibrary.cl_Lib : NULL; +} + + +static LIBFUNC(Openlib, libbase, struct Library *) +{ + struct PngIconObjectDtLibBase *PngDtLibBase = (struct PngIconObjectDtLibBase *) libbase; + + d1(kprintf("%s/%s/%ld: libbase=%08lx\n", __FILE__, __FUNC__, __LINE__, libbase)); + + PngDtLibBase->nib_ClassLibrary.cl_Lib.lib_OpenCnt++; + PngDtLibBase->nib_ClassLibrary.cl_Lib.lib_Flags &= ~LIBF_DELEXP; + + if (!OpenDatatype(PngDtLibBase)) + { + CALLLIBFUNC(Closelib, &PngDtLibBase->nib_ClassLibrary.cl_Lib); + return NULL; + } + + return &PngDtLibBase->nib_ClassLibrary.cl_Lib; +} +LIBFUNC_END + + +static LIBFUNC(Closelib, libbase, struct SegList *) +{ + struct PngIconObjectDtLibBase *PngDtLibBase = (struct PngIconObjectDtLibBase *) libbase; + + d1(kprintf("%s/%s/%ld: libbase=%08lx\n", __FILE__, __FUNC__, __LINE__, libbase)); + + PngDtLibBase->nib_ClassLibrary.cl_Lib.lib_OpenCnt--; + + if (0 == PngDtLibBase->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + if (PngDtLibBase->nib_ClassLibrary.cl_Lib.lib_Flags & LIBF_DELEXP) + { + return CALLLIBFUNC(Expungelib, &PngDtLibBase->nib_ClassLibrary.cl_Lib); + } + } + + return NULL; +} +LIBFUNC_END + + +static LIBFUNC(Expungelib, libbase, struct SegList *) +{ + struct PngIconObjectDtLibBase *PngDtLibBase = (struct PngIconObjectDtLibBase *) libbase; + + d1(kprintf("%s/%s/%ld: libbase=%08lx\n", __FILE__, __FUNC__, __LINE__, libbase)); + + if (0 == PngDtLibBase->nib_ClassLibrary.cl_Lib.lib_OpenCnt) + { + ULONG size = PngDtLibBase->nib_ClassLibrary.cl_Lib.lib_NegSize + PngDtLibBase->nib_ClassLibrary.cl_Lib.lib_PosSize; + UBYTE *ptr = (UBYTE *) PngDtLibBase - PngDtLibBase->nib_ClassLibrary.cl_Lib.lib_NegSize; + struct SegList *libseglist = PngDtLibBase->nib_SegList; + + Remove((struct Node *) PngDtLibBase); + CloseDatatype(PngDtLibBase); + FreeMem(ptr,size); + + return libseglist; + } + + PngDtLibBase->nib_ClassLibrary.cl_Lib.lib_Flags |= LIBF_DELEXP; + + return NULL; +} +LIBFUNC_END + + +static LIBFUNC(Extfunclib, libbase, ULONG) +{ + d1(KPrintF("%s/%s/%ld: libbase=%08lx\n", __FILE__, __FUNC__, __LINE__, libbase)); + (void) libbase; + return 0; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + diff --git a/scalos/datatypes/PNGIcons/PNGIconDt.c b/scalos/datatypes/PNGIcons/PNGIconDt.c new file mode 100644 index 000000000..b4972308e --- /dev/null +++ b/scalos/datatypes/PNGIcons/PNGIconDt.c @@ -0,0 +1,1263 @@ +// PNGIconDt.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include + +#include +#include + +#include "PNGIconDt.h" +#include "PNGIconProto.h" + +//----------------------------------------------------------------------------- + +struct DefIconName + { + ULONG din_IconType; + CONST_STRPTR din_Filename; + }; + +//----------------------------------------------------------------------------- + +void *PngMemPool; + +Class *PngIconClass; + +const ULONG InstanceSize = sizeof(struct InstanceData); + +static struct SignalSemaphore PngMemPoolSemaphore; + +struct ExecBase *SysBase; +struct Library *WorkbenchBase; +struct IntuitionBase *IntuitionBase; +T_UTILITYBASE UtilityBase; +static struct Library *IconObjectDTBase; +struct Library *IconBase; +struct GfxBase *GfxBase; +struct DosLibrary *DOSBase; +struct Library *CyberGfxBase; +#ifdef TIMESTAMPS +T_TIMERBASE TimerBase; +#endif /* TIMESTAMPS */ +#ifdef __amigaos4__ +struct Library *NewlibBase; +struct Interface *INewlib; +struct WorkbenchIFace *IWorkbench; +struct ExecIFace *IExec; +struct IntuitionIFace *IIntuition; +struct UtilityIFace *IUtility; +struct IconIFace *IIcon; +struct GraphicsIFace *IGraphics; +struct DOSIFace *IDOS; +struct CyberGfxIFace *ICyberGfx; +#endif /* __amigaos4__ */ + +#ifdef __GNUC__ +extern T_UTILITYBASE __UtilityBase; +#endif /* __GNUC__ */ + +//---------------------------------------------------------------------------- + +static SAVEDS(ULONG) INTERRUPT PngIconDispatcher(Class *cl, Object *obj, Msg msg); + +static BOOL DtNew(Class *cl, Object *o, struct opSet *ops); +static ULONG DtDispose(Class *cl, Object *o, Msg msg); +static ULONG DtGet(Class *cl, Object *o, struct opGet *opg); +static ULONG DtWrite(Class *cl, Object *o, struct iopWrite *opw); +static ULONG DtNewImage(Class *cl, Object *o, struct iopNewImage *iopw); +static ULONG DtClone(Class *cl, Object *o, struct iopCloneIconObject *iocio); + +static CONST_STRPTR GetFileNameForDefaultIcon(ULONG IconType); +static BOOL IsPiDiskObject(const struct DiskObject *icon); +#if !defined(__SASC) &&!defined(__MORPHOS__) +size_t stccpy(char *dest, const char *src, size_t MaxLen); +#endif /* !defined(__SASC) &&!defined(__MORPHOS__) */ +static BOOL GetARGBfromSAC(struct ARGBHeader *argbh, + const struct ScalosBitMapAndColor *sac); +static void FreePngImage(struct ARGBHeader *argbh, BOOL DoFreeIcon); +static void DoUpdateWb(struct InstanceData *inst, CONST_STRPTR SavePath); +static void SetParentAttributes(Class *cl, Object *o); + +//---------------------------------------------------------------------------- + +char ALIGNED libName[] = "pngiconobject.datatype"; +char ALIGNED libIdString[] = "$VER: pngiconobject.datatype " + STR(LIB_VERSION) "." STR(LIB_REVISION) + " (25 Jan 2008 22:27:14) " + COMPILER_STRING " ©2003" CURRENTYEAR + " The Scalos Team, parts of code ©Elena Novaretti "; + +//---------------------------------------------------------------------------- + +LIBFUNC(ObtainInfoEngine, libbase, ULONG) +{ + d1(KPrintF("%s/%s/%ld: libbase=%08lx\n", __FILE__, __FUNC__, __LINE__, libbase)); + (void) libbase; + return (ULONG) PngIconClass; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +void _XCEXIT(long x) +{ +} + +//---------------------------------------------------------------------------- + +static SAVEDS(ULONG) INTERRUPT PngIconDispatcher(Class *cl, Object *o, Msg msg) +{ + ULONG Result; + + d1(KPrintF("%s/%s/%ld: cl=%08lx o=%08lx msg=%08lx\n", __FILE__, __FUNC__, __LINE__, cl, o, msg)); + + switch (msg->MethodID) + { + case OM_NEW: + o = (Object *) DoSuperMethodA(cl, o, msg); + d1(KPrintF("%s/%s/%ld: OM_NEW o=%08lx\n", __FILE__, __FUNC__, __LINE__, o)); + if (o) + { + if (!DtNew(cl, o, (struct opSet *) msg)) + { + DoMethod(o, OM_DISPOSE); + o = NULL; + } + } + Result = (ULONG) o; + break; + + case OM_DISPOSE: + Result = DtDispose(cl, o, msg); + break; + + case OM_GET: + Result = DtGet(cl, o, (struct opGet *) msg); + break; + + case IDTM_Write: + Result = DtWrite(cl, o, (struct iopWrite *) msg); + break; + + case IDTM_NewImage: + Result = DtNewImage(cl, o, (struct iopNewImage *) msg); + break; + + case IDTM_CloneIconObject: + Result = DtClone(cl, o, (struct iopCloneIconObject *) msg); + break; + + default: + Result = DoSuperMethodA(cl, o, msg); + break; + } + + return Result; +} + +//----------------------------------------------------------------------------- + +static BOOL DtNew(Class *cl, Object *o, struct opSet *ops) +{ + BOOL Success = FALSE; + struct InstanceData *inst = INST_DATA(cl, o); + + memset(inst, 0, sizeof(struct InstanceData)); + + NewList(&inst->id_ToolTypesList); + inst->id_StackSize = MINSTACKSIZE; + inst->id_DoNotFreeIcon = FALSE; + + do { + struct ExtGadget *gg = (struct ExtGadget *) o; + + d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__)); + TIMESTAMP_d1(); + + if (FindTagItem(IDTA_CloneIconObject, ops->ops_AttrList)) + { + d1(KPrintF("%s/%s/%ld: IDTA_CloneIconObject\n", __FILE__, __FUNC__, __LINE__)); + } + else + { + CONST_STRPTR FileName; + const struct WBArg *wba; + BPTR IconFh; + + // We don't support user-rendered icons + if (FindTagItem(IDTA_RenderHook, ops->ops_AttrList)) + break; + + if (FindTagItem(IDTA_DefType, ops->ops_AttrList)) + { + ULONG IconType; + + IconType = GetTagData(IDTA_DefType, 0, ops->ops_AttrList); + d1(KPrintF("%s/%s/%ld: IDTA_DefType=%ld\n", __FILE__, __FUNC__, __LINE__, IconType)); + FileName = GetFileNameForDefaultIcon(IconType); + } + else + { + FileName = (CONST_STRPTR) GetTagData(DTA_Name, (ULONG)NULL, (struct TagItem *)ops->ops_AttrList); + } + + wba = (const struct WBArg *) GetTagData(IDTA_IconLocation, (ULONG) NULL, ops->ops_AttrList); + + inst->id_CurrentX = inst->id_CurrentY = NO_ICON_POSITION; + + stccpy(inst->id_FileName, FileName, sizeof(inst->id_FileName)); + + if (FindTagItem(AIDTA_Icon, ops->ops_AttrList)) + { + struct DiskObject *icon = (struct DiskObject *) GetTagData(AIDTA_Icon, (ULONG)NULL, (struct TagItem *)ops->ops_AttrList); + struct PiIconSpecial *ispc; + + d1(kprintf("%s/%s/%ld: DiskObject=%08lx\n", __FILE__, __FUNC__, __LINE__, icon)); + + if (!IsPiDiskObject(icon)) + // We only support "cloning of icons" for PowerIcons + break; + + ispc = (struct PiIconSpecial *) icon->do_Gadget.MutualExclude; + + if (!(ispc->Flags & ISF_PNGICON)) + break; + + inst->id_CurrentX = icon->do_CurrentX; + inst->id_CurrentY = icon->do_CurrentX; + inst->id_NormalImage.argb_Width = ispc->Width; + inst->id_NormalImage.argb_Height = ispc->Height; + inst->id_NormalImage.argb_ImageData = (struct ARGB *) ispc->ImgData; + inst->id_Type = icon->do_Type; + inst->id_StackSize = icon->do_StackSize; + inst->id_ToolTypes = icon->do_ToolTypes; + inst->id_DefaultTool = icon->do_DefaultTool; + inst->id_ToolWindow = icon->do_ToolWindow; + + d1(kprintf("%s/%s/%ld: w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, inst->id_NormalImage.argb_Width, inst->id_NormalImage.argb_Height)); + d1(kprintf("%s/%s/%ld: ImgData=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->id_NormalImage.argb_ImageData)); + d1(kprintf("%s/%s/%ld: ToolTypes=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->id_ToolTypes)); + + if (icon->do_DrawerData) + { + inst->id_DrawerData = *icon->do_DrawerData; + } + + inst->id_DoNotFreeIcon = TRUE; + + d1(kprintf("%s/%s/%ld: use existing DiskObject\n", __FILE__, __FUNC__, __LINE__)); + } + else + { + if (NULL == FileName) + break; + + if ('\0' == *FileName) + break; + + IconFh = GetTagData(DTA_Handle, 0, ops->ops_AttrList); + + d1(KPrintF("%s/%s/%ld: FileName=<%s>\n", __FILE__, __FUNC__, __LINE__, FileName)); + TIMESTAMP_d1(); + + if (!LoadPngIcon(inst, FileName, IconFh, wba)) + break; + + inst->id_Type = GetTagData(IDTA_DefType, inst->id_Type, ops->ops_AttrList); + d1(KPrintF("%s/%s/%ld: id_Type=%ld\n", __FILE__, __FUNC__, __LINE__, inst->id_Type)); + + d1(kprintf("%s/%s/%ld: LoadPngIcon succeeded\n", __FILE__, __FUNC__, __LINE__)); + TIMESTAMP_d1(); + } + + if (NO_ICON_POSITION == inst->id_CurrentX) + { + gg->LeftEdge = gg->TopEdge = (WORD) 0x8000; + } + else + { + gg->LeftEdge = inst->id_CurrentX; + gg->TopEdge = inst->id_CurrentY; + } + + TIMESTAMP_d1(); + SetParentAttributes(cl, o); + } + + TIMESTAMP_d1(); + Success = TRUE; + d1(KPrintF("%s/%s/%ld: o=%08lx ImgData=%08lx", \ + __FILE__, __FUNC__, __LINE__, o, inst->id_NormalImage.argb_ImageData)); + d1(kprintf("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + } while (0); + + d1(KPrintF("%s/%s/%ld: o=%08lx Success=%ld\n", __FILE__, __FUNC__, __LINE__, o, Success)); + TIMESTAMP_d1(); + + return Success; +} + +//---------------------------------------------------------------------------------------- + +static ULONG DtGet(Class *cl, Object *o, struct opGet *opg) +{ + ULONG result = 1; + + switch (opg->opg_AttrID) + { + case IDTA_IconType: + *opg->opg_Storage = ioICONTYPE_PngIcon; + break; + + case IDTA_NumberOfColorsSupported: + *opg->opg_Storage = 1 + 0x00ffffff; + break; + + default: + result = DoSuperMethodA(cl, o, (Msg) opg); + break; + } + + return result; +} + +//---------------------------------------------------------------------------------------- + +static ULONG DtDispose(Class *cl, Object *o, Msg msg) +{ + struct TTNode *ttnode; + struct InstanceData *inst = INST_DATA(cl, o); + + d1(kprintf("%s/%s/%ld: o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + + if (inst->id_DefaultTool && !inst->id_DoNotFreeIcon) + { + d1(kprintf("%s/%s/%ld: id_DefaultTool=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->id_DefaultTool)); + MyFreeVecPooled(inst->id_DefaultTool); + inst->id_DefaultTool = NULL; + } + if (inst->id_ToolWindow && !inst->id_DoNotFreeIcon) + { + d1(KPrintF("%s/%s/%ld: id_ToolWindow=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->id_ToolWindow)); + MyFreeVecPooled(inst->id_ToolWindow); + inst->id_ToolWindow = NULL; + } + if (inst->id_ToolTypes && !inst->id_DoNotFreeIcon) + { + d1(kprintf("%s/%s/%ld: id_ToolTypes=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->id_ToolTypes)); + MyFreeVecPooled(inst->id_ToolTypes); + inst->id_ToolTypes = NULL; + } + + while (ttnode = (struct TTNode *) RemTail(&inst->id_ToolTypesList)) + { + d1(kprintf("%s/%s/%ld: ttnode=%08lx\n", __FILE__, __FUNC__, __LINE__, ttnode)); + MyFreeVecPooled(ttnode); + } + + FreePngImage(&inst->id_NormalImage, !inst->id_DoNotFreeIcon); + FreePngImage(&inst->id_SelectedImage, !inst->id_DoNotFreeIcon); + + return DoSuperMethodA(cl, o, msg); +} + +//---------------------------------------------------------------------------------------- + +static ULONG DtWrite(Class *cl, Object *o, struct iopWrite *opw) +{ + struct ExtGadget *gg = (struct ExtGadget *) o; + struct InstanceData *inst = INST_DATA(cl, o); + STRPTR origDefaultTool = inst->id_DefaultTool; + STRPTR origToolWindow = inst->id_ToolWindow; + STRPTR *origTooltypes = inst->id_ToolTypes; + struct IBox *WindowRect = NULL; + struct ARGBHeader *NrmARGBImage = &inst->id_NormalImage; + struct ARGBHeader *SelARGBImage = &inst->id_SelectedImage; + ULONG ViewModes; + ULONG NeedUpdateWB; + LONG Result = RETURN_OK; + + d1(KPrintF("%s/%s/%ld: id_Type=%lu\n", __FILE__, __FUNC__, __LINE__, inst->id_Type)); + d1(KPrintF("%s/%s/%ld: ImgData=%08lx WorkBuffer=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->id_NormalImage.argb_ImageData)); + + GetAttr(IDTA_Type, o, &inst->id_Type); + GetAttr(IDTA_ViewModes, o, &ViewModes); + GetAttr(IDTA_Flags, o, &inst->id_DrawerData.dd_Flags); + GetAttr(IDTA_WinCurrentX, o, (ULONG *) &inst->id_DrawerData.dd_CurrentX); + GetAttr(IDTA_WinCurrentY, o, (ULONG *) &inst->id_DrawerData.dd_CurrentY); + GetAttr(IDTA_WindowRect, o, (APTR) &WindowRect); + GetAttr(IDTA_Stacksize, o, &inst->id_StackSize); + GetAttr(IDTA_ToolTypes, o, (ULONG *) &inst->id_ToolTypes); + GetAttr(IDTA_DefaultTool, o, (ULONG *) &inst->id_DefaultTool); + GetAttr(IDTA_ToolWindow, o, (ULONG *) &inst->id_ToolWindow); + GetAttr(IDTA_ARGBImageData, o, (APTR) &NrmARGBImage); + GetAttr(IDTA_SelARGBImageData, o, (APTR) &SelARGBImage); + + inst->id_DrawerData.dd_ViewModes = ViewModes; + + d1(KPrintF("%s/%s/%ld: id_Type=%lu\n", __FILE__, __FUNC__, __LINE__, inst->id_Type)); + d1(KPrintF("%s/%s/%ld: NrmImgData=%08lx SelImgData=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, NrmARGBImage->argb_ImageData, SelARGBImage->argb_ImageData)); + + NeedUpdateWB = GetTagData(ICONA_NotifyWorkbench, FALSE, opw->iopw_Tags); + + if (WindowRect) + { + inst->id_DrawerData.dd_NewWindow.LeftEdge = WindowRect->Left; + inst->id_DrawerData.dd_NewWindow.TopEdge = WindowRect->Top; + inst->id_DrawerData.dd_NewWindow.Width = WindowRect->Width; + inst->id_DrawerData.dd_NewWindow.Height = WindowRect->Height; + } + + if (GetTagData(ICONA_NoPosition, 0, opw->iopw_Tags)) + { + inst->id_CurrentX = inst->id_CurrentY = NO_ICON_POSITION; + } + else + { + if ((WORD) 0x8000 == gg->LeftEdge) + { + inst->id_CurrentX = inst->id_CurrentY = NO_ICON_POSITION; + } + else + { + inst->id_CurrentX = gg->LeftEdge; + inst->id_CurrentY = gg->TopEdge; + } + } + + if (!SavePngIcon(inst, opw->iopw_Path, NrmARGBImage, SelARGBImage)) + Result = IoErr(); + + d1(KPrintF("%s/%s/%ld: ImgData=%08lx WorkBuffer=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->id_NormalImage.argb_ImageData)); + + // Restore DefaultTool & ToolTypes + inst->id_ToolWindow = origToolWindow; + inst->id_DefaultTool = origDefaultTool; + inst->id_ToolTypes = origTooltypes; + + if ((RETURN_OK == Result) && NeedUpdateWB) + DoUpdateWb(inst, opw->iopw_Path); + + return (ULONG) Result; +} + +//----------------------------------------------------------------------------- + +static ULONG DtNewImage(Class *cl, Object *o, struct iopNewImage *ioni) +{ + struct InstanceData *inst = INST_DATA(cl, o); + struct ARGBHeader argbh; + + d1(KPrintF("%s/%ld: START o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + + do { + memset(&argbh, 0, sizeof(argbh)); + + if (GetARGBfromSAC(&argbh, ioni->ioni_NormalImage)) + { + if (inst->id_NormalImage.argb_ImageData && !inst->id_DoNotFreeIcon) + { + d1(kprintf("%s/%s/%ld: id_NormalImage.argb_ImageData=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->id_NormalImage.argb_ImageData)); + MyFreeVecPooled(inst->id_NormalImage.argb_ImageData); + inst->id_NormalImage.argb_ImageData = NULL; + } + inst->id_NormalImage = argbh; + } + if (GetARGBfromSAC(&argbh, ioni->ioni_SelectedImage)) + { + if (inst->id_SelectedImage.argb_ImageData && !inst->id_DoNotFreeIcon) + { + d1(kprintf("%s/%s/%ld: id_NormalImage.argb_ImageData=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->id_NormalImage.argb_ImageData)); + MyFreeVecPooled(inst->id_SelectedImage.argb_ImageData); + inst->id_SelectedImage.argb_ImageData = NULL; + } + inst->id_SelectedImage = argbh; + } + } while (0); + + d1(KPrintF("%s/%s/%ld: END o=%08lx inst=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst)); + + return 0; +} + +//----------------------------------------------------------------------------- + +static ULONG DtClone(Class *cl, Object *o, struct iopCloneIconObject *iocio) +{ + struct InstanceData *inst = INST_DATA(cl, o); + Object *oClone; + BOOL Success = FALSE; + + d1(KPrintF("%s/%ld: START o=%08lx inst=%08lx id_FileName=<%s>\n", __FUNC__, __LINE__, o, inst, inst->id_FileName)); + + do { + struct InstanceData *instClone; + + + oClone = (Object *) NewObject(cl, NULL, + DTA_Name, inst->id_FileName, // REQUIRED, otherwise NewObject() will fail + IDTA_CloneIconObject, o, + TAG_MORE, iocio->iocio_TagList, + TAG_END); + d1(KPrintF("%s/%s/%ld: o=%08lx inst=%08lx oClone=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst, oClone)); + if (NULL == oClone) + break; + + instClone = INST_DATA(cl, oClone); + + *instClone = *inst; + + if (inst->id_DefaultTool && !inst->id_DoNotFreeIcon) + { + // Clone Default Tool + instClone->id_DefaultTool = MyAllocVecPooled(1 + strlen(inst->id_DefaultTool)); + d1(KPrintF("%s/%s/%ld: id_DefaultTool=%08lx\n", __FILE__, __FUNC__, __LINE__, instClone->id_DefaultTool)); + if (NULL == instClone->id_DefaultTool) + break; + + strcpy(instClone->id_DefaultTool, inst->id_DefaultTool); + } + if (inst->id_ToolWindow && !inst->id_DoNotFreeIcon) + { + // Clone Tool Window + instClone->id_ToolWindow = MyAllocVecPooled(1 + strlen(inst->id_ToolWindow)); + d1(KPrintF("%s/%s/%ld: id_ToolWindow=%08lx\n", __FILE__, __FUNC__, __LINE__, instClone->id_ToolWindow)); + if (NULL == instClone->id_ToolWindow) + break; + + strcpy(instClone->id_ToolWindow, inst->id_ToolWindow); + } + + NewList(&instClone->id_ToolTypesList); + + // Clone Tooltypes array + + instClone->id_ToolTypes = NULL; + if (instClone->id_ToolTypesLength) + { + instClone->id_ToolTypes = MyAllocVecPooled(instClone->id_ToolTypesLength); + if (NULL == instClone->id_ToolTypes) + break; + + memcpy(instClone->id_ToolTypes, inst->id_ToolTypes, instClone->id_ToolTypesLength); + } + + d1(KPrintF("%s/%s/%ld: id_DoNotFreeIcon=%ld\n", __FILE__, __FUNC__, __LINE__, inst->id_DoNotFreeIcon)); + + if (!inst->id_DoNotFreeIcon) + { + struct ARGBHeader *NrmARGBImage = &inst->id_NormalImage; + struct ARGBHeader *SelARGBImage = &inst->id_SelectedImage; + size_t ImgSize; + + d1(KPrintF("%s/%s/%ld: id_NormalImage=%08lx w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, NrmARGBImage, NrmARGBImage->argb_Width, NrmARGBImage->argb_Height)); + d1(KPrintF("%s/%s/%ld: id_SelectedImage=%08lx w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, NrmARGBImage, SelARGBImage->argb_Width, SelARGBImage->argb_Height)); + + GetAttr(IDTA_ARGBImageData, o, (APTR) &NrmARGBImage); + GetAttr(IDTA_SelARGBImageData, o, (APTR) &SelARGBImage); + + d1(KPrintF("%s/%s/%ld: NrmARGBImage=%08lx w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, NrmARGBImage, NrmARGBImage->argb_Width, NrmARGBImage->argb_Height)); + d1(KPrintF("%s/%s/%ld: SelARGBImage=%08lx w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, NrmARGBImage, SelARGBImage->argb_Width, SelARGBImage->argb_Height)); + + ImgSize = sizeof(struct ARGB) * NrmARGBImage->argb_Width * NrmARGBImage->argb_Height; + + // Clone Normal image + instClone->id_NormalImage = *NrmARGBImage; + + instClone->id_NormalImage.argb_ImageData = MyAllocVecPooled(ImgSize); + if (NULL == instClone->id_NormalImage.argb_ImageData) + break; + + memcpy(instClone->id_NormalImage.argb_ImageData, + NrmARGBImage->argb_ImageData, ImgSize); + + if (SelARGBImage && SelARGBImage->argb_ImageData) + { + // Clone Selected Image + ImgSize = sizeof(struct ARGB) * SelARGBImage->argb_Width * SelARGBImage->argb_Height; + + instClone->id_SelectedImage = *SelARGBImage; + + instClone->id_SelectedImage.argb_ImageData = MyAllocVecPooled(ImgSize); + if (NULL == instClone->id_SelectedImage.argb_ImageData) + break; + + memcpy(instClone->id_SelectedImage.argb_ImageData, + SelARGBImage->argb_ImageData, ImgSize); + } + + } + + SetAttrsA(oClone, iocio->iocio_TagList); + + TIMESTAMP_d1(); + SetParentAttributes(cl, oClone); + + Success = TRUE; + } while (0); + + if (oClone && !Success) + { + DoMethod(oClone, OM_DISPOSE); + oClone = NULL; + } + + d1(KPrintF("%s/%s/%ld: END o=%08lx inst=%08lx oClone=%08lx\n", __FILE__, __FUNC__, __LINE__, o, inst, oClone)); + + return (ULONG) oClone; +} + +//----------------------------------------------------------------------------- + +APTR MyAllocVecPooled(size_t Size) +{ + APTR ptr; + + if (PngMemPool) + { + ObtainSemaphore(&PngMemPoolSemaphore); + ptr = AllocPooled(PngMemPool, Size + sizeof(size_t)); + ReleaseSemaphore(&PngMemPoolSemaphore); + if (ptr) + { + size_t *sptr = (size_t *) ptr; + + sptr[0] = Size; + + d1(kprintf("%s/%s/%ld: MemPool=%08lx Size=%lu mem=%08lx\n", __FILE__, __FUNC__, __LINE__, PngMemPool, Size, &sptr[1])); + return (APTR)(&sptr[1]); + } + } + + d1(kprintf("%s/%s/%ld: MemPool=%08lx Size=%lu\n", __FILE__, __FUNC__, __LINE__, PngMemPool, Size)); + + return NULL; +} + + +void MyFreeVecPooled(APTR mem) +{ + d1(kprintf("%s/%s/%ld: MemPool=%08lx mem=%08lx\n", __FILE__, __FUNC__, __LINE__, PngMemPool, mem)); + if (PngMemPool && mem) + { + size_t size; + size_t *sptr = (size_t *) mem; + + mem = &sptr[-1]; + size = sptr[-1]; + + ObtainSemaphore(&PngMemPoolSemaphore); + FreePooled(PngMemPool, mem, size + sizeof(size_t)); + ReleaseSemaphore(&PngMemPoolSemaphore); + } +} + +//----------------------------------------------------------------------------- + +static CONST_STRPTR GetFileNameForDefaultIcon(ULONG IconType) +{ + static const struct DefIconName DefIconNames[] = + { +#if defined(__AROS__) + { WBDISK, "ENVARC:sys/def_disk" }, + { WBDRAWER, "ENVARC:sys/def_drawer" }, + { WBTOOL, "ENVARC:sys/def_tool" }, + { WBPROJECT, "ENVARC:sys/def_project" }, + { WBGARBAGE, "ENVARC:sys/def_trashcan" }, + { WBDEVICE, "ENVARC:sys/def_device" }, + { WBKICK, "ENVARC:sys/def_kick" }, + { WBAPPICON, "ENVARC:sys/def_appicon" } +#else + { WBDISK, "ENV:sys/def_disk" }, + { WBDRAWER, "ENV:sys/def_drawer" }, + { WBTOOL, "ENV:sys/def_tool" }, + { WBPROJECT, "ENV:sys/def_project" }, + { WBGARBAGE, "ENV:sys/def_trashcan" }, + { WBDEVICE, "ENV:sys/def_device" }, + { WBKICK, "ENV:sys/def_kick" }, + { WBAPPICON, "ENV:sys/def_appicon" } +#endif + }; + + ULONG n; + + for (n=0; ndo_Gadget.NextGadget == (struct Gadget *) icon) + && (ispc = (const struct PiIconSpecial *) icon->do_Gadget.MutualExclude) + && (ispc->Myself == icon)); +} + +//----------------------------------------------------------------------------- + +// return 0 if error occurred +ULONG InitDatatype(struct PngIconObjectDtLibBase *dtLib) +{ + d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__)); + + dtLib->nib_Initialized = FALSE; + + return 1; +} + +// return 0 if error occurred +ULONG OpenDatatype(struct PngIconObjectDtLibBase *dtLib) +{ + d1(kprintf("%s/%s/%ld: OpenCnt=%ld\n", __FILE__, __FUNC__, __LINE__, dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt)); + + if (!dtLib->nib_Initialized) + { + ULONG WbScreenDepth; + struct Screen *WbScreen; + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + dtLib->nib_Initialized = TRUE; + + InitSemaphore(&PngMemPoolSemaphore); + + IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39); +#ifdef __amigaos4__ + if (IntuitionBase != NULL) + { + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (IIntuition == NULL) + { + CloseLibrary((struct Library *)IntuitionBase); + IntuitionBase = NULL; + } + } +#endif /* __amigaos4__ */ + if (NULL == IntuitionBase) + return 0; + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + UtilityBase = (T_UTILITYBASE) OpenLibrary("utility.library", 39); +#ifdef __amigaos4__ + if (UtilityBase != NULL) + { + IUtility = (struct UtilityIFace *)GetInterface((struct Library *)UtilityBase, "main", 1, NULL); + if (IUtility == NULL) + { + CloseLibrary((struct Library *)UtilityBase); + UtilityBase = NULL; + } + } +#endif /* __amigaos4__ */ + if (NULL == UtilityBase) + return 0; + +#if defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) + __UtilityBase = UtilityBase; +#endif /* defined(__GNUC__) && !defined(__MORPHOS__) */ + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + GfxBase = (struct GfxBase *) OpenLibrary(GRAPHICSNAME, 39); +#ifdef __amigaos4__ + if (GfxBase != NULL) + { + IGraphics = (struct GraphicsIFace *)GetInterface((struct Library *)GfxBase, "main", 1, NULL); + if (IGraphics == NULL) + { + CloseLibrary((struct Library *)GfxBase); + GfxBase = NULL; + } + } +#endif /* __amigaos4__ */ + if (NULL == GfxBase) + return 0; + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + WorkbenchBase = OpenLibrary("workbench.library", 39); + d1(KPrintF("%s/%s/%ld: WorkbenchBase=%08lx\n", __FILE__, __FUNC__, __LINE__, WorkbenchBase)); + if (NULL == WorkbenchBase) + return 0; +#ifdef __amigaos4__ + IWorkbench = (struct WorkbenchIFace *)GetInterface((struct Library *)WorkbenchBase, "main", 1, NULL); + if (NULL == IWorkbench) + return 0; +#endif /* __amigaos4__ */ + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + DOSBase = (struct DosLibrary *) OpenLibrary(DOSNAME, 39); +#ifdef __amigaos4__ + if (DOSBase != NULL) + { + IDOS = (struct DOSIFace *)GetInterface((struct Library *)DOSBase, "main", 1, NULL); + if (IDOS == NULL) + { + CloseLibrary((struct Library *)DOSBase); + DOSBase = NULL; + } + } +#endif /* __amigaos4__ */ + if (NULL == DOSBase) + return 0; + + IconBase = OpenLibrary(ICONNAME, 39); +#ifdef __amigaos4__ + if (IconBase != NULL) + { + IIcon = (struct IconIFace *)GetInterface((struct Library *)IconBase, "main", 1, NULL); + if (IIcon == NULL) + { + CloseLibrary((struct Library *)IconBase); + IconBase = NULL; + } + } +#endif /* __amigaos4__ */ + if (NULL == IconBase) + return 0; + + CyberGfxBase = OpenLibrary(CYBERGFXNAME, 0); +#ifdef __amigaos4__ + if (CyberGfxBase != NULL) + { + ICyberGfx = (struct CyberGfxIFace *)GetInterface((struct Library *)CyberGfxBase, "main", 1, NULL); + if (ICyberGfx == NULL) + { + CloseLibrary((struct Library *)CyberGfxBase); + CyberGfxBase = NULL; + } + } + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + return 0; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + return 0; +#endif /* __amigaos4__ */ + if (NULL == CyberGfxBase) + return 0; + + WbScreen = LockPubScreen("Workbench"); + d1(kprintf("%s/%s/%ld: WbScreen=%08lx\n", __FILE__, __FUNC__, __LINE__, WbScreen)); + if (NULL == WbScreen) + return 0; + + // We REQUIRE a high-color or full-color screen (depth > 8) !! + WbScreenDepth = GetBitMapAttr(WbScreen->RastPort.BitMap, BMA_DEPTH); + UnlockPubScreen(NULL, WbScreen); + d1(kprintf("%s/%s/%ld: WbScreenDepth=%lu\n", __FILE__, __FUNC__, __LINE__, WbScreenDepth)); + if (WbScreenDepth <= 8) + return 0; + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + // we explicitely need to open our parent datatype - otherwise MakeClass() will fail! + IconObjectDTBase = OpenLibrary("datatypes/iconobject.datatype", 39); + if (NULL == IconObjectDTBase) + return 0; + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + +#ifdef TIMESTAMPS + { + struct timerequest *iorequest; + + iorequest = (struct timerequest *) CreateIORequest(CreateMsgPort(), sizeof(struct timerequest)); + OpenDevice("timer.device", UNIT_VBLANK, &iorequest->tr_node, 0); + TimerBase = (T_TIMERBASE) iorequest->tr_node.io_Device; + } +#endif /* TIMESTAMPS */ + +#if !defined(__amigaos4__) && !defined(__AROS__) + if (_STI_240_InitMemFunctions()) + return 0; +#endif /* __amigaos4__ */ + + PngMemPool = CreatePool(MEMPOOL_MEMFLAGS, MEMPOOL_PUDDLESIZE, MEMPOOL_THRESHSIZE); + if (NULL == PngMemPool) + return 0; + + PngIconClass = dtLib->nib_ClassLibrary.cl_Class = MakeClass(libName, + "iconobject.datatype", NULL, sizeof(struct InstanceData), 0); + d1(kprintf("%s/%s/%ld: PngIconClass=%08lx\n", __FILE__, __FUNC__, __LINE__, PngIconClass)); + if (NULL == PngIconClass) + return 0; + + SETHOOKFUNC(PngIconClass->cl_Dispatcher, PngIconDispatcher); + PngIconClass->cl_Dispatcher.h_Data = NULL; + + // Make class available for the public + AddClass(PngIconClass); + } + + d1(kprintf("%s/%s/%ld: Open Success!\n", __FILE__, __FUNC__, __LINE__)); + + return 1; +} + + +void CloseDatatype(struct PngIconObjectDtLibBase *dtLib) +{ + d1(kprintf("%s/%s/%ld: OpenCnt=%ld\n", __FILE__, __FUNC__, __LINE__, dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt)); + + if (dtLib->nib_ClassLibrary.cl_Lib.lib_OpenCnt < 1) + { + if (PngIconClass) + { + RemoveClass(PngIconClass); + FreeClass(PngIconClass); + PngIconClass = dtLib->nib_ClassLibrary.cl_Class = NULL; + } + +#if !defined(__amigaos4__) && !defined(__AROS__) + _STD_240_TerminateMemFunctions(); +#endif /* __amigaos4__ */ + + if (NULL != PngMemPool) + { + DeletePool(PngMemPool); + PngMemPool = NULL; + } + +#ifdef __amigaos4__ + if (INewlib) + { + DropInterface(INewlib); + INewlib = NULL; + } + if (NewlibBase) + { + CloseLibrary(NewlibBase); + NewlibBase = NULL; + } +#endif + if (NULL != CyberGfxBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)ICyberGfx); +#endif /* __amigaos4__ */ + CloseLibrary(CyberGfxBase); + CyberGfxBase = NULL; + } + if (NULL != IconObjectDTBase) + { + CloseLibrary(IconObjectDTBase); + IconObjectDTBase = NULL; + } +#ifdef __amigaos4__ + if (NULL != IWorkbench) + { + DropInterface((struct Interface *)IWorkbench); + IWorkbench = NULL; + } +#endif /* __amigaos4__ */ + if (NULL != WorkbenchBase) + { + CloseLibrary(WorkbenchBase); + WorkbenchBase = NULL; + } + if (NULL != IntuitionBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)IIntuition); +#endif /* __amigaos4__ */ + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } + if (NULL != UtilityBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)IUtility); +#endif /* __amigaos4__ */ + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } + if (NULL != GfxBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)IGraphics); +#endif /* __amigaos4__ */ + CloseLibrary((struct Library *) GfxBase); + GfxBase = NULL; + } + if (NULL != IconBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)IIcon); +#endif /* __amigaos4__ */ + CloseLibrary(IconBase); + IconBase = NULL; + } + if (NULL != DOSBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)IDOS); +#endif /* __amigaos4__ */ + CloseLibrary((struct Library *) DOSBase); + DOSBase = NULL; + } + } +} + +//----------------------------------------------------------------------------- + +#if !defined(__SASC) +// Replacement for SAS/C library functions + +#if !defined(__MORPHOS__) +// Replacement for SAS/C library functions + +size_t stccpy(char *dest, const char *src, size_t MaxLen) +{ + size_t Count = 0; + + while (*src && MaxLen > 1) + { + *dest++ = *src++; + MaxLen--; + Count++; + } + *dest = '\0'; + Count++; + + return Count; +} +#endif /*__MORPHOS__*/ + +#ifndef __amigaos4__ +void exit(int x) +{ + (void) x; + while (1) + ; +} +#endif /* __amigaos4__ */ + +#endif /* !defined(__SASC) */ +//----------------------------------------------------------------------------- + +static BOOL GetARGBfromSAC(struct ARGBHeader *argbh, + const struct ScalosBitMapAndColor *sac) +{ + UBYTE *ImageLine = NULL; + struct BitMap *TempBM; + BOOL Success = FALSE; + + do { + struct ARGB *argb; + ULONG y; + struct RastPort rp; + struct RastPort TempRp; + size_t ImgSize; + + InitRastPort(&rp); + InitRastPort(&TempRp); + + rp.BitMap = sac->sac_BitMap; + d1(KPrintF(__FILE__ "/" "%s/%s/%ld: rp.BitMap=%08lx\n", __FILE__, __FUNC__, __LINE__, rp.BitMap)); + + // setup temp. RastPort for use by WritePixelLine8() + TempRp.Layer = NULL; + TempRp.BitMap = TempBM = AllocBitMap(TEMPRP_WIDTH(sac->sac_Width), 1, 8, 0, NULL); + if (NULL == TempBM) + break; + + ImageLine = MyAllocVecPooled(PIXELARRAY8_BUFFERSIZE(sac->sac_Width, 1)); + if (NULL == ImageLine) + break; + + argbh->argb_Width = sac->sac_Width; + argbh->argb_Height = sac->sac_Height; + + ImgSize = argbh->argb_Width * argbh->argb_Height; + + argbh->argb_ImageData = MyAllocVecPooled(ImgSize * sizeof(struct ARGB)); + if (NULL == argbh->argb_ImageData) + break; + + d1(KPrintF(__FILE__ "/" "%s/%s/%ld: sac_TransparentColor=%ld\n", __FILE__, __FUNC__, __LINE__, sac->sac_TransparentColor)); + + // nothing can go wrong from here on + Success = TRUE; + + d1(KPrintF("%s/%s/%ld: NumColors=%lu\n", __FILE__, __FUNC__, __LINE__, sac->sac_NumColors)); + + for (y = 0, argb = argbh->argb_ImageData; y < argbh->argb_Height; y++) + { + ULONG x; + const UBYTE *ImgLinePtr; + + d1(KPrintF("%s/%s/%ld: y=%ld\n", __FILE__, __FUNC__, __LINE__, y)); + + ReadPixelLine8(&rp, 0, y, sac->sac_Width, ImageLine, &TempRp); + + ImgLinePtr = ImageLine; + for (x = 0; x < argbh->argb_Width; x++, argb++, ImgLinePtr++) + { + ULONG *PalettePtr = sac->sac_ColorTable + 3 * *ImgLinePtr; + + argb->Red = PalettePtr[0] >> 24; + argb->Green = PalettePtr[1] >> 24; + argb->Blue = PalettePtr[2] >> 24; + + if (SAC_TRANSPARENT_NONE == sac->sac_TransparentColor) + argb->Alpha = 0xff; + else + argb->Alpha = (*ImgLinePtr == sac->sac_TransparentColor) ? 0 : 0xff; + } + } + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + } while (0); + + if (ImageLine) + MyFreeVecPooled(ImageLine); + if (TempBM) + FreeBitMap(TempBM); + + return Success; +} + +//----------------------------------------------------------------------------- + +static void FreePngImage(struct ARGBHeader *argbh, BOOL DoFreeIcon) +{ + if (argbh->argb_ImageData && DoFreeIcon) + { + d1(KPrintF("%s/%s/%ld: argb_ImageData=%08lx\n", __FILE__, __FUNC__, __LINE__, argbh->argb_ImageData)); + MyFreeVecPooled(argbh->argb_ImageData); + argbh->argb_ImageData = NULL; + } +} + +//----------------------------------------------------------------------------- + +static void DoUpdateWb(struct InstanceData *inst, CONST_STRPTR SavePath) +{ + BPTR fLock; + BPTR pLock = (BPTR)NULL; + + do { + CONST_STRPTR fName; + + fLock = Lock(SavePath, ACCESS_READ); + if ((BPTR)NULL == fLock) + break; + + pLock = ParentDir(fLock); + if ((BPTR)NULL == pLock) + break; + + fName = FilePart(SavePath); + + UpdateWorkbench(fName, pLock, UPDATEWB_ObjectAdded); + } while (0); + + if (pLock) + UnLock(pLock); + if (fLock) + UnLock(fLock); +} + +//----------------------------------------------------------------------------- + +static void SetParentAttributes(Class *cl, Object *o) +{ + struct InstanceData *inst = INST_DATA(cl, o); + + SetAttrs(o, + GA_Width, inst->id_NormalImage.argb_Width, + GA_Height, inst->id_NormalImage.argb_Height, + TAG_END); + + d1(KPrintF("%s/%s/%ld: Width=%ld Height=%ld\n", __FILE__, __FUNC__, __LINE__,\ + inst->id_NormalImage.argb_Width, inst->id_NormalImage.argb_Height)); + d1(KPrintF("%s/%s/%ld: id_Type=%lu\n", __FILE__, __FUNC__, __LINE__, inst->id_Type)); + + SetAttrs(o, + IDTA_CopyARGBImageData, FALSE, + IDTA_ARGBImageData, (ULONG) &inst->id_NormalImage, + IDTA_ToolTypes, (ULONG) inst->id_ToolTypes, + IDTA_Stacksize, inst->id_StackSize, + IDTA_DefaultTool, (ULONG) inst->id_DefaultTool, + IDTA_ToolWindow, (ULONG) inst->id_ToolWindow, + IDTA_Type, inst->id_Type, + TAG_END); + + if (inst->id_SelectedImage.argb_ImageData) + { + SetAttrs(o, + IDTA_CopySelARGBImageData, FALSE, + IDTA_SelARGBImageData, (ULONG) &inst->id_SelectedImage, + TAG_END); + } + + switch (inst->id_Type) + { + case WBDRAWER: + case WBDISK: + case WBGARBAGE: + d1(KPrintF("%s/%s/%ld: dd_CurrentX=%ld dd_CurrentY=%ld\n", \ + __FILE__, __FUNC__, __LINE__, inst->id_DrawerData.dd_CurrentX, \ + inst->id_DrawerData.dd_CurrentY)); + d1(KPrintF("%s/%s/%ld: dd_Flags=%08lx dd_ViewModes=%08lx\n", __FILE__, \ + __FUNC__, __LINE__, inst->id_DrawerData.dd_Flags, inst->id_DrawerData.dd_ViewModes)); + + SetAttrs(o, + IDTA_WindowRect, (ULONG) &inst->id_DrawerData.dd_NewWindow, + IDTA_WinCurrentX, inst->id_DrawerData.dd_CurrentX, + IDTA_WinCurrentY, inst->id_DrawerData.dd_CurrentY, + IDTA_Flags, inst->id_DrawerData.dd_Flags, + IDTA_ViewModes, inst->id_DrawerData.dd_ViewModes, + TAG_END); + break; + default: + break; + } +} + +//----------------------------------------------------------------------------- + + diff --git a/scalos/datatypes/PNGIcons/PNGIconDt.h b/scalos/datatypes/PNGIcons/PNGIconDt.h new file mode 100644 index 000000000..df2065a73 --- /dev/null +++ b/scalos/datatypes/PNGIcons/PNGIconDt.h @@ -0,0 +1,260 @@ +// PNGIconDt.h +// $Date$ +// $Revision$ + + +#ifndef PNGICONDT_H +#define PNGICONDT_H + +#include +#include +#include +#include + +#include + +//----------------------------------------------------------------------------- + +#define MAX_FILENAME 1024 + +#define MINSTACKSIZE 8192 + +#define MAXICONWIDTH 256 +#define MAXICONHEIGHT 256 + +//----------------------------------------------------------------------------- + +#if !defined(__AROS__) +#define BNULL ((BPTR) NULL) +#endif + +#define MAKE_ARGB(r,g,b) ( ((r) << 16) + ((g) << 8) + (b) ) + +// Width for TempRp.BitMap for ReadPixelLine8() and WritePixelLine8() +#define TEMPRP_WIDTH(width) (8 * ((((width) + 15) >> 4) << 1)) + +//----------------------------------------------------------------------------- + +#define MEMPOOL_MEMFLAGS MEMF_ANY +#define MEMPOOL_PUDDLESIZE 32768 +#define MEMPOOL_THRESHSIZE 8192 + +//----------------------------------------------------------------------------- + +#define LIB_VERSION 40 +#define LIB_REVISION 21 + +extern char ALIGNED libName[]; +extern char ALIGNED libIdString[]; + +//---------------------------------------------------------------------------- + +struct PngIconObjectDtLibBase + { + struct ClassLibrary nib_ClassLibrary; + + struct SegList *nib_SegList; + + UBYTE nib_Initialized; + }; + +//----------------------------------------------------------------------------- + +LIBFUNC_PROTO(ObtainInfoEngine, libbase, ULONG); + +ULONG InitDatatype(struct PngIconObjectDtLibBase *dtLib); +ULONG OpenDatatype(struct PngIconObjectDtLibBase *dtLib); +void CloseDatatype(struct PngIconObjectDtLibBase *dtLib); + +//----------------------------------------------------------------------------- + +struct InstanceData + { + char id_FileName[MAX_FILENAME]; + + ULONG id_Type; // WB Icon Type + + BOOL id_DoNotFreeIcon; + BOOL id_IconHunkLoaded; // set after first Icon hunk is read, ensures any following icon hunk is ignored + BOOL id_TypeSet; // set if PNGICONA_TYPE encountered - no more type guessing if set + + LONG id_DirEntryType; // fib_DirEntryType + + LONG id_CurrentX; + LONG id_CurrentY; + + ULONG id_StackSize; + + struct DrawerData id_DrawerData; // Args for drawer window + + // PNG Icon data - also valid for Color icons + struct ARGBHeader id_NormalImage; + struct ARGBHeader id_SelectedImage; + + struct List id_ToolTypesList; + ULONG id_ToolTypesCount; + + STRPTR id_ToolWindow; + STRPTR id_DefaultTool; + STRPTR *id_ToolTypes; + ULONG id_ToolTypesLength; // allocated length of id_ToolTypes + }; + +//----------------------------------------------------------------------------- + +#define PNGICONDUMMY TAG_USER + 0x1000 + +#define PNGICONA_XPOS (PNGICONDUMMY + 0x01) +#define PNGICONA_YPOS (PNGICONDUMMY + 0x02) +#define PNGICONA_DRAWERXPOS (PNGICONDUMMY + 0x03) +#define PNGICONA_DRAWERYPOS (PNGICONDUMMY + 0x04) +#define PNGICONA_DRAWERWIDTH (PNGICONDUMMY + 0x05) +#define PNGICONA_DRAWERHEIGHT (PNGICONDUMMY + 0x06) +#define PNGICONA_DRAWERVIEWMODE (PNGICONDUMMY + 0x07) +#define PNGICONA_TOOLWINDOW (PNGICONDUMMY + 0x08) +#define PNGICONA_STACKSIZE (PNGICONDUMMY + 0x09) +#define PNGICONA_DEFTOOL (PNGICONDUMMY + 0x0A) // Identifies a project icon, may be null +#define PNGICONA_TOOLTYPE (PNGICONDUMMY + 0x0B) // As many instances as needed +#define PNGICONA_SORTMODE (PNGICONDUMMY + 0x0c) +#define PNGICONA_OFFSETX (PNGICONDUMMY + 0x0d) +#define PNGICONA_OFFSETY (PNGICONDUMMY + 0x0e) +#define PNGICONA_TYPE (PNGICONDUMMY + 0x0f) // icon type WBDRAWER etc. + +// Viewmodes for PNGICONA_DRAWERVIEWMODE +// Actually Ambient supports only 2 values: 2 (only icons, by icon) and 3 (all files, by icon) +// For now we extend and interpret the bits as follows: +// bit0: 0=show only icons 1=show all files +// bit1: 0=view by text 1=view by icon +// bit2 and 3, just introduced to maintain WB compatibility, mean the sorting criterium: +// 00=by name 01=by date 02=by size 03=by type + +#define PNGDM_SHOWALLFILES 0x00000001 // 0=shows only icons +#define PNGDM_VIEWBYICON 0x00000002 // 0=view by text +#define PNGDM_SORTMODEMASK 0x0000000C +#define PNGDM_SORTBYNAME 0x00000000 +#define PNGDM_SORTBYDATE 0x00000004 +#define PNGDM_SORTBYSIZE 0x00000008 +#define PNGDM_SORTBYTYPE 0x0000000C + +#define PNGHEADER1 0x89504E47 +#define PNGHEADER2 0x0D0A1A0A +#define PNGIHDRHEADER MAKE_ID('I','H','D','R') +#define PNGIDATHEADER MAKE_ID('I','D','A','T') +#define PNGICONHEADER MAKE_ID('i','c','O','n') +#define PNGTERMHEADER MAKE_ID('I','E','N','D') +#define PNGIENDCRC 0xAE426082 // CRC of IEND hunk is obviously always the same + +// PNG format: PNGHEADER1 and 2,(chunks),(end chunk) +// PNG chunk format: LONG DataLength, LONG ChunkID, (data), LONG DataCRC + +struct PngChunk + { + ULONG DataLength; + ULONG ID; + UBYTE *Data; + }; + +typedef struct + { + ULONG Width; + ULONG Height; + UBYTE Depth; + UBYTE ColorType; + UBYTE Compression; + UBYTE Filter; + UBYTE Interlace; + } IHDR; +#define IHDR_SIZE 13 // WARNING: sizeof(such a badly aligned struct) is unpracticable !!!! + + +struct PiIconSpecial +{ + struct DiskObject *Myself; // Security backpointer + ULONG Flags; // See defines below + ULONG Width, Height; // Icon size + + // PNG Icon data - also valid for Color icons + + ULONG *ImgData; // Points to a 32-bits ARGB array + UBYTE *IconHunk; // Points to the icOn hunk into PNGFile. Null if "vergin" icon + APTR *PNGFile; // Cache of original png icon file (mainly for writing) + ULONG PNGFileSize; // Size of PNGFile buffer + UBYTE *FakeImgData; // Buffer containing a special ID (see below) plus original icon filename + STRPTR *TTArray; // At icon creation is == icon->do_ToolTypes. See notes in the source. + STRPTR DefaultTool; + struct Image Template; // Planar workaround for Workbench to show something when dragging +}; + +//----------------------------------------------------------------------------- + +#define ISF_PNGICON 0x00000001 // 0=Normal icon, no PNG +#define ISF_PNGHASALPHA 0x00000002 // PNG icon has alpha +#define ISF_ALTIMAGE 0x00000004 // Icon has alternate image (only color icons for now) + +struct TTNode +{ + struct Node Node; + ULONG Length; // Incl. zero + char ToolType[1]; +}; + +//----------------------------------------------------------------------------- + +#if !defined(__amigaos4__) && !defined(__AROS__) +VOID UpdateWorkbench(CONST_STRPTR name, BPTR parentlock, LONG action); + +#if defined(__MORPHOS__) + +#ifndef __PPCINLINE_MACROS_H +#include +#endif /* !__PPCINLINE_MACROS_H */ + +#define UpdateWorkbench(__p0, __p1, __p2) \ + LP3NR(30, UpdateWorkbench, \ + CONST_STRPTR , __p0, a0, \ + BPTR, __p1, a1, \ + LONG, __p2, d0, \ + , WB_BASE_NAME, 0, 0, 0, 0, 0, 0) + +#else + +#ifdef __SASC + +#ifdef __CLIB_PRAGMA_LIBCALL +#pragma libcall WorkbenchBase UpdateWorkbench 01e 09803 +#endif /* __CLIB_PRAGMA_LIBCALL */ + +#else + +#define WBInfo(lock, name, screen) \ + LP3NR(30, UpdateWorkbench, CONST_STRPTR, name, a0, BPTR, parentlock, a1, LONG, action, d0, \ + , WB_BASE_NAME) + +#endif /* __SASC */ + +#endif /* __MORPHOS__ */ + +#endif /* !__amigaos4__ */ + +//----------------------------------------------------------------------------- + +#define Sizeof(array) (sizeof(array) / sizeof((array)[0])) + +//----------------------------------------------------------------------------- + +#define d1(x) ; +#define d2(x) x; + +//#define TIMESTAMPS +#define TIMESTAMP_d1() ; +#define TIMESTAMP_d2() \ + { \ + struct EClockVal ev; \ + ULONG ticks; \ + ticks = ReadEClock(&ev); \ + KPrintF("%s/%s/%ld: ticks=%lu hi=%8lu lo=%8lu\n", __FILE__, __FUNC__, __LINE__, ticks, ev.ev_hi, ev.ev_lo); \ + } + +//----------------------------------------------------------------------------- + +#endif /* PNGICONDT_H */ diff --git a/scalos/datatypes/PNGIcons/PNGIconProto.h b/scalos/datatypes/PNGIcons/PNGIconProto.h new file mode 100644 index 000000000..9f40a5992 --- /dev/null +++ b/scalos/datatypes/PNGIcons/PNGIconProto.h @@ -0,0 +1,64 @@ +// PNGIconProto.h +// $Date$ +// $Revision$ + + +#ifndef PNGICONPROTO_H +#define PNGICONPROTO_H + +//----------------------------------------------------------------------------- + +// defined in PNGIconDt.c +APTR MyAllocVecPooled(size_t Size); +void MyFreeVecPooled(APTR mem); + +//----------------------------------------------------------------------------- + +// defined in LoadPngIcon.c +BOOL LoadPngIcon(struct InstanceData *inst, CONST_STRPTR filename, BPTR IconFh, const struct WBArg *ObjectLocation); +void HandleIconHunk(struct InstanceData *inst, const UBYTE *dataptr, size_t Length); + +//----------------------------------------------------------------------------- + +// defined in GetPNGPicture.c +BOOL GetPngPicture(struct InstanceData *inst, BPTR file, + ULONG SigBytesRead, struct ARGBHeader *argbh); + +//----------------------------------------------------------------------------- + +// defined in GenTemplate.c +BOOL GenMask(struct InstanceData *inst, ULONG width, ULONG height); +BOOL GenAlpha(struct InstanceData *inst, struct ExtGadget *gg, ULONG width, ULONG height); + +//----------------------------------------------------------------------------- + +// defined in SavePngIcon.c +ULONG SavePngIcon(struct InstanceData *inst, CONST_STRPTR name, + struct ARGBHeader *NormalARGBImage, struct ARGBHeader *SelectedARGBImage); + +//----------------------------------------------------------------------------- + +// defined in libz +//int uncompress(UBYTE *dest, ULONG *destLen, UBYTE *source, ULONG sourceLen); + +//----------------------------------------------------------------------------- + +// defined in mempools.lib + +extern int _STI_240_InitMemFunctions(void); +extern void _STD_240_TerminateMemFunctions(void); + +//----------------------------------------------------------------------------- + +// Defined in debug.lib +#ifdef __AROS__ +#include +#define KPrintF kprintf +#else +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); +#endif + +//----------------------------------------------------------------------------- + +#endif /* PNGICONPROTO_H */ diff --git a/scalos/datatypes/PNGIcons/SavePngIcon.c b/scalos/datatypes/PNGIcons/SavePngIcon.c new file mode 100644 index 000000000..3771b4cbe --- /dev/null +++ b/scalos/datatypes/PNGIcons/SavePngIcon.c @@ -0,0 +1,547 @@ +// SavePngIcon.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#ifdef __amigaos4__ +#define Flush FFlush +#endif /* __amigaos4__ */ +#include + +#include + +#include +#include +#include +#include + +#include "png.h" +#include +#include "PNGIconDt.h" +#include "PNGIconProto.h" + +//----------------------------------------------------------------------------- + +static BOOL WritePng(struct InstanceData *inst, BPTR file, + struct PngChunk *IconChunk, struct ARGBHeader *ARGBImage); +static png_voidp PngAllocMem(png_structp png_ptr, png_size_t size); +static void PngFreeMem(png_structp png_ptr, png_voidp ptr); +static void PngWriteData(png_structp png_ptr, png_bytep data, png_size_t length); +static void PngFlushData(png_structp png_ptr); +static void PngError(png_structp png_ptr, png_const_charp error_message); +static void PngWarning(png_structp png_ptr, png_const_charp warning_message); +static BOOL GenerateIconHunk(struct InstanceData *inst, struct PngChunk *chunk); +static ULONG GetIconHunkSize(struct InstanceData *inst); +static ULONG *AddItem(ULONG *IconHunkPtr, size_t *Length, + ULONG tag, const void *Value, size_t ValueLength); + +//----------------------------------------------------------------------------- + +ULONG SavePngIcon(struct InstanceData *inst, CONST_STRPTR name, + struct ARGBHeader *NormalARGBImage, struct ARGBHeader *SelectedARGBImage) +{ + BPTR file = 0; + STRPTR namedotinfo; + ULONG success = FALSE; + struct PngChunk IconChunk; + + do { + memset(&IconChunk, 0, sizeof(IconChunk)); + + // Build "filename.info" + namedotinfo = MyAllocVecPooled(1 + strlen(name) + 5); + if (NULL == namedotinfo) + { + SetIoErr(ERROR_NO_FREE_STORE); + break; + } + + strcpy(namedotinfo, name); + strcat(namedotinfo, ".info"); + + file = Open(namedotinfo, MODE_NEWFILE); + d1(KPrintF("%s/%s/%ld: file=%08lx\n", __FILE__, __FUNC__, __LINE__, file)); + if ((BPTR)NULL == file) + break; + + // Generate icOn hunk + if (!GenerateIconHunk(inst, &IconChunk)) + break; + + if (!WritePng(inst, file, &IconChunk, NormalARGBImage)) + break; + if (SelectedARGBImage->argb_ImageData) + { + if (!WritePng(inst, file, &IconChunk, SelectedARGBImage)) + break; + } + + d1(KPrintF("%s/%s/%ld: DataLength=%lu\n", __FILE__, __FUNC__, __LINE__, IconChunk.DataLength)); + + success = TRUE; + } while (0); + + if (file) + Close(file); + if (IconChunk.Data) + MyFreeVecPooled(IconChunk.Data); + if (namedotinfo) + MyFreeVecPooled(namedotinfo); + + return success; +} + + +static BOOL WritePng(struct InstanceData *inst, BPTR file, + struct PngChunk *IconChunk, struct ARGBHeader *ARGBImage) +{ + BOOL Success = FALSE; + png_structp png_ptr; + png_infop info_ptr; + png_bytepp row_pointers = NULL; + + do { + struct ARGB *argb; + ULONG y; + + /* Create and initialize the png_struct with the desired error handler + * functions. If you want to use the default stderr and longjump method, + * you can supply NULL for the last three parameters. We also check that + * the library version is compatible with the one used at compile time, + * in case we are using dynamically linked libraries. REQUIRED. + */ + png_ptr = png_create_write_struct_2(PNG_LIBPNG_VER_STRING, + (png_voidp) inst, PngError, PngWarning, + NULL, PngAllocMem, PngFreeMem); + + d1(KPrintF("%s/%s/%ld: png_ptr=%08lx\n", __FILE__, __FUNC__, __LINE__, png_ptr)); + if (png_ptr == NULL) + break; + + /* Allocate/initialize the image information data. REQUIRED */ + info_ptr = png_create_info_struct(png_ptr); + d1(KPrintF("%s/%s/%ld: info_ptr=%08lx\n", __FILE__, __FUNC__, __LINE__, info_ptr)); + if (info_ptr == NULL) + break; + + d1(KPrintF("%s/%s/%ld: png_jmpbuf=%08lx\n", __FILE__, __FUNC__, __LINE__, png_jmpbuf(png_ptr))); + if (NULL == png_jmpbuf(png_ptr)) + break; + + /* Set error handling. REQUIRED if you aren't supplying your own + * error handling functions in the png_create_write_struct() call. + */ + if (setjmp(png_jmpbuf(png_ptr))) + { + /* If we get here, we had a problem reading the file */ + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + Success = FALSE; + break; + } + + /* If you are using replacement read functions, instead of calling + * png_init_io() here you would call */ + png_set_write_fn(png_ptr, (void *) file, PngWriteData, + PngFlushData); + + /* Set the image information here. Width and height are up to 2^31, + * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on + * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY, + * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB, + * or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or + * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST + * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED + */ + png_set_IHDR(png_ptr, info_ptr, + ARGBImage->argb_Width, + ARGBImage->argb_Height, + 8, + PNG_COLOR_TYPE_RGB_ALPHA, + PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, + PNG_FILTER_TYPE_BASE); + + /* swap location of alpha bytes from ARGB to RGBA */ + png_set_swap_alpha(png_ptr); + + row_pointers = MyAllocVecPooled(sizeof(png_bytep) * ARGBImage->argb_Height); + d1(KPrintF("%s/%s/%ld: row_pointers=%08lx\n", __FILE__, __FUNC__, __LINE__, row_pointers)); + if (NULL == row_pointers) + break; + + argb = ARGBImage->argb_ImageData; + for (y = 0; y < ARGBImage->argb_Height; y++) + { + row_pointers[y] = (png_bytep) argb; + argb += ARGBImage->argb_Width; + } + + png_set_rows(png_ptr, info_ptr, row_pointers); + + /* Write the file header information. REQUIRED */ + png_write_info(png_ptr, info_ptr); + + /* write out the entire image data in one call */ + png_write_image(png_ptr, row_pointers); + + /* Write a PNG chunk - size, type, (optional) data, CRC. */ + png_write_chunk(png_ptr, (png_bytep) "icOn", IconChunk->Data, IconChunk->DataLength); + + /* It is REQUIRED to call this to finish writing the rest of the file */ + png_write_end(png_ptr, info_ptr); + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + Success = TRUE; + } while (0); + + if (row_pointers) + MyFreeVecPooled(row_pointers); + + /* clean up after the write, and free any memory allocated */ + png_destroy_write_struct(&png_ptr, &info_ptr); + + d1(KPrintF("%s/%s/%ld: Success=%ld\n", __FILE__, __FUNC__, __LINE__, Success)); + + return Success; +} + +static png_voidp PngAllocMem(png_structp png_ptr, png_size_t size) +{ + (void) png_ptr; + + return MyAllocVecPooled(size); +} + +static void PngFreeMem(png_structp png_ptr, png_voidp ptr) +{ + (void) png_ptr; + MyFreeVecPooled(ptr); +} + + +static void PngWriteData(png_structp png_ptr, png_bytep data, png_size_t length) +{ + BPTR fh = (BPTR) png_get_io_ptr(png_ptr); + + if (1 != FWrite(fh, data, length, 1)) + { +// png_error(); + } +} + +static void PngFlushData(png_structp png_ptr) +{ + BPTR fh = (BPTR) png_get_io_ptr(png_ptr); + + if (!Flush(fh)) + { +// png_error(); + } +} + + +static void PngError(png_structp png_ptr, png_const_charp error_message) +{ + d1(KPrintF("%s/%s/%ld: png_ptr=%08lx message=<%s>\n", \ + __FILE__, __FUNC__, __LINE__, png_ptr, error_message)); + + longjmp(png_jmpbuf(png_ptr), 1); +} + + +static void PngWarning(png_structp png_ptr, png_const_charp warning_message) +{ + d1(KPrintF("%s/%s/%ld: png_ptr=%08lx message=<%s>\n", \ + __FILE__, __FUNC__, __LINE__, png_ptr, warning_message)); +// png_default_warning(png_ptr, warning_message); +} + + +static ULONG GetIconHunkSize(struct InstanceData *inst) +{ + // Calculate allocation size for icOn hunk + size_t Length = 0; + ULONG tag; + + // Icon Type + Length += sizeof(ULONG) + sizeof(ULONG); + + // Write out ToolTypes + if (inst->id_ToolTypes) + { + STRPTR *tt; + + for(tt = inst->id_ToolTypes; *tt; tt++) + { + Length += sizeof(ULONG) + 1 + strlen(*tt); + } + } + + d1(kprintf("%s/%s/%ld: Length=%lu\n", __FILE__, __FUNC__, __LINE__, Length)); + + // Write out Stack Size + if ((inst->id_Type == WBPROJECT) || (inst->id_Type == WBTOOL)) + { + Length += sizeof(ULONG) + sizeof(inst->id_StackSize); + } + + d1(kprintf("%s/%s/%ld: Length=%lu\n", __FILE__, __FUNC__, __LINE__, Length)); + + + // Write out Default Tool + if (inst->id_Type == WBPROJECT) + { + if (inst->id_DefaultTool) + { + Length += sizeof(ULONG) + 1 + strlen(inst->id_DefaultTool); + } + else + { + Length += sizeof(ULONG) + 1; + } + } + + d1(kprintf("%s/%s/%ld: Length=%lu\n", __FILE__, __FUNC__, __LINE__, Length)); + + // Write out tool window + if (inst->id_ToolWindow) + { + Length += sizeof(ULONG) + 1 + strlen(inst->id_ToolWindow); + } + + d1(kprintf("%s/%s/%ld: Length=%lu\n", __FILE__, __FUNC__, __LINE__, Length)); + + // Write out X and Y pos + + if ((inst->id_CurrentX != NO_ICON_POSITION) && (inst->id_CurrentY != NO_ICON_POSITION)) + { + Length += sizeof(ULONG) + sizeof(inst->id_CurrentX); + Length += sizeof(ULONG) + sizeof(inst->id_CurrentY); + } + + d1(kprintf("%s/%s/%ld: id_Type=%lu\n", __FILE__, __FUNC__, __LINE__, inst->id_Type)); + + + // Write out Drawer or Disk data + + if((inst->id_Type == WBDISK)||(inst->id_Type == WBDRAWER)||(inst->id_Type == WBGARBAGE)) + { + ULONG flags = inst->id_DrawerData.dd_Flags; + UWORD viewmodes = inst->id_DrawerData.dd_ViewModes; + + // Write out viewmode and sortmode stuff + if(!((flags == DDFLAGS_SHOWDEFAULT) && (viewmodes == DDVM_BYDEFAULT))) + { + Length += sizeof(ULONG) + sizeof(tag); + + // Write out sort mode + if (inst->id_DrawerData.dd_ViewModes >= DDVM_BYNAME) + Length += sizeof(ULONG) + sizeof(tag); + } + + d1(kprintf("%s/%s/%ld: Length=%lu\n", __FILE__, __FUNC__, __LINE__, Length)); + + // Write out drawer size and position + Length += 4 * (sizeof(ULONG) + sizeof(tag)); + + // Write out dd_CurrentX and dd_CurrentY + Length += 2 * (sizeof(ULONG) + sizeof(tag)); + } + + d1(kprintf("%s/%s/%ld: Length=%lu\n", __FILE__, __FUNC__, __LINE__, Length)); + + return Length; +} + + +// Generate icOn hunk +static BOOL GenerateIconHunk(struct InstanceData *inst, struct PngChunk *chunk) +{ + BOOL Success = FALSE; + + do { + ULONG *IconHunkPtr; + size_t Length; + ULONG tag; + + chunk->ID = PNGICONHEADER; + chunk->DataLength = GetIconHunkSize(inst); + + chunk->Data = MyAllocVecPooled(chunk->DataLength); + d1(KPrintF("%s/%s/%ld: Data=%08lx Length=%lu\n", __FILE__, __FUNC__, __LINE__, chunk->Data, Length)); + if (NULL == chunk->Data) + { + SetIoErr(ERROR_NO_FREE_STORE); + break; + } + + IconHunkPtr = (ULONG *) chunk->Data; + Length = chunk->DataLength; + d1(KPrintF("%s/%s/%ld: IconHunkPtr=%08lx Length=%lu\n", __FILE__, __FUNC__, __LINE__, IconHunkPtr, Length)); + d1(KPrintF("%s/%s/%ld: id_Type=%lu\n", __FILE__, __FUNC__, __LINE__, inst->id_Type)); + + // write icon type + tag = SCA_LONG2BE(inst->id_Type); + IconHunkPtr = AddItem(IconHunkPtr, &Length, PNGICONA_TYPE, &tag, sizeof(ULONG)); + + // Write out ToolTypes + if (inst->id_ToolTypes) + { + STRPTR *tt; + + for(tt = inst->id_ToolTypes; *tt; tt++) + { + IconHunkPtr = AddItem(IconHunkPtr, &Length, PNGICONA_TOOLTYPE, *tt, 1 + strlen(*tt)); + } + } + + d1(kprintf("%s/%s/%ld: Length=%lu\n", __FILE__, __FUNC__, __LINE__, Length)); + + // Write out Stack Size + if ((inst->id_Type == WBPROJECT) || (inst->id_Type == WBTOOL)) + { + tag = SCA_LONG2BE(inst->id_StackSize); + IconHunkPtr = AddItem(IconHunkPtr, &Length, PNGICONA_STACKSIZE, &tag, sizeof(inst->id_StackSize)); + } + + d1(KPrintF("%s/%s/%ld: IconHunkPtr=%08lx Length=%lu\n", __FILE__, __FUNC__, __LINE__, IconHunkPtr, Length)); + + // Write out Default Tool + if (inst->id_Type == WBPROJECT) + { + if (inst->id_DefaultTool) + { + IconHunkPtr = AddItem(IconHunkPtr, &Length, PNGICONA_DEFTOOL, inst->id_DefaultTool, 1 + strlen(inst->id_DefaultTool)); + } + else + { + IconHunkPtr = AddItem(IconHunkPtr, &Length, PNGICONA_DEFTOOL, "", 1); + } + } + + d1(KPrintF("%s/%s/%ld: IconHunkPtr=%08lx Length=%lu\n", __FILE__, __FUNC__, __LINE__, IconHunkPtr, Length)); + + // Write out tool window + if (inst->id_ToolWindow) + { + IconHunkPtr = AddItem(IconHunkPtr, &Length, PNGICONA_TOOLWINDOW, inst->id_ToolWindow, 1 + strlen(inst->id_ToolWindow)); + } + + d1(KPrintF("%s/%s/%ld: IconHunkPtr=%08lx Length=%lu\n", __FILE__, __FUNC__, __LINE__, IconHunkPtr, Length)); + + // Write out X and Y pos + + if ((inst->id_CurrentX != NO_ICON_POSITION) && (inst->id_CurrentY != NO_ICON_POSITION)) + { + tag = SCA_LONG2BE(inst->id_CurrentX); + d1(KPrintF("%s/%s/%ld: IconHunkPtr=%08lx Length=%lu\n", __FILE__, __FUNC__, __LINE__, IconHunkPtr, Length)); + IconHunkPtr = AddItem(IconHunkPtr, &Length, PNGICONA_XPOS, &tag, sizeof(inst->id_CurrentX)); + d1(KPrintF("%s/%s/%ld: IconHunkPtr=%08lx Length=%lu\n", __FILE__, __FUNC__, __LINE__, IconHunkPtr, Length)); + tag = SCA_LONG2BE(inst->id_CurrentY); + IconHunkPtr = AddItem(IconHunkPtr, &Length, PNGICONA_YPOS, &tag, sizeof(inst->id_CurrentY)); + d1(KPrintF("%s/%s/%ld: IconHunkPtr=%08lx Length=%lu\n", __FILE__, __FUNC__, __LINE__, IconHunkPtr, Length)); + } + + d1(kprintf("%s/%s/%ld: id_Type=%lu\n", __FILE__, __FUNC__, __LINE__, inst->id_Type)); + + + // Write out Drawer or Disk data + + if((inst->id_Type == WBDISK)||(inst->id_Type == WBDRAWER)||(inst->id_Type == WBGARBAGE)) + { + ULONG flags = inst->id_DrawerData.dd_Flags; + UWORD viewmodes = inst->id_DrawerData.dd_ViewModes; + + // Write out viewmode and sortmode stuff + if(!((flags == DDFLAGS_SHOWDEFAULT) && (viewmodes == DDVM_BYDEFAULT))) + { + if (flags == DDFLAGS_SHOWDEFAULT) + flags = DDFLAGS_SHOWICONS; + if (viewmodes == DDVM_BYDEFAULT) + viewmodes = DDVM_BYICON; + + tag = 0; + if (flags & DDFLAGS_SHOWALL) + tag |= PNGDM_SHOWALLFILES; // WB inconsistancy + if (viewmodes == DDVM_BYICON) + tag |= PNGDM_VIEWBYICON; + else + tag |=((viewmodes-DDVM_BYNAME)<<2); + + tag = SCA_LONG2BE(tag); + IconHunkPtr = AddItem(IconHunkPtr, &Length, PNGICONA_DRAWERVIEWMODE, &tag, sizeof(tag)); + + // Write out sort mode + if (inst->id_DrawerData.dd_ViewModes >= DDVM_BYNAME) + { + tag = SCA_LONG2BE(inst->id_DrawerData.dd_ViewModes - DDVM_BYNAME); + IconHunkPtr = AddItem(IconHunkPtr, &Length, PNGICONA_SORTMODE, &tag, sizeof(tag)); + } + + d1(KPrintF("%s/%s/%ld: IconHunkPtr=%08lx Length=%lu\n", __FILE__, __FUNC__, __LINE__, IconHunkPtr, Length)); + } + + d1(KPrintF("%s/%s/%ld: IconHunkPtr=%08lx Length=%lu\n", __FILE__, __FUNC__, __LINE__, IconHunkPtr, Length)); + + // Write out drawer size and position + tag = SCA_LONG2BE(inst->id_DrawerData.dd_NewWindow.LeftEdge); + IconHunkPtr = AddItem(IconHunkPtr, &Length, PNGICONA_DRAWERXPOS, &tag, sizeof(tag)); + + tag = SCA_LONG2BE(inst->id_DrawerData.dd_NewWindow.TopEdge); + IconHunkPtr = AddItem(IconHunkPtr, &Length, PNGICONA_DRAWERYPOS, &tag, sizeof(tag)); + + tag = SCA_LONG2BE(inst->id_DrawerData.dd_NewWindow.Width); + IconHunkPtr = AddItem(IconHunkPtr, &Length, PNGICONA_DRAWERWIDTH, &tag, sizeof(tag)); + + tag = SCA_LONG2BE(inst->id_DrawerData.dd_NewWindow.Height); + IconHunkPtr = AddItem(IconHunkPtr, &Length, PNGICONA_DRAWERHEIGHT, &tag, sizeof(tag)); + + d1(KPrintF("%s/%s/%ld: IconHunkPtr=%08lx Length=%lu\n", __FILE__, __FUNC__, __LINE__, IconHunkPtr, Length)); + + // Write out dd_CurrentX and dd_CurrentY + tag = SCA_LONG2BE(inst->id_DrawerData.dd_CurrentX); + IconHunkPtr = AddItem(IconHunkPtr, &Length, PNGICONA_OFFSETX, &tag, sizeof(tag)); + + tag = SCA_LONG2BE(inst->id_DrawerData.dd_CurrentY); + /* IconHunkPtr = */ AddItem(IconHunkPtr, &Length, PNGICONA_OFFSETY, &tag, sizeof(tag)); + } + + d1(KPrintF("%s/%s/%ld: IconHunkPtr=%08lx Length=%lu\n", __FILE__, __FUNC__, __LINE__, IconHunkPtr, Length)); + + Success = TRUE; + } while (0); + + return Success; +} + + +static ULONG *AddItem(ULONG *IconHunkPtr, size_t *Length, + ULONG tag, const void *Value, size_t ValueLength) +{ + if (*Length >= sizeof(tag) + ValueLength) + { + *IconHunkPtr++ = SCA_LONG2BE(tag); + + if (ValueLength) + { + memcpy(IconHunkPtr, Value, ValueLength); + IconHunkPtr = (ULONG *) (((UBYTE *) IconHunkPtr) + ValueLength); + } + + *Length -= sizeof(tag) + ValueLength; + } + + return IconHunkPtr; +} + diff --git a/scalos/datatypes/PNGIcons/config.mk b/scalos/datatypes/PNGIcons/config.mk new file mode 100755 index 000000000..f83d500f5 --- /dev/null +++ b/scalos/datatypes/PNGIcons/config.mk @@ -0,0 +1,64 @@ +# $Date: 2012-08-10 13:47:28 +0200 (Fr, 10. Aug 2012) $ +# $Revision: 915 $ +############################################################################## + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################## + +MKDIR = mkdir -p #makedir force +DT_DIR = scalos:IconDatatypes/datatypes + +############################################################################## +# Check gcc + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS := -nostartfiles \ + -lpng \ + -lz \ + -lmempools \ + $(LFLAGS) \ +# -Wl,-Map,png.map \ +# --verbose + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += -nostartfiles \ + -lpng \ + -lz \ + -lm + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +LFLAGS += -nostartfiles \ + -larossupport \ + -lpng \ + -lz \ + -lm + +else + +############################################################################### +# AmigaOS + +LFLAGS += -ldebug -liconobject -lcybergraphics \ + -lmcpgfx -lz \ + -lnix -lamiga21 -lamiga -lstubs + +endif +endif +endif diff --git a/scalos/datatypes/PNGIcons/makefile b/scalos/datatypes/PNGIcons/makefile new file mode 100755 index 000000000..5d02e555c --- /dev/null +++ b/scalos/datatypes/PNGIcons/makefile @@ -0,0 +1,123 @@ +# makefile for PNG icon datatype +# using GNU make and SAS/C +# $Date$ +# $Revision$ +# $Id$ +##################################################################### + +ASRCS = +CSRCS = PNGIconDt-classic.c \ + PNGIconDt.c \ + LoadPngIcon.c \ + GetPNGPicture.c \ + SavePngIcon.c \ + +##################################################################### + +AS = phxass +SPLAT = sc:c/splat +LD = slink +CC = sc +MKDIR = mkdir -p #makedir force +LIBS = //SAS-lib/png.lib \ + //SAS-lib/z.lib \ + //SAS-lib/snprintf.lib \ + LIB:mempools.lib \ + LIB:scm.lib \ + LIB:sc.lib \ + LIB:debug.lib \ + LIB:amiga.lib +PRECOMP = Include:all.gst +DT_DIR = scalos:IconDatatypes/datatypes +OBJDIR = .sasobj + +.SUFFIXES: .asm + +############################################################# + +.PHONY: clean install nodebug + +##################################################################### + +CFLAGS = optimize nostackcheck nochkabort strcons debug=s \ + IGNORE=73 strmer nover streq \ + idir=sc:include/ \ + idir=include: \ + idir=//include +AFLAGS = QUIET m=68020 linedebug opt=NRQB i=include: +LNFLAGS = quiet batch noicons stripdebug +LNDBFLAGS = quiet batch noicons addsym +CSTARTUP = + +##################################################################### + +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(CSRCS:%.c=$(OBJDIR)/%.o) + +##################################################################### + +DTNAME = .bin_os3/pngiconobject.datatype +DTDBGNAME = $(DTNAME).debug + +##################################################################### + +all: $(DTNAME) \ + $(DTDBGNAME) + +##################################################################### + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +##################################################################### + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $< objectname $@ + +$(OBJDIR)/%.o : %.s + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +$(OBJDIR)/%.o : %.asm + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +##################################################################### + +$(DTNAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(OBJS) TO $(DTNAME) LIB $(LIBS) $(LNFLAGS) + +$(DTDBGNAME): $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LD) FROM $(OBJS) TO $(DTDBGNAME) LIB $(LIBS) $(LNDBFLAGS) + +##################################################################### + +$(OBJDIR)/PNGIconDt-classic.o : PNGIconDt.c PngIconDt.h PNGIconProto.h +$(OBJDIR)/PNGIconDt.o : PNGIconDt.c PngIconDt.h PNGIconProto.h +$(OBJDIR)/LoadPngIcon.o : LoadPngIcon.c PngIconDt.h PNGIconProto.h +$(OBJDIR)/SavePngIcon.o : SavePngIcon.c PngIconDt.h PNGIconProto.h + +##################################################################### + +install: + @printf '\033[32mFlushing memory...\033[0m\n' + avail flush + @printf '\033[32mInstall: \033[31m\033[1m$(DTNAME)\033[0m\n' + -@$(MKDIR) $(DT_DIR) + copy $(DTNAME) $(DT_DIR) + +##################################################################### + +clean: + @printf '\033[32mCleanup...\033[0m\n' + -@delete $(OBJS) $(DTNAME) $(DTNAME).debug + +############################################################# + +nodebug: + -@$(SPLAT) -s -o "d2(" "d1(" "#?.c" + +############################################################# + diff --git a/scalos/datatypes/PNGIcons/makefile-new b/scalos/datatypes/PNGIcons/makefile-new new file mode 100755 index 000000000..2675bacf7 --- /dev/null +++ b/scalos/datatypes/PNGIcons/makefile-new @@ -0,0 +1,78 @@ +# $Date: 2011-07-09 20:50:13 +0200 (Sa, 09. Jul 2011) $ +# $Revision: 759 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(OBJDIR)/PNGIconDt.o \ + $(OBJDIR)/LoadPngIcon.o \ + $(OBJDIR)/GetPNGPicture.o \ + $(OBJDIR)/SavePngIcon.o \ + +ifeq ($(MACHINE), ppc-amigaos) +OBJS += $(OBJDIR)/PNGIconDt-aos4.o +else +ifeq ($(MACHINE), i386-aros) +OBJS += $(OBJDIR)/PNGIconDt-aros.o +else +OBJS += $(OBJDIR)/PNGIconDt-classic.o +endif +endif + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Targets +# + +NAME = pngiconobject.datatype +NAME_DB = pngiconobject.datatype.debug + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + @$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + -@$(MKDIR) $(DT_DIR) + @copy $(BINDIR)/$(NAME) $(DT_DIR) + @avail flush + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* + +############################################################################## diff --git a/scalos/datatypes/config.mk b/scalos/datatypes/config.mk new file mode 100755 index 000000000..e7f4e0079 --- /dev/null +++ b/scalos/datatypes/config.mk @@ -0,0 +1,39 @@ +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += # + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += # + + +else + +############################################################################### +# AmigaOS and AROS + +LFLAGS += # + +endif +endif + diff --git a/scalos/datatypes/makefile b/scalos/datatypes/makefile new file mode 100644 index 000000000..b0727b4e8 --- /dev/null +++ b/scalos/datatypes/makefile @@ -0,0 +1,47 @@ +# makefile für Scalos Icon datatypes +# $Date$ +# $Revision$ +# $Id$ +############################################################# + +SUBDIRS = AmigaIconObj3.5 \ + AmigaIconObject \ + GlowIconObject \ + IconObject \ + PNGIcons \ + NewIcons \ + +############################################################# + +.PHONY: All install clean + +############################################################# + +define build_subdir +$(MAKE) -s --directory=$(1); +endef + +define install_subdir +$(MAKE) -s install --directory=$(1); +endef + +define clean_subdir +$(MAKE) -s clean --directory=$(1); +endef + +############################################################# + +All: + @$(foreach subdir,$(SUBDIRS),$(call build_subdir,$(subdir))) + +############################################################# + +install: + @$(foreach subdir,$(SUBDIRS),$(call install_subdir,$(subdir))) + +############################################################# + +clean: + @$(foreach subdir,$(SUBDIRS),$(call clean_subdir,$(subdir))) + +############################################################# diff --git a/scalos/datatypes/makefile-new b/scalos/datatypes/makefile-new new file mode 100755 index 000000000..56f3601b4 --- /dev/null +++ b/scalos/datatypes/makefile-new @@ -0,0 +1,38 @@ +# $Date: 2011-07-09 20:50:13 +0200 (Sa, 09. Jul 2011) $ +# $Revision: 759 $ +############################################################# +ifndef $(TOPLEVEL) + TOPLEVEL=$(shell pwd)/.. +endif + +############################################################################### + +include config.mk + +############################################################################### + +SUBDIRS = AmigaIconObj3.5 \ + AmigaIconObject \ + IconObject \ + PNGIcons \ + GlowIconObject + +ifneq ($(MACHINE), ppc-amigaos) +ifneq ($(MACHINE), i386-aros) +SUBDIRS += NewIcons +endif +endif + +############################################################################### + +.PHONY: all install clean bump dump + +all: all_subdirs + +clean: clean_subdirs + +install: install_subdirs + +nodebug: nodebug_subdirs + + diff --git a/scalos/gpl-3.0.txt b/scalos/gpl-3.0.txt new file mode 100755 index 000000000..94a9ed024 --- /dev/null +++ b/scalos/gpl-3.0.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/scalos/include/DefIcons.h b/scalos/include/DefIcons.h new file mode 100755 index 000000000..6140dd549 --- /dev/null +++ b/scalos/include/DefIcons.h @@ -0,0 +1,75 @@ +// DefIcons.h +// $Date$ +// $Revision$ + +#ifndef DEFICONS_H_INCLUDED +#define DEFICONS_H_INCLUDED + + +#if defined(__GNUC__) && !defined(mc68000) +#pragma pack(2) +#endif /* __GNUC__ */ + + +#define IS_TYPENODE(icontype) (MEMF_PUBLIC & TypeOfMem((void *) (icontype))) + +#define ACT_MATCH 1 /* arg1/2 = offset arg3 = length str = string */ +#define ACT_SEARCH 2 /* arg2 = length str = string */ +#define ACT_SEARCHSKIPSPACES 3 /* arg2 = length str = string */ +/* if length < 0, do a case unsensitive match */ + +#define ACT_FILESIZE 4 /* arg2 = file size */ +#define ACT_NAMEPATTERN 5 /* str = filename pattern */ +#define ACT_PROTECTION 6 /* arg1 = mask arg2 = protbits&mask */ +#define ACT_OR 7 /* an alternative description follows */ +#define ACT_ISASCII 8 /* this is used only by AsciiType */ + +#define ACT_DOSDEVICE 10 /* str = DOS device name like "CD0" or "DH0" */ +#define ACT_DEVICENAME 11 /* str = device name like "scsi.device" */ +#define ACT_CONTENTS 12 /* str = pattern match for device contents */ +#define ACT_MINSIZEMB 13 /* arg2 = minimum device size in MBytes */ +#define ACT_DOSTYPE 14 /* arg2 = length str = match string for DOS type like "DOS\0" */ + +#define ACT_MACROCLASS 20 /* this must be the ONLY ACT_xxx of the node. */ + /* (apart from ACT_END) */ + /* following descriptions are son of this one, but */ + /* this one will never be considered valid, i.e. */ + /* if none of the sons matches the file, we will */ + /* proceed with the following description. The parent */ + /* will be used only for icon picking purposes (e.g. */ + /* a class "picture" may contain "gif", "jpeg" and so */ + /* on, and if def_gif is missing def_picture will be used */ +#define ACT_END 0 + + + +#define TYPE_DOWN_LEVEL 1 /* following description is son of previous one */ +#define TYPE_UP_LEVEL 2 /* following description is brother of parent of previous one */ +#define TYPE_END 0 /* end of list */ + +struct Magic +{ + UBYTE action; + BYTE pad; + LONG arg1; + LONG arg2; + STRPTR str; + /* note: WORD aligned */ +}; + + +struct TypeNode +{ + struct TypeNode *tn_RightBrother; + struct TypeNode *tn_FirstSon; + struct TypeNode *tn_Parent; + Object *tn_IconObject; + STRPTR tn_Name; + struct Magic tn_Description[1]; +}; + +#if defined(__GNUC__) && !defined(mc68000) +#pragma pack() +#endif /* __GNUC__ */ + +#endif /* DEFICONS_H_INCLUDED */ diff --git a/scalos/include/MUIundoc.h b/scalos/include/MUIundoc.h new file mode 100755 index 000000000..5e36f4d4c --- /dev/null +++ b/scalos/include/MUIundoc.h @@ -0,0 +1,263 @@ +/*************************************************************************** +** The Hacker's include to MUI v1.8 :-) +** +** Copyright 1997-98 by Alessandro Zummo +** azummo@ita.flashnet.it +** +** This include is unofficial, use at your own risk! +** +** You can also find other undocumented tags in libraries/mui.h :-) +** +**************************************************************************** +** Class Tree +**************************************************************************** +** +** rootclass (BOOPSI's base class) +** +--Notify (implements notification mechanism) +** ! +--Area (base class for all GUI elements) +** ! +--Framedisplay (displays frame specification) +** ! ! \--Popframe (popup button to adjust a frame spec) +** ! +--Imagedisplay (displays image specification) +** ! ! \--Popimage (popup button to adjust an image spec) +** ! +--Pendisplay (displays a pen specification) +** ! ! \--Poppen (popup button to adjust a pen spec) +** ! +--Group (groups other GUI elements) +** ! +--Register (handles page groups with titles) +** ! ! \--Penadjust (group to adjust a pen) +** ! +--Frameadjust (group to adjust a frame) +** ! +--Imageadjust (group to adjust an image) +** +*/ + + +#ifndef MUI_UNDOC_H +#define MUI_UNDOC_H + + +//Uncomment this if you want be able to use all the undocumented features +//But remember to modify your libraries/mui.h include + +//#define UNDOC_HACK + + +/************************************************************************* +** Black box specification structures for images, pens, frames +*************************************************************************/ + +/* Defined in mui.h +struct MUI_PenSpec +{ + char buf[32]; +}; +*/ + +struct MUI_ImageSpec +{ + char buf[64]; +}; + +struct MUI_FrameSpec +{ + char buf[32]; +}; + + +// I'm not sure if MUI_ImageSpec and MUI_FrameSpec are 32 or 64 bytes wide. + +/************************************************************************* +** The real MUI_NotifyData structure +*************************************************************************/ + +#ifdef UNDOC_HACK + +struct MUI_NotifyData +{ + struct MUI_GlobalInfo *mnd_GlobalInfo; + ULONG mnd_UserData; + ULONG mnd_ObjectID; + ULONG priv1; + Object *mnd_ParentObject; // The name may not be the real one + ULONG priv3; + ULONG priv4; +}; + +#define _parent(obj) (muiNotifyData(obj)->mnd_ParentObject) /* valid between MUIM_Setup/Cleanup */ + +#else + +#define _parent(obj) xget(obj,MUIA_Parent) + +#endif + + +// The use of _parent(obj) macro is strictly forbidden! Use xget(obj,MUIA_Parent) instead. + + +/****************************************************************************/ +/** Flags **/ +/****************************************************************************/ + +#define MADF_OBJECTVISIBLE (1<<14) // The object is visible + +#define MUIMRI_INVIRTUALGROUP (1<<29) // The object is inside a virtual group +#define MUIMRI_ISVIRTUALGROUP (1<<30) // The object is a virtual group + + +/****************************************************************************/ +/** Crawling **/ +/****************************************************************************/ + +#ifdef _DCC +extern char MUIC_Crawling[]; +#else +#define MUIC_Crawling "Crawling.mcc" +#endif + +#define CrawlingObject MUI_NewObject(MUIC_Crawling + + +/****************************************************************************/ +/** Application **/ +/****************************************************************************/ + +/* Attributes */ + +#define MUIA_Application_UsedClasses 0x8042E9A7 /* V20 (!) */ + + +/****************************************************************************/ +/** Window **/ +/****************************************************************************/ + +/* Methods */ + +#define MUIM_Window_ActionIconify 0x80422cc0 /* V18 */ +#define MUIM_Window_Cleanup 0x8042ab26 /* Custom Class */ /* V18 */ +#define MUIM_Window_Setup 0x8042c34c /* Custom Class */ /* V18 */ + +struct MUIP_Window_Cleanup { ULONG MethodID; }; /* Custom Class */ +struct MUIP_Window_Setup { ULONG MethodID; }; /* Custom Class */ + +/* Attributes */ + +#define MUIA_Window_DisableKeys 0x80424c36 /* V15 isg ULONG */ + + +/****************************************************************************/ +/** Area **/ +/****************************************************************************/ + +/* Methods */ + +#define MUIM_DoDrag 0x804216bb /* V18 */ /* Custom Class */ +#define MUIM_CreateDragImage 0x8042eb6f /* V18 */ /* Custom Class */ +#define MUIM_DeleteDragImage 0x80423037 /* V18 */ /* Custom Class */ +#define MUIM_GoActive 0x8042491a +#define MUIM_GoInactive 0x80422c0c +#define MUIM_CustomBackfill 0x80428d73 + +struct MUIP_CustomBackfill { ULONG MethodID; LONG left; LONG top; LONG right; LONG bottom; LONG xoffset; LONG yoffset; }; +struct MUIP_DeleteDragImage { ULONG MethodID; struct MUI_DragImage *di; }; /* Custom Class */ +struct MUIP_CreateDragImage { ULONG MethodID; LONG touchx; LONG touchy; ULONG flags; }; /* Custom Class */ +struct MUIP_DoDrag { ULONG MethodID; LONG touchx; LONG touchy; ULONG flags; }; /* Custom Class */ + +/* Attributes */ + +#define MUIA_CustomBackfill 0x80420a63 + + +#define MUIV_CreateBubble_DontHidePointer (1<<0) + +struct MUI_DragImage +{ + struct BitMap *bm; + WORD width; /* exact width and height of bitmap */ + WORD height; + WORD touchx; /* position of pointer click relative to bitmap */ + WORD touchy; + ULONG flags; /* must be set to 0 */ +}; + + +/****************************************************************************/ +/** Imagedisplay **/ +/****************************************************************************/ + +/* Attributes */ + +#define MUIA_Imagedisplay_Spec 0x8042a547 /* V11 isg struct MUI_ImageSpec * */ + + +/****************************************************************************/ +/** Imageadjust **/ +/****************************************************************************/ + +/* Attributes */ + +#define MUIA_Imageadjust_Type 0x80422f2b /* V11 i.. LONG */ + + +/****************************************************************************/ +/** Framedisplay **/ +/****************************************************************************/ + +/* Attributes */ + +#define MUIA_Framedisplay_Spec 0x80421794 /* isg struct MUI_FrameSpec * */ + + +/****************************************************************************/ +/** Prop **/ +/****************************************************************************/ + +/* Attributes */ + +#ifndef MUIA_Prop_DeltaFactor +#define MUIA_Prop_DeltaFactor 0x80427c5e /* V4 .s. LONG */ +#endif /* MUIA_Prop_DeltaFactor */ +#define MUIA_Prop_DoSmooth 0x804236ce /* V4 i.. LONG */ +#define MUIA_Prop_Release 0x80429839 /* V? g BOOL */ /* private */ +#define MUIA_Prop_Pressed 0x80422cd7 /* V6 g BOOL */ /* private */ + + +/****************************************************************************/ +/** Group **/ +/****************************************************************************/ + +/* Attributes */ + +#define MUIA_Group_Forward 0x80421422 /* V11 .s. BOOL */ + +/****************************************************************************/ +/** List **/ +/****************************************************************************/ + +/* Attributes */ + +#define MUIA_List_Prop_Entries 0x8042a8f5 /* V? ??? */ +#define MUIA_List_Prop_Visible 0x804273e9 /* V? ??? */ +#define MUIA_List_Prop_First 0x80429df3 /* V? ??? */ + + +/****************************************************************************/ +/** Text **/ +/****************************************************************************/ + +/* Attributes */ + +#define MUIA_Text_HiCharIdx 0x804214f5 + + +/****************************************************************************/ +/** Dtpic **/ +/****************************************************************************/ + +/* Attributes */ + +#define MUIA_Dtpic_Name 0x80423d72 + + +#endif /* MUI_UNDOC_H */ + + + diff --git a/scalos/include/Year.h b/scalos/include/Year.h new file mode 100644 index 000000000..e4c1164f9 --- /dev/null +++ b/scalos/include/Year.h @@ -0,0 +1,11 @@ +// Year.h +jmc+ +// $Date$ +// $Revision$ +// Define the current year. + +#ifndef YEAR_H +#define YEAR_H + +#define CURRENTYEAR "-2012" + +#endif /* YEAR_H */ diff --git a/scalos/include/clib/cybergraphics_protos.h b/scalos/include/clib/cybergraphics_protos.h new file mode 100755 index 000000000..d4e89328a --- /dev/null +++ b/scalos/include/clib/cybergraphics_protos.h @@ -0,0 +1,78 @@ +#ifndef CLIB_CYBERGRAPHICS_PROTOS_H +#define CLIB_CYBERGRAPHICS_PROTOS_H + + +/* +** $VER: cybergraphics_protos.h 210.0 (29.08.2009) +** +** C prototypes. For use with 32 bit integers only. +** +** Copyright © 1996-1998 by phase5 digital products +** All Rights Reserved +*/ + +#ifndef UTILITY_TAGITEM_H +#include +#endif + +BOOL IsCyberModeID(ULONG displayID); +ULONG BestCModeIDTagList(struct TagItem * bestModeIDTags); +ULONG BestCModeIDTags(Tag bestModeIDTags, ...); +ULONG CModeRequestTagList(APTR modeRequest, struct TagItem * modeRequestTags); +ULONG CModeRequestTags(APTR modeRequest, Tag modeRequestTags, ...); +struct List * AllocCModeListTagList(struct TagItem * modeListTags); +struct List * AllocCModeListTags(Tag modeListTags, ...); +VOID FreeCModeList(struct List * modeList); +LONG ScalePixelArray(APTR srcRect, ULONG srcW, ULONG srcH, ULONG srcMod, + struct RastPort * rp, ULONG destX, ULONG destY, ULONG destW, + ULONG destH, ULONG srcFormat); +ULONG GetCyberMapAttr(struct BitMap * cyberGfxBitmap, ULONG cyberAttrTag); +ULONG GetCyberIDAttr(ULONG cyberIDAttr, ULONG cyberDisplayModeID); +ULONG ReadRGBPixel(struct RastPort * rp, ULONG x, ULONG y); +LONG WriteRGBPixel(struct RastPort * rp, ULONG x, ULONG y, ULONG argb); +ULONG ReadPixelArray(APTR destRect, ULONG destX, ULONG destY, ULONG destMod, + struct RastPort * rp, ULONG srcX, ULONG srcY, ULONG sizeX, + ULONG sizeY, ULONG destFormat); +ULONG WritePixelArray(APTR srcRect, ULONG srcX, ULONG srcY, ULONG srcMod, + struct RastPort * rp, ULONG destX, ULONG destY, ULONG sizeX, + ULONG sizeY, ULONG srcFormat); +ULONG MovePixelArray(ULONG srcX, ULONG srcY, struct RastPort * rp, ULONG destX, ULONG destY, + ULONG sizeX, ULONG sizeY); +ULONG InvertPixelArray(struct RastPort * rp, ULONG destX, ULONG destY, ULONG sizeX, + ULONG sizeY); +ULONG FillPixelArray(struct RastPort * rp, ULONG destX, ULONG destY, ULONG sizeX, + ULONG sizeY, ULONG aRGB); +VOID DoCDrawMethodTagList(struct Hook * hook, struct RastPort * rp, struct TagItem * tagList); +VOID DoCDrawMethodTags(struct Hook * hook, struct RastPort * rp, Tag tagList, ...); +VOID CVideoCtrlTagList(struct ViewPort * viewPort, struct TagItem * tagList); +VOID CVideoCtrlTags(struct ViewPort * viewPort, Tag tagList, ...); +APTR LockBitMapTagList(APTR bitMap, struct TagItem * tagList); +APTR LockBitMapTags(APTR bitMap, Tag tagList, ...); +VOID UnLockBitMap(APTR handle); +VOID UnLockBitMapTagList(APTR handle, struct TagItem * tagList); +VOID UnLockBitMapTags(APTR handle, Tag tagList, ...); +ULONG ExtractColor(struct RastPort * rp, struct BitMap * bitMap, ULONG colour, ULONG srcX, + ULONG srcY, ULONG width, ULONG height); +ULONG WriteLUTPixelArray(APTR srcRect, ULONG srcX, ULONG srcY, ULONG srcMod, + struct RastPort * rp, APTR colorTab, ULONG destX, ULONG destY, + ULONG sizeX, ULONG sizeY, ULONG cTFormat); +ULONG WritePixelArrayAlpha(APTR srcRect, ULONG srcX, ULONG srcY, ULONG srcMod, + struct RastPort * rp, ULONG destX, ULONG destY, ULONG sizeX, + ULONG sizeY, ULONG globalAlpha); +VOID BltTemplateAlpha(UBYTE * source, LONG xSrc, LONG srcMod, struct RastPort * destRP, + ULONG xDest, ULONG yDest, ULONG xSize, ULONG ySize); +VOID ProcessPixelArray(struct RastPort * rp, ULONG destX, ULONG destY, ULONG sizeX, + ULONG sizeY, ULONG operation, LONG value, struct TagItem * taglist); +VOID ProcessPixelArrayTags(struct RastPort * rp, ULONG destX, ULONG destY, ULONG sizeX, + ULONG sizeY, ULONG operation, LONG value, Tag taglist, ...); +ULONG BltBitMapAlpha(struct BitMap * srcBitMap, LONG srcX, LONG srcY, + struct BitMap * destBitMap, LONG destX, LONG destY, LONG sizeX, + LONG sizeY, struct TagItem * taglist); +ULONG BltBitMapRastPortAlpha(struct BitMap * srcBitMap, LONG srcX, LONG srcY, + struct RastPort * destRP, LONG destX, LONG destY, LONG sizeX, + LONG sizeY, struct TagItem * taglist); +LONG ScalePixelArrayAlpha(APTR srcRect, ULONG srcW, ULONG srcH, ULONG srcMod, + struct RastPort * rp, ULONG destX, ULONG destY, ULONG destW, + ULONG destH, ULONG globalAlpha); + +#endif /* CLIB_CYBERGRAPHICS_PROTOS_H */ diff --git a/scalos/include/clib/dtlib_protos.h b/scalos/include/clib/dtlib_protos.h new file mode 100755 index 000000000..3151d9b39 --- /dev/null +++ b/scalos/include/clib/dtlib_protos.h @@ -0,0 +1,29 @@ +#ifndef CLIB_DTLIB_PROTOS_H +#define CLIB_DTLIB_PROTOS_H + +/* +** $Id$ +** +** C prototypes. For use with 32 bit integers only. +** +** ©1999-2005 The Scalos Team +** All Rights Reserved +*/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef INTUITION_CLASSES_H +#include +#endif +Class *ObtainInfoEngine( struct Library *libBase ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CLIB_DTLIB_PROTOS_H */ diff --git a/scalos/include/clib/guigfx_protos.h b/scalos/include/clib/guigfx_protos.h new file mode 100755 index 000000000..d9706c90d --- /dev/null +++ b/scalos/include/clib/guigfx_protos.h @@ -0,0 +1,70 @@ +#ifndef CLIB_GUIGFX_PROTOS_H +#define CLIB_GUIGFX_PROTOS_H + + +/* +** $VER: guigfx_protos.h 5.0 (10.03.2009) +** +** C prototypes. For use with 32 bit integers only. +** +** Copyright © 2009 +** All Rights Reserved +*/ + +#ifndef EXEC_TYPES_H +#include +#endif + +APTR MakePictureA(APTR array, ULONG width, ULONG height, struct TagItem * tags); +APTR MakePicture(APTR array, ULONG width, ULONG height, ULONG tags, ...); +APTR LoadPictureA(STRPTR filename, struct TagItem * tags); +APTR LoadPicture(STRPTR filename, ULONG tags, ...); +APTR ReadPictureA(struct RastPort * rp, struct ColorMap * colormap, ULONG x, ULONG y, + ULONG width, ULONG height, struct TagItem * tags); +APTR ReadPicture(struct RastPort * rp, struct ColorMap * colormap, ULONG x, ULONG y, + ULONG width, ULONG height, ULONG tags, ...); +APTR ClonePictureA(APTR pic, struct TagItem * tags); +APTR ClonePicture(APTR pic, ULONG tags, ...); +VOID DeletePicture(APTR pic); +APTR AddPictureA(APTR psm, APTR pic, struct TagItem * tags); +APTR AddPicture(APTR psm, APTR pic, ULONG tags, ...); +APTR AddPaletteA(APTR psm, APTR palette, struct TagItem * tags); +APTR AddPalette(APTR psm, APTR palette, ULONG tags, ...); +APTR AddPixelArrayA(APTR psm, APTR array, ULONG width, ULONG height, struct TagItem * tags); +APTR AddPixelArray(APTR psm, APTR array, ULONG width, ULONG height, ULONG tags, ...); +VOID RemColorHandle(APTR colorhandle); +APTR CreatePenShareMapA(struct TagItem * tags); +APTR CreatePenShareMap(Tag tags, ...); +VOID DeletePenShareMap(APTR psm); +APTR ObtainDrawHandleA(APTR psm, struct RastPort * rp, struct ColorMap * cm, + struct TagItem * tags); +APTR ObtainDrawHandle(APTR psm, struct RastPort * rp, struct ColorMap * cm, ULONG tags, ...); +VOID ReleaseDrawHandle(APTR drawhandle); +BOOL DrawPictureA(APTR drawhandle, APTR pic, ULONG x, ULONG y, struct TagItem * tags); +BOOL DrawPicture(APTR drawhandle, APTR pic, ULONG x, ULONG y, ULONG tags, ...); +BOOL MapPaletteA(APTR drawhandle, APTR palette, UBYTE * pentab, struct TagItem * tags); +BOOL MapPalette(APTR drawhandle, APTR palette, UBYTE * pentab, ULONG tags, ...); +LONG MapPenA(APTR drawhandle, ULONG rgb, struct TagItem * tags); +LONG MapPen(APTR drawhandle, ULONG rgb, ULONG tags, ...); +struct BitMap * CreatePictureBitMapA(APTR drawhandle, APTR pic, struct TagItem * tags); +struct BitMap * CreatePictureBitMap(APTR drawhandle, APTR pic, ULONG tags, ...); +ULONG DoPictureMethodA(APTR pic, ULONG method, ULONG * arguments); +ULONG DoPictureMethod(APTR pic, ULONG method, ULONG arguments, ...); +ULONG GetPictureAttrsA(APTR pic, struct TagItem * tags); +ULONG GetPictureAttrs(APTR pic, ULONG tags, ...); +ULONG LockPictureA(APTR pic, ULONG mode, ULONG * args); +ULONG LockPicture(APTR pic, ULONG mode, ULONG args, ...); +VOID UnLockPicture(APTR pic, ULONG mode); +BOOL IsPictureA(STRPTR filename, struct TagItem * tags); +BOOL IsPicture(STRPTR filename, ULONG tags, ...); +APTR CreateDirectDrawHandleA(APTR drawhandle, ULONG sw, ULONG sh, ULONG dw, ULONG dh, + struct TagItem * tags); +APTR CreateDirectDrawHandle(APTR drawhandle, ULONG sw, ULONG sh, ULONG dw, ULONG dh, ULONG tags, + ...); +VOID DeleteDirectDrawHandle(APTR ddh); +BOOL DirectDrawTrueColorA(APTR ddh, ULONG * array, ULONG x, ULONG y, struct TagItem * tags); +BOOL DirectDrawTrueColor(APTR ddh, ULONG * array, ULONG x, ULONG y, ULONG tags, ...); +BOOL CreatePictureMaskA(APTR pic, UBYTE * mask, ULONG maskwidth, struct TagItem * tags); +BOOL CreatePictureMask(APTR pic, UBYTE * mask, ULONG maskwidth, ULONG tags, ...); + +#endif /* CLIB_GUIGFX_PROTOS_H */ diff --git a/scalos/include/clib/iconobject_protos.h b/scalos/include/clib/iconobject_protos.h new file mode 100755 index 000000000..b15a0ba67 --- /dev/null +++ b/scalos/include/clib/iconobject_protos.h @@ -0,0 +1,39 @@ +#ifndef CLIB_ICONOBJECT_PROTOS_H +#define CLIB_ICONOBJECT_PROTOS_H + +/* +** $Id$ +** +** C prototypes. For use with 32 bit integers only. +** +** ©1999-2002 The Scalos Team +** All Rights Reserved +*/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef INTUITION_CLASSUSR_H +#include +#endif +#ifndef WORKBENCH_WORKBENCH_H +#include +#endif +Object *NewIconObject( CONST_STRPTR name, CONST struct TagItem *tagList ); +Object *NewIconObjectTags( CONST_STRPTR name, ULONG firstTag, ... ); +VOID DisposeIconObject( Object *iconObject ); +Object *GetDefIconObject( ULONG iconType, CONST struct TagItem *tagList ); +Object *GetDefIconObjectTags( ULONG iconType, ULONG firstTag, ... ); +LONG PutIconObject( Object *iconObject, CONST_STRPTR path, CONST struct TagItem *tagList ); +LONG PutIconObjectTags( Object *iconObject, CONST_STRPTR path, ULONG firstTag, ... ); +ULONG IsIconName( CONST_STRPTR fileName ); +Object *Convert2IconObject( struct DiskObject *diskObject ); +Object *Convert2IconObjectA( struct DiskObject *diskObject, CONST struct TagItem *tagList ); +Object *Convert2IconObjectTags( struct DiskObject *diskObject, ULONG firstTag, ... ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CLIB_ICONOBJECT_PROTOS_H */ diff --git a/scalos/include/clib/mcpgfx_protos.h b/scalos/include/clib/mcpgfx_protos.h new file mode 100755 index 000000000..6a7dc5488 --- /dev/null +++ b/scalos/include/clib/mcpgfx_protos.h @@ -0,0 +1,46 @@ +#ifndef CLIB_MCPGFX_PROTOS_H +#define CLIB_MCPGFX_PROTOS_H + +/* +** $Id$ +** +** C prototypes. For use with 32 bit integers only. +** +** Copyright © 2001 Amiga, Inc. +** All Rights Reserved +*/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef LIBRARIES_MCPGFX_H +#include +#endif +#ifndef GRAPHICS_RASTPORT_H +#include +#endif +#ifndef INTUITION_SCREENS_H +#include +#endif +#ifndef UTILITY_TAGITEM_H +#include +#endif +VOID mcpPaintSysIGad( APTR sysImageObject, struct DrawInfo *drawInfo, LONG gadgetNumber, LONG width, LONG height ); +VOID mcpRectFillA( struct RastPort *rp, LONG x1, LONG y1, LONG x2, LONG y2, CONST struct TagItem *tagList ); +VOID mcpRectFill( struct RastPort *rp, LONG x1, LONG y1, LONG x2, LONG y2, Tag tagList, ... ); +VOID mcpDrawFrameA( struct RastPort *rp, LONG x1, LONG y1, LONG x2, LONG y2, struct TagItem *tagList ); +VOID mcpDrawFrame( struct RastPort *rp, LONG x1, LONG y1, LONG x2, LONG y2, Tag tagList, ... ); +struct ExtDrawInfo *mcpGetExtDrawInfo( struct Screen *screen, struct DrawInfo *drawInfo ); +struct FrameSize *mcpGetFrameSize( struct DrawInfo *drawInfo, LONG frameType ); +VOID mcpSetGFXAttrsA( struct TagItem *tagList ); +VOID mcpSetGFXAttrs( Tag tagList, ... ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CLIB_MCPGFX_PROTOS_H */ diff --git a/scalos/include/clib/newicon_protos.h b/scalos/include/clib/newicon_protos.h new file mode 100755 index 000000000..b0d557c03 --- /dev/null +++ b/scalos/include/clib/newicon_protos.h @@ -0,0 +1,37 @@ +#ifndef CLIB_NEWICON_PROTOS_H +#define CLIB_NEWICON_PROTOS_H + +/* +** $Id$ +** +** C prototypes. For use with 32 bit integers only. +** +** Copyright © 2001 Amiga, Inc. +** All Rights Reserved +*/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef LIBRARIES_NEWICON_H +#include +#endif +struct NewDiskObject *GetNewDiskObject( UBYTE *name ); +BOOL PutNewDiskObject( UBYTE *name, struct NewDiskObject *newdiskobj ); +VOID FreeNewDiskObject( struct NewDiskObject *newdiskobj ); +BOOL newiconPrivate1( struct NewDiskObject *diskobj ); +UBYTE **newiconPrivate2( struct NewDiskObject *diskobj ); +VOID newiconPrivate3( struct NewDiskObject *diskobj ); +struct Image *RemapChunkyImage( struct ChunkyImage *chunkyimage, struct Screen *screen ); +VOID FreeRemappedImage( struct Image *image, struct Screen *screen ); +struct NewDiskObject *GetDefNewDiskObject( LONG def_type ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CLIB_NEWICON_PROTOS_H */ diff --git a/scalos/include/clib/openurl_protos.h b/scalos/include/clib/openurl_protos.h new file mode 100755 index 000000000..601235e8c --- /dev/null +++ b/scalos/include/clib/openurl_protos.h @@ -0,0 +1,64 @@ +#ifndef CLIB_OPENURL_PROTOS_H +#define CLIB_OPENURL_PROTOS_H + +/* +** $VER: openurl_protos.h 7.2 (1.12.2005) +** +** C prototypes. For use with 32 bit integers only. +** +** openurl.library - universal URL display and browser +** launcher library +** +** Written by Troels Walsted Hansen +** Placed in the public domain. +** +** Developed by: +** - Alfonso Ranieri +** - Stefan Kost +** +*/ + +#ifndef LIBRARIES_OPENURL_H +# include +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* Obsolete, don't use! */ +struct URL_Prefs *URL_OldGetPrefs(void); +void URL_OldFreePrefs(struct URL_Prefs *); +ULONG URL_OldSetPrefs(struct URL_Prefs *, BOOL); +struct URL_Prefs *URL_OldGetDefaultPrefs(void); +ULONG URL_OldLaunchPrefsApp(void); + +/* Reach URL */ +ULONG URL_OpenA(STRPTR, struct TagItem *); + +/* Preferences */ +struct URL_Prefs *URL_GetPrefsA(struct TagItem *); +void URL_FreePrefsA(struct URL_Prefs *,struct TagItem *); +ULONG URL_SetPrefsA(struct URL_Prefs *,struct TagItem *); + +/* Prefs application */ +ULONG URL_LaunchPrefsAppA(struct TagItem *); + +/* Information */ +ULONG URL_GetAttr(ULONG attr,ULONG *storage); + +#if defined(_DCC) || defined(__SASC) || defined (__STORM__) +ULONG URL_Open(STRPTR, ...); +struct URL_Prefs *URL_GetPrefs(...); +void URL_FreePrefs(struct URL_Prefs *,...); +ULONG URL_SetPrefs(struct URL_Prefs *,...); +ULONG URL_LaunchPrefsApp(...); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* CLIB_OPENURL_PROTOS_H */ diff --git a/scalos/include/clib/pm_protos.h b/scalos/include/clib/pm_protos.h new file mode 100755 index 000000000..6747f745d --- /dev/null +++ b/scalos/include/clib/pm_protos.h @@ -0,0 +1,54 @@ +#ifndef CLIB_PM_PROTOS_H +#define CLIB_PM_PROTOS_H + +/* +** $Id$ +** +** C prototypes. For use with 32 bit integers only. +** +** Copyright © 2001 Amiga, Inc. +** All Rights Reserved +*/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef LIBRARIES_PM_H +#include +#endif +struct PopupMenu *PM_MakeMenuA( struct TagItem *tags ); +struct PopupMenu *PM_MakeMenu( ULONG tags, ... ); +struct PopupMenu *PM_MakeItemA( struct TagItem *tags ); +struct PopupMenu *PM_MakeItem( ULONG tags, ... ); +VOID PM_FreePopupMenu( struct PopupMenu *menu ); +ULONG PM_OpenPopupMenuA( struct Window *wnd, struct TagItem *tags ); +ULONG PM_OpenPopupMenu( struct Window *wnd, ULONG tags, ... ); +struct PM_IDLst *PM_MakeIDListA( struct TagItem *tags ); +struct PM_IDLst *PM_MakeIDList( ULONG tags, ... ); +BOOL PM_ItemChecked( struct PopupMenu *pm, ULONG id ); +LONG PM_GetItemAttrsA( struct PopupMenu *item, struct TagItem *tags ); +LONG PM_GetItemAttrs( struct PopupMenu *item, ULONG tags, ... ); +LONG PM_SetItemAttrsA( struct PopupMenu *item, struct TagItem *tags ); +LONG PM_SetItemAttrs( struct PopupMenu *item, ULONG tags, ... ); +struct PopupMenu *PM_FindItem( struct PopupMenu *menu, ULONG id ); +VOID PM_AlterState( struct PopupMenu *menu, struct PM_IDLst *idlst, ULONG action ); +struct PM_IDLst *PM_ExLstA( ULONG *id ); +struct PM_IDLst *PM_ExLst( ULONG id, ... ); +APTR PM_FilterIMsgA( struct Window *window, struct PopupMenu *menu, struct IntuiMessage *imsg, struct TagItem *tags ); +APTR PM_FilterIMsg( struct Window *window, struct PopupMenu *menu, struct IntuiMessage *imsg, ULONG tags, ... ); +LONG PM_InsertMenuItemA( struct PopupMenu *menu, struct TagItem *tags ); +LONG PM_InsertMenuItem( struct PopupMenu *menu, ULONG tags, ... ); +struct PopupMenu *PM_RemoveMenuItem( struct PopupMenu *menu, struct PopupMenu *item ); +BOOL PM_AbortHook( APTR handle ); +STRPTR PM_GetVersion( VOID ); +VOID PM_ReloadPrefs( VOID ); +LONG PM_LayoutMenuA( struct Window *window, struct PopupMenu *menu, struct TagItem *tags ); +LONG PM_LayoutMenu( struct Window *window, struct PopupMenu *menu, ULONG tags, ... ); +VOID PM_FreeIDList( struct PM_IDLst *list ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CLIB_PM_PROTOS_H */ diff --git a/scalos/include/clib/preferences_protos.h b/scalos/include/clib/preferences_protos.h new file mode 100755 index 000000000..2b7dac24f --- /dev/null +++ b/scalos/include/clib/preferences_protos.h @@ -0,0 +1,38 @@ +#ifndef CLIB_PREFERENCES_PROTOS_H +#define CLIB_PREFERENCES_PROTOS_H + +/* +** $Id$ +** +** C prototypes. For use with 32 bit integers only. +** +** Copyright © 2001 Amiga, Inc. +** All Rights Reserved +*/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef SCALOS_PREFERENCES_H +#include +#endif +APTR AllocPrefsHandle( CONST_STRPTR name ); +VOID FreePrefsHandle( APTR prefsHandle ); +VOID SetPreferences( APTR prefsHandle, ULONG iD, ULONG prefsTag, CONST APTR a1arg, ULONG struct_Size ); +ULONG GetPreferences( APTR prefsHandle, ULONG iD, ULONG prefsTag, APTR a1arg, ULONG struct_Size ); +VOID ReadPrefsHandle( APTR prefsHandle, CONST_STRPTR filename ); +VOID WritePrefsHandle( APTR prefsHandle, CONST_STRPTR filename ); +struct PrefsStruct *FindPreferences( APTR prefsHandle, ULONG iD, ULONG prefsTag ); +VOID SetEntry( APTR prefsHandle, ULONG iD, ULONG prefsTag, CONST APTR a1arg, ULONG struct_Size, ULONG entry ); +ULONG GetEntry( APTR prefsHandle, ULONG iD, ULONG prefsTag, APTR a1arg, ULONG struct_Size, ULONG entry ); +ULONG RemEntry( APTR prefsHandle, ULONG iD, ULONG prefsTag, ULONG entry ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CLIB_PREFERENCES_PROTOS_H */ diff --git a/scalos/include/clib/scalos_protos.h b/scalos/include/clib/scalos_protos.h new file mode 100755 index 000000000..67f2c052d --- /dev/null +++ b/scalos/include/clib/scalos_protos.h @@ -0,0 +1,83 @@ +#ifndef CLIB_SCALOS_PROTOS_H +#define CLIB_SCALOS_PROTOS_H + + +/* +** $VER: scalos_protos.h 21.42 (08.01.2008) +** +** C prototypes. For use with 32 bit integers only. +** +** Copyright © 2008 ©1999-2002 The Scalos Team +** All Rights Reserved +*/ + +#ifndef INTUITION_CLASSUSR_H +#include +#endif +#ifndef WORKBENCH_STARTUP_H +#include +#endif +#ifndef SCALOS_SCALOS_H +#include +#endif + +BOOL SCA_WBStart(APTR argArray, CONST struct TagItem * tagList, ULONG numArgs); +BOOL SCA_WBStartTags(APTR argArray, ULONG numArgs, ULONG firstTag, ...); +VOID SCA_SortNodes(struct ScalosNodeList * nodelist, struct Hook * sortHook, + ULONG sortType); +struct AppObject * SCA_NewAddAppIcon(ULONG iD, ULONG userData, Object * iconObj, + struct MsgPort * msgPort, CONST struct TagItem * tagList); +struct AppObject * SCA_NewAddAppIconTags(ULONG iD, ULONG userData, Object * iconObj, + struct MsgPort * msgPort, ULONG tagList, ...); +BOOL SCA_RemoveAppObject(struct AppObject * appObj); +struct AppObject * SCA_NewAddAppWindow(ULONG iD, ULONG userData, struct Window * win, + struct MsgPort * msgPort, CONST struct TagItem * tagList); +struct AppObject * SCA_NewAddAppWindowTags(ULONG iD, ULONG userData, struct Window * win, + struct MsgPort * msgPort, ULONG tagList, ...); +struct AppObject * SCA_NewAddAppMenuItem(ULONG iD, ULONG userData, CONST_STRPTR text, + struct MsgPort * msgPort, CONST struct TagItem * tagList); +struct AppObject * SCA_NewAddAppMenuItemTags(ULONG iD, ULONG userData, CONST_STRPTR text, + struct MsgPort * msgPort, ULONG tagList, ...); +struct MinNode * SCA_AllocStdNode(struct ScalosNodeList * nodeList, ULONG nodeType); +struct MinNode * SCA_AllocNode(struct ScalosNodeList * nodeList, ULONG size); +VOID SCA_FreeNode(struct ScalosNodeList * nodeList, struct MinNode * minNode); +VOID SCA_FreeAllNodes(struct ScalosNodeList * nodeList); +VOID SCA_MoveNode(struct ScalosNodeList * srcNodeList, + struct ScalosNodeList * destNodeList, struct MinNode * minNode); +VOID SCA_SwapNodes(struct MinNode * minNode1, struct MinNode * minNode2, + struct ScalosNodeList * nodeList); +BOOL SCA_OpenIconWindow(CONST struct TagItem * tagList); +BOOL SCA_OpenIconWindowTags(ULONG tagList, ...); +struct ScaWindowList * SCA_LockWindowList(LONG accessmode); +VOID SCA_UnLockWindowList(void); +struct ScalosMessage * SCA_AllocMessage(ULONG messagetype, ULONG additional_size); +VOID SCA_FreeMessage(struct ScalosMessage * message); +struct DragHandle * SCA_InitDrag(struct Screen * screen); +VOID SCA_EndDrag(struct DragHandle * dragHandle); +BOOL SCA_AddBob(struct DragHandle * dragHandle, struct BitMap * bm, APTR mask, + ULONG width, ULONG height, LONG xOffset, LONG yOffset); +VOID SCA_DrawDrag(struct DragHandle * dragHandle, LONG x, LONG y, ULONG flags); +VOID SCA_UpdateIcon(ULONG windowType, APTR updateIconStruct, ULONG ui_SIZE); +ULONG SCA_MakeWBArgs(struct WBArg * buffer, struct ScaIconNode * in, ULONG argsSize); +VOID SCA_FreeWBArgs(struct WBArg * buffer, ULONG number, ULONG flags); +VOID SCA_ScreenTitleMsg(CONST_STRPTR format, APTR args); +VOID SCA_ScreenTitleMsgArgs(CONST_STRPTR format, ULONG args, ...); +struct ScalosClass * SCA_MakeScalosClass(CONST_STRPTR className, CONST_STRPTR superClassName, + ULONG instSize, APTR dispFunc); +BOOL SCA_FreeScalosClass(struct ScalosClass * scalosClass); +Object * SCA_NewScalosObject(CONST_STRPTR className, CONST struct TagItem * tagList); +Object * SCA_NewScalosObjectTags(CONST_STRPTR className, ULONG tagList, ...); +VOID SCA_DisposeScalosObject(Object * obj); +ULONG SCA_ScalosControlA(CONST_STRPTR name, CONST struct TagItem * tagList); +ULONG SCA_ScalosControl(CONST_STRPTR name, ULONG tagList, ...); +ULONG SCA_ScalosControlTags(CONST_STRPTR name, ULONG tagList, ...); +Object * SCA_GetDefIconObject(BPTR dirLock, CONST_STRPTR name); +struct ScaWindowStruct * SCA_OpenDrawerByName(CONST_STRPTR path, struct TagItem * tagList); +struct ScaWindowStruct * SCA_OpenDrawerByNameTags(CONST_STRPTR path, ULONG tagList, ...); +ULONG SCA_CountWBArgs(struct ScaIconNode * in); +Object * SCA_GetDefIconObjectA(BPTR dirLock, CONST_STRPTR name, struct TagItem * tagList); +Object * SCA_GetDefIconObjectTags(BPTR dirLock, CONST_STRPTR name, ULONG tagList, ...); +ULONG SCA_LockDrag(struct DragHandle * dragHandle); +ULONG SCA_UnlockDrag(struct DragHandle * dragHandle); + +#endif /* CLIB_SCALOS_PROTOS_H */ diff --git a/scalos/include/clib/scalosfiletypeplugin_protos.h b/scalos/include/clib/scalosfiletypeplugin_protos.h new file mode 100755 index 000000000..16413ba8d --- /dev/null +++ b/scalos/include/clib/scalosfiletypeplugin_protos.h @@ -0,0 +1,26 @@ +#ifndef CLIB_SCALOSFILETYPEPLUGIN_PROTOS_H +#define CLIB_SCALOSFILETYPEPLUGIN_PROTOS_H + +/* +** $Id$ +** +** C prototypes. For use with 32 bit integers only. +** +** ©1999-2002 The Scalos Team +** All Rights Reserved +*/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef SCALOS_SCALOS_H +#include +#endif +STRPTR SCAToolTipInfoString( struct ScaToolTipInfoHookData *ttshd, CONST_STRPTR args ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CLIB_SCALOSFILETYPEPLUGIN_PROTOS_H */ diff --git a/scalos/include/clib/scalosgfx_protos.h b/scalos/include/clib/scalosgfx_protos.h new file mode 100755 index 000000000..199a9e8cf --- /dev/null +++ b/scalos/include/clib/scalosgfx_protos.h @@ -0,0 +1,93 @@ +#ifndef CLIB_SCALOSGFX_PROTOS_H +#define CLIB_SCALOSGFX_PROTOS_H + + +/* +** $VER: scalosgfx_protos.h 5.0 (13.09.2009) +** +** C prototypes. For use with 32 bit integers only. +** +** Copyright © 2009 ©2006 The Scalos Team +** All Rights Reserved +*/ + +#ifndef INTUITION_CLASSUSR_H +#include +#endif +#ifndef SCALOS_SCALOS_H +#include +#endif +#ifndef GRAPHICS_GFX_H +#include +#endif +#ifndef SCALOS_SCALOSGFX_H +#include +#endif + +struct ScalosBitMapAndColor * ScalosGfxCreateEmptySAC(void); +struct ScalosBitMapAndColor * ScalosGfxCreateSAC(ULONG width, ULONG height, ULONG depth, + struct BitMap * friendBM, struct TagItem * tagList); +struct ScalosBitMapAndColor * ScalosGfxCreateSACTags(ULONG width, ULONG height, ULONG depth, + struct BitMap * friendBM, ULONG tagList, ...); +VOID ScalosGfxFreeSAC(struct ScalosBitMapAndColor * sac); +struct gfxARGB * ScalosGfxCreateARGB(ULONG width, ULONG height, struct TagItem * tagList); +struct gfxARGB * ScalosGfxCreateARGBTags(ULONG width, ULONG height, ULONG tagList, ...); +VOID ScalosGfxFreeARGB(struct gfxARGB ** argb); +VOID ScalosGfxARGBSetAlpha(struct ARGBHeader * src, ULONG alpha); +VOID ScalosGfxARGBSetAlphaMask(struct ARGBHeader * argbh, PLANEPTR maskPlane); +struct gfxARGB * ScalosGfxCreateARGBFromBitMap(struct BitMap * bm, ULONG width, ULONG height, + ULONG numberOfColors, const ULONG * colorTable, PLANEPTR maskPlane); +VOID ScalosGfxFillARGBFromBitMap(struct ARGBHeader * argbh, struct BitMap * srcBM, PLANEPTR maskPlane); +VOID ScalosGfxWriteARGBToBitMap(struct ARGBHeader * argbh, struct BitMap * bm, ULONG numberOfColors, + const ULONG * colorTable); +struct ScalosBitMapAndColor * ScalosGfxMedianCut(struct ARGBHeader * argbh, ULONG depth, + struct TagItem * tagList); +struct ScalosBitMapAndColor * ScalosGfxMedianCutTags(struct ARGBHeader * argbh, ULONG depth, + ULONG tagList, ...); +struct gfxARGB * ScalosGfxScaleARGBArray(const struct ARGBHeader * src, ULONG * destWidth, + ULONG * destHeight, struct TagItem * tagList); +struct gfxARGB * ScalosGfxScaleARGBArrayTags(const struct ARGBHeader * src, ULONG * destWidth, + ULONG * destHeight, ULONG tagList, ...); +struct BitMap * ScalosGfxScaleBitMap(struct ScaleBitMapArg * sbma, struct TagItem * tagList); +struct BitMap * ScalosGfxScaleBitMapTags(struct ScaleBitMapArg * sbma, ULONG tagList, ...); +VOID ScalosGfxCalculateScaleAspect(ULONG sourceWidth, ULONG sourceHeight, ULONG * destWidth, + ULONG * destHeight); +VOID ScalosGfxBlitARGB(struct ARGBHeader * destARGB, const struct ARGBHeader * srcARGB, + LONG destLeft, LONG destTop, LONG srcLeft, LONG srcTop, LONG width, + LONG height); +VOID ScalosGfxFillRectARGB(struct ARGBHeader * destARGB, const struct gfxARGB * fillARGB, + LONG left, LONG top, LONG width, LONG height); +VOID ScalosGfxSetARGB(struct ARGBHeader * destARGB, const struct gfxARGB * fillARGB); +BOOL ScalosGfxNewColorMap(struct ScalosBitMapAndColor * sac, const ULONG * colorMap, + ULONG colorEntries); +VOID ScalosGfxARGBRectMult(struct RastPort * rp, const struct gfxARGB * numerator, + const struct gfxARGB * denominator, LONG xMin, LONG yMin, LONG xMax, + LONG yMax); +VOID ScalosGfxBlitARGBAlpha(struct RastPort * rp, const struct ARGBHeader * srcH, ULONG destLeft, + ULONG destTop, ULONG srcLeft, ULONG srcTop, ULONG width, + ULONG height); +VOID ScalosGfxBlitARGBAlphaTagList(struct RastPort * rp, const struct ARGBHeader * srcH, ULONG destLeft, + ULONG destTop, const struct IBox * srcSize, + struct TagItem * tagList); +VOID ScalosGfxBlitARGBAlphaTags(struct RastPort * rp, const struct ARGBHeader * srcH, ULONG destLeft, + ULONG destTop, const struct IBox * srcSize, ULONG tagList, ...); +VOID ScalosGfxBlitIcon(struct RastPort * rpBackground, struct RastPort * rpIcon, ULONG left, + ULONG top, ULONG width, ULONG height, struct TagItem * tagList); +VOID ScalosGfxBlitIconTags(struct RastPort * rpBackground, struct RastPort * rpIcon, ULONG left, + ULONG top, ULONG width, ULONG height, ULONG tagList, ...); +BOOL ScalosGfxDrawGradient(struct ARGBHeader * dest, LONG left, LONG top, LONG width, LONG height, + struct gfxARGB * start, struct gfxARGB * stop, ULONG gradType); +BOOL ScalosGfxDrawGradientRastPort(struct RastPort * rp, LONG left, LONG top, LONG width, LONG height, + struct gfxARGB * start, struct gfxARGB * stop, ULONG gradType); +VOID ScalosGfxDrawLine(struct ARGBHeader * dest, LONG fromX, LONG fromY, LONG toX, LONG toY, + const struct gfxARGB * lineColor); +VOID ScalosGfxDrawLineRastPort(struct RastPort * rp, LONG fromX, LONG fromY, LONG toX, LONG toY, + const struct gfxARGB * lineColor); +VOID ScalosGfxDrawEllipse(struct ARGBHeader * dest, LONG xCenter, LONG yCenter, LONG radiusX, + LONG radiusy, LONG segment, const struct gfxARGB * color1, + const struct gfxARGB * color2); +VOID ScalosGfxDrawEllipseRastPort(struct RastPort * rp, LONG xCenter, LONG yCenter, LONG radiusX, + LONG radiusy, LONG segment, const struct gfxARGB * color1, + const struct gfxARGB * color2); + +#endif /* CLIB_SCALOSGFX_PROTOS_H */ diff --git a/scalos/include/clib/scalosmenuplugin_protos.h b/scalos/include/clib/scalosmenuplugin_protos.h new file mode 100755 index 000000000..50f3fb1dd --- /dev/null +++ b/scalos/include/clib/scalosmenuplugin_protos.h @@ -0,0 +1,26 @@ +#ifndef CLIB_SCALOSMENUPLUGIN_PROTOS_H +#define CLIB_SCALOSMENUPLUGIN_PROTOS_H + +/* +** $Id$ +** +** C prototypes. For use with 32 bit integers only. +** +** ©1999-2002 The Scalos Team +** All Rights Reserved +*/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef SCALOS_SCALOS_H +#include +#endif +VOID SCAMenuFunction( struct ScaWindowTask *wt, struct ScaIconNode *in ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CLIB_SCALOSMENUPLUGIN_PROTOS_H */ diff --git a/scalos/include/clib/scalosplugin_protos.h b/scalos/include/clib/scalosplugin_protos.h new file mode 100755 index 000000000..b3de42c5c --- /dev/null +++ b/scalos/include/clib/scalosplugin_protos.h @@ -0,0 +1,18 @@ +#ifndef CLIB_SCALOSPLUGIN_PROTOS_H +#define CLIB_SCALOSPLUGIN_PROTOS_H + + +/* +** $VER: scalosplugin_protos.h 5.0 (10.04.2009) +** +** C prototypes. For use with 32 bit integers only. +** +** Copyright © 2009 ©1999-2002 The Scalos Team +** All Rights Reserved +*/ + +#include + +const struct ScaClassInfo * SCAGetClassInfo(void); + +#endif /* CLIB_SCALOSPLUGIN_PROTOS_H */ diff --git a/scalos/include/clib/scalosprefsplugin_protos.h b/scalos/include/clib/scalosprefsplugin_protos.h new file mode 100755 index 000000000..e8da3cd80 --- /dev/null +++ b/scalos/include/clib/scalosprefsplugin_protos.h @@ -0,0 +1,23 @@ +#ifndef CLIB_SCALOSPREFSPLUGIN_PROTOS_H +#define CLIB_SCALOSPREFSPLUGIN_PROTOS_H + +/* +** $Id$ +** +** C prototypes. For use with 32 bit integers only. +** +** ©1999-2002 The Scalos Team +** All Rights Reserved +*/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +ULONG SCAGetPrefsInfo( LONG which ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CLIB_SCALOSPREFSPLUGIN_PROTOS_H */ diff --git a/scalos/include/clib/scalospreviewplugin_protos.h b/scalos/include/clib/scalospreviewplugin_protos.h new file mode 100755 index 000000000..6670b4626 --- /dev/null +++ b/scalos/include/clib/scalospreviewplugin_protos.h @@ -0,0 +1,30 @@ +#ifndef CLIB_SCALOSPREVIEWPLUGIN_PROTOS_H +#define CLIB_SCALOSPREVIEWPLUGIN_PROTOS_H + +/* +** $Id$ +** +** C prototypes. For use with 32 bit integers only. +** +** Copyright © 2001 Amiga, Inc. +** All Rights Reserved +*/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef SCALOS_SCALOS_H +#include +#endif +#ifndef UTILITY_TAGITEM_H +#include +#endif +LONG SCAPreviewGenerate( struct ScaWindowTask *wt, BPTR dirLock, CONST_STRPTR iconName, struct TagItem *tagList ); +LONG SCAPreviewGenerateTags( struct ScaWindowTask *wt, BPTR dirLock, CONST_STRPTR iconName, ULONG firstTag, ... ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CLIB_SCALOSPREVIEWPLUGIN_PROTOS_H */ diff --git a/scalos/include/clib/sqlite3_protos.h b/scalos/include/clib/sqlite3_protos.h new file mode 100755 index 000000000..c90228794 --- /dev/null +++ b/scalos/include/clib/sqlite3_protos.h @@ -0,0 +1,138 @@ +#ifndef CLIB_SQLITE3_PROTOS_H +#define CLIB_SQLITE3_PROTOS_H + + +/* +** $VER: sqlite3_protos.h 2539 (17.08.2008) +** +** C prototypes. For use with 32 bit integers only. +** +** Copyright © 2008 ©2006 The Scalos Team +** All Rights Reserved +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef SQLITE3_H +#include +#endif + +LONG SQLite3Close(sqlite3 * db); +LONG SQLite3Exec(sqlite3 * db, CONST_STRPTR sql, sqlite3_callback xCallback, APTR pArg, + STRPTR * errmsg); +LONG SQLite3Changes(sqlite3 * db); +LONG SQLite3TotalChanges(sqlite3 * db); +VOID SQLite3Interrupt(sqlite3 * db); +LONG SQLite3Complete(CONST_STRPTR sql); +LONG SQLite3BusyHandler(sqlite3 * db, LONG (*callback)(APTR userdata, LONG l), APTR userdata); +LONG SQLite3BusyTimeout(sqlite3 * db, LONG ms); +LONG SQLite3GetTable(sqlite3 * db, CONST_STRPTR sql, STRPTR ** presult, LONG * nrow, + LONG * ncolumn, STRPTR * errmsg); +VOID SQLite3FreeTable(STRPTR * result); +VOID SQLite3Free(STRPTR z); +APTR SQLite3Trace(sqlite3 * db, VOID (*xTrace)(APTR p, CONST_STRPTR z), APTR parg); +VOID SQLite3ProgressHandler(sqlite3 * db, LONG nOps, LONG (*xProgress)(APTR p), APTR pArg); +APTR SQLite3CommitHook(sqlite3 * db, LONG (*xCallback)(APTR p), APTR pArg); +LONG SQLite3Open(CONST_STRPTR filename, sqlite3 ** ppDb); +LONG SQLite3Errcode(sqlite3 * db); +CONST_STRPTR SQLite3Errmsg(sqlite3 * db); +LONG SQLite3Prepare(sqlite3 * db, CONST_STRPTR zSql, LONG nBytes, sqlite3_stmt ** ppStmt, + CONST_STRPTR * pzTail); +LONG SQLite3BindBlob(sqlite3_stmt * pStmt, LONG i, CONST_APTR zData, LONG nData, + VOID (*xDel)(APTR p)); +LONG SQLite3BindInt(sqlite3_stmt * pStmt, LONG i, LONG iValue); +LONG SQLite3BindNull(sqlite3_stmt * pStmt, LONG i); +LONG SQLite3BindText(sqlite3_stmt * pStmt, LONG i, CONST_STRPTR zData, LONG nData, + VOID (*xDel)(APTR p)); +LONG SQLite3BindValue(sqlite3_stmt * pStmt, LONG i, CONST sqlite3_value * pVal); +LONG SQLite3BindParameterCount(sqlite3_stmt * pStmt); +CONST_STRPTR SQLite3BindParameterName(sqlite3_stmt * pStmt, LONG i); +LONG SQLite3BindParameterIndex(sqlite3_stmt * pStmt, CONST_STRPTR zName); +LONG SQLite3ClearBindings(sqlite3_stmt * pStmt); +LONG SQLite3ColumnCount(sqlite3_stmt * pStmt); +CONST_STRPTR SQLite3ColumnName(sqlite3_stmt * pStmt, LONG i); +CONST_STRPTR SQLite3ColumnDecltype(sqlite3_stmt * pStmt, LONG i); +LONG SQLite3Step(sqlite3_stmt * pStmt); +LONG SQLite3DataCount(sqlite3_stmt * pStmt); +CONST_APTR SQLite3ColumnBlob(sqlite3_stmt * pStmt, LONG iCol); +LONG SQLite3ColumnBytes(sqlite3_stmt * pStmt, LONG iCol); +LONG SQLite3ColumnInt(sqlite3_stmt * pStmt, LONG iCol); +CONST_STRPTR SQLite3ColumnText(sqlite3_stmt * pStmt, LONG iCol); +LONG SQLite3ColumnType(sqlite3_stmt * pStmt, LONG iCol); +LONG SQLite3Finalize(sqlite3_stmt * pStmt); +LONG SQLite3Reset(sqlite3_stmt * pStmt); +LONG SQLite3AggregateCount(sqlite3_context * pCtx); +CONST_APTR SQLite3ValueBlob(sqlite3_value * pVal); +LONG SQLite3ValueBytes(sqlite3_value * pVal); +LONG SQLite3ValueInt(sqlite3_value * pVal); +CONST_STRPTR SQLite3ValueText(sqlite3_value * pVal); +LONG SQLite3ValueType(sqlite3_value * pVal); +APTR SQLite3Aggregate_context(sqlite3_context * pCtx, LONG nBytes); +APTR SQLite3UserData(sqlite3_context * pCtx); +APTR SQLite3GetAuxdata(sqlite3_context * pCtx, LONG iArg); +VOID SQLite3SetAuxdata(sqlite3_context * pCtx, LONG iARg, APTR pAux, VOID (*xDelete)(APTR p)); +VOID SQLite3ResultBlob(sqlite3_context * pCtx, CONST_APTR z, LONG n, VOID (*xDelete)(APTR p)); +VOID SQLite3ResultError(sqlite3_context * pCtx, CONST_STRPTR z, LONG n); +VOID SQLite3ResultInt(sqlite3_context * pCtx, LONG iVal); +VOID SQLite3ResultNull(sqlite3_context * pCtx); +VOID SQLite3ResultText(sqlite3_context * pCtx, CONST_STRPTR z, LONG n, VOID (*xDelete)(APTR p)); +VOID SQLite3ResultValue(sqlite3_context * pCtx, sqlite3_value * pValue); +LONG SQLite3CreateCollation(sqlite3 * db, CONST_STRPTR zName, LONG eTextRep, APTR pCtx, + LONG (*xCompare)(APTR p, LONG i, CONST_APTR p2, LONG j, CONST_APTR p3)); +LONG SQLite3CollationNeeded(sqlite3 * db, APTR pCollNeededArg, + VOID (*xCollNeeded)(APTR p, sqlite3 *dv, LONG eTextRep, CONST_STRPTR z)); +LONG SQLite3Sleep(LONG ms); +LONG SQLite3Expired(sqlite3_stmt * pStmt); +LONG SQLite3TransferBindings(sqlite3_stmt * pFromStmt, sqlite3_stmt * pToStmt); +LONG SQLite3GlobalRecover(void); +LONG SQLite3GetAutocommit(sqlite3 * db); +sqlite3 * SQLite3DbHandle(sqlite3_stmt * pStmt); +APTR SQLite3RollbackHook(sqlite3 * db, VOID (*callback)(APTR pUserData), APTR pUserData); +LONG SQLite3EnableSharedCache(LONG enable); +LONG SQLite3ReleaseMemory(LONG bytesCount); +VOID SQLite3SoftHeapLimit(LONG maxBytes); +VOID SQLite3ThreadCleanup(void); +LONG SQLite3PrepareV2(sqlite3 * db, CONST_STRPTR zSql, LONG nBytes, sqlite3_stmt ** ppStmt, + CONST_STRPTR * pzTail); +LONG SQLite3CreateFunction(sqlite3 * db, CONST_STRPTR zFunctionName, LONG nArg, LONG eTextRep, + APTR userdata, + VOID (*xFunc)(sqlite3_context *pCtx, LONG i, sqlite3_value **pVal), + VOID (*xStep)(sqlite3_context *pCtx, LONG i, sqlite3_value **pVal), + VOID (*xFinal)(sqlite3_context *pCtx)); +LONG SQLite3CreateModule(sqlite3 * db, CONST_STRPTR zName, CONST sqlite3_module * methods, + APTR clientData); +LONG SQLite3DeclareVtab(sqlite3 * db, CONST_STRPTR zCreateTable); +LONG SQLite3OverloadFunction(sqlite3 * db, CONST_STRPTR zFuncName, LONG nArg); +LONG SQLite3BlobOpen(sqlite3 * db, CONST_STRPTR zDb, CONST_STRPTR zTable, + CONST_STRPTR zColumn, LONG iRow, LONG flags, sqlite3_blob ** ppBlob); +LONG SQLite3BlobClose(sqlite3_blob * blob); +LONG SQLite3BlobBytes(sqlite3_blob * blob); +LONG SQLite3BlobRead(sqlite3_blob * blob, APTR z, LONG n, LONG iOffset); +LONG SQLite3BlobWrite(sqlite3_blob * blob, CONST_APTR z, LONG n, LONG iOffset); +LONG SQLite3ExtendedResultCodes(sqlite3 * db, LONG onoff); +LONG SQLite3BindZeroBlob(sqlite3_stmt * pStmt, LONG i, LONG n); +CONST_STRPTR SQLite3ColumnDatabaseName(sqlite3_stmt * stmt, LONG n); +CONST_STRPTR SQLite3ColumnTableName(sqlite3_stmt * stmt, LONG n); +CONST_STRPTR SQLite3ColumnOriginName(sqlite3_stmt * stmt, LONG n); +sqlite3_value * SQLite3ColumnValue(sqlite3_stmt * pStmt, LONG iCol); +LONG SQLite3CreateCollationV2(sqlite3 * db, CONST_STRPTR zName, LONG eTextRep, APTR pCtx, + LONG (*xCompare)(APTR p, LONG i, CONST_APTR p2, LONG j, CONST_APTR p3), + VOID (*xDestroy)(APTR)); +CONST_STRPTR SQLite3LibVersion(void); +LONG SQLite3LibversionNumber(void); +VOID SQLite3ResultErrorToobig(sqlite3_context * pCtx); +VOID SQLite3ResultZeroBlob(sqlite3_context * pCtx, LONG n); +LONG SQLite3ValueNumericType(sqlite3_value * pVal); +LONG SQLite3ConfigV(LONG op, APTR ap); +LONG SQLite3Config(LONG op, ULONG ap, ...); +LONG SQLlite3DbConfigV(sqlite3 * db, LONG op, APTR ap); +LONG SQLlite3DbConfig(sqlite3 * db, LONG op, ULONG ap, ...); +sqlite3_vfs * SQLite3VfsFind(CONST_STRPTR zVfsName); +LONG SQLite3VfsRegister(sqlite3_vfs * vfs, LONG makeDflt); +LONG SQLite3VfsUnregister(sqlite3_vfs * vfs); +LONG SQLite3FileControl(sqlite3 * db, CONST_STRPTR zDbName, LONG op, void * arg); +LONG SQLite3Status(LONG op, LONG * pCurrent, LONG * pHighwater, LONG resetFlag); +LONG SQLite3DbStatus(sqlite3 * db, LONG op, LONG * pCur, LONG * pHiwtr, LONG resetFlg); + +#endif /* CLIB_SQLITE3_PROTOS_H */ diff --git a/scalos/include/clib/titlebarimage_protos.h b/scalos/include/clib/titlebarimage_protos.h new file mode 100755 index 000000000..d8e0f3713 --- /dev/null +++ b/scalos/include/clib/titlebarimage_protos.h @@ -0,0 +1,15 @@ + + +#ifndef CLIB_TITLEBARIMAGE_PROTOS_H +#define CLIB_TITLEBARIMAGE_PROTOS_H + + +/* Prototypes for the "titlebar image" BOOPSI public class functions */ + + +Class *ObtainTBIClass(void); + + +#endif + + diff --git a/scalos/include/clib/ttengine_protos.h b/scalos/include/clib/ttengine_protos.h new file mode 100644 index 000000000..09777c109 --- /dev/null +++ b/scalos/include/clib/ttengine_protos.h @@ -0,0 +1,56 @@ +#ifndef CLIB_TTENGINE_PROTOS_H +#define CLIB_TTENGINE_PROTOS_H + + +/* +** $VER: ttengine_protos.h 7.0 (13.01.2005) +** +** C prototypes. For use with 32 bit integers only. +** +** (c) Grzegorz Kraszewski 2003 - 2005 +** All Rights Reserved +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef UTILITY_TAGITEM_H +#include +#endif +#ifndef LIBRARIES_TTENGINE_H +#include +#endif +#ifndef GRAPHICS_TEXT_H +#include +#endif +#ifndef GRAPHICS_RASTPORT_H +#include +#endif + +APTR TT_OpenFontA(struct TagItem * taglist); +APTR TT_OpenFont(Tag tag1, ...); +BOOL TT_SetFont(struct RastPort * rp, APTR font); +void TT_CloseFont(APTR font); +void TT_Text(struct RastPort * rp, APTR string, ULONG count); +ULONG TT_SetAttrsA(struct RastPort * rp, struct TagItem * taglist); +ULONG TT_SetAttrs(struct RastPort * rp, Tag tag1, ...); +ULONG TT_GetAttrsA(struct RastPort * rp, struct TagItem * taglist); +ULONG TT_GetAttrs(struct RastPort * rp, Tag tag1, ...); +ULONG TT_TextLength(struct RastPort * rp, APTR string, ULONG count); +void TT_TextExtent(struct RastPort * rp, APTR string, WORD count, struct TextExtent * te); +ULONG TT_TextFit(struct RastPort * rp, APTR string, UWORD count, struct TextExtent * te, + struct TextExtent * tec, WORD dir, UWORD cwidth, UWORD cheight); +struct TT_Pixmap * TT_GetPixmapA(APTR font, APTR string, ULONG count, + struct TagItem * taglist); +struct TT_Pixmap * TT_GetPixmap(APTR font, APTR string, ULONG count, Tag tag1, ...); +void TT_FreePixmap(struct TT_Pixmap * pixmap); +void TT_DoneRastPort(struct RastPort * rp); +APTR TT_AllocRequest(void); +struct TagItem* TT_RequestA(APTR request, struct TagItem * taglist); +struct TagItem* TT_Request(APTR request, Tag tag1, ...); +void TT_FreeRequest(APTR request); +STRPTR * TT_ObtainFamilyListA(struct TagItem *taglist); +STRPTR * TT_ObtainFamilyList(Tag tag1, ...); +void TT_FreeFamilyList(STRPTR * list); + +#endif /* CLIB_TTENGINE_PROTOS_H */ diff --git a/scalos/include/curl/curl.h b/scalos/include/curl/curl.h new file mode 100644 index 000000000..fbd0d9b01 --- /dev/null +++ b/scalos/include/curl/curl.h @@ -0,0 +1,2125 @@ +#ifndef __CURL_CURL_H +#define __CURL_CURL_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * If you have libcurl problems, all docs and details are found here: + * http://curl.haxx.se/libcurl/ + * + * curl-library mailing list subscription and unsubscription web interface: + * http://cool.haxx.se/mailman/listinfo/curl-library/ + */ + +#include "curlver.h" /* libcurl version defines */ +#include "curlbuild.h" /* libcurl build definitions */ +#include "curlrules.h" /* libcurl rules enforcement */ + +/* + * Define WIN32 when build target is Win32 API + */ + +#if (defined(_WIN32) || defined(__WIN32__)) && \ + !defined(WIN32) && !defined(__SYMBIAN32__) +#define WIN32 +#endif + +#include +#include + +#if defined(__FreeBSD__) && (__FreeBSD__ >= 2) +/* Needed for __FreeBSD_version symbol definition */ +#include +#endif + +/* The include stuff here below is mainly for time_t! */ +#include +#include + +#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__GNUC__) && \ + !defined(__CYGWIN__) || defined(__MINGW32__) +#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H)) +/* The check above prevents the winsock2 inclusion if winsock.h already was + included, since they can't co-exist without problems */ +#include +#include +#endif +#else + +/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish + libc5-based Linux systems. Only include it on system that are known to + require it! */ +#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \ + defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \ + defined(ANDROID) || \ + (defined(__FreeBSD_version) && (__FreeBSD_version < 800000)) +#include +#endif + +#ifndef _WIN32_WCE +#include +#endif +#if !defined(WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__) +#include +#endif +#include +#endif + +#ifdef __BEOS__ +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void CURL; + +/* + * Decorate exportable functions for Win32 and Symbian OS DLL linking. + * This avoids using a .def file for building libcurl.dll. + */ +#if (defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__)) && \ + !defined(CURL_STATICLIB) +#if defined(BUILDING_LIBCURL) +#define CURL_EXTERN __declspec(dllexport) +#else +#define CURL_EXTERN __declspec(dllimport) +#endif +#else + +#ifdef CURL_HIDDEN_SYMBOLS +/* + * This definition is used to make external definitions visible in the + * shared library when symbols are hidden by default. It makes no + * difference when compiling applications whether this is set or not, + * only when compiling the library. + */ +#define CURL_EXTERN CURL_EXTERN_SYMBOL +#else +#define CURL_EXTERN +#endif +#endif + +#ifndef curl_socket_typedef +/* socket typedef */ +#ifdef WIN32 +typedef SOCKET curl_socket_t; +#define CURL_SOCKET_BAD INVALID_SOCKET +#else +typedef int curl_socket_t; +#define CURL_SOCKET_BAD -1 +#endif +#define curl_socket_typedef +#endif /* curl_socket_typedef */ + +struct curl_httppost { + struct curl_httppost *next; /* next entry in the list */ + char *name; /* pointer to allocated name */ + long namelength; /* length of name length */ + char *contents; /* pointer to allocated data contents */ + long contentslength; /* length of contents field */ + char *buffer; /* pointer to allocated buffer contents */ + long bufferlength; /* length of buffer field */ + char *contenttype; /* Content-Type */ + struct curl_slist* contentheader; /* list of extra headers for this form */ + struct curl_httppost *more; /* if one field name has more than one + file, this link should link to following + files */ + long flags; /* as defined below */ +#define HTTPPOST_FILENAME (1<<0) /* specified content is a file name */ +#define HTTPPOST_READFILE (1<<1) /* specified content is a file name */ +#define HTTPPOST_PTRNAME (1<<2) /* name is only stored pointer + do not free in formfree */ +#define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer + do not free in formfree */ +#define HTTPPOST_BUFFER (1<<4) /* upload file from buffer */ +#define HTTPPOST_PTRBUFFER (1<<5) /* upload file from pointer contents */ +#define HTTPPOST_CALLBACK (1<<6) /* upload file contents by using the + regular read callback to get the data + and pass the given pointer as custom + pointer */ + + char *showfilename; /* The file name to show. If not set, the + actual file name will be used (if this + is a file part) */ + void *userp; /* custom pointer used for + HTTPPOST_CALLBACK posts */ +}; + +typedef int (*curl_progress_callback)(void *clientp, + double dltotal, + double dlnow, + double ultotal, + double ulnow); + +#ifndef CURL_MAX_WRITE_SIZE + /* Tests have proven that 20K is a very bad buffer size for uploads on + Windows, while 16K for some odd reason performed a lot better. + We do the ifndef check to allow this value to easier be changed at build + time for those who feel adventurous. The practical minimum is about + 400 bytes since libcurl uses a buffer of this size as a scratch area + (unrelated to network send operations). */ +#define CURL_MAX_WRITE_SIZE 16384 +#endif + +#ifndef CURL_MAX_HTTP_HEADER +/* The only reason to have a max limit for this is to avoid the risk of a bad + server feeding libcurl with a never-ending header that will cause reallocs + infinitely */ +#define CURL_MAX_HTTP_HEADER (100*1024) +#endif + + +/* This is a magic return code for the write callback that, when returned, + will signal libcurl to pause receiving on the current transfer. */ +#define CURL_WRITEFUNC_PAUSE 0x10000001 +typedef size_t (*curl_write_callback)(char *buffer, + size_t size, + size_t nitems, + void *outstream); + + + +/* enumeration of file types */ +typedef enum { + CURLFILETYPE_FILE = 0, + CURLFILETYPE_DIRECTORY, + CURLFILETYPE_SYMLINK, + CURLFILETYPE_DEVICE_BLOCK, + CURLFILETYPE_DEVICE_CHAR, + CURLFILETYPE_NAMEDPIPE, + CURLFILETYPE_SOCKET, + CURLFILETYPE_DOOR, /* is possible only on Sun Solaris now */ + + CURLFILETYPE_UNKNOWN /* should never occur */ +} curlfiletype; + +#define CURLFINFOFLAG_KNOWN_FILENAME (1<<0) +#define CURLFINFOFLAG_KNOWN_FILETYPE (1<<1) +#define CURLFINFOFLAG_KNOWN_TIME (1<<2) +#define CURLFINFOFLAG_KNOWN_PERM (1<<3) +#define CURLFINFOFLAG_KNOWN_UID (1<<4) +#define CURLFINFOFLAG_KNOWN_GID (1<<5) +#define CURLFINFOFLAG_KNOWN_SIZE (1<<6) +#define CURLFINFOFLAG_KNOWN_HLINKCOUNT (1<<7) + +/* Content of this structure depends on information which is known and is + achievable (e.g. by FTP LIST parsing). Please see the url_easy_setopt(3) man + page for callbacks returning this structure -- some fields are mandatory, + some others are optional. The FLAG field has special meaning. */ +struct curl_fileinfo { + char *filename; + curlfiletype filetype; + time_t time; + unsigned int perm; + int uid; + int gid; + curl_off_t size; + long int hardlinks; + + struct { + /* If some of these fields is not NULL, it is a pointer to b_data. */ + char *time; + char *perm; + char *user; + char *group; + char *target; /* pointer to the target filename of a symlink */ + } strings; + + unsigned int flags; + + /* used internally */ + char * b_data; + size_t b_size; + size_t b_used; +}; + +/* return codes for CURLOPT_CHUNK_BGN_FUNCTION */ +#define CURL_CHUNK_BGN_FUNC_OK 0 +#define CURL_CHUNK_BGN_FUNC_FAIL 1 /* tell the lib to end the task */ +#define CURL_CHUNK_BGN_FUNC_SKIP 2 /* skip this chunk over */ + +/* if splitting of data transfer is enabled, this callback is called before + download of an individual chunk started. Note that parameter "remains" works + only for FTP wildcard downloading (for now), otherwise is not used */ +typedef long (*curl_chunk_bgn_callback)(const void *transfer_info, + void *ptr, + int remains); + +/* return codes for CURLOPT_CHUNK_END_FUNCTION */ +#define CURL_CHUNK_END_FUNC_OK 0 +#define CURL_CHUNK_END_FUNC_FAIL 1 /* tell the lib to end the task */ + +/* If splitting of data transfer is enabled this callback is called after + download of an individual chunk finished. + Note! After this callback was set then it have to be called FOR ALL chunks. + Even if downloading of this chunk was skipped in CHUNK_BGN_FUNC. + This is the reason why we don't need "transfer_info" parameter in this + callback and we are not interested in "remains" parameter too. */ +typedef long (*curl_chunk_end_callback)(void *ptr); + +/* return codes for FNMATCHFUNCTION */ +#define CURL_FNMATCHFUNC_MATCH 0 /* string corresponds to the pattern */ +#define CURL_FNMATCHFUNC_NOMATCH 1 /* pattern doesn't match the string */ +#define CURL_FNMATCHFUNC_FAIL 2 /* an error occurred */ + +/* callback type for wildcard downloading pattern matching. If the + string matches the pattern, return CURL_FNMATCHFUNC_MATCH value, etc. */ +typedef int (*curl_fnmatch_callback)(void *ptr, + const char *pattern, + const char *string); + +/* These are the return codes for the seek callbacks */ +#define CURL_SEEKFUNC_OK 0 +#define CURL_SEEKFUNC_FAIL 1 /* fail the entire transfer */ +#define CURL_SEEKFUNC_CANTSEEK 2 /* tell libcurl seeking can't be done, so + libcurl might try other means instead */ +typedef int (*curl_seek_callback)(void *instream, + curl_off_t offset, + int origin); /* 'whence' */ + +/* This is a return code for the read callback that, when returned, will + signal libcurl to immediately abort the current transfer. */ +#define CURL_READFUNC_ABORT 0x10000000 +/* This is a return code for the read callback that, when returned, will + signal libcurl to pause sending data on the current transfer. */ +#define CURL_READFUNC_PAUSE 0x10000001 + +typedef size_t (*curl_read_callback)(char *buffer, + size_t size, + size_t nitems, + void *instream); + +typedef enum { + CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */ + CURLSOCKTYPE_LAST /* never use */ +} curlsocktype; + +typedef int (*curl_sockopt_callback)(void *clientp, + curl_socket_t curlfd, + curlsocktype purpose); + +struct curl_sockaddr { + int family; + int socktype; + int protocol; + unsigned int addrlen; /* addrlen was a socklen_t type before 7.18.0 but it + turned really ugly and painful on the systems that + lack this type */ + struct sockaddr addr; +}; + +typedef curl_socket_t +(*curl_opensocket_callback)(void *clientp, + curlsocktype purpose, + struct curl_sockaddr *address); + +typedef enum { + CURLIOE_OK, /* I/O operation successful */ + CURLIOE_UNKNOWNCMD, /* command was unknown to callback */ + CURLIOE_FAILRESTART, /* failed to restart the read */ + CURLIOE_LAST /* never use */ +} curlioerr; + +typedef enum { + CURLIOCMD_NOP, /* no operation */ + CURLIOCMD_RESTARTREAD, /* restart the read stream from start */ + CURLIOCMD_LAST /* never use */ +} curliocmd; + +typedef curlioerr (*curl_ioctl_callback)(CURL *handle, + int cmd, + void *clientp); + +/* + * The following typedef's are signatures of malloc, free, realloc, strdup and + * calloc respectively. Function pointers of these types can be passed to the + * curl_global_init_mem() function to set user defined memory management + * callback routines. + */ +typedef void *(*curl_malloc_callback)(size_t size); +typedef void (*curl_free_callback)(void *ptr); +typedef void *(*curl_realloc_callback)(void *ptr, size_t size); +typedef char *(*curl_strdup_callback)(const char *str); +typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size); + +/* the kind of data that is passed to information_callback*/ +typedef enum { + CURLINFO_TEXT = 0, + CURLINFO_HEADER_IN, /* 1 */ + CURLINFO_HEADER_OUT, /* 2 */ + CURLINFO_DATA_IN, /* 3 */ + CURLINFO_DATA_OUT, /* 4 */ + CURLINFO_SSL_DATA_IN, /* 5 */ + CURLINFO_SSL_DATA_OUT, /* 6 */ + CURLINFO_END +} curl_infotype; + +typedef int (*curl_debug_callback) + (CURL *handle, /* the handle/transfer this concerns */ + curl_infotype type, /* what kind of data */ + char *data, /* points to the data */ + size_t size, /* size of the data pointed to */ + void *userptr); /* whatever the user please */ + +/* All possible error codes from all sorts of curl functions. Future versions + may return other values, stay prepared. + + Always add new return codes last. Never *EVER* remove any. The return + codes must remain the same! + */ + +typedef enum { + CURLE_OK = 0, + CURLE_UNSUPPORTED_PROTOCOL, /* 1 */ + CURLE_FAILED_INIT, /* 2 */ + CURLE_URL_MALFORMAT, /* 3 */ + CURLE_OBSOLETE4, /* 4 - NOT USED */ + CURLE_COULDNT_RESOLVE_PROXY, /* 5 */ + CURLE_COULDNT_RESOLVE_HOST, /* 6 */ + CURLE_COULDNT_CONNECT, /* 7 */ + CURLE_FTP_WEIRD_SERVER_REPLY, /* 8 */ + CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server + due to lack of access - when login fails + this is not returned. */ + CURLE_OBSOLETE10, /* 10 - NOT USED */ + CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */ + CURLE_OBSOLETE12, /* 12 - NOT USED */ + CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */ + CURLE_FTP_WEIRD_227_FORMAT, /* 14 */ + CURLE_FTP_CANT_GET_HOST, /* 15 */ + CURLE_OBSOLETE16, /* 16 - NOT USED */ + CURLE_FTP_COULDNT_SET_TYPE, /* 17 */ + CURLE_PARTIAL_FILE, /* 18 */ + CURLE_FTP_COULDNT_RETR_FILE, /* 19 */ + CURLE_OBSOLETE20, /* 20 - NOT USED */ + CURLE_QUOTE_ERROR, /* 21 - quote command failure */ + CURLE_HTTP_RETURNED_ERROR, /* 22 */ + CURLE_WRITE_ERROR, /* 23 */ + CURLE_OBSOLETE24, /* 24 - NOT USED */ + CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */ + CURLE_READ_ERROR, /* 26 - couldn't open/read from file */ + CURLE_OUT_OF_MEMORY, /* 27 */ + /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error + instead of a memory allocation error if CURL_DOES_CONVERSIONS + is defined + */ + CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time was reached */ + CURLE_OBSOLETE29, /* 29 - NOT USED */ + CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */ + CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */ + CURLE_OBSOLETE32, /* 32 - NOT USED */ + CURLE_RANGE_ERROR, /* 33 - RANGE "command" didn't work */ + CURLE_HTTP_POST_ERROR, /* 34 */ + CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */ + CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */ + CURLE_FILE_COULDNT_READ_FILE, /* 37 */ + CURLE_LDAP_CANNOT_BIND, /* 38 */ + CURLE_LDAP_SEARCH_FAILED, /* 39 */ + CURLE_OBSOLETE40, /* 40 - NOT USED */ + CURLE_FUNCTION_NOT_FOUND, /* 41 */ + CURLE_ABORTED_BY_CALLBACK, /* 42 */ + CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */ + CURLE_OBSOLETE44, /* 44 - NOT USED */ + CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */ + CURLE_OBSOLETE46, /* 46 - NOT USED */ + CURLE_TOO_MANY_REDIRECTS , /* 47 - catch endless re-direct loops */ + CURLE_UNKNOWN_TELNET_OPTION, /* 48 - User specified an unknown option */ + CURLE_TELNET_OPTION_SYNTAX , /* 49 - Malformed telnet option */ + CURLE_OBSOLETE50, /* 50 - NOT USED */ + CURLE_PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint + wasn't verified fine */ + CURLE_GOT_NOTHING, /* 52 - when this is a specific error */ + CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */ + CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as + default */ + CURLE_SEND_ERROR, /* 55 - failed sending network data */ + CURLE_RECV_ERROR, /* 56 - failure in receiving network data */ + CURLE_OBSOLETE57, /* 57 - NOT IN USE */ + CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */ + CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */ + CURLE_SSL_CACERT, /* 60 - problem with the CA cert (path?) */ + CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized transfer encoding */ + CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */ + CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */ + CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */ + CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind + that failed */ + CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */ + CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not + accepted and we failed to login */ + CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */ + CURLE_TFTP_PERM, /* 69 - permission problem on server */ + CURLE_REMOTE_DISK_FULL, /* 70 - out of disk space on server */ + CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */ + CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */ + CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */ + CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */ + CURLE_CONV_FAILED, /* 75 - conversion failed */ + CURLE_CONV_REQD, /* 76 - caller must register conversion + callbacks using curl_easy_setopt options + CURLOPT_CONV_FROM_NETWORK_FUNCTION, + CURLOPT_CONV_TO_NETWORK_FUNCTION, and + CURLOPT_CONV_FROM_UTF8_FUNCTION */ + CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing + or wrong format */ + CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */ + CURLE_SSH, /* 79 - error from the SSH layer, somewhat + generic so the error message will be of + interest when this has happened */ + + CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL + connection */ + CURLE_AGAIN, /* 81 - socket is not ready for send/recv, + wait till it's ready and try again (Added + in 7.18.2) */ + CURLE_SSL_CRL_BADFILE, /* 82 - could not load CRL file, missing or + wrong format (Added in 7.19.0) */ + CURLE_SSL_ISSUER_ERROR, /* 83 - Issuer check failed. (Added in + 7.19.0) */ + CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */ + CURLE_RTSP_CSEQ_ERROR, /* 85 - mismatch of RTSP CSeq numbers */ + CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Identifiers */ + CURLE_FTP_BAD_FILE_LIST, /* 87 - unable to parse FTP file list */ + CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */ + + CURL_LAST /* never use! */ +} CURLcode; + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Backwards compatibility with older names */ + +/* The following were added in 7.17.1 */ +/* These are scheduled to disappear by 2009 */ +#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION + +/* The following were added in 7.17.0 */ +/* These are scheduled to disappear by 2009 */ +#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* noone should be using this! */ +#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46 +#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44 +#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10 +#define CURLE_FTP_CANT_RECONNECT CURLE_OBSOLETE16 +#define CURLE_FTP_COULDNT_GET_SIZE CURLE_OBSOLETE32 +#define CURLE_FTP_COULDNT_SET_ASCII CURLE_OBSOLETE29 +#define CURLE_FTP_WEIRD_USER_REPLY CURLE_OBSOLETE12 +#define CURLE_FTP_WRITE_ERROR CURLE_OBSOLETE20 +#define CURLE_LIBRARY_NOT_FOUND CURLE_OBSOLETE40 +#define CURLE_MALFORMAT_USER CURLE_OBSOLETE24 +#define CURLE_SHARE_IN_USE CURLE_OBSOLETE57 +#define CURLE_URL_MALFORMAT_USER CURLE_OBSOLETE4 + +#define CURLE_FTP_ACCESS_DENIED CURLE_REMOTE_ACCESS_DENIED +#define CURLE_FTP_COULDNT_SET_BINARY CURLE_FTP_COULDNT_SET_TYPE +#define CURLE_FTP_QUOTE_ERROR CURLE_QUOTE_ERROR +#define CURLE_TFTP_DISKFULL CURLE_REMOTE_DISK_FULL +#define CURLE_TFTP_EXISTS CURLE_REMOTE_FILE_EXISTS +#define CURLE_HTTP_RANGE_ERROR CURLE_RANGE_ERROR +#define CURLE_FTP_SSL_FAILED CURLE_USE_SSL_FAILED + +/* The following were added earlier */ + +#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT + +#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR +#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED +#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED + +#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE +#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME + +/* This was the error code 50 in 7.7.3 and a few earlier versions, this + is no longer used by libcurl but is instead #defined here only to not + make programs break */ +#define CURLE_ALREADY_COMPLETE 99999 + +#endif /*!CURL_NO_OLDIES*/ + +/* This prototype applies to all conversion callbacks */ +typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length); + +typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */ + void *ssl_ctx, /* actually an + OpenSSL SSL_CTX */ + void *userptr); + +typedef enum { + CURLPROXY_HTTP = 0, /* added in 7.10, new in 7.19.4 default is to use + CONNECT HTTP/1.1 */ + CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT + HTTP/1.0 */ + CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already + in 7.10 */ + CURLPROXY_SOCKS5 = 5, /* added in 7.10 */ + CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */ + CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the + host name rather than the IP address. added + in 7.18.0 */ +} curl_proxytype; /* this enum was added in 7.10 */ + +#define CURLAUTH_NONE 0 /* nothing */ +#define CURLAUTH_BASIC (1<<0) /* Basic (default) */ +#define CURLAUTH_DIGEST (1<<1) /* Digest */ +#define CURLAUTH_GSSNEGOTIATE (1<<2) /* GSS-Negotiate */ +#define CURLAUTH_NTLM (1<<3) /* NTLM */ +#define CURLAUTH_DIGEST_IE (1<<4) /* Digest with IE flavour */ +#define CURLAUTH_ONLY (1<<31) /* used together with a single other + type to force no auth or just that + single type */ +#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE) /* all fine types set */ +#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE)) + +#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */ +#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */ +#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */ +#define CURLSSH_AUTH_PASSWORD (1<<1) /* password */ +#define CURLSSH_AUTH_HOST (1<<2) /* host key files */ +#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */ +#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY + +#define CURL_ERROR_SIZE 256 + +struct curl_khkey { + const char *key; /* points to a zero-terminated string encoded with base64 + if len is zero, otherwise to the "raw" data */ + size_t len; + enum type { + CURLKHTYPE_UNKNOWN, + CURLKHTYPE_RSA1, + CURLKHTYPE_RSA, + CURLKHTYPE_DSS + } keytype; +}; + +/* this is the set of return values expected from the curl_sshkeycallback + callback */ +enum curl_khstat { + CURLKHSTAT_FINE_ADD_TO_FILE, + CURLKHSTAT_FINE, + CURLKHSTAT_REJECT, /* reject the connection, return an error */ + CURLKHSTAT_DEFER, /* do not accept it, but we can't answer right now so + this causes a CURLE_DEFER error but otherwise the + connection will be left intact etc */ + CURLKHSTAT_LAST /* not for use, only a marker for last-in-list */ +}; + +/* this is the set of status codes pass in to the callback */ +enum curl_khmatch { + CURLKHMATCH_OK, /* match */ + CURLKHMATCH_MISMATCH, /* host found, key mismatch! */ + CURLKHMATCH_MISSING, /* no matching host/key found */ + CURLKHMATCH_LAST /* not for use, only a marker for last-in-list */ +}; + +typedef int + (*curl_sshkeycallback) (CURL *easy, /* easy handle */ + const struct curl_khkey *knownkey, /* known */ + const struct curl_khkey *foundkey, /* found */ + enum curl_khmatch, /* libcurl's view on the keys */ + void *clientp); /* custom pointer passed from app */ + +/* parameter for the CURLOPT_USE_SSL option */ +typedef enum { + CURLUSESSL_NONE, /* do not attempt to use SSL */ + CURLUSESSL_TRY, /* try using SSL, proceed anyway otherwise */ + CURLUSESSL_CONTROL, /* SSL for the control connection or fail */ + CURLUSESSL_ALL, /* SSL for all communication or fail */ + CURLUSESSL_LAST /* not an option, never use */ +} curl_usessl; + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Backwards compatibility with older names */ +/* These are scheduled to disappear by 2009 */ + +#define CURLFTPSSL_NONE CURLUSESSL_NONE +#define CURLFTPSSL_TRY CURLUSESSL_TRY +#define CURLFTPSSL_CONTROL CURLUSESSL_CONTROL +#define CURLFTPSSL_ALL CURLUSESSL_ALL +#define CURLFTPSSL_LAST CURLUSESSL_LAST +#define curl_ftpssl curl_usessl +#endif /*!CURL_NO_OLDIES*/ + +/* parameter for the CURLOPT_FTP_SSL_CCC option */ +typedef enum { + CURLFTPSSL_CCC_NONE, /* do not send CCC */ + CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */ + CURLFTPSSL_CCC_ACTIVE, /* Initiate the shutdown */ + CURLFTPSSL_CCC_LAST /* not an option, never use */ +} curl_ftpccc; + +/* parameter for the CURLOPT_FTPSSLAUTH option */ +typedef enum { + CURLFTPAUTH_DEFAULT, /* let libcurl decide */ + CURLFTPAUTH_SSL, /* use "AUTH SSL" */ + CURLFTPAUTH_TLS, /* use "AUTH TLS" */ + CURLFTPAUTH_LAST /* not an option, never use */ +} curl_ftpauth; + +/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */ +typedef enum { + CURLFTP_CREATE_DIR_NONE, /* do NOT create missing dirs! */ + CURLFTP_CREATE_DIR, /* (FTP/SFTP) if CWD fails, try MKD and then CWD + again if MKD succeeded, for SFTP this does + similar magic */ + CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD + again even if MKD failed! */ + CURLFTP_CREATE_DIR_LAST /* not an option, never use */ +} curl_ftpcreatedir; + +/* parameter for the CURLOPT_FTP_FILEMETHOD option */ +typedef enum { + CURLFTPMETHOD_DEFAULT, /* let libcurl pick */ + CURLFTPMETHOD_MULTICWD, /* single CWD operation for each path part */ + CURLFTPMETHOD_NOCWD, /* no CWD at all */ + CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */ + CURLFTPMETHOD_LAST /* not an option, never use */ +} curl_ftpmethod; + +/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */ +#define CURLPROTO_HTTP (1<<0) +#define CURLPROTO_HTTPS (1<<1) +#define CURLPROTO_FTP (1<<2) +#define CURLPROTO_FTPS (1<<3) +#define CURLPROTO_SCP (1<<4) +#define CURLPROTO_SFTP (1<<5) +#define CURLPROTO_TELNET (1<<6) +#define CURLPROTO_LDAP (1<<7) +#define CURLPROTO_LDAPS (1<<8) +#define CURLPROTO_DICT (1<<9) +#define CURLPROTO_FILE (1<<10) +#define CURLPROTO_TFTP (1<<11) +#define CURLPROTO_IMAP (1<<12) +#define CURLPROTO_IMAPS (1<<13) +#define CURLPROTO_POP3 (1<<14) +#define CURLPROTO_POP3S (1<<15) +#define CURLPROTO_SMTP (1<<16) +#define CURLPROTO_SMTPS (1<<17) +#define CURLPROTO_RTSP (1<<18) +#define CURLPROTO_RTMP (1<<19) +#define CURLPROTO_RTMPT (1<<20) +#define CURLPROTO_RTMPE (1<<21) +#define CURLPROTO_RTMPTE (1<<22) +#define CURLPROTO_RTMPS (1<<23) +#define CURLPROTO_RTMPTS (1<<24) +#define CURLPROTO_GOPHER (1<<25) +#define CURLPROTO_ALL (~0) /* enable everything */ + +/* long may be 32 or 64 bits, but we should never depend on anything else + but 32 */ +#define CURLOPTTYPE_LONG 0 +#define CURLOPTTYPE_OBJECTPOINT 10000 +#define CURLOPTTYPE_FUNCTIONPOINT 20000 +#define CURLOPTTYPE_OFF_T 30000 + +/* name is uppercase CURLOPT_, + type is one of the defined CURLOPTTYPE_ + number is unique identifier */ +#ifdef CINIT +#undef CINIT +#endif + +#ifdef CURL_ISOCPP +#define CINIT(name,type,number) CURLOPT_ ## name = CURLOPTTYPE_ ## type + number +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define LONG CURLOPTTYPE_LONG +#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT +#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT +#define OFF_T CURLOPTTYPE_OFF_T +#define CINIT(name,type,number) CURLOPT_/**/name = type + number +#endif + +/* + * This macro-mania below setups the CURLOPT_[what] enum, to be used with + * curl_easy_setopt(). The first argument in the CINIT() macro is the [what] + * word. + */ + +typedef enum { + /* This is the FILE * or void * the regular output should be written to. */ + CINIT(FILE, OBJECTPOINT, 1), + + /* The full URL to get/put */ + CINIT(URL, OBJECTPOINT, 2), + + /* Port number to connect to, if other than default. */ + CINIT(PORT, LONG, 3), + + /* Name of proxy to use. */ + CINIT(PROXY, OBJECTPOINT, 4), + + /* "name:password" to use when fetching. */ + CINIT(USERPWD, OBJECTPOINT, 5), + + /* "name:password" to use with proxy. */ + CINIT(PROXYUSERPWD, OBJECTPOINT, 6), + + /* Range to get, specified as an ASCII string. */ + CINIT(RANGE, OBJECTPOINT, 7), + + /* not used */ + + /* Specified file stream to upload from (use as input): */ + CINIT(INFILE, OBJECTPOINT, 9), + + /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE + * bytes big. If this is not used, error messages go to stderr instead: */ + CINIT(ERRORBUFFER, OBJECTPOINT, 10), + + /* Function that will be called to store the output (instead of fwrite). The + * parameters will use fwrite() syntax, make sure to follow them. */ + CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11), + + /* Function that will be called to read the input (instead of fread). The + * parameters will use fread() syntax, make sure to follow them. */ + CINIT(READFUNCTION, FUNCTIONPOINT, 12), + + /* Time-out the read operation after this amount of seconds */ + CINIT(TIMEOUT, LONG, 13), + + /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about + * how large the file being sent really is. That allows better error + * checking and better verifies that the upload was successful. -1 means + * unknown size. + * + * For large file support, there is also a _LARGE version of the key + * which takes an off_t type, allowing platforms with larger off_t + * sizes to handle larger files. See below for INFILESIZE_LARGE. + */ + CINIT(INFILESIZE, LONG, 14), + + /* POST static input fields. */ + CINIT(POSTFIELDS, OBJECTPOINT, 15), + + /* Set the referrer page (needed by some CGIs) */ + CINIT(REFERER, OBJECTPOINT, 16), + + /* Set the FTP PORT string (interface name, named or numerical IP address) + Use i.e '-' to use default address. */ + CINIT(FTPPORT, OBJECTPOINT, 17), + + /* Set the User-Agent string (examined by some CGIs) */ + CINIT(USERAGENT, OBJECTPOINT, 18), + + /* If the download receives less than "low speed limit" bytes/second + * during "low speed time" seconds, the operations is aborted. + * You could i.e if you have a pretty high speed connection, abort if + * it is less than 2000 bytes/sec during 20 seconds. + */ + + /* Set the "low speed limit" */ + CINIT(LOW_SPEED_LIMIT, LONG, 19), + + /* Set the "low speed time" */ + CINIT(LOW_SPEED_TIME, LONG, 20), + + /* Set the continuation offset. + * + * Note there is also a _LARGE version of this key which uses + * off_t types, allowing for large file offsets on platforms which + * use larger-than-32-bit off_t's. Look below for RESUME_FROM_LARGE. + */ + CINIT(RESUME_FROM, LONG, 21), + + /* Set cookie in request: */ + CINIT(COOKIE, OBJECTPOINT, 22), + + /* This points to a linked list of headers, struct curl_slist kind */ + CINIT(HTTPHEADER, OBJECTPOINT, 23), + + /* This points to a linked list of post entries, struct curl_httppost */ + CINIT(HTTPPOST, OBJECTPOINT, 24), + + /* name of the file keeping your private SSL-certificate */ + CINIT(SSLCERT, OBJECTPOINT, 25), + + /* password for the SSL or SSH private key */ + CINIT(KEYPASSWD, OBJECTPOINT, 26), + + /* send TYPE parameter? */ + CINIT(CRLF, LONG, 27), + + /* send linked-list of QUOTE commands */ + CINIT(QUOTE, OBJECTPOINT, 28), + + /* send FILE * or void * to store headers to, if you use a callback it + is simply passed to the callback unmodified */ + CINIT(WRITEHEADER, OBJECTPOINT, 29), + + /* point to a file to read the initial cookies from, also enables + "cookie awareness" */ + CINIT(COOKIEFILE, OBJECTPOINT, 31), + + /* What version to specifically try to use. + See CURL_SSLVERSION defines below. */ + CINIT(SSLVERSION, LONG, 32), + + /* What kind of HTTP time condition to use, see defines */ + CINIT(TIMECONDITION, LONG, 33), + + /* Time to use with the above condition. Specified in number of seconds + since 1 Jan 1970 */ + CINIT(TIMEVALUE, LONG, 34), + + /* 35 = OBSOLETE */ + + /* Custom request, for customizing the get command like + HTTP: DELETE, TRACE and others + FTP: to use a different list command + */ + CINIT(CUSTOMREQUEST, OBJECTPOINT, 36), + + /* HTTP request, for odd commands like DELETE, TRACE and others */ + CINIT(STDERR, OBJECTPOINT, 37), + + /* 38 is not used */ + + /* send linked-list of post-transfer QUOTE commands */ + CINIT(POSTQUOTE, OBJECTPOINT, 39), + + /* Pass a pointer to string of the output using full variable-replacement + as described elsewhere. */ + CINIT(WRITEINFO, OBJECTPOINT, 40), + + CINIT(VERBOSE, LONG, 41), /* talk a lot */ + CINIT(HEADER, LONG, 42), /* throw the header out too */ + CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */ + CINIT(NOBODY, LONG, 44), /* use HEAD to get http document */ + CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 300 */ + CINIT(UPLOAD, LONG, 46), /* this is an upload */ + CINIT(POST, LONG, 47), /* HTTP POST method */ + CINIT(DIRLISTONLY, LONG, 48), /* return bare names when listing directories */ + + CINIT(APPEND, LONG, 50), /* Append instead of overwrite on upload! */ + + /* Specify whether to read the user+password from the .netrc or the URL. + * This must be one of the CURL_NETRC_* enums below. */ + CINIT(NETRC, LONG, 51), + + CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */ + + CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */ + CINIT(PUT, LONG, 54), /* HTTP PUT */ + + /* 55 = OBSOLETE */ + + /* Function that will be called instead of the internal progress display + * function. This function should be defined as the curl_progress_callback + * prototype defines. */ + CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56), + + /* Data passed to the progress callback */ + CINIT(PROGRESSDATA, OBJECTPOINT, 57), + + /* We want the referrer field set automatically when following locations */ + CINIT(AUTOREFERER, LONG, 58), + + /* Port of the proxy, can be set in the proxy string as well with: + "[host]:[port]" */ + CINIT(PROXYPORT, LONG, 59), + + /* size of the POST input data, if strlen() is not good to use */ + CINIT(POSTFIELDSIZE, LONG, 60), + + /* tunnel non-http operations through a HTTP proxy */ + CINIT(HTTPPROXYTUNNEL, LONG, 61), + + /* Set the interface string to use as outgoing network interface */ + CINIT(INTERFACE, OBJECTPOINT, 62), + + /* Set the krb4/5 security level, this also enables krb4/5 awareness. This + * is a string, 'clear', 'safe', 'confidential' or 'private'. If the string + * is set but doesn't match one of these, 'private' will be used. */ + CINIT(KRBLEVEL, OBJECTPOINT, 63), + + /* Set if we should verify the peer in ssl handshake, set 1 to verify. */ + CINIT(SSL_VERIFYPEER, LONG, 64), + + /* The CApath or CAfile used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CINIT(CAINFO, OBJECTPOINT, 65), + + /* 66 = OBSOLETE */ + /* 67 = OBSOLETE */ + + /* Maximum number of http redirects to follow */ + CINIT(MAXREDIRS, LONG, 68), + + /* Pass a long set to 1 to get the date of the requested document (if + possible)! Pass a zero to shut it off. */ + CINIT(FILETIME, LONG, 69), + + /* This points to a linked list of telnet options */ + CINIT(TELNETOPTIONS, OBJECTPOINT, 70), + + /* Max amount of cached alive connections */ + CINIT(MAXCONNECTS, LONG, 71), + + /* What policy to use when closing connections when the cache is filled + up */ + CINIT(CLOSEPOLICY, LONG, 72), + + /* 73 = OBSOLETE */ + + /* Set to explicitly use a new connection for the upcoming transfer. + Do not use this unless you're absolutely sure of this, as it makes the + operation slower and is less friendly for the network. */ + CINIT(FRESH_CONNECT, LONG, 74), + + /* Set to explicitly forbid the upcoming transfer's connection to be re-used + when done. Do not use this unless you're absolutely sure of this, as it + makes the operation slower and is less friendly for the network. */ + CINIT(FORBID_REUSE, LONG, 75), + + /* Set to a file name that contains random data for libcurl to use to + seed the random engine when doing SSL connects. */ + CINIT(RANDOM_FILE, OBJECTPOINT, 76), + + /* Set to the Entropy Gathering Daemon socket pathname */ + CINIT(EGDSOCKET, OBJECTPOINT, 77), + + /* Time-out connect operations after this amount of seconds, if connects + are OK within this time, then fine... This only aborts the connect + phase. [Only works on unix-style/SIGALRM operating systems] */ + CINIT(CONNECTTIMEOUT, LONG, 78), + + /* Function that will be called to store headers (instead of fwrite). The + * parameters will use fwrite() syntax, make sure to follow them. */ + CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79), + + /* Set this to force the HTTP request to get back to GET. Only really usable + if POST, PUT or a custom request have been used first. + */ + CINIT(HTTPGET, LONG, 80), + + /* Set if we should verify the Common name from the peer certificate in ssl + * handshake, set 1 to check existence, 2 to ensure that it matches the + * provided hostname. */ + CINIT(SSL_VERIFYHOST, LONG, 81), + + /* Specify which file name to write all known cookies in after completed + operation. Set file name to "-" (dash) to make it go to stdout. */ + CINIT(COOKIEJAR, OBJECTPOINT, 82), + + /* Specify which SSL ciphers to use */ + CINIT(SSL_CIPHER_LIST, OBJECTPOINT, 83), + + /* Specify which HTTP version to use! This must be set to one of the + CURL_HTTP_VERSION* enums set below. */ + CINIT(HTTP_VERSION, LONG, 84), + + /* Specifically switch on or off the FTP engine's use of the EPSV command. By + default, that one will always be attempted before the more traditional + PASV command. */ + CINIT(FTP_USE_EPSV, LONG, 85), + + /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */ + CINIT(SSLCERTTYPE, OBJECTPOINT, 86), + + /* name of the file keeping your private SSL-key */ + CINIT(SSLKEY, OBJECTPOINT, 87), + + /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */ + CINIT(SSLKEYTYPE, OBJECTPOINT, 88), + + /* crypto engine for the SSL-sub system */ + CINIT(SSLENGINE, OBJECTPOINT, 89), + + /* set the crypto engine for the SSL-sub system as default + the param has no meaning... + */ + CINIT(SSLENGINE_DEFAULT, LONG, 90), + + /* Non-zero value means to use the global dns cache */ + CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* To become OBSOLETE soon */ + + /* DNS cache timeout */ + CINIT(DNS_CACHE_TIMEOUT, LONG, 92), + + /* send linked-list of pre-transfer QUOTE commands */ + CINIT(PREQUOTE, OBJECTPOINT, 93), + + /* set the debug function */ + CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94), + + /* set the data for the debug function */ + CINIT(DEBUGDATA, OBJECTPOINT, 95), + + /* mark this as start of a cookie session */ + CINIT(COOKIESESSION, LONG, 96), + + /* The CApath directory used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CINIT(CAPATH, OBJECTPOINT, 97), + + /* Instruct libcurl to use a smaller receive buffer */ + CINIT(BUFFERSIZE, LONG, 98), + + /* Instruct libcurl to not use any signal/alarm handlers, even when using + timeouts. This option is useful for multi-threaded applications. + See libcurl-the-guide for more background information. */ + CINIT(NOSIGNAL, LONG, 99), + + /* Provide a CURLShare for mutexing non-ts data */ + CINIT(SHARE, OBJECTPOINT, 100), + + /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default), + CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5. */ + CINIT(PROXYTYPE, LONG, 101), + + /* Set the Accept-Encoding string. Use this to tell a server you would like + the response to be compressed. */ + CINIT(ENCODING, OBJECTPOINT, 102), + + /* Set pointer to private data */ + CINIT(PRIVATE, OBJECTPOINT, 103), + + /* Set aliases for HTTP 200 in the HTTP Response header */ + CINIT(HTTP200ALIASES, OBJECTPOINT, 104), + + /* Continue to send authentication (user+password) when following locations, + even when hostname changed. This can potentially send off the name + and password to whatever host the server decides. */ + CINIT(UNRESTRICTED_AUTH, LONG, 105), + + /* Specifically switch on or off the FTP engine's use of the EPRT command ( it + also disables the LPRT attempt). By default, those ones will always be + attempted before the good old traditional PORT command. */ + CINIT(FTP_USE_EPRT, LONG, 106), + + /* Set this to a bitmask value to enable the particular authentications + methods you like. Use this in combination with CURLOPT_USERPWD. + Note that setting multiple bits may cause extra network round-trips. */ + CINIT(HTTPAUTH, LONG, 107), + + /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx + in second argument. The function must be matching the + curl_ssl_ctx_callback proto. */ + CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108), + + /* Set the userdata for the ssl context callback function's third + argument */ + CINIT(SSL_CTX_DATA, OBJECTPOINT, 109), + + /* FTP Option that causes missing dirs to be created on the remote server. + In 7.19.4 we introduced the convenience enums for this option using the + CURLFTP_CREATE_DIR prefix. + */ + CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110), + + /* Set this to a bitmask value to enable the particular authentications + methods you like. Use this in combination with CURLOPT_PROXYUSERPWD. + Note that setting multiple bits may cause extra network round-trips. */ + CINIT(PROXYAUTH, LONG, 111), + + /* FTP option that changes the timeout, in seconds, associated with + getting a response. This is different from transfer timeout time and + essentially places a demand on the FTP server to acknowledge commands + in a timely manner. */ + CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112), +#define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT + + /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to + tell libcurl to resolve names to those IP versions only. This only has + affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */ + CINIT(IPRESOLVE, LONG, 113), + + /* Set this option to limit the size of a file that will be downloaded from + an HTTP or FTP server. + + Note there is also _LARGE version which adds large file support for + platforms which have larger off_t sizes. See MAXFILESIZE_LARGE below. */ + CINIT(MAXFILESIZE, LONG, 114), + + /* See the comment for INFILESIZE above, but in short, specifies + * the size of the file being uploaded. -1 means unknown. + */ + CINIT(INFILESIZE_LARGE, OFF_T, 115), + + /* Sets the continuation offset. There is also a LONG version of this; + * look above for RESUME_FROM. + */ + CINIT(RESUME_FROM_LARGE, OFF_T, 116), + + /* Sets the maximum size of data that will be downloaded from + * an HTTP or FTP server. See MAXFILESIZE above for the LONG version. + */ + CINIT(MAXFILESIZE_LARGE, OFF_T, 117), + + /* Set this option to the file name of your .netrc file you want libcurl + to parse (using the CURLOPT_NETRC option). If not set, libcurl will do + a poor attempt to find the user's home directory and check for a .netrc + file in there. */ + CINIT(NETRC_FILE, OBJECTPOINT, 118), + + /* Enable SSL/TLS for FTP, pick one of: + CURLFTPSSL_TRY - try using SSL, proceed anyway otherwise + CURLFTPSSL_CONTROL - SSL for the control connection or fail + CURLFTPSSL_ALL - SSL for all communication or fail + */ + CINIT(USE_SSL, LONG, 119), + + /* The _LARGE version of the standard POSTFIELDSIZE option */ + CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120), + + /* Enable/disable the TCP Nagle algorithm */ + CINIT(TCP_NODELAY, LONG, 121), + + /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 123 OBSOLETE. Gone in 7.16.0 */ + /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 127 OBSOLETE. Gone in 7.16.0 */ + /* 128 OBSOLETE. Gone in 7.16.0 */ + + /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option + can be used to change libcurl's default action which is to first try + "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK + response has been received. + + Available parameters are: + CURLFTPAUTH_DEFAULT - let libcurl decide + CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS + CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL + */ + CINIT(FTPSSLAUTH, LONG, 129), + + CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130), + CINIT(IOCTLDATA, OBJECTPOINT, 131), + + /* 132 OBSOLETE. Gone in 7.16.0 */ + /* 133 OBSOLETE. Gone in 7.16.0 */ + + /* zero terminated string for pass on to the FTP server when asked for + "account" info */ + CINIT(FTP_ACCOUNT, OBJECTPOINT, 134), + + /* feed cookies into cookie engine */ + CINIT(COOKIELIST, OBJECTPOINT, 135), + + /* ignore Content-Length */ + CINIT(IGNORE_CONTENT_LENGTH, LONG, 136), + + /* Set to non-zero to skip the IP address received in a 227 PASV FTP server + response. Typically used for FTP-SSL purposes but is not restricted to + that. libcurl will then instead use the same IP address it used for the + control connection. */ + CINIT(FTP_SKIP_PASV_IP, LONG, 137), + + /* Select "file method" to use when doing FTP, see the curl_ftpmethod + above. */ + CINIT(FTP_FILEMETHOD, LONG, 138), + + /* Local port number to bind the socket to */ + CINIT(LOCALPORT, LONG, 139), + + /* Number of ports to try, including the first one set with LOCALPORT. + Thus, setting it to 1 will make no additional attempts but the first. + */ + CINIT(LOCALPORTRANGE, LONG, 140), + + /* no transfer, set up connection and let application use the socket by + extracting it with CURLINFO_LASTSOCKET */ + CINIT(CONNECT_ONLY, LONG, 141), + + /* Function that will be called to convert from the + network encoding (instead of using the iconv calls in libcurl) */ + CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142), + + /* Function that will be called to convert to the + network encoding (instead of using the iconv calls in libcurl) */ + CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143), + + /* Function that will be called to convert from UTF8 + (instead of using the iconv calls in libcurl) + Note that this is used only for SSL certificate processing */ + CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144), + + /* if the connection proceeds too quickly then need to slow it down */ + /* limit-rate: maximum number of bytes per second to send or receive */ + CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145), + CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146), + + /* Pointer to command string to send if USER/PASS fails. */ + CINIT(FTP_ALTERNATIVE_TO_USER, OBJECTPOINT, 147), + + /* callback function for setting socket options */ + CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148), + CINIT(SOCKOPTDATA, OBJECTPOINT, 149), + + /* set to 0 to disable session ID re-use for this transfer, default is + enabled (== 1) */ + CINIT(SSL_SESSIONID_CACHE, LONG, 150), + + /* allowed SSH authentication methods */ + CINIT(SSH_AUTH_TYPES, LONG, 151), + + /* Used by scp/sftp to do public/private key authentication */ + CINIT(SSH_PUBLIC_KEYFILE, OBJECTPOINT, 152), + CINIT(SSH_PRIVATE_KEYFILE, OBJECTPOINT, 153), + + /* Send CCC (Clear Command Channel) after authentication */ + CINIT(FTP_SSL_CCC, LONG, 154), + + /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */ + CINIT(TIMEOUT_MS, LONG, 155), + CINIT(CONNECTTIMEOUT_MS, LONG, 156), + + /* set to zero to disable the libcurl's decoding and thus pass the raw body + data to the application even when it is encoded/compressed */ + CINIT(HTTP_TRANSFER_DECODING, LONG, 157), + CINIT(HTTP_CONTENT_DECODING, LONG, 158), + + /* Permission used when creating new files and directories on the remote + server for protocols that support it, SFTP/SCP/FILE */ + CINIT(NEW_FILE_PERMS, LONG, 159), + CINIT(NEW_DIRECTORY_PERMS, LONG, 160), + + /* Set the behaviour of POST when redirecting. Values must be set to one + of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */ + CINIT(POSTREDIR, LONG, 161), + + /* used by scp/sftp to verify the host's public key */ + CINIT(SSH_HOST_PUBLIC_KEY_MD5, OBJECTPOINT, 162), + + /* Callback function for opening socket (instead of socket(2)). Optionally, + callback is able change the address or refuse to connect returning + CURL_SOCKET_BAD. The callback should have type + curl_opensocket_callback */ + CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163), + CINIT(OPENSOCKETDATA, OBJECTPOINT, 164), + + /* POST volatile input fields. */ + CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165), + + /* set transfer mode (;type=) when doing FTP via an HTTP proxy */ + CINIT(PROXY_TRANSFER_MODE, LONG, 166), + + /* Callback function for seeking in the input stream */ + CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167), + CINIT(SEEKDATA, OBJECTPOINT, 168), + + /* CRL file */ + CINIT(CRLFILE, OBJECTPOINT, 169), + + /* Issuer certificate */ + CINIT(ISSUERCERT, OBJECTPOINT, 170), + + /* (IPv6) Address scope */ + CINIT(ADDRESS_SCOPE, LONG, 171), + + /* Collect certificate chain info and allow it to get retrievable with + CURLINFO_CERTINFO after the transfer is complete. (Unfortunately) only + working with OpenSSL-powered builds. */ + CINIT(CERTINFO, LONG, 172), + + /* "name" and "pwd" to use when fetching. */ + CINIT(USERNAME, OBJECTPOINT, 173), + CINIT(PASSWORD, OBJECTPOINT, 174), + + /* "name" and "pwd" to use with Proxy when fetching. */ + CINIT(PROXYUSERNAME, OBJECTPOINT, 175), + CINIT(PROXYPASSWORD, OBJECTPOINT, 176), + + /* Comma separated list of hostnames defining no-proxy zones. These should + match both hostnames directly, and hostnames within a domain. For + example, local.com will match local.com and www.local.com, but NOT + notlocal.com or www.notlocal.com. For compatibility with other + implementations of this, .local.com will be considered to be the same as + local.com. A single * is the only valid wildcard, and effectively + disables the use of proxy. */ + CINIT(NOPROXY, OBJECTPOINT, 177), + + /* block size for TFTP transfers */ + CINIT(TFTP_BLKSIZE, LONG, 178), + + /* Socks Service */ + CINIT(SOCKS5_GSSAPI_SERVICE, OBJECTPOINT, 179), + + /* Socks Service */ + CINIT(SOCKS5_GSSAPI_NEC, LONG, 180), + + /* set the bitmask for the protocols that are allowed to be used for the + transfer, which thus helps the app which takes URLs from users or other + external inputs and want to restrict what protocol(s) to deal + with. Defaults to CURLPROTO_ALL. */ + CINIT(PROTOCOLS, LONG, 181), + + /* set the bitmask for the protocols that libcurl is allowed to follow to, + as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs + to be set in both bitmasks to be allowed to get redirected to. Defaults + to all protocols except FILE and SCP. */ + CINIT(REDIR_PROTOCOLS, LONG, 182), + + /* set the SSH knownhost file name to use */ + CINIT(SSH_KNOWNHOSTS, OBJECTPOINT, 183), + + /* set the SSH host key callback, must point to a curl_sshkeycallback + function */ + CINIT(SSH_KEYFUNCTION, FUNCTIONPOINT, 184), + + /* set the SSH host key callback custom pointer */ + CINIT(SSH_KEYDATA, OBJECTPOINT, 185), + + /* set the SMTP mail originator */ + CINIT(MAIL_FROM, OBJECTPOINT, 186), + + /* set the SMTP mail receiver(s) */ + CINIT(MAIL_RCPT, OBJECTPOINT, 187), + + /* FTP: send PRET before PASV */ + CINIT(FTP_USE_PRET, LONG, 188), + + /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */ + CINIT(RTSP_REQUEST, LONG, 189), + + /* The RTSP session identifier */ + CINIT(RTSP_SESSION_ID, OBJECTPOINT, 190), + + /* The RTSP stream URI */ + CINIT(RTSP_STREAM_URI, OBJECTPOINT, 191), + + /* The Transport: header to use in RTSP requests */ + CINIT(RTSP_TRANSPORT, OBJECTPOINT, 192), + + /* Manually initialize the client RTSP CSeq for this handle */ + CINIT(RTSP_CLIENT_CSEQ, LONG, 193), + + /* Manually initialize the server RTSP CSeq for this handle */ + CINIT(RTSP_SERVER_CSEQ, LONG, 194), + + /* The stream to pass to INTERLEAVEFUNCTION. */ + CINIT(INTERLEAVEDATA, OBJECTPOINT, 195), + + /* Let the application define a custom write method for RTP data */ + CINIT(INTERLEAVEFUNCTION, FUNCTIONPOINT, 196), + + /* Turn on wildcard matching */ + CINIT(WILDCARDMATCH, LONG, 197), + + /* Directory matching callback called before downloading of an + individual file (chunk) started */ + CINIT(CHUNK_BGN_FUNCTION, FUNCTIONPOINT, 198), + + /* Directory matching callback called after the file (chunk) + was downloaded, or skipped */ + CINIT(CHUNK_END_FUNCTION, FUNCTIONPOINT, 199), + + /* Change match (fnmatch-like) callback for wildcard matching */ + CINIT(FNMATCH_FUNCTION, FUNCTIONPOINT, 200), + + /* Let the application define custom chunk data pointer */ + CINIT(CHUNK_DATA, OBJECTPOINT, 201), + + /* FNMATCH_FUNCTION user pointer */ + CINIT(FNMATCH_DATA, OBJECTPOINT, 202), + + /* send linked-list of name:port:address sets */ + CINIT(RESOLVE, OBJECTPOINT, 203), + + CURLOPT_LASTENTRY /* the last unused */ +} CURLoption; + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Backwards compatibility with older names */ +/* These are scheduled to disappear by 2011 */ + +/* This was added in version 7.19.1 */ +#define CURLOPT_POST301 CURLOPT_POSTREDIR + +/* These are scheduled to disappear by 2009 */ + +/* The following were added in 7.17.0 */ +#define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD +#define CURLOPT_FTPAPPEND CURLOPT_APPEND +#define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY +#define CURLOPT_FTP_SSL CURLOPT_USE_SSL + +/* The following were added earlier */ + +#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD +#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL + +#else +/* This is set if CURL_NO_OLDIES is defined at compile-time */ +#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */ +#endif + + + /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host + name resolves addresses using more than one IP protocol version, this + option might be handy to force libcurl to use a specific IP version. */ +#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP + versions that your system allows */ +#define CURL_IPRESOLVE_V4 1 /* resolve to ipv4 addresses */ +#define CURL_IPRESOLVE_V6 2 /* resolve to ipv6 addresses */ + + /* three convenient "aliases" that follow the name scheme better */ +#define CURLOPT_WRITEDATA CURLOPT_FILE +#define CURLOPT_READDATA CURLOPT_INFILE +#define CURLOPT_HEADERDATA CURLOPT_WRITEHEADER +#define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER + + /* These enums are for use with the CURLOPT_HTTP_VERSION option. */ +enum { + CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd + like the library to choose the best possible + for us! */ + CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */ + CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */ + + CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */ +}; + +/* + * Public API enums for RTSP requests + */ +enum { + CURL_RTSPREQ_NONE, /* first in list */ + CURL_RTSPREQ_OPTIONS, + CURL_RTSPREQ_DESCRIBE, + CURL_RTSPREQ_ANNOUNCE, + CURL_RTSPREQ_SETUP, + CURL_RTSPREQ_PLAY, + CURL_RTSPREQ_PAUSE, + CURL_RTSPREQ_TEARDOWN, + CURL_RTSPREQ_GET_PARAMETER, + CURL_RTSPREQ_SET_PARAMETER, + CURL_RTSPREQ_RECORD, + CURL_RTSPREQ_RECEIVE, + CURL_RTSPREQ_LAST /* last in list */ +}; + + /* These enums are for use with the CURLOPT_NETRC option. */ +enum CURL_NETRC_OPTION { + CURL_NETRC_IGNORED, /* The .netrc will never be read. + * This is the default. */ + CURL_NETRC_OPTIONAL, /* A user:password in the URL will be preferred + * to one in the .netrc. */ + CURL_NETRC_REQUIRED, /* A user:password in the URL will be ignored. + * Unless one is set programmatically, the .netrc + * will be queried. */ + CURL_NETRC_LAST +}; + +enum { + CURL_SSLVERSION_DEFAULT, + CURL_SSLVERSION_TLSv1, + CURL_SSLVERSION_SSLv2, + CURL_SSLVERSION_SSLv3, + + CURL_SSLVERSION_LAST /* never use, keep last */ +}; + +/* symbols to use with CURLOPT_POSTREDIR. + CURL_REDIR_POST_301 and CURL_REDIR_POST_302 can be bitwise ORed so that + CURL_REDIR_POST_301 | CURL_REDIR_POST_302 == CURL_REDIR_POST_ALL */ + +#define CURL_REDIR_GET_ALL 0 +#define CURL_REDIR_POST_301 1 +#define CURL_REDIR_POST_302 2 +#define CURL_REDIR_POST_ALL (CURL_REDIR_POST_301|CURL_REDIR_POST_302) + +typedef enum { + CURL_TIMECOND_NONE, + + CURL_TIMECOND_IFMODSINCE, + CURL_TIMECOND_IFUNMODSINCE, + CURL_TIMECOND_LASTMOD, + + CURL_TIMECOND_LAST +} curl_TimeCond; + + +/* curl_strequal() and curl_strnequal() are subject for removal in a future + libcurl, see lib/README.curlx for details */ +CURL_EXTERN int (curl_strequal)(const char *s1, const char *s2); +CURL_EXTERN int (curl_strnequal)(const char *s1, const char *s2, size_t n); + +/* name is uppercase CURLFORM_ */ +#ifdef CFINIT +#undef CFINIT +#endif + +#ifdef CURL_ISOCPP +#define CFINIT(name) CURLFORM_ ## name +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define CFINIT(name) CURLFORM_/**/name +#endif + +typedef enum { + CFINIT(NOTHING), /********* the first one is unused ************/ + + /* */ + CFINIT(COPYNAME), + CFINIT(PTRNAME), + CFINIT(NAMELENGTH), + CFINIT(COPYCONTENTS), + CFINIT(PTRCONTENTS), + CFINIT(CONTENTSLENGTH), + CFINIT(FILECONTENT), + CFINIT(ARRAY), + CFINIT(OBSOLETE), + CFINIT(FILE), + + CFINIT(BUFFER), + CFINIT(BUFFERPTR), + CFINIT(BUFFERLENGTH), + + CFINIT(CONTENTTYPE), + CFINIT(CONTENTHEADER), + CFINIT(FILENAME), + CFINIT(END), + CFINIT(OBSOLETE2), + + CFINIT(STREAM), + + CURLFORM_LASTENTRY /* the last unused */ +} CURLformoption; + +#undef CFINIT /* done */ + +/* structure to be used as parameter for CURLFORM_ARRAY */ +struct curl_forms { + CURLformoption option; + const char *value; +}; + +/* use this for multipart formpost building */ +/* Returns code for curl_formadd() + * + * Returns: + * CURL_FORMADD_OK on success + * CURL_FORMADD_MEMORY if the FormInfo allocation fails + * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form + * CURL_FORMADD_NULL if a null pointer was given for a char + * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed + * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used + * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error) + * CURL_FORMADD_MEMORY if a curl_httppost struct cannot be allocated + * CURL_FORMADD_MEMORY if some allocation for string copying failed. + * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array + * + ***************************************************************************/ +typedef enum { + CURL_FORMADD_OK, /* first, no error */ + + CURL_FORMADD_MEMORY, + CURL_FORMADD_OPTION_TWICE, + CURL_FORMADD_NULL, + CURL_FORMADD_UNKNOWN_OPTION, + CURL_FORMADD_INCOMPLETE, + CURL_FORMADD_ILLEGAL_ARRAY, + CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */ + + CURL_FORMADD_LAST /* last */ +} CURLFORMcode; + +/* + * NAME curl_formadd() + * + * DESCRIPTION + * + * Pretty advanced function for building multi-part formposts. Each invoke + * adds one part that together construct a full post. Then use + * CURLOPT_HTTPPOST to send it off to libcurl. + */ +CURL_EXTERN CURLFORMcode curl_formadd(struct curl_httppost **httppost, + struct curl_httppost **last_post, + ...); + +/* + * callback function for curl_formget() + * The void *arg pointer will be the one passed as second argument to + * curl_formget(). + * The character buffer passed to it must not be freed. + * Should return the buffer length passed to it as the argument "len" on + * success. + */ +typedef size_t (*curl_formget_callback)(void *arg, const char *buf, size_t len); + +/* + * NAME curl_formget() + * + * DESCRIPTION + * + * Serialize a curl_httppost struct built with curl_formadd(). + * Accepts a void pointer as second argument which will be passed to + * the curl_formget_callback function. + * Returns 0 on success. + */ +CURL_EXTERN int curl_formget(struct curl_httppost *form, void *arg, + curl_formget_callback append); +/* + * NAME curl_formfree() + * + * DESCRIPTION + * + * Free a multipart formpost previously built with curl_formadd(). + */ +CURL_EXTERN void curl_formfree(struct curl_httppost *form); + +/* + * NAME curl_getenv() + * + * DESCRIPTION + * + * Returns a malloc()'ed string that MUST be curl_free()ed after usage is + * complete. DEPRECATED - see lib/README.curlx + */ +CURL_EXTERN char *curl_getenv(const char *variable); + +/* + * NAME curl_version() + * + * DESCRIPTION + * + * Returns a static ascii string of the libcurl version. + */ +CURL_EXTERN char *curl_version(void); + +/* + * NAME curl_easy_escape() + * + * DESCRIPTION + * + * Escapes URL strings (converts all letters consider illegal in URLs to their + * %XX versions). This function returns a new allocated string or NULL if an + * error occurred. + */ +CURL_EXTERN char *curl_easy_escape(CURL *handle, + const char *string, + int length); + +/* the previous version: */ +CURL_EXTERN char *curl_escape(const char *string, + int length); + + +/* + * NAME curl_easy_unescape() + * + * DESCRIPTION + * + * Unescapes URL encoding in strings (converts all %XX codes to their 8bit + * versions). This function returns a new allocated string or NULL if an error + * occurred. + * Conversion Note: On non-ASCII platforms the ASCII %XX codes are + * converted into the host encoding. + */ +CURL_EXTERN char *curl_easy_unescape(CURL *handle, + const char *string, + int length, + int *outlength); + +/* the previous version */ +CURL_EXTERN char *curl_unescape(const char *string, + int length); + +/* + * NAME curl_free() + * + * DESCRIPTION + * + * Provided for de-allocation in the same translation unit that did the + * allocation. Added in libcurl 7.10 + */ +CURL_EXTERN void curl_free(void *p); + +/* + * NAME curl_global_init() + * + * DESCRIPTION + * + * curl_global_init() should be invoked exactly once for each application that + * uses libcurl and before any call of other libcurl functions. + * + * This function is not thread-safe! + */ +CURL_EXTERN CURLcode curl_global_init(long flags); + +/* + * NAME curl_global_init_mem() + * + * DESCRIPTION + * + * curl_global_init() or curl_global_init_mem() should be invoked exactly once + * for each application that uses libcurl. This function can be used to + * initialize libcurl and set user defined memory management callback + * functions. Users can implement memory management routines to check for + * memory leaks, check for mis-use of the curl library etc. User registered + * callback routines with be invoked by this library instead of the system + * memory management routines like malloc, free etc. + */ +CURL_EXTERN CURLcode curl_global_init_mem(long flags, + curl_malloc_callback m, + curl_free_callback f, + curl_realloc_callback r, + curl_strdup_callback s, + curl_calloc_callback c); + +/* + * NAME curl_global_cleanup() + * + * DESCRIPTION + * + * curl_global_cleanup() should be invoked exactly once for each application + * that uses libcurl + */ +CURL_EXTERN void curl_global_cleanup(void); + +/* linked-list structure for the CURLOPT_QUOTE option (and other) */ +struct curl_slist { + char *data; + struct curl_slist *next; +}; + +/* + * NAME curl_slist_append() + * + * DESCRIPTION + * + * Appends a string to a linked list. If no list exists, it will be created + * first. Returns the new list, after appending. + */ +CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *, + const char *); + +/* + * NAME curl_slist_free_all() + * + * DESCRIPTION + * + * free a previously built curl_slist. + */ +CURL_EXTERN void curl_slist_free_all(struct curl_slist *); + +/* + * NAME curl_getdate() + * + * DESCRIPTION + * + * Returns the time, in seconds since 1 Jan 1970 of the time string given in + * the first argument. The time argument in the second parameter is unused + * and should be set to NULL. + */ +CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused); + +/* info about the certificate chain, only for OpenSSL builds. Asked + for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */ +struct curl_certinfo { + int num_of_certs; /* number of certificates with information */ + struct curl_slist **certinfo; /* for each index in this array, there's a + linked list with textual information in the + format "name: value" */ +}; + +#define CURLINFO_STRING 0x100000 +#define CURLINFO_LONG 0x200000 +#define CURLINFO_DOUBLE 0x300000 +#define CURLINFO_SLIST 0x400000 +#define CURLINFO_MASK 0x0fffff +#define CURLINFO_TYPEMASK 0xf00000 + +typedef enum { + CURLINFO_NONE, /* first, never use this */ + CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1, + CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2, + CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3, + CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4, + CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5, + CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6, + CURLINFO_SIZE_UPLOAD = CURLINFO_DOUBLE + 7, + CURLINFO_SIZE_DOWNLOAD = CURLINFO_DOUBLE + 8, + CURLINFO_SPEED_DOWNLOAD = CURLINFO_DOUBLE + 9, + CURLINFO_SPEED_UPLOAD = CURLINFO_DOUBLE + 10, + CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11, + CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12, + CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13, + CURLINFO_FILETIME = CURLINFO_LONG + 14, + CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15, + CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16, + CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17, + CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18, + CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19, + CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20, + CURLINFO_PRIVATE = CURLINFO_STRING + 21, + CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22, + CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23, + CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24, + CURLINFO_OS_ERRNO = CURLINFO_LONG + 25, + CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26, + CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27, + CURLINFO_COOKIELIST = CURLINFO_SLIST + 28, + CURLINFO_LASTSOCKET = CURLINFO_LONG + 29, + CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30, + CURLINFO_REDIRECT_URL = CURLINFO_STRING + 31, + CURLINFO_PRIMARY_IP = CURLINFO_STRING + 32, + CURLINFO_APPCONNECT_TIME = CURLINFO_DOUBLE + 33, + CURLINFO_CERTINFO = CURLINFO_SLIST + 34, + CURLINFO_CONDITION_UNMET = CURLINFO_LONG + 35, + CURLINFO_RTSP_SESSION_ID = CURLINFO_STRING + 36, + CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG + 37, + CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG + 38, + CURLINFO_RTSP_CSEQ_RECV = CURLINFO_LONG + 39, + CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40, + CURLINFO_LOCAL_IP = CURLINFO_STRING + 41, + CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42, + /* Fill in new entries below here! */ + + CURLINFO_LASTONE = 42 +} CURLINFO; + +/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as + CURLINFO_HTTP_CODE */ +#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE + +typedef enum { + CURLCLOSEPOLICY_NONE, /* first, never use this */ + + CURLCLOSEPOLICY_OLDEST, + CURLCLOSEPOLICY_LEAST_RECENTLY_USED, + CURLCLOSEPOLICY_LEAST_TRAFFIC, + CURLCLOSEPOLICY_SLOWEST, + CURLCLOSEPOLICY_CALLBACK, + + CURLCLOSEPOLICY_LAST /* last, never use this */ +} curl_closepolicy; + +#define CURL_GLOBAL_SSL (1<<0) +#define CURL_GLOBAL_WIN32 (1<<1) +#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32) +#define CURL_GLOBAL_NOTHING 0 +#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL + + +/***************************************************************************** + * Setup defines, protos etc for the sharing stuff. + */ + +/* Different data locks for a single share */ +typedef enum { + CURL_LOCK_DATA_NONE = 0, + /* CURL_LOCK_DATA_SHARE is used internally to say that + * the locking is just made to change the internal state of the share + * itself. + */ + CURL_LOCK_DATA_SHARE, + CURL_LOCK_DATA_COOKIE, + CURL_LOCK_DATA_DNS, + CURL_LOCK_DATA_SSL_SESSION, + CURL_LOCK_DATA_CONNECT, + CURL_LOCK_DATA_LAST +} curl_lock_data; + +/* Different lock access types */ +typedef enum { + CURL_LOCK_ACCESS_NONE = 0, /* unspecified action */ + CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */ + CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */ + CURL_LOCK_ACCESS_LAST /* never use */ +} curl_lock_access; + +typedef void (*curl_lock_function)(CURL *handle, + curl_lock_data data, + curl_lock_access locktype, + void *userptr); +typedef void (*curl_unlock_function)(CURL *handle, + curl_lock_data data, + void *userptr); + +typedef void CURLSH; + +typedef enum { + CURLSHE_OK, /* all is fine */ + CURLSHE_BAD_OPTION, /* 1 */ + CURLSHE_IN_USE, /* 2 */ + CURLSHE_INVALID, /* 3 */ + CURLSHE_NOMEM, /* out of memory */ + CURLSHE_LAST /* never use */ +} CURLSHcode; + +typedef enum { + CURLSHOPT_NONE, /* don't use */ + CURLSHOPT_SHARE, /* specify a data type to share */ + CURLSHOPT_UNSHARE, /* specify which data type to stop sharing */ + CURLSHOPT_LOCKFUNC, /* pass in a 'curl_lock_function' pointer */ + CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */ + CURLSHOPT_USERDATA, /* pass in a user data pointer used in the lock/unlock + callback functions */ + CURLSHOPT_LAST /* never use */ +} CURLSHoption; + +CURL_EXTERN CURLSH *curl_share_init(void); +CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...); +CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *); + +/**************************************************************************** + * Structures for querying information about the curl library at runtime. + */ + +typedef enum { + CURLVERSION_FIRST, + CURLVERSION_SECOND, + CURLVERSION_THIRD, + CURLVERSION_FOURTH, + CURLVERSION_LAST /* never actually use this */ +} CURLversion; + +/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by + basically all programs ever that want to get version information. It is + meant to be a built-in version number for what kind of struct the caller + expects. If the struct ever changes, we redefine the NOW to another enum + from above. */ +#define CURLVERSION_NOW CURLVERSION_FOURTH + +typedef struct { + CURLversion age; /* age of the returned struct */ + const char *version; /* LIBCURL_VERSION */ + unsigned int version_num; /* LIBCURL_VERSION_NUM */ + const char *host; /* OS/host/cpu/machine when configured */ + int features; /* bitmask, see defines below */ + const char *ssl_version; /* human readable string */ + long ssl_version_num; /* not used anymore, always 0 */ + const char *libz_version; /* human readable string */ + /* protocols is terminated by an entry with a NULL protoname */ + const char * const *protocols; + + /* The fields below this were added in CURLVERSION_SECOND */ + const char *ares; + int ares_num; + + /* This field was added in CURLVERSION_THIRD */ + const char *libidn; + + /* These field were added in CURLVERSION_FOURTH */ + + /* Same as '_libiconv_version' if built with HAVE_ICONV */ + int iconv_ver_num; + + const char *libssh_version; /* human readable string */ + +} curl_version_info_data; + +#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */ +#define CURL_VERSION_KERBEROS4 (1<<1) /* kerberos auth is supported */ +#define CURL_VERSION_SSL (1<<2) /* SSL options are present */ +#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */ +#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */ +#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth support */ +#define CURL_VERSION_DEBUG (1<<6) /* built with debug capabilities */ +#define CURL_VERSION_ASYNCHDNS (1<<7) /* asynchronous dns resolves */ +#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth */ +#define CURL_VERSION_LARGEFILE (1<<9) /* supports files bigger than 2GB */ +#define CURL_VERSION_IDN (1<<10) /* International Domain Names support */ +#define CURL_VERSION_SSPI (1<<11) /* SSPI is supported */ +#define CURL_VERSION_CONV (1<<12) /* character conversions supported */ +#define CURL_VERSION_CURLDEBUG (1<<13) /* debug memory tracking supported */ + +/* + * NAME curl_version_info() + * + * DESCRIPTION + * + * This function returns a pointer to a static copy of the version info + * struct. See above. + */ +CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion); + +/* + * NAME curl_easy_strerror() + * + * DESCRIPTION + * + * The curl_easy_strerror function may be used to turn a CURLcode value + * into the equivalent human readable error string. This is useful + * for printing meaningful error messages. + */ +CURL_EXTERN const char *curl_easy_strerror(CURLcode); + +/* + * NAME curl_share_strerror() + * + * DESCRIPTION + * + * The curl_share_strerror function may be used to turn a CURLSHcode value + * into the equivalent human readable error string. This is useful + * for printing meaningful error messages. + */ +CURL_EXTERN const char *curl_share_strerror(CURLSHcode); + +/* + * NAME curl_easy_pause() + * + * DESCRIPTION + * + * The curl_easy_pause function pauses or unpauses transfers. Select the new + * state by setting the bitmask, use the convenience defines below. + * + */ +CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask); + +#define CURLPAUSE_RECV (1<<0) +#define CURLPAUSE_RECV_CONT (0) + +#define CURLPAUSE_SEND (1<<2) +#define CURLPAUSE_SEND_CONT (0) + +#define CURLPAUSE_ALL (CURLPAUSE_RECV|CURLPAUSE_SEND) +#define CURLPAUSE_CONT (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT) + +#ifdef __cplusplus +} +#endif + +/* unfortunately, the easy.h and multi.h include files need options and info + stuff before they can be included! */ +#include "easy.h" /* nothing in curl is fun without the easy stuff */ +#include "multi.h" + +/* the typechecker doesn't work in C++ (yet) */ +#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ + ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \ + !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK) +#include "typecheck-gcc.h" +#else +#if defined(__STDC__) && (__STDC__ >= 1) +/* This preprocessor magic that replaces a call with the exact same call is + only done to make sure application authors pass exactly three arguments + to these functions. */ +#define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param) +#define curl_easy_getinfo(handle,info,arg) curl_easy_getinfo(handle,info,arg) +#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) +#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) +#endif /* __STDC__ >= 1 */ +#endif /* gcc >= 4.3 && !__cplusplus */ + +#endif /* __CURL_CURL_H */ diff --git a/scalos/include/curl/curlbuild.h b/scalos/include/curl/curlbuild.h new file mode 100644 index 000000000..c2efc91c2 --- /dev/null +++ b/scalos/include/curl/curlbuild.h @@ -0,0 +1,191 @@ +/* include/curl/curlbuild.h. Generated from curlbuild.h.in by configure. */ +#ifndef __CURL_CURLBUILD_H +#define __CURL_CURLBUILD_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * Nothing in this file is intended to be modified or adjusted by the + * curl library user nor by the curl library builder. + * + * If you think that something actually needs to be changed, adjusted + * or fixed in this file, then, report it on the libcurl development + * mailing list: http://cool.haxx.se/mailman/listinfo/curl-library/ + * + * This header file shall only export symbols which are 'curl' or 'CURL' + * prefixed, otherwise public name space would be polluted. + * + * NOTE 2: + * ------- + * + * Right now you might be staring at file include/curl/curlbuild.h.in or + * at file include/curl/curlbuild.h, this is due to the following reason: + * + * On systems capable of running the configure script, the configure process + * will overwrite the distributed include/curl/curlbuild.h file with one that + * is suitable and specific to the library being configured and built, which + * is generated from the include/curl/curlbuild.h.in template file. + * + */ + +/* ================================================================ */ +/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */ +/* ================================================================ */ + +#ifdef CURL_SIZEOF_LONG +# error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_SOCKLEN_T +# error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_SOCKLEN_T +# error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_OFF_T +# error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_T +# error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_TU +# error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined +#endif + +#ifdef CURL_FORMAT_OFF_T +# error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_OFF_T +# error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_T +# error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_TU +# error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined +#endif + +/* ================================================================ */ +/* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */ +/* ================================================================ */ + +/* Configure process defines this to 1 when it finds out that system */ +/* header file ws2tcpip.h must be included by the external interface. */ +/* #undef CURL_PULL_WS2TCPIP_H */ +#ifdef CURL_PULL_WS2TCPIP_H +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include +# include +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/types.h must be included by the external interface. */ +#define CURL_PULL_SYS_TYPES_H 1 +#ifdef CURL_PULL_SYS_TYPES_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file stdint.h must be included by the external interface. */ +#define CURL_PULL_STDINT_H 1 +#ifdef CURL_PULL_STDINT_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file inttypes.h must be included by the external interface. */ +#define CURL_PULL_INTTYPES_H 1 +#ifdef CURL_PULL_INTTYPES_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/socket.h must be included by the external interface. */ +/* #undef CURL_PULL_SYS_SOCKET_H */ +#ifdef CURL_PULL_SYS_SOCKET_H +# include +#endif + +/* The size of `long', as computed by sizeof. */ +#define CURL_SIZEOF_LONG 4 + +/* Integral data type used for curl_socklen_t. */ +#define CURL_TYPEOF_CURL_SOCKLEN_T int + +/* The size of `curl_socklen_t', as computed by sizeof. */ +#define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +/* Data type definition of curl_socklen_t. */ +typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; + +/* Signed integral data type used for curl_off_t. */ +#define CURL_TYPEOF_CURL_OFF_T int64_t + +/* Data type definition of curl_off_t. */ +typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; + +/* curl_off_t formatting string directive without "%" conversion specifier. */ +#define CURL_FORMAT_CURL_OFF_T "lld" + +/* unsigned curl_off_t formatting string without "%" conversion specifier. */ +#define CURL_FORMAT_CURL_OFF_TU "llu" + +/* curl_off_t formatting string directive with "%" conversion specifier. */ +#define CURL_FORMAT_OFF_T "%lld" + +/* The size of `curl_off_t', as computed by sizeof. */ +#define CURL_SIZEOF_CURL_OFF_T 8 + +/* curl_off_t constant suffix. */ +#define CURL_SUFFIX_CURL_OFF_T LL + +/* unsigned curl_off_t constant suffix. */ +#define CURL_SUFFIX_CURL_OFF_TU ULL + +#endif /* __CURL_CURLBUILD_H */ diff --git a/scalos/include/curl/curlrules.h b/scalos/include/curl/curlrules.h new file mode 100644 index 000000000..8aad1df67 --- /dev/null +++ b/scalos/include/curl/curlrules.h @@ -0,0 +1,252 @@ +#ifndef __CURL_CURLRULES_H +#define __CURL_CURLRULES_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* COMPILE TIME SANITY CHECKS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * All checks done in this file are intentionally placed in a public + * header file which is pulled by curl/curl.h when an application is + * being built using an already built libcurl library. Additionally + * this file is also included and used when building the library. + * + * If compilation fails on this file it is certainly sure that the + * problem is elsewhere. It could be a problem in the curlbuild.h + * header file, or simply that you are using different compilation + * settings than those used to build the library. + * + * Nothing in this file is intended to be modified or adjusted by the + * curl library user nor by the curl library builder. + * + * Do not deactivate any check, these are done to make sure that the + * library is properly built and used. + * + * You can find further help on the libcurl development mailing list: + * http://cool.haxx.se/mailman/listinfo/curl-library/ + * + * NOTE 2 + * ------ + * + * Some of the following compile time checks are based on the fact + * that the dimension of a constant array can not be a negative one. + * In this way if the compile time verification fails, the compilation + * will fail issuing an error. The error description wording is compiler + * dependent but it will be quite similar to one of the following: + * + * "negative subscript or subscript is too large" + * "array must have at least one element" + * "-1 is an illegal array size" + * "size of array is negative" + * + * If you are building an application which tries to use an already + * built libcurl library and you are getting this kind of errors on + * this file, it is a clear indication that there is a mismatch between + * how the library was built and how you are trying to use it for your + * application. Your already compiled or binary library provider is the + * only one who can give you the details you need to properly use it. + */ + +/* + * Verify that some macros are actually defined. + */ + +#ifndef CURL_SIZEOF_LONG +# error "CURL_SIZEOF_LONG definition is missing!" + Error Compilation_aborted_CURL_SIZEOF_LONG_is_missing +#endif + +#ifndef CURL_TYPEOF_CURL_SOCKLEN_T +# error "CURL_TYPEOF_CURL_SOCKLEN_T definition is missing!" + Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_is_missing +#endif + +#ifndef CURL_SIZEOF_CURL_SOCKLEN_T +# error "CURL_SIZEOF_CURL_SOCKLEN_T definition is missing!" + Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_is_missing +#endif + +#ifndef CURL_TYPEOF_CURL_OFF_T +# error "CURL_TYPEOF_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_FORMAT_CURL_OFF_T +# error "CURL_FORMAT_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_FORMAT_CURL_OFF_TU +# error "CURL_FORMAT_CURL_OFF_TU definition is missing!" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_is_missing +#endif + +#ifndef CURL_FORMAT_OFF_T +# error "CURL_FORMAT_OFF_T definition is missing!" + Error Compilation_aborted_CURL_FORMAT_OFF_T_is_missing +#endif + +#ifndef CURL_SIZEOF_CURL_OFF_T +# error "CURL_SIZEOF_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_SUFFIX_CURL_OFF_T +# error "CURL_SUFFIX_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_SUFFIX_CURL_OFF_TU +# error "CURL_SUFFIX_CURL_OFF_TU definition is missing!" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_is_missing +#endif + +/* + * Macros private to this header file. + */ + +#define CurlchkszEQ(t, s) sizeof(t) == s ? 1 : -1 + +#define CurlchkszGE(t1, t2) sizeof(t1) >= sizeof(t2) ? 1 : -1 + +/* + * Verify that the size previously defined and expected for long + * is the same as the one reported by sizeof() at compile time. + */ + +typedef char + __curl_rule_01__ + [CurlchkszEQ(long, CURL_SIZEOF_LONG)]; + +/* + * Verify that the size previously defined and expected for + * curl_off_t is actually the the same as the one reported + * by sizeof() at compile time. + */ + +typedef char + __curl_rule_02__ + [CurlchkszEQ(curl_off_t, CURL_SIZEOF_CURL_OFF_T)]; + +/* + * Verify at compile time that the size of curl_off_t as reported + * by sizeof() is greater or equal than the one reported for long + * for the current compilation. + */ + +typedef char + __curl_rule_03__ + [CurlchkszGE(curl_off_t, long)]; + +/* + * Verify that the size previously defined and expected for + * curl_socklen_t is actually the the same as the one reported + * by sizeof() at compile time. + */ + +typedef char + __curl_rule_04__ + [CurlchkszEQ(curl_socklen_t, CURL_SIZEOF_CURL_SOCKLEN_T)]; + +/* + * Verify at compile time that the size of curl_socklen_t as reported + * by sizeof() is greater or equal than the one reported for int for + * the current compilation. + */ + +typedef char + __curl_rule_05__ + [CurlchkszGE(curl_socklen_t, int)]; + +/* ================================================================ */ +/* EXTERNALLY AND INTERNALLY VISIBLE DEFINITIONS */ +/* ================================================================ */ + +/* + * CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow + * these to be visible and exported by the external libcurl interface API, + * while also making them visible to the library internals, simply including + * setup.h, without actually needing to include curl.h internally. + * If some day this section would grow big enough, all this should be moved + * to its own header file. + */ + +/* + * Figure out if we can use the ## preprocessor operator, which is supported + * by ISO/ANSI C and C++. Some compilers support it without setting __STDC__ + * or __cplusplus so we need to carefully check for them too. + */ + +#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \ + defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \ + defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \ + defined(__ILEC400__) + /* This compiler is believed to have an ISO compatible preprocessor */ +#define CURL_ISOCPP +#else + /* This compiler is believed NOT to have an ISO compatible preprocessor */ +#undef CURL_ISOCPP +#endif + +/* + * Macros for minimum-width signed and unsigned curl_off_t integer constants. + */ + +#ifdef CURL_ISOCPP +# define __CURL_OFF_T_C_HELPER2(Val,Suffix) Val ## Suffix +#else +# define __CURL_OFF_T_C_HELPER2(Val,Suffix) Val/**/Suffix +#endif +#define __CURL_OFF_T_C_HELPER1(Val,Suffix) __CURL_OFF_T_C_HELPER2(Val,Suffix) +#define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HELPER1(Val,CURL_SUFFIX_CURL_OFF_T) +#define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HELPER1(Val,CURL_SUFFIX_CURL_OFF_TU) + +/* + * Get rid of macros private to this header file. + */ + +#undef CurlchkszEQ +#undef CurlchkszGE + +/* + * Get rid of macros not intended to exist beyond this point. + */ + +#undef CURL_PULL_WS2TCPIP_H +#undef CURL_PULL_SYS_TYPES_H +#undef CURL_PULL_SYS_SOCKET_H +#undef CURL_PULL_STDINT_H +#undef CURL_PULL_INTTYPES_H + +#undef CURL_TYPEOF_CURL_SOCKLEN_T +#undef CURL_TYPEOF_CURL_OFF_T + +#ifdef CURL_NO_OLDIES +#undef CURL_FORMAT_OFF_T /* not required since 7.19.0 - obsoleted in 7.20.0 */ +#endif + +#endif /* __CURL_CURLRULES_H */ diff --git a/scalos/include/curl/curlver.h b/scalos/include/curl/curlver.h new file mode 100644 index 000000000..7c3ccc905 --- /dev/null +++ b/scalos/include/curl/curlver.h @@ -0,0 +1,69 @@ +#ifndef __CURL_CURLVER_H +#define __CURL_CURLVER_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* This header file contains nothing but libcurl version info, generated by + a script at release-time. This was made its own header file in 7.11.2 */ + +/* This is the global package copyright */ +#define LIBCURL_COPYRIGHT "1996 - 2010 Daniel Stenberg, ." + +/* This is the version number of the libcurl package from which this header + file origins: */ +#define LIBCURL_VERSION "7.21.3" + +/* The numeric version number is also available "in parts" by using these + defines: */ +#define LIBCURL_VERSION_MAJOR 7 +#define LIBCURL_VERSION_MINOR 21 +#define LIBCURL_VERSION_PATCH 3 + +/* This is the numeric version of the libcurl version number, meant for easier + parsing and comparions by programs. The LIBCURL_VERSION_NUM define will + always follow this syntax: + + 0xXXYYZZ + + Where XX, YY and ZZ are the main version, release and patch numbers in + hexadecimal (using 8 bits each). All three numbers are always represented + using two digits. 1.2 would appear as "0x010200" while version 9.11.7 + appears as "0x090b07". + + This 6-digit (24 bits) hexadecimal number does not show pre-release number, + and it is always a greater number in a more recent release. It makes + comparisons with greater than and less than work. +*/ +#define LIBCURL_VERSION_NUM 0x071503 + +/* + * This is the date and time when the full source package was created. The + * timestamp is not stored in git, as the timestamp is properly set in the + * tarballs by the maketgz script. + * + * The format of the date should follow this template: + * + * "Mon Feb 12 11:35:33 UTC 2007" + */ +#define LIBCURL_TIMESTAMP "Wed Dec 15 14:07:08 UTC 2010" + +#endif /* __CURL_CURLVER_H */ diff --git a/scalos/include/curl/easy.h b/scalos/include/curl/easy.h new file mode 100644 index 000000000..1ddb4fe5a --- /dev/null +++ b/scalos/include/curl/easy.h @@ -0,0 +1,102 @@ +#ifndef __CURL_EASY_H +#define __CURL_EASY_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2008, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +CURL_EXTERN CURL *curl_easy_init(void); +CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...); +CURL_EXTERN CURLcode curl_easy_perform(CURL *curl); +CURL_EXTERN void curl_easy_cleanup(CURL *curl); + +/* + * NAME curl_easy_getinfo() + * + * DESCRIPTION + * + * Request internal information from the curl session with this function. The + * third argument MUST be a pointer to a long, a pointer to a char * or a + * pointer to a double (as the documentation describes elsewhere). The data + * pointed to will be filled in accordingly and can be relied upon only if the + * function returns CURLE_OK. This function is intended to get used *AFTER* a + * performed transfer, all results from this function are undefined until the + * transfer is completed. + */ +CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...); + + +/* + * NAME curl_easy_duphandle() + * + * DESCRIPTION + * + * Creates a new curl session handle with the same options set for the handle + * passed in. Duplicating a handle could only be a matter of cloning data and + * options, internal state info and things like persistant connections cannot + * be transfered. It is useful in multithreaded applications when you can run + * curl_easy_duphandle() for each new thread to avoid a series of identical + * curl_easy_setopt() invokes in every thread. + */ +CURL_EXTERN CURL* curl_easy_duphandle(CURL *curl); + +/* + * NAME curl_easy_reset() + * + * DESCRIPTION + * + * Re-initializes a CURL handle to the default values. This puts back the + * handle to the same state as it was in when it was just created. + * + * It does keep: live connections, the Session ID cache, the DNS cache and the + * cookies. + */ +CURL_EXTERN void curl_easy_reset(CURL *curl); + +/* + * NAME curl_easy_recv() + * + * DESCRIPTION + * + * Receives data from the connected socket. Use after successful + * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. + */ +CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, + size_t *n); + +/* + * NAME curl_easy_send() + * + * DESCRIPTION + * + * Sends data over the connected socket. Use after successful + * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. + */ +CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer, + size_t buflen, size_t *n); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/scalos/include/curl/multi.h b/scalos/include/curl/multi.h new file mode 100644 index 000000000..f96566669 --- /dev/null +++ b/scalos/include/curl/multi.h @@ -0,0 +1,345 @@ +#ifndef __CURL_MULTI_H +#define __CURL_MULTI_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +/* + This is an "external" header file. Don't give away any internals here! + + GOALS + + o Enable a "pull" interface. The application that uses libcurl decides where + and when to ask libcurl to get/send data. + + o Enable multiple simultaneous transfers in the same thread without making it + complicated for the application. + + o Enable the application to select() on its own file descriptors and curl's + file descriptors simultaneous easily. + +*/ + +/* + * This header file should not really need to include "curl.h" since curl.h + * itself includes this file and we expect user applications to do #include + * without the need for especially including multi.h. + * + * For some reason we added this include here at one point, and rather than to + * break existing (wrongly written) libcurl applications, we leave it as-is + * but with this warning attached. + */ +#include "curl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void CURLM; + +typedef enum { + CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or + curl_multi_socket*() soon */ + CURLM_OK, + CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */ + CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */ + CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */ + CURLM_INTERNAL_ERROR, /* this is a libcurl bug */ + CURLM_BAD_SOCKET, /* the passed in socket argument did not match */ + CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */ + CURLM_LAST +} CURLMcode; + +/* just to make code nicer when using curl_multi_socket() you can now check + for CURLM_CALL_MULTI_SOCKET too in the same style it works for + curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */ +#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM + +typedef enum { + CURLMSG_NONE, /* first, not used */ + CURLMSG_DONE, /* This easy handle has completed. 'result' contains + the CURLcode of the transfer */ + CURLMSG_LAST /* last, not used */ +} CURLMSG; + +struct CURLMsg { + CURLMSG msg; /* what this message means */ + CURL *easy_handle; /* the handle it concerns */ + union { + void *whatever; /* message-specific data */ + CURLcode result; /* return code for transfer */ + } data; +}; +typedef struct CURLMsg CURLMsg; + +/* + * Name: curl_multi_init() + * + * Desc: inititalize multi-style curl usage + * + * Returns: a new CURLM handle to use in all 'curl_multi' functions. + */ +CURL_EXTERN CURLM *curl_multi_init(void); + +/* + * Name: curl_multi_add_handle() + * + * Desc: add a standard curl handle to the multi stack + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle, + CURL *curl_handle); + + /* + * Name: curl_multi_remove_handle() + * + * Desc: removes a curl handle from the multi stack again + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle, + CURL *curl_handle); + + /* + * Name: curl_multi_fdset() + * + * Desc: Ask curl for its fd_set sets. The app can use these to select() or + * poll() on. We want curl_multi_perform() called as soon as one of + * them are ready. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle, + fd_set *read_fd_set, + fd_set *write_fd_set, + fd_set *exc_fd_set, + int *max_fd); + + /* + * Name: curl_multi_perform() + * + * Desc: When the app thinks there's data available for curl it calls this + * function to read/write whatever there is right now. This returns + * as soon as the reads and writes are done. This function does not + * require that there actually is data available for reading or that + * data can be written, it can be called just in case. It returns + * the number of handles that still transfer data in the second + * argument's integer-pointer. + * + * Returns: CURLMcode type, general multi error code. *NOTE* that this only + * returns errors etc regarding the whole multi stack. There might + * still have occurred problems on invidual transfers even when this + * returns OK. + */ +CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle, + int *running_handles); + + /* + * Name: curl_multi_cleanup() + * + * Desc: Cleans up and removes a whole multi stack. It does not free or + * touch any individual easy handles in any way. We need to define + * in what state those handles will be if this function is called + * in the middle of a transfer. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle); + +/* + * Name: curl_multi_info_read() + * + * Desc: Ask the multi handle if there's any messages/informationals from + * the individual transfers. Messages include informationals such as + * error code from the transfer or just the fact that a transfer is + * completed. More details on these should be written down as well. + * + * Repeated calls to this function will return a new struct each + * time, until a special "end of msgs" struct is returned as a signal + * that there is no more to get at this point. + * + * The data the returned pointer points to will not survive calling + * curl_multi_cleanup(). + * + * The 'CURLMsg' struct is meant to be very simple and only contain + * very basic informations. If more involved information is wanted, + * we will provide the particular "transfer handle" in that struct + * and that should/could/would be used in subsequent + * curl_easy_getinfo() calls (or similar). The point being that we + * must never expose complex structs to applications, as then we'll + * undoubtably get backwards compatibility problems in the future. + * + * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out + * of structs. It also writes the number of messages left in the + * queue (after this read) in the integer the second argument points + * to. + */ +CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle, + int *msgs_in_queue); + +/* + * Name: curl_multi_strerror() + * + * Desc: The curl_multi_strerror function may be used to turn a CURLMcode + * value into the equivalent human readable error string. This is + * useful for printing meaningful error messages. + * + * Returns: A pointer to a zero-terminated error message. + */ +CURL_EXTERN const char *curl_multi_strerror(CURLMcode); + +/* + * Name: curl_multi_socket() and + * curl_multi_socket_all() + * + * Desc: An alternative version of curl_multi_perform() that allows the + * application to pass in one of the file descriptors that have been + * detected to have "action" on them and let libcurl perform. + * See man page for details. + */ +#define CURL_POLL_NONE 0 +#define CURL_POLL_IN 1 +#define CURL_POLL_OUT 2 +#define CURL_POLL_INOUT 3 +#define CURL_POLL_REMOVE 4 + +#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD + +#define CURL_CSELECT_IN 0x01 +#define CURL_CSELECT_OUT 0x02 +#define CURL_CSELECT_ERR 0x04 + +typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */ + curl_socket_t s, /* socket */ + int what, /* see above */ + void *userp, /* private callback + pointer */ + void *socketp); /* private socket + pointer */ +/* + * Name: curl_multi_timer_callback + * + * Desc: Called by libcurl whenever the library detects a change in the + * maximum number of milliseconds the app is allowed to wait before + * curl_multi_socket() or curl_multi_perform() must be called + * (to allow libcurl's timed events to take place). + * + * Returns: The callback should return zero. + */ +typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */ + long timeout_ms, /* see above */ + void *userp); /* private callback + pointer */ + +CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s, + int *running_handles); + +CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle, + curl_socket_t s, + int ev_bitmask, + int *running_handles); + +CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle, + int *running_handles); + +#ifndef CURL_ALLOW_OLD_MULTI_SOCKET +/* This macro below was added in 7.16.3 to push users who recompile to use + the new curl_multi_socket_action() instead of the old curl_multi_socket() +*/ +#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z) +#endif + +/* + * Name: curl_multi_timeout() + * + * Desc: Returns the maximum number of milliseconds the app is allowed to + * wait before curl_multi_socket() or curl_multi_perform() must be + * called (to allow libcurl's timed events to take place). + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle, + long *milliseconds); + +#undef CINIT /* re-using the same name as in curl.h */ + +#ifdef CURL_ISOCPP +#define CINIT(name,type,num) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + num +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define LONG CURLOPTTYPE_LONG +#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT +#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT +#define OFF_T CURLOPTTYPE_OFF_T +#define CINIT(name,type,number) CURLMOPT_/**/name = type + number +#endif + +typedef enum { + /* This is the socket callback function pointer */ + CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1), + + /* This is the argument passed to the socket callback */ + CINIT(SOCKETDATA, OBJECTPOINT, 2), + + /* set to 1 to enable pipelining for this multi handle */ + CINIT(PIPELINING, LONG, 3), + + /* This is the timer callback function pointer */ + CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4), + + /* This is the argument passed to the timer callback */ + CINIT(TIMERDATA, OBJECTPOINT, 5), + + /* maximum number of entries in the connection cache */ + CINIT(MAXCONNECTS, LONG, 6), + + CURLMOPT_LASTENTRY /* the last unused */ +} CURLMoption; + + +/* + * Name: curl_multi_setopt() + * + * Desc: Sets options for the multi handle. + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle, + CURLMoption option, ...); + + +/* + * Name: curl_multi_assign() + * + * Desc: This function sets an association in the multi handle between the + * given socket and a private pointer of the application. This is + * (only) useful for curl_multi_socket uses. + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle, + curl_socket_t sockfd, void *sockp); + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif diff --git a/scalos/include/cybergraphx/cybergraphics.h b/scalos/include/cybergraphx/cybergraphics.h new file mode 100644 index 000000000..4ee008238 --- /dev/null +++ b/scalos/include/cybergraphx/cybergraphics.h @@ -0,0 +1,300 @@ +/* +** $VER: cybergraphics.h 50.12 (13.08.2008) +** +** include file for cybergraphics.library +** +** Copyright © 1996-1998 by phase5 digital products +** All Rights reserved. +** +*/ + +#ifndef CYBERGRAPHX_CYBERGRAPHICS_H +#define CYBERGRAPHX_CYBERGRAPHICS_H 1 + +#ifndef UTILITY_TAGITEM_H +#include +#endif + +#ifndef GRAPHICS_DISPLAYINFO_H +#include +#endif + +#if defined(__GNUC__) && __GNUC__ > 2 +#pragma pack(2) +#endif //defined(__GNUC__) && __GNUC__ > 2 + + +#define CYBERGFXNAME "cybergraphics.library" +#define CYBERGFX_INCLUDE_VERSION (41UL) + +/* * + * Definition of CyberModeNode (Returned in AllocModeList) * + * */ + +struct CyberModeNode + { + struct Node Node; + char ModeText[DISPLAYNAMELEN]; /* name for this mode */ + ULONG DisplayID; /* display id associated with the node */ + UWORD Width; /* visible width */ + UWORD Height; /* visible height */ + UWORD Depth; /* display depth */ + struct TagItem *DisplayTagList; /* taglist with extended ModeID information */ + }; + + +/* * + * Parameters for GetCyberMapAttr() * + * */ + +#define CYBRMATTR_XMOD (0x80000001) /* function returns BytesPerRow if its called with this parameter */ +#define CYBRMATTR_BPPIX (0x80000002) /* BytesPerPixel shall be returned */ +#define CYBRMATTR_DISPADR (0x80000003) /* do not use this ! private tag */ +#define CYBRMATTR_PIXFMT (0x80000004) /* the pixel format is returned */ +#define CYBRMATTR_WIDTH (0x80000005) /* returns width in pixels */ +#define CYBRMATTR_HEIGHT (0x80000006) /* returns height in lines */ +#define CYBRMATTR_DEPTH (0x80000007) /* returns bits per pixel */ +#define CYBRMATTR_ISCYBERGFX (0x80000008) /* returns -1 if supplied bitmap is a cybergfx one */ +#define CYBRMATTR_ISLINEARMEM (0x80000009) /* returns -1 if supplied bitmap is linear accessable */ + +/* * + * Parameters for GetCyberIDAttr() * + * */ + +#define CYBRIDATTR_PIXFMT (0x80000001) /* the pixel format is returned */ +#define CYBRIDATTR_WIDTH (0x80000002) /* returns visible width in pixels */ +#define CYBRIDATTR_HEIGHT (0x80000003) /* returns visible height in lines */ +#define CYBRIDATTR_DEPTH (0x80000004) /* returns bits per pixel */ +#define CYBRIDATTR_BPPIX (0x80000005) /* BytesPerPixel shall be returned */ + +/* * + * Tags for CyberModeRequest() * + * */ + +#define CYBRMREQ_TB (TAG_USER+0x40000) + +/* * + * FilterTags * + * */ + +#define CYBRMREQ_MinDepth (CYBRMREQ_TB+0) /* Minimum depth for displayed screenmode */ +#define CYBRMREQ_MaxDepth (CYBRMREQ_TB+1) /* Maximum depth " " " */ +#define CYBRMREQ_MinWidth (CYBRMREQ_TB+2) /* Minumum width " " " */ +#define CYBRMREQ_MaxWidth (CYBRMREQ_TB+3) /* Maximum width " " " */ +#define CYBRMREQ_MinHeight (CYBRMREQ_TB+4) /* Minumum height " " " */ +#define CYBRMREQ_MaxHeight (CYBRMREQ_TB+5) /* Minumum height " " " */ +#define CYBRMREQ_CModelArray (CYBRMREQ_TB+6) + +#define CYBRMREQ_WinTitle (CYBRMREQ_TB+20) +#define CYBRMREQ_OKText (CYBRMREQ_TB+21) +#define CYBRMREQ_CancelText (CYBRMREQ_TB+22) + +#define CYBRMREQ_Screen (CYBRMREQ_TB+30) /* Screen you wish the Requester to open on */ + +/* * + * Tags for BestCyberModeID() * + * */ + +#define CYBRBIDTG_TB (TAG_USER+0x50000) + +/* FilterTags */ + +#define CYBRBIDTG_Depth (CYBRBIDTG_TB+0) +#define CYBRBIDTG_NominalWidth (CYBRBIDTG_TB+1) +#define CYBRBIDTG_NominalHeight (CYBRBIDTG_TB+2) +#define CYBRBIDTG_MonitorID (CYBRBIDTG_TB+3) +#define CYBRBIDTG_BoardName (CYBRBIDTG_TB+5) + +/* * + * definition of divers pixel formats * + * */ + +#define PIXFMT_LUT8 (0UL) +#define PIXFMT_RGB15 (1UL) +#define PIXFMT_RGB15X (2UL) /* CGX4 used it as RRRRRGGG GGBBBBBX, CGX3 did not support it at all */ +#define PIXFMT_BGR15 (2UL) +#define PIXFMT_RGB15PC (3UL) +#define PIXFMT_BGR15PC (4UL) +#define PIXFMT_RGB16 (5UL) +#define PIXFMT_BGR16 (6UL) +#define PIXFMT_RGB16PC (7UL) +#define PIXFMT_BGR16PC (8UL) +#define PIXFMT_RGB24 (9UL) +#define PIXFMT_BGR24 (10UL) +#define PIXFMT_ARGB32 (11UL) +#define PIXFMT_BGRA32 (12UL) +#define PIXFMT_RGBA32 (13UL) + +/* * + * SrcRectangle formats defines for xxxPixelArray calls() * + * */ + +#define RECTFMT_RGB (0UL) +#define RECTFMT_RGBA (1UL) +#define RECTFMT_ARGB (2UL) +#define RECTFMT_LUT8 (3UL) +#define RECTFMT_GREY8 (4UL) +#define RECTFMT_RAW (5UL) + +/* * + * Parameters for CVideoCtrlTagList() * + * */ + +#define SETVC_DPMSLevel (0x88002001) + +#define DPMS_ON (0UL) /* Full operation */ +#define DPMS_STANDBY (1UL) /* Optional state of minimal power reduction */ +#define DPMS_SUSPEND (2UL) /* Significant reduction of power consumption */ +#define DPMS_OFF (3UL) /* Lowest level of power consumption */ + +/* * + * Tags for LockBitMapTagList() * + * */ + +#define LBMI_WIDTH (0x84001001) +#define LBMI_HEIGHT (0x84001002) +#define LBMI_DEPTH (0x84001003) +#define LBMI_PIXFMT (0x84001004) +#define LBMI_BYTESPERPIX (0x84001005) +#define LBMI_BYTESPERROW (0x84001006) +#define LBMI_BASEADDRESS (0x84001007) + +/* * + * Tags for UnLockBitMapTagList() * + * */ + +#define UBMI_UPDATERECTS (0x85001001) +#define UBMI_REALLYUNLOCK (0x85001002) + + + +/* * + * Message passed to the DoCDrawMethodTagList() hook function * + * */ + + +struct CDrawMsg +{ + APTR cdm_MemPtr; + ULONG cdm_offx; + ULONG cdm_offy; + ULONG cdm_xsize; + ULONG cdm_ysize; + UWORD cdm_BytesPerRow; + UWORD cdm_BytesPerPix; + UWORD cdm_ColorModel; +}; + +/* * + * Colour Table source formats for WriteLUTPixelArray() * + * */ + +#define CTABFMT_XRGB8 (0UL) /* ULONG [] table */ + + +/* * + * graphics.library/AllocBitMap() extended flags * + * */ + +#ifndef BMB_SPECIALFMT +#define BMB_SPECIALFMT (7UL) +#define BMF_SPECIALFMT (1UL << BMB_SPECIALFMT) +#endif /* BMB_SPECIALFMT */ + +#define SHIFT_PIXFMT( fmt ) (((ULONG)(fmt)) << 24UL) + + +#ifndef BMF_REQUESTVMEM +#define BMF_REQUESTVMEM (BMF_MINPLANES|BMF_DISPLAYABLE) +#endif + +#ifndef BMB_ROOTMAP +#define BMB_ROOTMAP (5UL) +#define BMF_ROOTMAP (1UL << BMB_ROOTMAP) +#endif /* BMB_ROOTMAP */ + +#ifndef BMB_3DTARGET +#define BMB_3DTARGET (8UL) +#define BMF_3DTARGET (1UL << BMB_3DTARGET) +#endif /* BMB_3DTARGET */ + +/* + * Operations for ProcessPixelArray() (v50) + * + */ + +#define POP_BRIGHTEN 0 +#define POP_DARKEN 1 +#define POP_SETALPHA 2 +#define POP_TINT 3 +#define POP_BLUR 4 +#define POP_COLOR2GREY 5 +#define POP_NEGATIVE 6 +#define POP_NEGFADE 7 +#define POP_TINTFADE 8 +#define POP_GRADIENT 9 +#define POP_SHIFTRGB 10 + +/* + * Values for POP_SHIFTRGB + * + */ + +#define RGBSHIFT_BGR (1UL) +#define RGBSHIFT_BRG (2UL) +#define RGBSHIFT_GBR (3UL) +#define RGBSHIFT_GRB (4UL) +#define RGBSHIFT_RBG (5UL) + + +/* + * Tags for ProcessPixelArray() ops + * + */ + +#define PPAOPTAG_FADEFULLSCALE 0x85231020 +#define PPAOPTAG_FADEOFFSET 0x85231021 + + +#define PPAOPTAG_GRADIENTTYPE 0x85231022 + +#define GRADTYPE_HORIZONTAL 0 +#define GRADTYPE_VERTICAL 1 + +/* yet unsupported gradient types follow */ +#define GRADTYPE_RECTANGLE 2 +#define GRADTYPE_LINEAR_ANGLE 3 +#define GRADTYPE_RADIAL 4 /* "circle" center-based */ + +#define GRADIENT_NUMTYPES 2 + +#define PPAOPTAG_GRADCOLOR1 0x85231023 +#define PPAOPTAG_GRADCOLOR2 0x85231024 + +#define PPAOPTAG_GRADFULLSCALE PPAOPTAG_FADEFULLSCALE +#define PPAOPTAG_GRADOFFSET PPAOPTAG_FADEOFFSET + +#define PPAOPTAG_RGBMASK 0x85231025 + +#define PPAOPTAG_GRADSYMCENTER 0x85231026 + +/* + * Tags for BltBitMap(RastPort)Alpha() (v50) + * + */ + +#define BLTBMA_MIXLEVEL 0x88802000 /* from 0(0%) to 0xFFFFFFFF (100%) */ +#define BLTBMA_USESOURCEALPHA 0x88802001 +#define BLTBMA_GLOBALALPHA BLTBMA_MIXLEVEL +#define BLTBMA_DESTALPHAVALUE 0x88802002 + +#define DESTALPHAVALUE_UNDEFINED 0 /* default */ +#define DESTALPHAVALUE_ONE 1 +#define DESTALPHAVALUE_USESOURCE 2 +#define DESTALPHAVALUE_USEDEST 3 + +#if defined(__GNUC__) && __GNUC__ > 2 +#pragma pack() +#endif //defined(__GNUC__) && __GNUC__ > 2 + +#endif /* !CYBERGRAPHX_CYBERGRAPHICS_H */ diff --git a/scalos/include/datatypes/animationclassext.h b/scalos/include/datatypes/animationclassext.h new file mode 100755 index 000000000..9c8b270b7 --- /dev/null +++ b/scalos/include/datatypes/animationclassext.h @@ -0,0 +1,70 @@ + +#ifndef DATATYPES_ANIMATIONCLASSEXT_H +#define DATATYPES_ANIMATIONCLASSEXT_H 1 +/* +** $VER: animationclass.h 41.2 (23.9.97) +** +** Extended Interface definitions for DataType animation objects. +** Note: This include file will be merged with animationclass.h !! +** +** Written by Roland Mainz, gisburn@w-specht.rhein-ruhr.de +** +*/ + +#ifndef DATATYPES_ANIMATIONCLASS_H +#include +#endif /* !DATATYPES_ANIMATIONCLASS_H */ + +#ifndef LIBRARIES_REALTIME_H +#include +#endif /* !LIBRARIES_REALTIME_H */ + +/* Animation attributes */ +#ifndef ADTA_Dummy +#define ADTA_Dummy (DTA_Dummy + 600UL) +#endif /* !ADTA_Dummy */ + +/* reserved tag space for CBM/AT/AI usage */ +#define ADTA_CBMReserved0 (ADTA_Dummy + 8) +#define ADTA_CBMReserved1 (ADTA_Dummy + 9) +#define ADTA_CBMReserved2 (ADTA_Dummy + 10) +#define ADTA_CBMReserved3 (ADTA_Dummy + 11) +#define ADTA_CBMReserved4 (ADTA_Dummy + 12) +#define ADTA_CBMReserved5 (ADTA_Dummy + 13) +#define ADTA_CBMReserved6 (ADTA_Dummy + 14) +#define ADTA_CBMReserved7 (ADTA_Dummy + 15) +#define ADTA_CBMReserved8 (ADTA_Dummy + 16) +#define ADTA_CBMReserved9 (ADTA_Dummy + 17) +#define ADTA_CBMReserved10 (ADTA_Dummy + 18) +#define ADTA_CBMReserved11 (ADTA_Dummy + 19) +#define ADTA_CBMReserved12 (ADTA_Dummy + 20) +#define ADTA_CBMReserved13 (ADTA_Dummy + 21) +#define ADTA_CBMReserved14 (ADTA_Dummy + 22) +#define ADTA_CBMReserved15 (ADTA_Dummy + 23) + +/* Alias */ +#define ADTA_BitMapHeader PDTA_BitMapHeader /* (struct BitMapHeader *) */ +#define ADTA_VoiceHeader SDTA_VoiceHeader /* (struct VoiceHeader *) */ +#define ADTA_Grab PDTA_Grab /* (Point *) */ +#define ADTA_DestFrame PDTA_DestBitMap /* (struct BitMap *) -- current remapped frame. Only save to read when object os NOT playing */ + +/* Timing related */ +#define ADTA_TicksPerFrame (ADTA_Dummy + 24) /* (ULONG) Like ADTA_FramesPerSecond: TICK_FREQ / fps == tpf */ +#define ADTA_CurrTicksPerFrame (ADTA_Dummy + 25) /* (ULONG) Current tpf, as set by a slider etc, or set by adaptive + * FPS rate calculations + */ +#define ADTA_CurrFramesPerSecond (ADTA_Dummy + 26) /* (ULONG) Like TICK_FREQ / curr_tpf == curr_fps */ + +/* Touch and burn ! */ +#define ADTA_Private0 (ADTA_Dummy + 27) /* (APTR) Do NOT touch !! */ +#define ADTA_Private1 (ADTA_Dummy + 28) /* (APTR) Do NOT touch !! */ + +/* Misc */ +#define ADTA_AdaptiveFPS (ADTA_Dummy + 30) /* (BOOL) Use adaptive FPS rate selection during playback */ +#define ADTA_SmartSkip (ADTA_Dummy + 31) /* (BOOL) Skip frames based on display time weight */ +#define ADTA_NumPrefetchFrames (ADTA_Dummy + 32) /* Number of frames to prefetch by load process */ +#define ADTA_OvertakeScreen (ADTA_Dummy + 33) /* Overtake screen palette */ + +#endif /* !DATATYPES_ANIMATIONCLASSEXT_H */ + + diff --git a/scalos/include/datatypes/iconobject.h b/scalos/include/datatypes/iconobject.h new file mode 100755 index 000000000..3fc548e1f --- /dev/null +++ b/scalos/include/datatypes/iconobject.h @@ -0,0 +1,533 @@ +#ifndef DATATYPES_ICONOBJECT_H +#define DATATYPES_ICONOBJECT_H +/* +** $VER: iconobject.h 41.6 (23 Jan 2008 21:30:36) +** +** iconobject.library include +** +** (C) Copyright 1996-1999 ALiENDESiGN +** (C) Copyright 2000-2008 The Scalos Team +** All Rights Reserved +*/ + +#ifndef EXEC_TYPES_H +#include +#endif + +#ifndef INTUITION_IMAGECLASS_H +#include +#endif + +#ifndef DATATYPES_DATATYPESCLASS_H +#include +#endif + + +#define ICONOBJECTNAME "iconobject.library" + + +/* #define DTA_Dummy 0x80001000 // TAGUSER+0x1000 */ + + +/* + * Icon object attributes + */ + +#define IDTA_Type DTA_Dummy+901 /* (.SG) ULONG - Icon Type */ +#define IDTA_Text DTA_Dummy+902 /* (ISG) STRPTR - Icon Text */ +#define IDTA_DefaultTool DTA_Dummy+903 /* (.SG) STRPTR - DefaultTool */ +#define IDTA_WindowRect DTA_Dummy+904 /* (.SG) struct IBox * - WindowSize - Get can return NULL if icon has no DrawerData information */ + +#define IDTA_ToolTypes DTA_Dummy+905 /* (.SG) STRPTR * - Tooltype Array */ + /* Beware: a tooltype pointer received by GetAttr() will get invalid */ + /* (memory gets freed) as soon as tooltypes are changed with */ + /* SetAttrs(IDTA_ToolTypes...). */ + +#define IDTA_Stacksize DTA_Dummy+906 /* (.SG) Stacksize */ +#define IDTA_InnerLeft DTA_Dummy+907 /* (ISG) */ +#define IDTA_InnerTop DTA_Dummy+908 /* (ISG) */ +#define IDTA_InnerRight DTA_Dummy+909 /* (ISG) */ +#define IDTA_InnerBottom DTA_Dummy+910 /* (ISG) */ +#define IDTA_FrameType DTA_Dummy+911 /* (ISG) */ +#define IDTA_WinCurrentX DTA_Dummy+912 /* (.SG) */ +#define IDTA_WinCurrentY DTA_Dummy+913 /* (.SG) */ +#define IDTA_LayoutFlags DTA_Dummy+914 /* (..G) */ +#define IDTA_Extention DTA_Dummy+915 /* (..G) e.g. ".info" */ +#define IDTA_Mask_Normal DTA_Dummy+916 /* (.SG) UBYTE * - BlitMask */ +#define IDTA_Mask_Selected DTA_Dummy+917 /* (.SG) UBYTE * - BlitMask */ +#define IDTA_Flags DTA_Dummy+918 /* (.SG) DrawerData Flags */ +#define IDTA_ViewModes DTA_Dummy+919 /* (.SG) DrawerData ViewModes */ +#define IDTA_DefType DTA_Dummy+920 /* (I..) ULONG - DefIcon Type */ +//#define IDTA_MaxDepth DTA_Dummy+921 /* (.S.) of the bitmap */ UNUSED +#define IDTA_TextPenOutline DTA_Dummy+922 /* (ISG) UWORD - textpen for outline text */ +#define IDTA_TextMode DTA_Dummy+923 /* (IS.) UBYTE - textmode - IDTV_TextMode_*** */ +#define IDTA_TextSkip DTA_Dummy+924 /* (IS.) UBYTE - space between text and image */ +#define IDTA_FrameTypeSel DTA_Dummy+925 /* (ISG) UWORD - SelectedFrame */ +#define IDTA_HalfShadowPen DTA_Dummy+926 /* (ISG) UWORD - needed for some frames */ +#define IDTA_HalfShinePen DTA_Dummy+927 /* (ISG) UWORD - needed for some frames */ +#define IDTA_RenderHook DTA_Dummy+928 /* (IS.) struct Hook * - needed for animated AppIcons +jl+ */ +#define IDTA_DoFreeDiskObject DTA_Dummy+929 /* (I..) ULONG - Flag: free DiskObject delivered by AIDTA_Icon +jl+ */ +#define IDTA_TextStyle DTA_Dummy+930 /* (ISG) ULONG - +jl+ 20011231 Text style for icon text */ +#define IDTA_Font DTA_Dummy+931 /* (ISG) struct TextFont * - +jl+ 20010818 font to render icon text in */ +#define IDTA_SupportedIconTypes DTA_Dummy+932 /* (I..) ULONG - bits enable specific icon types */ +#define IDTA_TextPen DTA_Dummy+933 /* (ISG) UWORD - icon text pen */ +#define IDTA_TextPenSel DTA_Dummy+934 /* (ISG) UWORD - selected icon text pen */ +#define IDTA_TextPenShadow DTA_Dummy+935 /* (ISG) UWORD - icon text shadow pen */ +#define IDTA_MaskBM_Normal DTA_Dummy+936 /* (..G) struct BitMap * - +jl+ 20020201 */ +#define IDTA_MaskBM_Selected DTA_Dummy+937 /* (..G) struct BitMap * - +jl+ 20020201 */ +#define IDTA_UserFlags DTA_Dummy+938 /* (ISG) ULONG - +jl+ 20020928 */ +#define IDTA_Borderless DTA_Dummy+939 /* (ISG) ULONG - always draw icon without border */ +#define IDTA_AlphaChannel DTA_Dummy+940 /* (..G) UBYTE * - byte array of alpha channel information + or NULL if no alpha channel supported */ +#define IDTA_IconLocation DTA_Dummy+941 /* (I..) const struct WBArg * - icon location of object for this icon */ +#define IDTA_Fonthandle DTA_Dummy+942 /* (ISG) APTR - opaque font handle to use with font function vector */ +#define IDTA_FontHook DTA_Dummy+943 /* (ISG) struct Hook * - font function Hook */ +#define IDTA_MultiLineText DTA_Dummy+944 /* (ISG) ULONG - Flag: allow splitting of icon text into multiple lines */ +#define IDTA_ARGBImageData DTA_Dummy+945 /* (..G) struct ARGBHeader * image data in ARGB format. Not available for all icon types */ +#define IDTA_SizeConstraints DTA_Dummy+946 /* (I..) struct Rectangle * - set min/max sizes for icon */ +#define IDTA_Width_Mask_Normal DTA_Dummy+947 /* (ISG) ULONG - Witdh of non-selected mask bitplane */ +#define IDTA_Height_Mask_Normal DTA_Dummy+948 /* (ISG) UBYTE * - Height of non-selected mask bitplane */ +#define IDTA_Width_Mask_Selected DTA_Dummy+949 /* (ISG) UBYTE * - Width of selected mask bitplane */ +#define IDTA_Height_Mask_Selected DTA_Dummy+950 /* (ISG) UBYTE * - Height of non-selected mask bitplane */ +#define IDTA_CopyARGBImageData DTA_Dummy+951 /* (ISG) ULONG - If TRUE, copy IDTA_ARGBImageData */ +#define IDTA_IconType DTA_Dummy+952 /* (..G) ULONG - type of icon */ +#define IDTA_NumberOfColorsSupported DTA_Dummy+953 /* (..G) ULONG - number of colors supported by icon type (e.g. 256 by GlowIcons + NewIcons) */ +#define IDTA_OverlayType DTA_Dummy+954 /* (ISG) ULONG - type of overlay to draw over icon - not used, but only stored by datatype */ +#define IDTA_Backfill DTA_Dummy+955 /* (ISG) ULONG - Pen number to use for unselected background fill */ +#define IDTA_BackfillSel DTA_Dummy+956 /* (ISG) ULONG - Pen number to use for selected background fill */ +#define IDTA_TextDrawMode DTA_Dummy+957 /* (ISG) UBYTE - draw mode for icon Text (JAM1 or JAM2) */ +#define IDTA_TextBackPen DTA_Dummy+958 /* (ISG) UBYTE - icon text background color for IDTA_TextDrawMode = IDTA_TextDrawMode */ +#define IDTA_CopySelARGBImageData DTA_Dummy+959 /* (ISG) ULONG - If TRUE, copy IDTA_SelARGBImageData */ +#define IDTA_SelARGBImageData DTA_Dummy+960 /* (..G) struct ARGBHeader * selected image data in ARGB format. Not available for all icon types */ +#define IDTA_SelAlphaChannel DTA_Dummy+961 /* (..G) UBYTE * - byte array of alpha channel information + or NULL if no alpha channel supported */ +#define IDTA_ToolWindow DTA_Dummy+962 /* (.SG) STRPTR - Tool Window */ +#define IDTA_CloneIconObject DTA_Dummy+963 /* (I..) */ +#define IDTA_TextPenBgSel DTA_Dummy+964 /* (ISG) UWORD - pen for rectangle around selected icon text */ +#define IDTA_SelectedTextRectangle DTA_Dummy+965 /* (I.G) ULONG - Flag: draw rectangle around selected icon text */ +#define IDTA_SelTextRectBorderX DTA_Dummy+966 /* (ISG) UWORD - Additional horizontal border around selected icon text rectangle */ +#define IDTA_SelTextRectBorderY DTA_Dummy+967 /* (ISG) UWORD - Additional vertical border around selected icon text rectangle */ +#define IDTA_SelTextRectRadius DTA_Dummy+968 /* (ISG) UWORD - Radius for selected icon text rectangle corners */ + +#define IDTA_UnscaledWidth DTA_Dummy+969 /* (ISG) ULONG - unscaled width of icon */ +#define IDTA_UnscaledHeight DTA_Dummy+970 /* (ISG) ULONG - unscaled width of icon */ + +#define IDTA_ScalePercentage DTA_Dummy+971 /* (I..) UWORD - Scale factor in percent */ + +//amigaicon.datatype +#define AIDTA_Icon DTA_Dummy+1101 /* (I.G) orginal diskobject */ + +// allowed range for IDTA_ScalePercentage +#define IDTA_ScalePercentage_MIN 25 +#define IDTA_ScalePercentage_MAX 400 + +/* IDTA_SupportedIconTypes values (bit mask) */ +#define IDTV_IconType_NewIcon 0x00000001 +#define IDTV_IconType_ColorIcon 0x00000002 + + +/* IDTA_TextMode values */ +#define IDTV_TextMode_Normal 0 +#define IDTV_TextMode_Outline 1 +#define IDTV_TextMode_Shadow 2 + + +/* IDTA_Viewmodes values - also used in ws_Viewmodes */ +#define IDTV_ViewModes_Default 0 +#define IDTV_ViewModes_Icon 1 +#define IDTV_ViewModes_Name 2 +#define IDTV_ViewModes_Size 3 +#define IDTV_ViewModes_Date 4 +#define IDTV_ViewModes_Time 5 +#define IDTV_ViewModes_Comment 6 +#define IDTV_ViewModes_Protection 7 +#define IDTV_ViewModes_Owner 8 +#define IDTV_ViewModes_Group 9 +#define IDTV_ViewModes_Type 10 +#define IDTV_ViewModes_Version 11 +#define IDTV_ViewModes_MiniIcon 12 + + +/* IDTA_UserFlags flag bits */ +#define ICONOBJ_USERFLAGB_DrawShadowed 0 // this icon should be rendered in shadowed state +#define ICONOBJ_USERFLAGB_DefaultIcon 1 // this is a default icon and may be rendered specially +#define ICONOBJ_USERFLAGB_DrawHighlite 2 // Draw icon in highlighted state +#define ICONOBJ_USERFLAGB_Thumbnail 3 // This is an image thumbnail + +#define ICONOBJ_USERFLAGF_DrawShadowed (1L << ICONOBJ_USERFLAGB_DrawShadowed) +#define ICONOBJ_USERFLAGF_DefaultIcon (1L << ICONOBJ_USERFLAGB_DefaultIcon) +#define ICONOBJ_USERFLAGF_DrawHighlite (1L << ICONOBJ_USERFLAGB_DrawHighlite) +#define ICONOBJ_USERFLAGF_Thumbnail (1L << ICONOBJ_USERFLAGB_Thumbnail) + +/*----------------------------------------------------------------------------------*/ + +/* Icon types - parameter for IDTA_IconType */ +enum ioIconTypes + { + ioICONTYPE_Standard, // standard icon + ioICONTYPE_NewIcon, + ioICONTYPE_GlowIcon, // OS3.5+ GlowIcon + ioICONTYPE_PngIcon, + }; + +/*----------------------------------------------------------------------------------*/ + +/* parameter for IDTA_FontFunctions */ + +enum ioFontHookMsgTypes + { + iofMsg_DONERASTPORT, + iofMsg_SETFONT, + iofMsg_TEXT, + iofMsg_SETFONTSTYLE, + iofMsg_TEXTEXTENT, + iofMsg_TEXTFIT, + iofMsg_GETFONTHEIGHT, + iofMsg_GETFONTBASELINE, + iofMsg_SETTRANSPARENCY, + }; + +#if defined(__MORPHOS__) +#pragma pack(2) +#endif + +struct ioFontMsg_DoneRastPort + { + ULONG MsgID; // iofMsg_DONERASTPORT + struct RastPort *iofdr_RastPort; + void *iofdr_FontHandle; + }; + +struct ioFontMsg_SetFont + { + ULONG MsgID; // iofMsg_SETFONT + struct RastPort *iofsf_RastPort; + void *iofsf_FontHandle; + struct TextFont *iofsf_TextFont; + }; + +struct ioFontMsg_Text + { + ULONG MsgID; // iofMsg_TEXT + struct RastPort *ioft_RastPort; + void *ioft_FontHandle; + CONST_STRPTR ioft_String; + WORD ioft_Length; + }; + +struct ioFontMsg_SetFontStyle + { + ULONG MsgID; // iofMsg_SETFONTSTYLE + struct RastPort *iofsfs_RastPort; + void *iofsfs_FontHandle; + ULONG iofsfs_Style; + ULONG iofsfs_Enable; + }; + +struct ioFontMsg_TextExtent + { + ULONG MsgID; // iofMsg_TEXTEXTENT + struct RastPort *iofte_RastPort; + void *iofte_FontHandle; + CONST_STRPTR iofte_String; + WORD iofte_Length; + struct TextExtent *iofte_TextExtent; + }; + +struct ioFontMsg_TextFit + { + ULONG MsgID; // iofMsg_TEXTFIT + struct RastPort *ioftf_RastPort; + void *ioftf_FontHandle; + CONST_STRPTR ioftf_String; + WORD ioftf_Length; + struct TextExtent *ioftf_TextExtent; + struct TextExtent *ioftf_ConstrainingTextExtent; + WORD ioftf_StrDirection; + UWORD ioftf_ConstrainingBitWidth; + UWORD ioftf_ConstrainingBitHeight; + }; + +struct ioFontMsg_GetFontHeight + { + ULONG MsgID; // iofMsg_GETFONTHEIGHT + struct RastPort *iofgfh_RastPort; + void *iofgfh_FontHandle; + }; + +struct ioFontMsg_GetFontBaseline + { + ULONG MsgID; // iofMsg_GETFONTBASELINE + struct RastPort *iofgfb_RastPort; + void *iofgfb_FontHandle; + }; + +struct ioFontMsg_SetTransparency + { + ULONG MsgID; // iofMsg_SETTRANSPARENCY + struct RastPort *iofst_RastPort; + void *iofst_FontHandle; + ULONG iofst_Transparency; // 0=no transparency (opaque), 255=maximum transparency + }; + +#if defined(__MORPHOS__) +#pragma pack() +#endif + +/*----------------------------------------------------------------------------------*/ + +/* + * Icon object methods + */ + +#define IDTM_Layout (DTA_Dummy+1001) +#define IDTM_Draw (DTA_Dummy+1002) +#define IDTM_Write (DTA_Dummy+1003) /* PutDiskObject */ +#define IDTM_FindToolType (DTA_Dummy+1004) +#define IDTM_GetToolTypeValue (DTA_Dummy+1005) +#define IDTM_FreeLayout (DTA_Dummy+1006) +#define IDTM_Erase (DTA_Dummy+1007) // CURRENTLY UNUSED +#define IDTM_ScaleIcon (DTA_Dummy+1008) +#define IDTM_NewImage (DTA_Dummy+1009) +#define IDTM_CloneIconObject (DTA_Dummy+1010) + +/*----------------------------------------------------------------------------------*/ + +/* + * IDTM_Layout method + */ + +struct iopLayout +{ + ULONG MethodID; + struct Screen *iopl_Screen; + struct Window *iopl_Window; + struct RastPort *iopl_RastPort; + struct DrawInfo *iopl_DrawInfo; + ULONG iopl_Flags; +}; + +/* Flags */ +#define IOLAYOUTB_NormalImage 0 +#define IOLAYOUTB_SelectedImage 1 + +#define IOLAYOUTF_NormalImage (1L<Width, BoundsWidth will be adjusted accordingly) + ULONG iops_NewHeight; // Scaled icon height (Gadget->Height, BoundsHeight will be adjusted accordingly) + ULONG iops_Flags; /* flags */ +}; + +/* Flags */ +// same as for IDTM_Layout +//IOLAYOUTF_NormalImage +//IOLAYOUTF_SelectedImage + +/*----------------------------------------------------------------------------------*/ + +/* + * IDTM_NewImage method + */ + +struct iopNewImage +{ + ULONG MethodID; /* IDTM_NewImage */ + struct ScalosBitMapAndColor *ioni_NormalImage; + struct ScalosBitMapAndColor *ioni_SelectedImage; /* may be NULL for IDTM_NewSelectedImage */ +}; + +/*----------------------------------------------------------------------------------*/ + +/* + * IDTM_CloneIconObject method + */ + +struct iopCloneIconObject +{ + ULONG MethodID; + struct TagItem *iocio_TagList; +}; + +/*----------------------------------------------------------------------------------*/ + +// values for IDTA_OverlayType + +#define ICONOVERLAY_None 0 + +#define ICONOVERLAYB_LeftOut 0 +#define ICONOVERLAYB_ReadOnly 1 +#define ICONOVERLAYB_Thumbnail 2 + +#define ICONOVERLAY_MAX 3 + +#define ICONOVERLAYF_LeftOut (1 << ICONOVERLAYB_LeftOut) +#define ICONOVERLAYF_ReadOnly (1 << ICONOVERLAYB_ReadOnly) +#define ICONOVERLAYF_Thumbnail (1 << ICONOVERLAYB_Thumbnail) + +/*----------------------------------------------------------------------------------*/ + +// special value for IDTA_Backfill and IDTA_BackfillSel + +#define IDTA_BACKFILL_NONE ((ULONG) ~0) + +/*----------------------------------------------------------------------------------*/ + +/* + * texticon.datatype (scalos internal) + */ + +//#define TIDTA_ExAllData DTA_Dummy+1151 /* (IS.) deprecated */ +//#define TIDTA_ExAllType DTA_Dummy+1152 /* (IS.) deprecated */ +#define TIDTA_WidthArray DTA_Dummy+1153 /* (ISG) */ +//#define TIDTA_ExNextData DTA_Dummy+1154 /* (IS.) deprecated */ +#define TIDTA_FileType DTA_Dummy+1155 /* (..G) */ +#define TIDTA_Size DTA_Dummy+1156 /* (..G) */ +#define TIDTA_Days DTA_Dummy+1157 /* (..G) */ +#define TIDTA_Mins DTA_Dummy+1158 /* (..G) */ +#define TIDTA_Ticks DTA_Dummy+1159 /* (..G) */ +#define TIDTA_Comment DTA_Dummy+1160 /* (..G) */ +#define TIDTA_Owner_UID DTA_Dummy+1161 /* (..G) UWORD */ +#define TIDTA_Owner_GID DTA_Dummy+1162 /* (..G) UWORD */ +#define TIDTA_Protection DTA_Dummy+1163 /* (..G) */ +#define TIDTA_TextStyle DTA_Dummy+1164 /* (ISG) ULONG text style for text icons, see SetSoftStyle() +jl+ 20011231 */ +#define TIDTA_Font DTA_Dummy+1165 /* (ISG) (struct TextFont *) - font to render icon text in +jl+ 20010903 */ +#define TIDTA_IconType DTA_Dummy+1167 /* (ISG) ULONG - Workbench icon type +jl+ 20010906 */ +#define TIDTA_TTFont DTA_Dummy+1168 /* (ISG) APTR - ttEngine font to render icon text in +jl+ 20030110 */ +#define TIDTA_WindowTask DTA_Dummy+1169 /* (I..) struct ScaWindowTask * - parent WindowTask */ +#define TIDTA_IconObject DTA_Dummy+1170 /* (ISG) Object * */ +#define TIDTA_SoloIcon DTA_Dummy+1171 /* (ISG) ULONG (Boolean) TRUE if this an icon w/o object */ +#define TIDTA_ColumnWidthChangeHook DTA_Dummy+1172 /* (ISG) struct Hook * - Hook is called when icon layout causes column width to change */ +#define TIDTA_SelectNameOnly DTA_Dummy+1173 /* (ISG) ULONG - if TRUE, icon can only be selected at name column */ +#define TIDTA_TypeNode DTA_Dummy+1174 /* (ISG) struct TypeNode * - TypeNode Workbench icon type */ +#define TIDTA_TextPenDrawerNormal DTA_Dummy+1175 /* (ISG) UWORD - text window normal icon text pen for drawers */ +#define TIDTA_TextPenDrawerSelected DTA_Dummy+1176 /* (ISG) UWORD - text window selected icon text pen for drawers */ +#define TIDTA_TextPenFileNormal DTA_Dummy+1177 /* (ISG) UWORD - text window normal icon text pen for files */ +#define TIDTA_TextPenFileSelected DTA_Dummy+1178 /* (ISG) UWORD - text window selected icon text pen for files */ +#define TIDTA_ReadIconListData DTA_Dummy+1180 /* (IS.) struct ReadIconListData * */ + +/*----------------------------------------------------------------------------------*/ + +#endif /* DATATYPES_ICONOBJECT_H */ diff --git a/scalos/include/defines/dtlib.h b/scalos/include/defines/dtlib.h new file mode 100644 index 000000000..6a6b0b84a --- /dev/null +++ b/scalos/include/defines/dtlib.h @@ -0,0 +1,20 @@ +/* Automatically generated header! Do not edit! */ + +#ifndef _INLINE_DTLIB_LIB_SFD_H +#define _INLINE_DTLIB_LIB_SFD_H + +#ifndef AROS_LIBCALL_H +#include +#endif /* !AROS_LIBCALL_H */ + +#ifndef DTLIB_LIB_SFD_BASE_NAME +#define DTLIB_LIB_SFD_BASE_NAME DtLibBase +#endif /* !DTLIB_LIB_SFD_BASE_NAME */ + +#define ObtainInfoEngine(___libBase) __ObtainInfoEngine_WB(DTLIB_LIB_SFD_BASE_NAME, ___libBase) +#define __ObtainInfoEngine_WB(___base, ___libBase) \ + AROS_LC1(Class *, ObtainInfoEngine, \ + AROS_LCA(struct Library *, (___libBase), A0), \ + struct Library *, (___base), 5, Dtlib_lib_sfd) + +#endif /* !_INLINE_DTLIB_LIB_SFD_H */ diff --git a/scalos/include/defines/guigfx.h b/scalos/include/defines/guigfx.h new file mode 100644 index 000000000..832c07a3f --- /dev/null +++ b/scalos/include/defines/guigfx.h @@ -0,0 +1,342 @@ +/* Automatically generated header! Do not edit! */ + +#ifndef _INLINE_GUIGFX_LIB_SFD_H +#define _INLINE_GUIGFX_LIB_SFD_H + +#ifndef AROS_LIBCALL_H +#include +#endif /* !AROS_LIBCALL_H */ + +#ifndef GUIGFX_LIB_SFD_BASE_NAME +#define GUIGFX_LIB_SFD_BASE_NAME GuiGFXBase +#endif /* !GUIGFX_LIB_SFD_BASE_NAME */ + +#define MakePictureA(___array, ___width, ___height, ___tags) __MakePictureA_WB(GUIGFX_LIB_SFD_BASE_NAME, ___array, ___width, ___height, ___tags) +#define __MakePictureA_WB(___base, ___array, ___width, ___height, ___tags) \ + AROS_LC4(APTR, MakePictureA, \ + AROS_LCA(APTR, (___array), A0), \ + AROS_LCA(UWORD, (___width), D0), \ + AROS_LCA(UWORD, (___height), D1), \ + AROS_LCA(struct TagItem *, (___tags), A1), \ + struct Library *, (___base), 5, Guigfx_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define MakePicture(___array, ___width, ___height, ___firstTag, ...) __MakePicture_WB(GUIGFX_LIB_SFD_BASE_NAME, ___array, ___width, ___height, ___firstTag, ## __VA_ARGS__) +#define __MakePicture_WB(___base, ___array, ___width, ___height, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __MakePictureA_WB((___base), (___array), (___width), (___height), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define LoadPictureA(___filename, ___tags) __LoadPictureA_WB(GUIGFX_LIB_SFD_BASE_NAME, ___filename, ___tags) +#define __LoadPictureA_WB(___base, ___filename, ___tags) \ + AROS_LC2(APTR, LoadPictureA, \ + AROS_LCA(STRPTR, (___filename), A0), \ + AROS_LCA(struct TagItem *, (___tags), A1), \ + struct Library *, (___base), 6, Guigfx_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define LoadPicture(___filename, ___firstTag, ...) __LoadPicture_WB(GUIGFX_LIB_SFD_BASE_NAME, ___filename, ___firstTag, ## __VA_ARGS__) +#define __LoadPicture_WB(___base, ___filename, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __LoadPictureA_WB((___base), (___filename), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define ReadPictureA(___rp, ___colormap, ___x, ___y, ___width, ___height, ___tags) __ReadPictureA_WB(GUIGFX_LIB_SFD_BASE_NAME, ___rp, ___colormap, ___x, ___y, ___width, ___height, ___tags) +#define __ReadPictureA_WB(___base, ___rp, ___colormap, ___x, ___y, ___width, ___height, ___tags) \ + AROS_LC7(APTR, ReadPictureA, \ + AROS_LCA(struct RastPort *, (___rp), A0), \ + AROS_LCA(struct ColorMap *, (___colormap), A1), \ + AROS_LCA(UWORD, (___x), D0), \ + AROS_LCA(UWORD, (___y), D1), \ + AROS_LCA(UWORD, (___width), D2), \ + AROS_LCA(UWORD, (___height), D3), \ + AROS_LCA(struct TagItem *, (___tags), A2), \ + struct Library *, (___base), 7, Guigfx_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define ReadPicture(___rp, ___colormap, ___x, ___y, ___width, ___height, ___firstTag, ...) __ReadPicture_WB(GUIGFX_LIB_SFD_BASE_NAME, ___rp, ___colormap, ___x, ___y, ___width, ___height, ___firstTag, ## __VA_ARGS__) +#define __ReadPicture_WB(___base, ___rp, ___colormap, ___x, ___y, ___width, ___height, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __ReadPictureA_WB((___base), (___rp), (___colormap), (___x), (___y), (___width), (___height), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define ClonePictureA(___pic, ___tags) __ClonePictureA_WB(GUIGFX_LIB_SFD_BASE_NAME, ___pic, ___tags) +#define __ClonePictureA_WB(___base, ___pic, ___tags) \ + AROS_LC2(APTR, ClonePictureA, \ + AROS_LCA(APTR, (___pic), A0), \ + AROS_LCA(struct TagItem *, (___tags), A1), \ + struct Library *, (___base), 8, Guigfx_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define ClonePicture(___pic, ___firstTag, ...) __ClonePicture_WB(GUIGFX_LIB_SFD_BASE_NAME, ___pic, ___firstTag, ## __VA_ARGS__) +#define __ClonePicture_WB(___base, ___pic, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __ClonePictureA_WB((___base), (___pic), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define DeletePicture(___pic) __DeletePicture_WB(GUIGFX_LIB_SFD_BASE_NAME, ___pic) +#define __DeletePicture_WB(___base, ___pic) \ + AROS_LC1NR(VOID, DeletePicture, \ + AROS_LCA(APTR, (___pic), A0), \ + struct Library *, (___base), 9, Guigfx_lib_sfd) + +#define AddPictureA(___psm, ___pic, ___tags) __AddPictureA_WB(GUIGFX_LIB_SFD_BASE_NAME, ___psm, ___pic, ___tags) +#define __AddPictureA_WB(___base, ___psm, ___pic, ___tags) \ + AROS_LC3(APTR, AddPictureA, \ + AROS_LCA(APTR, (___psm), A0), \ + AROS_LCA(APTR, (___pic), A1), \ + AROS_LCA(struct TagItem *, (___tags), A2), \ + struct Library *, (___base), 11, Guigfx_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define AddPicture(___psm, ___pic, ___firstTag, ...) __AddPicture_WB(GUIGFX_LIB_SFD_BASE_NAME, ___psm, ___pic, ___firstTag, ## __VA_ARGS__) +#define __AddPicture_WB(___base, ___psm, ___pic, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __AddPictureA_WB((___base), (___psm), (___pic), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define AddPaletteA(___psm, ___palette, ___tags) __AddPaletteA_WB(GUIGFX_LIB_SFD_BASE_NAME, ___psm, ___palette, ___tags) +#define __AddPaletteA_WB(___base, ___psm, ___palette, ___tags) \ + AROS_LC3(APTR, AddPaletteA, \ + AROS_LCA(APTR, (___psm), A0), \ + AROS_LCA(APTR, (___palette), A1), \ + AROS_LCA(struct TagItem *, (___tags), A2), \ + struct Library *, (___base), 12, Guigfx_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define AddPalette(___psm, ___palette, ___firstTag, ...) __AddPalette_WB(GUIGFX_LIB_SFD_BASE_NAME, ___psm, ___palette, ___firstTag, ## __VA_ARGS__) +#define __AddPalette_WB(___base, ___psm, ___palette, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __AddPaletteA_WB((___base), (___psm), (___palette), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define AddPixelArrayA(___psm, ___array, ___width, ___height, ___tags) __AddPixelArrayA_WB(GUIGFX_LIB_SFD_BASE_NAME, ___psm, ___array, ___width, ___height, ___tags) +#define __AddPixelArrayA_WB(___base, ___psm, ___array, ___width, ___height, ___tags) \ + AROS_LC5(APTR, AddPixelArrayA, \ + AROS_LCA(APTR, (___psm), A0), \ + AROS_LCA(APTR, (___array), A1), \ + AROS_LCA(UWORD, (___width), D0), \ + AROS_LCA(UWORD, (___height), D1), \ + AROS_LCA(struct TagItem *, (___tags), A2), \ + struct Library *, (___base), 13, Guigfx_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define AddPixelArray(___psm, ___array, ___width, ___height, ___firstTag, ...) __AddPixelArray_WB(GUIGFX_LIB_SFD_BASE_NAME, ___psm, ___array, ___width, ___height, ___firstTag, ## __VA_ARGS__) +#define __AddPixelArray_WB(___base, ___psm, ___array, ___width, ___height, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __AddPixelArrayA_WB((___base), (___psm), (___array), (___width), (___height), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define RemColorHandle(___colorhandle) __RemColorHandle_WB(GUIGFX_LIB_SFD_BASE_NAME, ___colorhandle) +#define __RemColorHandle_WB(___base, ___colorhandle) \ + AROS_LC1NR(VOID, RemColorHandle, \ + AROS_LCA(APTR, (___colorhandle), A0), \ + struct Library *, (___base), 14, Guigfx_lib_sfd) + +#define CreatePenShareMapA(___tags) __CreatePenShareMapA_WB(GUIGFX_LIB_SFD_BASE_NAME, ___tags) +#define __CreatePenShareMapA_WB(___base, ___tags) \ + AROS_LC1(APTR, CreatePenShareMapA, \ + AROS_LCA(struct TagItem *, (___tags), A0), \ + struct Library *, (___base), 15, Guigfx_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define CreatePenShareMap(___tags, ...) __CreatePenShareMap_WB(GUIGFX_LIB_SFD_BASE_NAME, ___tags, ## __VA_ARGS__) +#define __CreatePenShareMap_WB(___base, ___tags, ...) \ + ({IPTR _tags[] = { (IPTR) ___tags, ## __VA_ARGS__ }; __CreatePenShareMapA_WB((___base), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define DeletePenShareMap(___psm) __DeletePenShareMap_WB(GUIGFX_LIB_SFD_BASE_NAME, ___psm) +#define __DeletePenShareMap_WB(___base, ___psm) \ + AROS_LC1NR(VOID, DeletePenShareMap, \ + AROS_LCA(APTR, (___psm), A0), \ + struct Library *, (___base), 16, Guigfx_lib_sfd) + +#define ObtainDrawHandleA(___psm, ___rp, ___cm, ___tags) __ObtainDrawHandleA_WB(GUIGFX_LIB_SFD_BASE_NAME, ___psm, ___rp, ___cm, ___tags) +#define __ObtainDrawHandleA_WB(___base, ___psm, ___rp, ___cm, ___tags) \ + AROS_LC4(APTR, ObtainDrawHandleA, \ + AROS_LCA(APTR, (___psm), A0), \ + AROS_LCA(struct RastPort *, (___rp), A1), \ + AROS_LCA(struct ColorMap *, (___cm), A2), \ + AROS_LCA(struct TagItem *, (___tags), A3), \ + struct Library *, (___base), 17, Guigfx_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define ObtainDrawHandle(___psm, ___rp, ___cm, ___firstTag, ...) __ObtainDrawHandle_WB(GUIGFX_LIB_SFD_BASE_NAME, ___psm, ___rp, ___cm, ___firstTag, ## __VA_ARGS__) +#define __ObtainDrawHandle_WB(___base, ___psm, ___rp, ___cm, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __ObtainDrawHandleA_WB((___base), (___psm), (___rp), (___cm), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define ReleaseDrawHandle(___drawhandle) __ReleaseDrawHandle_WB(GUIGFX_LIB_SFD_BASE_NAME, ___drawhandle) +#define __ReleaseDrawHandle_WB(___base, ___drawhandle) \ + AROS_LC1NR(VOID, ReleaseDrawHandle, \ + AROS_LCA(APTR, (___drawhandle), A0), \ + struct Library *, (___base), 18, Guigfx_lib_sfd) + +#define DrawPictureA(___drawhandle, ___pic, ___x, ___y, ___tags) __DrawPictureA_WB(GUIGFX_LIB_SFD_BASE_NAME, ___drawhandle, ___pic, ___x, ___y, ___tags) +#define __DrawPictureA_WB(___base, ___drawhandle, ___pic, ___x, ___y, ___tags) \ + AROS_LC5(BOOL, DrawPictureA, \ + AROS_LCA(APTR, (___drawhandle), A0), \ + AROS_LCA(APTR, (___pic), A1), \ + AROS_LCA(UWORD, (___x), D0), \ + AROS_LCA(UWORD, (___y), D1), \ + AROS_LCA(struct TagItem *, (___tags), A2), \ + struct Library *, (___base), 19, Guigfx_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define DrawPicture(___drawhandle, ___pic, ___x, ___y, ___firstTag, ...) __DrawPicture_WB(GUIGFX_LIB_SFD_BASE_NAME, ___drawhandle, ___pic, ___x, ___y, ___firstTag, ## __VA_ARGS__) +#define __DrawPicture_WB(___base, ___drawhandle, ___pic, ___x, ___y, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __DrawPictureA_WB((___base), (___drawhandle), (___pic), (___x), (___y), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define MapPaletteA(___drawhandle, ___palette, ___pentab, ___tags) __MapPaletteA_WB(GUIGFX_LIB_SFD_BASE_NAME, ___drawhandle, ___palette, ___pentab, ___tags) +#define __MapPaletteA_WB(___base, ___drawhandle, ___palette, ___pentab, ___tags) \ + AROS_LC4(BOOL, MapPaletteA, \ + AROS_LCA(APTR, (___drawhandle), A0), \ + AROS_LCA(APTR, (___palette), A1), \ + AROS_LCA(UBYTE *, (___pentab), A2), \ + AROS_LCA(struct TagItem *, (___tags), A3), \ + struct Library *, (___base), 20, Guigfx_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define MapPalette(___drawhandle, ___palette, ___pentab, ___firstTag, ...) __MapPalette_WB(GUIGFX_LIB_SFD_BASE_NAME, ___drawhandle, ___palette, ___pentab, ___firstTag, ## __VA_ARGS__) +#define __MapPalette_WB(___base, ___drawhandle, ___palette, ___pentab, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __MapPaletteA_WB((___base), (___drawhandle), (___palette), (___pentab), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define MapPenA(___drawhandle, ___rgb, ___tags) __MapPenA_WB(GUIGFX_LIB_SFD_BASE_NAME, ___drawhandle, ___rgb, ___tags) +#define __MapPenA_WB(___base, ___drawhandle, ___rgb, ___tags) \ + AROS_LC3(LONG, MapPenA, \ + AROS_LCA(APTR, (___drawhandle), A0), \ + AROS_LCA(ULONG, (___rgb), A1), \ + AROS_LCA(struct TagItem *, (___tags), A2), \ + struct Library *, (___base), 21, Guigfx_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define MapPen(___drawhandle, ___rgb, ___firstTag, ...) __MapPen_WB(GUIGFX_LIB_SFD_BASE_NAME, ___drawhandle, ___rgb, ___firstTag, ## __VA_ARGS__) +#define __MapPen_WB(___base, ___drawhandle, ___rgb, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __MapPenA_WB((___base), (___drawhandle), (___rgb), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define CreatePictureBitMapA(___drawhandle, ___pic, ___tags) __CreatePictureBitMapA_WB(GUIGFX_LIB_SFD_BASE_NAME, ___drawhandle, ___pic, ___tags) +#define __CreatePictureBitMapA_WB(___base, ___drawhandle, ___pic, ___tags) \ + AROS_LC3(struct BitMap *, CreatePictureBitMapA, \ + AROS_LCA(APTR, (___drawhandle), A0), \ + AROS_LCA(APTR, (___pic), A1), \ + AROS_LCA(struct TagItem *, (___tags), A2), \ + struct Library *, (___base), 22, Guigfx_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define CreatePictureBitMap(___drawhandle, ___pic, ___firstTag, ...) __CreatePictureBitMap_WB(GUIGFX_LIB_SFD_BASE_NAME, ___drawhandle, ___pic, ___firstTag, ## __VA_ARGS__) +#define __CreatePictureBitMap_WB(___base, ___drawhandle, ___pic, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __CreatePictureBitMapA_WB((___base), (___drawhandle), (___pic), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define DoPictureMethodA(___pic, ___method, ___arguments) __DoPictureMethodA_WB(GUIGFX_LIB_SFD_BASE_NAME, ___pic, ___method, ___arguments) +#define __DoPictureMethodA_WB(___base, ___pic, ___method, ___arguments) \ + AROS_LC3(ULONG, DoPictureMethodA, \ + AROS_LCA(APTR, (___pic), A0), \ + AROS_LCA(ULONG, (___method), D0), \ + AROS_LCA(ULONG *, (___arguments), A1), \ + struct Library *, (___base), 23, Guigfx_lib_sfd) + +#ifndef NO_INLINE_VARARGS +#define DoPictureMethod(___pic, ___method, ___firstTag, ...) __DoPictureMethod_WB(GUIGFX_LIB_SFD_BASE_NAME, ___pic, ___method, ___firstTag, ## __VA_ARGS__) +#define __DoPictureMethod_WB(___base, ___pic, ___method, ___firstTag, ...) \ + ({IPTR _message[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __DoPictureMethodA_WB((___base), (___pic), (___method), (ULONG *) _message); }) +#endif /* !NO_INLINE_VARARGS */ + +#define GetPictureAttrsA(___pic, ___tags) __GetPictureAttrsA_WB(GUIGFX_LIB_SFD_BASE_NAME, ___pic, ___tags) +#define __GetPictureAttrsA_WB(___base, ___pic, ___tags) \ + AROS_LC2(ULONG, GetPictureAttrsA, \ + AROS_LCA(APTR, (___pic), A0), \ + AROS_LCA(struct TagItem *, (___tags), A1), \ + struct Library *, (___base), 24, Guigfx_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define GetPictureAttrs(___pic, ___firstTag, ...) __GetPictureAttrs_WB(GUIGFX_LIB_SFD_BASE_NAME, ___pic, ___firstTag, ## __VA_ARGS__) +#define __GetPictureAttrs_WB(___base, ___pic, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __GetPictureAttrsA_WB((___base), (___pic), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define LockPictureA(___pic, ___mode, ___args) __LockPictureA_WB(GUIGFX_LIB_SFD_BASE_NAME, ___pic, ___mode, ___args) +#define __LockPictureA_WB(___base, ___pic, ___mode, ___args) \ + AROS_LC3(ULONG, LockPictureA, \ + AROS_LCA(APTR, (___pic), A0), \ + AROS_LCA(ULONG, (___mode), D0), \ + AROS_LCA(ULONG *, (___args), A1), \ + struct Library *, (___base), 25, Guigfx_lib_sfd) + +#ifndef NO_INLINE_VARARGS +#define LockPicture(___pic, ___mode, ___firstTag, ...) __LockPicture_WB(GUIGFX_LIB_SFD_BASE_NAME, ___pic, ___mode, ___firstTag, ## __VA_ARGS__) +#define __LockPicture_WB(___base, ___pic, ___mode, ___firstTag, ...) \ + ({IPTR _message[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __LockPictureA_WB((___base), (___pic), (___mode), (ULONG *) _message); }) +#endif /* !NO_INLINE_VARARGS */ + +#define UnLockPicture(___pic, ___mode) __UnLockPicture_WB(GUIGFX_LIB_SFD_BASE_NAME, ___pic, ___mode) +#define __UnLockPicture_WB(___base, ___pic, ___mode) \ + AROS_LC2NR(VOID, UnLockPicture, \ + AROS_LCA(APTR, (___pic), A0), \ + AROS_LCA(ULONG, (___mode), D0), \ + struct Library *, (___base), 26, Guigfx_lib_sfd) + +#define IsPictureA(___filename, ___tags) __IsPictureA_WB(GUIGFX_LIB_SFD_BASE_NAME, ___filename, ___tags) +#define __IsPictureA_WB(___base, ___filename, ___tags) \ + AROS_LC2(BOOL, IsPictureA, \ + AROS_LCA(STRPTR, (___filename), A0), \ + AROS_LCA(struct TagItem *, (___tags), A1), \ + struct Library *, (___base), 27, Guigfx_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define IsPicture(___filename, ___firstTag, ...) __IsPicture_WB(GUIGFX_LIB_SFD_BASE_NAME, ___filename, ___firstTag, ## __VA_ARGS__) +#define __IsPicture_WB(___base, ___filename, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __IsPictureA_WB((___base), (___filename), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define CreateDirectDrawHandleA(___drawhandle, ___sw, ___sh, ___dw, ___dh, ___tags) __CreateDirectDrawHandleA_WB(GUIGFX_LIB_SFD_BASE_NAME, ___drawhandle, ___sw, ___sh, ___dw, ___dh, ___tags) +#define __CreateDirectDrawHandleA_WB(___base, ___drawhandle, ___sw, ___sh, ___dw, ___dh, ___tags) \ + AROS_LC6(APTR, CreateDirectDrawHandleA, \ + AROS_LCA(APTR, (___drawhandle), A0), \ + AROS_LCA(UWORD, (___sw), D0), \ + AROS_LCA(UWORD, (___sh), D1), \ + AROS_LCA(UWORD, (___dw), D2), \ + AROS_LCA(UWORD, (___dh), D3), \ + AROS_LCA(struct TagItem *, (___tags), A1), \ + struct Library *, (___base), 28, Guigfx_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define CreateDirectDrawHandle(___drawhandle, ___sw, ___sh, ___dw, ___dh, ___firstTag, ...) __CreateDirectDrawHandle_WB(GUIGFX_LIB_SFD_BASE_NAME, ___drawhandle, ___sw, ___sh, ___dw, ___dh, ___firstTag, ## __VA_ARGS__) +#define __CreateDirectDrawHandle_WB(___base, ___drawhandle, ___sw, ___sh, ___dw, ___dh, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __CreateDirectDrawHandleA_WB((___base), (___drawhandle), (___sw), (___sh), (___dw), (___dh), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define DeleteDirectDrawHandle(___ddh) __DeleteDirectDrawHandle_WB(GUIGFX_LIB_SFD_BASE_NAME, ___ddh) +#define __DeleteDirectDrawHandle_WB(___base, ___ddh) \ + AROS_LC1NR(VOID, DeleteDirectDrawHandle, \ + AROS_LCA(APTR, (___ddh), A0), \ + struct Library *, (___base), 29, Guigfx_lib_sfd) + +#define DirectDrawTrueColorA(___ddh, ___array, ___x, ___y, ___tags) __DirectDrawTrueColorA_WB(GUIGFX_LIB_SFD_BASE_NAME, ___ddh, ___array, ___x, ___y, ___tags) +#define __DirectDrawTrueColorA_WB(___base, ___ddh, ___array, ___x, ___y, ___tags) \ + AROS_LC5(BOOL, DirectDrawTrueColorA, \ + AROS_LCA(APTR, (___ddh), A0), \ + AROS_LCA(ULONG *, (___array), A1), \ + AROS_LCA(UWORD, (___x), D0), \ + AROS_LCA(UWORD, (___y), D1), \ + AROS_LCA(struct TagItem *, (___tags), A2), \ + struct Library *, (___base), 30, Guigfx_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define DirectDrawTrueColor(___ddh, ___array, ___x, ___y, ___firstTag, ...) __DirectDrawTrueColor_WB(GUIGFX_LIB_SFD_BASE_NAME, ___ddh, ___array, ___x, ___y, ___firstTag, ## __VA_ARGS__) +#define __DirectDrawTrueColor_WB(___base, ___ddh, ___array, ___x, ___y, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __DirectDrawTrueColorA_WB((___base), (___ddh), (___array), (___x), (___y), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define CreatePictureMaskA(___pic, ___mask, ___maskwidth, ___tags) __CreatePictureMaskA_WB(GUIGFX_LIB_SFD_BASE_NAME, ___pic, ___mask, ___maskwidth, ___tags) +#define __CreatePictureMaskA_WB(___base, ___pic, ___mask, ___maskwidth, ___tags) \ + AROS_LC4(BOOL, CreatePictureMaskA, \ + AROS_LCA(APTR, (___pic), A0), \ + AROS_LCA(UBYTE *, (___mask), A1), \ + AROS_LCA(UWORD, (___maskwidth), D0), \ + AROS_LCA(struct TagItem *, (___tags), A2), \ + struct Library *, (___base), 31, Guigfx_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define CreatePictureMask(___pic, ___mask, ___maskwidth, ___firstTag, ...) __CreatePictureMask_WB(GUIGFX_LIB_SFD_BASE_NAME, ___pic, ___mask, ___maskwidth, ___firstTag, ## __VA_ARGS__) +#define __CreatePictureMask_WB(___base, ___pic, ___mask, ___maskwidth, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __CreatePictureMaskA_WB((___base), (___pic), (___mask), (___maskwidth), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#endif /* !_INLINE_GUIGFX_LIB_SFD_H */ diff --git a/scalos/include/defines/iconobject.h b/scalos/include/defines/iconobject.h new file mode 100644 index 000000000..dce75c138 --- /dev/null +++ b/scalos/include/defines/iconobject.h @@ -0,0 +1,85 @@ +/* Automatically generated header! Do not edit! */ + +#ifndef _INLINE_ICONOBJECT_LIB_SFD_H +#define _INLINE_ICONOBJECT_LIB_SFD_H + +#ifndef AROS_LIBCALL_H +#include +#endif /* !AROS_LIBCALL_H */ + +#ifndef ICONOBJECT_LIB_SFD_BASE_NAME +#define ICONOBJECT_LIB_SFD_BASE_NAME IconobjectBase +#endif /* !ICONOBJECT_LIB_SFD_BASE_NAME */ + +#define NewIconObject(___name, ___tagList) __NewIconObject_WB(ICONOBJECT_LIB_SFD_BASE_NAME, ___name, ___tagList) +#define __NewIconObject_WB(___base, ___name, ___tagList) \ + AROS_LC2(Object *, NewIconObject, \ + AROS_LCA(CONST_STRPTR, (___name), A0), \ + AROS_LCA(CONST struct TagItem *, (___tagList), A1), \ + struct Library *, (___base), 5, Iconobject_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define NewIconObjectTags(___name, ___firstTag, ...) __NewIconObjectTags_WB(ICONOBJECT_LIB_SFD_BASE_NAME, ___name, ___firstTag, ## __VA_ARGS__) +#define __NewIconObjectTags_WB(___base, ___name, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __NewIconObject_WB((___base), (___name), (CONST struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define DisposeIconObject(___iconObject) __DisposeIconObject_WB(ICONOBJECT_LIB_SFD_BASE_NAME, ___iconObject) +#define __DisposeIconObject_WB(___base, ___iconObject) \ + AROS_LC1NR(VOID, DisposeIconObject, \ + AROS_LCA(Object *, (___iconObject), A0), \ + struct Library *, (___base), 6, Iconobject_lib_sfd) + +#define GetDefIconObject(___iconType, ___tagList) __GetDefIconObject_WB(ICONOBJECT_LIB_SFD_BASE_NAME, ___iconType, ___tagList) +#define __GetDefIconObject_WB(___base, ___iconType, ___tagList) \ + AROS_LC2(Object *, GetDefIconObject, \ + AROS_LCA(ULONG, (___iconType), D0), \ + AROS_LCA(CONST struct TagItem *, (___tagList), A0), \ + struct Library *, (___base), 7, Iconobject_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define GetDefIconObjectTags(___iconType, ___firstTag, ...) __GetDefIconObjectTags_WB(ICONOBJECT_LIB_SFD_BASE_NAME, ___iconType, ___firstTag, ## __VA_ARGS__) +#define __GetDefIconObjectTags_WB(___base, ___iconType, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __GetDefIconObject_WB((___base), (___iconType), (CONST struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define PutIconObject(___iconObject, ___path, ___tagList) __PutIconObject_WB(ICONOBJECT_LIB_SFD_BASE_NAME, ___iconObject, ___path, ___tagList) +#define __PutIconObject_WB(___base, ___iconObject, ___path, ___tagList) \ + AROS_LC3(LONG, PutIconObject, \ + AROS_LCA(Object *, (___iconObject), A0), \ + AROS_LCA(CONST_STRPTR, (___path), A1), \ + AROS_LCA(CONST struct TagItem *, (___tagList), A2), \ + struct Library *, (___base), 8, Iconobject_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define PutIconObjectTags(___iconObject, ___path, ___firstTag, ...) __PutIconObjectTags_WB(ICONOBJECT_LIB_SFD_BASE_NAME, ___iconObject, ___path, ___firstTag, ## __VA_ARGS__) +#define __PutIconObjectTags_WB(___base, ___iconObject, ___path, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __PutIconObject_WB((___base), (___iconObject), (___path), (CONST struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define IsIconName(___fileName) __IsIconName_WB(ICONOBJECT_LIB_SFD_BASE_NAME, ___fileName) +#define __IsIconName_WB(___base, ___fileName) \ + AROS_LC1(ULONG, IsIconName, \ + AROS_LCA(CONST_STRPTR, (___fileName), A0), \ + struct Library *, (___base), 9, Iconobject_lib_sfd) + +#define Convert2IconObject(___diskObject) __Convert2IconObject_WB(ICONOBJECT_LIB_SFD_BASE_NAME, ___diskObject) +#define __Convert2IconObject_WB(___base, ___diskObject) \ + AROS_LC1(Object *, Convert2IconObject, \ + AROS_LCA(struct DiskObject *, (___diskObject), A0), \ + struct Library *, (___base), 10, Iconobject_lib_sfd) + +#define Convert2IconObjectA(___diskObject, ___tagList) __Convert2IconObjectA_WB(ICONOBJECT_LIB_SFD_BASE_NAME, ___diskObject, ___tagList) +#define __Convert2IconObjectA_WB(___base, ___diskObject, ___tagList) \ + AROS_LC2(Object *, Convert2IconObjectA, \ + AROS_LCA(struct DiskObject *, (___diskObject), A0), \ + AROS_LCA(CONST struct TagItem *, (___tagList), A1), \ + struct Library *, (___base), 11, Iconobject_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define Convert2IconObjectTags(___diskObject, ___firstTag, ...) __Convert2IconObjectTags_WB(ICONOBJECT_LIB_SFD_BASE_NAME, ___diskObject, ___firstTag, ## __VA_ARGS__) +#define __Convert2IconObjectTags_WB(___base, ___diskObject, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __Convert2IconObjectA_WB((___base), (___diskObject), (CONST struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#endif /* !_INLINE_ICONOBJECT_LIB_SFD_H */ diff --git a/scalos/include/defines/mcpgfx.h b/scalos/include/defines/mcpgfx.h new file mode 100644 index 000000000..6071faaa5 --- /dev/null +++ b/scalos/include/defines/mcpgfx.h @@ -0,0 +1,84 @@ +/* Automatically generated header! Do not edit! */ + +#ifndef _INLINE_MCPGFX_LIB_SFD_H +#define _INLINE_MCPGFX_LIB_SFD_H + +#ifndef AROS_LIBCALL_H +#include +#endif /* !AROS_LIBCALL_H */ + +#ifndef MCPGFX_LIB_SFD_BASE_NAME +#define MCPGFX_LIB_SFD_BASE_NAME MCPGfxBase +#endif /* !MCPGFX_LIB_SFD_BASE_NAME */ + +#define mcpPaintSysIGad(___sysImageObject, ___drawInfo, ___gadgetNumber, ___width, ___height) __mcpPaintSysIGad_WB(MCPGFX_LIB_SFD_BASE_NAME, ___sysImageObject, ___drawInfo, ___gadgetNumber, ___width, ___height) +#define __mcpPaintSysIGad_WB(___base, ___sysImageObject, ___drawInfo, ___gadgetNumber, ___width, ___height) \ + AROS_LC5NR(VOID, mcpPaintSysIGad, \ + AROS_LCA(APTR, (___sysImageObject), A0), \ + AROS_LCA(struct DrawInfo *, (___drawInfo), A1), \ + AROS_LCA(WORD, (___gadgetNumber), D0), \ + AROS_LCA(WORD, (___width), D1), \ + AROS_LCA(WORD, (___height), D2), \ + struct Library *, (___base), 5, Mcpgfx_lib_sfd) + +#define mcpRectFillA(___rp, ___x1, ___y1, ___x2, ___y2, ___tagList) __mcpRectFillA_WB(MCPGFX_LIB_SFD_BASE_NAME, ___rp, ___x1, ___y1, ___x2, ___y2, ___tagList) +#define __mcpRectFillA_WB(___base, ___rp, ___x1, ___y1, ___x2, ___y2, ___tagList) \ + AROS_LC6NR(VOID, mcpRectFillA, \ + AROS_LCA(struct RastPort *, (___rp), A0), \ + AROS_LCA(WORD, (___x1), D0), \ + AROS_LCA(WORD, (___y1), D1), \ + AROS_LCA(WORD, (___x2), D2), \ + AROS_LCA(WORD, (___y2), D3), \ + AROS_LCA(CONST struct TagItem *, (___tagList), A1), \ + struct Library *, (___base), 6, Mcpgfx_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define mcpRectFill(___rp, ___x1, ___y1, ___x2, ___y2, ___tagList, ...) __mcpRectFill_WB(MCPGFX_LIB_SFD_BASE_NAME, ___rp, ___x1, ___y1, ___x2, ___y2, ___tagList, ## __VA_ARGS__) +#define __mcpRectFill_WB(___base, ___rp, ___x1, ___y1, ___x2, ___y2, ___tagList, ...) \ + ({IPTR _tags[] = { (IPTR) ___tagList, ## __VA_ARGS__ }; __mcpRectFillA_WB((___base), (___rp), (___x1), (___y1), (___x2), (___y2), (CONST struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define mcpDrawFrameA(___rp, ___x1, ___y1, ___x2, ___y2, ___tagList) __mcpDrawFrameA_WB(MCPGFX_LIB_SFD_BASE_NAME, ___rp, ___x1, ___y1, ___x2, ___y2, ___tagList) +#define __mcpDrawFrameA_WB(___base, ___rp, ___x1, ___y1, ___x2, ___y2, ___tagList) \ + AROS_LC6NR(VOID, mcpDrawFrameA, \ + AROS_LCA(struct RastPort *, (___rp), A0), \ + AROS_LCA(WORD, (___x1), D0), \ + AROS_LCA(WORD, (___y1), D1), \ + AROS_LCA(WORD, (___x2), D2), \ + AROS_LCA(WORD, (___y2), D3), \ + AROS_LCA(struct TagItem *, (___tagList), A1), \ + struct Library *, (___base), 7, Mcpgfx_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define mcpDrawFrame(___rp, ___x1, ___y1, ___x2, ___y2, ___tagList, ...) __mcpDrawFrame_WB(MCPGFX_LIB_SFD_BASE_NAME, ___rp, ___x1, ___y1, ___x2, ___y2, ___tagList, ## __VA_ARGS__) +#define __mcpDrawFrame_WB(___base, ___rp, ___x1, ___y1, ___x2, ___y2, ___tagList, ...) \ + ({IPTR _tags[] = { (IPTR) ___tagList, ## __VA_ARGS__ }; __mcpDrawFrameA_WB((___base), (___rp), (___x1), (___y1), (___x2), (___y2), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define mcpGetExtDrawInfo(___screen, ___drawInfo) __mcpGetExtDrawInfo_WB(MCPGFX_LIB_SFD_BASE_NAME, ___screen, ___drawInfo) +#define __mcpGetExtDrawInfo_WB(___base, ___screen, ___drawInfo) \ + AROS_LC2(struct ExtDrawInfo *, mcpGetExtDrawInfo, \ + AROS_LCA(struct Screen *, (___screen), A0), \ + AROS_LCA(struct DrawInfo *, (___drawInfo), A1), \ + struct Library *, (___base), 8, Mcpgfx_lib_sfd) + +#define mcpGetFrameSize(___drawInfo, ___frameType) __mcpGetFrameSize_WB(MCPGFX_LIB_SFD_BASE_NAME, ___drawInfo, ___frameType) +#define __mcpGetFrameSize_WB(___base, ___drawInfo, ___frameType) \ + AROS_LC2(struct FrameSize *, mcpGetFrameSize, \ + AROS_LCA(struct DrawInfo *, (___drawInfo), A0), \ + AROS_LCA(WORD, (___frameType), D0), \ + struct Library *, (___base), 9, Mcpgfx_lib_sfd) + +#define mcpSetGFXAttrsA(___tagList) __mcpSetGFXAttrsA_WB(MCPGFX_LIB_SFD_BASE_NAME, ___tagList) +#define __mcpSetGFXAttrsA_WB(___base, ___tagList) \ + AROS_LC1NR(VOID, mcpSetGFXAttrsA, \ + AROS_LCA(struct TagItem *, (___tagList), A0), \ + struct Library *, (___base), 10, Mcpgfx_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define mcpSetGFXAttrs(___tagList, ...) __mcpSetGFXAttrs_WB(MCPGFX_LIB_SFD_BASE_NAME, ___tagList, ## __VA_ARGS__) +#define __mcpSetGFXAttrs_WB(___base, ___tagList, ...) \ + ({IPTR _tags[] = { (IPTR) ___tagList, ## __VA_ARGS__ }; __mcpSetGFXAttrsA_WB((___base), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#endif /* !_INLINE_MCPGFX_LIB_SFD_H */ diff --git a/scalos/include/defines/newicon.h b/scalos/include/defines/newicon.h new file mode 100644 index 000000000..14182a550 --- /dev/null +++ b/scalos/include/defines/newicon.h @@ -0,0 +1,71 @@ +/* Automatically generated header! Do not edit! */ + +#ifndef _INLINE_NEWICON_LIB_SFD_H +#define _INLINE_NEWICON_LIB_SFD_H + +#ifndef AROS_LIBCALL_H +#include +#endif /* !AROS_LIBCALL_H */ + +#ifndef NEWICON_LIB_SFD_BASE_NAME +#define NEWICON_LIB_SFD_BASE_NAME NewIconBase +#endif /* !NEWICON_LIB_SFD_BASE_NAME */ + +#define GetNewDiskObject(___name) __GetNewDiskObject_WB(NEWICON_LIB_SFD_BASE_NAME, ___name) +#define __GetNewDiskObject_WB(___base, ___name) \ + AROS_LC1(struct NewDiskObject *, GetNewDiskObject, \ + AROS_LCA(UBYTE *, (___name), A0), \ + struct Library *, (___base), 5, Newicon_lib_sfd) + +#define PutNewDiskObject(___name, ___newdiskobj) __PutNewDiskObject_WB(NEWICON_LIB_SFD_BASE_NAME, ___name, ___newdiskobj) +#define __PutNewDiskObject_WB(___base, ___name, ___newdiskobj) \ + AROS_LC2(BOOL, PutNewDiskObject, \ + AROS_LCA(UBYTE *, (___name), A0), \ + AROS_LCA(struct NewDiskObject *, (___newdiskobj), A1), \ + struct Library *, (___base), 6, Newicon_lib_sfd) + +#define FreeNewDiskObject(___newdiskobj) __FreeNewDiskObject_WB(NEWICON_LIB_SFD_BASE_NAME, ___newdiskobj) +#define __FreeNewDiskObject_WB(___base, ___newdiskobj) \ + AROS_LC1NR(VOID, FreeNewDiskObject, \ + AROS_LCA(struct NewDiskObject *, (___newdiskobj), A0), \ + struct Library *, (___base), 7, Newicon_lib_sfd) + +#define newiconPrivate1(___diskobj) __newiconPrivate1_WB(NEWICON_LIB_SFD_BASE_NAME, ___diskobj) +#define __newiconPrivate1_WB(___base, ___diskobj) \ + AROS_LC1(BOOL, newiconPrivate1, \ + AROS_LCA(struct NewDiskObject *, (___diskobj), A0), \ + struct Library *, (___base), 8, Newicon_lib_sfd) + +#define newiconPrivate2(___diskobj) __newiconPrivate2_WB(NEWICON_LIB_SFD_BASE_NAME, ___diskobj) +#define __newiconPrivate2_WB(___base, ___diskobj) \ + AROS_LC1(UBYTE **, newiconPrivate2, \ + AROS_LCA(struct NewDiskObject *, (___diskobj), A0), \ + struct Library *, (___base), 9, Newicon_lib_sfd) + +#define newiconPrivate3(___diskobj) __newiconPrivate3_WB(NEWICON_LIB_SFD_BASE_NAME, ___diskobj) +#define __newiconPrivate3_WB(___base, ___diskobj) \ + AROS_LC1NR(VOID, newiconPrivate3, \ + AROS_LCA(struct NewDiskObject *, (___diskobj), A0), \ + struct Library *, (___base), 10, Newicon_lib_sfd) + +#define RemapChunkyImage(___chunkyimage, ___screen) __RemapChunkyImage_WB(NEWICON_LIB_SFD_BASE_NAME, ___chunkyimage, ___screen) +#define __RemapChunkyImage_WB(___base, ___chunkyimage, ___screen) \ + AROS_LC2(struct Image *, RemapChunkyImage, \ + AROS_LCA(struct ChunkyImage *, (___chunkyimage), A0), \ + AROS_LCA(struct Screen *, (___screen), A1), \ + struct Library *, (___base), 11, Newicon_lib_sfd) + +#define FreeRemappedImage(___image, ___screen) __FreeRemappedImage_WB(NEWICON_LIB_SFD_BASE_NAME, ___image, ___screen) +#define __FreeRemappedImage_WB(___base, ___image, ___screen) \ + AROS_LC2NR(VOID, FreeRemappedImage, \ + AROS_LCA(struct Image *, (___image), A0), \ + AROS_LCA(struct Screen *, (___screen), A1), \ + struct Library *, (___base), 12, Newicon_lib_sfd) + +#define GetDefNewDiskObject(___def_type) __GetDefNewDiskObject_WB(NEWICON_LIB_SFD_BASE_NAME, ___def_type) +#define __GetDefNewDiskObject_WB(___base, ___def_type) \ + AROS_LC1(struct NewDiskObject *, GetDefNewDiskObject, \ + AROS_LCA(LONG, (___def_type), D0), \ + struct Library *, (___base), 13, Newicon_lib_sfd) + +#endif /* !_INLINE_NEWICON_LIB_SFD_H */ diff --git a/scalos/include/defines/preferences.h b/scalos/include/defines/preferences.h new file mode 100644 index 000000000..5eae41ca4 --- /dev/null +++ b/scalos/include/defines/preferences.h @@ -0,0 +1,99 @@ +/* Automatically generated header! Do not edit! */ + +#ifndef _INLINE_PREFERENCES_LIB_SFD_H +#define _INLINE_PREFERENCES_LIB_SFD_H + +#ifndef AROS_LIBCALL_H +#include +#endif /* !AROS_LIBCALL_H */ + +#ifndef PREFERENCES_LIB_SFD_BASE_NAME +#define PREFERENCES_LIB_SFD_BASE_NAME PreferencesBase +#endif /* !PREFERENCES_LIB_SFD_BASE_NAME */ + +#define AllocPrefsHandle(___name) __AllocPrefsHandle_WB(PREFERENCES_LIB_SFD_BASE_NAME, ___name) +#define __AllocPrefsHandle_WB(___base, ___name) \ + AROS_LC1(APTR, AllocPrefsHandle, \ + AROS_LCA(CONST_STRPTR, (___name), A0), \ + struct Library *, (___base), 5, Preferences_lib_sfd) + +#define FreePrefsHandle(___prefsHandle) __FreePrefsHandle_WB(PREFERENCES_LIB_SFD_BASE_NAME, ___prefsHandle) +#define __FreePrefsHandle_WB(___base, ___prefsHandle) \ + AROS_LC1NR(VOID, FreePrefsHandle, \ + AROS_LCA(APTR, (___prefsHandle), A0), \ + struct Library *, (___base), 6, Preferences_lib_sfd) + +#define SetPreferences(___prefsHandle, ___iD, ___prefsTag, ___a1arg, ___struct_Size) __SetPreferences_WB(PREFERENCES_LIB_SFD_BASE_NAME, ___prefsHandle, ___iD, ___prefsTag, ___a1arg, ___struct_Size) +#define __SetPreferences_WB(___base, ___prefsHandle, ___iD, ___prefsTag, ___a1arg, ___struct_Size) \ + AROS_LC5NR(VOID, SetPreferences, \ + AROS_LCA(APTR, (___prefsHandle), A0), \ + AROS_LCA(ULONG, (___iD), D0), \ + AROS_LCA(ULONG, (___prefsTag), D1), \ + AROS_LCA(const APTR, (___a1arg), A1), \ + AROS_LCA(UWORD, (___struct_Size), D2), \ + struct Library *, (___base), 7, Preferences_lib_sfd) + +#define GetPreferences(___prefsHandle, ___iD, ___prefsTag, ___a1arg, ___struct_Size) __GetPreferences_WB(PREFERENCES_LIB_SFD_BASE_NAME, ___prefsHandle, ___iD, ___prefsTag, ___a1arg, ___struct_Size) +#define __GetPreferences_WB(___base, ___prefsHandle, ___iD, ___prefsTag, ___a1arg, ___struct_Size) \ + AROS_LC5(ULONG, GetPreferences, \ + AROS_LCA(APTR, (___prefsHandle), A0), \ + AROS_LCA(ULONG, (___iD), D0), \ + AROS_LCA(ULONG, (___prefsTag), D1), \ + AROS_LCA(APTR, (___a1arg), A1), \ + AROS_LCA(UWORD, (___struct_Size), D2), \ + struct Library *, (___base), 8, Preferences_lib_sfd) + +#define ReadPrefsHandle(___prefsHandle, ___filename) __ReadPrefsHandle_WB(PREFERENCES_LIB_SFD_BASE_NAME, ___prefsHandle, ___filename) +#define __ReadPrefsHandle_WB(___base, ___prefsHandle, ___filename) \ + AROS_LC2NR(VOID, ReadPrefsHandle, \ + AROS_LCA(APTR, (___prefsHandle), A0), \ + AROS_LCA(CONST_STRPTR, (___filename), A1), \ + struct Library *, (___base), 9, Preferences_lib_sfd) + +#define WritePrefsHandle(___prefsHandle, ___filename) __WritePrefsHandle_WB(PREFERENCES_LIB_SFD_BASE_NAME, ___prefsHandle, ___filename) +#define __WritePrefsHandle_WB(___base, ___prefsHandle, ___filename) \ + AROS_LC2NR(VOID, WritePrefsHandle, \ + AROS_LCA(APTR, (___prefsHandle), A0), \ + AROS_LCA(CONST_STRPTR, (___filename), A1), \ + struct Library *, (___base), 10, Preferences_lib_sfd) + +#define FindPreferences(___prefsHandle, ___iD, ___prefsTag) __FindPreferences_WB(PREFERENCES_LIB_SFD_BASE_NAME, ___prefsHandle, ___iD, ___prefsTag) +#define __FindPreferences_WB(___base, ___prefsHandle, ___iD, ___prefsTag) \ + AROS_LC3(struct PrefsStruct *, FindPreferences, \ + AROS_LCA(APTR, (___prefsHandle), A0), \ + AROS_LCA(ULONG, (___iD), D0), \ + AROS_LCA(ULONG, (___prefsTag), D1), \ + struct Library *, (___base), 11, Preferences_lib_sfd) + +#define SetEntry(___prefsHandle, ___iD, ___prefsTag, ___a1arg, ___struct_Size, ___entry) __SetEntry_WB(PREFERENCES_LIB_SFD_BASE_NAME, ___prefsHandle, ___iD, ___prefsTag, ___a1arg, ___struct_Size, ___entry) +#define __SetEntry_WB(___base, ___prefsHandle, ___iD, ___prefsTag, ___a1arg, ___struct_Size, ___entry) \ + AROS_LC6NR(VOID, SetEntry, \ + AROS_LCA(APTR, (___prefsHandle), A0), \ + AROS_LCA(ULONG, (___iD), D0), \ + AROS_LCA(ULONG, (___prefsTag), D1), \ + AROS_LCA(const APTR, (___a1arg), A1), \ + AROS_LCA(UWORD, (___struct_Size), D2), \ + AROS_LCA(ULONG, (___entry), D3), \ + struct Library *, (___base), 12, Preferences_lib_sfd) + +#define GetEntry(___prefsHandle, ___iD, ___prefsTag, ___a1arg, ___struct_Size, ___entry) __GetEntry_WB(PREFERENCES_LIB_SFD_BASE_NAME, ___prefsHandle, ___iD, ___prefsTag, ___a1arg, ___struct_Size, ___entry) +#define __GetEntry_WB(___base, ___prefsHandle, ___iD, ___prefsTag, ___a1arg, ___struct_Size, ___entry) \ + AROS_LC6(ULONG, GetEntry, \ + AROS_LCA(APTR, (___prefsHandle), A0), \ + AROS_LCA(ULONG, (___iD), D0), \ + AROS_LCA(ULONG, (___prefsTag), D1), \ + AROS_LCA(APTR, (___a1arg), A1), \ + AROS_LCA(UWORD, (___struct_Size), D2), \ + AROS_LCA(ULONG, (___entry), D3), \ + struct Library *, (___base), 13, Preferences_lib_sfd) + +#define RemEntry(___prefsHandle, ___iD, ___prefsTag, ___entry) __RemEntry_WB(PREFERENCES_LIB_SFD_BASE_NAME, ___prefsHandle, ___iD, ___prefsTag, ___entry) +#define __RemEntry_WB(___base, ___prefsHandle, ___iD, ___prefsTag, ___entry) \ + AROS_LC4(ULONG, RemEntry, \ + AROS_LCA(APTR, (___prefsHandle), A0), \ + AROS_LCA(ULONG, (___iD), D0), \ + AROS_LCA(ULONG, (___prefsTag), D1), \ + AROS_LCA(ULONG, (___entry), D2), \ + struct Library *, (___base), 14, Preferences_lib_sfd) + +#endif /* !_INLINE_PREFERENCES_LIB_SFD_H */ diff --git a/scalos/include/defines/scalos.h b/scalos/include/defines/scalos.h new file mode 100644 index 000000000..6ccd5c557 --- /dev/null +++ b/scalos/include/defines/scalos.h @@ -0,0 +1,348 @@ +/* Automatically generated header! Do not edit! */ + +/*******************************************************************************/ +/* Different order of arguments for SCA_WBStart/SCA_WBStartTags manually fixed */ +/*******************************************************************************/ + +#ifndef _INLINE_SCALOS_LIB_SFD_H +#define _INLINE_SCALOS_LIB_SFD_H + +#ifndef AROS_LIBCALL_H +#include +#endif /* !AROS_LIBCALL_H */ + +#ifndef SCALOS_LIB_SFD_BASE_NAME +#define SCALOS_LIB_SFD_BASE_NAME ScalosBase +#endif /* !SCALOS_LIB_SFD_BASE_NAME */ + +#define SCA_WBStart(___argArray, ___tagList, ___numArgs) __SCA_WBStart_WB(SCALOS_LIB_SFD_BASE_NAME, ___argArray, ___tagList, ___numArgs) +#define __SCA_WBStart_WB(___base, ___argArray, ___tagList, ___numArgs) \ + AROS_LC3(BOOL, SCA_WBStart, \ + AROS_LCA(APTR, (___argArray), A0), \ + AROS_LCA(CONST struct TagItem *, (___tagList), A1), \ + AROS_LCA(ULONG, (___numArgs), D0), \ + struct Library *, (___base), 5, Scalos_lib_sfd) + +#ifndef NO_INLINE_VARARGS +#define SCA_WBStartTags(___argArray, ___numArgs, ___firstTag, ...) __SCA_WBStartTags_WB(SCALOS_LIB_SFD_BASE_NAME, ___argArray, ___numArgs, ___firstTag, ## __VA_ARGS__) +#define __SCA_WBStartTags_WB(___base, ___argArray, ___numArgs, ___firstTag, ...) \ + ({IPTR _message[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __SCA_WBStart_WB((___base), (___argArray), (ULONG) _message, (___numArgs)); }) +#endif /* !NO_INLINE_VARARGS */ + +#define SCA_SortNodes(___nodelist, ___sortHook, ___sortType) __SCA_SortNodes_WB(SCALOS_LIB_SFD_BASE_NAME, ___nodelist, ___sortHook, ___sortType) +#define __SCA_SortNodes_WB(___base, ___nodelist, ___sortHook, ___sortType) \ + AROS_LC3NR(VOID, SCA_SortNodes, \ + AROS_LCA(struct ScalosNodeList *, (___nodelist), A0), \ + AROS_LCA(struct Hook *, (___sortHook), A1), \ + AROS_LCA(ULONG, (___sortType), D0), \ + struct Library *, (___base), 6, Scalos_lib_sfd) + +#define SCA_NewAddAppIcon(___iD, ___userData, ___iconObj, ___msgPort, ___tagList) __SCA_NewAddAppIcon_WB(SCALOS_LIB_SFD_BASE_NAME, ___iD, ___userData, ___iconObj, ___msgPort, ___tagList) +#define __SCA_NewAddAppIcon_WB(___base, ___iD, ___userData, ___iconObj, ___msgPort, ___tagList) \ + AROS_LC5(struct AppObject *, SCA_NewAddAppIcon, \ + AROS_LCA(ULONG, (___iD), D0), \ + AROS_LCA(ULONG, (___userData), D1), \ + AROS_LCA(Object *, (___iconObj), A0), \ + AROS_LCA(struct MsgPort *, (___msgPort), A1), \ + AROS_LCA(CONST struct TagItem *, (___tagList), A2), \ + struct Library *, (___base), 7, Scalos_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define SCA_NewAddAppIconTags(___iD, ___userData, ___iconObj, ___msgPort, ___firstTag, ...) __SCA_NewAddAppIconTags_WB(SCALOS_LIB_SFD_BASE_NAME, ___iD, ___userData, ___iconObj, ___msgPort, ___firstTag, ## __VA_ARGS__) +#define __SCA_NewAddAppIconTags_WB(___base, ___iD, ___userData, ___iconObj, ___msgPort, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __SCA_NewAddAppIcon_WB((___base), (___iD), (___userData), (___iconObj), (___msgPort), (CONST struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define SCA_RemoveAppObject(___appObj) __SCA_RemoveAppObject_WB(SCALOS_LIB_SFD_BASE_NAME, ___appObj) +#define __SCA_RemoveAppObject_WB(___base, ___appObj) \ + AROS_LC1(BOOL, SCA_RemoveAppObject, \ + AROS_LCA(struct AppObject *, (___appObj), A0), \ + struct Library *, (___base), 8, Scalos_lib_sfd) + +#define SCA_NewAddAppWindow(___iD, ___userData, ___win, ___msgPort, ___tagList) __SCA_NewAddAppWindow_WB(SCALOS_LIB_SFD_BASE_NAME, ___iD, ___userData, ___win, ___msgPort, ___tagList) +#define __SCA_NewAddAppWindow_WB(___base, ___iD, ___userData, ___win, ___msgPort, ___tagList) \ + AROS_LC5(struct AppObject *, SCA_NewAddAppWindow, \ + AROS_LCA(ULONG, (___iD), D0), \ + AROS_LCA(ULONG, (___userData), D1), \ + AROS_LCA(struct Window *, (___win), A0), \ + AROS_LCA(struct MsgPort *, (___msgPort), A1), \ + AROS_LCA(CONST struct TagItem *, (___tagList), A2), \ + struct Library *, (___base), 9, Scalos_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define SCA_NewAddAppWindowTags(___iD, ___userData, ___win, ___msgPort, ___firstTag, ...) __SCA_NewAddAppWindowTags_WB(SCALOS_LIB_SFD_BASE_NAME, ___iD, ___userData, ___win, ___msgPort, ___firstTag, ## __VA_ARGS__) +#define __SCA_NewAddAppWindowTags_WB(___base, ___iD, ___userData, ___win, ___msgPort, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __SCA_NewAddAppWindow_WB((___base), (___iD), (___userData), (___win), (___msgPort), (CONST struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define SCA_NewAddAppMenuItem(___iD, ___userData, ___text, ___msgPort, ___tagList) __SCA_NewAddAppMenuItem_WB(SCALOS_LIB_SFD_BASE_NAME, ___iD, ___userData, ___text, ___msgPort, ___tagList) +#define __SCA_NewAddAppMenuItem_WB(___base, ___iD, ___userData, ___text, ___msgPort, ___tagList) \ + AROS_LC5(struct AppObject *, SCA_NewAddAppMenuItem, \ + AROS_LCA(ULONG, (___iD), D0), \ + AROS_LCA(ULONG, (___userData), D1), \ + AROS_LCA(CONST_STRPTR, (___text), A0), \ + AROS_LCA(struct MsgPort *, (___msgPort), A1), \ + AROS_LCA(CONST struct TagItem *, (___tagList), A2), \ + struct Library *, (___base), 10, Scalos_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define SCA_NewAddAppMenuItemTags(___iD, ___userData, ___text, ___msgPort, ___firstTag, ...) __SCA_NewAddAppMenuItemTags_WB(SCALOS_LIB_SFD_BASE_NAME, ___iD, ___userData, ___text, ___msgPort, ___firstTag, ## __VA_ARGS__) +#define __SCA_NewAddAppMenuItemTags_WB(___base, ___iD, ___userData, ___text, ___msgPort, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __SCA_NewAddAppMenuItem_WB((___base), (___iD), (___userData), (___text), (___msgPort), (CONST struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define SCA_AllocStdNode(___nodeList, ___nodeType) __SCA_AllocStdNode_WB(SCALOS_LIB_SFD_BASE_NAME, ___nodeList, ___nodeType) +#define __SCA_AllocStdNode_WB(___base, ___nodeList, ___nodeType) \ + AROS_LC2(struct MinNode *, SCA_AllocStdNode, \ + AROS_LCA(struct ScalosNodeList *, (___nodeList), A0), \ + AROS_LCA(ULONG, (___nodeType), D0), \ + struct Library *, (___base), 11, Scalos_lib_sfd) + +#define SCA_AllocNode(___nodeList, ___size) __SCA_AllocNode_WB(SCALOS_LIB_SFD_BASE_NAME, ___nodeList, ___size) +#define __SCA_AllocNode_WB(___base, ___nodeList, ___size) \ + AROS_LC2(struct MinNode *, SCA_AllocNode, \ + AROS_LCA(struct ScalosNodeList *, (___nodeList), A0), \ + AROS_LCA(ULONG, (___size), D0), \ + struct Library *, (___base), 12, Scalos_lib_sfd) + +#define SCA_FreeNode(___nodeList, ___minNode) __SCA_FreeNode_WB(SCALOS_LIB_SFD_BASE_NAME, ___nodeList, ___minNode) +#define __SCA_FreeNode_WB(___base, ___nodeList, ___minNode) \ + AROS_LC2NR(VOID, SCA_FreeNode, \ + AROS_LCA(struct ScalosNodeList *, (___nodeList), A0), \ + AROS_LCA(struct MinNode *, (___minNode), A1), \ + struct Library *, (___base), 13, Scalos_lib_sfd) + +#define SCA_FreeAllNodes(___nodeList) __SCA_FreeAllNodes_WB(SCALOS_LIB_SFD_BASE_NAME, ___nodeList) +#define __SCA_FreeAllNodes_WB(___base, ___nodeList) \ + AROS_LC1NR(VOID, SCA_FreeAllNodes, \ + AROS_LCA(struct ScalosNodeList *, (___nodeList), A0), \ + struct Library *, (___base), 14, Scalos_lib_sfd) + +#define SCA_MoveNode(___srcNodeList, ___destNodeList, ___minNode) __SCA_MoveNode_WB(SCALOS_LIB_SFD_BASE_NAME, ___srcNodeList, ___destNodeList, ___minNode) +#define __SCA_MoveNode_WB(___base, ___srcNodeList, ___destNodeList, ___minNode) \ + AROS_LC3NR(VOID, SCA_MoveNode, \ + AROS_LCA(struct ScalosNodeList *, (___srcNodeList), A0), \ + AROS_LCA(struct ScalosNodeList *, (___destNodeList), A1), \ + AROS_LCA(struct MinNode *, (___minNode), D0), \ + struct Library *, (___base), 15, Scalos_lib_sfd) + +#define SCA_SwapNodes(___minNode1, ___minNode2, ___nodeList) __SCA_SwapNodes_WB(SCALOS_LIB_SFD_BASE_NAME, ___minNode1, ___minNode2, ___nodeList) +#define __SCA_SwapNodes_WB(___base, ___minNode1, ___minNode2, ___nodeList) \ + AROS_LC3NR(VOID, SCA_SwapNodes, \ + AROS_LCA(struct MinNode *, (___minNode1), A0), \ + AROS_LCA(struct MinNode *, (___minNode2), A1), \ + AROS_LCA(struct ScalosNodeList *, (___nodeList), A2), \ + struct Library *, (___base), 16, Scalos_lib_sfd) + +#define SCA_OpenIconWindow(___tagList) __SCA_OpenIconWindow_WB(SCALOS_LIB_SFD_BASE_NAME, ___tagList) +#define __SCA_OpenIconWindow_WB(___base, ___tagList) \ + AROS_LC1(BOOL, SCA_OpenIconWindow, \ + AROS_LCA(CONST struct TagItem *, (___tagList), A0), \ + struct Library *, (___base), 17, Scalos_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define SCA_OpenIconWindowTags(___firstTag, ...) __SCA_OpenIconWindowTags_WB(SCALOS_LIB_SFD_BASE_NAME, ___firstTag, ## __VA_ARGS__) +#define __SCA_OpenIconWindowTags_WB(___base, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __SCA_OpenIconWindow_WB((___base), (CONST struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define SCA_LockWindowList(___accessmode) __SCA_LockWindowList_WB(SCALOS_LIB_SFD_BASE_NAME, ___accessmode) +#define __SCA_LockWindowList_WB(___base, ___accessmode) \ + AROS_LC1(struct ScaWindowList *, SCA_LockWindowList, \ + AROS_LCA(LONG, (___accessmode), D0), \ + struct Library *, (___base), 18, Scalos_lib_sfd) + +#define SCA_UnLockWindowList() __SCA_UnLockWindowList_WB(SCALOS_LIB_SFD_BASE_NAME) +#define __SCA_UnLockWindowList_WB(___base) \ + AROS_LC0NR(VOID, SCA_UnLockWindowList, \ + struct Library *, (___base), 19, Scalos_lib_sfd) + +#define SCA_AllocMessage(___messagetype, ___additional_size) __SCA_AllocMessage_WB(SCALOS_LIB_SFD_BASE_NAME, ___messagetype, ___additional_size) +#define __SCA_AllocMessage_WB(___base, ___messagetype, ___additional_size) \ + AROS_LC2(struct ScalosMessage *, SCA_AllocMessage, \ + AROS_LCA(ULONG, (___messagetype), D0), \ + AROS_LCA(UWORD, (___additional_size), D1), \ + struct Library *, (___base), 20, Scalos_lib_sfd) + +#define SCA_FreeMessage(___message) __SCA_FreeMessage_WB(SCALOS_LIB_SFD_BASE_NAME, ___message) +#define __SCA_FreeMessage_WB(___base, ___message) \ + AROS_LC1NR(VOID, SCA_FreeMessage, \ + AROS_LCA(struct ScalosMessage *, (___message), A1), \ + struct Library *, (___base), 21, Scalos_lib_sfd) + +#define SCA_InitDrag(___screen) __SCA_InitDrag_WB(SCALOS_LIB_SFD_BASE_NAME, ___screen) +#define __SCA_InitDrag_WB(___base, ___screen) \ + AROS_LC1(struct DragHandle *, SCA_InitDrag, \ + AROS_LCA(struct Screen *, (___screen), A0), \ + struct Library *, (___base), 22, Scalos_lib_sfd) + +#define SCA_EndDrag(___dragHandle) __SCA_EndDrag_WB(SCALOS_LIB_SFD_BASE_NAME, ___dragHandle) +#define __SCA_EndDrag_WB(___base, ___dragHandle) \ + AROS_LC1NR(VOID, SCA_EndDrag, \ + AROS_LCA(struct DragHandle *, (___dragHandle), A0), \ + struct Library *, (___base), 23, Scalos_lib_sfd) + +#define SCA_AddBob(___dragHandle, ___bm, ___mask, ___width, ___height, ___xOffset, ___yOffset) __SCA_AddBob_WB(SCALOS_LIB_SFD_BASE_NAME, ___dragHandle, ___bm, ___mask, ___width, ___height, ___xOffset, ___yOffset) +#define __SCA_AddBob_WB(___base, ___dragHandle, ___bm, ___mask, ___width, ___height, ___xOffset, ___yOffset) \ + AROS_LC7(BOOL, SCA_AddBob, \ + AROS_LCA(struct DragHandle *, (___dragHandle), A0), \ + AROS_LCA(struct BitMap *, (___bm), A1), \ + AROS_LCA(APTR, (___mask), A2), \ + AROS_LCA(ULONG, (___width), D0), \ + AROS_LCA(ULONG, (___height), D1), \ + AROS_LCA(LONG, (___xOffset), D2), \ + AROS_LCA(LONG, (___yOffset), D3), \ + struct Library *, (___base), 24, Scalos_lib_sfd) + +#define SCA_DrawDrag(___dragHandle, ___x, ___y, ___flags) __SCA_DrawDrag_WB(SCALOS_LIB_SFD_BASE_NAME, ___dragHandle, ___x, ___y, ___flags) +#define __SCA_DrawDrag_WB(___base, ___dragHandle, ___x, ___y, ___flags) \ + AROS_LC4NR(VOID, SCA_DrawDrag, \ + AROS_LCA(struct DragHandle *, (___dragHandle), A0), \ + AROS_LCA(LONG, (___x), D0), \ + AROS_LCA(LONG, (___y), D1), \ + AROS_LCA(ULONG, (___flags), D2), \ + struct Library *, (___base), 25, Scalos_lib_sfd) + +#define SCA_UpdateIcon(___windowType, ___updateIconStruct, ___ui_SIZE) __SCA_UpdateIcon_WB(SCALOS_LIB_SFD_BASE_NAME, ___windowType, ___updateIconStruct, ___ui_SIZE) +#define __SCA_UpdateIcon_WB(___base, ___windowType, ___updateIconStruct, ___ui_SIZE) \ + AROS_LC3NR(VOID, SCA_UpdateIcon, \ + AROS_LCA(UBYTE, (___windowType), D0), \ + AROS_LCA(APTR, (___updateIconStruct), A0), \ + AROS_LCA(ULONG, (___ui_SIZE), D1), \ + struct Library *, (___base), 26, Scalos_lib_sfd) + +#define SCA_MakeWBArgs(___buffer, ___in, ___argsSize) __SCA_MakeWBArgs_WB(SCALOS_LIB_SFD_BASE_NAME, ___buffer, ___in, ___argsSize) +#define __SCA_MakeWBArgs_WB(___base, ___buffer, ___in, ___argsSize) \ + AROS_LC3(ULONG, SCA_MakeWBArgs, \ + AROS_LCA(struct WBArg *, (___buffer), A0), \ + AROS_LCA(struct ScaIconNode *, (___in), A1), \ + AROS_LCA(ULONG, (___argsSize), D0), \ + struct Library *, (___base), 27, Scalos_lib_sfd) + +#define SCA_FreeWBArgs(___buffer, ___number, ___flags) __SCA_FreeWBArgs_WB(SCALOS_LIB_SFD_BASE_NAME, ___buffer, ___number, ___flags) +#define __SCA_FreeWBArgs_WB(___base, ___buffer, ___number, ___flags) \ + AROS_LC3NR(VOID, SCA_FreeWBArgs, \ + AROS_LCA(struct WBArg *, (___buffer), A0), \ + AROS_LCA(ULONG, (___number), D0), \ + AROS_LCA(ULONG, (___flags), D1), \ + struct Library *, (___base), 28, Scalos_lib_sfd) + +#define SCA_ScreenTitleMsg(___format, ___args) __SCA_ScreenTitleMsg_WB(SCALOS_LIB_SFD_BASE_NAME, ___format, ___args) +#define __SCA_ScreenTitleMsg_WB(___base, ___format, ___args) \ + AROS_LC2NR(VOID, SCA_ScreenTitleMsg, \ + AROS_LCA(CONST_STRPTR, (___format), A0), \ + AROS_LCA(APTR, (___args), A1), \ + struct Library *, (___base), 30, Scalos_lib_sfd) + +#ifndef NO_INLINE_VARARGS +#define SCA_ScreenTitleMsgArgs(___format, ___firstTag, ...) __SCA_ScreenTitleMsgArgs_WB(SCALOS_LIB_SFD_BASE_NAME, ___format, ___firstTag, ## __VA_ARGS__) +#define __SCA_ScreenTitleMsgArgs_WB(___base, ___format, ___firstTag, ...) \ + ({IPTR _message[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __SCA_ScreenTitleMsg_WB((___base), (___format), (APTR) _message); }) +#endif /* !NO_INLINE_VARARGS */ + +#define SCA_MakeScalosClass(___className, ___superClassName, ___instSize, ___dispFunc) __SCA_MakeScalosClass_WB(SCALOS_LIB_SFD_BASE_NAME, ___className, ___superClassName, ___instSize, ___dispFunc) +#define __SCA_MakeScalosClass_WB(___base, ___className, ___superClassName, ___instSize, ___dispFunc) \ + AROS_LC4(struct ScalosClass *, SCA_MakeScalosClass, \ + AROS_LCA(CONST_STRPTR, (___className), A0), \ + AROS_LCA(CONST_STRPTR, (___superClassName), A1), \ + AROS_LCA(UWORD, (___instSize), D0), \ + AROS_LCA(APTR, (___dispFunc), A2), \ + struct Library *, (___base), 31, Scalos_lib_sfd) + +#define SCA_FreeScalosClass(___scalosClass) __SCA_FreeScalosClass_WB(SCALOS_LIB_SFD_BASE_NAME, ___scalosClass) +#define __SCA_FreeScalosClass_WB(___base, ___scalosClass) \ + AROS_LC1(BOOL, SCA_FreeScalosClass, \ + AROS_LCA(struct ScalosClass *, (___scalosClass), A0), \ + struct Library *, (___base), 32, Scalos_lib_sfd) + +#define SCA_NewScalosObject(___className, ___tagList) __SCA_NewScalosObject_WB(SCALOS_LIB_SFD_BASE_NAME, ___className, ___tagList) +#define __SCA_NewScalosObject_WB(___base, ___className, ___tagList) \ + AROS_LC2(Object *, SCA_NewScalosObject, \ + AROS_LCA(CONST_STRPTR, (___className), A0), \ + AROS_LCA(CONST struct TagItem *, (___tagList), A1), \ + struct Library *, (___base), 33, Scalos_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define SCA_NewScalosObjectTags(___className, ___firstTag, ...) __SCA_NewScalosObjectTags_WB(SCALOS_LIB_SFD_BASE_NAME, ___className, ___firstTag, ## __VA_ARGS__) +#define __SCA_NewScalosObjectTags_WB(___base, ___className, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __SCA_NewScalosObject_WB((___base), (___className), (CONST struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define SCA_DisposeScalosObject(___obj) __SCA_DisposeScalosObject_WB(SCALOS_LIB_SFD_BASE_NAME, ___obj) +#define __SCA_DisposeScalosObject_WB(___base, ___obj) \ + AROS_LC1NR(VOID, SCA_DisposeScalosObject, \ + AROS_LCA(Object *, (___obj), A0), \ + struct Library *, (___base), 34, Scalos_lib_sfd) + +#define SCA_ScalosControlA(___name, ___tagList) __SCA_ScalosControlA_WB(SCALOS_LIB_SFD_BASE_NAME, ___name, ___tagList) +#define __SCA_ScalosControlA_WB(___base, ___name, ___tagList) \ + AROS_LC2(ULONG, SCA_ScalosControlA, \ + AROS_LCA(CONST_STRPTR, (___name), A0), \ + AROS_LCA(CONST struct TagItem *, (___tagList), A1), \ + struct Library *, (___base), 35, Scalos_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define SCA_ScalosControl(___name, ___firstTag, ...) __SCA_ScalosControl_WB(SCALOS_LIB_SFD_BASE_NAME, ___name, ___firstTag, ## __VA_ARGS__) +#define __SCA_ScalosControl_WB(___base, ___name, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __SCA_ScalosControlA_WB((___base), (___name), (CONST struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#ifndef NO_INLINE_STDARG +#define SCA_ScalosControlTags(___name, ___firstTag, ...) __SCA_ScalosControlTags_WB(SCALOS_LIB_SFD_BASE_NAME, ___name, ___firstTag, ## __VA_ARGS__) +#define __SCA_ScalosControlTags_WB(___base, ___name, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __SCA_ScalosControlA_WB((___base), (___name), (CONST struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define SCA_GetDefIconObject(___dirLock, ___name) __SCA_GetDefIconObject_WB(SCALOS_LIB_SFD_BASE_NAME, ___dirLock, ___name) +#define __SCA_GetDefIconObject_WB(___base, ___dirLock, ___name) \ + AROS_LC2(Object *, SCA_GetDefIconObject, \ + AROS_LCA(BPTR, (___dirLock), A0), \ + AROS_LCA(CONST_STRPTR, (___name), A1), \ + struct Library *, (___base), 36, Scalos_lib_sfd) + +#define SCA_OpenDrawerByName(___path, ___tagList) __SCA_OpenDrawerByName_WB(SCALOS_LIB_SFD_BASE_NAME, ___path, ___tagList) +#define __SCA_OpenDrawerByName_WB(___base, ___path, ___tagList) \ + AROS_LC2(struct ScaWindowStruct *, SCA_OpenDrawerByName, \ + AROS_LCA(CONST_STRPTR, (___path), A0), \ + AROS_LCA(struct TagItem *, (___tagList), A1), \ + struct Library *, (___base), 37, Scalos_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define SCA_OpenDrawerByNameTags(___path, ___firstTag, ...) __SCA_OpenDrawerByNameTags_WB(SCALOS_LIB_SFD_BASE_NAME, ___path, ___firstTag, ## __VA_ARGS__) +#define __SCA_OpenDrawerByNameTags_WB(___base, ___path, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __SCA_OpenDrawerByName_WB((___base), (___path), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define SCA_CountWBArgs(___in) __SCA_CountWBArgs_WB(SCALOS_LIB_SFD_BASE_NAME, ___in) +#define __SCA_CountWBArgs_WB(___base, ___in) \ + AROS_LC1(ULONG, SCA_CountWBArgs, \ + AROS_LCA(struct ScaIconNode *, (___in), A0), \ + struct Library *, (___base), 38, Scalos_lib_sfd) + +#define SCA_GetDefIconObjectA(___dirLock, ___name, ___tagList) __SCA_GetDefIconObjectA_WB(SCALOS_LIB_SFD_BASE_NAME, ___dirLock, ___name, ___tagList) +#define __SCA_GetDefIconObjectA_WB(___base, ___dirLock, ___name, ___tagList) \ + AROS_LC3(Object *, SCA_GetDefIconObjectA, \ + AROS_LCA(BPTR, (___dirLock), A0), \ + AROS_LCA(CONST_STRPTR, (___name), A1), \ + AROS_LCA(struct TagItem *, (___tagList), A2), \ + struct Library *, (___base), 39, Scalos_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define SCA_GetDefIconObjectTags(___dirLock, ___name, ___firstTag, ...) __SCA_GetDefIconObjectTags_WB(SCALOS_LIB_SFD_BASE_NAME, ___dirLock, ___name, ___firstTag, ## __VA_ARGS__) +#define __SCA_GetDefIconObjectTags_WB(___base, ___dirLock, ___name, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __SCA_GetDefIconObjectA_WB((___base), (___dirLock), (___name), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define SCA_LockDrag(___dragHandle) __SCA_LockDrag_WB(SCALOS_LIB_SFD_BASE_NAME, ___dragHandle) +#define __SCA_LockDrag_WB(___base, ___dragHandle) \ + AROS_LC1(ULONG, SCA_LockDrag, \ + AROS_LCA(struct DragHandle *, (___dragHandle), A0), \ + struct Library *, (___base), 40, Scalos_lib_sfd) + +#define SCA_UnlockDrag(___dragHandle) __SCA_UnlockDrag_WB(SCALOS_LIB_SFD_BASE_NAME, ___dragHandle) +#define __SCA_UnlockDrag_WB(___base, ___dragHandle) \ + AROS_LC1(ULONG, SCA_UnlockDrag, \ + AROS_LCA(struct DragHandle *, (___dragHandle), A0), \ + struct Library *, (___base), 41, Scalos_lib_sfd) + +#endif /* !_INLINE_SCALOS_LIB_SFD_H */ diff --git a/scalos/include/defines/scalosfiletypeplugin.h b/scalos/include/defines/scalosfiletypeplugin.h new file mode 100644 index 000000000..bf6d4d6d6 --- /dev/null +++ b/scalos/include/defines/scalosfiletypeplugin.h @@ -0,0 +1,21 @@ +/* Automatically generated header! Do not edit! */ + +#ifndef _INLINE_SCALOSFILETYPEPLUGIN_LIB_SFD_H +#define _INLINE_SCALOSFILETYPEPLUGIN_LIB_SFD_H + +#ifndef AROS_LIBCALL_H +#include +#endif /* !AROS_LIBCALL_H */ + +#ifndef SCALOSFILETYPEPLUGIN_LIB_SFD_BASE_NAME +#define SCALOSFILETYPEPLUGIN_LIB_SFD_BASE_NAME ScalosFileTypePluginBase +#endif /* !SCALOSFILETYPEPLUGIN_LIB_SFD_BASE_NAME */ + +#define SCAToolTipInfoString(___ttshd, ___args) __SCAToolTipInfoString_WB(SCALOSFILETYPEPLUGIN_LIB_SFD_BASE_NAME, ___ttshd, ___args) +#define __SCAToolTipInfoString_WB(___base, ___ttshd, ___args) \ + AROS_LC2(STRPTR, SCAToolTipInfoString, \ + AROS_LCA(struct ScaToolTipInfoHookData *, (___ttshd), A0), \ + AROS_LCA(CONST_STRPTR, (___args), A1), \ + struct Library *, (___base), 5, Scalosfiletypeplugin_lib_sfd) + +#endif /* !_INLINE_SCALOSFILETYPEPLUGIN_LIB_SFD_H */ diff --git a/scalos/include/defines/scalosgfx.h b/scalos/include/defines/scalosgfx.h new file mode 100644 index 000000000..62f42980e --- /dev/null +++ b/scalos/include/defines/scalosgfx.h @@ -0,0 +1,327 @@ +/* Automatically generated header! Do not edit! */ + +#ifndef _INLINE_SCALOSGFX_LIB_SFD_H +#define _INLINE_SCALOSGFX_LIB_SFD_H + +#ifndef AROS_LIBCALL_H +#include +#endif /* !AROS_LIBCALL_H */ + +#ifndef SCALOSGFX_LIB_SFD_BASE_NAME +#define SCALOSGFX_LIB_SFD_BASE_NAME ScalosGfxBase +#endif /* !SCALOSGFX_LIB_SFD_BASE_NAME */ + +#define ScalosGfxCreateEmptySAC() __ScalosGfxCreateEmptySAC_WB(SCALOSGFX_LIB_SFD_BASE_NAME) +#define __ScalosGfxCreateEmptySAC_WB(___base) \ + AROS_LC0(struct ScalosBitMapAndColor *, ScalosGfxCreateEmptySAC, \ + struct Library *, (___base), 5, Scalosgfx_lib_sfd) + +#define ScalosGfxCreateSAC(___width, ___height, ___depth, ___friendBM, ___tagList) __ScalosGfxCreateSAC_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___width, ___height, ___depth, ___friendBM, ___tagList) +#define __ScalosGfxCreateSAC_WB(___base, ___width, ___height, ___depth, ___friendBM, ___tagList) \ + AROS_LC5(struct ScalosBitMapAndColor *, ScalosGfxCreateSAC, \ + AROS_LCA(ULONG, (___width), D0), \ + AROS_LCA(ULONG, (___height), D1), \ + AROS_LCA(ULONG, (___depth), D2), \ + AROS_LCA(struct BitMap *, (___friendBM), A0), \ + AROS_LCA(struct TagItem *, (___tagList), A1), \ + struct Library *, (___base), 6, Scalosgfx_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define ScalosGfxCreateSACTags(___width, ___height, ___depth, ___friendBM, ___firstTag, ...) __ScalosGfxCreateSACTags_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___width, ___height, ___depth, ___friendBM, ___firstTag, ## __VA_ARGS__) +#define __ScalosGfxCreateSACTags_WB(___base, ___width, ___height, ___depth, ___friendBM, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __ScalosGfxCreateSAC_WB((___base), (___width), (___height), (___depth), (___friendBM), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define ScalosGfxFreeSAC(___sac) __ScalosGfxFreeSAC_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___sac) +#define __ScalosGfxFreeSAC_WB(___base, ___sac) \ + AROS_LC1NR(VOID, ScalosGfxFreeSAC, \ + AROS_LCA(struct ScalosBitMapAndColor *, (___sac), A0), \ + struct Library *, (___base), 7, Scalosgfx_lib_sfd) + +#define ScalosGfxCreateARGB(___width, ___height, ___tagList) __ScalosGfxCreateARGB_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___width, ___height, ___tagList) +#define __ScalosGfxCreateARGB_WB(___base, ___width, ___height, ___tagList) \ + AROS_LC3(struct gfxARGB *, ScalosGfxCreateARGB, \ + AROS_LCA(ULONG, (___width), D0), \ + AROS_LCA(ULONG, (___height), D1), \ + AROS_LCA(struct TagItem *, (___tagList), A0), \ + struct Library *, (___base), 8, Scalosgfx_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define ScalosGfxCreateARGBTags(___width, ___height, ___firstTag, ...) __ScalosGfxCreateARGBTags_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___width, ___height, ___firstTag, ## __VA_ARGS__) +#define __ScalosGfxCreateARGBTags_WB(___base, ___width, ___height, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __ScalosGfxCreateARGB_WB((___base), (___width), (___height), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define ScalosGfxFreeARGB(___argb) __ScalosGfxFreeARGB_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___argb) +#define __ScalosGfxFreeARGB_WB(___base, ___argb) \ + AROS_LC1NR(VOID, ScalosGfxFreeARGB, \ + AROS_LCA(struct gfxARGB **, (___argb), A0), \ + struct Library *, (___base), 9, Scalosgfx_lib_sfd) + +#define ScalosGfxARGBSetAlpha(___src, ___alpha) __ScalosGfxARGBSetAlpha_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___src, ___alpha) +#define __ScalosGfxARGBSetAlpha_WB(___base, ___src, ___alpha) \ + AROS_LC2NR(VOID, ScalosGfxARGBSetAlpha, \ + AROS_LCA(struct ARGBHeader *, (___src), A0), \ + AROS_LCA(UBYTE, (___alpha), D0), \ + struct Library *, (___base), 10, Scalosgfx_lib_sfd) + +#define ScalosGfxARGBSetAlphaMask(___argbh, ___maskPlane) __ScalosGfxARGBSetAlphaMask_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___argbh, ___maskPlane) +#define __ScalosGfxARGBSetAlphaMask_WB(___base, ___argbh, ___maskPlane) \ + AROS_LC2NR(VOID, ScalosGfxARGBSetAlphaMask, \ + AROS_LCA(struct ARGBHeader *, (___argbh), A0), \ + AROS_LCA(PLANEPTR, (___maskPlane), A1), \ + struct Library *, (___base), 11, Scalosgfx_lib_sfd) + +#define ScalosGfxCreateARGBFromBitMap(___bm, ___width, ___height, ___numberOfColors, ___colorTable, ___maskPlane) __ScalosGfxCreateARGBFromBitMap_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___bm, ___width, ___height, ___numberOfColors, ___colorTable, ___maskPlane) +#define __ScalosGfxCreateARGBFromBitMap_WB(___base, ___bm, ___width, ___height, ___numberOfColors, ___colorTable, ___maskPlane) \ + AROS_LC6(struct gfxARGB *, ScalosGfxCreateARGBFromBitMap, \ + AROS_LCA(struct BitMap *, (___bm), A0), \ + AROS_LCA(ULONG, (___width), D0), \ + AROS_LCA(ULONG, (___height), D1), \ + AROS_LCA(ULONG, (___numberOfColors), D2), \ + AROS_LCA(const ULONG *, (___colorTable), A1), \ + AROS_LCA(PLANEPTR, (___maskPlane), A2), \ + struct Library *, (___base), 12, Scalosgfx_lib_sfd) + +#define ScalosGfxFillARGBFromBitMap(___argbh, ___srcBM, ___maskPlane) __ScalosGfxFillARGBFromBitMap_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___argbh, ___srcBM, ___maskPlane) +#define __ScalosGfxFillARGBFromBitMap_WB(___base, ___argbh, ___srcBM, ___maskPlane) \ + AROS_LC3NR(VOID, ScalosGfxFillARGBFromBitMap, \ + AROS_LCA(struct ARGBHeader *, (___argbh), A0), \ + AROS_LCA(struct BitMap *, (___srcBM), A1), \ + AROS_LCA(PLANEPTR, (___maskPlane), A2), \ + struct Library *, (___base), 13, Scalosgfx_lib_sfd) + +#define ScalosGfxWriteARGBToBitMap(___argbh, ___bm, ___numberOfColors, ___colorTable) __ScalosGfxWriteARGBToBitMap_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___argbh, ___bm, ___numberOfColors, ___colorTable) +#define __ScalosGfxWriteARGBToBitMap_WB(___base, ___argbh, ___bm, ___numberOfColors, ___colorTable) \ + AROS_LC4NR(VOID, ScalosGfxWriteARGBToBitMap, \ + AROS_LCA(struct ARGBHeader *, (___argbh), A0), \ + AROS_LCA(struct BitMap *, (___bm), A1), \ + AROS_LCA(ULONG, (___numberOfColors), D0), \ + AROS_LCA(const ULONG *, (___colorTable), A2), \ + struct Library *, (___base), 14, Scalosgfx_lib_sfd) + +#define ScalosGfxMedianCut(___argbh, ___depth, ___tagList) __ScalosGfxMedianCut_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___argbh, ___depth, ___tagList) +#define __ScalosGfxMedianCut_WB(___base, ___argbh, ___depth, ___tagList) \ + AROS_LC3(struct ScalosBitMapAndColor *, ScalosGfxMedianCut, \ + AROS_LCA(struct ARGBHeader *, (___argbh), A0), \ + AROS_LCA(ULONG, (___depth), D0), \ + AROS_LCA(struct TagItem *, (___tagList), A1), \ + struct Library *, (___base), 15, Scalosgfx_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define ScalosGfxMedianCutTags(___argbh, ___depth, ___firstTag, ...) __ScalosGfxMedianCutTags_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___argbh, ___depth, ___firstTag, ## __VA_ARGS__) +#define __ScalosGfxMedianCutTags_WB(___base, ___argbh, ___depth, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __ScalosGfxMedianCut_WB((___base), (___argbh), (___depth), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define ScalosGfxScaleARGBArray(___src, ___destWidth, ___destHeight, ___tagList) __ScalosGfxScaleARGBArray_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___src, ___destWidth, ___destHeight, ___tagList) +#define __ScalosGfxScaleARGBArray_WB(___base, ___src, ___destWidth, ___destHeight, ___tagList) \ + AROS_LC4(struct gfxARGB *, ScalosGfxScaleARGBArray, \ + AROS_LCA(const struct ARGBHeader *, (___src), A0), \ + AROS_LCA(ULONG *, (___destWidth), A1), \ + AROS_LCA(ULONG *, (___destHeight), A2), \ + AROS_LCA(struct TagItem *, (___tagList), A3), \ + struct Library *, (___base), 16, Scalosgfx_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define ScalosGfxScaleARGBArrayTags(___src, ___destWidth, ___destHeight, ___firstTag, ...) __ScalosGfxScaleARGBArrayTags_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___src, ___destWidth, ___destHeight, ___firstTag, ## __VA_ARGS__) +#define __ScalosGfxScaleARGBArrayTags_WB(___base, ___src, ___destWidth, ___destHeight, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __ScalosGfxScaleARGBArray_WB((___base), (___src), (___destWidth), (___destHeight), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define ScalosGfxScaleBitMap(___sbma, ___tagList) __ScalosGfxScaleBitMap_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___sbma, ___tagList) +#define __ScalosGfxScaleBitMap_WB(___base, ___sbma, ___tagList) \ + AROS_LC2(struct BitMap *, ScalosGfxScaleBitMap, \ + AROS_LCA(struct ScaleBitMapArg *, (___sbma), A0), \ + AROS_LCA(struct TagItem *, (___tagList), A1), \ + struct Library *, (___base), 17, Scalosgfx_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define ScalosGfxScaleBitMapTags(___sbma, ___firstTag, ...) __ScalosGfxScaleBitMapTags_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___sbma, ___firstTag, ## __VA_ARGS__) +#define __ScalosGfxScaleBitMapTags_WB(___base, ___sbma, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __ScalosGfxScaleBitMap_WB((___base), (___sbma), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define ScalosGfxCalculateScaleAspect(___sourceWidth, ___sourceHeight, ___destWidth, ___destHeight) __ScalosGfxCalculateScaleAspect_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___sourceWidth, ___sourceHeight, ___destWidth, ___destHeight) +#define __ScalosGfxCalculateScaleAspect_WB(___base, ___sourceWidth, ___sourceHeight, ___destWidth, ___destHeight) \ + AROS_LC4NR(VOID, ScalosGfxCalculateScaleAspect, \ + AROS_LCA(ULONG, (___sourceWidth), D0), \ + AROS_LCA(ULONG, (___sourceHeight), D1), \ + AROS_LCA(ULONG *, (___destWidth), A0), \ + AROS_LCA(ULONG *, (___destHeight), A1), \ + struct Library *, (___base), 18, Scalosgfx_lib_sfd) + +#define ScalosGfxBlitARGB(___destARGB, ___srcARGB, ___destLeft, ___destTop, ___srcLeft, ___srcTop, ___width, ___height) __ScalosGfxBlitARGB_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___destARGB, ___srcARGB, ___destLeft, ___destTop, ___srcLeft, ___srcTop, ___width, ___height) +#define __ScalosGfxBlitARGB_WB(___base, ___destARGB, ___srcARGB, ___destLeft, ___destTop, ___srcLeft, ___srcTop, ___width, ___height) \ + AROS_LC8NR(VOID, ScalosGfxBlitARGB, \ + AROS_LCA(struct ARGBHeader *, (___destARGB), A0), \ + AROS_LCA(const struct ARGBHeader *, (___srcARGB), A1), \ + AROS_LCA(LONG, (___destLeft), D0), \ + AROS_LCA(LONG, (___destTop), D1), \ + AROS_LCA(LONG, (___srcLeft), D2), \ + AROS_LCA(LONG, (___srcTop), D3), \ + AROS_LCA(LONG, (___width), D4), \ + AROS_LCA(LONG, (___height), D5), \ + struct Library *, (___base), 19, Scalosgfx_lib_sfd) + +#define ScalosGfxFillRectARGB(___destARGB, ___fillARGB, ___left, ___top, ___width, ___height) __ScalosGfxFillRectARGB_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___destARGB, ___fillARGB, ___left, ___top, ___width, ___height) +#define __ScalosGfxFillRectARGB_WB(___base, ___destARGB, ___fillARGB, ___left, ___top, ___width, ___height) \ + AROS_LC6NR(VOID, ScalosGfxFillRectARGB, \ + AROS_LCA(struct ARGBHeader *, (___destARGB), A0), \ + AROS_LCA(const struct gfxARGB *, (___fillARGB), A1), \ + AROS_LCA(LONG, (___left), D0), \ + AROS_LCA(LONG, (___top), D1), \ + AROS_LCA(LONG, (___width), D2), \ + AROS_LCA(LONG, (___height), D3), \ + struct Library *, (___base), 20, Scalosgfx_lib_sfd) + +#define ScalosGfxSetARGB(___destARGB, ___fillARGB) __ScalosGfxSetARGB_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___destARGB, ___fillARGB) +#define __ScalosGfxSetARGB_WB(___base, ___destARGB, ___fillARGB) \ + AROS_LC2NR(VOID, ScalosGfxSetARGB, \ + AROS_LCA(struct ARGBHeader *, (___destARGB), A0), \ + AROS_LCA(const struct gfxARGB *, (___fillARGB), A1), \ + struct Library *, (___base), 21, Scalosgfx_lib_sfd) + +#define ScalosGfxNewColorMap(___sac, ___colorMap, ___colorEntries) __ScalosGfxNewColorMap_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___sac, ___colorMap, ___colorEntries) +#define __ScalosGfxNewColorMap_WB(___base, ___sac, ___colorMap, ___colorEntries) \ + AROS_LC3(BOOL, ScalosGfxNewColorMap, \ + AROS_LCA(struct ScalosBitMapAndColor *, (___sac), A0), \ + AROS_LCA(const ULONG *, (___colorMap), A1), \ + AROS_LCA(ULONG, (___colorEntries), D0), \ + struct Library *, (___base), 22, Scalosgfx_lib_sfd) + +#define ScalosGfxARGBRectMult(___rp, ___numerator, ___denominator, ___xMin, ___yMin, ___xMax, ___yMax) __ScalosGfxARGBRectMult_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___rp, ___numerator, ___denominator, ___xMin, ___yMin, ___xMax, ___yMax) +#define __ScalosGfxARGBRectMult_WB(___base, ___rp, ___numerator, ___denominator, ___xMin, ___yMin, ___xMax, ___yMax) \ + AROS_LC7NR(VOID, ScalosGfxARGBRectMult, \ + AROS_LCA(struct RastPort *, (___rp), A0), \ + AROS_LCA(const struct gfxARGB *, (___numerator), A1), \ + AROS_LCA(const struct gfxARGB *, (___denominator), A2), \ + AROS_LCA(WORD, (___xMin), D0), \ + AROS_LCA(WORD, (___yMin), D1), \ + AROS_LCA(WORD, (___xMax), D2), \ + AROS_LCA(WORD, (___yMax), D3), \ + struct Library *, (___base), 23, Scalosgfx_lib_sfd) + +#define ScalosGfxBlitARGBAlpha(___rp, ___srcH, ___destLeft, ___destTop, ___srcLeft, ___srcTop, ___width, ___height) __ScalosGfxBlitARGBAlpha_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___rp, ___srcH, ___destLeft, ___destTop, ___srcLeft, ___srcTop, ___width, ___height) +#define __ScalosGfxBlitARGBAlpha_WB(___base, ___rp, ___srcH, ___destLeft, ___destTop, ___srcLeft, ___srcTop, ___width, ___height) \ + AROS_LC8NR(VOID, ScalosGfxBlitARGBAlpha, \ + AROS_LCA(struct RastPort *, (___rp), A0), \ + AROS_LCA(const struct ARGBHeader *, (___srcH), A1), \ + AROS_LCA(ULONG, (___destLeft), D0), \ + AROS_LCA(ULONG, (___destTop), D1), \ + AROS_LCA(ULONG, (___srcLeft), D2), \ + AROS_LCA(ULONG, (___srcTop), D3), \ + AROS_LCA(ULONG, (___width), D4), \ + AROS_LCA(ULONG, (___height), D5), \ + struct Library *, (___base), 24, Scalosgfx_lib_sfd) + +#define ScalosGfxBlitARGBAlphaTagList(___rp, ___srcH, ___destLeft, ___destTop, ___srcSize, ___tagList) __ScalosGfxBlitARGBAlphaTagList_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___rp, ___srcH, ___destLeft, ___destTop, ___srcSize, ___tagList) +#define __ScalosGfxBlitARGBAlphaTagList_WB(___base, ___rp, ___srcH, ___destLeft, ___destTop, ___srcSize, ___tagList) \ + AROS_LC6NR(VOID, ScalosGfxBlitARGBAlphaTagList, \ + AROS_LCA(struct RastPort *, (___rp), A0), \ + AROS_LCA(const struct ARGBHeader *, (___srcH), A1), \ + AROS_LCA(ULONG, (___destLeft), D0), \ + AROS_LCA(ULONG, (___destTop), D1), \ + AROS_LCA(const struct IBox *, (___srcSize), A3), \ + AROS_LCA(struct TagItem *, (___tagList), A2), \ + struct Library *, (___base), 25, Scalosgfx_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define ScalosGfxBlitARGBAlphaTags(___rp, ___srcH, ___destLeft, ___destTop, ___srcSize, ___firstTag, ...) __ScalosGfxBlitARGBAlphaTags_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___rp, ___srcH, ___destLeft, ___destTop, ___srcSize, ___firstTag, ## __VA_ARGS__) +#define __ScalosGfxBlitARGBAlphaTags_WB(___base, ___rp, ___srcH, ___destLeft, ___destTop, ___srcSize, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __ScalosGfxBlitARGBAlphaTagList_WB((___base), (___rp), (___srcH), (___destLeft), (___destTop), (___srcSize), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define ScalosGfxBlitIcon(___rpBackground, ___rpIcon, ___left, ___top, ___width, ___height, ___tagList) __ScalosGfxBlitIcon_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___rpBackground, ___rpIcon, ___left, ___top, ___width, ___height, ___tagList) +#define __ScalosGfxBlitIcon_WB(___base, ___rpBackground, ___rpIcon, ___left, ___top, ___width, ___height, ___tagList) \ + AROS_LC7NR(VOID, ScalosGfxBlitIcon, \ + AROS_LCA(struct RastPort *, (___rpBackground), A0), \ + AROS_LCA(struct RastPort *, (___rpIcon), A1), \ + AROS_LCA(ULONG, (___left), D0), \ + AROS_LCA(ULONG, (___top), D1), \ + AROS_LCA(ULONG, (___width), D2), \ + AROS_LCA(ULONG, (___height), D3), \ + AROS_LCA(struct TagItem *, (___tagList), A2), \ + struct Library *, (___base), 26, Scalosgfx_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define ScalosGfxBlitIconTags(___rpBackground, ___rpIcon, ___left, ___top, ___width, ___height, ___firstTag, ...) __ScalosGfxBlitIconTags_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___rpBackground, ___rpIcon, ___left, ___top, ___width, ___height, ___firstTag, ## __VA_ARGS__) +#define __ScalosGfxBlitIconTags_WB(___base, ___rpBackground, ___rpIcon, ___left, ___top, ___width, ___height, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __ScalosGfxBlitIcon_WB((___base), (___rpBackground), (___rpIcon), (___left), (___top), (___width), (___height), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define ScalosGfxDrawGradient(___dest, ___left, ___top, ___width, ___height, ___start, ___stop, ___gradType) __ScalosGfxDrawGradient_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___dest, ___left, ___top, ___width, ___height, ___start, ___stop, ___gradType) +#define __ScalosGfxDrawGradient_WB(___base, ___dest, ___left, ___top, ___width, ___height, ___start, ___stop, ___gradType) \ + AROS_LC8(BOOL, ScalosGfxDrawGradient, \ + AROS_LCA(struct ARGBHeader *, (___dest), A0), \ + AROS_LCA(LONG, (___left), D0), \ + AROS_LCA(LONG, (___top), D1), \ + AROS_LCA(LONG, (___width), D2), \ + AROS_LCA(LONG, (___height), D3), \ + AROS_LCA(struct gfxARGB *, (___start), A1), \ + AROS_LCA(struct gfxARGB *, (___stop), A2), \ + AROS_LCA(ULONG, (___gradType), D4), \ + struct Library *, (___base), 27, Scalosgfx_lib_sfd) + +#define ScalosGfxDrawGradientRastPort(___rp, ___left, ___top, ___width, ___height, ___start, ___stop, ___gradType) __ScalosGfxDrawGradientRastPort_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___rp, ___left, ___top, ___width, ___height, ___start, ___stop, ___gradType) +#define __ScalosGfxDrawGradientRastPort_WB(___base, ___rp, ___left, ___top, ___width, ___height, ___start, ___stop, ___gradType) \ + AROS_LC8(BOOL, ScalosGfxDrawGradientRastPort, \ + AROS_LCA(struct RastPort *, (___rp), A0), \ + AROS_LCA(LONG, (___left), D0), \ + AROS_LCA(LONG, (___top), D1), \ + AROS_LCA(LONG, (___width), D2), \ + AROS_LCA(LONG, (___height), D3), \ + AROS_LCA(struct gfxARGB *, (___start), A1), \ + AROS_LCA(struct gfxARGB *, (___stop), A2), \ + AROS_LCA(ULONG, (___gradType), D4), \ + struct Library *, (___base), 28, Scalosgfx_lib_sfd) + +#define ScalosGfxDrawLine(___dest, ___fromX, ___fromY, ___toX, ___toY, ___lineColor) __ScalosGfxDrawLine_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___dest, ___fromX, ___fromY, ___toX, ___toY, ___lineColor) +#define __ScalosGfxDrawLine_WB(___base, ___dest, ___fromX, ___fromY, ___toX, ___toY, ___lineColor) \ + AROS_LC6NR(VOID, ScalosGfxDrawLine, \ + AROS_LCA(struct ARGBHeader *, (___dest), A0), \ + AROS_LCA(LONG, (___fromX), D0), \ + AROS_LCA(LONG, (___fromY), D1), \ + AROS_LCA(LONG, (___toX), D2), \ + AROS_LCA(LONG, (___toY), D3), \ + AROS_LCA(const struct gfxARGB *, (___lineColor), A1), \ + struct Library *, (___base), 29, Scalosgfx_lib_sfd) + +#define ScalosGfxDrawLineRastPort(___rp, ___fromX, ___fromY, ___toX, ___toY, ___lineColor) __ScalosGfxDrawLineRastPort_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___rp, ___fromX, ___fromY, ___toX, ___toY, ___lineColor) +#define __ScalosGfxDrawLineRastPort_WB(___base, ___rp, ___fromX, ___fromY, ___toX, ___toY, ___lineColor) \ + AROS_LC6NR(VOID, ScalosGfxDrawLineRastPort, \ + AROS_LCA(struct RastPort *, (___rp), A0), \ + AROS_LCA(LONG, (___fromX), D0), \ + AROS_LCA(LONG, (___fromY), D1), \ + AROS_LCA(LONG, (___toX), D2), \ + AROS_LCA(LONG, (___toY), D3), \ + AROS_LCA(const struct gfxARGB *, (___lineColor), A1), \ + struct Library *, (___base), 30, Scalosgfx_lib_sfd) + +#define ScalosGfxDrawEllipse(___dest, ___xCenter, ___yCenter, ___radiusX, ___radiusy, ___segment, ___color1, ___color2) __ScalosGfxDrawEllipse_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___dest, ___xCenter, ___yCenter, ___radiusX, ___radiusy, ___segment, ___color1, ___color2) +#define __ScalosGfxDrawEllipse_WB(___base, ___dest, ___xCenter, ___yCenter, ___radiusX, ___radiusy, ___segment, ___color1, ___color2) \ + AROS_LC8NR(VOID, ScalosGfxDrawEllipse, \ + AROS_LCA(struct ARGBHeader *, (___dest), A0), \ + AROS_LCA(LONG, (___xCenter), D0), \ + AROS_LCA(LONG, (___yCenter), D1), \ + AROS_LCA(LONG, (___radiusX), D2), \ + AROS_LCA(LONG, (___radiusy), D3), \ + AROS_LCA(WORD, (___segment), D4), \ + AROS_LCA(const struct gfxARGB *, (___color1), A1), \ + AROS_LCA(const struct gfxARGB *, (___color2), A2), \ + struct Library *, (___base), 31, Scalosgfx_lib_sfd) + +#define ScalosGfxDrawEllipseRastPort(___rp, ___xCenter, ___yCenter, ___radiusX, ___radiusy, ___segment, ___color1, ___color2) __ScalosGfxDrawEllipseRastPort_WB(SCALOSGFX_LIB_SFD_BASE_NAME, ___rp, ___xCenter, ___yCenter, ___radiusX, ___radiusy, ___segment, ___color1, ___color2) +#define __ScalosGfxDrawEllipseRastPort_WB(___base, ___rp, ___xCenter, ___yCenter, ___radiusX, ___radiusy, ___segment, ___color1, ___color2) \ + AROS_LC8NR(VOID, ScalosGfxDrawEllipseRastPort, \ + AROS_LCA(struct RastPort *, (___rp), A0), \ + AROS_LCA(LONG, (___xCenter), D0), \ + AROS_LCA(LONG, (___yCenter), D1), \ + AROS_LCA(LONG, (___radiusX), D2), \ + AROS_LCA(LONG, (___radiusy), D3), \ + AROS_LCA(WORD, (___segment), D4), \ + AROS_LCA(const struct gfxARGB *, (___color1), A1), \ + AROS_LCA(const struct gfxARGB *, (___color2), A2), \ + struct Library *, (___base), 32, Scalosgfx_lib_sfd) + +#endif /* !_INLINE_SCALOSGFX_LIB_SFD_H */ diff --git a/scalos/include/defines/scalosmenuplugin.h b/scalos/include/defines/scalosmenuplugin.h new file mode 100644 index 000000000..0a7454b45 --- /dev/null +++ b/scalos/include/defines/scalosmenuplugin.h @@ -0,0 +1,21 @@ +/* Automatically generated header! Do not edit! */ + +#ifndef _INLINE_SCALOSMENUPLUGIN_LIB_SFD_H +#define _INLINE_SCALOSMENUPLUGIN_LIB_SFD_H + +#ifndef AROS_LIBCALL_H +#include +#endif /* !AROS_LIBCALL_H */ + +#ifndef SCALOSMENUPLUGIN_LIB_SFD_BASE_NAME +#define SCALOSMENUPLUGIN_LIB_SFD_BASE_NAME ScalosMenuPluginBase +#endif /* !SCALOSMENUPLUGIN_LIB_SFD_BASE_NAME */ + +#define SCAMenuFunction(___wt, ___in) __SCAMenuFunction_WB(SCALOSMENUPLUGIN_LIB_SFD_BASE_NAME, ___wt, ___in) +#define __SCAMenuFunction_WB(___base, ___wt, ___in) \ + AROS_LC2NR(VOID, SCAMenuFunction, \ + AROS_LCA(struct ScaWindowTask *, (___wt), A0), \ + AROS_LCA(struct ScaIconNode *, (___in), A1), \ + struct Library *, (___base), 5, Scalosmenuplugin_lib_sfd) + +#endif /* !_INLINE_SCALOSMENUPLUGIN_LIB_SFD_H */ diff --git a/scalos/include/defines/scalosplugin.h b/scalos/include/defines/scalosplugin.h new file mode 100644 index 000000000..e6b371ffc --- /dev/null +++ b/scalos/include/defines/scalosplugin.h @@ -0,0 +1,19 @@ +/* Automatically generated header! Do not edit! */ + +#ifndef _INLINE_SCALOSPLUGIN_LIB_SFD_H +#define _INLINE_SCALOSPLUGIN_LIB_SFD_H + +#ifndef AROS_LIBCALL_H +#include +#endif /* !AROS_LIBCALL_H */ + +#ifndef SCALOSPLUGIN_LIB_SFD_BASE_NAME +#define SCALOSPLUGIN_LIB_SFD_BASE_NAME ScalosPluginBase +#endif /* !SCALOSPLUGIN_LIB_SFD_BASE_NAME */ + +#define SCAGetClassInfo() __SCAGetClassInfo_WB(SCALOSPLUGIN_LIB_SFD_BASE_NAME) +#define __SCAGetClassInfo_WB(___base) \ + AROS_LC0(const struct ScaClassInfo *, SCAGetClassInfo, \ + struct Library *, (___base), 5, Scalosplugin_lib_sfd) + +#endif /* !_INLINE_SCALOSPLUGIN_LIB_SFD_H */ diff --git a/scalos/include/defines/scalosprefsplugin.h b/scalos/include/defines/scalosprefsplugin.h new file mode 100644 index 000000000..5f4a592c9 --- /dev/null +++ b/scalos/include/defines/scalosprefsplugin.h @@ -0,0 +1,20 @@ +/* Automatically generated header! Do not edit! */ + +#ifndef _INLINE_SCALOSPREFSPLUGIN_LIB_SFD_H +#define _INLINE_SCALOSPREFSPLUGIN_LIB_SFD_H + +#ifndef AROS_LIBCALL_H +#include +#endif /* !AROS_LIBCALL_H */ + +#ifndef SCALOSPREFSPLUGIN_LIB_SFD_BASE_NAME +#define SCALOSPREFSPLUGIN_LIB_SFD_BASE_NAME ScalosPrefsPluginBase +#endif /* !SCALOSPREFSPLUGIN_LIB_SFD_BASE_NAME */ + +#define SCAGetPrefsInfo(___which) __SCAGetPrefsInfo_WB(SCALOSPREFSPLUGIN_LIB_SFD_BASE_NAME, ___which) +#define __SCAGetPrefsInfo_WB(___base, ___which) \ + AROS_LC1(ULONG, SCAGetPrefsInfo, \ + AROS_LCA(LONG, (___which), D0), \ + struct Library *, (___base), 5, Scalosprefsplugin_lib_sfd) + +#endif /* !_INLINE_SCALOSPREFSPLUGIN_LIB_SFD_H */ diff --git a/scalos/include/defines/scalospreviewplugin.h b/scalos/include/defines/scalospreviewplugin.h new file mode 100644 index 000000000..3e272b13c --- /dev/null +++ b/scalos/include/defines/scalospreviewplugin.h @@ -0,0 +1,29 @@ +/* Automatically generated header! Do not edit! */ + +#ifndef _INLINE_SCALOSPREVIEWPLUGIN_LIB_SFD_H +#define _INLINE_SCALOSPREVIEWPLUGIN_LIB_SFD_H + +#ifndef AROS_LIBCALL_H +#include +#endif /* !AROS_LIBCALL_H */ + +#ifndef SCALOSPREVIEWPLUGIN_LIB_SFD_BASE_NAME +#define SCALOSPREVIEWPLUGIN_LIB_SFD_BASE_NAME ScalosPreviewPluginBase +#endif /* !SCALOSPREVIEWPLUGIN_LIB_SFD_BASE_NAME */ + +#define SCAPreviewGenerate(___wt, ___dirLock, ___iconName, ___tagList) __SCAPreviewGenerate_WB(SCALOSPREVIEWPLUGIN_LIB_SFD_BASE_NAME, ___wt, ___dirLock, ___iconName, ___tagList) +#define __SCAPreviewGenerate_WB(___base, ___wt, ___dirLock, ___iconName, ___tagList) \ + AROS_LC4(LONG, SCAPreviewGenerate, \ + AROS_LCA(struct ScaWindowTask *, (___wt), A0), \ + AROS_LCA(BPTR, (___dirLock), A1), \ + AROS_LCA(CONST_STRPTR, (___iconName), A2), \ + AROS_LCA(struct TagItem *, (___tagList), A3), \ + struct Library *, (___base), 5, Scalospreviewplugin_lib_sfd) + +#ifndef NO_INLINE_STDARG +#define SCAPreviewGenerateTags(___wt, ___dirLock, ___iconName, ___firstTag, ...) __SCAPreviewGenerateTags_WB(SCALOSPREVIEWPLUGIN_LIB_SFD_BASE_NAME, ___wt, ___dirLock, ___iconName, ___firstTag, ## __VA_ARGS__) +#define __SCAPreviewGenerateTags_WB(___base, ___wt, ___dirLock, ___iconName, ___firstTag, ...) \ + ({IPTR _tags[] = { (IPTR) ___firstTag, ## __VA_ARGS__ }; __SCAPreviewGenerate_WB((___base), (___wt), (___dirLock), (___iconName), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#endif /* !_INLINE_SCALOSPREVIEWPLUGIN_LIB_SFD_H */ diff --git a/scalos/include/defines/sqlite3.h b/scalos/include/defines/sqlite3.h new file mode 100644 index 000000000..f1eb6f7ca --- /dev/null +++ b/scalos/include/defines/sqlite3.h @@ -0,0 +1,736 @@ +/* Automatically generated header! Do not edit! */ + +#ifndef _INLINE_SQLITE3_LIB_SFD_H +#define _INLINE_SQLITE3_LIB_SFD_H + +#ifndef AROS_LIBCALL_H +#include +#endif /* !AROS_LIBCALL_H */ + +#ifndef SQLITE3_LIB_SFD_BASE_NAME +#define SQLITE3_LIB_SFD_BASE_NAME SQLite3Base +#endif /* !SQLITE3_LIB_SFD_BASE_NAME */ + +#define SQLite3Close(___db) __SQLite3Close_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db) +#define __SQLite3Close_WB(___base, ___db) \ + AROS_LC1(LONG, SQLite3Close, \ + AROS_LCA(sqlite3 *, (___db), A0), \ + struct Library *, (___base), 5, Sqlite3_lib_sfd) + +#define SQLite3Exec(___db, ___sql, ___xCallback, ___pArg, ___errmsg) __SQLite3Exec_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db, ___sql, ___xCallback, ___pArg, ___errmsg) +#define __SQLite3Exec_WB(___base, ___db, ___sql, ___xCallback, ___pArg, ___errmsg) \ + AROS_LC5(LONG, SQLite3Exec, \ + AROS_LCA(sqlite3 *, (___db), A0), \ + AROS_LCA(CONST_STRPTR, (___sql), A1), \ + AROS_LCA(sqlite3_callback, (___xCallback), A2), \ + AROS_LCA(APTR, (___pArg), A3), \ + AROS_LCA(STRPTR *, (___errmsg), D0), \ + struct Library *, (___base), 6, Sqlite3_lib_sfd) + +#define SQLite3Changes(___db) __SQLite3Changes_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db) +#define __SQLite3Changes_WB(___base, ___db) \ + AROS_LC1(LONG, SQLite3Changes, \ + AROS_LCA(sqlite3 *, (___db), A0), \ + struct Library *, (___base), 7, Sqlite3_lib_sfd) + +#define SQLite3TotalChanges(___db) __SQLite3TotalChanges_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db) +#define __SQLite3TotalChanges_WB(___base, ___db) \ + AROS_LC1(LONG, SQLite3TotalChanges, \ + AROS_LCA(sqlite3 *, (___db), A0), \ + struct Library *, (___base), 8, Sqlite3_lib_sfd) + +#define SQLite3Interrupt(___db) __SQLite3Interrupt_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db) +#define __SQLite3Interrupt_WB(___base, ___db) \ + AROS_LC1NR(VOID, SQLite3Interrupt, \ + AROS_LCA(sqlite3 *, (___db), A0), \ + struct Library *, (___base), 9, Sqlite3_lib_sfd) + +#define SQLite3Complete(___sql) __SQLite3Complete_WB(SQLITE3_LIB_SFD_BASE_NAME, ___sql) +#define __SQLite3Complete_WB(___base, ___sql) \ + AROS_LC1(LONG, SQLite3Complete, \ + AROS_LCA(CONST_STRPTR, (___sql), A0), \ + struct Library *, (___base), 10, Sqlite3_lib_sfd) + +#define SQLite3BusyHandler(___db, ___callback, ___userdata) __SQLite3BusyHandler_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db, ___callback, ___userdata) +#define __SQLite3BusyHandler_WB(___base, ___db, ___callback, ___userdata) \ + AROS_LC3(LONG, SQLite3BusyHandler, \ + AROS_LCA(sqlite3 *, (___db), A0), \ + AROS_LCA(LONG(*)(APTR userdata,LONG l), (___callback), A1), \ + AROS_LCA(APTR, (___userdata), A2), \ + struct Library *, (___base), 11, Sqlite3_lib_sfd) + +#define SQLite3BusyTimeout(___db, ___ms) __SQLite3BusyTimeout_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db, ___ms) +#define __SQLite3BusyTimeout_WB(___base, ___db, ___ms) \ + AROS_LC2(LONG, SQLite3BusyTimeout, \ + AROS_LCA(sqlite3 *, (___db), A0), \ + AROS_LCA(LONG, (___ms), D0), \ + struct Library *, (___base), 12, Sqlite3_lib_sfd) + +#define SQLite3GetTable(___db, ___sql, ___presult, ___nrow, ___ncolumn, ___errmsg) __SQLite3GetTable_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db, ___sql, ___presult, ___nrow, ___ncolumn, ___errmsg) +#define __SQLite3GetTable_WB(___base, ___db, ___sql, ___presult, ___nrow, ___ncolumn, ___errmsg) \ + AROS_LC6(LONG, SQLite3GetTable, \ + AROS_LCA(sqlite3 *, (___db), A0), \ + AROS_LCA(CONST_STRPTR, (___sql), A1), \ + AROS_LCA(STRPTR **, (___presult), A2), \ + AROS_LCA(LONG *, (___nrow), A3), \ + AROS_LCA(LONG *, (___ncolumn), D0), \ + AROS_LCA(STRPTR *, (___errmsg), D1), \ + struct Library *, (___base), 13, Sqlite3_lib_sfd) + +#define SQLite3FreeTable(___result) __SQLite3FreeTable_WB(SQLITE3_LIB_SFD_BASE_NAME, ___result) +#define __SQLite3FreeTable_WB(___base, ___result) \ + AROS_LC1NR(VOID, SQLite3FreeTable, \ + AROS_LCA(STRPTR *, (___result), A0), \ + struct Library *, (___base), 14, Sqlite3_lib_sfd) + +#define SQLite3Free(___z) __SQLite3Free_WB(SQLITE3_LIB_SFD_BASE_NAME, ___z) +#define __SQLite3Free_WB(___base, ___z) \ + AROS_LC1NR(VOID, SQLite3Free, \ + AROS_LCA(STRPTR, (___z), A0), \ + struct Library *, (___base), 15, Sqlite3_lib_sfd) + +#define SQLite3Trace(___db, ___xTrace, ___parg) __SQLite3Trace_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db, ___xTrace, ___parg) +#define __SQLite3Trace_WB(___base, ___db, ___xTrace, ___parg) \ + AROS_LC3(APTR, SQLite3Trace, \ + AROS_LCA(sqlite3 *, (___db), A0), \ + AROS_LCA(VOID (*)(APTR p,CONST_STRPTR z), (___xTrace), A1), \ + AROS_LCA(APTR, (___parg), A2), \ + struct Library *, (___base), 16, Sqlite3_lib_sfd) + +#define SQLite3ProgressHandler(___db, ___nOps, ___xProgress, ___pArg) __SQLite3ProgressHandler_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db, ___nOps, ___xProgress, ___pArg) +#define __SQLite3ProgressHandler_WB(___base, ___db, ___nOps, ___xProgress, ___pArg) \ + AROS_LC4NR(VOID, SQLite3ProgressHandler, \ + AROS_LCA(sqlite3 *, (___db), A0), \ + AROS_LCA(LONG, (___nOps), D0), \ + AROS_LCA(LONG (*)(APTR p), (___xProgress), A1), \ + AROS_LCA(APTR, (___pArg), A2), \ + struct Library *, (___base), 17, Sqlite3_lib_sfd) + +#define SQLite3CommitHook(___db, ___xCallback, ___pArg) __SQLite3CommitHook_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db, ___xCallback, ___pArg) +#define __SQLite3CommitHook_WB(___base, ___db, ___xCallback, ___pArg) \ + AROS_LC3(APTR, SQLite3CommitHook, \ + AROS_LCA(sqlite3 *, (___db), A0), \ + AROS_LCA(LONG (*)(APTR p), (___xCallback), A1), \ + AROS_LCA(APTR, (___pArg), A2), \ + struct Library *, (___base), 18, Sqlite3_lib_sfd) + +#define SQLite3Open(___filename, ___ppDb) __SQLite3Open_WB(SQLITE3_LIB_SFD_BASE_NAME, ___filename, ___ppDb) +#define __SQLite3Open_WB(___base, ___filename, ___ppDb) \ + AROS_LC2(LONG, SQLite3Open, \ + AROS_LCA(CONST_STRPTR, (___filename), A0), \ + AROS_LCA(sqlite3 **, (___ppDb), A1), \ + struct Library *, (___base), 19, Sqlite3_lib_sfd) + +#define SQLite3Errcode(___db) __SQLite3Errcode_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db) +#define __SQLite3Errcode_WB(___base, ___db) \ + AROS_LC1(LONG, SQLite3Errcode, \ + AROS_LCA(sqlite3 *, (___db), A0), \ + struct Library *, (___base), 20, Sqlite3_lib_sfd) + +#define SQLite3Errmsg(___db) __SQLite3Errmsg_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db) +#define __SQLite3Errmsg_WB(___base, ___db) \ + AROS_LC1(CONST_STRPTR, SQLite3Errmsg, \ + AROS_LCA(sqlite3 *, (___db), A0), \ + struct Library *, (___base), 21, Sqlite3_lib_sfd) + +#define SQLite3Prepare(___db, ___zSql, ___nBytes, ___ppStmt, ___pzTail) __SQLite3Prepare_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db, ___zSql, ___nBytes, ___ppStmt, ___pzTail) +#define __SQLite3Prepare_WB(___base, ___db, ___zSql, ___nBytes, ___ppStmt, ___pzTail) \ + AROS_LC5(LONG, SQLite3Prepare, \ + AROS_LCA(sqlite3 *, (___db), A0), \ + AROS_LCA(CONST_STRPTR, (___zSql), A1), \ + AROS_LCA(LONG, (___nBytes), D0), \ + AROS_LCA(sqlite3_stmt **, (___ppStmt), A2), \ + AROS_LCA(CONST_STRPTR *, (___pzTail), A3), \ + struct Library *, (___base), 22, Sqlite3_lib_sfd) + +#define SQLite3BindBlob(___pStmt, ___i, ___zData, ___nData, ___xDel) __SQLite3BindBlob_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pStmt, ___i, ___zData, ___nData, ___xDel) +#define __SQLite3BindBlob_WB(___base, ___pStmt, ___i, ___zData, ___nData, ___xDel) \ + AROS_LC5(LONG, SQLite3BindBlob, \ + AROS_LCA(sqlite3_stmt *, (___pStmt), A0), \ + AROS_LCA(LONG, (___i), D0), \ + AROS_LCA(CONST_APTR, (___zData), A1), \ + AROS_LCA(LONG, (___nData), D1), \ + AROS_LCA(VOID (*)(APTR p), (___xDel), A2), \ + struct Library *, (___base), 23, Sqlite3_lib_sfd) + +#define SQLite3BindInt(___pStmt, ___i, ___iValue) __SQLite3BindInt_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pStmt, ___i, ___iValue) +#define __SQLite3BindInt_WB(___base, ___pStmt, ___i, ___iValue) \ + AROS_LC3(LONG, SQLite3BindInt, \ + AROS_LCA(sqlite3_stmt *, (___pStmt), A0), \ + AROS_LCA(LONG, (___i), D0), \ + AROS_LCA(LONG, (___iValue), D1), \ + struct Library *, (___base), 24, Sqlite3_lib_sfd) + +#define SQLite3BindNull(___pStmt, ___i) __SQLite3BindNull_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pStmt, ___i) +#define __SQLite3BindNull_WB(___base, ___pStmt, ___i) \ + AROS_LC2(LONG, SQLite3BindNull, \ + AROS_LCA(sqlite3_stmt *, (___pStmt), A0), \ + AROS_LCA(LONG, (___i), D0), \ + struct Library *, (___base), 25, Sqlite3_lib_sfd) + +#define SQLite3BindText(___pStmt, ___i, ___zData, ___nData, ___xDel) __SQLite3BindText_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pStmt, ___i, ___zData, ___nData, ___xDel) +#define __SQLite3BindText_WB(___base, ___pStmt, ___i, ___zData, ___nData, ___xDel) \ + AROS_LC5(LONG, SQLite3BindText, \ + AROS_LCA(sqlite3_stmt *, (___pStmt), A0), \ + AROS_LCA(LONG, (___i), D0), \ + AROS_LCA(CONST_STRPTR, (___zData), A1), \ + AROS_LCA(LONG, (___nData), D1), \ + AROS_LCA(VOID (*)(APTR p), (___xDel), A2), \ + struct Library *, (___base), 26, Sqlite3_lib_sfd) + +#define SQLite3BindValue(___pStmt, ___i, ___pVal) __SQLite3BindValue_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pStmt, ___i, ___pVal) +#define __SQLite3BindValue_WB(___base, ___pStmt, ___i, ___pVal) \ + AROS_LC3(LONG, SQLite3BindValue, \ + AROS_LCA(sqlite3_stmt *, (___pStmt), A0), \ + AROS_LCA(LONG, (___i), D0), \ + AROS_LCA(CONST sqlite3_value *, (___pVal), A1), \ + struct Library *, (___base), 27, Sqlite3_lib_sfd) + +#define SQLite3BindParameterCount(___pStmt) __SQLite3BindParameterCount_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pStmt) +#define __SQLite3BindParameterCount_WB(___base, ___pStmt) \ + AROS_LC1(LONG, SQLite3BindParameterCount, \ + AROS_LCA(sqlite3_stmt *, (___pStmt), A0), \ + struct Library *, (___base), 28, Sqlite3_lib_sfd) + +#define SQLite3BindParameterName(___pStmt, ___i) __SQLite3BindParameterName_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pStmt, ___i) +#define __SQLite3BindParameterName_WB(___base, ___pStmt, ___i) \ + AROS_LC2(CONST_STRPTR, SQLite3BindParameterName, \ + AROS_LCA(sqlite3_stmt *, (___pStmt), A0), \ + AROS_LCA(LONG, (___i), D0), \ + struct Library *, (___base), 29, Sqlite3_lib_sfd) + +#define SQLite3BindParameterIndex(___pStmt, ___zName) __SQLite3BindParameterIndex_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pStmt, ___zName) +#define __SQLite3BindParameterIndex_WB(___base, ___pStmt, ___zName) \ + AROS_LC2(LONG, SQLite3BindParameterIndex, \ + AROS_LCA(sqlite3_stmt *, (___pStmt), A0), \ + AROS_LCA(CONST_STRPTR, (___zName), A1), \ + struct Library *, (___base), 30, Sqlite3_lib_sfd) + +#define SQLite3ClearBindings(___pStmt) __SQLite3ClearBindings_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pStmt) +#define __SQLite3ClearBindings_WB(___base, ___pStmt) \ + AROS_LC1(LONG, SQLite3ClearBindings, \ + AROS_LCA(sqlite3_stmt *, (___pStmt), A0), \ + struct Library *, (___base), 31, Sqlite3_lib_sfd) + +#define SQLite3ColumnCount(___pStmt) __SQLite3ColumnCount_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pStmt) +#define __SQLite3ColumnCount_WB(___base, ___pStmt) \ + AROS_LC1(LONG, SQLite3ColumnCount, \ + AROS_LCA(sqlite3_stmt *, (___pStmt), A0), \ + struct Library *, (___base), 32, Sqlite3_lib_sfd) + +#define SQLite3ColumnName(___pStmt, ___i) __SQLite3ColumnName_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pStmt, ___i) +#define __SQLite3ColumnName_WB(___base, ___pStmt, ___i) \ + AROS_LC2(CONST_STRPTR, SQLite3ColumnName, \ + AROS_LCA(sqlite3_stmt *, (___pStmt), A0), \ + AROS_LCA(LONG, (___i), D0), \ + struct Library *, (___base), 33, Sqlite3_lib_sfd) + +#define SQLite3ColumnDecltype(___pStmt, ___i) __SQLite3ColumnDecltype_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pStmt, ___i) +#define __SQLite3ColumnDecltype_WB(___base, ___pStmt, ___i) \ + AROS_LC2(CONST_STRPTR, SQLite3ColumnDecltype, \ + AROS_LCA(sqlite3_stmt *, (___pStmt), A0), \ + AROS_LCA(LONG, (___i), D0), \ + struct Library *, (___base), 34, Sqlite3_lib_sfd) + +#define SQLite3Step(___pStmt) __SQLite3Step_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pStmt) +#define __SQLite3Step_WB(___base, ___pStmt) \ + AROS_LC1(LONG, SQLite3Step, \ + AROS_LCA(sqlite3_stmt *, (___pStmt), A0), \ + struct Library *, (___base), 35, Sqlite3_lib_sfd) + +#define SQLite3DataCount(___pStmt) __SQLite3DataCount_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pStmt) +#define __SQLite3DataCount_WB(___base, ___pStmt) \ + AROS_LC1(LONG, SQLite3DataCount, \ + AROS_LCA(sqlite3_stmt *, (___pStmt), A0), \ + struct Library *, (___base), 36, Sqlite3_lib_sfd) + +#define SQLite3ColumnBlob(___pStmt, ___iCol) __SQLite3ColumnBlob_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pStmt, ___iCol) +#define __SQLite3ColumnBlob_WB(___base, ___pStmt, ___iCol) \ + AROS_LC2(CONST_APTR, SQLite3ColumnBlob, \ + AROS_LCA(sqlite3_stmt *, (___pStmt), A0), \ + AROS_LCA(LONG, (___iCol), D0), \ + struct Library *, (___base), 37, Sqlite3_lib_sfd) + +#define SQLite3ColumnBytes(___pStmt, ___iCol) __SQLite3ColumnBytes_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pStmt, ___iCol) +#define __SQLite3ColumnBytes_WB(___base, ___pStmt, ___iCol) \ + AROS_LC2(LONG, SQLite3ColumnBytes, \ + AROS_LCA(sqlite3_stmt *, (___pStmt), A0), \ + AROS_LCA(LONG, (___iCol), D0), \ + struct Library *, (___base), 38, Sqlite3_lib_sfd) + +#define SQLite3ColumnInt(___pStmt, ___iCol) __SQLite3ColumnInt_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pStmt, ___iCol) +#define __SQLite3ColumnInt_WB(___base, ___pStmt, ___iCol) \ + AROS_LC2(LONG, SQLite3ColumnInt, \ + AROS_LCA(sqlite3_stmt *, (___pStmt), A0), \ + AROS_LCA(LONG, (___iCol), D0), \ + struct Library *, (___base), 39, Sqlite3_lib_sfd) + +#define SQLite3ColumnText(___pStmt, ___iCol) __SQLite3ColumnText_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pStmt, ___iCol) +#define __SQLite3ColumnText_WB(___base, ___pStmt, ___iCol) \ + AROS_LC2(CONST_STRPTR, SQLite3ColumnText, \ + AROS_LCA(sqlite3_stmt *, (___pStmt), A0), \ + AROS_LCA(LONG, (___iCol), D0), \ + struct Library *, (___base), 40, Sqlite3_lib_sfd) + +#define SQLite3ColumnType(___pStmt, ___iCol) __SQLite3ColumnType_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pStmt, ___iCol) +#define __SQLite3ColumnType_WB(___base, ___pStmt, ___iCol) \ + AROS_LC2(LONG, SQLite3ColumnType, \ + AROS_LCA(sqlite3_stmt *, (___pStmt), A0), \ + AROS_LCA(LONG, (___iCol), D0), \ + struct Library *, (___base), 41, Sqlite3_lib_sfd) + +#define SQLite3Finalize(___pStmt) __SQLite3Finalize_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pStmt) +#define __SQLite3Finalize_WB(___base, ___pStmt) \ + AROS_LC1(LONG, SQLite3Finalize, \ + AROS_LCA(sqlite3_stmt *, (___pStmt), A0), \ + struct Library *, (___base), 42, Sqlite3_lib_sfd) + +#define SQLite3Reset(___pStmt) __SQLite3Reset_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pStmt) +#define __SQLite3Reset_WB(___base, ___pStmt) \ + AROS_LC1(LONG, SQLite3Reset, \ + AROS_LCA(sqlite3_stmt *, (___pStmt), A0), \ + struct Library *, (___base), 43, Sqlite3_lib_sfd) + +#define SQLite3AggregateCount(___pCtx) __SQLite3AggregateCount_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pCtx) +#define __SQLite3AggregateCount_WB(___base, ___pCtx) \ + AROS_LC1(LONG, SQLite3AggregateCount, \ + AROS_LCA(sqlite3_context *, (___pCtx), A0), \ + struct Library *, (___base), 44, Sqlite3_lib_sfd) + +#define SQLite3ValueBlob(___pVal) __SQLite3ValueBlob_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pVal) +#define __SQLite3ValueBlob_WB(___base, ___pVal) \ + AROS_LC1(CONST_APTR, SQLite3ValueBlob, \ + AROS_LCA(sqlite3_value *, (___pVal), A0), \ + struct Library *, (___base), 45, Sqlite3_lib_sfd) + +#define SQLite3ValueBytes(___pVal) __SQLite3ValueBytes_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pVal) +#define __SQLite3ValueBytes_WB(___base, ___pVal) \ + AROS_LC1(LONG, SQLite3ValueBytes, \ + AROS_LCA(sqlite3_value *, (___pVal), A0), \ + struct Library *, (___base), 46, Sqlite3_lib_sfd) + +#define SQLite3ValueInt(___pVal) __SQLite3ValueInt_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pVal) +#define __SQLite3ValueInt_WB(___base, ___pVal) \ + AROS_LC1(LONG, SQLite3ValueInt, \ + AROS_LCA(sqlite3_value *, (___pVal), A0), \ + struct Library *, (___base), 47, Sqlite3_lib_sfd) + +#define SQLite3ValueText(___pVal) __SQLite3ValueText_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pVal) +#define __SQLite3ValueText_WB(___base, ___pVal) \ + AROS_LC1(CONST_STRPTR, SQLite3ValueText, \ + AROS_LCA(sqlite3_value *, (___pVal), A0), \ + struct Library *, (___base), 48, Sqlite3_lib_sfd) + +#define SQLite3ValueType(___pVal) __SQLite3ValueType_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pVal) +#define __SQLite3ValueType_WB(___base, ___pVal) \ + AROS_LC1(LONG, SQLite3ValueType, \ + AROS_LCA(sqlite3_value *, (___pVal), A0), \ + struct Library *, (___base), 49, Sqlite3_lib_sfd) + +#define SQLite3Aggregate_context(___pCtx, ___nBytes) __SQLite3Aggregate_context_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pCtx, ___nBytes) +#define __SQLite3Aggregate_context_WB(___base, ___pCtx, ___nBytes) \ + AROS_LC2(APTR, SQLite3Aggregate_context, \ + AROS_LCA(sqlite3_context *, (___pCtx), A0), \ + AROS_LCA(LONG, (___nBytes), D0), \ + struct Library *, (___base), 50, Sqlite3_lib_sfd) + +#define SQLite3UserData(___pCtx) __SQLite3UserData_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pCtx) +#define __SQLite3UserData_WB(___base, ___pCtx) \ + AROS_LC1(APTR, SQLite3UserData, \ + AROS_LCA(sqlite3_context *, (___pCtx), A0), \ + struct Library *, (___base), 51, Sqlite3_lib_sfd) + +#define SQLite3GetAuxdata(___pCtx, ___iArg) __SQLite3GetAuxdata_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pCtx, ___iArg) +#define __SQLite3GetAuxdata_WB(___base, ___pCtx, ___iArg) \ + AROS_LC2(APTR, SQLite3GetAuxdata, \ + AROS_LCA(sqlite3_context *, (___pCtx), A0), \ + AROS_LCA(LONG, (___iArg), D0), \ + struct Library *, (___base), 52, Sqlite3_lib_sfd) + +#define SQLite3SetAuxdata(___pCtx, ___iARg, ___pAux, ___xDelete) __SQLite3SetAuxdata_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pCtx, ___iARg, ___pAux, ___xDelete) +#define __SQLite3SetAuxdata_WB(___base, ___pCtx, ___iARg, ___pAux, ___xDelete) \ + AROS_LC4NR(VOID, SQLite3SetAuxdata, \ + AROS_LCA(sqlite3_context *, (___pCtx), A0), \ + AROS_LCA(LONG, (___iARg), D0), \ + AROS_LCA(APTR, (___pAux), A1), \ + AROS_LCA(VOID (*)(APTR p), (___xDelete), A2), \ + struct Library *, (___base), 53, Sqlite3_lib_sfd) + +#define SQLite3ResultBlob(___pCtx, ___z, ___n, ___xDelete) __SQLite3ResultBlob_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pCtx, ___z, ___n, ___xDelete) +#define __SQLite3ResultBlob_WB(___base, ___pCtx, ___z, ___n, ___xDelete) \ + AROS_LC4NR(VOID, SQLite3ResultBlob, \ + AROS_LCA(sqlite3_context *, (___pCtx), A0), \ + AROS_LCA(CONST_APTR, (___z), A1), \ + AROS_LCA(LONG, (___n), D0), \ + AROS_LCA(VOID (*)(APTR p), (___xDelete), A2), \ + struct Library *, (___base), 54, Sqlite3_lib_sfd) + +#define SQLite3ResultError(___pCtx, ___z, ___n) __SQLite3ResultError_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pCtx, ___z, ___n) +#define __SQLite3ResultError_WB(___base, ___pCtx, ___z, ___n) \ + AROS_LC3NR(VOID, SQLite3ResultError, \ + AROS_LCA(sqlite3_context *, (___pCtx), A0), \ + AROS_LCA(CONST_STRPTR, (___z), A1), \ + AROS_LCA(LONG, (___n), D0), \ + struct Library *, (___base), 55, Sqlite3_lib_sfd) + +#define SQLite3ResultInt(___pCtx, ___iVal) __SQLite3ResultInt_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pCtx, ___iVal) +#define __SQLite3ResultInt_WB(___base, ___pCtx, ___iVal) \ + AROS_LC2NR(VOID, SQLite3ResultInt, \ + AROS_LCA(sqlite3_context *, (___pCtx), A0), \ + AROS_LCA(LONG, (___iVal), D0), \ + struct Library *, (___base), 56, Sqlite3_lib_sfd) + +#define SQLite3ResultNull(___pCtx) __SQLite3ResultNull_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pCtx) +#define __SQLite3ResultNull_WB(___base, ___pCtx) \ + AROS_LC1NR(VOID, SQLite3ResultNull, \ + AROS_LCA(sqlite3_context *, (___pCtx), A0), \ + struct Library *, (___base), 57, Sqlite3_lib_sfd) + +#define SQLite3ResultText(___pCtx, ___z, ___n, ___xDelete) __SQLite3ResultText_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pCtx, ___z, ___n, ___xDelete) +#define __SQLite3ResultText_WB(___base, ___pCtx, ___z, ___n, ___xDelete) \ + AROS_LC4NR(VOID, SQLite3ResultText, \ + AROS_LCA(sqlite3_context *, (___pCtx), A0), \ + AROS_LCA(CONST_STRPTR, (___z), A1), \ + AROS_LCA(LONG, (___n), D0), \ + AROS_LCA(VOID (*)(APTR p), (___xDelete), A2), \ + struct Library *, (___base), 58, Sqlite3_lib_sfd) + +#define SQLite3ResultValue(___pCtx, ___pValue) __SQLite3ResultValue_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pCtx, ___pValue) +#define __SQLite3ResultValue_WB(___base, ___pCtx, ___pValue) \ + AROS_LC2NR(VOID, SQLite3ResultValue, \ + AROS_LCA(sqlite3_context *, (___pCtx), A0), \ + AROS_LCA(sqlite3_value *, (___pValue), A1), \ + struct Library *, (___base), 59, Sqlite3_lib_sfd) + +#define SQLite3CreateCollation(___db, ___zName, ___eTextRep, ___pCtx, ___xCompare) __SQLite3CreateCollation_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db, ___zName, ___eTextRep, ___pCtx, ___xCompare) +#define __SQLite3CreateCollation_WB(___base, ___db, ___zName, ___eTextRep, ___pCtx, ___xCompare) \ + AROS_LC5(LONG, SQLite3CreateCollation, \ + AROS_LCA(sqlite3 *, (___db), A0), \ + AROS_LCA(CONST_STRPTR, (___zName), A1), \ + AROS_LCA(LONG, (___eTextRep), D0), \ + AROS_LCA(APTR, (___pCtx), A2), \ + AROS_LCA(LONG(*)(APTR p,LONG i,CONST_APTR p2,LONG j,CONST_APTR p3), (___xCompare), A3), \ + struct Library *, (___base), 60, Sqlite3_lib_sfd) + +#define SQLite3CollationNeeded(___db, ___pCollNeededArg, ___xCollNeeded) __SQLite3CollationNeeded_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db, ___pCollNeededArg, ___xCollNeeded) +#define __SQLite3CollationNeeded_WB(___base, ___db, ___pCollNeededArg, ___xCollNeeded) \ + AROS_LC3(LONG, SQLite3CollationNeeded, \ + AROS_LCA(sqlite3 *, (___db), A0), \ + AROS_LCA(APTR, (___pCollNeededArg), D0), \ + AROS_LCA(VOID (*)(APTR p,sqlite3 *dv,LONG eTextRep,CONST_STRPTR z), (___xCollNeeded), A1), \ + struct Library *, (___base), 61, Sqlite3_lib_sfd) + +#define SQLite3Sleep(___ms) __SQLite3Sleep_WB(SQLITE3_LIB_SFD_BASE_NAME, ___ms) +#define __SQLite3Sleep_WB(___base, ___ms) \ + AROS_LC1(LONG, SQLite3Sleep, \ + AROS_LCA(LONG, (___ms), D0), \ + struct Library *, (___base), 62, Sqlite3_lib_sfd) + +#define SQLite3Expired(___pStmt) __SQLite3Expired_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pStmt) +#define __SQLite3Expired_WB(___base, ___pStmt) \ + AROS_LC1(LONG, SQLite3Expired, \ + AROS_LCA(sqlite3_stmt *, (___pStmt), A0), \ + struct Library *, (___base), 63, Sqlite3_lib_sfd) + +#define SQLite3TransferBindings(___pFromStmt, ___pToStmt) __SQLite3TransferBindings_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pFromStmt, ___pToStmt) +#define __SQLite3TransferBindings_WB(___base, ___pFromStmt, ___pToStmt) \ + AROS_LC2(LONG, SQLite3TransferBindings, \ + AROS_LCA(sqlite3_stmt *, (___pFromStmt), A0), \ + AROS_LCA(sqlite3_stmt *, (___pToStmt), A1), \ + struct Library *, (___base), 64, Sqlite3_lib_sfd) + +#define SQLite3GlobalRecover() __SQLite3GlobalRecover_WB(SQLITE3_LIB_SFD_BASE_NAME) +#define __SQLite3GlobalRecover_WB(___base) \ + AROS_LC0(LONG, SQLite3GlobalRecover, \ + struct Library *, (___base), 65, Sqlite3_lib_sfd) + +#define SQLite3GetAutocommit(___db) __SQLite3GetAutocommit_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db) +#define __SQLite3GetAutocommit_WB(___base, ___db) \ + AROS_LC1(LONG, SQLite3GetAutocommit, \ + AROS_LCA(sqlite3 *, (___db), A0), \ + struct Library *, (___base), 66, Sqlite3_lib_sfd) + +#define SQLite3DbHandle(___pStmt) __SQLite3DbHandle_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pStmt) +#define __SQLite3DbHandle_WB(___base, ___pStmt) \ + AROS_LC1(sqlite3 *, SQLite3DbHandle, \ + AROS_LCA(sqlite3_stmt *, (___pStmt), A0), \ + struct Library *, (___base), 67, Sqlite3_lib_sfd) + +#define SQLite3RollbackHook(___db, ___callback, ___pUserData) __SQLite3RollbackHook_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db, ___callback, ___pUserData) +#define __SQLite3RollbackHook_WB(___base, ___db, ___callback, ___pUserData) \ + AROS_LC3(APTR, SQLite3RollbackHook, \ + AROS_LCA(sqlite3 *, (___db), A0), \ + AROS_LCA(VOID (*)(APTR pUserData), (___callback), A1), \ + AROS_LCA(APTR, (___pUserData), A2), \ + struct Library *, (___base), 68, Sqlite3_lib_sfd) + +#define SQLite3EnableSharedCache(___enable) __SQLite3EnableSharedCache_WB(SQLITE3_LIB_SFD_BASE_NAME, ___enable) +#define __SQLite3EnableSharedCache_WB(___base, ___enable) \ + AROS_LC1(LONG, SQLite3EnableSharedCache, \ + AROS_LCA(BOOL, (___enable), D0), \ + struct Library *, (___base), 69, Sqlite3_lib_sfd) + +#define SQLite3ReleaseMemory(___bytesCount) __SQLite3ReleaseMemory_WB(SQLITE3_LIB_SFD_BASE_NAME, ___bytesCount) +#define __SQLite3ReleaseMemory_WB(___base, ___bytesCount) \ + AROS_LC1(LONG, SQLite3ReleaseMemory, \ + AROS_LCA(LONG, (___bytesCount), D0), \ + struct Library *, (___base), 70, Sqlite3_lib_sfd) + +#define SQLite3SoftHeapLimit(___maxBytes) __SQLite3SoftHeapLimit_WB(SQLITE3_LIB_SFD_BASE_NAME, ___maxBytes) +#define __SQLite3SoftHeapLimit_WB(___base, ___maxBytes) \ + AROS_LC1NR(VOID, SQLite3SoftHeapLimit, \ + AROS_LCA(LONG, (___maxBytes), D0), \ + struct Library *, (___base), 71, Sqlite3_lib_sfd) + +#define SQLite3ThreadCleanup() __SQLite3ThreadCleanup_WB(SQLITE3_LIB_SFD_BASE_NAME) +#define __SQLite3ThreadCleanup_WB(___base) \ + AROS_LC0NR(VOID, SQLite3ThreadCleanup, \ + struct Library *, (___base), 72, Sqlite3_lib_sfd) + +#define SQLite3PrepareV2(___db, ___zSql, ___nBytes, ___ppStmt, ___pzTail) __SQLite3PrepareV2_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db, ___zSql, ___nBytes, ___ppStmt, ___pzTail) +#define __SQLite3PrepareV2_WB(___base, ___db, ___zSql, ___nBytes, ___ppStmt, ___pzTail) \ + AROS_LC5(LONG, SQLite3PrepareV2, \ + AROS_LCA(sqlite3 *, (___db), A0), \ + AROS_LCA(CONST_STRPTR, (___zSql), A1), \ + AROS_LCA(LONG, (___nBytes), D0), \ + AROS_LCA(sqlite3_stmt **, (___ppStmt), A2), \ + AROS_LCA(CONST_STRPTR *, (___pzTail), A3), \ + struct Library *, (___base), 73, Sqlite3_lib_sfd) + +#define SQLite3CreateFunction(___db, ___zFunctionName, ___nArg, ___eTextRep, ___userdata, ___xFunc, ___xStep, ___xFinal) __SQLite3CreateFunction_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db, ___zFunctionName, ___nArg, ___eTextRep, ___userdata, ___xFunc, ___xStep, ___xFinal) +#define __SQLite3CreateFunction_WB(___base, ___db, ___zFunctionName, ___nArg, ___eTextRep, ___userdata, ___xFunc, ___xStep, ___xFinal) \ + AROS_LC8(LONG, SQLite3CreateFunction, \ + AROS_LCA(sqlite3 *, (___db), A0), \ + AROS_LCA(CONST_STRPTR, (___zFunctionName), A1), \ + AROS_LCA(LONG, (___nArg), D0), \ + AROS_LCA(LONG, (___eTextRep), D1), \ + AROS_LCA(APTR, (___userdata), A2), \ + AROS_LCA(VOID (*)(sqlite3_context *pCtx,LONG i,sqlite3_value **pVal), (___xFunc), A3), \ + AROS_LCA(VOID (*)(sqlite3_context *pCtx,LONG i,sqlite3_value **pVal), (___xStep), D2), \ + AROS_LCA(VOID (*)(sqlite3_context *pCtx), (___xFinal), D3), \ + struct Library *, (___base), 74, Sqlite3_lib_sfd) + +#define SQLite3CreateModule(___db, ___zName, ___methods, ___clientData) __SQLite3CreateModule_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db, ___zName, ___methods, ___clientData) +#define __SQLite3CreateModule_WB(___base, ___db, ___zName, ___methods, ___clientData) \ + AROS_LC4(LONG, SQLite3CreateModule, \ + AROS_LCA(sqlite3 *, (___db), A0), \ + AROS_LCA(CONST_STRPTR, (___zName), A1), \ + AROS_LCA(CONST sqlite3_module *, (___methods), A2), \ + AROS_LCA(APTR, (___clientData), A3), \ + struct Library *, (___base), 75, Sqlite3_lib_sfd) + +#define SQLite3DeclareVtab(___db, ___zCreateTable) __SQLite3DeclareVtab_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db, ___zCreateTable) +#define __SQLite3DeclareVtab_WB(___base, ___db, ___zCreateTable) \ + AROS_LC2(LONG, SQLite3DeclareVtab, \ + AROS_LCA(sqlite3 *, (___db), A0), \ + AROS_LCA(CONST_STRPTR, (___zCreateTable), A1), \ + struct Library *, (___base), 76, Sqlite3_lib_sfd) + +#define SQLite3OverloadFunction(___db, ___zFuncName, ___nArg) __SQLite3OverloadFunction_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db, ___zFuncName, ___nArg) +#define __SQLite3OverloadFunction_WB(___base, ___db, ___zFuncName, ___nArg) \ + AROS_LC3(LONG, SQLite3OverloadFunction, \ + AROS_LCA(sqlite3 *, (___db), A0), \ + AROS_LCA(CONST_STRPTR, (___zFuncName), A1), \ + AROS_LCA(LONG, (___nArg), D0), \ + struct Library *, (___base), 77, Sqlite3_lib_sfd) + +#define SQLite3BlobOpen(___db, ___zDb, ___zTable, ___zColumn, ___iRow, ___flags, ___ppBlob) __SQLite3BlobOpen_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db, ___zDb, ___zTable, ___zColumn, ___iRow, ___flags, ___ppBlob) +#define __SQLite3BlobOpen_WB(___base, ___db, ___zDb, ___zTable, ___zColumn, ___iRow, ___flags, ___ppBlob) \ + AROS_LC7(LONG, SQLite3BlobOpen, \ + AROS_LCA(sqlite3 *, (___db), A0), \ + AROS_LCA(CONST_STRPTR, (___zDb), A1), \ + AROS_LCA(CONST_STRPTR, (___zTable), A2), \ + AROS_LCA(CONST_STRPTR, (___zColumn), A3), \ + AROS_LCA(LONG, (___iRow), D0), \ + AROS_LCA(LONG, (___flags), D1), \ + AROS_LCA(sqlite3_blob **, (___ppBlob), A4), \ + struct Library *, (___base), 78, Sqlite3_lib_sfd) + +#define SQLite3BlobClose(___blob) __SQLite3BlobClose_WB(SQLITE3_LIB_SFD_BASE_NAME, ___blob) +#define __SQLite3BlobClose_WB(___base, ___blob) \ + AROS_LC1(LONG, SQLite3BlobClose, \ + AROS_LCA(sqlite3_blob *, (___blob), A0), \ + struct Library *, (___base), 79, Sqlite3_lib_sfd) + +#define SQLite3BlobBytes(___blob) __SQLite3BlobBytes_WB(SQLITE3_LIB_SFD_BASE_NAME, ___blob) +#define __SQLite3BlobBytes_WB(___base, ___blob) \ + AROS_LC1(LONG, SQLite3BlobBytes, \ + AROS_LCA(sqlite3_blob *, (___blob), A0), \ + struct Library *, (___base), 80, Sqlite3_lib_sfd) + +#define SQLite3BlobRead(___blob, ___z, ___n, ___iOffset) __SQLite3BlobRead_WB(SQLITE3_LIB_SFD_BASE_NAME, ___blob, ___z, ___n, ___iOffset) +#define __SQLite3BlobRead_WB(___base, ___blob, ___z, ___n, ___iOffset) \ + AROS_LC4(LONG, SQLite3BlobRead, \ + AROS_LCA(sqlite3_blob *, (___blob), A0), \ + AROS_LCA(APTR, (___z), A1), \ + AROS_LCA(LONG, (___n), D0), \ + AROS_LCA(LONG, (___iOffset), D1), \ + struct Library *, (___base), 81, Sqlite3_lib_sfd) + +#define SQLite3BlobWrite(___blob, ___z, ___n, ___iOffset) __SQLite3BlobWrite_WB(SQLITE3_LIB_SFD_BASE_NAME, ___blob, ___z, ___n, ___iOffset) +#define __SQLite3BlobWrite_WB(___base, ___blob, ___z, ___n, ___iOffset) \ + AROS_LC4(LONG, SQLite3BlobWrite, \ + AROS_LCA(sqlite3_blob *, (___blob), A0), \ + AROS_LCA(CONST_APTR, (___z), A1), \ + AROS_LCA(LONG, (___n), D0), \ + AROS_LCA(LONG, (___iOffset), D1), \ + struct Library *, (___base), 82, Sqlite3_lib_sfd) + +#define SQLite3ExtendedResultCodes(___db, ___onoff) __SQLite3ExtendedResultCodes_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db, ___onoff) +#define __SQLite3ExtendedResultCodes_WB(___base, ___db, ___onoff) \ + AROS_LC2(LONG, SQLite3ExtendedResultCodes, \ + AROS_LCA(sqlite3 *, (___db), A0), \ + AROS_LCA(LONG, (___onoff), D0), \ + struct Library *, (___base), 83, Sqlite3_lib_sfd) + +#define SQLite3BindZeroBlob(___pStmt, ___i, ___n) __SQLite3BindZeroBlob_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pStmt, ___i, ___n) +#define __SQLite3BindZeroBlob_WB(___base, ___pStmt, ___i, ___n) \ + AROS_LC3(LONG, SQLite3BindZeroBlob, \ + AROS_LCA(sqlite3_stmt *, (___pStmt), A0), \ + AROS_LCA(LONG, (___i), D0), \ + AROS_LCA(LONG, (___n), D1), \ + struct Library *, (___base), 84, Sqlite3_lib_sfd) + +#define SQLite3ColumnDatabaseName(___stmt, ___n) __SQLite3ColumnDatabaseName_WB(SQLITE3_LIB_SFD_BASE_NAME, ___stmt, ___n) +#define __SQLite3ColumnDatabaseName_WB(___base, ___stmt, ___n) \ + AROS_LC2(CONST_STRPTR, SQLite3ColumnDatabaseName, \ + AROS_LCA(sqlite3_stmt *, (___stmt), A0), \ + AROS_LCA(LONG, (___n), D0), \ + struct Library *, (___base), 85, Sqlite3_lib_sfd) + +#define SQLite3ColumnTableName(___stmt, ___n) __SQLite3ColumnTableName_WB(SQLITE3_LIB_SFD_BASE_NAME, ___stmt, ___n) +#define __SQLite3ColumnTableName_WB(___base, ___stmt, ___n) \ + AROS_LC2(CONST_STRPTR, SQLite3ColumnTableName, \ + AROS_LCA(sqlite3_stmt *, (___stmt), A0), \ + AROS_LCA(LONG, (___n), D0), \ + struct Library *, (___base), 86, Sqlite3_lib_sfd) + +#define SQLite3ColumnOriginName(___stmt, ___n) __SQLite3ColumnOriginName_WB(SQLITE3_LIB_SFD_BASE_NAME, ___stmt, ___n) +#define __SQLite3ColumnOriginName_WB(___base, ___stmt, ___n) \ + AROS_LC2(CONST_STRPTR, SQLite3ColumnOriginName, \ + AROS_LCA(sqlite3_stmt *, (___stmt), A0), \ + AROS_LCA(LONG, (___n), D0), \ + struct Library *, (___base), 87, Sqlite3_lib_sfd) + +#define SQLite3ColumnValue(___pStmt, ___iCol) __SQLite3ColumnValue_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pStmt, ___iCol) +#define __SQLite3ColumnValue_WB(___base, ___pStmt, ___iCol) \ + AROS_LC2(sqlite3_value *, SQLite3ColumnValue, \ + AROS_LCA(sqlite3_stmt *, (___pStmt), A0), \ + AROS_LCA(LONG, (___iCol), D0), \ + struct Library *, (___base), 88, Sqlite3_lib_sfd) + +#define SQLite3CreateCollationV2(___db, ___zName, ___eTextRep, ___pCtx, ___xCompare, ___xDestroy) __SQLite3CreateCollationV2_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db, ___zName, ___eTextRep, ___pCtx, ___xCompare, ___xDestroy) +#define __SQLite3CreateCollationV2_WB(___base, ___db, ___zName, ___eTextRep, ___pCtx, ___xCompare, ___xDestroy) \ + AROS_LC6(LONG, SQLite3CreateCollationV2, \ + AROS_LCA(sqlite3 *, (___db), A0), \ + AROS_LCA(CONST_STRPTR, (___zName), A1), \ + AROS_LCA(LONG, (___eTextRep), D0), \ + AROS_LCA(APTR, (___pCtx), A2), \ + AROS_LCA(LONG(*)(APTR p,LONG i,CONST_APTR p2,LONG j,CONST_APTR p3), (___xCompare), A3), \ + AROS_LCA(VOID (*)(APTR), (___xDestroy), D1), \ + struct Library *, (___base), 89, Sqlite3_lib_sfd) + +#define SQLite3LibVersion() __SQLite3LibVersion_WB(SQLITE3_LIB_SFD_BASE_NAME) +#define __SQLite3LibVersion_WB(___base) \ + AROS_LC0(CONST_STRPTR, SQLite3LibVersion, \ + struct Library *, (___base), 90, Sqlite3_lib_sfd) + +#define SQLite3LibversionNumber() __SQLite3LibversionNumber_WB(SQLITE3_LIB_SFD_BASE_NAME) +#define __SQLite3LibversionNumber_WB(___base) \ + AROS_LC0(LONG, SQLite3LibversionNumber, \ + struct Library *, (___base), 91, Sqlite3_lib_sfd) + +#define SQLite3ResultErrorToobig(___pCtx) __SQLite3ResultErrorToobig_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pCtx) +#define __SQLite3ResultErrorToobig_WB(___base, ___pCtx) \ + AROS_LC1NR(VOID, SQLite3ResultErrorToobig, \ + AROS_LCA(sqlite3_context *, (___pCtx), A0), \ + struct Library *, (___base), 92, Sqlite3_lib_sfd) + +#define SQLite3ResultZeroBlob(___pCtx, ___n) __SQLite3ResultZeroBlob_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pCtx, ___n) +#define __SQLite3ResultZeroBlob_WB(___base, ___pCtx, ___n) \ + AROS_LC2NR(VOID, SQLite3ResultZeroBlob, \ + AROS_LCA(sqlite3_context *, (___pCtx), A0), \ + AROS_LCA(LONG, (___n), D0), \ + struct Library *, (___base), 93, Sqlite3_lib_sfd) + +#define SQLite3ValueNumericType(___pVal) __SQLite3ValueNumericType_WB(SQLITE3_LIB_SFD_BASE_NAME, ___pVal) +#define __SQLite3ValueNumericType_WB(___base, ___pVal) \ + AROS_LC1(LONG, SQLite3ValueNumericType, \ + AROS_LCA(sqlite3_value *, (___pVal), A0), \ + struct Library *, (___base), 94, Sqlite3_lib_sfd) + +#define SQLite3ConfigV(___op, ___ap) __SQLite3ConfigV_WB(SQLITE3_LIB_SFD_BASE_NAME, ___op, ___ap) +#define __SQLite3ConfigV_WB(___base, ___op, ___ap) \ + AROS_LC2(LONG, SQLite3ConfigV, \ + AROS_LCA(LONG, (___op), D0), \ + AROS_LCA(APTR, (___ap), A0), \ + struct Library *, (___base), 95, Sqlite3_lib_sfd) + +#ifndef NO_INLINE_VARARGS +#define SQLite3Config(___op, ___dummy, ...) __SQLite3Config_WB(SQLITE3_LIB_SFD_BASE_NAME, ___op, ___dummy, ## __VA_ARGS__) +#define __SQLite3Config_WB(___base, ___op, ___dummy, ...) \ + ({IPTR _message[] = { (IPTR) ___dummy, ## __VA_ARGS__ }; __SQLite3ConfigV_WB((___base), (___op), (APTR) _message); }) +#endif /* !NO_INLINE_VARARGS */ + +#define SQLlite3DbConfigV(___db, ___op, ___ap) __SQLlite3DbConfigV_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db, ___op, ___ap) +#define __SQLlite3DbConfigV_WB(___base, ___db, ___op, ___ap) \ + AROS_LC3(LONG, SQLlite3DbConfigV, \ + AROS_LCA(sqlite3 *, (___db), A0), \ + AROS_LCA(LONG, (___op), D0), \ + AROS_LCA(APTR, (___ap), A1), \ + struct Library *, (___base), 96, Sqlite3_lib_sfd) + +#ifndef NO_INLINE_VARARGS +#define SQLlite3DbConfig(___db, ___op, ___dummy, ...) __SQLlite3DbConfig_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db, ___op, ___dummy, ## __VA_ARGS__) +#define __SQLlite3DbConfig_WB(___base, ___db, ___op, ___dummy, ...) \ + ({IPTR _message[] = { (IPTR) ___dummy, ## __VA_ARGS__ }; __SQLlite3DbConfigV_WB((___base), (___db), (___op), (APTR) _message); }) +#endif /* !NO_INLINE_VARARGS */ + +#define SQLite3VfsFind(___zVfsName) __SQLite3VfsFind_WB(SQLITE3_LIB_SFD_BASE_NAME, ___zVfsName) +#define __SQLite3VfsFind_WB(___base, ___zVfsName) \ + AROS_LC1(sqlite3_vfs *, SQLite3VfsFind, \ + AROS_LCA(CONST_STRPTR, (___zVfsName), A0), \ + struct Library *, (___base), 97, Sqlite3_lib_sfd) + +#define SQLite3VfsRegister(___vfs, ___makeDflt) __SQLite3VfsRegister_WB(SQLITE3_LIB_SFD_BASE_NAME, ___vfs, ___makeDflt) +#define __SQLite3VfsRegister_WB(___base, ___vfs, ___makeDflt) \ + AROS_LC2(LONG, SQLite3VfsRegister, \ + AROS_LCA(sqlite3_vfs *, (___vfs), A0), \ + AROS_LCA(LONG, (___makeDflt), D0), \ + struct Library *, (___base), 98, Sqlite3_lib_sfd) + +#define SQLite3VfsUnregister(___vfs) __SQLite3VfsUnregister_WB(SQLITE3_LIB_SFD_BASE_NAME, ___vfs) +#define __SQLite3VfsUnregister_WB(___base, ___vfs) \ + AROS_LC1(LONG, SQLite3VfsUnregister, \ + AROS_LCA(sqlite3_vfs *, (___vfs), A0), \ + struct Library *, (___base), 99, Sqlite3_lib_sfd) + +#define SQLite3FileControl(___db, ___zDbName, ___op, ___arg) __SQLite3FileControl_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db, ___zDbName, ___op, ___arg) +#define __SQLite3FileControl_WB(___base, ___db, ___zDbName, ___op, ___arg) \ + AROS_LC4(LONG, SQLite3FileControl, \ + AROS_LCA(sqlite3 *, (___db), A0), \ + AROS_LCA(CONST_STRPTR, (___zDbName), A1), \ + AROS_LCA(LONG, (___op), D0), \ + AROS_LCA(void *, (___arg), A2), \ + struct Library *, (___base), 100, Sqlite3_lib_sfd) + +#define SQLite3Status(___op, ___pCurrent, ___pHighwater, ___resetFlag) __SQLite3Status_WB(SQLITE3_LIB_SFD_BASE_NAME, ___op, ___pCurrent, ___pHighwater, ___resetFlag) +#define __SQLite3Status_WB(___base, ___op, ___pCurrent, ___pHighwater, ___resetFlag) \ + AROS_LC4(LONG, SQLite3Status, \ + AROS_LCA(LONG, (___op), D0), \ + AROS_LCA(LONG *, (___pCurrent), A0), \ + AROS_LCA(LONG *, (___pHighwater), A1), \ + AROS_LCA(LONG, (___resetFlag), D1), \ + struct Library *, (___base), 101, Sqlite3_lib_sfd) + +#define SQLite3DbStatus(___db, ___op, ___pCur, ___pHiwtr, ___resetFlg) __SQLite3DbStatus_WB(SQLITE3_LIB_SFD_BASE_NAME, ___db, ___op, ___pCur, ___pHiwtr, ___resetFlg) +#define __SQLite3DbStatus_WB(___base, ___db, ___op, ___pCur, ___pHiwtr, ___resetFlg) \ + AROS_LC5(LONG, SQLite3DbStatus, \ + AROS_LCA(sqlite3 *, (___db), A0), \ + AROS_LCA(LONG, (___op), D0), \ + AROS_LCA(LONG *, (___pCur), A1), \ + AROS_LCA(LONG *, (___pHiwtr), A2), \ + AROS_LCA(LONG, (___resetFlg), D1), \ + struct Library *, (___base), 102, Sqlite3_lib_sfd) + +#endif /* !_INLINE_SQLITE3_LIB_SFD_H */ diff --git a/scalos/include/defines/ttengine.h b/scalos/include/defines/ttengine.h new file mode 100644 index 000000000..7a293b528 --- /dev/null +++ b/scalos/include/defines/ttengine.h @@ -0,0 +1,172 @@ +/* Automatically generated header! Do not edit! */ + +#ifndef _INLINE_TTENGINE_H +#define _INLINE_TTENGINE_H + +#ifndef AROS_LIBCALL_H +#include +#endif /* !AROS_LIBCALL_H */ + +#ifndef TTENGINE_BASE_NAME +#define TTENGINE_BASE_NAME TTEngineBase +#endif /* !TTENGINE_BASE_NAME */ + +#define TT_OpenFontA(___taglist) __TT_OpenFontA_WB(TTENGINE_BASE_NAME, ___taglist) +#define __TT_OpenFontA_WB(___base, ___taglist) \ + AROS_LC1(APTR, TT_OpenFontA, \ + AROS_LCA(struct TagItem *, (___taglist), A0), \ + struct Library*, (___base), 5, Ttengine) + +#ifndef NO_INLINE_STDARG +#define TT_OpenFont(___tag1, ...) __TT_OpenFont_WB(TTENGINE_BASE_NAME, ___tag1, ## __VA_ARGS__) +#define __TT_OpenFont_WB(___base, ___tag1, ...) \ + ({ULONG _tags[] = { (ULONG) ___tag1, ## __VA_ARGS__ }; __TT_OpenFontA_WB((___base), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define TT_SetFont(___rp, ___font) __TT_SetFont_WB(TTENGINE_BASE_NAME, ___rp, ___font) +#define __TT_SetFont_WB(___base, ___rp, ___font) \ + AROS_LC2(BOOL, TT_SetFont, \ + AROS_LCA(struct RastPort *, (___rp), A1), \ + AROS_LCA(APTR, (___font), A0), \ + struct Library*, (___base), 6, Ttengine) + +#define TT_CloseFont(___font) __TT_CloseFont_WB(TTENGINE_BASE_NAME, ___font) +#define __TT_CloseFont_WB(___base, ___font) \ + AROS_LC1(VOID, TT_CloseFont, \ + AROS_LCA(APTR, (___font), A0), \ + struct Library*, (___base), 7, Ttengine) + +#define TT_Text(___rp, ___string, ___count) __TT_Text_WB(TTENGINE_BASE_NAME, ___rp, ___string, ___count) +#define __TT_Text_WB(___base, ___rp, ___string, ___count) \ + AROS_LC3(VOID, TT_Text, \ + AROS_LCA(struct RastPort *, (___rp), A1), \ + AROS_LCA(APTR, (___string), A0), \ + AROS_LCA(ULONG, (___count), D0), \ + struct Library*, (___base), 8, Ttengine) + +#define TT_SetAttrsA(___rp, ___taglist) __TT_SetAttrsA_WB(TTENGINE_BASE_NAME, ___rp, ___taglist) +#define __TT_SetAttrsA_WB(___base, ___rp, ___taglist) \ + AROS_LC2(ULONG, TT_SetAttrsA, \ + AROS_LCA(struct RastPort *, (___rp), A1), \ + AROS_LCA(struct TagItem *, (___taglist), A0), \ + struct Library*, (___base), 9, Ttengine) + +#ifndef NO_INLINE_STDARG +#define TT_SetAttrs(___rp, ___tag1, ...) __TT_SetAttrs_WB(TTENGINE_BASE_NAME, ___rp, ___tag1, ## __VA_ARGS__) +#define __TT_SetAttrs_WB(___base, ___rp, ___tag1, ...) \ + ({ULONG _tags[] = { (ULONG) ___tag1, ## __VA_ARGS__ }; __TT_SetAttrsA_WB((___base), (___rp), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define TT_GetAttrsA(___rp, ___taglist) __TT_GetAttrsA_WB(TTENGINE_BASE_NAME, ___rp, ___taglist) +#define __TT_GetAttrsA_WB(___base, ___rp, ___taglist) \ + AROS_LC2(ULONG, TT_GetAttrsA, \ + AROS_LCA(struct RastPort *, (___rp), A1), \ + AROS_LCA(struct TagItem *, (___taglist), A0), \ + struct Library*, (___base), 10, Ttengine) + +#ifndef NO_INLINE_STDARG +#define TT_GetAttrs(___rp, ___tag1, ...) __TT_GetAttrs_WB(TTENGINE_BASE_NAME, ___rp, ___tag1, ## __VA_ARGS__) +#define __TT_GetAttrs_WB(___base, ___rp, ___tag1, ...) \ + ({ULONG _tags[] = { (ULONG) ___tag1, ## __VA_ARGS__ }; __TT_GetAttrsA_WB((___base), (___rp), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define TT_TextLength(___rp, ___string, ___count) __TT_TextLength_WB(TTENGINE_BASE_NAME, ___rp, ___string, ___count) +#define __TT_TextLength_WB(___base, ___rp, ___string, ___count) \ + AROS_LC3(ULONG, TT_TextLength, \ + AROS_LCA(struct RastPort *, (___rp), A1), \ + AROS_LCA(APTR, (___string), A0), \ + AROS_LCA(ULONG, (___count), D0), \ + struct Library*, (___base), 11, Ttengine) + +#define TT_TextExtent(___rp, ___string, ___count, ___te) __TT_TextExtent_WB(TTENGINE_BASE_NAME, ___rp, ___string, ___count, ___te) +#define __TT_TextExtent_WB(___base, ___rp, ___string, ___count, ___te) \ + AROS_LC4(VOID, TT_TextExtent, \ + AROS_LCA(struct RastPort *, (___rp), A1), \ + AROS_LCA(APTR, (___string), A0), \ + AROS_LCA(WORD, (___count), D0), \ + AROS_LCA(struct TextExtent *, (___te), A2), \ + struct Library*, (___base), 12, Ttengine) + +#define TT_TextFit(___rp, ___string, ___count, ___te, ___tec, ___dir, ___cwidth, ___cheight) __TT_TextFit_WB(TTENGINE_BASE_NAME, ___rp, ___string, ___count, ___te, ___tec, ___dir, ___cwidth, ___cheight) +#define __TT_TextFit_WB(___base, ___rp, ___string, ___count, ___te, ___tec, ___dir, ___cwidth, ___cheight) \ + AROS_LC8(ULONG, TT_TextFit, \ + AROS_LCA(struct RastPort *, (___rp), A1), \ + AROS_LCA(APTR, (___string), A0), \ + AROS_LCA(UWORD, (___count), D0), \ + AROS_LCA(struct TextExtent *, (___te), A2), \ + AROS_LCA(struct TextExtent *, (___tec), A3), \ + AROS_LCA(WORD, (___dir), D1), \ + AROS_LCA(UWORD, (___cwidth), D2), \ + AROS_LCA(UWORD, (___cheight), D3), \ + struct Library*, (___base), 13, Ttengine) + +#define TT_GetPixmapA(___font, ___string, ___count, ___taglist) __TT_GetPixmapA_WB(TTENGINE_BASE_NAME, ___font, ___string, ___count, ___taglist) +#define __TT_GetPixmapA_WB(___base, ___font, ___string, ___count, ___taglist) \ + AROS_LC4(struct TT_Pixmap *, TT_GetPixmapA, \ + AROS_LCA(APTR, (___font), A1), \ + AROS_LCA(APTR, (___string), A2), \ + AROS_LCA(ULONG, (___count), D0), \ + AROS_LCA(struct TagItem *, (___taglist), A0), \ + struct Library*, (___base), 14, Ttengine) + +#ifndef NO_INLINE_STDARG +#define TT_GetPixmap(___font, ___string, ___count, ___tag1, ...) __TT_GetPixmap_WB(TTENGINE_BASE_NAME, ___font, ___string, ___count, ___tag1, ## __VA_ARGS__) +#define __TT_GetPixmap_WB(___base, ___font, ___string, ___count, ___tag1, ...) \ + ({ULONG _tags[] = { (ULONG) ___tag1, ## __VA_ARGS__ }; __TT_GetPixmapA_WB((___base), (___font), (___string), (___count), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define TT_FreePixmap(___pixmap) __TT_FreePixmap_WB(TTENGINE_BASE_NAME, ___pixmap) +#define __TT_FreePixmap_WB(___base, ___pixmap) \ + AROS_LC1(VOID, TT_FreePixmap, \ + AROS_LCA(struct TT_Pixmap *, (___pixmap), A0), \ + struct Library*, (___base), 15, Ttengine) + +#define TT_DoneRastPort(___rp) __TT_DoneRastPort_WB(TTENGINE_BASE_NAME, ___rp) +#define __TT_DoneRastPort_WB(___base, ___rp) \ + AROS_LC1(VOID, TT_DoneRastPort, \ + AROS_LCA(struct RastPort *, (___rp), A1), \ + struct Library*, (___base), 16, Ttengine) + +#define TT_AllocRequest() __TT_AllocRequest_WB(TTENGINE_BASE_NAME) +#define __TT_AllocRequest_WB(___base) \ + AROS_LC0(APTR, TT_AllocRequest, \ + struct Library*, (___base), 17, Ttengine) + +#define TT_RequestA(___request, ___taglist) __TT_RequestA_WB(TTENGINE_BASE_NAME, ___request, ___taglist) +#define __TT_RequestA_WB(___base, ___request, ___taglist) \ + AROS_LC2(struct TagItem*, TT_RequestA, \ + AROS_LCA(APTR, (___request), A0), \ + AROS_LCA(struct TagItem *, (___taglist), A1), \ + struct Library*, (___base), 18, Ttengine) + +#ifndef NO_INLINE_STDARG +#define TT_Request(___request, ___tag1, ...) __TT_Request_WB(TTENGINE_BASE_NAME, ___request, ___tag1, ## __VA_ARGS__) +#define __TT_Request_WB(___base, ___request, ___tag1, ...) \ + ({ULONG _tags[] = { (ULONG) ___tag1, ## __VA_ARGS__ }; __TT_RequestA_WB((___base), (___request), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define TT_FreeRequest(___request) __TT_FreeRequest_WB(TTENGINE_BASE_NAME, ___request) +#define __TT_FreeRequest_WB(___base, ___request) \ + AROS_LC1(VOID, TT_FreeRequest, \ + AROS_LCA(APTR, (___request), A0), \ + struct Library*, (___base), 19, Ttengine) + +#define TT_ObtainFamilyListA(___taglist) __TT_ObtainFamilyListA_WB(TTENGINE_BASE_NAME, ___taglist) +#define __TT_ObtainFamilyListA_WB(___base, ___taglist) \ + AROS_LC1(STRPTR *, TT_ObtainFamilyListA, \ + AROS_LCA(struct TagItem *, (___taglist), A0), \ + struct Library*, (___base), 20, Ttengine) + +#ifndef NO_INLINE_STDARG +#define TT_ObtainFamilyList(___tag1, ...) __TT_ObtainFamilyList_WB(TTENGINE_BASE_NAME, ___tag1, ## __VA_ARGS__) +#define __TT_ObtainFamilyList_WB(___base, ___tag1, ...) \ + ({ULONG _tags[] = { (ULONG) ___tag1, ## __VA_ARGS__ }; __TT_ObtainFamilyListA_WB((___base), (struct TagItem *) _tags); }) +#endif /* !NO_INLINE_STDARG */ + +#define TT_FreeFamilyList(___list) __TT_FreeFamilyList_WB(TTENGINE_BASE_NAME, ___list) +#define __TT_FreeFamilyList_WB(___base, ___list) \ + AROS_LC1(VOID, TT_FreeFamilyList, \ + AROS_LCA(STRPTR *, (___list), A0), \ + struct Library*, (___base), 21, Ttengine) + +#endif /* !_INLINE_TTENGINE_H */ diff --git a/scalos/include/defs.h b/scalos/include/defs.h new file mode 100755 index 000000000..6105176c1 --- /dev/null +++ b/scalos/include/defs.h @@ -0,0 +1,2872 @@ +/* + * defs.h + * + * $Date$ + * $Revision$ + * + * Some global compiler- and platform-dependent definitions + * + */ + +#ifndef DEFS_H +#define DEFS_H + +#ifndef EXEC_TYPES_H +#include +#endif + + +#ifdef __VBCC__ + #define SEGLISTPTR APTR +#else /* !VBCC */ + #include + #define SEGLISTPTR BPTR +#endif /* VBCC */ + + +#define STR(x) STR2(x) +#define STR2(x) #x + +// initialized exec List and MinList +#define DEFINE_LIST(l) struct List (l) = { (struct Node *) &(l).lh_Tail, NULL, (struct Node *) &(l).lh_TailPred, 0, 0 }; +#define DEFINE_MINLIST(l) struct MinList (l) = { (struct MinNode *) &(l).mlh_Tail, NULL, (struct MinNode *) &(l).mlh_TailPred }; + + +/* compiler specific stuff */ +#ifdef __VBCC__ + + #define REG(x, arg) __reg(#x) arg + #define ASM + #define SAVEDS(x) __saveds x + #define ALIGNED __aligned + + #define LIB_REG(x, arg) REG(x, arg) + #define LIB_ASM ASM + #define LIB_INTERRUPT INTERRUPT + #define LIB_SAVEDS(x) SAVEDS(x) + + #define COMPILER_STRING " (VBCC)"; + #define T_UTILITYBASE struct UtilityBase * + #define T_INPUTBASE struct Device * + #define WBENCHMSG WBenchMsg + #define T_LOCALEBASE struct LocaleBase * + #define T_REXXSYSBASE struct RxsLib * + #define T_TIMERBASE struct Device * + #define T_CONSOLEDEVICE struct Device * + #define T_INPUTDEVICE struct Device * + +#elif defined(__STORM__) + + #define REG(x, arg) register __##x arg + #define ASM + #define SAVEDS(x) x __saveds + #define INTERRUPT + #define INLINE + #define ALIGNED __aligned + + #define LIB_REG(x, arg) REG(x, arg) + #define LIB_ASM ASM + #define LIB_INTERRUPT INTERRUPT + #define LIB_SAVEDS(x) SAVEDS(x) + + #define T_UTILITYBASE struct Library * + #define T_INPUTBASE struct Device * + #define WBENCHMSG WBenchMsg + #define T_LOCALEBASE struct LocaleBase * + #define T_REXXSYSBASE struct RxsLib * + #define T_TIMERBASE struct Device * + #define T_CONSOLEDEVICE struct Device * + #define T_INPUTDEVICE struct Device * + + #define COMPILER_STRING " (VBCC)"; + +#elif defined(__GNUC__) + + #define ASM +// #define SAVEDS(x) x __saveds +#ifdef __amigaos4__ + #include + #undef SAVEDS +#elif defined(__AROS__) + #undef SAVEDS + #define INLINE inline + #define REG(x, arg) arg + + #define DoPkt1(port, action, arg1) DoPkt(port, action, arg1, 0, 0, 0, 0) + #define DoPkt2(port, action, arg1, arg2) DoPkt(port, action, arg1, arg2, 0, 0, 0) + #define DoPkt3(port, action, arg1, arg2, arg3) DoPkt(port, action, arg1, arg2, arg3, 0, 0) +#else + #define REG(x, arg) arg __asm(#x) + #define INLINE __inline +#endif + #define SAVEDS(x) x + #define INTERRUPT + +#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ > 3) + #define __FUNC__ __func__ +#else + #define __FUNC__ __FUNCTION__ +#endif + +#ifdef __amigaos4__ + #define WBENCHMSG WBenchMsg + #define T_ITEXT STRPTR +#else // __amigaos4__ + #define WBENCHMSG _WBenchMsg + #define T_ITEXT UBYTE * +#endif // __amigaos4__ + +#if defined(__MORPHOS__) || defined(__amigaos4__) || defined(__AROS__) + #define LIB_REG(x, arg) arg + #define LIB_ASM + #define LIB_INTERRUPT + #define LIB_SAVEDS(x) x + + #define ALIGNED + +#ifndef __USE_BASETYPE__ + #define T_UTILITYBASE struct Library * + #define T_LOCALEBASE struct Library * + #define T_REXXSYSBASE struct Library * + #define T_CONSOLEDEVICE struct Library * + #define T_TIMERBASE struct Library * + #define T_INPUTBASE struct Library * + #define T_INPUTDEVICE struct Library * +#else // __USE_BASETYPE__ + #define T_UTILITYBASE struct UtilityBase * +#if defined(__amigaos4__) + #define T_LOCALEBASE struct Library * +#else //defined(__amigaos4__) + #define T_LOCALEBASE struct LocaleBase * +#endif //defined(__amigaos4__) + #define T_REXXSYSBASE struct RxsLib * + #define T_CONSOLEDEVICE struct Device * + #define T_TIMERBASE struct Device * + #define T_INPUTBASE struct Device * + #define T_INPUTDEVICE struct Device * +#endif // __USE_BASETYPE__ + +#ifdef __amigaos4__ + #define GCC_PLATFORM "AmigaOS4/PPC" +#elif defined(__AROS__) +#ifdef __i386__ + #define GCC_PLATFORM "AROS/i386" +#else + #define GCC_PLATFORM "AROS/???" +#endif +#else // __amigaos4__ + #define GCC_PLATFORM "MorphOS/PPC" +#endif // __amigaos4__ + +#else /* __MORPHOS__ || __amigaos4__ */ + #define LIB_REG(x, arg) REG(x, arg) + #define LIB_ASM ASM + #define LIB_INTERRUPT INTERRUPT + #define LIB_SAVEDS(x) SAVEDS(x) + + #define ALIGNED __aligned + + #define T_LOCALEBASE struct LocaleBase * + #define T_UTILITYBASE struct UtilityBase * + #define T_INPUTBASE struct Device * + #define T_REXXSYSBASE struct RxsLib * + #define T_TIMERBASE struct Device * + #define T_CONSOLEDEVICE struct Device * + #define T_INPUTDEVICE struct Device * + + #define GCC_PLATFORM "68K" +#endif /* __MORPHOS__ || __amigaos4__ */ + + #if defined(__GNUC_PATCHLEVEL__) + #define COMPILER_STRING " (GCC " STR(__GNUC__) "." STR(__GNUC_MINOR__) "." STR(__GNUC_PATCHLEVEL__) " " GCC_PLATFORM ")" + #else + #define COMPILER_STRING " (GCC " STR(__GNUC__) "." STR(__GNUC_MINOR__) ".x " GCC_PLATFORM ")" + #endif + + #if defined(_INLINE_GRAPHICS_H) + // Remove definition made by "inline/graphics.h" becauses it causes errors (too many parameters...) + #undef BltBitMap + #endif /* _INLINE_GRAPHICS_H */ + +#elif defined(__SASC) + + #define REG(x, arg) register __##x arg + #define ASM __asm + #define SAVEDS(x) x __saveds + #define INTERRUPT __interrupt + #define INLINE __inline + #define ALIGNED __aligned + + #define LIB_REG(x, arg) REG(x, arg) + #define LIB_ASM ASM + #define LIB_INTERRUPT INTERRUPT + #define LIB_SAVEDS(x) SAVEDS(x) + + #define T_UTILITYBASE struct Library * + #define T_INPUTBASE struct Device * + #define WBENCHMSG WBenchMsg + #define T_LOCALEBASE struct LocaleBase * + #define T_REXXSYSBASE struct RxsLib * + #define T_TIMERBASE struct Device * + #define T_CONSOLEDEVICE struct Device * + #define T_INPUTDEVICE struct Device * + #define T_ITEXT UBYTE * + + #define COMPILER_STRING " (SAS/C " STR(__VERSION__) "." STR(__REVISION__) ")" + +#else + + /* other compilers would get stacked up in here */ + #error "You need VBCC, GCC SAS/C or StormC to compile this" + + #define COMPILER_STRING " (unknown)" +#endif + +/* Cut down on the load by not including old intuition defines */ +#define INTUI_V36_NAMES_ONLY + +#if defined(__MORPHOS__) && defined(WA_Opacity) + #define WA_SCA_Opaqueness WA_Opacity + #define SCALOS_OPAQUENESS(v) ((v) * (ULONG_MAX / 100)) +#elif defined(__amigaos4__) && defined(WA_Opaqueness) + #define WA_SCA_Opaqueness WA_Opaqueness + #define SCALOS_OPAQUENESS(v) (((v) * 255) / 100) + +#else + #define WA_SCA_Opaqueness TAG_IGNORE + #define SCALOS_OPAQUENESS(v) (0) +#endif + + +#ifdef __MORPHOS__ + #define DISPATCHER_PROTO(Name) \ + static ULONG Name##_Dispatcher(void) + + #define DISPATCHER(Name) \ + static ULONG Name##_Dispatcher(void); \ + struct EmulLibEntry GATE ##Name##_Dispatcher = { TRAP_LIB, 0, (void (*)(void)) Name##_Dispatcher }; \ + static ULONG Name##_Dispatcher(void) { struct IClass *cl=(struct IClass*)REG_A0; Msg msg=(Msg)REG_A1; Object *obj=(Object*)REG_A2; + #define DISPATCHER_REF(Name) &GATE##Name##_Dispatcher + #define DISPATCHER_END } + +#else //__MORPHOS__ + #define DISPATCHER_PROTO(Name) \ + static SAVEDS(ULONG) ASM Name##Dispatcher(REG(a0, struct IClass *cl), REG(a2, Object *obj), REG(a1, Msg msg)) + + #define DISPATCHER(Name) static SAVEDS(ULONG) ASM Name##Dispatcher(REG(a0, struct IClass *cl), REG(a2, Object *obj), REG(a1, Msg msg)) + #define DISPATCHER_REF(Name) Name##Dispatcher + #define DISPATCHER_END + +#endif //__MORPHOS__ + +#ifdef __amigaos4__ + #define SETHOOKFUNC(hook, func) \ + (hook).h_Entry = (HOOKFUNC)func + #define HOOKFUNC_DEF(func) \ + (HOOKFUNC)func, NULL +#else //__amigaos4__ + #define SETHOOKFUNC(hook, func) \ + (hook).h_Entry = (HOOKFUNC)HookEntry; \ + (hook).h_SubEntry = (HOOKFUNC)func + #define HOOKFUNC_DEF(func) \ + (HOOKFUNC)HookEntry, (HOOKFUNC)func +#endif //__amigaos4__ + +#if defined(M68K) && defined(__GNUC__) +#undef NewObject +#undef OpenWindowTags +#undef PutIconObjectTags +#endif //defined(M68K) && defined(__GNUC__) + +// ============================================================== +// Library function stuff +// ============================================================== + +#ifdef __MORPHOS__ + + #define PATCHFUNC(x) struct EmulLibEntry x##EmulEntry = \ + { TRAP_LIB, 0, (APTR) x } + #define STATIC_PATCHFUNC(x) static PATCHFUNC(x); + #define __EMULENTRY(x) x##EmulEntry + #define PATCH_NEWFUNC(x) (APTR) &__EMULENTRY(x) + + //======================================================= + + #define M68KFUNC_PROTO(funcname, libbase, returntype) \ + returntype funcname(void) + + + #define M68KFUNC_P1_PROTO(returntype, funcname, \ + register1, type1, name1) \ + returntype funcname(void) + + #define M68KFUNC_P2_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2) \ + returntype funcname(void) + + #define M68KFUNC_P3_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3) \ + returntype funcname(void) + + #define M68KFUNC_P4_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4) \ + returntype funcname(void) + + #define M68KFUNC_P5_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5) \ + returntype funcname(void) + + #define M68KFUNC_P6_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6) \ + returntype funcname(void) + + + #define M68KFUNC_P7_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7) \ + returntype funcname(void) + + #define M68KFUNC_P8_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8) \ + returntype funcname(void) + + #define M68KFUNC_P9_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8, \ + register9, type9, name9) \ + returntype funcname(void) + + //===== prototypes for data items ====================== + + #define M68KFUNC_P1_DPROTO(returntype, funcname, \ + register1, type1, name1) \ + returntype funcname(void) + + #define M68KFUNC_P2_DPROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2) \ + returntype funcname(void) + + #define M68KFUNC_P3_DPROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3) \ + returntype funcname(void) + + #define M68KFUNC_P4_DPROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4) \ + returntype funcname(void) + + #define M68KFUNC_P5_DPROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5) \ + returntype funcname(void) + + #define M68KFUNC_P6_DPROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6) \ + returntype funcname(void) + + + #define M68KFUNC_P7_DPROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7) \ + returntype funcname(void) + + #define M68KFUNC_P8_DPROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8) \ + returntype funcname(void) + + #define M68KFUNC_P9_DPROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8, \ + register9, type9, name9) \ + returntype funcname(void) + + //====================================================== + + #define M68KFUNC(name, libbase, returntype) \ + M68KFUNC_PROTO(name, libbase, returntype) \ + { \ + struct Library *libbase = (struct Library *) REG_A6; + + #define M68KFUNC_P1(returntype, funcname, \ + register1, type1, name1) \ + M68KFUNC_P1_PROTO(returntype, funcname, \ + register1, type1, name1) \ + { \ + type1 name1 = (type1) REG_##register1; + + #define M68KFUNC_P2(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2) \ + M68KFUNC_P2_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2) \ + { \ + type1 name1 = (type1) REG_##register1; \ + type2 name2 = (type2) REG_##register2; + + #define M68KFUNC_P3(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3) \ + M68KFUNC_P3_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3) \ + { \ + type1 name1 = (type1) REG_##register1; \ + type2 name2 = (type2) REG_##register2; \ + type3 name3 = (type3) REG_##register3; + + #define M68KFUNC_P4(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4) \ + M68KFUNC_P4_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4) \ + { \ + type1 name1 = (type1) REG_##register1; \ + type2 name2 = (type2) REG_##register2; \ + type3 name3 = (type3) REG_##register3; \ + type4 name4 = (type4) REG_##register4; + + #define M68KFUNC_P5(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5) \ + M68KFUNC_P5_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5) \ + { \ + type1 name1 = (type1) REG_##register1; \ + type2 name2 = (type2) REG_##register2; \ + type3 name3 = (type3) REG_##register3; \ + type4 name4 = (type4) REG_##register4; \ + type5 name5 = (type5) REG_##register5; + + #define M68KFUNC_P6(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6) \ + M68KFUNC_P6_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6) \ + { \ + type1 name1 = (type1) REG_##register1; \ + type2 name2 = (type2) REG_##register2; \ + type3 name3 = (type3) REG_##register3; \ + type4 name4 = (type4) REG_##register4; \ + type5 name5 = (type5) REG_##register5; \ + type6 name6 = (type6) REG_##register6; + + #define M68KFUNC_P7(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7) \ + M68KFUNC_P7_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7) \ + { \ + type1 name1 = (type1) REG_##register1; \ + type2 name2 = (type2) REG_##register2; \ + type3 name3 = (type3) REG_##register3; \ + type4 name4 = (type4) REG_##register4; \ + type5 name5 = (type5) REG_##register5; \ + type6 name6 = (type6) REG_##register6; \ + type7 name7 = (type7) REG_##register7; + + #define M68KFUNC_P8(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8) \ + M68KFUNC_P8_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8) \ + { \ + type1 name1 = (type1) REG_##register1; \ + type2 name2 = (type2) REG_##register2; \ + type3 name3 = (type3) REG_##register3; \ + type4 name4 = (type4) REG_##register4; \ + type5 name5 = (type5) REG_##register5; \ + type6 name6 = (type6) REG_##register6; \ + type7 name7 = (type7) REG_##register7; \ + type8 name8 = (type8) REG_##register8; + + #define M68KFUNC_P9(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8, \ + register9, type9, name9) \ + M68KFUNC_P9_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8, \ + register9, type9, name9) \ + { \ + type1 name1 = (type1) REG_##register1; \ + type2 name2 = (type2) REG_##register2; \ + type3 name3 = (type3) REG_##register3; \ + type4 name4 = (type4) REG_##register4; \ + type5 name5 = (type5) REG_##register5; \ + type6 name6 = (type6) REG_##register6; \ + type7 name7 = (type7) REG_##register7; \ + type8 name8 = (type8) REG_##register8; \ + type9 name9 = (type9) REG_##register9; + + //====================================================== + + #define M68KFUNC_END \ + } + + //====================================================== + + #define CALLM68KFUNC(funcname, libbase) \ + funcname() + + #define CALLM68KFUNC_P1(funcname, register1, arg1) \ + (*MyEmulHandle->EmulCallDirect68k)(( \ + REG_##register1 = (ULONG) arg1, \ + (APTR) funcname)) + + #define CALLM68KFUNC_P2(funcname, \ + register1, arg1, \ + register2, arg2) \ + (*MyEmulHandle->EmulCallDirect68k)(( \ + REG_##register1 = (ULONG) arg1, \ + REG_##register2 = (ULONG) arg2, \ + (APTR) funcname)) + + #define CALLM68KFUNC_P3(funcname, \ + register1, arg1, \ + register2, arg2, \ + register3, arg3) \ + (*MyEmulHandle->EmulCallDirect68k)(( \ + REG_##register1 = (ULONG) arg1, \ + REG_##register2 = (ULONG) arg2, \ + REG_##register3 = (ULONG) arg3, \ + (APTR) funcname)) + + #define CALLM68KFUNC_P4(funcname, \ + register1, arg1, \ + register2, arg2, \ + register3, arg3, \ + register4, arg4) \ + (*MyEmulHandle->EmulCallDirect68k)(( \ + REG_##register1 = (ULONG) arg1, \ + REG_##register2 = (ULONG) arg2, \ + REG_##register3 = (ULONG) arg3, \ + REG_##register4 = (ULONG) arg4, \ + (APTR) funcname)); + + #define CALLM68KFUNC_P5(funcname, \ + register1, arg1, \ + register2, arg2, \ + register3, arg3, \ + register4, arg4, \ + register5, arg5) \ + (*MyEmulHandle->EmulCallDirect68k)(( \ + REG_##register1 = (ULONG) arg1, \ + REG_##register2 = (ULONG) arg2, \ + REG_##register3 = (ULONG) arg3, \ + REG_##register4 = (ULONG) arg4, \ + REG_##register5 = (ULONG) arg5, \ + (APTR) funcname)) + + #define CALLM68KFUNC_P6(funcname, \ + register1, arg1, \ + register2, arg2, \ + register3, arg3, \ + register4, arg4, \ + register5, arg5, \ + register6, arg6) \ + (*MyEmulHandle->EmulCallDirect68k)(( \ + REG_##register1 = (ULONG) arg1, \ + REG_##register2 = (ULONG) arg2, \ + REG_##register3 = (ULONG) arg3, \ + REG_##register4 = (ULONG) arg4, \ + REG_##register5 = (ULONG) arg5, \ + REG_##register6 = (ULONG) arg6, \ + (APTR) funcname)) + + #define CALLM68KFUNC_P7(funcname, \ + register1, arg1, \ + register2, arg2, \ + register3, arg3, \ + register4, arg4, \ + register5, arg5, \ + register6, arg6, \ + register7, arg7) \ + (*MyEmulHandle->EmulCallDirect68k)(( \ + REG_##register1 = (ULONG) arg1, \ + REG_##register2 = (ULONG) arg2, \ + REG_##register3 = (ULONG) arg3, \ + REG_##register4 = (ULONG) arg4, \ + REG_##register5 = (ULONG) arg5, \ + REG_##register6 = (ULONG) arg6, \ + REG_##register7 = (ULONG) arg7, \ + (APTR) funcname)) + + #define CALLM68KFUNC_P8(funcname, \ + register1, arg1, \ + register2, arg2, \ + register3, arg3, \ + register4, arg4, \ + register5, arg5, \ + register6, arg6, \ + register7, arg7, \ + register8, arg8) \ + (*MyEmulHandle->EmulCallDirect68k)(( \ + REG_##register1 = (ULONG) arg1, \ + REG_##register2 = (ULONG) arg2, \ + REG_##register3 = (ULONG) arg3, \ + REG_##register4 = (ULONG) arg4, \ + REG_##register5 = (ULONG) arg5, \ + REG_##register6 = (ULONG) arg6, \ + REG_##register7 = (ULONG) arg7, \ + REG_##register8 = (ULONG) arg8, \ + (APTR) funcname)) + + #define CALLM68KFUNC_P9(funcname, \ + register1, arg1, \ + register2, arg2, \ + register3, arg3, \ + register4, arg4, \ + register5, arg5, \ + register6, arg6, \ + register7, arg7, \ + register8, arg8, \ + register9, arg9) \ + (*MyEmulHandle->EmulCallDirect68k)(( \ + REG_##register1 = (ULONG) arg1, \ + REG_##register2 = (ULONG) arg2, \ + REG_##register3 = (ULONG) arg3, \ + REG_##register4 = (ULONG) arg4, \ + REG_##register5 = (ULONG) arg5, \ + REG_##register6 = (ULONG) arg6, \ + REG_##register7 = (ULONG) arg7, \ + REG_##register8 = (ULONG) arg8, \ + REG_##register9 = (ULONG) arg9, \ + (APTR) funcname)) + + //====================================================== + + #define LIBFUNC_PROTO M68KFUNC_PROTO + #define LIBFUNC_P1_PROTO M68KFUNC_P1_PROTO + #define LIBFUNC_P2_PROTO M68KFUNC_P2_PROTO + #define LIBFUNC_P3_PROTO M68KFUNC_P3_PROTO + #define LIBFUNC_P4_PROTO M68KFUNC_P4_PROTO + #define LIBFUNC_P5_PROTO M68KFUNC_P5_PROTO + #define LIBFUNC_P6_PROTO M68KFUNC_P6_PROTO + #define LIBFUNC_P7_PROTO M68KFUNC_P7_PROTO + #define LIBFUNC_P8_PROTO M68KFUNC_P8_PROTO + #define LIBFUNC_P9_PROTO M68KFUNC_P9_PROTO + + #define LIBFUNC_P1_DPROTO M68KFUNC_P1_DPROTO + #define LIBFUNC_P2_DPROTO M68KFUNC_P2_DPROTO + #define LIBFUNC_P3_DPROTO M68KFUNC_P3_DPROTO + #define LIBFUNC_P4_DPROTO M68KFUNC_P4_DPROTO + #define LIBFUNC_P5_DPROTO M68KFUNC_P5_DPROTO + #define LIBFUNC_P6_DPROTO M68KFUNC_P6_DPROTO + #define LIBFUNC_P7_DPROTO M68KFUNC_P7_DPROTO + #define LIBFUNC_P8_DPROTO M68KFUNC_P8_DPROTO + #define LIBFUNC_P9_DPROTO M68KFUNC_P9_DPROTO + + #define LIBFUNC M68KFUNC + #define LIBFUNC_P1 M68KFUNC_P1 + #define LIBFUNC_P2 M68KFUNC_P2 + #define LIBFUNC_P3 M68KFUNC_P3 + #define LIBFUNC_P4 M68KFUNC_P4 + #define LIBFUNC_P5 M68KFUNC_P5 + #define LIBFUNC_P6 M68KFUNC_P6 + #define LIBFUNC_P7 M68KFUNC_P7 + #define LIBFUNC_P8 M68KFUNC_P8 + #define LIBFUNC_P9 M68KFUNC_P9 + + #define LIBFUNC_END M68KFUNC_END + + #define CALLLIBFUNC CALLM68KFUNC + #define CALLLIBFUNC_P1 CALLM68KFUNC_P1 + #define CALLLIBFUNC_P2 CALLM68KFUNC_P2 + #define CALLLIBFUNC_P3 CALLM68KFUNC_P3 + #define CALLLIBFUNC_P4 CALLM68KFUNC_P4 + #define CALLLIBFUNC_P5 CALLM68KFUNC_P5 + #define CALLLIBFUNC_P6 CALLM68KFUNC_P6 + #define CALLLIBFUNC_P7 CALLM68KFUNC_P7 + #define CALLLIBFUNC_P8 CALLM68KFUNC_P8 + #define CALLLIBFUNC_P9 CALLM68KFUNC_P9 + + //====================================================== + +#elif defined(__amigaos4__) + + //====================================================== + + #define PATCHFUNC(x) + #define STATIC_PATCHFUNC(x) + #define PATCH_NEWFUNC(x) (APTR) (x) + + //======================================================= + + #define M68KFUNC_PROTO(name, libbase, returntype) \ + returntype name##(void) + + + #define M68KFUNC_P1_PROTO(returntype, funcname, \ + register1, type1, name1) \ + returntype funcname(type1 name1) + + #define M68KFUNC_P2_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2) \ + returntype funcname( \ + type1 name1, \ + type2 name2) + + #define M68KFUNC_P3_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3) \ + returntype funcname( \ + type1 name1, \ + type2 name2, \ + type3 name3) + + #define M68KFUNC_P4_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4) \ + returntype funcname( \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4) + + #define M68KFUNC_P5_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5) \ + returntype funcname( \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5) + + #define M68KFUNC_P6_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6) \ + returntype funcname( \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5, \ + type6 name6) + + + #define M68KFUNC_P7_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7) \ + returntype funcname( \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5, \ + type6 name6, \ + type7 name7) + + #define M68KFUNC_P8_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8) \ + returntype funcname( \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5, \ + type6 name6, \ + type7 name7, \ + type8 name8) + + #define M68KFUNC_P9_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8, \ + register9, type9, name9) \ + returntype funcname( \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5, \ + type6 name6, \ + type7 name7, \ + type8 name8, \ + type9 name9) + + //===== prototypes for data items ====================== + + #define M68KFUNC_P1_DPROTO M68KFUNC_P1_PROTO + #define M68KFUNC_P2_DPROTO M68KFUNC_P2_PROTO + #define M68KFUNC_P3_DPROTO M68KFUNC_P3_PROTO + #define M68KFUNC_P4_DPROTO M68KFUNC_P4_PROTO + #define M68KFUNC_P5_DPROTO M68KFUNC_P5_PROTO + #define M68KFUNC_P6_DPROTO M68KFUNC_P6_PROTO + #define M68KFUNC_P7_DPROTO M68KFUNC_P7_PROTO + #define M68KFUNC_P8_DPROTO M68KFUNC_P8_PROTO + #define M68KFUNC_P9_DPROTO M68KFUNC_P9_PROTO + + //====================================================== + + #define M68KFUNC(name, libbase, returntype) \ + returntype name(void) { + + #define M68KFUNC_P1(returntype, funcname, \ + register1, type1, name1) \ + returntype funcname( \ + type1 name1) { + + #define M68KFUNC_P2(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2) \ + returntype funcname( \ + type1 name1, \ + type2 name2) { + + #define M68KFUNC_P3(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3) \ + returntype funcname( \ + type1 name1, \ + type2 name2, \ + type3 name3) { + + #define M68KFUNC_P4(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4) \ + returntype funcname( \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4) { + + #define M68KFUNC_P5(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5) \ + returntype funcname( \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5) { + + #define M68KFUNC_P6(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6) \ + returntype funcname( \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5, \ + type6 name6) { + + #define M68KFUNC_P7(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7) \ + returntype funcname( \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5, \ + type6 name6, \ + type7 name7) { + + #define M68KFUNC_P8(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8) \ + returntype funcname( \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5, \ + type6 name6, \ + type7 name7, \ + type8 name8) { + + #define M68KFUNC_P9(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8, \ + register9, type9, name9) \ + returntype funcname( \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5, \ + type6 name6, \ + type7 name7, \ + type8 name8, \ + type9 name9) { + + //====================================================== + + #define M68KFUNC_END \ + } + + //====================================================== + + #define CALLM68KFUNC(name, libbase) \ + name##() + + #define CALLM68KFUNC_P1(funcname, register1, arg1) \ + funcname(arg1) + + #define CALLM68KFUNC_P2(funcname, \ + register1, arg1, \ + register2, arg2) \ + funcname(arg1, arg2) + + #define CALLM68KFUNC_P3(funcname, \ + register1, arg1, \ + register2, arg2, \ + register3, arg3) \ + funcname(arg1, arg2, arg3) + + #define CALLM68KFUNC_P4(funcname, \ + register1, arg1, \ + register2, arg2, \ + register3, arg3, \ + register4, arg4) \ + funcname(arg1, arg2, arg3, arg4) + + #define CALLM68KFUNC_P5(funcname, \ + register1, arg1, \ + register2, arg2, \ + register3, arg3, \ + register4, arg4, \ + register5, arg5) \ + funcname(arg1, arg2, arg3, arg4, arg5) + + #define CALLM68KFUNC_P6(funcname, \ + register1, arg1, \ + register2, arg2, \ + register3, arg3, \ + register4, arg4, \ + register5, arg5, \ + register6, arg6) \ + funcname(arg1, arg2, arg3, arg4, arg5, arg6) + + #define CALLM68KFUNC_P7(funcname, \ + register1, arg1, \ + register2, arg2, \ + register3, arg3, \ + register4, arg4, \ + register5, arg5, \ + register6, arg6, \ + register7, arg7) \ + funcname(arg1, arg2, arg3, arg4, arg5, arg6, arg7) + + #define CALLM68KFUNC_P8(funcname, \ + register1, arg1, \ + register2, arg2, \ + register3, arg3, \ + register4, arg4, \ + register5, arg5, \ + register6, arg6, \ + register7, arg7, \ + register8, arg8) \ + funcname(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) + + #define CALLM68KFUNC_P9(funcname, \ + register1, arg1, \ + register2, arg2, \ + register3, arg3, \ + register4, arg4, \ + register5, arg5, \ + register6, arg6, \ + register7, arg7, \ + register8, arg8, \ + register9, arg9) \ + funcname(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) + + //====================================================== + + #define LIBFUNC_PROTO(name, libbase, returntype) \ + returntype name(struct Interface *self) + + + #define LIBFUNC_P1_PROTO(returntype, funcname, \ + register1, type1, name1) \ + returntype funcname(struct Interface *self) + + #define LIBFUNC_P2_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2) \ + returntype funcname( \ + struct Interface *self, \ + type1 name1) + + #define LIBFUNC_P3_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3) \ + returntype funcname( \ + struct Interface *self, \ + type1 name1, \ + type2 name2) + + #define LIBFUNC_P4_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4) \ + returntype funcname( \ + struct Interface *self, \ + type1 name1, \ + type2 name2, \ + type3 name3) + + #define LIBFUNC_P5_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5) \ + returntype funcname( \ + struct Interface *self, \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4) + + #define LIBFUNC_P6_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6) \ + returntype funcname( \ + struct Interface *self, \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5) + + #define LIBFUNC_P7_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7) \ + returntype funcname( \ + struct Interface *self, \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5, \ + type6 name6) + + #define LIBFUNC_P8_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8) \ + returntype funcname( \ + struct Interface *self, \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5, \ + type6 name6, \ + type7 name7) + + #define LIBFUNC_P9_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8, \ + register9, type9, name9) \ + returntype funcname( \ + struct Interface *self, \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5, \ + type6 name6, \ + type7 name7, \ + type8 name8) + + //===== prototypes for data items ====================== + + #define LIBFUNC_P1_DPROTO LIBFUNC_P1_PROTO + #define LIBFUNC_P2_DPROTO LIBFUNC_P2_PROTO + #define LIBFUNC_P3_DPROTO LIBFUNC_P3_PROTO + #define LIBFUNC_P4_DPROTO LIBFUNC_P4_PROTO + #define LIBFUNC_P5_DPROTO LIBFUNC_P5_PROTO + #define LIBFUNC_P6_DPROTO LIBFUNC_P6_PROTO + #define LIBFUNC_P7_DPROTO LIBFUNC_P7_PROTO + #define LIBFUNC_P8_DPROTO LIBFUNC_P8_PROTO + #define LIBFUNC_P9_DPROTO LIBFUNC_P9_PROTO + + //====================================================== + + #define LIBFUNC(name, libbase, returntype) \ + returntype name(struct Interface *self) { \ + struct Library *libbase = (struct Library *)self->Data.LibBase; + + #define LIBFUNC_P1(returntype, funcname, \ + register1, type1, name1) \ + returntype funcname( \ + struct Interface *self) { \ + type1 name1 = (type1)self->Data.LibBase; + + #define LIBFUNC_P2(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2) \ + returntype funcname( \ + struct Interface *self, \ + type1 name1) { \ + type2 name2 = (type2)self->Data.LibBase; + + #define LIBFUNC_P3(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3) \ + returntype funcname( \ + struct Interface *self, \ + type1 name1, \ + type2 name2) { \ + type3 name3 = (type3)self->Data.LibBase; + + #define LIBFUNC_P4(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4) \ + returntype funcname( \ + struct Interface *self, \ + type1 name1, \ + type2 name2, \ + type3 name3) { \ + type4 name4 = (type4)self->Data.LibBase; + + #define LIBFUNC_P5(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5) \ + returntype funcname( \ + struct Interface *self, \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4) { \ + type5 name5 = (type5)self->Data.LibBase; + + #define LIBFUNC_P6(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6) \ + returntype funcname( \ + struct Interface *self, \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5) { \ + type6 name6 = (type6)self->Data.LibBase; + + #define LIBFUNC_P7(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7) \ + returntype funcname( \ + struct Interface *self, \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5, \ + type6 name6) { \ + type7 name7 = (type7)self->Data.LibBase; + + #define LIBFUNC_P8(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8) \ + returntype funcname( \ + struct Interface *self, \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5, \ + type6 name6, \ + type7 name7) { \ + type8 name8 = (type8)self->Data.LibBase; + + #define LIBFUNC_P9(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8, \ + register9, type9, name9) \ + returntype funcname( \ + struct Interface *self, \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5, \ + type6 name6, \ + type7 name7, \ + type8 name8) { \ + type9 name9 = (type9)self->Data.LibBase; + + //====================================================== + + #define LIBFUNC_END \ + } + + //====================================================== + + #define LIBFUNC_P1VA_PROTO(returntype, funcname, \ + register1, type1, name1) \ + returntype VARARGS68K funcname(struct Interface *self, ...) + + #define LIBFUNC_P2VA_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2) \ + returntype VARARGS68K funcname( \ + struct Interface *self, \ + type1 name1, \ + ...) + + #define LIBFUNC_P3VA_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3) \ + returntype VARARGS68K funcname( \ + struct Interface *self, \ + type1 name1, \ + type2 name2, \ + ...) + + #define LIBFUNC_P4VA_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4) \ + returntype VARARGS68K funcname( \ + struct Interface *self, \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + ...) + + #define LIBFUNC_P5VA_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5) \ + returntype VARARGS68K funcname( \ + struct Interface *self, \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + ...) + + #define LIBFUNC_P6VA_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6) \ + returntype VARARGS68K funcname( \ + struct Interface *self, \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5, \ + ...) + + #define LIBFUNC_P7VA_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7) \ + returntype VARARGS68K funcname( \ + struct Interface *self, \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5, \ + type6 name6, \ + ...) + + #define LIBFUNC_P8VA_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8) \ + returntype VARARGS68K funcname( \ + struct Interface *self, \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5, \ + type6 name6, \ + type7 name7, \ + ...) + + #define LIBFUNC_P9VA_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8, \ + register9, type9, name9) \ + returntype VARARGS68K funcname( \ + struct Interface *self, \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5, \ + type6 name6, \ + type7 name7, \ + type8 name8, \ + ...) + + //====================================================== + + #define LIBFUNC_P1VA(returntype, funcname, \ + register1, type1, name1) \ + returntype VARARGS68K funcname( \ + struct Interface *self, \ + ...) { \ + type1 name1 = (type1)self->Data.LibBase; + + #define LIBFUNC_P2VA(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2) \ + returntype VARARGS68K funcname( \ + struct Interface *self, \ + type1 name1, \ + ...) { \ + type2 name2 = (type2)self->Data.LibBase; + + #define LIBFUNC_P3VA(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3) \ + returntype VARARGS68K funcname( \ + struct Interface *self, \ + type1 name1, \ + type2 name2, \ + ...) { \ + type3 name3 = (type3)self->Data.LibBase; + + #define LIBFUNC_P4VA(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4) \ + returntype VARARGS68K funcname( \ + struct Interface *self, \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + ...) { \ + type4 name4 = (type4)self->Data.LibBase; + + #define LIBFUNC_P5VA(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5) \ + returntype VARARGS68K funcname( \ + struct Interface *self, \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + ...) { \ + type5 name5 = (type5)self->Data.LibBase; + + #define LIBFUNC_P6VA(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6) \ + returntype VARARGS68K funcname( \ + struct Interface *self, \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5, \ + ...) { \ + type6 name6 = (type6)self->Data.LibBase; + + #define LIBFUNC_P7VA(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7) \ + returntype VARARGS68K funcname( \ + struct Interface *self, \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5, \ + type6 name6, \ + ...) { \ + type7 name7 = (type7)self->Data.LibBase; + + #define LIBFUNC_P8VA(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8) \ + returntype VARARGS68K funcname( \ + struct Interface *self, \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5, \ + type6 name6, \ + type7 name7, \ + ...) { \ + type8 name8 = (type8)self->Data.LibBase; + + #define LIBFUNC_P9VA(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8, \ + register9, type9, name9) \ + returntype VARARGS68K funcname( \ + struct Interface *self, \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5, \ + type6 name6, \ + type7 name7, \ + type8 name8, \ + ...) { \ + type9 name9 = (type9) self->Data.LibBase; + + //====================================================== + + #define EXTLIBBASE(base) ((struct ExtendedLibrary *) ( (ULONG)base + ((struct Library *)base)->lib_PosSize) ) + #define IFACEBASE(base) ( EXTLIBBASE(base)->MainIFace ) + + #define CALLLIBFUNC(name,base) \ + name(IFACEBASE(base)) + + #define CALLLIBFUNC_P1(name, \ + register1, arg1) \ + name(IFACEBASE(arg1)) + + #define CALLLIBFUNC_P2(name, \ + register1, arg1, \ + register2, arg2) \ + name(IFACEBASE(arg2), arg1) + + #define CALLLIBFUNC_P3(name, \ + register1, arg1, \ + register2, arg2, \ + register3, arg3) \ + name(IFACEBASE(arg3), arg1, arg2) + + #define CALLLIBFUNC_P4(name, \ + register1, arg1, \ + register2, arg2, \ + register3, arg3, \ + register4, arg4) \ + name(IFACEBASE(arg4), arg1, arg2, arg3) + + #define CALLLIBFUNC_P5(name, \ + register1, arg1, \ + register2, arg2, \ + register3, arg3, \ + register4, arg4, \ + register5, arg5) \ + name(IFACEBASE(arg5), arg1, arg2, arg3, arg4) + + #define CALLLIBFUNC_P6(name, \ + register1, arg1, \ + register2, arg2, \ + register3, arg3, \ + register4, arg4, \ + register5, arg5, \ + register6, arg6) \ + name(IFACEBASE(arg6), arg1, arg2, arg3, arg4, arg5) + + #define CALLLIBFUNC_P7(name, \ + register1, arg1, \ + register2, arg2, \ + register3, arg3, \ + register4, arg4, \ + register5, arg5, \ + register6, arg6, \ + register7, arg7) \ + name(IFACEBASE(arg7), arg1, arg2, arg3, arg4, arg5, arg6) + + #define CALLLIBFUNC_P8(name, \ + register1, arg1, \ + register2, arg2, \ + register3, arg3, \ + register4, arg4, \ + register5, arg5, \ + register6, arg6, \ + register7, arg7, \ + register8, arg8) \ + name(IFACEBASE(arg8), arg1, arg2, arg3, arg4, arg5, arg6, arg7) + + #define CALLLIBFUNC_P9(name, \ + register1, arg1, \ + register2, arg2, \ + register3, arg3, \ + register4, arg4, \ + register5, arg5, \ + register6, arg6, \ + register7, arg7, \ + register8, arg8, \ + register9, arg9) \ + name(IFACEBASE(arg9), arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) + + //====================================================== + +#elif defined(__AROS__) + + #include + #include + + //====================================================== + + #define PATCHFUNC(x) + #define STATIC_PATCHFUNC(x) + #define PATCH_NEWFUNC(x) (APTR) (x) + + //====================================================== + + #define M68KFUNC_P1_PROTO(returntype, funcname, \ + register1, type1, name1) \ + returntype funcname( \ + type1 name1) + + #define M68KFUNC_P2_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2) \ + returntype funcname( \ + type1 name1, \ + type2 name2) + + #define M68KFUNC_P3_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3) \ + returntype funcname( \ + type1 name1, \ + type2 name2, \ + type3 name3) + + #define M68KFUNC_P4_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4) \ + returntype funcname( \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4) + + #define M68KFUNC_P5_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5) \ + returntype funcname( \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5) + + #define M68KFUNC_P6_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6) \ + returntype funcname( \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5, \ + type6 name6) + + #define M68KFUNC_P7_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7) \ + returntype funcname( \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5, \ + type6 name6, \ + type7 name7) + + #define M68KFUNC_P8_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8) \ + returntype funcname( \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5, \ + type6 name6, \ + type7 name7, \ + type8 name8) + + #define M68KFUNC_P9_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8, \ + register9, type9, name9) \ + returntype funcname( \ + type1 name1, \ + type2 name2, \ + type3 name3, \ + type4 name4, \ + type5 name5, \ + type6 name6, \ + type7 name7, \ + type8 name8, \ + type9 name9) + +//====================================================== + + #define M68KFUNC_P1(returntype, funcname, \ + register1, type1, name1) \ + M68KFUNC_P1_PROTO(returntype, funcname, \ + register1, type1, name1) \ + { + + #define M68KFUNC_P2(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2) \ + M68KFUNC_P2_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2) \ + { + + #define M68KFUNC_P3(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3) \ + M68KFUNC_P3_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3) \ + { + + #define M68KFUNC_P4(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4) \ + M68KFUNC_P4_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4) \ + { + + #define M68KFUNC_P5(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5) \ + M68KFUNC_P5_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5) \ + { + + #define M68KFUNC_P6(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6) \ + M68KFUNC_P6_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6) \ + { + + #define M68KFUNC_P7(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7) \ + M68KFUNC_P7_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7) \ + { + + #define M68KFUNC_P8(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8) \ + M68KFUNC_P8_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8) \ + { + + #define M68KFUNC_P9(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8, \ + register9, type9, name9) \ + M68KFUNC_P9_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8, \ + register9, type9, name9) \ + { + + //======================================================= + + #define M68KFUNC_END \ + } + + //====================================================== + + #define LIBFUNC_PROTO(funcname, libbase, returntype) \ + AROS_LD0(returntype, funcname, \ + struct Library *, libbase, 0, Dummy) + + #define LIBFUNC_P1_PROTO(returntype, funcname, \ + register1, type1, name1) \ + AROS_LD0(returntype, funcname, \ + type1, name1, 0, name1) + + #define LIBFUNC_P2_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2) \ + AROS_LD1(returntype, funcname, \ + AROS_LPA(type1, name1, register1), \ + type2, name2, 0, name2) + + #define LIBFUNC_P3_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3) \ + AROS_LD2(returntype, funcname, \ + AROS_LPA(type1, name1, register1), \ + AROS_LPA(type2, name2, register2), \ + type3, name3, 0, name3) + + #define LIBFUNC_P4_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4) \ + AROS_LD3(returntype, funcname, \ + AROS_LPA(type1, name1, register1), \ + AROS_LPA(type2, name2, register2), \ + AROS_LPA(type3, name3, register3), \ + type4, name4, 0, name4) + + #define LIBFUNC_P5_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5) \ + AROS_LD4(returntype, funcname, \ + AROS_LPA(type1, name1, register1), \ + AROS_LPA(type2, name2, register2), \ + AROS_LPA(type3, name3, register3), \ + AROS_LPA(type4, name4, register4), \ + type5, name5, 0, name5) + + #define LIBFUNC_P6_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6) \ + AROS_LD5(returntype, funcname, \ + AROS_LPA(type1, name1, register1), \ + AROS_LPA(type2, name2, register2), \ + AROS_LPA(type3, name3, register3), \ + AROS_LPA(type4, name4, register4), \ + AROS_LPA(type5, name5, register5), \ + type6, name6, 0, name6) + + #define LIBFUNC_P7_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7) \ + AROS_LD6(returntype, funcname, \ + AROS_LPA(type1, name1, register1), \ + AROS_LPA(type2, name2, register2), \ + AROS_LPA(type3, name3, register3), \ + AROS_LPA(type4, name4, register4), \ + AROS_LPA(type5, name5, register5), \ + AROS_LPA(type6, name6, register6), \ + type7, name7, 0, name7) + + #define LIBFUNC_P8_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8) \ + AROS_LD7(returntype, funcname, \ + AROS_LPA(type1, name1, register1), \ + AROS_LPA(type2, name2, register2), \ + AROS_LPA(type3, name3, register3), \ + AROS_LPA(type4, name4, register4), \ + AROS_LPA(type5, name5, register5), \ + AROS_LPA(type6, name6, register6), \ + AROS_LPA(type7, name7, register7), \ + type8, name8, 0, name8) + + #define LIBFUNC_P9_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8, \ + register9, type9, name9) \ + AROS_LD8(returntype, funcname, \ + AROS_LPA(type1, name1, register1), \ + AROS_LPA(type2, name2, register2), \ + AROS_LPA(type3, name3, register3), \ + AROS_LPA(type4, name4, register4), \ + AROS_LPA(type5, name5, register5), \ + AROS_LPA(type6, name6, register6), \ + AROS_LPA(type7, name7, register7), \ + AROS_LPA(type8, name8, register8), \ + type9, name9, 0, name9) + + //====================================================== + + #define LIBFUNC(funcname, libbase, returntype) \ + AROS_LH0(returntype, funcname, \ + struct Library *, libbase, 0, Dummy) \ + { \ + AROS_LIBFUNC_INIT + + #define LIBFUNC_P1(returntype, funcname, \ + register1, type1, name1) \ + AROS_LH0(returntype, funcname, \ + type1, name1, 0, name1) \ + { \ + AROS_LIBFUNC_INIT + + #define LIBFUNC_P2(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2) \ + AROS_LH1(returntype, funcname, \ + AROS_LHA(type1, name1, register1), \ + type2, name2, 0, name2) \ + { \ + AROS_LIBFUNC_INIT + + #define LIBFUNC_P3(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3) \ + AROS_LH2(returntype, funcname, \ + AROS_LHA(type1, name1, register1), \ + AROS_LHA(type2, name2, register2), \ + type3, name3, 0, name3) \ + { \ + AROS_LIBFUNC_INIT + + #define LIBFUNC_P4(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4) \ + AROS_LH3(returntype, funcname, \ + AROS_LHA(type1, name1, register1), \ + AROS_LHA(type2, name2, register2), \ + AROS_LHA(type3, name3, register3), \ + type4, name4, 0, name4) \ + { \ + AROS_LIBFUNC_INIT + + #define LIBFUNC_P5(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5) \ + AROS_LH4(returntype, funcname, \ + AROS_LHA(type1, name1, register1), \ + AROS_LHA(type2, name2, register2), \ + AROS_LHA(type3, name3, register3), \ + AROS_LHA(type4, name4, register4), \ + type5, name5, 0, name5) \ + { \ + AROS_LIBFUNC_INIT + + #define LIBFUNC_P6(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6) \ + AROS_LH5(returntype, funcname, \ + AROS_LHA(type1, name1, register1), \ + AROS_LHA(type2, name2, register2), \ + AROS_LHA(type3, name3, register3), \ + AROS_LHA(type4, name4, register4), \ + AROS_LHA(type5, name5, register5), \ + type6, name6, 0, name6) \ + { \ + AROS_LIBFUNC_INIT + + #define LIBFUNC_P7(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7) \ + AROS_LH6(returntype, funcname, \ + AROS_LHA(type1, name1, register1), \ + AROS_LHA(type2, name2, register2), \ + AROS_LHA(type3, name3, register3), \ + AROS_LHA(type4, name4, register4), \ + AROS_LHA(type5, name5, register5), \ + AROS_LHA(type6, name6, register6), \ + type7, name7, 0, name7) \ + { \ + AROS_LIBFUNC_INIT + + #define LIBFUNC_P8(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8) \ + AROS_LH7(returntype, funcname, \ + AROS_LHA(type1, name1, register1), \ + AROS_LHA(type2, name2, register2), \ + AROS_LHA(type3, name3, register3), \ + AROS_LHA(type4, name4, register4), \ + AROS_LHA(type5, name5, register5), \ + AROS_LHA(type6, name6, register6), \ + AROS_LHA(type7, name7, register7), \ + type8, name8, 0, name8) \ + { \ + AROS_LIBFUNC_INIT + + #define LIBFUNC_P9(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8, \ + register9, type9, name9) \ + AROS_LH8(returntype, funcname, \ + AROS_LHA(type1, name1, register1), \ + AROS_LHA(type2, name2, register2), \ + AROS_LHA(type3, name3, register3), \ + AROS_LHA(type4, name4, register4), \ + AROS_LHA(type5, name5, register5), \ + AROS_LHA(type6, name6, register6), \ + AROS_LHA(type7, name7, register7), \ + AROS_LHA(type8, name8, register8), \ + type9, name9, 0, name9) \ + { \ + AROS_LIBFUNC_INIT + + //====================================================== + + #define LIBFUNC_END \ + AROS_LIBFUNC_EXIT \ + } + + //====================================================== + +#else + + //====================================================== + + #define REGPARM_A0 REG(a0 + #define REGPARM_A1 REG(a1 + #define REGPARM_A2 REG(a2 + #define REGPARM_A3 REG(a3 + #define REGPARM_A4 REG(a4 + #define REGPARM_A5 REG(a5 + #define REGPARM_A6 REG(a6 + + #define REGPARM_D0 REG(d0 + #define REGPARM_D1 REG(d1 + #define REGPARM_D2 REG(d2 + #define REGPARM_D3 REG(d3 + #define REGPARM_D4 REG(d4 + #define REGPARM_D5 REG(d5 + #define REGPARM_D6 REG(d6 + #define REGPARM_D7 REG(d7 + + //====================================================== + + #define PATCHFUNC(x) + #define STATIC_PATCHFUNC(x) + #define PATCH_NEWFUNC(x) (APTR) (x) + + //====================================================== + + #define M68KFUNC_PROTO(name, libbase, returntype) \ + SAVEDS(returntype##) ASM INTERRUPT name##(REG(a6, struct Library *libbase##)) + + #define M68KFUNC_P1_PROTO(returntype, funcname, \ + register1, type1, name1) \ + SAVEDS(returntype) ASM INTERRUPT funcname( \ + REGPARM_##register1, type1 name1)) + + #define M68KFUNC_P2_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2) \ + SAVEDS(returntype) ASM INTERRUPT funcname( \ + REGPARM_##register1, type1 name1), \ + REGPARM_##register2, type2 name2)) + + #define M68KFUNC_P3_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3) \ + SAVEDS(returntype) ASM INTERRUPT funcname( \ + REGPARM_##register1, type1 name1), \ + REGPARM_##register2, type2 name2), \ + REGPARM_##register3, type3 name3)) + + #define M68KFUNC_P4_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4) \ + SAVEDS(returntype) ASM INTERRUPT funcname( \ + REGPARM_##register1, type1 name1), \ + REGPARM_##register2, type2 name2), \ + REGPARM_##register3, type3 name3), \ + REGPARM_##register4, type4 name4)) + + #define M68KFUNC_P5_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5) \ + SAVEDS(returntype) ASM INTERRUPT funcname( \ + REGPARM_##register1, type1 name1), \ + REGPARM_##register2, type2 name2), \ + REGPARM_##register3, type3 name3), \ + REGPARM_##register4, type4 name4), \ + REGPARM_##register5, type5 name5)) + + #define M68KFUNC_P6_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6) \ + SAVEDS(returntype) ASM INTERRUPT funcname( \ + REGPARM_##register1, type1 name1), \ + REGPARM_##register2, type2 name2), \ + REGPARM_##register3, type3 name3), \ + REGPARM_##register4, type4 name4), \ + REGPARM_##register5, type5 name5), \ + REGPARM_##register6, type6 name6)) \ + + #define M68KFUNC_P7_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7) \ + SAVEDS(returntype) ASM INTERRUPT funcname( \ + REGPARM_##register1, type1 name1), \ + REGPARM_##register2, type2 name2), \ + REGPARM_##register3, type3 name3), \ + REGPARM_##register4, type4 name4), \ + REGPARM_##register5, type5 name5), \ + REGPARM_##register6, type6 name6), \ + REGPARM_##register7, type7 name7)) + + #define M68KFUNC_P8_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8) \ + SAVEDS(returntype) ASM INTERRUPT funcname( \ + REGPARM_##register1, type1 name1), \ + REGPARM_##register2, type2 name2), \ + REGPARM_##register3, type3 name3), \ + REGPARM_##register4, type4 name4), \ + REGPARM_##register5, type5 name5), \ + REGPARM_##register6, type6 name6), \ + REGPARM_##register7, type7 name7), \ + REGPARM_##register8, type8 name8)) + + #define M68KFUNC_P9_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8, \ + register9, type9, name9) \ + SAVEDS(returntype) ASM INTERRUPT funcname( \ + REGPARM_##register1, type1 name1), \ + REGPARM_##register2, type2 name2), \ + REGPARM_##register3, type3 name3), \ + REGPARM_##register4, type4 name4), \ + REGPARM_##register5, type5 name5), \ + REGPARM_##register6, type6 name6), \ + REGPARM_##register7, type7 name7), \ + REGPARM_##register8, type8 name8), \ + REGPARM_##register9, type9 name9)) + + //===== prototypes for data items (no SAVEDS, no INTERRUPT) ==== + + #define M68KFUNC_P1_DPROTO(returntype, funcname, \ + register1, type1, name1) \ + returntype ASM funcname( \ + REGPARM_##register1, type1 name1)) + + #define M68KFUNC_P2_DPROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2) \ + returntype ASM funcname( \ + REGPARM_##register1, type1 name1), \ + REGPARM_##register2, type2 name2)) + + #define M68KFUNC_P3_DPROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3) \ + returntype ASM funcname( \ + REGPARM_##register1, type1 name1), \ + REGPARM_##register2, type2 name2), \ + REGPARM_##register3, type3 name3)) + + #define M68KFUNC_P4_DPROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4) \ + returntype ASM funcname( \ + REGPARM_##register1, type1 name1), \ + REGPARM_##register2, type2 name2), \ + REGPARM_##register3, type3 name3), \ + REGPARM_##register4, type4 name4)) + + #define M68KFUNC_P5_DPROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5) \ + returntype ASM funcname( \ + REGPARM_##register1, type1 name1), \ + REGPARM_##register2, type2 name2), \ + REGPARM_##register3, type3 name3), \ + REGPARM_##register4, type4 name4), \ + REGPARM_##register5, type5 name5)) + + #define M68KFUNC_P6_DPROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6) \ + returntype ASM funcname( \ + REGPARM_##register1, type1 name1), \ + REGPARM_##register2, type2 name2), \ + REGPARM_##register3, type3 name3), \ + REGPARM_##register4, type4 name4), \ + REGPARM_##register5, type5 name5), \ + REGPARM_##register6, type6 name6)) \ + + #define M68KFUNC_P7_DPROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7) \ + returntype ASM funcname( \ + REGPARM_##register1, type1 name1), \ + REGPARM_##register2, type2 name2), \ + REGPARM_##register3, type3 name3), \ + REGPARM_##register4, type4 name4), \ + REGPARM_##register5, type5 name5), \ + REGPARM_##register6, type6 name6), \ + REGPARM_##register7, type7 name7)) + + #define M68KFUNC_P8_DPROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8) \ + returntype ASM funcname( \ + REGPARM_##register1, type1 name1), \ + REGPARM_##register2, type2 name2), \ + REGPARM_##register3, type3 name3), \ + REGPARM_##register4, type4 name4), \ + REGPARM_##register5, type5 name5), \ + REGPARM_##register6, type6 name6), \ + REGPARM_##register7, type7 name7), \ + REGPARM_##register8, type8 name8)) + + #define M68KFUNC_P9_DPROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8, \ + register9, type9, name9) \ + returntype ASM funcname( \ + REGPARM_##register1, type1 name1), \ + REGPARM_##register2, type2 name2), \ + REGPARM_##register3, type3 name3), \ + REGPARM_##register4, type4 name4), \ + REGPARM_##register5, type5 name5), \ + REGPARM_##register6, type6 name6), \ + REGPARM_##register7, type7 name7), \ + REGPARM_##register8, type8 name8), \ + REGPARM_##register9, type9 name9)) + + //======================================================= + + #define M68KFUNC(name, libbase, returntype) \ + M68KFUNC_PROTO(name, libbase, returntype) \ + { + + #define M68KFUNC_P1(returntype, funcname, \ + register1, type1, name1) \ + M68KFUNC_P1_PROTO(returntype, funcname, \ + register1, type1, name1) \ + { + + #define M68KFUNC_P2(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2) \ + M68KFUNC_P2_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2) \ + { + + #define M68KFUNC_P3(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3) \ + M68KFUNC_P3_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3) \ + { + + #define M68KFUNC_P4(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4) \ + M68KFUNC_P4_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4) \ + { + + #define M68KFUNC_P5(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5) \ + M68KFUNC_P5_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5) \ + { + + #define M68KFUNC_P6(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6) \ + M68KFUNC_P6_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6) \ + { + + + #define M68KFUNC_P7(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7) \ + M68KFUNC_P7_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7) \ + { + + #define M68KFUNC_P8(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8) \ + M68KFUNC_P8_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8) \ + { + + #define M68KFUNC_P9(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8, \ + register9, type9, name9) \ + M68KFUNC_P9_PROTO(returntype, funcname, \ + register1, type1, name1, \ + register2, type2, name2, \ + register3, type3, name3, \ + register4, type4, name4, \ + register5, type5, name5, \ + register6, type6, name6, \ + register7, type7, name7, \ + register8, type8, name8, \ + register9, type9, name9) \ + { + + //======================================================= + + #define M68KFUNC_END \ + } + + //======================================================= + + #define CALLM68KFUNC(name, libbase) \ + name##(libbase) + + #define CALLM68KFUNC_P1(funcname, register1, arg1) \ + funcname(arg1); + + #define CALLM68KFUNC_P2(funcname, \ + register1, arg1, \ + register2, arg2) \ + funcname(arg1, arg2) + + #define CALLM68KFUNC_P3(funcname, \ + register1, arg1, \ + register2, arg2, \ + register3, arg3) \ + funcname(arg1, arg2, arg3) + + #define CALLM68KFUNC_P4(funcname, \ + register1, arg1, \ + register2, arg2, \ + register3, arg3, \ + register4, arg4) \ + funcname(arg1, arg2, arg3, arg4) + + #define CALLM68KFUNC_P5(funcname, \ + register1, arg1, \ + register2, arg2, \ + register3, arg3, \ + register4, arg4, \ + register5, arg5) \ + funcname(arg1, arg2, arg3, arg4, arg5) + + #define CALLM68KFUNC_P6(funcname, \ + register1, arg1, \ + register2, arg2, \ + register3, arg3, \ + register4, arg4, \ + register5, arg5, \ + register6, arg6) \ + funcname(arg1, arg2, arg3, arg4, arg5, arg6) + + #define CALLM68KFUNC_P7(funcname, \ + register1, arg1, \ + register2, arg2, \ + register3, arg3, \ + register4, arg4, \ + register5, arg5, \ + register6, arg6, \ + register7, arg7) \ + funcname(arg1, arg2, arg3, arg4, arg5, arg6, arg7) + + #define CALLM68KFUNC_P8(funcname, \ + register1, arg1, \ + register2, arg2, \ + register3, arg3, \ + register4, arg4, \ + register5, arg5, \ + register6, arg6, \ + register7, arg7, \ + register8, arg8) \ + funcname(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) + + #define CALLM68KFUNC_P9(funcname, \ + register1, arg1, \ + register2, arg2, \ + register3, arg3, \ + register4, arg4, \ + register5, arg5, \ + register6, arg6, \ + register7, arg7, \ + register8, arg8, \ + register9, arg9) \ + funcname(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) + + //====================================================== + + #define LIBFUNC_PROTO M68KFUNC_PROTO + #define LIBFUNC_P1_PROTO M68KFUNC_P1_PROTO + #define LIBFUNC_P2_PROTO M68KFUNC_P2_PROTO + #define LIBFUNC_P3_PROTO M68KFUNC_P3_PROTO + #define LIBFUNC_P4_PROTO M68KFUNC_P4_PROTO + #define LIBFUNC_P5_PROTO M68KFUNC_P5_PROTO + #define LIBFUNC_P6_PROTO M68KFUNC_P6_PROTO + #define LIBFUNC_P7_PROTO M68KFUNC_P7_PROTO + #define LIBFUNC_P8_PROTO M68KFUNC_P8_PROTO + #define LIBFUNC_P9_PROTO M68KFUNC_P9_PROTO + + #define LIBFUNC_P1_DPROTO M68KFUNC_P1_DPROTO + #define LIBFUNC_P2_DPROTO M68KFUNC_P2_DPROTO + #define LIBFUNC_P3_DPROTO M68KFUNC_P3_DPROTO + #define LIBFUNC_P4_DPROTO M68KFUNC_P4_DPROTO + #define LIBFUNC_P5_DPROTO M68KFUNC_P5_DPROTO + #define LIBFUNC_P6_DPROTO M68KFUNC_P6_DPROTO + #define LIBFUNC_P7_DPROTO M68KFUNC_P7_DPROTO + #define LIBFUNC_P8_DPROTO M68KFUNC_P8_DPROTO + #define LIBFUNC_P9_DPROTO M68KFUNC_P9_DPROTO + + #define LIBFUNC M68KFUNC + #define LIBFUNC_P1 M68KFUNC_P1 + #define LIBFUNC_P2 M68KFUNC_P2 + #define LIBFUNC_P3 M68KFUNC_P3 + #define LIBFUNC_P4 M68KFUNC_P4 + #define LIBFUNC_P5 M68KFUNC_P5 + #define LIBFUNC_P6 M68KFUNC_P6 + #define LIBFUNC_P7 M68KFUNC_P7 + #define LIBFUNC_P8 M68KFUNC_P8 + #define LIBFUNC_P9 M68KFUNC_P9 + + #define LIBFUNC_END M68KFUNC_END + + #define CALLLIBFUNC CALLM68KFUNC + #define CALLLIBFUNC_P1 CALLM68KFUNC_P1 + #define CALLLIBFUNC_P2 CALLM68KFUNC_P2 + #define CALLLIBFUNC_P3 CALLM68KFUNC_P3 + #define CALLLIBFUNC_P4 CALLM68KFUNC_P4 + #define CALLLIBFUNC_P5 CALLM68KFUNC_P5 + #define CALLLIBFUNC_P6 CALLM68KFUNC_P6 + #define CALLLIBFUNC_P7 CALLM68KFUNC_P7 + #define CALLLIBFUNC_P8 CALLM68KFUNC_P8 + #define CALLLIBFUNC_P9 CALLM68KFUNC_P9 + + //====================================================== + +#endif + +// ============================================================== + +#if !defined(__AROS__) && !defined(__MORPHOS__) +// IPTR is an integer type which is large enough to store a pointer +#undef IPTR +#undef SIPTR + +#if defined(__SASC) +typedef LONG IPTR; +#else //defined(__SASC) +typedef ULONG IPTR; +#endif //defined(__SASC) + +typedef LONG SIPTR; +#endif + +// ============================================================== + +#if defined(__AROS__) + #include + #define SCA_WORD2BE(x) AROS_WORD2BE(x) + #define SCA_LONG2BE(x) AROS_LONG2BE(x) + #define SCA_BE2WORD(x) AROS_BE2WORD(x) + #define SCA_BE2LONG(x) AROS_BE2LONG(x) +#else + #define SCA_WORD2BE(x) (x) + #define SCA_LONG2BE(x) (x) + #define SCA_BE2WORD(x) (x) + #define SCA_BE2LONG(x) (x) +#endif + +#endif /* DEFS_H */ diff --git a/scalos/include/ffmpeg/avformat.h b/scalos/include/ffmpeg/avformat.h new file mode 100644 index 000000000..acdcec425 --- /dev/null +++ b/scalos/include/ffmpeg/avformat.h @@ -0,0 +1,1157 @@ +/* + * copyright (c) 2001 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVFORMAT_AVFORMAT_H +#define AVFORMAT_AVFORMAT_H + +#define LIBAVFORMAT_VERSION_MAJOR 52 +#define LIBAVFORMAT_VERSION_MINOR 23 +#define LIBAVFORMAT_VERSION_MICRO 1 + +#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ + LIBAVFORMAT_VERSION_MINOR, \ + LIBAVFORMAT_VERSION_MICRO) +#define LIBAVFORMAT_VERSION AV_VERSION(LIBAVFORMAT_VERSION_MAJOR, \ + LIBAVFORMAT_VERSION_MINOR, \ + LIBAVFORMAT_VERSION_MICRO) +#define LIBAVFORMAT_BUILD LIBAVFORMAT_VERSION_INT + +#define LIBAVFORMAT_IDENT "Lavf" AV_STRINGIFY(LIBAVFORMAT_VERSION) + +/** + * Returns the LIBAVFORMAT_VERSION_INT constant. + */ +unsigned avformat_version(void); + +#include +#include /* FILE */ +#include "libavcodec/avcodec.h" + +#include "avio.h" + +/* packet functions */ + +typedef struct AVPacket { + /** + * Presentation timestamp in time_base units. + * This is the time at which the decompressed packet will be presented + * to the user. + * Can be AV_NOPTS_VALUE if it is not stored in the file. + * pts MUST be larger or equal to dts as presentation cannot happen before + * decompression, unless one wants to view hex dumps. Some formats misuse + * the terms dts and pts/cts to mean something different, these timestamps + * must be converted to true pts/dts before they are stored in AVPacket. + */ + int64_t pts; + /** + * Decompression timestamp in time_base units. + * This is the time at which the packet is decompressed. + * Can be AV_NOPTS_VALUE if it is not stored in the file. + */ + int64_t dts; + uint8_t *data; + int size; + int stream_index; + int flags; + /** + * Duration of this packet in time_base units, 0 if unknown. + * Equals next_pts - this_pts in presentation order. + */ + int duration; + void (*destruct)(struct AVPacket *); + void *priv; + int64_t pos; ///< byte position in stream, -1 if unknown + + /** + * Time difference in stream time base units from the pts of this + * packet to the point at which the output from the decoder has converged + * independent from the availability of previous frames. That is, the + * frames are virtually identical no matter if decoding started from + * the very first frame or from this keyframe. + * Is AV_NOPTS_VALUE if unknown. + * This field is not the display duration of the current packet. + * + * The purpose of this field is to allow seeking in streams that have no + * keyframes in the conventional sense. It corresponds to the + * recovery point SEI in H.264 and match_time_delta in NUT. It is also + * essential for some types of subtitle streams to ensure that all + * subtitles are correctly displayed after seeking. + */ + int64_t convergence_duration; +} AVPacket; +#define PKT_FLAG_KEY 0x0001 + +void av_destruct_packet_nofree(AVPacket *pkt); + +/** + * Default packet destructor. + */ +void av_destruct_packet(AVPacket *pkt); + +/** + * Initialize optional fields of a packet with default values. + * + * @param pkt packet + */ +void av_init_packet(AVPacket *pkt); + +/** + * Allocate the payload of a packet and initialize its fields with + * default values. + * + * @param pkt packet + * @param size wanted payload size + * @return 0 if OK, AVERROR_xxx otherwise + */ +int av_new_packet(AVPacket *pkt, int size); + +/** + * Allocate and read the payload of a packet and initialize its fields with + * default values. + * + * @param pkt packet + * @param size desired payload size + * @return >0 (read size) if OK, AVERROR_xxx otherwise + */ +int av_get_packet(ByteIOContext *s, AVPacket *pkt, int size); + +/** + * @warning This is a hack - the packet memory allocation stuff is broken. The + * packet is allocated if it was not really allocated. + */ +int av_dup_packet(AVPacket *pkt); + +/** + * Free a packet. + * + * @param pkt packet to free + */ +static inline void av_free_packet(AVPacket *pkt) +{ + if (pkt && pkt->destruct) { + pkt->destruct(pkt); + } +} + +/*************************************************/ +/* fractional numbers for exact pts handling */ + +/** + * The exact value of the fractional number is: 'val + num / den'. + * num is assumed to be 0 <= num < den. + * @deprecated Use AVRational instead. +*/ +typedef struct AVFrac { + int64_t val, num, den; +} AVFrac attribute_deprecated; + +/*************************************************/ +/* input/output formats */ + +struct AVCodecTag; + +struct AVFormatContext; + +/** This structure contains the data a format has to probe a file. */ +typedef struct AVProbeData { + const char *filename; + unsigned char *buf; + int buf_size; +} AVProbeData; + +#define AVPROBE_SCORE_MAX 100 ///< Maximum score, half of that is used for file-extension-based detection. +#define AVPROBE_PADDING_SIZE 32 ///< extra allocated bytes at the end of the probe buffer + +typedef struct AVFormatParameters { + AVRational time_base; + int sample_rate; + int channels; + int width; + int height; + enum PixelFormat pix_fmt; + int channel; /**< Used to select DV channel. */ + const char *standard; /**< TV standard, NTSC, PAL, SECAM */ + unsigned int mpeg2ts_raw:1; /**< Force raw MPEG-2 transport stream output, if possible. */ + unsigned int mpeg2ts_compute_pcr:1; /**< Compute exact PCR for each transport + stream packet (only meaningful if + mpeg2ts_raw is TRUE). */ + unsigned int initial_pause:1; /**< Do not begin to play the stream + immediately (RTSP only). */ + unsigned int prealloced_context:1; +#if LIBAVFORMAT_VERSION_INT < (53<<16) + enum CodecID video_codec_id; + enum CodecID audio_codec_id; +#endif +} AVFormatParameters; + +//! Demuxer will use url_fopen, no opened file should be provided by the caller. +#define AVFMT_NOFILE 0x0001 +#define AVFMT_NEEDNUMBER 0x0002 /**< Needs '%d' in filename. */ +#define AVFMT_SHOW_IDS 0x0008 /**< Show format stream IDs numbers. */ +#define AVFMT_RAWPICTURE 0x0020 /**< Format wants AVPicture structure for + raw picture data. */ +#define AVFMT_GLOBALHEADER 0x0040 /**< Format wants global header. */ +#define AVFMT_NOTIMESTAMPS 0x0080 /**< Format does not need / have any timestamps. */ +#define AVFMT_GENERIC_INDEX 0x0100 /**< Use generic index building code. */ +#define AVFMT_TS_DISCONT 0x0200 /**< Format allows timestamp discontinuities. */ + +typedef struct AVOutputFormat { + const char *name; + /** + * Descriptive name for the format, meant to be more human-readable + * than \p name. You \e should use the NULL_IF_CONFIG_SMALL() macro + * to define it. + */ + const char *long_name; + const char *mime_type; + const char *extensions; /**< comma-separated filename extensions */ + /** Size of private data so that it can be allocated in the wrapper. */ + int priv_data_size; + /* output support */ + enum CodecID audio_codec; /**< default audio codec */ + enum CodecID video_codec; /**< default video codec */ + int (*write_header)(struct AVFormatContext *); + int (*write_packet)(struct AVFormatContext *, AVPacket *pkt); + int (*write_trailer)(struct AVFormatContext *); + /** can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_GLOBALHEADER */ + int flags; + /** Currently only used to set pixel format if not YUV420P. */ + int (*set_parameters)(struct AVFormatContext *, AVFormatParameters *); + int (*interleave_packet)(struct AVFormatContext *, AVPacket *out, + AVPacket *in, int flush); + + /** + * List of supported codec_id-codec_tag pairs, ordered by "better + * choice first". The arrays are all CODEC_ID_NONE terminated. + */ + const struct AVCodecTag * const *codec_tag; + + enum CodecID subtitle_codec; /**< default subtitle codec */ + + /* private fields */ + struct AVOutputFormat *next; +} AVOutputFormat; + +typedef struct AVInputFormat { + const char *name; + /** + * Descriptive name for the format, meant to be more human-readable + * than \p name. You \e should use the NULL_IF_CONFIG_SMALL() macro + * to define it. + */ + const char *long_name; + /** Size of private data so that it can be allocated in the wrapper. */ + int priv_data_size; + /** + * Tell if a given file has a chance of being parsed by this format. + * The buffer provided is guaranteed to be AVPROBE_PADDING_SIZE bytes + * big so you do not have to check for that unless you need more. + */ + int (*read_probe)(AVProbeData *); + /** Read the format header and initialize the AVFormatContext + structure. Return 0 if OK. 'ap' if non-NULL contains + additional parameters. Only used in raw format right + now. 'av_new_stream' should be called to create new streams. */ + int (*read_header)(struct AVFormatContext *, + AVFormatParameters *ap); + /** Read one packet and put it in 'pkt'. pts and flags are also + set. 'av_new_stream' can be called only if the flag + AVFMTCTX_NOHEADER is used. */ + int (*read_packet)(struct AVFormatContext *, AVPacket *pkt); + /** Close the stream. The AVFormatContext and AVStreams are not + freed by this function */ + int (*read_close)(struct AVFormatContext *); + /** + * Seek to a given timestamp relative to the frames in + * stream component stream_index. + * @param stream_index must not be -1 + * @param flags selects which direction should be preferred if no exact + * match is available + * @return >= 0 on success (but not necessarily the new offset) + */ + int (*read_seek)(struct AVFormatContext *, + int stream_index, int64_t timestamp, int flags); + /** + * Gets the next timestamp in stream[stream_index].time_base units. + * @return the timestamp or AV_NOPTS_VALUE if an error occurred + */ + int64_t (*read_timestamp)(struct AVFormatContext *s, int stream_index, + int64_t *pos, int64_t pos_limit); + /** Can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER. */ + int flags; + /** If extensions are defined, then no probe is done. You should + usually not use extension format guessing because it is not + reliable enough */ + const char *extensions; + /** General purpose read-only value that the format can use. */ + int value; + + /** Start/resume playing - only meaningful if using a network-based format + (RTSP). */ + int (*read_play)(struct AVFormatContext *); + + /** Pause playing - only meaningful if using a network-based format + (RTSP). */ + int (*read_pause)(struct AVFormatContext *); + + const struct AVCodecTag * const *codec_tag; + + /* private fields */ + struct AVInputFormat *next; +} AVInputFormat; + +enum AVStreamParseType { + AVSTREAM_PARSE_NONE, + AVSTREAM_PARSE_FULL, /**< full parsing and repack */ + AVSTREAM_PARSE_HEADERS, /**< Only parse headers, do not repack. */ + AVSTREAM_PARSE_TIMESTAMPS, /**< full parsing and interpolation of timestamps for frames not starting on a packet boundary */ +}; + +typedef struct AVIndexEntry { + int64_t pos; + int64_t timestamp; +#define AVINDEX_KEYFRAME 0x0001 + int flags:2; + int size:30; //Yeah, trying to keep the size of this small to reduce memory requirements (it is 24 vs. 32 bytes due to possible 8-byte alignment). + int min_distance; /**< Minimum distance between this and the previous keyframe, used to avoid unneeded searching. */ +} AVIndexEntry; + +#define AV_DISPOSITION_DEFAULT 0x0001 +#define AV_DISPOSITION_DUB 0x0002 +#define AV_DISPOSITION_ORIGINAL 0x0004 +#define AV_DISPOSITION_COMMENT 0x0008 +#define AV_DISPOSITION_LYRICS 0x0010 +#define AV_DISPOSITION_KARAOKE 0x0020 + +/** + * Stream structure. + * New fields can be added to the end with minor version bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. + * sizeof(AVStream) must not be used outside libav*. + */ +typedef struct AVStream { + int index; /**< stream index in AVFormatContext */ + int id; /**< format-specific stream ID */ + AVCodecContext *codec; /**< codec context */ + /** + * Real base frame rate of the stream. + * This is the lowest frame rate with which all timestamps can be + * represented accurately (it is the least common multiple of all + * frame rates in the stream). Note, this value is just a guess! + * For example if the time base is 1/90000 and all frames have either + * approximately 3600 or 1800 timer ticks, then r_frame_rate will be 50/1. + */ + AVRational r_frame_rate; + void *priv_data; + + /* internal data used in av_find_stream_info() */ + int64_t first_dts; + /** encoding: pts generation when outputting stream */ + struct AVFrac pts; + + /** + * This is the fundamental unit of time (in seconds) in terms + * of which frame timestamps are represented. For fixed-fps content, + * time base should be 1/frame rate and timestamp increments should be 1. + */ + AVRational time_base; + int pts_wrap_bits; /**< number of bits in pts (used for wrapping control) */ + /* ffmpeg.c private use */ + int stream_copy; /**< If set, just copy stream. */ + enum AVDiscard discard; ///< Selects which packets can be discarded at will and do not need to be demuxed. + //FIXME move stuff to a flags field? + /** Quality, as it has been removed from AVCodecContext and put in AVVideoFrame. + * MN: dunno if that is the right place for it */ + float quality; + /** + * Decoding: pts of the first frame of the stream, in stream time base. + * Only set this if you are absolutely 100% sure that the value you set + * it to really is the pts of the first frame. + * This may be undefined (AV_NOPTS_VALUE). + * @note The ASF header does NOT contain a correct start_time the ASF + * demuxer must NOT set this. + */ + int64_t start_time; + /** + * Decoding: duration of the stream, in stream time base. + * If a source file does not specify a duration, but does specify + * a bitrate, this value will be estimated from bitrate and file size. + */ + int64_t duration; + + char language[4]; /** ISO 639 3-letter language code (empty string if undefined) */ + + /* av_read_frame() support */ + enum AVStreamParseType need_parsing; + struct AVCodecParserContext *parser; + + int64_t cur_dts; + int last_IP_duration; + int64_t last_IP_pts; + /* av_seek_frame() support */ + AVIndexEntry *index_entries; /**< Only used if the format does not + support seeking natively. */ + int nb_index_entries; + unsigned int index_entries_allocated_size; + + int64_t nb_frames; ///< number of frames in this stream if known or 0 + +#if LIBAVFORMAT_VERSION_INT < (53<<16) + int64_t unused[4+1]; +#endif + + char *filename; /**< source filename of the stream */ + + int disposition; /**< AV_DISPOSITION_* bit field */ + + AVProbeData probe_data; +#define MAX_REORDER_DELAY 16 + int64_t pts_buffer[MAX_REORDER_DELAY+1]; + + /** + * sample aspect ratio (0 if unknown) + * - encoding: Set by user. + * - decoding: Set by libavformat. + */ + AVRational sample_aspect_ratio; +} AVStream; + +#define AV_PROGRAM_RUNNING 1 + +/** + * New fields can be added to the end with minor version bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. + * sizeof(AVProgram) must not be used outside libav*. + */ +typedef struct AVProgram { + int id; + char *provider_name; ///< network name for DVB streams + char *name; ///< service name for DVB streams + int flags; + enum AVDiscard discard; ///< selects which program to discard and which to feed to the caller + unsigned int *stream_index; + unsigned int nb_stream_indexes; +} AVProgram; + +#define AVFMTCTX_NOHEADER 0x0001 /**< signal that no header is present + (streams are added dynamically) */ + +typedef struct AVChapter { + int id; ///< unique ID to identify the chapter + AVRational time_base; ///< time base in which the start/end timestamps are specified + int64_t start, end; ///< chapter start/end time in time_base units + char *title; ///< chapter title +} AVChapter; + +#define MAX_STREAMS 20 + +/** + * Format I/O context. + * New fields can be added to the end with minor version bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. + * sizeof(AVFormatContext) must not be used outside libav*. + */ +typedef struct AVFormatContext { + const AVClass *av_class; /**< Set by av_alloc_format_context. */ + /* Can only be iformat or oformat, not both at the same time. */ + struct AVInputFormat *iformat; + struct AVOutputFormat *oformat; + void *priv_data; + ByteIOContext *pb; + unsigned int nb_streams; + AVStream *streams[MAX_STREAMS]; + char filename[1024]; /**< input or output filename */ + /* stream info */ + int64_t timestamp; + char title[512]; + char author[512]; + char copyright[512]; + char comment[512]; + char album[512]; + int year; /**< ID3 year, 0 if none */ + int track; /**< track number, 0 if none */ + char genre[32]; /**< ID3 genre */ + + int ctx_flags; /**< Format-specific flags, see AVFMTCTX_xx */ + /* private data for pts handling (do not modify directly). */ + /** This buffer is only needed when packets were already buffered but + not decoded, for example to get the codec parameters in MPEG + streams. */ + struct AVPacketList *packet_buffer; + + /** Decoding: position of the first frame of the component, in + AV_TIME_BASE fractional seconds. NEVER set this value directly: + It is deduced from the AVStream values. */ + int64_t start_time; + /** Decoding: duration of the stream, in AV_TIME_BASE fractional + seconds. NEVER set this value directly: it is deduced from the + AVStream values. */ + int64_t duration; + /** decoding: total file size, 0 if unknown */ + int64_t file_size; + /** Decoding: total stream bitrate in bit/s, 0 if not + available. Never set it directly if the file_size and the + duration are known as ffmpeg can compute it automatically. */ + int bit_rate; + + /* av_read_frame() support */ + AVStream *cur_st; + const uint8_t *cur_ptr; + int cur_len; + AVPacket cur_pkt; + + /* av_seek_frame() support */ + int64_t data_offset; /** offset of the first packet */ + int index_built; + + int mux_rate; + int packet_size; + int preload; + int max_delay; + +#define AVFMT_NOOUTPUTLOOP -1 +#define AVFMT_INFINITEOUTPUTLOOP 0 + /** number of times to loop output in formats that support it */ + int loop_output; + + int flags; +#define AVFMT_FLAG_GENPTS 0x0001 ///< Generate pts if missing even if it requires parsing future frames. +#define AVFMT_FLAG_IGNIDX 0x0002 ///< Ignore index. +#define AVFMT_FLAG_NONBLOCK 0x0004 ///< Do not block when reading packets from input. + + int loop_input; + /** Decoding: size of data to probe; encoding: unused. */ + unsigned int probesize; + + /** + * Maximum time (in AV_TIME_BASE units) during which the input should + * be analyzed in av_find_stream_info(). + */ + int max_analyze_duration; + + const uint8_t *key; + int keylen; + + unsigned int nb_programs; + AVProgram **programs; + + /** + * Forced video codec_id. + * Demuxing: Set by user. + */ + enum CodecID video_codec_id; + /** + * Forced audio codec_id. + * Demuxing: Set by user. + */ + enum CodecID audio_codec_id; + /** + * Forced subtitle codec_id. + * Demuxing: Set by user. + */ + enum CodecID subtitle_codec_id; + + /** + * Maximum amount of memory in bytes to use per stream for the index. + * If the needed index exceeds this size, entries will be discarded as + * needed to maintain a smaller size. This can lead to slower or less + * accurate seeking (depends on demuxer). + * Demuxers for which a full in-memory index is mandatory will ignore + * this. + * muxing : unused + * demuxing: set by user + */ + unsigned int max_index_size; + + /** + * Maximum amount of memory in bytes to use for buffering frames + * obtained from realtime capture devices. + */ + unsigned int max_picture_buffer; + + unsigned int nb_chapters; + AVChapter **chapters; + + /** + * Flags to enable debugging. + */ + int debug; +#define FF_FDEBUG_TS 0x0001 + + /** + * Raw packets from the demuxer, prior to parsing and decoding. + * This buffer is used for buffering packets until the codec can + * be identified, as parsing cannot be done without knowing the + * codec. + */ + struct AVPacketList *raw_packet_buffer; + struct AVPacketList *raw_packet_buffer_end; + + struct AVPacketList *packet_buffer_end; +} AVFormatContext; + +typedef struct AVPacketList { + AVPacket pkt; + struct AVPacketList *next; +} AVPacketList; + +#if LIBAVFORMAT_VERSION_INT < (53<<16) +extern AVInputFormat *first_iformat; +extern AVOutputFormat *first_oformat; +#endif + +AVInputFormat *av_iformat_next(AVInputFormat *f); +AVOutputFormat *av_oformat_next(AVOutputFormat *f); + +enum CodecID av_guess_image2_codec(const char *filename); + +/* XXX: use automatic init with either ELF sections or C file parser */ +/* modules */ + +/* utils.c */ +void av_register_input_format(AVInputFormat *format); +void av_register_output_format(AVOutputFormat *format); +AVOutputFormat *guess_stream_format(const char *short_name, + const char *filename, + const char *mime_type); +AVOutputFormat *guess_format(const char *short_name, + const char *filename, + const char *mime_type); + +/** + * Guesses the codec ID based upon muxer and filename. + */ +enum CodecID av_guess_codec(AVOutputFormat *fmt, const char *short_name, + const char *filename, const char *mime_type, + enum CodecType type); + +/** + * Send a nice hexadecimal dump of a buffer to the specified file stream. + * + * @param f The file stream pointer where the dump should be sent to. + * @param buf buffer + * @param size buffer size + * + * @see av_hex_dump_log, av_pkt_dump, av_pkt_dump_log + */ +void av_hex_dump(FILE *f, uint8_t *buf, int size); + +/** + * Send a nice hexadecimal dump of a buffer to the log. + * + * @param avcl A pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct. + * @param level The importance level of the message, lower values signifying + * higher importance. + * @param buf buffer + * @param size buffer size + * + * @see av_hex_dump, av_pkt_dump, av_pkt_dump_log + */ +void av_hex_dump_log(void *avcl, int level, uint8_t *buf, int size); + +/** + * Send a nice dump of a packet to the specified file stream. + * + * @param f The file stream pointer where the dump should be sent to. + * @param pkt packet to dump + * @param dump_payload True if the payload must be displayed, too. + */ +void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload); + +/** + * Send a nice dump of a packet to the log. + * + * @param avcl A pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct. + * @param level The importance level of the message, lower values signifying + * higher importance. + * @param pkt packet to dump + * @param dump_payload True if the payload must be displayed, too. + */ +void av_pkt_dump_log(void *avcl, int level, AVPacket *pkt, int dump_payload); + +void av_register_all(void); + +/** codec tag <-> codec id */ +enum CodecID av_codec_get_id(const struct AVCodecTag * const *tags, unsigned int tag); +unsigned int av_codec_get_tag(const struct AVCodecTag * const *tags, enum CodecID id); + +/* media file input */ + +/** + * Finds AVInputFormat based on the short name of the input format. + */ +AVInputFormat *av_find_input_format(const char *short_name); + +/** + * Guess file format. + * + * @param is_opened Whether the file is already opened; determines whether + * demuxers with or without AVFMT_NOFILE are probed. + */ +AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened); + +/** + * Allocates all the structures needed to read an input stream. + * This does not open the needed codecs for decoding the stream[s]. + */ +int av_open_input_stream(AVFormatContext **ic_ptr, + ByteIOContext *pb, const char *filename, + AVInputFormat *fmt, AVFormatParameters *ap); + +/** + * Open a media file as input. The codecs are not opened. Only the file + * header (if present) is read. + * + * @param ic_ptr The opened media file handle is put here. + * @param filename filename to open + * @param fmt If non-NULL, force the file format to use. + * @param buf_size optional buffer size (zero if default is OK) + * @param ap Additional parameters needed when opening the file + * (NULL if default). + * @return 0 if OK, AVERROR_xxx otherwise + */ +int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, + AVInputFormat *fmt, + int buf_size, + AVFormatParameters *ap); +/** + * Allocate an AVFormatContext. + * Can be freed with av_free() but do not forget to free everything you + * explicitly allocated as well! + */ +AVFormatContext *av_alloc_format_context(void); + +/** + * Read packets of a media file to get stream information. This + * is useful for file formats with no headers such as MPEG. This + * function also computes the real frame rate in case of MPEG-2 repeat + * frame mode. + * The logical file position is not changed by this function; + * examined packets may be buffered for later processing. + * + * @param ic media file handle + * @return >=0 if OK, AVERROR_xxx on error + * @todo Let the user decide somehow what information is needed so that + * we do not waste time getting stuff the user does not need. + */ +int av_find_stream_info(AVFormatContext *ic); + +/** + * Read a transport packet from a media file. + * + * This function is obsolete and should never be used. + * Use av_read_frame() instead. + * + * @param s media file handle + * @param pkt is filled + * @return 0 if OK, AVERROR_xxx on error + */ +int av_read_packet(AVFormatContext *s, AVPacket *pkt); + +/** + * Return the next frame of a stream. + * + * The returned packet is valid + * until the next av_read_frame() or until av_close_input_file() and + * must be freed with av_free_packet. For video, the packet contains + * exactly one frame. For audio, it contains an integer number of + * frames if each frame has a known fixed size (e.g. PCM or ADPCM + * data). If the audio frames have a variable size (e.g. MPEG audio), + * then it contains one frame. + * + * pkt->pts, pkt->dts and pkt->duration are always set to correct + * values in AVStream.timebase units (and guessed if the format cannot + * provide them). pkt->pts can be AV_NOPTS_VALUE if the video format + * has B-frames, so it is better to rely on pkt->dts if you do not + * decompress the payload. + * + * @return 0 if OK, < 0 on error or end of file + */ +int av_read_frame(AVFormatContext *s, AVPacket *pkt); + +/** + * Seek to the key frame at timestamp. + * 'timestamp' in 'stream_index'. + * @param stream_index If stream_index is (-1), a default + * stream is selected, and timestamp is automatically converted + * from AV_TIME_BASE units to the stream specific time_base. + * @param timestamp Timestamp in AVStream.time_base units + * or, if no stream is specified, in AV_TIME_BASE units. + * @param flags flags which select direction and seeking mode + * @return >= 0 on success + */ +int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, + int flags); + +/** + * Start playing a network based stream (e.g. RTSP stream) at the + * current position. + */ +int av_read_play(AVFormatContext *s); + +/** + * Pause a network based stream (e.g. RTSP stream). + * + * Use av_read_play() to resume it. + */ +int av_read_pause(AVFormatContext *s); + +/** + * Free a AVFormatContext allocated by av_open_input_stream. + * @param s context to free + */ +void av_close_input_stream(AVFormatContext *s); + +/** + * Close a media file (but not its codecs). + * + * @param s media file handle + */ +void av_close_input_file(AVFormatContext *s); + +/** + * Add a new stream to a media file. + * + * Can only be called in the read_header() function. If the flag + * AVFMTCTX_NOHEADER is in the format context, then new streams + * can be added in read_packet too. + * + * @param s media file handle + * @param id file-format-dependent stream ID + */ +AVStream *av_new_stream(AVFormatContext *s, int id); +AVProgram *av_new_program(AVFormatContext *s, int id); + +/** + * Add a new chapter. + * This function is NOT part of the public API + * and should ONLY be used by demuxers. + * + * @param s media file handle + * @param id unique ID for this chapter + * @param start chapter start time in time_base units + * @param end chapter end time in time_base units + * @param title chapter title + * + * @return AVChapter or NULL on error + */ +AVChapter *ff_new_chapter(AVFormatContext *s, int id, AVRational time_base, + int64_t start, int64_t end, const char *title); + +/** + * Set the pts for a given stream. + * + * @param s stream + * @param pts_wrap_bits number of bits effectively used by the pts + * (used for wrap control, 33 is the value for MPEG) + * @param pts_num numerator to convert to seconds (MPEG: 1) + * @param pts_den denominator to convert to seconds (MPEG: 90000) + */ +void av_set_pts_info(AVStream *s, int pts_wrap_bits, + int pts_num, int pts_den); + +#define AVSEEK_FLAG_BACKWARD 1 ///< seek backward +#define AVSEEK_FLAG_BYTE 2 ///< seeking based on position in bytes +#define AVSEEK_FLAG_ANY 4 ///< seek to any frame, even non-keyframes + +int av_find_default_stream_index(AVFormatContext *s); + +/** + * Gets the index for a specific timestamp. + * @param flags if AVSEEK_FLAG_BACKWARD then the returned index will correspond + * to the timestamp which is <= the requested one, if backward + * is 0, then it will be >= + * if AVSEEK_FLAG_ANY seek to any frame, only keyframes otherwise + * @return < 0 if no such timestamp could be found + */ +int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags); + +/** + * Ensures the index uses less memory than the maximum specified in + * AVFormatContext.max_index_size, by discarding entries if it grows + * too large. + * This function is not part of the public API and should only be called + * by demuxers. + */ +void ff_reduce_index(AVFormatContext *s, int stream_index); + +/** + * Add an index entry into a sorted list. Update the entry if the list + * already contains it. + * + * @param timestamp timestamp in the time base of the given stream + */ +int av_add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, + int size, int distance, int flags); + +/** + * Does a binary search using av_index_search_timestamp() and + * AVCodec.read_timestamp(). + * This is not supposed to be called directly by a user application, + * but by demuxers. + * @param target_ts target timestamp in the time base of the given stream + * @param stream_index stream number + */ +int av_seek_frame_binary(AVFormatContext *s, int stream_index, + int64_t target_ts, int flags); + +/** + * Updates cur_dts of all streams based on the given timestamp and AVStream. + * + * Stream ref_st unchanged, others set cur_dts in their native time base. + * Only needed for timestamp wrapping or if (dts not set and pts!=dts). + * @param timestamp new dts expressed in time_base of param ref_st + * @param ref_st reference stream giving time_base of param timestamp + */ +void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp); + +/** + * Does a binary search using read_timestamp(). + * This is not supposed to be called directly by a user application, + * but by demuxers. + * @param target_ts target timestamp in the time base of the given stream + * @param stream_index stream number + */ +int64_t av_gen_search(AVFormatContext *s, int stream_index, + int64_t target_ts, int64_t pos_min, + int64_t pos_max, int64_t pos_limit, + int64_t ts_min, int64_t ts_max, + int flags, int64_t *ts_ret, + int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t )); + +/** media file output */ +int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap); + +/** + * Allocate the stream private data and write the stream header to an + * output media file. + * + * @param s media file handle + * @return 0 if OK, AVERROR_xxx on error + */ +int av_write_header(AVFormatContext *s); + +/** + * Write a packet to an output media file. + * + * The packet shall contain one audio or video frame. + * The packet must be correctly interleaved according to the container + * specification, if not then av_interleaved_write_frame must be used. + * + * @param s media file handle + * @param pkt The packet, which contains the stream_index, buf/buf_size, + dts/pts, ... + * @return < 0 on error, = 0 if OK, 1 if end of stream wanted + */ +int av_write_frame(AVFormatContext *s, AVPacket *pkt); + +/** + * Writes a packet to an output media file ensuring correct interleaving. + * + * The packet must contain one audio or video frame. + * If the packets are already correctly interleaved the application should + * call av_write_frame() instead as it is slightly faster. It is also important + * to keep in mind that completely non-interleaved input will need huge amounts + * of memory to interleave with this, so it is preferable to interleave at the + * demuxer level. + * + * @param s media file handle + * @param pkt The packet, which contains the stream_index, buf/buf_size, + dts/pts, ... + * @return < 0 on error, = 0 if OK, 1 if end of stream wanted + */ +int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt); + +/** + * Interleave a packet per dts in an output media file. + * + * Packets with pkt->destruct == av_destruct_packet will be freed inside this + * function, so they cannot be used after it, note calling av_free_packet() + * on them is still safe. + * + * @param s media file handle + * @param out the interleaved packet will be output here + * @param in the input packet + * @param flush 1 if no further packets are available as input and all + * remaining packets should be output + * @return 1 if a packet was output, 0 if no packet could be output, + * < 0 if an error occurred + */ +int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, + AVPacket *pkt, int flush); + +/** + * @brief Write the stream trailer to an output media file and + * free the file private data. + * + * May only be called after a successful call to av_write_header. + * + * @param s media file handle + * @return 0 if OK, AVERROR_xxx on error + */ +int av_write_trailer(AVFormatContext *s); + +void dump_format(AVFormatContext *ic, + int index, + const char *url, + int is_output); + +/** + * Parses width and height out of string str. + * @deprecated Use av_parse_video_frame_size instead. + */ +attribute_deprecated int parse_image_size(int *width_ptr, int *height_ptr, + const char *str); + +/** + * Converts frame rate from string to a fraction. + * @deprecated Use av_parse_video_frame_rate instead. + */ +attribute_deprecated int parse_frame_rate(int *frame_rate, int *frame_rate_base, + const char *arg); + +/** + * Parses \p datestr and returns a corresponding number of microseconds. + * @param datestr String representing a date or a duration. + * - If a date the syntax is: + * @code + * [{YYYY-MM-DD|YYYYMMDD}]{T| }{HH[:MM[:SS[.m...]]][Z]|HH[MM[SS[.m...]]][Z]} + * @endcode + * Time is local time unless Z is appended, in which case it is + * interpreted as UTC. + * If the year-month-day part is not specified it takes the current + * year-month-day. + * Returns the number of microseconds since 1st of January, 1970 up to + * the time of the parsed date or INT64_MIN if \p datestr cannot be + * successfully parsed. + * - If a duration the syntax is: + * @code + * [-]HH[:MM[:SS[.m...]]] + * [-]S+[.m...] + * @endcode + * Returns the number of microseconds contained in a time interval + * with the specified duration or INT64_MIN if \p datestr cannot be + * successfully parsed. + * @param duration Flag which tells how to interpret \p datestr, if + * not zero \p datestr is interpreted as a duration, otherwise as a + * date. + */ +int64_t parse_date(const char *datestr, int duration); + +/** Gets the current time in microseconds. */ +int64_t av_gettime(void); + +/* ffm-specific for ffserver */ +#define FFM_PACKET_SIZE 4096 +int64_t ffm_read_write_index(int fd); +void ffm_write_write_index(int fd, int64_t pos); +void ffm_set_write_index(AVFormatContext *s, int64_t pos, int64_t file_size); + +/** + * Attempts to find a specific tag in a URL. + * + * syntax: '?tag1=val1&tag2=val2...'. Little URL decoding is done. + * Return 1 if found. + */ +int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info); + +/** + * Returns in 'buf' the path with '%d' replaced by number. + * + * Also handles the '%0nd' format where 'n' is the total number + * of digits and '%%'. + * + * @param buf destination buffer + * @param buf_size destination buffer size + * @param path numbered sequence string + * @param number frame number + * @return 0 if OK, -1 on format error + */ +int av_get_frame_filename(char *buf, int buf_size, + const char *path, int number); + +/** + * Check whether filename actually is a numbered sequence generator. + * + * @param filename possible numbered sequence string + * @return 1 if a valid numbered sequence string, 0 otherwise + */ +int av_filename_number_test(const char *filename); + +/** + * Generate an SDP for an RTP session. + * + * @param ac array of AVFormatContexts describing the RTP streams. If the + * array is composed by only one context, such context can contain + * multiple AVStreams (one AVStream per RTP stream). Otherwise, + * all the contexts in the array (an AVCodecContext per RTP stream) + * must contain only one AVStream. + * @param n_files number of AVCodecContexts contained in ac + * @param buff buffer where the SDP will be stored (must be allocated by + * the caller) + * @param size the size of the buffer + * @return 0 if OK, AVERROR_xxx on error + */ +int avf_sdp_create(AVFormatContext *ac[], int n_files, char *buff, int size); + +#ifdef HAVE_AV_CONFIG_H + +void ff_dynarray_add(unsigned long **tab_ptr, int *nb_ptr, unsigned long elem); + +#ifdef __GNUC__ +#define dynarray_add(tab, nb_ptr, elem)\ +do {\ + __typeof__(tab) _tab = (tab);\ + __typeof__(elem) _elem = (elem);\ + (void)sizeof(**_tab == _elem); /* check that types are compatible */\ + ff_dynarray_add((unsigned long **)_tab, nb_ptr, (unsigned long)_elem);\ +} while(0) +#else +#define dynarray_add(tab, nb_ptr, elem)\ +do {\ + ff_dynarray_add((unsigned long **)(tab), nb_ptr, (unsigned long)(elem));\ +} while(0) +#endif + +time_t mktimegm(struct tm *tm); +struct tm *brktimegm(time_t secs, struct tm *tm); +const char *small_strptime(const char *p, const char *fmt, + struct tm *dt); + +struct in_addr; +int resolve_host(struct in_addr *sin_addr, const char *hostname); + +void url_split(char *proto, int proto_size, + char *authorization, int authorization_size, + char *hostname, int hostname_size, + int *port_ptr, + char *path, int path_size, + const char *url); + +int match_ext(const char *filename, const char *extensions); + +#endif /* HAVE_AV_CONFIG_H */ + +#endif /* AVFORMAT_AVFORMAT_H */ diff --git a/scalos/include/ffmpeg/avio.h b/scalos/include/ffmpeg/avio.h new file mode 100644 index 000000000..3bb88b37c --- /dev/null +++ b/scalos/include/ffmpeg/avio.h @@ -0,0 +1,370 @@ +/* + * unbuffered io for ffmpeg system + * copyright (c) 2001 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef AVFORMAT_AVIO_H +#define AVFORMAT_AVIO_H + +#include + +/* unbuffered I/O */ + +/** + * URL Context. + * New fields can be added to the end with minor version bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. + * sizeof(URLContext) must not be used outside libav*. + */ +struct URLContext { +#if LIBAVFORMAT_VERSION_MAJOR >= 53 + const AVClass *av_class; ///< information for av_log(). Set by url_open(). +#endif + struct URLProtocol *prot; + int flags; + int is_streamed; /**< true if streamed (no seek possible), default = false */ + int max_packet_size; /**< if non zero, the stream is packetized with this max packet size */ + void *priv_data; + char *filename; /**< specified filename */ +}; + +typedef struct URLContext URLContext; + +typedef struct URLPollEntry { + URLContext *handle; + int events; + int revents; +} URLPollEntry; + +#define URL_RDONLY 0 +#define URL_WRONLY 1 +#define URL_RDWR 2 + +typedef int URLInterruptCB(void); + +int url_open_protocol (URLContext **puc, struct URLProtocol *up, + const char *filename, int flags); +int url_open(URLContext **h, const char *filename, int flags); +int url_read(URLContext *h, unsigned char *buf, int size); +int url_write(URLContext *h, unsigned char *buf, int size); +int64_t url_seek(URLContext *h, int64_t pos, int whence); +int url_close(URLContext *h); +int url_exist(const char *filename); +int64_t url_filesize(URLContext *h); + +/** + * Return the maximum packet size associated to packetized file + * handle. If the file is not packetized (stream like HTTP or file on + * disk), then 0 is returned. + * + * @param h file handle + * @return maximum packet size in bytes + */ +int url_get_max_packet_size(URLContext *h); +void url_get_filename(URLContext *h, char *buf, int buf_size); + +/** + * The callback is called in blocking functions to test regulary if + * asynchronous interruption is needed. AVERROR(EINTR) is returned + * in this case by the interrupted function. 'NULL' means no interrupt + * callback is given. + */ +void url_set_interrupt_cb(URLInterruptCB *interrupt_cb); + +/* not implemented */ +int url_poll(URLPollEntry *poll_table, int n, int timeout); + +/** + * Pause and resume playing - only meaningful if using a network streaming + * protocol (e.g. MMS). + * @param pause 1 for pause, 0 for resume + */ +int av_url_read_pause(URLContext *h, int pause); + +/** + * Seek to a given timestamp relative to some component stream. + * Only meaningful if using a network streaming protocol (e.g. MMS.). + * @param stream_index The stream index that the timestamp is relative to. + * If stream_index is (-1) the timestamp should be in AV_TIME_BASE + * units from the beginning of the presentation. + * If a stream_index >= 0 is used and the protocol does not support + * seeking based on component streams, the call will fail with ENOTSUP. + * @param timestamp timestamp in AVStream.time_base units + * or if there is no stream specified then in AV_TIME_BASE units. + * @param flags Optional combination of AVSEEK_FLAG_BACKWARD, AVSEEK_FLAG_BYTE + * and AVSEEK_FLAG_ANY. The protocol may silently ignore + * AVSEEK_FLAG_BACKWARD and AVSEEK_FLAG_ANY, but AVSEEK_FLAG_BYTE will + * fail with ENOTSUP if used and not supported. + * @return >= 0 on success + * @see AVInputFormat::read_seek + */ +int64_t av_url_read_seek(URLContext *h, int stream_index, + int64_t timestamp, int flags); + +/** + * Passing this as the "whence" parameter to a seek function causes it to + * return the filesize without seeking anywhere. Supporting this is optional. + * If it is not supported then the seek function will return <0. + */ +#define AVSEEK_SIZE 0x10000 + +typedef struct URLProtocol { + const char *name; + int (*url_open)(URLContext *h, const char *filename, int flags); + int (*url_read)(URLContext *h, unsigned char *buf, int size); + int (*url_write)(URLContext *h, unsigned char *buf, int size); + int64_t (*url_seek)(URLContext *h, int64_t pos, int whence); + int (*url_close)(URLContext *h); + struct URLProtocol *next; + int (*url_read_pause)(URLContext *h, int pause); + int64_t (*url_read_seek)(URLContext *h, int stream_index, + int64_t timestamp, int flags); +} URLProtocol; + +extern URLProtocol *first_protocol; +extern URLInterruptCB *url_interrupt_cb; + +URLProtocol *av_protocol_next(URLProtocol *p); + +int register_protocol(URLProtocol *protocol); + +/** + * Bytestream IO Context. + * New fields can be added to the end with minor version bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. + * sizeof(ByteIOContext) must not be used outside libav*. + */ +typedef struct { + unsigned char *buffer; + int buffer_size; + unsigned char *buf_ptr, *buf_end; + void *opaque; + int (*read_packet)(void *opaque, uint8_t *buf, int buf_size); + int (*write_packet)(void *opaque, uint8_t *buf, int buf_size); + int64_t (*seek)(void *opaque, int64_t offset, int whence); + int64_t pos; /**< position in the file of the current buffer */ + int must_flush; /**< true if the next seek should flush */ + int eof_reached; /**< true if eof reached */ + int write_flag; /**< true if open for writing */ + int is_streamed; + int max_packet_size; + unsigned long checksum; + unsigned char *checksum_ptr; + unsigned long (*update_checksum)(unsigned long checksum, const uint8_t *buf, unsigned int size); + int error; ///< contains the error code or 0 if no error happened + int (*read_pause)(void *opaque, int pause); + int64_t (*read_seek)(void *opaque, int stream_index, + int64_t timestamp, int flags); +} ByteIOContext; + +int init_put_byte(ByteIOContext *s, + unsigned char *buffer, + int buffer_size, + int write_flag, + void *opaque, + int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), + int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), + int64_t (*seek)(void *opaque, int64_t offset, int whence)); +ByteIOContext *av_alloc_put_byte( + unsigned char *buffer, + int buffer_size, + int write_flag, + void *opaque, + int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), + int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), + int64_t (*seek)(void *opaque, int64_t offset, int whence)); + +void put_byte(ByteIOContext *s, int b); +void put_buffer(ByteIOContext *s, const unsigned char *buf, int size); +void put_le64(ByteIOContext *s, uint64_t val); +void put_be64(ByteIOContext *s, uint64_t val); +void put_le32(ByteIOContext *s, unsigned int val); +void put_be32(ByteIOContext *s, unsigned int val); +void put_le24(ByteIOContext *s, unsigned int val); +void put_be24(ByteIOContext *s, unsigned int val); +void put_le16(ByteIOContext *s, unsigned int val); +void put_be16(ByteIOContext *s, unsigned int val); +void put_tag(ByteIOContext *s, const char *tag); + +void put_strz(ByteIOContext *s, const char *buf); + +/** + * fseek() equivalent for ByteIOContext. + * @return new position or AVERROR. + */ +int64_t url_fseek(ByteIOContext *s, int64_t offset, int whence); + +/** + * Skip given number of bytes forward. + * @param offset number of bytes + */ +void url_fskip(ByteIOContext *s, int64_t offset); + +/** + * ftell() equivalent for ByteIOContext. + * @return position or AVERROR. + */ +int64_t url_ftell(ByteIOContext *s); + +/** + * Gets the filesize. + * @return filesize or AVERROR + */ +int64_t url_fsize(ByteIOContext *s); + +/** + * feof() equivalent for ByteIOContext. + * @return non zero if and only if end of file + */ +int url_feof(ByteIOContext *s); + +int url_ferror(ByteIOContext *s); + +int av_url_read_fpause(ByteIOContext *h, int pause); +int64_t av_url_read_fseek(ByteIOContext *h, int stream_index, + int64_t timestamp, int flags); + +#define URL_EOF (-1) +/** @note return URL_EOF (-1) if EOF */ +int url_fgetc(ByteIOContext *s); + +/** @warning currently size is limited */ +#ifdef __GNUC__ +int url_fprintf(ByteIOContext *s, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 2, 3))); +#else +int url_fprintf(ByteIOContext *s, const char *fmt, ...); +#endif + +/** @note unlike fgets, the EOL character is not returned and a whole + line is parsed. return NULL if first char read was EOF */ +char *url_fgets(ByteIOContext *s, char *buf, int buf_size); + +void put_flush_packet(ByteIOContext *s); + + +/** + * Reads size bytes from ByteIOContext into buf. + * @returns number of bytes read or AVERROR + */ +int get_buffer(ByteIOContext *s, unsigned char *buf, int size); + +/** + * Reads size bytes from ByteIOContext into buf. + * This reads at most 1 packet. If that is not enough fewer bytes will be + * returned. + * @returns number of bytes read or AVERROR + */ +int get_partial_buffer(ByteIOContext *s, unsigned char *buf, int size); + +/** @note return 0 if EOF, so you cannot use it if EOF handling is + necessary */ +int get_byte(ByteIOContext *s); +unsigned int get_le24(ByteIOContext *s); +unsigned int get_le32(ByteIOContext *s); +uint64_t get_le64(ByteIOContext *s); +unsigned int get_le16(ByteIOContext *s); + +char *get_strz(ByteIOContext *s, char *buf, int maxlen); +unsigned int get_be16(ByteIOContext *s); +unsigned int get_be24(ByteIOContext *s); +unsigned int get_be32(ByteIOContext *s); +uint64_t get_be64(ByteIOContext *s); + +uint64_t ff_get_v(ByteIOContext *bc); + +static inline int url_is_streamed(ByteIOContext *s) +{ + return s->is_streamed; +} + +/** @note when opened as read/write, the buffers are only used for + writing */ +int url_fdopen(ByteIOContext **s, URLContext *h); + +/** @warning must be called before any I/O */ +int url_setbufsize(ByteIOContext *s, int buf_size); +/** Reset the buffer for reading or writing. + * @note Will drop any data currently in the buffer without transmitting it. + * @param flags URL_RDONLY to set up the buffer for reading, or URL_WRONLY + * to set up the buffer for writing. */ +int url_resetbuf(ByteIOContext *s, int flags); + +/** @note when opened as read/write, the buffers are only used for + writing */ +int url_fopen(ByteIOContext **s, const char *filename, int flags); +int url_fclose(ByteIOContext *s); +URLContext *url_fileno(ByteIOContext *s); + +/** + * Return the maximum packet size associated to packetized buffered file + * handle. If the file is not packetized (stream like http or file on + * disk), then 0 is returned. + * + * @param s buffered file handle + * @return maximum packet size in bytes + */ +int url_fget_max_packet_size(ByteIOContext *s); + +int url_open_buf(ByteIOContext **s, uint8_t *buf, int buf_size, int flags); + +/** return the written or read size */ +int url_close_buf(ByteIOContext *s); + +/** + * Open a write only memory stream. + * + * @param s new IO context + * @return zero if no error. + */ +int url_open_dyn_buf(ByteIOContext **s); + +/** + * Open a write only packetized memory stream with a maximum packet + * size of 'max_packet_size'. The stream is stored in a memory buffer + * with a big endian 4 byte header giving the packet size in bytes. + * + * @param s new IO context + * @param max_packet_size maximum packet size (must be > 0) + * @return zero if no error. + */ +int url_open_dyn_packet_buf(ByteIOContext **s, int max_packet_size); + +/** + * Return the written size and a pointer to the buffer. The buffer + * must be freed with av_free(). + * @param s IO context + * @param pbuffer pointer to a byte buffer + * @return the length of the byte buffer + */ +int url_close_dyn_buf(ByteIOContext *s, uint8_t **pbuffer); + +unsigned long ff_crc04C11DB7_update(unsigned long checksum, const uint8_t *buf, + unsigned int len); +unsigned long get_checksum(ByteIOContext *s); +void init_checksum(ByteIOContext *s, + unsigned long (*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len), + unsigned long checksum); + +/* udp.c */ +int udp_set_remote_url(URLContext *h, const char *uri); +int udp_get_local_port(URLContext *h); +int udp_get_file_handle(URLContext *h); + +#endif /* AVFORMAT_AVIO_H */ diff --git a/scalos/include/ffmpeg/common.h b/scalos/include/ffmpeg/common.h new file mode 100644 index 000000000..cd43abd06 --- /dev/null +++ b/scalos/include/ffmpeg/common.h @@ -0,0 +1,408 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file common.h + * common internal and external API header + */ + +#ifndef AVUTIL_COMMON_H +#define AVUTIL_COMMON_H + +#include + +#ifdef HAVE_AV_CONFIG_H +/* only include the following when compiling package */ +# include "config.h" + +# include +# include +# include +# include +# include +# include +# include +#endif /* HAVE_AV_CONFIG_H */ + +#ifndef av_always_inline +#if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0) +# define av_always_inline __attribute__((always_inline)) inline +#else +# define av_always_inline inline +#endif +#endif + +#ifndef av_noinline +#if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0) +# define av_noinline __attribute__((noinline)) +#else +# define av_noinline +#endif +#endif + +#ifndef av_pure +#if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0) +# define av_pure __attribute__((pure)) +#else +# define av_pure +#endif +#endif + +#ifndef av_const +#if defined(__GNUC__) && (__GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ > 5) +# define av_const __attribute__((const)) +#else +# define av_const +#endif +#endif + +#ifndef av_cold +#if defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ > 2) +# define av_cold __attribute__((cold)) +#else +# define av_cold +#endif +#endif + +#ifdef HAVE_AV_CONFIG_H +# include "internal.h" +#endif /* HAVE_AV_CONFIG_H */ + +#ifndef attribute_deprecated +#if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0) +# define attribute_deprecated __attribute__((deprecated)) +#else +# define attribute_deprecated +#endif +#endif + +#ifndef av_unused +#if defined(__GNUC__) +# define av_unused __attribute__((unused)) +#else +# define av_unused +#endif +#endif + +#include "mem.h" + +//rounded divison & shift +#define RSHIFT(a,b) ((a) > 0 ? ((a) + ((1<<(b))>>1))>>(b) : ((a) + ((1<<(b))>>1)-1)>>(b)) +/* assume b>0 */ +#define ROUNDED_DIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b)) +#define FFABS(a) ((a) >= 0 ? (a) : (-(a))) +#define FFSIGN(a) ((a) > 0 ? 1 : -1) + +#define FFMAX(a,b) ((a) > (b) ? (a) : (b)) +#define FFMAX3(a,b,c) FFMAX(FFMAX(a,b),c) +#define FFMIN(a,b) ((a) > (b) ? (b) : (a)) +#define FFMIN3(a,b,c) FFMIN(FFMIN(a,b),c) + +#define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0) +#define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0])) + +/* misc math functions */ +extern const uint8_t ff_log2_tab[256]; + +static inline av_const int av_log2(unsigned int v) +{ + int n = 0; + if (v & 0xffff0000) { + v >>= 16; + n += 16; + } + if (v & 0xff00) { + v >>= 8; + n += 8; + } + n += ff_log2_tab[v]; + + return n; +} + +static inline av_const int av_log2_16bit(unsigned int v) +{ + int n = 0; + if (v & 0xff00) { + v >>= 8; + n += 8; + } + n += ff_log2_tab[v]; + + return n; +} + +/* median of 3 */ +static inline av_const int mid_pred(int a, int b, int c) +{ +#ifdef HAVE_CMOV + int i=b; + __asm__ volatile( + "cmp %2, %1 \n\t" + "cmovg %1, %0 \n\t" + "cmovg %2, %1 \n\t" + "cmp %3, %1 \n\t" + "cmovl %3, %1 \n\t" + "cmp %1, %0 \n\t" + "cmovg %1, %0 \n\t" + :"+&r"(i), "+&r"(a) + :"r"(b), "r"(c) + ); + return i; +#elif 0 + int t= (a-b)&((a-b)>>31); + a-=t; + b+=t; + b-= (b-c)&((b-c)>>31); + b+= (a-b)&((a-b)>>31); + + return b; +#else + if(a>b){ + if(c>b){ + if(c>a) b=a; + else b=c; + } + }else{ + if(b>c){ + if(c>a) b=c; + else b=a; + } + } + return b; +#endif +} + +/** + * clip a signed integer value into the amin-amax range + * @param a value to clip + * @param amin minimum value of the clip range + * @param amax maximum value of the clip range + * @return clipped value + */ +static inline av_const int av_clip(int a, int amin, int amax) +{ + if (a < amin) return amin; + else if (a > amax) return amax; + else return a; +} + +/** + * clip a signed integer value into the 0-255 range + * @param a value to clip + * @return clipped value + */ +static inline av_const uint8_t av_clip_uint8(int a) +{ + if (a&(~255)) return (-a)>>31; + else return a; +} + +/** + * clip a signed integer value into the -32768,32767 range + * @param a value to clip + * @return clipped value + */ +static inline av_const int16_t av_clip_int16(int a) +{ + if ((a+32768) & ~65535) return (a>>31) ^ 32767; + else return a; +} + +/** + * clip a float value into the amin-amax range + * @param a value to clip + * @param amin minimum value of the clip range + * @param amax maximum value of the clip range + * @return clipped value + */ +static inline av_const float av_clipf(float a, float amin, float amax) +{ + if (a < amin) return amin; + else if (a > amax) return amax; + else return a; +} + +/* math */ +int64_t av_const ff_gcd(int64_t a, int64_t b); + +/** + * converts fourcc string to int + */ +static inline av_pure int ff_get_fourcc(const char *s){ +#ifdef HAVE_AV_CONFIG_H + assert( strlen(s)==4 ); +#endif + + return (s[0]) + (s[1]<<8) + (s[2]<<16) + (s[3]<<24); +} + +#define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24)) +#define MKBETAG(a,b,c,d) (d | (c << 8) | (b << 16) | (a << 24)) + +/*! + * \def GET_UTF8(val, GET_BYTE, ERROR) + * converts a UTF-8 character (up to 4 bytes long) to its 32-bit UCS-4 encoded form + * \param val is the output and should be of type uint32_t. It holds the converted + * UCS-4 character and should be a left value. + * \param GET_BYTE gets UTF-8 encoded bytes from any proper source. It can be + * a function or a statement whose return value or evaluated value is of type + * uint8_t. It will be executed up to 4 times for values in the valid UTF-8 range, + * and up to 7 times in the general case. + * \param ERROR action that should be taken when an invalid UTF-8 byte is returned + * from GET_BYTE. It should be a statement that jumps out of the macro, + * like exit(), goto, return, break, or continue. + */ +#define GET_UTF8(val, GET_BYTE, ERROR)\ + val= GET_BYTE;\ + {\ + int ones= 7 - av_log2(val ^ 255);\ + if(ones==1)\ + ERROR\ + val&= 127>>ones;\ + while(--ones > 0){\ + int tmp= GET_BYTE - 128;\ + if(tmp>>6)\ + ERROR\ + val= (val<<6) + tmp;\ + }\ + } + +/*! + * \def PUT_UTF8(val, tmp, PUT_BYTE) + * converts a 32-bit unicode character to its UTF-8 encoded form (up to 4 bytes long). + * \param val is an input only argument and should be of type uint32_t. It holds + * a ucs4 encoded unicode character that is to be converted to UTF-8. If + * val is given as a function it's executed only once. + * \param tmp is a temporary variable and should be of type uint8_t. It + * represents an intermediate value during conversion that is to be + * outputted by PUT_BYTE. + * \param PUT_BYTE writes the converted UTF-8 bytes to any proper destination. + * It could be a function or a statement, and uses tmp as the input byte. + * For example, PUT_BYTE could be "*output++ = tmp;" PUT_BYTE will be + * executed up to 4 times for values in the valid UTF-8 range and up to + * 7 times in the general case, depending on the length of the converted + * unicode character. + */ +#define PUT_UTF8(val, tmp, PUT_BYTE)\ + {\ + int bytes, shift;\ + uint32_t in = val;\ + if (in < 0x80) {\ + tmp = in;\ + PUT_BYTE\ + } else {\ + bytes = (av_log2(in) + 4) / 5;\ + shift = (bytes - 1) * 6;\ + tmp = (256 - (256 >> bytes)) | (in >> shift);\ + PUT_BYTE\ + while (shift >= 6) {\ + shift -= 6;\ + tmp = 0x80 | ((in >> shift) & 0x3f);\ + PUT_BYTE\ + }\ + }\ + } + +#if defined(ARCH_X86) || defined(ARCH_POWERPC) || defined(ARCH_BFIN) +#define AV_READ_TIME read_time +#if defined(ARCH_X86) +static inline uint64_t read_time(void) +{ + uint32_t a, d; + __asm__ volatile("rdtsc\n\t" + : "=a" (a), "=d" (d)); + return ((uint64_t)d << 32) + a; +} +#elif ARCH_BFIN +static inline uint64_t read_time(void) +{ + union { + struct { + unsigned lo; + unsigned hi; + } p; + unsigned long long c; + } t; + __asm__ volatile ("%0=cycles; %1=cycles2;" : "=d" (t.p.lo), "=d" (t.p.hi)); + return t.c; +} +#else //FIXME check ppc64 +static inline uint64_t read_time(void) +{ + uint32_t tbu, tbl, temp; + + /* from section 2.2.1 of the 32-bit PowerPC PEM */ + __asm__ volatile( + "1:\n" + "mftbu %2\n" + "mftb %0\n" + "mftbu %1\n" + "cmpw %2,%1\n" + "bne 1b\n" + : "=r"(tbl), "=r"(tbu), "=r"(temp) + : + : "cc"); + + return (((uint64_t)tbu)<<32) | (uint64_t)tbl; +} +#endif +#elif defined(HAVE_GETHRTIME) +#define AV_READ_TIME gethrtime +#endif + +#ifdef AV_READ_TIME +#define START_TIMER \ +uint64_t tend;\ +uint64_t tstart= AV_READ_TIME();\ + +#define STOP_TIMER(id) \ +tend= AV_READ_TIME();\ +{\ + static uint64_t tsum=0;\ + static int tcount=0;\ + static int tskip_count=0;\ + if(tcount<2 || tend - tstart < FFMAX(8*tsum/tcount, 2000)){\ + tsum+= tend - tstart;\ + tcount++;\ + }else\ + tskip_count++;\ + if(((tcount+tskip_count)&(tcount+tskip_count-1))==0){\ + av_log(NULL, AV_LOG_ERROR, "%"PRIu64" dezicycles in %s, %d runs, %d skips\n",\ + tsum*10/tcount, id, tcount, tskip_count);\ + }\ +} +#else +#define START_TIMER +#define STOP_TIMER(id) {} +#endif + +/** + * Returns NULL if CONFIG_SMALL is defined otherwise the argument + * without modifications, used to disable the definition of strings + * (for example AVCodec long_names). + */ +#ifdef CONFIG_SMALL +# define NULL_IF_CONFIG_SMALL(x) NULL +#else +# define NULL_IF_CONFIG_SMALL(x) x +#endif + +#endif /* AVUTIL_COMMON_H */ diff --git a/scalos/include/ffmpeg/integer.h b/scalos/include/ffmpeg/integer.h new file mode 100644 index 000000000..6c5c27414 --- /dev/null +++ b/scalos/include/ffmpeg/integer.h @@ -0,0 +1,84 @@ +/* + * arbitrary precision integers + * Copyright (c) 2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file integer.h + * arbitrary precision integers + * @author Michael Niedermayer + */ + +#ifndef AVUTIL_INTEGER_H +#define AVUTIL_INTEGER_H + +#include +#include "common.h" + +#define AV_INTEGER_SIZE 8 + +typedef struct AVInteger{ + uint16_t v[AV_INTEGER_SIZE]; +} AVInteger; + +AVInteger av_add_i(AVInteger a, AVInteger b) av_const; +AVInteger av_sub_i(AVInteger a, AVInteger b) av_const; + +/** + * returns the rounded down value of the logarithm of base 2 of the given AVInteger. + * this is simply the index of the most significant bit which is 1. Or 0 of all bits are 0 + */ +int av_log2_i(AVInteger a) av_const; +AVInteger av_mul_i(AVInteger a, AVInteger b) av_const; + +/** + * returns 0 if a==b, 1 if a>b and -1 if a + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_INTFLOAT_READWRITE_H +#define AVUTIL_INTFLOAT_READWRITE_H + +#include +#include "common.h" + +/* IEEE 80 bits extended float */ +typedef struct AVExtFloat { + uint8_t exponent[2]; + uint8_t mantissa[8]; +} AVExtFloat; + +double av_int2dbl(int64_t v) av_const; +float av_int2flt(int32_t v) av_const; +double av_ext2dbl(const AVExtFloat ext) av_const; +int64_t av_dbl2int(double d) av_const; +int32_t av_flt2int(float d) av_const; +AVExtFloat av_dbl2ext(double d) av_const; + +#endif /* AVUTIL_INTFLOAT_READWRITE_H */ diff --git a/scalos/include/ffmpeg/libavcodec/avcodec.h b/scalos/include/ffmpeg/libavcodec/avcodec.h new file mode 100644 index 000000000..85448d8c6 --- /dev/null +++ b/scalos/include/ffmpeg/libavcodec/avcodec.h @@ -0,0 +1,3036 @@ +/* + * copyright (c) 2001 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AVCODEC_H +#define AVCODEC_AVCODEC_H + +/** + * @file avcodec.h + * external API header + */ + + +#include "libavutil/avutil.h" + +#define LIBAVCODEC_VERSION_MAJOR 52 +#define LIBAVCODEC_VERSION_MINOR 6 +#define LIBAVCODEC_VERSION_MICRO 3 + +#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ + LIBAVCODEC_VERSION_MINOR, \ + LIBAVCODEC_VERSION_MICRO) +#define LIBAVCODEC_VERSION AV_VERSION(LIBAVCODEC_VERSION_MAJOR, \ + LIBAVCODEC_VERSION_MINOR, \ + LIBAVCODEC_VERSION_MICRO) +#define LIBAVCODEC_BUILD LIBAVCODEC_VERSION_INT + +#define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION) + +#define AV_NOPTS_VALUE INT64_C(0x8000000000000000) +#define AV_TIME_BASE 1000000 +#define AV_TIME_BASE_Q (AVRational){1, AV_TIME_BASE} + +/** + * Identifies the syntax and semantics of the bitstream. + * The principle is roughly: + * Two decoders with the same ID can decode the same streams. + * Two encoders with the same ID can encode compatible streams. + * There may be slight deviations from the principle due to implementation + * details. + * + * If you add a codec ID to this list, add it so that + * 1. no value of a existing codec ID changes (that would break ABI), + * 2. it is as close as possible to similar codecs. + */ +enum CodecID { + CODEC_ID_NONE, + + /* video codecs */ + CODEC_ID_MPEG1VIDEO, + CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding + CODEC_ID_MPEG2VIDEO_XVMC, + CODEC_ID_H261, + CODEC_ID_H263, + CODEC_ID_RV10, + CODEC_ID_RV20, + CODEC_ID_MJPEG, + CODEC_ID_MJPEGB, + CODEC_ID_LJPEG, + CODEC_ID_SP5X, + CODEC_ID_JPEGLS, + CODEC_ID_MPEG4, + CODEC_ID_RAWVIDEO, + CODEC_ID_MSMPEG4V1, + CODEC_ID_MSMPEG4V2, + CODEC_ID_MSMPEG4V3, + CODEC_ID_WMV1, + CODEC_ID_WMV2, + CODEC_ID_H263P, + CODEC_ID_H263I, + CODEC_ID_FLV1, + CODEC_ID_SVQ1, + CODEC_ID_SVQ3, + CODEC_ID_DVVIDEO, + CODEC_ID_HUFFYUV, + CODEC_ID_CYUV, + CODEC_ID_H264, + CODEC_ID_INDEO3, + CODEC_ID_VP3, + CODEC_ID_THEORA, + CODEC_ID_ASV1, + CODEC_ID_ASV2, + CODEC_ID_FFV1, + CODEC_ID_4XM, + CODEC_ID_VCR1, + CODEC_ID_CLJR, + CODEC_ID_MDEC, + CODEC_ID_ROQ, + CODEC_ID_INTERPLAY_VIDEO, + CODEC_ID_XAN_WC3, + CODEC_ID_XAN_WC4, + CODEC_ID_RPZA, + CODEC_ID_CINEPAK, + CODEC_ID_WS_VQA, + CODEC_ID_MSRLE, + CODEC_ID_MSVIDEO1, + CODEC_ID_IDCIN, + CODEC_ID_8BPS, + CODEC_ID_SMC, + CODEC_ID_FLIC, + CODEC_ID_TRUEMOTION1, + CODEC_ID_VMDVIDEO, + CODEC_ID_MSZH, + CODEC_ID_ZLIB, + CODEC_ID_QTRLE, + CODEC_ID_SNOW, + CODEC_ID_TSCC, + CODEC_ID_ULTI, + CODEC_ID_QDRAW, + CODEC_ID_VIXL, + CODEC_ID_QPEG, + CODEC_ID_XVID, + CODEC_ID_PNG, + CODEC_ID_PPM, + CODEC_ID_PBM, + CODEC_ID_PGM, + CODEC_ID_PGMYUV, + CODEC_ID_PAM, + CODEC_ID_FFVHUFF, + CODEC_ID_RV30, + CODEC_ID_RV40, + CODEC_ID_VC1, + CODEC_ID_WMV3, + CODEC_ID_LOCO, + CODEC_ID_WNV1, + CODEC_ID_AASC, + CODEC_ID_INDEO2, + CODEC_ID_FRAPS, + CODEC_ID_TRUEMOTION2, + CODEC_ID_BMP, + CODEC_ID_CSCD, + CODEC_ID_MMVIDEO, + CODEC_ID_ZMBV, + CODEC_ID_AVS, + CODEC_ID_SMACKVIDEO, + CODEC_ID_NUV, + CODEC_ID_KMVC, + CODEC_ID_FLASHSV, + CODEC_ID_CAVS, + CODEC_ID_JPEG2000, + CODEC_ID_VMNC, + CODEC_ID_VP5, + CODEC_ID_VP6, + CODEC_ID_VP6F, + CODEC_ID_TARGA, + CODEC_ID_DSICINVIDEO, + CODEC_ID_TIERTEXSEQVIDEO, + CODEC_ID_TIFF, + CODEC_ID_GIF, + CODEC_ID_FFH264, + CODEC_ID_DXA, + CODEC_ID_DNXHD, + CODEC_ID_THP, + CODEC_ID_SGI, + CODEC_ID_C93, + CODEC_ID_BETHSOFTVID, + CODEC_ID_PTX, + CODEC_ID_TXD, + CODEC_ID_VP6A, + CODEC_ID_AMV, + CODEC_ID_VB, + CODEC_ID_PCX, + CODEC_ID_SUNRAST, + CODEC_ID_INDEO4, + CODEC_ID_INDEO5, + CODEC_ID_MIMIC, + CODEC_ID_RL2, + CODEC_ID_8SVX_EXP, + CODEC_ID_8SVX_FIB, + CODEC_ID_ESCAPE124, + CODEC_ID_DIRAC, + CODEC_ID_BFI, + CODEC_ID_CMV, + CODEC_ID_MOTIONPIXELS, + CODEC_ID_TGV, + CODEC_ID_TGQ, + + /* various PCM "codecs" */ + CODEC_ID_PCM_S16LE= 0x10000, + CODEC_ID_PCM_S16BE, + CODEC_ID_PCM_U16LE, + CODEC_ID_PCM_U16BE, + CODEC_ID_PCM_S8, + CODEC_ID_PCM_U8, + CODEC_ID_PCM_MULAW, + CODEC_ID_PCM_ALAW, + CODEC_ID_PCM_S32LE, + CODEC_ID_PCM_S32BE, + CODEC_ID_PCM_U32LE, + CODEC_ID_PCM_U32BE, + CODEC_ID_PCM_S24LE, + CODEC_ID_PCM_S24BE, + CODEC_ID_PCM_U24LE, + CODEC_ID_PCM_U24BE, + CODEC_ID_PCM_S24DAUD, + CODEC_ID_PCM_ZORK, + CODEC_ID_PCM_S16LE_PLANAR, + CODEC_ID_PCM_DVD, + CODEC_ID_PCM_F32BE, + CODEC_ID_PCM_F32LE, + CODEC_ID_PCM_F64BE, + CODEC_ID_PCM_F64LE, + + /* various ADPCM codecs */ + CODEC_ID_ADPCM_IMA_QT= 0x11000, + CODEC_ID_ADPCM_IMA_WAV, + CODEC_ID_ADPCM_IMA_DK3, + CODEC_ID_ADPCM_IMA_DK4, + CODEC_ID_ADPCM_IMA_WS, + CODEC_ID_ADPCM_IMA_SMJPEG, + CODEC_ID_ADPCM_MS, + CODEC_ID_ADPCM_4XM, + CODEC_ID_ADPCM_XA, + CODEC_ID_ADPCM_ADX, + CODEC_ID_ADPCM_EA, + CODEC_ID_ADPCM_G726, + CODEC_ID_ADPCM_CT, + CODEC_ID_ADPCM_SWF, + CODEC_ID_ADPCM_YAMAHA, + CODEC_ID_ADPCM_SBPRO_4, + CODEC_ID_ADPCM_SBPRO_3, + CODEC_ID_ADPCM_SBPRO_2, + CODEC_ID_ADPCM_THP, + CODEC_ID_ADPCM_IMA_AMV, + CODEC_ID_ADPCM_EA_R1, + CODEC_ID_ADPCM_EA_R3, + CODEC_ID_ADPCM_EA_R2, + CODEC_ID_ADPCM_IMA_EA_SEAD, + CODEC_ID_ADPCM_IMA_EA_EACS, + CODEC_ID_ADPCM_EA_XAS, + CODEC_ID_ADPCM_EA_MAXIS_XA, + + /* AMR */ + CODEC_ID_AMR_NB= 0x12000, + CODEC_ID_AMR_WB, + + /* RealAudio codecs*/ + CODEC_ID_RA_144= 0x13000, + CODEC_ID_RA_288, + + /* various DPCM codecs */ + CODEC_ID_ROQ_DPCM= 0x14000, + CODEC_ID_INTERPLAY_DPCM, + CODEC_ID_XAN_DPCM, + CODEC_ID_SOL_DPCM, + + /* audio codecs */ + CODEC_ID_MP2= 0x15000, + CODEC_ID_MP3, ///< preferred ID for decoding MPEG audio layer 1, 2 or 3 + CODEC_ID_AAC, + CODEC_ID_AC3, + CODEC_ID_DTS, + CODEC_ID_VORBIS, + CODEC_ID_DVAUDIO, + CODEC_ID_WMAV1, + CODEC_ID_WMAV2, + CODEC_ID_MACE3, + CODEC_ID_MACE6, + CODEC_ID_VMDAUDIO, + CODEC_ID_SONIC, + CODEC_ID_SONIC_LS, + CODEC_ID_FLAC, + CODEC_ID_MP3ADU, + CODEC_ID_MP3ON4, + CODEC_ID_SHORTEN, + CODEC_ID_ALAC, + CODEC_ID_WESTWOOD_SND1, + CODEC_ID_GSM, ///< as in Berlin toast format + CODEC_ID_QDM2, + CODEC_ID_COOK, + CODEC_ID_TRUESPEECH, + CODEC_ID_TTA, + CODEC_ID_SMACKAUDIO, + CODEC_ID_QCELP, + CODEC_ID_WAVPACK, + CODEC_ID_DSICINAUDIO, + CODEC_ID_IMC, + CODEC_ID_MUSEPACK7, + CODEC_ID_MLP, + CODEC_ID_GSM_MS, /* as found in WAV */ + CODEC_ID_ATRAC3, + CODEC_ID_VOXWARE, + CODEC_ID_APE, + CODEC_ID_NELLYMOSER, + CODEC_ID_MUSEPACK8, + CODEC_ID_SPEEX, + CODEC_ID_WMAVOICE, + CODEC_ID_WMAPRO, + CODEC_ID_WMALOSSLESS, + CODEC_ID_ATRAC3P, + CODEC_ID_EAC3, + CODEC_ID_SIPR, + + /* subtitle codecs */ + CODEC_ID_DVD_SUBTITLE= 0x17000, + CODEC_ID_DVB_SUBTITLE, + CODEC_ID_TEXT, ///< raw UTF-8 text + CODEC_ID_XSUB, + CODEC_ID_SSA, + CODEC_ID_MOV_TEXT, + + /* other specific kind of codecs (generally used for attachments) */ + CODEC_ID_TTF= 0x18000, + + CODEC_ID_PROBE= 0x19000, ///< codec_id is not known (like CODEC_ID_NONE) but lavf should attempt to identify it + + CODEC_ID_MPEG2TS= 0x20000, /**< _FAKE_ codec to indicate a raw MPEG-2 TS + * stream (only used by libavformat) */ +}; + +enum CodecType { + CODEC_TYPE_UNKNOWN = -1, + CODEC_TYPE_VIDEO, + CODEC_TYPE_AUDIO, + CODEC_TYPE_DATA, + CODEC_TYPE_SUBTITLE, + CODEC_TYPE_ATTACHMENT, + CODEC_TYPE_NB +}; + +/** + * all in native-endian format + */ +enum SampleFormat { + SAMPLE_FMT_NONE = -1, + SAMPLE_FMT_U8, ///< unsigned 8 bits + SAMPLE_FMT_S16, ///< signed 16 bits + SAMPLE_FMT_S32, ///< signed 32 bits + SAMPLE_FMT_FLT, ///< float + SAMPLE_FMT_DBL, ///< double + SAMPLE_FMT_NB ///< Number of sample formats. DO NOT USE if dynamically linking to libavcodec +}; + +/* Audio channel masks */ +#define CH_FRONT_LEFT 0x00000001 +#define CH_FRONT_RIGHT 0x00000002 +#define CH_FRONT_CENTER 0x00000004 +#define CH_LOW_FREQUENCY 0x00000008 +#define CH_BACK_LEFT 0x00000010 +#define CH_BACK_RIGHT 0x00000020 +#define CH_FRONT_LEFT_OF_CENTER 0x00000040 +#define CH_FRONT_RIGHT_OF_CENTER 0x00000080 +#define CH_BACK_CENTER 0x00000100 +#define CH_SIDE_LEFT 0x00000200 +#define CH_SIDE_RIGHT 0x00000400 +#define CH_TOP_CENTER 0x00000800 +#define CH_TOP_FRONT_LEFT 0x00001000 +#define CH_TOP_FRONT_CENTER 0x00002000 +#define CH_TOP_FRONT_RIGHT 0x00004000 +#define CH_TOP_BACK_LEFT 0x00008000 +#define CH_TOP_BACK_CENTER 0x00010000 +#define CH_TOP_BACK_RIGHT 0x00020000 +#define CH_STEREO_LEFT 0x20000000 ///< Stereo downmix. +#define CH_STEREO_RIGHT 0x40000000 ///< See CH_STEREO_LEFT. + +/* Audio channel convenience macros */ +#define CH_LAYOUT_MONO (CH_FRONT_CENTER) +#define CH_LAYOUT_STEREO (CH_FRONT_LEFT|CH_FRONT_RIGHT) +#define CH_LAYOUT_SURROUND (CH_LAYOUT_STEREO|CH_FRONT_CENTER) +#define CH_LAYOUT_QUAD (CH_LAYOUT_STEREO|CH_BACK_LEFT|CH_BACK_RIGHT) +#define CH_LAYOUT_5POINT0 (CH_LAYOUT_SURROUND|CH_SIDE_LEFT|CH_SIDE_RIGHT) +#define CH_LAYOUT_5POINT1 (CH_LAYOUT_5POINT0|CH_LOW_FREQUENCY) +#define CH_LAYOUT_7POINT1 (CH_LAYOUT_5POINT1|CH_BACK_LEFT|CH_BACK_RIGHT) +#define CH_LAYOUT_7POINT1_WIDE (CH_LAYOUT_SURROUND|CH_LOW_FREQUENCY|\ + CH_BACK_LEFT|CH_BACK_RIGHT|\ + CH_FRONT_LEFT_OF_CENTER|CH_FRONT_RIGHT_OF_CENTER) +#define CH_LAYOUT_STEREO_DOWNMIX (CH_STEREO_LEFT|CH_STEREO_RIGHT) + +/* in bytes */ +#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio + +/** + * Required number of additionally allocated bytes at the end of the input bitstream for decoding. + * This is mainly needed because some optimized bitstream readers read + * 32 or 64 bit at once and could read over the end.
+ * Note: If the first 23 bits of the additional bytes are not 0, then damaged + * MPEG bitstreams could cause overread and segfault. + */ +#define FF_INPUT_BUFFER_PADDING_SIZE 8 + +/** + * minimum encoding buffer size + * Used to avoid some checks during header writing. + */ +#define FF_MIN_BUFFER_SIZE 16384 + +/** + * motion estimation type. + */ +enum Motion_Est_ID { + ME_ZERO = 1, ///< no search, that is use 0,0 vector whenever one is needed + ME_FULL, + ME_LOG, + ME_PHODS, + ME_EPZS, ///< enhanced predictive zonal search + ME_X1, ///< reserved for experiments + ME_HEX, ///< hexagon based search + ME_UMH, ///< uneven multi-hexagon search + ME_ITER, ///< iterative search + ME_TESA, ///< transformed exhaustive search algorithm +}; + +enum AVDiscard{ + /* We leave some space between them for extensions (drop some + * keyframes for intra-only or drop just some bidir frames). */ + AVDISCARD_NONE =-16, ///< discard nothing + AVDISCARD_DEFAULT= 0, ///< discard useless packets like 0 size packets in avi + AVDISCARD_NONREF = 8, ///< discard all non reference + AVDISCARD_BIDIR = 16, ///< discard all bidirectional frames + AVDISCARD_NONKEY = 32, ///< discard all frames except keyframes + AVDISCARD_ALL = 48, ///< discard all +}; + +typedef struct RcOverride{ + int start_frame; + int end_frame; + int qscale; // If this is 0 then quality_factor will be used instead. + float quality_factor; +} RcOverride; + +#define FF_MAX_B_FRAMES 16 + +/* encoding support + These flags can be passed in AVCodecContext.flags before initialization. + Note: Not everything is supported yet. +*/ + +#define CODEC_FLAG_QSCALE 0x0002 ///< Use fixed qscale. +#define CODEC_FLAG_4MV 0x0004 ///< 4 MV per MB allowed / advanced prediction for H.263. +#define CODEC_FLAG_QPEL 0x0010 ///< Use qpel MC. +#define CODEC_FLAG_GMC 0x0020 ///< Use GMC. +#define CODEC_FLAG_MV0 0x0040 ///< Always try a MB with MV=<0,0>. +#define CODEC_FLAG_PART 0x0080 ///< Use data partitioning. +/** + * The parent program guarantees that the input for B-frames containing + * streams is not written to for at least s->max_b_frames+1 frames, if + * this is not set the input will be copied. + */ +#define CODEC_FLAG_INPUT_PRESERVED 0x0100 +#define CODEC_FLAG_PASS1 0x0200 ///< Use internal 2pass ratecontrol in first pass mode. +#define CODEC_FLAG_PASS2 0x0400 ///< Use internal 2pass ratecontrol in second pass mode. +#define CODEC_FLAG_EXTERN_HUFF 0x1000 ///< Use external Huffman table (for MJPEG). +#define CODEC_FLAG_GRAY 0x2000 ///< Only decode/encode grayscale. +#define CODEC_FLAG_EMU_EDGE 0x4000 ///< Don't draw edges. +#define CODEC_FLAG_PSNR 0x8000 ///< error[?] variables will be set during encoding. +#define CODEC_FLAG_TRUNCATED 0x00010000 /** Input bitstream might be truncated at a random + location instead of only at frame boundaries. */ +#define CODEC_FLAG_NORMALIZE_AQP 0x00020000 ///< Normalize adaptive quantization. +#define CODEC_FLAG_INTERLACED_DCT 0x00040000 ///< Use interlaced DCT. +#define CODEC_FLAG_LOW_DELAY 0x00080000 ///< Force low delay. +#define CODEC_FLAG_ALT_SCAN 0x00100000 ///< Use alternate scan. +#define CODEC_FLAG_GLOBAL_HEADER 0x00400000 ///< Place global headers in extradata instead of every keyframe. +#define CODEC_FLAG_BITEXACT 0x00800000 ///< Use only bitexact stuff (except (I)DCT). +/* Fx : Flag for h263+ extra options */ +#define CODEC_FLAG_AC_PRED 0x01000000 ///< H.263 advanced intra coding / MPEG-4 AC prediction +#define CODEC_FLAG_H263P_UMV 0x02000000 ///< unlimited motion vector +#define CODEC_FLAG_CBP_RD 0x04000000 ///< Use rate distortion optimization for cbp. +#define CODEC_FLAG_QP_RD 0x08000000 ///< Use rate distortion optimization for qp selectioon. +#define CODEC_FLAG_H263P_AIV 0x00000008 ///< H.263 alternative inter VLC +#define CODEC_FLAG_OBMC 0x00000001 ///< OBMC +#define CODEC_FLAG_LOOP_FILTER 0x00000800 ///< loop filter +#define CODEC_FLAG_H263P_SLICE_STRUCT 0x10000000 +#define CODEC_FLAG_INTERLACED_ME 0x20000000 ///< interlaced motion estimation +#define CODEC_FLAG_SVCD_SCAN_OFFSET 0x40000000 ///< Will reserve space for SVCD scan offset user data. +#define CODEC_FLAG_CLOSED_GOP 0x80000000 +#define CODEC_FLAG2_FAST 0x00000001 ///< Allow non spec compliant speedup tricks. +#define CODEC_FLAG2_STRICT_GOP 0x00000002 ///< Strictly enforce GOP size. +#define CODEC_FLAG2_NO_OUTPUT 0x00000004 ///< Skip bitstream encoding. +#define CODEC_FLAG2_LOCAL_HEADER 0x00000008 ///< Place global headers at every keyframe instead of in extradata. +#define CODEC_FLAG2_BPYRAMID 0x00000010 ///< H.264 allow B-frames to be used as references. +#define CODEC_FLAG2_WPRED 0x00000020 ///< H.264 weighted biprediction for B-frames +#define CODEC_FLAG2_MIXED_REFS 0x00000040 ///< H.264 one reference per partition, as opposed to one reference per macroblock +#define CODEC_FLAG2_8X8DCT 0x00000080 ///< H.264 high profile 8x8 transform +#define CODEC_FLAG2_FASTPSKIP 0x00000100 ///< H.264 fast pskip +#define CODEC_FLAG2_AUD 0x00000200 ///< H.264 access unit delimiters +#define CODEC_FLAG2_BRDO 0x00000400 ///< B-frame rate-distortion optimization +#define CODEC_FLAG2_INTRA_VLC 0x00000800 ///< Use MPEG-2 intra VLC table. +#define CODEC_FLAG2_MEMC_ONLY 0x00001000 ///< Only do ME/MC (I frames -> ref, P frame -> ME+MC). +#define CODEC_FLAG2_DROP_FRAME_TIMECODE 0x00002000 ///< timecode is in drop frame format. +#define CODEC_FLAG2_SKIP_RD 0x00004000 ///< RD optimal MB level residual skipping +#define CODEC_FLAG2_CHUNKS 0x00008000 ///< Input bitstream might be truncated at a packet boundaries instead of only at frame boundaries. +#define CODEC_FLAG2_NON_LINEAR_QUANT 0x00010000 ///< Use MPEG-2 nonlinear quantizer. +#define CODEC_FLAG2_BIT_RESERVOIR 0x00020000 ///< Use a bit reservoir when encoding if possible + +/* Unsupported options : + * Syntax Arithmetic coding (SAC) + * Reference Picture Selection + * Independent Segment Decoding */ +/* /Fx */ +/* codec capabilities */ + +#define CODEC_CAP_DRAW_HORIZ_BAND 0x0001 ///< Decoder can use draw_horiz_band callback. +/** + * Codec uses get_buffer() for allocating buffers. + * direct rendering method 1 + */ +#define CODEC_CAP_DR1 0x0002 +/* If 'parse_only' field is true, then avcodec_parse_frame() can be used. */ +#define CODEC_CAP_PARSE_ONLY 0x0004 +#define CODEC_CAP_TRUNCATED 0x0008 +/* Codec can export data for HW decoding (XvMC). */ +#define CODEC_CAP_HWACCEL 0x0010 +/** + * Codec has a nonzero delay and needs to be fed with NULL at the end to get the delayed data. + * If this is not set, the codec is guaranteed to never be fed with NULL data. + */ +#define CODEC_CAP_DELAY 0x0020 +/** + * Codec can be fed a final frame with a smaller size. + * This can be used to prevent truncation of the last audio samples. + */ +#define CODEC_CAP_SMALL_LAST_FRAME 0x0040 + +//The following defines may change, don't expect compatibility if you use them. +#define MB_TYPE_INTRA4x4 0x0001 +#define MB_TYPE_INTRA16x16 0x0002 //FIXME H.264-specific +#define MB_TYPE_INTRA_PCM 0x0004 //FIXME H.264-specific +#define MB_TYPE_16x16 0x0008 +#define MB_TYPE_16x8 0x0010 +#define MB_TYPE_8x16 0x0020 +#define MB_TYPE_8x8 0x0040 +#define MB_TYPE_INTERLACED 0x0080 +#define MB_TYPE_DIRECT2 0x0100 //FIXME +#define MB_TYPE_ACPRED 0x0200 +#define MB_TYPE_GMC 0x0400 +#define MB_TYPE_SKIP 0x0800 +#define MB_TYPE_P0L0 0x1000 +#define MB_TYPE_P1L0 0x2000 +#define MB_TYPE_P0L1 0x4000 +#define MB_TYPE_P1L1 0x8000 +#define MB_TYPE_L0 (MB_TYPE_P0L0 | MB_TYPE_P1L0) +#define MB_TYPE_L1 (MB_TYPE_P0L1 | MB_TYPE_P1L1) +#define MB_TYPE_L0L1 (MB_TYPE_L0 | MB_TYPE_L1) +#define MB_TYPE_QUANT 0x00010000 +#define MB_TYPE_CBP 0x00020000 +//Note bits 24-31 are reserved for codec specific use (h264 ref0, mpeg1 0mv, ...) + +/** + * Pan Scan area. + * This specifies the area which should be displayed. + * Note there may be multiple such areas for one frame. + */ +typedef struct AVPanScan{ + /** + * id + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int id; + + /** + * width and height in 1/16 pel + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int width; + int height; + + /** + * position of the top left corner in 1/16 pel for up to 3 fields/frames + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int16_t position[3][2]; +}AVPanScan; + +#define FF_COMMON_FRAME \ + /**\ + * pointer to the picture planes.\ + * This might be different from the first allocated byte\ + * - encoding: \ + * - decoding: \ + */\ + uint8_t *data[4];\ + int linesize[4];\ + /**\ + * pointer to the first allocated byte of the picture. Can be used in get_buffer/release_buffer.\ + * This isn't used by libavcodec unless the default get/release_buffer() is used.\ + * - encoding: \ + * - decoding: \ + */\ + uint8_t *base[4];\ + /**\ + * 1 -> keyframe, 0-> not\ + * - encoding: Set by libavcodec.\ + * - decoding: Set by libavcodec.\ + */\ + int key_frame;\ +\ + /**\ + * Picture type of the frame, see ?_TYPE below.\ + * - encoding: Set by libavcodec. for coded_picture (and set by user for input).\ + * - decoding: Set by libavcodec.\ + */\ + int pict_type;\ +\ + /**\ + * presentation timestamp in time_base units (time when frame should be shown to user)\ + * If AV_NOPTS_VALUE then frame_rate = 1/time_base will be assumed.\ + * - encoding: MUST be set by user.\ + * - decoding: Set by libavcodec.\ + */\ + int64_t pts;\ +\ + /**\ + * picture number in bitstream order\ + * - encoding: set by\ + * - decoding: Set by libavcodec.\ + */\ + int coded_picture_number;\ + /**\ + * picture number in display order\ + * - encoding: set by\ + * - decoding: Set by libavcodec.\ + */\ + int display_picture_number;\ +\ + /**\ + * quality (between 1 (good) and FF_LAMBDA_MAX (bad)) \ + * - encoding: Set by libavcodec. for coded_picture (and set by user for input).\ + * - decoding: Set by libavcodec.\ + */\ + int quality; \ +\ + /**\ + * buffer age (1->was last buffer and dint change, 2->..., ...).\ + * Set to INT_MAX if the buffer has not been used yet.\ + * - encoding: unused\ + * - decoding: MUST be set by get_buffer().\ + */\ + int age;\ +\ + /**\ + * is this picture used as reference\ + * The values for this are the same as the MpegEncContext.picture_structure\ + * variable, that is 1->top field, 2->bottom field, 3->frame/both fields.\ + * - encoding: unused\ + * - decoding: Set by libavcodec. (before get_buffer() call)).\ + */\ + int reference;\ +\ + /**\ + * QP table\ + * - encoding: unused\ + * - decoding: Set by libavcodec.\ + */\ + int8_t *qscale_table;\ + /**\ + * QP store stride\ + * - encoding: unused\ + * - decoding: Set by libavcodec.\ + */\ + int qstride;\ +\ + /**\ + * mbskip_table[mb]>=1 if MB didn't change\ + * stride= mb_width = (width+15)>>4\ + * - encoding: unused\ + * - decoding: Set by libavcodec.\ + */\ + uint8_t *mbskip_table;\ +\ + /**\ + * motion vector table\ + * @code\ + * example:\ + * int mv_sample_log2= 4 - motion_subsample_log2;\ + * int mb_width= (width+15)>>4;\ + * int mv_stride= (mb_width << mv_sample_log2) + 1;\ + * motion_val[direction][x + y*mv_stride][0->mv_x, 1->mv_y];\ + * @endcode\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec.\ + */\ + int16_t (*motion_val[2])[2];\ +\ + /**\ + * macroblock type table\ + * mb_type_base + mb_width + 2\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec.\ + */\ + uint32_t *mb_type;\ +\ + /**\ + * log2 of the size of the block which a single vector in motion_val represents: \ + * (4->16x16, 3->8x8, 2-> 4x4, 1-> 2x2)\ + * - encoding: unused\ + * - decoding: Set by libavcodec.\ + */\ + uint8_t motion_subsample_log2;\ +\ + /**\ + * for some private data of the user\ + * - encoding: unused\ + * - decoding: Set by user.\ + */\ + void *opaque;\ +\ + /**\ + * error\ + * - encoding: Set by libavcodec. if flags&CODEC_FLAG_PSNR.\ + * - decoding: unused\ + */\ + uint64_t error[4];\ +\ + /**\ + * type of the buffer (to keep track of who has to deallocate data[*])\ + * - encoding: Set by the one who allocates it.\ + * - decoding: Set by the one who allocates it.\ + * Note: User allocated (direct rendering) & internal buffers cannot coexist currently.\ + */\ + int type;\ + \ + /**\ + * When decoding, this signals how much the picture must be delayed.\ + * extra_delay = repeat_pict / (2*fps)\ + * - encoding: unused\ + * - decoding: Set by libavcodec.\ + */\ + int repeat_pict;\ + \ + /**\ + * \ + */\ + int qscale_type;\ + \ + /**\ + * The content of the picture is interlaced.\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec. (default 0)\ + */\ + int interlaced_frame;\ + \ + /**\ + * If the content is interlaced, is top field displayed first.\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec.\ + */\ + int top_field_first;\ + \ + /**\ + * Pan scan.\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec.\ + */\ + AVPanScan *pan_scan;\ + \ + /**\ + * Tell user application that palette has changed from previous frame.\ + * - encoding: ??? (no palette-enabled encoder yet)\ + * - decoding: Set by libavcodec. (default 0).\ + */\ + int palette_has_changed;\ + \ + /**\ + * codec suggestion on buffer type if != 0\ + * - encoding: unused\ + * - decoding: Set by libavcodec. (before get_buffer() call)).\ + */\ + int buffer_hints;\ +\ + /**\ + * DCT coefficients\ + * - encoding: unused\ + * - decoding: Set by libavcodec.\ + */\ + short *dct_coeff;\ +\ + /**\ + * motion referece frame index\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec.\ + */\ + int8_t *ref_index[2];\ +\ + /**\ + * reordered opaque 64bit number (generally a PTS) from AVCodecContext.reordered_opaque\ + * output in AVFrame.reordered_opaque\ + * - encoding: unused\ + * - decoding: Read by user.\ + */\ + int64_t reordered_opaque;\ + + +#define FF_QSCALE_TYPE_MPEG1 0 +#define FF_QSCALE_TYPE_MPEG2 1 +#define FF_QSCALE_TYPE_H264 2 + +#define FF_BUFFER_TYPE_INTERNAL 1 +#define FF_BUFFER_TYPE_USER 2 ///< direct rendering buffers (image is (de)allocated by user) +#define FF_BUFFER_TYPE_SHARED 4 ///< Buffer from somewhere else; don't deallocate image (data/base), all other tables are not shared. +#define FF_BUFFER_TYPE_COPY 8 ///< Just a (modified) copy of some other buffer, don't deallocate anything. + + +#define FF_I_TYPE 1 ///< Intra +#define FF_P_TYPE 2 ///< Predicted +#define FF_B_TYPE 3 ///< Bi-dir predicted +#define FF_S_TYPE 4 ///< S(GMC)-VOP MPEG4 +#define FF_SI_TYPE 5 ///< Switching Intra +#define FF_SP_TYPE 6 ///< Switching Predicted +#define FF_BI_TYPE 7 + +#define FF_BUFFER_HINTS_VALID 0x01 // Buffer hints value is meaningful (if 0 ignore). +#define FF_BUFFER_HINTS_READABLE 0x02 // Codec will read from buffer. +#define FF_BUFFER_HINTS_PRESERVE 0x04 // User must not alter buffer content. +#define FF_BUFFER_HINTS_REUSABLE 0x08 // Codec will reuse the buffer (update). + +/** + * Audio Video Frame. + * New fields can be added to the end of FF_COMMON_FRAME with minor version + * bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. No fields should be added into AVFrame before or after + * FF_COMMON_FRAME! + * sizeof(AVFrame) must not be used outside libav*. + */ +typedef struct AVFrame { + FF_COMMON_FRAME +} AVFrame; + +/** + * main external API structure. + * New fields can be added to the end with minor version bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. + * sizeof(AVCodecContext) must not be used outside libav*. + */ +typedef struct AVCodecContext { + /** + * information on struct for av_log + * - set by avcodec_alloc_context + */ + const AVClass *av_class; + /** + * the average bitrate + * - encoding: Set by user; unused for constant quantizer encoding. + * - decoding: Set by libavcodec. 0 or some bitrate if this info is available in the stream. + */ + int bit_rate; + + /** + * number of bits the bitstream is allowed to diverge from the reference. + * the reference can be CBR (for CBR pass1) or VBR (for pass2) + * - encoding: Set by user; unused for constant quantizer encoding. + * - decoding: unused + */ + int bit_rate_tolerance; + + /** + * CODEC_FLAG_*. + * - encoding: Set by user. + * - decoding: Set by user. + */ + int flags; + + /** + * Some codecs need additional format info. It is stored here. + * If any muxer uses this then ALL demuxers/parsers AND encoders for the + * specific codec MUST set it correctly otherwise stream copy breaks. + * In general use of this field by muxers is not recommanded. + * - encoding: Set by libavcodec. + * - decoding: Set by libavcodec. (FIXME: Is this OK?) + */ + int sub_id; + + /** + * Motion estimation algorithm used for video coding. + * 1 (zero), 2 (full), 3 (log), 4 (phods), 5 (epzs), 6 (x1), 7 (hex), + * 8 (umh), 9 (iter), 10 (tesa) [7, 8, 10 are x264 specific, 9 is snow specific] + * - encoding: MUST be set by user. + * - decoding: unused + */ + int me_method; + + /** + * some codecs need / can use extradata like Huffman tables. + * mjpeg: Huffman tables + * rv10: additional flags + * mpeg4: global headers (they can be in the bitstream or here) + * The allocated memory should be FF_INPUT_BUFFER_PADDING_SIZE bytes larger + * than extradata_size to avoid prolems if it is read with the bitstream reader. + * The bytewise contents of extradata must not depend on the architecture or CPU endianness. + * - encoding: Set/allocated/freed by libavcodec. + * - decoding: Set/allocated/freed by user. + */ + uint8_t *extradata; + int extradata_size; + + /** + * This is the fundamental unit of time (in seconds) in terms + * of which frame timestamps are represented. For fixed-fps content, + * timebase should be 1/framerate and timestamp increments should be + * identically 1. + * - encoding: MUST be set by user. + * - decoding: Set by libavcodec. + */ + AVRational time_base; + + /* video only */ + /** + * picture width / height. + * - encoding: MUST be set by user. + * - decoding: Set by libavcodec. + * Note: For compatibility it is possible to set this instead of + * coded_width/height before decoding. + */ + int width, height; + +#define FF_ASPECT_EXTENDED 15 + + /** + * the number of pictures in a group of pictures, or 0 for intra_only + * - encoding: Set by user. + * - decoding: unused + */ + int gop_size; + + /** + * Pixel format, see PIX_FMT_xxx. + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + enum PixelFormat pix_fmt; + + /** + * Frame rate emulation. If not zero, the lower layer (i.e. format handler) + * has to read frames at native frame rate. + * - encoding: Set by user. + * - decoding: unused + */ + int rate_emu; + + /** + * If non NULL, 'draw_horiz_band' is called by the libavcodec + * decoder to draw a horizontal band. It improves cache usage. Not + * all codecs can do that. You must check the codec capabilities + * beforehand. + * - encoding: unused + * - decoding: Set by user. + * @param height the height of the slice + * @param y the y position of the slice + * @param type 1->top field, 2->bottom field, 3->frame + * @param offset offset into the AVFrame.data from which the slice should be read + */ + void (*draw_horiz_band)(struct AVCodecContext *s, + const AVFrame *src, int offset[4], + int y, int type, int height); + + /* audio only */ + int sample_rate; ///< samples per second + int channels; ///< number of audio channels + + /** + * audio sample format + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + enum SampleFormat sample_fmt; ///< sample format, currently unused + + /* The following data should not be initialized. */ + /** + * Samples per packet, initialized when calling 'init'. + */ + int frame_size; + int frame_number; ///< audio or video frame number + int real_pict_num; ///< Returns the real picture number of previous encoded frame. + + /** + * Number of frames the decoded output will be delayed relative to + * the encoded input. + * - encoding: Set by libavcodec. + * - decoding: unused + */ + int delay; + + /* - encoding parameters */ + float qcompress; ///< amount of qscale change between easy & hard scenes (0.0-1.0) + float qblur; ///< amount of qscale smoothing over time (0.0-1.0) + + /** + * minimum quantizer + * - encoding: Set by user. + * - decoding: unused + */ + int qmin; + + /** + * maximum quantizer + * - encoding: Set by user. + * - decoding: unused + */ + int qmax; + + /** + * maximum quantizer difference between frames + * - encoding: Set by user. + * - decoding: unused + */ + int max_qdiff; + + /** + * maximum number of B-frames between non-B-frames + * Note: The output will be delayed by max_b_frames+1 relative to the input. + * - encoding: Set by user. + * - decoding: unused + */ + int max_b_frames; + + /** + * qscale factor between IP and B-frames + * If > 0 then the last P-frame quantizer will be used (q= lastp_q*factor+offset). + * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset). + * - encoding: Set by user. + * - decoding: unused + */ + float b_quant_factor; + + /** obsolete FIXME remove */ + int rc_strategy; +#define FF_RC_STRATEGY_XVID 1 + + int b_frame_strategy; + + /** + * hurry up amount + * - encoding: unused + * - decoding: Set by user. 1-> Skip B-frames, 2-> Skip IDCT/dequant too, 5-> Skip everything except header + * @deprecated Deprecated in favor of skip_idct and skip_frame. + */ + int hurry_up; + + struct AVCodec *codec; + + void *priv_data; + + int rtp_payload_size; /* The size of the RTP payload: the coder will */ + /* do its best to deliver a chunk with size */ + /* below rtp_payload_size, the chunk will start */ + /* with a start code on some codecs like H.263. */ + /* This doesn't take account of any particular */ + /* headers inside the transmitted RTP payload. */ + + + /* The RTP callback: This function is called */ + /* every time the encoder has a packet to send. */ + /* It depends on the encoder if the data starts */ + /* with a Start Code (it should). H.263 does. */ + /* mb_nb contains the number of macroblocks */ + /* encoded in the RTP payload. */ + void (*rtp_callback)(struct AVCodecContext *avctx, void *data, int size, int mb_nb); + + /* statistics, used for 2-pass encoding */ + int mv_bits; + int header_bits; + int i_tex_bits; + int p_tex_bits; + int i_count; + int p_count; + int skip_count; + int misc_bits; + + /** + * number of bits used for the previously encoded frame + * - encoding: Set by libavcodec. + * - decoding: unused + */ + int frame_bits; + + /** + * Private data of the user, can be used to carry app specific stuff. + * - encoding: Set by user. + * - decoding: Set by user. + */ + void *opaque; + + char codec_name[32]; + enum CodecType codec_type; /* see CODEC_TYPE_xxx */ + enum CodecID codec_id; /* see CODEC_ID_xxx */ + + /** + * fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A'). + * This is used to work around some encoder bugs. + * A demuxer should set this to what is stored in the field used to identify the codec. + * If there are multiple such fields in a container then the demuxer should choose the one + * which maximizes the information about the used codec. + * If the codec tag field in a container is larger then 32 bits then the demuxer should + * remap the longer ID to 32 bits with a table or other structure. Alternatively a new + * extra_codec_tag + size could be added but for this a clear advantage must be demonstrated + * first. + * - encoding: Set by user, if not then the default based on codec_id will be used. + * - decoding: Set by user, will be converted to uppercase by libavcodec during init. + */ + unsigned int codec_tag; + + /** + * Work around bugs in encoders which sometimes cannot be detected automatically. + * - encoding: Set by user + * - decoding: Set by user + */ + int workaround_bugs; +#define FF_BUG_AUTODETECT 1 ///< autodetection +#define FF_BUG_OLD_MSMPEG4 2 +#define FF_BUG_XVID_ILACE 4 +#define FF_BUG_UMP4 8 +#define FF_BUG_NO_PADDING 16 +#define FF_BUG_AMV 32 +#define FF_BUG_AC_VLC 0 ///< Will be removed, libavcodec can now handle these non-compliant files by default. +#define FF_BUG_QPEL_CHROMA 64 +#define FF_BUG_STD_QPEL 128 +#define FF_BUG_QPEL_CHROMA2 256 +#define FF_BUG_DIRECT_BLOCKSIZE 512 +#define FF_BUG_EDGE 1024 +#define FF_BUG_HPEL_CHROMA 2048 +#define FF_BUG_DC_CLIP 4096 +#define FF_BUG_MS 8192 ///< Work around various bugs in Microsoft's broken decoders. +//#define FF_BUG_FAKE_SCALABILITY 16 //Autodetection should work 100%. + + /** + * luma single coefficient elimination threshold + * - encoding: Set by user. + * - decoding: unused + */ + int luma_elim_threshold; + + /** + * chroma single coeff elimination threshold + * - encoding: Set by user. + * - decoding: unused + */ + int chroma_elim_threshold; + + /** + * strictly follow the standard (MPEG4, ...). + * - encoding: Set by user. + * - decoding: Set by user. + * Setting this to STRICT or higher means the encoder and decoder will + * generally do stupid things. While setting it to inofficial or lower + * will mean the encoder might use things that are not supported by all + * spec compliant decoders. Decoders make no difference between normal, + * inofficial and experimental, that is they always try to decode things + * when they can unless they are explicitly asked to behave stupid + * (=strictly conform to the specs) + */ + int strict_std_compliance; +#define FF_COMPLIANCE_VERY_STRICT 2 ///< Strictly conform to a older more strict version of the spec or reference software. +#define FF_COMPLIANCE_STRICT 1 ///< Strictly conform to all the things in the spec no matter what consequences. +#define FF_COMPLIANCE_NORMAL 0 +#define FF_COMPLIANCE_INOFFICIAL -1 ///< Allow inofficial extensions. +#define FF_COMPLIANCE_EXPERIMENTAL -2 ///< Allow nonstandardized experimental things. + + /** + * qscale offset between IP and B-frames + * - encoding: Set by user. + * - decoding: unused + */ + float b_quant_offset; + + /** + * Error recognization; higher values will detect more errors but may + * misdetect some more or less valid parts as errors. + * - encoding: unused + * - decoding: Set by user. + */ + int error_recognition; +#define FF_ER_CAREFUL 1 +#define FF_ER_COMPLIANT 2 +#define FF_ER_AGGRESSIVE 3 +#define FF_ER_VERY_AGGRESSIVE 4 + + /** + * Called at the beginning of each frame to get a buffer for it. + * If pic.reference is set then the frame will be read later by libavcodec. + * avcodec_align_dimensions() should be used to find the required width and + * height, as they normally need to be rounded up to the next multiple of 16. + * - encoding: unused + * - decoding: Set by libavcodec., user can override. + */ + int (*get_buffer)(struct AVCodecContext *c, AVFrame *pic); + + /** + * Called to release buffers which were allocated with get_buffer. + * A released buffer can be reused in get_buffer(). + * pic.data[*] must be set to NULL. + * - encoding: unused + * - decoding: Set by libavcodec., user can override. + */ + void (*release_buffer)(struct AVCodecContext *c, AVFrame *pic); + + /** + * If 1 the stream has a 1 frame delay during decoding. + * - encoding: Set by libavcodec. + * - decoding: Set by libavcodec. + */ + int has_b_frames; + + /** + * number of bytes per packet if constant and known or 0 + * Used by some WAV based audio codecs. + */ + int block_align; + + int parse_only; /* - decoding only: If true, only parsing is done + (function avcodec_parse_frame()). The frame + data is returned. Only MPEG codecs support this now. */ + + /** + * 0-> h263 quant 1-> mpeg quant + * - encoding: Set by user. + * - decoding: unused + */ + int mpeg_quant; + + /** + * pass1 encoding statistics output buffer + * - encoding: Set by libavcodec. + * - decoding: unused + */ + char *stats_out; + + /** + * pass2 encoding statistics input buffer + * Concatenated stuff from stats_out of pass1 should be placed here. + * - encoding: Allocated/set/freed by user. + * - decoding: unused + */ + char *stats_in; + + /** + * ratecontrol qmin qmax limiting method + * 0-> clipping, 1-> use a nice continous function to limit qscale wthin qmin/qmax. + * - encoding: Set by user. + * - decoding: unused + */ + float rc_qsquish; + + float rc_qmod_amp; + int rc_qmod_freq; + + /** + * ratecontrol override, see RcOverride + * - encoding: Allocated/set/freed by user. + * - decoding: unused + */ + RcOverride *rc_override; + int rc_override_count; + + /** + * rate control equation + * - encoding: Set by user + * - decoding: unused + */ + const char *rc_eq; + + /** + * maximum bitrate + * - encoding: Set by user. + * - decoding: unused + */ + int rc_max_rate; + + /** + * minimum bitrate + * - encoding: Set by user. + * - decoding: unused + */ + int rc_min_rate; + + /** + * decoder bitstream buffer size + * - encoding: Set by user. + * - decoding: unused + */ + int rc_buffer_size; + float rc_buffer_aggressivity; + + /** + * qscale factor between P and I-frames + * If > 0 then the last p frame quantizer will be used (q= lastp_q*factor+offset). + * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset). + * - encoding: Set by user. + * - decoding: unused + */ + float i_quant_factor; + + /** + * qscale offset between P and I-frames + * - encoding: Set by user. + * - decoding: unused + */ + float i_quant_offset; + + /** + * initial complexity for pass1 ratecontrol + * - encoding: Set by user. + * - decoding: unused + */ + float rc_initial_cplx; + + /** + * DCT algorithm, see FF_DCT_* below + * - encoding: Set by user. + * - decoding: unused + */ + int dct_algo; +#define FF_DCT_AUTO 0 +#define FF_DCT_FASTINT 1 +#define FF_DCT_INT 2 +#define FF_DCT_MMX 3 +#define FF_DCT_MLIB 4 +#define FF_DCT_ALTIVEC 5 +#define FF_DCT_FAAN 6 + + /** + * luminance masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + float lumi_masking; + + /** + * temporary complexity masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + float temporal_cplx_masking; + + /** + * spatial complexity masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + float spatial_cplx_masking; + + /** + * p block masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + float p_masking; + + /** + * darkness masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + float dark_masking; + + /** + * IDCT algorithm, see FF_IDCT_* below. + * - encoding: Set by user. + * - decoding: Set by user. + */ + int idct_algo; +#define FF_IDCT_AUTO 0 +#define FF_IDCT_INT 1 +#define FF_IDCT_SIMPLE 2 +#define FF_IDCT_SIMPLEMMX 3 +#define FF_IDCT_LIBMPEG2MMX 4 +#define FF_IDCT_PS2 5 +#define FF_IDCT_MLIB 6 +#define FF_IDCT_ARM 7 +#define FF_IDCT_ALTIVEC 8 +#define FF_IDCT_SH4 9 +#define FF_IDCT_SIMPLEARM 10 +#define FF_IDCT_H264 11 +#define FF_IDCT_VP3 12 +#define FF_IDCT_IPP 13 +#define FF_IDCT_XVIDMMX 14 +#define FF_IDCT_CAVS 15 +#define FF_IDCT_SIMPLEARMV5TE 16 +#define FF_IDCT_SIMPLEARMV6 17 +#define FF_IDCT_SIMPLEVIS 18 +#define FF_IDCT_WMV2 19 +#define FF_IDCT_FAAN 20 +#define FF_IDCT_EA 21 +#define FF_IDCT_SIMPLENEON 22 + + /** + * slice count + * - encoding: Set by libavcodec. + * - decoding: Set by user (or 0). + */ + int slice_count; + /** + * slice offsets in the frame in bytes + * - encoding: Set/allocated by libavcodec. + * - decoding: Set/allocated by user (or NULL). + */ + int *slice_offset; + + /** + * error concealment flags + * - encoding: unused + * - decoding: Set by user. + */ + int error_concealment; +#define FF_EC_GUESS_MVS 1 +#define FF_EC_DEBLOCK 2 + + /** + * dsp_mask could be add used to disable unwanted CPU features + * CPU features (i.e. MMX, SSE. ...) + * + * With the FORCE flag you may instead enable given CPU features. + * (Dangerous: Usable in case of misdetection, improper usage however will + * result into program crash.) + */ + unsigned dsp_mask; +#define FF_MM_FORCE 0x80000000 /* Force usage of selected flags (OR) */ + /* lower 16 bits - CPU features */ +#define FF_MM_MMX 0x0001 ///< standard MMX +#define FF_MM_3DNOW 0x0004 ///< AMD 3DNOW +#define FF_MM_MMXEXT 0x0002 ///< SSE integer functions or AMD MMX ext +#define FF_MM_SSE 0x0008 ///< SSE functions +#define FF_MM_SSE2 0x0010 ///< PIV SSE2 functions +#define FF_MM_3DNOWEXT 0x0020 ///< AMD 3DNowExt +#define FF_MM_SSE3 0x0040 ///< Prescott SSE3 functions +#define FF_MM_SSSE3 0x0080 ///< Conroe SSSE3 functions +#define FF_MM_IWMMXT 0x0100 ///< XScale IWMMXT +#define FF_MM_ALTIVEC 0x0001 ///< standard AltiVec + + /** + * bits per sample/pixel from the demuxer (needed for huffyuv). + * - encoding: Set by libavcodec. + * - decoding: Set by user. + */ + int bits_per_coded_sample; + + /** + * prediction method (needed for huffyuv) + * - encoding: Set by user. + * - decoding: unused + */ + int prediction_method; +#define FF_PRED_LEFT 0 +#define FF_PRED_PLANE 1 +#define FF_PRED_MEDIAN 2 + + /** + * sample aspect ratio (0 if unknown) + * That is the width of a pixel divided by the height of the pixel. + * Numerator and denominator must be relatively prime and smaller than 256 for some video standards. + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + AVRational sample_aspect_ratio; + + /** + * the picture in the bitstream + * - encoding: Set by libavcodec. + * - decoding: Set by libavcodec. + */ + AVFrame *coded_frame; + + /** + * debug + * - encoding: Set by user. + * - decoding: Set by user. + */ + int debug; +#define FF_DEBUG_PICT_INFO 1 +#define FF_DEBUG_RC 2 +#define FF_DEBUG_BITSTREAM 4 +#define FF_DEBUG_MB_TYPE 8 +#define FF_DEBUG_QP 16 +#define FF_DEBUG_MV 32 +#define FF_DEBUG_DCT_COEFF 0x00000040 +#define FF_DEBUG_SKIP 0x00000080 +#define FF_DEBUG_STARTCODE 0x00000100 +#define FF_DEBUG_PTS 0x00000200 +#define FF_DEBUG_ER 0x00000400 +#define FF_DEBUG_MMCO 0x00000800 +#define FF_DEBUG_BUGS 0x00001000 +#define FF_DEBUG_VIS_QP 0x00002000 +#define FF_DEBUG_VIS_MB_TYPE 0x00004000 +#define FF_DEBUG_BUFFERS 0x00008000 + + /** + * debug + * - encoding: Set by user. + * - decoding: Set by user. + */ + int debug_mv; +#define FF_DEBUG_VIS_MV_P_FOR 0x00000001 //visualize forward predicted MVs of P frames +#define FF_DEBUG_VIS_MV_B_FOR 0x00000002 //visualize forward predicted MVs of B frames +#define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //visualize backward predicted MVs of B frames + + /** + * error + * - encoding: Set by libavcodec if flags&CODEC_FLAG_PSNR. + * - decoding: unused + */ + uint64_t error[4]; + + /** + * minimum MB quantizer + * - encoding: unused + * - decoding: unused + */ + int mb_qmin; + + /** + * maximum MB quantizer + * - encoding: unused + * - decoding: unused + */ + int mb_qmax; + + /** + * motion estimation comparison function + * - encoding: Set by user. + * - decoding: unused + */ + int me_cmp; + /** + * subpixel motion estimation comparison function + * - encoding: Set by user. + * - decoding: unused + */ + int me_sub_cmp; + /** + * macroblock comparison function (not supported yet) + * - encoding: Set by user. + * - decoding: unused + */ + int mb_cmp; + /** + * interlaced DCT comparison function + * - encoding: Set by user. + * - decoding: unused + */ + int ildct_cmp; +#define FF_CMP_SAD 0 +#define FF_CMP_SSE 1 +#define FF_CMP_SATD 2 +#define FF_CMP_DCT 3 +#define FF_CMP_PSNR 4 +#define FF_CMP_BIT 5 +#define FF_CMP_RD 6 +#define FF_CMP_ZERO 7 +#define FF_CMP_VSAD 8 +#define FF_CMP_VSSE 9 +#define FF_CMP_NSSE 10 +#define FF_CMP_W53 11 +#define FF_CMP_W97 12 +#define FF_CMP_DCTMAX 13 +#define FF_CMP_DCT264 14 +#define FF_CMP_CHROMA 256 + + /** + * ME diamond size & shape + * - encoding: Set by user. + * - decoding: unused + */ + int dia_size; + + /** + * amount of previous MV predictors (2a+1 x 2a+1 square) + * - encoding: Set by user. + * - decoding: unused + */ + int last_predictor_count; + + /** + * prepass for motion estimation + * - encoding: Set by user. + * - decoding: unused + */ + int pre_me; + + /** + * motion estimation prepass comparison function + * - encoding: Set by user. + * - decoding: unused + */ + int me_pre_cmp; + + /** + * ME prepass diamond size & shape + * - encoding: Set by user. + * - decoding: unused + */ + int pre_dia_size; + + /** + * subpel ME quality + * - encoding: Set by user. + * - decoding: unused + */ + int me_subpel_quality; + + /** + * callback to negotiate the pixelFormat + * @param fmt is the list of formats which are supported by the codec, + * it is terminated by -1 as 0 is a valid format, the formats are ordered by quality. + * The first is always the native one. + * @return the chosen format + * - encoding: unused + * - decoding: Set by user, if not set the native format will be chosen. + */ + enum PixelFormat (*get_format)(struct AVCodecContext *s, const enum PixelFormat * fmt); + + /** + * DTG active format information (additional aspect ratio + * information only used in DVB MPEG-2 transport streams) + * 0 if not set. + * + * - encoding: unused + * - decoding: Set by decoder. + */ + int dtg_active_format; +#define FF_DTG_AFD_SAME 8 +#define FF_DTG_AFD_4_3 9 +#define FF_DTG_AFD_16_9 10 +#define FF_DTG_AFD_14_9 11 +#define FF_DTG_AFD_4_3_SP_14_9 13 +#define FF_DTG_AFD_16_9_SP_14_9 14 +#define FF_DTG_AFD_SP_4_3 15 + + /** + * maximum motion estimation search range in subpel units + * If 0 then no limit. + * + * - encoding: Set by user. + * - decoding: unused + */ + int me_range; + + /** + * intra quantizer bias + * - encoding: Set by user. + * - decoding: unused + */ + int intra_quant_bias; +#define FF_DEFAULT_QUANT_BIAS 999999 + + /** + * inter quantizer bias + * - encoding: Set by user. + * - decoding: unused + */ + int inter_quant_bias; + + /** + * color table ID + * - encoding: unused + * - decoding: Which clrtable should be used for 8bit RGB images. + * Tables have to be stored somewhere. FIXME + */ + int color_table_id; + + /** + * internal_buffer count + * Don't touch, used by libavcodec default_get_buffer(). + */ + int internal_buffer_count; + + /** + * internal_buffers + * Don't touch, used by libavcodec default_get_buffer(). + */ + void *internal_buffer; + +#define FF_LAMBDA_SHIFT 7 +#define FF_LAMBDA_SCALE (1< ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A'). + * This is used to work around some encoder bugs. + * - encoding: unused + * - decoding: Set by user, will be converted to uppercase by libavcodec during init. + */ + unsigned int stream_codec_tag; + + /** + * scene change detection threshold + * 0 is default, larger means fewer detected scene changes. + * - encoding: Set by user. + * - decoding: unused + */ + int scenechange_threshold; + + /** + * minimum Lagrange multipler + * - encoding: Set by user. + * - decoding: unused + */ + int lmin; + + /** + * maximum Lagrange multipler + * - encoding: Set by user. + * - decoding: unused + */ + int lmax; + + /** + * palette control structure + * - encoding: ??? (no palette-enabled encoder yet) + * - decoding: Set by user. + */ + struct AVPaletteControl *palctrl; + + /** + * noise reduction strength + * - encoding: Set by user. + * - decoding: unused + */ + int noise_reduction; + + /** + * Called at the beginning of a frame to get cr buffer for it. + * Buffer type (size, hints) must be the same. libavcodec won't check it. + * libavcodec will pass previous buffer in pic, function should return + * same buffer or new buffer with old frame "painted" into it. + * If pic.data[0] == NULL must behave like get_buffer(). + * - encoding: unused + * - decoding: Set by libavcodec., user can override + */ + int (*reget_buffer)(struct AVCodecContext *c, AVFrame *pic); + + /** + * Number of bits which should be loaded into the rc buffer before decoding starts. + * - encoding: Set by user. + * - decoding: unused + */ + int rc_initial_buffer_occupancy; + + /** + * + * - encoding: Set by user. + * - decoding: unused + */ + int inter_threshold; + + /** + * CODEC_FLAG2_* + * - encoding: Set by user. + * - decoding: Set by user. + */ + int flags2; + + /** + * Simulates errors in the bitstream to test error concealment. + * - encoding: Set by user. + * - decoding: unused + */ + int error_rate; + + /** + * MP3 antialias algorithm, see FF_AA_* below. + * - encoding: unused + * - decoding: Set by user. + */ + int antialias_algo; +#define FF_AA_AUTO 0 +#define FF_AA_FASTINT 1 //not implemented yet +#define FF_AA_INT 2 +#define FF_AA_FLOAT 3 + /** + * quantizer noise shaping + * - encoding: Set by user. + * - decoding: unused + */ + int quantizer_noise_shaping; + + /** + * thread count + * is used to decide how many independent tasks should be passed to execute() + * - encoding: Set by user. + * - decoding: Set by user. + */ + int thread_count; + + /** + * The codec may call this to execute several independent things. + * It will return only after finishing all tasks. + * The user may replace this with some multithreaded implementation, + * the default implementation will execute the parts serially. + * @param count the number of things to execute + * - encoding: Set by libavcodec, user can override. + * - decoding: Set by libavcodec, user can override. + */ + int (*execute)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg), void *arg2, int *ret, int count, int size); + + /** + * thread opaque + * Can be used by execute() to store some per AVCodecContext stuff. + * - encoding: set by execute() + * - decoding: set by execute() + */ + void *thread_opaque; + + /** + * Motion estimation threshold below which no motion estimation is + * performed, but instead the user specified motion vectors are used. + * + * - encoding: Set by user. + * - decoding: unused + */ + int me_threshold; + + /** + * Macroblock threshold below which the user specified macroblock types will be used. + * - encoding: Set by user. + * - decoding: unused + */ + int mb_threshold; + + /** + * precision of the intra DC coefficient - 8 + * - encoding: Set by user. + * - decoding: unused + */ + int intra_dc_precision; + + /** + * noise vs. sse weight for the nsse comparsion function + * - encoding: Set by user. + * - decoding: unused + */ + int nsse_weight; + + /** + * Number of macroblock rows at the top which are skipped. + * - encoding: unused + * - decoding: Set by user. + */ + int skip_top; + + /** + * Number of macroblock rows at the bottom which are skipped. + * - encoding: unused + * - decoding: Set by user. + */ + int skip_bottom; + + /** + * profile + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int profile; +#define FF_PROFILE_UNKNOWN -99 +#define FF_PROFILE_AAC_MAIN 0 +#define FF_PROFILE_AAC_LOW 1 +#define FF_PROFILE_AAC_SSR 2 +#define FF_PROFILE_AAC_LTP 3 + + /** + * level + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int level; +#define FF_LEVEL_UNKNOWN -99 + + /** + * low resolution decoding, 1-> 1/2 size, 2->1/4 size + * - encoding: unused + * - decoding: Set by user. + */ + int lowres; + + /** + * Bitstream width / height, may be different from width/height if lowres + * or other things are used. + * - encoding: unused + * - decoding: Set by user before init if known. Codec should override / dynamically change if needed. + */ + int coded_width, coded_height; + + /** + * frame skip threshold + * - encoding: Set by user. + * - decoding: unused + */ + int frame_skip_threshold; + + /** + * frame skip factor + * - encoding: Set by user. + * - decoding: unused + */ + int frame_skip_factor; + + /** + * frame skip exponent + * - encoding: Set by user. + * - decoding: unused + */ + int frame_skip_exp; + + /** + * frame skip comparison function + * - encoding: Set by user. + * - decoding: unused + */ + int frame_skip_cmp; + + /** + * Border processing masking, raises the quantizer for mbs on the borders + * of the picture. + * - encoding: Set by user. + * - decoding: unused + */ + float border_masking; + + /** + * minimum MB lagrange multipler + * - encoding: Set by user. + * - decoding: unused + */ + int mb_lmin; + + /** + * maximum MB lagrange multipler + * - encoding: Set by user. + * - decoding: unused + */ + int mb_lmax; + + /** + * + * - encoding: Set by user. + * - decoding: unused + */ + int me_penalty_compensation; + + /** + * + * - encoding: unused + * - decoding: Set by user. + */ + enum AVDiscard skip_loop_filter; + + /** + * + * - encoding: unused + * - decoding: Set by user. + */ + enum AVDiscard skip_idct; + + /** + * + * - encoding: unused + * - decoding: Set by user. + */ + enum AVDiscard skip_frame; + + /** + * + * - encoding: Set by user. + * - decoding: unused + */ + int bidir_refine; + + /** + * + * - encoding: Set by user. + * - decoding: unused + */ + int brd_scale; + + /** + * constant rate factor - quality-based VBR - values ~correspond to qps + * - encoding: Set by user. + * - decoding: unused + */ + float crf; + + /** + * constant quantization parameter rate control method + * - encoding: Set by user. + * - decoding: unused + */ + int cqp; + + /** + * minimum GOP size + * - encoding: Set by user. + * - decoding: unused + */ + int keyint_min; + + /** + * number of reference frames + * - encoding: Set by user. + * - decoding: unused + */ + int refs; + + /** + * chroma qp offset from luma + * - encoding: Set by user. + * - decoding: unused + */ + int chromaoffset; + + /** + * Influences how often B-frames are used. + * - encoding: Set by user. + * - decoding: unused + */ + int bframebias; + + /** + * trellis RD quantization + * - encoding: Set by user. + * - decoding: unused + */ + int trellis; + + /** + * Reduce fluctuations in qp (before curve compression). + * - encoding: Set by user. + * - decoding: unused + */ + float complexityblur; + + /** + * in-loop deblocking filter alphac0 parameter + * alpha is in the range -6...6 + * - encoding: Set by user. + * - decoding: unused + */ + int deblockalpha; + + /** + * in-loop deblocking filter beta parameter + * beta is in the range -6...6 + * - encoding: Set by user. + * - decoding: unused + */ + int deblockbeta; + + /** + * macroblock subpartition sizes to consider - p8x8, p4x4, b8x8, i8x8, i4x4 + * - encoding: Set by user. + * - decoding: unused + */ + int partitions; +#define X264_PART_I4X4 0x001 /* Analyze i4x4 */ +#define X264_PART_I8X8 0x002 /* Analyze i8x8 (requires 8x8 transform) */ +#define X264_PART_P8X8 0x010 /* Analyze p16x8, p8x16 and p8x8 */ +#define X264_PART_P4X4 0x020 /* Analyze p8x4, p4x8, p4x4 */ +#define X264_PART_B8X8 0x100 /* Analyze b16x8, b8x16 and b8x8 */ + + /** + * direct MV prediction mode - 0 (none), 1 (spatial), 2 (temporal), 3 (auto) + * - encoding: Set by user. + * - decoding: unused + */ + int directpred; + + /** + * Audio cutoff bandwidth (0 means "automatic") + * - encoding: Set by user. + * - decoding: unused + */ + int cutoff; + + /** + * Multiplied by qscale for each frame and added to scene_change_score. + * - encoding: Set by user. + * - decoding: unused + */ + int scenechange_factor; + + /** + * + * Note: Value depends upon the compare function used for fullpel ME. + * - encoding: Set by user. + * - decoding: unused + */ + int mv0_threshold; + + /** + * Adjusts sensitivity of b_frame_strategy 1. + * - encoding: Set by user. + * - decoding: unused + */ + int b_sensitivity; + + /** + * - encoding: Set by user. + * - decoding: unused + */ + int compression_level; +#define FF_COMPRESSION_DEFAULT -1 + + /** + * Sets whether to use LPC mode - used by FLAC encoder. + * - encoding: Set by user. + * - decoding: unused + */ + int use_lpc; + + /** + * LPC coefficient precision - used by FLAC encoder + * - encoding: Set by user. + * - decoding: unused + */ + int lpc_coeff_precision; + + /** + * - encoding: Set by user. + * - decoding: unused + */ + int min_prediction_order; + + /** + * - encoding: Set by user. + * - decoding: unused + */ + int max_prediction_order; + + /** + * search method for selecting prediction order + * - encoding: Set by user. + * - decoding: unused + */ + int prediction_order_method; + + /** + * - encoding: Set by user. + * - decoding: unused + */ + int min_partition_order; + + /** + * - encoding: Set by user. + * - decoding: unused + */ + int max_partition_order; + + /** + * GOP timecode frame start number, in non drop frame format + * - encoding: Set by user. + * - decoding: unused + */ + int64_t timecode_frame_start; + +#if LIBAVCODEC_VERSION_MAJOR < 53 + /** + * Decoder should decode to this many channels if it can (0 for default) + * - encoding: unused + * - decoding: Set by user. + * @deprecated Deprecated in favor of request_channel_layout. + */ + int request_channels; +#endif + + /** + * Percentage of dynamic range compression to be applied by the decoder. + * The default value is 1.0, corresponding to full compression. + * - encoding: unused + * - decoding: Set by user. + */ + float drc_scale; + + /** + * opaque 64bit number (generally a PTS) that will be reordered and + * output in AVFrame.reordered_opaque + * - encoding: unused + * - decoding: Set by user. + */ + int64_t reordered_opaque; + + /** + * Bits per sample/pixel of internal libavcodec pixel/sample format. + * This field is applicable only when sample_fmt is SAMPLE_FMT_S32. + * - encoding: set by user. + * - decoding: set by libavcodec. + */ + int bits_per_raw_sample; + + /** + * Audio channel layout. + * - encoding: set by user. + * - decoding: set by libavcodec. + */ + int64_t channel_layout; + + /** + * Request decoder to use this channel layout if it can (0 for default) + * - encoding: unused + * - decoding: Set by user. + */ + int64_t request_channel_layout; + + /** + * Ratecontrol attempt to use, at maximum, of what can be used without an underflow. + * - encoding: Set by user. + * - decoding: unused. + */ + float rc_max_available_vbv_use; + + /** + * Ratecontrol attempt to use, at least, times the amount needed to prevent a vbv overflow. + * - encoding: Set by user. + * - decoding: unused. + */ + float rc_min_vbv_overflow_use; +} AVCodecContext; + +/** + * AVCodec. + */ +typedef struct AVCodec { + /** + * Name of the codec implementation. + * The name is globally unique among encoders and among decoders (but an + * encoder and a decoder can share the same name). + * This is the primary way to find a codec from the user perspective. + */ + const char *name; + enum CodecType type; + enum CodecID id; + int priv_data_size; + int (*init)(AVCodecContext *); + int (*encode)(AVCodecContext *, uint8_t *buf, int buf_size, void *data); + int (*close)(AVCodecContext *); + int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, + const uint8_t *buf, int buf_size); + /** + * Codec capabilities. + * see CODEC_CAP_* + */ + int capabilities; + struct AVCodec *next; + /** + * Flush buffers. + * Will be called when seeking + */ + void (*flush)(AVCodecContext *); + const AVRational *supported_framerates; ///< array of supported framerates, or NULL if any, array is terminated by {0,0} + const enum PixelFormat *pix_fmts; ///< array of supported pixel formats, or NULL if unknown, array is terminated by -1 + /** + * Descriptive name for the codec, meant to be more human readable than \p name. + * You \e should use the NULL_IF_CONFIG_SMALL() macro to define it. + */ + const char *long_name; + const int *supported_samplerates; ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0 + const enum SampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1 + const int64_t *channel_layouts; ///< array of support channel layouts, or NULL if unknown. array is terminated by 0 +} AVCodec; + +/** + * four components are given, that's all. + * the last component is alpha + */ +typedef struct AVPicture { + uint8_t *data[4]; + int linesize[4]; ///< number of bytes per line +} AVPicture; + +/** + * AVPaletteControl + * This structure defines a method for communicating palette changes + * between and demuxer and a decoder. + * + * @deprecated Use AVPacket to send palette changes instead. + * This is totally broken. + */ +#define AVPALETTE_SIZE 1024 +#define AVPALETTE_COUNT 256 +typedef struct AVPaletteControl { + + /* Demuxer sets this to 1 to indicate the palette has changed; + * decoder resets to 0. */ + int palette_changed; + + /* 4-byte ARGB palette entries, stored in native byte order; note that + * the individual palette components should be on a 8-bit scale; if + * the palette data comes from an IBM VGA native format, the component + * data is probably 6 bits in size and needs to be scaled. */ + unsigned int palette[AVPALETTE_COUNT]; + +} AVPaletteControl attribute_deprecated; + +typedef struct AVSubtitleRect { + uint16_t x; + uint16_t y; + uint16_t w; + uint16_t h; + uint16_t nb_colors; + int linesize; + uint32_t *rgba_palette; + uint8_t *bitmap; +} AVSubtitleRect; + +typedef struct AVSubtitle { + uint16_t format; /* 0 = graphics */ + uint32_t start_display_time; /* relative to packet pts, in ms */ + uint32_t end_display_time; /* relative to packet pts, in ms */ + uint32_t num_rects; + AVSubtitleRect *rects; +} AVSubtitle; + + +/* resample.c */ + +struct ReSampleContext; +struct AVResampleContext; + +typedef struct ReSampleContext ReSampleContext; + +ReSampleContext *audio_resample_init(int output_channels, int input_channels, + int output_rate, int input_rate); +int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples); +void audio_resample_close(ReSampleContext *s); + +struct AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_length, int log2_phase_count, int linear, double cutoff); +int av_resample(struct AVResampleContext *c, short *dst, short *src, int *consumed, int src_size, int dst_size, int update_ctx); +void av_resample_compensate(struct AVResampleContext *c, int sample_delta, int compensation_distance); +void av_resample_close(struct AVResampleContext *c); + +/** + * Allocate memory for a picture. Call avpicture_free to free it. + * + * @param picture the picture to be filled in + * @param pix_fmt the format of the picture + * @param width the width of the picture + * @param height the height of the picture + * @return zero if successful, a negative value if not + */ +int avpicture_alloc(AVPicture *picture, int pix_fmt, int width, int height); + +/** + * Free a picture previously allocated by avpicture_alloc(). + * + * @param picture the AVPicture to be freed + */ +void avpicture_free(AVPicture *picture); + +/** + * Fill in the AVPicture fields. + * The fields of the given AVPicture are filled in by using the 'ptr' address + * which points to the image data buffer. Depending on the specified picture + * format, one or multiple image data pointers and line sizes will be set. + * If a planar format is specified, several pointers will be set pointing to + * the different picture planes and the line sizes of the different planes + * will be stored in the lines_sizes array. + * + * @param picture AVPicture whose fields are to be filled in + * @param ptr Buffer which will contain or contains the actual image data + * @param pix_fmt The format in which the picture data is stored. + * @param width the width of the image in pixels + * @param height the height of the image in pixels + * @return size of the image data in bytes + */ +int avpicture_fill(AVPicture *picture, uint8_t *ptr, + int pix_fmt, int width, int height); +int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height, + unsigned char *dest, int dest_size); + +/** + * Calculate the size in bytes that a picture of the given width and height + * would occupy if stored in the given picture format. + * + * @param pix_fmt the given picture format + * @param width the width of the image + * @param height the height of the image + * @return Image data size in bytes + */ +int avpicture_get_size(int pix_fmt, int width, int height); +void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift); +const char *avcodec_get_pix_fmt_name(int pix_fmt); +void avcodec_set_dimensions(AVCodecContext *s, int width, int height); +enum PixelFormat avcodec_get_pix_fmt(const char* name); +unsigned int avcodec_pix_fmt_to_codec_tag(enum PixelFormat p); + +#define FF_LOSS_RESOLUTION 0x0001 /**< loss due to resolution change */ +#define FF_LOSS_DEPTH 0x0002 /**< loss due to color depth change */ +#define FF_LOSS_COLORSPACE 0x0004 /**< loss due to color space conversion */ +#define FF_LOSS_ALPHA 0x0008 /**< loss of alpha bits */ +#define FF_LOSS_COLORQUANT 0x0010 /**< loss due to color quantization */ +#define FF_LOSS_CHROMA 0x0020 /**< loss of chroma (e.g. RGB to gray conversion) */ + +/** + * Computes what kind of losses will occur when converting from one specific + * pixel format to another. + * When converting from one pixel format to another, information loss may occur. + * For example, when converting from RGB24 to GRAY, the color information will + * be lost. Similarly, other losses occur when converting from some formats to + * other formats. These losses can involve loss of chroma, but also loss of + * resolution, loss of color depth, loss due to the color space conversion, loss + * of the alpha bits or loss due to color quantization. + * avcodec_get_fix_fmt_loss() informs you about the various types of losses + * which will occur when converting from one pixel format to another. + * + * @param[in] dst_pix_fmt destination pixel format + * @param[in] src_pix_fmt source pixel format + * @param[in] has_alpha Whether the source pixel format alpha channel is used. + * @return Combination of flags informing you what kind of losses will occur. + */ +int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt, + int has_alpha); + +/** + * Finds the best pixel format to convert to given a certain source pixel + * format. When converting from one pixel format to another, information loss + * may occur. For example, when converting from RGB24 to GRAY, the color + * information will be lost. Similarly, other losses occur when converting from + * some formats to other formats. avcodec_find_best_pix_fmt() searches which of + * the given pixel formats should be used to suffer the least amount of loss. + * The pixel formats from which it chooses one, are determined by the + * \p pix_fmt_mask parameter. + * + * @code + * src_pix_fmt = PIX_FMT_YUV420P; + * pix_fmt_mask = (1 << PIX_FMT_YUV422P) || (1 << PIX_FMT_RGB24); + * dst_pix_fmt = avcodec_find_best_pix_fmt(pix_fmt_mask, src_pix_fmt, alpha, &loss); + * @endcode + * + * @param[in] pix_fmt_mask bitmask determining which pixel format to choose from + * @param[in] src_pix_fmt source pixel format + * @param[in] has_alpha Whether the source pixel format alpha channel is used. + * @param[out] loss_ptr Combination of flags informing you what kind of losses will occur. + * @return The best pixel format to convert to or -1 if none was found. + */ +int avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, int src_pix_fmt, + int has_alpha, int *loss_ptr); + + +/** + * Print in buf the string corresponding to the pixel format with + * number pix_fmt, or an header if pix_fmt is negative. + * + * @param[in] buf the buffer where to write the string + * @param[in] buf_size the size of buf + * @param[in] pix_fmt the number of the pixel format to print the corresponding info string, or + * a negative value to print the corresponding header. + * Meaningful values for obtaining a pixel format info vary from 0 to PIX_FMT_NB -1. + */ +void avcodec_pix_fmt_string (char *buf, int buf_size, int pix_fmt); + +#define FF_ALPHA_TRANSP 0x0001 /* image has some totally transparent pixels */ +#define FF_ALPHA_SEMI_TRANSP 0x0002 /* image has some transparent pixels */ + +/** + * Tell if an image really has transparent alpha values. + * @return ored mask of FF_ALPHA_xxx constants + */ +int img_get_alpha_info(const AVPicture *src, + int pix_fmt, int width, int height); + +/* deinterlace a picture */ +/* deinterlace - if not supported return -1 */ +int avpicture_deinterlace(AVPicture *dst, const AVPicture *src, + int pix_fmt, int width, int height); + +/* external high level API */ + +AVCodec *av_codec_next(AVCodec *c); + +/** + * Returns the LIBAVCODEC_VERSION_INT constant. + */ +unsigned avcodec_version(void); + +/** + * Initializes libavcodec. + * + * @warning This function \e must be called before any other libavcodec + * function. + */ +void avcodec_init(void); + +/** + * Register the codec \p codec and initialize libavcodec. + * + * @see avcodec_init() + */ +void register_avcodec(AVCodec *codec); + +/** + * Finds a registered encoder with a matching codec ID. + * + * @param id CodecID of the requested encoder + * @return An encoder if one was found, NULL otherwise. + */ +AVCodec *avcodec_find_encoder(enum CodecID id); + +/** + * Finds a registered encoder with the specified name. + * + * @param name name of the requested encoder + * @return An encoder if one was found, NULL otherwise. + */ +AVCodec *avcodec_find_encoder_by_name(const char *name); + +/** + * Finds a registered decoder with a matching codec ID. + * + * @param id CodecID of the requested decoder + * @return A decoder if one was found, NULL otherwise. + */ +AVCodec *avcodec_find_decoder(enum CodecID id); + +/** + * Finds a registered decoder with the specified name. + * + * @param name name of the requested decoder + * @return A decoder if one was found, NULL otherwise. + */ +AVCodec *avcodec_find_decoder_by_name(const char *name); +void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode); + +/** + * Sets the fields of the given AVCodecContext to default values. + * + * @param s The AVCodecContext of which the fields should be set to default values. + */ +void avcodec_get_context_defaults(AVCodecContext *s); + +/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API! + * we WILL change its arguments and name a few times! */ +void avcodec_get_context_defaults2(AVCodecContext *s, enum CodecType); + +/** + * Allocates an AVCodecContext and sets its fields to default values. The + * resulting struct can be deallocated by simply calling av_free(). + * + * @return An AVCodecContext filled with default values or NULL on failure. + * @see avcodec_get_context_defaults + */ +AVCodecContext *avcodec_alloc_context(void); + +/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API! + * we WILL change its arguments and name a few times! */ +AVCodecContext *avcodec_alloc_context2(enum CodecType); + +/** + * Sets the fields of the given AVFrame to default values. + * + * @param pic The AVFrame of which the fields should be set to default values. + */ +void avcodec_get_frame_defaults(AVFrame *pic); + +/** + * Allocates an AVFrame and sets its fields to default values. The resulting + * struct can be deallocated by simply calling av_free(). + * + * @return An AVFrame filled with default values or NULL on failure. + * @see avcodec_get_frame_defaults + */ +AVFrame *avcodec_alloc_frame(void); + +int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic); +void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic); +int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic); +void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height); + +/** + * Checks if the given dimension of a picture is valid, meaning that all + * bytes of the picture can be addressed with a signed int. + * + * @param[in] w Width of the picture. + * @param[in] h Height of the picture. + * @return Zero if valid, a negative value if invalid. + */ +int avcodec_check_dimensions(void *av_log_ctx, unsigned int w, unsigned int h); +enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum PixelFormat * fmt); + +int avcodec_thread_init(AVCodecContext *s, int thread_count); +void avcodec_thread_free(AVCodecContext *s); +int avcodec_thread_execute(AVCodecContext *s, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size); +int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size); +//FIXME func typedef + +/** + * Initializes the AVCodecContext to use the given AVCodec. Prior to using this + * function the context has to be allocated. + * + * The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(), + * avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for + * retrieving a codec. + * + * @warning This function is not thread safe! + * + * @code + * avcodec_register_all(); + * codec = avcodec_find_decoder(CODEC_ID_H264); + * if (!codec) + * exit(1); + * + * context = avcodec_alloc_context(); + * + * if (avcodec_open(context, codec) < 0) + * exit(1); + * @endcode + * + * @param avctx The context which will be set up to use the given codec. + * @param codec The codec to use within the context. + * @return zero on success, a negative value on error + * @see avcodec_alloc_context, avcodec_find_decoder, avcodec_find_encoder + */ +int avcodec_open(AVCodecContext *avctx, AVCodec *codec); + +/** + * Decodes an audio frame from \p buf into \p samples. + * The avcodec_decode_audio2() function decodes an audio frame from the input + * buffer \p buf of size \p buf_size. To decode it, it makes use of the + * audio codec which was coupled with \p avctx using avcodec_open(). The + * resulting decoded frame is stored in output buffer \p samples. If no frame + * could be decompressed, \p frame_size_ptr is zero. Otherwise, it is the + * decompressed frame size in \e bytes. + * + * @warning You \e must set \p frame_size_ptr to the allocated size of the + * output buffer before calling avcodec_decode_audio2(). + * + * @warning The input buffer must be \c FF_INPUT_BUFFER_PADDING_SIZE larger than + * the actual read bytes because some optimized bitstream readers read 32 or 64 + * bits at once and could read over the end. + * + * @warning The end of the input buffer \p buf should be set to 0 to ensure that + * no overreading happens for damaged MPEG streams. + * + * @note You might have to align the input buffer \p buf and output buffer \p + * samples. The alignment requirements depend on the CPU: On some CPUs it isn't + * necessary at all, on others it won't work at all if not aligned and on others + * it will work but it will have an impact on performance. In practice, the + * bitstream should have 4 byte alignment at minimum and all sample data should + * be 16 byte aligned unless the CPU doesn't need it (AltiVec and SSE do). If + * the linesize is not a multiple of 16 then there's no sense in aligning the + * start of the buffer to 16. + * + * @param avctx the codec context + * @param[out] samples the output buffer + * @param[in,out] frame_size_ptr the output buffer size in bytes + * @param[in] buf the input buffer + * @param[in] buf_size the input buffer size in bytes + * @return On error a negative value is returned, otherwise the number of bytes + * used or zero if no frame could be decompressed. + */ +int avcodec_decode_audio2(AVCodecContext *avctx, int16_t *samples, + int *frame_size_ptr, + const uint8_t *buf, int buf_size); + +/** + * Decodes a video frame from \p buf into \p picture. + * The avcodec_decode_video() function decodes a video frame from the input + * buffer \p buf of size \p buf_size. To decode it, it makes use of the + * video codec which was coupled with \p avctx using avcodec_open(). The + * resulting decoded frame is stored in \p picture. + * + * @warning The input buffer must be \c FF_INPUT_BUFFER_PADDING_SIZE larger than + * the actual read bytes because some optimized bitstream readers read 32 or 64 + * bits at once and could read over the end. + * + * @warning The end of the input buffer \p buf should be set to 0 to ensure that + * no overreading happens for damaged MPEG streams. + * + * @note You might have to align the input buffer \p buf and output buffer \p + * samples. The alignment requirements depend on the CPU: on some CPUs it isn't + * necessary at all, on others it won't work at all if not aligned and on others + * it will work but it will have an impact on performance. In practice, the + * bitstream should have 4 byte alignment at minimum and all sample data should + * be 16 byte aligned unless the CPU doesn't need it (AltiVec and SSE do). If + * the linesize is not a multiple of 16 then there's no sense in aligning the + * start of the buffer to 16. + * + * @param avctx the codec context + * @param[out] picture The AVFrame in which the decoded video frame will be stored. + * @param[in] buf the input buffer + * @param[in] buf_size the size of the input buffer in bytes + * @param[in,out] got_picture_ptr Zero if no frame could be decompressed, otherwise, it is nonzero. + * @return On error a negative value is returned, otherwise the number of bytes + * used or zero if no frame could be decompressed. + */ +int avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture, + int *got_picture_ptr, + const uint8_t *buf, int buf_size); + +/* Decode a subtitle message. Return -1 if error, otherwise return the + * number of bytes used. If no subtitle could be decompressed, + * got_sub_ptr is zero. Otherwise, the subtitle is stored in *sub. */ +int avcodec_decode_subtitle(AVCodecContext *avctx, AVSubtitle *sub, + int *got_sub_ptr, + const uint8_t *buf, int buf_size); +int avcodec_parse_frame(AVCodecContext *avctx, uint8_t **pdata, + int *data_size_ptr, + uint8_t *buf, int buf_size); + +/** + * Encodes an audio frame from \p samples into \p buf. + * The avcodec_encode_audio() function encodes an audio frame from the input + * buffer \p samples. To encode it, it makes use of the audio codec which was + * coupled with \p avctx using avcodec_open(). The resulting encoded frame is + * stored in output buffer \p buf. + * + * @note The output buffer should be at least \c FF_MIN_BUFFER_SIZE bytes large. + * + * @param avctx the codec context + * @param[out] buf the output buffer + * @param[in] buf_size the output buffer size + * @param[in] samples the input buffer containing the samples + * The number of samples read from this buffer is frame_size*channels, + * both of which are defined in \p avctx. + * For PCM audio the number of samples read from \p samples is equal to + * \p buf_size * input_sample_size / output_sample_size. + * @return On error a negative value is returned, on success zero or the number + * of bytes used to encode the data read from the input buffer. + */ +int avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size, + const short *samples); + +/** + * Encodes a video frame from \p pict into \p buf. + * The avcodec_encode_video() function encodes a video frame from the input + * \p pict. To encode it, it makes use of the video codec which was coupled with + * \p avctx using avcodec_open(). The resulting encoded bytes representing the + * frame are stored in the output buffer \p buf. The input picture should be + * stored using a specific format, namely \c avctx.pix_fmt. + * + * @param avctx the codec context + * @param[out] buf the output buffer for the bitstream of encoded frame + * @param[in] buf_size the size of the output buffer in bytes + * @param[in] pict the input picture to encode + * @return On error a negative value is returned, on success zero or the number + * of bytes used from the input buffer. + */ +int avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size, + const AVFrame *pict); +int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, + const AVSubtitle *sub); + +int avcodec_close(AVCodecContext *avctx); + +/** + * Register all the codecs, parsers and bitstream filters which were enabled at + * configuration time. If you do not call this function you can select exactly + * which formats you want to support, by using the individual registration + * functions. + * + * @see register_avcodec + * @see av_register_codec_parser + * @see av_register_bitstream_filter + */ +void avcodec_register_all(void); + +/** + * Flush buffers, should be called when seeking or when switching to a different stream. + */ +void avcodec_flush_buffers(AVCodecContext *avctx); + +void avcodec_default_free_buffers(AVCodecContext *s); + +/* misc useful functions */ + +/** + * Returns a single letter to describe the given picture type \p pict_type. + * + * @param[in] pict_type the picture type + * @return A single character representing the picture type. + */ +char av_get_pict_type_char(int pict_type); + +/** + * Returns codec bits per sample. + * + * @param[in] codec_id the codec + * @return Number of bits per sample or zero if unknown for the given codec. + */ +int av_get_bits_per_sample(enum CodecID codec_id); + +/** + * Returns sample format bits per sample. + * + * @param[in] sample_fmt the sample format + * @return Number of bits per sample or zero if unknown for the given sample format. + */ +int av_get_bits_per_sample_format(enum SampleFormat sample_fmt); + +/* frame parsing */ +typedef struct AVCodecParserContext { + void *priv_data; + struct AVCodecParser *parser; + int64_t frame_offset; /* offset of the current frame */ + int64_t cur_offset; /* current offset + (incremented by each av_parser_parse()) */ + int64_t next_frame_offset; /* offset of the next frame */ + /* video info */ + int pict_type; /* XXX: Put it back in AVCodecContext. */ + int repeat_pict; /* XXX: Put it back in AVCodecContext. */ + int64_t pts; /* pts of the current frame */ + int64_t dts; /* dts of the current frame */ + + /* private data */ + int64_t last_pts; + int64_t last_dts; + int fetch_timestamp; + +#define AV_PARSER_PTS_NB 4 + int cur_frame_start_index; + int64_t cur_frame_offset[AV_PARSER_PTS_NB]; + int64_t cur_frame_pts[AV_PARSER_PTS_NB]; + int64_t cur_frame_dts[AV_PARSER_PTS_NB]; + + int flags; +#define PARSER_FLAG_COMPLETE_FRAMES 0x0001 + + int64_t offset; ///< byte offset from starting packet start + int64_t cur_frame_end[AV_PARSER_PTS_NB]; +} AVCodecParserContext; + +typedef struct AVCodecParser { + int codec_ids[5]; /* several codec IDs are permitted */ + int priv_data_size; + int (*parser_init)(AVCodecParserContext *s); + int (*parser_parse)(AVCodecParserContext *s, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size); + void (*parser_close)(AVCodecParserContext *s); + int (*split)(AVCodecContext *avctx, const uint8_t *buf, int buf_size); + struct AVCodecParser *next; +} AVCodecParser; + +AVCodecParser *av_parser_next(AVCodecParser *c); + +void av_register_codec_parser(AVCodecParser *parser); +AVCodecParserContext *av_parser_init(int codec_id); +int av_parser_parse(AVCodecParserContext *s, + AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, + int64_t pts, int64_t dts); +int av_parser_change(AVCodecParserContext *s, + AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe); +void av_parser_close(AVCodecParserContext *s); + + +typedef struct AVBitStreamFilterContext { + void *priv_data; + struct AVBitStreamFilter *filter; + AVCodecParserContext *parser; + struct AVBitStreamFilterContext *next; +} AVBitStreamFilterContext; + + +typedef struct AVBitStreamFilter { + const char *name; + int priv_data_size; + int (*filter)(AVBitStreamFilterContext *bsfc, + AVCodecContext *avctx, const char *args, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe); + void (*close)(AVBitStreamFilterContext *bsfc); + struct AVBitStreamFilter *next; +} AVBitStreamFilter; + +void av_register_bitstream_filter(AVBitStreamFilter *bsf); +AVBitStreamFilterContext *av_bitstream_filter_init(const char *name); +int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc, + AVCodecContext *avctx, const char *args, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe); +void av_bitstream_filter_close(AVBitStreamFilterContext *bsf); + +AVBitStreamFilter *av_bitstream_filter_next(AVBitStreamFilter *f); + +/* memory */ + +/** + * Reallocates the given block if it is not large enough, otherwise it + * does nothing. + * + * @see av_realloc + */ +void *av_fast_realloc(void *ptr, unsigned int *size, unsigned int min_size); + +/** + * Copy image 'src' to 'dst'. + */ +void av_picture_copy(AVPicture *dst, const AVPicture *src, + int pix_fmt, int width, int height); + +/** + * Crop image top and left side. + */ +int av_picture_crop(AVPicture *dst, const AVPicture *src, + int pix_fmt, int top_band, int left_band); + +/** + * Pad image. + */ +int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width, int pix_fmt, + int padtop, int padbottom, int padleft, int padright, int *color); + +unsigned int av_xiphlacing(unsigned char *s, unsigned int v); + +/** + * Parses \p str and put in \p width_ptr and \p height_ptr the detected values. + * + * @return 0 in case of a successful parsing, a negative value otherwise + * @param[in] str the string to parse: it has to be a string in the format + * x or a valid video frame size abbreviation. + * @param[in,out] width_ptr pointer to the variable which will contain the detected + * frame width value + * @param[in,out] height_ptr pointer to the variable which will contain the detected + * frame height value + */ +int av_parse_video_frame_size(int *width_ptr, int *height_ptr, const char *str); + +/** + * Parses \p str and put in \p frame_rate the detected values. + * + * @return 0 in case of a successful parsing, a negative value otherwise + * @param[in] str the string to parse: it has to be a string in the format + * /, a float number or a valid video rate abbreviation + * @param[in,out] frame_rate pointer to the AVRational which will contain the detected + * frame rate + */ +int av_parse_video_frame_rate(AVRational *frame_rate, const char *str); + +/* error handling */ +#if EINVAL > 0 +#define AVERROR(e) (-(e)) /**< Returns a negative error code from a POSIX error code, to return from library functions. */ +#define AVUNERROR(e) (-(e)) /**< Returns a POSIX error code from a library function error return value. */ +#else +/* Some platforms have E* and errno already negated. */ +#define AVERROR(e) (e) +#define AVUNERROR(e) (e) +#endif +#define AVERROR_UNKNOWN AVERROR(EINVAL) /**< unknown error */ +#define AVERROR_IO AVERROR(EIO) /**< I/O error */ +#define AVERROR_NUMEXPECTED AVERROR(EDOM) /**< Number syntax expected in filename. */ +#define AVERROR_INVALIDDATA AVERROR(EINVAL) /**< invalid data found */ +#define AVERROR_NOMEM AVERROR(ENOMEM) /**< not enough memory */ +#define AVERROR_NOFMT AVERROR(EILSEQ) /**< unknown format */ +#define AVERROR_NOTSUPP AVERROR(ENOSYS) /**< Operation not supported. */ +#define AVERROR_NOENT AVERROR(ENOENT) /**< No such file or directory. */ +#define AVERROR_PATCHWELCOME -MKTAG('P','A','W','E') /**< Not yet implemented in FFmpeg. Patches welcome. */ + +#endif /* AVCODEC_AVCODEC_H */ diff --git a/scalos/include/ffmpeg/libavcodec/imgconvert.h b/scalos/include/ffmpeg/libavcodec/imgconvert.h new file mode 100644 index 000000000..83bce68f5 --- /dev/null +++ b/scalos/include/ffmpeg/libavcodec/imgconvert.h @@ -0,0 +1,39 @@ +/* + * Misc image conversion routines + * most functionality is exported to the public API, see avcodec.h + * + * Copyright (c) 2008 Vitor Sessak + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_IMGCONVERT_H +#define AVCODEC_IMGCONVERT_H + +#include +#include "avcodec.h" + +int ff_fill_linesize(AVPicture *picture, int pix_fmt, int width); + +int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, int pix_fmt, int height); + +int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane); + +int img_convert(AVPicture *dst, int dst_pix_fmt, const AVPicture *src, + int src_pix_fmt, int src_width, int src_height); + +#endif /* AVCODEC_IMGCONVERT_H */ diff --git a/scalos/include/ffmpeg/libavutil/avutil.h b/scalos/include/ffmpeg/libavutil/avutil.h new file mode 100644 index 000000000..a21a8a475 --- /dev/null +++ b/scalos/include/ffmpeg/libavutil/avutil.h @@ -0,0 +1,147 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AVUTIL_H +#define AVUTIL_AVUTIL_H + +/** + * @file avutil.h + * external API header + */ + + +#define AV_STRINGIFY(s) AV_TOSTRING(s) +#define AV_TOSTRING(s) #s + +#define AV_VERSION_INT(a, b, c) (a<<16 | b<<8 | c) +#define AV_VERSION_DOT(a, b, c) a ##.## b ##.## c +#define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c) + +#define LIBAVUTIL_VERSION_MAJOR 49 +#define LIBAVUTIL_VERSION_MINOR 12 +#define LIBAVUTIL_VERSION_MICRO 0 + +#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ + LIBAVUTIL_VERSION_MINOR, \ + LIBAVUTIL_VERSION_MICRO) +#define LIBAVUTIL_VERSION AV_VERSION(LIBAVUTIL_VERSION_MAJOR, \ + LIBAVUTIL_VERSION_MINOR, \ + LIBAVUTIL_VERSION_MICRO) +#define LIBAVUTIL_BUILD LIBAVUTIL_VERSION_INT + +#define LIBAVUTIL_IDENT "Lavu" AV_STRINGIFY(LIBAVUTIL_VERSION) + +/** + * Returns the LIBAVUTIL_VERSION_INT constant. + */ +unsigned avutil_version(void); + +#include "common.h" +#include "mathematics.h" +#include "rational.h" +#include "intfloat_readwrite.h" +#include "log.h" + +/** + * Pixel format. Notes: + * + * PIX_FMT_RGB32 is handled in an endian-specific manner. A RGBA + * color is put together as: + * (A << 24) | (R << 16) | (G << 8) | B + * This is stored as BGRA on little endian CPU architectures and ARGB on + * big endian CPUs. + * + * When the pixel format is palettized RGB (PIX_FMT_PAL8), the palettized + * image data is stored in AVFrame.data[0]. The palette is transported in + * AVFrame.data[1] and, is 1024 bytes long (256 4-byte entries) and is + * formatted the same as in PIX_FMT_RGB32 described above (i.e., it is + * also endian-specific). Note also that the individual RGB palette + * components stored in AVFrame.data[1] should be in the range 0..255. + * This is important as many custom PAL8 video codecs that were designed + * to run on the IBM VGA graphics adapter use 6-bit palette components. + */ +enum PixelFormat { + PIX_FMT_NONE= -1, + PIX_FMT_YUV420P, ///< Planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples) + PIX_FMT_YUYV422, ///< Packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr + PIX_FMT_RGB24, ///< Packed RGB 8:8:8, 24bpp, RGBRGB... + PIX_FMT_BGR24, ///< Packed RGB 8:8:8, 24bpp, BGRBGR... + PIX_FMT_YUV422P, ///< Planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples) + PIX_FMT_YUV444P, ///< Planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples) + PIX_FMT_RGB32, ///< Packed RGB 8:8:8, 32bpp, (msb)8A 8R 8G 8B(lsb), in cpu endianness + PIX_FMT_YUV410P, ///< Planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples) + PIX_FMT_YUV411P, ///< Planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) + PIX_FMT_RGB565, ///< Packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), in cpu endianness + PIX_FMT_RGB555, ///< Packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), in cpu endianness most significant bit to 0 + PIX_FMT_GRAY8, ///< Y , 8bpp + PIX_FMT_MONOWHITE, ///< Y , 1bpp, 0 is white, 1 is black + PIX_FMT_MONOBLACK, ///< Y , 1bpp, 0 is black, 1 is white + PIX_FMT_PAL8, ///< 8 bit with PIX_FMT_RGB32 palette + PIX_FMT_YUVJ420P, ///< Planar YUV 4:2:0, 12bpp, full scale (jpeg) + PIX_FMT_YUVJ422P, ///< Planar YUV 4:2:2, 16bpp, full scale (jpeg) + PIX_FMT_YUVJ444P, ///< Planar YUV 4:4:4, 24bpp, full scale (jpeg) + PIX_FMT_XVMC_MPEG2_MC,///< XVideo Motion Acceleration via common packet passing(xvmc_render.h) + PIX_FMT_XVMC_MPEG2_IDCT, + PIX_FMT_UYVY422, ///< Packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1 + PIX_FMT_UYYVYY411, ///< Packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3 + PIX_FMT_BGR32, ///< Packed RGB 8:8:8, 32bpp, (msb)8A 8B 8G 8R(lsb), in cpu endianness + PIX_FMT_BGR565, ///< Packed RGB 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), in cpu endianness + PIX_FMT_BGR555, ///< Packed RGB 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), in cpu endianness most significant bit to 1 + PIX_FMT_BGR8, ///< Packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb) + PIX_FMT_BGR4, ///< Packed RGB 1:2:1, 4bpp, (msb)1B 2G 1R(lsb) + PIX_FMT_BGR4_BYTE, ///< Packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb) + PIX_FMT_RGB8, ///< Packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb) + PIX_FMT_RGB4, ///< Packed RGB 1:2:1, 4bpp, (msb)1R 2G 1B(lsb) + PIX_FMT_RGB4_BYTE, ///< Packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb) + PIX_FMT_NV12, ///< Planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 for UV + PIX_FMT_NV21, ///< as above, but U and V bytes are swapped + + PIX_FMT_RGB32_1, ///< Packed RGB 8:8:8, 32bpp, (msb)8R 8G 8B 8A(lsb), in cpu endianness + PIX_FMT_BGR32_1, ///< Packed RGB 8:8:8, 32bpp, (msb)8B 8G 8R 8A(lsb), in cpu endianness + + PIX_FMT_GRAY16BE, ///< Y , 16bpp, big-endian + PIX_FMT_GRAY16LE, ///< Y , 16bpp, little-endian + PIX_FMT_YUV440P, ///< Planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples) + PIX_FMT_YUVJ440P, ///< Planar YUV 4:4:0 full scale (jpeg) + PIX_FMT_YUVA420P, ///< Planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples) + PIX_FMT_NB, ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions +}; + +#ifdef WORDS_BIGENDIAN +#define PIX_FMT_RGBA PIX_FMT_RGB32_1 +#define PIX_FMT_BGRA PIX_FMT_BGR32_1 +#define PIX_FMT_ARGB PIX_FMT_RGB32 +#define PIX_FMT_ABGR PIX_FMT_BGR32 +#define PIX_FMT_GRAY16 PIX_FMT_GRAY16BE +#else +#define PIX_FMT_RGBA PIX_FMT_BGR32 +#define PIX_FMT_BGRA PIX_FMT_RGB32 +#define PIX_FMT_ARGB PIX_FMT_BGR32_1 +#define PIX_FMT_ABGR PIX_FMT_RGB32_1 +#define PIX_FMT_GRAY16 PIX_FMT_GRAY16LE +#endif + +#if LIBAVUTIL_VERSION_INT < (50<<16) +#define PIX_FMT_UYVY411 PIX_FMT_UYYVYY411 +#define PIX_FMT_RGBA32 PIX_FMT_RGB32 +#define PIX_FMT_YUV422 PIX_FMT_YUYV422 +#endif + +#endif /* AVUTIL_AVUTIL_H */ diff --git a/scalos/include/ffmpeg/log.h b/scalos/include/ffmpeg/log.h new file mode 100644 index 000000000..152e773c2 --- /dev/null +++ b/scalos/include/ffmpeg/log.h @@ -0,0 +1,129 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_LOG_H +#define AVUTIL_LOG_H + +#include + +/** + * Describes the class of an AVClass context structure, that is an + * arbitrary struct of which the first field is a pointer to an + * AVClass struct (e.g. AVCodecContext, AVFormatContext etc.). + */ +typedef struct AVCLASS AVClass; +struct AVCLASS { + /** + * The name of the class; usually it is the same name as the + * context structure type to which the AVClass is associated. + */ + const char* class_name; + + /** + * a pointer to a function which returns the name of a context + * instance \p ctx associated with the class + */ + const char* (*item_name)(void* ctx); + + /** + * a pointer to the first option specified in the class if any or NULL + * + * @see av_set_default_options() + */ + const struct AVOption *option; +}; + +/* av_log API */ + +#if LIBAVUTIL_VERSION_INT < (50<<16) +#define AV_LOG_QUIET -1 +#define AV_LOG_FATAL 0 +#define AV_LOG_ERROR 0 +#define AV_LOG_WARNING 1 +#define AV_LOG_INFO 1 +#define AV_LOG_VERBOSE 1 +#define AV_LOG_DEBUG 2 +#else +#define AV_LOG_QUIET -8 + +/** + * something went really wrong and we will crash now + */ +#define AV_LOG_PANIC 0 + +/** + * something went wrong and recovery is not possible + * like no header in a format which depends on it or a combination + * of parameters which are not allowed + */ +#define AV_LOG_FATAL 8 + +/** + * something went wrong and cannot losslessly be recovered + * but not all future data is affected + */ +#define AV_LOG_ERROR 16 + +/** + * something somehow does not look correct / something which may or may not + * lead to some problems like use of -vstrict -2 + */ +#define AV_LOG_WARNING 24 + +#define AV_LOG_INFO 32 +#define AV_LOG_VERBOSE 40 + +/** + * stuff which is only useful for libav* developers + */ +#define AV_LOG_DEBUG 48 +#endif + +#if LIBAVUTIL_VERSION_INT < (50<<16) +extern int av_log_level; +#endif + +/** + * Send the specified message to the log if the level is less than or equal to + * the current av_log_level. By default, all logging messages are sent to + * stderr. This behavior can be altered by setting a different av_vlog callback + * function. + * + * @param avcl A pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct. + * @param level The importance level of the message, lower values signifying + * higher importance. + * @param fmt The format string (printf-compatible) that specifies how + * subsequent arguments are converted to output. + * @see av_vlog + */ +#ifdef __GNUC__ +void av_log(void*, int level, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 3, 4))); +#else +void av_log(void*, int level, const char *fmt, ...); +#endif + +void av_vlog(void*, int level, const char *fmt, va_list); +int av_log_get_level(void); +void av_log_set_level(int); +void av_log_set_callback(void (*)(void*, int, const char*, va_list)); +void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl); + +#endif /* AVUTIL_LOG_H */ diff --git a/scalos/include/ffmpeg/mathematics.h b/scalos/include/ffmpeg/mathematics.h new file mode 100644 index 000000000..74385274b --- /dev/null +++ b/scalos/include/ffmpeg/mathematics.h @@ -0,0 +1,69 @@ +/* + * copyright (c) 2005 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_MATHEMATICS_H +#define AVUTIL_MATHEMATICS_H + +#include +#include +#include "rational.h" + +#ifndef M_E +#define M_E 2.7182818284590452354 /* e */ +#endif +#ifndef M_LN2 +#define M_LN2 0.69314718055994530942 /* log_e 2 */ +#endif +#ifndef M_LN10 +#define M_LN10 2.30258509299404568402 /* log_e 10 */ +#endif +#ifndef M_PI +#define M_PI 3.14159265358979323846 /* pi */ +#endif +#ifndef M_SQRT1_2 +#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ +#endif + +enum AVRounding { + AV_ROUND_ZERO = 0, ///< round toward zero + AV_ROUND_INF = 1, ///< round away from zero + AV_ROUND_DOWN = 2, ///< round toward -infinity + AV_ROUND_UP = 3, ///< round toward +infinity + AV_ROUND_NEAR_INF = 5, ///< round to nearest and halfway cases away from zero +}; + +/** + * rescale a 64bit integer with rounding to nearest. + * a simple a*b/c isn't possible as it can overflow + */ +int64_t av_rescale(int64_t a, int64_t b, int64_t c) av_const; + +/** + * rescale a 64bit integer with specified rounding. + * a simple a*b/c isn't possible as it can overflow + */ +int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding) av_const; + +/** + * rescale a 64bit integer by 2 rational numbers. + */ +int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq) av_const; + +#endif /* AVUTIL_MATHEMATICS_H */ diff --git a/scalos/include/ffmpeg/mem.h b/scalos/include/ffmpeg/mem.h new file mode 100644 index 000000000..a02c7e150 --- /dev/null +++ b/scalos/include/ffmpeg/mem.h @@ -0,0 +1,119 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file mem.h + * Memory handling functions. + */ + +#ifndef AVUTIL_MEM_H +#define AVUTIL_MEM_H + +#if defined(__ICC) || defined(__SUNPRO_C) + #define DECLARE_ALIGNED(n,t,v) t v __attribute__ ((aligned (n))) + #define DECLARE_ASM_CONST(n,t,v) const t __attribute__ ((aligned (n))) v +#elif defined(__GNUC__) + #define DECLARE_ALIGNED(n,t,v) t v __attribute__ ((aligned (n))) + #define DECLARE_ASM_CONST(n,t,v) static const t v attribute_used __attribute__ ((aligned (n))) +#elif defined(_MSC_VER) + #define DECLARE_ALIGNED(n,t,v) __declspec(align(n)) t v + #define DECLARE_ASM_CONST(n,t,v) __declspec(align(n)) static const t v +#elif defined(HAVE_INLINE_ASM) + #error The asm code needs alignment, but we do not know how to do it for this compiler. +#else + #define DECLARE_ALIGNED(n,t,v) t v + #define DECLARE_ASM_CONST(n,t,v) static const t v +#endif + +#if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0) + #define av_malloc_attrib __attribute__((__malloc__)) +#else + #define av_malloc_attrib +#endif + +#if defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ > 2) + #define av_alloc_size(n) __attribute__((alloc_size(n))) +#else + #define av_alloc_size(n) +#endif + +/** + * Allocate a block of \p size bytes with alignment suitable for all + * memory accesses (including vectors if available on the CPU). + * @param size Size in bytes for the memory block to be allocated. + * @return Pointer to the allocated block, NULL if it cannot allocate + * it. + * @see av_mallocz() + */ +void *av_malloc(unsigned int size) av_malloc_attrib av_alloc_size(1); + +/** + * Allocate or reallocate a block of memory. + * If \p ptr is NULL and \p size > 0, allocate a new block. If \p + * size is zero, free the memory block pointed by \p ptr. + * @param size Size in bytes for the memory block to be allocated or + * reallocated. + * @param ptr Pointer to a memory block already allocated with + * av_malloc(z)() or av_realloc() or NULL. + * @return Pointer to a newly reallocated block or NULL if it cannot + * reallocate or the function is used to free the memory block. + * @see av_fast_realloc() + */ +void *av_realloc(void *ptr, unsigned int size) av_alloc_size(2); + +/** + * Free a memory block which has been allocated with av_malloc(z)() or + * av_realloc(). + * @param ptr Pointer to the memory block which should be freed. + * @note ptr = NULL is explicitly allowed. + * @note It is recommended that you use av_freep() instead. + * @see av_freep() + */ +void av_free(void *ptr); + +/** + * Allocate a block of \p size bytes with alignment suitable for all + * memory accesses (including vectors if available on the CPU) and + * set to zeroes all the bytes of the block. + * @param size Size in bytes for the memory block to be allocated. + * @return Pointer to the allocated block, NULL if it cannot allocate + * it. + * @see av_malloc() + */ +void *av_mallocz(unsigned int size) av_malloc_attrib av_alloc_size(1); + +/** + * Duplicate the string \p s. + * @param s String to be duplicated. + * @return Pointer to a newly allocated string containing a + * copy of \p s or NULL if it cannot be allocated. + */ +char *av_strdup(const char *s) av_malloc_attrib; + +/** + * Free a memory block which has been allocated with av_malloc(z)() or + * av_realloc() and set to NULL the pointer to it. + * @param ptr Pointer to the pointer to the memory block which should + * be freed. + * @see av_free() + */ +void av_freep(void *ptr); + +#endif /* AVUTIL_MEM_H */ diff --git a/scalos/include/ffmpeg/rational.h b/scalos/include/ffmpeg/rational.h new file mode 100644 index 000000000..70b7735da --- /dev/null +++ b/scalos/include/ffmpeg/rational.h @@ -0,0 +1,129 @@ +/* + * Rational numbers + * Copyright (c) 2003 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file rational.h + * Rational numbers. + * @author Michael Niedermayer + */ + +#ifndef AVUTIL_RATIONAL_H +#define AVUTIL_RATIONAL_H + +#include +#include "common.h" + +/** + * Rational number num/den. + */ +typedef struct AVRational{ + int num; ///< numerator + int den; ///< denominator +} AVRational; + +/** + * Compare two rationals. + * @param a first rational + * @param b second rational + * @return 0 if a==b, 1 if a>b and -1 if a>63)|1; + else return 0; +} + +/** + * Rational to double conversion. + * @param a rational to convert + * @return (double) a + */ +static inline double av_q2d(AVRational a){ + return a.num / (double) a.den; +} + +/** + * Reduce a fraction. + * This is useful for framerate calculations. + * @param dst_nom destination numerator + * @param dst_den destination denominator + * @param nom source numerator + * @param den source denominator + * @param max the maximum allowed for dst_nom & dst_den + * @return 1 if exact, 0 otherwise + */ +int av_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max); + +/** + * Multiplies two rationals. + * @param b first rational. + * @param c second rational. + * @return b*c. + */ +AVRational av_mul_q(AVRational b, AVRational c) av_const; + +/** + * Divides one rational by another. + * @param b first rational. + * @param c second rational. + * @return b/c. + */ +AVRational av_div_q(AVRational b, AVRational c) av_const; + +/** + * Adds two rationals. + * @param b first rational. + * @param c second rational. + * @return b+c. + */ +AVRational av_add_q(AVRational b, AVRational c) av_const; + +/** + * Subtracts one rational from another. + * @param b first rational. + * @param c second rational. + * @return b-c. + */ +AVRational av_sub_q(AVRational b, AVRational c) av_const; + +/** + * Converts a double precision floating point number to a rational. + * @param d double to convert + * @param max the maximum allowed numerator and denominator + * @return (AVRational) d. + */ +AVRational av_d2q(double d, int max) av_const; + +/** + * @return 1 if \q1 is nearer to \p q than \p q2, -1 if \p q2 is nearer + * than \p q1, 0 if they have the same distance. + */ +int av_nearer_q(AVRational q, AVRational q1, AVRational q2); + +/** + * Finds the nearest value in \p q_list to \p q. + * @param q_list an array of rationals terminated by {0, 0} + * @return the index of the nearest value found in the array + */ +int av_find_nearest_q_idx(AVRational q, const AVRational* q_list); + +#endif /* AVUTIL_RATIONAL_H */ diff --git a/scalos/include/ffmpeg/rtp.h b/scalos/include/ffmpeg/rtp.h new file mode 100644 index 000000000..7819ceb68 --- /dev/null +++ b/scalos/include/ffmpeg/rtp.h @@ -0,0 +1,92 @@ +/* + * RTP definitions + * Copyright (c) 2002 Fabrice Bellard. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef AVFORMAT_RTP_H +#define AVFORMAT_RTP_H + +#include "libavcodec/avcodec.h" +#include "avformat.h" + +/** Structure listing useful vars to parse RTP packet payload*/ +typedef struct rtp_payload_data +{ + int sizelength; + int indexlength; + int indexdeltalength; + int profile_level_id; + int streamtype; + int objecttype; + char *mode; + + /** mpeg 4 AU headers */ + struct AUHeaders { + int size; + int index; + int cts_flag; + int cts; + int dts_flag; + int dts; + int rap_flag; + int streamstate; + } *au_headers; + int nb_au_headers; + int au_headers_length_bytes; + int cur_au_index; +} RTPPayloadData; + +typedef struct PayloadContext PayloadContext; +typedef struct RTPDynamicProtocolHandler_s RTPDynamicProtocolHandler; + +#define RTP_MIN_PACKET_LENGTH 12 +#define RTP_MAX_PACKET_LENGTH 1500 /* XXX: suppress this define */ + +int rtp_get_codec_info(AVCodecContext *codec, int payload_type); + +/** return < 0 if unknown payload type */ +int rtp_get_payload_type(AVCodecContext *codec); + +typedef struct RTPDemuxContext RTPDemuxContext; +RTPDemuxContext *rtp_parse_open(AVFormatContext *s1, AVStream *st, URLContext *rtpc, int payload_type, RTPPayloadData *rtp_payload_data); +void rtp_parse_set_dynamic_protocol(RTPDemuxContext *s, PayloadContext *ctx, + RTPDynamicProtocolHandler *handler); +int rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt, + const uint8_t *buf, int len); +void rtp_parse_close(RTPDemuxContext *s); + +int rtp_get_local_port(URLContext *h); +int rtp_set_remote_url(URLContext *h, const char *uri); +void rtp_get_file_handles(URLContext *h, int *prtp_fd, int *prtcp_fd); + +/** + * some rtp servers assume client is dead if they don't hear from them... + * so we send a Receiver Report to the provided ByteIO context + * (we don't have access to the rtcp handle from here) + */ +int rtp_check_and_send_back_rr(RTPDemuxContext *s, int count); + +#define RTP_PT_PRIVATE 96 +#define RTP_VERSION 2 +#define RTP_MAX_SDES 256 /**< maximum text length for SDES */ + +/* RTCP paquets use 0.5 % of the bandwidth */ +#define RTCP_TX_RATIO_NUM 5 +#define RTCP_TX_RATIO_DEN 1000 + +#endif /* AVFORMAT_RTP_H */ diff --git a/scalos/include/ffmpeg/rtsp.h b/scalos/include/ffmpeg/rtsp.h new file mode 100644 index 000000000..611f5c3aa --- /dev/null +++ b/scalos/include/ffmpeg/rtsp.h @@ -0,0 +1,99 @@ +/* + * RTSP definitions + * Copyright (c) 2002 Fabrice Bellard. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef FFMPEG_RTSP_H +#define FFMPEG_RTSP_H + +#include +#include "avformat.h" +#include "rtspcodes.h" + +enum RTSPLowerTransport { + RTSP_LOWER_TRANSPORT_UDP = 0, + RTSP_LOWER_TRANSPORT_TCP = 1, + RTSP_LOWER_TRANSPORT_UDP_MULTICAST = 2, + /** + * This is not part of public API and shouldn't be used outside of ffmpeg. + */ + RTSP_LOWER_TRANSPORT_LAST +}; + +#define RTSP_DEFAULT_PORT 554 +#define RTSP_MAX_TRANSPORTS 8 +#define RTSP_TCP_MAX_PACKET_SIZE 1472 +#define RTSP_DEFAULT_NB_AUDIO_CHANNELS 2 +#define RTSP_DEFAULT_AUDIO_SAMPLERATE 44100 +#define RTSP_RTP_PORT_MIN 5000 +#define RTSP_RTP_PORT_MAX 10000 + +typedef struct RTSPTransportField { + int interleaved_min, interleaved_max; /**< interleave ids, if TCP transport */ + int port_min, port_max; /**< RTP ports */ + int client_port_min, client_port_max; /**< RTP ports */ + int server_port_min, server_port_max; /**< RTP ports */ + int ttl; /**< ttl value */ + uint32_t destination; /**< destination IP address */ + int transport; + enum RTSPLowerTransport lower_transport; +} RTSPTransportField; + +typedef struct RTSPHeader { + int content_length; + enum RTSPStatusCode status_code; /**< response code from server */ + int nb_transports; + /** in AV_TIME_BASE unit, AV_NOPTS_VALUE if not used */ + int64_t range_start, range_end; + RTSPTransportField transports[RTSP_MAX_TRANSPORTS]; + int seq; /**< sequence number */ + char session_id[512]; + char real_challenge[64]; /**< the RealChallenge1 field from the server */ +} RTSPHeader; + +/** the callback can be used to extend the connection setup/teardown step */ +enum RTSPCallbackAction { + RTSP_ACTION_SERVER_SETUP, + RTSP_ACTION_SERVER_TEARDOWN, + RTSP_ACTION_CLIENT_SETUP, + RTSP_ACTION_CLIENT_TEARDOWN, +}; + +typedef struct RTSPActionServerSetup { + uint32_t ipaddr; + char transport_option[512]; +} RTSPActionServerSetup; + +typedef int FFRTSPCallback(enum RTSPCallbackAction action, + const char *session_id, + char *buf, int buf_size, + void *arg); + +int rtsp_init(void); +void rtsp_parse_line(RTSPHeader *reply, const char *buf); + +#if LIBAVFORMAT_VERSION_INT < (53 << 16) +extern int rtsp_default_protocols; +#endif +extern int rtsp_rtp_port_min; +extern int rtsp_rtp_port_max; + +int rtsp_pause(AVFormatContext *s); +int rtsp_resume(AVFormatContext *s); + +#endif /* FFMPEG_RTSP_H */ diff --git a/scalos/include/ffmpeg/rtspcodes.h b/scalos/include/ffmpeg/rtspcodes.h new file mode 100644 index 000000000..9ee96bfcd --- /dev/null +++ b/scalos/include/ffmpeg/rtspcodes.h @@ -0,0 +1,40 @@ +/* + * RTSP definitions + * copyright (c) 2002 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVFORMAT_RTSPCODES_H +#define AVFORMAT_RTSPCODES_H + +/** RTSP handling */ +enum RTSPStatusCode { +RTSP_STATUS_OK =200, /**< OK */ +RTSP_STATUS_METHOD =405, /**< Method Not Allowed */ +RTSP_STATUS_BANDWIDTH =453, /**< Not Enough Bandwidth */ +RTSP_STATUS_SESSION =454, /**< Session Not Found */ +RTSP_STATUS_STATE =455, /**< Method Not Valid in This State */ +RTSP_STATUS_AGGREGATE =459, /**< Aggregate operation not allowed */ +RTSP_STATUS_ONLY_AGGREGATE =460, /**< Only aggregate operation allowed */ +RTSP_STATUS_TRANSPORT =461, /**< Unsupported transport */ +RTSP_STATUS_INTERNAL =500, /**< Internal Server Error */ +RTSP_STATUS_SERVICE =503, /**< Service Unavailable */ +RTSP_STATUS_VERSION =505, /**< RTSP Version not supported */ +}; + +#endif /* AVFORMAT_RTSPCODES_H */ diff --git a/scalos/include/ffmpeg/swscale.h b/scalos/include/ffmpeg/swscale.h new file mode 100644 index 000000000..95ff4f177 --- /dev/null +++ b/scalos/include/ffmpeg/swscale.h @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2001-2003 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SWSCALE_SWSCALE_H +#define SWSCALE_SWSCALE_H + +/** + * @file swscale.h + * @brief + * external api for the swscale stuff + */ + +#include "libavutil/avutil.h" + +#define LIBSWSCALE_VERSION_MAJOR 0 +#define LIBSWSCALE_VERSION_MINOR 6 +#define LIBSWSCALE_VERSION_MICRO 1 + +#define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \ + LIBSWSCALE_VERSION_MINOR, \ + LIBSWSCALE_VERSION_MICRO) +#define LIBSWSCALE_VERSION AV_VERSION(LIBSWSCALE_VERSION_MAJOR, \ + LIBSWSCALE_VERSION_MINOR, \ + LIBSWSCALE_VERSION_MICRO) +#define LIBSWSCALE_BUILD LIBSWSCALE_VERSION_INT + +#define LIBSWSCALE_IDENT "SwS" AV_STRINGIFY(LIBSWSCALE_VERSION) + +/** + * Returns the LIBSWSCALE_VERSION_INT constant. + */ +unsigned swscale_version(void); + +/* values for the flags, the stuff on the command line is different */ +#define SWS_FAST_BILINEAR 1 +#define SWS_BILINEAR 2 +#define SWS_BICUBIC 4 +#define SWS_X 8 +#define SWS_POINT 0x10 +#define SWS_AREA 0x20 +#define SWS_BICUBLIN 0x40 +#define SWS_GAUSS 0x80 +#define SWS_SINC 0x100 +#define SWS_LANCZOS 0x200 +#define SWS_SPLINE 0x400 + +#define SWS_SRC_V_CHR_DROP_MASK 0x30000 +#define SWS_SRC_V_CHR_DROP_SHIFT 16 + +#define SWS_PARAM_DEFAULT 123456 + +#define SWS_PRINT_INFO 0x1000 + +//the following 3 flags are not completely implemented +//internal chrominace subsampling info +#define SWS_FULL_CHR_H_INT 0x2000 +//input subsampling info +#define SWS_FULL_CHR_H_INP 0x4000 +#define SWS_DIRECT_BGR 0x8000 +#define SWS_ACCURATE_RND 0x40000 +#define SWS_BITEXACT 0x80000 + +#define SWS_CPU_CAPS_MMX 0x80000000 +#define SWS_CPU_CAPS_MMX2 0x20000000 +#define SWS_CPU_CAPS_3DNOW 0x40000000 +#define SWS_CPU_CAPS_ALTIVEC 0x10000000 +#define SWS_CPU_CAPS_BFIN 0x01000000 + +#define SWS_MAX_REDUCE_CUTOFF 0.002 + +#define SWS_CS_ITU709 1 +#define SWS_CS_FCC 4 +#define SWS_CS_ITU601 5 +#define SWS_CS_ITU624 5 +#define SWS_CS_SMPTE170M 5 +#define SWS_CS_SMPTE240M 7 +#define SWS_CS_DEFAULT 5 + + + +// when used for filters they must have an odd number of elements +// coeffs cannot be shared between vectors +typedef struct { + double *coeff; + int length; +} SwsVector; + +// vectors can be shared +typedef struct { + SwsVector *lumH; + SwsVector *lumV; + SwsVector *chrH; + SwsVector *chrV; +} SwsFilter; + +struct SwsContext; + +void sws_freeContext(struct SwsContext *swsContext); + +struct SwsContext *sws_getContext(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat, int flags, + SwsFilter *srcFilter, SwsFilter *dstFilter, double *param); +int sws_scale(struct SwsContext *context, uint8_t* src[], int srcStride[], int srcSliceY, + int srcSliceH, uint8_t* dst[], int dstStride[]); +int sws_scale_ordered(struct SwsContext *context, uint8_t* src[], int srcStride[], int srcSliceY, + int srcSliceH, uint8_t* dst[], int dstStride[]) attribute_deprecated; + + +int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4], int srcRange, const int table[4], int dstRange, int brightness, int contrast, int saturation); +int sws_getColorspaceDetails(struct SwsContext *c, int **inv_table, int *srcRange, int **table, int *dstRange, int *brightness, int *contrast, int *saturation); +SwsVector *sws_getGaussianVec(double variance, double quality); +SwsVector *sws_getConstVec(double c, int length); +SwsVector *sws_getIdentityVec(void); +void sws_scaleVec(SwsVector *a, double scalar); +void sws_normalizeVec(SwsVector *a, double height); +void sws_convVec(SwsVector *a, SwsVector *b); +void sws_addVec(SwsVector *a, SwsVector *b); +void sws_subVec(SwsVector *a, SwsVector *b); +void sws_shiftVec(SwsVector *a, int shift); +SwsVector *sws_cloneVec(SwsVector *a); + +void sws_printVec(SwsVector *a); +void sws_freeVec(SwsVector *a); + +SwsFilter *sws_getDefaultFilter(float lumaGBlur, float chromaGBlur, + float lumaSarpen, float chromaSharpen, + float chromaHShift, float chromaVShift, + int verbose); +void sws_freeFilter(SwsFilter *filter); + +struct SwsContext *sws_getCachedContext(struct SwsContext *context, + int srcW, int srcH, int srcFormat, + int dstW, int dstH, int dstFormat, int flags, + SwsFilter *srcFilter, SwsFilter *dstFilter, double *param); + +#endif /* SWSCALE_SWSCALE_H */ diff --git a/scalos/include/images/titlebar.h b/scalos/include/images/titlebar.h new file mode 100755 index 000000000..b0e40db78 --- /dev/null +++ b/scalos/include/images/titlebar.h @@ -0,0 +1,44 @@ + + +#ifndef IMAGES_TITLEBAR_H +#define IMAGES_TITLEBAR_H + + +/************************************************************/ +/* Public definitions for the "titlebar image" BOOPSI class */ +/************************************************************/ + +/* This macro can be used to compute the correct position for a gadget */ +/* to be placed into the titlebar. "tbi" is a pointer to a "tbiclass" */ +/* instance and "num" is the number of gadgets (zoom, depth...) that */ +/* will be at the right side of the new gadget. For instance, if your */ +/* window has both a zoom gadget and a depth gadget, you can compute */ +/* the position of a new titlebar gadget with TBI_RELPOS(tbi,2). */ +/* If there's instead only a depth gadget, you'll use TBI_RELPOS(tbi,1). */ +/* Note: the new gadget MUST have the GFLG_RELRIGHT flag set. */ + +#define TBI_RELPOS(tbi,num) (1 - ((1 + (num)) * ((tbi)->Width - 1))) + +/* Attributes defined by the "tbiclass" image class */ + +#define TBIA_Dummy (TAG_USER + 0x0B0000) +#define TBIA_ContentsBox (TBIA_Dummy + 0x0001) /* Get inner size (V40.12) */ + +/* Types of titlebar gadget images available */ + +#define POPUPIMAGE (101) +#define MUIIMAGE (102) +#define SNAPSHOTIMAGE (103) +#define ICONIFYIMAGE (104) +#define PADLOCKIMAGE (105) +#define TBFRAMEIMAGE (106) + + +/***********************************************************/ +/* Public structures for the "titlebar image" BOOPSI class */ +/***********************************************************/ + + +#endif + + diff --git a/scalos/include/inline/cybergraphics.h b/scalos/include/inline/cybergraphics.h new file mode 100755 index 000000000..bc52c0b6c --- /dev/null +++ b/scalos/include/inline/cybergraphics.h @@ -0,0 +1,172 @@ +#ifndef _INLINE_CYBERGRAPHICS_H +#define _INLINE_CYBERGRAPHICS_H + +#ifndef CLIB_CYBERGRAPHICS_PROTOS_H +#define CLIB_CYBERGRAPHICS_PROTOS_H +#endif + +#ifndef __INLINE_MACROS_H +#include +#endif + +#ifndef UTILITY_TAGITEM_H +#include +#endif + +#ifndef CYBERGRAPHICS_BASE_NAME +#define CYBERGRAPHICS_BASE_NAME CyberGfxBase +#endif + +#define IsCyberModeID(displayID) \ + LP1(0x36, BOOL, IsCyberModeID, ULONG, displayID, d0, \ + , CYBERGRAPHICS_BASE_NAME) + +#define BestCModeIDTagList(bestModeIDTags) \ + LP1(0x3c, ULONG, BestCModeIDTagList, struct TagItem *, bestModeIDTags, a0, \ + , CYBERGRAPHICS_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define BestCModeIDTags(tags...) \ + ({ULONG _tags[] = {tags}; BestCModeIDTagList((struct TagItem *) _tags);}) +#endif + +#define CModeRequestTagList(modeRequest, modeRequestTags) \ + LP2(0x42, ULONG, CModeRequestTagList, APTR, modeRequest, a0, struct TagItem *, modeRequestTags, a1, \ + , CYBERGRAPHICS_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define CModeRequestTags(modeRequest, tags...) \ + ({ULONG _tags[] = {tags}; CModeRequestTagList((modeRequest), (struct TagItem *) _tags);}) +#endif + +#define AllocCModeListTagList(modeListTags) \ + LP1(0x48, struct List *, AllocCModeListTagList, struct TagItem *, modeListTags, a1, \ + , CYBERGRAPHICS_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define AllocCModeListTags(tags...) \ + ({ULONG _tags[] = {tags}; AllocCModeListTagList((struct TagItem *) _tags);}) +#endif + +#define FreeCModeList(modeList) \ + LP1NR(0x4e, FreeCModeList, struct List *, modeList, a0, \ + , CYBERGRAPHICS_BASE_NAME) + +#define ScalePixelArray(srcRect, srcW, srcH, srcMod, rp, destX, destY, destW, destH, srcFormat) \ + LP10(0x5a, LONG, ScalePixelArray, APTR, srcRect, a0, ULONG, srcW, d0, ULONG, srcH, d1, ULONG, srcMod, d2, struct RastPort *, rp, a1, ULONG, destX, d3, ULONG, destY, d4, ULONG, destW, d5, ULONG, destH, d6, ULONG, srcFormat, d7, \ + , CYBERGRAPHICS_BASE_NAME) + +#define GetCyberMapAttr(cyberGfxBitmap, cyberAttrTag) \ + LP2(0x60, ULONG, GetCyberMapAttr, struct BitMap *, cyberGfxBitmap, a0, ULONG, cyberAttrTag, d0, \ + , CYBERGRAPHICS_BASE_NAME) + +#define GetCyberIDAttr(cyberIDAttr, cyberDisplayModeID) \ + LP2(0x66, ULONG, GetCyberIDAttr, ULONG, cyberIDAttr, d0, ULONG, cyberDisplayModeID, d1, \ + , CYBERGRAPHICS_BASE_NAME) + +#define ReadRGBPixel(rp, x, y) \ + LP3(0x6c, ULONG, ReadRGBPixel, struct RastPort *, rp, a1, ULONG, x, d0, ULONG, y, d1, \ + , CYBERGRAPHICS_BASE_NAME) + +#define WriteRGBPixel(rp, x, y, argb) \ + LP4(0x72, LONG, WriteRGBPixel, struct RastPort *, rp, a1, ULONG, x, d0, ULONG, y, d1, ULONG, argb, d2, \ + , CYBERGRAPHICS_BASE_NAME) + +#define ReadPixelArray(destRect, destX, destY, destMod, rp, srcX, srcY, sizeX, sizeY, destFormat) \ + LP10(0x78, ULONG, ReadPixelArray, APTR, destRect, a0, ULONG, destX, d0, ULONG, destY, d1, ULONG, destMod, d2, struct RastPort *, rp, a1, ULONG, srcX, d3, ULONG, srcY, d4, ULONG, sizeX, d5, ULONG, sizeY, d6, ULONG, destFormat, d7, \ + , CYBERGRAPHICS_BASE_NAME) + +#define WritePixelArray(srcRect, srcX, srcY, srcMod, rp, destX, destY, sizeX, sizeY, srcFormat) \ + LP10(0x7e, ULONG, WritePixelArray, APTR, srcRect, a0, ULONG, srcX, d0, ULONG, srcY, d1, ULONG, srcMod, d2, struct RastPort *, rp, a1, ULONG, destX, d3, ULONG, destY, d4, ULONG, sizeX, d5, ULONG, sizeY, d6, ULONG, srcFormat, d7, \ + , CYBERGRAPHICS_BASE_NAME) + +#define MovePixelArray(srcX, srcY, rp, destX, destY, sizeX, sizeY) \ + LP7(0x84, ULONG, MovePixelArray, ULONG, srcX, d0, ULONG, srcY, d1, struct RastPort *, rp, a1, ULONG, destX, d2, ULONG, destY, d3, ULONG, sizeX, d4, ULONG, sizeY, d5, \ + , CYBERGRAPHICS_BASE_NAME) + +#define InvertPixelArray(rp, destX, destY, sizeX, sizeY) \ + LP5(0x90, ULONG, InvertPixelArray, struct RastPort *, rp, a1, ULONG, destX, d0, ULONG, destY, d1, ULONG, sizeX, d2, ULONG, sizeY, d3, \ + , CYBERGRAPHICS_BASE_NAME) + +#define FillPixelArray(rp, destX, destY, sizeX, sizeY, aRGB) \ + LP6(0x96, ULONG, FillPixelArray, struct RastPort *, rp, a1, ULONG, destX, d0, ULONG, destY, d1, ULONG, sizeX, d2, ULONG, sizeY, d3, ULONG, aRGB, d4, \ + , CYBERGRAPHICS_BASE_NAME) + +#define DoCDrawMethodTagList(hook, rp, tagList) \ + LP3NR(0x9c, DoCDrawMethodTagList, struct Hook *, hook, a0, struct RastPort *, rp, a1, struct TagItem *, tagList, a2, \ + , CYBERGRAPHICS_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define DoCDrawMethodTags(hook, rp, tags...) \ + ({ULONG _tags[] = {tags}; DoCDrawMethodTagList((hook), (rp), (struct TagItem *) _tags);}) +#endif + +#define CVideoCtrlTagList(viewPort, tagList) \ + LP2NR(0xa2, CVideoCtrlTagList, struct ViewPort *, viewPort, a0, struct TagItem *, tagList, a1, \ + , CYBERGRAPHICS_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define CVideoCtrlTags(viewPort, tags...) \ + ({ULONG _tags[] = {tags}; CVideoCtrlTagList((viewPort), (struct TagItem *) _tags);}) +#endif + +#define LockBitMapTagList(bitMap, tagList) \ + LP2(0xa8, APTR, LockBitMapTagList, APTR, bitMap, a0, struct TagItem *, tagList, a1, \ + , CYBERGRAPHICS_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define LockBitMapTags(bitMap, tags...) \ + ({ULONG _tags[] = {tags}; LockBitMapTagList((bitMap), (struct TagItem *) _tags);}) +#endif + +#define UnLockBitMap(handle) \ + LP1NR(0xae, UnLockBitMap, APTR, handle, a0, \ + , CYBERGRAPHICS_BASE_NAME) + +#define UnLockBitMapTagList(handle, tagList) \ + LP2NR(0xb4, UnLockBitMapTagList, APTR, handle, a0, struct TagItem *, tagList, a1, \ + , CYBERGRAPHICS_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define UnLockBitMapTags(handle, tags...) \ + ({ULONG _tags[] = {tags}; UnLockBitMapTagList((handle), (struct TagItem *) _tags);}) +#endif + +#define ExtractColor(rp, bitMap, colour, srcX, srcY, width, height) \ + LP7(0xba, ULONG, ExtractColor, struct RastPort *, rp, a0, struct BitMap *, bitMap, a1, ULONG, colour, d0, ULONG, srcX, d1, ULONG, srcY, d2, ULONG, width, d3, ULONG, height, d4, \ + , CYBERGRAPHICS_BASE_NAME) + +#define WriteLUTPixelArray(srcRect, srcX, srcY, srcMod, rp, colorTab, destX, destY, sizeX, sizeY, cTFormat) \ + LP11(0xc6, ULONG, WriteLUTPixelArray, APTR, srcRect, a0, ULONG, srcX, d0, ULONG, srcY, d1, ULONG, srcMod, d2, struct RastPort *, rp, a1, APTR, colorTab, a2, ULONG, destX, d3, ULONG, destY, d4, ULONG, sizeX, d5, ULONG, sizeY, d6, ULONG, cTFormat, d7, \ + , CYBERGRAPHICS_BASE_NAME) + +#define WritePixelArrayAlpha(srcRect, srcX, srcY, srcMod, rp, destX, destY, sizeX, sizeY, globalAlpha) \ + LP10(0xd8, ULONG, WritePixelArrayAlpha, APTR, srcRect, a0, ULONG, srcX, d0, ULONG, srcY, d1, ULONG, srcMod, d2, struct RastPort *, rp, a1, ULONG, destX, d3, ULONG, destY, d4, ULONG, sizeX, d5, ULONG, sizeY, d6, ULONG, globalAlpha, d7, \ + , CYBERGRAPHICS_BASE_NAME) + +#define BltTemplateAlpha(source, xSrc, srcMod, destRP, xDest, yDest, xSize, ySize) \ + LP8NR(0xde, BltTemplateAlpha, UBYTE *, source, a0, LONG, xSrc, d0, LONG, srcMod, d1, struct RastPort *, destRP, a1, ULONG, xDest, d2, ULONG, yDest, d3, ULONG, xSize, d4, ULONG, ySize, d5, \ + , CYBERGRAPHICS_BASE_NAME) + +#define ProcessPixelArray(rp, destX, destY, sizeX, sizeY, operation, value, taglist) \ + LP8NR(0xe4, ProcessPixelArray, struct RastPort *, rp, a1, ULONG, destX, d0, ULONG, destY, d1, ULONG, sizeX, d2, ULONG, sizeY, d3, ULONG, operation, d4, LONG, value, d5, struct TagItem *, taglist, a2, \ + , CYBERGRAPHICS_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define ProcessPixelArrayTags(rp, destX, destY, sizeX, sizeY, operation, value, tags...) \ + ({ULONG _tags[] = {tags}; ProcessPixelArray((rp), (destX), (destY), (sizeX), (sizeY), (operation), (value), (struct TagItem *) _tags);}) +#endif + +#define BltBitMapAlpha(srcBitMap, srcX, srcY, destBitMap, destX, destY, sizeX, sizeY, taglist) \ + LP9(0xea, ULONG, BltBitMapAlpha, struct BitMap *, srcBitMap, a0, LONG, srcX, d0, LONG, srcY, d1, struct BitMap *, destBitMap, a1, LONG, destX, d2, LONG, destY, d3, LONG, sizeX, d4, LONG, sizeY, d5, struct TagItem *, taglist, a2, \ + , CYBERGRAPHICS_BASE_NAME) + +#define BltBitMapRastPortAlpha(srcBitMap, srcX, srcY, destRP, destX, destY, sizeX, sizeY, taglist) \ + LP9(0xf0, ULONG, BltBitMapRastPortAlpha, struct BitMap *, srcBitMap, a0, LONG, srcX, d0, LONG, srcY, d1, struct RastPort *, destRP, a1, LONG, destX, d2, LONG, destY, d3, LONG, sizeX, d4, LONG, sizeY, d5, struct TagItem *, taglist, a2, \ + , CYBERGRAPHICS_BASE_NAME) + +#define ScalePixelArrayAlpha(srcRect, srcW, srcH, srcMod, rp, destX, destY, destW, destH, globalAlpha) \ + LP10(0x102, LONG, ScalePixelArrayAlpha, APTR, srcRect, a0, ULONG, srcW, d0, ULONG, srcH, d1, ULONG, srcMod, d2, struct RastPort *, rp, a1, ULONG, destX, d3, ULONG, destY, d4, ULONG, destW, d5, ULONG, destH, d6, ULONG, globalAlpha, d7, \ + , CYBERGRAPHICS_BASE_NAME) + +#endif /* _INLINE_CYBERGRAPHICS_H */ diff --git a/scalos/include/inline/dtlib.h b/scalos/include/inline/dtlib.h new file mode 100755 index 000000000..56e449bc0 --- /dev/null +++ b/scalos/include/inline/dtlib.h @@ -0,0 +1,27 @@ +#ifndef _INLINE_DTLIB_H +#define _INLINE_DTLIB_H + +#ifndef CLIB_DTLIB_PROTOS_H +#define CLIB_DTLIB_PROTOS_H +#endif + +#ifndef __INLINE_MACROS_H +#include +#endif + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef INTUITION_CLASSES_H +#include +#endif + +#ifndef DTLIB_BASE_NAME +#define DTLIB_BASE_NAME DtLibBase +#endif + +#define ObtainInfoEngine(libBase) \ + LP1(0x1e, Class *, ObtainInfoEngine, struct Library *, libBase, a0, \ + , DTLIB_BASE_NAME) + +#endif /* _INLINE_DTLIB_H */ diff --git a/scalos/include/inline/guigfx.h b/scalos/include/inline/guigfx.h new file mode 100755 index 000000000..23e884ef0 --- /dev/null +++ b/scalos/include/inline/guigfx.h @@ -0,0 +1,224 @@ +#ifndef _INLINE_GUIGFX_H +#define _INLINE_GUIGFX_H + +#ifndef CLIB_GUIGFX_PROTOS_H +#define CLIB_GUIGFX_PROTOS_H +#endif + +#ifndef __INLINE_MACROS_H +#include +#endif + +#ifndef EXEC_TYPES_H +#include +#endif + +#ifndef GUIGFX_BASE_NAME +#define GUIGFX_BASE_NAME GuiGFXBase +#endif + +#define MakePictureA(array, width, height, tags) \ + LP4(0x1e, APTR, MakePictureA, APTR, array, a0, ULONG, width, d0, ULONG, height, d1, struct TagItem *, tags, a1, \ + , GUIGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define MakePicture(array, width, height, tags...) \ + ({ULONG _tags[] = {tags}; MakePictureA((array), (width), (height), (struct TagItem *) _tags);}) +#endif + +#define LoadPictureA(filename, tags) \ + LP2(0x24, APTR, LoadPictureA, STRPTR, filename, a0, struct TagItem *, tags, a1, \ + , GUIGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define LoadPicture(filename, tags...) \ + ({ULONG _tags[] = {tags}; LoadPictureA((filename), (struct TagItem *) _tags);}) +#endif + +#define ReadPictureA(rp, colormap, x, y, width, height, tags) \ + LP7(0x2a, APTR, ReadPictureA, struct RastPort *, rp, a0, struct ColorMap *, colormap, a1, ULONG, x, d0, ULONG, y, d1, ULONG, width, d2, ULONG, height, d3, struct TagItem *, tags, a2, \ + , GUIGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define ReadPicture(rp, colormap, x, y, width, height, tags...) \ + ({ULONG _tags[] = {tags}; ReadPictureA((rp), (colormap), (x), (y), (width), (height), (struct TagItem *) _tags);}) +#endif + +#define ClonePictureA(pic, tags) \ + LP2(0x30, APTR, ClonePictureA, APTR, pic, a0, struct TagItem *, tags, a1, \ + , GUIGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define ClonePicture(pic, tags...) \ + ({ULONG _tags[] = {tags}; ClonePictureA((pic), (struct TagItem *) _tags);}) +#endif + +#define DeletePicture(pic) \ + LP1NR(0x36, DeletePicture, APTR, pic, a0, \ + , GUIGFX_BASE_NAME) + +#define AddPictureA(psm, pic, tags) \ + LP3(0x42, APTR, AddPictureA, APTR, psm, a0, APTR, pic, a1, struct TagItem *, tags, a2, \ + , GUIGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define AddPicture(psm, pic, tags...) \ + ({ULONG _tags[] = {tags}; AddPictureA((psm), (pic), (struct TagItem *) _tags);}) +#endif + +#define AddPaletteA(psm, palette, tags) \ + LP3(0x48, APTR, AddPaletteA, APTR, psm, a0, APTR, palette, a1, struct TagItem *, tags, a2, \ + , GUIGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define AddPalette(psm, palette, tags...) \ + ({ULONG _tags[] = {tags}; AddPaletteA((psm), (palette), (struct TagItem *) _tags);}) +#endif + +#define AddPixelArrayA(psm, array, width, height, tags) \ + LP5(0x4e, APTR, AddPixelArrayA, APTR, psm, a0, APTR, array, a1, ULONG, width, d0, ULONG, height, d1, struct TagItem *, tags, a2, \ + , GUIGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define AddPixelArray(psm, array, width, height, tags...) \ + ({ULONG _tags[] = {tags}; AddPixelArrayA((psm), (array), (width), (height), (struct TagItem *) _tags);}) +#endif + +#define RemColorHandle(colorhandle) \ + LP1NR(0x54, RemColorHandle, APTR, colorhandle, a0, \ + , GUIGFX_BASE_NAME) + +#define CreatePenShareMapA(tags) \ + LP1(0x5a, APTR, CreatePenShareMapA, struct TagItem *, tags, a0, \ + , GUIGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define CreatePenShareMap(tags...) \ + ({ULONG _tags[] = {tags}; CreatePenShareMapA((struct TagItem *) _tags);}) +#endif + +#define DeletePenShareMap(psm) \ + LP1NR(0x60, DeletePenShareMap, APTR, psm, a0, \ + , GUIGFX_BASE_NAME) + +#define ObtainDrawHandleA(psm, rp, cm, tags) \ + LP4(0x66, APTR, ObtainDrawHandleA, APTR, psm, a0, struct RastPort *, rp, a1, struct ColorMap *, cm, a2, struct TagItem *, tags, a3, \ + , GUIGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define ObtainDrawHandle(psm, rp, cm, tags...) \ + ({ULONG _tags[] = {tags}; ObtainDrawHandleA((psm), (rp), (cm), (struct TagItem *) _tags);}) +#endif + +#define ReleaseDrawHandle(drawhandle) \ + LP1NR(0x6c, ReleaseDrawHandle, APTR, drawhandle, a0, \ + , GUIGFX_BASE_NAME) + +#define DrawPictureA(drawhandle, pic, x, y, tags) \ + LP5(0x72, BOOL, DrawPictureA, APTR, drawhandle, a0, APTR, pic, a1, ULONG, x, d0, ULONG, y, d1, struct TagItem *, tags, a2, \ + , GUIGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define DrawPicture(drawhandle, pic, x, y, tags...) \ + ({ULONG _tags[] = {tags}; DrawPictureA((drawhandle), (pic), (x), (y), (struct TagItem *) _tags);}) +#endif + +#define MapPaletteA(drawhandle, palette, pentab, tags) \ + LP4(0x78, BOOL, MapPaletteA, APTR, drawhandle, a0, APTR, palette, a1, UBYTE *, pentab, a2, struct TagItem *, tags, a3, \ + , GUIGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define MapPalette(drawhandle, palette, pentab, tags...) \ + ({ULONG _tags[] = {tags}; MapPaletteA((drawhandle), (palette), (pentab), (struct TagItem *) _tags);}) +#endif + +#define MapPenA(drawhandle, rgb, tags) \ + LP3(0x7e, LONG, MapPenA, APTR, drawhandle, a0, ULONG, rgb, a1, struct TagItem *, tags, a2, \ + , GUIGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define MapPen(drawhandle, rgb, tags...) \ + ({ULONG _tags[] = {tags}; MapPenA((drawhandle), (rgb), (struct TagItem *) _tags);}) +#endif + +#define CreatePictureBitMapA(drawhandle, pic, tags) \ + LP3(0x84, struct BitMap *, CreatePictureBitMapA, APTR, drawhandle, a0, APTR, pic, a1, struct TagItem *, tags, a2, \ + , GUIGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define CreatePictureBitMap(drawhandle, pic, tags...) \ + ({ULONG _tags[] = {tags}; CreatePictureBitMapA((drawhandle), (pic), (struct TagItem *) _tags);}) +#endif + +#define DoPictureMethodA(pic, method, arguments) \ + LP3(0x8a, ULONG, DoPictureMethodA, APTR, pic, a0, ULONG, method, d0, ULONG *, arguments, a1, \ + , GUIGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define DoPictureMethod(pic, method, tags...) \ + ({ULONG _tags[] = {tags}; DoPictureMethodA((pic), (method), (ULONG *) _tags);}) +#endif + +#define GetPictureAttrsA(pic, tags) \ + LP2(0x90, ULONG, GetPictureAttrsA, APTR, pic, a0, struct TagItem *, tags, a1, \ + , GUIGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define GetPictureAttrs(pic, tags...) \ + ({ULONG _tags[] = {tags}; GetPictureAttrsA((pic), (struct TagItem *) _tags);}) +#endif + +#define LockPictureA(pic, mode, args) \ + LP3(0x96, ULONG, LockPictureA, APTR, pic, a0, ULONG, mode, d0, ULONG *, args, a1, \ + , GUIGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define LockPicture(pic, mode, tags...) \ + ({ULONG _tags[] = {tags}; LockPictureA((pic), (mode), (ULONG *) _tags);}) +#endif + +#define UnLockPicture(pic, mode) \ + LP2NR(0x9c, UnLockPicture, APTR, pic, a0, ULONG, mode, d0, \ + , GUIGFX_BASE_NAME) + +#define IsPictureA(filename, tags) \ + LP2(0xa2, BOOL, IsPictureA, STRPTR, filename, a0, struct TagItem *, tags, a1, \ + , GUIGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define IsPicture(filename, tags...) \ + ({ULONG _tags[] = {tags}; IsPictureA((filename), (struct TagItem *) _tags);}) +#endif + +#define CreateDirectDrawHandleA(drawhandle, sw, sh, dw, dh, tags) \ + LP6(0xa8, APTR, CreateDirectDrawHandleA, APTR, drawhandle, a0, ULONG, sw, d0, ULONG, sh, d1, ULONG, dw, d2, ULONG, dh, d3, struct TagItem *, tags, a1, \ + , GUIGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define CreateDirectDrawHandle(drawhandle, sw, sh, dw, dh, tags...) \ + ({ULONG _tags[] = {tags}; CreateDirectDrawHandleA((drawhandle), (sw), (sh), (dw), (dh), (struct TagItem *) _tags);}) +#endif + +#define DeleteDirectDrawHandle(ddh) \ + LP1NR(0xae, DeleteDirectDrawHandle, APTR, ddh, a0, \ + , GUIGFX_BASE_NAME) + +#define DirectDrawTrueColorA(ddh, array, x, y, tags) \ + LP5(0xb4, BOOL, DirectDrawTrueColorA, APTR, ddh, a0, ULONG *, array, a1, ULONG, x, d0, ULONG, y, d1, struct TagItem *, tags, a2, \ + , GUIGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define DirectDrawTrueColor(ddh, array, x, y, tags...) \ + ({ULONG _tags[] = {tags}; DirectDrawTrueColorA((ddh), (array), (x), (y), (struct TagItem *) _tags);}) +#endif + +#define CreatePictureMaskA(pic, mask, maskwidth, tags) \ + LP4(0xba, BOOL, CreatePictureMaskA, APTR, pic, a0, UBYTE *, mask, a1, ULONG, maskwidth, d0, struct TagItem *, tags, a2, \ + , GUIGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define CreatePictureMask(pic, mask, maskwidth, tags...) \ + ({ULONG _tags[] = {tags}; CreatePictureMaskA((pic), (mask), (maskwidth), (struct TagItem *) _tags);}) +#endif + +#endif /* _INLINE_GUIGFX_H */ diff --git a/scalos/include/inline/iconobject.h b/scalos/include/inline/iconobject.h new file mode 100644 index 000000000..1715e8132 --- /dev/null +++ b/scalos/include/inline/iconobject.h @@ -0,0 +1,71 @@ +#ifndef _INLINE_ICONOBJECT_H +#define _INLINE_ICONOBJECT_H + +#ifndef CLIB_ICONOBJECT_PROTOS_H +#define CLIB_ICONOBJECT_PROTOS_H +#endif + +#ifndef __INLINE_MACROS_H +#include +#endif + +#ifndef INTUITION_CLASSUSR_H +#include +#endif +#ifndef WORKBENCH_WORKBENCH_H +#include +#endif + +#ifndef ICONOBJECT_BASE_NAME +#define ICONOBJECT_BASE_NAME IconobjectBase +#endif + +#define NewIconObject(name, tagList) \ + LP2(0x1e, Object *, NewIconObject, CONST_STRPTR, name, a0, CONST struct TagItem *, tagList, a1, \ + , ICONOBJECT_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define NewIconObjectTags(name, tags...) \ + ({ULONG _tags[] = {tags}; NewIconObject((name), (CONST struct TagItem *) _tags);}) +#endif + +#define DisposeIconObject(iconObject) \ + LP1NR(0x24, DisposeIconObject, Object *, iconObject, a0, \ + , ICONOBJECT_BASE_NAME) + +#define GetDefIconObject(iconType, tagList) \ + LP2(0x2a, Object *, GetDefIconObject, ULONG, iconType, d0, CONST struct TagItem *, tagList, a0, \ + , ICONOBJECT_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define GetDefIconObjectTags(iconType, tags...) \ + ({ULONG _tags[] = {tags}; GetDefIconObject((iconType), (CONST struct TagItem *) _tags);}) +#endif + +#define PutIconObject(iconObject, path, tagList) \ + LP3NR(0x30, PutIconObject, Object *, iconObject, a0, CONST_STRPTR, path, a1, CONST struct TagItem *, tagList, a2, \ + , ICONOBJECT_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define PutIconObjectTags(iconObject, path, tags...) \ + ({ULONG _tags[] = {tags}; PutIconObject((iconObject), (path), (CONST struct TagItem *) _tags);}) +#endif + +#define IsIconName(fileName) \ + LP1(0x36, ULONG, IsIconName, CONST_STRPTR, fileName, a0, \ + , ICONOBJECT_BASE_NAME) + +#define Convert2IconObject(diskObject) \ + LP1(0x3c, Object *, Convert2IconObject, struct DiskObject *, diskObject, a0, \ + , ICONOBJECT_BASE_NAME) + +#define Convert2IconObjectA(diskObject, tagList) \ + LP2(0x42, Object *, Convert2IconObjectA, struct DiskObject *, diskObject, a0, CONST struct TagItem *, tagList, a1, \ + , ICONOBJECT_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define Convert2IconObjectTags(diskObject, tags...) \ + ({ULONG _tags[] = {tags}; Convert2IconObjectA((diskObject), (CONST struct TagItem *) _tags);}) +#endif + +#endif /* _INLINE_ICONOBJECT_H */ diff --git a/scalos/include/inline/mcpgfx.h b/scalos/include/inline/mcpgfx.h new file mode 100755 index 000000000..cc696f36d --- /dev/null +++ b/scalos/include/inline/mcpgfx.h @@ -0,0 +1,71 @@ +#ifndef _INLINE_MCPGFX_H +#define _INLINE_MCPGFX_H + +#ifndef CLIB_MCPGFX_PROTOS_H +#define CLIB_MCPGFX_PROTOS_H +#endif + +#ifndef __INLINE_MACROS_H +#include +#endif + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef LIBRARIES_MCPGFX_H +#include +#endif +#ifndef GRAPHICS_RASTPORT_H +#include +#endif +#ifndef INTUITION_SCREENS_H +#include +#endif +#ifndef UTILITY_TAGITEM_H +#include +#endif + +#ifndef MCPGFX_BASE_NAME +#define MCPGFX_BASE_NAME MCPGfxBase +#endif + +#define mcpPaintSysIGad(sysImageObject, drawInfo, gadgetNumber, width, height) \ + LP5NR(0x1e, mcpPaintSysIGad, APTR, sysImageObject, a0, struct DrawInfo *, drawInfo, a1, LONG, gadgetNumber, d0, LONG, width, d1, LONG, height, d2, \ + , MCPGFX_BASE_NAME) + +#define mcpRectFillA(rp, x1, y1, x2, y2, tagList) \ + LP6NR(0x24, mcpRectFillA, struct RastPort *, rp, a0, LONG, x1, d0, LONG, y1, d1, LONG, x2, d2, LONG, y2, d3, CONST struct TagItem *, tagList, a1, \ + , MCPGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define mcpRectFill(rp, x1, y1, x2, y2, tags...) \ + ({ULONG _tags[] = {tags}; mcpRectFillA((rp), (x1), (y1), (x2), (y2), (CONST struct TagItem *) _tags);}) +#endif + +#define mcpDrawFrameA(rp, x1, y1, x2, y2, tagList) \ + LP6NR(0x2a, mcpDrawFrameA, struct RastPort *, rp, a0, LONG, x1, d0, LONG, y1, d1, LONG, x2, d2, LONG, y2, d3, struct TagItem *, tagList, a1, \ + , MCPGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define mcpDrawFrame(rp, x1, y1, x2, y2, tags...) \ + ({ULONG _tags[] = {tags}; mcpDrawFrameA((rp), (x1), (y1), (x2), (y2), (struct TagItem *) _tags);}) +#endif + +#define mcpGetExtDrawInfo(screen, drawInfo) \ + LP2(0x30, struct ExtDrawInfo *, mcpGetExtDrawInfo, struct Screen *, screen, a0, struct DrawInfo *, drawInfo, a1, \ + , MCPGFX_BASE_NAME) + +#define mcpGetFrameSize(drawInfo, frameType) \ + LP2(0x36, struct FrameSize *, mcpGetFrameSize, struct DrawInfo *, drawInfo, a0, LONG, frameType, d0, \ + , MCPGFX_BASE_NAME) + +#define mcpSetGFXAttrsA(tagList) \ + LP1NR(0x3c, mcpSetGFXAttrsA, struct TagItem *, tagList, a0, \ + , MCPGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define mcpSetGFXAttrs(tags...) \ + ({ULONG _tags[] = {tags}; mcpSetGFXAttrsA((struct TagItem *) _tags);}) +#endif + +#endif /* _INLINE_MCPGFX_H */ diff --git a/scalos/include/inline/newicon.h b/scalos/include/inline/newicon.h new file mode 100644 index 000000000..b74121f98 --- /dev/null +++ b/scalos/include/inline/newicon.h @@ -0,0 +1,59 @@ +#ifndef _INLINE_NEWICON_H +#define _INLINE_NEWICON_H + +#ifndef CLIB_NEWICON_PROTOS_H +#define CLIB_NEWICON_PROTOS_H +#endif + +#ifndef __INLINE_MACROS_H +#include +#endif + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef LIBRARIES_NEWICON_H +#include +#endif + +#ifndef NEWICON_BASE_NAME +#define NEWICON_BASE_NAME NewIconBase +#endif + +#define GetNewDiskObject(name) \ + LP1(0x1e, struct NewDiskObject *, GetNewDiskObject, UBYTE *, name, a0, \ + , NEWICON_BASE_NAME) + +#define PutNewDiskObject(name, newdiskobj) \ + LP2(0x24, BOOL, PutNewDiskObject, UBYTE *, name, a0, struct NewDiskObject *, newdiskobj, a1, \ + , NEWICON_BASE_NAME) + +#define FreeNewDiskObject(newdiskobj) \ + LP1NR(0x2a, FreeNewDiskObject, struct NewDiskObject *, newdiskobj, a0, \ + , NEWICON_BASE_NAME) + +#define newiconPrivate1(diskobj) \ + LP1(0x30, BOOL, newiconPrivate1, struct NewDiskObject *, diskobj, a0, \ + , NEWICON_BASE_NAME) + +#define newiconPrivate2(diskobj) \ + LP1(0x36, UBYTE **, newiconPrivate2, struct NewDiskObject *, diskobj, a0, \ + , NEWICON_BASE_NAME) + +#define newiconPrivate3(diskobj) \ + LP1NR(0x3c, newiconPrivate3, struct NewDiskObject *, diskobj, a0, \ + , NEWICON_BASE_NAME) + +#define RemapChunkyImage(chunkyimage, screen) \ + LP2(0x42, struct Image *, RemapChunkyImage, struct ChunkyImage *, chunkyimage, a0, struct Screen *, screen, a1, \ + , NEWICON_BASE_NAME) + +#define FreeRemappedImage(image, screen) \ + LP2NR(0x48, FreeRemappedImage, struct Image *, image, a0, struct Screen *, screen, a1, \ + , NEWICON_BASE_NAME) + +#define GetDefNewDiskObject(def_type) \ + LP1(0x4e, struct NewDiskObject *, GetDefNewDiskObject, LONG, def_type, d0, \ + , NEWICON_BASE_NAME) + +#endif /* _INLINE_NEWICON_H */ diff --git a/scalos/include/inline/openurl.h b/scalos/include/inline/openurl.h new file mode 100644 index 000000000..806283507 --- /dev/null +++ b/scalos/include/inline/openurl.h @@ -0,0 +1,89 @@ +#ifndef _INLINE_OPENURL_H +#define _INLINE_OPENURL_H + +#ifndef CLIB_OPENURL_PROTOS_H +#define CLIB_OPENURL_PROTOS_H +#endif + +#ifndef __INLINE_MACROS_H +#include +#endif + +#ifndef EXEC_TYPES_H +#include +#endif + +#ifndef OPENURL_BASE_NAME +#define OPENURL_BASE_NAME OpenURLBase +#endif + +#define URL_OpenA(url, tags) \ + LP2(0x1e, ULONG, URL_OpenA, STRPTR, url, a0, struct TagItem *, tags, a1, \ + , OPENURL_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define URL_Open(url, tags...) \ + ({ULONG _tags[] = {tags}; URL_OpenA((url), (struct TagItem *) _tags);}) +#endif + +#define URL_OldGetPrefs() \ + LP0(0x24, struct URL_Prefs *, URL_OldGetPrefs, \ + , OPENURL_BASE_NAME) + +#define URL_OldFreePrefs(up) \ + LP1NR(0x2a, URL_OldFreePrefs, struct URL_Prefs *, up, a0, \ + , OPENURL_BASE_NAME) + +#define URL_OldSetPrefs(up, permanent) \ + LP2(0x30, ULONG, URL_OldSetPrefs, struct URL_Prefs *, up, a0, LONG, permanent, d0, \ + , OPENURL_BASE_NAME) + +#define URL_OldGetDefaultPrefs() \ + LP0(0x36, struct URL_Prefs *, URL_OldGetDefaultPrefs, \ + , OPENURL_BASE_NAME) + +#define URL_OldLaunchPrefsApp() \ + LP0(0x3c, ULONG, URL_OldLaunchPrefsApp, \ + , OPENURL_BASE_NAME) + +#define URL_GetPrefsA(tags) \ + LP1(0x48, struct URL_Prefs *, URL_GetPrefsA, struct TagItem *, tags, a0, \ + , OPENURL_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define URL_GetPrefs(tags...) \ + ({ULONG _tags[] = {tags}; URL_GetPrefsA((struct TagItem *) _tags);}) +#endif + +#define URL_FreePrefsA(prefs, tags) \ + LP2NR(0x4e, URL_FreePrefsA, struct URL_Prefs *, prefs, a0, struct TagItem *, tags, a1, \ + , OPENURL_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define URL_FreePrefs(prefs, tags...) \ + ({ULONG _tags[] = {tags}; URL_FreePrefsA((prefs), (struct TagItem *) _tags);}) +#endif + +#define URL_SetPrefsA(up, tags) \ + LP2(0x54, ULONG, URL_SetPrefsA, struct URL_Prefs *, up, a0, struct TagItem *, tags, a1, \ + , OPENURL_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define URL_SetPrefs(up, tags...) \ + ({ULONG _tags[] = {tags}; URL_SetPrefsA((up), (struct TagItem *) _tags);}) +#endif + +#define URL_LaunchPrefsAppA(tags) \ + LP1(0x5a, ULONG, URL_LaunchPrefsAppA, struct TagItem *, tags, a0, \ + , OPENURL_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define URL_LaunchPrefsApp(tags...) \ + ({ULONG _tags[] = {tags}; URL_LaunchPrefsAppA((struct TagItem *) _tags);}) +#endif + +#define URL_GetAttr(attr, storage) \ + LP2(0x60, ULONG, URL_GetAttr, ULONG, attr, d0, ULONG *, storage, a0, \ + , OPENURL_BASE_NAME) + +#endif /* _INLINE_OPENURL_H */ diff --git a/scalos/include/inline/pm.h b/scalos/include/inline/pm.h new file mode 100755 index 000000000..03c083cad --- /dev/null +++ b/scalos/include/inline/pm.h @@ -0,0 +1,146 @@ +#ifndef _INLINE_PM_H +#define _INLINE_PM_H + +#ifndef CLIB_PM_PROTOS_H +#define CLIB_PM_PROTOS_H +#endif + +#ifndef __INLINE_MACROS_H +#include +#endif + +#ifndef LIBRARIES_PM_H +#include +#endif + +#ifndef PM_BASE_NAME +#define PM_BASE_NAME PopupMenuBase +#endif + +#define PM_MakeMenuA(tags) \ + LP1(0x1e, struct PopupMenu *, PM_MakeMenuA, struct TagItem *, tags, a1, \ + , PM_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define PM_MakeMenu(tags...) \ + ({ULONG _tags[] = {tags}; PM_MakeMenuA((struct TagItem *) _tags);}) +#endif + +#define PM_MakeItemA(tags) \ + LP1(0x24, struct PopupMenu *, PM_MakeItemA, struct TagItem *, tags, a1, \ + , PM_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define PM_MakeItem(tags...) \ + ({ULONG _tags[] = {tags}; PM_MakeItemA((struct TagItem *) _tags);}) +#endif + +#define PM_FreePopupMenu(menu) \ + LP1NR(0x2a, PM_FreePopupMenu, struct PopupMenu *, menu, a1, \ + , PM_BASE_NAME) + +#define PM_OpenPopupMenuA(wnd, tags) \ + LP2(0x30, ULONG, PM_OpenPopupMenuA, struct Window *, wnd, a1, struct TagItem *, tags, a2, \ + , PM_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define PM_OpenPopupMenu(wnd, tags...) \ + ({ULONG _tags[] = {tags}; PM_OpenPopupMenuA((wnd), (struct TagItem *) _tags);}) +#endif + +#define PM_MakeIDListA(tags) \ + LP1(0x36, struct PM_IDLst *, PM_MakeIDListA, struct TagItem *, tags, a1, \ + , PM_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define PM_MakeIDList(tags...) \ + ({ULONG _tags[] = {tags}; PM_MakeIDListA((struct TagItem *) _tags);}) +#endif + +#define PM_ItemChecked(pm, id) \ + LP2(0x3c, BOOL, PM_ItemChecked, struct PopupMenu *, pm, a1, ULONG, id, d1, \ + , PM_BASE_NAME) + +#define PM_GetItemAttrsA(item, tags) \ + LP2(0x42, LONG, PM_GetItemAttrsA, struct PopupMenu *, item, a2, struct TagItem *, tags, a1, \ + , PM_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define PM_GetItemAttrs(item, tags...) \ + ({ULONG _tags[] = {tags}; PM_GetItemAttrsA((item), (struct TagItem *) _tags);}) +#endif + +#define PM_SetItemAttrsA(item, tags) \ + LP2(0x48, LONG, PM_SetItemAttrsA, struct PopupMenu *, item, a2, struct TagItem *, tags, a1, \ + , PM_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define PM_SetItemAttrs(item, tags...) \ + ({ULONG _tags[] = {tags}; PM_SetItemAttrsA((item), (struct TagItem *) _tags);}) +#endif + +#define PM_FindItem(menu, id) \ + LP2(0x4e, struct PopupMenu *, PM_FindItem, struct PopupMenu *, menu, a1, ULONG, id, d1, \ + , PM_BASE_NAME) + +#define PM_AlterState(menu, idlst, action) \ + LP3NR(0x54, PM_AlterState, struct PopupMenu *, menu, a1, struct PM_IDLst *, idlst, a2, ULONG, action, d1, \ + , PM_BASE_NAME) + +#define PM_ExLstA(id) \ + LP1(0x60, struct PM_IDLst *, PM_ExLstA, ULONG *, id, a1, \ + , PM_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define PM_ExLst(tags...) \ + ({ULONG _tags[] = {tags}; PM_ExLstA((ULONG *) _tags);}) +#endif + +#define PM_FilterIMsgA(window, menu, imsg, tags) \ + LP4(0x66, APTR, PM_FilterIMsgA, struct Window *, window, a0, struct PopupMenu *, menu, a1, struct IntuiMessage *, imsg, a2, struct TagItem *, tags, a3, \ + , PM_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define PM_FilterIMsg(window, menu, imsg, tags...) \ + ({ULONG _tags[] = {tags}; PM_FilterIMsgA((window), (menu), (imsg), (struct TagItem *) _tags);}) +#endif + +#define PM_InsertMenuItemA(menu, tags) \ + LP2(0x6c, LONG, PM_InsertMenuItemA, struct PopupMenu *, menu, a0, struct TagItem *, tags, a1, \ + , PM_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define PM_InsertMenuItem(menu, tags...) \ + ({ULONG _tags[] = {tags}; PM_InsertMenuItemA((menu), (struct TagItem *) _tags);}) +#endif + +#define PM_RemoveMenuItem(menu, item) \ + LP2(0x72, struct PopupMenu *, PM_RemoveMenuItem, struct PopupMenu *, menu, a0, struct PopupMenu *, item, a1, \ + , PM_BASE_NAME) + +#define PM_AbortHook(handle) \ + LP1(0x78, BOOL, PM_AbortHook, APTR, handle, a0, \ + , PM_BASE_NAME) + +#define PM_GetVersion() \ + LP0(0x7e, STRPTR, PM_GetVersion, \ + , PM_BASE_NAME) + +#define PM_ReloadPrefs() \ + LP0NR(0x84, PM_ReloadPrefs, \ + , PM_BASE_NAME) + +#define PM_LayoutMenuA(window, menu, tags) \ + LP3(0x8a, LONG, PM_LayoutMenuA, struct Window *, window, a0, struct PopupMenu *, menu, a1, struct TagItem *, tags, a2, \ + , PM_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define PM_LayoutMenu(window, menu, tags...) \ + ({ULONG _tags[] = {tags}; PM_LayoutMenuA((window), (menu), (struct TagItem *) _tags);}) +#endif + +#define PM_FreeIDList(list) \ + LP1NR(0x96, PM_FreeIDList, struct PM_IDLst *, list, a0, \ + , PM_BASE_NAME) + +#endif /* _INLINE_PM_H */ diff --git a/scalos/include/inline/preferences.h b/scalos/include/inline/preferences.h new file mode 100755 index 000000000..a9809d82a --- /dev/null +++ b/scalos/include/inline/preferences.h @@ -0,0 +1,63 @@ +#ifndef _INLINE_PREFERENCES_H +#define _INLINE_PREFERENCES_H + +#ifndef CLIB_PREFERENCES_PROTOS_H +#define CLIB_PREFERENCES_PROTOS_H +#endif + +#ifndef __INLINE_MACROS_H +#include +#endif + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef SCALOS_PREFERENCES_H +#include +#endif + +#ifndef PREFERENCES_BASE_NAME +#define PREFERENCES_BASE_NAME PreferencesBase +#endif + +#define AllocPrefsHandle(name) \ + LP1(0x1e, APTR, AllocPrefsHandle, CONST_STRPTR, name, a0, \ + , PREFERENCES_BASE_NAME) + +#define FreePrefsHandle(prefsHandle) \ + LP1NR(0x24, FreePrefsHandle, APTR, prefsHandle, a0, \ + , PREFERENCES_BASE_NAME) + +#define SetPreferences(prefsHandle, iD, prefsTag, a1arg, struct_Size) \ + LP5NR(0x2a, SetPreferences, APTR, prefsHandle, a0, ULONG, iD, d0, ULONG, prefsTag, d1, CONST APTR, a1arg, a1, ULONG, struct_Size, d2, \ + , PREFERENCES_BASE_NAME) + +#define GetPreferences(prefsHandle, iD, prefsTag, a1arg, struct_Size) \ + LP5(0x30, ULONG, GetPreferences, APTR, prefsHandle, a0, ULONG, iD, d0, ULONG, prefsTag, d1, APTR, a1arg, a1, ULONG, struct_Size, d2, \ + , PREFERENCES_BASE_NAME) + +#define ReadPrefsHandle(prefsHandle, filename) \ + LP2NR(0x36, ReadPrefsHandle, APTR, prefsHandle, a0, CONST_STRPTR, filename, a1, \ + , PREFERENCES_BASE_NAME) + +#define WritePrefsHandle(prefsHandle, filename) \ + LP2NR(0x3c, WritePrefsHandle, APTR, prefsHandle, a0, CONST_STRPTR, filename, a1, \ + , PREFERENCES_BASE_NAME) + +#define FindPreferences(prefsHandle, iD, prefsTag) \ + LP3(0x42, struct PrefsStruct *, FindPreferences, APTR, prefsHandle, a0, ULONG, iD, d0, ULONG, prefsTag, d1, \ + , PREFERENCES_BASE_NAME) + +#define SetEntry(prefsHandle, iD, prefsTag, a1arg, struct_Size, entry) \ + LP6NR(0x48, SetEntry, APTR, prefsHandle, a0, ULONG, iD, d0, ULONG, prefsTag, d1, CONST APTR, a1arg, a1, ULONG, struct_Size, d2, ULONG, entry, d3, \ + , PREFERENCES_BASE_NAME) + +#define GetEntry(prefsHandle, iD, prefsTag, a1arg, struct_Size, entry) \ + LP6(0x4e, ULONG, GetEntry, APTR, prefsHandle, a0, ULONG, iD, d0, ULONG, prefsTag, d1, APTR, a1arg, a1, ULONG, struct_Size, d2, ULONG, entry, d3, \ + , PREFERENCES_BASE_NAME) + +#define RemEntry(prefsHandle, iD, prefsTag, entry) \ + LP4(0x54, ULONG, RemEntry, APTR, prefsHandle, a0, ULONG, iD, d0, ULONG, prefsTag, d1, ULONG, entry, d2, \ + , PREFERENCES_BASE_NAME) + +#endif /* _INLINE_PREFERENCES_H */ diff --git a/scalos/include/inline/scalos.h b/scalos/include/inline/scalos.h new file mode 100644 index 000000000..9355b4a81 --- /dev/null +++ b/scalos/include/inline/scalos.h @@ -0,0 +1,224 @@ +#ifndef _INLINE_SCALOS_H +#define _INLINE_SCALOS_H + +#ifndef CLIB_SCALOS_PROTOS_H +#define CLIB_SCALOS_PROTOS_H +#endif + +#ifndef __INLINE_MACROS_H +#include +#endif + +#ifndef INTUITION_CLASSUSR_H +#include +#endif +#ifndef WORKBENCH_STARTUP_H +#include +#endif +#ifndef SCALOS_SCALOS_H +#include +#endif + +#ifndef SCALOS_BASE_NAME +#define SCALOS_BASE_NAME ScalosBase +#endif + +#define SCA_WBStart(argArray, tagList, numArgs) \ + LP3(0x1e, BOOL, SCA_WBStart, APTR, argArray, a0, CONST struct TagItem *, tagList, a1, ULONG, numArgs, d0, \ + , SCALOS_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define SCA_WBStartTags(argArray, numArgs, tags...) \ + ({ULONG _tags[] = {tags}; SCA_WBStart((argArray), (struct TagItem *) _tags, (numArgs));}) +#endif + +#define SCA_SortNodes(nodelist, sortHook, sortType) \ + LP3NR(0x24, SCA_SortNodes, struct ScalosNodeList *, nodelist, a0, struct Hook *, sortHook, a1, ULONG, sortType, d0, \ + , SCALOS_BASE_NAME) + +#define SCA_NewAddAppIcon(iD, userData, iconObj, msgPort, tagList) \ + LP5(0x2a, struct AppObject *, SCA_NewAddAppIcon, ULONG, iD, d0, ULONG, userData, d1, Object *, iconObj, a0, struct MsgPort *, msgPort, a1, CONST struct TagItem *, tagList, a2, \ + , SCALOS_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define SCA_NewAddAppIconTags(iD, userData, iconObj, msgPort, tags...) \ + ({ULONG _tags[] = {tags}; SCA_NewAddAppIcon((iD), (userData), (iconObj), (msgPort), (CONST struct TagItem *) _tags);}) +#endif + +#define SCA_RemoveAppObject(appObj) \ + LP1(0x30, BOOL, SCA_RemoveAppObject, struct AppObject *, appObj, a0, \ + , SCALOS_BASE_NAME) + +#define SCA_NewAddAppWindow(iD, userData, win, msgPort, tagList) \ + LP5(0x36, struct AppObject *, SCA_NewAddAppWindow, ULONG, iD, d0, ULONG, userData, d1, struct Window *, win, a0, struct MsgPort *, msgPort, a1, CONST struct TagItem *, tagList, a2, \ + , SCALOS_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define SCA_NewAddAppWindowTags(iD, userData, win, msgPort, tags...) \ + ({ULONG _tags[] = {tags}; SCA_NewAddAppWindow((iD), (userData), (win), (msgPort), (CONST struct TagItem *) _tags);}) +#endif + +#define SCA_NewAddAppMenuItem(iD, userData, text, msgPort, tagList) \ + LP5(0x3c, struct AppObject *, SCA_NewAddAppMenuItem, ULONG, iD, d0, ULONG, userData, d1, CONST_STRPTR, text, a0, struct MsgPort *, msgPort, a1, CONST struct TagItem *, tagList, a2, \ + , SCALOS_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define SCA_NewAddAppMenuItemTags(iD, userData, text, msgPort, tags...) \ + ({ULONG _tags[] = {tags}; SCA_NewAddAppMenuItem((iD), (userData), (text), (msgPort), (CONST struct TagItem *) _tags);}) +#endif + +#define SCA_AllocStdNode(nodeList, nodeType) \ + LP2(0x42, struct MinNode *, SCA_AllocStdNode, struct ScalosNodeList *, nodeList, a0, ULONG, nodeType, d0, \ + , SCALOS_BASE_NAME) + +#define SCA_AllocNode(nodeList, size) \ + LP2(0x48, struct MinNode *, SCA_AllocNode, struct ScalosNodeList *, nodeList, a0, ULONG, size, d0, \ + , SCALOS_BASE_NAME) + +#define SCA_FreeNode(nodeList, minNode) \ + LP2NR(0x4e, SCA_FreeNode, struct ScalosNodeList *, nodeList, a0, struct MinNode *, minNode, a1, \ + , SCALOS_BASE_NAME) + +#define SCA_FreeAllNodes(nodeList) \ + LP1NR(0x54, SCA_FreeAllNodes, struct ScalosNodeList *, nodeList, a0, \ + , SCALOS_BASE_NAME) + +#define SCA_MoveNode(srcNodeList, destNodeList, minNode) \ + LP3NR(0x5a, SCA_MoveNode, struct ScalosNodeList *, srcNodeList, a0, struct ScalosNodeList *, destNodeList, a1, struct MinNode *, minNode, d0, \ + , SCALOS_BASE_NAME) + +#define SCA_SwapNodes(minNode1, minNode2, nodeList) \ + LP3NR(0x60, SCA_SwapNodes, struct MinNode *, minNode1, a0, struct MinNode *, minNode2, a1, struct ScalosNodeList *, nodeList, a2, \ + , SCALOS_BASE_NAME) + +#define SCA_OpenIconWindow(tagList) \ + LP1(0x66, BOOL, SCA_OpenIconWindow, CONST struct TagItem *, tagList, a0, \ + , SCALOS_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define SCA_OpenIconWindowTags(tags...) \ + ({ULONG _tags[] = {tags}; SCA_OpenIconWindow((CONST struct TagItem *) _tags);}) +#endif + +#define SCA_LockWindowList(accessmode) \ + LP1(0x6c, struct ScaWindowList *, SCA_LockWindowList, LONG, accessmode, d0, \ + , SCALOS_BASE_NAME) + +#define SCA_UnLockWindowList() \ + LP0NR(0x72, SCA_UnLockWindowList, \ + , SCALOS_BASE_NAME) + +#define SCA_AllocMessage(messagetype, additional_size) \ + LP2(0x78, struct ScalosMessage *, SCA_AllocMessage, ULONG, messagetype, d0, ULONG, additional_size, d1, \ + , SCALOS_BASE_NAME) + +#define SCA_FreeMessage(message) \ + LP1NR(0x7e, SCA_FreeMessage, struct ScalosMessage *, message, a1, \ + , SCALOS_BASE_NAME) + +#define SCA_InitDrag(screen) \ + LP1(0x84, struct DragHandle *, SCA_InitDrag, struct Screen *, screen, a0, \ + , SCALOS_BASE_NAME) + +#define SCA_EndDrag(dragHandle) \ + LP1NR(0x8a, SCA_EndDrag, struct DragHandle *, dragHandle, a0, \ + , SCALOS_BASE_NAME) + +#define SCA_AddBob(dragHandle, bm, mask, width, height, xOffset, yOffset) \ + LP7(0x90, BOOL, SCA_AddBob, struct DragHandle *, dragHandle, a0, struct BitMap *, bm, a1, APTR, mask, a2, ULONG, width, d0, ULONG, height, d1, LONG, xOffset, d2, LONG, yOffset, d3, \ + , SCALOS_BASE_NAME) + +#define SCA_DrawDrag(dragHandle, x, y, flags) \ + LP4NR(0x96, SCA_DrawDrag, struct DragHandle *, dragHandle, a0, LONG, x, d0, LONG, y, d1, ULONG, flags, d2, \ + , SCALOS_BASE_NAME) + +#define SCA_UpdateIcon(windowType, updateIconStruct, ui_SIZE) \ + LP3NR(0x9c, SCA_UpdateIcon, ULONG, windowType, d0, APTR, updateIconStruct, a0, ULONG, ui_SIZE, d1, \ + , SCALOS_BASE_NAME) + +#define SCA_MakeWBArgs(buffer, in, argsSize) \ + LP3(0xa2, ULONG, SCA_MakeWBArgs, struct WBArg *, buffer, a0, struct ScaIconNode *, in, a1, ULONG, argsSize, d0, \ + , SCALOS_BASE_NAME) + +#define SCA_FreeWBArgs(buffer, number, flags) \ + LP3NR(0xa8, SCA_FreeWBArgs, struct WBArg *, buffer, a0, ULONG, number, d0, ULONG, flags, d1, \ + , SCALOS_BASE_NAME) + +#define SCA_ScreenTitleMsg(format, args) \ + LP2NR(0xb4, SCA_ScreenTitleMsg, CONST_STRPTR, format, a0, APTR, args, a1, \ + , SCALOS_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define SCA_ScreenTitleMsgArgs(format, tags...) \ + ({ULONG _tags[] = {tags}; SCA_ScreenTitleMsg((format), (APTR) _tags);}) +#endif + +#define SCA_MakeScalosClass(className, superClassName, instSize, dispFunc) \ + LP4(0xba, struct ScalosClass *, SCA_MakeScalosClass, CONST_STRPTR, className, a0, CONST_STRPTR, superClassName, a1, ULONG, instSize, d0, APTR, dispFunc, a2, \ + , SCALOS_BASE_NAME) + +#define SCA_FreeScalosClass(scalosClass) \ + LP1(0xc0, BOOL, SCA_FreeScalosClass, struct ScalosClass *, scalosClass, a0, \ + , SCALOS_BASE_NAME) + +#define SCA_NewScalosObject(className, tagList) \ + LP2(0xc6, Object *, SCA_NewScalosObject, CONST_STRPTR, className, a0, CONST struct TagItem *, tagList, a1, \ + , SCALOS_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define SCA_NewScalosObjectTags(className, tags...) \ + ({ULONG _tags[] = {tags}; SCA_NewScalosObject((className), (CONST struct TagItem *) _tags);}) +#endif + +#define SCA_DisposeScalosObject(obj) \ + LP1NR(0xcc, SCA_DisposeScalosObject, Object *, obj, a0, \ + , SCALOS_BASE_NAME) + +#define SCA_ScalosControlA(name, tagList) \ + LP2(0xd2, ULONG, SCA_ScalosControlA, CONST_STRPTR, name, a0, CONST struct TagItem *, tagList, a1, \ + , SCALOS_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define SCA_ScalosControl(name, tags...) \ + ({ULONG _tags[] = {tags}; SCA_ScalosControlA((name), (CONST struct TagItem *) _tags);}) +#endif + +#ifndef NO_INLINE_STDARG +#define SCA_ScalosControlTags SCA_ScalosControl +#endif + +#define SCA_GetDefIconObject(dirLock, name) \ + LP2(0xd8, Object *, SCA_GetDefIconObject, BPTR, dirLock, a0, CONST_STRPTR, name, a1, \ + , SCALOS_BASE_NAME) + +#define SCA_OpenDrawerByName(path, tagList) \ + LP2(0xde, struct ScaWindowStruct *, SCA_OpenDrawerByName, CONST_STRPTR, path, a0, struct TagItem *, tagList, a1, \ + , SCALOS_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define SCA_OpenDrawerByNameTags(path, tags...) \ + ({ULONG _tags[] = {tags}; SCA_OpenDrawerByName((path), (struct TagItem *) _tags);}) +#endif + +#define SCA_CountWBArgs(in) \ + LP1(0xe4, ULONG, SCA_CountWBArgs, struct ScaIconNode *, in, a0, \ + , SCALOS_BASE_NAME) + +#define SCA_GetDefIconObjectA(dirLock, name, tagList) \ + LP3(0xea, Object *, SCA_GetDefIconObjectA, BPTR, dirLock, a0, CONST_STRPTR, name, a1, struct TagItem *, tagList, a2, \ + , SCALOS_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define SCA_GetDefIconObjectTags(dirLock, name, tags...) \ + ({ULONG _tags[] = {tags}; SCA_GetDefIconObjectA((dirLock), (name), (struct TagItem *) _tags);}) +#endif + +#define SCA_LockDrag(dragHandle) \ + LP1(0xf0, ULONG, SCA_LockDrag, struct DragHandle *, dragHandle, a0, \ + , SCALOS_BASE_NAME) + +#define SCA_UnlockDrag(dragHandle) \ + LP1(0xf6, ULONG, SCA_UnlockDrag, struct DragHandle *, dragHandle, a0, \ + , SCALOS_BASE_NAME) + +#endif /* _INLINE_SCALOS_H */ diff --git a/scalos/include/inline/scalosfiletypeplugin.h b/scalos/include/inline/scalosfiletypeplugin.h new file mode 100755 index 000000000..efb0f10f7 --- /dev/null +++ b/scalos/include/inline/scalosfiletypeplugin.h @@ -0,0 +1,29 @@ +#ifndef _INLINE_SCALOSFILETYPEPLUGIN_H +#define _INLINE_SCALOSFILETYPEPLUGIN_H + +#ifndef CLIB_SCALOSFILETYPEPLUGIN_PROTOS_H +#define CLIB_SCALOSFILETYPEPLUGIN_PROTOS_H +#endif + +#ifndef __INLINE_MACROS_H +#include +#endif + +#ifndef SCALOS_SCALOS_H +#include +#endif + +#ifndef SCALOSFILETYPEPLUGIN_BASE_NAME +#define SCALOSFILETYPEPLUGIN_BASE_NAME ScalosFileTypePluginBase +#endif + +#define SCAToolTipInfoString(ttshd, args) \ + LP2(0x1e, STRPTR, SCAToolTipInfoString, struct ScaToolTipInfoHookData *, ttshd, a0, CONST_STRPTR, args, a1, \ + , SCALOSFILETYPEPLUGIN_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define SCAToolTipInfoStringArgs(ttshd, tags...) \ + ({ULONG _tags[] = {tags}; SCAToolTipInfoString((ttshd), (CONST_STRPTR) _tags);}) +#endif + +#endif /* _INLINE_SCALOSFILETYPEPLUGIN_H */ diff --git a/scalos/include/inline/scalosgfx.h b/scalos/include/inline/scalosgfx.h new file mode 100755 index 000000000..e7da64d68 --- /dev/null +++ b/scalos/include/inline/scalosgfx.h @@ -0,0 +1,176 @@ +#ifndef _INLINE_SCALOSGFX_H +#define _INLINE_SCALOSGFX_H + +#ifndef CLIB_SCALOSGFX_PROTOS_H +#define CLIB_SCALOSGFX_PROTOS_H +#endif + +#ifndef __INLINE_MACROS_H +#include +#endif + +#ifndef INTUITION_CLASSUSR_H +#include +#endif +#ifndef SCALOS_SCALOS_H +#include +#endif +#ifndef GRAPHICS_GFX_H +#include +#endif +#ifndef SCALOS_SCALOSGFX_H +#include +#endif + +#ifndef SCALOSGFX_BASE_NAME +#define SCALOSGFX_BASE_NAME ScalosGfxBase +#endif + +#define ScalosGfxCreateEmptySAC() \ + LP0(0x1e, struct ScalosBitMapAndColor *, ScalosGfxCreateEmptySAC, \ + , SCALOSGFX_BASE_NAME) + +#define ScalosGfxCreateSAC(width, height, depth, friendBM, tagList) \ + LP5(0x24, struct ScalosBitMapAndColor *, ScalosGfxCreateSAC, ULONG, width, d0, ULONG, height, d1, ULONG, depth, d2, struct BitMap *, friendBM, a0, struct TagItem *, tagList, a1, \ + , SCALOSGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define ScalosGfxCreateSACTags(width, height, depth, friendBM, tags...) \ + ({ULONG _tags[] = {tags}; ScalosGfxCreateSAC((width), (height), (depth), (friendBM), (struct TagItem *) _tags);}) +#endif + +#define ScalosGfxFreeSAC(sac) \ + LP1NR(0x2a, ScalosGfxFreeSAC, struct ScalosBitMapAndColor *, sac, a0, \ + , SCALOSGFX_BASE_NAME) + +#define ScalosGfxCreateARGB(width, height, tagList) \ + LP3(0x30, struct gfxARGB *, ScalosGfxCreateARGB, ULONG, width, d0, ULONG, height, d1, struct TagItem *, tagList, a0, \ + , SCALOSGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define ScalosGfxCreateARGBTags(width, height, tags...) \ + ({ULONG _tags[] = {tags}; ScalosGfxCreateARGB((width), (height), (struct TagItem *) _tags);}) +#endif + +#define ScalosGfxFreeARGB(argb) \ + LP1NR(0x36, ScalosGfxFreeARGB, struct gfxARGB **, argb, a0, \ + , SCALOSGFX_BASE_NAME) + +#define ScalosGfxARGBSetAlpha(src, alpha) \ + LP2NR(0x3c, ScalosGfxARGBSetAlpha, struct ARGBHeader *, src, a0, ULONG, alpha, d0, \ + , SCALOSGFX_BASE_NAME) + +#define ScalosGfxARGBSetAlphaMask(argbh, maskPlane) \ + LP2NR(0x42, ScalosGfxARGBSetAlphaMask, struct ARGBHeader *, argbh, a0, PLANEPTR, maskPlane, a1, \ + , SCALOSGFX_BASE_NAME) + +#define ScalosGfxCreateARGBFromBitMap(bm, width, height, numberOfColors, colorTable, maskPlane) \ + LP6(0x48, struct gfxARGB *, ScalosGfxCreateARGBFromBitMap, struct BitMap *, bm, a0, ULONG, width, d0, ULONG, height, d1, ULONG, numberOfColors, d2, const ULONG *, colorTable, a1, PLANEPTR, maskPlane, a2, \ + , SCALOSGFX_BASE_NAME) + +#define ScalosGfxFillARGBFromBitMap(argbh, srcBM, maskPlane) \ + LP3NR(0x4e, ScalosGfxFillARGBFromBitMap, struct ARGBHeader *, argbh, a0, struct BitMap *, srcBM, a1, PLANEPTR, maskPlane, a2, \ + , SCALOSGFX_BASE_NAME) + +#define ScalosGfxWriteARGBToBitMap(argbh, bm, numberOfColors, colorTable) \ + LP4NR(0x54, ScalosGfxWriteARGBToBitMap, struct ARGBHeader *, argbh, a0, struct BitMap *, bm, a1, ULONG, numberOfColors, d0, const ULONG *, colorTable, a2, \ + , SCALOSGFX_BASE_NAME) + +#define ScalosGfxMedianCut(argbh, depth, tagList) \ + LP3(0x5a, struct ScalosBitMapAndColor *, ScalosGfxMedianCut, struct ARGBHeader *, argbh, a0, ULONG, depth, d0, struct TagItem *, tagList, a1, \ + , SCALOSGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define ScalosGfxMedianCutTags(argbh, depth, tags...) \ + ({ULONG _tags[] = {tags}; ScalosGfxMedianCut((argbh), (depth), (struct TagItem *) _tags);}) +#endif + +#define ScalosGfxScaleARGBArray(src, destWidth, destHeight, tagList) \ + LP4(0x60, struct gfxARGB *, ScalosGfxScaleARGBArray, const struct ARGBHeader *, src, a0, ULONG *, destWidth, a1, ULONG *, destHeight, a2, struct TagItem *, tagList, a3, \ + , SCALOSGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define ScalosGfxScaleARGBArrayTags(src, destWidth, destHeight, tags...) \ + ({ULONG _tags[] = {tags}; ScalosGfxScaleARGBArray((src), (destWidth), (destHeight), (struct TagItem *) _tags);}) +#endif + +#define ScalosGfxScaleBitMap(sbma, tagList) \ + LP2(0x66, struct BitMap *, ScalosGfxScaleBitMap, struct ScaleBitMapArg *, sbma, a0, struct TagItem *, tagList, a1, \ + , SCALOSGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define ScalosGfxScaleBitMapTags(sbma, tags...) \ + ({ULONG _tags[] = {tags}; ScalosGfxScaleBitMap((sbma), (struct TagItem *) _tags);}) +#endif + +#define ScalosGfxCalculateScaleAspect(sourceWidth, sourceHeight, destWidth, destHeight) \ + LP4NR(0x6c, ScalosGfxCalculateScaleAspect, ULONG, sourceWidth, d0, ULONG, sourceHeight, d1, ULONG *, destWidth, a0, ULONG *, destHeight, a1, \ + , SCALOSGFX_BASE_NAME) + +#define ScalosGfxBlitARGB(destARGB, srcARGB, destLeft, destTop, srcLeft, srcTop, width, height) \ + LP8NR(0x72, ScalosGfxBlitARGB, struct ARGBHeader *, destARGB, a0, const struct ARGBHeader *, srcARGB, a1, LONG, destLeft, d0, LONG, destTop, d1, LONG, srcLeft, d2, LONG, srcTop, d3, LONG, width, d4, LONG, height, d5, \ + , SCALOSGFX_BASE_NAME) + +#define ScalosGfxFillRectARGB(destARGB, fillARGB, left, top, width, height) \ + LP6NR(0x78, ScalosGfxFillRectARGB, struct ARGBHeader *, destARGB, a0, const struct gfxARGB *, fillARGB, a1, LONG, left, d0, LONG, top, d1, LONG, width, d2, LONG, height, d3, \ + , SCALOSGFX_BASE_NAME) + +#define ScalosGfxSetARGB(destARGB, fillARGB) \ + LP2NR(0x7e, ScalosGfxSetARGB, struct ARGBHeader *, destARGB, a0, const struct gfxARGB *, fillARGB, a1, \ + , SCALOSGFX_BASE_NAME) + +#define ScalosGfxNewColorMap(sac, colorMap, colorEntries) \ + LP3(0x84, BOOL, ScalosGfxNewColorMap, struct ScalosBitMapAndColor *, sac, a0, const ULONG *, colorMap, a1, ULONG, colorEntries, d0, \ + , SCALOSGFX_BASE_NAME) + +#define ScalosGfxARGBRectMult(rp, numerator, denominator, xMin, yMin, xMax, yMax) \ + LP7NR(0x8a, ScalosGfxARGBRectMult, struct RastPort *, rp, a0, const struct gfxARGB *, numerator, a1, const struct gfxARGB *, denominator, a2, LONG, xMin, d0, LONG, yMin, d1, LONG, xMax, d2, LONG, yMax, d3, \ + , SCALOSGFX_BASE_NAME) + +#define ScalosGfxBlitARGBAlpha(rp, srcH, destLeft, destTop, srcLeft, srcTop, width, height) \ + LP8NR(0x90, ScalosGfxBlitARGBAlpha, struct RastPort *, rp, a0, const struct ARGBHeader *, srcH, a1, ULONG, destLeft, d0, ULONG, destTop, d1, ULONG, srcLeft, d2, ULONG, srcTop, d3, ULONG, width, d4, ULONG, height, d5, \ + , SCALOSGFX_BASE_NAME) + +#define ScalosGfxBlitARGBAlphaTagList(rp, srcH, destLeft, destTop, srcSize, tagList) \ + LP6NR(0x96, ScalosGfxBlitARGBAlphaTagList, struct RastPort *, rp, a0, const struct ARGBHeader *, srcH, a1, ULONG, destLeft, d0, ULONG, destTop, d1, const struct IBox *, srcSize, a3, struct TagItem *, tagList, a2, \ + , SCALOSGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define ScalosGfxBlitARGBAlphaTags(rp, srcH, destLeft, destTop, srcSize, tags...) \ + ({ULONG _tags[] = {tags}; ScalosGfxBlitARGBAlphaTagList((rp), (srcH), (destLeft), (destTop), (srcSize), (struct TagItem *) _tags);}) +#endif + +#define ScalosGfxBlitIcon(rpBackground, rpIcon, left, top, width, height, tagList) \ + LP7NR(0x9c, ScalosGfxBlitIcon, struct RastPort *, rpBackground, a0, struct RastPort *, rpIcon, a1, ULONG, left, d0, ULONG, top, d1, ULONG, width, d2, ULONG, height, d3, struct TagItem *, tagList, a2, \ + , SCALOSGFX_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define ScalosGfxBlitIconTags(rpBackground, rpIcon, left, top, width, height, tags...) \ + ({ULONG _tags[] = {tags}; ScalosGfxBlitIcon((rpBackground), (rpIcon), (left), (top), (width), (height), (struct TagItem *) _tags);}) +#endif + +#define ScalosGfxDrawGradient(dest, left, top, width, height, start, stop, gradType) \ + LP8(0xa2, BOOL, ScalosGfxDrawGradient, struct ARGBHeader *, dest, a0, LONG, left, d0, LONG, top, d1, LONG, width, d2, LONG, height, d3, struct gfxARGB *, start, a1, struct gfxARGB *, stop, a2, ULONG, gradType, d4, \ + , SCALOSGFX_BASE_NAME) + +#define ScalosGfxDrawGradientRastPort(rp, left, top, width, height, start, stop, gradType) \ + LP8(0xa8, BOOL, ScalosGfxDrawGradientRastPort, struct RastPort *, rp, a0, LONG, left, d0, LONG, top, d1, LONG, width, d2, LONG, height, d3, struct gfxARGB *, start, a1, struct gfxARGB *, stop, a2, ULONG, gradType, d4, \ + , SCALOSGFX_BASE_NAME) + +#define ScalosGfxDrawLine(dest, fromX, fromY, toX, toY, lineColor) \ + LP6NR(0xae, ScalosGfxDrawLine, struct ARGBHeader *, dest, a0, LONG, fromX, d0, LONG, fromY, d1, LONG, toX, d2, LONG, toY, d3, const struct gfxARGB *, lineColor, a1, \ + , SCALOSGFX_BASE_NAME) + +#define ScalosGfxDrawLineRastPort(rp, fromX, fromY, toX, toY, lineColor) \ + LP6NR(0xb4, ScalosGfxDrawLineRastPort, struct RastPort *, rp, a0, LONG, fromX, d0, LONG, fromY, d1, LONG, toX, d2, LONG, toY, d3, const struct gfxARGB *, lineColor, a1, \ + , SCALOSGFX_BASE_NAME) + +#define ScalosGfxDrawEllipse(dest, xCenter, yCenter, radiusX, radiusy, segment, color1, color2) \ + LP8NR(0xba, ScalosGfxDrawEllipse, struct ARGBHeader *, dest, a0, LONG, xCenter, d0, LONG, yCenter, d1, LONG, radiusX, d2, LONG, radiusy, d3, LONG, segment, d4, const struct gfxARGB *, color1, a1, const struct gfxARGB *, color2, a2, \ + , SCALOSGFX_BASE_NAME) + +#define ScalosGfxDrawEllipseRastPort(rp, xCenter, yCenter, radiusX, radiusy, segment, color1, color2) \ + LP8NR(0xc0, ScalosGfxDrawEllipseRastPort, struct RastPort *, rp, a0, LONG, xCenter, d0, LONG, yCenter, d1, LONG, radiusX, d2, LONG, radiusy, d3, LONG, segment, d4, const struct gfxARGB *, color1, a1, const struct gfxARGB *, color2, a2, \ + , SCALOSGFX_BASE_NAME) + +#endif /* _INLINE_SCALOSGFX_H */ diff --git a/scalos/include/inline/scalosmenuplugin.h b/scalos/include/inline/scalosmenuplugin.h new file mode 100644 index 000000000..c5702807f --- /dev/null +++ b/scalos/include/inline/scalosmenuplugin.h @@ -0,0 +1,24 @@ +#ifndef _INLINE_SCALOSMENUPLUGIN_H +#define _INLINE_SCALOSMENUPLUGIN_H + +#ifndef CLIB_SCALOSMENUPLUGIN_PROTOS_H +#define CLIB_SCALOSMENUPLUGIN_PROTOS_H +#endif + +#ifndef __INLINE_MACROS_H +#include +#endif + +#ifndef SCALOS_SCALOS_H +#include +#endif + +#ifndef SCALOSMENUPLUGIN_BASE_NAME +#define SCALOSMENUPLUGIN_BASE_NAME ScalosMenuPluginBase +#endif + +#define SCAMenuFunction(wt, in) \ + LP2NR(0x1e, SCAMenuFunction, struct ScaWindowTask *, wt, a0, struct ScaIconNode *, in, a1, \ + , SCALOSMENUPLUGIN_BASE_NAME) + +#endif /* _INLINE_SCALOSMENUPLUGIN_H */ diff --git a/scalos/include/inline/scalosplugin.h b/scalos/include/inline/scalosplugin.h new file mode 100644 index 000000000..cf20fff30 --- /dev/null +++ b/scalos/include/inline/scalosplugin.h @@ -0,0 +1,22 @@ +#ifndef _INLINE_SCALOSPLUGIN_H +#define _INLINE_SCALOSPLUGIN_H + +#ifndef CLIB_SCALOSPLUGIN_PROTOS_H +#define CLIB_SCALOSPLUGIN_PROTOS_H +#endif + +#ifndef __INLINE_MACROS_H +#include +#endif + +#include + +#ifndef SCALOSPLUGIN_BASE_NAME +#define SCALOSPLUGIN_BASE_NAME ScalosPluginBase +#endif + +#define SCAGetClassInfo() \ + LP0(0x1e, const struct ScaClassInfo *, SCAGetClassInfo, \ + , SCALOSPLUGIN_BASE_NAME) + +#endif /* _INLINE_SCALOSPLUGIN_H */ diff --git a/scalos/include/inline/scalosprefsplugin.h b/scalos/include/inline/scalosprefsplugin.h new file mode 100755 index 000000000..a08c4c497 --- /dev/null +++ b/scalos/include/inline/scalosprefsplugin.h @@ -0,0 +1,22 @@ +#ifndef _INLINE_SCALOSPREFSPLUGIN_H +#define _INLINE_SCALOSPREFSPLUGIN_H + +#ifndef CLIB_SCALOSPREFSPLUGIN_PROTOS_H +#define CLIB_SCALOSPREFSPLUGIN_PROTOS_H +#endif + +#ifndef __INLINE_MACROS_H +#include +#endif + +#include + +#ifndef SCALOSPREFSPLUGIN_BASE_NAME +#define SCALOSPREFSPLUGIN_BASE_NAME ScalosPrefsPluginBase +#endif + +#define SCAGetPrefsInfo(which) \ + LP1(0x1e, ULONG, SCAGetPrefsInfo, LONG, which, d0, \ + , SCALOSPREFSPLUGIN_BASE_NAME) + +#endif /* _INLINE_SCALOSPREFSPLUGIN_H */ diff --git a/scalos/include/inline/scalospreviewplugin.h b/scalos/include/inline/scalospreviewplugin.h new file mode 100755 index 000000000..7780fb198 --- /dev/null +++ b/scalos/include/inline/scalospreviewplugin.h @@ -0,0 +1,32 @@ +#ifndef _INLINE_SCALOSPREVIEWPLUGIN_H +#define _INLINE_SCALOSPREVIEWPLUGIN_H + +#ifndef CLIB_SCALOSPREVIEWPLUGIN_PROTOS_H +#define CLIB_SCALOSPREVIEWPLUGIN_PROTOS_H +#endif + +#ifndef __INLINE_MACROS_H +#include +#endif + +#ifndef SCALOS_SCALOS_H +#include +#endif +#ifndef UTILITY_TAGITEM_H +#include +#endif + +#ifndef SCALOSPREVIEWPLUGIN_BASE_NAME +#define SCALOSPREVIEWPLUGIN_BASE_NAME ScalosPreviewPluginBase +#endif + +#define SCAPreviewGenerate(wt, dirLock, iconName, tagList) \ + LP4(0x1e, LONG, SCAPreviewGenerate, struct ScaWindowTask *, wt, a0, BPTR, dirLock, a1, CONST_STRPTR, iconName, a2, struct TagItem *, tagList, a3, \ + , SCALOSPREVIEWPLUGIN_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define SCAPreviewGenerateTags(wt, dirLock, iconName, tags...) \ + ({ULONG _tags[] = {tags}; SCAPreviewGenerate((wt), (dirLock), (iconName), (struct TagItem *) _tags);}) +#endif + +#endif /* _INLINE_SCALOSPREVIEWPLUGIN_H */ diff --git a/scalos/include/inline/sqlite3.h b/scalos/include/inline/sqlite3.h new file mode 100755 index 000000000..3c4787919 --- /dev/null +++ b/scalos/include/inline/sqlite3.h @@ -0,0 +1,425 @@ +#ifndef _INLINE_SQLITE3_H +#define _INLINE_SQLITE3_H + +#ifndef CLIB_SQLITE3_PROTOS_H +#define CLIB_SQLITE3_PROTOS_H +#endif + +#ifndef __INLINE_MACROS_H +#include +#endif + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef SQLITE3_H +#include +#endif + +#ifndef SQLITE3_BASE_NAME +#define SQLITE3_BASE_NAME SQLite3Base +#endif + +#define SQLite3Close(db) \ + LP1(0x1e, LONG, SQLite3Close, sqlite3 *, db, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3Exec(db, sql, xCallback, pArg, errmsg) \ + LP5(0x24, LONG, SQLite3Exec, sqlite3 *, db, a0, CONST_STRPTR, sql, a1, sqlite3_callback, xCallback, a2, APTR, pArg, a3, STRPTR *, errmsg, d0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3Changes(db) \ + LP1(0x2a, LONG, SQLite3Changes, sqlite3 *, db, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3TotalChanges(db) \ + LP1(0x30, LONG, SQLite3TotalChanges, sqlite3 *, db, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3Interrupt(db) \ + LP1NR(0x36, SQLite3Interrupt, sqlite3 *, db, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3Complete(sql) \ + LP1(0x3c, LONG, SQLite3Complete, CONST_STRPTR, sql, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3BusyHandler(db, callback, userdata) \ + LP3FP(0x42, LONG, SQLite3BusyHandler, sqlite3 *, db, a0, __fpt, callback, a1, APTR, userdata, a2, \ + , SQLITE3_BASE_NAME, LONG (*__fpt)(APTR userdata, LONG l)) + +#define SQLite3BusyTimeout(db, ms) \ + LP2(0x48, LONG, SQLite3BusyTimeout, sqlite3 *, db, a0, LONG, ms, d0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3GetTable(db, sql, presult, nrow, ncolumn, errmsg) \ + LP6(0x4e, LONG, SQLite3GetTable, sqlite3 *, db, a0, CONST_STRPTR, sql, a1, STRPTR **, presult, a2, LONG *, nrow, a3, LONG *, ncolumn, d0, STRPTR *, errmsg, d1, \ + , SQLITE3_BASE_NAME) + +#define SQLite3FreeTable(result) \ + LP1NR(0x54, SQLite3FreeTable, STRPTR *, result, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3Free(z) \ + LP1NR(0x5a, SQLite3Free, STRPTR, z, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3Trace(db, xTrace, parg) \ + LP3FP(0x60, APTR, SQLite3Trace, sqlite3 *, db, a0, __fpt, xTrace, a1, APTR, parg, a2, \ + , SQLITE3_BASE_NAME, VOID (*__fpt)(APTR p, CONST_STRPTR z)) + +#define SQLite3ProgressHandler(db, nOps, xProgress, pArg) \ + LP4NRFP(0x66, SQLite3ProgressHandler, sqlite3 *, db, a0, LONG, nOps, d0, __fpt, xProgress, a1, APTR, pArg, a2, \ + , SQLITE3_BASE_NAME, LONG (*__fpt)(APTR p)) + +#define SQLite3CommitHook(db, xCallback, pArg) \ + LP3FP(0x6c, APTR, SQLite3CommitHook, sqlite3 *, db, a0, __fpt, xCallback, a1, APTR, pArg, a2, \ + , SQLITE3_BASE_NAME, LONG (*__fpt)(APTR p)) + +#define SQLite3Open(filename, ppDb) \ + LP2(0x72, LONG, SQLite3Open, CONST_STRPTR, filename, a0, sqlite3 **, ppDb, a1, \ + , SQLITE3_BASE_NAME) + +#define SQLite3Errcode(db) \ + LP1(0x78, LONG, SQLite3Errcode, sqlite3 *, db, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3Errmsg(db) \ + LP1(0x7e, CONST_STRPTR, SQLite3Errmsg, sqlite3 *, db, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3Prepare(db, zSql, nBytes, ppStmt, pzTail) \ + LP5(0x84, LONG, SQLite3Prepare, sqlite3 *, db, a0, CONST_STRPTR, zSql, a1, LONG, nBytes, d0, sqlite3_stmt **, ppStmt, a2, CONST_STRPTR *, pzTail, a3, \ + , SQLITE3_BASE_NAME) + +#define SQLite3BindBlob(pStmt, i, zData, nData, xDel) \ + LP5FP(0x8a, LONG, SQLite3BindBlob, sqlite3_stmt *, pStmt, a0, LONG, i, d0, CONST_APTR, zData, a1, LONG, nData, d1, __fpt, xDel, a2, \ + , SQLITE3_BASE_NAME, VOID (*__fpt)(APTR p)) + +#define SQLite3BindInt(pStmt, i, iValue) \ + LP3(0x90, LONG, SQLite3BindInt, sqlite3_stmt *, pStmt, a0, LONG, i, d0, LONG, iValue, d1, \ + , SQLITE3_BASE_NAME) + +#define SQLite3BindNull(pStmt, i) \ + LP2(0x96, LONG, SQLite3BindNull, sqlite3_stmt *, pStmt, a0, LONG, i, d0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3BindText(pStmt, i, zData, nData, xDel) \ + LP5FP(0x9c, LONG, SQLite3BindText, sqlite3_stmt *, pStmt, a0, LONG, i, d0, CONST_STRPTR, zData, a1, LONG, nData, d1, __fpt, xDel, a2, \ + , SQLITE3_BASE_NAME, VOID (*__fpt)(APTR p)) + +#define SQLite3BindValue(pStmt, i, pVal) \ + LP3(0xa2, LONG, SQLite3BindValue, sqlite3_stmt *, pStmt, a0, LONG, i, d0, CONST sqlite3_value *, pVal, a1, \ + , SQLITE3_BASE_NAME) + +#define SQLite3BindParameterCount(pStmt) \ + LP1(0xa8, LONG, SQLite3BindParameterCount, sqlite3_stmt *, pStmt, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3BindParameterName(pStmt, i) \ + LP2(0xae, CONST_STRPTR, SQLite3BindParameterName, sqlite3_stmt *, pStmt, a0, LONG, i, d0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3BindParameterIndex(pStmt, zName) \ + LP2(0xb4, LONG, SQLite3BindParameterIndex, sqlite3_stmt *, pStmt, a0, CONST_STRPTR, zName, a1, \ + , SQLITE3_BASE_NAME) + +#define SQLite3ClearBindings(pStmt) \ + LP1(0xba, LONG, SQLite3ClearBindings, sqlite3_stmt *, pStmt, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3ColumnCount(pStmt) \ + LP1(0xc0, LONG, SQLite3ColumnCount, sqlite3_stmt *, pStmt, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3ColumnName(pStmt, i) \ + LP2(0xc6, CONST_STRPTR, SQLite3ColumnName, sqlite3_stmt *, pStmt, a0, LONG, i, d0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3ColumnDecltype(pStmt, i) \ + LP2(0xcc, CONST_STRPTR, SQLite3ColumnDecltype, sqlite3_stmt *, pStmt, a0, LONG, i, d0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3Step(pStmt) \ + LP1(0xd2, LONG, SQLite3Step, sqlite3_stmt *, pStmt, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3DataCount(pStmt) \ + LP1(0xd8, LONG, SQLite3DataCount, sqlite3_stmt *, pStmt, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3ColumnBlob(pStmt, iCol) \ + LP2(0xde, CONST_APTR, SQLite3ColumnBlob, sqlite3_stmt *, pStmt, a0, LONG, iCol, d0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3ColumnBytes(pStmt, iCol) \ + LP2(0xe4, LONG, SQLite3ColumnBytes, sqlite3_stmt *, pStmt, a0, LONG, iCol, d0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3ColumnInt(pStmt, iCol) \ + LP2(0xea, LONG, SQLite3ColumnInt, sqlite3_stmt *, pStmt, a0, LONG, iCol, d0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3ColumnText(pStmt, iCol) \ + LP2(0xf0, CONST_STRPTR, SQLite3ColumnText, sqlite3_stmt *, pStmt, a0, LONG, iCol, d0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3ColumnType(pStmt, iCol) \ + LP2(0xf6, LONG, SQLite3ColumnType, sqlite3_stmt *, pStmt, a0, LONG, iCol, d0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3Finalize(pStmt) \ + LP1(0xfc, LONG, SQLite3Finalize, sqlite3_stmt *, pStmt, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3Reset(pStmt) \ + LP1(0x102, LONG, SQLite3Reset, sqlite3_stmt *, pStmt, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3AggregateCount(pCtx) \ + LP1(0x108, LONG, SQLite3AggregateCount, sqlite3_context *, pCtx, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3ValueBlob(pVal) \ + LP1(0x10e, CONST_APTR, SQLite3ValueBlob, sqlite3_value *, pVal, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3ValueBytes(pVal) \ + LP1(0x114, LONG, SQLite3ValueBytes, sqlite3_value *, pVal, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3ValueInt(pVal) \ + LP1(0x11a, LONG, SQLite3ValueInt, sqlite3_value *, pVal, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3ValueText(pVal) \ + LP1(0x120, CONST_STRPTR, SQLite3ValueText, sqlite3_value *, pVal, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3ValueType(pVal) \ + LP1(0x126, LONG, SQLite3ValueType, sqlite3_value *, pVal, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3Aggregate_context(pCtx, nBytes) \ + LP2(0x12c, APTR, SQLite3Aggregate_context, sqlite3_context *, pCtx, a0, LONG, nBytes, d0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3UserData(pCtx) \ + LP1(0x132, APTR, SQLite3UserData, sqlite3_context *, pCtx, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3GetAuxdata(pCtx, iArg) \ + LP2(0x138, APTR, SQLite3GetAuxdata, sqlite3_context *, pCtx, a0, LONG, iArg, d0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3SetAuxdata(pCtx, iARg, pAux, xDelete) \ + LP4NRFP(0x13e, SQLite3SetAuxdata, sqlite3_context *, pCtx, a0, LONG, iARg, d0, APTR, pAux, a1, __fpt, xDelete, a2, \ + , SQLITE3_BASE_NAME, VOID (*__fpt)(APTR p)) + +#define SQLite3ResultBlob(pCtx, z, n, xDelete) \ + LP4NRFP(0x144, SQLite3ResultBlob, sqlite3_context *, pCtx, a0, CONST_APTR, z, a1, LONG, n, d0, __fpt, xDelete, a2, \ + , SQLITE3_BASE_NAME, VOID (*__fpt)(APTR p)) + +#define SQLite3ResultError(pCtx, z, n) \ + LP3NR(0x14a, SQLite3ResultError, sqlite3_context *, pCtx, a0, CONST_STRPTR, z, a1, LONG, n, d0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3ResultInt(pCtx, iVal) \ + LP2NR(0x150, SQLite3ResultInt, sqlite3_context *, pCtx, a0, LONG, iVal, d0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3ResultNull(pCtx) \ + LP1NR(0x156, SQLite3ResultNull, sqlite3_context *, pCtx, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3ResultText(pCtx, z, n, xDelete) \ + LP4NRFP(0x15c, SQLite3ResultText, sqlite3_context *, pCtx, a0, CONST_STRPTR, z, a1, LONG, n, d0, __fpt, xDelete, a2, \ + , SQLITE3_BASE_NAME, VOID (*__fpt)(APTR p)) + +#define SQLite3ResultValue(pCtx, pValue) \ + LP2NR(0x162, SQLite3ResultValue, sqlite3_context *, pCtx, a0, sqlite3_value *, pValue, a1, \ + , SQLITE3_BASE_NAME) + +#define SQLite3CreateCollation(db, zName, eTextRep, pCtx, xCompare) \ + LP5FP(0x168, LONG, SQLite3CreateCollation, sqlite3 *, db, a0, CONST_STRPTR, zName, a1, LONG, eTextRep, d0, APTR, pCtx, a2, __fpt, xCompare, a3, \ + , SQLITE3_BASE_NAME, LONG (*__fpt)(APTR p, LONG i, CONST_APTR p2, LONG j, CONST_APTR p3)) + +#define SQLite3CollationNeeded(db, pCollNeededArg, xCollNeeded) \ + LP3FP(0x16e, LONG, SQLite3CollationNeeded, sqlite3 *, db, a0, APTR, pCollNeededArg, d0, __fpt, xCollNeeded, a1, \ + , SQLITE3_BASE_NAME, VOID (*__fpt)(APTR p, sqlite3 *dv, LONG eTextRep, CONST_STRPTR z)) + +#define SQLite3Sleep(ms) \ + LP1(0x174, LONG, SQLite3Sleep, LONG, ms, d0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3Expired(pStmt) \ + LP1(0x17a, LONG, SQLite3Expired, sqlite3_stmt *, pStmt, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3TransferBindings(pFromStmt, pToStmt) \ + LP2(0x180, LONG, SQLite3TransferBindings, sqlite3_stmt *, pFromStmt, a0, sqlite3_stmt *, pToStmt, a1, \ + , SQLITE3_BASE_NAME) + +#define SQLite3GlobalRecover() \ + LP0(0x186, LONG, SQLite3GlobalRecover, \ + , SQLITE3_BASE_NAME) + +#define SQLite3GetAutocommit(db) \ + LP1(0x18c, LONG, SQLite3GetAutocommit, sqlite3 *, db, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3DbHandle(pStmt) \ + LP1(0x192, sqlite3 *, SQLite3DbHandle, sqlite3_stmt *, pStmt, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3RollbackHook(db, callback, pUserData) \ + LP3FP(0x198, APTR, SQLite3RollbackHook, sqlite3 *, db, a0, __fpt, callback, a1, APTR, pUserData, a2, \ + , SQLITE3_BASE_NAME, VOID (*__fpt)(APTR pUserData)) + +#define SQLite3EnableSharedCache(enable) \ + LP1(0x19e, LONG, SQLite3EnableSharedCache, LONG, enable, d0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3ReleaseMemory(bytesCount) \ + LP1(0x1a4, LONG, SQLite3ReleaseMemory, LONG, bytesCount, d0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3SoftHeapLimit(maxBytes) \ + LP1NR(0x1aa, SQLite3SoftHeapLimit, LONG, maxBytes, d0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3ThreadCleanup() \ + LP0NR(0x1b0, SQLite3ThreadCleanup, \ + , SQLITE3_BASE_NAME) + +#define SQLite3PrepareV2(db, zSql, nBytes, ppStmt, pzTail) \ + LP5(0x1b6, LONG, SQLite3PrepareV2, sqlite3 *, db, a0, CONST_STRPTR, zSql, a1, LONG, nBytes, d0, sqlite3_stmt **, ppStmt, a2, CONST_STRPTR *, pzTail, a3, \ + , SQLITE3_BASE_NAME) + +#define SQLite3CreateFunction(db, zFunctionName, nArg, eTextRep, userdata, xFunc, xStep, xFinal) \ + LP8FP(0x1bc, LONG, SQLite3CreateFunction, sqlite3 *, db, a0, CONST_STRPTR, zFunctionName, a1, LONG, nArg, d0, LONG, eTextRep, d1, APTR, userdata, a2, __fpt, xFunc, a3, void *, xStep, d2, void *, xFinal, d3, \ + , SQLITE3_BASE_NAME, VOID (*__fpt)(sqlite3_context *pCtx, LONG i, sqlite3_value **pVal)) + +#define SQLite3CreateModule(db, zName, methods, clientData) \ + LP4(0x1c2, LONG, SQLite3CreateModule, sqlite3 *, db, a0, CONST_STRPTR, zName, a1, CONST sqlite3_module *, methods, a2, APTR, clientData, a3, \ + , SQLITE3_BASE_NAME) + +#define SQLite3DeclareVtab(db, zCreateTable) \ + LP2(0x1c8, LONG, SQLite3DeclareVtab, sqlite3 *, db, a0, CONST_STRPTR, zCreateTable, a1, \ + , SQLITE3_BASE_NAME) + +#define SQLite3OverloadFunction(db, zFuncName, nArg) \ + LP3(0x1ce, LONG, SQLite3OverloadFunction, sqlite3 *, db, a0, CONST_STRPTR, zFuncName, a1, LONG, nArg, d0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3BlobOpen(db, zDb, zTable, zColumn, iRow, flags, ppBlob) \ + LP7A4(0x1d4, LONG, SQLite3BlobOpen, sqlite3 *, db, a0, CONST_STRPTR, zDb, a1, CONST_STRPTR, zTable, a2, CONST_STRPTR, zColumn, a3, LONG, iRow, d0, LONG, flags, d1, sqlite3_blob **, ppBlob, d7, \ + , SQLITE3_BASE_NAME) + +#define SQLite3BlobClose(blob) \ + LP1(0x1da, LONG, SQLite3BlobClose, sqlite3_blob *, blob, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3BlobBytes(blob) \ + LP1(0x1e0, LONG, SQLite3BlobBytes, sqlite3_blob *, blob, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3BlobRead(blob, z, n, iOffset) \ + LP4(0x1e6, LONG, SQLite3BlobRead, sqlite3_blob *, blob, a0, APTR, z, a1, LONG, n, d0, LONG, iOffset, d1, \ + , SQLITE3_BASE_NAME) + +#define SQLite3BlobWrite(blob, z, n, iOffset) \ + LP4(0x1ec, LONG, SQLite3BlobWrite, sqlite3_blob *, blob, a0, CONST_APTR, z, a1, LONG, n, d0, LONG, iOffset, d1, \ + , SQLITE3_BASE_NAME) + +#define SQLite3ExtendedResultCodes(db, onoff) \ + LP2(0x1f2, LONG, SQLite3ExtendedResultCodes, sqlite3 *, db, a0, LONG, onoff, d0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3BindZeroBlob(pStmt, i, n) \ + LP3(0x1f8, LONG, SQLite3BindZeroBlob, sqlite3_stmt *, pStmt, a0, LONG, i, d0, LONG, n, d1, \ + , SQLITE3_BASE_NAME) + +#define SQLite3ColumnDatabaseName(stmt, n) \ + LP2(0x1fe, CONST_STRPTR, SQLite3ColumnDatabaseName, sqlite3_stmt *, stmt, a0, LONG, n, d0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3ColumnTableName(stmt, n) \ + LP2(0x204, CONST_STRPTR, SQLite3ColumnTableName, sqlite3_stmt *, stmt, a0, LONG, n, d0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3ColumnOriginName(stmt, n) \ + LP2(0x20a, CONST_STRPTR, SQLite3ColumnOriginName, sqlite3_stmt *, stmt, a0, LONG, n, d0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3ColumnValue(pStmt, iCol) \ + LP2(0x210, sqlite3_value *, SQLite3ColumnValue, sqlite3_stmt *, pStmt, a0, LONG, iCol, d0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3CreateCollationV2(db, zName, eTextRep, pCtx, xCompare, xDestroy) \ + LP6FP(0x216, LONG, SQLite3CreateCollationV2, sqlite3 *, db, a0, CONST_STRPTR, zName, a1, LONG, eTextRep, d0, APTR, pCtx, a2, __fpt, xCompare, a3, void *, xDestroy, d1, \ + , SQLITE3_BASE_NAME, LONG (*__fpt)(APTR p, LONG i, CONST_APTR p2, LONG j, CONST_APTR p3)) + +#define SQLite3LibVersion() \ + LP0(0x21c, CONST_STRPTR, SQLite3LibVersion, \ + , SQLITE3_BASE_NAME) + +#define SQLite3LibversionNumber() \ + LP0(0x222, LONG, SQLite3LibversionNumber, \ + , SQLITE3_BASE_NAME) + +#define SQLite3ResultErrorToobig(pCtx) \ + LP1NR(0x228, SQLite3ResultErrorToobig, sqlite3_context *, pCtx, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3ResultZeroBlob(pCtx, n) \ + LP2NR(0x22e, SQLite3ResultZeroBlob, sqlite3_context *, pCtx, a0, LONG, n, d0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3ValueNumericType(pVal) \ + LP1(0x234, LONG, SQLite3ValueNumericType, sqlite3_value *, pVal, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3ConfigV(op, ap) \ + LP2(0x23a, LONG, SQLite3ConfigV, LONG, op, d0, APTR, ap, a0, \ + , SQLITE3_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define SQLite3Config(op, tags...) \ + ({ULONG _tags[] = {tags}; SQLite3ConfigV((op), (APTR) _tags);}) +#endif + +#define SQLlite3DbConfigV(db, op, ap) \ + LP3(0x240, LONG, SQLlite3DbConfigV, sqlite3 *, db, a0, LONG, op, d0, APTR, ap, a1, \ + , SQLITE3_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define SQLlite3DbConfig(db, op, tags...) \ + ({ULONG _tags[] = {tags}; SQLlite3DbConfigV((db), (op), (APTR) _tags);}) +#endif + +#define SQLite3VfsFind(zVfsName) \ + LP1(0x246, sqlite3_vfs *, SQLite3VfsFind, CONST_STRPTR, zVfsName, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3VfsRegister(vfs, makeDflt) \ + LP2(0x24c, LONG, SQLite3VfsRegister, sqlite3_vfs *, vfs, a0, LONG, makeDflt, d0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3VfsUnregister(vfs) \ + LP1(0x252, LONG, SQLite3VfsUnregister, sqlite3_vfs *, vfs, a0, \ + , SQLITE3_BASE_NAME) + +#define SQLite3FileControl(db, zDbName, op, arg) \ + LP4(0x258, LONG, SQLite3FileControl, sqlite3 *, db, a0, CONST_STRPTR, zDbName, a1, LONG, op, d0, void *, arg, a2, \ + , SQLITE3_BASE_NAME) + +#define SQLite3Status(op, pCurrent, pHighwater, resetFlag) \ + LP4(0x25e, LONG, SQLite3Status, LONG, op, d0, LONG *, pCurrent, a0, LONG *, pHighwater, a1, LONG, resetFlag, d1, \ + , SQLITE3_BASE_NAME) + +#define SQLite3DbStatus(db, op, pCur, pHiwtr, resetFlg) \ + LP5(0x264, LONG, SQLite3DbStatus, sqlite3 *, db, a0, LONG, op, d0, LONG *, pCur, a1, LONG *, pHiwtr, a2, LONG, resetFlg, d1, \ + , SQLITE3_BASE_NAME) + +#endif /* _INLINE_SQLITE3_H */ diff --git a/scalos/include/inline/ttengine.h b/scalos/include/inline/ttengine.h new file mode 100644 index 000000000..5d0378da9 --- /dev/null +++ b/scalos/include/inline/ttengine.h @@ -0,0 +1,127 @@ +#ifndef _INLINE_TTENGINE_H +#define _INLINE_TTENGINE_H + +#ifndef CLIB_TTENGINE_PROTOS_H +#define CLIB_TTENGINE_PROTOS_H +#endif + +#ifndef __INLINE_MACROS_H +#include +#endif + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef UTILITY_TAGITEM_H +#include +#endif +#ifndef LIBRARIES_TTENGINE_H +#include +#endif +#ifndef GRAPHICS_TEXT_H +#include +#endif + +#ifndef TTENGINE_BASE_NAME +#define TTENGINE_BASE_NAME TTEngineBase +#endif + +#define TT_OpenFontA(taglist) \ + LP1(0x1e, APTR, TT_OpenFontA, struct TagItem *, taglist, a0, \ + , TTENGINE_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define TT_OpenFont(tags...) \ + ({ULONG _tags[] = {tags}; TT_OpenFontA((struct TagItem *) _tags);}) +#endif + +#define TT_SetFont(rp, font) \ + LP2(0x24, BOOL, TT_SetFont, struct RastPort *, rp, a1, APTR, font, a0, \ + , TTENGINE_BASE_NAME) + +#define TT_CloseFont(font) \ + LP1NR(0x2a, TT_CloseFont, APTR, font, a0, \ + , TTENGINE_BASE_NAME) + +#define TT_Text(rp, string, count) \ + LP3NR(0x30, TT_Text, struct RastPort *, rp, a1, APTR, string, a0, ULONG, count, d0, \ + , TTENGINE_BASE_NAME) + +#define TT_SetAttrsA(rp, taglist) \ + LP2(0x36, ULONG, TT_SetAttrsA, struct RastPort *, rp, a1, struct TagItem *, taglist, a0, \ + , TTENGINE_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define TT_SetAttrs(rp, tags...) \ + ({ULONG _tags[] = {tags}; TT_SetAttrsA((rp), (struct TagItem *) _tags);}) +#endif + +#define TT_GetAttrsA(rp, taglist) \ + LP2(0x3c, ULONG, TT_GetAttrsA, struct RastPort *, rp, a1, struct TagItem *, taglist, a0, \ + , TTENGINE_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define TT_GetAttrs(rp, tags...) \ + ({ULONG _tags[] = {tags}; TT_GetAttrsA((rp), (struct TagItem *) _tags);}) +#endif + +#define TT_TextLength(rp, string, count) \ + LP3(0x42, ULONG, TT_TextLength, struct RastPort *, rp, a1, APTR, string, a0, ULONG, count, d0, \ + , TTENGINE_BASE_NAME) + +#define TT_TextExtent(rp, string, count, te) \ + LP4NR(0x48, TT_TextExtent, struct RastPort *, rp, a1, APTR, string, a0, LONG, count, d0, struct TextExtent *, te, a2, \ + , TTENGINE_BASE_NAME) + +#define TT_TextFit(rp, string, count, te, tec, dir, cwidth, cheight) \ + LP8(0x4e, ULONG, TT_TextFit, struct RastPort *, rp, a1, APTR, string, a0, ULONG, count, d0, struct TextExtent *, te, a2, struct TextExtent *, tec, a3, LONG, dir, d1, ULONG, cwidth, d2, ULONG, cheight, d3, \ + , TTENGINE_BASE_NAME) + +#define TT_GetPixmapA(font, string, count, taglist) \ + LP4(0x54, struct TT_Pixmap *, TT_GetPixmapA, APTR, font, a1, APTR, string, a2, ULONG, count, d0, struct TagItem *, taglist, a0, \ + , TTENGINE_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define TT_GetPixmap(font, string, count, tags...) \ + ({ULONG _tags[] = {tags}; TT_GetPixmapA((font), (string), (count), (struct TagItem *) _tags);}) +#endif + +#define TT_FreePixmap(pixmap) \ + LP1NR(0x5a, TT_FreePixmap, struct TT_Pixmap *, pixmap, a0, \ + , TTENGINE_BASE_NAME) + +#define TT_DoneRastPort(rp) \ + LP1NR(0x60, TT_DoneRastPort, struct RastPort *, rp, a1, \ + , TTENGINE_BASE_NAME) + +#define TT_AllocRequest() \ + LP0(0x66, APTR, TT_AllocRequest, \ + , TTENGINE_BASE_NAME) + +#define TT_RequestA(request, taglist) \ + LP2(0x6c, struct TagItem*, TT_RequestA, APTR, request, a0, struct TagItem *, taglist, a1, \ + , TTENGINE_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define TT_Request(request, tags...) \ + ({ULONG _tags[] = {tags}; TT_RequestA((request), (struct TagItem *) _tags);}) +#endif + +#define TT_FreeRequest(request) \ + LP1NR(0x72, TT_FreeRequest, APTR, request, a0, \ + , TTENGINE_BASE_NAME) + +#define TT_ObtainFamilyListA(taglist) \ + LP1(0x78, STRPTR *, TT_ObtainFamilyListA, struct TagItem *, taglist, a0, \ + , TTENGINE_BASE_NAME) + +#ifndef NO_INLINE_STDARG +#define TT_ObtainFamilyList(tags...) \ + ({ULONG _tags[] = {tags}; TT_ObtainFamilyListA((struct TagItem *) _tags);}) +#endif + +#define TT_FreeFamilyList(list) \ + LP1NR(0x7e, TT_FreeFamilyList, STRPTR *, list, a0, \ + , TTENGINE_BASE_NAME) + +#endif /* _INLINE_TTENGINE_H */ diff --git a/scalos/include/inline4/cybergraphics.h b/scalos/include/inline4/cybergraphics.h new file mode 100755 index 000000000..91245e90b --- /dev/null +++ b/scalos/include/inline4/cybergraphics.h @@ -0,0 +1,98 @@ +#ifndef INLINE4_CYBERGRAPHICS_H +#define INLINE4_CYBERGRAPHICS_H + +/* +** This file was auto generated by idltool 52.1. +** +** It provides compatibility to OS3 style library +** calls by substituting functions. +** +** Do not edit manually. +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif + +#ifndef UTILITY_TAGITEM_H +#include +#endif +#include + +/* Inline macros for Interface "main" */ +#define IsCyberModeID(displayID) ICyberGfx->IsCyberModeID((displayID)) +#define BestCModeIDTagList(bestModeIDTags) ICyberGfx->BestCModeIDTagList((bestModeIDTags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define BestCModeIDTags(...) ICyberGfx->BestCModeIDTags(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define BestCModeIDTags(...) ICyberGfx->BestCModeIDTags(## vargs) +#endif +#define CModeRequestTagList(modeRequest, modeRequestTags) ICyberGfx->CModeRequestTagList((modeRequest), (modeRequestTags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define CModeRequestTags(...) ICyberGfx->CModeRequestTags(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define CModeRequestTags(vargs...) ICyberGfx->CModeRequestTags(## vargs) +#endif +#define AllocCModeListTagList(modeListTags) ICyberGfx->AllocCModeListTagList((modeListTags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define AllocCModeListTags(...) ICyberGfx->AllocCModeListTags(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define AllocCModeListTags(...) ICyberGfx->AllocCModeListTags(## vargs) +#endif +#define FreeCModeList(modeList) ICyberGfx->FreeCModeList((modeList)) +#define ScalePixelArray(srcRect, srcW, srcH, srcMod, rp, destX, destY, destW, destH, srcFormat) ICyberGfx->ScalePixelArray((srcRect), (srcW), (srcH), (srcMod), (rp), (destX), (destY), (destW), (destH), (srcFormat)) +#define GetCyberMapAttr(cyberGfxBitmap, cyberAttrTag) ICyberGfx->GetCyberMapAttr((cyberGfxBitmap), (cyberAttrTag)) +#define GetCyberIDAttr(cyberIDAttr, cyberDisplayModeID) ICyberGfx->GetCyberIDAttr((cyberIDAttr), (cyberDisplayModeID)) +#define ReadRGBPixel(rp, x, y) ICyberGfx->ReadRGBPixel((rp), (x), (y)) +#define WriteRGBPixel(rp, x, y, argb) ICyberGfx->WriteRGBPixel((rp), (x), (y), (argb)) +#define ReadPixelArray(destRect, destX, destY, destMod, rp, srcX, srcY, sizeX, sizeY, destFormat) ICyberGfx->ReadPixelArray((destRect), (destX), (destY), (destMod), (rp), (srcX), (srcY), (sizeX), (sizeY), (destFormat)) +#define WritePixelArray(srcRect, srcX, srcY, srcMod, rp, destX, destY, sizeX, sizeY, srcFormat) ICyberGfx->WritePixelArray((srcRect), (srcX), (srcY), (srcMod), (rp), (destX), (destY), (sizeX), (sizeY), (srcFormat)) +#define MovePixelArray(srcX, srcY, rp, destX, destY, sizeX, sizeY) ICyberGfx->MovePixelArray((srcX), (srcY), (rp), (destX), (destY), (sizeX), (sizeY)) +#define InvertPixelArray(rp, destX, destY, sizeX, sizeY) ICyberGfx->InvertPixelArray((rp), (destX), (destY), (sizeX), (sizeY)) +#define FillPixelArray(rp, destX, destY, sizeX, sizeY, aRGB) ICyberGfx->FillPixelArray((rp), (destX), (destY), (sizeX), (sizeY), (aRGB)) +#define DoCDrawMethodTagList(hook, rp, tagList) ICyberGfx->DoCDrawMethodTagList((hook), (rp), (tagList)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define DoCDrawMethodTags(hook, ...) ICyberGfx->DoCDrawMethodTags((hook), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define DoCDrawMethodTags(hook, vargs...) ICyberGfx->DoCDrawMethodTags(hook, ## vargs) +#endif +#define CVideoCtrlTagList(viewPort, tagList) ICyberGfx->CVideoCtrlTagList((viewPort), (tagList)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define CVideoCtrlTags(...) ICyberGfx->CVideoCtrlTags(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define CVideoCtrlTags(vargs...) ICyberGfx->CVideoCtrlTags(## vargs) +#endif +#define LockBitMapTagList(bitMap, tagList) ICyberGfx->LockBitMapTagList((bitMap), (tagList)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define LockBitMapTags(...) ICyberGfx->LockBitMapTags(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define LockBitMapTags(vargs...) ICyberGfx->LockBitMapTags(## vargs) +#endif +#define UnLockBitMap(handle) ICyberGfx->UnLockBitMap((handle)) +#define UnLockBitMapTagList(handle, tagList) ICyberGfx->UnLockBitMapTagList((handle), (tagList)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define UnLockBitMapTags(...) ICyberGfx->UnLockBitMapTags(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define UnLockBitMapTags(vargs...) ICyberGfx->UnLockBitMapTags(## vargs) +#endif +#define ExtractColor(rp, bitMap, colour, srcX, srcY, width, height) ICyberGfx->ExtractColor((rp), (bitMap), (colour), (srcX), (srcY), (width), (height)) +#define WriteLUTPixelArray(srcRect, srcX, srcY, srcMod, rp, colorTab, destX, destY, sizeX, sizeY, cTFormat) ICyberGfx->WriteLUTPixelArray((srcRect), (srcX), (srcY), (srcMod), (rp), (colorTab), (destX), (destY), (sizeX), (sizeY), (cTFormat)) +#define WritePixelArrayAlpha(srcRect, srcX, srcY, srcMod, rp, destX, destY, sizeX, sizeY, globalAlpha) ICyberGfx->WritePixelArrayAlpha((srcRect), (srcX), (srcY), (srcMod), (rp), (destX), (destY), (sizeX), (sizeY), (globalAlpha)) +#define BltTemplateAlpha(source, xSrc, srcMod, destRP, xDest, yDest, xSize, ySize) ICyberGfx->BltTemplateAlpha((source), (xSrc), (srcMod), (destRP), (xDest), (yDest), (xSize), (ySize)) +#define ProcessPixelArray(rp, destX, destY, sizeX, sizeY, operation, value, taglist) ICyberGfx->ProcessPixelArray((rp), (destX), (destY), (sizeX), (sizeY), (operation), (value), (taglist)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define ProcessPixelArrayTags(rp, destX, destY, sizeX, sizeY, operation, ...) ICyberGfx->ProcessPixelArrayTags((rp), (destX), (destY), (sizeX), (sizeY), (operation), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define ProcessPixelArrayTags(rp, destX, destY, sizeX, sizeY, operation, vargs...) ICyberGfx->ProcessPixelArrayTags(rp, destX, destY, sizeX, sizeY, operation, ## vargs) +#endif +#define BltBitMapAlpha(srcBitMap, srcX, srcY, destBitMap, destX, destY, sizeX, sizeY, taglist) ICyberGfx->BltBitMapAlpha((srcBitMap), (srcX), (srcY), (destBitMap), (destX), (destY), (sizeX), (sizeY), (taglist)) +#define BltBitMapRastPortAlpha(srcBitMap, srcX, srcY, destRP, destX, destY, sizeX, sizeY, taglist) ICyberGfx->BltBitMapRastPortAlpha((srcBitMap), (srcX), (srcY), (destRP), (destX), (destY), (sizeX), (sizeY), (taglist)) +#define ScalePixelArrayAlpha(srcRect, srcW, srcH, srcMod, rp, destX, destY, destW, destH, globalAlpha) ICyberGfx->ScalePixelArrayAlpha((srcRect), (srcW), (srcH), (srcMod), (rp), (destX), (destY), (destW), (destH), (globalAlpha)) + +#endif /* INLINE4_CYBERGRAPHICS_H */ diff --git a/scalos/include/inline4/guigfx.h b/scalos/include/inline4/guigfx.h new file mode 100644 index 000000000..a1986c436 --- /dev/null +++ b/scalos/include/inline4/guigfx.h @@ -0,0 +1,153 @@ +#ifndef INLINE4_GUIGFX_H +#define INLINE4_GUIGFX_H + +/* +** This file was auto generated by idltool 52.7. +** +** It provides compatibility to OS3 style library +** calls by substituting functions. +** +** Do not edit manually. +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif + +#include + +/* Inline macros for Interface "main" */ +#define MakePictureA(array, width, height, tags) IGuiGFX->MakePictureA((array), (width), (height), (tags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define MakePicture(array, width, ...) IGuiGFX->MakePicture((array), (width), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define MakePicture(array, width, vargs...) IGuiGFX->MakePicture(array, width, ## vargs) +#endif +#define LoadPictureA(filename, tags) IGuiGFX->LoadPictureA((filename), (tags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define LoadPicture(...) IGuiGFX->LoadPicture(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define LoadPicture(vargs...) IGuiGFX->LoadPicture(## vargs) +#endif +#define ReadPictureA(rp, colormap, x, y, width, height, tags) IGuiGFX->ReadPictureA((rp), (colormap), (x), (y), (width), (height), (tags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define ReadPicture(rp, colormap, x, y, width, ...) IGuiGFX->ReadPicture((rp), (colormap), (x), (y), (width), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define ReadPicture(rp, colormap, x, y, width, vargs...) IGuiGFX->ReadPicture(rp, colormap, x, y, width, ## vargs) +#endif +#define ClonePictureA(pic, tags) IGuiGFX->ClonePictureA((pic), (tags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define ClonePicture(...) IGuiGFX->ClonePicture(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define ClonePicture(vargs...) IGuiGFX->ClonePicture(## vargs) +#endif +#define DeletePicture(pic) IGuiGFX->DeletePicture((pic)) +#define AddPictureA(psm, pic, tags) IGuiGFX->AddPictureA((psm), (pic), (tags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define AddPicture(psm, ...) IGuiGFX->AddPicture((psm), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define AddPicture(psm, vargs...) IGuiGFX->AddPicture(psm, ## vargs) +#endif +#define AddPaletteA(psm, palette, tags) IGuiGFX->AddPaletteA((psm), (palette), (tags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define AddPalette(psm, ...) IGuiGFX->AddPalette((psm), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define AddPalette(psm, vargs...) IGuiGFX->AddPalette(psm, ## vargs) +#endif +#define AddPixelArrayA(psm, array, width, height, tags) IGuiGFX->AddPixelArrayA((psm), (array), (width), (height), (tags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define AddPixelArray(psm, array, width, ...) IGuiGFX->AddPixelArray((psm), (array), (width), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define AddPixelArray(psm, array, width, vargs...) IGuiGFX->AddPixelArray(psm, array, width, ## vargs) +#endif +#define RemColorHandle(colorhandle) IGuiGFX->RemColorHandle((colorhandle)) +#define CreatePenShareMapA(tags) IGuiGFX->CreatePenShareMapA((tags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define CreatePenShareMap(...) IGuiGFX->CreatePenShareMap(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define CreatePenShareMap(...) IGuiGFX->CreatePenShareMap(## vargs) +#endif +#define DeletePenShareMap(psm) IGuiGFX->DeletePenShareMap((psm)) +#define ObtainDrawHandleA(psm, rp, cm, tags) IGuiGFX->ObtainDrawHandleA((psm), (rp), (cm), (tags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define ObtainDrawHandle(psm, rp, ...) IGuiGFX->ObtainDrawHandle((psm), (rp), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define ObtainDrawHandle(psm, rp, vargs...) IGuiGFX->ObtainDrawHandle(psm, rp, ## vargs) +#endif +#define ReleaseDrawHandle(drawhandle) IGuiGFX->ReleaseDrawHandle((drawhandle)) +#define DrawPictureA(drawhandle, pic, x, y, tags) IGuiGFX->DrawPictureA((drawhandle), (pic), (x), (y), (tags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define DrawPicture(drawhandle, pic, x, ...) IGuiGFX->DrawPicture((drawhandle), (pic), (x), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define DrawPicture(drawhandle, pic, x, vargs...) IGuiGFX->DrawPicture(drawhandle, pic, x, ## vargs) +#endif +#define MapPaletteA(drawhandle, palette, pentab, tags) IGuiGFX->MapPaletteA((drawhandle), (palette), (pentab), (tags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define MapPalette(drawhandle, palette, ...) IGuiGFX->MapPalette((drawhandle), (palette), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define MapPalette(drawhandle, palette, vargs...) IGuiGFX->MapPalette(drawhandle, palette, ## vargs) +#endif +#define MapPenA(drawhandle, rgb, tags) IGuiGFX->MapPenA((drawhandle), (rgb), (tags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define MapPen(drawhandle, ...) IGuiGFX->MapPen((drawhandle), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define MapPen(drawhandle, vargs...) IGuiGFX->MapPen(drawhandle, ## vargs) +#endif +#define CreatePictureBitMapA(drawhandle, pic, tags) IGuiGFX->CreatePictureBitMapA((drawhandle), (pic), (tags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define CreatePictureBitMap(drawhandle, ...) IGuiGFX->CreatePictureBitMap((drawhandle), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define CreatePictureBitMap(drawhandle, vargs...) IGuiGFX->CreatePictureBitMap(drawhandle, ## vargs) +#endif +#define DoPictureMethodA(pic, method, arguments) IGuiGFX->DoPictureMethodA((pic), (method), (arguments)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define DoPictureMethod(pic, ...) IGuiGFX->DoPictureMethod((pic), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define DoPictureMethod(pic, vargs...) IGuiGFX->DoPictureMethod(pic, ## vargs) +#endif +#define GetPictureAttrsA(pic, tags) IGuiGFX->GetPictureAttrsA((pic), (tags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define GetPictureAttrs(...) IGuiGFX->GetPictureAttrs(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define GetPictureAttrs(vargs...) IGuiGFX->GetPictureAttrs(## vargs) +#endif +#define LockPictureA(pic, mode, args) IGuiGFX->LockPictureA((pic), (mode), (args)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define LockPicture(pic, ...) IGuiGFX->LockPicture((pic), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define LockPicture(pic, vargs...) IGuiGFX->LockPicture(pic, ## vargs) +#endif +#define UnLockPicture(pic, mode) IGuiGFX->UnLockPicture((pic), (mode)) +#define IsPictureA(filename, tags) IGuiGFX->IsPictureA((filename), (tags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define IsPicture(...) IGuiGFX->IsPicture(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define IsPicture(vargs...) IGuiGFX->IsPicture(## vargs) +#endif +#define CreateDirectDrawHandleA(drawhandle, sw, sh, dw, dh, tags) IGuiGFX->CreateDirectDrawHandleA((drawhandle), (sw), (sh), (dw), (dh), (tags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define CreateDirectDrawHandle(drawhandle, sw, sh, dw, ...) IGuiGFX->CreateDirectDrawHandle((drawhandle), (sw), (sh), (dw), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define CreateDirectDrawHandle(drawhandle, sw, sh, dw, vargs...) IGuiGFX->CreateDirectDrawHandle(drawhandle, sw, sh, dw, ## vargs) +#endif +#define DeleteDirectDrawHandle(ddh) IGuiGFX->DeleteDirectDrawHandle((ddh)) +#define DirectDrawTrueColorA(ddh, array, x, y, tags) IGuiGFX->DirectDrawTrueColorA((ddh), (array), (x), (y), (tags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define DirectDrawTrueColor(ddh, array, x, ...) IGuiGFX->DirectDrawTrueColor((ddh), (array), (x), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define DirectDrawTrueColor(ddh, array, x, vargs...) IGuiGFX->DirectDrawTrueColor(ddh, array, x, ## vargs) +#endif +#define CreatePictureMaskA(pic, mask, maskwidth, tags) IGuiGFX->CreatePictureMaskA((pic), (mask), (maskwidth), (tags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define CreatePictureMask(pic, mask, ...) IGuiGFX->CreatePictureMask((pic), (mask), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define CreatePictureMask(pic, mask, vargs...) IGuiGFX->CreatePictureMask(pic, mask, ## vargs) +#endif + +#endif /* INLINE4_GUIGFX_H */ diff --git a/scalos/include/inline4/iconobject.h b/scalos/include/inline4/iconobject.h new file mode 100755 index 000000000..0e696fa13 --- /dev/null +++ b/scalos/include/inline4/iconobject.h @@ -0,0 +1,60 @@ +#ifndef INLINE4_ICONOBJECT_H +#define INLINE4_ICONOBJECT_H + +/* +** This file was auto generated by idltool 52.1. +** +** It provides compatibility to OS3 style library +** calls by substituting functions. +** +** Do not edit manually. +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif + +#ifndef INTUITION_CLASSUSR_H +#include +#endif +#ifndef WORKBENCH_WORKBENCH_H +#include +#endif +#include + +/* Inline macros for Interface "main" */ +#define NewIconObject(name, tagList) IIconobject->NewIconObject((name), (tagList)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define NewIconObjectTags(...) IIconobject->NewIconObjectTags(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define NewIconObjectTags(vargs...) IIconobject->NewIconObjectTags(## vargs) +#endif +#define DisposeIconObject(iconObject) IIconobject->DisposeIconObject((iconObject)) +#define GetDefIconObject(iconType, tagList) IIconobject->GetDefIconObject((iconType), (tagList)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define GetDefIconObjectTags(...) IIconobject->GetDefIconObjectTags(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define GetDefIconObjectTags(vargs...) IIconobject->GetDefIconObjectTags(## vargs) +#endif +#define PutIconObject(iconObject, path, tagList) IIconobject->PutIconObject((iconObject), (path), (tagList)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define PutIconObjectTags(iconObject, ...) IIconobject->PutIconObjectTags((iconObject), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define PutIconObjectTags(iconObject, vargs...) IIconobject->PutIconObjectTags(iconObject, ## vargs) +#endif +#define IsIconName(fileName) IIconobject->IsIconName((fileName)) +#define Convert2IconObject(diskObject) IIconobject->Convert2IconObject((diskObject)) +#define Convert2IconObjectA(diskObject, tagList) IIconobject->Convert2IconObjectA((diskObject), (tagList)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define Convert2IconObjectTags(...) IIconobject->Convert2IconObjectTags(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define Convert2IconObjectTags(vargs...) IIconobject->Convert2IconObjectTags(## vargs) +#endif + +#endif /* INLINE4_ICONOBJECT_H */ diff --git a/scalos/include/inline4/openurl.h b/scalos/include/inline4/openurl.h new file mode 100755 index 000000000..54bdffd25 --- /dev/null +++ b/scalos/include/inline4/openurl.h @@ -0,0 +1,57 @@ +#ifndef INLINE4_OPENURL_H +#define INLINE4_OPENURL_H + +/* +** This file was auto generated by idltool 51.3. +** +** It provides compatibility to OS3 style library +** calls by substituting functions. +** +** Do not edit manually. +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif + + +/* Inline macros for Interface "main" */ +#define URL_OpenA(url, tags) IOpenURL->URL_OpenA(url, tags) +#if !defined(__cplusplus) && (__GNUC__ >= 3 \ + || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) \ + || (__STDC_VERSION__ && __STDC_VERSION__ >= 199901L)) +#define URL_Open(...) IOpenURL->URL_Open(__VA_ARGS__) +#endif +#define URL_GetPrefsA(tags) IOpenURL->URL_GetPrefsA(tags) +#if !defined(__cplusplus) && (__GNUC__ >= 3 \ + || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) \ + || (__STDC_VERSION__ && __STDC_VERSION__ >= 199901L)) +#define URL_GetPrefs(...) IOpenURL->URL_GetPrefs(__VA_ARGS__) +#endif +#define URL_FreePrefsA(prefs, tags) IOpenURL->URL_FreePrefsA(prefs, tags) +#if !defined(__cplusplus) && (__GNUC__ >= 3 \ + || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) \ + || (__STDC_VERSION__ && __STDC_VERSION__ >= 199901L)) +#define URL_FreePrefs(...) IOpenURL->URL_FreePrefs(__VA_ARGS__) +#endif +#define URL_SetPrefsA(up, tags) IOpenURL->URL_SetPrefsA(up, tags) +#if !defined(__cplusplus) && (__GNUC__ >= 3 \ + || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) \ + || (__STDC_VERSION__ && __STDC_VERSION__ >= 199901L)) +#define URL_SetPrefs(...) IOpenURL->URL_SetPrefs(__VA_ARGS__) +#endif +#define URL_LaunchPrefsAppA(tags) IOpenURL->URL_LaunchPrefsAppA(tags) +#if !defined(__cplusplus) && (__GNUC__ >= 3 \ + || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) \ + || (__STDC_VERSION__ && __STDC_VERSION__ >= 199901L)) +#define URL_LaunchPrefsApp(...) IOpenURL->URL_LaunchPrefsApp(__VA_ARGS__) +#endif +#define URL_GetAttr(attr, storage) IOpenURL->URL_GetAttr(attr, storage) + +#endif /* INLINE4_OPENURL_H */ diff --git a/scalos/include/inline4/pm.h b/scalos/include/inline4/pm.h new file mode 100644 index 000000000..08417a016 --- /dev/null +++ b/scalos/include/inline4/pm.h @@ -0,0 +1,99 @@ +#ifndef INLINE4_PM_H +#define INLINE4_PM_H + +/* +** This file was auto generated by idltool 52.1. +** +** It provides compatibility to OS3 style library +** calls by substituting functions. +** +** Do not edit manually. +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif + +#ifndef LIBRARIES_PM_H +#include +#endif +#include + +/* Inline macros for Interface "main" */ +#define PM_MakeMenuA(tags) IPopupMenu->PM_MakeMenuA((tags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define PM_MakeMenu(...) IPopupMenu->PM_MakeMenu(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define PM_MakeMenu(...) IPopupMenu->PM_MakeMenu(## vargs) +#endif +#define PM_MakeItemA(tags) IPopupMenu->PM_MakeItemA((tags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define PM_MakeItem(...) IPopupMenu->PM_MakeItem(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define PM_MakeItem(...) IPopupMenu->PM_MakeItem(## vargs) +#endif +#define PM_FreePopupMenu(menu) IPopupMenu->PM_FreePopupMenu((menu)) +#define PM_OpenPopupMenuA(wnd, tags) IPopupMenu->PM_OpenPopupMenuA((wnd), (tags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define PM_OpenPopupMenu(...) IPopupMenu->PM_OpenPopupMenu(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define PM_OpenPopupMenu(vargs...) IPopupMenu->PM_OpenPopupMenu(## vargs) +#endif +#define PM_MakeIDListA(tags) IPopupMenu->PM_MakeIDListA((tags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define PM_MakeIDList(...) IPopupMenu->PM_MakeIDList(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define PM_MakeIDList(...) IPopupMenu->PM_MakeIDList(## vargs) +#endif +#define PM_ItemChecked(pm, id) IPopupMenu->PM_ItemChecked((pm), (id)) +#define PM_GetItemAttrsA(item, tags) IPopupMenu->PM_GetItemAttrsA((item), (tags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define PM_GetItemAttrs(...) IPopupMenu->PM_GetItemAttrs(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define PM_GetItemAttrs(vargs...) IPopupMenu->PM_GetItemAttrs(## vargs) +#endif +#define PM_SetItemAttrsA(item, tags) IPopupMenu->PM_SetItemAttrsA((item), (tags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define PM_SetItemAttrs(...) IPopupMenu->PM_SetItemAttrs(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define PM_SetItemAttrs(vargs...) IPopupMenu->PM_SetItemAttrs(## vargs) +#endif +#define PM_FindItem(menu, id) IPopupMenu->PM_FindItem((menu), (id)) +#define PM_AlterState(menu, idlst, action) IPopupMenu->PM_AlterState((menu), (idlst), (action)) +#define PM_ExLstA(id) IPopupMenu->PM_ExLstA((id)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define PM_ExLst(...) IPopupMenu->PM_ExLst(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define PM_ExLst(...) IPopupMenu->PM_ExLst(## vargs) +#endif +#define PM_FilterIMsgA(window, menu, imsg, tags) IPopupMenu->PM_FilterIMsgA((window), (menu), (imsg), (tags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define PM_FilterIMsg(window, menu, ...) IPopupMenu->PM_FilterIMsg((window), (menu), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define PM_FilterIMsg(window, menu, vargs...) IPopupMenu->PM_FilterIMsg(window, menu, ## vargs) +#endif +#define PM_InsertMenuItemA(menu, tags) IPopupMenu->PM_InsertMenuItemA((menu), (tags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define PM_InsertMenuItem(...) IPopupMenu->PM_InsertMenuItem(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define PM_InsertMenuItem(vargs...) IPopupMenu->PM_InsertMenuItem(## vargs) +#endif +#define PM_RemoveMenuItem(menu, item) IPopupMenu->PM_RemoveMenuItem((menu), (item)) +#define PM_AbortHook(handle) IPopupMenu->PM_AbortHook((handle)) +#define PM_GetVersion() IPopupMenu->PM_GetVersion() +#define PM_ReloadPrefs() IPopupMenu->PM_ReloadPrefs() +#define PM_LayoutMenuA(window, menu, tags) IPopupMenu->PM_LayoutMenuA((window), (menu), (tags)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define PM_LayoutMenu(window, ...) IPopupMenu->PM_LayoutMenu((window), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define PM_LayoutMenu(window, vargs...) IPopupMenu->PM_LayoutMenu(window, ## vargs) +#endif +#define PM_FreeIDList(list) IPopupMenu->PM_FreeIDList((list)) + +#endif /* INLINE4_PM_H */ diff --git a/scalos/include/inline4/preferences.h b/scalos/include/inline4/preferences.h new file mode 100644 index 000000000..b0721944d --- /dev/null +++ b/scalos/include/inline4/preferences.h @@ -0,0 +1,40 @@ +#ifndef INLINE4_PREFERENCES_H +#define INLINE4_PREFERENCES_H + +/* +** This file was auto generated by idltool 52.1. +** +** It provides compatibility to OS3 style library +** calls by substituting functions. +** +** Do not edit manually. +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif + +#ifndef SCALOS_PREFERENCES_H +#include +#endif +#include + +/* Inline macros for Interface "main" */ +#define AllocPrefsHandle(name) IPreferences->AllocPrefsHandle((name)) +#define FreePrefsHandle(prefsHandle) IPreferences->FreePrefsHandle((prefsHandle)) +#define SetPreferences(prefsHandle, iD, prefsTag, a1arg, struct_Size) IPreferences->SetPreferences((prefsHandle), (iD), (prefsTag), (a1arg), (struct_Size)) +#define GetPreferences(prefsHandle, iD, prefsTag, a1arg, struct_Size) IPreferences->GetPreferences((prefsHandle), (iD), (prefsTag), (a1arg), (struct_Size)) +#define ReadPrefsHandle(prefsHandle, filename) IPreferences->ReadPrefsHandle((prefsHandle), (filename)) +#define WritePrefsHandle(prefsHandle, filename) IPreferences->WritePrefsHandle((prefsHandle), (filename)) +#define FindPreferences(prefsHandle, iD, prefsTag) IPreferences->FindPreferences((prefsHandle), (iD), (prefsTag)) +#define SetEntry(prefsHandle, iD, prefsTag, a1arg, struct_Size, entry) IPreferences->SetEntry((prefsHandle), (iD), (prefsTag), (a1arg), (struct_Size), (entry)) +#define GetEntry(prefsHandle, iD, prefsTag, a1arg, struct_Size, entry) IPreferences->GetEntry((prefsHandle), (iD), (prefsTag), (a1arg), (struct_Size), (entry)) +#define RemEntry(prefsHandle, iD, prefsTag, entry) IPreferences->RemEntry((prefsHandle), (iD), (prefsTag), (entry)) + +#endif /* INLINE4_PREFERENCES_H */ diff --git a/scalos/include/inline4/scalos.h b/scalos/include/inline4/scalos.h new file mode 100644 index 000000000..36b2f069d --- /dev/null +++ b/scalos/include/inline4/scalos.h @@ -0,0 +1,128 @@ +#ifndef INLINE4_SCALOS_H +#define INLINE4_SCALOS_H + +/* +** This file was auto generated by idltool 52.1. +** +** It provides compatibility to OS3 style library +** calls by substituting functions. +** +** Do not edit manually. +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif + +#ifndef INTUITION_CLASSUSR_H +#include +#endif +#ifndef WORKBENCH_STARTUP_H +#include +#endif +#ifndef SCALOS_SCALOS_H +#include +#endif +#include + +/* Inline macros for Interface "main" */ +#define SCA_WBStart(argArray, tagList, numArgs) IScalos->SCA_WBStart((argArray), (tagList), (numArgs)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define SCA_WBStartTags(argArray, numArgs, ...) IScalos->SCA_WBStartTags((argArray), (numArgs), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define SCA_WBStartTags(argArray, numArgs, vargs...) IScalos->SCA_WBStartTags(argArray, numArgs, ## vargs) +#endif +#define SCA_SortNodes(nodelist, sortHook, sortType) IScalos->SCA_SortNodes((nodelist), (sortHook), (sortType)) +#define SCA_NewAddAppIcon(iD, userData, iconObj, msgPort, tagList) IScalos->SCA_NewAddAppIcon((iD), (userData), (iconObj), (msgPort), (tagList)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define SCA_NewAddAppIconTags(iD, userData, iconObj, ...) IScalos->SCA_NewAddAppIconTags((iD), (userData), (iconObj), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define SCA_NewAddAppIconTags(iD, userData, iconObj, vargs...) IScalos->SCA_NewAddAppIconTags(iD, userData, iconObj, ## vargs) +#endif +#define SCA_RemoveAppObject(appObj) IScalos->SCA_RemoveAppObject((appObj)) +#define SCA_NewAddAppWindow(iD, userData, win, msgPort, tagList) IScalos->SCA_NewAddAppWindow((iD), (userData), (win), (msgPort), (tagList)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define SCA_NewAddAppWindowTags(iD, userData, win, ...) IScalos->SCA_NewAddAppWindowTags((iD), (userData), (win), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define SCA_NewAddAppWindowTags(iD, userData, win, vargs...) IScalos->SCA_NewAddAppWindowTags(iD, userData, win, ## vargs) +#endif +#define SCA_NewAddAppMenuItem(iD, userData, text, msgPort, tagList) IScalos->SCA_NewAddAppMenuItem((iD), (userData), (text), (msgPort), (tagList)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define SCA_NewAddAppMenuItemTags(iD, userData, text, ...) IScalos->SCA_NewAddAppMenuItemTags((iD), (userData), (text), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define SCA_NewAddAppMenuItemTags(iD, userData, text, vargs...) IScalos->SCA_NewAddAppMenuItemTags(iD, userData, text, ## vargs) +#endif +#define SCA_AllocStdNode(nodeList, nodeType) IScalos->SCA_AllocStdNode((nodeList), (nodeType)) +#define SCA_AllocNode(nodeList, size) IScalos->SCA_AllocNode((nodeList), (size)) +#define SCA_FreeNode(nodeList, minNode) IScalos->SCA_FreeNode((nodeList), (minNode)) +#define SCA_FreeAllNodes(nodeList) IScalos->SCA_FreeAllNodes((nodeList)) +#define SCA_MoveNode(srcNodeList, destNodeList, minNode) IScalos->SCA_MoveNode((srcNodeList), (destNodeList), (minNode)) +#define SCA_SwapNodes(minNode1, minNode2, nodeList) IScalos->SCA_SwapNodes((minNode1), (minNode2), (nodeList)) +#define SCA_OpenIconWindow(tagList) IScalos->SCA_OpenIconWindow((tagList)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define SCA_OpenIconWindowTags(...) IScalos->SCA_OpenIconWindowTags(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define SCA_OpenIconWindowTags(...) IScalos->SCA_OpenIconWindowTags(## vargs) +#endif +#define SCA_LockWindowList(accessmode) IScalos->SCA_LockWindowList((accessmode)) +#define SCA_UnLockWindowList() IScalos->SCA_UnLockWindowList() +#define SCA_AllocMessage(messagetype, additional_size) IScalos->SCA_AllocMessage((messagetype), (additional_size)) +#define SCA_FreeMessage(message) IScalos->SCA_FreeMessage((message)) +#define SCA_InitDrag(screen) IScalos->SCA_InitDrag((screen)) +#define SCA_EndDrag(dragHandle) IScalos->SCA_EndDrag((dragHandle)) +#define SCA_AddBob(dragHandle, bm, mask, width, height, xOffset, yOffset) IScalos->SCA_AddBob((dragHandle), (bm), (mask), (width), (height), (xOffset), (yOffset)) +#define SCA_DrawDrag(dragHandle, x, y, flags) IScalos->SCA_DrawDrag((dragHandle), (x), (y), (flags)) +#define SCA_UpdateIcon(windowType, updateIconStruct, ui_SIZE) IScalos->SCA_UpdateIcon((windowType), (updateIconStruct), (ui_SIZE)) +#define SCA_MakeWBArgs(buffer, in, argsSize) IScalos->SCA_MakeWBArgs((buffer), (in), (argsSize)) +#define SCA_FreeWBArgs(buffer, number, flags) IScalos->SCA_FreeWBArgs((buffer), (number), (flags)) +#define SCA_RemapBitmap(srcBitmap, destBitmap, penArray) IScalos->SCA_RemapBitmap((srcBitmap), (destBitmap), (penArray)) +#define SCA_ScreenTitleMsg(format, args) IScalos->SCA_ScreenTitleMsg((format), (args)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define SCA_ScreenTitleMsgArgs(...) IScalos->SCA_ScreenTitleMsgArgs(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define SCA_ScreenTitleMsgArgs(vargs...) IScalos->SCA_ScreenTitleMsgArgs(## vargs) +#endif +#define SCA_MakeScalosClass(className, superClassName, instSize, dispFunc) IScalos->SCA_MakeScalosClass((className), (superClassName), (instSize), (dispFunc)) +#define SCA_FreeScalosClass(scalosClass) IScalos->SCA_FreeScalosClass((scalosClass)) +#define SCA_NewScalosObject(className, tagList) IScalos->SCA_NewScalosObject((className), (tagList)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define SCA_NewScalosObjectTags(...) IScalos->SCA_NewScalosObjectTags(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define SCA_NewScalosObjectTags(vargs...) IScalos->SCA_NewScalosObjectTags(## vargs) +#endif +#define SCA_DisposeScalosObject(obj) IScalos->SCA_DisposeScalosObject((obj)) +#define SCA_ScalosControlA(name, tagList) IScalos->SCA_ScalosControlA((name), (tagList)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define SCA_ScalosControl(...) IScalos->SCA_ScalosControl(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define SCA_ScalosControl(vargs...) IScalos->SCA_ScalosControl(## vargs) +#endif +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define SCA_ScalosControlTags(...) IScalos->SCA_ScalosControlTags(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define SCA_ScalosControlTags(vargs...) IScalos->SCA_ScalosControlTags(## vargs) +#endif +#define SCA_GetDefIconObject(dirLock, name) IScalos->SCA_GetDefIconObject((dirLock), (name)) +#define SCA_OpenDrawerByName(path, tagList) IScalos->SCA_OpenDrawerByName((path), (tagList)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define SCA_OpenDrawerByNameTags(...) IScalos->SCA_OpenDrawerByNameTags(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define SCA_OpenDrawerByNameTags(vargs...) IScalos->SCA_OpenDrawerByNameTags(## vargs) +#endif +#define SCA_CountWBArgs(in) IScalos->SCA_CountWBArgs((in)) +#define SCA_GetDefIconObjectA(dirLock, name, tagList) IScalos->SCA_GetDefIconObjectA((dirLock), (name), (tagList)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define SCA_GetDefIconObjectTags(dirLock, ...) IScalos->SCA_GetDefIconObjectTags((dirLock), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define SCA_GetDefIconObjectTags(dirLock, vargs...) IScalos->SCA_GetDefIconObjectTags(dirLock, ## vargs) +#endif +#define SCA_LockDrag(dragHandle) IScalos->SCA_LockDrag((dragHandle)) +#define SCA_UnlockDrag(dragHandle) IScalos->SCA_UnlockDrag((dragHandle)) + +#endif /* INLINE4_SCALOS_H */ diff --git a/scalos/include/inline4/scalosfiletypeplugin.h b/scalos/include/inline4/scalosfiletypeplugin.h new file mode 100644 index 000000000..191eac0ff --- /dev/null +++ b/scalos/include/inline4/scalosfiletypeplugin.h @@ -0,0 +1,31 @@ +#ifndef INLINE4_SCALOSFILETYPEPLUGIN_H +#define INLINE4_SCALOSFILETYPEPLUGIN_H + +/* +** This file was auto generated by idltool 52.7. +** +** It provides compatibility to OS3 style library +** calls by substituting functions. +** +** Do not edit manually. +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif + +#ifndef SCALOS_SCALOS_H +#include +#endif +#include + +/* Inline macros for Interface "main" */ +#define SCAToolTipInfoString(ttshd, args) IScalosFileTypePlugin->SCAToolTipInfoString((ttshd), (args)) + +#endif /* INLINE4_SCALOSFILETYPEPLUGIN_H */ diff --git a/scalos/include/inline4/scalosgfx.h b/scalos/include/inline4/scalosgfx.h new file mode 100755 index 000000000..b4c648dbc --- /dev/null +++ b/scalos/include/inline4/scalosgfx.h @@ -0,0 +1,102 @@ +#ifndef INLINE4_SCALOSGFX_H +#define INLINE4_SCALOSGFX_H + +/* +** This file was auto generated by idltool 52.1. +** +** It provides compatibility to OS3 style library +** calls by substituting functions. +** +** Do not edit manually. +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif + +#ifndef INTUITION_CLASSUSR_H +#include +#endif +#ifndef SCALOS_SCALOS_H +#include +#endif +#ifndef GRAPHICS_GFX_H +#include +#endif +#ifndef SCALOS_SCALOSGFX_H +#include +#endif +#include + +/* Inline macros for Interface "main" */ +#define ScalosGfxCreateEmptySAC() IScalosGfx->ScalosGfxCreateEmptySAC() +#define ScalosGfxCreateSAC(width, height, depth, friendBM, tagList) IScalosGfx->ScalosGfxCreateSAC((width), (height), (depth), (friendBM), (tagList)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define ScalosGfxCreateSACTags(width, height, depth, ...) IScalosGfx->ScalosGfxCreateSACTags((width), (height), (depth), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define ScalosGfxCreateSACTags(width, height, depth, vargs...) IScalosGfx->ScalosGfxCreateSACTags(width, height, depth, ## vargs) +#endif +#define ScalosGfxFreeSAC(sac) IScalosGfx->ScalosGfxFreeSAC((sac)) +#define ScalosGfxCreateARGB(width, height, tagList) IScalosGfx->ScalosGfxCreateARGB((width), (height), (tagList)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define ScalosGfxCreateARGBTags(width, ...) IScalosGfx->ScalosGfxCreateARGBTags((width), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define ScalosGfxCreateARGBTags(width, vargs...) IScalosGfx->ScalosGfxCreateARGBTags(width, ## vargs) +#endif +#define ScalosGfxFreeARGB(argb) IScalosGfx->ScalosGfxFreeARGB((argb)) +#define ScalosGfxARGBSetAlpha(src, alpha) IScalosGfx->ScalosGfxARGBSetAlpha((src), (alpha)) +#define ScalosGfxARGBSetAlphaMask(argbh, maskPlane) IScalosGfx->ScalosGfxARGBSetAlphaMask((argbh), (maskPlane)) +#define ScalosGfxCreateARGBFromBitMap(bm, width, height, numberOfColors, colorTable, maskPlane) IScalosGfx->ScalosGfxCreateARGBFromBitMap((bm), (width), (height), (numberOfColors), (colorTable), (maskPlane)) +#define ScalosGfxFillARGBFromBitMap(argbh, srcBM, maskPlane) IScalosGfx->ScalosGfxFillARGBFromBitMap((argbh), (srcBM), (maskPlane)) +#define ScalosGfxWriteARGBToBitMap(argbh, bm, numberOfColors, colorTable) IScalosGfx->ScalosGfxWriteARGBToBitMap((argbh), (bm), (numberOfColors), (colorTable)) +#define ScalosGfxMedianCut(argbh, depth, tagList) IScalosGfx->ScalosGfxMedianCut((argbh), (depth), (tagList)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define ScalosGfxMedianCutTags(argbh, ...) IScalosGfx->ScalosGfxMedianCutTags((argbh), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define ScalosGfxMedianCutTags(argbh, vargs...) IScalosGfx->ScalosGfxMedianCutTags(argbh, ## vargs) +#endif +#define ScalosGfxScaleARGBArray(src, destWidth, destHeight, tagList) IScalosGfx->ScalosGfxScaleARGBArray((src), (destWidth), (destHeight), (tagList)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define ScalosGfxScaleARGBArrayTags(src, destWidth, ...) IScalosGfx->ScalosGfxScaleARGBArrayTags((src), (destWidth), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define ScalosGfxScaleARGBArrayTags(src, destWidth, vargs...) IScalosGfx->ScalosGfxScaleARGBArrayTags(src, destWidth, ## vargs) +#endif +#define ScalosGfxScaleBitMap(sbma, tagList) IScalosGfx->ScalosGfxScaleBitMap((sbma), (tagList)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define ScalosGfxScaleBitMapTags(...) IScalosGfx->ScalosGfxScaleBitMapTags(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define ScalosGfxScaleBitMapTags(vargs...) IScalosGfx->ScalosGfxScaleBitMapTags(## vargs) +#endif +#define ScalosGfxCalculateScaleAspect(sourceWidth, sourceHeight, destWidth, destHeight) IScalosGfx->ScalosGfxCalculateScaleAspect((sourceWidth), (sourceHeight), (destWidth), (destHeight)) +#define ScalosGfxBlitARGB(destARGB, srcARGB, destLeft, destTop, srcLeft, srcTop, width, height) IScalosGfx->ScalosGfxBlitARGB((destARGB), (srcARGB), (destLeft), (destTop), (srcLeft), (srcTop), (width), (height)) +#define ScalosGfxFillRectARGB(destARGB, fillARGB, left, top, width, height) IScalosGfx->ScalosGfxFillRectARGB((destARGB), (fillARGB), (left), (top), (width), (height)) +#define ScalosGfxSetARGB(destARGB, fillARGB) IScalosGfx->ScalosGfxSetARGB((destARGB), (fillARGB)) +#define ScalosGfxNewColorMap(sac, colorMap, colorEntries) IScalosGfx->ScalosGfxNewColorMap((sac), (colorMap), (colorEntries)) +#define ScalosGfxARGBRectMult(rp, numerator, denominator, xMin, yMin, xMax, yMax) IScalosGfx->ScalosGfxARGBRectMult((rp), (numerator), (denominator), (xMin), (yMin), (xMax), (yMax)) +#define ScalosGfxBlitARGBAlpha(rp, srcH, destLeft, destTop, srcLeft, srcTop, width, height) IScalosGfx->ScalosGfxBlitARGBAlpha((rp), (srcH), (destLeft), (destTop), (srcLeft), (srcTop), (width), (height)) +#define ScalosGfxBlitARGBAlphaTagList(rp, srcH, destLeft, destTop, srcSize, tagList) IScalosGfx->ScalosGfxBlitARGBAlphaTagList((rp), (srcH), (destLeft), (destTop), (srcSize), (tagList)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define ScalosGfxBlitARGBAlphaTags(rp, srcH, destLeft, destTop, ...) IScalosGfx->ScalosGfxBlitARGBAlphaTags((rp), (srcH), (destLeft), (destTop), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define ScalosGfxBlitARGBAlphaTags(rp, srcH, destLeft, destTop, vargs...) IScalosGfx->ScalosGfxBlitARGBAlphaTags(rp, srcH, destLeft, destTop, ## vargs) +#endif +#define ScalosGfxBlitIcon(rpBackground, rpIcon, left, top, width, height, tagList) IScalosGfx->ScalosGfxBlitIcon((rpBackground), (rpIcon), (left), (top), (width), (height), (tagList)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define ScalosGfxBlitIconTags(rpBackground, rpIcon, left, top, width, ...) IScalosGfx->ScalosGfxBlitIconTags((rpBackground), (rpIcon), (left), (top), (width), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define ScalosGfxBlitIconTags(rpBackground, rpIcon, left, top, width, vargs...) IScalosGfx->ScalosGfxBlitIconTags(rpBackground, rpIcon, left, top, width, ## vargs) +#endif +#define ScalosGfxDrawGradient(dest, left, top, width, height, start, stop, gradType) IScalosGfx->ScalosGfxDrawGradient((dest), (left), (top), (width), (height), (start), (stop), (gradType)) +#define ScalosGfxDrawGradientRastPort(rp, left, top, width, height, start, stop, gradType) IScalosGfx->ScalosGfxDrawGradientRastPort((rp), (left), (top), (width), (height), (start), (stop), (gradType)) +#define ScalosGfxDrawLine(dest, fromX, fromY, toX, toY, lineColor) IScalosGfx->ScalosGfxDrawLine((dest), (fromX), (fromY), (toX), (toY), (lineColor)) +#define ScalosGfxDrawLineRastPort(rp, fromX, fromY, toX, toY, lineColor) IScalosGfx->ScalosGfxDrawLineRastPort((rp), (fromX), (fromY), (toX), (toY), (lineColor)) +#define ScalosGfxDrawEllipse(dest, xCenter, yCenter, radiusX, radiusy, segment, color1, color2) IScalosGfx->ScalosGfxDrawEllipse((dest), (xCenter), (yCenter), (radiusX), (radiusy), (segment), (color1), (color2)) +#define ScalosGfxDrawEllipseRastPort(rp, xCenter, yCenter, radiusX, radiusy, segment, color1, color2) IScalosGfx->ScalosGfxDrawEllipseRastPort((rp), (xCenter), (yCenter), (radiusX), (radiusy), (segment), (color1), (color2)) + +#endif /* INLINE4_SCALOSGFX_H */ diff --git a/scalos/include/inline4/scalosmenuplugin.h b/scalos/include/inline4/scalosmenuplugin.h new file mode 100644 index 000000000..4d11d8a76 --- /dev/null +++ b/scalos/include/inline4/scalosmenuplugin.h @@ -0,0 +1,31 @@ +#ifndef INLINE4_SCALOSMENUPLUGIN_H +#define INLINE4_SCALOSMENUPLUGIN_H + +/* +** This file was auto generated by idltool 52.7. +** +** It provides compatibility to OS3 style library +** calls by substituting functions. +** +** Do not edit manually. +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif + +#ifndef SCALOS_SCALOS_H +#include +#endif +#include + +/* Inline macros for Interface "main" */ +#define SCAMenuFunction(wt, in) IScalosMenuPlugin->SCAMenuFunction((wt), (in)) + +#endif /* INLINE4_SCALOSMENUPLUGIN_H */ diff --git a/scalos/include/inline4/scalosplugin.h b/scalos/include/inline4/scalosplugin.h new file mode 100644 index 000000000..a2b3f8916 --- /dev/null +++ b/scalos/include/inline4/scalosplugin.h @@ -0,0 +1,28 @@ +#ifndef INLINE4_SCALOSPLUGIN_H +#define INLINE4_SCALOSPLUGIN_H + +/* +** This file was auto generated by idltool 52.7. +** +** It provides compatibility to OS3 style library +** calls by substituting functions. +** +** Do not edit manually. +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif + +#include + +/* Inline macros for Interface "main" */ +#define SCAGetClassInfo() IScalosPlugin->SCAGetClassInfo() + +#endif /* INLINE4_SCALOSPLUGIN_H */ diff --git a/scalos/include/inline4/scalosprefsplugin.h b/scalos/include/inline4/scalosprefsplugin.h new file mode 100755 index 000000000..a780bebd0 --- /dev/null +++ b/scalos/include/inline4/scalosprefsplugin.h @@ -0,0 +1,28 @@ +#ifndef INLINE4_SCALOSPREFSPLUGIN_H +#define INLINE4_SCALOSPREFSPLUGIN_H + +/* +** This file was auto generated by idltool 52.7. +** +** It provides compatibility to OS3 style library +** calls by substituting functions. +** +** Do not edit manually. +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif + +#include + +/* Inline macros for Interface "main" */ +#define SCAGetPrefsInfo(which) IScalosPrefsPlugin->SCAGetPrefsInfo((which)) + +#endif /* INLINE4_SCALOSPREFSPLUGIN_H */ diff --git a/scalos/include/inline4/scalospreviewplugin.h b/scalos/include/inline4/scalospreviewplugin.h new file mode 100644 index 000000000..bd2795b48 --- /dev/null +++ b/scalos/include/inline4/scalospreviewplugin.h @@ -0,0 +1,39 @@ +#ifndef INLINE4_SCALOSPREVIEWPLUGIN_H +#define INLINE4_SCALOSPREVIEWPLUGIN_H + +/* +** This file was auto generated by idltool 52.7. +** +** It provides compatibility to OS3 style library +** calls by substituting functions. +** +** Do not edit manually. +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif + +#ifndef SCALOS_SCALOS_H +#include +#endif +#ifndef UTILITY_TAGITEM_H +#include +#endif +#include + +/* Inline macros for Interface "main" */ +#define SCAPreviewGenerate(wt, dirLock, iconName, tagList) IScalosPreviewPlugin->SCAPreviewGenerate((wt), (dirLock), (iconName), (tagList)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define SCAPreviewGenerateTags(wt, dirLock, ...) IScalosPreviewPlugin->SCAPreviewGenerateTags((wt), (dirLock), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define SCAPreviewGenerateTags(wt, dirLock, vargs...) IScalosPreviewPlugin->SCAPreviewGenerateTags(wt, dirLock, ## vargs) +#endif + +#endif /* INLINE4_SCALOSPREVIEWPLUGIN_H */ diff --git a/scalos/include/inline4/sqlite3.h b/scalos/include/inline4/sqlite3.h new file mode 100755 index 000000000..867bbdcd4 --- /dev/null +++ b/scalos/include/inline4/sqlite3.h @@ -0,0 +1,138 @@ +#ifndef INLINE4_SQLITE3_H +#define INLINE4_SQLITE3_H + +/* +** This file was auto generated by idltool 52.1. +** +** It provides compatibility to OS3 style library +** calls by substituting functions. +** +** Do not edit manually. +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif + +#ifndef SQLITE3_H +#include +#endif +#include + +/* Inline macros for Interface "main" */ +#define SQLite3Close(db) ISQLite3->SQLite3Close((db)) +#define SQLite3Exec(db, sql, xCallback, pArg, errmsg) ISQLite3->SQLite3Exec((db), (sql), (xCallback), (pArg), (errmsg)) +#define SQLite3Changes(db) ISQLite3->SQLite3Changes((db)) +#define SQLite3TotalChanges(db) ISQLite3->SQLite3TotalChanges((db)) +#define SQLite3Interrupt(db) ISQLite3->SQLite3Interrupt((db)) +#define SQLite3Complete(sql) ISQLite3->SQLite3Complete((sql)) +#define SQLite3BusyHandler(db, callback, userdata) ISQLite3->SQLite3BusyHandler((db), (callback), (userdata)) +#define SQLite3BusyTimeout(db, ms) ISQLite3->SQLite3BusyTimeout((db), (ms)) +#define SQLite3GetTable(db, sql, presult, nrow, ncolumn, errmsg) ISQLite3->SQLite3GetTable((db), (sql), (presult), (nrow), (ncolumn), (errmsg)) +#define SQLite3FreeTable(result) ISQLite3->SQLite3FreeTable((result)) +#define SQLite3Free(z) ISQLite3->SQLite3Free((z)) +#define SQLite3Trace(db, xTrace, parg) ISQLite3->SQLite3Trace((db), (xTrace), (parg)) +#define SQLite3ProgressHandler(db, nOps, xProgress, pArg) ISQLite3->SQLite3ProgressHandler((db), (nOps), (xProgress), (pArg)) +#define SQLite3CommitHook(db, xCallback, pArg) ISQLite3->SQLite3CommitHook((db), (xCallback), (pArg)) +#define SQLite3Open(filename, ppDb) ISQLite3->SQLite3Open((filename), (ppDb)) +#define SQLite3Errcode(db) ISQLite3->SQLite3Errcode((db)) +#define SQLite3Errmsg(db) ISQLite3->SQLite3Errmsg((db)) +#define SQLite3Prepare(db, zSql, nBytes, ppStmt, pzTail) ISQLite3->SQLite3Prepare((db), (zSql), (nBytes), (ppStmt), (pzTail)) +#define SQLite3BindBlob(pStmt, i, zData, nData, xDel) ISQLite3->SQLite3BindBlob((pStmt), (i), (zData), (nData), (xDel)) +#define SQLite3BindInt(pStmt, i, iValue) ISQLite3->SQLite3BindInt((pStmt), (i), (iValue)) +#define SQLite3BindNull(pStmt, i) ISQLite3->SQLite3BindNull((pStmt), (i)) +#define SQLite3BindText(pStmt, i, zData, nData, xDel) ISQLite3->SQLite3BindText((pStmt), (i), (zData), (nData), (xDel)) +#define SQLite3BindValue(pStmt, i, pVal) ISQLite3->SQLite3BindValue((pStmt), (i), (pVal)) +#define SQLite3BindParameterCount(pStmt) ISQLite3->SQLite3BindParameterCount((pStmt)) +#define SQLite3BindParameterName(pStmt, i) ISQLite3->SQLite3BindParameterName((pStmt), (i)) +#define SQLite3BindParameterIndex(pStmt, zName) ISQLite3->SQLite3BindParameterIndex((pStmt), (zName)) +#define SQLite3ClearBindings(pStmt) ISQLite3->SQLite3ClearBindings((pStmt)) +#define SQLite3ColumnCount(pStmt) ISQLite3->SQLite3ColumnCount((pStmt)) +#define SQLite3ColumnName(pStmt, i) ISQLite3->SQLite3ColumnName((pStmt), (i)) +#define SQLite3ColumnDecltype(pStmt, i) ISQLite3->SQLite3ColumnDecltype((pStmt), (i)) +#define SQLite3Step(pStmt) ISQLite3->SQLite3Step((pStmt)) +#define SQLite3DataCount(pStmt) ISQLite3->SQLite3DataCount((pStmt)) +#define SQLite3ColumnBlob(pStmt, iCol) ISQLite3->SQLite3ColumnBlob((pStmt), (iCol)) +#define SQLite3ColumnBytes(pStmt, iCol) ISQLite3->SQLite3ColumnBytes((pStmt), (iCol)) +#define SQLite3ColumnInt(pStmt, iCol) ISQLite3->SQLite3ColumnInt((pStmt), (iCol)) +#define SQLite3ColumnText(pStmt, iCol) ISQLite3->SQLite3ColumnText((pStmt), (iCol)) +#define SQLite3ColumnType(pStmt, iCol) ISQLite3->SQLite3ColumnType((pStmt), (iCol)) +#define SQLite3Finalize(pStmt) ISQLite3->SQLite3Finalize((pStmt)) +#define SQLite3Reset(pStmt) ISQLite3->SQLite3Reset((pStmt)) +#define SQLite3AggregateCount(pCtx) ISQLite3->SQLite3AggregateCount((pCtx)) +#define SQLite3ValueBlob(pVal) ISQLite3->SQLite3ValueBlob((pVal)) +#define SQLite3ValueBytes(pVal) ISQLite3->SQLite3ValueBytes((pVal)) +#define SQLite3ValueInt(pVal) ISQLite3->SQLite3ValueInt((pVal)) +#define SQLite3ValueText(pVal) ISQLite3->SQLite3ValueText((pVal)) +#define SQLite3ValueType(pVal) ISQLite3->SQLite3ValueType((pVal)) +#define SQLite3Aggregate_context(pCtx, nBytes) ISQLite3->SQLite3Aggregate_context((pCtx), (nBytes)) +#define SQLite3UserData(pCtx) ISQLite3->SQLite3UserData((pCtx)) +#define SQLite3GetAuxdata(pCtx, iArg) ISQLite3->SQLite3GetAuxdata((pCtx), (iArg)) +#define SQLite3SetAuxdata(pCtx, iARg, pAux, xDelete) ISQLite3->SQLite3SetAuxdata((pCtx), (iARg), (pAux), (xDelete)) +#define SQLite3ResultBlob(pCtx, z, n, xDelete) ISQLite3->SQLite3ResultBlob((pCtx), (z), (n), (xDelete)) +#define SQLite3ResultError(pCtx, z, n) ISQLite3->SQLite3ResultError((pCtx), (z), (n)) +#define SQLite3ResultInt(pCtx, iVal) ISQLite3->SQLite3ResultInt((pCtx), (iVal)) +#define SQLite3ResultNull(pCtx) ISQLite3->SQLite3ResultNull((pCtx)) +#define SQLite3ResultText(pCtx, z, n, xDelete) ISQLite3->SQLite3ResultText((pCtx), (z), (n), (xDelete)) +#define SQLite3ResultValue(pCtx, pValue) ISQLite3->SQLite3ResultValue((pCtx), (pValue)) +#define SQLite3CreateCollation(db, zName, eTextRep, pCtx, xCompare) ISQLite3->SQLite3CreateCollation((db), (zName), (eTextRep), (pCtx), (xCompare)) +#define SQLite3CollationNeeded(db, pCollNeededArg, xCollNeeded) ISQLite3->SQLite3CollationNeeded((db), (pCollNeededArg), (xCollNeeded)) +#define SQLite3Sleep(ms) ISQLite3->SQLite3Sleep((ms)) +#define SQLite3Expired(pStmt) ISQLite3->SQLite3Expired((pStmt)) +#define SQLite3TransferBindings(pFromStmt, pToStmt) ISQLite3->SQLite3TransferBindings((pFromStmt), (pToStmt)) +#define SQLite3GlobalRecover() ISQLite3->SQLite3GlobalRecover() +#define SQLite3GetAutocommit(db) ISQLite3->SQLite3GetAutocommit((db)) +#define SQLite3DbHandle(pStmt) ISQLite3->SQLite3DbHandle((pStmt)) +#define SQLite3RollbackHook(db, callback, pUserData) ISQLite3->SQLite3RollbackHook((db), (callback), (pUserData)) +#define SQLite3EnableSharedCache(enable) ISQLite3->SQLite3EnableSharedCache((enable)) +#define SQLite3ReleaseMemory(bytesCount) ISQLite3->SQLite3ReleaseMemory((bytesCount)) +#define SQLite3SoftHeapLimit(maxBytes) ISQLite3->SQLite3SoftHeapLimit((maxBytes)) +#define SQLite3ThreadCleanup() ISQLite3->SQLite3ThreadCleanup() +#define SQLite3PrepareV2(db, zSql, nBytes, ppStmt, pzTail) ISQLite3->SQLite3PrepareV2((db), (zSql), (nBytes), (ppStmt), (pzTail)) +#define SQLite3CreateFunction(db, zFunctionName, nArg, eTextRep, userdata, xFunc, xStep, xFinal) ISQLite3->SQLite3CreateFunction((db), (zFunctionName), (nArg), (eTextRep), (userdata), (xFunc), (xStep), (xFinal)) +#define SQLite3CreateModule(db, zName, methods, clientData) ISQLite3->SQLite3CreateModule((db), (zName), (methods), (clientData)) +#define SQLite3DeclareVtab(db, zCreateTable) ISQLite3->SQLite3DeclareVtab((db), (zCreateTable)) +#define SQLite3OverloadFunction(db, zFuncName, nArg) ISQLite3->SQLite3OverloadFunction((db), (zFuncName), (nArg)) +#define SQLite3BlobOpen(db, zDb, zTable, zColumn, iRow, flags, ppBlob) ISQLite3->SQLite3BlobOpen((db), (zDb), (zTable), (zColumn), (iRow), (flags), (ppBlob)) +#define SQLite3BlobClose(blob) ISQLite3->SQLite3BlobClose((blob)) +#define SQLite3BlobBytes(blob) ISQLite3->SQLite3BlobBytes((blob)) +#define SQLite3BlobRead(blob, z, n, iOffset) ISQLite3->SQLite3BlobRead((blob), (z), (n), (iOffset)) +#define SQLite3BlobWrite(blob, z, n, iOffset) ISQLite3->SQLite3BlobWrite((blob), (z), (n), (iOffset)) +#define SQLite3ExtendedResultCodes(db, onoff) ISQLite3->SQLite3ExtendedResultCodes((db), (onoff)) +#define SQLite3BindZeroBlob(pStmt, i, n) ISQLite3->SQLite3BindZeroBlob((pStmt), (i), (n)) +#define SQLite3ColumnDatabaseName(stmt, n) ISQLite3->SQLite3ColumnDatabaseName((stmt), (n)) +#define SQLite3ColumnTableName(stmt, n) ISQLite3->SQLite3ColumnTableName((stmt), (n)) +#define SQLite3ColumnOriginName(stmt, n) ISQLite3->SQLite3ColumnOriginName((stmt), (n)) +#define SQLite3ColumnValue(pStmt, iCol) ISQLite3->SQLite3ColumnValue((pStmt), (iCol)) +#define SQLite3CreateCollationV2(db, zName, eTextRep, pCtx, xCompare, xDestroy) ISQLite3->SQLite3CreateCollationV2((db), (zName), (eTextRep), (pCtx), (xCompare), (xDestroy)) +#define SQLite3LibVersion() ISQLite3->SQLite3LibVersion() +#define SQLite3LibversionNumber() ISQLite3->SQLite3LibversionNumber() +#define SQLite3ResultErrorToobig(pCtx) ISQLite3->SQLite3ResultErrorToobig((pCtx)) +#define SQLite3ResultZeroBlob(pCtx, n) ISQLite3->SQLite3ResultZeroBlob((pCtx), (n)) +#define SQLite3ValueNumericType(pVal) ISQLite3->SQLite3ValueNumericType((pVal)) +#define SQLite3ConfigV(op, ap) ISQLite3->SQLite3ConfigV((op), (ap)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define SQLite3Config(...) ISQLite3->SQLite3Config(__VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define SQLite3Config(vargs...) ISQLite3->SQLite3Config(## vargs) +#endif +#define SQLlite3DbConfigV(db, op, ap) ISQLite3->SQLlite3DbConfigV((db), (op), (ap)) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (__GNUC__ >= 3) +#define SQLlite3DbConfig(db, ...) ISQLite3->SQLlite3DbConfig((db), __VA_ARGS__) +#elif (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define SQLlite3DbConfig(db, vargs...) ISQLite3->SQLlite3DbConfig(db, ## vargs) +#endif +#define SQLite3VfsFind(zVfsName) ISQLite3->SQLite3VfsFind((zVfsName)) +#define SQLite3VfsRegister(vfs, makeDflt) ISQLite3->SQLite3VfsRegister((vfs), (makeDflt)) +#define SQLite3VfsUnregister(vfs) ISQLite3->SQLite3VfsUnregister((vfs)) +#define SQLite3FileControl(db, zDbName, op, arg) ISQLite3->SQLite3FileControl((db), (zDbName), (op), (arg)) +#define SQLite3Status(op, pCurrent, pHighwater, resetFlag) ISQLite3->SQLite3Status((op), (pCurrent), (pHighwater), (resetFlag)) +#define SQLite3DbStatus(db, op, pCur, pHiwtr, resetFlg) ISQLite3->SQLite3DbStatus((db), (op), (pCur), (pHiwtr), (resetFlg)) + +#endif /* INLINE4_SQLITE3_H */ diff --git a/scalos/include/inline4/ttengine.h b/scalos/include/inline4/ttengine.h new file mode 100644 index 000000000..f4572a98f --- /dev/null +++ b/scalos/include/inline4/ttengine.h @@ -0,0 +1,82 @@ +#ifndef INLINE4_TTENGINE_H +#define INLINE4_TTENGINE_H + +/* +** This file was auto generated by idltool 51.3. +** +** It provides compatibility to OS3 style library +** calls by substituting functions. +** +** Do not edit manually. +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif + +#ifndef UTILITY_TAGITEM_H +#include +#endif +#ifndef LIBRARIES_TTENGINE_H +#include +#endif +#ifndef GRAPHICS_TEXT_H +#include +#endif + +/* Inline macros for Interface "main" */ +#define TT_OpenFontA(taglist) ITTEngine->TT_OpenFontA(taglist) +#if !defined(__cplusplus) && (__GNUC__ >= 3 \ + || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) \ + || (__STDC_VERSION__ && __STDC_VERSION__ >= 199901L)) +#define TT_OpenFont(...) ITTEngine->TT_OpenFont(__VA_ARGS__) +#endif +#define TT_SetFont(rp, font) ITTEngine->TT_SetFont(rp, font) +#define TT_CloseFont(font) ITTEngine->TT_CloseFont(font) +#define TT_Text(rp, string, count) ITTEngine->TT_Text(rp, string, count) +#define TT_SetAttrsA(rp, taglist) ITTEngine->TT_SetAttrsA(rp, taglist) +#if !defined(__cplusplus) && (__GNUC__ >= 3 \ + || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) \ + || (__STDC_VERSION__ && __STDC_VERSION__ >= 199901L)) +#define TT_SetAttrs(...) ITTEngine->TT_SetAttrs(__VA_ARGS__) +#endif +#define TT_GetAttrsA(rp, taglist) ITTEngine->TT_GetAttrsA(rp, taglist) +#if !defined(__cplusplus) && (__GNUC__ >= 3 \ + || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) \ + || (__STDC_VERSION__ && __STDC_VERSION__ >= 199901L)) +#define TT_GetAttrs(...) ITTEngine->TT_GetAttrs(__VA_ARGS__) +#endif +#define TT_TextLength(rp, string, count) ITTEngine->TT_TextLength(rp, string, count) +#define TT_TextExtent(rp, string, count, te) ITTEngine->TT_TextExtent(rp, string, count, te) +#define TT_TextFit(rp, string, count, te, tec, dir, cwidth, cheight) ITTEngine->TT_TextFit(rp, string, count, te, tec, dir, cwidth, cheight) +#define TT_GetPixmapA(font, string, count, taglist) ITTEngine->TT_GetPixmapA(font, string, count, taglist) +#if !defined(__cplusplus) && (__GNUC__ >= 3 \ + || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) \ + || (__STDC_VERSION__ && __STDC_VERSION__ >= 199901L)) +#define TT_GetPixmap(font, string, ...) ITTEngine->TT_GetPixmap(font, string, __VA_ARGS__) +#endif +#define TT_FreePixmap(pixmap) ITTEngine->TT_FreePixmap(pixmap) +#define TT_DoneRastPort(rp) ITTEngine->TT_DoneRastPort(rp) +#define TT_AllocRequest() ITTEngine->TT_AllocRequest() +#define TT_RequestA(request, taglist) ITTEngine->TT_RequestA(request, taglist) +#if !defined(__cplusplus) && (__GNUC__ >= 3 \ + || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) \ + || (__STDC_VERSION__ && __STDC_VERSION__ >= 199901L)) +#define TT_Request(...) ITTEngine->TT_Request(__VA_ARGS__) +#endif +#define TT_FreeRequest(request) ITTEngine->TT_FreeRequest(request) +#define TT_ObtainFamilyListA(taglist) ITTEngine->TT_ObtainFamilyListA(taglist) +#if !defined(__cplusplus) && (__GNUC__ >= 3 \ + || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) \ + || (__STDC_VERSION__ && __STDC_VERSION__ >= 199901L)) +#define TT_ObtainFamilyList(...) ITTEngine->TT_ObtainFamilyList(__VA_ARGS__) +#endif +#define TT_FreeFamilyList(list) ITTEngine->TT_FreeFamilyList(list) + +#endif /* INLINE4_TTENGINE_H */ diff --git a/scalos/include/interfaces/cybergraphics.h b/scalos/include/interfaces/cybergraphics.h new file mode 100755 index 000000000..88884ed61 --- /dev/null +++ b/scalos/include/interfaces/cybergraphics.h @@ -0,0 +1,80 @@ +#ifndef CYBERGRAPHICS_INTERFACE_DEF_H +#define CYBERGRAPHICS_INTERFACE_DEF_H + +/* +** This file was machine generated by idltool 52.1. +** Do not edit +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif + +#ifndef UTILITY_TAGITEM_H +#include +#endif + +struct CyberGfxIFace +{ + struct InterfaceData Data; + + uint32 APICALL (*Obtain)(struct CyberGfxIFace *Self); + uint32 APICALL (*Release)(struct CyberGfxIFace *Self); + void APICALL (*Expunge)(struct CyberGfxIFace *Self); + struct Interface * APICALL (*Clone)(struct CyberGfxIFace *Self); + void APICALL (*Reserved1)(struct CyberGfxIFace *Self); + void APICALL (*Reserved2)(struct CyberGfxIFace *Self); + void APICALL (*Reserved3)(struct CyberGfxIFace *Self); + void APICALL (*Reserved4)(struct CyberGfxIFace *Self); + BOOL APICALL (*IsCyberModeID)(struct CyberGfxIFace *Self, ULONG displayID); + ULONG APICALL (*BestCModeIDTagList)(struct CyberGfxIFace *Self, struct TagItem * bestModeIDTags); + ULONG APICALL (*BestCModeIDTags)(struct CyberGfxIFace *Self, ...); + ULONG APICALL (*CModeRequestTagList)(struct CyberGfxIFace *Self, APTR modeRequest, struct TagItem * modeRequestTags); + ULONG APICALL (*CModeRequestTags)(struct CyberGfxIFace *Self, APTR modeRequest, ...); + struct List * APICALL (*AllocCModeListTagList)(struct CyberGfxIFace *Self, struct TagItem * modeListTags); + struct List * APICALL (*AllocCModeListTags)(struct CyberGfxIFace *Self, ...); + VOID APICALL (*FreeCModeList)(struct CyberGfxIFace *Self, struct List * modeList); + void APICALL (*Reserved5)(struct CyberGfxIFace *Self); + LONG APICALL (*ScalePixelArray)(struct CyberGfxIFace *Self, APTR srcRect, UWORD srcW, UWORD srcH, UWORD srcMod, struct RastPort * rp, UWORD destX, UWORD destY, UWORD destW, UWORD destH, UBYTE srcFormat); + ULONG APICALL (*GetCyberMapAttr)(struct CyberGfxIFace *Self, struct BitMap * cyberGfxBitmap, ULONG cyberAttrTag); + ULONG APICALL (*GetCyberIDAttr)(struct CyberGfxIFace *Self, ULONG cyberIDAttr, ULONG cyberDisplayModeID); + ULONG APICALL (*ReadRGBPixel)(struct CyberGfxIFace *Self, struct RastPort * rp, UWORD x, UWORD y); + LONG APICALL (*WriteRGBPixel)(struct CyberGfxIFace *Self, struct RastPort * rp, UWORD x, UWORD y, ULONG argb); + ULONG APICALL (*ReadPixelArray)(struct CyberGfxIFace *Self, APTR destRect, UWORD destX, UWORD destY, UWORD destMod, struct RastPort * rp, UWORD srcX, UWORD srcY, UWORD sizeX, UWORD sizeY, UBYTE destFormat); + ULONG APICALL (*WritePixelArray)(struct CyberGfxIFace *Self, APTR srcRect, UWORD srcX, UWORD srcY, UWORD srcMod, struct RastPort * rp, UWORD destX, UWORD destY, UWORD sizeX, UWORD sizeY, UBYTE srcFormat); + ULONG APICALL (*MovePixelArray)(struct CyberGfxIFace *Self, UWORD srcX, UWORD srcY, struct RastPort * rp, UWORD destX, UWORD destY, UWORD sizeX, UWORD sizeY); + void APICALL (*Reserved6)(struct CyberGfxIFace *Self); + ULONG APICALL (*InvertPixelArray)(struct CyberGfxIFace *Self, struct RastPort * rp, UWORD destX, UWORD destY, UWORD sizeX, UWORD sizeY); + ULONG APICALL (*FillPixelArray)(struct CyberGfxIFace *Self, struct RastPort * rp, UWORD destX, UWORD destY, UWORD sizeX, UWORD sizeY, ULONG aRGB); + VOID APICALL (*DoCDrawMethodTagList)(struct CyberGfxIFace *Self, struct Hook * hook, struct RastPort * rp, struct TagItem * tagList); + VOID APICALL (*DoCDrawMethodTags)(struct CyberGfxIFace *Self, struct Hook * hook, struct RastPort * rp, ...); + VOID APICALL (*CVideoCtrlTagList)(struct CyberGfxIFace *Self, struct ViewPort * viewPort, struct TagItem * tagList); + VOID APICALL (*CVideoCtrlTags)(struct CyberGfxIFace *Self, struct ViewPort * viewPort, ...); + APTR APICALL (*LockBitMapTagList)(struct CyberGfxIFace *Self, APTR bitMap, struct TagItem * tagList); + APTR APICALL (*LockBitMapTags)(struct CyberGfxIFace *Self, APTR bitMap, ...); + VOID APICALL (*UnLockBitMap)(struct CyberGfxIFace *Self, APTR handle); + VOID APICALL (*UnLockBitMapTagList)(struct CyberGfxIFace *Self, APTR handle, struct TagItem * tagList); + VOID APICALL (*UnLockBitMapTags)(struct CyberGfxIFace *Self, APTR handle, ...); + ULONG APICALL (*ExtractColor)(struct CyberGfxIFace *Self, struct RastPort * rp, struct BitMap * bitMap, ULONG colour, ULONG srcX, ULONG srcY, ULONG width, ULONG height); + void APICALL (*Reserved7)(struct CyberGfxIFace *Self); + ULONG APICALL (*WriteLUTPixelArray)(struct CyberGfxIFace *Self, APTR srcRect, UWORD srcX, UWORD srcY, UWORD srcMod, struct RastPort * rp, APTR colorTab, UWORD destX, UWORD destY, UWORD sizeX, UWORD sizeY, UBYTE cTFormat); + void APICALL (*Reserved8)(struct CyberGfxIFace *Self); + void APICALL (*Reserved9)(struct CyberGfxIFace *Self); + ULONG APICALL (*WritePixelArrayAlpha)(struct CyberGfxIFace *Self, APTR srcRect, UWORD srcX, UWORD srcY, UWORD srcMod, struct RastPort * rp, UWORD destX, UWORD destY, UWORD sizeX, UWORD sizeY, ULONG globalAlpha); + VOID APICALL (*BltTemplateAlpha)(struct CyberGfxIFace *Self, UBYTE * source, LONG xSrc, LONG srcMod, struct RastPort * destRP, ULONG xDest, ULONG yDest, ULONG xSize, ULONG ySize); + VOID APICALL (*ProcessPixelArray)(struct CyberGfxIFace *Self, struct RastPort * rp, ULONG destX, ULONG destY, ULONG sizeX, ULONG sizeY, ULONG operation, LONG value, struct TagItem * taglist); + VOID APICALL (*ProcessPixelArrayTags)(struct CyberGfxIFace *Self, struct RastPort * rp, ULONG destX, ULONG destY, ULONG sizeX, ULONG sizeY, ULONG operation, LONG value, ...); + ULONG APICALL (*BltBitMapAlpha)(struct CyberGfxIFace *Self, struct BitMap * srcBitMap, WORD srcX, WORD srcY, struct BitMap * destBitMap, WORD destX, WORD destY, WORD sizeX, WORD sizeY, struct TagItem * taglist); + ULONG APICALL (*BltBitMapRastPortAlpha)(struct CyberGfxIFace *Self, struct BitMap * srcBitMap, WORD srcX, WORD srcY, struct RastPort * destRP, WORD destX, WORD destY, WORD sizeX, WORD sizeY, struct TagItem * taglist); + void APICALL (*Reserved10)(struct CyberGfxIFace *Self); + void APICALL (*Reserved11)(struct CyberGfxIFace *Self); + LONG APICALL (*ScalePixelArrayAlpha)(struct CyberGfxIFace *Self, APTR srcRect, UWORD srcW, UWORD srcH, UWORD srcMod, struct RastPort * rp, UWORD destX, UWORD destY, UWORD destW, UWORD destH, ULONG globalAlpha); +}; + +#endif /* CYBERGRAPHICS_INTERFACE_DEF_H */ diff --git a/scalos/include/interfaces/guigfx.h b/scalos/include/interfaces/guigfx.h new file mode 100644 index 000000000..c88c2a6ac --- /dev/null +++ b/scalos/include/interfaces/guigfx.h @@ -0,0 +1,91 @@ +#ifndef GUIGFX_INTERFACE_DEF_H +#define GUIGFX_INTERFACE_DEF_H + +/* +** This file was machine generated by idltool 52.7. +** Do not edit +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif + + +#ifdef __cplusplus +#ifdef __USE_AMIGAOS_NAMESPACE__ +namespace AmigaOS { +#endif +extern "C" { +#endif + +struct GuiGFXIFace +{ + struct InterfaceData Data; + + ULONG APICALL (*Obtain)(struct GuiGFXIFace *Self); + ULONG APICALL (*Release)(struct GuiGFXIFace *Self); + void APICALL (*Expunge)(struct GuiGFXIFace *Self); + struct Interface * APICALL (*Clone)(struct GuiGFXIFace *Self); + APTR APICALL (*MakePictureA)(struct GuiGFXIFace *Self, APTR array, UWORD width, UWORD height, struct TagItem * tags); + APTR APICALL (*MakePicture)(struct GuiGFXIFace *Self, APTR array, UWORD width, UWORD height, ...); + APTR APICALL (*LoadPictureA)(struct GuiGFXIFace *Self, STRPTR filename, struct TagItem * tags); + APTR APICALL (*LoadPicture)(struct GuiGFXIFace *Self, STRPTR filename, ...); + APTR APICALL (*ReadPictureA)(struct GuiGFXIFace *Self, struct RastPort * rp, struct ColorMap * colormap, UWORD x, UWORD y, UWORD width, UWORD height, struct TagItem * tags); + APTR APICALL (*ReadPicture)(struct GuiGFXIFace *Self, struct RastPort * rp, struct ColorMap * colormap, UWORD x, UWORD y, UWORD width, UWORD height, ...); + APTR APICALL (*ClonePictureA)(struct GuiGFXIFace *Self, APTR pic, struct TagItem * tags); + APTR APICALL (*ClonePicture)(struct GuiGFXIFace *Self, APTR pic, ...); + VOID APICALL (*DeletePicture)(struct GuiGFXIFace *Self, APTR pic); + void APICALL (*Reserved1)(struct GuiGFXIFace *Self); + APTR APICALL (*AddPictureA)(struct GuiGFXIFace *Self, APTR psm, APTR pic, struct TagItem * tags); + APTR APICALL (*AddPicture)(struct GuiGFXIFace *Self, APTR psm, APTR pic, ...); + APTR APICALL (*AddPaletteA)(struct GuiGFXIFace *Self, APTR psm, APTR palette, struct TagItem * tags); + APTR APICALL (*AddPalette)(struct GuiGFXIFace *Self, APTR psm, APTR palette, ...); + APTR APICALL (*AddPixelArrayA)(struct GuiGFXIFace *Self, APTR psm, APTR array, UWORD width, UWORD height, struct TagItem * tags); + APTR APICALL (*AddPixelArray)(struct GuiGFXIFace *Self, APTR psm, APTR array, UWORD width, UWORD height, ...); + VOID APICALL (*RemColorHandle)(struct GuiGFXIFace *Self, APTR colorhandle); + APTR APICALL (*CreatePenShareMapA)(struct GuiGFXIFace *Self, struct TagItem * tags); + APTR APICALL (*CreatePenShareMap)(struct GuiGFXIFace *Self, ...); + VOID APICALL (*DeletePenShareMap)(struct GuiGFXIFace *Self, APTR psm); + APTR APICALL (*ObtainDrawHandleA)(struct GuiGFXIFace *Self, APTR psm, struct RastPort * rp, struct ColorMap * cm, struct TagItem * tags); + APTR APICALL (*ObtainDrawHandle)(struct GuiGFXIFace *Self, APTR psm, struct RastPort * rp, struct ColorMap * cm, ...); + VOID APICALL (*ReleaseDrawHandle)(struct GuiGFXIFace *Self, APTR drawhandle); + BOOL APICALL (*DrawPictureA)(struct GuiGFXIFace *Self, APTR drawhandle, APTR pic, UWORD x, UWORD y, struct TagItem * tags); + BOOL APICALL (*DrawPicture)(struct GuiGFXIFace *Self, APTR drawhandle, APTR pic, UWORD x, UWORD y, ...); + BOOL APICALL (*MapPaletteA)(struct GuiGFXIFace *Self, APTR drawhandle, APTR palette, UBYTE * pentab, struct TagItem * tags); + BOOL APICALL (*MapPalette)(struct GuiGFXIFace *Self, APTR drawhandle, APTR palette, UBYTE * pentab, ...); + LONG APICALL (*MapPenA)(struct GuiGFXIFace *Self, APTR drawhandle, ULONG rgb, struct TagItem * tags); + LONG APICALL (*MapPen)(struct GuiGFXIFace *Self, APTR drawhandle, ULONG rgb, ...); + struct BitMap * APICALL (*CreatePictureBitMapA)(struct GuiGFXIFace *Self, APTR drawhandle, APTR pic, struct TagItem * tags); + struct BitMap * APICALL (*CreatePictureBitMap)(struct GuiGFXIFace *Self, APTR drawhandle, APTR pic, ...); + ULONG APICALL (*DoPictureMethodA)(struct GuiGFXIFace *Self, APTR pic, ULONG method, ULONG * arguments); + ULONG APICALL (*DoPictureMethod)(struct GuiGFXIFace *Self, APTR pic, ULONG method, ...); + ULONG APICALL (*GetPictureAttrsA)(struct GuiGFXIFace *Self, APTR pic, struct TagItem * tags); + ULONG APICALL (*GetPictureAttrs)(struct GuiGFXIFace *Self, APTR pic, ...); + ULONG APICALL (*LockPictureA)(struct GuiGFXIFace *Self, APTR pic, ULONG mode, ULONG * args); + ULONG APICALL (*LockPicture)(struct GuiGFXIFace *Self, APTR pic, ULONG mode, ...); + VOID APICALL (*UnLockPicture)(struct GuiGFXIFace *Self, APTR pic, ULONG mode); + BOOL APICALL (*IsPictureA)(struct GuiGFXIFace *Self, STRPTR filename, struct TagItem * tags); + BOOL APICALL (*IsPicture)(struct GuiGFXIFace *Self, STRPTR filename, ...); + APTR APICALL (*CreateDirectDrawHandleA)(struct GuiGFXIFace *Self, APTR drawhandle, UWORD sw, UWORD sh, UWORD dw, UWORD dh, struct TagItem * tags); + APTR APICALL (*CreateDirectDrawHandle)(struct GuiGFXIFace *Self, APTR drawhandle, UWORD sw, UWORD sh, UWORD dw, UWORD dh, ...); + VOID APICALL (*DeleteDirectDrawHandle)(struct GuiGFXIFace *Self, APTR ddh); + BOOL APICALL (*DirectDrawTrueColorA)(struct GuiGFXIFace *Self, APTR ddh, ULONG * array, UWORD x, UWORD y, struct TagItem * tags); + BOOL APICALL (*DirectDrawTrueColor)(struct GuiGFXIFace *Self, APTR ddh, ULONG * array, UWORD x, UWORD y, ...); + BOOL APICALL (*CreatePictureMaskA)(struct GuiGFXIFace *Self, APTR pic, UBYTE * mask, UWORD maskwidth, struct TagItem * tags); + BOOL APICALL (*CreatePictureMask)(struct GuiGFXIFace *Self, APTR pic, UBYTE * mask, UWORD maskwidth, ...); +}; + +#ifdef __cplusplus +} +#ifdef __USE_AMIGAOS_NAMESPACE__ +} +#endif +#endif + +#endif /* GUIGFX_INTERFACE_DEF_H */ diff --git a/scalos/include/interfaces/iconobject.h b/scalos/include/interfaces/iconobject.h new file mode 100644 index 000000000..7b2d9ae5b --- /dev/null +++ b/scalos/include/interfaces/iconobject.h @@ -0,0 +1,47 @@ +#ifndef ICONOBJECT_INTERFACE_DEF_H +#define ICONOBJECT_INTERFACE_DEF_H + +/* +** This file was machine generated by idltool 52.1. +** Do not edit +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif + +#ifndef INTUITION_CLASSUSR_H +#include +#endif +#ifndef WORKBENCH_WORKBENCH_H +#include +#endif + +struct IconobjectIFace +{ + struct InterfaceData Data; + + uint32 APICALL (*Obtain)(struct IconobjectIFace *Self); + uint32 APICALL (*Release)(struct IconobjectIFace *Self); + void APICALL (*Expunge)(struct IconobjectIFace *Self); + struct Interface * APICALL (*Clone)(struct IconobjectIFace *Self); + Object * APICALL (*NewIconObject)(struct IconobjectIFace *Self, CONST_STRPTR name, CONST struct TagItem * tagList); + Object * APICALL (*NewIconObjectTags)(struct IconobjectIFace *Self, CONST_STRPTR name, ...); + VOID APICALL (*DisposeIconObject)(struct IconobjectIFace *Self, Object * iconObject); + Object * APICALL (*GetDefIconObject)(struct IconobjectIFace *Self, ULONG iconType, CONST struct TagItem * tagList); + Object * APICALL (*GetDefIconObjectTags)(struct IconobjectIFace *Self, ULONG iconType, ...); + LONG APICALL (*PutIconObject)(struct IconobjectIFace *Self, Object * iconObject, CONST_STRPTR path, CONST struct TagItem * tagList); + LONG APICALL (*PutIconObjectTags)(struct IconobjectIFace *Self, Object * iconObject, CONST_STRPTR path, ...); + ULONG APICALL (*IsIconName)(struct IconobjectIFace *Self, CONST_STRPTR fileName); + Object * APICALL (*Convert2IconObject)(struct IconobjectIFace *Self, struct DiskObject * diskObject); + Object * APICALL (*Convert2IconObjectA)(struct IconobjectIFace *Self, struct DiskObject * diskObject, CONST struct TagItem * tagList); + Object * APICALL (*Convert2IconObjectTags)(struct IconobjectIFace *Self, struct DiskObject * diskObject, ...); +}; + +#endif /* ICONOBJECT_INTERFACE_DEF_H */ diff --git a/scalos/include/interfaces/openurl.h b/scalos/include/interfaces/openurl.h new file mode 100755 index 000000000..4c6122f61 --- /dev/null +++ b/scalos/include/interfaces/openurl.h @@ -0,0 +1,48 @@ +#ifndef OPENURL_INTERFACE_DEF_H +#define OPENURL_INTERFACE_DEF_H + +/* +** This file was machine generated by idltool 51.3. +** Do not edit +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif + +#include + +struct OpenURLIFace +{ + struct InterfaceData Data; + + ULONG APICALL (*Obtain)(struct OpenURLIFace *Self); + ULONG APICALL (*Release)(struct OpenURLIFace *Self); + void APICALL (*Expunge)(struct OpenURLIFace *Self); + struct Interface * APICALL (*Clone)(struct OpenURLIFace *Self); + ULONG APICALL (*URL_OpenA)(struct OpenURLIFace *Self, STRPTR url, struct TagItem * tags); + ULONG APICALL (*URL_Open)(struct OpenURLIFace *Self, STRPTR url, ...); + void APICALL (*Reserved1)(struct OpenURLIFace *Self); + void APICALL (*Reserved2)(struct OpenURLIFace *Self); + void APICALL (*Reserved3)(struct OpenURLIFace *Self); + void APICALL (*Reserved4)(struct OpenURLIFace *Self); + void APICALL (*Reserved5)(struct OpenURLIFace *Self); + void APICALL (*Reserved6)(struct OpenURLIFace * Self, struct RexxMsg *msg, STRPTR *resPtr); + struct URL_Prefs * APICALL (*URL_GetPrefsA)(struct OpenURLIFace *Self, struct TagItem * tags); + struct URL_Prefs * APICALL (*URL_GetPrefs)(struct OpenURLIFace *Self, ...); + void APICALL (*URL_FreePrefsA)(struct OpenURLIFace *Self, struct URL_Prefs * prefs, struct TagItem * tags); + void APICALL (*URL_FreePrefs)(struct OpenURLIFace *Self, struct URL_Prefs * prefs, ...); + ULONG APICALL (*URL_SetPrefsA)(struct OpenURLIFace *Self, struct URL_Prefs * up, struct TagItem * tags); + ULONG APICALL (*URL_SetPrefs)(struct OpenURLIFace *Self, struct URL_Prefs * up, ...); + ULONG APICALL (*URL_LaunchPrefsAppA)(struct OpenURLIFace *Self, struct TagItem * tags); + ULONG APICALL (*URL_LaunchPrefsApp)(struct OpenURLIFace *Self, ...); + ULONG APICALL (*URL_GetAttr)(struct OpenURLIFace *Self, ULONG attr, ULONG * storage); +}; + +#endif /* OPENURL_INTERFACE_DEF_H */ diff --git a/scalos/include/interfaces/openurl.i b/scalos/include/interfaces/openurl.i new file mode 100755 index 000000000..9b05773e4 --- /dev/null +++ b/scalos/include/interfaces/openurl.i @@ -0,0 +1,36 @@ +#ifndef OPENURL_INTERFACE_DEF_H +#define OPENURL_INTERFACE_DEF_H +/* +** This file is machine generated from idltool +** Do not edit +*/ + +#include +#include +#include + +STRUCTURE OpenURLIFace, InterfaceData_SIZE + FPTR IOpenURL_Obtain + FPTR IOpenURL_Release + FPTR IOpenURL_Expunge + FPTR IOpenURL_Clone + FPTR IOpenURL_URL_OpenA + FPTR IOpenURL_URL_Open + FPTR IOpenURL_Reserved1 + FPTR IOpenURL_Reserved2 + FPTR IOpenURL_Reserved3 + FPTR IOpenURL_Reserved4 + FPTR IOpenURL_Reserved5 + FPTR IOpenURL_Reserved6 + FPTR IOpenURL_URL_GetPrefsA + FPTR IOpenURL_URL_GetPrefs + FPTR IOpenURL_URL_FreePrefsA + FPTR IOpenURL_URL_FreePrefs + FPTR IOpenURL_URL_SetPrefsA + FPTR IOpenURL_URL_SetPrefs + FPTR IOpenURL_URL_LaunchPrefsAppA + FPTR IOpenURL_URL_LaunchPrefsApp + FPTR IOpenURL_URL_GetAttr + LABEL OpenURLIFace_SIZE + +#endif diff --git a/scalos/include/interfaces/pm.h b/scalos/include/interfaces/pm.h new file mode 100644 index 000000000..f0110a170 --- /dev/null +++ b/scalos/include/interfaces/pm.h @@ -0,0 +1,64 @@ +#ifndef PM_INTERFACE_DEF_H +#define PM_INTERFACE_DEF_H + +/* +** This file was machine generated by idltool 52.1. +** Do not edit +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif + +#ifndef LIBRARIES_PM_H +#include +#endif + +struct PopupMenuIFace +{ + struct InterfaceData Data; + + uint32 APICALL (*Obtain)(struct PopupMenuIFace *Self); + uint32 APICALL (*Release)(struct PopupMenuIFace *Self); + void APICALL (*Expunge)(struct PopupMenuIFace *Self); + struct Interface * APICALL (*Clone)(struct PopupMenuIFace *Self); + struct PopupMenu * APICALL (*PM_MakeMenuA)(struct PopupMenuIFace *Self, struct TagItem * tags); + struct PopupMenu * APICALL (*PM_MakeMenu)(struct PopupMenuIFace *Self, ...); + struct PopupMenu * APICALL (*PM_MakeItemA)(struct PopupMenuIFace *Self, struct TagItem * tags); + struct PopupMenu * APICALL (*PM_MakeItem)(struct PopupMenuIFace *Self, ...); + VOID APICALL (*PM_FreePopupMenu)(struct PopupMenuIFace *Self, struct PopupMenu * menu); + ULONG APICALL (*PM_OpenPopupMenuA)(struct PopupMenuIFace *Self, struct Window * wnd, struct TagItem * tags); + ULONG APICALL (*PM_OpenPopupMenu)(struct PopupMenuIFace *Self, struct Window * wnd, ...); + struct PM_IDLst * APICALL (*PM_MakeIDListA)(struct PopupMenuIFace *Self, struct TagItem * tags); + struct PM_IDLst * APICALL (*PM_MakeIDList)(struct PopupMenuIFace *Self, ...); + BOOL APICALL (*PM_ItemChecked)(struct PopupMenuIFace *Self, struct PopupMenu * pm, ULONG id); + LONG APICALL (*PM_GetItemAttrsA)(struct PopupMenuIFace *Self, struct PopupMenu * item, struct TagItem * tags); + LONG APICALL (*PM_GetItemAttrs)(struct PopupMenuIFace *Self, struct PopupMenu * item, ...); + LONG APICALL (*PM_SetItemAttrsA)(struct PopupMenuIFace *Self, struct PopupMenu * item, struct TagItem * tags); + LONG APICALL (*PM_SetItemAttrs)(struct PopupMenuIFace *Self, struct PopupMenu * item, ...); + struct PopupMenu * APICALL (*PM_FindItem)(struct PopupMenuIFace *Self, struct PopupMenu * menu, ULONG id); + VOID APICALL (*PM_AlterState)(struct PopupMenuIFace *Self, struct PopupMenu * menu, struct PM_IDLst * idlst, UWORD action); + void APICALL (*Reserved1)(struct PopupMenuIFace *Self); + struct PM_IDLst * APICALL (*PM_ExLstA)(struct PopupMenuIFace *Self, ULONG * id); + struct PM_IDLst * APICALL (*PM_ExLst)(struct PopupMenuIFace *Self, ...); + APTR APICALL (*PM_FilterIMsgA)(struct PopupMenuIFace *Self, struct Window * window, struct PopupMenu * menu, struct IntuiMessage * imsg, struct TagItem * tags); + APTR APICALL (*PM_FilterIMsg)(struct PopupMenuIFace *Self, struct Window * window, struct PopupMenu * menu, struct IntuiMessage * imsg, ...); + LONG APICALL (*PM_InsertMenuItemA)(struct PopupMenuIFace *Self, struct PopupMenu * menu, struct TagItem * tags); + LONG APICALL (*PM_InsertMenuItem)(struct PopupMenuIFace *Self, struct PopupMenu * menu, ...); + struct PopupMenu * APICALL (*PM_RemoveMenuItem)(struct PopupMenuIFace *Self, struct PopupMenu * menu, struct PopupMenu * item); + BOOL APICALL (*PM_AbortHook)(struct PopupMenuIFace *Self, APTR handle); + STRPTR APICALL (*PM_GetVersion)(struct PopupMenuIFace *Self); + VOID APICALL (*PM_ReloadPrefs)(struct PopupMenuIFace *Self); + LONG APICALL (*PM_LayoutMenuA)(struct PopupMenuIFace *Self, struct Window * window, struct PopupMenu * menu, struct TagItem * tags); + LONG APICALL (*PM_LayoutMenu)(struct PopupMenuIFace *Self, struct Window * window, struct PopupMenu * menu, ...); + void APICALL (*Reserved2)(struct PopupMenuIFace *Self); + VOID APICALL (*PM_FreeIDList)(struct PopupMenuIFace *Self, struct PM_IDLst * list); +}; + +#endif /* PM_INTERFACE_DEF_H */ diff --git a/scalos/include/interfaces/preferences.h b/scalos/include/interfaces/preferences.h new file mode 100644 index 000000000..c2cc4389b --- /dev/null +++ b/scalos/include/interfaces/preferences.h @@ -0,0 +1,43 @@ +#ifndef PREFERENCES_INTERFACE_DEF_H +#define PREFERENCES_INTERFACE_DEF_H + +/* +** This file was machine generated by idltool 52.1. +** Do not edit +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif + +#ifndef SCALOS_PREFERENCES_H +#include +#endif + +struct PreferencesIFace +{ + struct InterfaceData Data; + + uint32 APICALL (*Obtain)(struct PreferencesIFace *Self); + uint32 APICALL (*Release)(struct PreferencesIFace *Self); + void APICALL (*Expunge)(struct PreferencesIFace *Self); + struct Interface * APICALL (*Clone)(struct PreferencesIFace *Self); + APTR APICALL (*AllocPrefsHandle)(struct PreferencesIFace *Self, CONST_STRPTR name); + VOID APICALL (*FreePrefsHandle)(struct PreferencesIFace *Self, APTR prefsHandle); + VOID APICALL (*SetPreferences)(struct PreferencesIFace *Self, APTR prefsHandle, ULONG iD, ULONG prefsTag, const APTR a1arg, UWORD struct_Size); + ULONG APICALL (*GetPreferences)(struct PreferencesIFace *Self, APTR prefsHandle, ULONG iD, ULONG prefsTag, APTR a1arg, UWORD struct_Size); + VOID APICALL (*ReadPrefsHandle)(struct PreferencesIFace *Self, APTR prefsHandle, CONST_STRPTR filename); + VOID APICALL (*WritePrefsHandle)(struct PreferencesIFace *Self, APTR prefsHandle, CONST_STRPTR filename); + struct PrefsStruct * APICALL (*FindPreferences)(struct PreferencesIFace *Self, APTR prefsHandle, ULONG iD, ULONG prefsTag); + VOID APICALL (*SetEntry)(struct PreferencesIFace *Self, APTR prefsHandle, ULONG iD, ULONG prefsTag, const APTR a1arg, UWORD struct_Size, ULONG entry); + ULONG APICALL (*GetEntry)(struct PreferencesIFace *Self, APTR prefsHandle, ULONG iD, ULONG prefsTag, APTR a1arg, UWORD struct_Size, ULONG entry); + ULONG APICALL (*RemEntry)(struct PreferencesIFace *Self, APTR prefsHandle, ULONG iD, ULONG prefsTag, ULONG entry); +}; + +#endif /* PREFERENCES_INTERFACE_DEF_H */ diff --git a/scalos/include/interfaces/scalos.h b/scalos/include/interfaces/scalos.h new file mode 100755 index 000000000..aa999b627 --- /dev/null +++ b/scalos/include/interfaces/scalos.h @@ -0,0 +1,87 @@ +#ifndef SCALOS_INTERFACE_DEF_H +#define SCALOS_INTERFACE_DEF_H + +/* +** This file was machine generated by idltool 52.1. +** Do not edit +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif + +#ifndef INTUITION_CLASSUSR_H +#include +#endif +#ifndef WORKBENCH_STARTUP_H +#include +#endif +#ifndef SCALOS_SCALOS_H +#include +#endif + +struct ScalosIFace +{ + struct InterfaceData Data; + + uint32 APICALL (*Obtain)(struct ScalosIFace *Self); + uint32 APICALL (*Release)(struct ScalosIFace *Self); + void APICALL (*Expunge)(struct ScalosIFace *Self); + struct Interface * APICALL (*Clone)(struct ScalosIFace *Self); + BOOL APICALL (*SCA_WBStart)(struct ScalosIFace *Self, APTR argArray, CONST struct TagItem * tagList, ULONG numArgs); + BOOL APICALL (*SCA_WBStartTags)(struct ScalosIFace *Self, APTR argArray, ULONG numArgs, ...); + VOID APICALL (*SCA_SortNodes)(struct ScalosIFace *Self, struct ScalosNodeList * nodelist, struct Hook * sortHook, ULONG sortType); + struct AppObject * APICALL (*SCA_NewAddAppIcon)(struct ScalosIFace *Self, ULONG iD, ULONG userData, Object * iconObj, struct MsgPort * msgPort, CONST struct TagItem * tagList); + struct AppObject * APICALL (*SCA_NewAddAppIconTags)(struct ScalosIFace *Self, ULONG iD, ULONG userData, Object * iconObj, struct MsgPort * msgPort, ...); + BOOL APICALL (*SCA_RemoveAppObject)(struct ScalosIFace *Self, struct AppObject * appObj); + struct AppObject * APICALL (*SCA_NewAddAppWindow)(struct ScalosIFace *Self, ULONG iD, ULONG userData, struct Window * win, struct MsgPort * msgPort, CONST struct TagItem * tagList); + struct AppObject * APICALL (*SCA_NewAddAppWindowTags)(struct ScalosIFace *Self, ULONG iD, ULONG userData, struct Window * win, struct MsgPort * msgPort, ...); + struct AppObject * APICALL (*SCA_NewAddAppMenuItem)(struct ScalosIFace *Self, ULONG iD, ULONG userData, CONST_STRPTR text, struct MsgPort * msgPort, CONST struct TagItem * tagList); + struct AppObject * APICALL (*SCA_NewAddAppMenuItemTags)(struct ScalosIFace *Self, ULONG iD, ULONG userData, CONST_STRPTR text, struct MsgPort * msgPort, ...); + struct MinNode * APICALL (*SCA_AllocStdNode)(struct ScalosIFace *Self, struct ScalosNodeList * nodeList, ULONG nodeType); + struct MinNode * APICALL (*SCA_AllocNode)(struct ScalosIFace *Self, struct ScalosNodeList * nodeList, ULONG size); + VOID APICALL (*SCA_FreeNode)(struct ScalosIFace *Self, struct ScalosNodeList * nodeList, struct MinNode * minNode); + VOID APICALL (*SCA_FreeAllNodes)(struct ScalosIFace *Self, struct ScalosNodeList * nodeList); + VOID APICALL (*SCA_MoveNode)(struct ScalosIFace *Self, struct ScalosNodeList * srcNodeList, struct ScalosNodeList * destNodeList, struct MinNode * minNode); + VOID APICALL (*SCA_SwapNodes)(struct ScalosIFace *Self, struct MinNode * minNode1, struct MinNode * minNode2, struct ScalosNodeList * nodeList); + BOOL APICALL (*SCA_OpenIconWindow)(struct ScalosIFace *Self, CONST struct TagItem * tagList); + BOOL APICALL (*SCA_OpenIconWindowTags)(struct ScalosIFace *Self, ...); + struct ScaWindowList * APICALL (*SCA_LockWindowList)(struct ScalosIFace *Self, LONG accessmode); + VOID APICALL (*SCA_UnLockWindowList)(struct ScalosIFace *Self); + struct ScalosMessage * APICALL (*SCA_AllocMessage)(struct ScalosIFace *Self, ULONG messagetype, UWORD additional_size); + VOID APICALL (*SCA_FreeMessage)(struct ScalosIFace *Self, struct ScalosMessage * message); + struct DragHandle * APICALL (*SCA_InitDrag)(struct ScalosIFace *Self, struct Screen * screen); + VOID APICALL (*SCA_EndDrag)(struct ScalosIFace *Self, struct DragHandle * dragHandle); + BOOL APICALL (*SCA_AddBob)(struct ScalosIFace *Self, struct DragHandle * dragHandle, struct BitMap * bm, APTR mask, ULONG width, ULONG height, LONG xOffset, LONG yOffset); + VOID APICALL (*SCA_DrawDrag)(struct ScalosIFace *Self, struct DragHandle * dragHandle, LONG x, LONG y, ULONG flags); + VOID APICALL (*SCA_UpdateIcon)(struct ScalosIFace *Self, UBYTE windowType, APTR updateIconStruct, ULONG ui_SIZE); + ULONG APICALL (*SCA_MakeWBArgs)(struct ScalosIFace *Self, struct WBArg * buffer, struct ScaIconNode * in, ULONG argsSize); + VOID APICALL (*SCA_FreeWBArgs)(struct ScalosIFace *Self, struct WBArg * buffer, ULONG number, ULONG flags); + VOID APICALL (*SCA_RemapBitmap)(struct ScalosIFace *Self, struct BitMap * srcBitmap, struct BitMap * destBitmap, APTR penArray); + VOID APICALL (*SCA_ScreenTitleMsg)(struct ScalosIFace *Self, CONST_STRPTR format, APTR args); + VOID APICALL (*SCA_ScreenTitleMsgArgs)(struct ScalosIFace *Self, CONST_STRPTR format, ...); + struct ScalosClass * APICALL (*SCA_MakeScalosClass)(struct ScalosIFace *Self, CONST_STRPTR className, CONST_STRPTR superClassName, UWORD instSize, APTR dispFunc); + BOOL APICALL (*SCA_FreeScalosClass)(struct ScalosIFace *Self, struct ScalosClass * scalosClass); + Object * APICALL (*SCA_NewScalosObject)(struct ScalosIFace *Self, CONST_STRPTR className, CONST struct TagItem * tagList); + Object * APICALL (*SCA_NewScalosObjectTags)(struct ScalosIFace *Self, CONST_STRPTR className, ...); + VOID APICALL (*SCA_DisposeScalosObject)(struct ScalosIFace *Self, Object * obj); + ULONG APICALL (*SCA_ScalosControlA)(struct ScalosIFace *Self, CONST_STRPTR name, CONST struct TagItem * tagList); + ULONG APICALL (*SCA_ScalosControl)(struct ScalosIFace *Self, CONST_STRPTR name, ...); + ULONG APICALL (*SCA_ScalosControlTags)(struct ScalosIFace *Self, CONST_STRPTR name, ...); + Object * APICALL (*SCA_GetDefIconObject)(struct ScalosIFace *Self, BPTR dirLock, CONST_STRPTR name); + struct ScaWindowStruct * APICALL (*SCA_OpenDrawerByName)(struct ScalosIFace *Self, CONST_STRPTR path, struct TagItem * tagList); + struct ScaWindowStruct * APICALL (*SCA_OpenDrawerByNameTags)(struct ScalosIFace *Self, CONST_STRPTR path, ...); + ULONG APICALL (*SCA_CountWBArgs)(struct ScalosIFace *Self, struct ScaIconNode * in); + Object * APICALL (*SCA_GetDefIconObjectA)(struct ScalosIFace *Self, BPTR dirLock, CONST_STRPTR name, struct TagItem * tagList); + Object * APICALL (*SCA_GetDefIconObjectTags)(struct ScalosIFace *Self, BPTR dirLock, CONST_STRPTR name, ...); + ULONG APICALL (*SCA_LockDrag)(struct ScalosIFace *Self, struct DragHandle * dragHandle); + ULONG APICALL (*SCA_UnlockDrag)(struct ScalosIFace *Self, struct DragHandle * dragHandle); +}; + +#endif /* SCALOS_INTERFACE_DEF_H */ diff --git a/scalos/include/interfaces/scalosfiletypeplugin.h b/scalos/include/interfaces/scalosfiletypeplugin.h new file mode 100644 index 000000000..fc9c157eb --- /dev/null +++ b/scalos/include/interfaces/scalosfiletypeplugin.h @@ -0,0 +1,34 @@ +#ifndef SCALOSFILETYPEPLUGIN_INTERFACE_DEF_H +#define SCALOSFILETYPEPLUGIN_INTERFACE_DEF_H + +/* +** This file was machine generated by idltool 52.1. +** Do not edit +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif + +#ifndef SCALOS_SCALOS_H +#include +#endif + +struct ScalosFileTypePluginIFace +{ + struct InterfaceData Data; + + uint32 APICALL (*Obtain)(struct ScalosFileTypePluginIFace *Self); + uint32 APICALL (*Release)(struct ScalosFileTypePluginIFace *Self); + void APICALL (*Expunge)(struct ScalosFileTypePluginIFace *Self); + struct Interface * APICALL (*Clone)(struct ScalosFileTypePluginIFace *Self); + STRPTR APICALL (*SCAToolTipInfoString)(struct ScalosFileTypePluginIFace *Self, struct ScaToolTipInfoHookData * ttshd, CONST_STRPTR args); +}; + +#endif /* SCALOSFILETYPEPLUGIN_INTERFACE_DEF_H */ diff --git a/scalos/include/interfaces/scalosgfx.h b/scalos/include/interfaces/scalosgfx.h new file mode 100755 index 000000000..fefbe03e0 --- /dev/null +++ b/scalos/include/interfaces/scalosgfx.h @@ -0,0 +1,77 @@ +#ifndef SCALOSGFX_INTERFACE_DEF_H +#define SCALOSGFX_INTERFACE_DEF_H + +/* +** This file was machine generated by idltool 52.1. +** Do not edit +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif + +#ifndef INTUITION_CLASSUSR_H +#include +#endif +#ifndef SCALOS_SCALOS_H +#include +#endif +#ifndef GRAPHICS_GFX_H +#include +#endif +#ifndef SCALOS_SCALOSGFX_H +#include +#endif + +struct ScalosGfxIFace +{ + struct InterfaceData Data; + + uint32 APICALL (*Obtain)(struct ScalosGfxIFace *Self); + uint32 APICALL (*Release)(struct ScalosGfxIFace *Self); + void APICALL (*Expunge)(struct ScalosGfxIFace *Self); + struct Interface * APICALL (*Clone)(struct ScalosGfxIFace *Self); + struct ScalosBitMapAndColor * APICALL (*ScalosGfxCreateEmptySAC)(struct ScalosGfxIFace *Self); + struct ScalosBitMapAndColor * APICALL (*ScalosGfxCreateSAC)(struct ScalosGfxIFace *Self, ULONG width, ULONG height, ULONG depth, struct BitMap * friendBM, struct TagItem * tagList); + struct ScalosBitMapAndColor * APICALL (*ScalosGfxCreateSACTags)(struct ScalosGfxIFace *Self, ULONG width, ULONG height, ULONG depth, struct BitMap * friendBM, ...); + VOID APICALL (*ScalosGfxFreeSAC)(struct ScalosGfxIFace *Self, struct ScalosBitMapAndColor * sac); + struct gfxARGB * APICALL (*ScalosGfxCreateARGB)(struct ScalosGfxIFace *Self, ULONG width, ULONG height, struct TagItem * tagList); + struct gfxARGB * APICALL (*ScalosGfxCreateARGBTags)(struct ScalosGfxIFace *Self, ULONG width, ULONG height, ...); + VOID APICALL (*ScalosGfxFreeARGB)(struct ScalosGfxIFace *Self, struct gfxARGB ** argb); + VOID APICALL (*ScalosGfxARGBSetAlpha)(struct ScalosGfxIFace *Self, struct ARGBHeader * src, UBYTE alpha); + VOID APICALL (*ScalosGfxARGBSetAlphaMask)(struct ScalosGfxIFace *Self, struct ARGBHeader * argbh, PLANEPTR maskPlane); + struct gfxARGB * APICALL (*ScalosGfxCreateARGBFromBitMap)(struct ScalosGfxIFace *Self, struct BitMap * bm, ULONG width, ULONG height, ULONG numberOfColors, const ULONG * colorTable, PLANEPTR maskPlane); + VOID APICALL (*ScalosGfxFillARGBFromBitMap)(struct ScalosGfxIFace *Self, struct ARGBHeader * argbh, struct BitMap * srcBM, PLANEPTR maskPlane); + VOID APICALL (*ScalosGfxWriteARGBToBitMap)(struct ScalosGfxIFace *Self, struct ARGBHeader * argbh, struct BitMap * bm, ULONG numberOfColors, const ULONG * colorTable); + struct ScalosBitMapAndColor * APICALL (*ScalosGfxMedianCut)(struct ScalosGfxIFace *Self, struct ARGBHeader * argbh, ULONG depth, struct TagItem * tagList); + struct ScalosBitMapAndColor * APICALL (*ScalosGfxMedianCutTags)(struct ScalosGfxIFace *Self, struct ARGBHeader * argbh, ULONG depth, ...); + struct gfxARGB * APICALL (*ScalosGfxScaleARGBArray)(struct ScalosGfxIFace *Self, const struct ARGBHeader * src, ULONG * destWidth, ULONG * destHeight, struct TagItem * tagList); + struct gfxARGB * APICALL (*ScalosGfxScaleARGBArrayTags)(struct ScalosGfxIFace *Self, const struct ARGBHeader * src, ULONG * destWidth, ULONG * destHeight, ...); + struct BitMap * APICALL (*ScalosGfxScaleBitMap)(struct ScalosGfxIFace *Self, struct ScaleBitMapArg * sbma, struct TagItem * tagList); + struct BitMap * APICALL (*ScalosGfxScaleBitMapTags)(struct ScalosGfxIFace *Self, struct ScaleBitMapArg * sbma, ...); + VOID APICALL (*ScalosGfxCalculateScaleAspect)(struct ScalosGfxIFace *Self, ULONG sourceWidth, ULONG sourceHeight, ULONG * destWidth, ULONG * destHeight); + VOID APICALL (*ScalosGfxBlitARGB)(struct ScalosGfxIFace *Self, struct ARGBHeader * destARGB, const struct ARGBHeader * srcARGB, LONG destLeft, LONG destTop, LONG srcLeft, LONG srcTop, LONG width, LONG height); + VOID APICALL (*ScalosGfxFillRectARGB)(struct ScalosGfxIFace *Self, struct ARGBHeader * destARGB, const struct gfxARGB * fillARGB, LONG left, LONG top, LONG width, LONG height); + VOID APICALL (*ScalosGfxSetARGB)(struct ScalosGfxIFace *Self, struct ARGBHeader * destARGB, const struct gfxARGB * fillARGB); + BOOL APICALL (*ScalosGfxNewColorMap)(struct ScalosGfxIFace *Self, struct ScalosBitMapAndColor * sac, const ULONG * colorMap, ULONG colorEntries); + VOID APICALL (*ScalosGfxARGBRectMult)(struct ScalosGfxIFace *Self, struct RastPort * rp, const struct gfxARGB * numerator, const struct gfxARGB * denominator, WORD xMin, WORD yMin, WORD xMax, WORD yMax); + VOID APICALL (*ScalosGfxBlitARGBAlpha)(struct ScalosGfxIFace *Self, struct RastPort * rp, const struct ARGBHeader * srcH, ULONG destLeft, ULONG destTop, ULONG srcLeft, ULONG srcTop, ULONG width, ULONG height); + VOID APICALL (*ScalosGfxBlitARGBAlphaTagList)(struct ScalosGfxIFace *Self, struct RastPort * rp, const struct ARGBHeader * srcH, ULONG destLeft, ULONG destTop, const struct IBox * srcSize, struct TagItem * tagList); + VOID APICALL (*ScalosGfxBlitARGBAlphaTags)(struct ScalosGfxIFace *Self, struct RastPort * rp, const struct ARGBHeader * srcH, ULONG destLeft, ULONG destTop, const struct IBox * srcSize, ...); + VOID APICALL (*ScalosGfxBlitIcon)(struct ScalosGfxIFace *Self, struct RastPort * rpBackground, struct RastPort * rpIcon, ULONG left, ULONG top, ULONG width, ULONG height, struct TagItem * tagList); + VOID APICALL (*ScalosGfxBlitIconTags)(struct ScalosGfxIFace *Self, struct RastPort * rpBackground, struct RastPort * rpIcon, ULONG left, ULONG top, ULONG width, ULONG height, ...); + BOOL APICALL (*ScalosGfxDrawGradient)(struct ScalosGfxIFace *Self, struct ARGBHeader * dest, LONG left, LONG top, LONG width, LONG height, struct gfxARGB * start, struct gfxARGB * stop, ULONG gradType); + BOOL APICALL (*ScalosGfxDrawGradientRastPort)(struct ScalosGfxIFace *Self, struct RastPort * rp, LONG left, LONG top, LONG width, LONG height, struct gfxARGB * start, struct gfxARGB * stop, ULONG gradType); + VOID APICALL (*ScalosGfxDrawLine)(struct ScalosGfxIFace *Self, struct ARGBHeader * dest, LONG fromX, LONG fromY, LONG toX, LONG toY, const struct gfxARGB * lineColor); + VOID APICALL (*ScalosGfxDrawLineRastPort)(struct ScalosGfxIFace *Self, struct RastPort * rp, LONG fromX, LONG fromY, LONG toX, LONG toY, const struct gfxARGB * lineColor); + VOID APICALL (*ScalosGfxDrawEllipse)(struct ScalosGfxIFace *Self, struct ARGBHeader * dest, LONG xCenter, LONG yCenter, LONG radiusX, LONG radiusy, WORD segment, const struct gfxARGB * color1, const struct gfxARGB * color2); + VOID APICALL (*ScalosGfxDrawEllipseRastPort)(struct ScalosGfxIFace *Self, struct RastPort * rp, LONG xCenter, LONG yCenter, LONG radiusX, LONG radiusy, WORD segment, const struct gfxARGB * color1, const struct gfxARGB * color2); +}; + +#endif /* SCALOSGFX_INTERFACE_DEF_H */ diff --git a/scalos/include/interfaces/scalosmenuplugin.h b/scalos/include/interfaces/scalosmenuplugin.h new file mode 100644 index 000000000..3ac10c889 --- /dev/null +++ b/scalos/include/interfaces/scalosmenuplugin.h @@ -0,0 +1,41 @@ +#ifndef SCALOSMENUPLUGIN_INTERFACE_DEF_H +#define SCALOSMENUPLUGIN_INTERFACE_DEF_H + +/* +** This file was machine generated by idltool 51.3. +** Do not edit +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif +#ifndef INTUITION_CLASSUSR_H +#include +#endif +#ifndef WORKBENCH_STARTUP_H +#include +#endif +#ifndef SCALOS_SCALOS_H +#include +#endif + + +struct ScalosMenuPluginIFace + { + struct InterfaceData Data; + + ULONG APICALL (*Obtain)(struct ScalosMenuPluginIFace *Self); + ULONG APICALL (*Release)(struct ScalosMenuPluginIFace *Self); + void APICALL (*Expunge)(struct ScalosMenuPluginIFace *Self); + struct Interface * APICALL (*Clone)(struct ScalosMenuPluginIFace *Self); + + void APICALL (*SCAMenuFunction)(struct ScalosMenuPluginIFace *self, struct ScaWindowTask *wt, struct ScaIconNode *in); + }; + +#endif /* SCALOSMENUPLUGIN_INTERFACE_DEF_H */ diff --git a/scalos/include/interfaces/scalosplugin.h b/scalos/include/interfaces/scalosplugin.h new file mode 100644 index 000000000..a2d521daa --- /dev/null +++ b/scalos/include/interfaces/scalosplugin.h @@ -0,0 +1,45 @@ +#ifndef SCALOSPLUGIN_INTERFACE_DEF_H +#define SCALOSPLUGIN_INTERFACE_DEF_H + +/* +** This file was machine generated by idltool 52.7. +** Do not edit +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif + + +#ifdef __cplusplus +#ifdef __USE_AMIGAOS_NAMESPACE__ +namespace AmigaOS { +#endif +extern "C" { +#endif + +struct ScalosPluginIFace +{ + struct InterfaceData Data; + + ULONG APICALL (*Obtain)(struct ScalosPluginIFace *Self); + ULONG APICALL (*Release)(struct ScalosPluginIFace *Self); + void APICALL (*Expunge)(struct ScalosPluginIFace *Self); + struct Interface * APICALL (*Clone)(struct ScalosPluginIFace *Self); + const struct ScaClassInfo * APICALL (*SCAGetClassInfo)(struct ScalosPluginIFace *Self); +}; + +#ifdef __cplusplus +} +#ifdef __USE_AMIGAOS_NAMESPACE__ +} +#endif +#endif + +#endif /* SCALOSPLUGIN_INTERFACE_DEF_H */ diff --git a/scalos/include/interfaces/scalosprefsplugin.h b/scalos/include/interfaces/scalosprefsplugin.h new file mode 100755 index 000000000..ca9be8e96 --- /dev/null +++ b/scalos/include/interfaces/scalosprefsplugin.h @@ -0,0 +1,31 @@ +#ifndef SCALOSPREFSPLUGIN_INTERFACE_DEF_H +#define SCALOSPREFSPLUGIN_INTERFACE_DEF_H + +/* +** This file was machine generated by idltool 52.1. +** Do not edit +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif + + +struct ScalosPrefsPluginIFace +{ + struct InterfaceData Data; + + uint32 APICALL (*Obtain)(struct ScalosPrefsPluginIFace *Self); + uint32 APICALL (*Release)(struct ScalosPrefsPluginIFace *Self); + void APICALL (*Expunge)(struct ScalosPrefsPluginIFace *Self); + struct Interface * APICALL (*Clone)(struct ScalosPrefsPluginIFace *Self); + ULONG APICALL (*SCAGetPrefsInfo)(struct ScalosPrefsPluginIFace *Self, LONG which); +}; + +#endif /* SCALOSPREFSPLUGIN_INTERFACE_DEF_H */ diff --git a/scalos/include/interfaces/scalospreviewplugin.h b/scalos/include/interfaces/scalospreviewplugin.h new file mode 100644 index 000000000..9a2e4d16a --- /dev/null +++ b/scalos/include/interfaces/scalospreviewplugin.h @@ -0,0 +1,38 @@ +#ifndef SCALOSPREVIEWPLUGIN_INTERFACE_DEF_H +#define SCALOSPREVIEWPLUGIN_INTERFACE_DEF_H + +/* +** This file was machine generated by idltool 52.1. +** Do not edit +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif + +#ifndef SCALOS_SCALOS_H +#include +#endif +#ifndef UTILITY_TAGITEM_H +#include +#endif + +struct ScalosPreviewPluginIFace +{ + struct InterfaceData Data; + + uint32 APICALL (*Obtain)(struct ScalosPreviewPluginIFace *Self); + uint32 APICALL (*Release)(struct ScalosPreviewPluginIFace *Self); + void APICALL (*Expunge)(struct ScalosPreviewPluginIFace *Self); + struct Interface * APICALL (*Clone)(struct ScalosPreviewPluginIFace *Self); + LONG APICALL (*SCAPreviewGenerate)(struct ScalosPreviewPluginIFace *Self, struct ScaWindowTask * wt, BPTR dirLock, CONST_STRPTR iconName, struct TagItem * tagList); + LONG APICALL (*SCAPreviewGenerateTags)(struct ScalosPreviewPluginIFace *Self, struct ScaWindowTask * wt, BPTR dirLock, CONST_STRPTR iconName, ...); +}; + +#endif /* SCALOSPREVIEWPLUGIN_INTERFACE_DEF_H */ diff --git a/scalos/include/interfaces/sqlite3.h b/scalos/include/interfaces/sqlite3.h new file mode 100755 index 000000000..7208ee1af --- /dev/null +++ b/scalos/include/interfaces/sqlite3.h @@ -0,0 +1,133 @@ +#ifndef SQLITE3_INTERFACE_DEF_H +#define SQLITE3_INTERFACE_DEF_H + +/* +** This file was machine generated by idltool 52.1. +** Do not edit +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif + +#ifndef SQLITE3_H +#include +#endif + +struct SQLite3IFace +{ + struct InterfaceData Data; + + uint32 APICALL (*Obtain)(struct SQLite3IFace *Self); + uint32 APICALL (*Release)(struct SQLite3IFace *Self); + void APICALL (*Expunge)(struct SQLite3IFace *Self); + struct Interface * APICALL (*Clone)(struct SQLite3IFace *Self); + LONG APICALL (*SQLite3Close)(struct SQLite3IFace *Self, sqlite3 * db); + LONG APICALL (*SQLite3Exec)(struct SQLite3IFace *Self, sqlite3 * db, CONST_STRPTR sql, sqlite3_callback xCallback, APTR pArg, STRPTR * errmsg); + LONG APICALL (*SQLite3Changes)(struct SQLite3IFace *Self, sqlite3 * db); + LONG APICALL (*SQLite3TotalChanges)(struct SQLite3IFace *Self, sqlite3 * db); + VOID APICALL (*SQLite3Interrupt)(struct SQLite3IFace *Self, sqlite3 * db); + LONG APICALL (*SQLite3Complete)(struct SQLite3IFace *Self, CONST_STRPTR sql); + LONG APICALL (*SQLite3BusyHandler)(struct SQLite3IFace *Self, sqlite3 * db, LONG (*callback)(APTR userdata, LONG l), APTR userdata); + LONG APICALL (*SQLite3BusyTimeout)(struct SQLite3IFace *Self, sqlite3 * db, LONG ms); + LONG APICALL (*SQLite3GetTable)(struct SQLite3IFace *Self, sqlite3 * db, CONST_STRPTR sql, STRPTR ** presult, LONG * nrow, LONG * ncolumn, STRPTR * errmsg); + VOID APICALL (*SQLite3FreeTable)(struct SQLite3IFace *Self, STRPTR * result); + VOID APICALL (*SQLite3Free)(struct SQLite3IFace *Self, STRPTR z); + APTR APICALL (*SQLite3Trace)(struct SQLite3IFace *Self, sqlite3 * db, VOID (*xTrace)(APTR p, CONST_STRPTR z), APTR parg); + VOID APICALL (*SQLite3ProgressHandler)(struct SQLite3IFace *Self, sqlite3 * db, LONG nOps, LONG (*xProgress)(APTR p), APTR pArg); + APTR APICALL (*SQLite3CommitHook)(struct SQLite3IFace *Self, sqlite3 * db, LONG (*xCallback)(APTR p), APTR pArg); + LONG APICALL (*SQLite3Open)(struct SQLite3IFace *Self, CONST_STRPTR filename, sqlite3 ** ppDb); + LONG APICALL (*SQLite3Errcode)(struct SQLite3IFace *Self, sqlite3 * db); + CONST_STRPTR APICALL (*SQLite3Errmsg)(struct SQLite3IFace *Self, sqlite3 * db); + LONG APICALL (*SQLite3Prepare)(struct SQLite3IFace *Self, sqlite3 * db, CONST_STRPTR zSql, LONG nBytes, sqlite3_stmt ** ppStmt, CONST_STRPTR * pzTail); + LONG APICALL (*SQLite3BindBlob)(struct SQLite3IFace *Self, sqlite3_stmt * pStmt, LONG i, CONST_APTR zData, LONG nData, VOID (*xDel)(APTR p)); + LONG APICALL (*SQLite3BindInt)(struct SQLite3IFace *Self, sqlite3_stmt * pStmt, LONG i, LONG iValue); + LONG APICALL (*SQLite3BindNull)(struct SQLite3IFace *Self, sqlite3_stmt * pStmt, LONG i); + LONG APICALL (*SQLite3BindText)(struct SQLite3IFace *Self, sqlite3_stmt * pStmt, LONG i, CONST_STRPTR zData, LONG nData, VOID (*xDel)(APTR p)); + LONG APICALL (*SQLite3BindValue)(struct SQLite3IFace *Self, sqlite3_stmt * pStmt, LONG i, CONST sqlite3_value * pVal); + LONG APICALL (*SQLite3BindParameterCount)(struct SQLite3IFace *Self, sqlite3_stmt * pStmt); + CONST_STRPTR APICALL (*SQLite3BindParameterName)(struct SQLite3IFace *Self, sqlite3_stmt * pStmt, LONG i); + LONG APICALL (*SQLite3BindParameterIndex)(struct SQLite3IFace *Self, sqlite3_stmt * pStmt, CONST_STRPTR zName); + LONG APICALL (*SQLite3ClearBindings)(struct SQLite3IFace *Self, sqlite3_stmt * pStmt); + LONG APICALL (*SQLite3ColumnCount)(struct SQLite3IFace *Self, sqlite3_stmt * pStmt); + CONST_STRPTR APICALL (*SQLite3ColumnName)(struct SQLite3IFace *Self, sqlite3_stmt * pStmt, LONG i); + CONST_STRPTR APICALL (*SQLite3ColumnDecltype)(struct SQLite3IFace *Self, sqlite3_stmt * pStmt, LONG i); + LONG APICALL (*SQLite3Step)(struct SQLite3IFace *Self, sqlite3_stmt * pStmt); + LONG APICALL (*SQLite3DataCount)(struct SQLite3IFace *Self, sqlite3_stmt * pStmt); + CONST_APTR APICALL (*SQLite3ColumnBlob)(struct SQLite3IFace *Self, sqlite3_stmt * pStmt, LONG iCol); + LONG APICALL (*SQLite3ColumnBytes)(struct SQLite3IFace *Self, sqlite3_stmt * pStmt, LONG iCol); + LONG APICALL (*SQLite3ColumnInt)(struct SQLite3IFace *Self, sqlite3_stmt * pStmt, LONG iCol); + CONST_STRPTR APICALL (*SQLite3ColumnText)(struct SQLite3IFace *Self, sqlite3_stmt * pStmt, LONG iCol); + LONG APICALL (*SQLite3ColumnType)(struct SQLite3IFace *Self, sqlite3_stmt * pStmt, LONG iCol); + LONG APICALL (*SQLite3Finalize)(struct SQLite3IFace *Self, sqlite3_stmt * pStmt); + LONG APICALL (*SQLite3Reset)(struct SQLite3IFace *Self, sqlite3_stmt * pStmt); + LONG APICALL (*SQLite3AggregateCount)(struct SQLite3IFace *Self, sqlite3_context * pCtx); + CONST_APTR APICALL (*SQLite3ValueBlob)(struct SQLite3IFace *Self, sqlite3_value * pVal); + LONG APICALL (*SQLite3ValueBytes)(struct SQLite3IFace *Self, sqlite3_value * pVal); + LONG APICALL (*SQLite3ValueInt)(struct SQLite3IFace *Self, sqlite3_value * pVal); + CONST_STRPTR APICALL (*SQLite3ValueText)(struct SQLite3IFace *Self, sqlite3_value * pVal); + LONG APICALL (*SQLite3ValueType)(struct SQLite3IFace *Self, sqlite3_value * pVal); + APTR APICALL (*SQLite3Aggregate_context)(struct SQLite3IFace *Self, sqlite3_context * pCtx, LONG nBytes); + APTR APICALL (*SQLite3UserData)(struct SQLite3IFace *Self, sqlite3_context * pCtx); + APTR APICALL (*SQLite3GetAuxdata)(struct SQLite3IFace *Self, sqlite3_context * pCtx, LONG iArg); + VOID APICALL (*SQLite3SetAuxdata)(struct SQLite3IFace *Self, sqlite3_context * pCtx, LONG iARg, APTR pAux, VOID (*xDelete)(APTR p)); + VOID APICALL (*SQLite3ResultBlob)(struct SQLite3IFace *Self, sqlite3_context * pCtx, CONST_APTR z, LONG n, VOID (*xDelete)(APTR p)); + VOID APICALL (*SQLite3ResultError)(struct SQLite3IFace *Self, sqlite3_context * pCtx, CONST_STRPTR z, LONG n); + VOID APICALL (*SQLite3ResultInt)(struct SQLite3IFace *Self, sqlite3_context * pCtx, LONG iVal); + VOID APICALL (*SQLite3ResultNull)(struct SQLite3IFace *Self, sqlite3_context * pCtx); + VOID APICALL (*SQLite3ResultText)(struct SQLite3IFace *Self, sqlite3_context * pCtx, CONST_STRPTR z, LONG n, VOID (*xDelete)(APTR p)); + VOID APICALL (*SQLite3ResultValue)(struct SQLite3IFace *Self, sqlite3_context * pCtx, sqlite3_value * pValue); + LONG APICALL (*SQLite3CreateCollation)(struct SQLite3IFace *Self, sqlite3 * db, CONST_STRPTR zName, LONG eTextRep, APTR pCtx, LONG (*xCompare)(APTR p, LONG i, CONST_APTR p2, LONG j, CONST_APTR p3)); + LONG APICALL (*SQLite3CollationNeeded)(struct SQLite3IFace *Self, sqlite3 * db, APTR pCollNeededArg, VOID (*xCollNeeded)(APTR p, sqlite3 *dv, LONG eTextRep, CONST_STRPTR z)); + LONG APICALL (*SQLite3Sleep)(struct SQLite3IFace *Self, LONG ms); + LONG APICALL (*SQLite3Expired)(struct SQLite3IFace *Self, sqlite3_stmt * pStmt); + LONG APICALL (*SQLite3TransferBindings)(struct SQLite3IFace *Self, sqlite3_stmt * pFromStmt, sqlite3_stmt * pToStmt); + LONG APICALL (*SQLite3GlobalRecover)(struct SQLite3IFace *Self); + LONG APICALL (*SQLite3GetAutocommit)(struct SQLite3IFace *Self, sqlite3 * db); + sqlite3 * APICALL (*SQLite3DbHandle)(struct SQLite3IFace *Self, sqlite3_stmt * pStmt); + APTR APICALL (*SQLite3RollbackHook)(struct SQLite3IFace *Self, sqlite3 * db, VOID (*callback)(APTR pUserData), APTR pUserData); + LONG APICALL (*SQLite3EnableSharedCache)(struct SQLite3IFace *Self, BOOL enable); + LONG APICALL (*SQLite3ReleaseMemory)(struct SQLite3IFace *Self, LONG bytesCount); + VOID APICALL (*SQLite3SoftHeapLimit)(struct SQLite3IFace *Self, LONG maxBytes); + VOID APICALL (*SQLite3ThreadCleanup)(struct SQLite3IFace *Self); + LONG APICALL (*SQLite3PrepareV2)(struct SQLite3IFace *Self, sqlite3 * db, CONST_STRPTR zSql, LONG nBytes, sqlite3_stmt ** ppStmt, CONST_STRPTR * pzTail); + LONG APICALL (*SQLite3CreateFunction)(struct SQLite3IFace *Self, sqlite3 * db, CONST_STRPTR zFunctionName, LONG nArg, LONG eTextRep, APTR userdata, VOID (*xFunc)(sqlite3_context *pCtx, LONG i, sqlite3_value **pVal), VOID (*xStep)(sqlite3_context *pCtx, LONG i, sqlite3_value **pVal), VOID (*xFinal)(sqlite3_context *pCtx)); + LONG APICALL (*SQLite3CreateModule)(struct SQLite3IFace *Self, sqlite3 * db, CONST_STRPTR zName, CONST sqlite3_module * methods, APTR clientData); + LONG APICALL (*SQLite3DeclareVtab)(struct SQLite3IFace *Self, sqlite3 * db, CONST_STRPTR zCreateTable); + LONG APICALL (*SQLite3OverloadFunction)(struct SQLite3IFace *Self, sqlite3 * db, CONST_STRPTR zFuncName, LONG nArg); + LONG APICALL (*SQLite3BlobOpen)(struct SQLite3IFace *Self, sqlite3 * db, CONST_STRPTR zDb, CONST_STRPTR zTable, CONST_STRPTR zColumn, LONG iRow, LONG flags, sqlite3_blob ** ppBlob); + LONG APICALL (*SQLite3BlobClose)(struct SQLite3IFace *Self, sqlite3_blob * blob); + LONG APICALL (*SQLite3BlobBytes)(struct SQLite3IFace *Self, sqlite3_blob * blob); + LONG APICALL (*SQLite3BlobRead)(struct SQLite3IFace *Self, sqlite3_blob * blob, APTR z, LONG n, LONG iOffset); + LONG APICALL (*SQLite3BlobWrite)(struct SQLite3IFace *Self, sqlite3_blob * blob, CONST_APTR z, LONG n, LONG iOffset); + LONG APICALL (*SQLite3ExtendedResultCodes)(struct SQLite3IFace *Self, sqlite3 * db, LONG onoff); + LONG APICALL (*SQLite3BindZeroBlob)(struct SQLite3IFace *Self, sqlite3_stmt * pStmt, LONG i, LONG n); + CONST_STRPTR APICALL (*SQLite3ColumnDatabaseName)(struct SQLite3IFace *Self, sqlite3_stmt * stmt, LONG n); + CONST_STRPTR APICALL (*SQLite3ColumnTableName)(struct SQLite3IFace *Self, sqlite3_stmt * stmt, LONG n); + CONST_STRPTR APICALL (*SQLite3ColumnOriginName)(struct SQLite3IFace *Self, sqlite3_stmt * stmt, LONG n); + sqlite3_value * APICALL (*SQLite3ColumnValue)(struct SQLite3IFace *Self, sqlite3_stmt * pStmt, LONG iCol); + LONG APICALL (*SQLite3CreateCollationV2)(struct SQLite3IFace *Self, sqlite3 * db, CONST_STRPTR zName, LONG eTextRep, APTR pCtx, LONG (*xCompare)(APTR p, LONG i, CONST_APTR p2, LONG j, CONST_APTR p3), VOID (*xDestroy)(APTR)); + CONST_STRPTR APICALL (*SQLite3LibVersion)(struct SQLite3IFace *Self); + LONG APICALL (*SQLite3LibversionNumber)(struct SQLite3IFace *Self); + VOID APICALL (*SQLite3ResultErrorToobig)(struct SQLite3IFace *Self, sqlite3_context * pCtx); + VOID APICALL (*SQLite3ResultZeroBlob)(struct SQLite3IFace *Self, sqlite3_context * pCtx, LONG n); + LONG APICALL (*SQLite3ValueNumericType)(struct SQLite3IFace *Self, sqlite3_value * pVal); + LONG APICALL (*SQLite3ConfigV)(struct SQLite3IFace *Self, LONG op, APTR ap); + LONG APICALL (*SQLite3Config)(struct SQLite3IFace *Self, LONG op, ...); + LONG APICALL (*SQLlite3DbConfigV)(struct SQLite3IFace *Self, sqlite3 * db, LONG op, APTR ap); + LONG APICALL (*SQLlite3DbConfig)(struct SQLite3IFace *Self, sqlite3 * db, LONG op, ...); + sqlite3_vfs * APICALL (*SQLite3VfsFind)(struct SQLite3IFace *Self, CONST_STRPTR zVfsName); + LONG APICALL (*SQLite3VfsRegister)(struct SQLite3IFace *Self, sqlite3_vfs * vfs, LONG makeDflt); + LONG APICALL (*SQLite3VfsUnregister)(struct SQLite3IFace *Self, sqlite3_vfs * vfs); + LONG APICALL (*SQLite3FileControl)(struct SQLite3IFace *Self, sqlite3 * db, CONST_STRPTR zDbName, LONG op, void * arg); + LONG APICALL (*SQLite3Status)(struct SQLite3IFace *Self, LONG op, LONG * pCurrent, LONG * pHighwater, LONG resetFlag); + LONG APICALL (*SQLite3DbStatus)(struct SQLite3IFace *Self, sqlite3 * db, LONG op, LONG * pCur, LONG * pHiwtr, LONG resetFlg); +}; + +#endif /* SQLITE3_INTERFACE_DEF_H */ diff --git a/scalos/include/interfaces/ttengine.h b/scalos/include/interfaces/ttengine.h new file mode 100644 index 000000000..8dae50d8e --- /dev/null +++ b/scalos/include/interfaces/ttengine.h @@ -0,0 +1,62 @@ +#ifndef TTENGINE_INTERFACE_DEF_H +#define TTENGINE_INTERFACE_DEF_H + +/* +** This file was machine generated by idltool 51.3. +** Do not edit +*/ + +#ifndef EXEC_TYPES_H +#include +#endif +#ifndef EXEC_EXEC_H +#include +#endif +#ifndef EXEC_INTERFACES_H +#include +#endif + +#ifndef UTILITY_TAGITEM_H +#include +#endif +#ifndef LIBRARIES_TTENGINE_H +#include +#endif +#ifndef GRAPHICS_TEXT_H +#include +#endif + +struct TTEngineIFace +{ + struct InterfaceData Data; + + ULONG APICALL (*Obtain)(struct TTEngineIFace *Self); + ULONG APICALL (*Release)(struct TTEngineIFace *Self); + void APICALL (*Expunge)(struct TTEngineIFace *Self); + struct Interface * APICALL (*Clone)(struct TTEngineIFace *Self); + APTR APICALL (*TT_OpenFontA)(struct TTEngineIFace *Self, struct TagItem * taglist); + APTR APICALL (*TT_OpenFont)(struct TTEngineIFace *Self, ...); + BOOL APICALL (*TT_SetFont)(struct TTEngineIFace *Self, struct RastPort * rp, APTR font); + VOID APICALL (*TT_CloseFont)(struct TTEngineIFace *Self, APTR font); + VOID APICALL (*TT_Text)(struct TTEngineIFace *Self, struct RastPort * rp, APTR string, ULONG count); + ULONG APICALL (*TT_SetAttrsA)(struct TTEngineIFace *Self, struct RastPort * rp, struct TagItem * taglist); + ULONG APICALL (*TT_SetAttrs)(struct TTEngineIFace *Self, struct RastPort * rp, ...); + ULONG APICALL (*TT_GetAttrsA)(struct TTEngineIFace *Self, struct RastPort * rp, struct TagItem * taglist); + ULONG APICALL (*TT_GetAttrs)(struct TTEngineIFace *Self, struct RastPort * rp, ...); + ULONG APICALL (*TT_TextLength)(struct TTEngineIFace *Self, struct RastPort * rp, APTR string, ULONG count); + VOID APICALL (*TT_TextExtent)(struct TTEngineIFace *Self, struct RastPort * rp, APTR string, WORD count, struct TextExtent * te); + ULONG APICALL (*TT_TextFit)(struct TTEngineIFace *Self, struct RastPort * rp, APTR string, UWORD count, struct TextExtent * te, struct TextExtent * tec, WORD dir, UWORD cwidth, UWORD cheight); + struct TT_Pixmap * APICALL (*TT_GetPixmapA)(struct TTEngineIFace *Self, APTR font, APTR string, ULONG count, struct TagItem * taglist); + struct TT_Pixmap * APICALL (*TT_GetPixmap)(struct TTEngineIFace *Self, APTR font, APTR string, ULONG count, ...); + VOID APICALL (*TT_FreePixmap)(struct TTEngineIFace *Self, struct TT_Pixmap * pixmap); + VOID APICALL (*TT_DoneRastPort)(struct TTEngineIFace *Self, struct RastPort * rp); + APTR APICALL (*TT_AllocRequest)(struct TTEngineIFace *Self); + struct TagItem * APICALL (*TT_RequestA)(struct TTEngineIFace *Self, APTR request, struct TagItem * taglist); + struct TagItem * APICALL (*TT_Request)(struct TTEngineIFace *Self, APTR request, ...); + VOID APICALL (*TT_FreeRequest)(struct TTEngineIFace *Self, APTR request); + STRPTR * APICALL (*TT_ObtainFamilyListA)(struct TTEngineIFace *Self, struct TagItem * taglist); + STRPTR * APICALL (*TT_ObtainFamilyList)(struct TTEngineIFace *Self, ...); + VOID APICALL (*TT_FreeFamilyList)(struct TTEngineIFace *Self, STRPTR * list); +}; + +#endif /* TTENGINE_INTERFACE_DEF_H */ diff --git a/scalos/include/intuition/newmouse.h b/scalos/include/intuition/newmouse.h new file mode 100755 index 000000000..bd4e66b84 --- /dev/null +++ b/scalos/include/intuition/newmouse.h @@ -0,0 +1,31 @@ +/* + * Include file for the NewMouse standard way of handling wheeled mice. + * + * Copyright (c) 1999 by Alessandro Zummo . All Rights Reserved. +*/ + +#ifndef NEWMOUSE_H +#define NEWMOUSE_H + +#if !defined(__MORPHOS__) + +#define NEWMOUSE_VERSION 1 + +#ifndef IECLASS_NEWMOUSE +#define IECLASS_NEWMOUSE (0x16) /* IECLASS_MAX + 1 as of V40 */ +#endif + +/* These are issued both under IECLASS_NEWMOUSE and IECLASS_RAWKEY */ +/* by the NewMouse driver */ + +#define NM_WHEEL_UP (0x7A) +#define NM_WHEEL_DOWN (0x7B) +#define NM_WHEEL_LEFT (0x7C) +#define NM_WHEEL_RIGHT (0x7D) + +#define NM_BUTTON_FOURTH (0x7E) + +#endif /* __MORPHOS__ */ + +#endif /* NEWMOUSE_H */ + diff --git a/scalos/include/jconfig.h b/scalos/include/jconfig.h new file mode 100644 index 000000000..9850a4a2b --- /dev/null +++ b/scalos/include/jconfig.h @@ -0,0 +1,46 @@ +/* jconfig.h. Generated from jconfig.cfg by configure. */ +/* jconfig.cfg --- source file edited by configure script */ +/* see jconfig.txt for explanations */ + +#define HAVE_PROTOTYPES +#define HAVE_UNSIGNED_CHAR +#define HAVE_UNSIGNED_SHORT +#undef void +#undef const +#define CHAR_IS_UNSIGNED +#define HAVE_STDDEF_H +#define HAVE_STDLIB_H +#define HAVE_LOCALE_H +#undef NEED_BSD_STRINGS +#undef NEED_SYS_TYPES_H +#undef NEED_FAR_POINTERS +#undef NEED_SHORT_EXTERNAL_NAMES +/* Define this if you get warnings about undefined structures. */ +#undef INCOMPLETE_TYPES_BROKEN + +#ifdef JPEG_INTERNALS + +#undef RIGHT_SHIFT_IS_UNSIGNED +#define INLINE __inline__ +/* These are for configuring the JPEG memory manager. */ +#undef DEFAULT_MAX_MEM +#undef NO_MKTEMP + +#endif /* JPEG_INTERNALS */ + +#ifdef JPEG_CJPEG_DJPEG + +#define BMP_SUPPORTED /* BMP image file format */ +#define GIF_SUPPORTED /* GIF image file format */ +#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */ +#undef RLE_SUPPORTED +#define TARGA_SUPPORTED /* Targa image file format */ + +#undef TWO_FILE_COMMANDLINE +#undef NEED_SIGNAL_CATCHER +#undef DONT_USE_B_MODE + +/* Define this if you want percent-done progress reports from cjpeg/djpeg. */ +#undef PROGRESS_REPORT + +#endif /* JPEG_CJPEG_DJPEG */ diff --git a/scalos/include/jerror.h b/scalos/include/jerror.h new file mode 100644 index 000000000..a4b661f71 --- /dev/null +++ b/scalos/include/jerror.h @@ -0,0 +1,304 @@ +/* + * jerror.h + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * Modified 1997-2012 by Guido Vollbeding. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file defines the error and message codes for the JPEG library. + * Edit this file to add new codes, or to translate the message strings to + * some other language. + * A set of error-reporting macros are defined too. Some applications using + * the JPEG library may wish to include this file to get the error codes + * and/or the macros. + */ + +/* + * To define the enum list of message codes, include this file without + * defining macro JMESSAGE. To create a message string table, include it + * again with a suitable JMESSAGE definition (see jerror.c for an example). + */ +#ifndef JMESSAGE +#ifndef JERROR_H +/* First time through, define the enum list */ +#define JMAKE_ENUM_LIST +#else +/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */ +#define JMESSAGE(code,string) +#endif /* JERROR_H */ +#endif /* JMESSAGE */ + +#ifdef JMAKE_ENUM_LIST + +typedef enum { + +#define JMESSAGE(code,string) code , + +#endif /* JMAKE_ENUM_LIST */ + +JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */ + +/* For maintenance convenience, list is alphabetical by message code name */ +JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix") +JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix") +JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode") +JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS") +JMESSAGE(JERR_BAD_CROP_SPEC, "Invalid crop request") +JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range") +JMESSAGE(JERR_BAD_DCTSIZE, "DCT scaled block size %dx%d not supported") +JMESSAGE(JERR_BAD_DROP_SAMPLING, + "Component index %d: mismatching sampling ratio %d:%d, %d:%d, %c") +JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition") +JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace") +JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace") +JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length") +JMESSAGE(JERR_BAD_LIB_VERSION, + "Wrong JPEG library version: library is %d, caller expects %d") +JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan") +JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d") +JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d") +JMESSAGE(JERR_BAD_PROGRESSION, + "Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d") +JMESSAGE(JERR_BAD_PROG_SCRIPT, + "Invalid progressive parameters at scan script entry %d") +JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors") +JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d") +JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d") +JMESSAGE(JERR_BAD_STRUCT_SIZE, + "JPEG parameter struct mismatch: library thinks size is %u, caller expects %u") +JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access") +JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small") +JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here") +JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet") +JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d") +JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request") +JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d") +JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x") +JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d") +JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d") +JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)") +JMESSAGE(JERR_EMS_READ, "Read from EMS failed") +JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed") +JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan") +JMESSAGE(JERR_FILE_READ, "Input file read error") +JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?") +JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet") +JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow") +JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry") +JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels") +JMESSAGE(JERR_INPUT_EMPTY, "Empty input file") +JMESSAGE(JERR_INPUT_EOF, "Premature end of input file") +JMESSAGE(JERR_MISMATCHED_QUANT_TABLE, + "Cannot transcode due to multiple use of quantization table %d") +JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data") +JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change") +JMESSAGE(JERR_NOTIMPL, "Not implemented yet") +JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time") +JMESSAGE(JERR_NO_ARITH_TABLE, "Arithmetic table 0x%02x was not defined") +JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported") +JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined") +JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image") +JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined") +JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x") +JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)") +JMESSAGE(JERR_QUANT_COMPONENTS, + "Cannot quantize more than %d color components") +JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors") +JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors") +JMESSAGE(JERR_SOF_BEFORE, "Invalid JPEG file structure: %s before SOF") +JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers") +JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker") +JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x") +JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers") +JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s") +JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file") +JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file") +JMESSAGE(JERR_TFILE_WRITE, + "Write failed on temporary file --- out of disk space?") +JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines") +JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x") +JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up") +JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation") +JMESSAGE(JERR_XMS_READ, "Read from XMS failed") +JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed") +JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT) +JMESSAGE(JMSG_VERSION, JVERSION) +JMESSAGE(JTRC_16BIT_TABLES, + "Caution: quantization tables are too coarse for baseline JPEG") +JMESSAGE(JTRC_ADOBE, + "Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d") +JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u") +JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u") +JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x") +JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x") +JMESSAGE(JTRC_DQT, "Define Quantization Table %d precision %d") +JMESSAGE(JTRC_DRI, "Define Restart Interval %u") +JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u") +JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u") +JMESSAGE(JTRC_EOI, "End Of Image") +JMESSAGE(JTRC_HUFFBITS, " %3d %3d %3d %3d %3d %3d %3d %3d") +JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d %d") +JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE, + "Warning: thumbnail image size does not match data length %u") +JMESSAGE(JTRC_JFIF_EXTENSION, + "JFIF extension marker: type 0x%02x, length %u") +JMESSAGE(JTRC_JFIF_THUMBNAIL, " with %d x %d thumbnail image") +JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u") +JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x") +JMESSAGE(JTRC_QUANTVALS, " %4u %4u %4u %4u %4u %4u %4u %4u") +JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors") +JMESSAGE(JTRC_QUANT_NCOLORS, "Quantizing to %d colors") +JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization") +JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d") +JMESSAGE(JTRC_RST, "RST%d") +JMESSAGE(JTRC_SMOOTH_NOTIMPL, + "Smoothing not supported with nonstandard sampling ratios") +JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d") +JMESSAGE(JTRC_SOF_COMPONENT, " Component %d: %dhx%dv q=%d") +JMESSAGE(JTRC_SOI, "Start of Image") +JMESSAGE(JTRC_SOS, "Start Of Scan: %d components") +JMESSAGE(JTRC_SOS_COMPONENT, " Component %d: dc=%d ac=%d") +JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d") +JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s") +JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s") +JMESSAGE(JTRC_THUMB_JPEG, + "JFIF extension marker: JPEG-compressed thumbnail image, length %u") +JMESSAGE(JTRC_THUMB_PALETTE, + "JFIF extension marker: palette thumbnail image, length %u") +JMESSAGE(JTRC_THUMB_RGB, + "JFIF extension marker: RGB thumbnail image, length %u") +JMESSAGE(JTRC_UNKNOWN_IDS, + "Unrecognized component IDs %d %d %d, assuming YCbCr") +JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u") +JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u") +JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d") +JMESSAGE(JWRN_ARITH_BAD_CODE, "Corrupt JPEG data: bad arithmetic code") +JMESSAGE(JWRN_BOGUS_PROGRESSION, + "Inconsistent progression sequence for component %d coefficient %d") +JMESSAGE(JWRN_EXTRANEOUS_DATA, + "Corrupt JPEG data: %u extraneous bytes before marker 0x%02x") +JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment") +JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code") +JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d") +JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file") +JMESSAGE(JWRN_MUST_RESYNC, + "Corrupt JPEG data: found marker 0x%02x instead of RST%d") +JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG") +JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines") + +#ifdef JMAKE_ENUM_LIST + + JMSG_LASTMSGCODE +} J_MESSAGE_CODE; + +#undef JMAKE_ENUM_LIST +#endif /* JMAKE_ENUM_LIST */ + +/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */ +#undef JMESSAGE + + +#ifndef JERROR_H +#define JERROR_H + +/* Macros to simplify using the error and trace message stuff */ +/* The first parameter is either type of cinfo pointer */ + +/* Fatal errors (print message and exit) */ +#define ERREXIT(cinfo,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT1(cinfo,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT2(cinfo,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT3(cinfo,code,p1,p2,p3) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (cinfo)->err->msg_parm.i[2] = (p3), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT4(cinfo,code,p1,p2,p3,p4) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (cinfo)->err->msg_parm.i[2] = (p3), \ + (cinfo)->err->msg_parm.i[3] = (p4), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT6(cinfo,code,p1,p2,p3,p4,p5,p6) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (cinfo)->err->msg_parm.i[2] = (p3), \ + (cinfo)->err->msg_parm.i[3] = (p4), \ + (cinfo)->err->msg_parm.i[4] = (p5), \ + (cinfo)->err->msg_parm.i[5] = (p6), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXITS(cinfo,code,str) \ + ((cinfo)->err->msg_code = (code), \ + strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) + +#define MAKESTMT(stuff) do { stuff } while (0) + +/* Nonfatal errors (we can keep going, but the data is probably corrupt) */ +#define WARNMS(cinfo,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) +#define WARNMS1(cinfo,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) +#define WARNMS2(cinfo,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) + +/* Informational/debugging messages */ +#define TRACEMS(cinfo,lvl,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS1(cinfo,lvl,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS2(cinfo,lvl,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS3(cinfo,lvl,code,p1,p2,p3) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + _mp[4] = (p5); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + _mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMSS(cinfo,lvl,code,str) \ + ((cinfo)->err->msg_code = (code), \ + strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) + +#endif /* JERROR_H */ diff --git a/scalos/include/jmorecfg.h b/scalos/include/jmorecfg.h new file mode 100644 index 000000000..2851d7adc --- /dev/null +++ b/scalos/include/jmorecfg.h @@ -0,0 +1,389 @@ +/* + * jmorecfg.h + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * Modified 1997-2012 by Guido Vollbeding. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains additional configuration options that customize the + * JPEG software for special applications or support machine-dependent + * optimizations. Most users will not need to touch this file. + */ + + +/* + * Define BITS_IN_JSAMPLE as either + * 8 for 8-bit sample values (the usual setting) + * 12 for 12-bit sample values + * Only 8 and 12 are legal data precisions for lossy JPEG according to the + * JPEG standard, and the IJG code does not support anything else! + * We do not support run-time selection of data precision, sorry. + */ + +#define BITS_IN_JSAMPLE 8 /* use 8 or 12 */ + + +/* + * Maximum number of components (color channels) allowed in JPEG image. + * To meet the letter of the JPEG spec, set this to 255. However, darn + * few applications need more than 4 channels (maybe 5 for CMYK + alpha + * mask). We recommend 10 as a reasonable compromise; use 4 if you are + * really short on memory. (Each allowed component costs a hundred or so + * bytes of storage, whether actually used in an image or not.) + */ + +#define MAX_COMPONENTS 10 /* maximum number of image components */ + + +/* + * Basic data types. + * You may need to change these if you have a machine with unusual data + * type sizes; for example, "char" not 8 bits, "short" not 16 bits, + * or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits, + * but it had better be at least 16. + */ + +/* Representation of a single sample (pixel element value). + * We frequently allocate large arrays of these, so it's important to keep + * them small. But if you have memory to burn and access to char or short + * arrays is very slow on your hardware, you might want to change these. + */ + +#if BITS_IN_JSAMPLE == 8 +/* JSAMPLE should be the smallest type that will hold the values 0..255. + * You can use a signed char by having GETJSAMPLE mask it with 0xFF. + */ + +#ifdef HAVE_UNSIGNED_CHAR + +typedef unsigned char JSAMPLE; +#define GETJSAMPLE(value) ((int) (value)) + +#else /* not HAVE_UNSIGNED_CHAR */ + +typedef char JSAMPLE; +#ifdef CHAR_IS_UNSIGNED +#define GETJSAMPLE(value) ((int) (value)) +#else +#define GETJSAMPLE(value) ((int) (value) & 0xFF) +#endif /* CHAR_IS_UNSIGNED */ + +#endif /* HAVE_UNSIGNED_CHAR */ + +#define MAXJSAMPLE 255 +#define CENTERJSAMPLE 128 + +#endif /* BITS_IN_JSAMPLE == 8 */ + + +#if BITS_IN_JSAMPLE == 12 +/* JSAMPLE should be the smallest type that will hold the values 0..4095. + * On nearly all machines "short" will do nicely. + */ + +typedef short JSAMPLE; +#define GETJSAMPLE(value) ((int) (value)) + +#define MAXJSAMPLE 4095 +#define CENTERJSAMPLE 2048 + +#endif /* BITS_IN_JSAMPLE == 12 */ + + +/* Representation of a DCT frequency coefficient. + * This should be a signed value of at least 16 bits; "short" is usually OK. + * Again, we allocate large arrays of these, but you can change to int + * if you have memory to burn and "short" is really slow. + */ + +typedef short JCOEF; + + +/* Compressed datastreams are represented as arrays of JOCTET. + * These must be EXACTLY 8 bits wide, at least once they are written to + * external storage. Note that when using the stdio data source/destination + * managers, this is also the data type passed to fread/fwrite. + */ + +#ifdef HAVE_UNSIGNED_CHAR + +typedef unsigned char JOCTET; +#define GETJOCTET(value) (value) + +#else /* not HAVE_UNSIGNED_CHAR */ + +typedef char JOCTET; +#ifdef CHAR_IS_UNSIGNED +#define GETJOCTET(value) (value) +#else +#define GETJOCTET(value) ((value) & 0xFF) +#endif /* CHAR_IS_UNSIGNED */ + +#endif /* HAVE_UNSIGNED_CHAR */ + + +/* These typedefs are used for various table entries and so forth. + * They must be at least as wide as specified; but making them too big + * won't cost a huge amount of memory, so we don't provide special + * extraction code like we did for JSAMPLE. (In other words, these + * typedefs live at a different point on the speed/space tradeoff curve.) + */ + +/* UINT8 must hold at least the values 0..255. */ + +#ifdef HAVE_UNSIGNED_CHAR +typedef unsigned char UINT8; +#else /* not HAVE_UNSIGNED_CHAR */ +#ifdef CHAR_IS_UNSIGNED +typedef char UINT8; +#else /* not CHAR_IS_UNSIGNED */ +typedef short UINT8; +#endif /* CHAR_IS_UNSIGNED */ +#endif /* HAVE_UNSIGNED_CHAR */ + +/* UINT16 must hold at least the values 0..65535. */ + +#ifdef HAVE_UNSIGNED_SHORT +typedef unsigned short UINT16; +#else /* not HAVE_UNSIGNED_SHORT */ +typedef unsigned int UINT16; +#endif /* HAVE_UNSIGNED_SHORT */ + +/* INT16 must hold at least the values -32768..32767. */ + +#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */ +typedef short INT16; +#endif + +/* INT32 must hold at least signed 32-bit values. */ + +#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */ +#ifndef _BASETSD_H_ /* Microsoft defines it in basetsd.h */ +#ifndef _BASETSD_H /* MinGW is slightly different */ +#ifndef QGLOBAL_H /* Qt defines it in qglobal.h */ +typedef long INT32; +#endif +#endif +#endif +#endif + +/* Datatype used for image dimensions. The JPEG standard only supports + * images up to 64K*64K due to 16-bit fields in SOF markers. Therefore + * "unsigned int" is sufficient on all machines. However, if you need to + * handle larger images and you don't mind deviating from the spec, you + * can change this datatype. + */ + +typedef unsigned int JDIMENSION; + +#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */ + + +/* These macros are used in all function definitions and extern declarations. + * You could modify them if you need to change function linkage conventions; + * in particular, you'll need to do that to make the library a Windows DLL. + * Another application is to make all functions global for use with debuggers + * or code profilers that require it. + */ + +/* a function called through method pointers: */ +#define METHODDEF(type) static type +/* a function used only in its module: */ +#define LOCAL(type) static type +/* a function referenced thru EXTERNs: */ +#define GLOBAL(type) type +/* a reference to a GLOBAL function: */ +#define EXTERN(type) extern type + + +/* This macro is used to declare a "method", that is, a function pointer. + * We want to supply prototype parameters if the compiler can cope. + * Note that the arglist parameter must be parenthesized! + * Again, you can customize this if you need special linkage keywords. + */ + +#ifdef HAVE_PROTOTYPES +#define JMETHOD(type,methodname,arglist) type (*methodname) arglist +#else +#define JMETHOD(type,methodname,arglist) type (*methodname) () +#endif + + +/* The noreturn type identifier is used to declare functions + * which cannot return. + * Compilers can thus create more optimized code and perform + * better checks for warnings and errors. + * Static analyzer tools can make improved inferences about + * execution paths and are prevented from giving false alerts. + * + * Unfortunately, the proposed specifications of corresponding + * extensions in the Dec 2011 ISO C standard revision (C11), + * GCC, MSVC, etc. are not viable. + * Thus we introduce a user defined type to declare noreturn + * functions at least for clarity. A proper compiler would + * have a suitable noreturn type to match in place of void. + */ + +#ifndef HAVE_NORETURN_T +typedef void noreturn_t; +#endif + + +/* Here is the pseudo-keyword for declaring pointers that must be "far" + * on 80x86 machines. Most of the specialized coding for 80x86 is handled + * by just saying "FAR *" where such a pointer is needed. In a few places + * explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol. + */ + +#ifndef FAR +#ifdef NEED_FAR_POINTERS +#define FAR far +#else +#define FAR +#endif +#endif + + +/* + * On a few systems, type boolean and/or its values FALSE, TRUE may appear + * in standard header files. Or you may have conflicts with application- + * specific header files that you want to include together with these files. + * Defining HAVE_BOOLEAN before including jpeglib.h should make it work. + */ + + +#ifndef HAVE_BOOLEAN +typedef int boolean; +#endif +#ifndef FALSE /* in case these macros already exist */ +#define FALSE 0 /* values of boolean */ +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +/* + * The remaining options affect code selection within the JPEG library, + * but they don't need to be visible to most applications using the library. + * To minimize application namespace pollution, the symbols won't be + * defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined. + */ + +#ifdef JPEG_INTERNALS +#define JPEG_INTERNAL_OPTIONS +#endif + +#ifdef JPEG_INTERNAL_OPTIONS + + +/* + * These defines indicate whether to include various optional functions. + * Undefining some of these symbols will produce a smaller but less capable + * library. Note that you can leave certain source files out of the + * compilation/linking process if you've #undef'd the corresponding symbols. + * (You may HAVE to do that if your compiler doesn't like null source files.) + */ + +/* Capability options common to encoder and decoder: */ + +#define DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */ +#define DCT_IFAST_SUPPORTED /* faster, less accurate integer method */ +#define DCT_FLOAT_SUPPORTED /* floating-point: accurate, fast on fast HW */ + +/* Encoder capability options: */ + +#define C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ +#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ +#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ +#define DCT_SCALING_SUPPORTED /* Input rescaling via DCT? (Requires DCT_ISLOW)*/ +#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */ +/* Note: if you selected 12-bit data precision, it is dangerous to turn off + * ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit + * precision, so jchuff.c normally uses entropy optimization to compute + * usable tables for higher precision. If you don't want to do optimization, + * you'll have to supply different default Huffman tables. + * The exact same statements apply for progressive JPEG: the default tables + * don't work for progressive mode. (This may get fixed, however.) + */ +#define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */ + +/* Decoder capability options: */ + +#define D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ +#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ +#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ +#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */ +#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */ +#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */ +#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */ +#define UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */ +#define QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */ +#define QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */ + +/* more capability options later, no doubt */ + + +/* + * Ordering of RGB data in scanlines passed to or from the application. + * If your application wants to deal with data in the order B,G,R, just + * change these macros. You can also deal with formats such as R,G,B,X + * (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing + * the offsets will also change the order in which colormap data is organized. + * RESTRICTIONS: + * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats. + * 2. The color quantizer modules will not behave desirably if RGB_PIXELSIZE + * is not 3 (they don't understand about dummy color components!). So you + * can't use color quantization if you change that value. + */ + +#define RGB_RED 0 /* Offset of Red in an RGB scanline element */ +#define RGB_GREEN 1 /* Offset of Green */ +#define RGB_BLUE 2 /* Offset of Blue */ +#define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */ + + +/* Definitions for speed-related optimizations. */ + + +/* If your compiler supports inline functions, define INLINE + * as the inline keyword; otherwise define it as empty. + */ + +#ifndef INLINE +#ifdef __GNUC__ /* for instance, GNU C knows about inline */ +#define INLINE __inline__ +#endif +#ifndef INLINE +#define INLINE /* default is to define it as empty */ +#endif +#endif + + +/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying + * two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER + * as short on such a machine. MULTIPLIER must be at least 16 bits wide. + */ + +#ifndef MULTIPLIER +#define MULTIPLIER int /* type for fastest integer multiply */ +#endif + + +/* FAST_FLOAT should be either float or double, whichever is done faster + * by your compiler. (Note that this type is only used in the floating point + * DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.) + * Typically, float is faster in ANSI C compilers, while double is faster in + * pre-ANSI compilers (because they insist on converting to double anyway). + * The code below therefore chooses float if we have ANSI-style prototypes. + */ + +#ifndef FAST_FLOAT +#ifdef HAVE_PROTOTYPES +#define FAST_FLOAT float +#else +#define FAST_FLOAT double +#endif +#endif + +#endif /* JPEG_INTERNAL_OPTIONS */ diff --git a/scalos/include/jpeglib.h b/scalos/include/jpeglib.h new file mode 100644 index 000000000..0a6dac44c --- /dev/null +++ b/scalos/include/jpeglib.h @@ -0,0 +1,1173 @@ +/* + * jpeglib.h + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * Modified 2002-2012 by Guido Vollbeding. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file defines the application interface for the JPEG library. + * Most applications using the library need only include this file, + * and perhaps jerror.h if they want to know the exact error codes. + */ + +#ifndef JPEGLIB_H +#define JPEGLIB_H + +/* + * First we include the configuration files that record how this + * installation of the JPEG library is set up. jconfig.h can be + * generated automatically for many systems. jmorecfg.h contains + * manual configuration options that most people need not worry about. + */ + +#ifndef JCONFIG_INCLUDED /* in case jinclude.h already did */ +#include "jconfig.h" /* widely used configuration options */ +#endif +#include "jmorecfg.h" /* seldom changed options */ + + +#ifdef __cplusplus +#ifndef DONT_USE_EXTERN_C +extern "C" { +#endif +#endif + +/* Version IDs for the JPEG library. + * Might be useful for tests like "#if JPEG_LIB_VERSION >= 90". + */ + +#define JPEG_LIB_VERSION 90 /* Compatibility version 9.0 */ +#define JPEG_LIB_VERSION_MAJOR 9 +#define JPEG_LIB_VERSION_MINOR 0 + + +/* Various constants determining the sizes of things. + * All of these are specified by the JPEG standard, so don't change them + * if you want to be compatible. + */ + +#define DCTSIZE 8 /* The basic DCT block is 8x8 coefficients */ +#define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */ +#define NUM_QUANT_TBLS 4 /* Quantization tables are numbered 0..3 */ +#define NUM_HUFF_TBLS 4 /* Huffman tables are numbered 0..3 */ +#define NUM_ARITH_TBLS 16 /* Arith-coding tables are numbered 0..15 */ +#define MAX_COMPS_IN_SCAN 4 /* JPEG limit on # of components in one scan */ +#define MAX_SAMP_FACTOR 4 /* JPEG limit on sampling factors */ +/* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard; + * the PostScript DCT filter can emit files with many more than 10 blocks/MCU. + * If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU + * to handle it. We even let you do this from the jconfig.h file. However, + * we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe + * sometimes emits noncompliant files doesn't mean you should too. + */ +#define C_MAX_BLOCKS_IN_MCU 10 /* compressor's limit on blocks per MCU */ +#ifndef D_MAX_BLOCKS_IN_MCU +#define D_MAX_BLOCKS_IN_MCU 10 /* decompressor's limit on blocks per MCU */ +#endif + + +/* Data structures for images (arrays of samples and of DCT coefficients). + * On 80x86 machines, the image arrays are too big for near pointers, + * but the pointer arrays can fit in near memory. + */ + +typedef JSAMPLE FAR *JSAMPROW; /* ptr to one image row of pixel samples. */ +typedef JSAMPROW *JSAMPARRAY; /* ptr to some rows (a 2-D sample array) */ +typedef JSAMPARRAY *JSAMPIMAGE; /* a 3-D sample array: top index is color */ + +typedef JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */ +typedef JBLOCK FAR *JBLOCKROW; /* pointer to one row of coefficient blocks */ +typedef JBLOCKROW *JBLOCKARRAY; /* a 2-D array of coefficient blocks */ +typedef JBLOCKARRAY *JBLOCKIMAGE; /* a 3-D array of coefficient blocks */ + +typedef JCOEF FAR *JCOEFPTR; /* useful in a couple of places */ + + +/* Types for JPEG compression parameters and working tables. */ + + +/* DCT coefficient quantization tables. */ + +typedef struct { + /* This array gives the coefficient quantizers in natural array order + * (not the zigzag order in which they are stored in a JPEG DQT marker). + * CAUTION: IJG versions prior to v6a kept this array in zigzag order. + */ + UINT16 quantval[DCTSIZE2]; /* quantization step for each coefficient */ + /* This field is used only during compression. It's initialized FALSE when + * the table is created, and set TRUE when it's been output to the file. + * You could suppress output of a table by setting this to TRUE. + * (See jpeg_suppress_tables for an example.) + */ + boolean sent_table; /* TRUE when table has been output */ +} JQUANT_TBL; + + +/* Huffman coding tables. */ + +typedef struct { + /* These two fields directly represent the contents of a JPEG DHT marker */ + UINT8 bits[17]; /* bits[k] = # of symbols with codes of */ + /* length k bits; bits[0] is unused */ + UINT8 huffval[256]; /* The symbols, in order of incr code length */ + /* This field is used only during compression. It's initialized FALSE when + * the table is created, and set TRUE when it's been output to the file. + * You could suppress output of a table by setting this to TRUE. + * (See jpeg_suppress_tables for an example.) + */ + boolean sent_table; /* TRUE when table has been output */ +} JHUFF_TBL; + + +/* Basic info about one component (color channel). */ + +typedef struct { + /* These values are fixed over the whole image. */ + /* For compression, they must be supplied by parameter setup; */ + /* for decompression, they are read from the SOF marker. */ + int component_id; /* identifier for this component (0..255) */ + int component_index; /* its index in SOF or cinfo->comp_info[] */ + int h_samp_factor; /* horizontal sampling factor (1..4) */ + int v_samp_factor; /* vertical sampling factor (1..4) */ + int quant_tbl_no; /* quantization table selector (0..3) */ + /* These values may vary between scans. */ + /* For compression, they must be supplied by parameter setup; */ + /* for decompression, they are read from the SOS marker. */ + /* The decompressor output side may not use these variables. */ + int dc_tbl_no; /* DC entropy table selector (0..3) */ + int ac_tbl_no; /* AC entropy table selector (0..3) */ + + /* Remaining fields should be treated as private by applications. */ + + /* These values are computed during compression or decompression startup: */ + /* Component's size in DCT blocks. + * Any dummy blocks added to complete an MCU are not counted; therefore + * these values do not depend on whether a scan is interleaved or not. + */ + JDIMENSION width_in_blocks; + JDIMENSION height_in_blocks; + /* Size of a DCT block in samples, + * reflecting any scaling we choose to apply during the DCT step. + * Values from 1 to 16 are supported. + * Note that different components may receive different DCT scalings. + */ + int DCT_h_scaled_size; + int DCT_v_scaled_size; + /* The downsampled dimensions are the component's actual, unpadded number + * of samples at the main buffer (preprocessing/compression interface); + * DCT scaling is included, so + * downsampled_width = ceil(image_width * Hi/Hmax * DCT_h_scaled_size/DCTSIZE) + * and similarly for height. + */ + JDIMENSION downsampled_width; /* actual width in samples */ + JDIMENSION downsampled_height; /* actual height in samples */ + /* This flag is used only for decompression. In cases where some of the + * components will be ignored (eg grayscale output from YCbCr image), + * we can skip most computations for the unused components. + */ + boolean component_needed; /* do we need the value of this component? */ + + /* These values are computed before starting a scan of the component. */ + /* The decompressor output side may not use these variables. */ + int MCU_width; /* number of blocks per MCU, horizontally */ + int MCU_height; /* number of blocks per MCU, vertically */ + int MCU_blocks; /* MCU_width * MCU_height */ + int MCU_sample_width; /* MCU width in samples: MCU_width * DCT_h_scaled_size */ + int last_col_width; /* # of non-dummy blocks across in last MCU */ + int last_row_height; /* # of non-dummy blocks down in last MCU */ + + /* Saved quantization table for component; NULL if none yet saved. + * See jdinput.c comments about the need for this information. + * This field is currently used only for decompression. + */ + JQUANT_TBL * quant_table; + + /* Private per-component storage for DCT or IDCT subsystem. */ + void * dct_table; +} jpeg_component_info; + + +/* The script for encoding a multiple-scan file is an array of these: */ + +typedef struct { + int comps_in_scan; /* number of components encoded in this scan */ + int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */ + int Ss, Se; /* progressive JPEG spectral selection parms */ + int Ah, Al; /* progressive JPEG successive approx. parms */ +} jpeg_scan_info; + +/* The decompressor can save APPn and COM markers in a list of these: */ + +typedef struct jpeg_marker_struct FAR * jpeg_saved_marker_ptr; + +struct jpeg_marker_struct { + jpeg_saved_marker_ptr next; /* next in list, or NULL */ + UINT8 marker; /* marker code: JPEG_COM, or JPEG_APP0+n */ + unsigned int original_length; /* # bytes of data in the file */ + unsigned int data_length; /* # bytes of data saved at data[] */ + JOCTET FAR * data; /* the data contained in the marker */ + /* the marker length word is not counted in data_length or original_length */ +}; + +/* Known color spaces. */ + +typedef enum { + JCS_UNKNOWN, /* error/unspecified */ + JCS_GRAYSCALE, /* monochrome */ + JCS_RGB, /* red/green/blue */ + JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */ + JCS_CMYK, /* C/M/Y/K */ + JCS_YCCK /* Y/Cb/Cr/K */ +} J_COLOR_SPACE; + +/* Supported color transforms. */ + +typedef enum { + JCT_NONE = 0, + JCT_SUBTRACT_GREEN = 1 +} J_COLOR_TRANSFORM; + +/* DCT/IDCT algorithm options. */ + +typedef enum { + JDCT_ISLOW, /* slow but accurate integer algorithm */ + JDCT_IFAST, /* faster, less accurate integer method */ + JDCT_FLOAT /* floating-point: accurate, fast on fast HW */ +} J_DCT_METHOD; + +#ifndef JDCT_DEFAULT /* may be overridden in jconfig.h */ +#define JDCT_DEFAULT JDCT_ISLOW +#endif +#ifndef JDCT_FASTEST /* may be overridden in jconfig.h */ +#define JDCT_FASTEST JDCT_IFAST +#endif + +/* Dithering options for decompression. */ + +typedef enum { + JDITHER_NONE, /* no dithering */ + JDITHER_ORDERED, /* simple ordered dither */ + JDITHER_FS /* Floyd-Steinberg error diffusion dither */ +} J_DITHER_MODE; + + +/* Common fields between JPEG compression and decompression master structs. */ + +#define jpeg_common_fields \ + struct jpeg_error_mgr * err; /* Error handler module */\ + struct jpeg_memory_mgr * mem; /* Memory manager module */\ + struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\ + void * client_data; /* Available for use by application */\ + boolean is_decompressor; /* So common code can tell which is which */\ + int global_state /* For checking call sequence validity */ + +/* Routines that are to be used by both halves of the library are declared + * to receive a pointer to this structure. There are no actual instances of + * jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct. + */ +struct jpeg_common_struct { + jpeg_common_fields; /* Fields common to both master struct types */ + /* Additional fields follow in an actual jpeg_compress_struct or + * jpeg_decompress_struct. All three structs must agree on these + * initial fields! (This would be a lot cleaner in C++.) + */ +}; + +typedef struct jpeg_common_struct * j_common_ptr; +typedef struct jpeg_compress_struct * j_compress_ptr; +typedef struct jpeg_decompress_struct * j_decompress_ptr; + + +/* Master record for a compression instance */ + +struct jpeg_compress_struct { + jpeg_common_fields; /* Fields shared with jpeg_decompress_struct */ + + /* Destination for compressed data */ + struct jpeg_destination_mgr * dest; + + /* Description of source image --- these fields must be filled in by + * outer application before starting compression. in_color_space must + * be correct before you can even call jpeg_set_defaults(). + */ + + JDIMENSION image_width; /* input image width */ + JDIMENSION image_height; /* input image height */ + int input_components; /* # of color components in input image */ + J_COLOR_SPACE in_color_space; /* colorspace of input image */ + + double input_gamma; /* image gamma of input image */ + + /* Compression parameters --- these fields must be set before calling + * jpeg_start_compress(). We recommend calling jpeg_set_defaults() to + * initialize everything to reasonable defaults, then changing anything + * the application specifically wants to change. That way you won't get + * burnt when new parameters are added. Also note that there are several + * helper routines to simplify changing parameters. + */ + + unsigned int scale_num, scale_denom; /* fraction by which to scale image */ + + JDIMENSION jpeg_width; /* scaled JPEG image width */ + JDIMENSION jpeg_height; /* scaled JPEG image height */ + /* Dimensions of actual JPEG image that will be written to file, + * derived from input dimensions by scaling factors above. + * These fields are computed by jpeg_start_compress(). + * You can also use jpeg_calc_jpeg_dimensions() to determine these values + * in advance of calling jpeg_start_compress(). + */ + + int data_precision; /* bits of precision in image data */ + + int num_components; /* # of color components in JPEG image */ + J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ + + jpeg_component_info * comp_info; + /* comp_info[i] describes component that appears i'th in SOF */ + + JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; + int q_scale_factor[NUM_QUANT_TBLS]; + /* ptrs to coefficient quantization tables, or NULL if not defined, + * and corresponding scale factors (percentage, initialized 100). + */ + + JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; + JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; + /* ptrs to Huffman coding tables, or NULL if not defined */ + + UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ + UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ + UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ + + int num_scans; /* # of entries in scan_info array */ + const jpeg_scan_info * scan_info; /* script for multi-scan file, or NULL */ + /* The default value of scan_info is NULL, which causes a single-scan + * sequential JPEG file to be emitted. To create a multi-scan file, + * set num_scans and scan_info to point to an array of scan definitions. + */ + + boolean raw_data_in; /* TRUE=caller supplies downsampled data */ + boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ + boolean optimize_coding; /* TRUE=optimize entropy encoding parms */ + boolean CCIR601_sampling; /* TRUE=first samples are cosited */ + boolean do_fancy_downsampling; /* TRUE=apply fancy downsampling */ + int smoothing_factor; /* 1..100, or 0 for no input smoothing */ + J_DCT_METHOD dct_method; /* DCT algorithm selector */ + + /* The restart interval can be specified in absolute MCUs by setting + * restart_interval, or in MCU rows by setting restart_in_rows + * (in which case the correct restart_interval will be figured + * for each scan). + */ + unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */ + int restart_in_rows; /* if > 0, MCU rows per restart interval */ + + /* Parameters controlling emission of special markers. */ + + boolean write_JFIF_header; /* should a JFIF marker be written? */ + UINT8 JFIF_major_version; /* What to write for the JFIF version number */ + UINT8 JFIF_minor_version; + /* These three values are not used by the JPEG code, merely copied */ + /* into the JFIF APP0 marker. density_unit can be 0 for unknown, */ + /* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */ + /* ratio is defined by X_density/Y_density even when density_unit=0. */ + UINT8 density_unit; /* JFIF code for pixel size units */ + UINT16 X_density; /* Horizontal pixel density */ + UINT16 Y_density; /* Vertical pixel density */ + boolean write_Adobe_marker; /* should an Adobe marker be written? */ + + J_COLOR_TRANSFORM color_transform; + /* Color transform identifier, writes LSE marker if nonzero */ + + /* State variable: index of next scanline to be written to + * jpeg_write_scanlines(). Application may use this to control its + * processing loop, e.g., "while (next_scanline < image_height)". + */ + + JDIMENSION next_scanline; /* 0 .. image_height-1 */ + + /* Remaining fields are known throughout compressor, but generally + * should not be touched by a surrounding application. + */ + + /* + * These fields are computed during compression startup + */ + boolean progressive_mode; /* TRUE if scan script uses progressive mode */ + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + + int min_DCT_h_scaled_size; /* smallest DCT_h_scaled_size of any component */ + int min_DCT_v_scaled_size; /* smallest DCT_v_scaled_size of any component */ + + JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */ + /* The coefficient controller receives data in units of MCU rows as defined + * for fully interleaved scans (whether the JPEG file is interleaved or not). + * There are v_samp_factor * DCTSIZE sample rows of each component in an + * "iMCU" (interleaved MCU) row. + */ + + /* + * These fields are valid during any one scan. + * They describe the components and MCUs actually appearing in the scan. + */ + int comps_in_scan; /* # of JPEG components in this scan */ + jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + + JDIMENSION MCUs_per_row; /* # of MCUs across the image */ + JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ + + int blocks_in_MCU; /* # of DCT blocks per MCU */ + int MCU_membership[C_MAX_BLOCKS_IN_MCU]; + /* MCU_membership[i] is index in cur_comp_info of component owning */ + /* i'th block in an MCU */ + + int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ + + int block_size; /* the basic DCT block size: 1..16 */ + const int * natural_order; /* natural-order position array */ + int lim_Se; /* min( Se, DCTSIZE2-1 ) */ + + /* + * Links to compression subobjects (methods and private variables of modules) + */ + struct jpeg_comp_master * master; + struct jpeg_c_main_controller * main; + struct jpeg_c_prep_controller * prep; + struct jpeg_c_coef_controller * coef; + struct jpeg_marker_writer * marker; + struct jpeg_color_converter * cconvert; + struct jpeg_downsampler * downsample; + struct jpeg_forward_dct * fdct; + struct jpeg_entropy_encoder * entropy; + jpeg_scan_info * script_space; /* workspace for jpeg_simple_progression */ + int script_space_size; +}; + + +/* Master record for a decompression instance */ + +struct jpeg_decompress_struct { + jpeg_common_fields; /* Fields shared with jpeg_compress_struct */ + + /* Source of compressed data */ + struct jpeg_source_mgr * src; + + /* Basic description of image --- filled in by jpeg_read_header(). */ + /* Application may inspect these values to decide how to process image. */ + + JDIMENSION image_width; /* nominal image width (from SOF marker) */ + JDIMENSION image_height; /* nominal image height */ + int num_components; /* # of color components in JPEG image */ + J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ + + /* Decompression processing parameters --- these fields must be set before + * calling jpeg_start_decompress(). Note that jpeg_read_header() initializes + * them to default values. + */ + + J_COLOR_SPACE out_color_space; /* colorspace for output */ + + unsigned int scale_num, scale_denom; /* fraction by which to scale image */ + + double output_gamma; /* image gamma wanted in output */ + + boolean buffered_image; /* TRUE=multiple output passes */ + boolean raw_data_out; /* TRUE=downsampled data wanted */ + + J_DCT_METHOD dct_method; /* IDCT algorithm selector */ + boolean do_fancy_upsampling; /* TRUE=apply fancy upsampling */ + boolean do_block_smoothing; /* TRUE=apply interblock smoothing */ + + boolean quantize_colors; /* TRUE=colormapped output wanted */ + /* the following are ignored if not quantize_colors: */ + J_DITHER_MODE dither_mode; /* type of color dithering to use */ + boolean two_pass_quantize; /* TRUE=use two-pass color quantization */ + int desired_number_of_colors; /* max # colors to use in created colormap */ + /* these are significant only in buffered-image mode: */ + boolean enable_1pass_quant; /* enable future use of 1-pass quantizer */ + boolean enable_external_quant;/* enable future use of external colormap */ + boolean enable_2pass_quant; /* enable future use of 2-pass quantizer */ + + /* Description of actual output image that will be returned to application. + * These fields are computed by jpeg_start_decompress(). + * You can also use jpeg_calc_output_dimensions() to determine these values + * in advance of calling jpeg_start_decompress(). + */ + + JDIMENSION output_width; /* scaled image width */ + JDIMENSION output_height; /* scaled image height */ + int out_color_components; /* # of color components in out_color_space */ + int output_components; /* # of color components returned */ + /* output_components is 1 (a colormap index) when quantizing colors; + * otherwise it equals out_color_components. + */ + int rec_outbuf_height; /* min recommended height of scanline buffer */ + /* If the buffer passed to jpeg_read_scanlines() is less than this many rows + * high, space and time will be wasted due to unnecessary data copying. + * Usually rec_outbuf_height will be 1 or 2, at most 4. + */ + + /* When quantizing colors, the output colormap is described by these fields. + * The application can supply a colormap by setting colormap non-NULL before + * calling jpeg_start_decompress; otherwise a colormap is created during + * jpeg_start_decompress or jpeg_start_output. + * The map has out_color_components rows and actual_number_of_colors columns. + */ + int actual_number_of_colors; /* number of entries in use */ + JSAMPARRAY colormap; /* The color map as a 2-D pixel array */ + + /* State variables: these variables indicate the progress of decompression. + * The application may examine these but must not modify them. + */ + + /* Row index of next scanline to be read from jpeg_read_scanlines(). + * Application may use this to control its processing loop, e.g., + * "while (output_scanline < output_height)". + */ + JDIMENSION output_scanline; /* 0 .. output_height-1 */ + + /* Current input scan number and number of iMCU rows completed in scan. + * These indicate the progress of the decompressor input side. + */ + int input_scan_number; /* Number of SOS markers seen so far */ + JDIMENSION input_iMCU_row; /* Number of iMCU rows completed */ + + /* The "output scan number" is the notional scan being displayed by the + * output side. The decompressor will not allow output scan/row number + * to get ahead of input scan/row, but it can fall arbitrarily far behind. + */ + int output_scan_number; /* Nominal scan number being displayed */ + JDIMENSION output_iMCU_row; /* Number of iMCU rows read */ + + /* Current progression status. coef_bits[c][i] indicates the precision + * with which component c's DCT coefficient i (in zigzag order) is known. + * It is -1 when no data has yet been received, otherwise it is the point + * transform (shift) value for the most recent scan of the coefficient + * (thus, 0 at completion of the progression). + * This pointer is NULL when reading a non-progressive file. + */ + int (*coef_bits)[DCTSIZE2]; /* -1 or current Al value for each coef */ + + /* Internal JPEG parameters --- the application usually need not look at + * these fields. Note that the decompressor output side may not use + * any parameters that can change between scans. + */ + + /* Quantization and Huffman tables are carried forward across input + * datastreams when processing abbreviated JPEG datastreams. + */ + + JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; + /* ptrs to coefficient quantization tables, or NULL if not defined */ + + JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; + JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; + /* ptrs to Huffman coding tables, or NULL if not defined */ + + /* These parameters are never carried across datastreams, since they + * are given in SOF/SOS markers or defined to be reset by SOI. + */ + + int data_precision; /* bits of precision in image data */ + + jpeg_component_info * comp_info; + /* comp_info[i] describes component that appears i'th in SOF */ + + boolean is_baseline; /* TRUE if Baseline SOF0 encountered */ + boolean progressive_mode; /* TRUE if SOFn specifies progressive mode */ + boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ + + UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ + UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ + UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ + + unsigned int restart_interval; /* MCUs per restart interval, or 0 for no restart */ + + /* These fields record data obtained from optional markers recognized by + * the JPEG library. + */ + boolean saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */ + /* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */ + UINT8 JFIF_major_version; /* JFIF version number */ + UINT8 JFIF_minor_version; + UINT8 density_unit; /* JFIF code for pixel size units */ + UINT16 X_density; /* Horizontal pixel density */ + UINT16 Y_density; /* Vertical pixel density */ + boolean saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */ + UINT8 Adobe_transform; /* Color transform code from Adobe marker */ + + J_COLOR_TRANSFORM color_transform; + /* Color transform identifier derived from LSE marker, otherwise zero */ + + boolean CCIR601_sampling; /* TRUE=first samples are cosited */ + + /* Aside from the specific data retained from APPn markers known to the + * library, the uninterpreted contents of any or all APPn and COM markers + * can be saved in a list for examination by the application. + */ + jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */ + + /* Remaining fields are known throughout decompressor, but generally + * should not be touched by a surrounding application. + */ + + /* + * These fields are computed during decompression startup + */ + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + + int min_DCT_h_scaled_size; /* smallest DCT_h_scaled_size of any component */ + int min_DCT_v_scaled_size; /* smallest DCT_v_scaled_size of any component */ + + JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */ + /* The coefficient controller's input and output progress is measured in + * units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows + * in fully interleaved JPEG scans, but are used whether the scan is + * interleaved or not. We define an iMCU row as v_samp_factor DCT block + * rows of each component. Therefore, the IDCT output contains + * v_samp_factor*DCT_v_scaled_size sample rows of a component per iMCU row. + */ + + JSAMPLE * sample_range_limit; /* table for fast range-limiting */ + + /* + * These fields are valid during any one scan. + * They describe the components and MCUs actually appearing in the scan. + * Note that the decompressor output side must not use these fields. + */ + int comps_in_scan; /* # of JPEG components in this scan */ + jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + + JDIMENSION MCUs_per_row; /* # of MCUs across the image */ + JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ + + int blocks_in_MCU; /* # of DCT blocks per MCU */ + int MCU_membership[D_MAX_BLOCKS_IN_MCU]; + /* MCU_membership[i] is index in cur_comp_info of component owning */ + /* i'th block in an MCU */ + + int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ + + /* These fields are derived from Se of first SOS marker. + */ + int block_size; /* the basic DCT block size: 1..16 */ + const int * natural_order; /* natural-order position array for entropy decode */ + int lim_Se; /* min( Se, DCTSIZE2-1 ) for entropy decode */ + + /* This field is shared between entropy decoder and marker parser. + * It is either zero or the code of a JPEG marker that has been + * read from the data source, but has not yet been processed. + */ + int unread_marker; + + /* + * Links to decompression subobjects (methods, private variables of modules) + */ + struct jpeg_decomp_master * master; + struct jpeg_d_main_controller * main; + struct jpeg_d_coef_controller * coef; + struct jpeg_d_post_controller * post; + struct jpeg_input_controller * inputctl; + struct jpeg_marker_reader * marker; + struct jpeg_entropy_decoder * entropy; + struct jpeg_inverse_dct * idct; + struct jpeg_upsampler * upsample; + struct jpeg_color_deconverter * cconvert; + struct jpeg_color_quantizer * cquantize; +}; + + +/* "Object" declarations for JPEG modules that may be supplied or called + * directly by the surrounding application. + * As with all objects in the JPEG library, these structs only define the + * publicly visible methods and state variables of a module. Additional + * private fields may exist after the public ones. + */ + + +/* Error handler object */ + +struct jpeg_error_mgr { + /* Error exit handler: does not return to caller */ + JMETHOD(noreturn_t, error_exit, (j_common_ptr cinfo)); + /* Conditionally emit a trace or warning message */ + JMETHOD(void, emit_message, (j_common_ptr cinfo, int msg_level)); + /* Routine that actually outputs a trace or error message */ + JMETHOD(void, output_message, (j_common_ptr cinfo)); + /* Format a message string for the most recent JPEG error or message */ + JMETHOD(void, format_message, (j_common_ptr cinfo, char * buffer)); +#define JMSG_LENGTH_MAX 200 /* recommended size of format_message buffer */ + /* Reset error state variables at start of a new image */ + JMETHOD(void, reset_error_mgr, (j_common_ptr cinfo)); + + /* The message ID code and any parameters are saved here. + * A message can have one string parameter or up to 8 int parameters. + */ + int msg_code; +#define JMSG_STR_PARM_MAX 80 + union { + int i[8]; + char s[JMSG_STR_PARM_MAX]; + } msg_parm; + + /* Standard state variables for error facility */ + + int trace_level; /* max msg_level that will be displayed */ + + /* For recoverable corrupt-data errors, we emit a warning message, + * but keep going unless emit_message chooses to abort. emit_message + * should count warnings in num_warnings. The surrounding application + * can check for bad data by seeing if num_warnings is nonzero at the + * end of processing. + */ + long num_warnings; /* number of corrupt-data warnings */ + + /* These fields point to the table(s) of error message strings. + * An application can change the table pointer to switch to a different + * message list (typically, to change the language in which errors are + * reported). Some applications may wish to add additional error codes + * that will be handled by the JPEG library error mechanism; the second + * table pointer is used for this purpose. + * + * First table includes all errors generated by JPEG library itself. + * Error code 0 is reserved for a "no such error string" message. + */ + const char * const * jpeg_message_table; /* Library errors */ + int last_jpeg_message; /* Table contains strings 0..last_jpeg_message */ + /* Second table can be added by application (see cjpeg/djpeg for example). + * It contains strings numbered first_addon_message..last_addon_message. + */ + const char * const * addon_message_table; /* Non-library errors */ + int first_addon_message; /* code for first string in addon table */ + int last_addon_message; /* code for last string in addon table */ +}; + + +/* Progress monitor object */ + +struct jpeg_progress_mgr { + JMETHOD(void, progress_monitor, (j_common_ptr cinfo)); + + long pass_counter; /* work units completed in this pass */ + long pass_limit; /* total number of work units in this pass */ + int completed_passes; /* passes completed so far */ + int total_passes; /* total number of passes expected */ +}; + + +/* Data destination object for compression */ + +struct jpeg_destination_mgr { + JOCTET * next_output_byte; /* => next byte to write in buffer */ + size_t free_in_buffer; /* # of byte spaces remaining in buffer */ + + JMETHOD(void, init_destination, (j_compress_ptr cinfo)); + JMETHOD(boolean, empty_output_buffer, (j_compress_ptr cinfo)); + JMETHOD(void, term_destination, (j_compress_ptr cinfo)); +}; + + +/* Data source object for decompression */ + +struct jpeg_source_mgr { + const JOCTET * next_input_byte; /* => next byte to read from buffer */ + size_t bytes_in_buffer; /* # of bytes remaining in buffer */ + + JMETHOD(void, init_source, (j_decompress_ptr cinfo)); + JMETHOD(boolean, fill_input_buffer, (j_decompress_ptr cinfo)); + JMETHOD(void, skip_input_data, (j_decompress_ptr cinfo, long num_bytes)); + JMETHOD(boolean, resync_to_restart, (j_decompress_ptr cinfo, int desired)); + JMETHOD(void, term_source, (j_decompress_ptr cinfo)); +}; + + +/* Memory manager object. + * Allocates "small" objects (a few K total), "large" objects (tens of K), + * and "really big" objects (virtual arrays with backing store if needed). + * The memory manager does not allow individual objects to be freed; rather, + * each created object is assigned to a pool, and whole pools can be freed + * at once. This is faster and more convenient than remembering exactly what + * to free, especially where malloc()/free() are not too speedy. + * NB: alloc routines never return NULL. They exit to error_exit if not + * successful. + */ + +#define JPOOL_PERMANENT 0 /* lasts until master record is destroyed */ +#define JPOOL_IMAGE 1 /* lasts until done with image/datastream */ +#define JPOOL_NUMPOOLS 2 + +typedef struct jvirt_sarray_control * jvirt_sarray_ptr; +typedef struct jvirt_barray_control * jvirt_barray_ptr; + + +struct jpeg_memory_mgr { + /* Method pointers */ + JMETHOD(void *, alloc_small, (j_common_ptr cinfo, int pool_id, + size_t sizeofobject)); + JMETHOD(void FAR *, alloc_large, (j_common_ptr cinfo, int pool_id, + size_t sizeofobject)); + JMETHOD(JSAMPARRAY, alloc_sarray, (j_common_ptr cinfo, int pool_id, + JDIMENSION samplesperrow, + JDIMENSION numrows)); + JMETHOD(JBLOCKARRAY, alloc_barray, (j_common_ptr cinfo, int pool_id, + JDIMENSION blocksperrow, + JDIMENSION numrows)); + JMETHOD(jvirt_sarray_ptr, request_virt_sarray, (j_common_ptr cinfo, + int pool_id, + boolean pre_zero, + JDIMENSION samplesperrow, + JDIMENSION numrows, + JDIMENSION maxaccess)); + JMETHOD(jvirt_barray_ptr, request_virt_barray, (j_common_ptr cinfo, + int pool_id, + boolean pre_zero, + JDIMENSION blocksperrow, + JDIMENSION numrows, + JDIMENSION maxaccess)); + JMETHOD(void, realize_virt_arrays, (j_common_ptr cinfo)); + JMETHOD(JSAMPARRAY, access_virt_sarray, (j_common_ptr cinfo, + jvirt_sarray_ptr ptr, + JDIMENSION start_row, + JDIMENSION num_rows, + boolean writable)); + JMETHOD(JBLOCKARRAY, access_virt_barray, (j_common_ptr cinfo, + jvirt_barray_ptr ptr, + JDIMENSION start_row, + JDIMENSION num_rows, + boolean writable)); + JMETHOD(void, free_pool, (j_common_ptr cinfo, int pool_id)); + JMETHOD(void, self_destruct, (j_common_ptr cinfo)); + + /* Limit on memory allocation for this JPEG object. (Note that this is + * merely advisory, not a guaranteed maximum; it only affects the space + * used for virtual-array buffers.) May be changed by outer application + * after creating the JPEG object. + */ + long max_memory_to_use; + + /* Maximum allocation request accepted by alloc_large. */ + long max_alloc_chunk; +}; + + +/* Routine signature for application-supplied marker processing methods. + * Need not pass marker code since it is stored in cinfo->unread_marker. + */ +typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo)); + + +/* Declarations for routines called by application. + * The JPP macro hides prototype parameters from compilers that can't cope. + * Note JPP requires double parentheses. + */ + +#ifdef HAVE_PROTOTYPES +#define JPP(arglist) arglist +#else +#define JPP(arglist) () +#endif + + +/* Short forms of external names for systems with brain-damaged linkers. + * We shorten external names to be unique in the first six letters, which + * is good enough for all known systems. + * (If your compiler itself needs names to be unique in less than 15 + * characters, you are out of luck. Get a better compiler.) + */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_std_error jStdError +#define jpeg_CreateCompress jCreaCompress +#define jpeg_CreateDecompress jCreaDecompress +#define jpeg_destroy_compress jDestCompress +#define jpeg_destroy_decompress jDestDecompress +#define jpeg_stdio_dest jStdDest +#define jpeg_stdio_src jStdSrc +#define jpeg_mem_dest jMemDest +#define jpeg_mem_src jMemSrc +#define jpeg_set_defaults jSetDefaults +#define jpeg_set_colorspace jSetColorspace +#define jpeg_default_colorspace jDefColorspace +#define jpeg_set_quality jSetQuality +#define jpeg_set_linear_quality jSetLQuality +#define jpeg_default_qtables jDefQTables +#define jpeg_add_quant_table jAddQuantTable +#define jpeg_quality_scaling jQualityScaling +#define jpeg_simple_progression jSimProgress +#define jpeg_suppress_tables jSuppressTables +#define jpeg_alloc_quant_table jAlcQTable +#define jpeg_alloc_huff_table jAlcHTable +#define jpeg_start_compress jStrtCompress +#define jpeg_write_scanlines jWrtScanlines +#define jpeg_finish_compress jFinCompress +#define jpeg_calc_jpeg_dimensions jCjpegDimensions +#define jpeg_write_raw_data jWrtRawData +#define jpeg_write_marker jWrtMarker +#define jpeg_write_m_header jWrtMHeader +#define jpeg_write_m_byte jWrtMByte +#define jpeg_write_tables jWrtTables +#define jpeg_read_header jReadHeader +#define jpeg_start_decompress jStrtDecompress +#define jpeg_read_scanlines jReadScanlines +#define jpeg_finish_decompress jFinDecompress +#define jpeg_read_raw_data jReadRawData +#define jpeg_has_multiple_scans jHasMultScn +#define jpeg_start_output jStrtOutput +#define jpeg_finish_output jFinOutput +#define jpeg_input_complete jInComplete +#define jpeg_new_colormap jNewCMap +#define jpeg_consume_input jConsumeInput +#define jpeg_core_output_dimensions jCoreDimensions +#define jpeg_calc_output_dimensions jCalcDimensions +#define jpeg_save_markers jSaveMarkers +#define jpeg_set_marker_processor jSetMarker +#define jpeg_read_coefficients jReadCoefs +#define jpeg_write_coefficients jWrtCoefs +#define jpeg_copy_critical_parameters jCopyCrit +#define jpeg_abort_compress jAbrtCompress +#define jpeg_abort_decompress jAbrtDecompress +#define jpeg_abort jAbort +#define jpeg_destroy jDestroy +#define jpeg_resync_to_restart jResyncRestart +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* Default error-management setup */ +EXTERN(struct jpeg_error_mgr *) jpeg_std_error + JPP((struct jpeg_error_mgr * err)); + +/* Initialization of JPEG compression objects. + * jpeg_create_compress() and jpeg_create_decompress() are the exported + * names that applications should call. These expand to calls on + * jpeg_CreateCompress and jpeg_CreateDecompress with additional information + * passed for version mismatch checking. + * NB: you must set up the error-manager BEFORE calling jpeg_create_xxx. + */ +#define jpeg_create_compress(cinfo) \ + jpeg_CreateCompress((cinfo), JPEG_LIB_VERSION, \ + (size_t) sizeof(struct jpeg_compress_struct)) +#define jpeg_create_decompress(cinfo) \ + jpeg_CreateDecompress((cinfo), JPEG_LIB_VERSION, \ + (size_t) sizeof(struct jpeg_decompress_struct)) +EXTERN(void) jpeg_CreateCompress JPP((j_compress_ptr cinfo, + int version, size_t structsize)); +EXTERN(void) jpeg_CreateDecompress JPP((j_decompress_ptr cinfo, + int version, size_t structsize)); +/* Destruction of JPEG compression objects */ +EXTERN(void) jpeg_destroy_compress JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_destroy_decompress JPP((j_decompress_ptr cinfo)); + +/* Standard data source and destination managers: stdio streams. */ +/* Caller is responsible for opening the file before and closing after. */ +EXTERN(void) jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile)); +EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile)); + +/* Data source and destination managers: memory buffers. */ +EXTERN(void) jpeg_mem_dest JPP((j_compress_ptr cinfo, + unsigned char ** outbuffer, + unsigned long * outsize)); +EXTERN(void) jpeg_mem_src JPP((j_decompress_ptr cinfo, + unsigned char * inbuffer, + unsigned long insize)); + +/* Default parameter setup for compression */ +EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo)); +/* Compression parameter setup aids */ +EXTERN(void) jpeg_set_colorspace JPP((j_compress_ptr cinfo, + J_COLOR_SPACE colorspace)); +EXTERN(void) jpeg_default_colorspace JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_set_quality JPP((j_compress_ptr cinfo, int quality, + boolean force_baseline)); +EXTERN(void) jpeg_set_linear_quality JPP((j_compress_ptr cinfo, + int scale_factor, + boolean force_baseline)); +EXTERN(void) jpeg_default_qtables JPP((j_compress_ptr cinfo, + boolean force_baseline)); +EXTERN(void) jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl, + const unsigned int *basic_table, + int scale_factor, + boolean force_baseline)); +EXTERN(int) jpeg_quality_scaling JPP((int quality)); +EXTERN(void) jpeg_simple_progression JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_suppress_tables JPP((j_compress_ptr cinfo, + boolean suppress)); +EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table JPP((j_common_ptr cinfo)); +EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table JPP((j_common_ptr cinfo)); + +/* Main entry points for compression */ +EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo, + boolean write_all_tables)); +EXTERN(JDIMENSION) jpeg_write_scanlines JPP((j_compress_ptr cinfo, + JSAMPARRAY scanlines, + JDIMENSION num_lines)); +EXTERN(void) jpeg_finish_compress JPP((j_compress_ptr cinfo)); + +/* Precalculate JPEG dimensions for current compression parameters. */ +EXTERN(void) jpeg_calc_jpeg_dimensions JPP((j_compress_ptr cinfo)); + +/* Replaces jpeg_write_scanlines when writing raw downsampled data. */ +EXTERN(JDIMENSION) jpeg_write_raw_data JPP((j_compress_ptr cinfo, + JSAMPIMAGE data, + JDIMENSION num_lines)); + +/* Write a special marker. See libjpeg.txt concerning safe usage. */ +EXTERN(void) jpeg_write_marker + JPP((j_compress_ptr cinfo, int marker, + const JOCTET * dataptr, unsigned int datalen)); +/* Same, but piecemeal. */ +EXTERN(void) jpeg_write_m_header + JPP((j_compress_ptr cinfo, int marker, unsigned int datalen)); +EXTERN(void) jpeg_write_m_byte + JPP((j_compress_ptr cinfo, int val)); + +/* Alternate compression function: just write an abbreviated table file */ +EXTERN(void) jpeg_write_tables JPP((j_compress_ptr cinfo)); + +/* Decompression startup: read start of JPEG datastream to see what's there */ +EXTERN(int) jpeg_read_header JPP((j_decompress_ptr cinfo, + boolean require_image)); +/* Return value is one of: */ +#define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */ +#define JPEG_HEADER_OK 1 /* Found valid image datastream */ +#define JPEG_HEADER_TABLES_ONLY 2 /* Found valid table-specs-only datastream */ +/* If you pass require_image = TRUE (normal case), you need not check for + * a TABLES_ONLY return code; an abbreviated file will cause an error exit. + * JPEG_SUSPENDED is only possible if you use a data source module that can + * give a suspension return (the stdio source module doesn't). + */ + +/* Main entry points for decompression */ +EXTERN(boolean) jpeg_start_decompress JPP((j_decompress_ptr cinfo)); +EXTERN(JDIMENSION) jpeg_read_scanlines JPP((j_decompress_ptr cinfo, + JSAMPARRAY scanlines, + JDIMENSION max_lines)); +EXTERN(boolean) jpeg_finish_decompress JPP((j_decompress_ptr cinfo)); + +/* Replaces jpeg_read_scanlines when reading raw downsampled data. */ +EXTERN(JDIMENSION) jpeg_read_raw_data JPP((j_decompress_ptr cinfo, + JSAMPIMAGE data, + JDIMENSION max_lines)); + +/* Additional entry points for buffered-image mode. */ +EXTERN(boolean) jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo)); +EXTERN(boolean) jpeg_start_output JPP((j_decompress_ptr cinfo, + int scan_number)); +EXTERN(boolean) jpeg_finish_output JPP((j_decompress_ptr cinfo)); +EXTERN(boolean) jpeg_input_complete JPP((j_decompress_ptr cinfo)); +EXTERN(void) jpeg_new_colormap JPP((j_decompress_ptr cinfo)); +EXTERN(int) jpeg_consume_input JPP((j_decompress_ptr cinfo)); +/* Return value is one of: */ +/* #define JPEG_SUSPENDED 0 Suspended due to lack of input data */ +#define JPEG_REACHED_SOS 1 /* Reached start of new scan */ +#define JPEG_REACHED_EOI 2 /* Reached end of image */ +#define JPEG_ROW_COMPLETED 3 /* Completed one iMCU row */ +#define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */ + +/* Precalculate output dimensions for current decompression parameters. */ +EXTERN(void) jpeg_core_output_dimensions JPP((j_decompress_ptr cinfo)); +EXTERN(void) jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo)); + +/* Control saving of COM and APPn markers into marker_list. */ +EXTERN(void) jpeg_save_markers + JPP((j_decompress_ptr cinfo, int marker_code, + unsigned int length_limit)); + +/* Install a special processing method for COM or APPn markers. */ +EXTERN(void) jpeg_set_marker_processor + JPP((j_decompress_ptr cinfo, int marker_code, + jpeg_marker_parser_method routine)); + +/* Read or write raw DCT coefficients --- useful for lossless transcoding. */ +EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients JPP((j_decompress_ptr cinfo)); +EXTERN(void) jpeg_write_coefficients JPP((j_compress_ptr cinfo, + jvirt_barray_ptr * coef_arrays)); +EXTERN(void) jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo, + j_compress_ptr dstinfo)); + +/* If you choose to abort compression or decompression before completing + * jpeg_finish_(de)compress, then you need to clean up to release memory, + * temporary files, etc. You can just call jpeg_destroy_(de)compress + * if you're done with the JPEG object, but if you want to clean it up and + * reuse it, call this: + */ +EXTERN(void) jpeg_abort_compress JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_abort_decompress JPP((j_decompress_ptr cinfo)); + +/* Generic versions of jpeg_abort and jpeg_destroy that work on either + * flavor of JPEG object. These may be more convenient in some places. + */ +EXTERN(void) jpeg_abort JPP((j_common_ptr cinfo)); +EXTERN(void) jpeg_destroy JPP((j_common_ptr cinfo)); + +/* Default restart-marker-resync procedure for use by data source modules */ +EXTERN(boolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo, + int desired)); + + +/* These marker codes are exported since applications and data source modules + * are likely to want to use them. + */ + +#define JPEG_RST0 0xD0 /* RST0 marker code */ +#define JPEG_EOI 0xD9 /* EOI marker code */ +#define JPEG_APP0 0xE0 /* APP0 marker code */ +#define JPEG_COM 0xFE /* COM marker code */ + + +/* If we have a brain-damaged compiler that emits warnings (or worse, errors) + * for structure definitions that are never filled in, keep it quiet by + * supplying dummy definitions for the various substructures. + */ + +#ifdef INCOMPLETE_TYPES_BROKEN +#ifndef JPEG_INTERNALS /* will be defined in jpegint.h */ +struct jvirt_sarray_control { long dummy; }; +struct jvirt_barray_control { long dummy; }; +struct jpeg_comp_master { long dummy; }; +struct jpeg_c_main_controller { long dummy; }; +struct jpeg_c_prep_controller { long dummy; }; +struct jpeg_c_coef_controller { long dummy; }; +struct jpeg_marker_writer { long dummy; }; +struct jpeg_color_converter { long dummy; }; +struct jpeg_downsampler { long dummy; }; +struct jpeg_forward_dct { long dummy; }; +struct jpeg_entropy_encoder { long dummy; }; +struct jpeg_decomp_master { long dummy; }; +struct jpeg_d_main_controller { long dummy; }; +struct jpeg_d_coef_controller { long dummy; }; +struct jpeg_d_post_controller { long dummy; }; +struct jpeg_input_controller { long dummy; }; +struct jpeg_marker_reader { long dummy; }; +struct jpeg_entropy_decoder { long dummy; }; +struct jpeg_inverse_dct { long dummy; }; +struct jpeg_upsampler { long dummy; }; +struct jpeg_color_deconverter { long dummy; }; +struct jpeg_color_quantizer { long dummy; }; +#endif /* JPEG_INTERNALS */ +#endif /* INCOMPLETE_TYPES_BROKEN */ + + +/* + * The JPEG library modules define JPEG_INTERNALS before including this file. + * The internal structure declarations are read only when that is true. + * Applications using the library should not include jpegint.h, but may wish + * to include jerror.h. + */ + +#ifdef JPEG_INTERNALS +#include "jpegint.h" /* fetch private declarations */ +#include "jerror.h" /* fetch error codes too */ +#endif + +#ifdef __cplusplus +#ifndef DONT_USE_EXTERN_C +} +#endif +#endif + +#endif /* JPEGLIB_H */ diff --git a/scalos/include/libraries/mcpgfx.h b/scalos/include/libraries/mcpgfx.h new file mode 100755 index 000000000..996180fc9 --- /dev/null +++ b/scalos/include/libraries/mcpgfx.h @@ -0,0 +1,88 @@ +#ifndef LIBRARIES_MCPGFX_H +#define LIBRARIES_MCPGFX_H + +#ifndef EXEC_TYPES_H +#include +#endif + +#ifndef UTILITY_TAGITEM_H +#include +#endif + + +/* Types of frames available */ +#define MF_FRAME_NONE 0 /* No frame */ +#define MF_FRAME_BUTTON 1 /* Standard 3D frame used for buttons */ +#define MF_FRAME_BORDER 2 /* Standard 2D frame used for */ +#define MF_FRAME_STRING 3 /* String */ +#define MF_FRAME_DROPBOX 4 /* Dropbox [String (with space)?] */ +#define MF_FRAME_XEN 5 /* Standard XEN button */ +#define MF_FRAME_MWB 6 /* Standard MWB */ +#define MF_FRAME_THICK 7 /* Standard Thick */ +#define MF_FRAME_XWIN 8 /* Standard XWIN */ +#define MF_FRAME_MAXIMUM 9 /* Maximum number of frame types */ + + +/* Sizes of frame egdes. Always in the order x1,y1,x2,y2,(recessed)x1,y1,x2,y2. */ +struct FrameSize +{ + WORD fs_Sizes[8]; +}; + + +/* Some constants for acessing the values from the FrameSize structure */ +#define FRAMESIZE_LEFT 0 /* Normal left edge width */ +#define FRAMESIZE_TOP 1 /* Normal top edge width */ +#define FRAMESIZE_RIGHT 2 /* Normal right edge width */ +#define FRAMESIZE_BOTTOM 3 /* Normal bottom edge width */ +#define FRAMESIZE_RELEFT 4 /* Recessed left edge width */ +#define FRAMESIZE_RETOP 5 /* Recessed top edge width */ +#define FRAMESIZE_RERIGHT 6 /* Recessed right edge width */ +#define FRAMESIZE_REBOTTOM 7 /* Recessed bottom edge width */ + + +/* Tags for the various function in mcpgfx.library */ +#define MCP_TagBase TAG_USER + 0x20000 + +#if 0 + +#define IA_Left MCP_TagBase + 0x01 +#define IA_Top MCP_TagBase + 0x02 +#define IA_Width MCP_TagBase + 0x03 +#define IA_Height MCP_TagBase + 0x04 +#define IA_FGPen MCP_TagBase + 0x05 +#define IA_BGPen MCP_TagBase + 0x06 +#define IA_Data MCP_TagBase + 0x07 +#define IA_ShadowPen MCP_TagBase + 0x09 + +#endif + +#define IA_ShinePen MCP_TagBase + 0x0a + +#if 0 + +#define IA_APattern MCP_TagBase + 0x10 +#define IA_APatSize MCP_TagBase + 0x11 +#define IA_Mode MCP_TagBase + 0x12 +#define IA_Recessed MCP_TagBase + 0x15 +#define IA_DrawInfo MCP_TagBase + 0x18 +#define IA_FrameType MCP_TagBase + 0x1b + +#endif + + +#define IA_HalfShadowPen MCP_TagBase + 0x1c +#define IA_HalfShinePen MCP_TagBase + 0x1d + + +/* A little something */ +struct ExtDrawInfo +{ + struct DrawInfo edi_DrawInfo; /* Original screen DrawInfo (copy of) */ + WORD *edi_Pens; /* Pointer to an array of pens to use for MWB colours */ + ULONG edi_dunno[2]; /* like I say */ +}; + + +#endif /* LIBRARIES_MCPGFX_H */ + diff --git a/scalos/include/libraries/openurl.h b/scalos/include/libraries/openurl.h new file mode 100755 index 000000000..b8dda136a --- /dev/null +++ b/scalos/include/libraries/openurl.h @@ -0,0 +1,227 @@ +#ifndef LIBRARIES_OPENURL_H +#define LIBRARIES_OPENURL_H + +/* +** $VER: openurl.h 7.2 (1.12.2005) +** Includes Release 7.2 +** +** openurl.library - universal URL display and browser +** launcher library +** +** Written by Troels Walsted Hansen +** Placed in the public domain. +** +** Developed by: +** - Alfonso Ranieri +** - Stefan Kost +** +*/ + +#ifndef EXEC_TYPES_H +#include +#endif + +#ifndef EXEC_LISTS_H +#include +#endif + +#ifndef EXEC_NODES_H +#include +#endif + +#ifndef UTILITY_TAGITEM_H +#include +#endif + +#if defined(__PPC__) + #if defined(__GNUC__) + #pragma pack(2) + #elif defined(__VBCC__) + #pragma amiga-align + #endif +#endif + +/**************************************************************************/ +/* +** Names +*/ + +#define OPENURLNAME "openurl.library" +#define OPENURLVER 7 +#define OPENURLREV 2 + +/**************************************************************************/ +/* +** Tags +*/ + +#define URL_Tagbase ((int)0x81480000) + +#define URL_Show (URL_Tagbase + 1) /* BOOL - Uniconify browser */ +#define URL_BringToFront (URL_Tagbase + 2) /* BOOL - Bring browser to front */ +#define URL_NewWindow (URL_Tagbase + 3) /* BOOL - Open URL in new window */ +#define URL_Launch (URL_Tagbase + 4) /* BOOL - Launch browser when not running */ +#define URL_PubScreenName (URL_Tagbase + 5) /* UBYTE * - Name of public screen to launch at */ + +#define URL_GetPrefs_Mode (URL_Tagbase + 20) /* BOOL - Get default prefs */ +#define URL_GetPrefs_FallBack (URL_Tagbase + 21) /* BOOL - Do not fail (TRUE) */ + +#define URL_SetPrefs_Save (URL_Tagbase + 30) /* BOOL - Save prefs to ENVARC: also */ + +#define URL_GetAttr_Version (URL_Tagbase + 60) /* ULONG - Library version */ +#define URL_GetAttr_Revision (URL_Tagbase + 61) /* ULONG - Library revision */ +#define URL_GetAttr_VerString (URL_Tagbase + 62) /* STRPTR - "openurl.library 6.4 (27.7.2005)" */ +#define URL_GetAttr_PrefsVer (URL_Tagbase + 63) /* ULONG - Library preferences version */ + +#define URL_GetAttr_HandlerVersion (URL_Tagbase + 64) /* Obsolete !!! DON'T USE !!! */ +#define URL_GetAttr_HandlerRevision (URL_Tagbase + 65) /* Obsolete !!! DON'T USE !!! */ +#define URL_GetAttr_HandlerVerString (URL_Tagbase + 66) /* Obsolete !!! DON'T USE !!! */ + +enum +{ + URL_GetPrefs_Mode_Env, + URL_GetPrefs_Mode_Envarc, + URL_GetPrefs_Mode_Default, + URL_GetPrefs_Mode_InUse, +}; + +/**************************************************************************/ + +#define REXX_CMD_LEN 64 +#define NAME_LEN 32 +#define PATH_LEN 256 +#define PORT_LEN 32 + +#define SHOWCMD_LEN REXX_CMD_LEN +#define TOFRONTCMD_LEN REXX_CMD_LEN +#define OPENURLCMD_LEN REXX_CMD_LEN +#define OPENURLWCMD_LEN REXX_CMD_LEN +#define WRITEMAILCMD_LEN (REXX_CMD_LEN*2) + +/**************************************************************************/ +/* +** Version 4 Prefs +*/ + +#define PREFS_VERSION ((UBYTE)4) + +struct URL_Prefs +{ + UBYTE up_Version; /* always check this version number! */ + struct MinList up_BrowserList; /* list of struct URL_BrowserNodes */ + struct MinList up_MailerList; /* list of struct URL_MailerNodes */ + struct MinList up_FTPList; /* list of struct URL_MailerNodes */ + + ULONG up_Flags; /* flags, see below */ + + ULONG up_DefShow; /* these BOOLs are the defaults for */ + ULONG up_DefBringToFront; /* the similarly named tags */ + ULONG up_DefNewWindow; /* they are all new with Version 2 */ + ULONG up_DefLaunch; +}; + +/* up_Flags */ +enum +{ + UPF_ISDEFAULTS = 1<<0, /* structure contains the default settings */ + UPF_PREPENDHTTP = 1<<1, /* prepend "http://" to URLs w/o scheme */ + UPF_DOMAILTO = 1<<2, /* mailto: URLs get special treatment */ + UPF_DOFTP = 1<<3, /* ftp:// URLs get special treatment */ +}; + +/**************************************************************************/ +/* +** Common #?_Flags values +*/ + +enum +{ + UNF_DISABLED = 1<<1, /* The entry is disabled */ + + UNF_NEW = 1<<16, /* Reserved for OpenURL preferences application */ + UNF_NTALLOC = 1<<17, /* Reserved for OpenURL preferences application */ +}; + +/**************************************************************************/ +/* +** Browsers +*/ + +struct URL_BrowserNode +{ + struct MinNode ubn_Node; + ULONG ubn_Flags; /* flags, see below */ + UBYTE ubn_Name[NAME_LEN]; /* name of webbrowser */ + UBYTE ubn_Path[PATH_LEN]; /* complete path to browser */ + UBYTE ubn_Port[PORT_LEN]; /* webbrowser arexx port */ + UBYTE ubn_ShowCmd[SHOWCMD_LEN]; /* command to show/uniconify browser */ + UBYTE ubn_ToFrontCmd[TOFRONTCMD_LEN]; /* command to bring browser to front */ + UBYTE ubn_OpenURLCmd[OPENURLCMD_LEN]; /* command to open url */ + UBYTE ubn_OpenURLWCmd[OPENURLWCMD_LEN]; /* command to open url in new window */ +}; + +/* ubn_Flags */ +enum +{ + /* + ** If set, browser supports getting an URL on + ** the commandline when launched. obsolete as + ** of V3 - use %u on commandline instead + */ + UBNF_URLONCMDLINE = 1<<0, +}; + +/**************************************************************************/ +/* +** Mailers +*/ + +struct URL_MailerNode +{ + struct MinNode umn_Node; + ULONG umn_Flags; /* flags, none defined */ + UBYTE umn_Name[NAME_LEN]; /* name of mailer */ + UBYTE umn_Path[PATH_LEN]; /* complete path to mailer */ + UBYTE umn_Port[PORT_LEN]; /* mailer arexx port */ + UBYTE umn_ShowCmd[SHOWCMD_LEN]; /* command to show/uniconify mailer */ + UBYTE umn_ToFrontCmd[TOFRONTCMD_LEN]; /* command to bring mailer to front */ + UBYTE umn_WriteMailCmd[WRITEMAILCMD_LEN]; /* command to write mail */ +}; + +/**************************************************************************/ +/* +** FTPs +*/ + +struct URL_FTPNode +{ + struct MinNode ufn_Node; + ULONG ufn_Flags; /* flags, see below */ + UBYTE ufn_Name[NAME_LEN]; /* name of ftp client */ + UBYTE ufn_Path[PATH_LEN]; /* complete path to ftp client */ + UBYTE ufn_Port[PORT_LEN]; /* webbrowser arexx port */ + UBYTE ufn_ShowCmd[SHOWCMD_LEN]; /* command to show/uniconify ftp client */ + UBYTE ufn_ToFrontCmd[TOFRONTCMD_LEN]; /* command to bring ftp client to front */ + UBYTE ufn_OpenURLCmd[OPENURLCMD_LEN]; /* command to open url */ + UBYTE ufn_OpenURLWCmd[OPENURLWCMD_LEN]; /* command to open url in new window */ +}; + +/* ufn_Flags */ +enum +{ + /* If set, ftp:// ise removed from the URL */ + UFNF_REMOVEFTP = 1<<0, +}; + +/**************************************************************************/ + +#if defined(__PPC__) + #if defined(__GNUC__) + #pragma pack() + #elif defined(__VBCC__) + #pragma default-align + #endif +#endif + +#endif /* LIBRARIES_OPENURL_H */ + diff --git a/scalos/include/libraries/pm.h b/scalos/include/libraries/pm.h new file mode 100755 index 000000000..9a48c7871 --- /dev/null +++ b/scalos/include/libraries/pm.h @@ -0,0 +1,311 @@ +/* +// $VER: pm.h 10.05 (11.11.00) +// +// Library base, tags and macro definitions +// for popupmenu.library. +// +// ©1996-2000 Henrik Isaksson +// All Rights Reserved. +// +// Changes: +// +// 9.00 New PopupMenu structure. +// Several new tags and updated macros. +// 9.01 Added PM_HintBox +// 10.0 Added PM_Toggle, PM_ExcludeShared +// Added macro PMMXItem +// Added two flags, PM_CHECKIT and PM_CHECKED +// 10.05 Changed the PopupMenu structure a bit. +// Added typedef for PopupMenu. +// Added american english equalients for some tags. +// +*/ + +#ifndef LIBRARIES_POPUPMENU_H +#define LIBRARIES_POPUPMENU_H + +#ifndef EXEC_TYPES_H +#include +#endif + +#ifndef EXEC_LIBRARIES_H +#include +#endif + +#ifndef UTILITY_TAGITEM_H +#include +#endif + +#ifndef INTUITION_CLASSUSR_H +#include +#endif + +/* +// Tags passed to PM_OpenPopupMenuA and PM_FilterIMsgA +*/ + +#define PM_Menu (TAG_USER+4) /* (struct PopupMenu *) Pointer to menulist initialized by MakeMenu() */ +#define PM_Top (TAG_USER+12) /* (LONG) Top (Y) position */ +#define PM_Left (TAG_USER+13) /* (LONG) Left (X) position */ +#define PM_Code (TAG_USER+14) /* (UWORD) Obsolete. */ +#define PM_Right (TAG_USER+15) /* (LONG) X position relative to right edge */ +#define PM_Bottom (TAG_USER+16) /* (LONG) Y position relative to bottom edge */ +#define PM_MinWidth (TAG_USER+17) /* (LONG) Minimum width */ +#define PM_MinHeight (TAG_USER+18) /* (LONG) Minimum height */ +#define PM_ForceFont (TAG_USER+19) /* (struct TextFont *tf) Use this font instead of user preferences. */ +#define PM_PullDown (TAG_USER+90) /* (BOOL) Turn the menu into a pulldown menu. */ +#define PM_MenuHandler (TAG_USER+91) /* (struct Hook *) Hook that is called for each selected item, after the */ + /* menu has been closed. This tag turns on MultiSelect. */ +#define PM_AutoPullDown (TAG_USER+92) /* (BOOL) Automatic pulldown menu. (PM_FilterIMsg only) */ +#define PM_LocaleHook (TAG_USER+93) /* (struct Hook *) Locale "GetString()" hook. (Not yet implemented) */ +#define PM_CenterScreen (TAG_USER+94) /* (BOOL) Center menu on the screen */ +#define PM_UseLMB (TAG_USER+95) /* (BOOL) Left mouse button should be used to select an item */ + /* (right button selects multiple items) */ +#define PM_DRIPensOnly (TAG_USER+96) /* (BOOL) Only use the screen's DRI pens, revert to system images if necessary. */ + /* Use with care as it overrides the user's prefs! */ +#define PM_HintBox (TAG_USER+97) /* (BOOL) Close the menu when the mouse is moved. */ +#define PM_RawKey (TAG_USER+98) /* (BOOL) Let PM_FilterIMsgA parse IDCMP_RAWKEY instead of IDCMP_VANILLAKEY. */ + +/* +// Tags passed to MakeItem +*/ + +#define PM_Title (TAG_USER+20) /* (STRPTR) Item title */ +#define PM_UserData (TAG_USER+21) /* (void *) Anything, returned by OpenPopupMenu when this item is selected */ +#define PM_ID (TAG_USER+22) /* (ULONG) ID number, if you want an easy way to access this item later */ +#define PM_CommKey (TAG_USER+47) /* (char) Keyboard shortcut for this item. */ +#define PM_TitleID (TAG_USER+49) /* (ULONG) Locale string ID */ +#define PM_Object (TAG_USER+43) /* (Object *) BOOPSI object with the abillity to render this item */ + +/* Submenu & Layout tags */ +/* PM_Sub & PM_Members are mutally exclusive */ +#define PM_Sub (TAG_USER+23) /* (PopupMenu *) Pointer to submenu list (from PM_MakeMenu) */ +#define PM_Members (TAG_USER+65) /* (PopupMenu *) Members for this group (list created by PM_MakeMenu) */ +#define PM_LayoutMode (TAG_USER+64) /* (ULONG) Layout method (PML_Horizontal / PML_Vertical) */ + +/* Text attributes */ +#define PM_FillPen (TAG_USER+26) /* (BOOL) Make the item appear in FILLPEN */ +#define PM_Italic (TAG_USER+29) /* (BOOL) Italic text */ +#define PM_Bold (TAG_USER+30) /* (BOOL) Bold text */ +#define PM_Underlined (TAG_USER+31) /* (BOOL) Underlined text */ +#define PM_ShadowPen (TAG_USER+34) /* (BOOL) Draw text in SHADOWPEN */ +#define PM_ShinePen (TAG_USER+35) /* (BOOL) Draw text in SHINEPEN */ +#define PM_Centre (TAG_USER+36) /* (BOOL) Center the text of this item */ +#define PM_Center PM_Centre /* American version... */ +#define PM_TextPen (TAG_USER+45) /* (ULONG) Pen number for text colour of this item */ +#define PM_Shadowed (TAG_USER+48) /* (BOOL) Draw a shadow behind the text */ + +/* Other item attributes */ +#define PM_TitleBar (TAG_USER+32) /* (BOOL) Horizontal separator bar */ +#define PM_WideTitleBar (TAG_USER+33) /* (BOOL) Same as above, but full width */ +#define PM_NoSelect (TAG_USER+25) /* (BOOL) Make the item unselectable (without visual indication) */ +#define PM_Disabled (TAG_USER+38) /* (BOOL) Disable an item */ +#define PM_Hidden (TAG_USER+63) /* (BOOL) This item is not to be drawn (nor used in the layout process) */ + +/* Images & Icons */ +#define PM_ImageSelected (TAG_USER+39) /* (struct Image *) Image when selected, title will be rendered on top it */ +#define PM_ImageUnselected (TAG_USER+40) /* (struct Image *) Image when unselected */ +#define PM_IconSelected (TAG_USER+41) /* (struct Image *) Icon when selected */ +#define PM_IconUnselected (TAG_USER+42) /* (struct Image *) Icon when unselected */ + +/* Check/MX items */ +#define PM_Checkit (TAG_USER+27) /* (BOOL) Leave space for a checkmark */ +#define PM_Checked (TAG_USER+28) /* (BOOL) Make this item is checked */ +#define PM_AutoStore (TAG_USER+44) /* (BOOL *) Pointer to BOOL reflecting the current state of the item */ +#define PM_Exclude (TAG_USER+37) /* (PM_IDLst *) Items to unselect or select when this gets selected */ +#define PM_ExcludeShared (TAG_USER+101) /* (BOOL) Used if the list is shared between two or more items */ +#define PM_Toggle (TAG_USER+100) /* (BOOL) Enable/disable toggling of check/mx items. Default: TRUE */ + +/* Dynamic construction/destruction */ +#define PM_SubConstruct (TAG_USER+61) /* (struct Hook *) Constructor hook for submenus. Called before menu is opened. */ +#define PM_SubDestruct (TAG_USER+62) /* (struct Hook *) Destructor hook for submenus. Called after menu has closed. */ + +/* Special/misc. stuff */ +#define PM_UserDataString (TAG_USER+46) /* (STRPTR) Allocates memory and copies the string to UserData. */ +#define PM_Flags (TAG_USER+24) /* (UlONG) For internal use */ +#define PM_ColourBox (TAG_USER+60) /* (UlONG) Filled rectangle (for palettes etc.) */ +#define PM_ColorBox PM_ColourBox /* For Americans... */ +/* +// Tags passed to MakeMenu +*/ + +#define PM_Item (TAG_USER+50) /* (PopupMenu *) Item pointer from MakeItem */ +#define PM_Dummy (TAG_USER+51) /* (void) Ignored. */ + +/* +// Tags passed to MakeIDList +*/ + +#define PM_ExcludeID (TAG_USER+55) /* (ULONG) ID number of menu to deselect when this gets selected */ +#define PM_IncludeID (TAG_USER+56) /* (ULONG) ID number of menu to select when this gets selected */ +#define PM_ReflectID (TAG_USER+57) /* (ULONG) ID number of menu that should reflect the state of this one */ +#define PM_InverseID (TAG_USER+58) /* (ULONG) ID number of menu to inverse reflect the state of this one */ + +/* +// Tags for PM_InsertMenuItemA() +*/ + +#define PM_Insert_Before (TAG_USER+200) /* (BOOL) Insert before the item pointed to by the following argument (N/A) */ +#define PM_Insert_BeforeID (TAG_USER+201) /* (ULONG) Insert before the first item with ID equal to the argument */ +#define PM_Insert_After (TAG_USER+202) /* (PopupMenu *) Insert after the item pointed to by the following argument */ +#define PM_Insert_AfterID (TAG_USER+203) /* (ULONG) Insert after the first item with ID equal to the argument */ +#define PM_Insert_Last (TAG_USER+205) /* (BOOL) Insert after the last item */ +#define PM_Insert_First (TAG_USER+209) /* (BOOL) Insert after the first item (which is usually invisible) */ +#define PM_InsertSub_First (TAG_USER+206) /* (PopupMenu *) Insert before the first item in the submenu */ +#define PM_InsertSub_Last (TAG_USER+207) /* (PopupMenu *) Insert at the and of a submenu */ +#define PM_InsertSub_Sorted (TAG_USER+208) /* (PopupMenu *) (N/A) */ +#define PM_Insert_Item (TAG_USER+210) /* (PopupMenu *) Item to insert, may be repeated for several items */ + +/* +// Layout methods +*/ + +#define PML_None 0 /* Normal item */ +#define PML_Horizontal 1 /* Horizontal group */ +#define PML_Vertical 2 /* Vertical group */ +#define PML_Table 3 /* Table group */ +#define PML_Default 255 /* Don't use */ + +/* +// Macros +*/ + +#define PMMenu(t) PM_MakeMenu(\ + PM_Item, PM_MakeItem(PM_Hidden, TRUE, TAG_DONE),\ + PM_Item, PM_MakeItem(PM_Title, t, PM_NoSelect, TRUE, PM_ShinePen, TRUE, PM_Shadowed, TRUE, PM_Center, TRUE, TAG_DONE),\ + PM_Item, PM_MakeItem(PM_WideTitleBar, TRUE, TAG_DONE) +#define PMMenuID(t) PM_MakeMenu(\ + PM_Item, PM_MakeItem(PM_Hidden, TRUE, TAG_DONE),\ + PM_Item, PM_MakeItem(PM_TitleID, t, PM_NoSelect, TRUE, PM_ShinePen, TRUE, PM_Shadowed, TRUE, PM_Center, TRUE, TAG_DONE),\ + PM_Item, PM_MakeItem(PM_WideTitleBar, TRUE, TAG_DONE) +#define PMSubMenu(t) PM_Sub, PM_MakeMenu(PM_Item, PM_MakeItem(PM_Title, t, PM_NoSelect, TRUE, PM_ShinePen, TRUE, TAG_DONE),\ + PM_Item, PM_MakeItem(PM_WideTitleBar, TRUE, TAG_DONE) +#define PMSimpleSub PM_Sub, PM_MakeMenu(PM_Dummy, 0 +#define PMItem(t) PM_Item, PM_MakeItem(PM_Title, t +#define PMItemID(t) PM_Item, PM_MakeItem(PM_TitleID, t +#define PMInfo(t) PM_Item, PM_MakeItem(PM_Title, t, PM_NoSelect, TRUE, PM_ShinePen, TRUE +#define PMColBox(c) PM_Item, PM_MakeItem(PM_ColourBox, c +#define PMBar PM_Item, PM_MakeItem(PM_TitleBar, TRUE +#define PMMenuTitle(t) PM_Item, PM_MakeItem(PM_Title, t, PM_NoSelect, TRUE, PM_ShinePen, TRUE, PM_Shadowed, TRUE, PM_Center, TRUE, TAG_DONE),\ + PM_Item, PM_MakeItem(PM_WideTitleBar, TRUE, TAG_DONE) +#define PMHoriz PM_Item, PM_MakeItem(PM_NoSelect, TRUE, PM_LayoutMode, PML_Horizontal +#define PMVert PM_Item, PM_MakeItem(PM_NoSelect, TRUE, PM_LayoutMode, PML_Vertical +#define PMMembers PM_Members, PM_MakeMenu(PM_Dummy, 0 + +#define PMExcl PM_Exclude, PM_MakeIDList( +#define ExID(id) PM_ExcludeID, id +#define InID(id) PM_IncludeID, id +#define RefID(id) PM_ReflectID, id +#define InvID(id) PM_InverseID, id + +#define PMCheckItem(t,id) PM_Item, PM_MakeItem(PM_Title, t, PM_ID, id, PM_Checkit, TRUE + +#define PMMXItem(t,id) PM_Item, PM_MakeItem(PM_Title, t, PM_ID, id, PM_Checkit, TRUE, PM_Toggle, FALSE + +#define PMEnd TAG_DONE) + +#ifndef End +#define End TAG_DONE) +#endif + +#define PMERR (-5L) + +/* For compatibility with old sources - DO NOT USE */ +#define PMTitleBar PMBar +#define PMNarrowBar PMBar +#define PMNarrowTitleBar PMBar + +/* +// Library base +*/ + +#ifndef PM_NOBASE + +struct PopupMenuBase { + struct Library pmb_Library; + ULONG pmb_SegList; + ULONG pmb_Flags; + struct Library *pmb_ExecBase; /* Theese library */ + struct Library *pmb_UtilityBase; /* pointers are */ + struct Library *pmb_IntuitionBase; /* valid as long */ + struct Library *pmb_GfxBase; /* as pm lib */ + struct Library *pmb_DOSBase; /* is open. */ + BOOL pmb_NewPrefs; /* Reload prefs. */ + struct Library *pmb_CxBase; /* commodities. */ + struct Library *pmb_LayersBase; /* layers.library */ + struct Library *pmb_CyberGfxBase; /* cybergfx.lib */ + struct Library *pmb_PreferencesBase; /* preferences.library */ +}; + +#endif + +#define POPUPMENU_VERSION 10L +#define POPUPMENU_NAME "popupmenu.library" +#define OPEN_PM_LIB (PopupMenuBase=(struct PopupMenuBase *)\ + OpenLibrary(POPUPMENU_NAME, POPUPMENU_VERSION)) +#define CLOSE_PM_LIB if(PopupMenuBase) CloseLibrary((struct Library *)PopupMenuBase); + +/* +// PopupMenu structure +// +// Note: +// This structure may change in future versions. +// Do not read or write fields directly, use PM_Set/GetPopupMenuAttrs() +*/ + +struct PopupMenu { + struct PopupMenu *Next; /* Next item in menu */ + union { + struct PopupMenu *Sub; /* Sub menu pointer */ + struct PopupMenu *Group; /* Group members */ + } SubGroup; + + union { + STRPTR Title; /* Title */ + ULONG TitleID; /* Locale string ID */ + Object *Boopsi; /* Boopsi object */ + } TitleUnion; + + ULONG Flags; /* Flags */ + ULONG ID; /* Item ID */ + APTR UserData; /* UserData */ + + WORD Left; /* Left pos of this item */ + WORD Top; /* Top pos of this item */ + UWORD Width; /* Width of this item */ + UWORD Height; /* Height of this item */ + + /* Very private and undocumented stuff follows. */ + /* Mess with it at your own risk. */ + + UWORD ExtFlags; /* Extended flags */ + + UBYTE Layout; /* Layout mode */ + UBYTE CBox; /* ColourBox pen */ + + struct PM_IDLst *Exclude; /* Exclude/Included/Reflected items */ + BOOL *AutoSetPtr;/* Ptr to BOOL containing current state */ + + union { + struct Image *Images[2]; /* Images/Icons (0 - unselected, 1 - sel) */ + STRPTR IconID; + } ImageUnion; + + UBYTE CommKey; /* Command Key */ + UBYTE Weight; /* Weight */ + struct Hook *SubConstruct; /* SubMenu Constructor hook */ + struct Hook *SubDestruct; /* SubMenu Destructor hook */ + UBYTE TextPen; /* Pen number for item's text */ + UBYTE Pad; + + APTR Image; +}; + +typedef struct PopupMenu PopupMenu; + +/* Public flags for the PopupMenu->Header.Flags field */ + +#define PM_CHECKIT 0x40000000 +#define PM_CHECKED 0x80000000 + +#endif diff --git a/scalos/include/libraries/ttengine.h b/scalos/include/libraries/ttengine.h new file mode 100755 index 000000000..98b62c63b --- /dev/null +++ b/scalos/include/libraries/ttengine.h @@ -0,0 +1,149 @@ +#ifndef LIBRARIES_TTENGINE_H +#define LIBRARIES_TTENGINE_H + +/* $VER: ttengine.h 7.2 (5.4.2005) (c) by Grzegorz Kraszewski 2002 - 2005. */ + +#define TTENGINENAME "ttengine.library" +#define TTENGINEVERSION 7 +#define TTENGINEMINVERSION 6 + +/* Tags */ + +/* Tags applicability legend: */ +/* O - TT_OpenFont() */ +/* G - TT_GetAttrs() */ +/* S - TT_SetAttrs() */ +/* P - TT_GetPixmap() */ + +/* ---- name -------------------- value ----- applicability */ + +#define TT_FontFile 0x6EDA0000 /* OG.. */ + +#define TT_FontStyle 0x6EDA0001 /* OG.. */ + +#define TT_FontStyle_Regular 0 +#define TT_FontStyle_Italic 1 + +#define TT_FamilyTable 0x6EDA0002 /* O... */ +#define TT_FontSize 0x6EDA0003 /* OG.. */ + +#define TT_FontWeight 0x6EDA0004 /* OG.. */ + +#define TT_FontWeight_Normal 400 +#define TT_FontWeight_Bold 700 + +#define TT_ColorMap 0x6EDA0005 /* O... */ +#define TT_Screen 0x6EDA0006 /* O... */ +#define TT_Window 0x6EDA0007 /* O... */ +#define TT_FontAscender 0x6EDA0008 /* .G.. */ +#define TT_FontDescender 0x6EDA0009 /* .G.. */ + +#define TT_Antialias 0x6EDA000F /* .GSP */ + +#define TT_Antialias_Auto 0 +#define TT_Antialias_Off 1 +#define TT_Antialias_On 2 + +#define TT_Encoding 0x6EDA0010 /* .GSP */ + +/* All encoding numbers (excluding TT_Encoding_Default) are equal to IANA */ +/* registered encoding numbers */ + +#define TT_Encoding_Default 0 /* use ENV:ttfcodepage or ISO-8859-1 if not found */ +#define TT_Encoding_ISO8859_1 4 /* Western Europe and US */ +#define TT_Encoding_ISO8859_2 5 /* Eastern Europe */ +#define TT_Encoding_ISO8859_3 6 +#define TT_Encoding_ISO8859_4 7 +#define TT_Encoding_ISO8859_5 8 +#define TT_Encoding_ISO8859_6 9 +#define TT_Encoding_ISO8859_7 10 +#define TT_Encoding_ISO8859_8 11 +#define TT_Encoding_ISO8859_9 12 +#define TT_Encoding_ISO8859_10 13 +#define TT_Encoding_ISO8859_11 14 +#define TT_Encoding_ISO8859_13 109 +#define TT_Encoding_ISO8859_14 110 +#define TT_Encoding_ISO8859_15 111 +#define TT_Encoding_ISO8859_16 112 +#define TT_Encoding_UTF16_BE 1013 +#define TT_Encoding_UTF32_BE 1018 +#define TT_Encoding_UTF8 106 +#define TT_Encoding_UTF16_LE 1014 +#define TT_Encoding_UTF32_LE 1019 +#define TT_Encoding_UTF16 1015 +#define TT_Encoding_UTF32 1017 + +#define TT_FontName 0x6EDA0011 /* .G.. */ +#define TT_FamilyName 0x6EDA0012 /* .G.. */ +#define TT_SubfamilyName 0x6EDA0013 /* .G.. */ +#define TT_Transparency 0x6EDA0014 /* .GS. from 0 to 255 */ +#define TT_ScaleX 0x6EDA0015 /* O.SP 16.16 scaled integer */ + +#define TT_SoftStyle 0x6EDA0017 /* ..SP (V5) */ + +#define TT_SoftStyle_None 0x0000 +#define TT_SoftStyle_Underlined 0x0001 +#define TT_SoftStyle_DblUnderlined 0x0002 +#define TT_SoftStyle_Overstriked 0x0004 +#define TT_SoftStyle_DblOverstriked 0x0008 + +#define TT_Foreground 0x6EDA0018 /* ..S. foreground RGB value*/ + +#define TT_Foreground_UseRastPort 0xFFFFFFFF + +#define TT_Background 0x6EDA0019 /* ..S. background RGB value*/ + +#define TT_Background_UseRastPort 0xFFFFFFFF + +#define TT_FontMaxTop 0x6EDA001E /* .G.. */ +#define TT_FontMaxBottom 0x6EDA001F /* .G.. */ +#define TT_FontDesignHeight 0x6EDA0020 /* .G.. */ +#define TT_FontRealAscender 0x6EDA0021 /* .G.. */ +#define TT_FontRealDescender 0x6EDA0022 /* .G.. */ +#define TT_FontAccentedAscender 0x6EDA0023 /* .G.. */ +#define TT_CustomEncoding 0x6EDA0024 /* ..SP */ +#define TT_Gamma 0x6EDA0025 /* .GS. */ /* gettable from V7.2 */ +#define TT_FontBaseline TT_FontMaxTop /* V6.7 */ +#define TT_FontFixedWidth 0x6EDA0026 /* OG.. */ /* V6.7 */ +#define TT_FontHeight 0x6EDA0027 /* .G.. */ /* V6.7 */ +#define TT_FontWidth 0x6EDA0028 /* .G.. */ /* V6.7 */ +#define TT_DiskFontMetrics 0x6EDA0029 /* ..SP */ /* V6.7 */ +#define TT_ForceFixedWidth 0x6EDA0030 /* ..SP */ /* V7.2 */ + +/* Structure returned by TT_GetPixmap() (V5)*/ + +struct TT_Pixmap +{ + ULONG ttp_Size; /* size of the structure inculdung this field */ + ULONG ttp_Width; /* also equal to bytes per row */ + ULONG ttp_Height; /* number of rows */ + UBYTE *ttp_Data; /* grayscale pixmap data */ +}; + +/* font requester attributes (V6) */ + + /* type, default value */ + +#define TTRQ_Window 0x6EDA2000 /* struct Window*, NULL */ +#define TTRQ_PubScreenName 0x6EDA2001 /* STRPTR, NULL [Workbench] */ +#define TTRQ_Screen 0x6EDA2002 /* struct Screen*, NULL */ +#define TTRQ_SleepWindow 0x6EDA2003 /* BOOL, FALSE */ +#define TTRQ_TitleText 0x6EDA2004 /* STRPTR, "Select TrueType font" or localized */ +#define TTRQ_PositiveText 0x6EDA2005 /* STRPTR, "OK" or localized */ +#define TTRQ_NegativeText 0x6EDA2006 /* STRPTR, "Cancel" or localized */ +#define TTRQ_InitialLeftEdge 0x6EDA2007 /* WORD, centered on screen */ +#define TTRQ_InitialTopEdge 0x6EDA2008 /* WORD, centered on screen */ +#define TTRQ_InitialWidth 0x6EDA2009 /* WORD, max(200, 25% of sceeen width) */ +#define TTRQ_InitialHeight 0x6EDA200A /* WORD, max(200, 50% of screen height) */ +#define TTRQ_DoSizes 0x6EDA200B /* BOOL, TRUE */ +#define TTRQ_DoWeight 0x6EDA200C /* BOOL, FALSE */ +#define TTRQ_DoStyle 0x6EDA200D /* BOOL, FALSE */ +#define TTRQ_Activate 0x6EDA200E /* BOOL, TRUE */ +#define TTRQ_InitialSize 0x6EDA200F /* LONG, 0 [no size] */ +#define TTRQ_InitialName 0x6EDA2010 /* STRPTR, NULL [no name] */ +#define TTRQ_InitialStyle 0x6EDA2011 /* LONG, TT_FontStyle_Regular */ +#define TTRQ_DoPreview 0x6EDA2012 /* BOOL, FALSE */ +#define TTRQ_FixedWidthOnly 0x6EDA2013 /* BOOL, FALSE */ + +#endif /* LIBRARIES_TTENGINE_H */ + diff --git a/scalos/include/png.h b/scalos/include/png.h new file mode 100644 index 000000000..527392738 --- /dev/null +++ b/scalos/include/png.h @@ -0,0 +1,3319 @@ + +/* png.h - header file for PNG reference library + * + * libpng version 1.6.7 - November 14, 2013 + * Copyright (c) 1998-2013 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This code is released under the libpng license (See LICENSE, below) + * + * Authors and maintainers: + * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat + * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger + * libpng versions 0.97, January 1998, through 1.6.7 - November 14, 2013: Glenn + * See also "Contributing Authors", below. + * + * Note about libpng version numbers: + * + * Due to various miscommunications, unforeseen code incompatibilities + * and occasional factors outside the authors' control, version numbering + * on the library has not always been consistent and straightforward. + * The following table summarizes matters since version 0.89c, which was + * the first widely used release: + * + * source png.h png.h shared-lib + * version string int version + * ------- ------ ----- ---------- + * 0.89c "1.0 beta 3" 0.89 89 1.0.89 + * 0.90 "1.0 beta 4" 0.90 90 0.90 [should have been 2.0.90] + * 0.95 "1.0 beta 5" 0.95 95 0.95 [should have been 2.0.95] + * 0.96 "1.0 beta 6" 0.96 96 0.96 [should have been 2.0.96] + * 0.97b "1.00.97 beta 7" 1.00.97 97 1.0.1 [should have been 2.0.97] + * 0.97c 0.97 97 2.0.97 + * 0.98 0.98 98 2.0.98 + * 0.99 0.99 98 2.0.99 + * 0.99a-m 0.99 99 2.0.99 + * 1.00 1.00 100 2.1.0 [100 should be 10000] + * 1.0.0 (from here on, the 100 2.1.0 [100 should be 10000] + * 1.0.1 png.h string is 10001 2.1.0 + * 1.0.1a-e identical to the 10002 from here on, the shared library + * 1.0.2 source version) 10002 is 2.V where V is the source code + * 1.0.2a-b 10003 version, except as noted. + * 1.0.3 10003 + * 1.0.3a-d 10004 + * 1.0.4 10004 + * 1.0.4a-f 10005 + * 1.0.5 (+ 2 patches) 10005 + * 1.0.5a-d 10006 + * 1.0.5e-r 10100 (not source compatible) + * 1.0.5s-v 10006 (not binary compatible) + * 1.0.6 (+ 3 patches) 10006 (still binary incompatible) + * 1.0.6d-f 10007 (still binary incompatible) + * 1.0.6g 10007 + * 1.0.6h 10007 10.6h (testing xy.z so-numbering) + * 1.0.6i 10007 10.6i + * 1.0.6j 10007 2.1.0.6j (incompatible with 1.0.0) + * 1.0.7beta11-14 DLLNUM 10007 2.1.0.7beta11-14 (binary compatible) + * 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 (binary compatible) + * 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible) + * 1.0.7 1 10007 (still compatible) + * 1.0.8beta1-4 1 10008 2.1.0.8beta1-4 + * 1.0.8rc1 1 10008 2.1.0.8rc1 + * 1.0.8 1 10008 2.1.0.8 + * 1.0.9beta1-6 1 10009 2.1.0.9beta1-6 + * 1.0.9rc1 1 10009 2.1.0.9rc1 + * 1.0.9beta7-10 1 10009 2.1.0.9beta7-10 + * 1.0.9rc2 1 10009 2.1.0.9rc2 + * 1.0.9 1 10009 2.1.0.9 + * 1.0.10beta1 1 10010 2.1.0.10beta1 + * 1.0.10rc1 1 10010 2.1.0.10rc1 + * 1.0.10 1 10010 2.1.0.10 + * 1.0.11beta1-3 1 10011 2.1.0.11beta1-3 + * 1.0.11rc1 1 10011 2.1.0.11rc1 + * 1.0.11 1 10011 2.1.0.11 + * 1.0.12beta1-2 2 10012 2.1.0.12beta1-2 + * 1.0.12rc1 2 10012 2.1.0.12rc1 + * 1.0.12 2 10012 2.1.0.12 + * 1.1.0a-f - 10100 2.1.1.0a-f (branch abandoned) + * 1.2.0beta1-2 2 10200 2.1.2.0beta1-2 + * 1.2.0beta3-5 3 10200 3.1.2.0beta3-5 + * 1.2.0rc1 3 10200 3.1.2.0rc1 + * 1.2.0 3 10200 3.1.2.0 + * 1.2.1beta1-4 3 10201 3.1.2.1beta1-4 + * 1.2.1rc1-2 3 10201 3.1.2.1rc1-2 + * 1.2.1 3 10201 3.1.2.1 + * 1.2.2beta1-6 12 10202 12.so.0.1.2.2beta1-6 + * 1.0.13beta1 10 10013 10.so.0.1.0.13beta1 + * 1.0.13rc1 10 10013 10.so.0.1.0.13rc1 + * 1.2.2rc1 12 10202 12.so.0.1.2.2rc1 + * 1.0.13 10 10013 10.so.0.1.0.13 + * 1.2.2 12 10202 12.so.0.1.2.2 + * 1.2.3rc1-6 12 10203 12.so.0.1.2.3rc1-6 + * 1.2.3 12 10203 12.so.0.1.2.3 + * 1.2.4beta1-3 13 10204 12.so.0.1.2.4beta1-3 + * 1.0.14rc1 13 10014 10.so.0.1.0.14rc1 + * 1.2.4rc1 13 10204 12.so.0.1.2.4rc1 + * 1.0.14 10 10014 10.so.0.1.0.14 + * 1.2.4 13 10204 12.so.0.1.2.4 + * 1.2.5beta1-2 13 10205 12.so.0.1.2.5beta1-2 + * 1.0.15rc1-3 10 10015 10.so.0.1.0.15rc1-3 + * 1.2.5rc1-3 13 10205 12.so.0.1.2.5rc1-3 + * 1.0.15 10 10015 10.so.0.1.0.15 + * 1.2.5 13 10205 12.so.0.1.2.5 + * 1.2.6beta1-4 13 10206 12.so.0.1.2.6beta1-4 + * 1.0.16 10 10016 10.so.0.1.0.16 + * 1.2.6 13 10206 12.so.0.1.2.6 + * 1.2.7beta1-2 13 10207 12.so.0.1.2.7beta1-2 + * 1.0.17rc1 10 10017 12.so.0.1.0.17rc1 + * 1.2.7rc1 13 10207 12.so.0.1.2.7rc1 + * 1.0.17 10 10017 12.so.0.1.0.17 + * 1.2.7 13 10207 12.so.0.1.2.7 + * 1.2.8beta1-5 13 10208 12.so.0.1.2.8beta1-5 + * 1.0.18rc1-5 10 10018 12.so.0.1.0.18rc1-5 + * 1.2.8rc1-5 13 10208 12.so.0.1.2.8rc1-5 + * 1.0.18 10 10018 12.so.0.1.0.18 + * 1.2.8 13 10208 12.so.0.1.2.8 + * 1.2.9beta1-3 13 10209 12.so.0.1.2.9beta1-3 + * 1.2.9beta4-11 13 10209 12.so.0.9[.0] + * 1.2.9rc1 13 10209 12.so.0.9[.0] + * 1.2.9 13 10209 12.so.0.9[.0] + * 1.2.10beta1-7 13 10210 12.so.0.10[.0] + * 1.2.10rc1-2 13 10210 12.so.0.10[.0] + * 1.2.10 13 10210 12.so.0.10[.0] + * 1.4.0beta1-5 14 10400 14.so.0.0[.0] + * 1.2.11beta1-4 13 10211 12.so.0.11[.0] + * 1.4.0beta7-8 14 10400 14.so.0.0[.0] + * 1.2.11 13 10211 12.so.0.11[.0] + * 1.2.12 13 10212 12.so.0.12[.0] + * 1.4.0beta9-14 14 10400 14.so.0.0[.0] + * 1.2.13 13 10213 12.so.0.13[.0] + * 1.4.0beta15-36 14 10400 14.so.0.0[.0] + * 1.4.0beta37-87 14 10400 14.so.14.0[.0] + * 1.4.0rc01 14 10400 14.so.14.0[.0] + * 1.4.0beta88-109 14 10400 14.so.14.0[.0] + * 1.4.0rc02-08 14 10400 14.so.14.0[.0] + * 1.4.0 14 10400 14.so.14.0[.0] + * 1.4.1beta01-03 14 10401 14.so.14.1[.0] + * 1.4.1rc01 14 10401 14.so.14.1[.0] + * 1.4.1beta04-12 14 10401 14.so.14.1[.0] + * 1.4.1 14 10401 14.so.14.1[.0] + * 1.4.2 14 10402 14.so.14.2[.0] + * 1.4.3 14 10403 14.so.14.3[.0] + * 1.4.4 14 10404 14.so.14.4[.0] + * 1.5.0beta01-58 15 10500 15.so.15.0[.0] + * 1.5.0rc01-07 15 10500 15.so.15.0[.0] + * 1.5.0 15 10500 15.so.15.0[.0] + * 1.5.1beta01-11 15 10501 15.so.15.1[.0] + * 1.5.1rc01-02 15 10501 15.so.15.1[.0] + * 1.5.1 15 10501 15.so.15.1[.0] + * 1.5.2beta01-03 15 10502 15.so.15.2[.0] + * 1.5.2rc01-03 15 10502 15.so.15.2[.0] + * 1.5.2 15 10502 15.so.15.2[.0] + * 1.5.3beta01-10 15 10503 15.so.15.3[.0] + * 1.5.3rc01-02 15 10503 15.so.15.3[.0] + * 1.5.3beta11 15 10503 15.so.15.3[.0] + * 1.5.3 [omitted] + * 1.5.4beta01-08 15 10504 15.so.15.4[.0] + * 1.5.4rc01 15 10504 15.so.15.4[.0] + * 1.5.4 15 10504 15.so.15.4[.0] + * 1.5.5beta01-08 15 10505 15.so.15.5[.0] + * 1.5.5rc01 15 10505 15.so.15.5[.0] + * 1.5.5 15 10505 15.so.15.5[.0] + * 1.5.6beta01-07 15 10506 15.so.15.6[.0] + * 1.5.6rc01-03 15 10506 15.so.15.6[.0] + * 1.5.6 15 10506 15.so.15.6[.0] + * 1.5.7beta01-05 15 10507 15.so.15.7[.0] + * 1.5.7rc01-03 15 10507 15.so.15.7[.0] + * 1.5.7 15 10507 15.so.15.7[.0] + * 1.6.0beta01-40 16 10600 16.so.16.0[.0] + * 1.6.0rc01-08 16 10600 16.so.16.0[.0] + * 1.6.0 16 10600 16.so.16.0[.0] + * 1.6.1beta01-09 16 10601 16.so.16.1[.0] + * 1.6.1rc01 16 10601 16.so.16.1[.0] + * 1.6.1 16 10601 16.so.16.1[.0] + * 1.6.2beta01 16 10602 16.so.16.2[.0] + * 1.6.2rc01-06 16 10602 16.so.16.2[.0] + * 1.6.2 16 10602 16.so.16.2[.0] + * 1.6.3beta01-11 16 10603 16.so.16.3[.0] + * 1.6.3rc01 16 10603 16.so.16.3[.0] + * 1.6.3 16 10603 16.so.16.3[.0] + * 1.6.4beta01-02 16 10604 16.so.16.4[.0] + * 1.6.4rc01 16 10604 16.so.16.4[.0] + * 1.6.4 16 10604 16.so.16.4[.0] + * 1.6.5 16 10605 16.so.16.5[.0] + * 1.6.6 16 10606 16.so.16.6[.0] + * 1.6.7beta01-04 16 10607 16.so.16.7[.0] + * 1.6.7rc01-02 16 10607 16.so.16.7[.0] + * 1.6.7 16 10607 16.so.16.7[.0] + * + * Henceforth the source version will match the shared-library major + * and minor numbers; the shared-library major version number will be + * used for changes in backward compatibility, as it is intended. The + * PNG_LIBPNG_VER macro, which is not used within libpng but is available + * for applications, is an unsigned integer of the form xyyzz corresponding + * to the source version x.y.z (leading zeros in y and z). Beta versions + * were given the previous public release number plus a letter, until + * version 1.0.6j; from then on they were given the upcoming public + * release number plus "betaNN" or "rcNN". + * + * Binary incompatibility exists only when applications make direct access + * to the info_ptr or png_ptr members through png.h, and the compiled + * application is loaded with a different version of the library. + * + * DLLNUM will change each time there are forward or backward changes + * in binary compatibility (e.g., when a new feature is added). + * + * See libpng-manual.txt or libpng.3 for more information. The PNG + * specification is available as a W3C Recommendation and as an ISO + * Specification, defines should NOT be changed. + */ +#define PNG_INFO_gAMA 0x0001 +#define PNG_INFO_sBIT 0x0002 +#define PNG_INFO_cHRM 0x0004 +#define PNG_INFO_PLTE 0x0008 +#define PNG_INFO_tRNS 0x0010 +#define PNG_INFO_bKGD 0x0020 +#define PNG_INFO_hIST 0x0040 +#define PNG_INFO_pHYs 0x0080 +#define PNG_INFO_oFFs 0x0100 +#define PNG_INFO_tIME 0x0200 +#define PNG_INFO_pCAL 0x0400 +#define PNG_INFO_sRGB 0x0800 /* GR-P, 0.96a */ +#define PNG_INFO_iCCP 0x1000 /* ESR, 1.0.6 */ +#define PNG_INFO_sPLT 0x2000 /* ESR, 1.0.6 */ +#define PNG_INFO_sCAL 0x4000 /* ESR, 1.0.6 */ +#define PNG_INFO_IDAT 0x8000 /* ESR, 1.0.6 */ + +/* This is used for the transformation routines, as some of them + * change these values for the row. It also should enable using + * the routines for other purposes. + */ +typedef struct png_row_info_struct +{ + png_uint_32 width; /* width of row */ + png_size_t rowbytes; /* number of bytes in row */ + png_byte color_type; /* color type of row */ + png_byte bit_depth; /* bit depth of row */ + png_byte channels; /* number of channels (1, 2, 3, or 4) */ + png_byte pixel_depth; /* bits per pixel (depth * channels) */ +} png_row_info; + +typedef png_row_info * png_row_infop; +typedef png_row_info * * png_row_infopp; + +/* These are the function types for the I/O functions and for the functions + * that allow the user to override the default I/O functions with his or her + * own. The png_error_ptr type should match that of user-supplied warning + * and error functions, while the png_rw_ptr type should match that of the + * user read/write data functions. Note that the 'write' function must not + * modify the buffer it is passed. The 'read' function, on the other hand, is + * expected to return the read data in the buffer. + */ +typedef PNG_CALLBACK(void, *png_error_ptr, (png_structp, png_const_charp)); +typedef PNG_CALLBACK(void, *png_rw_ptr, (png_structp, png_bytep, png_size_t)); +typedef PNG_CALLBACK(void, *png_flush_ptr, (png_structp)); +typedef PNG_CALLBACK(void, *png_read_status_ptr, (png_structp, png_uint_32, + int)); +typedef PNG_CALLBACK(void, *png_write_status_ptr, (png_structp, png_uint_32, + int)); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +typedef PNG_CALLBACK(void, *png_progressive_info_ptr, (png_structp, png_infop)); +typedef PNG_CALLBACK(void, *png_progressive_end_ptr, (png_structp, png_infop)); + +/* The following callback receives png_uint_32 row_number, int pass for the + * png_bytep data of the row. When transforming an interlaced image the + * row number is the row number within the sub-image of the interlace pass, so + * the value will increase to the height of the sub-image (not the full image) + * then reset to 0 for the next pass. + * + * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to + * find the output pixel (x,y) given an interlaced sub-image pixel + * (row,col,pass). (See below for these macros.) + */ +typedef PNG_CALLBACK(void, *png_progressive_row_ptr, (png_structp, png_bytep, + png_uint_32, int)); +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) +typedef PNG_CALLBACK(void, *png_user_transform_ptr, (png_structp, png_row_infop, + png_bytep)); +#endif + +#ifdef PNG_USER_CHUNKS_SUPPORTED +typedef PNG_CALLBACK(int, *png_user_chunk_ptr, (png_structp, + png_unknown_chunkp)); +#endif +#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED +/* not used anywhere */ +/* typedef PNG_CALLBACK(void, *png_unknown_chunk_ptr, (png_structp)); */ +#endif + +#ifdef PNG_SETJMP_SUPPORTED +/* This must match the function definition in , and the application + * must include this before png.h to obtain the definition of jmp_buf. The + * function is required to be PNG_NORETURN, but this is not checked. If the + * function does return the application will crash via an abort() or similar + * system level call. + * + * If you get a warning here while building the library you may need to make + * changes to ensure that pnglibconf.h records the calling convention used by + * your compiler. This may be very difficult - try using a different compiler + * to build the library! + */ +PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), PNGARG((jmp_buf, int)), typedef); +#endif + +/* Transform masks for the high-level interface */ +#define PNG_TRANSFORM_IDENTITY 0x0000 /* read and write */ +#define PNG_TRANSFORM_STRIP_16 0x0001 /* read only */ +#define PNG_TRANSFORM_STRIP_ALPHA 0x0002 /* read only */ +#define PNG_TRANSFORM_PACKING 0x0004 /* read and write */ +#define PNG_TRANSFORM_PACKSWAP 0x0008 /* read and write */ +#define PNG_TRANSFORM_EXPAND 0x0010 /* read only */ +#define PNG_TRANSFORM_INVERT_MONO 0x0020 /* read and write */ +#define PNG_TRANSFORM_SHIFT 0x0040 /* read and write */ +#define PNG_TRANSFORM_BGR 0x0080 /* read and write */ +#define PNG_TRANSFORM_SWAP_ALPHA 0x0100 /* read and write */ +#define PNG_TRANSFORM_SWAP_ENDIAN 0x0200 /* read and write */ +#define PNG_TRANSFORM_INVERT_ALPHA 0x0400 /* read and write */ +#define PNG_TRANSFORM_STRIP_FILLER 0x0800 /* write only */ +/* Added to libpng-1.2.34 */ +#define PNG_TRANSFORM_STRIP_FILLER_BEFORE PNG_TRANSFORM_STRIP_FILLER +#define PNG_TRANSFORM_STRIP_FILLER_AFTER 0x1000 /* write only */ +/* Added to libpng-1.4.0 */ +#define PNG_TRANSFORM_GRAY_TO_RGB 0x2000 /* read only */ +/* Added to libpng-1.5.4 */ +#define PNG_TRANSFORM_EXPAND_16 0x4000 /* read only */ +#define PNG_TRANSFORM_SCALE_16 0x8000 /* read only */ + +/* Flags for MNG supported features */ +#define PNG_FLAG_MNG_EMPTY_PLTE 0x01 +#define PNG_FLAG_MNG_FILTER_64 0x04 +#define PNG_ALL_MNG_FEATURES 0x05 + +/* NOTE: prior to 1.5 these functions had no 'API' style declaration, + * this allowed the zlib default functions to be used on Windows + * platforms. In 1.5 the zlib default malloc (which just calls malloc and + * ignores the first argument) should be completely compatible with the + * following. + */ +typedef PNG_CALLBACK(png_voidp, *png_malloc_ptr, (png_structp, + png_alloc_size_t)); +typedef PNG_CALLBACK(void, *png_free_ptr, (png_structp, png_voidp)); + +/* Section 3: exported functions + * Here are the function definitions most commonly used. This is not + * the place to find out how to use libpng. See libpng-manual.txt for the + * full explanation, see example.c for the summary. This just provides + * a simple one line description of the use of each function. + * + * The PNG_EXPORT() and PNG_EXPORTA() macros used below are defined in + * pngconf.h and in the *.dfn files in the scripts directory. + * + * PNG_EXPORT(ordinal, type, name, (args)); + * + * ordinal: ordinal that is used while building + * *.def files. The ordinal value is only + * relevant when preprocessing png.h with + * the *.dfn files for building symbol table + * entries, and are removed by pngconf.h. + * type: return type of the function + * name: function name + * args: function arguments, with types + * + * When we wish to append attributes to a function prototype we use + * the PNG_EXPORTA() macro instead. + * + * PNG_EXPORTA(ordinal, type, name, (args), attributes); + * + * ordinal, type, name, and args: same as in PNG_EXPORT(). + * attributes: function attributes + */ + +/* Returns the version number of the library */ +PNG_EXPORT(1, png_uint_32, png_access_version_number, (void)); + +/* Tell lib we have already handled the first magic bytes. + * Handling more than 8 bytes from the beginning of the file is an error. + */ +PNG_EXPORT(2, void, png_set_sig_bytes, (png_structrp png_ptr, int num_bytes)); + +/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a + * PNG file. Returns zero if the supplied bytes match the 8-byte PNG + * signature, and non-zero otherwise. Having num_to_check == 0 or + * start > 7 will always fail (ie return non-zero). + */ +PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, png_size_t start, + png_size_t num_to_check)); + +/* Simple signature checking function. This is the same as calling + * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n). + */ +#define png_check_sig(sig, n) !png_sig_cmp((sig), 0, (n)) + +/* Allocate and initialize png_ptr struct for reading, and any other memory. */ +PNG_EXPORTA(4, png_structp, png_create_read_struct, + (png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn), + PNG_ALLOCATED); + +/* Allocate and initialize png_ptr struct for writing, and any other memory */ +PNG_EXPORTA(5, png_structp, png_create_write_struct, + (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, + png_error_ptr warn_fn), + PNG_ALLOCATED); + +PNG_EXPORT(6, png_size_t, png_get_compression_buffer_size, + (png_const_structrp png_ptr)); + +PNG_EXPORT(7, void, png_set_compression_buffer_size, (png_structrp png_ptr, + png_size_t size)); + +/* Moved from pngconf.h in 1.4.0 and modified to ensure setjmp/longjmp + * match up. + */ +#ifdef PNG_SETJMP_SUPPORTED +/* This function returns the jmp_buf built in to *png_ptr. It must be + * supplied with an appropriate 'longjmp' function to use on that jmp_buf + * unless the default error function is overridden in which case NULL is + * acceptable. The size of the jmp_buf is checked against the actual size + * allocated by the library - the call will return NULL on a mismatch + * indicating an ABI mismatch. + */ +PNG_EXPORT(8, jmp_buf*, png_set_longjmp_fn, (png_structrp png_ptr, + png_longjmp_ptr longjmp_fn, size_t jmp_buf_size)); +# define png_jmpbuf(png_ptr) \ + (*png_set_longjmp_fn((png_ptr), longjmp, (sizeof (jmp_buf)))) +#else +# define png_jmpbuf(png_ptr) \ + (LIBPNG_WAS_COMPILED_WITH__PNG_NO_SETJMP) +#endif +/* This function should be used by libpng applications in place of + * longjmp(png_ptr->jmpbuf, val). If longjmp_fn() has been set, it + * will use it; otherwise it will call PNG_ABORT(). This function was + * added in libpng-1.5.0. + */ +PNG_EXPORTA(9, void, png_longjmp, (png_const_structrp png_ptr, int val), + PNG_NORETURN); + +#ifdef PNG_READ_SUPPORTED +/* Reset the compression stream */ +PNG_EXPORTA(10, int, png_reset_zstream, (png_structrp png_ptr), PNG_DEPRECATED); +#endif + +/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */ +#ifdef PNG_USER_MEM_SUPPORTED +PNG_EXPORTA(11, png_structp, png_create_read_struct_2, + (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, + png_error_ptr warn_fn, + png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn), + PNG_ALLOCATED); +PNG_EXPORTA(12, png_structp, png_create_write_struct_2, + (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, + png_error_ptr warn_fn, + png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn), + PNG_ALLOCATED); +#endif + +/* Write the PNG file signature. */ +PNG_EXPORT(13, void, png_write_sig, (png_structrp png_ptr)); + +/* Write a PNG chunk - size, type, (optional) data, CRC. */ +PNG_EXPORT(14, void, png_write_chunk, (png_structrp png_ptr, png_const_bytep + chunk_name, png_const_bytep data, png_size_t length)); + +/* Write the start of a PNG chunk - length and chunk name. */ +PNG_EXPORT(15, void, png_write_chunk_start, (png_structrp png_ptr, + png_const_bytep chunk_name, png_uint_32 length)); + +/* Write the data of a PNG chunk started with png_write_chunk_start(). */ +PNG_EXPORT(16, void, png_write_chunk_data, (png_structrp png_ptr, + png_const_bytep data, png_size_t length)); + +/* Finish a chunk started with png_write_chunk_start() (includes CRC). */ +PNG_EXPORT(17, void, png_write_chunk_end, (png_structrp png_ptr)); + +/* Allocate and initialize the info structure */ +PNG_EXPORTA(18, png_infop, png_create_info_struct, (png_const_structrp png_ptr), + PNG_ALLOCATED); + +/* DEPRECATED: this function allowed init structures to be created using the + * default allocation method (typically malloc). Use is deprecated in 1.6.0 and + * the API will be removed in the future. + */ +PNG_EXPORTA(19, void, png_info_init_3, (png_infopp info_ptr, + png_size_t png_info_struct_size), PNG_DEPRECATED); + +/* Writes all the PNG information before the image. */ +PNG_EXPORT(20, void, png_write_info_before_PLTE, + (png_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(21, void, png_write_info, + (png_structrp png_ptr, png_const_inforp info_ptr)); + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read the information before the actual image data. */ +PNG_EXPORT(22, void, png_read_info, + (png_structrp png_ptr, png_inforp info_ptr)); +#endif + +#ifdef PNG_TIME_RFC1123_SUPPORTED + /* Convert to a US string format: there is no localization support in this + * routine. The original implementation used a 29 character buffer in + * png_struct, this will be removed in future versions. + */ +#if PNG_LIBPNG_VER < 10700 +/* To do: remove this from libpng17 (and from libpng17/png.c and pngstruct.h) */ +PNG_EXPORTA(23, png_const_charp, png_convert_to_rfc1123, (png_structrp png_ptr, + png_const_timep ptime),PNG_DEPRECATED); +#endif +PNG_EXPORT(241, int, png_convert_to_rfc1123_buffer, (char out[29], + png_const_timep ptime)); +#endif + +#ifdef PNG_CONVERT_tIME_SUPPORTED +/* Convert from a struct tm to png_time */ +PNG_EXPORT(24, void, png_convert_from_struct_tm, (png_timep ptime, + const struct tm * ttime)); + +/* Convert from time_t to png_time. Uses gmtime() */ +PNG_EXPORT(25, void, png_convert_from_time_t, (png_timep ptime, time_t ttime)); +#endif /* PNG_CONVERT_tIME_SUPPORTED */ + +#ifdef PNG_READ_EXPAND_SUPPORTED +/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */ +PNG_EXPORT(26, void, png_set_expand, (png_structrp png_ptr)); +PNG_EXPORT(27, void, png_set_expand_gray_1_2_4_to_8, (png_structrp png_ptr)); +PNG_EXPORT(28, void, png_set_palette_to_rgb, (png_structrp png_ptr)); +PNG_EXPORT(29, void, png_set_tRNS_to_alpha, (png_structrp png_ptr)); +#endif + +#ifdef PNG_READ_EXPAND_16_SUPPORTED +/* Expand to 16-bit channels, forces conversion of palette to RGB and expansion + * of a tRNS chunk if present. + */ +PNG_EXPORT(221, void, png_set_expand_16, (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +/* Use blue, green, red order for pixels. */ +PNG_EXPORT(30, void, png_set_bgr, (png_structrp png_ptr)); +#endif + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED +/* Expand the grayscale to 24-bit RGB if necessary. */ +PNG_EXPORT(31, void, png_set_gray_to_rgb, (png_structrp png_ptr)); +#endif + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +/* Reduce RGB to grayscale. */ +#define PNG_ERROR_ACTION_NONE 1 +#define PNG_ERROR_ACTION_WARN 2 +#define PNG_ERROR_ACTION_ERROR 3 +#define PNG_RGB_TO_GRAY_DEFAULT (-1)/*for red/green coefficients*/ + +PNG_FP_EXPORT(32, void, png_set_rgb_to_gray, (png_structrp png_ptr, + int error_action, double red, double green)) +PNG_FIXED_EXPORT(33, void, png_set_rgb_to_gray_fixed, (png_structrp png_ptr, + int error_action, png_fixed_point red, png_fixed_point green)) + +PNG_EXPORT(34, png_byte, png_get_rgb_to_gray_status, (png_const_structrp + png_ptr)); +#endif + +#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED +PNG_EXPORT(35, void, png_build_grayscale_palette, (int bit_depth, + png_colorp palette)); +#endif + +#ifdef PNG_READ_ALPHA_MODE_SUPPORTED +/* How the alpha channel is interpreted - this affects how the color channels of + * a PNG file are returned when an alpha channel, or tRNS chunk in a palette + * file, is present. + * + * This has no effect on the way pixels are written into a PNG output + * datastream. The color samples in a PNG datastream are never premultiplied + * with the alpha samples. + * + * The default is to return data according to the PNG specification: the alpha + * channel is a linear measure of the contribution of the pixel to the + * corresponding composited pixel. The gamma encoded color channels must be + * scaled according to the contribution and to do this it is necessary to undo + * the encoding, scale the color values, perform the composition and reencode + * the values. This is the 'PNG' mode. + * + * The alternative is to 'associate' the alpha with the color information by + * storing color channel values that have been scaled by the alpha. The + * advantage is that the color channels can be resampled (the image can be + * scaled) in this form. The disadvantage is that normal practice is to store + * linear, not (gamma) encoded, values and this requires 16-bit channels for + * still images rather than the 8-bit channels that are just about sufficient if + * gamma encoding is used. In addition all non-transparent pixel values, + * including completely opaque ones, must be gamma encoded to produce the final + * image. This is the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' mode (the + * latter being the two common names for associated alpha color channels.) + * + * Since it is not necessary to perform arithmetic on opaque color values so + * long as they are not to be resampled and are in the final color space it is + * possible to optimize the handling of alpha by storing the opaque pixels in + * the PNG format (adjusted for the output color space) while storing partially + * opaque pixels in the standard, linear, format. The accuracy required for + * standard alpha composition is relatively low, because the pixels are + * isolated, therefore typically the accuracy loss in storing 8-bit linear + * values is acceptable. (This is not true if the alpha channel is used to + * simulate transparency over large areas - use 16 bits or the PNG mode in + * this case!) This is the 'OPTIMIZED' mode. For this mode a pixel is + * treated as opaque only if the alpha value is equal to the maximum value. + * + * The final choice is to gamma encode the alpha channel as well. This is + * broken because, in practice, no implementation that uses this choice + * correctly undoes the encoding before handling alpha composition. Use this + * choice only if other serious errors in the software or hardware you use + * mandate it; the typical serious error is for dark halos to appear around + * opaque areas of the composited PNG image because of arithmetic overflow. + * + * The API function png_set_alpha_mode specifies which of these choices to use + * with an enumerated 'mode' value and the gamma of the required output: + */ +#define PNG_ALPHA_PNG 0 /* according to the PNG standard */ +#define PNG_ALPHA_STANDARD 1 /* according to Porter/Duff */ +#define PNG_ALPHA_ASSOCIATED 1 /* as above; this is the normal practice */ +#define PNG_ALPHA_PREMULTIPLIED 1 /* as above */ +#define PNG_ALPHA_OPTIMIZED 2 /* 'PNG' for opaque pixels, else 'STANDARD' */ +#define PNG_ALPHA_BROKEN 3 /* the alpha channel is gamma encoded */ + +PNG_FP_EXPORT(227, void, png_set_alpha_mode, (png_structrp png_ptr, int mode, + double output_gamma)) +PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structrp png_ptr, + int mode, png_fixed_point output_gamma)) +#endif + +#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_READ_ALPHA_MODE_SUPPORTED) +/* The output_gamma value is a screen gamma in libpng terminology: it expresses + * how to decode the output values, not how they are encoded. The values used + * correspond to the normal numbers used to describe the overall gamma of a + * computer display system; for example 2.2 for an sRGB conformant system. The + * values are scaled by 100000 in the _fixed version of the API (so 220000 for + * sRGB.) + * + * The inverse of the value is always used to provide a default for the PNG file + * encoding if it has no gAMA chunk and if png_set_gamma() has not been called + * to override the PNG gamma information. + * + * When the ALPHA_OPTIMIZED mode is selected the output gamma is used to encode + * opaque pixels however pixels with lower alpha values are not encoded, + * regardless of the output gamma setting. + * + * When the standard Porter Duff handling is requested with mode 1 the output + * encoding is set to be linear and the output_gamma value is only relevant + * as a default for input data that has no gamma information. The linear output + * encoding will be overridden if png_set_gamma() is called - the results may be + * highly unexpected! + * + * The following numbers are derived from the sRGB standard and the research + * behind it. sRGB is defined to be approximated by a PNG gAMA chunk value of + * 0.45455 (1/2.2) for PNG. The value implicitly includes any viewing + * correction required to take account of any differences in the color + * environment of the original scene and the intended display environment; the + * value expresses how to *decode* the image for display, not how the original + * data was *encoded*. + * + * sRGB provides a peg for the PNG standard by defining a viewing environment. + * sRGB itself, and earlier TV standards, actually use a more complex transform + * (a linear portion then a gamma 2.4 power law) than PNG can express. (PNG is + * limited to simple power laws.) By saying that an image for direct display on + * an sRGB conformant system should be stored with a gAMA chunk value of 45455 + * (11.3.3.2 and 11.3.3.5 of the ISO PNG specification) the PNG specification + * makes it possible to derive values for other display systems and + * environments. + * + * The Mac value is deduced from the sRGB based on an assumption that the actual + * extra viewing correction used in early Mac display systems was implemented as + * a power 1.45 lookup table. + * + * Any system where a programmable lookup table is used or where the behavior of + * the final display device characteristics can be changed requires system + * specific code to obtain the current characteristic. However this can be + * difficult and most PNG gamma correction only requires an approximate value. + * + * By default, if png_set_alpha_mode() is not called, libpng assumes that all + * values are unencoded, linear, values and that the output device also has a + * linear characteristic. This is only very rarely correct - it is invariably + * better to call png_set_alpha_mode() with PNG_DEFAULT_sRGB than rely on the + * default if you don't know what the right answer is! + * + * The special value PNG_GAMMA_MAC_18 indicates an older Mac system (pre Mac OS + * 10.6) which used a correction table to implement a somewhat lower gamma on an + * otherwise sRGB system. + * + * Both these values are reserved (not simple gamma values) in order to allow + * more precise correction internally in the future. + * + * NOTE: the following values can be passed to either the fixed or floating + * point APIs, but the floating point API will also accept floating point + * values. + */ +#define PNG_DEFAULT_sRGB -1 /* sRGB gamma and color space */ +#define PNG_GAMMA_MAC_18 -2 /* Old Mac '1.8' gamma and color space */ +#define PNG_GAMMA_sRGB 220000 /* Television standards--matches sRGB gamma */ +#define PNG_GAMMA_LINEAR PNG_FP_1 /* Linear */ +#endif + +/* The following are examples of calls to png_set_alpha_mode to achieve the + * required overall gamma correction and, where necessary, alpha + * premultiplication. + * + * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB); + * This is the default libpng handling of the alpha channel - it is not + * pre-multiplied into the color components. In addition the call states + * that the output is for a sRGB system and causes all PNG files without gAMA + * chunks to be assumed to be encoded using sRGB. + * + * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC); + * In this case the output is assumed to be something like an sRGB conformant + * display preceeded by a power-law lookup table of power 1.45. This is how + * early Mac systems behaved. + * + * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR); + * This is the classic Jim Blinn approach and will work in academic + * environments where everything is done by the book. It has the shortcoming + * of assuming that input PNG data with no gamma information is linear - this + * is unlikely to be correct unless the PNG files where generated locally. + * Most of the time the output precision will be so low as to show + * significant banding in dark areas of the image. + * + * png_set_expand_16(pp); + * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_DEFAULT_sRGB); + * This is a somewhat more realistic Jim Blinn inspired approach. PNG files + * are assumed to have the sRGB encoding if not marked with a gamma value and + * the output is always 16 bits per component. This permits accurate scaling + * and processing of the data. If you know that your input PNG files were + * generated locally you might need to replace PNG_DEFAULT_sRGB with the + * correct value for your system. + * + * png_set_alpha_mode(pp, PNG_ALPHA_OPTIMIZED, PNG_DEFAULT_sRGB); + * If you just need to composite the PNG image onto an existing background + * and if you control the code that does this you can use the optimization + * setting. In this case you just copy completely opaque pixels to the + * output. For pixels that are not completely transparent (you just skip + * those) you do the composition math using png_composite or png_composite_16 + * below then encode the resultant 8-bit or 16-bit values to match the output + * encoding. + * + * Other cases + * If neither the PNG nor the standard linear encoding work for you because + * of the software or hardware you use then you have a big problem. The PNG + * case will probably result in halos around the image. The linear encoding + * will probably result in a washed out, too bright, image (it's actually too + * contrasty.) Try the ALPHA_OPTIMIZED mode above - this will probably + * substantially reduce the halos. Alternatively try: + * + * png_set_alpha_mode(pp, PNG_ALPHA_BROKEN, PNG_DEFAULT_sRGB); + * This option will also reduce the halos, but there will be slight dark + * halos round the opaque parts of the image where the background is light. + * In the OPTIMIZED mode the halos will be light halos where the background + * is dark. Take your pick - the halos are unavoidable unless you can get + * your hardware/software fixed! (The OPTIMIZED approach is slightly + * faster.) + * + * When the default gamma of PNG files doesn't match the output gamma. + * If you have PNG files with no gamma information png_set_alpha_mode allows + * you to provide a default gamma, but it also sets the ouput gamma to the + * matching value. If you know your PNG files have a gamma that doesn't + * match the output you can take advantage of the fact that + * png_set_alpha_mode always sets the output gamma but only sets the PNG + * default if it is not already set: + * + * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB); + * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC); + * The first call sets both the default and the output gamma values, the + * second call overrides the output gamma without changing the default. This + * is easier than achieving the same effect with png_set_gamma. You must use + * PNG_ALPHA_PNG for the first call - internal checking in png_set_alpha will + * fire if more than one call to png_set_alpha_mode and png_set_background is + * made in the same read operation, however multiple calls with PNG_ALPHA_PNG + * are ignored. + */ + +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED +PNG_EXPORT(36, void, png_set_strip_alpha, (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) +PNG_EXPORT(37, void, png_set_swap_alpha, (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) +PNG_EXPORT(38, void, png_set_invert_alpha, (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) +/* Add a filler byte to 8-bit Gray or 24-bit RGB images. */ +PNG_EXPORT(39, void, png_set_filler, (png_structrp png_ptr, png_uint_32 filler, + int flags)); +/* The values of the PNG_FILLER_ defines should NOT be changed */ +# define PNG_FILLER_BEFORE 0 +# define PNG_FILLER_AFTER 1 +/* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */ +PNG_EXPORT(40, void, png_set_add_alpha, (png_structrp png_ptr, + png_uint_32 filler, int flags)); +#endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */ + +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) +/* Swap bytes in 16-bit depth files. */ +PNG_EXPORT(41, void, png_set_swap, (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) +/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */ +PNG_EXPORT(42, void, png_set_packing, (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \ + defined(PNG_WRITE_PACKSWAP_SUPPORTED) +/* Swap packing order of pixels in bytes. */ +PNG_EXPORT(43, void, png_set_packswap, (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) +/* Converts files to legal bit depths. */ +PNG_EXPORT(44, void, png_set_shift, (png_structrp png_ptr, png_const_color_8p + true_bits)); +#endif + +#if defined(PNG_READ_INTERLACING_SUPPORTED) || \ + defined(PNG_WRITE_INTERLACING_SUPPORTED) +/* Have the code handle the interlacing. Returns the number of passes. + * MUST be called before png_read_update_info or png_start_read_image, + * otherwise it will not have the desired effect. Note that it is still + * necessary to call png_read_row or png_read_rows png_get_image_height + * times for each pass. +*/ +PNG_EXPORT(45, int, png_set_interlace_handling, (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) +/* Invert monochrome files */ +PNG_EXPORT(46, void, png_set_invert_mono, (png_structrp png_ptr)); +#endif + +#ifdef PNG_READ_BACKGROUND_SUPPORTED +/* Handle alpha and tRNS by replacing with a background color. Prior to + * libpng-1.5.4 this API must not be called before the PNG file header has been + * read. Doing so will result in unexpected behavior and possible warnings or + * errors if the PNG file contains a bKGD chunk. + */ +PNG_FP_EXPORT(47, void, png_set_background, (png_structrp png_ptr, + png_const_color_16p background_color, int background_gamma_code, + int need_expand, double background_gamma)) +PNG_FIXED_EXPORT(215, void, png_set_background_fixed, (png_structrp png_ptr, + png_const_color_16p background_color, int background_gamma_code, + int need_expand, png_fixed_point background_gamma)) +#endif +#ifdef PNG_READ_BACKGROUND_SUPPORTED +# define PNG_BACKGROUND_GAMMA_UNKNOWN 0 +# define PNG_BACKGROUND_GAMMA_SCREEN 1 +# define PNG_BACKGROUND_GAMMA_FILE 2 +# define PNG_BACKGROUND_GAMMA_UNIQUE 3 +#endif + +#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED +/* Scale a 16-bit depth file down to 8-bit, accurately. */ +PNG_EXPORT(229, void, png_set_scale_16, (png_structrp png_ptr)); +#endif + +#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED +#define PNG_READ_16_TO_8 SUPPORTED /* Name prior to 1.5.4 */ +/* Strip the second byte of information from a 16-bit depth file. */ +PNG_EXPORT(48, void, png_set_strip_16, (png_structrp png_ptr)); +#endif + +#ifdef PNG_READ_QUANTIZE_SUPPORTED +/* Turn on quantizing, and reduce the palette to the number of colors + * available. + */ +PNG_EXPORT(49, void, png_set_quantize, (png_structrp png_ptr, + png_colorp palette, int num_palette, int maximum_colors, + png_const_uint_16p histogram, int full_quantize)); +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED +/* The threshold on gamma processing is configurable but hard-wired into the + * library. The following is the floating point variant. + */ +#define PNG_GAMMA_THRESHOLD (PNG_GAMMA_THRESHOLD_FIXED*.00001) + +/* Handle gamma correction. Screen_gamma=(display_exponent). + * NOTE: this API simply sets the screen and file gamma values. It will + * therefore override the value for gamma in a PNG file if it is called after + * the file header has been read - use with care - call before reading the PNG + * file for best results! + * + * These routines accept the same gamma values as png_set_alpha_mode (described + * above). The PNG_GAMMA_ defines and PNG_DEFAULT_sRGB can be passed to either + * API (floating point or fixed.) Notice, however, that the 'file_gamma' value + * is the inverse of a 'screen gamma' value. + */ +PNG_FP_EXPORT(50, void, png_set_gamma, (png_structrp png_ptr, + double screen_gamma, double override_file_gamma)) +PNG_FIXED_EXPORT(208, void, png_set_gamma_fixed, (png_structrp png_ptr, + png_fixed_point screen_gamma, png_fixed_point override_file_gamma)) +#endif + +#ifdef PNG_WRITE_FLUSH_SUPPORTED +/* Set how many lines between output flushes - 0 for no flushing */ +PNG_EXPORT(51, void, png_set_flush, (png_structrp png_ptr, int nrows)); +/* Flush the current PNG output buffer */ +PNG_EXPORT(52, void, png_write_flush, (png_structrp png_ptr)); +#endif + +/* Optional update palette with requested transformations */ +PNG_EXPORT(53, void, png_start_read_image, (png_structrp png_ptr)); + +/* Optional call to update the users info structure */ +PNG_EXPORT(54, void, png_read_update_info, (png_structrp png_ptr, + png_inforp info_ptr)); + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read one or more rows of image data. */ +PNG_EXPORT(55, void, png_read_rows, (png_structrp png_ptr, png_bytepp row, + png_bytepp display_row, png_uint_32 num_rows)); +#endif + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read a row of data. */ +PNG_EXPORT(56, void, png_read_row, (png_structrp png_ptr, png_bytep row, + png_bytep display_row)); +#endif + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read the whole image into memory at once. */ +PNG_EXPORT(57, void, png_read_image, (png_structrp png_ptr, png_bytepp image)); +#endif + +/* Write a row of image data */ +PNG_EXPORT(58, void, png_write_row, (png_structrp png_ptr, + png_const_bytep row)); + +/* Write a few rows of image data: (*row) is not written; however, the type + * is declared as writeable to maintain compatibility with previous versions + * of libpng and to allow the 'display_row' array from read_rows to be passed + * unchanged to write_rows. + */ +PNG_EXPORT(59, void, png_write_rows, (png_structrp png_ptr, png_bytepp row, + png_uint_32 num_rows)); + +/* Write the image data */ +PNG_EXPORT(60, void, png_write_image, (png_structrp png_ptr, png_bytepp image)); + +/* Write the end of the PNG file. */ +PNG_EXPORT(61, void, png_write_end, (png_structrp png_ptr, + png_inforp info_ptr)); + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read the end of the PNG file. */ +PNG_EXPORT(62, void, png_read_end, (png_structrp png_ptr, png_inforp info_ptr)); +#endif + +/* Free any memory associated with the png_info_struct */ +PNG_EXPORT(63, void, png_destroy_info_struct, (png_const_structrp png_ptr, + png_infopp info_ptr_ptr)); + +/* Free any memory associated with the png_struct and the png_info_structs */ +PNG_EXPORT(64, void, png_destroy_read_struct, (png_structpp png_ptr_ptr, + png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr)); + +/* Free any memory associated with the png_struct and the png_info_structs */ +PNG_EXPORT(65, void, png_destroy_write_struct, (png_structpp png_ptr_ptr, + png_infopp info_ptr_ptr)); + +/* Set the libpng method of handling chunk CRC errors */ +PNG_EXPORT(66, void, png_set_crc_action, (png_structrp png_ptr, int crit_action, + int ancil_action)); + +/* Values for png_set_crc_action() say how to handle CRC errors in + * ancillary and critical chunks, and whether to use the data contained + * therein. Note that it is impossible to "discard" data in a critical + * chunk. For versions prior to 0.90, the action was always error/quit, + * whereas in version 0.90 and later, the action for CRC errors in ancillary + * chunks is warn/discard. These values should NOT be changed. + * + * value action:critical action:ancillary + */ +#define PNG_CRC_DEFAULT 0 /* error/quit warn/discard data */ +#define PNG_CRC_ERROR_QUIT 1 /* error/quit error/quit */ +#define PNG_CRC_WARN_DISCARD 2 /* (INVALID) warn/discard data */ +#define PNG_CRC_WARN_USE 3 /* warn/use data warn/use data */ +#define PNG_CRC_QUIET_USE 4 /* quiet/use data quiet/use data */ +#define PNG_CRC_NO_CHANGE 5 /* use current value use current value */ + +/* These functions give the user control over the scan-line filtering in + * libpng and the compression methods used by zlib. These functions are + * mainly useful for testing, as the defaults should work with most users. + * Those users who are tight on memory or want faster performance at the + * expense of compression can modify them. See the compression library + * header file (zlib.h) for an explination of the compression functions. + */ + +/* Set the filtering method(s) used by libpng. Currently, the only valid + * value for "method" is 0. + */ +PNG_EXPORT(67, void, png_set_filter, (png_structrp png_ptr, int method, + int filters)); + +/* Flags for png_set_filter() to say which filters to use. The flags + * are chosen so that they don't conflict with real filter types + * below, in case they are supplied instead of the #defined constants. + * These values should NOT be changed. + */ +#define PNG_NO_FILTERS 0x00 +#define PNG_FILTER_NONE 0x08 +#define PNG_FILTER_SUB 0x10 +#define PNG_FILTER_UP 0x20 +#define PNG_FILTER_AVG 0x40 +#define PNG_FILTER_PAETH 0x80 +#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \ + PNG_FILTER_AVG | PNG_FILTER_PAETH) + +/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now. + * These defines should NOT be changed. + */ +#define PNG_FILTER_VALUE_NONE 0 +#define PNG_FILTER_VALUE_SUB 1 +#define PNG_FILTER_VALUE_UP 2 +#define PNG_FILTER_VALUE_AVG 3 +#define PNG_FILTER_VALUE_PAETH 4 +#define PNG_FILTER_VALUE_LAST 5 + +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* EXPERIMENTAL */ +/* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_ + * defines, either the default (minimum-sum-of-absolute-differences), or + * the experimental method (weighted-minimum-sum-of-absolute-differences). + * + * Weights are factors >= 1.0, indicating how important it is to keep the + * filter type consistent between rows. Larger numbers mean the current + * filter is that many times as likely to be the same as the "num_weights" + * previous filters. This is cumulative for each previous row with a weight. + * There needs to be "num_weights" values in "filter_weights", or it can be + * NULL if the weights aren't being specified. Weights have no influence on + * the selection of the first row filter. Well chosen weights can (in theory) + * improve the compression for a given image. + * + * Costs are factors >= 1.0 indicating the relative decoding costs of a + * filter type. Higher costs indicate more decoding expense, and are + * therefore less likely to be selected over a filter with lower computational + * costs. There needs to be a value in "filter_costs" for each valid filter + * type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't + * setting the costs. Costs try to improve the speed of decompression without + * unduly increasing the compressed image size. + * + * A negative weight or cost indicates the default value is to be used, and + * values in the range [0.0, 1.0) indicate the value is to remain unchanged. + * The default values for both weights and costs are currently 1.0, but may + * change if good general weighting/cost heuristics can be found. If both + * the weights and costs are set to 1.0, this degenerates the WEIGHTED method + * to the UNWEIGHTED method, but with added encoding time/computation. + */ +PNG_FP_EXPORT(68, void, png_set_filter_heuristics, (png_structrp png_ptr, + int heuristic_method, int num_weights, png_const_doublep filter_weights, + png_const_doublep filter_costs)) +PNG_FIXED_EXPORT(209, void, png_set_filter_heuristics_fixed, + (png_structrp png_ptr, int heuristic_method, int num_weights, + png_const_fixed_point_p filter_weights, + png_const_fixed_point_p filter_costs)) +#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ + +/* Heuristic used for row filter selection. These defines should NOT be + * changed. + */ +#define PNG_FILTER_HEURISTIC_DEFAULT 0 /* Currently "UNWEIGHTED" */ +#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1 /* Used by libpng < 0.95 */ +#define PNG_FILTER_HEURISTIC_WEIGHTED 2 /* Experimental feature */ +#define PNG_FILTER_HEURISTIC_LAST 3 /* Not a valid value */ + +#ifdef PNG_WRITE_SUPPORTED +/* Set the library compression level. Currently, valid values range from + * 0 - 9, corresponding directly to the zlib compression levels 0 - 9 + * (0 - no compression, 9 - "maximal" compression). Note that tests have + * shown that zlib compression levels 3-6 usually perform as well as level 9 + * for PNG images, and do considerably fewer caclulations. In the future, + * these values may not correspond directly to the zlib compression levels. + */ +PNG_EXPORT(69, void, png_set_compression_level, (png_structrp png_ptr, + int level)); + +PNG_EXPORT(70, void, png_set_compression_mem_level, (png_structrp png_ptr, + int mem_level)); + +PNG_EXPORT(71, void, png_set_compression_strategy, (png_structrp png_ptr, + int strategy)); + +/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a + * smaller value of window_bits if it can do so safely. + */ +PNG_EXPORT(72, void, png_set_compression_window_bits, (png_structrp png_ptr, + int window_bits)); + +PNG_EXPORT(73, void, png_set_compression_method, (png_structrp png_ptr, + int method)); +#endif + +#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED +/* Also set zlib parameters for compressing non-IDAT chunks */ +PNG_EXPORT(222, void, png_set_text_compression_level, (png_structrp png_ptr, + int level)); + +PNG_EXPORT(223, void, png_set_text_compression_mem_level, (png_structrp png_ptr, + int mem_level)); + +PNG_EXPORT(224, void, png_set_text_compression_strategy, (png_structrp png_ptr, + int strategy)); + +/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a + * smaller value of window_bits if it can do so safely. + */ +PNG_EXPORT(225, void, png_set_text_compression_window_bits, + (png_structrp png_ptr, int window_bits)); + +PNG_EXPORT(226, void, png_set_text_compression_method, (png_structrp png_ptr, + int method)); +#endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */ + +/* These next functions are called for input/output, memory, and error + * handling. They are in the file pngrio.c, pngwio.c, and pngerror.c, + * and call standard C I/O routines such as fread(), fwrite(), and + * fprintf(). These functions can be made to use other I/O routines + * at run time for those applications that need to handle I/O in a + * different manner by calling png_set_???_fn(). See libpng-manual.txt for + * more information. + */ + +#ifdef PNG_STDIO_SUPPORTED +/* Initialize the input/output for the PNG file to the default functions. */ +PNG_EXPORT(74, void, png_init_io, (png_structrp png_ptr, png_FILE_p fp)); +#endif + +/* Replace the (error and abort), and warning functions with user + * supplied functions. If no messages are to be printed you must still + * write and use replacement functions. The replacement error_fn should + * still do a longjmp to the last setjmp location if you are using this + * method of error handling. If error_fn or warning_fn is NULL, the + * default function will be used. + */ + +PNG_EXPORT(75, void, png_set_error_fn, (png_structrp png_ptr, + png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn)); + +/* Return the user pointer associated with the error functions */ +PNG_EXPORT(76, png_voidp, png_get_error_ptr, (png_const_structrp png_ptr)); + +/* Replace the default data output functions with a user supplied one(s). + * If buffered output is not used, then output_flush_fn can be set to NULL. + * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time + * output_flush_fn will be ignored (and thus can be NULL). + * It is probably a mistake to use NULL for output_flush_fn if + * write_data_fn is not also NULL unless you have built libpng with + * PNG_WRITE_FLUSH_SUPPORTED undefined, because in this case libpng's + * default flush function, which uses the standard *FILE structure, will + * be used. + */ +PNG_EXPORT(77, void, png_set_write_fn, (png_structrp png_ptr, png_voidp io_ptr, + png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)); + +/* Replace the default data input function with a user supplied one. */ +PNG_EXPORT(78, void, png_set_read_fn, (png_structrp png_ptr, png_voidp io_ptr, + png_rw_ptr read_data_fn)); + +/* Return the user pointer associated with the I/O functions */ +PNG_EXPORT(79, png_voidp, png_get_io_ptr, (png_const_structrp png_ptr)); + +PNG_EXPORT(80, void, png_set_read_status_fn, (png_structrp png_ptr, + png_read_status_ptr read_row_fn)); + +PNG_EXPORT(81, void, png_set_write_status_fn, (png_structrp png_ptr, + png_write_status_ptr write_row_fn)); + +#ifdef PNG_USER_MEM_SUPPORTED +/* Replace the default memory allocation functions with user supplied one(s). */ +PNG_EXPORT(82, void, png_set_mem_fn, (png_structrp png_ptr, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn)); +/* Return the user pointer associated with the memory functions */ +PNG_EXPORT(83, png_voidp, png_get_mem_ptr, (png_const_structrp png_ptr)); +#endif + +#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED +PNG_EXPORT(84, void, png_set_read_user_transform_fn, (png_structrp png_ptr, + png_user_transform_ptr read_user_transform_fn)); +#endif + +#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED +PNG_EXPORT(85, void, png_set_write_user_transform_fn, (png_structrp png_ptr, + png_user_transform_ptr write_user_transform_fn)); +#endif + +#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED +PNG_EXPORT(86, void, png_set_user_transform_info, (png_structrp png_ptr, + png_voidp user_transform_ptr, int user_transform_depth, + int user_transform_channels)); +/* Return the user pointer associated with the user transform functions */ +PNG_EXPORT(87, png_voidp, png_get_user_transform_ptr, + (png_const_structrp png_ptr)); +#endif + +#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED +/* Return information about the row currently being processed. Note that these + * APIs do not fail but will return unexpected results if called outside a user + * transform callback. Also note that when transforming an interlaced image the + * row number is the row number within the sub-image of the interlace pass, so + * the value will increase to the height of the sub-image (not the full image) + * then reset to 0 for the next pass. + * + * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to + * find the output pixel (x,y) given an interlaced sub-image pixel + * (row,col,pass). (See below for these macros.) + */ +PNG_EXPORT(217, png_uint_32, png_get_current_row_number, (png_const_structrp)); +PNG_EXPORT(218, png_byte, png_get_current_pass_number, (png_const_structrp)); +#endif + +#ifdef PNG_READ_USER_CHUNKS_SUPPORTED +/* This callback is called only for *unknown* chunks. If + * PNG_HANDLE_AS_UNKNOWN_SUPPORTED is set then it is possible to set known + * chunks to be treated as unknown, however in this case the callback must do + * any processing required by the chunk (e.g. by calling the appropriate + * png_set_ APIs.) + * + * There is no write support - on write, by default, all the chunks in the + * 'unknown' list are written in the specified position. + * + * The integer return from the callback function is interpreted thus: + * + * negative: An error occured, png_chunk_error will be called. + * zero: The chunk was not handled, the chunk will be saved. A critical + * chunk will cause an error at this point unless it is to be saved. + * positive: The chunk was handled, libpng will ignore/discard it. + * + * See "INTERACTION WTIH USER CHUNK CALLBACKS" below for important notes about + * how this behavior will change in libpng 1.7 + */ +PNG_EXPORT(88, void, png_set_read_user_chunk_fn, (png_structrp png_ptr, + png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn)); +#endif + +#ifdef PNG_USER_CHUNKS_SUPPORTED +PNG_EXPORT(89, png_voidp, png_get_user_chunk_ptr, (png_const_structrp png_ptr)); +#endif + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +/* Sets the function callbacks for the push reader, and a pointer to a + * user-defined structure available to the callback functions. + */ +PNG_EXPORT(90, void, png_set_progressive_read_fn, (png_structrp png_ptr, + png_voidp progressive_ptr, png_progressive_info_ptr info_fn, + png_progressive_row_ptr row_fn, png_progressive_end_ptr end_fn)); + +/* Returns the user pointer associated with the push read functions */ +PNG_EXPORT(91, png_voidp, png_get_progressive_ptr, + (png_const_structrp png_ptr)); + +/* Function to be called when data becomes available */ +PNG_EXPORT(92, void, png_process_data, (png_structrp png_ptr, + png_inforp info_ptr, png_bytep buffer, png_size_t buffer_size)); + +/* A function which may be called *only* within png_process_data to stop the + * processing of any more data. The function returns the number of bytes + * remaining, excluding any that libpng has cached internally. A subsequent + * call to png_process_data must supply these bytes again. If the argument + * 'save' is set to true the routine will first save all the pending data and + * will always return 0. + */ +PNG_EXPORT(219, png_size_t, png_process_data_pause, (png_structrp, int save)); + +/* A function which may be called *only* outside (after) a call to + * png_process_data. It returns the number of bytes of data to skip in the + * input. Normally it will return 0, but if it returns a non-zero value the + * application must skip than number of bytes of input data and pass the + * following data to the next call to png_process_data. + */ +PNG_EXPORT(220, png_uint_32, png_process_data_skip, (png_structrp)); + +#ifdef PNG_READ_INTERLACING_SUPPORTED +/* Function that combines rows. 'new_row' is a flag that should come from + * the callback and be non-NULL if anything needs to be done; the library + * stores its own version of the new data internally and ignores the passed + * in value. + */ +PNG_EXPORT(93, void, png_progressive_combine_row, (png_const_structrp png_ptr, + png_bytep old_row, png_const_bytep new_row)); +#endif /* PNG_READ_INTERLACING_SUPPORTED */ +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + +PNG_EXPORTA(94, png_voidp, png_malloc, (png_const_structrp png_ptr, + png_alloc_size_t size), PNG_ALLOCATED); +/* Added at libpng version 1.4.0 */ +PNG_EXPORTA(95, png_voidp, png_calloc, (png_const_structrp png_ptr, + png_alloc_size_t size), PNG_ALLOCATED); + +/* Added at libpng version 1.2.4 */ +PNG_EXPORTA(96, png_voidp, png_malloc_warn, (png_const_structrp png_ptr, + png_alloc_size_t size), PNG_ALLOCATED); + +/* Frees a pointer allocated by png_malloc() */ +PNG_EXPORT(97, void, png_free, (png_const_structrp png_ptr, png_voidp ptr)); + +/* Free data that was allocated internally */ +PNG_EXPORT(98, void, png_free_data, (png_const_structrp png_ptr, + png_inforp info_ptr, png_uint_32 free_me, int num)); + +/* Reassign responsibility for freeing existing data, whether allocated + * by libpng or by the application; this works on the png_info structure passed + * in, it does not change the state for other png_info structures. + * + * It is unlikely that this function works correctly as of 1.6.0 and using it + * may result either in memory leaks or double free of allocated data. + */ +PNG_EXPORTA(99, void, png_data_freer, (png_const_structrp png_ptr, + png_inforp info_ptr, int freer, png_uint_32 mask), PNG_DEPRECATED); + +/* Assignments for png_data_freer */ +#define PNG_DESTROY_WILL_FREE_DATA 1 +#define PNG_SET_WILL_FREE_DATA 1 +#define PNG_USER_WILL_FREE_DATA 2 +/* Flags for png_ptr->free_me and info_ptr->free_me */ +#define PNG_FREE_HIST 0x0008 +#define PNG_FREE_ICCP 0x0010 +#define PNG_FREE_SPLT 0x0020 +#define PNG_FREE_ROWS 0x0040 +#define PNG_FREE_PCAL 0x0080 +#define PNG_FREE_SCAL 0x0100 +#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED +# define PNG_FREE_UNKN 0x0200 +#endif +/* PNG_FREE_LIST 0x0400 removed in 1.6.0 because it is ignored */ +#define PNG_FREE_PLTE 0x1000 +#define PNG_FREE_TRNS 0x2000 +#define PNG_FREE_TEXT 0x4000 +#define PNG_FREE_ALL 0x7fff +#define PNG_FREE_MUL 0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */ + +#ifdef PNG_USER_MEM_SUPPORTED +PNG_EXPORTA(100, png_voidp, png_malloc_default, (png_const_structrp png_ptr, + png_alloc_size_t size), PNG_ALLOCATED PNG_DEPRECATED); +PNG_EXPORTA(101, void, png_free_default, (png_const_structrp png_ptr, + png_voidp ptr), PNG_DEPRECATED); +#endif + +#ifdef PNG_ERROR_TEXT_SUPPORTED +/* Fatal error in PNG image of libpng - can't continue */ +PNG_EXPORTA(102, void, png_error, (png_const_structrp png_ptr, + png_const_charp error_message), PNG_NORETURN); + +/* The same, but the chunk name is prepended to the error string. */ +PNG_EXPORTA(103, void, png_chunk_error, (png_const_structrp png_ptr, + png_const_charp error_message), PNG_NORETURN); + +#else +/* Fatal error in PNG image of libpng - can't continue */ +PNG_EXPORTA(104, void, png_err, (png_const_structrp png_ptr), PNG_NORETURN); +#endif + +#ifdef PNG_WARNINGS_SUPPORTED +/* Non-fatal error in libpng. Can continue, but may have a problem. */ +PNG_EXPORT(105, void, png_warning, (png_const_structrp png_ptr, + png_const_charp warning_message)); + +/* Non-fatal error in libpng, chunk name is prepended to message. */ +PNG_EXPORT(106, void, png_chunk_warning, (png_const_structrp png_ptr, + png_const_charp warning_message)); +#endif + +#ifdef PNG_BENIGN_ERRORS_SUPPORTED +/* Benign error in libpng. Can continue, but may have a problem. + * User can choose whether to handle as a fatal error or as a warning. */ +PNG_EXPORT(107, void, png_benign_error, (png_const_structrp png_ptr, + png_const_charp warning_message)); + +#ifdef PNG_READ_SUPPORTED +/* Same, chunk name is prepended to message (only during read) */ +PNG_EXPORT(108, void, png_chunk_benign_error, (png_const_structrp png_ptr, + png_const_charp warning_message)); +#endif + +PNG_EXPORT(109, void, png_set_benign_errors, + (png_structrp png_ptr, int allowed)); +#else +# ifdef PNG_ALLOW_BENIGN_ERRORS +# define png_benign_error png_warning +# define png_chunk_benign_error png_chunk_warning +# else +# define png_benign_error png_error +# define png_chunk_benign_error png_chunk_error +# endif +#endif + +/* The png_set_ functions are for storing values in the png_info_struct. + * Similarly, the png_get_ calls are used to read values from the + * png_info_struct, either storing the parameters in the passed variables, or + * setting pointers into the png_info_struct where the data is stored. The + * png_get_ functions return a non-zero value if the data was available + * in info_ptr, or return zero and do not change any of the parameters if the + * data was not available. + * + * These functions should be used instead of directly accessing png_info + * to avoid problems with future changes in the size and internal layout of + * png_info_struct. + */ +/* Returns "flag" if chunk data is valid in info_ptr. */ +PNG_EXPORT(110, png_uint_32, png_get_valid, (png_const_structrp png_ptr, + png_const_inforp info_ptr, png_uint_32 flag)); + +/* Returns number of bytes needed to hold a transformed row. */ +PNG_EXPORT(111, png_size_t, png_get_rowbytes, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +#ifdef PNG_INFO_IMAGE_SUPPORTED +/* Returns row_pointers, which is an array of pointers to scanlines that was + * returned from png_read_png(). + */ +PNG_EXPORT(112, png_bytepp, png_get_rows, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Set row_pointers, which is an array of pointers to scanlines for use + * by png_write_png(). + */ +PNG_EXPORT(113, void, png_set_rows, (png_const_structrp png_ptr, + png_inforp info_ptr, png_bytepp row_pointers)); +#endif + +/* Returns number of color channels in image. */ +PNG_EXPORT(114, png_byte, png_get_channels, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +#ifdef PNG_EASY_ACCESS_SUPPORTED +/* Returns image width in pixels. */ +PNG_EXPORT(115, png_uint_32, png_get_image_width, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Returns image height in pixels. */ +PNG_EXPORT(116, png_uint_32, png_get_image_height, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Returns image bit_depth. */ +PNG_EXPORT(117, png_byte, png_get_bit_depth, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Returns image color_type. */ +PNG_EXPORT(118, png_byte, png_get_color_type, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Returns image filter_type. */ +PNG_EXPORT(119, png_byte, png_get_filter_type, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Returns image interlace_type. */ +PNG_EXPORT(120, png_byte, png_get_interlace_type, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Returns image compression_type. */ +PNG_EXPORT(121, png_byte, png_get_compression_type, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Returns image resolution in pixels per meter, from pHYs chunk data. */ +PNG_EXPORT(122, png_uint_32, png_get_pixels_per_meter, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(123, png_uint_32, png_get_x_pixels_per_meter, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(124, png_uint_32, png_get_y_pixels_per_meter, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +/* Returns pixel aspect ratio, computed from pHYs chunk data. */ +PNG_FP_EXPORT(125, float, png_get_pixel_aspect_ratio, + (png_const_structrp png_ptr, png_const_inforp info_ptr)) +PNG_FIXED_EXPORT(210, png_fixed_point, png_get_pixel_aspect_ratio_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr)) + +/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */ +PNG_EXPORT(126, png_int_32, png_get_x_offset_pixels, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(127, png_int_32, png_get_y_offset_pixels, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(128, png_int_32, png_get_x_offset_microns, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(129, png_int_32, png_get_y_offset_microns, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +#endif /* PNG_EASY_ACCESS_SUPPORTED */ + +#ifdef PNG_READ_SUPPORTED +/* Returns pointer to signature string read from PNG header */ +PNG_EXPORT(130, png_const_bytep, png_get_signature, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); +#endif + +#ifdef PNG_bKGD_SUPPORTED +PNG_EXPORT(131, png_uint_32, png_get_bKGD, (png_const_structrp png_ptr, + png_inforp info_ptr, png_color_16p *background)); +#endif + +#ifdef PNG_bKGD_SUPPORTED +PNG_EXPORT(132, void, png_set_bKGD, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_color_16p background)); +#endif + +#ifdef PNG_cHRM_SUPPORTED +PNG_FP_EXPORT(133, png_uint_32, png_get_cHRM, (png_const_structrp png_ptr, + png_const_inforp info_ptr, double *white_x, double *white_y, double *red_x, + double *red_y, double *green_x, double *green_y, double *blue_x, + double *blue_y)) +PNG_FP_EXPORT(230, png_uint_32, png_get_cHRM_XYZ, (png_const_structrp png_ptr, + png_const_inforp info_ptr, double *red_X, double *red_Y, double *red_Z, + double *green_X, double *green_Y, double *green_Z, double *blue_X, + double *blue_Y, double *blue_Z)) +PNG_FIXED_EXPORT(134, png_uint_32, png_get_cHRM_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + png_fixed_point *int_white_x, png_fixed_point *int_white_y, + png_fixed_point *int_red_x, png_fixed_point *int_red_y, + png_fixed_point *int_green_x, png_fixed_point *int_green_y, + png_fixed_point *int_blue_x, png_fixed_point *int_blue_y)) +PNG_FIXED_EXPORT(231, png_uint_32, png_get_cHRM_XYZ_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + png_fixed_point *int_red_X, png_fixed_point *int_red_Y, + png_fixed_point *int_red_Z, png_fixed_point *int_green_X, + png_fixed_point *int_green_Y, png_fixed_point *int_green_Z, + png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y, + png_fixed_point *int_blue_Z)) +#endif + +#ifdef PNG_cHRM_SUPPORTED +PNG_FP_EXPORT(135, void, png_set_cHRM, (png_const_structrp png_ptr, + png_inforp info_ptr, + double white_x, double white_y, double red_x, double red_y, double green_x, + double green_y, double blue_x, double blue_y)) +PNG_FP_EXPORT(232, void, png_set_cHRM_XYZ, (png_const_structrp png_ptr, + png_inforp info_ptr, double red_X, double red_Y, double red_Z, + double green_X, double green_Y, double green_Z, double blue_X, + double blue_Y, double blue_Z)) +PNG_FIXED_EXPORT(136, void, png_set_cHRM_fixed, (png_const_structrp png_ptr, + png_inforp info_ptr, png_fixed_point int_white_x, + png_fixed_point int_white_y, png_fixed_point int_red_x, + png_fixed_point int_red_y, png_fixed_point int_green_x, + png_fixed_point int_green_y, png_fixed_point int_blue_x, + png_fixed_point int_blue_y)) +PNG_FIXED_EXPORT(233, void, png_set_cHRM_XYZ_fixed, (png_const_structrp png_ptr, + png_inforp info_ptr, png_fixed_point int_red_X, png_fixed_point int_red_Y, + png_fixed_point int_red_Z, png_fixed_point int_green_X, + png_fixed_point int_green_Y, png_fixed_point int_green_Z, + png_fixed_point int_blue_X, png_fixed_point int_blue_Y, + png_fixed_point int_blue_Z)) +#endif + +#ifdef PNG_gAMA_SUPPORTED +PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, (png_const_structrp png_ptr, + png_const_inforp info_ptr, double *file_gamma)) +PNG_FIXED_EXPORT(138, png_uint_32, png_get_gAMA_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + png_fixed_point *int_file_gamma)) +#endif + +#ifdef PNG_gAMA_SUPPORTED +PNG_FP_EXPORT(139, void, png_set_gAMA, (png_const_structrp png_ptr, + png_inforp info_ptr, double file_gamma)) +PNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed, (png_const_structrp png_ptr, + png_inforp info_ptr, png_fixed_point int_file_gamma)) +#endif + +#ifdef PNG_hIST_SUPPORTED +PNG_EXPORT(141, png_uint_32, png_get_hIST, (png_const_structrp png_ptr, + png_inforp info_ptr, png_uint_16p *hist)); +#endif + +#ifdef PNG_hIST_SUPPORTED +PNG_EXPORT(142, void, png_set_hIST, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_uint_16p hist)); +#endif + +PNG_EXPORT(143, png_uint_32, png_get_IHDR, (png_const_structrp png_ptr, + png_const_inforp info_ptr, png_uint_32 *width, png_uint_32 *height, + int *bit_depth, int *color_type, int *interlace_method, + int *compression_method, int *filter_method)); + +PNG_EXPORT(144, void, png_set_IHDR, (png_const_structrp png_ptr, + png_inforp info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, + int color_type, int interlace_method, int compression_method, + int filter_method)); + +#ifdef PNG_oFFs_SUPPORTED +PNG_EXPORT(145, png_uint_32, png_get_oFFs, (png_const_structrp png_ptr, + png_const_inforp info_ptr, png_int_32 *offset_x, png_int_32 *offset_y, + int *unit_type)); +#endif + +#ifdef PNG_oFFs_SUPPORTED +PNG_EXPORT(146, void, png_set_oFFs, (png_const_structrp png_ptr, + png_inforp info_ptr, png_int_32 offset_x, png_int_32 offset_y, + int unit_type)); +#endif + +#ifdef PNG_pCAL_SUPPORTED +PNG_EXPORT(147, png_uint_32, png_get_pCAL, (png_const_structrp png_ptr, + png_inforp info_ptr, png_charp *purpose, png_int_32 *X0, + png_int_32 *X1, int *type, int *nparams, png_charp *units, + png_charpp *params)); +#endif + +#ifdef PNG_pCAL_SUPPORTED +PNG_EXPORT(148, void, png_set_pCAL, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_charp purpose, png_int_32 X0, png_int_32 X1, + int type, int nparams, png_const_charp units, png_charpp params)); +#endif + +#ifdef PNG_pHYs_SUPPORTED +PNG_EXPORT(149, png_uint_32, png_get_pHYs, (png_const_structrp png_ptr, + png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, + int *unit_type)); +#endif + +#ifdef PNG_pHYs_SUPPORTED +PNG_EXPORT(150, void, png_set_pHYs, (png_const_structrp png_ptr, + png_inforp info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type)); +#endif + +PNG_EXPORT(151, png_uint_32, png_get_PLTE, (png_const_structrp png_ptr, + png_inforp info_ptr, png_colorp *palette, int *num_palette)); + +PNG_EXPORT(152, void, png_set_PLTE, (png_structrp png_ptr, + png_inforp info_ptr, png_const_colorp palette, int num_palette)); + +#ifdef PNG_sBIT_SUPPORTED +PNG_EXPORT(153, png_uint_32, png_get_sBIT, (png_const_structrp png_ptr, + png_inforp info_ptr, png_color_8p *sig_bit)); +#endif + +#ifdef PNG_sBIT_SUPPORTED +PNG_EXPORT(154, void, png_set_sBIT, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_color_8p sig_bit)); +#endif + +#ifdef PNG_sRGB_SUPPORTED +PNG_EXPORT(155, png_uint_32, png_get_sRGB, (png_const_structrp png_ptr, + png_const_inforp info_ptr, int *file_srgb_intent)); +#endif + +#ifdef PNG_sRGB_SUPPORTED +PNG_EXPORT(156, void, png_set_sRGB, (png_const_structrp png_ptr, + png_inforp info_ptr, int srgb_intent)); +PNG_EXPORT(157, void, png_set_sRGB_gAMA_and_cHRM, (png_const_structrp png_ptr, + png_inforp info_ptr, int srgb_intent)); +#endif + +#ifdef PNG_iCCP_SUPPORTED +PNG_EXPORT(158, png_uint_32, png_get_iCCP, (png_const_structrp png_ptr, + png_inforp info_ptr, png_charpp name, int *compression_type, + png_bytepp profile, png_uint_32 *proflen)); +#endif + +#ifdef PNG_iCCP_SUPPORTED +PNG_EXPORT(159, void, png_set_iCCP, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_charp name, int compression_type, + png_const_bytep profile, png_uint_32 proflen)); +#endif + +#ifdef PNG_sPLT_SUPPORTED +PNG_EXPORT(160, int, png_get_sPLT, (png_const_structrp png_ptr, + png_inforp info_ptr, png_sPLT_tpp entries)); +#endif + +#ifdef PNG_sPLT_SUPPORTED +PNG_EXPORT(161, void, png_set_sPLT, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_sPLT_tp entries, int nentries)); +#endif + +#ifdef PNG_TEXT_SUPPORTED +/* png_get_text also returns the number of text chunks in *num_text */ +PNG_EXPORT(162, int, png_get_text, (png_const_structrp png_ptr, + png_inforp info_ptr, png_textp *text_ptr, int *num_text)); +#endif + +/* Note while png_set_text() will accept a structure whose text, + * language, and translated keywords are NULL pointers, the structure + * returned by png_get_text will always contain regular + * zero-terminated C strings. They might be empty strings but + * they will never be NULL pointers. + */ + +#ifdef PNG_TEXT_SUPPORTED +PNG_EXPORT(163, void, png_set_text, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_textp text_ptr, int num_text)); +#endif + +#ifdef PNG_tIME_SUPPORTED +PNG_EXPORT(164, png_uint_32, png_get_tIME, (png_const_structrp png_ptr, + png_inforp info_ptr, png_timep *mod_time)); +#endif + +#ifdef PNG_tIME_SUPPORTED +PNG_EXPORT(165, void, png_set_tIME, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_timep mod_time)); +#endif + +#ifdef PNG_tRNS_SUPPORTED +PNG_EXPORT(166, png_uint_32, png_get_tRNS, (png_const_structrp png_ptr, + png_inforp info_ptr, png_bytep *trans_alpha, int *num_trans, + png_color_16p *trans_color)); +#endif + +#ifdef PNG_tRNS_SUPPORTED +PNG_EXPORT(167, void, png_set_tRNS, (png_structrp png_ptr, + png_inforp info_ptr, png_const_bytep trans_alpha, int num_trans, + png_const_color_16p trans_color)); +#endif + +#ifdef PNG_sCAL_SUPPORTED +PNG_FP_EXPORT(168, png_uint_32, png_get_sCAL, (png_const_structrp png_ptr, + png_const_inforp info_ptr, int *unit, double *width, double *height)) +#if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \ + defined(PNG_FLOATING_POINT_SUPPORTED) +/* NOTE: this API is currently implemented using floating point arithmetic, + * consequently it can only be used on systems with floating point support. + * In any case the range of values supported by png_fixed_point is small and it + * is highly recommended that png_get_sCAL_s be used instead. + */ +PNG_FIXED_EXPORT(214, png_uint_32, png_get_sCAL_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit, + png_fixed_point *width, png_fixed_point *height)) +#endif +PNG_EXPORT(169, png_uint_32, png_get_sCAL_s, + (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit, + png_charpp swidth, png_charpp sheight)); + +PNG_FP_EXPORT(170, void, png_set_sCAL, (png_const_structrp png_ptr, + png_inforp info_ptr, int unit, double width, double height)) +PNG_FIXED_EXPORT(213, void, png_set_sCAL_fixed, (png_const_structrp png_ptr, + png_inforp info_ptr, int unit, png_fixed_point width, + png_fixed_point height)) +PNG_EXPORT(171, void, png_set_sCAL_s, (png_const_structrp png_ptr, + png_inforp info_ptr, int unit, + png_const_charp swidth, png_const_charp sheight)); +#endif /* PNG_sCAL_SUPPORTED */ + +#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED +/* Provide the default handling for all unknown chunks or, optionally, for + * specific unknown chunks. + * + * NOTE: prior to 1.6.0 the handling specified for particular chunks on read was + * ignored and the default was used, the per-chunk setting only had an effect on + * write. If you wish to have chunk-specific handling on read in code that must + * work on earlier versions you must use a user chunk callback to specify the + * desired handling (keep or discard.) + * + * The 'keep' parameter is a PNG_HANDLE_CHUNK_ value as listed below. The + * parameter is interpreted as follows: + * + * READ: + * PNG_HANDLE_CHUNK_AS_DEFAULT: + * Known chunks: do normal libpng processing, do not keep the chunk (but + * see the comments below about PNG_HANDLE_AS_UNKNOWN_SUPPORTED) + * Unknown chunks: for a specific chunk use the global default, when used + * as the default discard the chunk data. + * PNG_HANDLE_CHUNK_NEVER: + * Discard the chunk data. + * PNG_HANDLE_CHUNK_IF_SAFE: + * Keep the chunk data if the chunk is not critical else raise a chunk + * error. + * PNG_HANDLE_CHUNK_ALWAYS: + * Keep the chunk data. + * + * If the chunk data is saved it can be retrieved using png_get_unknown_chunks, + * below. Notice that specifying "AS_DEFAULT" as a global default is equivalent + * to specifying "NEVER", however when "AS_DEFAULT" is used for specific chunks + * it simply resets the behavior to the libpng default. + * + * INTERACTION WTIH USER CHUNK CALLBACKS: + * The per-chunk handling is always used when there is a png_user_chunk_ptr + * callback and the callback returns 0; the chunk is then always stored *unless* + * it is critical and the per-chunk setting is other than ALWAYS. Notice that + * the global default is *not* used in this case. (In effect the per-chunk + * value is incremented to at least IF_SAFE.) + * + * IMPORTANT NOTE: this behavior will change in libpng 1.7 - the global and + * per-chunk defaults will be honored. If you want to preserve the current + * behavior when your callback returns 0 you must set PNG_HANDLE_CHUNK_IF_SAFE + * as the default - if you don't do this libpng 1.6 will issue a warning. + * + * If you want unhandled unknown chunks to be discarded in libpng 1.6 and + * earlier simply return '1' (handled). + * + * PNG_HANDLE_AS_UNKNOWN_SUPPORTED: + * If this is *not* set known chunks will always be handled by libpng and + * will never be stored in the unknown chunk list. Known chunks listed to + * png_set_keep_unknown_chunks will have no effect. If it is set then known + * chunks listed with a keep other than AS_DEFAULT will *never* be processed + * by libpng, in addition critical chunks must either be processed by the + * callback or saved. + * + * The IHDR and IEND chunks must not be listed. Because this turns off the + * default handling for chunks that would otherwise be recognized the + * behavior of libpng transformations may well become incorrect! + * + * WRITE: + * When writing chunks the options only apply to the chunks specified by + * png_set_unknown_chunks (below), libpng will *always* write known chunks + * required by png_set_ calls and will always write the core critical chunks + * (as required for PLTE). + * + * Each chunk in the png_set_unknown_chunks list is looked up in the + * png_set_keep_unknown_chunks list to find the keep setting, this is then + * interpreted as follows: + * + * PNG_HANDLE_CHUNK_AS_DEFAULT: + * Write safe-to-copy chunks and write other chunks if the global + * default is set to _ALWAYS, otherwise don't write this chunk. + * PNG_HANDLE_CHUNK_NEVER: + * Do not write the chunk. + * PNG_HANDLE_CHUNK_IF_SAFE: + * Write the chunk if it is safe-to-copy, otherwise do not write it. + * PNG_HANDLE_CHUNK_ALWAYS: + * Write the chunk. + * + * Note that the default behavior is effectively the opposite of the read case - + * in read unknown chunks are not stored by default, in write they are written + * by default. Also the behavior of PNG_HANDLE_CHUNK_IF_SAFE is very different + * - on write the safe-to-copy bit is checked, on read the critical bit is + * checked and on read if the chunk is critical an error will be raised. + * + * num_chunks: + * =========== + * If num_chunks is positive, then the "keep" parameter specifies the manner + * for handling only those chunks appearing in the chunk_list array, + * otherwise the chunk list array is ignored. + * + * If num_chunks is 0 the "keep" parameter specifies the default behavior for + * unknown chunks, as described above. + * + * If num_chunks is negative, then the "keep" parameter specifies the manner + * for handling all unknown chunks plus all chunks recognized by libpng + * except for the IHDR, PLTE, tRNS, IDAT, and IEND chunks (which continue to + * be processed by libpng. + */ +PNG_EXPORT(172, void, png_set_keep_unknown_chunks, (png_structrp png_ptr, + int keep, png_const_bytep chunk_list, int num_chunks)); + +/* The "keep" PNG_HANDLE_CHUNK_ parameter for the specified chunk is returned; + * the result is therefore true (non-zero) if special handling is required, + * false for the default handling. + */ +PNG_EXPORT(173, int, png_handle_as_unknown, (png_const_structrp png_ptr, + png_const_bytep chunk_name)); +#endif + +#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED +PNG_EXPORT(174, void, png_set_unknown_chunks, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_unknown_chunkp unknowns, + int num_unknowns)); + /* NOTE: prior to 1.6.0 this routine set the 'location' field of the added + * unknowns to the location currently stored in the png_struct. This is + * invariably the wrong value on write. To fix this call the following API + * for each chunk in the list with the correct location. If you know your + * code won't be compiled on earlier versions you can rely on + * png_set_unknown_chunks(write-ptr, png_get_unknown_chunks(read-ptr)) doing + * the correct thing. + */ + +PNG_EXPORT(175, void, png_set_unknown_chunk_location, + (png_const_structrp png_ptr, png_inforp info_ptr, int chunk, int location)); + +PNG_EXPORT(176, int, png_get_unknown_chunks, (png_const_structrp png_ptr, + png_inforp info_ptr, png_unknown_chunkpp entries)); +#endif + +/* Png_free_data() will turn off the "valid" flag for anything it frees. + * If you need to turn it off for a chunk that your application has freed, + * you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK); + */ +PNG_EXPORT(177, void, png_set_invalid, (png_const_structrp png_ptr, + png_inforp info_ptr, int mask)); + +#ifdef PNG_INFO_IMAGE_SUPPORTED +/* The "params" pointer is currently not used and is for future expansion. */ +PNG_EXPORT(178, void, png_read_png, (png_structrp png_ptr, png_inforp info_ptr, + int transforms, png_voidp params)); +PNG_EXPORT(179, void, png_write_png, (png_structrp png_ptr, png_inforp info_ptr, + int transforms, png_voidp params)); +#endif + +PNG_EXPORT(180, png_const_charp, png_get_copyright, + (png_const_structrp png_ptr)); +PNG_EXPORT(181, png_const_charp, png_get_header_ver, + (png_const_structrp png_ptr)); +PNG_EXPORT(182, png_const_charp, png_get_header_version, + (png_const_structrp png_ptr)); +PNG_EXPORT(183, png_const_charp, png_get_libpng_ver, + (png_const_structrp png_ptr)); + +#ifdef PNG_MNG_FEATURES_SUPPORTED +PNG_EXPORT(184, png_uint_32, png_permit_mng_features, (png_structrp png_ptr, + png_uint_32 mng_features_permitted)); +#endif + +/* For use in png_set_keep_unknown, added to version 1.2.6 */ +#define PNG_HANDLE_CHUNK_AS_DEFAULT 0 +#define PNG_HANDLE_CHUNK_NEVER 1 +#define PNG_HANDLE_CHUNK_IF_SAFE 2 +#define PNG_HANDLE_CHUNK_ALWAYS 3 +#define PNG_HANDLE_CHUNK_LAST 4 + +/* Strip the prepended error numbers ("#nnn ") from error and warning + * messages before passing them to the error or warning handler. + */ +#ifdef PNG_ERROR_NUMBERS_SUPPORTED +PNG_EXPORT(185, void, png_set_strip_error_numbers, (png_structrp png_ptr, + png_uint_32 strip_mode)); +#endif + +/* Added in libpng-1.2.6 */ +#ifdef PNG_SET_USER_LIMITS_SUPPORTED +PNG_EXPORT(186, void, png_set_user_limits, (png_structrp png_ptr, + png_uint_32 user_width_max, png_uint_32 user_height_max)); +PNG_EXPORT(187, png_uint_32, png_get_user_width_max, + (png_const_structrp png_ptr)); +PNG_EXPORT(188, png_uint_32, png_get_user_height_max, + (png_const_structrp png_ptr)); +/* Added in libpng-1.4.0 */ +PNG_EXPORT(189, void, png_set_chunk_cache_max, (png_structrp png_ptr, + png_uint_32 user_chunk_cache_max)); +PNG_EXPORT(190, png_uint_32, png_get_chunk_cache_max, + (png_const_structrp png_ptr)); +/* Added in libpng-1.4.1 */ +PNG_EXPORT(191, void, png_set_chunk_malloc_max, (png_structrp png_ptr, + png_alloc_size_t user_chunk_cache_max)); +PNG_EXPORT(192, png_alloc_size_t, png_get_chunk_malloc_max, + (png_const_structrp png_ptr)); +#endif + +#if defined(PNG_INCH_CONVERSIONS_SUPPORTED) +PNG_EXPORT(193, png_uint_32, png_get_pixels_per_inch, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +PNG_EXPORT(194, png_uint_32, png_get_x_pixels_per_inch, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +PNG_EXPORT(195, png_uint_32, png_get_y_pixels_per_inch, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +PNG_FP_EXPORT(196, float, png_get_x_offset_inches, + (png_const_structrp png_ptr, png_const_inforp info_ptr)) +#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ +PNG_FIXED_EXPORT(211, png_fixed_point, png_get_x_offset_inches_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr)) +#endif + +PNG_FP_EXPORT(197, float, png_get_y_offset_inches, (png_const_structrp png_ptr, + png_const_inforp info_ptr)) +#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ +PNG_FIXED_EXPORT(212, png_fixed_point, png_get_y_offset_inches_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr)) +#endif + +# ifdef PNG_pHYs_SUPPORTED +PNG_EXPORT(198, png_uint_32, png_get_pHYs_dpi, (png_const_structrp png_ptr, + png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, + int *unit_type)); +# endif /* PNG_pHYs_SUPPORTED */ +#endif /* PNG_INCH_CONVERSIONS_SUPPORTED */ + +/* Added in libpng-1.4.0 */ +#ifdef PNG_IO_STATE_SUPPORTED +PNG_EXPORT(199, png_uint_32, png_get_io_state, (png_const_structrp png_ptr)); + +/* Removed from libpng 1.6; use png_get_io_chunk_type. */ +PNG_REMOVED(200, png_const_bytep, png_get_io_chunk_name, (png_structrp png_ptr), + PNG_DEPRECATED) + +PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type, + (png_const_structrp png_ptr)); + +/* The flags returned by png_get_io_state() are the following: */ +# define PNG_IO_NONE 0x0000 /* no I/O at this moment */ +# define PNG_IO_READING 0x0001 /* currently reading */ +# define PNG_IO_WRITING 0x0002 /* currently writing */ +# define PNG_IO_SIGNATURE 0x0010 /* currently at the file signature */ +# define PNG_IO_CHUNK_HDR 0x0020 /* currently at the chunk header */ +# define PNG_IO_CHUNK_DATA 0x0040 /* currently at the chunk data */ +# define PNG_IO_CHUNK_CRC 0x0080 /* currently at the chunk crc */ +# define PNG_IO_MASK_OP 0x000f /* current operation: reading/writing */ +# define PNG_IO_MASK_LOC 0x00f0 /* current location: sig/hdr/data/crc */ +#endif /* ?PNG_IO_STATE_SUPPORTED */ + +/* Interlace support. The following macros are always defined so that if + * libpng interlace handling is turned off the macros may be used to handle + * interlaced images within the application. + */ +#define PNG_INTERLACE_ADAM7_PASSES 7 + +/* Two macros to return the first row and first column of the original, + * full, image which appears in a given pass. 'pass' is in the range 0 + * to 6 and the result is in the range 0 to 7. + */ +#define PNG_PASS_START_ROW(pass) (((1&~(pass))<<(3-((pass)>>1)))&7) +#define PNG_PASS_START_COL(pass) (((1& (pass))<<(3-(((pass)+1)>>1)))&7) + +/* A macro to return the offset between pixels in the output row for a pair of + * pixels in the input - effectively the inverse of the 'COL_SHIFT' macro that + * follows. Note that ROW_OFFSET is the offset from one row to the next whereas + * COL_OFFSET is from one column to the next, within a row. + */ +#define PNG_PASS_ROW_OFFSET(pass) ((pass)>2?(8>>(((pass)-1)>>1)):8) +#define PNG_PASS_COL_OFFSET(pass) (1<<((7-(pass))>>1)) + +/* Two macros to help evaluate the number of rows or columns in each + * pass. This is expressed as a shift - effectively log2 of the number or + * rows or columns in each 8x8 tile of the original image. + */ +#define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3) +#define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3) + +/* Hence two macros to determine the number of rows or columns in a given + * pass of an image given its height or width. In fact these macros may + * return non-zero even though the sub-image is empty, because the other + * dimension may be empty for a small image. + */ +#define PNG_PASS_ROWS(height, pass) (((height)+(((1<>PNG_PASS_ROW_SHIFT(pass)) +#define PNG_PASS_COLS(width, pass) (((width)+(((1<>PNG_PASS_COL_SHIFT(pass)) + +/* For the reader row callbacks (both progressive and sequential) it is + * necessary to find the row in the output image given a row in an interlaced + * image, so two more macros: + */ +#define PNG_ROW_FROM_PASS_ROW(y_in, pass) \ + (((y_in)<>(((7-(off))-(pass))<<2)) & 0xF) | \ + ((0x01145AF0>>(((7-(off))-(pass))<<2)) & 0xF0)) + +#define PNG_ROW_IN_INTERLACE_PASS(y, pass) \ + ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1) +#define PNG_COL_IN_INTERLACE_PASS(x, pass) \ + ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1) + +#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED +/* With these routines we avoid an integer divide, which will be slower on + * most machines. However, it does take more operations than the corresponding + * divide method, so it may be slower on a few RISC systems. There are two + * shifts (by 8 or 16 bits) and an addition, versus a single integer divide. + * + * Note that the rounding factors are NOT supposed to be the same! 128 and + * 32768 are correct for the NODIV code; 127 and 32767 are correct for the + * standard method. + * + * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ] + */ + + /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */ + +# define png_composite(composite, fg, alpha, bg) \ + { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \ + * (png_uint_16)(alpha) \ + + (png_uint_16)(bg)*(png_uint_16)(255 \ + - (png_uint_16)(alpha)) + 128); \ + (composite) = (png_byte)((temp + (temp >> 8)) >> 8); } + +# define png_composite_16(composite, fg, alpha, bg) \ + { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) \ + * (png_uint_32)(alpha) \ + + (png_uint_32)(bg)*(65535 \ + - (png_uint_32)(alpha)) + 32768); \ + (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); } + +#else /* Standard method using integer division */ + +# define png_composite(composite, fg, alpha, bg) \ + (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) + \ + (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \ + 127) / 255) + +# define png_composite_16(composite, fg, alpha, bg) \ + (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \ + (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) + \ + 32767) / 65535) +#endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */ + +#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED +PNG_EXPORT(201, png_uint_32, png_get_uint_32, (png_const_bytep buf)); +PNG_EXPORT(202, png_uint_16, png_get_uint_16, (png_const_bytep buf)); +PNG_EXPORT(203, png_int_32, png_get_int_32, (png_const_bytep buf)); +#endif + +PNG_EXPORT(204, png_uint_32, png_get_uint_31, (png_const_structrp png_ptr, + png_const_bytep buf)); +/* No png_get_int_16 -- may be added if there's a real need for it. */ + +/* Place a 32-bit number into a buffer in PNG byte order (big-endian). */ +#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED +PNG_EXPORT(205, void, png_save_uint_32, (png_bytep buf, png_uint_32 i)); +#endif +#ifdef PNG_SAVE_INT_32_SUPPORTED +PNG_EXPORT(206, void, png_save_int_32, (png_bytep buf, png_int_32 i)); +#endif + +/* Place a 16-bit number into a buffer in PNG byte order. + * The parameter is declared unsigned int, not png_uint_16, + * just to avoid potential problems on pre-ANSI C compilers. + */ +#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED +PNG_EXPORT(207, void, png_save_uint_16, (png_bytep buf, unsigned int i)); +/* No png_save_int_16 -- may be added if there's a real need for it. */ +#endif + +#ifdef PNG_USE_READ_MACROS +/* Inline macros to do direct reads of bytes from the input buffer. + * The png_get_int_32() routine assumes we are using two's complement + * format for negative values, which is almost certainly true. + */ +# define PNG_get_uint_32(buf) \ + (((png_uint_32)(*(buf)) << 24) + \ + ((png_uint_32)(*((buf) + 1)) << 16) + \ + ((png_uint_32)(*((buf) + 2)) << 8) + \ + ((png_uint_32)(*((buf) + 3)))) + + /* From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the + * function) incorrectly returned a value of type png_uint_32. + */ +# define PNG_get_uint_16(buf) \ + ((png_uint_16) \ + (((unsigned int)(*(buf)) << 8) + \ + ((unsigned int)(*((buf) + 1))))) + +# define PNG_get_int_32(buf) \ + ((png_int_32)((*(buf) & 0x80) \ + ? -((png_int_32)((png_get_uint_32(buf) ^ 0xffffffffL) + 1)) \ + : (png_int_32)png_get_uint_32(buf))) + + /* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h, + * but defining a macro name prefixed with PNG_PREFIX. + */ +# ifndef PNG_PREFIX +# define png_get_uint_32(buf) PNG_get_uint_32(buf) +# define png_get_uint_16(buf) PNG_get_uint_16(buf) +# define png_get_int_32(buf) PNG_get_int_32(buf) +# endif +#else +# ifdef PNG_PREFIX + /* No macros; revert to the (redefined) function */ +# define PNG_get_uint_32 (png_get_uint_32) +# define PNG_get_uint_16 (png_get_uint_16) +# define PNG_get_int_32 (png_get_int_32) +# endif +#endif + +/******************************************************************************* + * SIMPLIFIED API + ******************************************************************************* + * + * Please read the documentation in libpng-manual.txt (TODO: write said + * documentation) if you don't understand what follows. + * + * The simplified API hides the details of both libpng and the PNG file format + * itself. It allows PNG files to be read into a very limited number of + * in-memory bitmap formats or to be written from the same formats. If these + * formats do not accomodate your needs then you can, and should, use the more + * sophisticated APIs above - these support a wide variety of in-memory formats + * and a wide variety of sophisticated transformations to those formats as well + * as a wide variety of APIs to manipulate ancillary information. + * + * To read a PNG file using the simplified API: + * + * 1) Declare a 'png_image' structure (see below) on the stack and set the + * version field to PNG_IMAGE_VERSION. + * 2) Call the appropriate png_image_begin_read... function. + * 3) Set the png_image 'format' member to the required sample format. + * 4) Allocate a buffer for the image and, if required, the color-map. + * 5) Call png_image_finish_read to read the image and, if required, the + * color-map into your buffers. + * + * There are no restrictions on the format of the PNG input itself; all valid + * color types, bit depths, and interlace methods are acceptable, and the + * input image is transformed as necessary to the requested in-memory format + * during the png_image_finish_read() step. The only caveat is that if you + * request a color-mapped image from a PNG that is full-color or makes + * complex use of an alpha channel the transformation is extremely lossy and the + * result may look terrible. + * + * To write a PNG file using the simplified API: + * + * 1) Declare a 'png_image' structure on the stack and memset() it to all zero. + * 2) Initialize the members of the structure that describe the image, setting + * the 'format' member to the format of the image samples. + * 3) Call the appropriate png_image_write... function with a pointer to the + * image and, if necessary, the color-map to write the PNG data. + * + * png_image is a structure that describes the in-memory format of an image + * when it is being read or defines the in-memory format of an image that you + * need to write: + */ +#define PNG_IMAGE_VERSION 1 + +typedef struct png_control *png_controlp; +typedef struct +{ + png_controlp opaque; /* Initialize to NULL, free with png_image_free */ + png_uint_32 version; /* Set to PNG_IMAGE_VERSION */ + png_uint_32 width; /* Image width in pixels (columns) */ + png_uint_32 height; /* Image height in pixels (rows) */ + png_uint_32 format; /* Image format as defined below */ + png_uint_32 flags; /* A bit mask containing informational flags */ + png_uint_32 colormap_entries; + /* Number of entries in the color-map */ + + /* In the event of an error or warning the following field will be set to a + * non-zero value and the 'message' field will contain a '\0' terminated + * string with the libpng error or warning message. If both warnings and + * an error were encountered, only the error is recorded. If there + * are multiple warnings, only the first one is recorded. + * + * The upper 30 bits of this value are reserved, the low two bits contain + * a value as follows: + */ +# define PNG_IMAGE_WARNING 1 +# define PNG_IMAGE_ERROR 2 + /* + * The result is a two bit code such that a value more than 1 indicates + * a failure in the API just called: + * + * 0 - no warning or error + * 1 - warning + * 2 - error + * 3 - error preceded by warning + */ +# define PNG_IMAGE_FAILED(png_cntrl) ((((png_cntrl).warning_or_error)&0x03)>1) + + png_uint_32 warning_or_error; + + char message[64]; +} png_image, *png_imagep; + +/* The samples of the image have one to four channels whose components have + * original values in the range 0 to 1.0: + * + * 1: A single gray or luminance channel (G). + * 2: A gray/luminance channel and an alpha channel (GA). + * 3: Three red, green, blue color channels (RGB). + * 4: Three color channels and an alpha channel (RGBA). + * + * The components are encoded in one of two ways: + * + * a) As a small integer, value 0..255, contained in a single byte. For the + * alpha channel the original value is simply value/255. For the color or + * luminance channels the value is encoded according to the sRGB specification + * and matches the 8-bit format expected by typical display devices. + * + * The color/gray channels are not scaled (pre-multiplied) by the alpha + * channel and are suitable for passing to color management software. + * + * b) As a value in the range 0..65535, contained in a 2-byte integer. All + * channels can be converted to the original value by dividing by 65535; all + * channels are linear. Color channels use the RGB encoding (RGB end-points) of + * the sRGB specification. This encoding is identified by the + * PNG_FORMAT_FLAG_LINEAR flag below. + * + * When the simplified API needs to convert between sRGB and linear colorspaces, + * the actual sRGB transfer curve defined in the sRGB specification (see the + * article at http://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2 + * approximation used elsewhere in libpng. + * + * When an alpha channel is present it is expected to denote pixel coverage + * of the color or luminance channels and is returned as an associated alpha + * channel: the color/gray channels are scaled (pre-multiplied) by the alpha + * value. + * + * The samples are either contained directly in the image data, between 1 and 8 + * bytes per pixel according to the encoding, or are held in a color-map indexed + * by bytes in the image data. In the case of a color-map the color-map entries + * are individual samples, encoded as above, and the image data has one byte per + * pixel to select the relevant sample from the color-map. + */ + +/* PNG_FORMAT_* + * + * #defines to be used in png_image::format. Each #define identifies a + * particular layout of sample data and, if present, alpha values. There are + * separate defines for each of the two component encodings. + * + * A format is built up using single bit flag values. All combinations are + * valid. Formats can be built up from the flag values or you can use one of + * the predefined values below. When testing formats always use the FORMAT_FLAG + * macros to test for individual features - future versions of the library may + * add new flags. + * + * When reading or writing color-mapped images the format should be set to the + * format of the entries in the color-map then png_image_{read,write}_colormap + * called to read or write the color-map and set the format correctly for the + * image data. Do not set the PNG_FORMAT_FLAG_COLORMAP bit directly! + * + * NOTE: libpng can be built with particular features disabled, if you see + * compiler errors because the definition of one of the following flags has been + * compiled out it is because libpng does not have the required support. It is + * possible, however, for the libpng configuration to enable the format on just + * read or just write; in that case you may see an error at run time. You can + * guard against this by checking for the definition of the appropriate + * "_SUPPORTED" macro, one of: + * + * PNG_SIMPLIFIED_{READ,WRITE}_{BGR,AFIRST}_SUPPORTED + */ +#define PNG_FORMAT_FLAG_ALPHA 0x01U /* format with an alpha channel */ +#define PNG_FORMAT_FLAG_COLOR 0x02U /* color format: otherwise grayscale */ +#define PNG_FORMAT_FLAG_LINEAR 0x04U /* 2 byte channels else 1 byte */ +#define PNG_FORMAT_FLAG_COLORMAP 0x08U /* image data is color-mapped */ + +#ifdef PNG_FORMAT_BGR_SUPPORTED +# define PNG_FORMAT_FLAG_BGR 0x10U /* BGR colors, else order is RGB */ +#endif + +#ifdef PNG_FORMAT_AFIRST_SUPPORTED +# define PNG_FORMAT_FLAG_AFIRST 0x20U /* alpha channel comes first */ +#endif + +/* Commonly used formats have predefined macros. + * + * First the single byte (sRGB) formats: + */ +#define PNG_FORMAT_GRAY 0 +#define PNG_FORMAT_GA PNG_FORMAT_FLAG_ALPHA +#define PNG_FORMAT_AG (PNG_FORMAT_GA|PNG_FORMAT_FLAG_AFIRST) +#define PNG_FORMAT_RGB PNG_FORMAT_FLAG_COLOR +#define PNG_FORMAT_BGR (PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_BGR) +#define PNG_FORMAT_RGBA (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_ALPHA) +#define PNG_FORMAT_ARGB (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_AFIRST) +#define PNG_FORMAT_BGRA (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_ALPHA) +#define PNG_FORMAT_ABGR (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_AFIRST) + +/* Then the linear 2-byte formats. When naming these "Y" is used to + * indicate a luminance (gray) channel. + */ +#define PNG_FORMAT_LINEAR_Y PNG_FORMAT_FLAG_LINEAR +#define PNG_FORMAT_LINEAR_Y_ALPHA (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_ALPHA) +#define PNG_FORMAT_LINEAR_RGB (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR) +#define PNG_FORMAT_LINEAR_RGB_ALPHA \ + (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA) + +/* With color-mapped formats the image data is one byte for each pixel, the byte + * is an index into the color-map which is formatted as above. To obtain a + * color-mapped format it is sufficient just to add the PNG_FOMAT_FLAG_COLORMAP + * to one of the above definitions, or you can use one of the definitions below. + */ +#define PNG_FORMAT_RGB_COLORMAP (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_COLORMAP) +#define PNG_FORMAT_BGR_COLORMAP (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_COLORMAP) +#define PNG_FORMAT_RGBA_COLORMAP (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_COLORMAP) +#define PNG_FORMAT_ARGB_COLORMAP (PNG_FORMAT_ARGB|PNG_FORMAT_FLAG_COLORMAP) +#define PNG_FORMAT_BGRA_COLORMAP (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_COLORMAP) +#define PNG_FORMAT_ABGR_COLORMAP (PNG_FORMAT_ABGR|PNG_FORMAT_FLAG_COLORMAP) + +/* PNG_IMAGE macros + * + * These are convenience macros to derive information from a png_image + * structure. The PNG_IMAGE_SAMPLE_ macros return values appropriate to the + * actual image sample values - either the entries in the color-map or the + * pixels in the image. The PNG_IMAGE_PIXEL_ macros return corresponding values + * for the pixels and will always return 1 for color-mapped formats. The + * remaining macros return information about the rows in the image and the + * complete image. + * + * NOTE: All the macros that take a png_image::format parameter are compile time + * constants if the format parameter is, itself, a constant. Therefore these + * macros can be used in array declarations and case labels where required. + * Similarly the macros are also pre-processor constants (sizeof is not used) so + * they can be used in #if tests. + * + * First the information about the samples. + */ +#define PNG_IMAGE_SAMPLE_CHANNELS(fmt)\ + (((fmt)&(PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA))+1) + /* Return the total number of channels in a given format: 1..4 */ + +#define PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)\ + ((((fmt) & PNG_FORMAT_FLAG_LINEAR) >> 2)+1) + /* Return the size in bytes of a single component of a pixel or color-map + * entry (as appropriate) in the image: 1 or 2. + */ + +#define PNG_IMAGE_SAMPLE_SIZE(fmt)\ + (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)) + /* This is the size of the sample data for one sample. If the image is + * color-mapped it is the size of one color-map entry (and image pixels are + * one byte in size), otherwise it is the size of one image pixel. + */ + +#define PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(fmt)\ + (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * 256) + /* The maximum size of the color-map required by the format expressed in a + * count of components. This can be used to compile-time allocate a + * color-map: + * + * png_uint_16 colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(linear_fmt)]; + * + * png_byte colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(sRGB_fmt)]; + * + * Alternatively use the PNG_IMAGE_COLORMAP_SIZE macro below to use the + * information from one of the png_image_begin_read_ APIs and dynamically + * allocate the required memory. + */ + +/* Corresponding information about the pixels */ +#define PNG_IMAGE_PIXEL_(test,fmt)\ + (((fmt)&PNG_FORMAT_FLAG_COLORMAP)?1:test(fmt)) + +#define PNG_IMAGE_PIXEL_CHANNELS(fmt)\ + PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_CHANNELS,fmt) + /* The number of separate channels (components) in a pixel; 1 for a + * color-mapped image. + */ + +#define PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)\ + PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_COMPONENT_SIZE,fmt) + /* The size, in bytes, of each component in a pixel; 1 for a color-mapped + * image. + */ + +#define PNG_IMAGE_PIXEL_SIZE(fmt) PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_SIZE,fmt) + /* The size, in bytes, of a complete pixel; 1 for a color-mapped image. */ + +/* Information about the whole row, or whole image */ +#define PNG_IMAGE_ROW_STRIDE(image)\ + (PNG_IMAGE_PIXEL_CHANNELS((image).format) * (image).width) + /* Return the total number of components in a single row of the image; this + * is the minimum 'row stride', the minimum count of components between each + * row. For a color-mapped image this is the minimum number of bytes in a + * row. + */ + +#define PNG_IMAGE_BUFFER_SIZE(image, row_stride)\ + (PNG_IMAGE_PIXEL_COMPONENT_SIZE((image).format)*(image).height*(row_stride)) + /* Return the size, in bytes, of an image buffer given a png_image and a row + * stride - the number of components to leave space for in each row. + */ + +#define PNG_IMAGE_SIZE(image)\ + PNG_IMAGE_BUFFER_SIZE(image, PNG_IMAGE_ROW_STRIDE(image)) + /* Return the size, in bytes, of the image in memory given just a png_image; + * the row stride is the minimum stride required for the image. + */ + +#define PNG_IMAGE_COLORMAP_SIZE(image)\ + (PNG_IMAGE_SAMPLE_SIZE((image).format) * (image).colormap_entries) + /* Return the size, in bytes, of the color-map of this image. If the image + * format is not a color-map format this will return a size sufficient for + * 256 entries in the given format; check PNG_FORMAT_FLAG_COLORMAP if + * you don't want to allocate a color-map in this case. + */ + +/* PNG_IMAGE_FLAG_* + * + * Flags containing additional information about the image are held in the + * 'flags' field of png_image. + */ +#define PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB 0x01 + /* This indicates the the RGB values of the in-memory bitmap do not + * correspond to the red, green and blue end-points defined by sRGB. + */ + +#define PNG_IMAGE_FLAG_FAST 0x02 + /* On write emphasise speed over compression; the resultant PNG file will be + * larger but will be produced significantly faster, particular for large + * images. Do not use this option for images which will be distributed, only + * used it when producing intermediate files that will be read back in + * repeatedly. For a typical 24-bit image the option will double the read + * speed at the cost of increasing the image size by 25%, however for many + * more compressible images the PNG file can be 10 times larger with only a + * slight speed gain. + */ + +#define PNG_IMAGE_FLAG_16BIT_sRGB 0x04 + /* On read if the image is a 16-bit per component image and there is no gAMA + * or sRGB chunk assume that the components are sRGB encoded. Notice that + * images output by the simplified API always have gamma information; setting + * this flag only affects the interpretation of 16-bit images from an + * external source. It is recommended that the application expose this flag + * to the user; the user can normally easily recognize the difference between + * linear and sRGB encoding. This flag has no effect on write - the data + * passed to the write APIs must have the correct encoding (as defined + * above.) + * + * If the flag is not set (the default) input 16-bit per component data is + * assumed to be linear. + * + * NOTE: the flag can only be set after the png_image_begin_read_ call, + * because that call initializes the 'flags' field. + */ + +#ifdef PNG_SIMPLIFIED_READ_SUPPORTED +/* READ APIs + * --------- + * + * The png_image passed to the read APIs must have been initialized by setting + * the png_controlp field 'opaque' to NULL (or, safer, memset the whole thing.) + */ +#ifdef PNG_STDIO_SUPPORTED +PNG_EXPORT(234, int, png_image_begin_read_from_file, (png_imagep image, + const char *file_name)); + /* The named file is opened for read and the image header is filled in + * from the PNG header in the file. + */ + +PNG_EXPORT(235, int, png_image_begin_read_from_stdio, (png_imagep image, + FILE* file)); + /* The PNG header is read from the stdio FILE object. */ +#endif /* PNG_STDIO_SUPPORTED */ + +PNG_EXPORT(236, int, png_image_begin_read_from_memory, (png_imagep image, + png_const_voidp memory, png_size_t size)); + /* The PNG header is read from the given memory buffer. */ + +PNG_EXPORT(237, int, png_image_finish_read, (png_imagep image, + png_const_colorp background, void *buffer, png_int_32 row_stride, + void *colormap)); + /* Finish reading the image into the supplied buffer and clean up the + * png_image structure. + * + * row_stride is the step, in byte or 2-byte units as appropriate, + * between adjacent rows. A positive stride indicates that the top-most row + * is first in the buffer - the normal top-down arrangement. A negative + * stride indicates that the bottom-most row is first in the buffer. + * + * background need only be supplied if an alpha channel must be removed from + * a png_byte format and the removal is to be done by compositing on a solid + * color; otherwise it may be NULL and any composition will be done directly + * onto the buffer. The value is an sRGB color to use for the background, + * for grayscale output the green channel is used. + * + * background must be supplied when an alpha channel must be removed from a + * single byte color-mapped output format, in other words if: + * + * 1) The original format from png_image_begin_read_from_* had + * PNG_FORMAT_FLAG_ALPHA set. + * 2) The format set by the application does not. + * 3) The format set by the application has PNG_FORMAT_FLAG_COLORMAP set and + * PNG_FORMAT_FLAG_LINEAR *not* set. + * + * For linear output removing the alpha channel is always done by compositing + * on black and background is ignored. + * + * colormap must be supplied when PNG_FORMAT_FLAG_COLORMAP is set. It must + * be at least the size (in bytes) returned by PNG_IMAGE_COLORMAP_SIZE. + * image->colormap_entries will be updated to the actual number of entries + * written to the colormap; this may be less than the original value. + */ + +PNG_EXPORT(238, void, png_image_free, (png_imagep image)); + /* Free any data allocated by libpng in image->opaque, setting the pointer to + * NULL. May be called at any time after the structure is initialized. + */ +#endif /* PNG_SIMPLIFIED_READ_SUPPORTED */ + +#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED +#ifdef PNG_STDIO_SUPPORTED +/* WRITE APIS + * ---------- + * For write you must initialize a png_image structure to describe the image to + * be written. To do this use memset to set the whole structure to 0 then + * initialize fields describing your image. + * + * version: must be set to PNG_IMAGE_VERSION + * opaque: must be initialized to NULL + * width: image width in pixels + * height: image height in rows + * format: the format of the data (image and color-map) you wish to write + * flags: set to 0 unless one of the defined flags applies; set + * PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB for color format images where the RGB + * values do not correspond to the colors in sRGB. + * colormap_entries: set to the number of entries in the color-map (0 to 256) + */ +PNG_EXPORT(239, int, png_image_write_to_file, (png_imagep image, + const char *file, int convert_to_8bit, const void *buffer, + png_int_32 row_stride, const void *colormap)); + /* Write the image to the named file. */ + +PNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *file, + int convert_to_8_bit, const void *buffer, png_int_32 row_stride, + const void *colormap)); + /* Write the image to the given (FILE*). */ + +/* With both write APIs if image is in one of the linear formats with 16-bit + * data then setting convert_to_8_bit will cause the output to be an 8-bit PNG + * gamma encoded according to the sRGB specification, otherwise a 16-bit linear + * encoded PNG file is written. + * + * With color-mapped data formats the colormap parameter point to a color-map + * with at least image->colormap_entries encoded in the specified format. If + * the format is linear the written PNG color-map will be converted to sRGB + * regardless of the convert_to_8_bit flag. + * + * With all APIs row_stride is handled as in the read APIs - it is the spacing + * from one row to the next in component sized units (1 or 2 bytes) and if + * negative indicates a bottom-up row layout in the buffer. + * + * Note that the write API does not support interlacing or sub-8-bit pixels. + */ +#endif /* PNG_STDIO_SUPPORTED */ +#endif /* PNG_SIMPLIFIED_WRITE_SUPPORTED */ +/******************************************************************************* + * END OF SIMPLIFIED API + ******************************************************************************/ + +#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED +PNG_EXPORT(242, void, png_set_check_for_invalid_index, + (png_structrp png_ptr, int allowed)); +# ifdef PNG_GET_PALETTE_MAX_SUPPORTED +PNG_EXPORT(243, int, png_get_palette_max, (png_const_structp png_ptr, + png_const_infop info_ptr)); +# endif +#endif /* CHECK_FOR_INVALID_INDEX */ + +/******************************************************************************* + * IMPLEMENTATION OPTIONS + ******************************************************************************* + * + * Support for arbitrary implementation-specific optimizations. The API allows + * particular options to be turned on or off. 'Option' is the number of the + * option and 'onoff' is 0 (off) or non-0 (on). The value returned is given + * by the PNG_OPTION_ defines below. + * + * HARDWARE: normally hardware capabilites, such as the Intel SSE instructions, + * are detected at run time, however sometimes it may be impossible + * to do this in user mode, in which case it is necessary to discover + * the capabilities in an OS specific way. Such capabilities are + * listed here when libpng has support for them and must be turned + * ON by the application if present. + * + * SOFTWARE: sometimes software optimizations actually result in performance + * decrease on some architectures or systems, or with some sets of + * PNG images. 'Software' options allow such optimizations to be + * selected at run time. + */ +#ifdef PNG_SET_OPTION_SUPPORTED +#ifdef PNG_ARM_NEON_API_SUPPORTED +# define PNG_ARM_NEON 0 /* HARDWARE: ARM Neon SIMD instructions supported */ +#endif +#define PNG_MAXIMUM_INFLATE_WINDOW 2 /* SOFTWARE: force maximum window */ +#define PNG_OPTION_NEXT 4 /* Next option - numbers must be even */ + +/* Return values: NOTE: there are four values and 'off' is *not* zero */ +#define PNG_OPTION_UNSET 0 /* Unset - defaults to off */ +#define PNG_OPTION_INVALID 1 /* Option number out of range */ +#define PNG_OPTION_OFF 2 +#define PNG_OPTION_ON 3 + +PNG_EXPORT(244, int, png_set_option, (png_structrp png_ptr, int option, + int onoff)); +#endif + +/******************************************************************************* + * END OF HARDWARE OPTIONS + ******************************************************************************/ + +/* Maintainer: Put new public prototypes here ^, in libpng.3, and project + * defs, scripts/pnglibconf.h, and scripts/pnglibconf.h.prebuilt + */ + +/* The last ordinal number (this is the *last* one already used; the next + * one to use is one more than this.) Maintainer, remember to add an entry to + * scripts/symbols.def as well. + */ +#ifdef PNG_EXPORT_LAST_ORDINAL + PNG_EXPORT_LAST_ORDINAL(244); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PNG_VERSION_INFO_ONLY */ +/* Do not put anything past this line */ +#endif /* PNG_H */ diff --git a/scalos/include/pngconf.h b/scalos/include/pngconf.h new file mode 100644 index 000000000..5fa1f8c0b --- /dev/null +++ b/scalos/include/pngconf.h @@ -0,0 +1,632 @@ + +/* pngconf.h - machine configurable file for libpng + * + * libpng version 1.6.7 - November 14, 2013 + * + * Copyright (c) 1998-2013 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + */ + +/* Any machine specific code is near the front of this file, so if you + * are configuring libpng for a machine, you may want to read the section + * starting here down to where it starts to typedef png_color, png_text, + * and png_info. + */ + +#ifndef PNGCONF_H +#define PNGCONF_H + +// AMIGA BEGIN +#undef PNG_CONSOLE_IO_SUPPORTED +#undef PNG_MNG_FEATURES_SUPPORTED +#undef PNG_FLOATING_POINT_SUPPORTED +#undef PNG_FLOATING_ARITHMETIC_SUPPORTED +#undef PNG_PROGRESSIVE_READ_SUPPORTED +#undef PNG_STDIO_SUPPORTED +#define PNG_NO_MNG_FEATURES +#define PNG_NO_FLOATING_POINT_SUPPORTED +#define PNG_NO_CONSOLE_IO +#define PNG_NO_STDIO +#define PNG_NO_PROGRESSIVE_READ +#undef PNG_WRITE_FLUSH_SUPPORTED +// AMIGA END + +/* To do: Do all of this in scripts/pnglibconf.dfa */ +#ifdef PNG_SAFE_LIMITS_SUPPORTED +# ifdef PNG_USER_WIDTH_MAX +# undef PNG_USER_WIDTH_MAX +# define PNG_USER_WIDTH_MAX 1000000L +# endif +# ifdef PNG_USER_HEIGHT_MAX +# undef PNG_USER_HEIGHT_MAX +# define PNG_USER_HEIGHT_MAX 1000000L +# endif +# ifdef PNG_USER_CHUNK_MALLOC_MAX +# undef PNG_USER_CHUNK_MALLOC_MAX +# define PNG_USER_CHUNK_MALLOC_MAX 4000000L +# endif +# ifdef PNG_USER_CHUNK_CACHE_MAX +# undef PNG_USER_CHUNK_CACHE_MAX +# define PNG_USER_CHUNK_CACHE_MAX 128 +# endif +#endif + +#ifndef PNG_BUILDING_SYMBOL_TABLE /* else includes may cause problems */ + +/* From libpng 1.6.0 libpng requires an ANSI X3.159-1989 ("ISOC90") compliant C + * compiler for correct compilation. The following header files are required by + * the standard. If your compiler doesn't provide these header files, or they + * do not match the standard, you will need to provide/improve them. + */ +#include +#include + +/* Library header files. These header files are all defined by ISOC90; libpng + * expects conformant implementations, however, an ISOC90 conformant system need + * not provide these header files if the functionality cannot be implemented. + * In this case it will be necessary to disable the relevant parts of libpng in + * the build of pnglibconf.h. + * + * Prior to 1.6.0 string.h was included here; the API changes in 1.6.0 to not + * include this unnecessary header file. + */ + +#ifdef PNG_STDIO_SUPPORTED + /* Required for the definition of FILE: */ +# include +#endif + +#ifdef PNG_SETJMP_SUPPORTED + /* Required for the definition of jmp_buf and the declaration of longjmp: */ +# include +#endif + +#ifdef PNG_CONVERT_tIME_SUPPORTED + /* Required for struct tm: */ +# include +#endif + +#endif /* PNG_BUILDING_SYMBOL_TABLE */ + +/* Prior to 1.6.0 it was possible to turn off 'const' in declarations using + * PNG_NO_CONST; this is no longer supported except for data declarations which + * apparently still cause problems in 2011 on some compilers. + */ +#define PNG_CONST const /* backward compatibility only */ + +/* This controls optimization of the reading of 16 and 32 bit values + * from PNG files. It can be set on a per-app-file basis - it + * just changes whether a macro is used when the function is called. + * The library builder sets the default; if read functions are not + * built into the library the macro implementation is forced on. + */ +#ifndef PNG_READ_INT_FUNCTIONS_SUPPORTED +# define PNG_USE_READ_MACROS +#endif +#if !defined(PNG_NO_USE_READ_MACROS) && !defined(PNG_USE_READ_MACROS) +# if PNG_DEFAULT_READ_MACROS +# define PNG_USE_READ_MACROS +# endif +#endif + +/* COMPILER SPECIFIC OPTIONS. + * + * These options are provided so that a variety of difficult compilers + * can be used. Some are fixed at build time (e.g. PNG_API_RULE + * below) but still have compiler specific implementations, others + * may be changed on a per-file basis when compiling against libpng. + */ + +/* The PNGARG macro was used in versions of libpng prior to 1.6.0 to protect + * against legacy (pre ISOC90) compilers that did not understand function + * prototypes. It is not required for modern C compilers. + */ +#ifndef PNGARG +# define PNGARG(arglist) arglist +#endif + +/* Function calling conventions. + * ============================= + * Normally it is not necessary to specify to the compiler how to call + * a function - it just does it - however on x86 systems derived from + * Microsoft and Borland C compilers ('IBM PC', 'DOS', 'Windows' systems + * and some others) there are multiple ways to call a function and the + * default can be changed on the compiler command line. For this reason + * libpng specifies the calling convention of every exported function and + * every function called via a user supplied function pointer. This is + * done in this file by defining the following macros: + * + * PNGAPI Calling convention for exported functions. + * PNGCBAPI Calling convention for user provided (callback) functions. + * PNGCAPI Calling convention used by the ANSI-C library (required + * for longjmp callbacks and sometimes used internally to + * specify the calling convention for zlib). + * + * These macros should never be overridden. If it is necessary to + * change calling convention in a private build this can be done + * by setting PNG_API_RULE (which defaults to 0) to one of the values + * below to select the correct 'API' variants. + * + * PNG_API_RULE=0 Use PNGCAPI - the 'C' calling convention - throughout. + * This is correct in every known environment. + * PNG_API_RULE=1 Use the operating system convention for PNGAPI and + * the 'C' calling convention (from PNGCAPI) for + * callbacks (PNGCBAPI). This is no longer required + * in any known environment - if it has to be used + * please post an explanation of the problem to the + * libpng mailing list. + * + * These cases only differ if the operating system does not use the C + * calling convention, at present this just means the above cases + * (x86 DOS/Windows sytems) and, even then, this does not apply to + * Cygwin running on those systems. + * + * Note that the value must be defined in pnglibconf.h so that what + * the application uses to call the library matches the conventions + * set when building the library. + */ + +/* Symbol export + * ============= + * When building a shared library it is almost always necessary to tell + * the compiler which symbols to export. The png.h macro 'PNG_EXPORT' + * is used to mark the symbols. On some systems these symbols can be + * extracted at link time and need no special processing by the compiler, + * on other systems the symbols are flagged by the compiler and just + * the declaration requires a special tag applied (unfortunately) in a + * compiler dependent way. Some systems can do either. + * + * A small number of older systems also require a symbol from a DLL to + * be flagged to the program that calls it. This is a problem because + * we do not know in the header file included by application code that + * the symbol will come from a shared library, as opposed to a statically + * linked one. For this reason the application must tell us by setting + * the magic flag PNG_USE_DLL to turn on the special processing before + * it includes png.h. + * + * Four additional macros are used to make this happen: + * + * PNG_IMPEXP The magic (if any) to cause a symbol to be exported from + * the build or imported if PNG_USE_DLL is set - compiler + * and system specific. + * + * PNG_EXPORT_TYPE(type) A macro that pre or appends PNG_IMPEXP to + * 'type', compiler specific. + * + * PNG_DLL_EXPORT Set to the magic to use during a libpng build to + * make a symbol exported from the DLL. Not used in the + * public header files; see pngpriv.h for how it is used + * in the libpng build. + * + * PNG_DLL_IMPORT Set to the magic to force the libpng symbols to come + * from a DLL - used to define PNG_IMPEXP when + * PNG_USE_DLL is set. + */ + +/* System specific discovery. + * ========================== + * This code is used at build time to find PNG_IMPEXP, the API settings + * and PNG_EXPORT_TYPE(), it may also set a macro to indicate the DLL + * import processing is possible. On Windows systems it also sets + * compiler-specific macros to the values required to change the calling + * conventions of the various functions. + */ +#if defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||\ + defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) + /* Windows system (DOS doesn't support DLLs). Includes builds under Cygwin or + * MinGW on any architecture currently supported by Windows. Also includes + * Watcom builds but these need special treatment because they are not + * compatible with GCC or Visual C because of different calling conventions. + */ +# if PNG_API_RULE == 2 + /* If this line results in an error, either because __watcall is not + * understood or because of a redefine just below you cannot use *this* + * build of the library with the compiler you are using. *This* build was + * build using Watcom and applications must also be built using Watcom! + */ +# define PNGCAPI __watcall +# endif + +# if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 800)) +# define PNGCAPI __cdecl +# if PNG_API_RULE == 1 + /* If this line results in an error __stdcall is not understood and + * PNG_API_RULE should not have been set to '1'. + */ +# define PNGAPI __stdcall +# endif +# else + /* An older compiler, or one not detected (erroneously) above, + * if necessary override on the command line to get the correct + * variants for the compiler. + */ +# ifndef PNGCAPI +# define PNGCAPI _cdecl +# endif +# if PNG_API_RULE == 1 && !defined(PNGAPI) +# define PNGAPI _stdcall +# endif +# endif /* compiler/api */ + + /* NOTE: PNGCBAPI always defaults to PNGCAPI. */ + +# if defined(PNGAPI) && !defined(PNG_USER_PRIVATEBUILD) +# error "PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed" +# endif + +# if (defined(_MSC_VER) && _MSC_VER < 800) ||\ + (defined(__BORLANDC__) && __BORLANDC__ < 0x500) + /* older Borland and MSC + * compilers used '__export' and required this to be after + * the type. + */ +# ifndef PNG_EXPORT_TYPE +# define PNG_EXPORT_TYPE(type) type PNG_IMPEXP +# endif +# define PNG_DLL_EXPORT __export +# else /* newer compiler */ +# define PNG_DLL_EXPORT __declspec(dllexport) +# ifndef PNG_DLL_IMPORT +# define PNG_DLL_IMPORT __declspec(dllimport) +# endif +# endif /* compiler */ + +#else /* !Windows */ +# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__) +# define PNGAPI _System +# else /* !Windows/x86 && !OS/2 */ + /* Use the defaults, or define PNG*API on the command line (but + * this will have to be done for every compile!) + */ +# endif /* other system, !OS/2 */ +#endif /* !Windows/x86 */ + +/* Now do all the defaulting . */ +#ifndef PNGCAPI +# define PNGCAPI +#endif +#ifndef PNGCBAPI +# define PNGCBAPI PNGCAPI +#endif +#ifndef PNGAPI +# define PNGAPI PNGCAPI +#endif + +/* PNG_IMPEXP may be set on the compilation system command line or (if not set) + * then in an internal header file when building the library, otherwise (when + * using the library) it is set here. + */ +#ifndef PNG_IMPEXP +# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT) + /* This forces use of a DLL, disallowing static linking */ +# define PNG_IMPEXP PNG_DLL_IMPORT +# endif + +# ifndef PNG_IMPEXP +# define PNG_IMPEXP +# endif +#endif + +/* In 1.5.2 the definition of PNG_FUNCTION has been changed to always treat + * 'attributes' as a storage class - the attributes go at the start of the + * function definition, and attributes are always appended regardless of the + * compiler. This considerably simplifies these macros but may cause problems + * if any compilers both need function attributes and fail to handle them as + * a storage class (this is unlikely.) + */ +#ifndef PNG_FUNCTION +# define PNG_FUNCTION(type, name, args, attributes) attributes type name args +#endif + +#ifndef PNG_EXPORT_TYPE +# define PNG_EXPORT_TYPE(type) PNG_IMPEXP type +#endif + + /* The ordinal value is only relevant when preprocessing png.h for symbol + * table entries, so we discard it here. See the .dfn files in the + * scripts directory. + */ +#ifndef PNG_EXPORTA + +# define PNG_EXPORTA(ordinal, type, name, args, attributes)\ + PNG_FUNCTION(PNG_EXPORT_TYPE(type),(PNGAPI name),PNGARG(args), \ + extern attributes) +#endif + +/* ANSI-C (C90) does not permit a macro to be invoked with an empty argument, + * so make something non-empty to satisfy the requirement: + */ +#define PNG_EMPTY /*empty list*/ + +#define PNG_EXPORT(ordinal, type, name, args)\ + PNG_EXPORTA(ordinal, type, name, args, PNG_EMPTY) + +/* Use PNG_REMOVED to comment out a removed interface. */ +#ifndef PNG_REMOVED +# define PNG_REMOVED(ordinal, type, name, args, attributes) +#endif + +#ifndef PNG_CALLBACK +# define PNG_CALLBACK(type, name, args) type (PNGCBAPI name) PNGARG(args) +#endif + +/* Support for compiler specific function attributes. These are used + * so that where compiler support is available incorrect use of API + * functions in png.h will generate compiler warnings. + * + * Added at libpng-1.2.41. + */ + +#ifndef PNG_NO_PEDANTIC_WARNINGS +# ifndef PNG_PEDANTIC_WARNINGS_SUPPORTED +# define PNG_PEDANTIC_WARNINGS_SUPPORTED +# endif +#endif + +#ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED + /* Support for compiler specific function attributes. These are used + * so that where compiler support is available, incorrect use of API + * functions in png.h will generate compiler warnings. Added at libpng + * version 1.2.41. Disabling these removes the warnings but may also produce + * less efficient code. + */ +# if defined(__GNUC__) +# ifndef PNG_USE_RESULT +# define PNG_USE_RESULT __attribute__((__warn_unused_result__)) +# endif +# ifndef PNG_NORETURN +# define PNG_NORETURN __attribute__((__noreturn__)) +# endif +# if __GNUC__ >= 3 +# ifndef PNG_ALLOCATED +# define PNG_ALLOCATED __attribute__((__malloc__)) +# endif +# ifndef PNG_DEPRECATED +# define PNG_DEPRECATED __attribute__((__deprecated__)) +# endif +# ifndef PNG_PRIVATE +# if 0 /* Doesn't work so we use deprecated instead*/ +# define PNG_PRIVATE \ + __attribute__((warning("This function is not exported by libpng."))) +# else +# define PNG_PRIVATE \ + __attribute__((__deprecated__)) +# endif +# endif +# if ((__GNUC__ != 3) || !defined(__GNUC_MINOR__) || (__GNUC_MINOR__ >= 1)) +# ifndef PNG_RESTRICT +# define PNG_RESTRICT __restrict +# endif +# endif /* __GNUC__ == 3.0 */ +# endif /* __GNUC__ >= 3 */ + +# elif defined(_MSC_VER) && (_MSC_VER >= 1300) +# ifndef PNG_USE_RESULT +# define PNG_USE_RESULT /* not supported */ +# endif +# ifndef PNG_NORETURN +# define PNG_NORETURN __declspec(noreturn) +# endif +# ifndef PNG_ALLOCATED +# if (_MSC_VER >= 1400) +# define PNG_ALLOCATED __declspec(restrict) +# endif +# endif +# ifndef PNG_DEPRECATED +# define PNG_DEPRECATED __declspec(deprecated) +# endif +# ifndef PNG_PRIVATE +# define PNG_PRIVATE __declspec(deprecated) +# endif +# ifndef PNG_RESTRICT +# if (_MSC_VER >= 1400) +# define PNG_RESTRICT __restrict +# endif +# endif + +# elif defined(__WATCOMC__) +# ifndef PNG_RESTRICT +# define PNG_RESTRICT __restrict +# endif +# endif /* _MSC_VER */ +#endif /* PNG_PEDANTIC_WARNINGS */ + +#ifndef PNG_DEPRECATED +# define PNG_DEPRECATED /* Use of this function is deprecated */ +#endif +#ifndef PNG_USE_RESULT +# define PNG_USE_RESULT /* The result of this function must be checked */ +#endif +#ifndef PNG_NORETURN +# define PNG_NORETURN /* This function does not return */ +#endif +#ifndef PNG_ALLOCATED +# define PNG_ALLOCATED /* The result of the function is new memory */ +#endif +#ifndef PNG_PRIVATE +# define PNG_PRIVATE /* This is a private libpng function */ +#endif +#ifndef PNG_RESTRICT +# define PNG_RESTRICT /* The C99 "restrict" feature */ +#endif +#ifndef PNG_FP_EXPORT /* A floating point API. */ +# ifdef PNG_FLOATING_POINT_SUPPORTED +# define PNG_FP_EXPORT(ordinal, type, name, args)\ + PNG_EXPORT(ordinal, type, name, args); +# else /* No floating point APIs */ +# define PNG_FP_EXPORT(ordinal, type, name, args) +# endif +#endif +#ifndef PNG_FIXED_EXPORT /* A fixed point API. */ +# ifdef PNG_FIXED_POINT_SUPPORTED +# define PNG_FIXED_EXPORT(ordinal, type, name, args)\ + PNG_EXPORT(ordinal, type, name, args); +# else /* No fixed point APIs */ +# define PNG_FIXED_EXPORT(ordinal, type, name, args) +# endif +#endif + +#ifndef PNG_BUILDING_SYMBOL_TABLE +/* Some typedefs to get us started. These should be safe on most of the common + * platforms. + * + * png_uint_32 and png_int_32 may, currently, be larger than required to hold a + * 32-bit value however this is not normally advisable. + * + * png_uint_16 and png_int_16 should always be two bytes in size - this is + * verified at library build time. + * + * png_byte must always be one byte in size. + * + * The checks below use constants from limits.h, as defined by the ISOC90 + * standard. + */ +#if CHAR_BIT == 8 && UCHAR_MAX == 255 + typedef unsigned char png_byte; +#else +# error "libpng requires 8 bit bytes" +#endif + +#if INT_MIN == -32768 && INT_MAX == 32767 + typedef int png_int_16; +#elif SHRT_MIN == -32768 && SHRT_MAX == 32767 + typedef short png_int_16; +#else +# error "libpng requires a signed 16 bit type" +#endif + +#if UINT_MAX == 65535 + typedef unsigned int png_uint_16; +#elif USHRT_MAX == 65535 + typedef unsigned short png_uint_16; +#else +# error "libpng requires an unsigned 16 bit type" +#endif + +#if INT_MIN < -2147483646 && INT_MAX > 2147483646 + typedef int png_int_32; +#elif LONG_MIN < -2147483646 && LONG_MAX > 2147483646 + typedef long int png_int_32; +#else +# error "libpng requires a signed 32 bit (or more) type" +#endif + +#if UINT_MAX > 4294967294 + typedef unsigned int png_uint_32; +#elif ULONG_MAX > 4294967294 + typedef unsigned long int png_uint_32; +#else +# error "libpng requires an unsigned 32 bit (or more) type" +#endif + +/* Prior to 1.6.0 it was possible to disable the use of size_t, 1.6.0, however, + * requires an ISOC90 compiler and relies on consistent behavior of sizeof. + */ +typedef size_t png_size_t; +typedef ptrdiff_t png_ptrdiff_t; + +/* libpng needs to know the maximum value of 'size_t' and this controls the + * definition of png_alloc_size_t, below. This maximum value of size_t limits + * but does not control the maximum allocations the library makes - there is + * direct application control of this through png_set_user_limits(). + */ +#ifndef PNG_SMALL_SIZE_T + /* Compiler specific tests for systems where size_t is known to be less than + * 32 bits (some of these systems may no longer work because of the lack of + * 'far' support; see above.) + */ +# if (defined(__TURBOC__) && !defined(__FLAT__)) ||\ + (defined(_MSC_VER) && defined(MAXSEG_64K)) +# define PNG_SMALL_SIZE_T +# endif +#endif + +/* png_alloc_size_t is guaranteed to be no smaller than png_size_t, and no + * smaller than png_uint_32. Casts from png_size_t or png_uint_32 to + * png_alloc_size_t are not necessary; in fact, it is recommended not to use + * them at all so that the compiler can complain when something turns out to be + * problematic. + * + * Casts in the other direction (from png_alloc_size_t to png_size_t or + * png_uint_32) should be explicitly applied; however, we do not expect to + * encounter practical situations that require such conversions. + * + * PNG_SMALL_SIZE_T must be defined if the maximum value of size_t is less than + * 4294967295 - i.e. less than the maximum value of png_uint_32. + */ +#ifdef PNG_SMALL_SIZE_T + typedef png_uint_32 png_alloc_size_t; +#else + typedef png_size_t png_alloc_size_t; +#endif + +/* Prior to 1.6.0 libpng offered limited support for Microsoft C compiler + * implementations of Intel CPU specific support of user-mode segmented address + * spaces, where 16-bit pointers address more than 65536 bytes of memory using + * separate 'segment' registers. The implementation requires two different + * types of pointer (only one of which includes the segment value.) + * + * If required this support is available in version 1.2 of libpng and may be + * available in versions through 1.5, although the correctness of the code has + * not been verified recently. + */ + +/* Typedef for floating-point numbers that are converted to fixed-point with a + * multiple of 100,000, e.g., gamma + */ +typedef png_int_32 png_fixed_point; + +/* Add typedefs for pointers */ +typedef void * png_voidp; +typedef const void * png_const_voidp; +typedef png_byte * png_bytep; +typedef const png_byte * png_const_bytep; +typedef png_uint_32 * png_uint_32p; +typedef const png_uint_32 * png_const_uint_32p; +typedef png_int_32 * png_int_32p; +typedef const png_int_32 * png_const_int_32p; +typedef png_uint_16 * png_uint_16p; +typedef const png_uint_16 * png_const_uint_16p; +typedef png_int_16 * png_int_16p; +typedef const png_int_16 * png_const_int_16p; +typedef char * png_charp; +typedef const char * png_const_charp; +typedef png_fixed_point * png_fixed_point_p; +typedef const png_fixed_point * png_const_fixed_point_p; +typedef png_size_t * png_size_tp; +typedef const png_size_t * png_const_size_tp; + +#ifdef PNG_STDIO_SUPPORTED +typedef FILE * png_FILE_p; +#endif + +#ifdef PNG_FLOATING_POINT_SUPPORTED +typedef double * png_doublep; +typedef const double * png_const_doublep; +#endif + +/* Pointers to pointers; i.e. arrays */ +typedef png_byte * * png_bytepp; +typedef png_uint_32 * * png_uint_32pp; +typedef png_int_32 * * png_int_32pp; +typedef png_uint_16 * * png_uint_16pp; +typedef png_int_16 * * png_int_16pp; +typedef const char * * png_const_charpp; +typedef char * * png_charpp; +typedef png_fixed_point * * png_fixed_point_pp; +#ifdef PNG_FLOATING_POINT_SUPPORTED +typedef double * * png_doublepp; +#endif + +/* Pointers to pointers to pointers; i.e., pointer to array */ +typedef char * * * png_charppp; + +#endif /* PNG_BUILDING_SYMBOL_TABLE */ + +#endif /* PNGCONF_H */ diff --git a/scalos/include/pnglibconf.h b/scalos/include/pnglibconf.h new file mode 100644 index 000000000..d8e0fc099 --- /dev/null +++ b/scalos/include/pnglibconf.h @@ -0,0 +1,209 @@ +/* pnglibconf.h - library build configuration */ + +/* libpng version 1.6.7 - November 14, 2013 */ + +/* Copyright (c) 1998-2012 Glenn Randers-Pehrson */ + +/* This code is released under the libpng license. */ +/* For conditions of distribution and use, see the disclaimer */ +/* and license in png.h */ + +/* pnglibconf.h */ +/* Machine generated file: DO NOT EDIT */ +/* Derived from: scripts/pnglibconf.dfa */ +#ifndef PNGLCONF_H +#define PNGLCONF_H +/* options */ +#define PNG_16BIT_SUPPORTED +#define PNG_ALIGNED_MEMORY_SUPPORTED +/*#undef PNG_ARM_NEON_API_SUPPORTED*/ +/*#undef PNG_ARM_NEON_CHECK_SUPPORTED*/ +#define PNG_BENIGN_ERRORS_SUPPORTED +#define PNG_BENIGN_READ_ERRORS_SUPPORTED +/*#undef PNG_BENIGN_WRITE_ERRORS_SUPPORTED*/ +#define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED +#define PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED +#define PNG_COLORSPACE_SUPPORTED +#define PNG_CONSOLE_IO_SUPPORTED +#define PNG_CONVERT_tIME_SUPPORTED +#define PNG_EASY_ACCESS_SUPPORTED +/*#undef PNG_ERROR_NUMBERS_SUPPORTED*/ +#define PNG_ERROR_TEXT_SUPPORTED +#define PNG_FIXED_POINT_SUPPORTED +#define PNG_FLOATING_ARITHMETIC_SUPPORTED +#define PNG_FLOATING_POINT_SUPPORTED +#define PNG_FORMAT_AFIRST_SUPPORTED +#define PNG_FORMAT_BGR_SUPPORTED +#define PNG_GAMMA_SUPPORTED +#define PNG_GET_PALETTE_MAX_SUPPORTED +#define PNG_HANDLE_AS_UNKNOWN_SUPPORTED +#define PNG_INCH_CONVERSIONS_SUPPORTED +#define PNG_INFO_IMAGE_SUPPORTED +#define PNG_IO_STATE_SUPPORTED +#define PNG_MNG_FEATURES_SUPPORTED +#define PNG_POINTER_INDEXING_SUPPORTED +#define PNG_PROGRESSIVE_READ_SUPPORTED +#define PNG_READ_16BIT_SUPPORTED +#define PNG_READ_ALPHA_MODE_SUPPORTED +#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED +#define PNG_READ_BACKGROUND_SUPPORTED +#define PNG_READ_BGR_SUPPORTED +#define PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED +#define PNG_READ_COMPOSITE_NODIV_SUPPORTED +#define PNG_READ_COMPRESSED_TEXT_SUPPORTED +#define PNG_READ_EXPAND_16_SUPPORTED +#define PNG_READ_EXPAND_SUPPORTED +#define PNG_READ_FILLER_SUPPORTED +#define PNG_READ_GAMMA_SUPPORTED +#define PNG_READ_GET_PALETTE_MAX_SUPPORTED +#define PNG_READ_GRAY_TO_RGB_SUPPORTED +#define PNG_READ_INTERLACING_SUPPORTED +#define PNG_READ_INT_FUNCTIONS_SUPPORTED +#define PNG_READ_INVERT_ALPHA_SUPPORTED +#define PNG_READ_INVERT_SUPPORTED +#define PNG_READ_OPT_PLTE_SUPPORTED +#define PNG_READ_PACKSWAP_SUPPORTED +#define PNG_READ_PACK_SUPPORTED +#define PNG_READ_QUANTIZE_SUPPORTED +#define PNG_READ_RGB_TO_GRAY_SUPPORTED +#define PNG_READ_SCALE_16_TO_8_SUPPORTED +#define PNG_READ_SHIFT_SUPPORTED +#define PNG_READ_STRIP_16_TO_8_SUPPORTED +#define PNG_READ_STRIP_ALPHA_SUPPORTED +#define PNG_READ_SUPPORTED +#define PNG_READ_SWAP_ALPHA_SUPPORTED +#define PNG_READ_SWAP_SUPPORTED +#define PNG_READ_TEXT_SUPPORTED +#define PNG_READ_TRANSFORMS_SUPPORTED +#define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_READ_USER_CHUNKS_SUPPORTED +#define PNG_READ_USER_TRANSFORM_SUPPORTED +#define PNG_READ_bKGD_SUPPORTED +#define PNG_READ_cHRM_SUPPORTED +#define PNG_READ_gAMA_SUPPORTED +#define PNG_READ_hIST_SUPPORTED +#define PNG_READ_iCCP_SUPPORTED +#define PNG_READ_iTXt_SUPPORTED +#define PNG_READ_oFFs_SUPPORTED +#define PNG_READ_pCAL_SUPPORTED +#define PNG_READ_pHYs_SUPPORTED +#define PNG_READ_sBIT_SUPPORTED +#define PNG_READ_sCAL_SUPPORTED +#define PNG_READ_sPLT_SUPPORTED +#define PNG_READ_sRGB_SUPPORTED +#define PNG_READ_tEXt_SUPPORTED +#define PNG_READ_tIME_SUPPORTED +#define PNG_READ_tRNS_SUPPORTED +#define PNG_READ_zTXt_SUPPORTED +/*#undef PNG_SAFE_LIMITS_SUPPORTED*/ +#define PNG_SAVE_INT_32_SUPPORTED +#define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_SEQUENTIAL_READ_SUPPORTED +#define PNG_SETJMP_SUPPORTED +#define PNG_SET_CHUNK_CACHE_LIMIT_SUPPORTED +#define PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED +#define PNG_SET_OPTION_SUPPORTED +#define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_SET_USER_LIMITS_SUPPORTED +#define PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED +#define PNG_SIMPLIFIED_READ_BGR_SUPPORTED +#define PNG_SIMPLIFIED_READ_SUPPORTED +#define PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED +#define PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED +#define PNG_SIMPLIFIED_WRITE_SUPPORTED +#define PNG_STDIO_SUPPORTED +#define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_TEXT_SUPPORTED +#define PNG_TIME_RFC1123_SUPPORTED +#define PNG_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_USER_CHUNKS_SUPPORTED +#define PNG_USER_LIMITS_SUPPORTED +#define PNG_USER_MEM_SUPPORTED +#define PNG_USER_TRANSFORM_INFO_SUPPORTED +#define PNG_USER_TRANSFORM_PTR_SUPPORTED +#define PNG_WARNINGS_SUPPORTED +#define PNG_WRITE_16BIT_SUPPORTED +#define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED +#define PNG_WRITE_BGR_SUPPORTED +#define PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED +#define PNG_WRITE_COMPRESSED_TEXT_SUPPORTED +#define PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED +#define PNG_WRITE_FILLER_SUPPORTED +#define PNG_WRITE_FILTER_SUPPORTED +#define PNG_WRITE_FLUSH_SUPPORTED +#define PNG_WRITE_GET_PALETTE_MAX_SUPPORTED +#define PNG_WRITE_INTERLACING_SUPPORTED +#define PNG_WRITE_INT_FUNCTIONS_SUPPORTED +#define PNG_WRITE_INVERT_ALPHA_SUPPORTED +#define PNG_WRITE_INVERT_SUPPORTED +#define PNG_WRITE_OPTIMIZE_CMF_SUPPORTED +#define PNG_WRITE_PACKSWAP_SUPPORTED +#define PNG_WRITE_PACK_SUPPORTED +#define PNG_WRITE_SHIFT_SUPPORTED +#define PNG_WRITE_SUPPORTED +#define PNG_WRITE_SWAP_ALPHA_SUPPORTED +#define PNG_WRITE_SWAP_SUPPORTED +#define PNG_WRITE_TEXT_SUPPORTED +#define PNG_WRITE_TRANSFORMS_SUPPORTED +#define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_WRITE_USER_TRANSFORM_SUPPORTED +#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED +#define PNG_WRITE_bKGD_SUPPORTED +#define PNG_WRITE_cHRM_SUPPORTED +#define PNG_WRITE_gAMA_SUPPORTED +#define PNG_WRITE_hIST_SUPPORTED +#define PNG_WRITE_iCCP_SUPPORTED +#define PNG_WRITE_iTXt_SUPPORTED +#define PNG_WRITE_oFFs_SUPPORTED +#define PNG_WRITE_pCAL_SUPPORTED +#define PNG_WRITE_pHYs_SUPPORTED +#define PNG_WRITE_sBIT_SUPPORTED +#define PNG_WRITE_sCAL_SUPPORTED +#define PNG_WRITE_sPLT_SUPPORTED +#define PNG_WRITE_sRGB_SUPPORTED +#define PNG_WRITE_tEXt_SUPPORTED +#define PNG_WRITE_tIME_SUPPORTED +#define PNG_WRITE_tRNS_SUPPORTED +#define PNG_WRITE_zTXt_SUPPORTED +#define PNG_bKGD_SUPPORTED +#define PNG_cHRM_SUPPORTED +#define PNG_gAMA_SUPPORTED +#define PNG_hIST_SUPPORTED +#define PNG_iCCP_SUPPORTED +#define PNG_iTXt_SUPPORTED +#define PNG_oFFs_SUPPORTED +#define PNG_pCAL_SUPPORTED +#define PNG_pHYs_SUPPORTED +#define PNG_sBIT_SUPPORTED +#define PNG_sCAL_SUPPORTED +#define PNG_sPLT_SUPPORTED +#define PNG_sRGB_SUPPORTED +#define PNG_tEXt_SUPPORTED +#define PNG_tIME_SUPPORTED +#define PNG_tRNS_SUPPORTED +#define PNG_zTXt_SUPPORTED +/* end of options */ +/* settings */ +#define PNG_API_RULE 0 +#define PNG_CALLOC_SUPPORTED +#define PNG_COST_SHIFT 3 +#define PNG_DEFAULT_READ_MACROS 1 +#define PNG_GAMMA_THRESHOLD_FIXED 5000 +#define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE +#define PNG_INFLATE_BUF_SIZE 1024 +#define PNG_MAX_GAMMA_8 11 +#define PNG_QUANTIZE_BLUE_BITS 5 +#define PNG_QUANTIZE_GREEN_BITS 5 +#define PNG_QUANTIZE_RED_BITS 5 +#define PNG_TEXT_Z_DEFAULT_COMPRESSION (-1) +#define PNG_TEXT_Z_DEFAULT_STRATEGY 0 +#define PNG_WEIGHT_SHIFT 8 +#define PNG_ZBUF_SIZE 8192 +#define PNG_ZLIB_VERNUM 0x1280 +#define PNG_Z_DEFAULT_COMPRESSION (-1) +#define PNG_Z_DEFAULT_NOFILTER_STRATEGY 0 +#define PNG_Z_DEFAULT_STRATEGY 1 +#define PNG_sCAL_PRECISION 5 +#define PNG_sRGB_PROFILE_CHECKS 2 +/* end of settings */ +#endif /* PNGLCONF_H */ diff --git a/scalos/include/ppcinline/macros.h b/scalos/include/ppcinline/macros.h new file mode 100755 index 000000000..38b947e58 --- /dev/null +++ b/scalos/include/ppcinline/macros.h @@ -0,0 +1,33 @@ +#if !defined(__INLINE_MACROS_H_SCALOS) +#define __INLINE_MACROS_H_SCALOS + +#include_next "ppcinline/macros.h" + +// this definition is missing in SDK macros.h +#define LP8FP(offs, rt, name, t1, v1, r1, t2, v2, r2, t3, v3, r3, t4, v4, r4, t5, v5, r5, t6, v6, r6, t7, v7, r7, t8, v8, r8, bt, bn, fpt, cm1, cs1, cl1, cm2, cs2, cl2 ) \ +({ \ + typedef fpt; \ + t1 _##name##_v1 = v1; \ + t2 _##name##_v2 = v2; \ + t3 _##name##_v3 = v3; \ + t4 _##name##_v4 = v4; \ + t5 _##name##_v5 = v5; \ + t6 _##name##_v6 = v6; \ + t7 _##name##_v7 = v7; \ + t8 _##name##_v8 = v8; \ + rt _##name##_re; \ + REG_##r1 = (ULONG) _##name##_v1; \ + REG_##r2 = (ULONG) _##name##_v2; \ + REG_##r3 = (ULONG) _##name##_v3; \ + REG_##r4 = (ULONG) _##name##_v4; \ + REG_##r5 = (ULONG) _##name##_v5; \ + REG_##r6 = (ULONG) _##name##_v6; \ + REG_##r7 = (ULONG) _##name##_v7; \ + REG_##r8 = (ULONG) _##name##_v8; \ + REG_A6 = (ULONG) (bn); \ + _##name##_re = (rt) (*MyEmulHandle->EmulCallDirectOS)(-offs);\ + _##name##_re; \ +}) + +#endif //!defined(__INLINE_MACROS_H_SCALOS) + diff --git a/scalos/include/ppcinline/openurl.h b/scalos/include/ppcinline/openurl.h new file mode 100755 index 000000000..31852f2e9 --- /dev/null +++ b/scalos/include/ppcinline/openurl.h @@ -0,0 +1,89 @@ +#ifndef _PPCINLINE_OPENURL_H +#define _PPCINLINE_OPENURL_H + +#ifndef CLIB_OPENURL_PROTOS_H +#define CLIB_OPENURL_PROTOS_H +#endif + +#ifndef __PPCINLINE_MACROS_H +#include +#endif + +#ifndef EXEC_TYPES_H +#include +#endif + +#ifndef OPENURL_BASE_NAME +#define OPENURL_BASE_NAME OpenURLBase +#endif + +#define URL_OpenA(url, tags) \ + LP2(0x1e, ULONG, URL_OpenA, STRPTR, url, a0, struct TagItem *, tags, a1, \ + , OPENURL_BASE_NAME, IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0) + +#ifndef NO_PPCINLINE_STDARG +#define URL_Open(url, tags...) \ + ({ULONG _tags[] = {tags}; URL_OpenA((url), (struct TagItem *) _tags);}) +#endif + +#define URL_OldGetPrefs() \ + LP0(0x24, struct URL_Prefs *, URL_OldGetPrefs, \ + , OPENURL_BASE_NAME, IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0) + +#define URL_OldFreePrefs(up) \ + LP1NR(0x2a, URL_OldFreePrefs, struct URL_Prefs *, up, a0, \ + , OPENURL_BASE_NAME, IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0) + +#define URL_OldSetPrefs(up, permanent) \ + LP2(0x30, ULONG, URL_OldSetPrefs, struct URL_Prefs *, up, a0, LONG, permanent, d0, \ + , OPENURL_BASE_NAME, IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0) + +#define URL_OldGetDefaultPrefs() \ + LP0(0x36, struct URL_Prefs *, URL_OldGetDefaultPrefs, \ + , OPENURL_BASE_NAME, IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0) + +#define URL_OldLaunchPrefsApp() \ + LP0(0x3c, ULONG, URL_OldLaunchPrefsApp, \ + , OPENURL_BASE_NAME, IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0) + +#define URL_GetPrefsA(tags) \ + LP1(0x48, struct URL_Prefs *, URL_GetPrefsA, struct TagItem *, tags, a0, \ + , OPENURL_BASE_NAME, IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0) + +#ifndef NO_PPCINLINE_STDARG +#define URL_GetPrefs(tags...) \ + ({ULONG _tags[] = {tags}; URL_GetPrefsA((struct TagItem *) _tags);}) +#endif + +#define URL_FreePrefsA(prefs, tags) \ + LP2NR(0x4e, URL_FreePrefsA, struct URL_Prefs *, prefs, a0, struct TagItem *, tags, a1, \ + , OPENURL_BASE_NAME, IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0) + +#ifndef NO_PPCINLINE_STDARG +#define URL_FreePrefs(prefs, tags...) \ + ({ULONG _tags[] = {tags}; URL_FreePrefsA((prefs), (struct TagItem *) _tags);}) +#endif + +#define URL_SetPrefsA(up, tags) \ + LP2(0x54, ULONG, URL_SetPrefsA, struct URL_Prefs *, up, a0, struct TagItem *, tags, a1, \ + , OPENURL_BASE_NAME, IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0) + +#ifndef NO_PPCINLINE_STDARG +#define URL_SetPrefs(up, tags...) \ + ({ULONG _tags[] = {tags}; URL_SetPrefsA((up), (struct TagItem *) _tags);}) +#endif + +#define URL_LaunchPrefsAppA(tags) \ + LP1(0x5a, ULONG, URL_LaunchPrefsAppA, struct TagItem *, tags, a0, \ + , OPENURL_BASE_NAME, IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0) + +#ifndef NO_PPCINLINE_STDARG +#define URL_LaunchPrefsApp(tags...) \ + ({ULONG _tags[] = {tags}; URL_LaunchPrefsAppA((struct TagItem *) _tags);}) +#endif + +#define URL_GetAttr(attr, storage) \ + LP2(0x60, ULONG, URL_GetAttr, ULONG, attr, d0, ULONG *, storage, a0, \ + , OPENURL_BASE_NAME, IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0) + +#endif /* _PPCINLINE_OPENURL_H */ diff --git a/scalos/include/ppcinline/ttengine.h b/scalos/include/ppcinline/ttengine.h new file mode 100644 index 000000000..081fbae41 --- /dev/null +++ b/scalos/include/ppcinline/ttengine.h @@ -0,0 +1,149 @@ +/* Automatically generated header! Do not edit! */ + +#ifndef _PPCINLINE_TTENGINE_H +#define _PPCINLINE_TTENGINE_H + +#ifndef __PPCINLINE_MACROS_H +#include +#endif /* !__PPCINLINE_MACROS_H */ + +#ifndef TTENGINE_BASE_NAME +#define TTENGINE_BASE_NAME TTEngineBase +#endif /* !TTENGINE_BASE_NAME */ + +#define TT_SetAttrsA(__p0, __p1) \ + LP2(54, ULONG , TT_SetAttrsA, \ + struct RastPort *, __p0, a1, \ + struct TagItem *, __p1, a0, \ + , TTENGINE_BASE_NAME, 0, 0, 0, 0, 0, 0) + +#define TT_ObtainFamilyListA(__p0) \ + LP1(120, STRPTR *, TT_ObtainFamilyListA, \ + struct TagItem *, __p0, a0, \ + , TTENGINE_BASE_NAME, 0, 0, 0, 0, 0, 0) + +#define TT_TextExtent(__p0, __p1, __p2, __p3) \ + LP4NR(72, TT_TextExtent, \ + struct RastPort *, __p0, a1, \ + APTR , __p1, a0, \ + WORD , __p2, d0, \ + struct TextExtent *, __p3, a2, \ + , TTENGINE_BASE_NAME, 0, 0, 0, 0, 0, 0) + +#define TT_FreeFamilyList(__p0) \ + LP1NR(126, TT_FreeFamilyList, \ + STRPTR *, __p0, a0, \ + , TTENGINE_BASE_NAME, 0, 0, 0, 0, 0, 0) + +#define TT_SetFont(__p0, __p1) \ + LP2(36, BOOL , TT_SetFont, \ + struct RastPort *, __p0, a1, \ + APTR , __p1, a0, \ + , TTENGINE_BASE_NAME, 0, 0, 0, 0, 0, 0) + +#define TT_DoneRastPort(__p0) \ + LP1NR(96, TT_DoneRastPort, \ + struct RastPort *, __p0, a1, \ + , TTENGINE_BASE_NAME, 0, 0, 0, 0, 0, 0) + +#define TT_Text(__p0, __p1, __p2) \ + LP3NR(48, TT_Text, \ + struct RastPort *, __p0, a1, \ + APTR , __p1, a0, \ + ULONG , __p2, d0, \ + , TTENGINE_BASE_NAME, 0, 0, 0, 0, 0, 0) + +#define TT_TextLength(__p0, __p1, __p2) \ + LP3(66, ULONG , TT_TextLength, \ + struct RastPort *, __p0, a1, \ + APTR , __p1, a0, \ + ULONG , __p2, d0, \ + , TTENGINE_BASE_NAME, 0, 0, 0, 0, 0, 0) + +#define TT_TextFit(__p0, __p1, __p2, __p3, __p4, __p5, __p6, __p7) \ + LP8(78, ULONG , TT_TextFit, \ + struct RastPort *, __p0, a1, \ + APTR , __p1, a0, \ + UWORD , __p2, d0, \ + struct TextExtent *, __p3, a2, \ + struct TextExtent *, __p4, a3, \ + WORD , __p5, d1, \ + UWORD , __p6, d2, \ + UWORD , __p7, d3, \ + , TTENGINE_BASE_NAME, 0, 0, 0, 0, 0, 0) + +#define TT_RequestA(__p0, __p1) \ + LP2(108, struct TagItem *, TT_RequestA, \ + APTR , __p0, a0, \ + struct TagItem *, __p1, a1, \ + , TTENGINE_BASE_NAME, 0, 0, 0, 0, 0, 0) + +#define TT_OpenFontA(__p0) \ + LP1(30, APTR , TT_OpenFontA, \ + struct TagItem *, __p0, a0, \ + , TTENGINE_BASE_NAME, 0, 0, 0, 0, 0, 0) + +#define TT_FreeRequest(__p0) \ + LP1NR(114, TT_FreeRequest, \ + APTR , __p0, a0, \ + , TTENGINE_BASE_NAME, 0, 0, 0, 0, 0, 0) + +#define TT_CloseFont(__p0) \ + LP1NR(42, TT_CloseFont, \ + APTR , __p0, a0, \ + , TTENGINE_BASE_NAME, 0, 0, 0, 0, 0, 0) + +#define TT_GetAttrsA(__p0, __p1) \ + LP2(60, ULONG , TT_GetAttrsA, \ + struct RastPort *, __p0, a1, \ + struct TagItem *, __p1, a0, \ + , TTENGINE_BASE_NAME, 0, 0, 0, 0, 0, 0) + +#define TT_GetPixmapA(__p0, __p1, __p2, __p3) \ + LP4(84, struct TT_Pixmap *, TT_GetPixmapA, \ + APTR , __p0, a1, \ + APTR , __p1, a2, \ + ULONG , __p2, d0, \ + struct TagItem *, __p3, a0, \ + , TTENGINE_BASE_NAME, 0, 0, 0, 0, 0, 0) + +#define TT_FreePixmap(__p0) \ + LP1NR(90, TT_FreePixmap, \ + struct TT_Pixmap *, __p0, a0, \ + , TTENGINE_BASE_NAME, 0, 0, 0, 0, 0, 0) + +#define TT_AllocRequest() \ + LP0(102, APTR , TT_AllocRequest, \ + , TTENGINE_BASE_NAME, 0, 0, 0, 0, 0, 0) + +#ifdef USE_INLINE_STDARG + +#include + +#define TT_SetAttrs(__p0, ...) \ + ({ULONG _tags[] = { __VA_ARGS__ }; \ + TT_SetAttrsA(__p0, (struct TagItem *)_tags);}) + +#define TT_ObtainFamilyList(...) \ + ({ULONG _tags[] = { __VA_ARGS__ }; \ + TT_ObtainFamilyListA((struct TagItem *)_tags);}) + +#define TT_Request(__p0, ...) \ + ({ULONG _tags[] = { __VA_ARGS__ }; \ + TT_RequestA(__p0, (struct TagItem *)_tags);}) + +#define TT_OpenFont(...) \ + ({ULONG _tags[] = { __VA_ARGS__ }; \ + TT_OpenFontA((struct TagItem *)_tags);}) + +#define TT_GetAttrs(__p0, ...) \ + ({ULONG _tags[] = { __VA_ARGS__ }; \ + TT_GetAttrsA(__p0, (struct TagItem *)_tags);}) + +#define TT_GetPixmap(__p0, __p1, __p2, ...) \ + ({ULONG _tags[] = { __VA_ARGS__ }; \ + TT_GetPixmapA(__p0, __p1, __p2, (struct TagItem *)_tags);}) + +#endif + +#endif /* !_PPCINLINE_TTENGINE_H */ diff --git a/scalos/include/pragmas/alib_stdio_pragmas.h b/scalos/include/pragmas/alib_stdio_pragmas.h new file mode 100755 index 000000000..e259ae10c --- /dev/null +++ b/scalos/include/pragmas/alib_stdio_pragmas.h @@ -0,0 +1,30 @@ +#ifndef PRAGMAS_ALIB_STDIO_PRAGMAS_H +#define PRAGMAS_ALIB_STDIO_PRAGMAS_H + +#if defined(LATTICE) || defined(__SASC) || defined(_DCC) +#ifndef __CLIB_PRAGMA_LIBCALL +#define __CLIB_PRAGMA_LIBCALL +#endif /* __CLIB_PRAGMA_LIBCALL */ +#else /* __MAXON__, __STORM__ or AZTEC_C */ +#ifndef __CLIB_PRAGMA_AMICALL +#define __CLIB_PRAGMA_AMICALL +#endif /* __CLIB_PRAGMA_AMICALL */ +#endif /* */ + +#if defined(__SASC) || defined(__STORM__) +#ifndef __CLIB_PRAGMA_TAGCALL +#define __CLIB_PRAGMA_TAGCALL +#endif /* __CLIB_PRAGMA_TAGCALL */ +#endif /* __MAXON__, __STORM__ or AZTEC_C */ + +#ifdef __CLIB_PRAGMA_LIBCALL +#pragma libcall None fclose 1E 001 +#pragma libcall None fgetc 24 001 +#pragma libcall None fputc 2A 1002 +#pragma libcall None fputs 30 0802 +#pragma libcall None getchar 36 0 +#pragma libcall None putchar 3C 001 +#pragma libcall None puts 42 801 +#endif /* __CLIB_PRAGMA_LIBCALL */ + +#endif /* PRAGMAS_ALIB_STDIO_PRAGMAS_H */ diff --git a/scalos/include/pragmas/cybergraphics_pragmas.h b/scalos/include/pragmas/cybergraphics_pragmas.h new file mode 100755 index 000000000..60777ff36 --- /dev/null +++ b/scalos/include/pragmas/cybergraphics_pragmas.h @@ -0,0 +1,47 @@ +#ifndef PRAGMAS_CYBERGRAPHICS_PRAGMAS_H +#define PRAGMAS_CYBERGRAPHICS_PRAGMAS_H + +#ifndef CLIB_CYBERGRAPHICS_PROTOS_H +#include +#endif + +#pragma libcall CyberGfxBase IsCyberModeID 036 001 +#pragma libcall CyberGfxBase BestCModeIDTagList 03c 801 +#pragma libcall CyberGfxBase CModeRequestTagList 042 9802 +#pragma libcall CyberGfxBase AllocCModeListTagList 048 901 +#pragma libcall CyberGfxBase FreeCModeList 04e 801 +#pragma libcall CyberGfxBase ScalePixelArray 05a 76543921080a +#pragma libcall CyberGfxBase GetCyberMapAttr 060 0802 +#pragma libcall CyberGfxBase GetCyberIDAttr 066 1002 +#pragma libcall CyberGfxBase ReadRGBPixel 06c 10903 +#pragma libcall CyberGfxBase WriteRGBPixel 072 210904 +#pragma libcall CyberGfxBase ReadPixelArray 078 76543921080a +#pragma libcall CyberGfxBase WritePixelArray 07e 76543921080a +#pragma libcall CyberGfxBase MovePixelArray 084 543291007 +#pragma libcall CyberGfxBase InvertPixelArray 090 3210905 +#pragma libcall CyberGfxBase FillPixelArray 096 43210906 +#pragma libcall CyberGfxBase DoCDrawMethodTagList 09c a9803 +#pragma libcall CyberGfxBase CVideoCtrlTagList 0a2 9802 +#pragma libcall CyberGfxBase LockBitMapTagList 0a8 9802 +#pragma libcall CyberGfxBase UnLockBitMap 0ae 801 +#pragma libcall CyberGfxBase UnLockBitMapTagList 0b4 9802 +#pragma libcall CyberGfxBase ExtractColor 0ba 432109807 +#pragma libcall CyberGfxBase WriteLUTPixelArray 0c6 76543a921080b +#pragma libcall CyberGfxBase WritePixelArrayAlpha 0d8 76543921080a +#pragma libcall CyberGfxBase BltTemplateAlpha 0de 5432910808 +#pragma libcall CyberGfxBase ProcessPixelArray 0e4 a543210908 +#pragma libcall CyberGfxBase BltBitMapAlpha 0ea a5432910809 +#pragma libcall CyberGfxBase BltBitMapRastPortAlpha 0f0 a5432910809 +#pragma libcall CyberGfxBase ScalePixelArrayAlpha 102 76543921080a +#ifdef __SASC_60 +#pragma tagcall CyberGfxBase BestCModeIDTags 03c 801 +#pragma tagcall CyberGfxBase CModeRequestTags 042 9802 +#pragma tagcall CyberGfxBase AllocCModeListTags 048 901 +#pragma tagcall CyberGfxBase DoCDrawMethodTags 09c a9803 +#pragma tagcall CyberGfxBase CVideoCtrlTags 0a2 9802 +#pragma tagcall CyberGfxBase LockBitMapTags 0a8 9802 +#pragma tagcall CyberGfxBase UnLockBitMapTags 0b4 9802 +#pragma tagcall CyberGfxBase ProcessPixelArrayTags 0e4 a543210908 +#endif + +#endif /* PRAGMAS_CYBERGRAPHICS_PRAGMA_H */ diff --git a/scalos/include/pragmas/dtlib_pragmas.h b/scalos/include/pragmas/dtlib_pragmas.h new file mode 100755 index 000000000..0a5e49316 --- /dev/null +++ b/scalos/include/pragmas/dtlib_pragmas.h @@ -0,0 +1,37 @@ +#ifndef PRAGMAS_DTLIB_PRAGMAS_H +#define PRAGMAS_DTLIB_PRAGMAS_H + +/* +** $Id$ +** +** Direct ROM interface (pragma) definitions. +** +** ©1999-2005 The Scalos Team +** All Rights Reserved +*/ + +#if defined(LATTICE) || defined(__SASC) || defined(_DCC) +#ifndef __CLIB_PRAGMA_LIBCALL +#define __CLIB_PRAGMA_LIBCALL +#endif /* __CLIB_PRAGMA_LIBCALL */ +#else /* __MAXON__, __STORM__ or AZTEC_C */ +#ifndef __CLIB_PRAGMA_AMICALL +#define __CLIB_PRAGMA_AMICALL +#endif /* __CLIB_PRAGMA_AMICALL */ +#endif /* */ + +#if defined(__SASC) || defined(__STORM__) +#ifndef __CLIB_PRAGMA_TAGCALL +#define __CLIB_PRAGMA_TAGCALL +#endif /* __CLIB_PRAGMA_TAGCALL */ +#endif /* __MAXON__, __STORM__ or AZTEC_C */ + +#ifndef CLIB_DTLIB_PROTOS_H +#include +#endif /* CLIB_DTLIB_PROTOS_H */ + +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall DtLibBase ObtainInfoEngine 1e 801 +#endif /* __CLIB_PRAGMA_LIBCALL */ + +#endif /* PRAGMAS_DTLIB_PRAGMAS_H */ diff --git a/scalos/include/pragmas/guigfx_pragmas.h b/scalos/include/pragmas/guigfx_pragmas.h new file mode 100755 index 000000000..46fb9aef4 --- /dev/null +++ b/scalos/include/pragmas/guigfx_pragmas.h @@ -0,0 +1,57 @@ +#ifndef PRAGMAS_GUIGFX_PRAGMAS_H +#define PRAGMAS_GUIGFX_PRAGMAS_H + +#ifndef CLIB_GUIGFX_PROTOS_H +#include +#endif + +#pragma libcall GuiGFXBase MakePictureA 01e 910804 +#pragma libcall GuiGFXBase LoadPictureA 024 9802 +#pragma libcall GuiGFXBase ReadPictureA 02a a32109807 +#pragma libcall GuiGFXBase ClonePictureA 030 9802 +#pragma libcall GuiGFXBase DeletePicture 036 801 +#pragma libcall GuiGFXBase AddPictureA 042 a9803 +#pragma libcall GuiGFXBase AddPaletteA 048 a9803 +#pragma libcall GuiGFXBase AddPixelArrayA 04e a109805 +#pragma libcall GuiGFXBase RemColorHandle 054 801 +#pragma libcall GuiGFXBase CreatePenShareMapA 05a 801 +#pragma libcall GuiGFXBase DeletePenShareMap 060 801 +#pragma libcall GuiGFXBase ObtainDrawHandleA 066 ba9804 +#pragma libcall GuiGFXBase ReleaseDrawHandle 06c 801 +#pragma libcall GuiGFXBase DrawPictureA 072 a109805 +#pragma libcall GuiGFXBase MapPaletteA 078 ba9804 +#pragma libcall GuiGFXBase MapPenA 07e a9803 +#pragma libcall GuiGFXBase CreatePictureBitMapA 084 a9803 +#pragma libcall GuiGFXBase DoPictureMethodA 08a 90803 +#pragma libcall GuiGFXBase GetPictureAttrsA 090 9802 +#pragma libcall GuiGFXBase LockPictureA 096 90803 +#pragma libcall GuiGFXBase UnLockPicture 09c 0802 +#pragma libcall GuiGFXBase IsPictureA 0a2 9802 +#pragma libcall GuiGFXBase CreateDirectDrawHandleA 0a8 93210806 +#pragma libcall GuiGFXBase DeleteDirectDrawHandle 0ae 801 +#pragma libcall GuiGFXBase DirectDrawTrueColorA 0b4 a109805 +#pragma libcall GuiGFXBase CreatePictureMaskA 0ba a09804 +#ifdef __SASC_60 +#pragma tagcall GuiGFXBase MakePicture 01e 910804 +#pragma tagcall GuiGFXBase LoadPicture 024 9802 +#pragma tagcall GuiGFXBase ReadPicture 02a a32109807 +#pragma tagcall GuiGFXBase ClonePicture 030 9802 +#pragma tagcall GuiGFXBase AddPicture 042 a9803 +#pragma tagcall GuiGFXBase AddPalette 048 a9803 +#pragma tagcall GuiGFXBase AddPixelArray 04e a109805 +#pragma tagcall GuiGFXBase CreatePenShareMap 05a 801 +#pragma tagcall GuiGFXBase ObtainDrawHandle 066 ba9804 +#pragma tagcall GuiGFXBase DrawPicture 072 a109805 +#pragma tagcall GuiGFXBase MapPalette 078 ba9804 +#pragma tagcall GuiGFXBase MapPen 07e a9803 +#pragma tagcall GuiGFXBase CreatePictureBitMap 084 a9803 +#pragma tagcall GuiGFXBase DoPictureMethod 08a 90803 +#pragma tagcall GuiGFXBase GetPictureAttrs 090 9802 +#pragma tagcall GuiGFXBase LockPicture 096 90803 +#pragma tagcall GuiGFXBase IsPicture 0a2 9802 +#pragma tagcall GuiGFXBase CreateDirectDrawHandle 0a8 93210806 +#pragma tagcall GuiGFXBase DirectDrawTrueColor 0b4 a109805 +#pragma tagcall GuiGFXBase CreatePictureMask 0ba a09804 +#endif + +#endif /* PRAGMAS_GUIGFX_PRAGMA_H */ diff --git a/scalos/include/pragmas/iconobject_pragmas.h b/scalos/include/pragmas/iconobject_pragmas.h new file mode 100755 index 000000000..c818bb313 --- /dev/null +++ b/scalos/include/pragmas/iconobject_pragmas.h @@ -0,0 +1,87 @@ +#ifndef PRAGMAS_ICONOBJECT_PRAGMAS_H +#define PRAGMAS_ICONOBJECT_PRAGMAS_H + +/* +** $Id$ +** +** Direct ROM interface (pragma) definitions. +** +** ©1999-2002 The Scalos Team +** All Rights Reserved +*/ + +#if defined(LATTICE) || defined(__SASC) || defined(_DCC) +#ifndef __CLIB_PRAGMA_LIBCALL +#define __CLIB_PRAGMA_LIBCALL +#endif /* __CLIB_PRAGMA_LIBCALL */ +#else /* __MAXON__, __STORM__ or AZTEC_C */ +#ifndef __CLIB_PRAGMA_AMICALL +#define __CLIB_PRAGMA_AMICALL +#endif /* __CLIB_PRAGMA_AMICALL */ +#endif /* */ + +#if defined(__SASC) || defined(__STORM__) +#ifndef __CLIB_PRAGMA_TAGCALL +#define __CLIB_PRAGMA_TAGCALL +#endif /* __CLIB_PRAGMA_TAGCALL */ +#endif /* __MAXON__, __STORM__ or AZTEC_C */ + +#ifndef CLIB_ICONOBJECT_PROTOS_H +#include +#endif /* CLIB_ICONOBJECT_PROTOS_H */ + +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall IconobjectBase NewIconObject 1e 9802 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_TAGCALL + #ifdef __CLIB_PRAGMA_LIBCALL + #pragma tagcall IconobjectBase NewIconObjectTags 1e 9802 + #endif /* __CLIB_PRAGMA_LIBCALL */ + #ifdef __CLIB_PRAGMA_AMICALL + #pragma tagcall(IconobjectBase, 0x1e, NewIconObjectTags(a0,a1)) + #endif /* __CLIB_PRAGMA_AMICALL */ +#endif /* __CLIB_PRAGMA_TAGCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall IconobjectBase DisposeIconObject 24 801 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall IconobjectBase GetDefIconObject 2a 8002 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_TAGCALL + #ifdef __CLIB_PRAGMA_LIBCALL + #pragma tagcall IconobjectBase GetDefIconObjectTags 2a 8002 + #endif /* __CLIB_PRAGMA_LIBCALL */ + #ifdef __CLIB_PRAGMA_AMICALL + #pragma tagcall(IconobjectBase, 0x2a, GetDefIconObjectTags(d0,a0)) + #endif /* __CLIB_PRAGMA_AMICALL */ +#endif /* __CLIB_PRAGMA_TAGCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall IconobjectBase PutIconObject 30 A9803 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_TAGCALL + #ifdef __CLIB_PRAGMA_LIBCALL + #pragma tagcall IconobjectBase PutIconObjectTags 30 A9803 + #endif /* __CLIB_PRAGMA_LIBCALL */ + #ifdef __CLIB_PRAGMA_AMICALL + #pragma tagcall(IconobjectBase, 0x30, PutIconObjectTags(a0,a1,a2)) + #endif /* __CLIB_PRAGMA_AMICALL */ +#endif /* __CLIB_PRAGMA_TAGCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall IconobjectBase IsIconName 36 801 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall IconobjectBase Convert2IconObject 3c 801 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall IconobjectBase Convert2IconObjectA 42 9802 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_TAGCALL + #ifdef __CLIB_PRAGMA_LIBCALL + #pragma tagcall IconobjectBase Convert2IconObjectTags 42 9802 + #endif /* __CLIB_PRAGMA_LIBCALL */ + #ifdef __CLIB_PRAGMA_AMICALL + #pragma tagcall(IconobjectBase, 0x42, Convert2IconObjectTags(a0,a1)) + #endif /* __CLIB_PRAGMA_AMICALL */ +#endif /* __CLIB_PRAGMA_TAGCALL */ + +#endif /* PRAGMAS_ICONOBJECT_PRAGMAS_H */ diff --git a/scalos/include/pragmas/mcpgfx_pragmas.h b/scalos/include/pragmas/mcpgfx_pragmas.h new file mode 100755 index 000000000..3064b02d1 --- /dev/null +++ b/scalos/include/pragmas/mcpgfx_pragmas.h @@ -0,0 +1,76 @@ +#ifndef PRAGMAS_MCPGFX_PRAGMAS_H +#define PRAGMAS_MCPGFX_PRAGMAS_H + +/* +** $Id$ +** +** Direct ROM interface (pragma) definitions. +** +** Copyright © 2001 Amiga, Inc. +** All Rights Reserved +*/ + +#if defined(LATTICE) || defined(__SASC) || defined(_DCC) +#ifndef __CLIB_PRAGMA_LIBCALL +#define __CLIB_PRAGMA_LIBCALL +#endif /* __CLIB_PRAGMA_LIBCALL */ +#else /* __MAXON__, __STORM__ or AZTEC_C */ +#ifndef __CLIB_PRAGMA_AMICALL +#define __CLIB_PRAGMA_AMICALL +#endif /* __CLIB_PRAGMA_AMICALL */ +#endif /* */ + +#if defined(__SASC) || defined(__STORM__) +#ifndef __CLIB_PRAGMA_TAGCALL +#define __CLIB_PRAGMA_TAGCALL +#endif /* __CLIB_PRAGMA_TAGCALL */ +#endif /* __MAXON__, __STORM__ or AZTEC_C */ + +#ifndef CLIB_MCPGFX_PROTOS_H +#include +#endif /* CLIB_MCPGFX_PROTOS_H */ + +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall MCPGfxBase mcpPaintSysIGad 1e 2109805 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall MCPGfxBase mcpRectFillA 24 93210806 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_TAGCALL + #ifdef __CLIB_PRAGMA_LIBCALL + #pragma tagcall MCPGfxBase mcpRectFill 24 93210806 + #endif /* __CLIB_PRAGMA_LIBCALL */ + #ifdef __CLIB_PRAGMA_AMICALL + #pragma tagcall(MCPGfxBase, 0x24, mcpRectFill(a0,d0,d1,d2,d3,a1)) + #endif /* __CLIB_PRAGMA_AMICALL */ +#endif /* __CLIB_PRAGMA_TAGCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall MCPGfxBase mcpDrawFrameA 2a 93210806 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_TAGCALL + #ifdef __CLIB_PRAGMA_LIBCALL + #pragma tagcall MCPGfxBase mcpDrawFrame 2a 93210806 + #endif /* __CLIB_PRAGMA_LIBCALL */ + #ifdef __CLIB_PRAGMA_AMICALL + #pragma tagcall(MCPGfxBase, 0x2a, mcpDrawFrame(a0,d0,d1,d2,d3,a1)) + #endif /* __CLIB_PRAGMA_AMICALL */ +#endif /* __CLIB_PRAGMA_TAGCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall MCPGfxBase mcpGetExtDrawInfo 30 9802 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall MCPGfxBase mcpGetFrameSize 36 0802 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall MCPGfxBase mcpSetGFXAttrsA 3c 801 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_TAGCALL + #ifdef __CLIB_PRAGMA_LIBCALL + #pragma tagcall MCPGfxBase mcpSetGFXAttrs 3c 801 + #endif /* __CLIB_PRAGMA_LIBCALL */ + #ifdef __CLIB_PRAGMA_AMICALL + #pragma tagcall(MCPGfxBase, 0x3c, mcpSetGFXAttrs(a0)) + #endif /* __CLIB_PRAGMA_AMICALL */ +#endif /* __CLIB_PRAGMA_TAGCALL */ + +#endif /* PRAGMAS_MCPGFX_PRAGMAS_H */ diff --git a/scalos/include/pragmas/newicon_pragmas.h b/scalos/include/pragmas/newicon_pragmas.h new file mode 100755 index 000000000..91072aa61 --- /dev/null +++ b/scalos/include/pragmas/newicon_pragmas.h @@ -0,0 +1,61 @@ +#ifndef PRAGMAS_NEWICON_PRAGMAS_H +#define PRAGMAS_NEWICON_PRAGMAS_H + +/* +** $Id$ +** +** Direct ROM interface (pragma) definitions. +** +** Copyright © 2001 Amiga, Inc. +** All Rights Reserved +*/ + +#if defined(LATTICE) || defined(__SASC) || defined(_DCC) +#ifndef __CLIB_PRAGMA_LIBCALL +#define __CLIB_PRAGMA_LIBCALL +#endif /* __CLIB_PRAGMA_LIBCALL */ +#else /* __MAXON__, __STORM__ or AZTEC_C */ +#ifndef __CLIB_PRAGMA_AMICALL +#define __CLIB_PRAGMA_AMICALL +#endif /* __CLIB_PRAGMA_AMICALL */ +#endif /* */ + +#if defined(__SASC) || defined(__STORM__) +#ifndef __CLIB_PRAGMA_TAGCALL +#define __CLIB_PRAGMA_TAGCALL +#endif /* __CLIB_PRAGMA_TAGCALL */ +#endif /* __MAXON__, __STORM__ or AZTEC_C */ + +#ifndef CLIB_NEWICON_PROTOS_H +#include +#endif /* CLIB_NEWICON_PROTOS_H */ + +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall NewIconBase GetNewDiskObject 1e 801 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall NewIconBase PutNewDiskObject 24 9802 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall NewIconBase FreeNewDiskObject 2a 801 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall NewIconBase newiconPrivate1 30 801 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall NewIconBase newiconPrivate2 36 801 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall NewIconBase newiconPrivate3 3c 801 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall NewIconBase RemapChunkyImage 42 9802 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall NewIconBase FreeRemappedImage 48 9802 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall NewIconBase GetDefNewDiskObject 4e 001 +#endif /* __CLIB_PRAGMA_LIBCALL */ + +#endif /* PRAGMAS_NEWICON_PRAGMAS_H */ diff --git a/scalos/include/pragmas/openurl_pragmas.h b/scalos/include/pragmas/openurl_pragmas.h new file mode 100755 index 000000000..6edd8eb0d --- /dev/null +++ b/scalos/include/pragmas/openurl_pragmas.h @@ -0,0 +1,69 @@ +#ifndef PRAGMAS_OPENURL_PRAGMAS_H +#define PRAGMAS_OPENURL_PRAGMAS_H + +/* +** $VER: openurl_pragmas.h 6.4 (27.7.2005) +** Includes Release 6.4 +** +** Direct ROM interface (pragma) definitions. +** +** openurl.library - universal URL display and browser +** launcher library +** +** Written by Troels Walsted Hansen +** Placed in the public domain. +** +** Developed by: +** - Alfonso Ranieri +** - Stefan Kost +** +*/ + +#ifndef CLIB_OPENURL_PROTOS_H +#include +#endif + +#if defined(AZTEC_C) || defined(__MAXON__) || defined(__STORM__) +#pragma amicall(OpenURLBase,0x01e,URL_OpenA(a0,a1)) +#pragma amicall(OpenURLBase,0x024,URL_OldGetPrefs()) +#pragma amicall(OpenURLBase,0x02a,URL_OldFreePrefs(a0)) +#pragma amicall(OpenURLBase,0x030,URL_OldSetPrefs(a0,d0)) +#pragma amicall(OpenURLBase,0x036,URL_OldGetDefaultPrefs()) +#pragma amicall(OpenURLBase,0x03c,URL_OldLaunchPrefsApp()) +#pragma amicall(OpenURLBase,0x042,DoFunction(a0)) +#pragma amicall(OpenURLBase,0x048,URL_GetPrefsA(a0)) +#pragma amicall(OpenURLBase,0x04e,URL_FreePrefsA(a0,a1)) +#pragma amicall(OpenURLBase,0x054,URL_SetPrefsA(a0,a1)) +#pragma amicall(OpenURLBase,0x05a,URL_LaunchPrefsAppA(a0)) +#pragma amicall(OpenURLBase,0x060,URL_GetAttr(d0,a0)) +#endif +#if defined(_DCC) || defined(__SASC) +#pragma libcall OpenURLBase URL_OpenA 01e 9802 +#pragma libcall OpenURLBase URL_OldGetPrefs 024 00 +#pragma libcall OpenURLBase URL_OldFreePrefs 02a 801 +#pragma libcall OpenURLBase URL_OldSetPrefs 030 0802 +#pragma libcall OpenURLBase URL_OldGetDefaultPrefs 036 00 +#pragma libcall OpenURLBase URL_OldLaunchPrefsApp 03c 00 +#pragma libcall OpenURLBase DoFunction 042 801 +#pragma libcall OpenURLBase URL_GetPrefsA 048 801 +#pragma libcall OpenURLBase URL_FreePrefsA 04e 9802 +#pragma libcall OpenURLBase URL_SetPrefsA 054 9802 +#pragma libcall OpenURLBase URL_LaunchPrefsAppA 05a 801 +#pragma libcall OpenURLBase URL_GetAttr 060 8002 +#endif +#ifdef __STORM__ +#pragma tagcall(OpenURLBase,0x01e,URL_Open(a0,a1)) +#pragma tagcall(OpenURLBase,0x048,URL_GetPrefs(a0)) +#pragma tagcall(OpenURLBase,0x04e,URL_FreePrefs(a0,a1)) +#pragma tagcall(OpenURLBase,0x054,URL_SetPrefs(a0,a1)) +#pragma tagcall(OpenURLBase,0x05a,URL_LaunchPrefsApp(a0)) +#endif +#ifdef __SASC_60 +#pragma tagcall OpenURLBase URL_Open 01e 9802 +#pragma tagcall OpenURLBase URL_GetPrefs 048 801 +#pragma tagcall OpenURLBase URL_FreePrefs 04e 9802 +#pragma tagcall OpenURLBase URL_SetPrefs 054 9802 +#pragma tagcall OpenURLBase URL_LaunchPrefsApp 05a 801 +#endif + +#endif /* PRAGMAS_OPENURL_PRAGMAS_H */ diff --git a/scalos/include/pragmas/pm_pragmas.h b/scalos/include/pragmas/pm_pragmas.h new file mode 100755 index 000000000..7bd3575fb --- /dev/null +++ b/scalos/include/pragmas/pm_pragmas.h @@ -0,0 +1,173 @@ +#ifndef PRAGMAS_PM_PRAGMAS_H +#define PRAGMAS_PM_PRAGMAS_H + +/* +** $Id$ +** +** Direct ROM interface (pragma) definitions. +** +** Copyright © 2001 Amiga, Inc. +** All Rights Reserved +*/ + +#if defined(LATTICE) || defined(__SASC) || defined(_DCC) +#ifndef __CLIB_PRAGMA_LIBCALL +#define __CLIB_PRAGMA_LIBCALL +#endif /* __CLIB_PRAGMA_LIBCALL */ +#else /* __MAXON__, __STORM__ or AZTEC_C */ +#ifndef __CLIB_PRAGMA_AMICALL +#define __CLIB_PRAGMA_AMICALL +#endif /* __CLIB_PRAGMA_AMICALL */ +#endif /* */ + +#if defined(__SASC) || defined(__STORM__) +#ifndef __CLIB_PRAGMA_TAGCALL +#define __CLIB_PRAGMA_TAGCALL +#endif /* __CLIB_PRAGMA_TAGCALL */ +#endif /* __MAXON__, __STORM__ or AZTEC_C */ + +#ifndef CLIB_PM_PROTOS_H +#include +#endif /* CLIB_PM_PROTOS_H */ + +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall PopupMenuBase PM_MakeMenuA 1e 901 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_TAGCALL + #ifdef __CLIB_PRAGMA_LIBCALL + #pragma tagcall PopupMenuBase PM_MakeMenu 1e 901 + #endif /* __CLIB_PRAGMA_LIBCALL */ + #ifdef __CLIB_PRAGMA_AMICALL + #pragma tagcall(PopupMenuBase, 0x1e, PM_MakeMenu(a1)) + #endif /* __CLIB_PRAGMA_AMICALL */ +#endif /* __CLIB_PRAGMA_TAGCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall PopupMenuBase PM_MakeItemA 24 901 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_TAGCALL + #ifdef __CLIB_PRAGMA_LIBCALL + #pragma tagcall PopupMenuBase PM_MakeItem 24 901 + #endif /* __CLIB_PRAGMA_LIBCALL */ + #ifdef __CLIB_PRAGMA_AMICALL + #pragma tagcall(PopupMenuBase, 0x24, PM_MakeItem(a1)) + #endif /* __CLIB_PRAGMA_AMICALL */ +#endif /* __CLIB_PRAGMA_TAGCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall PopupMenuBase PM_FreePopupMenu 2a 901 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall PopupMenuBase PM_OpenPopupMenuA 30 A902 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_TAGCALL + #ifdef __CLIB_PRAGMA_LIBCALL + #pragma tagcall PopupMenuBase PM_OpenPopupMenu 30 A902 + #endif /* __CLIB_PRAGMA_LIBCALL */ + #ifdef __CLIB_PRAGMA_AMICALL + #pragma tagcall(PopupMenuBase, 0x30, PM_OpenPopupMenu(a1,a2)) + #endif /* __CLIB_PRAGMA_AMICALL */ +#endif /* __CLIB_PRAGMA_TAGCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall PopupMenuBase PM_MakeIDListA 36 901 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_TAGCALL + #ifdef __CLIB_PRAGMA_LIBCALL + #pragma tagcall PopupMenuBase PM_MakeIDList 36 901 + #endif /* __CLIB_PRAGMA_LIBCALL */ + #ifdef __CLIB_PRAGMA_AMICALL + #pragma tagcall(PopupMenuBase, 0x36, PM_MakeIDList(a1)) + #endif /* __CLIB_PRAGMA_AMICALL */ +#endif /* __CLIB_PRAGMA_TAGCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall PopupMenuBase PM_ItemChecked 3c 1902 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall PopupMenuBase PM_GetItemAttrsA 42 9A02 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_TAGCALL + #ifdef __CLIB_PRAGMA_LIBCALL + #pragma tagcall PopupMenuBase PM_GetItemAttrs 42 9A02 + #endif /* __CLIB_PRAGMA_LIBCALL */ + #ifdef __CLIB_PRAGMA_AMICALL + #pragma tagcall(PopupMenuBase, 0x42, PM_GetItemAttrs(a2,a1)) + #endif /* __CLIB_PRAGMA_AMICALL */ +#endif /* __CLIB_PRAGMA_TAGCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall PopupMenuBase PM_SetItemAttrsA 48 9A02 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_TAGCALL + #ifdef __CLIB_PRAGMA_LIBCALL + #pragma tagcall PopupMenuBase PM_SetItemAttrs 48 9A02 + #endif /* __CLIB_PRAGMA_LIBCALL */ + #ifdef __CLIB_PRAGMA_AMICALL + #pragma tagcall(PopupMenuBase, 0x48, PM_SetItemAttrs(a2,a1)) + #endif /* __CLIB_PRAGMA_AMICALL */ +#endif /* __CLIB_PRAGMA_TAGCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall PopupMenuBase PM_FindItem 4e 1902 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall PopupMenuBase PM_AlterState 54 1A903 +#endif /* __CLIB_PRAGMA_LIBCALL */ +/*--- (1 function slot reserved here) ---*/ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall PopupMenuBase PM_ExLstA 60 901 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_TAGCALL + #ifdef __CLIB_PRAGMA_LIBCALL + #pragma tagcall PopupMenuBase PM_ExLst 60 901 + #endif /* __CLIB_PRAGMA_LIBCALL */ + #ifdef __CLIB_PRAGMA_AMICALL + #pragma tagcall(PopupMenuBase, 0x60, PM_ExLst(a1)) + #endif /* __CLIB_PRAGMA_AMICALL */ +#endif /* __CLIB_PRAGMA_TAGCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall PopupMenuBase PM_FilterIMsgA 66 BA9804 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_TAGCALL + #ifdef __CLIB_PRAGMA_LIBCALL + #pragma tagcall PopupMenuBase PM_FilterIMsg 66 BA9804 + #endif /* __CLIB_PRAGMA_LIBCALL */ + #ifdef __CLIB_PRAGMA_AMICALL + #pragma tagcall(PopupMenuBase, 0x66, PM_FilterIMsg(a0,a1,a2,a3)) + #endif /* __CLIB_PRAGMA_AMICALL */ +#endif /* __CLIB_PRAGMA_TAGCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall PopupMenuBase PM_InsertMenuItemA 6c 9802 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_TAGCALL + #ifdef __CLIB_PRAGMA_LIBCALL + #pragma tagcall PopupMenuBase PM_InsertMenuItem 6c 9802 + #endif /* __CLIB_PRAGMA_LIBCALL */ + #ifdef __CLIB_PRAGMA_AMICALL + #pragma tagcall(PopupMenuBase, 0x6c, PM_InsertMenuItem(a0,a1)) + #endif /* __CLIB_PRAGMA_AMICALL */ +#endif /* __CLIB_PRAGMA_TAGCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall PopupMenuBase PM_RemoveMenuItem 72 9802 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall PopupMenuBase PM_AbortHook 78 801 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall PopupMenuBase PM_GetVersion 7e 00 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall PopupMenuBase PM_ReloadPrefs 84 00 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall PopupMenuBase PM_LayoutMenuA 8a A9803 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_TAGCALL + #ifdef __CLIB_PRAGMA_LIBCALL + #pragma tagcall PopupMenuBase PM_LayoutMenu 8a A9803 + #endif /* __CLIB_PRAGMA_LIBCALL */ + #ifdef __CLIB_PRAGMA_AMICALL + #pragma tagcall(PopupMenuBase, 0x8a, PM_LayoutMenu(a0,a1,a2)) + #endif /* __CLIB_PRAGMA_AMICALL */ +#endif /* __CLIB_PRAGMA_TAGCALL */ +/*--- (1 function slot reserved here) ---*/ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall PopupMenuBase PM_FreeIDList 96 801 +#endif /* __CLIB_PRAGMA_LIBCALL */ + +#endif /* PRAGMAS_PM_PRAGMAS_H */ diff --git a/scalos/include/pragmas/preferences_pragmas.h b/scalos/include/pragmas/preferences_pragmas.h new file mode 100755 index 000000000..3b7c7ee40 --- /dev/null +++ b/scalos/include/pragmas/preferences_pragmas.h @@ -0,0 +1,64 @@ +#ifndef PRAGMAS_PREFERENCES_PRAGMAS_H +#define PRAGMAS_PREFERENCES_PRAGMAS_H + +/* +** $Id$ +** +** Direct ROM interface (pragma) definitions. +** +** Copyright © 2001 Amiga, Inc. +** All Rights Reserved +*/ + +#if defined(LATTICE) || defined(__SASC) || defined(_DCC) +#ifndef __CLIB_PRAGMA_LIBCALL +#define __CLIB_PRAGMA_LIBCALL +#endif /* __CLIB_PRAGMA_LIBCALL */ +#else /* __MAXON__, __STORM__ or AZTEC_C */ +#ifndef __CLIB_PRAGMA_AMICALL +#define __CLIB_PRAGMA_AMICALL +#endif /* __CLIB_PRAGMA_AMICALL */ +#endif /* */ + +#if defined(__SASC) || defined(__STORM__) +#ifndef __CLIB_PRAGMA_TAGCALL +#define __CLIB_PRAGMA_TAGCALL +#endif /* __CLIB_PRAGMA_TAGCALL */ +#endif /* __MAXON__, __STORM__ or AZTEC_C */ + +#ifndef CLIB_PREFERENCES_PROTOS_H +#include +#endif /* CLIB_PREFERENCES_PROTOS_H */ + +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall PreferencesBase AllocPrefsHandle 1e 801 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall PreferencesBase FreePrefsHandle 24 801 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall PreferencesBase SetPreferences 2a 2910805 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall PreferencesBase GetPreferences 30 2910805 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall PreferencesBase ReadPrefsHandle 36 9802 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall PreferencesBase WritePrefsHandle 3c 9802 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall PreferencesBase FindPreferences 42 10803 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall PreferencesBase SetEntry 48 32910806 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall PreferencesBase GetEntry 4e 32910806 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall PreferencesBase RemEntry 54 210804 +#endif /* __CLIB_PRAGMA_LIBCALL */ + +#endif /* PRAGMAS_PREFERENCES_PRAGMAS_H */ diff --git a/scalos/include/pragmas/scalos_pragmas.h b/scalos/include/pragmas/scalos_pragmas.h new file mode 100755 index 000000000..0e65bd617 --- /dev/null +++ b/scalos/include/pragmas/scalos_pragmas.h @@ -0,0 +1,58 @@ +#ifndef PRAGMAS_SCALOS_PRAGMAS_H +#define PRAGMAS_SCALOS_PRAGMAS_H + +#ifndef CLIB_SCALOS_PROTOS_H +#include +#endif + +#pragma libcall ScalosBase SCA_WBStart 01e 09803 +#pragma libcall ScalosBase SCA_SortNodes 024 09803 +#pragma libcall ScalosBase SCA_NewAddAppIcon 02a a981005 +#pragma libcall ScalosBase SCA_RemoveAppObject 030 801 +#pragma libcall ScalosBase SCA_NewAddAppWindow 036 a981005 +#pragma libcall ScalosBase SCA_NewAddAppMenuItem 03c a981005 +#pragma libcall ScalosBase SCA_AllocStdNode 042 0802 +#pragma libcall ScalosBase SCA_AllocNode 048 0802 +#pragma libcall ScalosBase SCA_FreeNode 04e 9802 +#pragma libcall ScalosBase SCA_FreeAllNodes 054 801 +#pragma libcall ScalosBase SCA_MoveNode 05a 09803 +#pragma libcall ScalosBase SCA_SwapNodes 060 a9803 +#pragma libcall ScalosBase SCA_OpenIconWindow 066 801 +#pragma libcall ScalosBase SCA_LockWindowList 06c 001 +#pragma libcall ScalosBase SCA_UnLockWindowList 072 00 +#pragma libcall ScalosBase SCA_AllocMessage 078 1002 +#pragma libcall ScalosBase SCA_FreeMessage 07e 901 +#pragma libcall ScalosBase SCA_InitDrag 084 801 +#pragma libcall ScalosBase SCA_EndDrag 08a 801 +#pragma libcall ScalosBase SCA_AddBob 090 3210a9807 +#pragma libcall ScalosBase SCA_DrawDrag 096 210804 +#pragma libcall ScalosBase SCA_UpdateIcon 09c 18003 +#pragma libcall ScalosBase SCA_MakeWBArgs 0a2 09803 +#pragma libcall ScalosBase SCA_FreeWBArgs 0a8 10803 +#pragma libcall ScalosBase SCA_ScreenTitleMsg 0b4 9802 +#pragma libcall ScalosBase SCA_MakeScalosClass 0ba a09804 +#pragma libcall ScalosBase SCA_FreeScalosClass 0c0 801 +#pragma libcall ScalosBase SCA_NewScalosObject 0c6 9802 +#pragma libcall ScalosBase SCA_DisposeScalosObject 0cc 801 +#pragma libcall ScalosBase SCA_ScalosControlA 0d2 9802 +#pragma libcall ScalosBase SCA_GetDefIconObject 0d8 9802 +#pragma libcall ScalosBase SCA_OpenDrawerByName 0de 9802 +#pragma libcall ScalosBase SCA_CountWBArgs 0e4 801 +#pragma libcall ScalosBase SCA_GetDefIconObjectA 0ea a9803 +#pragma libcall ScalosBase SCA_LockDrag 0f0 801 +#pragma libcall ScalosBase SCA_UnlockDrag 0f6 801 +#ifdef __SASC_60 +#pragma tagcall ScalosBase SCA_WBStartTags 01e 90803 +#pragma tagcall ScalosBase SCA_NewAddAppIconTags 02a a981005 +#pragma tagcall ScalosBase SCA_NewAddAppWindowTags 036 a981005 +#pragma tagcall ScalosBase SCA_NewAddAppMenuItemTags 03c a981005 +#pragma tagcall ScalosBase SCA_OpenIconWindowTags 066 801 +#pragma tagcall ScalosBase SCA_ScreenTitleMsgArgs 0b4 9802 +#pragma tagcall ScalosBase SCA_NewScalosObjectTags 0c6 9802 +#pragma tagcall ScalosBase SCA_ScalosControl 0d2 9802 +#pragma tagcall ScalosBase SCA_ScalosControlTags 0d2 9802 +#pragma tagcall ScalosBase SCA_OpenDrawerByNameTags 0de 9802 +#pragma tagcall ScalosBase SCA_GetDefIconObjectTags 0ea a9803 +#endif + +#endif /* PRAGMAS_SCALOS_PRAGMA_H */ diff --git a/scalos/include/pragmas/scalosfiletypeplugin_pragmas.h b/scalos/include/pragmas/scalosfiletypeplugin_pragmas.h new file mode 100755 index 000000000..866c27baf --- /dev/null +++ b/scalos/include/pragmas/scalosfiletypeplugin_pragmas.h @@ -0,0 +1,37 @@ +#ifndef PRAGMAS_SCALOSFILETYPEPLUGIN_PRAGMAS_H +#define PRAGMAS_SCALOSFILETYPEPLUGIN_PRAGMAS_H + +/* +** $Id$ +** +** Direct ROM interface (pragma) definitions. +** +** ©1999-2002 The Scalos Team +** All Rights Reserved +*/ + +#if defined(LATTICE) || defined(__SASC) || defined(_DCC) +#ifndef __CLIB_PRAGMA_LIBCALL +#define __CLIB_PRAGMA_LIBCALL +#endif /* __CLIB_PRAGMA_LIBCALL */ +#else /* __MAXON__, __STORM__ or AZTEC_C */ +#ifndef __CLIB_PRAGMA_AMICALL +#define __CLIB_PRAGMA_AMICALL +#endif /* __CLIB_PRAGMA_AMICALL */ +#endif /* */ + +#if defined(__SASC) || defined(__STORM__) +#ifndef __CLIB_PRAGMA_TAGCALL +#define __CLIB_PRAGMA_TAGCALL +#endif /* __CLIB_PRAGMA_TAGCALL */ +#endif /* __MAXON__, __STORM__ or AZTEC_C */ + +#ifndef CLIB_SCALOSFILETYPEPLUGIN_PROTOS_H +#include +#endif /* CLIB_SCALOSFILETYPEPLUGIN_PROTOS_H */ + +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall ScalosFileTypePluginBase SCAToolTipInfoString 1e 9802 +#endif /* __CLIB_PRAGMA_LIBCALL */ + +#endif /* PRAGMAS_SCALOSFILETYPEPLUGIN_PRAGMAS_H */ diff --git a/scalos/include/pragmas/scalosgfx_pragmas.h b/scalos/include/pragmas/scalosgfx_pragmas.h new file mode 100755 index 000000000..6dc14a95d --- /dev/null +++ b/scalos/include/pragmas/scalosgfx_pragmas.h @@ -0,0 +1,46 @@ +#ifndef PRAGMAS_SCALOSGFX_PRAGMAS_H +#define PRAGMAS_SCALOSGFX_PRAGMAS_H + +#ifndef CLIB_SCALOSGFX_PROTOS_H +#include +#endif + +#pragma libcall ScalosGfxBase ScalosGfxCreateEmptySAC 01e 00 +#pragma libcall ScalosGfxBase ScalosGfxCreateSAC 024 9821005 +#pragma libcall ScalosGfxBase ScalosGfxFreeSAC 02a 801 +#pragma libcall ScalosGfxBase ScalosGfxCreateARGB 030 81003 +#pragma libcall ScalosGfxBase ScalosGfxFreeARGB 036 801 +#pragma libcall ScalosGfxBase ScalosGfxARGBSetAlpha 03c 0802 +#pragma libcall ScalosGfxBase ScalosGfxARGBSetAlphaMask 042 9802 +#pragma libcall ScalosGfxBase ScalosGfxCreateARGBFromBitMap 048 a9210806 +#pragma libcall ScalosGfxBase ScalosGfxFillARGBFromBitMap 04e a9803 +#pragma libcall ScalosGfxBase ScalosGfxWriteARGBToBitMap 054 a09804 +#pragma libcall ScalosGfxBase ScalosGfxMedianCut 05a 90803 +#pragma libcall ScalosGfxBase ScalosGfxScaleARGBArray 060 ba9804 +#pragma libcall ScalosGfxBase ScalosGfxScaleBitMap 066 9802 +#pragma libcall ScalosGfxBase ScalosGfxCalculateScaleAspect 06c 981004 +#pragma libcall ScalosGfxBase ScalosGfxBlitARGB 072 5432109808 +#pragma libcall ScalosGfxBase ScalosGfxFillRectARGB 078 32109806 +#pragma libcall ScalosGfxBase ScalosGfxSetARGB 07e 9802 +#pragma libcall ScalosGfxBase ScalosGfxNewColorMap 084 09803 +#pragma libcall ScalosGfxBase ScalosGfxARGBRectMult 08a 3210a9807 +#pragma libcall ScalosGfxBase ScalosGfxBlitARGBAlpha 090 5432109808 +#pragma libcall ScalosGfxBase ScalosGfxBlitARGBAlphaTagList 096 ab109806 +#pragma libcall ScalosGfxBase ScalosGfxBlitIcon 09c a32109807 +#pragma libcall ScalosGfxBase ScalosGfxDrawGradient 0a2 4a93210808 +#pragma libcall ScalosGfxBase ScalosGfxDrawGradientRastPort 0a8 4a93210808 +#pragma libcall ScalosGfxBase ScalosGfxDrawLine 0ae 93210806 +#pragma libcall ScalosGfxBase ScalosGfxDrawLineRastPort 0b4 93210806 +#pragma libcall ScalosGfxBase ScalosGfxDrawEllipse 0ba a943210808 +#pragma libcall ScalosGfxBase ScalosGfxDrawEllipseRastPort 0c0 a943210808 +#ifdef __SASC_60 +#pragma tagcall ScalosGfxBase ScalosGfxCreateSACTags 024 9821005 +#pragma tagcall ScalosGfxBase ScalosGfxCreateARGBTags 030 81003 +#pragma tagcall ScalosGfxBase ScalosGfxMedianCutTags 05a 90803 +#pragma tagcall ScalosGfxBase ScalosGfxScaleARGBArrayTags 060 ba9804 +#pragma tagcall ScalosGfxBase ScalosGfxScaleBitMapTags 066 9802 +#pragma tagcall ScalosGfxBase ScalosGfxBlitARGBAlphaTags 096 ab109806 +#pragma tagcall ScalosGfxBase ScalosGfxBlitIconTags 09c a32109807 +#endif + +#endif /* PRAGMAS_SCALOSGFX_PRAGMA_H */ diff --git a/scalos/include/pragmas/scalosmenuplugin_pragmas.h b/scalos/include/pragmas/scalosmenuplugin_pragmas.h new file mode 100755 index 000000000..c70f2ce1b --- /dev/null +++ b/scalos/include/pragmas/scalosmenuplugin_pragmas.h @@ -0,0 +1,37 @@ +#ifndef PRAGMAS_SCALOSMENUPLUGIN_PRAGMAS_H +#define PRAGMAS_SCALOSMENUPLUGIN_PRAGMAS_H + +/* +** $Id$ +** +** Direct ROM interface (pragma) definitions. +** +** ©1999-2002 The Scalos Team +** All Rights Reserved +*/ + +#if defined(LATTICE) || defined(__SASC) || defined(_DCC) +#ifndef __CLIB_PRAGMA_LIBCALL +#define __CLIB_PRAGMA_LIBCALL +#endif /* __CLIB_PRAGMA_LIBCALL */ +#else /* __MAXON__, __STORM__ or AZTEC_C */ +#ifndef __CLIB_PRAGMA_AMICALL +#define __CLIB_PRAGMA_AMICALL +#endif /* __CLIB_PRAGMA_AMICALL */ +#endif /* */ + +#if defined(__SASC) || defined(__STORM__) +#ifndef __CLIB_PRAGMA_TAGCALL +#define __CLIB_PRAGMA_TAGCALL +#endif /* __CLIB_PRAGMA_TAGCALL */ +#endif /* __MAXON__, __STORM__ or AZTEC_C */ + +#ifndef CLIB_SCALOSMENUPLUGIN_PROTOS_H +#include +#endif /* CLIB_SCALOSMENUPLUGIN_PROTOS_H */ + +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall ScalosMenuPluginBase SCAMenuFunction 1e 9802 +#endif /* __CLIB_PRAGMA_LIBCALL */ + +#endif /* PRAGMAS_SCALOSMENUPLUGIN_PRAGMAS_H */ diff --git a/scalos/include/pragmas/scalosplugin_pragmas.h b/scalos/include/pragmas/scalosplugin_pragmas.h new file mode 100755 index 000000000..eb1ef44ac --- /dev/null +++ b/scalos/include/pragmas/scalosplugin_pragmas.h @@ -0,0 +1,10 @@ +#ifndef PRAGMAS_SCALOSPLUGIN_PRAGMAS_H +#define PRAGMAS_SCALOSPLUGIN_PRAGMAS_H + +#ifndef CLIB_SCALOSPLUGIN_PROTOS_H +#include +#endif + +#pragma libcall ScalosPluginBase SCAGetClassInfo 01e 00 + +#endif /* PRAGMAS_SCALOSPLUGIN_PRAGMA_H */ diff --git a/scalos/include/pragmas/scalosprefsplugin_pragmas.h b/scalos/include/pragmas/scalosprefsplugin_pragmas.h new file mode 100755 index 000000000..2661ff213 --- /dev/null +++ b/scalos/include/pragmas/scalosprefsplugin_pragmas.h @@ -0,0 +1,37 @@ +#ifndef PRAGMAS_SCALOSPREFSPLUGIN_PRAGMAS_H +#define PRAGMAS_SCALOSPREFSPLUGIN_PRAGMAS_H + +/* +** $Id$ +** +** Direct ROM interface (pragma) definitions. +** +** ©1999-2002 The Scalos Team +** All Rights Reserved +*/ + +#if defined(LATTICE) || defined(__SASC) || defined(_DCC) +#ifndef __CLIB_PRAGMA_LIBCALL +#define __CLIB_PRAGMA_LIBCALL +#endif /* __CLIB_PRAGMA_LIBCALL */ +#else /* __MAXON__, __STORM__ or AZTEC_C */ +#ifndef __CLIB_PRAGMA_AMICALL +#define __CLIB_PRAGMA_AMICALL +#endif /* __CLIB_PRAGMA_AMICALL */ +#endif /* */ + +#if defined(__SASC) || defined(__STORM__) +#ifndef __CLIB_PRAGMA_TAGCALL +#define __CLIB_PRAGMA_TAGCALL +#endif /* __CLIB_PRAGMA_TAGCALL */ +#endif /* __MAXON__, __STORM__ or AZTEC_C */ + +#ifndef CLIB_SCALOSPREFSPLUGIN_PROTOS_H +#include +#endif /* CLIB_SCALOSPREFSPLUGIN_PROTOS_H */ + +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall ScalosPrefsPluginBase SCAGetPrefsInfo 1e 001 +#endif /* __CLIB_PRAGMA_LIBCALL */ + +#endif /* PRAGMAS_SCALOSPREFSPLUGIN_PRAGMAS_H */ diff --git a/scalos/include/pragmas/scalospreviewplugin_pragmas.h b/scalos/include/pragmas/scalospreviewplugin_pragmas.h new file mode 100755 index 000000000..26c9fe501 --- /dev/null +++ b/scalos/include/pragmas/scalospreviewplugin_pragmas.h @@ -0,0 +1,45 @@ +#ifndef PRAGMAS_SCALOSPREVIEWPLUGIN_PRAGMAS_H +#define PRAGMAS_SCALOSPREVIEWPLUGIN_PRAGMAS_H + +/* +** $Id$ +** +** Direct ROM interface (pragma) definitions. +** +** Copyright © 2001 Amiga, Inc. +** All Rights Reserved +*/ + +#if defined(LATTICE) || defined(__SASC) || defined(_DCC) +#ifndef __CLIB_PRAGMA_LIBCALL +#define __CLIB_PRAGMA_LIBCALL +#endif /* __CLIB_PRAGMA_LIBCALL */ +#else /* __MAXON__, __STORM__ or AZTEC_C */ +#ifndef __CLIB_PRAGMA_AMICALL +#define __CLIB_PRAGMA_AMICALL +#endif /* __CLIB_PRAGMA_AMICALL */ +#endif /* */ + +#if defined(__SASC) || defined(__STORM__) +#ifndef __CLIB_PRAGMA_TAGCALL +#define __CLIB_PRAGMA_TAGCALL +#endif /* __CLIB_PRAGMA_TAGCALL */ +#endif /* __MAXON__, __STORM__ or AZTEC_C */ + +#ifndef CLIB_SCALOSPREVIEWPLUGIN_PROTOS_H +#include +#endif /* CLIB_SCALOSPREVIEWPLUGIN_PROTOS_H */ + +#ifdef __CLIB_PRAGMA_LIBCALL + #pragma libcall ScalosPreviewPluginBase SCAPreviewGenerate 1e BA9804 +#endif /* __CLIB_PRAGMA_LIBCALL */ +#ifdef __CLIB_PRAGMA_TAGCALL + #ifdef __CLIB_PRAGMA_LIBCALL + #pragma tagcall ScalosPreviewPluginBase SCAPreviewGenerateTags 1e BA9804 + #endif /* __CLIB_PRAGMA_LIBCALL */ + #ifdef __CLIB_PRAGMA_AMICALL + #pragma tagcall(ScalosPreviewPluginBase, 0x1e, SCAPreviewGenerateTags(a0,a1,a2,a3)) + #endif /* __CLIB_PRAGMA_AMICALL */ +#endif /* __CLIB_PRAGMA_TAGCALL */ + +#endif /* PRAGMAS_SCALOSPREVIEWPLUGIN_PRAGMAS_H */ diff --git a/scalos/include/pragmas/sqlite3_pragmas.h b/scalos/include/pragmas/sqlite3_pragmas.h new file mode 100755 index 000000000..485a60c81 --- /dev/null +++ b/scalos/include/pragmas/sqlite3_pragmas.h @@ -0,0 +1,111 @@ +#ifndef PRAGMAS_SQLITE3_PRAGMAS_H +#define PRAGMAS_SQLITE3_PRAGMAS_H + +#ifndef CLIB_SQLITE3_PROTOS_H +#include +#endif + +#pragma libcall SQLite3Base SQLite3Close 01e 801 +#pragma libcall SQLite3Base SQLite3Exec 024 0ba9805 +#pragma libcall SQLite3Base SQLite3Changes 02a 801 +#pragma libcall SQLite3Base SQLite3TotalChanges 030 801 +#pragma libcall SQLite3Base SQLite3Interrupt 036 801 +#pragma libcall SQLite3Base SQLite3Complete 03c 801 +#pragma libcall SQLite3Base SQLite3BusyHandler 042 a9803 +#pragma libcall SQLite3Base SQLite3BusyTimeout 048 0802 +#pragma libcall SQLite3Base SQLite3GetTable 04e 10ba9806 +#pragma libcall SQLite3Base SQLite3FreeTable 054 801 +#pragma libcall SQLite3Base SQLite3Free 05a 801 +#pragma libcall SQLite3Base SQLite3Trace 060 a9803 +#pragma libcall SQLite3Base SQLite3ProgressHandler 066 a90804 +#pragma libcall SQLite3Base SQLite3CommitHook 06c a9803 +#pragma libcall SQLite3Base SQLite3Open 072 9802 +#pragma libcall SQLite3Base SQLite3Errcode 078 801 +#pragma libcall SQLite3Base SQLite3Errmsg 07e 801 +#pragma libcall SQLite3Base SQLite3Prepare 084 ba09805 +#pragma libcall SQLite3Base SQLite3BindBlob 08a a190805 +#pragma libcall SQLite3Base SQLite3BindInt 090 10803 +#pragma libcall SQLite3Base SQLite3BindNull 096 0802 +#pragma libcall SQLite3Base SQLite3BindText 09c a190805 +#pragma libcall SQLite3Base SQLite3BindValue 0a2 90803 +#pragma libcall SQLite3Base SQLite3BindParameterCount 0a8 801 +#pragma libcall SQLite3Base SQLite3BindParameterName 0ae 0802 +#pragma libcall SQLite3Base SQLite3BindParameterIndex 0b4 9802 +#pragma libcall SQLite3Base SQLite3ClearBindings 0ba 801 +#pragma libcall SQLite3Base SQLite3ColumnCount 0c0 801 +#pragma libcall SQLite3Base SQLite3ColumnName 0c6 0802 +#pragma libcall SQLite3Base SQLite3ColumnDecltype 0cc 0802 +#pragma libcall SQLite3Base SQLite3Step 0d2 801 +#pragma libcall SQLite3Base SQLite3DataCount 0d8 801 +#pragma libcall SQLite3Base SQLite3ColumnBlob 0de 0802 +#pragma libcall SQLite3Base SQLite3ColumnBytes 0e4 0802 +#pragma libcall SQLite3Base SQLite3ColumnInt 0ea 0802 +#pragma libcall SQLite3Base SQLite3ColumnText 0f0 0802 +#pragma libcall SQLite3Base SQLite3ColumnType 0f6 0802 +#pragma libcall SQLite3Base SQLite3Finalize 0fc 801 +#pragma libcall SQLite3Base SQLite3Reset 102 801 +#pragma libcall SQLite3Base SQLite3AggregateCount 108 801 +#pragma libcall SQLite3Base SQLite3ValueBlob 10e 801 +#pragma libcall SQLite3Base SQLite3ValueBytes 114 801 +#pragma libcall SQLite3Base SQLite3ValueInt 11a 801 +#pragma libcall SQLite3Base SQLite3ValueText 120 801 +#pragma libcall SQLite3Base SQLite3ValueType 126 801 +#pragma libcall SQLite3Base SQLite3Aggregate_context 12c 0802 +#pragma libcall SQLite3Base SQLite3UserData 132 801 +#pragma libcall SQLite3Base SQLite3GetAuxdata 138 0802 +#pragma libcall SQLite3Base SQLite3SetAuxdata 13e a90804 +#pragma libcall SQLite3Base SQLite3ResultBlob 144 a09804 +#pragma libcall SQLite3Base SQLite3ResultError 14a 09803 +#pragma libcall SQLite3Base SQLite3ResultInt 150 0802 +#pragma libcall SQLite3Base SQLite3ResultNull 156 801 +#pragma libcall SQLite3Base SQLite3ResultText 15c a09804 +#pragma libcall SQLite3Base SQLite3ResultValue 162 9802 +#pragma libcall SQLite3Base SQLite3CreateCollation 168 ba09805 +#pragma libcall SQLite3Base SQLite3CollationNeeded 16e 90803 +#pragma libcall SQLite3Base SQLite3Sleep 174 001 +#pragma libcall SQLite3Base SQLite3Expired 17a 801 +#pragma libcall SQLite3Base SQLite3TransferBindings 180 9802 +#pragma libcall SQLite3Base SQLite3GlobalRecover 186 00 +#pragma libcall SQLite3Base SQLite3GetAutocommit 18c 801 +#pragma libcall SQLite3Base SQLite3DbHandle 192 801 +#pragma libcall SQLite3Base SQLite3RollbackHook 198 a9803 +#pragma libcall SQLite3Base SQLite3EnableSharedCache 19e 001 +#pragma libcall SQLite3Base SQLite3ReleaseMemory 1a4 001 +#pragma libcall SQLite3Base SQLite3SoftHeapLimit 1aa 001 +#pragma libcall SQLite3Base SQLite3ThreadCleanup 1b0 00 +#pragma libcall SQLite3Base SQLite3PrepareV2 1b6 ba09805 +#pragma libcall SQLite3Base SQLite3CreateFunction 1bc 32ba109808 +#pragma libcall SQLite3Base SQLite3CreateModule 1c2 ba9804 +#pragma libcall SQLite3Base SQLite3DeclareVtab 1c8 9802 +#pragma libcall SQLite3Base SQLite3OverloadFunction 1ce 09803 +#pragma libcall SQLite3Base SQLite3BlobOpen 1d4 c10ba9807 +#pragma libcall SQLite3Base SQLite3BlobClose 1da 801 +#pragma libcall SQLite3Base SQLite3BlobBytes 1e0 801 +#pragma libcall SQLite3Base SQLite3BlobRead 1e6 109804 +#pragma libcall SQLite3Base SQLite3BlobWrite 1ec 109804 +#pragma libcall SQLite3Base SQLite3ExtendedResultCodes 1f2 0802 +#pragma libcall SQLite3Base SQLite3BindZeroBlob 1f8 10803 +#pragma libcall SQLite3Base SQLite3ColumnDatabaseName 1fe 0802 +#pragma libcall SQLite3Base SQLite3ColumnTableName 204 0802 +#pragma libcall SQLite3Base SQLite3ColumnOriginName 20a 0802 +#pragma libcall SQLite3Base SQLite3ColumnValue 210 0802 +#pragma libcall SQLite3Base SQLite3CreateCollationV2 216 1ba09806 +#pragma libcall SQLite3Base SQLite3LibVersion 21c 00 +#pragma libcall SQLite3Base SQLite3LibversionNumber 222 00 +#pragma libcall SQLite3Base SQLite3ResultErrorToobig 228 801 +#pragma libcall SQLite3Base SQLite3ResultZeroBlob 22e 0802 +#pragma libcall SQLite3Base SQLite3ValueNumericType 234 801 +#pragma libcall SQLite3Base SQLite3ConfigV 23a 8002 +#pragma libcall SQLite3Base SQLlite3DbConfigV 240 90803 +#pragma libcall SQLite3Base SQLite3VfsFind 246 801 +#pragma libcall SQLite3Base SQLite3VfsRegister 24c 0802 +#pragma libcall SQLite3Base SQLite3VfsUnregister 252 801 +#pragma libcall SQLite3Base SQLite3FileControl 258 a09804 +#pragma libcall SQLite3Base SQLite3Status 25e 198004 +#pragma libcall SQLite3Base SQLite3DbStatus 264 1a90805 +#ifdef __SASC_60 +#pragma tagcall SQLite3Base SQLite3Config 23a 8002 +#pragma tagcall SQLite3Base SQLlite3DbConfig 240 90803 +#endif + +#endif /* PRAGMAS_SQLITE3_PRAGMA_H */ diff --git a/scalos/include/pragmas/titlebarimage_pragmas.h b/scalos/include/pragmas/titlebarimage_pragmas.h new file mode 100755 index 000000000..84b647bc4 --- /dev/null +++ b/scalos/include/pragmas/titlebarimage_pragmas.h @@ -0,0 +1,12 @@ +#ifndef PRAGMAS_TITLEBAR_PRAGMAS_H +#define PRAGMAS_TITLEBAR_PRAGMAS_H + +/* "titlebar.image"*/ +/*--- functions in V40 or higher ---*/ +/**/ + +#if defined(LATTICE) || defined(__SASC) || defined(_DCC) +#pragma libcall TitlebarImageBase ObtainTBIClass 1e 0 +#endif /* */ + +#endif /* PRAGMAS_TITLEBAR_PRAGMAS_H */ diff --git a/scalos/include/pragmas/ttengine_pragmas.h b/scalos/include/pragmas/ttengine_pragmas.h new file mode 100644 index 000000000..663e30557 --- /dev/null +++ b/scalos/include/pragmas/ttengine_pragmas.h @@ -0,0 +1,63 @@ +#ifndef _INCLUDE_PRAGMA_TTENGINE_LIB_H +#define _INCLUDE_PRAGMA_TTENGINE_LIB_H + +#ifndef CLIB_TTENGINE_PROTOS_H +#include +#endif + +#if defined(AZTEC_C) || defined(__MAXON__) || defined(__STORM__) +#pragma amicall(TTEngineBase,0x01e,TT_OpenFontA(a0)) +#pragma amicall(TTEngineBase,0x024,TT_SetFont(a1,a0)) +#pragma amicall(TTEngineBase,0x02a,TT_CloseFont(a0)) +#pragma amicall(TTEngineBase,0x030,TT_Text(a1,a0,d0)) +#pragma amicall(TTEngineBase,0x036,TT_SetAttrsA(a1,a0)) +#pragma amicall(TTEngineBase,0x03c,TT_GetAttrsA(a1,a0)) +#pragma amicall(TTEngineBase,0x042,TT_TextLength(a1,a0,d0)) +#pragma amicall(TTEngineBase,0x048,TT_TextExtent(a1,a0,d0,a2)) +#pragma amicall(TTEngineBase,0x04e,TT_TextFit(a1,a0,d0,a2,a3,d1,d2,d3)) +#pragma amicall(TTEngineBase,0x054,TT_GetPixmapA(a1,a2,d0,a0)) +#pragma amicall(TTEngineBase,0x05a,TT_FreePixmap(a0)) +#pragma amicall(TTEngineBase,0x060,TT_DoneRastPort(a1)) +#pragma amicall(TTEngineBase,0x066,TT_AllocRequest()) +#pragma amicall(TTEngineBase,0x06c,TT_RequestA(a0,a1)) +#pragma amicall(TTEngineBase,0x072,TT_FreeRequest(a0)) +#pragma amicall(TTEngineBase,0x078,TT_ObtainFamilyListA(a0)) +#pragma amicall(TTEngineBase,0x07e,TT_FreeFamilyList(a0)) +#endif +#if defined(_DCC) || defined(__SASC) +#pragma libcall TTEngineBase TT_OpenFontA 01e 801 +#pragma libcall TTEngineBase TT_SetFont 024 8902 +#pragma libcall TTEngineBase TT_CloseFont 02a 801 +#pragma libcall TTEngineBase TT_Text 030 08903 +#pragma libcall TTEngineBase TT_SetAttrsA 036 8902 +#pragma libcall TTEngineBase TT_GetAttrsA 03c 8902 +#pragma libcall TTEngineBase TT_TextLength 042 08903 +#pragma libcall TTEngineBase TT_TextExtent 048 a08904 +#pragma libcall TTEngineBase TT_TextFit 04e 321ba08908 +#pragma libcall TTEngineBase TT_GetPixmapA 054 80a904 +#pragma libcall TTEngineBase TT_FreePixmap 05a 801 +#pragma libcall TTEngineBase TT_DoneRastPort 060 901 +#pragma libcall TTEngineBase TT_AllocRequest 066 00 +#pragma libcall TTEngineBase TT_RequestA 06c 9802 +#pragma libcall TTEngineBase TT_FreeRequest 072 801 +#pragma libcall TTEngineBase TT_ObtainFamilyListA 078 801 +#pragma libcall TTEngineBase TT_FreeFamilyList 07e 801 +#endif +#ifdef __STORM__ +#pragma tagcall(TTEngineBase,0x01e,TT_OpenFont(a0)) +#pragma tagcall(TTEngineBase,0x036,TT_SetAttrs(a1,a0)) +#pragma tagcall(TTEngineBase,0x03c,TT_GetAttrs(a1,a0)) +#pragma tagcall(TTEngineBase,0x054,TT_GetPixmap(a1,a2,d0,a0)) +#pragma tagcall(TTEngineBase,0x06c,TT_Request(a0,a1)) +#pragma tagcall(TTEngineBase,0x078,TT_ObtainFamilyList(a0)) +#endif +#ifdef __SASC_60 +#pragma tagcall TTEngineBase TT_OpenFont 01e 801 +#pragma tagcall TTEngineBase TT_SetAttrs 036 8902 +#pragma tagcall TTEngineBase TT_GetAttrs 03c 8902 +#pragma tagcall TTEngineBase TT_GetPixmap 054 80a904 +#pragma tagcall TTEngineBase TT_Request 06c 9802 +#pragma tagcall TTEngineBase TT_ObtainFamilyList 078 801 +#endif + +#endif /* _INCLUDE_PRAGMA_TTENGINE_LIB_H */ diff --git a/scalos/include/prefs/popupmenu.h b/scalos/include/prefs/popupmenu.h new file mode 100644 index 000000000..a30f04f48 --- /dev/null +++ b/scalos/include/prefs/popupmenu.h @@ -0,0 +1,125 @@ +#ifndef PREFS_POPUPMENU_H +#define PREFS_POPUPMENU_H +/* +** $VER: popupmenu.h 50.1 (15.5.2002) +** Includes Release 50.1 +** +** File format for example preferences +** +** (C) Copyright 2002 Amiga, Inc. +** All Rights Reserved +*/ + +/*****************************************************************************/ + + +#ifndef EXEC_TYPES_H +#include +#endif + +#ifndef LIBRARIES_IFFPARSE_H +#include +#endif + +/*****************************************************************************/ + +// preferences.library IDs + +#define PMP_AnimationType 0x80007001 // UBYTE +#define PMP_PullDownMenuPos 0x80007002 // UBYTE +#define PMP_Sticky 0x80007003 // WORD +#define PMP_Flags 0x80007004 // UBYTE +#define PMP_SubMenuDelay 0x80007005 // UBYTE +#define PMP_MenuBorderType 0x80007006 // UBYTE +#define PMP_SelItemBorderType 0x80007007 // UBYTE +#define PMP_SeparatorBarStyle 0x80007008 // UBYTE +#define PMP_XOffset 0x80007009 // UBYTE +#define PMP_YOffset 0x8000700a // UBYTE +#define PMP_XSpace 0x8000700b // UBYTE +#define PMP_YSpace 0x8000700c // UBYTE +#define PMP_Intermediate 0x8000700d // UBYTE +#define PMP_TransparencyBlur 0x8000700e // UBYTE +#define PMP_TextDisplace 0x8000700f // BYTE +#define PMP_MenuTitleStyle 0x80007010 // UBYTE +#define PMP_MenuItemStyle 0x80007011 // UBYTE + +/*****************************************************************************/ + + +#define ID_PMNU MAKE_ID('P','M','N','U') + +/* !!! obsolete !!! */ +struct oldPopupMenuPrefs +{ + UBYTE pmp_Flags; /* Enable shadows, transparency, etc. */ + UBYTE pmp_SubMenuDelay; /* Delay before opening submenus */ + UBYTE pmp_Animation; /* Animation, see below for defines */ + /* (Only one animation effect implemented currently) */ + UBYTE pmp_PulldownPos; /* Where to show pulldownmenus */ + BOOL pmp_Sticky; /* Use 'sticky' mode */ + BOOL pmp_SameHeight; /* !!unused!! Try to give all items same height */ + UBYTE pmp_MenuBorder; /* Menu border */ + UBYTE pmp_SelItemBorder; /* Border around selected item */ + UBYTE pmp_SeparatorBar; /* Separator bar style */ + UBYTE pmp_MenuTitles; /* Flags for drawing menu texts */ + UBYTE pmp_MenuItems; /* Flags for drawing menu item texts */ + UBYTE pmp_XOffset; + UBYTE pmp_YOffset; + UBYTE pmp_XSpace; + UBYTE pmp_YSpace; + UBYTE pmp_Intermediate; + BYTE pmp_TextDisplace; + BYTE pmp_ShadowR; /* !!unused!! */ + BYTE pmp_ShadowG; /* !!unused!! */ + BYTE pmp_ShadowB; /* !!unused!! */ + BYTE pmp_TransparencyR; /* !!unused!! */ + BYTE pmp_TransparencyG; /* !!unused!! */ + BYTE pmp_TransparencyB; /* !!unused!! */ + UBYTE pmp_TransparencyBlur; + UBYTE pmp_AnimationSpeed; /* !!unused!! */ + UBYTE pmp_Reserved[16]; /* Reserved for future use */ +}; + +#define PMP_FLAGS_SHADOWS 0x01 +#define PMP_FLAGS_TRANSPARENCY 0x02 + +#define PMP_ANIM_NONE 0 +#define PMP_ANIM_ZOOM 1 +#define PMP_ANIM_FADE 2 +#define PMP_ANIM_EXPLODE 3 + +#define PMP_PD_SCREENBAR 0 +#define PMP_PD_WINDOWBAR 1 +#define PMP_PD_MOUSE 2 /* Show as popup menu */ + +#define PMP_TITLE_NORMAL 0x00 +#define PMP_TITLE_ITALIC 0x01 +#define PMP_TITLE_BOLD 0x02 +#define PMP_TITLE_UNDERLINE 0x04 +#define PMP_TITLE_SHADOW 0x08 +#define PMP_TITLE_EMBOSS 0x10 +#define PMP_TITLE_OUTLINE 0x20 + +#define PMP_TEXT_NORMAL 0x00 +#define PMP_TEXT_ITALIC 0x01 +#define PMP_TEXT_BOLD 0x02 +#define PMP_TEXT_UNDERLINE 0x04 +#define PMP_TEXT_SHADOW 0x08 +#define PMP_TEXT_EMBOSS 0x10 +#define PMP_TEXT_OUTLINE 0x20 + +#define PMP_MENUBORDER_THIN 0 +#define PMP_MENUBORDER_MM 1 +#define PMP_MENUBORDER_THICK 2 +#define PMP_MENUBORDER_RIDGE 3 +#define PMP_MENUBORDER_DROPBOX 4 +#define PMP_MENUBORDER_OLDSTYLE 5 + +#define PMP_SELITEM_NO_BORDER 0 +#define PMP_SELITEM_RECESS 1 +#define PMP_SELITEM_RAISE 2 + +/*****************************************************************************/ + + +#endif /* PREFS_POPUPMENU_H */ diff --git a/scalos/include/proto/alib.h b/scalos/include/proto/alib.h new file mode 100755 index 000000000..598c1f757 --- /dev/null +++ b/scalos/include/proto/alib.h @@ -0,0 +1,3 @@ +#include +#include +#include diff --git a/scalos/include/proto/cybergraphics.h b/scalos/include/proto/cybergraphics.h new file mode 100644 index 000000000..7f84a138c --- /dev/null +++ b/scalos/include/proto/cybergraphics.h @@ -0,0 +1,28 @@ +#ifndef PROTO_CYBERGRAPHICS_H +#define PROTO_CYBERGRAPHICS_H 1 +#include +extern struct Library *CyberGfxBase; +#ifdef __amigaos4__ +#include +extern struct CyberGfxIFace *ICyberGfx; +#endif /* __amigaos4__ */ + +#include + +#ifdef __amigaos4__ + #ifdef __USE_INLINE__ + #include + #endif +#elif defined(__GNUC__) + #ifdef __AROS__ + #include + #else + #include + #endif +#elif defined(VBCC) + #include +#else + #include +#endif + +#endif /* !PROTO_CYBERGRAPHICS_H */ diff --git a/scalos/include/proto/dtlib.h b/scalos/include/proto/dtlib.h new file mode 100755 index 000000000..c58bc867b --- /dev/null +++ b/scalos/include/proto/dtlib.h @@ -0,0 +1,21 @@ +#ifndef PROTO_SCALOSPLUGIN_H +#define PROTO_SCALOSPLUGIN_H + +#include +extern struct Library *DtLibBase ; + +#include + +#if defined(__GNUC__) + #ifdef __AROS__ + #include + #else + #include + #endif +#elif defined(VBCC) + #include +#else + #include +#endif + +#endif diff --git a/scalos/include/proto/guigfx.h b/scalos/include/proto/guigfx.h new file mode 100755 index 000000000..8525e2240 --- /dev/null +++ b/scalos/include/proto/guigfx.h @@ -0,0 +1,29 @@ +#ifndef PROTO_GUIGFX_H +#define PROTO_GUIGFX_H +#include +extern struct Library *GuiGFXBase; + +#ifdef __amigaos4__ +#include +extern struct GuiGFXIFace *IGuiGFX; +#endif + +#include + +#ifdef __amigaos4__ + #ifdef __USE_INLINE__ + #include + #endif +#elif defined(__GNUC__) + #ifdef __AROS__ + #include + #else + #include + #endif +#elif defined(VBCC) + #include +#else + #include +#endif + +#endif diff --git a/scalos/include/proto/iconobject.h b/scalos/include/proto/iconobject.h new file mode 100755 index 000000000..51d3a26c2 --- /dev/null +++ b/scalos/include/proto/iconobject.h @@ -0,0 +1,29 @@ +#ifndef PROTO_ICONOBJECT_H +#define PROTO_ICONOBJECT_H +#include +#include + +extern struct Library *IconobjectBase; +#ifdef __amigaos4__ +#include +extern struct IconobjectIFace *IIconobject; +#endif + +#include + +#ifdef __amigaos4__ + #ifdef __USE_INLINE__ + #include + #endif +#elif defined(__GNUC__) + #ifdef __AROS__ + #include + #else + #include + #endif +#elif defined(VBCC) + #include +#else + #include +#endif +#endif diff --git a/scalos/include/proto/mcpgfx.h b/scalos/include/proto/mcpgfx.h new file mode 100755 index 000000000..4782a0a69 --- /dev/null +++ b/scalos/include/proto/mcpgfx.h @@ -0,0 +1,25 @@ +#ifndef PROTO_MCPGFX_H +#define PROTO_MCPGFX_H + +#ifndef EXEC_TYPES_H +#include +#endif + +extern struct Library *MCPGfxBase; + +#include + +#if defined(__GNUC__) + #ifdef __AROS__ + #include + #else + #include + #endif +#elif defined(VBCC) + #include +#else + #include +#endif /* __VBCC__ */ + +#endif /* PROTO_MCPGFX_H */ + diff --git a/scalos/include/proto/newicon.h b/scalos/include/proto/newicon.h new file mode 100644 index 000000000..816d54e2e --- /dev/null +++ b/scalos/include/proto/newicon.h @@ -0,0 +1,30 @@ +#ifndef _PROTO_NEWICON_H +#define _PROTO_NEWICON_H + +#ifndef EXEC_TYPES_H +#include +#endif +#if !defined(CLIB_NEWICON_PROTOS_H) && !defined(__GNUC__) +#include +#endif +#ifndef LIBRARIES_NEWICON_H +#include +#endif + +#ifndef __NOLIBBASE__ +extern struct NewIconBase *NewIconBase ; +#endif + +#if defined(__GNUC__) + #ifdef __AROS__ + #include + #else + #include + #endif +#elif defined(VBCC) + #include +#else + #include +#endif + +#endif /* _PROTO_NEWICON_H */ diff --git a/scalos/include/proto/openurl.h b/scalos/include/proto/openurl.h new file mode 100755 index 000000000..4b1ee054d --- /dev/null +++ b/scalos/include/proto/openurl.h @@ -0,0 +1,83 @@ +#ifndef PROTO_OPENURL_H +#define PROTO_OPENURL_H + +/* +** $VER: openurl.h 7.2 (1.12.2005) +** Includes Release 7.2 +** +** SAS `C' style prototype/pragma header file combo +** +** openurl.library - universal URL display and browser +** launcher library +** +** Written by Troels Walsted Hansen +** Placed in the public domain. +** +** Developed by: +** - Alfonso Ranieri +** - Stefan Kost +** - Alexandre Balaban +** +*/ + +#ifndef EXEC_TYPES_H +#include +#endif + +/****************************************************************************/ + +#ifndef __NOLIBBASE__ + #ifndef __USE_BASETYPE__ +extern struct Library * +#ifdef __CONSTLIBBASEDECL__ +__CONSTLIBBASEDECL__ +#endif /* __CONSTLIBBASEDECL__ */ +OpenURLBase; + +#else + extern struct Library * + #ifdef __CONSTLIBBASEDECL__ + __CONSTLIBBASEDECL__ + #endif /* __CONSTLIBBASEDECL__ */ + OpenURLBase; + #endif /* __USE_BASETYPE__ */ +#endif /* __NOLIBBASE__ */ + +/****************************************************************************/ + +#ifdef __amigaos4__ + #include + #ifdef __USE_INLINE__ + #include + #endif /* __USE_INLINE__ */ + #ifndef CLIB_OPENURL_PROTOS_H + #define CLIB_OPENURL_PROTOS_H 1 + #endif /* CLIB_OPENURL_PROTOS_H */ + #ifndef __NOGLOBALIFACE__ + extern struct OpenURLIFace *IOpenURL; + #endif /* __NOGLOBALIFACE__ */ +#else /* __amigaos4__ */ + #ifndef CLIB_OPENURL_PROTOS_H + #include + #endif /* CLIB_OPENURL_PROTOS_H */ + #if defined(__GNUC__) + #ifdef __AROS__ + #include + #elif __PPC__ + #include + #else + #include + #endif /* __PPC__ */ + #elif defined(__VBCC__) + #ifndef __PPC__ + #include + #endif /* __PPC__ */ + #else + #include + #endif /* __GNUC__ */ +#endif /* __amigaos4__ */ + +/****************************************************************************/ + +#endif /* PROTO_OPENURL_H */ + diff --git a/scalos/include/proto/pm.h b/scalos/include/proto/pm.h new file mode 100755 index 000000000..35a84a247 --- /dev/null +++ b/scalos/include/proto/pm.h @@ -0,0 +1,27 @@ +#ifndef POPUPMENU_PROTO_H +#define POPUPMENU_PROTO_H +#include +#include +extern struct PopupMenuBase *PopupMenuBase; +#ifdef __amigaos4__ +#include +extern struct PopupMenuIFace *IPopupMenu; +#endif + +#if defined(__amigaos4__) + #ifdef __USE_INLINE__ + #include + #endif +#elif defined(__GNUC__) + #ifdef __AROS__ + #include + #else + #include + #endif +#elif defined(VBCC) + #include +#else + #include +#endif + +#endif diff --git a/scalos/include/proto/preferences.h b/scalos/include/proto/preferences.h new file mode 100755 index 000000000..936518304 --- /dev/null +++ b/scalos/include/proto/preferences.h @@ -0,0 +1,30 @@ +#ifndef PROTO_PREFERENCES_H +#define PROTO_PREFERENCES_H + +#include +extern struct Library *PreferencesBase; +#ifdef __amigaos4__ +#include +extern struct PreferencesIFace *IPreferences; +#endif + +#include + +#ifdef __amigaos4__ + #ifdef __USE_INLINE__ + #include + #endif +#elif defined(__GNUC__) + #ifdef __AROS__ + #include + #else + #include + #endif +#elif defined(VBCC) + #include +#else + #include +#endif /* __VBCC__ */ + +#endif /* PROTO_PREFERENCES_H */ + diff --git a/scalos/include/proto/scalos.h b/scalos/include/proto/scalos.h new file mode 100755 index 000000000..6e6329730 --- /dev/null +++ b/scalos/include/proto/scalos.h @@ -0,0 +1,31 @@ +#ifndef PROTO_SCALOS_H +#define PROTO_SCALOS_H + +#include +#include +#include +extern struct ScalosBase *ScalosBase ; +#ifdef __amigaos4__ +#include +extern struct ScalosIFace *IScalos; +#endif + +#include + +#ifdef __amigaos4__ + #ifdef __USE_INLINE__ + #include + #endif +#elif defined(__GNUC__) + #ifdef __AROS__ + #include + #else + #include + #endif +#elif defined(VBCC) + #include +#else + #include +#endif + +#endif diff --git a/scalos/include/proto/scalosfiletypeplugin.h b/scalos/include/proto/scalosfiletypeplugin.h new file mode 100755 index 000000000..d6ac1f685 --- /dev/null +++ b/scalos/include/proto/scalosfiletypeplugin.h @@ -0,0 +1,29 @@ +#ifndef PROTO_SCALOSFILETYPEPLUGIN_H +#define PROTO_SCALOSFILETYPEPLUGIN_H + +#include +extern struct Library *ScalosFileTypePluginBase ; +#ifdef __amigaos4__ +#include +extern struct ScalosFileTypePluginIFace *IScalosFileTypePlugin; +#endif + +#include + +#ifdef __amigaos4__ + #ifdef __USE_INLINE__ + #include + #endif +#elif defined(__GNUC__) + #ifdef __AROS__ + #include + #else + #include + #endif +#elif defined(VBCC) + #include +#else + #include +#endif + +#endif diff --git a/scalos/include/proto/scalosgfx.h b/scalos/include/proto/scalosgfx.h new file mode 100755 index 000000000..de8507fbb --- /dev/null +++ b/scalos/include/proto/scalosgfx.h @@ -0,0 +1,31 @@ +#ifndef PROTO_SCALOSGFX_H +#define PROTO_SCALOSGFX_H + +#include +#include +extern struct ScalosGfxBase *ScalosGfxBase ; +#ifdef __amigaos4__ +#include +extern struct ScalosGfxIFace *IScalosGfx; +#endif /* __amigaos4__ */ + +#include + +#ifdef __amigaos4__ + #ifdef __USE_INLINE__ + #include + #endif +#elif defined(__GNUC__) + #ifdef __AROS__ + #include + #else + #include + #endif +#elif defined(VBCC) + #include +#else + #include +#endif + +#endif /* PROTO_SCALOSGFX_H */ + diff --git a/scalos/include/proto/scalosmenuplugin.h b/scalos/include/proto/scalosmenuplugin.h new file mode 100755 index 000000000..c1e93dc6e --- /dev/null +++ b/scalos/include/proto/scalosmenuplugin.h @@ -0,0 +1,29 @@ +#ifndef PROTO_SCALOSMENUPLUGIN_H +#define PROTO_SCALOSMENUPLUGIN_H + +#include +extern struct Library *ScalosMenuPluginBase ; +#ifdef __amigaos4__ +#include +extern struct ScalosMenuPluginIFace *IScalosMenuPlugin; +#endif + +#include + +#ifdef __amigaos4__ + #ifdef __USE_INLINE__ + #include + #endif +#elif defined(__GNUC__) + #ifdef __AROS__ + #include + #else + #include + #endif +#elif defined(VBCC) + #include +#else + #include +#endif + +#endif diff --git a/scalos/include/proto/scalosplugin.h b/scalos/include/proto/scalosplugin.h new file mode 100755 index 000000000..011331801 --- /dev/null +++ b/scalos/include/proto/scalosplugin.h @@ -0,0 +1,29 @@ +#ifndef PROTO_SCALOSPLUGIN_H +#define PROTO_SCALOSPLUGIN_H + +#include +extern struct Library *ScalosPluginBase ; +#ifdef __amigaos4__ +#include +extern struct ScalosPluginIFace *IScalosPlugin; +#endif + +#include + +#ifdef __amigaos4__ + #ifdef __USE_INLINE__ + #include + #endif +#elif defined(__GNUC__) + #ifdef __AROS__ + #include + #else + #include + #endif +#elif defined(VBCC) + #include +#else + #include +#endif + +#endif diff --git a/scalos/include/proto/scalosprefsplugin.h b/scalos/include/proto/scalosprefsplugin.h new file mode 100755 index 000000000..fff05ca1c --- /dev/null +++ b/scalos/include/proto/scalosprefsplugin.h @@ -0,0 +1,29 @@ +#ifndef PROTO_SCALOSPREFSPLUGIN_H +#define PROTO_SCALOSPREFSPLUGIN_H + +#include +extern struct Library *ScalosPrefsPluginBase ; +#ifdef __amigaos4__ +#include +extern struct ScalosPrefsPluginIFace *IScalosPrefsPlugin; +#endif + +#include + +#ifdef __amigaos4__ + #ifdef __USE_INLINE__ + #include + #endif +#elif defined(__GNUC__) + #ifdef __AROS__ + #include + #else + #include + #endif +#elif defined(VBCC) + #include +#else + #include +#endif + +#endif /* PROTO_SCALOSPREFSPLUGIN_H */ diff --git a/scalos/include/proto/scalospreviewplugin.h b/scalos/include/proto/scalospreviewplugin.h new file mode 100755 index 000000000..c640bffbf --- /dev/null +++ b/scalos/include/proto/scalospreviewplugin.h @@ -0,0 +1,29 @@ +#ifndef PROTO_SCALOSPREVIEWPLUGIN_H +#define PROTO_SCALOSPREVIEWPLUGIN_H + +#include +extern struct Library *ScalosPreviewPluginBase ; +#ifdef __amigaos4__ +#include +extern struct ScalosPreviewPluginIFace *IScalosPreviewPlugin; +#endif + +#include + +#ifdef __amigaos4__ + #ifdef __USE_INLINE__ + #include + #endif +#elif defined(__GNUC__) + #ifdef __AROS__ + #include + #else + #include + #endif +#elif defined(VBCC) + #include +#else + #include +#endif + +#endif /* PROTO_SCALOSPREVIEWPLUGIN_H */ diff --git a/scalos/include/proto/sqlite3.h b/scalos/include/proto/sqlite3.h new file mode 100755 index 000000000..4d5024c12 --- /dev/null +++ b/scalos/include/proto/sqlite3.h @@ -0,0 +1,30 @@ +#ifndef PROTO_SQLITE3_H +#define PROTO_SQLITE3_H + +#include +#include +extern struct Library *SQLite3Base; +#ifdef __amigaos4__ +#include +extern struct SQLite3IFace *ISQLite3; +#endif + +#include + +#ifdef __amigaos4__ + #ifdef __USE_INLINE__ + #include + #endif +#elif defined(__GNUC__) + #ifdef __AROS__ + #include + #else + #include + #endif +#elif defined(VBCC) + #include +#else + #include +#endif + +#endif diff --git a/scalos/include/proto/titlebarimage.h b/scalos/include/proto/titlebarimage.h new file mode 100755 index 000000000..8200e357a --- /dev/null +++ b/scalos/include/proto/titlebarimage.h @@ -0,0 +1,7 @@ +#ifndef PROTO_TITLEBARIMAGE_H +#define PROTO_TITLEBARIMAGE_H +#include +extern struct Library *TitlebarImageBase; +#include +#include +#endif diff --git a/scalos/include/proto/ttengine.h b/scalos/include/proto/ttengine.h new file mode 100644 index 000000000..53c6ef4cc --- /dev/null +++ b/scalos/include/proto/ttengine.h @@ -0,0 +1,41 @@ +/* Automatically generated header! Do not edit! */ + +#ifndef PROTO_TTENGINE_H +#define PROTO_TTENGINE_H + +#include + +#ifdef __amigaos4__ +# include +#ifdef __USE_INLINE__ + #include +#endif +# ifndef __NOGLOBALIFACE__ + extern struct TTEngineIFace *ITTEngine; +# endif /* __NOGLOBALIFACE__*/ +#else /* !__amigaos4__ */ + +#ifndef _NO_INLINE +# if defined(__GNUC__) +# ifdef __AROS__ +# include +# elif defined(__PPC__) +# include +# else +# include +# endif +# else +# include +# endif +#endif /* _NO_INLINE */ + +# ifndef __NOLIBBASE__ + extern struct Library* +# ifdef __CONSTLIBBASEDECL__ + __CONSTLIBBASEDECL__ +# endif /* __CONSTLIBBASEDECL__ */ + TTEngineBase; +# endif /* !__NOLIBBASE__ */ +#endif /* !__amigaos4__ */ + +#endif /* !PROTO_TTENGINE_H */ diff --git a/scalos/include/scalos/GadgetBar.h b/scalos/include/scalos/GadgetBar.h new file mode 100755 index 000000000..791c0bda4 --- /dev/null +++ b/scalos/include/scalos/GadgetBar.h @@ -0,0 +1,120 @@ +#ifndef SCALOS_GADGETBAR_H +#define SCALOS_GADGETBAR_H +/* +** $VER: GadgetBar.h 41.5 (06 Jan 2006 20:00:13) +** +** $Date$ +** $Revision$ +** +** Scalos.library include +** +** (C) Copyright 2000-2007 The Scalos Team +** All Rights Reserved +** +*/ + +/****************************************************************************/ + +#if defined(__GNUC__) && !defined(mc68000) +#pragma pack(2) +#endif /* __GNUC__ */ + +// +jl+ 20011029 +// Tags for GadgetBar class + +#define SCALOSGADGETBAR_BASE 0x80530400 + +enum GBposition + { + GBPOS_Top, // add GadgetBar at window top + GBPOS_Bottom // add GadgetBar at window bottom + }; + + +#define GB_FIXED_WIDTH ~0 + +/****************************************************************************/ + +// GadgetBar methods + +#define GBCL_UPDATEMEMBER (SCALOSGADGETBAR_BASE+1001) // update GadgetBar member +#define GBCL_HANDLEMOUSEWHEEL (SCALOSGADGETBAR_BASE+1002) // mouse wheel event, uses gpInput + +/****************************************************************************/ + +// GadgetBar attributes + +#define GBDTA_WindowTask (SCALOSGADGETBAR_BASE+1) // [I..] struct ScaWindowTask * +#define GBDTA_Position (SCALOSGADGETBAR_BASE+2) // [I.G] enum GBposition +#define GBDTA_TopSpace (SCALOSGADGETBAR_BASE+3) // [ISG] space at top edge +#define GBDTA_BottomSpace (SCALOSGADGETBAR_BASE+4) // [ISG] space at bottom edge +#define GBDTA_LeftSpace (SCALOSGADGETBAR_BASE+5) // [ISG] space at left edge +#define GBDTA_RightSpace (SCALOSGADGETBAR_BASE+6) // [ISG] space at right edge +#define GBDTA_BetweenSpace (SCALOSGADGETBAR_BASE+7) // [ISG] space between images +#define GBDTA_BGPen (SCALOSGADGETBAR_BASE+8) // [ISG] background fill pen +#define GBDTA_Weight (SCALOSGADGETBAR_BASE+9) // [...] for OM_ADDMEMBER, child weight, default=GB_FIXED_WIDTH + // object weight for non-fixed width, set to GB_FIXED_WIDTH for fixed-width image +#define GBDTA_BackgroundImageName (SCALOSGADGETBAR_BASE+10) // [IS.] CONST_STRPTR file name for (datatypes) backfill image +#define GBDTA_LastActive (SCALOSGADGETBAR_BASE+11) // [..G] (ULONG) GadgetID of most recent active member +#define GBDTA_BackfillHook (SCALOSGADGETBAR_BASE+12) // [...] (struct Hook *) used to forward backfill hook to children +#define GBDTA_Hidden (SCALOSGADGETBAR_BASE+13) // [ISG] (ULONG) Flag for hidden sub-gadgets (hidden due to lack of space) + +/****************************************************************************/ + +// definition to keep compatible with old typo +#define DBDTA_BackgroundImageName GBDTA_BackgroundImageName + +/****************************************************************************/ + +// struct for OM_ADDMEMBER +struct opGBAddMember + { + ULONG MethodID; + struct GadgetInfo *opam_GInfo; + Object *opam_Object; + struct TagItem *opam_AttrList; + }; + +// struct for OM_REMMEMBER +struct opGBRemMember + { + ULONG MethodID; + struct GadgetInfo *oprm_GInfo; + Object *oprm_Object; + }; + +// struct for GBCL_UPDATEMEMBER +struct opGBUpdateMember + { + ULONG MethodID; + struct GadgetInfo *opum_GInfo; + Object *opum_Object; // Member object to update + struct TagItem *opum_AttrList; // currently unused + }; + +/****************************************************************************/ + +// Tags for GadgetBarImageClass + +#define GBIDTA_WindowTask (SCALOSGADGETBAR_BASE+101) // [I..] struct ScaWindowTask * + +/****************************************************************************/ + +// Tags for GadgetBarTextClass + +#define GBTDTA_Text (SCALOSGADGETBAR_BASE+201) // [ISG] STRPTR - Text to display +#define GBTDTA_DrawMode (SCALOSGADGETBAR_BASE+202) // [ISG] ULONG - DrawMode for text (JAM1, JAM2) +#define GBTDTA_Justification (SCALOSGADGETBAR_BASE+203) // [ISG] ULONG - Justification for text (GACT_STRINGLEFT, GACT_STRINGRIGHT, GACT_STRINGCENTER) +#define GBTDTA_TextFont (SCALOSGADGETBAR_BASE+204) // [ISG] struct TextFont * - Font for text +#define GBTDTA_TextPen (SCALOSGADGETBAR_BASE+205) // [ISG] ULONG - Text Pen +#define GBTDTA_BgPen (SCALOSGADGETBAR_BASE+206) // [ISG] ULONG - Background Pen (used if GBTDTA_DrawMode = JAM2) +#define GBTDTA_SoftStyle (SCALOSGADGETBAR_BASE+207) // [ISG] ULONG - SoftStyle for text (bold/italic/...) +#define GBTDTA_TTFont (SCALOSGADGETBAR_BASE+208) // [ISG] struct TTFontFamily * - TTengine Font for text + +/****************************************************************************/ + +#if defined(__GNUC__) && !defined(mc68000) +#pragma pack() +#endif /* __GNUC__ */ + +#endif /* SCALOS_GADGETBAR_H */ diff --git a/scalos/include/scalos/int64types.h b/scalos/include/scalos/int64types.h new file mode 100644 index 000000000..3ea663988 --- /dev/null +++ b/scalos/include/scalos/int64types.h @@ -0,0 +1,42 @@ +// int64types.h +// $Date$ +// $Revision$ + +#ifndef SCALOS_INT64TYPES_H +#define SCALOS_INT64TYPES_H + +#include +#include +#include +#include +#include +#include + +#ifdef __GNUC__ + +typedef unsigned long long ULONG64; +typedef signed long long SLONG64; + +// Macros to acccess one of the longs of an ULONG64 +#define ULONG64_LOW(long64) ((ULONG) ((long64) & 0xffffffff)) +#define ULONG64_HIGH(long64) ((ULONG) (((long64) >> 32) & 0xffffffff)) + +#define SLONG64_LOW(long64) ((SLONG) ((long64) & 0xffffffff)) +#define SLONG64_HIGH(long64) ((SLONG) (((long64) >> 32) & 0xffffffff)) + +#else /* __GNUC__ */ + +typedef struct { ULONG High, Low; } ULONG64; +typedef struct { LONG High; ULONG Low; } SLONG64; + + +// Macros to acccess one of the longs of an ULONG64 +#define ULONG64_LOW(long64) ((long64).Low) +#define ULONG64_HIGH(long64) ((long64).High) + +#define SLONG64_LOW(long64) ((long64).Low) +#define SLONG64_HIGH(long64) ((long64).High) + +#endif /* __GNUC__ */ + +#endif // SCALOS_INT64TYPES_H diff --git a/scalos/include/scalos/menu.h b/scalos/include/scalos/menu.h new file mode 100755 index 000000000..7ac2a66fe --- /dev/null +++ b/scalos/include/scalos/menu.h @@ -0,0 +1,94 @@ +#ifndef PREFS_SCA_MENU_H +#define PREFS_SCA_MENU_H +/* +** $VER: scalos_pattern.h 40.33 (14 Apr 2005 19:41:04) +** +** $Date$ +** $Revision$ +** +** File format for scalos_menu preferences +** +** (C) Copyright 2000-2006 The Scalos Team +** All Rights Reserved +*/ + +// --------------------------------------------------------------------------- + +#ifndef EXEC_TYPES_H +#include +#endif + +#ifndef LIBRARIES_IFFPARSE_H +#include +#endif + +// --------------------------------------------------------------------------- + +#if defined(__GNUC__) && !defined(mc68000) +#pragma pack(2) +#endif /* __GNUC__ */ + +// This is the exact structure that stores menu information in menu preferences files +// !!! BE VERY CAREFUL TO KEEP PREFS COMPATIBLE IF YOU EVER CHANGE THIS STRUCTURE !!! +struct ScalosMenuTree + { + struct ScalosMenuTree *mtre_Next; + struct ScalosMenuTree *mtre_tree; + UBYTE mtre_type; + UBYTE mtre_flags; + union { + struct { + char mtre_hotkey[2]; + STRPTR mtre_name; + STRPTR mtre_iconnames; // only valid if MTREFLGF_IconNames + // points to 2 strings with menu icon path names + // for empty path names, it points to two '\0' + } MenuTree; + struct { + UBYTE mcom_flags; + UBYTE mcom_type; // enum ScalosMenuCommandType + ULONG mcom_stack; + STRPTR mcom_name; + BYTE mcom_pri; // priority for command process + // only valid if MCOMFLGF_Priority set + } MenuCommand; + } MenuCombo; + }; + +enum ScalosMenuType + { + SCAMENUTYPE_MainMenu = 0, + SCAMENUTYPE_Menu, + SCAMENUTYPE_MenuItem, + SCAMENUTYPE_Command, + SCAMENUTYPE_ToolsMenu + }; + +enum ScalosMenuCommandType + { + SCAMENUCMDTYPE_Command = 0, // 0 = Command (internal) + SCAMENUCMDTYPE_Workbench, // 1 = Workbench + SCAMENUCMDTYPE_AmigaDOS, // 2 = AmigaDOS + SCAMENUCMDTYPE_IconWindow, // 3 = Iconwindow + SCAMENUCMDTYPE_ARexx, // 4 = Arexx + SCAMENUCMDTYPE_Plugin // 5 = Menu plugin + }; + +// values in mtre_flags +// bits 0..2 are RESERVED +#define MTREFLGB_IconNames 7 // mtre_iconnames are valid +#define MTREFLGF_IconNames (1 << MTREFLGB_IconNames) + +// values in mcom_flags +#define MCOMFLGB_Args 0 // this command uses arguments +#define MCOMFLGF_Args (1 << MCOMFLGB_Args) +#define MCOMFLGB_Priority 1 // this command uses priority information in mcom_pri +#define MCOMFLGF_Priority (1 << MCOMFLGB_Priority) + +// --------------------------------------------------------------------------- + +#if defined(__GNUC__) && !defined(mc68000) +#pragma pack() +#endif /* __GNUC__ */ + +#endif /* PREFS_SCA_MENU_H */ diff --git a/scalos/include/scalos/palette.h b/scalos/include/scalos/palette.h new file mode 100755 index 000000000..d7f3012d1 --- /dev/null +++ b/scalos/include/scalos/palette.h @@ -0,0 +1,84 @@ +#ifndef PREFS_SCA_PALETTE_H +#define PREFS_SCA_PALETTE_H +/* +** $VER: scalos_palette.h 40.33 (14 Apr 2005 18:56:51) +** +** $Date$ +** $Revision$ +** +** File format for scalos_palette preferences +** +** (C) Copyright 1996-1997 ALiENDESiGN +** (C) Copyright 2000-2005 The Scalos Team +** All Rights Reserved +*/ + +// --------------------------------------------------------------------------- + +#ifndef EXEC_TYPES_H +#include +#endif + +#ifndef LIBRARIES_IFFPARSE_H +#include +#endif + +#if defined(__GNUC__) && !defined(mc68000) +#pragma pack(2) +#endif /* __GNUC__ */ + +// --------------------------------------------------------------------------- + +#define ID_SPAL MAKE_ID('S','P','A','L') +#define ID_PENS MAKE_ID('P','E','N','S') + +// --------------------------------------------------------------------------- + +struct ScaPalettePrefs { + UWORD scl_count; // count of the following colors + UWORD scl_first; // first color, normaly 0 + ULONG scl_colors[1]; // a long for each RGB value +}; + +// the structure is very similar to the LoadRGB32 structure + +// --------------------------------------------------------------------------- + +struct ScalosPen { + WORD sp_pentype; // see below + UWORD sp_pen; // the selected pen + }; + + +struct ScaPensPrefs { + UWORD sce_count; // count of the following colors + struct ScalosPen sce_pen[1]; + }; + + +// constants for ScalosPen.sp_pentype +// a standard Drawinfo Pen or: + +#define SP_HALFSHINE -1 +#define SP_HALFSHADOW -2 +#define SP_OUTLINE -3 +#define SP_DRAWERTEXT -4 +#define SP_DRAWERTEXTSEL -5 +#define SP_DRAWERTBACKGROUND -6 +#define SP_FILETEXT -7 +#define SP_FILETEXTSEL -8 +#define SP_FILEBACKGROUND -9 +#define SP_BACKDROPDETAIL -10 +#define SP_BACKDROPBLOCK -11 +#define SP_TOOLTIP_TEXT -12 +#define SP_TOOLTIP_BG -13 +#define SP_DRAGINFOTEXT_TEXT -14 +#define SP_DRAGINFOTEXT_BG -15 + +// --------------------------------------------------------------------------- + +#if defined(__GNUC__) && !defined(mc68000) +#pragma pack() +#endif /* __GNUC__ */ + +#endif /* PREFS_SCAPALETTE_H */ diff --git a/scalos/include/scalos/pattern.h b/scalos/include/scalos/pattern.h new file mode 100755 index 000000000..791b2bb04 --- /dev/null +++ b/scalos/include/scalos/pattern.h @@ -0,0 +1,166 @@ +#ifndef PREFS_SCA_PATTERN_H +#define PREFS_SCA_PATTERN_H +/* +** $VER: scalos_pattern.h 40.33 (14 Apr 2005 22:27:54) +** +** $Date$ +** $Revision$ +** +** File format for scalos_pattern preferences +** +** (C) Copyright 1996-1997 ALiENDESiGN +** (C) Copyright 2000-2005 The Scalos Team +** All Rights Reserved +*/ + +// --------------------------------------------------------------------------- + +#ifndef EXEC_TYPES_H +#include +#endif + +#ifndef LIBRARIES_IFFPARSE_H +#include +#endif + +#include + +#if defined(__GNUC__) && !defined(mc68000) +#pragma pack(2) +#endif /* __GNUC__ */ + +// --------------------------------------------------------------------------- + +#define ID_PATT MAKE_ID('P','A','T','T') +#define ID_DEFS MAKE_ID('D','E','F','S') +#define ID_TCOL MAKE_ID('T','C','O','L') +#define ID_TBMP MAKE_ID('T','B','M','P') + +// --------------------------------------------------------------------------- + +// default pattern numbers + +#define PATTERNNR_WorkbenchDefault (SHRT_MAX-1) +#define PATTERNNR_IconWindowDefault (SHRT_MAX-2) +#define PATTERNNR_TextWindowDefault (SHRT_MAX-3) + +// --------------------------------------------------------------------------- + +// TCOL structure + +struct ScaPatternPrefsThumbnailColors + { + UWORD stc_NumColors; // Number of entries in color table + // always <= 256 + UBYTE stc_ColorTable[0]; // color table, contains entries + // with 3 x UBYTE each + }; + +// --------------------------------------------------------------------------- + +// TBMP structure + +struct ScaPatternPrefsBitMap + { + UWORD spb_Width; // BitMap width + UWORD spb_Height; // BitMap height + + UBYTE spb_BitMapArray[0]; // Array for BitMap pen numbers, sized + // spb_Width * spb_Height bytes + // ready to use for WritePixelArray8() + }; + +// --------------------------------------------------------------------------- + +// PATT Structure + +struct ScaPatternPrefs +{ + UWORD scp_Number; // Which pattern is it + UWORD scp_RenderType; // render type (see below) + UWORD scp_Flags; // see below + UWORD scp_NumColors; // number of colors to use for + // remapping (enhanced mode) + UWORD scp_DitherMode; // render.library dithermode + UWORD scp_DitherAmount; // render.library ditheramount + BYTE scp_Precision; // Pen Precision (OBP_Precision) + UBYTE scp_Type; // Type of Pattern (see below) + + UBYTE scp_color1[3]; // rrggbb values for background color (SCP_RenderType_Centered) + UBYTE scp_color2[3]; // rrggbb values for second background color +}; + +struct ScaExtPatternPrefs +{ + struct ScaPatternPrefs scxp_PatternPrefs; + char scxp_Name[512]; // Filename or Pattern +}; + +// scp_Flags values +#define SCPF_NOREMAP (1L<<0) +#define SCPF_ENHANCED (1L<<1) +#define SCPF_AUTODITHER (1L<<2) + +// scp_RenderType values +enum ScpRenderType + { + SCP_RenderType_Tiled = 0, + SCP_RenderType_FitSize, + SCP_RenderType_Centered, + SCP_RenderType_ScaledMin, // similar to SCP_RenderType_FitSize, + // but keeps aspect of original image. + // Can leave empty stripes on window top/bottom or left/right borders + SCP_RenderType_ScaledMax, // similar to SCP_RenderType_FitSize, + // but keeps aspect of original image. + // Creates no empty stripes on window borders, + // but stripes of image may fall outside of window + }; + +// scp_DitherMode values +#ifndef DITHERMODE_NONE +#define DITHERMODE_NONE 0 +#define DITHERMODE_FS 1 +#define DITHERMODE_RANDOM 2 +#endif /* DITHERMODE_NONE */ + +// scp_Type +enum ScpBgType + { + SCP_BgType_Picture = 0, // Picture only, no background color + SCP_BgType_SingleColor, // Optional Picture with single background color + SCP_BgType_HorizontalGradient, // Optional Picture with horizontal gradient + SCP_BGType_VerticalGradient, // Optional Picture with vertical gradient + }; + +// --------------------------------------------------------------------------- + +// DEFS Structure + +struct ScaPatternDefs +{ + UWORD scd_Flags; // see below + UWORD scd_WorkbenchPattern; // def PatternNum for the Main window + UWORD scd_ScreenPattern; // def PatternNum for the Screen + UWORD scd_WindowPattern; // def PatternNum for windows + UWORD scd_TextModePattern; // def PatternNum for Textmode + BYTE scd_TaskPriority; // asynchronous taskpri + UBYTE scd_Reserved[1]; +}; + +// scd_Flags +#define SCDB_ASYNCLAYOUT 0 +#define SCDF_ASYNCLAYOUT (1L< +#endif + +#ifndef DOS_NOTIFY_H +#include +#endif + +#ifndef EXEC_LISTS_H +#include +#endif + +#ifndef EXEC_PORTS_H +#include +#endif + +#ifndef INTUITION_CLASSES_H +#include +#endif + +#ifndef INTUITION_CLASSUSR_H +#include +#endif + +#ifndef DATATYPES_ICONOBJECT_H +#include +#endif + +#ifndef REXX_STORAGE_H +#include +#endif + +#ifndef WORKBENCH_STARTUP_H +#include +#endif + +#ifndef WORKBENCH_WORKBENCH_H +#include +#endif + +#ifndef DEVICES_TIMER_H +#include +#endif + +#ifndef GRAPHICS_GFX_H +#include +#endif + +#ifndef GRAPHICS_REGIONS_H +#include +#endif + +# +#ifndef SCALOS_SCALOSGFX_H +#include +#endif + +#ifndef SCALOS_UNDO_H +#include +#endif + +#ifndef SCALOS_INT64TYPES_H +#include +#endif + +#define SCALOSNAME "scalos.library" + +#if defined(__GNUC__) && !defined(mc68000) +#pragma pack(2) +#endif /* __GNUC__ */ + +// --------------------------------------------------------------------------- + +#if !defined(SCALOSSEMAPHORE) +#define SCALOSSEMAPHORE struct SignalSemaphore +#endif /* SCALOSSEMAPHORE */ + +#if !defined(TIMEVAL_TYPE_DEFINED) +#define TIMEVAL_TYPE_DEFINED +#if defined(__NEW_TIMEVAL_DEFINITION_USED__) + typedef struct TimeVal T_TIMEVAL; + typedef struct TimeRequest T_TIMEREQUEST; + #define tr_node Request + #define tr_time Time + #define tv_secs Seconds + #define tv_micro Microseconds +#else //defined(__amigaos4__) && defined(__NEW_TIMEVAL_DEFINITION_USED__) + typedef struct timeval T_TIMEVAL; + typedef struct timerequest T_TIMEREQUEST; +#endif //defined(__NEW_TIMEVAL_DEFINITION_USED__) +#endif //!defined(TIMEVAL_TYPE_DEFINED) + +// --------------------------------------------------------------------------- +// forward declarations + +struct internalScaWindowTask; + +// --------------------------------------------------------------------------- + +#define SCA_TagBase 0x80530000 + +#define SCA_IconObject (SCA_TagBase+1) // Object * - IconObject to use when opening a drawer +#define SCA_Stacksize (SCA_TagBase+2) +#define SCA_Flags (SCA_TagBase+3) +#define SCA_IconNode (SCA_TagBase+4) +#define SCA_WindowTitle (SCA_TagBase+5) +#define SCA_Path (SCA_TagBase+6) +#define SCA_WindowRect (SCA_TagBase+7) +#define SCA_XOffset (SCA_TagBase+8) +#define SCA_YOffset (SCA_TagBase+9) +#define SCA_PatternNumber (SCA_TagBase+10) // see pattern.h +#define SCA_ShowAllFiles (SCA_TagBase+11) // obsolete, use SCA_ShowAllMode instead! +#define SCA_ViewModes (SCA_TagBase+12) +#define SCA_MessagePort (SCA_TagBase+13) +#define SCA_Iconify (SCA_TagBase+14) +#define SCA_ClassName (SCA_TagBase+15) +#define SCA_Class (SCA_TagBase+16) +#define SCA_WaitTimeout (SCA_TagBase+17) // +jl+ 20010324 +#define SCA_SemaphoreExclusive (SCA_TagBase+18) // +jl+ 20010408 +#define SCA_SemaphoreShared (SCA_TagBase+19) // +jl+ 20010408 +#define SCA_NoStatusBar (SCA_TagBase+20) // +jl+ 20011111 +#define SCA_NoActivateWindow (SCA_TagBase+21) // +jl+ 20020512 +#define SCA_Priority (SCA_TagBase+22) // +jl+ 20020823 +#define SCA_WindowStruct (SCA_TagBase+23) // +jl+ 20021204 +#define SCA_SemaphoreExclusiveNoNest (SCA_TagBase+24) // +jl+ 20040904 +#define SCA_ShowAllMode (SCA_TagBase+25) // one of the workbench DDFLAGS_*** values +#define SCA_IconList (SCA_TagBase+26) // struct ScaIconNode * +#define SCA_BrowserMode (SCA_TagBase+27) // ULONG +//#define SCA_HideStatusBar (SCA_TagBase+28) // ULONG ***obsolete, use SCA_NoStatusBar instead*** +#define SCA_CheckOverlappingIcons (SCA_TagBase+29) // ULONG +#define SCA_TransparencyActive (SCA_TagBase+30) // ULONG - percentage of opacity in active window state, 0=transparent, 100=opaque +#define SCA_TransparencyInactive (SCA_TagBase+31) // ULONG - percentage of opacity in inactive window state, 0=transparent, 100=opaque +#define SCA_DdPopupWindow (SCA_TagBase+32) // ULONG - Flag: this window has popped up during D&D operation +#define SCA_NoControlBar (SCA_TagBase+33) // don't display control bar for this window + +#define SCAB_WBStart_NoIcon 0 +#define SCAB_WBStart_Wait 1 +#define SCAB_WBStart_PathSearch 2 +#define SCAB_WBStart_NoIconCheck 3 + +#define SCAF_WBStart_NoIcon (1L << SCAB_WBStart_NoIcon) +#define SCAF_WBStart_Wait (1L << SCAB_WBStart_Wait) +#define SCAF_WBStart_PathSearch (1L << SCAB_WBStart_PathSearch) +#define SCAF_WBStart_NoIconCheck (1L << SCAB_WBStart_NoIconCheck) + +#define SCAV_WBStart_NoIcon SCAF_WBStart_NoIcon +#define SCAV_WBStart_Wait SCAF_WBStart_Wait +#define SCAV_WBStart_PathSearch SCAF_WBStart_PathSearch +#define SCAV_WBStart_NoIconCheck SCAF_WBStart_NoIconCheck + +#define SCAB_OpenWindow_ScalosPort 0 // private +#define SCAF_OpenWindow_ScalosPort (1 << SCAB_OpenWindow_ScalosPort) + +// LockWindowList(): +#define SCA_LockWindowList_Shared 0 +#define SCA_LockWindowList_Exclusiv 1 +#define SCA_LockWindowList_AttemptShared 2 +#define SCA_LockWindowList_AttemptExclusive 3 + +// FreeWBArgs(): +#define SCAV_FreeLocks 1 +#define SCAB_FreeLocks 0 +#define SCAF_FreeLocks (1 << SCAB_FreeLocks) +#define SCAV_FreeNames 2 +#define SCAB_FreeNames 1 +#define SCAF_FreeNames (1 << SCAB_FreeNames) + +#define SCA_SortType_Bubble 0 +#define SCA_SortType_Selection 1 +#define SCA_SortType_Insertion 2 +#define SCA_SortType_Quick 3 +#define SCA_SortType_Best -1 + +// window dropmark types +enum WindowDropMarkTypes + { + IDTV_WinDropMark_Never, // never show any window dropmarks + IDTV_WinDropMark_WindowedOnly, // non-backdrop windows only + IDTV_WinDropMark_Always // always show window dropmarks + }; + +// ---------------------- NodeTypes for AllocStdNode() ------------------------ + +#define NTYP_IconNode 0 +#define NTYP_WindowStruct 1 +#define NTYP_DragNode 2 +#define NTYP_PatternNode 3 +#define NTYP_ScalosArg 4 +#define NTYP_DeviceIcon 5 +#define NTYP_AppObject 8 +#define NTYP_MenuInfo 9 +#define NTYP_PluginClass 10 // +jl+ +#define NTYP_PluginNode 11 // +jl+ + +// ------------------------ MessageTypes for AllocMsg() ----------------------- + +#define MTYP_DropProc 1 +#define MTYP_CloseWindow 2 +#define MTYP_StartWindow 3 +#define MTYP_Timer 4 +#define MTYP_Requester 5 +#define MTYP_NewPattern 6 +#define MTYP_Sleep 7 +#define MTYP_Wakeup 8 +#define MTYP_AsyncRoutine 9 +#define MTYP_RunProcess 10 +#define MTYP_AppSleep 11 +#define MTYP_AppWakeup 12 +#define MTYP_Redraw 13 +#define MTYP_Update 14 +#define MTYP_UpdateIcon 15 +#define MTYP_AddIcon 16 +#define MTYP_RemIcon 17 +#define MTYP_ARexxRoutine 18 +#define MTYP_Iconify 19 +#define MTYP_UnIconify 20 +#define MTYP_AsyncBackFill 21 +#define MTYP_ShowTitle 22 +#define MTYP_RunMenuCmd 23 // +jl+ 20010415 +#define MTYP_ShowPopupMenu 24 // +jl+ 20011209 +#define MTYP_ShowStatusBar 25 // +jl+ 20040919 +#define MTYP_RedrawIcon 26 // +jl+ 20050303 +#define MTYP_DoPopupMenu 27 // +jl+ 20050319 +#define MTYP_RedrawIconObj 28 +#define MTYP_NewPreferences 29 +#define MTYP_DeltaMove 30 +#define MTYP_SetThumbnailImage_Remapped 31 +#define MTYP_SetThumbnailImage_ARGB 32 +#define MTYP_NewWindowPath 33 +#define MTYP_PrefsChanged 34 +#define MTYP_StartChildProcess 35 +#define MTYP_RootEvent 36 +#define MTYP_ShowControlBar 37 + +#define MTYP_MAX 38 // must always be 1 larger than last MTYP_??5 + +// --------------------------------------------------------------------------- + +enum ScanDirResult + { + SCANDIR_OK, // everything worked, continue + SCANDIR_FAIL_ABORT, // fatal error, abort + SCANDIR_FAIL_RETRY, // maybe recoverable error, continue + SCANDIR_EXALL_FAIL, // ExAll failed, retry with Examine + SCANDIR_EXALL_BADNUMBER, // ExAll failed, retry with lower rilc_ExAllType + SCANDIR_ABORT, // externally aborted + SCANDIR_FINISHED, // dir scan finished, end + SCANDIR_VIEWMODE_CHANGE, // window view mode changed + SCANDIR_WINDOW_CLOSING, // Window is about to be closed + }; + +enum ScalosSortOrder +{ + SortOrder_Default, + SortOrder_Ascending, + SortOrder_Descending +}; + +struct ScaWindowList +{ + struct ScaWindowStruct *wl_WindowStruct; // Pointer to the first windowstruct + struct ScaWindowStruct *ml_MainWindowStruct; // Pointer into the list of windowstructs + struct ScaWindowStruct *ml_AppWindowStruct; // dito - windowstruct for AppIcons +}; + +struct ScaWindowStruct +{ + struct MinNode ws_Node; + struct Process *ws_Task; // Window-Task address + BPTR ws_Lock; // filelock to the windows directory + struct Window *ws_Window; // pointer to the window or NULL + struct MsgPort *ws_MessagePort; // the API-messageport + WORD ws_Left; + WORD ws_Top; + WORD ws_Width; + WORD ws_Height; // size and position of the window + WORD ws_xoffset; + WORD ws_yoffset; // the virtual position inside + APTR ws_PatternNode; + struct ScaWindowTask *ws_WindowTask; // windowtask structure + STRPTR ws_Name; // windows name (is displayed in the title) + STRPTR ws_Title; // title-formatstring + STRPTR ms_ClassName; // scalos class name + Class *ms_Class; // BOOPSI Class if ms_classname is NULL + UWORD ws_Flags; // see below + WORD ws_PatternNumber; // number of the pattern + UBYTE ws_Viewmodes; // see below + UBYTE ws_WindowType; // see below + STRPTR ws_WindowTaskName; // name of window task +jl+ 20011211 + UWORD ws_ViewAll; // DDFLAGS_SHOWDEFAULT, DDFLAGS_SHOWICONS, or DDFLAGS_SHOWALL + ULONG ws_ThumbnailView; // THUMBNAILS_Never, THUMBNAILS_Always, THUMBNAILS_AsDefault + ULONG ws_ThumbnailsLifetimeDays; //Maximum lifetime for generated thumbnails + enum ScalosSortOrder ws_SortOrder; // current sorting or ascending or descending + UWORD ws_WindowOpacityActive; // percentage of active Scalos Window transparency - not used on all platforms! + // (0=PREFS_TRANSPARENCY_TRANSPARENT=invisible, 100=PREFS_TRANSPARENCY_OPAQUE=opaque) + UWORD ws_WindowOpacityInactive; // percentage of inactive Scalos Window transparency - not used on all platforms! + struct Rectangle ws_IconSizeConstraints; // size limits for icons, larger or smaller icons are scaled + UWORD ws_IconScaleFactor; // icon scaling factor in percent + ULONG ws_MoreFlags; // various flags, see below +}; + +// ws_Flags: +#define WSV_FlagB_RootWindow 0 // a RootDir window +#define WSV_FlagF_RootWindow (1 << WSV_FlagB_RootWindow) +#define WSV_FlagB_NeedsTimerMsg 1 // window likes to get TimerMessages +#define WSV_FlagF_NeedsTimerMsg (1 << WSV_FlagB_NeedsTimerMsg) +#define WSV_FlagB_Backdrop 2 // is the window in backdrop mode +#define WSV_FlagF_Backdrop (1 << WSV_FlagB_Backdrop) +#define WSV_FlagB_TimerMsgSent 3 // timermsg already sent *PRIVATE* +#define WSV_FlagF_TimerMsgSent (1 << WSV_FlagB_TimerMsgSent) +#define WSV_FlagB_TaskSleeps 4 // windowtask is sleeping +#define WSV_FlagF_TaskSleeps (1 << WSV_FlagB_TaskSleeps) +#define WSV_FlagB_ShowAllFiles 5 // just what it said +#define WSV_FlagF_ShowAllFiles (1 << WSV_FlagB_ShowAllFiles) +#define WSV_FlagB_Iconify 6 // windowtask is in iconify state +#define WSV_FlagF_Iconify (1 << WSV_FlagB_Iconify) +#define WSV_FlagB_CheckUpdatePending 7 // IconWinCheckUpdate() is pending *PRIVATE* +#define WSV_FlagF_CheckUpdatePending (1 << WSV_FlagB_CheckUpdatePending) +#define WSV_FlagB_ActivatePending 8 // ActivateWindow() has been issued *PRIVATE* +#define WSV_FlagF_ActivatePending (1 << WSV_FlagB_ActivatePending) +#define WSV_FlagB_Typing 9 // typing name for keyboard icon selection *PRIVATE* +#define WSV_FlagF_Typing (1L << WSV_FlagB_Typing) +#define WSV_FlagB_NoStatusBar 10 // don't display status bar for this window +#define WSV_FlagF_NoStatusBar (1L << WSV_FlagB_NoStatusBar) +#define WSV_FlagB_NoActivateWindow 11 // don't activate window on OpenWindow() +#define WSV_FlagF_NoActivateWindow (1L << WSV_FlagB_NoActivateWindow) +#define WSV_FlagB_RefreshPending 12 // IDCMP_REFRESHWINDOW could not be processed, refresh is pending *PRIVATE* +#define WSV_FlagF_RefreshPending (1 << WSV_FlagB_RefreshPending) +#define WSV_FlagB_BrowserMode 13 // enable single-window browser mode +#define WSV_FlagF_BrowserMode (1 << WSV_FlagB_BrowserMode) +#define WSV_FlagB_CheckOverlappingIcons 14 // prevent icons from overlapping each other +#define WSV_FlagF_CheckOverlappingIcons (1 << WSV_FlagB_CheckOverlappingIcons) +#define WSV_FlagB_DdPopupWindow 15 // this window has popped up during a D&D operation +#define WSV_FlagF_DdPopupWindow (1 << WSV_FlagB_DdPopupWindow) + +// ws_MoreFlags +#define WSV_MoreFlagB_NoControlBar 0 // don't display control bar for this window +#define WSV_MoreFlagF_NoControlBar (1L << WSV_MoreFlagB_NoControlBar) + +// ws_WindowType: +#define WSV_Type_IconWindow 0 // Window filled with icons +#define WSV_Type_DeviceWindow 1 +#define WSV_Type_DesktopWindow WSV_Type_DeviceWindow // synonym for WSV_Type_DeviceWindow + +// ws_Viewmodes +#define SCAV_ViewModes_Default IDTV_ViewModes_Default +#define SCAV_ViewModes_Icon IDTV_ViewModes_Icon +#define SCAV_ViewModes_Name IDTV_ViewModes_Name +#define SCAV_ViewModes_Size IDTV_ViewModes_Size +#define SCAV_ViewModes_Date IDTV_ViewModes_Date +#define SCAV_ViewModes_Time IDTV_ViewModes_Time +#define SCAV_ViewModes_Comment IDTV_ViewModes_Comment +#define SCAV_ViewModes_Protection IDTV_ViewModes_Protection +#define SCAV_ViewModes_Owner IDTV_ViewModes_Owner +#define SCAV_ViewModes_Group IDTV_ViewModes_Group +#define SCAV_ViewModes_Type IDTV_ViewModes_Type +#define SCAV_ViewModes_Version IDTV_ViewModes_Version +#define SCAV_ViewModes_MiniIcon IDTV_ViewModes_MiniIcon + +// for compatibility +jl+ +#define SIV_IconWin WSV_Type_IconWindow +#define SIV_DeviceWin WSV_Type_DeviceWindow + +// ------------------------------------------------------------------ + +struct PatternInfo + { + struct Hook ptinf_hook; //Backfill Hook + WORD ptinf_width; //Width + WORD ptinf_height; //and Height of Bitmap in Pixels + struct BitMap *ptinf_bitmap; //Bitmap or NULL + APTR ptinf_pattern; //Pattern Array or NULL + UWORD ptinf_flags; //see below + WORD ptinf_pad; //padword + LONG ptinf_BgPen; //Allocated pen for background pattern + struct Message *ptinf_message; //Message + }; + +// ------------------------------------------------------------------ + +struct ScaWindowTask { + struct PatternInfo wt_PatternInfo; + WORD wt_XOffset; + WORD wt_YOffset; // Innerwindow offset + APTR mt_MainObject; // main ScalosClass object + APTR mt_WindowObject; // "Window.sca" object + struct Window *wt_Window; // pointer to the window of the task or NULL + struct ScaIconNode *wt_IconList; // Pointer to the first IconNode + struct ScaIconNode *wt_LateIconList; // Pointer to the first IconNode of all not yet + // displayed icons (e.g. non-position icon while + // loading) + SCALOSSEMAPHORE *wt_IconSemaphore; // Semaphore to access the wt_IconList/wt_LateIconList + // It *MUST* be locked before accessing the list. + // Shared lock should be used for read-only access + struct MsgPort *wt_IconPort; // MessagePort of the windowtask + SCALOSSEMAPHORE *wt_WindowSemaphore; // Semaphore to avoid the task from closing + struct ScaWindowStruct *mt_WindowStruct; // Pointer to the WindowStruct of this task +}; // It's only the documented end of this structure. + // In reality it's much bigger. +// ------------------------------------------------------------------ + +// some structure forward declarations +struct SM_RunProcess; + +// Function pointer definitions +// for some SM_ messages + +typedef void (*ASYNCROUTINEFUNC)(struct ScaWindowTask *, APTR); +typedef void (*AREXXFUNC)(struct ScaWindowTask *, struct RexxMsg *); +typedef ULONG (*RUNPROCFUNC)(APTR, struct SM_RunProcess *); + +// ------------------------------------------------------------------ + +#define ID_IMSG MAKE_ID('I','M','S','G') + +struct ScalosMessage + { + struct Message sm_Message; + ULONG sm_Signature; // ID_IMSG + ULONG sm_MessageType; // SCA_AllocMessage() type + }; + +struct UpdateIconData + { + struct WBArg uid_WBArg; + ULONG uid_IconType; + }; + +struct SM_CloseWindow + { + struct ScalosMessage ScalosMessage; + }; + +struct SM_StartWindow + { + struct ScalosMessage ScalosMessage; + struct ScaWindowStruct *WindowStruct; + }; + +struct SM_Timer + { + struct ScalosMessage ScalosMessage; + struct ScaWindowStruct *smtm_WindowStruct; + T_TIMEVAL smtm_Time; + }; + +struct SM_NewPattern + { + struct ScalosMessage ScalosMessage; + APTR smnp_PatternNode; // PatternNode or NULL + }; + +struct SM_Sleep + { + struct ScalosMessage ScalosMessage; + }; + +struct SM_Wakeup + { + struct ScalosMessage ScalosMessage; + ULONG smwu_ReLayout; // BOOL + }; + +struct SM_ShowTitle + { + struct ScalosMessage ScalosMessage; + ULONG smst_showTitle; // BOOL + }; + +struct SM_AsyncRoutine + { + struct ScalosMessage ScalosMessage; + ASYNCROUTINEFUNC smar_EntryPoint;/* address of start of code to execute */ + // code will be executed with pointer to ScaWindowTask in A5 + // and pointer to smar_Args in A0 + // so, Message can easily be extended to pass arguments. + // Result from routine will be placed in EntryPoint + UBYTE smar_Args[0]; + }; + +struct SM_RunProcess + { + struct ScalosMessage ScalosMessage; + struct ScaWindowTask *WindowTask; + RUNPROCFUNC EntryPoint; // address of start of code to execute + // EntryPoint gets called with address of + // and pointer to SM_RunProcess message + + ULONG Flags; // dunno, but it's long and it's used + // might have additional space here, depending on RunProcess() "NumLongs" parameter. + }; + + +struct SM_AppSleep + { + struct ScalosMessage ScalosMessage; + }; + +struct SM_AppWakeup + { + struct ScalosMessage ScalosMessage; + ULONG smaw_ReLayout; // BOOL + }; + +struct SM_Redraw + { + struct ScalosMessage ScalosMessage; + ULONG smmr_Flags; // see below + }; + +struct SM_Update + { + struct ScalosMessage ScalosMessage; + }; + +struct SM_UpdateIcon + { + struct ScalosMessage ScalosMessage; + BPTR smui_DirLock; + CONST_STRPTR smui_IconName; + ULONG smui_IconType; // indication for icon type, if known + // like WBDRAWER, leave at 0 if unknown + }; + +struct SM_AddIcon + { + struct ScalosMessage ScalosMessage; + UWORD smai_x; + UWORD smai_y; + BPTR smai_DirLock; /* +jl+ 20010217 */ + STRPTR smai_IconName; /* +jl+ 20010217 */ + }; + +struct SM_RemIcon + { + struct ScalosMessage ScalosMessage; + BPTR smri_DirLock; /* +jl+ 20010217 */ + STRPTR smri_IconName; /* +jl+ 20010217 */ + }; + +struct SM_Iconify + { + struct ScalosMessage ScalosMessage; + }; + +struct SM_UnIconify + { + struct ScalosMessage ScalosMessage; + }; + +struct SM_Requester + { + struct ScalosMessage ScalosMessage; + union { + ULONG smrq_ReqResult; // Result from EasyRequest() + struct Window *smrq_ParentWindow; + } smrq_MultiPurpose; + APTR smrq_ArgList; // pointer to ArgList + struct EasyStruct smrq_ez; + UBYTE smrq_ArgListBuffer[0]; // buffer for ArgList - allocated as large as needed + }; + +struct SM_AsyncBackFill + { + struct ScalosMessage ScalosMessage; + RUNPROCFUNC smab_BackfillFunc; // Backfill function entry point + struct PatternNode *smab_PatternNode; + struct PatternInfo *smab_PatternInfo; + struct Screen *smab_Screen; + struct ScaWindowTask *smab_WindowTask; + UBYTE smab_PatternInfoCopy[0]; + }; + +struct SM_ARexxRoutine + { + struct ScalosMessage ScalosMessage; + AREXXFUNC smrx_EntryPoint; + struct RexxMsg *smrx_RexxMsg; + }; + +struct SM_MenuCmd + { + struct SM_AsyncRoutine smc_AsyncRoutine; + ULONG smc_Flags; + struct ScaIconNode *smc_IconNode; + }; + +struct SM_RunMenuCmd + { + struct ScalosMessage ScalosMessage; + struct ScalosMenuTree *smrm_MenuItem; + struct ScaIconNode *smrm_IconNode; + ULONG smrm_Flags; + }; + +struct SM_RealUpdateIcon + { + struct SM_AsyncRoutine rui_AsyncRoutine; + struct UpdateIconData rui_Args; + }; + +struct SM_ShowPopupMenu + { + struct ScalosMessage ScalosMessage; + struct PopupMenu *smpm_PopupMenu; + struct ScaIconNode *smpm_IconNode; + ULONG smpm_Flags; + struct FileTypeDef *smpm_FileType; + UWORD smpm_Qualifier; // the smpm_Qualifier field is a copy of the current IntuiMessage's Qualifier + }; + +// values in smpm_Flags - same as in mpm_Flags + +struct SM_ShowStatusBar + { + struct ScalosMessage ScalosMessage; + BOOL smsb_Visible; + }; + +struct SM_ShowControlBar + { + struct ScalosMessage ScalosMessage; + BOOL smcb_Visible; + }; + +struct SM_RedrawIcon + { + struct ScalosMessage ScalosMessage; + struct ScaIconNode *smri_Icon; + }; + +struct SM_DoPopupMenu + { + struct ScalosMessage ScalosMessage; + struct InputEvent smdpm_InputEvent; + }; + +struct SM_RedrawIconObj + { + struct ScalosMessage ScalosMessage; + Object *smrio_IconObject; + ULONG smrio_Flags; + }; + +// values in smrio_Flags +#define SMRIOFLAGB_EraseIcon 0 +#define SMRIOFLAGB_FreeLayout 1 +#define SMRIOFLAGB_Highlight 2 // set this flag to indicate that there is only a change in icon highlighting state +#define SMRIOFLAGB_IconListLocked 3 // flag: icon list is currently locked +#define SMRIOFLAGB_HightlightOn 4 // flag: set ICONOBJ_USERFLAGF_DrawHighlite before drawing +#define SMRIOFLAGB_HightlightOff 5 // flag: clear ICONOBJ_USERFLAGF_DrawHighlite before drawing +#define SMRIOFLAGF_EraseIcon (1L << SMRIOFLAGB_EraseIcon) +#define SMRIOFLAGF_FreeLayout (1L << SMRIOFLAGB_FreeLayout) +#define SMRIOFLAGF_Highlight (1L << SMRIOFLAGB_Highlight) +#define SMRIOFLAGF_IconListLocked (1L << SMRIOFLAGB_IconListLocked) +#define SMRIOFLAGF_HightlightOn (1L << SMRIOFLAGB_HightlightOn) +#define SMRIOFLAGF_HightlightOff (1L << SMRIOFLAGB_HightlightOff) + +struct SM_NewPreferences + { + struct ScalosMessage ScalosMessage; + ULONG smnp_PrefsFlags; + }; + +// values in smnp_PrefsFlags +// one bit is set for each changed subsystem prefs +#define SMNPFLAGB_PATTERNPREFS 0 +#define SMNPFLAGB_MENUPREFS 1 +#define SMNPFLAGB_FONTPREFS 2 +#define SMNPFLAGB_SCALOSPREFS 3 +#define SMNPFLAGB_PALETTEPREFS 4 +#define SMNPFLAGB_DEFICONSPREFS 5 +#define SMNPFLAGB_LOCALEPREFS 6 +#define SMNPFLAGB_FILETYPESPREFS 7 + +#define SMNPFLAGF_PATTERNPREFS (1L << SMNPFLAGB_PATTERNPREFS) +#define SMNPFLAGF_MENUPREFS (1L << SMNPFLAGB_MENUPREFS) +#define SMNPFLAGF_FONTPREFS (1L << SMNPFLAGB_FONTPREFS) +#define SMNPFLAGF_SCALOSPREFS (1L << SMNPFLAGB_SCALOSPREFS) +#define SMNPFLAGF_PALETTEPREFS (1L << SMNPFLAGB_PALETTEPREFS) +#define SMNPFLAGF_DEFICONSPREFS (1L << SMNPFLAGB_DEFICONSPREFS) +#define SMNPFLAGF_LOCALEPREFS (1L << SMNPFLAGB_LOCALEPREFS) +#define SMNPFLAGF_FILETYPESPREFS (1L << SMNPFLAGB_FILETYPESPREFS) + +struct SM_DeltaMove + { + struct ScalosMessage ScalosMessage; + LONG smdm_DeltaX; + LONG smdm_DeltaY; + ULONG smdm_AdjustSlider; + }; + +struct SM_SetThumbnailImage_Remapped + { + struct ScalosMessage ScalosMessage; + Object *smtir_IconObject; // the icon to attach the new image to + struct ScalosBitMapAndColor *smtir_NewImage; // the new image. ScalosBitMapAndColor contents is freed by message handler + }; + +struct SM_SetThumbnailImage_ARGB + { + struct ScalosMessage ScalosMessage; + Object *smtia_IconObject; // the icon to attach the new image to + struct ARGBHeader smtia_NewImage; // the new image. ARGBHeader contents is freed by message handler + }; + +struct SM_NewWindowPath + { + struct ScalosMessage ScalosMessage; + STRPTR smnwp_Path; // Path of the new drawer to display in the window + struct TagItem *smnwp_TagList; + }; + +struct SM_PrefsChanged + { + struct ScalosMessage ScalosMessage; + ULONG smpc_Flags; + }; + +struct SM_StartChildProcess + { + struct ScalosMessage ScalosMessage; + struct ScaWindowTask *smscp_WindowTask; + }; + +struct SM_RootEvent + { + struct ScalosMessage ScalosMessage; + ULONG smre_MethodID; // the MethodID of the event + APTR smre_EventHandle; // the handle that had been returned by SCCM_AddListener + Class *smre_Class; // Class variable of the method call + Object *smre_Object; // Object variable of the method call + Msg smre_Message; // msg variable of the method call - might no longer be valid when event is received! + }; + +// ------------------------------------------------------------------ + +struct ScaBackdropIcon + { + struct MinNode sbi_Node; + Object *sbi_Icon; // IconObject from iconobject.library + struct NotifyRequest *sbi_NotifyReq; + STRPTR sbi_DrawerName; // full name of parent directory + }; + + +// This structure WILL grow in the future. Do not rely on its size! +// Do NOT ALLOCATE ScaIconNode's yourself! +// Do NOT MODIFY any member on your own ! +struct ScaIconNode +{ + struct MinNode in_Node; + Object *in_Icon; // IconObject from iconobject.library + STRPTR in_Name; // Filename of the icon + struct ScaDeviceIcon *in_DeviceIcon; // NULL except for disk icons + BPTR in_Lock; // for backdrop (left-out) icons, this lock + // points to the original icon dir. + struct ScaBackdropIcon *in_IconList; // list of linked icons (used for backdrop icons) + // Contains a list of ad hoc created ScaBackdropIcon's where + // each in_Icon points to in_Icon of the corresponding + // "left-out" icon. + UWORD in_Flags; // see below + UWORD in_Userdata; + struct DateStamp in_DateStamp; // +jl+ datestamp when the icon was read + ULONG in_SupportFlags; // +jl+ Flags to determine which kind of menu + // operation this specific icon supports. see below + const struct TypeNode *in_FileType; // +jl+ this icon's file type + + struct DateStamp in_FileDateStamp; // +jl+ the file's datestamp + ULONG in_FileSize; // +jl+ size of the file, 0 for drawers + + WORD in_OldLeftEdge; + WORD in_OldTopEdge; +}; + +// in_Flags: +#define INB_DefaultIcon 0 // the icon has diskobject +#define INB_File 1 // File or Drawer (TextMode only) +#define INB_TextIcon 2 // TextMode icon +#define INB_Sticky 3 // icon not moveable +#define INB_DropMarkVisible 4 // Icon drop mark current visible +#define INB_VolumeWriteProtected 5 // volume is write-protected +#define INB_FreeIconPosition 6 // Icon is stored with "no position" +#define INB_IconVisible 7 // Icon has been drawn +#define INB_Identified 8 // Icon file type has been determined + +#define INF_DefaultIcon (1L< +#endif + +#ifndef INTUITION_IMAGECLASS_H +#include +#endif + +#ifndef DATATYPES_DATATYPESCLASS_H +#include +#endif + + +//---------------------------------------------------------------------------- + +#define SCALOSGFXNAME "scalosgfx.library" + +#define gfxARGB ARGB + +// Width for TempRp.BitMap for ReadPixelLine8() and WritePixelLine8() +#define TEMPRP_WIDTH(width) (8 * ((((width) + 15) >> 4) << 1)) + +#define PIXELARRAY8_WIDTH(width) \ + ((((width) + 15) >> 4) << 4) + +// buffer size for ReadPixelArray8() and WritePixelArray8() +#define PIXELARRAY8_BUFFERSIZE(width, height) \ + (PIXELARRAY8_WIDTH(width) * ((height) + 1)) + +// check equality of 2 ARGB variables +#define ARGB_EQ(a, b) (*((ULONG *) &(a)) == *((ULONG *) &(b))) + +// convert 8 bit to 32 bit R/G/B palette value +#define RGB_8_TO_32(val) ((((UBYTE)(val)) << 24) \ + | (((UBYTE)(val)) << 16) \ + | (((UBYTE)(val)) << 8) \ + | ((UBYTE)(val))) + +// get number of bytes in sac_ColortTable +#define SAC_COLORTABLESIZE(sac) ((sac)->sac_NumColors * 3 * sizeof(ULONG)) + +//--------------------------------------------------------------- + +#define SCALOSGFX_TAGBASE 0x80537000 + +//--------------------------------------------------------------- + +// Flag values for ScalosGfxScaleBitMap() + +#define SCALEFLAGB_BILINEAR 0 +#define SCALEFLAGB_AVERAGE 1 +#define SCALEFLAGB_DOUBLESIZE 2 +#define SCALEFLAGB_CORRECTASPECT 3 +#define SCALEFLAGB_BICUBIC 4 + +#define SCALEFLAGF_BICUBIC (1L << SCALEFLAGB_BICUBIC) +#define SCALEFLAGF_BILINEAR (1L << SCALEFLAGB_BILINEAR) +#define SCALEFLAGF_AVERAGE (1L << SCALEFLAGB_AVERAGE) +#define SCALEFLAGF_DOUBLESIZE (1L << SCALEFLAGB_DOUBLESIZE) +#define SCALEFLAGF_CORRECTASPECT (1L << SCALEFLAGB_CORRECTASPECT) + +/*----------------------------------------------------------------------------------*/ + +/* ARGB data */ + +struct ARGB + { + UBYTE Alpha; + UBYTE Red; + UBYTE Green; + UBYTE Blue; + }; + +struct ARGBHeader + { + ULONG argb_Width; + ULONG argb_Height; + struct ARGB *argb_ImageData; + }; + +/*----------------------------------------------------------------------------------*/ + +/* combined BitMap and color map data + - parameter for IDTM_NewNormalImage and IDTM_NewSelectedImage */ +struct ScalosBitMapAndColor + { + ULONG sac_Width; + ULONG sac_Height; + ULONG sac_Depth; + struct BitMap *sac_BitMap; + ULONG sac_TransparentColor; // number of pen for transparent color + ULONG sac_NumColors; // number of entries in sac_ColorTable + ULONG *sac_ColorTable; // color table, 3 longwords per entry + ULONG sac_Flags; // Flags, see below + }; + +// set sac_TransparentColor to this value for no transparency +#define SAC_TRANSPARENT_NONE ((ULONG) ~0) + +// value in sac_Flags +#define SACFLAGB_NO_FREE_COLORTABLE 0 // Do not attempt to free sac_ColorTable +#define SACFLAGB_NO_FREE_BITMAP 1 // Do not attempt to free sac_BitMap + +#define SACFLAGF_NO_FREE_COLORTABLE (1 << SACFLAGB_NO_FREE_COLORTABLE) +#define SACFLAGF_NO_FREE_BITMAP (1 << SACFLAGB_NO_FREE_BITMAP) + +/*----------------------------------------------------------------------------------*/ + +struct ScaleBitMapArg + { + struct BitMap *sbma_SourceBM; + ULONG sbma_SourceWidth; + ULONG sbma_SourceHeight; + ULONG *sbma_DestWidth; + ULONG *sbma_DestHeight; + ULONG sbma_NumberOfColors; + CONST ULONG *sbma_ColorTable; + ULONG sbma_Flags; + struct BitMap *sbma_ScreenBM; + }; + +/*----------------------------------------------------------------------------------*/ + +// ScalosGfxMedianCut tags + +#define SCALOSGFX_MedianCutFlags (SCALOSGFX_TAGBASE + 1) // ULONG +#define SCALOSGFX_MedianCutFriendBitMap (SCALOSGFX_TAGBASE + 2) // struct BitMap * +#define SCALOSGFX_MedianCutReservedColors (SCALOSGFX_TAGBASE + 3) // ULONG + +// values in SCALOSGFX_MedianCutFlags + +#define SCALOSGFXFLAGF_MedianCut_FloydSteinberg 0x00000001 + +/*----------------------------------------------------------------------------------*/ + +// ScalosGfxScaleARGBArray tags + +#define SCALOSGFX_ScaleARGBArrayFlags (SCALOSGFX_TAGBASE + 10) // ULONG + +/*----------------------------------------------------------------------------------*/ + +// ScalosGfxScaleBitMap tags + +// none defined yet. + +/*----------------------------------------------------------------------------------*/ + +// LIBScalosGfxBlitIcon tags +#define SCALOSGFX_BlitIconHilight (SCALOSGFX_TAGBASE + 20) // const struct ARGB * +#define SCALOSGFX_BlitIconAlpha (SCALOSGFX_TAGBASE + 21) // const UBYTE * +#define SCALOSGFX_BlitIconTransparency (SCALOSGFX_TAGBASE + 22) // ULONG + +/*----------------------------------------------------------------------------------*/ + +// ScalosGfxBlitARGBAlphaTagList Tags + +#define SCALOSGFX_BlitARGBHilight (SCALOSGFX_TAGBASE + 30) // const struct ARGB * +#define SCALOSGFX_BlitARGBNoAlpha (SCALOSGFX_TAGBASE + 31) // ULONG +#define SCALOSGFX_BlitARGBTransparency (SCALOSGFX_TAGBASE + 32) // ULONG + +/*----------------------------------------------------------------------------------*/ + +// Gradient types for ScalosGfxDrawGradient and ScalosGfxDrawGradientRastPort + +#define SCALOS_GRADIENT_VERTICAL 1 +#define SCALOS_GRADIENT_HORIZONTAL 2 + +/*----------------------------------------------------------------------------------*/ + +// Segment types for ScalosGfxDrawEllipse + +#define ELLIPSE_SEGMENT_TOPLEFT 8 +#define ELLIPSE_SEGMENT_TOPRIGHT 2 +#define ELLIPSE_SEGMENT_BOTTOMLEFT 4 +#define ELLIPSE_SEGMENT_BOTTOMRIGHT 1 + +/*----------------------------------------------------------------------------------*/ + +#endif /* SCALOS_SCALOSGFX_H */ diff --git a/scalos/include/scalos/scalosmenuprefsplugin.h b/scalos/include/scalos/scalosmenuprefsplugin.h new file mode 100755 index 000000000..6ede97ef8 --- /dev/null +++ b/scalos/include/scalos/scalosmenuprefsplugin.h @@ -0,0 +1,49 @@ +#ifndef SCALOS_MENUPREFSPLUGIN_H +#define SCALOS_MENUPREFSPLUGIN_H +/* +** $VER: scalosmenuprefsplugin.h 40.33 (14 Apr 2005 21:52:37) +** +** $Date$ +** $Revision$ +** +** Special methods and tags for Scalos menu preferences plugin +** +** (C) Copyright 2000-2005 The Scalos Team +** All Rights Reserved +*/ + +#if defined(__GNUC__) && !defined(mc68000) +#pragma pack(2) +#endif /* __GNUC__ */ + +// --------------------------------------------------------------------------- + +/*** Methods ***/ + +#define MUIM_ScalosPrefs_MenuPrefs_ImportTD (MUIM_ScalosPrefs_User + 1) +#define MUIM_ScalosPrefs_MenuPrefs_ImportP (MUIM_ScalosPrefs_User + 2) +#define MUIM_ScalosPrefs_MenuPrefs_Merge (MUIM_ScalosPrefs_User + 3) +#define MUIM_ScalosPrefs_MenuPrefs_CollapseAll (MUIM_ScalosPrefs_User + 4) +#define MUIM_ScalosPrefs_MenuPrefs_ExpandAll (MUIM_ScalosPrefs_User + 5) + + +/*** Method structs ***/ + +/*** Special method values ***/ + +/*** Attributes ***/ +#define MUIM_ScalosPrefs_MenuPrefs_HideObsolete (MUIM_ScalosPrefs_User + 1001) + +/*** Special attribute values ***/ + + + +/*** Structures, Flags & Values ***/ + +// --------------------------------------------------------------------------- + +#if defined(__GNUC__) && !defined(mc68000) +#pragma pack() +#endif /* __GNUC__ */ + +#endif /* SCALOS_MENUPREFSPLUGIN_H */ diff --git a/scalos/include/scalos/scalospatternprefsplugin.h b/scalos/include/scalos/scalospatternprefsplugin.h new file mode 100755 index 000000000..72531ce0a --- /dev/null +++ b/scalos/include/scalos/scalospatternprefsplugin.h @@ -0,0 +1,46 @@ +#ifndef SCALOS_PATTERNPREFSPLUGIN_H +#define SCALOS_PATTERNPREFSPLUGIN_H +/* +** $VER: scalospatternprefsplugin.h 40.14 (04 Apr 2006 20:07:08) +** +** $Date$ +** $Revision$ +** +** Special methods and tags for Scalos menu preferences plugin +** +** (C) Copyright 2000-2005 The Scalos Team +** All Rights Reserved +*/ + +#if defined(__GNUC__) && !defined(mc68000) +#pragma pack(2) +#endif /* __GNUC__ */ + +// --------------------------------------------------------------------------- + +/*** Methods ***/ + +/*** Method structs ***/ + +/*** Special method values ***/ + +/*** Attributes ***/ + +#define MUIA_ScalosPrefs_PatternPrefs_Preview (MUIM_ScalosPrefs_User + 101) +#define MUIA_ScalosPrefs_PatternPrefs_AutoPreview (MUIM_ScalosPrefs_User + 102) +#define MUIA_ScalosPrefs_PatternPrefs_PreviewWeight (MUIM_ScalosPrefs_User + 103) +#define MUIA_ScalosPrefs_PatternPrefs_Thumbnails (MUIM_ScalosPrefs_User + 104) + +/*** Special attribute values ***/ + + + +/*** Structures, Flags & Values ***/ + +// --------------------------------------------------------------------------- + +#if defined(__GNUC__) && !defined(mc68000) +#pragma pack() +#endif /* __GNUC__ */ + +#endif /* SCALOS_PATTERNPREFSPLUGIN_H */ diff --git a/scalos/include/scalos/scalosprefs.h b/scalos/include/scalos/scalosprefs.h new file mode 100755 index 000000000..a6b78f84e --- /dev/null +++ b/scalos/include/scalos/scalosprefs.h @@ -0,0 +1,120 @@ +#ifndef SCALOS_PREFS_H +#define SCALOS_PREFS_H +/* +** $VER: scalosprefs.h 40.33 (14 Apr 2005 17:32:41) +** +** $Date$ +** $Revision$ +** +** File format for Scalos main preferences +** +** (C) Copyright 2000-2005 The Scalos Team +** All Rights Reserved +*/ + +#if defined(__GNUC__) && !defined(mc68000) +#pragma pack(2) +#endif /* __GNUC__ */ + +// --------------------------------------------------------------------------- + +// values in DragType +enum ScalosPrefsDragType + { + DRAGTYPE_ImageOnly = 0, + DRAGTYPE_ImageAndText + }; + +// Values in _prefDragMethod +enum ScalosPrefsDragMethodValues + { + DRAGMETHOD_GELS = 0, + DRAGMETHOD_Custom + }; + +// Values in dragTranspType +enum ScalosPrefsTranspType + { + TRANSPTYPE_Ghosted, + TRANSPTYPE_Transparent, + }; + +// Values in dragtranspmode +enum ScalosPrefsDragTranspModeValues + { + DRAGTRANSPMODE_SolidAndTransp = 0, + DRAGTRANSPMODE_Solid, + DRAGTRANSPMODE_Transp, + DRAGTRANSPMODE_TranspAndSolid, + }; + +// Values in dragtransp +#define DRAGTRANSPB_DiskIcons 0 +#define DRAGTRANSPB_DrawerIcons 1 +#define DRAGTRANSPB_ToolIcons 2 +#define DRAGTRANSPB_ProjectIcons 3 +#define DRAGTRANSPB_TrashcanIcons 4 +#define DRAGTRANSPB_KickIcons 5 +#define DRAGTRANSPB_AppIcons 6 +#define DRAGTRANSPB_AppWindows 7 +#define DRAGTRANSPB_ScalosWindows 8 +#define DRAGTRANSPB_IconifiedWinIcons 9 + +#define DRAGTRANSPF_DiskIcons (1 << DRAGTRANSPB_DiskIcons) +#define DRAGTRANSPF_DrawerIcons (1 << DRAGTRANSPB_DrawerIcons) +#define DRAGTRANSPF_ToolIcons (1 << DRAGTRANSPB_ToolIcons) +#define DRAGTRANSPF_ProjectIcons (1 << DRAGTRANSPB_ProjectIcons) +#define DRAGTRANSPF_TrashcanIcons (1 << DRAGTRANSPB_TrashcanIcons) +#define DRAGTRANSPF_KickIcons (1 << DRAGTRANSPB_KickIcons) +#define DRAGTRANSPF_AppIcons (1 << DRAGTRANSPB_AppIcons) +#define DRAGTRANSPF_AppWindows (1 << DRAGTRANSPB_AppWindows) +#define DRAGTRANSPF_ScalosWindows (1 << DRAGTRANSPB_ScalosWindows) +#define DRAGTRANSPF_IconifiedWinIcons (1 << DRAGTRANSPB_IconifiedWinIcons) + +struct SCP_PluginEntry + { + WORD pey_Priority; + UWORD pey_InstSize; + UWORD pey_NeededVersion; + UWORD pey_unused; + char pey_Path[1]; // variable-length string, terminated by '\0' +// char pey_ClassName[1]; // variable-length string, terminated by '\0' +// char pey_SuperclassName[1]; // variable-length string, terminated by '\0' + }; + +struct SCP_GadgetStringEntry + { + ULONG gse_Length; // size of gse_Strings + char gse_Strings[1]; // variable length + }; + +struct SCP_GadgetEntry + { + UWORD sgy_GadgetType; + char sgy_Action[40]; // Name of Menu Command - + ULONG sgy_NormalImageIndex; // file name of normal state image - index into SCP_ControlBarGadgetStrings array + ULONG sgy_SelectedImageIndex; // file name of selected state image - index into SCP_ControlBarGadgetStrings array + ULONG sgy_DisabledImageIndex; // file name of disabled state image - index into SCP_ControlBarGadgetStrings array + ULONG sgy_HelpTextIndex; // Bubble help text - index into SCP_ControlBarGadgetStrings array + }; + +enum SCPGadgetTypes + { + SCPGadgetType_BackButton, + SCPGadgetType_ForwardButton, + SCPGadgetType_UpButton, + SCPGadgetType_History, + SCPGadgetType_BrowseButton, + SCPGadgetType_ViewBy, // cycle gadget for "View By" + SCPGadgetType_ShowMode, // cycle gadget for "Show All" vs. "Show Only Icons" + SCPGadgetType_Separator, // empty space as separator + SCPGadgetType_ActionButton, // user-defined action button with arbitrary menu command + }; + +// --------------------------------------------------------------------------- + +#if defined(__GNUC__) && !defined(mc68000) +#pragma pack() +#endif /* __GNUC__ */ + +#endif /* SCALOS_PREFS_H */ diff --git a/scalos/include/scalos/scalosprefsplugin.h b/scalos/include/scalos/scalosprefsplugin.h new file mode 100755 index 000000000..83dc524ee --- /dev/null +++ b/scalos/include/scalos/scalosprefsplugin.h @@ -0,0 +1,105 @@ +#ifndef SCALOS_PREFSPLUGIN_H +#define SCALOS_PREFSPLUGIN_H +/* +** $VER: scalosprefsplugin.h 40.33 (14 Apr 2005 21:15:40) +** +** $Date$ +** $Revision$ +** +** Interface definitions for Scalos prefs plugins +** +** (C) Copyright 2000-2005 The Scalos Team +** All Rights Reserved +*/ + +#if defined(__GNUC__) && !defined(mc68000) +#pragma pack(2) +#endif /* __GNUC__ */ + +// --------------------------------------------------------------------------- + +/*** Methods ***/ + +#define MUIM_ScalosPrefs_LoadConfig 0x84723201 +#define MUIM_ScalosPrefs_UseConfig 0x84723202 +#define MUIM_ScalosPrefs_SaveConfig 0x84723203 +#define MUIM_ScalosPrefs_RestoreConfig 0x84723204 +#define MUIM_ScalosPrefs_ResetToDefaults 0x84723205 +#define MUIM_ScalosPrefs_LastSavedConfig 0x84723206 +#define MUIM_ScalosPrefs_PageActive 0x84723207 +#define MUIM_ScalosPrefs_OpenConfig 0x84723208 +#define MUIM_ScalosPrefs_SaveConfigAs 0x84723209 +#define MUIM_ScalosPrefs_About 0x8472320a +#define MUIM_ScalosPrefs_LoadNamedConfig 0x8472320b +#define MUIM_ScalosPrefs_CreateSubWindows 0x8472320c +#define MUIM_ScalosPrefs_SaveConfigIfChanged 0x8472320d +#define MUIM_ScalosPrefs_UseConfigIfChanged 0x8472320e +#define MUIM_ScalosPrefs_ParseToolTypes 0x8472320f +#define MUIM_ScalosPrefs_GetListOfMCCs 0x84723210 + + +// plugin-specific method IDs may start here +#define MUIM_ScalosPrefs_User 0x84723fff + + +/*** Method structs ***/ + +struct MUIP_ScalosPrefs_PageActive + { + ULONG MethodID; + ULONG isActive; + }; + +struct MUIP_ScalosPrefs_LoadNamedConfig + { + ULONG MethodID; + STRPTR ConfigFileName; + }; + +struct MUIP_ScalosPrefs_ParseToolTypes + { + ULONG MethodID; + STRPTR *ToolTypes; + }; + +struct MUIP_ScalosPrefs_MCCList + { + CONST_STRPTR MccName; + ULONG MccMinVersion; + ULONG MccMinRevision; + }; + +struct MUIP_ScalosPrefs_GetListOfMCCs + { + ULONG MethodID; + }; + +/*** Special method values ***/ + +/*** Attributes ***/ + +#define MUIA_ScalosPrefs_CreateIcons 0x84723301 // [isg] BOOL +#define MUIA_ScalosPrefs_MainWindow 0x84723302 // [is.] Object * +#define MUIA_ScalosPrefs_Application 0x84723303 // [is.] Object * +#define MUIA_ScalosPrefs_ProgramName 0x84723304 // [is.] CONST_STRPTR + + +/*** Special attribute values ***/ + + + +/*** Structures, Flags & Values ***/ + +// "Which" values for SCAGetPrefsInfo() call +#define SCAPREFSINFO_GetClass 1 +#define SCAPREFSINFO_GetTitle 2 +#define SCAPREFSINFO_GetTitleImage 3 + + +// --------------------------------------------------------------------------- + +#if defined(__GNUC__) && !defined(mc68000) +#pragma pack() +#endif /* __GNUC__ */ + +#endif /* SCALOS_PREFSPLUGIN_H */ diff --git a/scalos/include/scalos/scalospreviewplugin.h b/scalos/include/scalos/scalospreviewplugin.h new file mode 100755 index 000000000..de44fd208 --- /dev/null +++ b/scalos/include/scalos/scalospreviewplugin.h @@ -0,0 +1,71 @@ +#ifndef SCALOS_PREVIEWPLUGIN_H +#define SCALOS_PREVIEWPLUGIN_H +/* +** $VER: scalospreviewplugin.h 41.1 (28 Apr 2006 19:34:08) +** +** $Date$ +** $Revision$ +** +** Special methods and tags for Scalos menu preferences plugin +** +** (C) Copyright 2006 The Scalos Team +** All Rights Reserved +*/ + +#if defined(__GNUC__) && !defined(mc68000) +#pragma pack(2) +#endif /* __GNUC__ */ + +// --------------------------------------------------------------------------- + +#define SCALOSPREVIEW_Tagbase 0x84722fff + +// --------------------------------------------------------------------------- + +/*** Methods ***/ + +// --------------------------------------------------------------------------- + +/*** Method structs ***/ + +// --------------------------------------------------------------------------- + +/*** Special method values ***/ + +// --------------------------------------------------------------------------- + +/*** Attributes ***/ + +#define SCALOSPREVIEW_ThumbnailWidth (SCALOSPREVIEW_Tagbase + 101) // ULONG +#define SCALOSPREVIEW_ThumbnailHeight (SCALOSPREVIEW_Tagbase + 102) // ULONG +#define SCALOSPREVIEW_Screen (SCALOSPREVIEW_Tagbase + 103) // struct Screen * +#define SCALOSPREVIEW_SupportedColors (SCALOSPREVIEW_Tagbase + 104) // ULONG +#define SCALOSPREVIEW_ResultStruct (SCALOSPREVIEW_Tagbase + 105) // struct ScalosPreviewResult * +#define SCALOSPREVIEW_ImgBitMapHeader (SCALOSPREVIEW_Tagbase + 106) // struct BitMapHeader * +#define SCALOSPREVIEW_Quality (SCALOSPREVIEW_Tagbase + 107) // ULONG [0..15] +#define SCALOSPREVIEW_ReservedColors (SCALOSPREVIEW_Tagbase + 108) // ULONG + +// --------------------------------------------------------------------------- + +/*** Special attribute values ***/ + +#define SCALOSPREVIEWA_Quality_Min 0 +#define SCALOSPREVIEWA_Quality_Max 15 + +// --------------------------------------------------------------------------- + +/*** Structures, Flags & Values ***/ + +struct ScalosPreviewResult + { + struct ARGBHeader spvr_ARGBheader; // true-color thumbnail (> 256 colors) + struct ScalosBitMapAndColor *spvr_sac; // remapped thumbnail (<= 256 colors) + }; + +// --------------------------------------------------------------------------- + +#if defined(__GNUC__) && !defined(mc68000) +#pragma pack() +#endif /* __GNUC__ */ + +#endif /* SCALOS_PREVIEWPLUGIN_H */ diff --git a/scalos/include/scalos/undo.h b/scalos/include/scalos/undo.h new file mode 100755 index 000000000..a3f6b47ac --- /dev/null +++ b/scalos/include/scalos/undo.h @@ -0,0 +1,230 @@ +#ifndef SCALOS_UNDO_H +#define SCALOS_UNDO_H +/* +** $VER: undo.h 41.1 (23 Mar 2009 21:05:36) +** +** scalosgfx.library include +** +** (C) Copyright 2009 The Scalos Team +** All Rights Reserved +*/ + +#ifndef EXEC_TYPES_H +#include +#endif //EXEC_TYPES_H + +#ifndef UTILITY_TAGITEM_H +#include +#endif //UTILITY_TAGITEM_H + +//---------------------------------------------------------------------------- + +enum ScalosUndoType + { + UNDO_Snapshot, // UNDOTAG_IconDirLock, UNDOTAG_SaveIcon, UNDOTAG_IconNode + UNDO_Unsnapshot, // UNDOTAG_IconDirLock, UNDOTAG_SaveIcon, UNDOTAG_IconNode + UNDO_Cleanup, // UNDOTAG_CleanupMode, UNDOTAG_WindowTask, UNDOTAG_IconList + UNDO_Copy, // UNDOTAG_CopySrcDirLock, UNDOTAG_CopyDestDirLock, UNDOTAG_CopySrcName, UNDOTAG_CopyDestName + UNDO_Move, // UNDOTAG_CopySrcDirLock, UNDOTAG_CopyDestDirLock, UNDOTAG_CopySrcName, UNDOTAG_CopyDestName + UNDO_CreateLink, // UNDOTAG_CopySrcDirLock, UNDOTAG_CopyDestDirLock, UNDOTAG_CopySrcName, UNDOTAG_CopyDestName + UNDO_ChangeIconPos, // UNDOTAG_IconDirLock, UNDOTAG_IconNode, + UNDO_Rename, // UNDOTAG_CopySrcDirLock, UNDOTAG_CopySrcName, UNDOTAG_CopyDestName + UNDO_Relabel, // UNDOTAG_CopySrcName, UNDOTAG_CopyDestName + UNDO_Delete, // UNDOTAG_CopySrcDirLock, UNDOTAG_CopySrcName, UNDOTAG_CopyDestName + UNDO_Leaveout, // UNDOTAG_IconDirLock, UNDOTAG_IconName + UNDO_PutAway, // UNDOTAG_IconDirLock, UNDOTAG_IconName + UNDO_NewDrawer, // UNDOTAG_IconDirLock, UNDOTAG_IconName, UNDOTAG_CreateIcon + UNDO_SizeWindow, // UNDOTAG_WindowTask, UNDOTAG_OldWindowLeft, UNDOTAG_OldWindowTop, UNDOTAG_OldWindowWidth, UNDOTAG_OldWindowHeight, UNDOTAG_OldWindowVirtX, UNDOTAG_OldWindowVirtY,UNDOTAG_NewWindowLeft,UNDOTAG_NewWindowTop,UNDOTAG_NewWindowWidth,UNDOTAG_NewWindowHeight,UNDOTAG_NewWindowVirtX,UNDOTAG_NewWindowVirtY + UNDO_SetProtection, // UNDOTAG_IconDirLock, UNDOTAG_IconName, UNDOTAG_OldProtection, UNDOTAG_NewProtection + UNDO_SetComment, // UNDOTAG_IconDirLock, UNDOTAG_IconName, UNDOTAG_OldComment, UNDOTAG_NewComment + UNDO_SetToolTypes, // UNDOTAG_IconDirLock, UNDOTAG_IconName, UNDOTAG_OldToolTypes, UNDOTAG_NewToolTypes + UNDO_ChangeIconObject, // UNDOTAG_IconDirLock, UNDOTAG_IconName, UNDOTAG_OldIconObject, UNDOTAG_NewIconObject + UNDO_CloseWindow, // UNDOTAG_WindowTask + }; + +enum ScalosUndoTags + { + UNDOTAG_UndoMultiStep = (int) (TAG_USER + 1287), + UNDOTAG_IconNode, // struct ScaIconNode * + UNDOTAG_IconList, // struct ScaIconNode * + UNDOTAG_IconDirLock, // BPTR + UNDOTAG_CopySrcDirLock, // BPTR + UNDOTAG_CopyDestDirLock, // BPTR + UNDOTAG_CopySrcName, // CONST_STRPTR + UNDOTAG_CopyDestName, // CONST_STRPTR + UNDOTAG_IconPosX, // LONG + UNDOTAG_IconPosY, // LONG + UNDOTAG_OldIconPosX, // LONG + UNDOTAG_OldIconPosY, // LONG + UNDOTAG_WindowTask, // struct internalScaWindowTask * + UNDOTAG_CleanupMode, // ULONG + UNDOTAG_UndoHook, // struct Hook * + UNDOTAG_RedoHook, // struct Hook * + UNDOTAG_DisposeHook, // struct Hook * + UNDOTAG_SaveIcon, // ULONG + UNDOTAG_CustomAddHook, // struct Hook * + UNDOTAG_WbArg, // struct WBArg * + UNDOTAG_OldWindowLeft, // LONG + UNDOTAG_OldWindowTop, // LONG + UNDOTAG_OldWindowWidth, // ULONG + UNDOTAG_OldWindowHeight, // ULONG + UNDOTAG_NewWindowLeft, // LONG + UNDOTAG_NewWindowTop, // LONG + UNDOTAG_NewWindowWidth, // ULONG + UNDOTAG_NewWindowHeight, // ULONG + UNDOTAG_OldWindowVirtX, // LONG + UNDOTAG_OldWindowVirtY, // LONG + UNDOTAG_NewWindowVirtX, // LONG + UNDOTAG_NewWindowVirtY, // LONG + UNDOTAG_CreateIcon, // LONG + UNDOTAG_IconName, // CONST_STRPTR + UNDOTAG_OldProtection, // ULONG + UNDOTAG_NewProtection, // ULONG + UNDOTAG_OldComment, // CONST_STRPTR + UNDOTAG_NewComment, // CONST_STRPTR + UNDOTAG_OldToolTypes, // const STRPTR * + UNDOTAG_NewToolTypes, // const STRPTR * + UNDOTAG_OldIconObject, // Object * + UNDOTAG_NewIconObject, // Object * + }; + +enum ScalosUndoCleanupMode + { + CLEANUP_Default, + CLEANUP_ByName, + CLEANUP_ByDate, + CLEANUP_BySize, + CLEANUP_ByType, + }; + +struct UndoCleanupIconEntry + { + const struct ScaIconNode *ucin_IconNode; + LONG ucin_Left; // original x position of icon + LONG ucin_Top; // original y position of icon + }; + +struct UndoEvent + { + struct Node uev_Node; + enum ScalosUndoType uev_Type; + + struct Hook *uev_UndoHook; + struct Hook *uev_RedoHook; + struct Hook *uev_DisposeHook; + struct Hook *uev_CustomAddHook; + + LONG uev_OldPosX; + LONG uev_OldPosY; + LONG uev_NewPosX; + LONG uev_NewPosY; + + union UndoEventData + { + APTR uev_PrivateData; + struct UndoCopyMoveEventData + { + // we do not keep Locks to src/dest directories here since it wouldn't be nice to block rename/delete of referenced objects! + STRPTR ucmed_srcDirName; + STRPTR ucmed_destDirName; + STRPTR ucmed_srcName; + STRPTR ucmed_destName; + } uev_CopyMoveData; + struct UndoNewDrawerData + { + // we do not keep Locks to src directory here since it wouldn't be nice to block rename/delete of referenced objects! + STRPTR und_DirName; + STRPTR und_srcName; + BOOL und_CreateIcon; + } uev_NewDrawerData; + struct UndoIconEventData + { + // we do not keep Locks to icon directory here since it wouldn't be nice to block rename/delete of referenced objects! + STRPTR uid_DirName; + STRPTR uid_IconName; + } uev_IconData; + struct UndoCleanupData + { + enum ScalosUndoCleanupMode ucd_CleanupMode; + struct UndoCleanupIconEntry *ucd_Icons; + ULONG ucd_IconCount; // number of entries in ucd_Icons + struct ScaWindowTask *ucd_WindowTask; + STRPTR ucd_WindowTitle; // a copy of the window title of ucd_WindowTask + } uev_CleanupData; + struct UndoSnaphotIconData + { + STRPTR usid_DirName; + STRPTR usid_IconName; + Object *usid_IconObj; // Iconobject BEFORE snapshot/unsnaphot + ULONG usid_SaveIcon; + } uev_SnapshotData; + struct UndoSizeWindowData + { + struct ScaWindowTask *uswd_WindowTask; + STRPTR uswd_WindowTitle; // a copy of the window title of ucd_WindowTask + LONG uswd_OldLeft; + LONG uswd_OldTop; + ULONG uswd_OldWidth; + ULONG uswd_OldHeight; + LONG uswd_NewLeft; + LONG uswd_NewTop; + ULONG uswd_NewWidth; + ULONG uswd_NewHeight; + LONG uswd_OldVirtX; + LONG uswd_OldVirtY; + LONG uswd_NewVirtX; + LONG uswd_NewVirtY; + } uev_SizeWindowData; + struct UndoSetProtectionData + { + STRPTR uspd_DirName; + STRPTR uspd_IconName; + ULONG uspd_OldProtection; + ULONG uspd_NewProtection; + } uev_SetProtectionData; + struct UndoSetCommentData + { + STRPTR uscd_DirName; + STRPTR uscd_IconName; + STRPTR uscd_OldComment; + STRPTR uscd_NewComment; + } uev_SetCommentData; + struct UndoSetToolTypesData + { + STRPTR ustd_DirName; + STRPTR ustd_IconName; + STRPTR *ustd_OldToolTypes; + STRPTR *ustd_NewToolTypes; + } uev_SetToolTypesData; + struct UndoChangeIconObjectData + { + STRPTR uciod_DirName; + STRPTR uciod_IconName; + Object *uciod_OldIconObject; + Object *uciod_NewIconObject; + } uev_ChangeIconObjectData; + struct UndoCloseWindowData + { + STRPTR ucwd_DirName; + STRPTR ucwd_WindowTitle; + LONG ucwd_Left; + LONG ucwd_Top; + ULONG ucwd_Width; + ULONG ucwd_Height; + LONG ucwd_VirtX; + LONG ucwd_VirtY; + UWORD ucwd_ViewAll; + UBYTE ucwd_Viewmodes; + } uev_CloseWindowData; + } uev_Data; + + struct UndoStep *uev_UndoStep; + + ULONG uev_DescrMsgIDSingle; + ULONG uev_DescrMsgIDMultiple; + STRPTR *uev_DescrObjName; + }; + +/*----------------------------------------------------------------------------------*/ + +#endif /* SCALOS_UNDO_H */ diff --git a/scalos/include/scalosdebug.h b/scalos/include/scalosdebug.h new file mode 100755 index 000000000..cdc824d8c --- /dev/null +++ b/scalos/include/scalosdebug.h @@ -0,0 +1,18 @@ +// Pattern.c +// $Date$ +// $Revision$ + +//---------------------------------------------------------------------------- + +#undef d1 +#undef d2 + +#define d1(x) ; +#define d2(x) x; + +// from debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +//---------------------------------------------------------------------------- + diff --git a/scalos/include/sqlite3.h b/scalos/include/sqlite3.h new file mode 100644 index 000000000..fc9cd076a --- /dev/null +++ b/scalos/include/sqlite3.h @@ -0,0 +1,6949 @@ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This header file defines the interface that the SQLite library +** presents to client programs. If a C-function, structure, datatype, +** or constant definition does not appear in this file, then it is +** not a published API of SQLite, is subject to change without +** notice, and should not be referenced by programs that use SQLite. +** +** Some of the definitions that are in this file are marked as +** "experimental". Experimental interfaces are normally new +** features recently added to SQLite. We do not anticipate changes +** to experimental interfaces but reserve the right to make minor changes +** if experience from use "in the wild" suggest such changes are prudent. +** +** The official C-language API documentation for SQLite is derived +** from comments in this file. This file is the authoritative source +** on how SQLite interfaces are suppose to operate. +** +** The name of this file under configuration management is "sqlite.h.in". +** The makefile makes some minor changes to this file (such as inserting +** the version number) and changes its name to "sqlite3.h" as +** part of the build process. +*/ +#ifndef _SQLITE3_H_ +#define _SQLITE3_H_ +#include /* Needed for the definition of va_list */ + +/* +** Make sure we can call this stuff from C++. +*/ +#ifdef __cplusplus +extern "C" { +#endif + + +/* +** Add the ability to override 'extern' +*/ +#ifndef SQLITE_EXTERN +# define SQLITE_EXTERN extern +#endif + +#ifndef SQLITE_API +# define SQLITE_API +#endif + + +/* +** These no-op macros are used in front of interfaces to mark those +** interfaces as either deprecated or experimental. New applications +** should not use deprecated interfaces - they are support for backwards +** compatibility only. Application writers should be aware that +** experimental interfaces are subject to change in point releases. +** +** These macros used to resolve to various kinds of compiler magic that +** would generate warning messages when they were used. But that +** compiler magic ended up generating such a flurry of bug reports +** that we have taken it all out and gone back to using simple +** noop macros. +*/ +#define SQLITE_DEPRECATED +#define SQLITE_EXPERIMENTAL + +/* +** Ensure these symbols were not defined by some previous header file. +*/ +#ifdef SQLITE_VERSION +# undef SQLITE_VERSION +#endif +#ifdef SQLITE_VERSION_NUMBER +# undef SQLITE_VERSION_NUMBER +#endif + +/* +** CAPI3REF: Compile-Time Library Version Numbers +** +** ^(The [SQLITE_VERSION] C preprocessor macro in the sqlite3.h header +** evaluates to a string literal that is the SQLite version in the +** format "X.Y.Z" where X is the major version number (always 3 for +** SQLite3) and Y is the minor version number and Z is the release number.)^ +** ^(The [SQLITE_VERSION_NUMBER] C preprocessor macro resolves to an integer +** with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z are the same +** numbers used in [SQLITE_VERSION].)^ +** The SQLITE_VERSION_NUMBER for any given release of SQLite will also +** be larger than the release from which it is derived. Either Y will +** be held constant and Z will be incremented or else Y will be incremented +** and Z will be reset to zero. +** +** Since version 3.6.18, SQLite source code has been stored in the +**
Fossil configuration management +** system. ^The SQLITE_SOURCE_ID macro evaluates to +** a string which identifies a particular check-in of SQLite +** within its configuration management system. ^The SQLITE_SOURCE_ID +** string contains the date and time of the check-in (UTC) and an SHA1 +** hash of the entire source tree. +** +** See also: [sqlite3_libversion()], +** [sqlite3_libversion_number()], [sqlite3_sourceid()], +** [sqlite_version()] and [sqlite_source_id()]. +*/ +#define SQLITE_VERSION "3.7.10" +#define SQLITE_VERSION_NUMBER 3007010 +#define SQLITE_SOURCE_ID "2012-01-16 13:28:40 ebd01a8deffb5024a5d7494eef800d2366d97204" + +/* +** CAPI3REF: Run-Time Library Version Numbers +** KEYWORDS: sqlite3_version, sqlite3_sourceid +** +** These interfaces provide the same information as the [SQLITE_VERSION], +** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros +** but are associated with the library instead of the header file. ^(Cautious +** programmers might include assert() statements in their application to +** verify that values returned by these interfaces match the macros in +** the header, and thus insure that the application is +** compiled with matching library and header files. +** +**
+** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
+** assert( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)==0 );
+** assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 );
+** 
)^ +** +** ^The sqlite3_version[] string constant contains the text of [SQLITE_VERSION] +** macro. ^The sqlite3_libversion() function returns a pointer to the +** to the sqlite3_version[] string constant. The sqlite3_libversion() +** function is provided for use in DLLs since DLL users usually do not have +** direct access to string constants within the DLL. ^The +** sqlite3_libversion_number() function returns an integer equal to +** [SQLITE_VERSION_NUMBER]. ^The sqlite3_sourceid() function returns +** a pointer to a string constant whose value is the same as the +** [SQLITE_SOURCE_ID] C preprocessor macro. +** +** See also: [sqlite_version()] and [sqlite_source_id()]. +*/ +SQLITE_API SQLITE_EXTERN const char sqlite3_version[]; +SQLITE_API const char *sqlite3_libversion(void); +SQLITE_API const char *sqlite3_sourceid(void); +SQLITE_API int sqlite3_libversion_number(void); + +/* +** CAPI3REF: Run-Time Library Compilation Options Diagnostics +** +** ^The sqlite3_compileoption_used() function returns 0 or 1 +** indicating whether the specified option was defined at +** compile time. ^The SQLITE_ prefix may be omitted from the +** option name passed to sqlite3_compileoption_used(). +** +** ^The sqlite3_compileoption_get() function allows iterating +** over the list of options that were defined at compile time by +** returning the N-th compile time option string. ^If N is out of range, +** sqlite3_compileoption_get() returns a NULL pointer. ^The SQLITE_ +** prefix is omitted from any strings returned by +** sqlite3_compileoption_get(). +** +** ^Support for the diagnostic functions sqlite3_compileoption_used() +** and sqlite3_compileoption_get() may be omitted by specifying the +** [SQLITE_OMIT_COMPILEOPTION_DIAGS] option at compile time. +** +** See also: SQL functions [sqlite_compileoption_used()] and +** [sqlite_compileoption_get()] and the [compile_options pragma]. +*/ +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS +SQLITE_API int sqlite3_compileoption_used(const char *zOptName); +SQLITE_API const char *sqlite3_compileoption_get(int N); +#endif + +/* +** CAPI3REF: Test To See If The Library Is Threadsafe +** +** ^The sqlite3_threadsafe() function returns zero if and only if +** SQLite was compiled with mutexing code omitted due to the +** [SQLITE_THREADSAFE] compile-time option being set to 0. +** +** SQLite can be compiled with or without mutexes. When +** the [SQLITE_THREADSAFE] C preprocessor macro is 1 or 2, mutexes +** are enabled and SQLite is threadsafe. When the +** [SQLITE_THREADSAFE] macro is 0, +** the mutexes are omitted. Without the mutexes, it is not safe +** to use SQLite concurrently from more than one thread. +** +** Enabling mutexes incurs a measurable performance penalty. +** So if speed is of utmost importance, it makes sense to disable +** the mutexes. But for maximum safety, mutexes should be enabled. +** ^The default behavior is for mutexes to be enabled. +** +** This interface can be used by an application to make sure that the +** version of SQLite that it is linking against was compiled with +** the desired setting of the [SQLITE_THREADSAFE] macro. +** +** This interface only reports on the compile-time mutex setting +** of the [SQLITE_THREADSAFE] flag. If SQLite is compiled with +** SQLITE_THREADSAFE=1 or =2 then mutexes are enabled by default but +** can be fully or partially disabled using a call to [sqlite3_config()] +** with the verbs [SQLITE_CONFIG_SINGLETHREAD], [SQLITE_CONFIG_MULTITHREAD], +** or [SQLITE_CONFIG_MUTEX]. ^(The return value of the +** sqlite3_threadsafe() function shows only the compile-time setting of +** thread safety, not any run-time changes to that setting made by +** sqlite3_config(). In other words, the return value from sqlite3_threadsafe() +** is unchanged by calls to sqlite3_config().)^ +** +** See the [threading mode] documentation for additional information. +*/ +SQLITE_API int sqlite3_threadsafe(void); + +/* +** CAPI3REF: Database Connection Handle +** KEYWORDS: {database connection} {database connections} +** +** Each open SQLite database is represented by a pointer to an instance of +** the opaque structure named "sqlite3". It is useful to think of an sqlite3 +** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and +** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()] +** is its destructor. There are many other interfaces (such as +** [sqlite3_prepare_v2()], [sqlite3_create_function()], and +** [sqlite3_busy_timeout()] to name but three) that are methods on an +** sqlite3 object. +*/ +typedef struct sqlite3 sqlite3; + +/* +** CAPI3REF: 64-Bit Integer Types +** KEYWORDS: sqlite_int64 sqlite_uint64 +** +** Because there is no cross-platform way to specify 64-bit integer types +** SQLite includes typedefs for 64-bit signed and unsigned integers. +** +** The sqlite3_int64 and sqlite3_uint64 are the preferred type definitions. +** The sqlite_int64 and sqlite_uint64 types are supported for backwards +** compatibility only. +** +** ^The sqlite3_int64 and sqlite_int64 types can store integer values +** between -9223372036854775808 and +9223372036854775807 inclusive. ^The +** sqlite3_uint64 and sqlite_uint64 types can store integer values +** between 0 and +18446744073709551615 inclusive. +*/ +#ifdef SQLITE_INT64_TYPE + typedef SQLITE_INT64_TYPE sqlite_int64; + typedef unsigned SQLITE_INT64_TYPE sqlite_uint64; +#elif defined(_MSC_VER) || defined(__BORLANDC__) + typedef __int64 sqlite_int64; + typedef unsigned __int64 sqlite_uint64; +#else + typedef long long int sqlite_int64; + typedef unsigned long long int sqlite_uint64; +#endif +typedef sqlite_int64 sqlite3_int64; +typedef sqlite_uint64 sqlite3_uint64; + +/* +** If compiling for a processor that lacks floating point support, +** substitute integer for floating-point. +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# define double sqlite3_int64 +#endif + +/* +** CAPI3REF: Closing A Database Connection +** +** ^The sqlite3_close() routine is the destructor for the [sqlite3] object. +** ^Calls to sqlite3_close() return SQLITE_OK if the [sqlite3] object is +** successfully destroyed and all associated resources are deallocated. +** +** Applications must [sqlite3_finalize | finalize] all [prepared statements] +** and [sqlite3_blob_close | close] all [BLOB handles] associated with +** the [sqlite3] object prior to attempting to close the object. ^If +** sqlite3_close() is called on a [database connection] that still has +** outstanding [prepared statements] or [BLOB handles], then it returns +** SQLITE_BUSY. +** +** ^If [sqlite3_close()] is invoked while a transaction is open, +** the transaction is automatically rolled back. +** +** The C parameter to [sqlite3_close(C)] must be either a NULL +** pointer or an [sqlite3] object pointer obtained +** from [sqlite3_open()], [sqlite3_open16()], or +** [sqlite3_open_v2()], and not previously closed. +** ^Calling sqlite3_close() with a NULL pointer argument is a +** harmless no-op. +*/ +SQLITE_API int sqlite3_close(sqlite3 *); + +/* +** The type for a callback function. +** This is legacy and deprecated. It is included for historical +** compatibility and is not documented. +*/ +typedef int (*sqlite3_callback)(void*,int,char**, char**); + +/* +** CAPI3REF: One-Step Query Execution Interface +** +** The sqlite3_exec() interface is a convenience wrapper around +** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()], +** that allows an application to run multiple statements of SQL +** without having to use a lot of C code. +** +** ^The sqlite3_exec() interface runs zero or more UTF-8 encoded, +** semicolon-separate SQL statements passed into its 2nd argument, +** in the context of the [database connection] passed in as its 1st +** argument. ^If the callback function of the 3rd argument to +** sqlite3_exec() is not NULL, then it is invoked for each result row +** coming out of the evaluated SQL statements. ^The 4th argument to +** sqlite3_exec() is relayed through to the 1st argument of each +** callback invocation. ^If the callback pointer to sqlite3_exec() +** is NULL, then no callback is ever invoked and result rows are +** ignored. +** +** ^If an error occurs while evaluating the SQL statements passed into +** sqlite3_exec(), then execution of the current statement stops and +** subsequent statements are skipped. ^If the 5th parameter to sqlite3_exec() +** is not NULL then any error message is written into memory obtained +** from [sqlite3_malloc()] and passed back through the 5th parameter. +** To avoid memory leaks, the application should invoke [sqlite3_free()] +** on error message strings returned through the 5th parameter of +** of sqlite3_exec() after the error message string is no longer needed. +** ^If the 5th parameter to sqlite3_exec() is not NULL and no errors +** occur, then sqlite3_exec() sets the pointer in its 5th parameter to +** NULL before returning. +** +** ^If an sqlite3_exec() callback returns non-zero, the sqlite3_exec() +** routine returns SQLITE_ABORT without invoking the callback again and +** without running any subsequent SQL statements. +** +** ^The 2nd argument to the sqlite3_exec() callback function is the +** number of columns in the result. ^The 3rd argument to the sqlite3_exec() +** callback is an array of pointers to strings obtained as if from +** [sqlite3_column_text()], one for each column. ^If an element of a +** result row is NULL then the corresponding string pointer for the +** sqlite3_exec() callback is a NULL pointer. ^The 4th argument to the +** sqlite3_exec() callback is an array of pointers to strings where each +** entry represents the name of corresponding result column as obtained +** from [sqlite3_column_name()]. +** +** ^If the 2nd parameter to sqlite3_exec() is a NULL pointer, a pointer +** to an empty string, or a pointer that contains only whitespace and/or +** SQL comments, then no SQL statements are evaluated and the database +** is not changed. +** +** Restrictions: +** +**
    +**
  • The application must insure that the 1st parameter to sqlite3_exec() +** is a valid and open [database connection]. +**
  • The application must not close [database connection] specified by +** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running. +**
  • The application must not modify the SQL statement text passed into +** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running. +**
+*/ +SQLITE_API int sqlite3_exec( + sqlite3*, /* An open database */ + const char *sql, /* SQL to be evaluated */ + int (*callback)(void*,int,char**,char**), /* Callback function */ + void *, /* 1st argument to callback */ + char **errmsg /* Error msg written here */ +); + +/* +** CAPI3REF: Result Codes +** KEYWORDS: SQLITE_OK {error code} {error codes} +** KEYWORDS: {result code} {result codes} +** +** Many SQLite functions return an integer result code from the set shown +** here in order to indicate success or failure. +** +** New error codes may be added in future versions of SQLite. +** +** See also: [SQLITE_IOERR_READ | extended result codes], +** [sqlite3_vtab_on_conflict()] [SQLITE_ROLLBACK | result codes]. +*/ +#define SQLITE_OK 0 /* Successful result */ +/* beginning-of-error-codes */ +#define SQLITE_ERROR 1 /* SQL error or missing database */ +#define SQLITE_INTERNAL 2 /* Internal logic error in SQLite */ +#define SQLITE_PERM 3 /* Access permission denied */ +#define SQLITE_ABORT 4 /* Callback routine requested an abort */ +#define SQLITE_BUSY 5 /* The database file is locked */ +#define SQLITE_LOCKED 6 /* A table in the database is locked */ +#define SQLITE_NOMEM 7 /* A malloc() failed */ +#define SQLITE_READONLY 8 /* Attempt to write a readonly database */ +#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/ +#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */ +#define SQLITE_CORRUPT 11 /* The database disk image is malformed */ +#define SQLITE_NOTFOUND 12 /* Unknown opcode in sqlite3_file_control() */ +#define SQLITE_FULL 13 /* Insertion failed because database is full */ +#define SQLITE_CANTOPEN 14 /* Unable to open the database file */ +#define SQLITE_PROTOCOL 15 /* Database lock protocol error */ +#define SQLITE_EMPTY 16 /* Database is empty */ +#define SQLITE_SCHEMA 17 /* The database schema changed */ +#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */ +#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */ +#define SQLITE_MISMATCH 20 /* Data type mismatch */ +#define SQLITE_MISUSE 21 /* Library used incorrectly */ +#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ +#define SQLITE_AUTH 23 /* Authorization denied */ +#define SQLITE_FORMAT 24 /* Auxiliary database format error */ +#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */ +#define SQLITE_NOTADB 26 /* File opened that is not a database file */ +#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */ +#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */ +/* end-of-error-codes */ + +/* +** CAPI3REF: Extended Result Codes +** KEYWORDS: {extended error code} {extended error codes} +** KEYWORDS: {extended result code} {extended result codes} +** +** In its default configuration, SQLite API routines return one of 26 integer +** [SQLITE_OK | result codes]. However, experience has shown that many of +** these result codes are too coarse-grained. They do not provide as +** much information about problems as programmers might like. In an effort to +** address this, newer versions of SQLite (version 3.3.8 and later) include +** support for additional result codes that provide more detailed information +** about errors. The extended result codes are enabled or disabled +** on a per database connection basis using the +** [sqlite3_extended_result_codes()] API. +** +** Some of the available extended result codes are listed here. +** One may expect the number of extended result codes will be expand +** over time. Software that uses extended result codes should expect +** to see new result codes in future releases of SQLite. +** +** The SQLITE_OK result code will never be extended. It will always +** be exactly zero. +*/ +#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) +#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8)) +#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) +#define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8)) +#define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8)) +#define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8)) +#define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8)) +#define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8)) +#define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8)) +#define SQLITE_IOERR_DELETE (SQLITE_IOERR | (10<<8)) +#define SQLITE_IOERR_BLOCKED (SQLITE_IOERR | (11<<8)) +#define SQLITE_IOERR_NOMEM (SQLITE_IOERR | (12<<8)) +#define SQLITE_IOERR_ACCESS (SQLITE_IOERR | (13<<8)) +#define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8)) +#define SQLITE_IOERR_LOCK (SQLITE_IOERR | (15<<8)) +#define SQLITE_IOERR_CLOSE (SQLITE_IOERR | (16<<8)) +#define SQLITE_IOERR_DIR_CLOSE (SQLITE_IOERR | (17<<8)) +#define SQLITE_IOERR_SHMOPEN (SQLITE_IOERR | (18<<8)) +#define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) +#define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) +#define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) +#define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) +#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) +#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) +#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) +#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) +#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) +#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) + +/* +** CAPI3REF: Flags For File Open Operations +** +** These bit values are intended for use in the +** 3rd parameter to the [sqlite3_open_v2()] interface and +** in the 4th parameter to the [sqlite3_vfs.xOpen] method. +*/ +#define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */ +#define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */ +#define SQLITE_OPEN_AUTOPROXY 0x00000020 /* VFS only */ +#define SQLITE_OPEN_URI 0x00000040 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */ +#define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */ +#define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */ +#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */ +#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */ +#define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */ +#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */ +#define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_WAL 0x00080000 /* VFS only */ + +/* Reserved: 0x00F00000 */ + +/* +** CAPI3REF: Device Characteristics +** +** The xDeviceCharacteristics method of the [sqlite3_io_methods] +** object returns an integer which is a vector of the these +** bit values expressing I/O characteristics of the mass storage +** device that holds the file that the [sqlite3_io_methods] +** refers to. +** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). The SQLITE_IOCAP_POWERSAFE_OVERWRITE property means that +** after reboot following a crash or power loss, the only bytes in a +** file that were written at the application level might have changed +** and that adjacent bytes, even bytes within the same sector are +** guaranteed to be unchanged. +*/ +#define SQLITE_IOCAP_ATOMIC 0x00000001 +#define SQLITE_IOCAP_ATOMIC512 0x00000002 +#define SQLITE_IOCAP_ATOMIC1K 0x00000004 +#define SQLITE_IOCAP_ATOMIC2K 0x00000008 +#define SQLITE_IOCAP_ATOMIC4K 0x00000010 +#define SQLITE_IOCAP_ATOMIC8K 0x00000020 +#define SQLITE_IOCAP_ATOMIC16K 0x00000040 +#define SQLITE_IOCAP_ATOMIC32K 0x00000080 +#define SQLITE_IOCAP_ATOMIC64K 0x00000100 +#define SQLITE_IOCAP_SAFE_APPEND 0x00000200 +#define SQLITE_IOCAP_SEQUENTIAL 0x00000400 +#define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800 +#define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 + +/* +** CAPI3REF: File Locking Levels +** +** SQLite uses one of these integer values as the second +** argument to calls it makes to the xLock() and xUnlock() methods +** of an [sqlite3_io_methods] object. +*/ +#define SQLITE_LOCK_NONE 0 +#define SQLITE_LOCK_SHARED 1 +#define SQLITE_LOCK_RESERVED 2 +#define SQLITE_LOCK_PENDING 3 +#define SQLITE_LOCK_EXCLUSIVE 4 + +/* +** CAPI3REF: Synchronization Type Flags +** +** When SQLite invokes the xSync() method of an +** [sqlite3_io_methods] object it uses a combination of +** these integer values as the second argument. +** +** When the SQLITE_SYNC_DATAONLY flag is used, it means that the +** sync operation only needs to flush data to mass storage. Inode +** information need not be flushed. If the lower four bits of the flag +** equal SQLITE_SYNC_NORMAL, that means to use normal fsync() semantics. +** If the lower four bits equal SQLITE_SYNC_FULL, that means +** to use Mac OS X style fullsync instead of fsync(). +** +** Do not confuse the SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL flags +** with the [PRAGMA synchronous]=NORMAL and [PRAGMA synchronous]=FULL +** settings. The [synchronous pragma] determines when calls to the +** xSync VFS method occur and applies uniformly across all platforms. +** The SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL flags determine how +** energetic or rigorous or forceful the sync operations are and +** only make a difference on Mac OSX for the default SQLite code. +** (Third-party VFS implementations might also make the distinction +** between SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL, but among the +** operating systems natively supported by SQLite, only Mac OSX +** cares about the difference.) +*/ +#define SQLITE_SYNC_NORMAL 0x00002 +#define SQLITE_SYNC_FULL 0x00003 +#define SQLITE_SYNC_DATAONLY 0x00010 + +/* +** CAPI3REF: OS Interface Open File Handle +** +** An [sqlite3_file] object represents an open file in the +** [sqlite3_vfs | OS interface layer]. Individual OS interface +** implementations will +** want to subclass this object by appending additional fields +** for their own use. The pMethods entry is a pointer to an +** [sqlite3_io_methods] object that defines methods for performing +** I/O operations on the open file. +*/ +typedef struct sqlite3_file sqlite3_file; +struct sqlite3_file { + const struct sqlite3_io_methods *pMethods; /* Methods for an open file */ +}; + +/* +** CAPI3REF: OS Interface File Virtual Methods Object +** +** Every file opened by the [sqlite3_vfs.xOpen] method populates an +** [sqlite3_file] object (or, more commonly, a subclass of the +** [sqlite3_file] object) with a pointer to an instance of this object. +** This object defines the methods used to perform various operations +** against the open file represented by the [sqlite3_file] object. +** +** If the [sqlite3_vfs.xOpen] method sets the sqlite3_file.pMethods element +** to a non-NULL pointer, then the sqlite3_io_methods.xClose method +** may be invoked even if the [sqlite3_vfs.xOpen] reported that it failed. The +** only way to prevent a call to xClose following a failed [sqlite3_vfs.xOpen] +** is for the [sqlite3_vfs.xOpen] to set the sqlite3_file.pMethods element +** to NULL. +** +** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or +** [SQLITE_SYNC_FULL]. The first choice is the normal fsync(). +** The second choice is a Mac OS X style fullsync. The [SQLITE_SYNC_DATAONLY] +** flag may be ORed in to indicate that only the data of the file +** and not its inode needs to be synced. +** +** The integer values to xLock() and xUnlock() are one of +**
    +**
  • [SQLITE_LOCK_NONE], +**
  • [SQLITE_LOCK_SHARED], +**
  • [SQLITE_LOCK_RESERVED], +**
  • [SQLITE_LOCK_PENDING], or +**
  • [SQLITE_LOCK_EXCLUSIVE]. +**
+** xLock() increases the lock. xUnlock() decreases the lock. +** The xCheckReservedLock() method checks whether any database connection, +** either in this process or in some other process, is holding a RESERVED, +** PENDING, or EXCLUSIVE lock on the file. It returns true +** if such a lock exists and false otherwise. +** +** The xFileControl() method is a generic interface that allows custom +** VFS implementations to directly control an open file using the +** [sqlite3_file_control()] interface. The second "op" argument is an +** integer opcode. The third argument is a generic pointer intended to +** point to a structure that may contain arguments or space in which to +** write return values. Potential uses for xFileControl() might be +** functions to enable blocking locks with timeouts, to change the +** locking strategy (for example to use dot-file locks), to inquire +** about the status of a lock, or to break stale locks. The SQLite +** core reserves all opcodes less than 100 for its own use. +** A [SQLITE_FCNTL_LOCKSTATE | list of opcodes] less than 100 is available. +** Applications that define a custom xFileControl method should use opcodes +** greater than 100 to avoid conflicts. VFS implementations should +** return [SQLITE_NOTFOUND] for file control opcodes that they do not +** recognize. +** +** The xSectorSize() method returns the sector size of the +** device that underlies the file. The sector size is the +** minimum write that can be performed without disturbing +** other bytes in the file. The xDeviceCharacteristics() +** method returns a bit vector describing behaviors of the +** underlying device: +** +**
    +**
  • [SQLITE_IOCAP_ATOMIC] +**
  • [SQLITE_IOCAP_ATOMIC512] +**
  • [SQLITE_IOCAP_ATOMIC1K] +**
  • [SQLITE_IOCAP_ATOMIC2K] +**
  • [SQLITE_IOCAP_ATOMIC4K] +**
  • [SQLITE_IOCAP_ATOMIC8K] +**
  • [SQLITE_IOCAP_ATOMIC16K] +**
  • [SQLITE_IOCAP_ATOMIC32K] +**
  • [SQLITE_IOCAP_ATOMIC64K] +**
  • [SQLITE_IOCAP_SAFE_APPEND] +**
  • [SQLITE_IOCAP_SEQUENTIAL] +**
+** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). +** +** If xRead() returns SQLITE_IOERR_SHORT_READ it must also fill +** in the unread portions of the buffer with zeros. A VFS that +** fails to zero-fill short reads might seem to work. However, +** failure to zero-fill short reads will eventually lead to +** database corruption. +*/ +typedef struct sqlite3_io_methods sqlite3_io_methods; +struct sqlite3_io_methods { + int iVersion; + int (*xClose)(sqlite3_file*); + int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); + int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst); + int (*xTruncate)(sqlite3_file*, sqlite3_int64 size); + int (*xSync)(sqlite3_file*, int flags); + int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize); + int (*xLock)(sqlite3_file*, int); + int (*xUnlock)(sqlite3_file*, int); + int (*xCheckReservedLock)(sqlite3_file*, int *pResOut); + int (*xFileControl)(sqlite3_file*, int op, void *pArg); + int (*xSectorSize)(sqlite3_file*); + int (*xDeviceCharacteristics)(sqlite3_file*); + /* Methods above are valid for version 1 */ + int (*xShmMap)(sqlite3_file*, int iPg, int pgsz, int, void volatile**); + int (*xShmLock)(sqlite3_file*, int offset, int n, int flags); + void (*xShmBarrier)(sqlite3_file*); + int (*xShmUnmap)(sqlite3_file*, int deleteFlag); + /* Methods above are valid for version 2 */ + /* Additional methods may be added in future releases */ +}; + +/* +** CAPI3REF: Standard File Control Opcodes +** +** These integer constants are opcodes for the xFileControl method +** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()] +** interface. +** +** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This +** opcode causes the xFileControl method to write the current state of +** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], +** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) +** into an integer that the pArg argument points to. This capability +** is used during testing and only needs to be supported when SQLITE_TEST +** is defined. +** +** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS +** layer a hint of how large the database file will grow to be during the +** current transaction. This hint is not guaranteed to be accurate but it +** is often close. The underlying VFS might choose to preallocate database +** file space based on this hint in order to help writes to the database +** file run faster. +** +** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS +** extends and truncates the database file in chunks of a size specified +** by the user. The fourth argument to [sqlite3_file_control()] should +** point to an integer (type int) containing the new chunk-size to use +** for the nominated database. Allocating database file space in large +** chunks (say 1MB at a time), may reduce file-system fragmentation and +** improve performance on some systems. +** +** The [SQLITE_FCNTL_FILE_POINTER] opcode is used to obtain a pointer +** to the [sqlite3_file] object associated with a particular database +** connection. See the [sqlite3_file_control()] documentation for +** additional information. +** +** ^(The [SQLITE_FCNTL_SYNC_OMITTED] opcode is generated internally by +** SQLite and sent to all VFSes in place of a call to the xSync method +** when the database connection has [PRAGMA synchronous] set to OFF.)^ +** Some specialized VFSes need this signal in order to operate correctly +** when [PRAGMA synchronous | PRAGMA synchronous=OFF] is set, but most +** VFSes do not need this signal and should silently ignore this opcode. +** Applications should not call [sqlite3_file_control()] with this +** opcode as doing so may disrupt the operation of the specialized VFSes +** that do require it. +** +** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic +** retry counts and intervals for certain disk I/O operations for the +** windows [VFS] in order to provide robustness in the presence of +** anti-virus programs. By default, the windows VFS will retry file read, +** file write, and file delete operations up to 10 times, with a delay +** of 25 milliseconds before the first retry and with the delay increasing +** by an additional 25 milliseconds with each subsequent retry. This +** opcode allows these two values (10 retries and 25 milliseconds of delay) +** to be adjusted. The values are changed for all database connections +** within the same process. The argument is a pointer to an array of two +** integers where the first integer i the new retry count and the second +** integer is the delay. If either integer is negative, then the setting +** is not changed but instead the prior value of that setting is written +** into the array entry, allowing the current retry settings to be +** interrogated. The zDbName parameter is ignored. +** +** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the +** persistent [WAL | Write AHead Log] setting. By default, the auxiliary +** write ahead log and shared memory files used for transaction control +** are automatically deleted when the latest connection to the database +** closes. Setting persistent WAL mode causes those files to persist after +** close. Persisting the files is useful when other processes that do not +** have write permission on the directory containing the database file want +** to read the database file, as the WAL and shared memory files must exist +** in order for the database to be readable. The fourth parameter to +** [sqlite3_file_control()] for this opcode should be a pointer to an integer. +** That integer is 0 to disable persistent WAL mode or 1 to enable persistent +** WAL mode. If the integer is -1, then it is overwritten with the current +** WAL persistence setting. +** +** ^The [SQLITE_FCNTL_POWERSAFE_OVERWRITE] opcode is used to set or query the +** persistent "powersafe-overwrite" or "PSOW" setting. The PSOW setting +** determines the [SQLITE_IOCAP_POWERSAFE_OVERWRITE] bit of the +** xDeviceCharacteristics methods. The fourth parameter to +** [sqlite3_file_control()] for this opcode should be a pointer to an integer. +** That integer is 0 to disable zero-damage mode or 1 to enable zero-damage +** mode. If the integer is -1, then it is overwritten with the current +** zero-damage mode setting. +** +** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening +** a write transaction to indicate that, unless it is rolled back for some +** reason, the entire database file will be overwritten by the current +** transaction. This is used by VACUUM operations. +** +** ^The [SQLITE_FCNTL_VFSNAME] opcode can be used to obtain the names of +** all [VFSes] in the VFS stack. The names are of all VFS shims and the +** final bottom-level VFS are written into memory obtained from +** [sqlite3_malloc()] and the result is stored in the char* variable +** that the fourth parameter of [sqlite3_file_control()] points to. +** The caller is responsible for freeing the memory when done. As with +** all file-control actions, there is no guarantee that this will actually +** do anything. Callers should initialize the char* variable to a NULL +** pointer in case this file-control is not implemented. This file-control +** is intended for diagnostic use only. +*/ +#define SQLITE_FCNTL_LOCKSTATE 1 +#define SQLITE_GET_LOCKPROXYFILE 2 +#define SQLITE_SET_LOCKPROXYFILE 3 +#define SQLITE_LAST_ERRNO 4 +#define SQLITE_FCNTL_SIZE_HINT 5 +#define SQLITE_FCNTL_CHUNK_SIZE 6 +#define SQLITE_FCNTL_FILE_POINTER 7 +#define SQLITE_FCNTL_SYNC_OMITTED 8 +#define SQLITE_FCNTL_WIN32_AV_RETRY 9 +#define SQLITE_FCNTL_PERSIST_WAL 10 +#define SQLITE_FCNTL_OVERWRITE 11 +#define SQLITE_FCNTL_VFSNAME 12 +#define SQLITE_FCNTL_POWERSAFE_OVERWRITE 13 + +/* +** CAPI3REF: Mutex Handle +** +** The mutex module within SQLite defines [sqlite3_mutex] to be an +** abstract type for a mutex object. The SQLite core never looks +** at the internal representation of an [sqlite3_mutex]. It only +** deals with pointers to the [sqlite3_mutex] object. +** +** Mutexes are created using [sqlite3_mutex_alloc()]. +*/ +typedef struct sqlite3_mutex sqlite3_mutex; + +/* +** CAPI3REF: OS Interface Object +** +** An instance of the sqlite3_vfs object defines the interface between +** the SQLite core and the underlying operating system. The "vfs" +** in the name of the object stands for "virtual file system". See +** the [VFS | VFS documentation] for further information. +** +** The value of the iVersion field is initially 1 but may be larger in +** future versions of SQLite. Additional fields may be appended to this +** object when the iVersion value is increased. Note that the structure +** of the sqlite3_vfs object changes in the transaction between +** SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not +** modified. +** +** The szOsFile field is the size of the subclassed [sqlite3_file] +** structure used by this VFS. mxPathname is the maximum length of +** a pathname in this VFS. +** +** Registered sqlite3_vfs objects are kept on a linked list formed by +** the pNext pointer. The [sqlite3_vfs_register()] +** and [sqlite3_vfs_unregister()] interfaces manage this list +** in a thread-safe way. The [sqlite3_vfs_find()] interface +** searches the list. Neither the application code nor the VFS +** implementation should use the pNext pointer. +** +** The pNext field is the only field in the sqlite3_vfs +** structure that SQLite will ever modify. SQLite will only access +** or modify this field while holding a particular static mutex. +** The application should never modify anything within the sqlite3_vfs +** object once the object has been registered. +** +** The zName field holds the name of the VFS module. The name must +** be unique across all VFS modules. +** +** [[sqlite3_vfs.xOpen]] +** ^SQLite guarantees that the zFilename parameter to xOpen +** is either a NULL pointer or string obtained +** from xFullPathname() with an optional suffix added. +** ^If a suffix is added to the zFilename parameter, it will +** consist of a single "-" character followed by no more than +** 11 alphanumeric and/or "-" characters. +** ^SQLite further guarantees that +** the string will be valid and unchanged until xClose() is +** called. Because of the previous sentence, +** the [sqlite3_file] can safely store a pointer to the +** filename if it needs to remember the filename for some reason. +** If the zFilename parameter to xOpen is a NULL pointer then xOpen +** must invent its own temporary name for the file. ^Whenever the +** xFilename parameter is NULL it will also be the case that the +** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE]. +** +** The flags argument to xOpen() includes all bits set in +** the flags argument to [sqlite3_open_v2()]. Or if [sqlite3_open()] +** or [sqlite3_open16()] is used, then flags includes at least +** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. +** If xOpen() opens a file read-only then it sets *pOutFlags to +** include [SQLITE_OPEN_READONLY]. Other bits in *pOutFlags may be set. +** +** ^(SQLite will also add one of the following flags to the xOpen() +** call, depending on the object being opened: +** +**
    +**
  • [SQLITE_OPEN_MAIN_DB] +**
  • [SQLITE_OPEN_MAIN_JOURNAL] +**
  • [SQLITE_OPEN_TEMP_DB] +**
  • [SQLITE_OPEN_TEMP_JOURNAL] +**
  • [SQLITE_OPEN_TRANSIENT_DB] +**
  • [SQLITE_OPEN_SUBJOURNAL] +**
  • [SQLITE_OPEN_MASTER_JOURNAL] +**
  • [SQLITE_OPEN_WAL] +**
)^ +** +** The file I/O implementation can use the object type flags to +** change the way it deals with files. For example, an application +** that does not care about crash recovery or rollback might make +** the open of a journal file a no-op. Writes to this journal would +** also be no-ops, and any attempt to read the journal would return +** SQLITE_IOERR. Or the implementation might recognize that a database +** file will be doing page-aligned sector reads and writes in a random +** order and set up its I/O subsystem accordingly. +** +** SQLite might also add one of the following flags to the xOpen method: +** +**
    +**
  • [SQLITE_OPEN_DELETEONCLOSE] +**
  • [SQLITE_OPEN_EXCLUSIVE] +**
+** +** The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be +** deleted when it is closed. ^The [SQLITE_OPEN_DELETEONCLOSE] +** will be set for TEMP databases and their journals, transient +** databases, and subjournals. +** +** ^The [SQLITE_OPEN_EXCLUSIVE] flag is always used in conjunction +** with the [SQLITE_OPEN_CREATE] flag, which are both directly +** analogous to the O_EXCL and O_CREAT flags of the POSIX open() +** API. The SQLITE_OPEN_EXCLUSIVE flag, when paired with the +** SQLITE_OPEN_CREATE, is used to indicate that file should always +** be created, and that it is an error if it already exists. +** It is not used to indicate the file should be opened +** for exclusive access. +** +** ^At least szOsFile bytes of memory are allocated by SQLite +** to hold the [sqlite3_file] structure passed as the third +** argument to xOpen. The xOpen method does not have to +** allocate the structure; it should just fill it in. Note that +** the xOpen method must set the sqlite3_file.pMethods to either +** a valid [sqlite3_io_methods] object or to NULL. xOpen must do +** this even if the open fails. SQLite expects that the sqlite3_file.pMethods +** element will be valid after xOpen returns regardless of the success +** or failure of the xOpen call. +** +** [[sqlite3_vfs.xAccess]] +** ^The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS] +** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to +** test whether a file is readable and writable, or [SQLITE_ACCESS_READ] +** to test whether a file is at least readable. The file can be a +** directory. +** +** ^SQLite will always allocate at least mxPathname+1 bytes for the +** output buffer xFullPathname. The exact size of the output buffer +** is also passed as a parameter to both methods. If the output buffer +** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is +** handled as a fatal error by SQLite, vfs implementations should endeavor +** to prevent this by setting mxPathname to a sufficiently large value. +** +** The xRandomness(), xSleep(), xCurrentTime(), and xCurrentTimeInt64() +** interfaces are not strictly a part of the filesystem, but they are +** included in the VFS structure for completeness. +** The xRandomness() function attempts to return nBytes bytes +** of good-quality randomness into zOut. The return value is +** the actual number of bytes of randomness obtained. +** The xSleep() method causes the calling thread to sleep for at +** least the number of microseconds given. ^The xCurrentTime() +** method returns a Julian Day Number for the current date and time as +** a floating point value. +** ^The xCurrentTimeInt64() method returns, as an integer, the Julian +** Day Number multiplied by 86400000 (the number of milliseconds in +** a 24-hour day). +** ^SQLite will use the xCurrentTimeInt64() method to get the current +** date and time if that method is available (if iVersion is 2 or +** greater and the function pointer is not NULL) and will fall back +** to xCurrentTime() if xCurrentTimeInt64() is unavailable. +** +** ^The xSetSystemCall(), xGetSystemCall(), and xNestSystemCall() interfaces +** are not used by the SQLite core. These optional interfaces are provided +** by some VFSes to facilitate testing of the VFS code. By overriding +** system calls with functions under its control, a test program can +** simulate faults and error conditions that would otherwise be difficult +** or impossible to induce. The set of system calls that can be overridden +** varies from one VFS to another, and from one version of the same VFS to the +** next. Applications that use these interfaces must be prepared for any +** or all of these interfaces to be NULL or for their behavior to change +** from one release to the next. Applications must not attempt to access +** any of these methods if the iVersion of the VFS is less than 3. +*/ +typedef struct sqlite3_vfs sqlite3_vfs; +typedef void (*sqlite3_syscall_ptr)(void); +struct sqlite3_vfs { + int iVersion; /* Structure version number (currently 3) */ + int szOsFile; /* Size of subclassed sqlite3_file */ + int mxPathname; /* Maximum file pathname length */ + sqlite3_vfs *pNext; /* Next registered VFS */ + const char *zName; /* Name of this virtual file system */ + void *pAppData; /* Pointer to application-specific data */ + int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, + int flags, int *pOutFlags); + int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); + int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut); + int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); + void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); + void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg); + void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void); + void (*xDlClose)(sqlite3_vfs*, void*); + int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut); + int (*xSleep)(sqlite3_vfs*, int microseconds); + int (*xCurrentTime)(sqlite3_vfs*, double*); + int (*xGetLastError)(sqlite3_vfs*, int, char *); + /* + ** The methods above are in version 1 of the sqlite_vfs object + ** definition. Those that follow are added in version 2 or later + */ + int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*); + /* + ** The methods above are in versions 1 and 2 of the sqlite_vfs object. + ** Those below are for version 3 and greater. + */ + int (*xSetSystemCall)(sqlite3_vfs*, const char *zName, sqlite3_syscall_ptr); + sqlite3_syscall_ptr (*xGetSystemCall)(sqlite3_vfs*, const char *zName); + const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName); + /* + ** The methods above are in versions 1 through 3 of the sqlite_vfs object. + ** New fields may be appended in figure versions. The iVersion + ** value will increment whenever this happens. + */ +}; + +/* +** CAPI3REF: Flags for the xAccess VFS method +** +** These integer constants can be used as the third parameter to +** the xAccess method of an [sqlite3_vfs] object. They determine +** what kind of permissions the xAccess method is looking for. +** With SQLITE_ACCESS_EXISTS, the xAccess method +** simply checks whether the file exists. +** With SQLITE_ACCESS_READWRITE, the xAccess method +** checks whether the named directory is both readable and writable +** (in other words, if files can be added, removed, and renamed within +** the directory). +** The SQLITE_ACCESS_READWRITE constant is currently used only by the +** [temp_store_directory pragma], though this could change in a future +** release of SQLite. +** With SQLITE_ACCESS_READ, the xAccess method +** checks whether the file is readable. The SQLITE_ACCESS_READ constant is +** currently unused, though it might be used in a future release of +** SQLite. +*/ +#define SQLITE_ACCESS_EXISTS 0 +#define SQLITE_ACCESS_READWRITE 1 /* Used by PRAGMA temp_store_directory */ +#define SQLITE_ACCESS_READ 2 /* Unused */ + +/* +** CAPI3REF: Flags for the xShmLock VFS method +** +** These integer constants define the various locking operations +** allowed by the xShmLock method of [sqlite3_io_methods]. The +** following are the only legal combinations of flags to the +** xShmLock method: +** +**
    +**
  • SQLITE_SHM_LOCK | SQLITE_SHM_SHARED +**
  • SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE +**
  • SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED +**
  • SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE +**
+** +** When unlocking, the same SHARED or EXCLUSIVE flag must be supplied as +** was given no the corresponding lock. +** +** The xShmLock method can transition between unlocked and SHARED or +** between unlocked and EXCLUSIVE. It cannot transition between SHARED +** and EXCLUSIVE. +*/ +#define SQLITE_SHM_UNLOCK 1 +#define SQLITE_SHM_LOCK 2 +#define SQLITE_SHM_SHARED 4 +#define SQLITE_SHM_EXCLUSIVE 8 + +/* +** CAPI3REF: Maximum xShmLock index +** +** The xShmLock method on [sqlite3_io_methods] may use values +** between 0 and this upper bound as its "offset" argument. +** The SQLite core will never attempt to acquire or release a +** lock outside of this range +*/ +#define SQLITE_SHM_NLOCK 8 + + +/* +** CAPI3REF: Initialize The SQLite Library +** +** ^The sqlite3_initialize() routine initializes the +** SQLite library. ^The sqlite3_shutdown() routine +** deallocates any resources that were allocated by sqlite3_initialize(). +** These routines are designed to aid in process initialization and +** shutdown on embedded systems. Workstation applications using +** SQLite normally do not need to invoke either of these routines. +** +** A call to sqlite3_initialize() is an "effective" call if it is +** the first time sqlite3_initialize() is invoked during the lifetime of +** the process, or if it is the first time sqlite3_initialize() is invoked +** following a call to sqlite3_shutdown(). ^(Only an effective call +** of sqlite3_initialize() does any initialization. All other calls +** are harmless no-ops.)^ +** +** A call to sqlite3_shutdown() is an "effective" call if it is the first +** call to sqlite3_shutdown() since the last sqlite3_initialize(). ^(Only +** an effective call to sqlite3_shutdown() does any deinitialization. +** All other valid calls to sqlite3_shutdown() are harmless no-ops.)^ +** +** The sqlite3_initialize() interface is threadsafe, but sqlite3_shutdown() +** is not. The sqlite3_shutdown() interface must only be called from a +** single thread. All open [database connections] must be closed and all +** other SQLite resources must be deallocated prior to invoking +** sqlite3_shutdown(). +** +** Among other things, ^sqlite3_initialize() will invoke +** sqlite3_os_init(). Similarly, ^sqlite3_shutdown() +** will invoke sqlite3_os_end(). +** +** ^The sqlite3_initialize() routine returns [SQLITE_OK] on success. +** ^If for some reason, sqlite3_initialize() is unable to initialize +** the library (perhaps it is unable to allocate a needed resource such +** as a mutex) it returns an [error code] other than [SQLITE_OK]. +** +** ^The sqlite3_initialize() routine is called internally by many other +** SQLite interfaces so that an application usually does not need to +** invoke sqlite3_initialize() directly. For example, [sqlite3_open()] +** calls sqlite3_initialize() so the SQLite library will be automatically +** initialized when [sqlite3_open()] is called if it has not be initialized +** already. ^However, if SQLite is compiled with the [SQLITE_OMIT_AUTOINIT] +** compile-time option, then the automatic calls to sqlite3_initialize() +** are omitted and the application must call sqlite3_initialize() directly +** prior to using any other SQLite interface. For maximum portability, +** it is recommended that applications always invoke sqlite3_initialize() +** directly prior to using any other SQLite interface. Future releases +** of SQLite may require this. In other words, the behavior exhibited +** when SQLite is compiled with [SQLITE_OMIT_AUTOINIT] might become the +** default behavior in some future release of SQLite. +** +** The sqlite3_os_init() routine does operating-system specific +** initialization of the SQLite library. The sqlite3_os_end() +** routine undoes the effect of sqlite3_os_init(). Typical tasks +** performed by these routines include allocation or deallocation +** of static resources, initialization of global variables, +** setting up a default [sqlite3_vfs] module, or setting up +** a default configuration using [sqlite3_config()]. +** +** The application should never invoke either sqlite3_os_init() +** or sqlite3_os_end() directly. The application should only invoke +** sqlite3_initialize() and sqlite3_shutdown(). The sqlite3_os_init() +** interface is called automatically by sqlite3_initialize() and +** sqlite3_os_end() is called by sqlite3_shutdown(). Appropriate +** implementations for sqlite3_os_init() and sqlite3_os_end() +** are built into SQLite when it is compiled for Unix, Windows, or OS/2. +** When [custom builds | built for other platforms] +** (using the [SQLITE_OS_OTHER=1] compile-time +** option) the application must supply a suitable implementation for +** sqlite3_os_init() and sqlite3_os_end(). An application-supplied +** implementation of sqlite3_os_init() or sqlite3_os_end() +** must return [SQLITE_OK] on success and some other [error code] upon +** failure. +*/ +SQLITE_API int sqlite3_initialize(void); +SQLITE_API int sqlite3_shutdown(void); +SQLITE_API int sqlite3_os_init(void); +SQLITE_API int sqlite3_os_end(void); + +/* +** CAPI3REF: Configuring The SQLite Library +** +** The sqlite3_config() interface is used to make global configuration +** changes to SQLite in order to tune SQLite to the specific needs of +** the application. The default configuration is recommended for most +** applications and so this routine is usually not necessary. It is +** provided to support rare applications with unusual needs. +** +** The sqlite3_config() interface is not threadsafe. The application +** must insure that no other SQLite interfaces are invoked by other +** threads while sqlite3_config() is running. Furthermore, sqlite3_config() +** may only be invoked prior to library initialization using +** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()]. +** ^If sqlite3_config() is called after [sqlite3_initialize()] and before +** [sqlite3_shutdown()] then it will return SQLITE_MISUSE. +** Note, however, that ^sqlite3_config() can be called as part of the +** implementation of an application-defined [sqlite3_os_init()]. +** +** The first argument to sqlite3_config() is an integer +** [configuration option] that determines +** what property of SQLite is to be configured. Subsequent arguments +** vary depending on the [configuration option] +** in the first argument. +** +** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK]. +** ^If the option is unknown or SQLite is unable to set the option +** then this routine returns a non-zero [error code]. +*/ +SQLITE_API int sqlite3_config(int, ...); + +/* +** CAPI3REF: Configure database connections +** +** The sqlite3_db_config() interface is used to make configuration +** changes to a [database connection]. The interface is similar to +** [sqlite3_config()] except that the changes apply to a single +** [database connection] (specified in the first argument). +** +** The second argument to sqlite3_db_config(D,V,...) is the +** [SQLITE_DBCONFIG_LOOKASIDE | configuration verb] - an integer code +** that indicates what aspect of the [database connection] is being configured. +** Subsequent arguments vary depending on the configuration verb. +** +** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if +** the call is considered successful. +*/ +SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...); + +/* +** CAPI3REF: Memory Allocation Routines +** +** An instance of this object defines the interface between SQLite +** and low-level memory allocation routines. +** +** This object is used in only one place in the SQLite interface. +** A pointer to an instance of this object is the argument to +** [sqlite3_config()] when the configuration option is +** [SQLITE_CONFIG_MALLOC] or [SQLITE_CONFIG_GETMALLOC]. +** By creating an instance of this object +** and passing it to [sqlite3_config]([SQLITE_CONFIG_MALLOC]) +** during configuration, an application can specify an alternative +** memory allocation subsystem for SQLite to use for all of its +** dynamic memory needs. +** +** Note that SQLite comes with several [built-in memory allocators] +** that are perfectly adequate for the overwhelming majority of applications +** and that this object is only useful to a tiny minority of applications +** with specialized memory allocation requirements. This object is +** also used during testing of SQLite in order to specify an alternative +** memory allocator that simulates memory out-of-memory conditions in +** order to verify that SQLite recovers gracefully from such +** conditions. +** +** The xMalloc, xRealloc, and xFree methods must work like the +** malloc(), realloc() and free() functions from the standard C library. +** ^SQLite guarantees that the second argument to +** xRealloc is always a value returned by a prior call to xRoundup. +** +** xSize should return the allocated size of a memory allocation +** previously obtained from xMalloc or xRealloc. The allocated size +** is always at least as big as the requested size but may be larger. +** +** The xRoundup method returns what would be the allocated size of +** a memory allocation given a particular requested size. Most memory +** allocators round up memory allocations at least to the next multiple +** of 8. Some allocators round up to a larger multiple or to a power of 2. +** Every memory allocation request coming in through [sqlite3_malloc()] +** or [sqlite3_realloc()] first calls xRoundup. If xRoundup returns 0, +** that causes the corresponding memory allocation to fail. +** +** The xInit method initializes the memory allocator. (For example, +** it might allocate any require mutexes or initialize internal data +** structures. The xShutdown method is invoked (indirectly) by +** [sqlite3_shutdown()] and should deallocate any resources acquired +** by xInit. The pAppData pointer is used as the only parameter to +** xInit and xShutdown. +** +** SQLite holds the [SQLITE_MUTEX_STATIC_MASTER] mutex when it invokes +** the xInit method, so the xInit method need not be threadsafe. The +** xShutdown method is only called from [sqlite3_shutdown()] so it does +** not need to be threadsafe either. For all other methods, SQLite +** holds the [SQLITE_MUTEX_STATIC_MEM] mutex as long as the +** [SQLITE_CONFIG_MEMSTATUS] configuration option is turned on (which +** it is by default) and so the methods are automatically serialized. +** However, if [SQLITE_CONFIG_MEMSTATUS] is disabled, then the other +** methods must be threadsafe or else make their own arrangements for +** serialization. +** +** SQLite will never invoke xInit() more than once without an intervening +** call to xShutdown(). +*/ +typedef struct sqlite3_mem_methods sqlite3_mem_methods; +struct sqlite3_mem_methods { + void *(*xMalloc)(int); /* Memory allocation function */ + void (*xFree)(void*); /* Free a prior allocation */ + void *(*xRealloc)(void*,int); /* Resize an allocation */ + int (*xSize)(void*); /* Return the size of an allocation */ + int (*xRoundup)(int); /* Round up request size to allocation size */ + int (*xInit)(void*); /* Initialize the memory allocator */ + void (*xShutdown)(void*); /* Deinitialize the memory allocator */ + void *pAppData; /* Argument to xInit() and xShutdown() */ +}; + +/* +** CAPI3REF: Configuration Options +** KEYWORDS: {configuration option} +** +** These constants are the available integer configuration options that +** can be passed as the first argument to the [sqlite3_config()] interface. +** +** New configuration options may be added in future releases of SQLite. +** Existing configuration options might be discontinued. Applications +** should check the return code from [sqlite3_config()] to make sure that +** the call worked. The [sqlite3_config()] interface will return a +** non-zero [error code] if a discontinued or unsupported configuration option +** is invoked. +** +**
+** [[SQLITE_CONFIG_SINGLETHREAD]]
SQLITE_CONFIG_SINGLETHREAD
+**
There are no arguments to this option. ^This option sets the +** [threading mode] to Single-thread. In other words, it disables +** all mutexing and puts SQLite into a mode where it can only be used +** by a single thread. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** it is not possible to change the [threading mode] from its default +** value of Single-thread and so [sqlite3_config()] will return +** [SQLITE_ERROR] if called with the SQLITE_CONFIG_SINGLETHREAD +** configuration option.
+** +** [[SQLITE_CONFIG_MULTITHREAD]]
SQLITE_CONFIG_MULTITHREAD
+**
There are no arguments to this option. ^This option sets the +** [threading mode] to Multi-thread. In other words, it disables +** mutexing on [database connection] and [prepared statement] objects. +** The application is responsible for serializing access to +** [database connections] and [prepared statements]. But other mutexes +** are enabled so that SQLite will be safe to use in a multi-threaded +** environment as long as no two threads attempt to use the same +** [database connection] at the same time. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** it is not possible to set the Multi-thread [threading mode] and +** [sqlite3_config()] will return [SQLITE_ERROR] if called with the +** SQLITE_CONFIG_MULTITHREAD configuration option.
+** +** [[SQLITE_CONFIG_SERIALIZED]]
SQLITE_CONFIG_SERIALIZED
+**
There are no arguments to this option. ^This option sets the +** [threading mode] to Serialized. In other words, this option enables +** all mutexes including the recursive +** mutexes on [database connection] and [prepared statement] objects. +** In this mode (which is the default when SQLite is compiled with +** [SQLITE_THREADSAFE=1]) the SQLite library will itself serialize access +** to [database connections] and [prepared statements] so that the +** application is free to use the same [database connection] or the +** same [prepared statement] in different threads at the same time. +** ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** it is not possible to set the Serialized [threading mode] and +** [sqlite3_config()] will return [SQLITE_ERROR] if called with the +** SQLITE_CONFIG_SERIALIZED configuration option.
+** +** [[SQLITE_CONFIG_MALLOC]]
SQLITE_CONFIG_MALLOC
+**
^(This option takes a single argument which is a pointer to an +** instance of the [sqlite3_mem_methods] structure. The argument specifies +** alternative low-level memory allocation routines to be used in place of +** the memory allocation routines built into SQLite.)^ ^SQLite makes +** its own private copy of the content of the [sqlite3_mem_methods] structure +** before the [sqlite3_config()] call returns.
+** +** [[SQLITE_CONFIG_GETMALLOC]]
SQLITE_CONFIG_GETMALLOC
+**
^(This option takes a single argument which is a pointer to an +** instance of the [sqlite3_mem_methods] structure. The [sqlite3_mem_methods] +** structure is filled with the currently defined memory allocation routines.)^ +** This option can be used to overload the default memory allocation +** routines with a wrapper that simulations memory allocation failure or +** tracks memory usage, for example.
+** +** [[SQLITE_CONFIG_MEMSTATUS]]
SQLITE_CONFIG_MEMSTATUS
+**
^This option takes single argument of type int, interpreted as a +** boolean, which enables or disables the collection of memory allocation +** statistics. ^(When memory allocation statistics are disabled, the +** following SQLite interfaces become non-operational: +**
    +**
  • [sqlite3_memory_used()] +**
  • [sqlite3_memory_highwater()] +**
  • [sqlite3_soft_heap_limit64()] +**
  • [sqlite3_status()] +**
)^ +** ^Memory allocation statistics are enabled by default unless SQLite is +** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory +** allocation statistics are disabled by default. +**
+** +** [[SQLITE_CONFIG_SCRATCH]]
SQLITE_CONFIG_SCRATCH
+**
^This option specifies a static memory buffer that SQLite can use for +** scratch memory. There are three arguments: A pointer an 8-byte +** aligned memory buffer from which the scratch allocations will be +** drawn, the size of each scratch allocation (sz), +** and the maximum number of scratch allocations (N). The sz +** argument must be a multiple of 16. +** The first argument must be a pointer to an 8-byte aligned buffer +** of at least sz*N bytes of memory. +** ^SQLite will use no more than two scratch buffers per thread. So +** N should be set to twice the expected maximum number of threads. +** ^SQLite will never require a scratch buffer that is more than 6 +** times the database page size. ^If SQLite needs needs additional +** scratch memory beyond what is provided by this configuration option, then +** [sqlite3_malloc()] will be used to obtain the memory needed.
+** +** [[SQLITE_CONFIG_PAGECACHE]]
SQLITE_CONFIG_PAGECACHE
+**
^This option specifies a static memory buffer that SQLite can use for +** the database page cache with the default page cache implementation. +** This configuration should not be used if an application-define page +** cache implementation is loaded using the SQLITE_CONFIG_PCACHE2 option. +** There are three arguments to this option: A pointer to 8-byte aligned +** memory, the size of each page buffer (sz), and the number of pages (N). +** The sz argument should be the size of the largest database page +** (a power of two between 512 and 32768) plus a little extra for each +** page header. ^The page header size is 20 to 40 bytes depending on +** the host architecture. ^It is harmless, apart from the wasted memory, +** to make sz a little too large. The first +** argument should point to an allocation of at least sz*N bytes of memory. +** ^SQLite will use the memory provided by the first argument to satisfy its +** memory needs for the first N pages that it adds to cache. ^If additional +** page cache memory is needed beyond what is provided by this option, then +** SQLite goes to [sqlite3_malloc()] for the additional storage space. +** The pointer in the first argument must +** be aligned to an 8-byte boundary or subsequent behavior of SQLite +** will be undefined.
+** +** [[SQLITE_CONFIG_HEAP]]
SQLITE_CONFIG_HEAP
+**
^This option specifies a static memory buffer that SQLite will use +** for all of its dynamic memory allocation needs beyond those provided +** for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE]. +** There are three arguments: An 8-byte aligned pointer to the memory, +** the number of bytes in the memory buffer, and the minimum allocation size. +** ^If the first pointer (the memory pointer) is NULL, then SQLite reverts +** to using its default memory allocator (the system malloc() implementation), +** undoing any prior invocation of [SQLITE_CONFIG_MALLOC]. ^If the +** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or +** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory +** allocator is engaged to handle all of SQLites memory allocation needs. +** The first pointer (the memory pointer) must be aligned to an 8-byte +** boundary or subsequent behavior of SQLite will be undefined. +** The minimum allocation size is capped at 2**12. Reasonable values +** for the minimum allocation size are 2**5 through 2**8.
+** +** [[SQLITE_CONFIG_MUTEX]]
SQLITE_CONFIG_MUTEX
+**
^(This option takes a single argument which is a pointer to an +** instance of the [sqlite3_mutex_methods] structure. The argument specifies +** alternative low-level mutex routines to be used in place +** the mutex routines built into SQLite.)^ ^SQLite makes a copy of the +** content of the [sqlite3_mutex_methods] structure before the call to +** [sqlite3_config()] returns. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** the entire mutexing subsystem is omitted from the build and hence calls to +** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will +** return [SQLITE_ERROR].
+** +** [[SQLITE_CONFIG_GETMUTEX]]
SQLITE_CONFIG_GETMUTEX
+**
^(This option takes a single argument which is a pointer to an +** instance of the [sqlite3_mutex_methods] structure. The +** [sqlite3_mutex_methods] +** structure is filled with the currently defined mutex routines.)^ +** This option can be used to overload the default mutex allocation +** routines with a wrapper used to track mutex usage for performance +** profiling or testing, for example. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** the entire mutexing subsystem is omitted from the build and hence calls to +** [sqlite3_config()] with the SQLITE_CONFIG_GETMUTEX configuration option will +** return [SQLITE_ERROR].
+** +** [[SQLITE_CONFIG_LOOKASIDE]]
SQLITE_CONFIG_LOOKASIDE
+**
^(This option takes two arguments that determine the default +** memory allocation for the lookaside memory allocator on each +** [database connection]. The first argument is the +** size of each lookaside buffer slot and the second is the number of +** slots allocated to each database connection.)^ ^(This option sets the +** default lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE] +** verb to [sqlite3_db_config()] can be used to change the lookaside +** configuration on individual connections.)^
+** +** [[SQLITE_CONFIG_PCACHE2]]
SQLITE_CONFIG_PCACHE2
+**
^(This option takes a single argument which is a pointer to +** an [sqlite3_pcache_methods2] object. This object specifies the interface +** to a custom page cache implementation.)^ ^SQLite makes a copy of the +** object and uses it for page cache memory allocations.
+** +** [[SQLITE_CONFIG_GETPCACHE2]]
SQLITE_CONFIG_GETPCACHE2
+**
^(This option takes a single argument which is a pointer to an +** [sqlite3_pcache_methods2] object. SQLite copies of the current +** page cache implementation into that object.)^
+** +** [[SQLITE_CONFIG_LOG]]
SQLITE_CONFIG_LOG
+**
^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a +** function with a call signature of void(*)(void*,int,const char*), +** and a pointer to void. ^If the function pointer is not NULL, it is +** invoked by [sqlite3_log()] to process each logging event. ^If the +** function pointer is NULL, the [sqlite3_log()] interface becomes a no-op. +** ^The void pointer that is the second argument to SQLITE_CONFIG_LOG is +** passed through as the first parameter to the application-defined logger +** function whenever that function is invoked. ^The second parameter to +** the logger function is a copy of the first parameter to the corresponding +** [sqlite3_log()] call and is intended to be a [result code] or an +** [extended result code]. ^The third parameter passed to the logger is +** log message after formatting via [sqlite3_snprintf()]. +** The SQLite logging interface is not reentrant; the logger function +** supplied by the application must not invoke any SQLite interface. +** In a multi-threaded application, the application-defined logger +** function must be threadsafe.
+** +** [[SQLITE_CONFIG_URI]]
SQLITE_CONFIG_URI +**
This option takes a single argument of type int. If non-zero, then +** URI handling is globally enabled. If the parameter is zero, then URI handling +** is globally disabled. If URI handling is globally enabled, all filenames +** passed to [sqlite3_open()], [sqlite3_open_v2()], [sqlite3_open16()] or +** specified as part of [ATTACH] commands are interpreted as URIs, regardless +** of whether or not the [SQLITE_OPEN_URI] flag is set when the database +** connection is opened. If it is globally disabled, filenames are +** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the +** database connection is opened. By default, URI handling is globally +** disabled. The default value may be changed by compiling with the +** [SQLITE_USE_URI] symbol defined. +** +** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]] +**
SQLITE_CONFIG_PCACHE and SQLITE_CONFNIG_GETPCACHE +**
These options are obsolete and should not be used by new code. +** They are retained for backwards compatibility but are now no-ops. +**
+*/ +#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ +#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ +#define SQLITE_CONFIG_SERIALIZED 3 /* nil */ +#define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */ +#define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */ +#define SQLITE_CONFIG_SCRATCH 6 /* void*, int sz, int N */ +#define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */ +#define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */ +#define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */ +#define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */ +#define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */ +/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ +#define SQLITE_CONFIG_LOOKASIDE 13 /* int int */ +#define SQLITE_CONFIG_PCACHE 14 /* no-op */ +#define SQLITE_CONFIG_GETPCACHE 15 /* no-op */ +#define SQLITE_CONFIG_LOG 16 /* xFunc, void* */ +#define SQLITE_CONFIG_URI 17 /* int */ +#define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */ +#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */ + +/* +** CAPI3REF: Database Connection Configuration Options +** +** These constants are the available integer configuration options that +** can be passed as the second argument to the [sqlite3_db_config()] interface. +** +** New configuration options may be added in future releases of SQLite. +** Existing configuration options might be discontinued. Applications +** should check the return code from [sqlite3_db_config()] to make sure that +** the call worked. ^The [sqlite3_db_config()] interface will return a +** non-zero [error code] if a discontinued or unsupported configuration option +** is invoked. +** +**
+**
SQLITE_DBCONFIG_LOOKASIDE
+**
^This option takes three additional arguments that determine the +** [lookaside memory allocator] configuration for the [database connection]. +** ^The first argument (the third parameter to [sqlite3_db_config()] is a +** pointer to a memory buffer to use for lookaside memory. +** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb +** may be NULL in which case SQLite will allocate the +** lookaside buffer itself using [sqlite3_malloc()]. ^The second argument is the +** size of each lookaside buffer slot. ^The third argument is the number of +** slots. The size of the buffer in the first argument must be greater than +** or equal to the product of the second and third arguments. The buffer +** must be aligned to an 8-byte boundary. ^If the second argument to +** SQLITE_DBCONFIG_LOOKASIDE is not a multiple of 8, it is internally +** rounded down to the next smaller multiple of 8. ^(The lookaside memory +** configuration for a database connection can only be changed when that +** connection is not currently using lookaside memory, or in other words +** when the "current value" returned by +** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero. +** Any attempt to change the lookaside memory configuration when lookaside +** memory is in use leaves the configuration unchanged and returns +** [SQLITE_BUSY].)^
+** +**
SQLITE_DBCONFIG_ENABLE_FKEY
+**
^This option is used to enable or disable the enforcement of +** [foreign key constraints]. There should be two additional arguments. +** The first argument is an integer which is 0 to disable FK enforcement, +** positive to enable FK enforcement or negative to leave FK enforcement +** unchanged. The second parameter is a pointer to an integer into which +** is written 0 or 1 to indicate whether FK enforcement is off or on +** following this call. The second parameter may be a NULL pointer, in +** which case the FK enforcement setting is not reported back.
+** +**
SQLITE_DBCONFIG_ENABLE_TRIGGER
+**
^This option is used to enable or disable [CREATE TRIGGER | triggers]. +** There should be two additional arguments. +** The first argument is an integer which is 0 to disable triggers, +** positive to enable triggers or negative to leave the setting unchanged. +** The second parameter is a pointer to an integer into which +** is written 0 or 1 to indicate whether triggers are disabled or enabled +** following this call. The second parameter may be a NULL pointer, in +** which case the trigger setting is not reported back.
+** +**
+*/ +#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ +#define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */ +#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ + + +/* +** CAPI3REF: Enable Or Disable Extended Result Codes +** +** ^The sqlite3_extended_result_codes() routine enables or disables the +** [extended result codes] feature of SQLite. ^The extended result +** codes are disabled by default for historical compatibility. +*/ +SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff); + +/* +** CAPI3REF: Last Insert Rowid +** +** ^Each entry in an SQLite table has a unique 64-bit signed +** integer key called the [ROWID | "rowid"]. ^The rowid is always available +** as an undeclared column named ROWID, OID, or _ROWID_ as long as those +** names are not also used by explicitly declared columns. ^If +** the table has a column of type [INTEGER PRIMARY KEY] then that column +** is another alias for the rowid. +** +** ^This routine returns the [rowid] of the most recent +** successful [INSERT] into the database from the [database connection] +** in the first argument. ^As of SQLite version 3.7.7, this routines +** records the last insert rowid of both ordinary tables and [virtual tables]. +** ^If no successful [INSERT]s +** have ever occurred on that database connection, zero is returned. +** +** ^(If an [INSERT] occurs within a trigger or within a [virtual table] +** method, then this routine will return the [rowid] of the inserted +** row as long as the trigger or virtual table method is running. +** But once the trigger or virtual table method ends, the value returned +** by this routine reverts to what it was before the trigger or virtual +** table method began.)^ +** +** ^An [INSERT] that fails due to a constraint violation is not a +** successful [INSERT] and does not change the value returned by this +** routine. ^Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK, +** and INSERT OR ABORT make no changes to the return value of this +** routine when their insertion fails. ^(When INSERT OR REPLACE +** encounters a constraint violation, it does not fail. The +** INSERT continues to completion after deleting rows that caused +** the constraint problem so INSERT OR REPLACE will always change +** the return value of this interface.)^ +** +** ^For the purposes of this routine, an [INSERT] is considered to +** be successful even if it is subsequently rolled back. +** +** This function is accessible to SQL statements via the +** [last_insert_rowid() SQL function]. +** +** If a separate thread performs a new [INSERT] on the same +** database connection while the [sqlite3_last_insert_rowid()] +** function is running and thus changes the last insert [rowid], +** then the value returned by [sqlite3_last_insert_rowid()] is +** unpredictable and might not equal either the old or the new +** last insert [rowid]. +*/ +SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); + +/* +** CAPI3REF: Count The Number Of Rows Modified +** +** ^This function returns the number of database rows that were changed +** or inserted or deleted by the most recently completed SQL statement +** on the [database connection] specified by the first parameter. +** ^(Only changes that are directly specified by the [INSERT], [UPDATE], +** or [DELETE] statement are counted. Auxiliary changes caused by +** triggers or [foreign key actions] are not counted.)^ Use the +** [sqlite3_total_changes()] function to find the total number of changes +** including changes caused by triggers and foreign key actions. +** +** ^Changes to a view that are simulated by an [INSTEAD OF trigger] +** are not counted. Only real table changes are counted. +** +** ^(A "row change" is a change to a single row of a single table +** caused by an INSERT, DELETE, or UPDATE statement. Rows that +** are changed as side effects of [REPLACE] constraint resolution, +** rollback, ABORT processing, [DROP TABLE], or by any other +** mechanisms do not count as direct row changes.)^ +** +** A "trigger context" is a scope of execution that begins and +** ends with the script of a [CREATE TRIGGER | trigger]. +** Most SQL statements are +** evaluated outside of any trigger. This is the "top level" +** trigger context. If a trigger fires from the top level, a +** new trigger context is entered for the duration of that one +** trigger. Subtriggers create subcontexts for their duration. +** +** ^Calling [sqlite3_exec()] or [sqlite3_step()] recursively does +** not create a new trigger context. +** +** ^This function returns the number of direct row changes in the +** most recent INSERT, UPDATE, or DELETE statement within the same +** trigger context. +** +** ^Thus, when called from the top level, this function returns the +** number of changes in the most recent INSERT, UPDATE, or DELETE +** that also occurred at the top level. ^(Within the body of a trigger, +** the sqlite3_changes() interface can be called to find the number of +** changes in the most recently completed INSERT, UPDATE, or DELETE +** statement within the body of the same trigger. +** However, the number returned does not include changes +** caused by subtriggers since those have their own context.)^ +** +** See also the [sqlite3_total_changes()] interface, the +** [count_changes pragma], and the [changes() SQL function]. +** +** If a separate thread makes changes on the same database connection +** while [sqlite3_changes()] is running then the value returned +** is unpredictable and not meaningful. +*/ +SQLITE_API int sqlite3_changes(sqlite3*); + +/* +** CAPI3REF: Total Number Of Rows Modified +** +** ^This function returns the number of row changes caused by [INSERT], +** [UPDATE] or [DELETE] statements since the [database connection] was opened. +** ^(The count returned by sqlite3_total_changes() includes all changes +** from all [CREATE TRIGGER | trigger] contexts and changes made by +** [foreign key actions]. However, +** the count does not include changes used to implement [REPLACE] constraints, +** do rollbacks or ABORT processing, or [DROP TABLE] processing. The +** count does not include rows of views that fire an [INSTEAD OF trigger], +** though if the INSTEAD OF trigger makes changes of its own, those changes +** are counted.)^ +** ^The sqlite3_total_changes() function counts the changes as soon as +** the statement that makes them is completed (when the statement handle +** is passed to [sqlite3_reset()] or [sqlite3_finalize()]). +** +** See also the [sqlite3_changes()] interface, the +** [count_changes pragma], and the [total_changes() SQL function]. +** +** If a separate thread makes changes on the same database connection +** while [sqlite3_total_changes()] is running then the value +** returned is unpredictable and not meaningful. +*/ +SQLITE_API int sqlite3_total_changes(sqlite3*); + +/* +** CAPI3REF: Interrupt A Long-Running Query +** +** ^This function causes any pending database operation to abort and +** return at its earliest opportunity. This routine is typically +** called in response to a user action such as pressing "Cancel" +** or Ctrl-C where the user wants a long query operation to halt +** immediately. +** +** ^It is safe to call this routine from a thread different from the +** thread that is currently running the database operation. But it +** is not safe to call this routine with a [database connection] that +** is closed or might close before sqlite3_interrupt() returns. +** +** ^If an SQL operation is very nearly finished at the time when +** sqlite3_interrupt() is called, then it might not have an opportunity +** to be interrupted and might continue to completion. +** +** ^An SQL operation that is interrupted will return [SQLITE_INTERRUPT]. +** ^If the interrupted SQL operation is an INSERT, UPDATE, or DELETE +** that is inside an explicit transaction, then the entire transaction +** will be rolled back automatically. +** +** ^The sqlite3_interrupt(D) call is in effect until all currently running +** SQL statements on [database connection] D complete. ^Any new SQL statements +** that are started after the sqlite3_interrupt() call and before the +** running statements reaches zero are interrupted as if they had been +** running prior to the sqlite3_interrupt() call. ^New SQL statements +** that are started after the running statement count reaches zero are +** not effected by the sqlite3_interrupt(). +** ^A call to sqlite3_interrupt(D) that occurs when there are no running +** SQL statements is a no-op and has no effect on SQL statements +** that are started after the sqlite3_interrupt() call returns. +** +** If the database connection closes while [sqlite3_interrupt()] +** is running then bad things will likely happen. +*/ +SQLITE_API void sqlite3_interrupt(sqlite3*); + +/* +** CAPI3REF: Determine If An SQL Statement Is Complete +** +** These routines are useful during command-line input to determine if the +** currently entered text seems to form a complete SQL statement or +** if additional input is needed before sending the text into +** SQLite for parsing. ^These routines return 1 if the input string +** appears to be a complete SQL statement. ^A statement is judged to be +** complete if it ends with a semicolon token and is not a prefix of a +** well-formed CREATE TRIGGER statement. ^Semicolons that are embedded within +** string literals or quoted identifier names or comments are not +** independent tokens (they are part of the token in which they are +** embedded) and thus do not count as a statement terminator. ^Whitespace +** and comments that follow the final semicolon are ignored. +** +** ^These routines return 0 if the statement is incomplete. ^If a +** memory allocation fails, then SQLITE_NOMEM is returned. +** +** ^These routines do not parse the SQL statements thus +** will not detect syntactically incorrect SQL. +** +** ^(If SQLite has not been initialized using [sqlite3_initialize()] prior +** to invoking sqlite3_complete16() then sqlite3_initialize() is invoked +** automatically by sqlite3_complete16(). If that initialization fails, +** then the return value from sqlite3_complete16() will be non-zero +** regardless of whether or not the input SQL is complete.)^ +** +** The input to [sqlite3_complete()] must be a zero-terminated +** UTF-8 string. +** +** The input to [sqlite3_complete16()] must be a zero-terminated +** UTF-16 string in native byte order. +*/ +SQLITE_API int sqlite3_complete(const char *sql); +SQLITE_API int sqlite3_complete16(const void *sql); + +/* +** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors +** +** ^This routine sets a callback function that might be invoked whenever +** an attempt is made to open a database table that another thread +** or process has locked. +** +** ^If the busy callback is NULL, then [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] +** is returned immediately upon encountering the lock. ^If the busy callback +** is not NULL, then the callback might be invoked with two arguments. +** +** ^The first argument to the busy handler is a copy of the void* pointer which +** is the third argument to sqlite3_busy_handler(). ^The second argument to +** the busy handler callback is the number of times that the busy handler has +** been invoked for this locking event. ^If the +** busy callback returns 0, then no additional attempts are made to +** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned. +** ^If the callback returns non-zero, then another attempt +** is made to open the database for reading and the cycle repeats. +** +** The presence of a busy handler does not guarantee that it will be invoked +** when there is lock contention. ^If SQLite determines that invoking the busy +** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY] +** or [SQLITE_IOERR_BLOCKED] instead of invoking the busy handler. +** Consider a scenario where one process is holding a read lock that +** it is trying to promote to a reserved lock and +** a second process is holding a reserved lock that it is trying +** to promote to an exclusive lock. The first process cannot proceed +** because it is blocked by the second and the second process cannot +** proceed because it is blocked by the first. If both processes +** invoke the busy handlers, neither will make any progress. Therefore, +** SQLite returns [SQLITE_BUSY] for the first process, hoping that this +** will induce the first process to release its read lock and allow +** the second process to proceed. +** +** ^The default busy callback is NULL. +** +** ^The [SQLITE_BUSY] error is converted to [SQLITE_IOERR_BLOCKED] +** when SQLite is in the middle of a large transaction where all the +** changes will not fit into the in-memory cache. SQLite will +** already hold a RESERVED lock on the database file, but it needs +** to promote this lock to EXCLUSIVE so that it can spill cache +** pages into the database file without harm to concurrent +** readers. ^If it is unable to promote the lock, then the in-memory +** cache will be left in an inconsistent state and so the error +** code is promoted from the relatively benign [SQLITE_BUSY] to +** the more severe [SQLITE_IOERR_BLOCKED]. ^This error code promotion +** forces an automatic rollback of the changes. See the +** +** CorruptionFollowingBusyError wiki page for a discussion of why +** this is important. +** +** ^(There can only be a single busy handler defined for each +** [database connection]. Setting a new busy handler clears any +** previously set handler.)^ ^Note that calling [sqlite3_busy_timeout()] +** will also set or clear the busy handler. +** +** The busy callback should not take any actions which modify the +** database connection that invoked the busy handler. Any such actions +** result in undefined behavior. +** +** A busy handler must not close the database connection +** or [prepared statement] that invoked the busy handler. +*/ +SQLITE_API int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); + +/* +** CAPI3REF: Set A Busy Timeout +** +** ^This routine sets a [sqlite3_busy_handler | busy handler] that sleeps +** for a specified amount of time when a table is locked. ^The handler +** will sleep multiple times until at least "ms" milliseconds of sleeping +** have accumulated. ^After at least "ms" milliseconds of sleeping, +** the handler returns 0 which causes [sqlite3_step()] to return +** [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED]. +** +** ^Calling this routine with an argument less than or equal to zero +** turns off all busy handlers. +** +** ^(There can only be a single busy handler for a particular +** [database connection] any any given moment. If another busy handler +** was defined (using [sqlite3_busy_handler()]) prior to calling +** this routine, that other busy handler is cleared.)^ +*/ +SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); + +/* +** CAPI3REF: Convenience Routines For Running Queries +** +** This is a legacy interface that is preserved for backwards compatibility. +** Use of this interface is not recommended. +** +** Definition: A result table is memory data structure created by the +** [sqlite3_get_table()] interface. A result table records the +** complete query results from one or more queries. +** +** The table conceptually has a number of rows and columns. But +** these numbers are not part of the result table itself. These +** numbers are obtained separately. Let N be the number of rows +** and M be the number of columns. +** +** A result table is an array of pointers to zero-terminated UTF-8 strings. +** There are (N+1)*M elements in the array. The first M pointers point +** to zero-terminated strings that contain the names of the columns. +** The remaining entries all point to query results. NULL values result +** in NULL pointers. All other values are in their UTF-8 zero-terminated +** string representation as returned by [sqlite3_column_text()]. +** +** A result table might consist of one or more memory allocations. +** It is not safe to pass a result table directly to [sqlite3_free()]. +** A result table should be deallocated using [sqlite3_free_table()]. +** +** ^(As an example of the result table format, suppose a query result +** is as follows: +** +**
+**        Name        | Age
+**        -----------------------
+**        Alice       | 43
+**        Bob         | 28
+**        Cindy       | 21
+** 
+** +** There are two column (M==2) and three rows (N==3). Thus the +** result table has 8 entries. Suppose the result table is stored +** in an array names azResult. Then azResult holds this content: +** +**
+**        azResult[0] = "Name";
+**        azResult[1] = "Age";
+**        azResult[2] = "Alice";
+**        azResult[3] = "43";
+**        azResult[4] = "Bob";
+**        azResult[5] = "28";
+**        azResult[6] = "Cindy";
+**        azResult[7] = "21";
+** 
)^ +** +** ^The sqlite3_get_table() function evaluates one or more +** semicolon-separated SQL statements in the zero-terminated UTF-8 +** string of its 2nd parameter and returns a result table to the +** pointer given in its 3rd parameter. +** +** After the application has finished with the result from sqlite3_get_table(), +** it must pass the result table pointer to sqlite3_free_table() in order to +** release the memory that was malloced. Because of the way the +** [sqlite3_malloc()] happens within sqlite3_get_table(), the calling +** function must not try to call [sqlite3_free()] directly. Only +** [sqlite3_free_table()] is able to release the memory properly and safely. +** +** The sqlite3_get_table() interface is implemented as a wrapper around +** [sqlite3_exec()]. The sqlite3_get_table() routine does not have access +** to any internal data structures of SQLite. It uses only the public +** interface defined here. As a consequence, errors that occur in the +** wrapper layer outside of the internal [sqlite3_exec()] call are not +** reflected in subsequent calls to [sqlite3_errcode()] or +** [sqlite3_errmsg()]. +*/ +SQLITE_API int sqlite3_get_table( + sqlite3 *db, /* An open database */ + const char *zSql, /* SQL to be evaluated */ + char ***pazResult, /* Results of the query */ + int *pnRow, /* Number of result rows written here */ + int *pnColumn, /* Number of result columns written here */ + char **pzErrmsg /* Error msg written here */ +); +SQLITE_API void sqlite3_free_table(char **result); + +/* +** CAPI3REF: Formatted String Printing Functions +** +** These routines are work-alikes of the "printf()" family of functions +** from the standard C library. +** +** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their +** results into memory obtained from [sqlite3_malloc()]. +** The strings returned by these two routines should be +** released by [sqlite3_free()]. ^Both routines return a +** NULL pointer if [sqlite3_malloc()] is unable to allocate enough +** memory to hold the resulting string. +** +** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from +** the standard C library. The result is written into the +** buffer supplied as the second parameter whose size is given by +** the first parameter. Note that the order of the +** first two parameters is reversed from snprintf().)^ This is an +** historical accident that cannot be fixed without breaking +** backwards compatibility. ^(Note also that sqlite3_snprintf() +** returns a pointer to its buffer instead of the number of +** characters actually written into the buffer.)^ We admit that +** the number of characters written would be a more useful return +** value but we cannot change the implementation of sqlite3_snprintf() +** now without breaking compatibility. +** +** ^As long as the buffer size is greater than zero, sqlite3_snprintf() +** guarantees that the buffer is always zero-terminated. ^The first +** parameter "n" is the total size of the buffer, including space for +** the zero terminator. So the longest string that can be completely +** written will be n-1 characters. +** +** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf(). +** +** These routines all implement some additional formatting +** options that are useful for constructing SQL statements. +** All of the usual printf() formatting options apply. In addition, there +** is are "%q", "%Q", and "%z" options. +** +** ^(The %q option works like %s in that it substitutes a nul-terminated +** string from the argument list. But %q also doubles every '\'' character. +** %q is designed for use inside a string literal.)^ By doubling each '\'' +** character it escapes that character and allows it to be inserted into +** the string. +** +** For example, assume the string variable zText contains text as follows: +** +**
+**  char *zText = "It's a happy day!";
+** 
+** +** One can use this text in an SQL statement as follows: +** +**
+**  char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText);
+**  sqlite3_exec(db, zSQL, 0, 0, 0);
+**  sqlite3_free(zSQL);
+** 
+** +** Because the %q format string is used, the '\'' character in zText +** is escaped and the SQL generated is as follows: +** +**
+**  INSERT INTO table1 VALUES('It''s a happy day!')
+** 
+** +** This is correct. Had we used %s instead of %q, the generated SQL +** would have looked like this: +** +**
+**  INSERT INTO table1 VALUES('It's a happy day!');
+** 
+** +** This second example is an SQL syntax error. As a general rule you should +** always use %q instead of %s when inserting text into a string literal. +** +** ^(The %Q option works like %q except it also adds single quotes around +** the outside of the total string. Additionally, if the parameter in the +** argument list is a NULL pointer, %Q substitutes the text "NULL" (without +** single quotes).)^ So, for example, one could say: +** +**
+**  char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText);
+**  sqlite3_exec(db, zSQL, 0, 0, 0);
+**  sqlite3_free(zSQL);
+** 
+** +** The code above will render a correct SQL statement in the zSQL +** variable even if the zText variable is a NULL pointer. +** +** ^(The "%z" formatting option works like "%s" but with the +** addition that after the string has been read and copied into +** the result, [sqlite3_free()] is called on the input string.)^ +*/ +SQLITE_API char *sqlite3_mprintf(const char*,...); +SQLITE_API char *sqlite3_vmprintf(const char*, va_list); +SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...); +SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list); + +/* +** CAPI3REF: Memory Allocation Subsystem +** +** The SQLite core uses these three routines for all of its own +** internal memory allocation needs. "Core" in the previous sentence +** does not include operating-system specific VFS implementation. The +** Windows VFS uses native malloc() and free() for some operations. +** +** ^The sqlite3_malloc() routine returns a pointer to a block +** of memory at least N bytes in length, where N is the parameter. +** ^If sqlite3_malloc() is unable to obtain sufficient free +** memory, it returns a NULL pointer. ^If the parameter N to +** sqlite3_malloc() is zero or negative then sqlite3_malloc() returns +** a NULL pointer. +** +** ^Calling sqlite3_free() with a pointer previously returned +** by sqlite3_malloc() or sqlite3_realloc() releases that memory so +** that it might be reused. ^The sqlite3_free() routine is +** a no-op if is called with a NULL pointer. Passing a NULL pointer +** to sqlite3_free() is harmless. After being freed, memory +** should neither be read nor written. Even reading previously freed +** memory might result in a segmentation fault or other severe error. +** Memory corruption, a segmentation fault, or other severe error +** might result if sqlite3_free() is called with a non-NULL pointer that +** was not obtained from sqlite3_malloc() or sqlite3_realloc(). +** +** ^(The sqlite3_realloc() interface attempts to resize a +** prior memory allocation to be at least N bytes, where N is the +** second parameter. The memory allocation to be resized is the first +** parameter.)^ ^ If the first parameter to sqlite3_realloc() +** is a NULL pointer then its behavior is identical to calling +** sqlite3_malloc(N) where N is the second parameter to sqlite3_realloc(). +** ^If the second parameter to sqlite3_realloc() is zero or +** negative then the behavior is exactly the same as calling +** sqlite3_free(P) where P is the first parameter to sqlite3_realloc(). +** ^sqlite3_realloc() returns a pointer to a memory allocation +** of at least N bytes in size or NULL if sufficient memory is unavailable. +** ^If M is the size of the prior allocation, then min(N,M) bytes +** of the prior allocation are copied into the beginning of buffer returned +** by sqlite3_realloc() and the prior allocation is freed. +** ^If sqlite3_realloc() returns NULL, then the prior allocation +** is not freed. +** +** ^The memory returned by sqlite3_malloc() and sqlite3_realloc() +** is always aligned to at least an 8 byte boundary, or to a +** 4 byte boundary if the [SQLITE_4_BYTE_ALIGNED_MALLOC] compile-time +** option is used. +** +** In SQLite version 3.5.0 and 3.5.1, it was possible to define +** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in +** implementation of these routines to be omitted. That capability +** is no longer provided. Only built-in memory allocators can be used. +** +** The Windows OS interface layer calls +** the system malloc() and free() directly when converting +** filenames between the UTF-8 encoding used by SQLite +** and whatever filename encoding is used by the particular Windows +** installation. Memory allocation errors are detected, but +** they are reported back as [SQLITE_CANTOPEN] or +** [SQLITE_IOERR] rather than [SQLITE_NOMEM]. +** +** The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()] +** must be either NULL or else pointers obtained from a prior +** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have +** not yet been released. +** +** The application must not read or write any part of +** a block of memory after it has been released using +** [sqlite3_free()] or [sqlite3_realloc()]. +*/ +SQLITE_API void *sqlite3_malloc(int); +SQLITE_API void *sqlite3_realloc(void*, int); +SQLITE_API void sqlite3_free(void*); + +/* +** CAPI3REF: Memory Allocator Statistics +** +** SQLite provides these two interfaces for reporting on the status +** of the [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()] +** routines, which form the built-in memory allocation subsystem. +** +** ^The [sqlite3_memory_used()] routine returns the number of bytes +** of memory currently outstanding (malloced but not freed). +** ^The [sqlite3_memory_highwater()] routine returns the maximum +** value of [sqlite3_memory_used()] since the high-water mark +** was last reset. ^The values returned by [sqlite3_memory_used()] and +** [sqlite3_memory_highwater()] include any overhead +** added by SQLite in its implementation of [sqlite3_malloc()], +** but not overhead added by the any underlying system library +** routines that [sqlite3_malloc()] may call. +** +** ^The memory high-water mark is reset to the current value of +** [sqlite3_memory_used()] if and only if the parameter to +** [sqlite3_memory_highwater()] is true. ^The value returned +** by [sqlite3_memory_highwater(1)] is the high-water mark +** prior to the reset. +*/ +SQLITE_API sqlite3_int64 sqlite3_memory_used(void); +SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag); + +/* +** CAPI3REF: Pseudo-Random Number Generator +** +** SQLite contains a high-quality pseudo-random number generator (PRNG) used to +** select random [ROWID | ROWIDs] when inserting new records into a table that +** already uses the largest possible [ROWID]. The PRNG is also used for +** the build-in random() and randomblob() SQL functions. This interface allows +** applications to access the same PRNG for other purposes. +** +** ^A call to this routine stores N bytes of randomness into buffer P. +** +** ^The first time this routine is invoked (either internally or by +** the application) the PRNG is seeded using randomness obtained +** from the xRandomness method of the default [sqlite3_vfs] object. +** ^On all subsequent invocations, the pseudo-randomness is generated +** internally and without recourse to the [sqlite3_vfs] xRandomness +** method. +*/ +SQLITE_API void sqlite3_randomness(int N, void *P); + +/* +** CAPI3REF: Compile-Time Authorization Callbacks +** +** ^This routine registers an authorizer callback with a particular +** [database connection], supplied in the first argument. +** ^The authorizer callback is invoked as SQL statements are being compiled +** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()], +** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()]. ^At various +** points during the compilation process, as logic is being created +** to perform various actions, the authorizer callback is invoked to +** see if those actions are allowed. ^The authorizer callback should +** return [SQLITE_OK] to allow the action, [SQLITE_IGNORE] to disallow the +** specific action but allow the SQL statement to continue to be +** compiled, or [SQLITE_DENY] to cause the entire SQL statement to be +** rejected with an error. ^If the authorizer callback returns +** any value other than [SQLITE_IGNORE], [SQLITE_OK], or [SQLITE_DENY] +** then the [sqlite3_prepare_v2()] or equivalent call that triggered +** the authorizer will fail with an error message. +** +** When the callback returns [SQLITE_OK], that means the operation +** requested is ok. ^When the callback returns [SQLITE_DENY], the +** [sqlite3_prepare_v2()] or equivalent call that triggered the +** authorizer will fail with an error message explaining that +** access is denied. +** +** ^The first parameter to the authorizer callback is a copy of the third +** parameter to the sqlite3_set_authorizer() interface. ^The second parameter +** to the callback is an integer [SQLITE_COPY | action code] that specifies +** the particular action to be authorized. ^The third through sixth parameters +** to the callback are zero-terminated strings that contain additional +** details about the action to be authorized. +** +** ^If the action code is [SQLITE_READ] +** and the callback returns [SQLITE_IGNORE] then the +** [prepared statement] statement is constructed to substitute +** a NULL value in place of the table column that would have +** been read if [SQLITE_OK] had been returned. The [SQLITE_IGNORE] +** return can be used to deny an untrusted user access to individual +** columns of a table. +** ^If the action code is [SQLITE_DELETE] and the callback returns +** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the +** [truncate optimization] is disabled and all rows are deleted individually. +** +** An authorizer is used when [sqlite3_prepare | preparing] +** SQL statements from an untrusted source, to ensure that the SQL statements +** do not try to access data they are not allowed to see, or that they do not +** try to execute malicious statements that damage the database. For +** example, an application may allow a user to enter arbitrary +** SQL queries for evaluation by a database. But the application does +** not want the user to be able to make arbitrary changes to the +** database. An authorizer could then be put in place while the +** user-entered SQL is being [sqlite3_prepare | prepared] that +** disallows everything except [SELECT] statements. +** +** Applications that need to process SQL from untrusted sources +** might also consider lowering resource limits using [sqlite3_limit()] +** and limiting database size using the [max_page_count] [PRAGMA] +** in addition to using an authorizer. +** +** ^(Only a single authorizer can be in place on a database connection +** at a time. Each call to sqlite3_set_authorizer overrides the +** previous call.)^ ^Disable the authorizer by installing a NULL callback. +** The authorizer is disabled by default. +** +** The authorizer callback must not do anything that will modify +** the database connection that invoked the authorizer callback. +** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their +** database connections for the meaning of "modify" in this paragraph. +** +** ^When [sqlite3_prepare_v2()] is used to prepare a statement, the +** statement might be re-prepared during [sqlite3_step()] due to a +** schema change. Hence, the application should ensure that the +** correct authorizer callback remains in place during the [sqlite3_step()]. +** +** ^Note that the authorizer callback is invoked only during +** [sqlite3_prepare()] or its variants. Authorization is not +** performed during statement evaluation in [sqlite3_step()], unless +** as stated in the previous paragraph, sqlite3_step() invokes +** sqlite3_prepare_v2() to reprepare a statement after a schema change. +*/ +SQLITE_API int sqlite3_set_authorizer( + sqlite3*, + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), + void *pUserData +); + +/* +** CAPI3REF: Authorizer Return Codes +** +** The [sqlite3_set_authorizer | authorizer callback function] must +** return either [SQLITE_OK] or one of these two constants in order +** to signal SQLite whether or not the action is permitted. See the +** [sqlite3_set_authorizer | authorizer documentation] for additional +** information. +** +** Note that SQLITE_IGNORE is also used as a [SQLITE_ROLLBACK | return code] +** from the [sqlite3_vtab_on_conflict()] interface. +*/ +#define SQLITE_DENY 1 /* Abort the SQL statement with an error */ +#define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */ + +/* +** CAPI3REF: Authorizer Action Codes +** +** The [sqlite3_set_authorizer()] interface registers a callback function +** that is invoked to authorize certain SQL statement actions. The +** second parameter to the callback is an integer code that specifies +** what action is being authorized. These are the integer action codes that +** the authorizer callback may be passed. +** +** These action code values signify what kind of operation is to be +** authorized. The 3rd and 4th parameters to the authorization +** callback function will be parameters or NULL depending on which of these +** codes is used as the second parameter. ^(The 5th parameter to the +** authorizer callback is the name of the database ("main", "temp", +** etc.) if applicable.)^ ^The 6th parameter to the authorizer callback +** is the name of the inner-most trigger or view that is responsible for +** the access attempt or NULL if this access attempt is directly from +** top-level SQL code. +*/ +/******************************************* 3rd ************ 4th ***********/ +#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */ +#define SQLITE_CREATE_TABLE 2 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */ +#define SQLITE_CREATE_TEMP_TABLE 4 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_TRIGGER 5 /* Trigger Name Table Name */ +#define SQLITE_CREATE_TEMP_VIEW 6 /* View Name NULL */ +#define SQLITE_CREATE_TRIGGER 7 /* Trigger Name Table Name */ +#define SQLITE_CREATE_VIEW 8 /* View Name NULL */ +#define SQLITE_DELETE 9 /* Table Name NULL */ +#define SQLITE_DROP_INDEX 10 /* Index Name Table Name */ +#define SQLITE_DROP_TABLE 11 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_INDEX 12 /* Index Name Table Name */ +#define SQLITE_DROP_TEMP_TABLE 13 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_TRIGGER 14 /* Trigger Name Table Name */ +#define SQLITE_DROP_TEMP_VIEW 15 /* View Name NULL */ +#define SQLITE_DROP_TRIGGER 16 /* Trigger Name Table Name */ +#define SQLITE_DROP_VIEW 17 /* View Name NULL */ +#define SQLITE_INSERT 18 /* Table Name NULL */ +#define SQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */ +#define SQLITE_READ 20 /* Table Name Column Name */ +#define SQLITE_SELECT 21 /* NULL NULL */ +#define SQLITE_TRANSACTION 22 /* Operation NULL */ +#define SQLITE_UPDATE 23 /* Table Name Column Name */ +#define SQLITE_ATTACH 24 /* Filename NULL */ +#define SQLITE_DETACH 25 /* Database Name NULL */ +#define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */ +#define SQLITE_REINDEX 27 /* Index Name NULL */ +#define SQLITE_ANALYZE 28 /* Table Name NULL */ +#define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */ +#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */ +#define SQLITE_FUNCTION 31 /* NULL Function Name */ +#define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */ +#define SQLITE_COPY 0 /* No longer used */ + +/* +** CAPI3REF: Tracing And Profiling Functions +** +** These routines register callback functions that can be used for +** tracing and profiling the execution of SQL statements. +** +** ^The callback function registered by sqlite3_trace() is invoked at +** various times when an SQL statement is being run by [sqlite3_step()]. +** ^The sqlite3_trace() callback is invoked with a UTF-8 rendering of the +** SQL statement text as the statement first begins executing. +** ^(Additional sqlite3_trace() callbacks might occur +** as each triggered subprogram is entered. The callbacks for triggers +** contain a UTF-8 SQL comment that identifies the trigger.)^ +** +** ^The callback function registered by sqlite3_profile() is invoked +** as each SQL statement finishes. ^The profile callback contains +** the original statement text and an estimate of wall-clock time +** of how long that statement took to run. ^The profile callback +** time is in units of nanoseconds, however the current implementation +** is only capable of millisecond resolution so the six least significant +** digits in the time are meaningless. Future versions of SQLite +** might provide greater resolution on the profiler callback. The +** sqlite3_profile() function is considered experimental and is +** subject to change in future versions of SQLite. +*/ +SQLITE_API void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); +SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*, + void(*xProfile)(void*,const char*,sqlite3_uint64), void*); + +/* +** CAPI3REF: Query Progress Callbacks +** +** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback +** function X to be invoked periodically during long running calls to +** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for +** database connection D. An example use for this +** interface is to keep a GUI updated during a large query. +** +** ^The parameter P is passed through as the only parameter to the +** callback function X. ^The parameter N is the number of +** [virtual machine instructions] that are evaluated between successive +** invocations of the callback X. +** +** ^Only a single progress handler may be defined at one time per +** [database connection]; setting a new progress handler cancels the +** old one. ^Setting parameter X to NULL disables the progress handler. +** ^The progress handler is also disabled by setting N to a value less +** than 1. +** +** ^If the progress callback returns non-zero, the operation is +** interrupted. This feature can be used to implement a +** "Cancel" button on a GUI progress dialog box. +** +** The progress handler callback must not do anything that will modify +** the database connection that invoked the progress handler. +** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their +** database connections for the meaning of "modify" in this paragraph. +** +*/ +SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); + +/* +** CAPI3REF: Opening A New Database Connection +** +** ^These routines open an SQLite database file as specified by the +** filename argument. ^The filename argument is interpreted as UTF-8 for +** sqlite3_open() and sqlite3_open_v2() and as UTF-16 in the native byte +** order for sqlite3_open16(). ^(A [database connection] handle is usually +** returned in *ppDb, even if an error occurs. The only exception is that +** if SQLite is unable to allocate memory to hold the [sqlite3] object, +** a NULL will be written into *ppDb instead of a pointer to the [sqlite3] +** object.)^ ^(If the database is opened (and/or created) successfully, then +** [SQLITE_OK] is returned. Otherwise an [error code] is returned.)^ ^The +** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain +** an English language description of the error following a failure of any +** of the sqlite3_open() routines. +** +** ^The default encoding for the database will be UTF-8 if +** sqlite3_open() or sqlite3_open_v2() is called and +** UTF-16 in the native byte order if sqlite3_open16() is used. +** +** Whether or not an error occurs when it is opened, resources +** associated with the [database connection] handle should be released by +** passing it to [sqlite3_close()] when it is no longer required. +** +** The sqlite3_open_v2() interface works like sqlite3_open() +** except that it accepts two additional parameters for additional control +** over the new database connection. ^(The flags parameter to +** sqlite3_open_v2() can take one of +** the following three values, optionally combined with the +** [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX], [SQLITE_OPEN_SHAREDCACHE], +** [SQLITE_OPEN_PRIVATECACHE], and/or [SQLITE_OPEN_URI] flags:)^ +** +**
+** ^(
[SQLITE_OPEN_READONLY]
+**
The database is opened in read-only mode. If the database does not +** already exist, an error is returned.
)^ +** +** ^(
[SQLITE_OPEN_READWRITE]
+**
The database is opened for reading and writing if possible, or reading +** only if the file is write protected by the operating system. In either +** case the database must already exist, otherwise an error is returned.
)^ +** +** ^(
[SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]
+**
The database is opened for reading and writing, and is created if +** it does not already exist. This is the behavior that is always used for +** sqlite3_open() and sqlite3_open16().
)^ +**
+** +** If the 3rd parameter to sqlite3_open_v2() is not one of the +** combinations shown above optionally combined with other +** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits] +** then the behavior is undefined. +** +** ^If the [SQLITE_OPEN_NOMUTEX] flag is set, then the database connection +** opens in the multi-thread [threading mode] as long as the single-thread +** mode has not been set at compile-time or start-time. ^If the +** [SQLITE_OPEN_FULLMUTEX] flag is set then the database connection opens +** in the serialized [threading mode] unless single-thread was +** previously selected at compile-time or start-time. +** ^The [SQLITE_OPEN_SHAREDCACHE] flag causes the database connection to be +** eligible to use [shared cache mode], regardless of whether or not shared +** cache is enabled using [sqlite3_enable_shared_cache()]. ^The +** [SQLITE_OPEN_PRIVATECACHE] flag causes the database connection to not +** participate in [shared cache mode] even if it is enabled. +** +** ^The fourth parameter to sqlite3_open_v2() is the name of the +** [sqlite3_vfs] object that defines the operating system interface that +** the new database connection should use. ^If the fourth parameter is +** a NULL pointer then the default [sqlite3_vfs] object is used. +** +** ^If the filename is ":memory:", then a private, temporary in-memory database +** is created for the connection. ^This in-memory database will vanish when +** the database connection is closed. Future versions of SQLite might +** make use of additional special filenames that begin with the ":" character. +** It is recommended that when a database filename actually does begin with +** a ":" character you should prefix the filename with a pathname such as +** "./" to avoid ambiguity. +** +** ^If the filename is an empty string, then a private, temporary +** on-disk database will be created. ^This private database will be +** automatically deleted as soon as the database connection is closed. +** +** [[URI filenames in sqlite3_open()]]

URI Filenames

+** +** ^If [URI filename] interpretation is enabled, and the filename argument +** begins with "file:", then the filename is interpreted as a URI. ^URI +** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is +** set in the fourth argument to sqlite3_open_v2(), or if it has +** been enabled globally using the [SQLITE_CONFIG_URI] option with the +** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option. +** As of SQLite version 3.7.7, URI filename interpretation is turned off +** by default, but future releases of SQLite might enable URI filename +** interpretation by default. See "[URI filenames]" for additional +** information. +** +** URI filenames are parsed according to RFC 3986. ^If the URI contains an +** authority, then it must be either an empty string or the string +** "localhost". ^If the authority is not an empty string or "localhost", an +** error is returned to the caller. ^The fragment component of a URI, if +** present, is ignored. +** +** ^SQLite uses the path component of the URI as the name of the disk file +** which contains the database. ^If the path begins with a '/' character, +** then it is interpreted as an absolute path. ^If the path does not begin +** with a '/' (meaning that the authority section is omitted from the URI) +** then the path is interpreted as a relative path. +** ^On windows, the first component of an absolute path +** is a drive specification (e.g. "C:"). +** +** [[core URI query parameters]] +** The query component of a URI may contain parameters that are interpreted +** either by SQLite itself, or by a [VFS | custom VFS implementation]. +** SQLite interprets the following three query parameters: +** +**
    +**
  • vfs: ^The "vfs" parameter may be used to specify the name of +** a VFS object that provides the operating system interface that should +** be used to access the database file on disk. ^If this option is set to +** an empty string the default VFS object is used. ^Specifying an unknown +** VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is +** present, then the VFS specified by the option takes precedence over +** the value passed as the fourth parameter to sqlite3_open_v2(). +** +**
  • mode: ^(The mode parameter may be set to either "ro", "rw" or +** "rwc". Attempting to set it to any other value is an error)^. +** ^If "ro" is specified, then the database is opened for read-only +** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the +** third argument to sqlite3_prepare_v2(). ^If the mode option is set to +** "rw", then the database is opened for read-write (but not create) +** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had +** been set. ^Value "rwc" is equivalent to setting both +** SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. ^If sqlite3_open_v2() is +** used, it is an error to specify a value for the mode parameter that is +** less restrictive than that specified by the flags passed as the third +** parameter. +** +**
  • cache: ^The cache parameter may be set to either "shared" or +** "private". ^Setting it to "shared" is equivalent to setting the +** SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to +** sqlite3_open_v2(). ^Setting the cache parameter to "private" is +** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit. +** ^If sqlite3_open_v2() is used and the "cache" parameter is present in +** a URI filename, its value overrides any behaviour requested by setting +** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag. +**
+** +** ^Specifying an unknown parameter in the query component of a URI is not an +** error. Future versions of SQLite might understand additional query +** parameters. See "[query parameters with special meaning to SQLite]" for +** additional information. +** +** [[URI filename examples]]

URI filename examples

+** +** +**
URI filenames Results +**
file:data.db +** Open the file "data.db" in the current directory. +**
file:/home/fred/data.db
+** file:///home/fred/data.db
+** file://localhost/home/fred/data.db
+** Open the database file "/home/fred/data.db". +**
file://darkstar/home/fred/data.db +** An error. "darkstar" is not a recognized authority. +**
+** file:///C:/Documents%20and%20Settings/fred/Desktop/data.db +** Windows only: Open the file "data.db" on fred's desktop on drive +** C:. Note that the %20 escaping in this example is not strictly +** necessary - space characters can be used literally +** in URI filenames. +**
file:data.db?mode=ro&cache=private +** Open file "data.db" in the current directory for read-only access. +** Regardless of whether or not shared-cache mode is enabled by +** default, use a private cache. +**
file:/home/fred/data.db?vfs=unix-nolock +** Open file "/home/fred/data.db". Use the special VFS "unix-nolock". +**
file:data.db?mode=readonly +** An error. "readonly" is not a valid option for the "mode" parameter. +**
+** +** ^URI hexadecimal escape sequences (%HH) are supported within the path and +** query components of a URI. A hexadecimal escape sequence consists of a +** percent sign - "%" - followed by exactly two hexadecimal digits +** specifying an octet value. ^Before the path or query components of a +** URI filename are interpreted, they are encoded using UTF-8 and all +** hexadecimal escape sequences replaced by a single byte containing the +** corresponding octet. If this process generates an invalid UTF-8 encoding, +** the results are undefined. +** +** Note to Windows users: The encoding used for the filename argument +** of sqlite3_open() and sqlite3_open_v2() must be UTF-8, not whatever +** codepage is currently defined. Filenames containing international +** characters must be converted to UTF-8 prior to passing them into +** sqlite3_open() or sqlite3_open_v2(). +*/ +SQLITE_API int sqlite3_open( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +SQLITE_API int sqlite3_open16( + const void *filename, /* Database filename (UTF-16) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +SQLITE_API int sqlite3_open_v2( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs /* Name of VFS module to use */ +); + +/* +** CAPI3REF: Obtain Values For URI Parameters +** +** These are utility routines, useful to VFS implementations, that check +** to see if a database file was a URI that contained a specific query +** parameter, and if so obtains the value of that query parameter. +** +** If F is the database filename pointer passed into the xOpen() method of +** a VFS implementation when the flags parameter to xOpen() has one or +** more of the [SQLITE_OPEN_URI] or [SQLITE_OPEN_MAIN_DB] bits set and +** P is the name of the query parameter, then +** sqlite3_uri_parameter(F,P) returns the value of the P +** parameter if it exists or a NULL pointer if P does not appear as a +** query parameter on F. If P is a query parameter of F +** has no explicit value, then sqlite3_uri_parameter(F,P) returns +** a pointer to an empty string. +** +** The sqlite3_uri_boolean(F,P,B) routine assumes that P is a boolean +** parameter and returns true (1) or false (0) according to the value +** of P. The value of P is true if it is "yes" or "true" or "on" or +** a non-zero number and is false otherwise. If P is not a query parameter +** on F then sqlite3_uri_boolean(F,P,B) returns (B!=0). +** +** The sqlite3_uri_int64(F,P,D) routine converts the value of P into a +** 64-bit signed integer and returns that integer, or D if P does not +** exist. If the value of P is something other than an integer, then +** zero is returned. +** +** If F is a NULL pointer, then sqlite3_uri_parameter(F,P) returns NULL and +** sqlite3_uri_boolean(F,P,B) returns B. If F is not a NULL pointer and +** is not a database file pathname pointer that SQLite passed into the xOpen +** VFS method, then the behavior of this routine is undefined and probably +** undesirable. +*/ +SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam); +SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault); +SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64); + + +/* +** CAPI3REF: Error Codes And Messages +** +** ^The sqlite3_errcode() interface returns the numeric [result code] or +** [extended result code] for the most recent failed sqlite3_* API call +** associated with a [database connection]. If a prior API call failed +** but the most recent API call succeeded, the return value from +** sqlite3_errcode() is undefined. ^The sqlite3_extended_errcode() +** interface is the same except that it always returns the +** [extended result code] even when extended result codes are +** disabled. +** +** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language +** text that describes the error, as either UTF-8 or UTF-16 respectively. +** ^(Memory to hold the error message string is managed internally. +** The application does not need to worry about freeing the result. +** However, the error string might be overwritten or deallocated by +** subsequent calls to other SQLite interface functions.)^ +** +** When the serialized [threading mode] is in use, it might be the +** case that a second error occurs on a separate thread in between +** the time of the first error and the call to these interfaces. +** When that happens, the second error will be reported since these +** interfaces always report the most recent result. To avoid +** this, each thread can obtain exclusive use of the [database connection] D +** by invoking [sqlite3_mutex_enter]([sqlite3_db_mutex](D)) before beginning +** to use D and invoking [sqlite3_mutex_leave]([sqlite3_db_mutex](D)) after +** all calls to the interfaces listed here are completed. +** +** If an interface fails with SQLITE_MISUSE, that means the interface +** was invoked incorrectly by the application. In that case, the +** error code and message may or may not be set. +*/ +SQLITE_API int sqlite3_errcode(sqlite3 *db); +SQLITE_API int sqlite3_extended_errcode(sqlite3 *db); +SQLITE_API const char *sqlite3_errmsg(sqlite3*); +SQLITE_API const void *sqlite3_errmsg16(sqlite3*); + +/* +** CAPI3REF: SQL Statement Object +** KEYWORDS: {prepared statement} {prepared statements} +** +** An instance of this object represents a single SQL statement. +** This object is variously known as a "prepared statement" or a +** "compiled SQL statement" or simply as a "statement". +** +** The life of a statement object goes something like this: +** +**
    +**
  1. Create the object using [sqlite3_prepare_v2()] or a related +** function. +**
  2. Bind values to [host parameters] using the sqlite3_bind_*() +** interfaces. +**
  3. Run the SQL by calling [sqlite3_step()] one or more times. +**
  4. Reset the statement using [sqlite3_reset()] then go back +** to step 2. Do this zero or more times. +**
  5. Destroy the object using [sqlite3_finalize()]. +**
+** +** Refer to documentation on individual methods above for additional +** information. +*/ +typedef struct sqlite3_stmt sqlite3_stmt; + +/* +** CAPI3REF: Run-time Limits +** +** ^(This interface allows the size of various constructs to be limited +** on a connection by connection basis. The first parameter is the +** [database connection] whose limit is to be set or queried. The +** second parameter is one of the [limit categories] that define a +** class of constructs to be size limited. The third parameter is the +** new limit for that construct.)^ +** +** ^If the new limit is a negative number, the limit is unchanged. +** ^(For each limit category SQLITE_LIMIT_NAME there is a +** [limits | hard upper bound] +** set at compile-time by a C preprocessor macro called +** [limits | SQLITE_MAX_NAME]. +** (The "_LIMIT_" in the name is changed to "_MAX_".))^ +** ^Attempts to increase a limit above its hard upper bound are +** silently truncated to the hard upper bound. +** +** ^Regardless of whether or not the limit was changed, the +** [sqlite3_limit()] interface returns the prior value of the limit. +** ^Hence, to find the current value of a limit without changing it, +** simply invoke this interface with the third parameter set to -1. +** +** Run-time limits are intended for use in applications that manage +** both their own internal database and also databases that are controlled +** by untrusted external sources. An example application might be a +** web browser that has its own databases for storing history and +** separate databases controlled by JavaScript applications downloaded +** off the Internet. The internal databases can be given the +** large, default limits. Databases managed by external sources can +** be given much smaller limits designed to prevent a denial of service +** attack. Developers might also want to use the [sqlite3_set_authorizer()] +** interface to further control untrusted SQL. The size of the database +** created by an untrusted script can be contained using the +** [max_page_count] [PRAGMA]. +** +** New run-time limit categories may be added in future releases. +*/ +SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); + +/* +** CAPI3REF: Run-Time Limit Categories +** KEYWORDS: {limit category} {*limit categories} +** +** These constants define various performance limits +** that can be lowered at run-time using [sqlite3_limit()]. +** The synopsis of the meanings of the various limits is shown below. +** Additional information is available at [limits | Limits in SQLite]. +** +**
+** [[SQLITE_LIMIT_LENGTH]] ^(
SQLITE_LIMIT_LENGTH
+**
The maximum size of any string or BLOB or table row, in bytes.
)^ +** +** [[SQLITE_LIMIT_SQL_LENGTH]] ^(
SQLITE_LIMIT_SQL_LENGTH
+**
The maximum length of an SQL statement, in bytes.
)^ +** +** [[SQLITE_LIMIT_COLUMN]] ^(
SQLITE_LIMIT_COLUMN
+**
The maximum number of columns in a table definition or in the +** result set of a [SELECT] or the maximum number of columns in an index +** or in an ORDER BY or GROUP BY clause.
)^ +** +** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(
SQLITE_LIMIT_EXPR_DEPTH
+**
The maximum depth of the parse tree on any expression.
)^ +** +** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(
SQLITE_LIMIT_COMPOUND_SELECT
+**
The maximum number of terms in a compound SELECT statement.
)^ +** +** [[SQLITE_LIMIT_VDBE_OP]] ^(
SQLITE_LIMIT_VDBE_OP
+**
The maximum number of instructions in a virtual machine program +** used to implement an SQL statement. This limit is not currently +** enforced, though that might be added in some future release of +** SQLite.
)^ +** +** [[SQLITE_LIMIT_FUNCTION_ARG]] ^(
SQLITE_LIMIT_FUNCTION_ARG
+**
The maximum number of arguments on a function.
)^ +** +** [[SQLITE_LIMIT_ATTACHED]] ^(
SQLITE_LIMIT_ATTACHED
+**
The maximum number of [ATTACH | attached databases].)^
+** +** [[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]] +** ^(
SQLITE_LIMIT_LIKE_PATTERN_LENGTH
+**
The maximum length of the pattern argument to the [LIKE] or +** [GLOB] operators.
)^ +** +** [[SQLITE_LIMIT_VARIABLE_NUMBER]] +** ^(
SQLITE_LIMIT_VARIABLE_NUMBER
+**
The maximum index number of any [parameter] in an SQL statement.)^ +** +** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(
SQLITE_LIMIT_TRIGGER_DEPTH
+**
The maximum depth of recursion for triggers.
)^ +**
+*/ +#define SQLITE_LIMIT_LENGTH 0 +#define SQLITE_LIMIT_SQL_LENGTH 1 +#define SQLITE_LIMIT_COLUMN 2 +#define SQLITE_LIMIT_EXPR_DEPTH 3 +#define SQLITE_LIMIT_COMPOUND_SELECT 4 +#define SQLITE_LIMIT_VDBE_OP 5 +#define SQLITE_LIMIT_FUNCTION_ARG 6 +#define SQLITE_LIMIT_ATTACHED 7 +#define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8 +#define SQLITE_LIMIT_VARIABLE_NUMBER 9 +#define SQLITE_LIMIT_TRIGGER_DEPTH 10 + +/* +** CAPI3REF: Compiling An SQL Statement +** KEYWORDS: {SQL statement compiler} +** +** To execute an SQL query, it must first be compiled into a byte-code +** program using one of these routines. +** +** The first argument, "db", is a [database connection] obtained from a +** prior successful call to [sqlite3_open()], [sqlite3_open_v2()] or +** [sqlite3_open16()]. The database connection must not have been closed. +** +** The second argument, "zSql", is the statement to be compiled, encoded +** as either UTF-8 or UTF-16. The sqlite3_prepare() and sqlite3_prepare_v2() +** interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2() +** use UTF-16. +** +** ^If the nByte argument is less than zero, then zSql is read up to the +** first zero terminator. ^If nByte is non-negative, then it is the maximum +** number of bytes read from zSql. ^When nByte is non-negative, the +** zSql string ends at either the first '\000' or '\u0000' character or +** the nByte-th byte, whichever comes first. If the caller knows +** that the supplied string is nul-terminated, then there is a small +** performance advantage to be gained by passing an nByte parameter that +** is equal to the number of bytes in the input string including +** the nul-terminator bytes as this saves SQLite from having to +** make a copy of the input string. +** +** ^If pzTail is not NULL then *pzTail is made to point to the first byte +** past the end of the first SQL statement in zSql. These routines only +** compile the first statement in zSql, so *pzTail is left pointing to +** what remains uncompiled. +** +** ^*ppStmt is left pointing to a compiled [prepared statement] that can be +** executed using [sqlite3_step()]. ^If there is an error, *ppStmt is set +** to NULL. ^If the input text contains no SQL (if the input is an empty +** string or a comment) then *ppStmt is set to NULL. +** The calling procedure is responsible for deleting the compiled +** SQL statement using [sqlite3_finalize()] after it has finished with it. +** ppStmt may not be NULL. +** +** ^On success, the sqlite3_prepare() family of routines return [SQLITE_OK]; +** otherwise an [error code] is returned. +** +** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are +** recommended for all new programs. The two older interfaces are retained +** for backwards compatibility, but their use is discouraged. +** ^In the "v2" interfaces, the prepared statement +** that is returned (the [sqlite3_stmt] object) contains a copy of the +** original SQL text. This causes the [sqlite3_step()] interface to +** behave differently in three ways: +** +**
    +**
  1. +** ^If the database schema changes, instead of returning [SQLITE_SCHEMA] as it +** always used to do, [sqlite3_step()] will automatically recompile the SQL +** statement and try to run it again. +**
  2. +** +**
  3. +** ^When an error occurs, [sqlite3_step()] will return one of the detailed +** [error codes] or [extended error codes]. ^The legacy behavior was that +** [sqlite3_step()] would only return a generic [SQLITE_ERROR] result code +** and the application would have to make a second call to [sqlite3_reset()] +** in order to find the underlying cause of the problem. With the "v2" prepare +** interfaces, the underlying reason for the error is returned immediately. +**
  4. +** +**
  5. +** ^If the specific value bound to [parameter | host parameter] in the +** WHERE clause might influence the choice of query plan for a statement, +** then the statement will be automatically recompiled, as if there had been +** a schema change, on the first [sqlite3_step()] call following any change +** to the [sqlite3_bind_text | bindings] of that [parameter]. +** ^The specific value of WHERE-clause [parameter] might influence the +** choice of query plan if the parameter is the left-hand side of a [LIKE] +** or [GLOB] operator or if the parameter is compared to an indexed column +** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled. +** the +**
  6. +**
+*/ +SQLITE_API int sqlite3_prepare( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +SQLITE_API int sqlite3_prepare_v2( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +SQLITE_API int sqlite3_prepare16( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); +SQLITE_API int sqlite3_prepare16_v2( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); + +/* +** CAPI3REF: Retrieving Statement SQL +** +** ^This interface can be used to retrieve a saved copy of the original +** SQL text used to create a [prepared statement] if that statement was +** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()]. +*/ +SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Determine If An SQL Statement Writes The Database +** +** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if +** and only if the [prepared statement] X makes no direct changes to +** the content of the database file. +** +** Note that [application-defined SQL functions] or +** [virtual tables] might change the database indirectly as a side effect. +** ^(For example, if an application defines a function "eval()" that +** calls [sqlite3_exec()], then the following SQL statement would +** change the database file through side-effects: +** +**
+**    SELECT eval('DELETE FROM t1') FROM t2;
+** 
+** +** But because the [SELECT] statement does not change the database file +** directly, sqlite3_stmt_readonly() would still return true.)^ +** +** ^Transaction control statements such as [BEGIN], [COMMIT], [ROLLBACK], +** [SAVEPOINT], and [RELEASE] cause sqlite3_stmt_readonly() to return true, +** since the statements themselves do not actually modify the database but +** rather they control the timing of when other statements modify the +** database. ^The [ATTACH] and [DETACH] statements also cause +** sqlite3_stmt_readonly() to return true since, while those statements +** change the configuration of a database connection, they do not make +** changes to the content of the database files on disk. +*/ +SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Determine If A Prepared Statement Has Been Reset +** +** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the +** [prepared statement] S has been stepped at least once using +** [sqlite3_step(S)] but has not run to completion and/or has not +** been reset using [sqlite3_reset(S)]. ^The sqlite3_stmt_busy(S) +** interface returns false if S is a NULL pointer. If S is not a +** NULL pointer and is not a pointer to a valid [prepared statement] +** object, then the behavior is undefined and probably undesirable. +** +** This interface can be used in combination [sqlite3_next_stmt()] +** to locate all prepared statements associated with a database +** connection that are in need of being reset. This can be used, +** for example, in diagnostic routines to search for prepared +** statements that are holding a transaction open. +*/ +SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*); + +/* +** CAPI3REF: Dynamically Typed Value Object +** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value} +** +** SQLite uses the sqlite3_value object to represent all values +** that can be stored in a database table. SQLite uses dynamic typing +** for the values it stores. ^Values stored in sqlite3_value objects +** can be integers, floating point values, strings, BLOBs, or NULL. +** +** An sqlite3_value object may be either "protected" or "unprotected". +** Some interfaces require a protected sqlite3_value. Other interfaces +** will accept either a protected or an unprotected sqlite3_value. +** Every interface that accepts sqlite3_value arguments specifies +** whether or not it requires a protected sqlite3_value. +** +** The terms "protected" and "unprotected" refer to whether or not +** a mutex is held. An internal mutex is held for a protected +** sqlite3_value object but no mutex is held for an unprotected +** sqlite3_value object. If SQLite is compiled to be single-threaded +** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0) +** or if SQLite is run in one of reduced mutex modes +** [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD] +** then there is no distinction between protected and unprotected +** sqlite3_value objects and they can be used interchangeably. However, +** for maximum code portability it is recommended that applications +** still make the distinction between protected and unprotected +** sqlite3_value objects even when not strictly required. +** +** ^The sqlite3_value objects that are passed as parameters into the +** implementation of [application-defined SQL functions] are protected. +** ^The sqlite3_value object returned by +** [sqlite3_column_value()] is unprotected. +** Unprotected sqlite3_value objects may only be used with +** [sqlite3_result_value()] and [sqlite3_bind_value()]. +** The [sqlite3_value_blob | sqlite3_value_type()] family of +** interfaces require protected sqlite3_value objects. +*/ +typedef struct Mem sqlite3_value; + +/* +** CAPI3REF: SQL Function Context Object +** +** The context in which an SQL function executes is stored in an +** sqlite3_context object. ^A pointer to an sqlite3_context object +** is always first parameter to [application-defined SQL functions]. +** The application-defined SQL function implementation will pass this +** pointer through into calls to [sqlite3_result_int | sqlite3_result()], +** [sqlite3_aggregate_context()], [sqlite3_user_data()], +** [sqlite3_context_db_handle()], [sqlite3_get_auxdata()], +** and/or [sqlite3_set_auxdata()]. +*/ +typedef struct sqlite3_context sqlite3_context; + +/* +** CAPI3REF: Binding Values To Prepared Statements +** KEYWORDS: {host parameter} {host parameters} {host parameter name} +** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding} +** +** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, +** literals may be replaced by a [parameter] that matches one of following +** templates: +** +**
    +**
  • ? +**
  • ?NNN +**
  • :VVV +**
  • @VVV +**
  • $VVV +**
+** +** In the templates above, NNN represents an integer literal, +** and VVV represents an alphanumeric identifier.)^ ^The values of these +** parameters (also called "host parameter names" or "SQL parameters") +** can be set using the sqlite3_bind_*() routines defined here. +** +** ^The first argument to the sqlite3_bind_*() routines is always +** a pointer to the [sqlite3_stmt] object returned from +** [sqlite3_prepare_v2()] or its variants. +** +** ^The second argument is the index of the SQL parameter to be set. +** ^The leftmost SQL parameter has an index of 1. ^When the same named +** SQL parameter is used more than once, second and subsequent +** occurrences have the same index as the first occurrence. +** ^The index for named parameters can be looked up using the +** [sqlite3_bind_parameter_index()] API if desired. ^The index +** for "?NNN" parameters is the value of NNN. +** ^The NNN value must be between 1 and the [sqlite3_limit()] +** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 999). +** +** ^The third argument is the value to bind to the parameter. +** +** ^(In those routines that have a fourth argument, its value is the +** number of bytes in the parameter. To be clear: the value is the +** number of bytes in the value, not the number of characters.)^ +** ^If the fourth parameter is negative, the length of the string is +** the number of bytes up to the first zero terminator. +** If a non-negative fourth parameter is provided to sqlite3_bind_text() +** or sqlite3_bind_text16() then that parameter must be the byte offset +** where the NUL terminator would occur assuming the string were NUL +** terminated. If any NUL characters occur at byte offsets less than +** the value of the fourth parameter then the resulting string value will +** contain embedded NULs. The result of expressions involving strings +** with embedded NULs is undefined. +** +** ^The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and +** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or +** string after SQLite has finished with it. ^The destructor is called +** to dispose of the BLOB or string even if the call to sqlite3_bind_blob(), +** sqlite3_bind_text(), or sqlite3_bind_text16() fails. +** ^If the fifth argument is +** the special value [SQLITE_STATIC], then SQLite assumes that the +** information is in static, unmanaged space and does not need to be freed. +** ^If the fifth argument has the value [SQLITE_TRANSIENT], then +** SQLite makes its own private copy of the data immediately, before +** the sqlite3_bind_*() routine returns. +** +** ^The sqlite3_bind_zeroblob() routine binds a BLOB of length N that +** is filled with zeroes. ^A zeroblob uses a fixed amount of memory +** (just an integer to hold its size) while it is being processed. +** Zeroblobs are intended to serve as placeholders for BLOBs whose +** content is later written using +** [sqlite3_blob_open | incremental BLOB I/O] routines. +** ^A negative value for the zeroblob results in a zero-length BLOB. +** +** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer +** for the [prepared statement] or with a prepared statement for which +** [sqlite3_step()] has been called more recently than [sqlite3_reset()], +** then the call will return [SQLITE_MISUSE]. If any sqlite3_bind_() +** routine is passed a [prepared statement] that has been finalized, the +** result is undefined and probably harmful. +** +** ^Bindings are not cleared by the [sqlite3_reset()] routine. +** ^Unbound parameters are interpreted as NULL. +** +** ^The sqlite3_bind_* routines return [SQLITE_OK] on success or an +** [error code] if anything goes wrong. +** ^[SQLITE_RANGE] is returned if the parameter +** index is out of range. ^[SQLITE_NOMEM] is returned if malloc() fails. +** +** See also: [sqlite3_bind_parameter_count()], +** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); +SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double); +SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int); +SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); +SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int); +SQLITE_API int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*)); +SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); +SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); +SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); + +/* +** CAPI3REF: Number Of SQL Parameters +** +** ^This routine can be used to find the number of [SQL parameters] +** in a [prepared statement]. SQL parameters are tokens of the +** form "?", "?NNN", ":AAA", "$AAA", or "@AAA" that serve as +** placeholders for values that are [sqlite3_bind_blob | bound] +** to the parameters at a later time. +** +** ^(This routine actually returns the index of the largest (rightmost) +** parameter. For all forms except ?NNN, this will correspond to the +** number of unique parameters. If parameters of the ?NNN form are used, +** there may be gaps in the list.)^ +** +** See also: [sqlite3_bind_blob|sqlite3_bind()], +** [sqlite3_bind_parameter_name()], and +** [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*); + +/* +** CAPI3REF: Name Of A Host Parameter +** +** ^The sqlite3_bind_parameter_name(P,N) interface returns +** the name of the N-th [SQL parameter] in the [prepared statement] P. +** ^(SQL parameters of the form "?NNN" or ":AAA" or "@AAA" or "$AAA" +** have a name which is the string "?NNN" or ":AAA" or "@AAA" or "$AAA" +** respectively. +** In other words, the initial ":" or "$" or "@" or "?" +** is included as part of the name.)^ +** ^Parameters of the form "?" without a following integer have no name +** and are referred to as "nameless" or "anonymous parameters". +** +** ^The first host parameter has an index of 1, not 0. +** +** ^If the value N is out of range or if the N-th parameter is +** nameless, then NULL is returned. ^The returned string is +** always in UTF-8 encoding even if the named parameter was +** originally specified as UTF-16 in [sqlite3_prepare16()] or +** [sqlite3_prepare16_v2()]. +** +** See also: [sqlite3_bind_blob|sqlite3_bind()], +** [sqlite3_bind_parameter_count()], and +** [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); + +/* +** CAPI3REF: Index Of A Parameter With A Given Name +** +** ^Return the index of an SQL parameter given its name. ^The +** index value returned is suitable for use as the second +** parameter to [sqlite3_bind_blob|sqlite3_bind()]. ^A zero +** is returned if no matching parameter is found. ^The parameter +** name must be given in UTF-8 even if the original statement +** was prepared from UTF-16 text using [sqlite3_prepare16_v2()]. +** +** See also: [sqlite3_bind_blob|sqlite3_bind()], +** [sqlite3_bind_parameter_count()], and +** [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); + +/* +** CAPI3REF: Reset All Bindings On A Prepared Statement +** +** ^Contrary to the intuition of many, [sqlite3_reset()] does not reset +** the [sqlite3_bind_blob | bindings] on a [prepared statement]. +** ^Use this routine to reset all host parameters to NULL. +*/ +SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*); + +/* +** CAPI3REF: Number Of Columns In A Result Set +** +** ^Return the number of columns in the result set returned by the +** [prepared statement]. ^This routine returns 0 if pStmt is an SQL +** statement that does not return data (for example an [UPDATE]). +** +** See also: [sqlite3_data_count()] +*/ +SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Column Names In A Result Set +** +** ^These routines return the name assigned to a particular column +** in the result set of a [SELECT] statement. ^The sqlite3_column_name() +** interface returns a pointer to a zero-terminated UTF-8 string +** and sqlite3_column_name16() returns a pointer to a zero-terminated +** UTF-16 string. ^The first parameter is the [prepared statement] +** that implements the [SELECT] statement. ^The second parameter is the +** column number. ^The leftmost column is number 0. +** +** ^The returned string pointer is valid until either the [prepared statement] +** is destroyed by [sqlite3_finalize()] or until the statement is automatically +** reprepared by the first call to [sqlite3_step()] for a particular run +** or until the next call to +** sqlite3_column_name() or sqlite3_column_name16() on the same column. +** +** ^If sqlite3_malloc() fails during the processing of either routine +** (for example during a conversion from UTF-8 to UTF-16) then a +** NULL pointer is returned. +** +** ^The name of a result column is the value of the "AS" clause for +** that column, if there is an AS clause. If there is no AS clause +** then the name of the column is unspecified and may change from +** one release of SQLite to the next. +*/ +SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N); +SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N); + +/* +** CAPI3REF: Source Of Data In A Query Result +** +** ^These routines provide a means to determine the database, table, and +** table column that is the origin of a particular result column in +** [SELECT] statement. +** ^The name of the database or table or column can be returned as +** either a UTF-8 or UTF-16 string. ^The _database_ routines return +** the database name, the _table_ routines return the table name, and +** the origin_ routines return the column name. +** ^The returned string is valid until the [prepared statement] is destroyed +** using [sqlite3_finalize()] or until the statement is automatically +** reprepared by the first call to [sqlite3_step()] for a particular run +** or until the same information is requested +** again in a different encoding. +** +** ^The names returned are the original un-aliased names of the +** database, table, and column. +** +** ^The first argument to these interfaces is a [prepared statement]. +** ^These functions return information about the Nth result column returned by +** the statement, where N is the second function argument. +** ^The left-most column is column 0 for these routines. +** +** ^If the Nth column returned by the statement is an expression or +** subquery and is not a column value, then all of these functions return +** NULL. ^These routine might also return NULL if a memory allocation error +** occurs. ^Otherwise, they return the name of the attached database, table, +** or column that query result column was extracted from. +** +** ^As with all other SQLite APIs, those whose names end with "16" return +** UTF-16 encoded strings and the other functions return UTF-8. +** +** ^These APIs are only available if the library was compiled with the +** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol. +** +** If two or more threads call one or more of these routines against the same +** prepared statement and column at the same time then the results are +** undefined. +** +** If two or more threads call one or more +** [sqlite3_column_database_name | column metadata interfaces] +** for the same [prepared statement] and result column +** at the same time then the results are undefined. +*/ +SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int); +SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int); +SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Declared Datatype Of A Query Result +** +** ^(The first parameter is a [prepared statement]. +** If this statement is a [SELECT] statement and the Nth column of the +** returned result set of that [SELECT] is a table column (not an +** expression or subquery) then the declared type of the table +** column is returned.)^ ^If the Nth column of the result set is an +** expression or subquery, then a NULL pointer is returned. +** ^The returned string is always UTF-8 encoded. +** +** ^(For example, given the database schema: +** +** CREATE TABLE t1(c1 VARIANT); +** +** and the following statement to be compiled: +** +** SELECT c1 + 1, c1 FROM t1; +** +** this routine would return the string "VARIANT" for the second result +** column (i==1), and a NULL pointer for the first result column (i==0).)^ +** +** ^SQLite uses dynamic run-time typing. ^So just because a column +** is declared to contain a particular type does not mean that the +** data stored in that column is of the declared type. SQLite is +** strongly typed, but the typing is dynamic not static. ^Type +** is associated with individual values, not with the containers +** used to hold those values. +*/ +SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Evaluate An SQL Statement +** +** After a [prepared statement] has been prepared using either +** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy +** interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function +** must be called one or more times to evaluate the statement. +** +** The details of the behavior of the sqlite3_step() interface depend +** on whether the statement was prepared using the newer "v2" interface +** [sqlite3_prepare_v2()] and [sqlite3_prepare16_v2()] or the older legacy +** interface [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the +** new "v2" interface is recommended for new applications but the legacy +** interface will continue to be supported. +** +** ^In the legacy interface, the return value will be either [SQLITE_BUSY], +** [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE]. +** ^With the "v2" interface, any of the other [result codes] or +** [extended result codes] might be returned as well. +** +** ^[SQLITE_BUSY] means that the database engine was unable to acquire the +** database locks it needs to do its job. ^If the statement is a [COMMIT] +** or occurs outside of an explicit transaction, then you can retry the +** statement. If the statement is not a [COMMIT] and occurs within an +** explicit transaction then you should rollback the transaction before +** continuing. +** +** ^[SQLITE_DONE] means that the statement has finished executing +** successfully. sqlite3_step() should not be called again on this virtual +** machine without first calling [sqlite3_reset()] to reset the virtual +** machine back to its initial state. +** +** ^If the SQL statement being executed returns any data, then [SQLITE_ROW] +** is returned each time a new row of data is ready for processing by the +** caller. The values may be accessed using the [column access functions]. +** sqlite3_step() is called again to retrieve the next row of data. +** +** ^[SQLITE_ERROR] means that a run-time error (such as a constraint +** violation) has occurred. sqlite3_step() should not be called again on +** the VM. More information may be found by calling [sqlite3_errmsg()]. +** ^With the legacy interface, a more specific error code (for example, +** [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth) +** can be obtained by calling [sqlite3_reset()] on the +** [prepared statement]. ^In the "v2" interface, +** the more specific error code is returned directly by sqlite3_step(). +** +** [SQLITE_MISUSE] means that the this routine was called inappropriately. +** Perhaps it was called on a [prepared statement] that has +** already been [sqlite3_finalize | finalized] or on one that had +** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could +** be the case that the same database connection is being used by two or +** more threads at the same moment in time. +** +** For all versions of SQLite up to and including 3.6.23.1, a call to +** [sqlite3_reset()] was required after sqlite3_step() returned anything +** other than [SQLITE_ROW] before any subsequent invocation of +** sqlite3_step(). Failure to reset the prepared statement using +** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from +** sqlite3_step(). But after version 3.6.23.1, sqlite3_step() began +** calling [sqlite3_reset()] automatically in this circumstance rather +** than returning [SQLITE_MISUSE]. This is not considered a compatibility +** break because any application that ever receives an SQLITE_MISUSE error +** is broken by definition. The [SQLITE_OMIT_AUTORESET] compile-time option +** can be used to restore the legacy behavior. +** +** Goofy Interface Alert: In the legacy interface, the sqlite3_step() +** API always returns a generic error code, [SQLITE_ERROR], following any +** error other than [SQLITE_BUSY] and [SQLITE_MISUSE]. You must call +** [sqlite3_reset()] or [sqlite3_finalize()] in order to find one of the +** specific [error codes] that better describes the error. +** We admit that this is a goofy design. The problem has been fixed +** with the "v2" interface. If you prepare all of your SQL statements +** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead +** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces, +** then the more specific [error codes] are returned directly +** by sqlite3_step(). The use of the "v2" interface is recommended. +*/ +SQLITE_API int sqlite3_step(sqlite3_stmt*); + +/* +** CAPI3REF: Number of columns in a result set +** +** ^The sqlite3_data_count(P) interface returns the number of columns in the +** current row of the result set of [prepared statement] P. +** ^If prepared statement P does not have results ready to return +** (via calls to the [sqlite3_column_int | sqlite3_column_*()] of +** interfaces) then sqlite3_data_count(P) returns 0. +** ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer. +** ^The sqlite3_data_count(P) routine returns 0 if the previous call to +** [sqlite3_step](P) returned [SQLITE_DONE]. ^The sqlite3_data_count(P) +** will return non-zero if previous call to [sqlite3_step](P) returned +** [SQLITE_ROW], except in the case of the [PRAGMA incremental_vacuum] +** where it always returns zero since each step of that multi-step +** pragma returns 0 columns of data. +** +** See also: [sqlite3_column_count()] +*/ +SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Fundamental Datatypes +** KEYWORDS: SQLITE_TEXT +** +** ^(Every value in SQLite has one of five fundamental datatypes: +** +**
    +**
  • 64-bit signed integer +**
  • 64-bit IEEE floating point number +**
  • string +**
  • BLOB +**
  • NULL +**
)^ +** +** These constants are codes for each of those types. +** +** Note that the SQLITE_TEXT constant was also used in SQLite version 2 +** for a completely different meaning. Software that links against both +** SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT, not +** SQLITE_TEXT. +*/ +#define SQLITE_INTEGER 1 +#define SQLITE_FLOAT 2 +#define SQLITE_BLOB 4 +#define SQLITE_NULL 5 +#ifdef SQLITE_TEXT +# undef SQLITE_TEXT +#else +# define SQLITE_TEXT 3 +#endif +#define SQLITE3_TEXT 3 + +/* +** CAPI3REF: Result Values From A Query +** KEYWORDS: {column access functions} +** +** These routines form the "result set" interface. +** +** ^These routines return information about a single column of the current +** result row of a query. ^In every case the first argument is a pointer +** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*] +** that was returned from [sqlite3_prepare_v2()] or one of its variants) +** and the second argument is the index of the column for which information +** should be returned. ^The leftmost column of the result set has the index 0. +** ^The number of columns in the result can be determined using +** [sqlite3_column_count()]. +** +** If the SQL statement does not currently point to a valid row, or if the +** column index is out of range, the result is undefined. +** These routines may only be called when the most recent call to +** [sqlite3_step()] has returned [SQLITE_ROW] and neither +** [sqlite3_reset()] nor [sqlite3_finalize()] have been called subsequently. +** If any of these routines are called after [sqlite3_reset()] or +** [sqlite3_finalize()] or after [sqlite3_step()] has returned +** something other than [SQLITE_ROW], the results are undefined. +** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()] +** are called from a different thread while any of these routines +** are pending, then the results are undefined. +** +** ^The sqlite3_column_type() routine returns the +** [SQLITE_INTEGER | datatype code] for the initial data type +** of the result column. ^The returned value is one of [SQLITE_INTEGER], +** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL]. The value +** returned by sqlite3_column_type() is only meaningful if no type +** conversions have occurred as described below. After a type conversion, +** the value returned by sqlite3_column_type() is undefined. Future +** versions of SQLite may change the behavior of sqlite3_column_type() +** following a type conversion. +** +** ^If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes() +** routine returns the number of bytes in that BLOB or string. +** ^If the result is a UTF-16 string, then sqlite3_column_bytes() converts +** the string to UTF-8 and then returns the number of bytes. +** ^If the result is a numeric value then sqlite3_column_bytes() uses +** [sqlite3_snprintf()] to convert that value to a UTF-8 string and returns +** the number of bytes in that string. +** ^If the result is NULL, then sqlite3_column_bytes() returns zero. +** +** ^If the result is a BLOB or UTF-16 string then the sqlite3_column_bytes16() +** routine returns the number of bytes in that BLOB or string. +** ^If the result is a UTF-8 string, then sqlite3_column_bytes16() converts +** the string to UTF-16 and then returns the number of bytes. +** ^If the result is a numeric value then sqlite3_column_bytes16() uses +** [sqlite3_snprintf()] to convert that value to a UTF-16 string and returns +** the number of bytes in that string. +** ^If the result is NULL, then sqlite3_column_bytes16() returns zero. +** +** ^The values returned by [sqlite3_column_bytes()] and +** [sqlite3_column_bytes16()] do not include the zero terminators at the end +** of the string. ^For clarity: the values returned by +** [sqlite3_column_bytes()] and [sqlite3_column_bytes16()] are the number of +** bytes in the string, not the number of characters. +** +** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(), +** even empty strings, are always zero-terminated. ^The return +** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer. +** +** ^The object returned by [sqlite3_column_value()] is an +** [unprotected sqlite3_value] object. An unprotected sqlite3_value object +** may only be used with [sqlite3_bind_value()] and [sqlite3_result_value()]. +** If the [unprotected sqlite3_value] object returned by +** [sqlite3_column_value()] is used in any other way, including calls +** to routines like [sqlite3_value_int()], [sqlite3_value_text()], +** or [sqlite3_value_bytes()], then the behavior is undefined. +** +** These routines attempt to convert the value where appropriate. ^For +** example, if the internal representation is FLOAT and a text result +** is requested, [sqlite3_snprintf()] is used internally to perform the +** conversion automatically. ^(The following table details the conversions +** that are applied: +** +**
+** +**
Internal
Type
Requested
Type
Conversion +** +**
NULL INTEGER Result is 0 +**
NULL FLOAT Result is 0.0 +**
NULL TEXT Result is NULL pointer +**
NULL BLOB Result is NULL pointer +**
INTEGER FLOAT Convert from integer to float +**
INTEGER TEXT ASCII rendering of the integer +**
INTEGER BLOB Same as INTEGER->TEXT +**
FLOAT INTEGER Convert from float to integer +**
FLOAT TEXT ASCII rendering of the float +**
FLOAT BLOB Same as FLOAT->TEXT +**
TEXT INTEGER Use atoi() +**
TEXT FLOAT Use atof() +**
TEXT BLOB No change +**
BLOB INTEGER Convert to TEXT then use atoi() +**
BLOB FLOAT Convert to TEXT then use atof() +**
BLOB TEXT Add a zero terminator if needed +**
+**
)^ +** +** The table above makes reference to standard C library functions atoi() +** and atof(). SQLite does not really use these functions. It has its +** own equivalent internal routines. The atoi() and atof() names are +** used in the table for brevity and because they are familiar to most +** C programmers. +** +** Note that when type conversions occur, pointers returned by prior +** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or +** sqlite3_column_text16() may be invalidated. +** Type conversions and pointer invalidations might occur +** in the following cases: +** +**
    +**
  • The initial content is a BLOB and sqlite3_column_text() or +** sqlite3_column_text16() is called. A zero-terminator might +** need to be added to the string.
  • +**
  • The initial content is UTF-8 text and sqlite3_column_bytes16() or +** sqlite3_column_text16() is called. The content must be converted +** to UTF-16.
  • +**
  • The initial content is UTF-16 text and sqlite3_column_bytes() or +** sqlite3_column_text() is called. The content must be converted +** to UTF-8.
  • +**
+** +** ^Conversions between UTF-16be and UTF-16le are always done in place and do +** not invalidate a prior pointer, though of course the content of the buffer +** that the prior pointer references will have been modified. Other kinds +** of conversion are done in place when it is possible, but sometimes they +** are not possible and in those cases prior pointers are invalidated. +** +** The safest and easiest to remember policy is to invoke these routines +** in one of the following ways: +** +**
    +**
  • sqlite3_column_text() followed by sqlite3_column_bytes()
  • +**
  • sqlite3_column_blob() followed by sqlite3_column_bytes()
  • +**
  • sqlite3_column_text16() followed by sqlite3_column_bytes16()
  • +**
+** +** In other words, you should call sqlite3_column_text(), +** sqlite3_column_blob(), or sqlite3_column_text16() first to force the result +** into the desired format, then invoke sqlite3_column_bytes() or +** sqlite3_column_bytes16() to find the size of the result. Do not mix calls +** to sqlite3_column_text() or sqlite3_column_blob() with calls to +** sqlite3_column_bytes16(), and do not mix calls to sqlite3_column_text16() +** with calls to sqlite3_column_bytes(). +** +** ^The pointers returned are valid until a type conversion occurs as +** described above, or until [sqlite3_step()] or [sqlite3_reset()] or +** [sqlite3_finalize()] is called. ^The memory space used to hold strings +** and BLOBs is freed automatically. Do not pass the pointers returned +** [sqlite3_column_blob()], [sqlite3_column_text()], etc. into +** [sqlite3_free()]. +** +** ^(If a memory allocation error occurs during the evaluation of any +** of these routines, a default value is returned. The default value +** is either the integer 0, the floating point number 0.0, or a NULL +** pointer. Subsequent calls to [sqlite3_errcode()] will return +** [SQLITE_NOMEM].)^ +*/ +SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); +SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol); +SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); +SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); +SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol); +SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); + +/* +** CAPI3REF: Destroy A Prepared Statement Object +** +** ^The sqlite3_finalize() function is called to delete a [prepared statement]. +** ^If the most recent evaluation of the statement encountered no errors +** or if the statement is never been evaluated, then sqlite3_finalize() returns +** SQLITE_OK. ^If the most recent evaluation of statement S failed, then +** sqlite3_finalize(S) returns the appropriate [error code] or +** [extended error code]. +** +** ^The sqlite3_finalize(S) routine can be called at any point during +** the life cycle of [prepared statement] S: +** before statement S is ever evaluated, after +** one or more calls to [sqlite3_reset()], or after any call +** to [sqlite3_step()] regardless of whether or not the statement has +** completed execution. +** +** ^Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op. +** +** The application must finalize every [prepared statement] in order to avoid +** resource leaks. It is a grievous error for the application to try to use +** a prepared statement after it has been finalized. Any use of a prepared +** statement after it has been finalized can result in undefined and +** undesirable behavior such as segfaults and heap corruption. +*/ +SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Reset A Prepared Statement Object +** +** The sqlite3_reset() function is called to reset a [prepared statement] +** object back to its initial state, ready to be re-executed. +** ^Any SQL statement variables that had values bound to them using +** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values. +** Use [sqlite3_clear_bindings()] to reset the bindings. +** +** ^The [sqlite3_reset(S)] interface resets the [prepared statement] S +** back to the beginning of its program. +** +** ^If the most recent call to [sqlite3_step(S)] for the +** [prepared statement] S returned [SQLITE_ROW] or [SQLITE_DONE], +** or if [sqlite3_step(S)] has never before been called on S, +** then [sqlite3_reset(S)] returns [SQLITE_OK]. +** +** ^If the most recent call to [sqlite3_step(S)] for the +** [prepared statement] S indicated an error, then +** [sqlite3_reset(S)] returns an appropriate [error code]. +** +** ^The [sqlite3_reset(S)] interface does not change the values +** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S. +*/ +SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Create Or Redefine SQL Functions +** KEYWORDS: {function creation routines} +** KEYWORDS: {application-defined SQL function} +** KEYWORDS: {application-defined SQL functions} +** +** ^These functions (collectively known as "function creation routines") +** are used to add SQL functions or aggregates or to redefine the behavior +** of existing SQL functions or aggregates. The only differences between +** these routines are the text encoding expected for +** the second parameter (the name of the function being created) +** and the presence or absence of a destructor callback for +** the application data pointer. +** +** ^The first parameter is the [database connection] to which the SQL +** function is to be added. ^If an application uses more than one database +** connection then application-defined SQL functions must be added +** to each database connection separately. +** +** ^The second parameter is the name of the SQL function to be created or +** redefined. ^The length of the name is limited to 255 bytes in a UTF-8 +** representation, exclusive of the zero-terminator. ^Note that the name +** length limit is in UTF-8 bytes, not characters nor UTF-16 bytes. +** ^Any attempt to create a function with a longer name +** will result in [SQLITE_MISUSE] being returned. +** +** ^The third parameter (nArg) +** is the number of arguments that the SQL function or +** aggregate takes. ^If this parameter is -1, then the SQL function or +** aggregate may take any number of arguments between 0 and the limit +** set by [sqlite3_limit]([SQLITE_LIMIT_FUNCTION_ARG]). If the third +** parameter is less than -1 or greater than 127 then the behavior is +** undefined. +** +** ^The fourth parameter, eTextRep, specifies what +** [SQLITE_UTF8 | text encoding] this SQL function prefers for +** its parameters. Every SQL function implementation must be able to work +** with UTF-8, UTF-16le, or UTF-16be. But some implementations may be +** more efficient with one encoding than another. ^An application may +** invoke sqlite3_create_function() or sqlite3_create_function16() multiple +** times with the same function but with different values of eTextRep. +** ^When multiple implementations of the same function are available, SQLite +** will pick the one that involves the least amount of data conversion. +** If there is only a single implementation which does not care what text +** encoding is used, then the fourth argument should be [SQLITE_ANY]. +** +** ^(The fifth parameter is an arbitrary pointer. The implementation of the +** function can gain access to this pointer using [sqlite3_user_data()].)^ +** +** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are +** pointers to C-language functions that implement the SQL function or +** aggregate. ^A scalar SQL function requires an implementation of the xFunc +** callback only; NULL pointers must be passed as the xStep and xFinal +** parameters. ^An aggregate SQL function requires an implementation of xStep +** and xFinal and NULL pointer must be passed for xFunc. ^To delete an existing +** SQL function or aggregate, pass NULL pointers for all three function +** callbacks. +** +** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL, +** then it is destructor for the application data pointer. +** The destructor is invoked when the function is deleted, either by being +** overloaded or when the database connection closes.)^ +** ^The destructor is also invoked if the call to +** sqlite3_create_function_v2() fails. +** ^When the destructor callback of the tenth parameter is invoked, it +** is passed a single argument which is a copy of the application data +** pointer which was the fifth parameter to sqlite3_create_function_v2(). +** +** ^It is permitted to register multiple implementations of the same +** functions with the same name but with either differing numbers of +** arguments or differing preferred text encodings. ^SQLite will use +** the implementation that most closely matches the way in which the +** SQL function is used. ^A function implementation with a non-negative +** nArg parameter is a better match than a function implementation with +** a negative nArg. ^A function where the preferred text encoding +** matches the database encoding is a better +** match than a function where the encoding is different. +** ^A function where the encoding difference is between UTF16le and UTF16be +** is a closer match than a function where the encoding difference is +** between UTF8 and UTF16. +** +** ^Built-in functions may be overloaded by new application-defined functions. +** +** ^An application-defined function is permitted to call other +** SQLite interfaces. However, such calls must not +** close the database connection nor finalize or reset the prepared +** statement in which the function is running. +*/ +SQLITE_API int sqlite3_create_function( + sqlite3 *db, + const char *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); +SQLITE_API int sqlite3_create_function16( + sqlite3 *db, + const void *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); +SQLITE_API int sqlite3_create_function_v2( + sqlite3 *db, + const char *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void(*xDestroy)(void*) +); + +/* +** CAPI3REF: Text Encodings +** +** These constant define integer codes that represent the various +** text encodings supported by SQLite. +*/ +#define SQLITE_UTF8 1 +#define SQLITE_UTF16LE 2 +#define SQLITE_UTF16BE 3 +#define SQLITE_UTF16 4 /* Use native byte order */ +#define SQLITE_ANY 5 /* sqlite3_create_function only */ +#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */ + +/* +** CAPI3REF: Deprecated Functions +** DEPRECATED +** +** These functions are [deprecated]. In order to maintain +** backwards compatibility with older code, these functions continue +** to be supported. However, new applications should avoid +** the use of these functions. To help encourage people to avoid +** using these functions, we are not going to tell you what they do. +*/ +#ifndef SQLITE_OMIT_DEPRECATED +SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*); +SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*); +SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); +SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void); +SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void); +SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),void*,sqlite3_int64); +#endif + +/* +** CAPI3REF: Obtaining SQL Function Parameter Values +** +** The C-language implementation of SQL functions and aggregates uses +** this set of interface routines to access the parameter values on +** the function or aggregate. +** +** The xFunc (for scalar functions) or xStep (for aggregates) parameters +** to [sqlite3_create_function()] and [sqlite3_create_function16()] +** define callbacks that implement the SQL functions and aggregates. +** The 3rd parameter to these callbacks is an array of pointers to +** [protected sqlite3_value] objects. There is one [sqlite3_value] object for +** each parameter to the SQL function. These routines are used to +** extract values from the [sqlite3_value] objects. +** +** These routines work only with [protected sqlite3_value] objects. +** Any attempt to use these routines on an [unprotected sqlite3_value] +** object results in undefined behavior. +** +** ^These routines work just like the corresponding [column access functions] +** except that these routines take a single [protected sqlite3_value] object +** pointer instead of a [sqlite3_stmt*] pointer and an integer column number. +** +** ^The sqlite3_value_text16() interface extracts a UTF-16 string +** in the native byte-order of the host machine. ^The +** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces +** extract UTF-16 strings as big-endian and little-endian respectively. +** +** ^(The sqlite3_value_numeric_type() interface attempts to apply +** numeric affinity to the value. This means that an attempt is +** made to convert the value to an integer or floating point. If +** such a conversion is possible without loss of information (in other +** words, if the value is a string that looks like a number) +** then the conversion is performed. Otherwise no conversion occurs. +** The [SQLITE_INTEGER | datatype] after conversion is returned.)^ +** +** Please pay particular attention to the fact that the pointer returned +** from [sqlite3_value_blob()], [sqlite3_value_text()], or +** [sqlite3_value_text16()] can be invalidated by a subsequent call to +** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()], +** or [sqlite3_value_text16()]. +** +** These routines must be called from the same thread as +** the SQL function that supplied the [sqlite3_value*] parameters. +*/ +SQLITE_API const void *sqlite3_value_blob(sqlite3_value*); +SQLITE_API int sqlite3_value_bytes(sqlite3_value*); +SQLITE_API int sqlite3_value_bytes16(sqlite3_value*); +SQLITE_API double sqlite3_value_double(sqlite3_value*); +SQLITE_API int sqlite3_value_int(sqlite3_value*); +SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*); +SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*); +SQLITE_API const void *sqlite3_value_text16(sqlite3_value*); +SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*); +SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*); +SQLITE_API int sqlite3_value_type(sqlite3_value*); +SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); + +/* +** CAPI3REF: Obtain Aggregate Function Context +** +** Implementations of aggregate SQL functions use this +** routine to allocate memory for storing their state. +** +** ^The first time the sqlite3_aggregate_context(C,N) routine is called +** for a particular aggregate function, SQLite +** allocates N of memory, zeroes out that memory, and returns a pointer +** to the new memory. ^On second and subsequent calls to +** sqlite3_aggregate_context() for the same aggregate function instance, +** the same buffer is returned. Sqlite3_aggregate_context() is normally +** called once for each invocation of the xStep callback and then one +** last time when the xFinal callback is invoked. ^(When no rows match +** an aggregate query, the xStep() callback of the aggregate function +** implementation is never called and xFinal() is called exactly once. +** In those cases, sqlite3_aggregate_context() might be called for the +** first time from within xFinal().)^ +** +** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer if N is +** less than or equal to zero or if a memory allocate error occurs. +** +** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is +** determined by the N parameter on first successful call. Changing the +** value of N in subsequent call to sqlite3_aggregate_context() within +** the same aggregate function instance will not resize the memory +** allocation.)^ +** +** ^SQLite automatically frees the memory allocated by +** sqlite3_aggregate_context() when the aggregate query concludes. +** +** The first parameter must be a copy of the +** [sqlite3_context | SQL function context] that is the first parameter +** to the xStep or xFinal callback routine that implements the aggregate +** function. +** +** This routine must be called from the same thread in which +** the aggregate SQL function is running. +*/ +SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); + +/* +** CAPI3REF: User Data For Functions +** +** ^The sqlite3_user_data() interface returns a copy of +** the pointer that was the pUserData parameter (the 5th parameter) +** of the [sqlite3_create_function()] +** and [sqlite3_create_function16()] routines that originally +** registered the application defined function. +** +** This routine must be called from the same thread in which +** the application-defined function is running. +*/ +SQLITE_API void *sqlite3_user_data(sqlite3_context*); + +/* +** CAPI3REF: Database Connection For Functions +** +** ^The sqlite3_context_db_handle() interface returns a copy of +** the pointer to the [database connection] (the 1st parameter) +** of the [sqlite3_create_function()] +** and [sqlite3_create_function16()] routines that originally +** registered the application defined function. +*/ +SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); + +/* +** CAPI3REF: Function Auxiliary Data +** +** The following two functions may be used by scalar SQL functions to +** associate metadata with argument values. If the same value is passed to +** multiple invocations of the same SQL function during query execution, under +** some circumstances the associated metadata may be preserved. This may +** be used, for example, to add a regular-expression matching scalar +** function. The compiled version of the regular expression is stored as +** metadata associated with the SQL value passed as the regular expression +** pattern. The compiled regular expression can be reused on multiple +** invocations of the same function so that the original pattern string +** does not need to be recompiled on each invocation. +** +** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata +** associated by the sqlite3_set_auxdata() function with the Nth argument +** value to the application-defined function. ^If no metadata has been ever +** been set for the Nth argument of the function, or if the corresponding +** function parameter has changed since the meta-data was set, +** then sqlite3_get_auxdata() returns a NULL pointer. +** +** ^The sqlite3_set_auxdata() interface saves the metadata +** pointed to by its 3rd parameter as the metadata for the N-th +** argument of the application-defined function. Subsequent +** calls to sqlite3_get_auxdata() might return this data, if it has +** not been destroyed. +** ^If it is not NULL, SQLite will invoke the destructor +** function given by the 4th parameter to sqlite3_set_auxdata() on +** the metadata when the corresponding function parameter changes +** or when the SQL statement completes, whichever comes first. +** +** SQLite is free to call the destructor and drop metadata on any +** parameter of any function at any time. ^The only guarantee is that +** the destructor will be called before the metadata is dropped. +** +** ^(In practice, metadata is preserved between function calls for +** expressions that are constant at compile time. This includes literal +** values and [parameters].)^ +** +** These routines must be called from the same thread in which +** the SQL function is running. +*/ +SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N); +SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); + + +/* +** CAPI3REF: Constants Defining Special Destructor Behavior +** +** These are special values for the destructor that is passed in as the +** final argument to routines like [sqlite3_result_blob()]. ^If the destructor +** argument is SQLITE_STATIC, it means that the content pointer is constant +** and will never change. It does not need to be destroyed. ^The +** SQLITE_TRANSIENT value means that the content will likely change in +** the near future and that SQLite should make its own private copy of +** the content before returning. +** +** The typedef is necessary to work around problems in certain +** C++ compilers. See ticket #2191. +*/ +typedef void (*sqlite3_destructor_type)(void*); +#define SQLITE_STATIC ((sqlite3_destructor_type)0) +#define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1) + +/* +** CAPI3REF: Setting The Result Of An SQL Function +** +** These routines are used by the xFunc or xFinal callbacks that +** implement SQL functions and aggregates. See +** [sqlite3_create_function()] and [sqlite3_create_function16()] +** for additional information. +** +** These functions work very much like the [parameter binding] family of +** functions used to bind values to host parameters in prepared statements. +** Refer to the [SQL parameter] documentation for additional information. +** +** ^The sqlite3_result_blob() interface sets the result from +** an application-defined function to be the BLOB whose content is pointed +** to by the second parameter and which is N bytes long where N is the +** third parameter. +** +** ^The sqlite3_result_zeroblob() interfaces set the result of +** the application-defined function to be a BLOB containing all zero +** bytes and N bytes in size, where N is the value of the 2nd parameter. +** +** ^The sqlite3_result_double() interface sets the result from +** an application-defined function to be a floating point value specified +** by its 2nd argument. +** +** ^The sqlite3_result_error() and sqlite3_result_error16() functions +** cause the implemented SQL function to throw an exception. +** ^SQLite uses the string pointed to by the +** 2nd parameter of sqlite3_result_error() or sqlite3_result_error16() +** as the text of an error message. ^SQLite interprets the error +** message string from sqlite3_result_error() as UTF-8. ^SQLite +** interprets the string from sqlite3_result_error16() as UTF-16 in native +** byte order. ^If the third parameter to sqlite3_result_error() +** or sqlite3_result_error16() is negative then SQLite takes as the error +** message all text up through the first zero character. +** ^If the third parameter to sqlite3_result_error() or +** sqlite3_result_error16() is non-negative then SQLite takes that many +** bytes (not characters) from the 2nd parameter as the error message. +** ^The sqlite3_result_error() and sqlite3_result_error16() +** routines make a private copy of the error message text before +** they return. Hence, the calling function can deallocate or +** modify the text after they return without harm. +** ^The sqlite3_result_error_code() function changes the error code +** returned by SQLite as a result of an error in a function. ^By default, +** the error code is SQLITE_ERROR. ^A subsequent call to sqlite3_result_error() +** or sqlite3_result_error16() resets the error code to SQLITE_ERROR. +** +** ^The sqlite3_result_toobig() interface causes SQLite to throw an error +** indicating that a string or BLOB is too long to represent. +** +** ^The sqlite3_result_nomem() interface causes SQLite to throw an error +** indicating that a memory allocation failed. +** +** ^The sqlite3_result_int() interface sets the return value +** of the application-defined function to be the 32-bit signed integer +** value given in the 2nd argument. +** ^The sqlite3_result_int64() interface sets the return value +** of the application-defined function to be the 64-bit signed integer +** value given in the 2nd argument. +** +** ^The sqlite3_result_null() interface sets the return value +** of the application-defined function to be NULL. +** +** ^The sqlite3_result_text(), sqlite3_result_text16(), +** sqlite3_result_text16le(), and sqlite3_result_text16be() interfaces +** set the return value of the application-defined function to be +** a text string which is represented as UTF-8, UTF-16 native byte order, +** UTF-16 little endian, or UTF-16 big endian, respectively. +** ^SQLite takes the text result from the application from +** the 2nd parameter of the sqlite3_result_text* interfaces. +** ^If the 3rd parameter to the sqlite3_result_text* interfaces +** is negative, then SQLite takes result text from the 2nd parameter +** through the first zero character. +** ^If the 3rd parameter to the sqlite3_result_text* interfaces +** is non-negative, then as many bytes (not characters) of the text +** pointed to by the 2nd parameter are taken as the application-defined +** function result. If the 3rd parameter is non-negative, then it +** must be the byte offset into the string where the NUL terminator would +** appear if the string where NUL terminated. If any NUL characters occur +** in the string at a byte offset that is less than the value of the 3rd +** parameter, then the resulting string will contain embedded NULs and the +** result of expressions operating on strings with embedded NULs is undefined. +** ^If the 4th parameter to the sqlite3_result_text* interfaces +** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that +** function as the destructor on the text or BLOB result when it has +** finished using that result. +** ^If the 4th parameter to the sqlite3_result_text* interfaces or to +** sqlite3_result_blob is the special constant SQLITE_STATIC, then SQLite +** assumes that the text or BLOB result is in constant space and does not +** copy the content of the parameter nor call a destructor on the content +** when it has finished using that result. +** ^If the 4th parameter to the sqlite3_result_text* interfaces +** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT +** then SQLite makes a copy of the result into space obtained from +** from [sqlite3_malloc()] before it returns. +** +** ^The sqlite3_result_value() interface sets the result of +** the application-defined function to be a copy the +** [unprotected sqlite3_value] object specified by the 2nd parameter. ^The +** sqlite3_result_value() interface makes a copy of the [sqlite3_value] +** so that the [sqlite3_value] specified in the parameter may change or +** be deallocated after sqlite3_result_value() returns without harm. +** ^A [protected sqlite3_value] object may always be used where an +** [unprotected sqlite3_value] object is required, so either +** kind of [sqlite3_value] object can be used with this interface. +** +** If these routines are called from within the different thread +** than the one containing the application-defined function that received +** the [sqlite3_context] pointer, the results are undefined. +*/ +SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); +SQLITE_API void sqlite3_result_double(sqlite3_context*, double); +SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int); +SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int); +SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*); +SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*); +SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int); +SQLITE_API void sqlite3_result_int(sqlite3_context*, int); +SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); +SQLITE_API void sqlite3_result_null(sqlite3_context*); +SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); +SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); +SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); +SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); +SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*); +SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n); + +/* +** CAPI3REF: Define New Collating Sequences +** +** ^These functions add, remove, or modify a [collation] associated +** with the [database connection] specified as the first argument. +** +** ^The name of the collation is a UTF-8 string +** for sqlite3_create_collation() and sqlite3_create_collation_v2() +** and a UTF-16 string in native byte order for sqlite3_create_collation16(). +** ^Collation names that compare equal according to [sqlite3_strnicmp()] are +** considered to be the same name. +** +** ^(The third argument (eTextRep) must be one of the constants: +**
    +**
  • [SQLITE_UTF8], +**
  • [SQLITE_UTF16LE], +**
  • [SQLITE_UTF16BE], +**
  • [SQLITE_UTF16], or +**
  • [SQLITE_UTF16_ALIGNED]. +**
)^ +** ^The eTextRep argument determines the encoding of strings passed +** to the collating function callback, xCallback. +** ^The [SQLITE_UTF16] and [SQLITE_UTF16_ALIGNED] values for eTextRep +** force strings to be UTF16 with native byte order. +** ^The [SQLITE_UTF16_ALIGNED] value for eTextRep forces strings to begin +** on an even byte address. +** +** ^The fourth argument, pArg, is an application data pointer that is passed +** through as the first argument to the collating function callback. +** +** ^The fifth argument, xCallback, is a pointer to the collating function. +** ^Multiple collating functions can be registered using the same name but +** with different eTextRep parameters and SQLite will use whichever +** function requires the least amount of data transformation. +** ^If the xCallback argument is NULL then the collating function is +** deleted. ^When all collating functions having the same name are deleted, +** that collation is no longer usable. +** +** ^The collating function callback is invoked with a copy of the pArg +** application data pointer and with two strings in the encoding specified +** by the eTextRep argument. The collating function must return an +** integer that is negative, zero, or positive +** if the first string is less than, equal to, or greater than the second, +** respectively. A collating function must always return the same answer +** given the same inputs. If two or more collating functions are registered +** to the same collation name (using different eTextRep values) then all +** must give an equivalent answer when invoked with equivalent strings. +** The collating function must obey the following properties for all +** strings A, B, and C: +** +**
    +**
  1. If A==B then B==A. +**
  2. If A==B and B==C then A==C. +**
  3. If A<B THEN B>A. +**
  4. If A<B and B<C then A<C. +**
+** +** If a collating function fails any of the above constraints and that +** collating function is registered and used, then the behavior of SQLite +** is undefined. +** +** ^The sqlite3_create_collation_v2() works like sqlite3_create_collation() +** with the addition that the xDestroy callback is invoked on pArg when +** the collating function is deleted. +** ^Collating functions are deleted when they are overridden by later +** calls to the collation creation functions or when the +** [database connection] is closed using [sqlite3_close()]. +** +** ^The xDestroy callback is not called if the +** sqlite3_create_collation_v2() function fails. Applications that invoke +** sqlite3_create_collation_v2() with a non-NULL xDestroy argument should +** check the return code and dispose of the application data pointer +** themselves rather than expecting SQLite to deal with it for them. +** This is different from every other SQLite interface. The inconsistency +** is unfortunate but cannot be changed without breaking backwards +** compatibility. +** +** See also: [sqlite3_collation_needed()] and [sqlite3_collation_needed16()]. +*/ +SQLITE_API int sqlite3_create_collation( + sqlite3*, + const char *zName, + int eTextRep, + void *pArg, + int(*xCompare)(void*,int,const void*,int,const void*) +); +SQLITE_API int sqlite3_create_collation_v2( + sqlite3*, + const char *zName, + int eTextRep, + void *pArg, + int(*xCompare)(void*,int,const void*,int,const void*), + void(*xDestroy)(void*) +); +SQLITE_API int sqlite3_create_collation16( + sqlite3*, + const void *zName, + int eTextRep, + void *pArg, + int(*xCompare)(void*,int,const void*,int,const void*) +); + +/* +** CAPI3REF: Collation Needed Callbacks +** +** ^To avoid having to register all collation sequences before a database +** can be used, a single callback function may be registered with the +** [database connection] to be invoked whenever an undefined collation +** sequence is required. +** +** ^If the function is registered using the sqlite3_collation_needed() API, +** then it is passed the names of undefined collation sequences as strings +** encoded in UTF-8. ^If sqlite3_collation_needed16() is used, +** the names are passed as UTF-16 in machine native byte order. +** ^A call to either function replaces the existing collation-needed callback. +** +** ^(When the callback is invoked, the first argument passed is a copy +** of the second argument to sqlite3_collation_needed() or +** sqlite3_collation_needed16(). The second argument is the database +** connection. The third argument is one of [SQLITE_UTF8], [SQLITE_UTF16BE], +** or [SQLITE_UTF16LE], indicating the most desirable form of the collation +** sequence function required. The fourth parameter is the name of the +** required collation sequence.)^ +** +** The callback function should register the desired collation using +** [sqlite3_create_collation()], [sqlite3_create_collation16()], or +** [sqlite3_create_collation_v2()]. +*/ +SQLITE_API int sqlite3_collation_needed( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const char*) +); +SQLITE_API int sqlite3_collation_needed16( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const void*) +); + +#ifdef SQLITE_HAS_CODEC +/* +** Specify the key for an encrypted database. This routine should be +** called right after sqlite3_open(). +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +SQLITE_API int sqlite3_key( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The key */ +); + +/* +** Change the key on an open database. If the current database is not +** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the +** database is decrypted. +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +SQLITE_API int sqlite3_rekey( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The new key */ +); + +/* +** Specify the activation key for a SEE database. Unless +** activated, none of the SEE routines will work. +*/ +SQLITE_API void sqlite3_activate_see( + const char *zPassPhrase /* Activation phrase */ +); +#endif + +#ifdef SQLITE_ENABLE_CEROD +/* +** Specify the activation key for a CEROD database. Unless +** activated, none of the CEROD routines will work. +*/ +SQLITE_API void sqlite3_activate_cerod( + const char *zPassPhrase /* Activation phrase */ +); +#endif + +/* +** CAPI3REF: Suspend Execution For A Short Time +** +** The sqlite3_sleep() function causes the current thread to suspend execution +** for at least a number of milliseconds specified in its parameter. +** +** If the operating system does not support sleep requests with +** millisecond time resolution, then the time will be rounded up to +** the nearest second. The number of milliseconds of sleep actually +** requested from the operating system is returned. +** +** ^SQLite implements this interface by calling the xSleep() +** method of the default [sqlite3_vfs] object. If the xSleep() method +** of the default VFS is not implemented correctly, or not implemented at +** all, then the behavior of sqlite3_sleep() may deviate from the description +** in the previous paragraphs. +*/ +SQLITE_API int sqlite3_sleep(int); + +/* +** CAPI3REF: Name Of The Folder Holding Temporary Files +** +** ^(If this global variable is made to point to a string which is +** the name of a folder (a.k.a. directory), then all temporary files +** created by SQLite when using a built-in [sqlite3_vfs | VFS] +** will be placed in that directory.)^ ^If this variable +** is a NULL pointer, then SQLite performs a search for an appropriate +** temporary file directory. +** +** It is not safe to read or modify this variable in more than one +** thread at a time. It is not safe to read or modify this variable +** if a [database connection] is being used at the same time in a separate +** thread. +** It is intended that this variable be set once +** as part of process initialization and before any SQLite interface +** routines have been called and that this variable remain unchanged +** thereafter. +** +** ^The [temp_store_directory pragma] may modify this variable and cause +** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore, +** the [temp_store_directory pragma] always assumes that any string +** that this variable points to is held in memory obtained from +** [sqlite3_malloc] and the pragma may attempt to free that memory +** using [sqlite3_free]. +** Hence, if this variable is modified directly, either it should be +** made NULL or made to point to memory obtained from [sqlite3_malloc] +** or else the use of the [temp_store_directory pragma] should be avoided. +*/ +SQLITE_API SQLITE_EXTERN char *sqlite3_temp_directory; + +/* +** CAPI3REF: Test For Auto-Commit Mode +** KEYWORDS: {autocommit mode} +** +** ^The sqlite3_get_autocommit() interface returns non-zero or +** zero if the given database connection is or is not in autocommit mode, +** respectively. ^Autocommit mode is on by default. +** ^Autocommit mode is disabled by a [BEGIN] statement. +** ^Autocommit mode is re-enabled by a [COMMIT] or [ROLLBACK]. +** +** If certain kinds of errors occur on a statement within a multi-statement +** transaction (errors including [SQLITE_FULL], [SQLITE_IOERR], +** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the +** transaction might be rolled back automatically. The only way to +** find out whether SQLite automatically rolled back the transaction after +** an error is to use this function. +** +** If another thread changes the autocommit status of the database +** connection while this routine is running, then the return value +** is undefined. +*/ +SQLITE_API int sqlite3_get_autocommit(sqlite3*); + +/* +** CAPI3REF: Find The Database Handle Of A Prepared Statement +** +** ^The sqlite3_db_handle interface returns the [database connection] handle +** to which a [prepared statement] belongs. ^The [database connection] +** returned by sqlite3_db_handle is the same [database connection] +** that was the first argument +** to the [sqlite3_prepare_v2()] call (or its variants) that was used to +** create the statement in the first place. +*/ +SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); + +/* +** CAPI3REF: Return The Filename For A Database Connection +** +** ^The sqlite3_db_filename(D,N) interface returns a pointer to a filename +** associated with database N of connection D. ^The main database file +** has the name "main". If there is no attached database N on the database +** connection D, or if database N is a temporary or in-memory database, then +** a NULL pointer is returned. +** +** ^The filename returned by this function is the output of the +** xFullPathname method of the [VFS]. ^In other words, the filename +** will be an absolute pathname, even if the filename used +** to open the database originally was a URI or relative pathname. +*/ +SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName); + +/* +** CAPI3REF: Find the next prepared statement +** +** ^This interface returns a pointer to the next [prepared statement] after +** pStmt associated with the [database connection] pDb. ^If pStmt is NULL +** then this interface returns a pointer to the first prepared statement +** associated with the database connection pDb. ^If no prepared statement +** satisfies the conditions of this routine, it returns NULL. +** +** The [database connection] pointer D in a call to +** [sqlite3_next_stmt(D,S)] must refer to an open database +** connection and in particular must not be a NULL pointer. +*/ +SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Commit And Rollback Notification Callbacks +** +** ^The sqlite3_commit_hook() interface registers a callback +** function to be invoked whenever a transaction is [COMMIT | committed]. +** ^Any callback set by a previous call to sqlite3_commit_hook() +** for the same database connection is overridden. +** ^The sqlite3_rollback_hook() interface registers a callback +** function to be invoked whenever a transaction is [ROLLBACK | rolled back]. +** ^Any callback set by a previous call to sqlite3_rollback_hook() +** for the same database connection is overridden. +** ^The pArg argument is passed through to the callback. +** ^If the callback on a commit hook function returns non-zero, +** then the commit is converted into a rollback. +** +** ^The sqlite3_commit_hook(D,C,P) and sqlite3_rollback_hook(D,C,P) functions +** return the P argument from the previous call of the same function +** on the same [database connection] D, or NULL for +** the first call for each function on D. +** +** The commit and rollback hook callbacks are not reentrant. +** The callback implementation must not do anything that will modify +** the database connection that invoked the callback. Any actions +** to modify the database connection must be deferred until after the +** completion of the [sqlite3_step()] call that triggered the commit +** or rollback hook in the first place. +** Note that running any other SQL statements, including SELECT statements, +** or merely calling [sqlite3_prepare_v2()] and [sqlite3_step()] will modify +** the database connections for the meaning of "modify" in this paragraph. +** +** ^Registering a NULL function disables the callback. +** +** ^When the commit hook callback routine returns zero, the [COMMIT] +** operation is allowed to continue normally. ^If the commit hook +** returns non-zero, then the [COMMIT] is converted into a [ROLLBACK]. +** ^The rollback hook is invoked on a rollback that results from a commit +** hook returning non-zero, just as it would be with any other rollback. +** +** ^For the purposes of this API, a transaction is said to have been +** rolled back if an explicit "ROLLBACK" statement is executed, or +** an error or constraint causes an implicit rollback to occur. +** ^The rollback callback is not invoked if a transaction is +** automatically rolled back because the database connection is closed. +** +** See also the [sqlite3_update_hook()] interface. +*/ +SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); +SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); + +/* +** CAPI3REF: Data Change Notification Callbacks +** +** ^The sqlite3_update_hook() interface registers a callback function +** with the [database connection] identified by the first argument +** to be invoked whenever a row is updated, inserted or deleted. +** ^Any callback set by a previous call to this function +** for the same database connection is overridden. +** +** ^The second argument is a pointer to the function to invoke when a +** row is updated, inserted or deleted. +** ^The first argument to the callback is a copy of the third argument +** to sqlite3_update_hook(). +** ^The second callback argument is one of [SQLITE_INSERT], [SQLITE_DELETE], +** or [SQLITE_UPDATE], depending on the operation that caused the callback +** to be invoked. +** ^The third and fourth arguments to the callback contain pointers to the +** database and table name containing the affected row. +** ^The final callback parameter is the [rowid] of the row. +** ^In the case of an update, this is the [rowid] after the update takes place. +** +** ^(The update hook is not invoked when internal system tables are +** modified (i.e. sqlite_master and sqlite_sequence).)^ +** +** ^In the current implementation, the update hook +** is not invoked when duplication rows are deleted because of an +** [ON CONFLICT | ON CONFLICT REPLACE] clause. ^Nor is the update hook +** invoked when rows are deleted using the [truncate optimization]. +** The exceptions defined in this paragraph might change in a future +** release of SQLite. +** +** The update hook implementation must not do anything that will modify +** the database connection that invoked the update hook. Any actions +** to modify the database connection must be deferred until after the +** completion of the [sqlite3_step()] call that triggered the update hook. +** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their +** database connections for the meaning of "modify" in this paragraph. +** +** ^The sqlite3_update_hook(D,C,P) function +** returns the P argument from the previous call +** on the same [database connection] D, or NULL for +** the first call on D. +** +** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()] +** interfaces. +*/ +SQLITE_API void *sqlite3_update_hook( + sqlite3*, + void(*)(void *,int ,char const *,char const *,sqlite3_int64), + void* +); + +/* +** CAPI3REF: Enable Or Disable Shared Pager Cache +** KEYWORDS: {shared cache} +** +** ^(This routine enables or disables the sharing of the database cache +** and schema data structures between [database connection | connections] +** to the same database. Sharing is enabled if the argument is true +** and disabled if the argument is false.)^ +** +** ^Cache sharing is enabled and disabled for an entire process. +** This is a change as of SQLite version 3.5.0. In prior versions of SQLite, +** sharing was enabled or disabled for each thread separately. +** +** ^(The cache sharing mode set by this interface effects all subsequent +** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()]. +** Existing database connections continue use the sharing mode +** that was in effect at the time they were opened.)^ +** +** ^(This routine returns [SQLITE_OK] if shared cache was enabled or disabled +** successfully. An [error code] is returned otherwise.)^ +** +** ^Shared cache is disabled by default. But this might change in +** future releases of SQLite. Applications that care about shared +** cache setting should set it explicitly. +** +** See Also: [SQLite Shared-Cache Mode] +*/ +SQLITE_API int sqlite3_enable_shared_cache(int); + +/* +** CAPI3REF: Attempt To Free Heap Memory +** +** ^The sqlite3_release_memory() interface attempts to free N bytes +** of heap memory by deallocating non-essential memory allocations +** held by the database library. Memory used to cache database +** pages to improve performance is an example of non-essential memory. +** ^sqlite3_release_memory() returns the number of bytes actually freed, +** which might be more or less than the amount requested. +** ^The sqlite3_release_memory() routine is a no-op returning zero +** if SQLite is not compiled with [SQLITE_ENABLE_MEMORY_MANAGEMENT]. +** +** See also: [sqlite3_db_release_memory()] +*/ +SQLITE_API int sqlite3_release_memory(int); + +/* +** CAPI3REF: Free Memory Used By A Database Connection +** +** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap +** memory as possible from database connection D. Unlike the +** [sqlite3_release_memory()] interface, this interface is effect even +** when then [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is +** omitted. +** +** See also: [sqlite3_release_memory()] +*/ +SQLITE_API int sqlite3_db_release_memory(sqlite3*); + +/* +** CAPI3REF: Impose A Limit On Heap Size +** +** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the +** soft limit on the amount of heap memory that may be allocated by SQLite. +** ^SQLite strives to keep heap memory utilization below the soft heap +** limit by reducing the number of pages held in the page cache +** as heap memory usages approaches the limit. +** ^The soft heap limit is "soft" because even though SQLite strives to stay +** below the limit, it will exceed the limit rather than generate +** an [SQLITE_NOMEM] error. In other words, the soft heap limit +** is advisory only. +** +** ^The return value from sqlite3_soft_heap_limit64() is the size of +** the soft heap limit prior to the call, or negative in the case of an +** error. ^If the argument N is negative +** then no change is made to the soft heap limit. Hence, the current +** size of the soft heap limit can be determined by invoking +** sqlite3_soft_heap_limit64() with a negative argument. +** +** ^If the argument N is zero then the soft heap limit is disabled. +** +** ^(The soft heap limit is not enforced in the current implementation +** if one or more of following conditions are true: +** +**
    +**
  • The soft heap limit is set to zero. +**
  • Memory accounting is disabled using a combination of the +** [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and +** the [SQLITE_DEFAULT_MEMSTATUS] compile-time option. +**
  • An alternative page cache implementation is specified using +** [sqlite3_config]([SQLITE_CONFIG_PCACHE2],...). +**
  • The page cache allocates from its own memory pool supplied +** by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than +** from the heap. +**
)^ +** +** Beginning with SQLite version 3.7.3, the soft heap limit is enforced +** regardless of whether or not the [SQLITE_ENABLE_MEMORY_MANAGEMENT] +** compile-time option is invoked. With [SQLITE_ENABLE_MEMORY_MANAGEMENT], +** the soft heap limit is enforced on every memory allocation. Without +** [SQLITE_ENABLE_MEMORY_MANAGEMENT], the soft heap limit is only enforced +** when memory is allocated by the page cache. Testing suggests that because +** the page cache is the predominate memory user in SQLite, most +** applications will achieve adequate soft heap limit enforcement without +** the use of [SQLITE_ENABLE_MEMORY_MANAGEMENT]. +** +** The circumstances under which SQLite will enforce the soft heap limit may +** changes in future releases of SQLite. +*/ +SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N); + +/* +** CAPI3REF: Deprecated Soft Heap Limit Interface +** DEPRECATED +** +** This is a deprecated version of the [sqlite3_soft_heap_limit64()] +** interface. This routine is provided for historical compatibility +** only. All new applications should use the +** [sqlite3_soft_heap_limit64()] interface rather than this one. +*/ +SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N); + + +/* +** CAPI3REF: Extract Metadata About A Column Of A Table +** +** ^This routine returns metadata about a specific column of a specific +** database table accessible using the [database connection] handle +** passed as the first function argument. +** +** ^The column is identified by the second, third and fourth parameters to +** this function. ^The second parameter is either the name of the database +** (i.e. "main", "temp", or an attached database) containing the specified +** table or NULL. ^If it is NULL, then all attached databases are searched +** for the table using the same algorithm used by the database engine to +** resolve unqualified table references. +** +** ^The third and fourth parameters to this function are the table and column +** name of the desired column, respectively. Neither of these parameters +** may be NULL. +** +** ^Metadata is returned by writing to the memory locations passed as the 5th +** and subsequent parameters to this function. ^Any of these arguments may be +** NULL, in which case the corresponding element of metadata is omitted. +** +** ^(
+** +**
Parameter Output
Type
Description +** +**
5th const char* Data type +**
6th const char* Name of default collation sequence +**
7th int True if column has a NOT NULL constraint +**
8th int True if column is part of the PRIMARY KEY +**
9th int True if column is [AUTOINCREMENT] +**
+**
)^ +** +** ^The memory pointed to by the character pointers returned for the +** declaration type and collation sequence is valid only until the next +** call to any SQLite API function. +** +** ^If the specified table is actually a view, an [error code] is returned. +** +** ^If the specified column is "rowid", "oid" or "_rowid_" and an +** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output +** parameters are set for the explicitly declared column. ^(If there is no +** explicitly declared [INTEGER PRIMARY KEY] column, then the output +** parameters are set as follows: +** +**
+**     data type: "INTEGER"
+**     collation sequence: "BINARY"
+**     not null: 0
+**     primary key: 1
+**     auto increment: 0
+** 
)^ +** +** ^(This function may load one or more schemas from database files. If an +** error occurs during this process, or if the requested table or column +** cannot be found, an [error code] is returned and an error message left +** in the [database connection] (to be retrieved using sqlite3_errmsg()).)^ +** +** ^This API is only available if the library was compiled with the +** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol defined. +*/ +SQLITE_API int sqlite3_table_column_metadata( + sqlite3 *db, /* Connection handle */ + const char *zDbName, /* Database name or NULL */ + const char *zTableName, /* Table name */ + const char *zColumnName, /* Column name */ + char const **pzDataType, /* OUTPUT: Declared data type */ + char const **pzCollSeq, /* OUTPUT: Collation sequence name */ + int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ + int *pPrimaryKey, /* OUTPUT: True if column part of PK */ + int *pAutoinc /* OUTPUT: True if column is auto-increment */ +); + +/* +** CAPI3REF: Load An Extension +** +** ^This interface loads an SQLite extension library from the named file. +** +** ^The sqlite3_load_extension() interface attempts to load an +** SQLite extension library contained in the file zFile. +** +** ^The entry point is zProc. +** ^zProc may be 0, in which case the name of the entry point +** defaults to "sqlite3_extension_init". +** ^The sqlite3_load_extension() interface returns +** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong. +** ^If an error occurs and pzErrMsg is not 0, then the +** [sqlite3_load_extension()] interface shall attempt to +** fill *pzErrMsg with error message text stored in memory +** obtained from [sqlite3_malloc()]. The calling function +** should free this memory by calling [sqlite3_free()]. +** +** ^Extension loading must be enabled using +** [sqlite3_enable_load_extension()] prior to calling this API, +** otherwise an error will be returned. +** +** See also the [load_extension() SQL function]. +*/ +SQLITE_API int sqlite3_load_extension( + sqlite3 *db, /* Load the extension into this database connection */ + const char *zFile, /* Name of the shared library containing extension */ + const char *zProc, /* Entry point. Derived from zFile if 0 */ + char **pzErrMsg /* Put error message here if not 0 */ +); + +/* +** CAPI3REF: Enable Or Disable Extension Loading +** +** ^So as not to open security holes in older applications that are +** unprepared to deal with extension loading, and as a means of disabling +** extension loading while evaluating user-entered SQL, the following API +** is provided to turn the [sqlite3_load_extension()] mechanism on and off. +** +** ^Extension loading is off by default. See ticket #1863. +** ^Call the sqlite3_enable_load_extension() routine with onoff==1 +** to turn extension loading on and call it with onoff==0 to turn +** it back off again. +*/ +SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff); + +/* +** CAPI3REF: Automatically Load Statically Linked Extensions +** +** ^This interface causes the xEntryPoint() function to be invoked for +** each new [database connection] that is created. The idea here is that +** xEntryPoint() is the entry point for a statically linked SQLite extension +** that is to be automatically loaded into all new database connections. +** +** ^(Even though the function prototype shows that xEntryPoint() takes +** no arguments and returns void, SQLite invokes xEntryPoint() with three +** arguments and expects and integer result as if the signature of the +** entry point where as follows: +** +**
+**    int xEntryPoint(
+**      sqlite3 *db,
+**      const char **pzErrMsg,
+**      const struct sqlite3_api_routines *pThunk
+**    );
+** 
)^ +** +** If the xEntryPoint routine encounters an error, it should make *pzErrMsg +** point to an appropriate error message (obtained from [sqlite3_mprintf()]) +** and return an appropriate [error code]. ^SQLite ensures that *pzErrMsg +** is NULL before calling the xEntryPoint(). ^SQLite will invoke +** [sqlite3_free()] on *pzErrMsg after xEntryPoint() returns. ^If any +** xEntryPoint() returns an error, the [sqlite3_open()], [sqlite3_open16()], +** or [sqlite3_open_v2()] call that provoked the xEntryPoint() will fail. +** +** ^Calling sqlite3_auto_extension(X) with an entry point X that is already +** on the list of automatic extensions is a harmless no-op. ^No entry point +** will be called more than once for each database connection that is opened. +** +** See also: [sqlite3_reset_auto_extension()]. +*/ +SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void)); + +/* +** CAPI3REF: Reset Automatic Extension Loading +** +** ^This interface disables all automatic extensions previously +** registered using [sqlite3_auto_extension()]. +*/ +SQLITE_API void sqlite3_reset_auto_extension(void); + +/* +** The interface to the virtual-table mechanism is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stabilizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +*/ + +/* +** Structures used by the virtual table interface +*/ +typedef struct sqlite3_vtab sqlite3_vtab; +typedef struct sqlite3_index_info sqlite3_index_info; +typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; +typedef struct sqlite3_module sqlite3_module; + +/* +** CAPI3REF: Virtual Table Object +** KEYWORDS: sqlite3_module {virtual table module} +** +** This structure, sometimes called a "virtual table module", +** defines the implementation of a [virtual tables]. +** This structure consists mostly of methods for the module. +** +** ^A virtual table module is created by filling in a persistent +** instance of this structure and passing a pointer to that instance +** to [sqlite3_create_module()] or [sqlite3_create_module_v2()]. +** ^The registration remains valid until it is replaced by a different +** module or until the [database connection] closes. The content +** of this structure must not change while it is registered with +** any database connection. +*/ +struct sqlite3_module { + int iVersion; + int (*xCreate)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xConnect)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); + int (*xDisconnect)(sqlite3_vtab *pVTab); + int (*xDestroy)(sqlite3_vtab *pVTab); + int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor); + int (*xClose)(sqlite3_vtab_cursor*); + int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr, + int argc, sqlite3_value **argv); + int (*xNext)(sqlite3_vtab_cursor*); + int (*xEof)(sqlite3_vtab_cursor*); + int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int); + int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid); + int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *); + int (*xBegin)(sqlite3_vtab *pVTab); + int (*xSync)(sqlite3_vtab *pVTab); + int (*xCommit)(sqlite3_vtab *pVTab); + int (*xRollback)(sqlite3_vtab *pVTab); + int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), + void **ppArg); + int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); + /* The methods above are in version 1 of the sqlite_module object. Those + ** below are for version 2 and greater. */ + int (*xSavepoint)(sqlite3_vtab *pVTab, int); + int (*xRelease)(sqlite3_vtab *pVTab, int); + int (*xRollbackTo)(sqlite3_vtab *pVTab, int); +}; + +/* +** CAPI3REF: Virtual Table Indexing Information +** KEYWORDS: sqlite3_index_info +** +** The sqlite3_index_info structure and its substructures is used as part +** of the [virtual table] interface to +** pass information into and receive the reply from the [xBestIndex] +** method of a [virtual table module]. The fields under **Inputs** are the +** inputs to xBestIndex and are read-only. xBestIndex inserts its +** results into the **Outputs** fields. +** +** ^(The aConstraint[] array records WHERE clause constraints of the form: +** +**
column OP expr
+** +** where OP is =, <, <=, >, or >=.)^ ^(The particular operator is +** stored in aConstraint[].op using one of the +** [SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_ values].)^ +** ^(The index of the column is stored in +** aConstraint[].iColumn.)^ ^(aConstraint[].usable is TRUE if the +** expr on the right-hand side can be evaluated (and thus the constraint +** is usable) and false if it cannot.)^ +** +** ^The optimizer automatically inverts terms of the form "expr OP column" +** and makes other simplifications to the WHERE clause in an attempt to +** get as many WHERE clause terms into the form shown above as possible. +** ^The aConstraint[] array only reports WHERE clause terms that are +** relevant to the particular virtual table being queried. +** +** ^Information about the ORDER BY clause is stored in aOrderBy[]. +** ^Each term of aOrderBy records a column of the ORDER BY clause. +** +** The [xBestIndex] method must fill aConstraintUsage[] with information +** about what parameters to pass to xFilter. ^If argvIndex>0 then +** the right-hand side of the corresponding aConstraint[] is evaluated +** and becomes the argvIndex-th entry in argv. ^(If aConstraintUsage[].omit +** is true, then the constraint is assumed to be fully handled by the +** virtual table and is not checked again by SQLite.)^ +** +** ^The idxNum and idxPtr values are recorded and passed into the +** [xFilter] method. +** ^[sqlite3_free()] is used to free idxPtr if and only if +** needToFreeIdxPtr is true. +** +** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in +** the correct order to satisfy the ORDER BY clause so that no separate +** sorting step is required. +** +** ^The estimatedCost value is an estimate of the cost of doing the +** particular lookup. A full scan of a table with N entries should have +** a cost of N. A binary search of a table of N entries should have a +** cost of approximately log(N). +*/ +struct sqlite3_index_info { + /* Inputs */ + int nConstraint; /* Number of entries in aConstraint */ + struct sqlite3_index_constraint { + int iColumn; /* Column on left-hand side of constraint */ + unsigned char op; /* Constraint operator */ + unsigned char usable; /* True if this constraint is usable */ + int iTermOffset; /* Used internally - xBestIndex should ignore */ + } *aConstraint; /* Table of WHERE clause constraints */ + int nOrderBy; /* Number of terms in the ORDER BY clause */ + struct sqlite3_index_orderby { + int iColumn; /* Column number */ + unsigned char desc; /* True for DESC. False for ASC. */ + } *aOrderBy; /* The ORDER BY clause */ + /* Outputs */ + struct sqlite3_index_constraint_usage { + int argvIndex; /* if >0, constraint is part of argv to xFilter */ + unsigned char omit; /* Do not code a test for this constraint */ + } *aConstraintUsage; + int idxNum; /* Number used to identify the index */ + char *idxStr; /* String, possibly obtained from sqlite3_malloc */ + int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */ + int orderByConsumed; /* True if output is already ordered */ + double estimatedCost; /* Estimated cost of using this index */ +}; + +/* +** CAPI3REF: Virtual Table Constraint Operator Codes +** +** These macros defined the allowed values for the +** [sqlite3_index_info].aConstraint[].op field. Each value represents +** an operator that is part of a constraint term in the wHERE clause of +** a query that uses a [virtual table]. +*/ +#define SQLITE_INDEX_CONSTRAINT_EQ 2 +#define SQLITE_INDEX_CONSTRAINT_GT 4 +#define SQLITE_INDEX_CONSTRAINT_LE 8 +#define SQLITE_INDEX_CONSTRAINT_LT 16 +#define SQLITE_INDEX_CONSTRAINT_GE 32 +#define SQLITE_INDEX_CONSTRAINT_MATCH 64 + +/* +** CAPI3REF: Register A Virtual Table Implementation +** +** ^These routines are used to register a new [virtual table module] name. +** ^Module names must be registered before +** creating a new [virtual table] using the module and before using a +** preexisting [virtual table] for the module. +** +** ^The module name is registered on the [database connection] specified +** by the first parameter. ^The name of the module is given by the +** second parameter. ^The third parameter is a pointer to +** the implementation of the [virtual table module]. ^The fourth +** parameter is an arbitrary client data pointer that is passed through +** into the [xCreate] and [xConnect] methods of the virtual table module +** when a new virtual table is be being created or reinitialized. +** +** ^The sqlite3_create_module_v2() interface has a fifth parameter which +** is a pointer to a destructor for the pClientData. ^SQLite will +** invoke the destructor function (if it is not NULL) when SQLite +** no longer needs the pClientData pointer. ^The destructor will also +** be invoked if the call to sqlite3_create_module_v2() fails. +** ^The sqlite3_create_module() +** interface is equivalent to sqlite3_create_module_v2() with a NULL +** destructor. +*/ +SQLITE_API int sqlite3_create_module( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *p, /* Methods for the module */ + void *pClientData /* Client data for xCreate/xConnect */ +); +SQLITE_API int sqlite3_create_module_v2( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *p, /* Methods for the module */ + void *pClientData, /* Client data for xCreate/xConnect */ + void(*xDestroy)(void*) /* Module destructor function */ +); + +/* +** CAPI3REF: Virtual Table Instance Object +** KEYWORDS: sqlite3_vtab +** +** Every [virtual table module] implementation uses a subclass +** of this object to describe a particular instance +** of the [virtual table]. Each subclass will +** be tailored to the specific needs of the module implementation. +** The purpose of this superclass is to define certain fields that are +** common to all module implementations. +** +** ^Virtual tables methods can set an error message by assigning a +** string obtained from [sqlite3_mprintf()] to zErrMsg. The method should +** take care that any prior string is freed by a call to [sqlite3_free()] +** prior to assigning a new string to zErrMsg. ^After the error message +** is delivered up to the client application, the string will be automatically +** freed by sqlite3_free() and the zErrMsg field will be zeroed. +*/ +struct sqlite3_vtab { + const sqlite3_module *pModule; /* The module for this virtual table */ + int nRef; /* NO LONGER USED */ + char *zErrMsg; /* Error message from sqlite3_mprintf() */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* +** CAPI3REF: Virtual Table Cursor Object +** KEYWORDS: sqlite3_vtab_cursor {virtual table cursor} +** +** Every [virtual table module] implementation uses a subclass of the +** following structure to describe cursors that point into the +** [virtual table] and are used +** to loop through the virtual table. Cursors are created using the +** [sqlite3_module.xOpen | xOpen] method of the module and are destroyed +** by the [sqlite3_module.xClose | xClose] method. Cursors are used +** by the [xFilter], [xNext], [xEof], [xColumn], and [xRowid] methods +** of the module. Each module implementation will define +** the content of a cursor structure to suit its own needs. +** +** This superclass exists in order to define fields of the cursor that +** are common to all implementations. +*/ +struct sqlite3_vtab_cursor { + sqlite3_vtab *pVtab; /* Virtual table of this cursor */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* +** CAPI3REF: Declare The Schema Of A Virtual Table +** +** ^The [xCreate] and [xConnect] methods of a +** [virtual table module] call this interface +** to declare the format (the names and datatypes of the columns) of +** the virtual tables they implement. +*/ +SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL); + +/* +** CAPI3REF: Overload A Function For A Virtual Table +** +** ^(Virtual tables can provide alternative implementations of functions +** using the [xFindFunction] method of the [virtual table module]. +** But global versions of those functions +** must exist in order to be overloaded.)^ +** +** ^(This API makes sure a global version of a function with a particular +** name and number of parameters exists. If no such function exists +** before this API is called, a new function is created.)^ ^The implementation +** of the new function always causes an exception to be thrown. So +** the new function is not good for anything by itself. Its only +** purpose is to be a placeholder function that can be overloaded +** by a [virtual table]. +*/ +SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); + +/* +** The interface to the virtual-table mechanism defined above (back up +** to a comment remarkably similar to this one) is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stabilizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +*/ + +/* +** CAPI3REF: A Handle To An Open BLOB +** KEYWORDS: {BLOB handle} {BLOB handles} +** +** An instance of this object represents an open BLOB on which +** [sqlite3_blob_open | incremental BLOB I/O] can be performed. +** ^Objects of this type are created by [sqlite3_blob_open()] +** and destroyed by [sqlite3_blob_close()]. +** ^The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces +** can be used to read or write small subsections of the BLOB. +** ^The [sqlite3_blob_bytes()] interface returns the size of the BLOB in bytes. +*/ +typedef struct sqlite3_blob sqlite3_blob; + +/* +** CAPI3REF: Open A BLOB For Incremental I/O +** +** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located +** in row iRow, column zColumn, table zTable in database zDb; +** in other words, the same BLOB that would be selected by: +** +**
+**     SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
+** 
)^ +** +** ^If the flags parameter is non-zero, then the BLOB is opened for read +** and write access. ^If it is zero, the BLOB is opened for read access. +** ^It is not possible to open a column that is part of an index or primary +** key for writing. ^If [foreign key constraints] are enabled, it is +** not possible to open a column that is part of a [child key] for writing. +** +** ^Note that the database name is not the filename that contains +** the database but rather the symbolic name of the database that +** appears after the AS keyword when the database is connected using [ATTACH]. +** ^For the main database file, the database name is "main". +** ^For TEMP tables, the database name is "temp". +** +** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is written +** to *ppBlob. Otherwise an [error code] is returned and *ppBlob is set +** to be a null pointer.)^ +** ^This function sets the [database connection] error code and message +** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()] and related +** functions. ^Note that the *ppBlob variable is always initialized in a +** way that makes it safe to invoke [sqlite3_blob_close()] on *ppBlob +** regardless of the success or failure of this routine. +** +** ^(If the row that a BLOB handle points to is modified by an +** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects +** then the BLOB handle is marked as "expired". +** This is true if any column of the row is changed, even a column +** other than the one the BLOB handle is open on.)^ +** ^Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for +** an expired BLOB handle fail with a return code of [SQLITE_ABORT]. +** ^(Changes written into a BLOB prior to the BLOB expiring are not +** rolled back by the expiration of the BLOB. Such changes will eventually +** commit if the transaction continues to completion.)^ +** +** ^Use the [sqlite3_blob_bytes()] interface to determine the size of +** the opened blob. ^The size of a blob may not be changed by this +** interface. Use the [UPDATE] SQL command to change the size of a +** blob. +** +** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces +** and the built-in [zeroblob] SQL function can be used, if desired, +** to create an empty, zero-filled blob in which to read or write using +** this interface. +** +** To avoid a resource leak, every open [BLOB handle] should eventually +** be released by a call to [sqlite3_blob_close()]. +*/ +SQLITE_API int sqlite3_blob_open( + sqlite3*, + const char *zDb, + const char *zTable, + const char *zColumn, + sqlite3_int64 iRow, + int flags, + sqlite3_blob **ppBlob +); + +/* +** CAPI3REF: Move a BLOB Handle to a New Row +** +** ^This function is used to move an existing blob handle so that it points +** to a different row of the same database table. ^The new row is identified +** by the rowid value passed as the second argument. Only the row can be +** changed. ^The database, table and column on which the blob handle is open +** remain the same. Moving an existing blob handle to a new row can be +** faster than closing the existing handle and opening a new one. +** +** ^(The new row must meet the same criteria as for [sqlite3_blob_open()] - +** it must exist and there must be either a blob or text value stored in +** the nominated column.)^ ^If the new row is not present in the table, or if +** it does not contain a blob or text value, or if another error occurs, an +** SQLite error code is returned and the blob handle is considered aborted. +** ^All subsequent calls to [sqlite3_blob_read()], [sqlite3_blob_write()] or +** [sqlite3_blob_reopen()] on an aborted blob handle immediately return +** SQLITE_ABORT. ^Calling [sqlite3_blob_bytes()] on an aborted blob handle +** always returns zero. +** +** ^This function sets the database handle error code and message. +*/ +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64); + +/* +** CAPI3REF: Close A BLOB Handle +** +** ^Closes an open [BLOB handle]. +** +** ^Closing a BLOB shall cause the current transaction to commit +** if there are no other BLOBs, no pending prepared statements, and the +** database connection is in [autocommit mode]. +** ^If any writes were made to the BLOB, they might be held in cache +** until the close operation if they will fit. +** +** ^(Closing the BLOB often forces the changes +** out to disk and so if any I/O errors occur, they will likely occur +** at the time when the BLOB is closed. Any errors that occur during +** closing are reported as a non-zero return value.)^ +** +** ^(The BLOB is closed unconditionally. Even if this routine returns +** an error code, the BLOB is still closed.)^ +** +** ^Calling this routine with a null pointer (such as would be returned +** by a failed call to [sqlite3_blob_open()]) is a harmless no-op. +*/ +SQLITE_API int sqlite3_blob_close(sqlite3_blob *); + +/* +** CAPI3REF: Return The Size Of An Open BLOB +** +** ^Returns the size in bytes of the BLOB accessible via the +** successfully opened [BLOB handle] in its only argument. ^The +** incremental blob I/O routines can only read or overwriting existing +** blob content; they cannot change the size of a blob. +** +** This routine only works on a [BLOB handle] which has been created +** by a prior successful call to [sqlite3_blob_open()] and which has not +** been closed by [sqlite3_blob_close()]. Passing any other pointer in +** to this routine results in undefined and probably undesirable behavior. +*/ +SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *); + +/* +** CAPI3REF: Read Data From A BLOB Incrementally +** +** ^(This function is used to read data from an open [BLOB handle] into a +** caller-supplied buffer. N bytes of data are copied into buffer Z +** from the open BLOB, starting at offset iOffset.)^ +** +** ^If offset iOffset is less than N bytes from the end of the BLOB, +** [SQLITE_ERROR] is returned and no data is read. ^If N or iOffset is +** less than zero, [SQLITE_ERROR] is returned and no data is read. +** ^The size of the blob (and hence the maximum value of N+iOffset) +** can be determined using the [sqlite3_blob_bytes()] interface. +** +** ^An attempt to read from an expired [BLOB handle] fails with an +** error code of [SQLITE_ABORT]. +** +** ^(On success, sqlite3_blob_read() returns SQLITE_OK. +** Otherwise, an [error code] or an [extended error code] is returned.)^ +** +** This routine only works on a [BLOB handle] which has been created +** by a prior successful call to [sqlite3_blob_open()] and which has not +** been closed by [sqlite3_blob_close()]. Passing any other pointer in +** to this routine results in undefined and probably undesirable behavior. +** +** See also: [sqlite3_blob_write()]. +*/ +SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset); + +/* +** CAPI3REF: Write Data Into A BLOB Incrementally +** +** ^This function is used to write data into an open [BLOB handle] from a +** caller-supplied buffer. ^N bytes of data are copied from the buffer Z +** into the open BLOB, starting at offset iOffset. +** +** ^If the [BLOB handle] passed as the first argument was not opened for +** writing (the flags parameter to [sqlite3_blob_open()] was zero), +** this function returns [SQLITE_READONLY]. +** +** ^This function may only modify the contents of the BLOB; it is +** not possible to increase the size of a BLOB using this API. +** ^If offset iOffset is less than N bytes from the end of the BLOB, +** [SQLITE_ERROR] is returned and no data is written. ^If N is +** less than zero [SQLITE_ERROR] is returned and no data is written. +** The size of the BLOB (and hence the maximum value of N+iOffset) +** can be determined using the [sqlite3_blob_bytes()] interface. +** +** ^An attempt to write to an expired [BLOB handle] fails with an +** error code of [SQLITE_ABORT]. ^Writes to the BLOB that occurred +** before the [BLOB handle] expired are not rolled back by the +** expiration of the handle, though of course those changes might +** have been overwritten by the statement that expired the BLOB handle +** or by other independent statements. +** +** ^(On success, sqlite3_blob_write() returns SQLITE_OK. +** Otherwise, an [error code] or an [extended error code] is returned.)^ +** +** This routine only works on a [BLOB handle] which has been created +** by a prior successful call to [sqlite3_blob_open()] and which has not +** been closed by [sqlite3_blob_close()]. Passing any other pointer in +** to this routine results in undefined and probably undesirable behavior. +** +** See also: [sqlite3_blob_read()]. +*/ +SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); + +/* +** CAPI3REF: Virtual File System Objects +** +** A virtual filesystem (VFS) is an [sqlite3_vfs] object +** that SQLite uses to interact +** with the underlying operating system. Most SQLite builds come with a +** single default VFS that is appropriate for the host computer. +** New VFSes can be registered and existing VFSes can be unregistered. +** The following interfaces are provided. +** +** ^The sqlite3_vfs_find() interface returns a pointer to a VFS given its name. +** ^Names are case sensitive. +** ^Names are zero-terminated UTF-8 strings. +** ^If there is no match, a NULL pointer is returned. +** ^If zVfsName is NULL then the default VFS is returned. +** +** ^New VFSes are registered with sqlite3_vfs_register(). +** ^Each new VFS becomes the default VFS if the makeDflt flag is set. +** ^The same VFS can be registered multiple times without injury. +** ^To make an existing VFS into the default VFS, register it again +** with the makeDflt flag set. If two different VFSes with the +** same name are registered, the behavior is undefined. If a +** VFS is registered with a name that is NULL or an empty string, +** then the behavior is undefined. +** +** ^Unregister a VFS with the sqlite3_vfs_unregister() interface. +** ^(If the default VFS is unregistered, another VFS is chosen as +** the default. The choice for the new VFS is arbitrary.)^ +*/ +SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName); +SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); +SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); + +/* +** CAPI3REF: Mutexes +** +** The SQLite core uses these routines for thread +** synchronization. Though they are intended for internal +** use by SQLite, code that links against SQLite is +** permitted to use any of these routines. +** +** The SQLite source code contains multiple implementations +** of these mutex routines. An appropriate implementation +** is selected automatically at compile-time. ^(The following +** implementations are available in the SQLite core: +** +**
    +**
  • SQLITE_MUTEX_OS2 +**
  • SQLITE_MUTEX_PTHREADS +**
  • SQLITE_MUTEX_W32 +**
  • SQLITE_MUTEX_NOOP +**
)^ +** +** ^The SQLITE_MUTEX_NOOP implementation is a set of routines +** that does no real locking and is appropriate for use in +** a single-threaded application. ^The SQLITE_MUTEX_OS2, +** SQLITE_MUTEX_PTHREADS, and SQLITE_MUTEX_W32 implementations +** are appropriate for use on OS/2, Unix, and Windows. +** +** ^(If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor +** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex +** implementation is included with the library. In this case the +** application must supply a custom mutex implementation using the +** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function +** before calling sqlite3_initialize() or any other public sqlite3_ +** function that calls sqlite3_initialize().)^ +** +** ^The sqlite3_mutex_alloc() routine allocates a new +** mutex and returns a pointer to it. ^If it returns NULL +** that means that a mutex could not be allocated. ^SQLite +** will unwind its stack and return an error. ^(The argument +** to sqlite3_mutex_alloc() is one of these integer constants: +** +**
    +**
  • SQLITE_MUTEX_FAST +**
  • SQLITE_MUTEX_RECURSIVE +**
  • SQLITE_MUTEX_STATIC_MASTER +**
  • SQLITE_MUTEX_STATIC_MEM +**
  • SQLITE_MUTEX_STATIC_MEM2 +**
  • SQLITE_MUTEX_STATIC_PRNG +**
  • SQLITE_MUTEX_STATIC_LRU +**
  • SQLITE_MUTEX_STATIC_LRU2 +**
)^ +** +** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) +** cause sqlite3_mutex_alloc() to create +** a new mutex. ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE +** is used but not necessarily so when SQLITE_MUTEX_FAST is used. +** The mutex implementation does not need to make a distinction +** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does +** not want to. ^SQLite will only request a recursive mutex in +** cases where it really needs one. ^If a faster non-recursive mutex +** implementation is available on the host platform, the mutex subsystem +** might return such a mutex in response to SQLITE_MUTEX_FAST. +** +** ^The other allowed parameters to sqlite3_mutex_alloc() (anything other +** than SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) each return +** a pointer to a static preexisting mutex. ^Six static mutexes are +** used by the current version of SQLite. Future versions of SQLite +** may add additional static mutexes. Static mutexes are for internal +** use by SQLite only. Applications that use SQLite mutexes should +** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or +** SQLITE_MUTEX_RECURSIVE. +** +** ^Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST +** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() +** returns a different mutex on every call. ^But for the static +** mutex types, the same mutex is returned on every call that has +** the same type number. +** +** ^The sqlite3_mutex_free() routine deallocates a previously +** allocated dynamic mutex. ^SQLite is careful to deallocate every +** dynamic mutex that it allocates. The dynamic mutexes must not be in +** use when they are deallocated. Attempting to deallocate a static +** mutex results in undefined behavior. ^SQLite never deallocates +** a static mutex. +** +** ^The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt +** to enter a mutex. ^If another thread is already within the mutex, +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. ^The sqlite3_mutex_try() interface returns [SQLITE_OK] +** upon successful entry. ^(Mutexes created using +** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread. +** In such cases the, +** mutex must be exited an equal number of times before another thread +** can enter.)^ ^(If the same thread tries to enter any other +** kind of mutex more than once, the behavior is undefined. +** SQLite will never exhibit +** such behavior in its own use of mutexes.)^ +** +** ^(Some systems (for example, Windows 95) do not support the operation +** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() +** will always return SQLITE_BUSY. The SQLite core only ever uses +** sqlite3_mutex_try() as an optimization so this is acceptable behavior.)^ +** +** ^The sqlite3_mutex_leave() routine exits a mutex that was +** previously entered by the same thread. ^(The behavior +** is undefined if the mutex is not currently entered by the +** calling thread or is not currently allocated. SQLite will +** never do either.)^ +** +** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or +** sqlite3_mutex_leave() is a NULL pointer, then all three routines +** behave as no-ops. +** +** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. +*/ +SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int); +SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*); +SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*); +SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*); +SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*); + +/* +** CAPI3REF: Mutex Methods Object +** +** An instance of this structure defines the low-level routines +** used to allocate and use mutexes. +** +** Usually, the default mutex implementations provided by SQLite are +** sufficient, however the user has the option of substituting a custom +** implementation for specialized deployments or systems for which SQLite +** does not provide a suitable implementation. In this case, the user +** creates and populates an instance of this structure to pass +** to sqlite3_config() along with the [SQLITE_CONFIG_MUTEX] option. +** Additionally, an instance of this structure can be used as an +** output variable when querying the system for the current mutex +** implementation, using the [SQLITE_CONFIG_GETMUTEX] option. +** +** ^The xMutexInit method defined by this structure is invoked as +** part of system initialization by the sqlite3_initialize() function. +** ^The xMutexInit routine is called by SQLite exactly once for each +** effective call to [sqlite3_initialize()]. +** +** ^The xMutexEnd method defined by this structure is invoked as +** part of system shutdown by the sqlite3_shutdown() function. The +** implementation of this method is expected to release all outstanding +** resources obtained by the mutex methods implementation, especially +** those obtained by the xMutexInit method. ^The xMutexEnd() +** interface is invoked exactly once for each call to [sqlite3_shutdown()]. +** +** ^(The remaining seven methods defined by this structure (xMutexAlloc, +** xMutexFree, xMutexEnter, xMutexTry, xMutexLeave, xMutexHeld and +** xMutexNotheld) implement the following interfaces (respectively): +** +**
    +**
  • [sqlite3_mutex_alloc()]
  • +**
  • [sqlite3_mutex_free()]
  • +**
  • [sqlite3_mutex_enter()]
  • +**
  • [sqlite3_mutex_try()]
  • +**
  • [sqlite3_mutex_leave()]
  • +**
  • [sqlite3_mutex_held()]
  • +**
  • [sqlite3_mutex_notheld()]
  • +**
)^ +** +** The only difference is that the public sqlite3_XXX functions enumerated +** above silently ignore any invocations that pass a NULL pointer instead +** of a valid mutex handle. The implementations of the methods defined +** by this structure are not required to handle this case, the results +** of passing a NULL pointer instead of a valid mutex handle are undefined +** (i.e. it is acceptable to provide an implementation that segfaults if +** it is passed a NULL pointer). +** +** The xMutexInit() method must be threadsafe. ^It must be harmless to +** invoke xMutexInit() multiple times within the same process and without +** intervening calls to xMutexEnd(). Second and subsequent calls to +** xMutexInit() must be no-ops. +** +** ^xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()] +** and its associates). ^Similarly, xMutexAlloc() must not use SQLite memory +** allocation for a static mutex. ^However xMutexAlloc() may use SQLite +** memory allocation for a fast or recursive mutex. +** +** ^SQLite will invoke the xMutexEnd() method when [sqlite3_shutdown()] is +** called, but only if the prior call to xMutexInit returned SQLITE_OK. +** If xMutexInit fails in any way, it is expected to clean up after itself +** prior to returning. +*/ +typedef struct sqlite3_mutex_methods sqlite3_mutex_methods; +struct sqlite3_mutex_methods { + int (*xMutexInit)(void); + int (*xMutexEnd)(void); + sqlite3_mutex *(*xMutexAlloc)(int); + void (*xMutexFree)(sqlite3_mutex *); + void (*xMutexEnter)(sqlite3_mutex *); + int (*xMutexTry)(sqlite3_mutex *); + void (*xMutexLeave)(sqlite3_mutex *); + int (*xMutexHeld)(sqlite3_mutex *); + int (*xMutexNotheld)(sqlite3_mutex *); +}; + +/* +** CAPI3REF: Mutex Verification Routines +** +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines +** are intended for use inside assert() statements. ^The SQLite core +** never uses these routines except inside an assert() and applications +** are advised to follow the lead of the core. ^The SQLite core only +** provides implementations for these routines when it is compiled +** with the SQLITE_DEBUG flag. ^External mutex implementations +** are only required to provide these routines if SQLITE_DEBUG is +** defined and if NDEBUG is not defined. +** +** ^These routines should return true if the mutex in their argument +** is held or not held, respectively, by the calling thread. +** +** ^The implementation is not required to provide versions of these +** routines that actually work. If the implementation does not provide working +** versions of these routines, it should at least provide stubs that always +** return true so that one does not get spurious assertion failures. +** +** ^If the argument to sqlite3_mutex_held() is a NULL pointer then +** the routine should return 1. This seems counter-intuitive since +** clearly the mutex cannot be held if it does not exist. But +** the reason the mutex does not exist is because the build is not +** using mutexes. And we do not want the assert() containing the +** call to sqlite3_mutex_held() to fail, so a non-zero return is +** the appropriate thing to do. ^The sqlite3_mutex_notheld() +** interface should also return 1 when given a NULL pointer. +*/ +#ifndef NDEBUG +SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*); +SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*); +#endif + +/* +** CAPI3REF: Mutex Types +** +** The [sqlite3_mutex_alloc()] interface takes a single argument +** which is one of these integer constants. +** +** The set of static mutexes may change from one SQLite release to the +** next. Applications that override the built-in mutex logic must be +** prepared to accommodate additional static mutexes. +*/ +#define SQLITE_MUTEX_FAST 0 +#define SQLITE_MUTEX_RECURSIVE 1 +#define SQLITE_MUTEX_STATIC_MASTER 2 +#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */ +#define SQLITE_MUTEX_STATIC_MEM2 4 /* NOT USED */ +#define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */ +#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */ +#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ +#define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */ +#define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */ + +/* +** CAPI3REF: Retrieve the mutex for a database connection +** +** ^This interface returns a pointer the [sqlite3_mutex] object that +** serializes access to the [database connection] given in the argument +** when the [threading mode] is Serialized. +** ^If the [threading mode] is Single-thread or Multi-thread then this +** routine returns a NULL pointer. +*/ +SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*); + +/* +** CAPI3REF: Low-Level Control Of Database Files +** +** ^The [sqlite3_file_control()] interface makes a direct call to the +** xFileControl method for the [sqlite3_io_methods] object associated +** with a particular database identified by the second argument. ^The +** name of the database is "main" for the main database or "temp" for the +** TEMP database, or the name that appears after the AS keyword for +** databases that are added using the [ATTACH] SQL command. +** ^A NULL pointer can be used in place of "main" to refer to the +** main database file. +** ^The third and fourth parameters to this routine +** are passed directly through to the second and third parameters of +** the xFileControl method. ^The return value of the xFileControl +** method becomes the return value of this routine. +** +** ^The SQLITE_FCNTL_FILE_POINTER value for the op parameter causes +** a pointer to the underlying [sqlite3_file] object to be written into +** the space pointed to by the 4th parameter. ^The SQLITE_FCNTL_FILE_POINTER +** case is a short-circuit path which does not actually invoke the +** underlying sqlite3_io_methods.xFileControl method. +** +** ^If the second parameter (zDbName) does not match the name of any +** open database file, then SQLITE_ERROR is returned. ^This error +** code is not remembered and will not be recalled by [sqlite3_errcode()] +** or [sqlite3_errmsg()]. The underlying xFileControl method might +** also return SQLITE_ERROR. There is no way to distinguish between +** an incorrect zDbName and an SQLITE_ERROR return from the underlying +** xFileControl method. +** +** See also: [SQLITE_FCNTL_LOCKSTATE] +*/ +SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); + +/* +** CAPI3REF: Testing Interface +** +** ^The sqlite3_test_control() interface is used to read out internal +** state of SQLite and to inject faults into SQLite for testing +** purposes. ^The first parameter is an operation code that determines +** the number, meaning, and operation of all subsequent parameters. +** +** This interface is not for use by applications. It exists solely +** for verifying the correct operation of the SQLite library. Depending +** on how the SQLite library is compiled, this interface might not exist. +** +** The details of the operation codes, their meanings, the parameters +** they take, and what they do are all subject to change without notice. +** Unlike most of the SQLite API, this function is not guaranteed to +** operate consistently from one release to the next. +*/ +SQLITE_API int sqlite3_test_control(int op, ...); + +/* +** CAPI3REF: Testing Interface Operation Codes +** +** These constants are the valid operation code parameters used +** as the first argument to [sqlite3_test_control()]. +** +** These parameters and their meanings are subject to change +** without notice. These values are for testing purposes only. +** Applications should not use any of these parameters or the +** [sqlite3_test_control()] interface. +*/ +#define SQLITE_TESTCTRL_FIRST 5 +#define SQLITE_TESTCTRL_PRNG_SAVE 5 +#define SQLITE_TESTCTRL_PRNG_RESTORE 6 +#define SQLITE_TESTCTRL_PRNG_RESET 7 +#define SQLITE_TESTCTRL_BITVEC_TEST 8 +#define SQLITE_TESTCTRL_FAULT_INSTALL 9 +#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10 +#define SQLITE_TESTCTRL_PENDING_BYTE 11 +#define SQLITE_TESTCTRL_ASSERT 12 +#define SQLITE_TESTCTRL_ALWAYS 13 +#define SQLITE_TESTCTRL_RESERVE 14 +#define SQLITE_TESTCTRL_OPTIMIZATIONS 15 +#define SQLITE_TESTCTRL_ISKEYWORD 16 +#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 +#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 +#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 +#define SQLITE_TESTCTRL_LAST 19 + +/* +** CAPI3REF: SQLite Runtime Status +** +** ^This interface is used to retrieve runtime status information +** about the performance of SQLite, and optionally to reset various +** highwater marks. ^The first argument is an integer code for +** the specific parameter to measure. ^(Recognized integer codes +** are of the form [status parameters | SQLITE_STATUS_...].)^ +** ^The current value of the parameter is returned into *pCurrent. +** ^The highest recorded value is returned in *pHighwater. ^If the +** resetFlag is true, then the highest record value is reset after +** *pHighwater is written. ^(Some parameters do not record the highest +** value. For those parameters +** nothing is written into *pHighwater and the resetFlag is ignored.)^ +** ^(Other parameters record only the highwater mark and not the current +** value. For these latter parameters nothing is written into *pCurrent.)^ +** +** ^The sqlite3_status() routine returns SQLITE_OK on success and a +** non-zero [error code] on failure. +** +** This routine is threadsafe but is not atomic. This routine can be +** called while other threads are running the same or different SQLite +** interfaces. However the values returned in *pCurrent and +** *pHighwater reflect the status of SQLite at different points in time +** and it is possible that another thread might change the parameter +** in between the times when *pCurrent and *pHighwater are written. +** +** See also: [sqlite3_db_status()] +*/ +SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag); + + +/* +** CAPI3REF: Status Parameters +** KEYWORDS: {status parameters} +** +** These integer constants designate various run-time status parameters +** that can be returned by [sqlite3_status()]. +** +**
+** [[SQLITE_STATUS_MEMORY_USED]] ^(
SQLITE_STATUS_MEMORY_USED
+**
This parameter is the current amount of memory checked out +** using [sqlite3_malloc()], either directly or indirectly. The +** figure includes calls made to [sqlite3_malloc()] by the application +** and internal memory usage by the SQLite library. Scratch memory +** controlled by [SQLITE_CONFIG_SCRATCH] and auxiliary page-cache +** memory controlled by [SQLITE_CONFIG_PAGECACHE] is not included in +** this parameter. The amount returned is the sum of the allocation +** sizes as reported by the xSize method in [sqlite3_mem_methods].
)^ +** +** [[SQLITE_STATUS_MALLOC_SIZE]] ^(
SQLITE_STATUS_MALLOC_SIZE
+**
This parameter records the largest memory allocation request +** handed to [sqlite3_malloc()] or [sqlite3_realloc()] (or their +** internal equivalents). Only the value returned in the +** *pHighwater parameter to [sqlite3_status()] is of interest. +** The value written into the *pCurrent parameter is undefined.
)^ +** +** [[SQLITE_STATUS_MALLOC_COUNT]] ^(
SQLITE_STATUS_MALLOC_COUNT
+**
This parameter records the number of separate memory allocations +** currently checked out.
)^ +** +** [[SQLITE_STATUS_PAGECACHE_USED]] ^(
SQLITE_STATUS_PAGECACHE_USED
+**
This parameter returns the number of pages used out of the +** [pagecache memory allocator] that was configured using +** [SQLITE_CONFIG_PAGECACHE]. The +** value returned is in pages, not in bytes.
)^ +** +** [[SQLITE_STATUS_PAGECACHE_OVERFLOW]] +** ^(
SQLITE_STATUS_PAGECACHE_OVERFLOW
+**
This parameter returns the number of bytes of page cache +** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE] +** buffer and where forced to overflow to [sqlite3_malloc()]. The +** returned value includes allocations that overflowed because they +** where too large (they were larger than the "sz" parameter to +** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because +** no space was left in the page cache.
)^ +** +** [[SQLITE_STATUS_PAGECACHE_SIZE]] ^(
SQLITE_STATUS_PAGECACHE_SIZE
+**
This parameter records the largest memory allocation request +** handed to [pagecache memory allocator]. Only the value returned in the +** *pHighwater parameter to [sqlite3_status()] is of interest. +** The value written into the *pCurrent parameter is undefined.
)^ +** +** [[SQLITE_STATUS_SCRATCH_USED]] ^(
SQLITE_STATUS_SCRATCH_USED
+**
This parameter returns the number of allocations used out of the +** [scratch memory allocator] configured using +** [SQLITE_CONFIG_SCRATCH]. The value returned is in allocations, not +** in bytes. Since a single thread may only have one scratch allocation +** outstanding at time, this parameter also reports the number of threads +** using scratch memory at the same time.
)^ +** +** [[SQLITE_STATUS_SCRATCH_OVERFLOW]] ^(
SQLITE_STATUS_SCRATCH_OVERFLOW
+**
This parameter returns the number of bytes of scratch memory +** allocation which could not be satisfied by the [SQLITE_CONFIG_SCRATCH] +** buffer and where forced to overflow to [sqlite3_malloc()]. The values +** returned include overflows because the requested allocation was too +** larger (that is, because the requested allocation was larger than the +** "sz" parameter to [SQLITE_CONFIG_SCRATCH]) and because no scratch buffer +** slots were available. +**
)^ +** +** [[SQLITE_STATUS_SCRATCH_SIZE]] ^(
SQLITE_STATUS_SCRATCH_SIZE
+**
This parameter records the largest memory allocation request +** handed to [scratch memory allocator]. Only the value returned in the +** *pHighwater parameter to [sqlite3_status()] is of interest. +** The value written into the *pCurrent parameter is undefined.
)^ +** +** [[SQLITE_STATUS_PARSER_STACK]] ^(
SQLITE_STATUS_PARSER_STACK
+**
This parameter records the deepest parser stack. It is only +** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].
)^ +**
+** +** New status parameters may be added from time to time. +*/ +#define SQLITE_STATUS_MEMORY_USED 0 +#define SQLITE_STATUS_PAGECACHE_USED 1 +#define SQLITE_STATUS_PAGECACHE_OVERFLOW 2 +#define SQLITE_STATUS_SCRATCH_USED 3 +#define SQLITE_STATUS_SCRATCH_OVERFLOW 4 +#define SQLITE_STATUS_MALLOC_SIZE 5 +#define SQLITE_STATUS_PARSER_STACK 6 +#define SQLITE_STATUS_PAGECACHE_SIZE 7 +#define SQLITE_STATUS_SCRATCH_SIZE 8 +#define SQLITE_STATUS_MALLOC_COUNT 9 + +/* +** CAPI3REF: Database Connection Status +** +** ^This interface is used to retrieve runtime status information +** about a single [database connection]. ^The first argument is the +** database connection object to be interrogated. ^The second argument +** is an integer constant, taken from the set of +** [SQLITE_DBSTATUS options], that +** determines the parameter to interrogate. The set of +** [SQLITE_DBSTATUS options] is likely +** to grow in future releases of SQLite. +** +** ^The current value of the requested parameter is written into *pCur +** and the highest instantaneous value is written into *pHiwtr. ^If +** the resetFlg is true, then the highest instantaneous value is +** reset back down to the current value. +** +** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a +** non-zero [error code] on failure. +** +** See also: [sqlite3_status()] and [sqlite3_stmt_status()]. +*/ +SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); + +/* +** CAPI3REF: Status Parameters for database connections +** KEYWORDS: {SQLITE_DBSTATUS options} +** +** These constants are the available integer "verbs" that can be passed as +** the second argument to the [sqlite3_db_status()] interface. +** +** New verbs may be added in future releases of SQLite. Existing verbs +** might be discontinued. Applications should check the return code from +** [sqlite3_db_status()] to make sure that the call worked. +** The [sqlite3_db_status()] interface will return a non-zero error code +** if a discontinued or unsupported verb is invoked. +** +**
+** [[SQLITE_DBSTATUS_LOOKASIDE_USED]] ^(
SQLITE_DBSTATUS_LOOKASIDE_USED
+**
This parameter returns the number of lookaside memory slots currently +** checked out.
)^ +** +** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(
SQLITE_DBSTATUS_LOOKASIDE_HIT
+**
This parameter returns the number malloc attempts that were +** satisfied using lookaside memory. Only the high-water value is meaningful; +** the current value is always zero.)^ +** +** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE]] +** ^(
SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE
+**
This parameter returns the number malloc attempts that might have +** been satisfied using lookaside memory but failed due to the amount of +** memory requested being larger than the lookaside slot size. +** Only the high-water value is meaningful; +** the current value is always zero.)^ +** +** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL]] +** ^(
SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL
+**
This parameter returns the number malloc attempts that might have +** been satisfied using lookaside memory but failed due to all lookaside +** memory already being in use. +** Only the high-water value is meaningful; +** the current value is always zero.)^ +** +** [[SQLITE_DBSTATUS_CACHE_USED]] ^(
SQLITE_DBSTATUS_CACHE_USED
+**
This parameter returns the approximate number of of bytes of heap +** memory used by all pager caches associated with the database connection.)^ +** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0. +** +** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(
SQLITE_DBSTATUS_SCHEMA_USED
+**
This parameter returns the approximate number of of bytes of heap +** memory used to store the schema for all databases associated +** with the connection - main, temp, and any [ATTACH]-ed databases.)^ +** ^The full amount of memory used by the schemas is reported, even if the +** schema memory is shared with other database connections due to +** [shared cache mode] being enabled. +** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0. +** +** [[SQLITE_DBSTATUS_STMT_USED]] ^(
SQLITE_DBSTATUS_STMT_USED
+**
This parameter returns the approximate number of of bytes of heap +** and lookaside memory used by all prepared statements associated with +** the database connection.)^ +** ^The highwater mark associated with SQLITE_DBSTATUS_STMT_USED is always 0. +**
+** +** [[SQLITE_DBSTATUS_CACHE_HIT]] ^(
SQLITE_DBSTATUS_CACHE_HIT
+**
This parameter returns the number of pager cache hits that have +** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_HIT +** is always 0. +**
+** +** [[SQLITE_DBSTATUS_CACHE_MISS]] ^(
SQLITE_DBSTATUS_CACHE_MISS
+**
This parameter returns the number of pager cache misses that have +** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS +** is always 0. +**
+**
+*/ +#define SQLITE_DBSTATUS_LOOKASIDE_USED 0 +#define SQLITE_DBSTATUS_CACHE_USED 1 +#define SQLITE_DBSTATUS_SCHEMA_USED 2 +#define SQLITE_DBSTATUS_STMT_USED 3 +#define SQLITE_DBSTATUS_LOOKASIDE_HIT 4 +#define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5 +#define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6 +#define SQLITE_DBSTATUS_CACHE_HIT 7 +#define SQLITE_DBSTATUS_CACHE_MISS 8 +#define SQLITE_DBSTATUS_MAX 8 /* Largest defined DBSTATUS */ + + +/* +** CAPI3REF: Prepared Statement Status +** +** ^(Each prepared statement maintains various +** [SQLITE_STMTSTATUS counters] that measure the number +** of times it has performed specific operations.)^ These counters can +** be used to monitor the performance characteristics of the prepared +** statements. For example, if the number of table steps greatly exceeds +** the number of table searches or result rows, that would tend to indicate +** that the prepared statement is using a full table scan rather than +** an index. +** +** ^(This interface is used to retrieve and reset counter values from +** a [prepared statement]. The first argument is the prepared statement +** object to be interrogated. The second argument +** is an integer code for a specific [SQLITE_STMTSTATUS counter] +** to be interrogated.)^ +** ^The current value of the requested counter is returned. +** ^If the resetFlg is true, then the counter is reset to zero after this +** interface call returns. +** +** See also: [sqlite3_status()] and [sqlite3_db_status()]. +*/ +SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); + +/* +** CAPI3REF: Status Parameters for prepared statements +** KEYWORDS: {SQLITE_STMTSTATUS counter} {SQLITE_STMTSTATUS counters} +** +** These preprocessor macros define integer codes that name counter +** values associated with the [sqlite3_stmt_status()] interface. +** The meanings of the various counters are as follows: +** +**
+** [[SQLITE_STMTSTATUS_FULLSCAN_STEP]]
SQLITE_STMTSTATUS_FULLSCAN_STEP
+**
^This is the number of times that SQLite has stepped forward in +** a table as part of a full table scan. Large numbers for this counter +** may indicate opportunities for performance improvement through +** careful use of indices.
+** +** [[SQLITE_STMTSTATUS_SORT]]
SQLITE_STMTSTATUS_SORT
+**
^This is the number of sort operations that have occurred. +** A non-zero value in this counter may indicate an opportunity to +** improvement performance through careful use of indices.
+** +** [[SQLITE_STMTSTATUS_AUTOINDEX]]
SQLITE_STMTSTATUS_AUTOINDEX
+**
^This is the number of rows inserted into transient indices that +** were created automatically in order to help joins run faster. +** A non-zero value in this counter may indicate an opportunity to +** improvement performance by adding permanent indices that do not +** need to be reinitialized each time the statement is run.
+**
+*/ +#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1 +#define SQLITE_STMTSTATUS_SORT 2 +#define SQLITE_STMTSTATUS_AUTOINDEX 3 + +/* +** CAPI3REF: Custom Page Cache Object +** +** The sqlite3_pcache type is opaque. It is implemented by +** the pluggable module. The SQLite core has no knowledge of +** its size or internal structure and never deals with the +** sqlite3_pcache object except by holding and passing pointers +** to the object. +** +** See [sqlite3_pcache_methods2] for additional information. +*/ +typedef struct sqlite3_pcache sqlite3_pcache; + +/* +** CAPI3REF: Custom Page Cache Object +** +** The sqlite3_pcache_page object represents a single page in the +** page cache. The page cache will allocate instances of this +** object. Various methods of the page cache use pointers to instances +** of this object as parameters or as their return value. +** +** See [sqlite3_pcache_methods2] for additional information. +*/ +typedef struct sqlite3_pcache_page sqlite3_pcache_page; +struct sqlite3_pcache_page { + void *pBuf; /* The content of the page */ + void *pExtra; /* Extra information associated with the page */ +}; + +/* +** CAPI3REF: Application Defined Page Cache. +** KEYWORDS: {page cache} +** +** ^(The [sqlite3_config]([SQLITE_CONFIG_PCACHE2], ...) interface can +** register an alternative page cache implementation by passing in an +** instance of the sqlite3_pcache_methods2 structure.)^ +** In many applications, most of the heap memory allocated by +** SQLite is used for the page cache. +** By implementing a +** custom page cache using this API, an application can better control +** the amount of memory consumed by SQLite, the way in which +** that memory is allocated and released, and the policies used to +** determine exactly which parts of a database file are cached and for +** how long. +** +** The alternative page cache mechanism is an +** extreme measure that is only needed by the most demanding applications. +** The built-in page cache is recommended for most uses. +** +** ^(The contents of the sqlite3_pcache_methods2 structure are copied to an +** internal buffer by SQLite within the call to [sqlite3_config]. Hence +** the application may discard the parameter after the call to +** [sqlite3_config()] returns.)^ +** +** [[the xInit() page cache method]] +** ^(The xInit() method is called once for each effective +** call to [sqlite3_initialize()])^ +** (usually only once during the lifetime of the process). ^(The xInit() +** method is passed a copy of the sqlite3_pcache_methods2.pArg value.)^ +** The intent of the xInit() method is to set up global data structures +** required by the custom page cache implementation. +** ^(If the xInit() method is NULL, then the +** built-in default page cache is used instead of the application defined +** page cache.)^ +** +** [[the xShutdown() page cache method]] +** ^The xShutdown() method is called by [sqlite3_shutdown()]. +** It can be used to clean up +** any outstanding resources before process shutdown, if required. +** ^The xShutdown() method may be NULL. +** +** ^SQLite automatically serializes calls to the xInit method, +** so the xInit method need not be threadsafe. ^The +** xShutdown method is only called from [sqlite3_shutdown()] so it does +** not need to be threadsafe either. All other methods must be threadsafe +** in multithreaded applications. +** +** ^SQLite will never invoke xInit() more than once without an intervening +** call to xShutdown(). +** +** [[the xCreate() page cache methods]] +** ^SQLite invokes the xCreate() method to construct a new cache instance. +** SQLite will typically create one cache instance for each open database file, +** though this is not guaranteed. ^The +** first parameter, szPage, is the size in bytes of the pages that must +** be allocated by the cache. ^szPage will always a power of two. ^The +** second parameter szExtra is a number of bytes of extra storage +** associated with each page cache entry. ^The szExtra parameter will +** a number less than 250. SQLite will use the +** extra szExtra bytes on each page to store metadata about the underlying +** database page on disk. The value passed into szExtra depends +** on the SQLite version, the target platform, and how SQLite was compiled. +** ^The third argument to xCreate(), bPurgeable, is true if the cache being +** created will be used to cache database pages of a file stored on disk, or +** false if it is used for an in-memory database. The cache implementation +** does not have to do anything special based with the value of bPurgeable; +** it is purely advisory. ^On a cache where bPurgeable is false, SQLite will +** never invoke xUnpin() except to deliberately delete a page. +** ^In other words, calls to xUnpin() on a cache with bPurgeable set to +** false will always have the "discard" flag set to true. +** ^Hence, a cache created with bPurgeable false will +** never contain any unpinned pages. +** +** [[the xCachesize() page cache method]] +** ^(The xCachesize() method may be called at any time by SQLite to set the +** suggested maximum cache-size (number of pages stored by) the cache +** instance passed as the first argument. This is the value configured using +** the SQLite "[PRAGMA cache_size]" command.)^ As with the bPurgeable +** parameter, the implementation is not required to do anything with this +** value; it is advisory only. +** +** [[the xPagecount() page cache methods]] +** The xPagecount() method must return the number of pages currently +** stored in the cache, both pinned and unpinned. +** +** [[the xFetch() page cache methods]] +** The xFetch() method locates a page in the cache and returns a pointer to +** an sqlite3_pcache_page object associated with that page, or a NULL pointer. +** The pBuf element of the returned sqlite3_pcache_page object will be a +** pointer to a buffer of szPage bytes used to store the content of a +** single database page. The pExtra element of sqlite3_pcache_page will be +** a pointer to the szExtra bytes of extra storage that SQLite has requested +** for each entry in the page cache. +** +** The page to be fetched is determined by the key. ^The minimum key value +** is 1. After it has been retrieved using xFetch, the page is considered +** to be "pinned". +** +** If the requested page is already in the page cache, then the page cache +** implementation must return a pointer to the page buffer with its content +** intact. If the requested page is not already in the cache, then the +** cache implementation should use the value of the createFlag +** parameter to help it determined what action to take: +** +** +**
createFlag Behaviour when page is not already in cache +**
0 Do not allocate a new page. Return NULL. +**
1 Allocate a new page if it easy and convenient to do so. +** Otherwise return NULL. +**
2 Make every effort to allocate a new page. Only return +** NULL if allocating a new page is effectively impossible. +**
+** +** ^(SQLite will normally invoke xFetch() with a createFlag of 0 or 1. SQLite +** will only use a createFlag of 2 after a prior call with a createFlag of 1 +** failed.)^ In between the to xFetch() calls, SQLite may +** attempt to unpin one or more cache pages by spilling the content of +** pinned pages to disk and synching the operating system disk cache. +** +** [[the xUnpin() page cache method]] +** ^xUnpin() is called by SQLite with a pointer to a currently pinned page +** as its second argument. If the third parameter, discard, is non-zero, +** then the page must be evicted from the cache. +** ^If the discard parameter is +** zero, then the page may be discarded or retained at the discretion of +** page cache implementation. ^The page cache implementation +** may choose to evict unpinned pages at any time. +** +** The cache must not perform any reference counting. A single +** call to xUnpin() unpins the page regardless of the number of prior calls +** to xFetch(). +** +** [[the xRekey() page cache methods]] +** The xRekey() method is used to change the key value associated with the +** page passed as the second argument. If the cache +** previously contains an entry associated with newKey, it must be +** discarded. ^Any prior cache entry associated with newKey is guaranteed not +** to be pinned. +** +** When SQLite calls the xTruncate() method, the cache must discard all +** existing cache entries with page numbers (keys) greater than or equal +** to the value of the iLimit parameter passed to xTruncate(). If any +** of these pages are pinned, they are implicitly unpinned, meaning that +** they can be safely discarded. +** +** [[the xDestroy() page cache method]] +** ^The xDestroy() method is used to delete a cache allocated by xCreate(). +** All resources associated with the specified cache should be freed. ^After +** calling the xDestroy() method, SQLite considers the [sqlite3_pcache*] +** handle invalid, and will not use it with any other sqlite3_pcache_methods2 +** functions. +** +** [[the xShrink() page cache method]] +** ^SQLite invokes the xShrink() method when it wants the page cache to +** free up as much of heap memory as possible. The page cache implementation +** is not obligated to free any memory, but well-behaved implementations should +** do their best. +*/ +typedef struct sqlite3_pcache_methods2 sqlite3_pcache_methods2; +struct sqlite3_pcache_methods2 { + int iVersion; + void *pArg; + int (*xInit)(void*); + void (*xShutdown)(void*); + sqlite3_pcache *(*xCreate)(int szPage, int szExtra, int bPurgeable); + void (*xCachesize)(sqlite3_pcache*, int nCachesize); + int (*xPagecount)(sqlite3_pcache*); + sqlite3_pcache_page *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); + void (*xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, int discard); + void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*, + unsigned oldKey, unsigned newKey); + void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); + void (*xDestroy)(sqlite3_pcache*); + void (*xShrink)(sqlite3_pcache*); +}; + +/* +** This is the obsolete pcache_methods object that has now been replaced +** by sqlite3_pcache_methods2. This object is not used by SQLite. It is +** retained in the header file for backwards compatibility only. +*/ +typedef struct sqlite3_pcache_methods sqlite3_pcache_methods; +struct sqlite3_pcache_methods { + void *pArg; + int (*xInit)(void*); + void (*xShutdown)(void*); + sqlite3_pcache *(*xCreate)(int szPage, int bPurgeable); + void (*xCachesize)(sqlite3_pcache*, int nCachesize); + int (*xPagecount)(sqlite3_pcache*); + void *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); + void (*xUnpin)(sqlite3_pcache*, void*, int discard); + void (*xRekey)(sqlite3_pcache*, void*, unsigned oldKey, unsigned newKey); + void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); + void (*xDestroy)(sqlite3_pcache*); +}; + + +/* +** CAPI3REF: Online Backup Object +** +** The sqlite3_backup object records state information about an ongoing +** online backup operation. ^The sqlite3_backup object is created by +** a call to [sqlite3_backup_init()] and is destroyed by a call to +** [sqlite3_backup_finish()]. +** +** See Also: [Using the SQLite Online Backup API] +*/ +typedef struct sqlite3_backup sqlite3_backup; + +/* +** CAPI3REF: Online Backup API. +** +** The backup API copies the content of one database into another. +** It is useful either for creating backups of databases or +** for copying in-memory databases to or from persistent files. +** +** See Also: [Using the SQLite Online Backup API] +** +** ^SQLite holds a write transaction open on the destination database file +** for the duration of the backup operation. +** ^The source database is read-locked only while it is being read; +** it is not locked continuously for the entire backup operation. +** ^Thus, the backup may be performed on a live source database without +** preventing other database connections from +** reading or writing to the source database while the backup is underway. +** +** ^(To perform a backup operation: +**
    +**
  1. sqlite3_backup_init() is called once to initialize the +** backup, +**
  2. sqlite3_backup_step() is called one or more times to transfer +** the data between the two databases, and finally +**
  3. sqlite3_backup_finish() is called to release all resources +** associated with the backup operation. +**
)^ +** There should be exactly one call to sqlite3_backup_finish() for each +** successful call to sqlite3_backup_init(). +** +** [[sqlite3_backup_init()]] sqlite3_backup_init() +** +** ^The D and N arguments to sqlite3_backup_init(D,N,S,M) are the +** [database connection] associated with the destination database +** and the database name, respectively. +** ^The database name is "main" for the main database, "temp" for the +** temporary database, or the name specified after the AS keyword in +** an [ATTACH] statement for an attached database. +** ^The S and M arguments passed to +** sqlite3_backup_init(D,N,S,M) identify the [database connection] +** and database name of the source database, respectively. +** ^The source and destination [database connections] (parameters S and D) +** must be different or else sqlite3_backup_init(D,N,S,M) will fail with +** an error. +** +** ^If an error occurs within sqlite3_backup_init(D,N,S,M), then NULL is +** returned and an error code and error message are stored in the +** destination [database connection] D. +** ^The error code and message for the failed call to sqlite3_backup_init() +** can be retrieved using the [sqlite3_errcode()], [sqlite3_errmsg()], and/or +** [sqlite3_errmsg16()] functions. +** ^A successful call to sqlite3_backup_init() returns a pointer to an +** [sqlite3_backup] object. +** ^The [sqlite3_backup] object may be used with the sqlite3_backup_step() and +** sqlite3_backup_finish() functions to perform the specified backup +** operation. +** +** [[sqlite3_backup_step()]] sqlite3_backup_step() +** +** ^Function sqlite3_backup_step(B,N) will copy up to N pages between +** the source and destination databases specified by [sqlite3_backup] object B. +** ^If N is negative, all remaining source pages are copied. +** ^If sqlite3_backup_step(B,N) successfully copies N pages and there +** are still more pages to be copied, then the function returns [SQLITE_OK]. +** ^If sqlite3_backup_step(B,N) successfully finishes copying all pages +** from source to destination, then it returns [SQLITE_DONE]. +** ^If an error occurs while running sqlite3_backup_step(B,N), +** then an [error code] is returned. ^As well as [SQLITE_OK] and +** [SQLITE_DONE], a call to sqlite3_backup_step() may return [SQLITE_READONLY], +** [SQLITE_NOMEM], [SQLITE_BUSY], [SQLITE_LOCKED], or an +** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX] extended error code. +** +** ^(The sqlite3_backup_step() might return [SQLITE_READONLY] if +**
    +**
  1. the destination database was opened read-only, or +**
  2. the destination database is using write-ahead-log journaling +** and the destination and source page sizes differ, or +**
  3. the destination database is an in-memory database and the +** destination and source page sizes differ. +**
)^ +** +** ^If sqlite3_backup_step() cannot obtain a required file-system lock, then +** the [sqlite3_busy_handler | busy-handler function] +** is invoked (if one is specified). ^If the +** busy-handler returns non-zero before the lock is available, then +** [SQLITE_BUSY] is returned to the caller. ^In this case the call to +** sqlite3_backup_step() can be retried later. ^If the source +** [database connection] +** is being used to write to the source database when sqlite3_backup_step() +** is called, then [SQLITE_LOCKED] is returned immediately. ^Again, in this +** case the call to sqlite3_backup_step() can be retried later on. ^(If +** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX], [SQLITE_NOMEM], or +** [SQLITE_READONLY] is returned, then +** there is no point in retrying the call to sqlite3_backup_step(). These +** errors are considered fatal.)^ The application must accept +** that the backup operation has failed and pass the backup operation handle +** to the sqlite3_backup_finish() to release associated resources. +** +** ^The first call to sqlite3_backup_step() obtains an exclusive lock +** on the destination file. ^The exclusive lock is not released until either +** sqlite3_backup_finish() is called or the backup operation is complete +** and sqlite3_backup_step() returns [SQLITE_DONE]. ^Every call to +** sqlite3_backup_step() obtains a [shared lock] on the source database that +** lasts for the duration of the sqlite3_backup_step() call. +** ^Because the source database is not locked between calls to +** sqlite3_backup_step(), the source database may be modified mid-way +** through the backup process. ^If the source database is modified by an +** external process or via a database connection other than the one being +** used by the backup operation, then the backup will be automatically +** restarted by the next call to sqlite3_backup_step(). ^If the source +** database is modified by the using the same database connection as is used +** by the backup operation, then the backup database is automatically +** updated at the same time. +** +** [[sqlite3_backup_finish()]] sqlite3_backup_finish() +** +** When sqlite3_backup_step() has returned [SQLITE_DONE], or when the +** application wishes to abandon the backup operation, the application +** should destroy the [sqlite3_backup] by passing it to sqlite3_backup_finish(). +** ^The sqlite3_backup_finish() interfaces releases all +** resources associated with the [sqlite3_backup] object. +** ^If sqlite3_backup_step() has not yet returned [SQLITE_DONE], then any +** active write-transaction on the destination database is rolled back. +** The [sqlite3_backup] object is invalid +** and may not be used following a call to sqlite3_backup_finish(). +** +** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no +** sqlite3_backup_step() errors occurred, regardless or whether or not +** sqlite3_backup_step() completed. +** ^If an out-of-memory condition or IO error occurred during any prior +** sqlite3_backup_step() call on the same [sqlite3_backup] object, then +** sqlite3_backup_finish() returns the corresponding [error code]. +** +** ^A return of [SQLITE_BUSY] or [SQLITE_LOCKED] from sqlite3_backup_step() +** is not a permanent error and does not affect the return value of +** sqlite3_backup_finish(). +** +** [[sqlite3_backup__remaining()]] [[sqlite3_backup_pagecount()]] +** sqlite3_backup_remaining() and sqlite3_backup_pagecount() +** +** ^Each call to sqlite3_backup_step() sets two values inside +** the [sqlite3_backup] object: the number of pages still to be backed +** up and the total number of pages in the source database file. +** The sqlite3_backup_remaining() and sqlite3_backup_pagecount() interfaces +** retrieve these two values, respectively. +** +** ^The values returned by these functions are only updated by +** sqlite3_backup_step(). ^If the source database is modified during a backup +** operation, then the values are not updated to account for any extra +** pages that need to be updated or the size of the source database file +** changing. +** +** Concurrent Usage of Database Handles +** +** ^The source [database connection] may be used by the application for other +** purposes while a backup operation is underway or being initialized. +** ^If SQLite is compiled and configured to support threadsafe database +** connections, then the source database connection may be used concurrently +** from within other threads. +** +** However, the application must guarantee that the destination +** [database connection] is not passed to any other API (by any thread) after +** sqlite3_backup_init() is called and before the corresponding call to +** sqlite3_backup_finish(). SQLite does not currently check to see +** if the application incorrectly accesses the destination [database connection] +** and so no error code is reported, but the operations may malfunction +** nevertheless. Use of the destination database connection while a +** backup is in progress might also also cause a mutex deadlock. +** +** If running in [shared cache mode], the application must +** guarantee that the shared cache used by the destination database +** is not accessed while the backup is running. In practice this means +** that the application must guarantee that the disk file being +** backed up to is not accessed by any connection within the process, +** not just the specific connection that was passed to sqlite3_backup_init(). +** +** The [sqlite3_backup] object itself is partially threadsafe. Multiple +** threads may safely make multiple concurrent calls to sqlite3_backup_step(). +** However, the sqlite3_backup_remaining() and sqlite3_backup_pagecount() +** APIs are not strictly speaking threadsafe. If they are invoked at the +** same time as another thread is invoking sqlite3_backup_step() it is +** possible that they return invalid values. +*/ +SQLITE_API sqlite3_backup *sqlite3_backup_init( + sqlite3 *pDest, /* Destination database handle */ + const char *zDestName, /* Destination database name */ + sqlite3 *pSource, /* Source database handle */ + const char *zSourceName /* Source database name */ +); +SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage); +SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p); +SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p); +SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); + +/* +** CAPI3REF: Unlock Notification +** +** ^When running in shared-cache mode, a database operation may fail with +** an [SQLITE_LOCKED] error if the required locks on the shared-cache or +** individual tables within the shared-cache cannot be obtained. See +** [SQLite Shared-Cache Mode] for a description of shared-cache locking. +** ^This API may be used to register a callback that SQLite will invoke +** when the connection currently holding the required lock relinquishes it. +** ^This API is only available if the library was compiled with the +** [SQLITE_ENABLE_UNLOCK_NOTIFY] C-preprocessor symbol defined. +** +** See Also: [Using the SQLite Unlock Notification Feature]. +** +** ^Shared-cache locks are released when a database connection concludes +** its current transaction, either by committing it or rolling it back. +** +** ^When a connection (known as the blocked connection) fails to obtain a +** shared-cache lock and SQLITE_LOCKED is returned to the caller, the +** identity of the database connection (the blocking connection) that +** has locked the required resource is stored internally. ^After an +** application receives an SQLITE_LOCKED error, it may call the +** sqlite3_unlock_notify() method with the blocked connection handle as +** the first argument to register for a callback that will be invoked +** when the blocking connections current transaction is concluded. ^The +** callback is invoked from within the [sqlite3_step] or [sqlite3_close] +** call that concludes the blocking connections transaction. +** +** ^(If sqlite3_unlock_notify() is called in a multi-threaded application, +** there is a chance that the blocking connection will have already +** concluded its transaction by the time sqlite3_unlock_notify() is invoked. +** If this happens, then the specified callback is invoked immediately, +** from within the call to sqlite3_unlock_notify().)^ +** +** ^If the blocked connection is attempting to obtain a write-lock on a +** shared-cache table, and more than one other connection currently holds +** a read-lock on the same table, then SQLite arbitrarily selects one of +** the other connections to use as the blocking connection. +** +** ^(There may be at most one unlock-notify callback registered by a +** blocked connection. If sqlite3_unlock_notify() is called when the +** blocked connection already has a registered unlock-notify callback, +** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is +** called with a NULL pointer as its second argument, then any existing +** unlock-notify callback is canceled. ^The blocked connections +** unlock-notify callback may also be canceled by closing the blocked +** connection using [sqlite3_close()]. +** +** The unlock-notify callback is not reentrant. If an application invokes +** any sqlite3_xxx API functions from within an unlock-notify callback, a +** crash or deadlock may be the result. +** +** ^Unless deadlock is detected (see below), sqlite3_unlock_notify() always +** returns SQLITE_OK. +** +** Callback Invocation Details +** +** When an unlock-notify callback is registered, the application provides a +** single void* pointer that is passed to the callback when it is invoked. +** However, the signature of the callback function allows SQLite to pass +** it an array of void* context pointers. The first argument passed to +** an unlock-notify callback is a pointer to an array of void* pointers, +** and the second is the number of entries in the array. +** +** When a blocking connections transaction is concluded, there may be +** more than one blocked connection that has registered for an unlock-notify +** callback. ^If two or more such blocked connections have specified the +** same callback function, then instead of invoking the callback function +** multiple times, it is invoked once with the set of void* context pointers +** specified by the blocked connections bundled together into an array. +** This gives the application an opportunity to prioritize any actions +** related to the set of unblocked database connections. +** +** Deadlock Detection +** +** Assuming that after registering for an unlock-notify callback a +** database waits for the callback to be issued before taking any further +** action (a reasonable assumption), then using this API may cause the +** application to deadlock. For example, if connection X is waiting for +** connection Y's transaction to be concluded, and similarly connection +** Y is waiting on connection X's transaction, then neither connection +** will proceed and the system may remain deadlocked indefinitely. +** +** To avoid this scenario, the sqlite3_unlock_notify() performs deadlock +** detection. ^If a given call to sqlite3_unlock_notify() would put the +** system in a deadlocked state, then SQLITE_LOCKED is returned and no +** unlock-notify callback is registered. The system is said to be in +** a deadlocked state if connection A has registered for an unlock-notify +** callback on the conclusion of connection B's transaction, and connection +** B has itself registered for an unlock-notify callback when connection +** A's transaction is concluded. ^Indirect deadlock is also detected, so +** the system is also considered to be deadlocked if connection B has +** registered for an unlock-notify callback on the conclusion of connection +** C's transaction, where connection C is waiting on connection A. ^Any +** number of levels of indirection are allowed. +** +** The "DROP TABLE" Exception +** +** When a call to [sqlite3_step()] returns SQLITE_LOCKED, it is almost +** always appropriate to call sqlite3_unlock_notify(). There is however, +** one exception. When executing a "DROP TABLE" or "DROP INDEX" statement, +** SQLite checks if there are any currently executing SELECT statements +** that belong to the same connection. If there are, SQLITE_LOCKED is +** returned. In this case there is no "blocking connection", so invoking +** sqlite3_unlock_notify() results in the unlock-notify callback being +** invoked immediately. If the application then re-attempts the "DROP TABLE" +** or "DROP INDEX" query, an infinite loop might be the result. +** +** One way around this problem is to check the extended error code returned +** by an sqlite3_step() call. ^(If there is a blocking connection, then the +** extended error code is set to SQLITE_LOCKED_SHAREDCACHE. Otherwise, in +** the special "DROP TABLE/INDEX" case, the extended error code is just +** SQLITE_LOCKED.)^ +*/ +SQLITE_API int sqlite3_unlock_notify( + sqlite3 *pBlocked, /* Waiting connection */ + void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */ + void *pNotifyArg /* Argument to pass to xNotify */ +); + + +/* +** CAPI3REF: String Comparison +** +** ^The [sqlite3_strnicmp()] API allows applications and extensions to +** compare the contents of two buffers containing UTF-8 strings in a +** case-independent fashion, using the same definition of case independence +** that SQLite uses internally when comparing identifiers. +*/ +SQLITE_API int sqlite3_strnicmp(const char *, const char *, int); + +/* +** CAPI3REF: Error Logging Interface +** +** ^The [sqlite3_log()] interface writes a message into the error log +** established by the [SQLITE_CONFIG_LOG] option to [sqlite3_config()]. +** ^If logging is enabled, the zFormat string and subsequent arguments are +** used with [sqlite3_snprintf()] to generate the final output string. +** +** The sqlite3_log() interface is intended for use by extensions such as +** virtual tables, collating functions, and SQL functions. While there is +** nothing to prevent an application from calling sqlite3_log(), doing so +** is considered bad form. +** +** The zFormat string must not be NULL. +** +** To avoid deadlocks and other threading problems, the sqlite3_log() routine +** will not use dynamically allocated memory. The log message is stored in +** a fixed-length buffer on the stack. If the log message is longer than +** a few hundred characters, it will be truncated to the length of the +** buffer. +*/ +SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...); + +/* +** CAPI3REF: Write-Ahead Log Commit Hook +** +** ^The [sqlite3_wal_hook()] function is used to register a callback that +** will be invoked each time a database connection commits data to a +** [write-ahead log] (i.e. whenever a transaction is committed in +** [journal_mode | journal_mode=WAL mode]). +** +** ^The callback is invoked by SQLite after the commit has taken place and +** the associated write-lock on the database released, so the implementation +** may read, write or [checkpoint] the database as required. +** +** ^The first parameter passed to the callback function when it is invoked +** is a copy of the third parameter passed to sqlite3_wal_hook() when +** registering the callback. ^The second is a copy of the database handle. +** ^The third parameter is the name of the database that was written to - +** either "main" or the name of an [ATTACH]-ed database. ^The fourth parameter +** is the number of pages currently in the write-ahead log file, +** including those that were just committed. +** +** The callback function should normally return [SQLITE_OK]. ^If an error +** code is returned, that error will propagate back up through the +** SQLite code base to cause the statement that provoked the callback +** to report an error, though the commit will have still occurred. If the +** callback returns [SQLITE_ROW] or [SQLITE_DONE], or if it returns a value +** that does not correspond to any valid SQLite error code, the results +** are undefined. +** +** A single database handle may have at most a single write-ahead log callback +** registered at one time. ^Calling [sqlite3_wal_hook()] replaces any +** previously registered write-ahead log callback. ^Note that the +** [sqlite3_wal_autocheckpoint()] interface and the +** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will +** those overwrite any prior [sqlite3_wal_hook()] settings. +*/ +SQLITE_API void *sqlite3_wal_hook( + sqlite3*, + int(*)(void *,sqlite3*,const char*,int), + void* +); + +/* +** CAPI3REF: Configure an auto-checkpoint +** +** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around +** [sqlite3_wal_hook()] that causes any database on [database connection] D +** to automatically [checkpoint] +** after committing a transaction if there are N or +** more frames in the [write-ahead log] file. ^Passing zero or +** a negative value as the nFrame parameter disables automatic +** checkpoints entirely. +** +** ^The callback registered by this function replaces any existing callback +** registered using [sqlite3_wal_hook()]. ^Likewise, registering a callback +** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism +** configured by this function. +** +** ^The [wal_autocheckpoint pragma] can be used to invoke this interface +** from SQL. +** +** ^Every new [database connection] defaults to having the auto-checkpoint +** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT] +** pages. The use of this interface +** is only necessary if the default setting is found to be suboptimal +** for a particular application. +*/ +SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N); + +/* +** CAPI3REF: Checkpoint a database +** +** ^The [sqlite3_wal_checkpoint(D,X)] interface causes database named X +** on [database connection] D to be [checkpointed]. ^If X is NULL or an +** empty string, then a checkpoint is run on all databases of +** connection D. ^If the database connection D is not in +** [WAL | write-ahead log mode] then this interface is a harmless no-op. +** +** ^The [wal_checkpoint pragma] can be used to invoke this interface +** from SQL. ^The [sqlite3_wal_autocheckpoint()] interface and the +** [wal_autocheckpoint pragma] can be used to cause this interface to be +** run whenever the WAL reaches a certain size threshold. +** +** See also: [sqlite3_wal_checkpoint_v2()] +*/ +SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb); + +/* +** CAPI3REF: Checkpoint a database +** +** Run a checkpoint operation on WAL database zDb attached to database +** handle db. The specific operation is determined by the value of the +** eMode parameter: +** +**
+**
SQLITE_CHECKPOINT_PASSIVE
+** Checkpoint as many frames as possible without waiting for any database +** readers or writers to finish. Sync the db file if all frames in the log +** are checkpointed. This mode is the same as calling +** sqlite3_wal_checkpoint(). The busy-handler callback is never invoked. +** +**
SQLITE_CHECKPOINT_FULL
+** This mode blocks (calls the busy-handler callback) until there is no +** database writer and all readers are reading from the most recent database +** snapshot. It then checkpoints all frames in the log file and syncs the +** database file. This call blocks database writers while it is running, +** but not database readers. +** +**
SQLITE_CHECKPOINT_RESTART
+** This mode works the same way as SQLITE_CHECKPOINT_FULL, except after +** checkpointing the log file it blocks (calls the busy-handler callback) +** until all readers are reading from the database file only. This ensures +** that the next client to write to the database file restarts the log file +** from the beginning. This call blocks database writers while it is running, +** but not database readers. +**
+** +** If pnLog is not NULL, then *pnLog is set to the total number of frames in +** the log file before returning. If pnCkpt is not NULL, then *pnCkpt is set to +** the total number of checkpointed frames (including any that were already +** checkpointed when this function is called). *pnLog and *pnCkpt may be +** populated even if sqlite3_wal_checkpoint_v2() returns other than SQLITE_OK. +** If no values are available because of an error, they are both set to -1 +** before returning to communicate this to the caller. +** +** All calls obtain an exclusive "checkpoint" lock on the database file. If +** any other process is running a checkpoint operation at the same time, the +** lock cannot be obtained and SQLITE_BUSY is returned. Even if there is a +** busy-handler configured, it will not be invoked in this case. +** +** The SQLITE_CHECKPOINT_FULL and RESTART modes also obtain the exclusive +** "writer" lock on the database file. If the writer lock cannot be obtained +** immediately, and a busy-handler is configured, it is invoked and the writer +** lock retried until either the busy-handler returns 0 or the lock is +** successfully obtained. The busy-handler is also invoked while waiting for +** database readers as described above. If the busy-handler returns 0 before +** the writer lock is obtained or while waiting for database readers, the +** checkpoint operation proceeds from that point in the same way as +** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible +** without blocking any further. SQLITE_BUSY is returned in this case. +** +** If parameter zDb is NULL or points to a zero length string, then the +** specified operation is attempted on all WAL databases. In this case the +** values written to output parameters *pnLog and *pnCkpt are undefined. If +** an SQLITE_BUSY error is encountered when processing one or more of the +** attached WAL databases, the operation is still attempted on any remaining +** attached databases and SQLITE_BUSY is returned to the caller. If any other +** error occurs while processing an attached database, processing is abandoned +** and the error code returned to the caller immediately. If no error +** (SQLITE_BUSY or otherwise) is encountered while processing the attached +** databases, SQLITE_OK is returned. +** +** If database zDb is the name of an attached database that is not in WAL +** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. If +** zDb is not NULL (or a zero length string) and is not the name of any +** attached database, SQLITE_ERROR is returned to the caller. +*/ +SQLITE_API int sqlite3_wal_checkpoint_v2( + sqlite3 *db, /* Database handle */ + const char *zDb, /* Name of attached database (or NULL) */ + int eMode, /* SQLITE_CHECKPOINT_* value */ + int *pnLog, /* OUT: Size of WAL log in frames */ + int *pnCkpt /* OUT: Total number of frames checkpointed */ +); + +/* +** CAPI3REF: Checkpoint operation parameters +** +** These constants can be used as the 3rd parameter to +** [sqlite3_wal_checkpoint_v2()]. See the [sqlite3_wal_checkpoint_v2()] +** documentation for additional information about the meaning and use of +** each of these values. +*/ +#define SQLITE_CHECKPOINT_PASSIVE 0 +#define SQLITE_CHECKPOINT_FULL 1 +#define SQLITE_CHECKPOINT_RESTART 2 + +/* +** CAPI3REF: Virtual Table Interface Configuration +** +** This function may be called by either the [xConnect] or [xCreate] method +** of a [virtual table] implementation to configure +** various facets of the virtual table interface. +** +** If this interface is invoked outside the context of an xConnect or +** xCreate virtual table method then the behavior is undefined. +** +** At present, there is only one option that may be configured using +** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].) Further options +** may be added in the future. +*/ +SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); + +/* +** CAPI3REF: Virtual Table Configuration Options +** +** These macros define the various options to the +** [sqlite3_vtab_config()] interface that [virtual table] implementations +** can use to customize and optimize their behavior. +** +**
+**
SQLITE_VTAB_CONSTRAINT_SUPPORT +**
Calls of the form +** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported, +** where X is an integer. If X is zero, then the [virtual table] whose +** [xCreate] or [xConnect] method invoked [sqlite3_vtab_config()] does not +** support constraints. In this configuration (which is the default) if +** a call to the [xUpdate] method returns [SQLITE_CONSTRAINT], then the entire +** statement is rolled back as if [ON CONFLICT | OR ABORT] had been +** specified as part of the users SQL statement, regardless of the actual +** ON CONFLICT mode specified. +** +** If X is non-zero, then the virtual table implementation guarantees +** that if [xUpdate] returns [SQLITE_CONSTRAINT], it will do so before +** any modifications to internal or persistent data structures have been made. +** If the [ON CONFLICT] mode is ABORT, FAIL, IGNORE or ROLLBACK, SQLite +** is able to roll back a statement or database transaction, and abandon +** or continue processing the current SQL statement as appropriate. +** If the ON CONFLICT mode is REPLACE and the [xUpdate] method returns +** [SQLITE_CONSTRAINT], SQLite handles this as if the ON CONFLICT mode +** had been ABORT. +** +** Virtual table implementations that are required to handle OR REPLACE +** must do so within the [xUpdate] method. If a call to the +** [sqlite3_vtab_on_conflict()] function indicates that the current ON +** CONFLICT policy is REPLACE, the virtual table implementation should +** silently replace the appropriate rows within the xUpdate callback and +** return SQLITE_OK. Or, if this is not possible, it may return +** SQLITE_CONSTRAINT, in which case SQLite falls back to OR ABORT +** constraint handling. +**
+*/ +#define SQLITE_VTAB_CONSTRAINT_SUPPORT 1 + +/* +** CAPI3REF: Determine The Virtual Table Conflict Policy +** +** This function may only be called from within a call to the [xUpdate] method +** of a [virtual table] implementation for an INSERT or UPDATE operation. ^The +** value returned is one of [SQLITE_ROLLBACK], [SQLITE_IGNORE], [SQLITE_FAIL], +** [SQLITE_ABORT], or [SQLITE_REPLACE], according to the [ON CONFLICT] mode +** of the SQL statement that triggered the call to the [xUpdate] method of the +** [virtual table]. +*/ +SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *); + +/* +** CAPI3REF: Conflict resolution modes +** +** These constants are returned by [sqlite3_vtab_on_conflict()] to +** inform a [virtual table] implementation what the [ON CONFLICT] mode +** is for the SQL statement being evaluated. +** +** Note that the [SQLITE_IGNORE] constant is also used as a potential +** return value from the [sqlite3_set_authorizer()] callback and that +** [SQLITE_ABORT] is also a [result code]. +*/ +#define SQLITE_ROLLBACK 1 +/* #define SQLITE_IGNORE 2 // Also used by sqlite3_authorizer() callback */ +#define SQLITE_FAIL 3 +/* #define SQLITE_ABORT 4 // Also an error code */ +#define SQLITE_REPLACE 5 + + + +/* +** Undo the hack that converts floating point types to integer for +** builds on processors without floating point support. +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# undef double +#endif + +#ifdef __cplusplus +} /* End of the 'extern "C"' block */ +#endif +#endif + +/* +** 2010 August 30 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +*/ + +#ifndef _SQLITE3RTREE_H_ +#define _SQLITE3RTREE_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry; + +/* +** Register a geometry callback named zGeom that can be used as part of an +** R-Tree geometry query as follows: +** +** SELECT ... FROM WHERE MATCH $zGeom(... params ...) +*/ +SQLITE_API int sqlite3_rtree_geometry_callback( + sqlite3 *db, + const char *zGeom, + int (*xGeom)(sqlite3_rtree_geometry *, int nCoord, double *aCoord, int *pRes), + void *pContext +); + + +/* +** A pointer to a structure of the following type is passed as the first +** argument to callbacks registered using rtree_geometry_callback(). +*/ +struct sqlite3_rtree_geometry { + void *pContext; /* Copy of pContext passed to s_r_g_c() */ + int nParam; /* Size of array aParam[] */ + double *aParam; /* Parameters passed to SQL geom function */ + void *pUser; /* Callback implementation user data */ + void (*xDelUser)(void *); /* Called by SQLite to clean up pUser */ +}; + + +#ifdef __cplusplus +} /* end of the 'extern "C"' block */ +#endif + +#endif /* ifndef _SQLITE3RTREE_H_ */ + diff --git a/scalos/include/zconf.h b/scalos/include/zconf.h new file mode 100644 index 000000000..b23438744 --- /dev/null +++ b/scalos/include/zconf.h @@ -0,0 +1,428 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2010 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". + */ +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ + +/* all linked symbols */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright +# define get_crc_table z_get_crc_table +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflush z_gzflush +# define gzgetc z_gzgetc +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# define gzprintf z_gzprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzwrite z_gzwrite +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetHeader z_inflateGetHeader +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# define uncompress z_uncompress +# define zError z_zError +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +# define Byte z_Byte +# define Bytef z_Bytef +# define alloc_func z_alloc_func +# define charf z_charf +# define free_func z_free_func +# define gzFile z_gzFile +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# define in_func z_in_func +# define intf z_intf +# define out_func z_out_func +# define uInt z_uInt +# define uIntf z_uIntf +# define uLong z_uLong +# define uLongf z_uLongf +# define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# define gz_header_s z_gz_header_s +# define internal_state z_internal_state + +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if 1 /* was set to #if 1 by ./configure */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef STDC +# include /* for off_t */ +#endif + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +# include /* for SEEK_* and off_t */ +# ifdef VMS +# include /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +#endif + +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define z_off64_t off64_t +#else +# define z_off64_t z_off_t +#endif + +#if defined(__OS400__) +# define NO_vsnprintf +#endif + +#if defined(__MVS__) +# define NO_vsnprintf +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) + #pragma map(deflateInit_,"DEIN") + #pragma map(deflateInit2_,"DEIN2") + #pragma map(deflateEnd,"DEEND") + #pragma map(deflateBound,"DEBND") + #pragma map(inflateInit_,"ININ") + #pragma map(inflateInit2_,"ININ2") + #pragma map(inflateEnd,"INEND") + #pragma map(inflateSync,"INSY") + #pragma map(inflateSetDictionary,"INSEDI") + #pragma map(compressBound,"CMBND") + #pragma map(inflate_table,"INTABL") + #pragma map(inflate_fast,"INFA") + #pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/scalos/include/zlib.h b/scalos/include/zlib.h new file mode 100644 index 000000000..bfbba83e8 --- /dev/null +++ b/scalos/include/zlib.h @@ -0,0 +1,1613 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.5, April 19th, 2010 + + Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.5" +#define ZLIB_VERNUM 0x1250 +#define ZLIB_VER_MAJOR 1 +#define ZLIB_VER_MINOR 2 +#define ZLIB_VER_REVISION 5 +#define ZLIB_VER_SUBREVISION 0 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. + + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip streams in memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this if + the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers + returned by zalloc for objects of exactly 65536 bytes *must* have their + offset normalized to zero. The default allocation function provided by this + library ensures this (see zutil.c). To reduce memory requirements and avoid + any allocation of 64K objects, at the expense of compression ratio, compile + the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use in the decompressor (particularly + if the decompressor wants to decompress everything in a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is not + compatible with the zlib.h header file used by the application. This check + is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to Z_NULL, deflateInit updates them to use default + allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level, or + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). msg is set to null + if there is no error message. deflateInit does not perform any compression: + this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). Some + output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumulate before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed code + block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the stream + are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least the + value returned by deflateBound (see below). If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect the + compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the + exact value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit() does not process any header information -- that is deferred + until inflate() is called. +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing will + resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all the uncompressed data. (The size + of the uncompressed data may have been saved by the compressor for this + purpose.) The next operation on this stream must be inflateEnd to deallocate + the decompression state. The use of Z_FINISH is never required, but can be + used to inform inflate that a faster approach may be used for the single + inflate() call. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the only effect of the flush parameter in this implementation + is on the return value of inflate(), as noted below, or when it returns early + because Z_BLOCK or Z_TREES is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the adler32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the adler32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained, so applications that need that information should + instead use raw inflate, see inflateInit2() below, or inflateBack() and + perform their own processing of the gzip header and trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by the + caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to 255 (unknown). If a + gzip stream is being written, strm->adler is a crc32 instead of an adler32. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid + method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is + incompatible with the version assumed by the caller (ZLIB_VERSION). msg is + set to null if there is no error message. deflateInit2 does not perform any + compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any call + of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size + provided in deflateInit or deflateInit2. Thus the strings most likely to be + useful should be put at the end of the dictionary, not at the front. In + addition, the current implementation of deflate will use at most the window + size minus 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + adler32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and can + consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. The + stream will keep the same compression level and any other attributes that + may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different strategy. + If the compression level is changed, the input available so far is + compressed with the old level (and may be flushed); the new level will take + effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to be + compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if + strm->avail_out was zero. +*/ + +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() or + deflateInit2(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). +*/ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the bits + leftover from a previous deflate stream when appending to it. As such, this + function can only be used for raw deflate, and must be used before the first + deflate() call after a deflateInit2() or deflateReset(). bits must be less + than or equal to 16, and that many of the least significant bits of value + will be inserted in the output. + + deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + crc32 instead of an adler32. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit2 does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit2() does not process any header information -- that is + deferred until inflate() is called. +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called + immediately after inflateInit2() or inflateReset() and before any call of + inflate() to set the dictionary. The application must insure that the + dictionary that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been + found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the + success case, the application may save the current current value of total_in + which indicates where valid compressed data was found. In the error case, + the application may repeatedly call inflateSync, providing more input each + time, until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. The + stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, + int windowBits)); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL), or if + the windowBits parameter is invalid. +*/ + +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above or -1 << 16 if the provided + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, + gz_headerp head)); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be + used to force inflate() to return immediately after header processing is + complete and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When any + of extra, name, or comment are not Z_NULL and the respective field is not + present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the paramaters are invalid, Z_MEM_ERROR if the internal state could not be + allocated, or Z_VERSION_ERROR if the version of the library does not match + the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is more efficient than inflate() for + file i/o applications in that it avoids copying between the output and the + sliding window by simply making the window itself the output buffer. This + function trusts the application to not change the output buffer passed by + the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free the + allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects only + the raw deflate stream to decompress. This is different from the normal + behavior of inflate(), which expects either a zlib or gzip header and + trailer around the deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero--buf is ignored in that + case--and inflateBack() will return a buffer error. inflateBack() will call + out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() + should return zero on success, or non-zero on failure. If out() returns + non-zero, inflateBack() will return with an error. Neither in() nor out() + are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format error + in the deflate stream (in which case strm->msg is set to indicate the nature + of the error), or Z_STREAM_ERROR if the stream was not properly initialized. + In the case of Z_BUF_ERROR, an input or output error can be distinguished + using strm->next_in which will be Z_NULL only if in() returned an error. If + strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning + non-zero. (in() will always be called before out(), so strm->next_in is + assured to be defined if out() returns non-zero.) Note that inflateBack() + cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the basic + stream-oriented functions. To simplify the interface, some default options + are assumed (compression level and memory usage, standard memory allocation + functions). The source code of these utility functions can be modified if + you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before a + compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, destLen + is the actual size of the uncompressed buffer. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. +*/ + + + /* gzip file access functions */ + +/* + This library supports reading and writing files in gzip (.gz) format with + an interface similar to that of stdio, using the functions that start with + "gz". The gzip format is different from the zlib format. gzip is a gzip + wrapper, documented in RFC 1952, wrapped around a deflate stream. +*/ + +typedef voidp gzFile; /* opaque gzip file descriptor */ + +/* +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); + + Opens a gzip (.gz) file for reading or writing. The mode parameter is as + in fopen ("rb" or "wb") but can also include a compression level ("wb9") or + a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only + compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' + for fixed code compression as in "wb9F". (See the description of + deflateInit2 for more information about the strategy parameter.) Also "a" + can be used instead of "w" to request that the gzip stream that will be + written be appended to the file. "+" will result in an error, since reading + and writing to the same gzip file is not supported. + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen associates a gzFile with the file descriptor fd. File descriptors + are obtained from calls like open, dup, creat, pipe or fileno (if the file + has been previously opened with fopen). The mode parameter is as in gzopen. + + The next call of gzclose on the returned gzFile will also close the file + descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor + fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); +/* + Set the internal buffer size used by this library's functions. The + default buffer size is 8192 bytes. This function must be called after + gzopen() or gzdopen(), and before any other calls that read or write the + file. The buffer memory allocation is always deferred to the first read or + write. Two buffers are allocated, either both of the specified size when + writing, or one of the specified size and the other twice that size when + reading. A larger buffer size of, for example, 64K or 128K bytes will + noticeably increase the speed of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. If + the input file was not in gzip format, gzread copies the given number of + bytes into the buffer. + + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream, or failing that, reading the rest + of the input file directly without decompression. The entire input file + will be read if gzread is called until it returns less than the requested + len. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -1 for error. +*/ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes written or 0 in case of + error. +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the arguments to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or 0 in case of error. The number of + uncompressed bytes written is limited to 8191, or one less than the buffer + size given to gzbuffer(). The caller should assure that this limit is not + exceeded. If it is exceeded, then gzprintf() will return an error (0) with + nothing written. In this case, there may also be a buffer overflow with + unpredictable consequences, which is possible only if zlib was compiled with + the insecure functions sprintf() or vsprintf() because the secure snprintf() + or vsnprintf() functions were not available. This can be determined using + zlibCompileFlags(). +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or a + newline character is read and transferred to buf, or an end-of-file + condition is encountered. If any characters are read or if len == 1, the + string is terminated with a null character. If no characters are read due + to an end-of-file or len < 1, then the buffer is left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. gzputc + returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte or -1 + in case of end of file or error. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read as the first character + on the next read. At least one character of push-back is allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + The pushed character will be discarded if the stream is repositioned with + gzseek() or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter flush + is as in the deflate() function. The return value is the zlib error number + (see function gzerror below). gzflush is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatented gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); + + Sets the starting position for the next gzread or gzwrite on the given + compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); + + Returns the starting position for the next gzread or gzwrite on the given + compressed file. This position represents a number of bytes in the + uncompressed data stream, and is zero when starting, even if appending or + reading a gzip stream from the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); + + Returns the current offset in the file being read or written. This offset + includes the count of bytes that precede the gzip stream, for example when + appending or when using gzdopen() for reading. When reading, the offset + does not include as yet unused buffered input. This information can be used + for a progress indicator. On error, gzoffset() returns -1. +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns true (1) if the end-of-file indicator has been set while reading, + false (0) otherwise. Note that the end-of-file indicator is set only if the + read tried to go past the end of the input, but came up short. Therefore, + just like feof(), gzeof() may return false even if there is no more data to + read, in the event that the last read request was for the exact number of + bytes remaining in the input file. This will happen if the input file size + is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. This state can change from + false to true while reading the input file if the end of a gzip stream is + reached, but is followed by data that is not another gzip stream. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file and + deallocates the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, or Z_OK on success. +*/ + +ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); +ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the given + compressed file. errnum is set to zlib error number. If an error occurred + in the file system and not in the compression library, errnum is set to + Z_ERRNO and the application may consult errno to get the exact error code. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the compression + library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is Z_NULL, this function returns the + required initial value for the checksum. + + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. + + Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +/* +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, + z_off_t len2)); + + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. If buf is Z_NULL, this function returns the required + initial value for the for the crc. Pre- and post-conditioning (one's + complement) is performed within this function so it shouldn't be done by the + application. + + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +/* +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); + + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, sizeof(z_stream)) + +/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or + * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if + * both are true, the application gets the *64 functions, and the regular + * functions are changed to 64 bits) -- in case these are set on systems + * without large file support, _LFS64_LARGEFILE must also be true + */ +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); +#endif + +#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0 +# define gzopen gzopen64 +# define gzseek gzseek64 +# define gztell gztell64 +# define gzoffset gzoffset64 +# define adler32_combine adler32_combine64 +# define crc32_combine crc32_combine64 +# ifdef _LARGEFILE64_SOURCE + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +# endif +#else + ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); +#endif + +/* hack for buggy compilers */ +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; +#endif + +/* undocumented functions */ +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); +ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/scalos/lgpl-3.0.txt b/scalos/lgpl-3.0.txt new file mode 100755 index 000000000..fc8a5de7e --- /dev/null +++ b/scalos/lgpl-3.0.txt @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/scalos/libraries/config.mk b/scalos/libraries/config.mk new file mode 100755 index 000000000..df98bbb93 --- /dev/null +++ b/scalos/libraries/config.mk @@ -0,0 +1,48 @@ +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += -nostartfiles \ + -lmempools \ +# --verbose + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += -nostartfiles + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +LFLAGS += -nostartfiles -lrom + +else + +############################################################################### +# AmigaOS + +LFLAGS += -liconobject -lstack -lnix -lnixmain -lamiga -lstubs + +endif +endif +endif diff --git a/scalos/libraries/iconobject/IconObject-aos4.c b/scalos/libraries/iconobject/IconObject-aos4.c new file mode 100644 index 000000000..223cd241b --- /dev/null +++ b/scalos/libraries/iconobject/IconObject-aos4.c @@ -0,0 +1,290 @@ +// IconObject-aos4.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include + +#include +#include + +#include + +#include "IconObject.h" + +int _start(void) +{ + return -1; +} + +static struct Library *Initlib(struct Library *libbase, BPTR seglist, struct ExecIFace *pIExec); +static BPTR Expungelib(struct LibraryManagerInterface *Self); +static struct LibraryHeader *Openlib(struct LibraryManagerInterface *Self, ULONG version); +static BPTR Closelib(struct LibraryManagerInterface *Self); +static ULONG Obtainlib(struct LibraryManagerInterface *Self); +static ULONG Releaselib(struct LibraryManagerInterface *Self); + +LIBFUNC_P2VA_PROTO(Object *, LIBNewIconObjectTags, + A0, APTR, Name, + A6, struct IconObjectBase *, IconObjectBase); +LIBFUNC_P2VA_PROTO(Object *, LIBGetDefIconObjectTags, + D0, ULONG, IconType, + A6, struct IconObjectBase *, IconObjectBase); +LIBFUNC_P3VA_PROTO(LONG, LIBPutIconObjectTags, + A0, Object *, iconobject, + A1, APTR, path, + A6, struct IconObjectBase *, IconObjectBase); +LIBFUNC_P2VA_PROTO(Object *, LIBConvert2IconObjectTags, + A0, struct DiskObject *, diskobject, + A6, struct IconObjectBase *, IconObjectBase); + +extern const CONST_APTR VecTable68K[]; + +/* OS4.0 Library */ + +/* ------------------- OS4 Manager Interface ------------------------ */ +static const APTR managerfunctable[] = +{ + (APTR)Obtainlib, + (APTR)Releaselib, + (APTR)NULL, + (APTR)NULL, + (APTR)Openlib, + (APTR)Closelib, + (APTR)Expungelib, + (APTR)NULL, + (APTR)-1 +}; + +static const struct TagItem managertags[] = +{ + {MIT_Name, (ULONG)"__library"}, + {MIT_VectorTable, (ULONG)managerfunctable}, + {MIT_Version, 1}, + {TAG_DONE, 0} +}; + +/* ---------------------- OS4 Main Interface ------------------------ */ +static APTR functable[] = + { + Obtainlib, + Releaselib, + NULL, + NULL, + LIBNewIconObject, + LIBNewIconObjectTags, + LIBDisposeIconObject, + LIBGetDefIconObject, + LIBGetDefIconObjectTags, + LIBPutIconObject, + LIBPutIconObjectTags, + LIBIsIconName, + LIBConvert2IconObject, + LIBConvert2IconObjectA, + LIBConvert2IconObjectTags, + (APTR) -1 + }; + +static const struct TagItem maintags[] = + { + {MIT_Name, (ULONG)"main"}, + {MIT_VectorTable, (ULONG)functable}, + {MIT_Version, 1}, + {TAG_DONE, 0} + }; + +/* Init table used in library initialization. */ +static const ULONG interfaces[] = +{ + (ULONG)managertags, + (ULONG)maintags, + (ULONG)0 +}; + +static const struct TagItem inittab[] = + { + {CLT_DataSize, (ULONG)sizeof(struct IconObjectBase)}, + {CLT_Interfaces, (ULONG) interfaces}, + {CLT_Vector68K, (ULONG)VecTable68K}, + {CLT_InitFunc, (ULONG) Initlib}, + {TAG_DONE, 0} + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, + RTF_NATIVE | RTF_AUTOINIT, + LIB_VERSION, + NT_LIBRARY, + 0, + libName, + libIdString, + (struct TagItem *)inittab + }; + +/* ------------------- OS4 Manager Functions ------------------------ */ +static struct Library * Initlib(struct Library *libbase, BPTR seglist, struct ExecIFace *pIExec) +{ + struct IconObjectBase *IconObjLibBase = (struct IconObjectBase *) libbase; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)libbase + libbase->lib_PosSize); + struct LibraryManagerInterface *Self = (struct LibraryManagerInterface *) ExtLib->ILibrary; + + SysBase = (struct ExecBase *)pIExec->Data.LibBase; + IExec = pIExec; + IconObjLibBase->iob_LibNode.lib_Revision = LIB_REVISION; + IconObjLibBase->iob_SegList = (struct SegList *)seglist; + + if (!IconObjectInit(IconObjLibBase)) + { + Expungelib(Self); + IconObjLibBase = NULL; + } + + return IconObjLibBase ? &IconObjLibBase->iob_LibNode : NULL; +} + +static BPTR Expungelib(struct LibraryManagerInterface *Self) +{ + struct IconObjectBase *IconObjLibBase = (struct IconObjectBase *) Self->Data.LibBase; + + if (0 == IconObjLibBase->iob_LibNode.lib_OpenCnt) + { + struct SegList *libseglist = IconObjLibBase->iob_SegList; + + Remove((struct Node *) IconObjLibBase); + IconObjectCleanup(IconObjLibBase); + DeleteLibrary((struct Library *)IconObjLibBase); + + return (BPTR)libseglist; + } + + IconObjLibBase->iob_LibNode.lib_Flags |= LIBF_DELEXP; + + return (BPTR)NULL; +} + +static struct LibraryHeader *Openlib(struct LibraryManagerInterface *Self, ULONG version) +{ + struct IconObjectBase *IconObjLibBase = (struct IconObjectBase *) Self->Data.LibBase; + + IconObjLibBase->iob_LibNode.lib_OpenCnt++; + IconObjLibBase->iob_LibNode.lib_Flags &= ~LIBF_DELEXP; + + if (!IconObjectOpen(IconObjLibBase)) + { + Closelib(Self); + return NULL; + } + + return (struct LibraryHeader *)&IconObjLibBase->iob_LibNode; +} + +static BPTR Closelib(struct LibraryManagerInterface *Self) +{ + struct IconObjectBase *IconObjLibBase = (struct IconObjectBase *) Self->Data.LibBase; + + IconObjLibBase->iob_LibNode.lib_OpenCnt--; +/* + if (0 == IconObjLibBase->iob_LibNode.lib_OpenCnt) + { + if (IconObjLibBase->iob_LibNode.lib_Flags & LIBF_DELEXP) + { + return Expungelib(Self); + } + } +*/ + return (BPTR)NULL; +} + +static ULONG Obtainlib(struct LibraryManagerInterface *Self) +{ + return(Self->Data.RefCount++); +} + +static ULONG Releaselib(struct LibraryManagerInterface *Self) +{ + return(Self->Data.RefCount--); +} + +/* ------------------- OS4 Varargs Functions ------------------------ */ +LIBFUNC_P2VA(Object *, LIBNewIconObjectTags, + A0, APTR, Name, + A6, struct IconObjectBase *, IconObjectBase) +{ + Object *ret; + va_list args; + va_startlinear(args, Name); + + (void)IconObjectBase; + + ret = ((struct IconobjectIFace *)self)->NewIconObject(Name, va_getlinearva(args, const struct TagItem *)); + + va_end(args); + + return(ret); +} +LIBFUNC_END + +LIBFUNC_P2VA(Object *, LIBGetDefIconObjectTags, + D0, ULONG, IconType, + A6, struct IconObjectBase *, IconObjectBase) +{ + Object *ret; + va_list args; + va_startlinear(args, IconType); + + (void)IconObjectBase; + + ret = ((struct IconobjectIFace *)self)->GetDefIconObject(IconType, va_getlinearva(args, const struct TagItem *)); + + va_end(args); + + return(ret); +} +LIBFUNC_END + +LIBFUNC_P3VA(LONG, LIBPutIconObjectTags, + A0, Object *, iconobject, + A1, APTR, path, + A6, struct IconObjectBase *, IconObjectBase) +{ + va_list args; + LONG ret; + va_startlinear(args, path); + + (void)IconObjectBase; + + ret = ((struct IconobjectIFace *)self)->PutIconObject(iconobject, path, va_getlinearva(args, const struct TagItem *)); + + va_end(args); + + return ret; +} +LIBFUNC_END + +LIBFUNC_P2VA(Object *, LIBConvert2IconObjectTags, + A0, struct DiskObject *, diskobject, + A6, struct IconObjectBase *, IconObjectBase) +{ + Object *ret; + va_list args; + va_startlinear(args, diskobject); + + (void)IconObjectBase; + + ret = ((struct IconobjectIFace *)self)->Convert2IconObjectA(diskobject, va_getlinearva(args, const struct TagItem *)); + + va_end(args); + + return(ret); +} +LIBFUNC_END + + diff --git a/scalos/libraries/iconobject/IconObject-aros.c b/scalos/libraries/iconobject/IconObject-aros.c new file mode 100644 index 000000000..cb57bdaeb --- /dev/null +++ b/scalos/libraries/iconobject/IconObject-aros.c @@ -0,0 +1,205 @@ +// IconObject-classic.c +// $Date$ +// $Revision$ + + +#include +#include + +#include + +#include + +#include +#include + + +#include "IconObject.h" + +//---------------------------------------------------------------------------- +// Standard library functions + +static AROS_UFP3 (struct Library *, Initlib, + AROS_UFPA(struct Library *, libbase, D0), + AROS_UFPA(struct SegList *, seglist, A0), + AROS_UFPA(struct ExecBase *, sysbase, A6) +); +static AROS_LD1 (struct Library *, Openlib, + AROS_LPA (__unused ULONG, version, D0), + struct Library *, base, 1, IconObject +); +static AROS_LD0 (struct SegList *, Closelib, + struct Library *, base, 2, IconObject +); +static AROS_LD1 (struct SegList *, Expungelib, + AROS_LPA(__unused struct Library *, __extrabase, D0), + struct Library *, base, 3, IconObject +); +static AROS_LD0 (ULONG, Extfunclib, + __unused struct Library *, libbase, 4, IconObject +); + +//---------------------------------------------------------------------------- + +SAVEDS(LONG) ASM Libstart(void) +{ + return -1; +} + +/* OS3.x Library */ + +static APTR functable[] = + { + IconObject_1_Openlib, + IconObject_2_Closelib, + IconObject_3_Expungelib, + IconObject_4_Extfunclib, + IconObjectBase_0_LIBNewIconObject, + IconObjectBase_0_LIBDisposeIconObject, + IconObjectBase_0_LIBGetDefIconObject, + IconObjectBase_0_LIBPutIconObject, + IconObjectBase_0_LIBIsIconName, + IconObjectBase_0_LIBConvert2IconObject, + IconObjectBase_0_LIBConvert2IconObjectA, + (APTR) -1 + }; + +/* Init table used in library initialization. */ +static ULONG inittab[] = + { + sizeof(struct IconObjectBase), + (ULONG) functable, + 0, + (ULONG) Initlib + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, + RTF_AUTOINIT, + LIB_VERSION, + NT_LIBRARY, + 0, + libName, + libIdString, + inittab + }; + + +//---------------------------------------------------------------------------- + +static AROS_UFH3(struct Library *, Initlib, + AROS_UFHA(struct Library *, libbase, D0), + AROS_UFHA(struct SegList *, seglist, A0), + AROS_UFHA(struct ExecBase *, sysbase, A6) +) +{ + AROS_USERFUNC_INIT + + struct IconObjectBase *IconObjLibBase = (struct IconObjectBase *) libbase; + + SysBase = sysbase; + IconObjLibBase->iob_LibNode.lib_Revision = LIB_REVISION; + IconObjLibBase->iob_SegList = seglist; + + if (!IconObjectInit(IconObjLibBase)) + { + IconObject_3_Expungelib(&IconObjLibBase->iob_LibNode, &IconObjLibBase->iob_LibNode); + IconObjLibBase = NULL; + } + + return IconObjLibBase ? &IconObjLibBase->iob_LibNode : NULL; + + AROS_USERFUNC_EXIT +} + +static AROS_LH1(struct Library *, Openlib, + AROS_LHA(__unused ULONG, version, D0), + struct Library *, libbase, 1, IconObject +) +{ + AROS_LIBFUNC_INIT + + struct IconObjectBase *IconObjLibBase = (struct IconObjectBase *) libbase; + + IconObjLibBase->iob_LibNode.lib_OpenCnt++; + IconObjLibBase->iob_LibNode.lib_Flags &= ~LIBF_DELEXP; + + if (!IconObjectOpen(IconObjLibBase)) + { + IconObject_2_Closelib(&IconObjLibBase->iob_LibNode); + return NULL; + } + + return &IconObjLibBase->iob_LibNode; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH0(struct SegList *, Closelib, + struct Library *, libbase, 2, IconObject +) +{ + AROS_LIBFUNC_INIT + + struct IconObjectBase *IconObjLibBase = (struct IconObjectBase *) libbase; + + IconObjLibBase->iob_LibNode.lib_OpenCnt--; + + if (0 == IconObjLibBase->iob_LibNode.lib_OpenCnt) + { + if (IconObjLibBase->iob_LibNode.lib_Flags & LIBF_DELEXP) + { + return IconObject_3_Expungelib(&IconObjLibBase->iob_LibNode, &IconObjLibBase->iob_LibNode); + } + } + + return NULL; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH1(struct SegList *, Expungelib, + AROS_LHA(__unused struct Library *, __extrabase, D0), + struct Library *, libbase, 3, IconObject +) +{ + AROS_LIBFUNC_INIT + + struct IconObjectBase *IconObjLibBase = (struct IconObjectBase *) libbase; + + if (0 == IconObjLibBase->iob_LibNode.lib_OpenCnt) + { + ULONG size = IconObjLibBase->iob_LibNode.lib_NegSize + IconObjLibBase->iob_LibNode.lib_PosSize; + UBYTE *ptr = (UBYTE *) IconObjLibBase - IconObjLibBase->iob_LibNode.lib_NegSize; + struct SegList *libseglist = IconObjLibBase->iob_SegList; + + Remove((struct Node *) IconObjLibBase); + IconObjectCleanup(IconObjLibBase); + FreeMem(ptr,size); + + return libseglist; + } + + IconObjLibBase->iob_LibNode.lib_Flags |= LIBF_DELEXP; + + return NULL; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH0(ULONG, Extfunclib, __unused struct Library *, libbase, 4, IconObject) +{ + AROS_LIBFUNC_INIT + + return 0; + + AROS_LIBFUNC_EXIT +} diff --git a/scalos/libraries/iconobject/IconObject-classic.c b/scalos/libraries/iconobject/IconObject-classic.c new file mode 100644 index 000000000..3d65b029d --- /dev/null +++ b/scalos/libraries/iconobject/IconObject-classic.c @@ -0,0 +1,179 @@ +// IconObject-classic.c +// $Date$ +// $Revision$ + + +#include +#include + +#include + +#include +#include + + +#include "IconObject.h" + +//---------------------------------------------------------------------------- +// Standard library functions + +static LIB_SAVEDS(struct Library *) LIB_ASM LIB_INTERRUPT Initlib(LIB_REG(d0, struct Library *libbase), + LIB_REG(a0, struct SegList *seglist), LIB_REG(a6, struct ExecBase *sysbase)); + +static LIBFUNC_PROTO(Openlib, libbase, struct Library *); +static LIBFUNC_PROTO(Closelib, libbase, struct SegList *); +static LIBFUNC_PROTO(Expungelib, libbase, struct SegList *); +static LIBFUNC_PROTO(Extfunclib, libbase, ULONG); + +//---------------------------------------------------------------------------- + +SAVEDS(LONG) ASM Libstart(void) +{ + return -1; +} + +/* OS3.x Library */ + +static APTR functable[] = + { +#ifdef __MORPHOS__ + (APTR) FUNCARRAY_32BIT_NATIVE, +#endif + Openlib, + Closelib, + Expungelib, + Extfunclib, + LIBNewIconObject, + LIBDisposeIconObject, + LIBGetDefIconObject, + LIBPutIconObject, + LIBIsIconName, + LIBConvert2IconObject, + LIBConvert2IconObjectA, + (APTR) -1 + }; + +/* Init table used in library initialization. */ +static ULONG inittab[] = + { + sizeof(struct IconObjectBase), + (ULONG) functable, + 0, + (ULONG) Initlib + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, +#ifdef __MORPHOS__ + RTF_PPC | RTF_AUTOINIT, +#else + RTF_AUTOINIT, +#endif + LIB_VERSION, + NT_LIBRARY, + 0, + libName, + libIdString, + inittab + }; + +#ifdef __MORPHOS__ +ULONG __abox__=1; +#endif + +//---------------------------------------------------------------------------- + +static LIB_SAVEDS(struct Library *) LIB_ASM LIB_INTERRUPT Initlib(LIB_REG(d0, struct Library *libbase), + LIB_REG(a0, struct SegList *seglist), LIB_REG(a6, struct ExecBase *sysbase)) +{ + struct IconObjectBase *IconObjLibBase = (struct IconObjectBase *) libbase; + + SysBase = sysbase; + IconObjLibBase->iob_LibNode.lib_Revision = LIB_REVISION; + IconObjLibBase->iob_SegList = seglist; + + if (!IconObjectInit(IconObjLibBase)) + { + CALLLIBFUNC(Expungelib, &IconObjLibBase->iob_LibNode); + IconObjLibBase = NULL; + } + + return IconObjLibBase ? &IconObjLibBase->iob_LibNode : NULL; +} + + +static LIBFUNC(Openlib, libbase, struct Library *) +{ + struct IconObjectBase *IconObjLibBase = (struct IconObjectBase *) libbase; + + IconObjLibBase->iob_LibNode.lib_OpenCnt++; + IconObjLibBase->iob_LibNode.lib_Flags &= ~LIBF_DELEXP; + + if (!IconObjectOpen(IconObjLibBase)) + { + CALLLIBFUNC(Closelib, &IconObjLibBase->iob_LibNode); + return NULL; + } + + return &IconObjLibBase->iob_LibNode; +} +LIBFUNC_END + + +static LIBFUNC(Closelib, libbase, struct SegList *) +{ + struct IconObjectBase *IconObjLibBase = (struct IconObjectBase *) libbase; + + IconObjLibBase->iob_LibNode.lib_OpenCnt--; + + if (0 == IconObjLibBase->iob_LibNode.lib_OpenCnt) + { + if (IconObjLibBase->iob_LibNode.lib_Flags & LIBF_DELEXP) + { + return CALLLIBFUNC(Expungelib, &IconObjLibBase->iob_LibNode); + } + } + + return NULL; +} +LIBFUNC_END + + +static LIBFUNC(Expungelib, libbase, struct SegList *) +{ + struct IconObjectBase *IconObjLibBase = (struct IconObjectBase *) libbase; + + if (0 == IconObjLibBase->iob_LibNode.lib_OpenCnt) + { + ULONG size = IconObjLibBase->iob_LibNode.lib_NegSize + IconObjLibBase->iob_LibNode.lib_PosSize; + UBYTE *ptr = (UBYTE *) IconObjLibBase - IconObjLibBase->iob_LibNode.lib_NegSize; + struct SegList *libseglist = IconObjLibBase->iob_SegList; + + Remove((struct Node *) IconObjLibBase); + IconObjectCleanup(IconObjLibBase); + FreeMem(ptr,size); + + return libseglist; + } + + IconObjLibBase->iob_LibNode.lib_Flags |= LIBF_DELEXP; + + return NULL; +} +LIBFUNC_END + + +static LIBFUNC(Extfunclib, libbase, ULONG) +{ + (void) libbase; + + return 0; +} +LIBFUNC_END + + diff --git a/scalos/libraries/iconobject/IconObject.c b/scalos/libraries/iconobject/IconObject.c new file mode 100644 index 000000000..70e17a291 --- /dev/null +++ b/scalos/libraries/iconobject/IconObject.c @@ -0,0 +1,760 @@ +// IconObject.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "iconobject_base.h" +#include "iconnode.h" +#include "IconObject.h" +#include +#include + + +#define DATATYPES_PATH "Scalos:IconDatatypes/" + + +//---------------------------------------------------------------------------- + +static struct IconNode *IconNode_New( CONST_STRPTR base_name, struct IconObjectBase *IconObjectBase ); +static VOID IconNode_Free( struct IconNode *node, struct IconObjectBase *IconObjectBase ); +static void AddDtLib( CONST_STRPTR LibFileName, struct IconObjectBase *IconObjectBase ); +static BOOL ReadClassList( struct IconObjectBase *IconObjectBase ); +static VOID FreeClassList( struct IconObjectBase *IconObjectBase ); +static APTR MyAllocVecPooled(size_t Size); +static void MyFreeVecPooled(APTR mem); + +static struct Iconobject *InternalConvert2IconObjectA( + struct DiskObject *diskobject, const struct TagItem *TagList, + struct IconObjectBase *IconObjectBase); + +//---------------------------------------------------------------------------- + +struct ExecBase *SysBase; +struct IntuitionBase *IntuitionBase; +T_UTILITYBASE UtilityBase; +struct DosLibrary * DOSBase; +#ifdef __amigaos4__ +struct Library *NewlibBase; +struct Interface *INewlib; +struct ExecIFace *IExec; +struct IntuitionIFace *IIntuition; +struct UtilityIFace *IUtility; +struct DOSIFace *IDOS; +#endif + +static void *MemPool; +static struct SignalSemaphore PubMemPoolSemaphore; + +//---------------------------------------------------------------------------- + +char ALIGNED libName[] = "iconobject.library"; +char ALIGNED libIdString[] = "$VER: iconobject.library " + STR(LIB_VERSION) "." STR(LIB_REVISION) " " __DATE__ " " + COMPILER_STRING + " ©1999" CURRENTYEAR " The Scalos Team"; + +//---------------------------------------------------------------------------- + +BOOL IconObjectInit(struct IconObjectBase *IconObjectBase) +{ + /* store pointer to execbase for global access */ + + d1(kprintf(__FILE__ "/%s/%ld: IconObjectBase=%08lx procName=<%s>\n", __FUNC__ , __LINE__, \ + IconObjectBase, FindTask(NULL)->tc_Node.ln_Name)); + + InitSemaphore(&PubMemPoolSemaphore); + InitSemaphore(&IconObjectBase->iob_Semaphore); + NewList(&IconObjectBase->iob_ClassList); + + DOSBase = (APTR) OpenLibrary( "dos.library", 39 ); + IntuitionBase = (APTR) OpenLibrary( "intuition.library", 39 ); + UtilityBase = (APTR) OpenLibrary( "utility.library", 39 ); +#ifdef __amigaos4__ + if (DOSBase) + { + IDOS = (struct DOSIFace *)GetInterface((struct Library *)DOSBase, "main", 1, NULL); + if (!IDOS) + { + CloseLibrary((struct Library *)DOSBase); + DOSBase = NULL; + } + } + if (IntuitionBase) + { + IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (!IIntuition) + { + CloseLibrary((struct Library *)IIntuition); + IntuitionBase = NULL; + } + } + if (UtilityBase) + { + IUtility = (struct UtilityIFace *)GetInterface(UtilityBase, "main", 1, NULL); + if (!IUtility) + { + CloseLibrary((struct Library *)UtilityBase); + UtilityBase = NULL; + } + } + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + return 0; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + return 0; +#endif /* __amigaos4__ */ + + MemPool = CreatePool(MEMPOOL_MEMFLAGS, MEMPOOL_PUDDLESIZE, MEMPOOL_THRESHSIZE); + d1(kprintf("%s/%s/%ld: MemPool=%08lx\n", __FILE__, __FUNC__, __LINE__, MemPool)); + if (NULL == MemPool) + return 0; + + if (DOSBase && + IntuitionBase && + UtilityBase) + { + d1(kprintf("%s/%ld: Success\n", __FUNC__, __LINE__)); + return TRUE; // Success + } + + d1(kprintf("%s/%ld: Fail\n", __FUNC__, __LINE__)); + +// IconObjectCleanup(IconObjectBase); + + return FALSE; // Failure +} + +//----------------------------------------------------------------------------- + +BOOL IconObjectOpen(struct IconObjectBase *IconObjectBase) +{ + d1(kprintf(__FILE__ "/%s/%ld: IconObjectBase=%08lx procName=<%s>\n", __FUNC__ , __LINE__, \ + IconObjectBase, FindTask(NULL)->tc_Node.ln_Name)); + + if (0 == IconObjectBase->iob_dtPathLock) + { + IconObjectBase->iob_dtPathLock = Lock(DATATYPES_PATH, ACCESS_READ); + if (0 == IconObjectBase->iob_dtPathLock) + { + d1(kprintf(__FILE__ "/%s/%ld: Lock(%s) Failed\n", __FUNC__, __LINE__, DATATYPES_PATH)); + return FALSE; // Fail + } + + if (!AssignAdd("LIBS", IconObjectBase->iob_dtPathLock)) + { + d1(kprintf(__FILE__ "/%s/%ld: AssignAdd Failed, IoErr=%ld\n", __FUNC__, __LINE__, IoErr())); + return FALSE; // Fail + } + } + + if (IsListEmpty(&IconObjectBase->iob_ClassList)) + { + if (ReadClassList(IconObjectBase)) + { + d1(kprintf(__FILE__ "/%s/%ld: Success\n", __FUNC__, __LINE__)); + return TRUE; // Success + } + else + { + d1(kprintf(__FILE__ "/%s/%ld: Fail\n", __FUNC__, __LINE__)); + return FALSE; // Fail + } + } + + d1(kprintf(__FILE__ "/%s/%ld: Success\n", __FUNC__, __LINE__)); + + return TRUE; // Success +} + +//----------------------------------------------------------------------------- + +void IconObjectCleanup(struct IconObjectBase *IconObjectBase) +{ + d1(kprintf("%s/%ld:\n", __FUNC__, __LINE__)); + + FreeClassList(IconObjectBase); + + if (IconObjectBase->iob_dtPathLock) + { + RemAssignList("LIBS", IconObjectBase->iob_dtPathLock); + IconObjectBase->iob_dtPathLock = 0; + } +#ifdef __amigaos4__ + if (INewlib) + { + DropInterface(INewlib); + INewlib = NULL; + } + if (NewlibBase) + { + CloseLibrary(NewlibBase); + NewlibBase = NULL; + } +#endif /* __amigaos4__ */ + if (UtilityBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)IUtility); +#endif /* __amigaos4__ */ + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } + if (IntuitionBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)IIntuition); +#endif /* __amigaos4__ */ + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } + if (DOSBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)IDOS); +#endif /* __amigaos4__ */ + CloseLibrary((struct Library *) DOSBase); + DOSBase = NULL; + } + if (NULL != MemPool) + { + DeletePool(MemPool); + MemPool = NULL; + } + d1(kprintf("%s/%ld: Done!\n", __FUNC__, __LINE__)); +} + +//----------------------------------------------------------------------------- + +/* + * IconNode_New() + * + * PURPOSE: Constructor + * INPUTS: base_name - base name of this iconobject datatype + * RESULT: + */ +static struct IconNode *IconNode_New( CONST_STRPTR base_name, struct IconObjectBase *IconObjectBase) +{ +#define dt_path DATATYPES_PATH "datatypes/" +#define dt_suffix "" +#define DT_NAME_LEN ( sizeof(dt_path) + sizeof(dt_suffix) ) +#define icon_suffix ".info" +#define ICON_SUFFIX_LEN ( sizeof(icon_suffix) ) + + struct IconNode *node; + + d1(kprintf(__FILE__ "/%s/%ld: name=<%s>\n", + __FUNC__, __LINE__, base_name)); + + if( node = (struct IconNode *) MyAllocVecPooled(sizeof(struct IconNode))) + { + STRPTR name; + + memset(node, 0, sizeof(struct IconNode)); + + /* make some space for the datatype library's pathname */ + if( node->Node.ln_Name = name = MyAllocVecPooled(DT_NAME_LEN + strlen( base_name )) ) + { + /* make datatype's pathname from descriptor's basename */ + /* name = 'datatypes/' + base_name + '.datatype */ + strcpy( name, dt_path ); + strcat( name, base_name ); + strcat( name, dt_suffix ); + + /* get suffix for icon filename */ + /* Stefan's code extracted this from the DT descriptor's match pattern */ + + /* It seems unnecessary, so I've hard-wired this for now - with a view to removing it */ + node->in_Suffix = (STRPTR) icon_suffix; + node->in_SuffixLen = strlen(node->in_Suffix); + + d1(kprintf("%s/%ld: node=%08lx\n", __FUNC__, __LINE__, node)); + } + else + { + /* allocation failed - cleanup */ + d1(kprintf("%s/%ld:\n", __FUNC__, __LINE__)); + MyFreeVecPooled(node); + node = NULL; + } + } + + return node; +} + +//----------------------------------------------------------------------------- + +/* + * IconNode_Free() + * + */ + +static VOID IconNode_Free( struct IconNode *node, struct IconObjectBase *IconObjectBase ) +{ + d1(kprintf(__FILE__ "/%s/%ld: node=%08lx\n", __FUNC__, __LINE__, node)); + if(node) + { + if (node->in_LibBase) + { + CloseLibrary(node->in_LibBase); + node->in_LibBase = NULL; + } + if ( node->Node.ln_Name ) + { + MyFreeVecPooled(node->Node.ln_Name); + node->Node.ln_Name = NULL; + } + MyFreeVecPooled(node); + } +} + +//----------------------------------------------------------------------------- + +static void AddDtLib( CONST_STRPTR LibFileName, struct IconObjectBase *IconObjectBase ) +{ + struct IconNode *node; + BOOL Success = FALSE; + + do { + struct Library *DTClassBase; +#ifdef __amigaos4__ + struct DTClassIFace *IDTClass; +#endif /* __amigaos4__ */ + + node = IconNode_New( LibFileName, IconObjectBase); + if (NULL == node) + break; + + d1(kprintf("%s/%ld: node=%08lx LibFileName=<%s>\n", __FUNC__, __LINE__, \ + node, LibFileName)); + + d1(kprintf("%s/%ld: name=<%s>\n", __FUNC__, __LINE__, node->Node.ln_Name)); + + node->in_LibBase = DTClassBase = OpenLibrary( node->Node.ln_Name, 0L ); + d1(kprintf("%s/%ld: in_LibBase=%08lx\n", __FUNC__, __LINE__, node->in_LibBase)); + if (NULL == node->in_LibBase) + break; + + if (SCHAR_MIN == node->in_LibBase->lib_Node.ln_Pri) + break; +#ifdef __amigaos4__ + node->in_IFace = IDTClass = (struct DTClassIFace *)GetInterface(DTClassBase, "main", 1, NULL); + d1(kprintf("%s/%ld: in_IFace=%08lx\n", __FUNC__, __LINE__, node->in_IFace)); + if (NULL == node->in_IFace) + break; +#endif /* __amigaos4__ */ + + d1(kprintf("%s/%ld: OpenLib(%s) OK\n", __FUNC__, __LINE__, LibFileName)); + d1(kprintf("%s/%ld: lib_IdString=<%s> ln_Pri=%ld\n", __FUNC__, __LINE__, node->in_LibBase->lib_IdString, node->in_LibBase->lib_Node.ln_Pri)); + +#ifdef __AROS__ + node->in_Class = AROS_LVO_CALL0(Class *, struct Library *, DTClassBase, 5,); +#else + node->in_Class = ObtainEngine(); +#endif + d1(kprintf("%s/%ld: in_Class=%08lx\n", __FUNC__, __LINE__, node->in_Class)); + if (NULL == node->in_Class) + break; + + node->Node.ln_Pri = node->in_LibBase->lib_Node.ln_Pri; + + d1(kprintf("%s/%ld: Class=%08lx SysBase=%08lx\n", __FUNC__, __LINE__, node->in_Class, SysBase)); + + Enqueue(&IconObjectBase->iob_ClassList, (struct Node *) node ); + + d1(kprintf("%s/%ld: Success, after Enqueue\n", __FUNC__, __LINE__)); + Success = TRUE; + } while (0); + + + if (!Success) + { + d1(kprintf("%s/%ld: OpenLib(%s) FAIL\n", __FUNC__, __LINE__, LibFileName)); + IconNode_Free(node, IconObjectBase); + } +} + +//----------------------------------------------------------------------------- + +/* + * ReadClassList() + * + */ + +static BOOL ReadClassList( struct IconObjectBase *IconObjectBase ) +{ + BOOL success = FALSE; + struct List *list = &IconObjectBase->iob_ClassList; + BPTR lock; + + NewList(list); + + d1(kprintf(__FILE__ "/%s/%ld: START\n", __FUNC__, __LINE__)); + + if( lock = Lock( DATATYPES_PATH "datatypes", SHARED_LOCK ) ) + { + BPTR olddir = CurrentDir( lock ); + struct FileInfoBlock *fib; + + d1(kprintf(__FILE__ "/%s/%ld: Lock(%s) OK\n", __FUNC__, __LINE__, DATATYPES_PATH)); + + if( fib = (struct FileInfoBlock *) AllocDosObject( DOS_FIB, TAG_DONE ) ) + { + if( Examine( lock, fib ) ) + { + while( ExNext( lock, fib ) ) + { + d1(kprintf(__FILE__ "/%s/%ld: found <%s>\n", __FUNC__, __LINE__, fib->fib_FileName)); + + AddDtLib( fib->fib_FileName, IconObjectBase ); + } + if( IoErr() == ERROR_NO_MORE_ENTRIES ) + success = TRUE; + } + FreeDosObject( DOS_FIB, fib ); + } + CurrentDir( olddir ); + + UnLock( lock ); + } + else + { + d1(kprintf("%s/%ld: Failed to Lock(%s), IoErr=%ld\n", __FUNC__, __LINE__, DATATYPES_PATH "datatypes", IoErr())); + } + + d1(kprintf("%s/%ld: success=%ld\n", __FUNC__, __LINE__, success)); + + return success; +} + +//----------------------------------------------------------------------------- + +/* + * FreeClassList() + * + */ + +static VOID FreeClassList( struct IconObjectBase *IconObjectBase ) +{ + struct IconNode *n1; + + d1(kprintf(__FILE__ "/%s/%ld:\n", __FUNC__, __LINE__)); + + while (n1 = (struct IconNode *) RemHead(&IconObjectBase->iob_ClassList)) + { + if ( n1->in_LibBase ) + { + //RemLibrary( n1->in_LibBase ); +#ifdef __amigaos4__ + DropInterface((struct Interface *)n1->in_IFace); +#endif /* __amigaos4__ */ + CloseLibrary( n1->in_LibBase ); + } + IconNode_Free(n1, IconObjectBase ); + } +} + +//----------------------------------------------------------------------------- + +// NewIconObject() +LIBFUNC_P3(struct Iconobject *, LIBNewIconObject, + A0, APTR, Name, + A1, CONST struct TagItem *, Taglist, + A6, struct IconObjectBase *, IconObjectBase) +{ + struct Iconobject *obj = NULL; + BPTR IconFh = (BPTR) NULL; + + d1(kprintf(__FILE__ "/%s/%ld: Name=<%s>\n", __FUNC__, __LINE__, Name)); + + if (Name) + { + STRPTR IconName; + + IconName = MyAllocVecPooled(strlen(Name) + 1 + 5); // allocate space for Name and ".info" + if (IconName) + { + strcpy(IconName, Name); + strcat(IconName, ".info"); + + IconFh = Open(IconName, MODE_OLDFILE); + MyFreeVecPooled(IconName); + } + } + + d1(KPrintF("%s/%s/%ld: IconFh=%08lx\n", __FILE__, __FUNC__, __LINE__, IconFh)); + + if (IconFh) + { + struct IconNode *in; + + SetVBuf(IconFh, NULL, BUF_FULL, 16384); + + for (in = (struct IconNode *) IconObjectBase->iob_ClassList.lh_Head; + NULL == obj && in != (struct IconNode *) &IconObjectBase->iob_ClassList.lh_Tail; + in = (struct IconNode *) in->Node.ln_Succ) + { + d1(KPrintF("%s/%ld: datatype=<%s> class=%08lx ln_name=<%s>\n", \ + __FUNC__, __LINE__, in->Node.ln_Name, in->in_Class, in->Node.ln_Name)); + + // Make sure each datatype starts with 0 file offset + Seek(IconFh, 0, OFFSET_BEGINNING); + + obj = (struct Iconobject *) NewObject(in->in_Class, NULL, + DTA_Name, (ULONG) Name, + DTA_Handle, (ULONG) IconFh, + TAG_MORE, (ULONG) Taglist, + TAG_END); + + d1(kprintf("%s/%ld: datatype=<%s> obj=%08lx ln_name=<%s>\n", \ + __FUNC__, __LINE__, in->Node.ln_Name, obj, in->Node.ln_Name)); + } + + Close(IconFh); + } + + d1(kprintf("%s/%ld: obj=%08lx\n", __FUNC__, __LINE__, obj)); + + return obj; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +// DisposeIconObject() +LIBFUNC_P2(void, LIBDisposeIconObject, + A0, struct Iconobject *, iconobject, + A6, struct IconObjectBase *, IconObjectBase) +{ + d1(kprintf(__FILE__ "/%s/%ld: iconobject=%08lx\n", __FUNC__ , __LINE__, iconobject)); + (void) IconObjectBase; + + DisposeObject((Object *) iconobject); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +// GetDefIconObject() +LIBFUNC_P3(struct Iconobject *, LIBGetDefIconObject, + D0, ULONG, IconType, + A0, CONST struct TagItem *, TagList, + A6, struct IconObjectBase *, IconObjectBase) +{ + struct IconNode *in; + struct Iconobject *obj = NULL; + + (void) IconObjectBase; + + d1(kprintf(__FILE__ "/%s/%ld: type=%08lx\n", __FUNC__, __LINE__, IconType)); + + for (in = (struct IconNode *) IconObjectBase->iob_ClassList.lh_Head; + NULL == obj && in != (struct IconNode *) &IconObjectBase->iob_ClassList.lh_Tail; + in = (struct IconNode *) in->Node.ln_Succ) + { + obj = (struct Iconobject *) NewObject(in->in_Class, NULL, + IDTA_DefType, IconType, + DTA_Name, (ULONG) GetTagData(DTA_Name, (ULONG) "", TagList), + TAG_MORE, (ULONG) TagList, + TAG_END); + + d1(kprintf("%s/%ld: obj=%08lx ln_name=<%s>\n", __FUNC__, __LINE__, obj, in->Node.ln_Name)); + } + + d1(kprintf("%s/%ld: obj=%08lx\n", __FUNC__, __LINE__, obj)); + + return obj; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +// PutIconObject() +LIBFUNC_P4(LONG, LIBPutIconObject, + A0, struct Iconobject *, iconobject, + A1, APTR, path, + A2, CONST struct TagItem *, TagList, + A6, struct IconObjectBase *, IconObjectBase) +{ + d1(kprintf(__FILE__ "/%s/%ld: obj=%08lx\n", __FUNC__, __LINE__, iconobject)); + + (void) IconObjectBase; + + return (LONG) DoMethod((Object *) iconobject, IDTM_Write, path, NULL, TagList); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +// Input: A0 = Filename +// Output: D0 = address of extension ( or NULL or -1 ) +// IsIconName() +LIBFUNC_P2(ULONG, LIBIsIconName, + A0, const char *, filename, + A6, struct IconObjectBase *, IconObjectBase); +{ + struct IconNode *in; + + d1(kprintf(__FILE__ "/%s/%ld: name=<%s>\n", __FUNC__, __LINE__, filename)); + + filename += strlen(filename); + + for (in = (struct IconNode *) IconObjectBase->iob_ClassList.lh_Head; + in != (struct IconNode *) &IconObjectBase->iob_ClassList.lh_Tail; + in = (struct IconNode *) in->Node.ln_Succ) + { + d1(kprintf("%s/%ld: Suffix=<%s> Len=%ld\n", __FUNC__, __LINE__, in->in_Suffix, in->in_SuffixLen)); + + if (0 == in->in_SuffixLen) + { + d1(kprintf("%s/%ld: Found (1)\n", __FUNC__, __LINE__)); + return -1; // Found + } + if (0 == Stricmp(in->in_Suffix, filename - in->in_SuffixLen)) + { + d1(kprintf("%s/%ld: Found (2)\n", __FUNC__, __LINE__)); + return (ULONG) (filename - in->in_SuffixLen); + } + } + + d1(kprintf("%s/%ld: Not Found\n", __FUNC__, __LINE__)); + + return 0; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +// Convert2IconObjectA() +LIBFUNC_P3(struct Iconobject *, LIBConvert2IconObjectA, + A0, struct DiskObject *, diskobject, + A1, const struct TagItem *, TagList, + A6, struct IconObjectBase *, IconObjectBase) +{ + return InternalConvert2IconObjectA(diskobject, TagList, IconObjectBase); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +// Convert2IconObject() +LIBFUNC_P2(struct Iconobject *, LIBConvert2IconObject, + A0, struct DiskObject *, diskobject, + A6, struct IconObjectBase *, IconObjectBase) +{ + return InternalConvert2IconObjectA(diskobject, NULL, IconObjectBase); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +static struct Iconobject *InternalConvert2IconObjectA( + struct DiskObject *diskobject, const struct TagItem *TagList, + struct IconObjectBase *IconObjectBase) +{ + struct IconNode *in; + struct Iconobject *obj = NULL; + + d1(kprintf(__FILE__ "/%s/%ld: diskobj=%08lx\n", __FUNC__, __LINE__, diskobject)); + + for (in = (struct IconNode *) IconObjectBase->iob_ClassList.lh_Head; + NULL == obj && in != (struct IconNode *) &IconObjectBase->iob_ClassList.lh_Tail; + in = (struct IconNode *) in->Node.ln_Succ) + { + obj = (struct Iconobject *) NewObject(in->in_Class, NULL, + AIDTA_Icon, (ULONG) diskobject, + DTA_Name, (ULONG) "", + TAG_MORE, (ULONG) TagList, + TAG_END); + + d1(kprintf("%s/%ld: obj=%08lx ln_name=<%s>\n", __FUNC__, __LINE__, obj, in->Node.ln_Name)); + } + + return obj; +} + +//---------------------------------------------------------------------------------------- + +static APTR MyAllocVecPooled(size_t Size) +{ + APTR ptr; + + if (MemPool) + { + ObtainSemaphore(&PubMemPoolSemaphore); + ptr = AllocPooled(MemPool, Size + sizeof(size_t)); + ReleaseSemaphore(&PubMemPoolSemaphore); + if (ptr) + { + size_t *sptr = (size_t *) ptr; + + sptr[0] = Size; + + d1(kprintf("%s/%s/%ld: MemPool=%08lx Size=%lu mem=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, MemPool, Size, &sptr[1])); + return (APTR)(&sptr[1]); + } + } + + d1(kprintf("%s/%s/%ld: MemPool=%08lx Size=%lu\n", __FILE__, __FUNC__, __LINE__, MemPool, Size)); + + return NULL; +} + + +static void MyFreeVecPooled(APTR mem) +{ + d1(kprintf("%s/%s/%ld: MemPool=%08lx mem=%08lx\n", __FILE__, __FUNC__, __LINE__, MemPool, mem)); + if (MemPool && mem) + { + size_t size; + size_t *sptr = (size_t *) mem; + + mem = &sptr[-1]; + size = sptr[-1]; + + ObtainSemaphore(&PubMemPoolSemaphore); + FreePooled(MemPool, mem, size + sizeof(size_t)); + ReleaseSemaphore(&PubMemPoolSemaphore); + } +} + +//---------------------------------------------------------------------------------------- + +#if !defined(__SASC) && !defined(__amigaos4__) +void exit(int x) +{ + (void) x; + while (1) + ; +} + +#endif /* !defined(__SASC) */ + +//----------------------------------------------------------------------------- + diff --git a/scalos/libraries/iconobject/IconObject.h b/scalos/libraries/iconobject/IconObject.h new file mode 100644 index 000000000..d9e979eef --- /dev/null +++ b/scalos/libraries/iconobject/IconObject.h @@ -0,0 +1,93 @@ +// IconObject.h +// $Date$ +// $Revision$ +//---------------------------------------------------------------------------- + +#ifndef ICONOBJ_H +#define ICONOBJ_H + +#include +#include +#include + +#include "iconobject_base.h" +#include "iconnode.h" + +#include + +//---------------------------------------------------------------------------- + +extern struct ExecBase *SysBase; +extern struct IntuitionBase *IntuitionBase; +extern T_UTILITYBASE UtilityBase; +extern struct DosLibrary * DOSBase; + +//---------------------------------------------------------------------------- + +#define LIB_VERSION 40 +#define LIB_REVISION 8 + +extern char ALIGNED libName[]; +extern char ALIGNED libIdString[]; + +//----------------------------------------------------------------------------- + +#define MEMPOOL_MEMFLAGS MEMF_PUBLIC +#define MEMPOOL_PUDDLESIZE 8192 +#define MEMPOOL_THRESHSIZE 8192 + +//----------------------------------------------------------------------------- + +BOOL IconObjectInit(struct IconObjectBase *IconObjectBase); +BOOL IconObjectOpen(struct IconObjectBase *IconObjectBase); +void IconObjectCleanup(struct IconObjectBase *IconObjectBase); + +LIBFUNC_P3_PROTO(struct Iconobject *, LIBNewIconObject, + A0, APTR, Name, + A1, CONST struct TagItem *, Taglist, + A6, struct IconObjectBase *, IconObjectBase); +LIBFUNC_P2_PROTO(void, LIBDisposeIconObject, + A0, struct Iconobject *, iconobject, + A6, struct IconObjectBase *, IconObjectBase); +LIBFUNC_P3_PROTO(struct Iconobject *, LIBGetDefIconObject, + D0, ULONG, IconType, + A0, CONST struct TagItem *, TagList, + A6, struct IconObjectBase *, IconObjectBase); +LIBFUNC_P4_PROTO(LONG, LIBPutIconObject, + A0, struct Iconobject *, iconobject, + A1, APTR, path, + A2, CONST struct TagItem *, TagList, + A6, struct IconObjectBase *, IconObjectBase); +LIBFUNC_P2_PROTO(ULONG, LIBIsIconName, + A0, const char *, filename, + A6, struct IconObjectBase *, IconObjectBase); +LIBFUNC_P3_PROTO(struct Iconobject *, LIBConvert2IconObjectA, + A0, struct DiskObject *, diskobject, + A1, const struct TagItem *, TagList, + A6, struct IconObjectBase *, IconObjectBase); +LIBFUNC_P2_PROTO(struct Iconobject *, LIBConvert2IconObject, + A0, struct DiskObject *, diskobject, + A6, struct IconObjectBase *, IconObjectBase); + +//---------------------------------------------------------------------------- + +// Debugging... +#define d(x) ; +#define d1(x) ; +#define d2(x) x; + + +// aus debug.lib +#ifdef __AROS__ +#include +#define KPrintF kprintf +#else +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); +#endif + +//---------------------------------------------------------------------------- + +#endif /* ICONOBJ_H */ + + diff --git a/scalos/libraries/iconobject/config.mk b/scalos/libraries/iconobject/config.mk new file mode 100755 index 000000000..cc2a14757 --- /dev/null +++ b/scalos/libraries/iconobject/config.mk @@ -0,0 +1,49 @@ +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += -nostartfiles \ + -lmempools \ +# --verbose + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += -nostartfiles + +else + +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +LFLAGS += -nostartfiles -larossupport + +else + +############################################################################### +# AmigaOS + +LFLAGS += -liconobject -lstack -lnix -lnixmain -lamiga -lstubs + +endif +endif +endif diff --git a/scalos/libraries/iconobject/iconnode.h b/scalos/libraries/iconobject/iconnode.h new file mode 100644 index 000000000..e10b008ec --- /dev/null +++ b/scalos/libraries/iconobject/iconnode.h @@ -0,0 +1,53 @@ +/* + * Scalos/iconnode.h + * iconnode.h + * + * $Date$ + * $Revision$ + * + * Richard Drummond + * + * Module to handle nodes in library's internal + * list of iconobject datatypes + * + */ + +#ifndef ICONNODE_H +#define ICONNODE_H + +#ifndef EXEC_TYPES_H +#include +#endif + +#ifndef EXEC_NODES_H +#include +#endif + +#ifndef INTUITION_CLASSES_H +#include +#endif + +#ifndef EXEC_LIBRARIES_H +#include +#endif + +/* + * iconobject.library maintains a list of all iconobject datatypes. + * Each member has the following structure. + */ + +struct IconNode +{ + struct Node Node; + + Class *in_Class; /* Pointer to the datatype's BOOPSI class */ + struct Library *in_LibBase; /* Pointer to the datatype's library */ +#ifdef __amigaos4__ + struct DTClassIFace *in_IFace; /* Pointer to the datatype's interface */ +#endif + CONST_STRPTR in_Suffix; /* Filename suffix for icon file's of this type */ + WORD in_SuffixLen; /* Length of the above */ +}; + +#endif + diff --git a/scalos/libraries/iconobject/iconobject-aos4-68kstubs.c b/scalos/libraries/iconobject/iconobject-aos4-68kstubs.c new file mode 100644 index 000000000..56d5500ae --- /dev/null +++ b/scalos/libraries/iconobject/iconobject-aos4-68kstubs.c @@ -0,0 +1,161 @@ +/* +** This file was automatically generated by fdtrans 52.1. +** Do not edit it by hand. Instead, edit the sfd file +** that was used to generate this file +*/ + +#ifdef __USE_INLINE__ +#undef __USE_INLINE__ +#endif +#ifndef __NOGLOBALIFACE__ +#define __NOGLOBALIFACE__ +#endif + +#include +#include +#include +#include +#include +#include + + +static inline int8 convert_int8 (uint32 x) { return x; } +static inline int16 convert_int16(uint32 x) { return x; } + + +STATIC struct Library * stub_OpenPPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct LibraryManagerInterface *Self = (struct LibraryManagerInterface *) ExtLib->ILibrary; + + return Self->Open(0); +} +STATIC CONST struct EmuTrap stub_Open = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_OpenPPC }; + +STATIC APTR stub_ClosePPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct LibraryManagerInterface *Self = (struct LibraryManagerInterface *) ExtLib->ILibrary; + + return Self->Close(); +} +STATIC CONST struct EmuTrap stub_Close = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_ClosePPC }; + +STATIC APTR stub_ExpungePPC(ULONG *regarray __attribute__((unused))) +{ + return NULL; +} +STATIC CONST struct EmuTrap stub_Expunge = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_ExpungePPC }; + +STATIC ULONG stub_ReservedPPC(ULONG *regarray __attribute__((unused))) +{ + return 0UL; +} +STATIC CONST struct EmuTrap stub_Reserved = { TRAPINST, TRAPTYPE, stub_ReservedPPC }; + +static Object * stub_NewIconObjectPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct IconobjectIFace *Self = (struct IconobjectIFace *) ExtLib->MainIFace; + + return Self->NewIconObject( + (CONST_STRPTR)regarray[8], + (CONST struct TagItem *)regarray[9] + ); +} +STATIC CONST struct EmuTrap stub_NewIconObject = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_NewIconObjectPPC }; + +static VOID stub_DisposeIconObjectPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct IconobjectIFace *Self = (struct IconobjectIFace *) ExtLib->MainIFace; + + Self->DisposeIconObject( + (Object *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_DisposeIconObject = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_DisposeIconObjectPPC }; + +static Object * stub_GetDefIconObjectPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct IconobjectIFace *Self = (struct IconobjectIFace *) ExtLib->MainIFace; + + return Self->GetDefIconObject( + (ULONG)regarray[0], + (CONST struct TagItem *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_GetDefIconObject = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_GetDefIconObjectPPC }; + +static LONG stub_PutIconObjectPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct IconobjectIFace *Self = (struct IconobjectIFace *) ExtLib->MainIFace; + + return Self->PutIconObject( + (Object *)regarray[8], + (CONST_STRPTR)regarray[9], + (CONST struct TagItem *)regarray[10] + ); +} +STATIC CONST struct EmuTrap stub_PutIconObject = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_PutIconObjectPPC }; + +static ULONG stub_IsIconNamePPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct IconobjectIFace *Self = (struct IconobjectIFace *) ExtLib->MainIFace; + + return Self->IsIconName( + (CONST_STRPTR)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_IsIconName = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_IsIconNamePPC }; + +static Object * stub_Convert2IconObjectPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct IconobjectIFace *Self = (struct IconobjectIFace *) ExtLib->MainIFace; + + return Self->Convert2IconObject( + (struct DiskObject *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_Convert2IconObject = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_Convert2IconObjectPPC }; + +static Object * stub_Convert2IconObjectAPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct IconobjectIFace *Self = (struct IconobjectIFace *) ExtLib->MainIFace; + + return Self->Convert2IconObjectA( + (struct DiskObject *)regarray[8], + (CONST struct TagItem *)regarray[9] + ); +} +STATIC CONST struct EmuTrap stub_Convert2IconObjectA = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_Convert2IconObjectAPPC }; + +CONST CONST_APTR VecTable68K[] = +{ + &stub_Open, + &stub_Close, + &stub_Expunge, + &stub_Reserved, + &stub_NewIconObject, + &stub_DisposeIconObject, + &stub_GetDefIconObject, + &stub_PutIconObject, + &stub_IsIconName, + &stub_Convert2IconObject, + &stub_Convert2IconObjectA, + (CONST_APTR)-1 +}; diff --git a/scalos/libraries/iconobject/iconobject_base.h b/scalos/libraries/iconobject/iconobject_base.h new file mode 100644 index 000000000..5b856e830 --- /dev/null +++ b/scalos/libraries/iconobject/iconobject_base.h @@ -0,0 +1,30 @@ +// iconobject_base.h +// $Date$ +// $Revision$ + + +#ifndef ICONOBJBASE_H +#define ICONOBJBASE_H + +#include +#include +#include +#include + +struct IconObjectBase +{ + struct Library iob_LibNode; + + struct SegList *iob_SegList; + + APTR iob_AmigaIcon; + struct SignalSemaphore iob_Semaphore; + + struct List iob_ClassList; + + BPTR iob_dtPathLock; + + UWORD iob_pad; +}; + +#endif /* ICONOBJBASE_H */ diff --git a/scalos/libraries/iconobject/makefile b/scalos/libraries/iconobject/makefile new file mode 100644 index 000000000..c7b58eb6f --- /dev/null +++ b/scalos/libraries/iconobject/makefile @@ -0,0 +1,106 @@ +# makefile für Scalos IconObject library (C-Version) +# $Date$ +# $Revision$ +# $Id$ +############################################################# + +CSRCS = IconObject.c \ + IconObject-classic.c +ASRCS = + +AS = phxAss +SPLAT = sc:c/splat +LINK = slink +CC = sc +LIBS = LIB:sc.lib LIB:debug.lib LIB:amiga.lib +PRECOMP = Include:all.gst +OBJDIR = .sasobj + +############################################################# + +.SUFFIXES: .s .asm .plugin .plugin.debug + +############################################################# + +.PHONY: clean install nodebug + +############################################################# + +CFLAGS = optimize nostackcheck nover dbg=s DATA=far idir=//include +LNFLAGS = quiet batch noicons stripdebug SD +LNDBFLAGS = quiet batch noicons addsym SD + +ifdef L +AFLAGS = QUIET DS NOEXE opt=NRQB LIST=* XREFS linedebug I=SC:Assembler_Headers +#AFLAGS = -l -t -iINCLUDE: +else +AFLAGS = QUIET DS opt=NRQB NOEXE linedebug I=SC:Assembler_Headers +#AFLAGS = -t -iINCLUDE: +endif + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +############################################################# + +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(CSRCS:%.c=$(OBJDIR)/%.o) + +############################################################# + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $* objectname $@ + +$(OBJDIR)/%.o : %.s + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +$(OBJDIR)/%.o : %.asm + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +############################################################ + +NAME = .bin_os3/iconobject.library +DBGNAME = $(NAME).debug + +############################################################# + +all: $(NAME) $(DBGNAME) + +############################################################# + +$(OBJDIR)/IconObject.o : iconnode.h iconobject_base.h +$(OBJDIR)/IconObject-classic.o : iconnode.h iconobject_base.h + +############################################################# + +$(NAME) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LINK) to $@ FROM $(OBJS) lib $(LIBS) $(LNFLAGS) + +$(DBGNAME) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LINK) to $@ FROM $(OBJS) lib $(LIBS) $(LNDBFLAGS) + +############################################################# + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(NAME)\033[0m to \033[1mLIBS: \033[0m\n' + @copy $(NAME) LIBS: clone + +############################################################# + +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + @delete $(NAME) $(DBGNAME) $(OBJS) + @printf '\033[0m' + +############################################################# + +nodebug: + -@$(SPLAT) -s -o "d2(" "d1(" "#?.c" + +############################################################# diff --git a/scalos/libraries/iconobject/makefile-new b/scalos/libraries/iconobject/makefile-new new file mode 100755 index 000000000..807dd3d02 --- /dev/null +++ b/scalos/libraries/iconobject/makefile-new @@ -0,0 +1,78 @@ +# $Date: 2011-06-23 22:22:37 +0200 (Do, 23. Jun 2011) $ +# $Revision: 739 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../.. +endif + +############################################################################## + +include config.mk + +############################################################################### +# +# Project Object files +# + +ifeq ($(MACHINE),ppc-amigaos) +OBJS := $(OBJDIR)/IconObject-aos4.o \ + $(OBJDIR)/iconobject-aos4-68kstubs.o +else +ifeq ($(MACHINE),i386-aros) +OBJS := $(OBJDIR)/IconObject-aros.o +else +OBJS := $(OBJDIR)/IconObject-classic.o +endif +endif + +OBJS += $(OBJDIR)/IconObject.o + + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Targets +# + +NAME = iconobject.library +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump + +all: all_subdirs \ + $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + $(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: install_subdirs + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) LIBS: clone + @avail flush + + +clean: clean_subdirs + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* + +############################################################################## diff --git a/scalos/libraries/iconobject/test.c b/scalos/libraries/iconobject/test.c new file mode 100644 index 000000000..48520d17d --- /dev/null +++ b/scalos/libraries/iconobject/test.c @@ -0,0 +1,45 @@ +// test.c +// 17 Jun 2001 15:52:49 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +struct Library *IconobjectBase; + +int main(int argc, char *argv[]) +{ + if( IconobjectBase = (APTR) OpenLibrary( "iconobject.library", 0L ) ) + { + Object *iobj; + char *IconName = "SYS:WBStartup/ASyncWB"; + + if (2 == argc) + IconName = argv[1]; + + printf("OK, Version %ld.%ld\n", IconobjectBase->lib_Version, IconobjectBase->lib_Revision); + + iobj = NewIconObjectTags(IconName, + TAG_END); + + printf("IconObject = %p\n", iobj); + + if (iobj) + { + DisposeIconObject(iobj); + } + + CloseLibrary( IconobjectBase ); + } + + return 0; +} + diff --git a/scalos/libraries/makefile b/scalos/libraries/makefile new file mode 100644 index 000000000..0f1a46ea3 --- /dev/null +++ b/scalos/libraries/makefile @@ -0,0 +1,47 @@ +# makefile für Scalos IconObject library (C-Version) +# $Date$ +# $Revision$ +# $Id$ + +############################################################# + +SUBDIRS = preferences \ + sqlite \ + scalosgfx \ + iconobject \ + popupmenu \ + +############################################################# + +.PHONY: All install clean + +############################################################# + +define build_subdir +$(MAKE) -s --directory=$(1); +endef + +define install_subdir +$(MAKE) -s install --directory=$(1); +endef + +define clean_subdir +$(MAKE) -s clean --directory=$(1); +endef + +############################################################# + +all: + @$(foreach subdir,$(SUBDIRS),$(call build_subdir,$(subdir))) + +############################################################# + +install: + @$(foreach subdir,$(SUBDIRS),$(call install_subdir,$(subdir))) + +############################################################# + +clean: + @$(foreach subdir,$(SUBDIRS),$(call clean_subdir,$(subdir))) + +############################################################# diff --git a/scalos/libraries/makefile-new b/scalos/libraries/makefile-new new file mode 100755 index 000000000..80906b4a3 --- /dev/null +++ b/scalos/libraries/makefile-new @@ -0,0 +1,40 @@ +# $Date: 2011-06-23 22:23:38 +0200 (Do, 23. Jun 2011) $ +# $Revision: 740 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/.. +endif + +############################################################################## + +include config.mk + +############################################################################### + +SUBDIRS = preferences \ + sqlite \ + scalosgfx \ + iconobject + +ifeq ($(MACHINE), ppc-amigaos) +else +ifeq ($(MACHINE), i386-aros) +else +SUBDIRS += popupmenu +endif +endif + +############################################################################## + +.PHONY: all install clean bump dump + +all: all_subdirs + +install: install_subdirs + +clean: clean_subdirs + +nodebug: nodebug_subdirs + +############################################################################## diff --git a/scalos/libraries/popupmenu/LICENSE b/scalos/libraries/popupmenu/LICENSE new file mode 100644 index 000000000..9146ee7f3 --- /dev/null +++ b/scalos/libraries/popupmenu/LICENSE @@ -0,0 +1,3 @@ +"Any license is ok with me" + +(Henrik Isaksson Original popupmenu.library author) diff --git a/scalos/libraries/popupmenu/compiler.h b/scalos/libraries/popupmenu/compiler.h new file mode 100644 index 000000000..474c9397f --- /dev/null +++ b/scalos/libraries/popupmenu/compiler.h @@ -0,0 +1,22 @@ +/* +** $VER: compiler.h 37.31 (18.3.98) +** +** Compiler independent register (and SAS/C extensions) handling +** +** (C) Copyright 1997-98 Andreas R. Kleinert +** All Rights Reserved. +** +** $Date$ +** $Revision$ +*/ + +#ifndef COMPILER_H +#define COMPILER_H + + /* ============================================================ */ + +#include "defs.h" + +/* ********************************************************************* */ + +#endif /* COMPILER_H */ diff --git a/scalos/libraries/popupmenu/config.mk b/scalos/libraries/popupmenu/config.mk new file mode 100755 index 000000000..0db81afab --- /dev/null +++ b/scalos/libraries/popupmenu/config.mk @@ -0,0 +1,52 @@ +############################################################################## +# $Date: 2009-02-17 21:22:13 +0100 (Di, 17. Feb 2009) $ +# $Revision: 5 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +SCALOS_INC = scalos:Src/scalos + +INCLUDES += -I$(SCALOS_INC)/ppc-mos-include \ + -I$(SCALOS_INC)/include + +LFLAGS += -nostartfiles \ +# --verbose + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +# Overwrite the DEFINES so that __NOLIBBASE__ is not defined +OS4LIBBASE = -D__USE_BASETYPE__ + +LFLAGS += -nostartfiles \ +# --verbose + +else + +############################################################################### +# AmigaOS + +LFLAGS += -liconobject -lstack -lnix -lnixmain -lamiga -lstubs + +endif +endif diff --git a/scalos/libraries/popupmenu/iff.c b/scalos/libraries/popupmenu/iff.c new file mode 100644 index 000000000..00fd79f86 --- /dev/null +++ b/scalos/libraries/popupmenu/iff.c @@ -0,0 +1,225 @@ +// iff.c +// +// $Date$ +// $Revision$ + +/* Standard module for reading/writing simple IFF files */ + +#include "pmpriv.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* This function opens an IFF file and prepares it for reading or writing. */ +/* If the file is opened for writing, it is initialized as a FORM of the */ +/* specified 'type'. If an error occurs, it is returned in 'error'. */ + +#ifdef __amigaos4__ +struct IFFParseIFace *IIFFParse; +#endif + +struct IFFHandle *OpenIFFFile(CONST_STRPTR name, LONG type, ULONG mode, LONG *error, struct Library *IFFParseBase) +{ + struct IFFHandle *iffh; + BPTR file; + LONG dosmode = (mode == IFFF_WRITE)? MODE_NEWFILE: MODE_OLDFILE; + + *error = ERROR_OBJECT_NOT_FOUND; + + d1(KPrintF("%s/%s/%ld: name=<%s>\n", __FILE__, __FUNC__, __LINE__, name)); + if ((file = Open(name,dosmode))) + { + *error = IFFERR_NOMEM; + + d1(KPrintF("%s/%s/%ld: Open success file=%08lx\n", __FILE__, __FUNC__, __LINE__, file)); + + if ((iffh = AllocIFF())) + { + d1(KPrintF("%s/%s/%ld: AllocIFF success iffh=%08lx\n", __FILE__, __FUNC__, __LINE__, iffh)); + iffh->iff_Stream = (ULONG)file; + InitIFFasDOS(iffh); + + *error = OpenIFF(iffh,mode); + d1(KPrintF("%s/%s/%ld: OpenIFF returned error=%ld\n", __FILE__, __FUNC__, __LINE__, *error)); + + if (RETURN_OK == *error) + { + if (mode == IFFF_WRITE) + { + *error = PushChunk(iffh,type,ID_FORM,IFFSIZE_UNKNOWN); + if (*error) + PopChunk(iffh); + } + + if (RETURN_OK == *error) + return (iffh); + } + + CloseIFF(iffh); + FreeIFF(iffh); + } + + Close(file); + } + + return (NULL); +} + +/* This function closes a previously opened IFF file. */ + +void CloseIFFFile(struct IFFHandle *iffh, struct Library *IFFParseBase) +{ + if (iffh) + { + if (iffh->iff_Flags & IFFF_WRITE) + { + PopChunk(iffh); + } + + CloseIFF(iffh); + Close((BPTR)(iffh->iff_Stream)); + FreeIFF(iffh); + } +} + +/* This function resets the reading/writing position of an IFF file */ +/* so that the next I/O operation restarts from the beginning. */ + +LONG ResetIFFFile(struct IFFHandle *iffh, struct Library *IFFParseBase) +{ + ULONG flags; + BPTR file; + LONG error = 0L; + + if (iffh) + { + file = (BPTR)(iffh->iff_Stream); + flags = iffh->iff_Flags; + CloseIFF(iffh); + Seek(file,0,OFFSET_BEGINNING); + error = OpenIFF(iffh,flags & IFFF_RWBITS); + } + + return (error); +} + +/* This function can be used to read a chunk of the specified ID, or just */ +/* the next chunk if 'id' is zero. You can read a series of chunks having */ +/* the same ID just by calling ReadChunk() multiple times, as it remembers */ +/* its current position. By doing this with an 'id' of zero, you can even */ +/* read all the chunks in the IFF file. If you need to read chunks having */ +/* different IDs, you should call ResetIFFFile() before each new search, */ +/* to make sure the scan always starts from the beginning. If the wanted */ +/* chunk is found, no more than 'size' bytes are copied from it to the */ +/* buffer pointed to by 'data'; if either 'data' or 'size' is zero, no */ +/* copy occurs. You can always retrieve the chunk bytes from the returned */ +/* ContextNode structure; a NULL return value means that no more chunks of */ +/* the specified ID were found (or the end of file was reached). */ + +struct ContextNode *ReadChunk(struct IFFHandle *iffh, LONG id, APTR data, ULONG size, struct Library *IFFParseBase) +{ + LONG error; + struct ContextNode *cn = NULL; + + if (iffh && ((iffh->iff_Flags & IFFF_RWBITS) == IFFF_READ)) + { + while (TRUE) + { + error = ParseIFF(iffh,IFFPARSE_RAWSTEP); + + if (error == IFFERR_EOC) + { + continue; + } + else if (error) + { + break; + } + else + { + cn = CurrentChunk(iffh); + + if (!id || (cn->cn_ID == id)) + { + if (data && size && (cn->cn_ID != ID_FORM) && (cn->cn_ID != ID_PROP)) + { + error = ReadChunkBytes(iffh,data,size); + } + + if (error < 0L) cn = NULL; + break; + } + + cn = NULL; + } + } + } + + return (cn); +} + + +void PM_LoadPrefsFile(CONST_STRPTR filename, ULONG flags, struct oldPopupMenuPrefs *prefs, const struct oldPopupMenuPrefs *defprefs) +{ + struct IFFHandle *iffh = NULL; + struct ContextNode *cn; + struct Library *IFFParseBase; + ULONG read; + LONG error = 0; + + + if ((IFFParseBase = OpenLibrary("iffparse.library", 0))) + { + d1(KPrintF("%s/%s/%ld: OpenLibrary(iffparse.library) success \n", __FILE__, __FUNC__, __LINE__)); +#ifdef __amigaos4__ + IIFFParse = (struct IFFParseIFace *)GetInterface(IFFParseBase, "main", 1, NULL); +#endif + d1(KPrintF("%s/%s/%ld: filename=<%s> \n", __FILE__, __FUNC__, __LINE__, filename)); + if ((iffh = OpenIFFFile(filename, ID_PREF, IFFF_READ, &error, IFFParseBase))) + { + d1(KPrintF("%s/%s/%ld: OpenIFFFile success\n", __FILE__, __FUNC__, __LINE__)); + if ((cn = ReadChunk(iffh,ID_PMNU,prefs,sizeof(struct oldPopupMenuPrefs),IFFParseBase))) + { + d1(KPrintF("%s/%s/%ld: ReadChunk success cn_Size=%lu\n", __FILE__, __FUNC__, __LINE__, cn->cn_Size)); + read = cn->cn_Size; + } + else + { + d1(KPrintF("%s/%s/%ld: ReadChunk failed\n", __FILE__, __FUNC__, __LINE__)); + read = 0L; + } + + if (read != sizeof(struct oldPopupMenuPrefs)) + { + d1(KPrintF("%s/%s/%ld: size mismatch: read=%lu expected=%lu\n", \ + __FILE__, __FUNC__, __LINE__, read, sizeof(struct oldPopupMenuPrefs))); + error = IFFERR_READ; + } + + CloseIFFFile(iffh, IFFParseBase); + } + +#ifdef __amigaos4__ + DropInterface((struct Interface *)IIFFParse); +#endif + CloseLibrary(IFFParseBase); + } + else + { + d1(KPrintF("%s/%s/%ld: OpenLibrary(iffparse.library) success \n", __FILE__, __FUNC__, __LINE__)); + } + + d1(KPrintF("%s/%s/%ld: error=%ld \n", __FILE__, __FUNC__, __LINE__, error)); + if (!iffh || (RETURN_OK != error)) + { + *prefs = *defprefs; + } +} + diff --git a/scalos/libraries/popupmenu/makefile b/scalos/libraries/popupmenu/makefile new file mode 100644 index 000000000..737926ad6 --- /dev/null +++ b/scalos/libraries/popupmenu/makefile @@ -0,0 +1,132 @@ +# makefile für Scalos popupmenu library +# Copyright Henrik Isaksson +# $Date$ +# $Revision$ +# +############################################################# + +CSRCS = popupmenu-classic.c \ + pm.c \ + pmgraph.c \ + pminit.c \ + window.c \ + pmimages.c \ + pmfind.c \ + pmshadow.c \ + pmtopography.c \ + pmdlist.c \ + pmlayout.c \ + pmdrawshadow.c \ + pmtags.c \ + pmcreate.c \ + pmmem.c \ + pmprefs.c \ + pminput.c \ + pmversion.c \ + iff.c \ + +ASRCS = + +SPLAT = sc:c/splat +LINK = slink +CC = sc +LIBS = LIB:sc.lib LIB:debug.lib LIB:amiga.lib +PRECOMP = Include:all.gst +OBJDIR = .sasobj + +############################################################# + +.SUFFIXES: plugin .plugin.debug + +############################################################# + +CFLAGS = optimize nostackcheck nover dbg=s DATA=far idlen=64 idir=//include +LNFLAGS = quiet batch noicons stripdebug SD +LNDBFLAGS = quiet batch noicons addsym SD + +ifdef L +AFLAGS = QUIET DS NOEXE opt=NRQB LIST=* XREFS linedebug I=SC:Assembler_Headers +#AFLAGS = -l -t -iINCLUDE: +else +AFLAGS = QUIET DS opt=NRQB NOEXE linedebug I=SC:Assembler_Headers +#AFLAGS = -t -iINCLUDE: +endif + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +############################################################# + +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(CSRCS:%.c=$(OBJDIR)/%.o) + +############################################################# + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $* objectname $@ + +############################################################ + +NAME = .bin_os3/popupmenu.library +DBGNAME = $(NAME).debug + +############################################################# + +all: $(NAME) $(DBGNAME) + +############################################################# + +pmpriv.h : compiler.h popupmenu.h pmtypes.h pmmem.h \ + pmshadow.h pmtopography.h pminput.h \ + pmfind.h pminternals.h pmgraph.h pmimages.h + +$(OBJDIR)/popupmenu-classic.o : pmpriv.h +$(OBJDIR)/pm.o : pmpriv.h +$(OBJDIR)/pmgraph.o : pmpriv.h +$(OBJDIR)/pminit.o : pmpriv.h +$(OBJDIR)/window.o : pmpriv.h +$(OBJDIR)/pmfind.o : pmpriv.h +$(OBJDIR)/pmshadow.o : pmpriv.h +$(OBJDIR)/pmtopography.o : pmpriv.h +$(OBJDIR)/pmdlist.o : pmpriv.h +$(OBJDIR)/pmlayout.o : pmpriv.h +$(OBJDIR)/pmdrawshadow.o : pmpriv.h +$(OBJDIR)/pmtags.c : pmpriv.h +$(OBJDIR)/pmcreate.o : pmpriv.h +$(OBJDIR)/pmmem.o : pmpriv.h +$(OBJDIR)/pmprefs.o : pmpriv.h +$(OBJDIR)/pminput.o : pmpriv.h +$(OBJDIR)/pmverson.o : pmpriv.h +$(OBJDIR)/iff.o : pmpriv.h + +############################################################# + +$(NAME) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LINK) to $@ FROM $(OBJS) lib $(LIBS) $(LNFLAGS) + +$(DBGNAME) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LINK) to $@ FROM $(OBJS) lib $(LIBS) $(LNDBFLAGS) + +############################################################# + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(NAME)\033[0m to \033[1mLIBS: \033[0m\n' + @copy $(NAME) LIBS: clone + +############################################################# + +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + @delete $(NAME) $(DBGNAME) $(OBJS) + @printf '\033[0m' + +############################################################# + +nodebug: + -@$(SPLAT) -s -o "d2(" "d1(" "#?.c" + +############################################################# diff --git a/scalos/libraries/popupmenu/makefile-new b/scalos/libraries/popupmenu/makefile-new new file mode 100755 index 000000000..d5abd4903 --- /dev/null +++ b/scalos/libraries/popupmenu/makefile-new @@ -0,0 +1,90 @@ +# $Date: 2010-05-02 20:34:59 +0200 (So, 02. Mai 2010) $ +# $Revision: 599 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../.. +endif + +############################################################################### + +include config.mk + +############################################################################## +# +# Project Object files +# + +ifneq ($(MACHINE),ppc-amigaos) +OBJS := $(OBJDIR)/popupmenu-classic.o +else +OBJS := $(OBJDIR)/popupmenu-aos4.o \ + $(OBJDIR)/pm-aos4-68kstubs.o +endif + +OBJS += $(OBJDIR)/pm.o \ + $(OBJDIR)/pmgraph.o \ + $(OBJDIR)/pminit.o \ + $(OBJDIR)/window.o \ + $(OBJDIR)/pmimages.o \ + $(OBJDIR)/pmfind.o \ + $(OBJDIR)/pmshadow.o \ + $(OBJDIR)/pmtopography.o \ + $(OBJDIR)/pmdlist.o \ + $(OBJDIR)/pmlayout.o \ + $(OBJDIR)/pmdrawshadow.o \ + $(OBJDIR)/pmtags.o \ + $(OBJDIR)/pmcreate.o \ + $(OBJDIR)/pmmem.o \ + $(OBJDIR)/pmprefs.o \ + $(OBJDIR)/pminput.o \ + $(OBJDIR)/pmversion.o \ + $(OBJDIR)/iff.o \ + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Target +# + +NAME = popupmenu.library +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump nodebug + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + $(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @protect $@ +e + +############################################################################## + +install: install_subdirs + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) LIBS: clone + @avail flush + + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i \ + $(OBJDIR)/*.s $(OBJDIR)/*.d.* \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* + +############################################################################## diff --git a/scalos/libraries/popupmenu/pm-aos4-68kstubs.c b/scalos/libraries/popupmenu/pm-aos4-68kstubs.c new file mode 100644 index 000000000..f71459ae7 --- /dev/null +++ b/scalos/libraries/popupmenu/pm-aos4-68kstubs.c @@ -0,0 +1,328 @@ +/* +** This file was automatically generated by fdtrans 51.19. +** Do not edit it by hand. Instead, edit the sfd file +** that was used to generate this file +*/ + +#ifdef __USE_INLINE__ +#undef __USE_INLINE__ +#endif +#ifndef __NOGLOBALIFACE__ +#define __NOGLOBALIFACE__ +#endif + +#include +#include +#include +#include +#include +#include +#include + + +static inline int8 convert_int8 (uint32 x) { return x; } +static inline int16 convert_int16(uint32 x) { return x; } + + +STATIC struct Library * stub_OpenPPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct LibraryManagerInterface *Self = (struct LibraryManagerInterface *) ExtLib->ILibrary; + + return Self->Open(0); +} +STATIC CONST struct EmuTrap stub_Open = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_OpenPPC }; + +STATIC APTR stub_ClosePPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct LibraryManagerInterface *Self = (struct LibraryManagerInterface *) ExtLib->ILibrary; + + return Self->Close(); +} +STATIC CONST struct EmuTrap stub_Close = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_ClosePPC }; + +STATIC APTR stub_ExpungePPC(ULONG *regarray __attribute__((unused))) +{ + return NULL; +} +STATIC CONST struct EmuTrap stub_Expunge = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_ExpungePPC }; + +STATIC ULONG stub_ReservedPPC(ULONG *regarray __attribute__((unused))) +{ + return 0UL; +} +STATIC CONST struct EmuTrap stub_Reserved = { TRAPINST, TRAPTYPE, stub_ReservedPPC }; + +static struct PopupMenu * stub_PM_MakeMenuAPPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct PopupMenuIFace *Self = (struct PopupMenuIFace *) ExtLib->MainIFace; + + return Self->PM_MakeMenuA( + (struct TagItem *)regarray[9] + ); +} +STATIC CONST struct EmuTrap stub_PM_MakeMenuA = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_PM_MakeMenuAPPC }; + +static struct PopupMenu * stub_PM_MakeItemAPPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct PopupMenuIFace *Self = (struct PopupMenuIFace *) ExtLib->MainIFace; + + return Self->PM_MakeItemA( + (struct TagItem *)regarray[9] + ); +} +STATIC CONST struct EmuTrap stub_PM_MakeItemA = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_PM_MakeItemAPPC }; + +static VOID stub_PM_FreePopupMenuPPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct PopupMenuIFace *Self = (struct PopupMenuIFace *) ExtLib->MainIFace; + + Self->PM_FreePopupMenu( + (struct PopupMenu *)regarray[9] + ); +} +STATIC CONST struct EmuTrap stub_PM_FreePopupMenu = { TRAPINST, TRAPTYPENR, (ULONG (*)(ULONG *))stub_PM_FreePopupMenuPPC }; + +static ULONG stub_PM_OpenPopupMenuAPPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct PopupMenuIFace *Self = (struct PopupMenuIFace *) ExtLib->MainIFace; + + return Self->PM_OpenPopupMenuA( + (struct Window *)regarray[9], + (struct TagItem *)regarray[10] + ); +} +STATIC CONST struct EmuTrap stub_PM_OpenPopupMenuA = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_PM_OpenPopupMenuAPPC }; + +static struct PM_IDLst * stub_PM_MakeIDListAPPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct PopupMenuIFace *Self = (struct PopupMenuIFace *) ExtLib->MainIFace; + + return Self->PM_MakeIDListA( + (struct TagItem *)regarray[9] + ); +} +STATIC CONST struct EmuTrap stub_PM_MakeIDListA = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_PM_MakeIDListAPPC }; + +static BOOL stub_PM_ItemCheckedPPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct PopupMenuIFace *Self = (struct PopupMenuIFace *) ExtLib->MainIFace; + + return Self->PM_ItemChecked( + (struct PopupMenu *)regarray[9], + (ULONG)regarray[1] + ); +} +STATIC CONST struct EmuTrap stub_PM_ItemChecked = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_PM_ItemCheckedPPC }; + +static LONG stub_PM_GetItemAttrsAPPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct PopupMenuIFace *Self = (struct PopupMenuIFace *) ExtLib->MainIFace; + + return Self->PM_GetItemAttrsA( + (struct PopupMenu *)regarray[10], + (struct TagItem *)regarray[9] + ); +} +STATIC CONST struct EmuTrap stub_PM_GetItemAttrsA = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_PM_GetItemAttrsAPPC }; + +static LONG stub_PM_SetItemAttrsAPPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct PopupMenuIFace *Self = (struct PopupMenuIFace *) ExtLib->MainIFace; + + return Self->PM_SetItemAttrsA( + (struct PopupMenu *)regarray[10], + (struct TagItem *)regarray[9] + ); +} +STATIC CONST struct EmuTrap stub_PM_SetItemAttrsA = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_PM_SetItemAttrsAPPC }; + +static struct PopupMenu * stub_PM_FindItemPPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct PopupMenuIFace *Self = (struct PopupMenuIFace *) ExtLib->MainIFace; + + return Self->PM_FindItem( + (struct PopupMenu *)regarray[9], + (ULONG)regarray[1] + ); +} +STATIC CONST struct EmuTrap stub_PM_FindItem = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_PM_FindItemPPC }; + +static VOID stub_PM_AlterStatePPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct PopupMenuIFace *Self = (struct PopupMenuIFace *) ExtLib->MainIFace; + + Self->PM_AlterState( + (struct PopupMenu *)regarray[9], + (struct PM_IDLst *)regarray[10], + (UWORD)(regarray[1] & 0xffff) + ); +} +STATIC CONST struct EmuTrap stub_PM_AlterState = { TRAPINST, TRAPTYPENR, (ULONG (*)(ULONG *))stub_PM_AlterStatePPC }; + +static struct PM_IDLst * stub_PM_ExLstAPPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct PopupMenuIFace *Self = (struct PopupMenuIFace *) ExtLib->MainIFace; + + return Self->PM_ExLstA( + (ULONG *)regarray[9] + ); +} +STATIC CONST struct EmuTrap stub_PM_ExLstA = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_PM_ExLstAPPC }; + +static APTR stub_PM_FilterIMsgAPPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct PopupMenuIFace *Self = (struct PopupMenuIFace *) ExtLib->MainIFace; + + return Self->PM_FilterIMsgA( + (struct Window *)regarray[8], + (struct PopupMenu *)regarray[9], + (struct IntuiMessage *)regarray[10], + (struct TagItem *)regarray[11] + ); +} +STATIC CONST struct EmuTrap stub_PM_FilterIMsgA = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_PM_FilterIMsgAPPC }; + +static LONG stub_PM_InsertMenuItemAPPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct PopupMenuIFace *Self = (struct PopupMenuIFace *) ExtLib->MainIFace; + + return Self->PM_InsertMenuItemA( + (struct PopupMenu *)regarray[8], + (struct TagItem *)regarray[9] + ); +} +STATIC CONST struct EmuTrap stub_PM_InsertMenuItemA = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_PM_InsertMenuItemAPPC }; + +static struct PopupMenu * stub_PM_RemoveMenuItemPPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct PopupMenuIFace *Self = (struct PopupMenuIFace *) ExtLib->MainIFace; + + return Self->PM_RemoveMenuItem( + (struct PopupMenu *)regarray[8], + (struct PopupMenu *)regarray[9] + ); +} +STATIC CONST struct EmuTrap stub_PM_RemoveMenuItem = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_PM_RemoveMenuItemPPC }; + +static BOOL stub_PM_AbortHookPPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct PopupMenuIFace *Self = (struct PopupMenuIFace *) ExtLib->MainIFace; + + return Self->PM_AbortHook( + (APTR)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_PM_AbortHook = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_PM_AbortHookPPC }; + +static STRPTR stub_PM_GetVersionPPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct PopupMenuIFace *Self = (struct PopupMenuIFace *) ExtLib->MainIFace; + + return Self->PM_GetVersion( + ); +} +STATIC CONST struct EmuTrap stub_PM_GetVersion = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_PM_GetVersionPPC }; + +static VOID stub_PM_ReloadPrefsPPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct PopupMenuIFace *Self = (struct PopupMenuIFace *) ExtLib->MainIFace; + + Self->PM_ReloadPrefs( + ); +} +STATIC CONST struct EmuTrap stub_PM_ReloadPrefs = { TRAPINST, TRAPTYPENR, (ULONG (*)(ULONG *))stub_PM_ReloadPrefsPPC }; + +static LONG stub_PM_LayoutMenuAPPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct PopupMenuIFace *Self = (struct PopupMenuIFace *) ExtLib->MainIFace; + + return Self->PM_LayoutMenuA( + (struct Window *)regarray[8], + (struct PopupMenu *)regarray[9], + (struct TagItem *)regarray[10] + ); +} +STATIC CONST struct EmuTrap stub_PM_LayoutMenuA = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_PM_LayoutMenuAPPC }; + +static VOID stub_PM_FreeIDListPPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct PopupMenuIFace *Self = (struct PopupMenuIFace *) ExtLib->MainIFace; + + Self->PM_FreeIDList( + (struct PM_IDLst *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_PM_FreeIDList = { TRAPINST, TRAPTYPENR, (ULONG (*)(ULONG *))stub_PM_FreeIDListPPC }; + +CONST CONST_APTR VecTable68K[] = +{ + &stub_Open, + &stub_Close, + &stub_Expunge, + &stub_Reserved, + &stub_PM_MakeMenuA, + &stub_PM_MakeItemA, + &stub_PM_FreePopupMenu, + &stub_PM_OpenPopupMenuA, + &stub_PM_MakeIDListA, + &stub_PM_ItemChecked, + &stub_PM_GetItemAttrsA, + &stub_PM_SetItemAttrsA, + &stub_PM_FindItem, + &stub_PM_AlterState, + &stub_Reserved, + &stub_PM_ExLstA, + &stub_PM_FilterIMsgA, + &stub_PM_InsertMenuItemA, + &stub_PM_RemoveMenuItem, + &stub_PM_AbortHook, + &stub_PM_GetVersion, + &stub_PM_ReloadPrefs, + &stub_PM_LayoutMenuA, + &stub_Reserved, + &stub_PM_FreeIDList, + (CONST_APTR)-1 +}; + diff --git a/scalos/libraries/popupmenu/pm.c b/scalos/libraries/popupmenu/pm.c new file mode 100644 index 000000000..d2fc81919 --- /dev/null +++ b/scalos/libraries/popupmenu/pm.c @@ -0,0 +1,1373 @@ +// +// pm.c - popupmenu.library +// +// popupmenu.library and the PopupMenu package is +// Copyright ©1996 - 2002 Henrik Isaksson +// All Rights Reserved. +// +// $Date$ +// $Revision$ +// + +#include "pmpriv.h" + +#include "pminput.h" + +#if 0 +#ifndef __AROS__ +#include "newgui.h" +#endif +#endif + + +static APTR pm_OpenPopupMenuA(struct Window *prevwnd, struct TagItem *tags, struct PopupMenuBase *PopupMenuBase); + + +// struct PM_Root *p = NULL; + +// PM_HandleShadow +// +// Interface to the shadow handling algortihms. +// This will add the current menu rect to the menu topology map, that +// keeps track of the depth arrengement of the menus. This way shadows +// can be mapped to the height differences of various parts of the menu +// structure so that the size of each shadow segment correlates to the +// distance between the background and the menu that cast the shadow. +// Each shadow rectangle computed, is added to a list of shadowed +// regions that will prevent shadows cast by submenus to overlap any of +// the shadows previoulsy drawn. +// When all this is done, the shadow is finally rendered by calls to +// PM_DrawShadow(), for each rectangular segment of the shadow cast by +// this menu. +// + +void PM_HandleShadow(struct PM_Window *a) +{ + PMSR *worknode; + PMSR *nextnode; + PMSRList *delta; + int depth=a->MenuLevel; + int l=a->Wnd->LeftEdge, t=a->Wnd->TopEdge; + int w=a->Width; + int h=a->Height; + + if (!a->Shadowmap || !a->Topographic) + return; // Shadows not used + + if ((delta=PM_InitShadowList())) + { + + // + // The three following calls will create shadows for a lightsource + // positioned somewhere near the top left corner of the screen. + // + // +----------+ + // | |--+ + // | | | + // | |1 | + // | | | + // | | | + // +-+--------+--+ + // | 2 |3 | + // +--------+--+ + // + + d1(KPrintF("%s/%s/%ld: Window LeftEdge=%ld TopEdge=%ld\n", __FILE__, __FUNC__, __LINE__, a->Wnd->LeftEdge, a->Wnd->TopEdge)); + + // Shadow 1 + PM_MapShadow(a->Topographic, delta, + l+w, t, l+w, t+h, + depth, PMSHADOW_HORIZ|PMSHADOW_TOP); + + // Shadow 2 + PM_MapShadow(a->Topographic, delta, + l, t+h, l+w, t+h, + depth, PMSHADOW_VERT|PMSHADOW_LEFT); + + // Shadow 3 + PM_MapShadow(a->Topographic, delta, + l+w, t+h, l+w, t+h, + depth, PMSHADOW_HORIZ|PMSHADOW_VERT); + + // + // The list "delta" represents the additional shadows necessary to + // achieve the desired result. + // + + PM_AddShadow(a->Shadowmap, delta); + + PM_SubMenuRect(a->Shadowmap, l, t, w, h); + + PM_AddTopographicRegion(a->Topographic, + l, t, l+w, h+t, depth+1); + + for (worknode = (PMSR *)(delta->mlh_Head); + nextnode = (PMSR *)PM_NextNode(worknode); + worknode=nextnode) + { + PM_DrawShadow(a, + worknode->Left-a->Wnd->LeftEdge, + worknode->Top-a->Wnd->TopEdge, + worknode->Right-a->Wnd->LeftEdge-1, + worknode->Bottom-a->Wnd->TopEdge-1, + worknode->pmsr_Type); + } + + PM_FreeShadowList(delta); + } +} + +// PM_RenderMenu +void PM_RenderMenu(struct PM_Window *a, BOOL MenuDisable, BOOL refresh) +{ + if (a->te.RPort && !refresh) { + /* Off screen buffer present - draw into it instead */ + /* (Unless it's a menu refresh) */ + a->RPort = a->te.RPort; + } + + SetDrMd(a->RPort, JAM1); + + + // Clear the background + + PM_DrawBg(a, 0, 0, a->Width-1, a->Height-1); + + // Draw a frame around the menu + + if (a->p->PullDown && a->FirstTime) + PM_DrawBox(a, 0, 0, a->Width-1, a->Height-1, SHINE(a->p), SHADOW(a->p)); + else + PM_DrawPrefBox(a->p, a, 0, 0, a->Width-1, a->Height-1); + +/******************************************************* + + { + struct Hook *menurenderhook = NULL; + GetGUIAttrs(NULL, a->p->DrawInfo, GUIA_MenuRenderHook, &menurenderhook, TAG_DONE); // V50 + if (menurenderhook) { + struct MenuRenderMsg rendermsg; + rendermsg.mrm_MethodID = MR_MENUPANEL; + rendermsg.mrm_RastPort = a->RPort; + rendermsg.mrm_DrawInfo = a->p->DrawInfo; + rendermsg.mrm_Bounds = ; + rendermsg.mrm_State = 0; + rendermsg.mrm_Window = a->Wnd; + rendermsg.mrm_Flags = MRF_POPUP; // | MRF_TRANSPARENT + CallHook(menurenderhook, (Object *)&rendermsg); + } else { + } + } +*******************************************************/ + + + // Set Menu Font + + SetFont(a->RPort, a->p->MenuFont); + + // Draw the items + + PM_NewDrawItem(a, &a->PM, FALSE, MenuDisable); + + // Dither the menu, if disabled and if Old Style is selected + + if (MenuDisable && PM_Prefs->pmp_SeparatorBar) + PM_Ghost(a, 0, 0, a->Width, a->Height, SHADOW(a->p)); + + /* Back to on-screen rendering */ + a->RPort = a->Wnd->RPort; +} + +void SelectItem(struct PM_Window *c, BOOL mdis, struct PopupMenuBase *PopupMenuBase) +{ + if (!(c->Selected->Flags & NPM_DISABLED) && !mdis) { + if (c->Selected->Flags & NPM_CHECKIT) { + if (c->Selected->Flags & NPM_CHECKED) { + if (!(c->Selected->Flags & NPM_NOTOGGLE)) { + if (c->Selected->Exclude) { + pm_AlterState(c->p->PM, c->Selected->Exclude, PMACT_DESELECT); + } + c->Selected->Flags&=~NPM_CHECKED; + c->Selected->Flags|=NPM_ISSELECTED; + if (c->Selected->AutoSetPtr) *c->Selected->AutoSetPtr=FALSE; + if (c->Selected->Exclude) { + PM_RenderMenu(c, FALSE, TRUE); + } else { + PM_NewDrawItem(c, c->Selected, TRUE, FALSE); + } + } + } else { + if (c->Selected->Exclude) { + pm_AlterState(c->p->PM, c->Selected->Exclude, PMACT_SELECT); + } + c->Selected->Flags|=NPM_CHECKED|NPM_ISSELECTED; + if (c->Selected->AutoSetPtr) *c->Selected->AutoSetPtr=TRUE; + if (c->Selected->Exclude) { + PM_RenderMenu(c, FALSE, TRUE); + } else { + PM_NewDrawItem(c, c->Selected, TRUE, FALSE); + } + } + } else { + if (c->Selected->Flags & NPM_ISSELECTED) c->Selected->Flags&=~NPM_ISSELECTED; + else c->Selected->Flags|=NPM_ISSELECTED; + PM_NewDrawItem(c, c->Selected, TRUE, FALSE); + } + + c->p->ReturnCode=c->Selected->UserData; + c->p->ReturnID=c->Selected->ID; + } +} + +// +// PM_MBHit +// +// Called when a mouse button changes state. +// +BOOL PM_MBHit(struct PM_Window *c, struct PM_InpMsg *msg, BOOL mdis, struct PopupMenuBase *PopupMenuBase) +{ + UBYTE whattodo=0; + + if (PM_Prefs->pmp_Sticky) { + if (((msg->Code&IECODE_LBUTTON) || (msg->Code&IECODE_RBUTTON))) { + if ((msg->Code&IECODE_UP_PREFIX) && + ((msg->Qual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) || + (msg->Qual & (IEQUALIFIER_LEFTBUTTON|IEQUALIFIER_RBUTTON)))) { + if (c->p->DoMultiSel) { + whattodo=3; + c->p->DoneMulti=TRUE; + } else { + return FALSE; + } + } else { + if (!(msg->Code&IECODE_UP_PREFIX)) { + c->StickyFlag=TRUE; + return FALSE; + } else { + if (c->StickyFlag) { + if (!c->p->DoneMulti) { + whattodo=1; + } else { + if (c->Prev) c->Prev->Running=0L; + c->Running=0L; + return TRUE; + } + } + } + } + } else { + return FALSE; + } + } else { + if (((msg->Code&IECODE_LBUTTON) || (msg->Code&IECODE_RBUTTON))) { + if ((msg->Code&IECODE_UP_PREFIX) && + ((msg->Qual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) || + (msg->Qual & (IEQUALIFIER_LEFTBUTTON|IEQUALIFIER_RBUTTON)))) { + if (c->p->DoMultiSel) { + whattodo=3; + c->p->DoneMulti=TRUE; + } else { + return FALSE; + } + } else { + if (msg->Code&IECODE_UP_PREFIX) { + if (!c->p->DoneMulti) { + whattodo=1; + } else { + if (c->Prev) c->Prev->Running=0L; + c->Running=0L; + return TRUE; + } + } + } + } else return FALSE; + } + + if (whattodo & 1) { // Select an item + if (c->Selected) { + SelectItem(c, mdis, PopupMenuBase); + } + } + + if (whattodo==1) { // Close if multiselect not requested + if (c->Prev) c->Prev->Running=0L; + c->Running=0L; + } + + if (whattodo==0) return FALSE; + else return TRUE; +} + +// PM_InsideItemBox +struct PopupMenu *PM_InsideItemBox(struct PM_Window *c, struct PopupMenu *pm, ULONG mx, ULONG my) +{ + PopupMenu *tmppm; + + while (pm) { + if (pm->SubGroup.Sub && (pm->Flags&NPM_GROUP)) { + tmppm=PM_InsideItemBox(c, pm->SubGroup.Sub, mx, my); + if (tmppm) return tmppm; + } else if (!(pm->Flags&NPM_NOSELECT)) { + if (c->p->PullDown && c->FirstTime) { + if (my>=c->Wnd->TopEdge && + my<=c->Wnd->TopEdge+pm->Top+pm->Height && + mx>=c->Wnd->LeftEdge+pm->Left && + mx<=c->Wnd->LeftEdge+pm->Left+pm->Width) { + return pm; + } + } else { + if (my>=c->Wnd->TopEdge+pm->Top && + my<=c->Wnd->TopEdge+pm->Top+pm->Height && + mx>=c->Wnd->LeftEdge+pm->Left && + mx<=c->Wnd->LeftEdge+pm->Left+pm->Width) { + return pm; + } + } + } + pm=pm->Next; + } + + return NULL; +} + +// +// PM_RedrawPrevSel +// +// Redraws the previously selected item. +// +void PM_RedrawPrevSel(struct PM_Window *c) +{ + if (c->PrevSel) { + PM_NewDrawItem(c, c->PrevSel, FALSE, FALSE); + } +} + +// +// PM_MMove +// +// Called on mouse moves +// +BOOL PM_MMove(struct PM_Window *c, struct PM_InpMsg *msg, + ULONG wleft, ULONG wtop, ULONG mx, ULONG my, BOOL MenuDisable) +{ + if (c->Running && my>=c->Wnd->TopEdge && my<=c->Wnd->TopEdge+c->Height && mx>=c->Wnd->LeftEdge && mx<=c->Wnd->LeftEdge+c->Width) { + c->PrevSel=c->Selected; + + c->Selected=PM_InsideItemBox(c, &c->PM, mx, my); + + if ((c->PrevSel!=c->Selected)) { + c->p->Subtimer=0; + if (c->PrevSel) { + if (!MenuDisable) PM_RedrawPrevSel(c); + c->PrevSel=0L; + } + if (c->Selected) { + if (!MenuDisable) PM_NewDrawItem(c, c->Selected, TRUE, MenuDisable); + } + } + } else { + if (c->Selected) { + if (!MenuDisable) PM_NewDrawItem(c, c->Selected, FALSE, MenuDisable); + c->Selected=0L; + } + return FALSE; + } + return TRUE; +} + +// +// PM_OpenPopupWindow +// +// 1) Opens a window at the appropriate position +// 2) If the window has been opened before, it will be resized to fit +// changes in menu size +// 3) Renders the menu. +// 4) Performs transition effects (TE). +// 5) Renders shadows. +// +BOOL PM_OpenPopupWindow(struct PM_Window *a) +{ + ULONG shadows = TRUE; + +#if 0 +#ifndef __AROS__ + if ( IntuitionBase->LibNode.lib_Version >= 50 ) { + GetGUIAttrs(NULL, a->p->DrawInfo, GUIA_MenuDropShadows, &shadows, TAG_DONE); // V50 !! + } +#endif +#endif + + PMPM_LayoutMenu(a); + + if (!shadows) { + a->p->ShadowHeight=0; + a->p->ShadowWidth=0; + } + + if (a->FirstTime) { + // The first menu may be affected by some special parameters + // set through PM_OpenPopupMenu() + if (a->p->MenuWidth>a->Width) a->Width=a->p->MenuWidth; + if (a->p->MenuHeight>a->Height) a->Height=a->p->MenuHeight; + if (a->p->MenuRight) a->Wnd->MouseX=a->p->MenuRight-a->Width; + if (a->p->MenuBottom) a->Wnd->MouseY=a->p->MenuBottom-a->Height; + if (a->p->MenuCenter) { + a->Wnd->MouseX=(a->p->RootWnd->WScreen->Width/2)-a->Width/2; + a->Wnd->MouseY=(a->p->RootWnd->WScreen->Height/2)-a->Height/2; + } + } + + if (a->FirstTime && a->p->PullDown) { + // A pulldown menu will be horizontally laid out + if (!a->Wnd) + PM_OpenWindow(a, a->MenuX, a->MenuY, a->Width+1, a->Height+1, a->p->RootWnd->WScreen); + else + PM_ResizeWindow(a, a->MenuX, a->MenuY, a->Width+1, a->Height+1); + } else { + if (!a->Wnd) { + WORD mx, my; + + mx = a->MenuX; + my = a->MenuY; + + if (mx+a->Width > a->p->RootWnd->WScreen->Width) { + // If we're too close to the right edge, open menus to the left hereafter. + a->ReverseDirection=TRUE; + } + if (a->AltXPos-a->Width < 0) { + // If we're too close to the left edge, open menus to the right (default). + a->ReverseDirection=FALSE; + } + + if (!a->ReverseDirection) { + PM_OpenWindow(a, mx, my, a->Width+(a->p->ShadowWidth+a->MenuLevel*2)+1, a->Height+(a->p->ShadowHeight+a->MenuLevel*2)+1, a->p->RootWnd->WScreen); + } else { + PM_OpenWindow(a, a->AltXPos-a->Width, my, a->Width+(a->p->ShadowWidth+a->MenuLevel*2)+1, a->Height+(a->p->ShadowHeight+a->MenuLevel*2)+1, a->p->RootWnd->WScreen); + } + } else { + PM_ResizeWindow(a, SCREENMOUSEPOS(a->p), a->Width+1, a->Height+1); + } + } + + if (a->Wnd) + { + PM_RenderMenu(a, a->MenuDisabled, FALSE); + + if (a->te.BMap) + { + // If there is a TE (transition effects) bitmap. + + // Currently, only an "animation" effect is implemented. + + int i; + int w, h; + int dw, dh; + + w = a->Wnd->Width-1; + h = a->Wnd->Height-1; + + if (!(a->p->PullDown && a->FirstTime)) { + w-=a->p->ShadowWidth+a->MenuLevel*2; + h-=a->p->ShadowHeight+a->MenuLevel*2; + } + + dw = w/10; + dh = h/10; + + for(i=1;i<10;i++) + { + BltBitMapRastPort(a->te.BMap, + 0, 0, + a->Wnd->RPort, + 0, 0, + dw*i, dh*i, + 0xc0); + WaitBlit(); + WaitTOF(); + } + + BltBitMapRastPort(a->te.BMap, + 0, 0, + a->Wnd->RPort, + 0, 0, + w, h, + 0xc0); + WaitBlit(); + } + + // Handle shadows + if (shadows) + { + if (!(a->p->PullDown && a->FirstTime)) + { + PM_HandleShadow(a); + } + } + + return TRUE; + } + return FALSE; +} + +struct PM_Window *PM_SetupSubWindow(struct PM_Window *parent, struct PM_Root *p, struct PopupMenu *pm) +{ + struct PM_Window *newwin; + + newwin=PM_Mem_Alloc(sizeof(struct PM_Window)); + if (newwin) { + if (parent) { + parent->WasSelected = parent->Selected; + newwin->ReverseDirection = parent->ReverseDirection; + newwin->Topographic = PM_CopyList(parent->Topographic); + newwin->Shadowmap = PM_CopyList(parent->Shadowmap); + + if ((parent->Selected->Flags & NPM_DISABLED) || parent->MenuDisabled) + newwin->MenuDisabled = TRUE; + } else { + newwin->ReverseDirection = 0; + if (PM_Prefs->pmp_Flags & PMP_FLAGS_SHADOWS) + { + newwin->Topographic = PM_InitTopographicList(); + newwin->Shadowmap = PM_InitShadowList(); + if (newwin->Topographic) + PM_AddTopographicRegion(newwin->Topographic, 0, 0, 5000, 5000, 0); + } + } + + newwin->PM.SubGroup.Sub = pm; + newwin->PM.Flags = NPM_NOSELECT|NPM_GROUP; + newwin->PM.Layout = PML_Vertical; + newwin->PM.Image = NULL; + + newwin->Running = TRUE; + newwin->Prev = parent; + newwin->p = p; + + if (parent) { + if (p->PullDown && parent->FirstTime) { + newwin->MenuX = parent->WasSelected->Left + parent->Wnd->LeftEdge - 1; + newwin->MenuY = parent->Height + 1 + parent->Wnd->TopEdge - 1; + newwin->AltXPos = parent->WasSelected->Left + parent ->Wnd->LeftEdge; + } else { + newwin->MenuX = (int)(parent->WasSelected->Width - parent->WasSelected->Width / 3) + parent->Wnd->LeftEdge + parent->WasSelected->Left; + + if (newwin->MenuX & 1) // Prevents interference in dithered shadows + newwin->MenuX += 1; + + newwin->MenuY = YAPosSelBar(parent, parent->WasSelected) - 5 + parent->Wnd->TopEdge; + newwin->AltXPos = (int)(parent->WasSelected->Width / 3) + parent->Wnd->LeftEdge + parent->WasSelected->Left; + } + + newwin->MenuLevel = parent->MenuLevel + 1; + if (newwin->MenuLevel>4) newwin->MenuLevel = 4; + + if (parent->SubMenuParent->SubConstruct) { + newwin->PM.SubGroup.Sub = (struct PopupMenu *)CallHook(parent->SubMenuParent->SubConstruct, (Object *)parent->Selected, parent); + } + } else { + newwin->AltXPos = newwin->MenuX = p->Scr->MouseX; + newwin->MenuY = p->Scr->MouseY; + newwin->MenuLevel = 0; + newwin->FirstTime = TRUE; + return newwin; + } + + if (newwin->PM.SubGroup.Sub) + return newwin; + + // Constructor hook cancelled the operation, we must tidy up a bit... + + PM_FreeSubWindow(parent, newwin); + } + return NULL; +} + +void PM_FreeSubWindow(struct PM_Window *parent, struct PM_Window *window) +{ + if (window) { + if (parent) { + if (parent->SubMenuParent->SubDestruct) { + CallHook(parent->SubMenuParent->SubDestruct, (Object *)parent->SubMenuParent); + } + } + + if (window->Topographic) + PM_FreeTopographicList(window->Topographic); + if (window->Shadowmap) + PM_FreeShadowList(window->Shadowmap); + + PM_CloseWindow(window); + PM_Mem_Free(window); + } + if (parent) + parent->SubMenuToOpen = 0L; +} + +void PM_SelectNext(struct PM_Window *a) +{ + BOOL found=FALSE; + a->Selected=PM_FindNextSelectable(a, a->PM.SubGroup.Sub, &found); + if (a->Selected==NULL) a->Selected=PM_FindFirstSelectable(a->PM.SubGroup.Sub); +} + +void PM_SelectPrev(struct PM_Window *a) +{ + BOOL found=FALSE; + a->Selected=PM_FindPrevSelectable(a, a->PM.SubGroup.Sub, &found); + if (!a->Selected) + a->Selected=PM_FindLastSelectable(a->PM.SubGroup.Sub); +} + + APTR PM_DoPopup(struct PM_Window *a, struct PopupMenuBase *PopupMenuBase) +{ + if (PM_OpenPopupWindow(a)) { + BOOL halt; + BOOL keymode=FALSE; + + while (a->Running && (a->p->TimeOut<2)) { + struct PM_InpMsg *msg; + ULONG s; + + s=Wait(1L << a->p->pmh->port->mp_SigBit | 1L << a->p->tport->mp_SigBit); + + if (s & (1L << a->p->tport->mp_SigBit)) { + if (GetMsg(a->p->tport)) { + a->p->treq->tr_node.io_Command = TR_ADDREQUEST; + a->p->treq->tr_time.tv_secs=0; + a->p->treq->tr_time.tv_micro=200000; + SendIO((struct IORequest *)a->p->treq); + a->p->TimeOut++; + } + } + + halt=FALSE; + + if (s & (1L << a->p->pmh->port->mp_SigBit)) { + while ((msg=(struct PM_InpMsg *)GetMsg(a->p->pmh->port))) { + switch(msg->Kind) { + case PM_MSG_RAWMOUSE: + keymode=FALSE; + if (msg->Code!=IECODE_NOBUTTON) { + PM_MBHit(a, msg, a->MenuDisabled, PopupMenuBase); + break; + } else { + if (!PM_MMove(a, msg, 0, 0, a->Wnd->WScreen->MouseX, a->Wnd->WScreen->MouseY, a->MenuDisabled)) { + if (PM_InsideWindows(a->Wnd->WScreen->MouseX, a->Wnd->WScreen->MouseY, a)) { + a->Running=0L; + if (a->Prev) a->Prev->Running=TRUE; + } + } + } + + case PM_MSG_TIMER: + if (a->p->TimeOut>0) a->p->TimeOut--; + if (msg->Kind==PM_MSG_TIMER || a->p->Subtimer==0) { + a->p->Subtimer++; + if (a->Selected && (a->p->Subtimer > PM_Prefs->pmp_SubMenuDelay) && !keymode) { + if (a->Selected->SubGroup.Sub || a->Selected->SubConstruct) { + a->SubMenuToOpen=a->Selected->SubGroup.Sub; + a->SubMenuParent=a->Selected; + + halt=TRUE; // stop before we get too many timer msgs + } + } + } + break; + + case PM_MSG_DOWN: + keymode=TRUE; + a->PrevSel=a->Selected; + PM_RedrawPrevSel(a); + PM_SelectNext(a); + if (a->Selected) PM_NewDrawItem(a, a->Selected, TRUE, FALSE); + break; + + case PM_MSG_UP: + keymode=TRUE; + a->PrevSel=a->Selected; + PM_RedrawPrevSel(a); + PM_SelectPrev(a); + if (a->Selected) PM_NewDrawItem(a, a->Selected, TRUE, FALSE); + break; + + case PM_MSG_MULTISELECT: + case PM_MSG_SELECT: + if (a->Selected) { + if (!a->Selected->SubGroup.Sub && !a->Selected->SubConstruct) { + SelectItem(a, FALSE, PopupMenuBase); + if (msg->Kind==PM_MSG_SELECT) { + a->Running=0; + if (a->Prev) a->Prev->Running=FALSE; + } + } + } + case PM_MSG_OPENSUB: + if (a->Selected) { + if (a->Selected->SubGroup.Sub || a->Selected->SubConstruct) { + a->SubMenuToOpen=a->Selected->SubGroup.Sub; + a->SubMenuParent=a->Selected; + + halt=TRUE; // stop before we get too many timer msgs + } + } + break; + + case PM_MSG_CLOSESUB: + a->Running=0; + if (a->Prev) a->Prev->Running=TRUE; + halt=TRUE; + break; + + case PM_MSG_TERMINATE: + a->Running=0L; + halt=TRUE; + break; + } + PM_Mem_Free(msg); + + if (halt) break; + } + } + + if (a->SubMenuToOpen) { + struct Task *tsk; + tsk=FindTask(NULL); + if ((UBYTE *)tsk->tc_SPReg<((UBYTE *)tsk->tc_SPLower)+1024) { + DisplayBeep(NULL); +#if 0 + } else if ((a->NextWindow = PM_SetupSubWindow(a, p, a->SubMenuToOpen))) { +#else +#if !defined(__SASC) + #warning "CHECKME: trying to avoid global p" +#endif /* !defined(__SASC) */ + } else if ((a->NextWindow = PM_SetupSubWindow(a, a->p, a->SubMenuToOpen))) { +#endif + PM_DoPopup(a->NextWindow, PopupMenuBase); + + if (a->Prev) a->Prev->Running = FALSE; + + if (!keymode) { + if (!PM_MMove(a, 0, 0, 0, a->Wnd->WScreen->MouseX, a->Wnd->WScreen->MouseY, a->MenuDisabled)) { + if (PM_InsideWindows(a->Wnd->WScreen->MouseX, a->Wnd->WScreen->MouseY, a)) { + a->Running = 0L; + if (a->Prev) a->Prev->Running = TRUE; + } + } + } + + PM_FreeSubWindow(a, a->NextWindow); + a->NextWindow = NULL; + } + a->SubMenuToOpen=NULL; + } + } + PM_CloseWindow(a); + } + + return 0L; +} + +// +// Popup a "hint" window, and close it at first mouse move +// +APTR PM_DoHint(struct PM_Window *a, struct PopupMenuBase *PopupMenuBase) +{ + if (PM_OpenPopupWindow(a)) { + while (a->Running && (a->p->TimeOut<2)) { + struct PM_InpMsg *msg; + ULONG s; + + s=Wait(1L << a->p->pmh->port->mp_SigBit | 1L << a->p->tport->mp_SigBit); + + if (s & (1L << a->p->tport->mp_SigBit)) { + if (GetMsg(a->p->tport)) { + a->p->treq->tr_node.io_Command = TR_ADDREQUEST; + a->p->treq->tr_time.tv_secs=0; + a->p->treq->tr_time.tv_micro=200000; + SendIO((struct IORequest *)a->p->treq); + a->p->TimeOut++; + } + } + + if (s & (1L << a->p->pmh->port->mp_SigBit)) { + while ((msg=(struct PM_InpMsg *)GetMsg(a->p->pmh->port))) { + switch(msg->Kind) { + case PM_MSG_TIMER: + if (a->p->TimeOut>0) a->p->TimeOut--; + break; + default: + a->Running=0L; + } + PM_Mem_Free(msg); + } + } + + } + PM_CloseWindow(a); + } + return 0L; +} + + +LIBFUNC_P1(APTR, LIBPM_OBSOLETEFilterIMsgA, + A6, struct PopupMenuBase *, PopupMenuBase) +{ + (void) PopupMenuBase; + return NULL; +} +LIBFUNC_END + +// +// Filter the IntuiMessage structure for command key sequences, and +// mouse events for intuition menu replacement mode. +// +LIBFUNC_P5(APTR, LIBPM_FilterIMsgA, + A0, struct Window *, w, + A1, struct PopupMenu *, pm, + A2, struct IntuiMessage *, im, + A3, struct TagItem *, tags, + A6, struct PopupMenuBase *, PopupMenuBase) +{ + struct TagItem *tstate; + struct TagItem *tag; + struct Hook *MenuHandler=NULL; + BOOL autpd = FALSE, rawkey = FALSE; + + if (!pm) return 0L; + if (!im) return 0L; + + tstate = tags; + while ((tag=NextTagItem(&tstate))) { + switch(tag->ti_Tag) { + case PM_MenuHandler: + MenuHandler=(struct Hook *)tag->ti_Data; + break; + case PM_AutoPullDown: + autpd=TRUE; + break; + case PM_RawKey: + rawkey = (BOOL)tag->ti_Data; + break; + } + } + + if (im->Class==IDCMP_MOUSEBUTTONS) { + if (autpd) { + if (im->Code==MENUDOWN || im->Code==MENUUP) { + struct TagItem opmtags[6]; + + opmtags[0].ti_Tag=PM_Menu; opmtags[0].ti_Data=(ULONG)pm; + opmtags[1].ti_Tag=PM_Code; opmtags[1].ti_Data=im->Code; + opmtags[2].ti_Tag=PM_PullDown; opmtags[2].ti_Data=TRUE; + if (MenuHandler) { + opmtags[3].ti_Tag=PM_MenuHandler; opmtags[3].ti_Data=(ULONG)MenuHandler; + } else { + opmtags[3].ti_Tag=PM_Dummy; opmtags[3].ti_Data=0; + } + opmtags[4].ti_Tag=TAG_MORE; opmtags[4].ti_Data=(ULONG)tags; + opmtags[5].ti_Tag=TAG_DONE; opmtags[5].ti_Data=0; + + return pm_OpenPopupMenuA(w, opmtags, PopupMenuBase); + } + } + } else if (im->Class==IDCMP_VANILLAKEY && !rawkey) { + if (im->Qualifier&IEQUALIFIER_RCOMMAND) { + struct PopupMenu *p; + + p=PM_FindItemCommKey(pm, im->Code); + if (p) { + if (!(p->Flags & NPM_DISABLED)) { + if (p->Flags & NPM_CHECKIT) { + if (p->Flags & NPM_CHECKED) { + p->Flags&=~NPM_CHECKED; + if (p->Exclude) + pm_AlterState(pm, p->Exclude, PMACT_DESELECT); + if (p->AutoSetPtr) *p->AutoSetPtr=FALSE; + } else { + if (p->Exclude) + pm_AlterState(pm, p->Exclude, PMACT_SELECT); + p->Flags|=NPM_CHECKED; + if (p->AutoSetPtr) *p->AutoSetPtr=TRUE; + } + } + if (MenuHandler) CallHook(MenuHandler, (Object *)p); + return p->UserData; + } + } + } + } else if (im->Class==IDCMP_RAWKEY && rawkey) { + if (im->Qualifier&IEQUALIFIER_RCOMMAND) { + struct PopupMenu *p; + + p=PM_FindItemCommKey(pm, im->Code); + if (p) { + if (!(p->Flags & NPM_DISABLED)) { + if (p->Flags & NPM_CHECKIT) { + if (p->Flags & NPM_CHECKED) { + p->Flags&=~NPM_CHECKED; + if (p->Exclude) + pm_AlterState(pm, p->Exclude, PMACT_DESELECT); + if (p->AutoSetPtr) *p->AutoSetPtr=FALSE; + } else { + if (p->Exclude) + pm_AlterState(pm, p->Exclude, PMACT_SELECT); + p->Flags|=NPM_CHECKED; + if (p->AutoSetPtr) *p->AutoSetPtr=TRUE; + } + } + if (MenuHandler) CallHook(MenuHandler, (Object *)p); + return p->UserData; + } + } + } + } + return NULL; +} +LIBFUNC_END + +// +// Call MenuHandler for each selected item +// +void PM_DoSelected(struct PM_Root *p, struct PopupMenu *pm) +{ + struct PopupMenu *z=pm; + + while (z) { + if (z->Flags&NPM_ISSELECTED) { + if (p->DoMultiSel) CallHook(p->MenuHandler, (Object *)z, 0); + z->Flags&=~NPM_ISSELECTED; + if (z->Flags&NPM_CHECKED) + z->Flags|=NPM_INITIAL_CHECKED; + else + z->Flags&=~NPM_INITIAL_CHECKED; + } + if (z->Flags&NPM_CHECKED) + z->Flags|=NPM_INITIAL_CHECKED; + else + z->Flags&=~NPM_INITIAL_CHECKED; + + if (z->SubGroup.Sub) PM_DoSelected(p, z->SubGroup.Sub); + z=z->Next; + } +} + +/// PM_OpenPopupMenuA +struct Window FakeWnd; + +LIBFUNC_P3(APTR, LIBPM_OpenPopupMenuA, + A1, struct Window *, prevwnd, + A2, struct TagItem *, tags, + A6, struct PopupMenuBase *, PopupMenuBase) +{ + return pm_OpenPopupMenuA(prevwnd, tags, PopupMenuBase); +} +LIBFUNC_END + + +static APTR pm_OpenPopupMenuA(struct Window *prevwnd, struct TagItem *tags, struct PopupMenuBase *PopupMenuBase) +{ + APTR ret = 0L; + BOOL shut_down = FALSE; + struct TagItem *tstate; + struct TagItem *tag; +#if 1 +#if !defined(__SASC) +#warning "trying to get rid of global p" +#endif /* !defined(__SASC) */ + struct PM_Root *p; +#endif + + if (!prevwnd) { + prevwnd=&FakeWnd; + FakeWnd.LeftEdge=0; + FakeWnd.TopEdge=0; + FakeWnd.WScreen=IntuitionBase->ActiveScreen; + FakeWnd.RPort=&FakeWnd.WScreen->RastPort; + } + + p=PM_AllocPMRoot(prevwnd); + if (p) { + p->RootWnd = prevwnd; + p->Scr = prevwnd->WScreen; + + p->pmh=PM_InstallHandler(127); + + if (p->pmh) + { + PM_Prefs_Load(PMP_PATH_OLD, PMP_PATH_NEW); + + p->RootMenu = PM_SetupSubWindow(NULL, p, NULL); + p->RButton=TRUE; // default + + tstate = tags; + while ((tag = NextTagItem(&tstate)) && !shut_down) { + switch(tag->ti_Tag) { + case PM_ForceFont: + p->MenuFont=(struct TextFont *)tag->ti_Data; + break; + case PM_LocaleHook: + p->LocaleHook=(struct Hook *)tag->ti_Data; + break; + case PM_Code: + if (tag->ti_Data & IECODE_RBUTTON) p->RButton=TRUE; + if (tag->ti_Data & IECODE_LBUTTON) p->LButton=TRUE; + if ((tag->ti_Data & IECODE_UP_PREFIX)) { + shut_down=TRUE; + } + break; + case PM_UseLMB: + if (tag->ti_Data) p->LButton = TRUE; + p->RButton = FALSE; + break; + case PM_CenterScreen: + p->MenuCenter = tag->ti_Data; + break; + case PM_Right: + p->MenuRight = tag->ti_Data + prevwnd->LeftEdge; + break; + case PM_Bottom: + p->MenuBottom = tag->ti_Data + prevwnd->TopEdge; + break; + case PM_MinWidth: + p->MenuWidth = tag->ti_Data; + break; + case PM_MinHeight: + p->MenuHeight = tag->ti_Data; + break; + case PM_Left: + p->RootMenu->MenuX = tag->ti_Data+(tag->ti_Data&1L?1:0)+prevwnd->LeftEdge; + break; + case PM_Top: + p->RootMenu->MenuY = tag->ti_Data+prevwnd->TopEdge; + break; + case PM_Menu: + if (tag->ti_Data) { + p->PM = (struct PopupMenu *)tag->ti_Data; + } + break; + case PM_PullDown: + if (PM_Prefs->pmp_PulldownPos == PMP_PD_MOUSE) { // Popup pulldowns? + p->PullDown = tag->ti_Data; + } /*else if (PM_Prefs->Popup == 2) { // pos dependent + if (PM_Prefs->WinBar) { + if (prevwnd->LeftEdgeWScreen->MouseX && + prevwnd->TopEdgeWScreen->MouseY && + prevwnd->LeftEdge+prevwnd->Width>prevwnd->WScreen->MouseX && + prevwnd->TopEdge+prevwnd->BorderTop>prevwnd->WScreen->MouseY) { + p->PullDown = tag->ti_Data; + } + } else if (prevwnd->WScreen->MouseY < prevwnd->WScreen->BarHeight) { + p->PullDown = tag->ti_Data; + } + }*/ + + if (p->PullDown) { // Put pulldowns at screen top-left + p->RootMenu->MenuX = 0; + p->RootMenu->MenuY = 0; + p->RootMenu->MenuLevel = -1; // Right shadow-size + p->RootMenu->PM.Layout = PML_Horizontal; + } else { + p->RootMenu->PM.Layout=PML_Vertical; + } + break; + case PM_MenuHandler: + p->MenuHandler = (struct Hook *)tag->ti_Data; + p->DoMultiSel = TRUE; + break; + case PM_HintBox: + p->HintBox = TRUE; + break; + } + } + + if (!shut_down) { + + switch(PM_Prefs->pmp_MenuBorder) { + case BUTTON_FRAME: + p->BorderWidth=p->BorderHeight=1; + break; + case MAGIC_FRAME: + case THICK_BUTTON_FRAME: + case DOUBLE_FRAME: + p->BorderWidth=p->BorderHeight=2; + break; + case INTUI_FRAME: + p->BorderWidth=2; + p->BorderHeight=1; + break; + case DROPBOX_FRAME: + p->BorderWidth=p->BorderHeight=4; + break; + } + + if (p->DrawInfo) { + if (!p->MenuFont) p->MenuFont=p->DrawInfo->dri_Font; + } + + if (!p->MenuFont) p->MenuFont=(struct TextFont *)prevwnd->WScreen->Font; + + p->RootMenu->PM.SubGroup.Sub = p->PM; + + PM_Image_Allocate(p); + +#ifdef __AROS__ + p->treq=EZCreateTimer(UNIT_VBLANK); +#else + p->treq=EZCreateTimer(0); +#endif + if (p->treq) { + p->treq->tr_time.tv_secs=0; + p->treq->tr_time.tv_micro=200000; + + p->tport=p->treq->tr_node.io_Message.mn_ReplyPort; + + p->treq->tr_node.io_Command=TR_ADDREQUEST; + SendIO((struct IORequest *)p->treq); + } + + if (p->HintBox) + PM_DoHint(p->RootMenu, PopupMenuBase); + else + PM_DoPopup(p->RootMenu, PopupMenuBase); + + if (p->treq) { + AbortIO((struct IORequest *)p->treq); + WaitIO((struct IORequest *)p->treq); + EZDeleteTimer(p->treq); + } + + } /* if (!shut_down) */ + + if (p->DrawInfo) FreeScreenDrawInfo(prevwnd->WScreen, p->DrawInfo); + + ret = p->ReturnCode; + + Delay(2); + + PM_FreeSubWindow(NULL, p->RootMenu); + PM_RemoveHandler(p->pmh); + } + + PM_DoSelected(p, p->PM); + PM_Image_Free(p); + PM_Mem_Free(p); + + return ret; + } else DisplayBeep(NULL); + + return 0L; +} +/// + +/// PM_InsertMenuItemA +// +// Function to add an item to a menu +// + +LIBFUNC_P3(LONG, LIBPM_InsertMenuItemA, + A2, struct PopupMenu *, base, + A1, struct TagItem *, tags, + A6, struct PopupMenuBase *, l) +{ + struct TagItem *tag, *tstate; + LONG count=0; + ULONG method=0; // insertion method + struct PopupMenu *pointer = NULL, *pm; + + (void) l; + + if (!base) return 0; + + tstate = tags; + while ((tag=NextTagItem(&tstate))) { + switch(tag->ti_Tag) { + case PM_Insert_Before: + case PM_Insert_After: + case PM_Insert_First: + case PM_Insert_Last: + case PM_InsertSub_Last: + case PM_InsertSub_First: + case PM_InsertSub_Sorted: + method=tag->ti_Tag; + pointer=(struct PopupMenu *)tag->ti_Data; + break; + case PM_Insert_AfterID: + method=tag->ti_Tag; + pointer=PM_FindID(base, tag->ti_Data); + break; + case PM_Insert_BeforeID: + method=tag->ti_Tag; + pointer=(struct PopupMenu *)PM_FindBeforeID(base, tag->ti_Data); + break; + case PM_Insert_Item: + if (tag->ti_Data && pointer) { + + switch(method) { + case PM_Insert_Last: + pm=PM_FindLast(base); + if (pm) pm->Next=(struct PopupMenu *)tag->ti_Data; + break; + case PM_Insert_First: // Relies on first itm being hdr (invis itm) + pm=base->Next; + base->Next=(struct PopupMenu *)tag->ti_Data; + base->Next->Next=pm; + break; + case PM_Insert_Before: + pm=PM_FindBefore(base, pointer); + if (pm) { + pm->Next=(struct PopupMenu *)tag->ti_Data; + pm->Next->Next=pointer; + } + break; + case PM_Insert_BeforeID: + case PM_Insert_After: + case PM_Insert_AfterID: + pm=pointer->Next; + pointer->Next=(struct PopupMenu *)tag->ti_Data; + pointer->Next->Next=pm; + break; + case PM_InsertSub_Last: + pm=PM_FindLast(pointer); + if (pm) pm->Next=(struct PopupMenu *)tag->ti_Data; + break; + case PM_InsertSub_First: + pm=pointer->SubGroup.Sub; + pointer->SubGroup.Sub=(struct PopupMenu *)tag->ti_Data; + pointer->SubGroup.Sub->Next=pm; + break; + case PM_InsertSub_Sorted: + pm=PM_FindSortedInsertPoint(base, pointer); + if (pm) { + pm->Next=(struct PopupMenu *)tag->ti_Data; + pm->Next->Next=pointer; + } + break; + } + + count++; + } + break; + } + } + + return count; +} +LIBFUNC_END +/// + +/// PM_RemoveMenuItem +// +// Function to remove an item +// + +LIBFUNC_P3(APTR, LIBPM_RemoveMenuItem, + A0, struct PopupMenu *, base, + A1, struct PopupMenu *, item, + A6, struct PopupMenuBase *, l) +{ + struct PopupMenu *pm, *prev=NULL; + + (void) l; + + pm=base; + + if (pm) do { + if (pm==item) { + if (prev) { + prev->Next=item->Next; + item->Next=NULL; + return item; + } else { + return NULL; + } + } + prev=pm; + pm=pm->Next; + } while (pm); + + return NULL; +} +LIBFUNC_END +/// + +/// PM_AbortHook +LIBFUNC_P2(BOOL, LIBPM_AbortHook, + A0, APTR, handle, + A6, struct PopupMenuBase *, l) +{ + struct PM_Window *a=(struct PM_Window *)handle; + int mx=a->Wnd->WScreen->MouseX-a->Wnd->LeftEdge; + int my=a->Wnd->WScreen->MouseY-a->Wnd->TopEdge; + + (void) l; + + if (mx>=a->Selected->Left && mx<=a->Selected->Left+a->Selected->Width && + my>=a->Selected->Top && my<=a->Selected->Top+a->Selected->Height) { + + if (a->NextWindow) { + if (a->Selected->SubGroup.Sub) { + ULONG m; + a->NextWindow->PM.SubGroup.Sub=a->Selected->SubGroup.Sub; + CurrentTime(&a->p->Secs, &m); + if (m - a->p->Micros > 60000) /* Update only every 60th millisecond */ + PM_OpenPopupWindow(a->NextWindow); + a->p->Micros=m; + } + } + + return FALSE; + } + return TRUE; +} +LIBFUNC_END +/// + +/// PM_GetVersion + +char version[256]; + +#ifdef __AROS__ +#include "popupmenu_libdefs.h" +#define _LibID VERSION_STRING +#else +extern char _LibID[]; +#endif + +LIBFUNC_P1(STRPTR, LIBPM_GetVersion, + A6, struct PopupMenuBase *, l) +{ + strcpy(version, _LibID); + + (void) l; + + if (CyberGfx) PM_StrCat(version, "\nGraphics card environment found and utilized."); + if (V40Gfx) PM_StrCat(version, "\nOS3.1 graphics.library found and utilized."); + + return version; +} +LIBFUNC_END +/// + +LIBFUNC_P4(LONG, LIBPM_LayoutMenuA, + A0, struct Window *, w, + A1, struct PopupMenu *, pm, + A2, struct TagItem *, tags, + A6, struct PopupMenuBase *, PopupMenuBase) +{ + (void) PopupMenuBase; + (void) tags; + (void) pm; + (void) w; + return 0; +} +LIBFUNC_END + + +LIBFUNC_P1(LONG, LIBPM_RESERVED1, + A6, struct PopupMenuBase *, PopupMenuBase) +{ + (void) PopupMenuBase; + return 0; +} +LIBFUNC_END + diff --git a/scalos/libraries/popupmenu/pmcreate.c b/scalos/libraries/popupmenu/pmcreate.c new file mode 100644 index 000000000..199ec7c77 --- /dev/null +++ b/scalos/libraries/popupmenu/pmcreate.c @@ -0,0 +1,294 @@ +// +// PopupMenu +// ©1996-2002 Henrik Isaksson +// +// Menu creation/disposal & id list functions +// +// $Date$ +// $Revision$ +// + +#include "pmpriv.h" + +void FreeIDList(struct PM_IDLst *f) +{ + if (f) { + struct PM_IDLst *n; + + while (f) { + n=f->Next; + PM_Mem_Free(f); + f=n; + } + } +} + +void PM_FreeTitle(struct PopupMenu *p) +{ + if (!p) return; + + if (p->TitleUnion.Title && GET_TXTMODE(p)==0) PM_Mem_Free(p->TitleUnion.Title); + + p->TitleUnion.Title=NULL; +} + +LIBFUNC_P2(void, LIBPM_FreePopupMenu, + A1, struct PopupMenu *, p, + A6, struct PopupMenuBase *, PopupMenuBase) +{ + pm_FreePopupMenu(p, PopupMenuBase); +} +LIBFUNC_END + + +void pm_FreePopupMenu(struct PopupMenu *p, struct PopupMenuBase *PopupMenuBase) +{ + + if (p) { + struct PopupMenu *n; + + while (p) { + n=p->Next; + if (p->SubGroup.Sub) + pm_FreePopupMenu(p->SubGroup.Sub, PopupMenuBase); + PM_FreeTitle(p); + if (p->UserData && (p->Flags&NPM_UDATASTRING)) PM_Mem_Free(p->UserData); + if (p->Exclude && !(p->Flags&NPM_EXCLUDE_SHARED)) { + FreeIDList(p->Exclude); + } + PM_Mem_Free(p); + p=n; + } + } +} + +LIBFUNC_P2(void, LIBPM_FreeIDList, + A0, struct PM_IDLst *, f, + A6, struct PopupMenuBase *, PopupMenuBase); +{ + (void) PopupMenuBase; + FreeIDList(f); +} +LIBFUNC_END + +LIBFUNC_P2(struct PopupMenu *, LIBPM_MakeItemA, + A1, struct TagItem *, tags, + A6, struct PopupMenuBase *, PopupMenuBase) +{ + struct PopupMenu *p; + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld START\n", __LINE__)); + + p = PM_Mem_Alloc(sizeof(struct PopupMenu)); + if (p) { + pm_SetItemAttrsA(p, tags, PopupMenuBase); + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld END p=%08lx\n", __LINE__, p)); + return p; + } + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld END first=%08lx\n", __LINE__, NULL)); + + return NULL; +} +LIBFUNC_END + +LIBFUNC_P2(struct PopupMenu *, LIBPM_MakeMenuA, + A1, struct TagItem *, tags, + A6, struct PopupMenuBase *, PopupMenuBase) +{ + struct TagItem *tag, *tstate; + struct PopupMenu *first=0L, *last=0L; + BOOL error=0; + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld START\n", __LINE__)); + + (void) PopupMenuBase; + + tstate = tags; + while ((tag=NextTagItem(&tstate))) { + switch(tag->ti_Tag) { + case PM_Item: + if (tag->ti_Data) { + if (last) { + last->Next=(struct PopupMenu *)tag->ti_Data; + last=last->Next; + } else { + last=first=(struct PopupMenu *)tag->ti_Data; + } + } else error=1; + break; + } + } + + if (error) { + pm_FreePopupMenu(first, PopupMenuBase); + first=0L; + } + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld END first=%08lx\n", __LINE__, first)); + + return first; +} +LIBFUNC_END + +LIBFUNC_P2(struct PM_IDLst *, LIBPM_MakeIDListA, + A1, struct TagItem *, tags, + A6, struct PopupMenuBase *, PopupMenuBase) +{ + struct TagItem *tag, *tstate; + struct PM_IDLst *first=0L, *last=0L, *n; + BOOL error=0; + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld START\n", __LINE__)); + + (void) PopupMenuBase; + + tstate = tags; + while ((tag=NextTagItem(&tstate))) { + switch(tag->ti_Tag) { + case PM_ExcludeID: + n=PM_Mem_Alloc(sizeof(struct PM_IDLst)); + if (n) { + n->Next=0L; + n->ID=tag->ti_Data; + n->Kind=IDKND_EXCLUDE; + n->Flags=0L; + + if (last) { + last->Next=n; + last=last->Next; + } else { + last=first=n; + } + } else error=1; + break; + case PM_IncludeID: + n=PM_Mem_Alloc(sizeof(struct PM_IDLst)); + if (n) { + n->Next=0L; + n->ID=tag->ti_Data; + n->Kind=IDKND_INCLUDE; + n->Flags=0L; + + if (last) { + last->Next=n; + last=last->Next; + } else { + last=first=n; + } + } else error=1; + break; + case PM_ReflectID: + n=PM_Mem_Alloc(sizeof(struct PM_IDLst)); + if (n) { + n->Next=0L; + n->ID=tag->ti_Data; + n->Kind=IDKND_REFLECT; + n->Flags=0L; + + if (last) { + last->Next=n; + last=last->Next; + } else { + last=first=n; + } + } else error=1; + break; + case PM_InverseID: + n=PM_Mem_Alloc(sizeof(struct PM_IDLst)); + if (n) { + n->Next=0L; + n->ID=tag->ti_Data; + n->Kind=IDKND_INVERSE; + n->Flags=0L; + + if (last) { + last->Next=n; + last=last->Next; + } else { + last=first=n; + } + } else error=1; + break; + } + } + + if (error) { + FreeIDList(first); + first=0L; + } + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld END first=%08lx\n", __LINE__, first)); + + return first; +} +LIBFUNC_END + +LIBFUNC_P2(struct PM_IDLst *, LIBPM_ExLstA, + A1, ULONG *, id, + A6, struct PopupMenuBase *, PopupMenuBase) +{ + struct PM_IDLst *first=0L, *last=0L, *n; + BOOL error=0; + int i=0; + + (void) PopupMenuBase; + + while (id[i]) + { + n=PM_Mem_Alloc(sizeof(struct PM_IDLst)); + if (n) + { + n->Next=0L; + n->ID=id[i]; + n->Kind=IDKND_EXCLUDE; + n->Flags=0L; + + if (last) + { + last->Next=n; + last=last->Next; + } + else + { + last=first=n; + } + } + else + error=1; + i++; + } + + if (error) + { + FreeIDList(first); + first=0L; + } + + return first; +} +LIBFUNC_END + +// +// Allocate local variables to save stack +// +struct PM_Root *PM_AllocPMRoot(struct Window *w) +{ + struct PM_Root *p; + + p=PM_Mem_Alloc(sizeof(struct PM_Root)); + if (p) { + p->ShadowWidth=p->ShadowHeight=4; + p->ShadowAddX=p->ShadowAddY=2; + + p->BorderWidth=p->BorderHeight=1; + + p->DrawInfo=GetScreenDrawInfo(w->WScreen); + + p->PM=0L; + + return p; + } + return NULL; +} diff --git a/scalos/libraries/popupmenu/pmdlist.c b/scalos/libraries/popupmenu/pmdlist.c new file mode 100644 index 000000000..50b871432 --- /dev/null +++ b/scalos/libraries/popupmenu/pmdlist.c @@ -0,0 +1,115 @@ +// +// pmdlist.c +// +// PopupMenu Library - Linked Lists +// +// Copyright (C)2000 Henrik Isaksson +// All Rights Reserved. +// +// $Date$ +// $Revision$ +// + +#include "pmdlist.h" + +#include + +#include +#include + +// +// PM_InitList - allocate and initialize an Exec MinList structure. +// +PMDList *PM_InitList(void) +{ + PMDList *newlist; + + newlist=(PMDList *)AllocVec(sizeof(struct MinList), MEMF_ANY); + if (newlist) { + NewList((struct List *)newlist); + } + + return newlist; +} + +// +// PM_FreeList - free all nodes in a list and the list structure itself. +// +void PM_FreeList(PMDList *list) +{ + PMGLN *worknode; + PMGLN *nextnode; + + worknode = (PMGLN *)(list->mlh_Head); /* First node */ + while ((nextnode = (PMGLN *)(worknode->n.mln_Succ))) { + PM_FreeNode((PMNode *)worknode); + worknode = nextnode; + } + + FreeVec(list); +} + +// +// PM_CopyList - copy a list. +// +PMDList *PM_CopyList(PMDList *list) +{ + PMDList *newlist; + PMGLN *worknode; + PMGLN *nextnode; + + newlist=PM_InitList(); + if (newlist) { + if (list) { + worknode = (PMGLN *)(list->mlh_Head); /* First node */ + while ((nextnode = (PMGLN *)(worknode->n.mln_Succ))) { + PMGLN *copy=(PMGLN *)PM_CopyNode((PMNode *)worknode); + if (copy) PM_AddToList(newlist, (PMNode *)copy); + worknode = nextnode; + } + } + } + + return newlist; +} + +// +// PM_AddToList - add A to list l. +// +void PM_AddToList(PMDList *l, PMNode *A) +{ + AddHead((struct List *)l, (struct Node *)A); +} + +// +// PM_Unlink - remove A from list l. +// +void PM_Unlink(PMDList *l, PMNode *A) +{ + Remove((struct Node *)A); +} + +// +// PM_FreeNode - free a PMNode. +// +void PM_FreeNode(PMNode *A) +{ + FreeVec(A); +} + +// +// PM_CopyNode - copy a PMNode. +// +PMNode *PM_CopyNode(PMNode *A) +{ + PMNode *newnode=NULL; + + if (A) { + newnode=(PMNode *)AllocVec(((PMGLN *)A)->Length, MEMF_ANY); + if (newnode) { + CopyMem(A, newnode, ((PMGLN *)A)->Length); + } + } + + return newnode; +} diff --git a/scalos/libraries/popupmenu/pmdlist.h b/scalos/libraries/popupmenu/pmdlist.h new file mode 100644 index 000000000..7ca7b8674 --- /dev/null +++ b/scalos/libraries/popupmenu/pmdlist.h @@ -0,0 +1,41 @@ +// +// pmdlist.h +// +// PopupMenu Library - Linked Lists +// +// Copyright (C)2000 Henrik Isaksson +// All Rights Reserved. +// +// $Date$ +// $Revision$ +// + + +#ifndef PM_DLIST_H +#define PM_DLIST_H + +#ifndef EXEC_NODES_H +#include +#endif + +struct PM_GenericListNode { + struct MinNode n; + UWORD Length; +}; + +typedef struct MinList PMDList; +typedef APTR PMNode; +typedef struct PM_GenericListNode PMGLN; + +#define PM_NextNode(x) (((struct MinNode *)x)->mln_Succ) + +PMDList *PM_InitList(void); // Create a new list header. * +void PM_FreeList(PMDList *list); // Free a list. * +PMDList *PM_CopyList(PMDList *list); // Copy a list. * + +void PM_AddToList(PMDList *l, PMNode *A); // Add A to l. * +void PM_Unlink(PMDList *l, PMNode *A); // Remove A from l. * +void PM_FreeNode(PMNode *A); // Free a node. * +PMNode *PM_CopyNode(PMNode *A); // Copy a node. * + +#endif diff --git a/scalos/libraries/popupmenu/pmdrawshadow.c b/scalos/libraries/popupmenu/pmdrawshadow.c new file mode 100644 index 000000000..a65dafd70 --- /dev/null +++ b/scalos/libraries/popupmenu/pmdrawshadow.c @@ -0,0 +1,182 @@ +// +// pmdrawshadow.c - Renders shadows, uses CyberGfx if available. +// +// Copyright (C) 1996 - 2002 Henrik Isaksson +// All Rights Reserved. +// +// $Date$ +// $Revision$ +// + +#include +#include +#include + +#include +#include +#include "pmpriv.h" + + + +// PM_DrawShadow - This function draws a shadow in a PM_Window. The shadow +// will be a rectangle defined by x, y - xb, yb (left, top - right, bottom) + +struct RGB + { + UBYTE Red; + UBYTE Green; + UBYTE Blue; + }; + +// Precalculated alpha values for smooth dropshadows +static const UBYTE ShadowTable[] = + { + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 254, 254, 254, 253, 253, 253, + 252, 252, 251, 250, 250, 249, 249, 248, + 247, 246, 246, 245, 244, 243, 242, 241, + 240, 240, 239, 238, 237, 235, 234, 233, + 232, 231, 230, 229, 227, 226, 225, 224, + 222, 221, 220, 218, 217, 216, 214, 213, + 211, 210, 208, 207, 206, 204, 202, 201, + 199, 198, 196, 195, 193, 191, 190, 188, + 187, 185, 183, 182, 180, 178, 177, 175, + 173, 172, 170, 168, 166, 165, 163, 161, + 160, 158, 156, 154, 153, 151, 149, 148, + 146, 144, 142, 141, 139, 137, 136, 134, + 132, 131, 129, 127, 126, 124, 122, 121, + 119, 117, 116, 114, 113, 111, 109, 108, + 106, 105, 103, 102, 100, 99, 97, 96, + 94, 93, 91, 90, 88, 87, 86, 84, + 83, 81, 80, 79, 77, 76, 75, 73, + 72, 71, 70, 68, 67, 66, 65, 64, + 62, 61, 60, 59, 58, 57, 56, 55, + 54, 53, 52, 51, 50, 49, 48, 47, + 46, 45, 44, 43, 42, 41, 40, 39, + 39, 38, 37, 36, 35, 35, 34, 33, + 32, 32, 31, 30, 30, 29, 28, 28, + 27, 26, 26, 25, 25, 24, 23, 23, + 22, 22, 21, 21, 20, 20, 19, 19, + 18, 18, 17, 17, 16, 16, 16, 15, + 15, 14, 14, 14, 13, 13, 13, 12, + 12, 12, 11, 11, 11, 10, 10, 10, + 10, 9, 9, 9, 9, 8, 8, 8, + 8, 7, 7, 7, 7, 7, 6, 6, + 6, 6, 6, 5, 5, 5, 5, 5, + }; + +void PM_DrawShadow(struct PM_Window *w, int x, int y, int xb, int yb, UBYTE Type) +{ +#ifndef __AROS__ +// BOOL realshadow = PM_Prefs->RealShadows; + BOOL realshadow = FALSE; + + // Shall we draw a real CGFX shadow? + do { + ULONG depth, iscgfx; + ULONG y0; + LONG Width = xb - x + 1; + LONG Height = yb - y + 1; + size_t Size = Width * Height; + struct RGB *SrcRGB; + struct RGB *pRGB; + const ULONG MaxAlpha = 150; + + if (!CyberGfx) + break; + + iscgfx = GetCyberMapAttr(w->RPort->BitMap, CYBRMATTR_ISCYBERGFX); + if (!iscgfx) + break; + + depth = GetCyberMapAttr(w->RPort->BitMap, CYBRMATTR_DEPTH); + if (depth <= 8) + break; + + d1(KPrintF("%s/%s/%ld: x=%ld y=%ld xb=%ld yb=%ld\n", __FILE__, __FUNC__, __LINE__, x, y, xb, yb)); + d1(KPrintF("%s/%s/%ld: Width=%ld Height=%ld\n", __FILE__, __FUNC__, __LINE__, Width, Height)); + d1(KPrintF("%s/%s/%ld: Type=%ld\n", __FILE__, __FUNC__, __LINE__, Type)); + + SrcRGB = PM_Mem_Alloc(Size * sizeof(struct RGB)); + + if (NULL == SrcRGB) + break; + + // read screen background into SrcRGB + ReadPixelArray(SrcRGB, + 0, 0, + Width * sizeof(struct RGB), + w->RPort, + x, y, + Width, + Height, + RECTFMT_RGB); + + for (pRGB = SrcRGB, y0 = 0; y0 < Height; y0++) + { + ULONG x0; + struct RGB *pLineRGB = pRGB; + ULONG fy; + ULONG ky = (Height > 1) ? ((255 * y0) / (Height - 1)) : 255; + + if (Type & SHADOWFLAG_TOP) + fy = ShadowTable[255 - ky]; + else if (Type & SHADOWFLAG_BOTTOM) + fy = ShadowTable[ky]; + else + fy = 255; + + for (x0 = 0; x0 < Width; x0++, pLineRGB++) + { + ULONG fx; + ULONG f; + ULONG kx = (Width > 1) ? ((255 * x0) / (Width - 1)) : 255; + + if (Type & SHADOWFLAG_LEFT) + fx = ShadowTable[255 - kx]; + else if (Type & SHADOWFLAG_RIGHT) + fx = ShadowTable[kx]; + else + fx = 255; + + // calculate (1 - Alpha) + f = 255 - (fx * fy * MaxAlpha) / (256 * 256); + d1(KPrintF("%s/%s/%ld: x=%ld y=%ld kx=%ld ky=%ld fx=%ld fy=%ld f=%ld Type=%08lx\n", __FILE__, __FUNC__, __LINE__, x0, y0, kx, ky, fx, fy, f, Type)); + + pLineRGB->Red = (pLineRGB->Red * f) / 256; + pLineRGB->Green = (pLineRGB->Green * f) / 256; + pLineRGB->Blue = (pLineRGB->Blue * f) / 256; + } + + pRGB += Width; + } + + WritePixelArray(SrcRGB, + 0, 0, + Width * sizeof(struct RGB), + w->RPort, + x, y, + Width, + Height, + RECTFMT_RGB); + + PM_Mem_Free(SrcRGB); + + realshadow = TRUE; + } while (0); + + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); + + if (!realshadow) +#endif /* AROS */ + { + // A "real" shadow could not be drawn, or it was not desired. + static UWORD pat[] = { 0xaaaa, 0x5555 }; + + SetAPen(w->RPort, 1); // Should use DRIPen + SetAfPt(w->RPort, pat, 1); + PM_RectFill(w, x, y, xb, yb); + SetAfPt(w->RPort, NULL, 0); + } +} + diff --git a/scalos/libraries/popupmenu/pmfind.c b/scalos/libraries/popupmenu/pmfind.c new file mode 100644 index 000000000..e3511f117 --- /dev/null +++ b/scalos/libraries/popupmenu/pmfind.c @@ -0,0 +1,294 @@ +// +// pmfind.c - Various support functions used to search the menu item tree. +// +// Copyright ©1996 - 2002 Henrik Isaksson +// All Rights Reserved. +// +// $Date$ +// $Revision$ +// + +#include "pmpriv.h" + +// +// Find an item +// + +// Find a selectable item after a->Selected. If none is found, return NULL. +struct PopupMenu *PM_FindNextSelectable(struct PM_Window *a, struct PopupMenu *pm, BOOL *found) +{ + struct PopupMenu *tmp; + + if (pm) do { + if (pm->Flags&NPM_GROUP) { + tmp=PM_FindNextSelectable(a, pm->SubGroup.Sub, found); + if (tmp) { + if (*found) + return tmp; + } + } + + if (!(pm->Flags&NPM_NOSELECT) && !(pm->Flags&NPM_HIDDEN) && *found) + return pm; + + if (pm==a->Selected) { + *found=TRUE; + } + + pm=pm->Next; + } while (pm); + + return NULL; +} + +// Find the first selectable item in the menu. If none is found, return NULL. +struct PopupMenu *PM_FindFirstSelectable(struct PopupMenu *pm) +{ + struct PopupMenu *tmp; + + if (pm) do { + if (pm->Flags&NPM_GROUP) { + tmp=PM_FindFirstSelectable(pm->SubGroup.Sub); + if (tmp) { + return tmp; + } + } + + if (!(pm->Flags&NPM_NOSELECT) && !(pm->Flags&NPM_HIDDEN)) + return pm; + + pm=pm->Next; + } while (pm); + + return NULL; +} + + +// Find a selectable item ahead of a->Selected. If none is found, return NULL. +struct PopupMenu *PM_FindPrevSelectable(struct PM_Window *a, struct PopupMenu *pm, BOOL *found) +{ + struct PopupMenu *prv=NULL, *tmp; + + if (pm) do { + if (pm->Flags&NPM_GROUP) { + tmp=PM_FindPrevSelectable(a, pm->SubGroup.Sub, found); + if (tmp) { + if (*found) + return tmp; + prv=tmp; + } else if (*found) + return prv; + } + + if (pm==a->Selected) { + *found=TRUE; + return prv; + } + if (!(pm->Flags&NPM_NOSELECT) && !(pm->Flags&NPM_HIDDEN)) + prv=pm; + pm=pm->Next; + } while (pm); + + return prv; +} + +// Find the last selectable item in the menu. If none is found, return NULL. +struct PopupMenu *PM_FindLastSelectable(struct PopupMenu *pm) +{ + struct PopupMenu *prv=NULL, *tmp; + + if (pm) do { + if (pm->Flags&NPM_GROUP) { + tmp=PM_FindLastSelectable(pm->SubGroup.Sub); + if (tmp) { + prv=tmp; + } + } else if (!(pm->Flags&NPM_NOSELECT) && !(pm->Flags&NPM_HIDDEN)) + prv=pm; + + pm=pm->Next; + } while (pm); + + return prv; +} + +// PM_FindID - Find an item based on it's ID +struct PopupMenu *PM_FindID(struct PopupMenu *base, ULONG ID) +{ + struct PopupMenu *pm=base,*xm; + + while (pm) { + if (pm->ID==ID) return pm; + if (pm->SubGroup.Sub) { + xm=PM_FindID(pm->SubGroup.Sub, ID); + if (xm) return xm; + } + pm=pm->Next; + } + return NULL; +} + +// PM_FindBeforeID - find the item before item with ID in pm +struct PopupMenu *PM_FindBeforeID(struct PopupMenu *pm, ULONG ID) +{ + struct PopupMenu *prev=pm,*xm; + + while (pm) { + if (pm->ID==ID) return prev; + if (pm->SubGroup.Sub) { + xm=PM_FindBeforeID(pm->SubGroup.Sub, ID); + if (xm) return xm; + } + prev=pm; + pm=pm->Next; + } + return NULL; +} + +// PM_FindBefore - Find the item before fm in pm +struct PopupMenu *PM_FindBefore(struct PopupMenu *pm, struct PopupMenu *fm) +{ + struct PopupMenu *prev=pm,*xm; + + while (pm) { + if (pm==fm) return prev; + if (pm->SubGroup.Sub) { + xm=PM_FindBefore(pm->SubGroup.Sub, fm); + if (xm) return xm; + } + prev=pm; + pm=pm->Next; + } + return NULL; +} + +// PM_FindSortedInsertPoint - find where to insert the item fm in the list pm +struct PopupMenu *PM_FindSortedInsertPoint(struct PopupMenu *pm, struct PopupMenu *fm) +{ + struct PopupMenu *prev=pm; + + while (pm) { + if (PM_String_Compare(pm->TitleUnion.Title, fm->TitleUnion.Title) < 0) + return prev; + prev=pm; + pm=pm->Next; + } + return NULL; +} + +// PM_FindLast - Find the end of the list. +struct PopupMenu *PM_FindLast(struct PopupMenu *base) +{ + struct PopupMenu *pm=base; + + while (pm) { + if (pm->Next==NULL) return pm; + pm=pm->Next; + } + + return NULL; +} + +// PM_FindItemCommKey - Find an item based on it's CommKey (command key) +struct PopupMenu *PM_FindItemCommKey(struct PopupMenu *base, UBYTE key) +{ + struct PopupMenu *pm=base,*xm; + + while (pm) { + if (ToUpper((UBYTE)pm->CommKey)==ToUpper(key)) return pm; + + if (pm->SubGroup.Sub) { + xm=PM_FindItemCommKey(pm->SubGroup.Sub, key); + if (xm) return xm; + } + pm=pm->Next; + } + return NULL; +} + +// PM_FindItem - find an item based on it's ID +LIBFUNC_P3(struct PopupMenu *, LIBPM_FindItem, + A1, struct PopupMenu *, menu, + D1, ULONG, ID, + A6, struct PopupMenuBase *, l) +{ + (void) l; + + if (!menu) return NULL; + return PM_FindID(menu, ID); +} +LIBFUNC_END + +// +// See if an item is checked +// +LIBFUNC_P3(BOOL, LIBPM_ItemChecked, + A1, struct PopupMenu *, pm, + D1, ULONG, ID, + A6, struct PopupMenuBase *, l); +{ + struct PopupMenu *p; + + (void) l; + + p=PM_FindID(pm, ID); + + if (p) { + if (p->Flags&NPM_CHECKED) return TRUE; + return FALSE; + } + return -5L; +} +LIBFUNC_END + +// +// Set/Clear all items in a list +// + +LIBFUNC_P4(void, LIBPM_AlterState, + A1, struct PopupMenu *, base, + A2, struct PM_IDLst *, ids, + D1, UWORD, action, + A6, struct PopupMenuBase *, l) +{ + (void) l; + + pm_AlterState(base, ids, action); +} +LIBFUNC_END + + +void pm_AlterState(struct PopupMenu *base, struct PM_IDLst *ids, UWORD action) +{ + struct PopupMenu *pm; + struct PM_IDLst *id=ids; + while (id) { + pm=PM_FindID(base, id->ID); + if (pm) { + if (action==PMACT_SELECT) { + if (id->Kind==IDKND_REFLECT) { + pm->Flags|=NPM_CHECKED|NPM_ISSELECTED; + if (pm->AutoSetPtr) *pm->AutoSetPtr=TRUE; + } else if (id->Kind==IDKND_INVERSE) { + pm->Flags&=~(NPM_CHECKED|NPM_ISSELECTED); + if (pm->AutoSetPtr) *pm->AutoSetPtr=FALSE; + } else if (id->Kind==IDKND_INCLUDE) { + pm->Flags|=NPM_CHECKED|NPM_ISSELECTED; + if (pm->AutoSetPtr) *pm->AutoSetPtr=TRUE; + } else if (id->Kind==IDKND_EXCLUDE) { + pm->Flags&=~(NPM_CHECKED|NPM_ISSELECTED); + if (pm->AutoSetPtr) *pm->AutoSetPtr=FALSE; + } + } else if (action==PMACT_DESELECT) { + if (id->Kind==IDKND_INVERSE) { + pm->Flags|=NPM_CHECKED|NPM_ISSELECTED; + if (pm->AutoSetPtr) *pm->AutoSetPtr=TRUE; + } else if (id->Kind==IDKND_REFLECT) { + pm->Flags&=~(NPM_CHECKED|NPM_ISSELECTED); + if (pm->AutoSetPtr) *pm->AutoSetPtr=FALSE; + } + } + } + id=id->Next; + } +} diff --git a/scalos/libraries/popupmenu/pmfind.h b/scalos/libraries/popupmenu/pmfind.h new file mode 100644 index 000000000..0ed3ed8dd --- /dev/null +++ b/scalos/libraries/popupmenu/pmfind.h @@ -0,0 +1,53 @@ +// +// pmfind.h +// +// PopupMenu Library - Menu item searching +// +// Copyright (C)2000 Henrik Isaksson +// All Rights Reserved. +// + +#ifndef PM_FIND_H +#define PM_FIND_H + +struct PM_Window; + +#ifndef LIBRARIES_POPUPMENU_H +struct PopupMenu; +#endif /* LIBRARIES_POPUPMENU_H */ + +// Find a selectable item in a menu, no submenu recursion, but group recursion. +struct PopupMenu *PM_FindNextSelectable(struct PM_Window *a, struct PopupMenu *pm, BOOL *found); +struct PopupMenu *PM_FindFirstSelectable(struct PopupMenu *pm); +struct PopupMenu *PM_FindPrevSelectable(struct PM_Window *a, struct PopupMenu *pm, BOOL *found); +struct PopupMenu *PM_FindLastSelectable(struct PopupMenu *pm); + +// Find item 'ID' in menu 'base'. Recursive. +struct PopupMenu *PM_FindID(struct PopupMenu *base, ULONG ID); + +// Find last item in a menu. Recursive. +struct PopupMenu *PM_FindLast(struct PopupMenu *base); + +// Find item with command key 'key' in menu 'base'. Recursive. +struct PopupMenu *PM_FindItemCommKey(struct PopupMenu *base, UBYTE key); + +// Find item before item 'ID' in menu 'base'. Recursive. +struct PopupMenu *PM_FindBeforeID(struct PopupMenu *base, ULONG ID); + +// Find item before item 'item' :) in menu 'base'. Recursive. +struct PopupMenu *PM_FindBefore(struct PopupMenu *base, struct PopupMenu *item); + +LIBFUNC_P3_PROTO(BOOL, LIBPM_ItemChecked, + A1, struct PopupMenu *, pm, + D1, ULONG, ID, + A6, struct PopupMenuBase *, l); + +// Exported PM_FindID +LIBFUNC_P3_PROTO(struct PopupMenu *, LIBPM_FindItem, + A1, struct PopupMenu *, menu, + D1, ULONG, ID, + A6, struct PopupMenuBase *, l); + +struct PopupMenu *PM_FindSortedInsertPoint(struct PopupMenu *pm, struct PopupMenu *fm); + +#endif /* PM_FIND_H */ diff --git a/scalos/libraries/popupmenu/pmgraph.c b/scalos/libraries/popupmenu/pmgraph.c new file mode 100644 index 000000000..0e7a994b8 --- /dev/null +++ b/scalos/libraries/popupmenu/pmgraph.c @@ -0,0 +1,739 @@ +// +// PopupMenu +// ©1996-2000 Henrik Isaksson +// +// Graphic rendering routines +// +// $Date$ +// $Revision$ +// + +#include "pmpriv.h" + +// +// Generic PM_Window graphics +// + +void PM_DrawBg(struct PM_Window *pw, int x, int y, int xb, int yb) +{ + int xa = x, ya = y; + + if (pw->bg.BgArray) + { + WritePixelArray(pw->bg.BgArray, x, y, + pw->Width*3, pw->RPort, xa, ya, + xb-xa, yb-ya, RECTFMT_RGB); + + } + else + { + SetAPen(pw->RPort, BGPEN(pw->p)); + SetDrMd(pw->RPort, JAM1); + RectFill(pw->RPort, xa, ya, xb, yb); + } +} + +void PM_RectFill(struct PM_Window *pw, int xa, int ya, int xb, int yb) +{ + SetDrMd(pw->RPort, JAM1); + RectFill(pw->RPort, xa, ya, xb, yb); +} + +static void PM_Move(struct PM_Window *pw, int x, int y) +{ + Move(pw->RPort, x, y); +} + +static void PM_Pixel(struct PM_Window *pw, int x, int y) +{ + WritePixel(pw->RPort, x, y); +} + +static void PM_Draw(struct PM_Window *pw, int x, int y) +{ + Draw(pw->RPort, x, y); +} + +static void PM_DrawImage(struct PM_Window *pw, struct Image *img, int x, int y, struct DrawInfo *dri, ULONG state) +{ + d1(KPrintF("%s/%s/%ld: START img=%08lx x=%ld y=%ld state=%ld dri=%08lx\n", __FILE__, __FUNC__, __LINE__, img, x, y, state, dri)); +// PM_RectFill(pw, x, y, x+20, y+20); + DrawImageState(pw->RPort, img, x, y, state, dri); + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); +} + +// +// Ghost an item +// + +void PM_Ghost(struct PM_Window *w, int x, int y, int xb, int yb, int pen) +{ + static UWORD ghostpat[] = { 0x2222, 0x8888 }; + + SetAPen(w->RPort, pen); + SetAfPt(w->RPort, ghostpat, 1); + PM_RectFill(w, x, y, xb, yb); + SetAfPt(w->RPort, NULL, 0); +} + +// +// Render a ColourBox +// + +void ColourBox(struct PM_Window *w, int xa, int ya, int xb, int yb, int pen, int shine, int shade, BOOL selected) +{ + if (selected) + { + PM_DrawBox(w, xa, ya, xb, yb, shade, shine); + } + else + { + PM_DrawBox(w, xa, ya, xb, yb, shine, shade); + } + + SetAPen(w->RPort, pen); + PM_RectFill(w, xa+1, ya+1, xb-1, yb-1); +} + +// +// This is used by the other functions. +// + +void PM_DI_SetTextPen(struct PM_Window *a, struct PopupMenu *pm) +{ + SetAPen(a->RPort, TEXT(a->p)); + if (pm->Flags&NPM_FILLTEXT) + SetAPen(a->RPort, FILL(a->p)); + if (pm->Flags&NPM_SHADOWTEXT) + SetAPen(a->RPort, SHADOW(a->p)); + if (pm->Flags&NPM_SHINETEXT) + SetAPen(a->RPort, SHINE(a->p)); + if (pm->Flags&NPM_HILITETEXT) + SetAPen(a->RPort, HILITE(a->p)); + if (pm->Flags&NPM_CUSTOMPEN) + SetAPen(a->RPort, pm->TextPen); + + d1(KPrintF("%s/%s/%ld: dri_NumPens=%ld FILL=%ld SHADOW=%ld SHINE=%ld HILITE=%ld\n", __FILE__, __FUNC__, \ + __LINE__, a->p->DrawInfo->dri_NumPens, FILL(a->p), SHADOW(a->p), SHINE(a->p), HILITE(a->p))); +} + +ULONG PM_RenderCheckMark(struct PM_Window *a, struct PopupMenu *pm, BOOL Selected) +{ + ULONG xoff=0; + + if (pm->Flags&NPM_CHECKIT) { // Should this item have a checkmark? + + if (pm->Flags&NPM_CHECKED) { + xoff=PM_Image_Draw(a, + pm->Exclude?PMIMG_EXCLUDE:PMIMG_CHECKMARK, + pm->Left+PM_Prefs->pmp_XSpace+1, + a->p->DrawInfo, + Selected?IDS_SELECTED:IDS_INACTIVESELECTED, + pm) + PM_Prefs->pmp_Intermediate; + } else { + /* + xoff=PM_Image_Draw(a, + pm->Exclude?PMIMG_EXCLUDE:PMIMG_CHECKMARK, + pm->Left+PM_Prefs->pmp_XSpace+1, + a->p->DrawInfo, + Selected?IDS_NORMAL:IDS_INACTIVENORMAL, + pm); + */ + xoff = PM_Image_Width(a->p, pm->Exclude?PMIMG_EXCLUDE:PMIMG_CHECKMARK, pm) + PM_Prefs->pmp_Intermediate; + } + + } + + return xoff+PM_Prefs->pmp_XSpace; +} + +int PM_NewDrawItem(struct PM_Window *a, struct PopupMenu *pm, BOOL Selected, BOOL Disabled) +{ + ULONG style, xoff; + STRPTR pmtitle=pm->TitleUnion.Title; + + if (pm->Flags&NPM_HIDDEN) return 0; + + if (GET_TXTMODE(pm)==NPX_TXTLOCALE) + pmtitle=(STRPTR)CallHook(a->p->LocaleHook, (Object *)pm, (Object *)pm->TitleUnion.TitleID); + + if (Selected) + { + SetAPen(a->RPort, FILL(a->p)); + PM_RectFill(a, pm->Left, pm->Top, + pm->Left + pm->Width - 1, pm->Top + pm->Height - 1); + + // --- Test to see how it looks... --- // + //PM_DrawBg(a, pm->Left, pm->Top, pm->Left+pm->Width, pm->Top+pm->Height); + //PM_DrawShadow(a, pm->Left, pm->Top, pm->Left+pm->Width, pm->Top+pm->Height); + // --- // + + } + else + { + PM_DrawBg(a, pm->Left, pm->Top, pm->Left+pm->Width, pm->Top+pm->Height); + } + + if (pm->Flags&NPM_GROUP) + { + struct PopupMenu *pmp=pm->SubGroup.Sub; + + if (pmp) + do { + PM_NewDrawItem(a, pmp, Selected, Disabled); + pmp=pmp->Next; + } while (pmp); + return 0; + } + + + if (pm->Flags&NPM_HBAR_BIT) + { + PM_ShortSeparator(a, pm); + return TRUE; + } + else if (pm->Flags&NPM_WIDE_BAR_BIT) + { + PM_WideSeparator(a, pm); + return TRUE; + } + + if (!Selected) + { // Use RastPort Pen + PM_DI_SetTextPen(a, pm); + } + + /* Text style and font */ + + SetFont(a->RPort, a->p->MenuFont); + SetDrMd(a->RPort, JAM1); + + style = 0; + + if (pm->Flags&NPM_UNDERLINEDTEXT) style|=FSF_UNDERLINED; + if (pm->Flags&NPM_BOLDTEXT) style|=FSF_BOLD; + if (pm->Flags&NPM_ITALICTEXT) style|=FSF_ITALIC; + + SetSoftStyle(a->RPort, style, ~0); + + xoff=PM_RenderCheckMark(a, pm, Selected); + d1(KPrintF("%s/%s/%ld: xoff=%ld\n", __FILE__, __FUNC__, __LINE__, xoff)); + + if (pm->Flags&NPM_COLOURBOX) + { + if (pm->Flags&NPM_CHECKIT) + { + if (pm->CommKey) + { + int x1=(a->Width-3*a->RPort->Font->tf_XSize-PM_Prefs->pmp_XSpace-a->p->BorderWidth)-a->RPort->Font->tf_XSize; + + x1-=a->RPort->Font->tf_XSize*3+PM_Prefs->pmp_Intermediate; + + ColourBox(a, x1, pm->Top+PM_Prefs->pmp_YSpace+1, x1+3*a->RPort->Font->tf_XSize, pm->Top+pm->Height-PM_Prefs->pmp_YSpace-1, pm->CBox, SHINE(a->p), SHADOW(a->p), Selected); + } + else + { + int x1 = (pm->Width + pm->Left - 3*a->RPort->Font->tf_XSize - PM_Prefs->pmp_XSpace - a->p->BorderWidth); + ColourBox(a, x1, pm->Top + PM_Prefs->pmp_YSpace + 1, + x1 + 3*a->RPort->Font->tf_XSize, pm->Top + pm->Height - PM_Prefs->pmp_YSpace - 1, + pm->CBox, SHINE(a->p), SHADOW(a->p), Selected); + } + } + else + { + ColourBox(a, pm->Left+PM_Prefs->pmp_XSpace, pm->Top+PM_Prefs->pmp_YSpace+1, pm->Left+3*a->RPort->Font->tf_XSize, pm->Top+pm->Height-PM_Prefs->pmp_YSpace-1, pm->CBox, SHINE(a->p), SHADOW(a->p), Selected); + xoff+=PM_Prefs->pmp_XSpace+3*a->RPort->Font->tf_XSize; + d1(KPrintF("%s/%s/%ld: xoff=%ld\n", __FILE__, __FUNC__, __LINE__, xoff)); + } + } + + if (!a->p->PullDown) + { + if (pm->SubGroup.Sub) + { + PM_Image_Draw(a, + PMIMG_SUBMENU, + -PM_Prefs->pmp_XSpace, + a->p->DrawInfo, + Selected?IDS_NORMAL:IDS_INACTIVENORMAL, + pm); + } + } + + if (Selected) + { + if (pm->Flags&NPM_ISIMAGE) + { + if (pm->ImageUnion.Images[1]) + { + if (pm->Flags&NPM_CENTERED) + { + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + PM_DrawImage(a, pm->ImageUnion.Images[1], + pm->Left+PM_Prefs->pmp_XSpace+ (pm->Width/2-pm->ImageUnion.Images[1]->Width/2)>xoff?pm->Width/2-pm->ImageUnion.Images[1]->Width/2:xoff, + YPosImage_(a, pm, pm->ImageUnion.Images[1]), a->p->DrawInfo, IDS_SELECTED); + } + else + { + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + PM_DrawImage(a, pm->ImageUnion.Images[1], pm->Left+PM_Prefs->pmp_XSpace+xoff+a->IconColumn, YPosImage_(a, pm, pm->ImageUnion.Images[1]), a->p->DrawInfo, IDS_SELECTED); + } + } + } + else + { + if (pm->ImageUnion.Images[1]) + { + WORD ixoff; + ixoff=a->IconColumn/2-pm->ImageUnion.Images[1]->Width/2; + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + PM_DrawImage(a, pm->ImageUnion.Images[1], pm->Left+PM_Prefs->pmp_XSpace+ixoff, YPosImage_(a, pm, pm->ImageUnion.Images[1]), a->p->DrawInfo, IDS_SELECTED); + } + } + } + else + { + if (pm->Flags&NPM_ISIMAGE) + { + if (pm->ImageUnion.Images[0]) + { + if (pm->Flags&NPM_CENTERED) + { + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + PM_DrawImage(a, pm->ImageUnion.Images[0], + pm->Left+PM_Prefs->pmp_XSpace+ (pm->Width/2-pm->ImageUnion.Images[0]->Width/2)>xoff?pm->Width/2-pm->ImageUnion.Images[0]->Width/2:xoff, + YPosImage_(a, pm, pm->ImageUnion.Images[0]), a->p->DrawInfo, IDS_SELECTED); + } + else + { + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + PM_DrawImage(a, pm->ImageUnion.Images[0], pm->Left+PM_Prefs->pmp_XSpace+xoff+a->IconColumn, YPosImage_(a, pm, pm->ImageUnion.Images[0]), a->p->DrawInfo, IDS_NORMAL); + } + } + } + else + { + if (pm->ImageUnion.Images[0]) + { + WORD ixoff; + ixoff=a->IconColumn/2-pm->ImageUnion.Images[0]->Width/2; + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + PM_DrawImage(a, pm->ImageUnion.Images[0], pm->Left+PM_Prefs->pmp_XSpace+ixoff, YPosImage_(a, pm, pm->ImageUnion.Images[0]), a->p->DrawInfo, IDS_NORMAL); + } + } + } + + if (a->IconColumn) + { + if (pm->Next && ((pm->Flags&NPM_NOSELECT) && !(pm->Flags&NPM_DISABLED) && (pm->Next->Flags&NPM_WIDE_BAR))) + { + // Do not reserve space for icon column on menu titles + } + else + { + xoff+=a->IconColumn+PM_Prefs->pmp_Intermediate; + } + d1(KPrintF("%s/%s/%ld: xoff=%ld IconColumn=%ld\n", __FILE__, __FUNC__, __LINE__, xoff, a->IconColumn)); + } + + if (pm->Flags&NPM_CENTERED) + { + int offs, tw; + + tw=TextLength(a->RPort,pmtitle,strlen(pmtitle)); + offs=pm->Width/2-tw/2; + + if (xoffWidth, offs, xoff)); + } + + if ((pm->Flags&NPM_DISABLED || Disabled) && !PM_Prefs->pmp_SeparatorBar) + { + SetAPen(a->RPort, BGSHINE(a->p)); + PM_Move(a, pm->Left+xoff+1, YPosText(a, pm)+1); + if (pmtitle) Text(a->RPort, pmtitle, strlen(pmtitle)); + } + else if (pm->Flags&NPM_SHADOWED) + { + SetAPen(a->RPort, TEXTSHADOW(a->p)); + PM_Move(a, pm->Left+xoff+1, YPosText(a, pm)+1); + if (pmtitle) Text(a->RPort, pmtitle, strlen(pmtitle)); + } + else if (pm->Flags&NPM_OUTLINED) + { + if (pmtitle) + { + SetAPen(a->RPort, TEXTOUTLINE(a->p)); + PM_Move(a, pm->Left+xoff-1, YPosText(a, pm)-1); + Text(a->RPort, pmtitle, strlen(pmtitle)); + PM_Move(a, pm->Left+xoff+1, YPosText(a, pm)+1); + Text(a->RPort, pmtitle, strlen(pmtitle)); + PM_Move(a, pm->Left+xoff+1, YPosText(a, pm)-1); + Text(a->RPort, pmtitle, strlen(pmtitle)); + PM_Move(a, pm->Left+xoff-1, YPosText(a, pm)+1); + Text(a->RPort, pmtitle, strlen(pmtitle)); + PM_Move(a, pm->Left+xoff-1, YPosText(a, pm)+1); + Text(a->RPort, pmtitle, strlen(pmtitle)); + PM_Move(a, pm->Left+xoff+1, YPosText(a, pm)); + Text(a->RPort, pmtitle, strlen(pmtitle)); + PM_Move(a, pm->Left+xoff-1, YPosText(a, pm)); + Text(a->RPort, pmtitle, strlen(pmtitle)); + PM_Move(a, pm->Left+xoff, YPosText(a, pm)+1); + Text(a->RPort, pmtitle, strlen(pmtitle)); + PM_Move(a, pm->Left+xoff, YPosText(a, pm)-1); + Text(a->RPort, pmtitle, strlen(pmtitle)); + } + } + else if (pm->Flags&NPM_EMBOSSED) + { + if (pmtitle) + { + SetAPen(a->RPort, SHINE(a->p)); + PM_Move(a, pm->Left+xoff-1, YPosText(a, pm)-1); + Text(a->RPort, pmtitle, strlen(pmtitle)); + PM_Move(a, pm->Left+xoff-1, YPosText(a, pm)); + Text(a->RPort, pmtitle, strlen(pmtitle)); + PM_Move(a, pm->Left+xoff, YPosText(a, pm)-1); + Text(a->RPort, pmtitle, strlen(pmtitle)); + SetAPen(a->RPort, SHADOW(a->p)); + PM_Move(a, pm->Left+xoff+1, YPosText(a, pm)+1); + Text(a->RPort, pmtitle, strlen(pmtitle)); + PM_Move(a, pm->Left+xoff+1, YPosText(a, pm)); + Text(a->RPort, pmtitle, strlen(pmtitle)); + PM_Move(a, pm->Left+xoff, YPosText(a, pm)+1); + Text(a->RPort, pmtitle, strlen(pmtitle)); + } + } + + if (!Selected) + { + PM_DI_SetTextPen(a, pm); + } + else + { + SetAPen(a->RPort, FTPEN(a->p)); + } + + if (pm->Flags&NPM_ISSELECTED) + { + if (pm->Flags&NPM_CHECKIT) + { + if ((!(pm->Flags&NPM_CHECKED) && pm->Flags&NPM_INITIAL_CHECKED) || + ((pm->Flags&NPM_CHECKED) && !(pm->Flags&NPM_INITIAL_CHECKED))) + { + SetAPen(a->RPort, HILITE(a->p)); + } + } + else + { + SetAPen(a->RPort, HILITE(a->p)); + } + } + + if (pm->CommKey) + { + char x[2]; + + PM_Image_Draw(a, + PMIMG_AMIGAKEY, + -PM_Prefs->pmp_XSpace-a->RPort->Font->tf_XSize-PM_Prefs->pmp_Intermediate, + a->p->DrawInfo, + Selected?IDS_NORMAL:IDS_INACTIVENORMAL, + pm); + + x[0]=pm->CommKey; + PM_Move(a, XPosLastCol(a), YPosText(a,pm)); + Text(a->RPort, x, 1); + } + + PM_Move(a, pm->Left+xoff, YPosText(a, pm)); + if ((pm->Flags&NPM_DISABLED || Disabled) && !PM_Prefs->pmp_SeparatorBar) SetAPen(a->RPort, BGSHADOW(a->p)); // Set text colour to 'bgminus' if disabled + if (pmtitle) Text(a->RPort, pmtitle, strlen(pmtitle)); + + if (PM_Prefs->pmp_SelItemBorder && Selected) + { + if (PM_Prefs->pmp_MenuBorder==MAGIC_FRAME) + { + if (PM_Prefs->pmp_SelItemBorder==1) /* Raised */ + PM_DrawBoxMM2(a, pm->Left, pm->Top, pm->Left+pm->Width, pm->Top+pm->Height, SHINE(a->p), SHADOW(a->p), HALF(a->p)); + else + PM_DrawBoxMM2(a, pm->Left, pm->Top, pm->Left+pm->Width, pm->Top+pm->Height, SHADOW(a->p), SHINE(a->p), HALF(a->p)); + } + else + { + if (PM_Prefs->pmp_SelItemBorder==1) /* Raised */ + PM_DrawBox(a, pm->Left, pm->Top, pm->Left+pm->Width, pm->Top+pm->Height, SHINE(a->p), SHADOW(a->p)); + else + PM_DrawBox(a, pm->Left, pm->Top, pm->Left+pm->Width, pm->Top+pm->Height, SHADOW(a->p), SHINE(a->p)); + } + } + + if (pm->Flags&NPM_DISABLED && PM_Prefs->pmp_SeparatorBar) + { + PM_Ghost(a, pm->Left, pm->Top, pm->Left+pm->Width, pm->Top+pm->Height, SHADOW(a->p)); + } + + return 0; +} + +// +// Draw a horizontal bar +// + +void PM_Separator(struct PM_Window *w, int x, int y, int x2, int shine, int shadow) +{ + PM_Move(w, x, y-1); + SetAPen(w->RPort, shadow); + PM_Draw(w, x2, y-1); + PM_Move(w, x, y); + SetAPen(w->RPort, shine); + PM_Draw(w, x2, y); +} + +void PM_XENSeparator(struct PM_Window *w, int x, int y, int x2, int shine, int shadow, int bgplus, int bgminus) +{ + PM_Move(w, x+1, y-2); + SetAPen(w->RPort, bgminus); + PM_Draw(w, x2-1, y-2); + + PM_Move(w, x, y-1); + SetAPen(w->RPort, shadow); + PM_Draw(w, x2, y-1); + + PM_Move(w, x, y); + SetAPen(w->RPort, shine); + PM_Draw(w, x2, y); + + PM_Move(w, x+1, y+1); + SetAPen(w->RPort, bgplus); + PM_Draw(w, x2-1, y+1); +} + +void PM_XENSeparatorHalf(struct PM_Window *w, int x, int y, int x2, int shine, int shadow, int bgplus, int bgminus, int half) +{ + PM_Move(w, x+1, y-2); + SetAPen(w->RPort, bgminus); + PM_Draw(w, x2-1, y-2); + + PM_Move(w, x, y-1); + SetAPen(w->RPort, shadow); + PM_Draw(w, x2, y-1); + + PM_Move(w, x, y); + SetAPen(w->RPort, shine); + PM_Draw(w, x2, y); + + PM_Move(w, x+1, y+1); + SetAPen(w->RPort, bgplus); + PM_Draw(w, x2-1, y+1); +} + +void PM_NewSeparator(struct PM_Window *w, int x, int y, int x2, int shine, int shadow) +{ + PM_Move(w, x, y); + SetAPen(w->RPort, shadow); + PM_Draw(w, x, y-1); + PM_Draw(w, x2-1, y-1); + PM_Move(w, x+1, y); + SetAPen(w->RPort, shine); + PM_Draw(w, x2, y); + PM_Draw(w, x2, y-1); +} + +void PM_OldSeparator(struct PM_Window *w, int x, int y, int x2, int shine, int shadow) +{ + PM_Move(w, x, y-1); + SetAPen(w->RPort, shadow); + SetDrPt(w->RPort, 0xbbbb); + PM_Draw(w, x2, y-1); + + PM_Move(w, x, y); + SetAPen(w->RPort, shadow); + SetDrPt(w->RPort, 0xeeee); + PM_Draw(w, x2, y); + + SetDrPt(w->RPort, 0xffff); +} + +void PM_ShortSeparator(struct PM_Window *a, struct PopupMenu *pm) +{ + if (!PM_Prefs->pmp_SeparatorBar) { + if (PM_Prefs->pmp_MenuBorder==MAGIC_FRAME) + PM_NewSeparator(a, BarLeft(a, pm), BarTop(a, pm), BarRight(a, pm), BGSHINE(a->p), BGSHADOW(a->p)); + else PM_NewSeparator(a, BarLeft(a, pm), BarTop(a, pm), BarRight(a, pm), SHINE(a->p), SHADOW(a->p)); + } else PM_OldSeparator(a, BarLeft(a, pm), BarTop(a, pm), BarRight(a, pm), SHINE(a->p), SHADOW(a->p)); +} + +void PM_WideSeparator(struct PM_Window *a, struct PopupMenu *pm) +{ + if (!PM_Prefs->pmp_SeparatorBar) { + if (PM_Prefs->pmp_MenuBorder==MAGIC_FRAME) { + PM_XENSeparatorHalf(a, 0, BarTop(a, pm), a->Width-2, SHINE(a->p), SHADOW(a->p), BGSHINE(a->p), BGSHADOW(a->p), HALF(a->p)); + } else if (PM_Prefs->pmp_MenuBorder==DROPBOX_FRAME) { + PM_Move(a, a->p->BorderWidth-1, BarTop(a, pm)-2); + SetAPen(a->RPort, SHINE(a->p)); + PM_Draw(a, a->Width-a->p->BorderWidth, BarTop(a, pm)-2); + PM_Move(a, a->p->BorderWidth-1, BarTop(a, pm)+1); + SetAPen(a->RPort, SHADOW(a->p)); + PM_Draw(a, a->Width-a->p->BorderWidth, BarTop(a, pm)+1); + + SetAPen(a->RPort, BGPEN(a->p)); + PM_Move(a, a->p->BorderWidth-1, BarTop(a, pm)-1); + PM_Draw(a, a->p->BorderWidth-1, BarTop(a, pm)); + PM_Move(a, a->Width-a->p->BorderWidth, BarTop(a, pm)-1); + PM_Draw(a, a->Width-a->p->BorderWidth, BarTop(a, pm)); + } else { + PM_Separator(a, a->p->BorderWidth-1, BarTop(a, pm), a->Width-a->p->BorderWidth-1, SHINE(a->p), SHADOW(a->p)); + } + } else { + SetAPen(a->RPort, SHADOW(a->p)); + PM_Move(a, a->p->BorderWidth, BarTop(a, pm)); + PM_Draw(a, a->Width-a->p->BorderWidth, BarTop(a, pm)); + PM_Move(a, a->p->BorderWidth, BarTop(a, pm)+1); + PM_Draw(a, a->Width-a->p->BorderWidth, BarTop(a, pm)+1); + } +} + +// +// Draw a bevel box +// + +void PM_DrawBoxMM2(struct PM_Window *w, int x1, int y1, int x2, int y2, int shine, int shadow, int halfshine) +{ + SetAPen(w->RPort, halfshine); + PM_Pixel(w, x1, y2); + PM_Pixel(w, x2, y1); + SetAPen(w->RPort, shine); + PM_Move(w, x1, y2-1); + PM_Draw(w, x1, y1); + PM_Draw(w, x2-1, y1); + SetAPen(w->RPort, shadow); + PM_Move(w, x1+1, y2); + PM_Draw(w, x2, y2); + PM_Draw(w, x2, y1+1); +} + +void PM_DrawXENBoxMM2(struct PM_Window *w, int x1, int y1, int x2, int y2, int shine, int shadow, int bgplus, int bgminus, int halfshine) +{ + SetAPen(w->RPort, shine); + PM_Move(w, x1, y2); + PM_Draw(w, x1, y1); + PM_Draw(w, x2, y1); + SetAPen(w->RPort, bgplus); + PM_Move(w, x1+1, y2-1); + PM_Draw(w, x1+1, y1+1); + PM_Draw(w, x2-1, y1+1); + SetAPen(w->RPort, shadow); + PM_Move(w, x1, y2); + PM_Draw(w, x2, y2); + PM_Draw(w, x2, y1); + SetAPen(w->RPort, bgminus); + PM_Move(w, x1+1, y2-1); + PM_Draw(w, x2-1, y2-1); + PM_Draw(w, x2-1, y1+1); + SetAPen(w->RPort, halfshine); + PM_Pixel(w, x1, y2); + PM_Pixel(w, x2, y1); +} + +void PM_DrawBox(struct PM_Window *w, int x1, int y1, int x2, int y2, int shine, int shadow) +{ + SetAPen(w->RPort, shine); + PM_Move(w, x1, y2-1); + PM_Draw(w, x1, y1); + PM_Draw(w, x2-1, y1); + SetAPen(w->RPort, shadow); + PM_Move(w, x1, y2); + PM_Draw(w, x2, y2); + PM_Draw(w, x2, y1); + +} + +void PM_DrawIBox(struct PM_Window *w, int x1, int y1, int x2, int y2, int shine, int shadow) +{ + SetAPen(w->RPort, shadow); + PM_Move(w, x1, y2); + PM_Draw(w, x1, y1); + PM_Draw(w, x2, y1); + + PM_Move(w, x1, y2); + PM_Draw(w, x2, y2); + PM_Draw(w, x2, y1); + + PM_Move(w, x1+1, y1); + PM_Draw(w, x1+1, y2); + + PM_Move(w, x2-1, y1); + PM_Draw(w, x2-1, y2); +} + +void PM_DrawXENBox(struct PM_Window *w, int x1, int y1, int x2, int y2, int shine, int shadow, int bgplus, int bgminus) +{ + SetAPen(w->RPort, shine); + PM_Move(w, x1, y2); + PM_Draw(w, x1, y1); + PM_Draw(w, x2, y1); + SetAPen(w->RPort, bgplus); + PM_Move(w, x1+1, y2-1); + PM_Draw(w, x1+1, y1+1); + PM_Draw(w, x2-1, y1+1); + SetAPen(w->RPort, shadow); + PM_Move(w, x1, y2); + PM_Draw(w, x2, y2); + PM_Draw(w, x2, y1); + SetAPen(w->RPort, bgminus); + PM_Move(w, x1+1, y2-1); + PM_Draw(w, x2-1, y2-1); + PM_Draw(w, x2-1, y1+1); +} + +void PM_DrawDBLBox(struct PM_Window *w, int x1, int y1, int x2, int y2, int shine, int shadow) +{ + PM_DrawBox(w, x1, y1, x2, y2, shine, shadow); + PM_DrawBox(w, x1+1, y1+1, x2-1, y2-1, shine, shadow); +} + +void PM_DrawDropBox(struct PM_Window *w, int x1, int y1, int x2, int y2, int shine, int shadow) +{ + SetAPen(w->RPort, shine); + PM_Move(w, x1, y2-1); + PM_Draw(w, x1, y1); + PM_Draw(w, x2-1, y1); + PM_Move(w, x1+4, y2-3); + PM_Draw(w, x2-3, y2-3); + PM_Draw(w, x2-3, y1+4); + SetAPen(w->RPort, shadow); + PM_Move(w, x1+3, y2-3); + PM_Draw(w, x1+3, y1+3); + PM_Draw(w, x2-4, y1+3); + PM_Move(w, x1, y2); + PM_Draw(w, x2, y2); + PM_Draw(w, x2, y1); +} + +void PM_DrawPrefBox(struct PM_Root *p, struct PM_Window *w, int x1, int y1, int x2, int y2) +{ + switch(PM_Prefs->pmp_MenuBorder) + { + case BUTTON_FRAME: + PM_DrawBox(w, x1, y1, x2, y2, SHINE(p), SHADOW(p)); + break; + case MAGIC_FRAME: + PM_DrawXENBoxMM2(w, x1, y1, x2, y2, SHINE(p), SHADOW(p), BGSHINE(p), BGSHADOW(p), HALF(p)); + break; + case THICK_BUTTON_FRAME: + PM_DrawXENBox(w, x1, y1, x2, y2, SHINE(p), SHADOW(p), SHINE(p), SHADOW(p)); + break; + case DOUBLE_FRAME: + PM_DrawDBLBox(w, x1, y1, x2, y2, SHINE(p), SHADOW(p)); + break; + case DROPBOX_FRAME: + PM_DrawDropBox(w, x1, y1, x2, y2, SHINE(p), SHADOW(p)); + break; + case INTUI_FRAME: + PM_DrawIBox(w, x1, y1, x2, y2, 0, SHADOW(p)); + break; + } +} + diff --git a/scalos/libraries/popupmenu/pmgraph.h b/scalos/libraries/popupmenu/pmgraph.h new file mode 100644 index 000000000..1c4b03255 --- /dev/null +++ b/scalos/libraries/popupmenu/pmgraph.h @@ -0,0 +1,38 @@ +// +// pmgraph.h +// +// PopupMenu Library - Graphics routines +// +// Copyright (C)2000 Henrik Isaksson +// All Rights Reserved. +// + +#ifndef PM_GRAPH_H +#define PM_GRAPH_H + +struct CGXHook; +struct PM_Root; + +void PM_DrawBg(struct PM_Window *pw, int xa, int ya, int xb, int yb); +void PM_Ghost(struct PM_Window *w, int x, int y, int xb, int yb, int pen); +void PM_Shadow(struct PM_Window *w, int x, int y, int xb, int yb, int pen, struct CGXHook *ch); +void ColourBox(struct PM_Window *w, int xa, int ya, int xb, int yb, int pen, int sh, int sd, BOOL selected); +void PM_DI_SetTextPen(struct PM_Window *a, struct PopupMenu *pm); +ULONG PM_RenderCheckMark(struct PM_Window *a, struct PopupMenu *pm, BOOL Selected); +void PM_Separator(struct PM_Window *w, int x, int y, int x2, int shine, int shadow); +void PM_DrawBox(struct PM_Window *w, int x1, int y1, int x2, int y2, int shine, int shadow); +int PM_NewDrawItem(struct PM_Window *a, struct PopupMenu *pm, BOOL UsePen, BOOL disabled); +int PM_DrawItemHoriz(struct PM_Window *a, struct PopupMenu *pm, BOOL Selected); +void PM_XENSeparator(struct PM_Window *w, int x, int y, int x2, int shine, int shadow, int bgplus, int bgminus); +void PM_NewSeparator(struct PM_Window *w, int x, int y, int x2, int shine, int shadow); +void PM_OldSeparator(struct PM_Window *w, int x, int y, int x2, int shine, int shadow); +void PM_DrawXENBox(struct PM_Window *w, int x1, int y1, int x2, int y2, int shine, int shadow, int bgplus, int bgminus); +void PM_DrawDBLBox(struct PM_Window *w, int x1, int y1, int x2, int y2, int shine, int shadow); +void PM_DrawDropBox(struct PM_Window *w, int x1, int y1, int x2, int y2, int shine, int shadow); +void PM_DrawPrefBox(struct PM_Root *p, struct PM_Window *w, int x1, int y1, int x2, int y2); +void PM_WideSeparator(struct PM_Window *a, struct PopupMenu *pm); +void PM_ShortSeparator(struct PM_Window *a, struct PopupMenu *pm); +void PM_DrawBoxMM2(struct PM_Window *w, int x1, int y1, int x2, int y2, int shine, int shadow, int halfshine); +void PM_RectFill(struct PM_Window *pw, int xa, int ya, int xb, int yb); + +#endif /* PM_GRAPH_H */ diff --git a/scalos/libraries/popupmenu/pmimages.c b/scalos/libraries/popupmenu/pmimages.c new file mode 100644 index 000000000..bd918790a --- /dev/null +++ b/scalos/libraries/popupmenu/pmimages.c @@ -0,0 +1,144 @@ +// +// Popup Menu Images +// ©1996-1997 Henrik Isaksson +// +// $Date$ +// $Revision$ +// + +#include +#include +#include +#include +#include "pmpriv.h" + +extern BOOL V40Gfx; + +UBYTE /* __chip */ arrowData[9*2] = +{ + 0x80,0x00,0xC0,0x00,0xE0,0x00,0xF0,0x00,0xF8,0x00,0xF0,0x00,0xE0,0x00,0xC0,0x00, + 0x80,0x00 +}; + +struct Image arrow = +{ + 0, 0, /* LeftEdge, TopEdge */ + 5, 9, 1, /* Width, Height, Depth */ + (void *)arrowData, /* ImageData */ + 0x0001, 0x0000, /* PlanePick, PlaneOnOff */ + NULL /* NextImage */ +}; + +struct Image *MakeSysImage(struct PM_Root *p, ULONG image, ULONG ist) +{ + struct Image *img; +/* struct DrawInfo dri; + UWORD TP[MAX_PENS]; + + CopyMem(p->DrawInfo,&dri,sizeof(struct DrawInfo)); + if (dri.dri_Version>=2) { + if (ist==IST_INACTIVE) { + TP[SHINEPEN] = p->DrawInfo->dri_Pens[SHINEPEN]; + TP[SHADOWPEN]=PM_Pens_Get(PMPEN_SHADOW); + TP[BACKGROUNDPEN]=PM_Pens_Get(PMPEN_BG); + TP[FILLPEN]=PM_Pens_Get(PMPEN_ACTIVEBG); + TP[BARBLOCKPEN]=TP[BACKGROUNDPEN]; + TP[BARDETAILPEN]=PM_Pens_Get(PMPEN_TEXT); + } else { + TP[SHINEPEN]=PM_Pens_Get(PMPEN_SHINE); + TP[SHADOWPEN]=PM_Pens_Get(PMPEN_SHADOW); + TP[BACKGROUNDPEN]=PM_Pens_Get(PMPEN_ACTIVEBG); + TP[FILLPEN]=PM_Pens_Get(PMPEN_BG); + TP[BARBLOCKPEN]=TP[BACKGROUNDPEN]; + TP[BARDETAILPEN]=PM_Pens_Get(PMPEN_ACTIVETEXT); + } + dri.dri_Pens=TP; + }*/ + + img = (struct Image *) NewObject(NULL, SYSICLASS, + //SYSIA_DrawInfo, &dri, + SYSIA_DrawInfo, p->DrawInfo, + SYSIA_Size, SYSISIZE_HIRES, + SYSIA_Which, image, + IA_Left, 0, + IA_Top, 0, + //IA_BGPen, 0, + //IA_FGPen, TP[BARDETAILPEN], + //IA_Width, p->MenuFont->tf_YSize, + //IA_Height, p->MenuFont->tf_YSize, + TAG_DONE); + + + return img; +} + +void PM_Image_Allocate(struct PM_Root *p) +{ + int i; + + for(i = 0; i < PMIMG_LAST; i++) + p->MenuImages[i] = 0; + + p->MenuImages[PMIMG_AMIGAKEY] = MakeSysImage(p, AMIGAKEY, 0); + p->MenuImages[PMIMG_CHECKMARK] = MakeSysImage(p, MENUCHECK, 0); + p->MenuImages[PMIMG_EXCLUDE] = MakeSysImage(p, MENUCHECK, 0); + p->MenuImages[PMIMG_SUBMENU] = &arrow; //MakeSysImage(p, RIGHTIMAGE, 0); +} + +void PM_Image_Free(struct PM_Root *p) +{ + if (p->MenuImages[PMIMG_AMIGAKEY]) + DisposeObject((Object *) p->MenuImages[PMIMG_AMIGAKEY]); + if (p->MenuImages[PMIMG_CHECKMARK]) + DisposeObject((Object *) p->MenuImages[PMIMG_CHECKMARK]); + if (p->MenuImages[PMIMG_EXCLUDE]) + DisposeObject((Object *) p->MenuImages[PMIMG_EXCLUDE]); + /*if (p->MenuImages[PMIMG_SUBMENU]) + DisposeObject((Object *) p->MenuImages[PMIMG_SUBMENU]); */ +} + +struct PrefsImage *PM_Image_Get(ULONG type, struct PopupMenu *item) +{ + return NULL; +} + +UWORD PM_Image_Draw(struct PM_Window *w, ULONG type, WORD l, struct DrawInfo *dri, ULONG state, struct PopupMenu *item) +{ +#if 1 +#if !defined(__SASC) +#warning "trying to get rid of global p" +#endif /* !defined(__SASC) */ + struct PM_Root *p = w->p; +#endif + d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__)); + + if (p->MenuImages[type]) + { + int y = item->Top + item->Height/2 - p->MenuImages[type]->Height/2; + if (l < 0) + l += item->Left + item->Width - p->MenuImages[type]->Width; + + d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__)); + DrawImageState(w->RPort, p->MenuImages[type], l, y, state, dri); + + d1(KPrintF("%s/%s/%ld: END(%ld)\n", __FILE__, __FUNC__, __LINE__, p->MenuImages[type]->Width)); + return (UWORD) p->MenuImages[type]->Width; + } + + d1(KPrintF("%s/%s/%ld: END(0)\n", __FILE__, __FUNC__, __LINE__)); + return 0; +} + +UWORD PM_Image_Height(struct PM_Root *p, ULONG type, struct PopupMenu *item) +{ + if (p->MenuImages[type]) + return (UWORD) p->MenuImages[type]->Height; + return 0; +} + +UWORD PM_Image_Width(struct PM_Root *p, ULONG type, struct PopupMenu *item) +{ + if (p->MenuImages[type]) + return (UWORD) p->MenuImages[type]->Width; + return 0; +} diff --git a/scalos/libraries/popupmenu/pmimages.h b/scalos/libraries/popupmenu/pmimages.h new file mode 100644 index 000000000..d13287346 --- /dev/null +++ b/scalos/libraries/popupmenu/pmimages.h @@ -0,0 +1,27 @@ +// pmimages.h +// +// $Date$ +// $Revision$ + +enum { + PMIMG_SUBMENU, + PMIMG_SUBMENU_S, + PMIMG_CHECKMARK, + PMIMG_CHECKMARK_S, + PMIMG_EXCLUDE, + PMIMG_EXCLUDE_S, + PMIMG_AMIGAKEY, + PMIMG_AMIGAKEY_S, + PMIMG_CTRLKEY, + PMIMG_CTRLKEY_S, + PMIMG_MULTISELECT, + PMIMG_MULTISELECT_S, + PMIMG_LAST +}; + +void PM_Image_Allocate(struct PM_Root *p); +void PM_Image_Free(struct PM_Root *p); +UWORD PM_Image_Height(struct PM_Root *p, ULONG type, struct PopupMenu *item); +UWORD PM_Image_Width(struct PM_Root *p, ULONG type, struct PopupMenu *item); +UWORD PM_Image_Draw(struct PM_Window *w, ULONG type, WORD l, struct DrawInfo *dri, ULONG state, struct PopupMenu *item); + diff --git a/scalos/libraries/popupmenu/pminit.c b/scalos/libraries/popupmenu/pminit.c new file mode 100644 index 000000000..380b9c9a4 --- /dev/null +++ b/scalos/libraries/popupmenu/pminit.c @@ -0,0 +1,374 @@ +// +// PopupMenu +// ©1996-2000 Henrik Isaksson +// +// Library init & cleanup +// +// $Date$ +// $Revision$ +// + +#define INIT 1 + +#include "pmpriv.h" + + +// +// Libraries we need +// + +#ifdef __amigaos4__ +#define UTILITYBASE_T struct UtilityBase +#else +#define UTILITYBASE_T struct Library +#endif + +UTILITYBASE_T *UtilityBase=NULL; +struct IntuitionBase *IntuitionBase=NULL; +struct GfxBase *GfxBase=NULL; +struct DosLibrary *DOSBase=NULL; +struct Library *CxBase=NULL; +struct Library *LayersBase=NULL; +struct Library *CyberGfxBase=NULL; +struct Library *PreferencesBase = NULL; + +struct ExecBase *SysBase; + +#ifdef __amigaos4__ +struct Library *NewlibBase; +struct ExecIFace *IExec; +struct Interface *INewlib; +struct UtilityIFace *IUtility; +struct GraphicsIFace *IGraphics; +struct IntuitionIFace *IIntuition; +struct DOSIFace *IDOS; +struct CyberGfxIFace *ICyberGfx; +struct LayersIFace *ILayers; +struct CommoditiesIFace *ICommodities; +struct PreferencesIFace *IPreferences; +#endif + +APTR MemPool = NULL; +struct SignalSemaphore MemPoolSemaphore; + +BOOL V40Gfx=FALSE; +BOOL CyberGfx=FALSE; + +void CloseLibs(void) +{ + if (MemPool) + DeletePool(MemPool); + +#ifdef __amigaos4__ + if (IPreferences) + DropInterface((struct Interface *) IPreferences); + if (IUtility) + DropInterface((struct Interface *)IUtility); + if (IGraphics) + DropInterface((struct Interface *)IGraphics); + if (IIntuition) + DropInterface((struct Interface *)IIntuition); + if (IDOS) + DropInterface((struct Interface *)IDOS); + if (ICommodities) + DropInterface((struct Interface *)ICommodities); + if (ILayers) + DropInterface((struct Interface *)ILayers); + if (ICyberGfx) + DropInterface((struct Interface *)ICyberGfx); + if (INewlib) + DropInterface((struct Interface *)INewlib); + if (NewlibBase) + CloseLibrary((struct Library *)NewlibBase); + + IPreferences = NULL; + IUtility = NULL; + IGraphics = NULL; + IIntuition = NULL; + IDOS = NULL; + ICommodities = NULL; + ILayers = NULL; + ICyberGfx = NULL; + INewlib = NULL; + NewlibBase = NULL; +#endif + + if (PreferencesBase) + CloseLibrary(PreferencesBase); + if (UtilityBase) + CloseLibrary((struct Library *)UtilityBase); + if (GfxBase) + CloseLibrary((struct Library *)GfxBase); + if (IntuitionBase) + CloseLibrary((struct Library *)IntuitionBase); + if (DOSBase) + CloseLibrary((struct Library *)DOSBase); + if (CxBase) + CloseLibrary((struct Library *)CxBase); + if (LayersBase) + CloseLibrary((struct Library *)LayersBase); + if (CyberGfxBase) + CloseLibrary((struct Library *)CyberGfxBase); + + MemPool = NULL; + + PreferencesBase = NULL; + UtilityBase=NULL; + GfxBase=NULL; + IntuitionBase=NULL; + DOSBase=NULL; + CxBase=NULL; + LayersBase=NULL; + CyberGfxBase=NULL; +} + +BOOL OpenLibs(struct PopupMenuBase *l) +{ + BOOL Success = FALSE; + + if (UtilityBase) + return TRUE; + + l->pmb_ExecBase = (struct Library *) SysBase; + + do { +#ifdef __amigaos4__ + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + break;; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + break;; +#endif + + l->pmb_UtilityBase = OpenLibrary("utility.library",37L); + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld pmb_UtilityBase=%08lx\n", __LINE__, l->pmb_UtilityBase)); + if (NULL == l->pmb_UtilityBase) + break;; + + UtilityBase = (UTILITYBASE_T *)l->pmb_UtilityBase; +#ifdef __amigaos4__ + IUtility = (struct UtilityIFace *)GetInterface(l->pmb_UtilityBase, "main", 1, NULL); + if (NULL == IUtility) + break; +#endif + l->pmb_GfxBase = OpenLibrary("graphics.library",40L); + if (!l->pmb_GfxBase) + l->pmb_GfxBase = OpenLibrary("graphics.library",37L); + else + V40Gfx = TRUE; + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld pmb_GfxBase=%08lx\n", __LINE__, l->pmb_GfxBase)); + if (NULL == l->pmb_GfxBase) + break; + + GfxBase = (struct GfxBase *)l->pmb_GfxBase; +#ifdef __amigaos4__ + IGraphics = (struct GraphicsIFace *)GetInterface(l->pmb_GfxBase, "main", 1, NULL); + if (NULL == IGraphics) + break; +#endif + l->pmb_IntuitionBase = OpenLibrary("intuition.library",37L); + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld pmb_IntuitionBase=%08lx\n", __LINE__, l->pmb_IntuitionBase)); + if (NULL == l->pmb_IntuitionBase) + break; + + IntuitionBase = (struct IntuitionBase *)l->pmb_IntuitionBase; +#ifdef __amigaos4__ + IIntuition = (struct IntuitionIFace *)GetInterface(l->pmb_IntuitionBase, "main", 1, NULL); + if (NULL == IIntuition) + break; +#endif + l->pmb_DOSBase = OpenLibrary("dos.library",0L); + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld pmb_DOSBase=%08lx\n", __LINE__, l->pmb_DOSBase)); + if (NULL == l->pmb_DOSBase) + break; + + DOSBase = (struct DosLibrary *)l->pmb_DOSBase; +#ifdef __amigaos4__ + IDOS = (struct DOSIFace *)GetInterface(l->pmb_DOSBase, "main", 1, NULL); + if (NULL == IDOS) + break; +#endif + l->pmb_CxBase = OpenLibrary("commodities.library",37L); + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld pmb_CxBase=%08lx\n", __LINE__, l->pmb_CxBase)); + if (NULL == l->pmb_CxBase) + break; + + CxBase=l->pmb_CxBase; +#ifdef __amigaos4__ + ICommodities = (struct CommoditiesIFace *)GetInterface(l->pmb_CxBase, "main", 1, NULL); + if (NULL == ICommodities) + break; +#endif + LayersBase = OpenLibrary("layers.library",0); + if (NULL == LayersBase) + break; + l->pmb_LayersBase = LayersBase; + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld pmb_LayersBase=%08lx\n", __LINE__, l->pmb_LayersBase)); +#ifdef __amigaos4__ + ILayers = (struct LayersIFace *)GetInterface(l->pmb_LayersBase, "main", 1, NULL); + if (NULL == ILayers) + break; +#endif + PreferencesBase = OpenLibrary("preferences.library", 39); + if (NULL == PreferencesBase) + break; + l->pmb_PreferencesBase = PreferencesBase; + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld pmb_PreferencesBase=%08lx\n", __LINE__, l->pmb_PreferencesBase)); +#ifdef __amigaos4__ + IPreferences = (struct PreferencesIFace *)GetInterface(l->pmb_PreferencesBase, "main", 1, NULL); + if (NULL == IPreferences) + break; +#endif + + CyberGfxBase = OpenLibrary("cybergraphics.library",39L); + if (CyberGfxBase) + { +#ifdef __amigaos4__ + ICyberGfx = (struct CyberGfxIFace *)GetInterface(CyberGfxBase, "main", 1, NULL); + if (NULL == ICyberGfx) + break; +#endif + CyberGfx=TRUE; + } + l->pmb_CyberGfxBase = CyberGfxBase; + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld pmb_CyberGfxBase=%08lx\n", __LINE__, l->pmb_CyberGfxBase)); + + InitSemaphore(&MemPoolSemaphore); + + MemPool = CreatePool(MEMF_PUBLIC | MEMF_CLEAR, 10240L, 10240L); + if (NULL == MemPool) + break; + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld CreatePool OK\n", __LINE__)); + + PM_Prefs_Load(PMP_PATH_OLD, PMP_PATH_NEW); + + Success = TRUE; + } while (0); + + return Success; +} + +// +// Library initializtion +// + +int PMLibInit(struct PopupMenuBase *PopupMenuBase) +{ + d1(KPrintF(__FUNC__ "/%ld: START PopupMenuBase=%08lx\n", __LINE__, PopupMenuBase)); + + if (OpenLibs(PopupMenuBase)) + { + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld success\n", __LINE__)); + return -1; + } + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld fail\n", __LINE__)); + + return 0; +} + +void PMLibCleanup(struct PopupMenuBase *l) +{ + + //kprintf("UserLibCleanUp, pmbase = %08lx\n", l); + + //PM_FreeAllImages(); + + PM_Prefs_Free(); + + //CloseLibs(); + + if (MemPool) + DeletePool(MemPool); + + if (PreferencesBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)IPreferences); +#endif + CloseLibrary(PreferencesBase); + } + if (UtilityBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)IUtility); +#endif + CloseLibrary((struct Library *)UtilityBase); + } + if (GfxBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)IGraphics); +#endif + CloseLibrary((struct Library *)GfxBase); + } + if (IntuitionBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)IUtility); +#endif + CloseLibrary((struct Library *)UtilityBase); + } + if (l->pmb_DOSBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)IDOS); +#endif + CloseLibrary((struct Library *)l->pmb_DOSBase); + } + if (CxBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)ICommodities); +#endif + CloseLibrary((struct Library *)CxBase); + } + if (LayersBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)ILayers); +#endif + CloseLibrary((struct Library *)LayersBase); + } + if (CyberGfxBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)ICyberGfx); +#endif + CloseLibrary((struct Library *)CyberGfxBase); + } + + //kprintf("UserLibCleanUp done.\n"); +} + +#ifdef __AROS__ +#include +#include + +AROS_SET_LIBFUNC(AROS__UserLibInit, struct PopupMenuBase, PopupMenuBase) +{ + AROS_SET_LIBFUNC_INIT + + return (__UserLibInit(PopupMenuBase) == 0) ? TRUE : FALSE; + + AROS_SET_LIBFUNC_EXIT +} + +AROS_SET_LIBFUNC(AROS__UserLibCleanup, struct PopupMenuBase, PopupMenuBase) +{ + AROS_SET_LIBFUNC_INIT + + __UserLibCleanup(PopupMenuBase); + + return TRUE; + + AROS_SET_LIBFUNC_EXIT +} + +ADD2INITLIB(AROS__UserLibInit, 0); +ADD2EXPUNGELIB(AROS__UserLibCleanup, 0); +#endif + diff --git a/scalos/libraries/popupmenu/pminput.c b/scalos/libraries/popupmenu/pminput.c new file mode 100644 index 000000000..192cef217 --- /dev/null +++ b/scalos/libraries/popupmenu/pminput.c @@ -0,0 +1,238 @@ +// +// PopupMenu +// ©1996-2002 Henrik Isaksson +// +// User Input & timer +// +// $Date$ +// $Revision$ +// + +#include "pmpriv.h" +#include "pminput.h" + +// +// Input Handler +// + +/// Input handler +M68KFUNC_P2(struct InputEvent *, myhandler, + A0, struct InputEvent *, ev, + A1, struct MsgPort *, port) +{ + struct InputEvent *evnt = ev; + + do { + if (evnt->ie_Class == IECLASS_RAWKEY) { + struct PM_InpMsg *m; + + m = PM_Mem_Alloc(sizeof(struct PM_InpMsg)); + if (m) { + m->msg.mn_Length = sizeof(struct PM_InpMsg); + m->msg.mn_ReplyPort = NULL; + m->Kind = 0; + switch(evnt->ie_Code) { + case 208: + case 0x45: + m->Kind = PM_MSG_TERMINATE; + break; + case 0x4c: + m->Kind = PM_MSG_UP; + break; + case 0x4d: + m->Kind = PM_MSG_DOWN; + break; + case 0x4e: + m->Kind = PM_MSG_OPENSUB; + break; + case 0x4f: + m->Kind = PM_MSG_CLOSESUB; + break; + case 0x44: + case 0x43: + m->Kind = PM_MSG_SELECT; + break; + case 0x40: + m->Kind = PM_MSG_MULTISELECT; + break; + case 0x50: + m->Kind = PM_MSG_DEBUGINFO; + break; + } + if (m->Kind) PutMsg(port, (struct Message *)m); + else PM_Mem_Free(m); + } + evnt->ie_Class = 0; + } + if (evnt->ie_Class == IECLASS_TIMER) { + struct PM_InpMsg *m; + + m = PM_Mem_Alloc(sizeof(struct PM_InpMsg)); + if (m) { + m->msg.mn_Length = sizeof(struct PM_InpMsg); + m->msg.mn_ReplyPort = NULL; + m->Kind = PM_MSG_TIMER; + PutMsg(port, (struct Message *)m); + } + } + if (evnt->ie_Class == IECLASS_RAWMOUSE) { + struct PM_InpMsg *m; + + m = PM_Mem_Alloc(sizeof(struct PM_InpMsg)); + if (m) { + m->msg.mn_Length = sizeof(struct PM_InpMsg); + m->msg.mn_ReplyPort = NULL; + m->Kind = PM_MSG_RAWMOUSE; + m->Code = evnt->ie_Code; + m->Qual = evnt->ie_Qualifier; + PutMsg(port, (struct Message *)m); + } + + evnt->ie_Code = IECODE_NOBUTTON; + } + evnt = evnt->ie_NextEvent; + } while (evnt); + + return ev; +} +M68KFUNC_END +/// + +/// handlername +static char handlername[] = "PM Input Handler"; +/// + +#ifdef __AROS__ +AROS_UFH2(struct InputEvent *, myhandler_aros, + AROS_UFHA(struct InputEvent *, ev, A0), + AROS_UFHA(struct MsgPort *, port, A1)) +{ + AROS_USERFUNC_INIT + + return myhandler(ev, port); + + AROS_USERFUNC_EXIT +} +#define HANDLER_CODE (APTR)AROS_ASMSYMNAME(myhandler_aros) +#else +#define HANDLER_CODE (void *)myhandler +#endif + + +/// Install handler +struct PM_InputHandler *PM_InstallHandler(int pri) +{ + struct PM_InputHandler *pmh; + STATIC_PATCHFUNC(myhandler) + + pmh = PM_Mem_Alloc(sizeof(struct PM_InputHandler)); + if (pmh) { + pmh->mp = CreatePort(0,0); + if (pmh->mp) { + pmh->port = CreatePort(0,0); + if (pmh->port) { + pmh->ior = CreateStdIO(pmh->mp); + if (pmh->ior) { + pmh->error = OpenDevice("input.device",0,(struct IORequest *)pmh->ior,0); + if (!pmh->error) { + pmh->intr.is_Data = (APTR)pmh->port; + pmh->intr.is_Code = (VOID (*)()) PATCH_NEWFUNC(myhandler); + pmh->intr.is_Node.ln_Pri = pri; + pmh->intr.is_Node.ln_Name = handlername; + + pmh->ior->io_Command = IND_ADDHANDLER; + pmh->ior->io_Data = (APTR)&pmh->intr; + pmh->ior->io_Message.mn_ReplyPort = pmh->mp; + + DoIO((struct IORequest *)pmh->ior); + + } + } + } + } + + } + + return pmh; +} +/// + +/// Remove handler +void PM_RemoveHandler(struct PM_InputHandler *pmh) +{ + struct PM_InpMsg *msg; + + if (pmh->mp) { + if (pmh->port) { + if (pmh->ior) { + if (!pmh->error) { + pmh->ior->io_Command = IND_REMHANDLER; + pmh->ior->io_Data = (APTR)&pmh->intr; + DoIO((struct IORequest *)pmh->ior); + + CloseDevice((struct IORequest *)pmh->ior); + } + DeleteStdIO(pmh->ior); + } + while ((msg = (struct PM_InpMsg *)GetMsg(pmh->port))) { + PM_Mem_Free(msg); + } + DeletePort(pmh->port); + } + DeletePort(pmh->mp); + } + PM_Mem_Free(pmh); +} +/// + +// +// Timer +// + +/// Timer functions +// +// timer funcs +// + +void EZDeleteTimer(T_TIMEREQUEST *TimeRequest) +{ + struct MsgPort *TimePort; + + if (TimeRequest) + { + if (TimeRequest->tr_node.io_Device) + CloseDevice((struct IORequest *)TimeRequest); + + if ((TimePort = TimeRequest->tr_node.io_Message.mn_ReplyPort)) + DeletePort(TimePort); + + DeleteExtIO((struct IORequest *)TimeRequest); + } +} + +T_TIMEREQUEST *EZCreateTimer(LONG Unit) +{ + struct MsgPort *TimePort; + T_TIMEREQUEST *TimeRequest; + + if (!(TimePort = (struct MsgPort *)CreatePort(NULL,0))) + return(NULL); + + if (!(TimeRequest = (T_TIMEREQUEST *)CreateExtIO(TimePort,sizeof(T_TIMEREQUEST)))) + { + DeletePort(TimePort); + + return(NULL); + } + + if (OpenDevice(TIMERNAME, Unit, (struct IORequest *)TimeRequest, 0)) + { + DeleteExtIO((struct IORequest *)TimeRequest); + DeletePort(TimePort); + + return(NULL); + } + + return(TimeRequest); +} +/// diff --git a/scalos/libraries/popupmenu/pminput.h b/scalos/libraries/popupmenu/pminput.h new file mode 100644 index 000000000..4c1aa081c --- /dev/null +++ b/scalos/libraries/popupmenu/pminput.h @@ -0,0 +1,36 @@ +#ifndef PM_INPUT_H +#define PM_INPUT_H + +#define PM_MSG_TIMER 1 +#define PM_MSG_RAWMOUSE 2 +#define PM_MSG_DOWN 3 +#define PM_MSG_UP 4 +#define PM_MSG_SELECT 5 +#define PM_MSG_MULTISELECT 6 +#define PM_MSG_TERMINATE 7 +#define PM_MSG_OPENSUB 8 +#define PM_MSG_CLOSESUB 9 +#define PM_MSG_DEBUGINFO 10 + +struct PM_InpMsg { + struct Message msg; // Message struct + UWORD Kind; // Kind of message + UWORD Code; // InputEvent code + UWORD Qual; // Qualifier + UWORD Res; // Reserved + +}; + +struct PM_InputHandler { + struct MsgPort *mp; // Replyport + struct MsgPort *port; // Port for input events + struct IOStdReq *ior; // IO Request + struct Interrupt intr; // Interrupt structure + int error; // OpenDevice error +}; + +void PM_RemoveHandler(struct PM_InputHandler *pmh); +struct PM_InputHandler *PM_InstallHandler(int pri); + +#endif + diff --git a/scalos/libraries/popupmenu/pminternals.h b/scalos/libraries/popupmenu/pminternals.h new file mode 100644 index 000000000..1b1dccede --- /dev/null +++ b/scalos/libraries/popupmenu/pminternals.h @@ -0,0 +1,65 @@ +/* +// $VER: pminternals.h 10.00 (9.11.00) +// +// Internal structures used by popupmenu.library +// +// ©1996-2000 Henrik Isaksson +// All Rights Reserved. +// +// Changes: +// +// 10.00 Initial version +// +// *WARNING* +// +// Everything in this file is subject to change. +// +// $Date$ +// $Revision$ +*/ + +#ifndef LIBRARIES_PMINTERNALS_H +#define LIBRARIES_PMINTERNALS_H + +/* +// Flags +*/ +#define NPM_HBAR_BIT 0x00000001 /* Draw a horizontal bar */ +#define NPM_NOSELECT 0x00000002 /* Make this item unselectable. */ +#define NPM_WIDE_BAR_BIT 0x00000004 /* Almost same as NPM_HBAR_BIT, but wider */ +#define NPM_UDATASTRING 0x00000008 /* FreeVec(UserData) when menu is freed */ +#define NPM_HIDDEN 0x00000010 /* Hidden */ +#define NPM_SELECTABLE 0x00000020 /* Item with SubMenu is selectable */ +#define NPM_GROUP 0x00000040 /* Group */ +#define NPM_EXCLUDE_SHARED 0x00000080 /* Don't free exclude list */ +#define NPM_FIXEDSIZE 0x00000100 /* Fixed size */ +#define NPM_ISIMAGE 0x00000200 /* This item has an image not an icon */ +#define NPM_OUTLINED 0x00000400 /* Outline text */ +#define NPM_HILITETEXT 0x00000800 /* Highlight Text */ +#define NPM_FILLTEXT 0x00001000 /* */ +#define NPM_SHADOWTEXT 0x00002000 /* */ +#define NPM_SHINETEXT 0x00004000 /* */ +#define NPM_BOLDTEXT 0x00008000 /* Bold text */ +#define NPM_ITALICTEXT 0x00010000 /* Italic text */ +#define NPM_UNDERLINEDTEXT 0x00020000 /* Underline text */ +#define NPM_EMBOSSED 0x00040000 /* Emboss text */ +#define NPM_DISABLED 0x00080000 /* Ghosted text */ +#define NPM_CUSTOMPEN 0x00100000 /* Use custom pen */ +#define NPM_SHADOWED 0x00200000 /* Shadowed text */ +#define NPM_CENTRED 0x00400000 /* Centred text */ +#define NPM_ISSELECTED 0x00800000 /* This item has been selected this time */ +#define NPM_NOTOGGLE 0x01000000 /* Don't un-check checked checkmarks... =) */ +#define NPM_ICONISID 0x02000000 /* FREE */ +#define NPM_COLOURBOX 0x04000000 /* Colour box */ +#define NPM_INITIAL_CHECKED 0x08000000 /* Checked when menu opened */ +#define NPM_FREE03 0x10000000 /* FREE */ +#define NPM_MINSIZE 0x20000000 /* Minimum size = fixed size */ +#define NPM_CHECKIT 0x40000000 /* Space for checkmark */ +#define NPM_CHECKED 0x80000000 /* Checkmark */ +#define NPM_WIDE_BAR (NPM_WIDE_BAR_BIT|NPM_NOSELECT) // Same as NPM_HBAR but it covers the whole window +#define NPM_HBAR (NPM_HBAR_BIT|NPM_NOSELECT) // Horizontal bar. + +#define NPM_CENTERED NPM_CENTRED +#define NPM_COLORBOX NPM_COLOURBOX + +#endif /* LIBRARIES_PMINTERNALS_H */ diff --git a/scalos/libraries/popupmenu/pmlayout.c b/scalos/libraries/popupmenu/pmlayout.c new file mode 100644 index 000000000..ae7ab4d9b --- /dev/null +++ b/scalos/libraries/popupmenu/pmlayout.c @@ -0,0 +1,504 @@ +// +// PopupMenu +// ©1996-2000 Henrik Isaksson +// +// Menu Item Layout +// +// $Date$ +// $Revision$ +// + +#include "pmpriv.h" + +UWORD PM_ItemHeight(struct PM_Window *a, struct PopupMenu *pm) +{ + UWORD r,fonty=a->p->MenuFont->tf_YSize; + + if (pm->Flags&NPM_HBAR_BIT) + { + r=(UWORD)(PM_Prefs->pmp_YSpace*2+5); + pm->Flags|=NPM_FIXEDSIZE; + } + else if (pm->Flags&NPM_WIDE_BAR_BIT) + { + r=(UWORD)(PM_Prefs->pmp_YOffset*2+5); + pm->Flags|=NPM_FIXEDSIZE; + } + else + { + r=(UWORD)(fonty+1); + + if (pm->ImageUnion.Images[0]) + { + if (pm->ImageUnion.Images[0]->Height>r) + r=(UWORD)pm->ImageUnion.Images[0]->Height+1; + } + if (pm->ImageUnion.Images[1]) + { + if (pm->ImageUnion.Images[1]->Height>r) + r=(UWORD)pm->ImageUnion.Images[1]->Height+1; + } + + if (pm->SubGroup.Sub) + { + UBYTE x=PM_Image_Height(a->p, PMIMG_SUBMENU, pm); + if (x>r) r=x; + } + else if (pm->Flags&NPM_CHECKIT) + { + UBYTE x=PM_Image_Height(a->p, pm->Exclude?PMIMG_EXCLUDE:PMIMG_CHECKMARK, pm); + if (x>r) r=x; + } + if (pm->CommKey!=0) + { + UBYTE x=PM_Image_Height(a->p, PMIMG_AMIGAKEY, pm); + if (x>r) r=x; + } + + r+=(UWORD)PM_Prefs->pmp_YSpace*2; // *2 + } + + return r; +} + +UWORD PM_ItemWidth(struct PM_Window *a, struct PopupMenu *pm) +{ + UWORD tmp=0,img=0, icn, fontx; + struct RastPort tmprp; + + fontx=a->p->MenuFont->tf_XSize; + CopyMem(a->p->RootWnd->RPort, &tmprp, sizeof(struct RastPort)); + tmprp.Font=a->p->MenuFont; + + if (pm->TitleUnion.Title) + { + if (GET_TXTMODE(pm)==NPX_TXTBOOPSI) + { + } + else + { + STRPTR title=pm->TitleUnion.Title; + + if (GET_TXTMODE(pm)==NPX_TXTLOCALE) + title=(STRPTR)CallHook(a->p->LocaleHook, (Object *)pm, pm->TitleUnion.TitleID, 123); + + if (title) + tmp=TextLength(&tmprp,title,strlen(title)); + } + } + + if (pm->Flags&NPM_CHECKIT) + { + tmp+=PM_Image_Width(a->p, pm->Exclude?PMIMG_EXCLUDE:PMIMG_CHECKMARK, pm); + tmp+=PM_Prefs->pmp_Intermediate; + } + else if (pm->SubGroup.Sub && (a->p->PullDown==0) && (pm->Layout==0)) + { + tmp+=PM_Image_Width(a->p, PMIMG_SUBMENU, pm); + tmp+=PM_Prefs->pmp_Intermediate; + } + + if (pm->CommKey!=0) + { + tmp+=PM_Image_Width(a->p, PMIMG_AMIGAKEY, pm); + tmp+=PM_Prefs->pmp_Intermediate+fontx*4; + } + + if (pm->Flags&NPM_ISIMAGE) + { + if (pm->ImageUnion.Images[0]) + img=pm->ImageUnion.Images[0]->Width; + if (pm->ImageUnion.Images[1]) + if (pm->ImageUnion.Images[1]->Width>img) + img=pm->ImageUnion.Images[1]->Width; + + if (img>tmp) + tmp=img; + } + else + { + struct Image *img=pm->ImageUnion.Images[0]; + + // Hitta den största + + if (!img) + { + img=pm->ImageUnion.Images[1]; + } + else if (pm->ImageUnion.Images[1]) + { + if (img->WidthImageUnion.Images[1]->Width) + img=pm->ImageUnion.Images[1]; + } + if (img) + { + tmp+=PM_Prefs->pmp_Intermediate; + + icn=img->Width+PM_Prefs->pmp_Intermediate; + + if (icn>a->IconColumn) + a->IconColumn=icn; + } + } + + if (pm->Flags&NPM_COLOURBOX) + { + if (!tmp) + { // If there's no other stuff in the item, no intermediate spacing is req'd + tmp+=fontx*3; + tmp-=PM_Prefs->pmp_XSpace+2; // Must be like this for some unknow reason... + } + else + { + tmp+=PM_Prefs->pmp_Intermediate+fontx*3; + } + } + + tmp+=PM_Prefs->pmp_XSpace*2; // "Horizontal spacing" + tmp+=2; // Item border + + return (UWORD)(tmp); +} + + +void PM_CalcItemSize(struct PM_Window *a, struct PopupMenu *pm) +{ + UWORD tmpw, tmph; + struct PopupMenu *p; + + pm->Width=0; + pm->Height=0; + + if (pm->Flags & NPM_HIDDEN) { + return; + } + + if (pm->Flags & NPM_GROUP) { + // + // Calculate minimum size for each item. + // Calculate total size for the group. + // + + p=pm->SubGroup.Sub; + tmpw=1; + tmph=1; + if (p) do { + PM_CalcItemSize(a, p); + + if (!(p->Flags & NPM_HIDDEN)) { + if (pm->Layout==PML_Vertical) { + tmph+=p->Height; + if (p->Width>tmpw) tmpw=p->Width; + } + + if (pm->Layout==PML_Horizontal) { + tmpw+=p->Width; + if (p->Height>tmph) tmph=p->Height; + } + + } + + p=p->Next; + } while (p); + } else { + struct PopupMenu *tmppm; + + BOOL patched=FALSE; + + tmppm=pm; + + if (pm->Next) { + if ((tmppm->Flags&NPM_NOSELECT) && (tmppm->Flags&NPM_SHADOWED) && !(tmppm->Flags&NPM_DISABLED) && (tmppm->Next->Flags&NPM_WIDE_BAR)) { + //PATCH(TP_CENTER, NPM_CENTERED); + + PATCH(PMP_TITLE_UNDERLINE, NPM_UNDERLINEDTEXT); + PATCH(PMP_TITLE_BOLD, NPM_BOLDTEXT); + PATCH(PMP_TITLE_SHADOW, NPM_SHADOWED); + PATCH(PMP_TITLE_EMBOSS, NPM_EMBOSSED); + PATCH(PMP_TITLE_OUTLINE, NPM_OUTLINED); + + //PATCH(TP_SHINE, NPM_SHINETEXT); + //PATCH(TP_SHADOW, NPM_SHADOWTEXT); + //PATCH(TP_HILITE, NPM_HILITETEXT); + + patched=TRUE; + } + } + + + if (!patched) { + //TPATCH(TP_CENTER, NPM_CENTERED); + + TPATCH(PMP_TEXT_UNDERLINE, NPM_UNDERLINEDTEXT); + TPATCH(PMP_TEXT_BOLD, NPM_BOLDTEXT); + TPATCH(PMP_TEXT_SHADOW, NPM_SHADOWED); + TPATCH(PMP_TEXT_EMBOSS, NPM_EMBOSSED); + TPATCH(PMP_TEXT_OUTLINE, NPM_OUTLINED); + + //TPATCH(TP_SHINE, NPM_SHINETEXT); + //TPATCH(TP_SHADOW, NPM_SHADOWTEXT); + //TPATCH(TP_HILITE, NPM_HILITETEXT); + } + + tmph=PM_ItemHeight(a, pm); + tmpw=PM_ItemWidth(a, pm); + } + + pm->Height=tmph; + pm->Width=tmpw; +} + +void PM_LayoutGroup(struct PM_Window *a, struct PopupMenu *pm) +{ + UWORD tw, t, l, tsz, tmp; + struct PopupMenu *p; + BOOL restart; + + // Is this a group? If not, return. + + if (!(pm->Flags & NPM_GROUP)) + return; + + // Set up group offset + + l=pm->Left; + t=pm->Top; + + switch(pm->Layout) { + case PML_Vertical: + // + // Step 1. Calculate total weight. + // Hidden items and fixed size items are to be excluded from + // the size distribution, so they must be excluded from weight + // calculation aswell. + // + tw=0; + p=pm->SubGroup.Sub; + while (p) { + p->Flags&=~NPM_MINSIZE; + if (!(p->Flags & NPM_HIDDEN) && !(p->Flags&NPM_FIXEDSIZE)) { + tw++; + } + p=p->Next; + } + + //kprintf("\n\nLAYOUT: Start. Maximum vertical size %ld\n", pm->Height); + + //kprintf("LAYOUT: Initial vertical weight %ld\n", tw); + + // + // Step 2. Find the items whose size is larger than what they + // would normally get if the available size was distributed + // equally. + // + + do { + restart=FALSE; + + // First we have to exclude fixed size items, and items that + // require more space than what equal distribution would + // result in. + tsz=pm->Height; + p=pm->SubGroup.Sub; + while (p) { + if (!(p->Flags & NPM_HIDDEN) && (p->Flags&NPM_FIXEDSIZE || p->Flags&NPM_MINSIZE)) + tsz-=p->Height; + p=p->Next; + } + + // Then we scan through the other items for those who require + // more space, and mark them with NPM_MINSIZE for exclusion + // in the loop above. + // If one, or more such items are found, we must repeat these + // steps once more, until there are no more such items left. + // (Until all remaining items can share the available space + // equally) + p=pm->SubGroup.Sub; + while (p) { + if (!(p->Flags & NPM_HIDDEN)) { + if (!(p->Flags & NPM_FIXEDSIZE) && !(p->Flags & NPM_MINSIZE)) { + if (tw) tmp=tsz/tw; + else tmp=0; + + if (tmpHeight) { + p->Flags|=NPM_MINSIZE; + //kprintf("LAYOUT: Removed item %s (%ld > %ld)\n", p->Title, p->Height, tmp); + tw--; + restart=TRUE; + //break; // optimization, will require less looping + } + } + } + + p=p->Next; + } + } while (restart); + + //kprintf("LAYOUT: Remaining vertical size %ld\n", tsz); + //kprintf("LAYOUT: Remaining vertical weight %ld\n", tw); + + // + // Step 3. Distribute the remaining size among the remaining items + // and position all items. + // + + p=pm->SubGroup.Sub; + while (p) { + + p->Width=pm->Width; + + if (!(p->Flags & NPM_HIDDEN) && !(p->Flags&NPM_FIXEDSIZE) && !(p->Flags&NPM_MINSIZE)) { + if (tw) { + p->Height=tsz/tw; // Assign height + + tsz-=p->Height; // This will avoid leaving an empty space at the end of a group, + tw--; // due to precision limitations when dividing integers. + } + } + + p->Left=l; // Set item's + p->Top=t; // position + + PM_LayoutGroup(a, p); // If this item is a group, layout will be handled here. + + t+=p->Height; + p=p->Next; + } + break; + case PML_Horizontal: + // + // See PML_Vertical for explanations. + // + tw=0; + p=pm->SubGroup.Sub; + while (p) { + p->Flags&=~NPM_MINSIZE; + if (!(p->Flags & NPM_HIDDEN) && !(p->Flags&NPM_FIXEDSIZE)) { + tw++; + } + p=p->Next; + } + + do { + restart=FALSE; + + tsz=pm->Width; + p=pm->SubGroup.Sub; + while (p) { + if (!(p->Flags & NPM_HIDDEN) && (p->Flags&NPM_FIXEDSIZE || p->Flags&NPM_MINSIZE)) + tsz-=p->Width; + p=p->Next; + } + + p=pm->SubGroup.Sub; + while (p) { + if (!(p->Flags & NPM_HIDDEN)) { + if (!(p->Flags & NPM_FIXEDSIZE) && !(p->Flags & NPM_MINSIZE)) { + if (tw) tmp=tsz/tw; + else tmp=0; + + if (tmpWidth) { + p->Flags|=NPM_MINSIZE; + tw--; + restart=TRUE; + } + } + } + + p=p->Next; + } + } while (restart); + + p=pm->SubGroup.Sub; + while (p) { + + p->Height=pm->Height; + + if (!(p->Flags & NPM_HIDDEN) && !(p->Flags&NPM_FIXEDSIZE) && !(p->Flags&NPM_MINSIZE)) { + if (tw) { + p->Width=tsz/tw; // Assign height + + tsz-=p->Width; // This will avoid leaving an empty space at the end of a group, + tw--; // due to precision limitations when dividing integers. + } + } + + p->Left=l; // Set item's + p->Top=t; // position + + PM_LayoutGroup(a, p); // If this item is a group, layout will be handled here. + + l+=p->Width; + p=p->Next; + } + break; + case PML_Table: + break; + } +} + +void PMPM_LayoutMenu(struct PM_Window *a) +{ + BOOL wb=PM_Prefs->pmp_PulldownPos==PMP_PD_WINDOWBAR; + + + // Calculate Item and Group sizes + + PM_CalcItemSize(a, &a->PM); + a->PM.Width+=a->IconColumn; + + // Set offsets + + a->PM.Left=PM_Prefs->pmp_XOffset+a->p->BorderWidth; + a->PM.Top=PM_Prefs->pmp_YOffset+a->p->BorderHeight; + + // Adjust for pulldowns + + if (a->p->PullDown) { + + if (a->p->RootWnd->BorderTop<10) wb=FALSE; + + a->PM.Left=1; + a->PM.Top=1; + + if (wb) { + a->PM.Height=a->p->RootWnd->BorderTop - 3; + } + + if (!wb) { + a->PM.Height=a->p->RootWnd->WScreen->BarHeight - 2; + } + } + + // Layout groups + + PM_LayoutGroup(a, &a->PM); + + // Set size of window + + a->Height=a->PM.Height + (PM_Prefs->pmp_YOffset+a->p->BorderHeight)*2+1; + a->Width=a->PM.Width + (PM_Prefs->pmp_XOffset+a->p->BorderWidth)*2+1; + + // Adjust for pulldowns + + if (a->p->PullDown) { + + if (wb) { + a->Height=a->p->RootWnd->BorderTop; + } + + if (!wb) { + a->Height=a->p->RootWnd->WScreen->BarHeight+1; + } + + if (wb) { + a->Width+=2; // 2 * borderwidth + if (a->Widthp->RootWnd->Width-1) { + a->Width=a->p->RootWnd->Width-1; + } + } else { + a->Width=a->p->RootWnd->WScreen->Width-1; + } + } +} + diff --git a/scalos/libraries/popupmenu/pmmem.c b/scalos/libraries/popupmenu/pmmem.c new file mode 100644 index 000000000..a45f11fa4 --- /dev/null +++ b/scalos/libraries/popupmenu/pmmem.c @@ -0,0 +1,110 @@ +// +// pmmem.h +// +// $Date$ +// $Revision$ +// + +#include "pmpriv.h" +#include "pmmem.h" + +APTR PM_AllocVecPooled(size_t size) +{ + APTR ptr; + + if (MemPool) + { + ObtainSemaphore(&MemPoolSemaphore); + ptr = AllocPooled(MemPool, size + sizeof(size_t)); + ReleaseSemaphore(&MemPoolSemaphore); + if (ptr) + { + size_t *sptr = (size_t *) ptr; + + sptr[0] = size; + + d1(kprintf(__FILE__ "/%s/%ld: MemPool=%08lx Size=%lu mem=%08lx\n", + __FUNC__, __LINE__, MemPool, size, &sptr[1])); + return (APTR)(&sptr[1]); + } + } + + d1(kprintf(__FILE__ "/%s/%ld: MemPool=%08lx Size=%lu\n", __FUNC__, __LINE__, MemPool, size)); + + return NULL; +} + +void PM_FreeVecPooled(APTR mem) +{ + d1(kprintf(__FUNC__ "/%ld: MemPool=%08lx mem=%08lx\n", __LINE__, MemPool, mem)); + if (MemPool && mem) + { + size_t size; + size_t *sptr = (size_t *) mem; + + mem = &sptr[-1]; + size = sptr[-1]; + + d1(kprintf(__FILE__ "/%s/%ld: MemPool=%08lx size=%lu mem=%08lx\n", + __FUNC__, __LINE__, MemPool, size, &sptr[1])); + + ObtainSemaphore(&MemPoolSemaphore); + FreePooled(MemPool, mem, size + sizeof(size_t)); + ReleaseSemaphore(&MemPoolSemaphore); + } +} + +ULONG PM_String_Length(STRPTR s) +{ + ULONG r=(ULONG)s; + + while (*s++); + + return ((ULONG)s)-r; +} + +STRPTR PM_String_Copy(STRPTR Source, STRPTR Dest, LONG Len) +{ + if (Len==-1) + { + while (*Source) + *Dest++=*Source++; + *Dest++=0; + return Dest; + } + else + { + LONG ctr=0; + + while (ctr +#define PM_Mem_Alloc(size) PM_AllocVecPooled(size) +#define PM_Mem_Free(mem) PM_FreeVecPooled(mem) +#define PM_Mem_Copy(s, d, l) CopyMem(s, d, l) + +STRPTR PM_String_Copy(STRPTR Source, STRPTR Dest, LONG Len); +ULONG PM_String_Length(STRPTR s); +ULONG PM_String_Compare(STRPTR str1, STRPTR str2); +void PM_StrCat(STRPTR Dst, STRPTR Src); + +APTR PM_AllocVecPooled(size_t size); +void PM_FreeVecPooled(APTR mem); + +#endif /* PM_MEM_H */ diff --git a/scalos/libraries/popupmenu/pmprefs.c b/scalos/libraries/popupmenu/pmprefs.c new file mode 100644 index 000000000..c168daeef --- /dev/null +++ b/scalos/libraries/popupmenu/pmprefs.c @@ -0,0 +1,177 @@ +// pmprefs.c +// +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include "pmprefs.h" + +//#ifdef __AROS__ +#include "pmpriv.h" +void PM_LoadPrefsFile(CONST_STRPTR filename, ULONG flags, + struct oldPopupMenuPrefs *prefs, const struct oldPopupMenuPrefs *defprefs); +//#endif + +static struct PopupMenuPrefs DefaultPrefs = + { + PMP_FLAGS_SHADOWS, /* pmp_Flags */ + 0, /* pmp_SubMenuDelay */ + PMP_ANIM_NONE, /* pmp_Animation */ + PMP_PD_SCREENBAR, /* pmp_PulldownPos */ + FALSE, /* pmp_Sticky */ + 0, /* pmp_MenuBorder */ + 0, /* pmp_SelItemBorder */ + 0, /* pmp_SeparatorBar */ + 0, /* pmp_MenuTitles */ + 0, /* pmp_MenuItems */ + 2, /* pmp_XOffset */ + 2, /* pmp_YOffset */ + 2, /* pmp_XSpace */ + 2, /* pmp_YSpace */ + 2, /* pmp_Intermediate */ + 0, /* pmp_TextDisplace */ + 0, /* pmp_TransparencyBlur */ + }; + +struct PopupMenuPrefs *PM_Prefs = &DefaultPrefs; + + +static void ConvertPmPrefs(CONST_STRPTR prefsFileOld, CONST_STRPTR prefsFileNew); + + +void PM_Prefs_Free(void) +{ +} + +void PM_Prefs_Load(CONST_STRPTR prefsFileOld, CONST_STRPTR prefsFileNew) +{ + static struct PopupMenuPrefs pmPrefs; + APTR myPrefsHandle; + + ConvertPmPrefs(prefsFileOld, prefsFileNew); + + myPrefsHandle = AllocPrefsHandle("PopupMenuPrefs"); + if (myPrefsHandle) + { + LONG lID = MAKE_ID('M', 'A', 'I', 'N'); + + ReadPrefsHandle(myPrefsHandle, prefsFileNew); + + GetPreferences(myPrefsHandle, lID, PMP_Flags, &pmPrefs.pmp_Flags, sizeof(pmPrefs.pmp_Flags) ); + GetPreferences(myPrefsHandle, lID, PMP_SubMenuDelay, &pmPrefs.pmp_SubMenuDelay, sizeof(pmPrefs.pmp_SubMenuDelay) ); + GetPreferences(myPrefsHandle, lID, PMP_AnimationType, &pmPrefs.pmp_Animation, sizeof(pmPrefs.pmp_Animation) ); + GetPreferences(myPrefsHandle, lID, PMP_PullDownMenuPos, &pmPrefs.pmp_PulldownPos, sizeof(pmPrefs.pmp_PulldownPos) ); + GetPreferences(myPrefsHandle, lID, PMP_Sticky, &pmPrefs.pmp_Sticky, sizeof(pmPrefs.pmp_Sticky) ); + GetPreferences(myPrefsHandle, lID, PMP_MenuBorderType, &pmPrefs.pmp_MenuBorder, sizeof(pmPrefs.pmp_MenuBorder) ); + GetPreferences(myPrefsHandle, lID, PMP_SelItemBorderType, &pmPrefs.pmp_SelItemBorder, sizeof(pmPrefs.pmp_SelItemBorder) ); + GetPreferences(myPrefsHandle, lID, PMP_SeparatorBarStyle, &pmPrefs.pmp_SeparatorBar, sizeof(pmPrefs.pmp_SeparatorBar) ); + GetPreferences(myPrefsHandle, lID, PMP_XOffset, &pmPrefs.pmp_XOffset, sizeof(pmPrefs.pmp_XOffset) ); + GetPreferences(myPrefsHandle, lID, PMP_YOffset, &pmPrefs.pmp_YOffset, sizeof(pmPrefs.pmp_YOffset) ); + GetPreferences(myPrefsHandle, lID, PMP_XSpace, &pmPrefs.pmp_XSpace, sizeof(pmPrefs.pmp_XSpace) ); + GetPreferences(myPrefsHandle, lID, PMP_YSpace, &pmPrefs.pmp_YSpace, sizeof(pmPrefs.pmp_YSpace) ); + GetPreferences(myPrefsHandle, lID, PMP_Intermediate, &pmPrefs.pmp_Intermediate, sizeof(pmPrefs.pmp_Intermediate) ); + GetPreferences(myPrefsHandle, lID, PMP_TransparencyBlur, &pmPrefs.pmp_TransparencyBlur, sizeof(pmPrefs.pmp_TransparencyBlur) ); + GetPreferences(myPrefsHandle, lID, PMP_TextDisplace, &pmPrefs.pmp_TextDisplace, sizeof(pmPrefs.pmp_TextDisplace) ); + GetPreferences(myPrefsHandle, lID, PMP_MenuTitleStyle, &pmPrefs.pmp_MenuTitles, sizeof(pmPrefs.pmp_MenuTitles) ); + GetPreferences(myPrefsHandle, lID, PMP_MenuItemStyle, &pmPrefs.pmp_MenuItems, sizeof(pmPrefs.pmp_MenuItems) ); + + FreePrefsHandle(myPrefsHandle); + } + + PM_Prefs = &pmPrefs; +} + +LIBFUNC_P1(void, LIBPM_ReloadPrefs, + A6, struct PopupMenuBase *, l) +{ + (void) l; + + PM_Prefs_Free(); + PM_Prefs_Load(PMP_PATH_OLD, PMP_PATH_NEW); +} +LIBFUNC_END + + +static void ConvertPmPrefs(CONST_STRPTR prefsFileOld, CONST_STRPTR prefsFileNew) +{ + BPTR fLock; + + fLock = Lock(prefsFileNew, ACCESS_READ); + if (fLock) + { + UnLock(fLock); + } + else + { + struct oldPopupMenuPrefs LoadedPrefs; + APTR myPrefsHandle; + static const struct oldPopupMenuPrefs DefaultPrefs = + { + PMP_FLAGS_SHADOWS, /* pmp_Flags */ + 0, /* pmp_SubMenuDelay */ + PMP_ANIM_NONE, /* pmp_Animation */ + PMP_PD_SCREENBAR, /* pmp_PulldownPos */ + FALSE, /* pmp_Sticky */ + FALSE, /* pmp_SameHeight unused */ + 0, /* pmp_MenuBorder */ + 0, /* pmp_SelItemBorder */ + 0, /* pmp_SeparatorBar */ + 0, /* pmp_MenuTitles */ + 0, /* pmp_MenuItems */ + 2, /* pmp_XOffset */ + 2, /* pmp_YOffset */ + 2, /* pmp_XSpace */ + 2, /* pmp_YSpace */ + 2, /* pmp_Intermediate */ + 0, /* pmp_TextDisplace */ + -30, /* pmp_ShadowR unused */ + -30, /* pmp_ShadowG unused */ + -30, /* pmp_ShadowB unused */ + 0, /* pmp_TransparencyR unused */ + 0, /* pmp_TransparencyG unused */ + 0, /* pmp_TransparencyB unused */ + 0, /* pmp_TransparencyBlur */ + 0, /* pmp_AnimationSpeed unused */ + + {0}, /* pmp_Reserved */ + }; + + PM_LoadPrefsFile(prefsFileOld, 0, &LoadedPrefs, &DefaultPrefs); + + d1(KPrintF("%s/%s/%ld: pmp_Animation=%ld\n", __FILE__, __FUNC__, __LINE__, LoadedPrefs.pmp_Animation)); + + myPrefsHandle = AllocPrefsHandle("PopupMenuPrefs"); + if (myPrefsHandle) + { + LONG lID = MAKE_ID('M', 'A', 'I', 'N'); + + SetPreferences(myPrefsHandle, lID, PMP_Flags, &LoadedPrefs.pmp_Flags, sizeof(LoadedPrefs.pmp_Flags) ); + SetPreferences(myPrefsHandle, lID, PMP_SubMenuDelay, &LoadedPrefs.pmp_SubMenuDelay, sizeof(LoadedPrefs.pmp_SubMenuDelay) ); + SetPreferences(myPrefsHandle, lID, PMP_AnimationType, &LoadedPrefs.pmp_Animation, sizeof(LoadedPrefs.pmp_Animation) ); + SetPreferences(myPrefsHandle, lID, PMP_PullDownMenuPos, &LoadedPrefs.pmp_PulldownPos, sizeof(LoadedPrefs.pmp_PulldownPos) ); + SetPreferences(myPrefsHandle, lID, PMP_Sticky, &LoadedPrefs.pmp_Sticky, sizeof(LoadedPrefs.pmp_Sticky) ); + SetPreferences(myPrefsHandle, lID, PMP_MenuBorderType, &LoadedPrefs.pmp_MenuBorder, sizeof(LoadedPrefs.pmp_MenuBorder) ); + SetPreferences(myPrefsHandle, lID, PMP_SelItemBorderType, &LoadedPrefs.pmp_SelItemBorder, sizeof(LoadedPrefs.pmp_SelItemBorder) ); + SetPreferences(myPrefsHandle, lID, PMP_SeparatorBarStyle, &LoadedPrefs.pmp_SeparatorBar, sizeof(LoadedPrefs.pmp_SeparatorBar) ); + SetPreferences(myPrefsHandle, lID, PMP_XOffset, &LoadedPrefs.pmp_XOffset, sizeof(LoadedPrefs.pmp_XOffset) ); + SetPreferences(myPrefsHandle, lID, PMP_YOffset, &LoadedPrefs.pmp_YOffset, sizeof(LoadedPrefs.pmp_YOffset) ); + SetPreferences(myPrefsHandle, lID, PMP_XSpace, &LoadedPrefs.pmp_XSpace, sizeof(LoadedPrefs.pmp_XSpace) ); + SetPreferences(myPrefsHandle, lID, PMP_YSpace, &LoadedPrefs.pmp_YSpace, sizeof(LoadedPrefs.pmp_YSpace) ); + SetPreferences(myPrefsHandle, lID, PMP_Intermediate, &LoadedPrefs.pmp_Intermediate, sizeof(LoadedPrefs.pmp_Intermediate) ); + SetPreferences(myPrefsHandle, lID, PMP_TransparencyBlur, &LoadedPrefs.pmp_TransparencyBlur, sizeof(LoadedPrefs.pmp_TransparencyBlur) ); + SetPreferences(myPrefsHandle, lID, PMP_TextDisplace, &LoadedPrefs.pmp_TextDisplace, sizeof(LoadedPrefs.pmp_TextDisplace) ); + SetPreferences(myPrefsHandle, lID, PMP_MenuTitleStyle, &LoadedPrefs.pmp_MenuTitles, sizeof(LoadedPrefs.pmp_MenuTitles) ); + SetPreferences(myPrefsHandle, lID, PMP_MenuItemStyle, &LoadedPrefs.pmp_MenuItems, sizeof(LoadedPrefs.pmp_MenuItems) ); + + WritePrefsHandle(myPrefsHandle, prefsFileNew); + + FreePrefsHandle(myPrefsHandle); + } + } +} + + diff --git a/scalos/libraries/popupmenu/pmprefs.h b/scalos/libraries/popupmenu/pmprefs.h new file mode 100644 index 000000000..b41568578 --- /dev/null +++ b/scalos/libraries/popupmenu/pmprefs.h @@ -0,0 +1,75 @@ +// pmprefs.h +// +// Menu Prefs +// +// $Date$ +// $Revision$ +// + +#ifndef PM_PREFS_H +#define PM_PREFS_H + +#include "prefs/popupmenu.h" + + +struct PopupMenuPrefs +{ + UBYTE pmp_Flags; /* Enable shadows, transparency, etc. */ + UBYTE pmp_SubMenuDelay; /* Delay before opening submenus */ + UBYTE pmp_Animation; /* Animation, see below for defines */ + /* (Only one animation effect implemented currently) */ + UBYTE pmp_PulldownPos; /* Where to show pulldownmenus */ + WORD pmp_Sticky; /* Use 'sticky' mode */ + UBYTE pmp_MenuBorder; /* Menu border */ + UBYTE pmp_SelItemBorder; /* Border around selected item */ + UBYTE pmp_SeparatorBar; /* Separator bar style */ + UBYTE pmp_MenuTitles; /* Style flags for drawing menu texts */ + UBYTE pmp_MenuItems; /* Style flags for drawing menu item texts */ + UBYTE pmp_XOffset; + UBYTE pmp_YOffset; + UBYTE pmp_XSpace; + UBYTE pmp_YSpace; + UBYTE pmp_Intermediate; + BYTE pmp_TextDisplace; + UBYTE pmp_TransparencyBlur; +}; + +/// Frames +#define BUTTON_FRAME 0 +#define MAGIC_FRAME 1 +#define THICK_BUTTON_FRAME 2 +#define DOUBLE_FRAME 3 +#define DROPBOX_FRAME 4 +#define INTUI_FRAME 5 +/// + +/// TextPatch +#define TP_CENTER 0x0001 +#define TP_UNDERLINE 0x0002 +#define TP_BOLD 0x0004 +#define TP_SHINE 0x0008 +#define TP_SHADOW 0x0010 +#define TP_TEXT 0x0020 +#define TP_HILITE 0x0040 +#define TP_SHADOWED 0x0080 +#define TP_LEFT 0x0100 +#define TP_RIGHT 0x0200 +#define TP_EMBOSS 0x0400 +#define TP_KILLBAR 0x0800 +#define TP_OUTLINE 0x1000 +#define TP_ACTIVATE 0x8000 +/// + +/// File name/ID +#define PMP_ID (0x504d4e55) +#define PMP_VERSION 1 +#define PMP_PATH_OLD "ENV:sys/PopupMenu.prefs" +#define PMP_PATH_NEW "ENV:sys/NewPopupMenu.prefs" +/// + +extern struct PopupMenuPrefs *PM_Prefs; + +void PM_Prefs_Load(CONST_STRPTR prefsFileOld, CONST_STRPTR prefsFileNew); +void PM_Prefs_Free(void); + +#endif diff --git a/scalos/libraries/popupmenu/pmpriv.h b/scalos/libraries/popupmenu/pmpriv.h new file mode 100644 index 000000000..2582072f1 --- /dev/null +++ b/scalos/libraries/popupmenu/pmpriv.h @@ -0,0 +1,557 @@ +// pmpriv.h +// +// Popup Menu +// ©1996-2002 Henrik Isaksson +// Private definitons +// +// $Date$ +// $Revision$ +// + +#ifndef PMPRIV_H +#define PMPRIV_H + +#include "compiler.h" + +#if 0 +#ifndef __AROS__ +#include "screens.h" +#include "gui.h" +#endif +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#include + +#include /* v41 uses cybergraphx/ dir */ + +#include "popupmenu.h" + +#include "pmtypes.h" +#include "pmmem.h" +#include "pmprefs.h" +#include "pmshadow.h" +#include "pmtopography.h" +#include "pminput.h" +#include "pmfind.h" +#include "pminternals.h" +#include "pmgraph.h" +#include "pmimages.h" + + +#define POPUPMENU_REVISION 11L + + +#define PM_Req(c, s) if(c) EZReq("Assertion failed:\n\n" s, "OK", 0) + +#define SelBarLeft(a) (a->p->BorderWidth+1+PM_Prefs->pmp_XSpace) +#define SelBarRight(a) (a->p->BorderWidth-1-PM_Prefs->pmp_XSpace) +#define SelBarTop(a, pm) (pm->Top+PM_Prefs->pmp_YSpace+1) +#define SelBarBottom(a, pm) (pm->Top-PM_Prefs->pmp_YSpace+pm->Height-1) + +#define FirstColumn(a) (PM_Prefs->pmp_XOffset+a->p->BorderWidth+1) /* sista 1 == selbarwidth */ + +#define BarTop(a, pm) (pm->Top+pm->Height/2+1) + +#define BarLeft(a, pm) (pm->Left) + +#define BarRight(a, pm) (pm->Left+pm->Width) + +#define XAPosWideSelBar(a) SelBarLeft(a) +#define XBPosWideSelBar(a) SelBarRight(a) +#define XAPosSelBar(a) SelBarLeft(a) +#define XBPosSelBar(a) SelBarRight(a) +#define YAPosSelBar(a, pm) SelBarTop(a, pm) +#define YBPosSelBar(a, pm) SelBarBottom(a, pm) +#define CheckmarkSize(a) (PM_Prefs->pmp_Intermediate+a->p->MenuFont->tf_XSize) +#define SubmarkSize(a) (PM_Prefs->pmp_Intermediate+a->p->MenuFont->tf_XSize) +#define YPosText(a, pm) (pm->Top+a->p->MenuFont->tf_Baseline+(pm->Height+1)/2-(a->p->MenuFont->tf_YSize)/2+PM_Prefs->pmp_TextDisplace) +//#define XPosLastCol(a) (a->Width-(1)-a->p->MenuFont->tf_XSize-PM_Prefs->pmp_Intermediate-PM_Prefs->pmp_XSpace) +//#define XPosLastColImg(a, img) (a->Width-a->p->BorderWidth-PMImgWidth(img)-PM_Prefs->pmp_Intermediate) +#define XPosLastCol(a) (pm->Left+pm->Width-a->p->MenuFont->tf_XSize-PM_Prefs->pmp_XSpace) +#define XPosLastColImg(a, img) (pm->Left+pm->Width-PMImgWidth(img)-PM_Prefs->pmp_XSpace) +#define YPosImage(a, pm, img) (pm->Top+(pm->Height+1)/2-PMImgHeight(img)/2) +#define YPosImage_(a, pm, img) (pm->Top+(pm->Height+1)/2-img->Height/2) + +#define OutOfRange(x, min, max) (x>=max || x<=min) + +#define SCREENMOUSEPOS(p) p->RootWnd->WScreen->MouseX, p->RootWnd->WScreen->MouseY +#define SCREENMOUSEX(p) p->RootWnd->WScreen->MouseX +#define SCREENMOUSEY(p) p->RootWnd->WScreen->MouseY + +#ifdef __AROS__ +#warning "FIXME: Pens" +#define MENUSHINEPEN SHINEPEN +#define MENUSHADOWPEN SHADOWPEN +#define MENUTEXTPEN TEXTPEN +#define SELECTPEN FILLPEN +#define SELECTTEXTPEN FILLTEXTPEN +#define MENUBACKGROUNDPEN BACKGROUNDPEN +#endif + +#if !defined(HALFSHINEPEN) +#define HALFSHINEPEN SHINEPEN +#define HALFSHADOWPEN SHADOWPEN +#endif /* defined(__SASC) */ + +#define SHINE(xyz) ((xyz->DrawInfo->dri_Pens[HALFSHINEPEN] <= 255) ? xyz->DrawInfo->dri_Pens[HALFSHINEPEN] : xyz->DrawInfo->dri_Pens[SHINEPEN]) +#define SHADOW(xyz) ((xyz->DrawInfo->dri_Pens[HALFSHADOWPEN] <= 255) ? xyz->DrawInfo->dri_Pens[HALFSHADOWPEN] : xyz->DrawInfo->dri_Pens[SHADOWPEN]) +#define TEXT(xyz) xyz->DrawInfo->dri_Pens[TEXTPEN] +#define FILL(xyz) xyz->DrawInfo->dri_Pens[FILLPEN] +#define FTPEN(xyz) xyz->DrawInfo->dri_Pens[FILLTEXTPEN] +#define BGPEN(xyz) xyz->DrawInfo->dri_Pens[BACKGROUNDPEN] +#define HILITE(xyz) xyz->DrawInfo->dri_Pens[HIGHLIGHTTEXTPEN] +#define TEXTSHADOW(xyz) xyz->DrawInfo->dri_Pens[BARDETAILPEN] +#define TEXTOUTLINE(xyz) xyz->DrawInfo->dri_Pens[BARDETAILPEN] + +#define BGSHADOW(xyz) xyz->DrawInfo->dri_Pens[HALFSHADOWPEN] +#define BGSHINE(xyz) xyz->DrawInfo->dri_Pens[HALFSHINEPEN] +#define HALF(xyz) xyz->DrawInfo->dri_Pens[BACKGROUNDPEN] + +#define PATCH(p, n) if(PM_Prefs->pmp_MenuTitles & p) pm->Flags|=n; else pm->Flags&=~n; +#define TPATCH(p, n) if(PM_Prefs->pmp_MenuItems & p) pm->Flags|=n; + +#define PM_IDCMP (IDCMP_MOUSEBUTTONS|IDCMP_MOUSEMOVE|IDCMP_INACTIVEWINDOW|IDCMP_INTUITICKS|IDCMP_REFRESHWINDOW) + +#define BWRP &a->Wnd->RPort +#define BWX (a->Wnd->Left) +#define BWY (a->Wnd->Top) +#define BWW (a->Wnd->Width) +#define BWH (a->Wnd->Height) +#define BWXX (a->Wnd->Left+a->Wnd->Width) +#define BWYY (a->Wnd->Top+a->Wnd->Height) + +// +// Extended flags +// + +#define NPX_IMGPLANAR 0x0000 // +#define NPX_IMGCHUNKY 0x0001 // +#define NPX_IMGVECTOR 0x0002 // +#define NPX_TXTNORMAL 0x0000 // Normal (STRPTR) title +#define NPX_TXTLOCALE 0x0010 // Localized title +#define NPX_TXTBOOPSI 0x0020 // BOOPSI Object title + +#define GET_TXTMODE(x) (x->ExtFlags&0x0030) +#define GET_IMGMODE(x) (x->ExtFlags&0x0003) + +#define SET_TXTMODE(x, y) { x->ExtFlags&=~0x0030; x->ExtFlags|=y; } +#define SET_IMGMODE(x, y) { x->ExtFlags&=~0x0003; x->ExtFlags|=y; } + +// +// Built-in Images +// + + // / +#define IMG_CHECKMARK (0x10L) // Checkmark \/ +#define IMG_RIGHTARROW (0x0CL) // SysIClass Arrow |>| +#define IMG_MXIMAGE (0x0FL) // SysIClass MX (*) +#define IMG_CHECKIMAGE (0x0EL) // SysIClass Checkbox | | +#define IMG_AMIGAKEY (0x11L) // Amiga Key Image |A| + +#define IMG_MMCHECK (0x7000L) // MagicMenu CheckMark +#define IMG_MMAMIGA (0x7001L) // MagicMenu AmigaKey +#define IMG_MMSUB (0x7002L) // MagicMenu Submenu arrow +#define IMG_MMEXCLUDE (0x7003L) // MagicMenu MX Image + +#define IMG_BULLET_A (0x8000L) // bullet · +#define IMG_BULLET_B (0x8100L) // 3d bullet · +#define IMG_ARROW_A (0x8200L) // Arrow > +#define IMG_ARROW_B (0x8300L) // 3d arrow > +#define IMG_ARROW_C (0x8400L) // Arrow -> + +struct PM_IDLst { + struct PM_IDLst *Next; + ULONG ID; + UBYTE Kind; + UBYTE Flags; +}; + +#define IDKND_EXCLUDE 0x1 +#define IDKND_INCLUDE 0x2 +#define IDKND_REFLECT 0x3 +#define IDKND_INVERSE 0x4 + +struct PM_Root; + +// +// PM_Window holds menu window information +// +struct PM_Window { + struct PM_Window *Prev; // Previous window in the chain, for bounds checking of the entire menu + struct PM_Window *NextWindow; // Points to a submenu, while it's open + + UWORD Width; // Menu size differs from window size, because of shadows. + UWORD Height; // + UWORD MenuX; + UWORD MenuY; + + struct Window *Wnd; // The menu window + struct RastPort *RPort; // Window RastPort, NEVER use wnd->RPort + + struct PM_WBackground { // Background buffer for transparency or backdrop images + UBYTE *BgArray; + } bg; + + struct PM_EffectBuffer { // Used for transition effects + struct BitMap *BMap; + struct RastPort *RPort; // RastPort, PM_Window::RPort will be redirected here when TE's are used + } te; + + struct PopupMenu *Selected; // Currently selected item (the one in 'focus'), or NULL + struct PopupMenu *PrevSel; // Previously selected + struct PopupMenu *WasSelected; // Was selected when button was released + struct PopupMenu *SubMenuToOpen; + struct PopupMenu *SubMenuParent; // For construct hook + + LONG AltXPos; // Alternate X position + + BOOL Running; // TRUE while active, setting to FALSE will terminate this window + // Can be set to TRUE by submenus + + BOOL MenuDisabled; // Entire menu is disabled + ULONG IconColumn; // Width of Icon Column(s) + ULONG ItemHeight; // Height of items + ULONG MenuLevel; // Wich level of submenu this is + BOOL FirstTime; // Pulldown menus need to be drawn differently the first time + BOOL ReverseDirection; // Open menus to the left + BOOL StickyFlag; // Sticky mode: MB is down => multiselect on, close on up + + PMTRList *Topographic; // Shadow management - topography + PMSRList *Shadowmap; // Shadow management - overlapping control + + struct PopupMenu PM; + + struct PM_Root *p; // Menu globals +}; + +struct MultiSlct { + struct MultiSlct *next; + struct PopupMenu *pm; +}; + +// +// Root menu structure, holds "global" variables +// + +struct PM_Root { + struct Window *RootWnd; // Window that the menu belongs to + struct Screen *Scr; // Menu screen + struct DrawInfo *DrawInfo; // Screen's drawinfo + struct PopupMenu *PM; // The menu + struct PM_Window *RootMenu; // First window in the menu + + ULONG Subtimer; // Timer for submenu + APTR ReturnCode; // Return code + ULONG ReturnID; // Return ID + + LONG BorderWidth; // Line width of menu borders + LONG BorderHeight; // Line Height of menu borders + + // Menu options + BOOL PullDown; // This menu is a pulldown menu + + // Shadows + + UWORD ShadowWidth; // Width of shadows + UWORD ShadowHeight; // Height of shadows + UWORD ShadowAddX; // Width increase for each layer + UWORD ShadowAddY; // Height increase for each layer + + // + // Timeout + // + + ULONG TimeOut; + T_TIMEREQUEST *treq; + struct MsgPort *tport; + + // + // Current Timer - Used to figure out when to refresh menus (update hook for dynamic menus) + // + + ULONG Secs, Micros; + + // + // MultiSelect + // + + struct MultiSlct *MultiSel; + BOOL DoMultiSel; + ULONG MultiSelCount; + + // + // Hooks + // + + struct Hook *MenuHandler; // Handles multiselect + struct Hook *LocaleHook; // Translates numbers to strings + + // + // Button that opened the menu + // + + BOOL RButton; + BOOL LButton; + + // + // Menu position + // + + BOOL MenuCenter; // + UWORD MenuHeight; // + UWORD MenuWidth; // Only used for the first menu + UWORD MenuRight; // + UWORD MenuBottom; // + + // + // Menu font - All font operations must use this font! + // + + struct TextFont *MenuFont; + + // + // HintBox + // + + BOOL HintBox; + + + + BOOL DoneMulti; // MultiSelect has been used => turns SingleSelect off + + struct PM_InputHandler *pmh; + + struct Image *MenuImages[PMIMG_LAST]; +}; + +extern struct PM_Root *p; + +// + +#define IST_ACTIVE 1 +#define IST_INACTIVE 2 + +#define PMACT_DESELECT 2 +#define PMACT_SELECT 3 + +/// Protos +// +// Prototypes +// + +#ifndef PM_NOPROTOS + +void PM_DrawShadow(struct PM_Window *w, int x, int y, int xb, int yb, UBYTE Type); +struct PM_Root *PM_AllocPMRoot(struct Window *w); + +void PM_FreeSubWindow(struct PM_Window *parent, struct PM_Window *a); +struct PM_Window *PM_SetupSubWindow(struct PM_Window *parent, struct PM_Root *p, struct PopupMenu *pm); +APTR PM_DoPopup(struct PM_Window *a, struct PopupMenuBase *l); +void PM_CloseWindow(struct PM_Window *); +BOOL PM_OpenWindow(struct PM_Window *pw, int left, int top, int width, int height, struct Screen *scr); +void PM_ResizeWindow(struct PM_Window *bw, int l, int t, int w, int h); +BOOL PM_InsideWindows(int px, int py, struct PM_Window *wnd); +UWORD PM_ItemHeight(struct PM_Window *a, struct PopupMenu *pm); +UWORD PM_ItemWidth(struct PM_Window *a, struct PopupMenu *pm); +void PMPM_LayoutMenu(struct PM_Window *a); +void PM_RenderMenu(struct PM_Window *a, BOOL MenuDisable, BOOL); +void LoadPref(void); + +void EZDeleteTimer(T_TIMEREQUEST *); +T_TIMEREQUEST *EZCreateTimer(LONG Unit); + +// +// PMInit.c +// +int PMLibInit(struct PopupMenuBase *PopupMenuBase); +void PMLibCleanup(struct PopupMenuBase *l); + +// +// PMCreate.c +// + +void PM_FreeTitle(struct PopupMenu *p); + +// +// PMError.C +// + +LONG EZReq(STRPTR Text, STRPTR ButtonText, ULONG Arg, ...); + +// +// PMLayout.C +// + +//void PM_LayoutMenu(struct PM_Window *a); +void PM_LayoutGroup(struct PM_Window *a, struct PopupMenu *pm); +void PM_CalcItemSize(struct PM_Window *a, struct PopupMenu *pm); +UWORD PM_ItemWidth(struct PM_Window *a, struct PopupMenu *pm); +UWORD PM_ItemHeight(struct PM_Window *a, struct PopupMenu *pm); + +// +// PMInit.C +// + +#ifndef INIT +BOOL OpenLibs(void); +void CloseLibs(void); +#endif + +// +// Globals +// + +extern BOOL V40Gfx; +extern BOOL CyberGfx; +extern APTR MemPool; +extern struct SignalSemaphore MemPoolSemaphore; + +// +// Lib funcs +// + +LIBFUNC_P3_PROTO(APTR, LIBPM_OpenPopupMenuA, + A1, struct Window *, prevwnd, + A2, struct TagItem *, tags, + A6, struct PopupMenuBase *, l); + +LIBFUNC_P2_PROTO(void, LIBPM_FreePopupMenu, + A1, struct PopupMenu *, p, + A6, struct PopupMenuBase *, l); + +LIBFUNC_P2_PROTO(void, LIBPM_FreeIDList, + A0, struct PM_IDLst *, f, + A6, struct PopupMenuBase *, l); + +LIBFUNC_P3_PROTO(LONG, LIBPM_InsertMenuItemA, + A2, struct PopupMenu *, base, + A1, struct TagItem *, tags, + A6, struct PopupMenuBase *, l); + +LIBFUNC_P3_PROTO(APTR, LIBPM_RemoveMenuItem, + A0, struct PopupMenu *, base, + A1, struct PopupMenu *, item, + A6, struct PopupMenuBase *, l); + +LIBFUNC_P2_PROTO(BOOL, LIBPM_AbortHook, + A0, APTR, handle, + A6, struct PopupMenuBase *, l); + +LIBFUNC_P1_PROTO(STRPTR, LIBPM_GetVersion, + A6, struct PopupMenuBase *, l); + +LIBFUNC_P4_PROTO(LONG, LIBPM_LayoutMenuA, + A0, struct Window *, w, + A1, struct PopupMenu *, pm, + A2, struct TagItem *, tags, + A6, struct PopupMenuBase *, l); + +LIBFUNC_P2_PROTO(struct PopupMenu *, LIBPM_MakeItemA, + A1, struct TagItem *, tags, + A6, struct PopupMenuBase *, l); + +LIBFUNC_P2_PROTO(struct PopupMenu *, LIBPM_MakeMenuA, + A1, struct TagItem *, tags, + A6, struct PopupMenuBase *, l); + +LIBFUNC_P2_PROTO(struct PM_IDLst *, LIBPM_MakeIDListA, + A1, struct TagItem *, tags, + A6, struct PopupMenuBase *, l); + +LIBFUNC_P3_PROTO(LONG, LIBPM_GetItemAttrsA, + A2, struct PopupMenu *, p, + A1, struct TagItem *, tags, + A6, struct PopupMenuBase *, l); + +LIBFUNC_P3_PROTO(LONG, LIBPM_SetItemAttrsA, + A2, struct PopupMenu *, p, + A1, struct TagItem *, tags, + A6, struct PopupMenuBase *, l); + +// Alter the states of a list of items. (Execute an IDList program) +LIBFUNC_P4_PROTO(void, LIBPM_AlterState, + A1, struct PopupMenu *, base, + A2, struct PM_IDLst *, ids, + D1, UWORD, action, + A6, struct PopupMenuBase *, l); + +LIBFUNC_P2_PROTO(struct PM_IDLst *, LIBPM_ExLstA, + A1, ULONG, *id, + A6, struct PopupMenuBase *, l); + +LIBFUNC_P1_PROTO(APTR, LIBPM_OBSOLETEFilterIMsgA, + A6, struct PopupMenuBase *, l); + +LIBFUNC_P5_PROTO(APTR, LIBPM_FilterIMsgA, + A0, struct Window *, w, + A1, struct PopupMenu *, pm, + A2, struct IntuiMessage *, im, + A3, struct TagItem *, tags, + A6, struct PopupMenuBase *, l); + +LIBFUNC_P3_PROTO(struct PopupMenu *, LIBPM_FindItem, + A1, struct PopupMenu *, pm, + D1, ULONG, ID, + A6, struct PopupMenuBase *, l); + +LIBFUNC_P3_PROTO(BOOL, LIBPM_ItemChecked, + A2, struct PopupMenu *, p, + D1, ULONG, ID, + A6, struct PopupMenuBase *, l); + +LIBFUNC_P1_PROTO(void, LIBPM_ReloadPrefs, + A6, struct PopupMenuBase *, l); + +LIBFUNC_P1_PROTO(LONG, LIBPM_RESERVED1, + A6, struct PopupMenuBase *, PopupMenuBase); + + + +void pm_AlterState(struct PopupMenu *base, struct PM_IDLst *ids, UWORD action); +void pm_FreePopupMenu(struct PopupMenu *p, struct PopupMenuBase *PopupMenuBase); +LONG pm_SetItemAttrsA(struct PopupMenu *p, struct TagItem *tags, struct PopupMenuBase *PopupMenuBase); +void FreeIDList(struct PM_IDLst *f); + + +#define d1(x) ; +#define d2(x) x; + +// from debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); + +#endif +/// + +#endif diff --git a/scalos/libraries/popupmenu/pmshadow.c b/scalos/libraries/popupmenu/pmshadow.c new file mode 100644 index 000000000..863763970 --- /dev/null +++ b/scalos/libraries/popupmenu/pmshadow.c @@ -0,0 +1,271 @@ +// +// pmshadow.c +// +// PopupMenu Library - Shadows +// +// Copyright (C)2000 Henrik Isaksson +// All Rights Reserved. +// +// $Date$ +// $Revision$ +// + +#include "pmpriv.h" +#include "pmshadow.h" + +#include + +#include +#include + +#include + +#define ADDSHADOW(l,s) { \ + rectptr = PM_CopyShadowNode(s); \ + if (rectptr) \ + PM_AddShadowToList(l, rectptr); \ + else \ + fail = TRUE; \ + } +#define INSIDEX(a, b1, b2) (a > b1 && a < b2) +#define INSIDE(a, b1, b2) (a >= b1 && a <= b2) +#define INTERVALOVERLAP(a1, a2, b1, b2) (INSIDE(a1, b1, b2) || INSIDE(a2, b1, b2) \ + || INSIDE(b1, a1, a2) || INSIDE(b2, a1, a2)) + +static BOOL PM_SubRects(PMSRList *dest, // Remove parts of worknode + PMSR *worknode, PMSR *rect); // that are overlapped by rect. * + +// +// PM_ShadowOverlap - return TRUE if the two rects touch each other anywhere +// +BOOL PM_ShadowOverlap(PMSR *A, PMSR *B) +{ +#if 0 + if (INTERVALOVERLAP(A->Top+1, A->Bottom, B->Top+1, B->Bottom)) + { + if (INTERVALOVERLAP(A->Left+1, A->Right, B->Left+1, B->Right)) + { + d1(KPrintF("%s/%s/%ld: A(Type=%ld %ld %ld %ld %ld) B(Type=%ld %ld %ld %ld %ld)\n", \ + __FILE__, __FUNC__, __LINE__, \ + A->pmsr_Type, A->Left, A->Top, A->Right, A->Bottom, \ + B->pmsr_Type, B->Left, B->Top, B->Right, B->Bottom)); + return TRUE; + } + } + + if ((A->Top == B->Top && (A->Left == B->Left || A->Right == B->Right)) || + (A->Bottom == B->Bottom && (A->Left == B->Left || A->Right == B->Right))) + { + d1(KPrintF("%s/%s/%ld: A(Type=%ld %ld %ld %ld %ld) B(Type=%ld %ld %ld %ld %ld)\n", \ + __FILE__, __FUNC__, __LINE__, \ + A->pmsr_Type, A->Left, A->Top, A->Right, A->Bottom, \ + B->pmsr_Type, B->Left, B->Top, B->Right, B->Bottom)); + return TRUE; + } +#endif + return FALSE; +} + +// +// PM_CopyShadowNode - copy a PMShadowRect. +// +PMSR *PM_CopyShadowNode(PMSR *A) +{ + PMSR *newnode = NULL; + + if (A) { + ((PMGLN *)A)->Length = sizeof(PMSR); + + newnode = (PMSR *)PM_CopyNode((PMNode *)A); + } + + return newnode; +} + +// +// PM_SubRects - subtract one rect from another to a list of new rects +// +static BOOL PM_SubRects(PMSRList *dest, PMSR *worknode, PMSR *rect) +{ + PMSR tmprect, *rectptr; + BOOL fail = FALSE; + + // Definition: "old shadow" = worknode + // "new shadow" = rect + + // Now, check existance and size of the following four regions: + // + // +-------------+ + // | A | + // +---+-----+---+ + // | C | new | D | + // +---+-----+---+ + // | B | + // +-------------+ + + d1(KPrintF("%s/%s/%ld: rect(%ld %ld %ld %ld) <> worknode(%ld %ld %ld %ld) transformed to:\n", \ + __FILE__, __FUNC__, __LINE__, \ + rect->Left, rect->Top, rect->Right, rect->Bottom, \ + worknode->Left, worknode->Top, worknode->Right, worknode->Bottom)); + + /*if (rect->Left == worknode->Left && rect->Right == worknode->Right && + rect->Top == worknode->Top && rect->Bottom == worknode->Bottom) + return TRUE;*/ + + tmprect.Left = worknode->Left; + tmprect.Right = worknode->Right; + tmprect.pmsr_Type = worknode->pmsr_Type; + + // For A to exist, the rect's upper edge must be inside the + // old shadow. + + if (INSIDEX(rect->Top, worknode->Top, worknode->Bottom)) + { + tmprect.Top = worknode->Top; + tmprect.Bottom = rect->Top; + + // Add the new rect to the list + d1(KPrintF("%s/%s/%ld: Left=%ld Top=%ld Right=%ld Bottom=%ld\n", \ + __FILE__, __FUNC__, __LINE__, tmprect.Left, tmprect.Top, tmprect.Right, tmprect.Bottom)); + + ADDSHADOW(dest, &tmprect); + } + + // For B to exist, the rect's lower edge must be inside the + // old shadow. + + if (INSIDEX(rect->Bottom, worknode->Top, worknode->Bottom)) + { + tmprect.Top = rect->Bottom; + tmprect.Bottom = worknode->Bottom; + + // Add the new rect to the list + d1(KPrintF("%s/%s/%ld: Left=%ld Top=%ld Right=%ld Bottom=%ld\n", \ + __FILE__, __FUNC__, __LINE__, tmprect.Left, tmprect.Top, tmprect.Right, tmprect.Bottom)); + + ADDSHADOW(dest, &tmprect); + } + + tmprect.Top = MAX(rect->Top, worknode->Top); + tmprect.Bottom = MIN(rect->Bottom, worknode->Bottom); + + // For C to exist, the left edge of the new shadow must be + // inside the old one. + + if (INSIDEX(rect->Left, worknode->Left, worknode->Right)) + { + tmprect.Left = worknode->Left; + tmprect.Right = rect->Left; + + // Add the new rect to the list + d1(KPrintF("%s/%s/%ld: Left=%ld Top=%ld Right=%ld Bottom=%ld\n", \ + __FILE__, __FUNC__, __LINE__, tmprect.Left, tmprect.Top, tmprect.Right, tmprect.Bottom)); + + ADDSHADOW(dest, &tmprect); + } + + // For D to exist, the right edge of the new shadow must be + // inside the old one. + + if (INSIDEX(rect->Right, worknode->Left, worknode->Right)) + { + tmprect.Left = rect->Right; + tmprect.Right = worknode->Right; + + // Add the new rect to the list + d1(KPrintF("%s/%s/%ld: Left=%ld Top=%ld Right=%ld Bottom=%ld\n", \ + __FILE__, __FUNC__, __LINE__, tmprect.Left, tmprect.Top, tmprect.Right, tmprect.Bottom)); + + ADDSHADOW(dest, &tmprect); + } + + //printf("--- End of transformation ---\n"); + + return (BOOL) (!fail); +} + +// +// PM_AddShadow - Add a new shadow to sigma and add the change to delta. +// +BOOL PM_AddShadow(PMSRList *sigma, PMSRList *delta) +{ + PMSR *sigmanode, *nextsigmanode; + PMSR *deltanode, *nextdeltanode; + BOOL fail = FALSE; + + // + // Find old (sigma) shadows overlapped by the new one. + // + sigmanode = (PMSR *)(sigma->mlh_Head); /* First node */ + if (!IsListEmpty((struct List *)sigma)) + while ((nextsigmanode = (PMSR *)PM_NextNode(sigmanode))) { + + deltanode = (PMSR *)(delta->mlh_Head); /* First node */ + while ((nextdeltanode = (PMSR *)PM_NextNode(deltanode))) { + + if (PM_ShadowOverlap(deltanode, sigmanode)) { + PM_UnlinkShadow(delta, deltanode); // Remove from delta list + PM_SubRects(delta, deltanode, sigmanode); + PM_FreeShadowNode(deltanode); // Free the old shadow + } + + deltanode = nextdeltanode; + } + + sigmanode = nextsigmanode; + } + + // + // Now we add whatever is left in delta to sigma. + // + deltanode = (PMSR *)(delta->mlh_Head); /* First node */ + while ((nextdeltanode = (PMSR *)PM_NextNode(deltanode))) { + + PMSR *cpy = PM_CopyShadowNode(deltanode); + if (cpy) { + PM_AddShadowToList(sigma, cpy); + } + + deltanode = nextdeltanode; + } + + return (BOOL) (!fail); +} + +// +// PM_SubMenuRect - subtract a menu rect from the shadow list. +// +BOOL PM_SubMenuRect(PMSRList *sigma, WORD l, WORD t, WORD w, WORD h) +{ + PMSR *sigmanode, *nextsigmanode; + PMSR rect; + BOOL fail = FALSE; + + rect.Left = l; + rect.Top = t; + rect.Right = l+w; + rect.Bottom = t+h; + + // + // Find old (sigma) shadows overlapped by the new one. + // + sigmanode = (PMSR *)(sigma->mlh_Head); /* First node */ + while ((nextsigmanode = (PMSR *)PM_NextNode(sigmanode))) + { + rect.pmsr_Type = sigmanode->pmsr_Type; + + if (PM_ShadowOverlap(&rect, sigmanode)) + { + PM_UnlinkShadow(sigma, sigmanode); // Remove from delta list + PM_SubRects(sigma, sigmanode, &rect); + PM_FreeShadowNode(sigmanode); // Free the old shadow + } + + + sigmanode = nextsigmanode; + } + + return (BOOL) (!fail); +} + + diff --git a/scalos/libraries/popupmenu/pmshadow.h b/scalos/libraries/popupmenu/pmshadow.h new file mode 100644 index 000000000..ee72b82c4 --- /dev/null +++ b/scalos/libraries/popupmenu/pmshadow.h @@ -0,0 +1,78 @@ +// +// pmshadow.h +// +// PopupMenu Library - Shadows +// +// Copyright (C)2000 Henrik Isaksson +// All Rights Reserved. +// +// $Date$ +// $Revision$ +// + +#ifndef PM_SHADOW_H +#define PM_SHADOW_H + +#ifndef PM_DLIST_H +#include "pmdlist.h" +#endif + +#ifndef MAX +#define MAX(a,b) (a>b?a:b) +#endif +#ifndef MIN +#define MIN(a,b) (ati_Tag) { + case PM_Title: + PM_FreeTitle(p); + if (tag->ti_Data) { + p->TitleUnion.Title=PM_Mem_Alloc(strlen((STRPTR)tag->ti_Data)+1); + if (p->TitleUnion.Title) { + strcpy(p->TitleUnion.Title, (STRPTR)tag->ti_Data); + count++; + } else { + p->TitleUnion.Title=NULL; + } + } + SET_TXTMODE(p, NPX_TXTNORMAL); + break; + case PM_TitleID: + PM_FreeTitle(p); + p->TitleUnion.TitleID=tag->ti_Data; + SET_TXTMODE(p, NPX_TXTLOCALE); + count++; + break; + case PM_Object: + PM_FreeTitle(p); + p->TitleUnion.Boopsi=(Object *)tag->ti_Data; + SET_TXTMODE(p, NPX_TXTBOOPSI); + count++; + break; + case PM_UserData: + if ((p->Flags&NPM_UDATASTRING) && p->UserData) + PM_Mem_Free(p->UserData); + p->Flags&=~(NPM_UDATASTRING); + p->UserData=(APTR)tag->ti_Data; + count++; + break; + case PM_UserDataString: + if ((p->Flags&NPM_UDATASTRING) && p->UserData) + PM_Mem_Free(p->UserData); + p->Flags|=NPM_UDATASTRING; + p->UserData=PM_Mem_Alloc(strlen((STRPTR)tag->ti_Data)+1); + if (p->UserData) { + strcpy(p->UserData, (STRPTR)tag->ti_Data); + count++; + } + break; + case PM_ID: + count++; + p->ID=tag->ti_Data; + break; + case PM_Sub: + count++; + if (p->SubGroup.Sub) + pm_FreePopupMenu(p->SubGroup.Sub, PopupMenuBase); + p->SubGroup.Sub=(struct PopupMenu *)tag->ti_Data; + p->Flags&=~NPM_GROUP; + p->Layout=0; + break; + case PM_Members: + count++; + if (p->SubGroup.Sub) + pm_FreePopupMenu(p->SubGroup.Sub, PopupMenuBase); + p->SubGroup.Sub=(struct PopupMenu *)tag->ti_Data; + if (p->Layout==0) p->Layout=PML_Horizontal; + p->Flags|=NPM_GROUP; + break; + case PM_LayoutMode: + count++; + p->Layout=tag->ti_Data; + if (tag->ti_Data) { + p->Flags|=NPM_GROUP; + } else { + p->Flags&=~NPM_GROUP; + } + break; + case PM_Flags: + count++; + p->Flags=tag->ti_Data; + break; + case PM_NoSelect: + count++; + if (tag->ti_Data) p->Flags|=NPM_NOSELECT; + else { + p->Flags&=~NPM_NOSELECT; + p->Flags|=NPM_SELECTABLE; + } + break; + case PM_FillPen: + count++; + if (tag->ti_Data) p->Flags|=NPM_FILLTEXT; + else p->Flags&=~NPM_FILLTEXT; + break; + case PM_ShadowPen: + count++; + if (tag->ti_Data) p->Flags|=NPM_SHADOWTEXT; + else p->Flags&=~NPM_SHADOWTEXT; + break; + case PM_ShinePen: + count++; + if (tag->ti_Data) p->Flags|=NPM_SHINETEXT; + else p->Flags&=~NPM_SHINETEXT; + break; + case PM_Checkit: + count++; + if (tag->ti_Data) p->Flags|=NPM_CHECKIT; + else p->Flags&=~NPM_CHECKIT; + break; + case PM_Checked: + count++; + if (tag->ti_Data) p->Flags|=NPM_CHECKED|NPM_INITIAL_CHECKED; + else p->Flags&=~(NPM_CHECKED|NPM_INITIAL_CHECKED); + break; + case PM_Italic: + count++; + if (tag->ti_Data) p->Flags|=NPM_ITALICTEXT; + else p->Flags&=~NPM_ITALICTEXT; + break; + case PM_Bold: + count++; + if (tag->ti_Data) p->Flags|=NPM_BOLDTEXT; + else p->Flags&=~NPM_BOLDTEXT; + break; + case PM_Underlined: + count++; + if (tag->ti_Data) p->Flags|=NPM_UNDERLINEDTEXT; + else p->Flags&=~NPM_UNDERLINEDTEXT; + break; + case PM_TitleBar: + count++; + if (tag->ti_Data) p->Flags|=NPM_HBAR; + else p->Flags&=~NPM_HBAR; + break; + case PM_WideTitleBar: + count++; + if (tag->ti_Data) p->Flags|=NPM_WIDE_BAR; + else p->Flags&=~NPM_WIDE_BAR; + break; + case PM_ExcludeShared: + count++; + if (tag->ti_Data) p->Flags|=NPM_EXCLUDE_SHARED; + else p->Flags&=~NPM_EXCLUDE_SHARED; + break; + case PM_Exclude: + count++; + if (p->Exclude && !(p->Flags&NPM_EXCLUDE_SHARED)) + FreeIDList(p->Exclude); + if (tag->ti_Data) p->Exclude=(struct PM_IDLst *)tag->ti_Data; + break; + case PM_Disabled: + count++; + if (tag->ti_Data) p->Flags|=NPM_DISABLED|NPM_NOSELECT; + else p->Flags&=~(NPM_DISABLED|NPM_NOSELECT); + break; + case PM_ImageSelected: + count++; + p->ImageUnion.Images[1]=(struct Image *)tag->ti_Data; + if (!p->ImageUnion.Images[0]) p->ImageUnion.Images[0] = p->ImageUnion.Images[1]; + p->Flags|=NPM_ISIMAGE; + break; + case PM_ImageUnselected: + count++; + p->ImageUnion.Images[0] = (struct Image *)tag->ti_Data; + if (!p->ImageUnion.Images[1]) p->ImageUnion.Images[1] = p->ImageUnion.Images[0]; + p->Flags|=NPM_ISIMAGE; + break; + case PM_IconSelected: + count++; + p->ImageUnion.Images[1]=(struct Image *)tag->ti_Data; + if (!p->ImageUnion.Images[0]) p->ImageUnion.Images[0]=p->ImageUnion.Images[1]; + p->Flags&=~NPM_ISIMAGE; + break; + case PM_IconUnselected: + count++; + p->ImageUnion.Images[0]=(struct Image *)tag->ti_Data; + if (!p->ImageUnion.Images[1]) p->ImageUnion.Images[1]=p->ImageUnion.Images[0]; + p->Flags&=~NPM_ISIMAGE; + break; + case PM_AutoStore: + count++; + p->AutoSetPtr=(BOOL *)tag->ti_Data; + if (p->AutoSetPtr) { + if (*p->AutoSetPtr) p->Flags|=NPM_CHECKED; + else p->Flags&=~NPM_CHECKED; + } + break; + case PM_TextPen: + count++; + p->TextPen=tag->ti_Data; + p->Flags|=NPM_CUSTOMPEN; + break; + case PM_Shadowed: + count++; + if (tag->ti_Data) p->Flags|=NPM_SHADOWED; + else p->Flags&=~NPM_SHADOWED; + break; + case PM_Center: + count++; + if (tag->ti_Data) p->Flags|=NPM_CENTERED; + else p->Flags&=~NPM_CENTERED; + break; + case PM_CommKey: + count++; + if (tag->ti_Data) p->CommKey=((char *)tag->ti_Data)[0]; + break; + case PM_ColourBox: + count++; + p->Flags|=NPM_COLOURBOX; + p->CBox=(UBYTE)tag->ti_Data; + break; + case PM_SubConstruct: + p->SubConstruct=(struct Hook *)tag->ti_Data; + count++; + break; + case PM_SubDestruct: + p->SubDestruct=(struct Hook *)tag->ti_Data; + count++; + break; + case PM_Hidden: + if (tag->ti_Data) p->Flags|=NPM_HIDDEN; + else p->Flags&=~NPM_HIDDEN; + count++; + break; + case PM_Toggle: + if (tag->ti_Data) p->Flags&=~NPM_NOTOGGLE; + else p->Flags|=NPM_NOTOGGLE; + count++; + break; + } + } + + return count; +} + +/// + +/// PM_GetItemAttrsA +LIBFUNC_P3(LONG, LIBPM_GetItemAttrsA, + A2, struct PopupMenu *, p, + A1, struct TagItem *, tags, + A6, struct PopupMenuBase *, PopupMenuBase) +{ + struct TagItem *tag, *tstate; + LONG count=0; + + (void) PopupMenuBase; + + if (!p) return 0; + + tstate = tags; + while ((tag=NextTagItem(&tstate))) { + switch(tag->ti_Tag) { + case PM_Title: + if (GET_TXTMODE(p)==0) { + *((STRPTR *)tag->ti_Data)=p->TitleUnion.Title; + count++; + } + break; + case PM_TitleID: + if (GET_TXTMODE(p)==NPX_TXTLOCALE) { + *((ULONG *)tag->ti_Data)=p->TitleUnion.TitleID; + count++; + } + break; + case PM_Object: + if (GET_TXTMODE(p)==NPX_TXTBOOPSI) { + *((Object **)tag->ti_Data)=p->TitleUnion.Boopsi; + count++; + } + break; + case PM_UserData: + *((APTR *)tag->ti_Data)=p->UserData; + count++; + break; + case PM_ID: + count++; + *((ULONG *)tag->ti_Data)=p->ID; + break; + case PM_Members: + case PM_Sub: + count++; + *((struct PopupMenu **)tag->ti_Data) = p->SubGroup.Sub; + break; + case PM_LayoutMode: + count++; + *((ULONG *)tag->ti_Data)=p->Layout; + break; + case PM_Flags: + count++; + *((ULONG *)tag->ti_Data)=p->Flags; + break; + case PM_NoSelect: + count++; + if (p->Flags&NPM_NOSELECT) *((BOOL *)tag->ti_Data)=TRUE; + else *((BOOL *)tag->ti_Data)=FALSE; + break; + case PM_FillPen: + count++; + if (p->Flags&NPM_FILLTEXT) *((BOOL *)tag->ti_Data)=TRUE; + else *((BOOL *)tag->ti_Data)=FALSE; + break; + case PM_ShadowPen: + count++; + if (p->Flags&NPM_SHADOWTEXT) *((BOOL *)tag->ti_Data)=TRUE; + else *((BOOL *)tag->ti_Data)=FALSE; + break; + case PM_ShinePen: + count++; + if (p->Flags&NPM_SHINETEXT) *((BOOL *)tag->ti_Data)=TRUE; + else *((BOOL *)tag->ti_Data)=FALSE; + break; + case PM_Checkit: + count++; + if (p->Flags&NPM_CHECKIT) *((BOOL *)tag->ti_Data)=TRUE; + else *((BOOL *)tag->ti_Data)=FALSE; + break; + case PM_Checked: + count++; + if (p->Flags&NPM_CHECKED) *((BOOL *)tag->ti_Data)=TRUE; + else *((BOOL *)tag->ti_Data)=FALSE; + break; + case PM_Italic: + count++; + if (p->Flags&NPM_ITALICTEXT) *((BOOL *)tag->ti_Data)=TRUE; + else *((BOOL *)tag->ti_Data)=FALSE; + break; + case PM_Bold: + count++; + if (p->Flags&NPM_BOLDTEXT) *((BOOL *)tag->ti_Data)=TRUE; + else *((BOOL *)tag->ti_Data)=FALSE; + break; + case PM_Underlined: + count++; + if (p->Flags&NPM_UNDERLINEDTEXT) *((BOOL *)tag->ti_Data)=TRUE; + else *((BOOL *)tag->ti_Data)=FALSE; + break; + case PM_TitleBar: + count++; + if (p->Flags&NPM_HBAR) *((BOOL *)tag->ti_Data)=TRUE; + else *((BOOL *)tag->ti_Data)=FALSE; + break; + case PM_WideTitleBar: + count++; + if (p->Flags&NPM_WIDE_BAR) *((BOOL *)tag->ti_Data)=TRUE; + else *((BOOL *)tag->ti_Data)=FALSE; + break; + case PM_ExcludeShared: + count++; + if (p->Flags&NPM_EXCLUDE_SHARED) *((BOOL *)tag->ti_Data)=TRUE; + else *((BOOL *)tag->ti_Data)=FALSE; + break; + case PM_Exclude: + count++; + *((struct PM_IDLst **)tag->ti_Data)=p->Exclude; + break; + case PM_Disabled: + count++; + if (p->Flags&NPM_DISABLED) *((BOOL *)tag->ti_Data)=TRUE; + else *((BOOL *)tag->ti_Data)=FALSE; + break; + case PM_ImageSelected: + case PM_IconSelected: + count++; + *((struct Image **)tag->ti_Data)=p->ImageUnion.Images[1]; + break; + case PM_ImageUnselected: + case PM_IconUnselected: + count++; + *((struct Image **)tag->ti_Data)=p->ImageUnion.Images[0]; + break; + case PM_AutoStore: + count++; + *((BOOL **)tag->ti_Data)=p->AutoSetPtr; + break; + case PM_TextPen: + count++; + *((ULONG *)tag->ti_Data)=p->TextPen; + break; + case PM_Shadowed: + if (p->Flags&NPM_SHADOWED) *((BOOL *)tag->ti_Data)=TRUE; + else *((BOOL *)tag->ti_Data)=FALSE; + count++; + break; + case PM_Center: + if (p->Flags&NPM_CENTERED) *((BOOL *)tag->ti_Data)=TRUE; + else *((BOOL *)tag->ti_Data)=FALSE; + count++; + break; + case PM_CommKey: + *((STRPTR)tag->ti_Data)=p->CommKey; + count++; + break; + case PM_Hidden: + count++; + if (p->Flags&NPM_HIDDEN) *((BOOL *)tag->ti_Data)=TRUE; + else *((BOOL *)tag->ti_Data)=FALSE; + break; + case PM_Toggle: + count++; + if (p->Flags&NPM_NOTOGGLE) *((BOOL *)tag->ti_Data)=FALSE; + else *((BOOL *)tag->ti_Data)=TRUE; + break; + } + } + + return count; +} +LIBFUNC_END +/// diff --git a/scalos/libraries/popupmenu/pmtopography.c b/scalos/libraries/popupmenu/pmtopography.c new file mode 100644 index 000000000..cf8961ed1 --- /dev/null +++ b/scalos/libraries/popupmenu/pmtopography.c @@ -0,0 +1,314 @@ +// +// pmtopography.h +// +// PopupMenu Library - Topographical Menu Map +// +// Copyright (C)2000 Henrik Isaksson +// All Rights Reserved. +// +// $Date$ +// $Revision$ +// + +#include "pmpriv.h" +#include "pmtopography.h" + +#include +#include +#include +#include + + +static BOOL PM_MapShadowPart(PMTRList *top, PMSRList *delta, + const PMSR *shrect, WORD l, WORD t, UWORD ss, + UWORD direction, UBYTE Type); + + +// +// PM_AddTopographicRegion - add a rectangular region of height h to the topographic map. +// +BOOL PM_AddTopographicRegion(PMTRList *lst, WORD l, WORD t, WORD r, WORD b, WORD h) +{ + PMTR rect, *tmprect; + PMTR *worknode, *nextnode; + BOOL fail=FALSE; + + rect.Left=l; + rect.Top=t; + rect.Right=r; + rect.Bottom=b; + rect.Height=h; + rect.n.Length=sizeof(PMTR); + + d1(KPrintF("Adding topographic region: %ld %ld %ld %ld, height: %ld\n", l, t, r, b, h)); + + // + // Step 1: Remove all parts in l that would overlap rect. + // + worknode = (PMTR *)(lst->mlh_Head); /* First node */ + while ((nextnode = (PMTR *)PM_NextNode(worknode))) + { + if (PM_RegionOverlap(worknode, &rect)) + { + PM_UnlinkRegion(lst, worknode); + PM_SubTopographicRects(lst, worknode, &rect); + PM_FreeTopographicNode(worknode); + } + worknode = nextnode; + } + + // + // Step 2: Add rect to l. + // + tmprect=PM_CopyTopographicNode(&rect); + if (tmprect) + { + PM_AddRegionToList(lst, tmprect); + } + else + fail = TRUE; + + return (BOOL) !fail; +} + +// +// PM_CopyTopographicNode - copy a PMTopographicRect, or allocate a new if A is NULL. +// +PMTR *PM_CopyTopographicNode(PMTR *A) +{ + PMTR *newnode; + + newnode=(PMTR *) AllocVec(sizeof(PMTR), MEMF_ANY); + if (newnode && A) + *newnode = *A; + + return newnode; +} + +// +// PM_SubTopographicRects - like PM_SubRects but preserves height +// +BOOL PM_SubTopographicRects(PMTRList *dest, PMTR *worknode, PMTR *rect) +{ + PMTR tmprect, *rectptr; + BOOL fail = FALSE; + + tmprect.Height = worknode->Height; + + tmprect.Left = worknode->Left; + tmprect.Right = worknode->Right; + + tmprect.n.Length = sizeof(tmprect); + + if (rect->Top>worknode->Top && rect->TopBottom) + { + tmprect.Top = worknode->Top; + tmprect.Bottom = rect->Top; + + rectptr = PM_CopyTopographicNode(&tmprect); + if (rectptr) + PM_AddToList((PMDList *)dest, (PMNode *)rectptr); + else + fail = TRUE; + } + + if (rect->Bottom>worknode->Top && rect->BottomBottom) + { + tmprect.Top = rect->Bottom; + tmprect.Bottom = worknode->Bottom; + + rectptr = PM_CopyTopographicNode(&tmprect); + if (rectptr) + PM_AddToList((PMDList *)dest, (PMNode *)rectptr); + else + fail = TRUE; + } + + tmprect.Top = MAX(rect->Top, worknode->Top); + tmprect.Bottom = MIN(rect->Bottom, worknode->Bottom); + + if (rect->Left>worknode->Left && rect->LeftRight) + { + tmprect.Left = worknode->Left; + tmprect.Right = rect->Left; + + rectptr = PM_CopyTopographicNode(&tmprect); + if (rectptr) + PM_AddToList((PMDList *)dest, (PMNode *)rectptr); + else + fail = TRUE; + } + + if (rect->Right>worknode->Left && rect->RightRight) + { + tmprect.Left = rect->Right; + tmprect.Right = worknode->Right; + + rectptr = PM_CopyTopographicNode(&tmprect); + if (rectptr) + PM_AddShadowToList((PMDList *)dest, (PMNode *)rectptr); + else + fail = TRUE; + } + + return (BOOL) !fail; +} + +// +// PM_MapShadow +// +BOOL PM_MapShadow(PMTRList *top, PMSRList *delta, + WORD l, WORD t, WORD r, WORD b, + UWORD menulevel, UWORD direction) +{ + PMSR shrect; + BOOL Success = TRUE; + UWORD ss; + + shrect.Left = l; + shrect.Top = t; + shrect.Right = r; + shrect.Bottom = b; + + // + // The five following calls will create shadows for a lightsource + // positioned somewhere near the top left corner of the screen. + // + // +------------+ + // | |--+ + // | |4 | + // | |--+ + // | | | + // | |1 | + // | | | + // | | | + // +-+-+--------+--+ + // |5| 2 |3 | + // +-+--------+--+ + // + + // Shadow size + ss = menulevel * 2 + 8; + + d1(KPrintF("%s/%s/%ld: left=%ld top=%ld right=%ld bottom=%ld\n", __FILE__, __FUNC__, __LINE__, l, t, r, b)); + + if (direction & PMSHADOW_HORIZ) + { + shrect.Right = l + ss; + } + + if (direction & PMSHADOW_VERT) + { + shrect.Bottom = t + ss; + } + + if ((PMSHADOW_HORIZ | PMSHADOW_VERT) == direction) + { + // bottom right corner + // Shadow 3 + d1(KPrintF("%s/%s/%ld: Shadow 3\n", __FILE__, __FUNC__, __LINE__)); + Success = PM_MapShadowPart(top, delta, &shrect, l, t, ss, direction, SHADOWFLAG_BOTTOM | SHADOWFLAG_RIGHT); + } + else if (direction & PMSHADOW_HORIZ) + { + d1(KPrintF("%s/%s/%ld: PMSHADOW_HORIZ\n", __FILE__, __FUNC__, __LINE__)); + // Shadow 4 + shrect.Top = t; + shrect.Bottom = t + ss; + Success = PM_MapShadowPart(top, delta, &shrect, l, t, ss, direction, SHADOWFLAG_RIGHT | SHADOWFLAG_TOP); + + if (Success) + { + // Shadow 1 + shrect.Top = t + ss; + shrect.Bottom = b; + Success = PM_MapShadowPart(top, delta, &shrect, l, t, ss, direction, SHADOWFLAG_RIGHT); + } + } + else if (direction & PMSHADOW_VERT) + { + d1(KPrintF("%s/%s/%ld: PMSHADOW_VERT\n", __FILE__, __FUNC__, __LINE__)); + // Shadow 5 + shrect.Left = l; + shrect.Right = l + ss; + Success = PM_MapShadowPart(top, delta, &shrect, l, t, ss, direction, SHADOWFLAG_BOTTOM | SHADOWFLAG_LEFT); + + if (Success) + { + // Shadow 2 + shrect.Left = l + ss; + shrect.Right = r; + Success = PM_MapShadowPart(top, delta, &shrect, l, t, ss, direction, SHADOWFLAG_BOTTOM); + } + } + + return Success; +} + + +static BOOL PM_MapShadowPart(PMTRList *top, PMSRList *delta, + const PMSR *shrect, WORD l, WORD t, UWORD ss, + UWORD direction, UBYTE Type) +{ + PMTR *topnode, *nexttopnode; + BOOL Success = TRUE; + + d1(KPrintF("%s/%s/%ld: Left=%ld Top=%ld Right=%ld Bottom=%ld\n", \ + __FILE__, __FUNC__, __LINE__, shrect->Left, shrect->Top, shrect->Right, shrect->Bottom)); + + topnode = (PMTR *)(top->mlh_Head); /* First node */ + while ((nexttopnode = (PMTR *)PM_NextNode(topnode))) + { + PMSR rect, *newnode; + UWORD dx, dy; + + dx = dy = 0; + + d1(KPrintF("Mapping shadow to region: %ld %ld %ld %ld, height: %ld\n", \ + topnode->Left, topnode->Top, topnode->Right, topnode->Bottom, topnode->Height)); + + if (direction & PMSHADOW_HORIZ) + dx = topnode->Height * 2; + if (direction & PMSHADOW_VERT) + dy = topnode->Height * 2; + + rect.pmsr_Type = Type; + + rect.Left = MAX(shrect->Left, topnode->Left); + rect.Right = MIN(shrect->Right-dx, topnode->Right); + rect.Top = MAX(shrect->Top, topnode->Top); + rect.Bottom = MIN(shrect->Bottom-dy, topnode->Bottom); + rect.n.Length = sizeof(PMSR); +#if 0 + if (direction & PMSHADOW_LEFT) + { + if (rect.Left < l + ss - (topnode->Height * 2)) + rect.Left = l + ss - (topnode->Height * 2); + } + + if (direction & PMSHADOW_TOP) + { + if (rect.Top < t+ss-(topnode->Height*2)) + rect.Top = t+ss-(topnode->Height*2); + } +#endif + d1(KPrintF("%s/%s/%ld: Left=%ld Top=%ld RIght=%ld Bottom=%ld\n", \ + __FILE__, __FUNC__, __LINE__, rect.Left, rect.Top, rect.Right, rect.Bottom)); + if (rect.Right > rect.Left && rect.Bottom > rect.Top) + { + newnode = PM_CopyShadowNode(&rect); + if (newnode) + { + AddHead((struct List *)delta, (struct Node *)newnode); + } + else + { + Success = FALSE; + } + } + + topnode = nexttopnode; + } + + return Success; +} diff --git a/scalos/libraries/popupmenu/pmtopography.h b/scalos/libraries/popupmenu/pmtopography.h new file mode 100644 index 000000000..930f81696 --- /dev/null +++ b/scalos/libraries/popupmenu/pmtopography.h @@ -0,0 +1,56 @@ +// +// pmtopography.h +// +// PopupMenu Library - Topographical Menu Map +// +// Copyright ©2000 Henrik Isaksson +// All Rights Reserved. +// +// $Date$ +// $Revision$ +// + +#ifndef PM_TOPOGRAPHY_H +#define PM_TOPOGRAPHY_H + +#ifndef PM_SHADOW_H +#include "pmshadow.h" +#endif + +#define PMSHADOW_HORIZ 0x01 // Adjust shadow width +#define PMSHADOW_VERT 0x02 // Adjust shadow height +#define PMSHADOW_LEFT 0x04 // Adjust shadow left pos +#define PMSHADOW_TOP 0x08 // Adjust shadow top pos + +struct PMTopographicRect { + PMGLN n; + WORD Left; + WORD Top; + WORD Right; + WORD Bottom; + WORD Height; // Height over 'ground' measured in menu levels +}; + +typedef struct PMTopographicRect PMTR; +typedef struct MinList PMTRList; + +#define PM_InitTopographicList() ((PMTRList *)PM_InitList()) +#define PM_FreeTopographicList(l) PM_FreeList((PMDList *)l) +#define PM_CopyTopographicList(l) ((PMTRList *)PM_CopyList((PMDList *)l)) +#define PM_RegionOverlap(A, B) PM_ShadowOverlap((PMSR *)A, (PMSR *)B) +#define PM_AddRegionToList(l, A) PM_AddToList((PMDList *)l, (PMNode *)A) +#define PM_UnlinkRegion(l, A) PM_Unlink((PMDList *)l, (PMNode *)A) +#define PM_FreeTopographicNode(A) PM_FreeNode((PMNode *)A) + +BOOL PM_AddTopographicRegion(PMTRList *lst, // Add a rectangular region of height + WORD l, WORD t, WORD r, WORD b, WORD h); // 'h' to the topographic map. + +BOOL PM_MapShadow(PMTRList *top, PMSRList *delta, + WORD l, WORD t, WORD r, WORD b, + UWORD menulevel, UWORD direction); + +PMTR *PM_CopyTopographicNode(PMTR *A); + +BOOL PM_SubTopographicRects(PMTRList *dest, PMTR *worknode, PMTR *rect); + +#endif diff --git a/scalos/libraries/popupmenu/pmtypes.h b/scalos/libraries/popupmenu/pmtypes.h new file mode 100644 index 000000000..3335e4b34 --- /dev/null +++ b/scalos/libraries/popupmenu/pmtypes.h @@ -0,0 +1,39 @@ +// +// pmtypes.h +// +// OS independent exec/types.h equivalent +// +// $Date$ +// $Revision$ +// + +#ifndef PM_TYPES_H +#define PM_TYPES_H + +#define AMIGA 1 + +#ifdef AMIGA + +#include + +#else + +typedef unsigned long ULONG; +typedef long LONG; + +typedef unsigned short UWORD; +typedef short WORD; + +typedef unsigned char UBYTE; +typedef char BYTE; + +typedef char BOOL; + +typedef char * STRPTR; + +#define TRUE 1 +#define FALSE 0 + +#endif + +#endif /* PM_TYPES_H */ diff --git a/scalos/libraries/popupmenu/pmversion.c b/scalos/libraries/popupmenu/pmversion.c new file mode 100644 index 000000000..4e1825d6e --- /dev/null +++ b/scalos/libraries/popupmenu/pmversion.c @@ -0,0 +1,34 @@ +// +// pmversion.c +// +// PopupMenu Library - Version information +// +// Copyright (C)1996-2001 Henrik Isaksson +// All Rights Reserved. +// +// $Date$ +// $Revision$ +// + +#if defined(__amigaos4__) || defined(__MORPHOS__) +#define __CPU__ "PPC" +#elif defined( _M68020) +#ifdef _M68030 +#ifdef _M68040 +#ifdef _M68060 +#define __CPU__ "060" +#else +#define __CPU__ "040" +#endif +#else +#define __CPU__ "030" +#endif +#else +#define __CPU__ "020" +#endif +#else +#define __CPU__ "000" +#endif + + +char _LibID[] = "$VER: popupmenu.library-" __CPU__ " 10.11 (02.01.2010) ©1996-2010 Henrik Isaksson"; diff --git a/scalos/libraries/popupmenu/popupmenu-aos4.c b/scalos/libraries/popupmenu/popupmenu-aos4.c new file mode 100644 index 000000000..f0f42a79b --- /dev/null +++ b/scalos/libraries/popupmenu/popupmenu-aos4.c @@ -0,0 +1,445 @@ +// popupmenu-aos4.c +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include + +#include + +#ifdef __USE_INLINE__ +#undef __USE_INLINE__ +#endif + +#include + +#include + +#include "pmpriv.h" + +//---------------------------------------------------------------------------- + +// defined in pminit.c +extern struct ExecBase *SysBase; + +// defined in pmversion.c +extern char _LibID[]; + +extern const CONST_APTR VecTable68K[]; + +//---------------------------------------------------------------------------- + +int _start(void) +{ + return -1; +} + +static struct Library *Initlib(struct Library *libbase, BPTR seglist, struct ExecIFace *pIExec); +static BPTR Expungelib(struct LibraryManagerInterface *Self); +static struct LibraryHeader *Openlib(struct LibraryManagerInterface *Self, ULONG version); +static BPTR Closelib(struct LibraryManagerInterface *Self); +static ULONG Obtainlib(struct LibraryManagerInterface *Self); +static ULONG Releaselib(struct LibraryManagerInterface *Self); + +LIBFUNC_P1VA_PROTO(struct PopupMenu *, LIBPM_MakeMenu, + A6, struct PopupMenuBase *, PopupMenuBase); +LIBFUNC_P1VA_PROTO(struct PopupMenu *, LIBPM_MakeItem, + A6, struct PopupMenuBase *, PopupMenuBase); +LIBFUNC_P1VA_PROTO(struct PM_IDLst *, LIBPM_MakeIDList, + A6, struct PopupMenuBase *, PopupMenuBase); + +LIBFUNC_P2VA_PROTO(ULONG, LIBPM_OpenPopupMenu, + A1, struct Window *, wnd, + A6, struct PopupMenuBase *, PopupMenuBase); +LIBFUNC_P2VA_PROTO(LONG, LIBPM_GetItemAttrs, + A2, struct PopupMenu *, item, + A6, struct PopupMenuBase *, PopupMenuBase); +LIBFUNC_P2VA_PROTO(LONG, LIBPM_SetItemAttrs, + A2, struct PopupMenu *, item, + A6, struct PopupMenuBase *, PopupMenuBase); +LIBFUNC_P2VA_PROTO(struct PM_IDLst *, LIBPM_ExLst, + A1, ULONG, id, + A6, struct PopupMenuBase *, PopupMenuBase); +LIBFUNC_P4VA_PROTO(APTR, LIBPM_FilterIMsg, + A0, struct Window *, window, + A1, struct PopupMenu *, menu, + A2, struct IntuiMessage *, imsg, + A6, struct PopupMenuBase *, PopupMenuBase); +LIBFUNC_P3VA_PROTO(LONG, LIBPM_LayoutMenu, + A0, struct Window *, window, + A1, struct PopupMenu *, menu, + A6, struct PopupMenuBase *, PopupMenuBase); +LIBFUNC_P2VA_PROTO(LONG, LIBPM_InsertMenuItem, + A2, struct PopupMenu *, base, + A6, struct PopupMenuBase *, l); + +/* OS4.0 Library */ + +/* ------------------- OS4 Manager Interface ------------------------ */ +static const APTR managerfunctable[] = +{ + (APTR)Obtainlib, + (APTR)Releaselib, + (APTR)NULL, + (APTR)NULL, + (APTR)Openlib, + (APTR)Closelib, + (APTR)Expungelib, + (APTR)NULL, + (APTR)-1 +}; + +static const struct TagItem managertags[] = +{ + {MIT_Name, (ULONG)"__library"}, + {MIT_VectorTable, (ULONG)managerfunctable}, + {MIT_Version, 1}, + {TAG_DONE, 0} +}; + +/* ---------------------- OS4 Main Interface ------------------------ */ +static APTR functable[] = + { + Obtainlib, + Releaselib, + NULL, + NULL, + LIBPM_MakeMenuA, + LIBPM_MakeMenu, + LIBPM_MakeItemA, + LIBPM_MakeItem, + LIBPM_FreePopupMenu, + LIBPM_OpenPopupMenuA, + LIBPM_OpenPopupMenu, + LIBPM_MakeIDListA, + LIBPM_MakeIDList, + LIBPM_ItemChecked, + LIBPM_GetItemAttrsA, + LIBPM_GetItemAttrs, + LIBPM_SetItemAttrsA, + LIBPM_SetItemAttrs, + LIBPM_FindItem, + LIBPM_AlterState, + LIBPM_OBSOLETEFilterIMsgA, + LIBPM_ExLstA, + LIBPM_ExLst, + LIBPM_FilterIMsgA, + LIBPM_FilterIMsg, + LIBPM_InsertMenuItemA, + LIBPM_InsertMenuItem, + LIBPM_RemoveMenuItem, + LIBPM_AbortHook, + LIBPM_GetVersion, + LIBPM_ReloadPrefs, + LIBPM_LayoutMenuA, + LIBPM_LayoutMenu, + LIBPM_RESERVED1, + LIBPM_FreeIDList, + + (APTR) -1 + }; + +static const struct TagItem maintags[] = + { + {MIT_Name, (ULONG)"main"}, + {MIT_VectorTable, (ULONG)functable}, + {MIT_Version, 1}, + {TAG_DONE, 0} + }; + +/* Init table used in library initialization. */ +static const ULONG interfaces[] = +{ + (ULONG)managertags, + (ULONG)maintags, + (ULONG)0 +}; + +static const struct TagItem inittab[] = + { + {CLT_DataSize, (ULONG)sizeof(struct PopupMenuBase)}, + {CLT_Interfaces, (ULONG) interfaces}, + {CLT_Vector68K, (ULONG)VecTable68K}, + {CLT_InitFunc, (ULONG) Initlib}, + {TAG_DONE, 0} + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, + RTF_NATIVE | RTF_AUTOINIT, + POPUPMENU_VERSION, + NT_LIBRARY, + 0, + POPUPMENU_NAME, + (char *)_LibID, + (APTR)inittab + }; + +/* ------------------- OS4 Manager Functions ------------------------ */ +static struct Library * Initlib(struct Library *libbase, BPTR seglist, struct ExecIFace *pIExec) +{ + struct PopupMenuBase *PMLibBase = (struct PopupMenuBase *) libbase; +// struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)libbase + libbase->lib_PosSize); +// struct LibraryManagerInterface *Self = (struct LibraryManagerInterface *) ExtLib->ILibrary; + + SysBase = (struct ExecBase *)pIExec->Data.LibBase; + IExec = pIExec; + PMLibBase->pmb_Library.lib_Revision = POPUPMENU_REVISION; + PMLibBase->pmb_SegList = seglist; + + return PMLibBase ? &PMLibBase->pmb_Library : NULL; +} + +static BPTR Expungelib(struct LibraryManagerInterface *Self) +{ + struct PopupMenuBase *PMLibBase = (struct PopupMenuBase *) Self->Data.LibBase; + + if (0 == PMLibBase->pmb_Library.lib_OpenCnt) + { + BPTR libseglist = PMLibBase->pmb_SegList; + + Remove((struct Node *) PMLibBase); + PMLibCleanup(PMLibBase); + DeleteLibrary((struct Library *)PMLibBase); + + return libseglist; + } + + PMLibBase->pmb_Library.lib_Flags |= LIBF_DELEXP; + + return (BPTR)NULL; +} + +static struct LibraryHeader *Openlib(struct LibraryManagerInterface *Self, ULONG version) +{ + struct PopupMenuBase *PMLibBase = (struct PopupMenuBase *) Self->Data.LibBase; + + PMLibBase->pmb_Library.lib_OpenCnt++; + PMLibBase->pmb_Library.lib_Flags &= ~LIBF_DELEXP; + + if (!PMLibInit(PMLibBase)) + { + Closelib(Self); + return NULL; + } + + return (struct LibraryHeader *)&PMLibBase->pmb_Library; +} + +static BPTR Closelib(struct LibraryManagerInterface *Self) +{ + struct PopupMenuBase *PMLibBase = (struct PopupMenuBase *) Self->Data.LibBase; + + PMLibBase->pmb_Library.lib_OpenCnt--; +/* + if (0 == PMLibBase->pmb_Library.lib_OpenCnt) + { + if (PMLibBase->pmb_Library.lib_Flags & LIBF_DELEXP) + { + return Expungelib(Self); + } + } +*/ + return (BPTR)NULL; +} + +static ULONG Obtainlib(struct LibraryManagerInterface *Self) +{ + return(Self->Data.RefCount++); +} + +static ULONG Releaselib(struct LibraryManagerInterface *Self) +{ + return(Self->Data.RefCount--); +} + +/* ------------------- OS4 Varargs Functions ------------------------ */ +LIBFUNC_P1VA(struct PopupMenu *, LIBPM_MakeMenu, + A6, struct PopupMenuBase *, PopupMenuBase) +{ + struct PopupMenu *ret; + va_list args; + va_startlinear(args, self); // self is always the first argument + + (void)PopupMenuBase; + + ret = ((struct PopupMenuIFace *)self)->PM_MakeMenuA(va_getlinearva(args, struct TagItem *)); + + va_end(args); + + return(ret); +} +LIBFUNC_END + +LIBFUNC_P1VA(struct PopupMenu *, LIBPM_MakeItem, + A6, struct PopupMenuBase *, PopupMenuBase) +{ + struct PopupMenu *ret; + va_list args; + va_startlinear(args, self); // self is always the first argument + + (void)PopupMenuBase; + + ret = ((struct PopupMenuIFace *)self)->PM_MakeItemA(va_getlinearva(args, struct TagItem *)); + + va_end(args); + + return(ret); +} +LIBFUNC_END + +LIBFUNC_P1VA(struct PM_IDLst *, LIBPM_MakeIDList, + A6, struct PopupMenuBase *, PopupMenuBase) +{ + struct PM_IDLst *ret; + va_list args; + va_startlinear(args, self); // self is always the first argument + + (void)PopupMenuBase; + + ret = ((struct PopupMenuIFace *)self)->PM_MakeIDListA(va_getlinearva(args, struct TagItem *)); + + va_end(args); + + return(ret); +} +LIBFUNC_END + +LIBFUNC_P2VA(ULONG, LIBPM_OpenPopupMenu, + A1, struct Window *, wnd, + A6, struct PopupMenuBase *, PopupMenuBase) +{ + ULONG ret; + va_list args; + va_startlinear(args, wnd); + + (void)PopupMenuBase; + + ret = ((struct PopupMenuIFace *)self)->PM_OpenPopupMenuA(wnd, va_getlinearva(args, struct TagItem *)); + + va_end(args); + + return(ret); +} +LIBFUNC_END + +LIBFUNC_P2VA(LONG, LIBPM_GetItemAttrs, + A2, struct PopupMenu *, item, + A6, struct PopupMenuBase *, PopupMenuBase) +{ + LONG ret; + va_list args; + va_startlinear(args, item); + + (void)PopupMenuBase; + + ret = ((struct PopupMenuIFace *)self)->PM_GetItemAttrsA(item, va_getlinearva(args, struct TagItem *)); + + va_end(args); + + return(ret); +} +LIBFUNC_END + +LIBFUNC_P2VA(LONG, LIBPM_SetItemAttrs, + A2, struct PopupMenu *, item, + A6, struct PopupMenuBase *, PopupMenuBase) +{ + LONG ret; + va_list args; + va_startlinear(args, item); + + (void)PopupMenuBase; + + ret = ((struct PopupMenuIFace *)self)->PM_SetItemAttrsA(item, va_getlinearva(args, struct TagItem *)); + + va_end(args); + + return(ret); +} +LIBFUNC_END + +LIBFUNC_P2VA(struct PM_IDLst *, LIBPM_ExLst, + A1, ULONG, id, + A6, struct PopupMenuBase *, PopupMenuBase) +{ + struct PM_IDLst *ret; + va_list args; + va_startlinear(args, id); + + (void)PopupMenuBase; + + ret = ((struct PopupMenuIFace *)self)->PM_ExLstA(&id); + + va_end(args); + + return(ret); +} +LIBFUNC_END + +LIBFUNC_P4VA(APTR, LIBPM_FilterIMsg, + A0, struct Window *, window, + A1, struct PopupMenu *, menu, + A2, struct IntuiMessage *, imsg, + A6, struct PopupMenuBase *, PopupMenuBase) +{ + APTR ret; + va_list args; + va_startlinear(args, imsg); + + (void)PopupMenuBase; + + ret = ((struct PopupMenuIFace *)self)->PM_FilterIMsgA(window, menu, imsg, va_getlinearva(args, struct TagItem *)); + + va_end(args); + + return(ret); +} +LIBFUNC_END + +LIBFUNC_P3VA(LONG, LIBPM_LayoutMenu, + A0, struct Window *, window, + A1, struct PopupMenu *, menu, + A6, struct PopupMenuBase *, PopupMenuBase); +{ + LONG ret; + va_list args; + va_startlinear(args, menu); + + (void)PopupMenuBase; + + ret = ((struct PopupMenuIFace *)self)->PM_LayoutMenuA(window, menu, va_getlinearva(args, struct TagItem *)); + + va_end(args); + + return(ret); +} +LIBFUNC_END + +LIBFUNC_P2VA(LONG, LIBPM_InsertMenuItem, + A2, struct PopupMenu *, base, + A6, struct PopupMenuBase *, PopupMenuBase) +{ + LONG ret; + va_list args; + va_startlinear(args, base); + + (void)PopupMenuBase; + + ret = ((struct PopupMenuIFace *)self)->PM_InsertMenuItemA(base, va_getlinearva(args, struct TagItem *)); + + va_end(args); + + return(ret); +} +LIBFUNC_END + + diff --git a/scalos/libraries/popupmenu/popupmenu-classic.c b/scalos/libraries/popupmenu/popupmenu-classic.c new file mode 100644 index 000000000..7b618344e --- /dev/null +++ b/scalos/libraries/popupmenu/popupmenu-classic.c @@ -0,0 +1,220 @@ +// popupmenu-classic.c +// $Date$ +// $Revision$ + + +#include +#include + +#include + +#include +#include + + +#include "pmpriv.h" +#include "pmfind.h" + +//---------------------------------------------------------------------------- + +// defined in pminit.c +extern struct ExecBase *SysBase; + +struct SegList; + +//---------------------------------------------------------------------------- +// Standard library functions + +static LIB_SAVEDS(struct Library *) LIB_ASM LIB_INTERRUPT Initlib(LIB_REG(d0, struct Library *libbase), + LIB_REG(a0, struct SegList *seglist), LIB_REG(a6, struct ExecBase *sysbase)); + +static LIBFUNC_PROTO(Openlib, libbase, struct Library *); +static LIBFUNC_PROTO(Closelib, libbase, struct SegList *); +static LIBFUNC_PROTO(Expungelib, libbase, struct SegList *); +static LIBFUNC_PROTO(Extfunclib, libbase, ULONG); + +//---------------------------------------------------------------------------- + +// defined in pmversion.c +extern char _LibID[]; + +//---------------------------------------------------------------------------- + +SAVEDS(LONG) ASM Libstart(void) +{ + return -1; +} + +/* OS3.x Library */ + +static APTR functable[] = + { +#ifdef __MORPHOS__ + (APTR) FUNCARRAY_32BIT_NATIVE, +#endif + Openlib, + Closelib, + Expungelib, + Extfunclib, + + LIBPM_MakeMenuA, + LIBPM_MakeItemA, + LIBPM_FreePopupMenu, + LIBPM_OpenPopupMenuA, + LIBPM_MakeIDListA, + LIBPM_ItemChecked, + LIBPM_GetItemAttrsA, + LIBPM_SetItemAttrsA, + LIBPM_FindItem, + LIBPM_AlterState, + LIBPM_OBSOLETEFilterIMsgA, + LIBPM_ExLstA, + LIBPM_FilterIMsgA, + LIBPM_InsertMenuItemA, + LIBPM_RemoveMenuItem, + LIBPM_AbortHook, + LIBPM_GetVersion, + LIBPM_ReloadPrefs, + LIBPM_LayoutMenuA, + LIBPM_RESERVED1, + LIBPM_FreeIDList, + (APTR) -1 + }; + +/* Init table used in library initialization. */ +static ULONG inittab[] = + { + sizeof(struct PopupMenuBase), + (ULONG) functable, + 0, + (ULONG) Initlib + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, +#ifdef __MORPHOS__ + RTF_PPC | RTF_AUTOINIT, +#else + RTF_AUTOINIT, +#endif + POPUPMENU_VERSION, + NT_LIBRARY, + 0, + POPUPMENU_NAME, + _LibID, + inittab + }; + +#ifdef __MORPHOS__ +ULONG __abox__=1; +#endif + +//---------------------------------------------------------------------------- + +static LIB_SAVEDS(struct Library *) LIB_ASM LIB_INTERRUPT Initlib(LIB_REG(d0, struct Library *libbase), + LIB_REG(a0, struct SegList *seglist), LIB_REG(a6, struct ExecBase *sysbase)) +{ + struct PopupMenuBase *PopupMenuBase = (struct PopupMenuBase *) libbase; + + SysBase = sysbase; + + PopupMenuBase->pmb_ExecBase = (struct Library *) SysBase; + PopupMenuBase->pmb_Library.lib_Revision = POPUPMENU_REVISION; + PopupMenuBase->pmb_SegList = (ULONG) seglist; + +#if 0 + if (!IconObjectInit(PopupMenuBase)) + { + CALLLIBFUNC(Expungelib, &PopupMenuBase->pmb_Library); + PopupMenuBase = NULL; + } +#endif + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld PopupMenuBase=%08lx\n", __LINE__, PopupMenuBase)); + + return PopupMenuBase ? &PopupMenuBase->pmb_Library : NULL; +} + + +static LIBFUNC(Openlib, libbase, struct Library *) +{ + struct PopupMenuBase *PopupMenuBase = (struct PopupMenuBase *) libbase; + + PopupMenuBase->pmb_Library.lib_OpenCnt++; + PopupMenuBase->pmb_Library.lib_Flags &= ~LIBF_DELEXP; + + if (!PMLibInit(PopupMenuBase)) + { + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld fail\n", __LINE__)); + CALLLIBFUNC(Closelib, &PopupMenuBase->pmb_Library); + return NULL; + } + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld success\n", __LINE__)); + + return &PopupMenuBase->pmb_Library; +} +LIBFUNC_END + + +static LIBFUNC(Closelib, libbase, struct SegList *) +{ + struct PopupMenuBase *PopupMenuBase = (struct PopupMenuBase *) libbase; + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld OpenCnt=%lu\n", __LINE__, PopupMenuBase->pmb_Library.lib_OpenCnt)); + + PopupMenuBase->pmb_Library.lib_OpenCnt--; + + if (0 == PopupMenuBase->pmb_Library.lib_OpenCnt) + { + if (PopupMenuBase->pmb_Library.lib_Flags & LIBF_DELEXP) + { + return CALLLIBFUNC(Expungelib, &PopupMenuBase->pmb_Library); + } + } + + return NULL; +} +LIBFUNC_END + + +static LIBFUNC(Expungelib, libbase, struct SegList *) +{ + struct PopupMenuBase *PopupMenuBase = (struct PopupMenuBase *) libbase; + + d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld OpenCnt=%lu\n", __LINE__, PopupMenuBase->pmb_Library.lib_OpenCnt)); + + if (0 == PopupMenuBase->pmb_Library.lib_OpenCnt) + { + ULONG size = PopupMenuBase->pmb_Library.lib_NegSize + PopupMenuBase->pmb_Library.lib_PosSize; + UBYTE *ptr = (UBYTE *) PopupMenuBase - PopupMenuBase->pmb_Library.lib_NegSize; + struct SegList *libseglist = (struct SegList *) PopupMenuBase->pmb_SegList; + + Remove((struct Node *) PopupMenuBase); + PMLibCleanup(PopupMenuBase); + FreeMem(ptr,size); + + return libseglist; + } + + PopupMenuBase->pmb_Library.lib_Flags |= LIBF_DELEXP; + + return NULL; +} +LIBFUNC_END + + +static LIBFUNC(Extfunclib, libbase, ULONG) +{ + (void) libbase; + + return 0; +} +LIBFUNC_END + + diff --git a/scalos/libraries/popupmenu/popupmenu.h b/scalos/libraries/popupmenu/popupmenu.h new file mode 100644 index 000000000..cd174eb08 --- /dev/null +++ b/scalos/libraries/popupmenu/popupmenu.h @@ -0,0 +1,313 @@ +/* +// $VER: pm.h 10.05 (11.11.00) +// +// Library base, tags and macro definitions +// for popupmenu.library. +// +// ©1996-2000 Henrik Isaksson +// All Rights Reserved. +// +// $Date$ +// $Revision$ +// +// Changes: +// +// 9.00 New PopupMenu structure. +// Several new tags and updated macros. +// 9.01 Added PM_HintBox +// 10.0 Added PM_Toggle, PM_ExcludeShared +// Added macro PMMXItem +// Added two flags, PM_CHECKIT and PM_CHECKED +// 10.05 Changed the PopupMenu structure a bit. +// Added typedef for PopupMenu. +// Added american english equalients for some tags. +// +*/ + +#ifndef LIBRARIES_POPUPMENU_H +#define LIBRARIES_POPUPMENU_H + +#ifndef EXEC_TYPES_H +#include +#endif + +#ifndef EXEC_LIBRARIES_H +#include +#endif + +#ifndef UTILITY_TAGITEM_H +#include +#endif + +#ifndef INTUITION_CLASSUSR_H +#include +#endif + +/* +// Tags passed to PM_OpenPopupMenuA and PM_FilterIMsgA +*/ + +#define PM_Menu (TAG_USER+4) /* (struct PopupMenu *) Pointer to menulist initialized by MakeMenu() */ +#define PM_Top (TAG_USER+12) /* (LONG) Top (Y) position */ +#define PM_Left (TAG_USER+13) /* (LONG) Left (X) position */ +#define PM_Code (TAG_USER+14) /* (UWORD) Obsolete. */ +#define PM_Right (TAG_USER+15) /* (LONG) X position relative to right edge */ +#define PM_Bottom (TAG_USER+16) /* (LONG) Y position relative to bottom edge */ +#define PM_MinWidth (TAG_USER+17) /* (LONG) Minimum width */ +#define PM_MinHeight (TAG_USER+18) /* (LONG) Minimum height */ +#define PM_ForceFont (TAG_USER+19) /* (struct TextFont *tf) Use this font instead of user preferences. */ +#define PM_PullDown (TAG_USER+90) /* (BOOL) Turn the menu into a pulldown menu. */ +#define PM_MenuHandler (TAG_USER+91) /* (struct Hook *) Hook that is called for each selected item, after the */ + /* menu has been closed. This tag turns on MultiSelect. */ +#define PM_AutoPullDown (TAG_USER+92) /* (BOOL) Automatic pulldown menu. (PM_FilterIMsg only) */ +#define PM_LocaleHook (TAG_USER+93) /* (struct Hook *) Locale "GetString()" hook. (Not yet implemented) */ +#define PM_CenterScreen (TAG_USER+94) /* (BOOL) Center menu on the screen */ +#define PM_UseLMB (TAG_USER+95) /* (BOOL) Left mouse button should be used to select an item */ + /* (right button selects multiple items) */ +#define PM_DRIPensOnly (TAG_USER+96) /* (BOOL) Only use the screen's DRI pens, revert to system images if necessary. */ + /* Use with care as it overrides the user's prefs! */ +#define PM_HintBox (TAG_USER+97) /* (BOOL) Close the menu when the mouse is moved. */ +#define PM_RawKey (TAG_USER+98) /* (BOOL) Let PM_FilterIMsgA parse IDCMP_RAWKEY instead of IDCMP_VANILLAKEY. */ + +/* +// Tags passed to MakeItem +*/ + +#define PM_Title (TAG_USER+20) /* (STRPTR) Item title */ +#define PM_UserData (TAG_USER+21) /* (void *) Anything, returned by OpenPopupMenu when this item is selected */ +#define PM_ID (TAG_USER+22) /* (ULONG) ID number, if you want an easy way to access this item later */ +#define PM_CommKey (TAG_USER+47) /* (char) Keyboard shortcut for this item. */ +#define PM_TitleID (TAG_USER+49) /* (ULONG) Locale string ID */ +#define PM_Object (TAG_USER+43) /* (Object *) BOOPSI object with the abillity to render this item */ + +/* Submenu & Layout tags */ +/* PM_Sub & PM_Members are mutally exclusive */ +#define PM_Sub (TAG_USER+23) /* (PopupMenu *) Pointer to submenu list (from PM_MakeMenu) */ +#define PM_Members (TAG_USER+65) /* (PopupMenu *) Members for this group (list created by PM_MakeMenu) */ +#define PM_LayoutMode (TAG_USER+64) /* (ULONG) Layout method (PML_Horizontal / PML_Vertical) */ + +/* Text attributes */ +#define PM_FillPen (TAG_USER+26) /* (BOOL) Make the item appear in FILLPEN */ +#define PM_Italic (TAG_USER+29) /* (BOOL) Italic text */ +#define PM_Bold (TAG_USER+30) /* (BOOL) Bold text */ +#define PM_Underlined (TAG_USER+31) /* (BOOL) Underlined text */ +#define PM_ShadowPen (TAG_USER+34) /* (BOOL) Draw text in SHADOWPEN */ +#define PM_ShinePen (TAG_USER+35) /* (BOOL) Draw text in SHINEPEN */ +#define PM_Centre (TAG_USER+36) /* (BOOL) Center the text of this item */ +#define PM_Center PM_Centre /* American version... */ +#define PM_TextPen (TAG_USER+45) /* (ULONG) Pen number for text colour of this item */ +#define PM_Shadowed (TAG_USER+48) /* (BOOL) Draw a shadow behind the text */ + +/* Other item attributes */ +#define PM_TitleBar (TAG_USER+32) /* (BOOL) Horizontal separator bar */ +#define PM_WideTitleBar (TAG_USER+33) /* (BOOL) Same as above, but full width */ +#define PM_NoSelect (TAG_USER+25) /* (BOOL) Make the item unselectable (without visual indication) */ +#define PM_Disabled (TAG_USER+38) /* (BOOL) Disable an item */ +#define PM_Hidden (TAG_USER+63) /* (BOOL) This item is not to be drawn (nor used in the layout process) */ + +/* Images & Icons */ +#define PM_ImageSelected (TAG_USER+39) /* (struct Image *) Image when selected, title will be rendered on top it */ +#define PM_ImageUnselected (TAG_USER+40) /* (struct Image *) Image when unselected */ +#define PM_IconSelected (TAG_USER+41) /* (struct Image *) Icon when selected */ +#define PM_IconUnselected (TAG_USER+42) /* (struct Image *) Icon when unselected */ + +/* Check/MX items */ +#define PM_Checkit (TAG_USER+27) /* (BOOL) Leave space for a checkmark */ +#define PM_Checked (TAG_USER+28) /* (BOOL) Make this item is checked */ +#define PM_AutoStore (TAG_USER+44) /* (BOOL *) Pointer to BOOL reflecting the current state of the item */ +#define PM_Exclude (TAG_USER+37) /* (PM_IDLst *) Items to unselect or select when this gets selected */ +#define PM_ExcludeShared (TAG_USER+101) /* (BOOL) Used if the list is shared between two or more items */ +#define PM_Toggle (TAG_USER+100) /* (BOOL) Enable/disable toggling of check/mx items. Default: TRUE */ + +/* Dynamic construction/destruction */ +#define PM_SubConstruct (TAG_USER+61) /* (struct Hook *) Constructor hook for submenus. Called before menu is opened. */ +#define PM_SubDestruct (TAG_USER+62) /* (struct Hook *) Destructor hook for submenus. Called after menu has closed. */ + +/* Special/misc. stuff */ +#define PM_UserDataString (TAG_USER+46) /* (STRPTR) Allocates memory and copies the string to UserData. */ +#define PM_Flags (TAG_USER+24) /* (UlONG) For internal use */ +#define PM_ColourBox (TAG_USER+60) /* (UlONG) Filled rectangle (for palettes etc.) */ +#define PM_ColorBox PM_ColourBox /* For Americans... */ +/* +// Tags passed to MakeMenu +*/ + +#define PM_Item (TAG_USER+50) /* (PopupMenu *) Item pointer from MakeItem */ +#define PM_Dummy (TAG_USER+51) /* (void) Ignored. */ + +/* +// Tags passed to MakeIDList +*/ + +#define PM_ExcludeID (TAG_USER+55) /* (ULONG) ID number of menu to deselect when this gets selected */ +#define PM_IncludeID (TAG_USER+56) /* (ULONG) ID number of menu to select when this gets selected */ +#define PM_ReflectID (TAG_USER+57) /* (ULONG) ID number of menu that should reflect the state of this one */ +#define PM_InverseID (TAG_USER+58) /* (ULONG) ID number of menu to inverse reflect the state of this one */ + +/* +// Tags for PM_InsertMenuItemA() +*/ + +#define PM_Insert_Before (TAG_USER+200) /* (BOOL) Insert before the item pointed to by the following argument (N/A) */ +#define PM_Insert_BeforeID (TAG_USER+201) /* (ULONG) Insert before the first item with ID equal to the argument */ +#define PM_Insert_After (TAG_USER+202) /* (PopupMenu *) Insert after the item pointed to by the following argument */ +#define PM_Insert_AfterID (TAG_USER+203) /* (ULONG) Insert after the first item with ID equal to the argument */ +#define PM_Insert_Last (TAG_USER+205) /* (BOOL) Insert after the last item */ +#define PM_Insert_First (TAG_USER+209) /* (BOOL) Insert after the first item (which is usually invisible) */ +#define PM_InsertSub_First (TAG_USER+206) /* (PopupMenu *) Insert before the first item in the submenu */ +#define PM_InsertSub_Last (TAG_USER+207) /* (PopupMenu *) Insert at the and of a submenu */ +#define PM_InsertSub_Sorted (TAG_USER+208) /* (PopupMenu *) (N/A) */ +#define PM_Insert_Item (TAG_USER+210) /* (PopupMenu *) Item to insert, may be repeated for several items */ + +/* +// Layout methods +*/ + +#define PML_None 0 /* Normal item */ +#define PML_Horizontal 1 /* Horizontal group */ +#define PML_Vertical 2 /* Vertical group */ +#define PML_Table 3 /* Table group */ +#define PML_Default 255 /* Don't use */ + +/* +// Macros +*/ + +#define PMMenu(t) PM_MakeMenu(\ + PM_Item, PM_MakeItem(PM_Hidden, TRUE, TAG_DONE),\ + PM_Item, PM_MakeItem(PM_Title, t, PM_NoSelect, TRUE, PM_ShinePen, TRUE, PM_Shadowed, TRUE, PM_Center, TRUE, TAG_DONE),\ + PM_Item, PM_MakeItem(PM_WideTitleBar, TRUE, TAG_DONE) +#define PMMenuID(t) PM_MakeMenu(\ + PM_Item, PM_MakeItem(PM_Hidden, TRUE, TAG_DONE),\ + PM_Item, PM_MakeItem(PM_TitleID, t, PM_NoSelect, TRUE, PM_ShinePen, TRUE, PM_Shadowed, TRUE, PM_Center, TRUE, TAG_DONE),\ + PM_Item, PM_MakeItem(PM_WideTitleBar, TRUE, TAG_DONE) +#define PMSubMenu(t) PM_Sub, PM_MakeMenu(PM_Item, PM_MakeItem(PM_Title, t, PM_NoSelect, TRUE, PM_ShinePen, TRUE, TAG_DONE),\ + PM_Item, PM_MakeItem(PM_WideTitleBar, TRUE, TAG_DONE) +#define PMSimpleSub PM_Sub, PM_MakeMenu(PM_Dummy, 0 +#define PMItem(t) PM_Item, PM_MakeItem(PM_Title, t +#define PMItemID(t) PM_Item, PM_MakeItem(PM_TitleID, t +#define PMInfo(t) PM_Item, PM_MakeItem(PM_Title, t, PM_NoSelect, TRUE, PM_ShinePen, TRUE +#define PMColBox(c) PM_Item, PM_MakeItem(PM_ColourBox, c +#define PMBar PM_Item, PM_MakeItem(PM_TitleBar, TRUE +#define PMMenuTitle(t) PM_Item, PM_MakeItem(PM_Title, t, PM_NoSelect, TRUE, PM_ShinePen, TRUE, PM_Shadowed, TRUE, PM_Center, TRUE, TAG_DONE),\ + PM_Item, PM_MakeItem(PM_WideTitleBar, TRUE, TAG_DONE) +#define PMHoriz PM_Item, PM_MakeItem(PM_NoSelect, TRUE, PM_LayoutMode, PML_Horizontal +#define PMVert PM_Item, PM_MakeItem(PM_NoSelect, TRUE, PM_LayoutMode, PML_Vertical +#define PMMembers PM_Members, PM_MakeMenu(PM_Dummy, 0 + +#define PMExcl PM_Exclude, PM_MakeIDList( +#define ExID(id) PM_ExcludeID, id +#define InID(id) PM_IncludeID, id +#define RefID(id) PM_ReflectID, id +#define InvID(id) PM_InverseID, id + +#define PMCheckItem(t,id) PM_Item, PM_MakeItem(PM_Title, t, PM_ID, id, PM_Checkit, TRUE + +#define PMMXItem(t,id) PM_Item, PM_MakeItem(PM_Title, t, PM_ID, id, PM_Checkit, TRUE, PM_Toggle, FALSE + +#define PMEnd TAG_DONE) + +#ifndef End +#define End TAG_DONE) +#endif + +#define PMERR (-5L) + +/* For compatibility with old sources - DO NOT USE */ +#define PMTitleBar PMBar +#define PMNarrowBar PMBar +#define PMNarrowTitleBar PMBar + +/* +// Library base +*/ + +#ifndef PM_NOBASE + +struct PopupMenuBase { + struct Library pmb_Library; + ULONG pmb_SegList; + ULONG pmb_Flags; + struct Library *pmb_ExecBase; /* Theese library */ + struct Library *pmb_UtilityBase; /* pointers are */ + struct Library *pmb_IntuitionBase; /* valid as long */ + struct Library *pmb_GfxBase; /* as pm lib */ + struct Library *pmb_DOSBase; /* is open. */ + BOOL pmb_NewPrefs; /* Reload prefs. */ + struct Library *pmb_CxBase; /* commodities. */ + struct Library *pmb_LayersBase; /* layers.library */ + struct Library *pmb_CyberGfxBase; /* cybergfx.lib */ +}; + +#endif + +#define POPUPMENU_VERSION 10L +#define POPUPMENU_NAME "popupmenu.library" +#define OPEN_PM_LIB (PopupMenuBase=(struct PopupMenuBase *)\ + OpenLibrary(POPUPMENU_NAME, POPUPMENU_VERSION)) +#define CLOSE_PM_LIB if(PopupMenuBase) CloseLibrary((struct Library *)PopupMenuBase); + +/* +// PopupMenu structure +// +// Note: +// This structure may change in future versions. +// Do not read or write fields directly, use PM_Set/GetPopupMenuAttrs() +*/ + +struct PopupMenu { + struct PopupMenu *Next; /* Next item in menu */ + union { + struct PopupMenu *Sub; /* Sub menu pointer */ + struct PopupMenu *Group; /* Group members */ + } SubGroup; + + union { + STRPTR Title; /* Title */ + ULONG TitleID; /* Locale string ID */ + Object *Boopsi; /* Boopsi object */ + } TitleUnion; + + ULONG Flags; /* Flags */ + ULONG ID; /* Item ID */ + APTR UserData; /* UserData */ + + WORD Left; /* Left pos of this item */ + WORD Top; /* Top pos of this item */ + UWORD Width; /* Width of this item */ + UWORD Height; /* Height of this item */ + + /* Very private and undocumented stuff follows. */ + /* Mess with it at your own risk. */ + + UWORD ExtFlags; /* Extended flags */ + + UBYTE Layout; /* Layout mode */ + UBYTE CBox; /* ColourBox pen */ + + struct PM_IDLst *Exclude; /* Exclude/Included/Reflected items */ + BOOL *AutoSetPtr;/* Ptr to BOOL containing current state */ + + union { + struct Image *Images[2]; /* Images/Icons (0 - unselected, 1 - sel) */ + STRPTR IconID; + } ImageUnion; + + UBYTE CommKey; /* Command Key */ + UBYTE Weight; /* Weight */ + struct Hook *SubConstruct; /* SubMenu Constructor hook */ + struct Hook *SubDestruct; /* SubMenu Destructor hook */ + UBYTE TextPen; /* Pen number for item's text */ + UBYTE Pad; + + APTR Image; +}; + +typedef struct PopupMenu PopupMenu; + +/* Public flags for the PopupMenu->Header.Flags field */ + +#define PM_CHECKIT 0x40000000 +#define PM_CHECKED 0x80000000 + +#endif diff --git a/scalos/libraries/popupmenu/window.c b/scalos/libraries/popupmenu/window.c new file mode 100644 index 000000000..eb61860c6 --- /dev/null +++ b/scalos/libraries/popupmenu/window.c @@ -0,0 +1,312 @@ +// +// Popup Menu Window funcs +// ©1996-2002 Henrik Isaksson +// +// $Date$ +// $Revision$ +// + +#include "pmpriv.h" + +struct RGB +{ + UBYTE Red; + UBYTE Green; + UBYTE Blue; +}; + +static void PM_BlurPixelArray(struct RGB *Dest, const struct RGB *Src, + UWORD SizeX, UWORD SizeY, ULONG Blur); + + +// +// Allocate memory and copy a RastPort structure +// +struct RastPort *PM_CpyRPort(struct RastPort *rp) +{ +#ifdef __AROS__ + return CloneRastPort(rp); +#else + struct RastPort *rpc; + + rpc=PM_Mem_Alloc(sizeof(struct RastPort)); + if (rpc) { + CopyMem(rp, rpc, sizeof(struct RastPort)); + } + + return rpc; +#endif +} + +// +// Copy the region beneath a window to the transparency buffer. +// +void PM_TransparencyBfr(struct PM_Window *bw) +{ + int j, bpp; + ULONG transparent; + struct RGB *TempArray = NULL; + + transparent = PM_Prefs->pmp_Flags & PMP_FLAGS_TRANSPARENCY; +#if 0 +#ifndef __AROS__ + GetGUIAttrs(NULL, bw->p->DrawInfo, GUIA_MenuTransparency, &transparent, TAG_DONE); +#endif +#endif + + do { + ULONG BytesPerRow = sizeof(struct RGB) * bw->Width; + + if (!CyberGfx) + break; + if (!transparent) + break; + + if (!GetCyberMapAttr(bw->Wnd->WScreen->RastPort.BitMap, CYBRMATTR_ISCYBERGFX)) + break; + + bpp = GetCyberMapAttr(bw->Wnd->WScreen->RastPort.BitMap, CYBRMATTR_BPPIX); + if (bpp<2) + break; + + // If we've gotten this far, the screen is CyberGfx and > 15 bpp + + TempArray = PM_Mem_Alloc(BytesPerRow * bw->Height); + if (NULL == TempArray) + break; + + bw->bg.BgArray = PM_Mem_Alloc(BytesPerRow * bw->Height); + if (NULL == bw->bg.BgArray) + break; + + ReadPixelArray(TempArray, 0, 0, + BytesPerRow, + bw->RPort, + 0, 0, + bw->Width, bw->Height, + RECTFMT_RGB); + + PM_BlurPixelArray((struct RGB *) bw->bg.BgArray, TempArray, + bw->Width, bw->Height, PM_Prefs->pmp_TransparencyBlur + 1); + + // Fast and simple way to blend the background to gray... + for(j = 0; j < BytesPerRow * bw->Height; j++) + { + bw->bg.BgArray[j] = (bw->bg.BgArray[j]>>2) + 150; + } + } while (0); + + if (TempArray) + PM_Mem_Free(TempArray); +} + +static void PM_BlurPixelArray(struct RGB *Dest, const struct RGB *Src, + UWORD SizeX, UWORD SizeY, ULONG Blur) +{ + ULONG y; + ULONG Divisor = Blur + 24; + + for (y = 0; y < SizeY; y++) + { + ULONG x; + const struct RGB *SrcPtr = Src; + const struct RGB *Upper, *Lower; + const struct RGB *Upper2, *Lower2; + struct RGB *DestPtr = Dest; + + Upper = Upper2 = Lower = Lower2 = SrcPtr; + if (y > 0) + Upper -= SizeX; + if (y > 1) + Upper2 -= 2 * SizeX; + if (y < (SizeY - 1)) + Lower += SizeX; + if (y < (SizeY - 2)) + Lower2 += SizeX; + + for (x = 0; x < SizeX; x++) + { + ULONG Left, Right; + ULONG Left2, Right2; + + Left = (x > 0) ? -1 : 0; + Left2 = (x > 1) ? -2 : 0; + Right = (x < (SizeX - 1)) ? 1 : 0; + Right2 = (x < (SizeX - 2)) ? 2 : 0; + + DestPtr->Red = (Upper2[Left2].Red + Upper2[Left].Red + Upper2[0].Red + Upper2[Right].Red + Upper2[Right2].Red + + Upper[Left2].Red + Upper[Left].Red + Upper[0].Red + Upper[Right].Red + Upper[Right2].Red + + SrcPtr[Left2].Red + SrcPtr[Left].Red + Blur * SrcPtr[0].Red + SrcPtr[Right].Red + SrcPtr[Right2].Red + + Lower[Left2].Red + Lower[Left].Red + Lower[0].Red + Lower[Right].Red + Lower[Right2].Red + + Lower2[Left2].Red + Lower2[Left].Red + Lower2[0].Red + Lower2[Right].Red + Lower2[Right2].Red ) / Divisor; + + DestPtr->Green = (Upper2[Left2].Green + Upper2[Left].Green + Upper2[0].Green + Upper2[Right].Green + Upper2[Right2].Green + + Upper[Left2].Green + Upper[Left].Green + Upper[0].Green + Upper[Right].Green + Upper[Right2].Green + + SrcPtr[Left2].Green + SrcPtr[Left].Green + Blur * SrcPtr[0].Green + SrcPtr[Right].Green + SrcPtr[Right2].Green + + Lower[Left2].Green + Lower[Left].Green + Lower[0].Green + Lower[Right].Green + Lower[Right2].Green + + Lower2[Left2].Green + Lower2[Left].Green + Lower2[0].Green + Lower2[Right].Green + Lower2[Right2].Green ) / Divisor; + + DestPtr->Blue = (Upper2[Left2].Blue + Upper2[Left].Blue + Upper2[0].Blue + Upper2[Right].Blue + Upper2[Right2].Blue + + Upper[Left2].Blue + Upper[Left].Blue + Upper[0].Blue + Upper[Right].Blue + Upper[Right2].Blue + + SrcPtr[Left2].Blue + SrcPtr[Left].Blue + Blur * SrcPtr[0].Blue + SrcPtr[Right].Blue + SrcPtr[Right2].Blue + + Lower[Left2].Blue + Lower[Left].Blue + Lower[0].Blue + Lower[Right].Blue + Lower[Right2].Blue + + Lower2[Left2].Blue + Lower2[Left].Blue + Lower2[0].Blue + Lower2[Right].Blue + Lower2[Right2].Blue ) / Divisor; + + SrcPtr++; + Upper++; + Upper2++; + Lower++; + Lower2++; + DestPtr++; + } + + Src += SizeX; + Dest += SizeX; + } +} + + +// +// Create an offscreen buffer for rendering animation and transition +// effects. +// +void PM_OffScreenBfr(struct PM_Window *bw) +{ + if (PM_Prefs->pmp_Animation) { + bw->te.BMap=AllocBitMap(bw->Width, bw->Height, bw->Wnd->WScreen->RastPort.BitMap->Depth, BMF_MINPLANES, bw->Wnd->WScreen->RastPort.BitMap); + if (bw->te.BMap) { + bw->te.RPort=PM_CpyRPort(&bw->Wnd->WScreen->RastPort); + if (bw->te.RPort) { + bw->te.RPort->Layer = NULL; /* huuu! */ + bw->te.RPort->BitMap = bw->te.BMap; + } + } + } +} + +// +// Open a window +// +BOOL PM_OpenWindow(struct PM_Window *pw, int left, int top, int width, int height, struct Screen *scr) +{ + pw->bg.BgArray = NULL; + pw->te.RPort = NULL; + pw->te.BMap = NULL; + pw->Wnd = OpenWindowTags(NULL, + WA_Borderless, TRUE, + WA_RMBTrap, TRUE, + WA_Left, left, + WA_Top, top, + WA_Width, width, + WA_Height, height, + //WA_ReportMouse, TRUE, + WA_CustomScreen, scr, + //WA_IDCMP, IDCMP_CLOSEWINDOW, // Kommer aldrig att inträffa - anv. för resize + WA_SmartRefresh, TRUE, + WA_BackFill, LAYERS_NOBACKFILL, +#if defined(WA_FrontWindow) + WA_FrontWindow, TRUE, +#endif /* WA_FrontWindow */ + TAG_DONE); + + if (pw->Wnd) + { + pw->RPort = pw->Wnd->RPort; + d1(KPrintF("%s/%s/%ld: pw=%08lx RPort=%08lx\n", __FILE__, __FUNC__, __LINE__, pw, pw->RPort)); + + /* Transparency/background image */ + PM_TransparencyBfr(pw); + + /* Transition effects */ + PM_OffScreenBfr(pw); + + return TRUE; + } + else + { + DisplayBeep(NULL); + return FALSE; + } +} + +// +// Close a window +// +void PM_CloseWindow(struct PM_Window *bw) +{ + if (bw->bg.BgArray) PM_Mem_Free(bw->bg.BgArray); +#ifdef __AROS__ + if (bw->te.RPort) FreeRastPort(bw->te.RPort); +#else + if (bw->te.RPort) PM_Mem_Free(bw->te.RPort); +#endif + if (bw->te.BMap) FreeBitMap(bw->te.BMap); + if (bw->Wnd) CloseWindow(bw->Wnd); + + bw->bg.BgArray = NULL; + bw->te.RPort = NULL; + bw->te.BMap = NULL; + bw->Wnd = NULL; +} + +// +// Resize a window +// +void PM_ResizeWindow(struct PM_Window *bw, int l, int t, int w, int h) +{ + struct Message *msg; + + if (l==bw->Wnd->LeftEdge && t==bw->Wnd->TopEdge && w==bw->Width && h==bw->Height) + return; // If no change + + ModifyIDCMP(bw->Wnd, IDCMP_CLOSEWINDOW|IDCMP_NEWSIZE); + ChangeWindowBox(bw->Wnd, l, t, w, h); + WaitPort(bw->Wnd->UserPort); + while ((msg=GetMsg(bw->Wnd->UserPort))) ReplyMsg(msg); + ModifyIDCMP(bw->Wnd, IDCMP_CLOSEWINDOW); + + // bw->Width=bw->wnd->Width; + // bw->Height=bw->wnd->Height; +} + +// +// Find out if we should close our submenu +// + +// +// PM_InsideWindows(px, py, wnd) +// +// px, py - Screen coords +// wnd - PM_Window +// + +BOOL PM_InsideWindows(int px, int py, struct PM_Window *wnd) +{ + int x=px; + int y=py; + struct PM_Window *w; + + w = wnd->Prev; + + if (w) { + if (w->Selected) { + if (px > w->Wnd->LeftEdge + w->Selected->Left - 2 && + px < w->Wnd->LeftEdge + w->Selected->Left + w->Selected->Width + 2 && + py > w->Wnd->TopEdge + w->Selected->Top - 2 && + py < w->Wnd->TopEdge + w->Selected->Top + w->Selected->Height + 2) + return FALSE; + } + } + + while (w) { + if (x > w->Wnd->LeftEdge && + y >= w->Wnd->TopEdge && + x < w->Wnd->LeftEdge + w->Width && + y < w->Wnd->TopEdge + w->Height) { + return TRUE; + } + w=w->Prev; + } + + return FALSE; +} diff --git a/scalos/libraries/preferences/Preferences-aos4-68kstubs.c b/scalos/libraries/preferences/Preferences-aos4-68kstubs.c new file mode 100644 index 000000000..7dbaf3691 --- /dev/null +++ b/scalos/libraries/preferences/Preferences-aos4-68kstubs.c @@ -0,0 +1,220 @@ +/* +** This file was automatically generated by fdtrans 52.1. +** Do not edit it by hand. Instead, edit the sfd file +** that was used to generate this file +*/ + +#ifdef __USE_INLINE__ +#undef __USE_INLINE__ +#endif +#ifndef __NOGLOBALIFACE__ +#define __NOGLOBALIFACE__ +#endif + +#include +#include +#include +#include +#include +#include + + +static inline int8 convert_int8 (uint32 x) { return x; } +static inline int16 convert_int16(uint32 x) { return x; } + + +STATIC struct Library * stub_OpenPPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct LibraryManagerInterface *Self = (struct LibraryManagerInterface *) ExtLib->ILibrary; + + return Self->Open(0); +} +STATIC CONST struct EmuTrap stub_Open = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_OpenPPC }; + +STATIC APTR stub_ClosePPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct LibraryManagerInterface *Self = (struct LibraryManagerInterface *) ExtLib->ILibrary; + + return Self->Close(); +} +STATIC CONST struct EmuTrap stub_Close = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_ClosePPC }; + +STATIC APTR stub_ExpungePPC(ULONG *regarray __attribute__((unused))) +{ + return NULL; +} +STATIC CONST struct EmuTrap stub_Expunge = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_ExpungePPC }; + +STATIC ULONG stub_ReservedPPC(ULONG *regarray __attribute__((unused))) +{ + return 0UL; +} +STATIC CONST struct EmuTrap stub_Reserved = { TRAPINST, TRAPTYPE, stub_ReservedPPC }; + +static APTR stub_AllocPrefsHandlePPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct PreferencesIFace *Self = (struct PreferencesIFace *) ExtLib->MainIFace; + + return Self->AllocPrefsHandle( + (CONST_STRPTR)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_AllocPrefsHandle = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_AllocPrefsHandlePPC }; + +static VOID stub_FreePrefsHandlePPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct PreferencesIFace *Self = (struct PreferencesIFace *) ExtLib->MainIFace; + + Self->FreePrefsHandle( + (APTR)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_FreePrefsHandle = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_FreePrefsHandlePPC }; + +static VOID stub_SetPreferencesPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct PreferencesIFace *Self = (struct PreferencesIFace *) ExtLib->MainIFace; + + Self->SetPreferences( + (APTR)regarray[8], + (ULONG)regarray[0], + (ULONG)regarray[1], + (const APTR)regarray[9], + (UWORD)(regarray[2] & 0xffff) + ); +} +STATIC CONST struct EmuTrap stub_SetPreferences = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_SetPreferencesPPC }; + +static ULONG stub_GetPreferencesPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct PreferencesIFace *Self = (struct PreferencesIFace *) ExtLib->MainIFace; + + return Self->GetPreferences( + (APTR)regarray[8], + (ULONG)regarray[0], + (ULONG)regarray[1], + (APTR)regarray[9], + (UWORD)(regarray[2] & 0xffff) + ); +} +STATIC CONST struct EmuTrap stub_GetPreferences = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_GetPreferencesPPC }; + +static VOID stub_ReadPrefsHandlePPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct PreferencesIFace *Self = (struct PreferencesIFace *) ExtLib->MainIFace; + + Self->ReadPrefsHandle( + (APTR)regarray[8], + (CONST_STRPTR)regarray[9] + ); +} +STATIC CONST struct EmuTrap stub_ReadPrefsHandle = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_ReadPrefsHandlePPC }; + +static VOID stub_WritePrefsHandlePPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct PreferencesIFace *Self = (struct PreferencesIFace *) ExtLib->MainIFace; + + Self->WritePrefsHandle( + (APTR)regarray[8], + (CONST_STRPTR)regarray[9] + ); +} +STATIC CONST struct EmuTrap stub_WritePrefsHandle = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_WritePrefsHandlePPC }; + +static struct PrefsStruct * stub_FindPreferencesPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct PreferencesIFace *Self = (struct PreferencesIFace *) ExtLib->MainIFace; + + return Self->FindPreferences( + (APTR)regarray[8], + (ULONG)regarray[0], + (ULONG)regarray[1] + ); +} +STATIC CONST struct EmuTrap stub_FindPreferences = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_FindPreferencesPPC }; + +static VOID stub_SetEntryPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct PreferencesIFace *Self = (struct PreferencesIFace *) ExtLib->MainIFace; + + Self->SetEntry( + (APTR)regarray[8], + (ULONG)regarray[0], + (ULONG)regarray[1], + (const APTR)regarray[9], + (UWORD)(regarray[2] & 0xffff), + (ULONG)regarray[3] + ); +} +STATIC CONST struct EmuTrap stub_SetEntry = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_SetEntryPPC }; + +static ULONG stub_GetEntryPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct PreferencesIFace *Self = (struct PreferencesIFace *) ExtLib->MainIFace; + + return Self->GetEntry( + (APTR)regarray[8], + (ULONG)regarray[0], + (ULONG)regarray[1], + (APTR)regarray[9], + (UWORD)(regarray[2] & 0xffff), + (ULONG)regarray[3] + ); +} +STATIC CONST struct EmuTrap stub_GetEntry = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_GetEntryPPC }; + +static ULONG stub_RemEntryPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct PreferencesIFace *Self = (struct PreferencesIFace *) ExtLib->MainIFace; + + return Self->RemEntry( + (APTR)regarray[8], + (ULONG)regarray[0], + (ULONG)regarray[1], + (ULONG)regarray[2] + ); +} +STATIC CONST struct EmuTrap stub_RemEntry = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_RemEntryPPC }; + +CONST CONST_APTR VecTable68K[] = +{ + &stub_Open, + &stub_Close, + &stub_Expunge, + &stub_Reserved, + &stub_AllocPrefsHandle, + &stub_FreePrefsHandle, + &stub_SetPreferences, + &stub_GetPreferences, + &stub_ReadPrefsHandle, + &stub_WritePrefsHandle, + &stub_FindPreferences, + &stub_SetEntry, + &stub_GetEntry, + &stub_RemEntry, + (CONST_APTR)-1 +}; diff --git a/scalos/libraries/preferences/Preferences-aos4.c b/scalos/libraries/preferences/Preferences-aos4.c new file mode 100644 index 000000000..b4a20dfc0 --- /dev/null +++ b/scalos/libraries/preferences/Preferences-aos4.c @@ -0,0 +1,221 @@ +// Preferences-aos4.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include + +#include +#include + +#include + +#include "Preferences_base.h" +#include "Preferences.h" + +#include + +int _start(void) +{ + return -1; +} + +static struct Library *Initlib(struct Library *libbase, BPTR seglist, struct ExecIFace *pIExec); +static BPTR Expungelib(struct LibraryManagerInterface *Self); +static struct LibraryHeader *Openlib(struct LibraryManagerInterface *Self, ULONG version); +static BPTR Closelib(struct LibraryManagerInterface *Self); +static ULONG Obtainlib(struct LibraryManagerInterface *Self); +static ULONG Releaselib(struct LibraryManagerInterface *Self); + +extern const CONST_APTR VecTable68K[]; + +/* OS4.0 Library */ + +/* ------------------- OS4 Manager Interface ------------------------ */ +static const APTR managerfunctable[] = +{ + (APTR)Obtainlib, + (APTR)Releaselib, + (APTR)NULL, + (APTR)NULL, + (APTR)Openlib, + (APTR)Closelib, + (APTR)Expungelib, + (APTR)NULL, + (APTR)-1 +}; + +static const struct TagItem managertags[] = +{ + {MIT_Name, (ULONG)"__library"}, + {MIT_VectorTable, (ULONG)managerfunctable}, + {MIT_Version, 1}, + {TAG_DONE, 0} +}; + +/* ---------------------- OS4 Main Interface ------------------------ */ +static APTR functable[] = + { + Obtainlib, + Releaselib, + NULL, + NULL, + LIBAllocPrefsHandle, + LIBFreePrefsHandle, + LIBSetPreferences, + LIBGetPreferences, + LIBReadPrefsHandle, + LIBWritePrefsHandle, + LIBFindPreferences, + LIBSetEntry, + LIBGetEntry, + LIBRemEntry, + (APTR) -1 + }; + +static const struct TagItem maintags[] = + { + {MIT_Name, (ULONG)"main"}, + {MIT_VectorTable, (ULONG)functable}, + {MIT_Version, 1}, + {TAG_DONE, 0} + }; + +/* Init table used in library initialization. */ +static const ULONG interfaces[] = +{ + (ULONG)managertags, + (ULONG)maintags, + (ULONG)0 +}; + +static const struct TagItem inittab[] = + { + {CLT_DataSize, (ULONG)sizeof(struct PreferencesBase)}, + {CLT_Interfaces, (ULONG) interfaces}, + {CLT_Vector68K, (ULONG)VecTable68K}, + {CLT_InitFunc, (ULONG) Initlib}, + {TAG_DONE, 0} + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, + RTF_NATIVE | RTF_AUTOINIT, + LIB_VERSION, + NT_LIBRARY, + 0, + (STRPTR)libName, + (STRPTR)libIdString, + (struct TagItem *)inittab + }; + +/* ------------------- OS4 Manager Functions ------------------------ */ +static struct Library * Initlib(struct Library *libbase, BPTR seglist, struct ExecIFace *pIExec) +{ + struct PreferencesBase *PrefsLibBase = (struct PreferencesBase *) libbase; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)libbase + libbase->lib_PosSize); + struct LibraryManagerInterface *Self = (struct LibraryManagerInterface *) ExtLib->ILibrary; + + SysBase = (struct ExecBase *)pIExec->Data.LibBase; + IExec = pIExec; + PrefsLibBase->prb_LibNode.lib_Revision = LIB_REVISION; + PrefsLibBase->prb_SegList = (struct SegList *)seglist; + + d1(kprintf(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + if (!PreferencesInit(PrefsLibBase)) + { + Expungelib(Self); + PrefsLibBase = NULL; + } + + d1(kprintf(__FILE__ "/%s/%ld: PrefsLibBase=%08lx\n", __FUNC__, __LINE__, PrefsLibBase)); + + return PrefsLibBase ? &PrefsLibBase->prb_LibNode : NULL; +} + +static BPTR Expungelib(struct LibraryManagerInterface *Self) +{ + struct PreferencesBase *PrefsLibBase = (struct PreferencesBase *) Self->Data.LibBase; + + if (0 == PrefsLibBase->prb_LibNode.lib_OpenCnt) + { + struct SegList *libseglist = PrefsLibBase->prb_SegList; + + d1(kprintf(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + Remove((struct Node *) PrefsLibBase); + PreferencesCleanup(PrefsLibBase); + DeleteLibrary((struct Library *)PrefsLibBase); + + return (BPTR)libseglist; + } + + PrefsLibBase->prb_LibNode.lib_Flags |= LIBF_DELEXP; + + return (BPTR)NULL; +} + +static struct LibraryHeader *Openlib(struct LibraryManagerInterface *Self, ULONG version) +{ + struct PreferencesBase *PrefsLibBase = (struct PreferencesBase *) Self->Data.LibBase; + + PrefsLibBase->prb_LibNode.lib_OpenCnt++; + PrefsLibBase->prb_LibNode.lib_Flags &= ~LIBF_DELEXP; + + d1(kprintf(__FILE__ "/%s/%ld: OpenCnt=%ld\n", __FUNC__, __LINE__, PrefsLibBase->prb_LibNode.lib_OpenCnt)); + + if (!PrefsLibBase->prb_Initialized) + { + if (!PreferencesOpen(PrefsLibBase)) + { + d1(kprintf(__FILE__ "/%s/%ld: Initialization failed\n", __FUNC__, __LINE__)); + + Closelib(Self); + return NULL; + } + + PrefsLibBase->prb_Initialized = TRUE; + } + + d1(kprintf(__FILE__ "/%s/%ld: Initialization succeeded\n", __FUNC__, __LINE__)); + + return (struct LibraryHeader *)&PrefsLibBase->prb_LibNode; +} + +static BPTR Closelib(struct LibraryManagerInterface *Self) +{ + struct PreferencesBase *PrefsLibBase = (struct PreferencesBase *) Self->Data.LibBase; + + PrefsLibBase->prb_LibNode.lib_OpenCnt--; + + d1(kprintf(__FILE__ "/%s/%ld: OpenCnt=%ld\n", __FUNC__, __LINE__, PrefsLibBase->prb_LibNode.lib_OpenCnt)); +/* + if (0 == PrefsLibBase->prb_LibNode.lib_OpenCnt) + { + if (PrefsLibBase->prb_LibNode.lib_Flags & LIBF_DELEXP) + { + return Expungelib(Self); + } + } +*/ + return (BPTR)NULL; +} + +static ULONG Obtainlib(struct LibraryManagerInterface *Self) +{ + return(Self->Data.RefCount++); +} + +static ULONG Releaselib(struct LibraryManagerInterface *Self) +{ + return(Self->Data.RefCount--); +} diff --git a/scalos/libraries/preferences/Preferences-aros.c b/scalos/libraries/preferences/Preferences-aros.c new file mode 100644 index 000000000..c4e2ec7f9 --- /dev/null +++ b/scalos/libraries/preferences/Preferences-aros.c @@ -0,0 +1,225 @@ +// Preferences-classic.c +// $Date$ +// $Revision$ + + +#include +#include + +#include + +#include +#include + +#include + +#include "Preferences_base.h" +#include "Preferences.h" + +//---------------------------------------------------------------------------- +// Standard library functions + +static AROS_UFP3 (struct Library *, Initlib, + AROS_UFPA(struct Library *, libbase, D0), + AROS_UFPA(struct SegList *, seglist, A0), + AROS_UFPA(struct ExecBase *, sysbase, A6) +); +static AROS_LD1 (struct Library *, Openlib, + AROS_LPA (__unused ULONG, version, D0), + struct Library *, libbase, 1, Preferences +); +static AROS_LD0 (struct SegList *, Closelib, + struct Library *, base, 2, Preferences +); +static AROS_LD1 (struct SegList *, Expungelib, + AROS_LPA(__unused struct Library *, __extrabase, D0), + struct Library *, libbase, 3, Preferences +); +static AROS_LD0 (ULONG, Extfunclib, + __unused struct Library *, libbase, 4, Preferences +); + + +//---------------------------------------------------------------------------- + +SAVEDS(LONG) ASM Libstart(void) +{ + return -1; +} + +//---------------------------------------------------------------------------- + +/* OS3.x Library */ + +static APTR functable[] = + { + Preferences_1_Openlib, + Preferences_2_Closelib, + Preferences_3_Expungelib, + Preferences_4_Extfunclib, + PreferencesBase_0_LIBAllocPrefsHandle, + PreferencesBase_0_LIBFreePrefsHandle, + PreferencesBase_0_LIBSetPreferences, + PreferencesBase_0_LIBGetPreferences, + PreferencesBase_0_LIBReadPrefsHandle, + PreferencesBase_0_LIBWritePrefsHandle, + PreferencesBase_0_LIBFindPreferences, + PreferencesBase_0_LIBSetEntry, + PreferencesBase_0_LIBGetEntry, + PreferencesBase_0_LIBRemEntry, + (APTR) -1 + }; + +/* Init table used in library initialization. */ +static ULONG inittab[] = + { + sizeof(struct PreferencesBase), + (ULONG) functable, + 0, + (ULONG) Initlib + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, + RTF_AUTOINIT, + LIB_VERSION, + NT_LIBRARY, + 0, + libName, + libIdString, + inittab + }; + + +//---------------------------------------------------------------------------- + + static AROS_UFH3(struct Library *, Initlib, + AROS_UFHA(struct Library *, libbase, D0), + AROS_UFHA(struct SegList *, seglist, A0), + AROS_UFHA(struct ExecBase *, sysbase, A6) +) +{ + AROS_USERFUNC_INIT + + struct PreferencesBase *PrefsLibBase = (struct PreferencesBase *) libbase; + + /* store pointer to execbase for global access */ + SysBase = sysbase; + + PrefsLibBase->prb_LibNode.lib_Revision = LIB_REVISION; + PrefsLibBase->prb_SegList = seglist; + + PrefsLibBase->prb_Initialized = FALSE; + + if (!PreferencesInit(PrefsLibBase)) + { + Preferences_3_Expungelib(&PrefsLibBase->prb_LibNode, &PrefsLibBase->prb_LibNode); + PrefsLibBase = NULL; + } + + return PrefsLibBase ? &PrefsLibBase->prb_LibNode : NULL; + + AROS_USERFUNC_EXIT +} + + +static AROS_LH1(struct Library *, Openlib, + AROS_LHA(__unused ULONG, version, D0), + struct Library *, libbase, 1, Preferences +) +{ + AROS_LIBFUNC_INIT + + struct PreferencesBase *PrefsLibBase = (struct PreferencesBase *) libbase; + + PrefsLibBase->prb_LibNode.lib_OpenCnt++; + PrefsLibBase->prb_LibNode.lib_Flags &= ~LIBF_DELEXP; + + if (!PrefsLibBase->prb_Initialized) + { + if (!PreferencesOpen(PrefsLibBase)) + { + Preferences_2_Closelib(&PrefsLibBase->prb_LibNode); + return NULL; + } + + PrefsLibBase->prb_Initialized = TRUE; + } + + return &PrefsLibBase->prb_LibNode; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH0(struct SegList *, Closelib, + struct Library *, libbase, 2, Preferences +) +{ + AROS_LIBFUNC_INIT + + struct PreferencesBase *PrefsLibBase = (struct PreferencesBase *) libbase; + + PrefsLibBase->prb_LibNode.lib_OpenCnt--; + + if (0 == PrefsLibBase->prb_LibNode.lib_OpenCnt) + { + if (PrefsLibBase->prb_LibNode.lib_Flags & LIBF_DELEXP) + { + return Preferences_3_Expungelib(&PrefsLibBase->prb_LibNode, &PrefsLibBase->prb_LibNode); + } + } + + return NULL; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH1(struct SegList *, Expungelib, + AROS_LHA(__unused struct Library *, __extrabase, D0), + struct Library *, libbase, 3, Preferences +) +{ + AROS_LIBFUNC_INIT + + struct PreferencesBase *PrefsLibBase = (struct PreferencesBase *) libbase; + + if (0 == PrefsLibBase->prb_LibNode.lib_OpenCnt) + { + ULONG size = PrefsLibBase->prb_LibNode.lib_NegSize + PrefsLibBase->prb_LibNode.lib_PosSize; + UBYTE *ptr = (UBYTE *) PrefsLibBase - PrefsLibBase->prb_LibNode.lib_NegSize; + struct SegList *libseglist = PrefsLibBase->prb_SegList; + + Remove((struct Node *) PrefsLibBase); + PreferencesCleanup(PrefsLibBase); + FreeMem(ptr,size); + + return libseglist; + } + + PrefsLibBase->prb_LibNode.lib_Flags |= LIBF_DELEXP; + + return NULL; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH0(ULONG, Extfunclib, + __unused struct Library *, libbase, 4, Preferences +) +{ + AROS_LIBFUNC_INIT + + return 0; + + AROS_LIBFUNC_EXIT +} + +//---------------------------------------------------------------------------- diff --git a/scalos/libraries/preferences/Preferences-classic.c b/scalos/libraries/preferences/Preferences-classic.c new file mode 100644 index 000000000..bebbd6312 --- /dev/null +++ b/scalos/libraries/preferences/Preferences-classic.c @@ -0,0 +1,195 @@ +// Preferences-classic.c +// $Date$ +// $Revision$ + + +#include +#include + +#include + +#include +#include + + +#include "Preferences_base.h" +#include "Preferences.h" + +//---------------------------------------------------------------------------- +// Standard library functions + +static LIB_SAVEDS(struct Library *) LIB_ASM LIB_INTERRUPT Initlib(LIB_REG(d0, struct Library *libbase), + LIB_REG(a0, struct SegList *seglist), LIB_REG(a6, struct ExecBase *sysbase)); + +static LIBFUNC_PROTO(Openlib, libbase, struct Library *); +static LIBFUNC_PROTO(Closelib, libbase, struct SegList *); +static LIBFUNC_PROTO(Expungelib, libbase, struct SegList *); +static LIBFUNC_PROTO(Extfunclib, libbase, ULONG); + +//---------------------------------------------------------------------------- + +SAVEDS(LONG) ASM Libstart(void) +{ + return -1; +} + +//---------------------------------------------------------------------------- + +/* OS3.x Library */ + +static APTR functable[] = + { +#ifdef __MORPHOS__ + (APTR) FUNCARRAY_32BIT_NATIVE, +#endif + Openlib, + Closelib, + Expungelib, + Extfunclib, + LIBAllocPrefsHandle, + LIBFreePrefsHandle, + LIBSetPreferences, + LIBGetPreferences, + LIBReadPrefsHandle, + LIBWritePrefsHandle, + LIBFindPreferences, + LIBSetEntry, + LIBGetEntry, + LIBRemEntry, + (APTR) -1 + }; + +/* Init table used in library initialization. */ +static ULONG inittab[] = + { + sizeof(struct PreferencesBase), + (ULONG) functable, + 0, + (ULONG) Initlib + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, +#ifdef __MORPHOS__ + RTF_PPC | RTF_AUTOINIT, +#else + RTF_AUTOINIT, +#endif + LIB_VERSION, + NT_LIBRARY, + 0, + libName, + libIdString, + inittab + }; + +#ifdef __MORPHOS__ +ULONG __abox__=1; +#endif + +//---------------------------------------------------------------------------- + +static LIB_SAVEDS(struct Library *) LIB_ASM LIB_INTERRUPT Initlib(LIB_REG(d0, struct Library *libbase), + LIB_REG(a0, struct SegList *seglist), LIB_REG(a6, struct ExecBase *sysbase)) +{ + struct PreferencesBase *PrefsLibBase = (struct PreferencesBase *) libbase; + + /* store pointer to execbase for global access */ + SysBase = sysbase; + + PrefsLibBase->prb_LibNode.lib_Revision = LIB_REVISION; + PrefsLibBase->prb_SegList = seglist; + + PrefsLibBase->prb_Initialized = FALSE; + + if (!PreferencesInit(PrefsLibBase)) + { + CALLLIBFUNC(Expungelib, &PrefsLibBase->prb_LibNode); + PrefsLibBase = NULL; + } + + return PrefsLibBase ? &PrefsLibBase->prb_LibNode : NULL; +} + + +static LIBFUNC(Openlib, libbase, struct Library *) +{ + struct PreferencesBase *PrefsLibBase = (struct PreferencesBase *) libbase; + + PrefsLibBase->prb_LibNode.lib_OpenCnt++; + PrefsLibBase->prb_LibNode.lib_Flags &= ~LIBF_DELEXP; + + if (!PrefsLibBase->prb_Initialized) + { + if (!PreferencesOpen(PrefsLibBase)) + { + CALLLIBFUNC(Closelib, &PrefsLibBase->prb_LibNode); + return NULL; + } + + PrefsLibBase->prb_Initialized = TRUE; + } + + return &PrefsLibBase->prb_LibNode; +} +LIBFUNC_END + + +static LIBFUNC(Closelib, libbase, struct SegList *) +{ + struct PreferencesBase *PrefsLibBase = (struct PreferencesBase *) libbase; + + PrefsLibBase->prb_LibNode.lib_OpenCnt--; + + if (0 == PrefsLibBase->prb_LibNode.lib_OpenCnt) + { + if (PrefsLibBase->prb_LibNode.lib_Flags & LIBF_DELEXP) + { + return CALLLIBFUNC(Expungelib, &PrefsLibBase->prb_LibNode); + } + } + + return NULL; +} +LIBFUNC_END + + +static LIBFUNC(Expungelib, libbase, struct SegList *) +{ + struct PreferencesBase *PrefsLibBase = (struct PreferencesBase *) libbase; + + if (0 == PrefsLibBase->prb_LibNode.lib_OpenCnt) + { + ULONG size = PrefsLibBase->prb_LibNode.lib_NegSize + PrefsLibBase->prb_LibNode.lib_PosSize; + UBYTE *ptr = (UBYTE *) PrefsLibBase - PrefsLibBase->prb_LibNode.lib_NegSize; + struct SegList *libseglist = PrefsLibBase->prb_SegList; + + Remove((struct Node *) PrefsLibBase); + PreferencesCleanup(PrefsLibBase); + FreeMem(ptr,size); + + return libseglist; + } + + PrefsLibBase->prb_LibNode.lib_Flags |= LIBF_DELEXP; + + return NULL; +} +LIBFUNC_END + + +static LIBFUNC(Extfunclib, libbase, ULONG) +{ + (void) libbase; + + return 0; +} +LIBFUNC_END + +//---------------------------------------------------------------------------- + diff --git a/scalos/libraries/preferences/Preferences.c b/scalos/libraries/preferences/Preferences.c new file mode 100644 index 000000000..f794c2dbd --- /dev/null +++ b/scalos/libraries/preferences/Preferences.c @@ -0,0 +1,1535 @@ +// Preferences.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "Preferences_base.h" +#include "Preferences.h" +#include +#include + +//---------------------------------------------------------------------------- + +#define IS_NOT_EVEN(len) ((len) & 1) +#define EVEN(len) (((len) + 1) & ~1) +#define MAGIC_PREFS_LIST_ENTRY_LIST ((UWORD) -1) + +#define min(a,b) ((a) < (b) ? (a) : (b)) + +#ifdef __amigaos4__ +#define ExtLib(base) ((struct ExtendedLibrary *)((ULONG)base + ((struct Library *)base)->lib_PosSize)) +#define IPreferences ((struct PreferencesIFace *)ExtLib(PreferencesBase)->MainIFace) +#endif + +//---------------------------------------------------------------------------- + +struct PrefsListEntry + { + struct Node ple_Node; + + struct List ple_IdList; + struct SignalSemaphore ple_Semaphore; + + char ple_Name[32]; + UWORD ple_AllocCount; + }; + +struct PrefsId + { + struct Node pid_Node; + ULONG pid_Id; + struct List pid_PrefsTagList; + }; + +struct PrefsTag + { + struct Node ptg_Node; + ULONG ptg_Tag; + + UWORD ptg_DataSize; + UBYTE ptg_Data[0]; + }; + +struct PrefsEntry + { + struct Node pre_Node; + UWORD pre_DataSize; + UBYTE pre_Data[0]; + }; + +#if defined(__GNUC__) +#pragma pack(2) +#endif /* __GNUC__ */ + +// preferences chunk, as stored on disk + +struct PrefsChunk + { + ULONG pck_Tag; + UWORD pck_DataSize; + UBYTE pck_Data[0]; + }; + +struct PrefsListChunk + { + UWORD plc_DataSize; + UBYTE plc_Data[0]; + }; + +#if defined(__GNUC__) +#pragma pack() +#endif /* __GNUC__ */ + +//---------------------------------------------------------------------------- + +// Standard library functions + +static struct PrefsListEntry *CreateNewPrefsListEntry(struct PreferencesBase *PreferencesBase, + CONST_STRPTR name); +static void FreePrefsId(struct PreferencesBase *PreferencesBase, struct PrefsId *pid); +static void FreePrefsTag(struct PreferencesBase *PreferencesBase, struct PrefsTag *ptg); +static void FreePrefsEntry(struct PreferencesBase *PreferencesBase, struct PrefsEntry *pre); +static struct PrefsId *CreateNewPrefsId(struct PreferencesBase *PreferencesBase, + struct PrefsListEntry *ple, ULONG id); +static struct PrefsEntry *CreateNewPrefsTagListEntry(struct PreferencesBase *PreferencesBase, + const void *Data, size_t DataLen); +static struct PrefsTag *CreateNewPrefsTag(struct PreferencesBase *PreferencesBase, + struct PrefsId *pid, ULONG tag, const void *Data, UWORD StructSize); +static APTR MyAllocVecPooled(struct PreferencesBase *PreferencesBase, size_t Size); +static void MyFreeVecPooled(struct PreferencesBase *PreferencesBase, APTR mem); +static struct Node *GetNthListEntry(struct List *PrefsList, ULONG nEntry); +static LONG SameName(CONST_STRPTR Name1, CONST_STRPTR Name2, size_t MaxLen); + +//---------------------------------------------------------------------------- + +struct ExecBase *SysBase; +struct IntuitionBase *IntuitionBase; +T_UTILITYBASE UtilityBase; +struct DosLibrary * DOSBase; +struct Library *IFFParseBase; +#ifdef __amigaos4__ +struct Library *NewlibBase; +struct Interface *INewlib; +struct ExecIFace *IExec; +struct IntuitionIFace *IIntuition; +struct UtilityIFace *IUtility; +struct DOSIFace *IDOS; +struct IFFParseIFace *IIFFParse; +#endif + +//---------------------------------------------------------------------------- + +char ALIGNED libName[] = "preferences.library"; +char ALIGNED libIdString[] = "$VER: preferences.library " + STR(LIB_VERSION) "." STR(LIB_REVISION) + " (16 Dec 2005 21:16:25) " + COMPILER_STRING + " ©2005" CURRENTYEAR " The Scalos Team"; + +//---------------------------------------------------------------------------- + + +BOOL PreferencesInit(struct PreferencesBase *PreferencesBase) +{ + d1(KPrintF("%s/%s/%ld: START PreferencesBase=%08lx procName=<%s>\n", __FILE__, __FUNC__, __LINE__, \ + PreferencesBase, FindTask(NULL)->tc_Node.ln_Name)); + + NewList(&PreferencesBase->prb_PrefsList); + + InitSemaphore(&PreferencesBase->prb_MemPoolSemaphore); + InitSemaphore(&PreferencesBase->prb_PrefsListSem); + + d1(kprintf("%s/%s/%ld: END Success\n", __FILE__, __FUNC__, __LINE__)); + + return TRUE; // Success +} + +//----------------------------------------------------------------------------- + +BOOL PreferencesOpen(struct PreferencesBase *PreferencesBase) +{ + BOOL Success = FALSE; + + d1(kprintf("%s/%s/%ld: START PreferencesBase=%08lx procName=<%s>\n", __FILE__, __FUNC__, __LINE__, \ + PreferencesBase, FindTask(NULL)->tc_Node.ln_Name)); + + do { + IntuitionBase = (APTR) OpenLibrary( "intuition.library", 39 ); +#ifdef __amigaos4__ + if (IntuitionBase) + { + IIntuition = (APTR) GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (!IIntuition) + { + CloseLibrary((struct Library *)IntuitionBase); + IntuitionBase = NULL; + } + } +#endif + if (NULL == IntuitionBase) + break; + + UtilityBase = (APTR) OpenLibrary( "utility.library", 39 ); +#ifdef __amigaos4__ + if (UtilityBase) + { + IUtility = (APTR) GetInterface((struct Library *)UtilityBase, "main", 1, NULL); + if (!IUtility) + { + CloseLibrary((struct Library *)UtilityBase); + UtilityBase = NULL; + } + } +#endif + if (NULL == UtilityBase) + break; + + IFFParseBase = (APTR) OpenLibrary( "iffparse.library", 39 ); +#ifdef __amigaos4__ + if (IFFParseBase) + { + IIFFParse = (APTR) GetInterface((struct Library *)IFFParseBase, "main", 1, NULL); + if (!IIFFParse) + { + CloseLibrary((struct Library *)IFFParseBase); + IFFParseBase = NULL; + } + } +#endif + if (NULL == IFFParseBase) + break; + + DOSBase = (APTR) OpenLibrary( "dos.library", 39 ); +#ifdef __amigaos4__ + if (DOSBase) + { + IDOS = (APTR) GetInterface((struct Library *)DOSBase, "main", 1, NULL); + if (!IDOS) + { + CloseLibrary((struct Library *)DOSBase); + DOSBase = NULL; + } + } +#endif + if (NULL == DOSBase) + break; + +#ifdef __amigaos4__ + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + break; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + break; +#endif + + PreferencesBase->prb_MemPool = CreatePool(MEMF_PUBLIC | MEMF_CLEAR, 8192, 256); + if (NULL == PreferencesBase->prb_MemPool) + break; + + Success = TRUE; + } while (0); + + d1(kprintf("%s/%s/%ld: END Success=%ld\n", __FILE__, __FUNC__, __LINE__, Success)); + + return Success; +} + +//----------------------------------------------------------------------------- + +void PreferencesCleanup(struct PreferencesBase *PreferencesBase) +{ + d1(KPrintF("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__)); + + if (PreferencesBase->prb_MemPool) + { + DeletePool(PreferencesBase->prb_MemPool); + PreferencesBase->prb_MemPool = NULL; + } +#ifdef __amigaos4__ + if (INewlib) + { + DropInterface(INewlib); + INewlib = NULL; + } + if (NewlibBase) + { + CloseLibrary(NewlibBase); + NewlibBase = NULL; + } + if (IIFFParse) + { + DropInterface((struct Interface *)IIFFParse); + IIFFParse = NULL; + } +#endif + if (IFFParseBase) + { + CloseLibrary(IFFParseBase); + IFFParseBase = NULL; + } +#ifdef __amigaos4__ + if (IUtility) + { + DropInterface((struct Interface *)IUtility); + IUtility = NULL; + } +#endif + if (UtilityBase) + { + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } +#ifdef __amigaos4__ + if (IIntuition) + { + DropInterface((struct Interface *)IIntuition); + IIntuition = NULL; + } +#endif + if (IntuitionBase) + { + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } +#ifdef __amigaos4__ + if (IDOS) + { + DropInterface((struct Interface *)IDOS); + IDOS = NULL; + } +#endif + if (DOSBase) + { + CloseLibrary((struct Library *) DOSBase); + DOSBase = NULL; + } +} + +//----------------------------------------------------------------------------- + +// prefshandle = AllocPrefsHandle( name ) +// D0 A0 +// +// APTR AllocPrefsHandle( CONST_STRPTR ); + +LIBFUNC_P2(APTR, LIBAllocPrefsHandle, + A0, CONST_STRPTR, Name, + A6, struct PreferencesBase *, PreferencesBase) +{ + struct PrefsListEntry *pleFound = NULL; + + d1(kprintf("%s/%s/%ld: START PreferencesBase=%08lx name=<%s>\n", __FILE__, __FUNC__, __LINE__, \ + PreferencesBase, Name)); + + ObtainSemaphore(&PreferencesBase->prb_PrefsListSem); + + if (Name) + { + struct PrefsListEntry *ple; + + for (ple = (struct PrefsListEntry *) PreferencesBase->prb_PrefsList.lh_Head; + ple != (struct PrefsListEntry *) &PreferencesBase->prb_PrefsList.lh_Tail; + ple = (struct PrefsListEntry *) ple->ple_Node.ln_Succ) + { + if (0 == SameName(Name, ple->ple_Name, sizeof(ple->ple_Name))) + { + pleFound = ple; + break; + } + } + } + if (NULL == pleFound) + { + pleFound = CreateNewPrefsListEntry(PreferencesBase, Name); + } + + if (pleFound) + pleFound->ple_AllocCount++; + + ReleaseSemaphore(&PreferencesBase->prb_PrefsListSem); + + d1(KPrintF("%s/%s/%ld: END PrefsHandle=%08lx\n", __FILE__, __FUNC__, __LINE__, pleFound)); + + return pleFound; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +// FreePrefsHandle(PrefsHandle); +// A0 +// +// void FreePrefsHandle(APTR); + +LIBFUNC_P2(void, LIBFreePrefsHandle, + A0, APTR, PrefsHandle, + A6, struct PreferencesBase *, PreferencesBase) +{ + struct PrefsListEntry *ple = (struct PrefsListEntry *) PrefsHandle; + + d1(KPrintF("%s/%s/%ld: START PreferencesBase=%08lx PrefsHandle\n", __FILE__, __FUNC__, __LINE__, \ + PreferencesBase, PrefsHandle)); + + ObtainSemaphore(&PreferencesBase->prb_PrefsListSem); + + if (ple && 0 == --ple->ple_AllocCount) + { + struct PrefsId *pid; + + ObtainSemaphore(&ple->ple_Semaphore); + + while ((pid = (struct PrefsId *) RemHead(&ple->ple_IdList))) + { + FreePrefsId(PreferencesBase, pid); + } + ReleaseSemaphore(&ple->ple_Semaphore); + } + + ReleaseSemaphore(&PreferencesBase->prb_PrefsListSem); + + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +// SetPreferences(PrefsHandle, ID, Tag, Struct, Struct_Size); +// A0, D0, D1, A1, D2 +// +// void SetPreferences(APTR, ULONG, ULONG, const APTR, UWORD); + +LIBFUNC_P6(void, LIBSetPreferences, + A0, APTR, PrefsHandle, + D0, ULONG, id, + D1, ULONG, tag, + A1, const APTR, Struct, + D2, UWORD, StructSize, + A6, struct PreferencesBase *, PreferencesBase) +{ + struct PrefsListEntry *ple = (struct PrefsListEntry *) PrefsHandle; + + d1(KPrintF("%s/%s/%ld: START PreferencesBase=%08lx PrefsHandle=%08lx ID=%08lx Tag=%08lx Struct=%08lx Size=%lu\n", __FILE__, __FUNC__, __LINE__, \ + PreferencesBase, PrefsHandle, id, tag, Struct, StructSize)); + + ObtainSemaphore(&ple->ple_Semaphore); + + do { + struct PrefsId *pid; + struct PrefsId *pidFound = NULL; + struct PrefsTag *ptg; + struct PrefsTag *ptgFound = NULL; + + if (0 == id) + break; + if (0 == tag) + break; + + for (pid = (struct PrefsId *) ple->ple_IdList.lh_Head; + pid != (struct PrefsId *) &ple->ple_IdList.lh_Tail; + pid = (struct PrefsId *) pid->pid_Node.ln_Succ) + { + if (pid->pid_Id == id) + { + pidFound = pid; + break; + } + } + if (NULL == pidFound) + pidFound = CreateNewPrefsId(PreferencesBase, ple, id); + + if (NULL == pidFound) + break; + + for (ptg = (struct PrefsTag *) pidFound->pid_PrefsTagList.lh_Head; + ptg != (struct PrefsTag *) &pidFound->pid_PrefsTagList.lh_Tail; + ptg = (struct PrefsTag *) ptg->ptg_Node.ln_Succ) + { + if (ptg->ptg_Tag == tag) + { + if (ptg->ptg_DataSize == StructSize) + { + ptgFound = ptg; + } + else + { + // correct tag, but wrong size + // we remove the old PrefsTag and allocate a new one + Remove(&ptg->ptg_Node); + FreePrefsTag(PreferencesBase, ptg); + } + break; + } + } + + if (ptgFound) + memcpy(ptg->ptg_Data, Struct, StructSize); + else + { + ptgFound = CreateNewPrefsTag(PreferencesBase, pidFound, tag, Struct, StructSize); + + if (NULL == ptgFound) + break; + } + + } while (0); + + ReleaseSemaphore(&ple->ple_Semaphore); + + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +// bytescopied = GetPreferences(PrefsHandle, ID, Tag, Struct, Struct_Size); +// D0 A0 D0 D1 A1 D2 +// +// ULONG GetPreferences(APTR, ULONG, ULONG, const APTR, UWORD); + +LIBFUNC_P6(ULONG, LIBGetPreferences, + A0, APTR, PrefsHandle, + D0, ULONG, id, + D1, ULONG, tag, + A1, APTR, Struct, + D2, UWORD, StructSize, + A6, struct PreferencesBase *, PreferencesBase) +{ + struct PrefsListEntry *ple = (struct PrefsListEntry *) PrefsHandle; + ULONG BytesCopied = 0; + + (void) PreferencesBase; + + d1(KPrintF("%s/%s/%ld: START PreferencesBase=%08lx PrefsHandle=%08lx ID=%08lx Tag=%08lx Struct=%08lx Size=%lu\n", __FILE__, __FUNC__, __LINE__, \ + PreferencesBase, PrefsHandle, id, tag, Struct, StructSize)); + + ObtainSemaphoreShared(&ple->ple_Semaphore); + + do { + struct PrefsId *pid; + struct PrefsId *pidFound = NULL; + struct PrefsTag *ptg; + struct PrefsTag *ptgFound = NULL; + + if (0 == id) + break; + if (0 == tag) + break; + + for (pid = (struct PrefsId *) ple->ple_IdList.lh_Head; + pid != (struct PrefsId *) &ple->ple_IdList.lh_Tail; + pid = (struct PrefsId *) pid->pid_Node.ln_Succ) + { + if (pid->pid_Id == id) + { + pidFound = pid; + break; + } + } + if (NULL == pidFound) + break; + + for (ptg = (struct PrefsTag *) pidFound->pid_PrefsTagList.lh_Head; + ptg != (struct PrefsTag *) &pidFound->pid_PrefsTagList.lh_Tail; + ptg = (struct PrefsTag *) ptg->ptg_Node.ln_Succ) + { + if (ptg->ptg_Tag == tag) + { + ptgFound = ptg; + break; + } + } + + if (NULL == ptgFound) + break; + + BytesCopied = min(StructSize, ptg->ptg_DataSize); + memcpy(Struct, ptg->ptg_Data, BytesCopied); + } while (0); + + ReleaseSemaphore(&ple->ple_Semaphore); + + d1(kprintf("%s/%s/%ld: END BytesCopied=%lu\n", __FILE__, __FUNC__, __LINE__, BytesCopied)); + + return BytesCopied; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +// ReadPrefsHandle(PrefsHandle, Filename); +// A0 A1 +// +// void ReadPrefsHandle(APTR, CONST_STRPTR); +LIBFUNC_P3(void, LIBReadPrefsHandle, + A0, APTR, PrefsHandle, + A1, CONST_STRPTR, Filename, + A6, struct PreferencesBase *, PreferencesBase) +{ + struct PrefsListEntry *ple = (struct PrefsListEntry *) PrefsHandle; + struct IFFHandle *iff; + BOOL IffOpen = FALSE; + UBYTE *PrefsChunk = NULL; + LONG Result; + + d1(kprintf("%s/%s/%ld: START PreferencesBase=%08lx PrefsHandle=%08lx Filename=<%s>\n", __FILE__, __FUNC__, __LINE__, \ + PreferencesBase, PrefsHandle, Filename)); + + ObtainSemaphore(&ple->ple_Semaphore); + + do { + iff = AllocIFF(); + if (NULL == iff) + break; + + InitIFFasDOS(iff); + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + iff->iff_Stream = (IPTR) Open(Filename, MODE_OLDFILE); + if (0 == iff->iff_Stream) + break; + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + Result = OpenIFF(iff, IFFF_READ); + if (RETURN_OK != Result) + break; + + d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + + IffOpen = TRUE; + } while (0); + + if (IffOpen) + { + d1(kprintf("%s/%s/%ld: IFF Opened\n", __FILE__, __FUNC__, __LINE__)); + + do { + struct ContextNode *cn; + const struct PrefsChunk *pck; + ULONG Entry; + + Result = ParseIFF(iff, IFFPARSE_STEP); + if (IFFERR_EOC == Result) + continue; + if (RETURN_OK != Result) + break; + + cn = CurrentChunk(iff); + if (NULL == cn) + continue; + if (ID_PREF != cn->cn_Type) + continue; + if (ID_FORM == cn->cn_ID) + continue; + if (ID_PRHD == cn->cn_ID) + continue; + + PrefsChunk = MyAllocVecPooled(PreferencesBase, cn->cn_Size); + if (NULL == PrefsChunk) + continue; + + d1(kprintf("%s/%s/%ld: PrefsChunk=%08lx\n", __FILE__, __FUNC__, __LINE__, + PrefsChunk)); + + if (cn->cn_Size != ReadChunkBytes(iff, PrefsChunk, cn->cn_Size)) + break; + + pck = (struct PrefsChunk *) PrefsChunk; + while (pck->pck_Tag) + { + d1(KPrintF("%s/%s/%ld: pck=%08lx Tag=%08lx DataSize=%lu\n", \ + __FILE__, __FUNC__, __LINE__, pck, pck->pck_Tag, pck->pck_DataSize)); + + if (MAGIC_PREFS_LIST_ENTRY_LIST == pck->pck_DataSize) + { + const struct PrefsListChunk *plc; + + d1(KPrintF("%s/%s/%ld: MAGIC_PREFS_LIST_ENTRY_LIST\n", + __FILE__, __FUNC__, __LINE__)); + + plc = (const struct PrefsListChunk *) pck->pck_Data; + Entry = 0; + + while (plc->plc_DataSize) + { + size_t len; + + d1(KPrintF("%s/%s/%ld: plc=%08lx DataSize=%lu\n", + __FILE__, __FUNC__, __LINE__, plc, plc->plc_DataSize)); + + SetEntry(ple, cn->cn_ID, pck->pck_Tag, (APTR) plc->plc_Data, plc->plc_DataSize, Entry); + + len = EVEN(sizeof(struct PrefsListChunk) + plc->plc_DataSize); + plc = (const struct PrefsListChunk *) (((UBYTE *) plc) + len); + Entry++; + } + + pck = (const struct PrefsChunk *) (((UBYTE *) plc) + sizeof(UWORD)); + } + else + { + // .stdnode + size_t len; + + SetPreferences(ple, cn->cn_ID, pck->pck_Tag, (APTR) pck->pck_Data, pck->pck_DataSize); + + len = EVEN(sizeof(struct PrefsChunk) + pck->pck_DataSize); + d1(KPrintF("%s/%s/%ld: len=%lu\n", __FILE__, __FUNC__, __LINE__, len)); + + pck = (const struct PrefsChunk *) (((UBYTE *) pck) + len); + } + } + } while (1); + } + + ReleaseSemaphore(&ple->ple_Semaphore); + + if (PrefsChunk) + MyFreeVecPooled(PreferencesBase, PrefsChunk); + if (iff) + { + if (IffOpen) + CloseIFF(iff); + if (iff->iff_Stream) + { + Close((BPTR) iff->iff_Stream); + iff->iff_Stream = 0; + } + FreeIFF(iff); + } + + d1(kprintf("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +// WritePrefsHandle(PrefsHandle, Filename); +// A0 A1 +// +// void WritePrefsHandle(APTR, CONST_STRPTR); + +LIBFUNC_P3(void, LIBWritePrefsHandle, + A0, APTR, PrefsHandle, + A1, CONST_STRPTR, Filename, + A6, struct PreferencesBase *, PreferencesBase) +{ + struct PrefsListEntry *ple = (struct PrefsListEntry *) PrefsHandle; + struct IFFHandle *iff; + BOOL IffOpen = FALSE; + LONG Result; + + (void) PreferencesBase; + + d1(KPrintF("%s/%s/%ld: START PreferencesBase=%08lx PrefsHandle=%08lx Filename=<%s>\n", __FILE__, __FUNC__, __LINE__, \ + PreferencesBase, PrefsHandle, Filename)); + + ObtainSemaphore(&ple->ple_Semaphore); + + do { + static const struct PrefHeader prefHeader = { 1, 0, 0L }; + struct PrefsId *pid; + + iff = AllocIFF(); + if (NULL == iff) + break; + + InitIFFasDOS(iff); + + iff->iff_Stream = (IPTR) Open(Filename, MODE_NEWFILE); + if (0 == iff->iff_Stream) + break; + + Result = OpenIFF(iff, IFFF_WRITE); + if (RETURN_OK != Result) + break; + + IffOpen = TRUE; + + Result = PushChunk(iff, ID_PREF, ID_FORM, IFFSIZE_UNKNOWN); + if (RETURN_OK != Result) + break; + + Result = PushChunk(iff, 0, ID_PRHD, IFFSIZE_UNKNOWN); + if (RETURN_OK != Result) + break; + + if (WriteChunkBytes(iff, (APTR) &prefHeader, sizeof(prefHeader)) < 0) + break; + + Result = PopChunk(iff); + if (RETURN_OK != Result) + break; + + for (pid = (struct PrefsId *) ple->ple_IdList.lh_Head; + pid != (struct PrefsId *) &ple->ple_IdList.lh_Tail; + pid = (struct PrefsId *) pid->pid_Node.ln_Succ) + { + ULONG NullDummy = 0; + ULONG EndMark = 0; + struct PrefsTag *ptg; + + d1(KPrintF("%s/%s/%ld: pid=%08lx pid_Id=%08lx\n", __FILE__, __FUNC__, __LINE__, pid, pid->pid_Id)); + + Result = PushChunk(iff, 0, pid->pid_Id, IFFSIZE_UNKNOWN); + if (RETURN_OK != Result) + break; + + for (ptg = (struct PrefsTag *) pid->pid_PrefsTagList.lh_Head; + ptg != (struct PrefsTag *) &pid->pid_PrefsTagList.lh_Tail; + ptg = (struct PrefsTag *) ptg->ptg_Node.ln_Succ) + { + UWORD PtgSize = (UWORD) ptg->ptg_DataSize; + + d1(KPrintF("%s/%s/%ld: ptg=%08lx ptg_DataSize=%lu\n", __FILE__, __FUNC__, __LINE__, ptg, ptg->ptg_DataSize)); + + if (MAGIC_PREFS_LIST_ENTRY_LIST == ptg->ptg_DataSize) + { + struct List *PrefsList = (struct List *) ptg->ptg_Data;; + + d1(KPrintF("%s/%s/%ld: PrefsList=%08lx\n", __FILE__, __FUNC__, __LINE__, PrefsList)); + + if (!IsListEmpty(PrefsList)) + { + struct PrefsEntry *pre; + UWORD DataSize = 0; + + WriteChunkBytes(iff, &ptg->ptg_Tag, sizeof(ptg->ptg_Tag)); + WriteChunkBytes(iff, &PtgSize, sizeof(PtgSize)); + + for (pre = (struct PrefsEntry *) PrefsList->lh_Head; + pre != (struct PrefsEntry *) &PrefsList->lh_Tail; + pre = (struct PrefsEntry *) pre->pre_Node.ln_Succ) + { + d1(KPrintF("%s/%s/%ld: pre=%08lx pre_DataSize=%lu\n", __FILE__, __FUNC__, __LINE__, pre, pre->pre_DataSize)); + + WriteChunkBytes(iff, &pre->pre_DataSize, sizeof(pre->pre_DataSize)); + WriteChunkBytes(iff, &pre->pre_Data, pre->pre_DataSize); + if (IS_NOT_EVEN(pre->pre_DataSize)) + WriteChunkBytes(iff, &NullDummy, 1); + } + + WriteChunkBytes(iff, &DataSize, sizeof(DataSize)); + } + } + else + { + // .stdnode + WriteChunkBytes(iff, &ptg->ptg_Tag, sizeof(ptg->ptg_Tag)); + WriteChunkBytes(iff, &PtgSize, sizeof(PtgSize)); + WriteChunkBytes(iff, ptg->ptg_Data, ptg->ptg_DataSize); + if (IS_NOT_EVEN(ptg->ptg_DataSize)) + WriteChunkBytes(iff, &NullDummy, 1); + } + } + + WriteChunkBytes(iff, &EndMark, sizeof(EndMark)); + + Result = PopChunk(iff); + if (RETURN_OK != Result) + break; + + d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__)); + } + + if (RETURN_OK != Result) + break; + + Result = PopChunk(iff); + if (RETURN_OK != Result) + break; + } while (0); + + d1(KPrintF("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result)); + + ReleaseSemaphore(&ple->ple_Semaphore); + + if (iff) + { + if (IffOpen) + CloseIFF(iff); + if (iff->iff_Stream) + { + Close((BPTR) iff->iff_Stream); + iff->iff_Stream = 0; + } + FreeIFF(iff); + } + + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +// prefsstruct = FindPreferences(prefshandle, ID, Tag); +// D0 A0 D0 D1 +// +// struct PrefsStruct *FindPreferences(APTR, ULONG, ULONG); + +LIBFUNC_P4(struct PrefsStruct *, LIBFindPreferences, + A0, APTR, PrefsHandle, + D0, ULONG, ID, + D1, ULONG, tag, + A6, struct PreferencesBase *, PreferencesBase) +{ + struct PrefsListEntry *ple = (struct PrefsListEntry *) PrefsHandle; + struct PrefsStruct *ps = NULL; + + (void) PreferencesBase; + + d1(KPrintF("%s/%s/%ld: START PreferencesBase=%08lx PrefsHandle=%08lx ID=%08lx Tag=%08lx\n", __FILE__, __FUNC__, __LINE__, \ + PreferencesBase, PrefsHandle, ID, tag)); + + ObtainSemaphoreShared(&ple->ple_Semaphore); + + do { + struct PrefsId *pid; + struct PrefsId *pidFound = NULL; + struct PrefsTag *ptg; + struct PrefsTag *ptgFound = NULL; + + for (pid = (struct PrefsId *) ple->ple_IdList.lh_Head; + pid != (struct PrefsId *) &ple->ple_IdList.lh_Tail; + pid = (struct PrefsId *) pid->pid_Node.ln_Succ) + { + if (pid->pid_Id == ID) + { + pidFound = pid; + break; + } + } + + if (NULL == pidFound) + break; + + for (ptg = (struct PrefsTag *) pidFound->pid_PrefsTagList.lh_Head; + ptg != (struct PrefsTag *) &pidFound->pid_PrefsTagList.lh_Tail; + ptg = (struct PrefsTag *) ptg->ptg_Node.ln_Succ) + { + if (ptg->ptg_Tag == tag) + { + ptgFound = ptg; + break; + } + } + + if (NULL == ptgFound) + break; + + ps = (struct PrefsStruct *) &ptgFound->ptg_DataSize; + } while (0); + + ReleaseSemaphore(&ple->ple_Semaphore); + + d1(KPrintF("%s/%s/%ld: END ps=%08lx\n", __FILE__, __FUNC__, __LINE__, ps)); + + return ps; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +// SetEntry(PrefsHandle, ID, Tag, Struct, Struct_Size, Entry) +// A0 D0 D1 A1 D2 D3 +// +// void SetEntry(APTR, ULONG, ULONG, const APTR, UWORD, ULONG); + +LIBFUNC_P7(void, LIBSetEntry, + A0, APTR, PrefsHandle, + D0, ULONG, ID, + D1, ULONG, tag, + A1, const APTR, Struct, + D2, UWORD, StructSize, + D3, ULONG, Entry, + A6, struct PreferencesBase *, PreferencesBase) +{ + struct PrefsListEntry *ple = (struct PrefsListEntry *) PrefsHandle; + + d1(KPrintF("%s/%s/%ld: START PreferencesBase=%08lx PrefsHandle=%08lx ID=%08lx Tag=%08lx Struct=%08lx Size=%lu, Entry=%lu\n", + __FILE__, __FUNC__, __LINE__, PreferencesBase, PrefsHandle, ID, tag, Struct, StructSize, Entry)); + + ObtainSemaphore(&ple->ple_Semaphore); + + do { + struct PrefsId *pid; + struct PrefsId *pidFound = NULL; + struct PrefsTag *ptg; + struct PrefsTag *ptgFound = NULL; + struct PrefsEntry *pre; + struct PrefsEntry *preFound; + struct List *PrefsList; + + d1(KPrintF("%s/%s/%ld: ID=%08lx tag=%08lx\n", __FILE__, __FUNC__, __LINE__, ID, tag)); + + if (0 == ID) + break; + if (0 == tag) + break; + + for (pid = (struct PrefsId *) ple->ple_IdList.lh_Head; + pid != (struct PrefsId *) &ple->ple_IdList.lh_Tail; + pid = (struct PrefsId *) pid->pid_Node.ln_Succ) + { + if (pid->pid_Id == ID) + { + pidFound = pid; + break; + } + } + + d1(KPrintF("%s/%s/%ld: pidFound=%08lx\n", __FILE__, __FUNC__, __LINE__, pidFound)); + + if (NULL == pidFound) + pidFound = CreateNewPrefsId(PreferencesBase, ple, ID); + + d1(KPrintF("%s/%s/%ld: pidFound=%08lx\n", __FILE__, __FUNC__, __LINE__, pidFound)); + if (NULL == pidFound) + break; + + for (ptg = (struct PrefsTag *) pidFound->pid_PrefsTagList.lh_Head; + ptg != (struct PrefsTag *) &pidFound->pid_PrefsTagList.lh_Tail; + ptg = (struct PrefsTag *) ptg->ptg_Node.ln_Succ) + { + if (ptg->ptg_Tag == tag) + { + ptgFound = ptg; + break; + } + } + + d1(KPrintF("%s/%s/%ld: ptgFound=%08lx\n", __FILE__, __FUNC__, __LINE__, ptgFound)); + + if (NULL == ptgFound) + ptgFound = CreateNewPrefsTag(PreferencesBase, pidFound, tag, NULL, MAGIC_PREFS_LIST_ENTRY_LIST); + + d1(KPrintF("%s/%s/%ld: ptgFound=%08lx\n", __FILE__, __FUNC__, __LINE__, ptgFound)); + if (NULL == ptgFound) + break; + + if (MAGIC_PREFS_LIST_ENTRY_LIST != ptgFound->ptg_DataSize) + break; + + PrefsList = (struct List *) ptgFound->ptg_Data; + + preFound = (struct PrefsEntry *) GetNthListEntry(PrefsList, Entry); + + d1(KPrintF("%s/%s/%ld: PrefsList=%08lx\n", __FILE__, __FUNC__, __LINE__, PrefsList)); + d1(KPrintF("%s/%s/%ld: preFound=%08lx\n", __FILE__, __FUNC__, __LINE__, preFound)); + if (preFound) + { + Remove(&preFound->pre_Node); + FreePrefsEntry(PreferencesBase, preFound); + } + preFound = CreateNewPrefsTagListEntry(PreferencesBase, Struct, StructSize); + + d1(KPrintF("%s/%s/%ld: preFound=%08lx\n", __FILE__, __FUNC__, __LINE__, preFound)); + if (preFound) + { + if (0 == Entry) + { + d1(KPrintF("%s/%s/%ld: Add to head\n", __FILE__, __FUNC__, __LINE__)); + AddHead(PrefsList, &preFound->pre_Node); + } + else + { + pre = (struct PrefsEntry *) GetNthListEntry(PrefsList, Entry); + d1(KPrintF("%s/%s/%ld: pre=%08lx\n", __FILE__, __FUNC__, __LINE__, pre)); + if (pre) + Insert(PrefsList, &preFound->pre_Node, &pre->pre_Node); + else + AddTail(PrefsList, &preFound->pre_Node); + } + } + } while (0); + + ReleaseSemaphore(&ple->ple_Semaphore); + + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +// bytescopied = GetEntry(PrefsHandle, ID, Tag, Struct, Struct_Size, Entry) +// D0 A0 D0 D1 A1 D2 D3 +// +// ULONG GetEntry(APTR, ULONG, ULONG, APTR, UWORD, ULONG); + +LIBFUNC_P7(ULONG, LIBGetEntry, + A0, APTR, PrefsHandle, + D0, ULONG, ID, + D1, ULONG, tag, + A1, APTR, Struct, + D2, UWORD, StructSize, + D3, ULONG, Entry, + A6, struct PreferencesBase *, PreferencesBase) +{ + struct PrefsListEntry *ple = (struct PrefsListEntry *) PrefsHandle; + ULONG BytesCopied = 0; + + (void) PreferencesBase; + + d1(KPrintF("%s/%s/%ld: START PreferencesBase=%08lx PrefsHandle=%08lx ID=%08lx Tag=%08lx Struct=%08lx Size=%lu, Entry=%lu\n", __FILE__, __FUNC__, __LINE__, \ + PreferencesBase, PrefsHandle, ID, tag, Struct, StructSize, Entry)); + + ObtainSemaphoreShared(&ple->ple_Semaphore); + + do { + struct PrefsId *pid; + struct PrefsId *pidFound = NULL; + struct PrefsTag *ptg; + struct PrefsTag *ptgFound = NULL; + struct PrefsEntry *preFound; + struct List *PrefsList; + + for (pid = (struct PrefsId *) ple->ple_IdList.lh_Head; + pid != (struct PrefsId *) &ple->ple_IdList.lh_Tail; + pid = (struct PrefsId *) pid->pid_Node.ln_Succ) + { + if (pid->pid_Id == ID) + { + pidFound = pid; + break; + } + } + + d1(KPrintF("%s/%s/%ld: pidFound=%08lx\n", __FILE__, __FUNC__, __LINE__, pidFound)); + if (NULL == pidFound) + break; + + for (ptg = (struct PrefsTag *) pidFound->pid_PrefsTagList.lh_Head; + ptg != (struct PrefsTag *) &pidFound->pid_PrefsTagList.lh_Tail; + ptg = (struct PrefsTag *) ptg->ptg_Node.ln_Succ) + { + if (ptg->ptg_Tag == tag) + { + ptgFound = ptg; + break; + } + } + + d1(KPrintF("%s/%s/%ld: ptgFound=%08lx\n", __FILE__, __FUNC__, __LINE__, ptgFound)); + if (NULL == ptgFound) + break; + + d1(KPrintF("%s/%s/%ld: DataSize=%lu\n", __FILE__, __FUNC__, __LINE__, ptgFound->ptg_DataSize)); + if (MAGIC_PREFS_LIST_ENTRY_LIST != ptgFound->ptg_DataSize) + break; + + PrefsList = (struct List *) ptgFound->ptg_Data;; + + preFound = (struct PrefsEntry *) GetNthListEntry(PrefsList, Entry); + d1(KPrintF("%s/%s/%ld: preFound=%08lx\n", __FILE__, __FUNC__, __LINE__, preFound)); + if (preFound) + { + d1(KPrintF("%s/%s/%ld: pre_Data=%08lx pre_DataSize=%lu\n", __FILE__, __FUNC__, __LINE__, preFound->pre_Data, preFound->pre_DataSize)); + BytesCopied = min(preFound->pre_DataSize, StructSize); + memcpy(Struct, preFound->pre_Data, BytesCopied); + } + } while (0); + + ReleaseSemaphore(&ple->ple_Semaphore); + + d1(KPrintF("%s/%s/%ld: END BytesCopied=%lu\n", __FILE__, __FUNC__, __LINE__, BytesCopied)); + + return BytesCopied; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +// success = RemEntry(PrefsHandle, ID, Tag, Entry); +// D0 A0 D0 D1 D2 +// +// ULONG RemEntry(APTR, ULONG, ULONG, ULONG); + +LIBFUNC_P5(ULONG, LIBRemEntry, + A0, APTR, PrefsHandle, + D0, ULONG, ID, + D1, ULONG, tag, + D2, ULONG, Entry, + A6, struct PreferencesBase *, PreferencesBase) +{ + struct PrefsListEntry *ple = (struct PrefsListEntry *) PrefsHandle; + ULONG Success = 0; + + d1(KPrintF("%s/%s/%ld: START PreferencesBase=%08lx PrefsHandle=%08lx ID=%08lx Tag=%08lx Entry=%lu\n", __FILE__, __FUNC__, __LINE__, \ + PreferencesBase, PrefsHandle, ID, tag, Entry)); + + ObtainSemaphore(&ple->ple_Semaphore); + + do { + struct PrefsId *pid; + struct PrefsId *pidFound = NULL; + struct PrefsTag *ptg; + struct PrefsTag *ptgFound = NULL; + struct PrefsEntry *preFound; + struct List *PrefsList; + + for (pid = (struct PrefsId *) ple->ple_IdList.lh_Head; + pid != (struct PrefsId *) &ple->ple_IdList.lh_Tail; + pid = (struct PrefsId *) pid->pid_Node.ln_Succ) + { + if (pid->pid_Id == ID) + { + pidFound = pid; + break; + } + } + + if (NULL == pidFound) + break; + + for (ptg = (struct PrefsTag *) pidFound->pid_PrefsTagList.lh_Head; + ptg != (struct PrefsTag *) &pidFound->pid_PrefsTagList.lh_Tail; + ptg = (struct PrefsTag *) ptg->ptg_Node.ln_Succ) + { + if (ptg->ptg_Tag == tag) + { + ptgFound = ptg; + break; + } + } + + if (NULL == ptgFound) + break; + + if (MAGIC_PREFS_LIST_ENTRY_LIST != ptgFound->ptg_DataSize) + break; + + PrefsList = (struct List *) ptgFound->ptg_Data;; + + preFound = (struct PrefsEntry *) GetNthListEntry(PrefsList, Entry); + if (preFound) + { + Success = 1; + Remove(&preFound->pre_Node); + FreePrefsEntry(PreferencesBase, preFound); + } + } while (0); + + ReleaseSemaphore(&ple->ple_Semaphore); + + d1(KPrintF("%s/%s/%ld: END Success=%ld\n", __FILE__, __FUNC__, __LINE__, Success)); + + return Success; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +#if !defined(__SASC) +void exit(int x) +{ + (void) x; + while (1) + ; +} + +#if !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) + +static size_t stccpy(char *dest, const char *src, size_t MaxLen) +{ + size_t Count = 0; + + while (*src && MaxLen > 1) + { + *dest++ = *src++; + MaxLen--; + Count++; + } + *dest = '\0'; + Count++; + + return Count; +} + +#endif /*__MORPHOS__*/ + +#endif /* !defined(__SASC) */ + +//----------------------------------------------------------------------------- + +static struct PrefsListEntry *CreateNewPrefsListEntry(struct PreferencesBase *PreferencesBase, + CONST_STRPTR name) +{ + struct PrefsListEntry *ple; + + d1(KPrintF("%s/%s/%ld: START name=<%s>\n", __FILE__, __FUNC__, __LINE__, name)); + + ple = MyAllocVecPooled(PreferencesBase, sizeof(struct PrefsListEntry)); + if (ple) + { + memset(ple, 0, sizeof(struct PrefsListEntry)); + + InitSemaphore(&ple->ple_Semaphore); + NewList(&ple->ple_IdList); + + if (name) + stccpy(ple->ple_Name, name, sizeof(ple->ple_Name)); + + AddTail(&PreferencesBase->prb_PrefsList, &ple->ple_Node); + } + + d1(KPrintF("%s/%s/%ld: END ple=%08lx\n", __FILE__, __FUNC__, __LINE__, ple)); + + return ple; +} + +//----------------------------------------------------------------------------- + +static void FreePrefsId(struct PreferencesBase *PreferencesBase, struct PrefsId *pid) +{ + d1(KPrintF("%s/%s/%ld: START pid=%08lx\n", __FILE__, __FUNC__, __LINE__, pid)); + + if (pid) + { + struct PrefsTag *ptg; + + while ((ptg = (struct PrefsTag *) RemHead(&pid->pid_PrefsTagList))) + { + FreePrefsTag(PreferencesBase, ptg); + } + + MyFreeVecPooled(PreferencesBase, pid); + } + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); +} + +//----------------------------------------------------------------------------- + +static void FreePrefsTag(struct PreferencesBase *PreferencesBase, struct PrefsTag *ptg) +{ + d1(KPrintF("%s/%s/%ld: START ptg=%08lx\n", __FILE__, __FUNC__, __LINE__, ptg)); + + if (ptg) + { + if (MAGIC_PREFS_LIST_ENTRY_LIST == ptg->ptg_DataSize) + { + struct PrefsEntry *pre; + struct List *PrefsList = (struct List *) ptg->ptg_Data; + + while ((pre = (struct PrefsEntry *) RemTail(PrefsList))) + FreePrefsEntry(PreferencesBase, pre); + } + + MyFreeVecPooled(PreferencesBase, ptg); + } + d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); +} + +//----------------------------------------------------------------------------- + +static void FreePrefsEntry(struct PreferencesBase *PreferencesBase, struct PrefsEntry *pre) +{ + d1(KPrintF("%s/%s/%ld: START pre=%08lx\n", __FILE__, __FUNC__, __LINE__, pre)); + + if (pre) + { + MyFreeVecPooled(PreferencesBase, pre); + } + d1(kprintf("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__)); +} + +//----------------------------------------------------------------------------- + +static struct PrefsId *CreateNewPrefsId(struct PreferencesBase *PreferencesBase, + struct PrefsListEntry *ple, ULONG id) +{ + struct PrefsId *pid; + + d1(KPrintF("%s/%s/%ld: START ple=%08lx id=%08lx\n", __FILE__, __FUNC__, __LINE__, ple, id)); + + pid = MyAllocVecPooled(PreferencesBase, sizeof(struct PrefsId)); + if (pid) + { + NewList(&pid->pid_PrefsTagList); + pid->pid_Id = id; + + ObtainSemaphore(&ple->ple_Semaphore); + AddTail(&ple->ple_IdList, &pid->pid_Node); + ReleaseSemaphore(&ple->ple_Semaphore); + } + + d1(KPrintF("%s/%s/%ld: END pid=%08lx\n", __FILE__, __FUNC__, __LINE__, pid)); + + return pid; +} + +//----------------------------------------------------------------------------- + +static struct PrefsEntry *CreateNewPrefsTagListEntry(struct PreferencesBase *PreferencesBase, + const void *Data, size_t DataLen) +{ + struct PrefsEntry *pre; + + d1(kprintf("%s/%s/%ld: END Data=%08lx Len=%lu\n", __FILE__, __FUNC__, __LINE__, Data, DataLen)); + + pre = MyAllocVecPooled(PreferencesBase, sizeof(struct PrefsEntry) + DataLen); + if (pre) + { + pre->pre_DataSize = DataLen; + memcpy(pre->pre_Data, Data, DataLen); + } + + d1(kprintf("%s/%s/%ld: END pre=%08lx\n", __FILE__, __FUNC__, __LINE__, pre)); + + return pre; +} + +//----------------------------------------------------------------------------- + +static struct PrefsTag *CreateNewPrefsTag(struct PreferencesBase *PreferencesBase, + struct PrefsId *pid, ULONG tag, const void *Data, UWORD StructSize) +{ + struct PrefsTag *ptg; + size_t DataSize; + + d1(kprintf("%s/%s/%ld: END pid=%08lx tag=%08lx Data=%08lx Size=%lu\n", \ + __FILE__, __FUNC__, __LINE__, pid, tag, Data, StructSize)); + + if (MAGIC_PREFS_LIST_ENTRY_LIST == StructSize) + DataSize = sizeof(struct List); + else + DataSize = StructSize; + + ptg = MyAllocVecPooled(PreferencesBase, sizeof(struct PrefsTag) + DataSize); + if (ptg) + { + ptg->ptg_DataSize = StructSize; + ptg->ptg_Tag = tag; + + if (MAGIC_PREFS_LIST_ENTRY_LIST == StructSize) + { + NewList((struct List *) ptg->ptg_Data); + } + else + { + memcpy(ptg->ptg_Data, Data, StructSize); + } + + AddTail(&pid->pid_PrefsTagList, &ptg->ptg_Node); + } + + d1(KPrintF("%s/%s/%ld: END ptg=%08lx\n", __FILE__, __FUNC__, __LINE__, ptg)); + + return ptg; +} + +//----------------------------------------------------------------------------- + +static APTR MyAllocVecPooled(struct PreferencesBase *PreferencesBase, size_t Size) +{ + APTR ptr; + + if (PreferencesBase->prb_MemPool) + { + ObtainSemaphore(&PreferencesBase->prb_MemPoolSemaphore); + ptr = AllocPooled(PreferencesBase->prb_MemPool, Size + sizeof(size_t)); + ReleaseSemaphore(&PreferencesBase->prb_MemPoolSemaphore); + if (ptr) + { + size_t *sptr = (size_t *) ptr; + + sptr[0] = Size; + + d1(kprintf("%s/%s/%ld: MemPool=%08lx Size=%lu mem=%08lx\n", + __FILE__, __FUNC__, __LINE__, PreferencesBase->prb_MemPool, Size, &sptr[1])); + return (APTR)(&sptr[1]); + } + } + + d1(kprintf("%s/%s/%ld: MemPool=%08lx Size=%lu\n", __FILE__, __FUNC__, __LINE__, PreferencesBase->prb_MemPool, Size)); + + return NULL; +} + +//----------------------------------------------------------------------------- + +static void MyFreeVecPooled(struct PreferencesBase *PreferencesBase, APTR mem) +{ + d1(KPrintF("%s/%s/%ld: MemPool=%08lx mem=%08lx\n", __FILE__, __FUNC__, __LINE__, PreferencesBase->prb_MemPool, mem)); + if (PreferencesBase->prb_MemPool && mem) + { + size_t size; + size_t *sptr = (size_t *) mem; + + mem = &sptr[-1]; + size = sptr[-1]; + + d1(kprintf("%s/%s/%ld: MemPool=%08lx size=%lu mem=%08lx\n", + __FILE__, __FUNC__, __LINE__, PreferencesBase->prb_MemPool, size, &sptr[1])); + + ObtainSemaphore(&PreferencesBase->prb_MemPoolSemaphore); + FreePooled(PreferencesBase->prb_MemPool, mem, size + sizeof(size_t)); + ReleaseSemaphore(&PreferencesBase->prb_MemPoolSemaphore); + } +} + +//----------------------------------------------------------------------------- + +static struct Node *GetNthListEntry(struct List *PrefsList, ULONG nEntry) +{ + ULONG Count = 0; + struct Node *node; + + for (node = PrefsList->lh_Head; + node != (struct Node *) &PrefsList->lh_Tail; + node = node->ln_Succ, Count++) + { + if (Count == nEntry) + { + return node; + } + } + + // not found + return NULL; +} + +//----------------------------------------------------------------------------- + +static LONG SameName(CONST_STRPTR Name1, CONST_STRPTR Name2, size_t MaxLen) +{ + (void) MaxLen; + + return Stricmp(Name1, Name2); +} + +//----------------------------------------------------------------------------- + diff --git a/scalos/libraries/preferences/Preferences.h b/scalos/libraries/preferences/Preferences.h new file mode 100644 index 000000000..5ebc8a9d5 --- /dev/null +++ b/scalos/libraries/preferences/Preferences.h @@ -0,0 +1,87 @@ +// Preferences.h +// $Date$ +// $Revision$ + + +#ifndef PREFERENCES_H +#define PREFERENCES_H + +#include +#include +#include + +#include + +#define LIB_VERSION 41 +#define LIB_REVISION 2 + +extern char ALIGNED libName[]; +extern char ALIGNED libIdString[]; + +extern struct ExecBase *SysBase; + +//---------------------------------------------------------------------------- + +BOOL PreferencesInit(struct PreferencesBase *PreferencesBase); +BOOL PreferencesOpen(struct PreferencesBase *PreferencesBase); +void PreferencesCleanup(struct PreferencesBase *PreferencesBase); + +LIBFUNC_P2_PROTO(APTR, LIBAllocPrefsHandle, + A0, CONST_STRPTR, Name, + A6, struct PreferencesBase *, PreferencesBase); +LIBFUNC_P2_PROTO(void, LIBFreePrefsHandle, + A0, APTR, PrefsHandle, + A6, struct PreferencesBase *, PreferencesBase); +LIBFUNC_P6_PROTO(void, LIBSetPreferences, + A0, APTR, PrefsHandle, + D0, ULONG, id, + D1, ULONG, tag, + A1, const APTR, Struct, + D2, UWORD, StructSize, + A6, struct PreferencesBase *, PreferencesBase); +LIBFUNC_P6_PROTO(ULONG, LIBGetPreferences, + A0, APTR, PrefsHandle, + D0, ULONG, id, + D1, ULONG, tag, + A1, APTR, Struct, + D2, UWORD, StructSize, + A6, struct PreferencesBase *, PreferencesBase); +LIBFUNC_P3_PROTO(void, LIBReadPrefsHandle, + A0, APTR, PrefsHandle, + A1, CONST_STRPTR, Filename, + A6, struct PreferencesBase *, PreferencesBase); +LIBFUNC_P3_PROTO(void, LIBWritePrefsHandle, + A0, APTR, PrefsHandle, + A1, CONST_STRPTR, Filename, + A6, struct PreferencesBase *, PreferencesBase); +LIBFUNC_P4_PROTO(struct PrefsStruct *, LIBFindPreferences, + A0, APTR, PrefsHandle, + D0, ULONG, ID, + D1, ULONG, tag, + A6, struct PreferencesBase *, PreferencesBase); +LIBFUNC_P7_PROTO(void, LIBSetEntry, + A0, APTR, PrefsHandle, + D0, ULONG, ID, + D1, ULONG, tag, + A1, const APTR, Struct, + D2, UWORD, StructSize, + D3, ULONG, Entry, + A6, struct PreferencesBase *, PreferencesBase); +LIBFUNC_P7_PROTO(ULONG, LIBGetEntry, + A0, APTR, PrefsHandle, + D0, ULONG, ID, + D1, ULONG, tag, + A1, const APTR, Struct, + D2, UWORD, StructSize, + D3, ULONG, Entry, + A6, struct PreferencesBase *, PreferencesBase); +LIBFUNC_P5_PROTO(ULONG, LIBRemEntry, + A0, APTR, PrefsHandle, + D0, ULONG, ID, + D1, ULONG, tag, + D2, ULONG, Entry, + A6, struct PreferencesBase *, PreferencesBase); + +//---------------------------------------------------------------------------- + +#endif /* PREFERENCES_H */ diff --git a/scalos/libraries/preferences/Preferences_base.h b/scalos/libraries/preferences/Preferences_base.h new file mode 100644 index 000000000..442efe45c --- /dev/null +++ b/scalos/libraries/preferences/Preferences_base.h @@ -0,0 +1,48 @@ +// Preferences_base.h +// $Date$ +// $Revision$ + + +#ifndef PREFERENCESBASE_H +#define PREFERENCESBASE_H + +#include +#include +#include + + +struct PreferencesBase +{ + struct Library prb_LibNode; + + struct SegList *prb_SegList; + + BOOL prb_Initialized; + + struct SignalSemaphore prb_MemPoolSemaphore; + APTR prb_MemPool; + + struct SignalSemaphore prb_PrefsListSem; + struct List prb_PrefsList; +}; + +//---------------------------------------------------------------------------- + +// Debugging... +#define d(x) ; +#define d1(x) ; +#define d2(x) x; + + +// aus debug.lib +#ifdef __AROS__ +#include +#define KPrintF kprintf +#else +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); +#endif + +//---------------------------------------------------------------------------- + +#endif /* PREFERENCESBASE_H */ diff --git a/scalos/libraries/preferences/config.mk b/scalos/libraries/preferences/config.mk new file mode 100755 index 000000000..87af79e27 --- /dev/null +++ b/scalos/libraries/preferences/config.mk @@ -0,0 +1,53 @@ +# $Date: 2012-08-10 13:47:28 +0200 (Fr, 10. Aug 2012) $ +# $Revision: 915 $ + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += -nostartfiles \ + -lmempools \ +# --verbose + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += -nostartfiles \ +# --verbose + +else + +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +LFLAGS += -nostartfiles -larossupport + +else + +############################################################################### +# AmigaOS + +LFLAGS += -liconobject -lstack -lnix -lnixmain -lamiga -lstubs + +endif +endif +endif diff --git a/scalos/libraries/preferences/makefile b/scalos/libraries/preferences/makefile new file mode 100644 index 000000000..7b454c40a --- /dev/null +++ b/scalos/libraries/preferences/makefile @@ -0,0 +1,94 @@ +# makefile für Scalos Preferences library (C-Version) +# $Date$ +# $Revision$ +# $Id$ +############################################################# + +CSRCS = Preferences-classic.c Preferences.c +ASRCS = + +SPLAT = sc:c/splat +LINK = slink +CC = sc +LIBS = LIB:sc.lib LIB:debug.lib LIB:amiga.lib +PRECOMP = Include:all.gst +OBJDIR = .sasobj + +############################################################# + +.SUFFIXES: .s .asm .plugin .plugin.debug + +############################################################# + +CFLAGS = optimize nostackcheck nover dbg=s DATA=far idir=//include +LNFLAGS = quiet batch noicons stripdebug SD +LNDBFLAGS = quiet batch noicons addsym SD + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +############################################################# + +OBJS = $(ASRCS:%.asm=$(OBJDIR)/%.o) $(CSRCS:%.c=$(OBJDIR)/%.o) + +############################################################# + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $* objectname $@ + +$(OBJDIR)/%.o : %.s + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +$(OBJDIR)/%.o : %.asm + @printf '\033[32mAssemble: \033[31m\033[1m$<\033[0m\n' + @$(AS) $(AFLAGS) $< to $@ + +############################################################ + +NAME = .bin_os3/preferences.library +DBGNAME = $(NAME).debug + +############################################################# + +all: $(NAME) $(DBGNAME) +# install +# clean + +############################################################# + +$(OBJDIR)/Preferences.o : Preferences_base.h + +############################################################# + +$(NAME) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LINK) to $@ FROM $(OBJS) lib $(LIBS) $(LNFLAGS) + +$(DBGNAME) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LINK) to $@ FROM $(OBJS) lib $(LIBS) $(LNDBFLAGS) + +############################################################# + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(NAME)\033[0m to \033[1mLIBS: \033[0m\n' + @copy $(NAME) LIBS: clone + @avail flush + +############################################################# + +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + @delete $(NAME) $(DBGNAME) $(OBJS) + @printf '\033[0m' + +############################################################# + +nodebug: + -@$(SPLAT) -s -o "d2(" "d1(" "#?.c" + +############################################################# diff --git a/scalos/libraries/preferences/makefile-new b/scalos/libraries/preferences/makefile-new new file mode 100755 index 000000000..866c3a2f3 --- /dev/null +++ b/scalos/libraries/preferences/makefile-new @@ -0,0 +1,76 @@ +# $Date: 2011-06-23 22:21:49 +0200 (Do, 23. Jun 2011) $ +# $Revision: 738 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(OBJDIR)/Preferences.o \ + +ifeq ($(MACHINE),ppc-amigaos) +OBJS := $(OBJDIR)/Preferences-aos4.o \ + $(OBJDIR)/Preferences-aos4-68kstubs.o \ + $(OBJS) +else +ifeq ($(MACHINE),i386-aros) +OBJS := $(OBJDIR)/Preferences-aros.o $(OBJS) +else +OBJS := $(OBJDIR)/Preferences-classic.o $(OBJS) +endif +endif + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Targets +# + +NAME = preferences.library +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + $(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) LIBS: clone + @avail flush + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* + +############################################################################## diff --git a/scalos/libraries/scalosgfx/BitMapScale.c b/scalos/libraries/scalosgfx/BitMapScale.c new file mode 100644 index 000000000..64b16b748 --- /dev/null +++ b/scalos/libraries/scalosgfx/BitMapScale.c @@ -0,0 +1,799 @@ +// BitMapScale.c +// $Date$ +// $Revision$ + +// Algorithms and code parts taken from here: +// http://www.compuphase.com/graphic/scale.htm + +#include +#include +#include +#include +#include +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include + +#include "scalosgfx.h" + +//----------------------------------------------------------------------- + +#define MULT_SCALE 4096 + +#define PIXEL_NORTH (y ? - src->argb_Width : 0) +#define PIXEL_SOUTH ((y < src->argb_Height - 1) ? src->argb_Width : 0) +#define PIXEL_WEST (x ? -1 : 0) +#define PIXEL_EAST ((x < src->argb_Width - 1) ? 1 : 0) + +struct ARGBLong + { + LONG Red; + LONG Green; + LONG Blue; + LONG Alpha; + }; + +#define min(a, b) ((a) < (b) ? (a) : (b)) + +//----------------------------------------------------------------------- + +static struct ARGB ScaleARGBBicubic(const struct ARGB *src, + ULONG x, ULONG y, + ULONG SourceWidth, ULONG SourceHeight, + ULONG FractPartX, ULONG FractPartY); +static struct ARGB ScaleNearestNeighbour(const struct ARGB *s, + ULONG x, ULONG y, + ULONG SourceWidth, ULONG SourceHeight, + ULONG FractPartX, ULONG FractPartY); +static struct ARGB INLINE ScaleARGBBilinear(const struct ARGB *s, + ULONG x, ULONG y, + ULONG SourceWidth, ULONG SourceHeight, + ULONG FractPartX, ULONG FractPartY); +static struct ARGB INLINE ScaleARGBAverage2x2(const struct ARGB *src, + ULONG x, ULONG y, + ULONG SourceWidth, ULONG SourceHeight, + ULONG FractPartX, ULONG FractPartY); +static struct ARGB INLINE ScaleARGBAverage3x3(const struct ARGB *src, + ULONG x, ULONG y, + ULONG SourceWidth, ULONG SourceHeight, + ULONG FractPartX, ULONG FractPartY); +static struct ARGB INLINE ScaleARGBAverage4x4(const struct ARGB *src, + ULONG x, ULONG y, + ULONG SourceWidth, ULONG SourceHeight, + ULONG FractPartX, ULONG FractPartY); +#if 0 +static void ScaleARGB2X(const struct ARGBHeader *src, struct ARGBHeader *Dest); +#endif + +//----------------------------------------------------------------------- + +static struct ARGB ScaleNearestNeighbour(const struct ARGB *src, + ULONG x, ULONG y, + ULONG SourceWidth, ULONG SourceHeight, + ULONG FractPartX, ULONG FractPartY) +{ + (void) x; + (void) y; + (void) SourceWidth; + (void) SourceHeight; + (void) FractPartX; + (void) FractPartY; + + return src[0]; +} + + +static struct ARGB ScaleARGBBicubic(const struct ARGB *src, + ULONG x, ULONG y, + ULONG SourceWidth, ULONG SourceHeight, + ULONG FractPartX, ULONG FractPartY) +{ + const LONG BcScale = MULT_SCALE >> 2; + const LONG BcScale2 = BcScale * BcScale; + const LONG BcScale4 = BcScale2 * 4; + LONG BcFracX = FractPartX >> 2; + LONG BcFracY = FractPartY >> 2; + LONG BcFracX2 = BcFracX * BcFracX; + LONG BcFracY2 = BcFracY * BcFracY; + struct ARGBLong d[4]; + struct ARGBLong px; + struct ARGB result; + ULONG advx1, advy1, advx2, advy2; + LONG s[4], t[4]; + + // handle image borders + advx1 = (x + 1 >= SourceWidth) ? 0 : 1; + advx2 = (x + 2 >= SourceWidth) ? 0 : 2; + advy1 = (y + 1 >= SourceHeight) ? 0 : 1 * SourceWidth; + advy2 = (y + 2 >= SourceHeight) ? 0 : 2 * SourceWidth; + + d1(KPrintF("%s/%ld: SourceWidth=%lu SourceHeight=%lu\n", __FUNC__, __LINE__, SourceWidth, SourceHeight)); + d1(KPrintF("%s/%ld: s=%08lx advx1=%lu advy1=%lu\n", __FUNC__, __LINE__, s, advx1, advy1)); + + s[0] = (( 2 * BcScale - 1 * BcFracX) * BcFracX / BcScale - 1 * BcScale) * BcFracX / BcScale; // - 1 + s[1] = ( -5 * BcScale + 3 * BcFracX ) * BcFracX2 / BcScale2 + 2 * BcScale; // 0 + s[2] = (( 4 * BcScale - 3 * BcFracX) * BcFracX / BcScale + 1 * BcScale) * BcFracX / BcScale; // +1 + s[3] = ( -1 * BcScale + 1 * BcFracX) * BcFracX2 / BcScale2; // +2 + + t[0] = (( 2 * BcScale - 1 * BcFracY) * BcFracY / BcScale - 1 * BcScale) * BcFracY / BcScale; // - 1 + t[1] = ( -5 * BcScale + 3 * BcFracY) * BcFracY2 / BcScale2 + 2 * BcScale; // 0 + t[2] = (( 4 * BcScale - 3 * BcFracY) * BcFracY / BcScale + 1 * BcScale) * BcFracY / BcScale; // +1 + t[3] = ( -1 * BcScale + 1 * BcFracY) * BcFracY2 / BcScale2; // +2 + +#define GETPIXEL(x, y) \ + px.Red = src[(x)+(y)].Red; \ + px.Green = src[(x)+(y)].Green; \ + px.Blue = src[(x)+(y)].Blue; \ + px.Alpha = src[(x)+(y)].Alpha; + +#define SCALEADDPIXEL(dst, src, scale ) \ + dst.Red += scale * src.Red; \ + dst.Green += scale * src.Green; \ + dst.Blue += scale * src.Blue; \ + dst.Alpha += scale * src.Alpha; + +#define SCALEPIXEL(dst, src, scale ) \ + dst.Red = scale * src.Red; \ + dst.Green = scale * src.Green; \ + dst.Blue = scale * src.Blue; \ + dst.Alpha = scale * src.Alpha; + + GETPIXEL(advx1, advy1); SCALEPIXEL(d[0], px, s[0]); + GETPIXEL(0, advy1); SCALEADDPIXEL(d[0], px, s[1]); + GETPIXEL(advx1, advy1); SCALEADDPIXEL(d[0], px, s[2]); + GETPIXEL(advx2, advy1); SCALEADDPIXEL(d[0], px, s[3]); + + GETPIXEL(advx1, 0); SCALEPIXEL(d[1], px, s[0]); + GETPIXEL(0, 0); SCALEADDPIXEL(d[1], px, s[1]); + GETPIXEL(advx1, 0); SCALEADDPIXEL(d[1], px, s[2]); + GETPIXEL(advx2, 0); SCALEADDPIXEL(d[1], px, s[3]); + + GETPIXEL(advx1, advy1); SCALEPIXEL(d[2], px, s[0]); + GETPIXEL(0, advy1); SCALEADDPIXEL(d[2], px, s[1]); + GETPIXEL(advx1, advy1); SCALEADDPIXEL(d[2], px, s[2]); + GETPIXEL(advx2, advy1); SCALEADDPIXEL(d[2], px, s[3]); + + GETPIXEL(advx1, advy2); SCALEPIXEL(d[3], px, s[0]); + GETPIXEL(0, advy2); SCALEADDPIXEL(d[3], px, s[1]); + GETPIXEL(advx1, advy2); SCALEADDPIXEL(d[3], px, s[2]); + GETPIXEL(advx2, advy2); SCALEADDPIXEL(d[3], px, s[3]); + + d[0].Red = ( d[0].Red * t[0] + d[1].Red * t[1] + d[2].Red * t[2] + d[3].Red * t[3] ) / BcScale4; + d[0].Green = ( d[0].Green * t[0] + d[1].Green * t[1] + d[2].Green * t[2] + d[3].Green * t[3] ) / BcScale4; + d[0].Blue = ( d[0].Blue * t[0] + d[1].Blue * t[1] + d[2].Blue * t[2] + d[3].Blue * t[3] ) / BcScale4; + d[0].Alpha = ( d[0].Alpha * t[0] + d[1].Alpha * t[1] + d[2].Alpha * t[2] + d[3].Alpha * t[3] ) / BcScale4; + + if (d[0].Red < 0) + result.Red = 0; + else if (d[0].Red > 255 ) + result.Red = 255; + else + result.Red = d[0].Red; + + if (d[0].Green < 0) + result.Green = 0; + else if (d[0].Green > 255 ) + result.Green = 255; + else + result.Green = d[0].Green; + + if (d[0].Blue < 0) + result.Blue = 0; + else if (d[0].Blue > 255 ) + result.Blue = 255; + else + result.Blue = d[0].Blue; + + if (d[0].Alpha < 0) + result.Alpha = 0; + else if (d[0].Alpha > 255 ) + result.Alpha = 255; + else + result.Alpha = d[0].Alpha; + + return result; +} + + +static struct ARGB ScaleARGBBilinear(const struct ARGB *src, + ULONG x, ULONG y, + ULONG SourceWidth, ULONG SourceHeight, + ULONG FractPartX, ULONG FractPartY) +{ + ULONG v[2][2]; + ULONG vm[2][2]; + struct ARGB temp[2][2]; + struct ARGB d; + ULONG advx, advy; + + // handle image borders + advx = (x + 1 >= SourceWidth) ? 0 : 1; + advy = (y + 1 >= SourceHeight) ? 0 : SourceWidth; + + d1(KPrintF("%s/%ld: SourceWidth=%lu SourceHeight=%lu\n", __FUNC__, __LINE__, SourceWidth, SourceHeight)); + d1(KPrintF("%s/%ld: advx=%lu advy=%lu\n", __FUNC__, __LINE__, advx, advy)); + + // copy pixel data to temp + temp[0][0] = src[0]; + temp[0][1] = src[advx]; + temp[1][0] = src[advy]; + temp[1][1] = src[advy + advx]; + + vm[0][0] = (MULT_SCALE - FractPartX) * (MULT_SCALE - FractPartY); + vm[0][1] = FractPartX * (MULT_SCALE - FractPartY); + vm[1][0] = (MULT_SCALE - FractPartX) * FractPartY; + vm[1][1] = FractPartX * FractPartY; + + // Alpha + v[0][0] = vm[0][0] * temp[0][0].Alpha; + v[0][1] = vm[0][1] * temp[0][1].Alpha; + v[1][0] = vm[1][0] * temp[1][0].Alpha; + v[1][1] = vm[1][1] * temp[1][1].Alpha; + d.Alpha = (v[0][0] + v[1][0] + + v[0][1] + v[1][1] + MULT_SCALE * MULT_SCALE / 2) / (MULT_SCALE * MULT_SCALE); + + // Red + v[0][0] = vm[0][0] * temp[0][0].Red; + v[0][1] = vm[0][1] * temp[0][1].Red; + v[1][0] = vm[1][0] * temp[1][0].Red; + v[1][1] = vm[1][1] * temp[1][1].Red; + d.Red = (v[0][0] + v[1][0] + + v[0][1] + v[1][1] + MULT_SCALE * MULT_SCALE / 2) / (MULT_SCALE * MULT_SCALE); + + // Green + v[0][0] = vm[0][0] * temp[0][0].Green; + v[0][1] = vm[0][1] * temp[0][1].Green; + v[1][0] = vm[1][0] * temp[1][0].Green; + v[1][1] = vm[1][1] * temp[1][1].Green; + d.Green = (v[0][0] + v[1][0] + + v[0][1] + v[1][1] + MULT_SCALE * MULT_SCALE / 2) / (MULT_SCALE * MULT_SCALE); + + // Blue + v[0][0] = vm[0][0] * temp[0][0].Blue; + v[0][1] = vm[0][1] * temp[0][1].Blue; + v[1][0] = vm[1][0] * temp[1][0].Blue; + v[1][1] = vm[1][1] * temp[1][1].Blue; + d.Blue = (v[0][0] + v[1][0] + + v[0][1] + v[1][1] + MULT_SCALE * MULT_SCALE / 2) / (MULT_SCALE * MULT_SCALE); + + return d; +} + + +static struct ARGB INLINE ScaleARGBAverage2x2(const struct ARGB *src, + ULONG x, ULONG y, + ULONG SourceWidth, ULONG SourceHeight, + ULONG FractPartX, ULONG FractPartY) +{ + ULONG v[2][2]; + struct ARGB temp[2][2]; + struct ARGB d; + LONG BackX; + LONG BackY; + + // handle image borders + BackX = (x < 1) ? 0 : -1; + BackY = (y < 1) ? 0 : -SourceWidth; + + // copy pixel data to temp + temp[0][0] = src[BackY + BackX]; + temp[0][1] = src[BackY]; + temp[1][0] = src[BackX]; + temp[1][1] = src[0]; + + // Alpha + v[0][0] = temp[0][0].Alpha; + v[0][1] = temp[0][1].Alpha; + v[1][0] = temp[1][0].Alpha; + v[1][1] = temp[1][1].Alpha; + d.Alpha = (v[0][0] + v[0][1] + v[1][0] + v[1][1]) / 4; + + // Red + v[0][0] = temp[0][0].Red; + v[0][1] = temp[0][1].Red; + v[1][0] = temp[1][0].Red; + v[1][1] = temp[1][1].Red; + d.Red = (v[0][0] + v[0][1] + v[1][0] + v[1][1]) / 4; + + // Green + v[0][0] = temp[0][0].Green; + v[0][1] = temp[0][1].Green; + v[1][0] = temp[1][0].Green; + v[1][1] = temp[1][1].Green; + d.Green = (v[0][0] + v[0][1] + v[1][0] + v[1][1]) / 4; + + // Blue + v[0][0] = temp[0][0].Blue; + v[0][1] = temp[0][1].Blue; + v[1][0] = temp[1][0].Blue; + v[1][1] = temp[1][1].Blue; + d.Blue = (v[0][0] + v[0][1] + v[1][0] + v[1][1]) / 4; + + return d; +} + + +static struct ARGB INLINE ScaleARGBAverage3x3(const struct ARGB *src, + ULONG x, ULONG y, + ULONG SourceWidth, ULONG SourceHeight, + ULONG FractPartX, ULONG FractPartY) +{ + ULONG v[3][3]; + struct ARGB temp[3][3]; + struct ARGB d; + LONG BackX; + LONG BackY; + + // handle image borders + BackX = (x < 1) ? 0 : -1; + BackY = (y < 1) ? 0 : -SourceWidth; + + // copy pixel data to temp + temp[0][0] = src[BackY + BackX]; + temp[0][1] = src[BackY]; + temp[0][2] = src[BackY + 1]; + temp[1][0] = src[BackX]; + temp[1][1] = src[0]; + temp[1][2] = src[1]; + temp[2][0] = src[SourceWidth + BackX]; + temp[2][1] = src[SourceWidth]; + temp[2][2] = src[SourceWidth + 1]; + + // Alpha + v[0][0] = temp[0][0].Alpha; v[0][1] = temp[0][1].Alpha; v[0][2] = temp[0][2].Alpha; + v[1][0] = temp[1][0].Alpha; v[1][1] = temp[1][1].Alpha; v[1][2] = temp[1][2].Alpha; + v[2][0] = temp[2][0].Alpha; v[2][1] = temp[2][1].Alpha; v[2][2] = temp[2][2].Alpha; + d.Alpha = (v[0][0] + v[0][1] + v[0][2] + + v[1][0] + v[1][1] + v[1][2] + + v[2][0] + v[2][1] + v[2][2]) / 9; + + // Red + v[0][0] = temp[0][0].Red; v[0][1] = temp[0][1].Red; v[0][2] = temp[0][2].Red; + v[1][0] = temp[1][0].Red; v[1][1] = temp[1][1].Red; v[1][2] = temp[1][2].Red; + v[2][0] = temp[2][0].Red; v[2][1] = temp[2][1].Red; v[2][2] = temp[2][2].Red; + d.Red = (v[0][0] + v[0][1] + v[0][2] + + v[1][0] + v[1][1] + v[1][2] + + v[2][0] + v[2][1] + v[2][2]) / 9; + + // Green + v[0][0] = temp[0][0].Green; v[0][1] = temp[0][1].Green; v[0][2] = temp[0][2].Green; + v[1][0] = temp[1][0].Green; v[1][1] = temp[1][1].Green; v[1][2] = temp[1][2].Green; + v[2][0] = temp[2][0].Green; v[2][1] = temp[2][1].Green; v[2][2] = temp[2][2].Green; + d.Green = (v[0][0] + v[0][1] + v[0][2] + + v[1][0] + v[1][1] + v[1][2] + + v[2][0] + v[2][1] + v[2][2]) / 9; + + // Blue + v[0][0] = temp[0][0].Blue; v[0][1] = temp[0][1].Blue; v[0][2] = temp[0][2].Blue; + v[1][0] = temp[1][0].Blue; v[1][1] = temp[1][1].Blue; v[1][2] = temp[1][2].Blue; + v[2][0] = temp[2][0].Blue; v[2][1] = temp[2][1].Blue; v[2][2] = temp[2][2].Blue; + d.Blue = (v[0][0] + v[0][1] + v[0][2] + + v[1][0] + v[1][1] + v[1][2] + + v[2][0] + v[2][1] + v[2][2]) / 9; + + return d; +} + + +static struct ARGB INLINE ScaleARGBAverage4x4(const struct ARGB *src, + ULONG x, ULONG y, + ULONG SourceWidth, ULONG SourceHeight, + ULONG FractPartX, ULONG FractPartY) +{ + ULONG v[4][4]; + struct ARGB temp[4][4]; + struct ARGB d; + LONG BackX; + LONG BackY; + + // handle image borders + BackX = (x < 1) ? 0 : -1; + BackY = (y < 1) ? 0 : -SourceWidth; + + // copy pixel data to temp + temp[0][0] = src[BackY + BackX]; + temp[0][1] = src[BackY]; + temp[0][2] = src[BackY + 1]; + temp[0][3] = src[BackY + 2]; + temp[1][0] = src[BackX]; + temp[1][1] = src[0]; + temp[1][2] = src[1]; + temp[1][3] = src[2]; + temp[2][0] = src[SourceWidth + BackX]; + temp[2][1] = src[SourceWidth]; + temp[2][2] = src[SourceWidth + 1]; + temp[2][3] = src[SourceWidth + 2]; + temp[3][0] = src[SourceWidth * 2 + BackX]; + temp[3][1] = src[SourceWidth * 2]; + temp[3][2] = src[SourceWidth * 2 + 1]; + temp[3][3] = src[SourceWidth * 2 + 2]; + + // Alpha + v[0][0] = temp[0][0].Alpha; v[0][1] = temp[0][1].Alpha; v[0][2] = temp[0][2].Alpha; v[0][3] = temp[0][3].Alpha; + v[1][0] = temp[1][0].Alpha; v[1][1] = temp[1][1].Alpha; v[1][2] = temp[1][2].Alpha; v[1][3] = temp[1][3].Alpha; + v[2][0] = temp[2][0].Alpha; v[2][1] = temp[2][1].Alpha; v[2][2] = temp[2][2].Alpha; v[2][3] = temp[2][3].Alpha; + v[3][0] = temp[3][0].Alpha; v[3][1] = temp[3][1].Alpha; v[3][2] = temp[3][2].Alpha; v[3][3] = temp[3][3].Alpha; + d.Alpha = (v[0][0] + v[0][1] + v[0][2] + v[0][3] + + v[1][0] + v[1][1] + v[1][2] + v[1][3] + + v[2][0] + v[2][1] + v[2][2] + v[2][3] + + v[3][0] + v[3][1] + v[3][2] + v[3][3]) / 16; + + // Red + v[0][0] = temp[0][0].Red; v[0][1] = temp[0][1].Red; v[0][2] = temp[0][2].Red; v[0][3] = temp[0][3].Red; + v[1][0] = temp[1][0].Red; v[1][1] = temp[1][1].Red; v[1][2] = temp[1][2].Red; v[1][3] = temp[1][3].Red; + v[2][0] = temp[2][0].Red; v[2][1] = temp[2][1].Red; v[2][2] = temp[2][2].Red; v[2][3] = temp[2][3].Red; + v[3][0] = temp[3][0].Red; v[3][1] = temp[3][1].Red; v[3][2] = temp[3][2].Red; v[3][3] = temp[3][3].Red; + d.Red = (v[0][0] + v[0][1] + v[0][2] + v[0][3] + + v[1][0] + v[1][1] + v[1][2] + v[1][3] + + v[2][0] + v[2][1] + v[2][2] + v[2][3] + + v[3][0] + v[3][1] + v[3][2] + v[3][3]) / 16; + + // Green + v[0][0] = temp[0][0].Green; v[0][1] = temp[0][1].Green; v[0][2] = temp[0][2].Green; v[0][3] = temp[0][3].Green; + v[1][0] = temp[1][0].Green; v[1][1] = temp[1][1].Green; v[1][2] = temp[1][2].Green; v[1][3] = temp[1][3].Green; + v[2][0] = temp[2][0].Green; v[2][1] = temp[2][1].Green; v[2][2] = temp[2][2].Green; v[2][3] = temp[2][3].Green; + v[3][0] = temp[3][0].Green; v[3][1] = temp[3][1].Green; v[3][2] = temp[3][2].Green; v[3][3] = temp[3][3].Green; + d.Green = (v[0][0] + v[0][1] + v[0][2] + v[0][3] + + v[1][0] + v[1][1] + v[1][2] + v[1][3] + + v[2][0] + v[2][1] + v[2][2] + v[2][3] + + v[3][0] + v[3][1] + v[3][2] + v[3][3]) / 16; + + // Blue + v[0][0] = temp[0][0].Blue; v[0][1] = temp[0][1].Blue; v[0][2] = temp[0][2].Blue; v[0][3] = temp[0][3].Blue; + v[1][0] = temp[1][0].Blue; v[1][1] = temp[1][1].Blue; v[1][2] = temp[1][2].Blue; v[1][3] = temp[1][3].Blue; + v[2][0] = temp[2][0].Blue; v[2][1] = temp[2][1].Blue; v[2][2] = temp[2][2].Blue; v[2][3] = temp[2][3].Blue; + v[3][0] = temp[3][0].Blue; v[3][1] = temp[3][1].Blue; v[3][2] = temp[3][2].Blue; v[3][3] = temp[3][3].Blue; + d.Blue = (v[0][0] + v[0][1] + v[0][2] + v[0][3] + + v[1][0] + v[1][1] + v[1][2] + v[1][3] + + v[2][0] + v[2][1] + v[2][2] + v[2][3] + + v[3][0] + v[3][1] + v[3][2] + v[3][3]) / 16; + + return d; +} + + +// Scale 2x with directional interpolation +#if 0 +static void ScaleARGB2X(const struct ARGBHeader *src, struct ARGBHeader *Dest) +{ + ULONG y; + const struct ARGB *SourcePtr = src->argb_ImageData; + ULONG DestWidth = 2 * src->argb_Width; + + for (y = 0; y < src->argb_Height; y++) + { + ULONG x; + struct ARGB *TargetLineStart; + + TargetLineStart = Dest->argb_ImageData + 2 * y * Dest->argb_Width; + + for (x = 0; x < src->argb_Width; x++) + { + struct ARGB v[3][3]; + struct ARGB *Target; + + Target = TargetLineStart + 2 * x; + + v[0][2] = SourcePtr[PIXEL_NORTH]; + v[1][0] = SourcePtr[PIXEL_WEST]; + v[1][1] = SourcePtr[0]; + + v[1][2] = SourcePtr[PIXEL_EAST]; + v[2][1] = SourcePtr[PIXEL_SOUTH]; + + Target[0] = (ARGB_EQ(v[1][0], v[0][2]) && !ARGB_EQ(v[0][2], v[1][2]) && !ARGB_EQ(v[1][0], v[2][1])) ? v[1][0] : v[1][1]; + Target[1] = (ARGB_EQ(v[0][2], v[1][2]) && !ARGB_EQ(v[0][2], v[1][0]) && !ARGB_EQ(v[1][2], v[2][1])) ? v[1][2] : v[1][1]; + Target[DestWidth] = (ARGB_EQ(v[1][0], v[2][1]) && !ARGB_EQ(v[1][0], v[0][2]) && !ARGB_EQ(v[2][1], v[1][2])) ? v[1][0] : v[1][1]; + Target[DestWidth + 1] = (ARGB_EQ(v[2][1], v[1][2]) && !ARGB_EQ(v[1][0], v[2][1]) && !ARGB_EQ(v[0][2], v[1][2])) ? v[1][2] : v[1][1]; + + SourcePtr++; + } + } +} +#endif + +struct ARGB *ScaleARGBArray(const struct ARGBHeader *src, + ULONG *DestWidth, ULONG *DestHeight, ULONG Flags, + struct ScalosGfxBase *ScalosGfxBase) +{ + struct ARGB *DestArray = NULL; + struct ARGBHeader TempARGB; + + memset(&TempARGB, 0, sizeof(TempARGB)); + + if (Flags & SCALEFLAGF_CORRECTASPECT) + { + CalculateScaleAspect(src->argb_Width, src->argb_Height, DestWidth, DestHeight); + } + + do { + struct ARGB (*ScalingFunction)(const struct ARGB *, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG); + ULONG y; + struct ARGB *DestPtr; + ULONG IntPartX, IntPartY; + + d1(KPrintF("%s/%ld: DestWidth=%lu DestHeight=%lu\n", __FUNC__, __LINE__, *DestWidth, *DestHeight)); + + if (!(Flags & (SCALEFLAGF_BILINEAR | SCALEFLAGF_AVERAGE | SCALEFLAGF_DOUBLESIZE))) + break; + + DestArray = AllocARGB(*DestWidth, *DestHeight, ScalosGfxBase); + if (NULL == DestArray) + break; + + if (src->argb_Width == *DestWidth && src->argb_Height == *DestHeight) + { + memcpy(DestArray, src->argb_ImageData, + src->argb_Width * src->argb_Height * sizeof(struct ARGB)); + break; + } + +#if 0 + while ((Flags & SCALEFLAGF_DOUBLESIZE) && + ((*DestWidth > src->argb_Width) || (*DestHeight > src->argb_Height))) + { + struct ARGBHeader Temp2ARGB; + + memset(&Temp2ARGB, 0, sizeof(Temp2ARGB)); + + if (TempARGB.argb_ImageData) + { + Temp2ARGB = TempARGB; + src = &Temp2ARGB; + } + + TempARGB.argb_Width = 2 * src->argb_Width; + TempARGB.argb_Height = 2 * src->argb_Height; + TempARGB.argb_ImageData = AllocARGB(TempARGB.argb_Width, TempARGB.argb_Height, + ScalosGfxBase); + if (TempARGB.argb_ImageData) + { + ScaleARGB2X(src, &TempARGB); + + src = &TempARGB; + } + + if (Temp2ARGB.argb_ImageData) + FreeARGB(&Temp2ARGB.argb_ImageData, ScalosGfxBase); + d1(KPrintF("%s/%ld: ScaleARGB2X Width=%ld Height=%ld\n", __FUNC__, __LINE__, src->argb_Width, src->argb_Height)); + } +#endif + + IntPartX = (src->argb_Width * MULT_SCALE) / *DestWidth; + IntPartY = (src->argb_Height * MULT_SCALE) / *DestHeight; + +#if 0 + ScalingFunction = ScaleARGBAverage2x2; +#else + if ((Flags & SCALEFLAGF_AVERAGE) + && ((*DestWidth <= src->argb_Width / 4) || (*DestHeight <= src->argb_Height / 4))) + { + d1(KPrintF("%s/%ld: ScaleARGBAverage4x4 Flags=%08lx\n", __FUNC__, __LINE__, Flags)); + ScalingFunction = ScaleARGBAverage4x4; + } + else if ((Flags & SCALEFLAGF_AVERAGE) + && (((2 * *DestWidth) < src->argb_Width / 5) || ((2 * *DestHeight) < src->argb_Height / 5))) + { + d1(KPrintF("%s/%ld: ScaleARGBAverage3x3 Flags=%08lx\n", __FUNC__, __LINE__, Flags)); + ScalingFunction = ScaleARGBAverage3x3; + } + else if ((Flags & SCALEFLAGF_AVERAGE) + && (((5 * *DestWidth) < src->argb_Width / 3) || ((5 * *DestHeight) < src->argb_Height / 3))) + { + d1(KPrintF("%s/%ld: ScaleARGBAverage2x2 Flags=%08lx\n", __FUNC__, __LINE__, Flags)); + ScalingFunction = ScaleARGBAverage2x2; + } + else if (Flags & SCALEFLAGF_BICUBIC) + { + d1(KPrintF("%s/%ld: ScaleARGBBicubic Flags=%08lx\n", __FUNC__, __LINE__, Flags)); + ScalingFunction = ScaleARGBBicubic; + } + else if (Flags & SCALEFLAGF_BILINEAR) + { + d1(KPrintF("%s/%ld: ScaleARGBBilinear Flags=%08lx\n", __FUNC__, __LINE__, Flags)); + ScalingFunction = ScaleARGBBilinear; + } + else + { + d1(KPrintF("%s/%ld: ScaleNearestNeighbour Flags=%08lx\n", __FUNC__, __LINE__, Flags)); + ScalingFunction = ScaleNearestNeighbour; + } +#endif + + d1(KPrintF("%s/%ld: IntPartX=%lu IntPartY=%lu\n", __FUNC__, __LINE__, IntPartX, IntPartY)); + + DestPtr = DestArray; + for (y = 0; y < *DestHeight; y++) + { + ULONG x; + ULONG TargetY; + LONG FractPartY; + const struct ARGB *SrcLineStart; + + TargetY = (IntPartY * y); + FractPartY = TargetY & (MULT_SCALE - 1); + TargetY /= MULT_SCALE; + + d1(KPrintF("%s/%ld: DestPtr=%08lx TargetY=%lu FractPartY=%lu\n", __FUNC__, __LINE__, DestPtr, TargetY, FractPartY)); + + SrcLineStart = src->argb_ImageData + TargetY * src->argb_Width; + + for (x = 0; x < *DestWidth; x++) + { + LONG FractPartX; + ULONG TargetX; + const struct ARGB *SourcePtr; + + TargetX = (IntPartX * x); + FractPartX = TargetX & (MULT_SCALE - 1); + TargetX /= MULT_SCALE; + + SourcePtr = SrcLineStart + TargetX; + + *DestPtr = ScalingFunction(SourcePtr, + TargetX, TargetY, + src->argb_Width, src->argb_Height, + FractPartX, FractPartY); + + DestPtr++; + } + } + } while (0); + + if (TempARGB.argb_ImageData) + FreeARGB(&TempARGB.argb_ImageData, ScalosGfxBase); + + return DestArray; +} + + +struct BitMap *ScaleBitMap(struct BitMap *SourceBM, + ULONG SourceWidth, ULONG SourceHeight, + ULONG *DestWidth, ULONG *DestHeight, + ULONG NumberOfColors, const ULONG *ColorTable, + ULONG Flags, struct BitMap *ScreenBM, + struct ScalosGfxBase *ScalosGfxBase) +{ + struct ARGBHeader Source; + struct ARGB *DestArray = NULL; + ULONG Depth; + struct BitMap *DestBM = NULL; + + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + + memset(&Source, 0, sizeof(Source)); + + Depth = GetBitMapAttr(SourceBM, BMA_DEPTH); + + if (Flags & SCALEFLAGF_CORRECTASPECT) + { + CalculateScaleAspect(SourceWidth, SourceHeight, + DestWidth, DestHeight); + } + + d1(KPrintF("%s/%ld: CyberGfxBase=%08lx ScreenBM=%08lx\n", __FUNC__, __LINE__, CyberGfxBase, ScreenBM)); + d1(KPrintF("%s/%ld: SourceWidth=%lu SourceHeight=%ld\n", __FUNC__, __LINE__, SourceWidth, SourceHeight)); + d1(KPrintF("%s/%ld: DestWidth=%lu DestHeight=%ld\n", __FUNC__, __LINE__, *DestWidth, *DestHeight)); + d1(KPrintF("%s/%ld: NumberOfColors=%ld Depth=%lu\n", __FUNC__, __LINE__, NumberOfColors, Depth)); + + do { + if (Source.argb_Width == *DestWidth && Source.argb_Height == *DestHeight) + break; + + Source.argb_Width = SourceWidth; + Source.argb_Height = SourceHeight; + + DestBM = AllocBitMap(*DestWidth, *DestHeight, + Depth, 0, SourceBM); + if (NULL == DestBM) + break; + + d1(KPrintF("%s/%ld: DestBM: Width=%lu Height=%ld Depth=%ld\n", \ + __FUNC__, __LINE__, \ + GetBitMapAttr(DestBM, BMA_WIDTH), \ + GetBitMapAttr(DestBM, BMA_HEIGHT), \ + GetBitMapAttr(DestBM, BMA_DEPTH))); + + if (CyberGfxBase) + { + d1(KPrintF("%s/%ld: ARGB Scaling\n", __FUNC__, __LINE__)); + + Source.argb_ImageData = CreateARGBFromBitMap(SourceBM, + Source.argb_Width, Source.argb_Height, + NumberOfColors, ColorTable, NULL, ScalosGfxBase); + d1(KPrintF("%s/%ld: argb_ImageData=%08lx\n", __FUNC__, __LINE__, Source.argb_ImageData)); + if (NULL == Source.argb_ImageData) + break; + + DestArray = ScaleARGBArray(&Source, + DestWidth, DestHeight, + Flags, ScalosGfxBase); + d1(KPrintF("%s/%ld: DestArray=%08lx\n", __FUNC__, __LINE__, DestArray)); + if (NULL == DestArray) + break; + + WriteARGBToBitMap(DestArray, + DestBM, *DestWidth, *DestHeight, + NumberOfColors, ColorTable, ScalosGfxBase); + } + else + { + struct BitScaleArgs bitScaleArgs; + + d1(KPrintF("%s/%ld: BitMapScale Scaling\n", __FUNC__, __LINE__)); + + bitScaleArgs.bsa_SrcBitMap = SourceBM; + bitScaleArgs.bsa_DestBitMap = DestBM; + + bitScaleArgs.bsa_SrcX = 0; + bitScaleArgs.bsa_SrcY = 0; + + bitScaleArgs.bsa_SrcWidth = SourceWidth; + bitScaleArgs.bsa_SrcHeight = SourceHeight; + + bitScaleArgs.bsa_DestX = 0; + bitScaleArgs.bsa_DestY = 0; + + bitScaleArgs.bsa_Flags = 0; + + bitScaleArgs.bsa_XSrcFactor = SourceWidth; + bitScaleArgs.bsa_YSrcFactor = SourceHeight; + bitScaleArgs.bsa_XDestFactor = *DestWidth; + bitScaleArgs.bsa_YDestFactor = *DestHeight; + + BitMapScale(&bitScaleArgs); + } + } while (0); + + d1(KPrintF("%s/%ld: \n", __FUNC__, __LINE__)); + + FreeARGB(&Source.argb_ImageData, ScalosGfxBase); + FreeARGB(&DestArray, ScalosGfxBase); + + d1(KPrintF("%s/%ld: END\n", __FUNC__, __LINE__)); + + return DestBM; +} + + +void CalculateScaleAspect(ULONG SourceWidth, ULONG SourceHeight, + ULONG *DestWidth, ULONG *DestHeight) +{ + d1(KPrintF("%s/%ld: SourceWidth=%lu SourceHeight=%lu\n", __FUNC__, __LINE__, SourceWidth, SourceHeight)); + + if (SourceWidth > SourceHeight) + { + // image is wider than tall + *DestHeight = (SourceHeight * + ((*DestWidth << 16) / SourceWidth)) >> 16; + if (*DestHeight < 1) + *DestHeight = 1; + } + else + { + // image is taller than wide + *DestWidth = (SourceWidth * + ((*DestHeight << 16) / SourceHeight)) >> 16; + if (*DestWidth < 1) + *DestWidth = 1; + } + + d1(KPrintF("%s/%ld: DestWidth=%lu DestHeight=%lu\n", __FUNC__, __LINE__, *DestWidth, *DestHeight)); +} + diff --git a/scalos/libraries/scalosgfx/Dither.c b/scalos/libraries/scalosgfx/Dither.c new file mode 100755 index 000000000..c2faabba3 --- /dev/null +++ b/scalos/libraries/scalosgfx/Dither.c @@ -0,0 +1,1045 @@ +// Dither.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include + +#include "scalosgfx.h" + +//----------------------------------------------------------------------- + +#define HASH_SIZE 20023 + +#define MAXCOLORS 32767 + +/* #define LARGE_NORM */ +#define LARGE_LUM + +/* #define REP_CENTER_BOX */ +/* #define REP_AVERAGE_COLORS */ +#define REP_AVERAGE_PIXELS + +//----------------------------------------------------------------------- + +#define PPM_MAXMAXVAL PGM_MAXMAXVAL + +#define PPM_GETR(p) ((p).Red) +#define PPM_GETG(p) ((p).Green) +#define PPM_GETB(p) ((p).Blue) + +/************* added definitions *****************/ + +#define PPM_EQUAL(p,q) ( (p).Red == (q).Red \ + && (p).Green == (q).Green \ + && (p).Blue == (q).Blue ) + +/* Color scaling macro -- to make writing ppmtowhatever easier. */ + +#define PPM_DEPTH(newp, p, oldmaxval, newmaxval) \ + (newp).Red = ( (int) (p).Red * (newmaxval) + (oldmaxval) / 2 ) / (oldmaxval); \ + (newp).Green = ( (int) (p).Green * (newmaxval) + (oldmaxval) / 2 ) / (oldmaxval); \ + (newp).Blue = ( (int) (p).Blue * (newmaxval) + (oldmaxval) / 2 ) / (oldmaxval) + + +/* Luminance macro. */ + +#define PPM_LUMIN(p) ( 0.299 * (p).Red + 0.587 * (p).Green + 0.114 * (p).Blue ) + +struct box + { + int ind; + int colors; + int sum; + }; + +/* Color histogram stuff. */ + +struct colorhist_item + { + struct ARGB color; + int value; + }; + +struct colorhist_list_item + { + struct colorhist_item ch; + struct colorhist_list_item * next; + }; + +struct longRGB + { + LONG Red; + LONG Green; + LONG Blue; + }; + +//----------------------------------------------------------------------- + +static struct colorhist_item *mediancut( struct colorhist_item * chv, int colors, + int sum, ULONG maxval, int newcolors, struct ScalosGfxBase *ScalosGfxBase); +static int redcompare(const void *c1, const void *c2); +static int greencompare(const void *c1, const void *c2); +static int bluecompare(const void *c1, const void *c2); +static int sumcompare(const void *c1, const void *c2); +static long ppm_hashpixel(const struct ARGB *p); +static struct colorhist_item * ppm_computecolorhist(const struct ARGBHeader *argbh, + int maxcolors, int *colorsP, struct ScalosGfxBase *ScalosGfxBase); +static struct colorhist_list_item **ppm_computecolorhash(const struct ARGBHeader *argbh, + int maxcolors, int *colorsP, struct ScalosGfxBase *ScalosGfxBase); +static struct colorhist_list_item ** ppm_alloccolorhash(struct ScalosGfxBase *ScalosGfxBase); +static int ppm_addtocolorhash(struct colorhist_list_item **cht, const struct ARGB *colorP, int value, struct ScalosGfxBase *ScalosGfxBase); +static struct colorhist_item * ppm_colorhashtocolorhist(struct colorhist_list_item ** cht, int maxcolors, struct ScalosGfxBase *ScalosGfxBase); +static int ppm_lookupcolor(struct colorhist_list_item ** cht, const struct ARGB *colorP); +static void ppm_freecolorhist(struct colorhist_item * chv, struct ScalosGfxBase *ScalosGfxBase); +static void ppm_freecolorhash(struct colorhist_list_item ** cht, struct ScalosGfxBase *ScalosGfxBase); +static void *pm_allocrow(int cols, int size, struct ScalosGfxBase *ScalosGfxBase); +static void pm_freerow(void *itrow, struct ScalosGfxBase *ScalosGfxBase); + +//----------------------------------------------------------------------- + +/* +** Copyright (C) 1989, 1991 by Jef Poskanzer. +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation. This software is provided "as is" without express or +** implied warranty. +*/ + + +struct ScalosBitMapAndColor *MedianCut(struct ARGBHeader *argbh, + ULONG Depth, ULONG newcolors, + BOOL floyd, struct BitMap *FriendBM, + struct ScalosGfxBase *ScalosGfxBase) +{ + struct ScalosBitMapAndColor *sac = NULL; + struct ARGBHeader mappixels; + struct ARGB *pixels; + UBYTE *AllocPixelLine = NULL; + struct BitMap *TempBM = NULL; + int row; + int col, limitcol; + ULONG maxval, newmaxval; + int colors = 0; + int ind; + struct colorhist_item *chv = NULL; + struct colorhist_item *colormap = NULL; + struct colorhist_list_item **cht = NULL; + BOOL usehash; + struct longRGB *thiserr = NULL; + struct longRGB *nexterr = NULL; +#define FS_SCALE 1024 + BOOL fs_direction = FALSE; + BOOL Success = FALSE; + + d1(KPrintF(__FILE__ "/" "%s/%ld: START w=%ld h=%ld floyd=%ld\n", \ + __LINE__, argbh->argb_Width, argbh->argb_Height, floyd)); + + d1(KPrintF(__FILE__ "/" "%s/%ld: argb_ImageData: A=%ld R=%ld G=%ld B=%ld\n", \ + __LINE__, argbh->argb_ImageData->Alpha, \ + argbh->argb_ImageData->Red, argbh->argb_ImageData->Green, \ + argbh->argb_ImageData->Blue)); + + do { + ULONG *pColorTable; + struct RastPort rp; + struct RastPort TempRp; + struct longRGB s = { 0, 0, 0 }; + + InitRastPort(&rp); + InitRastPort(&TempRp); + + memset(&mappixels, 0, sizeof(mappixels)); + + if (newcolors < 2) + { + d1(KPrintF(__FILE__ "/" "%s/%ld:number of colors must be > 2\n", __FUNC__, __LINE__)); + break; + } + if (newcolors > 256) + { + d1(KPrintF(__FILE__ "/" "%s/%ld:number of colors must be < 256\n", __FUNC__, __LINE__)); + break; + } + + maxval = 255; + + sac = AllocSAC(argbh->argb_Width, argbh->argb_Height, Depth, FriendBM, NULL, ScalosGfxBase); + if (NULL == sac) + break; + + sac->sac_TransparentColor = SAC_TRANSPARENT_NONE; + + rp.BitMap = sac->sac_BitMap; + d1(KPrintF(__FILE__ "/" "%s/%ld: rp.BitMap=%08lx\n", __FUNC__, __LINE__, rp.BitMap)); + + // setup temp. RastPort for use by WritePixelLine8() + TempRp.Layer = NULL; + TempRp.BitMap = TempBM = AllocBitMap(TEMPRP_WIDTH(argbh->argb_Width), 1, 8, 0, NULL); + if (NULL == TempBM) + break; + + // allocate pens for 1 line (1 byte per pixel) + AllocPixelLine = ScalosGfxAllocVecPooled(ScalosGfxBase, ((argbh->argb_Width + 15) >> 4) << 4); + if (NULL == AllocPixelLine) + break; + + /* + ** Step 2: attempt to make a histogram of the colors, unclustered. + ** If at first we don't succeed, lower maxval to increase color + ** coherence and try again. This will eventually terminate, with + ** maxval at worst 15, since 32^3 is approximately MAXCOLORS. + */ + for ( ; ; ) + { + d1(KPrintF(__FILE__ "/" "%s/%ld: making histogram...\n", __FUNC__, __LINE__)); + chv = ppm_computecolorhist(argbh, MAXCOLORS, &colors, ScalosGfxBase); + if ( chv != (struct colorhist_item *) NULL ) + break; + + d1(KPrintF(__FILE__ "/" "%s/%ld: too many colors!\n", __FUNC__, __LINE__)); + + newmaxval = maxval / 2; + d1(KPrintF(__FILE__ "/" "%s/%ld: scaling colors from maxval=%d to maxval=%d to improve clustering...\n", + __LINE__, maxval, newmaxval)); + for ( row = 0, pixels = argbh->argb_ImageData; + row < argbh->argb_Height; + ++row, pixels += argbh->argb_Width) + { + struct ARGB *pP = pixels; + for ( col = 0; col < argbh->argb_Width; ++col, ++pP ) + { + PPM_DEPTH(*pP, *pP, maxval, newmaxval); + } + } + maxval = newmaxval; + } + d1(KPrintF(__FILE__ "/" "%s/%ld: %d colors found\n", __FUNC__, __LINE__, colors)); + + /* + ** Step 3: apply median-cut to histogram, making the new colormap. + */ + d1(KPrintF(__FILE__ "/" "%s/%ld: choosing %d colors...\n", __FUNC__, __LINE__, newcolors)); + colormap = mediancut( chv, colors, argbh->argb_Height * argbh->argb_Width, maxval, newcolors, ScalosGfxBase ); + if (NULL == colormap) + break; + + d1(KPrintF(__FILE__ "/" "%s/%ld: colormap: %08lx %08lx %08lx %08lx\n", \ + __LINE__, *((ULONG *) &colormap[0].color), \ + *((ULONG *) &colormap[1].color), \ + *((ULONG *) &colormap[2].color), \ + *((ULONG *) &colormap[3].color))); + + /* + ** Step 4: map the colors in the image to their closest match in the + ** new colormap, and write 'em out. + */ + d1(KPrintF(__FILE__ "/" "%s/%ld: mapping image to new colors...\n", __FUNC__, __LINE__)); + cht = ppm_alloccolorhash(ScalosGfxBase); + d1(KPrintF(__FILE__ "/" "%s/%ld: cht=%08lx\n", __FUNC__, __LINE__, cht)); + if (NULL == cht) + break; + + usehash = TRUE; +//+++ ppm_writeppminit( stdout, argbh->argb_Width, argbh->argb_Height, maxval, 0 ); + if ( floyd ) + { + struct DateStamp ds; + + /* Initialize Floyd-Steinberg error vectors. */ + thiserr = (struct longRGB *) pm_allocrow( argbh->argb_Width + 2, sizeof(struct longRGB), ScalosGfxBase); + if (NULL == thiserr) + break; + nexterr = (struct longRGB *) pm_allocrow( argbh->argb_Width + 2, sizeof(struct longRGB), ScalosGfxBase ); + if (NULL == nexterr) + break; + + DateStamp(&ds); + srand(ds.ds_Tick); + + d1(KPrintF(__FILE__ "/" "%s/%ld: thiserr=%08lx nexterr=%08lx\n", \ + __LINE__, thiserr, nexterr)); + + for ( col = 0; col < argbh->argb_Width + 2; ++col ) + { + thiserr[col].Red = rand() % ( FS_SCALE * 2 ) - FS_SCALE; + thiserr[col].Green = rand() % ( FS_SCALE * 2 ) - FS_SCALE; + thiserr[col].Blue = rand() % ( FS_SCALE * 2 ) - FS_SCALE; + /* (random errors in [-1 .. 1]) */ + d1(KPrintF(__FILE__ "/" "%s/%ld: F/S error[%ld]: R=%08lx G=%08lx B=%08lx\n", \ + __LINE__, col, thiserr[col].Red, thiserr[col].Green, thiserr[col].Blue)); + } + + fs_direction = TRUE; + } + + d1(KPrintF(__FILE__ "/" "%s/%ld: \n", __FUNC__, __LINE__)); + + for ( row = 0, pixels = argbh->argb_ImageData; + row < argbh->argb_Height; + ++row, pixels += argbh->argb_Width) + { + UBYTE *pPixelLine; + struct ARGB *pP; + + d1(KPrintF(__FILE__ "/" "%s/%ld: row=%ld pixels=%08lx\n", __FUNC__, __LINE__, row, pixels)); + + if ( floyd ) + { + for ( col = 0; col < argbh->argb_Width + 2; ++col ) + nexterr[col].Red = nexterr[col].Green = nexterr[col].Blue = 0; + } + if ( ( ! floyd ) || fs_direction ) + { + col = 0; + limitcol = argbh->argb_Width; + pP = pixels; + pPixelLine = AllocPixelLine; + } + else + { + col = argbh->argb_Width - 1; + limitcol = -1; + pP = pixels + col; + pPixelLine = AllocPixelLine + col; + } + + d1(KPrintF(__FILE__ "/" "%s/%ld: pP=%08lx\n", __FUNC__, __LINE__, pP)); + + do { + if ( floyd ) + { + /* Use Floyd-Steinberg errors to adjust actual color. */ + d1(KPrintF(__FILE__ "/" "%s/%ld: thiserr[%ld]: R=%4ld G=%4ld B=%4ld\n", \ + __LINE__, col + 1, thiserr[col + 1].Red, thiserr[col + 1].Green, thiserr[col + 1].Blue)); + + s.Red = pP->Red + thiserr[col + 1].Red / FS_SCALE; + s.Green = pP->Green + thiserr[col + 1].Green / FS_SCALE; + s.Blue = pP->Blue + thiserr[col + 1].Blue / FS_SCALE; + + if ( s.Red < 0 ) + s.Red = 0; + else if ( s.Red > maxval ) + s.Red = maxval; + if ( s.Green < 0 ) + s.Green = 0; + else if ( s.Green > maxval ) + s.Green = maxval; + if ( s.Blue < 0 ) + s.Blue = 0; + else if ( s.Blue > maxval ) + s.Blue = maxval; + + d1(KPrintF(__FILE__ "/" "%s/%ld: Red=%3d s.Red=%ld\n", __FUNC__, __LINE__, pP->Red, s.Red)); + d1(KPrintF(__FILE__ "/" "%s/%ld: Green=%3d s.Green=%ld\n", __FUNC__, __LINE__, pP->Green, s.Green)); + d1(KPrintF(__FILE__ "/" "%s/%ld: Blue=%3d s.Blue=%ld\n", __FUNC__, __LINE__, pP->Blue, s.Blue)); + + pP->Red = s.Red; + pP->Green = s.Green; + pP->Blue = s.Blue; + } + + /* Check hash table to see if we have already matched this color. */ + ind = ppm_lookupcolor( cht, pP ); + d1(KPrintF(__FILE__ "/" "%s/%ld: ind=%ld\n", __FUNC__, __LINE__, ind)); + if ( ind == -1 ) + { + /* No; search colormap for closest match. */ + int i, r1, g1, b1; + long dist; + + r1 = pP->Red; + g1 = pP->Green; + b1 = pP->Blue; + dist = LONG_MAX; + for ( i = 0; i < newcolors; ++i ) + { + int r2, g2, b2; + long newdist; + + r2 = colormap[i].color.Red; + g2 = colormap[i].color.Green; + b2 = colormap[i].color.Blue; + + newdist = ( r1 - r2 ) * ( r1 - r2 ) + + ( g1 - g2 ) * ( g1 - g2 ) + + ( b1 - b2 ) * ( b1 - b2 ); + if ( newdist < dist ) + { + ind = i; + dist = newdist; + } + } + if ( usehash ) + { + if ( ppm_addtocolorhash( cht, pP, ind, ScalosGfxBase) < 0 ) + { + d1(KPrintF(__FILE__ "/" "%s/%ld: out of memory adding to hash table, proceeding without it\n", __FUNC__, __LINE__)); + usehash = FALSE; + } + } + } + + if ( floyd ) + { + /* Propagate Floyd-Steinberg error terms. */ + long err; + + if ( fs_direction ) + { + err = (s.Red - (long) colormap[ind].color.Red) * FS_SCALE; + d1(KPrintF(__FILE__ "/" "%s/%ld: Red err=%ld\n", __FUNC__, __LINE__, err)); + thiserr[col + 2].Red += ( err * 7 ) / 16; + nexterr[col ].Red += ( err * 3 ) / 16; + nexterr[col + 1].Red += ( err * 5 ) / 16; + nexterr[col + 2].Red += ( err ) / 16; + err = (s.Green - (long) colormap[ind].color.Green) * FS_SCALE; + d1(KPrintF(__FILE__ "/" "%s/%ld: Green err=%ld\n", __FUNC__, __LINE__, err)); + thiserr[col + 2].Green += ( err * 7 ) / 16; + nexterr[col ].Green += ( err * 3 ) / 16; + nexterr[col + 1].Green += ( err * 5 ) / 16; + nexterr[col + 2].Green += ( err ) / 16; + err = (s.Blue - (long) colormap[ind].color.Blue) * FS_SCALE; + d1(KPrintF(__FILE__ "/" "%s/%ld: Blue err=%ld\n", __FUNC__, __LINE__, err)); + thiserr[col + 2].Blue += ( err * 7 ) / 16; + nexterr[col ].Blue += ( err * 3 ) / 16; + nexterr[col + 1].Blue += ( err * 5 ) / 16; + nexterr[col + 2].Blue += ( err ) / 16; + } + else + { + err = (s.Red - (long) colormap[ind].color.Red) * FS_SCALE; + d1(KPrintF(__FILE__ "/" "%s/%ld: Red err=%ld\n", __FUNC__, __LINE__, err)); + thiserr[col ].Red += ( err * 7 ) / 16; + nexterr[col + 2].Red += ( err * 3 ) / 16; + nexterr[col + 1].Red += ( err * 5 ) / 16; + nexterr[col ].Red += ( err ) / 16; + err = (s.Green - (long) colormap[ind].color.Green) * FS_SCALE; + d1(KPrintF(__FILE__ "/" "%s/%ld: Green err=%ld\n", __FUNC__, __LINE__, err)); + thiserr[col ].Green += ( err * 7 ) / 16; + nexterr[col + 2].Green += ( err * 3 ) / 16; + nexterr[col + 1].Green += ( err * 5 ) / 16; + nexterr[col ].Green += ( err ) / 16; + err = (s.Blue - (long) colormap[ind].color.Blue) * FS_SCALE; + d1(KPrintF(__FILE__ "/" "%s/%ld: Blue err=%ld\n", __FUNC__, __LINE__, err)); + thiserr[col ].Blue += ( err * 7 ) / 16; + nexterr[col + 2].Blue += ( err * 3 ) / 16; + nexterr[col + 1].Blue += ( err * 5 ) / 16; + nexterr[col ].Blue += ( err ) / 16; + } + } + + pP->Red = colormap[ind].color.Red; + pP->Green = colormap[ind].color.Green; + pP->Blue = colormap[ind].color.Blue; + + // Check transparency, and set color index to 0 for transparent pixels + if (pP->Alpha >= 128) + *pPixelLine = 1 + ind; + else + { + // mark this pixel as transparent + *pPixelLine = sac->sac_TransparentColor = 0; + } + + d1(KPrintF(__FILE__ "/" "%s/%ld: row=%ld col=%ld ind=%ld color=%08lx\n", \ + __LINE__, row, col, ind, *((ULONG *) pP))); + + if ( ( ! floyd ) || fs_direction ) + { + ++col; + ++pP; + ++pPixelLine; + } + else + { + --col; + --pP; + --pPixelLine; + } + } while ( col != limitcol ); + + if ( floyd ) + { + struct longRGB *temperr; + + temperr = thiserr; + thiserr = nexterr; + nexterr = temperr; + fs_direction = !fs_direction; + } + + d1(KPrintF(__FILE__ "/" "%s/%ld: row=%ld\n", __FUNC__, __LINE__, row)); + + WritePixelLine8(&rp, 0, row, + argbh->argb_Width, AllocPixelLine, &TempRp); + } + + d1(KPrintF(__FILE__ "/" "%s/%ld: \n", __FUNC__, __LINE__)); + + // fill sac_ColorTable + // leave first entry in sac_ColorTable free since + // it is used as transparency indicator + for (ind = 0, pColorTable = sac->sac_ColorTable + 3; + ind < sac->sac_NumColors - 1; ind++) + { + *pColorTable++ = colormap[ind].color.Red << 24; + *pColorTable++ = colormap[ind].color.Green << 24; + *pColorTable++ = colormap[ind].color.Blue << 24; + } + Success = TRUE; + } while (0); + + d1(KPrintF(__FILE__ "/" "%s/%ld: \n", __FUNC__, __LINE__)); + + if (!Success) + FreeSAC(sac, ScalosGfxBase); + if (colormap) + ScalosGfxFreeVecPooled(ScalosGfxBase, colormap); + if (cht) + ppm_freecolorhash(cht, ScalosGfxBase); + if (chv) + ppm_freecolorhist( chv, ScalosGfxBase); + if (thiserr) + pm_freerow(thiserr, ScalosGfxBase); + if (nexterr) + pm_freerow(nexterr, ScalosGfxBase); + if (AllocPixelLine) + ScalosGfxFreeVecPooled(ScalosGfxBase, AllocPixelLine); + if (TempBM) + FreeBitMap(TempBM); + + d1(KPrintF(__FILE__ "/" "%s/%ld: END Success=%ld\n", __FUNC__, __LINE__, Success)); + + return sac; +} + + +/* +** Here is the fun part, the median-cut colormap generator. This is based +** on Paul Heckbert's paper "Color Image Quantization for Frame Buffer +** Display", SIGGRAPH '82 Proceedings, page 297. +*/ +static struct colorhist_item *mediancut( struct colorhist_item * chv, + int colors, int sum, ULONG maxval, int newcolors, + struct ScalosGfxBase *ScalosGfxBase ) +{ + struct colorhist_item * colormap; + struct box * bv; + int bi, i; + int boxes; + + bv = (struct box *) ScalosGfxAllocVecPooled(ScalosGfxBase, sizeof(struct box) * newcolors ); + colormap = (struct colorhist_item *) ScalosGfxAllocVecPooled(ScalosGfxBase, sizeof(struct colorhist_item) * newcolors ); + + if (bv == NULL || colormap == NULL) + { + d1(KPrintF(__FILE__ "/" "%s/%ld: out of memory\n", __FUNC__, __LINE__)); + return NULL; + } + + for ( i = 0; i < newcolors; ++i ) + { + colormap[i].color.Alpha = 0xff; + colormap[i].color.Red = 0; + colormap[i].color.Green = 0; + colormap[i].color.Blue = 0; + } + + /* + ** Set up the initial box. + */ + bv[0].ind = 0; + bv[0].colors = colors; + bv[0].sum = sum; + boxes = 1; + + /* + ** Main loop: split boxes until we have enough. + */ + while ( boxes < newcolors ) + { + int indx, clrs; + int sm; + int minr, maxr, ming, maxg, minb, maxb, v; + int halfsum, lowersum; + + /* + ** Find the first splittable box. + */ + for ( bi = 0; bi < boxes; ++bi ) + { + if ( bv[bi].colors >= 2 ) + break; + } + if ( bi == boxes ) + break; /* ran out of colors! */ + + indx = bv[bi].ind; + clrs = bv[bi].colors; + sm = bv[bi].sum; + + /* + ** Go through the box finding the minimum and maximum of each + ** component - the boundaries of the box. + */ + minr = maxr = chv[indx].color.Red; + ming = maxg = chv[indx].color.Green; + minb = maxb = chv[indx].color.Blue; + + for ( i = 1; i < clrs; ++i ) + { + v = chv[indx + i].color.Red; + if ( v < minr ) + minr = v; + if ( v > maxr ) + maxr = v; + v = chv[indx + i].color.Green; + if ( v < ming ) + ming = v; + if ( v > maxg ) + maxg = v; + v = chv[indx + i].color.Blue; + if ( v < minb ) + minb = v; + if ( v > maxb ) + maxb = v; + } + + /* + ** Find the largest dimension, and sort by that component. I have + ** included two methods for determining the "largest" dimension; + ** first by simply comparing the range in RGB space, and second + ** by transforming into luminosities before the comparison. You + ** can switch which method is used by switching the commenting on + ** the LARGE_ defines at the beginning of this source file. + */ +#ifdef LARGE_NORM + if ( maxr - minr >= maxg - ming && maxr - minr >= maxb - minb ) + qsort((char*) &(chv[indx]), clrs, sizeof(struct colorhist_item), redcompare ); + else if ( maxg - ming >= maxb - minb ) + qsort((char*) &(chv[indx]), clrs, sizeof(struct colorhist_item), greencompare ); + else + qsort((char*) &(chv[indx]), clrs, sizeof(struct colorhist_item), bluecompare ); +#endif /*LARGE_NORM*/ + +#ifdef LARGE_LUM + { + struct ARGB p; + float rl, gl, bl; + + p.Red = maxr - minr; + p.Green = 0; + p.Blue = 0; + + rl = PPM_LUMIN(p); + + p.Red = 0; + p.Green = maxg - ming; + p.Blue = 0; + gl = PPM_LUMIN(p); + + p.Red = 0; + p.Green = 0; + p.Blue = maxb - minb; + bl = PPM_LUMIN(p); + + if ( rl >= gl && rl >= bl ) + qsort((char*) &(chv[indx]), clrs, sizeof(struct colorhist_item), redcompare ); + else if ( gl >= bl ) + qsort((char*) &(chv[indx]), clrs, sizeof(struct colorhist_item), greencompare ); + else + qsort((char*) &(chv[indx]), clrs, sizeof(struct colorhist_item), bluecompare ); + } +#endif /*LARGE_LUM*/ + + /* + ** Now find the median based on the counts, so that about half the + ** pixels (not colors, pixels) are in each subdivision. + */ + lowersum = chv[indx].value; + halfsum = sm / 2; + for ( i = 1; i < clrs - 1; ++i ) + { + if ( lowersum >= halfsum ) + break; + lowersum += chv[indx + i].value; + } + + /* + ** Split the box, and sort to bring the biggest boxes to the top. + */ + bv[bi].colors = i; + bv[bi].sum = lowersum; + bv[boxes].ind = indx + i; + bv[boxes].colors = clrs - i; + bv[boxes].sum = sm - lowersum; + ++boxes; + + qsort( (char*) bv, boxes, sizeof(struct box), sumcompare ); + } + + /* + ** Ok, we've got enough boxes. Now choose a representative color for + ** each box. There are a number of possible ways to make this choice. + ** One would be to choose the center of the box; this ignores any structure + ** within the boxes. Another method would be to average all the colors in + ** the box - this is the method specified in Heckbert's paper. A third + ** method is to average all the pixels in the box. You can switch which + ** method is used by switching the commenting on the REP_ defines at + ** the beginning of this source file. + */ + for ( bi = 0; bi < boxes; ++bi ) + { +#ifdef REP_CENTER_BOX + int indx = bv[bi].ind; + int clrs = bv[bi].colors; + int minr, maxr, ming, maxg, minb, maxb, v; + + minr = maxr = chv[indx].color.Red; + ming = maxg = chv[indx].color.Green; + minb = maxb = chv[indx].color.Blue; + for ( i = 1; i < clrs; ++i ) + { + v = chv[indx + i].color.Red; + minr = min( minr, v ); + maxr = max( maxr, v ); + v = chv[indx + i].color.Green; + ming = min( ming, v ); + maxg = max( maxg, v ); + v = chv[indx + i].color.Blue; + minb = min( minb, v ); + maxb = max( maxb, v ); + } + + colormap[bi].color.Red = (minr + maxr) / 2; + colormap[bi].color.Green = (ming + maxg) / 2; + colormap[bi].color.Blue = (minb + maxb) / 2; + +#endif /*REP_CENTER_BOX*/ +#ifdef REP_AVERAGE_COLORS + int indx = bv[bi].ind; + int clrs = bv[bi].colors; + long r = 0, g = 0, b = 0; + + for ( i = 0; i < clrs; ++i ) + { + r += chv[indx + i].color.Red; + g += chv[indx + i].color.Green; + b += chv[indx + i].color.Blue; + } + colormap[bi].color.Red = r / clrs; + colormap[bi].color.Green = g / clrs; + colormap[bi].color.Blue = b / clrs; +#endif /*REP_AVERAGE_COLORS*/ + +#ifdef REP_AVERAGE_PIXELS + int indx = bv[bi].ind; + int clrs = bv[bi].colors; + long r = 0, g = 0, b = 0, sum = 0; + + for ( i = 0; i < clrs; ++i ) + { + r += chv[indx + i].color.Red * chv[indx + i].value; + g += chv[indx + i].color.Green * chv[indx + i].value; + b += chv[indx + i].color.Blue * chv[indx + i].value; + sum += chv[indx + i].value; + } + r = r / sum; + if ( r > maxval ) + r = maxval; /* avoid math errors */ + g = g / sum; + if ( g > maxval ) + g = maxval; + b = b / sum; + if ( b > maxval ) + b = maxval; + + colormap[bi].color.Red = r; + colormap[bi].color.Green = g; + colormap[bi].color.Blue = b; +#endif /*REP_AVERAGE_PIXELS*/ + } + + /* + ** All done. + */ + + ScalosGfxFreeVecPooled(ScalosGfxBase, (char*) bv); //+++ + + return colormap; +} + +static int redcompare(const void *c1, const void *c2) +{ + const struct colorhist_item * ch1 = c1; + const struct colorhist_item * ch2 = c2; + + return (int) (ch1->color.Red - ch2->color.Red); +} + +static int greencompare(const void *c1, const void *c2) +{ + const struct colorhist_item * ch1 = c1; + const struct colorhist_item * ch2 = c2; + + return (int) (ch1->color.Green - ch2->color.Green); +} + +static int bluecompare(const void *c1, const void *c2) +{ + const struct colorhist_item * ch1 = c1; + const struct colorhist_item * ch2 = c2; + + return (int) (ch1->color.Blue - ch2->color.Blue); +} + +static int sumcompare(const void *c1, const void *c2) +{ + const struct box *b1 = c1; + const struct box *b2 = c2; + + return b2->sum - b1->sum; +} + + +static long ppm_hashpixel(const struct ARGB *p) +{ + return (long) ((p->Red * 33023 + p->Green * 30013 + p->Blue * 27011) & 0x7fffffff ) % HASH_SIZE; +} + + +static struct colorhist_item * ppm_computecolorhist(const struct ARGBHeader *argbh, + int maxcolors, int *colorsP, struct ScalosGfxBase *ScalosGfxBase) +{ + struct colorhist_list_item ** cht; + struct colorhist_item * chv; + + cht = ppm_computecolorhash(argbh, maxcolors, colorsP, ScalosGfxBase); + if ( cht == (struct colorhist_list_item **) 0 ) + return (struct colorhist_item *) 0; + + chv = ppm_colorhashtocolorhist( cht, maxcolors, ScalosGfxBase); + ppm_freecolorhash( cht, ScalosGfxBase ); + + return chv; +} + + +static struct colorhist_list_item ** ppm_computecolorhash(const struct ARGBHeader *argbh, + int maxcolors, int *colorsP, struct ScalosGfxBase *ScalosGfxBase) +{ + struct colorhist_list_item ** cht; + struct colorhist_list_item * chl; + int row; + const struct ARGB *argb = argbh->argb_ImageData; + + cht = ppm_alloccolorhash(ScalosGfxBase); + *colorsP = 0; + + /* Go through the entire image, building a hash table of colors. */ + for (row = 0; row < argbh->argb_Height; ++row) + { + int col; + const struct ARGB *pP = argb; + + argb += argbh->argb_Width; + + for (col = 0; col < argbh->argb_Width; ++col, ++pP) + { + int hash; + + hash = ppm_hashpixel(pP); + + for ( chl = cht[hash]; chl != NULL; chl = chl->next ) + { + if ( PPM_EQUAL( chl->ch.color, *pP ) ) + break; + } + + if ( chl != NULL) + ++(chl->ch.value); + else + { + if ( ++(*colorsP) > maxcolors ) + { + ppm_freecolorhash( cht, ScalosGfxBase ); + return NULL; + } + chl = (struct colorhist_list_item *) ScalosGfxAllocVecPooled(ScalosGfxBase, sizeof(struct colorhist_list_item) ); + if ( chl == 0 ) + { + d1(KPrintF(__FILE__ "/" "%s/%ld: out of memory computing hash table\n", __FUNC__, __LINE__)); + return NULL; + } + chl->ch.color = *pP; + chl->ch.value = 1; + chl->next = cht[hash]; + cht[hash] = chl; + } + } + } + + return cht; +} + + +static struct colorhist_list_item ** ppm_alloccolorhash(struct ScalosGfxBase *ScalosGfxBase) +{ + struct colorhist_list_item ** cht; + int i; + + cht = (struct colorhist_list_item **) ScalosGfxAllocVecPooled(ScalosGfxBase, HASH_SIZE * sizeof(struct colorhist_list_item *) ); + if (NULL == cht) + { + d1(KPrintF(__FILE__ "/" "%s/%ld: out of memory allocating hash table\n", __FUNC__, __LINE__)); + return NULL; + } + + for ( i = 0; i < HASH_SIZE; ++i ) + cht[i] = NULL; + + return cht; +} + + +static int ppm_addtocolorhash(struct colorhist_list_item **cht, const struct ARGB *colorP, int value, struct ScalosGfxBase *ScalosGfxBase) +{ + int hash; + struct colorhist_list_item * chl; + + chl = (struct colorhist_list_item *) ScalosGfxAllocVecPooled(ScalosGfxBase, sizeof(struct colorhist_list_item) ); + if (NULL == chl) + return -1; + hash = ppm_hashpixel(colorP); + chl->ch.color = *colorP; + chl->ch.value = value; + chl->next = cht[hash]; + cht[hash] = chl; + + return 0; +} + + +static struct colorhist_item * ppm_colorhashtocolorhist(struct colorhist_list_item ** cht, int maxcolors, struct ScalosGfxBase *ScalosGfxBase) +{ + struct colorhist_item * chv; + struct colorhist_list_item * chl; + int i, j; + + /* Now collate the hash table into a simple colorhist array. */ + chv = (struct colorhist_item *) ScalosGfxAllocVecPooled(ScalosGfxBase, maxcolors * sizeof(struct colorhist_item) ); + /* (Leave room for expansion by caller.) */ + if (NULL == chv) + { + d1(KPrintF(__FILE__ "/" "%s/%ld: out of memory generating histogram\n", __FUNC__, __LINE__)); + return NULL; + } + + /* Loop through the hash table. */ + j = 0; + for ( i = 0; i < HASH_SIZE; ++i ) + { + for ( chl = cht[i]; chl != (struct colorhist_list_item *) 0; chl = chl->next ) + { + /* Add the new entry. */ + chv[j] = chl->ch; + ++j; + } + } + + /* All done. */ + return chv; +} + + +static int ppm_lookupcolor(struct colorhist_list_item ** cht, const struct ARGB *colorP) +{ + int hash; + struct colorhist_list_item * chl; + + hash = ppm_hashpixel(colorP); + + for ( chl = cht[hash]; chl != (struct colorhist_list_item *) 0; chl = chl->next ) + { + if ( PPM_EQUAL( chl->ch.color, *colorP ) ) + return chl->ch.value; + } + + return -1; +} + + +static void ppm_freecolorhist(struct colorhist_item *chv, struct ScalosGfxBase *ScalosGfxBase) +{ + ScalosGfxFreeVecPooled(ScalosGfxBase, (char*) chv ); +} + + +static void ppm_freecolorhash(struct colorhist_list_item **cht, struct ScalosGfxBase *ScalosGfxBase) +{ + int i; + struct colorhist_list_item *chl, *chlnext; + + for ( i = 0; i < HASH_SIZE; ++i ) + { + for ( chl = cht[i]; chl != NULL; chl = chlnext ) + { + chlnext = chl->next; + ScalosGfxFreeVecPooled(ScalosGfxBase, (char*) chl ); + } + } + ScalosGfxFreeVecPooled(ScalosGfxBase, (char*) cht ); +} + + +static void *pm_allocrow(int cols, int size, struct ScalosGfxBase *ScalosGfxBase) +{ + void *itrow; + + itrow = ScalosGfxAllocVecPooled(ScalosGfxBase, cols * size ); + if (NULL == itrow) + d1(KPrintF(__FILE__ "/" "%s/%ld: out of memory allocating a row\n", __FUNC__, __LINE__)); + + return itrow; +} + + +static void pm_freerow(void *itrow, struct ScalosGfxBase *ScalosGfxBase) +{ + ScalosGfxFreeVecPooled(ScalosGfxBase, itrow ); +} + diff --git a/scalos/libraries/scalosgfx/Render.c b/scalos/libraries/scalosgfx/Render.c new file mode 100644 index 000000000..72e2ec9fa --- /dev/null +++ b/scalos/libraries/scalosgfx/Render.c @@ -0,0 +1,1542 @@ +// Render.c +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include + +#include "scalosgfx.h" + +#include + +//----------------------------------------------------------------------- + +#define abs(x) ((x) < 0 ? -(x) : x) + +//----------------------------------------------------------------------- + +static struct ARGB *CreateGradientVertical(LONG Width, LONG Height, struct ARGB Top, + struct ARGB Bottom, struct ScalosGfxBase *ScalosGfxBase); +static struct ARGB *CreateGradientHorizontal(LONG Width, LONG Height, struct ARGB Left, + struct ARGB Right, struct ScalosGfxBase *ScalosGfxBase); +#ifndef __amigaos4__ +static BOOL DrawGradientVerticalRastPort(struct RastPort *rp, LONG xStart, LONG yStart, + LONG Width, LONG Height, struct ARGB Top, struct ARGB Bottom, struct ScalosGfxBase *ScalosGfxBase); +static BOOL DrawGradientHorizontalRastPort(struct RastPort *rp, LONG xStart, LONG yStart, + LONG Width, LONG Height, struct ARGB Left, struct ARGB Right, struct ScalosGfxBase *ScalosGfxBase); +#endif //__amigaos4__ +static BOOL DrawGradientVertical(struct ARGBHeader *argbh, LONG xStart, LONG yStart, + LONG Width, LONG Height, struct ARGB Top, struct ARGB Bottom, struct ScalosGfxBase *ScalosGfxBase); +static BOOL DrawGradientHorizontal(struct ARGBHeader *argbh, LONG xStart, LONG yStart, + LONG Width, LONG Height, struct ARGB Left, struct ARGB Right, struct ScalosGfxBase *ScalosGfxBase); +static void DrawRGBPixelWeighted(struct ARGBHeader *argbh, + WORD x, WORD y, const struct ARGB *color, UBYTE Weight); +static void DrawRGBPixelWeightedRastPort(struct RastPort *rp, + WORD x, WORD y, const struct ARGB *color, UBYTE Weight); + +//----------------------------------------------------------------------- + +BOOL ScaDrawGradient(struct ARGBHeader *dest, LONG left, LONG top, + LONG width, LONG height, struct gfxARGB *start, struct gfxARGB *stop, + ULONG gradType, struct ScalosGfxBase *ScalosGfxBase) +{ + BOOL Success = FALSE; + + (void) ScalosGfxBase; + + if (SCALOS_GRADIENT_VERTICAL == gradType) + { + Success = DrawGradientVertical(dest, left, top, width, height, + *start, *stop, ScalosGfxBase); + } + else if (SCALOS_GRADIENT_HORIZONTAL == gradType) + { + Success = DrawGradientHorizontal(dest, left, top, width, height, + *start, *stop, ScalosGfxBase); + } + + return Success; +} + +//----------------------------------------------------------------------- + +BOOL DrawGradientRastPort(struct RastPort *rp, LONG left, LONG top, + LONG width, LONG height, struct gfxARGB *start, struct gfxARGB *stop, + ULONG gradType, struct ScalosGfxBase *ScalosGfxBase) +{ + BOOL Success = FALSE; + + (void) ScalosGfxBase; + +#ifdef __amigaos4__ + { + struct Screen *pubScreen = NULL; + struct DrawInfo *dri = NULL; + + do { + struct GradientSpec gradSpec; + + memset(&gradSpec, 0, sizeof(gradSpec)); + + if (SCALOS_GRADIENT_VERTICAL == gradType) + gradSpec.Direction = DirectionVector(0); + else if (SCALOS_GRADIENT_HORIZONTAL == gradType) + gradSpec.Direction = DirectionVector(90); + else + break; + + pubScreen = LockPubScreen(NULL); + if (NULL == pubScreen) + break; + + dri = GetScreenDrawInfo(pubScreen); + if (NULL == dri) + break; + + gradSpec.Mode = GRADMODE_COLOR; + gradSpec.Specs.Abs.RGBStart[0] = start->Red; + gradSpec.Specs.Abs.RGBStart[1] = start->Green; + gradSpec.Specs.Abs.RGBStart[2] = start->Blue; + gradSpec.Specs.Abs.RGBEnd[0] = stop->Red; + gradSpec.Specs.Abs.RGBEnd[1] = stop->Green; + gradSpec.Specs.Abs.RGBEnd[2] = stop->Blue; + + Success = DrawGradient(rp, left, top, width, height, NULL, 0, &gradSpec, dri); + } while (0); + + if (dri) + FreeScreenDrawInfo(pubScreen, dri); + if (pubScreen) + UnlockPubScreen(NULL, pubScreen); + } +#else //__amigaos4__ + if (CyberGfxBase->lib_Version >= 50) + { + ULONG paGradType; + + if (SCALOS_GRADIENT_VERTICAL == gradType) + paGradType = GRADTYPE_VERTICAL; + else if (SCALOS_GRADIENT_HORIZONTAL == gradType) + paGradType = GRADTYPE_HORIZONTAL; + else + return FALSE; + + d1(KPrintF("%s/%s/%ld: paGradType=%ld\n", __FILE__, __FUNC__, __LINE__, paGradType)); + + ProcessPixelArrayTags(rp, + left, top, + width, + height, + POP_GRADIENT, + 0, + PPAOPTAG_GRADIENTTYPE, paGradType, + PPAOPTAG_GRADCOLOR1, *((ULONG *) start), + PPAOPTAG_GRADCOLOR2, *((ULONG *) stop), + TAG_END); + + Success = TRUE; + } + else + { + if (SCALOS_GRADIENT_VERTICAL == gradType) + { + Success = DrawGradientVerticalRastPort(rp, left, top, + width, height, *start, *stop, ScalosGfxBase); + } + else if (SCALOS_GRADIENT_HORIZONTAL == gradType) + { + Success = DrawGradientHorizontalRastPort(rp, left, top, + width, height, *start, *stop, ScalosGfxBase); + } + } +#endif //__amigaos4__ + + return Success; +} + +//----------------------------------------------------------------------- + +static struct ARGB *CreateGradientVertical(LONG Width, LONG Height, struct ARGB Top, + struct ARGB Bottom, struct ScalosGfxBase *ScalosGfxBase) +{ + struct ARGB *Source; + LONG DeltaRed, DeltaGreen, DeltaBlue, DeltaAlpha; + LONG StepRed, StepGreen, StepBlue, StepAlpha; + LONG RemRed, RemGreen, RemBlue, RemAlpha; + + d1(KPrintF("%s/%s/%ld: Top Red=%3ld Green=%2ld Blue=%3ld\n", __FILE__, __FUNC__, __LINE__, Top.Red, Top.Green, Top.Blue)); + d1(KPrintF("%s/%s/%ld: Bottom Red=%3ld Green=%2ld Blue=%3ld\n", __FILE__, __FUNC__, __LINE__, Bottom.Red, Bottom.Green, Bottom.Blue)); + + DeltaRed = Bottom.Red - Top.Red; + DeltaGreen = Bottom.Green - Top.Green; + DeltaBlue = Bottom.Blue - Top.Blue; + DeltaAlpha = Bottom.Alpha - Top.Alpha; + + d1(KPrintF("%s/%s/%ld: DeltaRed=%ld DeltaGreen=%ld DeltaBlue=%ld\n", __FILE__, __FUNC__, __LINE__, DeltaRed, DeltaGreen, DeltaBlue)); + + StepRed = DeltaRed / Height; + RemRed = DeltaRed % Height; + + d1(KPrintF("%s/%s/%ld: StepRed=%ld RemRed=%ld\n", __FILE__, __FUNC__, __LINE__, StepRed, RemRed)); + + StepGreen = DeltaGreen / Height; + RemGreen = DeltaGreen % Height; + + d1(KPrintF("%s/%s/%ld: StepGreen=%ld RemGreen=%ld\n", __FILE__, __FUNC__, __LINE__, StepGreen, RemGreen)); + + StepBlue = DeltaBlue / Height; + RemBlue = DeltaBlue % Height; + + d1(KPrintF("%s/%s/%ld: StepBlue=%ld RemBlue=%ld\n", __FILE__, __FUNC__, __LINE__, StepBlue, RemBlue)); + + StepAlpha = DeltaAlpha / Height; + RemAlpha = DeltaAlpha % Height; + + d1(KPrintF("%s/%s/%ld: StepAlpha=%ld RemAlpha=%ld\n", __FILE__, __FUNC__, __LINE__, StepAlpha, RemAlpha)); + + Source = AllocARGB(1, Height, ScalosGfxBase); + if (Source) + { + LONG y; + struct ARGB *pSrc = Source; + LONG AccumulatedDiffRed = 0; + LONG AccumulatedDiffGreen = 0; + LONG AccumulatedDiffBlue = 0; + LONG AccumulatedDiffAlpha = 0; + + // fill Source with RGB Top-to-Bottom gradient + for (y = 0; y < Height; y++) + { + *pSrc = Top; + + Top.Red += StepRed; + AccumulatedDiffRed += RemRed; + if (AccumulatedDiffRed >= Height) + { + Top.Red++; + AccumulatedDiffRed -= Height; + } + else if (AccumulatedDiffRed <= -Height) + { + Top.Red--; + AccumulatedDiffRed += Height; + } + + Top.Green += StepGreen; + AccumulatedDiffGreen += RemGreen; + if (AccumulatedDiffGreen >= Height) + { + Top.Green++; + AccumulatedDiffGreen -= Height; + } + else if (AccumulatedDiffGreen <= -Height) + { + Top.Green--; + AccumulatedDiffGreen += Height; + } + + Top.Blue += StepBlue; + AccumulatedDiffBlue += RemBlue; + if (AccumulatedDiffBlue >= Height) + { + Top.Blue++; + AccumulatedDiffBlue -= Height; + } + else if (AccumulatedDiffBlue <= -Height) + { + Top.Blue--; + AccumulatedDiffBlue += Height; + } + + Top.Alpha += StepAlpha; + AccumulatedDiffAlpha += RemAlpha; + if (AccumulatedDiffAlpha >= Height) + { + Top.Alpha++; + AccumulatedDiffAlpha -= Height; + } + else if (AccumulatedDiffAlpha <= -Height) + { + Top.Alpha--; + AccumulatedDiffAlpha += Height; + } + + pSrc++; + } + d1(KPrintF("%s/%s/%ld: Top Red=%3ld Green=%2ld Blue=%3ld\n", __FILE__, __FUNC__, __LINE__, Top.Red, Top.Green, Top.Blue)); + } + + return Source; +} + +// ---------------------------------------------------------- + +static struct ARGB *CreateGradientHorizontal(LONG Width, LONG Height, struct ARGB Left, + struct ARGB Right, struct ScalosGfxBase *ScalosGfxBase) +{ + struct ARGB *Source; + LONG DeltaRed, DeltaGreen, DeltaBlue, DeltaAlpha; + LONG StepRed, StepGreen, StepBlue, StepAlpha; + LONG RemRed, RemGreen, RemBlue, RemAlpha; + + d1(KPrintF("%s/%s/%ld: Left Red=%3ld Green=%2ld Blue=%3ld\n", __FILE__, __FUNC__, __LINE__, Left.Red, Left.Green, Left.Blue)); + d1(KPrintF("%s/%s/%ld: Right Red=%3ld Green=%2ld Blue=%3ld\n", __FILE__, __FUNC__, __LINE__, Right.Red, Right.Green, Right.Blue)); + + DeltaRed = Right.Red - Left.Red; + DeltaGreen = Right.Green - Left.Green; + DeltaBlue = Right.Blue - Left.Blue; + DeltaAlpha = Right.Alpha - Left.Alpha; + + d1(KPrintF("%s/%s/%ld: DeltaRed=%ld DeltaGreen=%ld DeltaBlue=%ld\n", __FILE__, __FUNC__, __LINE__, DeltaRed, DeltaGreen, DeltaBlue)); + + StepRed = DeltaRed / Width; + RemRed = DeltaRed % Width; + + d1(KPrintF("%s/%s/%ld: StepRed=%ld RemRed=%ld\n", __FILE__, __FUNC__, __LINE__, StepRed, RemRed)); + + StepGreen = DeltaGreen / Width; + RemGreen = DeltaGreen % Width; + + d1(KPrintF("%s/%s/%ld: StepGreen=%ld RemGreen=%ld\n", __FILE__, __FUNC__, __LINE__, StepGreen, RemGreen)); + + StepBlue = DeltaBlue / Width; + RemBlue = DeltaBlue % Width; + + d1(KPrintF("%s/%s/%ld: StepBlue=%ld RemBlue=%ld\n", __FILE__, __FUNC__, __LINE__, StepBlue, RemBlue)); + + StepAlpha = DeltaAlpha / Width; + RemAlpha = DeltaAlpha % Width; + + d1(KPrintF("%s/%s/%ld: StepAlpha=%ld RemAlpha=%ld\n", __FILE__, __FUNC__, __LINE__, StepAlpha, RemAlpha)); + + Source = AllocARGB(Width, 1, ScalosGfxBase); + if (Source) + { + LONG x; + struct ARGB *pSrc = Source; + LONG AccumulatedDiffRed = 0; + LONG AccumulatedDiffGreen = 0; + LONG AccumulatedDiffBlue = 0; + LONG AccumulatedDiffAlpha = 0; + + // fill Source with RGB left-to-right gradient + for (x = 0; x < Width; x++) + { + *pSrc = Left; + + d1(KPrintF("%s/%s/%ld: x=%ld RGB=%ld %ld %ld\n", __FILE__, __FUNC__, __LINE__, x, Left.Red, Left.Green, Left.Blue)); + + Left.Red += StepRed; + AccumulatedDiffRed += RemRed; + if (AccumulatedDiffRed >= Width) + { + Left.Red++; + AccumulatedDiffRed -= Width; + } + else if (AccumulatedDiffRed <= -Width) + { + Left.Red--; + AccumulatedDiffRed += Width; + } + + Left.Green += StepGreen; + AccumulatedDiffGreen += RemGreen; + if (AccumulatedDiffGreen >= Width) + { + Left.Green++; + AccumulatedDiffGreen -= Width; + } + else if (AccumulatedDiffGreen <= -Width) + { + Left.Green--; + AccumulatedDiffGreen += Width; + } + + Left.Blue += StepBlue; + AccumulatedDiffBlue += RemBlue; + if (AccumulatedDiffBlue >= Width) + { + Left.Blue++; + AccumulatedDiffBlue -= Width; + } + else if (AccumulatedDiffBlue <= -Width) + { + Left.Blue--; + AccumulatedDiffBlue += Width; + } + + Left.Alpha += StepAlpha; + AccumulatedDiffAlpha += RemAlpha; + if (AccumulatedDiffAlpha >= Width) + { + Left.Alpha++; + AccumulatedDiffAlpha -= Width; + } + else if (AccumulatedDiffAlpha <= -Width) + { + Left.Alpha--; + AccumulatedDiffAlpha += Width; + } + + pSrc++; + } + d1(KPrintF("%s/%s/%ld: Left Red=%3ld Green=%2ld Blue=%3ld\n", __FILE__, __FUNC__, __LINE__, Left.Red, Left.Green, Left.Blue)); + } + + return Source; +} + +//----------------------------------------------------------------------- + +#ifndef __amigaos4__ +static BOOL DrawGradientVerticalRastPort(struct RastPort *rp, LONG xStart, LONG yStart, + LONG Width, LONG Height, struct ARGB Top, struct ARGB Bottom, struct ScalosGfxBase *ScalosGfxBase) +{ + BOOL Success = FALSE; + + if (CyberGfxBase && GetCyberMapAttr(rp->BitMap, CYBRMATTR_ISCYBERGFX)) + { + struct ARGB *Source; + + Source = CreateGradientVertical(Width, Height, Top, Bottom, ScalosGfxBase); + if (Source) + { + // blit pre-generated gradient column by column into dest bitmap + ULONG x; + + for (x = 0; x < Width; x++) + { + WritePixelArray(Source, + 0, 0, + sizeof(struct ARGB) * 1, + rp, + x + xStart, yStart, + 1, Height, + RECTFMT_ARGB); + } + + FreeARGB(&Source, ScalosGfxBase); + + Success = TRUE; + } + } + + return Success; +} + +// ---------------------------------------------------------- + +static BOOL DrawGradientHorizontalRastPort(struct RastPort *rp, LONG xStart, LONG yStart, + LONG Width, LONG Height, struct ARGB Left, struct ARGB Right, struct ScalosGfxBase *ScalosGfxBase) +{ + BOOL Success = FALSE; + + if (CyberGfxBase && GetCyberMapAttr(rp->BitMap, CYBRMATTR_ISCYBERGFX)) + { + struct ARGB *Source; + + Source = CreateGradientHorizontal(Width, Height, Left, Right, ScalosGfxBase); + if (Source) + { + ULONG y; + + // blit pre-generated gradient line by line into dest bitmap + for (y = 0; y < Height; y++) + { + WritePixelArray(Source, + 0, 0, + sizeof(struct ARGB) * Width, + rp, + xStart, y + yStart, + Width, 1, + RECTFMT_ARGB); + } + + FreeARGB(&Source, ScalosGfxBase); + Success = TRUE; + } + } + + return Success; +} +#endif //__amigaos4__ + +//----------------------------------------------------------------------- + +static BOOL DrawGradientVertical(struct ARGBHeader *argbh, LONG xStart, LONG yStart, + LONG Width, LONG Height, struct ARGB Top, struct ARGB Bottom, struct ScalosGfxBase *ScalosGfxBase) +{ + struct ARGB *Source; + BOOL Success = FALSE; + + Source = CreateGradientVertical(Width, Height, Top, Bottom, ScalosGfxBase); + if (Source) + { + // blit pre-generated gradient column by column into dest + ULONG x; + struct ARGBHeader src; + + src.argb_Width = 1; + src.argb_Height = Height; + src.argb_ImageData = Source; + + for (x = 0; x < Width; x++) + { + BlitARGB(argbh, &src, + x + xStart, yStart, + 0, 0, + 1, Height); + } + + FreeARGB(&Source, ScalosGfxBase); + + Success = TRUE; + } + + return Success; +} + +// ---------------------------------------------------------- + +static BOOL DrawGradientHorizontal(struct ARGBHeader *argbh, LONG xStart, LONG yStart, + LONG Width, LONG Height, struct ARGB Left, struct ARGB Right, struct ScalosGfxBase *ScalosGfxBase) +{ + struct ARGB *Source; + BOOL Success = FALSE; + + Source = CreateGradientHorizontal(Width, Height, Left, Right, ScalosGfxBase); + if (Source) + { + ULONG y; + struct ARGBHeader src; + + src.argb_Width = Width; + src.argb_Height = 1; + src.argb_ImageData = Source; + + // blit pre-generated gradient line by line into dest + for (y = 0; y < Height; y++) + { + BlitARGB(argbh, &src, + xStart, y + yStart, + 0, 0, + Width, 1); + } + + FreeARGB(&Source, ScalosGfxBase); + Success = TRUE; + } + + return Success; +} + +//----------------------------------------------------------------------- + +static void DrawRGBPixelWeighted(struct ARGBHeader *argbh, + WORD x, WORD y, const struct ARGB *color, UBYTE Weight) +{ + struct ARGB *argb = &argbh->argb_ImageData[y * argbh->argb_Width + x]; + struct ARGB b, r; + double grayl, grayb; + + d1(KPrintF("%s/%s/%ld: Weight=%ld\n", __FILE__, __FUNC__, __LINE__, Weight)); + + b = *argb; + + Weight = 255 - Weight; + + grayl = color->Red * 0.299 + color->Green * 0.587 + color->Blue * 0.114, + grayb = b.Red * 0.299 + b.Green * 0.587 + b.Blue * 0.114; + + r.Red = ( b.Red > color->Red ? ( ( UBYTE )( ( ( double )( grayl < grayb ? Weight: + (Weight ^ 255)) ) / 255.0 * ( b.Red - color->Red ) + color->Red ) ) : + ( ( UBYTE )( ( ( double )( graylRed - b.Red ) + b.Red ) ) ); + r.Green = ( b.Green > color->Green ? ( ( UBYTE )( ( ( double )( grayl < grayb ? Weight: + (Weight ^ 255)) ) / 255.0 * ( b.Green - color->Green ) + color->Green ) ) : + ( ( UBYTE )( ( ( double )( grayl < grayb ? Weight : (Weight ^ 255)) ) + / 255.0 * ( color->Green - b.Green ) + b.Green ) ) ); + r.Blue = ( b.Blue > color->Blue ? ( ( UBYTE )( ( ( double )( grayl < grayb ? Weight: + (Weight ^ 255)) ) / 255.0 * ( b.Blue - color->Blue ) + color->Blue ) ) : + ( ( UBYTE )( ( ( double )( grayl Blue - b.Blue ) + b.Blue ) ) ); + r.Alpha = ( b.Alpha > color->Alpha ? ( ( UBYTE )( ( ( double )( grayl < grayb ? Weight: + (Weight ^ 255)) ) / 255.0 * ( b.Alpha - color->Alpha ) + color->Alpha ) ) : + ( ( UBYTE )( ( ( double )( grayl Alpha - b.Alpha ) + b.Alpha ) ) ); + *argb = r; +} + +//----------------------------------------------------------------------- + +// Draw an antialiased ellipse +void DrawARGBEllipse(struct ARGBHeader *argbh, + LONG xc, LONG yc, LONG rx, LONG ry, + WORD Segment, struct ARGB rgbColor1, struct ARGB rgbColor2) +{ + int i; + int a2, b2, ds, dt, dxt, t, s, d; + WORD x, y, xs, ys, dyt, xx, yy, xc2, yc2; + double cp; + UBYTE weight, iweight; + + // Sanity check for 0 radii + if ((rx < 0) || (ry < 0)) + return; + + // Special case for rx=0 - draw a vertical line + if (rx == 0) + { + DrawLine(argbh, xc, yc - ry, xc, yc + ry, rgbColor1); + return; + } + // Special case for ry=0 - draw a horizontal line + if (ry == 0) + { + DrawLine(argbh, xc - rx, yc, xc + rx, yc, rgbColor1); + return; + } + + /* Variable setup */ + a2 = rx * rx; + b2 = ry * ry; + + ds = 2 * a2; + dt = 2 * b2; + + xc2 = 2 * xc; + yc2 = 2 * yc; + + dxt = (int) (a2 / sqrt((double) (a2 + b2))); + + t = 0; + s = -2 * a2 * ry; + d = 0; + + x = xc; + y = yc - ry; + + // counting of ellipse octants: + // 8 1 + // 7 2 + // 6 3 + // 5 4 + + /* Draw */ + + for (i = 1; i <= dxt; i++) + { + x--; + d += t - b2; + + if (d >= 0) + ys = y - 1; + else if ((d - s - a2) > 0) + { + if ((2 * d - s - a2) >= 0) + ys = y + 1; + else + { + ys = y; + y++; + d -= s + a2; + s += ds; + } + } + else + { + y++; + ys = y + 1; + d -= s + a2; + s += ds; + } + + t -= dt; + + /* Calculate alpha */ + if (s != 0.0) + { + cp = (double) abs(d) / (double) abs(s); + if (cp > 1.0) + { + cp = 1.0; + } + } + else + { + cp = 1.0; + } + + /* Calculate weights */ + weight = (UBYTE) (cp * 255); + iweight = 255 - weight; + + /* Upper half */ + xx = xc2 - x; + if (Segment & ELLIPSE_SEGMENT_TOPLEFT) + DrawRGBPixelWeighted(argbh, x, y, &rgbColor2, iweight); // octand 8 + if (Segment & ELLIPSE_SEGMENT_TOPRIGHT) + DrawRGBPixelWeighted(argbh, xx, y, &rgbColor1, iweight); // octand 1 + + if (Segment & ELLIPSE_SEGMENT_TOPLEFT) + DrawRGBPixelWeighted(argbh, x, ys, &rgbColor2, weight); // octand 8 + if (Segment & ELLIPSE_SEGMENT_TOPRIGHT) + DrawRGBPixelWeighted(argbh, xx, ys, &rgbColor1, weight); // octand 1 + + /* Lower half */ + yy = yc2 - y; + if (Segment & ELLIPSE_SEGMENT_BOTTOMLEFT) + DrawRGBPixelWeighted(argbh, x, yy, &rgbColor1, iweight); // octand 5 + if (Segment & ELLIPSE_SEGMENT_BOTTOMRIGHT) + DrawRGBPixelWeighted(argbh, xx, yy, &rgbColor2, iweight); // octand 4 + + yy = yc2 - ys; + if (Segment & ELLIPSE_SEGMENT_BOTTOMLEFT) + DrawRGBPixelWeighted(argbh, x, yy, &rgbColor1, weight); // octand 5 + if (Segment & ELLIPSE_SEGMENT_BOTTOMRIGHT) + DrawRGBPixelWeighted(argbh, xx, yy, &rgbColor2, weight); // octand 4 + } + + dyt = abs(y - yc); + + for (i = 1; i <= dyt; i++) + { + y++; + d -= s + a2; + + if (d <= 0) + xs = x + 1; + else if ((d + t - b2) < 0) + { + if ((2 * d + t - b2) <= 0) + xs = x - 1; + else + { + xs = x; + x--; + d += t - b2; + t -= dt; + } + } + else + { + x--; + xs = x - 1; + d += t - b2; + t -= dt; + } + + s += ds; + + /* Calculate alpha */ + if (t != 0.0) + { + cp = (double) abs(d) / (double) abs(t); + if (cp > 1.0) + { + cp = 1.0; + } + } + else + { + cp = 1.0; + } + + /* Calculate weight */ + weight = (UBYTE) (cp * 255); + iweight = 255 - weight; + + /* Left half */ + yy = yc2 - y; + xx = xc2 - x; + if (Segment & ELLIPSE_SEGMENT_TOPLEFT) + DrawRGBPixelWeighted(argbh, x, y, &rgbColor1, iweight); // octand 7 + if (Segment & ELLIPSE_SEGMENT_TOPRIGHT) + DrawRGBPixelWeighted(argbh, xx, y, &rgbColor2, iweight); // octand 2 + + if (Segment & ELLIPSE_SEGMENT_BOTTOMLEFT) + DrawRGBPixelWeighted(argbh, x, yy, &rgbColor2, iweight); // octand 6 + if (Segment & ELLIPSE_SEGMENT_BOTTOMRIGHT) + DrawRGBPixelWeighted(argbh, xx, yy, &rgbColor1, iweight); // octand 3 + + /* Right half */ + xx = 2 * xc - xs; + if (Segment & ELLIPSE_SEGMENT_TOPLEFT) + DrawRGBPixelWeighted(argbh, xs, y, &rgbColor1, weight); // octand 7 + if (Segment & ELLIPSE_SEGMENT_TOPRIGHT) + DrawRGBPixelWeighted(argbh, xx, y, &rgbColor2, weight); // octand 2? + + if (Segment & ELLIPSE_SEGMENT_BOTTOMLEFT) + DrawRGBPixelWeighted(argbh, xs, yy, &rgbColor2, weight); // octand 6? + if (Segment & ELLIPSE_SEGMENT_BOTTOMRIGHT) + DrawRGBPixelWeighted(argbh, xx, yy, &rgbColor1, weight); // octand 3? + } +} + +//----------------------------------------------------------------------- + +void DrawLine(struct ARGBHeader *argbh, LONG X0, LONG Y0, LONG X1, LONG Y1, struct ARGB Color32) +{ + int XDir, DeltaX, DeltaY; + unsigned short ErrorAdj; + unsigned short ErrorAccTemp, Weighting; + unsigned short ErrorAcc = 0; /* initialize the line error accumulator to 0 */ + struct ARGB l; + double grayl; + + l = Color32; + grayl = Color32.Red * 0.299 + Color32.Green * 0.587 + Color32.Blue * 0.114; + + d1(KPrintF("%s/%s/%ld: r=%ld g=%ld b=%ld Color32=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, l.Blue, l.Green, l.Blue, Color32)); + + /* Make sure the line runs top to bottom */ + if (Y0 > Y1) + { + int Temp = Y0; + + Y0 = Y1; + Y1 = Temp; + Temp = X0; + X0 = X1; + X1 = Temp; + } + + DeltaX = X1 - X0; + DeltaY = Y1 - Y0; + + if( DeltaX >= 0 ) + { + XDir = 1; + } + else + { + XDir = -1; + DeltaX = - DeltaX; /* make DeltaX positive */ + } + + /* Special-case horizontal, vertical, and diagonal lines, which + require no weighting because they go right through the center of + every pixel */ + if (0 == DeltaX) + { + do { + Y0++; + argbh->argb_ImageData[Y0 * argbh->argb_Width + X0] = Color32; + } while (--DeltaY != 0); + return; + } + if (0 == DeltaY) + { + do { + X0 += XDir; + argbh->argb_ImageData[Y0 * argbh->argb_Width + X0] = Color32; + } while (--DeltaX != 0); + return; + } + + /* Draw the initial pixel, which is always exactly intersected by + the line and so needs no weighting */ + argbh->argb_ImageData[Y0 * argbh->argb_Width + X0] = Color32; +#if 0 + if (DeltaX == DeltaY) + { + /* Diagonal line */ + do { + X0 += XDir; + Y0++; + argbh->argb_ImageData[Y0 * argbh->argb_Width + X0] = Color32; + } while (--DeltaY != 0); + return; + } +#endif + + /* Line is not horizontal, diagonal, or vertical */ + + d1(KPrintF("%s/%s/%ld: DeltaX=%ld DeltaY=%ld\n", __FILE__, __FUNC__, __LINE__, DeltaX, DeltaY)); + + /* Is this an X-major or Y-major line? */ + if (DeltaY > DeltaX) + { + /* Y-major line; calculate 16-bit fixed-point fractional part of a + pixel that X advances each time Y advances 1 pixel, truncating the + result so that we won't overrun the endpoint along the X axis */ + + ErrorAdj = ((unsigned long) DeltaX << 16) / (unsigned long) DeltaY; + + /* Draw all pixels other than the first and last */ + while (--DeltaY) + { + struct ARGB b, r; + double grayb; + + ErrorAccTemp = ErrorAcc; /* remember currrent accumulated error */ + ErrorAcc += ErrorAdj; /* calculate error for next pixel */ + if (ErrorAcc <= ErrorAccTemp) + { + /* The error accumulator turned over, so advance the X coord */ + X0 += XDir; + } + Y0++; /* Y-major, so always advance Y */ + /* The IntensityBits most significant bits of ErrorAcc give us the + intensity weighting for this pixel, and the complement of the + weighting for the paired pixel */ + Weighting = ErrorAcc >> 8; + +// ASSERT( Weighting < 256 ); +// ASSERT( ( Weighting ^ 255 ) < 256 ); + + b = argbh->argb_ImageData[Y0 * argbh->argb_Width + X0]; + grayb = b.Red * 0.299 + b.Green * 0.587 + b.Blue * 0.114; + + r.Red = ( b.Red > l.Red ? ( ( UBYTE )( ( ( double )( grayl l.Green ? ( ( UBYTE )( ( ( double )( grayl l.Blue ? ( ( UBYTE )( ( ( double )( grayl l.Alpha ? ( ( UBYTE )( ( ( double )( graylargb_ImageData[Y0 * argbh->argb_Width + X0] = r; + d1(KPrintF("%s/%s/%ld: (x=%ld,Y=%ld) r=%ld g=%ld b=%ld a=%ld\n", __FILE__, __FUNC__, __LINE__, X0, Y0, r.Red, r.Green, r.Blue, r.Alpha)); + + b = argbh->argb_ImageData[Y0 * argbh->argb_Width + X0 + XDir]; + grayb = b.Red * 0.299 + b.Green * 0.587 + b.Blue * 0.114; + + r.Red = ( b.Red > l.Red ? ( ( UBYTE )( ( ( double )( grayl l.Green ? ( ( UBYTE )( ( ( double )( grayl l.Blue ? ( ( UBYTE )( ( ( double )( grayl l.Alpha ? ( ( UBYTE )( ( ( double )( graylargb_ImageData[Y0 * argbh->argb_Width + X0 + XDir] = r; + d1(KPrintF("%s/%s/%ld: (x=%ld,Y=%ld) r=%ld g=%ld b=%ld a=%ld\n", __FILE__, __FUNC__, __LINE__, X0+XDir, Y0, r.Red, r.Green, r.Blue, r.Alpha)); + } + } + else + { + /* It's an X-major line; calculate 16-bit fixed-point fractional part of a + pixel that Y advances each time X advances 1 pixel, truncating the + result to avoid overrunning the endpoint along the X axis */ + + ErrorAdj = ((unsigned long) DeltaY << 16) / (unsigned long) DeltaX; + + /* Draw all pixels other than the first and last */ + + while (--DeltaX) + { + struct ARGB b, r; + double grayb; + + ErrorAccTemp = ErrorAcc; /* remember currrent accumulated error */ + ErrorAcc += ErrorAdj; /* calculate error for next pixel */ + + if (ErrorAcc <= ErrorAccTemp) + { + /* The error accumulator turned over, so advance the Y coord */ + Y0++; + } + + X0 += XDir; /* X-major, so always advance X */ + /* The IntensityBits most significant bits of ErrorAcc give us the + intensity weighting for this pixel, and the complement of the + weighting for the paired pixel */ + + Weighting = ErrorAcc >> 8; + +// ASSERT( Weighting < 256 ); +// ASSERT( ( Weighting ^ 255 ) < 256 ); + + b = argbh->argb_ImageData[Y0 * argbh->argb_Width + X0]; + grayb = b.Red * 0.299 + b.Green * 0.587 + b.Blue * 0.114; + + r.Red = ( b.Red > l.Red ? ( ( UBYTE )( ( ( double )( grayl l.Green ? ( ( UBYTE )( ( ( double )( grayl l.Blue ? ( ( UBYTE )( ( ( double )( grayl l.Alpha ? ( ( UBYTE )( ( ( double )( graylargb_ImageData[Y0 * argbh->argb_Width + X0] = r; + d1(KPrintF("%s/%s/%ld: (x=%ld,Y=%ld) r=%ld g=%ld b=%ld a=%ld\n", __FILE__, __FUNC__, __LINE__, X0, Y0, r.Red, r.Green, r.Blue, r.Alpha)); + + b = argbh->argb_ImageData[(Y0 + 1) * argbh->argb_Width + X0]; + grayb = b.Red * 0.299 + b.Green * 0.587 + b.Blue * 0.114; + + r.Red = ( b.Red > l.Red ? ( ( UBYTE )( ( ( double )( grayl l.Green ? ( ( UBYTE )( ( ( double )( grayl l.Blue ? ( ( UBYTE )( ( ( double )( grayl l.Alpha ? ( ( UBYTE )( ( ( double )( graylargb_ImageData[(Y0 + 1) * argbh->argb_Width + X0] = r; + d1(KPrintF("%s/%s/%ld: (x=%ld,Y=%ld) r=%ld g=%ld b=%ld a=%ld\n", __FILE__, __FUNC__, __LINE__, X0, Y0+1, r.Red, r.Green, r.Blue, r.Alpha)); + } + } + + /* Draw the final pixel, which is always exactly intersected by the line + and so needs no weighting */ + argbh->argb_ImageData[Y1 * argbh->argb_Width + X1] = Color32; +} + +//----------------------------------------------------------------------- + +// Draw an antialiased ellipse into a RastPort +void DrawARGBEllipseRastPort(struct RastPort *rp, + LONG xc, LONG yc, LONG rx, LONG ry, + WORD Segment, struct ARGB rgbColor1, struct ARGB rgbColor2) +{ + int i; + int a2, b2, ds, dt, dxt, t, s, d; + WORD x, y, xs, ys, dyt, xx, yy, xc2, yc2; + double cp; + UBYTE weight, iweight; + + if ((NULL == CyberGfxBase) || !GetCyberMapAttr(rp->BitMap, CYBRMATTR_ISCYBERGFX)) + return; + + // Sanity check for 0 radii + if ((rx < 0) || (ry < 0)) + return; + + // Special case for rx=0 - draw a vertical line + if (rx == 0) + { + //SetAPen(rp, color1); + Move(rp, xc, yc - ry); + Draw(rp, xc, yc + ry); + return; + } + // Special case for ry=0 - draw a horizontal line + if (ry == 0) + { + //SetAPen(rp, color1); + Move(rp, xc - rx, yc); + Draw(rp, xc + rx, yc); + return; + } + + /* Variable setup */ + a2 = rx * rx; + b2 = ry * ry; + + ds = 2 * a2; + dt = 2 * b2; + + xc2 = 2 * xc; + yc2 = 2 * yc; + + dxt = (int) (a2 / sqrt((double) (a2 + b2))); + + t = 0; + s = -2 * a2 * ry; + d = 0; + + x = xc; + y = yc - ry; + + // counting of ellipse octants: + // 8 1 + // 7 2 + // 6 3 + // 5 4 + + /* Draw */ + + for (i = 1; i <= dxt; i++) + { + x--; + d += t - b2; + + if (d >= 0) + ys = y - 1; + else if ((d - s - a2) > 0) + { + if ((2 * d - s - a2) >= 0) + ys = y + 1; + else + { + ys = y; + y++; + d -= s + a2; + s += ds; + } + } + else + { + y++; + ys = y + 1; + d -= s + a2; + s += ds; + } + + t -= dt; + + /* Calculate alpha */ + if (s != 0.0) + { + cp = (double) abs(d) / (double) abs(s); + if (cp > 1.0) + { + cp = 1.0; + } + } + else + { + cp = 1.0; + } + + /* Calculate weights */ + weight = (UBYTE) (cp * 255); + iweight = 255 - weight; + + /* Upper half */ + xx = xc2 - x; + if (Segment & ELLIPSE_SEGMENT_TOPLEFT) + DrawRGBPixelWeightedRastPort(rp, x, y, &rgbColor2, iweight); // octand 8 + if (Segment & ELLIPSE_SEGMENT_TOPRIGHT) + DrawRGBPixelWeightedRastPort(rp, xx, y, &rgbColor1, iweight); // octand 1 + + if (Segment & ELLIPSE_SEGMENT_TOPLEFT) + DrawRGBPixelWeightedRastPort(rp, x, ys, &rgbColor2, weight); // octand 8 + if (Segment & ELLIPSE_SEGMENT_TOPRIGHT) + DrawRGBPixelWeightedRastPort(rp, xx, ys, &rgbColor1, weight); // octand 1 + + /* Lower half */ + yy = yc2 - y; + if (Segment & ELLIPSE_SEGMENT_BOTTOMLEFT) + DrawRGBPixelWeightedRastPort(rp, x, yy, &rgbColor1, iweight); // octand 5 + if (Segment & ELLIPSE_SEGMENT_BOTTOMRIGHT) + DrawRGBPixelWeightedRastPort(rp, xx, yy, &rgbColor2, iweight); // octand 4 + + yy = yc2 - ys; + if (Segment & ELLIPSE_SEGMENT_BOTTOMLEFT) + DrawRGBPixelWeightedRastPort(rp, x, yy, &rgbColor1, weight); // octand 5 + if (Segment & ELLIPSE_SEGMENT_BOTTOMRIGHT) + DrawRGBPixelWeightedRastPort(rp, xx, yy, &rgbColor2, weight); // octand 4 + } + + dyt = abs(y - yc); + + for (i = 1; i <= dyt; i++) + { + y++; + d -= s + a2; + + if (d <= 0) + xs = x + 1; + else if ((d + t - b2) < 0) + { + if ((2 * d + t - b2) <= 0) + xs = x - 1; + else + { + xs = x; + x--; + d += t - b2; + t -= dt; + } + } + else + { + x--; + xs = x - 1; + d += t - b2; + t -= dt; + } + + s += ds; + + /* Calculate alpha */ + if (t != 0.0) + { + cp = (double) abs(d) / (double) abs(t); + if (cp > 1.0) + { + cp = 1.0; + } + } + else + { + cp = 1.0; + } + + /* Calculate weight */ + weight = (UBYTE) (cp * 255); + iweight = 255 - weight; + + /* Left half */ + yy = yc2 - y; + xx = xc2 - x; + if (Segment & ELLIPSE_SEGMENT_TOPLEFT) + DrawRGBPixelWeightedRastPort(rp, x, y, &rgbColor1, iweight); // octand 7 + if (Segment & ELLIPSE_SEGMENT_TOPRIGHT) + DrawRGBPixelWeightedRastPort(rp, xx, y, &rgbColor2, iweight); // octand 2 + + if (Segment & ELLIPSE_SEGMENT_BOTTOMLEFT) + DrawRGBPixelWeightedRastPort(rp, x, yy, &rgbColor2, iweight); // octand 6 + if (Segment & ELLIPSE_SEGMENT_BOTTOMRIGHT) + DrawRGBPixelWeightedRastPort(rp, xx, yy, &rgbColor1, iweight); // octand 3 + + /* Right half */ + xx = 2 * xc - xs; + if (Segment & ELLIPSE_SEGMENT_TOPLEFT) + DrawRGBPixelWeightedRastPort(rp, xs, y, &rgbColor1, weight); // octand 7 + if (Segment & ELLIPSE_SEGMENT_TOPRIGHT) + DrawRGBPixelWeightedRastPort(rp, xx, y, &rgbColor2, weight); // octand 2? + + if (Segment & ELLIPSE_SEGMENT_BOTTOMLEFT) + DrawRGBPixelWeightedRastPort(rp, xs, yy, &rgbColor2, weight); // octand 6? + if (Segment & ELLIPSE_SEGMENT_BOTTOMRIGHT) + DrawRGBPixelWeightedRastPort(rp, xx, yy, &rgbColor1, weight); // octand 3? + } +} + +//----------------------------------------------------------------------- + +#define COMBINE_RGB(r,b,g) (0xff000000 | \ + (((r) & 0xff) << 16) | \ + (((g) & 0xff) << 8) | \ + ((b) & 0xff)) +#define GET_R_BYTE(color) ((UBYTE) ((color) >> 16)) +#define GET_G_BYTE(color) ((UBYTE) ((color) >> 8)) +#define GET_B_BYTE(color) ((UBYTE) (color)) + +// Draw an antialiased line into a RastPort +void DrawLineRastPort(struct RastPort *rp, LONG X0, LONG Y0, LONG X1, LONG Y1, struct ARGB FgColor) +{ + int XDir, DeltaX, DeltaY; + unsigned short ErrorAdj; + unsigned short ErrorAccTemp, Weighting; + unsigned short ErrorAcc = 0; /* initialize the line error accumulator to 0 */ + double grayl; + ULONG Color32; + + if ((NULL == CyberGfxBase) || !GetCyberMapAttr(rp->BitMap, CYBRMATTR_ISCYBERGFX)) + return; + + grayl = FgColor.Red * 0.299 + FgColor.Green * 0.587 + FgColor.Blue * 0.114; + Color32 = COMBINE_RGB(FgColor.Red, FgColor.Green, FgColor.Blue); + + d1(KPrintF("%s/%s/%ld: r=%ld g=%ld b=%ld Color32=%08lx\n", \ + __FILE__, __FUNC__, __LINE__, FgColor.Red, FgColor.Green, FgColor.Blue, Color32)); + + /* Make sure the line runs top to bottom */ + if (Y0 > Y1) + { + int Temp = Y0; + + Y0 = Y1; + Y1 = Temp; + Temp = X0; + X0 = X1; + X1 = Temp; + } + + DeltaX = X1 - X0; + DeltaY = Y1 - Y0; + + if( DeltaX >= 0 ) + { + XDir = 1; + } + else + { + XDir = -1; + DeltaX = - DeltaX; /* make DeltaX positive */ + } + + /* Special-case horizontal, vertical, and diagonal lines, which + require no weighting because they go right through the center of + every pixel */ + if (DeltaY == 0 || DeltaX == 0) + { + Move(rp, X0, Y0); + Draw(rp, X1, Y1); + return; + } + + /* Draw the initial pixel, which is always exactly intersected by + the line and so needs no weighting */ + WriteRGBPixel(rp, X0, Y0, Color32); +#if 0 + if (DeltaX == DeltaY) + { + /* Diagonal line */ + do { + X0 += XDir; + Y0++; + WriteRGBPixel(rp, X0, Y0, Color32); + } while (--DeltaY != 0); + return; + } +#endif + + /* Line is not horizontal, diagonal, or vertical */ + + + /* Is this an X-major or Y-major line? */ + if (DeltaY > DeltaX) + { + /* Y-major line; calculate 16-bit fixed-point fractional part of a + pixel that X advances each time Y advances 1 pixel, truncating the + result so that we won't overrun the endpoint along the X axis */ + + ErrorAdj = ((unsigned long) DeltaX << 16) / (unsigned long) DeltaY; + + /* Draw all pixels other than the first and last */ + while (--DeltaY) + { + ULONG clrBackGround; + UBYTE rb, gb, bb; + UBYTE rr, gr, br; + double grayb; + + ErrorAccTemp = ErrorAcc; /* remember currrent accumulated error */ + ErrorAcc += ErrorAdj; /* calculate error for next pixel */ + if (ErrorAcc <= ErrorAccTemp) + { + /* The error accumulator turned over, so advance the X coord */ + X0 += XDir; + } + Y0++; /* Y-major, so always advance Y */ + /* The IntensityBits most significant bits of ErrorAcc give us the + intensity weighting for this pixel, and the complement of the + weighting for the paired pixel */ + Weighting = ErrorAcc >> 8; + +// ASSERT( Weighting < 256 ); +// ASSERT( ( Weighting ^ 255 ) < 256 ); + + clrBackGround = ReadRGBPixel(rp, X0, Y0); + rb = GET_R_BYTE(clrBackGround); + gb = GET_G_BYTE(clrBackGround); + bb = GET_B_BYTE(clrBackGround); + grayb = rb * 0.299 + gb * 0.587 + bb * 0.114; + + rr = ( rb > FgColor.Red ? ( ( UBYTE )( ( ( double )( grayl FgColor.Green ? ( ( UBYTE )( ( ( double )( grayl FgColor.Blue ? ( ( UBYTE )( ( ( double )( grayl FgColor.Red ? ( ( UBYTE )( ( ( double )( grayl FgColor.Green ? ( ( UBYTE )( ( ( double )( grayl FgColor.Blue ? ( ( UBYTE )( ( ( double )( grayl> 8; + + // ASSERT( Weighting < 256 ); + // ASSERT( ( Weighting ^ 255 ) < 256 ); + + clrBackGround = ReadRGBPixel(rp, X0, Y0); + rb = GET_R_BYTE(clrBackGround); + gb = GET_G_BYTE(clrBackGround); + bb = GET_B_BYTE(clrBackGround); + grayb = rb * 0.299 + gb * 0.587 + bb * 0.114; + + rr = ( rb > FgColor.Red ? ( ( UBYTE )( ( ( double )( grayl FgColor.Green ? ( ( UBYTE )( ( ( double )( grayl FgColor.Blue ? ( ( UBYTE )( ( ( double )( grayl FgColor.Red ? ( ( UBYTE )( ( ( double )( grayl FgColor.Green ? ( ( UBYTE )( ( ( double )( grayl FgColor.Blue ? ( ( UBYTE )( ( ( double )( graylRed * 0.299 + color->Green * 0.587 + color->Blue * 0.114, + grayb = rb * 0.299 + gb * 0.587 + bb * 0.114; + + rr = ( rb > color->Red ? ( ( UBYTE )( ( ( double )( grayl < grayb ? Weight: + (Weight ^ 255)) ) / 255.0 * ( rb - color->Red ) + color->Red ) ) : + ( ( UBYTE )( ( ( double )( graylRed - rb ) + rb ) ) ); + gr = ( gb > color->Green ? ( ( UBYTE )( ( ( double )( grayl < grayb ? Weight: + (Weight ^ 255)) ) / 255.0 * ( gb - color->Green ) + color->Green ) ) : + ( ( UBYTE )( ( ( double )( grayl < grayb ? Weight : (Weight ^ 255)) ) + / 255.0 * ( color->Green - gb ) + gb ) ) ); + br = ( bb > color->Blue ? ( ( UBYTE )( ( ( double )( grayl < grayb ? Weight: + (Weight ^ 255)) ) / 255.0 * ( bb - color->Blue ) + color->Blue ) ) : + ( ( UBYTE )( ( ( double )( grayl Blue - bb ) + bb ) ) ); + + WriteRGBPixel(rp, x, y, COMBINE_RGB(rr, gr, br)); +} + +//----------------------------------------------------------------------- + diff --git a/scalos/libraries/scalosgfx/argb.c b/scalos/libraries/scalosgfx/argb.c new file mode 100644 index 000000000..af8fbba94 --- /dev/null +++ b/scalos/libraries/scalosgfx/argb.c @@ -0,0 +1,872 @@ +// argb.c +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#include +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include + +#include "scalosgfx.h" + +//----------------------------------------------------------------------- + +//----------------------------------------------------------------------- + +static ULONG FindBestPen(const ULONG *ColorTable, ULONG NumColors, ULONG Red, ULONG Green, LONG Blue); +static long GetColorDistance(const ULONG *ColorTableEntry, ULONG Red, ULONG Green, ULONG Blue); + +//----------------------------------------------------------------------- + +void ARGBSetAlpha(struct ARGB *argb, ULONG Width, ULONG Height, UBYTE Alpha) +{ + ULONG y; + + d1(KPrintF("%s/%ld: argb=%08lx Width=%lu Height=%lu Alpha=%lu\n", \ + __FUNC__, __LINE__, argb, Width, Height, Alpha)); + + for (y = 0; y < Height; y++) + { + ULONG x; + + for (x = 0; x < Width; x++) + { + argb->Alpha = Alpha; + argb++; + } + } +} + +//----------------------------------------------------------------------- + +void ARGBSetAlphaFromMask(struct ARGBHeader *argbh, PLANEPTR MaskPlane) +{ + ULONG y; + ULONG MaskBytesPerRow = ((argbh->argb_Width + 15) & ~0x0f) / 8; + struct ARGB *pargb = argbh->argb_ImageData; + + for (y = 0; y < argbh->argb_Height; y++) + { + ULONG x; + + UWORD BitMask = 0x0080; + const UBYTE *MaskPtr2 = MaskPlane; + + for (x = 0; x < argbh->argb_Width; x++, pargb++) + { + if (*MaskPtr2 & BitMask) + pargb->Alpha = 0xff; + else + pargb->Alpha = 0; + + BitMask >>= 1; + if (0 == BitMask) + { + BitMask = 0x0080; + MaskPtr2++; + } + } + + MaskPlane += MaskBytesPerRow; + } +} + +//----------------------------------------------------------------------- + +struct ARGB *CreateARGBFromBitMap(struct BitMap *bm, + ULONG Width, ULONG Height, + ULONG NumberOfColors, const ULONG *ColorTable, PLANEPTR MaskPlane, + struct ScalosGfxBase *ScalosGfxBase) +{ + struct ARGB *argb; + UBYTE *LineArray = NULL; + struct BitMap *TempBM = NULL; + + do { + struct RastPort rp; + ULONG Depth; + ULONG MaskBytesPerRow = ((Width + 15) & ~0x0f) / 8; + + d1(KPrintF("%s/%ld: MaskPlane=%08lx MaskBytesPerRow=%lu\n", __FUNC__, __LINE__, MaskPlane, MaskBytesPerRow)); + + argb = AllocARGB(Width, Height, ScalosGfxBase); + if (NULL == argb) + break; + + Depth = GetBitMapAttr(bm, BMA_DEPTH); + + InitRastPort(&rp); + rp.BitMap = bm; + + if (Depth <= 8 || (NULL == CyberGfxBase)) + { + struct RastPort TempRp; + ULONG y; + struct ARGB *pargb = argb; + size_t ArraySize = (((Width + 15) >> 4) << 4); + + LineArray = ScalosGfxAllocVecPooled(ScalosGfxBase, ArraySize); + if (NULL == LineArray) + break; + + InitRastPort(&TempRp); + TempRp = rp; + TempRp.Layer = NULL; + TempRp.BitMap = TempBM = AllocBitMap(TEMPRP_WIDTH(Width), 1, 8, 0, NULL); + if (NULL == TempBM) + break; + + for (y = 0; y < Height; y++) + { + ULONG x; + UBYTE *pLine = LineArray; + + ReadPixelLine8(&rp, + 0, y, + Width, + LineArray, + &TempRp); + + if (MaskPlane) + { + UWORD BitMask = 0x0080; + const UBYTE *MaskPtr2 = MaskPlane; + + for (x = 0; x < Width; x++, pargb++) + { + UBYTE col = *pLine++; + const ULONG *ColorReg = ColorTable + 3 * col; + + pargb->Red = ColorReg[0] >> 24; + pargb->Green = ColorReg[1] >> 24; + pargb->Blue = ColorReg[2] >> 24; + + if (*MaskPtr2 & BitMask) + pargb->Alpha = 0xff; + else + pargb->Alpha = 0; + + BitMask >>= 1; + if (0 == BitMask) + { + BitMask = 0x0080; + MaskPtr2++; + } + } + + MaskPlane += MaskBytesPerRow; + } + else + { + for (x = 0; x < Width; x++, pargb++) + { + UBYTE col = *pLine++; + const ULONG *ColorReg = ColorTable + 3 * col; + + pargb->Alpha = 0xff; + pargb->Red = ColorReg[0] >> 24; + pargb->Green = ColorReg[1] >> 24; + pargb->Blue = ColorReg[2] >> 24; + } + } + } + } + else + { + ReadPixelArray(argb, 0, 0, + Width * sizeof(struct ARGB), + &rp, 0, 0, + Width, Height, + RECTFMT_ARGB); + if (MaskPlane) + { + struct ARGBHeader argbh; + + argbh.argb_Width = Width; + argbh.argb_Height = Height; + argbh.argb_ImageData = argb; + + d1(KPrintF("%s/%ld: MaskPlane=%08lx\n", __FUNC__, __LINE__, MaskPlane)); + + ARGBSetAlphaFromMask(&argbh, MaskPlane); + } + else + { + ARGBSetAlpha(argb, Width, Height, (UBYTE) ~0); + } + } + } while (0); + + if (TempBM) + FreeBitMap(TempBM); + if (LineArray) + ScalosGfxFreeVecPooled(ScalosGfxBase, LineArray); + + return argb; +} + +//----------------------------------------------------------------------- + +void WriteARGBToBitMap(struct ARGB *argb, struct BitMap *bm, + ULONG Width, ULONG Height, + ULONG NumberOfColors, const ULONG *ColorTable, + struct ScalosGfxBase *ScalosGfxBase) +{ + ULONG Depth; + struct RastPort rp; + UBYTE *LineArray = NULL; + struct BitMap *TempBM = NULL; + + do { + InitRastPort(&rp); + rp.BitMap = bm; + + Depth = GetBitMapAttr(bm, BMA_DEPTH); + + d1(KPrintF("%s/%ld: DestWidth=%lu DestHeight=%ld\n", __FUNC__, __LINE__, Width, Height)); + + if ((NULL == CyberGfxBase) || (Depth <= 8) || !GetCyberMapAttr(bm, CYBRMATTR_ISCYBERGFX)) + { + struct RastPort TempRp; + ULONG y; + struct ARGB *pargb = argb; + size_t ArraySize = (((Width + 15) >> 4) << 4); + + d1(KPrintF("%s/%ld: DestWidth=%lu DestHeight=%ld\n", __FUNC__, __LINE__, Width, Height)); + + LineArray = ScalosGfxAllocVecPooled(ScalosGfxBase, ArraySize); + if (NULL == LineArray) + break; + + InitRastPort(&TempRp); + TempRp = rp; + TempRp.Layer = NULL; + TempRp.BitMap = TempBM = AllocBitMap(TEMPRP_WIDTH(Width), 1, 8, 0, NULL); + if (NULL == TempBM) + break; + + for (y = 0; y < Height; y++) + { + ULONG x; + UBYTE *pLine = LineArray; + + for (x = 0; x < Width; x++) + { + *pLine++ = FindBestPen(ColorTable, NumberOfColors, + pargb->Red << 24, + pargb->Green << 24, + pargb->Blue << 24); + pargb++; + } + + WritePixelLine8(&rp, + 0, y, + Width, + LineArray, + &TempRp); + } + } + else + { + WritePixelArray(argb, 0, 0, + Width * sizeof(struct ARGB), + &rp, 0, 0, + Width, Height, + RECTFMT_ARGB); + } + } while (0); + + if (TempBM) + FreeBitMap(TempBM); + if (LineArray) + ScalosGfxFreeVecPooled(ScalosGfxBase, LineArray); +} + +//----------------------------------------------------------------------- + +void FreeARGB(struct ARGB **argb, struct ScalosGfxBase *ScalosGfxBase) +{ + if (*argb) + { + WaitBlit(); + d1(KPrintF("%s/%ld: argb=%08lx\n", __FUNC__, __LINE__, *argb)); + ScalosGfxFreeVecPooled(ScalosGfxBase, *argb); + *argb = NULL; + } +} + +//----------------------------------------------------------------------- + +struct ARGB *AllocARGB(ULONG Width, ULONG Height, struct ScalosGfxBase *ScalosGfxBase) +{ + struct ARGB *argb; + + if (0 == Width || 0 == Height) + return NULL; + + argb = ScalosGfxAllocVecPooled(ScalosGfxBase, Width * Height * sizeof(struct ARGB)); + d1(KPrintF("%s/%ld: ARGB=%08lx Width=%lu Height=%ld\n", __FUNC__, __LINE__, argb, Width, Height)); + + return argb; +} + +//----------------------------------------------------------------------- + +void FillARGBFromBitMap(struct ARGBHeader *argbh, struct BitMap *srcBM, + PLANEPTR MaskPlane) +{ + ULONG PixFmt; + ULONG BytesPerRow; + ULONG BytesPerPixel; + const UBYTE *src; + struct ARGB *dest; + APTR handle; + + if ((NULL == CyberGfxBase) || !GetCyberMapAttr(srcBM, CYBRMATTR_ISCYBERGFX)) + return; + + d1(KPrintF("%s/%ld: Width=%ld Height=%ld\n", __FUNC__, __LINE__, argbh->argb_Width, argbh->argb_Height)); + + handle = LockBitMapTags(srcBM, + LBMI_PIXFMT, (ULONG) &PixFmt, + LBMI_BASEADDRESS, (ULONG) &src, + LBMI_BYTESPERROW, (ULONG) &BytesPerRow, + LBMI_BYTESPERPIX, (ULONG) &BytesPerPixel, + TAG_END); + + d1(KPrintF(__FILE__ "/%s/%ld: handle=%08lx\n", __FUNC__, __LINE__, handle)); + if (handle) + { + ULONG y; + + d1(KPrintF("%s/%ld: src=%08lx\n", __FUNC__, __LINE__, src)); + d1(KPrintF("%s/%ld: PixFmt=%ld BytesPerRow=%ld\n", __FUNC__, __LINE__, PixFmt, BytesPerRow)); + + dest = argbh->argb_ImageData; + + switch (PixFmt) + { + case PIXFMT_BGR24: + for (y = 0; y < argbh->argb_Height; y++) + { + ULONG x; + const UBYTE *srcPtr = src; + + for (x = 0; x < argbh->argb_Width; x++) + { + dest->Blue = srcPtr[0]; + dest->Green = srcPtr[1]; + dest->Red = srcPtr[2]; + dest->Alpha = (UBYTE) ~0; + + dest++; + srcPtr += BytesPerPixel; + } + + src += BytesPerRow; + } + break; + case PIXFMT_BGRA32: + for (y = 0; y < argbh->argb_Height; y++) + { + ULONG x; + const UBYTE *srcPtr = src; + + for (x = 0; x < argbh->argb_Width; x++) + { + dest->Blue = srcPtr[0]; + dest->Green = srcPtr[1]; + dest->Red = srcPtr[2]; + dest->Alpha = srcPtr[3]; + + dest++; + srcPtr += BytesPerPixel; + } + + src += BytesPerRow; + } + break; + + case PIXFMT_RGB24: + for (y = 0; y < argbh->argb_Height; y++) + { + ULONG x; + const UBYTE *srcPtr = src; + + for (x = 0; x < argbh->argb_Width; x++) + { + dest->Red = srcPtr[0]; + dest->Green = srcPtr[1]; + dest->Blue = srcPtr[2]; + dest->Alpha = (UBYTE) ~0; + + dest++; + srcPtr += BytesPerPixel; + } + + src += BytesPerRow; + } + break; + case PIXFMT_RGBA32: + for (y = 0; y < argbh->argb_Height; y++) + { + ULONG x; + const UBYTE *srcPtr = src; + + for (x = 0; x < argbh->argb_Width; x++) + { + dest->Red = srcPtr[0]; + dest->Green = srcPtr[1]; + dest->Blue = srcPtr[2]; + dest->Alpha = srcPtr[3]; + + dest++; + srcPtr += BytesPerPixel; + } + + src += BytesPerRow; + } + break; + + case PIXFMT_ARGB32: + for (y = 0; y < argbh->argb_Height; y++) + { + ULONG x; + const UBYTE *srcPtr = src; + + for (x = 0; x < argbh->argb_Width; x++) + { + dest->Red = srcPtr[1]; + dest->Green = srcPtr[2]; + dest->Blue = srcPtr[3]; + dest->Alpha = srcPtr[0]; + + dest++; + srcPtr += BytesPerPixel; + } + + src += BytesPerRow; + } + break; + + case PIXFMT_RGB16: + for (y = 0; y < argbh->argb_Height; y++) + { + ULONG x; + const UWORD *srcPtr = (UWORD *) src; + + for (x = 0; x < argbh->argb_Width; x++) + { + dest->Red = GET_RED_RGB16(srcPtr); + dest->Green = GET_GREEN_RGB16(srcPtr); + dest->Blue = GET_BLUE_RGB16(srcPtr); + dest->Alpha = (UBYTE) ~0; + + srcPtr++; + dest++; + } + + src += BytesPerRow; + } + break; + + case PIXFMT_BGR16: + for (y = 0; y < argbh->argb_Height; y++) + { + ULONG x; + const UWORD *srcPtr = (UWORD *) src; + + for (x = 0; x < argbh->argb_Width; x++) + { + dest->Red = GET_RED_BGR16(srcPtr); + dest->Green = GET_GREEN_BGR16(srcPtr); + dest->Blue = GET_BLUE_BGR16(srcPtr); + dest->Alpha = (UBYTE) ~0; + srcPtr++; + dest++; + } + + src += BytesPerRow; + } + break; + + case PIXFMT_RGB15: + for (y = 0; y < argbh->argb_Height; y++) + { + ULONG x; + const UWORD *srcPtr = (UWORD *) src; + + for (x = 0; x < argbh->argb_Width; x++) + { + dest->Red = GET_RED_RGB15(srcPtr); + dest->Green = GET_GREEN_RGB15(srcPtr); + dest->Blue = GET_BLUE_RGB15(srcPtr); + dest->Alpha = (UBYTE) ~0; + srcPtr++; + dest++; + } + + src += BytesPerRow; + } + break; + + case PIXFMT_BGR15: + for (y = 0; y < argbh->argb_Height; y++) + { + ULONG x; + const UWORD *srcPtr = (UWORD *) src; + + for (x = 0; x < argbh->argb_Width; x++) + { + dest->Red = GET_RED_BGR15(srcPtr); + dest->Green = GET_GREEN_BGR15(srcPtr); + dest->Blue = GET_BLUE_BGR15(srcPtr); + dest->Alpha = (UBYTE) ~0; + srcPtr++; + dest++; + } + + src += BytesPerRow; + } + break; + + case PIXFMT_RGB16PC: + for (y = 0; y < argbh->argb_Height; y++) + { + ULONG x; + const UWORD *srcPtr = (UWORD *) src; + + for (x = 0; x < argbh->argb_Width; x++) + { + dest->Red = GET_RED_RGB16PC(srcPtr); + dest->Green = GET_GREEN_RGB16PC(srcPtr); + dest->Blue = GET_BLUE_RGB16PC(srcPtr); + dest->Alpha = (UBYTE) ~0; + srcPtr++; + dest++; + } + + src += BytesPerRow; + } + break; + + case PIXFMT_BGR16PC: + for (y = 0; y < argbh->argb_Height; y++) + { + ULONG x; + const UWORD *srcPtr = (UWORD *) src; + + for (x = 0; x < argbh->argb_Width; x++) + { + dest->Red = GET_RED_BGR16PC(srcPtr); + dest->Green = GET_GREEN_BGR16PC(srcPtr); + dest->Blue = GET_BLUE_BGR16PC(srcPtr); + dest->Alpha = (UBYTE) ~0; + srcPtr++; + dest++; + } + + src += BytesPerRow; + } + break; + + case PIXFMT_RGB15PC: + for (y = 0; y < argbh->argb_Height; y++) + { + ULONG x; + const UWORD *srcPtr = (UWORD *) src; + + for (x = 0; x < argbh->argb_Width; x++) + { + dest->Red = GET_RED_RGB15PC(srcPtr); + dest->Green = GET_GREEN_RGB15PC(srcPtr); + dest->Blue = GET_BLUE_RGB15PC(srcPtr); + dest->Alpha = (UBYTE) ~0; + srcPtr++; + dest++; + } + + src += BytesPerRow; + } + break; + + case PIXFMT_BGR15PC: + d1(KPrintF("%s/%ld: src=%08lx\n", __FUNC__, __LINE__, src)); + + dest = argbh->argb_ImageData; + + for (y = 0; y < argbh->argb_Height; y++) + { + ULONG x; + const UWORD *srcPtr = (UWORD *) src; + + for (x = 0; x < argbh->argb_Width; x++) + { + dest->Red = GET_RED_BGR15PC(srcPtr); + dest->Green = GET_GREEN_BGR15PC(srcPtr); + dest->Blue = GET_BLUE_BGR15PC(srcPtr); + dest->Alpha = (UBYTE) ~0; + srcPtr++; + dest++; + } + + src += BytesPerRow; + } + break; + + default: + break; + } + + UnLockBitMap(handle); + if (MaskPlane) + ARGBSetAlphaFromMask(argbh, MaskPlane); + } + else + { + kprintf(__FILE__ "/%s/%ld: Can't lock bitmap\n", __FUNC__, __LINE__); + } +} + +//----------------------------------------------------------------------- + +static ULONG FindBestPen(const ULONG *ColorTable, ULONG NumColors, ULONG Red, ULONG Green, LONG Blue) +{ + ULONG BestPen = 0; + long BestDistance = LONG_MAX; + ULONG n; + + for (n = 0; n < NumColors; n++) + { + long ColorDistance = GetColorDistance(ColorTable, Red, Green, Blue); + + d1(KPrintF("%s/%ld: R=%08lx G=%08lx b=%08lx Best=%ld Dist=%ld\n", \ + __LINE__, ColorTable[0], ColorTable[1], ColorTable[2], BestDistance, ColorDistance)); + + if (ColorDistance < BestDistance) + { + BestDistance = ColorDistance; + BestPen = n; + } + + ColorTable += 3; + } + + d1(KPrintF("%s/%ld: R=%08lx G=%08lx B=%08lx NumColors=%lu BestPen=%lu\n", \ + __LINE__, Red, Green, Blue, NumColors, BestPen)); + + return BestPen; +} + +//----------------------------------------------------------------------- + +static long GetColorDistance(const ULONG *ColorTableEntry, ULONG Red, ULONG Green, ULONG Blue) +{ + LONG dRed,dGreen,dBlue; + + dRed = (LONG) (Red >> 24) - (LONG) (ColorTableEntry[0] >> 24); + dGreen = (LONG) (Green >> 24) - (LONG) (ColorTableEntry[1] >> 24); + dBlue = (LONG) (Blue >> 24) - (LONG) (ColorTableEntry[2] >> 24); + + return dRed * dRed + dGreen * dGreen +dBlue * dBlue; +} + +//----------------------------------------------------------------------- + +struct ScalosBitMapAndColor *AllocEmptySAC(struct ScalosGfxBase *ScalosGfxBase) +{ + struct ScalosBitMapAndColor *sac; + + sac = ScalosGfxAllocVecPooled(ScalosGfxBase, sizeof(struct ScalosBitMapAndColor)); + if (sac) + memset(sac, 0, sizeof(struct ScalosBitMapAndColor)); + + d1(KPrintF(__FILE__ "/%s/%ld: END sac=%08lx\n", __FUNC__, __LINE__, sac)); + + return sac; +} + +//----------------------------------------------------------------------- + +struct ScalosBitMapAndColor *AllocSAC(ULONG Width, ULONG Height, ULONG Depth, + struct BitMap *FriendBM, struct TagItem *TagList, + struct ScalosGfxBase *ScalosGfxBase) +{ + struct ScalosBitMapAndColor *sac = NULL; + BOOL Success = FALSE; + + (void) TagList; + + d1(KPrintF(__FILE__ "/%s/%ld: START Width=%lu Heioght=%lu Depth=%lu FriendBM=%08lx\n", \ + __FUNC__, __LINE__, Width, Height, Depth, FriendBM)); + + do { + if (Depth < 1 || Depth > 8) + break; + if (Width < 1 || Height < 1) + break; + + sac = AllocEmptySAC(ScalosGfxBase); + if (NULL == sac) + break; + + sac->sac_Width = Width; + sac->sac_Height = Height; + sac->sac_Depth = Depth; + + sac->sac_BitMap = AllocBitMap(Width, Height, 8, BMF_CLEAR, FriendBM); + d1(KPrintF(__FILE__ "/%s/%ld: sac_BitMap=%08lx\n", __FUNC__, __LINE__, sac->sac_BitMap)); + if (NULL == sac->sac_BitMap) + break; + + sac->sac_NumColors = 1 << Depth; + + sac->sac_ColorTable = ScalosGfxAllocVecPooled(ScalosGfxBase, SAC_COLORTABLESIZE(sac)); + d1(KPrintF(__FILE__ "/%s/%ld: sac_ColorTable=%08lx\n", __FUNC__, __LINE__, sac->sac_ColorTable)); + if (NULL == sac->sac_ColorTable) + break; + + Success = TRUE; + } while (0); + + if (!Success) + { + FreeSAC(sac, ScalosGfxBase); + sac = NULL; + } + + d1(KPrintF(__FILE__ "/%s/%ld: END sac=%08lx\n", __FUNC__, __LINE__, sac)); + return sac; +} + +//----------------------------------------------------------------------- + +void FreeSAC(struct ScalosBitMapAndColor *sac, struct ScalosGfxBase *ScalosGfxBase) +{ + d1(KPrintF(__FILE__ "/%s/%ld: START sac=%08lx\n", __FUNC__, __LINE__, sac)); + if (sac) + { + d1(KPrintF(__FILE__ "/%s/%ld: sac_ColorTable=%08lx\n", __FUNC__, __LINE__, sac->sac_ColorTable)); + if (sac->sac_ColorTable) + { + if (!(sac->sac_Flags & SACFLAGF_NO_FREE_COLORTABLE)) + ScalosGfxFreeVecPooled(ScalosGfxBase, sac->sac_ColorTable); + sac->sac_ColorTable = NULL; + } + d1(KPrintF(__FILE__ "/%s/%ld: sac_Flags=%08lx sac_BitMap=%08lx\n", __FUNC__, __LINE__, sac->sac_Flags, sac->sac_BitMap)); + if (sac->sac_BitMap) + { + if (!(sac->sac_Flags & SACFLAGF_NO_FREE_BITMAP)) + FreeBitMap(sac->sac_BitMap); + sac->sac_BitMap = NULL; + } + ScalosGfxFreeVecPooled(ScalosGfxBase, sac); + } + d1(KPrintF(__FILE__ "/%s/%ld: END\n", __FUNC__, __LINE__)); +} + +//----------------------------------------------------------------------- + +void BlitARGB(struct ARGBHeader *DestARGB, const struct ARGBHeader *SrcARGB, + LONG DestLeft, LONG DestTop, LONG SrcLeft, LONG SrcTop, + LONG Width, LONG Height) +{ + struct ARGB *dest = DestARGB->argb_ImageData + DestTop * DestARGB->argb_Width; + const struct ARGB *src = SrcARGB->argb_ImageData + SrcTop * SrcARGB->argb_Width; + LONG y; + + for (y = 0; y < Height; y++) + { + memcpy(dest + DestLeft, src + SrcLeft, Width * sizeof(struct ARGB)); + dest += DestARGB->argb_Width; + src += SrcARGB->argb_Width; + } +} + +//----------------------------------------------------------------------- + +void FillARGB(struct ARGBHeader *DestARGB, const struct ARGB *fillARGB, + LONG left, LONG top, LONG width, LONG height) +{ + struct ARGB *dest = DestARGB->argb_ImageData + top * DestARGB->argb_Width; + LONG y; + + for (y = 0; y < height; y++) + { + LONG x; + struct ARGB *destRow = dest + left; + + for (x = 0; x < width; x++) + *destRow++ = *fillARGB; + + dest += DestARGB->argb_Width; + } +} + +//----------------------------------------------------------------------- + +void SetARGB(struct ARGBHeader *DestARGB, const struct ARGB *fillARGB) +{ + struct ARGB *dest = DestARGB->argb_ImageData; + size_t Length = DestARGB->argb_Width * DestARGB->argb_Height; + + while (Length--) + *dest++ = *fillARGB; +} + +//----------------------------------------------------------------------- + +BOOL SetNewSacColorMap(struct ScalosBitMapAndColor *sac, const ULONG *colorMap, + ULONG colorEntries, struct ScalosGfxBase *ScalosGfxBase) +{ + BOOL Success = FALSE; + + do { + if (NULL == sac) + break; + + if (sac->sac_ColorTable) + { + if (!(sac->sac_Flags & SACFLAGF_NO_FREE_COLORTABLE)) + ScalosGfxFreeVecPooled(ScalosGfxBase, sac->sac_ColorTable); + sac->sac_ColorTable = NULL; + } + + sac->sac_NumColors = colorEntries; + sac->sac_Flags &= ~SACFLAGF_NO_FREE_COLORTABLE; + + sac->sac_ColorTable = ScalosGfxAllocVecPooled(ScalosGfxBase, SAC_COLORTABLESIZE(sac)); + if (NULL == sac->sac_ColorTable) + break; + + memcpy(sac->sac_ColorTable, colorMap, SAC_COLORTABLESIZE(sac)); + + Success = TRUE; + } while (0); + + return Success; +} + +//----------------------------------------------------------------------- + diff --git a/scalos/libraries/scalosgfx/blit.c b/scalos/libraries/scalosgfx/blit.c new file mode 100644 index 000000000..0723d7c01 --- /dev/null +++ b/scalos/libraries/scalosgfx/blit.c @@ -0,0 +1,4762 @@ +// blit.c +// $Date$ +// $Revision$ + +#include +#include +#include +#include +#ifdef __amigaos4__ +#include +#include +#include +#endif //__amigaos4__ +#include +#include + +#define __USE_SYSBASE + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include + +#include "scalosgfx.h" + +//----------------------------------------------------------------------- + +#define ALPHA_OPAQUE 255 + +struct ARGBMultData + { + struct ARGB amd_Numerator; + struct ARGB amd_Denominator; + }; + +struct BlitARGBAlphaData + { + ULONG baa_SrcLeft; + ULONG baa_SrcTop; + ULONG baa_DestLeft; + ULONG baa_DestTop; + ULONG baa_Transparency; + const struct ARGB *baa_K; + const struct ARGBHeader *baa_Src; + }; + +struct BlitTransparentKData + { + const struct ARGB *btk_K; + ULONG btk_Width; + ULONG btk_Height; + }; + +struct BlitTransparentData + { + struct ARGB *bt_BufferBg; + ULONG bt_a; + ULONG bt_mla; + ULONG bt_Width; + ULONG bt_Height; + }; + +struct BlitTransparentAlphaData + { + const UBYTE *bta_Alpha; + struct ARGB *bta_BufferBg; + ULONG bta_Transparency; + ULONG bta_Width; + ULONG bta_Height; + }; + +struct BlitTransparentAlphaKData + { + const UBYTE *btak_Alpha; + struct ARGB *btak_BufferBg; + const struct ARGB *btak_K; + ULONG btak_Width; + ULONG btak_Height; + }; + +struct DoHookClipRectMsg + { + struct Layer *dhcr_Layer; + struct Rectangle dhcr_Bounds; + LONG dhcr_OffsetX; + LONG dhcr_OffsetY; + }; + +//----------------------------------------------------------------------- + +static SAVEDS(ULONG) INTERRUPT ARGBRectMultHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(ULONG) INTERRUPT BlitARGBAlphaHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(ULONG) INTERRUPT BlitARGBAlphaKTHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(ULONG) INTERRUPT BlitARGBKTHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(ULONG) INTERRUPT BlitTransparentKHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(ULONG) INTERRUPT BlitTransparentHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(ULONG) INTERRUPT BlitTransparentAlphaHookFunc(struct Hook *hook, Object *o, Msg msg); +static SAVEDS(ULONG) INTERRUPT BlitTransparentAlphaKHookFunc(struct Hook *hook, Object *o, Msg msg); + +//----------------------------------------------------------------------- + +void ARGBRectMult(struct RastPort *rp, + struct ARGB Numerator, struct ARGB Denominator, + WORD xMin, WORD yMin, WORD xMax, WORD yMax, + struct ScalosGfxBase *ScalosGfxBase) +{ +#ifdef __amigaos4__ + extern struct GfxBase *GfxBase; + + if (GfxBase->LibNode.lib_Version >= 51) + { + struct BitMap *SrcBM = NULL; + struct BitMap *AllocDestBM = NULL; + + d1(KPrintF(__FILE__ "/%s/%ld: xMin=%ld xMax=%ld yMin=%ld yMax=%ld\n", \ + __FUNC__, __LINE__, xMin, xMax, yMin, yMax)); + d1(KPrintF(__FILE__ "/%s/%ld: Layer=%08lx\n", __FUNC__, __LINE__, rp->Layer)); + + do { + enum enCompositeError rc; + LONG Width = 1 + xMax - xMin; + LONG Height = 1 + yMax - yMin; + float alpha; + struct RastPort srcRp; + enum enPDOperator op; + + InitRastPort(&srcRp); + SrcBM = AllocBitMap(Width, Height, + 32, + BMF_CLEAR | BMF_SPECIALFMT | SHIFT_PIXFMT(PIXFMT_ARGB32), + rp->BitMap); + d1(KPrintF(__FILE__ "/%s/%ld: SrcBM=%08lx\n", __FUNC__, __LINE__, SrcBM)); + if (NULL == SrcBM) + break; + + srcRp.BitMap = SrcBM; + + if (Numerator.Red > Denominator.Red) + { + // brighten + d1(KPrintF(__FILE__ "/%s/%ld: brighten\n", __FUNC__, __LINE__)); + + SetRPAttrs(&srcRp, + RPTAG_APenColor, 0xffffffff, + TAG_END); + RectFill(&srcRp, 0, 0, Width - 1, Height - 1); + + alpha = (float) Numerator.Red / (float) Denominator.Red; + + op = COMPOSITE_Plus; + } + else + { + // darken + float f; + + d1(KPrintF(__FILE__ "/%s/%ld: darken\n", __FUNC__, __LINE__)); + + if (Denominator.Red) + f = (float) Numerator.Red / (float) Denominator.Red; + else + f = 0.0; + + SetRPAttrs(&srcRp, + RPTAG_APenColor, 0xff000000, + TAG_END); + RectFill(&srcRp, 0, 0, Width - 1, Height - 1); + + if (f) + alpha = (1.0 - f) / f; + else + alpha = 0.0; + + op = COMPOSITE_Src_Over_Dest; + } + + if (rp->Layer) + { + struct RastPort destRp; + struct BitMap *destBM = AllocDestBM = AllocBitMap(Width, Height, + 32, + BMF_SPECIALFMT | SHIFT_PIXFMT(PIXFMT_ARGB32), + rp->BitMap); + d1(KPrintF(__FILE__ "/%s/%ld: SrcBM=%08lx\n", __FUNC__, __LINE__, SrcBM)); + if (NULL == AllocDestBM) + break; + + InitRastPort(&destRp); + destRp.BitMap = destBM; + + ClipBlit(rp, + xMin, yMin, + &destRp, + 0, 0, + Width, Height, + 0xc0); + + // CompositeTagList() + rc = CompositeTags(op, + SrcBM, + destBM, + COMPTAG_SrcAlpha, COMP_FLOAT_TO_FIX(alpha), + COMPTAG_SrcX, 0, + COMPTAG_SrcY, 0, + COMPTAG_SrcWidth, Width, + COMPTAG_SrcHeight, Height, + COMPTAG_Flags, COMPFLAG_SrcAlphaOverride, + TAG_END); + + ClipBlit(&destRp, + 0, 0, + rp, + xMin, yMin, + Width, Height, + 0xc0); + } + else + { + // CompositeTagList() + rc = CompositeTags(op, + SrcBM, + rp->BitMap, + COMPTAG_SrcAlpha, COMP_FLOAT_TO_FIX(alpha), + COMPTAG_SrcX, 0, + COMPTAG_SrcY, 0, + COMPTAG_SrcWidth, Width, + COMPTAG_SrcHeight, Height, + COMPTAG_OffsetX, xMin, + COMPTAG_OffsetY, yMin, + COMPTAG_Flags, COMPFLAG_SrcAlphaOverride, + TAG_END); + } + + d1(KPrintF(__FILE__ "/%s/%ld: rc=%ld\n", __FUNC__, __LINE__, rc)); + } while (0); + + if (SrcBM) + FreeBitMap(SrcBM); + if (AllocDestBM) + FreeBitMap(AllocDestBM); + } + else +#endif //__amigaos4__ + if (CyberGfxBase->lib_Version >= 51) + { + if (Numerator.Red > Denominator.Red) + { + ProcessPixelArray(rp, + xMin, + yMin, + 1 + xMax - xMin, + 1 + yMax - yMin, + POP_BRIGHTEN, + (256 * Numerator.Red) / Denominator.Red, + NULL); + } + else + { + ProcessPixelArray(rp, + xMin, + yMin, + 1 + xMax - xMin, + 1 + yMax - yMin, + POP_DARKEN, + (256 * Denominator.Red) / Numerator.Red, + NULL); + } + } + else + { + ULONG Width = xMax - xMin + 1; + struct ARGBMultData amd; + struct Rectangle ARGBRectMultRect; + struct Hook ARGBRectMultHook; + + amd.amd_Numerator = Numerator; + amd.amd_Denominator = Denominator; + + ARGBRectMultRect.MinX = xMin; + ARGBRectMultRect.MinY = yMin; + ARGBRectMultRect.MaxX = Width - 1; + ARGBRectMultRect.MaxY = yMax; + + SETHOOKFUNC(ARGBRectMultHook, ARGBRectMultHookFunc); + ARGBRectMultHook.h_Data = &amd; + + DoHookClipRects(&ARGBRectMultHook, rp, &ARGBRectMultRect); + } +} + +//----------------------------------------------------------------------- + +static SAVEDS(ULONG) INTERRUPT ARGBRectMultHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct RastPort *rp = (struct RastPort *) o; + struct DoHookClipRectMsg *dhcr = (struct DoHookClipRectMsg *) msg; + struct ARGBMultData *amd = (struct ARGBMultData *) hook->h_Data; + ULONG PixFmt; + ULONG BytesPerRow; + ULONG BytesPerPixel; + APTR Addr; + APTR handle; + + handle = LockBitMapTags(rp->BitMap, + LBMI_PIXFMT, (ULONG) &PixFmt, + LBMI_BYTESPERROW, (ULONG) &BytesPerRow, + LBMI_BYTESPERPIX, (ULONG) &BytesPerPixel, + LBMI_BASEADDRESS, (ULONG) &Addr, + TAG_END); + + d1(KPrintF(__FILE__ "/%s/%ld: handle=%08lx\n", __FUNC__, __LINE__, handle)); + if (handle) + { + ULONG y; + LONG xMin = dhcr->dhcr_Bounds.MinX; + LONG yMin = dhcr->dhcr_Bounds.MinY; + UBYTE *pPixel = ((UBYTE *) Addr) + BytesPerRow * yMin; + + d1(KPrintF(__FILE__ "/%s/%ld: PixFmt=%lu\n", __FUNC__, __LINE__, PixFmt)); + + switch (PixFmt) + { + case PIXFMT_RGB24: + case PIXFMT_RGBA32: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + xMin * BytesPerPixel; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + Red = pLine[0]; + Green = pLine[1]; + Blue = pLine[2]; + Red = amd->amd_Numerator.Red * Red / amd->amd_Denominator.Red; + Green = amd->amd_Numerator.Green * Green / amd->amd_Denominator.Green; + Blue = amd->amd_Numerator.Blue * Blue / amd->amd_Denominator.Blue; + Red = min(255, Red); + Green = min(255, Green); + Blue = min(255, Blue); + pLine[0] = Red; + pLine[1] = Green; + pLine[2] = Blue; + + pLine += BytesPerPixel; + } + pPixel += BytesPerRow; + } + break; + case PIXFMT_BGR24: + case PIXFMT_BGRA32: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + xMin * BytesPerPixel; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + Red = pLine[2]; + Green = pLine[1]; + Blue = pLine[0]; + Red = amd->amd_Numerator.Red * Red / amd->amd_Denominator.Red; + Green = amd->amd_Numerator.Green * Green / amd->amd_Denominator.Green; + Blue = amd->amd_Numerator.Blue * Blue / amd->amd_Denominator.Blue; + Red = min(255, Red); + Green = min(255, Green); + Blue = min(255, Blue); + pLine[2] = Red; + pLine[1] = Green; + pLine[0] = Blue; + + pLine += BytesPerPixel; + } + pPixel += BytesPerRow; + } + break; + case PIXFMT_ARGB32: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + xMin * BytesPerPixel; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + Red = pLine[1]; + Green = pLine[2]; + Blue = pLine[3]; + Red = amd->amd_Numerator.Red * Red / amd->amd_Denominator.Red; + Green = amd->amd_Numerator.Green * Green / amd->amd_Denominator.Green; + Blue = amd->amd_Numerator.Blue * Blue / amd->amd_Denominator.Blue; + Red = min(255, Red); + Green = min(255, Green); + Blue = min(255, Blue); + pLine[1] = Red; + pLine[2] = Green; + pLine[3] = Blue; + + pLine += BytesPerPixel; + } + pPixel += BytesPerRow; + } + break; + case PIXFMT_RGB16: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + xMin * BytesPerPixel; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + Red = GET_RED_RGB16(pLine16); + Green = GET_GREEN_RGB16(pLine16); + Blue = GET_BLUE_RGB16(pLine16); + Red = amd->amd_Numerator.Red * Red / amd->amd_Denominator.Red; + Green = amd->amd_Numerator.Green * Green / amd->amd_Denominator.Green; + Blue = amd->amd_Numerator.Blue * Blue / amd->amd_Denominator.Blue; + Red = min(255, Red); + Green = min(255, Green); + Blue = min(255, Blue); + *pLine16 = SET_BLUE_RGB16(Blue) + + SET_GREEN_RGB16(Green) + + SET_RED_RGB16(Red); + + pLine += BytesPerPixel; + } + pPixel += BytesPerRow; + } + break; + case PIXFMT_BGR16: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + xMin * BytesPerPixel; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + Red = GET_RED_BGR16(pLine16); + Green = GET_GREEN_BGR16(pLine16); + Blue = GET_BLUE_BGR16(pLine16); + Red = amd->amd_Numerator.Red * Red / amd->amd_Denominator.Red; + Green = amd->amd_Numerator.Green * Green / amd->amd_Denominator.Green; + Blue = amd->amd_Numerator.Blue * Blue / amd->amd_Denominator.Blue; + Red = min(255, Red); + Green = min(255, Green); + Blue = min(255, Blue); + *pLine16 = SET_BLUE_BGR16(Blue) + + SET_GREEN_BGR16(Green) + + SET_RED_BGR16(Red); + + pLine += BytesPerPixel; + } + pPixel += BytesPerRow; + } + break; + case PIXFMT_RGB15: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + xMin * BytesPerPixel; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + Red = GET_RED_RGB15(pLine16); + Green = GET_GREEN_RGB15(pLine16); + Blue = GET_BLUE_RGB15(pLine16); + Red = amd->amd_Numerator.Red * Red / amd->amd_Denominator.Red; + Green = amd->amd_Numerator.Green * Green / amd->amd_Denominator.Green; + Blue = amd->amd_Numerator.Blue * Blue / amd->amd_Denominator.Blue; + Red = min(255, Red); + Green = min(255, Green); + Blue = min(255, Blue); + *pLine16 = SET_BLUE_RGB15(Blue) + + SET_GREEN_RGB15(Green) + + SET_RED_RGB15(Red); + + pLine += BytesPerPixel; + } + pPixel += BytesPerRow; + } + break; + case PIXFMT_BGR15: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + xMin * BytesPerPixel; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + Red = GET_RED_BGR15(pLine16); + Green = GET_GREEN_BGR15(pLine16); + Blue = GET_BLUE_BGR15(pLine16); + Red = amd->amd_Numerator.Red * Red / amd->amd_Denominator.Red; + Green = amd->amd_Numerator.Green * Green / amd->amd_Denominator.Green; + Blue = amd->amd_Numerator.Blue * Blue / amd->amd_Denominator.Blue; + Red = min(255, Red); + Green = min(255, Green); + Blue = min(255, Blue); + *pLine16 = SET_BLUE_BGR15(Blue) + + SET_GREEN_BGR15(Green) + + SET_RED_BGR15(Red); + + pLine += BytesPerPixel; + } + pPixel += BytesPerRow; + } + break; + case PIXFMT_RGB15PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + xMin * BytesPerPixel; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + Red = GET_RED_RGB15PC(pLine16); + Green = GET_GREEN_RGB15PC(pLine16); + Blue = GET_BLUE_RGB15PC(pLine16); + Red = amd->amd_Numerator.Red * Red / amd->amd_Denominator.Red; + Green = amd->amd_Numerator.Green * Green / amd->amd_Denominator.Green; + Blue = amd->amd_Numerator.Blue * Blue / amd->amd_Denominator.Blue; + Red = min(255, Red); + Green = min(255, Green); + Blue = min(255, Blue); + *pLine16 = SET_BLUE_RGB15PC(Blue) + + SET_GREEN_RGB15PC(Green) + + SET_RED_RGB15PC(Red); + + pLine += BytesPerPixel; + } + pPixel += BytesPerRow; + } + break; + case PIXFMT_BGR15PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + xMin * BytesPerPixel; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + Red = GET_RED_BGR15PC(pLine16); + Green = GET_GREEN_BGR15PC(pLine16); + Blue = GET_BLUE_BGR15PC(pLine16); + Red = amd->amd_Numerator.Red * Red / amd->amd_Denominator.Red; + Green = amd->amd_Numerator.Green * Green / amd->amd_Denominator.Green; + Blue = amd->amd_Numerator.Blue * Blue / amd->amd_Denominator.Blue; + Red = min(255, Red); + Green = min(255, Green); + Blue = min(255, Blue); + *pLine16 = SET_BLUE_BGR15PC(Blue) + + SET_GREEN_BGR15PC(Green) + + SET_RED_BGR15PC(Red); + + pLine += BytesPerPixel; + } + pPixel += BytesPerRow; + } + break; + case PIXFMT_RGB16PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + xMin * BytesPerPixel; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + Red = GET_RED_RGB16PC(pLine16); + Green = GET_GREEN_RGB16PC(pLine16); + Blue = GET_BLUE_RGB16PC(pLine16); + Red = amd->amd_Numerator.Red * Red / amd->amd_Denominator.Red; + Green = amd->amd_Numerator.Green * Green / amd->amd_Denominator.Green; + Blue = amd->amd_Numerator.Blue * Blue / amd->amd_Denominator.Blue; + Red = min(255, Red); + Green = min(255, Green); + Blue = min(255, Blue); + *pLine16 = SET_BLUE_RGB16PC(Blue) + + SET_GREEN_RGB16PC(Green) + + SET_RED_RGB16PC(Red); + + pLine += BytesPerPixel; + } + pPixel += BytesPerRow; + } + break; + case PIXFMT_BGR16PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + xMin * BytesPerPixel; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + Red = GET_RED_BGR16PC(pLine16); + Green = GET_GREEN_BGR16PC(pLine16); + Blue = GET_BLUE_BGR16PC(pLine16); + Red = amd->amd_Numerator.Red * Red / amd->amd_Denominator.Red; + Green = amd->amd_Numerator.Green * Green / amd->amd_Denominator.Green; + Blue = amd->amd_Numerator.Blue * Blue / amd->amd_Denominator.Blue; + Red = min(255, Red); + Green = min(255, Green); + Blue = min(255, Blue); + *pLine16 = SET_BLUE_BGR16PC(Blue) + + SET_GREEN_BGR16PC(Green) + + SET_RED_BGR16PC(Red); + + pLine += BytesPerPixel; + } + pPixel += BytesPerRow; + } + break; + default: + break; + } + + UnLockBitMap(handle); + } + else + { + kprintf(__FILE__ "/%s/%ld: Can't lock bitmap\n", __FUNC__, __LINE__); + } + + return 0; +} + +//----------------------------------------------------------------------- + +// Blit with Alpha from Src into RastPort rp +void BlitARGBAlpha(struct RastPort *rp, const struct ARGBHeader *SrcH, + ULONG DestLeft, ULONG DestTop, + ULONG SrcLeft, ULONG SrcTop, + ULONG Width, ULONG Height, + struct ScalosGfxBase *ScalosGfxBase) +{ + struct BlitARGBAlphaData baa; + struct Rectangle BlitARGBAlphaRect; + struct Hook BlitARGBAlphaHook; + + baa.baa_SrcLeft = SrcLeft; + baa.baa_SrcTop = SrcTop; + baa.baa_DestLeft = DestLeft; + baa.baa_DestTop = DestTop; + baa.baa_Src = SrcH; + + BlitARGBAlphaRect.MinX = BlitARGBAlphaRect.MaxX = DestLeft; + BlitARGBAlphaRect.MinY = BlitARGBAlphaRect.MaxY = DestTop; + BlitARGBAlphaRect.MaxX += Width - 1; + BlitARGBAlphaRect.MaxY += Height - 1; + + SETHOOKFUNC(BlitARGBAlphaHook, BlitARGBAlphaHookFunc); + BlitARGBAlphaHook.h_Data = &baa; + + DoHookClipRects(&BlitARGBAlphaHook, rp, &BlitARGBAlphaRect); +} + +//----------------------------------------------------------------------- + +// Blit with Alpha from Src into RastPort rp +// with additional Transparency and Tint "K" + +void BlitARGBAlphaKT(struct RastPort *rp, const struct ARGBHeader *SrcH, + ULONG DestLeft, ULONG DestTop, + ULONG SrcLeft, ULONG SrcTop, + ULONG Width, ULONG Height, + const struct ARGB *K, ULONG Transparency, + struct ScalosGfxBase *ScalosGfxBase) +{ + struct BlitARGBAlphaData baa; + struct Rectangle BlitARGBAlphaKTRect; + struct Hook BlitARGBAlphaKTHook; + + baa.baa_SrcLeft = SrcLeft; + baa.baa_SrcTop = SrcTop; + baa.baa_DestLeft = DestLeft; + baa.baa_DestTop = DestTop; + baa.baa_Src = SrcH; + baa.baa_K = K; + baa.baa_Transparency = Transparency; + + BlitARGBAlphaKTRect.MinX = BlitARGBAlphaKTRect.MaxX = DestLeft; + BlitARGBAlphaKTRect.MinY = BlitARGBAlphaKTRect.MaxY = DestTop; + BlitARGBAlphaKTRect.MaxX += Width - 1; + BlitARGBAlphaKTRect.MaxY += Height - 1; + + SETHOOKFUNC(BlitARGBAlphaKTHook, BlitARGBAlphaKTHookFunc); + BlitARGBAlphaKTHook.h_Data = &baa; + + DoHookClipRects(&BlitARGBAlphaKTHook, rp, &BlitARGBAlphaKTRect); +} + +//----------------------------------------------------------------------- + +// Blit without Alpha from Src into RastPort rp +// with additional Transparency and Tint "K" + +void BlitARGBKT(struct RastPort *rp, const struct ARGBHeader *SrcH, + ULONG DestLeft, ULONG DestTop, + ULONG SrcLeft, ULONG SrcTop, + ULONG Width, ULONG Height, + const struct ARGB *K, ULONG Transparency, + struct ScalosGfxBase *ScalosGfxBase) +{ + struct BlitARGBAlphaData baa; + struct Rectangle BlitARGBKTRect; + struct Hook BlitARGBKTHook; + + baa.baa_SrcLeft = SrcLeft; + baa.baa_SrcTop = SrcTop; + baa.baa_DestLeft = DestLeft; + baa.baa_DestTop = DestTop; + baa.baa_Src = SrcH; + baa.baa_K = K; + baa.baa_Transparency = Transparency; + + BlitARGBKTRect.MinX = BlitARGBKTRect.MaxX = DestLeft; + BlitARGBKTRect.MinY = BlitARGBKTRect.MaxY = DestTop; + BlitARGBKTRect.MaxX += Width - 1; + BlitARGBKTRect.MaxY += Height - 1; + + SETHOOKFUNC(BlitARGBKTHook, BlitARGBKTHookFunc); + BlitARGBKTHook.h_Data = &baa; + + DoHookClipRects(&BlitARGBKTHook, rp, &BlitARGBKTRect); +} + +//----------------------------------------------------------------------- + +static SAVEDS(ULONG) INTERRUPT BlitARGBAlphaHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct RastPort *rp = (struct RastPort *) o; + struct DoHookClipRectMsg *dhcr = (struct DoHookClipRectMsg *) msg; + struct BlitARGBAlphaData *baa = (struct BlitARGBAlphaData *) hook->h_Data; + ULONG PixFmt; + ULONG BytesPerRow; + ULONG BytesPerPixel; + APTR Addr; + APTR handle; + + handle = LockBitMapTags(rp->BitMap, + LBMI_PIXFMT, (ULONG) &PixFmt, + LBMI_BYTESPERROW, (ULONG) &BytesPerRow, + LBMI_BYTESPERPIX, (ULONG) &BytesPerPixel, + LBMI_BASEADDRESS, (ULONG) &Addr, + TAG_END); + + d1(KPrintF(__FILE__ "/%s/%ld: handle=%08lx\n", __FUNC__, __LINE__, handle)); + if (handle) + { + ULONG y; + ULONG SrcLeft = baa->baa_SrcLeft + (dhcr->dhcr_OffsetX - baa->baa_DestLeft); + ULONG SrcTop = baa->baa_SrcTop + (dhcr->dhcr_OffsetY - baa->baa_DestTop); + const struct ARGB *Src = baa->baa_Src->argb_ImageData + SrcTop * baa->baa_Src->argb_Width; + UBYTE *pPixel = ((UBYTE *) Addr) + BytesPerRow * dhcr->dhcr_Bounds.MinY; + + d1(KPrintF(__FILE__ "/%s/%ld: baa_SrcLeft=%ld baa_SrcTop=%ld\n", __FUNC__, __LINE__, baa->baa_SrcLeft, baa->baa_SrcTop)); + d1(KPrintF(__FILE__ "/%s/%ld: baa_DestLeft=%ld baa_DestTop=%ld\n", __FUNC__, __LINE__, baa->baa_DestLeft, baa->baa_DestTop)); + d1(KPrintF(__FILE__ "/%s/%ld: MinX=%ld MinY=%ld MaxX=%ld MaxY=%ld\n", __FUNC__, __LINE__, dhcr->dhcr_Bounds.MinX, dhcr->dhcr_Bounds.MinY, dhcr->dhcr_Bounds.MaxX, dhcr->dhcr_Bounds.MaxY)); + d1(KPrintF(__FILE__ "/%s/%ld: SrcLeft=%ld SrcTop=%ld\n", __FUNC__, __LINE__, SrcLeft, SrcTop)); + d1(KPrintF(__FILE__ "/%s/%ld: dhcr_OffsetX=%ld dhcr_OffsetY=%ld\n", __FUNC__, __LINE__, dhcr->dhcr_OffsetX, dhcr->dhcr_OffsetY)); + d1(KPrintF(__FILE__ "/%s/%ld: BytesPerPixel=%ld BytesPerRow=%ld\n", __FUNC__, __LINE__, BytesPerPixel, BytesPerRow)); + + d1(KPrintF(__FILE__ "/%s/%ld: PixFmt=%lu\n", __FUNC__, __LINE__, PixFmt)); + + switch (PixFmt) + { + case PIXFMT_RGB24: + case PIXFMT_RGBA32: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + ULONG a = (ULONG) SrcPtr->Alpha; + ULONG mla; + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + pLine[0] = SrcPtr->Red; + pLine[1] = SrcPtr->Green; + pLine[2] = SrcPtr->Blue; + break; + default: + mla = 257 - a; + + pLine[0] = (a * SrcPtr->Red + mla * pLine[0]) >> 8; + pLine[1] = (a * SrcPtr->Green + mla * pLine[1]) >> 8; + pLine[2] = (a * SrcPtr->Blue + mla * pLine[2]) >> 8; + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_BGR24: + case PIXFMT_BGRA32: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + ULONG a = (ULONG) SrcPtr->Alpha; + ULONG mla; + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + pLine[0] = SrcPtr->Blue; + pLine[1] = SrcPtr->Green; + pLine[2] = SrcPtr->Red; + break; + default: + mla = 257 - a; + + pLine[0] = (a * SrcPtr->Blue + mla * pLine[0]) >> 8; + pLine[1] = (a * SrcPtr->Green + mla * pLine[1]) >> 8; + pLine[2] = (a * SrcPtr->Red + mla * pLine[2]) >> 8; + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_ARGB32: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + ULONG a = (ULONG) SrcPtr->Alpha; + ULONG mla; + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + pLine[1] = SrcPtr->Red; + pLine[2] = SrcPtr->Green; + pLine[3] = SrcPtr->Blue; + break; + default: + mla = 257 - a; + + pLine[1] = (a * SrcPtr->Red + mla * pLine[1]) >> 8; + pLine[2] = (a * SrcPtr->Green + mla * pLine[2]) >> 8; + pLine[3] = (a * SrcPtr->Blue + mla * pLine[3]) >> 8; + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_RGB16: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + ULONG a = (ULONG) SrcPtr->Alpha; + ULONG mla; + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + *pLine16 = SET_BLUE_RGB16(SrcPtr->Blue) + + SET_GREEN_RGB16(SrcPtr->Green) + + SET_RED_RGB16(SrcPtr->Red); + break; + default: + mla = 257 - a; + + Red = GET_RED_RGB16(pLine16); + Green = GET_GREEN_RGB16(pLine16); + Blue = GET_BLUE_RGB16(pLine16); + Red = (a * SrcPtr->Red + mla * Red) >> 8; + Green = (a * SrcPtr->Green + mla * Green) >> 8; + Blue = (a * SrcPtr->Blue + mla * Blue) >> 8; + *pLine16 = SET_BLUE_RGB16(Blue) + + SET_GREEN_RGB16(Green) + + SET_RED_RGB16(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_BGR16: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + ULONG a = (ULONG) SrcPtr->Alpha; + ULONG mla; + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + *pLine16 = SET_BLUE_BGR16(SrcPtr->Blue) + + SET_GREEN_BGR16(SrcPtr->Green) + + SET_RED_BGR16(SrcPtr->Red); + break; + default: + mla = 257 - a; + + Blue = GET_BLUE_BGR16(pLine16); + Green = GET_GREEN_BGR16(pLine16); + Red = GET_RED_BGR16(pLine16); + Red = (a * SrcPtr->Red + mla * Red) >> 8; + Green = (a * SrcPtr->Green + mla * Green) >> 8; + Blue = (a * SrcPtr->Blue + mla * Blue) >> 8; + *pLine16 = SET_BLUE_BGR16(Blue) + + SET_GREEN_BGR16(Green) + + SET_RED_BGR16(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_RGB15: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + ULONG a = (ULONG) SrcPtr->Alpha; + ULONG mla; + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + *pLine16 = SET_BLUE_RGB15(SrcPtr->Blue) + + SET_GREEN_RGB15(SrcPtr->Green) + + SET_RED_RGB15(SrcPtr->Red); + break; + default: + mla = 257 - a; + + Red = GET_RED_RGB15(pLine16); + Green = GET_GREEN_RGB15(pLine16); + Blue = GET_BLUE_RGB15(pLine16); + Red = (a * SrcPtr->Red + mla * Red) >> 8; + Green = (a * SrcPtr->Green + mla * Green) >> 8; + Blue = (a * SrcPtr->Blue + mla * Blue) >> 8; + *pLine16 = SET_BLUE_RGB15(Blue) + + SET_GREEN_RGB15(Green) + + SET_RED_RGB15(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_BGR15: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + ULONG a = (ULONG) SrcPtr->Alpha; + ULONG mla; + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + *pLine16 = SET_BLUE_BGR15(SrcPtr->Blue) + + SET_GREEN_BGR15(SrcPtr->Green) + + SET_RED_BGR15(SrcPtr->Red); + break; + default: + mla = 257 - a; + + Red = GET_RED_BGR15(pLine16); + Green = GET_GREEN_BGR15(pLine16); + Blue = GET_BLUE_BGR15(pLine16); + Red = (a * SrcPtr->Red + mla * Red) >> 8; + Green = (a * SrcPtr->Green + mla * Green) >> 8; + Blue = (a * SrcPtr->Blue + mla * Blue) >> 8; + *pLine16 = SET_BLUE_BGR15(Blue) + + SET_GREEN_BGR15(Green) + + SET_RED_BGR15(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_RGB15PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + ULONG a = (ULONG) SrcPtr->Alpha; + ULONG mla; + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + *pLine16 = SET_BLUE_RGB15PC(SrcPtr->Blue) + + SET_GREEN_RGB15PC(SrcPtr->Green) + + SET_RED_RGB15PC(SrcPtr->Red); + break; + default: + mla = 257 - a; + + Red = GET_RED_RGB15PC(pLine16); + Green = GET_GREEN_RGB15PC(pLine16); + Blue = GET_BLUE_RGB15PC(pLine16); + Red = (a * SrcPtr->Red + mla * Red) >> 8; + Green = (a * SrcPtr->Green + mla * Green) >> 8; + Blue = (a * SrcPtr->Blue + mla * Blue) >> 8; + *pLine16 = SET_BLUE_RGB15PC(Blue) + + SET_GREEN_RGB15PC(Green) + + SET_RED_RGB15PC(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_BGR15PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + ULONG a = (ULONG) SrcPtr->Alpha; + ULONG mla; + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + *pLine16 = SET_BLUE_BGR15PC(SrcPtr->Blue) + + SET_GREEN_BGR15PC(SrcPtr->Green) + + SET_RED_BGR15PC(SrcPtr->Red); + break; + default: + mla = 257 - a; + + Red = GET_RED_BGR15PC(pLine16); + Green = GET_GREEN_BGR15PC(pLine16); + Blue = GET_BLUE_BGR15PC(pLine16); + Red = (a * SrcPtr->Red + mla * Red) >> 8; + Green = (a * SrcPtr->Green + mla * Green) >> 8; + Blue = (a * SrcPtr->Blue + mla * Blue) >> 8; + *pLine16 = SET_BLUE_BGR15PC(Blue) + + SET_GREEN_BGR15PC(Green) + + SET_RED_BGR15PC(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_RGB16PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + ULONG a = (ULONG) SrcPtr->Alpha; + ULONG mla; + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + *pLine16 = SET_BLUE_RGB16PC(SrcPtr->Blue) + + SET_GREEN_RGB16PC(SrcPtr->Green) + + SET_RED_RGB16PC(SrcPtr->Red); + break; + default: + mla = 257 - a; + + Red = GET_RED_RGB16PC(pLine16); + Green = GET_GREEN_RGB16PC(pLine16); + Blue = GET_BLUE_RGB16PC(pLine16); + Red = (a * SrcPtr->Red + mla * Red) >> 8; + Green = (a * SrcPtr->Green + mla * Green) >> 8; + Blue = (a * SrcPtr->Blue + mla * Blue) >> 8; + *pLine16 = SET_BLUE_RGB16PC(Blue) + + SET_GREEN_RGB16PC(Green) + + SET_RED_RGB16PC(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_BGR16PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + ULONG a = (ULONG) SrcPtr->Alpha; + ULONG mla; + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + *pLine16 = SET_BLUE_BGR16PC(SrcPtr->Blue) + + SET_GREEN_BGR16PC(SrcPtr->Green) + + SET_RED_BGR16PC(SrcPtr->Red); + break; + default: + mla = 257 - a; + + Blue = GET_BLUE_BGR16PC(pLine16); + Green = GET_GREEN_BGR16PC(pLine16); + Red = GET_RED_BGR16PC(pLine16); + Red = (a * SrcPtr->Red + mla * Red) >> 8; + Green = (a * SrcPtr->Green + mla * Green) >> 8; + Blue = (a * SrcPtr->Blue + mla * Blue) >> 8; + *pLine16 = SET_BLUE_BGR16PC(Blue) + + SET_GREEN_BGR16PC(Green) + + SET_RED_BGR16PC(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + default: + break; + } + UnLockBitMap(handle); + } + else + { + LONG width = dhcr->dhcr_Bounds.MaxX - dhcr->dhcr_Bounds.MinX + 1; + LONG height = dhcr->dhcr_Bounds.MaxY - dhcr->dhcr_Bounds.MinY + 1; + if (width > 0 && height > 0) + { + BytesPerPixel = 3; + BytesPerRow = BytesPerPixel * width; + Addr = AllocVec(BytesPerRow * height, MEMF_ANY); + if (Addr) + { + ULONG y; + ULONG SrcLeft = baa->baa_SrcLeft + (dhcr->dhcr_OffsetX - baa->baa_DestLeft); + ULONG SrcTop = baa->baa_SrcTop + (dhcr->dhcr_OffsetY - baa->baa_DestTop); + const struct ARGB *Src = baa->baa_Src->argb_ImageData + SrcTop * baa->baa_Src->argb_Width; + UBYTE *pPixel = ((UBYTE *) Addr); // + BytesPerRow * dhcr->dhcr_Bounds.MinY; + + ReadPixelArray(Addr, 0, 0, BytesPerRow, rp, + baa->baa_DestLeft, baa->baa_DestTop, + width, height, + RECTFMT_RGB); + + //PIXFMT_RGB24 + for (y = 0; y < height; y++) + { + ULONG x; + UBYTE *pLine = pPixel; // + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + + for (x = 0; x < width; x++) + { + ULONG a = (ULONG) SrcPtr->Alpha; + ULONG mla; + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + pLine[0] = SrcPtr->Red; + pLine[1] = SrcPtr->Green; + pLine[2] = SrcPtr->Blue; + break; + default: + mla = 257 - a; + + pLine[0] = (a * SrcPtr->Red + mla * pLine[0]) >> 8; + pLine[1] = (a * SrcPtr->Green + mla * pLine[1]) >> 8; + pLine[2] = (a * SrcPtr->Blue + mla * pLine[2]) >> 8; + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + WritePixelArray(Addr, 0, 0, BytesPerRow, rp, + baa->baa_DestLeft, baa->baa_DestTop, + width, height, + RECTFMT_RGB); + FreeVec(Addr); + } + } + } + + return 0; +} + +//----------------------------------------------------------------------- + +static SAVEDS(ULONG) INTERRUPT BlitARGBAlphaKTHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct RastPort *rp = (struct RastPort *) o; + struct DoHookClipRectMsg *dhcr = (struct DoHookClipRectMsg *) msg; + struct BlitARGBAlphaData *baa = (struct BlitARGBAlphaData *) hook->h_Data; + ULONG PixFmt; + ULONG BytesPerRow; + ULONG BytesPerPixel; + APTR Addr; + APTR handle; + + handle = LockBitMapTags(rp->BitMap, + LBMI_PIXFMT, (ULONG) &PixFmt, + LBMI_BYTESPERROW, (ULONG) &BytesPerRow, + LBMI_BYTESPERPIX, (ULONG) &BytesPerPixel, + LBMI_BASEADDRESS, (ULONG) &Addr, + TAG_END); + + d1(KPrintF(__FILE__ "/%s/%ld: handle=%08lx\n", __FUNC__, __LINE__, handle)); + if (handle) + { + ULONG y; + ULONG SrcLeft = baa->baa_SrcLeft + (dhcr->dhcr_OffsetX - baa->baa_DestLeft); + ULONG SrcTop = baa->baa_SrcTop + (dhcr->dhcr_OffsetY - baa->baa_DestTop); + const struct ARGB *Src = baa->baa_Src->argb_ImageData + SrcTop * baa->baa_Src->argb_Width; + UBYTE *pPixel = ((UBYTE *) Addr) + BytesPerRow * dhcr->dhcr_Bounds.MinY; + ULONG T = baa->baa_Transparency; + + d1(KPrintF(__FILE__ "/%s/%ld: baa_SrcLeft=%ld baa_SrcTop=%ld\n", __FUNC__, __LINE__, baa->baa_SrcLeft, baa->baa_SrcTop)); + d1(KPrintF(__FILE__ "/%s/%ld: baa_DestLeft=%ld baa_DestTop=%ld\n", __FUNC__, __LINE__, baa->baa_DestLeft, baa->baa_DestTop)); + d1(KPrintF(__FILE__ "/%s/%ld: MinX=%ld MinY=%ld MaxX=%ld MaxY=%ld\n", __FUNC__, __LINE__, dhcr->dhcr_Bounds.MinX, dhcr->dhcr_Bounds.MinY, dhcr->dhcr_Bounds.MaxX, dhcr->dhcr_Bounds.MaxY)); + d1(KPrintF(__FILE__ "/%s/%ld: SrcLeft=%ld SrcTop=%ld\n", __FUNC__, __LINE__, SrcLeft, SrcTop)); + d1(KPrintF(__FILE__ "/%s/%ld: dhcr_OffsetX=%ld dhcr_OffsetY=%ld\n", __FUNC__, __LINE__, dhcr->dhcr_OffsetX, dhcr->dhcr_OffsetY)); + d1(KPrintF(__FILE__ "/%s/%ld: BytesPerPixel=%ld BytesPerRow=%ld\n", __FUNC__, __LINE__, BytesPerPixel, BytesPerRow)); + + d1(KPrintF(__FILE__ "/%s/%ld: PixFmt=%lu\n", __FUNC__, __LINE__, PixFmt)); + + switch (PixFmt) + { + case PIXFMT_RGB24: + case PIXFMT_RGBA32: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD SrcRed, SrcGreen, SrcBlue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + ULONG a = ((T * SrcPtr->Alpha) >> 8) + 1; + ULONG mla; + + SrcRed = min(255, SrcPtr->Red + baa->baa_K->Red); + SrcGreen = min(255, SrcPtr->Green + baa->baa_K->Green); + SrcBlue = min(255, SrcPtr->Blue + baa->baa_K->Blue); + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + pLine[0] = SrcRed; + pLine[1] = SrcGreen; + pLine[2] = SrcBlue; + break; + default: + mla = 257 - a; + + pLine[0] = (a * SrcRed + mla * pLine[0]) >> 8; + pLine[1] = (a * SrcGreen + mla * pLine[1]) >> 8; + pLine[2] = (a * SrcBlue + mla * pLine[2]) >> 8; + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_BGR24: + case PIXFMT_BGRA32: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD SrcRed, SrcGreen, SrcBlue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + ULONG a = ((T * SrcPtr->Alpha) >> 8) + 1; + ULONG mla; + + SrcRed = min(255, SrcPtr->Red + baa->baa_K->Red); + SrcGreen = min(255, SrcPtr->Green + baa->baa_K->Green); + SrcBlue = min(255, SrcPtr->Blue + baa->baa_K->Blue); + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + pLine[0] = SrcBlue; + pLine[1] = SrcGreen; + pLine[2] = SrcRed; + break; + default: + mla = 257 - a; + + pLine[0] = (a * SrcBlue + mla * pLine[0]) >> 8; + pLine[1] = (a * SrcGreen + mla * pLine[1]) >> 8; + pLine[2] = (a * SrcRed + mla * pLine[2]) >> 8; + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_ARGB32: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD SrcRed, SrcGreen, SrcBlue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + ULONG a = ((T * SrcPtr->Alpha) >> 8) + 1; + ULONG mla; + + SrcRed = min(255, SrcPtr->Red + baa->baa_K->Red); + SrcGreen = min(255, SrcPtr->Green + baa->baa_K->Green); + SrcBlue = min(255, SrcPtr->Blue + baa->baa_K->Blue); + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + pLine[1] = SrcRed; + pLine[2] = SrcGreen; + pLine[3] = SrcBlue; + break; + default: + mla = 257 - a; + + pLine[1] = (a * SrcRed + mla * pLine[1]) >> 8; + pLine[2] = (a * SrcGreen + mla * pLine[2]) >> 8; + pLine[3] = (a * SrcBlue + mla * pLine[3]) >> 8; + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_RGB16: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD Red, Green, Blue; + UWORD SrcRed, SrcGreen, SrcBlue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + ULONG a = ((T * SrcPtr->Alpha) >> 8) + 1; + ULONG mla; + + SrcRed = min(255, SrcPtr->Red + baa->baa_K->Red); + SrcGreen = min(255, SrcPtr->Green + baa->baa_K->Green); + SrcBlue = min(255, SrcPtr->Blue + baa->baa_K->Blue); + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + *pLine16 = SET_BLUE_RGB16(SrcBlue) + + SET_GREEN_RGB16(SrcGreen) + + SET_RED_RGB16(SrcRed); + break; + default: + mla = 257 - a; + + Red = GET_RED_RGB16(pLine16); + Green = GET_GREEN_RGB16(pLine16); + Blue = GET_BLUE_RGB16(pLine16); + Red = (a * SrcRed + mla * Red) >> 8; + Green = (a * SrcGreen + mla * Green) >> 8; + Blue = (a * SrcBlue + mla * Blue) >> 8; + *pLine16 = SET_BLUE_RGB16(Blue) + + SET_GREEN_RGB16(Green) + + SET_RED_RGB16(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_BGR16: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD Red, Green, Blue; + UWORD SrcRed, SrcGreen, SrcBlue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + ULONG a = ((T * SrcPtr->Alpha) >> 8) + 1; + ULONG mla; + + SrcRed = min(255, SrcPtr->Red + baa->baa_K->Red); + SrcGreen = min(255, SrcPtr->Green + baa->baa_K->Green); + SrcBlue = min(255, SrcPtr->Blue + baa->baa_K->Blue); + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + *pLine16 = SET_BLUE_BGR16(SrcBlue) + + SET_GREEN_BGR16(SrcGreen) + + SET_RED_BGR16(SrcRed); + break; + default: + mla = 257 - a; + + Blue = GET_BLUE_BGR16(pLine16); + Green = GET_GREEN_BGR16(pLine16); + Red = GET_RED_BGR16(pLine16); + Red = (a * SrcRed + mla * Red) >> 8; + Green = (a * SrcGreen + mla * Green) >> 8; + Blue = (a * SrcBlue + mla * Blue) >> 8; + *pLine16 = SET_BLUE_BGR16(Blue) + + SET_GREEN_BGR16(Green) + + SET_RED_BGR16(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_RGB15: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD Red, Green, Blue; + UWORD SrcRed, SrcGreen, SrcBlue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + ULONG a = ((T * SrcPtr->Alpha) >> 8) + 1; + ULONG mla; + + SrcRed = min(255, SrcPtr->Red + baa->baa_K->Red); + SrcGreen = min(255, SrcPtr->Green + baa->baa_K->Green); + SrcBlue = min(255, SrcPtr->Blue + baa->baa_K->Blue); + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + *pLine16 = SET_BLUE_RGB15(SrcBlue) + + SET_GREEN_RGB15(SrcGreen) + + SET_RED_RGB15(SrcRed); + break; + default: + mla = 257 - a; + + Red = GET_RED_RGB15(pLine16); + Green = GET_GREEN_RGB15(pLine16); + Blue = GET_BLUE_RGB15(pLine16); + Red = (a * SrcRed + mla * Red) >> 8; + Green = (a * SrcGreen + mla * Green) >> 8; + Blue = (a * SrcBlue + mla * Blue) >> 8; + *pLine16 = SET_BLUE_RGB15(Blue) + + SET_GREEN_RGB15(Green) + + SET_RED_RGB15(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_BGR15: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD Red, Green, Blue; + UWORD SrcRed, SrcGreen, SrcBlue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + ULONG a = ((T * SrcPtr->Alpha) >> 8) + 1; + ULONG mla; + + SrcRed = min(255, SrcPtr->Red + baa->baa_K->Red); + SrcGreen = min(255, SrcPtr->Green + baa->baa_K->Green); + SrcBlue = min(255, SrcPtr->Blue + baa->baa_K->Blue); + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + *pLine16 = SET_BLUE_BGR15(SrcBlue) + + SET_GREEN_BGR15(SrcGreen) + + SET_RED_BGR15(SrcRed); + break; + default: + mla = 257 - a; + + Red = GET_RED_BGR15(pLine16); + Green = GET_GREEN_BGR15(pLine16); + Blue = GET_BLUE_BGR15(pLine16); + Red = (a * SrcRed + mla * Red) >> 8; + Green = (a * SrcGreen + mla * Green) >> 8; + Blue = (a * SrcBlue + mla * Blue) >> 8; + *pLine16 = SET_BLUE_BGR15(Blue) + + SET_GREEN_BGR15(Green) + + SET_RED_BGR15(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_RGB15PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD Red, Green, Blue; + UWORD SrcRed, SrcGreen, SrcBlue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + ULONG a = ((T * SrcPtr->Alpha) >> 8) + 1; + ULONG mla; + + SrcRed = min(255, SrcPtr->Red + baa->baa_K->Red); + SrcGreen = min(255, SrcPtr->Green + baa->baa_K->Green); + SrcBlue = min(255, SrcPtr->Blue + baa->baa_K->Blue); + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + *pLine16 = SET_BLUE_RGB15PC(SrcBlue) + + SET_GREEN_RGB15PC(SrcGreen) + + SET_RED_RGB15PC(SrcRed); + break; + default: + mla = 257 - a; + + Red = GET_RED_RGB15PC(pLine16); + Green = GET_GREEN_RGB15PC(pLine16); + Blue = GET_BLUE_RGB15PC(pLine16); + Red = (a * SrcRed + mla * Red) >> 8; + Green = (a * SrcGreen + mla * Green) >> 8; + Blue = (a * SrcBlue + mla * Blue) >> 8; + *pLine16 = SET_BLUE_RGB15PC(Blue) + + SET_GREEN_RGB15PC(Green) + + SET_RED_RGB15PC(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_BGR15PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD Red, Green, Blue; + UWORD SrcRed, SrcGreen, SrcBlue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + ULONG a = ((T * SrcPtr->Alpha) >> 8) + 1; + ULONG mla; + + SrcRed = min(255, SrcPtr->Red + baa->baa_K->Red); + SrcGreen = min(255, SrcPtr->Green + baa->baa_K->Green); + SrcBlue = min(255, SrcPtr->Blue + baa->baa_K->Blue); + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + *pLine16 = SET_BLUE_BGR15PC(SrcBlue) + + SET_GREEN_BGR15PC(SrcGreen) + + SET_RED_BGR15PC(SrcRed); + break; + default: + mla = 257 - a; + + Red = GET_RED_BGR15PC(pLine16); + Green = GET_GREEN_BGR15PC(pLine16); + Blue = GET_BLUE_BGR15PC(pLine16); + Red = (a * SrcRed + mla * Red) >> 8; + Green = (a * SrcGreen + mla * Green) >> 8; + Blue = (a * SrcBlue + mla * Blue) >> 8; + *pLine16 = SET_BLUE_BGR15PC(Blue) + + SET_GREEN_BGR15PC(Green) + + SET_RED_BGR15PC(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_RGB16PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD Red, Green, Blue; + UWORD SrcRed, SrcGreen, SrcBlue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + ULONG a = ((T * SrcPtr->Alpha) >> 8) + 1; + ULONG mla; + + SrcRed = min(255, SrcPtr->Red + baa->baa_K->Red); + SrcGreen = min(255, SrcPtr->Green + baa->baa_K->Green); + SrcBlue = min(255, SrcPtr->Blue + baa->baa_K->Blue); + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + *pLine16 = SET_BLUE_RGB16PC(SrcBlue) + + SET_GREEN_RGB16PC(SrcGreen) + + SET_RED_RGB16PC(SrcRed); + break; + default: + mla = 257 - a; + + Red = GET_RED_RGB16PC(pLine16); + Green = GET_GREEN_RGB16PC(pLine16); + Blue = GET_BLUE_RGB16PC(pLine16); + Red = (a * SrcRed + mla * Red) >> 8; + Green = (a * SrcGreen + mla * Green) >> 8; + Blue = (a * SrcBlue + mla * Blue) >> 8; + *pLine16 = SET_BLUE_RGB16PC(Blue) + + SET_GREEN_RGB16PC(Green) + + SET_RED_RGB16PC(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_BGR16PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD Red, Green, Blue; + UWORD SrcRed, SrcGreen, SrcBlue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + ULONG a = ((T * SrcPtr->Alpha) >> 8) + 1; + ULONG mla; + + SrcRed = min(255, SrcPtr->Red + baa->baa_K->Red); + SrcGreen = min(255, SrcPtr->Green + baa->baa_K->Green); + SrcBlue = min(255, SrcPtr->Blue + baa->baa_K->Blue); + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + *pLine16 = SET_BLUE_BGR16PC(SrcBlue) + + SET_GREEN_BGR16PC(SrcGreen) + + SET_RED_BGR16PC(SrcRed); + break; + default: + mla = 257 - a; + + Blue = GET_BLUE_BGR16PC(pLine16); + Green = GET_GREEN_BGR16PC(pLine16); + Red = GET_RED_BGR16PC(pLine16); + Red = (a * SrcRed + mla * Red) >> 8; + Green = (a * SrcGreen + mla * Green) >> 8; + Blue = (a * SrcBlue + mla * Blue) >> 8; + *pLine16 = SET_BLUE_BGR16PC(Blue) + + SET_GREEN_BGR16PC(Green) + + SET_RED_BGR16PC(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + default: + break; + } + UnLockBitMap(handle); + } + else + { + LONG width = dhcr->dhcr_Bounds.MaxX - dhcr->dhcr_Bounds.MinX + 1; + LONG height = dhcr->dhcr_Bounds.MaxY - dhcr->dhcr_Bounds.MinY + 1; + if (width > 0 && height > 0) + { + ULONG T = baa->baa_Transparency; + BytesPerPixel = 3; + BytesPerRow = BytesPerPixel * width; + Addr = AllocVec(BytesPerRow * height, MEMF_ANY); + + if (Addr && width > 0 && height > 0) + { + ULONG y; + ULONG SrcLeft = baa->baa_SrcLeft + (dhcr->dhcr_OffsetX - baa->baa_DestLeft); + ULONG SrcTop = baa->baa_SrcTop + (dhcr->dhcr_OffsetY - baa->baa_DestTop); + const struct ARGB *Src = baa->baa_Src->argb_ImageData + SrcTop * baa->baa_Src->argb_Width; + UBYTE *pPixel = ((UBYTE *) Addr); // + BytesPerRow * dhcr->dhcr_Bounds.MinY; + + ReadPixelArray(Addr, 0, 0, BytesPerRow, rp, + baa->baa_DestLeft, baa->baa_DestTop, + width, height, + RECTFMT_RGB); + + for (y = 0; y < height; y++) + { + ULONG x; + UBYTE *pLine = pPixel; // + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD SrcRed, SrcGreen, SrcBlue; + + for (x = 0; x < width; x++) + { + ULONG a = ((T * SrcPtr->Alpha) >> 8) + 1; + ULONG mla; + + SrcRed = min(255, SrcPtr->Red + baa->baa_K->Red); + SrcGreen = min(255, SrcPtr->Green + baa->baa_K->Green); + SrcBlue = min(255, SrcPtr->Blue + baa->baa_K->Blue); + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + pLine[0] = SrcRed; + pLine[1] = SrcGreen; + pLine[2] = SrcBlue; + break; + default: + mla = 257 - a; + + pLine[0] = (a * SrcRed + mla * pLine[0]) >> 8; + pLine[1] = (a * SrcGreen + mla * pLine[1]) >> 8; + pLine[2] = (a * SrcBlue + mla * pLine[2]) >> 8; + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + WritePixelArray(Addr, 0, 0, BytesPerRow, rp, + baa->baa_DestLeft, baa->baa_DestTop, + width, height, + RECTFMT_RGB); + FreeVec(Addr); + } + } + } + + return 0; +} + +//----------------------------------------------------------------------- + +static SAVEDS(ULONG) INTERRUPT BlitARGBKTHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct RastPort *rp = (struct RastPort *) o; + struct DoHookClipRectMsg *dhcr = (struct DoHookClipRectMsg *) msg; + struct BlitARGBAlphaData *baa = (struct BlitARGBAlphaData *) hook->h_Data; + ULONG PixFmt; + ULONG BytesPerRow; + ULONG BytesPerPixel; + APTR Addr; + APTR handle; + + handle = LockBitMapTags(rp->BitMap, + LBMI_PIXFMT, (ULONG) &PixFmt, + LBMI_BYTESPERROW, (ULONG) &BytesPerRow, + LBMI_BYTESPERPIX, (ULONG) &BytesPerPixel, + LBMI_BASEADDRESS, (ULONG) &Addr, + TAG_END); + + d1(KPrintF(__FILE__ "/%s/%ld: handle=%08lx\n", __FUNC__, __LINE__, handle)); + if (handle) + { + ULONG y; + ULONG SrcLeft = baa->baa_SrcLeft + (dhcr->dhcr_OffsetX - baa->baa_DestLeft); + ULONG SrcTop = baa->baa_SrcTop + (dhcr->dhcr_OffsetY - baa->baa_DestTop); + const struct ARGB *Src = baa->baa_Src->argb_ImageData + SrcTop * baa->baa_Src->argb_Width; + UBYTE *pPixel = ((UBYTE *) Addr) + BytesPerRow * dhcr->dhcr_Bounds.MinY; + ULONG T = baa->baa_Transparency; + ULONG a = T + 1; + ULONG mla = 257 - a; + + d1(KPrintF(__FILE__ "/%s/%ld: baa_SrcLeft=%ld baa_SrcTop=%ld\n", __FUNC__, __LINE__, baa->baa_SrcLeft, baa->baa_SrcTop)); + d1(KPrintF(__FILE__ "/%s/%ld: baa_DestLeft=%ld baa_DestTop=%ld\n", __FUNC__, __LINE__, baa->baa_DestLeft, baa->baa_DestTop)); + d1(KPrintF(__FILE__ "/%s/%ld: MinX=%ld MinY=%ld MaxX=%ld MaxY=%ld\n", __FUNC__, __LINE__, dhcr->dhcr_Bounds.MinX, dhcr->dhcr_Bounds.MinY, dhcr->dhcr_Bounds.MaxX, dhcr->dhcr_Bounds.MaxY)); + d1(KPrintF(__FILE__ "/%s/%ld: SrcLeft=%ld SrcTop=%ld\n", __FUNC__, __LINE__, SrcLeft, SrcTop)); + d1(KPrintF(__FILE__ "/%s/%ld: dhcr_OffsetX=%ld dhcr_OffsetY=%ld\n", __FUNC__, __LINE__, dhcr->dhcr_OffsetX, dhcr->dhcr_OffsetY)); + d1(KPrintF(__FILE__ "/%s/%ld: BytesPerPixel=%ld BytesPerRow=%ld\n", __FUNC__, __LINE__, BytesPerPixel, BytesPerRow)); + + d1(KPrintF(__FILE__ "/%s/%ld: PixFmt=%lu\n", __FUNC__, __LINE__, PixFmt)); + + switch (PixFmt) + { + case PIXFMT_RGB24: + case PIXFMT_RGBA32: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD SrcRed, SrcGreen, SrcBlue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + SrcRed = min(255, SrcPtr->Red + baa->baa_K->Red); + SrcGreen = min(255, SrcPtr->Green + baa->baa_K->Green); + SrcBlue = min(255, SrcPtr->Blue + baa->baa_K->Blue); + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + pLine[0] = SrcRed; + pLine[1] = SrcGreen; + pLine[2] = SrcBlue; + break; + default: + pLine[0] = (a * SrcRed + mla * pLine[0]) >> 8; + pLine[1] = (a * SrcGreen + mla * pLine[1]) >> 8; + pLine[2] = (a * SrcBlue + mla * pLine[2]) >> 8; + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_BGR24: + case PIXFMT_BGRA32: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD SrcRed, SrcGreen, SrcBlue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + SrcRed = min(255, SrcPtr->Red + baa->baa_K->Red); + SrcGreen = min(255, SrcPtr->Green + baa->baa_K->Green); + SrcBlue = min(255, SrcPtr->Blue + baa->baa_K->Blue); + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + pLine[0] = SrcBlue; + pLine[1] = SrcGreen; + pLine[2] = SrcRed; + break; + default: + pLine[0] = (a * SrcBlue + mla * pLine[0]) >> 8; + pLine[1] = (a * SrcGreen + mla * pLine[1]) >> 8; + pLine[2] = (a * SrcRed + mla * pLine[2]) >> 8; + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_ARGB32: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD SrcRed, SrcGreen, SrcBlue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + SrcRed = min(255, SrcPtr->Red + baa->baa_K->Red); + SrcGreen = min(255, SrcPtr->Green + baa->baa_K->Green); + SrcBlue = min(255, SrcPtr->Blue + baa->baa_K->Blue); + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + pLine[1] = SrcRed; + pLine[2] = SrcGreen; + pLine[3] = SrcBlue; + break; + default: + pLine[1] = (a * SrcRed + mla * pLine[1]) >> 8; + pLine[2] = (a * SrcGreen + mla * pLine[2]) >> 8; + pLine[3] = (a * SrcBlue + mla * pLine[3]) >> 8; + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_RGB16: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD Red, Green, Blue; + UWORD SrcRed, SrcGreen, SrcBlue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + SrcRed = min(255, SrcPtr->Red + baa->baa_K->Red); + SrcGreen = min(255, SrcPtr->Green + baa->baa_K->Green); + SrcBlue = min(255, SrcPtr->Blue + baa->baa_K->Blue); + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + *pLine16 = SET_BLUE_RGB16(SrcBlue) + + SET_GREEN_RGB16(SrcGreen) + + SET_RED_RGB16(SrcRed); + break; + default: + Red = GET_RED_RGB16(pLine16); + Green = GET_GREEN_RGB16(pLine16); + Blue = GET_BLUE_RGB16(pLine16); + Red = (a * SrcRed + mla * Red) >> 8; + Green = (a * SrcGreen + mla * Green) >> 8; + Blue = (a * SrcBlue + mla * Blue) >> 8; + *pLine16 = SET_BLUE_RGB16(Blue) + + SET_GREEN_RGB16(Green) + + SET_RED_RGB16(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_BGR16: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD Red, Green, Blue; + UWORD SrcRed, SrcGreen, SrcBlue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + SrcRed = min(255, SrcPtr->Red + baa->baa_K->Red); + SrcGreen = min(255, SrcPtr->Green + baa->baa_K->Green); + SrcBlue = min(255, SrcPtr->Blue + baa->baa_K->Blue); + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + *pLine16 = SET_BLUE_BGR16(SrcBlue) + + SET_GREEN_BGR16(SrcGreen) + + SET_RED_BGR16(SrcRed); + break; + default: + Blue = GET_BLUE_BGR16(pLine16); + Green = GET_GREEN_BGR16(pLine16); + Red = GET_RED_BGR16(pLine16); + Red = (a * SrcRed + mla * Red) >> 8; + Green = (a * SrcGreen + mla * Green) >> 8; + Blue = (a * SrcBlue + mla * Blue) >> 8; + *pLine16 = SET_BLUE_BGR16(Blue) + + SET_GREEN_BGR16(Green) + + SET_RED_BGR16(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_RGB15: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD Red, Green, Blue; + UWORD SrcRed, SrcGreen, SrcBlue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + SrcRed = min(255, SrcPtr->Red + baa->baa_K->Red); + SrcGreen = min(255, SrcPtr->Green + baa->baa_K->Green); + SrcBlue = min(255, SrcPtr->Blue + baa->baa_K->Blue); + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + *pLine16 = SET_BLUE_RGB15(SrcBlue) + + SET_GREEN_RGB15(SrcGreen) + + SET_RED_RGB15(SrcRed); + break; + default: + Red = GET_RED_RGB15(pLine16); + Green = GET_GREEN_RGB15(pLine16); + Blue = GET_BLUE_RGB15(pLine16); + Red = (a * SrcRed + mla * Red) >> 8; + Green = (a * SrcGreen + mla * Green) >> 8; + Blue = (a * SrcBlue + mla * Blue) >> 8; + *pLine16 = SET_BLUE_RGB15(Blue) + + SET_GREEN_RGB15(Green) + + SET_RED_RGB15(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_BGR15: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD Red, Green, Blue; + UWORD SrcRed, SrcGreen, SrcBlue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + SrcRed = min(255, SrcPtr->Red + baa->baa_K->Red); + SrcGreen = min(255, SrcPtr->Green + baa->baa_K->Green); + SrcBlue = min(255, SrcPtr->Blue + baa->baa_K->Blue); + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + *pLine16 = SET_BLUE_BGR15(SrcBlue) + + SET_GREEN_BGR15(SrcGreen) + + SET_RED_BGR15(SrcRed); + break; + default: + Red = GET_RED_BGR15(pLine16); + Green = GET_GREEN_BGR15(pLine16); + Blue = GET_BLUE_BGR15(pLine16); + Red = (a * SrcRed + mla * Red) >> 8; + Green = (a * SrcGreen + mla * Green) >> 8; + Blue = (a * SrcBlue + mla * Blue) >> 8; + *pLine16 = SET_BLUE_BGR15(Blue) + + SET_GREEN_BGR15(Green) + + SET_RED_BGR15(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_RGB15PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD Red, Green, Blue; + UWORD SrcRed, SrcGreen, SrcBlue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + SrcRed = min(255, SrcPtr->Red + baa->baa_K->Red); + SrcGreen = min(255, SrcPtr->Green + baa->baa_K->Green); + SrcBlue = min(255, SrcPtr->Blue + baa->baa_K->Blue); + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + *pLine16 = SET_BLUE_RGB15PC(SrcBlue) + + SET_GREEN_RGB15PC(SrcGreen) + + SET_RED_RGB15PC(SrcRed); + break; + default: + Red = GET_RED_RGB15PC(pLine16); + Green = GET_GREEN_RGB15PC(pLine16); + Blue = GET_BLUE_RGB15PC(pLine16); + Red = (a * SrcRed + mla * Red) >> 8; + Green = (a * SrcGreen + mla * Green) >> 8; + Blue = (a * SrcBlue + mla * Blue) >> 8; + *pLine16 = SET_BLUE_RGB15PC(Blue) + + SET_GREEN_RGB15PC(Green) + + SET_RED_RGB15PC(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_BGR15PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD Red, Green, Blue; + UWORD SrcRed, SrcGreen, SrcBlue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + SrcRed = min(255, SrcPtr->Red + baa->baa_K->Red); + SrcGreen = min(255, SrcPtr->Green + baa->baa_K->Green); + SrcBlue = min(255, SrcPtr->Blue + baa->baa_K->Blue); + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + *pLine16 = SET_BLUE_BGR15PC(SrcBlue) + + SET_GREEN_BGR15PC(SrcGreen) + + SET_RED_BGR15PC(SrcRed); + break; + default: + Red = GET_RED_BGR15PC(pLine16); + Green = GET_GREEN_BGR15PC(pLine16); + Blue = GET_BLUE_BGR15PC(pLine16); + Red = (a * SrcRed + mla * Red) >> 8; + Green = (a * SrcGreen + mla * Green) >> 8; + Blue = (a * SrcBlue + mla * Blue) >> 8; + *pLine16 = SET_BLUE_BGR15PC(Blue) + + SET_GREEN_BGR15PC(Green) + + SET_RED_BGR15PC(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_RGB16PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD Red, Green, Blue; + UWORD SrcRed, SrcGreen, SrcBlue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + SrcRed = min(255, SrcPtr->Red + baa->baa_K->Red); + SrcGreen = min(255, SrcPtr->Green + baa->baa_K->Green); + SrcBlue = min(255, SrcPtr->Blue + baa->baa_K->Blue); + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + *pLine16 = SET_BLUE_RGB16PC(SrcBlue) + + SET_GREEN_RGB16PC(SrcGreen) + + SET_RED_RGB16PC(SrcRed); + break; + default: + Red = GET_RED_RGB16PC(pLine16); + Green = GET_GREEN_RGB16PC(pLine16); + Blue = GET_BLUE_RGB16PC(pLine16); + Red = (a * SrcRed + mla * Red) >> 8; + Green = (a * SrcGreen + mla * Green) >> 8; + Blue = (a * SrcBlue + mla * Blue) >> 8; + *pLine16 = SET_BLUE_RGB16PC(Blue) + + SET_GREEN_RGB16PC(Green) + + SET_RED_RGB16PC(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + case PIXFMT_BGR16PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + SrcLeft; + UWORD Red, Green, Blue; + UWORD SrcRed, SrcGreen, SrcBlue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + SrcRed = min(255, SrcPtr->Red + baa->baa_K->Red); + SrcGreen = min(255, SrcPtr->Green + baa->baa_K->Green); + SrcBlue = min(255, SrcPtr->Blue + baa->baa_K->Blue); + + switch (a) + { + case 0: + case 1: + break; + case ALPHA_OPAQUE: + *pLine16 = SET_BLUE_BGR16PC(SrcBlue) + + SET_GREEN_BGR16PC(SrcGreen) + + SET_RED_BGR16PC(SrcRed); + break; + default: + Blue = GET_BLUE_BGR16PC(pLine16); + Green = GET_GREEN_BGR16PC(pLine16); + Red = GET_RED_BGR16PC(pLine16); + Red = (a * SrcRed + mla * Red) >> 8; + Green = (a * SrcGreen + mla * Green) >> 8; + Blue = (a * SrcBlue + mla * Blue) >> 8; + *pLine16 = SET_BLUE_BGR16PC(Blue) + + SET_GREEN_BGR16PC(Green) + + SET_RED_BGR16PC(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += baa->baa_Src->argb_Width; + } + break; + default: + break; + } + UnLockBitMap(handle); + } + else + { + kprintf(__FILE__ "/%s/%ld: Can't lock bitmap\n", __FUNC__, __LINE__); + } + + return 0; +} + +//----------------------------------------------------------------------- + +void BlitTransparentK(struct RastPort *rpBackground, struct RastPort *rpIcon, + ULONG Left, ULONG Top, ULONG Width, ULONG Height, + const struct ARGB *K, + struct ScalosGfxBase *ScalosGfxBase) +{ + struct BlitTransparentKData btk; + struct Rectangle BlitTransparentKRect; + struct Hook BlitTransparentKHook; + + d1(KPrintF(__FILE__ "/%s/%ld: R=%ld G=%ld B=%ld\n", __FUNC__, __LINE__, K->Red, K->Green, K->Blue)); + + btk.btk_K = K; + btk.btk_Width = Width; + btk.btk_Height = Height; + + BlitTransparentKRect.MinX = 0; + BlitTransparentKRect.MinY = 0; + BlitTransparentKRect.MaxX = Width - 1; + BlitTransparentKRect.MaxY = Height - 1; + + SETHOOKFUNC(BlitTransparentKHook, BlitTransparentKHookFunc); + BlitTransparentKHook.h_Data = &btk; + + DoHookClipRects(&BlitTransparentKHook, rpIcon, &BlitTransparentKRect); +} + +//----------------------------------------------------------------------- + +void BlitTransparent(struct RastPort *rpBackground, struct RastPort *rpIcon, + ULONG Left, ULONG Top, ULONG Width, ULONG Height, + ULONG Trans, + struct ScalosGfxBase *ScalosGfxBase) +{ + struct ARGB *BufferBg; + + BufferBg = AllocARGB(Width, Height, ScalosGfxBase); + + if (BufferBg) + { + struct BlitTransparentData bt; + struct Rectangle BlitTransparentRect; + struct Hook BlitTransparentHook; + + d1(KPrintF(__FILE__ "/%s/%ld: Trans=%ld\n", __FUNC__, __LINE__, Trans)); + + // Read background + ReadPixelArray(BufferBg, + 0, 0, + Width * sizeof(struct ARGB), + rpBackground, + Left, Top, + Width, Height, + RECTFMT_ARGB); + + bt.bt_a = Trans + 1; + bt.bt_mla = 257 - bt.bt_a; + + d1(KPrintF(__FILE__ "/%s/%ld: a=%lu mla=%lu\n", __FUNC__, __LINE__, bt.bt_a, bt.bt_mla)); + + if (ALPHA_OPAQUE != bt.bt_a) + { + bt.bt_BufferBg = BufferBg; + bt.bt_Width = Width; + bt.bt_Height = Height; + + BlitTransparentRect.MinX = 0; + BlitTransparentRect.MinY = 0; + BlitTransparentRect.MaxX = Width - 1; + BlitTransparentRect.MaxY = Height - 1; + + SETHOOKFUNC(BlitTransparentHook, BlitTransparentHookFunc); + BlitTransparentHook.h_Data = &bt; + + DoHookClipRects(&BlitTransparentHook, rpIcon, &BlitTransparentRect); + } + + FreeARGB(&BufferBg, ScalosGfxBase); + } +} + +//----------------------------------------------------------------------- + +void BlitTransparentAlpha(struct RastPort *rpBackground, struct RastPort *rpIcon, + ULONG Left, ULONG Top, ULONG Width, ULONG Height, + ULONG Trans, const UBYTE *Alpha, + struct ScalosGfxBase *ScalosGfxBase) +{ + struct ARGB *BufferBg; + + BufferBg = AllocARGB(Width, Height, ScalosGfxBase); + + if (BufferBg) + { + struct BlitTransparentAlphaData bta; + struct Rectangle BlitTransparentAlphaRect; + struct Hook BlitTransparentAlphaHook; + + d1(KPrintF(__FILE__ "/%s/%ld: Trans=%ld\n", __FUNC__, __LINE__, Trans)); + + // Read background + ReadPixelArray(BufferBg, + 0, 0, + Width * sizeof(struct ARGB), + rpBackground, + Left, Top, + Width, Height, + RECTFMT_ARGB); + + bta.bta_BufferBg = BufferBg; + bta.bta_Alpha = Alpha; + bta.bta_Transparency = Trans; + bta.bta_Width = Width; + bta.bta_Height = Height; + + BlitTransparentAlphaRect.MinX = 0; + BlitTransparentAlphaRect.MinY = 0; + BlitTransparentAlphaRect.MaxX = Width - 1; + BlitTransparentAlphaRect.MaxY = Height - 1; + + SETHOOKFUNC(BlitTransparentAlphaHook, BlitTransparentAlphaHookFunc); + BlitTransparentAlphaHook.h_Data = &bta; + + DoHookClipRects(&BlitTransparentAlphaHook, rpIcon, &BlitTransparentAlphaRect); + + FreeARGB(&BufferBg, ScalosGfxBase); + } +} + +//----------------------------------------------------------------------- + +void BlitTransparentAlphaK(struct RastPort *rpBackground, struct RastPort *rpIcon, + ULONG Left, ULONG Top, ULONG Width, ULONG Height, + const struct ARGB *K, const UBYTE *Alpha, + struct ScalosGfxBase *ScalosGfxBase) +{ + struct ARGB *BufferBg; + + BufferBg = AllocARGB(Width, Height, ScalosGfxBase); + + if (BufferBg) + { + struct BlitTransparentAlphaKData btak; + struct Rectangle BlitTransparentAlphaKRect; + struct Hook BlitTransparentAlphaKHook; + + d1(KPrintF(__FILE__ "/%s/%ld: R=%ld G=%ld B=%ld\n", __FUNC__, __LINE__, K->Red, K->Green, K->Blue)); + + // Read background + ReadPixelArray(BufferBg, + 0, 0, + Width * sizeof(struct ARGB), + rpBackground, + Left, Top, + Width, Height, + RECTFMT_ARGB); + + btak.btak_BufferBg = BufferBg; + btak.btak_Alpha = Alpha; + btak.btak_K = K; + btak.btak_Width = Width; + btak.btak_Height = Height; + + BlitTransparentAlphaKRect.MinX = 0; + BlitTransparentAlphaKRect.MinY = 0; + BlitTransparentAlphaKRect.MaxX = Width - 1; + BlitTransparentAlphaKRect.MaxY = Height - 1; + + SETHOOKFUNC(BlitTransparentAlphaKHook, BlitTransparentAlphaKHookFunc); + BlitTransparentAlphaKHook.h_Data = &btak; + + DoHookClipRects(&BlitTransparentAlphaKHook, rpIcon, &BlitTransparentAlphaKRect); + + FreeARGB(&BufferBg, ScalosGfxBase); + } +} + +//----------------------------------------------------------------------- + +static SAVEDS(ULONG) INTERRUPT BlitTransparentKHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct RastPort *rp = (struct RastPort *) o; + struct DoHookClipRectMsg *dhcr = (struct DoHookClipRectMsg *) msg; + struct BlitTransparentKData *btk = (struct BlitTransparentKData *) hook->h_Data; + ULONG PixFmt; + ULONG BytesPerRow; + ULONG BytesPerPixel; + APTR Addr; + APTR handle; + + handle = LockBitMapTags(rp->BitMap, + LBMI_PIXFMT, (ULONG) &PixFmt, + LBMI_BYTESPERROW, (ULONG) &BytesPerRow, + LBMI_BYTESPERPIX, (ULONG) &BytesPerPixel, + LBMI_BASEADDRESS, (ULONG) &Addr, + TAG_END); + + d1(KPrintF(__FILE__ "/%s/%ld: handle=%08lx\n", __FUNC__, __LINE__, handle)); + if (handle) + { + ULONG y; + UBYTE *pPixel = ((UBYTE *) Addr) + BytesPerRow * dhcr->dhcr_Bounds.MinY; + const struct ARGB *K = btk->btk_K; + + d1(KPrintF(__FILE__ "/%s/%ld: MinX=%ld MinY=%ld MaxX=%ld MaxY=%ld\n", __FUNC__, __LINE__, dhcr->dhcr_Bounds.MinX, dhcr->dhcr_Bounds.MinY, dhcr->dhcr_Bounds.MaxX, dhcr->dhcr_Bounds.MaxY)); + d1(KPrintF(__FILE__ "/%s/%ld: dhcr_OffsetX=%ld dhcr_OffsetY=%ld\n", __FUNC__, __LINE__, dhcr->dhcr_OffsetX, dhcr->dhcr_OffsetY)); + d1(KPrintF(__FILE__ "/%s/%ld: BytesPerPixel=%ld BytesPerRow=%ld\n", __FUNC__, __LINE__, BytesPerPixel, BytesPerRow)); + + d1(KPrintF(__FILE__ "/%s/%ld: PixFmt=%lu\n", __FUNC__, __LINE__, PixFmt)); + + switch (PixFmt) + { + case PIXFMT_RGB24: + case PIXFMT_RGBA32: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + Red = pLine[0]; + Green = pLine[1]; + Blue = pLine[2]; + Red = min(255, Red + K->Red); + Green = min(255, Green + K->Green); + Blue = min(255, Blue + K->Blue); + pLine[0] = Red; + pLine[1] = Green; + pLine[2] = Blue; + + pLine += BytesPerPixel; + } + pPixel += BytesPerRow; + } + break; + case PIXFMT_BGR24: + case PIXFMT_BGRA32: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + Red = pLine[2]; + Green = pLine[1]; + Blue = pLine[0]; + Red = min(255, Red + K->Red); + Green = min(255, Green + K->Green); + Blue = min(255, Blue + K->Blue); + pLine[2] = Red; + pLine[1] = Green; + pLine[0] = Blue; + + pLine += BytesPerPixel; + } + pPixel += BytesPerRow; + } + break; + case PIXFMT_ARGB32: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + Red = pLine[1]; + Green = pLine[2]; + Blue = pLine[3]; + Red = min(255, Red + K->Red); + Green = min(255, Green + K->Green); + Blue = min(255, Blue + K->Blue); + pLine[1] = Red; + pLine[2] = Green; + pLine[3] = Blue; + + pLine += BytesPerPixel; + } + pPixel += BytesPerRow; + } + break; + case PIXFMT_RGB16: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + Red = GET_RED_RGB16(pLine16); + Green = GET_GREEN_RGB16(pLine16); + Blue = GET_BLUE_RGB16(pLine16); + Red = min(255, Red + K->Red); + Green = min(255, Green + K->Green); + Blue = min(255, Blue + K->Blue); + *pLine16 = SET_BLUE_RGB16(Blue) + + SET_GREEN_RGB16(Green) + + SET_RED_RGB16(Red); + + pLine += BytesPerPixel; + } + pPixel += BytesPerRow; + } + break; + case PIXFMT_BGR16: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + Red = GET_RED_BGR16(pLine16); + Green = GET_GREEN_BGR16(pLine16); + Blue = GET_BLUE_BGR16(pLine16); + Red = min(255, Red + K->Red); + Green = min(255, Green + K->Green); + Blue = min(255, Blue + K->Blue); + *pLine16 = SET_BLUE_BGR16(Blue) + + SET_GREEN_BGR16(Green) + + SET_RED_BGR16(Red); + + pLine += BytesPerPixel; + } + pPixel += BytesPerRow; + } + break; + case PIXFMT_RGB15: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + Red = GET_RED_RGB15(pLine16); + Green = GET_GREEN_RGB15(pLine16); + Blue = GET_BLUE_RGB15(pLine16); + Red = min(255, Red + K->Red); + Green = min(255, Green + K->Green); + Blue = min(255, Blue + K->Blue); + *pLine16 = SET_BLUE_RGB15(Blue) + + SET_GREEN_RGB15(Green) + + SET_RED_RGB15(Red); + + pLine += BytesPerPixel; + } + pPixel += BytesPerRow; + } + break; + case PIXFMT_BGR15: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + Red = GET_RED_BGR15(pLine16); + Green = GET_GREEN_BGR15(pLine16); + Blue = GET_BLUE_BGR15(pLine16); + Red = min(255, Red + K->Red); + Green = min(255, Green + K->Green); + Blue = min(255, Blue + K->Blue); + *pLine16 = SET_BLUE_BGR15(Blue) + + SET_GREEN_BGR15(Green) + + SET_RED_BGR15(Red); + + pLine += BytesPerPixel; + } + pPixel += BytesPerRow; + } + break; + case PIXFMT_RGB15PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + Red = GET_RED_RGB15PC(pLine16); + Green = GET_GREEN_RGB15PC(pLine16); + Blue = GET_BLUE_RGB15PC(pLine16); + Red = min(255, Red + K->Red); + Green = min(255, Green + K->Green); + Blue = min(255, Blue + K->Blue); + *pLine16 = SET_BLUE_RGB15PC(Blue) + + SET_GREEN_RGB15PC(Green) + + SET_RED_RGB15PC(Red); + + pLine += BytesPerPixel; + } + pPixel += BytesPerRow; + } + break; + case PIXFMT_BGR15PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + Red = GET_RED_BGR15PC(pLine16); + Green = GET_GREEN_BGR15PC(pLine16); + Blue = GET_BLUE_BGR15PC(pLine16); + Red = min(255, Red + K->Red); + Green = min(255, Green + K->Green); + Blue = min(255, Blue + K->Blue); + *pLine16 = SET_BLUE_BGR15PC(Blue) + + SET_GREEN_BGR15PC(Green) + + SET_RED_BGR15PC(Red); + + pLine += BytesPerPixel; + } + pPixel += BytesPerRow; + } + break; + case PIXFMT_RGB16PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + Red = GET_RED_RGB16PC(pLine16); + Green = GET_GREEN_RGB16PC(pLine16); + Blue = GET_BLUE_RGB16PC(pLine16); + Red = min(255, Red + K->Red); + Green = min(255, Green + K->Green); + Blue = min(255, Blue + K->Blue); + *pLine16 = SET_BLUE_RGB16PC(Blue) + + SET_GREEN_RGB16PC(Green) + + SET_RED_RGB16PC(Red); + + pLine += BytesPerPixel; + } + pPixel += BytesPerRow; + } + break; + case PIXFMT_BGR16PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + Red = GET_RED_BGR16PC(pLine16); + Green = GET_GREEN_BGR16PC(pLine16); + Blue = GET_BLUE_BGR16PC(pLine16); + Red = min(255, Red + K->Red); + Green = min(255, Green + K->Green); + Blue = min(255, Blue + K->Blue); + *pLine16 = SET_BLUE_BGR16PC(Blue) + + SET_GREEN_BGR16PC(Green) + + SET_RED_BGR16PC(Red); + + pLine += BytesPerPixel; + } + pPixel += BytesPerRow; + } + break; + default: + break; + } + UnLockBitMap(handle); + } + else + { + kprintf(__FILE__ "/%s/%ld: Can't lock bitmap\n", __FUNC__, __LINE__); + } + + return 0; +} + +//----------------------------------------------------------------------- + +static SAVEDS(ULONG) INTERRUPT BlitTransparentHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct RastPort *rp = (struct RastPort *) o; + struct DoHookClipRectMsg *dhcr = (struct DoHookClipRectMsg *) msg; + struct BlitTransparentData *bt = (struct BlitTransparentData *) hook->h_Data; + ULONG PixFmt; + ULONG BytesPerRow; + ULONG BytesPerPixel; + APTR Addr; + APTR handle; + + handle = LockBitMapTags(rp->BitMap, + LBMI_PIXFMT, (ULONG) &PixFmt, + LBMI_BYTESPERROW, (ULONG) &BytesPerRow, + LBMI_BYTESPERPIX, (ULONG) &BytesPerPixel, + LBMI_BASEADDRESS, (ULONG) &Addr, + TAG_END); + + d1(KPrintF(__FILE__ "/%s/%ld: handle=%08lx\n", __FUNC__, __LINE__, handle)); + if (handle) + { + ULONG a = bt->bt_a; + ULONG mla = bt->bt_mla; + ULONG y; + const struct ARGB *Src = bt->bt_BufferBg + dhcr->dhcr_OffsetY * bt->bt_Width; + UBYTE *pPixel = ((UBYTE *) Addr) + BytesPerRow * dhcr->dhcr_Bounds.MinY; + + d1(KPrintF(__FILE__ "/%s/%ld: MinX=%ld MinY=%ld MaxX=%ld MaxY=%ld\n", __FUNC__, __LINE__, dhcr->dhcr_Bounds.MinX, dhcr->dhcr_Bounds.MinY, dhcr->dhcr_Bounds.MaxX, dhcr->dhcr_Bounds.MaxY)); + d1(KPrintF(__FILE__ "/%s/%ld: dhcr_OffsetX=%ld dhcr_OffsetY=%ld\n", __FUNC__, __LINE__, dhcr->dhcr_OffsetX, dhcr->dhcr_OffsetY)); + d1(KPrintF(__FILE__ "/%s/%ld: BytesPerPixel=%ld BytesPerRow=%ld\n", __FUNC__, __LINE__, BytesPerPixel, BytesPerRow)); + + d1(KPrintF(__FILE__ "/%s/%ld: PixFmt=%lu\n", __FUNC__, __LINE__, PixFmt)); + + switch (PixFmt) + { + case PIXFMT_RGB24: + case PIXFMT_RGBA32: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + Red = pLine[0]; + Green = pLine[1]; + Blue = pLine[2]; + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + pLine[0] = Red; + pLine[1] = Green; + pLine[2] = Blue; + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += bt->bt_Width; + } + break; + case PIXFMT_BGR24: + case PIXFMT_BGRA32: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + Red = pLine[2]; + Green = pLine[1]; + Blue = pLine[0]; + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + pLine[2] = Red; + pLine[1] = Green; + pLine[0] = Blue; + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += bt->bt_Width; + } + break; + case PIXFMT_ARGB32: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + Red = pLine[1]; + Green = pLine[2]; + Blue = pLine[3]; + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + pLine[1] = Red; + pLine[2] = Green; + pLine[3] = Blue; + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += bt->bt_Width; + } + break; + case PIXFMT_RGB16: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + Red = GET_RED_RGB16(pLine16); + Green = GET_GREEN_RGB16(pLine16); + Blue = GET_BLUE_RGB16(pLine16); + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + *pLine16 = SET_BLUE_RGB16(Blue) + + SET_GREEN_RGB16(Green) + + SET_RED_RGB16(Red); + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += bt->bt_Width; + } + break; + case PIXFMT_BGR16: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + Red = GET_RED_BGR16(pLine16); + Green = GET_GREEN_BGR16(pLine16); + Blue = GET_BLUE_BGR16(pLine16); + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + *pLine16 = SET_BLUE_BGR16(Blue) + + SET_GREEN_BGR16(Green) + + SET_RED_BGR16(Red); + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += bt->bt_Width; + } + break; + case PIXFMT_RGB15: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + Red = GET_RED_RGB15(pLine16); + Green = GET_GREEN_RGB15(pLine16); + Blue = GET_BLUE_RGB15(pLine16); + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + *pLine16 = SET_BLUE_RGB15(Blue) + + SET_GREEN_RGB15(Green) + + SET_RED_RGB15(Red); + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += bt->bt_Width; + } + break; + case PIXFMT_BGR15: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + Red = GET_RED_BGR15(pLine16); + Green = GET_GREEN_BGR15(pLine16); + Blue = GET_BLUE_BGR15(pLine16); + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + *pLine16 = SET_BLUE_BGR15(Blue) + + SET_GREEN_BGR15(Green) + + SET_RED_BGR15(Red); + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += bt->bt_Width; + } + break; + case PIXFMT_RGB15PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + Red = GET_RED_RGB15PC(pLine16); + Green = GET_GREEN_RGB15PC(pLine16); + Blue = GET_BLUE_RGB15PC(pLine16); + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + *pLine16 = SET_BLUE_RGB15PC(Blue) + + SET_GREEN_RGB15PC(Green) + + SET_RED_RGB15PC(Red); + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += bt->bt_Width; + } + break; + case PIXFMT_BGR15PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + Red = GET_RED_BGR15PC(pLine16); + Green = GET_GREEN_BGR15PC(pLine16); + Blue = GET_BLUE_BGR15PC(pLine16); + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + *pLine16 = SET_BLUE_BGR15PC(Blue) + + SET_GREEN_BGR15PC(Green) + + SET_RED_BGR15PC(Red); + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += bt->bt_Width; + } + break; + case PIXFMT_RGB16PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + Red = GET_RED_RGB16PC(pLine16); + Green = GET_GREEN_RGB16PC(pLine16); + Blue = GET_BLUE_RGB16PC(pLine16); + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + *pLine16 = SET_BLUE_RGB16PC(Blue) + + SET_GREEN_RGB16PC(Green) + + SET_RED_RGB16PC(Red); + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += bt->bt_Width; + } + break; + case PIXFMT_BGR16PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + Red = GET_RED_BGR16PC(pLine16); + Green = GET_GREEN_BGR16PC(pLine16); + Blue = GET_BLUE_BGR16PC(pLine16); + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + *pLine16 = SET_BLUE_BGR16PC(Blue) + + SET_GREEN_BGR16PC(Green) + + SET_RED_BGR16PC(Red); + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += bt->bt_Width; + } + break; + default: + break; + } + UnLockBitMap(handle); + } + else + { + LONG width; + LONG height; + + d1(KPrintF(__FILE__ "/%s/%ld: MinX=%ld MinY=%ld MaxX=%ld MaxY=%ld\n", __FUNC__, __LINE__, dhcr->dhcr_Bounds.MinX, dhcr->dhcr_Bounds.MinY, dhcr->dhcr_Bounds.MaxX, dhcr->dhcr_Bounds.MaxY)); + d1(KPrintF(__FILE__ "/%s/%ld: dhcr_OffsetX=%ld dhcr_OffsetY=%ld\n", __FUNC__, __LINE__, dhcr->dhcr_OffsetX, dhcr->dhcr_OffsetY)); + d1(KPrintF(__FILE__ "/%s/%ld: BytesPerPixel=%ld BytesPerRow=%ld\n", __FUNC__, __LINE__, BytesPerPixel, BytesPerRow)); + + d1(KPrintF(__FILE__ "/%s/%ld: bt_BufferBg=%p\n", __FUNC__, __LINE__, bt->bt_BufferBg)); + d1(KPrintF(__FILE__ "/%s/%ld: bt_a=%ld bt_mla=%ld\n", __FUNC__, __LINE__, bt->bt_a, bt->bt_mla)); + d1(KPrintF(__FILE__ "/%s/%ld: bt_Width=%ld bt_Height=%ld\n", __FUNC__, __LINE__, bt->bt_Width, bt->bt_Height)); + + width = dhcr->dhcr_Bounds.MaxX - dhcr->dhcr_Bounds.MinX + 1; + height = dhcr->dhcr_Bounds.MaxY - dhcr->dhcr_Bounds.MinY + 1; + if (width > 0 && height > 0) + { + BytesPerPixel = 3; + BytesPerRow = BytesPerPixel * width; + Addr = AllocVec(BytesPerRow * height, MEMF_ANY); + if (Addr && width > 0 && height > 0) + { + ULONG a = bt->bt_a; + ULONG mla = bt->bt_mla; + ULONG y; + const struct ARGB *Src = bt->bt_BufferBg + dhcr->dhcr_OffsetY * bt->bt_Width; + UBYTE *pPixel = ((UBYTE *) Addr) + BytesPerRow * dhcr->dhcr_Bounds.MinY; + + ReadPixelArray(Addr, 0, 0, BytesPerRow, rp, + 0, 0, + width, height, + RECTFMT_RGB); + + for (y = 0; y < height; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = 0; x < width; x++) + { + Red = pLine[0]; + Green = pLine[1]; + Blue = pLine[2]; + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + pLine[0] = Red; + pLine[1] = Green; + pLine[2] = Blue; + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + Src += bt->bt_Width; + } + WritePixelArray(Addr, 0, 0, BytesPerRow, rp, + 0, 0, + width, height, + RECTFMT_RGB); + FreeVec(Addr); + } + } + } + + return 0; +} + +//----------------------------------------------------------------------- + +static SAVEDS(ULONG) INTERRUPT BlitTransparentAlphaHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct RastPort *rp = (struct RastPort *) o; + struct DoHookClipRectMsg *dhcr = (struct DoHookClipRectMsg *) msg; + struct BlitTransparentAlphaData *bta = (struct BlitTransparentAlphaData *) hook->h_Data; + ULONG PixFmt; + ULONG BytesPerRow; + ULONG BytesPerPixel; + APTR Addr; + APTR handle; + + handle = LockBitMapTags(rp->BitMap, + LBMI_PIXFMT, (ULONG) &PixFmt, + LBMI_BYTESPERROW, (ULONG) &BytesPerRow, + LBMI_BYTESPERPIX, (ULONG) &BytesPerPixel, + LBMI_BASEADDRESS, (ULONG) &Addr, + TAG_END); + + d1(KPrintF(__FILE__ "/%s/%ld: handle=%08lx\n", __FUNC__, __LINE__, handle)); + if (handle) + { + ULONG a; + ULONG mla; + ULONG y; + const struct ARGB *Src = bta->bta_BufferBg + dhcr->dhcr_OffsetY * bta->bta_Width; + const UBYTE *pAlpha = bta->bta_Alpha + dhcr->dhcr_OffsetY * bta->bta_Width; + UBYTE *pPixel = ((UBYTE *) Addr) + BytesPerRow * dhcr->dhcr_Bounds.MinY; + ULONG Trans = bta->bta_Transparency; + + d1(KPrintF(__FILE__ "/%s/%ld: MinX=%ld MinY=%ld MaxX=%ld MaxY=%ld\n", __FUNC__, __LINE__, dhcr->dhcr_Bounds.MinX, dhcr->dhcr_Bounds.MinY, dhcr->dhcr_Bounds.MaxX, dhcr->dhcr_Bounds.MaxY)); + d1(KPrintF(__FILE__ "/%s/%ld: dhcr_OffsetX=%ld dhcr_OffsetY=%ld\n", __FUNC__, __LINE__, dhcr->dhcr_OffsetX, dhcr->dhcr_OffsetY)); + d1(KPrintF(__FILE__ "/%s/%ld: BytesPerPixel=%ld BytesPerRow=%ld\n", __FUNC__, __LINE__, BytesPerPixel, BytesPerRow)); + + d1(KPrintF(__FILE__ "/%s/%ld: PixFmt=%lu\n", __FUNC__, __LINE__, PixFmt)); + + switch (PixFmt) + { + case PIXFMT_RGB24: + case PIXFMT_RGBA32: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + const UBYTE *pLineAlpha = pAlpha + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + a = (ULONG) *pLineAlpha++; + a = ((Trans * a) >> 8) + 1; + + switch (a) + { + case 0: + case 1: + pLine[0] = SrcPtr->Red; + pLine[1] = SrcPtr->Green; + pLine[2] = SrcPtr->Blue; + break; + case ALPHA_OPAQUE: + break; + default: + mla = 257 - a; + + Red = pLine[0]; + Green = pLine[1]; + Blue = pLine[2]; + + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + + pLine[0] = Red; + pLine[1] = Green; + pLine[2] = Blue; + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + pAlpha += bta->bta_Width; + Src += bta->bta_Width; + } + break; + case PIXFMT_BGR24: + case PIXFMT_BGRA32: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + const UBYTE *pLineAlpha = pAlpha + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + a = (ULONG) *pLineAlpha++; + a = ((Trans * a) >> 8) + 1; + + switch (a) + { + case 0: + case 1: + pLine[2] = SrcPtr->Red; + pLine[1] = SrcPtr->Green; + pLine[0] = SrcPtr->Blue; + break; + case ALPHA_OPAQUE: + break; + default: + mla = 257 - a; + + Red = pLine[2]; + Green = pLine[1]; + Blue = pLine[0]; + + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + + pLine[2] = Red; + pLine[1] = Green; + pLine[0] = Blue; + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + pAlpha += bta->bta_Width; + Src += bta->bta_Width; + } + break; + case PIXFMT_ARGB32: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + const UBYTE *pLineAlpha = pAlpha + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + a = (ULONG) *pLineAlpha++; + a = ((Trans * a) >> 8) + 1; + + switch (a) + { + case 0: + case 1: + pLine[1] = SrcPtr->Red; + pLine[2] = SrcPtr->Green; + pLine[3] = SrcPtr->Blue; + break; + case ALPHA_OPAQUE: + break; + default: + mla = 257 - a; + + Red = pLine[1]; + Green = pLine[2]; + Blue = pLine[3]; + + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + + pLine[1] = Red; + pLine[2] = Green; + pLine[3] = Blue; + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + pAlpha += bta->bta_Width; + Src += bta->bta_Width; + } + break; + case PIXFMT_RGB16: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + const UBYTE *pLineAlpha = pAlpha + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + a = (ULONG) *pLineAlpha++; + a = ((Trans * a) >> 8) + 1; + + switch (a) + { + case 0: + case 1: + *pLine16 = SET_BLUE_RGB16(SrcPtr->Blue) + + SET_GREEN_RGB16(SrcPtr->Green) + + SET_RED_RGB16(SrcPtr->Red); + break; + case ALPHA_OPAQUE: + break; + default: + mla = 257 - a; + + Red = GET_RED_RGB16(pLine16); + Green = GET_GREEN_RGB16(pLine16); + Blue = GET_BLUE_RGB16(pLine16); + + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + + *pLine16 = SET_BLUE_RGB16(Blue) + + SET_GREEN_RGB16(Green) + + SET_RED_RGB16(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + pAlpha += bta->bta_Width; + Src += bta->bta_Width; + } + break; + case PIXFMT_BGR16: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + const UBYTE *pLineAlpha = pAlpha + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + a = (ULONG) *pLineAlpha++; + a = ((Trans * a) >> 8) + 1; + + switch (a) + { + case 0: + case 1: + *pLine16 = SET_BLUE_BGR16(SrcPtr->Blue) + + SET_GREEN_BGR16(SrcPtr->Green) + + SET_RED_BGR16(SrcPtr->Red); + break; + case ALPHA_OPAQUE: + break; + default: + mla = 257 - a; + + Red = GET_RED_BGR16(pLine16); + Green = GET_GREEN_BGR16(pLine16); + Blue = GET_BLUE_BGR16(pLine16); + + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + + *pLine16 = SET_BLUE_BGR16(Blue) + + SET_GREEN_BGR16(Green) + + SET_RED_BGR16(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + pAlpha += bta->bta_Width; + Src += bta->bta_Width; + } + break; + case PIXFMT_RGB15: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + const UBYTE *pLineAlpha = pAlpha + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + a = (ULONG) *pLineAlpha++; + a = ((Trans * a) >> 8) + 1; + + switch (a) + { + case 0: + case 1: + *pLine16 = SET_BLUE_RGB15(SrcPtr->Blue) + + SET_GREEN_RGB15(SrcPtr->Green) + + SET_RED_RGB15(SrcPtr->Red); + break; + case ALPHA_OPAQUE: + break; + default: + mla = 257 - a; + + Red = GET_RED_RGB15(pLine16); + Green = GET_GREEN_RGB15(pLine16); + Blue = GET_BLUE_RGB15(pLine16); + + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + + *pLine16 = SET_BLUE_RGB15(Blue) + + SET_GREEN_RGB15(Green) + + SET_RED_RGB15(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + pAlpha += bta->bta_Width; + Src += bta->bta_Width; + } + break; + case PIXFMT_BGR15: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + const UBYTE *pLineAlpha = pAlpha + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + a = (ULONG) *pLineAlpha++; + a = ((Trans * a) >> 8) + 1; + + switch (a) + { + case 0: + case 1: + *pLine16 = SET_BLUE_BGR15(SrcPtr->Blue) + + SET_GREEN_BGR15(SrcPtr->Green) + + SET_RED_BGR15(SrcPtr->Red); + break; + case ALPHA_OPAQUE: + break; + default: + mla = 257 - a; + + Red = GET_RED_BGR15(pLine16); + Green = GET_GREEN_BGR15(pLine16); + Blue = GET_BLUE_BGR15(pLine16); + + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + + *pLine16 = SET_BLUE_BGR15(Blue) + + SET_GREEN_BGR15(Green) + + SET_RED_BGR15(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + pAlpha += bta->bta_Width; + Src += bta->bta_Width; + } + break; + case PIXFMT_RGB15PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + const UBYTE *pLineAlpha = pAlpha + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + a = (ULONG) *pLineAlpha++; + a = ((Trans * a) >> 8) + 1; + + switch (a) + { + case 0: + case 1: + *pLine16 = SET_BLUE_RGB15PC(SrcPtr->Blue) + + SET_GREEN_RGB15PC(SrcPtr->Green) + + SET_RED_RGB15PC(SrcPtr->Red); + break; + case ALPHA_OPAQUE: + break; + default: + mla = 257 - a; + + Red = GET_RED_RGB15PC(pLine16); + Green = GET_GREEN_RGB15PC(pLine16); + Blue = GET_BLUE_RGB15PC(pLine16); + + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + + *pLine16 = SET_BLUE_RGB15PC(Blue) + + SET_GREEN_RGB15PC(Green) + + SET_RED_RGB15PC(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + pAlpha += bta->bta_Width; + Src += bta->bta_Width; + } + break; + case PIXFMT_BGR15PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + const UBYTE *pLineAlpha = pAlpha + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + a = (ULONG) *pLineAlpha++; + a = ((Trans * a) >> 8) + 1; + + switch (a) + { + case 0: + case 1: + *pLine16 = SET_BLUE_BGR15PC(SrcPtr->Blue) + + SET_GREEN_BGR15PC(SrcPtr->Green) + + SET_RED_BGR15PC(SrcPtr->Red); + break; + case ALPHA_OPAQUE: + break; + default: + mla = 257 - a; + + Red = GET_RED_BGR15PC(pLine16); + Green = GET_GREEN_BGR15PC(pLine16); + Blue = GET_BLUE_BGR15PC(pLine16); + + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + + *pLine16 = SET_BLUE_BGR15PC(Blue) + + SET_GREEN_BGR15PC(Green) + + SET_RED_BGR15PC(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + pAlpha += bta->bta_Width; + Src += bta->bta_Width; + } + break; + case PIXFMT_RGB16PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + const UBYTE *pLineAlpha = pAlpha + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + a = (ULONG) *pLineAlpha++; + a = ((Trans * a) >> 8) + 1; + + switch (a) + { + case 0: + case 1: + *pLine16 = SET_BLUE_RGB16PC(SrcPtr->Blue) + + SET_GREEN_RGB16PC(SrcPtr->Green) + + SET_RED_RGB16PC(SrcPtr->Red); + break; + case ALPHA_OPAQUE: + break; + default: + mla = 257 - a; + + Red = GET_RED_RGB16PC(pLine16); + Green = GET_GREEN_RGB16PC(pLine16); + Blue = GET_BLUE_RGB16PC(pLine16); + + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + + *pLine16 = SET_BLUE_RGB16PC(Blue) + + SET_GREEN_RGB16PC(Green) + + SET_RED_RGB16PC(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + pAlpha += bta->bta_Width; + Src += bta->bta_Width; + } + break; + case PIXFMT_BGR16PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + const UBYTE *pLineAlpha = pAlpha + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + a = (ULONG) *pLineAlpha++; + a = ((Trans * a) >> 8) + 1; + + switch (a) + { + case 0: + case 1: + *pLine16 = SET_BLUE_BGR16PC(SrcPtr->Blue) + + SET_GREEN_BGR16PC(SrcPtr->Green) + + SET_RED_BGR16PC(SrcPtr->Red); + break; + case ALPHA_OPAQUE: + break; + default: + mla = 257 - a; + + Red = GET_RED_BGR16PC(pLine16); + Green = GET_GREEN_BGR16PC(pLine16); + Blue = GET_BLUE_BGR16PC(pLine16); + + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + + *pLine16 = SET_BLUE_BGR16PC(Blue) + + SET_GREEN_BGR16PC(Green) + + SET_RED_BGR16PC(Red); + break; + } + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + pAlpha += bta->bta_Width; + Src += bta->bta_Width; + } + break; + default: + break; + } + UnLockBitMap(handle); + } + else + { + kprintf(__FILE__ "/%s/%ld: Can't lock bitmap\n", __FUNC__, __LINE__); + } + + return 0; +} + +//----------------------------------------------------------------------- + +static SAVEDS(ULONG) INTERRUPT BlitTransparentAlphaKHookFunc(struct Hook *hook, Object *o, Msg msg) +{ + struct RastPort *rp = (struct RastPort *) o; + struct DoHookClipRectMsg *dhcr = (struct DoHookClipRectMsg *) msg; + struct BlitTransparentAlphaKData *btak = (struct BlitTransparentAlphaKData *) hook->h_Data; + ULONG PixFmt; + ULONG BytesPerRow; + ULONG BytesPerPixel; + APTR Addr; + APTR handle; + + handle = LockBitMapTags(rp->BitMap, + LBMI_PIXFMT, (ULONG) &PixFmt, + LBMI_BYTESPERROW, (ULONG) &BytesPerRow, + LBMI_BYTESPERPIX, (ULONG) &BytesPerPixel, + LBMI_BASEADDRESS, (ULONG) &Addr, + TAG_END); + + d1(KPrintF(__FILE__ "/%s/%ld: handle=%08lx\n", __FUNC__, __LINE__, handle)); + if (handle) + { + ULONG a; + ULONG mla; + ULONG y; + const struct ARGB *Src = btak->btak_BufferBg + dhcr->dhcr_OffsetY * btak->btak_Width; + const UBYTE *pAlpha = btak->btak_Alpha + dhcr->dhcr_OffsetY * btak->btak_Width; + UBYTE *pPixel = ((UBYTE *) Addr) + BytesPerRow * dhcr->dhcr_Bounds.MinY; + const struct ARGB *K = btak->btak_K; + + d1(KPrintF(__FILE__ "/%s/%ld: MinX=%ld MinY=%ld MaxX=%ld MaxY=%ld\n", __FUNC__, __LINE__, dhcr->dhcr_Bounds.MinX, dhcr->dhcr_Bounds.MinY, dhcr->dhcr_Bounds.MaxX, dhcr->dhcr_Bounds.MaxY)); + d1(KPrintF(__FILE__ "/%s/%ld: dhcr_OffsetX=%ld dhcr_OffsetY=%ld\n", __FUNC__, __LINE__, dhcr->dhcr_OffsetX, dhcr->dhcr_OffsetY)); + d1(KPrintF(__FILE__ "/%s/%ld: BytesPerPixel=%ld BytesPerRow=%ld\n", __FUNC__, __LINE__, BytesPerPixel, BytesPerRow)); + + d1(KPrintF(__FILE__ "/%s/%ld: PixFmt=%lu\n", __FUNC__, __LINE__, PixFmt)); + + switch (PixFmt) + { + case PIXFMT_RGB24: + case PIXFMT_RGBA32: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + const UBYTE *pLineAlpha = pAlpha + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + a = (ULONG) *pLineAlpha++; + + Red = pLine[0]; + Green = pLine[1]; + Blue = pLine[2]; + + Red = min(0xff, Red + K->Red); + Green = min(0xff, Green + K->Green); + Blue = min(0xff, Blue + K->Blue); + + switch (a) + { + case 0: + case 1: + Red = SrcPtr->Red; + Green = SrcPtr->Green; + Blue = SrcPtr->Blue; + break; + case ALPHA_OPAQUE: + break; + default: + mla = 257 - a; + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + break; + } + + pLine[1] = Red; + pLine[1] = Green; + pLine[2] = Blue; + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + pAlpha += btak->btak_Width; + Src += btak->btak_Width; + } + break; + case PIXFMT_BGR24: + case PIXFMT_BGRA32: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + const UBYTE *pLineAlpha = pAlpha + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + a = (ULONG) *pLineAlpha++; + + Red = pLine[2]; + Green = pLine[1]; + Blue = pLine[0]; + + Red = min(0xff, Red + K->Red); + Green = min(0xff, Green + K->Green); + Blue = min(0xff, Blue + K->Blue); + + switch (a) + { + case 0: + case 1: + Red = SrcPtr->Red; + Green = SrcPtr->Green; + Blue = SrcPtr->Blue; + break; + case ALPHA_OPAQUE: + break; + default: + mla = 257 - a; + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + break; + } + + pLine[2] = Red; + pLine[1] = Green; + pLine[0] = Blue; + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + pAlpha += btak->btak_Width; + Src += btak->btak_Width; + } + break; + case PIXFMT_ARGB32: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + const UBYTE *pLineAlpha = pAlpha + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + a = (ULONG) *pLineAlpha++; + + Red = pLine[1]; + Green = pLine[2]; + Blue = pLine[3]; + + Red = min(0xff, Red + K->Red); + Green = min(0xff, Green + K->Green); + Blue = min(0xff, Blue + K->Blue); + + switch (a) + { + case 0: + case 1: + Red = SrcPtr->Red; + Green = SrcPtr->Green; + Blue = SrcPtr->Blue; + break; + case ALPHA_OPAQUE: + break; + default: + mla = 257 - a; + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + break; + } + + pLine[1] = Red; + pLine[2] = Green; + pLine[3] = Blue; + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + pAlpha += btak->btak_Width; + Src += btak->btak_Width; + } + break; + case PIXFMT_RGB16: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + const UBYTE *pLineAlpha = pAlpha + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + a = (ULONG) *pLineAlpha++; + + Red = GET_RED_RGB16(pLine16); + Green = GET_GREEN_RGB16(pLine16); + Blue = GET_BLUE_RGB16(pLine16); + + Red = min(0xff, Red + K->Red); + Green = min(0xff, Green + K->Green); + Blue = min(0xff, Blue + K->Blue); + + switch (a) + { + case 0: + case 1: + Red = SrcPtr->Red; + Green = SrcPtr->Green; + Blue = SrcPtr->Blue; + break; + case ALPHA_OPAQUE: + break; + default: + mla = 257 - a; + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + break; + } + + *pLine16 = SET_BLUE_RGB16(Blue) + + SET_GREEN_RGB16(Green) + + SET_RED_RGB16(Red); + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + pAlpha += btak->btak_Width; + Src += btak->btak_Width; + } + break; + case PIXFMT_BGR16: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + const UBYTE *pLineAlpha = pAlpha + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + a = (ULONG) *pLineAlpha++; + + Red = GET_RED_BGR16(pLine16); + Green = GET_GREEN_BGR16(pLine16); + Blue = GET_BLUE_BGR16(pLine16); + + Red = min(0xff, Red + K->Red); + Green = min(0xff, Green + K->Green); + Blue = min(0xff, Blue + K->Blue); + + switch (a) + { + case 0: + case 1: + Red = SrcPtr->Red; + Green = SrcPtr->Green; + Blue = SrcPtr->Blue; + break; + case ALPHA_OPAQUE: + break; + default: + mla = 257 - a; + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + break; + } + + *pLine16 = SET_BLUE_BGR16(Blue) + + SET_GREEN_BGR16(Green) + + SET_RED_BGR16(Red); + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + pAlpha += btak->btak_Width; + Src += btak->btak_Width; + } + break; + case PIXFMT_RGB15: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + const UBYTE *pLineAlpha = pAlpha + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + a = (ULONG) *pLineAlpha++; + + Red = GET_RED_RGB15(pLine16); + Green = GET_GREEN_RGB15(pLine16); + Blue = GET_BLUE_RGB15(pLine16); + + Red = min(0xff, Red + K->Red); + Green = min(0xff, Green + K->Green); + Blue = min(0xff, Blue + K->Blue); + + switch (a) + { + case 0: + case 1: + Red = SrcPtr->Red; + Green = SrcPtr->Green; + Blue = SrcPtr->Blue; + break; + case ALPHA_OPAQUE: + break; + default: + mla = 257 - a; + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + break; + } + + *pLine16 = SET_BLUE_RGB15(Blue) + + SET_GREEN_RGB15(Green) + + SET_RED_RGB15(Red); + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + pAlpha += btak->btak_Width; + Src += btak->btak_Width; + } + break; + case PIXFMT_BGR15: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + const UBYTE *pLineAlpha = pAlpha + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + a = (ULONG) *pLineAlpha++; + + Red = GET_RED_BGR15(pLine16); + Green = GET_GREEN_BGR15(pLine16); + Blue = GET_BLUE_BGR15(pLine16); + + Red = min(0xff, Red + K->Red); + Green = min(0xff, Green + K->Green); + Blue = min(0xff, Blue + K->Blue); + + switch (a) + { + case 0: + case 1: + Red = SrcPtr->Red; + Green = SrcPtr->Green; + Blue = SrcPtr->Blue; + break; + case ALPHA_OPAQUE: + break; + default: + mla = 257 - a; + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + break; + } + + *pLine16 = SET_BLUE_BGR15(Blue) + + SET_GREEN_BGR15(Green) + + SET_RED_BGR15(Red); + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + pAlpha += btak->btak_Width; + Src += btak->btak_Width; + } + break; + case PIXFMT_RGB15PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + const UBYTE *pLineAlpha = pAlpha + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + a = (ULONG) *pLineAlpha++; + + Red = GET_RED_RGB15PC(pLine16); + Green = GET_GREEN_RGB15PC(pLine16); + Blue = GET_BLUE_RGB15PC(pLine16); + + Red = min(0xff, Red + K->Red); + Green = min(0xff, Green + K->Green); + Blue = min(0xff, Blue + K->Blue); + + switch (a) + { + case 0: + case 1: + Red = SrcPtr->Red; + Green = SrcPtr->Green; + Blue = SrcPtr->Blue; + break; + case ALPHA_OPAQUE: + break; + default: + mla = 257 - a; + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + break; + } + + *pLine16 = SET_BLUE_RGB15PC(Blue) + + SET_GREEN_RGB15PC(Green) + + SET_RED_RGB15PC(Red); + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + pAlpha += btak->btak_Width; + Src += btak->btak_Width; + } + break; + case PIXFMT_BGR15PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + const UBYTE *pLineAlpha = pAlpha + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + a = (ULONG) *pLineAlpha++; + + Red = GET_RED_BGR15PC(pLine16); + Green = GET_GREEN_BGR15PC(pLine16); + Blue = GET_BLUE_BGR15PC(pLine16); + + Red = min(0xff, Red + K->Red); + Green = min(0xff, Green + K->Green); + Blue = min(0xff, Blue + K->Blue); + + switch (a) + { + case 0: + case 1: + Red = SrcPtr->Red; + Green = SrcPtr->Green; + Blue = SrcPtr->Blue; + break; + case ALPHA_OPAQUE: + break; + default: + mla = 257 - a; + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + break; + } + + *pLine16 = SET_BLUE_BGR15PC(Blue) + + SET_GREEN_BGR15PC(Green) + + SET_RED_BGR15PC(Red); + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + pAlpha += btak->btak_Width; + Src += btak->btak_Width; + } + break; + case PIXFMT_RGB16PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + const UBYTE *pLineAlpha = pAlpha + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + a = (ULONG) *pLineAlpha++; + + Red = GET_RED_RGB16PC(pLine16); + Green = GET_GREEN_RGB16PC(pLine16); + Blue = GET_BLUE_RGB16PC(pLine16); + + Red = min(0xff, Red + K->Red); + Green = min(0xff, Green + K->Green); + Blue = min(0xff, Blue + K->Blue); + + switch (a) + { + case 0: + case 1: + Red = SrcPtr->Red; + Green = SrcPtr->Green; + Blue = SrcPtr->Blue; + break; + case ALPHA_OPAQUE: + break; + default: + mla = 257 - a; + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + break; + } + + *pLine16 = SET_BLUE_RGB16PC(Blue) + + SET_GREEN_RGB16PC(Green) + + SET_RED_RGB16PC(Red); + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + pAlpha += btak->btak_Width; + Src += btak->btak_Width; + } + break; + case PIXFMT_BGR16PC: + for (y = dhcr->dhcr_Bounds.MinY; y <= dhcr->dhcr_Bounds.MaxY; y++) + { + ULONG x; + UBYTE *pLine = pPixel + dhcr->dhcr_Bounds.MinX * BytesPerPixel; + const struct ARGB *SrcPtr = Src + dhcr->dhcr_OffsetX; + const UBYTE *pLineAlpha = pAlpha + dhcr->dhcr_OffsetX; + UWORD Red, Green, Blue; + + for (x = dhcr->dhcr_Bounds.MinX; x <= dhcr->dhcr_Bounds.MaxX; x++) + { + UWORD *pLine16 = (UWORD *) pLine; + + a = (ULONG) *pLineAlpha++; + + Red = GET_RED_BGR16PC(pLine16); + Green = GET_GREEN_BGR16PC(pLine16); + Blue = GET_BLUE_BGR16PC(pLine16); + + Red = min(0xff, Red + K->Red); + Green = min(0xff, Green + K->Green); + Blue = min(0xff, Blue + K->Blue); + + switch (a) + { + case 0: + case 1: + Red = SrcPtr->Red; + Green = SrcPtr->Green; + Blue = SrcPtr->Blue; + break; + case ALPHA_OPAQUE: + break; + default: + mla = 257 - a; + Red = (SrcPtr->Red * mla + Red * a) >> 8; + Green = (SrcPtr->Green * mla + Green * a) >> 8 ; + Blue = (SrcPtr->Blue * mla + Blue * a) >> 8; + break; + } + + *pLine16 = SET_BLUE_BGR16PC(Blue) + + SET_GREEN_BGR16PC(Green) + + SET_RED_BGR16PC(Red); + + pLine += BytesPerPixel; + SrcPtr++; + } + pPixel += BytesPerRow; + pAlpha += btak->btak_Width; + Src += btak->btak_Width; + } + break; + default: + break; + } + UnLockBitMap(handle); + } + else + { + kprintf(__FILE__ "/%s/%ld: Can't lock bitmap\n", __FUNC__, __LINE__); + } + + return 0; +} + +//----------------------------------------------------------------------- + diff --git a/scalos/libraries/scalosgfx/config.mk b/scalos/libraries/scalosgfx/config.mk new file mode 100755 index 000000000..4567a30ff --- /dev/null +++ b/scalos/libraries/scalosgfx/config.mk @@ -0,0 +1,51 @@ +# $Date: 2012-08-10 13:47:28 +0200 (Fr, 10. Aug 2012) $ +# $Revision: 915 $ + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += -nostartfiles \ +# --verbose + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += -nostartfiles \ +# --verbose + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +LFLAGS += -nostartfiles -larossupport + +else + +############################################################################### +# AmigaOS + +LFLAGS += -lstack -lnix -lnixmain -lamiga -lstubs + +endif +endif +endif diff --git a/scalos/libraries/scalosgfx/makefile b/scalos/libraries/scalosgfx/makefile new file mode 100644 index 000000000..6e0d74750 --- /dev/null +++ b/scalos/libraries/scalosgfx/makefile @@ -0,0 +1,102 @@ +# makefile für Scalos scalosgfx.library +# $Date$ +# $Revision$ +# $Id$ +############################################################ + +CSRCS = scalosgfx-classic.c \ + scalosgfx.c \ + argb.c \ + blit.c \ + Dither.c \ + Render.c \ + BitMapScale.c \ + + +ASRCS = + +SPLAT = sc:c/splat +LINK = slink +CC = sc +LIBS = LIB:scmnb.lib LIB:scnb.lib LIB:debug.lib LIB:amiga.lib +PRECOMP = Include:all.gst +OBJDIR = .sasobj + +############################################################# + +.SUFFIXES: .s .asm .plugin .plugin.debug + +############################################################# + +CFLAGS = optimize nochkabort nostackcheck nover \ + dbg=f DATA=far code=far \ + ignore=306 idlen=64 idir=//include +LNFLAGS = quiet batch noicons stripdebug +LNDBFLAGS = quiet batch noicons addsym + +############################################################# + +$(OBJDIR):: + @[ -d $(OBJDIR) ] || mkdir $(OBJDIR) > /dev/null 2>&1 + +############################################################# + +OBJS = $(CSRCS:%.c=$(OBJDIR)/%.o) + +############################################################# + +$(OBJDIR)/%.o : %.c + @printf '\033[32mCompile: \033[31m\033[1m$<\033[0m\n' + @$(CC) $(CFLAGS) $* objectname $@ + +############################################################ + +NAME = .bin_os3/scalosgfx.library +DBGNAME = $(NAME).debug + +############################################################# + +all: $(NAME) $(DBGNAME) +# install +# clean + +############################################################# + +$(OBJDIR)/scalosgfx-classic.o : scalosgfx_base.h scalosgfx.h +$(OBJDIR)/scalosgfx.o : scalosgfx_base.h scalosgfx.h +$(OBJDIR)/argb.o : scalosgfx_base.h scalosgfx.h +$(OBJDIR)/blit.o : scalosgfx_base.h scalosgfx.h +$(OBJDIR)/Dither.o : scalosgfx_base.h scalosgfx.h +$(OBJDIR)/Render.o : scalosgfx_base.h scalosgfx.h +$(OBJDIR)/BitMapScale.o : scalosgfx_base.h scalosgfx.h + +############################################################# + +$(NAME) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LINK) to $@ FROM $(OBJS) lib $(LIBS) $(LNFLAGS) + +$(DBGNAME) : $(OBJS) + @printf '\033[32mLink: \033[31m\033[1m$@\033[0m\n' + @$(LINK) to $@ FROM $(OBJS) lib $(LIBS) $(LNDBFLAGS) + +############################################################# + +install: + @printf '\033[32mInstall: \033[31m\033[1m$(NAME)\033[0m to \033[1mLIBS: \033[0m\n' + @copy $(NAME) LIBS: clone + @avail flush + +############################################################# + +clean: + @printf '\033[32mCleanup: \033[31m\033[1m' + @delete $(NAME) $(DBGNAME) $(OBJS) + @printf '\033[0m' + +############################################################# + +nodebug: + -@$(SPLAT) -s -o "d2(" "d1(" "#?.c" + +############################################################# diff --git a/scalos/libraries/scalosgfx/makefile-new b/scalos/libraries/scalosgfx/makefile-new new file mode 100755 index 000000000..c5dd46718 --- /dev/null +++ b/scalos/libraries/scalosgfx/makefile-new @@ -0,0 +1,79 @@ +# $Date: 2011-06-23 22:21:05 +0200 (Do, 23. Jun 2011) $ +# $Revision: 737 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../.. +endif + +############################################################################## + +include config.mk + +############################################################################## +# +# Project Object files +# + +OBJS = $(OBJDIR)/scalosgfx.o \ + $(OBJDIR)/argb.o \ + $(OBJDIR)/blit.o \ + $(OBJDIR)/BitMapScale.o \ + $(OBJDIR)/Dither.o \ + $(OBJDIR)/Render.o \ + +ifeq ($(MACHINE),ppc-amigaos) +OBJS := $(OBJDIR)/scalosgfx-aos4.o $(OBJDIR)/scalosgfx-aos4-68kstubs.o $(OBJS) +else +ifeq ($(MACHINE),i386-aros) +OBJS := $(OBJDIR)/scalosgfx-aros.o $(OBJS) +else +OBJS := $(OBJDIR)/scalosgfx-classic.o $(OBJS) +endif +endif + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Targets +# + +NAME = scalosgfx.library +NAME_DB = $(NAME).debug + +############################################################################## + +.PHONY: all install clean bump dump + +all: $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + $(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) LIBS: clone + @avail flush + +clean: + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* + +############################################################################## diff --git a/scalos/libraries/scalosgfx/scalosgfx-aos4-68kstubs.c b/scalos/libraries/scalosgfx/scalosgfx-aos4-68kstubs.c new file mode 100644 index 000000000..3e3fce3e0 --- /dev/null +++ b/scalos/libraries/scalosgfx/scalosgfx-aos4-68kstubs.c @@ -0,0 +1,416 @@ +/* +** This file was automatically generated by fdtrans 52.1. +** Do not edit it by hand. Instead, edit the sfd file +** that was used to generate this file +*/ + +#ifdef __USE_INLINE__ +#undef __USE_INLINE__ +#endif +#ifndef __NOGLOBALIFACE__ +#define __NOGLOBALIFACE__ +#endif + +#include +#include +#include +#include +#include +#include + + +static inline int8 convert_int8 (uint32 x) { return x; } +static inline int16 convert_int16(uint32 x) { return x; } + + +STATIC struct Library * stub_OpenPPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct LibraryManagerInterface *Self = (struct LibraryManagerInterface *) ExtLib->ILibrary; + + return Self->Open(0); +} +STATIC CONST struct EmuTrap stub_Open = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_OpenPPC }; + +STATIC APTR stub_ClosePPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct LibraryManagerInterface *Self = (struct LibraryManagerInterface *) ExtLib->ILibrary; + + return Self->Close(); +} +STATIC CONST struct EmuTrap stub_Close = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_ClosePPC }; + +STATIC APTR stub_ExpungePPC(ULONG *regarray __attribute__((unused))) +{ + return NULL; +} +STATIC CONST struct EmuTrap stub_Expunge = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_ExpungePPC }; + +STATIC ULONG stub_ReservedPPC(ULONG *regarray __attribute__((unused))) +{ + return 0UL; +} +STATIC CONST struct EmuTrap stub_Reserved = { TRAPINST, TRAPTYPE, stub_ReservedPPC }; + +static struct ScalosBitMapAndColor * stub_ScalosGfxCreateEmptySACPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct ScalosGfxIFace *Self = (struct ScalosGfxIFace *) ExtLib->MainIFace; + + return Self->ScalosGfxCreateEmptySAC( + ); +} +STATIC CONST struct EmuTrap stub_ScalosGfxCreateEmptySAC = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_ScalosGfxCreateEmptySACPPC }; + +static struct ScalosBitMapAndColor * stub_ScalosGfxCreateSACPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct ScalosGfxIFace *Self = (struct ScalosGfxIFace *) ExtLib->MainIFace; + + return Self->ScalosGfxCreateSAC( + (ULONG)regarray[0], + (ULONG)regarray[1], + (ULONG)regarray[2], + (struct BitMap *)regarray[8], + (struct TagItem *)regarray[9] + ); +} +STATIC CONST struct EmuTrap stub_ScalosGfxCreateSAC = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_ScalosGfxCreateSACPPC }; + +static VOID stub_ScalosGfxFreeSACPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct ScalosGfxIFace *Self = (struct ScalosGfxIFace *) ExtLib->MainIFace; + + Self->ScalosGfxFreeSAC( + (struct ScalosBitMapAndColor *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_ScalosGfxFreeSAC = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_ScalosGfxFreeSACPPC }; + +static struct gfxARGB * stub_ScalosGfxCreateARGBPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct ScalosGfxIFace *Self = (struct ScalosGfxIFace *) ExtLib->MainIFace; + + return Self->ScalosGfxCreateARGB( + (ULONG)regarray[0], + (ULONG)regarray[1], + (struct TagItem *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_ScalosGfxCreateARGB = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_ScalosGfxCreateARGBPPC }; + +static VOID stub_ScalosGfxFreeARGBPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct ScalosGfxIFace *Self = (struct ScalosGfxIFace *) ExtLib->MainIFace; + + Self->ScalosGfxFreeARGB( + (struct gfxARGB **)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_ScalosGfxFreeARGB = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_ScalosGfxFreeARGBPPC }; + +static VOID stub_ScalosGfxARGBSetAlphaPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct ScalosGfxIFace *Self = (struct ScalosGfxIFace *) ExtLib->MainIFace; + + Self->ScalosGfxARGBSetAlpha( + (struct ARGBHeader *)regarray[8], + (UBYTE)(regarray[0] & 0xff) + ); +} +STATIC CONST struct EmuTrap stub_ScalosGfxARGBSetAlpha = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_ScalosGfxARGBSetAlphaPPC }; + +static VOID stub_ScalosGfxARGBSetAlphaMaskPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct ScalosGfxIFace *Self = (struct ScalosGfxIFace *) ExtLib->MainIFace; + + Self->ScalosGfxARGBSetAlphaMask( + (struct ARGBHeader *)regarray[8], + (PLANEPTR)regarray[9] + ); +} +STATIC CONST struct EmuTrap stub_ScalosGfxARGBSetAlphaMask = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_ScalosGfxARGBSetAlphaMaskPPC }; + +static struct gfxARGB * stub_ScalosGfxCreateARGBFromBitMapPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct ScalosGfxIFace *Self = (struct ScalosGfxIFace *) ExtLib->MainIFace; + + return Self->ScalosGfxCreateARGBFromBitMap( + (struct BitMap *)regarray[8], + (ULONG)regarray[0], + (ULONG)regarray[1], + (ULONG)regarray[2], + (const ULONG *)regarray[9], + (PLANEPTR)regarray[10] + ); +} +STATIC CONST struct EmuTrap stub_ScalosGfxCreateARGBFromBitMap = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_ScalosGfxCreateARGBFromBitMapPPC }; + +static VOID stub_ScalosGfxFillARGBFromBitMapPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct ScalosGfxIFace *Self = (struct ScalosGfxIFace *) ExtLib->MainIFace; + + Self->ScalosGfxFillARGBFromBitMap( + (struct ARGBHeader *)regarray[8], + (struct BitMap *)regarray[9], + (PLANEPTR)regarray[10] + ); +} +STATIC CONST struct EmuTrap stub_ScalosGfxFillARGBFromBitMap = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_ScalosGfxFillARGBFromBitMapPPC }; + +static VOID stub_ScalosGfxWriteARGBToBitMapPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct ScalosGfxIFace *Self = (struct ScalosGfxIFace *) ExtLib->MainIFace; + + Self->ScalosGfxWriteARGBToBitMap( + (struct ARGBHeader *)regarray[8], + (struct BitMap *)regarray[9], + (ULONG)regarray[0], + (const ULONG *)regarray[10] + ); +} +STATIC CONST struct EmuTrap stub_ScalosGfxWriteARGBToBitMap = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_ScalosGfxWriteARGBToBitMapPPC }; + +static struct ScalosBitMapAndColor * stub_ScalosGfxMedianCutPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct ScalosGfxIFace *Self = (struct ScalosGfxIFace *) ExtLib->MainIFace; + + return Self->ScalosGfxMedianCut( + (struct ARGBHeader *)regarray[8], + (ULONG)regarray[0], + (struct TagItem *)regarray[9] + ); +} +STATIC CONST struct EmuTrap stub_ScalosGfxMedianCut = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_ScalosGfxMedianCutPPC }; + +static struct gfxARGB * stub_ScalosGfxScaleARGBArrayPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct ScalosGfxIFace *Self = (struct ScalosGfxIFace *) ExtLib->MainIFace; + + return Self->ScalosGfxScaleARGBArray( + (const struct ARGBHeader *)regarray[8], + (ULONG *)regarray[9], + (ULONG *)regarray[10], + (struct TagItem *)regarray[11] + ); +} +STATIC CONST struct EmuTrap stub_ScalosGfxScaleARGBArray = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_ScalosGfxScaleARGBArrayPPC }; + +static struct BitMap * stub_ScalosGfxScaleBitMapPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct ScalosGfxIFace *Self = (struct ScalosGfxIFace *) ExtLib->MainIFace; + + return Self->ScalosGfxScaleBitMap( + (struct ScaleBitMapArg *)regarray[8], + (struct TagItem *)regarray[9] + ); +} +STATIC CONST struct EmuTrap stub_ScalosGfxScaleBitMap = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_ScalosGfxScaleBitMapPPC }; + +static VOID stub_ScalosGfxCalculateScaleAspectPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct ScalosGfxIFace *Self = (struct ScalosGfxIFace *) ExtLib->MainIFace; + + Self->ScalosGfxCalculateScaleAspect( + (ULONG)regarray[0], + (ULONG)regarray[1], + (ULONG *)regarray[8], + (ULONG *)regarray[9] + ); +} +STATIC CONST struct EmuTrap stub_ScalosGfxCalculateScaleAspect = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_ScalosGfxCalculateScaleAspectPPC }; + +static VOID stub_ScalosGfxBlitARGBPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct ScalosGfxIFace *Self = (struct ScalosGfxIFace *) ExtLib->MainIFace; + + Self->ScalosGfxBlitARGB( + (struct ARGBHeader *)regarray[8], + (const struct ARGBHeader *)regarray[9], + (LONG)regarray[0], + (LONG)regarray[1], + (LONG)regarray[2], + (LONG)regarray[3], + (LONG)regarray[4], + (LONG)regarray[5] + ); +} +STATIC CONST struct EmuTrap stub_ScalosGfxBlitARGB = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_ScalosGfxBlitARGBPPC }; + +static VOID stub_ScalosGfxFillRectARGBPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct ScalosGfxIFace *Self = (struct ScalosGfxIFace *) ExtLib->MainIFace; + + Self->ScalosGfxFillRectARGB( + (struct ARGBHeader *)regarray[8], + (const struct gfxARGB *)regarray[9], + (LONG)regarray[0], + (LONG)regarray[1], + (LONG)regarray[2], + (LONG)regarray[3] + ); +} +STATIC CONST struct EmuTrap stub_ScalosGfxFillRectARGB = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_ScalosGfxFillRectARGBPPC }; + +static VOID stub_ScalosGfxSetARGBPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct ScalosGfxIFace *Self = (struct ScalosGfxIFace *) ExtLib->MainIFace; + + Self->ScalosGfxSetARGB( + (struct ARGBHeader *)regarray[8], + (const struct gfxARGB *)regarray[9] + ); +} +STATIC CONST struct EmuTrap stub_ScalosGfxSetARGB = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_ScalosGfxSetARGBPPC }; + +static BOOL stub_ScalosGfxNewColorMapPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct ScalosGfxIFace *Self = (struct ScalosGfxIFace *) ExtLib->MainIFace; + + return Self->ScalosGfxNewColorMap( + (struct ScalosBitMapAndColor *)regarray[8], + (const ULONG *)regarray[9], + (ULONG)regarray[0] + ); +} +STATIC CONST struct EmuTrap stub_ScalosGfxNewColorMap = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_ScalosGfxNewColorMapPPC }; + +static VOID stub_ScalosGfxARGBRectMultPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct ScalosGfxIFace *Self = (struct ScalosGfxIFace *) ExtLib->MainIFace; + + Self->ScalosGfxARGBRectMult( + (struct RastPort *)regarray[8], + (const struct gfxARGB *)regarray[9], + (const struct gfxARGB *)regarray[10], + (WORD)convert_int16(regarray[0]), + (WORD)convert_int16(regarray[1]), + (WORD)convert_int16(regarray[2]), + (WORD)convert_int16(regarray[3]) + ); +} +STATIC CONST struct EmuTrap stub_ScalosGfxARGBRectMult = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_ScalosGfxARGBRectMultPPC }; + +static VOID stub_ScalosGfxBlitARGBAlphaPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct ScalosGfxIFace *Self = (struct ScalosGfxIFace *) ExtLib->MainIFace; + + Self->ScalosGfxBlitARGBAlpha( + (struct RastPort *)regarray[8], + (const struct ARGBHeader *)regarray[9], + (ULONG)regarray[0], + (ULONG)regarray[1], + (ULONG)regarray[2], + (ULONG)regarray[3], + (ULONG)regarray[4], + (ULONG)regarray[5] + ); +} +STATIC CONST struct EmuTrap stub_ScalosGfxBlitARGBAlpha = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_ScalosGfxBlitARGBAlphaPPC }; + +static VOID stub_ScalosGfxBlitARGBAlphaTagListPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct ScalosGfxIFace *Self = (struct ScalosGfxIFace *) ExtLib->MainIFace; + + Self->ScalosGfxBlitARGBAlphaTagList( + (struct RastPort *)regarray[8], + (const struct ARGBHeader *)regarray[9], + (ULONG)regarray[0], + (ULONG)regarray[1], + (const struct IBox *)regarray[11], + (struct TagItem *)regarray[10] + ); +} +STATIC CONST struct EmuTrap stub_ScalosGfxBlitARGBAlphaTagList = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_ScalosGfxBlitARGBAlphaTagListPPC }; + +static VOID stub_ScalosGfxBlitIconPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct ScalosGfxIFace *Self = (struct ScalosGfxIFace *) ExtLib->MainIFace; + + Self->ScalosGfxBlitIcon( + (struct RastPort *)regarray[8], + (struct RastPort *)regarray[9], + (ULONG)regarray[0], + (ULONG)regarray[1], + (ULONG)regarray[2], + (ULONG)regarray[3], + (struct TagItem *)regarray[10] + ); +} +STATIC CONST struct EmuTrap stub_ScalosGfxBlitIcon = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_ScalosGfxBlitIconPPC }; + +CONST CONST_APTR VecTable68K[] = +{ + &stub_Open, + &stub_Close, + &stub_Expunge, + &stub_Reserved, + &stub_ScalosGfxCreateEmptySAC, + &stub_ScalosGfxCreateSAC, + &stub_ScalosGfxFreeSAC, + &stub_ScalosGfxCreateARGB, + &stub_ScalosGfxFreeARGB, + &stub_ScalosGfxARGBSetAlpha, + &stub_ScalosGfxARGBSetAlphaMask, + &stub_ScalosGfxCreateARGBFromBitMap, + &stub_ScalosGfxFillARGBFromBitMap, + &stub_ScalosGfxWriteARGBToBitMap, + &stub_ScalosGfxMedianCut, + &stub_ScalosGfxScaleARGBArray, + &stub_ScalosGfxScaleBitMap, + &stub_ScalosGfxCalculateScaleAspect, + &stub_ScalosGfxBlitARGB, + &stub_ScalosGfxFillRectARGB, + &stub_ScalosGfxSetARGB, + &stub_ScalosGfxNewColorMap, + &stub_ScalosGfxARGBRectMult, + &stub_ScalosGfxBlitARGBAlpha, + &stub_ScalosGfxBlitARGBAlphaTagList, + &stub_ScalosGfxBlitIcon, + (CONST_APTR)-1 +}; diff --git a/scalos/libraries/scalosgfx/scalosgfx-aos4.c b/scalos/libraries/scalosgfx/scalosgfx-aos4.c new file mode 100644 index 000000000..d393e5e28 --- /dev/null +++ b/scalos/libraries/scalosgfx/scalosgfx-aos4.c @@ -0,0 +1,422 @@ +// scalosgfx-aos4.c +// $Date$ +// $Revision$ + + +#include +#include +#include + +#include +#include + +#include + +#include "scalosgfx.h" + +#include + +int _start(void) +{ + return -1; +} + +extern CONST_APTR VecTable68K[]; + +/* -------------------- Internal functions ------------------------- */ + +static struct Library *Initlib(struct Library *libbase, BPTR seglist, struct ExecIFace *pIExec); +static BPTR Expungelib(struct LibraryManagerInterface *Self); +static struct LibraryHeader *Openlib(struct LibraryManagerInterface *Self, ULONG version); +static BPTR Closelib(struct LibraryManagerInterface *Self); +static ULONG Obtainlib(struct LibraryManagerInterface *Self); +static ULONG Releaselib(struct LibraryManagerInterface *Self); + +static LIBFUNC_P5VA_PROTO(struct ScalosBitMapAndColor *, LIBScalosGfxCreateSACTags, + D0, ULONG, width, + D1, ULONG, height, + D2, ULONG, depth, + A0, struct BitMap *, friendBM, + A6, struct ScalosGfxBase *, ScalosGfxBase); +static LIBFUNC_P3VA_PROTO(struct gfxARGB *, LIBScalosGfxCreateARGBTags, + D0, ULONG, width, + D1, ULONG, height, + A6, struct ScalosGfxBase *, ScalosGfxBase); +static LIBFUNC_P3VA_PROTO(struct ScalosBitMapAndColor *, LIBScalosGfxMedianCutTags, + A0, struct ARGBHeader *, argbh, + D0, ULONG, depth, + A6, struct ScalosGfxBase *, ScalosGfxBase); +static LIBFUNC_P4VA_PROTO(struct gfxARGB *, LIBScalosGfxScaleARGBArrayTags, + A0, const struct ARGBHeader *, src, + A1, ULONG *, destWidth, + A2, ULONG *, destHeight, + A6, struct ScalosGfxBase *, ScalosGfxBase); +static LIBFUNC_P2VA_PROTO(struct BitMap *, LIBScalosGfxScaleBitMapTags, + A0, struct ScaleBitMapArg *, sbma, + A6, struct ScalosGfxBase *, ScalosGfxBase); +static LIBFUNC_P6VA_PROTO(VOID, LIBScalosGfxBlitARGBAlphaTags, + A0, struct RastPort *, rp, + A1, const struct ARGBHeader *, srcH, + D0, ULONG, destLeft, + D1, ULONG, destTop, + A3, const struct IBox *, srcSize, + A6, struct ScalosGfxBase *, ScalosGfxBase); +static LIBFUNC_P7VA_PROTO(VOID, LIBScalosGfxBlitIconTags, + A0, struct RastPort *, rpBackground, + A1, struct RastPort *, rpIcon, + D0, ULONG, left, + D1, ULONG, top, + D2, ULONG, width, + D3, ULONG, height, + A6, struct ScalosGfxBase *, ScalosGfxBase); + +/* OS4.0 Library */ + +/* ------------------- OS4 Manager Interface ------------------------ */ +static const APTR managerfunctable[] = +{ + (APTR)Obtainlib, + (APTR)Releaselib, + (APTR)NULL, + (APTR)NULL, + (APTR)Openlib, + (APTR)Closelib, + (APTR)Expungelib, + (APTR)NULL, + (APTR)-1 +}; + +static const struct TagItem managertags[] = +{ + {MIT_Name, (ULONG)"__library"}, + {MIT_VectorTable, (ULONG)managerfunctable}, + {MIT_Version, 1}, + {TAG_DONE, 0} +}; + +/* ---------------------- OS4 Main Interface ------------------------ */ +static APTR functable[] = + { + Obtainlib, + Releaselib, + NULL, + NULL, + LIBScalosGfxCreateEmptySAC, + LIBScalosGfxCreateSAC, + LIBScalosGfxCreateSACTags, + LIBScalosGfxFreeSAC, + LIBScalosGfxCreateARGB, + LIBScalosGfxCreateARGBTags, + LIBScalosGfxFreeARGB, + LIBScalosGfxARGBSetAlpha, + LIBScalosGfxARGBSetAlphaMask, + LIBScalosGfxCreateARGBFromBitMap, + LIBScalosGfxFillARGBFromBitMap, + LIBScalosGfxWriteARGBToBitMap, + LIBScalosGfxMedianCut, + LIBScalosGfxMedianCutTags, + LIBScalosGfxScaleARGBArray, + LIBScalosGfxScaleARGBArrayTags, + LIBScalosGfxScaleBitMap, + LIBScalosGfxScaleBitMapTags, + LIBScalosGfxCalculateScaleAspect, + LIBScalosGfxBlitARGB, + LIBScalosGfxFillRectARGB, + LIBScalosGfxSetARGB, + LIBScalosGfxNewColorMap, + LIBScalosGfxARGBRectMult, + LIBScalosGfxBlitARGBAlpha, + LIBScalosGfxBlitARGBAlphaTagList, + LIBScalosGfxBlitARGBAlphaTags, + LIBScalosGfxBlitIcon, + LIBScalosGfxBlitIconTags, + LIBScalosGfxDrawGradient, + LIBScalosGfxDrawGradientRastPort, + LIBScalosGfxDrawLine, + LIBScalosGfxDrawLineRastPort, + LIBScalosGfxDrawEllipse, + LIBScalosGfxDrawEllipseRastPort, + (APTR) -1 + }; + +static const struct TagItem maintags[] = + { + {MIT_Name, (ULONG)"main"}, + {MIT_VectorTable, (ULONG)functable}, + {MIT_Version, 1}, + {TAG_DONE, 0} + }; + +/* Init table used in library initialization. */ +static const ULONG interfaces[] = +{ + (ULONG)managertags, + (ULONG)maintags, + (ULONG)0 +}; + +static const struct TagItem inittab[] = + { + {CLT_DataSize, (ULONG)sizeof(struct ScalosGfxBase)}, + {CLT_Interfaces, (ULONG) interfaces}, + {CLT_Vector68K, (ULONG)VecTable68K}, + {CLT_InitFunc, (ULONG) Initlib}, + {TAG_DONE, 0} + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, + RTF_NATIVE | RTF_AUTOINIT, + LIB_VERSION, + NT_LIBRARY, + 0, + libName, + libIdString, + (struct TagItem *)inittab + }; + +/* ------------------- OS4 Manager Functions ------------------------ */ +static struct Library * Initlib(struct Library *libbase, BPTR seglist, struct ExecIFace *pIExec) +{ + struct ScalosGfxBase *ScalosGfxLibBase = (struct ScalosGfxBase *) libbase; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)libbase + libbase->lib_PosSize); + struct LibraryManagerInterface *Self = (struct LibraryManagerInterface *) ExtLib->ILibrary; + + SysBase = (struct ExecBase *)pIExec->Data.LibBase; + IExec = pIExec; + ScalosGfxLibBase->sgb_LibNode.lib_Revision = LIB_REVISION; + ScalosGfxLibBase->sgb_SegList = (struct SegList *)seglist; + + if (!ScalosGfxInit(ScalosGfxLibBase)) + { + Expungelib(Self); + ScalosGfxLibBase = NULL; + } + + return ScalosGfxLibBase ? &ScalosGfxLibBase->sgb_LibNode : NULL; +} + +static BPTR Expungelib(struct LibraryManagerInterface *Self) +{ + struct ScalosGfxBase *ScalosGfxLibBase = (struct ScalosGfxBase *) Self->Data.LibBase; + + if (0 == ScalosGfxLibBase->sgb_LibNode.lib_OpenCnt) + { + struct SegList *libseglist = ScalosGfxLibBase->sgb_SegList; + + Remove((struct Node *) ScalosGfxLibBase); + ScalosGfxCleanup(ScalosGfxLibBase); + DeleteLibrary((struct Library *)ScalosGfxLibBase); + + return (BPTR)libseglist; + } + + ScalosGfxLibBase->sgb_LibNode.lib_Flags |= LIBF_DELEXP; + + return (BPTR)NULL; +} + +static struct LibraryHeader *Openlib(struct LibraryManagerInterface *Self, ULONG version) +{ + struct ScalosGfxBase *ScalosGfxLibBase = (struct ScalosGfxBase *) Self->Data.LibBase; + + ScalosGfxLibBase->sgb_LibNode.lib_OpenCnt++; + ScalosGfxLibBase->sgb_LibNode.lib_Flags &= ~LIBF_DELEXP; + + if (!ScalosGfxLibBase->sgb_Initialized) + { + if (!ScalosGfxOpen(ScalosGfxLibBase)) + { + Closelib(Self); + return NULL; + } + + ScalosGfxLibBase->sgb_Initialized = TRUE; + } + + return (struct LibraryHeader *)&ScalosGfxLibBase->sgb_LibNode; +} + +static BPTR Closelib(struct LibraryManagerInterface *Self) +{ + struct ScalosGfxBase *ScalosGfxLibBase = (struct ScalosGfxBase *) Self->Data.LibBase; + + d1(kprintf("%s/%s/%ld: lib_OpenCnt=%ld\n", __FILE__, __FUNC__, __LINE__, \ + ScalosGfxLibBase->sgb_LibNode.lib_OpenCnt)); + + ScalosGfxLibBase->sgb_LibNode.lib_OpenCnt--; + +/* if (0 == ScalosGfxLibBase->sgb_LibNode.lib_OpenCnt) + { + if (ScalosGfxLibBase->sgb_LibNode.lib_Flags & LIBF_DELEXP) + { + return Expungelib(Self); + } + } +*/ + d1(kprintf("%s/%s/%ld: lib_OpenCnt=%ld\n", __FILE__, __FUNC__, __LINE__, \ + ScalosGfxLibBase->sgb_LibNode.lib_OpenCnt)); + + return (BPTR)NULL; +} + +static ULONG Obtainlib(struct LibraryManagerInterface *Self) +{ + return(Self->Data.RefCount++); +} + +static ULONG Releaselib(struct LibraryManagerInterface *Self) +{ + return(Self->Data.RefCount--); +} + + +static LIBFUNC_P5VA(struct ScalosBitMapAndColor *, LIBScalosGfxCreateSACTags, + D0, ULONG, width, + D1, ULONG, height, + D2, ULONG, depth, + A0, struct BitMap *, friendBM, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + struct ScalosBitMapAndColor *ret; + va_list args; + va_startlinear(args, friendBM); + + (void)ScalosGfxBase; + + ret = ((struct ScalosGfxIFace *)self)->ScalosGfxCreateSAC(width, height, depth, friendBM, va_getlinearva(args, struct TagItem *)); + + va_end(args); + + return(ret); +} +LIBFUNC_END + +static LIBFUNC_P3VA(struct gfxARGB *, LIBScalosGfxCreateARGBTags, + D0, ULONG, width, + D1, ULONG, height, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + struct gfxARGB *ret; + va_list args; + va_startlinear(args, height); + + (void)ScalosGfxBase; + + ret = ((struct ScalosGfxIFace *)self)->ScalosGfxCreateARGB(width, height, va_getlinearva(args, struct TagItem *)); + + va_end(args); + + return(ret); +} +LIBFUNC_END + +static LIBFUNC_P3VA(struct ScalosBitMapAndColor *, LIBScalosGfxMedianCutTags, + A0, struct ARGBHeader *, argbh, + D0, ULONG, depth, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + struct ScalosBitMapAndColor *ret; + va_list args; + va_startlinear(args, depth); + + (void)ScalosGfxBase; + + ret = ((struct ScalosGfxIFace *)self)->ScalosGfxMedianCut(argbh, depth, va_getlinearva(args, struct TagItem *)); + + va_end(args); + + return(ret); +} +LIBFUNC_END + +static LIBFUNC_P4VA(struct gfxARGB *, LIBScalosGfxScaleARGBArrayTags, + A0, const struct ARGBHeader *, src, + A1, ULONG *, destWidth, + A2, ULONG *, destHeight, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + struct gfxARGB *ret; + va_list args; + va_startlinear(args, destHeight); + + (void)ScalosGfxBase; + + ret = ((struct ScalosGfxIFace *)self)->ScalosGfxScaleARGBArray(src, destWidth, destHeight, va_getlinearva(args, struct TagItem *)); + + va_end(args); + + return(ret); +} +LIBFUNC_END + +static LIBFUNC_P2VA(struct BitMap *, LIBScalosGfxScaleBitMapTags, + A0, struct ScaleBitMapArg *, sbma, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + struct BitMap *ret; + va_list args; + va_startlinear(args, sbma); + + (void)ScalosGfxBase; + + ret = ((struct ScalosGfxIFace *)self)->ScalosGfxScaleBitMap(sbma, va_getlinearva(args, struct TagItem *)); + + va_end(args); + + return(ret); +} +LIBFUNC_END + +static LIBFUNC_P6VA(VOID, LIBScalosGfxBlitARGBAlphaTags, + A0, struct RastPort *, rp, + A1, const struct ARGBHeader *, srcH, + D0, ULONG, destLeft, + D1, ULONG, destTop, + A3, const struct IBox *, srcSize, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + va_list args; + va_startlinear(args, srcSize); + + (void)ScalosGfxBase; + + ((struct ScalosGfxIFace *)self)->ScalosGfxBlitARGBAlphaTagList(rp, + srcH, + destLeft, destTop, + srcSize, + va_getlinearva(args, struct TagItem *)); + + va_end(args); +} +LIBFUNC_END + +static LIBFUNC_P7VA(VOID, LIBScalosGfxBlitIconTags, + A0, struct RastPort *, rpBackground, + A1, struct RastPort *, rpIcon, + D0, ULONG, left, + D1, ULONG, top, + D2, ULONG, width, + D3, ULONG, height, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + va_list args; + va_startlinear(args, height); + + (void)ScalosGfxBase; + + ((struct ScalosGfxIFace *)self)->ScalosGfxBlitIcon(rpBackground, + rpIcon, + left, top, width, height, + va_getlinearva(args, struct TagItem *)); + + va_end(args); +} +LIBFUNC_END + + diff --git a/scalos/libraries/scalosgfx/scalosgfx-aros.c b/scalos/libraries/scalosgfx/scalosgfx-aros.c new file mode 100644 index 000000000..6e0ba057c --- /dev/null +++ b/scalos/libraries/scalosgfx/scalosgfx-aros.c @@ -0,0 +1,246 @@ +// scalosgfx-classic.c +// $Date$ +// $Revision$ + + +#include +#include + +#include + +#include + +#include + +#include "scalosgfx.h" + +struct Library *aroscbase; + +//---------------------------------------------------------------------------- +// Standard library functions + +static AROS_UFP3 (struct Library *, Initlib, + AROS_UFPA(struct Library *, libbase, D0), + AROS_UFPA(struct SegList *, seglist, A0), + AROS_UFPA(struct ExecBase *, sysbase, A6) +); +static AROS_LD1 (struct Library *, Openlib, + AROS_LPA (__unused ULONG, version, D0), + struct Library *, libbase, 1, ScalosGfx +); +static AROS_LD0 (struct SegList *, Closelib, + struct Library *, base, 2, ScalosGfx +); +static AROS_LD1 (struct SegList *, Expungelib, + AROS_LPA(__unused struct Library *, __extrabase, D0), + struct Library *, libbase, 3, ScalosGfx +); +static AROS_LD0 (ULONG, Extfunclib, + __unused struct Library *, libbase, 4, ScalosGfx +); + +//---------------------------------------------------------------------------- + +SAVEDS(LONG) ASM Libstart(void) +{ + return -1; +} + +//---------------------------------------------------------------------------- + +/* OS3.x Library */ + +static APTR functable[] = + { + ScalosGfx_1_Openlib, + ScalosGfx_2_Closelib, + ScalosGfx_3_Expungelib, + ScalosGfx_4_Extfunclib, + ScalosGfxBase_0_LIBScalosGfxCreateEmptySAC, + ScalosGfxBase_0_LIBScalosGfxCreateSAC, + ScalosGfxBase_0_LIBScalosGfxFreeSAC, + ScalosGfxBase_0_LIBScalosGfxCreateARGB, + ScalosGfxBase_0_LIBScalosGfxFreeARGB, + ScalosGfxBase_0_LIBScalosGfxARGBSetAlpha, + ScalosGfxBase_0_LIBScalosGfxARGBSetAlphaMask, + ScalosGfxBase_0_LIBScalosGfxCreateARGBFromBitMap, + ScalosGfxBase_0_LIBScalosGfxFillARGBFromBitMap, + ScalosGfxBase_0_LIBScalosGfxWriteARGBToBitMap, + ScalosGfxBase_0_LIBScalosGfxMedianCut, + ScalosGfxBase_0_LIBScalosGfxScaleARGBArray, + ScalosGfxBase_0_LIBScalosGfxScaleBitMap, + ScalosGfxBase_0_LIBScalosGfxCalculateScaleAspect, + ScalosGfxBase_0_LIBScalosGfxBlitARGB, + ScalosGfxBase_0_LIBScalosGfxFillRectARGB, + ScalosGfxBase_0_LIBScalosGfxSetARGB, + ScalosGfxBase_0_LIBScalosGfxNewColorMap, + ScalosGfxBase_0_LIBScalosGfxARGBRectMult, + ScalosGfxBase_0_LIBScalosGfxBlitARGBAlpha, + ScalosGfxBase_0_LIBScalosGfxBlitARGBAlphaTagList, + ScalosGfxBase_0_LIBScalosGfxBlitIcon, + ScalosGfxBase_0_LIBScalosGfxDrawGradient, + ScalosGfxBase_0_LIBScalosGfxDrawGradientRastPort, + ScalosGfxBase_0_LIBScalosGfxDrawLine, + ScalosGfxBase_0_LIBScalosGfxDrawLineRastPort, + ScalosGfxBase_0_LIBScalosGfxDrawEllipse, + ScalosGfxBase_0_LIBScalosGfxDrawEllipseRastPort, + (APTR) -1 + }; + +/* Init table used in library initialization. */ +static ULONG inittab[] = + { + sizeof(struct ScalosGfxBase), + (ULONG) functable, + 0, + (ULONG) Initlib + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, + RTF_AUTOINIT, + LIB_VERSION, + NT_LIBRARY, + 0, + libName, + libIdString, + inittab + }; + + +//---------------------------------------------------------------------------- + +static AROS_UFH3(struct Library *, Initlib, + AROS_UFHA(struct Library *, libbase, D0), + AROS_UFHA(struct SegList *, seglist, A0), + AROS_UFHA(struct ExecBase *, sysbase, A6) +) +{ + AROS_USERFUNC_INIT + + struct ScalosGfxBase *ScalosGfxLibBase = (struct ScalosGfxBase *) libbase; + + /* store pointer to execbase for global access */ + SysBase = sysbase; + + ScalosGfxLibBase->sgb_LibNode.lib_Revision = LIB_REVISION; + ScalosGfxLibBase->sgb_SegList = seglist; + + ScalosGfxLibBase->sgb_Initialized = FALSE; + + aroscbase = OpenLibrary("arosc.library", 0); + + if (!ScalosGfxInit(ScalosGfxLibBase) || !aroscbase) + { + ScalosGfx_3_Expungelib(&ScalosGfxLibBase->sgb_LibNode, &ScalosGfxLibBase->sgb_LibNode); + ScalosGfxLibBase = NULL; + } + + return ScalosGfxLibBase ? &ScalosGfxLibBase->sgb_LibNode : NULL; + + AROS_USERFUNC_EXIT +} + + +static AROS_LH1(struct Library *, Openlib, + AROS_LHA(__unused ULONG, version, D0), + struct Library *, libbase, 1, ScalosGfx +) +{ + AROS_LIBFUNC_INIT + + struct ScalosGfxBase *ScalosGfxLibBase = (struct ScalosGfxBase *) libbase; + + ScalosGfxLibBase->sgb_LibNode.lib_OpenCnt++; + ScalosGfxLibBase->sgb_LibNode.lib_Flags &= ~LIBF_DELEXP; + + if (!ScalosGfxLibBase->sgb_Initialized) + { + if (!ScalosGfxOpen(ScalosGfxLibBase)) + { + ScalosGfx_2_Closelib(&ScalosGfxLibBase->sgb_LibNode); + return NULL; + } + + ScalosGfxLibBase->sgb_Initialized = TRUE; + } + + return &ScalosGfxLibBase->sgb_LibNode; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH0(struct SegList *, Closelib, + struct Library *, libbase, 2, ScalosGfx +) +{ + AROS_LIBFUNC_INIT + + struct ScalosGfxBase *ScalosGfxLibBase = (struct ScalosGfxBase *) libbase; + + ScalosGfxLibBase->sgb_LibNode.lib_OpenCnt--; + + if (0 == ScalosGfxLibBase->sgb_LibNode.lib_OpenCnt) + { + if (ScalosGfxLibBase->sgb_LibNode.lib_Flags & LIBF_DELEXP) + { + return ScalosGfx_3_Expungelib(&ScalosGfxLibBase->sgb_LibNode, &ScalosGfxLibBase->sgb_LibNode); + } + } + + return NULL; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH1(struct SegList *, Expungelib, + AROS_LHA(__unused struct Library *, __extrabase, D0), + struct Library *, libbase, 3, ScalosGfx +) +{ + AROS_LIBFUNC_INIT + + struct ScalosGfxBase *ScalosGfxLibBase = (struct ScalosGfxBase *) libbase; + + if (0 == ScalosGfxLibBase->sgb_LibNode.lib_OpenCnt) + { + ULONG size = ScalosGfxLibBase->sgb_LibNode.lib_NegSize + ScalosGfxLibBase->sgb_LibNode.lib_PosSize; + UBYTE *ptr = (UBYTE *) ScalosGfxLibBase - ScalosGfxLibBase->sgb_LibNode.lib_NegSize; + struct SegList *libseglist = ScalosGfxLibBase->sgb_SegList; + + Remove((struct Node *) ScalosGfxLibBase); + ScalosGfxCleanup(ScalosGfxLibBase); + FreeMem(ptr,size); + + CloseLibrary(aroscbase); + + return libseglist; + } + + ScalosGfxLibBase->sgb_LibNode.lib_Flags |= LIBF_DELEXP; + + return NULL; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH0(ULONG, Extfunclib, + __unused struct Library *, libbase, 4, ScalosGfx +) +{ + AROS_LIBFUNC_INIT + + return 0; + + AROS_LIBFUNC_EXIT +} + +//---------------------------------------------------------------------------- diff --git a/scalos/libraries/scalosgfx/scalosgfx-classic.c b/scalos/libraries/scalosgfx/scalosgfx-classic.c new file mode 100644 index 000000000..7ff520355 --- /dev/null +++ b/scalos/libraries/scalosgfx/scalosgfx-classic.c @@ -0,0 +1,210 @@ +// scalosgfx-classic.c +// $Date$ +// $Revision$ + + +#include +#include + +#include + +#include + +#include "scalosgfx.h" + +//---------------------------------------------------------------------------- +// Standard library functions + +static LIB_SAVEDS(struct Library *) LIB_ASM LIB_INTERRUPT Initlib(LIB_REG(d0, struct Library *libbase), + LIB_REG(a0, struct SegList *seglist), LIB_REG(a6, struct ExecBase *sysbase)); + +static LIBFUNC_PROTO(Openlib, libbase, struct Library *); +static LIBFUNC_PROTO(Closelib, libbase, struct SegList *); +static LIBFUNC_PROTO(Expungelib, libbase, struct SegList *); +static LIBFUNC_PROTO(Extfunclib, libbase, ULONG); + +//---------------------------------------------------------------------------- + +SAVEDS(LONG) ASM Libstart(void) +{ + return -1; +} + +//---------------------------------------------------------------------------- + +/* OS3.x Library */ + +static APTR functable[] = + { +#ifdef __MORPHOS__ + (APTR) FUNCARRAY_32BIT_NATIVE, +#endif + Openlib, + Closelib, + Expungelib, + Extfunclib, + LIBScalosGfxCreateEmptySAC, + LIBScalosGfxCreateSAC, + LIBScalosGfxFreeSAC, + LIBScalosGfxCreateARGB, + LIBScalosGfxFreeARGB, + LIBScalosGfxARGBSetAlpha, + LIBScalosGfxARGBSetAlphaMask, + LIBScalosGfxCreateARGBFromBitMap, + LIBScalosGfxFillARGBFromBitMap, + LIBScalosGfxWriteARGBToBitMap, + LIBScalosGfxMedianCut, + LIBScalosGfxScaleARGBArray, + LIBScalosGfxScaleBitMap, + LIBScalosGfxCalculateScaleAspect, + LIBScalosGfxBlitARGB, + LIBScalosGfxFillRectARGB, + LIBScalosGfxSetARGB, + LIBScalosGfxNewColorMap, + LIBScalosGfxARGBRectMult, + LIBScalosGfxBlitARGBAlpha, + LIBScalosGfxBlitARGBAlphaTagList, + LIBScalosGfxBlitIcon, + LIBScalosGfxDrawGradient, + LIBScalosGfxDrawGradientRastPort, + LIBScalosGfxDrawLine, + LIBScalosGfxDrawLineRastPort, + LIBScalosGfxDrawEllipse, + LIBScalosGfxDrawEllipseRastPort, + (APTR) -1 + }; + +/* Init table used in library initialization. */ +static ULONG inittab[] = + { + sizeof(struct ScalosGfxBase), + (ULONG) functable, + 0, + (ULONG) Initlib + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, +#ifdef __MORPHOS__ + RTF_PPC | RTF_AUTOINIT, +#else + RTF_AUTOINIT, +#endif + LIB_VERSION, + NT_LIBRARY, + 0, + libName, + libIdString, + inittab + }; + +#ifdef __MORPHOS__ +ULONG __abox__=1; +#endif + +//---------------------------------------------------------------------------- + +static LIB_SAVEDS(struct Library *) LIB_ASM LIB_INTERRUPT Initlib(LIB_REG(d0, struct Library *libbase), + LIB_REG(a0, struct SegList *seglist), LIB_REG(a6, struct ExecBase *sysbase)) +{ + struct ScalosGfxBase *ScalosGfxLibBase = (struct ScalosGfxBase *) libbase; + + /* store pointer to execbase for global access */ + SysBase = sysbase; + + ScalosGfxLibBase->sgb_LibNode.lib_Revision = LIB_REVISION; + ScalosGfxLibBase->sgb_SegList = seglist; + + ScalosGfxLibBase->sgb_Initialized = FALSE; + + if (!ScalosGfxInit(ScalosGfxLibBase)) + { + CALLLIBFUNC(Expungelib, &ScalosGfxLibBase->sgb_LibNode); + ScalosGfxLibBase = NULL; + } + + return ScalosGfxLibBase ? &ScalosGfxLibBase->sgb_LibNode : NULL; +} + + +static LIBFUNC(Openlib, libbase, struct Library *) +{ + struct ScalosGfxBase *ScalosGfxLibBase = (struct ScalosGfxBase *) libbase; + + ScalosGfxLibBase->sgb_LibNode.lib_OpenCnt++; + ScalosGfxLibBase->sgb_LibNode.lib_Flags &= ~LIBF_DELEXP; + + if (!ScalosGfxLibBase->sgb_Initialized) + { + if (!ScalosGfxOpen(ScalosGfxLibBase)) + { + CALLLIBFUNC(Closelib, &ScalosGfxLibBase->sgb_LibNode); + return NULL; + } + + ScalosGfxLibBase->sgb_Initialized = TRUE; + } + + return &ScalosGfxLibBase->sgb_LibNode; +} +LIBFUNC_END + + +static LIBFUNC(Closelib, libbase, struct SegList *) +{ + struct ScalosGfxBase *ScalosGfxLibBase = (struct ScalosGfxBase *) libbase; + + ScalosGfxLibBase->sgb_LibNode.lib_OpenCnt--; + + if (0 == ScalosGfxLibBase->sgb_LibNode.lib_OpenCnt) + { + if (ScalosGfxLibBase->sgb_LibNode.lib_Flags & LIBF_DELEXP) + { + return CALLLIBFUNC(Expungelib, &ScalosGfxLibBase->sgb_LibNode); + } + } + + return NULL; +} +LIBFUNC_END + + +static LIBFUNC(Expungelib, libbase, struct SegList *) +{ + struct ScalosGfxBase *ScalosGfxLibBase = (struct ScalosGfxBase *) libbase; + + if (0 == ScalosGfxLibBase->sgb_LibNode.lib_OpenCnt) + { + ULONG size = ScalosGfxLibBase->sgb_LibNode.lib_NegSize + ScalosGfxLibBase->sgb_LibNode.lib_PosSize; + UBYTE *ptr = (UBYTE *) ScalosGfxLibBase - ScalosGfxLibBase->sgb_LibNode.lib_NegSize; + struct SegList *libseglist = ScalosGfxLibBase->sgb_SegList; + + Remove((struct Node *) ScalosGfxLibBase); + ScalosGfxCleanup(ScalosGfxLibBase); + FreeMem(ptr,size); + + return libseglist; + } + + ScalosGfxLibBase->sgb_LibNode.lib_Flags |= LIBF_DELEXP; + + return NULL; +} +LIBFUNC_END + + +static LIBFUNC(Extfunclib, libbase, ULONG) +{ + (void) libbase; + + return 0; +} +LIBFUNC_END + +//---------------------------------------------------------------------------- + diff --git a/scalos/libraries/scalosgfx/scalosgfx.c b/scalos/libraries/scalosgfx/scalosgfx.c new file mode 100644 index 000000000..df5a8810c --- /dev/null +++ b/scalos/libraries/scalosgfx/scalosgfx.c @@ -0,0 +1,921 @@ +// scalosgfx.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include + +#include "scalosgfx_base.h" +#include "scalosgfx.h" +#include +#include + +//---------------------------------------------------------------------------- + +#define IS_NOT_EVEN(len) ((len) & 1) +#define EVEN(len) (((len) + 1) & ~1) +#define MAGIC_PREFS_LIST_ENTRY_LIST ((UWORD) -1) + +#define min(a,b) ((a) < (b) ? (a) : (b)) + +#ifdef __amigaos4__ +#define ExtLib(base) ((struct ExtendedLibrary *)((ULONG)base + ((struct Library *)base)->lib_PosSize)) +#define IScalosGfx ((struct ScaosGfxIFace *)ExtLib(ScalosGfxBase)->MainIFace) +#endif + +//---------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- + +// Standard library functions + +//---------------------------------------------------------------------------- + +struct ExecBase *SysBase; +struct IntuitionBase *IntuitionBase; +T_UTILITYBASE UtilityBase; +struct DosLibrary * DOSBase; +struct Library *CyberGfxBase; +struct GfxBase *GfxBase; +struct Library *LayersBase; +#ifdef __amigaos4__ +struct Library *NewlibBase; +struct Interface *INewlib; +struct GraphicsIFace *IGraphics; +struct ExecIFace *IExec; +struct IntuitionIFace *IIntuition; +struct UtilityIFace *IUtility; +struct DOSIFace *IDOS; +struct CyberGfxIFace *ICyberGfx; +struct LayersIFace *ILayers; +#endif + +//---------------------------------------------------------------------------- + +char ALIGNED libName[] = "scalosgfx.library"; +char ALIGNED libIdString[] = "$VER: scalosgfx.library " + STR(LIB_VERSION) "." STR(LIB_REVISION) + " (29 Jul 2008 19:29:17) " + COMPILER_STRING + " ©2006" CURRENTYEAR " The Scalos Team"; + +//---------------------------------------------------------------------------- + + +BOOL ScalosGfxInit(struct ScalosGfxBase *ScalosGfxBase) +{ + d1(kprintf("%s/%ld: START ScalosGfxBase=%08lx procName=<%s>\n", __FUNC__, __LINE__, \ + ScalosGfxBase, FindTask(NULL)->tc_Node.ln_Name)); + + NewList(&ScalosGfxBase->sgb_PrefsList); + + InitSemaphore(&ScalosGfxBase->sgb_MemPoolSemaphore); + InitSemaphore(&ScalosGfxBase->sgb_PrefsListSem); + + d1(kprintf("%s/%ld: END Success\n", __FUNC__, __LINE__)); + + return TRUE; // Success +} + +//----------------------------------------------------------------------------- + +BOOL ScalosGfxOpen(struct ScalosGfxBase *ScalosGfxBase) +{ + BOOL Success = FALSE; + + d1(kprintf("%s/%ld: START ScalosGfxBase=%08lx procName=<%s>\n", __FUNC__, __LINE__, \ + ScalosGfxBase, FindTask(NULL)->tc_Node.ln_Name)); + + do { + IntuitionBase = (APTR) OpenLibrary( "intuition.library", 39 ); +#ifdef __amigaos4__ + if (IntuitionBase) + { + IIntuition = (APTR) GetInterface((struct Library *)IntuitionBase, "main", 1, NULL); + if (!IIntuition) + { + CloseLibrary((struct Library *)IntuitionBase); + IntuitionBase = NULL; + } + } +#endif + if (NULL == IntuitionBase) + break; + + UtilityBase = (APTR) OpenLibrary( "utility.library", 39 ); +#ifdef __amigaos4__ + if (UtilityBase) + { + IUtility = (APTR) GetInterface((struct Library *)UtilityBase, "main", 1, NULL); + if (!IUtility) + { + CloseLibrary((struct Library *)UtilityBase); + UtilityBase = NULL; + } + } +#endif + if (NULL == UtilityBase) + break; + + GfxBase = (struct GfxBase *) OpenLibrary(GRAPHICSNAME, 39); +#ifdef __amigaos4__ + if (GfxBase != NULL) + { + IGraphics = (struct GraphicsIFace *)GetInterface((struct Library *)GfxBase, "main", 1, NULL); + if (IGraphics == NULL) + { + CloseLibrary((struct Library *)GfxBase); + GfxBase = NULL; + } + } +#endif + d1(kprintf("%s/%ld: GfxBase=%08lx\n", __FUNC__, __LINE__, GfxBase)); + if (NULL == GfxBase) + return 0; + + CyberGfxBase = (APTR) OpenLibrary( "cybergraphics.library", 40); +#ifdef __amigaos4__ + if (CyberGfxBase) + { + ICyberGfx = (APTR) GetInterface((struct Library *)CyberGfxBase, "main", 1, NULL); + if (!ICyberGfx) + { + CloseLibrary(CyberGfxBase); + CyberGfxBase = NULL; + } + } +#endif + // CyberGfxBase may be NULL + + DOSBase = (APTR) OpenLibrary( "dos.library", 39 ); +#ifdef __amigaos4__ + if (DOSBase) + { + IDOS = (APTR) GetInterface((struct Library *)DOSBase, "main", 1, NULL); + if (!IDOS) + { + CloseLibrary((struct Library *)DOSBase); + DOSBase = NULL; + } + } +#endif + if (NULL == DOSBase) + break; + + LayersBase = OpenLibrary( "layers.library", 39 ); +#ifdef __amigaos4__ + if (LayersBase) + { + ILayers = (APTR) GetInterface(LayersBase, "main", 1, NULL); + if (!ILayers) + { + CloseLibrary(LayersBase); + LayersBase = NULL; + } + } +#endif + if (NULL == LayersBase) + break; + +#ifdef __amigaos4__ + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + break; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + break; +#endif + + ScalosGfxBase->sgb_MemPool = CreatePool(MEMF_PUBLIC | MEMF_CLEAR, 8192, 256); + if (NULL == ScalosGfxBase->sgb_MemPool) + break; + + Success = TRUE; + } while (0); + + d1(kprintf("%s/%ld: END Success=%ld\n", __FUNC__, __LINE__, Success)); + + return Success; +} + +//----------------------------------------------------------------------------- + +void ScalosGfxCleanup(struct ScalosGfxBase *ScalosGfxBase) +{ + d1(kprintf("%s/%ld:\n", __FUNC__, __LINE__)); + + if (CyberGfxBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)ICyberGfx); +#endif + CloseLibrary(CyberGfxBase); + CyberGfxBase = NULL; + } + if (NULL != GfxBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)IGraphics); +#endif + CloseLibrary((struct Library *) GfxBase); + GfxBase = NULL; + } + if (UtilityBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)IUtility); +#endif + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } + if (IntuitionBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)IIntuition); +#endif + CloseLibrary((struct Library *) IntuitionBase); + IntuitionBase = NULL; + } + if (DOSBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)IDOS); +#endif + CloseLibrary((struct Library *) DOSBase); + DOSBase = NULL; + } + if (LayersBase) + { +#ifdef __amigaos4__ + DropInterface((struct Interface *)ILayers); +#endif + CloseLibrary(LayersBase); + LayersBase = NULL; + } +#ifdef __amigaos4__ + if (INewlib) + { + DropInterface(INewlib); + INewlib = NULL; + } + if (NewlibBase) + { + CloseLibrary(NewlibBase); + NewlibBase = NULL; + } +#endif + if (ScalosGfxBase->sgb_MemPool) + { + DeletePool(ScalosGfxBase->sgb_MemPool); + ScalosGfxBase->sgb_MemPool = NULL; + } + d1(kprintf("%s/%ld:\n", __FUNC__, __LINE__)); +} + +//----------------------------------------------------------------------------- + +LIBFUNC_P1(struct ScalosBitMapAndColor *, LIBScalosGfxCreateEmptySAC, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + return AllocEmptySAC(ScalosGfxBase); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P6(struct ScalosBitMapAndColor *, LIBScalosGfxCreateSAC, + D0, ULONG, width, + D1, ULONG, height, + D2, ULONG, depth, + A0, struct BitMap *, friendBM, + A1, struct TagItem *, tagList, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + (void) tagList; + + return AllocSAC(width, height, depth, friendBM, tagList, ScalosGfxBase); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(VOID, LIBScalosGfxFreeSAC, + A0, struct ScalosBitMapAndColor *, sac, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + FreeSAC(sac, ScalosGfxBase); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P4(struct gfxARGB *, LIBScalosGfxCreateARGB, + D0, ULONG, width, + D1, ULONG, height, + A0, struct TagItem *, tagList, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + (void) tagList; + + return AllocARGB(width, height, ScalosGfxBase); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(VOID, LIBScalosGfxFreeARGB, + A0, struct gfxARGB **, argb, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + FreeARGB(argb, ScalosGfxBase); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P3(VOID, LIBScalosGfxARGBSetAlpha, + A0, struct ARGBHeader *, argbh, + D0, UBYTE, alpha, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + (void) ScalosGfxBase; + + ARGBSetAlpha(argbh->argb_ImageData, + argbh->argb_Width, argbh->argb_Height, alpha); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P3(VOID, LIBScalosGfxARGBSetAlphaMask, + A0, struct ARGBHeader *, argbh, + A1, PLANEPTR, maskPlane, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + (void) ScalosGfxBase; + + ARGBSetAlphaFromMask(argbh, maskPlane); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P7(struct gfxARGB *, LIBScalosGfxCreateARGBFromBitMap, + A0, struct BitMap *,bm, + D0, ULONG, width, + D1, ULONG, height, + D2, ULONG, numberOfColors, + A1, const ULONG *, colorTable, + A2, PLANEPTR, maskPlane, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + return CreateARGBFromBitMap(bm, width, height, + numberOfColors, colorTable, maskPlane, ScalosGfxBase); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P4(VOID, LIBScalosGfxFillARGBFromBitMap, + A0, struct ARGBHeader *, argbh, + A1, struct BitMap *, srcBM, + A2, PLANEPTR, maskPlane, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + (void) ScalosGfxBase; + + FillARGBFromBitMap(argbh, srcBM, maskPlane); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P5(VOID, LIBScalosGfxWriteARGBToBitMap, + A0, struct ARGBHeader *, argbh, + A1, struct BitMap *, bm, + D0, ULONG, numberOfColors, + A2, const ULONG *, colorTable, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + (void) ScalosGfxBase; + + WriteARGBToBitMap(argbh->argb_ImageData, bm, + argbh->argb_Width, argbh->argb_Height, + numberOfColors, colorTable, ScalosGfxBase); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P4(struct ScalosBitMapAndColor *, LIBScalosGfxMedianCut, + A0, struct ARGBHeader *, argbh, + D0, ULONG, depth, + A1, struct TagItem *, tagList, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + ULONG flags; + BOOL floyd; + struct BitMap *friendBM; + ULONG ReservedColors; + ULONG NewColors; + struct ScalosBitMapAndColor *sac = NULL; + + d1(KPrintF(__FILE__ "/%s/%ld: START tagList=%08lx\n", __FUNC__, __LINE__, tagList)); + + flags = GetTagData(SCALOSGFX_MedianCutFlags, 0, tagList); + floyd = flags & SCALOSGFXFLAGF_MedianCut_FloydSteinberg; + ReservedColors = GetTagData(SCALOSGFX_MedianCutReservedColors, 0, tagList); + friendBM = (struct BitMap *) GetTagData(SCALOSGFX_MedianCutFriendBitMap, (ULONG)NULL, tagList); + + d1(KPrintF(__FILE__ "/%s/%ld: flags=%08lx ReservedColors=%lu\n", __FUNC__, __LINE__, flags, ReservedColors)); + + NewColors = 1 << depth; + + do { + NewColors += ReservedColors; + if (NewColors > 256) + break; + + // adjst depth for reserved colors + while (NewColors > (1 << depth)) + depth++; + + d1(KPrintF("%s/%ld: NewColors=%lu depth=%lu ReservedColors=%lu\n", \ + __FUNC__, __LINE__, NewColors, depth, ReservedColors)); + + sac = MedianCut(argbh, depth, NewColors, floyd, friendBM, ScalosGfxBase); + } while (0); + + return sac; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P5(struct gfxARGB *, LIBScalosGfxScaleARGBArray, + A0, const struct ARGBHeader *, src, + A1, ULONG *, destWidth, + A2, ULONG *, destHeight, + A3, struct TagItem *, tagList, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + ULONG flags; + + flags = GetTagData(SCALOSGFX_ScaleARGBArrayFlags, 0, tagList); + + return ScaleARGBArray(src, destWidth, destHeight, flags, ScalosGfxBase); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P3(struct BitMap *, LIBScalosGfxScaleBitMap, + A0, struct ScaleBitMapArg *, sbma, + A1, struct TagItem *, tagList, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + (void) tagList; + + return ScaleBitMap(sbma->sbma_SourceBM, + sbma->sbma_SourceWidth, + sbma->sbma_SourceHeight, + sbma->sbma_DestWidth, + sbma->sbma_DestHeight, + sbma->sbma_NumberOfColors, + sbma->sbma_ColorTable, + sbma->sbma_Flags, + sbma->sbma_ScreenBM, + ScalosGfxBase); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P5(VOID, LIBScalosGfxCalculateScaleAspect, + D0, ULONG, sourceWidth, + D1, ULONG, sourceHeight, + A0, ULONG *, destWidth, + A1, ULONG *, destHeight, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + (void) ScalosGfxBase; + + CalculateScaleAspect(sourceWidth, sourceHeight, destWidth, destHeight); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P9(VOID, LIBScalosGfxBlitARGB, + A0, struct ARGBHeader *, DestARGB, + A1, const struct ARGBHeader *, SrcARGB, + D0, LONG, DestLeft, + D1, LONG, DestTop, + D2, LONG, SrcLeft, + D3, LONG, SrcTop, + D4, LONG, Width, + D5, LONG, Height, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + (void) ScalosGfxBase; + + BlitARGB(DestARGB, SrcARGB, DestLeft, DestTop, + SrcLeft, SrcTop, Width, Height); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +// Fill a rectangle with a given ARGB color. + +LIBFUNC_P7(VOID, LIBScalosGfxFillRectARGB, + A0, struct ARGBHeader *, DestARGB, + A1, const struct gfxARGB *, fillARGB, + D0, LONG, left, + D1, LONG, top, + D2, LONG, width, + D3, LONG, height, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + (void) ScalosGfxBase; + + FillARGB(DestARGB, fillARGB, left, top, width, height); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +// Fill entire ARGB with given ARGB color + +LIBFUNC_P3(VOID, LIBScalosGfxSetARGB, + A0, struct ARGBHeader *, DestARGB, + A1, const struct gfxARGB *, fillARGB, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + (void) ScalosGfxBase; + + SetARGB(DestARGB, fillARGB); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +// replace ColorMap in sac by given new one + +LIBFUNC_P4(BOOL, LIBScalosGfxNewColorMap, + A0, struct ScalosBitMapAndColor *, sac, + A1, const ULONG *, colorMap, + D0, ULONG, colorEntries, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + (void) ScalosGfxBase; + + return SetNewSacColorMap(sac, colorMap, colorEntries, ScalosGfxBase); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P8(VOID, LIBScalosGfxARGBRectMult, + A0, struct RastPort *, rp, + A1, const struct ARGB *, numerator, + A2, const struct ARGB *, denominator, + D0, WORD, xMin, + D1, WORD, yMin, + D2, WORD, xMax, + D3, WORD, yMax, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + ARGBRectMult(rp, *numerator, *denominator, + xMin, yMin, + xMax, yMax, + ScalosGfxBase); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P9(VOID, LIBScalosGfxBlitARGBAlpha, + A0, struct RastPort *, rp, + A1, const struct ARGBHeader *, srcH, + D0, ULONG, destLeft, + D1, ULONG, destTop, + D2, ULONG, srcLeft, + D3, ULONG, srcTop, + D4, ULONG, width, + D5, ULONG, height, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + BlitARGBAlpha(rp, srcH, + destLeft, destTop, + srcLeft, srcTop, + width, height, + ScalosGfxBase); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P7(VOID, LIBScalosGfxBlitARGBAlphaTagList, + A0, struct RastPort *, rp, + A1, const struct ARGBHeader *, srcH, + D0, ULONG, destLeft, + D1, ULONG, destTop, + A3, const struct IBox *, srcSize, + A2, struct TagItem *, tagList, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + const struct ARGB KDefault = { 255, 0, 0, 0 }; + const struct ARGB *K; + ULONG Trans; + ULONG NoAlpha; + + K = (const struct ARGB *) GetTagData(SCALOSGFX_BlitARGBHilight, (ULONG) NULL, tagList); + Trans = GetTagData(SCALOSGFX_BlitARGBTransparency, 255, tagList); + NoAlpha = GetTagData(SCALOSGFX_BlitARGBNoAlpha, FALSE, tagList); + + if (NoAlpha) + { + if (NULL == K) + K = &KDefault; + + d1(KPrintF("%s/%ld: Red=%ld Green=%ld Blue=%ld Trans=%lu\n", __FUNC__, __LINE__, K->Red, K->Green, K->Blue, Trans)); + + BlitARGBKT(rp, srcH, + destLeft, destTop, + srcSize->Left, srcSize->Top, + srcSize->Width, srcSize->Height, + K, Trans, + ScalosGfxBase); + } + else if (K || 255 != Trans) + { + d1(KPrintF("%s/%ld: Red=%ld Green=%ld Blue=%ld Trans=%lu\n", __FUNC__, __LINE__, K->Red, K->Green, K->Blue, Trans)); + BlitARGBAlphaKT(rp, srcH, + destLeft, destTop, + srcSize->Left, srcSize->Top, + srcSize->Width, srcSize->Height, + K, Trans, + ScalosGfxBase); + } + else + { + BlitARGBAlpha(rp, srcH, + destLeft, destTop, + srcSize->Left, srcSize->Top, + srcSize->Width, srcSize->Height, + ScalosGfxBase); + } +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P8(VOID, LIBScalosGfxBlitIcon, + A0, struct RastPort *, rpBackground, + A1, struct RastPort *, rpIcon, + D0, ULONG, left, + D1, ULONG, top, + D2, ULONG, width, + D3, ULONG, height, + A2, struct TagItem *, tagList, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + const struct ARGB *K; + const UBYTE *Alpha; + ULONG Trans; + + K = (const struct ARGB *) GetTagData(SCALOSGFX_BlitIconHilight, (ULONG) NULL, tagList); + Alpha = (const UBYTE *) GetTagData(SCALOSGFX_BlitIconAlpha, (ULONG) NULL, tagList); + Trans = GetTagData(SCALOSGFX_BlitIconTransparency, 255, tagList); + + if (Alpha) + { + if (K) + { + BlitTransparentAlphaK(rpBackground, rpIcon, + left, top, width, height, + K, Alpha, ScalosGfxBase); + } + else + { + BlitTransparentAlpha(rpBackground, rpIcon, + left, top, width, height, + Trans, Alpha, ScalosGfxBase); + } + } + else + { + if (K) + { + BlitTransparentK(rpBackground, rpIcon, + left, top, width, height, + K, ScalosGfxBase); + } + else + { + BlitTransparent(rpBackground, rpIcon, + left, top, width, height, + Trans, ScalosGfxBase); + } + } +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P9(BOOL, LIBScalosGfxDrawGradient, + A0, struct ARGBHeader *, dest, + D0, LONG, left, + D1, LONG, top, + D2, LONG, width, + D3, LONG, height, + A1, struct gfxARGB *, start, + A2, struct gfxARGB *, stop, + D4, ULONG, gradType, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + return ScaDrawGradient(dest, left, top, width, height, start, stop, gradType, ScalosGfxBase); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P9(BOOL, LIBScalosGfxDrawGradientRastPort, + A0, struct RastPort *, rp, + D0, LONG, left, + D1, LONG, top, + D2, LONG, width, + D3, LONG, height, + A1, struct gfxARGB *, start, + A2, struct gfxARGB *, stop, + D4, ULONG, gradType, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + return DrawGradientRastPort(rp, left, top, width, height, start, stop, gradType, ScalosGfxBase); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P7(VOID, LIBScalosGfxDrawLine, + A0, struct ARGBHeader *, dest, + D0, LONG, fromX, + D1, LONG, fromY, + D2, LONG, toX, + D3, LONG, toY, + A1, const struct gfxARGB *, lineColor, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + (void) ScalosGfxBase; + + DrawLine(dest, fromX, fromY, toX, toY, *lineColor); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P7(VOID, LIBScalosGfxDrawLineRastPort, + A0, struct RastPort *, rp, + D0, LONG, fromX, + D1, LONG, fromY, + D2, LONG, toX, + D3, LONG, toY, + A1, const struct gfxARGB *, lineColor, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + (void) ScalosGfxBase; + + DrawLineRastPort(rp, fromX, fromY, toX, toY, *lineColor); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P9(VOID, LIBScalosGfxDrawEllipse, + A0, struct ARGBHeader *, dest, + D0, LONG, xCenter, + D1, LONG, yCenter, + D2, LONG, radiusX, + D3, LONG, radiusY, + D4, WORD, segment, + A1, const struct gfxARGB *, color1, + A2, const struct gfxARGB *, color2, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + (void) ScalosGfxBase; + + DrawARGBEllipse(dest, xCenter, yCenter, radiusX, radiusY, + segment, *color1, *color2); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P9(VOID, LIBScalosGfxDrawEllipseRastPort, + A0, struct RastPort *, rp, + D0, LONG, xCenter, + D1, LONG, yCenter, + D2, LONG, radiusX, + D3, LONG, radiusY, + D4, WORD, segment, + A1, const struct gfxARGB *, color1, + A2, const struct gfxARGB *, color2, + A6, struct ScalosGfxBase *, ScalosGfxBase) +{ + (void) ScalosGfxBase; + + DrawARGBEllipseRastPort(rp, xCenter, yCenter, radiusX, radiusY, + segment, *color1, *color2); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +APTR ScalosGfxAllocVecPooled(struct ScalosGfxBase *ScalosGfxBase, ULONG Size) +{ + APTR ptr; + + if (ScalosGfxBase->sgb_MemPool) + { + ObtainSemaphore(&ScalosGfxBase->sgb_MemPoolSemaphore); + ptr = AllocPooled(ScalosGfxBase->sgb_MemPool, Size + sizeof(size_t)); + ReleaseSemaphore(&ScalosGfxBase->sgb_MemPoolSemaphore); + if (ptr) + { + size_t *sptr = (size_t *) ptr; + + sptr[0] = Size; + + d1(kprintf("%s/%ld: MemPool=%08lx Size=%lu mem=%08lx\n", __FUNC__, __LINE__, ScalosGfxBase->sgb_MemPool, Size, &sptr[1])); + return (APTR)(&sptr[1]); + } + } + + d1(kprintf("%s/%ld: MemPool=%08lx Size=%lu\n", __FUNC__, __LINE__, ScalosGfxBase->sgb_MemPool, Size)); + + return NULL; +} + +//----------------------------------------------------------------------------- + +void ScalosGfxFreeVecPooled(struct ScalosGfxBase *ScalosGfxBase, APTR mem) +{ + d1(kprintf("%s/%ld: MemPool=%08lx mem=%08lx\n", __FUNC__, __LINE__, ScalosGfxBase->sgb_MemPool, mem)); + if (ScalosGfxBase->sgb_MemPool && mem) + { + size_t size; + size_t *sptr = (size_t *) mem; + + mem = &sptr[-1]; + size = sptr[-1]; + + ObtainSemaphore(&ScalosGfxBase->sgb_MemPoolSemaphore); + FreePooled(ScalosGfxBase->sgb_MemPool, mem, size + sizeof(size_t)); + ReleaseSemaphore(&ScalosGfxBase->sgb_MemPoolSemaphore); + } +} + +//----------------------------------------------------------------------------- + +#if !defined(__SASC) && !defined(__amigaos4__) +void exit(int x) +{ + (void) x; + while (1) + ; +} + +#endif /* !defined(__SASC) */ + +//----------------------------------------------------------------------------- + +#if defined(__SASC) +void _XCEXIT(long x) +{ +} +#endif /* defined(__SASC) */ + +//---------------------------------------------------------------------------- diff --git a/scalos/libraries/scalosgfx/scalosgfx.h b/scalos/libraries/scalosgfx/scalosgfx.h new file mode 100644 index 000000000..283af6ccc --- /dev/null +++ b/scalos/libraries/scalosgfx/scalosgfx.h @@ -0,0 +1,458 @@ +// scalosgfx.h +// $Date$ +// $Revision$ + + +#ifndef SCALOSGFX_H +#define SCALOSGFX_H + +#include +#include +#include +#include +#include + +#include + +#include "scalosgfx_base.h" + +//---------------------------------------------------------------------------- + +#define LIB_VERSION 42 +#define LIB_REVISION 2 + +//---------------------------------------------------------------------------- + +#if defined(__MORPHOS__) && !defined(ProcessPixelArrayTags) +#define ProcessPixelArrayTags(rp, destX, destY, sizeX, sizeY, operation, value, tags...) \ + ({ULONG _tags[] = {tags}; ProcessPixelArray((rp), (destX), (destY), (sizeX), (sizeY), (operation), (value), (struct TagItem *) _tags);}) +#endif //defined(__MORPHOS__) && !defined(ProcessPixelArrayTags) + +//---------------------------------------------------------------------------- + +// RGB16: rrrr rggg gggb bbbb +// BGR16: bbbb bggg gggr rrrr +// RGB15: 0rrr rrgg gggb bbbb +// GBR15: 0bbb bbgg gggr rrrr + +// RGB16PC: gggb bbbb rrrr rggg +// BGR16PC: gggr rrrr bbbb bggg +// RGB15PC: gggb bbbb 0rrr rrgg +// GBR15PC: gggr rrrr 0bbb bbgg + +#define GET_RED_RGB16(p) ((*((UWORD *) (p)) & 0xf800) >> 8) +#define GET_GREEN_RGB16(p) ((*((UWORD *) (p)) & 0x07e0) >> 3) +#define GET_BLUE_RGB16(p) ((*((UWORD *) (p)) & 0x001f) << 3) + +#define GET_RED_BGR16(p) ((*((UWORD *) (p)) & 0x001f) << 3) +#define GET_GREEN_BGR16(p) ((*((UWORD *) (p)) & 0x07e0) >> 3) +#define GET_BLUE_BGR16(p) ((*((UWORD *) (p)) & 0xf800) >> 8) + +#define GET_RED_RGB15(p) ((*((UWORD *) (p)) & 0x7c00) >> 7) +#define GET_GREEN_RGB15(p) ((*((UWORD *) (p)) & 0x03e0) >> 2) +#define GET_BLUE_RGB15(p) ((*((UWORD *) (p)) & 0x001f) << 3) + +#define GET_RED_BGR15(p) ((*((UWORD *) (p)) & 0x001f) << 3) +#define GET_GREEN_BGR15(p) ((*((UWORD *) (p)) & 0x03e0) >> 2) +#define GET_BLUE_BGR15(p) ((*((UWORD *) (p)) & 0x7c00) >> 7) + +#define SET_RED_RGB16(r) (((r) << 8) & 0xf800) +#define SET_GREEN_RGB16(g) (((g) << 3) & 0x07e0) +#define SET_BLUE_RGB16(b) (((b) >> 3) & 0x001f) + +#define SET_RED_BGR16(r) (((r) >> 3) & 0x001f) +#define SET_GREEN_BGR16(g) (((g) << 3) & 0x07e0) +#define SET_BLUE_BGR16(b) (((b) << 8) & 0xf800) + +#define SET_RED_RGB15(r) (((r) << 7) & 0x7c00) +#define SET_GREEN_RGB15(g) (((g) << 2) & 0x03e0) +#define SET_BLUE_RGB15(b) (((b) >> 3) & 0x001f) + +#define SET_RED_BGR15(r) (((r) >> 3) & 0x001f) +#define SET_GREEN_BGR15(g) (((g) << 2) & 0x03e0) +#define SET_BLUE_BGR15(b) (((b) << 7) & 0x7c00) + +#define GET_RED_RGB16PC(p) ((*((UWORD *) (p)) & 0x00f8) ) +#define GET_GREEN_RGB16PC(p) (((*((UWORD *) (p)) & 0x0007) << 5) | ((*((UWORD *) (p)) & 0xe000) >> 11)) +#define GET_BLUE_RGB16PC(p) ((*((UWORD *) (p)) & 0x1f00) >> 5) + +#define GET_RED_BGR16PC(p) ((*((UWORD *) (p)) & 0x1f00) >> 5) +#define GET_GREEN_BGR16PC(p) (((*((UWORD *) (p)) & 0x0007) << 5) | ((*((UWORD *) (p)) & 0xe000) >> 11)) +#define GET_BLUE_BGR16PC(p) ((*((UWORD *) (p)) & 0x00f8) ) + +#define GET_RED_RGB15PC(p) ((*((UWORD *) (p)) & 0x007c) << 1) +#define GET_GREEN_RGB15PC(p) (((*((UWORD *) (p)) & 0x0003) << 6) | ((*((UWORD *) (p)) & 0xe000) >> 10)) +#define GET_BLUE_RGB15PC(p) ((*((UWORD *) (p)) & 0x1f00) >> 5) + +#define GET_RED_BGR15PC(p) ((*((UWORD *) (p)) & 0x1f00) >> 5) +#define GET_GREEN_BGR15PC(p) (((*((UWORD *) (p)) & 0x0003) << 6) | ((*((UWORD *) (p)) & 0xe000) >> 10)) +#define GET_BLUE_BGR15PC(p) ((*((UWORD *) (p)) & 0x007c) << 1) + +#define SET_RED_RGB16PC(r) (((r) ) & 0x00f8) +#define SET_GREEN_RGB16PC(g) ((((g) >> 5) & 0x0007) | (((g) << 11) & 0xe000)) +#define SET_BLUE_RGB16PC(b) (((b) << 5) & 0x1f00) + +#define SET_RED_BGR16PC(r) (((r) << 5) & 0x1f00) +#define SET_GREEN_BGR16PC(g) ((((g) >> 5) & 0x0007) | (((g) << 11) & 0xe000)) +#define SET_BLUE_BGR16PC(b) (((b) ) & 0x00f8) + +#define SET_RED_RGB15PC(r) (((r) >> 1) & 0x007c) +#define SET_GREEN_RGB15PC(g) ((((g) >> 6) & 0x0003) | (((g) << 10) & 0xe000)) +#define SET_BLUE_RGB15PC(b) (((b) << 5) & 0x1f00) + +#define SET_RED_BGR15PC(r) (((r) << 5) & 0x1f00) +#define SET_GREEN_BGR15PC(g) ((((g) >> 6) & 0x0003) | (((g) << 10) & 0xe000)) +#define SET_BLUE_BGR15PC(b) (((b) >> 1) & 0x007c) + + +#define min(a, b) ((a) < (b) ? (a) : (b)) + +//---------------------------------------------------------------------------- + +extern char ALIGNED libName[]; +extern char ALIGNED libIdString[]; + +extern struct ExecBase *SysBase; +extern struct Library *CyberGfxBase; + +//---------------------------------------------------------------------------- + +BOOL ScalosGfxInit(struct ScalosGfxBase *ScalosGfxBase); +BOOL ScalosGfxOpen(struct ScalosGfxBase *ScalosGfxBase); +void ScalosGfxCleanup(struct ScalosGfxBase *ScalosGfxBase); + +LIBFUNC_P1_PROTO(struct ScalosBitMapAndColor *, LIBScalosGfxCreateEmptySAC, + A6, struct ScalosGfxBase *, ScalosGfxBase); +LIBFUNC_P6_PROTO(struct ScalosBitMapAndColor *, LIBScalosGfxCreateSAC, + D0, ULONG, width, + D1, ULONG, height, + D2, ULONG, depth, + A0, struct BitMap *, friendBM, + A1, struct TagItem *, tagList, + A6, struct ScalosGfxBase *, ScalosGfxBase); +LIBFUNC_P2_PROTO(VOID, LIBScalosGfxFreeSAC, + A0, struct ScalosBitMapAndColor *, sac, + A6, struct ScalosGfxBase *, ScalosGfxBase); +LIBFUNC_P4_PROTO(struct gfxARGB *, LIBScalosGfxCreateARGB, + D0, ULONG, width, + D1, ULONG, height, + A0, struct TagItem *, tagList, + A6, struct ScalosGfxBase *, ScalosGfxBase); +LIBFUNC_P2_PROTO(VOID, LIBScalosGfxFreeARGB, + A0, struct gfxARGB **, argb, + A6, struct ScalosGfxBase *, ScalosGfxBase); +LIBFUNC_P3_PROTO(VOID, LIBScalosGfxARGBSetAlpha, + A0, struct ARGBHeader *, argbh, + D0, UBYTE, alpha, + A6, struct ScalosGfxBase *, ScalosGfxBase); +LIBFUNC_P3_PROTO(VOID, LIBScalosGfxARGBSetAlphaMask, + A0, struct ARGBHeader *, argbh, + A1, PLANEPTR, maskPlane, + A6, struct ScalosGfxBase *, ScalosGfxBase); +LIBFUNC_P7_PROTO(struct gfxARGB *, LIBScalosGfxCreateARGBFromBitMap, + A0, struct BitMap *,bm, + D0, ULONG, width, + D1, ULONG, height, + D2, ULONG, numberOfColors, + A1, const ULONG *, colorTable, + A2, PLANEPTR, maskPlane, + A6, struct ScalosGfxBase *, ScalosGfxBase); +LIBFUNC_P4_PROTO(VOID, LIBScalosGfxFillARGBFromBitMap, + A0, struct ARGBHeader *, argbh, + A1, struct BitMap *, srcBM, + A2, PLANEPTR, maskPlane, + A6, struct ScalosGfxBase *, ScalosGfxBase); +LIBFUNC_P5_PROTO(VOID, LIBScalosGfxWriteARGBToBitMap, + A0, struct ARGBHeader *, argbh, + A1, struct BitMap *, bm, + D0, ULONG, numberOfColors, + A2, const ULONG *, colorTable, + A6, struct ScalosGfxBase *, ScalosGfxBase); +LIBFUNC_P4_PROTO(struct ScalosBitMapAndColor *, LIBScalosGfxMedianCut, + A0, struct ARGBHeader *, argbh, + D0, ULONG, depth, + A1, struct TagItem *, tagList, + A6, struct ScalosGfxBase *, ScalosGfxBase); +LIBFUNC_P5_PROTO(struct gfxARGB *, LIBScalosGfxScaleARGBArray, + A0, const struct ARGBHeader *, src, + A1, ULONG *, destWidth, + A2, ULONG *, destHeight, + A3, struct TagItem *, tagList, + A6, struct ScalosGfxBase *, ScalosGfxBase); +LIBFUNC_P3_PROTO(struct BitMap *, LIBScalosGfxScaleBitMap, + A0, struct ScaleBitMapArg *, sbma, + A1, struct TagItem *, tagList, + A6, struct ScalosGfxBase *, ScalosGfxBase); +LIBFUNC_P5_PROTO(VOID, LIBScalosGfxCalculateScaleAspect, + D0, ULONG, sourceWidth, + D1, ULONG, sourceHeight, + A0, ULONG *, destWidth, + A1, ULONG *, destHeight, + A6, struct ScalosGfxBase *, ScalosGfxBase); +LIBFUNC_P9_PROTO(VOID, LIBScalosGfxBlitARGB, + A0, struct ARGBHeader *, DestARGB, + A1, const struct ARGBHeader *, SrcARGB, + D0, LONG, DestLeft, + D1, LONG, DestTop, + D2, LONG, SrcLeft, + D3, LONG, SrcTop, + D4, LONG, Width, + D5, LONG, Height, + A6, struct ScalosGfxBase *, ScalosGfxBase); +LIBFUNC_P7_PROTO(VOID, LIBScalosGfxFillRectARGB, + A0, struct ARGBHeader *, DestARGB, + A1, const struct gfxARGB *, fillARGB, + D0, LONG, left, + D1, LONG, top, + D2, LONG, width, + D3, LONG, height, + A6, struct ScalosGfxBase *, ScalosGfxBase); +LIBFUNC_P3_PROTO(VOID, LIBScalosGfxSetARGB, + A0, struct ARGBHeader *, DestARGB, + A1, const struct gfxARGB *, fillARGB, + A6, struct ScalosGfxBase *, ScalosGfxBase); +LIBFUNC_P4_PROTO(BOOL, LIBScalosGfxNewColorMap, + A0, struct ScalosBitMapAndColor *, sac, + A1, const ULONG *, colorMap, + D0, ULONG, colorEntries, + A6, struct ScalosGfxBase *, ScalosGfxBase); +LIBFUNC_P8_PROTO(VOID, LIBScalosGfxARGBRectMult, + A0, struct RastPort *, rp, + A1, const struct ARGB *, numerator, + A2, const struct ARGB *, denominator, + D0, WORD, xMin, + D1, WORD, yMin, + D2, WORD, xMax, + D3, WORD, yMax, + A6, struct ScalosGfxBase *, ScalosGfxBase); +LIBFUNC_P9_PROTO(VOID, LIBScalosGfxBlitARGBAlpha, + A0, struct RastPort *, rp, + A1, const struct ARGBHeader *, srcH, + D0, ULONG, destLeft, + D1, ULONG, destTop, + D2, ULONG, srcLeft, + D3, ULONG, srcTop, + D4, ULONG, width, + D5, ULONG, height, + A6, struct ScalosGfxBase *, ScalosGfxBase); +LIBFUNC_P7_PROTO(VOID, LIBScalosGfxBlitARGBAlphaTagList, + A0, struct RastPort *, rp, + A1, const struct ARGBHeader *, srcH, + D0, ULONG, destLeft, + D1, ULONG, destTop, + A3, const struct IBox *, srcSize, + A2, struct TagItem *, tagList, + A6, struct ScalosGfxBase *, ScalosGfxBase); +LIBFUNC_P8_PROTO(VOID, LIBScalosGfxBlitIcon, + A0, struct RastPort *, rpBackground, + A1, struct RastPort *, rpIcon, + D0, ULONG, left, + D1, ULONG, top, + D2, ULONG, width, + D3, ULONG, height, + A2, struct TagItem *, tagList, + A6, struct ScalosGfxBase *, ScalosGfxBase); +LIBFUNC_P9_PROTO(BOOL, LIBScalosGfxDrawGradient, + A0, struct ARGBHeader *, dest, + D0, LONG, left, + D1, LONG, top, + D2, LONG, width, + D3, LONG, height, + A1, struct gfxARGB *, start, + A2, struct gfxARGB *, stop, + D4, ULONG, gradType, + A6, struct ScalosGfxBase *, ScalosGfxBase); +LIBFUNC_P9_PROTO(BOOL, LIBScalosGfxDrawGradientRastPort, + A0, struct RastPort *, rp, + D0, LONG, left, + D1, LONG, top, + D2, LONG, width, + D3, LONG, height, + A1, struct gfxARGB *, start, + A2, struct gfxARGB *, stop, + D4, ULONG, gradType, + A6, struct ScalosGfxBase *, ScalosGfxBase); +LIBFUNC_P7_PROTO(VOID, LIBScalosGfxDrawLine, + A0, struct ARGBHeader *, dest, + D0, LONG, fromX, + D1, LONG, fromY, + D2, LONG, toX, + D3, LONG, toY, + A1, const struct gfxARGB *, lineColor, + A6, struct ScalosGfxBase *, ScalosGfxBase); +LIBFUNC_P7_PROTO(VOID, LIBScalosGfxDrawLineRastPort, + A0, struct RastPort *, rp, + D0, LONG, fromX, + D1, LONG, fromY, + D2, LONG, toX, + D3, LONG, toY, + A1, const struct gfxARGB *, lineColor, + A6, struct ScalosGfxBase *, ScalosGfxBase); +LIBFUNC_P9_PROTO(VOID, LIBScalosGfxDrawEllipse, + A0, struct ARGBHeader *, dest, + D0, LONG, xCenter, + D1, LONG, yCenter, + D2, LONG, radiusX, + D3, LONG, radiusY, + D4, WORD, segment, + A1, const struct gfxARGB *, color1, + A2, const struct gfxARGB *, color2, + A6, struct ScalosGfxBase *, ScalosGfxBase); +LIBFUNC_P9_PROTO(VOID, LIBScalosGfxDrawEllipseRastPort, + A0, struct RastPort *, rp, + D0, LONG, xCenter, + D1, LONG, yCenter, + D2, LONG, radiusX, + D3, LONG, radiusY, + D4, WORD, segment, + A1, const struct gfxARGB *, color1, + A2, const struct gfxARGB *, color2, + A6, struct ScalosGfxBase *, ScalosGfxBase); +APTR ScalosGfxAllocVecPooled(struct ScalosGfxBase *ScalosGfxBase, ULONG Size); +void ScalosGfxFreeVecPooled(struct ScalosGfxBase *ScalosGfxBase, APTR mem); + +//---------------------------------------------------------------------------- + +// defined in argb.c +/// +void ARGBSetAlpha(struct ARGB *argb, ULONG Width, ULONG Height, UBYTE Alpha); +void ARGBSetAlphaFromMask(struct ARGBHeader *argbh, PLANEPTR MaskPlane); +struct ARGB *CreateARGBFromBitMap(struct BitMap *bm, + ULONG Width, ULONG Height, + ULONG NumberOfColors, const ULONG *ColorTable, PLANEPTR MaskPlane, + struct ScalosGfxBase *ScalosGfxBase); +void FreeARGB(struct ARGB **argb, struct ScalosGfxBase *ScalosGfxBase); +struct ARGB *AllocARGB(ULONG Width, ULONG Height, struct ScalosGfxBase *ScalosGfxBase); +void FillARGBFromBitMap(struct ARGBHeader *argbh, + struct BitMap *srcBM, PLANEPTR MaskPlane); +void WriteARGBToBitMap(struct ARGB *argb, struct BitMap *bm, + ULONG Width, ULONG Height, + ULONG NumberOfColors, const ULONG *ColorTable, + struct ScalosGfxBase *ScalosGfxBase); +struct ScalosBitMapAndColor *AllocEmptySAC(struct ScalosGfxBase *ScalosGfxBase); +struct ScalosBitMapAndColor *AllocSAC(ULONG Width, ULONG Height, ULONG Depth, + struct BitMap *FriendBM, struct TagItem *TagList, + struct ScalosGfxBase *ScalosGfxBase); +void FreeSAC(struct ScalosBitMapAndColor *sac, struct ScalosGfxBase *ScalosGfxBase); +void BlitARGB(struct ARGBHeader *DestARGB, const struct ARGBHeader *SrcARGB, + LONG DestLeft, LONG DestTop, LONG SrcLeft, LONG SrcTop, + LONG Width, LONG Height); +void FillARGB(struct ARGBHeader *DestARGB, const struct ARGB *fillARGB, + LONG left, LONG tTop, LONG width, LONG height); +void SetARGB(struct ARGBHeader *DestARGB, const struct ARGB *fillARGB); +BOOL SetNewSacColorMap(struct ScalosBitMapAndColor *sac, const ULONG *colorMap, + ULONG colorEntries, struct ScalosGfxBase *ScalosGfxBase); +/// + +//---------------------------------------------------------------------------- + +// defined in BitMapScale.c +/// +struct ARGB *ScaleARGBArray(const struct ARGBHeader *src, + ULONG *DestWidth, ULONG *DestHeight, ULONG Flags, + struct ScalosGfxBase *ScalosGfxBase); +struct BitMap *ScaleBitMap(struct BitMap *SourceBM, + ULONG SourceWidth, ULONG SourceHeight, + ULONG *DestWidth, ULONG *DestHeight, + ULONG NumberOfColors, const ULONG *ColorTable, + ULONG Flags, struct BitMap *ScreenBM, + struct ScalosGfxBase *ScalosGfxBase); +void CalculateScaleAspect(ULONG SourceWidth, ULONG SourceHeight, + ULONG *DestWidth, ULONG *DestHeight); +/// + +//---------------------------------------------------------------------------- + +// defined in Dither.c +/// +struct ScalosBitMapAndColor *MedianCut(struct ARGBHeader *argbh, + ULONG Depth, ULONG newcolors, + BOOL floyd, struct BitMap *FriendBM, + struct ScalosGfxBase *ScalosGfxBase); +/// + +//---------------------------------------------------------------------------- + +// defined in Render.c +/// +BOOL ScaDrawGradient(struct ARGBHeader *dest, LONG left, LONG top, + LONG width, LONG height, struct gfxARGB *start, struct gfxARGB *stop, + ULONG gradType, struct ScalosGfxBase *ScalosGfxBase); +BOOL DrawGradientRastPort(struct RastPort *rp, LONG left, LONG top, + LONG width, LONG height, struct gfxARGB *start, struct gfxARGB *stop, + ULONG gradType, struct ScalosGfxBase *ScalosGfxBase); +void DrawLine(struct ARGBHeader *argbh, LONG X0, LONG Y0, LONG X1, LONG Y1, struct ARGB Color32); +void DrawLineRastPort(struct RastPort *rp, LONG X0, LONG Y0, LONG X1, LONG Y1, struct ARGB Color32); +void DrawARGBEllipse(struct ARGBHeader *argbh, + LONG xc, LONG yc, LONG rx, LONG ry, + WORD Segment, struct ARGB rgbColor1, struct ARGB rgbColor2); +void DrawARGBEllipseRastPort(struct RastPort *rp, + LONG xc, LONG yc, LONG rx, LONG ry, + WORD Segment, struct ARGB rgbColor1, struct ARGB rgbColor2); +/// + +//---------------------------------------------------------------------------- + +// defined in blit.c +/// +void ARGBRectMult(struct RastPort *rp, + struct ARGB Numerator, struct ARGB Denominator, + WORD xMin, WORD yMin, WORD xMax, WORD yMax, + struct ScalosGfxBase *ScalosGfxBase); +void BlitARGBAlpha(struct RastPort *rp, const struct ARGBHeader *SrcH, + ULONG DestLeft, ULONG DestTop, + ULONG SrcLeft, ULONG SrcTop, + ULONG Width, ULONG Height, + struct ScalosGfxBase *ScalosGfxBase); +void BlitARGBAlphaKT(struct RastPort *rp, const struct ARGBHeader *SrcH, + ULONG DestLeft, ULONG DestTop, + ULONG SrcLeft, ULONG SrcTop, + ULONG Width, ULONG Height, + const struct ARGB *K, ULONG Transparency, + struct ScalosGfxBase *ScalosGfxBase); +void BlitARGBKT(struct RastPort *rp, const struct ARGBHeader *SrcH, + ULONG DestLeft, ULONG DestTop, + ULONG SrcLeft, ULONG SrcTop, + ULONG Width, ULONG Height, + const struct ARGB *K, ULONG Transparency, + struct ScalosGfxBase *ScalosGfxBase); +void BlitTransparentK(struct RastPort *rpBackground, struct RastPort *rpIcon, + ULONG Left, ULONG Top, ULONG Width, ULONG Height, + const struct ARGB *K, + struct ScalosGfxBase *ScalosGfxBase); +void BlitTransparent(struct RastPort *rpBackground, struct RastPort *rpIcon, + ULONG Left, ULONG Top, ULONG Width, ULONG Height, + ULONG Trans, + struct ScalosGfxBase *ScalosGfxBase); +void BlitTransparentAlpha(struct RastPort *rpBackground, struct RastPort *rpIcon, + ULONG Left, ULONG Top, ULONG Width, ULONG Height, + ULONG Trans, const UBYTE *Alpha, + struct ScalosGfxBase *ScalosGfxBase); +void BlitTransparentAlphaK(struct RastPort *rpBackground, struct RastPort *rpIcon, + ULONG Left, ULONG Top, ULONG Width, ULONG Height, + const struct ARGB *K, const UBYTE *Alpha, + struct ScalosGfxBase *ScalosGfxBase); +/// +//---------------------------------------------------------------------------- + +#ifndef __AROS__ +extern ULONG HookEntry(); +#endif + +//---------------------------------------------------------------------------- + +#define d1(x) ; +#define d2(x) { Forbid(); x; Permit(); } + +#ifdef __AROS__ +#include +#define KPrintF kprintf +#else +// from debug.lib +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); +#endif + +//---------------------------------------------------------------------------- + +#endif /* SCALOSGFX_H */ diff --git a/scalos/libraries/scalosgfx/scalosgfx_base.h b/scalos/libraries/scalosgfx/scalosgfx_base.h new file mode 100644 index 000000000..99fc23f8d --- /dev/null +++ b/scalos/libraries/scalosgfx/scalosgfx_base.h @@ -0,0 +1,31 @@ +// scalosgfx_base.h +// $Date$ +// $Revision$ + + +#ifndef SCALOSGFXBASE_H +#define SCALOSGFXBASE_H + +#include +#include +#include + + +struct ScalosGfxBase +{ + struct Library sgb_LibNode; + + struct SegList *sgb_SegList; + + BOOL sgb_Initialized; + + struct SignalSemaphore sgb_MemPoolSemaphore; + APTR sgb_MemPool; + + struct SignalSemaphore sgb_PrefsListSem; + struct List sgb_PrefsList; +}; + +//---------------------------------------------------------------------------- + +#endif /* SCALOSGFXBASE_H */ diff --git a/scalos/libraries/sqlite/LibSQLite3.c b/scalos/libraries/sqlite/LibSQLite3.c new file mode 100644 index 000000000..53df09747 --- /dev/null +++ b/scalos/libraries/sqlite/LibSQLite3.c @@ -0,0 +1,1932 @@ +// LibSQLite3.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "sqlite3_base.h" +#include "LibSQLite3.h" +#include +#include + +//---------------------------------------------------------------------------- + +#ifdef __amigaos4__ +#define ExtLib(base) ((struct ExtendedLibrary *)((ULONG)base + ((struct Library *)base)->lib_PosSize)) +#define ISQLite3 ((struct SQLite3IFace *)ExtLib(SQLite3Base)->MainIFace) +#endif + +//---------------------------------------------------------------------------- + +// Standard library functions + +//---------------------------------------------------------------------------- + +struct ExecBase *SysBase; +T_UTILITYBASE UtilityBase; +struct DosLibrary * DOSBase; +T_TIMERBASE TimerBase; +#ifdef __amigaos4__ +struct Library *NewlibBase; +struct Interface *INewlib; +struct ExecIFace *IExec; +struct UtilityIFace *IUtility; +struct DOSIFace *IDOS; +struct TimerIFace *ITimer; +#endif + +#if defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__AROS__) +extern T_UTILITYBASE __UtilityBase; +extern struct Library *__MathIeeeDoubBasBase; +#endif /* defined(__GNUC__) && !defined(__MORPHOS__) */ + +//---------------------------------------------------------------------------- + +char ALIGNED libName[] = "sqlite3.library"; +char ALIGNED libIdString[] = "$VER: sqlite3.library " + STR(LIB_VERSION) "." STR(LIB_REVISION) + " (" __DATE__ ") " + COMPILER_STRING + " ©2006" CURRENTYEAR " The Scalos Team"; + +//---------------------------------------------------------------------------- + +BOOL SQLite3Init(struct SQLite3Base *SQLite3Base) +{ + d1(kprintf("%s/%ld: START SQLite3Base=%08lx procName=<%s>\n",__FUNC__ , __LINE__, \ + SQLite3Base, FindTask(NULL)->tc_Node.ln_Name)); + +#if !defined(__amigaos4__) && !defined(__AROS__) + if (_STI_240_InitMemFunctions()) + return FALSE; +#endif + + d1(kprintf("%s/%ld: END Success\n",__FUNC__ , __LINE__)); + + return TRUE; // Success +} + +//----------------------------------------------------------------------------- + +BOOL SQLite3Open(struct SQLite3Base *SQLite3Base) +{ + BOOL Success = FALSE; + + d1(kprintf("%s/%ld: START SQLite3Base=%08lx procName=<%s>\n", __FUNC__, __LINE__, \ + SQLite3Base, FindTask(NULL)->tc_Node.ln_Name)); + + do { + SQLite3Base->sql3_TimerIO = (T_TIMEREQUEST *)CreateIORequest(CreateMsgPort(), sizeof(T_TIMEREQUEST)); + if (NULL == SQLite3Base->sql3_TimerIO) + break; + + if (0 != OpenDevice("timer.device", UNIT_VBLANK, &SQLite3Base->sql3_TimerIO->tr_node, 0)) + break; + TimerBase = (T_TIMERBASE) SQLite3Base->sql3_TimerIO->tr_node.io_Device; + if (NULL == TimerBase) + break; + +#ifdef __amigaos4__ + ITimer = (struct TimerIFace *)GetInterface(TimerBase, "main", 1, NULL); + if (NULL == ITimer) + break; +#endif /* __amigaos4__ */ + + UtilityBase = (APTR) OpenLibrary( "utility.library", 39 ); + if (NULL == UtilityBase) + break; +#ifdef __amigaos4__ + IUtility = (APTR) GetInterface((struct Library *)UtilityBase, "main", 1, NULL); + if (NULL == IUtility) + break; +#endif /* __amigaos4__ */ + +#if defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) + __UtilityBase = UtilityBase; + + __MathIeeeDoubBasBase = OpenLibrary("mathieeedoubbas.library", 0); + if (NULL == __MathIeeeDoubBasBase) + break; + +#endif /* defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__)*/ + + DOSBase = (APTR) OpenLibrary( "dos.library", 39 ); + if (NULL == DOSBase) + break; +#ifdef __amigaos4__ + IDOS = (APTR) GetInterface((struct Library *)DOSBase, "main", 1, NULL); + if (NULL == IDOS) + break; + NewlibBase = OpenLibrary("newlib.library", 0); + if (NULL == NewlibBase) + break; + INewlib = GetInterface(NewlibBase, "main", 1, NULL); + if (NULL == INewlib) + break; +// kprintf("%s/%s/%ld: NewlibBase=%lx, INewlib=%lx\n", __FILE__, __FUNC__, __LINE__, +// NewlibBase, INewlib +// ); +#endif /* __amigaos4__ */ + + if (SQLITE_OK != sqlite3_config(SQLITE_CONFIG_MUTEX, sqlite3OtherMutex())) + break; + + Success = TRUE; + } while (0); + + d1(kprintf("%s/%ld: END Success=%ld\n", __FUNC__, __LINE__, Success)); + + return Success; +} + +//----------------------------------------------------------------------------- + +void SQLite3Cleanup(struct SQLite3Base *SQLite3Base) +{ + d1(kprintf("%s/%ld: START\n", __FUNC__, __LINE__)); + +#if !defined(__amigaos4__) && !defined(__AROS__) + _STD_240_TerminateMemFunctions(); +#endif + +#if defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) + if (__MathIeeeDoubBasBase) + { + CloseLibrary(__MathIeeeDoubBasBase); + __MathIeeeDoubBasBase = NULL; + } +#endif /* defined(__GNUC__) && !defined(__MORPHOS__) && !defined(__amigaos4__) */ + +#ifdef __amigaos4__ + if (INewlib) + { + DropInterface(INewlib); + INewlib = NULL; + } + if (NewlibBase) + { + CloseLibrary(NewlibBase); + NewlibBase = NULL; + } + if (ITimer) + { + DropInterface((struct Interface *)ITimer); + ITimer = NULL; + } +#endif /* __amigaos4__ */ + if (SQLite3Base->sql3_TimerIO) + { + struct MsgPort *TimerPort = SQLite3Base->sql3_TimerIO->tr_node.io_Message.mn_ReplyPort; + + CloseDevice(&SQLite3Base->sql3_TimerIO->tr_node); + DeleteIORequest(&SQLite3Base->sql3_TimerIO->tr_node); + if (TimerPort) + DeleteMsgPort(TimerPort); + + SQLite3Base->sql3_TimerIO = NULL; + TimerBase = NULL; + } +#ifdef __amigaos4__ + if (IUtility) + { + DropInterface((struct Interface *)IUtility); + IUtility = NULL; + } +#endif /* __amigaos4__ */ + if (UtilityBase) + { + CloseLibrary((struct Library *) UtilityBase); + UtilityBase = NULL; + } +#ifdef __amigaos4__ + if (IDOS) + { + DropInterface((struct Interface *)IDOS); + IDOS = NULL; + } +#endif /* __amigaos4__ */ + if (DOSBase) + { + CloseLibrary((struct Library *) DOSBase); + DOSBase = NULL; + } +} + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(LONG, LIBSQLite3Close, + A0, sqlite3 *, db, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(kprintf("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_close(db); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P6(LONG, LIBSQLite3Exec, + A0, sqlite3 *, db, + A1, CONST_STRPTR, sql, + A2, sqlite3_callback, xCallback, + A3, APTR, pArg, + D0, STRPTR *, errmsg, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START sql=<%s>\n", __FUNC__, __LINE__)); + Result = sqlite3_exec(db, sql, xCallback, pArg, (char **) errmsg); + d1(KPrintF("%s/%ld: END Result=%ld errmsg=<%s>\n", __FUNC__, __LINE__, Result, *errmsg)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(LONG, LIBSQLite3Changes, + A0, sqlite3 *, db, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_changes(db); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(LONG, LIBSQLite3TotalChanges, + A0, sqlite3 *, db, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_total_changes(db); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(VOID, LIBSQLite3Interrupt, + A0, sqlite3 *, db, + A6, struct SQLite3Base *, SQLite3Base) +{ + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + sqlite3_interrupt(db); + d1(KPrintF("%s/%ld: END\n", __FUNC__, __LINE__)); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(LONG, LIBSQLite3Complete, + A0, CONST_STRPTR, sql, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_complete(sql); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P4(LONG, LIBSQLite3BusyHandler, + A0, sqlite3 *, db, + A1, xBusyFunc, callback, + A2, APTR, userdata, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_busy_handler(db, callback, userdata); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P3(LONG, LIBSQLite3BusyTimeout, + A0, sqlite3 *, db, + D0, LONG, ms, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_busy_timeout(db, ms); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P7(LONG, LIBSQLite3GetTable, + A0, sqlite3 *, db, + A1, CONST_STRPTR, sql, + A2, STRPTR **, presult, + A3, LONG *, nrow, + D0, LONG *, ncolumn, + D1, STRPTR *, errmsg, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + int NRow, NColumn; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_get_table(db, sql, (char ***) presult, + &NRow, &NColumn, (char **) errmsg); + *nrow = NRow; + *ncolumn = NColumn; + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(VOID, LIBSQLite3FreeTable, + A0, STRPTR *, result, + A6, struct SQLite3Base *, SQLite3Base) +{ + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + sqlite3_free_table((char **) result); + d1(KPrintF("%s/%ld: END\n", __FUNC__, __LINE__)); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(VOID, LIBSQLite3Free, + A0, STRPTR, z, + A6, struct SQLite3Base *, SQLite3Base) +{ + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + sqlite3_free((char *) z); + d1(KPrintF("%s/%ld: END\n", __FUNC__, __LINE__)); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P4(APTR, LIBSQLite3Trace, + A0, sqlite3 *, db, + A1, xTraceFunc, xTrace, + A2, APTR, parg, + A6, struct SQLite3Base *, SQLite3Base) +{ + APTR Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_trace(db, xTrace, parg); + d1(KPrintF("%s/%ld: END Result=%08lx\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P5(VOID, LIBSQLite3ProgressHandler, + A0, sqlite3 *, db, + D0, LONG, nOps, + A1, xProgressFunc, xProgress, + A2, APTR, pArg, + A6, struct SQLite3Base *, SQLite3Base) +{ + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + sqlite3_progress_handler(db, nOps, xProgress, pArg); + d1(KPrintF("%s/%ld: END\n", __FUNC__, __LINE__)); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P4(APTR, LIBSQLite3CommitHook, + A0, sqlite3 *, db, + A1, xCommitFunc, xCallback, + A2, APTR, pArg, + A6, struct SQLite3Base *, SQLite3Base) +{ + APTR Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_commit_hook(db, xCallback, pArg); + d1(KPrintF("%s/%ld: END Result=%08lx\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P3(LONG, LIBSQLite3Open, + A0, CONST_STRPTR, filename, + A1, sqlite3 **, ppDb, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_open(filename, ppDb); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(LONG, LIBSQLite3Errcode, + A0, sqlite3 *, db, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_errcode(db); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(CONST_STRPTR, LIBSQLite3Errmsg, + A0, sqlite3 *, db, + A6, struct SQLite3Base *, SQLite3Base) +{ + CONST_STRPTR Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_errmsg(db); + d1(KPrintF("%s/%ld: END Result=<%s>\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P6(LONG, LIBSQLite3Prepare, + A0, sqlite3 *, db, + A1, CONST_STRPTR, zSql, + D0, LONG, nBytes, + A2, sqlite3_stmt **, ppStmt, + A3, CONST_STRPTR *, pzTail, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START zSql=<%s>\n", __FUNC__, __LINE__)); + Result = sqlite3_prepare(db, (const char *) zSql, + nBytes, ppStmt, (const char **) pzTail); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P6(LONG, LIBSQLite3BindBlob, + A0, sqlite3_stmt *, pStmt, + D0, LONG, i, + A1, CONST_APTR, zData, + D1, LONG, nData, + A2, xDeleteFunc, xDel, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_bind_blob(pStmt, i, zData, nData, xDel); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P4(LONG, LIBSQLite3BindInt, + A0, sqlite3_stmt *, pStmt, + D0, LONG, i, + D1, LONG, iValue, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_bind_int(pStmt, i, iValue); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P3(LONG, LIBSQLite3BindNull, + A0, sqlite3_stmt *, pStmt, + D0, LONG, i, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_bind_null(pStmt, i); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P6(LONG, LIBSQLite3BindText, + A0, sqlite3_stmt *, pStmt, + D0, LONG, i, + A1, CONST_STRPTR, zData, + D1, LONG, nData, + A2, xDeleteFunc, xDel, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_bind_text(pStmt, i, (const char *) zData, + nData, xDel); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P4(LONG, LIBSQLite3BindValue, + A0, sqlite3_stmt *, pStmt, + D0, LONG, i, + A1, CONST sqlite3_value *, pVal, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); +// Result = sqlite3_bind_value(pStmt, i, pVal); + (void) pStmt; + (void) i; + (void) pVal; + Result = SQLITE_ERROR; + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(LONG, LIBSQLite3BindParameterCount, + A0, sqlite3_stmt *, pStmt, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_bind_parameter_count(pStmt); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P3(CONST_STRPTR, LIBSQLite3BindParameterName, + A0, sqlite3_stmt *, pStmt, + D0, LONG, i, + A6, struct SQLite3Base *, SQLite3Base) +{ + CONST_STRPTR Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_bind_parameter_name(pStmt, i); + d1(KPrintF("%s/%ld: END Result=<%s>\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P3(LONG, LIBSQLite3BindParameterIndex, + A0, sqlite3_stmt *, pStmt, + A1, CONST_STRPTR, zName, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_bind_parameter_index(pStmt, (const char *) zName); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(LONG, LIBSQLite3ClearBindings, + A0, sqlite3_stmt *, pStmt, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_clear_bindings(pStmt); + (void) pStmt; + Result = SQLITE_ERROR; + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(LONG, LIBSQLite3ColumnCount, + A0, sqlite3_stmt *, pStmt, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_column_count(pStmt); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P3(CONST_STRPTR, LIBSQLite3ColumnName, + A0, sqlite3_stmt *, pStmt, + D0, LONG, i, + A6, struct SQLite3Base *, SQLite3Base) +{ + CONST_STRPTR Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_column_name(pStmt, i); + d1(KPrintF("%s/%ld: END Result=<%s>\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P3(CONST_STRPTR, LIBSQLite3ColumnDecltype, + A0, sqlite3_stmt *, pStmt, + D0, LONG, i, + A6, struct SQLite3Base *, SQLite3Base) +{ + CONST_STRPTR Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_column_decltype(pStmt, i); + d1(KPrintF("%s/%ld: END Result=<%s>\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(LONG, LIBSQLite3Step, + A0, sqlite3_stmt *, pStmt, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_step(pStmt); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(LONG, LIBSQLite3DataCount, + A0, sqlite3_stmt *, pStmt, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_data_count(pStmt); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P3(CONST_APTR, LIBSQLite3ColumnBlob, + A0, sqlite3_stmt *, pStmt, + D0, LONG, i, + A6, struct SQLite3Base *, SQLite3Base) +{ + CONST_APTR Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_column_blob(pStmt, i); + d1(KPrintF("%s/%ld: END Result=%08lx\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P3(LONG, LIBSQLite3ColumnBytes, + A0, sqlite3_stmt *, pStmt, + D0, LONG, i, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_column_bytes(pStmt, i); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P3(LONG, LIBSQLite3ColumnInt, + A0, sqlite3_stmt *, pStmt, + D0, LONG, i, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_column_int(pStmt, i); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P3(CONST_STRPTR, LIBSQLite3ColumnText, + A0, sqlite3_stmt *, pStmt, + D0, LONG, i, + A6, struct SQLite3Base *, SQLite3Base) +{ + CONST_STRPTR Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = (CONST_STRPTR)sqlite3_column_text(pStmt, i); + d1(KPrintF("%s/%ld: END Result=<%s>\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P3(LONG, LIBSQLite3ColumnType, + A0, sqlite3_stmt *, pStmt, + D0, LONG, i, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_column_type(pStmt, i); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(LONG, LIBSQLite3Finalize, + A0, sqlite3_stmt *, pStmt, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_finalize(pStmt); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(LONG, LIBSQLite3Reset, + A0, sqlite3_stmt *, pStmt, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_reset(pStmt); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(LONG , LIBSQLite3AggregateCount, + A0, sqlite3_context *, pCtx, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_aggregate_count(pCtx); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(CONST_APTR, LIBSQLite3ValueBlob, + A0, sqlite3_value *, pVal, + A6, struct SQLite3Base *, SQLite3Base) +{ + CONST_APTR Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_value_blob(pVal); + d1(KPrintF("%s/%ld: END Result=%08lx\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(LONG, LIBSQLite3ValueBytes, + A0, sqlite3_value *, pVal, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_value_bytes(pVal); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(LONG, LIBSQLite3ValueInt, + A0, sqlite3_value *, pVal, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_value_int(pVal); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(CONST_STRPTR, LIBSQLite3ValueText, + A0, sqlite3_value *, pVal, + A6, struct SQLite3Base *, SQLite3Base) +{ + CONST_STRPTR Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = (CONST_STRPTR)sqlite3_value_text(pVal); + d1(KPrintF("%s/%ld: END Result=<%s>\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(LONG, LIBSQLite3ValueType, + A0, sqlite3_value *, pVal, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_value_type(pVal); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P3(APTR, LIBSQLite3Aggregate_context, + A0, sqlite3_context *, pCtx, + D0, LONG, nBytes, + A6, struct SQLite3Base *, SQLite3Base) +{ + APTR Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_aggregate_context(pCtx, nBytes); + d1(KPrintF("%s/%ld: END Result=%08lx\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(APTR, LIBSQLite3UserData, + A0, sqlite3_context *, pCtx, + A6, struct SQLite3Base *, SQLite3Base) +{ + APTR Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_user_data(pCtx); + d1(KPrintF("%s/%ld: END Result=%08lx\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P3(APTR, LIBSQLite3GetAuxdata, + A0, sqlite3_context *, pCtx, + D0, LONG, iArg, + A6, struct SQLite3Base *, SQLite3Base) +{ + APTR Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_get_auxdata(pCtx, iArg); + d1(KPrintF("%s/%ld: END Result=%08lx\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P5(VOID, LIBSQLite3SetAuxdata, + A0, sqlite3_context *, pCtx, + D0, LONG, iArg, + A1, APTR, pAux, + A2, xDeleteFunc, xDelete, + A6, struct SQLite3Base *, SQLite3Base) +{ + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + sqlite3_set_auxdata(pCtx, iArg, pAux, xDelete); + d1(kprintf("%s/%ld: END\n", __FUNC__, __LINE__)); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P5(VOID, LIBSQLite3ResultBlob, + A0, sqlite3_context *, pCtx, + A1, CONST_APTR, z, + D1, LONG, n, + A2, xDeleteFunc, xDelete, + A6, struct SQLite3Base *, SQLite3Base) +{ + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + sqlite3_result_blob(pCtx, z, n, xDelete); + d1(kprintf("%s/%ld: END\n", __FUNC__, __LINE__)); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P4(VOID, LIBSQLite3ResultError, + A0, sqlite3_context *, pCtx, + A1, CONST_STRPTR, z, + D0, LONG, n, + A6, struct SQLite3Base *, SQLite3Base) +{ + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + sqlite3_result_error(pCtx, z, n); + d1(kprintf("%s/%ld: END\n", __FUNC__, __LINE__)); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P3(VOID, LIBSQLite3ResultInt, + A0, sqlite3_context *, pCtx, + D0, LONG, iVal, + A6, struct SQLite3Base *, SQLite3Base) +{ + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + sqlite3_result_int(pCtx, iVal); + d1(kprintf("%s/%ld: END\n", __FUNC__, __LINE__)); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(VOID, LIBSQLite3ResultNull, + A0, sqlite3_context *, pCtx, + A6, struct SQLite3Base *, SQLite3Base) +{ + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + sqlite3_result_null(pCtx); + d1(kprintf("%s/%ld: END\n", __FUNC__, __LINE__)); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P5(VOID, LIBSQLite3ResultText, + A0, sqlite3_context *, pCtx, + A1, CONST_STRPTR, z, + D1, LONG, n, + A2, xDeleteFunc, xDelete, + A6, struct SQLite3Base *, SQLite3Base) +{ + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + sqlite3_result_text(pCtx, z, n, xDelete); + d1(kprintf("%s/%ld: END\n", __FUNC__, __LINE__)); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P3(VOID, LIBSQLite3ResultValue, + A0, sqlite3_context *, pCtx, + A1, sqlite3_value *, pValue, + A6, struct SQLite3Base *, SQLite3Base) +{ + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + sqlite3_result_value(pCtx, pValue); + d1(kprintf("%s/%ld: END\n", __FUNC__, __LINE__)); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P6(LONG, LIBSQLite3CreateCollation, + A0, sqlite3 *, db, + A1, CONST_STRPTR, zName, + D0, LONG, eTextRep, + A2, APTR, pCtx, + A3, xCompareFunc, xCompare, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_create_collation(db, (const char *) zName, + eTextRep, pCtx, xCompare); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P4(LONG, LIBSQLite3CollationNeeded, + A0, sqlite3 *, db, + D0, APTR, pCollNeededArg, + A1, xCollationNeededFunc, xCollNeeded, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_collation_needed(db, pCollNeededArg, xCollNeeded); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(LONG, LIBSQLite3Sleep, + D0, LONG, ms, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_sleep(ms); + (void) ms; + Result = SQLITE_ERROR; + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(LONG, LIBSQLite3Expired, + A0, sqlite3_stmt *, pStmt, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_expired(pStmt); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P3(LONG, LIBSQLite3TransferBindings, + A0, sqlite3_stmt *, pFromStmt, + A1, sqlite3_stmt *, pToStmt, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_transfer_bindings(pFromStmt, pToStmt); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P1(LONG, LIBSQLite3GlobalRecover, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_global_recover(); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(LONG, LIBSQLite3GetAutocommit, + A0, sqlite3 *, db, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_get_autocommit(db); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(sqlite3 *, LIBSQLite3DbHandle, + A0, sqlite3_stmt *, pStmt, + A6, struct SQLite3Base *, SQLite3Base) +{ + sqlite3 *Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_db_handle(pStmt); + d1(KPrintF("%s/%ld: END Result=%08lx\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P4(APTR, LIBSQLite3RollbackHook, + A0, sqlite3 *, db, + A1, xRollbackCallbackFunc, callback, + A2, APTR, pUserData, + A6, struct SQLite3Base *, SQLite3Base) +{ + APTR Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_rollback_hook(db, callback, pUserData); + d1(KPrintF("%s/%ld: END Result=%08lx\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(LONG, LIBSQLite3EnableSharedCache, + D0, BOOL, enable, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_enable_shared_cache(enable); + d1(KPrintF("%s/%ld: END Result=%08lx\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(LONG, LIBSQLite3ReleaseMemory, + D0, LONG, bytesCount, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_release_memory(bytesCount); + d1(KPrintF("%s/%ld: END Result=%08lx\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(VOID, LIBSQLite3SoftHeapLimit, + D0, LONG, maxBytes, + A6, struct SQLite3Base *, SQLite3Base) +{ + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + sqlite3_soft_heap_limit(maxBytes); + d1(KPrintF("%s/%ld: END\n", __FUNC__, __LINE__)); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P1(VOID, LIBSQLite3ThreadCleanup, + A6, struct SQLite3Base *, SQLite3Base) +{ + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + sqlite3_thread_cleanup(); + d1(KPrintF("%s/%ld: END\n", __FUNC__, __LINE__)); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P6(LONG, LIBSQLite3PrepareV2, + A0, sqlite3 *, db, + A1, CONST_STRPTR, zSql, + D0, LONG, nBytes, + A2, sqlite3_stmt **, ppStmt, + A3, CONST_STRPTR *, pzTail, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START zSql=<%s>\n", __FUNC__, __LINE__)); + Result = sqlite3_prepare_v2(db, (const char *) zSql, + nBytes, ppStmt, (const char **) pzTail); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P9(LONG, LIBSQLite3CreateFunction, + A0, sqlite3 *, db, + A1, CONST_STRPTR, zFunctionName, + D0, LONG, nArg, + D1, LONG, eTextRep, + A2, APTR, userdata, + A3, xFunctionFunc, xFunc, + D2, xFunctionStep, xStep, + D3, xFunctionFinal, xFinal, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START zFunctionName=<%s>\n", __FUNC__, __LINE__, (const char *) zFunctionName)); + Result = sqlite3_create_function(db, zFunctionName, nArg, eTextRep, + userdata, xFunc, xStep, xFinal); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P5(LONG, LIBSQLite3CreateModule, + A0, sqlite3 *, db, + A1, CONST_STRPTR, zName, + A2, CONST sqlite3_module *, methods, + A3, APTR, clientData, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START zName=<%s>\n", __FUNC__, __LINE__)); + Result = sqlite3_create_module(db, zName, methods, clientData); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P3(LONG, LIBSQLite3DeclareVtab, + A0, sqlite3 *, db, + A1, CONST_STRPTR, zCreateTable, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START zCreateTable=<%s>\n", __FUNC__, __LINE__, zCreateTable)); + Result = sqlite3_declare_vtab(db, (const char *) zCreateTable); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P4(LONG, LIBSQLite3OverloadFunction, + A0, sqlite3 *, db, + A1, CONST_STRPTR, zFuncName, + D0, LONG, nArg, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START zFuncName=<%s>\n", __FUNC__, __LINE__, zFuncName)); + Result = sqlite3_overload_function(db, (const char *) zFuncName, nArg); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P8(LONG, LIBSQLite3BlobOpen, + A0, sqlite3 *, db, + A1, CONST_STRPTR, zDb, + A2, CONST_STRPTR, zTable, + A3, CONST_STRPTR, zColumn, + D0, LONG, iRow, + D1, LONG, flags, + A4, sqlite3_blob **, ppBlob, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START zTable=<%s>\n", __FUNC__, __LINE__, zTable)); + Result = sqlite3_blob_open(db, zDb, zTable, zColumn, iRow, flags, ppBlob); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(LONG, LIBSQLite3BlobClose, + A0, sqlite3_blob *, blob, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_blob_close(blob); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(LONG, LIBSQLite3BlobBytes, + A0, sqlite3_blob *, blob, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_blob_bytes(blob); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P5(LONG, LIBSQLite3BlobRead, + A0, sqlite3_blob *, blob, + A1, APTR, z, + D0, LONG, n, + D1, LONG, iOffset, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_blob_read(blob, z, n, iOffset); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P5(LONG, LIBSQLite3BlobWrite, + A0, sqlite3_blob *, blob, + A1, CONST_APTR, z, + D0, LONG, n, + D1, LONG, iOffset, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_blob_write(blob, z, n, iOffset); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P3(LONG, LIBSQLite3ExtendedResultCodes, + A0, sqlite3 *, db, + D0, LONG, onoff, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_extended_result_codes(db, onoff); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P4(LONG, LIBSQLite3BindZeroBlob, + A0, sqlite3_stmt *, pStmt, + D0, LONG, i, + D1, LONG, n, + A6, struct SQLite3Base *, SQLite3Base); +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_bind_zeroblob(pStmt, i, n); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P3(CONST_STRPTR, LIBSQLite3ColumnDatabaseName, + A0, sqlite3_stmt *, stmt, + D0, LONG, iCol, + A6, struct SQLite3Base *, SQLite3Base) +{ + CONST_STRPTR Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_column_database_name(stmt, iCol); + d1(KPrintF("%s/%ld: END Result=<%s>\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P3(CONST_STRPTR, LIBSQLite3ColumnTableName, + A0, sqlite3_stmt *, stmt, + D0, LONG, iCol, + A6, struct SQLite3Base *, SQLite3Base) +{ + CONST_STRPTR Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_column_table_name(stmt, iCol); + d1(KPrintF("%s/%ld: END Result=<%s>\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P3(CONST_STRPTR, LIBSQLite3ColumnOriginName, + A0, sqlite3_stmt *, stmt, + D0, LONG, iCol, + A6, struct SQLite3Base *, SQLite3Base) +{ + CONST_STRPTR Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_column_origin_name(stmt, iCol); + d1(KPrintF("%s/%ld: END Result=<%s>\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P3(sqlite3_value *, LIBSQLite3ColumnValue, + A0, sqlite3_stmt *, pStmt, + D0, LONG, iCol, + A6, struct SQLite3Base *, SQLite3Base); +{ + sqlite3_value *Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_column_value(pStmt, iCol); + d1(KPrintF("%s/%ld: END Result=%08lx\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P7(LONG, LIBSQLite3CreateCollationV2, + A0, sqlite3 *, db, + A1, CONST_STRPTR, zName, + D0, LONG, eTextRep, + A2, APTR, pCtx, + A3, xCreateCollationCompare, xCompare, + D1, xCreateCollationDestroy, xDestroy, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_create_collation_v2(db, zName, eTextRep, pCtx, xCompare, xDestroy); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P1(CONST_STRPTR, LIBSQLite3LibVersion, + A6, struct SQLite3Base *, SQLite3Base) +{ + CONST_STRPTR Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_libversion(); + d1(KPrintF("%s/%ld: END Result=<%s>\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P1(LONG, LIBSQLite3LibversionNumber, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_libversion_number(); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(VOID, LIBSQLite3ResultErrorToobig, + A0, sqlite3_context *, pCtx, + A6, struct SQLite3Base *, SQLite3Base) +{ + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + sqlite3_result_error_toobig(pCtx); + d1(KPrintF("%s/%ld: END\n", __FUNC__, __LINE__)); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P3(VOID, LIBSQLite3ResultZeroBlob, + A0, sqlite3_context *, pCtx, + D0, LONG, n, + A6, struct SQLite3Base *, SQLite3Base) +{ + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + sqlite3_result_zeroblob(pCtx, n); + d1(KPrintF("%s/%ld: END\n", __FUNC__, __LINE__)); +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(LONG, LIBSQLite3ValueNumericType, + A0, sqlite3_value *, pVal, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_value_numeric_type(pVal); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P3(LONG, LIBSQLite3ConfigV, + D0, LONG, op, + A0, APTR, ap, + A6, struct SQLite3Base *, SQLite3Base) +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_configv(op, ap); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P4(LONG, LIBSQLlite3DbConfigV, + A0, sqlite3 *, db, + D0, LONG, op, + A1, APTR, ap, + A6, struct SQLite3Base *, SQLite3Base); +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_db_configv(db, op, ap); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(sqlite3_vfs *, LIBSQLite3VfsFind, + A0, CONST_STRPTR, zVfsName, + A6, struct SQLite3Base *, SQLite3Base); +{ + sqlite3_vfs *Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_vfs_find(zVfsName); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P3(LONG, LIBSQLite3VfsRegister, + A0, sqlite3_vfs *, vfs, + D0, LONG, makeDflt, + A6, struct SQLite3Base *, SQLite3Base); +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_vfs_register(vfs, makeDflt); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P2(LONG, LIBSQLite3VfsUnregister, + A0, sqlite3_vfs *, vfs, + A6, struct SQLite3Base *, SQLite3Base); +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_vfs_unregister(vfs); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P5(LONG, LIBSQLite3FileControl, + A0, sqlite3 *, db, + A1, CONST_STRPTR, zDbName, + D0, LONG, op, + A2, void *, arg, + A6, struct SQLite3Base *, SQLite3Base); +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_file_control(db, zDbName, op, arg); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P5(LONG, LIBSQLite3Status, + D0, LONG, op, + A0, LONG *, pCurrent, + A1, LONG *, pHighwater, + D1, LONG, resetFlag, + A6, struct SQLite3Base *, SQLite3Base); +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_status(op, (int *) pCurrent, (int *) pHighwater, resetFlag); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +LIBFUNC_P6(LONG, LIBSQLite3DbStatus, + A0, sqlite3 *, db, + D0, LONG, op, + A1, LONG *, pCur, + A2, LONG *, pHiwtr, + D1, LONG, resetFlg, + A6, struct SQLite3Base *, SQLite3Base); +{ + LONG Result; + + (void) SQLite3Base; + d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__)); + Result = sqlite3_db_status(db, op, (int *) pCur, (int *) pHiwtr, resetFlg); + d1(KPrintF("%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + return Result; +} +LIBFUNC_END + +//----------------------------------------------------------------------------- + +#if !defined(__SASC) +// Replacement for SAS/C library functions + +#if !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__) + +struct WBStartup *_WBenchMsg; + +int __fpclassify_double(float x) +{ + return 0; +} + +void exit(int x) +{ + (void) x; + while (1) + ; +} +#endif /*__MORPHOS__*/ + +#endif /* !defined(__SASC) */ +//----------------------------------------------------------------------------- diff --git a/scalos/libraries/sqlite/LibSQLite3.h b/scalos/libraries/sqlite/LibSQLite3.h new file mode 100644 index 000000000..fa35e75df --- /dev/null +++ b/scalos/libraries/sqlite/LibSQLite3.h @@ -0,0 +1,502 @@ +// LibSQLite3.h +// $Date$ +// $Revision$ + + +#ifndef LIBSQLITE3_H +#define LIBSQLITE3_H + +#include +#include +#include +#include + +#include + +//---------------------------------------------------------------------------- + +#define LIB_VERSION 44 +#define LIB_REVISION 34 + +//---------------------------------------------------------------------------- + +// Name for public semaphores +#define SQLITE3_SHARED_SEMA_NAME "SQLite3_Shared" +#define SQLITE3_PENDING_SEMA_NAME "SQLite3_Pending" +#define SQLITE3_RESERVED_SEMA_NAME "SQLite3_Reserved" + +//---------------------------------------------------------------------------- + +extern char ALIGNED libName[]; +extern char ALIGNED libIdString[]; + +extern struct ExecBase *SysBase; + +//---------------------------------------------------------------------------- + +typedef int (*xBusyFunc)(void*,int); +typedef void (*xTraceFunc)(void*, const char*); +typedef int (*xProgressFunc)(void *); +typedef int (*xCommitFunc)(void*); +typedef void (*xDeleteFunc)(void*); +typedef int (*xCompareFunc)(void*,int,const void*,int,const void*); +typedef void (*xCollationNeededFunc)(void*, sqlite3*, int eTextRep, const char*); +typedef VOID (*xRollbackCallbackFunc)(VOID *); +typedef VOID (*xFunctionFunc)(sqlite3_context *pCtx, int i, sqlite3_value **pVal); +typedef VOID (*xFunctionStep)(sqlite3_context *pCtx, int i, sqlite3_value **pVal); +typedef VOID (*xFunctionFinal)(sqlite3_context *pCtx); +typedef int (*xCreateCollationCompare)(APTR p, int i, CONST_APTR p2, int j, CONST_APTR p3); +typedef VOID (*xCreateCollationDestroy)(APTR p); + +//---------------------------------------------------------------------------- + +BOOL SQLite3Init(struct SQLite3Base *SQLite3Base); +BOOL SQLite3Open(struct SQLite3Base *SQLite3Base); +void SQLite3Cleanup(struct SQLite3Base *SQLite3Base); + +LIBFUNC_P2_PROTO(LONG, LIBSQLite3Close, + A0, sqlite3 *, db, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P6_PROTO(LONG, LIBSQLite3Exec, + A0, sqlite3 *, db, + A1, CONST_STRPTR, sql, + A2, sqlite3_callback, xCallback, + A3, APTR, pArg, + D0, STRPTR *, errmsg, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(LONG, LIBSQLite3Changes, + A0, sqlite3 *, db, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(LONG, LIBSQLite3TotalChanges, + A0, sqlite3 *, db, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(VOID, LIBSQLite3Interrupt, + A0, sqlite3 *, db, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(LONG, LIBSQLite3Complete, + A0, CONST_STRPTR, sql, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P4_PROTO(LONG, LIBSQLite3BusyHandler, + A0, sqlite3 *, db, + A1, xBusyFunc, callback, + A2, APTR, userdata, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P3_PROTO(LONG, LIBSQLite3BusyTimeout, + A0, sqlite3 *, db, + D0, LONG, ms, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P7_PROTO(LONG, LIBSQLite3GetTable, + A0, sqlite3 *, db, + A1, CONST_STRPTR, sql, + A2, STRPTR **, presult, + A3, LONG *, nrow, + D0, LONG *, ncolumn, + D1, STRPTR *, errmsg, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(VOID, LIBSQLite3FreeTable, + A0, STRPTR *, result, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(VOID, LIBSQLite3Free, + A0, STRPTR, z, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P4_PROTO(APTR, LIBSQLite3Trace, + A0, sqlite3 *, db, + A1, xTraceFunc, xTrace, + A2, APTR, parg, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P5_PROTO(VOID, LIBSQLite3ProgressHandler, + A0, sqlite3 *, db, + D0, LONG, nOps, + A1, xProgressFunc, xProgress, + A2, APTR, pArg, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P4_PROTO(APTR, LIBSQLite3CommitHook, + A0, sqlite3 *, db, + A1, xCommitFunc, xCallback, + A2, APTR, pArg, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P3_PROTO(LONG, LIBSQLite3Open, + A0, CONST_STRPTR, filename, + A1, sqlite3 **, ppDb, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(LONG, LIBSQLite3Errcode, + A0, sqlite3 *, db, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(CONST_STRPTR, LIBSQLite3Errmsg, + A0, sqlite3 *, db, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P6_PROTO(LONG, LIBSQLite3Prepare, + A0, sqlite3 *, db, + A1, CONST_STRPTR, zSql, + D0, LONG, nBytes, + A2, sqlite3_stmt **, ppStmt, + A3, CONST_STRPTR *, pzTail, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P6_PROTO(LONG, LIBSQLite3BindBlob, + A0, sqlite3_stmt *, pStmt, + D0, LONG, i, + A1, CONST_APTR, zData, + D1, LONG, nData, + A2, xDeleteFunc, xDel, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P4_PROTO(LONG, LIBSQLite3BindInt, + A0, sqlite3_stmt *, pStmt, + D0, LONG, i, + D1, LONG, iValue, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P3_PROTO(LONG, LIBSQLite3BindNull, + A0, sqlite3_stmt *, pStmt, + D0, LONG, i, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P6_PROTO(LONG, LIBSQLite3BindText, + A0, sqlite3_stmt *, pStmt, + D0, LONG, i, + A1, CONST_STRPTR, zData, + D1, LONG, nData, + A2, xDeleteFunc, xDel, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P4_PROTO(LONG, LIBSQLite3BindValue, + A0, sqlite3_stmt *, pStmt, + D0, LONG, i, + A1, CONST sqlite3_value *, pVal, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(LONG, LIBSQLite3BindParameterCount, + A0, sqlite3_stmt *, pStmt, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P3_PROTO(CONST_STRPTR, LIBSQLite3BindParameterName, + A0, sqlite3_stmt *, pStmt, + D0, LONG, i, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P3_PROTO(LONG, LIBSQLite3BindParameterIndex, + A0, sqlite3_stmt *, pStmt, + A1, CONST_STRPTR, zName, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(LONG, LIBSQLite3ClearBindings, + A0, sqlite3_stmt *, pStmt, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(LONG, LIBSQLite3ColumnCount, + A0, sqlite3_stmt *, pStmt, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P3_PROTO(CONST_STRPTR, LIBSQLite3ColumnName, + A0, sqlite3_stmt *, pStmt, + D0, LONG, i, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P3_PROTO(CONST_STRPTR, LIBSQLite3ColumnDecltype, + A0, sqlite3_stmt *, pStmt, + D0, LONG, i, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(LONG, LIBSQLite3Step, + A0, sqlite3_stmt *, pStmt, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(LONG, LIBSQLite3DataCount, + A0, sqlite3_stmt *, pStmt, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P3_PROTO(CONST_APTR, LIBSQLite3ColumnBlob, + A0, sqlite3_stmt *, pStmt, + D0, LONG, i, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P3_PROTO(LONG, LIBSQLite3ColumnBytes, + A0, sqlite3_stmt *, pStmt, + D0, LONG, i, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P3_PROTO(LONG, LIBSQLite3ColumnInt, + A0, sqlite3_stmt *, pStmt, + D0, LONG, i, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P3_PROTO(CONST_STRPTR, LIBSQLite3ColumnText, + A0, sqlite3_stmt *, pStmt, + D0, LONG, i, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P3_PROTO(LONG, LIBSQLite3ColumnType, + A0, sqlite3_stmt *, pStmt, + D0, LONG, i, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(LONG, LIBSQLite3Finalize, + A0, sqlite3_stmt *, pStmt, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(LONG, LIBSQLite3Reset, + A0, sqlite3_stmt *, pStmt, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(LONG , LIBSQLite3AggregateCount, + A0, sqlite3_context *, pCtx, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(CONST_APTR, LIBSQLite3ValueBlob, + A0, sqlite3_value *, pVal, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(LONG, LIBSQLite3ValueBytes, + A0, sqlite3_value *, pVal, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(LONG, LIBSQLite3ValueInt, + A0, sqlite3_value *, pVal, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(CONST_STRPTR, LIBSQLite3ValueText, + A0, sqlite3_value *, pVal, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(LONG, LIBSQLite3ValueType, + A0, sqlite3_value *, pVal, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P3_PROTO(APTR, LIBSQLite3Aggregate_context, + A0, sqlite3_context *, pCtx, + D0, LONG, nBytes, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(APTR, LIBSQLite3UserData, + A0, sqlite3_context *, pCtx, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P3_PROTO(APTR, LIBSQLite3GetAuxdata, + A0, sqlite3_context *, pCtx, + D0, LONG, iArg, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P5_PROTO(VOID, LIBSQLite3SetAuxdata, + A0, sqlite3_context *, pCtx, + D0, LONG, iArg, + A1, APTR, pAux, + A2, xDeleteFunc, xDelete, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P5_PROTO(VOID, LIBSQLite3ResultBlob, + A0, sqlite3_context *, pCtx, + A1, CONST_APTR, z, + D1, LONG, n, + A2, xDeleteFunc, xDelete, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P4_PROTO(VOID, LIBSQLite3ResultError, + A0, sqlite3_context *, pCtx, + A1, CONST_STRPTR, z, + D0, LONG, n, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P3_PROTO(VOID, LIBSQLite3ResultInt, + A0, sqlite3_context *, pCtx, + D0, LONG, iVal, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(VOID, LIBSQLite3ResultNull, + A0, sqlite3_context *, pCtx, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P5_PROTO(VOID, LIBSQLite3ResultText, + A0, sqlite3_context *, pCtx, + A1, CONST_STRPTR, z, + D1, LONG, n, + A2, xDeleteFunc, xDelete, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P3_PROTO(VOID, LIBSQLite3ResultValue, + A0, sqlite3_context *, pCtx, + A1, sqlite3_value *, pValue, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P6_PROTO(LONG, LIBSQLite3CreateCollation, + A0, sqlite3 *, db, + A1, CONST_STRPTR, zName, + D0, LONG, eTextRep, + A2, APTR, pCtx, + A3, xCompareFunc, xCompare, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P4_PROTO(LONG, LIBSQLite3CollationNeeded, + A0, sqlite3 *, db, + D0, APTR, pCollNeededArg, + A1, xCollationNeededFunc, xCollNeeded, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(LONG, LIBSQLite3Sleep, + D0, LONG, ms, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(LONG, LIBSQLite3Expired, + A0, sqlite3_stmt *, pStmt, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P3_PROTO(LONG, LIBSQLite3TransferBindings, + A0, sqlite3_stmt *, pFromStmt, + A1, sqlite3_stmt *, pToStmt, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P1_PROTO(LONG, LIBSQLite3GlobalRecover, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(LONG, LIBSQLite3GetAutocommit, + A0, sqlite3 *, db, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(sqlite3 *, LIBSQLite3DbHandle, + A0, sqlite3_stmt *, pStmt, + A6, struct SQLite3Base *, SQLite3Base); + +// new functions in V41 +LIBFUNC_P4_PROTO(APTR, LIBSQLite3RollbackHook, + A0, sqlite3 *, db, + A1, xRollbackCallbackFunc, callback, + A2, APTR, pUserData, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(LONG, LIBSQLite3EnableSharedCache, + D0, BOOL, enable, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(LONG, LIBSQLite3ReleaseMemory, + D0, LONG, bytesCount, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(VOID, LIBSQLite3SoftHeapLimit, + D0, LONG, maxBytes, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P1_PROTO(VOID, LIBSQLite3ThreadCleanup, + A6, struct SQLite3Base *, SQLite3Base); + +// new function in V42 +LIBFUNC_P6_PROTO(LONG, LIBSQLite3PrepareV2, + A0, sqlite3 *, db, + A1, CONST_STRPTR, zSql, + D0, LONG, nBytes, + A2, sqlite3_stmt **, ppStmt, + A3, CONST_STRPTR *, pzTail, + A6, struct SQLite3Base *, SQLite3Base); + +// new functions in V43 +LIBFUNC_P9_PROTO(LONG, LIBSQLite3CreateFunction, + A0, sqlite3 *, db, + A1, CONST_STRPTR, zFunctionName, + D0, LONG, nArg, + D1, LONG, eTextRep, + A2, APTR, userdata, + A3, xFunctionFunc, xFunc, + D2, xFunctionStep, xStep, + D3, xFunctionFinal, xFinal, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P5_PROTO(LONG, LIBSQLite3CreateModule, + A0, sqlite3 *, db, + A1, CONST_STRPTR, zName, + A2, CONST sqlite3_module *, methods, + A3, APTR, clientData, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P3_PROTO(LONG, LIBSQLite3DeclareVtab, + A0, sqlite3 *, db, + A1, CONST_STRPTR, zCreateTable, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P4_PROTO(LONG, LIBSQLite3OverloadFunction, + A0, sqlite3 *, db, + A1, CONST_STRPTR, zFuncName, + D0, LONG, nArg, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P8_PROTO(LONG, LIBSQLite3BlobOpen, + A0, sqlite3 *, db, + A1, CONST_STRPTR, zDb, + A2, CONST_STRPTR, zTable, + A3, CONST_STRPTR, zColumn, + D0, LONG, iRow, + D1, LONG, flags, + A4, sqlite3_blob **, ppBlob, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(LONG, LIBSQLite3BlobClose, + A0, sqlite3_blob *, blob, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(LONG, LIBSQLite3BlobBytes, + A0, sqlite3_blob *, blob, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P5_PROTO(LONG, LIBSQLite3BlobRead, + A0, sqlite3_blob *, blob, + A1, APTR, z, + D0, LONG, n, + D1, LONG, iOffset, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P5_PROTO(LONG, LIBSQLite3BlobWrite, + A0, sqlite3_blob *, blob, + A1, CONST_APTR, z, + D0, LONG, n, + D1, LONG, iOffset, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P3_PROTO(LONG, LIBSQLite3ExtendedResultCodes, + A0, sqlite3 *, db, + D0, LONG, onoff, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P4_PROTO(LONG, LIBSQLite3BindZeroBlob, + A0, sqlite3_stmt *, pStmt, + D0, LONG, i, + D1, LONG, n, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P3_PROTO(CONST_STRPTR, LIBSQLite3ColumnDatabaseName, + A0, sqlite3_stmt *, pStmt, + D0, LONG, iCol, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P3_PROTO(CONST_STRPTR, LIBSQLite3ColumnTableName, + A0, sqlite3_stmt *, pStmt, + D0, LONG, iCol, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P3_PROTO(CONST_STRPTR, LIBSQLite3ColumnOriginName, + A0, sqlite3_stmt *, pStmt, + D0, LONG, iCol, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P3_PROTO(sqlite3_value *, LIBSQLite3ColumnValue, + A0, sqlite3_stmt *, pStmt, + D0, LONG, iCol, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P7_PROTO(LONG, LIBSQLite3CreateCollationV2, + A0, sqlite3 *, db, + A1, CONST_STRPTR, zName, + D0, LONG, eTextRep, + A2, APTR, pCtx, + A3, xCreateCollationCompare, xCompare, + D1, xCreateCollationDestroy, xDestroy, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P1_PROTO(CONST_STRPTR, LIBSQLite3LibVersion, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P1_PROTO(LONG, LIBSQLite3LibversionNumber, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(VOID, LIBSQLite3ResultErrorToobig, + A0, sqlite3_context *, pCtx, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P3_PROTO(VOID, LIBSQLite3ResultZeroBlob, + A0, sqlite3_context *, pCtx, + D0, LONG, n, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(LONG, LIBSQLite3ValueNumericType, + A0, sqlite3_value *, pVal, + A6, struct SQLite3Base *, SQLite3Base); + +// new functions in V43 +LIBFUNC_P3_PROTO(LONG, LIBSQLite3ConfigV, + D0, LONG, op, + A0, APTR, ap, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P4_PROTO(LONG, LIBSQLlite3DbConfigV, + A0, sqlite3 *, db, + D0, LONG, op, + A1, APTR, ap, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(sqlite3_vfs *, LIBSQLite3VfsFind, + A0, CONST_STRPTR, zVfsName, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P3_PROTO(LONG, LIBSQLite3VfsRegister, + A0, sqlite3_vfs *, vfs, + D0, LONG, makeDflt, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P2_PROTO(LONG, LIBSQLite3VfsUnregister, + A0, sqlite3_vfs *, vfs, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P5_PROTO(LONG, LIBSQLite3FileControl, + A0, sqlite3 *, db, + A1, CONST_STRPTR, zDbName, + D0, LONG, op, + A2, void *, arg, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P5_PROTO(LONG, LIBSQLite3Status, + D0, LONG, op, + A0, LONG *, pCurrent, + A1, LONG *, pHighwater, + D1, LONG, resetFlag, + A6, struct SQLite3Base *, SQLite3Base); +LIBFUNC_P6_PROTO(LONG, LIBSQLite3DbStatus, + A0, sqlite3 *, db, + D0, LONG, op, + A1, LONG *, pCur, + A2, LONG *, pHiwtr, + D1, LONG, resetFlg, + A6, struct SQLite3Base *, SQLite3Base); + +//----------------------------------------------------------------------------- + +// defined in mempools.lib + +extern int _STI_240_InitMemFunctions(void); +extern void _STD_240_TerminateMemFunctions(void); + +//---------------------------------------------------------------------------- + +// special Amiga-specific vararg functions: + +int sqlite3_configv(int op, va_list ap); +int sqlite3_db_configv(sqlite3 *db, int op, va_list ap); + +//---------------------------------------------------------------------------- + +sqlite3_mutex_methods *sqlite3OtherMutex(void); + +//---------------------------------------------------------------------------- + +#endif /* LIBSQLITE3_H */ diff --git a/scalos/libraries/sqlite/Makefile b/scalos/libraries/sqlite/Makefile new file mode 100644 index 000000000..27395e2b7 --- /dev/null +++ b/scalos/libraries/sqlite/Makefile @@ -0,0 +1,8 @@ +# makefile für sqlite3.ibrary (C-Version) +# $Date$ +# $Revision$ + +# sqlite3.library cannot be built with SAS/C due to lack of 64-bit integers. + +include makefile-new + diff --git a/scalos/libraries/sqlite/VERSION b/scalos/libraries/sqlite/VERSION new file mode 100644 index 000000000..f06fb9e91 --- /dev/null +++ b/scalos/libraries/sqlite/VERSION @@ -0,0 +1 @@ +3.7.10 diff --git a/scalos/libraries/sqlite/config.mk b/scalos/libraries/sqlite/config.mk new file mode 100755 index 000000000..3f66913c4 --- /dev/null +++ b/scalos/libraries/sqlite/config.mk @@ -0,0 +1,81 @@ +# $Date: 2012-08-10 13:47:28 +0200 (Fr, 10. Aug 2012) $ +# $Revision: 915 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../.. +endif + +############################################################################### + +include $(TOPLEVEL)/config.mk +include $(TOPLEVEL)/rules.mk + +############################################################################### + +SRCDIR = ./src + +DEFINES += -DNO_TCL=1 \ + -DHAVE_USLEEP=0 \ + -DSQLITE_THREADSAFE=1 \ + -DSQLITE_MUTEX_NOOP=1 \ + -DSQLITE_EXTRA \ + -DSQLITE_OS_OTHER=1 \ + -DSQLITE_OMIT_UTF16=1 \ + -DSQLITE_ENABLE_MEMORY_MANAGEMENT \ + -DSQLITE_ENABLE_COLUMN_METADATA \ + -DSQLITE_OMIT_AUTHORIZATION=1 \ + -DTEMP_FILE_PREFIX="t:etilqs_" \ +# -DSQLITE_DEBUG + + +INCLUDES += -I./src + +############################################################################### +# Check compiler + +ifeq ($(MACHINE), ppc-morphos) + +############################################################################### +# MorphOS + +LFLAGS += -nostartfiles \ + -lmempools \ +# --verbose + + +else +ifeq ($(MACHINE), ppc-amigaos) + +############################################################################### +# AmigaOS4 + +LFLAGS += -nostartfiles + +else +ifeq ($(MACHINE), i386-aros) + +############################################################################### +# i386-aros + +LFLAGS += -nostartfiles -larossupport + +else + +############################################################################### +# AmigaOS + +LFLAGS += -specs=gg:etc/specs -nostdlib -nostartfiles \ + -lm \ + -lmempools \ + -ldebug \ + -lgcc \ + -lnix \ + -lnixmain \ + -lamiga21 \ + -lamiga \ + -lstubs + +endif +endif +endif diff --git a/scalos/libraries/sqlite/keywordhash.h b/scalos/libraries/sqlite/keywordhash.h new file mode 100644 index 000000000..298c0902a --- /dev/null +++ b/scalos/libraries/sqlite/keywordhash.h @@ -0,0 +1,270 @@ +/***** This file contains automatically generated code ****** +** +** The code in this file has been automatically generated by +** +** sqlite/tool/mkkeywordhash.c +** +** The code in this file implements a function that determines whether +** or not a given identifier is really an SQL keyword. The same thing +** might be implemented more directly using a hand-written hash table. +** But by using this automatically generated code, the size of the code +** is substantially reduced. This is important for embedded applications +** on platforms with limited memory. +*/ +/* Hash score: 175 */ +static int keywordCode(const char *z, int n){ + /* zText[] encodes 811 bytes of keywords in 541 bytes */ + /* REINDEXEDESCAPEACHECKEYBEFOREIGNOREGEXPLAINSTEADDATABASELECT */ + /* ABLEFTHENDEFERRABLELSEXCEPTRANSACTIONATURALTERAISEXCLUSIVE */ + /* XISTSAVEPOINTERSECTRIGGEREFERENCESCONSTRAINTOFFSETEMPORARY */ + /* UNIQUERYATTACHAVINGROUPDATEBEGINNERELEASEBETWEENOTNULLIKE */ + /* CASCADELETECASECOLLATECREATECURRENT_DATEDETACHIMMEDIATEJOIN */ + /* SERTMATCHPLANALYZEPRAGMABORTVALUESVIRTUALIMITWHENWHERENAME */ + /* AFTEREPLACEANDEFAULTAUTOINCREMENTCASTCOLUMNCOMMITCONFLICTCROSS */ + /* CURRENT_TIMESTAMPRIMARYDEFERREDISTINCTDROPFAILFROMFULLGLOBYIF */ + /* ISNULLORDERESTRICTOUTERIGHTROLLBACKROWUNIONUSINGVACUUMVIEW */ + /* INITIALLY */ + static const char zText[540] = { + 'R','E','I','N','D','E','X','E','D','E','S','C','A','P','E','A','C','H', + 'E','C','K','E','Y','B','E','F','O','R','E','I','G','N','O','R','E','G', + 'E','X','P','L','A','I','N','S','T','E','A','D','D','A','T','A','B','A', + 'S','E','L','E','C','T','A','B','L','E','F','T','H','E','N','D','E','F', + 'E','R','R','A','B','L','E','L','S','E','X','C','E','P','T','R','A','N', + 'S','A','C','T','I','O','N','A','T','U','R','A','L','T','E','R','A','I', + 'S','E','X','C','L','U','S','I','V','E','X','I','S','T','S','A','V','E', + 'P','O','I','N','T','E','R','S','E','C','T','R','I','G','G','E','R','E', + 'F','E','R','E','N','C','E','S','C','O','N','S','T','R','A','I','N','T', + 'O','F','F','S','E','T','E','M','P','O','R','A','R','Y','U','N','I','Q', + 'U','E','R','Y','A','T','T','A','C','H','A','V','I','N','G','R','O','U', + 'P','D','A','T','E','B','E','G','I','N','N','E','R','E','L','E','A','S', + 'E','B','E','T','W','E','E','N','O','T','N','U','L','L','I','K','E','C', + 'A','S','C','A','D','E','L','E','T','E','C','A','S','E','C','O','L','L', + 'A','T','E','C','R','E','A','T','E','C','U','R','R','E','N','T','_','D', + 'A','T','E','D','E','T','A','C','H','I','M','M','E','D','I','A','T','E', + 'J','O','I','N','S','E','R','T','M','A','T','C','H','P','L','A','N','A', + 'L','Y','Z','E','P','R','A','G','M','A','B','O','R','T','V','A','L','U', + 'E','S','V','I','R','T','U','A','L','I','M','I','T','W','H','E','N','W', + 'H','E','R','E','N','A','M','E','A','F','T','E','R','E','P','L','A','C', + 'E','A','N','D','E','F','A','U','L','T','A','U','T','O','I','N','C','R', + 'E','M','E','N','T','C','A','S','T','C','O','L','U','M','N','C','O','M', + 'M','I','T','C','O','N','F','L','I','C','T','C','R','O','S','S','C','U', + 'R','R','E','N','T','_','T','I','M','E','S','T','A','M','P','R','I','M', + 'A','R','Y','D','E','F','E','R','R','E','D','I','S','T','I','N','C','T', + 'D','R','O','P','F','A','I','L','F','R','O','M','F','U','L','L','G','L', + 'O','B','Y','I','F','I','S','N','U','L','L','O','R','D','E','R','E','S', + 'T','R','I','C','T','O','U','T','E','R','I','G','H','T','R','O','L','L', + 'B','A','C','K','R','O','W','U','N','I','O','N','U','S','I','N','G','V', + 'A','C','U','U','M','V','I','E','W','I','N','I','T','I','A','L','L','Y', + }; + static const unsigned char aHash[127] = { + 72, 101, 114, 70, 0, 45, 0, 0, 78, 0, 73, 0, 0, + 42, 12, 74, 15, 0, 113, 81, 50, 108, 0, 19, 0, 0, + 118, 0, 116, 111, 0, 22, 89, 0, 9, 0, 0, 66, 67, + 0, 65, 6, 0, 48, 86, 98, 0, 115, 97, 0, 0, 44, + 0, 99, 24, 0, 17, 0, 119, 49, 23, 0, 5, 106, 25, + 92, 0, 0, 121, 102, 56, 120, 53, 28, 51, 0, 87, 0, + 96, 26, 0, 95, 0, 0, 0, 91, 88, 93, 84, 105, 14, + 39, 104, 0, 77, 0, 18, 85, 107, 32, 0, 117, 76, 109, + 58, 46, 80, 0, 0, 90, 40, 0, 112, 0, 36, 0, 0, + 29, 0, 82, 59, 60, 0, 20, 57, 0, 52, + }; + static const unsigned char aNext[121] = { + 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, + 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 33, 0, 21, 0, 0, 0, 43, 3, 47, + 0, 0, 0, 0, 30, 0, 54, 0, 38, 0, 0, 0, 1, + 62, 0, 0, 63, 0, 41, 0, 0, 0, 0, 0, 0, 0, + 61, 0, 0, 0, 0, 31, 55, 16, 34, 10, 0, 0, 0, + 0, 0, 0, 0, 11, 68, 75, 0, 8, 0, 100, 94, 0, + 103, 0, 83, 0, 71, 0, 0, 110, 27, 37, 69, 79, 0, + 35, 64, 0, 0, + }; + static const unsigned char aLen[121] = { + 7, 7, 5, 4, 6, 4, 5, 3, 6, 7, 3, 6, 6, + 7, 7, 3, 8, 2, 6, 5, 4, 4, 3, 10, 4, 6, + 11, 6, 2, 7, 5, 5, 9, 6, 9, 9, 7, 10, 10, + 4, 6, 2, 3, 9, 4, 2, 6, 5, 6, 6, 5, 6, + 5, 5, 7, 7, 7, 3, 2, 4, 4, 7, 3, 6, 4, + 7, 6, 12, 6, 9, 4, 6, 5, 4, 7, 6, 5, 6, + 7, 5, 4, 5, 6, 5, 7, 3, 7, 13, 2, 2, 4, + 6, 6, 8, 5, 17, 12, 7, 8, 8, 2, 4, 4, 4, + 4, 4, 2, 2, 6, 5, 8, 5, 5, 8, 3, 5, 5, + 6, 4, 9, 3, + }; + static const unsigned short int aOffset[121] = { + 0, 2, 2, 8, 9, 14, 16, 20, 23, 25, 25, 29, 33, + 36, 41, 46, 48, 53, 54, 59, 62, 65, 67, 69, 78, 81, + 86, 91, 95, 96, 101, 105, 109, 117, 122, 128, 136, 142, 152, + 159, 162, 162, 165, 167, 167, 171, 176, 179, 184, 189, 194, 197, + 203, 206, 210, 217, 223, 223, 223, 226, 229, 233, 234, 238, 244, + 248, 255, 261, 273, 279, 288, 290, 296, 301, 303, 310, 315, 320, + 326, 332, 337, 341, 344, 350, 354, 361, 363, 370, 372, 374, 383, + 387, 393, 399, 407, 412, 412, 428, 435, 442, 443, 450, 454, 458, + 462, 466, 469, 471, 473, 479, 483, 491, 495, 500, 508, 511, 516, + 521, 527, 531, 536, + }; + static const unsigned char aCode[121] = { + TK_REINDEX, TK_INDEXED, TK_INDEX, TK_DESC, TK_ESCAPE, + TK_EACH, TK_CHECK, TK_KEY, TK_BEFORE, TK_FOREIGN, + TK_FOR, TK_IGNORE, TK_LIKE_KW, TK_EXPLAIN, TK_INSTEAD, + TK_ADD, TK_DATABASE, TK_AS, TK_SELECT, TK_TABLE, + TK_JOIN_KW, TK_THEN, TK_END, TK_DEFERRABLE, TK_ELSE, + TK_EXCEPT, TK_TRANSACTION,TK_ACTION, TK_ON, TK_JOIN_KW, + TK_ALTER, TK_RAISE, TK_EXCLUSIVE, TK_EXISTS, TK_SAVEPOINT, + TK_INTERSECT, TK_TRIGGER, TK_REFERENCES, TK_CONSTRAINT, TK_INTO, + TK_OFFSET, TK_OF, TK_SET, TK_TEMP, TK_TEMP, + TK_OR, TK_UNIQUE, TK_QUERY, TK_ATTACH, TK_HAVING, + TK_GROUP, TK_UPDATE, TK_BEGIN, TK_JOIN_KW, TK_RELEASE, + TK_BETWEEN, TK_NOTNULL, TK_NOT, TK_NO, TK_NULL, + TK_LIKE_KW, TK_CASCADE, TK_ASC, TK_DELETE, TK_CASE, + TK_COLLATE, TK_CREATE, TK_CTIME_KW, TK_DETACH, TK_IMMEDIATE, + TK_JOIN, TK_INSERT, TK_MATCH, TK_PLAN, TK_ANALYZE, + TK_PRAGMA, TK_ABORT, TK_VALUES, TK_VIRTUAL, TK_LIMIT, + TK_WHEN, TK_WHERE, TK_RENAME, TK_AFTER, TK_REPLACE, + TK_AND, TK_DEFAULT, TK_AUTOINCR, TK_TO, TK_IN, + TK_CAST, TK_COLUMNKW, TK_COMMIT, TK_CONFLICT, TK_JOIN_KW, + TK_CTIME_KW, TK_CTIME_KW, TK_PRIMARY, TK_DEFERRED, TK_DISTINCT, + TK_IS, TK_DROP, TK_FAIL, TK_FROM, TK_JOIN_KW, + TK_LIKE_KW, TK_BY, TK_IF, TK_ISNULL, TK_ORDER, + TK_RESTRICT, TK_JOIN_KW, TK_JOIN_KW, TK_ROLLBACK, TK_ROW, + TK_UNION, TK_USING, TK_VACUUM, TK_VIEW, TK_INITIALLY, + TK_ALL, + }; + int h, i; + if( n<2 ) return TK_ID; + h = ((charMap(z[0])*4) ^ + (charMap(z[n-1])*3) ^ + n) % 127; + for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){ + if( aLen[i]==n && sqlite3StrNICmp(&zText[aOffset[i]],z,n)==0 ){ + testcase( i==0 ); /* REINDEX */ + testcase( i==1 ); /* INDEXED */ + testcase( i==2 ); /* INDEX */ + testcase( i==3 ); /* DESC */ + testcase( i==4 ); /* ESCAPE */ + testcase( i==5 ); /* EACH */ + testcase( i==6 ); /* CHECK */ + testcase( i==7 ); /* KEY */ + testcase( i==8 ); /* BEFORE */ + testcase( i==9 ); /* FOREIGN */ + testcase( i==10 ); /* FOR */ + testcase( i==11 ); /* IGNORE */ + testcase( i==12 ); /* REGEXP */ + testcase( i==13 ); /* EXPLAIN */ + testcase( i==14 ); /* INSTEAD */ + testcase( i==15 ); /* ADD */ + testcase( i==16 ); /* DATABASE */ + testcase( i==17 ); /* AS */ + testcase( i==18 ); /* SELECT */ + testcase( i==19 ); /* TABLE */ + testcase( i==20 ); /* LEFT */ + testcase( i==21 ); /* THEN */ + testcase( i==22 ); /* END */ + testcase( i==23 ); /* DEFERRABLE */ + testcase( i==24 ); /* ELSE */ + testcase( i==25 ); /* EXCEPT */ + testcase( i==26 ); /* TRANSACTION */ + testcase( i==27 ); /* ACTION */ + testcase( i==28 ); /* ON */ + testcase( i==29 ); /* NATURAL */ + testcase( i==30 ); /* ALTER */ + testcase( i==31 ); /* RAISE */ + testcase( i==32 ); /* EXCLUSIVE */ + testcase( i==33 ); /* EXISTS */ + testcase( i==34 ); /* SAVEPOINT */ + testcase( i==35 ); /* INTERSECT */ + testcase( i==36 ); /* TRIGGER */ + testcase( i==37 ); /* REFERENCES */ + testcase( i==38 ); /* CONSTRAINT */ + testcase( i==39 ); /* INTO */ + testcase( i==40 ); /* OFFSET */ + testcase( i==41 ); /* OF */ + testcase( i==42 ); /* SET */ + testcase( i==43 ); /* TEMPORARY */ + testcase( i==44 ); /* TEMP */ + testcase( i==45 ); /* OR */ + testcase( i==46 ); /* UNIQUE */ + testcase( i==47 ); /* QUERY */ + testcase( i==48 ); /* ATTACH */ + testcase( i==49 ); /* HAVING */ + testcase( i==50 ); /* GROUP */ + testcase( i==51 ); /* UPDATE */ + testcase( i==52 ); /* BEGIN */ + testcase( i==53 ); /* INNER */ + testcase( i==54 ); /* RELEASE */ + testcase( i==55 ); /* BETWEEN */ + testcase( i==56 ); /* NOTNULL */ + testcase( i==57 ); /* NOT */ + testcase( i==58 ); /* NO */ + testcase( i==59 ); /* NULL */ + testcase( i==60 ); /* LIKE */ + testcase( i==61 ); /* CASCADE */ + testcase( i==62 ); /* ASC */ + testcase( i==63 ); /* DELETE */ + testcase( i==64 ); /* CASE */ + testcase( i==65 ); /* COLLATE */ + testcase( i==66 ); /* CREATE */ + testcase( i==67 ); /* CURRENT_DATE */ + testcase( i==68 ); /* DETACH */ + testcase( i==69 ); /* IMMEDIATE */ + testcase( i==70 ); /* JOIN */ + testcase( i==71 ); /* INSERT */ + testcase( i==72 ); /* MATCH */ + testcase( i==73 ); /* PLAN */ + testcase( i==74 ); /* ANALYZE */ + testcase( i==75 ); /* PRAGMA */ + testcase( i==76 ); /* ABORT */ + testcase( i==77 ); /* VALUES */ + testcase( i==78 ); /* VIRTUAL */ + testcase( i==79 ); /* LIMIT */ + testcase( i==80 ); /* WHEN */ + testcase( i==81 ); /* WHERE */ + testcase( i==82 ); /* RENAME */ + testcase( i==83 ); /* AFTER */ + testcase( i==84 ); /* REPLACE */ + testcase( i==85 ); /* AND */ + testcase( i==86 ); /* DEFAULT */ + testcase( i==87 ); /* AUTOINCREMENT */ + testcase( i==88 ); /* TO */ + testcase( i==89 ); /* IN */ + testcase( i==90 ); /* CAST */ + testcase( i==91 ); /* COLUMN */ + testcase( i==92 ); /* COMMIT */ + testcase( i==93 ); /* CONFLICT */ + testcase( i==94 ); /* CROSS */ + testcase( i==95 ); /* CURRENT_TIMESTAMP */ + testcase( i==96 ); /* CURRENT_TIME */ + testcase( i==97 ); /* PRIMARY */ + testcase( i==98 ); /* DEFERRED */ + testcase( i==99 ); /* DISTINCT */ + testcase( i==100 ); /* IS */ + testcase( i==101 ); /* DROP */ + testcase( i==102 ); /* FAIL */ + testcase( i==103 ); /* FROM */ + testcase( i==104 ); /* FULL */ + testcase( i==105 ); /* GLOB */ + testcase( i==106 ); /* BY */ + testcase( i==107 ); /* IF */ + testcase( i==108 ); /* ISNULL */ + testcase( i==109 ); /* ORDER */ + testcase( i==110 ); /* RESTRICT */ + testcase( i==111 ); /* OUTER */ + testcase( i==112 ); /* RIGHT */ + testcase( i==113 ); /* ROLLBACK */ + testcase( i==114 ); /* ROW */ + testcase( i==115 ); /* UNION */ + testcase( i==116 ); /* USING */ + testcase( i==117 ); /* VACUUM */ + testcase( i==118 ); /* VIEW */ + testcase( i==119 ); /* INITIALLY */ + testcase( i==120 ); /* ALL */ + return aCode[i]; + } + } + return TK_ID; +} +int sqlite3KeywordCode(const unsigned char *z, int n){ + return keywordCode((char*)z, n); +} +#define SQLITE_N_KEYWORD 121 diff --git a/scalos/libraries/sqlite/makefile-new b/scalos/libraries/sqlite/makefile-new new file mode 100755 index 000000000..d6d888ade --- /dev/null +++ b/scalos/libraries/sqlite/makefile-new @@ -0,0 +1,162 @@ +# $Date: 2011-10-20 20:07:22 +0200 (Do, 20. Okt 2011) $ +# $Revision: 879 $ +############################################################################## + +ifndef TOPLEVEL + TOPLEVEL=$(shell pwd)/../.. +endif + +############################################################################## + +include config.mk + +############################################################################### +# +# Project Object files +# + +ifeq ($(MACHINE),ppc-amigaos) +OBJS := $(OBJDIR)/sqlite3-aos4.o \ + $(OBJDIR)/sqlite3-aos4-68kstubs.o +else +ifeq ($(MACHINE),i386-aros) +OBJS := $(OBJDIR)/sqlite3-aros.o +else +OBJS := $(OBJDIR)/sqlite3-classic.o +endif +endif + +OBJS += $(OBJDIR)/alter.o \ + $(OBJDIR)/analyze.o \ + $(OBJDIR)/attach.o \ + $(OBJDIR)/auth.o \ + $(OBJDIR)/backup.o \ + $(OBJDIR)/bitvec.o \ + $(OBJDIR)/btmutex.o \ + $(OBJDIR)/btree.o \ + $(OBJDIR)/build.o \ + $(OBJDIR)/callback.o \ + $(OBJDIR)/complete.o \ + $(OBJDIR)/ctime.o \ + $(OBJDIR)/date.o \ + $(OBJDIR)/delete.o \ + $(OBJDIR)/expr.o \ + $(OBJDIR)/fault.o \ + $(OBJDIR)/fkey.o \ + $(OBJDIR)/func.o \ + $(OBJDIR)/global.o \ + $(OBJDIR)/hash.o \ + $(OBJDIR)/insert.o \ + $(OBJDIR)/journal.o \ + $(OBJDIR)/loadext.o \ + $(OBJDIR)/malloc.o \ + $(OBJDIR)/main.o \ + $(OBJDIR)/mem0.o \ + $(OBJDIR)/mem1.o \ + $(OBJDIR)/mem2.o \ + $(OBJDIR)/mem3.o \ + $(OBJDIR)/mem5.o \ + $(OBJDIR)/memjournal.o \ + $(OBJDIR)/mutex.o \ + $(OBJDIR)/mutex_noop.o \ + $(OBJDIR)/mutex_other.o \ + $(OBJDIR)/notify.o \ + $(OBJDIR)/opcodes.o \ + $(OBJDIR)/os.o \ + $(OBJDIR)/os_other.o \ + $(OBJDIR)/os_unix.o \ + $(OBJDIR)/os_win.o \ + $(OBJDIR)/pager.o \ + $(OBJDIR)/pcache1.o \ + $(OBJDIR)/parse.o \ + $(OBJDIR)/pcache.o \ + $(OBJDIR)/pragma.o \ + $(OBJDIR)/prepare.o \ + $(OBJDIR)/printf.o \ + $(OBJDIR)/random.o \ + $(OBJDIR)/resolve.o \ + $(OBJDIR)/rowset.o \ + $(OBJDIR)/select.o \ + $(OBJDIR)/status.o \ + $(OBJDIR)/table.o \ + $(OBJDIR)/tokenize.o \ + $(OBJDIR)/trigger.o \ + $(OBJDIR)/update.o \ + $(OBJDIR)/util.o \ + $(OBJDIR)/vacuum.o \ + $(OBJDIR)/vdbe.o \ + $(OBJDIR)/vdbeapi.o \ + $(OBJDIR)/vdbeaux.o \ + $(OBJDIR)/vdbeblob.o \ + $(OBJDIR)/vdbemem.o \ + $(OBJDIR)/vdbesort.o \ + $(OBJDIR)/vdbetrace.o \ + $(OBJDIR)/vtab.o \ + $(OBJDIR)/wal.o \ + $(OBJDIR)/walker.o \ + $(OBJDIR)/where.o \ + $(OBJDIR)/utf.o \ + $(OBJDIR)/legacy.o \ + $(OBJDIR)/LibSQLite3.o \ + +############################################################################## +# +# Autodependencies +# +ifneq ($(MAKECMDGOALS),clean) + -include $(OBJS:.o=.d) +endif + +############################################################################## +# +# Targets +# + +NAME = sqlite3.library +NAME_DB = $(NAME).debug + +############################################################################## +# +# Some lame deps + +$(OBJDIR)/%.o: $(SRCDIR)/%.c + @$(run-cc) + +$(OBJDIR)/%.d :: $(SRCDIR)/%.c + -@$(ECHO) "Update dependencies for $<"; \ + set -e; rm -f $@; \ + $(CC) -MM $(DEFINES) $(CFLAGS) $< > $@.$$$$; \ + sed 's,\($*\)\.o[ :]*,$(OBJDIR)/\1.o $@ : ,g' < $@.$$$$ > $@; \ + rm -f $@.$$$$ + +############################################################################## + +.PHONY: all install clean bump dump + +all: all_subdirs \ + $(BINDIR)/$(NAME) \ + $(BINDIR)/$(NAME_DB) + +############################################################################## + +$(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) : $(OBJS) + @$(ECHO) "Link $(NAME)" + @$(CC) $(OBJS) $(LFLAGS) $(DEFINES) -o$(BINDIR)/$(NAME_DB) + @$(STRIP) $(SFLAGS) $(BINDIR)/$(NAME_DB) -o $(BINDIR)/$(NAME) + @chmod u+x $@ + +############################################################################## + +install: install_subdirs + -@$(ECHO) "Installing $(NAME)" + @copy $(BINDIR)/$(NAME) LIBS: clone + @avail flush + + +clean: clean_subdirs + -@$(RM) -frv $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.d.* \ + $(OBJDIR)/*.i $(OBJDIR)/*.s \ + $(BINDIR)/$(NAME) $(BINDIR)/$(NAME_DB) \ + *.dump *_str.* + +############################################################################## diff --git a/scalos/libraries/sqlite/opcodes.c b/scalos/libraries/sqlite/opcodes.c new file mode 100644 index 000000000..a36230310 --- /dev/null +++ b/scalos/libraries/sqlite/opcodes.c @@ -0,0 +1,159 @@ +/* Automatically generated. Do not edit */ +/* See the mkopcodec.awk script for details. */ +#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) +const char *sqlite3OpcodeName(int i){ + static const char *const azName[] = { "?", + /* 1 */ "Goto", + /* 2 */ "Gosub", + /* 3 */ "Return", + /* 4 */ "Yield", + /* 5 */ "HaltIfNull", + /* 6 */ "Halt", + /* 7 */ "Integer", + /* 8 */ "Int64", + /* 9 */ "String", + /* 10 */ "Null", + /* 11 */ "Blob", + /* 12 */ "Variable", + /* 13 */ "Move", + /* 14 */ "Copy", + /* 15 */ "SCopy", + /* 16 */ "ResultRow", + /* 17 */ "CollSeq", + /* 18 */ "Function", + /* 19 */ "Not", + /* 20 */ "AddImm", + /* 21 */ "MustBeInt", + /* 22 */ "RealAffinity", + /* 23 */ "Permutation", + /* 24 */ "Compare", + /* 25 */ "Jump", + /* 26 */ "Once", + /* 27 */ "If", + /* 28 */ "IfNot", + /* 29 */ "Column", + /* 30 */ "Affinity", + /* 31 */ "MakeRecord", + /* 32 */ "Count", + /* 33 */ "Savepoint", + /* 34 */ "AutoCommit", + /* 35 */ "Transaction", + /* 36 */ "ReadCookie", + /* 37 */ "SetCookie", + /* 38 */ "VerifyCookie", + /* 39 */ "OpenRead", + /* 40 */ "OpenWrite", + /* 41 */ "OpenAutoindex", + /* 42 */ "OpenEphemeral", + /* 43 */ "SorterOpen", + /* 44 */ "OpenPseudo", + /* 45 */ "Close", + /* 46 */ "SeekLt", + /* 47 */ "SeekLe", + /* 48 */ "SeekGe", + /* 49 */ "SeekGt", + /* 50 */ "Seek", + /* 51 */ "NotFound", + /* 52 */ "Found", + /* 53 */ "IsUnique", + /* 54 */ "NotExists", + /* 55 */ "Sequence", + /* 56 */ "NewRowid", + /* 57 */ "Insert", + /* 58 */ "InsertInt", + /* 59 */ "Delete", + /* 60 */ "ResetCount", + /* 61 */ "SorterCompare", + /* 62 */ "SorterData", + /* 63 */ "RowKey", + /* 64 */ "RowData", + /* 65 */ "Rowid", + /* 66 */ "NullRow", + /* 67 */ "Last", + /* 68 */ "Or", + /* 69 */ "And", + /* 70 */ "SorterSort", + /* 71 */ "Sort", + /* 72 */ "Rewind", + /* 73 */ "IsNull", + /* 74 */ "NotNull", + /* 75 */ "Ne", + /* 76 */ "Eq", + /* 77 */ "Gt", + /* 78 */ "Le", + /* 79 */ "Lt", + /* 80 */ "Ge", + /* 81 */ "SorterNext", + /* 82 */ "BitAnd", + /* 83 */ "BitOr", + /* 84 */ "ShiftLeft", + /* 85 */ "ShiftRight", + /* 86 */ "Add", + /* 87 */ "Subtract", + /* 88 */ "Multiply", + /* 89 */ "Divide", + /* 90 */ "Remainder", + /* 91 */ "Concat", + /* 92 */ "Prev", + /* 93 */ "BitNot", + /* 94 */ "String8", + /* 95 */ "Next", + /* 96 */ "SorterInsert", + /* 97 */ "IdxInsert", + /* 98 */ "IdxDelete", + /* 99 */ "IdxRowid", + /* 100 */ "IdxLT", + /* 101 */ "IdxGE", + /* 102 */ "Destroy", + /* 103 */ "Clear", + /* 104 */ "CreateIndex", + /* 105 */ "CreateTable", + /* 106 */ "ParseSchema", + /* 107 */ "LoadAnalysis", + /* 108 */ "DropTable", + /* 109 */ "DropIndex", + /* 110 */ "DropTrigger", + /* 111 */ "IntegrityCk", + /* 112 */ "RowSetAdd", + /* 113 */ "RowSetRead", + /* 114 */ "RowSetTest", + /* 115 */ "Program", + /* 116 */ "Param", + /* 117 */ "FkCounter", + /* 118 */ "FkIfZero", + /* 119 */ "MemMax", + /* 120 */ "IfPos", + /* 121 */ "IfNeg", + /* 122 */ "IfZero", + /* 123 */ "AggStep", + /* 124 */ "AggFinal", + /* 125 */ "Checkpoint", + /* 126 */ "JournalMode", + /* 127 */ "Vacuum", + /* 128 */ "IncrVacuum", + /* 129 */ "Expire", + /* 130 */ "Real", + /* 131 */ "TableLock", + /* 132 */ "VBegin", + /* 133 */ "VCreate", + /* 134 */ "VDestroy", + /* 135 */ "VOpen", + /* 136 */ "VFilter", + /* 137 */ "VColumn", + /* 138 */ "VNext", + /* 139 */ "VRename", + /* 140 */ "VUpdate", + /* 141 */ "ToText", + /* 142 */ "ToBlob", + /* 143 */ "ToNumeric", + /* 144 */ "ToInt", + /* 145 */ "ToReal", + /* 146 */ "Pagecount", + /* 147 */ "MaxPgcnt", + /* 148 */ "Trace", + /* 149 */ "Noop", + /* 150 */ "Explain", + }; + return azName[i]; +} +#endif diff --git a/scalos/libraries/sqlite/opcodes.h b/scalos/libraries/sqlite/opcodes.h new file mode 100644 index 000000000..bc69d0418 --- /dev/null +++ b/scalos/libraries/sqlite/opcodes.h @@ -0,0 +1,185 @@ +/* Automatically generated. Do not edit */ +/* See the mkopcodeh.awk script for details */ +#define OP_Goto 1 +#define OP_Gosub 2 +#define OP_Return 3 +#define OP_Yield 4 +#define OP_HaltIfNull 5 +#define OP_Halt 6 +#define OP_Integer 7 +#define OP_Int64 8 +#define OP_Real 130 /* same as TK_FLOAT */ +#define OP_String8 94 /* same as TK_STRING */ +#define OP_String 9 +#define OP_Null 10 +#define OP_Blob 11 +#define OP_Variable 12 +#define OP_Move 13 +#define OP_Copy 14 +#define OP_SCopy 15 +#define OP_ResultRow 16 +#define OP_Concat 91 /* same as TK_CONCAT */ +#define OP_Add 86 /* same as TK_PLUS */ +#define OP_Subtract 87 /* same as TK_MINUS */ +#define OP_Multiply 88 /* same as TK_STAR */ +#define OP_Divide 89 /* same as TK_SLASH */ +#define OP_Remainder 90 /* same as TK_REM */ +#define OP_CollSeq 17 +#define OP_Function 18 +#define OP_BitAnd 82 /* same as TK_BITAND */ +#define OP_BitOr 83 /* same as TK_BITOR */ +#define OP_ShiftLeft 84 /* same as TK_LSHIFT */ +#define OP_ShiftRight 85 /* same as TK_RSHIFT */ +#define OP_AddImm 20 +#define OP_MustBeInt 21 +#define OP_RealAffinity 22 +#define OP_ToText 141 /* same as TK_TO_TEXT */ +#define OP_ToBlob 142 /* same as TK_TO_BLOB */ +#define OP_ToNumeric 143 /* same as TK_TO_NUMERIC*/ +#define OP_ToInt 144 /* same as TK_TO_INT */ +#define OP_ToReal 145 /* same as TK_TO_REAL */ +#define OP_Eq 76 /* same as TK_EQ */ +#define OP_Ne 75 /* same as TK_NE */ +#define OP_Lt 79 /* same as TK_LT */ +#define OP_Le 78 /* same as TK_LE */ +#define OP_Gt 77 /* same as TK_GT */ +#define OP_Ge 80 /* same as TK_GE */ +#define OP_Permutation 23 +#define OP_Compare 24 +#define OP_Jump 25 +#define OP_And 69 /* same as TK_AND */ +#define OP_Or 68 /* same as TK_OR */ +#define OP_Not 19 /* same as TK_NOT */ +#define OP_BitNot 93 /* same as TK_BITNOT */ +#define OP_Once 26 +#define OP_If 27 +#define OP_IfNot 28 +#define OP_IsNull 73 /* same as TK_ISNULL */ +#define OP_NotNull 74 /* same as TK_NOTNULL */ +#define OP_Column 29 +#define OP_Affinity 30 +#define OP_MakeRecord 31 +#define OP_Count 32 +#define OP_Savepoint 33 +#define OP_AutoCommit 34 +#define OP_Transaction 35 +#define OP_ReadCookie 36 +#define OP_SetCookie 37 +#define OP_VerifyCookie 38 +#define OP_OpenRead 39 +#define OP_OpenWrite 40 +#define OP_OpenAutoindex 41 +#define OP_OpenEphemeral 42 +#define OP_SorterOpen 43 +#define OP_OpenPseudo 44 +#define OP_Close 45 +#define OP_SeekLt 46 +#define OP_SeekLe 47 +#define OP_SeekGe 48 +#define OP_SeekGt 49 +#define OP_Seek 50 +#define OP_NotFound 51 +#define OP_Found 52 +#define OP_IsUnique 53 +#define OP_NotExists 54 +#define OP_Sequence 55 +#define OP_NewRowid 56 +#define OP_Insert 57 +#define OP_InsertInt 58 +#define OP_Delete 59 +#define OP_ResetCount 60 +#define OP_SorterCompare 61 +#define OP_SorterData 62 +#define OP_RowKey 63 +#define OP_RowData 64 +#define OP_Rowid 65 +#define OP_NullRow 66 +#define OP_Last 67 +#define OP_SorterSort 70 +#define OP_Sort 71 +#define OP_Rewind 72 +#define OP_SorterNext 81 +#define OP_Prev 92 +#define OP_Next 95 +#define OP_SorterInsert 96 +#define OP_IdxInsert 97 +#define OP_IdxDelete 98 +#define OP_IdxRowid 99 +#define OP_IdxLT 100 +#define OP_IdxGE 101 +#define OP_Destroy 102 +#define OP_Clear 103 +#define OP_CreateIndex 104 +#define OP_CreateTable 105 +#define OP_ParseSchema 106 +#define OP_LoadAnalysis 107 +#define OP_DropTable 108 +#define OP_DropIndex 109 +#define OP_DropTrigger 110 +#define OP_IntegrityCk 111 +#define OP_RowSetAdd 112 +#define OP_RowSetRead 113 +#define OP_RowSetTest 114 +#define OP_Program 115 +#define OP_Param 116 +#define OP_FkCounter 117 +#define OP_FkIfZero 118 +#define OP_MemMax 119 +#define OP_IfPos 120 +#define OP_IfNeg 121 +#define OP_IfZero 122 +#define OP_AggStep 123 +#define OP_AggFinal 124 +#define OP_Checkpoint 125 +#define OP_JournalMode 126 +#define OP_Vacuum 127 +#define OP_IncrVacuum 128 +#define OP_Expire 129 +#define OP_TableLock 131 +#define OP_VBegin 132 +#define OP_VCreate 133 +#define OP_VDestroy 134 +#define OP_VOpen 135 +#define OP_VFilter 136 +#define OP_VColumn 137 +#define OP_VNext 138 +#define OP_VRename 139 +#define OP_VUpdate 140 +#define OP_Pagecount 146 +#define OP_MaxPgcnt 147 +#define OP_Trace 148 +#define OP_Noop 149 +#define OP_Explain 150 + + +/* Properties such as "out2" or "jump" that are specified in +** comments following the "case" for each opcode in the vdbe.c +** are encoded into bitvectors as follows: +*/ +#define OPFLG_JUMP 0x0001 /* jump: P2 holds jmp target */ +#define OPFLG_OUT2_PRERELEASE 0x0002 /* out2-prerelease: */ +#define OPFLG_IN1 0x0004 /* in1: P1 is an input */ +#define OPFLG_IN2 0x0008 /* in2: P2 is an input */ +#define OPFLG_IN3 0x0010 /* in3: P3 is an input */ +#define OPFLG_OUT2 0x0020 /* out2: P2 is an output */ +#define OPFLG_OUT3 0x0040 /* out3: P3 is an output */ +#define OPFLG_INITIALIZER {\ +/* 0 */ 0x00, 0x01, 0x01, 0x04, 0x04, 0x10, 0x00, 0x02,\ +/* 8 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x24, 0x24,\ +/* 16 */ 0x00, 0x00, 0x00, 0x24, 0x04, 0x05, 0x04, 0x00,\ +/* 24 */ 0x00, 0x01, 0x01, 0x05, 0x05, 0x00, 0x00, 0x00,\ +/* 32 */ 0x02, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,\ +/* 40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11,\ +/* 48 */ 0x11, 0x11, 0x08, 0x11, 0x11, 0x11, 0x11, 0x02,\ +/* 56 */ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 64 */ 0x00, 0x02, 0x00, 0x01, 0x4c, 0x4c, 0x01, 0x01,\ +/* 72 */ 0x01, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x15,\ +/* 80 */ 0x15, 0x01, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,\ +/* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x01, 0x24, 0x02, 0x01,\ +/* 96 */ 0x08, 0x08, 0x00, 0x02, 0x01, 0x01, 0x02, 0x00,\ +/* 104 */ 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 112 */ 0x0c, 0x45, 0x15, 0x01, 0x02, 0x00, 0x01, 0x08,\ +/* 120 */ 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00,\ +/* 128 */ 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 136 */ 0x01, 0x00, 0x01, 0x00, 0x00, 0x04, 0x04, 0x04,\ +/* 144 */ 0x04, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00,} diff --git a/scalos/libraries/sqlite/parse.c b/scalos/libraries/sqlite/parse.c new file mode 100644 index 000000000..9ea3625dc --- /dev/null +++ b/scalos/libraries/sqlite/parse.c @@ -0,0 +1,3854 @@ +/* Driver template for the LEMON parser generator. +** The author disclaims copyright to this source code. +** +** This version of "lempar.c" is modified, slightly, for use by SQLite. +** The only modifications are the addition of a couple of NEVER() +** macros to disable tests that are needed in the case of a general +** LALR(1) grammar but which are always false in the +** specific grammar used by SQLite. +*/ +/* First off, code is included that follows the "include" declaration +** in the input grammar file. */ +#include +#line 49 "parse.y" + +#include "sqliteInt.h" + +/* +** Disable all error recovery processing in the parser push-down +** automaton. +*/ +#define YYNOERRORRECOVERY 1 + +/* +** Make yytestcase() the same as testcase() +*/ +#define yytestcase(X) testcase(X) + +/* +** An instance of this structure holds information about the +** LIMIT clause of a SELECT statement. +*/ +struct LimitVal { + Expr *pLimit; /* The LIMIT expression. NULL if there is no limit */ + Expr *pOffset; /* The OFFSET expression. NULL if there is none */ +}; + +/* +** An instance of this structure is used to store the LIKE, +** GLOB, NOT LIKE, and NOT GLOB operators. +*/ +struct LikeOp { + Token eOperator; /* "like" or "glob" or "regexp" */ + int not; /* True if the NOT keyword is present */ +}; + +/* +** An instance of the following structure describes the event of a +** TRIGGER. "a" is the event type, one of TK_UPDATE, TK_INSERT, +** TK_DELETE, or TK_INSTEAD. If the event is of the form +** +** UPDATE ON (a,b,c) +** +** Then the "b" IdList records the list "a,b,c". +*/ +struct TrigEvent { int a; IdList * b; }; + +/* +** An instance of this structure holds the ATTACH key and the key type. +*/ +struct AttachKey { int type; Token key; }; + +#line 723 "parse.y" + + /* This is a utility routine used to set the ExprSpan.zStart and + ** ExprSpan.zEnd values of pOut so that the span covers the complete + ** range of text beginning with pStart and going to the end of pEnd. + */ + static void spanSet(ExprSpan *pOut, Token *pStart, Token *pEnd){ + pOut->zStart = pStart->z; + pOut->zEnd = &pEnd->z[pEnd->n]; + } + + /* Construct a new Expr object from a single identifier. Use the + ** new Expr to populate pOut. Set the span of pOut to be the identifier + ** that created the expression. + */ + static void spanExpr(ExprSpan *pOut, Parse *pParse, int op, Token *pValue){ + pOut->pExpr = sqlite3PExpr(pParse, op, 0, 0, pValue); + pOut->zStart = pValue->z; + pOut->zEnd = &pValue->z[pValue->n]; + } +#line 818 "parse.y" + + /* This routine constructs a binary expression node out of two ExprSpan + ** objects and uses the result to populate a new ExprSpan object. + */ + static void spanBinaryExpr( + ExprSpan *pOut, /* Write the result here */ + Parse *pParse, /* The parsing context. Errors accumulate here */ + int op, /* The binary operation */ + ExprSpan *pLeft, /* The left operand */ + ExprSpan *pRight /* The right operand */ + ){ + pOut->pExpr = sqlite3PExpr(pParse, op, pLeft->pExpr, pRight->pExpr, 0); + pOut->zStart = pLeft->zStart; + pOut->zEnd = pRight->zEnd; + } +#line 874 "parse.y" + + /* Construct an expression node for a unary postfix operator + */ + static void spanUnaryPostfix( + ExprSpan *pOut, /* Write the new expression node here */ + Parse *pParse, /* Parsing context to record errors */ + int op, /* The operator */ + ExprSpan *pOperand, /* The operand */ + Token *pPostOp /* The operand token for setting the span */ + ){ + pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0); + pOut->zStart = pOperand->zStart; + pOut->zEnd = &pPostOp->z[pPostOp->n]; + } +#line 893 "parse.y" + + /* A routine to convert a binary TK_IS or TK_ISNOT expression into a + ** unary TK_ISNULL or TK_NOTNULL expression. */ + static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){ + sqlite3 *db = pParse->db; + if( db->mallocFailed==0 && pY->op==TK_NULL ){ + pA->op = (u8)op; + sqlite3ExprDelete(db, pA->pRight); + pA->pRight = 0; + } + } +#line 921 "parse.y" + + /* Construct an expression node for a unary prefix operator + */ + static void spanUnaryPrefix( + ExprSpan *pOut, /* Write the new expression node here */ + Parse *pParse, /* Parsing context to record errors */ + int op, /* The operator */ + ExprSpan *pOperand, /* The operand */ + Token *pPreOp /* The operand token for setting the span */ + ){ + pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0); + pOut->zStart = pPreOp->z; + pOut->zEnd = pOperand->zEnd; + } +#line 141 "parse.c" +/* Next is all token values, in a form suitable for use by makeheaders. +** This section will be null unless lemon is run with the -m switch. +*/ +/* +** These constants (all generated automatically by the parser generator) +** specify the various kinds of tokens (terminals) that the parser +** understands. +** +** Each symbol here is a terminal symbol in the grammar. +*/ +/* Make sure the INTERFACE macro is defined. +*/ +#ifndef INTERFACE +# define INTERFACE 1 +#endif +/* The next thing included is series of defines which control +** various aspects of the generated parser. +** YYCODETYPE is the data type used for storing terminal +** and nonterminal numbers. "unsigned char" is +** used if there are fewer than 250 terminals +** and nonterminals. "int" is used otherwise. +** YYNOCODE is a number of type YYCODETYPE which corresponds +** to no legal terminal or nonterminal number. This +** number is used to fill in empty slots of the hash +** table. +** YYFALLBACK If defined, this indicates that one or more tokens +** have fall-back values which should be used if the +** original value of the token will not parse. +** YYACTIONTYPE is the data type used for storing terminal +** and nonterminal numbers. "unsigned char" is +** used if there are fewer than 250 rules and +** states combined. "int" is used otherwise. +** sqlite3ParserTOKENTYPE is the data type used for minor tokens given +** directly to the parser from the tokenizer. +** YYMINORTYPE is the data type used for all minor tokens. +** This is typically a union of many types, one of +** which is sqlite3ParserTOKENTYPE. The entry in the union +** for base tokens is called "yy0". +** YYSTACKDEPTH is the maximum depth of the parser's stack. If +** zero the stack is dynamically sized using realloc() +** sqlite3ParserARG_SDECL A static variable declaration for the %extra_argument +** sqlite3ParserARG_PDECL A parameter declaration for the %extra_argument +** sqlite3ParserARG_STORE Code to store %extra_argument into yypParser +** sqlite3ParserARG_FETCH Code to extract %extra_argument from yypParser +** YYNSTATE the combined number of states. +** YYNRULE the number of rules in the grammar +** YYERRORSYMBOL is the code number of the error symbol. If not +** defined, then do no error processing. +*/ +#define YYCODETYPE unsigned char +#define YYNOCODE 253 +#define YYACTIONTYPE unsigned short int +#define YYWILDCARD 67 +#define sqlite3ParserTOKENTYPE Token +typedef union { + int yyinit; + sqlite3ParserTOKENTYPE yy0; + int yy4; + struct TrigEvent yy90; + ExprSpan yy118; + TriggerStep* yy203; + u8 yy210; + struct {int value; int mask;} yy215; + SrcList* yy259; + struct LimitVal yy292; + Expr* yy314; + ExprList* yy322; + struct LikeOp yy342; + IdList* yy384; + Select* yy387; +} YYMINORTYPE; +#ifndef YYSTACKDEPTH +#define YYSTACKDEPTH 100 +#endif +#define sqlite3ParserARG_SDECL Parse *pParse; +#define sqlite3ParserARG_PDECL ,Parse *pParse +#define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse +#define sqlite3ParserARG_STORE yypParser->pParse = pParse +#define YYNSTATE 630 +#define YYNRULE 329 +#define YYFALLBACK 1 +#define YY_NO_ACTION (YYNSTATE+YYNRULE+2) +#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) +#define YY_ERROR_ACTION (YYNSTATE+YYNRULE) + +/* The yyzerominor constant is used to initialize instances of +** YYMINORTYPE objects to zero. */ +static const YYMINORTYPE yyzerominor = { 0 }; + +/* Define the yytestcase() macro to be a no-op if is not already defined +** otherwise. +** +** Applications can choose to define yytestcase() in the %include section +** to a macro that can assist in verifying code coverage. For production +** code the yytestcase() macro should be turned off. But it is useful +** for testing. +*/ +#ifndef yytestcase +# define yytestcase(X) +#endif + + +/* Next are the tables used to determine what action to take based on the +** current state and lookahead token. These tables are used to implement +** functions that take a state number and lookahead value and return an +** action integer. +** +** Suppose the action integer is N. Then the action is determined as +** follows +** +** 0 <= N < YYNSTATE Shift N. That is, push the lookahead +** token onto the stack and goto state N. +** +** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE. +** +** N == YYNSTATE+YYNRULE A syntax error has occurred. +** +** N == YYNSTATE+YYNRULE+1 The parser accepts its input. +** +** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused +** slots in the yy_action[] table. +** +** The action table is constructed as a single large table named yy_action[]. +** Given state S and lookahead X, the action is computed as +** +** yy_action[ yy_shift_ofst[S] + X ] +** +** If the index value yy_shift_ofst[S]+X is out of range or if the value +** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S] +** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table +** and that yy_default[S] should be used instead. +** +** The formula above is for computing the action when the lookahead is +** a terminal symbol. If the lookahead is a non-terminal (as occurs after +** a reduce action) then the yy_reduce_ofst[] array is used in place of +** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of +** YY_SHIFT_USE_DFLT. +** +** The following are the tables generated in this section: +** +** yy_action[] A single table containing all actions. +** yy_lookahead[] A table containing the lookahead for each entry in +** yy_action. Used to detect hash collisions. +** yy_shift_ofst[] For each state, the offset into yy_action for +** shifting terminals. +** yy_reduce_ofst[] For each state, the offset into yy_action for +** shifting non-terminals after a reduce. +** yy_default[] Default action for each state. +*/ +#define YY_ACTTAB_COUNT (1557) +static const YYACTIONTYPE yy_action[] = { + /* 0 */ 313, 960, 186, 419, 2, 172, 627, 597, 55, 55, + /* 10 */ 55, 55, 48, 53, 53, 53, 53, 52, 52, 51, + /* 20 */ 51, 51, 50, 238, 302, 283, 623, 622, 516, 515, + /* 30 */ 590, 584, 55, 55, 55, 55, 282, 53, 53, 53, + /* 40 */ 53, 52, 52, 51, 51, 51, 50, 238, 6, 56, + /* 50 */ 57, 47, 582, 581, 583, 583, 54, 54, 55, 55, + /* 60 */ 55, 55, 608, 53, 53, 53, 53, 52, 52, 51, + /* 70 */ 51, 51, 50, 238, 313, 597, 409, 330, 579, 579, + /* 80 */ 32, 53, 53, 53, 53, 52, 52, 51, 51, 51, + /* 90 */ 50, 238, 330, 217, 620, 619, 166, 411, 624, 382, + /* 100 */ 379, 378, 7, 491, 590, 584, 200, 199, 198, 58, + /* 110 */ 377, 300, 414, 621, 481, 66, 623, 622, 621, 580, + /* 120 */ 254, 601, 94, 56, 57, 47, 582, 581, 583, 583, + /* 130 */ 54, 54, 55, 55, 55, 55, 671, 53, 53, 53, + /* 140 */ 53, 52, 52, 51, 51, 51, 50, 238, 313, 532, + /* 150 */ 226, 506, 507, 133, 177, 139, 284, 385, 279, 384, + /* 160 */ 169, 197, 342, 398, 251, 226, 253, 275, 388, 167, + /* 170 */ 139, 284, 385, 279, 384, 169, 570, 236, 590, 584, + /* 180 */ 672, 240, 275, 157, 620, 619, 554, 437, 51, 51, + /* 190 */ 51, 50, 238, 343, 439, 553, 438, 56, 57, 47, + /* 200 */ 582, 581, 583, 583, 54, 54, 55, 55, 55, 55, + /* 210 */ 465, 53, 53, 53, 53, 52, 52, 51, 51, 51, + /* 220 */ 50, 238, 313, 390, 52, 52, 51, 51, 51, 50, + /* 230 */ 238, 391, 166, 491, 566, 382, 379, 378, 409, 440, + /* 240 */ 579, 579, 252, 440, 607, 66, 377, 513, 621, 49, + /* 250 */ 46, 147, 590, 584, 621, 16, 466, 189, 621, 441, + /* 260 */ 442, 673, 526, 441, 340, 577, 595, 64, 194, 482, + /* 270 */ 434, 56, 57, 47, 582, 581, 583, 583, 54, 54, + /* 280 */ 55, 55, 55, 55, 30, 53, 53, 53, 53, 52, + /* 290 */ 52, 51, 51, 51, 50, 238, 313, 593, 593, 593, + /* 300 */ 387, 578, 606, 493, 259, 351, 258, 411, 1, 623, + /* 310 */ 622, 496, 623, 622, 65, 240, 623, 622, 597, 443, + /* 320 */ 237, 239, 414, 341, 237, 602, 590, 584, 18, 603, + /* 330 */ 166, 601, 87, 382, 379, 378, 67, 623, 622, 38, + /* 340 */ 623, 622, 176, 270, 377, 56, 57, 47, 582, 581, + /* 350 */ 583, 583, 54, 54, 55, 55, 55, 55, 175, 53, + /* 360 */ 53, 53, 53, 52, 52, 51, 51, 51, 50, 238, + /* 370 */ 313, 396, 233, 411, 531, 565, 317, 620, 619, 44, + /* 380 */ 620, 619, 240, 206, 620, 619, 597, 266, 414, 268, + /* 390 */ 409, 597, 579, 579, 352, 184, 505, 601, 73, 533, + /* 400 */ 590, 584, 466, 548, 190, 620, 619, 576, 620, 619, + /* 410 */ 547, 383, 551, 35, 332, 575, 574, 600, 504, 56, + /* 420 */ 57, 47, 582, 581, 583, 583, 54, 54, 55, 55, + /* 430 */ 55, 55, 567, 53, 53, 53, 53, 52, 52, 51, + /* 440 */ 51, 51, 50, 238, 313, 411, 561, 561, 528, 364, + /* 450 */ 259, 351, 258, 183, 361, 549, 524, 374, 411, 597, + /* 460 */ 414, 240, 560, 560, 409, 604, 579, 579, 328, 601, + /* 470 */ 93, 623, 622, 414, 590, 584, 237, 564, 559, 559, + /* 480 */ 520, 402, 601, 87, 409, 210, 579, 579, 168, 421, + /* 490 */ 950, 519, 950, 56, 57, 47, 582, 581, 583, 583, + /* 500 */ 54, 54, 55, 55, 55, 55, 192, 53, 53, 53, + /* 510 */ 53, 52, 52, 51, 51, 51, 50, 238, 313, 600, + /* 520 */ 293, 563, 511, 234, 357, 146, 475, 475, 367, 411, + /* 530 */ 562, 411, 358, 542, 425, 171, 411, 215, 144, 620, + /* 540 */ 619, 544, 318, 353, 414, 203, 414, 275, 590, 584, + /* 550 */ 549, 414, 174, 601, 94, 601, 79, 558, 471, 61, + /* 560 */ 601, 79, 421, 949, 350, 949, 34, 56, 57, 47, + /* 570 */ 582, 581, 583, 583, 54, 54, 55, 55, 55, 55, + /* 580 */ 535, 53, 53, 53, 53, 52, 52, 51, 51, 51, + /* 590 */ 50, 238, 313, 307, 424, 394, 272, 49, 46, 147, + /* 600 */ 349, 322, 4, 411, 491, 312, 321, 425, 568, 492, + /* 610 */ 216, 264, 407, 575, 574, 429, 66, 549, 414, 621, + /* 620 */ 540, 602, 590, 584, 13, 603, 621, 601, 72, 12, + /* 630 */ 618, 617, 616, 202, 210, 621, 546, 469, 422, 319, + /* 640 */ 148, 56, 57, 47, 582, 581, 583, 583, 54, 54, + /* 650 */ 55, 55, 55, 55, 338, 53, 53, 53, 53, 52, + /* 660 */ 52, 51, 51, 51, 50, 238, 313, 600, 600, 411, + /* 670 */ 39, 21, 37, 170, 237, 875, 411, 572, 572, 201, + /* 680 */ 144, 473, 538, 331, 414, 474, 143, 146, 630, 628, + /* 690 */ 334, 414, 353, 601, 68, 168, 590, 584, 132, 365, + /* 700 */ 601, 96, 307, 423, 530, 336, 49, 46, 147, 568, + /* 710 */ 406, 216, 549, 360, 529, 56, 57, 47, 582, 581, + /* 720 */ 583, 583, 54, 54, 55, 55, 55, 55, 411, 53, + /* 730 */ 53, 53, 53, 52, 52, 51, 51, 51, 50, 238, + /* 740 */ 313, 411, 605, 414, 484, 510, 172, 422, 597, 318, + /* 750 */ 496, 485, 601, 99, 411, 142, 414, 411, 231, 411, + /* 760 */ 540, 411, 359, 629, 2, 601, 97, 426, 308, 414, + /* 770 */ 590, 584, 414, 20, 414, 621, 414, 621, 601, 106, + /* 780 */ 503, 601, 105, 601, 108, 601, 109, 204, 28, 56, + /* 790 */ 57, 47, 582, 581, 583, 583, 54, 54, 55, 55, + /* 800 */ 55, 55, 411, 53, 53, 53, 53, 52, 52, 51, + /* 810 */ 51, 51, 50, 238, 313, 411, 597, 414, 411, 276, + /* 820 */ 214, 600, 411, 366, 213, 381, 601, 134, 274, 500, + /* 830 */ 414, 167, 130, 414, 621, 411, 354, 414, 376, 601, + /* 840 */ 135, 129, 601, 100, 590, 584, 601, 104, 522, 521, + /* 850 */ 414, 621, 224, 273, 600, 167, 327, 282, 600, 601, + /* 860 */ 103, 468, 521, 56, 57, 47, 582, 581, 583, 583, + /* 870 */ 54, 54, 55, 55, 55, 55, 411, 53, 53, 53, + /* 880 */ 53, 52, 52, 51, 51, 51, 50, 238, 313, 411, + /* 890 */ 27, 414, 411, 375, 276, 167, 359, 544, 50, 238, + /* 900 */ 601, 95, 128, 223, 414, 411, 165, 414, 411, 621, + /* 910 */ 411, 621, 612, 601, 102, 372, 601, 76, 590, 584, + /* 920 */ 414, 570, 236, 414, 470, 414, 167, 621, 188, 601, + /* 930 */ 98, 225, 601, 138, 601, 137, 232, 56, 45, 47, + /* 940 */ 582, 581, 583, 583, 54, 54, 55, 55, 55, 55, + /* 950 */ 411, 53, 53, 53, 53, 52, 52, 51, 51, 51, + /* 960 */ 50, 238, 313, 276, 276, 414, 411, 276, 544, 459, + /* 970 */ 359, 171, 209, 479, 601, 136, 628, 334, 621, 621, + /* 980 */ 125, 414, 621, 368, 411, 621, 257, 540, 589, 588, + /* 990 */ 601, 75, 590, 584, 458, 446, 23, 23, 124, 414, + /* 1000 */ 326, 325, 621, 427, 324, 309, 600, 288, 601, 92, + /* 1010 */ 586, 585, 57, 47, 582, 581, 583, 583, 54, 54, + /* 1020 */ 55, 55, 55, 55, 411, 53, 53, 53, 53, 52, + /* 1030 */ 52, 51, 51, 51, 50, 238, 313, 587, 411, 414, + /* 1040 */ 411, 207, 611, 476, 171, 472, 160, 123, 601, 91, + /* 1050 */ 323, 261, 15, 414, 464, 414, 411, 621, 411, 354, + /* 1060 */ 222, 411, 601, 74, 601, 90, 590, 584, 159, 264, + /* 1070 */ 158, 414, 461, 414, 621, 600, 414, 121, 120, 25, + /* 1080 */ 601, 89, 601, 101, 621, 601, 88, 47, 582, 581, + /* 1090 */ 583, 583, 54, 54, 55, 55, 55, 55, 544, 53, + /* 1100 */ 53, 53, 53, 52, 52, 51, 51, 51, 50, 238, + /* 1110 */ 43, 405, 263, 3, 610, 264, 140, 415, 622, 24, + /* 1120 */ 410, 11, 456, 594, 118, 155, 219, 452, 408, 621, + /* 1130 */ 621, 621, 156, 43, 405, 621, 3, 286, 621, 113, + /* 1140 */ 415, 622, 111, 445, 411, 400, 557, 403, 545, 10, + /* 1150 */ 411, 408, 264, 110, 205, 436, 541, 566, 453, 414, + /* 1160 */ 621, 621, 63, 621, 435, 414, 411, 621, 601, 94, + /* 1170 */ 403, 621, 411, 337, 601, 86, 150, 40, 41, 534, + /* 1180 */ 566, 414, 242, 264, 42, 413, 412, 414, 600, 595, + /* 1190 */ 601, 85, 191, 333, 107, 451, 601, 84, 621, 539, + /* 1200 */ 40, 41, 420, 230, 411, 149, 316, 42, 413, 412, + /* 1210 */ 398, 127, 595, 315, 621, 399, 278, 625, 181, 414, + /* 1220 */ 593, 593, 593, 592, 591, 14, 450, 411, 601, 71, + /* 1230 */ 240, 621, 43, 405, 264, 3, 615, 180, 264, 415, + /* 1240 */ 622, 614, 414, 593, 593, 593, 592, 591, 14, 621, + /* 1250 */ 408, 601, 70, 621, 417, 33, 405, 613, 3, 411, + /* 1260 */ 264, 411, 415, 622, 418, 626, 178, 509, 8, 403, + /* 1270 */ 241, 416, 126, 408, 414, 621, 414, 449, 208, 566, + /* 1280 */ 240, 221, 621, 601, 83, 601, 82, 599, 297, 277, + /* 1290 */ 296, 30, 403, 31, 395, 264, 295, 397, 489, 40, + /* 1300 */ 41, 411, 566, 220, 621, 294, 42, 413, 412, 271, + /* 1310 */ 621, 595, 600, 621, 59, 60, 414, 269, 267, 623, + /* 1320 */ 622, 36, 40, 41, 621, 601, 81, 598, 235, 42, + /* 1330 */ 413, 412, 621, 621, 595, 265, 344, 411, 248, 556, + /* 1340 */ 173, 185, 593, 593, 593, 592, 591, 14, 218, 29, + /* 1350 */ 621, 543, 414, 305, 304, 303, 179, 301, 411, 566, + /* 1360 */ 454, 601, 80, 289, 335, 593, 593, 593, 592, 591, + /* 1370 */ 14, 411, 287, 414, 151, 392, 246, 260, 411, 196, + /* 1380 */ 195, 523, 601, 69, 411, 245, 414, 526, 537, 285, + /* 1390 */ 389, 595, 621, 414, 536, 601, 17, 362, 153, 414, + /* 1400 */ 466, 463, 601, 78, 154, 414, 462, 152, 601, 77, + /* 1410 */ 355, 255, 621, 455, 601, 9, 621, 386, 444, 517, + /* 1420 */ 247, 621, 593, 593, 593, 621, 621, 244, 621, 243, + /* 1430 */ 430, 518, 292, 621, 329, 621, 145, 393, 280, 513, + /* 1440 */ 291, 131, 621, 514, 621, 621, 311, 621, 259, 346, + /* 1450 */ 249, 621, 621, 229, 314, 621, 228, 512, 227, 240, + /* 1460 */ 494, 488, 310, 164, 487, 486, 373, 480, 163, 262, + /* 1470 */ 369, 371, 162, 26, 212, 478, 477, 161, 141, 363, + /* 1480 */ 467, 122, 339, 187, 119, 348, 347, 117, 116, 115, + /* 1490 */ 114, 112, 182, 457, 320, 22, 433, 432, 448, 19, + /* 1500 */ 609, 431, 428, 62, 193, 596, 573, 298, 555, 552, + /* 1510 */ 571, 404, 290, 380, 498, 510, 495, 306, 281, 499, + /* 1520 */ 250, 5, 497, 460, 345, 447, 569, 550, 238, 299, + /* 1530 */ 527, 525, 508, 961, 502, 501, 961, 401, 961, 211, + /* 1540 */ 490, 356, 256, 961, 483, 961, 961, 961, 961, 961, + /* 1550 */ 961, 961, 961, 961, 961, 961, 370, +}; +static const YYCODETYPE yy_lookahead[] = { + /* 0 */ 19, 142, 143, 144, 145, 24, 1, 26, 77, 78, + /* 10 */ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + /* 20 */ 89, 90, 91, 92, 15, 98, 26, 27, 7, 8, + /* 30 */ 49, 50, 77, 78, 79, 80, 109, 82, 83, 84, + /* 40 */ 85, 86, 87, 88, 89, 90, 91, 92, 22, 68, + /* 50 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + /* 60 */ 79, 80, 23, 82, 83, 84, 85, 86, 87, 88, + /* 70 */ 89, 90, 91, 92, 19, 94, 112, 19, 114, 115, + /* 80 */ 25, 82, 83, 84, 85, 86, 87, 88, 89, 90, + /* 90 */ 91, 92, 19, 22, 94, 95, 96, 150, 150, 99, + /* 100 */ 100, 101, 76, 150, 49, 50, 105, 106, 107, 54, + /* 110 */ 110, 158, 165, 165, 161, 162, 26, 27, 165, 113, + /* 120 */ 16, 174, 175, 68, 69, 70, 71, 72, 73, 74, + /* 130 */ 75, 76, 77, 78, 79, 80, 118, 82, 83, 84, + /* 140 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 23, + /* 150 */ 92, 97, 98, 24, 96, 97, 98, 99, 100, 101, + /* 160 */ 102, 25, 97, 216, 60, 92, 62, 109, 221, 25, + /* 170 */ 97, 98, 99, 100, 101, 102, 86, 87, 49, 50, + /* 180 */ 118, 116, 109, 25, 94, 95, 32, 97, 88, 89, + /* 190 */ 90, 91, 92, 128, 104, 41, 106, 68, 69, 70, + /* 200 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + /* 210 */ 11, 82, 83, 84, 85, 86, 87, 88, 89, 90, + /* 220 */ 91, 92, 19, 19, 86, 87, 88, 89, 90, 91, + /* 230 */ 92, 27, 96, 150, 66, 99, 100, 101, 112, 150, + /* 240 */ 114, 115, 138, 150, 161, 162, 110, 103, 165, 222, + /* 250 */ 223, 224, 49, 50, 165, 22, 57, 24, 165, 170, + /* 260 */ 171, 118, 94, 170, 171, 23, 98, 25, 185, 186, + /* 270 */ 243, 68, 69, 70, 71, 72, 73, 74, 75, 76, + /* 280 */ 77, 78, 79, 80, 126, 82, 83, 84, 85, 86, + /* 290 */ 87, 88, 89, 90, 91, 92, 19, 129, 130, 131, + /* 300 */ 88, 23, 172, 173, 105, 106, 107, 150, 22, 26, + /* 310 */ 27, 181, 26, 27, 22, 116, 26, 27, 26, 230, + /* 320 */ 231, 197, 165, 230, 231, 113, 49, 50, 204, 117, + /* 330 */ 96, 174, 175, 99, 100, 101, 22, 26, 27, 136, + /* 340 */ 26, 27, 118, 16, 110, 68, 69, 70, 71, 72, + /* 350 */ 73, 74, 75, 76, 77, 78, 79, 80, 118, 82, + /* 360 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + /* 370 */ 19, 214, 215, 150, 23, 23, 155, 94, 95, 22, + /* 380 */ 94, 95, 116, 160, 94, 95, 94, 60, 165, 62, + /* 390 */ 112, 26, 114, 115, 128, 23, 36, 174, 175, 88, + /* 400 */ 49, 50, 57, 120, 22, 94, 95, 23, 94, 95, + /* 410 */ 120, 51, 25, 136, 169, 170, 171, 194, 58, 68, + /* 420 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + /* 430 */ 79, 80, 23, 82, 83, 84, 85, 86, 87, 88, + /* 440 */ 89, 90, 91, 92, 19, 150, 12, 12, 23, 228, + /* 450 */ 105, 106, 107, 23, 233, 25, 165, 19, 150, 94, + /* 460 */ 165, 116, 28, 28, 112, 174, 114, 115, 108, 174, + /* 470 */ 175, 26, 27, 165, 49, 50, 231, 11, 44, 44, + /* 480 */ 46, 46, 174, 175, 112, 160, 114, 115, 50, 22, + /* 490 */ 23, 57, 25, 68, 69, 70, 71, 72, 73, 74, + /* 500 */ 75, 76, 77, 78, 79, 80, 119, 82, 83, 84, + /* 510 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 194, + /* 520 */ 225, 23, 23, 215, 19, 95, 105, 106, 107, 150, + /* 530 */ 23, 150, 27, 23, 67, 25, 150, 206, 207, 94, + /* 540 */ 95, 166, 104, 218, 165, 22, 165, 109, 49, 50, + /* 550 */ 120, 165, 25, 174, 175, 174, 175, 23, 21, 234, + /* 560 */ 174, 175, 22, 23, 239, 25, 25, 68, 69, 70, + /* 570 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + /* 580 */ 205, 82, 83, 84, 85, 86, 87, 88, 89, 90, + /* 590 */ 91, 92, 19, 22, 23, 216, 23, 222, 223, 224, + /* 600 */ 63, 220, 35, 150, 150, 163, 220, 67, 166, 167, + /* 610 */ 168, 150, 169, 170, 171, 161, 162, 25, 165, 165, + /* 620 */ 150, 113, 49, 50, 25, 117, 165, 174, 175, 35, + /* 630 */ 7, 8, 9, 160, 160, 165, 120, 100, 67, 247, + /* 640 */ 248, 68, 69, 70, 71, 72, 73, 74, 75, 76, + /* 650 */ 77, 78, 79, 80, 193, 82, 83, 84, 85, 86, + /* 660 */ 87, 88, 89, 90, 91, 92, 19, 194, 194, 150, + /* 670 */ 135, 24, 137, 35, 231, 138, 150, 129, 130, 206, + /* 680 */ 207, 30, 27, 213, 165, 34, 118, 95, 0, 1, + /* 690 */ 2, 165, 218, 174, 175, 50, 49, 50, 22, 48, + /* 700 */ 174, 175, 22, 23, 23, 244, 222, 223, 224, 166, + /* 710 */ 167, 168, 120, 239, 23, 68, 69, 70, 71, 72, + /* 720 */ 73, 74, 75, 76, 77, 78, 79, 80, 150, 82, + /* 730 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + /* 740 */ 19, 150, 173, 165, 181, 182, 24, 67, 26, 104, + /* 750 */ 181, 188, 174, 175, 150, 39, 165, 150, 52, 150, + /* 760 */ 150, 150, 150, 144, 145, 174, 175, 249, 250, 165, + /* 770 */ 49, 50, 165, 52, 165, 165, 165, 165, 174, 175, + /* 780 */ 29, 174, 175, 174, 175, 174, 175, 160, 22, 68, + /* 790 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + /* 800 */ 79, 80, 150, 82, 83, 84, 85, 86, 87, 88, + /* 810 */ 89, 90, 91, 92, 19, 150, 94, 165, 150, 150, + /* 820 */ 160, 194, 150, 213, 160, 52, 174, 175, 23, 23, + /* 830 */ 165, 25, 22, 165, 165, 150, 150, 165, 52, 174, + /* 840 */ 175, 22, 174, 175, 49, 50, 174, 175, 190, 191, + /* 850 */ 165, 165, 240, 23, 194, 25, 187, 109, 194, 174, + /* 860 */ 175, 190, 191, 68, 69, 70, 71, 72, 73, 74, + /* 870 */ 75, 76, 77, 78, 79, 80, 150, 82, 83, 84, + /* 880 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 150, + /* 890 */ 22, 165, 150, 23, 150, 25, 150, 166, 91, 92, + /* 900 */ 174, 175, 22, 217, 165, 150, 102, 165, 150, 165, + /* 910 */ 150, 165, 150, 174, 175, 19, 174, 175, 49, 50, + /* 920 */ 165, 86, 87, 165, 23, 165, 25, 165, 24, 174, + /* 930 */ 175, 187, 174, 175, 174, 175, 205, 68, 69, 70, + /* 940 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + /* 950 */ 150, 82, 83, 84, 85, 86, 87, 88, 89, 90, + /* 960 */ 91, 92, 19, 150, 150, 165, 150, 150, 166, 23, + /* 970 */ 150, 25, 160, 20, 174, 175, 1, 2, 165, 165, + /* 980 */ 104, 165, 165, 43, 150, 165, 240, 150, 49, 50, + /* 990 */ 174, 175, 49, 50, 23, 23, 25, 25, 53, 165, + /* 1000 */ 187, 187, 165, 23, 187, 25, 194, 205, 174, 175, + /* 1010 */ 71, 72, 69, 70, 71, 72, 73, 74, 75, 76, + /* 1020 */ 77, 78, 79, 80, 150, 82, 83, 84, 85, 86, + /* 1030 */ 87, 88, 89, 90, 91, 92, 19, 98, 150, 165, + /* 1040 */ 150, 160, 150, 59, 25, 53, 104, 22, 174, 175, + /* 1050 */ 213, 138, 5, 165, 1, 165, 150, 165, 150, 150, + /* 1060 */ 240, 150, 174, 175, 174, 175, 49, 50, 118, 150, + /* 1070 */ 35, 165, 27, 165, 165, 194, 165, 108, 127, 76, + /* 1080 */ 174, 175, 174, 175, 165, 174, 175, 70, 71, 72, + /* 1090 */ 73, 74, 75, 76, 77, 78, 79, 80, 166, 82, + /* 1100 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + /* 1110 */ 19, 20, 193, 22, 150, 150, 150, 26, 27, 76, + /* 1120 */ 150, 22, 1, 150, 119, 121, 217, 20, 37, 165, + /* 1130 */ 165, 165, 16, 19, 20, 165, 22, 205, 165, 119, + /* 1140 */ 26, 27, 108, 128, 150, 150, 150, 56, 150, 22, + /* 1150 */ 150, 37, 150, 127, 160, 23, 150, 66, 193, 165, + /* 1160 */ 165, 165, 16, 165, 23, 165, 150, 165, 174, 175, + /* 1170 */ 56, 165, 150, 65, 174, 175, 15, 86, 87, 88, + /* 1180 */ 66, 165, 140, 150, 93, 94, 95, 165, 194, 98, + /* 1190 */ 174, 175, 22, 3, 164, 193, 174, 175, 165, 150, + /* 1200 */ 86, 87, 4, 180, 150, 248, 251, 93, 94, 95, + /* 1210 */ 216, 180, 98, 251, 165, 221, 150, 149, 6, 165, + /* 1220 */ 129, 130, 131, 132, 133, 134, 193, 150, 174, 175, + /* 1230 */ 116, 165, 19, 20, 150, 22, 149, 151, 150, 26, + /* 1240 */ 27, 149, 165, 129, 130, 131, 132, 133, 134, 165, + /* 1250 */ 37, 174, 175, 165, 149, 19, 20, 13, 22, 150, + /* 1260 */ 150, 150, 26, 27, 146, 147, 151, 150, 25, 56, + /* 1270 */ 152, 159, 154, 37, 165, 165, 165, 193, 160, 66, + /* 1280 */ 116, 193, 165, 174, 175, 174, 175, 194, 199, 150, + /* 1290 */ 200, 126, 56, 124, 123, 150, 201, 122, 150, 86, + /* 1300 */ 87, 150, 66, 193, 165, 202, 93, 94, 95, 150, + /* 1310 */ 165, 98, 194, 165, 125, 22, 165, 150, 150, 26, + /* 1320 */ 27, 135, 86, 87, 165, 174, 175, 203, 226, 93, + /* 1330 */ 94, 95, 165, 165, 98, 150, 218, 150, 193, 157, + /* 1340 */ 118, 157, 129, 130, 131, 132, 133, 134, 5, 104, + /* 1350 */ 165, 211, 165, 10, 11, 12, 13, 14, 150, 66, + /* 1360 */ 17, 174, 175, 210, 246, 129, 130, 131, 132, 133, + /* 1370 */ 134, 150, 210, 165, 31, 121, 33, 150, 150, 86, + /* 1380 */ 87, 176, 174, 175, 150, 42, 165, 94, 211, 210, + /* 1390 */ 150, 98, 165, 165, 211, 174, 175, 150, 55, 165, + /* 1400 */ 57, 150, 174, 175, 61, 165, 150, 64, 174, 175, + /* 1410 */ 150, 150, 165, 150, 174, 175, 165, 104, 150, 184, + /* 1420 */ 150, 165, 129, 130, 131, 165, 165, 150, 165, 150, + /* 1430 */ 150, 176, 150, 165, 47, 165, 150, 150, 176, 103, + /* 1440 */ 150, 22, 165, 178, 165, 165, 179, 165, 105, 106, + /* 1450 */ 107, 165, 165, 229, 111, 165, 92, 176, 229, 116, + /* 1460 */ 184, 176, 179, 156, 176, 176, 18, 157, 156, 237, + /* 1470 */ 45, 157, 156, 135, 157, 157, 238, 156, 68, 157, + /* 1480 */ 189, 189, 139, 219, 22, 157, 18, 192, 192, 192, + /* 1490 */ 192, 189, 219, 199, 157, 242, 40, 157, 199, 242, + /* 1500 */ 153, 157, 38, 245, 196, 166, 232, 198, 177, 177, + /* 1510 */ 232, 227, 209, 178, 166, 182, 166, 148, 177, 177, + /* 1520 */ 209, 196, 177, 199, 209, 199, 166, 208, 92, 195, + /* 1530 */ 174, 174, 183, 252, 183, 183, 252, 191, 252, 235, + /* 1540 */ 186, 241, 241, 252, 186, 252, 252, 252, 252, 252, + /* 1550 */ 252, 252, 252, 252, 252, 252, 236, +}; +#define YY_SHIFT_USE_DFLT (-74) +#define YY_SHIFT_COUNT (418) +#define YY_SHIFT_MIN (-73) +#define YY_SHIFT_MAX (1468) +static const short yy_shift_ofst[] = { + /* 0 */ 975, 1114, 1343, 1114, 1213, 1213, 90, 90, 0, -19, + /* 10 */ 1213, 1213, 1213, 1213, 1213, 345, 445, 721, 1091, 1213, + /* 20 */ 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, + /* 30 */ 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, + /* 40 */ 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1236, 1213, 1213, + /* 50 */ 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, + /* 60 */ 1213, 199, 445, 445, 835, 835, 365, 1164, 55, 647, + /* 70 */ 573, 499, 425, 351, 277, 203, 129, 795, 795, 795, + /* 80 */ 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, + /* 90 */ 795, 795, 795, 795, 795, 869, 795, 943, 1017, 1017, + /* 100 */ -69, -45, -45, -45, -45, -45, -1, 58, 138, 100, + /* 110 */ 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, + /* 120 */ 445, 445, 445, 445, 445, 445, 537, 438, 445, 445, + /* 130 */ 445, 445, 445, 365, 807, 1436, -74, -74, -74, 1293, + /* 140 */ 73, 434, 434, 311, 314, 290, 283, 286, 540, 467, + /* 150 */ 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, + /* 160 */ 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, + /* 170 */ 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, + /* 180 */ 445, 445, 65, 722, 722, 722, 688, 266, 1164, 1164, + /* 190 */ 1164, -74, -74, -74, 136, 168, 168, 234, 360, 360, + /* 200 */ 360, 430, 372, 435, 352, 278, 126, -36, -36, -36, + /* 210 */ -36, 421, 651, -36, -36, 592, 292, 212, 623, 158, + /* 220 */ 204, 204, 505, 158, 505, 144, 365, 154, 365, 154, + /* 230 */ 645, 154, 204, 154, 154, 535, 548, 548, 365, 387, + /* 240 */ 508, 233, 1464, 1222, 1222, 1456, 1456, 1222, 1462, 1410, + /* 250 */ 1165, 1468, 1468, 1468, 1468, 1222, 1165, 1462, 1410, 1410, + /* 260 */ 1222, 1448, 1338, 1425, 1222, 1222, 1448, 1222, 1448, 1222, + /* 270 */ 1448, 1419, 1313, 1313, 1313, 1387, 1364, 1364, 1419, 1313, + /* 280 */ 1336, 1313, 1387, 1313, 1313, 1254, 1245, 1254, 1245, 1254, + /* 290 */ 1245, 1222, 1222, 1186, 1189, 1175, 1169, 1171, 1165, 1164, + /* 300 */ 1243, 1244, 1244, 1212, 1212, 1212, 1212, -74, -74, -74, + /* 310 */ -74, -74, -74, 939, 104, 680, 571, 327, 1, 980, + /* 320 */ 26, 972, 971, 946, 901, 870, 830, 806, 54, 21, + /* 330 */ -73, 510, 242, 1198, 1190, 1170, 1042, 1161, 1108, 1146, + /* 340 */ 1141, 1132, 1015, 1127, 1026, 1034, 1020, 1107, 1004, 1116, + /* 350 */ 1121, 1005, 1099, 951, 1043, 1003, 969, 1045, 1035, 950, + /* 360 */ 1053, 1047, 1025, 942, 913, 992, 1019, 945, 984, 940, + /* 370 */ 876, 904, 953, 896, 748, 804, 880, 786, 868, 819, + /* 380 */ 805, 810, 773, 751, 766, 706, 716, 691, 681, 568, + /* 390 */ 655, 638, 676, 516, 541, 594, 599, 567, 541, 534, + /* 400 */ 507, 527, 498, 523, 466, 382, 409, 384, 357, 6, + /* 410 */ 240, 224, 143, 62, 18, 71, 39, 9, 5, +}; +#define YY_REDUCE_USE_DFLT (-142) +#define YY_REDUCE_COUNT (312) +#define YY_REDUCE_MIN (-141) +#define YY_REDUCE_MAX (1369) +static const short yy_reduce_ofst[] = { + /* 0 */ -141, 994, 1118, 223, 157, -53, 93, 89, 83, 375, + /* 10 */ 386, 381, 379, 308, 295, 325, -47, 27, 1240, 1234, + /* 20 */ 1228, 1221, 1208, 1187, 1151, 1111, 1109, 1077, 1054, 1022, + /* 30 */ 1016, 1000, 911, 908, 906, 890, 888, 874, 834, 816, + /* 40 */ 800, 760, 758, 755, 742, 739, 726, 685, 672, 668, + /* 50 */ 665, 652, 611, 609, 607, 604, 591, 578, 526, 519, + /* 60 */ 453, 474, 454, 461, 443, 245, 442, 473, 484, 484, + /* 70 */ 484, 484, 484, 484, 484, 484, 484, 484, 484, 484, + /* 80 */ 484, 484, 484, 484, 484, 484, 484, 484, 484, 484, + /* 90 */ 484, 484, 484, 484, 484, 484, 484, 484, 484, 484, + /* 100 */ 484, 484, 484, 484, 484, 484, 484, 130, 484, 484, + /* 110 */ 1145, 909, 1110, 1088, 1084, 1033, 1002, 965, 820, 837, + /* 120 */ 746, 686, 612, 817, 610, 919, 221, 563, 814, 813, + /* 130 */ 744, 669, 470, 543, 484, 484, 484, 484, 484, 291, + /* 140 */ 569, 671, 658, 970, 1290, 1287, 1286, 1282, 518, 518, + /* 150 */ 1280, 1279, 1277, 1270, 1268, 1263, 1261, 1260, 1256, 1251, + /* 160 */ 1247, 1227, 1185, 1168, 1167, 1159, 1148, 1139, 1117, 1066, + /* 170 */ 1049, 1006, 998, 996, 995, 973, 970, 966, 964, 892, + /* 180 */ 762, -52, 881, 932, 802, 731, 619, 812, 664, 660, + /* 190 */ 627, 392, 331, 124, 1358, 1357, 1356, 1354, 1352, 1351, + /* 200 */ 1349, 1319, 1334, 1346, 1334, 1334, 1334, 1334, 1334, 1334, + /* 210 */ 1334, 1320, 1304, 1334, 1334, 1319, 1360, 1325, 1369, 1326, + /* 220 */ 1315, 1311, 1301, 1324, 1300, 1335, 1350, 1345, 1348, 1342, + /* 230 */ 1333, 1341, 1303, 1332, 1331, 1284, 1278, 1274, 1339, 1309, + /* 240 */ 1308, 1347, 1258, 1344, 1340, 1257, 1253, 1337, 1273, 1302, + /* 250 */ 1299, 1298, 1297, 1296, 1295, 1328, 1294, 1264, 1292, 1291, + /* 260 */ 1322, 1321, 1238, 1232, 1318, 1317, 1316, 1314, 1312, 1310, + /* 270 */ 1307, 1283, 1289, 1288, 1285, 1276, 1229, 1224, 1267, 1281, + /* 280 */ 1265, 1262, 1235, 1255, 1205, 1183, 1179, 1177, 1162, 1140, + /* 290 */ 1153, 1184, 1182, 1102, 1124, 1103, 1095, 1090, 1089, 1093, + /* 300 */ 1112, 1115, 1086, 1105, 1092, 1087, 1068, 962, 955, 957, + /* 310 */ 1031, 1023, 1030, +}; +static const YYACTIONTYPE yy_default[] = { + /* 0 */ 635, 870, 959, 959, 959, 870, 899, 899, 959, 759, + /* 10 */ 959, 959, 959, 959, 868, 959, 959, 933, 959, 959, + /* 20 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, + /* 30 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, + /* 40 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, + /* 50 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, + /* 60 */ 959, 959, 959, 959, 899, 899, 674, 763, 794, 959, + /* 70 */ 959, 959, 959, 959, 959, 959, 959, 932, 934, 809, + /* 80 */ 808, 802, 801, 912, 774, 799, 792, 785, 796, 871, + /* 90 */ 864, 865, 863, 867, 872, 959, 795, 831, 848, 830, + /* 100 */ 842, 847, 854, 846, 843, 833, 832, 666, 834, 835, + /* 110 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, + /* 120 */ 959, 959, 959, 959, 959, 959, 661, 728, 959, 959, + /* 130 */ 959, 959, 959, 959, 836, 837, 851, 850, 849, 959, + /* 140 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, + /* 150 */ 959, 939, 937, 959, 883, 959, 959, 959, 959, 959, + /* 160 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, + /* 170 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, + /* 180 */ 959, 641, 959, 759, 759, 759, 635, 959, 959, 959, + /* 190 */ 959, 951, 763, 753, 719, 959, 959, 959, 959, 959, + /* 200 */ 959, 959, 959, 959, 959, 959, 959, 804, 742, 922, + /* 210 */ 924, 959, 905, 740, 663, 761, 676, 751, 643, 798, + /* 220 */ 776, 776, 917, 798, 917, 700, 959, 788, 959, 788, + /* 230 */ 697, 788, 776, 788, 788, 866, 959, 959, 959, 760, + /* 240 */ 751, 959, 944, 767, 767, 936, 936, 767, 810, 732, + /* 250 */ 798, 739, 739, 739, 739, 767, 798, 810, 732, 732, + /* 260 */ 767, 658, 911, 909, 767, 767, 658, 767, 658, 767, + /* 270 */ 658, 876, 730, 730, 730, 715, 880, 880, 876, 730, + /* 280 */ 700, 730, 715, 730, 730, 780, 775, 780, 775, 780, + /* 290 */ 775, 767, 767, 959, 793, 781, 791, 789, 798, 959, + /* 300 */ 718, 651, 651, 640, 640, 640, 640, 956, 956, 951, + /* 310 */ 702, 702, 684, 959, 959, 959, 959, 959, 959, 959, + /* 320 */ 885, 959, 959, 959, 959, 959, 959, 959, 959, 959, + /* 330 */ 959, 959, 959, 959, 636, 946, 959, 959, 943, 959, + /* 340 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, + /* 350 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 915, + /* 360 */ 959, 959, 959, 959, 959, 959, 908, 907, 959, 959, + /* 370 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, + /* 380 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, + /* 390 */ 959, 959, 959, 959, 790, 959, 782, 959, 869, 959, + /* 400 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 745, + /* 410 */ 819, 959, 818, 822, 817, 668, 959, 649, 959, 632, + /* 420 */ 637, 955, 958, 957, 954, 953, 952, 947, 945, 942, + /* 430 */ 941, 940, 938, 935, 931, 889, 887, 894, 893, 892, + /* 440 */ 891, 890, 888, 886, 884, 805, 803, 800, 797, 930, + /* 450 */ 882, 741, 738, 737, 657, 948, 914, 923, 921, 811, + /* 460 */ 920, 919, 918, 916, 913, 900, 807, 806, 733, 874, + /* 470 */ 873, 660, 904, 903, 902, 906, 910, 901, 769, 659, + /* 480 */ 656, 665, 722, 721, 729, 727, 726, 725, 724, 723, + /* 490 */ 720, 667, 675, 686, 714, 699, 698, 879, 881, 878, + /* 500 */ 877, 707, 706, 712, 711, 710, 709, 708, 705, 704, + /* 510 */ 703, 696, 695, 701, 694, 717, 716, 713, 693, 736, + /* 520 */ 735, 734, 731, 692, 691, 690, 822, 689, 688, 828, + /* 530 */ 827, 815, 858, 756, 755, 754, 766, 765, 778, 777, + /* 540 */ 813, 812, 779, 764, 758, 757, 773, 772, 771, 770, + /* 550 */ 762, 752, 784, 787, 786, 783, 860, 768, 857, 929, + /* 560 */ 928, 927, 926, 925, 862, 861, 829, 826, 679, 680, + /* 570 */ 898, 896, 897, 895, 682, 681, 678, 677, 859, 747, + /* 580 */ 746, 855, 852, 844, 840, 856, 853, 845, 841, 839, + /* 590 */ 838, 824, 823, 821, 820, 816, 825, 670, 748, 744, + /* 600 */ 743, 814, 750, 749, 687, 685, 683, 664, 662, 655, + /* 610 */ 653, 652, 654, 650, 648, 647, 646, 645, 644, 673, + /* 620 */ 672, 671, 669, 668, 642, 639, 638, 634, 633, 631, +}; + +/* The next table maps tokens into fallback tokens. If a construct +** like the following: +** +** %fallback ID X Y Z. +** +** appears in the grammar, then ID becomes a fallback token for X, Y, +** and Z. Whenever one of the tokens X, Y, or Z is input to the parser +** but it does not parse, the type of the token is changed to ID and +** the parse is retried before an error is thrown. +*/ +#ifdef YYFALLBACK +static const YYCODETYPE yyFallback[] = { + 0, /* $ => nothing */ + 0, /* SEMI => nothing */ + 26, /* EXPLAIN => ID */ + 26, /* QUERY => ID */ + 26, /* PLAN => ID */ + 26, /* BEGIN => ID */ + 0, /* TRANSACTION => nothing */ + 26, /* DEFERRED => ID */ + 26, /* IMMEDIATE => ID */ + 26, /* EXCLUSIVE => ID */ + 0, /* COMMIT => nothing */ + 26, /* END => ID */ + 26, /* ROLLBACK => ID */ + 26, /* SAVEPOINT => ID */ + 26, /* RELEASE => ID */ + 0, /* TO => nothing */ + 0, /* TABLE => nothing */ + 0, /* CREATE => nothing */ + 26, /* IF => ID */ + 0, /* NOT => nothing */ + 0, /* EXISTS => nothing */ + 26, /* TEMP => ID */ + 0, /* LP => nothing */ + 0, /* RP => nothing */ + 0, /* AS => nothing */ + 0, /* COMMA => nothing */ + 0, /* ID => nothing */ + 0, /* INDEXED => nothing */ + 26, /* ABORT => ID */ + 26, /* ACTION => ID */ + 26, /* AFTER => ID */ + 26, /* ANALYZE => ID */ + 26, /* ASC => ID */ + 26, /* ATTACH => ID */ + 26, /* BEFORE => ID */ + 26, /* BY => ID */ + 26, /* CASCADE => ID */ + 26, /* CAST => ID */ + 26, /* COLUMNKW => ID */ + 26, /* CONFLICT => ID */ + 26, /* DATABASE => ID */ + 26, /* DESC => ID */ + 26, /* DETACH => ID */ + 26, /* EACH => ID */ + 26, /* FAIL => ID */ + 26, /* FOR => ID */ + 26, /* IGNORE => ID */ + 26, /* INITIALLY => ID */ + 26, /* INSTEAD => ID */ + 26, /* LIKE_KW => ID */ + 26, /* MATCH => ID */ + 26, /* NO => ID */ + 26, /* KEY => ID */ + 26, /* OF => ID */ + 26, /* OFFSET => ID */ + 26, /* PRAGMA => ID */ + 26, /* RAISE => ID */ + 26, /* REPLACE => ID */ + 26, /* RESTRICT => ID */ + 26, /* ROW => ID */ + 26, /* TRIGGER => ID */ + 26, /* VACUUM => ID */ + 26, /* VIEW => ID */ + 26, /* VIRTUAL => ID */ + 26, /* REINDEX => ID */ + 26, /* RENAME => ID */ + 26, /* CTIME_KW => ID */ +}; +#endif /* YYFALLBACK */ + +/* The following structure represents a single element of the +** parser's stack. Information stored includes: +** +** + The state number for the parser at this level of the stack. +** +** + The value of the token stored at this level of the stack. +** (In other words, the "major" token.) +** +** + The semantic value stored at this level of the stack. This is +** the information used by the action routines in the grammar. +** It is sometimes called the "minor" token. +*/ +struct yyStackEntry { + YYACTIONTYPE stateno; /* The state-number */ + YYCODETYPE major; /* The major token value. This is the code + ** number for the token at this stack level */ + YYMINORTYPE minor; /* The user-supplied minor token value. This + ** is the value of the token */ +}; +typedef struct yyStackEntry yyStackEntry; + +/* The state of the parser is completely contained in an instance of +** the following structure */ +struct yyParser { + int yyidx; /* Index of top element in stack */ +#ifdef YYTRACKMAXSTACKDEPTH + int yyidxMax; /* Maximum value of yyidx */ +#endif + int yyerrcnt; /* Shifts left before out of the error */ + sqlite3ParserARG_SDECL /* A place to hold %extra_argument */ +#if YYSTACKDEPTH<=0 + int yystksz; /* Current side of the stack */ + yyStackEntry *yystack; /* The parser's stack */ +#else + yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */ +#endif +}; +typedef struct yyParser yyParser; + +#ifndef NDEBUG +#include +static FILE *yyTraceFILE = 0; +static char *yyTracePrompt = 0; +#endif /* NDEBUG */ + +#ifndef NDEBUG +/* +** Turn parser tracing on by giving a stream to which to write the trace +** and a prompt to preface each trace message. Tracing is turned off +** by making either argument NULL +** +** Inputs: +**
    +**
  • A FILE* to which trace output should be written. +** If NULL, then tracing is turned off. +**
  • A prefix string written at the beginning of every +** line of trace output. If NULL, then tracing is +** turned off. +**
+** +** Outputs: +** None. +*/ +void sqlite3ParserTrace(FILE *TraceFILE, char *zTracePrompt){ + yyTraceFILE = TraceFILE; + yyTracePrompt = zTracePrompt; + if( yyTraceFILE==0 ) yyTracePrompt = 0; + else if( yyTracePrompt==0 ) yyTraceFILE = 0; +} +#endif /* NDEBUG */ + +#ifndef NDEBUG +/* For tracing shifts, the names of all terminals and nonterminals +** are required. The following table supplies these names */ +static const char *const yyTokenName[] = { + "$", "SEMI", "EXPLAIN", "QUERY", + "PLAN", "BEGIN", "TRANSACTION", "DEFERRED", + "IMMEDIATE", "EXCLUSIVE", "COMMIT", "END", + "ROLLBACK", "SAVEPOINT", "RELEASE", "TO", + "TABLE", "CREATE", "IF", "NOT", + "EXISTS", "TEMP", "LP", "RP", + "AS", "COMMA", "ID", "INDEXED", + "ABORT", "ACTION", "AFTER", "ANALYZE", + "ASC", "ATTACH", "BEFORE", "BY", + "CASCADE", "CAST", "COLUMNKW", "CONFLICT", + "DATABASE", "DESC", "DETACH", "EACH", + "FAIL", "FOR", "IGNORE", "INITIALLY", + "INSTEAD", "LIKE_KW", "MATCH", "NO", + "KEY", "OF", "OFFSET", "PRAGMA", + "RAISE", "REPLACE", "RESTRICT", "ROW", + "TRIGGER", "VACUUM", "VIEW", "VIRTUAL", + "REINDEX", "RENAME", "CTIME_KW", "ANY", + "OR", "AND", "IS", "BETWEEN", + "IN", "ISNULL", "NOTNULL", "NE", + "EQ", "GT", "LE", "LT", + "GE", "ESCAPE", "BITAND", "BITOR", + "LSHIFT", "RSHIFT", "PLUS", "MINUS", + "STAR", "SLASH", "REM", "CONCAT", + "COLLATE", "BITNOT", "STRING", "JOIN_KW", + "CONSTRAINT", "DEFAULT", "NULL", "PRIMARY", + "UNIQUE", "CHECK", "REFERENCES", "AUTOINCR", + "ON", "INSERT", "DELETE", "UPDATE", + "SET", "DEFERRABLE", "FOREIGN", "DROP", + "UNION", "ALL", "EXCEPT", "INTERSECT", + "SELECT", "DISTINCT", "DOT", "FROM", + "JOIN", "USING", "ORDER", "GROUP", + "HAVING", "LIMIT", "WHERE", "INTO", + "VALUES", "INTEGER", "FLOAT", "BLOB", + "REGISTER", "VARIABLE", "CASE", "WHEN", + "THEN", "ELSE", "INDEX", "ALTER", + "ADD", "error", "input", "cmdlist", + "ecmd", "explain", "cmdx", "cmd", + "transtype", "trans_opt", "nm", "savepoint_opt", + "create_table", "create_table_args", "createkw", "temp", + "ifnotexists", "dbnm", "columnlist", "conslist_opt", + "select", "column", "columnid", "type", + "carglist", "id", "ids", "typetoken", + "typename", "signed", "plus_num", "minus_num", + "carg", "ccons", "term", "expr", + "onconf", "sortorder", "autoinc", "idxlist_opt", + "refargs", "defer_subclause", "refarg", "refact", + "init_deferred_pred_opt", "conslist", "tcons", "idxlist", + "defer_subclause_opt", "orconf", "resolvetype", "raisetype", + "ifexists", "fullname", "oneselect", "multiselect_op", + "distinct", "selcollist", "from", "where_opt", + "groupby_opt", "having_opt", "orderby_opt", "limit_opt", + "sclp", "as", "seltablist", "stl_prefix", + "joinop", "indexed_opt", "on_opt", "using_opt", + "joinop2", "inscollist", "sortlist", "sortitem", + "nexprlist", "setlist", "insert_cmd", "inscollist_opt", + "itemlist", "exprlist", "likeop", "between_op", + "in_op", "case_operand", "case_exprlist", "case_else", + "uniqueflag", "collate", "nmnum", "plus_opt", + "number", "trigger_decl", "trigger_cmd_list", "trigger_time", + "trigger_event", "foreach_clause", "when_clause", "trigger_cmd", + "trnm", "tridxby", "database_kw_opt", "key_opt", + "add_column_fullname", "kwcolumn_opt", "create_vtab", "vtabarglist", + "vtabarg", "vtabargtoken", "lp", "anylist", +}; +#endif /* NDEBUG */ + +#ifndef NDEBUG +/* For tracing reduce actions, the names of all rules are required. +*/ +static const char *const yyRuleName[] = { + /* 0 */ "input ::= cmdlist", + /* 1 */ "cmdlist ::= cmdlist ecmd", + /* 2 */ "cmdlist ::= ecmd", + /* 3 */ "ecmd ::= SEMI", + /* 4 */ "ecmd ::= explain cmdx SEMI", + /* 5 */ "explain ::=", + /* 6 */ "explain ::= EXPLAIN", + /* 7 */ "explain ::= EXPLAIN QUERY PLAN", + /* 8 */ "cmdx ::= cmd", + /* 9 */ "cmd ::= BEGIN transtype trans_opt", + /* 10 */ "trans_opt ::=", + /* 11 */ "trans_opt ::= TRANSACTION", + /* 12 */ "trans_opt ::= TRANSACTION nm", + /* 13 */ "transtype ::=", + /* 14 */ "transtype ::= DEFERRED", + /* 15 */ "transtype ::= IMMEDIATE", + /* 16 */ "transtype ::= EXCLUSIVE", + /* 17 */ "cmd ::= COMMIT trans_opt", + /* 18 */ "cmd ::= END trans_opt", + /* 19 */ "cmd ::= ROLLBACK trans_opt", + /* 20 */ "savepoint_opt ::= SAVEPOINT", + /* 21 */ "savepoint_opt ::=", + /* 22 */ "cmd ::= SAVEPOINT nm", + /* 23 */ "cmd ::= RELEASE savepoint_opt nm", + /* 24 */ "cmd ::= ROLLBACK trans_opt TO savepoint_opt nm", + /* 25 */ "cmd ::= create_table create_table_args", + /* 26 */ "create_table ::= createkw temp TABLE ifnotexists nm dbnm", + /* 27 */ "createkw ::= CREATE", + /* 28 */ "ifnotexists ::=", + /* 29 */ "ifnotexists ::= IF NOT EXISTS", + /* 30 */ "temp ::= TEMP", + /* 31 */ "temp ::=", + /* 32 */ "create_table_args ::= LP columnlist conslist_opt RP", + /* 33 */ "create_table_args ::= AS select", + /* 34 */ "columnlist ::= columnlist COMMA column", + /* 35 */ "columnlist ::= column", + /* 36 */ "column ::= columnid type carglist", + /* 37 */ "columnid ::= nm", + /* 38 */ "id ::= ID", + /* 39 */ "id ::= INDEXED", + /* 40 */ "ids ::= ID|STRING", + /* 41 */ "nm ::= id", + /* 42 */ "nm ::= STRING", + /* 43 */ "nm ::= JOIN_KW", + /* 44 */ "type ::=", + /* 45 */ "type ::= typetoken", + /* 46 */ "typetoken ::= typename", + /* 47 */ "typetoken ::= typename LP signed RP", + /* 48 */ "typetoken ::= typename LP signed COMMA signed RP", + /* 49 */ "typename ::= ids", + /* 50 */ "typename ::= typename ids", + /* 51 */ "signed ::= plus_num", + /* 52 */ "signed ::= minus_num", + /* 53 */ "carglist ::= carglist carg", + /* 54 */ "carglist ::=", + /* 55 */ "carg ::= CONSTRAINT nm ccons", + /* 56 */ "carg ::= ccons", + /* 57 */ "ccons ::= DEFAULT term", + /* 58 */ "ccons ::= DEFAULT LP expr RP", + /* 59 */ "ccons ::= DEFAULT PLUS term", + /* 60 */ "ccons ::= DEFAULT MINUS term", + /* 61 */ "ccons ::= DEFAULT id", + /* 62 */ "ccons ::= NULL onconf", + /* 63 */ "ccons ::= NOT NULL onconf", + /* 64 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc", + /* 65 */ "ccons ::= UNIQUE onconf", + /* 66 */ "ccons ::= CHECK LP expr RP", + /* 67 */ "ccons ::= REFERENCES nm idxlist_opt refargs", + /* 68 */ "ccons ::= defer_subclause", + /* 69 */ "ccons ::= COLLATE ids", + /* 70 */ "autoinc ::=", + /* 71 */ "autoinc ::= AUTOINCR", + /* 72 */ "refargs ::=", + /* 73 */ "refargs ::= refargs refarg", + /* 74 */ "refarg ::= MATCH nm", + /* 75 */ "refarg ::= ON INSERT refact", + /* 76 */ "refarg ::= ON DELETE refact", + /* 77 */ "refarg ::= ON UPDATE refact", + /* 78 */ "refact ::= SET NULL", + /* 79 */ "refact ::= SET DEFAULT", + /* 80 */ "refact ::= CASCADE", + /* 81 */ "refact ::= RESTRICT", + /* 82 */ "refact ::= NO ACTION", + /* 83 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt", + /* 84 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt", + /* 85 */ "init_deferred_pred_opt ::=", + /* 86 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED", + /* 87 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE", + /* 88 */ "conslist_opt ::=", + /* 89 */ "conslist_opt ::= COMMA conslist", + /* 90 */ "conslist ::= conslist COMMA tcons", + /* 91 */ "conslist ::= conslist tcons", + /* 92 */ "conslist ::= tcons", + /* 93 */ "tcons ::= CONSTRAINT nm", + /* 94 */ "tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf", + /* 95 */ "tcons ::= UNIQUE LP idxlist RP onconf", + /* 96 */ "tcons ::= CHECK LP expr RP onconf", + /* 97 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt", + /* 98 */ "defer_subclause_opt ::=", + /* 99 */ "defer_subclause_opt ::= defer_subclause", + /* 100 */ "onconf ::=", + /* 101 */ "onconf ::= ON CONFLICT resolvetype", + /* 102 */ "orconf ::=", + /* 103 */ "orconf ::= OR resolvetype", + /* 104 */ "resolvetype ::= raisetype", + /* 105 */ "resolvetype ::= IGNORE", + /* 106 */ "resolvetype ::= REPLACE", + /* 107 */ "cmd ::= DROP TABLE ifexists fullname", + /* 108 */ "ifexists ::= IF EXISTS", + /* 109 */ "ifexists ::=", + /* 110 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select", + /* 111 */ "cmd ::= DROP VIEW ifexists fullname", + /* 112 */ "cmd ::= select", + /* 113 */ "select ::= oneselect", + /* 114 */ "select ::= select multiselect_op oneselect", + /* 115 */ "multiselect_op ::= UNION", + /* 116 */ "multiselect_op ::= UNION ALL", + /* 117 */ "multiselect_op ::= EXCEPT|INTERSECT", + /* 118 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt", + /* 119 */ "distinct ::= DISTINCT", + /* 120 */ "distinct ::= ALL", + /* 121 */ "distinct ::=", + /* 122 */ "sclp ::= selcollist COMMA", + /* 123 */ "sclp ::=", + /* 124 */ "selcollist ::= sclp expr as", + /* 125 */ "selcollist ::= sclp STAR", + /* 126 */ "selcollist ::= sclp nm DOT STAR", + /* 127 */ "as ::= AS nm", + /* 128 */ "as ::= ids", + /* 129 */ "as ::=", + /* 130 */ "from ::=", + /* 131 */ "from ::= FROM seltablist", + /* 132 */ "stl_prefix ::= seltablist joinop", + /* 133 */ "stl_prefix ::=", + /* 134 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt", + /* 135 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt", + /* 136 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt", + /* 137 */ "dbnm ::=", + /* 138 */ "dbnm ::= DOT nm", + /* 139 */ "fullname ::= nm dbnm", + /* 140 */ "joinop ::= COMMA|JOIN", + /* 141 */ "joinop ::= JOIN_KW JOIN", + /* 142 */ "joinop ::= JOIN_KW nm JOIN", + /* 143 */ "joinop ::= JOIN_KW nm nm JOIN", + /* 144 */ "on_opt ::= ON expr", + /* 145 */ "on_opt ::=", + /* 146 */ "indexed_opt ::=", + /* 147 */ "indexed_opt ::= INDEXED BY nm", + /* 148 */ "indexed_opt ::= NOT INDEXED", + /* 149 */ "using_opt ::= USING LP inscollist RP", + /* 150 */ "using_opt ::=", + /* 151 */ "orderby_opt ::=", + /* 152 */ "orderby_opt ::= ORDER BY sortlist", + /* 153 */ "sortlist ::= sortlist COMMA sortitem sortorder", + /* 154 */ "sortlist ::= sortitem sortorder", + /* 155 */ "sortitem ::= expr", + /* 156 */ "sortorder ::= ASC", + /* 157 */ "sortorder ::= DESC", + /* 158 */ "sortorder ::=", + /* 159 */ "groupby_opt ::=", + /* 160 */ "groupby_opt ::= GROUP BY nexprlist", + /* 161 */ "having_opt ::=", + /* 162 */ "having_opt ::= HAVING expr", + /* 163 */ "limit_opt ::=", + /* 164 */ "limit_opt ::= LIMIT expr", + /* 165 */ "limit_opt ::= LIMIT expr OFFSET expr", + /* 166 */ "limit_opt ::= LIMIT expr COMMA expr", + /* 167 */ "cmd ::= DELETE FROM fullname indexed_opt where_opt", + /* 168 */ "where_opt ::=", + /* 169 */ "where_opt ::= WHERE expr", + /* 170 */ "cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt", + /* 171 */ "setlist ::= setlist COMMA nm EQ expr", + /* 172 */ "setlist ::= nm EQ expr", + /* 173 */ "cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP", + /* 174 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select", + /* 175 */ "cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES", + /* 176 */ "insert_cmd ::= INSERT orconf", + /* 177 */ "insert_cmd ::= REPLACE", + /* 178 */ "itemlist ::= itemlist COMMA expr", + /* 179 */ "itemlist ::= expr", + /* 180 */ "inscollist_opt ::=", + /* 181 */ "inscollist_opt ::= LP inscollist RP", + /* 182 */ "inscollist ::= inscollist COMMA nm", + /* 183 */ "inscollist ::= nm", + /* 184 */ "expr ::= term", + /* 185 */ "expr ::= LP expr RP", + /* 186 */ "term ::= NULL", + /* 187 */ "expr ::= id", + /* 188 */ "expr ::= JOIN_KW", + /* 189 */ "expr ::= nm DOT nm", + /* 190 */ "expr ::= nm DOT nm DOT nm", + /* 191 */ "term ::= INTEGER|FLOAT|BLOB", + /* 192 */ "term ::= STRING", + /* 193 */ "expr ::= REGISTER", + /* 194 */ "expr ::= VARIABLE", + /* 195 */ "expr ::= expr COLLATE ids", + /* 196 */ "expr ::= CAST LP expr AS typetoken RP", + /* 197 */ "expr ::= ID LP distinct exprlist RP", + /* 198 */ "expr ::= ID LP STAR RP", + /* 199 */ "term ::= CTIME_KW", + /* 200 */ "expr ::= expr AND expr", + /* 201 */ "expr ::= expr OR expr", + /* 202 */ "expr ::= expr LT|GT|GE|LE expr", + /* 203 */ "expr ::= expr EQ|NE expr", + /* 204 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", + /* 205 */ "expr ::= expr PLUS|MINUS expr", + /* 206 */ "expr ::= expr STAR|SLASH|REM expr", + /* 207 */ "expr ::= expr CONCAT expr", + /* 208 */ "likeop ::= LIKE_KW", + /* 209 */ "likeop ::= NOT LIKE_KW", + /* 210 */ "likeop ::= MATCH", + /* 211 */ "likeop ::= NOT MATCH", + /* 212 */ "expr ::= expr likeop expr", + /* 213 */ "expr ::= expr likeop expr ESCAPE expr", + /* 214 */ "expr ::= expr ISNULL|NOTNULL", + /* 215 */ "expr ::= expr NOT NULL", + /* 216 */ "expr ::= expr IS expr", + /* 217 */ "expr ::= expr IS NOT expr", + /* 218 */ "expr ::= NOT expr", + /* 219 */ "expr ::= BITNOT expr", + /* 220 */ "expr ::= MINUS expr", + /* 221 */ "expr ::= PLUS expr", + /* 222 */ "between_op ::= BETWEEN", + /* 223 */ "between_op ::= NOT BETWEEN", + /* 224 */ "expr ::= expr between_op expr AND expr", + /* 225 */ "in_op ::= IN", + /* 226 */ "in_op ::= NOT IN", + /* 227 */ "expr ::= expr in_op LP exprlist RP", + /* 228 */ "expr ::= LP select RP", + /* 229 */ "expr ::= expr in_op LP select RP", + /* 230 */ "expr ::= expr in_op nm dbnm", + /* 231 */ "expr ::= EXISTS LP select RP", + /* 232 */ "expr ::= CASE case_operand case_exprlist case_else END", + /* 233 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", + /* 234 */ "case_exprlist ::= WHEN expr THEN expr", + /* 235 */ "case_else ::= ELSE expr", + /* 236 */ "case_else ::=", + /* 237 */ "case_operand ::= expr", + /* 238 */ "case_operand ::=", + /* 239 */ "exprlist ::= nexprlist", + /* 240 */ "exprlist ::=", + /* 241 */ "nexprlist ::= nexprlist COMMA expr", + /* 242 */ "nexprlist ::= expr", + /* 243 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP", + /* 244 */ "uniqueflag ::= UNIQUE", + /* 245 */ "uniqueflag ::=", + /* 246 */ "idxlist_opt ::=", + /* 247 */ "idxlist_opt ::= LP idxlist RP", + /* 248 */ "idxlist ::= idxlist COMMA nm collate sortorder", + /* 249 */ "idxlist ::= nm collate sortorder", + /* 250 */ "collate ::=", + /* 251 */ "collate ::= COLLATE ids", + /* 252 */ "cmd ::= DROP INDEX ifexists fullname", + /* 253 */ "cmd ::= VACUUM", + /* 254 */ "cmd ::= VACUUM nm", + /* 255 */ "cmd ::= PRAGMA nm dbnm", + /* 256 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", + /* 257 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", + /* 258 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", + /* 259 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", + /* 260 */ "nmnum ::= plus_num", + /* 261 */ "nmnum ::= nm", + /* 262 */ "nmnum ::= ON", + /* 263 */ "nmnum ::= DELETE", + /* 264 */ "nmnum ::= DEFAULT", + /* 265 */ "plus_num ::= plus_opt number", + /* 266 */ "minus_num ::= MINUS number", + /* 267 */ "number ::= INTEGER|FLOAT", + /* 268 */ "plus_opt ::= PLUS", + /* 269 */ "plus_opt ::=", + /* 270 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", + /* 271 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", + /* 272 */ "trigger_time ::= BEFORE", + /* 273 */ "trigger_time ::= AFTER", + /* 274 */ "trigger_time ::= INSTEAD OF", + /* 275 */ "trigger_time ::=", + /* 276 */ "trigger_event ::= DELETE|INSERT", + /* 277 */ "trigger_event ::= UPDATE", + /* 278 */ "trigger_event ::= UPDATE OF inscollist", + /* 279 */ "foreach_clause ::=", + /* 280 */ "foreach_clause ::= FOR EACH ROW", + /* 281 */ "when_clause ::=", + /* 282 */ "when_clause ::= WHEN expr", + /* 283 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", + /* 284 */ "trigger_cmd_list ::= trigger_cmd SEMI", + /* 285 */ "trnm ::= nm", + /* 286 */ "trnm ::= nm DOT nm", + /* 287 */ "tridxby ::=", + /* 288 */ "tridxby ::= INDEXED BY nm", + /* 289 */ "tridxby ::= NOT INDEXED", + /* 290 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt", + /* 291 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt VALUES LP itemlist RP", + /* 292 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select", + /* 293 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt", + /* 294 */ "trigger_cmd ::= select", + /* 295 */ "expr ::= RAISE LP IGNORE RP", + /* 296 */ "expr ::= RAISE LP raisetype COMMA nm RP", + /* 297 */ "raisetype ::= ROLLBACK", + /* 298 */ "raisetype ::= ABORT", + /* 299 */ "raisetype ::= FAIL", + /* 300 */ "cmd ::= DROP TRIGGER ifexists fullname", + /* 301 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", + /* 302 */ "cmd ::= DETACH database_kw_opt expr", + /* 303 */ "key_opt ::=", + /* 304 */ "key_opt ::= KEY expr", + /* 305 */ "database_kw_opt ::= DATABASE", + /* 306 */ "database_kw_opt ::=", + /* 307 */ "cmd ::= REINDEX", + /* 308 */ "cmd ::= REINDEX nm dbnm", + /* 309 */ "cmd ::= ANALYZE", + /* 310 */ "cmd ::= ANALYZE nm dbnm", + /* 311 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", + /* 312 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column", + /* 313 */ "add_column_fullname ::= fullname", + /* 314 */ "kwcolumn_opt ::=", + /* 315 */ "kwcolumn_opt ::= COLUMNKW", + /* 316 */ "cmd ::= create_vtab", + /* 317 */ "cmd ::= create_vtab LP vtabarglist RP", + /* 318 */ "create_vtab ::= createkw VIRTUAL TABLE nm dbnm USING nm", + /* 319 */ "vtabarglist ::= vtabarg", + /* 320 */ "vtabarglist ::= vtabarglist COMMA vtabarg", + /* 321 */ "vtabarg ::=", + /* 322 */ "vtabarg ::= vtabarg vtabargtoken", + /* 323 */ "vtabargtoken ::= ANY", + /* 324 */ "vtabargtoken ::= lp anylist RP", + /* 325 */ "lp ::= LP", + /* 326 */ "anylist ::=", + /* 327 */ "anylist ::= anylist LP anylist RP", + /* 328 */ "anylist ::= anylist ANY", +}; +#endif /* NDEBUG */ + + +#if YYSTACKDEPTH<=0 +/* +** Try to increase the size of the parser stack. +*/ +static void yyGrowStack(yyParser *p){ + int newSize; + yyStackEntry *pNew; + + newSize = p->yystksz*2 + 100; + pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); + if( pNew ){ + p->yystack = pNew; + p->yystksz = newSize; +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sStack grows to %d entries!\n", + yyTracePrompt, p->yystksz); + } +#endif + } +} +#endif + +/* +** This function allocates a new parser. +** The only argument is a pointer to a function which works like +** malloc. +** +** Inputs: +** A pointer to the function used to allocate memory. +** +** Outputs: +** A pointer to a parser. This pointer is used in subsequent calls +** to sqlite3Parser and sqlite3ParserFree. +*/ +void *sqlite3ParserAlloc(void *(*mallocProc)(size_t)){ + yyParser *pParser; + pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) ); + if( pParser ){ + pParser->yyidx = -1; +#ifdef YYTRACKMAXSTACKDEPTH + pParser->yyidxMax = 0; +#endif +#if YYSTACKDEPTH<=0 + pParser->yystack = NULL; + pParser->yystksz = 0; + yyGrowStack(pParser); +#endif + } + return pParser; +} + +/* The following function deletes the value associated with a +** symbol. The symbol can be either a terminal or nonterminal. +** "yymajor" is the symbol code, and "yypminor" is a pointer to +** the value. +*/ +static void yy_destructor( + yyParser *yypParser, /* The parser */ + YYCODETYPE yymajor, /* Type code for object to destroy */ + YYMINORTYPE *yypminor /* The object to be destroyed */ +){ + sqlite3ParserARG_FETCH; + switch( yymajor ){ + /* Here is inserted the actions which take place when a + ** terminal or non-terminal is destroyed. This can happen + ** when the symbol is popped from the stack during a + ** reduce or during error processing or when a parser is + ** being destroyed before it is finished parsing. + ** + ** Note: during a reduce, the only symbols destroyed are those + ** which appear on the RHS of the rule, but which are not used + ** inside the C code. + */ + case 160: /* select */ + case 194: /* oneselect */ +{ +#line 404 "parse.y" +sqlite3SelectDelete(pParse->db, (yypminor->yy387)); +#line 1399 "parse.c" +} + break; + case 174: /* term */ + case 175: /* expr */ +{ +#line 721 "parse.y" +sqlite3ExprDelete(pParse->db, (yypminor->yy118).pExpr); +#line 1407 "parse.c" +} + break; + case 179: /* idxlist_opt */ + case 187: /* idxlist */ + case 197: /* selcollist */ + case 200: /* groupby_opt */ + case 202: /* orderby_opt */ + case 204: /* sclp */ + case 214: /* sortlist */ + case 216: /* nexprlist */ + case 217: /* setlist */ + case 220: /* itemlist */ + case 221: /* exprlist */ + case 226: /* case_exprlist */ +{ +#line 1104 "parse.y" +sqlite3ExprListDelete(pParse->db, (yypminor->yy322)); +#line 1425 "parse.c" +} + break; + case 193: /* fullname */ + case 198: /* from */ + case 206: /* seltablist */ + case 207: /* stl_prefix */ +{ +#line 535 "parse.y" +sqlite3SrcListDelete(pParse->db, (yypminor->yy259)); +#line 1435 "parse.c" +} + break; + case 199: /* where_opt */ + case 201: /* having_opt */ + case 210: /* on_opt */ + case 215: /* sortitem */ + case 225: /* case_operand */ + case 227: /* case_else */ + case 238: /* when_clause */ + case 243: /* key_opt */ +{ +#line 645 "parse.y" +sqlite3ExprDelete(pParse->db, (yypminor->yy314)); +#line 1449 "parse.c" +} + break; + case 211: /* using_opt */ + case 213: /* inscollist */ + case 219: /* inscollist_opt */ +{ +#line 567 "parse.y" +sqlite3IdListDelete(pParse->db, (yypminor->yy384)); +#line 1458 "parse.c" +} + break; + case 234: /* trigger_cmd_list */ + case 239: /* trigger_cmd */ +{ +#line 1211 "parse.y" +sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy203)); +#line 1466 "parse.c" +} + break; + case 236: /* trigger_event */ +{ +#line 1197 "parse.y" +sqlite3IdListDelete(pParse->db, (yypminor->yy90).b); +#line 1473 "parse.c" +} + break; + default: break; /* If no destructor action specified: do nothing */ + } +} + +/* +** Pop the parser's stack once. +** +** If there is a destructor routine associated with the token which +** is popped from the stack, then call it. +** +** Return the major token number for the symbol popped. +*/ +static int yy_pop_parser_stack(yyParser *pParser){ + YYCODETYPE yymajor; + yyStackEntry *yytos = &pParser->yystack[pParser->yyidx]; + + /* There is no mechanism by which the parser stack can be popped below + ** empty in SQLite. */ + if( NEVER(pParser->yyidx<0) ) return 0; +#ifndef NDEBUG + if( yyTraceFILE && pParser->yyidx>=0 ){ + fprintf(yyTraceFILE,"%sPopping %s\n", + yyTracePrompt, + yyTokenName[yytos->major]); + } +#endif + yymajor = yytos->major; + yy_destructor(pParser, yymajor, &yytos->minor); + pParser->yyidx--; + return yymajor; +} + +/* +** Deallocate and destroy a parser. Destructors are all called for +** all stack elements before shutting the parser down. +** +** Inputs: +**
    +**
  • A pointer to the parser. This should be a pointer +** obtained from sqlite3ParserAlloc. +**
  • A pointer to a function used to reclaim memory obtained +** from malloc. +**
+*/ +void sqlite3ParserFree( + void *p, /* The parser to be deleted */ + void (*freeProc)(void*) /* Function used to reclaim memory */ +){ + yyParser *pParser = (yyParser*)p; + /* In SQLite, we never try to destroy a parser that was not successfully + ** created in the first place. */ + if( NEVER(pParser==0) ) return; + while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser); +#if YYSTACKDEPTH<=0 + free(pParser->yystack); +#endif + (*freeProc)((void*)pParser); +} + +/* +** Return the peak depth of the stack for a parser. +*/ +#ifdef YYTRACKMAXSTACKDEPTH +int sqlite3ParserStackPeak(void *p){ + yyParser *pParser = (yyParser*)p; + return pParser->yyidxMax; +} +#endif + +/* +** Find the appropriate action for a parser given the terminal +** look-ahead token iLookAhead. +** +** If the look-ahead token is YYNOCODE, then check to see if the action is +** independent of the look-ahead. If it is, return the action, otherwise +** return YY_NO_ACTION. +*/ +static int yy_find_shift_action( + yyParser *pParser, /* The parser */ + YYCODETYPE iLookAhead /* The look-ahead token */ +){ + int i; + int stateno = pParser->yystack[pParser->yyidx].stateno; + + if( stateno>YY_SHIFT_COUNT + || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){ + return yy_default[stateno]; + } + assert( iLookAhead!=YYNOCODE ); + i += iLookAhead; + if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){ + if( iLookAhead>0 ){ +#ifdef YYFALLBACK + YYCODETYPE iFallback; /* Fallback token */ + if( iLookAhead %s\n", + yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); + } +#endif + return yy_find_shift_action(pParser, iFallback); + } +#endif +#ifdef YYWILDCARD + { + int j = i - iLookAhead + YYWILDCARD; + if( +#if YY_SHIFT_MIN+YYWILDCARD<0 + j>=0 && +#endif +#if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT + j %s\n", + yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]); + } +#endif /* NDEBUG */ + return yy_action[j]; + } + } +#endif /* YYWILDCARD */ + } + return yy_default[stateno]; + }else{ + return yy_action[i]; + } +} + +/* +** Find the appropriate action for a parser given the non-terminal +** look-ahead token iLookAhead. +** +** If the look-ahead token is YYNOCODE, then check to see if the action is +** independent of the look-ahead. If it is, return the action, otherwise +** return YY_NO_ACTION. +*/ +static int yy_find_reduce_action( + int stateno, /* Current state number */ + YYCODETYPE iLookAhead /* The look-ahead token */ +){ + int i; +#ifdef YYERRORSYMBOL + if( stateno>YY_REDUCE_COUNT ){ + return yy_default[stateno]; + } +#else + assert( stateno<=YY_REDUCE_COUNT ); +#endif + i = yy_reduce_ofst[stateno]; + assert( i!=YY_REDUCE_USE_DFLT ); + assert( iLookAhead!=YYNOCODE ); + i += iLookAhead; +#ifdef YYERRORSYMBOL + if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){ + return yy_default[stateno]; + } +#else + assert( i>=0 && iyyidx--; +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt); + } +#endif + while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); + /* Here code is inserted which will execute if the parser + ** stack every overflows */ +#line 37 "parse.y" + + UNUSED_PARAMETER(yypMinor); /* Silence some compiler warnings */ + sqlite3ErrorMsg(pParse, "parser stack overflow"); +#line 1663 "parse.c" + sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument var */ +} + +/* +** Perform a shift action. +*/ +static void yy_shift( + yyParser *yypParser, /* The parser to be shifted */ + int yyNewState, /* The new state to shift in */ + int yyMajor, /* The major token to shift in */ + YYMINORTYPE *yypMinor /* Pointer to the minor token to shift in */ +){ + yyStackEntry *yytos; + yypParser->yyidx++; +#ifdef YYTRACKMAXSTACKDEPTH + if( yypParser->yyidx>yypParser->yyidxMax ){ + yypParser->yyidxMax = yypParser->yyidx; + } +#endif +#if YYSTACKDEPTH>0 + if( yypParser->yyidx>=YYSTACKDEPTH ){ + yyStackOverflow(yypParser, yypMinor); + return; + } +#else + if( yypParser->yyidx>=yypParser->yystksz ){ + yyGrowStack(yypParser); + if( yypParser->yyidx>=yypParser->yystksz ){ + yyStackOverflow(yypParser, yypMinor); + return; + } + } +#endif + yytos = &yypParser->yystack[yypParser->yyidx]; + yytos->stateno = (YYACTIONTYPE)yyNewState; + yytos->major = (YYCODETYPE)yyMajor; + yytos->minor = *yypMinor; +#ifndef NDEBUG + if( yyTraceFILE && yypParser->yyidx>0 ){ + int i; + fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState); + fprintf(yyTraceFILE,"%sStack:",yyTracePrompt); + for(i=1; i<=yypParser->yyidx; i++) + fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]); + fprintf(yyTraceFILE,"\n"); + } +#endif +} + +/* The following table contains information about every rule that +** is used during the reduce. +*/ +static const struct { + YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ + unsigned char nrhs; /* Number of right-hand side symbols in the rule */ +} yyRuleInfo[] = { + { 142, 1 }, + { 143, 2 }, + { 143, 1 }, + { 144, 1 }, + { 144, 3 }, + { 145, 0 }, + { 145, 1 }, + { 145, 3 }, + { 146, 1 }, + { 147, 3 }, + { 149, 0 }, + { 149, 1 }, + { 149, 2 }, + { 148, 0 }, + { 148, 1 }, + { 148, 1 }, + { 148, 1 }, + { 147, 2 }, + { 147, 2 }, + { 147, 2 }, + { 151, 1 }, + { 151, 0 }, + { 147, 2 }, + { 147, 3 }, + { 147, 5 }, + { 147, 2 }, + { 152, 6 }, + { 154, 1 }, + { 156, 0 }, + { 156, 3 }, + { 155, 1 }, + { 155, 0 }, + { 153, 4 }, + { 153, 2 }, + { 158, 3 }, + { 158, 1 }, + { 161, 3 }, + { 162, 1 }, + { 165, 1 }, + { 165, 1 }, + { 166, 1 }, + { 150, 1 }, + { 150, 1 }, + { 150, 1 }, + { 163, 0 }, + { 163, 1 }, + { 167, 1 }, + { 167, 4 }, + { 167, 6 }, + { 168, 1 }, + { 168, 2 }, + { 169, 1 }, + { 169, 1 }, + { 164, 2 }, + { 164, 0 }, + { 172, 3 }, + { 172, 1 }, + { 173, 2 }, + { 173, 4 }, + { 173, 3 }, + { 173, 3 }, + { 173, 2 }, + { 173, 2 }, + { 173, 3 }, + { 173, 5 }, + { 173, 2 }, + { 173, 4 }, + { 173, 4 }, + { 173, 1 }, + { 173, 2 }, + { 178, 0 }, + { 178, 1 }, + { 180, 0 }, + { 180, 2 }, + { 182, 2 }, + { 182, 3 }, + { 182, 3 }, + { 182, 3 }, + { 183, 2 }, + { 183, 2 }, + { 183, 1 }, + { 183, 1 }, + { 183, 2 }, + { 181, 3 }, + { 181, 2 }, + { 184, 0 }, + { 184, 2 }, + { 184, 2 }, + { 159, 0 }, + { 159, 2 }, + { 185, 3 }, + { 185, 2 }, + { 185, 1 }, + { 186, 2 }, + { 186, 7 }, + { 186, 5 }, + { 186, 5 }, + { 186, 10 }, + { 188, 0 }, + { 188, 1 }, + { 176, 0 }, + { 176, 3 }, + { 189, 0 }, + { 189, 2 }, + { 190, 1 }, + { 190, 1 }, + { 190, 1 }, + { 147, 4 }, + { 192, 2 }, + { 192, 0 }, + { 147, 8 }, + { 147, 4 }, + { 147, 1 }, + { 160, 1 }, + { 160, 3 }, + { 195, 1 }, + { 195, 2 }, + { 195, 1 }, + { 194, 9 }, + { 196, 1 }, + { 196, 1 }, + { 196, 0 }, + { 204, 2 }, + { 204, 0 }, + { 197, 3 }, + { 197, 2 }, + { 197, 4 }, + { 205, 2 }, + { 205, 1 }, + { 205, 0 }, + { 198, 0 }, + { 198, 2 }, + { 207, 2 }, + { 207, 0 }, + { 206, 7 }, + { 206, 7 }, + { 206, 7 }, + { 157, 0 }, + { 157, 2 }, + { 193, 2 }, + { 208, 1 }, + { 208, 2 }, + { 208, 3 }, + { 208, 4 }, + { 210, 2 }, + { 210, 0 }, + { 209, 0 }, + { 209, 3 }, + { 209, 2 }, + { 211, 4 }, + { 211, 0 }, + { 202, 0 }, + { 202, 3 }, + { 214, 4 }, + { 214, 2 }, + { 215, 1 }, + { 177, 1 }, + { 177, 1 }, + { 177, 0 }, + { 200, 0 }, + { 200, 3 }, + { 201, 0 }, + { 201, 2 }, + { 203, 0 }, + { 203, 2 }, + { 203, 4 }, + { 203, 4 }, + { 147, 5 }, + { 199, 0 }, + { 199, 2 }, + { 147, 7 }, + { 217, 5 }, + { 217, 3 }, + { 147, 8 }, + { 147, 5 }, + { 147, 6 }, + { 218, 2 }, + { 218, 1 }, + { 220, 3 }, + { 220, 1 }, + { 219, 0 }, + { 219, 3 }, + { 213, 3 }, + { 213, 1 }, + { 175, 1 }, + { 175, 3 }, + { 174, 1 }, + { 175, 1 }, + { 175, 1 }, + { 175, 3 }, + { 175, 5 }, + { 174, 1 }, + { 174, 1 }, + { 175, 1 }, + { 175, 1 }, + { 175, 3 }, + { 175, 6 }, + { 175, 5 }, + { 175, 4 }, + { 174, 1 }, + { 175, 3 }, + { 175, 3 }, + { 175, 3 }, + { 175, 3 }, + { 175, 3 }, + { 175, 3 }, + { 175, 3 }, + { 175, 3 }, + { 222, 1 }, + { 222, 2 }, + { 222, 1 }, + { 222, 2 }, + { 175, 3 }, + { 175, 5 }, + { 175, 2 }, + { 175, 3 }, + { 175, 3 }, + { 175, 4 }, + { 175, 2 }, + { 175, 2 }, + { 175, 2 }, + { 175, 2 }, + { 223, 1 }, + { 223, 2 }, + { 175, 5 }, + { 224, 1 }, + { 224, 2 }, + { 175, 5 }, + { 175, 3 }, + { 175, 5 }, + { 175, 4 }, + { 175, 4 }, + { 175, 5 }, + { 226, 5 }, + { 226, 4 }, + { 227, 2 }, + { 227, 0 }, + { 225, 1 }, + { 225, 0 }, + { 221, 1 }, + { 221, 0 }, + { 216, 3 }, + { 216, 1 }, + { 147, 11 }, + { 228, 1 }, + { 228, 0 }, + { 179, 0 }, + { 179, 3 }, + { 187, 5 }, + { 187, 3 }, + { 229, 0 }, + { 229, 2 }, + { 147, 4 }, + { 147, 1 }, + { 147, 2 }, + { 147, 3 }, + { 147, 5 }, + { 147, 6 }, + { 147, 5 }, + { 147, 6 }, + { 230, 1 }, + { 230, 1 }, + { 230, 1 }, + { 230, 1 }, + { 230, 1 }, + { 170, 2 }, + { 171, 2 }, + { 232, 1 }, + { 231, 1 }, + { 231, 0 }, + { 147, 5 }, + { 233, 11 }, + { 235, 1 }, + { 235, 1 }, + { 235, 2 }, + { 235, 0 }, + { 236, 1 }, + { 236, 1 }, + { 236, 3 }, + { 237, 0 }, + { 237, 3 }, + { 238, 0 }, + { 238, 2 }, + { 234, 3 }, + { 234, 2 }, + { 240, 1 }, + { 240, 3 }, + { 241, 0 }, + { 241, 3 }, + { 241, 2 }, + { 239, 7 }, + { 239, 8 }, + { 239, 5 }, + { 239, 5 }, + { 239, 1 }, + { 175, 4 }, + { 175, 6 }, + { 191, 1 }, + { 191, 1 }, + { 191, 1 }, + { 147, 4 }, + { 147, 6 }, + { 147, 3 }, + { 243, 0 }, + { 243, 2 }, + { 242, 1 }, + { 242, 0 }, + { 147, 1 }, + { 147, 3 }, + { 147, 1 }, + { 147, 3 }, + { 147, 6 }, + { 147, 6 }, + { 244, 1 }, + { 245, 0 }, + { 245, 1 }, + { 147, 1 }, + { 147, 4 }, + { 246, 7 }, + { 247, 1 }, + { 247, 3 }, + { 248, 0 }, + { 248, 2 }, + { 249, 1 }, + { 249, 3 }, + { 250, 1 }, + { 251, 0 }, + { 251, 4 }, + { 251, 2 }, +}; + +static void yy_accept(yyParser*); /* Forward Declaration */ + +/* +** Perform a reduce action and the shift that must immediately +** follow the reduce. +*/ +static void yy_reduce( + yyParser *yypParser, /* The parser */ + int yyruleno /* Number of the rule by which to reduce */ +){ + int yygoto; /* The next state */ + int yyact; /* The next action */ + YYMINORTYPE yygotominor; /* The LHS of the rule reduced */ + yyStackEntry *yymsp; /* The top of the parser's stack */ + int yysize; /* Amount to pop the stack */ + sqlite3ParserARG_FETCH; + yymsp = &yypParser->yystack[yypParser->yyidx]; +#ifndef NDEBUG + if( yyTraceFILE && yyruleno>=0 + && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ + fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt, + yyRuleName[yyruleno]); + } +#endif /* NDEBUG */ + + /* Silence complaints from purify about yygotominor being uninitialized + ** in some cases when it is copied into the stack after the following + ** switch. yygotominor is uninitialized when a rule reduces that does + ** not set the value of its left-hand side nonterminal. Leaving the + ** value of the nonterminal uninitialized is utterly harmless as long + ** as the value is never used. So really the only thing this code + ** accomplishes is to quieten purify. + ** + ** 2007-01-16: The wireshark project (www.wireshark.org) reports that + ** without this code, their parser segfaults. I'm not sure what there + ** parser is doing to make this happen. This is the second bug report + ** from wireshark this week. Clearly they are stressing Lemon in ways + ** that it has not been previously stressed... (SQLite ticket #2172) + */ + /*memset(&yygotominor, 0, sizeof(yygotominor));*/ + yygotominor = yyzerominor; + + + switch( yyruleno ){ + /* Beginning here are the reduction cases. A typical example + ** follows: + ** case 0: + ** #line + ** { ... } // User supplied code + ** #line + ** break; + */ + case 5: /* explain ::= */ +#line 105 "parse.y" +{ sqlite3BeginParse(pParse, 0); } +#line 2106 "parse.c" + break; + case 6: /* explain ::= EXPLAIN */ +#line 107 "parse.y" +{ sqlite3BeginParse(pParse, 1); } +#line 2111 "parse.c" + break; + case 7: /* explain ::= EXPLAIN QUERY PLAN */ +#line 108 "parse.y" +{ sqlite3BeginParse(pParse, 2); } +#line 2116 "parse.c" + break; + case 8: /* cmdx ::= cmd */ +#line 110 "parse.y" +{ sqlite3FinishCoding(pParse); } +#line 2121 "parse.c" + break; + case 9: /* cmd ::= BEGIN transtype trans_opt */ +#line 115 "parse.y" +{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy4);} +#line 2126 "parse.c" + break; + case 13: /* transtype ::= */ +#line 120 "parse.y" +{yygotominor.yy4 = TK_DEFERRED;} +#line 2131 "parse.c" + break; + case 14: /* transtype ::= DEFERRED */ + case 15: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==15); + case 16: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==16); + case 115: /* multiselect_op ::= UNION */ yytestcase(yyruleno==115); + case 117: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==117); +#line 121 "parse.y" +{yygotominor.yy4 = yymsp[0].major;} +#line 2140 "parse.c" + break; + case 17: /* cmd ::= COMMIT trans_opt */ + case 18: /* cmd ::= END trans_opt */ yytestcase(yyruleno==18); +#line 124 "parse.y" +{sqlite3CommitTransaction(pParse);} +#line 2146 "parse.c" + break; + case 19: /* cmd ::= ROLLBACK trans_opt */ +#line 126 "parse.y" +{sqlite3RollbackTransaction(pParse);} +#line 2151 "parse.c" + break; + case 22: /* cmd ::= SAVEPOINT nm */ +#line 130 "parse.y" +{ + sqlite3Savepoint(pParse, SAVEPOINT_BEGIN, &yymsp[0].minor.yy0); +} +#line 2158 "parse.c" + break; + case 23: /* cmd ::= RELEASE savepoint_opt nm */ +#line 133 "parse.y" +{ + sqlite3Savepoint(pParse, SAVEPOINT_RELEASE, &yymsp[0].minor.yy0); +} +#line 2165 "parse.c" + break; + case 24: /* cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ +#line 136 "parse.y" +{ + sqlite3Savepoint(pParse, SAVEPOINT_ROLLBACK, &yymsp[0].minor.yy0); +} +#line 2172 "parse.c" + break; + case 26: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */ +#line 143 "parse.y" +{ + sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy4,0,0,yymsp[-2].minor.yy4); +} +#line 2179 "parse.c" + break; + case 27: /* createkw ::= CREATE */ +#line 146 "parse.y" +{ + pParse->db->lookaside.bEnabled = 0; + yygotominor.yy0 = yymsp[0].minor.yy0; +} +#line 2187 "parse.c" + break; + case 28: /* ifnotexists ::= */ + case 31: /* temp ::= */ yytestcase(yyruleno==31); + case 70: /* autoinc ::= */ yytestcase(yyruleno==70); + case 83: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==83); + case 85: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==85); + case 87: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==87); + case 98: /* defer_subclause_opt ::= */ yytestcase(yyruleno==98); + case 109: /* ifexists ::= */ yytestcase(yyruleno==109); + case 120: /* distinct ::= ALL */ yytestcase(yyruleno==120); + case 121: /* distinct ::= */ yytestcase(yyruleno==121); + case 222: /* between_op ::= BETWEEN */ yytestcase(yyruleno==222); + case 225: /* in_op ::= IN */ yytestcase(yyruleno==225); +#line 151 "parse.y" +{yygotominor.yy4 = 0;} +#line 2203 "parse.c" + break; + case 29: /* ifnotexists ::= IF NOT EXISTS */ + case 30: /* temp ::= TEMP */ yytestcase(yyruleno==30); + case 71: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==71); + case 86: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ yytestcase(yyruleno==86); + case 108: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==108); + case 119: /* distinct ::= DISTINCT */ yytestcase(yyruleno==119); + case 223: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==223); + case 226: /* in_op ::= NOT IN */ yytestcase(yyruleno==226); +#line 152 "parse.y" +{yygotominor.yy4 = 1;} +#line 2215 "parse.c" + break; + case 32: /* create_table_args ::= LP columnlist conslist_opt RP */ +#line 158 "parse.y" +{ + sqlite3EndTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0); +} +#line 2222 "parse.c" + break; + case 33: /* create_table_args ::= AS select */ +#line 161 "parse.y" +{ + sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy387); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy387); +} +#line 2230 "parse.c" + break; + case 36: /* column ::= columnid type carglist */ +#line 173 "parse.y" +{ + yygotominor.yy0.z = yymsp[-2].minor.yy0.z; + yygotominor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-2].minor.yy0.z) + pParse->sLastToken.n; +} +#line 2238 "parse.c" + break; + case 37: /* columnid ::= nm */ +#line 177 "parse.y" +{ + sqlite3AddColumn(pParse,&yymsp[0].minor.yy0); + yygotominor.yy0 = yymsp[0].minor.yy0; +} +#line 2246 "parse.c" + break; + case 38: /* id ::= ID */ + case 39: /* id ::= INDEXED */ yytestcase(yyruleno==39); + case 40: /* ids ::= ID|STRING */ yytestcase(yyruleno==40); + case 41: /* nm ::= id */ yytestcase(yyruleno==41); + case 42: /* nm ::= STRING */ yytestcase(yyruleno==42); + case 43: /* nm ::= JOIN_KW */ yytestcase(yyruleno==43); + case 46: /* typetoken ::= typename */ yytestcase(yyruleno==46); + case 49: /* typename ::= ids */ yytestcase(yyruleno==49); + case 127: /* as ::= AS nm */ yytestcase(yyruleno==127); + case 128: /* as ::= ids */ yytestcase(yyruleno==128); + case 138: /* dbnm ::= DOT nm */ yytestcase(yyruleno==138); + case 147: /* indexed_opt ::= INDEXED BY nm */ yytestcase(yyruleno==147); + case 251: /* collate ::= COLLATE ids */ yytestcase(yyruleno==251); + case 260: /* nmnum ::= plus_num */ yytestcase(yyruleno==260); + case 261: /* nmnum ::= nm */ yytestcase(yyruleno==261); + case 262: /* nmnum ::= ON */ yytestcase(yyruleno==262); + case 263: /* nmnum ::= DELETE */ yytestcase(yyruleno==263); + case 264: /* nmnum ::= DEFAULT */ yytestcase(yyruleno==264); + case 265: /* plus_num ::= plus_opt number */ yytestcase(yyruleno==265); + case 266: /* minus_num ::= MINUS number */ yytestcase(yyruleno==266); + case 267: /* number ::= INTEGER|FLOAT */ yytestcase(yyruleno==267); + case 285: /* trnm ::= nm */ yytestcase(yyruleno==285); +#line 187 "parse.y" +{yygotominor.yy0 = yymsp[0].minor.yy0;} +#line 2272 "parse.c" + break; + case 45: /* type ::= typetoken */ +#line 249 "parse.y" +{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy0);} +#line 2277 "parse.c" + break; + case 47: /* typetoken ::= typename LP signed RP */ +#line 251 "parse.y" +{ + yygotominor.yy0.z = yymsp[-3].minor.yy0.z; + yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z); +} +#line 2285 "parse.c" + break; + case 48: /* typetoken ::= typename LP signed COMMA signed RP */ +#line 255 "parse.y" +{ + yygotominor.yy0.z = yymsp[-5].minor.yy0.z; + yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z); +} +#line 2293 "parse.c" + break; + case 50: /* typename ::= typename ids */ +#line 261 "parse.y" +{yygotominor.yy0.z=yymsp[-1].minor.yy0.z; yygotominor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);} +#line 2298 "parse.c" + break; + case 57: /* ccons ::= DEFAULT term */ + case 59: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==59); +#line 272 "parse.y" +{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy118);} +#line 2304 "parse.c" + break; + case 58: /* ccons ::= DEFAULT LP expr RP */ +#line 273 "parse.y" +{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy118);} +#line 2309 "parse.c" + break; + case 60: /* ccons ::= DEFAULT MINUS term */ +#line 275 "parse.y" +{ + ExprSpan v; + v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy118.pExpr, 0, 0); + v.zStart = yymsp[-1].minor.yy0.z; + v.zEnd = yymsp[0].minor.yy118.zEnd; + sqlite3AddDefaultValue(pParse,&v); +} +#line 2320 "parse.c" + break; + case 61: /* ccons ::= DEFAULT id */ +#line 282 "parse.y" +{ + ExprSpan v; + spanExpr(&v, pParse, TK_STRING, &yymsp[0].minor.yy0); + sqlite3AddDefaultValue(pParse,&v); +} +#line 2329 "parse.c" + break; + case 63: /* ccons ::= NOT NULL onconf */ +#line 292 "parse.y" +{sqlite3AddNotNull(pParse, yymsp[0].minor.yy4);} +#line 2334 "parse.c" + break; + case 64: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */ +#line 294 "parse.y" +{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy4,yymsp[0].minor.yy4,yymsp[-2].minor.yy4);} +#line 2339 "parse.c" + break; + case 65: /* ccons ::= UNIQUE onconf */ +#line 295 "parse.y" +{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy4,0,0,0,0);} +#line 2344 "parse.c" + break; + case 66: /* ccons ::= CHECK LP expr RP */ +#line 296 "parse.y" +{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy118.pExpr);} +#line 2349 "parse.c" + break; + case 67: /* ccons ::= REFERENCES nm idxlist_opt refargs */ +#line 298 "parse.y" +{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy322,yymsp[0].minor.yy4);} +#line 2354 "parse.c" + break; + case 68: /* ccons ::= defer_subclause */ +#line 299 "parse.y" +{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy4);} +#line 2359 "parse.c" + break; + case 69: /* ccons ::= COLLATE ids */ +#line 300 "parse.y" +{sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);} +#line 2364 "parse.c" + break; + case 72: /* refargs ::= */ +#line 313 "parse.y" +{ yygotominor.yy4 = OE_None*0x0101; /* EV: R-19803-45884 */} +#line 2369 "parse.c" + break; + case 73: /* refargs ::= refargs refarg */ +#line 314 "parse.y" +{ yygotominor.yy4 = (yymsp[-1].minor.yy4 & ~yymsp[0].minor.yy215.mask) | yymsp[0].minor.yy215.value; } +#line 2374 "parse.c" + break; + case 74: /* refarg ::= MATCH nm */ + case 75: /* refarg ::= ON INSERT refact */ yytestcase(yyruleno==75); +#line 316 "parse.y" +{ yygotominor.yy215.value = 0; yygotominor.yy215.mask = 0x000000; } +#line 2380 "parse.c" + break; + case 76: /* refarg ::= ON DELETE refact */ +#line 318 "parse.y" +{ yygotominor.yy215.value = yymsp[0].minor.yy4; yygotominor.yy215.mask = 0x0000ff; } +#line 2385 "parse.c" + break; + case 77: /* refarg ::= ON UPDATE refact */ +#line 319 "parse.y" +{ yygotominor.yy215.value = yymsp[0].minor.yy4<<8; yygotominor.yy215.mask = 0x00ff00; } +#line 2390 "parse.c" + break; + case 78: /* refact ::= SET NULL */ +#line 321 "parse.y" +{ yygotominor.yy4 = OE_SetNull; /* EV: R-33326-45252 */} +#line 2395 "parse.c" + break; + case 79: /* refact ::= SET DEFAULT */ +#line 322 "parse.y" +{ yygotominor.yy4 = OE_SetDflt; /* EV: R-33326-45252 */} +#line 2400 "parse.c" + break; + case 80: /* refact ::= CASCADE */ +#line 323 "parse.y" +{ yygotominor.yy4 = OE_Cascade; /* EV: R-33326-45252 */} +#line 2405 "parse.c" + break; + case 81: /* refact ::= RESTRICT */ +#line 324 "parse.y" +{ yygotominor.yy4 = OE_Restrict; /* EV: R-33326-45252 */} +#line 2410 "parse.c" + break; + case 82: /* refact ::= NO ACTION */ +#line 325 "parse.y" +{ yygotominor.yy4 = OE_None; /* EV: R-33326-45252 */} +#line 2415 "parse.c" + break; + case 84: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ + case 99: /* defer_subclause_opt ::= defer_subclause */ yytestcase(yyruleno==99); + case 101: /* onconf ::= ON CONFLICT resolvetype */ yytestcase(yyruleno==101); + case 104: /* resolvetype ::= raisetype */ yytestcase(yyruleno==104); +#line 328 "parse.y" +{yygotominor.yy4 = yymsp[0].minor.yy4;} +#line 2423 "parse.c" + break; + case 88: /* conslist_opt ::= */ +#line 337 "parse.y" +{yygotominor.yy0.n = 0; yygotominor.yy0.z = 0;} +#line 2428 "parse.c" + break; + case 89: /* conslist_opt ::= COMMA conslist */ +#line 338 "parse.y" +{yygotominor.yy0 = yymsp[-1].minor.yy0;} +#line 2433 "parse.c" + break; + case 94: /* tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf */ +#line 344 "parse.y" +{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy322,yymsp[0].minor.yy4,yymsp[-2].minor.yy4,0);} +#line 2438 "parse.c" + break; + case 95: /* tcons ::= UNIQUE LP idxlist RP onconf */ +#line 346 "parse.y" +{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy322,yymsp[0].minor.yy4,0,0,0,0);} +#line 2443 "parse.c" + break; + case 96: /* tcons ::= CHECK LP expr RP onconf */ +#line 348 "parse.y" +{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy118.pExpr);} +#line 2448 "parse.c" + break; + case 97: /* tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt */ +#line 350 "parse.y" +{ + sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy322, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy322, yymsp[-1].minor.yy4); + sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy4); +} +#line 2456 "parse.c" + break; + case 100: /* onconf ::= */ +#line 364 "parse.y" +{yygotominor.yy4 = OE_Default;} +#line 2461 "parse.c" + break; + case 102: /* orconf ::= */ +#line 366 "parse.y" +{yygotominor.yy210 = OE_Default;} +#line 2466 "parse.c" + break; + case 103: /* orconf ::= OR resolvetype */ +#line 367 "parse.y" +{yygotominor.yy210 = (u8)yymsp[0].minor.yy4;} +#line 2471 "parse.c" + break; + case 105: /* resolvetype ::= IGNORE */ +#line 369 "parse.y" +{yygotominor.yy4 = OE_Ignore;} +#line 2476 "parse.c" + break; + case 106: /* resolvetype ::= REPLACE */ +#line 370 "parse.y" +{yygotominor.yy4 = OE_Replace;} +#line 2481 "parse.c" + break; + case 107: /* cmd ::= DROP TABLE ifexists fullname */ +#line 374 "parse.y" +{ + sqlite3DropTable(pParse, yymsp[0].minor.yy259, 0, yymsp[-1].minor.yy4); +} +#line 2488 "parse.c" + break; + case 110: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select */ +#line 384 "parse.y" +{ + sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, yymsp[0].minor.yy387, yymsp[-6].minor.yy4, yymsp[-4].minor.yy4); +} +#line 2495 "parse.c" + break; + case 111: /* cmd ::= DROP VIEW ifexists fullname */ +#line 387 "parse.y" +{ + sqlite3DropTable(pParse, yymsp[0].minor.yy259, 1, yymsp[-1].minor.yy4); +} +#line 2502 "parse.c" + break; + case 112: /* cmd ::= select */ +#line 394 "parse.y" +{ + SelectDest dest = {SRT_Output, 0, 0, 0, 0}; + sqlite3Select(pParse, yymsp[0].minor.yy387, &dest); + sqlite3ExplainBegin(pParse->pVdbe); + sqlite3ExplainSelect(pParse->pVdbe, yymsp[0].minor.yy387); + sqlite3ExplainFinish(pParse->pVdbe); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy387); +} +#line 2514 "parse.c" + break; + case 113: /* select ::= oneselect */ +#line 408 "parse.y" +{yygotominor.yy387 = yymsp[0].minor.yy387;} +#line 2519 "parse.c" + break; + case 114: /* select ::= select multiselect_op oneselect */ +#line 410 "parse.y" +{ + if( yymsp[0].minor.yy387 ){ + yymsp[0].minor.yy387->op = (u8)yymsp[-1].minor.yy4; + yymsp[0].minor.yy387->pPrior = yymsp[-2].minor.yy387; + }else{ + sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy387); + } + yygotominor.yy387 = yymsp[0].minor.yy387; +} +#line 2532 "parse.c" + break; + case 116: /* multiselect_op ::= UNION ALL */ +#line 421 "parse.y" +{yygotominor.yy4 = TK_ALL;} +#line 2537 "parse.c" + break; + case 118: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ +#line 425 "parse.y" +{ + yygotominor.yy387 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy322,yymsp[-5].minor.yy259,yymsp[-4].minor.yy314,yymsp[-3].minor.yy322,yymsp[-2].minor.yy314,yymsp[-1].minor.yy322,yymsp[-7].minor.yy4,yymsp[0].minor.yy292.pLimit,yymsp[0].minor.yy292.pOffset); +} +#line 2544 "parse.c" + break; + case 122: /* sclp ::= selcollist COMMA */ + case 247: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==247); +#line 446 "parse.y" +{yygotominor.yy322 = yymsp[-1].minor.yy322;} +#line 2550 "parse.c" + break; + case 123: /* sclp ::= */ + case 151: /* orderby_opt ::= */ yytestcase(yyruleno==151); + case 159: /* groupby_opt ::= */ yytestcase(yyruleno==159); + case 240: /* exprlist ::= */ yytestcase(yyruleno==240); + case 246: /* idxlist_opt ::= */ yytestcase(yyruleno==246); +#line 447 "parse.y" +{yygotominor.yy322 = 0;} +#line 2559 "parse.c" + break; + case 124: /* selcollist ::= sclp expr as */ +#line 448 "parse.y" +{ + yygotominor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy322, yymsp[-1].minor.yy118.pExpr); + if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yygotominor.yy322, &yymsp[0].minor.yy0, 1); + sqlite3ExprListSetSpan(pParse,yygotominor.yy322,&yymsp[-1].minor.yy118); +} +#line 2568 "parse.c" + break; + case 125: /* selcollist ::= sclp STAR */ +#line 453 "parse.y" +{ + Expr *p = sqlite3Expr(pParse->db, TK_ALL, 0); + yygotominor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy322, p); +} +#line 2576 "parse.c" + break; + case 126: /* selcollist ::= sclp nm DOT STAR */ +#line 457 "parse.y" +{ + Expr *pRight = sqlite3PExpr(pParse, TK_ALL, 0, 0, &yymsp[0].minor.yy0); + Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0); + Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0); + yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322, pDot); +} +#line 2586 "parse.c" + break; + case 129: /* as ::= */ +#line 470 "parse.y" +{yygotominor.yy0.n = 0;} +#line 2591 "parse.c" + break; + case 130: /* from ::= */ +#line 482 "parse.y" +{yygotominor.yy259 = sqlite3DbMallocZero(pParse->db, sizeof(*yygotominor.yy259));} +#line 2596 "parse.c" + break; + case 131: /* from ::= FROM seltablist */ +#line 483 "parse.y" +{ + yygotominor.yy259 = yymsp[0].minor.yy259; + sqlite3SrcListShiftJoinType(yygotominor.yy259); +} +#line 2604 "parse.c" + break; + case 132: /* stl_prefix ::= seltablist joinop */ +#line 491 "parse.y" +{ + yygotominor.yy259 = yymsp[-1].minor.yy259; + if( ALWAYS(yygotominor.yy259 && yygotominor.yy259->nSrc>0) ) yygotominor.yy259->a[yygotominor.yy259->nSrc-1].jointype = (u8)yymsp[0].minor.yy4; +} +#line 2612 "parse.c" + break; + case 133: /* stl_prefix ::= */ +#line 495 "parse.y" +{yygotominor.yy259 = 0;} +#line 2617 "parse.c" + break; + case 134: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ +#line 496 "parse.y" +{ + yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy314,yymsp[0].minor.yy384); + sqlite3SrcListIndexedBy(pParse, yygotominor.yy259, &yymsp[-2].minor.yy0); +} +#line 2625 "parse.c" + break; + case 135: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */ +#line 502 "parse.y" +{ + yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy387,yymsp[-1].minor.yy314,yymsp[0].minor.yy384); + } +#line 2632 "parse.c" + break; + case 136: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ +#line 506 "parse.y" +{ + if( yymsp[-6].minor.yy259==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy314==0 && yymsp[0].minor.yy384==0 ){ + yygotominor.yy259 = yymsp[-4].minor.yy259; + }else{ + Select *pSubquery; + sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy259); + pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy259,0,0,0,0,0,0,0); + yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy314,yymsp[0].minor.yy384); + } + } +#line 2646 "parse.c" + break; + case 137: /* dbnm ::= */ + case 146: /* indexed_opt ::= */ yytestcase(yyruleno==146); +#line 531 "parse.y" +{yygotominor.yy0.z=0; yygotominor.yy0.n=0;} +#line 2652 "parse.c" + break; + case 139: /* fullname ::= nm dbnm */ +#line 536 "parse.y" +{yygotominor.yy259 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);} +#line 2657 "parse.c" + break; + case 140: /* joinop ::= COMMA|JOIN */ +#line 540 "parse.y" +{ yygotominor.yy4 = JT_INNER; } +#line 2662 "parse.c" + break; + case 141: /* joinop ::= JOIN_KW JOIN */ +#line 541 "parse.y" +{ yygotominor.yy4 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); } +#line 2667 "parse.c" + break; + case 142: /* joinop ::= JOIN_KW nm JOIN */ +#line 542 "parse.y" +{ yygotominor.yy4 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); } +#line 2672 "parse.c" + break; + case 143: /* joinop ::= JOIN_KW nm nm JOIN */ +#line 544 "parse.y" +{ yygotominor.yy4 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); } +#line 2677 "parse.c" + break; + case 144: /* on_opt ::= ON expr */ + case 155: /* sortitem ::= expr */ yytestcase(yyruleno==155); + case 162: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==162); + case 169: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==169); + case 235: /* case_else ::= ELSE expr */ yytestcase(yyruleno==235); + case 237: /* case_operand ::= expr */ yytestcase(yyruleno==237); +#line 548 "parse.y" +{yygotominor.yy314 = yymsp[0].minor.yy118.pExpr;} +#line 2687 "parse.c" + break; + case 145: /* on_opt ::= */ + case 161: /* having_opt ::= */ yytestcase(yyruleno==161); + case 168: /* where_opt ::= */ yytestcase(yyruleno==168); + case 236: /* case_else ::= */ yytestcase(yyruleno==236); + case 238: /* case_operand ::= */ yytestcase(yyruleno==238); +#line 549 "parse.y" +{yygotominor.yy314 = 0;} +#line 2696 "parse.c" + break; + case 148: /* indexed_opt ::= NOT INDEXED */ +#line 564 "parse.y" +{yygotominor.yy0.z=0; yygotominor.yy0.n=1;} +#line 2701 "parse.c" + break; + case 149: /* using_opt ::= USING LP inscollist RP */ + case 181: /* inscollist_opt ::= LP inscollist RP */ yytestcase(yyruleno==181); +#line 568 "parse.y" +{yygotominor.yy384 = yymsp[-1].minor.yy384;} +#line 2707 "parse.c" + break; + case 150: /* using_opt ::= */ + case 180: /* inscollist_opt ::= */ yytestcase(yyruleno==180); +#line 569 "parse.y" +{yygotominor.yy384 = 0;} +#line 2713 "parse.c" + break; + case 152: /* orderby_opt ::= ORDER BY sortlist */ + case 160: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==160); + case 239: /* exprlist ::= nexprlist */ yytestcase(yyruleno==239); +#line 580 "parse.y" +{yygotominor.yy322 = yymsp[0].minor.yy322;} +#line 2720 "parse.c" + break; + case 153: /* sortlist ::= sortlist COMMA sortitem sortorder */ +#line 581 "parse.y" +{ + yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322,yymsp[-1].minor.yy314); + if( yygotominor.yy322 ) yygotominor.yy322->a[yygotominor.yy322->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy4; +} +#line 2728 "parse.c" + break; + case 154: /* sortlist ::= sortitem sortorder */ +#line 585 "parse.y" +{ + yygotominor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy314); + if( yygotominor.yy322 && ALWAYS(yygotominor.yy322->a) ) yygotominor.yy322->a[0].sortOrder = (u8)yymsp[0].minor.yy4; +} +#line 2736 "parse.c" + break; + case 156: /* sortorder ::= ASC */ + case 158: /* sortorder ::= */ yytestcase(yyruleno==158); +#line 593 "parse.y" +{yygotominor.yy4 = SQLITE_SO_ASC;} +#line 2742 "parse.c" + break; + case 157: /* sortorder ::= DESC */ +#line 594 "parse.y" +{yygotominor.yy4 = SQLITE_SO_DESC;} +#line 2747 "parse.c" + break; + case 163: /* limit_opt ::= */ +#line 620 "parse.y" +{yygotominor.yy292.pLimit = 0; yygotominor.yy292.pOffset = 0;} +#line 2752 "parse.c" + break; + case 164: /* limit_opt ::= LIMIT expr */ +#line 621 "parse.y" +{yygotominor.yy292.pLimit = yymsp[0].minor.yy118.pExpr; yygotominor.yy292.pOffset = 0;} +#line 2757 "parse.c" + break; + case 165: /* limit_opt ::= LIMIT expr OFFSET expr */ +#line 623 "parse.y" +{yygotominor.yy292.pLimit = yymsp[-2].minor.yy118.pExpr; yygotominor.yy292.pOffset = yymsp[0].minor.yy118.pExpr;} +#line 2762 "parse.c" + break; + case 166: /* limit_opt ::= LIMIT expr COMMA expr */ +#line 625 "parse.y" +{yygotominor.yy292.pOffset = yymsp[-2].minor.yy118.pExpr; yygotominor.yy292.pLimit = yymsp[0].minor.yy118.pExpr;} +#line 2767 "parse.c" + break; + case 167: /* cmd ::= DELETE FROM fullname indexed_opt where_opt */ +#line 638 "parse.y" +{ + sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy259, &yymsp[-1].minor.yy0); + sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy259,yymsp[0].minor.yy314); +} +#line 2775 "parse.c" + break; + case 170: /* cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt */ +#line 661 "parse.y" +{ + sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy259, &yymsp[-3].minor.yy0); + sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy322,"set list"); + sqlite3Update(pParse,yymsp[-4].minor.yy259,yymsp[-1].minor.yy322,yymsp[0].minor.yy314,yymsp[-5].minor.yy210); +} +#line 2784 "parse.c" + break; + case 171: /* setlist ::= setlist COMMA nm EQ expr */ +#line 671 "parse.y" +{ + yygotominor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[0].minor.yy118.pExpr); + sqlite3ExprListSetName(pParse, yygotominor.yy322, &yymsp[-2].minor.yy0, 1); +} +#line 2792 "parse.c" + break; + case 172: /* setlist ::= nm EQ expr */ +#line 675 "parse.y" +{ + yygotominor.yy322 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy118.pExpr); + sqlite3ExprListSetName(pParse, yygotominor.yy322, &yymsp[-2].minor.yy0, 1); +} +#line 2800 "parse.c" + break; + case 173: /* cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP */ +#line 684 "parse.y" +{sqlite3Insert(pParse, yymsp[-5].minor.yy259, yymsp[-1].minor.yy322, 0, yymsp[-4].minor.yy384, yymsp[-7].minor.yy210);} +#line 2805 "parse.c" + break; + case 174: /* cmd ::= insert_cmd INTO fullname inscollist_opt select */ +#line 686 "parse.y" +{sqlite3Insert(pParse, yymsp[-2].minor.yy259, 0, yymsp[0].minor.yy387, yymsp[-1].minor.yy384, yymsp[-4].minor.yy210);} +#line 2810 "parse.c" + break; + case 175: /* cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES */ +#line 688 "parse.y" +{sqlite3Insert(pParse, yymsp[-3].minor.yy259, 0, 0, yymsp[-2].minor.yy384, yymsp[-5].minor.yy210);} +#line 2815 "parse.c" + break; + case 176: /* insert_cmd ::= INSERT orconf */ +#line 691 "parse.y" +{yygotominor.yy210 = yymsp[0].minor.yy210;} +#line 2820 "parse.c" + break; + case 177: /* insert_cmd ::= REPLACE */ +#line 692 "parse.y" +{yygotominor.yy210 = OE_Replace;} +#line 2825 "parse.c" + break; + case 178: /* itemlist ::= itemlist COMMA expr */ + case 241: /* nexprlist ::= nexprlist COMMA expr */ yytestcase(yyruleno==241); +#line 699 "parse.y" +{yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[0].minor.yy118.pExpr);} +#line 2831 "parse.c" + break; + case 179: /* itemlist ::= expr */ + case 242: /* nexprlist ::= expr */ yytestcase(yyruleno==242); +#line 701 "parse.y" +{yygotominor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy118.pExpr);} +#line 2837 "parse.c" + break; + case 182: /* inscollist ::= inscollist COMMA nm */ +#line 711 "parse.y" +{yygotominor.yy384 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy384,&yymsp[0].minor.yy0);} +#line 2842 "parse.c" + break; + case 183: /* inscollist ::= nm */ +#line 713 "parse.y" +{yygotominor.yy384 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);} +#line 2847 "parse.c" + break; + case 184: /* expr ::= term */ +#line 744 "parse.y" +{yygotominor.yy118 = yymsp[0].minor.yy118;} +#line 2852 "parse.c" + break; + case 185: /* expr ::= LP expr RP */ +#line 745 "parse.y" +{yygotominor.yy118.pExpr = yymsp[-1].minor.yy118.pExpr; spanSet(&yygotominor.yy118,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);} +#line 2857 "parse.c" + break; + case 186: /* term ::= NULL */ + case 191: /* term ::= INTEGER|FLOAT|BLOB */ yytestcase(yyruleno==191); + case 192: /* term ::= STRING */ yytestcase(yyruleno==192); +#line 746 "parse.y" +{spanExpr(&yygotominor.yy118, pParse, yymsp[0].major, &yymsp[0].minor.yy0);} +#line 2864 "parse.c" + break; + case 187: /* expr ::= id */ + case 188: /* expr ::= JOIN_KW */ yytestcase(yyruleno==188); +#line 747 "parse.y" +{spanExpr(&yygotominor.yy118, pParse, TK_ID, &yymsp[0].minor.yy0);} +#line 2870 "parse.c" + break; + case 189: /* expr ::= nm DOT nm */ +#line 749 "parse.y" +{ + Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0); + Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0); + yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0); + spanSet(&yygotominor.yy118,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); +} +#line 2880 "parse.c" + break; + case 190: /* expr ::= nm DOT nm DOT nm */ +#line 755 "parse.y" +{ + Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-4].minor.yy0); + Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0); + Expr *temp3 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0); + Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0); + yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0); + spanSet(&yygotominor.yy118,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); +} +#line 2892 "parse.c" + break; + case 193: /* expr ::= REGISTER */ +#line 765 "parse.y" +{ + /* When doing a nested parse, one can include terms in an expression + ** that look like this: #1 #2 ... These terms refer to registers + ** in the virtual machine. #N is the N-th register. */ + if( pParse->nested==0 ){ + sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &yymsp[0].minor.yy0); + yygotominor.yy118.pExpr = 0; + }else{ + yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &yymsp[0].minor.yy0); + if( yygotominor.yy118.pExpr ) sqlite3GetInt32(&yymsp[0].minor.yy0.z[1], &yygotominor.yy118.pExpr->iTable); + } + spanSet(&yygotominor.yy118, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); +} +#line 2909 "parse.c" + break; + case 194: /* expr ::= VARIABLE */ +#line 778 "parse.y" +{ + spanExpr(&yygotominor.yy118, pParse, TK_VARIABLE, &yymsp[0].minor.yy0); + sqlite3ExprAssignVarNumber(pParse, yygotominor.yy118.pExpr); + spanSet(&yygotominor.yy118, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); +} +#line 2918 "parse.c" + break; + case 195: /* expr ::= expr COLLATE ids */ +#line 783 "parse.y" +{ + yygotominor.yy118.pExpr = sqlite3ExprSetCollByToken(pParse, yymsp[-2].minor.yy118.pExpr, &yymsp[0].minor.yy0); + yygotominor.yy118.zStart = yymsp[-2].minor.yy118.zStart; + yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; +} +#line 2927 "parse.c" + break; + case 196: /* expr ::= CAST LP expr AS typetoken RP */ +#line 789 "parse.y" +{ + yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy118.pExpr, 0, &yymsp[-1].minor.yy0); + spanSet(&yygotominor.yy118,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); +} +#line 2935 "parse.c" + break; + case 197: /* expr ::= ID LP distinct exprlist RP */ +#line 794 "parse.y" +{ + if( yymsp[-1].minor.yy322 && yymsp[-1].minor.yy322->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){ + sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0); + } + yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0); + spanSet(&yygotominor.yy118,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); + if( yymsp[-2].minor.yy4 && yygotominor.yy118.pExpr ){ + yygotominor.yy118.pExpr->flags |= EP_Distinct; + } +} +#line 2949 "parse.c" + break; + case 198: /* expr ::= ID LP STAR RP */ +#line 804 "parse.y" +{ + yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0); + spanSet(&yygotominor.yy118,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); +} +#line 2957 "parse.c" + break; + case 199: /* term ::= CTIME_KW */ +#line 808 "parse.y" +{ + /* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are + ** treated as functions that return constants */ + yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, 0,&yymsp[0].minor.yy0); + if( yygotominor.yy118.pExpr ){ + yygotominor.yy118.pExpr->op = TK_CONST_FUNC; + } + spanSet(&yygotominor.yy118, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); +} +#line 2970 "parse.c" + break; + case 200: /* expr ::= expr AND expr */ + case 201: /* expr ::= expr OR expr */ yytestcase(yyruleno==201); + case 202: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==202); + case 203: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==203); + case 204: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==204); + case 205: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==205); + case 206: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==206); + case 207: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==207); +#line 835 "parse.y" +{spanBinaryExpr(&yygotominor.yy118,pParse,yymsp[-1].major,&yymsp[-2].minor.yy118,&yymsp[0].minor.yy118);} +#line 2982 "parse.c" + break; + case 208: /* likeop ::= LIKE_KW */ + case 210: /* likeop ::= MATCH */ yytestcase(yyruleno==210); +#line 848 "parse.y" +{yygotominor.yy342.eOperator = yymsp[0].minor.yy0; yygotominor.yy342.not = 0;} +#line 2988 "parse.c" + break; + case 209: /* likeop ::= NOT LIKE_KW */ + case 211: /* likeop ::= NOT MATCH */ yytestcase(yyruleno==211); +#line 849 "parse.y" +{yygotominor.yy342.eOperator = yymsp[0].minor.yy0; yygotominor.yy342.not = 1;} +#line 2994 "parse.c" + break; + case 212: /* expr ::= expr likeop expr */ +#line 852 "parse.y" +{ + ExprList *pList; + pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy118.pExpr); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy118.pExpr); + yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy342.eOperator); + if( yymsp[-1].minor.yy342.not ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0); + yygotominor.yy118.zStart = yymsp[-2].minor.yy118.zStart; + yygotominor.yy118.zEnd = yymsp[0].minor.yy118.zEnd; + if( yygotominor.yy118.pExpr ) yygotominor.yy118.pExpr->flags |= EP_InfixFunc; +} +#line 3008 "parse.c" + break; + case 213: /* expr ::= expr likeop expr ESCAPE expr */ +#line 862 "parse.y" +{ + ExprList *pList; + pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy118.pExpr); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy118.pExpr); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy118.pExpr); + yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy342.eOperator); + if( yymsp[-3].minor.yy342.not ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0); + yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart; + yygotominor.yy118.zEnd = yymsp[0].minor.yy118.zEnd; + if( yygotominor.yy118.pExpr ) yygotominor.yy118.pExpr->flags |= EP_InfixFunc; +} +#line 3023 "parse.c" + break; + case 214: /* expr ::= expr ISNULL|NOTNULL */ +#line 890 "parse.y" +{spanUnaryPostfix(&yygotominor.yy118,pParse,yymsp[0].major,&yymsp[-1].minor.yy118,&yymsp[0].minor.yy0);} +#line 3028 "parse.c" + break; + case 215: /* expr ::= expr NOT NULL */ +#line 891 "parse.y" +{spanUnaryPostfix(&yygotominor.yy118,pParse,TK_NOTNULL,&yymsp[-2].minor.yy118,&yymsp[0].minor.yy0);} +#line 3033 "parse.c" + break; + case 216: /* expr ::= expr IS expr */ +#line 912 "parse.y" +{ + spanBinaryExpr(&yygotominor.yy118,pParse,TK_IS,&yymsp[-2].minor.yy118,&yymsp[0].minor.yy118); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy118.pExpr, yygotominor.yy118.pExpr, TK_ISNULL); +} +#line 3041 "parse.c" + break; + case 217: /* expr ::= expr IS NOT expr */ +#line 916 "parse.y" +{ + spanBinaryExpr(&yygotominor.yy118,pParse,TK_ISNOT,&yymsp[-3].minor.yy118,&yymsp[0].minor.yy118); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy118.pExpr, yygotominor.yy118.pExpr, TK_NOTNULL); +} +#line 3049 "parse.c" + break; + case 218: /* expr ::= NOT expr */ + case 219: /* expr ::= BITNOT expr */ yytestcase(yyruleno==219); +#line 939 "parse.y" +{spanUnaryPrefix(&yygotominor.yy118,pParse,yymsp[-1].major,&yymsp[0].minor.yy118,&yymsp[-1].minor.yy0);} +#line 3055 "parse.c" + break; + case 220: /* expr ::= MINUS expr */ +#line 942 "parse.y" +{spanUnaryPrefix(&yygotominor.yy118,pParse,TK_UMINUS,&yymsp[0].minor.yy118,&yymsp[-1].minor.yy0);} +#line 3060 "parse.c" + break; + case 221: /* expr ::= PLUS expr */ +#line 944 "parse.y" +{spanUnaryPrefix(&yygotominor.yy118,pParse,TK_UPLUS,&yymsp[0].minor.yy118,&yymsp[-1].minor.yy0);} +#line 3065 "parse.c" + break; + case 224: /* expr ::= expr between_op expr AND expr */ +#line 949 "parse.y" +{ + ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy118.pExpr); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy118.pExpr); + yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy118.pExpr, 0, 0); + if( yygotominor.yy118.pExpr ){ + yygotominor.yy118.pExpr->x.pList = pList; + }else{ + sqlite3ExprListDelete(pParse->db, pList); + } + if( yymsp[-3].minor.yy4 ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0); + yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart; + yygotominor.yy118.zEnd = yymsp[0].minor.yy118.zEnd; +} +#line 3082 "parse.c" + break; + case 227: /* expr ::= expr in_op LP exprlist RP */ +#line 966 "parse.y" +{ + if( yymsp[-1].minor.yy322==0 ){ + /* Expressions of the form + ** + ** expr1 IN () + ** expr1 NOT IN () + ** + ** simplify to constants 0 (false) and 1 (true), respectively, + ** regardless of the value of expr1. + */ + yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &sqlite3IntTokens[yymsp[-3].minor.yy4]); + sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy118.pExpr); + }else{ + yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy118.pExpr, 0, 0); + if( yygotominor.yy118.pExpr ){ + yygotominor.yy118.pExpr->x.pList = yymsp[-1].minor.yy322; + sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr); + }else{ + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322); + } + if( yymsp[-3].minor.yy4 ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0); + } + yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart; + yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; + } +#line 3111 "parse.c" + break; + case 228: /* expr ::= LP select RP */ +#line 991 "parse.y" +{ + yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0); + if( yygotominor.yy118.pExpr ){ + yygotominor.yy118.pExpr->x.pSelect = yymsp[-1].minor.yy387; + ExprSetProperty(yygotominor.yy118.pExpr, EP_xIsSelect); + sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr); + }else{ + sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy387); + } + yygotominor.yy118.zStart = yymsp[-2].minor.yy0.z; + yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; + } +#line 3127 "parse.c" + break; + case 229: /* expr ::= expr in_op LP select RP */ +#line 1003 "parse.y" +{ + yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy118.pExpr, 0, 0); + if( yygotominor.yy118.pExpr ){ + yygotominor.yy118.pExpr->x.pSelect = yymsp[-1].minor.yy387; + ExprSetProperty(yygotominor.yy118.pExpr, EP_xIsSelect); + sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr); + }else{ + sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy387); + } + if( yymsp[-3].minor.yy4 ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0); + yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart; + yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; + } +#line 3144 "parse.c" + break; + case 230: /* expr ::= expr in_op nm dbnm */ +#line 1016 "parse.y" +{ + SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0); + yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy118.pExpr, 0, 0); + if( yygotominor.yy118.pExpr ){ + yygotominor.yy118.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0); + ExprSetProperty(yygotominor.yy118.pExpr, EP_xIsSelect); + sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr); + }else{ + sqlite3SrcListDelete(pParse->db, pSrc); + } + if( yymsp[-2].minor.yy4 ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0); + yygotominor.yy118.zStart = yymsp[-3].minor.yy118.zStart; + yygotominor.yy118.zEnd = yymsp[0].minor.yy0.z ? &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] : &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]; + } +#line 3162 "parse.c" + break; + case 231: /* expr ::= EXISTS LP select RP */ +#line 1030 "parse.y" +{ + Expr *p = yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0); + if( p ){ + p->x.pSelect = yymsp[-1].minor.yy387; + ExprSetProperty(p, EP_xIsSelect); + sqlite3ExprSetHeight(pParse, p); + }else{ + sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy387); + } + yygotominor.yy118.zStart = yymsp[-3].minor.yy0.z; + yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; + } +#line 3178 "parse.c" + break; + case 232: /* expr ::= CASE case_operand case_exprlist case_else END */ +#line 1045 "parse.y" +{ + yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy314, yymsp[-1].minor.yy314, 0); + if( yygotominor.yy118.pExpr ){ + yygotominor.yy118.pExpr->x.pList = yymsp[-2].minor.yy322; + sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr); + }else{ + sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy322); + } + yygotominor.yy118.zStart = yymsp[-4].minor.yy0.z; + yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; +} +#line 3193 "parse.c" + break; + case 233: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ +#line 1058 "parse.y" +{ + yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[-2].minor.yy118.pExpr); + yygotominor.yy322 = sqlite3ExprListAppend(pParse,yygotominor.yy322, yymsp[0].minor.yy118.pExpr); +} +#line 3201 "parse.c" + break; + case 234: /* case_exprlist ::= WHEN expr THEN expr */ +#line 1062 "parse.y" +{ + yygotominor.yy322 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy118.pExpr); + yygotominor.yy322 = sqlite3ExprListAppend(pParse,yygotominor.yy322, yymsp[0].minor.yy118.pExpr); +} +#line 3209 "parse.c" + break; + case 243: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP */ +#line 1091 "parse.y" +{ + sqlite3CreateIndex(pParse, &yymsp[-6].minor.yy0, &yymsp[-5].minor.yy0, + sqlite3SrcListAppend(pParse->db,0,&yymsp[-3].minor.yy0,0), yymsp[-1].minor.yy322, yymsp[-9].minor.yy4, + &yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy4); +} +#line 3218 "parse.c" + break; + case 244: /* uniqueflag ::= UNIQUE */ + case 298: /* raisetype ::= ABORT */ yytestcase(yyruleno==298); +#line 1098 "parse.y" +{yygotominor.yy4 = OE_Abort;} +#line 3224 "parse.c" + break; + case 245: /* uniqueflag ::= */ +#line 1099 "parse.y" +{yygotominor.yy4 = OE_None;} +#line 3229 "parse.c" + break; + case 248: /* idxlist ::= idxlist COMMA nm collate sortorder */ +#line 1108 "parse.y" +{ + Expr *p = 0; + if( yymsp[-1].minor.yy0.n>0 ){ + p = sqlite3Expr(pParse->db, TK_COLUMN, 0); + sqlite3ExprSetCollByToken(pParse, p, &yymsp[-1].minor.yy0); + } + yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, p); + sqlite3ExprListSetName(pParse,yygotominor.yy322,&yymsp[-2].minor.yy0,1); + sqlite3ExprListCheckLength(pParse, yygotominor.yy322, "index"); + if( yygotominor.yy322 ) yygotominor.yy322->a[yygotominor.yy322->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy4; +} +#line 3244 "parse.c" + break; + case 249: /* idxlist ::= nm collate sortorder */ +#line 1119 "parse.y" +{ + Expr *p = 0; + if( yymsp[-1].minor.yy0.n>0 ){ + p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0); + sqlite3ExprSetCollByToken(pParse, p, &yymsp[-1].minor.yy0); + } + yygotominor.yy322 = sqlite3ExprListAppend(pParse,0, p); + sqlite3ExprListSetName(pParse, yygotominor.yy322, &yymsp[-2].minor.yy0, 1); + sqlite3ExprListCheckLength(pParse, yygotominor.yy322, "index"); + if( yygotominor.yy322 ) yygotominor.yy322->a[yygotominor.yy322->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy4; +} +#line 3259 "parse.c" + break; + case 250: /* collate ::= */ +#line 1132 "parse.y" +{yygotominor.yy0.z = 0; yygotominor.yy0.n = 0;} +#line 3264 "parse.c" + break; + case 252: /* cmd ::= DROP INDEX ifexists fullname */ +#line 1138 "parse.y" +{sqlite3DropIndex(pParse, yymsp[0].minor.yy259, yymsp[-1].minor.yy4);} +#line 3269 "parse.c" + break; + case 253: /* cmd ::= VACUUM */ + case 254: /* cmd ::= VACUUM nm */ yytestcase(yyruleno==254); +#line 1144 "parse.y" +{sqlite3Vacuum(pParse);} +#line 3275 "parse.c" + break; + case 255: /* cmd ::= PRAGMA nm dbnm */ +#line 1152 "parse.y" +{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} +#line 3280 "parse.c" + break; + case 256: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ +#line 1153 "parse.y" +{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);} +#line 3285 "parse.c" + break; + case 257: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ +#line 1154 "parse.y" +{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);} +#line 3290 "parse.c" + break; + case 258: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ +#line 1156 "parse.y" +{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);} +#line 3295 "parse.c" + break; + case 259: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ +#line 1158 "parse.y" +{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);} +#line 3300 "parse.c" + break; + case 270: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ +#line 1176 "parse.y" +{ + Token all; + all.z = yymsp[-3].minor.yy0.z; + all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n; + sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy203, &all); +} +#line 3310 "parse.c" + break; + case 271: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ +#line 1185 "parse.y" +{ + sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy4, yymsp[-4].minor.yy90.a, yymsp[-4].minor.yy90.b, yymsp[-2].minor.yy259, yymsp[0].minor.yy314, yymsp[-10].minor.yy4, yymsp[-8].minor.yy4); + yygotominor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); +} +#line 3318 "parse.c" + break; + case 272: /* trigger_time ::= BEFORE */ + case 275: /* trigger_time ::= */ yytestcase(yyruleno==275); +#line 1191 "parse.y" +{ yygotominor.yy4 = TK_BEFORE; } +#line 3324 "parse.c" + break; + case 273: /* trigger_time ::= AFTER */ +#line 1192 "parse.y" +{ yygotominor.yy4 = TK_AFTER; } +#line 3329 "parse.c" + break; + case 274: /* trigger_time ::= INSTEAD OF */ +#line 1193 "parse.y" +{ yygotominor.yy4 = TK_INSTEAD;} +#line 3334 "parse.c" + break; + case 276: /* trigger_event ::= DELETE|INSERT */ + case 277: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==277); +#line 1198 "parse.y" +{yygotominor.yy90.a = yymsp[0].major; yygotominor.yy90.b = 0;} +#line 3340 "parse.c" + break; + case 278: /* trigger_event ::= UPDATE OF inscollist */ +#line 1200 "parse.y" +{yygotominor.yy90.a = TK_UPDATE; yygotominor.yy90.b = yymsp[0].minor.yy384;} +#line 3345 "parse.c" + break; + case 281: /* when_clause ::= */ + case 303: /* key_opt ::= */ yytestcase(yyruleno==303); +#line 1207 "parse.y" +{ yygotominor.yy314 = 0; } +#line 3351 "parse.c" + break; + case 282: /* when_clause ::= WHEN expr */ + case 304: /* key_opt ::= KEY expr */ yytestcase(yyruleno==304); +#line 1208 "parse.y" +{ yygotominor.yy314 = yymsp[0].minor.yy118.pExpr; } +#line 3357 "parse.c" + break; + case 283: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ +#line 1212 "parse.y" +{ + assert( yymsp[-2].minor.yy203!=0 ); + yymsp[-2].minor.yy203->pLast->pNext = yymsp[-1].minor.yy203; + yymsp[-2].minor.yy203->pLast = yymsp[-1].minor.yy203; + yygotominor.yy203 = yymsp[-2].minor.yy203; +} +#line 3367 "parse.c" + break; + case 284: /* trigger_cmd_list ::= trigger_cmd SEMI */ +#line 1218 "parse.y" +{ + assert( yymsp[-1].minor.yy203!=0 ); + yymsp[-1].minor.yy203->pLast = yymsp[-1].minor.yy203; + yygotominor.yy203 = yymsp[-1].minor.yy203; +} +#line 3376 "parse.c" + break; + case 286: /* trnm ::= nm DOT nm */ +#line 1230 "parse.y" +{ + yygotominor.yy0 = yymsp[0].minor.yy0; + sqlite3ErrorMsg(pParse, + "qualified table names are not allowed on INSERT, UPDATE, and DELETE " + "statements within triggers"); +} +#line 3386 "parse.c" + break; + case 288: /* tridxby ::= INDEXED BY nm */ +#line 1242 "parse.y" +{ + sqlite3ErrorMsg(pParse, + "the INDEXED BY clause is not allowed on UPDATE or DELETE statements " + "within triggers"); +} +#line 3395 "parse.c" + break; + case 289: /* tridxby ::= NOT INDEXED */ +#line 1247 "parse.y" +{ + sqlite3ErrorMsg(pParse, + "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements " + "within triggers"); +} +#line 3404 "parse.c" + break; + case 290: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */ +#line 1260 "parse.y" +{ yygotominor.yy203 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy322, yymsp[0].minor.yy314, yymsp[-5].minor.yy210); } +#line 3409 "parse.c" + break; + case 291: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt VALUES LP itemlist RP */ +#line 1265 "parse.y" +{yygotominor.yy203 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy384, yymsp[-1].minor.yy322, 0, yymsp[-7].minor.yy210);} +#line 3414 "parse.c" + break; + case 292: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select */ +#line 1268 "parse.y" +{yygotominor.yy203 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy384, 0, yymsp[0].minor.yy387, yymsp[-4].minor.yy210);} +#line 3419 "parse.c" + break; + case 293: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */ +#line 1272 "parse.y" +{yygotominor.yy203 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy314);} +#line 3424 "parse.c" + break; + case 294: /* trigger_cmd ::= select */ +#line 1275 "parse.y" +{yygotominor.yy203 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy387); } +#line 3429 "parse.c" + break; + case 295: /* expr ::= RAISE LP IGNORE RP */ +#line 1278 "parse.y" +{ + yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0); + if( yygotominor.yy118.pExpr ){ + yygotominor.yy118.pExpr->affinity = OE_Ignore; + } + yygotominor.yy118.zStart = yymsp[-3].minor.yy0.z; + yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; +} +#line 3441 "parse.c" + break; + case 296: /* expr ::= RAISE LP raisetype COMMA nm RP */ +#line 1286 "parse.y" +{ + yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0); + if( yygotominor.yy118.pExpr ) { + yygotominor.yy118.pExpr->affinity = (char)yymsp[-3].minor.yy4; + } + yygotominor.yy118.zStart = yymsp[-5].minor.yy0.z; + yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; +} +#line 3453 "parse.c" + break; + case 297: /* raisetype ::= ROLLBACK */ +#line 1297 "parse.y" +{yygotominor.yy4 = OE_Rollback;} +#line 3458 "parse.c" + break; + case 299: /* raisetype ::= FAIL */ +#line 1299 "parse.y" +{yygotominor.yy4 = OE_Fail;} +#line 3463 "parse.c" + break; + case 300: /* cmd ::= DROP TRIGGER ifexists fullname */ +#line 1304 "parse.y" +{ + sqlite3DropTrigger(pParse,yymsp[0].minor.yy259,yymsp[-1].minor.yy4); +} +#line 3470 "parse.c" + break; + case 301: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ +#line 1311 "parse.y" +{ + sqlite3Attach(pParse, yymsp[-3].minor.yy118.pExpr, yymsp[-1].minor.yy118.pExpr, yymsp[0].minor.yy314); +} +#line 3477 "parse.c" + break; + case 302: /* cmd ::= DETACH database_kw_opt expr */ +#line 1314 "parse.y" +{ + sqlite3Detach(pParse, yymsp[0].minor.yy118.pExpr); +} +#line 3484 "parse.c" + break; + case 307: /* cmd ::= REINDEX */ +#line 1329 "parse.y" +{sqlite3Reindex(pParse, 0, 0);} +#line 3489 "parse.c" + break; + case 308: /* cmd ::= REINDEX nm dbnm */ +#line 1330 "parse.y" +{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} +#line 3494 "parse.c" + break; + case 309: /* cmd ::= ANALYZE */ +#line 1335 "parse.y" +{sqlite3Analyze(pParse, 0, 0);} +#line 3499 "parse.c" + break; + case 310: /* cmd ::= ANALYZE nm dbnm */ +#line 1336 "parse.y" +{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} +#line 3504 "parse.c" + break; + case 311: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ +#line 1341 "parse.y" +{ + sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy259,&yymsp[0].minor.yy0); +} +#line 3511 "parse.c" + break; + case 312: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */ +#line 1344 "parse.y" +{ + sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy0); +} +#line 3518 "parse.c" + break; + case 313: /* add_column_fullname ::= fullname */ +#line 1347 "parse.y" +{ + pParse->db->lookaside.bEnabled = 0; + sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy259); +} +#line 3526 "parse.c" + break; + case 316: /* cmd ::= create_vtab */ +#line 1357 "parse.y" +{sqlite3VtabFinishParse(pParse,0);} +#line 3531 "parse.c" + break; + case 317: /* cmd ::= create_vtab LP vtabarglist RP */ +#line 1358 "parse.y" +{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} +#line 3536 "parse.c" + break; + case 318: /* create_vtab ::= createkw VIRTUAL TABLE nm dbnm USING nm */ +#line 1359 "parse.y" +{ + sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); +} +#line 3543 "parse.c" + break; + case 321: /* vtabarg ::= */ +#line 1364 "parse.y" +{sqlite3VtabArgInit(pParse);} +#line 3548 "parse.c" + break; + case 323: /* vtabargtoken ::= ANY */ + case 324: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==324); + case 325: /* lp ::= LP */ yytestcase(yyruleno==325); +#line 1366 "parse.y" +{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} +#line 3555 "parse.c" + break; + default: + /* (0) input ::= cmdlist */ yytestcase(yyruleno==0); + /* (1) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==1); + /* (2) cmdlist ::= ecmd */ yytestcase(yyruleno==2); + /* (3) ecmd ::= SEMI */ yytestcase(yyruleno==3); + /* (4) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==4); + /* (10) trans_opt ::= */ yytestcase(yyruleno==10); + /* (11) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==11); + /* (12) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==12); + /* (20) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==20); + /* (21) savepoint_opt ::= */ yytestcase(yyruleno==21); + /* (25) cmd ::= create_table create_table_args */ yytestcase(yyruleno==25); + /* (34) columnlist ::= columnlist COMMA column */ yytestcase(yyruleno==34); + /* (35) columnlist ::= column */ yytestcase(yyruleno==35); + /* (44) type ::= */ yytestcase(yyruleno==44); + /* (51) signed ::= plus_num */ yytestcase(yyruleno==51); + /* (52) signed ::= minus_num */ yytestcase(yyruleno==52); + /* (53) carglist ::= carglist carg */ yytestcase(yyruleno==53); + /* (54) carglist ::= */ yytestcase(yyruleno==54); + /* (55) carg ::= CONSTRAINT nm ccons */ yytestcase(yyruleno==55); + /* (56) carg ::= ccons */ yytestcase(yyruleno==56); + /* (62) ccons ::= NULL onconf */ yytestcase(yyruleno==62); + /* (90) conslist ::= conslist COMMA tcons */ yytestcase(yyruleno==90); + /* (91) conslist ::= conslist tcons */ yytestcase(yyruleno==91); + /* (92) conslist ::= tcons */ yytestcase(yyruleno==92); + /* (93) tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==93); + /* (268) plus_opt ::= PLUS */ yytestcase(yyruleno==268); + /* (269) plus_opt ::= */ yytestcase(yyruleno==269); + /* (279) foreach_clause ::= */ yytestcase(yyruleno==279); + /* (280) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==280); + /* (287) tridxby ::= */ yytestcase(yyruleno==287); + /* (305) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==305); + /* (306) database_kw_opt ::= */ yytestcase(yyruleno==306); + /* (314) kwcolumn_opt ::= */ yytestcase(yyruleno==314); + /* (315) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==315); + /* (319) vtabarglist ::= vtabarg */ yytestcase(yyruleno==319); + /* (320) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==320); + /* (322) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==322); + /* (326) anylist ::= */ yytestcase(yyruleno==326); + /* (327) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==327); + /* (328) anylist ::= anylist ANY */ yytestcase(yyruleno==328); + break; + }; + yygoto = yyRuleInfo[yyruleno].lhs; + yysize = yyRuleInfo[yyruleno].nrhs; + yypParser->yyidx -= yysize; + yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto); + if( yyact < YYNSTATE ){ +#ifdef NDEBUG + /* If we are not debugging and the reduce action popped at least + ** one element off the stack, then we can push the new element back + ** onto the stack here, and skip the stack overflow test in yy_shift(). + ** That gives a significant speed improvement. */ + if( yysize ){ + yypParser->yyidx++; + yymsp -= yysize-1; + yymsp->stateno = (YYACTIONTYPE)yyact; + yymsp->major = (YYCODETYPE)yygoto; + yymsp->minor = yygotominor; + }else +#endif + { + yy_shift(yypParser,yyact,yygoto,&yygotominor); + } + }else{ + assert( yyact == YYNSTATE + YYNRULE + 1 ); + yy_accept(yypParser); + } +} + +/* +** The following code executes when the parse fails +*/ +#ifndef YYNOERRORRECOVERY +static void yy_parse_failed( + yyParser *yypParser /* The parser */ +){ + sqlite3ParserARG_FETCH; +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); + } +#endif + while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); + /* Here code is inserted which will be executed whenever the + ** parser fails */ + sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */ +} +#endif /* YYNOERRORRECOVERY */ + +/* +** The following code executes when a syntax error first occurs. +*/ +static void yy_syntax_error( + yyParser *yypParser, /* The parser */ + int yymajor, /* The major type of the error token */ + YYMINORTYPE yyminor /* The minor type of the error token */ +){ + sqlite3ParserARG_FETCH; +#define TOKEN (yyminor.yy0) +#line 32 "parse.y" + + UNUSED_PARAMETER(yymajor); /* Silence some compiler warnings */ + assert( TOKEN.z[0] ); /* The tokenizer always gives us a token */ + sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN); +#line 3662 "parse.c" + sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */ +} + +/* +** The following is executed when the parser accepts +*/ +static void yy_accept( + yyParser *yypParser /* The parser */ +){ + sqlite3ParserARG_FETCH; +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); + } +#endif + while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); + /* Here code is inserted which will be executed whenever the + ** parser accepts */ + sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */ +} + +/* The main parser program. +** The first argument is a pointer to a structure obtained from +** "sqlite3ParserAlloc" which describes the current state of the parser. +** The second argument is the major token number. The third is +** the minor token. The fourth optional argument is whatever the +** user wants (and specified in the grammar) and is available for +** use by the action routines. +** +** Inputs: +**
    +**
  • A pointer to the parser (an opaque structure.) +**
  • The major token number. +**
  • The minor token number. +**
  • An option argument of a grammar-specified type. +**
+** +** Outputs: +** None. +*/ +void sqlite3Parser( + void *yyp, /* The parser */ + int yymajor, /* The major token code number */ + sqlite3ParserTOKENTYPE yyminor /* The value for the token */ + sqlite3ParserARG_PDECL /* Optional %extra_argument parameter */ +){ + YYMINORTYPE yyminorunion; + int yyact; /* The parser action. */ +#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) + int yyendofinput; /* True if we are at the end of input */ +#endif +#ifdef YYERRORSYMBOL + int yyerrorhit = 0; /* True if yymajor has invoked an error */ +#endif + yyParser *yypParser; /* The parser */ + + /* (re)initialize the parser, if necessary */ + yypParser = (yyParser*)yyp; + if( yypParser->yyidx<0 ){ +#if YYSTACKDEPTH<=0 + if( yypParser->yystksz <=0 ){ + /*memset(&yyminorunion, 0, sizeof(yyminorunion));*/ + yyminorunion = yyzerominor; + yyStackOverflow(yypParser, &yyminorunion); + return; + } +#endif + yypParser->yyidx = 0; + yypParser->yyerrcnt = -1; + yypParser->yystack[0].stateno = 0; + yypParser->yystack[0].major = 0; + } + yyminorunion.yy0 = yyminor; +#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) + yyendofinput = (yymajor==0); +#endif + sqlite3ParserARG_STORE; + +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]); + } +#endif + + do{ + yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor); + if( yyactyyerrcnt--; + yymajor = YYNOCODE; + }else if( yyact < YYNSTATE + YYNRULE ){ + yy_reduce(yypParser,yyact-YYNSTATE); + }else{ + assert( yyact == YY_ERROR_ACTION ); +#ifdef YYERRORSYMBOL + int yymx; +#endif +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt); + } +#endif +#ifdef YYERRORSYMBOL + /* A syntax error has occurred. + ** The response to an error depends upon whether or not the + ** grammar defines an error token "ERROR". + ** + ** This is what we do if the grammar does define ERROR: + ** + ** * Call the %syntax_error function. + ** + ** * Begin popping the stack until we enter a state where + ** it is legal to shift the error symbol, then shift + ** the error symbol. + ** + ** * Set the error count to three. + ** + ** * Begin accepting and shifting new tokens. No new error + ** processing will occur until three tokens have been + ** shifted successfully. + ** + */ + if( yypParser->yyerrcnt<0 ){ + yy_syntax_error(yypParser,yymajor,yyminorunion); + } + yymx = yypParser->yystack[yypParser->yyidx].major; + if( yymx==YYERRORSYMBOL || yyerrorhit ){ +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sDiscard input token %s\n", + yyTracePrompt,yyTokenName[yymajor]); + } +#endif + yy_destructor(yypParser, (YYCODETYPE)yymajor,&yyminorunion); + yymajor = YYNOCODE; + }else{ + while( + yypParser->yyidx >= 0 && + yymx != YYERRORSYMBOL && + (yyact = yy_find_reduce_action( + yypParser->yystack[yypParser->yyidx].stateno, + YYERRORSYMBOL)) >= YYNSTATE + ){ + yy_pop_parser_stack(yypParser); + } + if( yypParser->yyidx < 0 || yymajor==0 ){ + yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); + yy_parse_failed(yypParser); + yymajor = YYNOCODE; + }else if( yymx!=YYERRORSYMBOL ){ + YYMINORTYPE u2; + u2.YYERRSYMDT = 0; + yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2); + } + } + yypParser->yyerrcnt = 3; + yyerrorhit = 1; +#elif defined(YYNOERRORRECOVERY) + /* If the YYNOERRORRECOVERY macro is defined, then do not attempt to + ** do any kind of error recovery. Instead, simply invoke the syntax + ** error routine and continue going as if nothing had happened. + ** + ** Applications can set this macro (for example inside %include) if + ** they intend to abandon the parse upon the first syntax error seen. + */ + yy_syntax_error(yypParser,yymajor,yyminorunion); + yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); + yymajor = YYNOCODE; + +#else /* YYERRORSYMBOL is not defined */ + /* This is what we do if the grammar does not define ERROR: + ** + ** * Report an error message, and throw away the input token. + ** + ** * If the input token is $, then fail the parse. + ** + ** As before, subsequent error messages are suppressed until + ** three input tokens have been successfully shifted. + */ + if( yypParser->yyerrcnt<=0 ){ + yy_syntax_error(yypParser,yymajor,yyminorunion); + } + yypParser->yyerrcnt = 3; + yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); + if( yyendofinput ){ + yy_parse_failed(yypParser); + } + yymajor = YYNOCODE; +#endif + } + }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 ); + return; +} diff --git a/scalos/libraries/sqlite/parse.h b/scalos/libraries/sqlite/parse.h new file mode 100644 index 000000000..536f63286 --- /dev/null +++ b/scalos/libraries/sqlite/parse.h @@ -0,0 +1,157 @@ +#define TK_SEMI 1 +#define TK_EXPLAIN 2 +#define TK_QUERY 3 +#define TK_PLAN 4 +#define TK_BEGIN 5 +#define TK_TRANSACTION 6 +#define TK_DEFERRED 7 +#define TK_IMMEDIATE 8 +#define TK_EXCLUSIVE 9 +#define TK_COMMIT 10 +#define TK_END 11 +#define TK_ROLLBACK 12 +#define TK_SAVEPOINT 13 +#define TK_RELEASE 14 +#define TK_TO 15 +#define TK_TABLE 16 +#define TK_CREATE 17 +#define TK_IF 18 +#define TK_NOT 19 +#define TK_EXISTS 20 +#define TK_TEMP 21 +#define TK_LP 22 +#define TK_RP 23 +#define TK_AS 24 +#define TK_COMMA 25 +#define TK_ID 26 +#define TK_INDEXED 27 +#define TK_ABORT 28 +#define TK_ACTION 29 +#define TK_AFTER 30 +#define TK_ANALYZE 31 +#define TK_ASC 32 +#define TK_ATTACH 33 +#define TK_BEFORE 34 +#define TK_BY 35 +#define TK_CASCADE 36 +#define TK_CAST 37 +#define TK_COLUMNKW 38 +#define TK_CONFLICT 39 +#define TK_DATABASE 40 +#define TK_DESC 41 +#define TK_DETACH 42 +#define TK_EACH 43 +#define TK_FAIL 44 +#define TK_FOR 45 +#define TK_IGNORE 46 +#define TK_INITIALLY 47 +#define TK_INSTEAD 48 +#define TK_LIKE_KW 49 +#define TK_MATCH 50 +#define TK_NO 51 +#define TK_KEY 52 +#define TK_OF 53 +#define TK_OFFSET 54 +#define TK_PRAGMA 55 +#define TK_RAISE 56 +#define TK_REPLACE 57 +#define TK_RESTRICT 58 +#define TK_ROW 59 +#define TK_TRIGGER 60 +#define TK_VACUUM 61 +#define TK_VIEW 62 +#define TK_VIRTUAL 63 +#define TK_REINDEX 64 +#define TK_RENAME 65 +#define TK_CTIME_KW 66 +#define TK_ANY 67 +#define TK_OR 68 +#define TK_AND 69 +#define TK_IS 70 +#define TK_BETWEEN 71 +#define TK_IN 72 +#define TK_ISNULL 73 +#define TK_NOTNULL 74 +#define TK_NE 75 +#define TK_EQ 76 +#define TK_GT 77 +#define TK_LE 78 +#define TK_LT 79 +#define TK_GE 80 +#define TK_ESCAPE 81 +#define TK_BITAND 82 +#define TK_BITOR 83 +#define TK_LSHIFT 84 +#define TK_RSHIFT 85 +#define TK_PLUS 86 +#define TK_MINUS 87 +#define TK_STAR 88 +#define TK_SLASH 89 +#define TK_REM 90 +#define TK_CONCAT 91 +#define TK_COLLATE 92 +#define TK_BITNOT 93 +#define TK_STRING 94 +#define TK_JOIN_KW 95 +#define TK_CONSTRAINT 96 +#define TK_DEFAULT 97 +#define TK_NULL 98 +#define TK_PRIMARY 99 +#define TK_UNIQUE 100 +#define TK_CHECK 101 +#define TK_REFERENCES 102 +#define TK_AUTOINCR 103 +#define TK_ON 104 +#define TK_INSERT 105 +#define TK_DELETE 106 +#define TK_UPDATE 107 +#define TK_SET 108 +#define TK_DEFERRABLE 109 +#define TK_FOREIGN 110 +#define TK_DROP 111 +#define TK_UNION 112 +#define TK_ALL 113 +#define TK_EXCEPT 114 +#define TK_INTERSECT 115 +#define TK_SELECT 116 +#define TK_DISTINCT 117 +#define TK_DOT 118 +#define TK_FROM 119 +#define TK_JOIN 120 +#define TK_USING 121 +#define TK_ORDER 122 +#define TK_GROUP 123 +#define TK_HAVING 124 +#define TK_LIMIT 125 +#define TK_WHERE 126 +#define TK_INTO 127 +#define TK_VALUES 128 +#define TK_INTEGER 129 +#define TK_FLOAT 130 +#define TK_BLOB 131 +#define TK_REGISTER 132 +#define TK_VARIABLE 133 +#define TK_CASE 134 +#define TK_WHEN 135 +#define TK_THEN 136 +#define TK_ELSE 137 +#define TK_INDEX 138 +#define TK_ALTER 139 +#define TK_ADD 140 +#define TK_TO_TEXT 141 +#define TK_TO_BLOB 142 +#define TK_TO_NUMERIC 143 +#define TK_TO_INT 144 +#define TK_TO_REAL 145 +#define TK_ISNOT 146 +#define TK_END_OF_FILE 147 +#define TK_ILLEGAL 148 +#define TK_SPACE 149 +#define TK_UNCLOSED_STRING 150 +#define TK_FUNCTION 151 +#define TK_COLUMN 152 +#define TK_AGG_FUNCTION 153 +#define TK_AGG_COLUMN 154 +#define TK_CONST_FUNC 155 +#define TK_UMINUS 156 +#define TK_UPLUS 157 diff --git a/scalos/libraries/sqlite/sqlite3-aos4-68kstubs.c b/scalos/libraries/sqlite/sqlite3-aos4-68kstubs.c new file mode 100644 index 000000000..05e235072 --- /dev/null +++ b/scalos/libraries/sqlite/sqlite3-aos4-68kstubs.c @@ -0,0 +1,1034 @@ +/* +** This file was automatically generated by fdtrans 52.1. +** Do not edit it by hand. Instead, edit the sfd file +** that was used to generate this file +*/ + +#ifdef __USE_INLINE__ +#undef __USE_INLINE__ +#endif +#ifndef __NOGLOBALIFACE__ +#define __NOGLOBALIFACE__ +#endif + +#include +#include +#include +#include +#include +#include + + +static inline int8 convert_int8 (uint32 x) { return x; } +static inline int16 convert_int16(uint32 x) { return x; } + + +STATIC struct Library * stub_OpenPPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct LibraryManagerInterface *Self = (struct LibraryManagerInterface *) ExtLib->ILibrary; + + return Self->Open(0); +} +STATIC CONST struct EmuTrap stub_Open = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_OpenPPC }; + +STATIC APTR stub_ClosePPC(ULONG *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)Base + Base->lib_PosSize); + struct LibraryManagerInterface *Self = (struct LibraryManagerInterface *) ExtLib->ILibrary; + + return Self->Close(); +} +STATIC CONST struct EmuTrap stub_Close = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_ClosePPC }; + +STATIC APTR stub_ExpungePPC(ULONG *regarray __attribute__((unused))) +{ + return NULL; +} +STATIC CONST struct EmuTrap stub_Expunge = { TRAPINST, TRAPTYPE, (ULONG (*)(ULONG *))stub_ExpungePPC }; + +STATIC ULONG stub_ReservedPPC(ULONG *regarray __attribute__((unused))) +{ + return 0UL; +} +STATIC CONST struct EmuTrap stub_Reserved = { TRAPINST, TRAPTYPE, stub_ReservedPPC }; + +static LONG stub_SQLite3ClosePPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3Close( + (sqlite3 *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3Close = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3ClosePPC }; + +static LONG stub_SQLite3ExecPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3Exec( + (sqlite3 *)regarray[8], + (CONST_STRPTR)regarray[9], + (sqlite3_callback)regarray[10], + (APTR)regarray[11], + (STRPTR *)regarray[0] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3Exec = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3ExecPPC }; + +static LONG stub_SQLite3ChangesPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3Changes( + (sqlite3 *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3Changes = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3ChangesPPC }; + +static LONG stub_SQLite3TotalChangesPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3TotalChanges( + (sqlite3 *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3TotalChanges = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3TotalChangesPPC }; + +static VOID stub_SQLite3InterruptPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + Self->SQLite3Interrupt( + (sqlite3 *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3Interrupt = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_SQLite3InterruptPPC }; + +static LONG stub_SQLite3CompletePPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3Complete( + (CONST_STRPTR)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3Complete = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3CompletePPC }; + +static LONG stub_SQLite3BusyHandlerPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3BusyHandler( + (sqlite3 *)regarray[8], + (LONG (*)(APTR userdata, LONG l))regarray[9], + (APTR)regarray[10] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3BusyHandler = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3BusyHandlerPPC }; + +static LONG stub_SQLite3BusyTimeoutPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3BusyTimeout( + (sqlite3 *)regarray[8], + (LONG)regarray[0] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3BusyTimeout = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3BusyTimeoutPPC }; + +static LONG stub_SQLite3GetTablePPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3GetTable( + (sqlite3 *)regarray[8], + (CONST_STRPTR)regarray[9], + (STRPTR **)regarray[10], + (LONG *)regarray[11], + (LONG *)regarray[0], + (STRPTR *)regarray[1] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3GetTable = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3GetTablePPC }; + +static VOID stub_SQLite3FreeTablePPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + Self->SQLite3FreeTable( + (STRPTR *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3FreeTable = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_SQLite3FreeTablePPC }; + +static VOID stub_SQLite3FreePPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + Self->SQLite3Free( + (STRPTR)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3Free = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_SQLite3FreePPC }; + +static APTR stub_SQLite3TracePPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3Trace( + (sqlite3 *)regarray[8], + (VOID (*)(APTR p, CONST_STRPTR z))regarray[9], + (APTR)regarray[10] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3Trace = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3TracePPC }; + +static VOID stub_SQLite3ProgressHandlerPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + Self->SQLite3ProgressHandler( + (sqlite3 *)regarray[8], + (LONG)regarray[0], + (LONG (*)(APTR p))regarray[9], + (APTR)regarray[10] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3ProgressHandler = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_SQLite3ProgressHandlerPPC }; + +static APTR stub_SQLite3CommitHookPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3CommitHook( + (sqlite3 *)regarray[8], + (LONG (*)(APTR p))regarray[9], + (APTR)regarray[10] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3CommitHook = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3CommitHookPPC }; + +static LONG stub_SQLite3OpenPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3Open( + (CONST_STRPTR)regarray[8], + (sqlite3 **)regarray[9] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3Open = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3OpenPPC }; + +static LONG stub_SQLite3ErrcodePPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3Errcode( + (sqlite3 *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3Errcode = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3ErrcodePPC }; + +static CONST_STRPTR stub_SQLite3ErrmsgPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3Errmsg( + (sqlite3 *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3Errmsg = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3ErrmsgPPC }; + +static LONG stub_SQLite3PreparePPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3Prepare( + (sqlite3 *)regarray[8], + (CONST_STRPTR)regarray[9], + (LONG)regarray[0], + (sqlite3_stmt **)regarray[10], + (CONST_STRPTR *)regarray[11] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3Prepare = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3PreparePPC }; + +static LONG stub_SQLite3BindBlobPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3BindBlob( + (sqlite3_stmt *)regarray[8], + (LONG)regarray[0], + (CONST_APTR)regarray[9], + (LONG)regarray[1], + (VOID (*)(APTR p))regarray[10] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3BindBlob = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3BindBlobPPC }; + +static LONG stub_SQLite3BindIntPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3BindInt( + (sqlite3_stmt *)regarray[8], + (LONG)regarray[0], + (LONG)regarray[1] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3BindInt = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3BindIntPPC }; + +static LONG stub_SQLite3BindNullPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3BindNull( + (sqlite3_stmt *)regarray[8], + (LONG)regarray[0] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3BindNull = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3BindNullPPC }; + +static LONG stub_SQLite3BindTextPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3BindText( + (sqlite3_stmt *)regarray[8], + (LONG)regarray[0], + (CONST_STRPTR)regarray[9], + (LONG)regarray[1], + (VOID (*)(APTR p))regarray[10] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3BindText = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3BindTextPPC }; + +static LONG stub_SQLite3BindValuePPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3BindValue( + (sqlite3_stmt *)regarray[8], + (LONG)regarray[0], + (CONST sqlite3_value *)regarray[9] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3BindValue = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3BindValuePPC }; + +static LONG stub_SQLite3BindParameterCountPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3BindParameterCount( + (sqlite3_stmt *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3BindParameterCount = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3BindParameterCountPPC }; + +static CONST_STRPTR stub_SQLite3BindParameterNamePPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3BindParameterName( + (sqlite3_stmt *)regarray[8], + (LONG)regarray[0] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3BindParameterName = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3BindParameterNamePPC }; + +static LONG stub_SQLite3BindParameterIndexPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3BindParameterIndex( + (sqlite3_stmt *)regarray[8], + (CONST_STRPTR)regarray[9] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3BindParameterIndex = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3BindParameterIndexPPC }; + +static LONG stub_SQLite3ClearBindingsPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3ClearBindings( + (sqlite3_stmt *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3ClearBindings = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3ClearBindingsPPC }; + +static LONG stub_SQLite3ColumnCountPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3ColumnCount( + (sqlite3_stmt *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3ColumnCount = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3ColumnCountPPC }; + +static CONST_STRPTR stub_SQLite3ColumnNamePPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3ColumnName( + (sqlite3_stmt *)regarray[8], + (LONG)regarray[0] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3ColumnName = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3ColumnNamePPC }; + +static CONST_STRPTR stub_SQLite3ColumnDecltypePPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3ColumnDecltype( + (sqlite3_stmt *)regarray[8], + (LONG)regarray[0] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3ColumnDecltype = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3ColumnDecltypePPC }; + +static LONG stub_SQLite3StepPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3Step( + (sqlite3_stmt *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3Step = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3StepPPC }; + +static LONG stub_SQLite3DataCountPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3DataCount( + (sqlite3_stmt *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3DataCount = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3DataCountPPC }; + +static CONST_APTR stub_SQLite3ColumnBlobPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3ColumnBlob( + (sqlite3_stmt *)regarray[8], + (LONG)regarray[0] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3ColumnBlob = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3ColumnBlobPPC }; + +static LONG stub_SQLite3ColumnBytesPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3ColumnBytes( + (sqlite3_stmt *)regarray[8], + (LONG)regarray[0] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3ColumnBytes = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3ColumnBytesPPC }; + +static LONG stub_SQLite3ColumnIntPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3ColumnInt( + (sqlite3_stmt *)regarray[8], + (LONG)regarray[0] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3ColumnInt = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3ColumnIntPPC }; + +static CONST_STRPTR stub_SQLite3ColumnTextPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3ColumnText( + (sqlite3_stmt *)regarray[8], + (LONG)regarray[0] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3ColumnText = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3ColumnTextPPC }; + +static LONG stub_SQLite3ColumnTypePPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3ColumnType( + (sqlite3_stmt *)regarray[8], + (LONG)regarray[0] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3ColumnType = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3ColumnTypePPC }; + +static LONG stub_SQLite3FinalizePPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3Finalize( + (sqlite3_stmt *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3Finalize = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3FinalizePPC }; + +static LONG stub_SQLite3ResetPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3Reset( + (sqlite3_stmt *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3Reset = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3ResetPPC }; + +static LONG stub_SQLite3AggregateCountPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3AggregateCount( + (sqlite3_context *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3AggregateCount = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3AggregateCountPPC }; + +static CONST_APTR stub_SQLite3ValueBlobPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3ValueBlob( + (sqlite3_value *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3ValueBlob = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3ValueBlobPPC }; + +static LONG stub_SQLite3ValueBytesPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3ValueBytes( + (sqlite3_value *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3ValueBytes = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3ValueBytesPPC }; + +static LONG stub_SQLite3ValueIntPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3ValueInt( + (sqlite3_value *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3ValueInt = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3ValueIntPPC }; + +static CONST_STRPTR stub_SQLite3ValueTextPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3ValueText( + (sqlite3_value *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3ValueText = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3ValueTextPPC }; + +static LONG stub_SQLite3ValueTypePPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3ValueType( + (sqlite3_value *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3ValueType = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3ValueTypePPC }; + +static APTR stub_SQLite3Aggregate_contextPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3Aggregate_context( + (sqlite3_context *)regarray[8], + (LONG)regarray[0] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3Aggregate_context = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3Aggregate_contextPPC }; + +static APTR stub_SQLite3UserDataPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3UserData( + (sqlite3_context *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3UserData = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3UserDataPPC }; + +static APTR stub_SQLite3GetAuxdataPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3GetAuxdata( + (sqlite3_context *)regarray[8], + (LONG)regarray[0] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3GetAuxdata = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3GetAuxdataPPC }; + +static VOID stub_SQLite3SetAuxdataPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + Self->SQLite3SetAuxdata( + (sqlite3_context *)regarray[8], + (LONG)regarray[0], + (APTR)regarray[9], + (VOID (*)(APTR p))regarray[10] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3SetAuxdata = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_SQLite3SetAuxdataPPC }; + +static VOID stub_SQLite3ResultBlobPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + Self->SQLite3ResultBlob( + (sqlite3_context *)regarray[8], + (CONST_APTR)regarray[9], + (LONG)regarray[0], + (VOID (*)(APTR p))regarray[10] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3ResultBlob = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_SQLite3ResultBlobPPC }; + +static VOID stub_SQLite3ResultErrorPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + Self->SQLite3ResultError( + (sqlite3_context *)regarray[8], + (CONST_STRPTR)regarray[9], + (LONG)regarray[0] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3ResultError = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_SQLite3ResultErrorPPC }; + +static VOID stub_SQLite3ResultIntPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + Self->SQLite3ResultInt( + (sqlite3_context *)regarray[8], + (LONG)regarray[0] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3ResultInt = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_SQLite3ResultIntPPC }; + +static VOID stub_SQLite3ResultNullPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + Self->SQLite3ResultNull( + (sqlite3_context *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3ResultNull = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_SQLite3ResultNullPPC }; + +static VOID stub_SQLite3ResultTextPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + Self->SQLite3ResultText( + (sqlite3_context *)regarray[8], + (CONST_STRPTR)regarray[9], + (LONG)regarray[0], + (VOID (*)(APTR p))regarray[10] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3ResultText = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_SQLite3ResultTextPPC }; + +static VOID stub_SQLite3ResultValuePPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + Self->SQLite3ResultValue( + (sqlite3_context *)regarray[8], + (sqlite3_value *)regarray[9] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3ResultValue = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_SQLite3ResultValuePPC }; + +static LONG stub_SQLite3CreateCollationPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3CreateCollation( + (sqlite3 *)regarray[8], + (CONST_STRPTR)regarray[9], + (LONG)regarray[0], + (APTR)regarray[10], + (LONG (*)(APTR p, LONG i, CONST_APTR p2, LONG j, CONST_APTR p3))regarray[11] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3CreateCollation = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3CreateCollationPPC }; + +static LONG stub_SQLite3CollationNeededPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3CollationNeeded( + (sqlite3 *)regarray[8], + (APTR)regarray[0], + (VOID (*)(APTR p, sqlite3 *dv, LONG eTextRep, CONST_STRPTR z))regarray[9] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3CollationNeeded = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3CollationNeededPPC }; + +static LONG stub_SQLite3SleepPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3Sleep( + (LONG)regarray[0] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3Sleep = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3SleepPPC }; + +static LONG stub_SQLite3ExpiredPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3Expired( + (sqlite3_stmt *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3Expired = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3ExpiredPPC }; + +static LONG stub_SQLite3TransferBindingsPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3TransferBindings( + (sqlite3_stmt *)regarray[8], + (sqlite3_stmt *)regarray[9] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3TransferBindings = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3TransferBindingsPPC }; + +static LONG stub_SQLite3GlobalRecoverPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3GlobalRecover( + ); +} +STATIC CONST struct EmuTrap stub_SQLite3GlobalRecover = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3GlobalRecoverPPC }; + +static LONG stub_SQLite3GetAutocommitPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3GetAutocommit( + (sqlite3 *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3GetAutocommit = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3GetAutocommitPPC }; + +static sqlite3 * stub_SQLite3DbHandlePPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3DbHandle( + (sqlite3_stmt *)regarray[8] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3DbHandle = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3DbHandlePPC }; + +static APTR stub_SQLite3RollbackHookPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3RollbackHook( + (sqlite3 *)regarray[8], + (VOID (*)(APTR pUserData))regarray[9], + (APTR)regarray[10] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3RollbackHook = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3RollbackHookPPC }; + +static LONG stub_SQLite3EnableSharedCachePPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3EnableSharedCache( + (BOOL)convert_int16(regarray[0]) + ); +} +STATIC CONST struct EmuTrap stub_SQLite3EnableSharedCache = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3EnableSharedCachePPC }; + +static LONG stub_SQLite3ReleaseMemoryPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3ReleaseMemory( + (LONG)regarray[0] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3ReleaseMemory = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3ReleaseMemoryPPC }; + +static VOID stub_SQLite3SoftHeapLimitPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + Self->SQLite3SoftHeapLimit( + (LONG)regarray[0] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3SoftHeapLimit = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_SQLite3SoftHeapLimitPPC }; + +static VOID stub_SQLite3ThreadCleanupPPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + Self->SQLite3ThreadCleanup( + ); +} +STATIC CONST struct EmuTrap stub_SQLite3ThreadCleanup = { TRAPINST, TRAPTYPENR, (uint32 (*)(uint32 *))stub_SQLite3ThreadCleanupPPC }; + +static LONG stub_SQLite3PrepareV2PPC(uint32 *regarray) +{ + struct Library *Base = (struct Library *) regarray[REG68K_A6/4]; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize); + struct SQLite3IFace *Self = (struct SQLite3IFace *) ExtLib->MainIFace; + + return Self->SQLite3PrepareV2( + (sqlite3 *)regarray[8], + (CONST_STRPTR)regarray[9], + (LONG)regarray[0], + (sqlite3_stmt **)regarray[10], + (CONST_STRPTR *)regarray[11] + ); +} +STATIC CONST struct EmuTrap stub_SQLite3PrepareV2 = { TRAPINST, TRAPTYPE, (uint32 (*)(uint32 *))stub_SQLite3PrepareV2PPC }; + +CONST CONST_APTR VecTable68K[] = +{ + &stub_Open, + &stub_Close, + &stub_Expunge, + &stub_Reserved, + &stub_SQLite3Close, + &stub_SQLite3Exec, + &stub_SQLite3Changes, + &stub_SQLite3TotalChanges, + &stub_SQLite3Interrupt, + &stub_SQLite3Complete, + &stub_SQLite3BusyHandler, + &stub_SQLite3BusyTimeout, + &stub_SQLite3GetTable, + &stub_SQLite3FreeTable, + &stub_SQLite3Free, + &stub_SQLite3Trace, + &stub_SQLite3ProgressHandler, + &stub_SQLite3CommitHook, + &stub_SQLite3Open, + &stub_SQLite3Errcode, + &stub_SQLite3Errmsg, + &stub_SQLite3Prepare, + &stub_SQLite3BindBlob, + &stub_SQLite3BindInt, + &stub_SQLite3BindNull, + &stub_SQLite3BindText, + &stub_SQLite3BindValue, + &stub_SQLite3BindParameterCount, + &stub_SQLite3BindParameterName, + &stub_SQLite3BindParameterIndex, + &stub_SQLite3ClearBindings, + &stub_SQLite3ColumnCount, + &stub_SQLite3ColumnName, + &stub_SQLite3ColumnDecltype, + &stub_SQLite3Step, + &stub_SQLite3DataCount, + &stub_SQLite3ColumnBlob, + &stub_SQLite3ColumnBytes, + &stub_SQLite3ColumnInt, + &stub_SQLite3ColumnText, + &stub_SQLite3ColumnType, + &stub_SQLite3Finalize, + &stub_SQLite3Reset, + &stub_SQLite3AggregateCount, + &stub_SQLite3ValueBlob, + &stub_SQLite3ValueBytes, + &stub_SQLite3ValueInt, + &stub_SQLite3ValueText, + &stub_SQLite3ValueType, + &stub_SQLite3Aggregate_context, + &stub_SQLite3UserData, + &stub_SQLite3GetAuxdata, + &stub_SQLite3SetAuxdata, + &stub_SQLite3ResultBlob, + &stub_SQLite3ResultError, + &stub_SQLite3ResultInt, + &stub_SQLite3ResultNull, + &stub_SQLite3ResultText, + &stub_SQLite3ResultValue, + &stub_SQLite3CreateCollation, + &stub_SQLite3CollationNeeded, + &stub_SQLite3Sleep, + &stub_SQLite3Expired, + &stub_SQLite3TransferBindings, + &stub_SQLite3GlobalRecover, + &stub_SQLite3GetAutocommit, + &stub_SQLite3DbHandle, + &stub_SQLite3RollbackHook, + &stub_SQLite3EnableSharedCache, + &stub_SQLite3ReleaseMemory, + &stub_SQLite3SoftHeapLimit, + &stub_SQLite3ThreadCleanup, + &stub_SQLite3PrepareV2, + (CONST_APTR)-1 +}; diff --git a/scalos/libraries/sqlite/sqlite3-aos4.c b/scalos/libraries/sqlite/sqlite3-aos4.c new file mode 100644 index 000000000..427a095fb --- /dev/null +++ b/scalos/libraries/sqlite/sqlite3-aos4.c @@ -0,0 +1,305 @@ +// Preferences-aos4.c +// $Date$ +// $Revision$ + + +#include +#include +#include +#include + +#include +#include + +#include + +#include "sqlite3_base.h" +#include "LibSQLite3.h" +#include "sqlite3.h" + +#include + +int _start(void) +{ + return -1; +} + +extern CONST_APTR VecTable68K[]; + +static struct Library *Initlib(struct Library *libbase, BPTR seglist, struct ExecIFace *pIExec); +static BPTR Expungelib(struct LibraryManagerInterface *Self); +static struct LibraryHeader *Openlib(struct LibraryManagerInterface *Self, ULONG version); +static BPTR Closelib(struct LibraryManagerInterface *Self); +static ULONG Obtainlib(struct LibraryManagerInterface *Self); +static ULONG Releaselib(struct LibraryManagerInterface *Self); + +/* OS4.0 Library */ + +/* ------------------- OS4 Manager Interface ------------------------ */ +static const APTR managerfunctable[] = +{ + (APTR)Obtainlib, + (APTR)Releaselib, + (APTR)NULL, + (APTR)NULL, + (APTR)Openlib, + (APTR)Closelib, + (APTR)Expungelib, + (APTR)NULL, + (APTR)-1 +}; + +static const struct TagItem managertags[] = +{ + {MIT_Name, (ULONG)"__library"}, + {MIT_VectorTable, (ULONG)managerfunctable}, + {MIT_Version, 1}, + {TAG_DONE, 0} +}; + +/* ---------------------- OS4 Main Interface ------------------------ */ +static APTR functable[] = + { + Obtainlib, + Releaselib, + NULL, + NULL, + LIBSQLite3Close, + LIBSQLite3Exec, + LIBSQLite3Changes, + LIBSQLite3TotalChanges, + LIBSQLite3Interrupt, + LIBSQLite3Complete, + LIBSQLite3BusyHandler, + LIBSQLite3BusyTimeout, + LIBSQLite3GetTable, + LIBSQLite3FreeTable, + LIBSQLite3Free, + LIBSQLite3Trace, + LIBSQLite3ProgressHandler, + LIBSQLite3CommitHook, + LIBSQLite3Open, + LIBSQLite3Errcode, + LIBSQLite3Errmsg, + LIBSQLite3Prepare, + LIBSQLite3BindBlob, + LIBSQLite3BindInt, + LIBSQLite3BindNull, + LIBSQLite3BindText, + LIBSQLite3BindValue, + LIBSQLite3BindParameterCount, + LIBSQLite3BindParameterName, + LIBSQLite3BindParameterIndex, + LIBSQLite3ClearBindings, + LIBSQLite3ColumnCount, + LIBSQLite3ColumnName, + LIBSQLite3ColumnDecltype, + LIBSQLite3Step, + LIBSQLite3DataCount, + LIBSQLite3ColumnBlob, + LIBSQLite3ColumnBytes, + LIBSQLite3ColumnInt, + LIBSQLite3ColumnText, + LIBSQLite3ColumnType, + LIBSQLite3Finalize, + LIBSQLite3Reset, + LIBSQLite3AggregateCount, + LIBSQLite3ValueBlob, + LIBSQLite3ValueBytes, + LIBSQLite3ValueInt, + LIBSQLite3ValueText, + LIBSQLite3ValueType, + LIBSQLite3Aggregate_context, + LIBSQLite3UserData, + LIBSQLite3GetAuxdata, + LIBSQLite3SetAuxdata, + LIBSQLite3ResultBlob, + LIBSQLite3ResultError, + LIBSQLite3ResultInt, + LIBSQLite3ResultNull, + LIBSQLite3ResultText, + LIBSQLite3ResultValue, + LIBSQLite3CreateCollation, + LIBSQLite3CollationNeeded, + LIBSQLite3Sleep, + LIBSQLite3Expired, + LIBSQLite3TransferBindings, + LIBSQLite3GlobalRecover, + LIBSQLite3GetAutocommit, + LIBSQLite3DbHandle, + + // new functions in V41 + LIBSQLite3RollbackHook, + LIBSQLite3EnableSharedCache, + LIBSQLite3ReleaseMemory, + LIBSQLite3SoftHeapLimit, + LIBSQLite3ThreadCleanup, + + // new function in V42 + LIBSQLite3PrepareV2, + + // new function in V43 + LIBSQLite3CreateFunction, + LIBSQLite3CreateModule, + LIBSQLite3DeclareVtab, + LIBSQLite3OverloadFunction, + LIBSQLite3BlobOpen, + LIBSQLite3BlobClose, + LIBSQLite3BlobBytes, + LIBSQLite3BlobRead, + LIBSQLite3BlobWrite, + LIBSQLite3ExtendedResultCodes, + LIBSQLite3BindZeroBlob, + LIBSQLite3ColumnDatabaseName, + LIBSQLite3ColumnTableName, + LIBSQLite3ColumnOriginName, + LIBSQLite3ColumnValue, + LIBSQLite3CreateCollationV2, + LIBSQLite3LibVersion, + LIBSQLite3LibversionNumber, + LIBSQLite3ResultErrorToobig, + LIBSQLite3ResultZeroBlob, + LIBSQLite3ValueNumericType, + + // new function in V44 + LIBSQLite3ConfigV, + LIBSQLlite3DbConfigV, + LIBSQLite3VfsFind, + LIBSQLite3VfsRegister, + LIBSQLite3VfsUnregister, + LIBSQLite3FileControl, + LIBSQLite3Status, + LIBSQLite3DbStatus, + + (APTR) -1 + }; + +static const struct TagItem maintags[] = + { + {MIT_Name, (ULONG)"main"}, + {MIT_VectorTable, (ULONG)functable}, + {MIT_Version, 1}, + {TAG_DONE, 0} + }; + +/* Init table used in library initialization. */ +static const ULONG interfaces[] = +{ + (ULONG)managertags, + (ULONG)maintags, + (ULONG)0 +}; + +static const struct TagItem inittab[] = + { + {CLT_DataSize, (ULONG)sizeof(struct SQLite3Base)}, + {CLT_Interfaces, (ULONG) interfaces}, + {CLT_Vector68K, (ULONG)VecTable68K}, + {CLT_InitFunc, (ULONG) Initlib}, + {TAG_DONE, 0} + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, + RTF_NATIVE | RTF_AUTOINIT, + LIB_VERSION, + NT_LIBRARY, + 0, + libName, + libIdString, + inittab + }; + +/* ------------------- OS4 Manager Functions ------------------------ */ +static struct Library * Initlib(struct Library *libbase, BPTR seglist, struct ExecIFace *pIExec) +{ + struct SQLite3Base *SQLite3LibBase = (struct SQLite3Base *) libbase; + struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((ULONG)libbase + libbase->lib_PosSize); + struct LibraryManagerInterface *Self = (struct LibraryManagerInterface *) ExtLib->ILibrary; + + SysBase = (struct ExecBase *)pIExec->Data.LibBase; + IExec = pIExec; + SQLite3LibBase->sql3_LibNode.lib_Revision = LIB_REVISION; + SQLite3LibBase->sql3_SegList = (struct SegList *)seglist; + + if (!SQLite3Init(SQLite3LibBase)) + { + Expungelib(Self); + SQLite3LibBase = NULL; + } + + return SQLite3LibBase ? &SQLite3LibBase->sql3_LibNode : NULL; +} + +static BPTR Expungelib(struct LibraryManagerInterface *Self) +{ + struct SQLite3Base *SQLite3LibBase = (struct SQLite3Base *) Self->Data.LibBase; + + if (0 == SQLite3LibBase->sql3_LibNode.lib_OpenCnt) + { + struct SegList *libseglist = SQLite3LibBase->sql3_SegList; + + Remove((struct Node *) SQLite3LibBase); + SQLite3Cleanup(SQLite3LibBase); + DeleteLibrary((struct Library *)SQLite3LibBase); + + return (BPTR)libseglist; + } + + SQLite3LibBase->sql3_LibNode.lib_Flags |= LIBF_DELEXP; + + return (BPTR)NULL; +} + +static struct LibraryHeader *Openlib(struct LibraryManagerInterface *Self, ULONG version) +{ + struct SQLite3Base *SQLite3LibBase = (struct SQLite3Base *) Self->Data.LibBase; + + SQLite3LibBase->sql3_LibNode.lib_OpenCnt++; + SQLite3LibBase->sql3_LibNode.lib_Flags &= ~LIBF_DELEXP; + + if (!SQLite3LibBase->sql3_Initialized) + { + if (!SQLite3Open(SQLite3LibBase)) + { + KPrintF("SQLite3Open failed\n"); + Closelib(Self); + return NULL; + } + SQLite3LibBase->sql3_Initialized = TRUE; + } + + return (struct LibraryHeader *)SQLite3LibBase; +} + +static BPTR Closelib(struct LibraryManagerInterface *Self) +{ + struct SQLite3Base *SQLite3LibBase = (struct SQLite3Base *) Self->Data.LibBase; + + SQLite3LibBase->sql3_LibNode.lib_OpenCnt--; +/* + if (0 == SQLite3LibBase->sql3_LibNode.lib_OpenCnt) + { + if (SQLite3LibBase->sql3_LibNode.lib_Flags & LIBF_DELEXP) + { + return Expungelib(Self); + } + } +*/ + return (BPTR)NULL; +} + +static ULONG Obtainlib(struct LibraryManagerInterface *Self) +{ + return(Self->Data.RefCount++); +} + +static ULONG Releaselib(struct LibraryManagerInterface *Self) +{ + return(Self->Data.RefCount--); +} diff --git a/scalos/libraries/sqlite/sqlite3-aros.c b/scalos/libraries/sqlite/sqlite3-aros.c new file mode 100644 index 000000000..5835d2013 --- /dev/null +++ b/scalos/libraries/sqlite/sqlite3-aros.c @@ -0,0 +1,330 @@ +// Preferences-classic.c +// $Date$ +// $Revision$ + + +#include +#include + +#include + +#include + +#include +#include + + +#include "sqlite3_base.h" +#include "LibSQLite3.h" +#include "sqlite3.h" + +struct Library *aroscbase; + +//---------------------------------------------------------------------------- +// Standard library functions + +static AROS_UFP3 (struct Library *, Initlib, + AROS_UFPA(struct Library *, libbase, D0), + AROS_UFPA(struct SegList *, seglist, A0), + AROS_UFPA(struct ExecBase *, sysbase, A6) +); +static AROS_LD1 (struct Library *, Openlib, + AROS_LPA (__unused ULONG, version, D0), + struct Library *, libbase, 1, SQLite3 +); +static AROS_LD0 (struct SegList *, Closelib, + struct Library *, base, 2, SQLite3 +); +static AROS_LD1 (struct SegList *, Expungelib, + AROS_LPA(__unused struct Library *, __extrabase, D0), + struct Library *, libbase, 3, SQLite3 +); +static AROS_LD0 (ULONG, Extfunclib, + __unused struct Library *, libbase, 4, SQLite3 +); + + +//---------------------------------------------------------------------------- + +SAVEDS(LONG) ASM Libstart(void) +{ + return -1; +} + +//---------------------------------------------------------------------------- + +/* OS3.x Library */ + +static APTR functable[] = + { + SQLite3_1_Openlib, + SQLite3_2_Closelib, + SQLite3_3_Expungelib, + SQLite3_4_Extfunclib, + SQLite3Base_0_LIBSQLite3Close, + SQLite3Base_0_LIBSQLite3Exec, + SQLite3Base_0_LIBSQLite3Changes, + SQLite3Base_0_LIBSQLite3TotalChanges, + SQLite3Base_0_LIBSQLite3Interrupt, + SQLite3Base_0_LIBSQLite3Complete, + SQLite3Base_0_LIBSQLite3BusyHandler, + SQLite3Base_0_LIBSQLite3BusyTimeout, + SQLite3Base_0_LIBSQLite3GetTable, + SQLite3Base_0_LIBSQLite3FreeTable, + SQLite3Base_0_LIBSQLite3Free, + SQLite3Base_0_LIBSQLite3Trace, + SQLite3Base_0_LIBSQLite3ProgressHandler, + SQLite3Base_0_LIBSQLite3CommitHook, + SQLite3Base_0_LIBSQLite3Open, + SQLite3Base_0_LIBSQLite3Errcode, + SQLite3Base_0_LIBSQLite3Errmsg, + SQLite3Base_0_LIBSQLite3Prepare, + SQLite3Base_0_LIBSQLite3BindBlob, + SQLite3Base_0_LIBSQLite3BindInt, + SQLite3Base_0_LIBSQLite3BindNull, + SQLite3Base_0_LIBSQLite3BindText, + SQLite3Base_0_LIBSQLite3BindValue, + SQLite3Base_0_LIBSQLite3BindParameterCount, + SQLite3Base_0_LIBSQLite3BindParameterName, + SQLite3Base_0_LIBSQLite3BindParameterIndex, + SQLite3Base_0_LIBSQLite3ClearBindings, + SQLite3Base_0_LIBSQLite3ColumnCount, + SQLite3Base_0_LIBSQLite3ColumnName, + SQLite3Base_0_LIBSQLite3ColumnDecltype, + SQLite3Base_0_LIBSQLite3Step, + SQLite3Base_0_LIBSQLite3DataCount, + SQLite3Base_0_LIBSQLite3ColumnBlob, + SQLite3Base_0_LIBSQLite3ColumnBytes, + SQLite3Base_0_LIBSQLite3ColumnInt, + SQLite3Base_0_LIBSQLite3ColumnText, + SQLite3Base_0_LIBSQLite3ColumnType, + SQLite3Base_0_LIBSQLite3Finalize, + SQLite3Base_0_LIBSQLite3Reset, + SQLite3Base_0_LIBSQLite3AggregateCount, + SQLite3Base_0_LIBSQLite3ValueBlob, + SQLite3Base_0_LIBSQLite3ValueBytes, + SQLite3Base_0_LIBSQLite3ValueInt, + SQLite3Base_0_LIBSQLite3ValueText, + SQLite3Base_0_LIBSQLite3ValueType, + SQLite3Base_0_LIBSQLite3Aggregate_context, + SQLite3Base_0_LIBSQLite3UserData, + SQLite3Base_0_LIBSQLite3GetAuxdata, + SQLite3Base_0_LIBSQLite3SetAuxdata, + SQLite3Base_0_LIBSQLite3ResultBlob, + SQLite3Base_0_LIBSQLite3ResultError, + SQLite3Base_0_LIBSQLite3ResultInt, + SQLite3Base_0_LIBSQLite3ResultNull, + SQLite3Base_0_LIBSQLite3ResultText, + SQLite3Base_0_LIBSQLite3ResultValue, + SQLite3Base_0_LIBSQLite3CreateCollation, + SQLite3Base_0_LIBSQLite3CollationNeeded, + SQLite3Base_0_LIBSQLite3Sleep, + SQLite3Base_0_LIBSQLite3Expired, + SQLite3Base_0_LIBSQLite3TransferBindings, + SQLite3Base_0_LIBSQLite3GlobalRecover, + SQLite3Base_0_LIBSQLite3GetAutocommit, + SQLite3Base_0_LIBSQLite3DbHandle, + + // new functions in V41 + SQLite3Base_0_LIBSQLite3RollbackHook, + SQLite3Base_0_LIBSQLite3EnableSharedCache, + SQLite3Base_0_LIBSQLite3ReleaseMemory, + SQLite3Base_0_LIBSQLite3SoftHeapLimit, + SQLite3Base_0_LIBSQLite3ThreadCleanup, + + // new function in V42 + SQLite3Base_0_LIBSQLite3PrepareV2, + + // new function in V43 + SQLite3Base_0_LIBSQLite3CreateFunction, + SQLite3Base_0_LIBSQLite3CreateModule, + SQLite3Base_0_LIBSQLite3DeclareVtab, + SQLite3Base_0_LIBSQLite3OverloadFunction, + SQLite3Base_0_LIBSQLite3BlobOpen, + SQLite3Base_0_LIBSQLite3BlobClose, + SQLite3Base_0_LIBSQLite3BlobBytes, + SQLite3Base_0_LIBSQLite3BlobRead, + SQLite3Base_0_LIBSQLite3BlobWrite, + SQLite3Base_0_LIBSQLite3ExtendedResultCodes, + SQLite3Base_0_LIBSQLite3BindZeroBlob, + SQLite3Base_0_LIBSQLite3ColumnDatabaseName, + SQLite3Base_0_LIBSQLite3ColumnTableName, + SQLite3Base_0_LIBSQLite3ColumnOriginName, + SQLite3Base_0_LIBSQLite3ColumnValue, + SQLite3Base_0_LIBSQLite3CreateCollationV2, + SQLite3Base_0_LIBSQLite3LibVersion, + SQLite3Base_0_LIBSQLite3LibversionNumber, + SQLite3Base_0_LIBSQLite3ResultErrorToobig, + SQLite3Base_0_LIBSQLite3ResultZeroBlob, + SQLite3Base_0_LIBSQLite3ValueNumericType, + + // new function in V44 + SQLite3Base_0_LIBSQLite3ConfigV, + SQLite3Base_0_LIBSQLlite3DbConfigV, + SQLite3Base_0_LIBSQLite3VfsFind, + SQLite3Base_0_LIBSQLite3VfsRegister, + SQLite3Base_0_LIBSQLite3VfsUnregister, + SQLite3Base_0_LIBSQLite3FileControl, + SQLite3Base_0_LIBSQLite3Status, + SQLite3Base_0_LIBSQLite3DbStatus, + + (APTR) -1 + }; + +/* Init table used in library initialization. */ +static ULONG inittab[] = + { + sizeof(struct SQLite3Base), + (ULONG) functable, + 0, + (ULONG) Initlib + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, + RTF_AUTOINIT, + LIB_VERSION, + NT_LIBRARY, + 0, + libName, + libIdString, + inittab + }; + + +//---------------------------------------------------------------------------- + + static AROS_UFH3(struct Library *, Initlib, + AROS_UFHA(struct Library *, libbase, D0), + AROS_UFHA(struct SegList *, seglist, A0), + AROS_UFHA(struct ExecBase *, sysbase, A6) +) +{ + AROS_USERFUNC_INIT + + struct SQLite3Base *SQLite3LibBase = (struct SQLite3Base *) libbase; + + /* store pointer to execbase for global access */ + SysBase = sysbase; + + SQLite3LibBase->sql3_LibNode.lib_Revision = LIB_REVISION; + SQLite3LibBase->sql3_SegList = seglist; + + SQLite3LibBase->sql3_Initialized = FALSE; + + aroscbase = OpenLibrary("arosc.library", 0); + + if (!aroscbase || !SQLite3Init(SQLite3LibBase)) + { + SQLite3_3_Expungelib(&SQLite3LibBase->sql3_LibNode, &SQLite3LibBase->sql3_LibNode); + SQLite3LibBase = NULL; + } + + return SQLite3LibBase ? &SQLite3LibBase->sql3_LibNode : NULL; + + AROS_USERFUNC_EXIT +} + + +static AROS_LH1(struct Library *, Openlib, + AROS_LHA(__unused ULONG, version, D0), + struct Library *, libbase, 1, SQLite3 +) +{ + AROS_LIBFUNC_INIT + + struct SQLite3Base *SQLite3LibBase = (struct SQLite3Base *) libbase; + + SQLite3LibBase->sql3_LibNode.lib_OpenCnt++; + SQLite3LibBase->sql3_LibNode.lib_Flags &= ~LIBF_DELEXP; + + if (!SQLite3LibBase->sql3_Initialized) + { + if (!SQLite3Open(SQLite3LibBase)) + { + SQLite3_2_Closelib(&SQLite3LibBase->sql3_LibNode); + return NULL; + } + + SQLite3LibBase->sql3_Initialized = TRUE; + } + + return &SQLite3LibBase->sql3_LibNode; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH0(struct SegList *, Closelib, + struct Library *, libbase, 2, SQLite3 +) +{ + AROS_LIBFUNC_INIT + + struct SQLite3Base *SQLite3LibBase = (struct SQLite3Base *) libbase; + + SQLite3LibBase->sql3_LibNode.lib_OpenCnt--; + + if (0 == SQLite3LibBase->sql3_LibNode.lib_OpenCnt) + { + if (SQLite3LibBase->sql3_LibNode.lib_Flags & LIBF_DELEXP) + { + SQLite3_3_Expungelib(&SQLite3LibBase->sql3_LibNode, &SQLite3LibBase->sql3_LibNode); + } + } + + return NULL; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH1(struct SegList *, Expungelib, + AROS_LHA(__unused struct Library *, __extrabase, D0), + struct Library *, libbase, 3, SQLite3 +) +{ + AROS_LIBFUNC_INIT + + struct SQLite3Base *SQLite3LibBase = (struct SQLite3Base *) libbase; + + if (0 == SQLite3LibBase->sql3_LibNode.lib_OpenCnt) + { + ULONG size = SQLite3LibBase->sql3_LibNode.lib_NegSize + SQLite3LibBase->sql3_LibNode.lib_PosSize; + UBYTE *ptr = (UBYTE *) SQLite3LibBase - SQLite3LibBase->sql3_LibNode.lib_NegSize; + struct SegList *libseglist = SQLite3LibBase->sql3_SegList; + + Remove((struct Node *) SQLite3LibBase); + SQLite3Cleanup(SQLite3LibBase); + FreeMem(ptr,size); + + CloseLibrary(aroscbase); + + return libseglist; + } + + SQLite3LibBase->sql3_LibNode.lib_Flags |= LIBF_DELEXP; + + return NULL; + + AROS_LIBFUNC_EXIT +} + + +static AROS_LH0(ULONG, Extfunclib, + __unused struct Library *, libbase, 4, SQLite3 +) +{ + AROS_LIBFUNC_INIT + + return 0; + + AROS_LIBFUNC_EXIT +} + +//---------------------------------------------------------------------------- diff --git a/scalos/libraries/sqlite/sqlite3-classic.c b/scalos/libraries/sqlite/sqlite3-classic.c new file mode 100644 index 000000000..14b4c1a2f --- /dev/null +++ b/scalos/libraries/sqlite/sqlite3-classic.c @@ -0,0 +1,293 @@ +// Preferences-classic.c +// $Date$ +// $Revision$ + + +#include +#include + +#include + +#include +#include + + +#include "sqlite3_base.h" +#include "LibSQLite3.h" +#include "sqlite3.h" + +//---------------------------------------------------------------------------- +// Standard library functions + +static LIB_SAVEDS(struct Library *) LIB_ASM LIB_INTERRUPT Initlib(LIB_REG(d0, struct Library *libbase), + LIB_REG(a0, struct SegList *seglist), LIB_REG(a6, struct ExecBase *sysbase)); + +static LIBFUNC_PROTO(Openlib, libbase, struct Library *); +static LIBFUNC_PROTO(Closelib, libbase, struct SegList *); +static LIBFUNC_PROTO(Expungelib, libbase, struct SegList *); +static LIBFUNC_PROTO(Extfunclib, libbase, ULONG); + +//---------------------------------------------------------------------------- + +SAVEDS(LONG) ASM Libstart(void) +{ + return -1; +} + +//---------------------------------------------------------------------------- + +/* OS3.x Library */ + +static APTR functable[] = + { +#ifdef __MORPHOS__ + (APTR) FUNCARRAY_32BIT_NATIVE, +#endif + Openlib, + Closelib, + Expungelib, + Extfunclib, + LIBSQLite3Close, + LIBSQLite3Exec, + LIBSQLite3Changes, + LIBSQLite3TotalChanges, + LIBSQLite3Interrupt, + LIBSQLite3Complete, + LIBSQLite3BusyHandler, + LIBSQLite3BusyTimeout, + LIBSQLite3GetTable, + LIBSQLite3FreeTable, + LIBSQLite3Free, + LIBSQLite3Trace, + LIBSQLite3ProgressHandler, + LIBSQLite3CommitHook, + LIBSQLite3Open, + LIBSQLite3Errcode, + LIBSQLite3Errmsg, + LIBSQLite3Prepare, + LIBSQLite3BindBlob, + LIBSQLite3BindInt, + LIBSQLite3BindNull, + LIBSQLite3BindText, + LIBSQLite3BindValue, + LIBSQLite3BindParameterCount, + LIBSQLite3BindParameterName, + LIBSQLite3BindParameterIndex, + LIBSQLite3ClearBindings, + LIBSQLite3ColumnCount, + LIBSQLite3ColumnName, + LIBSQLite3ColumnDecltype, + LIBSQLite3Step, + LIBSQLite3DataCount, + LIBSQLite3ColumnBlob, + LIBSQLite3ColumnBytes, + LIBSQLite3ColumnInt, + LIBSQLite3ColumnText, + LIBSQLite3ColumnType, + LIBSQLite3Finalize, + LIBSQLite3Reset, + LIBSQLite3AggregateCount, + LIBSQLite3ValueBlob, + LIBSQLite3ValueBytes, + LIBSQLite3ValueInt, + LIBSQLite3ValueText, + LIBSQLite3ValueType, + LIBSQLite3Aggregate_context, + LIBSQLite3UserData, + LIBSQLite3GetAuxdata, + LIBSQLite3SetAuxdata, + LIBSQLite3ResultBlob, + LIBSQLite3ResultError, + LIBSQLite3ResultInt, + LIBSQLite3ResultNull, + LIBSQLite3ResultText, + LIBSQLite3ResultValue, + LIBSQLite3CreateCollation, + LIBSQLite3CollationNeeded, + LIBSQLite3Sleep, + LIBSQLite3Expired, + LIBSQLite3TransferBindings, + LIBSQLite3GlobalRecover, + LIBSQLite3GetAutocommit, + LIBSQLite3DbHandle, + + // new functions in V41 + LIBSQLite3RollbackHook, + LIBSQLite3EnableSharedCache, + LIBSQLite3ReleaseMemory, + LIBSQLite3SoftHeapLimit, + LIBSQLite3ThreadCleanup, + + // new function in V42 + LIBSQLite3PrepareV2, + + // new function in V43 + LIBSQLite3CreateFunction, + LIBSQLite3CreateModule, + LIBSQLite3DeclareVtab, + LIBSQLite3OverloadFunction, + LIBSQLite3BlobOpen, + LIBSQLite3BlobClose, + LIBSQLite3BlobBytes, + LIBSQLite3BlobRead, + LIBSQLite3BlobWrite, + LIBSQLite3ExtendedResultCodes, + LIBSQLite3BindZeroBlob, + LIBSQLite3ColumnDatabaseName, + LIBSQLite3ColumnTableName, + LIBSQLite3ColumnOriginName, + LIBSQLite3ColumnValue, + LIBSQLite3CreateCollationV2, + LIBSQLite3LibVersion, + LIBSQLite3LibversionNumber, + LIBSQLite3ResultErrorToobig, + LIBSQLite3ResultZeroBlob, + LIBSQLite3ValueNumericType, + + // new function in V44 + LIBSQLite3ConfigV, + LIBSQLlite3DbConfigV, + LIBSQLite3VfsFind, + LIBSQLite3VfsRegister, + LIBSQLite3VfsUnregister, + LIBSQLite3FileControl, + LIBSQLite3Status, + LIBSQLite3DbStatus, + + (APTR) -1 + }; + +/* Init table used in library initialization. */ +static ULONG inittab[] = + { + sizeof(struct SQLite3Base), + (ULONG) functable, + 0, + (ULONG) Initlib + }; + + +/* The ROM tag */ +struct Resident ALIGNED romtag = + { + RTC_MATCHWORD, + &romtag, + &romtag + 1, +#ifdef __MORPHOS__ + RTF_PPC | RTF_AUTOINIT, +#else + RTF_AUTOINIT, +#endif + LIB_VERSION, + NT_LIBRARY, + 0, + libName, + libIdString, + inittab + }; + +#ifdef __MORPHOS__ +ULONG __abox__=1; +#endif + +//---------------------------------------------------------------------------- + +static LIB_SAVEDS(struct Library *) LIB_ASM LIB_INTERRUPT Initlib(LIB_REG(d0, struct Library *libbase), + LIB_REG(a0, struct SegList *seglist), LIB_REG(a6, struct ExecBase *sysbase)) +{ + struct SQLite3Base *SQLite3LibBase = (struct SQLite3Base *) libbase; + + /* store pointer to execbase for global access */ + SysBase = sysbase; + + SQLite3LibBase->sql3_LibNode.lib_Revision = LIB_REVISION; + SQLite3LibBase->sql3_SegList = seglist; + + SQLite3LibBase->sql3_Initialized = FALSE; + + if (!SQLite3Init(SQLite3LibBase)) + { + CALLLIBFUNC(Expungelib, &SQLite3LibBase->sql3_LibNode); + SQLite3LibBase = NULL; + } + + return SQLite3LibBase ? &SQLite3LibBase->sql3_LibNode : NULL; +} + + +static LIBFUNC(Openlib, libbase, struct Library *) +{ + struct SQLite3Base *SQLite3LibBase = (struct SQLite3Base *) libbase; + + SQLite3LibBase->sql3_LibNode.lib_OpenCnt++; + SQLite3LibBase->sql3_LibNode.lib_Flags &= ~LIBF_DELEXP; + + if (!SQLite3LibBase->sql3_Initialized) + { + if (!SQLite3Open(SQLite3LibBase)) + { + CALLLIBFUNC(Closelib, &SQLite3LibBase->sql3_LibNode); + return NULL; + } + + SQLite3LibBase->sql3_Initialized = TRUE; + } + + return &SQLite3LibBase->sql3_LibNode; +} +LIBFUNC_END + + +static LIBFUNC(Closelib, libbase, struct SegList *) +{ + struct SQLite3Base *SQLite3LibBase = (struct SQLite3Base *) libbase; + + SQLite3LibBase->sql3_LibNode.lib_OpenCnt--; + + if (0 == SQLite3LibBase->sql3_LibNode.lib_OpenCnt) + { + if (SQLite3LibBase->sql3_LibNode.lib_Flags & LIBF_DELEXP) + { + return CALLLIBFUNC(Expungelib, &SQLite3LibBase->sql3_LibNode); + } + } + + return NULL; +} +LIBFUNC_END + + +static LIBFUNC(Expungelib, libbase, struct SegList *) +{ + struct SQLite3Base *SQLite3LibBase = (struct SQLite3Base *) libbase; + + if (0 == SQLite3LibBase->sql3_LibNode.lib_OpenCnt) + { + ULONG size = SQLite3LibBase->sql3_LibNode.lib_NegSize + SQLite3LibBase->sql3_LibNode.lib_PosSize; + UBYTE *ptr = (UBYTE *) SQLite3LibBase - SQLite3LibBase->sql3_LibNode.lib_NegSize; + struct SegList *libseglist = SQLite3LibBase->sql3_SegList; + + Remove((struct Node *) SQLite3LibBase); + SQLite3Cleanup(SQLite3LibBase); + FreeMem(ptr,size); + + return libseglist; + } + + SQLite3LibBase->sql3_LibNode.lib_Flags |= LIBF_DELEXP; + + return NULL; +} +LIBFUNC_END + + +static LIBFUNC(Extfunclib, libbase, ULONG) +{ + (void) libbase; + + return 0; +} +LIBFUNC_END + +//---------------------------------------------------------------------------- + diff --git a/scalos/libraries/sqlite/sqlite3.h b/scalos/libraries/sqlite/sqlite3.h new file mode 100644 index 000000000..fc9cd076a --- /dev/null +++ b/scalos/libraries/sqlite/sqlite3.h @@ -0,0 +1,6949 @@ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This header file defines the interface that the SQLite library +** presents to client programs. If a C-function, structure, datatype, +** or constant definition does not appear in this file, then it is +** not a published API of SQLite, is subject to change without +** notice, and should not be referenced by programs that use SQLite. +** +** Some of the definitions that are in this file are marked as +** "experimental". Experimental interfaces are normally new +** features recently added to SQLite. We do not anticipate changes +** to experimental interfaces but reserve the right to make minor changes +** if experience from use "in the wild" suggest such changes are prudent. +** +** The official C-language API documentation for SQLite is derived +** from comments in this file. This file is the authoritative source +** on how SQLite interfaces are suppose to operate. +** +** The name of this file under configuration management is "sqlite.h.in". +** The makefile makes some minor changes to this file (such as inserting +** the version number) and changes its name to "sqlite3.h" as +** part of the build process. +*/ +#ifndef _SQLITE3_H_ +#define _SQLITE3_H_ +#include /* Needed for the definition of va_list */ + +/* +** Make sure we can call this stuff from C++. +*/ +#ifdef __cplusplus +extern "C" { +#endif + + +/* +** Add the ability to override 'extern' +*/ +#ifndef SQLITE_EXTERN +# define SQLITE_EXTERN extern +#endif + +#ifndef SQLITE_API +# define SQLITE_API +#endif + + +/* +** These no-op macros are used in front of interfaces to mark those +** interfaces as either deprecated or experimental. New applications +** should not use deprecated interfaces - they are support for backwards +** compatibility only. Application writers should be aware that +** experimental interfaces are subject to change in point releases. +** +** These macros used to resolve to various kinds of compiler magic that +** would generate warning messages when they were used. But that +** compiler magic ended up generating such a flurry of bug reports +** that we have taken it all out and gone back to using simple +** noop macros. +*/ +#define SQLITE_DEPRECATED +#define SQLITE_EXPERIMENTAL + +/* +** Ensure these symbols were not defined by some previous header file. +*/ +#ifdef SQLITE_VERSION +# undef SQLITE_VERSION +#endif +#ifdef SQLITE_VERSION_NUMBER +# undef SQLITE_VERSION_NUMBER +#endif + +/* +** CAPI3REF: Compile-Time Library Version Numbers +** +** ^(The [SQLITE_VERSION] C preprocessor macro in the sqlite3.h header +** evaluates to a string literal that is the SQLite version in the +** format "X.Y.Z" where X is the major version number (always 3 for +** SQLite3) and Y is the minor version number and Z is the release number.)^ +** ^(The [SQLITE_VERSION_NUMBER] C preprocessor macro resolves to an integer +** with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z are the same +** numbers used in [SQLITE_VERSION].)^ +** The SQLITE_VERSION_NUMBER for any given release of SQLite will also +** be larger than the release from which it is derived. Either Y will +** be held constant and Z will be incremented or else Y will be incremented +** and Z will be reset to zero. +** +** Since version 3.6.18, SQLite source code has been stored in the +** Fossil configuration management +** system. ^The SQLITE_SOURCE_ID macro evaluates to +** a string which identifies a particular check-in of SQLite +** within its configuration management system. ^The SQLITE_SOURCE_ID +** string contains the date and time of the check-in (UTC) and an SHA1 +** hash of the entire source tree. +** +** See also: [sqlite3_libversion()], +** [sqlite3_libversion_number()], [sqlite3_sourceid()], +** [sqlite_version()] and [sqlite_source_id()]. +*/ +#define SQLITE_VERSION "3.7.10" +#define SQLITE_VERSION_NUMBER 3007010 +#define SQLITE_SOURCE_ID "2012-01-16 13:28:40 ebd01a8deffb5024a5d7494eef800d2366d97204" + +/* +** CAPI3REF: Run-Time Library Version Numbers +** KEYWORDS: sqlite3_version, sqlite3_sourceid +** +** These interfaces provide the same information as the [SQLITE_VERSION], +** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros +** but are associated with the library instead of the header file. ^(Cautious +** programmers might include assert() statements in their application to +** verify that values returned by these interfaces match the macros in +** the header, and thus insure that the application is +** compiled with matching library and header files. +** +**
+** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
+** assert( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)==0 );
+** assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 );
+** 
)^ +** +** ^The sqlite3_version[] string constant contains the text of [SQLITE_VERSION] +** macro. ^The sqlite3_libversion() function returns a pointer to the +** to the sqlite3_version[] string constant. The sqlite3_libversion() +** function is provided for use in DLLs since DLL users usually do not have +** direct access to string constants within the DLL. ^The +** sqlite3_libversion_number() function returns an integer equal to +** [SQLITE_VERSION_NUMBER]. ^The sqlite3_sourceid() function returns +** a pointer to a string constant whose value is the same as the +** [SQLITE_SOURCE_ID] C preprocessor macro. +** +** See also: [sqlite_version()] and [sqlite_source_id()]. +*/ +SQLITE_API SQLITE_EXTERN const char sqlite3_version[]; +SQLITE_API const char *sqlite3_libversion(void); +SQLITE_API const char *sqlite3_sourceid(void); +SQLITE_API int sqlite3_libversion_number(void); + +/* +** CAPI3REF: Run-Time Library Compilation Options Diagnostics +** +** ^The sqlite3_compileoption_used() function returns 0 or 1 +** indicating whether the specified option was defined at +** compile time. ^The SQLITE_ prefix may be omitted from the +** option name passed to sqlite3_compileoption_used(). +** +** ^The sqlite3_compileoption_get() function allows iterating +** over the list of options that were defined at compile time by +** returning the N-th compile time option string. ^If N is out of range, +** sqlite3_compileoption_get() returns a NULL pointer. ^The SQLITE_ +** prefix is omitted from any strings returned by +** sqlite3_compileoption_get(). +** +** ^Support for the diagnostic functions sqlite3_compileoption_used() +** and sqlite3_compileoption_get() may be omitted by specifying the +** [SQLITE_OMIT_COMPILEOPTION_DIAGS] option at compile time. +** +** See also: SQL functions [sqlite_compileoption_used()] and +** [sqlite_compileoption_get()] and the [compile_options pragma]. +*/ +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS +SQLITE_API int sqlite3_compileoption_used(const char *zOptName); +SQLITE_API const char *sqlite3_compileoption_get(int N); +#endif + +/* +** CAPI3REF: Test To See If The Library Is Threadsafe +** +** ^The sqlite3_threadsafe() function returns zero if and only if +** SQLite was compiled with mutexing code omitted due to the +** [SQLITE_THREADSAFE] compile-time option being set to 0. +** +** SQLite can be compiled with or without mutexes. When +** the [SQLITE_THREADSAFE] C preprocessor macro is 1 or 2, mutexes +** are enabled and SQLite is threadsafe. When the +** [SQLITE_THREADSAFE] macro is 0, +** the mutexes are omitted. Without the mutexes, it is not safe +** to use SQLite concurrently from more than one thread. +** +** Enabling mutexes incurs a measurable performance penalty. +** So if speed is of utmost importance, it makes sense to disable +** the mutexes. But for maximum safety, mutexes should be enabled. +** ^The default behavior is for mutexes to be enabled. +** +** This interface can be used by an application to make sure that the +** version of SQLite that it is linking against was compiled with +** the desired setting of the [SQLITE_THREADSAFE] macro. +** +** This interface only reports on the compile-time mutex setting +** of the [SQLITE_THREADSAFE] flag. If SQLite is compiled with +** SQLITE_THREADSAFE=1 or =2 then mutexes are enabled by default but +** can be fully or partially disabled using a call to [sqlite3_config()] +** with the verbs [SQLITE_CONFIG_SINGLETHREAD], [SQLITE_CONFIG_MULTITHREAD], +** or [SQLITE_CONFIG_MUTEX]. ^(The return value of the +** sqlite3_threadsafe() function shows only the compile-time setting of +** thread safety, not any run-time changes to that setting made by +** sqlite3_config(). In other words, the return value from sqlite3_threadsafe() +** is unchanged by calls to sqlite3_config().)^ +** +** See the [threading mode] documentation for additional information. +*/ +SQLITE_API int sqlite3_threadsafe(void); + +/* +** CAPI3REF: Database Connection Handle +** KEYWORDS: {database connection} {database connections} +** +** Each open SQLite database is represented by a pointer to an instance of +** the opaque structure named "sqlite3". It is useful to think of an sqlite3 +** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and +** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()] +** is its destructor. There are many other interfaces (such as +** [sqlite3_prepare_v2()], [sqlite3_create_function()], and +** [sqlite3_busy_timeout()] to name but three) that are methods on an +** sqlite3 object. +*/ +typedef struct sqlite3 sqlite3; + +/* +** CAPI3REF: 64-Bit Integer Types +** KEYWORDS: sqlite_int64 sqlite_uint64 +** +** Because there is no cross-platform way to specify 64-bit integer types +** SQLite includes typedefs for 64-bit signed and unsigned integers. +** +** The sqlite3_int64 and sqlite3_uint64 are the preferred type definitions. +** The sqlite_int64 and sqlite_uint64 types are supported for backwards +** compatibility only. +** +** ^The sqlite3_int64 and sqlite_int64 types can store integer values +** between -9223372036854775808 and +9223372036854775807 inclusive. ^The +** sqlite3_uint64 and sqlite_uint64 types can store integer values +** between 0 and +18446744073709551615 inclusive. +*/ +#ifdef SQLITE_INT64_TYPE + typedef SQLITE_INT64_TYPE sqlite_int64; + typedef unsigned SQLITE_INT64_TYPE sqlite_uint64; +#elif defined(_MSC_VER) || defined(__BORLANDC__) + typedef __int64 sqlite_int64; + typedef unsigned __int64 sqlite_uint64; +#else + typedef long long int sqlite_int64; + typedef unsigned long long int sqlite_uint64; +#endif +typedef sqlite_int64 sqlite3_int64; +typedef sqlite_uint64 sqlite3_uint64; + +/* +** If compiling for a processor that lacks floating point support, +** substitute integer for floating-point. +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# define double sqlite3_int64 +#endif + +/* +** CAPI3REF: Closing A Database Connection +** +** ^The sqlite3_close() routine is the destructor for the [sqlite3] object. +** ^Calls to sqlite3_close() return SQLITE_OK if the [sqlite3] object is +** successfully destroyed and all associated resources are deallocated. +** +** Applications must [sqlite3_finalize | finalize] all [prepared statements] +** and [sqlite3_blob_close | close] all [BLOB handles] associated with +** the [sqlite3] object prior to attempting to close the object. ^If +** sqlite3_close() is called on a [database connection] that still has +** outstanding [prepared statements] or [BLOB handles], then it returns +** SQLITE_BUSY. +** +** ^If [sqlite3_close()] is invoked while a transaction is open, +** the transaction is automatically rolled back. +** +** The C parameter to [sqlite3_close(C)] must be either a NULL +** pointer or an [sqlite3] object pointer obtained +** from [sqlite3_open()], [sqlite3_open16()], or +** [sqlite3_open_v2()], and not previously closed. +** ^Calling sqlite3_close() with a NULL pointer argument is a +** harmless no-op. +*/ +SQLITE_API int sqlite3_close(sqlite3 *); + +/* +** The type for a callback function. +** This is legacy and deprecated. It is included for historical +** compatibility and is not documented. +*/ +typedef int (*sqlite3_callback)(void*,int,char**, char**); + +/* +** CAPI3REF: One-Step Query Execution Interface +** +** The sqlite3_exec() interface is a convenience wrapper around +** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()], +** that allows an application to run multiple statements of SQL +** without having to use a lot of C code. +** +** ^The sqlite3_exec() interface runs zero or more UTF-8 encoded, +** semicolon-separate SQL statements passed into its 2nd argument, +** in the context of the [database connection] passed in as its 1st +** argument. ^If the callback function of the 3rd argument to +** sqlite3_exec() is not NULL, then it is invoked for each result row +** coming out of the evaluated SQL statements. ^The 4th argument to +** sqlite3_exec() is relayed through to the 1st argument of each +** callback invocation. ^If the callback pointer to sqlite3_exec() +** is NULL, then no callback is ever invoked and result rows are +** ignored. +** +** ^If an error occurs while evaluating the SQL statements passed into +** sqlite3_exec(), then execution of the current statement stops and +** subsequent statements are skipped. ^If the 5th parameter to sqlite3_exec() +** is not NULL then any error message is written into memory obtained +** from [sqlite3_malloc()] and passed back through the 5th parameter. +** To avoid memory leaks, the application should invoke [sqlite3_free()] +** on error message strings returned through the 5th parameter of +** of sqlite3_exec() after the error message string is no longer needed. +** ^If the 5th parameter to sqlite3_exec() is not NULL and no errors +** occur, then sqlite3_exec() sets the pointer in its 5th parameter to +** NULL before returning. +** +** ^If an sqlite3_exec() callback returns non-zero, the sqlite3_exec() +** routine returns SQLITE_ABORT without invoking the callback again and +** without running any subsequent SQL statements. +** +** ^The 2nd argument to the sqlite3_exec() callback function is the +** number of columns in the result. ^The 3rd argument to the sqlite3_exec() +** callback is an array of pointers to strings obtained as if from +** [sqlite3_column_text()], one for each column. ^If an element of a +** result row is NULL then the corresponding string pointer for the +** sqlite3_exec() callback is a NULL pointer. ^The 4th argument to the +** sqlite3_exec() callback is an array of pointers to strings where each +** entry represents the name of corresponding result column as obtained +** from [sqlite3_column_name()]. +** +** ^If the 2nd parameter to sqlite3_exec() is a NULL pointer, a pointer +** to an empty string, or a pointer that contains only whitespace and/or +** SQL comments, then no SQL statements are evaluated and the database +** is not changed. +** +** Restrictions: +** +**
    +**
  • The application must insure that the 1st parameter to sqlite3_exec() +** is a valid and open [database connection]. +**
  • The application must not close [database connection] specified by +** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running. +**
  • The application must not modify the SQL statement text passed into +** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running. +**
+*/ +SQLITE_API int sqlite3_exec( + sqlite3*, /* An open database */ + const char *sql, /* SQL to be evaluated */ + int (*callback)(void*,int,char**,char**), /* Callback function */ + void *, /* 1st argument to callback */ + char **errmsg /* Error msg written here */ +); + +/* +** CAPI3REF: Result Codes +** KEYWORDS: SQLITE_OK {error code} {error codes} +** KEYWORDS: {result code} {result codes} +** +** Many SQLite functions return an integer result code from the set shown +** here in order to indicate success or failure. +** +** New error codes may be added in future versions of SQLite. +** +** See also: [SQLITE_IOERR_READ | extended result codes], +** [sqlite3_vtab_on_conflict()] [SQLITE_ROLLBACK | result codes]. +*/ +#define SQLITE_OK 0 /* Successful result */ +/* beginning-of-error-codes */ +#define SQLITE_ERROR 1 /* SQL error or missing database */ +#define SQLITE_INTERNAL 2 /* Internal logic error in SQLite */ +#define SQLITE_PERM 3 /* Access permission denied */ +#define SQLITE_ABORT 4 /* Callback routine requested an abort */ +#define SQLITE_BUSY 5 /* The database file is locked */ +#define SQLITE_LOCKED 6 /* A table in the database is locked */ +#define SQLITE_NOMEM 7 /* A malloc() failed */ +#define SQLITE_READONLY 8 /* Attempt to write a readonly database */ +#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/ +#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */ +#define SQLITE_CORRUPT 11 /* The database disk image is malformed */ +#define SQLITE_NOTFOUND 12 /* Unknown opcode in sqlite3_file_control() */ +#define SQLITE_FULL 13 /* Insertion failed because database is full */ +#define SQLITE_CANTOPEN 14 /* Unable to open the database file */ +#define SQLITE_PROTOCOL 15 /* Database lock protocol error */ +#define SQLITE_EMPTY 16 /* Database is empty */ +#define SQLITE_SCHEMA 17 /* The database schema changed */ +#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */ +#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */ +#define SQLITE_MISMATCH 20 /* Data type mismatch */ +#define SQLITE_MISUSE 21 /* Library used incorrectly */ +#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ +#define SQLITE_AUTH 23 /* Authorization denied */ +#define SQLITE_FORMAT 24 /* Auxiliary database format error */ +#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */ +#define SQLITE_NOTADB 26 /* File opened that is not a database file */ +#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */ +#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */ +/* end-of-error-codes */ + +/* +** CAPI3REF: Extended Result Codes +** KEYWORDS: {extended error code} {extended error codes} +** KEYWORDS: {extended result code} {extended result codes} +** +** In its default configuration, SQLite API routines return one of 26 integer +** [SQLITE_OK | result codes]. However, experience has shown that many of +** these result codes are too coarse-grained. They do not provide as +** much information about problems as programmers might like. In an effort to +** address this, newer versions of SQLite (version 3.3.8 and later) include +** support for additional result codes that provide more detailed information +** about errors. The extended result codes are enabled or disabled +** on a per database connection basis using the +** [sqlite3_extended_result_codes()] API. +** +** Some of the available extended result codes are listed here. +** One may expect the number of extended result codes will be expand +** over time. Software that uses extended result codes should expect +** to see new result codes in future releases of SQLite. +** +** The SQLITE_OK result code will never be extended. It will always +** be exactly zero. +*/ +#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) +#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8)) +#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) +#define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8)) +#define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8)) +#define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8)) +#define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8)) +#define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8)) +#define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8)) +#define SQLITE_IOERR_DELETE (SQLITE_IOERR | (10<<8)) +#define SQLITE_IOERR_BLOCKED (SQLITE_IOERR | (11<<8)) +#define SQLITE_IOERR_NOMEM (SQLITE_IOERR | (12<<8)) +#define SQLITE_IOERR_ACCESS (SQLITE_IOERR | (13<<8)) +#define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8)) +#define SQLITE_IOERR_LOCK (SQLITE_IOERR | (15<<8)) +#define SQLITE_IOERR_CLOSE (SQLITE_IOERR | (16<<8)) +#define SQLITE_IOERR_DIR_CLOSE (SQLITE_IOERR | (17<<8)) +#define SQLITE_IOERR_SHMOPEN (SQLITE_IOERR | (18<<8)) +#define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) +#define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) +#define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) +#define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) +#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) +#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) +#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) +#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) +#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) +#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) + +/* +** CAPI3REF: Flags For File Open Operations +** +** These bit values are intended for use in the +** 3rd parameter to the [sqlite3_open_v2()] interface and +** in the 4th parameter to the [sqlite3_vfs.xOpen] method. +*/ +#define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */ +#define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */ +#define SQLITE_OPEN_AUTOPROXY 0x00000020 /* VFS only */ +#define SQLITE_OPEN_URI 0x00000040 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */ +#define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */ +#define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */ +#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */ +#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */ +#define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */ +#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */ +#define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_WAL 0x00080000 /* VFS only */ + +/* Reserved: 0x00F00000 */ + +/* +** CAPI3REF: Device Characteristics +** +** The xDeviceCharacteristics method of the [sqlite3_io_methods] +** object returns an integer which is a vector of the these +** bit values expressing I/O characteristics of the mass storage +** device that holds the file that the [sqlite3_io_methods] +** refers to. +** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). The SQLITE_IOCAP_POWERSAFE_OVERWRITE property means that +** after reboot following a crash or power loss, the only bytes in a +** file that were written at the application level might have changed +** and that adjacent bytes, even bytes within the same sector are +** guaranteed to be unchanged. +*/ +#define SQLITE_IOCAP_ATOMIC 0x00000001 +#define SQLITE_IOCAP_ATOMIC512 0x00000002 +#define SQLITE_IOCAP_ATOMIC1K 0x00000004 +#define SQLITE_IOCAP_ATOMIC2K 0x00000008 +#define SQLITE_IOCAP_ATOMIC4K 0x00000010 +#define SQLITE_IOCAP_ATOMIC8K 0x00000020 +#define SQLITE_IOCAP_ATOMIC16K 0x00000040 +#define SQLITE_IOCAP_ATOMIC32K 0x00000080 +#define SQLITE_IOCAP_ATOMIC64K 0x00000100 +#define SQLITE_IOCAP_SAFE_APPEND 0x00000200 +#define SQLITE_IOCAP_SEQUENTIAL 0x00000400 +#define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800 +#define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 + +/* +** CAPI3REF: File Locking Levels +** +** SQLite uses one of these integer values as the second +** argument to calls it makes to the xLock() and xUnlock() methods +** of an [sqlite3_io_methods] object. +*/ +#define SQLITE_LOCK_NONE 0 +#define SQLITE_LOCK_SHARED 1 +#define SQLITE_LOCK_RESERVED 2 +#define SQLITE_LOCK_PENDING 3 +#define SQLITE_LOCK_EXCLUSIVE 4 + +/* +** CAPI3REF: Synchronization Type Flags +** +** When SQLite invokes the xSync() method of an +** [sqlite3_io_methods] object it uses a combination of +** these integer values as the second argument. +** +** When the SQLITE_SYNC_DATAONLY flag is used, it means that the +** sync operation only needs to flush data to mass storage. Inode +** information need not be flushed. If the lower four bits of the flag +** equal SQLITE_SYNC_NORMAL, that means to use normal fsync() semantics. +** If the lower four bits equal SQLITE_SYNC_FULL, that means +** to use Mac OS X style fullsync instead of fsync(). +** +** Do not confuse the SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL flags +** with the [PRAGMA synchronous]=NORMAL and [PRAGMA synchronous]=FULL +** settings. The [synchronous pragma] determines when calls to the +** xSync VFS method occur and applies uniformly across all platforms. +** The SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL flags determine how +** energetic or rigorous or forceful the sync operations are and +** only make a difference on Mac OSX for the default SQLite code. +** (Third-party VFS implementations might also make the distinction +** between SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL, but among the +** operating systems natively supported by SQLite, only Mac OSX +** cares about the difference.) +*/ +#define SQLITE_SYNC_NORMAL 0x00002 +#define SQLITE_SYNC_FULL 0x00003 +#define SQLITE_SYNC_DATAONLY 0x00010 + +/* +** CAPI3REF: OS Interface Open File Handle +** +** An [sqlite3_file] object represents an open file in the +** [sqlite3_vfs | OS interface layer]. Individual OS interface +** implementations will +** want to subclass this object by appending additional fields +** for their own use. The pMethods entry is a pointer to an +** [sqlite3_io_methods] object that defines methods for performing +** I/O operations on the open file. +*/ +typedef struct sqlite3_file sqlite3_file; +struct sqlite3_file { + const struct sqlite3_io_methods *pMethods; /* Methods for an open file */ +}; + +/* +** CAPI3REF: OS Interface File Virtual Methods Object +** +** Every file opened by the [sqlite3_vfs.xOpen] method populates an +** [sqlite3_file] object (or, more commonly, a subclass of the +** [sqlite3_file] object) with a pointer to an instance of this object. +** This object defines the methods used to perform various operations +** against the open file represented by the [sqlite3_file] object. +** +** If the [sqlite3_vfs.xOpen] method sets the sqlite3_file.pMethods element +** to a non-NULL pointer, then the sqlite3_io_methods.xClose method +** may be invoked even if the [sqlite3_vfs.xOpen] reported that it failed. The +** only way to prevent a call to xClose following a failed [sqlite3_vfs.xOpen] +** is for the [sqlite3_vfs.xOpen] to set the sqlite3_file.pMethods element +** to NULL. +** +** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or +** [SQLITE_SYNC_FULL]. The first choice is the normal fsync(). +** The second choice is a Mac OS X style fullsync. The [SQLITE_SYNC_DATAONLY] +** flag may be ORed in to indicate that only the data of the file +** and not its inode needs to be synced. +** +** The integer values to xLock() and xUnlock() are one of +**
    +**
  • [SQLITE_LOCK_NONE], +**
  • [SQLITE_LOCK_SHARED], +**
  • [SQLITE_LOCK_RESERVED], +**
  • [SQLITE_LOCK_PENDING], or +**
  • [SQLITE_LOCK_EXCLUSIVE]. +**
+** xLock() increases the lock. xUnlock() decreases the lock. +** The xCheckReservedLock() method checks whether any database connection, +** either in this process or in some other process, is holding a RESERVED, +** PENDING, or EXCLUSIVE lock on the file. It returns true +** if such a lock exists and false otherwise. +** +** The xFileControl() method is a generic interface that allows custom +** VFS implementations to directly control an open file using the +** [sqlite3_file_control()] interface. The second "op" argument is an +** integer opcode. The third argument is a generic pointer intended to +** point to a structure that may contain arguments or space in which to +** write return values. Potential uses for xFileControl() might be +** functions to enable blocking locks with timeouts, to change the +** locking strategy (for example to use dot-file locks), to inquire +** about the status of a lock, or to break stale locks. The SQLite +** core reserves all opcodes less than 100 for its own use. +** A [SQLITE_FCNTL_LOCKSTATE | list of opcodes] less than 100 is available. +** Applications that define a custom xFileControl method should use opcodes +** greater than 100 to avoid conflicts. VFS implementations should +** return [SQLITE_NOTFOUND] for file control opcodes that they do not +** recognize. +** +** The xSectorSize() method returns the sector size of the +** device that underlies the file. The sector size is the +** minimum write that can be performed without disturbing +** other bytes in the file. The xDeviceCharacteristics() +** method returns a bit vector describing behaviors of the +** underlying device: +** +**
    +**
  • [SQLITE_IOCAP_ATOMIC] +**
  • [SQLITE_IOCAP_ATOMIC512] +**
  • [SQLITE_IOCAP_ATOMIC1K] +**
  • [SQLITE_IOCAP_ATOMIC2K] +**
  • [SQLITE_IOCAP_ATOMIC4K] +**
  • [SQLITE_IOCAP_ATOMIC8K] +**
  • [SQLITE_IOCAP_ATOMIC16K] +**
  • [SQLITE_IOCAP_ATOMIC32K] +**
  • [SQLITE_IOCAP_ATOMIC64K] +**
  • [SQLITE_IOCAP_SAFE_APPEND] +**
  • [SQLITE_IOCAP_SEQUENTIAL] +**
+** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). +** +** If xRead() returns SQLITE_IOERR_SHORT_READ it must also fill +** in the unread portions of the buffer with zeros. A VFS that +** fails to zero-fill short reads might seem to work. However, +** failure to zero-fill short reads will eventually lead to +** database corruption. +*/ +typedef struct sqlite3_io_methods sqlite3_io_methods; +struct sqlite3_io_methods { + int iVersion; + int (*xClose)(sqlite3_file*); + int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); + int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst); + int (*xTruncate)(sqlite3_file*, sqlite3_int64 size); + int (*xSync)(sqlite3_file*, int flags); + int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize); + int (*xLock)(sqlite3_file*, int); + int (*xUnlock)(sqlite3_file*, int); + int (*xCheckReservedLock)(sqlite3_file*, int *pResOut); + int (*xFileControl)(sqlite3_file*, int op, void *pArg); + int (*xSectorSize)(sqlite3_file*); + int (*xDeviceCharacteristics)(sqlite3_file*); + /* Methods above are valid for version 1 */ + int (*xShmMap)(sqlite3_file*, int iPg, int pgsz, int, void volatile**); + int (*xShmLock)(sqlite3_file*, int offset, int n, int flags); + void (*xShmBarrier)(sqlite3_file*); + int (*xShmUnmap)(sqlite3_file*, int deleteFlag); + /* Methods above are valid for version 2 */ + /* Additional methods may be added in future releases */ +}; + +/* +** CAPI3REF: Standard File Control Opcodes +** +** These integer constants are opcodes for the xFileControl method +** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()] +** interface. +** +** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This +** opcode causes the xFileControl method to write the current state of +** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], +** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) +** into an integer that the pArg argument points to. This capability +** is used during testing and only needs to be supported when SQLITE_TEST +** is defined. +** +** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS +** layer a hint of how large the database file will grow to be during the +** current transaction. This hint is not guaranteed to be accurate but it +** is often close. The underlying VFS might choose to preallocate database +** file space based on this hint in order to help writes to the database +** file run faster. +** +** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS +** extends and truncates the database file in chunks of a size specified +** by the user. The fourth argument to [sqlite3_file_control()] should +** point to an integer (type int) containing the new chunk-size to use +** for the nominated database. Allocating database file space in large +** chunks (say 1MB at a time), may reduce file-system fragmentation and +** improve performance on some systems. +** +** The [SQLITE_FCNTL_FILE_POINTER] opcode is used to obtain a pointer +** to the [sqlite3_file] object associated with a particular database +** connection. See the [sqlite3_file_control()] documentation for +** additional information. +** +** ^(The [SQLITE_FCNTL_SYNC_OMITTED] opcode is generated internally by +** SQLite and sent to all VFSes in place of a call to the xSync method +** when the database connection has [PRAGMA synchronous] set to OFF.)^ +** Some specialized VFSes need this signal in order to operate correctly +** when [PRAGMA synchronous | PRAGMA synchronous=OFF] is set, but most +** VFSes do not need this signal and should silently ignore this opcode. +** Applications should not call [sqlite3_file_control()] with this +** opcode as doing so may disrupt the operation of the specialized VFSes +** that do require it. +** +** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic +** retry counts and intervals for certain disk I/O operations for the +** windows [VFS] in order to provide robustness in the presence of +** anti-virus programs. By default, the windows VFS will retry file read, +** file write, and file delete operations up to 10 times, with a delay +** of 25 milliseconds before the first retry and with the delay increasing +** by an additional 25 milliseconds with each subsequent retry. This +** opcode allows these two values (10 retries and 25 milliseconds of delay) +** to be adjusted. The values are changed for all database connections +** within the same process. The argument is a pointer to an array of two +** integers where the first integer i the new retry count and the second +** integer is the delay. If either integer is negative, then the setting +** is not changed but instead the prior value of that setting is written +** into the array entry, allowing the current retry settings to be +** interrogated. The zDbName parameter is ignored. +** +** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the +** persistent [WAL | Write AHead Log] setting. By default, the auxiliary +** write ahead log and shared memory files used for transaction control +** are automatically deleted when the latest connection to the database +** closes. Setting persistent WAL mode causes those files to persist after +** close. Persisting the files is useful when other processes that do not +** have write permission on the directory containing the database file want +** to read the database file, as the WAL and shared memory files must exist +** in order for the database to be readable. The fourth parameter to +** [sqlite3_file_control()] for this opcode should be a pointer to an integer. +** That integer is 0 to disable persistent WAL mode or 1 to enable persistent +** WAL mode. If the integer is -1, then it is overwritten with the current +** WAL persistence setting. +** +** ^The [SQLITE_FCNTL_POWERSAFE_OVERWRITE] opcode is used to set or query the +** persistent "powersafe-overwrite" or "PSOW" setting. The PSOW setting +** determines the [SQLITE_IOCAP_POWERSAFE_OVERWRITE] bit of the +** xDeviceCharacteristics methods. The fourth parameter to +** [sqlite3_file_control()] for this opcode should be a pointer to an integer. +** That integer is 0 to disable zero-damage mode or 1 to enable zero-damage +** mode. If the integer is -1, then it is overwritten with the current +** zero-damage mode setting. +** +** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening +** a write transaction to indicate that, unless it is rolled back for some +** reason, the entire database file will be overwritten by the current +** transaction. This is used by VACUUM operations. +** +** ^The [SQLITE_FCNTL_VFSNAME] opcode can be used to obtain the names of +** all [VFSes] in the VFS stack. The names are of all VFS shims and the +** final bottom-level VFS are written into memory obtained from +** [sqlite3_malloc()] and the result is stored in the char* variable +** that the fourth parameter of [sqlite3_file_control()] points to. +** The caller is responsible for freeing the memory when done. As with +** all file-control actions, there is no guarantee that this will actually +** do anything. Callers should initialize the char* variable to a NULL +** pointer in case this file-control is not implemented. This file-control +** is intended for diagnostic use only. +*/ +#define SQLITE_FCNTL_LOCKSTATE 1 +#define SQLITE_GET_LOCKPROXYFILE 2 +#define SQLITE_SET_LOCKPROXYFILE 3 +#define SQLITE_LAST_ERRNO 4 +#define SQLITE_FCNTL_SIZE_HINT 5 +#define SQLITE_FCNTL_CHUNK_SIZE 6 +#define SQLITE_FCNTL_FILE_POINTER 7 +#define SQLITE_FCNTL_SYNC_OMITTED 8 +#define SQLITE_FCNTL_WIN32_AV_RETRY 9 +#define SQLITE_FCNTL_PERSIST_WAL 10 +#define SQLITE_FCNTL_OVERWRITE 11 +#define SQLITE_FCNTL_VFSNAME 12 +#define SQLITE_FCNTL_POWERSAFE_OVERWRITE 13 + +/* +** CAPI3REF: Mutex Handle +** +** The mutex module within SQLite defines [sqlite3_mutex] to be an +** abstract type for a mutex object. The SQLite core never looks +** at the internal representation of an [sqlite3_mutex]. It only +** deals with pointers to the [sqlite3_mutex] object. +** +** Mutexes are created using [sqlite3_mutex_alloc()]. +*/ +typedef struct sqlite3_mutex sqlite3_mutex; + +/* +** CAPI3REF: OS Interface Object +** +** An instance of the sqlite3_vfs object defines the interface between +** the SQLite core and the underlying operating system. The "vfs" +** in the name of the object stands for "virtual file system". See +** the [VFS | VFS documentation] for further information. +** +** The value of the iVersion field is initially 1 but may be larger in +** future versions of SQLite. Additional fields may be appended to this +** object when the iVersion value is increased. Note that the structure +** of the sqlite3_vfs object changes in the transaction between +** SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not +** modified. +** +** The szOsFile field is the size of the subclassed [sqlite3_file] +** structure used by this VFS. mxPathname is the maximum length of +** a pathname in this VFS. +** +** Registered sqlite3_vfs objects are kept on a linked list formed by +** the pNext pointer. The [sqlite3_vfs_register()] +** and [sqlite3_vfs_unregister()] interfaces manage this list +** in a thread-safe way. The [sqlite3_vfs_find()] interface +** searches the list. Neither the application code nor the VFS +** implementation should use the pNext pointer. +** +** The pNext field is the only field in the sqlite3_vfs +** structure that SQLite will ever modify. SQLite will only access +** or modify this field while holding a particular static mutex. +** The application should never modify anything within the sqlite3_vfs +** object once the object has been registered. +** +** The zName field holds the name of the VFS module. The name must +** be unique across all VFS modules. +** +** [[sqlite3_vfs.xOpen]] +** ^SQLite guarantees that the zFilename parameter to xOpen +** is either a NULL pointer or string obtained +** from xFullPathname() with an optional suffix added. +** ^If a suffix is added to the zFilename parameter, it will +** consist of a single "-" character followed by no more than +** 11 alphanumeric and/or "-" characters. +** ^SQLite further guarantees that +** the string will be valid and unchanged until xClose() is +** called. Because of the previous sentence, +** the [sqlite3_file] can safely store a pointer to the +** filename if it needs to remember the filename for some reason. +** If the zFilename parameter to xOpen is a NULL pointer then xOpen +** must invent its own temporary name for the file. ^Whenever the +** xFilename parameter is NULL it will also be the case that the +** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE]. +** +** The flags argument to xOpen() includes all bits set in +** the flags argument to [sqlite3_open_v2()]. Or if [sqlite3_open()] +** or [sqlite3_open16()] is used, then flags includes at least +** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. +** If xOpen() opens a file read-only then it sets *pOutFlags to +** include [SQLITE_OPEN_READONLY]. Other bits in *pOutFlags may be set. +** +** ^(SQLite will also add one of the following flags to the xOpen() +** call, depending on the object being opened: +** +**
    +**
  • [SQLITE_OPEN_MAIN_DB] +**
  • [SQLITE_OPEN_MAIN_JOURNAL] +**
  • [SQLITE_OPEN_TEMP_DB] +**
  • [SQLITE_OPEN_TEMP_JOURNAL] +**
  • [SQLITE_OPEN_TRANSIENT_DB] +**
  • [SQLITE_OPEN_SUBJOURNAL] +**
  • [SQLITE_OPEN_MASTER_JOURNAL] +**
  • [SQLITE_OPEN_WAL] +**
)^ +** +** The file I/O implementation can use the object type flags to +** change the way it deals with files. For example, an application +** that does not care about crash recovery or rollback might make +** the open of a journal file a no-op. Writes to this journal would +** also be no-ops, and any attempt to read the journal would return +** SQLITE_IOERR. Or the implementation might recognize that a database +** file will be doing page-aligned sector reads and writes in a random +** order and set up its I/O subsystem accordingly. +** +** SQLite might also add one of the following flags to the xOpen method: +** +**
    +**
  • [SQLITE_OPEN_DELETEONCLOSE] +**
  • [SQLITE_OPEN_EXCLUSIVE] +**
+** +** The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be +** deleted when it is closed. ^The [SQLITE_OPEN_DELETEONCLOSE] +** will be set for TEMP databases and their journals, transient +** databases, and subjournals. +** +** ^The [SQLITE_OPEN_EXCLUSIVE] flag is always used in conjunction +** with the [SQLITE_OPEN_CREATE] flag, which are both directly +** analogous to the O_EXCL and O_CREAT flags of the POSIX open() +** API. The SQLITE_OPEN_EXCLUSIVE flag, when paired with the +** SQLITE_OPEN_CREATE, is used to indicate that file should always +** be created, and that it is an error if it already exists. +** It is not used to indicate the file should be opened +** for exclusive access. +** +** ^At least szOsFile bytes of memory are allocated by SQLite +** to hold the [sqlite3_file] structure passed as the third +** argument to xOpen. The xOpen method does not have to +** allocate the structure; it should just fill it in. Note that +** the xOpen method must set the sqlite3_file.pMethods to either +** a valid [sqlite3_io_methods] object or to NULL. xOpen must do +** this even if the open fails. SQLite expects that the sqlite3_file.pMethods +** element will be valid after xOpen returns regardless of the success +** or failure of the xOpen call. +** +** [[sqlite3_vfs.xAccess]] +** ^The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS] +** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to +** test whether a file is readable and writable, or [SQLITE_ACCESS_READ] +** to test whether a file is at least readable. The file can be a +** directory. +** +** ^SQLite will always allocate at least mxPathname+1 bytes for the +** output buffer xFullPathname. The exact size of the output buffer +** is also passed as a parameter to both methods. If the output buffer +** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is +** handled as a fatal error by SQLite, vfs implementations should endeavor +** to prevent this by setting mxPathname to a sufficiently large value. +** +** The xRandomness(), xSleep(), xCurrentTime(), and xCurrentTimeInt64() +** interfaces are not strictly a part of the filesystem, but they are +** included in the VFS structure for completeness. +** The xRandomness() function attempts to return nBytes bytes +** of good-quality randomness into zOut. The return value is +** the actual number of bytes of randomness obtained. +** The xSleep() method causes the calling thread to sleep for at +** least the number of microseconds given. ^The xCurrentTime() +** method returns a Julian Day Number for the current date and time as +** a floating point value. +** ^The xCurrentTimeInt64() method returns, as an integer, the Julian +** Day Number multiplied by 86400000 (the number of milliseconds in +** a 24-hour day). +** ^SQLite will use the xCurrentTimeInt64() method to get the current +** date and time if that method is available (if iVersion is 2 or +** greater and the function pointer is not NULL) and will fall back +** to xCurrentTime() if xCurrentTimeInt64() is unavailable. +** +** ^The xSetSystemCall(), xGetSystemCall(), and xNestSystemCall() interfaces +** are not used by the SQLite core. These optional interfaces are provided +** by some VFSes to facilitate testing of the VFS code. By overriding +** system calls with functions under its control, a test program can +** simulate faults and error conditions that would otherwise be difficult +** or impossible to induce. The set of system calls that can be overridden +** varies from one VFS to another, and from one version of the same VFS to the +** next. Applications that use these interfaces must be prepared for any +** or all of these interfaces to be NULL or for their behavior to change +** from one release to the next. Applications must not attempt to access +** any of these methods if the iVersion of the VFS is less than 3. +*/ +typedef struct sqlite3_vfs sqlite3_vfs; +typedef void (*sqlite3_syscall_ptr)(void); +struct sqlite3_vfs { + int iVersion; /* Structure version number (currently 3) */ + int szOsFile; /* Size of subclassed sqlite3_file */ + int mxPathname; /* Maximum file pathname length */ + sqlite3_vfs *pNext; /* Next registered VFS */ + const char *zName; /* Name of this virtual file system */ + void *pAppData; /* Pointer to application-specific data */ + int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, + int flags, int *pOutFlags); + int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); + int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut); + int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); + void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); + void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg); + void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void); + void (*xDlClose)(sqlite3_vfs*, void*); + int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut); + int (*xSleep)(sqlite3_vfs*, int microseconds); + int (*xCurrentTime)(sqlite3_vfs*, double*); + int (*xGetLastError)(sqlite3_vfs*, int, char *); + /* + ** The methods above are in version 1 of the sqlite_vfs object + ** definition. Those that follow are added in version 2 or later + */ + int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*); + /* + ** The methods above are in versions 1 and 2 of the sqlite_vfs object. + ** Those below are for version 3 and greater. + */ + int (*xSetSystemCall)(sqlite3_vfs*, const char *zName, sqlite3_syscall_ptr); + sqlite3_syscall_ptr (*xGetSystemCall)(sqlite3_vfs*, const char *zName); + const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName); + /* + ** The methods above are in versions 1 through 3 of the sqlite_vfs object. + ** New fields may be appended in figure versions. The iVersion + ** value will increment whenever this happens. + */ +}; + +/* +** CAPI3REF: Flags for the xAccess VFS method +** +** These integer constants can be used as the third parameter to +** the xAccess method of an [sqlite3_vfs] object. They determine +** what kind of permissions the xAccess method is looking for. +** With SQLITE_ACCESS_EXISTS, the xAccess method +** simply checks whether the file exists. +** With SQLITE_ACCESS_READWRITE, the xAccess method +** checks whether the named directory is both readable and writable +** (in other words, if files can be added, removed, and renamed within +** the directory). +** The SQLITE_ACCESS_READWRITE constant is currently used only by the +** [temp_store_directory pragma], though this could change in a future +** release of SQLite. +** With SQLITE_ACCESS_READ, the xAccess method +** checks whether the file is readable. The SQLITE_ACCESS_READ constant is +** currently unused, though it might be used in a future release of +** SQLite. +*/ +#define SQLITE_ACCESS_EXISTS 0 +#define SQLITE_ACCESS_READWRITE 1 /* Used by PRAGMA temp_store_directory */ +#define SQLITE_ACCESS_READ 2 /* Unused */ + +/* +** CAPI3REF: Flags for the xShmLock VFS method +** +** These integer constants define the various locking operations +** allowed by the xShmLock method of [sqlite3_io_methods]. The +** following are the only legal combinations of flags to the +** xShmLock method: +** +**
    +**
  • SQLITE_SHM_LOCK | SQLITE_SHM_SHARED +**
  • SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE +**
  • SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED +**
  • SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE +**
+** +** When unlocking, the same SHARED or EXCLUSIVE flag must be supplied as +** was given no the corresponding lock. +** +** The xShmLock method can transition between unlocked and SHARED or +** between unlocked and EXCLUSIVE. It cannot transition between SHARED +** and EXCLUSIVE. +*/ +#define SQLITE_SHM_UNLOCK 1 +#define SQLITE_SHM_LOCK 2 +#define SQLITE_SHM_SHARED 4 +#define SQLITE_SHM_EXCLUSIVE 8 + +/* +** CAPI3REF: Maximum xShmLock index +** +** The xShmLock method on [sqlite3_io_methods] may use values +** between 0 and this upper bound as its "offset" argument. +** The SQLite core will never attempt to acquire or release a +** lock outside of this range +*/ +#define SQLITE_SHM_NLOCK 8 + + +/* +** CAPI3REF: Initialize The SQLite Library +** +** ^The sqlite3_initialize() routine initializes the +** SQLite library. ^The sqlite3_shutdown() routine +** deallocates any resources that were allocated by sqlite3_initialize(). +** These routines are designed to aid in process initialization and +** shutdown on embedded systems. Workstation applications using +** SQLite normally do not need to invoke either of these routines. +** +** A call to sqlite3_initialize() is an "effective" call if it is +** the first time sqlite3_initialize() is invoked during the lifetime of +** the process, or if it is the first time sqlite3_initialize() is invoked +** following a call to sqlite3_shutdown(). ^(Only an effective call +** of sqlite3_initialize() does any initialization. All other calls +** are harmless no-ops.)^ +** +** A call to sqlite3_shutdown() is an "effective" call if it is the first +** call to sqlite3_shutdown() since the last sqlite3_initialize(). ^(Only +** an effective call to sqlite3_shutdown() does any deinitialization. +** All other valid calls to sqlite3_shutdown() are harmless no-ops.)^ +** +** The sqlite3_initialize() interface is threadsafe, but sqlite3_shutdown() +** is not. The sqlite3_shutdown() interface must only be called from a +** single thread. All open [database connections] must be closed and all +** other SQLite resources must be deallocated prior to invoking +** sqlite3_shutdown(). +** +** Among other things, ^sqlite3_initialize() will invoke +** sqlite3_os_init(). Similarly, ^sqlite3_shutdown() +** will invoke sqlite3_os_end(). +** +** ^The sqlite3_initialize() routine returns [SQLITE_OK] on success. +** ^If for some reason, sqlite3_initialize() is unable to initialize +** the library (perhaps it is unable to allocate a needed resource such +** as a mutex) it returns an [error code] other than [SQLITE_OK]. +** +** ^The sqlite3_initialize() routine is called internally by many other +** SQLite interfaces so that an application usually does not need to +** invoke sqlite3_initialize() directly. For example, [sqlite3_open()] +** calls sqlite3_initialize() so the SQLite library will be automatically +** initialized when [sqlite3_open()] is called if it has not be initialized +** already. ^However, if SQLite is compiled with the [SQLITE_OMIT_AUTOINIT] +** compile-time option, then the automatic calls to sqlite3_initialize() +** are omitted and the application must call sqlite3_initialize() directly +** prior to using any other SQLite interface. For maximum portability, +** it is recommended that applications always invoke sqlite3_initialize() +** directly prior to using any other SQLite interface. Future releases +** of SQLite may require this. In other words, the behavior exhibited +** when SQLite is compiled with [SQLITE_OMIT_AUTOINIT] might become the +** default behavior in some future release of SQLite. +** +** The sqlite3_os_init() routine does operating-system specific +** initialization of the SQLite library. The sqlite3_os_end() +** routine undoes the effect of sqlite3_os_init(). Typical tasks +** performed by these routines include allocation or deallocation +** of static resources, initialization of global variables, +** setting up a default [sqlite3_vfs] module, or setting up +** a default configuration using [sqlite3_config()]. +** +** The application should never invoke either sqlite3_os_init() +** or sqlite3_os_end() directly. The application should only invoke +** sqlite3_initialize() and sqlite3_shutdown(). The sqlite3_os_init() +** interface is called automatically by sqlite3_initialize() and +** sqlite3_os_end() is called by sqlite3_shutdown(). Appropriate +** implementations for sqlite3_os_init() and sqlite3_os_end() +** are built into SQLite when it is compiled for Unix, Windows, or OS/2. +** When [custom builds | built for other platforms] +** (using the [SQLITE_OS_OTHER=1] compile-time +** option) the application must supply a suitable implementation for +** sqlite3_os_init() and sqlite3_os_end(). An application-supplied +** implementation of sqlite3_os_init() or sqlite3_os_end() +** must return [SQLITE_OK] on success and some other [error code] upon +** failure. +*/ +SQLITE_API int sqlite3_initialize(void); +SQLITE_API int sqlite3_shutdown(void); +SQLITE_API int sqlite3_os_init(void); +SQLITE_API int sqlite3_os_end(void); + +/* +** CAPI3REF: Configuring The SQLite Library +** +** The sqlite3_config() interface is used to make global configuration +** changes to SQLite in order to tune SQLite to the specific needs of +** the application. The default configuration is recommended for most +** applications and so this routine is usually not necessary. It is +** provided to support rare applications with unusual needs. +** +** The sqlite3_config() interface is not threadsafe. The application +** must insure that no other SQLite interfaces are invoked by other +** threads while sqlite3_config() is running. Furthermore, sqlite3_config() +** may only be invoked prior to library initialization using +** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()]. +** ^If sqlite3_config() is called after [sqlite3_initialize()] and before +** [sqlite3_shutdown()] then it will return SQLITE_MISUSE. +** Note, however, that ^sqlite3_config() can be called as part of the +** implementation of an application-defined [sqlite3_os_init()]. +** +** The first argument to sqlite3_config() is an integer +** [configuration option] that determines +** what property of SQLite is to be configured. Subsequent arguments +** vary depending on the [configuration option] +** in the first argument. +** +** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK]. +** ^If the option is unknown or SQLite is unable to set the option +** then this routine returns a non-zero [error code]. +*/ +SQLITE_API int sqlite3_config(int, ...); + +/* +** CAPI3REF: Configure database connections +** +** The sqlite3_db_config() interface is used to make configuration +** changes to a [database connection]. The interface is similar to +** [sqlite3_config()] except that the changes apply to a single +** [database connection] (specified in the first argument). +** +** The second argument to sqlite3_db_config(D,V,...) is the +** [SQLITE_DBCONFIG_LOOKASIDE | configuration verb] - an integer code +** that indicates what aspect of the [database connection] is being configured. +** Subsequent arguments vary depending on the configuration verb. +** +** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if +** the call is considered successful. +*/ +SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...); + +/* +** CAPI3REF: Memory Allocation Routines +** +** An instance of this object defines the interface between SQLite +** and low-level memory allocation routines. +** +** This object is used in only one place in the SQLite interface. +** A pointer to an instance of this object is the argument to +** [sqlite3_config()] when the configuration option is +** [SQLITE_CONFIG_MALLOC] or [SQLITE_CONFIG_GETMALLOC]. +** By creating an instance of this object +** and passing it to [sqlite3_config]([SQLITE_CONFIG_MALLOC]) +** during configuration, an application can specify an alternative +** memory allocation subsystem for SQLite to use for all of its +** dynamic memory needs. +** +** Note that SQLite comes with several [built-in memory allocators] +** that are perfectly adequate for the overwhelming majority of applications +** and that this object is only useful to a tiny minority of applications +** with specialized memory allocation requirements. This object is +** also used during testing of SQLite in order to specify an alternative +** memory allocator that simulates memory out-of-memory conditions in +** order to verify that SQLite recovers gracefully from such +** conditions. +** +** The xMalloc, xRealloc, and xFree methods must work like the +** malloc(), realloc() and free() functions from the standard C library. +** ^SQLite guarantees that the second argument to +** xRealloc is always a value returned by a prior call to xRoundup. +** +** xSize should return the allocated size of a memory allocation +** previously obtained from xMalloc or xRealloc. The allocated size +** is always at least as big as the requested size but may be larger. +** +** The xRoundup method returns what would be the allocated size of +** a memory allocation given a particular requested size. Most memory +** allocators round up memory allocations at least to the next multiple +** of 8. Some allocators round up to a larger multiple or to a power of 2. +** Every memory allocation request coming in through [sqlite3_malloc()] +** or [sqlite3_realloc()] first calls xRoundup. If xRoundup returns 0, +** that causes the corresponding memory allocation to fail. +** +** The xInit method initializes the memory allocator. (For example, +** it might allocate any require mutexes or initialize internal data +** structures. The xShutdown method is invoked (indirectly) by +** [sqlite3_shutdown()] and should deallocate any resources acquired +** by xInit. The pAppData pointer is used as the only parameter to +** xInit and xShutdown. +** +** SQLite holds the [SQLITE_MUTEX_STATIC_MASTER] mutex when it invokes +** the xInit method, so the xInit method need not be threadsafe. The +** xShutdown method is only called from [sqlite3_shutdown()] so it does +** not need to be threadsafe either. For all other methods, SQLite +** holds the [SQLITE_MUTEX_STATIC_MEM] mutex as long as the +** [SQLITE_CONFIG_MEMSTATUS] configuration option is turned on (which +** it is by default) and so the methods are automatically serialized. +** However, if [SQLITE_CONFIG_MEMSTATUS] is disabled, then the other +** methods must be threadsafe or else make their own arrangements for +** serialization. +** +** SQLite will never invoke xInit() more than once without an intervening +** call to xShutdown(). +*/ +typedef struct sqlite3_mem_methods sqlite3_mem_methods; +struct sqlite3_mem_methods { + void *(*xMalloc)(int); /* Memory allocation function */ + void (*xFree)(void*); /* Free a prior allocation */ + void *(*xRealloc)(void*,int); /* Resize an allocation */ + int (*xSize)(void*); /* Return the size of an allocation */ + int (*xRoundup)(int); /* Round up request size to allocation size */ + int (*xInit)(void*); /* Initialize the memory allocator */ + void (*xShutdown)(void*); /* Deinitialize the memory allocator */ + void *pAppData; /* Argument to xInit() and xShutdown() */ +}; + +/* +** CAPI3REF: Configuration Options +** KEYWORDS: {configuration option} +** +** These constants are the available integer configuration options that +** can be passed as the first argument to the [sqlite3_config()] interface. +** +** New configuration options may be added in future releases of SQLite. +** Existing configuration options might be discontinued. Applications +** should check the return code from [sqlite3_config()] to make sure that +** the call worked. The [sqlite3_config()] interface will return a +** non-zero [error code] if a discontinued or unsupported configuration option +** is invoked. +** +**
+** [[SQLITE_CONFIG_SINGLETHREAD]]
SQLITE_CONFIG_SINGLETHREAD
+**
There are no arguments to this option. ^This option sets the +** [threading mode] to Single-thread. In other words, it disables +** all mutexing and puts SQLite into a mode where it can only be used +** by a single thread. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** it is not possible to change the [threading mode] from its default +** value of Single-thread and so [sqlite3_config()] will return +** [SQLITE_ERROR] if called with the SQLITE_CONFIG_SINGLETHREAD +** configuration option.
+** +** [[SQLITE_CONFIG_MULTITHREAD]]
SQLITE_CONFIG_MULTITHREAD
+**
There are no arguments to this option. ^This option sets the +** [threading mode] to Multi-thread. In other words, it disables +** mutexing on [database connection] and [prepared statement] objects. +** The application is responsible for serializing access to +** [database connections] and [prepared statements]. But other mutexes +** are enabled so that SQLite will be safe to use in a multi-threaded +** environment as long as no two threads attempt to use the same +** [database connection] at the same time. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** it is not possible to set the Multi-thread [threading mode] and +** [sqlite3_config()] will return [SQLITE_ERROR] if called with the +** SQLITE_CONFIG_MULTITHREAD configuration option.
+** +** [[SQLITE_CONFIG_SERIALIZED]]
SQLITE_CONFIG_SERIALIZED
+**
There are no arguments to this option. ^This option sets the +** [threading mode] to Serialized. In other words, this option enables +** all mutexes including the recursive +** mutexes on [database connection] and [prepared statement] objects. +** In this mode (which is the default when SQLite is compiled with +** [SQLITE_THREADSAFE=1]) the SQLite library will itself serialize access +** to [database connections] and [prepared statements] so that the +** application is free to use the same [database connection] or the +** same [prepared statement] in different threads at the same time. +** ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** it is not possible to set the Serialized [threading mode] and +** [sqlite3_config()] will return [SQLITE_ERROR] if called with the +** SQLITE_CONFIG_SERIALIZED configuration option.
+** +** [[SQLITE_CONFIG_MALLOC]]
SQLITE_CONFIG_MALLOC
+**
^(This option takes a single argument which is a pointer to an +** instance of the [sqlite3_mem_methods] structure. The argument specifies +** alternative low-level memory allocation routines to be used in place of +** the memory allocation routines built into SQLite.)^ ^SQLite makes +** its own private copy of the content of the [sqlite3_mem_methods] structure +** before the [sqlite3_config()] call returns.
+** +** [[SQLITE_CONFIG_GETMALLOC]]
SQLITE_CONFIG_GETMALLOC
+**
^(This option takes a single argument which is a pointer to an +** instance of the [sqlite3_mem_methods] structure. The [sqlite3_mem_methods] +** structure is filled with the currently defined memory allocation routines.)^ +** This option can be used to overload the default memory allocation +** routines with a wrapper that simulations memory allocation failure or +** tracks memory usage, for example.
+** +** [[SQLITE_CONFIG_MEMSTATUS]]
SQLITE_CONFIG_MEMSTATUS
+**
^This option takes single argument of type int, interpreted as a +** boolean, which enables or disables the collection of memory allocation +** statistics. ^(When memory allocation statistics are disabled, the +** following SQLite interfaces become non-operational: +**
    +**
  • [sqlite3_memory_used()] +**
  • [sqlite3_memory_highwater()] +**
  • [sqlite3_soft_heap_limit64()] +**
  • [sqlite3_status()] +**
)^ +** ^Memory allocation statistics are enabled by default unless SQLite is +** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory +** allocation statistics are disabled by default. +**
+** +** [[SQLITE_CONFIG_SCRATCH]]
SQLITE_CONFIG_SCRATCH
+**
^This option specifies a static memory buffer that SQLite can use for +** scratch memory. There are three arguments: A pointer an 8-byte +** aligned memory buffer from which the scratch allocations will be +** drawn, the size of each scratch allocation (sz), +** and the maximum number of scratch allocations (N). The sz +** argument must be a multiple of 16. +** The first argument must be a pointer to an 8-byte aligned buffer +** of at least sz*N bytes of memory. +** ^SQLite will use no more than two scratch buffers per thread. So +** N should be set to twice the expected maximum number of threads. +** ^SQLite will never require a scratch buffer that is more than 6 +** times the database page size. ^If SQLite needs needs additional +** scratch memory beyond what is provided by this configuration option, then +** [sqlite3_malloc()] will be used to obtain the memory needed.
+** +** [[SQLITE_CONFIG_PAGECACHE]]
SQLITE_CONFIG_PAGECACHE
+**
^This option specifies a static memory buffer that SQLite can use for +** the database page cache with the default page cache implementation. +** This configuration should not be used if an application-define page +** cache implementation is loaded using the SQLITE_CONFIG_PCACHE2 option. +** There are three arguments to this option: A pointer to 8-byte aligned +** memory, the size of each page buffer (sz), and the number of pages (N). +** The sz argument should be the size of the largest database page +** (a power of two between 512 and 32768) plus a little extra for each +** page header. ^The page header size is 20 to 40 bytes depending on +** the host architecture. ^It is harmless, apart from the wasted memory, +** to make sz a little too large. The first +** argument should point to an allocation of at least sz*N bytes of memory. +** ^SQLite will use the memory provided by the first argument to satisfy its +** memory needs for the first N pages that it adds to cache. ^If additional +** page cache memory is needed beyond what is provided by this option, then +** SQLite goes to [sqlite3_malloc()] for the additional storage space. +** The pointer in the first argument must +** be aligned to an 8-byte boundary or subsequent behavior of SQLite +** will be undefined.
+** +** [[SQLITE_CONFIG_HEAP]]
SQLITE_CONFIG_HEAP
+**
^This option specifies a static memory buffer that SQLite will use +** for all of its dynamic memory allocation needs beyond those provided +** for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE]. +** There are three arguments: An 8-byte aligned pointer to the memory, +** the number of bytes in the memory buffer, and the minimum allocation size. +** ^If the first pointer (the memory pointer) is NULL, then SQLite reverts +** to using its default memory allocator (the system malloc() implementation), +** undoing any prior invocation of [SQLITE_CONFIG_MALLOC]. ^If the +** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or +** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory +** allocator is engaged to handle all of SQLites memory allocation needs. +** The first pointer (the memory pointer) must be aligned to an 8-byte +** boundary or subsequent behavior of SQLite will be undefined. +** The minimum allocation size is capped at 2**12. Reasonable values +** for the minimum allocation size are 2**5 through 2**8.
+** +** [[SQLITE_CONFIG_MUTEX]]
SQLITE_CONFIG_MUTEX
+**
^(This option takes a single argument which is a pointer to an +** instance of the [sqlite3_mutex_methods] structure. The argument specifies +** alternative low-level mutex routines to be used in place +** the mutex routines built into SQLite.)^ ^SQLite makes a copy of the +** content of the [sqlite3_mutex_methods] structure before the call to +** [sqlite3_config()] returns. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** the entire mutexing subsystem is omitted from the build and hence calls to +** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will +** return [SQLITE_ERROR].
+** +** [[SQLITE_CONFIG_GETMUTEX]]
SQLITE_CONFIG_GETMUTEX
+**
^(This option takes a single argument which is a pointer to an +** instance of the [sqlite3_mutex_methods] structure. The +** [sqlite3_mutex_methods] +** structure is filled with the currently defined mutex routines.)^ +** This option can be used to overload the default mutex allocation +** routines with a wrapper used to track mutex usage for performance +** profiling or testing, for example. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** the entire mutexing subsystem is omitted from the build and hence calls to +** [sqlite3_config()] with the SQLITE_CONFIG_GETMUTEX configuration option will +** return [SQLITE_ERROR].
+** +** [[SQLITE_CONFIG_LOOKASIDE]]
SQLITE_CONFIG_LOOKASIDE
+**
^(This option takes two arguments that determine the default +** memory allocation for the lookaside memory allocator on each +** [database connection]. The first argument is the +** size of each lookaside buffer slot and the second is the number of +** slots allocated to each database connection.)^ ^(This option sets the +** default lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE] +** verb to [sqlite3_db_config()] can be used to change the lookaside +** configuration on individual connections.)^
+** +** [[SQLITE_CONFIG_PCACHE2]]
SQLITE_CONFIG_PCACHE2
+**
^(This option takes a single argument which is a pointer to +** an [sqlite3_pcache_methods2] object. This object specifies the interface +** to a custom page cache implementation.)^ ^SQLite makes a copy of the +** object and uses it for page cache memory allocations.
+** +** [[SQLITE_CONFIG_GETPCACHE2]]
SQLITE_CONFIG_GETPCACHE2
+**
^(This option takes a single argument which is a pointer to an +** [sqlite3_pcache_methods2] object. SQLite copies of the current +** page cache implementation into that object.)^
+** +** [[SQLITE_CONFIG_LOG]]
SQLITE_CONFIG_LOG
+**
^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a +** function with a call signature of void(*)(void*,int,const char*), +** and a pointer to void. ^If the function pointer is not NULL, it is +** invoked by [sqlite3_log()] to process each logging event. ^If the +** function pointer is NULL, the [sqlite3_log()] interface becomes a no-op. +** ^The void pointer that is the second argument to SQLITE_CONFIG_LOG is +** passed through as the first parameter to the application-defined logger +** function whenever that function is invoked. ^The second parameter to +** the logger function is a copy of the first parameter to the corresponding +** [sqlite3_log()] call and is intended to be a [result code] or an +** [extended result code]. ^The third parameter passed to the logger is +** log message after formatting via [sqlite3_snprintf()]. +** The SQLite logging interface is not reentrant; the logger function +** supplied by the application must not invoke any SQLite interface. +** In a multi-threaded application, the application-defined logger +** function must be threadsafe.
+** +** [[SQLITE_CONFIG_URI]]
SQLITE_CONFIG_URI +**
This option takes a single argument of type int. If non-zero, then +** URI handling is globally enabled. If the parameter is zero, then URI handling +** is globally disabled. If URI handling is globally enabled, all filenames +** passed to [sqlite3_open()], [sqlite3_open_v2()], [sqlite3_open16()] or +** specified as part of [ATTACH] commands are interpreted as URIs, regardless +** of whether or not the [SQLITE_OPEN_URI] flag is set when the database +** connection is opened. If it is globally disabled, filenames are +** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the +** database connection is opened. By default, URI handling is globally +** disabled. The default value may be changed by compiling with the +** [SQLITE_USE_URI] symbol defined. +** +** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]] +**
SQLITE_CONFIG_PCACHE and SQLITE_CONFNIG_GETPCACHE +**
These options are obsolete and should not be used by new code. +** They are retained for backwards compatibility but are now no-ops. +**
+*/ +#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ +#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ +#define SQLITE_CONFIG_SERIALIZED 3 /* nil */ +#define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */ +#define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */ +#define SQLITE_CONFIG_SCRATCH 6 /* void*, int sz, int N */ +#define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */ +#define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */ +#define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */ +#define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */ +#define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */ +/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ +#define SQLITE_CONFIG_LOOKASIDE 13 /* int int */ +#define SQLITE_CONFIG_PCACHE 14 /* no-op */ +#define SQLITE_CONFIG_GETPCACHE 15 /* no-op */ +#define SQLITE_CONFIG_LOG 16 /* xFunc, void* */ +#define SQLITE_CONFIG_URI 17 /* int */ +#define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */ +#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */ + +/* +** CAPI3REF: Database Connection Configuration Options +** +** These constants are the available integer configuration options that +** can be passed as the second argument to the [sqlite3_db_config()] interface. +** +** New configuration options may be added in future releases of SQLite. +** Existing configuration options might be discontinued. Applications +** should check the return code from [sqlite3_db_config()] to make sure that +** the call worked. ^The [sqlite3_db_config()] interface will return a +** non-zero [error code] if a discontinued or unsupported configuration option +** is invoked. +** +**
+**
SQLITE_DBCONFIG_LOOKASIDE
+**
^This option takes three additional arguments that determine the +** [lookaside memory allocator] configuration for the [database connection]. +** ^The first argument (the third parameter to [sqlite3_db_config()] is a +** pointer to a memory buffer to use for lookaside memory. +** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb +** may be NULL in which case SQLite will allocate the +** lookaside buffer itself using [sqlite3_malloc()]. ^The second argument is the +** size of each lookaside buffer slot. ^The third argument is the number of +** slots. The size of the buffer in the first argument must be greater than +** or equal to the product of the second and third arguments. The buffer +** must be aligned to an 8-byte boundary. ^If the second argument to +** SQLITE_DBCONFIG_LOOKASIDE is not a multiple of 8, it is internally +** rounded down to the next smaller multiple of 8. ^(The lookaside memory +** configuration for a database connection can only be changed when that +** connection is not currently using lookaside memory, or in other words +** when the "current value" returned by +** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero. +** Any attempt to change the lookaside memory configuration when lookaside +** memory is in use leaves the configuration unchanged and returns +** [SQLITE_BUSY].)^
+** +**
SQLITE_DBCONFIG_ENABLE_FKEY
+**
^This option is used to enable or disable the enforcement of +** [foreign key constraints]. There should be two additional arguments. +** The first argument is an integer which is 0 to disable FK enforcement, +** positive to enable FK enforcement or negative to leave FK enforcement +** unchanged. The second parameter is a pointer to an integer into which +** is written 0 or 1 to indicate whether FK enforcement is off or on +** following this call. The second parameter may be a NULL pointer, in +** which case the FK enforcement setting is not reported back.
+** +**
SQLITE_DBCONFIG_ENABLE_TRIGGER
+**
^This option is used to enable or disable [CREATE TRIGGER | triggers]. +** There should be two additional arguments. +** The first argument is an integer which is 0 to disable triggers, +** positive to enable triggers or negative to leave the setting unchanged. +** The second parameter is a pointer to an integer into which +** is written 0 or 1 to indicate whether triggers are disabled or enabled +** following this call. The second parameter may be a NULL pointer, in +** which case the trigger setting is not reported back.
+** +**
+*/ +#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ +#define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */ +#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ + + +/* +** CAPI3REF: Enable Or Disable Extended Result Codes +** +** ^The sqlite3_extended_result_codes() routine enables or disables the +** [extended result codes] feature of SQLite. ^The extended result +** codes are disabled by default for historical compatibility. +*/ +SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff); + +/* +** CAPI3REF: Last Insert Rowid +** +** ^Each entry in an SQLite table has a unique 64-bit signed +** integer key called the [ROWID | "rowid"]. ^The rowid is always available +** as an undeclared column named ROWID, OID, or _ROWID_ as long as those +** names are not also used by explicitly declared columns. ^If +** the table has a column of type [INTEGER PRIMARY KEY] then that column +** is another alias for the rowid. +** +** ^This routine returns the [rowid] of the most recent +** successful [INSERT] into the database from the [database connection] +** in the first argument. ^As of SQLite version 3.7.7, this routines +** records the last insert rowid of both ordinary tables and [virtual tables]. +** ^If no successful [INSERT]s +** have ever occurred on that database connection, zero is returned. +** +** ^(If an [INSERT] occurs within a trigger or within a [virtual table] +** method, then this routine will return the [rowid] of the inserted +** row as long as the trigger or virtual table method is running. +** But once the trigger or virtual table method ends, the value returned +** by this routine reverts to what it was before the trigger or virtual +** table method began.)^ +** +** ^An [INSERT] that fails due to a constraint violation is not a +** successful [INSERT] and does not change the value returned by this +** routine. ^Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK, +** and INSERT OR ABORT make no changes to the return value of this +** routine when their insertion fails. ^(When INSERT OR REPLACE +** encounters a constraint violation, it does not fail. The +** INSERT continues to completion after deleting rows that caused +** the constraint problem so INSERT OR REPLACE will always change +** the return value of this interface.)^ +** +** ^For the purposes of this routine, an [INSERT] is considered to +** be successful even if it is subsequently rolled back. +** +** This function is accessible to SQL statements via the +** [last_insert_rowid() SQL function]. +** +** If a separate thread performs a new [INSERT] on the same +** database connection while the [sqlite3_last_insert_rowid()] +** function is running and thus changes the last insert [rowid], +** then the value returned by [sqlite3_last_insert_rowid()] is +** unpredictable and might not equal either the old or the new +** last insert [rowid]. +*/ +SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); + +/* +** CAPI3REF: Count The Number Of Rows Modified +** +** ^This function returns the number of database rows that were changed +** or inserted or deleted by the most recently completed SQL statement +** on the [database connection] specified by the first parameter. +** ^(Only changes that are directly specified by the [INSERT], [UPDATE], +** or [DELETE] statement are counted. Auxiliary changes caused by +** triggers or [foreign key actions] are not counted.)^ Use the +** [sqlite3_total_changes()] function to find the total number of changes +** including changes caused by triggers and foreign key actions. +** +** ^Changes to a view that are simulated by an [INSTEAD OF trigger] +** are not counted. Only real table changes are counted. +** +** ^(A "row change" is a change to a single row of a single table +** caused by an INSERT, DELETE, or UPDATE statement. Rows that +** are changed as side effects of [REPLACE] constraint resolution, +** rollback, ABORT processing, [DROP TABLE], or by any other +** mechanisms do not count as direct row changes.)^ +** +** A "trigger context" is a scope of execution that begins and +** ends with the script of a [CREATE TRIGGER | trigger]. +** Most SQL statements are +** evaluated outside of any trigger. This is the "top level" +** trigger context. If a trigger fires from the top level, a +** new trigger context is entered for the duration of that one +** trigger. Subtriggers create subcontexts for their duration. +** +** ^Calling [sqlite3_exec()] or [sqlite3_step()] recursively does +** not create a new trigger context. +** +** ^This function returns the number of direct row changes in the +** most recent INSERT, UPDATE, or DELETE statement within the same +** trigger context. +** +** ^Thus, when called from the top level, this function returns the +** number of changes in the most recent INSERT, UPDATE, or DELETE +** that also occurred at the top level. ^(Within the body of a trigger, +** the sqlite3_changes() interface can be called to find the number of +** changes in the most recently completed INSERT, UPDATE, or DELETE +** statement within the body of the same trigger. +** However, the number returned does not include changes +** caused by subtriggers since those have their own context.)^ +** +** See also the [sqlite3_total_changes()] interface, the +** [count_changes pragma], and the [changes() SQL function]. +** +** If a separate thread makes changes on the same database connection +** while [sqlite3_changes()] is running then the value returned +** is unpredictable and not meaningful. +*/ +SQLITE_API int sqlite3_changes(sqlite3*); + +/* +** CAPI3REF: Total Number Of Rows Modified +** +** ^This function returns the number of row changes caused by [INSERT], +** [UPDATE] or [DELETE] statements since the [database connection] was opened. +** ^(The count returned by sqlite3_total_changes() includes all changes +** from all [CREATE TRIGGER | trigger] contexts and changes made by +** [foreign key actions]. However, +** the count does not include changes used to implement [REPLACE] constraints, +** do rollbacks or ABORT processing, or [DROP TABLE] processing. The +** count does not include rows of views that fire an [INSTEAD OF trigger], +** though if the INSTEAD OF trigger makes changes of its own, those changes +** are counted.)^ +** ^The sqlite3_total_changes() function counts the changes as soon as +** the statement that makes them is completed (when the statement handle +** is passed to [sqlite3_reset()] or [sqlite3_finalize()]). +** +** See also the [sqlite3_changes()] interface, the +** [count_changes pragma], and the [total_changes() SQL function]. +** +** If a separate thread makes changes on the same database connection +** while [sqlite3_total_changes()] is running then the value +** returned is unpredictable and not meaningful. +*/ +SQLITE_API int sqlite3_total_changes(sqlite3*); + +/* +** CAPI3REF: Interrupt A Long-Running Query +** +** ^This function causes any pending database operation to abort and +** return at its earliest opportunity. This routine is typically +** called in response to a user action such as pressing "Cancel" +** or Ctrl-C where the user wants a long query operation to halt +** immediately. +** +** ^It is safe to call this routine from a thread different from the +** thread that is currently running the database operation. But it +** is not safe to call this routine with a [database connection] that +** is closed or might close before sqlite3_interrupt() returns. +** +** ^If an SQL operation is very nearly finished at the time when +** sqlite3_interrupt() is called, then it might not have an opportunity +** to be interrupted and might continue to completion. +** +** ^An SQL operation that is interrupted will return [SQLITE_INTERRUPT]. +** ^If the interrupted SQL operation is an INSERT, UPDATE, or DELETE +** that is inside an explicit transaction, then the entire transaction +** will be rolled back automatically. +** +** ^The sqlite3_interrupt(D) call is in effect until all currently running +** SQL statements on [database connection] D complete. ^Any new SQL statements +** that are started after the sqlite3_interrupt() call and before the +** running statements reaches zero are interrupted as if they had been +** running prior to the sqlite3_interrupt() call. ^New SQL statements +** that are started after the running statement count reaches zero are +** not effected by the sqlite3_interrupt(). +** ^A call to sqlite3_interrupt(D) that occurs when there are no running +** SQL statements is a no-op and has no effect on SQL statements +** that are started after the sqlite3_interrupt() call returns. +** +** If the database connection closes while [sqlite3_interrupt()] +** is running then bad things will likely happen. +*/ +SQLITE_API void sqlite3_interrupt(sqlite3*); + +/* +** CAPI3REF: Determine If An SQL Statement Is Complete +** +** These routines are useful during command-line input to determine if the +** currently entered text seems to form a complete SQL statement or +** if additional input is needed before sending the text into +** SQLite for parsing. ^These routines return 1 if the input string +** appears to be a complete SQL statement. ^A statement is judged to be +** complete if it ends with a semicolon token and is not a prefix of a +** well-formed CREATE TRIGGER statement. ^Semicolons that are embedded within +** string literals or quoted identifier names or comments are not +** independent tokens (they are part of the token in which they are +** embedded) and thus do not count as a statement terminator. ^Whitespace +** and comments that follow the final semicolon are ignored. +** +** ^These routines return 0 if the statement is incomplete. ^If a +** memory allocation fails, then SQLITE_NOMEM is returned. +** +** ^These routines do not parse the SQL statements thus +** will not detect syntactically incorrect SQL. +** +** ^(If SQLite has not been initialized using [sqlite3_initialize()] prior +** to invoking sqlite3_complete16() then sqlite3_initialize() is invoked +** automatically by sqlite3_complete16(). If that initialization fails, +** then the return value from sqlite3_complete16() will be non-zero +** regardless of whether or not the input SQL is complete.)^ +** +** The input to [sqlite3_complete()] must be a zero-terminated +** UTF-8 string. +** +** The input to [sqlite3_complete16()] must be a zero-terminated +** UTF-16 string in native byte order. +*/ +SQLITE_API int sqlite3_complete(const char *sql); +SQLITE_API int sqlite3_complete16(const void *sql); + +/* +** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors +** +** ^This routine sets a callback function that might be invoked whenever +** an attempt is made to open a database table that another thread +** or process has locked. +** +** ^If the busy callback is NULL, then [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] +** is returned immediately upon encountering the lock. ^If the busy callback +** is not NULL, then the callback might be invoked with two arguments. +** +** ^The first argument to the busy handler is a copy of the void* pointer which +** is the third argument to sqlite3_busy_handler(). ^The second argument to +** the busy handler callback is the number of times that the busy handler has +** been invoked for this locking event. ^If the +** busy callback returns 0, then no additional attempts are made to +** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned. +** ^If the callback returns non-zero, then another attempt +** is made to open the database for reading and the cycle repeats. +** +** The presence of a busy handler does not guarantee that it will be invoked +** when there is lock contention. ^If SQLite determines that invoking the busy +** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY] +** or [SQLITE_IOERR_BLOCKED] instead of invoking the busy handler. +** Consider a scenario where one process is holding a read lock that +** it is trying to promote to a reserved lock and +** a second process is holding a reserved lock that it is trying +** to promote to an exclusive lock. The first process cannot proceed +** because it is blocked by the second and the second process cannot +** proceed because it is blocked by the first. If both processes +** invoke the busy handlers, neither will make any progress. Therefore, +** SQLite returns [SQLITE_BUSY] for the first process, hoping that this +** will induce the first process to release its read lock and allow +** the second process to proceed. +** +** ^The default busy callback is NULL. +** +** ^The [SQLITE_BUSY] error is converted to [SQLITE_IOERR_BLOCKED] +** when SQLite is in the middle of a large transaction where all the +** changes will not fit into the in-memory cache. SQLite will +** already hold a RESERVED lock on the database file, but it needs +** to promote this lock to EXCLUSIVE so that it can spill cache +** pages into the database file without harm to concurrent +** readers. ^If it is unable to promote the lock, then the in-memory +** cache will be left in an inconsistent state and so the error +** code is promoted from the relatively benign [SQLITE_BUSY] to +** the more severe [SQLITE_IOERR_BLOCKED]. ^This error code promotion +** forces an automatic rollback of the changes. See the +** +** CorruptionFollowingBusyError wiki page for a discussion of why +** this is important. +** +** ^(There can only be a single busy handler defined for each +** [database connection]. Setting a new busy handler clears any +** previously set handler.)^ ^Note that calling [sqlite3_busy_timeout()] +** will also set or clear the busy handler. +** +** The busy callback should not take any actions which modify the +** database connection that invoked the busy handler. Any such actions +** result in undefined behavior. +** +** A busy handler must not close the database connection +** or [prepared statement] that invoked the busy handler. +*/ +SQLITE_API int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); + +/* +** CAPI3REF: Set A Busy Timeout +** +** ^This routine sets a [sqlite3_busy_handler | busy handler] that sleeps +** for a specified amount of time when a table is locked. ^The handler +** will sleep multiple times until at least "ms" milliseconds of sleeping +** have accumulated. ^After at least "ms" milliseconds of sleeping, +** the handler returns 0 which causes [sqlite3_step()] to return +** [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED]. +** +** ^Calling this routine with an argument less than or equal to zero +** turns off all busy handlers. +** +** ^(There can only be a single busy handler for a particular +** [database connection] any any given moment. If another busy handler +** was defined (using [sqlite3_busy_handler()]) prior to calling +** this routine, that other busy handler is cleared.)^ +*/ +SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); + +/* +** CAPI3REF: Convenience Routines For Running Queries +** +** This is a legacy interface that is preserved for backwards compatibility. +** Use of this interface is not recommended. +** +** Definition: A result table is memory data structure created by the +** [sqlite3_get_table()] interface. A result table records the +** complete query results from one or more queries. +** +** The table conceptually has a number of rows and columns. But +** these numbers are not part of the result table itself. These +** numbers are obtained separately. Let N be the number of rows +** and M be the number of columns. +** +** A result table is an array of pointers to zero-terminated UTF-8 strings. +** There are (N+1)*M elements in the array. The first M pointers point +** to zero-terminated strings that contain the names of the columns. +** The remaining entries all point to query results. NULL values result +** in NULL pointers. All other values are in their UTF-8 zero-terminated +** string representation as returned by [sqlite3_column_text()]. +** +** A result table might consist of one or more memory allocations. +** It is not safe to pass a result table directly to [sqlite3_free()]. +** A result table should be deallocated using [sqlite3_free_table()]. +** +** ^(As an example of the result table format, suppose a query result +** is as follows: +** +**
+**        Name        | Age
+**        -----------------------
+**        Alice       | 43
+**        Bob         | 28
+**        Cindy       | 21
+** 
+** +** There are two column (M==2) and three rows (N==3). Thus the +** result table has 8 entries. Suppose the result table is stored +** in an array names azResult. Then azResult holds this content: +** +**
+**        azResult[0] = "Name";
+**        azResult[1] = "Age";
+**        azResult[2] = "Alice";
+**        azResult[3] = "43";
+**        azResult[4] = "Bob";
+**        azResult[5] = "28";
+**        azResult[6] = "Cindy";
+**        azResult[7] = "21";
+** 
)^ +** +** ^The sqlite3_get_table() function evaluates one or more +** semicolon-separated SQL statements in the zero-terminated UTF-8 +** string of its 2nd parameter and returns a result table to the +** pointer given in its 3rd parameter. +** +** After the application has finished with the result from sqlite3_get_table(), +** it must pass the result table pointer to sqlite3_free_table() in order to +** release the memory that was malloced. Because of the way the +** [sqlite3_malloc()] happens within sqlite3_get_table(), the calling +** function must not try to call [sqlite3_free()] directly. Only +** [sqlite3_free_table()] is able to release the memory properly and safely. +** +** The sqlite3_get_table() interface is implemented as a wrapper around +** [sqlite3_exec()]. The sqlite3_get_table() routine does not have access +** to any internal data structures of SQLite. It uses only the public +** interface defined here. As a consequence, errors that occur in the +** wrapper layer outside of the internal [sqlite3_exec()] call are not +** reflected in subsequent calls to [sqlite3_errcode()] or +** [sqlite3_errmsg()]. +*/ +SQLITE_API int sqlite3_get_table( + sqlite3 *db, /* An open database */ + const char *zSql, /* SQL to be evaluated */ + char ***pazResult, /* Results of the query */ + int *pnRow, /* Number of result rows written here */ + int *pnColumn, /* Number of result columns written here */ + char **pzErrmsg /* Error msg written here */ +); +SQLITE_API void sqlite3_free_table(char **result); + +/* +** CAPI3REF: Formatted String Printing Functions +** +** These routines are work-alikes of the "printf()" family of functions +** from the standard C library. +** +** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their +** results into memory obtained from [sqlite3_malloc()]. +** The strings returned by these two routines should be +** released by [sqlite3_free()]. ^Both routines return a +** NULL pointer if [sqlite3_malloc()] is unable to allocate enough +** memory to hold the resulting string. +** +** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from +** the standard C library. The result is written into the +** buffer supplied as the second parameter whose size is given by +** the first parameter. Note that the order of the +** first two parameters is reversed from snprintf().)^ This is an +** historical accident that cannot be fixed without breaking +** backwards compatibility. ^(Note also that sqlite3_snprintf() +** returns a pointer to its buffer instead of the number of +** characters actually written into the buffer.)^ We admit that +** the number of characters written would be a more useful return +** value but we cannot change the implementation of sqlite3_snprintf() +** now without breaking compatibility. +** +** ^As long as the buffer size is greater than zero, sqlite3_snprintf() +** guarantees that the buffer is always zero-terminated. ^The first +** parameter "n" is the total size of the buffer, including space for +** the zero terminator. So the longest string that can be completely +** written will be n-1 characters. +** +** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf(). +** +** These routines all implement some additional formatting +** options that are useful for constructing SQL statements. +** All of the usual printf() formatting options apply. In addition, there +** is are "%q", "%Q", and "%z" options. +** +** ^(The %q option works like %s in that it substitutes a nul-terminated +** string from the argument list. But %q also doubles every '\'' character. +** %q is designed for use inside a string literal.)^ By doubling each '\'' +** character it escapes that character and allows it to be inserted into +** the string. +** +** For example, assume the string variable zText contains text as follows: +** +**
+**  char *zText = "It's a happy day!";
+** 
+** +** One can use this text in an SQL statement as follows: +** +**
+**  char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText);
+**  sqlite3_exec(db, zSQL, 0, 0, 0);
+**  sqlite3_free(zSQL);
+** 
+** +** Because the %q format string is used, the '\'' character in zText +** is escaped and the SQL generated is as follows: +** +**
+**  INSERT INTO table1 VALUES('It''s a happy day!')
+** 
+** +** This is correct. Had we used %s instead of %q, the generated SQL +** would have looked like this: +** +**
+**  INSERT INTO table1 VALUES('It's a happy day!');
+** 
+** +** This second example is an SQL syntax error. As a general rule you should +** always use %q instead of %s when inserting text into a string literal. +** +** ^(The %Q option works like %q except it also adds single quotes around +** the outside of the total string. Additionally, if the parameter in the +** argument list is a NULL pointer, %Q substitutes the text "NULL" (without +** single quotes).)^ So, for example, one could say: +** +**
+**  char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText);
+**  sqlite3_exec(db, zSQL, 0, 0, 0);
+**  sqlite3_free(zSQL);
+** 
+** +** The code above will render a correct SQL statement in the zSQL +** variable even if the zText variable is a NULL pointer. +** +** ^(The "%z" formatting option works like "%s" but with the +** addition that after the string has been read and copied into +** the result, [sqlite3_free()] is called on the input string.)^ +*/ +SQLITE_API char *sqlite3_mprintf(const char*,...); +SQLITE_API char *sqlite3_vmprintf(const char*, va_list); +SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...); +SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list); + +/* +** CAPI3REF: Memory Allocation Subsystem +** +** The SQLite core uses these three routines for all of its own +** internal memory allocation needs. "Core" in the previous sentence +** does not include operating-system specific VFS implementation. The +** Windows VFS uses native malloc() and free() for some operations. +** +** ^The sqlite3_malloc() routine returns a pointer to a block +** of memory at least N bytes in length, where N is the parameter. +** ^If sqlite3_malloc() is unable to obtain sufficient free +** memory, it returns a NULL pointer. ^If the parameter N to +** sqlite3_malloc() is zero or negative then sqlite3_malloc() returns +** a NULL pointer. +** +** ^Calling sqlite3_free() with a pointer previously returned +** by sqlite3_malloc() or sqlite3_realloc() releases that memory so +** that it might be reused. ^The sqlite3_free() routine is +** a no-op if is called with a NULL pointer. Passing a NULL pointer +** to sqlite3_free() is harmless. After being freed, memory +** should neither be read nor written. Even reading previously freed +** memory might result in a segmentation fault or other severe error. +** Memory corruption, a segmentation fault, or other severe error +** might result if sqlite3_free() is called with a non-NULL pointer that +** was not obtained from sqlite3_malloc() or sqlite3_realloc(). +** +** ^(The sqlite3_realloc() interface attempts to resize a +** prior memory allocation to be at least N bytes, where N is the +** second parameter. The memory allocation to be resized is the first +** parameter.)^ ^ If the first parameter to sqlite3_realloc() +** is a NULL pointer then its behavior is identical to calling +** sqlite3_malloc(N) where N is the second parameter to sqlite3_realloc(). +** ^If the second parameter to sqlite3_realloc() is zero or +** negative then the behavior is exactly the same as calling +** sqlite3_free(P) where P is the first parameter to sqlite3_realloc(). +** ^sqlite3_realloc() returns a pointer to a memory allocation +** of at least N bytes in size or NULL if sufficient memory is unavailable. +** ^If M is the size of the prior allocation, then min(N,M) bytes +** of the prior allocation are copied into the beginning of buffer returned +** by sqlite3_realloc() and the prior allocation is freed. +** ^If sqlite3_realloc() returns NULL, then the prior allocation +** is not freed. +** +** ^The memory returned by sqlite3_malloc() and sqlite3_realloc() +** is always aligned to at least an 8 byte boundary, or to a +** 4 byte boundary if the [SQLITE_4_BYTE_ALIGNED_MALLOC] compile-time +** option is used. +** +** In SQLite version 3.5.0 and 3.5.1, it was possible to define +** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in +** implementation of these routines to be omitted. That capability +** is no longer provided. Only built-in memory allocators can be used. +** +** The Windows OS interface layer calls +** the system malloc() and free() directly when converting +** filenames between the UTF-8 encoding used by SQLite +** and whatever filename encoding is used by the particular Windows +** installation. Memory allocation errors are detected, but +** they are reported back as [SQLITE_CANTOPEN] or +** [SQLITE_IOERR] rather than [SQLITE_NOMEM]. +** +** The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()] +** must be either NULL or else pointers obtained from a prior +** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have +** not yet been released. +** +** The application must not read or write any part of +** a block of memory after it has been released using +** [sqlite3_free()] or [sqlite3_realloc()]. +*/ +SQLITE_API void *sqlite3_malloc(int); +SQLITE_API void *sqlite3_realloc(void*, int); +SQLITE_API void sqlite3_free(void*); + +/* +** CAPI3REF: Memory Allocator Statistics +** +** SQLite provides these two interfaces for reporting on the status +** of the [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()] +** routines, which form the built-in memory allocation subsystem. +** +** ^The [sqlite3_memory_used()] routine returns the number of bytes +** of memory currently outstanding (malloced but not freed). +** ^The [sqlite3_memory_highwater()] routine returns the maximum +** value of [sqlite3_memory_used()] since the high-water mark +** was last reset. ^The values returned by [sqlite3_memory_used()] and +** [sqlite3_memory_highwater()] include any overhead +** added by SQLite in its implementation of [sqlite3_malloc()], +** but not overhead added by the any underlying system library +** routines that [sqlite3_malloc()] may call. +** +** ^The memory high-water mark is reset to the current value of +** [sqlite3_memory_used()] if and only if the parameter to +** [sqlite3_memory_highwater()] is true. ^The value returned +** by [sqlite3_memory_highwater(1)] is the high-water mark +** prior to the reset. +*/ +SQLITE_API sqlite3_int64 sqlite3_memory_used(void); +SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag); + +/* +** CAPI3REF: Pseudo-Random Number Generator +** +** SQLite contains a high-quality pseudo-random number generator (PRNG) used to +** select random [ROWID | ROWIDs] when inserting new records into a table that +** already uses the largest possible [ROWID]. The PRNG is also used for +** the build-in random() and randomblob() SQL functions. This interface allows +** applications to access the same PRNG for other purposes. +** +** ^A call to this routine stores N bytes of randomness into buffer P. +** +** ^The first time this routine is invoked (either internally or by +** the application) the PRNG is seeded using randomness obtained +** from the xRandomness method of the default [sqlite3_vfs] object. +** ^On all subsequent invocations, the pseudo-randomness is generated +** internally and without recourse to the [sqlite3_vfs] xRandomness +** method. +*/ +SQLITE_API void sqlite3_randomness(int N, void *P); + +/* +** CAPI3REF: Compile-Time Authorization Callbacks +** +** ^This routine registers an authorizer callback with a particular +** [database connection], supplied in the first argument. +** ^The authorizer callback is invoked as SQL statements are being compiled +** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()], +** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()]. ^At various +** points during the compilation process, as logic is being created +** to perform various actions, the authorizer callback is invoked to +** see if those actions are allowed. ^The authorizer callback should +** return [SQLITE_OK] to allow the action, [SQLITE_IGNORE] to disallow the +** specific action but allow the SQL statement to continue to be +** compiled, or [SQLITE_DENY] to cause the entire SQL statement to be +** rejected with an error. ^If the authorizer callback returns +** any value other than [SQLITE_IGNORE], [SQLITE_OK], or [SQLITE_DENY] +** then the [sqlite3_prepare_v2()] or equivalent call that triggered +** the authorizer will fail with an error message. +** +** When the callback returns [SQLITE_OK], that means the operation +** requested is ok. ^When the callback returns [SQLITE_DENY], the +** [sqlite3_prepare_v2()] or equivalent call that triggered the +** authorizer will fail with an error message explaining that +** access is denied. +** +** ^The first parameter to the authorizer callback is a copy of the third +** parameter to the sqlite3_set_authorizer() interface. ^The second parameter +** to the callback is an integer [SQLITE_COPY | action code] that specifies +** the particular action to be authorized. ^The third through sixth parameters +** to the callback are zero-terminated strings that contain additional +** details about the action to be authorized. +** +** ^If the action code is [SQLITE_READ] +** and the callback returns [SQLITE_IGNORE] then the +** [prepared statement] statement is constructed to substitute +** a NULL value in place of the table column that would have +** been read if [SQLITE_OK] had been returned. The [SQLITE_IGNORE] +** return can be used to deny an untrusted user access to individual +** columns of a table. +** ^If the action code is [SQLITE_DELETE] and the callback returns +** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the +** [truncate optimization] is disabled and all rows are deleted individually. +** +** An authorizer is used when [sqlite3_prepare | preparing] +** SQL statements from an untrusted source, to ensure that the SQL statements +** do not try to access data they are not allowed to see, or that they do not +** try to execute malicious statements that damage the database. For +** example, an application may allow a user to enter arbitrary +** SQL queries for evaluation by a database. But the application does +** not want the user to be able to make arbitrary changes to the +** database. An authorizer could then be put in place while the +** user-entered SQL is being [sqlite3_prepare | prepared] that +** disallows everything except [SELECT] statements. +** +** Applications that need to process SQL from untrusted sources +** might also consider lowering resource limits using [sqlite3_limit()] +** and limiting database size using the [max_page_count] [PRAGMA] +** in addition to using an authorizer. +** +** ^(Only a single authorizer can be in place on a database connection +** at a time. Each call to sqlite3_set_authorizer overrides the +** previous call.)^ ^Disable the authorizer by installing a NULL callback. +** The authorizer is disabled by default. +** +** The authorizer callback must not do anything that will modify +** the database connection that invoked the authorizer callback. +** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their +** database connections for the meaning of "modify" in this paragraph. +** +** ^When [sqlite3_prepare_v2()] is used to prepare a statement, the +** statement might be re-prepared during [sqlite3_step()] due to a +** schema change. Hence, the application should ensure that the +** correct authorizer callback remains in place during the [sqlite3_step()]. +** +** ^Note that the authorizer callback is invoked only during +** [sqlite3_prepare()] or its variants. Authorization is not +** performed during statement evaluation in [sqlite3_step()], unless +** as stated in the previous paragraph, sqlite3_step() invokes +** sqlite3_prepare_v2() to reprepare a statement after a schema change. +*/ +SQLITE_API int sqlite3_set_authorizer( + sqlite3*, + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), + void *pUserData +); + +/* +** CAPI3REF: Authorizer Return Codes +** +** The [sqlite3_set_authorizer | authorizer callback function] must +** return either [SQLITE_OK] or one of these two constants in order +** to signal SQLite whether or not the action is permitted. See the +** [sqlite3_set_authorizer | authorizer documentation] for additional +** information. +** +** Note that SQLITE_IGNORE is also used as a [SQLITE_ROLLBACK | return code] +** from the [sqlite3_vtab_on_conflict()] interface. +*/ +#define SQLITE_DENY 1 /* Abort the SQL statement with an error */ +#define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */ + +/* +** CAPI3REF: Authorizer Action Codes +** +** The [sqlite3_set_authorizer()] interface registers a callback function +** that is invoked to authorize certain SQL statement actions. The +** second parameter to the callback is an integer code that specifies +** what action is being authorized. These are the integer action codes that +** the authorizer callback may be passed. +** +** These action code values signify what kind of operation is to be +** authorized. The 3rd and 4th parameters to the authorization +** callback function will be parameters or NULL depending on which of these +** codes is used as the second parameter. ^(The 5th parameter to the +** authorizer callback is the name of the database ("main", "temp", +** etc.) if applicable.)^ ^The 6th parameter to the authorizer callback +** is the name of the inner-most trigger or view that is responsible for +** the access attempt or NULL if this access attempt is directly from +** top-level SQL code. +*/ +/******************************************* 3rd ************ 4th ***********/ +#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */ +#define SQLITE_CREATE_TABLE 2 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */ +#define SQLITE_CREATE_TEMP_TABLE 4 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_TRIGGER 5 /* Trigger Name Table Name */ +#define SQLITE_CREATE_TEMP_VIEW 6 /* View Name NULL */ +#define SQLITE_CREATE_TRIGGER 7 /* Trigger Name Table Name */ +#define SQLITE_CREATE_VIEW 8 /* View Name NULL */ +#define SQLITE_DELETE 9 /* Table Name NULL */ +#define SQLITE_DROP_INDEX 10 /* Index Name Table Name */ +#define SQLITE_DROP_TABLE 11 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_INDEX 12 /* Index Name Table Name */ +#define SQLITE_DROP_TEMP_TABLE 13 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_TRIGGER 14 /* Trigger Name Table Name */ +#define SQLITE_DROP_TEMP_VIEW 15 /* View Name NULL */ +#define SQLITE_DROP_TRIGGER 16 /* Trigger Name Table Name */ +#define SQLITE_DROP_VIEW 17 /* View Name NULL */ +#define SQLITE_INSERT 18 /* Table Name NULL */ +#define SQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */ +#define SQLITE_READ 20 /* Table Name Column Name */ +#define SQLITE_SELECT 21 /* NULL NULL */ +#define SQLITE_TRANSACTION 22 /* Operation NULL */ +#define SQLITE_UPDATE 23 /* Table Name Column Name */ +#define SQLITE_ATTACH 24 /* Filename NULL */ +#define SQLITE_DETACH 25 /* Database Name NULL */ +#define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */ +#define SQLITE_REINDEX 27 /* Index Name NULL */ +#define SQLITE_ANALYZE 28 /* Table Name NULL */ +#define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */ +#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */ +#define SQLITE_FUNCTION 31 /* NULL Function Name */ +#define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */ +#define SQLITE_COPY 0 /* No longer used */ + +/* +** CAPI3REF: Tracing And Profiling Functions +** +** These routines register callback functions that can be used for +** tracing and profiling the execution of SQL statements. +** +** ^The callback function registered by sqlite3_trace() is invoked at +** various times when an SQL statement is being run by [sqlite3_step()]. +** ^The sqlite3_trace() callback is invoked with a UTF-8 rendering of the +** SQL statement text as the statement first begins executing. +** ^(Additional sqlite3_trace() callbacks might occur +** as each triggered subprogram is entered. The callbacks for triggers +** contain a UTF-8 SQL comment that identifies the trigger.)^ +** +** ^The callback function registered by sqlite3_profile() is invoked +** as each SQL statement finishes. ^The profile callback contains +** the original statement text and an estimate of wall-clock time +** of how long that statement took to run. ^The profile callback +** time is in units of nanoseconds, however the current implementation +** is only capable of millisecond resolution so the six least significant +** digits in the time are meaningless. Future versions of SQLite +** might provide greater resolution on the profiler callback. The +** sqlite3_profile() function is considered experimental and is +** subject to change in future versions of SQLite. +*/ +SQLITE_API void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); +SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*, + void(*xProfile)(void*,const char*,sqlite3_uint64), void*); + +/* +** CAPI3REF: Query Progress Callbacks +** +** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback +** function X to be invoked periodically during long running calls to +** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for +** database connection D. An example use for this +** interface is to keep a GUI updated during a large query. +** +** ^The parameter P is passed through as the only parameter to the +** callback function X. ^The parameter N is the number of +** [virtual machine instructions] that are evaluated between successive +** invocations of the callback X. +** +** ^Only a single progress handler may be defined at one time per +** [database connection]; setting a new progress handler cancels the +** old one. ^Setting parameter X to NULL disables the progress handler. +** ^The progress handler is also disabled by setting N to a value less +** than 1. +** +** ^If the progress callback returns non-zero, the operation is +** interrupted. This feature can be used to implement a +** "Cancel" button on a GUI progress dialog box. +** +** The progress handler callback must not do anything that will modify +** the database connection that invoked the progress handler. +** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their +** database connections for the meaning of "modify" in this paragraph. +** +*/ +SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); + +/* +** CAPI3REF: Opening A New Database Connection +** +** ^These routines open an SQLite database file as specified by the +** filename argument. ^The filename argument is interpreted as UTF-8 for +** sqlite3_open() and sqlite3_open_v2() and as UTF-16 in the native byte +** order for sqlite3_open16(). ^(A [database connection] handle is usually +** returned in *ppDb, even if an error occurs. The only exception is that +** if SQLite is unable to allocate memory to hold the [sqlite3] object, +** a NULL will be written into *ppDb instead of a pointer to the [sqlite3] +** object.)^ ^(If the database is opened (and/or created) successfully, then +** [SQLITE_OK] is returned. Otherwise an [error code] is returned.)^ ^The +** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain +** an English language description of the error following a failure of any +** of the sqlite3_open() routines. +** +** ^The default encoding for the database will be UTF-8 if +** sqlite3_open() or sqlite3_open_v2() is called and +** UTF-16 in the native byte order if sqlite3_open16() is used. +** +** Whether or not an error occurs when it is opened, resources +** associated with the [database connection] handle should be released by +** passing it to [sqlite3_close()] when it is no longer required. +** +** The sqlite3_open_v2() interface works like sqlite3_open() +** except that it accepts two additional parameters for additional control +** over the new database connection. ^(The flags parameter to +** sqlite3_open_v2() can take one of +** the following three values, optionally combined with the +** [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX], [SQLITE_OPEN_SHAREDCACHE], +** [SQLITE_OPEN_PRIVATECACHE], and/or [SQLITE_OPEN_URI] flags:)^ +** +**
+** ^(
[SQLITE_OPEN_READONLY]
+**
The database is opened in read-only mode. If the database does not +** already exist, an error is returned.
)^ +** +** ^(
[SQLITE_OPEN_READWRITE]
+**
The database is opened for reading and writing if possible, or reading +** only if the file is write protected by the operating system. In either +** case the database must already exist, otherwise an error is returned.
)^ +** +** ^(
[SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]
+**
The database is opened for reading and writing, and is created if +** it does not already exist. This is the behavior that is always used for +** sqlite3_open() and sqlite3_open16().
)^ +**
+** +** If the 3rd parameter to sqlite3_open_v2() is not one of the +** combinations shown above optionally combined with other +** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits] +** then the behavior is undefined. +** +** ^If the [SQLITE_OPEN_NOMUTEX] flag is set, then the database connection +** opens in the multi-thread [threading mode] as long as the single-thread +** mode has not been set at compile-time or start-time. ^If the +** [SQLITE_OPEN_FULLMUTEX] flag is set then the database connection opens +** in the serialized [threading mode] unless single-thread was +** previously selected at compile-time or start-time. +** ^The [SQLITE_OPEN_SHAREDCACHE] flag causes the database connection to be +** eligible to use [shared cache mode], regardless of whether or not shared +** cache is enabled using [sqlite3_enable_shared_cache()]. ^The +** [SQLITE_OPEN_PRIVATECACHE] flag causes the database connection to not +** participate in [shared cache mode] even if it is enabled. +** +** ^The fourth parameter to sqlite3_open_v2() is the name of the +** [sqlite3_vfs] object that defines the operating system interface that +** the new database connection should use. ^If the fourth parameter is +** a NULL pointer then the default [sqlite3_vfs] object is used. +** +** ^If the filename is ":memory:", then a private, temporary in-memory database +** is created for the connection. ^This in-memory database will vanish when +** the database connection is closed. Future versions of SQLite might +** make use of additional special filenames that begin with the ":" character. +** It is recommended that when a database filename actually does begin with +** a ":" character you should prefix the filename with a pathname such as +** "./" to avoid ambiguity. +** +** ^If the filename is an empty string, then a private, temporary +** on-disk database will be created. ^This private database will be +** automatically deleted as soon as the database connection is closed. +** +** [[URI filenames in sqlite3_open()]]

URI Filenames

+** +** ^If [URI filename] interpretation is enabled, and the filename argument +** begins with "file:", then the filename is interpreted as a URI. ^URI +** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is +** set in the fourth argument to sqlite3_open_v2(), or if it has +** been enabled globally using the [SQLITE_CONFIG_URI] option with the +** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option. +** As of SQLite version 3.7.7, URI filename interpretation is turned off +** by default, but future releases of SQLite might enable URI filename +** interpretation by default. See "[URI filenames]" for additional +** information. +** +** URI filenames are parsed according to RFC 3986. ^If the URI contains an +** authority, then it must be either an empty string or the string +** "localhost". ^If the authority is not an empty string or "localhost", an +** error is returned to the caller. ^The fragment component of a URI, if +** present, is ignored. +** +** ^SQLite uses the path component of the URI as the name of the disk file +** which contains the database. ^If the path begins with a '/' character, +** then it is interpreted as an absolute path. ^If the path does not begin +** with a '/' (meaning that the authority section is omitted from the URI) +** then the path is interpreted as a relative path. +** ^On windows, the first component of an absolute path +** is a drive specification (e.g. "C:"). +** +** [[core URI query parameters]] +** The query component of a URI may contain parameters that are interpreted +** either by SQLite itself, or by a [VFS | custom VFS implementation]. +** SQLite interprets the following three query parameters: +** +**
    +**
  • vfs: ^The "vfs" parameter may be used to specify the name of +** a VFS object that provides the operating system interface that should +** be used to access the database file on disk. ^If this option is set to +** an empty string the default VFS object is used. ^Specifying an unknown +** VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is +** present, then the VFS specified by the option takes precedence over +** the value passed as the fourth parameter to sqlite3_open_v2(). +** +**
  • mode: ^(The mode parameter may be set to either "ro", "rw" or +** "rwc". Attempting to set it to any other value is an error)^. +** ^If "ro" is specified, then the database is opened for read-only +** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the +** third argument to sqlite3_prepare_v2(). ^If the mode option is set to +** "rw", then the database is opened for read-write (but not create) +** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had +** been set. ^Value "rwc" is equivalent to setting both +** SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. ^If sqlite3_open_v2() is +** used, it is an error to specify a value for the mode parameter that is +** less restrictive than that specified by the flags passed as the third +** parameter. +** +**
  • cache: ^The cache parameter may be set to either "shared" or +** "private". ^Setting it to "shared" is equivalent to setting the +** SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to +** sqlite3_open_v2(). ^Setting the cache parameter to "private" is +** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit. +** ^If sqlite3_open_v2() is used and the "cache" parameter is present in +** a URI filename, its value overrides any behaviour requested by setting +** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag. +**
+** +** ^Specifying an unknown parameter in the query component of a URI is not an +** error. Future versions of SQLite might understand additional query +** parameters. See "[query parameters with special meaning to SQLite]" for +** additional information. +** +** [[URI filename examples]]

URI filename examples

+** +** +**
URI filenames Results +**
file:data.db +** Open the file "data.db" in the current directory. +**
file:/home/fred/data.db
+** file:///home/fred/data.db
+** file://localhost/home/fred/data.db
+** Open the database file "/home/fred/data.db". +**
file://darkstar/home/fred/data.db +** An error. "darkstar" is not a recognized authority. +**
+** file:///C:/Documents%20and%20Settings/fred/Desktop/data.db +** Windows only: Open the file "data.db" on fred's desktop on drive +** C:. Note that the %20 escaping in this example is not strictly +** necessary - space characters can be used literally +** in URI filenames. +**
file:data.db?mode=ro&cache=private +** Open file "data.db" in the current directory for read-only access. +** Regardless of whether or not shared-cache mode is enabled by +** default, use a private cache. +**
file:/home/fred/data.db?vfs=unix-nolock +** Open file "/home/fred/data.db". Use the special VFS "unix-nolock". +**
file:data.db?mode=readonly +** An error. "readonly" is not a valid option for the "mode" parameter. +**
+** +** ^URI hexadecimal escape sequences (%HH) are supported within the path and +** query components of a URI. A hexadecimal escape sequence consists of a +** percent sign - "%" - followed by exactly two hexadecimal digits +** specifying an octet value. ^Before the path or query components of a +** URI filename are interpreted, they are encoded using UTF-8 and all +** hexadecimal escape sequences replaced by a single byte containing the +** corresponding octet. If this process generates an invalid UTF-8 encoding, +** the results are undefined. +** +** Note to Windows users: The encoding used for the filename argument +** of sqlite3_open() and sqlite3_open_v2() must be UTF-8, not whatever +** codepage is currently defined. Filenames containing international +** characters must be converted to UTF-8 prior to passing them into +** sqlite3_open() or sqlite3_open_v2(). +*/ +SQLITE_API int sqlite3_open( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +SQLITE_API int sqlite3_open16( + const void *filename, /* Database filename (UTF-16) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +SQLITE_API int sqlite3_open_v2( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs /* Name of VFS module to use */ +); + +/* +** CAPI3REF: Obtain Values For URI Parameters +** +** These are utility routines, useful to VFS implementations, that check +** to see if a database file was a URI that contained a specific query +** parameter, and if so obtains the value of that query parameter. +** +** If F is the database filename pointer passed into the xOpen() method of +** a VFS implementation when the flags parameter to xOpen() has one or +** more of the [SQLITE_OPEN_URI] or [SQLITE_OPEN_MAIN_DB] bits set and +** P is the name of the query parameter, then +** sqlite3_uri_parameter(F,P) returns the value of the P +** parameter if it exists or a NULL pointer if P does not appear as a +** query parameter on F. If P is a query parameter of F +** has no explicit value, then sqlite3_uri_parameter(F,P) returns +** a pointer to an empty string. +** +** The sqlite3_uri_boolean(F,P,B) routine assumes that P is a boolean +** parameter and returns true (1) or false (0) according to the value +** of P. The value of P is true if it is "yes" or "true" or "on" or +** a non-zero number and is false otherwise. If P is not a query parameter +** on F then sqlite3_uri_boolean(F,P,B) returns (B!=0). +** +** The sqlite3_uri_int64(F,P,D) routine converts the value of P into a +** 64-bit signed integer and returns that integer, or D if P does not +** exist. If the value of P is something other than an integer, then +** zero is returned. +** +** If F is a NULL pointer, then sqlite3_uri_parameter(F,P) returns NULL and +** sqlite3_uri_boolean(F,P,B) returns B. If F is not a NULL pointer and +** is not a database file pathname pointer that SQLite passed into the xOpen +** VFS method, then the behavior of this routine is undefined and probably +** undesirable. +*/ +SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam); +SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault); +SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64); + + +/* +** CAPI3REF: Error Codes And Messages +** +** ^The sqlite3_errcode() interface returns the numeric [result code] or +** [extended result code] for the most recent failed sqlite3_* API call +** associated with a [database connection]. If a prior API call failed +** but the most recent API call succeeded, the return value from +** sqlite3_errcode() is undefined. ^The sqlite3_extended_errcode() +** interface is the same except that it always returns the +** [extended result code] even when extended result codes are +** disabled. +** +** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language +** text that describes the error, as either UTF-8 or UTF-16 respectively. +** ^(Memory to hold the error message string is managed internally. +** The application does not need to worry about freeing the result. +** However, the error string might be overwritten or deallocated by +** subsequent calls to other SQLite interface functions.)^ +** +** When the serialized [threading mode] is in use, it might be the +** case that a second error occurs on a separate thread in between +** the time of the first error and the call to these interfaces. +** When that happens, the second error will be reported since these +** interfaces always report the most recent result. To avoid +** this, each thread can obtain exclusive use of the [database connection] D +** by invoking [sqlite3_mutex_enter]([sqlite3_db_mutex](D)) before beginning +** to use D and invoking [sqlite3_mutex_leave]([sqlite3_db_mutex](D)) after +** all calls to the interfaces listed here are completed. +** +** If an interface fails with SQLITE_MISUSE, that means the interface +** was invoked incorrectly by the application. In that case, the +** error code and message may or may not be set. +*/ +SQLITE_API int sqlite3_errcode(sqlite3 *db); +SQLITE_API int sqlite3_extended_errcode(sqlite3 *db); +SQLITE_API const char *sqlite3_errmsg(sqlite3*); +SQLITE_API const void *sqlite3_errmsg16(sqlite3*); + +/* +** CAPI3REF: SQL Statement Object +** KEYWORDS: {prepared statement} {prepared statements} +** +** An instance of this object represents a single SQL statement. +** This object is variously known as a "prepared statement" or a +** "compiled SQL statement" or simply as a "statement". +** +** The life of a statement object goes something like this: +** +**
    +**
  1. Create the object using [sqlite3_prepare_v2()] or a related +** function. +**
  2. Bind values to [host parameters] using the sqlite3_bind_*() +** interfaces. +**
  3. Run the SQL by calling [sqlite3_step()] one or more times. +**
  4. Reset the statement using [sqlite3_reset()] then go back +** to step 2. Do this zero or more times. +**
  5. Destroy the object using [sqlite3_finalize()]. +**
+** +** Refer to documentation on individual methods above for additional +** information. +*/ +typedef struct sqlite3_stmt sqlite3_stmt; + +/* +** CAPI3REF: Run-time Limits +** +** ^(This interface allows the size of various constructs to be limited +** on a connection by connection basis. The first parameter is the +** [database connection] whose limit is to be set or queried. The +** second parameter is one of the [limit categories] that define a +** class of constructs to be size limited. The third parameter is the +** new limit for that construct.)^ +** +** ^If the new limit is a negative number, the limit is unchanged. +** ^(For each limit category SQLITE_LIMIT_NAME there is a +** [limits | hard upper bound] +** set at compile-time by a C preprocessor macro called +** [limits | SQLITE_MAX_NAME]. +** (The "_LIMIT_" in the name is changed to "_MAX_".))^ +** ^Attempts to increase a limit above its hard upper bound are +** silently truncated to the hard upper bound. +** +** ^Regardless of whether or not the limit was changed, the +** [sqlite3_limit()] interface returns the prior value of the limit. +** ^Hence, to find the current value of a limit without changing it, +** simply invoke this interface with the third parameter set to -1. +** +** Run-time limits are intended for use in applications that manage +** both their own internal database and also databases that are controlled +** by untrusted external sources. An example application might be a +** web browser that has its own databases for storing history and +** separate databases controlled by JavaScript applications downloaded +** off the Internet. The internal databases can be given the +** large, default limits. Databases managed by external sources can +** be given much smaller limits designed to prevent a denial of service +** attack. Developers might also want to use the [sqlite3_set_authorizer()] +** interface to further control untrusted SQL. The size of the database +** created by an untrusted script can be contained using the +** [max_page_count] [PRAGMA]. +** +** New run-time limit categories may be added in future releases. +*/ +SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); + +/* +** CAPI3REF: Run-Time Limit Categories +** KEYWORDS: {limit category} {*limit categories} +** +** These constants define various performance limits +** that can be lowered at run-time using [sqlite3_limit()]. +** The synopsis of the meanings of the various limits is shown below. +** Additional information is available at [limits | Limits in SQLite]. +** +**
+** [[SQLITE_LIMIT_LENGTH]] ^(
SQLITE_LIMIT_LENGTH
+**
The maximum size of any string or BLOB or table row, in bytes.
)^ +** +** [[SQLITE_LIMIT_SQL_LENGTH]] ^(
SQLITE_LIMIT_SQL_LENGTH
+**
The maximum length of an SQL statement, in bytes.
)^ +** +** [[SQLITE_LIMIT_COLUMN]] ^(
SQLITE_LIMIT_COLUMN
+**
The maximum number of columns in a table definition or in the +** result set of a [SELECT] or the maximum number of columns in an index +** or in an ORDER BY or GROUP BY clause.
)^ +** +** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(
SQLITE_LIMIT_EXPR_DEPTH
+**
The maximum depth of the parse tree on any expression.
)^ +** +** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(
SQLITE_LIMIT_COMPOUND_SELECT
+**
The maximum number of terms in a compound SELECT statement.
)^ +** +** [[SQLITE_LIMIT_VDBE_OP]] ^(
SQLITE_LIMIT_VDBE_OP
+**
The maximum number of instructions in a virtual machine program +** used to implement an SQL statement. This limit is not currently +** enforced, though that might be added in some future release of +** SQLite.
)^ +** +** [[SQLITE_LIMIT_FUNCTION_ARG]] ^(
SQLITE_LIMIT_FUNCTION_ARG
+**
The maximum number of arguments on a function.
)^ +** +** [[SQLITE_LIMIT_ATTACHED]] ^(
SQLITE_LIMIT_ATTACHED
+**
The maximum number of [ATTACH | attached databases].)^
+** +** [[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]] +** ^(
SQLITE_LIMIT_LIKE_PATTERN_LENGTH
+**
The maximum length of the pattern argument to the [LIKE] or +** [GLOB] operators.
)^ +** +** [[SQLITE_LIMIT_VARIABLE_NUMBER]] +** ^(
SQLITE_LIMIT_VARIABLE_NUMBER
+**
The maximum index number of any [parameter] in an SQL statement.)^ +** +** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(
SQLITE_LIMIT_TRIGGER_DEPTH
+**
The maximum depth of recursion for triggers.
)^ +**
+*/ +#define SQLITE_LIMIT_LENGTH 0 +#define SQLITE_LIMIT_SQL_LENGTH 1 +#define SQLITE_LIMIT_COLUMN 2 +#define SQLITE_LIMIT_EXPR_DEPTH 3 +#define SQLITE_LIMIT_COMPOUND_SELECT 4 +#define SQLITE_LIMIT_VDBE_OP 5 +#define SQLITE_LIMIT_FUNCTION_ARG 6 +#define SQLITE_LIMIT_ATTACHED 7 +#define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8 +#define SQLITE_LIMIT_VARIABLE_NUMBER 9 +#define SQLITE_LIMIT_TRIGGER_DEPTH 10 + +/* +** CAPI3REF: Compiling An SQL Statement +** KEYWORDS: {SQL statement compiler} +** +** To execute an SQL query, it must first be compiled into a byte-code +** program using one of these routines. +** +** The first argument, "db", is a [database connection] obtained from a +** prior successful call to [sqlite3_open()], [sqlite3_open_v2()] or +** [sqlite3_open16()]. The database connection must not have been closed. +** +** The second argument, "zSql", is the statement to be compiled, encoded +** as either UTF-8 or UTF-16. The sqlite3_prepare() and sqlite3_prepare_v2() +** interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2() +** use UTF-16. +** +** ^If the nByte argument is less than zero, then zSql is read up to the +** first zero terminator. ^If nByte is non-negative, then it is the maximum +** number of bytes read from zSql. ^When nByte is non-negative, the +** zSql string ends at either the first '\000' or '\u0000' character or +** the nByte-th byte, whichever comes first. If the caller knows +** that the supplied string is nul-terminated, then there is a small +** performance advantage to be gained by passing an nByte parameter that +** is equal to the number of bytes in the input string including +** the nul-terminator bytes as this saves SQLite from having to +** make a copy of the input string. +** +** ^If pzTail is not NULL then *pzTail is made to point to the first byte +** past the end of the first SQL statement in zSql. These routines only +** compile the first statement in zSql, so *pzTail is left pointing to +** what remains uncompiled. +** +** ^*ppStmt is left pointing to a compiled [prepared statement] that can be +** executed using [sqlite3_step()]. ^If there is an error, *ppStmt is set +** to NULL. ^If the input text contains no SQL (if the input is an empty +** string or a comment) then *ppStmt is set to NULL. +** The calling procedure is responsible for deleting the compiled +** SQL statement using [sqlite3_finalize()] after it has finished with it. +** ppStmt may not be NULL. +** +** ^On success, the sqlite3_prepare() family of routines return [SQLITE_OK]; +** otherwise an [error code] is returned. +** +** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are +** recommended for all new programs. The two older interfaces are retained +** for backwards compatibility, but their use is discouraged. +** ^In the "v2" interfaces, the prepared statement +** that is returned (the [sqlite3_stmt] object) contains a copy of the +** original SQL text. This causes the [sqlite3_step()] interface to +** behave differently in three ways: +** +**
    +**
  1. +** ^If the database schema changes, instead of returning [SQLITE_SCHEMA] as it +** always used to do, [sqlite3_step()] will automatically recompile the SQL +** statement and try to run it again. +**
  2. +** +**
  3. +** ^When an error occurs, [sqlite3_step()] will return one of the detailed +** [error codes] or [extended error codes]. ^The legacy behavior was that +** [sqlite3_step()] would only return a generic [SQLITE_ERROR] result code +** and the application would have to make a second call to [sqlite3_reset()] +** in order to find the underlying cause of the problem. With the "v2" prepare +** interfaces, the underlying reason for the error is returned immediately. +**
  4. +** +**
  5. +** ^If the specific value bound to [parameter | host parameter] in the +** WHERE clause might influence the choice of query plan for a statement, +** then the statement will be automatically recompiled, as if there had been +** a schema change, on the first [sqlite3_step()] call following any change +** to the [sqlite3_bind_text | bindings] of that [parameter]. +** ^The specific value of WHERE-clause [parameter] might influence the +** choice of query plan if the parameter is the left-hand side of a [LIKE] +** or [GLOB] operator or if the parameter is compared to an indexed column +** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled. +** the +**
  6. +**
+*/ +SQLITE_API int sqlite3_prepare( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +SQLITE_API int sqlite3_prepare_v2( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +SQLITE_API int sqlite3_prepare16( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); +SQLITE_API int sqlite3_prepare16_v2( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); + +/* +** CAPI3REF: Retrieving Statement SQL +** +** ^This interface can be used to retrieve a saved copy of the original +** SQL text used to create a [prepared statement] if that statement was +** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()]. +*/ +SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Determine If An SQL Statement Writes The Database +** +** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if +** and only if the [prepared statement] X makes no direct changes to +** the content of the database file. +** +** Note that [application-defined SQL functions] or +** [virtual tables] might change the database indirectly as a side effect. +** ^(For example, if an application defines a function "eval()" that +** calls [sqlite3_exec()], then the following SQL statement would +** change the database file through side-effects: +** +**
+**    SELECT eval('DELETE FROM t1') FROM t2;
+** 
+** +** But because the [SELECT] statement does not change the database file +** directly, sqlite3_stmt_readonly() would still return true.)^ +** +** ^Transaction control statements such as [BEGIN], [COMMIT], [ROLLBACK], +** [SAVEPOINT], and [RELEASE] cause sqlite3_stmt_readonly() to return true, +** since the statements themselves do not actually modify the database but +** rather they control the timing of when other statements modify the +** database. ^The [ATTACH] and [DETACH] statements also cause +** sqlite3_stmt_readonly() to return true since, while those statements +** change the configuration of a database connection, they do not make +** changes to the content of the database files on disk. +*/ +SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Determine If A Prepared Statement Has Been Reset +** +** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the +** [prepared statement] S has been stepped at least once using +** [sqlite3_step(S)] but has not run to completion and/or has not +** been reset using [sqlite3_reset(S)]. ^The sqlite3_stmt_busy(S) +** interface returns false if S is a NULL pointer. If S is not a +** NULL pointer and is not a pointer to a valid [prepared statement] +** object, then the behavior is undefined and probably undesirable. +** +** This interface can be used in combination [sqlite3_next_stmt()] +** to locate all prepared statements associated with a database +** connection that are in need of being reset. This can be used, +** for example, in diagnostic routines to search for prepared +** statements that are holding a transaction open. +*/ +SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*); + +/* +** CAPI3REF: Dynamically Typed Value Object +** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value} +** +** SQLite uses the sqlite3_value object to represent all values +** that can be stored in a database table. SQLite uses dynamic typing +** for the values it stores. ^Values stored in sqlite3_value objects +** can be integers, floating point values, strings, BLOBs, or NULL. +** +** An sqlite3_value object may be either "protected" or "unprotected". +** Some interfaces require a protected sqlite3_value. Other interfaces +** will accept either a protected or an unprotected sqlite3_value. +** Every interface that accepts sqlite3_value arguments specifies +** whether or not it requires a protected sqlite3_value. +** +** The terms "protected" and "unprotected" refer to whether or not +** a mutex is held. An internal mutex is held for a protected +** sqlite3_value object but no mutex is held for an unprotected +** sqlite3_value object. If SQLite is compiled to be single-threaded +** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0) +** or if SQLite is run in one of reduced mutex modes +** [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD] +** then there is no distinction between protected and unprotected +** sqlite3_value objects and they can be used interchangeably. However, +** for maximum code portability it is recommended that applications +** still make the distinction between protected and unprotected +** sqlite3_value objects even when not strictly required. +** +** ^The sqlite3_value objects that are passed as parameters into the +** implementation of [application-defined SQL functions] are protected. +** ^The sqlite3_value object returned by +** [sqlite3_column_value()] is unprotected. +** Unprotected sqlite3_value objects may only be used with +** [sqlite3_result_value()] and [sqlite3_bind_value()]. +** The [sqlite3_value_blob | sqlite3_value_type()] family of +** interfaces require protected sqlite3_value objects. +*/ +typedef struct Mem sqlite3_value; + +/* +** CAPI3REF: SQL Function Context Object +** +** The context in which an SQL function executes is stored in an +** sqlite3_context object. ^A pointer to an sqlite3_context object +** is always first parameter to [application-defined SQL functions]. +** The application-defined SQL function implementation will pass this +** pointer through into calls to [sqlite3_result_int | sqlite3_result()], +** [sqlite3_aggregate_context()], [sqlite3_user_data()], +** [sqlite3_context_db_handle()], [sqlite3_get_auxdata()], +** and/or [sqlite3_set_auxdata()]. +*/ +typedef struct sqlite3_context sqlite3_context; + +/* +** CAPI3REF: Binding Values To Prepared Statements +** KEYWORDS: {host parameter} {host parameters} {host parameter name} +** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding} +** +** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, +** literals may be replaced by a [parameter] that matches one of following +** templates: +** +**
    +**
  • ? +**
  • ?NNN +**
  • :VVV +**
  • @VVV +**
  • $VVV +**
+** +** In the templates above, NNN represents an integer literal, +** and VVV represents an alphanumeric identifier.)^ ^The values of these +** parameters (also called "host parameter names" or "SQL parameters") +** can be set using the sqlite3_bind_*() routines defined here. +** +** ^The first argument to the sqlite3_bind_*() routines is always +** a pointer to the [sqlite3_stmt] object returned from +** [sqlite3_prepare_v2()] or its variants. +** +** ^The second argument is the index of the SQL parameter to be set. +** ^The leftmost SQL parameter has an index of 1. ^When the same named +** SQL parameter is used more than once, second and subsequent +** occurrences have the same index as the first occurrence. +** ^The index for named parameters can be looked up using the +** [sqlite3_bind_parameter_index()] API if desired. ^The index +** for "?NNN" parameters is the value of NNN. +** ^The NNN value must be between 1 and the [sqlite3_limit()] +** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 999). +** +** ^The third argument is the value to bind to the parameter. +** +** ^(In those routines that have a fourth argument, its value is the +** number of bytes in the parameter. To be clear: the value is the +** number of bytes in the value, not the number of characters.)^ +** ^If the fourth parameter is negative, the length of the string is +** the number of bytes up to the first zero terminator. +** If a non-negative fourth parameter is provided to sqlite3_bind_text() +** or sqlite3_bind_text16() then that parameter must be the byte offset +** where the NUL terminator would occur assuming the string were NUL +** terminated. If any NUL characters occur at byte offsets less than +** the value of the fourth parameter then the resulting string value will +** contain embedded NULs. The result of expressions involving strings +** with embedded NULs is undefined. +** +** ^The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and +** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or +** string after SQLite has finished with it. ^The destructor is called +** to dispose of the BLOB or string even if the call to sqlite3_bind_blob(), +** sqlite3_bind_text(), or sqlite3_bind_text16() fails. +** ^If the fifth argument is +** the special value [SQLITE_STATIC], then SQLite assumes that the +** information is in static, unmanaged space and does not need to be freed. +** ^If the fifth argument has the value [SQLITE_TRANSIENT], then +** SQLite makes its own private copy of the data immediately, before +** the sqlite3_bind_*() routine returns. +** +** ^The sqlite3_bind_zeroblob() routine binds a BLOB of length N that +** is filled with zeroes. ^A zeroblob uses a fixed amount of memory +** (just an integer to hold its size) while it is being processed. +** Zeroblobs are intended to serve as placeholders for BLOBs whose +** content is later written using +** [sqlite3_blob_open | incremental BLOB I/O] routines. +** ^A negative value for the zeroblob results in a zero-length BLOB. +** +** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer +** for the [prepared statement] or with a prepared statement for which +** [sqlite3_step()] has been called more recently than [sqlite3_reset()], +** then the call will return [SQLITE_MISUSE]. If any sqlite3_bind_() +** routine is passed a [prepared statement] that has been finalized, the +** result is undefined and probably harmful. +** +** ^Bindings are not cleared by the [sqlite3_reset()] routine. +** ^Unbound parameters are interpreted as NULL. +** +** ^The sqlite3_bind_* routines return [SQLITE_OK] on success or an +** [error code] if anything goes wrong. +** ^[SQLITE_RANGE] is returned if the parameter +** index is out of range. ^[SQLITE_NOMEM] is returned if malloc() fails. +** +** See also: [sqlite3_bind_parameter_count()], +** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); +SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double); +SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int); +SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); +SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int); +SQLITE_API int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*)); +SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); +SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); +SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); + +/* +** CAPI3REF: Number Of SQL Parameters +** +** ^This routine can be used to find the number of [SQL parameters] +** in a [prepared statement]. SQL parameters are tokens of the +** form "?", "?NNN", ":AAA", "$AAA", or "@AAA" that serve as +** placeholders for values that are [sqlite3_bind_blob | bound] +** to the parameters at a later time. +** +** ^(This routine actually returns the index of the largest (rightmost) +** parameter. For all forms except ?NNN, this will correspond to the +** number of unique parameters. If parameters of the ?NNN form are used, +** there may be gaps in the list.)^ +** +** See also: [sqlite3_bind_blob|sqlite3_bind()], +** [sqlite3_bind_parameter_name()], and +** [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*); + +/* +** CAPI3REF: Name Of A Host Parameter +** +** ^The sqlite3_bind_parameter_name(P,N) interface returns +** the name of the N-th [SQL parameter] in the [prepared statement] P. +** ^(SQL parameters of the form "?NNN" or ":AAA" or "@AAA" or "$AAA" +** have a name which is the string "?NNN" or ":AAA" or "@AAA" or "$AAA" +** respectively. +** In other words, the initial ":" or "$" or "@" or "?" +** is included as part of the name.)^ +** ^Parameters of the form "?" without a following integer have no name +** and are referred to as "nameless" or "anonymous parameters". +** +** ^The first host parameter has an index of 1, not 0. +** +** ^If the value N is out of range or if the N-th parameter is +** nameless, then NULL is returned. ^The returned string is +** always in UTF-8 encoding even if the named parameter was +** originally specified as UTF-16 in [sqlite3_prepare16()] or +** [sqlite3_prepare16_v2()]. +** +** See also: [sqlite3_bind_blob|sqlite3_bind()], +** [sqlite3_bind_parameter_count()], and +** [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); + +/* +** CAPI3REF: Index Of A Parameter With A Given Name +** +** ^Return the index of an SQL parameter given its name. ^The +** index value returned is suitable for use as the second +** parameter to [sqlite3_bind_blob|sqlite3_bind()]. ^A zero +** is returned if no matching parameter is found. ^The parameter +** name must be given in UTF-8 even if the original statement +** was prepared from UTF-16 text using [sqlite3_prepare16_v2()]. +** +** See also: [sqlite3_bind_blob|sqlite3_bind()], +** [sqlite3_bind_parameter_count()], and +** [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); + +/* +** CAPI3REF: Reset All Bindings On A Prepared Statement +** +** ^Contrary to the intuition of many, [sqlite3_reset()] does not reset +** the [sqlite3_bind_blob | bindings] on a [prepared statement]. +** ^Use this routine to reset all host parameters to NULL. +*/ +SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*); + +/* +** CAPI3REF: Number Of Columns In A Result Set +** +** ^Return the number of columns in the result set returned by the +** [prepared statement]. ^This routine returns 0 if pStmt is an SQL +** statement that does not return data (for example an [UPDATE]). +** +** See also: [sqlite3_data_count()] +*/ +SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Column Names In A Result Set +** +** ^These routines return the name assigned to a particular column +** in the result set of a [SELECT] statement. ^The sqlite3_column_name() +** interface returns a pointer to a zero-terminated UTF-8 string +** and sqlite3_column_name16() returns a pointer to a zero-terminated +** UTF-16 string. ^The first parameter is the [prepared statement] +** that implements the [SELECT] statement. ^The second parameter is the +** column number. ^The leftmost column is number 0. +** +** ^The returned string pointer is valid until either the [prepared statement] +** is destroyed by [sqlite3_finalize()] or until the statement is automatically +** reprepared by the first call to [sqlite3_step()] for a particular run +** or until the next call to +** sqlite3_column_name() or sqlite3_column_name16() on the same column. +** +** ^If sqlite3_malloc() fails during the processing of either routine +** (for example during a conversion from UTF-8 to UTF-16) then a +** NULL pointer is returned. +** +** ^The name of a result column is the value of the "AS" clause for +** that column, if there is an AS clause. If there is no AS clause +** then the name of the column is unspecified and may change from +** one release of SQLite to the next. +*/ +SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N); +SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N); + +/* +** CAPI3REF: Source Of Data In A Query Result +** +** ^These routines provide a means to determine the database, table, and +** table column that is the origin of a particular result column in +** [SELECT] statement. +** ^The name of the database or table or column can be returned as +** either a UTF-8 or UTF-16 string. ^The _database_ routines return +** the database name, the _table_ routines return the table name, and +** the origin_ routines return the column name. +** ^The returned string is valid until the [prepared statement] is destroyed +** using [sqlite3_finalize()] or until the statement is automatically +** reprepared by the first call to [sqlite3_step()] for a particular run +** or until the same information is requested +** again in a different encoding. +** +** ^The names returned are the original un-aliased names of the +** database, table, and column. +** +** ^The first argument to these interfaces is a [prepared statement]. +** ^These functions return information about the Nth result column returned by +** the statement, where N is the second function argument. +** ^The left-most column is column 0 for these routines. +** +** ^If the Nth column returned by the statement is an expression or +** subquery and is not a column value, then all of these functions return +** NULL. ^These routine might also return NULL if a memory allocation error +** occurs. ^Otherwise, they return the name of the attached database, table, +** or column that query result column was extracted from. +** +** ^As with all other SQLite APIs, those whose names end with "16" return +** UTF-16 encoded strings and the other functions return UTF-8. +** +** ^These APIs are only available if the library was compiled with the +** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol. +** +** If two or more threads call one or more of these routines against the same +** prepared statement and column at the same time then the results are +** undefined. +** +** If two or more threads call one or more +** [sqlite3_column_database_name | column metadata interfaces] +** for the same [prepared statement] and result column +** at the same time then the results are undefined. +*/ +SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int); +SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int); +SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Declared Datatype Of A Query Result +** +** ^(The first parameter is a [prepared statement]. +** If this statement is a [SELECT] statement and the Nth column of the +** returned result set of that [SELECT] is a table column (not an +** expression or subquery) then the declared type of the table +** column is returned.)^ ^If the Nth column of the result set is an +** expression or subquery, then a NULL pointer is returned. +** ^The returned string is always UTF-8 encoded. +** +** ^(For example, given the database schema: +** +** CREATE TABLE t1(c1 VARIANT); +** +** and the following statement to be compiled: +** +** SELECT c1 + 1, c1 FROM t1; +** +** this routine would return the string "VARIANT" for the second result +** column (i==1), and a NULL pointer for the first result column (i==0).)^ +** +** ^SQLite uses dynamic run-time typing. ^So just because a column +** is declared to contain a particular type does not mean that the +** data stored in that column is of the declared type. SQLite is +** strongly typed, but the typing is dynamic not static. ^Type +** is associated with individual values, not with the containers +** used to hold those values. +*/ +SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Evaluate An SQL Statement +** +** After a [prepared statement] has been prepared using either +** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy +** interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function +** must be called one or more times to evaluate the statement. +** +** The details of the behavior of the sqlite3_step() interface depend +** on whether the statement was prepared using the newer "v2" interface +** [sqlite3_prepare_v2()] and [sqlite3_prepare16_v2()] or the older legacy +** interface [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the +** new "v2" interface is recommended for new applications but the legacy +** interface will continue to be supported. +** +** ^In the legacy interface, the return value will be either [SQLITE_BUSY], +** [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE]. +** ^With the "v2" interface, any of the other [result codes] or +** [extended result codes] might be returned as well. +** +** ^[SQLITE_BUSY] means that the database engine was unable to acquire the +** database locks it needs to do its job. ^If the statement is a [COMMIT] +** or occurs outside of an explicit transaction, then you can retry the +** statement. If the statement is not a [COMMIT] and occurs within an +** explicit transaction then you should rollback the transaction before +** continuing. +** +** ^[SQLITE_DONE] means that the statement has finished executing +** successfully. sqlite3_step() should not be called again on this virtual +** machine without first calling [sqlite3_reset()] to reset the virtual +** machine back to its initial state. +** +** ^If the SQL statement being executed returns any data, then [SQLITE_ROW] +** is returned each time a new row of data is ready for processing by the +** caller. The values may be accessed using the [column access functions]. +** sqlite3_step() is called again to retrieve the next row of data. +** +** ^[SQLITE_ERROR] means that a run-time error (such as a constraint +** violation) has occurred. sqlite3_step() should not be called again on +** the VM. More information may be found by calling [sqlite3_errmsg()]. +** ^With the legacy interface, a more specific error code (for example, +** [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth) +** can be obtained by calling [sqlite3_reset()] on the +** [prepared statement]. ^In the "v2" interface, +** the more specific error code is returned directly by sqlite3_step(). +** +** [SQLITE_MISUSE] means that the this routine was called inappropriately. +** Perhaps it was called on a [prepared statement] that has +** already been [sqlite3_finalize | finalized] or on one that had +** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could +** be the case that the same database connection is being used by two or +** more threads at the same moment in time. +** +** For all versions of SQLite up to and including 3.6.23.1, a call to +** [sqlite3_reset()] was required after sqlite3_step() returned anything +** other than [SQLITE_ROW] before any subsequent invocation of +** sqlite3_step(). Failure to reset the prepared statement using +** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from +** sqlite3_step(). But after version 3.6.23.1, sqlite3_step() began +** calling [sqlite3_reset()] automatically in this circumstance rather +** than returning [SQLITE_MISUSE]. This is not considered a compatibility +** break because any application that ever receives an SQLITE_MISUSE error +** is broken by definition. The [SQLITE_OMIT_AUTORESET] compile-time option +** can be used to restore the legacy behavior. +** +** Goofy Interface Alert: In the legacy interface, the sqlite3_step() +** API always returns a generic error code, [SQLITE_ERROR], following any +** error other than [SQLITE_BUSY] and [SQLITE_MISUSE]. You must call +** [sqlite3_reset()] or [sqlite3_finalize()] in order to find one of the +** specific [error codes] that better describes the error. +** We admit that this is a goofy design. The problem has been fixed +** with the "v2" interface. If you prepare all of your SQL statements +** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead +** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces, +** then the more specific [error codes] are returned directly +** by sqlite3_step(). The use of the "v2" interface is recommended. +*/ +SQLITE_API int sqlite3_step(sqlite3_stmt*); + +/* +** CAPI3REF: Number of columns in a result set +** +** ^The sqlite3_data_count(P) interface returns the number of columns in the +** current row of the result set of [prepared statement] P. +** ^If prepared statement P does not have results ready to return +** (via calls to the [sqlite3_column_int | sqlite3_column_*()] of +** interfaces) then sqlite3_data_count(P) returns 0. +** ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer. +** ^The sqlite3_data_count(P) routine returns 0 if the previous call to +** [sqlite3_step](P) returned [SQLITE_DONE]. ^The sqlite3_data_count(P) +** will return non-zero if previous call to [sqlite3_step](P) returned +** [SQLITE_ROW], except in the case of the [PRAGMA incremental_vacuum] +** where it always returns zero since each step of that multi-step +** pragma returns 0 columns of data. +** +** See also: [sqlite3_column_count()] +*/ +SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Fundamental Datatypes +** KEYWORDS: SQLITE_TEXT +** +** ^(Every value in SQLite has one of five fundamental datatypes: +** +**
    +**
  • 64-bit signed integer +**
  • 64-bit IEEE floating point number +**
  • string +**
  • BLOB +**
  • NULL +**
)^ +** +** These constants are codes for each of those types. +** +** Note that the SQLITE_TEXT constant was also used in SQLite version 2 +** for a completely different meaning. Software that links against both +** SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT, not +** SQLITE_TEXT. +*/ +#define SQLITE_INTEGER 1 +#define SQLITE_FLOAT 2 +#define SQLITE_BLOB 4 +#define SQLITE_NULL 5 +#ifdef SQLITE_TEXT +# undef SQLITE_TEXT +#else +# define SQLITE_TEXT 3 +#endif +#define SQLITE3_TEXT 3 + +/* +** CAPI3REF: Result Values From A Query +** KEYWORDS: {column access functions} +** +** These routines form the "result set" interface. +** +** ^These routines return information about a single column of the current +** result row of a query. ^In every case the first argument is a pointer +** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*] +** that was returned from [sqlite3_prepare_v2()] or one of its variants) +** and the second argument is the index of the column for which information +** should be returned. ^The leftmost column of the result set has the index 0. +** ^The number of columns in the result can be determined using +** [sqlite3_column_count()]. +** +** If the SQL statement does not currently point to a valid row, or if the +** column index is out of range, the result is undefined. +** These routines may only be called when the most recent call to +** [sqlite3_step()] has returned [SQLITE_ROW] and neither +** [sqlite3_reset()] nor [sqlite3_finalize()] have been called subsequently. +** If any of these routines are called after [sqlite3_reset()] or +** [sqlite3_finalize()] or after [sqlite3_step()] has returned +** something other than [SQLITE_ROW], the results are undefined. +** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()] +** are called from a different thread while any of these routines +** are pending, then the results are undefined. +** +** ^The sqlite3_column_type() routine returns the +** [SQLITE_INTEGER | datatype code] for the initial data type +** of the result column. ^The returned value is one of [SQLITE_INTEGER], +** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL]. The value +** returned by sqlite3_column_type() is only meaningful if no type +** conversions have occurred as described below. After a type conversion, +** the value returned by sqlite3_column_type() is undefined. Future +** versions of SQLite may change the behavior of sqlite3_column_type() +** following a type conversion. +** +** ^If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes() +** routine returns the number of bytes in that BLOB or string. +** ^If the result is a UTF-16 string, then sqlite3_column_bytes() converts +** the string to UTF-8 and then returns the number of bytes. +** ^If the result is a numeric value then sqlite3_column_bytes() uses +** [sqlite3_snprintf()] to convert that value to a UTF-8 string and returns +** the number of bytes in that string. +** ^If the result is NULL, then sqlite3_column_bytes() returns zero. +** +** ^If the result is a BLOB or UTF-16 string then the sqlite3_column_bytes16() +** routine returns the number of bytes in that BLOB or string. +** ^If the result is a UTF-8 string, then sqlite3_column_bytes16() converts +** the string to UTF-16 and then returns the number of bytes. +** ^If the result is a numeric value then sqlite3_column_bytes16() uses +** [sqlite3_snprintf()] to convert that value to a UTF-16 string and returns +** the number of bytes in that string. +** ^If the result is NULL, then sqlite3_column_bytes16() returns zero. +** +** ^The values returned by [sqlite3_column_bytes()] and +** [sqlite3_column_bytes16()] do not include the zero terminators at the end +** of the string. ^For clarity: the values returned by +** [sqlite3_column_bytes()] and [sqlite3_column_bytes16()] are the number of +** bytes in the string, not the number of characters. +** +** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(), +** even empty strings, are always zero-terminated. ^The return +** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer. +** +** ^The object returned by [sqlite3_column_value()] is an +** [unprotected sqlite3_value] object. An unprotected sqlite3_value object +** may only be used with [sqlite3_bind_value()] and [sqlite3_result_value()]. +** If the [unprotected sqlite3_value] object returned by +** [sqlite3_column_value()] is used in any other way, including calls +** to routines like [sqlite3_value_int()], [sqlite3_value_text()], +** or [sqlite3_value_bytes()], then the behavior is undefined. +** +** These routines attempt to convert the value where appropriate. ^For +** example, if the internal representation is FLOAT and a text result +** is requested, [sqlite3_snprintf()] is used internally to perform the +** conversion automatically. ^(The following table details the conversions +** that are applied: +** +**
+** +**
Internal
Type
Requested
Type
Conversion +** +**
NULL INTEGER Result is 0 +**
NULL FLOAT Result is 0.0 +**
NULL TEXT Result is NULL pointer +**
NULL BLOB Result is NULL pointer +**
INTEGER FLOAT Convert from integer to float +**
INTEGER TEXT ASCII rendering of the integer +**
INTEGER BLOB Same as INTEGER->TEXT +**
FLOAT INTEGER Convert from float to integer +**
FLOAT TEXT ASCII rendering of the float +**
FLOAT BLOB Same as FLOAT->TEXT +**
TEXT INTEGER Use atoi() +**
TEXT FLOAT Use atof() +**
TEXT BLOB No change +**
BLOB INTEGER Convert to TEXT then use atoi() +**
BLOB FLOAT Convert to TEXT then use atof() +**
BLOB TEXT Add a zero terminator if needed +**
+**
)^ +** +** The table above makes reference to standard C library functions atoi() +** and atof(). SQLite does not really use these functions. It has its +** own equivalent internal routines. The atoi() and atof() names are +** used in the table for brevity and because they are familiar to most +** C programmers. +** +** Note that when type conversions occur, pointers returned by prior +** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or +** sqlite3_column_text16() may be invalidated. +** Type conversions and pointer invalidations might occur +** in the following cases: +** +**
    +**
  • The initial content is a BLOB and sqlite3_column_text() or +** sqlite3_column_text16() is called. A zero-terminator might +** need to be added to the string.
  • +**
  • The initial content is UTF-8 text and sqlite3_column_bytes16() or +** sqlite3_column_text16() is called. The content must be converted +** to UTF-16.
  • +**
  • The initial content is UTF-16 text and sqlite3_column_bytes() or +** sqlite3_column_text() is called. The content must be converted +** to UTF-8.
  • +**
+** +** ^Conversions between UTF-16be and UTF-16le are always done in place and do +** not invalidate a prior pointer, though of course the content of the buffer +** that the prior pointer references will have been modified. Other kinds +** of conversion are done in place when it is possible, but sometimes they +** are not possible and in those cases prior pointers are invalidated. +** +** The safest and easiest to remember policy is to invoke these routines +** in one of the following ways: +** +**
    +**
  • sqlite3_column_text() followed by sqlite3_column_bytes()
  • +**
  • sqlite3_column_blob() followed by sqlite3_column_bytes()
  • +**
  • sqlite3_column_text16() followed by sqlite3_column_bytes16()
  • +**
+** +** In other words, you should call sqlite3_column_text(), +** sqlite3_column_blob(), or sqlite3_column_text16() first to force the result +** into the desired format, then invoke sqlite3_column_bytes() or +** sqlite3_column_bytes16() to find the size of the result. Do not mix calls +** to sqlite3_column_text() or sqlite3_column_blob() with calls to +** sqlite3_column_bytes16(), and do not mix calls to sqlite3_column_text16() +** with calls to sqlite3_column_bytes(). +** +** ^The pointers returned are valid until a type conversion occurs as +** described above, or until [sqlite3_step()] or [sqlite3_reset()] or +** [sqlite3_finalize()] is called. ^The memory space used to hold strings +** and BLOBs is freed automatically. Do not pass the pointers returned +** [sqlite3_column_blob()], [sqlite3_column_text()], etc. into +** [sqlite3_free()]. +** +** ^(If a memory allocation error occurs during the evaluation of any +** of these routines, a default value is returned. The default value +** is either the integer 0, the floating point number 0.0, or a NULL +** pointer. Subsequent calls to [sqlite3_errcode()] will return +** [SQLITE_NOMEM].)^ +*/ +SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); +SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol); +SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); +SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); +SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol); +SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); + +/* +** CAPI3REF: Destroy A Prepared Statement Object +** +** ^The sqlite3_finalize() function is called to delete a [prepared statement]. +** ^If the most recent evaluation of the statement encountered no errors +** or if the statement is never been evaluated, then sqlite3_finalize() returns +** SQLITE_OK. ^If the most recent evaluation of statement S failed, then +** sqlite3_finalize(S) returns the appropriate [error code] or +** [extended error code]. +** +** ^The sqlite3_finalize(S) routine can be called at any point during +** the life cycle of [prepared statement] S: +** before statement S is ever evaluated, after +** one or more calls to [sqlite3_reset()], or after any call +** to [sqlite3_step()] regardless of whether or not the statement has +** completed execution. +** +** ^Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op. +** +** The application must finalize every [prepared statement] in order to avoid +** resource leaks. It is a grievous error for the application to try to use +** a prepared statement after it has been finalized. Any use of a prepared +** statement after it has been finalized can result in undefined and +** undesirable behavior such as segfaults and heap corruption. +*/ +SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Reset A Prepared Statement Object +** +** The sqlite3_reset() function is called to reset a [prepared statement] +** object back to its initial state, ready to be re-executed. +** ^Any SQL statement variables that had values bound to them using +** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values. +** Use [sqlite3_clear_bindings()] to reset the bindings. +** +** ^The [sqlite3_reset(S)] interface resets the [prepared statement] S +** back to the beginning of its program. +** +** ^If the most recent call to [sqlite3_step(S)] for the +** [prepared statement] S returned [SQLITE_ROW] or [SQLITE_DONE], +** or if [sqlite3_step(S)] has never before been called on S, +** then [sqlite3_reset(S)] returns [SQLITE_OK]. +** +** ^If the most recent call to [sqlite3_step(S)] for the +** [prepared statement] S indicated an error, then +** [sqlite3_reset(S)] returns an appropriate [error code]. +** +** ^The [sqlite3_reset(S)] interface does not change the values +** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S. +*/ +SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Create Or Redefine SQL Functions +** KEYWORDS: {function creation routines} +** KEYWORDS: {application-defined SQL function} +** KEYWORDS: {application-defined SQL functions} +** +** ^These functions (collectively known as "function creation routines") +** are used to add SQL functions or aggregates or to redefine the behavior +** of existing SQL functions or aggregates. The only differences between +** these routines are the text encoding expected for +** the second parameter (the name of the function being created) +** and the presence or absence of a destructor callback for +** the application data pointer. +** +** ^The first parameter is the [database connection] to which the SQL +** function is to be added. ^If an application uses more than one database +** connection then application-defined SQL functions must be added +** to each database connection separately. +** +** ^The second parameter is the name of the SQL function to be created or +** redefined. ^The length of the name is limited to 255 bytes in a UTF-8 +** representation, exclusive of the zero-terminator. ^Note that the name +** length limit is in UTF-8 bytes, not characters nor UTF-16 bytes. +** ^Any attempt to create a function with a longer name +** will result in [SQLITE_MISUSE] being returned. +** +** ^The third parameter (nArg) +** is the number of arguments that the SQL function or +** aggregate takes. ^If this parameter is -1, then the SQL function or +** aggregate may take any number of arguments between 0 and the limit +** set by [sqlite3_limit]([SQLITE_LIMIT_FUNCTION_ARG]). If the third +** parameter is less than -1 or greater than 127 then the behavior is +** undefined. +** +** ^The fourth parameter, eTextRep, specifies what +** [SQLITE_UTF8 | text encoding] this SQL function prefers for +** its parameters. Every SQL function implementation must be able to work +** with UTF-8, UTF-16le, or UTF-16be. But some implementations may be +** more efficient with one encoding than another. ^An application may +** invoke sqlite3_create_function() or sqlite3_create_function16() multiple +** times with the same function but with different values of eTextRep. +** ^When multiple implementations of the same function are available, SQLite +** will pick the one that involves the least amount of data conversion. +** If there is only a single implementation which does not care what text +** encoding is used, then the fourth argument should be [SQLITE_ANY]. +** +** ^(The fifth parameter is an arbitrary pointer. The implementation of the +** function can gain access to this pointer using [sqlite3_user_data()].)^ +** +** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are +** pointers to C-language functions that implement the SQL function or +** aggregate. ^A scalar SQL function requires an implementation of the xFunc +** callback only; NULL pointers must be passed as the xStep and xFinal +** parameters. ^An aggregate SQL function requires an implementation of xStep +** and xFinal and NULL pointer must be passed for xFunc. ^To delete an existing +** SQL function or aggregate, pass NULL pointers for all three function +** callbacks. +** +** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL, +** then it is destructor for the application data pointer. +** The destructor is invoked when the function is deleted, either by being +** overloaded or when the database connection closes.)^ +** ^The destructor is also invoked if the call to +** sqlite3_create_function_v2() fails. +** ^When the destructor callback of the tenth parameter is invoked, it +** is passed a single argument which is a copy of the application data +** pointer which was the fifth parameter to sqlite3_create_function_v2(). +** +** ^It is permitted to register multiple implementations of the same +** functions with the same name but with either differing numbers of +** arguments or differing preferred text encodings. ^SQLite will use +** the implementation that most closely matches the way in which the +** SQL function is used. ^A function implementation with a non-negative +** nArg parameter is a better match than a function implementation with +** a negative nArg. ^A function where the preferred text encoding +** matches the database encoding is a better +** match than a function where the encoding is different. +** ^A function where the encoding difference is between UTF16le and UTF16be +** is a closer match than a function where the encoding difference is +** between UTF8 and UTF16. +** +** ^Built-in functions may be overloaded by new application-defined functions. +** +** ^An application-defined function is permitted to call other +** SQLite interfaces. However, such calls must not +** close the database connection nor finalize or reset the prepared +** statement in which the function is running. +*/ +SQLITE_API int sqlite3_create_function( + sqlite3 *db, + const char *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); +SQLITE_API int sqlite3_create_function16( + sqlite3 *db, + const void *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); +SQLITE_API int sqlite3_create_function_v2( + sqlite3 *db, + const char *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void(*xDestroy)(void*) +); + +/* +** CAPI3REF: Text Encodings +** +** These constant define integer codes that represent the various +** text encodings supported by SQLite. +*/ +#define SQLITE_UTF8 1 +#define SQLITE_UTF16LE 2 +#define SQLITE_UTF16BE 3 +#define SQLITE_UTF16 4 /* Use native byte order */ +#define SQLITE_ANY 5 /* sqlite3_create_function only */ +#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */ + +/* +** CAPI3REF: Deprecated Functions +** DEPRECATED +** +** These functions are [deprecated]. In order to maintain +** backwards compatibility with older code, these functions continue +** to be supported. However, new applications should avoid +** the use of these functions. To help encourage people to avoid +** using these functions, we are not going to tell you what they do. +*/ +#ifndef SQLITE_OMIT_DEPRECATED +SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*); +SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*); +SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); +SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void); +SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void); +SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),void*,sqlite3_int64); +#endif + +/* +** CAPI3REF: Obtaining SQL Function Parameter Values +** +** The C-language implementation of SQL functions and aggregates uses +** this set of interface routines to access the parameter values on +** the function or aggregate. +** +** The xFunc (for scalar functions) or xStep (for aggregates) parameters +** to [sqlite3_create_function()] and [sqlite3_create_function16()] +** define callbacks that implement the SQL functions and aggregates. +** The 3rd parameter to these callbacks is an array of pointers to +** [protected sqlite3_value] objects. There is one [sqlite3_value] object for +** each parameter to the SQL function. These routines are used to +** extract values from the [sqlite3_value] objects. +** +** These routines work only with [protected sqlite3_value] objects. +** Any attempt to use these routines on an [unprotected sqlite3_value] +** object results in undefined behavior. +** +** ^These routines work just like the corresponding [column access functions] +** except that these routines take a single [protected sqlite3_value] object +** pointer instead of a [sqlite3_stmt*] pointer and an integer column number. +** +** ^The sqlite3_value_text16() interface extracts a UTF-16 string +** in the native byte-order of the host machine. ^The +** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces +** extract UTF-16 strings as big-endian and little-endian respectively. +** +** ^(The sqlite3_value_numeric_type() interface attempts to apply +** numeric affinity to the value. This means that an attempt is +** made to convert the value to an integer or floating point. If +** such a conversion is possible without loss of information (in other +** words, if the value is a string that looks like a number) +** then the conversion is performed. Otherwise no conversion occurs. +** The [SQLITE_INTEGER | datatype] after conversion is returned.)^ +** +** Please pay particular attention to the fact that the pointer returned +** from [sqlite3_value_blob()], [sqlite3_value_text()], or +** [sqlite3_value_text16()] can be invalidated by a subsequent call to +** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()], +** or [sqlite3_value_text16()]. +** +** These routines must be called from the same thread as +** the SQL function that supplied the [sqlite3_value*] parameters. +*/ +SQLITE_API const void *sqlite3_value_blob(sqlite3_value*); +SQLITE_API int sqlite3_value_bytes(sqlite3_value*); +SQLITE_API int sqlite3_value_bytes16(sqlite3_value*); +SQLITE_API double sqlite3_value_double(sqlite3_value*); +SQLITE_API int sqlite3_value_int(sqlite3_value*); +SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*); +SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*); +SQLITE_API const void *sqlite3_value_text16(sqlite3_value*); +SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*); +SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*); +SQLITE_API int sqlite3_value_type(sqlite3_value*); +SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); + +/* +** CAPI3REF: Obtain Aggregate Function Context +** +** Implementations of aggregate SQL functions use this +** routine to allocate memory for storing their state. +** +** ^The first time the sqlite3_aggregate_context(C,N) routine is called +** for a particular aggregate function, SQLite +** allocates N of memory, zeroes out that memory, and returns a pointer +** to the new memory. ^On second and subsequent calls to +** sqlite3_aggregate_context() for the same aggregate function instance, +** the same buffer is returned. Sqlite3_aggregate_context() is normally +** called once for each invocation of the xStep callback and then one +** last time when the xFinal callback is invoked. ^(When no rows match +** an aggregate query, the xStep() callback of the aggregate function +** implementation is never called and xFinal() is called exactly once. +** In those cases, sqlite3_aggregate_context() might be called for the +** first time from within xFinal().)^ +** +** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer if N is +** less than or equal to zero or if a memory allocate error occurs. +** +** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is +** determined by the N parameter on first successful call. Changing the +** value of N in subsequent call to sqlite3_aggregate_context() within +** the same aggregate function instance will not resize the memory +** allocation.)^ +** +** ^SQLite automatically frees the memory allocated by +** sqlite3_aggregate_context() when the aggregate query concludes. +** +** The first parameter must be a copy of the +** [sqlite3_context | SQL function context] that is the first parameter +** to the xStep or xFinal callback routine that implements the aggregate +** function. +** +** This routine must be called from the same thread in which +** the aggregate SQL function is running. +*/ +SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); + +/* +** CAPI3REF: User Data For Functions +** +** ^The sqlite3_user_data() interface returns a copy of +** the pointer that was the pUserData parameter (the 5th parameter) +** of the [sqlite3_create_function()] +** and [sqlite3_create_function16()] routines that originally +** registered the application defined function. +** +** This routine must be called from the same thread in which +** the application-defined function is running. +*/ +SQLITE_API void *sqlite3_user_data(sqlite3_context*); + +/* +** CAPI3REF: Database Connection For Functions +** +** ^The sqlite3_context_db_handle() interface returns a copy of +** the pointer to the [database connection] (the 1st parameter) +** of the [sqlite3_create_function()] +** and [sqlite3_create_function16()] routines that originally +** registered the application defined function. +*/ +SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); + +/* +** CAPI3REF: Function Auxiliary Data +** +** The following two functions may be used by scalar SQL functions to +** associate metadata with argument values. If the same value is passed to +** multiple invocations of the same SQL function during query execution, under +** some circumstances the associated metadata may be preserved. This may +** be used, for example, to add a regular-expression matching scalar +** function. The compiled version of the regular expression is stored as +** metadata associated with the SQL value passed as the regular expression +** pattern. The compiled regular expression can be reused on multiple +** invocations of the same function so that the original pattern string +** does not need to be recompiled on each invocation. +** +** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata +** associated by the sqlite3_set_auxdata() function with the Nth argument +** value to the application-defined function. ^If no metadata has been ever +** been set for the Nth argument of the function, or if the corresponding +** function parameter has changed since the meta-data was set, +** then sqlite3_get_auxdata() returns a NULL pointer. +** +** ^The sqlite3_set_auxdata() interface saves the metadata +** pointed to by its 3rd parameter as the metadata for the N-th +** argument of the application-defined function. Subsequent +** calls to sqlite3_get_auxdata() might return this data, if it has +** not been destroyed. +** ^If it is not NULL, SQLite will invoke the destructor +** function given by the 4th parameter to sqlite3_set_auxdata() on +** the metadata when the corresponding function parameter changes +** or when the SQL statement completes, whichever comes first. +** +** SQLite is free to call the destructor and drop metadata on any +** parameter of any function at any time. ^The only guarantee is that +** the destructor will be called before the metadata is dropped. +** +** ^(In practice, metadata is preserved between function calls for +** expressions that are constant at compile time. This includes literal +** values and [parameters].)^ +** +** These routines must be called from the same thread in which +** the SQL function is running. +*/ +SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N); +SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); + + +/* +** CAPI3REF: Constants Defining Special Destructor Behavior +** +** These are special values for the destructor that is passed in as the +** final argument to routines like [sqlite3_result_blob()]. ^If the destructor +** argument is SQLITE_STATIC, it means that the content pointer is constant +** and will never change. It does not need to be destroyed. ^The +** SQLITE_TRANSIENT value means that the content will likely change in +** the near future and that SQLite should make its own private copy of +** the content before returning. +** +** The typedef is necessary to work around problems in certain +** C++ compilers. See ticket #2191. +*/ +typedef void (*sqlite3_destructor_type)(void*); +#define SQLITE_STATIC ((sqlite3_destructor_type)0) +#define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1) + +/* +** CAPI3REF: Setting The Result Of An SQL Function +** +** These routines are used by the xFunc or xFinal callbacks that +** implement SQL functions and aggregates. See +** [sqlite3_create_function()] and [sqlite3_create_function16()] +** for additional information. +** +** These functions work very much like the [parameter binding] family of +** functions used to bind values to host parameters in prepared statements. +** Refer to the [SQL parameter] documentation for additional information. +** +** ^The sqlite3_result_blob() interface sets the result from +** an application-defined function to be the BLOB whose content is pointed +** to by the second parameter and which is N bytes long where N is the +** third parameter. +** +** ^The sqlite3_result_zeroblob() interfaces set the result of +** the application-defined function to be a BLOB containing all zero +** bytes and N bytes in size, where N is the value of the 2nd parameter. +** +** ^The sqlite3_result_double() interface sets the result from +** an application-defined function to be a floating point value specified +** by its 2nd argument. +** +** ^The sqlite3_result_error() and sqlite3_result_error16() functions +** cause the implemented SQL function to throw an exception. +** ^SQLite uses the string pointed to by the +** 2nd parameter of sqlite3_result_error() or sqlite3_result_error16() +** as the text of an error message. ^SQLite interprets the error +** message string from sqlite3_result_error() as UTF-8. ^SQLite +** interprets the string from sqlite3_result_error16() as UTF-16 in native +** byte order. ^If the third parameter to sqlite3_result_error() +** or sqlite3_result_error16() is negative then SQLite takes as the error +** message all text up through the first zero character. +** ^If the third parameter to sqlite3_result_error() or +** sqlite3_result_error16() is non-negative then SQLite takes that many +** bytes (not characters) from the 2nd parameter as the error message. +** ^The sqlite3_result_error() and sqlite3_result_error16() +** routines make a private copy of the error message text before +** they return. Hence, the calling function can deallocate or +** modify the text after they return without harm. +** ^The sqlite3_result_error_code() function changes the error code +** returned by SQLite as a result of an error in a function. ^By default, +** the error code is SQLITE_ERROR. ^A subsequent call to sqlite3_result_error() +** or sqlite3_result_error16() resets the error code to SQLITE_ERROR. +** +** ^The sqlite3_result_toobig() interface causes SQLite to throw an error +** indicating that a string or BLOB is too long to represent. +** +** ^The sqlite3_result_nomem() interface causes SQLite to throw an error +** indicating that a memory allocation failed. +** +** ^The sqlite3_result_int() interface sets the return value +** of the application-defined function to be the 32-bit signed integer +** value given in the 2nd argument. +** ^The sqlite3_result_int64() interface sets the return value +** of the application-defined function to be the 64-bit signed integer +** value given in the 2nd argument. +** +** ^The sqlite3_result_null() interface sets the return value +** of the application-defined function to be NULL. +** +** ^The sqlite3_result_text(), sqlite3_result_text16(), +** sqlite3_result_text16le(), and sqlite3_result_text16be() interfaces +** set the return value of the application-defined function to be +** a text string which is represented as UTF-8, UTF-16 native byte order, +** UTF-16 little endian, or UTF-16 big endian, respectively. +** ^SQLite takes the text result from the application from +** the 2nd parameter of the sqlite3_result_text* interfaces. +** ^If the 3rd parameter to the sqlite3_result_text* interfaces +** is negative, then SQLite takes result text from the 2nd parameter +** through the first zero character. +** ^If the 3rd parameter to the sqlite3_result_text* interfaces +** is non-negative, then as many bytes (not characters) of the text +** pointed to by the 2nd parameter are taken as the application-defined +** function result. If the 3rd parameter is non-negative, then it +** must be the byte offset into the string where the NUL terminator would +** appear if the string where NUL terminated. If any NUL characters occur +** in the string at a byte offset that is less than the value of the 3rd +** parameter, then the resulting string will contain embedded NULs and the +** result of expressions operating on strings with embedded NULs is undefined. +** ^If the 4th parameter to the sqlite3_result_text* interfaces +** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that +** function as the destructor on the text or BLOB result when it has +** finished using that result. +** ^If the 4th parameter to the sqlite3_result_text* interfaces or to +** sqlite3_result_blob is the special constant SQLITE_STATIC, then SQLite +** assumes that the text or BLOB result is in constant space and does not +** copy the content of the parameter nor call a destructor on the content +** when it has finished using that result. +** ^If the 4th parameter to the sqlite3_result_text* interfaces +** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT +** then SQLite makes a copy of the result into space obtained from +** from [sqlite3_malloc()] before it returns. +** +** ^The sqlite3_result_value() interface sets the result of +** the application-defined function to be a copy the +** [unprotected sqlite3_value] object specified by the 2nd parameter. ^The +** sqlite3_result_value() interface makes a copy of the [sqlite3_value] +** so that the [sqlite3_value] specified in the parameter may change or +** be deallocated after sqlite3_result_value() returns without harm. +** ^A [protected sqlite3_value] object may always be used where an +** [unprotected sqlite3_value] object is required, so either +** kind of [sqlite3_value] object can be used with this interface. +** +** If these routines are called from within the different thread +** than the one containing the application-defined function that received +** the [sqlite3_context] pointer, the results are undefined. +*/ +SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); +SQLITE_API void sqlite3_result_double(sqlite3_context*, double); +SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int); +SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int); +SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*); +SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*); +SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int); +SQLITE_API void sqlite3_result_int(sqlite3_context*, int); +SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); +SQLITE_API void sqlite3_result_null(sqlite3_context*); +SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); +SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); +SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); +SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); +SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*); +SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n); + +/* +** CAPI3REF: Define New Collating Sequences +** +** ^These functions add, remove, or modify a [collation] associated +** with the [database connection] specified as the first argument. +** +** ^The name of the collation is a UTF-8 string +** for sqlite3_create_collation() and sqlite3_create_collation_v2() +** and a UTF-16 string in native byte order for sqlite3_create_collation16(). +** ^Collation names that compare equal according to [sqlite3_strnicmp()] are +** considered to be the same name. +** +** ^(The third argument (eTextRep) must be one of the constants: +**
    +**
  • [SQLITE_UTF8], +**
  • [SQLITE_UTF16LE], +**
  • [SQLITE_UTF16BE], +**
  • [SQLITE_UTF16], or +**
  • [SQLITE_UTF16_ALIGNED]. +**
)^ +** ^The eTextRep argument determines the encoding of strings passed +** to the collating function callback, xCallback. +** ^The [SQLITE_UTF16] and [SQLITE_UTF16_ALIGNED] values for eTextRep +** force strings to be UTF16 with native byte order. +** ^The [SQLITE_UTF16_ALIGNED] value for eTextRep forces strings to begin +** on an even byte address. +** +** ^The fourth argument, pArg, is an application data pointer that is passed +** through as the first argument to the collating function callback. +** +** ^The fifth argument, xCallback, is a pointer to the collating function. +** ^Multiple collating functions can be registered using the same name but +** with different eTextRep parameters and SQLite will use whichever +** function requires the least amount of data transformation. +** ^If the xCallback argument is NULL then the collating function is +** deleted. ^When all collating functions having the same name are deleted, +** that collation is no longer usable. +** +** ^The collating function callback is invoked with a copy of the pArg +** application data pointer and with two strings in the encoding specified +** by the eTextRep argument. The collating function must return an +** integer that is negative, zero, or positive +** if the first string is less than, equal to, or greater than the second, +** respectively. A collating function must always return the same answer +** given the same inputs. If two or more collating functions are registered +** to the same collation name (using different eTextRep values) then all +** must give an equivalent answer when invoked with equivalent strings. +** The collating function must obey the following properties for all +** strings A, B, and C: +** +**
    +**
  1. If A==B then B==A. +**
  2. If A==B and B==C then A==C. +**
  3. If A<B THEN B>A. +**
  4. If A<B and B<C then A<C. +**
+** +** If a collating function fails any of the above constraints and that +** collating function is registered and used, then the behavior of SQLite +** is undefined. +** +** ^The sqlite3_create_collation_v2() works like sqlite3_create_collation() +** with the addition that the xDestroy callback is invoked on pArg when +** the collating function is deleted. +** ^Collating functions are deleted when they are overridden by later +** calls to the collation creation functions or when the +** [database connection] is closed using [sqlite3_close()]. +** +** ^The xDestroy callback is not called if the +** sqlite3_create_collation_v2() function fails. Applications that invoke +** sqlite3_create_collation_v2() with a non-NULL xDestroy argument should +** check the return code and dispose of the application data pointer +** themselves rather than expecting SQLite to deal with it for them. +** This is different from every other SQLite interface. The inconsistency +** is unfortunate but cannot be changed without breaking backwards +** compatibility. +** +** See also: [sqlite3_collation_needed()] and [sqlite3_collation_needed16()]. +*/ +SQLITE_API int sqlite3_create_collation( + sqlite3*, + const char *zName, + int eTextRep, + void *pArg, + int(*xCompare)(void*,int,const void*,int,const void*) +); +SQLITE_API int sqlite3_create_collation_v2( + sqlite3*, + const char *zName, + int eTextRep, + void *pArg, + int(*xCompare)(void*,int,const void*,int,const void*), + void(*xDestroy)(void*) +); +SQLITE_API int sqlite3_create_collation16( + sqlite3*, + const void *zName, + int eTextRep, + void *pArg, + int(*xCompare)(void*,int,const void*,int,const void*) +); + +/* +** CAPI3REF: Collation Needed Callbacks +** +** ^To avoid having to register all collation sequences before a database +** can be used, a single callback function may be registered with the +** [database connection] to be invoked whenever an undefined collation +** sequence is required. +** +** ^If the function is registered using the sqlite3_collation_needed() API, +** then it is passed the names of undefined collation sequences as strings +** encoded in UTF-8. ^If sqlite3_collation_needed16() is used, +** the names are passed as UTF-16 in machine native byte order. +** ^A call to either function replaces the existing collation-needed callback. +** +** ^(When the callback is invoked, the first argument passed is a copy +** of the second argument to sqlite3_collation_needed() or +** sqlite3_collation_needed16(). The second argument is the database +** connection. The third argument is one of [SQLITE_UTF8], [SQLITE_UTF16BE], +** or [SQLITE_UTF16LE], indicating the most desirable form of the collation +** sequence function required. The fourth parameter is the name of the +** required collation sequence.)^ +** +** The callback function should register the desired collation using +** [sqlite3_create_collation()], [sqlite3_create_collation16()], or +** [sqlite3_create_collation_v2()]. +*/ +SQLITE_API int sqlite3_collation_needed( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const char*) +); +SQLITE_API int sqlite3_collation_needed16( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const void*) +); + +#ifdef SQLITE_HAS_CODEC +/* +** Specify the key for an encrypted database. This routine should be +** called right after sqlite3_open(). +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +SQLITE_API int sqlite3_key( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The key */ +); + +/* +** Change the key on an open database. If the current database is not +** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the +** database is decrypted. +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +SQLITE_API int sqlite3_rekey( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The new key */ +); + +/* +** Specify the activation key for a SEE database. Unless +** activated, none of the SEE routines will work. +*/ +SQLITE_API void sqlite3_activate_see( + const char *zPassPhrase /* Activation phrase */ +); +#endif + +#ifdef SQLITE_ENABLE_CEROD +/* +** Specify the activation key for a CEROD database. Unless +** activated, none of the CEROD routines will work. +*/ +SQLITE_API void sqlite3_activate_cerod( + const char *zPassPhrase /* Activation phrase */ +); +#endif + +/* +** CAPI3REF: Suspend Execution For A Short Time +** +** The sqlite3_sleep() function causes the current thread to suspend execution +** for at least a number of milliseconds specified in its parameter. +** +** If the operating system does not support sleep requests with +** millisecond time resolution, then the time will be rounded up to +** the nearest second. The number of milliseconds of sleep actually +** requested from the operating system is returned. +** +** ^SQLite implements this interface by calling the xSleep() +** method of the default [sqlite3_vfs] object. If the xSleep() method +** of the default VFS is not implemented correctly, or not implemented at +** all, then the behavior of sqlite3_sleep() may deviate from the description +** in the previous paragraphs. +*/ +SQLITE_API int sqlite3_sleep(int); + +/* +** CAPI3REF: Name Of The Folder Holding Temporary Files +** +** ^(If this global variable is made to point to a string which is +** the name of a folder (a.k.a. directory), then all temporary files +** created by SQLite when using a built-in [sqlite3_vfs | VFS] +** will be placed in that directory.)^ ^If this variable +** is a NULL pointer, then SQLite performs a search for an appropriate +** temporary file directory. +** +** It is not safe to read or modify this variable in more than one +** thread at a time. It is not safe to read or modify this variable +** if a [database connection] is being used at the same time in a separate +** thread. +** It is intended that this variable be set once +** as part of process initialization and before any SQLite interface +** routines have been called and that this variable remain unchanged +** thereafter. +** +** ^The [temp_store_directory pragma] may modify this variable and cause +** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore, +** the [temp_store_directory pragma] always assumes that any string +** that this variable points to is held in memory obtained from +** [sqlite3_malloc] and the pragma may attempt to free that memory +** using [sqlite3_free]. +** Hence, if this variable is modified directly, either it should be +** made NULL or made to point to memory obtained from [sqlite3_malloc] +** or else the use of the [temp_store_directory pragma] should be avoided. +*/ +SQLITE_API SQLITE_EXTERN char *sqlite3_temp_directory; + +/* +** CAPI3REF: Test For Auto-Commit Mode +** KEYWORDS: {autocommit mode} +** +** ^The sqlite3_get_autocommit() interface returns non-zero or +** zero if the given database connection is or is not in autocommit mode, +** respectively. ^Autocommit mode is on by default. +** ^Autocommit mode is disabled by a [BEGIN] statement. +** ^Autocommit mode is re-enabled by a [COMMIT] or [ROLLBACK]. +** +** If certain kinds of errors occur on a statement within a multi-statement +** transaction (errors including [SQLITE_FULL], [SQLITE_IOERR], +** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the +** transaction might be rolled back automatically. The only way to +** find out whether SQLite automatically rolled back the transaction after +** an error is to use this function. +** +** If another thread changes the autocommit status of the database +** connection while this routine is running, then the return value +** is undefined. +*/ +SQLITE_API int sqlite3_get_autocommit(sqlite3*); + +/* +** CAPI3REF: Find The Database Handle Of A Prepared Statement +** +** ^The sqlite3_db_handle interface returns the [database connection] handle +** to which a [prepared statement] belongs. ^The [database connection] +** returned by sqlite3_db_handle is the same [database connection] +** that was the first argument +** to the [sqlite3_prepare_v2()] call (or its variants) that was used to +** create the statement in the first place. +*/ +SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); + +/* +** CAPI3REF: Return The Filename For A Database Connection +** +** ^The sqlite3_db_filename(D,N) interface returns a pointer to a filename +** associated with database N of connection D. ^The main database file +** has the name "main". If there is no attached database N on the database +** connection D, or if database N is a temporary or in-memory database, then +** a NULL pointer is returned. +** +** ^The filename returned by this function is the output of the +** xFullPathname method of the [VFS]. ^In other words, the filename +** will be an absolute pathname, even if the filename used +** to open the database originally was a URI or relative pathname. +*/ +SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName); + +/* +** CAPI3REF: Find the next prepared statement +** +** ^This interface returns a pointer to the next [prepared statement] after +** pStmt associated with the [database connection] pDb. ^If pStmt is NULL +** then this interface returns a pointer to the first prepared statement +** associated with the database connection pDb. ^If no prepared statement +** satisfies the conditions of this routine, it returns NULL. +** +** The [database connection] pointer D in a call to +** [sqlite3_next_stmt(D,S)] must refer to an open database +** connection and in particular must not be a NULL pointer. +*/ +SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Commit And Rollback Notification Callbacks +** +** ^The sqlite3_commit_hook() interface registers a callback +** function to be invoked whenever a transaction is [COMMIT | committed]. +** ^Any callback set by a previous call to sqlite3_commit_hook() +** for the same database connection is overridden. +** ^The sqlite3_rollback_hook() interface registers a callback +** function to be invoked whenever a transaction is [ROLLBACK | rolled back]. +** ^Any callback set by a previous call to sqlite3_rollback_hook() +** for the same database connection is overridden. +** ^The pArg argument is passed through to the callback. +** ^If the callback on a commit hook function returns non-zero, +** then the commit is converted into a rollback. +** +** ^The sqlite3_commit_hook(D,C,P) and sqlite3_rollback_hook(D,C,P) functions +** return the P argument from the previous call of the same function +** on the same [database connection] D, or NULL for +** the first call for each function on D. +** +** The commit and rollback hook callbacks are not reentrant. +** The callback implementation must not do anything that will modify +** the database connection that invoked the callback. Any actions +** to modify the database connection must be deferred until after the +** completion of the [sqlite3_step()] call that triggered the commit +** or rollback hook in the first place. +** Note that running any other SQL statements, including SELECT statements, +** or merely calling [sqlite3_prepare_v2()] and [sqlite3_step()] will modify +** the database connections for the meaning of "modify" in this paragraph. +** +** ^Registering a NULL function disables the callback. +** +** ^When the commit hook callback routine returns zero, the [COMMIT] +** operation is allowed to continue normally. ^If the commit hook +** returns non-zero, then the [COMMIT] is converted into a [ROLLBACK]. +** ^The rollback hook is invoked on a rollback that results from a commit +** hook returning non-zero, just as it would be with any other rollback. +** +** ^For the purposes of this API, a transaction is said to have been +** rolled back if an explicit "ROLLBACK" statement is executed, or +** an error or constraint causes an implicit rollback to occur. +** ^The rollback callback is not invoked if a transaction is +** automatically rolled back because the database connection is closed. +** +** See also the [sqlite3_update_hook()] interface. +*/ +SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); +SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); + +/* +** CAPI3REF: Data Change Notification Callbacks +** +** ^The sqlite3_update_hook() interface registers a callback function +** with the [database connection] identified by the first argument +** to be invoked whenever a row is updated, inserted or deleted. +** ^Any callback set by a previous call to this function +** for the same database connection is overridden. +** +** ^The second argument is a pointer to the function to invoke when a +** row is updated, inserted or deleted. +** ^The first argument to the callback is a copy of the third argument +** to sqlite3_update_hook(). +** ^The second callback argument is one of [SQLITE_INSERT], [SQLITE_DELETE], +** or [SQLITE_UPDATE], depending on the operation that caused the callback +** to be invoked. +** ^The third and fourth arguments to the callback contain pointers to the +** database and table name containing the affected row. +** ^The final callback parameter is the [rowid] of the row. +** ^In the case of an update, this is the [rowid] after the update takes place. +** +** ^(The update hook is not invoked when internal system tables are +** modified (i.e. sqlite_master and sqlite_sequence).)^ +** +** ^In the current implementation, the update hook +** is not invoked when duplication rows are deleted because of an +** [ON CONFLICT | ON CONFLICT REPLACE] clause. ^Nor is the update hook +** invoked when rows are deleted using the [truncate optimization]. +** The exceptions defined in this paragraph might change in a future +** release of SQLite. +** +** The update hook implementation must not do anything that will modify +** the database connection that invoked the update hook. Any actions +** to modify the database connection must be deferred until after the +** completion of the [sqlite3_step()] call that triggered the update hook. +** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their +** database connections for the meaning of "modify" in this paragraph. +** +** ^The sqlite3_update_hook(D,C,P) function +** returns the P argument from the previous call +** on the same [database connection] D, or NULL for +** the first call on D. +** +** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()] +** interfaces. +*/ +SQLITE_API void *sqlite3_update_hook( + sqlite3*, + void(*)(void *,int ,char const *,char const *,sqlite3_int64), + void* +); + +/* +** CAPI3REF: Enable Or Disable Shared Pager Cache +** KEYWORDS: {shared cache} +** +** ^(This routine enables or disables the sharing of the database cache +** and schema data structures between [database connection | connections] +** to the same database. Sharing is enabled if the argument is true +** and disabled if the argument is false.)^ +** +** ^Cache sharing is enabled and disabled for an entire process. +** This is a change as of SQLite version 3.5.0. In prior versions of SQLite, +** sharing was enabled or disabled for each thread separately. +** +** ^(The cache sharing mode set by this interface effects all subsequent +** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()]. +** Existing database connections continue use the sharing mode +** that was in effect at the time they were opened.)^ +** +** ^(This routine returns [SQLITE_OK] if shared cache was enabled or disabled +** successfully. An [error code] is returned otherwise.)^ +** +** ^Shared cache is disabled by default. But this might change in +** future releases of SQLite. Applications that care about shared +** cache setting should set it explicitly. +** +** See Also: [SQLite Shared-Cache Mode] +*/ +SQLITE_API int sqlite3_enable_shared_cache(int); + +/* +** CAPI3REF: Attempt To Free Heap Memory +** +** ^The sqlite3_release_memory() interface attempts to free N bytes +** of heap memory by deallocating non-essential memory allocations +** held by the database library. Memory used to cache database +** pages to improve performance is an example of non-essential memory. +** ^sqlite3_release_memory() returns the number of bytes actually freed, +** which might be more or less than the amount requested. +** ^The sqlite3_release_memory() routine is a no-op returning zero +** if SQLite is not compiled with [SQLITE_ENABLE_MEMORY_MANAGEMENT]. +** +** See also: [sqlite3_db_release_memory()] +*/ +SQLITE_API int sqlite3_release_memory(int); + +/* +** CAPI3REF: Free Memory Used By A Database Connection +** +** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap +** memory as possible from database connection D. Unlike the +** [sqlite3_release_memory()] interface, this interface is effect even +** when then [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is +** omitted. +** +** See also: [sqlite3_release_memory()] +*/ +SQLITE_API int sqlite3_db_release_memory(sqlite3*); + +/* +** CAPI3REF: Impose A Limit On Heap Size +** +** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the +** soft limit on the amount of heap memory that may be allocated by SQLite. +** ^SQLite strives to keep heap memory utilization below the soft heap +** limit by reducing the number of pages held in the page cache +** as heap memory usages approaches the limit. +** ^The soft heap limit is "soft" because even though SQLite strives to stay +** below the limit, it will exceed the limit rather than generate +** an [SQLITE_NOMEM] error. In other words, the soft heap limit +** is advisory only. +** +** ^The return value from sqlite3_soft_heap_limit64() is the size of +** the soft heap limit prior to the call, or negative in the case of an +** error. ^If the argument N is negative +** then no change is made to the soft heap limit. Hence, the current +** size of the soft heap limit can be determined by invoking +** sqlite3_soft_heap_limit64() with a negative argument. +** +** ^If the argument N is zero then the soft heap limit is disabled. +** +** ^(The soft heap limit is not enforced in the current implementation +** if one or more of following conditions are true: +** +**
    +**
  • The soft heap limit is set to zero. +**
  • Memory accounting is disabled using a combination of the +** [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and +** the [SQLITE_DEFAULT_MEMSTATUS] compile-time option. +**
  • An alternative page cache implementation is specified using +** [sqlite3_config]([SQLITE_CONFIG_PCACHE2],...). +**
  • The page cache allocates from its own memory pool supplied +** by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than +** from the heap. +**
)^ +** +** Beginning with SQLite version 3.7.3, the soft heap limit is enforced +** regardless of whether or not the [SQLITE_ENABLE_MEMORY_MANAGEMENT] +** compile-time option is invoked. With [SQLITE_ENABLE_MEMORY_MANAGEMENT], +** the soft heap limit is enforced on every memory allocation. Without +** [SQLITE_ENABLE_MEMORY_MANAGEMENT], the soft heap limit is only enforced +** when memory is allocated by the page cache. Testing suggests that because +** the page cache is the predominate memory user in SQLite, most +** applications will achieve adequate soft heap limit enforcement without +** the use of [SQLITE_ENABLE_MEMORY_MANAGEMENT]. +** +** The circumstances under which SQLite will enforce the soft heap limit may +** changes in future releases of SQLite. +*/ +SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N); + +/* +** CAPI3REF: Deprecated Soft Heap Limit Interface +** DEPRECATED +** +** This is a deprecated version of the [sqlite3_soft_heap_limit64()] +** interface. This routine is provided for historical compatibility +** only. All new applications should use the +** [sqlite3_soft_heap_limit64()] interface rather than this one. +*/ +SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N); + + +/* +** CAPI3REF: Extract Metadata About A Column Of A Table +** +** ^This routine returns metadata about a specific column of a specific +** database table accessible using the [database connection] handle +** passed as the first function argument. +** +** ^The column is identified by the second, third and fourth parameters to +** this function. ^The second parameter is either the name of the database +** (i.e. "main", "temp", or an attached database) containing the specified +** table or NULL. ^If it is NULL, then all attached databases are searched +** for the table using the same algorithm used by the database engine to +** resolve unqualified table references. +** +** ^The third and fourth parameters to this function are the table and column +** name of the desired column, respectively. Neither of these parameters +** may be NULL. +** +** ^Metadata is returned by writing to the memory locations passed as the 5th +** and subsequent parameters to this function. ^Any of these arguments may be +** NULL, in which case the corresponding element of metadata is omitted. +** +** ^(
+** +**
Parameter Output
Type
Description +** +**
5th const char* Data type +**
6th const char* Name of default collation sequence +**
7th int True if column has a NOT NULL constraint +**
8th int True if column is part of the PRIMARY KEY +**
9th int True if column is [AUTOINCREMENT] +**
+**
)^ +** +** ^The memory pointed to by the character pointers returned for the +** declaration type and collation sequence is valid only until the next +** call to any SQLite API function. +** +** ^If the specified table is actually a view, an [error code] is returned. +** +** ^If the specified column is "rowid", "oid" or "_rowid_" and an +** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output +** parameters are set for the explicitly declared column. ^(If there is no +** explicitly declared [INTEGER PRIMARY KEY] column, then the output +** parameters are set as follows: +** +**
+**     data type: "INTEGER"
+**     collation sequence: "BINARY"
+**     not null: 0
+**     primary key: 1
+**     auto increment: 0
+** 
)^ +** +** ^(This function may load one or more schemas from database files. If an +** error occurs during this process, or if the requested table or column +** cannot be found, an [error code] is returned and an error message left +** in the [database connection] (to be retrieved using sqlite3_errmsg()).)^ +** +** ^This API is only available if the library was compiled with the +** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol defined. +*/ +SQLITE_API int sqlite3_table_column_metadata( + sqlite3 *db, /* Connection handle */ + const char *zDbName, /* Database name or NULL */ + const char *zTableName, /* Table name */ + const char *zColumnName, /* Column name */ + char const **pzDataType, /* OUTPUT: Declared data type */ + char const **pzCollSeq, /* OUTPUT: Collation sequence name */ + int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ + int *pPrimaryKey, /* OUTPUT: True if column part of PK */ + int *pAutoinc /* OUTPUT: True if column is auto-increment */ +); + +/* +** CAPI3REF: Load An Extension +** +** ^This interface loads an SQLite extension library from the named file. +** +** ^The sqlite3_load_extension() interface attempts to load an +** SQLite extension library contained in the file zFile. +** +** ^The entry point is zProc. +** ^zProc may be 0, in which case the name of the entry point +** defaults to "sqlite3_extension_init". +** ^The sqlite3_load_extension() interface returns +** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong. +** ^If an error occurs and pzErrMsg is not 0, then the +** [sqlite3_load_extension()] interface shall attempt to +** fill *pzErrMsg with error message text stored in memory +** obtained from [sqlite3_malloc()]. The calling function +** should free this memory by calling [sqlite3_free()]. +** +** ^Extension loading must be enabled using +** [sqlite3_enable_load_extension()] prior to calling this API, +** otherwise an error will be returned. +** +** See also the [load_extension() SQL function]. +*/ +SQLITE_API int sqlite3_load_extension( + sqlite3 *db, /* Load the extension into this database connection */ + const char *zFile, /* Name of the shared library containing extension */ + const char *zProc, /* Entry point. Derived from zFile if 0 */ + char **pzErrMsg /* Put error message here if not 0 */ +); + +/* +** CAPI3REF: Enable Or Disable Extension Loading +** +** ^So as not to open security holes in older applications that are +** unprepared to deal with extension loading, and as a means of disabling +** extension loading while evaluating user-entered SQL, the following API +** is provided to turn the [sqlite3_load_extension()] mechanism on and off. +** +** ^Extension loading is off by default. See ticket #1863. +** ^Call the sqlite3_enable_load_extension() routine with onoff==1 +** to turn extension loading on and call it with onoff==0 to turn +** it back off again. +*/ +SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff); + +/* +** CAPI3REF: Automatically Load Statically Linked Extensions +** +** ^This interface causes the xEntryPoint() function to be invoked for +** each new [database connection] that is created. The idea here is that +** xEntryPoint() is the entry point for a statically linked SQLite extension +** that is to be automatically loaded into all new database connections. +** +** ^(Even though the function prototype shows that xEntryPoint() takes +** no arguments and returns void, SQLite invokes xEntryPoint() with three +** arguments and expects and integer result as if the signature of the +** entry point where as follows: +** +**
+**    int xEntryPoint(
+**      sqlite3 *db,
+**      const char **pzErrMsg,
+**      const struct sqlite3_api_routines *pThunk
+**    );
+** 
)^ +** +** If the xEntryPoint routine encounters an error, it should make *pzErrMsg +** point to an appropriate error message (obtained from [sqlite3_mprintf()]) +** and return an appropriate [error code]. ^SQLite ensures that *pzErrMsg +** is NULL before calling the xEntryPoint(). ^SQLite will invoke +** [sqlite3_free()] on *pzErrMsg after xEntryPoint() returns. ^If any +** xEntryPoint() returns an error, the [sqlite3_open()], [sqlite3_open16()], +** or [sqlite3_open_v2()] call that provoked the xEntryPoint() will fail. +** +** ^Calling sqlite3_auto_extension(X) with an entry point X that is already +** on the list of automatic extensions is a harmless no-op. ^No entry point +** will be called more than once for each database connection that is opened. +** +** See also: [sqlite3_reset_auto_extension()]. +*/ +SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void)); + +/* +** CAPI3REF: Reset Automatic Extension Loading +** +** ^This interface disables all automatic extensions previously +** registered using [sqlite3_auto_extension()]. +*/ +SQLITE_API void sqlite3_reset_auto_extension(void); + +/* +** The interface to the virtual-table mechanism is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stabilizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +*/ + +/* +** Structures used by the virtual table interface +*/ +typedef struct sqlite3_vtab sqlite3_vtab; +typedef struct sqlite3_index_info sqlite3_index_info; +typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; +typedef struct sqlite3_module sqlite3_module; + +/* +** CAPI3REF: Virtual Table Object +** KEYWORDS: sqlite3_module {virtual table module} +** +** This structure, sometimes called a "virtual table module", +** defines the implementation of a [virtual tables]. +** This structure consists mostly of methods for the module. +** +** ^A virtual table module is created by filling in a persistent +** instance of this structure and passing a pointer to that instance +** to [sqlite3_create_module()] or [sqlite3_create_module_v2()]. +** ^The registration remains valid until it is replaced by a different +** module or until the [database connection] closes. The content +** of this structure must not change while it is registered with +** any database connection. +*/ +struct sqlite3_module { + int iVersion; + int (*xCreate)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xConnect)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); + int (*xDisconnect)(sqlite3_vtab *pVTab); + int (*xDestroy)(sqlite3_vtab *pVTab); + int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor); + int (*xClose)(sqlite3_vtab_cursor*); + int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr, + int argc, sqlite3_value **argv); + int (*xNext)(sqlite3_vtab_cursor*); + int (*xEof)(sqlite3_vtab_cursor*); + int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int); + int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid); + int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *); + int (*xBegin)(sqlite3_vtab *pVTab); + int (*xSync)(sqlite3_vtab *pVTab); + int (*xCommit)(sqlite3_vtab *pVTab); + int (*xRollback)(sqlite3_vtab *pVTab); + int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), + void **ppArg); + int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); + /* The methods above are in version 1 of the sqlite_module object. Those + ** below are for version 2 and greater. */ + int (*xSavepoint)(sqlite3_vtab *pVTab, int); + int (*xRelease)(sqlite3_vtab *pVTab, int); + int (*xRollbackTo)(sqlite3_vtab *pVTab, int); +}; + +/* +** CAPI3REF: Virtual Table Indexing Information +** KEYWORDS: sqlite3_index_info +** +** The sqlite3_index_info structure and its substructures is used as part +** of the [virtual table] interface to +** pass information into and receive the reply from the [xBestIndex] +** method of a [virtual table module]. The fields under **Inputs** are the +** inputs to xBestIndex and are read-only. xBestIndex inserts its +** results into the **Outputs** fields. +** +** ^(The aConstraint[] array records WHERE clause constraints of the form: +** +**
column OP expr
+** +** where OP is =, <, <=, >, or >=.)^ ^(The particular operator is +** stored in aConstraint[].op using one of the +** [SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_ values].)^ +** ^(The index of the column is stored in +** aConstraint[].iColumn.)^ ^(aConstraint[].usable is TRUE if the +** expr on the right-hand side can be evaluated (and thus the constraint +** is usable) and false if it cannot.)^ +** +** ^The optimizer automatically inverts terms of the form "expr OP column" +** and makes other simplifications to the WHERE clause in an attempt to +** get as many WHERE clause terms into the form shown above as possible. +** ^The aConstraint[] array only reports WHERE clause terms that are +** relevant to the particular virtual table being queried. +** +** ^Information about the ORDER BY clause is stored in aOrderBy[]. +** ^Each term of aOrderBy records a column of the ORDER BY clause. +** +** The [xBestIndex] method must fill aConstraintUsage[] with information +** about what parameters to pass to xFilter. ^If argvIndex>0 then +** the right-hand side of the corresponding aConstraint[] is evaluated +** and becomes the argvIndex-th entry in argv. ^(If aConstraintUsage[].omit +** is true, then the constraint is assumed to be fully handled by the +** virtual table and is not checked again by SQLite.)^ +** +** ^The idxNum and idxPtr values are recorded and passed into the +** [xFilter] method. +** ^[sqlite3_free()] is used to free idxPtr if and only if +** needToFreeIdxPtr is true. +** +** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in +** the correct order to satisfy the ORDER BY clause so that no separate +** sorting step is required. +** +** ^The estimatedCost value is an estimate of the cost of doing the +** particular lookup. A full scan of a table with N entries should have +** a cost of N. A binary search of a table of N entries should have a +** cost of approximately log(N). +*/ +struct sqlite3_index_info { + /* Inputs */ + int nConstraint; /* Number of entries in aConstraint */ + struct sqlite3_index_constraint { + int iColumn; /* Column on left-hand side of constraint */ + unsigned char op; /* Constraint operator */ + unsigned char usable; /* True if this constraint is usable */ + int iTermOffset; /* Used internally - xBestIndex should ignore */ + } *aConstraint; /* Table of WHERE clause constraints */ + int nOrderBy; /* Number of terms in the ORDER BY clause */ + struct sqlite3_index_orderby { + int iColumn; /* Column number */ + unsigned char desc; /* True for DESC. False for ASC. */ + } *aOrderBy; /* The ORDER BY clause */ + /* Outputs */ + struct sqlite3_index_constraint_usage { + int argvIndex; /* if >0, constraint is part of argv to xFilter */ + unsigned char omit; /* Do not code a test for this constraint */ + } *aConstraintUsage; + int idxNum; /* Number used to identify the index */ + char *idxStr; /* String, possibly obtained from sqlite3_malloc */ + int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */ + int orderByConsumed; /* True if output is already ordered */ + double estimatedCost; /* Estimated cost of using this index */ +}; + +/* +** CAPI3REF: Virtual Table Constraint Operator Codes +** +** These macros defined the allowed values for the +** [sqlite3_index_info].aConstraint[].op field. Each value represents +** an operator that is part of a constraint term in the wHERE clause of +** a query that uses a [virtual table]. +*/ +#define SQLITE_INDEX_CONSTRAINT_EQ 2 +#define SQLITE_INDEX_CONSTRAINT_GT 4 +#define SQLITE_INDEX_CONSTRAINT_LE 8 +#define SQLITE_INDEX_CONSTRAINT_LT 16 +#define SQLITE_INDEX_CONSTRAINT_GE 32 +#define SQLITE_INDEX_CONSTRAINT_MATCH 64 + +/* +** CAPI3REF: Register A Virtual Table Implementation +** +** ^These routines are used to register a new [virtual table module] name. +** ^Module names must be registered before +** creating a new [virtual table] using the module and before using a +** preexisting [virtual table] for the module. +** +** ^The module name is registered on the [database connection] specified +** by the first parameter. ^The name of the module is given by the +** second parameter. ^The third parameter is a pointer to +** the implementation of the [virtual table module]. ^The fourth +** parameter is an arbitrary client data pointer that is passed through +** into the [xCreate] and [xConnect] methods of the virtual table module +** when a new virtual table is be being created or reinitialized. +** +** ^The sqlite3_create_module_v2() interface has a fifth parameter which +** is a pointer to a destructor for the pClientData. ^SQLite will +** invoke the destructor function (if it is not NULL) when SQLite +** no longer needs the pClientData pointer. ^The destructor will also +** be invoked if the call to sqlite3_create_module_v2() fails. +** ^The sqlite3_create_module() +** interface is equivalent to sqlite3_create_module_v2() with a NULL +** destructor. +*/ +SQLITE_API int sqlite3_create_module( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *p, /* Methods for the module */ + void *pClientData /* Client data for xCreate/xConnect */ +); +SQLITE_API int sqlite3_create_module_v2( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *p, /* Methods for the module */ + void *pClientData, /* Client data for xCreate/xConnect */ + void(*xDestroy)(void*) /* Module destructor function */ +); + +/* +** CAPI3REF: Virtual Table Instance Object +** KEYWORDS: sqlite3_vtab +** +** Every [virtual table module] implementation uses a subclass +** of this object to describe a particular instance +** of the [virtual table]. Each subclass will +** be tailored to the specific needs of the module implementation. +** The purpose of this superclass is to define certain fields that are +** common to all module implementations. +** +** ^Virtual tables methods can set an error message by assigning a +** string obtained from [sqlite3_mprintf()] to zErrMsg. The method should +** take care that any prior string is freed by a call to [sqlite3_free()] +** prior to assigning a new string to zErrMsg. ^After the error message +** is delivered up to the client application, the string will be automatically +** freed by sqlite3_free() and the zErrMsg field will be zeroed. +*/ +struct sqlite3_vtab { + const sqlite3_module *pModule; /* The module for this virtual table */ + int nRef; /* NO LONGER USED */ + char *zErrMsg; /* Error message from sqlite3_mprintf() */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* +** CAPI3REF: Virtual Table Cursor Object +** KEYWORDS: sqlite3_vtab_cursor {virtual table cursor} +** +** Every [virtual table module] implementation uses a subclass of the +** following structure to describe cursors that point into the +** [virtual table] and are used +** to loop through the virtual table. Cursors are created using the +** [sqlite3_module.xOpen | xOpen] method of the module and are destroyed +** by the [sqlite3_module.xClose | xClose] method. Cursors are used +** by the [xFilter], [xNext], [xEof], [xColumn], and [xRowid] methods +** of the module. Each module implementation will define +** the content of a cursor structure to suit its own needs. +** +** This superclass exists in order to define fields of the cursor that +** are common to all implementations. +*/ +struct sqlite3_vtab_cursor { + sqlite3_vtab *pVtab; /* Virtual table of this cursor */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* +** CAPI3REF: Declare The Schema Of A Virtual Table +** +** ^The [xCreate] and [xConnect] methods of a +** [virtual table module] call this interface +** to declare the format (the names and datatypes of the columns) of +** the virtual tables they implement. +*/ +SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL); + +/* +** CAPI3REF: Overload A Function For A Virtual Table +** +** ^(Virtual tables can provide alternative implementations of functions +** using the [xFindFunction] method of the [virtual table module]. +** But global versions of those functions +** must exist in order to be overloaded.)^ +** +** ^(This API makes sure a global version of a function with a particular +** name and number of parameters exists. If no such function exists +** before this API is called, a new function is created.)^ ^The implementation +** of the new function always causes an exception to be thrown. So +** the new function is not good for anything by itself. Its only +** purpose is to be a placeholder function that can be overloaded +** by a [virtual table]. +*/ +SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); + +/* +** The interface to the virtual-table mechanism defined above (back up +** to a comment remarkably similar to this one) is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stabilizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +*/ + +/* +** CAPI3REF: A Handle To An Open BLOB +** KEYWORDS: {BLOB handle} {BLOB handles} +** +** An instance of this object represents an open BLOB on which +** [sqlite3_blob_open | incremental BLOB I/O] can be performed. +** ^Objects of this type are created by [sqlite3_blob_open()] +** and destroyed by [sqlite3_blob_close()]. +** ^The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces +** can be used to read or write small subsections of the BLOB. +** ^The [sqlite3_blob_bytes()] interface returns the size of the BLOB in bytes. +*/ +typedef struct sqlite3_blob sqlite3_blob; + +/* +** CAPI3REF: Open A BLOB For Incremental I/O +** +** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located +** in row iRow, column zColumn, table zTable in database zDb; +** in other words, the same BLOB that would be selected by: +** +**
+**     SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
+** 
)^ +** +** ^If the flags parameter is non-zero, then the BLOB is opened for read +** and write access. ^If it is zero, the BLOB is opened for read access. +** ^It is not possible to open a column that is part of an index or primary +** key for writing. ^If [foreign key constraints] are enabled, it is +** not possible to open a column that is part of a [child key] for writing. +** +** ^Note that the database name is not the filename that contains +** the database but rather the symbolic name of the database that +** appears after the AS keyword when the database is connected using [ATTACH]. +** ^For the main database file, the database name is "main". +** ^For TEMP tables, the database name is "temp". +** +** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is written +** to *ppBlob. Otherwise an [error code] is returned and *ppBlob is set +** to be a null pointer.)^ +** ^This function sets the [database connection] error code and message +** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()] and related +** functions. ^Note that the *ppBlob variable is always initialized in a +** way that makes it safe to invoke [sqlite3_blob_close()] on *ppBlob +** regardless of the success or failure of this routine. +** +** ^(If the row that a BLOB handle points to is modified by an +** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects +** then the BLOB handle is marked as "expired". +** This is true if any column of the row is changed, even a column +** other than the one the BLOB handle is open on.)^ +** ^Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for +** an expired BLOB handle fail with a return code of [SQLITE_ABORT]. +** ^(Changes written into a BLOB prior to the BLOB expiring are not +** rolled back by the expiration of the BLOB. Such changes will eventually +** commit if the transaction continues to completion.)^ +** +** ^Use the [sqlite3_blob_bytes()] interface to determine the size of +** the opened blob. ^The size of a blob may not be changed by this +** interface. Use the [UPDATE] SQL command to change the size of a +** blob. +** +** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces +** and the built-in [zeroblob] SQL function can be used, if desired, +** to create an empty, zero-filled blob in which to read or write using +** this interface. +** +** To avoid a resource leak, every open [BLOB handle] should eventually +** be released by a call to [sqlite3_blob_close()]. +*/ +SQLITE_API int sqlite3_blob_open( + sqlite3*, + const char *zDb, + const char *zTable, + const char *zColumn, + sqlite3_int64 iRow, + int flags, + sqlite3_blob **ppBlob +); + +/* +** CAPI3REF: Move a BLOB Handle to a New Row +** +** ^This function is used to move an existing blob handle so that it points +** to a different row of the same database table. ^The new row is identified +** by the rowid value passed as the second argument. Only the row can be +** changed. ^The database, table and column on which the blob handle is open +** remain the same. Moving an existing blob handle to a new row can be +** faster than closing the existing handle and opening a new one. +** +** ^(The new row must meet the same criteria as for [sqlite3_blob_open()] - +** it must exist and there must be either a blob or text value stored in +** the nominated column.)^ ^If the new row is not present in the table, or if +** it does not contain a blob or text value, or if another error occurs, an +** SQLite error code is returned and the blob handle is considered aborted. +** ^All subsequent calls to [sqlite3_blob_read()], [sqlite3_blob_write()] or +** [sqlite3_blob_reopen()] on an aborted blob handle immediately return +** SQLITE_ABORT. ^Calling [sqlite3_blob_bytes()] on an aborted blob handle +** always returns zero. +** +** ^This function sets the database handle error code and message. +*/ +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64); + +/* +** CAPI3REF: Close A BLOB Handle +** +** ^Closes an open [BLOB handle]. +** +** ^Closing a BLOB shall cause the current transaction to commit +** if there are no other BLOBs, no pending prepared statements, and the +** database connection is in [autocommit mode]. +** ^If any writes were made to the BLOB, they might be held in cache +** until the close operation if they will fit. +** +** ^(Closing the BLOB often forces the changes +** out to disk and so if any I/O errors occur, they will likely occur +** at the time when the BLOB is closed. Any errors that occur during +** closing are reported as a non-zero return value.)^ +** +** ^(The BLOB is closed unconditionally. Even if this routine returns +** an error code, the BLOB is still closed.)^ +** +** ^Calling this routine with a null pointer (such as would be returned +** by a failed call to [sqlite3_blob_open()]) is a harmless no-op. +*/ +SQLITE_API int sqlite3_blob_close(sqlite3_blob *); + +/* +** CAPI3REF: Return The Size Of An Open BLOB +** +** ^Returns the size in bytes of the BLOB accessible via the +** successfully opened [BLOB handle] in its only argument. ^The +** incremental blob I/O routines can only read or overwriting existing +** blob content; they cannot change the size of a blob. +** +** This routine only works on a [BLOB handle] which has been created +** by a prior successful call to [sqlite3_blob_open()] and which has not +** been closed by [sqlite3_blob_close()]. Passing any other pointer in +** to this routine results in undefined and probably undesirable behavior. +*/ +SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *); + +/* +** CAPI3REF: Read Data From A BLOB Incrementally +** +** ^(This function is used to read data from an open [BLOB handle] into a +** caller-supplied buffer. N bytes of data are copied into buffer Z +** from the open BLOB, starting at offset iOffset.)^ +** +** ^If offset iOffset is less than N bytes from the end of the BLOB, +** [SQLITE_ERROR] is returned and no data is read. ^If N or iOffset is +** less than zero, [SQLITE_ERROR] is returned and no data is read. +** ^The size of the blob (and hence the maximum value of N+iOffset) +** can be determined using the [sqlite3_blob_bytes()] interface. +** +** ^An attempt to read from an expired [BLOB handle] fails with an +** error code of [SQLITE_ABORT]. +** +** ^(On success, sqlite3_blob_read() returns SQLITE_OK. +** Otherwise, an [error code] or an [extended error code] is returned.)^ +** +** This routine only works on a [BLOB handle] which has been created +** by a prior successful call to [sqlite3_blob_open()] and which has not +** been closed by [sqlite3_blob_close()]. Passing any other pointer in +** to this routine results in undefined and probably undesirable behavior. +** +** See also: [sqlite3_blob_write()]. +*/ +SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset); + +/* +** CAPI3REF: Write Data Into A BLOB Incrementally +** +** ^This function is used to write data into an open [BLOB handle] from a +** caller-supplied buffer. ^N bytes of data are copied from the buffer Z +** into the open BLOB, starting at offset iOffset. +** +** ^If the [BLOB handle] passed as the first argument was not opened for +** writing (the flags parameter to [sqlite3_blob_open()] was zero), +** this function returns [SQLITE_READONLY]. +** +** ^This function may only modify the contents of the BLOB; it is +** not possible to increase the size of a BLOB using this API. +** ^If offset iOffset is less than N bytes from the end of the BLOB, +** [SQLITE_ERROR] is returned and no data is written. ^If N is +** less than zero [SQLITE_ERROR] is returned and no data is written. +** The size of the BLOB (and hence the maximum value of N+iOffset) +** can be determined using the [sqlite3_blob_bytes()] interface. +** +** ^An attempt to write to an expired [BLOB handle] fails with an +** error code of [SQLITE_ABORT]. ^Writes to the BLOB that occurred +** before the [BLOB handle] expired are not rolled back by the +** expiration of the handle, though of course those changes might +** have been overwritten by the statement that expired the BLOB handle +** or by other independent statements. +** +** ^(On success, sqlite3_blob_write() returns SQLITE_OK. +** Otherwise, an [error code] or an [extended error code] is returned.)^ +** +** This routine only works on a [BLOB handle] which has been created +** by a prior successful call to [sqlite3_blob_open()] and which has not +** been closed by [sqlite3_blob_close()]. Passing any other pointer in +** to this routine results in undefined and probably undesirable behavior. +** +** See also: [sqlite3_blob_read()]. +*/ +SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); + +/* +** CAPI3REF: Virtual File System Objects +** +** A virtual filesystem (VFS) is an [sqlite3_vfs] object +** that SQLite uses to interact +** with the underlying operating system. Most SQLite builds come with a +** single default VFS that is appropriate for the host computer. +** New VFSes can be registered and existing VFSes can be unregistered. +** The following interfaces are provided. +** +** ^The sqlite3_vfs_find() interface returns a pointer to a VFS given its name. +** ^Names are case sensitive. +** ^Names are zero-terminated UTF-8 strings. +** ^If there is no match, a NULL pointer is returned. +** ^If zVfsName is NULL then the default VFS is returned. +** +** ^New VFSes are registered with sqlite3_vfs_register(). +** ^Each new VFS becomes the default VFS if the makeDflt flag is set. +** ^The same VFS can be registered multiple times without injury. +** ^To make an existing VFS into the default VFS, register it again +** with the makeDflt flag set. If two different VFSes with the +** same name are registered, the behavior is undefined. If a +** VFS is registered with a name that is NULL or an empty string, +** then the behavior is undefined. +** +** ^Unregister a VFS with the sqlite3_vfs_unregister() interface. +** ^(If the default VFS is unregistered, another VFS is chosen as +** the default. The choice for the new VFS is arbitrary.)^ +*/ +SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName); +SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); +SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); + +/* +** CAPI3REF: Mutexes +** +** The SQLite core uses these routines for thread +** synchronization. Though they are intended for internal +** use by SQLite, code that links against SQLite is +** permitted to use any of these routines. +** +** The SQLite source code contains multiple implementations +** of these mutex routines. An appropriate implementation +** is selected automatically at compile-time. ^(The following +** implementations are available in the SQLite core: +** +**
    +**
  • SQLITE_MUTEX_OS2 +**
  • SQLITE_MUTEX_PTHREADS +**
  • SQLITE_MUTEX_W32 +**
  • SQLITE_MUTEX_NOOP +**
)^ +** +** ^The SQLITE_MUTEX_NOOP implementation is a set of routines +** that does no real locking and is appropriate for use in +** a single-threaded application. ^The SQLITE_MUTEX_OS2, +** SQLITE_MUTEX_PTHREADS, and SQLITE_MUTEX_W32 implementations +** are appropriate for use on OS/2, Unix, and Windows. +** +** ^(If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor +** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex +** implementation is included with the library. In this case the +** application must supply a custom mutex implementation using the +** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function +** before calling sqlite3_initialize() or any other public sqlite3_ +** function that calls sqlite3_initialize().)^ +** +** ^The sqlite3_mutex_alloc() routine allocates a new +** mutex and returns a pointer to it. ^If it returns NULL +** that means that a mutex could not be allocated. ^SQLite +** will unwind its stack and return an error. ^(The argument +** to sqlite3_mutex_alloc() is one of these integer constants: +** +**
    +**
  • SQLITE_MUTEX_FAST +**
  • SQLITE_MUTEX_RECURSIVE +**
  • SQLITE_MUTEX_STATIC_MASTER +**
  • SQLITE_MUTEX_STATIC_MEM +**
  • SQLITE_MUTEX_STATIC_MEM2 +**
  • SQLITE_MUTEX_STATIC_PRNG +**
  • SQLITE_MUTEX_STATIC_LRU +**
  • SQLITE_MUTEX_STATIC_LRU2 +**
)^ +** +** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) +** cause sqlite3_mutex_alloc() to create +** a new mutex. ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE +** is used but not necessarily so when SQLITE_MUTEX_FAST is used. +** The mutex implementation does not need to make a distinction +** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does +** not want to. ^SQLite will only request a recursive mutex in +** cases where it really needs one. ^If a faster non-recursive mutex +** implementation is available on the host platform, the mutex subsystem +** might return such a mutex in response to SQLITE_MUTEX_FAST. +** +** ^The other allowed parameters to sqlite3_mutex_alloc() (anything other +** than SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) each return +** a pointer to a static preexisting mutex. ^Six static mutexes are +** used by the current version of SQLite. Future versions of SQLite +** may add additional static mutexes. Static mutexes are for internal +** use by SQLite only. Applications that use SQLite mutexes should +** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or +** SQLITE_MUTEX_RECURSIVE. +** +** ^Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST +** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() +** returns a different mutex on every call. ^But for the static +** mutex types, the same mutex is returned on every call that has +** the same type number. +** +** ^The sqlite3_mutex_free() routine deallocates a previously +** allocated dynamic mutex. ^SQLite is careful to deallocate every +** dynamic mutex that it allocates. The dynamic mutexes must not be in +** use when they are deallocated. Attempting to deallocate a static +** mutex results in undefined behavior. ^SQLite never deallocates +** a static mutex. +** +** ^The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt +** to enter a mutex. ^If another thread is already within the mutex, +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. ^The sqlite3_mutex_try() interface returns [SQLITE_OK] +** upon successful entry. ^(Mutexes created using +** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread. +** In such cases the, +** mutex must be exited an equal number of times before another thread +** can enter.)^ ^(If the same thread tries to enter any other +** kind of mutex more than once, the behavior is undefined. +** SQLite will never exhibit +** such behavior in its own use of mutexes.)^ +** +** ^(Some systems (for example, Windows 95) do not support the operation +** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() +** will always return SQLITE_BUSY. The SQLite core only ever uses +** sqlite3_mutex_try() as an optimization so this is acceptable behavior.)^ +** +** ^The sqlite3_mutex_leave() routine exits a mutex that was +** previously entered by the same thread. ^(The behavior +** is undefined if the mutex is not currently entered by the +** calling thread or is not currently allocated. SQLite will +** never do either.)^ +** +** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or +** sqlite3_mutex_leave() is a NULL pointer, then all three routines +** behave as no-ops. +** +** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. +*/ +SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int); +SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*); +SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*); +SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*); +SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*); + +/* +** CAPI3REF: Mutex Methods Object +** +** An instance of this structure defines the low-level routines +** used to allocate and use mutexes. +** +** Usually, the default mutex implementations provided by SQLite are +** sufficient, however the user has the option of substituting a custom +** implementation for specialized deployments or systems for which SQLite +** does not provide a suitable implementation. In this case, the user +** creates and populates an instance of this structure to pass +** to sqlite3_config() along with the [SQLITE_CONFIG_MUTEX] option. +** Additionally, an instance of this structure can be used as an +** output variable when querying the system for the current mutex +** implementation, using the [SQLITE_CONFIG_GETMUTEX] option. +** +** ^The xMutexInit method defined by this structure is invoked as +** part of system initialization by the sqlite3_initialize() function. +** ^The xMutexInit routine is called by SQLite exactly once for each +** effective call to [sqlite3_initialize()]. +** +** ^The xMutexEnd method defined by this structure is invoked as +** part of system shutdown by the sqlite3_shutdown() function. The +** implementation of this method is expected to release all outstanding +** resources obtained by the mutex methods implementation, especially +** those obtained by the xMutexInit method. ^The xMutexEnd() +** interface is invoked exactly once for each call to [sqlite3_shutdown()]. +** +** ^(The remaining seven methods defined by this structure (xMutexAlloc, +** xMutexFree, xMutexEnter, xMutexTry, xMutexLeave, xMutexHeld and +** xMutexNotheld) implement the following interfaces (respectively): +** +**
    +**
  • [sqlite3_mutex_alloc()]
  • +**
  • [sqlite3_mutex_free()]
  • +**
  • [sqlite3_mutex_enter()]
  • +**
  • [sqlite3_mutex_try()]
  • +**
  • [sqlite3_mutex_leave()]
  • +**
  • [sqlite3_mutex_held()]
  • +**
  • [sqlite3_mutex_notheld()]
  • +**
)^ +** +** The only difference is that the public sqlite3_XXX functions enumerated +** above silently ignore any invocations that pass a NULL pointer instead +** of a valid mutex handle. The implementations of the methods defined +** by this structure are not required to handle this case, the results +** of passing a NULL pointer instead of a valid mutex handle are undefined +** (i.e. it is acceptable to provide an implementation that segfaults if +** it is passed a NULL pointer). +** +** The xMutexInit() method must be threadsafe. ^It must be harmless to +** invoke xMutexInit() multiple times within the same process and without +** intervening calls to xMutexEnd(). Second and subsequent calls to +** xMutexInit() must be no-ops. +** +** ^xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()] +** and its associates). ^Similarly, xMutexAlloc() must not use SQLite memory +** allocation for a static mutex. ^However xMutexAlloc() may use SQLite +** memory allocation for a fast or recursive mutex. +** +** ^SQLite will invoke the xMutexEnd() method when [sqlite3_shutdown()] is +** called, but only if the prior call to xMutexInit returned SQLITE_OK. +** If xMutexInit fails in any way, it is expected to clean up after itself +** prior to returning. +*/ +typedef struct sqlite3_mutex_methods sqlite3_mutex_methods; +struct sqlite3_mutex_methods { + int (*xMutexInit)(void); + int (*xMutexEnd)(void); + sqlite3_mutex *(*xMutexAlloc)(int); + void (*xMutexFree)(sqlite3_mutex *); + void (*xMutexEnter)(sqlite3_mutex *); + int (*xMutexTry)(sqlite3_mutex *); + void (*xMutexLeave)(sqlite3_mutex *); + int (*xMutexHeld)(sqlite3_mutex *); + int (*xMutexNotheld)(sqlite3_mutex *); +}; + +/* +** CAPI3REF: Mutex Verification Routines +** +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines +** are intended for use inside assert() statements. ^The SQLite core +** never uses these routines except inside an assert() and applications +** are advised to follow the lead of the core. ^The SQLite core only +** provides implementations for these routines when it is compiled +** with the SQLITE_DEBUG flag. ^External mutex implementations +** are only required to provide these routines if SQLITE_DEBUG is +** defined and if NDEBUG is not defined. +** +** ^These routines should return true if the mutex in their argument +** is held or not held, respectively, by the calling thread. +** +** ^The implementation is not required to provide versions of these +** routines that actually work. If the implementation does not provide working +** versions of these routines, it should at least provide stubs that always +** return true so that one does not get spurious assertion failures. +** +** ^If the argument to sqlite3_mutex_held() is a NULL pointer then +** the routine should return 1. This seems counter-intuitive since +** clearly the mutex cannot be held if it does not exist. But +** the reason the mutex does not exist is because the build is not +** using mutexes. And we do not want the assert() containing the +** call to sqlite3_mutex_held() to fail, so a non-zero return is +** the appropriate thing to do. ^The sqlite3_mutex_notheld() +** interface should also return 1 when given a NULL pointer. +*/ +#ifndef NDEBUG +SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*); +SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*); +#endif + +/* +** CAPI3REF: Mutex Types +** +** The [sqlite3_mutex_alloc()] interface takes a single argument +** which is one of these integer constants. +** +** The set of static mutexes may change from one SQLite release to the +** next. Applications that override the built-in mutex logic must be +** prepared to accommodate additional static mutexes. +*/ +#define SQLITE_MUTEX_FAST 0 +#define SQLITE_MUTEX_RECURSIVE 1 +#define SQLITE_MUTEX_STATIC_MASTER 2 +#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */ +#define SQLITE_MUTEX_STATIC_MEM2 4 /* NOT USED */ +#define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */ +#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */ +#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ +#define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */ +#define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */ + +/* +** CAPI3REF: Retrieve the mutex for a database connection +** +** ^This interface returns a pointer the [sqlite3_mutex] object that +** serializes access to the [database connection] given in the argument +** when the [threading mode] is Serialized. +** ^If the [threading mode] is Single-thread or Multi-thread then this +** routine returns a NULL pointer. +*/ +SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*); + +/* +** CAPI3REF: Low-Level Control Of Database Files +** +** ^The [sqlite3_file_control()] interface makes a direct call to the +** xFileControl method for the [sqlite3_io_methods] object associated +** with a particular database identified by the second argument. ^The +** name of the database is "main" for the main database or "temp" for the +** TEMP database, or the name that appears after the AS keyword for +** databases that are added using the [ATTACH] SQL command. +** ^A NULL pointer can be used in place of "main" to refer to the +** main database file. +** ^The third and fourth parameters to this routine +** are passed directly through to the second and third parameters of +** the xFileControl method. ^The return value of the xFileControl +** method becomes the return value of this routine. +** +** ^The SQLITE_FCNTL_FILE_POINTER value for the op parameter causes +** a pointer to the underlying [sqlite3_file] object to be written into +** the space pointed to by the 4th parameter. ^The SQLITE_FCNTL_FILE_POINTER +** case is a short-circuit path which does not actually invoke the +** underlying sqlite3_io_methods.xFileControl method. +** +** ^If the second parameter (zDbName) does not match the name of any +** open database file, then SQLITE_ERROR is returned. ^This error +** code is not remembered and will not be recalled by [sqlite3_errcode()] +** or [sqlite3_errmsg()]. The underlying xFileControl method might +** also return SQLITE_ERROR. There is no way to distinguish between +** an incorrect zDbName and an SQLITE_ERROR return from the underlying +** xFileControl method. +** +** See also: [SQLITE_FCNTL_LOCKSTATE] +*/ +SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); + +/* +** CAPI3REF: Testing Interface +** +** ^The sqlite3_test_control() interface is used to read out internal +** state of SQLite and to inject faults into SQLite for testing +** purposes. ^The first parameter is an operation code that determines +** the number, meaning, and operation of all subsequent parameters. +** +** This interface is not for use by applications. It exists solely +** for verifying the correct operation of the SQLite library. Depending +** on how the SQLite library is compiled, this interface might not exist. +** +** The details of the operation codes, their meanings, the parameters +** they take, and what they do are all subject to change without notice. +** Unlike most of the SQLite API, this function is not guaranteed to +** operate consistently from one release to the next. +*/ +SQLITE_API int sqlite3_test_control(int op, ...); + +/* +** CAPI3REF: Testing Interface Operation Codes +** +** These constants are the valid operation code parameters used +** as the first argument to [sqlite3_test_control()]. +** +** These parameters and their meanings are subject to change +** without notice. These values are for testing purposes only. +** Applications should not use any of these parameters or the +** [sqlite3_test_control()] interface. +*/ +#define SQLITE_TESTCTRL_FIRST 5 +#define SQLITE_TESTCTRL_PRNG_SAVE 5 +#define SQLITE_TESTCTRL_PRNG_RESTORE 6 +#define SQLITE_TESTCTRL_PRNG_RESET 7 +#define SQLITE_TESTCTRL_BITVEC_TEST 8 +#define SQLITE_TESTCTRL_FAULT_INSTALL 9 +#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10 +#define SQLITE_TESTCTRL_PENDING_BYTE 11 +#define SQLITE_TESTCTRL_ASSERT 12 +#define SQLITE_TESTCTRL_ALWAYS 13 +#define SQLITE_TESTCTRL_RESERVE 14 +#define SQLITE_TESTCTRL_OPTIMIZATIONS 15 +#define SQLITE_TESTCTRL_ISKEYWORD 16 +#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 +#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 +#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 +#define SQLITE_TESTCTRL_LAST 19 + +/* +** CAPI3REF: SQLite Runtime Status +** +** ^This interface is used to retrieve runtime status information +** about the performance of SQLite, and optionally to reset various +** highwater marks. ^The first argument is an integer code for +** the specific parameter to measure. ^(Recognized integer codes +** are of the form [status parameters | SQLITE_STATUS_...].)^ +** ^The current value of the parameter is returned into *pCurrent. +** ^The highest recorded value is returned in *pHighwater. ^If the +** resetFlag is true, then the highest record value is reset after +** *pHighwater is written. ^(Some parameters do not record the highest +** value. For those parameters +** nothing is written into *pHighwater and the resetFlag is ignored.)^ +** ^(Other parameters record only the highwater mark and not the current +** value. For these latter parameters nothing is written into *pCurrent.)^ +** +** ^The sqlite3_status() routine returns SQLITE_OK on success and a +** non-zero [error code] on failure. +** +** This routine is threadsafe but is not atomic. This routine can be +** called while other threads are running the same or different SQLite +** interfaces. However the values returned in *pCurrent and +** *pHighwater reflect the status of SQLite at different points in time +** and it is possible that another thread might change the parameter +** in between the times when *pCurrent and *pHighwater are written. +** +** See also: [sqlite3_db_status()] +*/ +SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag); + + +/* +** CAPI3REF: Status Parameters +** KEYWORDS: {status parameters} +** +** These integer constants designate various run-time status parameters +** that can be returned by [sqlite3_status()]. +** +**
+** [[SQLITE_STATUS_MEMORY_USED]] ^(
SQLITE_STATUS_MEMORY_USED
+**
This parameter is the current amount of memory checked out +** using [sqlite3_malloc()], either directly or indirectly. The +** figure includes calls made to [sqlite3_malloc()] by the application +** and internal memory usage by the SQLite library. Scratch memory +** controlled by [SQLITE_CONFIG_SCRATCH] and auxiliary page-cache +** memory controlled by [SQLITE_CONFIG_PAGECACHE] is not included in +** this parameter. The amount returned is the sum of the allocation +** sizes as reported by the xSize method in [sqlite3_mem_methods].
)^ +** +** [[SQLITE_STATUS_MALLOC_SIZE]] ^(
SQLITE_STATUS_MALLOC_SIZE
+**
This parameter records the largest memory allocation request +** handed to [sqlite3_malloc()] or [sqlite3_realloc()] (or their +** internal equivalents). Only the value returned in the +** *pHighwater parameter to [sqlite3_status()] is of interest. +** The value written into the *pCurrent parameter is undefined.
)^ +** +** [[SQLITE_STATUS_MALLOC_COUNT]] ^(
SQLITE_STATUS_MALLOC_COUNT
+**
This parameter records the number of separate memory allocations +** currently checked out.
)^ +** +** [[SQLITE_STATUS_PAGECACHE_USED]] ^(
SQLITE_STATUS_PAGECACHE_USED
+**
This parameter returns the number of pages used out of the +** [pagecache memory allocator] that was configured using +** [SQLITE_CONFIG_PAGECACHE]. The +** value returned is in pages, not in bytes.
)^ +** +** [[SQLITE_STATUS_PAGECACHE_OVERFLOW]] +** ^(
SQLITE_STATUS_PAGECACHE_OVERFLOW
+**
This parameter returns the number of bytes of page cache +** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE] +** buffer and where forced to overflow to [sqlite3_malloc()]. The +** returned value includes allocations that overflowed because they +** where too large (they were larger than the "sz" parameter to +** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because +** no space was left in the page cache.
)^ +** +** [[SQLITE_STATUS_PAGECACHE_SIZE]] ^(
SQLITE_STATUS_PAGECACHE_SIZE
+**
This parameter records the largest memory allocation request +** handed to [pagecache memory allocator]. Only the value returned in the +** *pHighwater parameter to [sqlite3_status()] is of interest. +** The value written into the *pCurrent parameter is undefined.
)^ +** +** [[SQLITE_STATUS_SCRATCH_USED]] ^(
SQLITE_STATUS_SCRATCH_USED
+**
This parameter returns the number of allocations used out of the +** [scratch memory allocator] configured using +** [SQLITE_CONFIG_SCRATCH]. The value returned is in allocations, not +** in bytes. Since a single thread may only have one scratch allocation +** outstanding at time, this parameter also reports the number of threads +** using scratch memory at the same time.
)^ +** +** [[SQLITE_STATUS_SCRATCH_OVERFLOW]] ^(
SQLITE_STATUS_SCRATCH_OVERFLOW
+**
This parameter returns the number of bytes of scratch memory +** allocation which could not be satisfied by the [SQLITE_CONFIG_SCRATCH] +** buffer and where forced to overflow to [sqlite3_malloc()]. The values +** returned include overflows because the requested allocation was too +** larger (that is, because the requested allocation was larger than the +** "sz" parameter to [SQLITE_CONFIG_SCRATCH]) and because no scratch buffer +** slots were available. +**
)^ +** +** [[SQLITE_STATUS_SCRATCH_SIZE]] ^(
SQLITE_STATUS_SCRATCH_SIZE
+**
This parameter records the largest memory allocation request +** handed to [scratch memory allocator]. Only the value returned in the +** *pHighwater parameter to [sqlite3_status()] is of interest. +** The value written into the *pCurrent parameter is undefined.
)^ +** +** [[SQLITE_STATUS_PARSER_STACK]] ^(
SQLITE_STATUS_PARSER_STACK
+**
This parameter records the deepest parser stack. It is only +** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].
)^ +**
+** +** New status parameters may be added from time to time. +*/ +#define SQLITE_STATUS_MEMORY_USED 0 +#define SQLITE_STATUS_PAGECACHE_USED 1 +#define SQLITE_STATUS_PAGECACHE_OVERFLOW 2 +#define SQLITE_STATUS_SCRATCH_USED 3 +#define SQLITE_STATUS_SCRATCH_OVERFLOW 4 +#define SQLITE_STATUS_MALLOC_SIZE 5 +#define SQLITE_STATUS_PARSER_STACK 6 +#define SQLITE_STATUS_PAGECACHE_SIZE 7 +#define SQLITE_STATUS_SCRATCH_SIZE 8 +#define SQLITE_STATUS_MALLOC_COUNT 9 + +/* +** CAPI3REF: Database Connection Status +** +** ^This interface is used to retrieve runtime status information +** about a single [database connection]. ^The first argument is the +** database connection object to be interrogated. ^The second argument +** is an integer constant, taken from the set of +** [SQLITE_DBSTATUS options], that +** determines the parameter to interrogate. The set of +** [SQLITE_DBSTATUS options] is likely +** to grow in future releases of SQLite. +** +** ^The current value of the requested parameter is written into *pCur +** and the highest instantaneous value is written into *pHiwtr. ^If +** the resetFlg is true, then the highest instantaneous value is +** reset back down to the current value. +** +** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a +** non-zero [error code] on failure. +** +** See also: [sqlite3_status()] and [sqlite3_stmt_status()]. +*/ +SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); + +/* +** CAPI3REF: Status Parameters for database connections +** KEYWORDS: {SQLITE_DBSTATUS options} +** +** These constants are the available integer "verbs" that can be passed as +** the second argument to the [sqlite3_db_status()] interface. +** +** New verbs may be added in future releases of SQLite. Existing verbs +** might be discontinued. Applications should check the return code from +** [sqlite3_db_status()] to make sure that the call worked. +** The [sqlite3_db_status()] interface will return a non-zero error code +** if a discontinued or unsupported verb is invoked. +** +**
+** [[SQLITE_DBSTATUS_LOOKASIDE_USED]] ^(
SQLITE_DBSTATUS_LOOKASIDE_USED
+**
This parameter returns the number of lookaside memory slots currently +** checked out.
)^ +** +** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(
SQLITE_DBSTATUS_LOOKASIDE_HIT
+**
This parameter returns the number malloc attempts that were +** satisfied using lookaside memory. Only the high-water value is meaningful; +** the current value is always zero.)^ +** +** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE]] +** ^(
SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE
+**
This parameter returns the number malloc attempts that might have +** been satisfied using lookaside memory but failed due to the amount of +** memory requested being larger than the lookaside slot size. +** Only the high-water value is meaningful; +** the current value is always zero.)^ +** +** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL]] +** ^(
SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL
+**
This parameter returns the number malloc attempts that might have +** been satisfied using lookaside memory but failed due to all lookaside +** memory already being in use. +** Only the high-water value is meaningful; +** the current value is always zero.)^ +** +** [[SQLITE_DBSTATUS_CACHE_USED]] ^(
SQLITE_DBSTATUS_CACHE_USED
+**
This parameter returns the approximate number of of bytes of heap +** memory used by all pager caches associated with the database connection.)^ +** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0. +** +** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(
SQLITE_DBSTATUS_SCHEMA_USED
+**
This parameter returns the approximate number of of bytes of heap +** memory used to store the schema for all databases associated +** with the connection - main, temp, and any [ATTACH]-ed databases.)^ +** ^The full amount of memory used by the schemas is reported, even if the +** schema memory is shared with other database connections due to +** [shared cache mode] being enabled. +** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0. +** +** [[SQLITE_DBSTATUS_STMT_USED]] ^(
SQLITE_DBSTATUS_STMT_USED
+**
This parameter returns the approximate number of of bytes of heap +** and lookaside memory used by all prepared statements associated with +** the database connection.)^ +** ^The highwater mark associated with SQLITE_DBSTATUS_STMT_USED is always 0. +**
+** +** [[SQLITE_DBSTATUS_CACHE_HIT]] ^(
SQLITE_DBSTATUS_CACHE_HIT
+**
This parameter returns the number of pager cache hits that have +** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_HIT +** is always 0. +**
+** +** [[SQLITE_DBSTATUS_CACHE_MISS]] ^(
SQLITE_DBSTATUS_CACHE_MISS
+**
This parameter returns the number of pager cache misses that have +** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS +** is always 0. +**
+**
+*/ +#define SQLITE_DBSTATUS_LOOKASIDE_USED 0 +#define SQLITE_DBSTATUS_CACHE_USED 1 +#define SQLITE_DBSTATUS_SCHEMA_USED 2 +#define SQLITE_DBSTATUS_STMT_USED 3 +#define SQLITE_DBSTATUS_LOOKASIDE_HIT 4 +#define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5 +#define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6 +#define SQLITE_DBSTATUS_CACHE_HIT 7 +#define SQLITE_DBSTATUS_CACHE_MISS 8 +#define SQLITE_DBSTATUS_MAX 8 /* Largest defined DBSTATUS */ + + +/* +** CAPI3REF: Prepared Statement Status +** +** ^(Each prepared statement maintains various +** [SQLITE_STMTSTATUS counters] that measure the number +** of times it has performed specific operations.)^ These counters can +** be used to monitor the performance characteristics of the prepared +** statements. For example, if the number of table steps greatly exceeds +** the number of table searches or result rows, that would tend to indicate +** that the prepared statement is using a full table scan rather than +** an index. +** +** ^(This interface is used to retrieve and reset counter values from +** a [prepared statement]. The first argument is the prepared statement +** object to be interrogated. The second argument +** is an integer code for a specific [SQLITE_STMTSTATUS counter] +** to be interrogated.)^ +** ^The current value of the requested counter is returned. +** ^If the resetFlg is true, then the counter is reset to zero after this +** interface call returns. +** +** See also: [sqlite3_status()] and [sqlite3_db_status()]. +*/ +SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); + +/* +** CAPI3REF: Status Parameters for prepared statements +** KEYWORDS: {SQLITE_STMTSTATUS counter} {SQLITE_STMTSTATUS counters} +** +** These preprocessor macros define integer codes that name counter +** values associated with the [sqlite3_stmt_status()] interface. +** The meanings of the various counters are as follows: +** +**
+** [[SQLITE_STMTSTATUS_FULLSCAN_STEP]]
SQLITE_STMTSTATUS_FULLSCAN_STEP
+**
^This is the number of times that SQLite has stepped forward in +** a table as part of a full table scan. Large numbers for this counter +** may indicate opportunities for performance improvement through +** careful use of indices.
+** +** [[SQLITE_STMTSTATUS_SORT]]
SQLITE_STMTSTATUS_SORT
+**
^This is the number of sort operations that have occurred. +** A non-zero value in this counter may indicate an opportunity to +** improvement performance through careful use of indices.
+** +** [[SQLITE_STMTSTATUS_AUTOINDEX]]
SQLITE_STMTSTATUS_AUTOINDEX
+**
^This is the number of rows inserted into transient indices that +** were created automatically in order to help joins run faster. +** A non-zero value in this counter may indicate an opportunity to +** improvement performance by adding permanent indices that do not +** need to be reinitialized each time the statement is run.
+**
+*/ +#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1 +#define SQLITE_STMTSTATUS_SORT 2 +#define SQLITE_STMTSTATUS_AUTOINDEX 3 + +/* +** CAPI3REF: Custom Page Cache Object +** +** The sqlite3_pcache type is opaque. It is implemented by +** the pluggable module. The SQLite core has no knowledge of +** its size or internal structure and never deals with the +** sqlite3_pcache object except by holding and passing pointers +** to the object. +** +** See [sqlite3_pcache_methods2] for additional information. +*/ +typedef struct sqlite3_pcache sqlite3_pcache; + +/* +** CAPI3REF: Custom Page Cache Object +** +** The sqlite3_pcache_page object represents a single page in the +** page cache. The page cache will allocate instances of this +** object. Various methods of the page cache use pointers to instances +** of this object as parameters or as their return value. +** +** See [sqlite3_pcache_methods2] for additional information. +*/ +typedef struct sqlite3_pcache_page sqlite3_pcache_page; +struct sqlite3_pcache_page { + void *pBuf; /* The content of the page */ + void *pExtra; /* Extra information associated with the page */ +}; + +/* +** CAPI3REF: Application Defined Page Cache. +** KEYWORDS: {page cache} +** +** ^(The [sqlite3_config]([SQLITE_CONFIG_PCACHE2], ...) interface can +** register an alternative page cache implementation by passing in an +** instance of the sqlite3_pcache_methods2 structure.)^ +** In many applications, most of the heap memory allocated by +** SQLite is used for the page cache. +** By implementing a +** custom page cache using this API, an application can better control +** the amount of memory consumed by SQLite, the way in which +** that memory is allocated and released, and the policies used to +** determine exactly which parts of a database file are cached and for +** how long. +** +** The alternative page cache mechanism is an +** extreme measure that is only needed by the most demanding applications. +** The built-in page cache is recommended for most uses. +** +** ^(The contents of the sqlite3_pcache_methods2 structure are copied to an +** internal buffer by SQLite within the call to [sqlite3_config]. Hence +** the application may discard the parameter after the call to +** [sqlite3_config()] returns.)^ +** +** [[the xInit() page cache method]] +** ^(The xInit() method is called once for each effective +** call to [sqlite3_initialize()])^ +** (usually only once during the lifetime of the process). ^(The xInit() +** method is passed a copy of the sqlite3_pcache_methods2.pArg value.)^ +** The intent of the xInit() method is to set up global data structures +** required by the custom page cache implementation. +** ^(If the xInit() method is NULL, then the +** built-in default page cache is used instead of the application defined +** page cache.)^ +** +** [[the xShutdown() page cache method]] +** ^The xShutdown() method is called by [sqlite3_shutdown()]. +** It can be used to clean up +** any outstanding resources before process shutdown, if required. +** ^The xShutdown() method may be NULL. +** +** ^SQLite automatically serializes calls to the xInit method, +** so the xInit method need not be threadsafe. ^The +** xShutdown method is only called from [sqlite3_shutdown()] so it does +** not need to be threadsafe either. All other methods must be threadsafe +** in multithreaded applications. +** +** ^SQLite will never invoke xInit() more than once without an intervening +** call to xShutdown(). +** +** [[the xCreate() page cache methods]] +** ^SQLite invokes the xCreate() method to construct a new cache instance. +** SQLite will typically create one cache instance for each open database file, +** though this is not guaranteed. ^The +** first parameter, szPage, is the size in bytes of the pages that must +** be allocated by the cache. ^szPage will always a power of two. ^The +** second parameter szExtra is a number of bytes of extra storage +** associated with each page cache entry. ^The szExtra parameter will +** a number less than 250. SQLite will use the +** extra szExtra bytes on each page to store metadata about the underlying +** database page on disk. The value passed into szExtra depends +** on the SQLite version, the target platform, and how SQLite was compiled. +** ^The third argument to xCreate(), bPurgeable, is true if the cache being +** created will be used to cache database pages of a file stored on disk, or +** false if it is used for an in-memory database. The cache implementation +** does not have to do anything special based with the value of bPurgeable; +** it is purely advisory. ^On a cache where bPurgeable is false, SQLite will +** never invoke xUnpin() except to deliberately delete a page. +** ^In other words, calls to xUnpin() on a cache with bPurgeable set to +** false will always have the "discard" flag set to true. +** ^Hence, a cache created with bPurgeable false will +** never contain any unpinned pages. +** +** [[the xCachesize() page cache method]] +** ^(The xCachesize() method may be called at any time by SQLite to set the +** suggested maximum cache-size (number of pages stored by) the cache +** instance passed as the first argument. This is the value configured using +** the SQLite "[PRAGMA cache_size]" command.)^ As with the bPurgeable +** parameter, the implementation is not required to do anything with this +** value; it is advisory only. +** +** [[the xPagecount() page cache methods]] +** The xPagecount() method must return the number of pages currently +** stored in the cache, both pinned and unpinned. +** +** [[the xFetch() page cache methods]] +** The xFetch() method locates a page in the cache and returns a pointer to +** an sqlite3_pcache_page object associated with that page, or a NULL pointer. +** The pBuf element of the returned sqlite3_pcache_page object will be a +** pointer to a buffer of szPage bytes used to store the content of a +** single database page. The pExtra element of sqlite3_pcache_page will be +** a pointer to the szExtra bytes of extra storage that SQLite has requested +** for each entry in the page cache. +** +** The page to be fetched is determined by the key. ^The minimum key value +** is 1. After it has been retrieved using xFetch, the page is considered +** to be "pinned". +** +** If the requested page is already in the page cache, then the page cache +** implementation must return a pointer to the page buffer with its content +** intact. If the requested page is not already in the cache, then the +** cache implementation should use the value of the createFlag +** parameter to help it determined what action to take: +** +** +**
createFlag Behaviour when page is not already in cache +**
0 Do not allocate a new page. Return NULL. +**
1 Allocate a new page if it easy and convenient to do so. +** Otherwise return NULL. +**
2 Make every effort to allocate a new page. Only return +** NULL if allocating a new page is effectively impossible. +**
+** +** ^(SQLite will normally invoke xFetch() with a createFlag of 0 or 1. SQLite +** will only use a createFlag of 2 after a prior call with a createFlag of 1 +** failed.)^ In between the to xFetch() calls, SQLite may +** attempt to unpin one or more cache pages by spilling the content of +** pinned pages to disk and synching the operating system disk cache. +** +** [[the xUnpin() page cache method]] +** ^xUnpin() is called by SQLite with a pointer to a currently pinned page +** as its second argument. If the third parameter, discard, is non-zero, +** then the page must be evicted from the cache. +** ^If the discard parameter is +** zero, then the page may be discarded or retained at the discretion of +** page cache implementation. ^The page cache implementation +** may choose to evict unpinned pages at any time. +** +** The cache must not perform any reference counting. A single +** call to xUnpin() unpins the page regardless of the number of prior calls +** to xFetch(). +** +** [[the xRekey() page cache methods]] +** The xRekey() method is used to change the key value associated with the +** page passed as the second argument. If the cache +** previously contains an entry associated with newKey, it must be +** discarded. ^Any prior cache entry associated with newKey is guaranteed not +** to be pinned. +** +** When SQLite calls the xTruncate() method, the cache must discard all +** existing cache entries with page numbers (keys) greater than or equal +** to the value of the iLimit parameter passed to xTruncate(). If any +** of these pages are pinned, they are implicitly unpinned, meaning that +** they can be safely discarded. +** +** [[the xDestroy() page cache method]] +** ^The xDestroy() method is used to delete a cache allocated by xCreate(). +** All resources associated with the specified cache should be freed. ^After +** calling the xDestroy() method, SQLite considers the [sqlite3_pcache*] +** handle invalid, and will not use it with any other sqlite3_pcache_methods2 +** functions. +** +** [[the xShrink() page cache method]] +** ^SQLite invokes the xShrink() method when it wants the page cache to +** free up as much of heap memory as possible. The page cache implementation +** is not obligated to free any memory, but well-behaved implementations should +** do their best. +*/ +typedef struct sqlite3_pcache_methods2 sqlite3_pcache_methods2; +struct sqlite3_pcache_methods2 { + int iVersion; + void *pArg; + int (*xInit)(void*); + void (*xShutdown)(void*); + sqlite3_pcache *(*xCreate)(int szPage, int szExtra, int bPurgeable); + void (*xCachesize)(sqlite3_pcache*, int nCachesize); + int (*xPagecount)(sqlite3_pcache*); + sqlite3_pcache_page *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); + void (*xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, int discard); + void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*, + unsigned oldKey, unsigned newKey); + void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); + void (*xDestroy)(sqlite3_pcache*); + void (*xShrink)(sqlite3_pcache*); +}; + +/* +** This is the obsolete pcache_methods object that has now been replaced +** by sqlite3_pcache_methods2. This object is not used by SQLite. It is +** retained in the header file for backwards compatibility only. +*/ +typedef struct sqlite3_pcache_methods sqlite3_pcache_methods; +struct sqlite3_pcache_methods { + void *pArg; + int (*xInit)(void*); + void (*xShutdown)(void*); + sqlite3_pcache *(*xCreate)(int szPage, int bPurgeable); + void (*xCachesize)(sqlite3_pcache*, int nCachesize); + int (*xPagecount)(sqlite3_pcache*); + void *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); + void (*xUnpin)(sqlite3_pcache*, void*, int discard); + void (*xRekey)(sqlite3_pcache*, void*, unsigned oldKey, unsigned newKey); + void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); + void (*xDestroy)(sqlite3_pcache*); +}; + + +/* +** CAPI3REF: Online Backup Object +** +** The sqlite3_backup object records state information about an ongoing +** online backup operation. ^The sqlite3_backup object is created by +** a call to [sqlite3_backup_init()] and is destroyed by a call to +** [sqlite3_backup_finish()]. +** +** See Also: [Using the SQLite Online Backup API] +*/ +typedef struct sqlite3_backup sqlite3_backup; + +/* +** CAPI3REF: Online Backup API. +** +** The backup API copies the content of one database into another. +** It is useful either for creating backups of databases or +** for copying in-memory databases to or from persistent files. +** +** See Also: [Using the SQLite Online Backup API] +** +** ^SQLite holds a write transaction open on the destination database file +** for the duration of the backup operation. +** ^The source database is read-locked only while it is being read; +** it is not locked continuously for the entire backup operation. +** ^Thus, the backup may be performed on a live source database without +** preventing other database connections from +** reading or writing to the source database while the backup is underway. +** +** ^(To perform a backup operation: +**
    +**
  1. sqlite3_backup_init() is called once to initialize the +** backup, +**
  2. sqlite3_backup_step() is called one or more times to transfer +** the data between the two databases, and finally +**
  3. sqlite3_backup_finish() is called to release all resources +** associated with the backup operation. +**
)^ +** There should be exactly one call to sqlite3_backup_finish() for each +** successful call to sqlite3_backup_init(). +** +** [[sqlite3_backup_init()]] sqlite3_backup_init() +** +** ^The D and N arguments to sqlite3_backup_init(D,N,S,M) are the +** [database connection] associated with the destination database +** and the database name, respectively. +** ^The database name is "main" for the main database, "temp" for the +** temporary database, or the name specified after the AS keyword in +** an [ATTACH] statement for an attached database. +** ^The S and M arguments passed to +** sqlite3_backup_init(D,N,S,M) identify the [database connection] +** and database name of the source database, respectively. +** ^The source and destination [database connections] (parameters S and D) +** must be different or else sqlite3_backup_init(D,N,S,M) will fail with +** an error. +** +** ^If an error occurs within sqlite3_backup_init(D,N,S,M), then NULL is +** returned and an error code and error message are stored in the +** destination [database connection] D. +** ^The error code and message for the failed call to sqlite3_backup_init() +** can be retrieved using the [sqlite3_errcode()], [sqlite3_errmsg()], and/or +** [sqlite3_errmsg16()] functions. +** ^A successful call to sqlite3_backup_init() returns a pointer to an +** [sqlite3_backup] object. +** ^The [sqlite3_backup] object may be used with the sqlite3_backup_step() and +** sqlite3_backup_finish() functions to perform the specified backup +** operation. +** +** [[sqlite3_backup_step()]] sqlite3_backup_step() +** +** ^Function sqlite3_backup_step(B,N) will copy up to N pages between +** the source and destination databases specified by [sqlite3_backup] object B. +** ^If N is negative, all remaining source pages are copied. +** ^If sqlite3_backup_step(B,N) successfully copies N pages and there +** are still more pages to be copied, then the function returns [SQLITE_OK]. +** ^If sqlite3_backup_step(B,N) successfully finishes copying all pages +** from source to destination, then it returns [SQLITE_DONE]. +** ^If an error occurs while running sqlite3_backup_step(B,N), +** then an [error code] is returned. ^As well as [SQLITE_OK] and +** [SQLITE_DONE], a call to sqlite3_backup_step() may return [SQLITE_READONLY], +** [SQLITE_NOMEM], [SQLITE_BUSY], [SQLITE_LOCKED], or an +** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX] extended error code. +** +** ^(The sqlite3_backup_step() might return [SQLITE_READONLY] if +**
    +**
  1. the destination database was opened read-only, or +**
  2. the destination database is using write-ahead-log journaling +** and the destination and source page sizes differ, or +**
  3. the destination database is an in-memory database and the +** destination and source page sizes differ. +**
)^ +** +** ^If sqlite3_backup_step() cannot obtain a required file-system lock, then +** the [sqlite3_busy_handler | busy-handler function] +** is invoked (if one is specified). ^If the +** busy-handler returns non-zero before the lock is available, then +** [SQLITE_BUSY] is returned to the caller. ^In this case the call to +** sqlite3_backup_step() can be retried later. ^If the source +** [database connection] +** is being used to write to the source database when sqlite3_backup_step() +** is called, then [SQLITE_LOCKED] is returned immediately. ^Again, in this +** case the call to sqlite3_backup_step() can be retried later on. ^(If +** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX], [SQLITE_NOMEM], or +** [SQLITE_READONLY] is returned, then +** there is no point in retrying the call to sqlite3_backup_step(). These +** errors are considered fatal.)^ The application must accept +** that the backup operation has failed and pass the backup operation handle +** to the sqlite3_backup_finish() to release associated resources. +** +** ^The first call to sqlite3_backup_step() obtains an exclusive lock +** on the destination file. ^The exclusive lock is not released until either +** sqlite3_backup_finish() is called or the backup operation is complete +** and sqlite3_backup_step() returns [SQLITE_DONE]. ^Every call to +** sqlite3_backup_step() obtains a [shared lock] on the source database that +** lasts for the duration of the sqlite3_backup_step() call. +** ^Because the source database is not locked between calls to +** sqlite3_backup_step(), the source database may be modified mid-way +** through the backup process. ^If the source database is modified by an +** external process or via a database connection other than the one being +** used by the backup operation, then the backup will be automatically +** restarted by the next call to sqlite3_backup_step(). ^If the source +** database is modified by the using the same database connection as is used +** by the backup operation, then the backup database is automatically +** updated at the same time. +** +** [[sqlite3_backup_finish()]] sqlite3_backup_finish() +** +** When sqlite3_backup_step() has returned [SQLITE_DONE], or when the +** application wishes to abandon the backup operation, the application +** should destroy the [sqlite3_backup] by passing it to sqlite3_backup_finish(). +** ^The sqlite3_backup_finish() interfaces releases all +** resources associated with the [sqlite3_backup] object. +** ^If sqlite3_backup_step() has not yet returned [SQLITE_DONE], then any +** active write-transaction on the destination database is rolled back. +** The [sqlite3_backup] object is invalid +** and may not be used following a call to sqlite3_backup_finish(). +** +** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no +** sqlite3_backup_step() errors occurred, regardless or whether or not +** sqlite3_backup_step() completed. +** ^If an out-of-memory condition or IO error occurred during any prior +** sqlite3_backup_step() call on the same [sqlite3_backup] object, then +** sqlite3_backup_finish() returns the corresponding [error code]. +** +** ^A return of [SQLITE_BUSY] or [SQLITE_LOCKED] from sqlite3_backup_step() +** is not a permanent error and does not affect the return value of +** sqlite3_backup_finish(). +** +** [[sqlite3_backup__remaining()]] [[sqlite3_backup_pagecount()]] +** sqlite3_backup_remaining() and sqlite3_backup_pagecount() +** +** ^Each call to sqlite3_backup_step() sets two values inside +** the [sqlite3_backup] object: the number of pages still to be backed +** up and the total number of pages in the source database file. +** The sqlite3_backup_remaining() and sqlite3_backup_pagecount() interfaces +** retrieve these two values, respectively. +** +** ^The values returned by these functions are only updated by +** sqlite3_backup_step(). ^If the source database is modified during a backup +** operation, then the values are not updated to account for any extra +** pages that need to be updated or the size of the source database file +** changing. +** +** Concurrent Usage of Database Handles +** +** ^The source [database connection] may be used by the application for other +** purposes while a backup operation is underway or being initialized. +** ^If SQLite is compiled and configured to support threadsafe database +** connections, then the source database connection may be used concurrently +** from within other threads. +** +** However, the application must guarantee that the destination +** [database connection] is not passed to any other API (by any thread) after +** sqlite3_backup_init() is called and before the corresponding call to +** sqlite3_backup_finish(). SQLite does not currently check to see +** if the application incorrectly accesses the destination [database connection] +** and so no error code is reported, but the operations may malfunction +** nevertheless. Use of the destination database connection while a +** backup is in progress might also also cause a mutex deadlock. +** +** If running in [shared cache mode], the application must +** guarantee that the shared cache used by the destination database +** is not accessed while the backup is running. In practice this means +** that the application must guarantee that the disk file being +** backed up to is not accessed by any connection within the process, +** not just the specific connection that was passed to sqlite3_backup_init(). +** +** The [sqlite3_backup] object itself is partially threadsafe. Multiple +** threads may safely make multiple concurrent calls to sqlite3_backup_step(). +** However, the sqlite3_backup_remaining() and sqlite3_backup_pagecount() +** APIs are not strictly speaking threadsafe. If they are invoked at the +** same time as another thread is invoking sqlite3_backup_step() it is +** possible that they return invalid values. +*/ +SQLITE_API sqlite3_backup *sqlite3_backup_init( + sqlite3 *pDest, /* Destination database handle */ + const char *zDestName, /* Destination database name */ + sqlite3 *pSource, /* Source database handle */ + const char *zSourceName /* Source database name */ +); +SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage); +SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p); +SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p); +SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); + +/* +** CAPI3REF: Unlock Notification +** +** ^When running in shared-cache mode, a database operation may fail with +** an [SQLITE_LOCKED] error if the required locks on the shared-cache or +** individual tables within the shared-cache cannot be obtained. See +** [SQLite Shared-Cache Mode] for a description of shared-cache locking. +** ^This API may be used to register a callback that SQLite will invoke +** when the connection currently holding the required lock relinquishes it. +** ^This API is only available if the library was compiled with the +** [SQLITE_ENABLE_UNLOCK_NOTIFY] C-preprocessor symbol defined. +** +** See Also: [Using the SQLite Unlock Notification Feature]. +** +** ^Shared-cache locks are released when a database connection concludes +** its current transaction, either by committing it or rolling it back. +** +** ^When a connection (known as the blocked connection) fails to obtain a +** shared-cache lock and SQLITE_LOCKED is returned to the caller, the +** identity of the database connection (the blocking connection) that +** has locked the required resource is stored internally. ^After an +** application receives an SQLITE_LOCKED error, it may call the +** sqlite3_unlock_notify() method with the blocked connection handle as +** the first argument to register for a callback that will be invoked +** when the blocking connections current transaction is concluded. ^The +** callback is invoked from within the [sqlite3_step] or [sqlite3_close] +** call that concludes the blocking connections transaction. +** +** ^(If sqlite3_unlock_notify() is called in a multi-threaded application, +** there is a chance that the blocking connection will have already +** concluded its transaction by the time sqlite3_unlock_notify() is invoked. +** If this happens, then the specified callback is invoked immediately, +** from within the call to sqlite3_unlock_notify().)^ +** +** ^If the blocked connection is attempting to obtain a write-lock on a +** shared-cache table, and more than one other connection currently holds +** a read-lock on the same table, then SQLite arbitrarily selects one of +** the other connections to use as the blocking connection. +** +** ^(There may be at most one unlock-notify callback registered by a +** blocked connection. If sqlite3_unlock_notify() is called when the +** blocked connection already has a registered unlock-notify callback, +** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is +** called with a NULL pointer as its second argument, then any existing +** unlock-notify callback is canceled. ^The blocked connections +** unlock-notify callback may also be canceled by closing the blocked +** connection using [sqlite3_close()]. +** +** The unlock-notify callback is not reentrant. If an application invokes +** any sqlite3_xxx API functions from within an unlock-notify callback, a +** crash or deadlock may be the result. +** +** ^Unless deadlock is detected (see below), sqlite3_unlock_notify() always +** returns SQLITE_OK. +** +** Callback Invocation Details +** +** When an unlock-notify callback is registered, the application provides a +** single void* pointer that is passed to the callback when it is invoked. +** However, the signature of the callback function allows SQLite to pass +** it an array of void* context pointers. The first argument passed to +** an unlock-notify callback is a pointer to an array of void* pointers, +** and the second is the number of entries in the array. +** +** When a blocking connections transaction is concluded, there may be +** more than one blocked connection that has registered for an unlock-notify +** callback. ^If two or more such blocked connections have specified the +** same callback function, then instead of invoking the callback function +** multiple times, it is invoked once with the set of void* context pointers +** specified by the blocked connections bundled together into an array. +** This gives the application an opportunity to prioritize any actions +** related to the set of unblocked database connections. +** +** Deadlock Detection +** +** Assuming that after registering for an unlock-notify callback a +** database waits for the callback to be issued before taking any further +** action (a reasonable assumption), then using this API may cause the +** application to deadlock. For example, if connection X is waiting for +** connection Y's transaction to be concluded, and similarly connection +** Y is waiting on connection X's transaction, then neither connection +** will proceed and the system may remain deadlocked indefinitely. +** +** To avoid this scenario, the sqlite3_unlock_notify() performs deadlock +** detection. ^If a given call to sqlite3_unlock_notify() would put the +** system in a deadlocked state, then SQLITE_LOCKED is returned and no +** unlock-notify callback is registered. The system is said to be in +** a deadlocked state if connection A has registered for an unlock-notify +** callback on the conclusion of connection B's transaction, and connection +** B has itself registered for an unlock-notify callback when connection +** A's transaction is concluded. ^Indirect deadlock is also detected, so +** the system is also considered to be deadlocked if connection B has +** registered for an unlock-notify callback on the conclusion of connection +** C's transaction, where connection C is waiting on connection A. ^Any +** number of levels of indirection are allowed. +** +** The "DROP TABLE" Exception +** +** When a call to [sqlite3_step()] returns SQLITE_LOCKED, it is almost +** always appropriate to call sqlite3_unlock_notify(). There is however, +** one exception. When executing a "DROP TABLE" or "DROP INDEX" statement, +** SQLite checks if there are any currently executing SELECT statements +** that belong to the same connection. If there are, SQLITE_LOCKED is +** returned. In this case there is no "blocking connection", so invoking +** sqlite3_unlock_notify() results in the unlock-notify callback being +** invoked immediately. If the application then re-attempts the "DROP TABLE" +** or "DROP INDEX" query, an infinite loop might be the result. +** +** One way around this problem is to check the extended error code returned +** by an sqlite3_step() call. ^(If there is a blocking connection, then the +** extended error code is set to SQLITE_LOCKED_SHAREDCACHE. Otherwise, in +** the special "DROP TABLE/INDEX" case, the extended error code is just +** SQLITE_LOCKED.)^ +*/ +SQLITE_API int sqlite3_unlock_notify( + sqlite3 *pBlocked, /* Waiting connection */ + void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */ + void *pNotifyArg /* Argument to pass to xNotify */ +); + + +/* +** CAPI3REF: String Comparison +** +** ^The [sqlite3_strnicmp()] API allows applications and extensions to +** compare the contents of two buffers containing UTF-8 strings in a +** case-independent fashion, using the same definition of case independence +** that SQLite uses internally when comparing identifiers. +*/ +SQLITE_API int sqlite3_strnicmp(const char *, const char *, int); + +/* +** CAPI3REF: Error Logging Interface +** +** ^The [sqlite3_log()] interface writes a message into the error log +** established by the [SQLITE_CONFIG_LOG] option to [sqlite3_config()]. +** ^If logging is enabled, the zFormat string and subsequent arguments are +** used with [sqlite3_snprintf()] to generate the final output string. +** +** The sqlite3_log() interface is intended for use by extensions such as +** virtual tables, collating functions, and SQL functions. While there is +** nothing to prevent an application from calling sqlite3_log(), doing so +** is considered bad form. +** +** The zFormat string must not be NULL. +** +** To avoid deadlocks and other threading problems, the sqlite3_log() routine +** will not use dynamically allocated memory. The log message is stored in +** a fixed-length buffer on the stack. If the log message is longer than +** a few hundred characters, it will be truncated to the length of the +** buffer. +*/ +SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...); + +/* +** CAPI3REF: Write-Ahead Log Commit Hook +** +** ^The [sqlite3_wal_hook()] function is used to register a callback that +** will be invoked each time a database connection commits data to a +** [write-ahead log] (i.e. whenever a transaction is committed in +** [journal_mode | journal_mode=WAL mode]). +** +** ^The callback is invoked by SQLite after the commit has taken place and +** the associated write-lock on the database released, so the implementation +** may read, write or [checkpoint] the database as required. +** +** ^The first parameter passed to the callback function when it is invoked +** is a copy of the third parameter passed to sqlite3_wal_hook() when +** registering the callback. ^The second is a copy of the database handle. +** ^The third parameter is the name of the database that was written to - +** either "main" or the name of an [ATTACH]-ed database. ^The fourth parameter +** is the number of pages currently in the write-ahead log file, +** including those that were just committed. +** +** The callback function should normally return [SQLITE_OK]. ^If an error +** code is returned, that error will propagate back up through the +** SQLite code base to cause the statement that provoked the callback +** to report an error, though the commit will have still occurred. If the +** callback returns [SQLITE_ROW] or [SQLITE_DONE], or if it returns a value +** that does not correspond to any valid SQLite error code, the results +** are undefined. +** +** A single database handle may have at most a single write-ahead log callback +** registered at one time. ^Calling [sqlite3_wal_hook()] replaces any +** previously registered write-ahead log callback. ^Note that the +** [sqlite3_wal_autocheckpoint()] interface and the +** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will +** those overwrite any prior [sqlite3_wal_hook()] settings. +*/ +SQLITE_API void *sqlite3_wal_hook( + sqlite3*, + int(*)(void *,sqlite3*,const char*,int), + void* +); + +/* +** CAPI3REF: Configure an auto-checkpoint +** +** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around +** [sqlite3_wal_hook()] that causes any database on [database connection] D +** to automatically [checkpoint] +** after committing a transaction if there are N or +** more frames in the [write-ahead log] file. ^Passing zero or +** a negative value as the nFrame parameter disables automatic +** checkpoints entirely. +** +** ^The callback registered by this function replaces any existing callback +** registered using [sqlite3_wal_hook()]. ^Likewise, registering a callback +** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism +** configured by this function. +** +** ^The [wal_autocheckpoint pragma] can be used to invoke this interface +** from SQL. +** +** ^Every new [database connection] defaults to having the auto-checkpoint +** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT] +** pages. The use of this interface +** is only necessary if the default setting is found to be suboptimal +** for a particular application. +*/ +SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N); + +/* +** CAPI3REF: Checkpoint a database +** +** ^The [sqlite3_wal_checkpoint(D,X)] interface causes database named X +** on [database connection] D to be [checkpointed]. ^If X is NULL or an +** empty string, then a checkpoint is run on all databases of +** connection D. ^If the database connection D is not in +** [WAL | write-ahead log mode] then this interface is a harmless no-op. +** +** ^The [wal_checkpoint pragma] can be used to invoke this interface +** from SQL. ^The [sqlite3_wal_autocheckpoint()] interface and the +** [wal_autocheckpoint pragma] can be used to cause this interface to be +** run whenever the WAL reaches a certain size threshold. +** +** See also: [sqlite3_wal_checkpoint_v2()] +*/ +SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb); + +/* +** CAPI3REF: Checkpoint a database +** +** Run a checkpoint operation on WAL database zDb attached to database +** handle db. The specific operation is determined by the value of the +** eMode parameter: +** +**
+**
SQLITE_CHECKPOINT_PASSIVE
+** Checkpoint as many frames as possible without waiting for any database +** readers or writers to finish. Sync the db file if all frames in the log +** are checkpointed. This mode is the same as calling +** sqlite3_wal_checkpoint(). The busy-handler callback is never invoked. +** +**
SQLITE_CHECKPOINT_FULL
+** This mode blocks (calls the busy-handler callback) until there is no +** database writer and all readers are reading from the most recent database +** snapshot. It then checkpoints all frames in the log file and syncs the +** database file. This call blocks database writers while it is running, +** but not database readers. +** +**
SQLITE_CHECKPOINT_RESTART
+** This mode works the same way as SQLITE_CHECKPOINT_FULL, except after +** checkpointing the log file it blocks (calls the busy-handler callback) +** until all readers are reading from the database file only. This ensures +** that the next client to write to the database file restarts the log file +** from the beginning. This call blocks database writers while it is running, +** but not database readers. +**
+** +** If pnLog is not NULL, then *pnLog is set to the total number of frames in +** the log file before returning. If pnCkpt is not NULL, then *pnCkpt is set to +** the total number of checkpointed frames (including any that were already +** checkpointed when this function is called). *pnLog and *pnCkpt may be +** populated even if sqlite3_wal_checkpoint_v2() returns other than SQLITE_OK. +** If no values are available because of an error, they are both set to -1 +** before returning to communicate this to the caller. +** +** All calls obtain an exclusive "checkpoint" lock on the database file. If +** any other process is running a checkpoint operation at the same time, the +** lock cannot be obtained and SQLITE_BUSY is returned. Even if there is a +** busy-handler configured, it will not be invoked in this case. +** +** The SQLITE_CHECKPOINT_FULL and RESTART modes also obtain the exclusive +** "writer" lock on the database file. If the writer lock cannot be obtained +** immediately, and a busy-handler is configured, it is invoked and the writer +** lock retried until either the busy-handler returns 0 or the lock is +** successfully obtained. The busy-handler is also invoked while waiting for +** database readers as described above. If the busy-handler returns 0 before +** the writer lock is obtained or while waiting for database readers, the +** checkpoint operation proceeds from that point in the same way as +** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible +** without blocking any further. SQLITE_BUSY is returned in this case. +** +** If parameter zDb is NULL or points to a zero length string, then the +** specified operation is attempted on all WAL databases. In this case the +** values written to output parameters *pnLog and *pnCkpt are undefined. If +** an SQLITE_BUSY error is encountered when processing one or more of the +** attached WAL databases, the operation is still attempted on any remaining +** attached databases and SQLITE_BUSY is returned to the caller. If any other +** error occurs while processing an attached database, processing is abandoned +** and the error code returned to the caller immediately. If no error +** (SQLITE_BUSY or otherwise) is encountered while processing the attached +** databases, SQLITE_OK is returned. +** +** If database zDb is the name of an attached database that is not in WAL +** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. If +** zDb is not NULL (or a zero length string) and is not the name of any +** attached database, SQLITE_ERROR is returned to the caller. +*/ +SQLITE_API int sqlite3_wal_checkpoint_v2( + sqlite3 *db, /* Database handle */ + const char *zDb, /* Name of attached database (or NULL) */ + int eMode, /* SQLITE_CHECKPOINT_* value */ + int *pnLog, /* OUT: Size of WAL log in frames */ + int *pnCkpt /* OUT: Total number of frames checkpointed */ +); + +/* +** CAPI3REF: Checkpoint operation parameters +** +** These constants can be used as the 3rd parameter to +** [sqlite3_wal_checkpoint_v2()]. See the [sqlite3_wal_checkpoint_v2()] +** documentation for additional information about the meaning and use of +** each of these values. +*/ +#define SQLITE_CHECKPOINT_PASSIVE 0 +#define SQLITE_CHECKPOINT_FULL 1 +#define SQLITE_CHECKPOINT_RESTART 2 + +/* +** CAPI3REF: Virtual Table Interface Configuration +** +** This function may be called by either the [xConnect] or [xCreate] method +** of a [virtual table] implementation to configure +** various facets of the virtual table interface. +** +** If this interface is invoked outside the context of an xConnect or +** xCreate virtual table method then the behavior is undefined. +** +** At present, there is only one option that may be configured using +** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].) Further options +** may be added in the future. +*/ +SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); + +/* +** CAPI3REF: Virtual Table Configuration Options +** +** These macros define the various options to the +** [sqlite3_vtab_config()] interface that [virtual table] implementations +** can use to customize and optimize their behavior. +** +**
+**
SQLITE_VTAB_CONSTRAINT_SUPPORT +**
Calls of the form +** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported, +** where X is an integer. If X is zero, then the [virtual table] whose +** [xCreate] or [xConnect] method invoked [sqlite3_vtab_config()] does not +** support constraints. In this configuration (which is the default) if +** a call to the [xUpdate] method returns [SQLITE_CONSTRAINT], then the entire +** statement is rolled back as if [ON CONFLICT | OR ABORT] had been +** specified as part of the users SQL statement, regardless of the actual +** ON CONFLICT mode specified. +** +** If X is non-zero, then the virtual table implementation guarantees +** that if [xUpdate] returns [SQLITE_CONSTRAINT], it will do so before +** any modifications to internal or persistent data structures have been made. +** If the [ON CONFLICT] mode is ABORT, FAIL, IGNORE or ROLLBACK, SQLite +** is able to roll back a statement or database transaction, and abandon +** or continue processing the current SQL statement as appropriate. +** If the ON CONFLICT mode is REPLACE and the [xUpdate] method returns +** [SQLITE_CONSTRAINT], SQLite handles this as if the ON CONFLICT mode +** had been ABORT. +** +** Virtual table implementations that are required to handle OR REPLACE +** must do so within the [xUpdate] method. If a call to the +** [sqlite3_vtab_on_conflict()] function indicates that the current ON +** CONFLICT policy is REPLACE, the virtual table implementation should +** silently replace the appropriate rows within the xUpdate callback and +** return SQLITE_OK. Or, if this is not possible, it may return +** SQLITE_CONSTRAINT, in which case SQLite falls back to OR ABORT +** constraint handling. +**
+*/ +#define SQLITE_VTAB_CONSTRAINT_SUPPORT 1 + +/* +** CAPI3REF: Determine The Virtual Table Conflict Policy +** +** This function may only be called from within a call to the [xUpdate] method +** of a [virtual table] implementation for an INSERT or UPDATE operation. ^The +** value returned is one of [SQLITE_ROLLBACK], [SQLITE_IGNORE], [SQLITE_FAIL], +** [SQLITE_ABORT], or [SQLITE_REPLACE], according to the [ON CONFLICT] mode +** of the SQL statement that triggered the call to the [xUpdate] method of the +** [virtual table]. +*/ +SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *); + +/* +** CAPI3REF: Conflict resolution modes +** +** These constants are returned by [sqlite3_vtab_on_conflict()] to +** inform a [virtual table] implementation what the [ON CONFLICT] mode +** is for the SQL statement being evaluated. +** +** Note that the [SQLITE_IGNORE] constant is also used as a potential +** return value from the [sqlite3_set_authorizer()] callback and that +** [SQLITE_ABORT] is also a [result code]. +*/ +#define SQLITE_ROLLBACK 1 +/* #define SQLITE_IGNORE 2 // Also used by sqlite3_authorizer() callback */ +#define SQLITE_FAIL 3 +/* #define SQLITE_ABORT 4 // Also an error code */ +#define SQLITE_REPLACE 5 + + + +/* +** Undo the hack that converts floating point types to integer for +** builds on processors without floating point support. +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# undef double +#endif + +#ifdef __cplusplus +} /* End of the 'extern "C"' block */ +#endif +#endif + +/* +** 2010 August 30 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +*/ + +#ifndef _SQLITE3RTREE_H_ +#define _SQLITE3RTREE_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry; + +/* +** Register a geometry callback named zGeom that can be used as part of an +** R-Tree geometry query as follows: +** +** SELECT ... FROM WHERE MATCH $zGeom(... params ...) +*/ +SQLITE_API int sqlite3_rtree_geometry_callback( + sqlite3 *db, + const char *zGeom, + int (*xGeom)(sqlite3_rtree_geometry *, int nCoord, double *aCoord, int *pRes), + void *pContext +); + + +/* +** A pointer to a structure of the following type is passed as the first +** argument to callbacks registered using rtree_geometry_callback(). +*/ +struct sqlite3_rtree_geometry { + void *pContext; /* Copy of pContext passed to s_r_g_c() */ + int nParam; /* Size of array aParam[] */ + double *aParam; /* Parameters passed to SQL geom function */ + void *pUser; /* Callback implementation user data */ + void (*xDelUser)(void *); /* Called by SQLite to clean up pUser */ +}; + + +#ifdef __cplusplus +} /* end of the 'extern "C"' block */ +#endif + +#endif /* ifndef _SQLITE3RTREE_H_ */ + diff --git a/scalos/libraries/sqlite/sqlite3_base.h b/scalos/libraries/sqlite/sqlite3_base.h new file mode 100644 index 000000000..f7f4cab94 --- /dev/null +++ b/scalos/libraries/sqlite/sqlite3_base.h @@ -0,0 +1,50 @@ +// sqlite3_base.h +// $Date$ +// $Revision$ + + +#ifndef SQLITE3BASE_H +#define SQLITE3BASE_H + +#include +#include +#include +#include +#include + + +struct SQLite3Base +{ + struct Library sql3_LibNode; + + struct SegList *sql3_SegList; + + BOOL sql3_Initialized; + BOOL sql3_SemaAdded; + + T_TIMEREQUEST *sql3_TimerIO; +}; + +//---------------------------------------------------------------------------- + +// Debugging... +#define d(x) ; +#define d1(x) ; +#ifdef NDEBUG +#define d2(x) ; +#else +#define d2(x) x; +#endif + +// aus debug.lib +#ifdef __AROS__ +#include +#define KPrintF kprintf +#else +extern int kprintf(const char *fmt, ...); +extern int KPrintF(const char *fmt, ...); +#endif + +//---------------------------------------------------------------------------- + +#endif /* SQLITE3BASE_H */ diff --git a/scalos/libraries/sqlite/src/alter.c b/scalos/libraries/sqlite/src/alter.c new file mode 100644 index 000000000..fb6d89de6 --- /dev/null +++ b/scalos/libraries/sqlite/src/alter.c @@ -0,0 +1,826 @@ +/* +** 2005 February 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains C code routines that used to generate VDBE code +** that implements the ALTER TABLE command. +*/ +#include "sqliteInt.h" + +/* +** The code in this file only exists if we are not omitting the +** ALTER TABLE logic from the build. +*/ +#ifndef SQLITE_OMIT_ALTERTABLE + + +/* +** This function is used by SQL generated to implement the +** ALTER TABLE command. The first argument is the text of a CREATE TABLE or +** CREATE INDEX command. The second is a table name. The table name in +** the CREATE TABLE or CREATE INDEX statement is replaced with the third +** argument and the result returned. Examples: +** +** sqlite_rename_table('CREATE TABLE abc(a, b, c)', 'def') +** -> 'CREATE TABLE def(a, b, c)' +** +** sqlite_rename_table('CREATE INDEX i ON abc(a)', 'def') +** -> 'CREATE INDEX i ON def(a, b, c)' +*/ +static void renameTableFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + unsigned char const *zSql = sqlite3_value_text(argv[0]); + unsigned char const *zTableName = sqlite3_value_text(argv[1]); + + int token; + Token tname; + unsigned char const *zCsr = zSql; + int len = 0; + char *zRet; + + sqlite3 *db = sqlite3_context_db_handle(context); + + UNUSED_PARAMETER(NotUsed); + + /* The principle used to locate the table name in the CREATE TABLE + ** statement is that the table name is the first non-space token that + ** is immediately followed by a TK_LP or TK_USING token. + */ + if( zSql ){ + do { + if( !*zCsr ){ + /* Ran out of input before finding an opening bracket. Return NULL. */ + return; + } + + /* Store the token that zCsr points to in tname. */ + tname.z = (char*)zCsr; + tname.n = len; + + /* Advance zCsr to the next token. Store that token type in 'token', + ** and its length in 'len' (to be used next iteration of this loop). + */ + do { + zCsr += len; + len = sqlite3GetToken(zCsr, &token); + } while( token==TK_SPACE ); + assert( len>0 ); + } while( token!=TK_LP && token!=TK_USING ); + + zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql, + zTableName, tname.z+tname.n); + sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC); + } +} + +/* +** This C function implements an SQL user function that is used by SQL code +** generated by the ALTER TABLE ... RENAME command to modify the definition +** of any foreign key constraints that use the table being renamed as the +** parent table. It is passed three arguments: +** +** 1) The complete text of the CREATE TABLE statement being modified, +** 2) The old name of the table being renamed, and +** 3) The new name of the table being renamed. +** +** It returns the new CREATE TABLE statement. For example: +** +** sqlite_rename_parent('CREATE TABLE t1(a REFERENCES t2)', 't2', 't3') +** -> 'CREATE TABLE t1(a REFERENCES t3)' +*/ +#ifndef SQLITE_OMIT_FOREIGN_KEY +static void renameParentFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + char *zOutput = 0; + char *zResult; + unsigned char const *zInput = sqlite3_value_text(argv[0]); + unsigned char const *zOld = sqlite3_value_text(argv[1]); + unsigned char const *zNew = sqlite3_value_text(argv[2]); + + unsigned const char *z; /* Pointer to token */ + int n; /* Length of token z */ + int token; /* Type of token */ + + UNUSED_PARAMETER(NotUsed); + for(z=zInput; *z; z=z+n){ + n = sqlite3GetToken(z, &token); + if( token==TK_REFERENCES ){ + char *zParent; + do { + z += n; + n = sqlite3GetToken(z, &token); + }while( token==TK_SPACE ); + + zParent = sqlite3DbStrNDup(db, (const char *)z, n); + if( zParent==0 ) break; + sqlite3Dequote(zParent); + if( 0==sqlite3StrICmp((const char *)zOld, zParent) ){ + char *zOut = sqlite3MPrintf(db, "%s%.*s\"%w\"", + (zOutput?zOutput:""), z-zInput, zInput, (const char *)zNew + ); + sqlite3DbFree(db, zOutput); + zOutput = zOut; + zInput = &z[n]; + } + sqlite3DbFree(db, zParent); + } + } + + zResult = sqlite3MPrintf(db, "%s%s", (zOutput?zOutput:""), zInput), + sqlite3_result_text(context, zResult, -1, SQLITE_DYNAMIC); + sqlite3DbFree(db, zOutput); +} +#endif + +#ifndef SQLITE_OMIT_TRIGGER +/* This function is used by SQL generated to implement the +** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER +** statement. The second is a table name. The table name in the CREATE +** TRIGGER statement is replaced with the third argument and the result +** returned. This is analagous to renameTableFunc() above, except for CREATE +** TRIGGER, not CREATE INDEX and CREATE TABLE. +*/ +static void renameTriggerFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + unsigned char const *zSql = sqlite3_value_text(argv[0]); + unsigned char const *zTableName = sqlite3_value_text(argv[1]); + + int token; + Token tname; + int dist = 3; + unsigned char const *zCsr = zSql; + int len = 0; + char *zRet; + sqlite3 *db = sqlite3_context_db_handle(context); + + UNUSED_PARAMETER(NotUsed); + + /* The principle used to locate the table name in the CREATE TRIGGER + ** statement is that the table name is the first token that is immediatedly + ** preceded by either TK_ON or TK_DOT and immediatedly followed by one + ** of TK_WHEN, TK_BEGIN or TK_FOR. + */ + if( zSql ){ + do { + + if( !*zCsr ){ + /* Ran out of input before finding the table name. Return NULL. */ + return; + } + + /* Store the token that zCsr points to in tname. */ + tname.z = (char*)zCsr; + tname.n = len; + + /* Advance zCsr to the next token. Store that token type in 'token', + ** and its length in 'len' (to be used next iteration of this loop). + */ + do { + zCsr += len; + len = sqlite3GetToken(zCsr, &token); + }while( token==TK_SPACE ); + assert( len>0 ); + + /* Variable 'dist' stores the number of tokens read since the most + ** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN + ** token is read and 'dist' equals 2, the condition stated above + ** to be met. + ** + ** Note that ON cannot be a database, table or column name, so + ** there is no need to worry about syntax like + ** "CREATE TRIGGER ... ON ON.ON BEGIN ..." etc. + */ + dist++; + if( token==TK_DOT || token==TK_ON ){ + dist = 0; + } + } while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) ); + + /* Variable tname now contains the token that is the old table-name + ** in the CREATE TRIGGER statement. + */ + zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql, + zTableName, tname.z+tname.n); + sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC); + } +} +#endif /* !SQLITE_OMIT_TRIGGER */ + +/* +** Register built-in functions used to help implement ALTER TABLE +*/ +void sqlite3AlterFunctions(void){ + static SQLITE_WSD FuncDef aAlterTableFuncs[] = { + FUNCTION(sqlite_rename_table, 2, 0, 0, renameTableFunc), +#ifndef SQLITE_OMIT_TRIGGER + FUNCTION(sqlite_rename_trigger, 2, 0, 0, renameTriggerFunc), +#endif +#ifndef SQLITE_OMIT_FOREIGN_KEY + FUNCTION(sqlite_rename_parent, 3, 0, 0, renameParentFunc), +#endif + }; + int i; + FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions); + FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aAlterTableFuncs); + + for(i=0; i OR name= OR ... +** +** If argument zWhere is NULL, then a pointer string containing the text +** "name=" is returned, where is the quoted version +** of the string passed as argument zConstant. The returned buffer is +** allocated using sqlite3DbMalloc(). It is the responsibility of the +** caller to ensure that it is eventually freed. +** +** If argument zWhere is not NULL, then the string returned is +** " OR name=", where is the contents of zWhere. +** In this case zWhere is passed to sqlite3DbFree() before returning. +** +*/ +static char *whereOrName(sqlite3 *db, char *zWhere, char *zConstant){ + char *zNew; + if( !zWhere ){ + zNew = sqlite3MPrintf(db, "name=%Q", zConstant); + }else{ + zNew = sqlite3MPrintf(db, "%s OR name=%Q", zWhere, zConstant); + sqlite3DbFree(db, zWhere); + } + return zNew; +} + +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) +/* +** Generate the text of a WHERE expression which can be used to select all +** tables that have foreign key constraints that refer to table pTab (i.e. +** constraints for which pTab is the parent table) from the sqlite_master +** table. +*/ +static char *whereForeignKeys(Parse *pParse, Table *pTab){ + FKey *p; + char *zWhere = 0; + for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ + zWhere = whereOrName(pParse->db, zWhere, p->pFrom->zName); + } + return zWhere; +} +#endif + +/* +** Generate the text of a WHERE expression which can be used to select all +** temporary triggers on table pTab from the sqlite_temp_master table. If +** table pTab has no temporary triggers, or is itself stored in the +** temporary database, NULL is returned. +*/ +static char *whereTempTriggers(Parse *pParse, Table *pTab){ + Trigger *pTrig; + char *zWhere = 0; + const Schema *pTempSchema = pParse->db->aDb[1].pSchema; /* Temp db schema */ + + /* If the table is not located in the temp-db (in which case NULL is + ** returned, loop through the tables list of triggers. For each trigger + ** that is not part of the temp-db schema, add a clause to the WHERE + ** expression being built up in zWhere. + */ + if( pTab->pSchema!=pTempSchema ){ + sqlite3 *db = pParse->db; + for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){ + if( pTrig->pSchema==pTempSchema ){ + zWhere = whereOrName(db, zWhere, pTrig->zName); + } + } + } + if( zWhere ){ + char *zNew = sqlite3MPrintf(pParse->db, "type='trigger' AND (%s)", zWhere); + sqlite3DbFree(pParse->db, zWhere); + zWhere = zNew; + } + return zWhere; +} + +/* +** Generate code to drop and reload the internal representation of table +** pTab from the database, including triggers and temporary triggers. +** Argument zName is the name of the table in the database schema at +** the time the generated code is executed. This can be different from +** pTab->zName if this function is being called to code part of an +** "ALTER TABLE RENAME TO" statement. +*/ +static void reloadTableSchema(Parse *pParse, Table *pTab, const char *zName){ + Vdbe *v; + char *zWhere; + int iDb; /* Index of database containing pTab */ +#ifndef SQLITE_OMIT_TRIGGER + Trigger *pTrig; +#endif + + v = sqlite3GetVdbe(pParse); + if( NEVER(v==0) ) return; + assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); + iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + assert( iDb>=0 ); + +#ifndef SQLITE_OMIT_TRIGGER + /* Drop any table triggers from the internal schema. */ + for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){ + int iTrigDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema); + assert( iTrigDb==iDb || iTrigDb==1 ); + sqlite3VdbeAddOp4(v, OP_DropTrigger, iTrigDb, 0, 0, pTrig->zName, 0); + } +#endif + + /* Drop the table and index from the internal schema. */ + sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0); + + /* Reload the table, index and permanent trigger schemas. */ + zWhere = sqlite3MPrintf(pParse->db, "tbl_name=%Q", zName); + if( !zWhere ) return; + sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere); + +#ifndef SQLITE_OMIT_TRIGGER + /* Now, if the table is not stored in the temp database, reload any temp + ** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined. + */ + if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){ + sqlite3VdbeAddParseSchemaOp(v, 1, zWhere); + } +#endif +} + +/* +** Parameter zName is the name of a table that is about to be altered +** (either with ALTER TABLE ... RENAME TO or ALTER TABLE ... ADD COLUMN). +** If the table is a system table, this function leaves an error message +** in pParse->zErr (system tables may not be altered) and returns non-zero. +** +** Or, if zName is not a system table, zero is returned. +*/ +static int isSystemTable(Parse *pParse, const char *zName){ + if( sqlite3Strlen30(zName)>6 && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){ + sqlite3ErrorMsg(pParse, "table %s may not be altered", zName); + return 1; + } + return 0; +} + +/* +** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy" +** command. +*/ +void sqlite3AlterRenameTable( + Parse *pParse, /* Parser context. */ + SrcList *pSrc, /* The table to rename. */ + Token *pName /* The new table name. */ +){ + int iDb; /* Database that contains the table */ + char *zDb; /* Name of database iDb */ + Table *pTab; /* Table being renamed */ + char *zName = 0; /* NULL-terminated version of pName */ + sqlite3 *db = pParse->db; /* Database connection */ + int nTabName; /* Number of UTF-8 characters in zTabName */ + const char *zTabName; /* Original name of the table */ + Vdbe *v; +#ifndef SQLITE_OMIT_TRIGGER + char *zWhere = 0; /* Where clause to locate temp triggers */ +#endif + VTable *pVTab = 0; /* Non-zero if this is a v-tab with an xRename() */ + int savedDbFlags; /* Saved value of db->flags */ + + savedDbFlags = db->flags; + if( NEVER(db->mallocFailed) ) goto exit_rename_table; + assert( pSrc->nSrc==1 ); + assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); + + pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName, pSrc->a[0].zDatabase); + if( !pTab ) goto exit_rename_table; + iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + zDb = db->aDb[iDb].zName; + db->flags |= SQLITE_PreferBuiltin; + + /* Get a NULL terminated version of the new table name. */ + zName = sqlite3NameFromToken(db, pName); + if( !zName ) goto exit_rename_table; + + /* Check that a table or index named 'zName' does not already exist + ** in database iDb. If so, this is an error. + */ + if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){ + sqlite3ErrorMsg(pParse, + "there is already another table or index with this name: %s", zName); + goto exit_rename_table; + } + + /* Make sure it is not a system table being altered, or a reserved name + ** that the table is being renamed to. + */ + if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ){ + goto exit_rename_table; + } + if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ goto + exit_rename_table; + } + +#ifndef SQLITE_OMIT_VIEW + if( pTab->pSelect ){ + sqlite3ErrorMsg(pParse, "view %s may not be altered", pTab->zName); + goto exit_rename_table; + } +#endif + +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Invoke the authorization callback. */ + if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ + goto exit_rename_table; + } +#endif + +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( sqlite3ViewGetColumnNames(pParse, pTab) ){ + goto exit_rename_table; + } + if( IsVirtual(pTab) ){ + pVTab = sqlite3GetVTable(db, pTab); + if( pVTab->pVtab->pModule->xRename==0 ){ + pVTab = 0; + } + } +#endif + + /* Begin a transaction and code the VerifyCookie for database iDb. + ** Then modify the schema cookie (since the ALTER TABLE modifies the + ** schema). Open a statement transaction if the table is a virtual + ** table. + */ + v = sqlite3GetVdbe(pParse); + if( v==0 ){ + goto exit_rename_table; + } + sqlite3BeginWriteOperation(pParse, pVTab!=0, iDb); + sqlite3ChangeCookie(pParse, iDb); + + /* If this is a virtual table, invoke the xRename() function if + ** one is defined. The xRename() callback will modify the names + ** of any resources used by the v-table implementation (including other + ** SQLite tables) that are identified by the name of the virtual table. + */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( pVTab ){ + int i = ++pParse->nMem; + sqlite3VdbeAddOp4(v, OP_String8, 0, i, 0, zName, 0); + sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB); + sqlite3MayAbort(pParse); + } +#endif + + /* figure out how many UTF-8 characters are in zName */ + zTabName = pTab->zName; + nTabName = sqlite3Utf8CharLen(zTabName, -1); + +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) + if( db->flags&SQLITE_ForeignKeys ){ + /* If foreign-key support is enabled, rewrite the CREATE TABLE + ** statements corresponding to all child tables of foreign key constraints + ** for which the renamed table is the parent table. */ + if( (zWhere=whereForeignKeys(pParse, pTab))!=0 ){ + sqlite3NestedParse(pParse, + "UPDATE \"%w\".%s SET " + "sql = sqlite_rename_parent(sql, %Q, %Q) " + "WHERE %s;", zDb, SCHEMA_TABLE(iDb), zTabName, zName, zWhere); + sqlite3DbFree(db, zWhere); + } + } +#endif + + /* Modify the sqlite_master table to use the new table name. */ + sqlite3NestedParse(pParse, + "UPDATE %Q.%s SET " +#ifdef SQLITE_OMIT_TRIGGER + "sql = sqlite_rename_table(sql, %Q), " +#else + "sql = CASE " + "WHEN type = 'trigger' THEN sqlite_rename_trigger(sql, %Q)" + "ELSE sqlite_rename_table(sql, %Q) END, " +#endif + "tbl_name = %Q, " + "name = CASE " + "WHEN type='table' THEN %Q " + "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN " + "'sqlite_autoindex_' || %Q || substr(name,%d+18) " + "ELSE name END " + "WHERE tbl_name=%Q AND " + "(type='table' OR type='index' OR type='trigger');", + zDb, SCHEMA_TABLE(iDb), zName, zName, zName, +#ifndef SQLITE_OMIT_TRIGGER + zName, +#endif + zName, nTabName, zTabName + ); + +#ifndef SQLITE_OMIT_AUTOINCREMENT + /* If the sqlite_sequence table exists in this database, then update + ** it with the new table name. + */ + if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){ + sqlite3NestedParse(pParse, + "UPDATE \"%w\".sqlite_sequence set name = %Q WHERE name = %Q", + zDb, zName, pTab->zName); + } +#endif + +#ifndef SQLITE_OMIT_TRIGGER + /* If there are TEMP triggers on this table, modify the sqlite_temp_master + ** table. Don't do this if the table being ALTERed is itself located in + ** the temp database. + */ + if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){ + sqlite3NestedParse(pParse, + "UPDATE sqlite_temp_master SET " + "sql = sqlite_rename_trigger(sql, %Q), " + "tbl_name = %Q " + "WHERE %s;", zName, zName, zWhere); + sqlite3DbFree(db, zWhere); + } +#endif + +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) + if( db->flags&SQLITE_ForeignKeys ){ + FKey *p; + for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ + Table *pFrom = p->pFrom; + if( pFrom!=pTab ){ + reloadTableSchema(pParse, p->pFrom, pFrom->zName); + } + } + } +#endif + + /* Drop and reload the internal table schema. */ + reloadTableSchema(pParse, pTab, zName); + +exit_rename_table: + sqlite3SrcListDelete(db, pSrc); + sqlite3DbFree(db, zName); + db->flags = savedDbFlags; +} + + +/* +** Generate code to make sure the file format number is at least minFormat. +** The generated code will increase the file format number if necessary. +*/ +void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){ + Vdbe *v; + v = sqlite3GetVdbe(pParse); + /* The VDBE should have been allocated before this routine is called. + ** If that allocation failed, we would have quit before reaching this + ** point */ + if( ALWAYS(v) ){ + int r1 = sqlite3GetTempReg(pParse); + int r2 = sqlite3GetTempReg(pParse); + int j1; + sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT); + sqlite3VdbeUsesBtree(v, iDb); + sqlite3VdbeAddOp2(v, OP_Integer, minFormat, r2); + j1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, r2); + sqlite3VdbeJumpHere(v, j1); + sqlite3ReleaseTempReg(pParse, r1); + sqlite3ReleaseTempReg(pParse, r2); + } +} + +/* +** This function is called after an "ALTER TABLE ... ADD" statement +** has been parsed. Argument pColDef contains the text of the new +** column definition. +** +** The Table structure pParse->pNewTable was extended to include +** the new column during parsing. +*/ +void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ + Table *pNew; /* Copy of pParse->pNewTable */ + Table *pTab; /* Table being altered */ + int iDb; /* Database number */ + const char *zDb; /* Database name */ + const char *zTab; /* Table name */ + char *zCol; /* Null-terminated column definition */ + Column *pCol; /* The new column */ + Expr *pDflt; /* Default value for the new column */ + sqlite3 *db; /* The database connection; */ + + db = pParse->db; + if( pParse->nErr || db->mallocFailed ) return; + pNew = pParse->pNewTable; + assert( pNew ); + + assert( sqlite3BtreeHoldsAllMutexes(db) ); + iDb = sqlite3SchemaToIndex(db, pNew->pSchema); + zDb = db->aDb[iDb].zName; + zTab = &pNew->zName[16]; /* Skip the "sqlite_altertab_" prefix on the name */ + pCol = &pNew->aCol[pNew->nCol-1]; + pDflt = pCol->pDflt; + pTab = sqlite3FindTable(db, zTab, zDb); + assert( pTab ); + +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Invoke the authorization callback. */ + if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ + return; + } +#endif + + /* If the default value for the new column was specified with a + ** literal NULL, then set pDflt to 0. This simplifies checking + ** for an SQL NULL default below. + */ + if( pDflt && pDflt->op==TK_NULL ){ + pDflt = 0; + } + + /* Check that the new column is not specified as PRIMARY KEY or UNIQUE. + ** If there is a NOT NULL constraint, then the default value for the + ** column must not be NULL. + */ + if( pCol->isPrimKey ){ + sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column"); + return; + } + if( pNew->pIndex ){ + sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column"); + return; + } + if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){ + sqlite3ErrorMsg(pParse, + "Cannot add a REFERENCES column with non-NULL default value"); + return; + } + if( pCol->notNull && !pDflt ){ + sqlite3ErrorMsg(pParse, + "Cannot add a NOT NULL column with default value NULL"); + return; + } + + /* Ensure the default expression is something that sqlite3ValueFromExpr() + ** can handle (i.e. not CURRENT_TIME etc.) + */ + if( pDflt ){ + sqlite3_value *pVal; + if( sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){ + db->mallocFailed = 1; + return; + } + if( !pVal ){ + sqlite3ErrorMsg(pParse, "Cannot add a column with non-constant default"); + return; + } + sqlite3ValueFree(pVal); + } + + /* Modify the CREATE TABLE statement. */ + zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n); + if( zCol ){ + char *zEnd = &zCol[pColDef->n-1]; + int savedDbFlags = db->flags; + while( zEnd>zCol && (*zEnd==';' || sqlite3Isspace(*zEnd)) ){ + *zEnd-- = '\0'; + } + db->flags |= SQLITE_PreferBuiltin; + sqlite3NestedParse(pParse, + "UPDATE \"%w\".%s SET " + "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) " + "WHERE type = 'table' AND name = %Q", + zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1, + zTab + ); + sqlite3DbFree(db, zCol); + db->flags = savedDbFlags; + } + + /* If the default value of the new column is NULL, then set the file + ** format to 2. If the default value of the new column is not NULL, + ** the file format becomes 3. + */ + sqlite3MinimumFileFormat(pParse, iDb, pDflt ? 3 : 2); + + /* Reload the schema of the modified table. */ + reloadTableSchema(pParse, pTab, pTab->zName); +} + +/* +** This function is called by the parser after the table-name in +** an "ALTER TABLE ADD" statement is parsed. Argument +** pSrc is the full-name of the table being altered. +** +** This routine makes a (partial) copy of the Table structure +** for the table being altered and sets Parse.pNewTable to point +** to it. Routines called by the parser as the column definition +** is parsed (i.e. sqlite3AddColumn()) add the new Column data to +** the copy. The copy of the Table structure is deleted by tokenize.c +** after parsing is finished. +** +** Routine sqlite3AlterFinishAddColumn() will be called to complete +** coding the "ALTER TABLE ... ADD" statement. +*/ +void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ + Table *pNew; + Table *pTab; + Vdbe *v; + int iDb; + int i; + int nAlloc; + sqlite3 *db = pParse->db; + + /* Look up the table being altered. */ + assert( pParse->pNewTable==0 ); + assert( sqlite3BtreeHoldsAllMutexes(db) ); + if( db->mallocFailed ) goto exit_begin_add_column; + pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName, pSrc->a[0].zDatabase); + if( !pTab ) goto exit_begin_add_column; + +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + sqlite3ErrorMsg(pParse, "virtual tables may not be altered"); + goto exit_begin_add_column; + } +#endif + + /* Make sure this is not an attempt to ALTER a view. */ + if( pTab->pSelect ){ + sqlite3ErrorMsg(pParse, "Cannot add a column to a view"); + goto exit_begin_add_column; + } + if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ){ + goto exit_begin_add_column; + } + + assert( pTab->addColOffset>0 ); + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + + /* Put a copy of the Table struct in Parse.pNewTable for the + ** sqlite3AddColumn() function and friends to modify. But modify + ** the name by adding an "sqlite_altertab_" prefix. By adding this + ** prefix, we insure that the name will not collide with an existing + ** table because user table are not allowed to have the "sqlite_" + ** prefix on their name. + */ + pNew = (Table*)sqlite3DbMallocZero(db, sizeof(Table)); + if( !pNew ) goto exit_begin_add_column; + pParse->pNewTable = pNew; + pNew->nRef = 1; + pNew->nCol = pTab->nCol; + assert( pNew->nCol>0 ); + nAlloc = (((pNew->nCol-1)/8)*8)+8; + assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 ); + pNew->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*nAlloc); + pNew->zName = sqlite3MPrintf(db, "sqlite_altertab_%s", pTab->zName); + if( !pNew->aCol || !pNew->zName ){ + db->mallocFailed = 1; + goto exit_begin_add_column; + } + memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol); + for(i=0; inCol; i++){ + Column *pCol = &pNew->aCol[i]; + pCol->zName = sqlite3DbStrDup(db, pCol->zName); + pCol->zColl = 0; + pCol->zType = 0; + pCol->pDflt = 0; + pCol->zDflt = 0; + } + pNew->pSchema = db->aDb[iDb].pSchema; + pNew->addColOffset = pTab->addColOffset; + pNew->nRef = 1; + + /* Begin a transaction and increment the schema cookie. */ + sqlite3BeginWriteOperation(pParse, 0, iDb); + v = sqlite3GetVdbe(pParse); + if( !v ) goto exit_begin_add_column; + sqlite3ChangeCookie(pParse, iDb); + +exit_begin_add_column: + sqlite3SrcListDelete(db, pSrc); + return; +} +#endif /* SQLITE_ALTER_TABLE */ diff --git a/scalos/libraries/sqlite/src/analyze.c b/scalos/libraries/sqlite/src/analyze.c new file mode 100644 index 000000000..cbfdc8587 --- /dev/null +++ b/scalos/libraries/sqlite/src/analyze.c @@ -0,0 +1,1121 @@ +/* +** 2005 July 8 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code associated with the ANALYZE command. +** +** The ANALYZE command gather statistics about the content of tables +** and indices. These statistics are made available to the query planner +** to help it make better decisions about how to perform queries. +** +** The following system tables are or have been supported: +** +** CREATE TABLE sqlite_stat1(tbl, idx, stat); +** CREATE TABLE sqlite_stat2(tbl, idx, sampleno, sample); +** CREATE TABLE sqlite_stat3(tbl, idx, nEq, nLt, nDLt, sample); +** +** Additional tables might be added in future releases of SQLite. +** The sqlite_stat2 table is not created or used unless the SQLite version +** is between 3.6.18 and 3.7.8, inclusive, and unless SQLite is compiled +** with SQLITE_ENABLE_STAT2. The sqlite_stat2 table is deprecated. +** The sqlite_stat2 table is superceded by sqlite_stat3, which is only +** created and used by SQLite versions 3.7.9 and later and with +** SQLITE_ENABLE_STAT3 defined. The fucntionality of sqlite_stat3 +** is a superset of sqlite_stat2. +** +** Format of sqlite_stat1: +** +** There is normally one row per index, with the index identified by the +** name in the idx column. The tbl column is the name of the table to +** which the index belongs. In each such row, the stat column will be +** a string consisting of a list of integers. The first integer in this +** list is the number of rows in the index and in the table. The second +** integer is the average number of rows in the index that have the same +** value in the first column of the index. The third integer is the average +** number of rows in the index that have the same value for the first two +** columns. The N-th integer (for N>1) is the average number of rows in +** the index which have the same value for the first N-1 columns. For +** a K-column index, there will be K+1 integers in the stat column. If +** the index is unique, then the last integer will be 1. +** +** The list of integers in the stat column can optionally be followed +** by the keyword "unordered". The "unordered" keyword, if it is present, +** must be separated from the last integer by a single space. If the +** "unordered" keyword is present, then the query planner assumes that +** the index is unordered and will not use the index for a range query. +** +** If the sqlite_stat1.idx column is NULL, then the sqlite_stat1.stat +** column contains a single integer which is the (estimated) number of +** rows in the table identified by sqlite_stat1.tbl. +** +** Format of sqlite_stat2: +** +** The sqlite_stat2 is only created and is only used if SQLite is compiled +** with SQLITE_ENABLE_STAT2 and if the SQLite version number is between +** 3.6.18 and 3.7.8. The "stat2" table contains additional information +** about the distribution of keys within an index. The index is identified by +** the "idx" column and the "tbl" column is the name of the table to which +** the index belongs. There are usually 10 rows in the sqlite_stat2 +** table for each index. +** +** The sqlite_stat2 entries for an index that have sampleno between 0 and 9 +** inclusive are samples of the left-most key value in the index taken at +** evenly spaced points along the index. Let the number of samples be S +** (10 in the standard build) and let C be the number of rows in the index. +** Then the sampled rows are given by: +** +** rownumber = (i*C*2 + C)/(S*2) +** +** For i between 0 and S-1. Conceptually, the index space is divided into +** S uniform buckets and the samples are the middle row from each bucket. +** +** The format for sqlite_stat2 is recorded here for legacy reference. This +** version of SQLite does not support sqlite_stat2. It neither reads nor +** writes the sqlite_stat2 table. This version of SQLite only supports +** sqlite_stat3. +** +** Format for sqlite_stat3: +** +** The sqlite_stat3 is an enhancement to sqlite_stat2. A new name is +** used to avoid compatibility problems. +** +** The format of the sqlite_stat3 table is similar to the format of +** the sqlite_stat2 table. There are multiple entries for each index. +** The idx column names the index and the tbl column is the table of the +** index. If the idx and tbl columns are the same, then the sample is +** of the INTEGER PRIMARY KEY. The sample column is a value taken from +** the left-most column of the index. The nEq column is the approximate +** number of entires in the index whose left-most column exactly matches +** the sample. nLt is the approximate number of entires whose left-most +** column is less than the sample. The nDLt column is the approximate +** number of distinct left-most entries in the index that are less than +** the sample. +** +** Future versions of SQLite might change to store a string containing +** multiple integers values in the nDLt column of sqlite_stat3. The first +** integer will be the number of prior index entires that are distinct in +** the left-most column. The second integer will be the number of prior index +** entries that are distinct in the first two columns. The third integer +** will be the number of prior index entries that are distinct in the first +** three columns. And so forth. With that extension, the nDLt field is +** similar in function to the sqlite_stat1.stat field. +** +** There can be an arbitrary number of sqlite_stat3 entries per index. +** The ANALYZE command will typically generate sqlite_stat3 tables +** that contain between 10 and 40 samples which are distributed across +** the key space, though not uniformly, and which include samples with +** largest possible nEq values. +*/ +#ifndef SQLITE_OMIT_ANALYZE +#include "sqliteInt.h" + +/* +** This routine generates code that opens the sqlite_stat1 table for +** writing with cursor iStatCur. If the library was built with the +** SQLITE_ENABLE_STAT3 macro defined, then the sqlite_stat3 table is +** opened for writing using cursor (iStatCur+1) +** +** If the sqlite_stat1 tables does not previously exist, it is created. +** Similarly, if the sqlite_stat3 table does not exist and the library +** is compiled with SQLITE_ENABLE_STAT3 defined, it is created. +** +** Argument zWhere may be a pointer to a buffer containing a table name, +** or it may be a NULL pointer. If it is not NULL, then all entries in +** the sqlite_stat1 and (if applicable) sqlite_stat3 tables associated +** with the named table are deleted. If zWhere==0, then code is generated +** to delete all stat table entries. +*/ +static void openStatTable( + Parse *pParse, /* Parsing context */ + int iDb, /* The database we are looking in */ + int iStatCur, /* Open the sqlite_stat1 table on this cursor */ + const char *zWhere, /* Delete entries for this table or index */ + const char *zWhereType /* Either "tbl" or "idx" */ +){ + static const struct { + const char *zName; + const char *zCols; + } aTable[] = { + { "sqlite_stat1", "tbl,idx,stat" }, +#ifdef SQLITE_ENABLE_STAT3 + { "sqlite_stat3", "tbl,idx,neq,nlt,ndlt,sample" }, +#endif + }; + + int aRoot[] = {0, 0}; + u8 aCreateTbl[] = {0, 0}; + + int i; + sqlite3 *db = pParse->db; + Db *pDb; + Vdbe *v = sqlite3GetVdbe(pParse); + if( v==0 ) return; + assert( sqlite3BtreeHoldsAllMutexes(db) ); + assert( sqlite3VdbeDb(v)==db ); + pDb = &db->aDb[iDb]; + + /* Create new statistic tables if they do not exist, or clear them + ** if they do already exist. + */ + for(i=0; izName))==0 ){ + /* The sqlite_stat[12] table does not exist. Create it. Note that a + ** side-effect of the CREATE TABLE statement is to leave the rootpage + ** of the new table in register pParse->regRoot. This is important + ** because the OpenWrite opcode below will be needing it. */ + sqlite3NestedParse(pParse, + "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols + ); + aRoot[i] = pParse->regRoot; + aCreateTbl[i] = 1; + }else{ + /* The table already exists. If zWhere is not NULL, delete all entries + ** associated with the table zWhere. If zWhere is NULL, delete the + ** entire contents of the table. */ + aRoot[i] = pStat->tnum; + sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab); + if( zWhere ){ + sqlite3NestedParse(pParse, + "DELETE FROM %Q.%s WHERE %s=%Q", pDb->zName, zTab, zWhereType, zWhere + ); + }else{ + /* The sqlite_stat[12] table already exists. Delete all rows. */ + sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb); + } + } + } + + /* Open the sqlite_stat[13] tables for writing. */ + for(i=0; ia[0])*mxSample; + p = sqlite3_malloc( n ); + if( p==0 ){ + sqlite3_result_error_nomem(context); + return; + } + memset(p, 0, n); + p->a = (struct Stat3Sample*)&p[1]; + p->nRow = nRow; + p->mxSample = mxSample; + p->nPSample = p->nRow/(mxSample/3+1) + 1; + sqlite3_randomness(sizeof(p->iPrn), &p->iPrn); + sqlite3_result_blob(context, p, sizeof(p), sqlite3_free); +} +static const FuncDef stat3InitFuncdef = { + 2, /* nArg */ + SQLITE_UTF8, /* iPrefEnc */ + 0, /* flags */ + 0, /* pUserData */ + 0, /* pNext */ + stat3Init, /* xFunc */ + 0, /* xStep */ + 0, /* xFinalize */ + "stat3_init", /* zName */ + 0, /* pHash */ + 0 /* pDestructor */ +}; + + +/* +** Implementation of the stat3_push(nEq,nLt,nDLt,rowid,P) SQL function. The +** arguments describe a single key instance. This routine makes the +** decision about whether or not to retain this key for the sqlite_stat3 +** table. +** +** The return value is NULL. +*/ +static void stat3Push( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + Stat3Accum *p = (Stat3Accum*)sqlite3_value_blob(argv[4]); + tRowcnt nEq = sqlite3_value_int64(argv[0]); + tRowcnt nLt = sqlite3_value_int64(argv[1]); + tRowcnt nDLt = sqlite3_value_int64(argv[2]); + i64 rowid = sqlite3_value_int64(argv[3]); + u8 isPSample = 0; + u8 doInsert = 0; + int iMin = p->iMin; + struct Stat3Sample *pSample; + int i; + u32 h; + + UNUSED_PARAMETER(context); + UNUSED_PARAMETER(argc); + if( nEq==0 ) return; + h = p->iPrn = p->iPrn*1103515245 + 12345; + if( (nLt/p->nPSample)!=((nEq+nLt)/p->nPSample) ){ + doInsert = isPSample = 1; + }else if( p->nSamplemxSample ){ + doInsert = 1; + }else{ + if( nEq>p->a[iMin].nEq || (nEq==p->a[iMin].nEq && h>p->a[iMin].iHash) ){ + doInsert = 1; + } + } + if( !doInsert ) return; + if( p->nSample==p->mxSample ){ + assert( p->nSample - iMin - 1 >= 0 ); + memmove(&p->a[iMin], &p->a[iMin+1], sizeof(p->a[0])*(p->nSample-iMin-1)); + pSample = &p->a[p->nSample-1]; + }else{ + pSample = &p->a[p->nSample++]; + } + pSample->iRowid = rowid; + pSample->nEq = nEq; + pSample->nLt = nLt; + pSample->nDLt = nDLt; + pSample->iHash = h; + pSample->isPSample = isPSample; + + /* Find the new minimum */ + if( p->nSample==p->mxSample ){ + pSample = p->a; + i = 0; + while( pSample->isPSample ){ + i++; + pSample++; + assert( inSample ); + } + nEq = pSample->nEq; + h = pSample->iHash; + iMin = i; + for(i++, pSample++; inSample; i++, pSample++){ + if( pSample->isPSample ) continue; + if( pSample->nEqnEq==nEq && pSample->iHashnEq; + h = pSample->iHash; + } + } + p->iMin = iMin; + } +} +static const FuncDef stat3PushFuncdef = { + 5, /* nArg */ + SQLITE_UTF8, /* iPrefEnc */ + 0, /* flags */ + 0, /* pUserData */ + 0, /* pNext */ + stat3Push, /* xFunc */ + 0, /* xStep */ + 0, /* xFinalize */ + "stat3_push", /* zName */ + 0, /* pHash */ + 0 /* pDestructor */ +}; + +/* +** Implementation of the stat3_get(P,N,...) SQL function. This routine is +** used to query the results. Content is returned for the Nth sqlite_stat3 +** row where N is between 0 and S-1 and S is the number of samples. The +** value returned depends on the number of arguments. +** +** argc==2 result: rowid +** argc==3 result: nEq +** argc==4 result: nLt +** argc==5 result: nDLt +*/ +static void stat3Get( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int n = sqlite3_value_int(argv[1]); + Stat3Accum *p = (Stat3Accum*)sqlite3_value_blob(argv[0]); + + assert( p!=0 ); + if( p->nSample<=n ) return; + switch( argc ){ + case 2: sqlite3_result_int64(context, p->a[n].iRowid); break; + case 3: sqlite3_result_int64(context, p->a[n].nEq); break; + case 4: sqlite3_result_int64(context, p->a[n].nLt); break; + default: sqlite3_result_int64(context, p->a[n].nDLt); break; + } +} +static const FuncDef stat3GetFuncdef = { + -1, /* nArg */ + SQLITE_UTF8, /* iPrefEnc */ + 0, /* flags */ + 0, /* pUserData */ + 0, /* pNext */ + stat3Get, /* xFunc */ + 0, /* xStep */ + 0, /* xFinalize */ + "stat3_get", /* zName */ + 0, /* pHash */ + 0 /* pDestructor */ +}; +#endif /* SQLITE_ENABLE_STAT3 */ + + + + +/* +** Generate code to do an analysis of all indices associated with +** a single table. +*/ +static void analyzeOneTable( + Parse *pParse, /* Parser context */ + Table *pTab, /* Table whose indices are to be analyzed */ + Index *pOnlyIdx, /* If not NULL, only analyze this one index */ + int iStatCur, /* Index of VdbeCursor that writes the sqlite_stat1 table */ + int iMem /* Available memory locations begin here */ +){ + sqlite3 *db = pParse->db; /* Database handle */ + Index *pIdx; /* An index to being analyzed */ + int iIdxCur; /* Cursor open on index being analyzed */ + Vdbe *v; /* The virtual machine being built up */ + int i; /* Loop counter */ + int topOfLoop; /* The top of the loop */ + int endOfLoop; /* The end of the loop */ + int jZeroRows = -1; /* Jump from here if number of rows is zero */ + int iDb; /* Index of database containing pTab */ + int regTabname = iMem++; /* Register containing table name */ + int regIdxname = iMem++; /* Register containing index name */ + int regStat1 = iMem++; /* The stat column of sqlite_stat1 */ +#ifdef SQLITE_ENABLE_STAT3 + int regNumEq = regStat1; /* Number of instances. Same as regStat1 */ + int regNumLt = iMem++; /* Number of keys less than regSample */ + int regNumDLt = iMem++; /* Number of distinct keys less than regSample */ + int regSample = iMem++; /* The next sample value */ + int regRowid = regSample; /* Rowid of a sample */ + int regAccum = iMem++; /* Register to hold Stat3Accum object */ + int regLoop = iMem++; /* Loop counter */ + int regCount = iMem++; /* Number of rows in the table or index */ + int regTemp1 = iMem++; /* Intermediate register */ + int regTemp2 = iMem++; /* Intermediate register */ + int once = 1; /* One-time initialization */ + int shortJump = 0; /* Instruction address */ + int iTabCur = pParse->nTab++; /* Table cursor */ +#endif + int regCol = iMem++; /* Content of a column in analyzed table */ + int regRec = iMem++; /* Register holding completed record */ + int regTemp = iMem++; /* Temporary use register */ + int regNewRowid = iMem++; /* Rowid for the inserted record */ + + + v = sqlite3GetVdbe(pParse); + if( v==0 || NEVER(pTab==0) ){ + return; + } + if( pTab->tnum==0 ){ + /* Do not gather statistics on views or virtual tables */ + return; + } + if( memcmp(pTab->zName, "sqlite_", 7)==0 ){ + /* Do not gather statistics on system tables */ + return; + } + assert( sqlite3BtreeHoldsAllMutexes(db) ); + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iDb>=0 ); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); +#ifndef SQLITE_OMIT_AUTHORIZATION + if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0, + db->aDb[iDb].zName ) ){ + return; + } +#endif + + /* Establish a read-lock on the table at the shared-cache level. */ + sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); + + iIdxCur = pParse->nTab++; + sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0); + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + int nCol; + KeyInfo *pKey; + int addrIfNot = 0; /* address of OP_IfNot */ + int *aChngAddr; /* Array of jump instruction addresses */ + + if( pOnlyIdx && pOnlyIdx!=pIdx ) continue; + VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName)); + nCol = pIdx->nColumn; + aChngAddr = sqlite3DbMallocRaw(db, sizeof(int)*nCol); + if( aChngAddr==0 ) continue; + pKey = sqlite3IndexKeyinfo(pParse, pIdx); + if( iMem+1+(nCol*2)>pParse->nMem ){ + pParse->nMem = iMem+1+(nCol*2); + } + + /* Open a cursor to the index to be analyzed. */ + assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) ); + sqlite3VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb, + (char *)pKey, P4_KEYINFO_HANDOFF); + VdbeComment((v, "%s", pIdx->zName)); + + /* Populate the register containing the index name. */ + sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, pIdx->zName, 0); + +#ifdef SQLITE_ENABLE_STAT3 + if( once ){ + once = 0; + sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); + } + sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regCount); + sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_STAT3_SAMPLES, regTemp1); + sqlite3VdbeAddOp2(v, OP_Integer, 0, regNumEq); + sqlite3VdbeAddOp2(v, OP_Integer, 0, regNumLt); + sqlite3VdbeAddOp2(v, OP_Integer, -1, regNumDLt); + sqlite3VdbeAddOp3(v, OP_Null, 0, regSample, regAccum); + sqlite3VdbeAddOp4(v, OP_Function, 1, regCount, regAccum, + (char*)&stat3InitFuncdef, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, 2); +#endif /* SQLITE_ENABLE_STAT3 */ + + /* The block of memory cells initialized here is used as follows. + ** + ** iMem: + ** The total number of rows in the table. + ** + ** iMem+1 .. iMem+nCol: + ** Number of distinct entries in index considering the + ** left-most N columns only, where N is between 1 and nCol, + ** inclusive. + ** + ** iMem+nCol+1 .. Mem+2*nCol: + ** Previous value of indexed columns, from left to right. + ** + ** Cells iMem through iMem+nCol are initialized to 0. The others are + ** initialized to contain an SQL NULL. + */ + for(i=0; i<=nCol; i++){ + sqlite3VdbeAddOp2(v, OP_Integer, 0, iMem+i); + } + for(i=0; iazColl!=0 ); + assert( pIdx->azColl[i]!=0 ); + pColl = sqlite3LocateCollSeq(pParse, pIdx->azColl[i]); + aChngAddr[i] = sqlite3VdbeAddOp4(v, OP_Ne, regCol, 0, iMem+nCol+i+1, + (char*)pColl, P4_COLLSEQ); + sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); + VdbeComment((v, "jump if column %d changed", i)); +#ifdef SQLITE_ENABLE_STAT3 + if( i==0 ){ + sqlite3VdbeAddOp2(v, OP_AddImm, regNumEq, 1); + VdbeComment((v, "incr repeat count")); + } +#endif + } + sqlite3VdbeAddOp2(v, OP_Goto, 0, endOfLoop); + for(i=0; inColumn, regRowid); + sqlite3VdbeAddOp3(v, OP_Add, regNumEq, regNumLt, regNumLt); + sqlite3VdbeAddOp2(v, OP_AddImm, regNumDLt, 1); + sqlite3VdbeAddOp2(v, OP_Integer, 1, regNumEq); +#endif + } + sqlite3VdbeAddOp2(v, OP_AddImm, iMem+i+1, 1); + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, iMem+nCol+i+1); + } + sqlite3DbFree(db, aChngAddr); + + /* Always jump here after updating the iMem+1...iMem+1+nCol counters */ + sqlite3VdbeResolveLabel(v, endOfLoop); + + sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, topOfLoop); + sqlite3VdbeAddOp1(v, OP_Close, iIdxCur); +#ifdef SQLITE_ENABLE_STAT3 + sqlite3VdbeAddOp4(v, OP_Function, 1, regNumEq, regTemp2, + (char*)&stat3PushFuncdef, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, 5); + sqlite3VdbeAddOp2(v, OP_Integer, -1, regLoop); + shortJump = + sqlite3VdbeAddOp2(v, OP_AddImm, regLoop, 1); + sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regTemp1, + (char*)&stat3GetFuncdef, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, 2); + sqlite3VdbeAddOp1(v, OP_IsNull, regTemp1); + sqlite3VdbeAddOp3(v, OP_NotExists, iTabCur, shortJump, regTemp1); + sqlite3VdbeAddOp3(v, OP_Column, iTabCur, pIdx->aiColumn[0], regSample); + sqlite3ColumnDefault(v, pTab, pIdx->aiColumn[0], regSample); + sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regNumEq, + (char*)&stat3GetFuncdef, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, 3); + sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regNumLt, + (char*)&stat3GetFuncdef, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, 4); + sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regNumDLt, + (char*)&stat3GetFuncdef, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, 5); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 6, regRec, "bbbbbb", 0); + sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid); + sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regRec, regNewRowid); + sqlite3VdbeAddOp2(v, OP_Goto, 0, shortJump); + sqlite3VdbeJumpHere(v, shortJump+2); +#endif + + /* Store the results in sqlite_stat1. + ** + ** The result is a single row of the sqlite_stat1 table. The first + ** two columns are the names of the table and index. The third column + ** is a string composed of a list of integer statistics about the + ** index. The first integer in the list is the total number of entries + ** in the index. There is one additional integer in the list for each + ** column of the table. This additional integer is a guess of how many + ** rows of the table the index will select. If D is the count of distinct + ** values and K is the total number of rows, then the integer is computed + ** as: + ** + ** I = (K+D-1)/D + ** + ** If K==0 then no entry is made into the sqlite_stat1 table. + ** If K>0 then it is always the case the D>0 so division by zero + ** is never possible. + */ + sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regStat1); + if( jZeroRows<0 ){ + jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, iMem); + } + for(i=0; ipIndex==0 ){ + sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pTab->tnum, iDb); + VdbeComment((v, "%s", pTab->zName)); + sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat1); + sqlite3VdbeAddOp1(v, OP_Close, iIdxCur); + jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1); + }else{ + sqlite3VdbeJumpHere(v, jZeroRows); + jZeroRows = sqlite3VdbeAddOp0(v, OP_Goto); + } + sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0); + sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); + sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); + if( pParse->nMemnMem = regRec; + sqlite3VdbeJumpHere(v, jZeroRows); +} + + +/* +** Generate code that will cause the most recent index analysis to +** be loaded into internal hash tables where is can be used. +*/ +static void loadAnalysis(Parse *pParse, int iDb){ + Vdbe *v = sqlite3GetVdbe(pParse); + if( v ){ + sqlite3VdbeAddOp1(v, OP_LoadAnalysis, iDb); + } +} + +/* +** Generate code that will do an analysis of an entire database +*/ +static void analyzeDatabase(Parse *pParse, int iDb){ + sqlite3 *db = pParse->db; + Schema *pSchema = db->aDb[iDb].pSchema; /* Schema of database iDb */ + HashElem *k; + int iStatCur; + int iMem; + + sqlite3BeginWriteOperation(pParse, 0, iDb); + iStatCur = pParse->nTab; + pParse->nTab += 3; + openStatTable(pParse, iDb, iStatCur, 0, 0); + iMem = pParse->nMem+1; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ + Table *pTab = (Table*)sqliteHashData(k); + analyzeOneTable(pParse, pTab, 0, iStatCur, iMem); + } + loadAnalysis(pParse, iDb); +} + +/* +** Generate code that will do an analysis of a single table in +** a database. If pOnlyIdx is not NULL then it is a single index +** in pTab that should be analyzed. +*/ +static void analyzeTable(Parse *pParse, Table *pTab, Index *pOnlyIdx){ + int iDb; + int iStatCur; + + assert( pTab!=0 ); + assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); + iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + sqlite3BeginWriteOperation(pParse, 0, iDb); + iStatCur = pParse->nTab; + pParse->nTab += 3; + if( pOnlyIdx ){ + openStatTable(pParse, iDb, iStatCur, pOnlyIdx->zName, "idx"); + }else{ + openStatTable(pParse, iDb, iStatCur, pTab->zName, "tbl"); + } + analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur, pParse->nMem+1); + loadAnalysis(pParse, iDb); +} + +/* +** Generate code for the ANALYZE command. The parser calls this routine +** when it recognizes an ANALYZE command. +** +** ANALYZE -- 1 +** ANALYZE -- 2 +** ANALYZE ?.? -- 3 +** +** Form 1 causes all indices in all attached databases to be analyzed. +** Form 2 analyzes all indices the single database named. +** Form 3 analyzes all indices associated with the named table. +*/ +void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){ + sqlite3 *db = pParse->db; + int iDb; + int i; + char *z, *zDb; + Table *pTab; + Index *pIdx; + Token *pTableName; + + /* Read the database schema. If an error occurs, leave an error message + ** and code in pParse and return NULL. */ + assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + return; + } + + assert( pName2!=0 || pName1==0 ); + if( pName1==0 ){ + /* Form 1: Analyze everything */ + for(i=0; inDb; i++){ + if( i==1 ) continue; /* Do not analyze the TEMP database */ + analyzeDatabase(pParse, i); + } + }else if( pName2->n==0 ){ + /* Form 2: Analyze the database or table named */ + iDb = sqlite3FindDb(db, pName1); + if( iDb>=0 ){ + analyzeDatabase(pParse, iDb); + }else{ + z = sqlite3NameFromToken(db, pName1); + if( z ){ + if( (pIdx = sqlite3FindIndex(db, z, 0))!=0 ){ + analyzeTable(pParse, pIdx->pTable, pIdx); + }else if( (pTab = sqlite3LocateTable(pParse, 0, z, 0))!=0 ){ + analyzeTable(pParse, pTab, 0); + } + sqlite3DbFree(db, z); + } + } + }else{ + /* Form 3: Analyze the fully qualified table name */ + iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName); + if( iDb>=0 ){ + zDb = db->aDb[iDb].zName; + z = sqlite3NameFromToken(db, pTableName); + if( z ){ + if( (pIdx = sqlite3FindIndex(db, z, zDb))!=0 ){ + analyzeTable(pParse, pIdx->pTable, pIdx); + }else if( (pTab = sqlite3LocateTable(pParse, 0, z, zDb))!=0 ){ + analyzeTable(pParse, pTab, 0); + } + sqlite3DbFree(db, z); + } + } + } +} + +/* +** Used to pass information from the analyzer reader through to the +** callback routine. +*/ +typedef struct analysisInfo analysisInfo; +struct analysisInfo { + sqlite3 *db; + const char *zDatabase; +}; + +/* +** This callback is invoked once for each index when reading the +** sqlite_stat1 table. +** +** argv[0] = name of the table +** argv[1] = name of the index (might be NULL) +** argv[2] = results of analysis - on integer for each column +** +** Entries for which argv[1]==NULL simply record the number of rows in +** the table. +*/ +static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){ + analysisInfo *pInfo = (analysisInfo*)pData; + Index *pIndex; + Table *pTable; + int i, c, n; + tRowcnt v; + const char *z; + + assert( argc==3 ); + UNUSED_PARAMETER2(NotUsed, argc); + + if( argv==0 || argv[0]==0 || argv[2]==0 ){ + return 0; + } + pTable = sqlite3FindTable(pInfo->db, argv[0], pInfo->zDatabase); + if( pTable==0 ){ + return 0; + } + if( argv[1] ){ + pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); + }else{ + pIndex = 0; + } + n = pIndex ? pIndex->nColumn : 0; + z = argv[2]; + for(i=0; *z && i<=n; i++){ + v = 0; + while( (c=z[0])>='0' && c<='9' ){ + v = v*10 + c - '0'; + z++; + } + if( i==0 ) pTable->nRowEst = v; + if( pIndex==0 ) break; + pIndex->aiRowEst[i] = v; + if( *z==' ' ) z++; + if( memcmp(z, "unordered", 10)==0 ){ + pIndex->bUnordered = 1; + break; + } + } + return 0; +} + +/* +** If the Index.aSample variable is not NULL, delete the aSample[] array +** and its contents. +*/ +void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){ +#ifdef SQLITE_ENABLE_STAT3 + if( pIdx->aSample ){ + int j; + for(j=0; jnSample; j++){ + IndexSample *p = &pIdx->aSample[j]; + if( p->eType==SQLITE_TEXT || p->eType==SQLITE_BLOB ){ + sqlite3DbFree(db, p->u.z); + } + } + sqlite3DbFree(db, pIdx->aSample); + } + if( db && db->pnBytesFreed==0 ){ + pIdx->nSample = 0; + pIdx->aSample = 0; + } +#else + UNUSED_PARAMETER(db); + UNUSED_PARAMETER(pIdx); +#endif +} + +#ifdef SQLITE_ENABLE_STAT3 +/* +** Load content from the sqlite_stat3 table into the Index.aSample[] +** arrays of all indices. +*/ +static int loadStat3(sqlite3 *db, const char *zDb){ + int rc; /* Result codes from subroutines */ + sqlite3_stmt *pStmt = 0; /* An SQL statement being run */ + char *zSql; /* Text of the SQL statement */ + Index *pPrevIdx = 0; /* Previous index in the loop */ + int idx = 0; /* slot in pIdx->aSample[] for next sample */ + int eType; /* Datatype of a sample */ + IndexSample *pSample; /* A slot in pIdx->aSample[] */ + + if( !sqlite3FindTable(db, "sqlite_stat3", zDb) ){ + return SQLITE_OK; + } + + zSql = sqlite3MPrintf(db, + "SELECT idx,count(*) FROM %Q.sqlite_stat3" + " GROUP BY idx", zDb); + if( !zSql ){ + return SQLITE_NOMEM; + } + rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); + sqlite3DbFree(db, zSql); + if( rc ) return rc; + + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + char *zIndex; /* Index name */ + Index *pIdx; /* Pointer to the index object */ + int nSample; /* Number of samples */ + + zIndex = (char *)sqlite3_column_text(pStmt, 0); + if( zIndex==0 ) continue; + nSample = sqlite3_column_int(pStmt, 1); + pIdx = sqlite3FindIndex(db, zIndex, zDb); + if( pIdx==0 ) continue; + assert( pIdx->nSample==0 ); + pIdx->nSample = nSample; + pIdx->aSample = sqlite3MallocZero( nSample*sizeof(IndexSample) ); + pIdx->avgEq = pIdx->aiRowEst[1]; + if( pIdx->aSample==0 ){ + db->mallocFailed = 1; + sqlite3_finalize(pStmt); + return SQLITE_NOMEM; + } + } + rc = sqlite3_finalize(pStmt); + if( rc ) return rc; + + zSql = sqlite3MPrintf(db, + "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat3", zDb); + if( !zSql ){ + return SQLITE_NOMEM; + } + rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); + sqlite3DbFree(db, zSql); + if( rc ) return rc; + + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + char *zIndex; /* Index name */ + Index *pIdx; /* Pointer to the index object */ + int i; /* Loop counter */ + tRowcnt sumEq; /* Sum of the nEq values */ + + zIndex = (char *)sqlite3_column_text(pStmt, 0); + if( zIndex==0 ) continue; + pIdx = sqlite3FindIndex(db, zIndex, zDb); + if( pIdx==0 ) continue; + if( pIdx==pPrevIdx ){ + idx++; + }else{ + pPrevIdx = pIdx; + idx = 0; + } + assert( idxnSample ); + pSample = &pIdx->aSample[idx]; + pSample->nEq = (tRowcnt)sqlite3_column_int64(pStmt, 1); + pSample->nLt = (tRowcnt)sqlite3_column_int64(pStmt, 2); + pSample->nDLt = (tRowcnt)sqlite3_column_int64(pStmt, 3); + if( idx==pIdx->nSample-1 ){ + if( pSample->nDLt>0 ){ + for(i=0, sumEq=0; i<=idx-1; i++) sumEq += pIdx->aSample[i].nEq; + pIdx->avgEq = (pSample->nLt - sumEq)/pSample->nDLt; + } + if( pIdx->avgEq<=0 ) pIdx->avgEq = 1; + } + eType = sqlite3_column_type(pStmt, 4); + pSample->eType = (u8)eType; + switch( eType ){ + case SQLITE_INTEGER: { + pSample->u.i = sqlite3_column_int64(pStmt, 4); + break; + } + case SQLITE_FLOAT: { + pSample->u.r = sqlite3_column_double(pStmt, 4); + break; + } + case SQLITE_NULL: { + break; + } + default: assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); { + const char *z = (const char *)( + (eType==SQLITE_BLOB) ? + sqlite3_column_blob(pStmt, 4): + sqlite3_column_text(pStmt, 4) + ); + int n = z ? sqlite3_column_bytes(pStmt, 4) : 0; + pSample->nByte = n; + if( n < 1){ + pSample->u.z = 0; + }else{ + pSample->u.z = sqlite3Malloc(n); + if( pSample->u.z==0 ){ + db->mallocFailed = 1; + sqlite3_finalize(pStmt); + return SQLITE_NOMEM; + } + memcpy(pSample->u.z, z, n); + } + } + } + } + return sqlite3_finalize(pStmt); +} +#endif /* SQLITE_ENABLE_STAT3 */ + +/* +** Load the content of the sqlite_stat1 and sqlite_stat3 tables. The +** contents of sqlite_stat1 are used to populate the Index.aiRowEst[] +** arrays. The contents of sqlite_stat3 are used to populate the +** Index.aSample[] arrays. +** +** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR +** is returned. In this case, even if SQLITE_ENABLE_STAT3 was defined +** during compilation and the sqlite_stat3 table is present, no data is +** read from it. +** +** If SQLITE_ENABLE_STAT3 was defined during compilation and the +** sqlite_stat3 table is not present in the database, SQLITE_ERROR is +** returned. However, in this case, data is read from the sqlite_stat1 +** table (if it is present) before returning. +** +** If an OOM error occurs, this function always sets db->mallocFailed. +** This means if the caller does not care about other errors, the return +** code may be ignored. +*/ +int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ + analysisInfo sInfo; + HashElem *i; + char *zSql; + int rc; + + assert( iDb>=0 && iDbnDb ); + assert( db->aDb[iDb].pBt!=0 ); + + /* Clear any prior statistics */ + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ + Index *pIdx = sqliteHashData(i); + sqlite3DefaultRowEst(pIdx); +#ifdef SQLITE_ENABLE_STAT3 + sqlite3DeleteIndexSamples(db, pIdx); + pIdx->aSample = 0; +#endif + } + + /* Check to make sure the sqlite_stat1 table exists */ + sInfo.db = db; + sInfo.zDatabase = db->aDb[iDb].zName; + if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)==0 ){ + return SQLITE_ERROR; + } + + /* Load new statistics out of the sqlite_stat1 table */ + zSql = sqlite3MPrintf(db, + "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase); + if( zSql==0 ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); + sqlite3DbFree(db, zSql); + } + + + /* Load the statistics from the sqlite_stat3 table. */ +#ifdef SQLITE_ENABLE_STAT3 + if( rc==SQLITE_OK ){ + rc = loadStat3(db, sInfo.zDatabase); + } +#endif + + if( rc==SQLITE_NOMEM ){ + db->mallocFailed = 1; + } + return rc; +} + + +#endif /* SQLITE_OMIT_ANALYZE */ diff --git a/scalos/libraries/sqlite/src/attach.c b/scalos/libraries/sqlite/src/attach.c new file mode 100644 index 000000000..18f8823b3 --- /dev/null +++ b/scalos/libraries/sqlite/src/attach.c @@ -0,0 +1,557 @@ +/* +** 2003 April 6 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code used to implement the ATTACH and DETACH commands. +*/ +#include "sqliteInt.h" + +#ifndef SQLITE_OMIT_ATTACH +/* +** Resolve an expression that was part of an ATTACH or DETACH statement. This +** is slightly different from resolving a normal SQL expression, because simple +** identifiers are treated as strings, not possible column names or aliases. +** +** i.e. if the parser sees: +** +** ATTACH DATABASE abc AS def +** +** it treats the two expressions as literal strings 'abc' and 'def' instead of +** looking for columns of the same name. +** +** This only applies to the root node of pExpr, so the statement: +** +** ATTACH DATABASE abc||def AS 'db2' +** +** will fail because neither abc or def can be resolved. +*/ +static int resolveAttachExpr(NameContext *pName, Expr *pExpr) +{ + int rc = SQLITE_OK; + if( pExpr ){ + if( pExpr->op!=TK_ID ){ + rc = sqlite3ResolveExprNames(pName, pExpr); + if( rc==SQLITE_OK && !sqlite3ExprIsConstant(pExpr) ){ + sqlite3ErrorMsg(pName->pParse, "invalid name: \"%s\"", pExpr->u.zToken); + return SQLITE_ERROR; + } + }else{ + pExpr->op = TK_STRING; + } + } + return rc; +} + +/* +** An SQL user-function registered to do the work of an ATTACH statement. The +** three arguments to the function come directly from an attach statement: +** +** ATTACH DATABASE x AS y KEY z +** +** SELECT sqlite_attach(x, y, z) +** +** If the optional "KEY z" syntax is omitted, an SQL NULL is passed as the +** third argument. +*/ +static void attachFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + int i; + int rc = 0; + sqlite3 *db = sqlite3_context_db_handle(context); + const char *zName; + const char *zFile; + char *zPath = 0; + char *zErr = 0; + unsigned int flags; + Db *aNew; + char *zErrDyn = 0; + sqlite3_vfs *pVfs; + + UNUSED_PARAMETER(NotUsed); + + zFile = (const char *)sqlite3_value_text(argv[0]); + zName = (const char *)sqlite3_value_text(argv[1]); + if( zFile==0 ) zFile = ""; + if( zName==0 ) zName = ""; + + /* Check for the following errors: + ** + ** * Too many attached databases, + ** * Transaction currently open + ** * Specified database name already being used. + */ + if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){ + zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d", + db->aLimit[SQLITE_LIMIT_ATTACHED] + ); + goto attach_error; + } + if( !db->autoCommit ){ + zErrDyn = sqlite3MPrintf(db, "cannot ATTACH database within transaction"); + goto attach_error; + } + for(i=0; inDb; i++){ + char *z = db->aDb[i].zName; + assert( z && zName ); + if( sqlite3StrICmp(z, zName)==0 ){ + zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName); + goto attach_error; + } + } + + /* Allocate the new entry in the db->aDb[] array and initialise the schema + ** hash tables. + */ + if( db->aDb==db->aDbStatic ){ + aNew = sqlite3DbMallocRaw(db, sizeof(db->aDb[0])*3 ); + if( aNew==0 ) return; + memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); + }else{ + aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) ); + if( aNew==0 ) return; + } + db->aDb = aNew; + aNew = &db->aDb[db->nDb]; + memset(aNew, 0, sizeof(*aNew)); + + /* Open the database file. If the btree is successfully opened, use + ** it to obtain the database schema. At this point the schema may + ** or may not be initialised. + */ + flags = db->openFlags; + rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; + sqlite3_result_error(context, zErr, -1); + sqlite3_free(zErr); + return; + } + assert( pVfs ); + flags |= SQLITE_OPEN_MAIN_DB; + rc = sqlite3BtreeOpen(pVfs, zPath, db, &aNew->pBt, 0, flags); + sqlite3_free( zPath ); + db->nDb++; + if( rc==SQLITE_CONSTRAINT ){ + rc = SQLITE_ERROR; + zErrDyn = sqlite3MPrintf(db, "database is already attached"); + }else if( rc==SQLITE_OK ){ + Pager *pPager; + aNew->pSchema = sqlite3SchemaGet(db, aNew->pBt); + if( !aNew->pSchema ){ + rc = SQLITE_NOMEM; + }else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){ + zErrDyn = sqlite3MPrintf(db, + "attached databases must use the same text encoding as main database"); + rc = SQLITE_ERROR; + } + pPager = sqlite3BtreePager(aNew->pBt); + sqlite3PagerLockingMode(pPager, db->dfltLockMode); + sqlite3BtreeSecureDelete(aNew->pBt, + sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) ); + } + aNew->safety_level = 3; + aNew->zName = sqlite3DbStrDup(db, zName); + if( rc==SQLITE_OK && aNew->zName==0 ){ + rc = SQLITE_NOMEM; + } + + +#ifdef SQLITE_HAS_CODEC + if( rc==SQLITE_OK ){ + extern int sqlite3CodecAttach(sqlite3*, int, const void*, int); + extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*); + int nKey; + char *zKey; + int t = sqlite3_value_type(argv[2]); + switch( t ){ + case SQLITE_INTEGER: + case SQLITE_FLOAT: + zErrDyn = sqlite3DbStrDup(db, "Invalid key value"); + rc = SQLITE_ERROR; + break; + + case SQLITE_TEXT: + case SQLITE_BLOB: + nKey = sqlite3_value_bytes(argv[2]); + zKey = (char *)sqlite3_value_blob(argv[2]); + rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); + break; + + case SQLITE_NULL: + /* No key specified. Use the key from the main database */ + sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey); + if( nKey>0 || sqlite3BtreeGetReserve(db->aDb[0].pBt)>0 ){ + rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); + } + break; + } + } +#endif + + /* If the file was opened successfully, read the schema for the new database. + ** If this fails, or if opening the file failed, then close the file and + ** remove the entry from the db->aDb[] array. i.e. put everything back the way + ** we found it. + */ + if( rc==SQLITE_OK ){ + sqlite3BtreeEnterAll(db); + rc = sqlite3Init(db, &zErrDyn); + sqlite3BtreeLeaveAll(db); + } + if( rc ){ + int iDb = db->nDb - 1; + assert( iDb>=2 ); + if( db->aDb[iDb].pBt ){ + sqlite3BtreeClose(db->aDb[iDb].pBt); + db->aDb[iDb].pBt = 0; + db->aDb[iDb].pSchema = 0; + } + sqlite3ResetInternalSchema(db, -1); + db->nDb = iDb; + if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ + db->mallocFailed = 1; + sqlite3DbFree(db, zErrDyn); + zErrDyn = sqlite3MPrintf(db, "out of memory"); + }else if( zErrDyn==0 ){ + zErrDyn = sqlite3MPrintf(db, "unable to open database: %s", zFile); + } + goto attach_error; + } + + return; + +attach_error: + /* Return an error if we get here */ + if( zErrDyn ){ + sqlite3_result_error(context, zErrDyn, -1); + sqlite3DbFree(db, zErrDyn); + } + if( rc ) sqlite3_result_error_code(context, rc); +} + +/* +** An SQL user-function registered to do the work of an DETACH statement. The +** three arguments to the function come directly from a detach statement: +** +** DETACH DATABASE x +** +** SELECT sqlite_detach(x) +*/ +static void detachFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + const char *zName = (const char *)sqlite3_value_text(argv[0]); + sqlite3 *db = sqlite3_context_db_handle(context); + int i; + Db *pDb = 0; + char zErr[128]; + + UNUSED_PARAMETER(NotUsed); + + if( zName==0 ) zName = ""; + for(i=0; inDb; i++){ + pDb = &db->aDb[i]; + if( pDb->pBt==0 ) continue; + if( sqlite3StrICmp(pDb->zName, zName)==0 ) break; + } + + if( i>=db->nDb ){ + sqlite3_snprintf(sizeof(zErr),zErr, "no such database: %s", zName); + goto detach_error; + } + if( i<2 ){ + sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName); + goto detach_error; + } + if( !db->autoCommit ){ + sqlite3_snprintf(sizeof(zErr), zErr, + "cannot DETACH database within transaction"); + goto detach_error; + } + if( sqlite3BtreeIsInReadTrans(pDb->pBt) || sqlite3BtreeIsInBackup(pDb->pBt) ){ + sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName); + goto detach_error; + } + + sqlite3BtreeClose(pDb->pBt); + pDb->pBt = 0; + pDb->pSchema = 0; + sqlite3ResetInternalSchema(db, -1); + return; + +detach_error: + sqlite3_result_error(context, zErr, -1); +} + +/* +** This procedure generates VDBE code for a single invocation of either the +** sqlite_detach() or sqlite_attach() SQL user functions. +*/ +static void codeAttach( + Parse *pParse, /* The parser context */ + int type, /* Either SQLITE_ATTACH or SQLITE_DETACH */ + FuncDef const *pFunc,/* FuncDef wrapper for detachFunc() or attachFunc() */ + Expr *pAuthArg, /* Expression to pass to authorization callback */ + Expr *pFilename, /* Name of database file */ + Expr *pDbname, /* Name of the database to use internally */ + Expr *pKey /* Database key for encryption extension */ +){ + int rc; + NameContext sName; + Vdbe *v; + sqlite3* db = pParse->db; + int regArgs; + + memset(&sName, 0, sizeof(NameContext)); + sName.pParse = pParse; + + if( + SQLITE_OK!=(rc = resolveAttachExpr(&sName, pFilename)) || + SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) || + SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey)) + ){ + pParse->nErr++; + goto attach_end; + } + +#ifndef SQLITE_OMIT_AUTHORIZATION + if( pAuthArg ){ + char *zAuthArg; + if( pAuthArg->op==TK_STRING ){ + zAuthArg = pAuthArg->u.zToken; + }else{ + zAuthArg = 0; + } + rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0); + if(rc!=SQLITE_OK ){ + goto attach_end; + } + } +#endif /* SQLITE_OMIT_AUTHORIZATION */ + + + v = sqlite3GetVdbe(pParse); + regArgs = sqlite3GetTempRange(pParse, 4); + sqlite3ExprCode(pParse, pFilename, regArgs); + sqlite3ExprCode(pParse, pDbname, regArgs+1); + sqlite3ExprCode(pParse, pKey, regArgs+2); + + assert( v || db->mallocFailed ); + if( v ){ + sqlite3VdbeAddOp3(v, OP_Function, 0, regArgs+3-pFunc->nArg, regArgs+3); + assert( pFunc->nArg==-1 || (pFunc->nArg&0xff)==pFunc->nArg ); + sqlite3VdbeChangeP5(v, (u8)(pFunc->nArg)); + sqlite3VdbeChangeP4(v, -1, (char *)pFunc, P4_FUNCDEF); + + /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this + ** statement only). For DETACH, set it to false (expire all existing + ** statements). + */ + sqlite3VdbeAddOp1(v, OP_Expire, (type==SQLITE_ATTACH)); + } + +attach_end: + sqlite3ExprDelete(db, pFilename); + sqlite3ExprDelete(db, pDbname); + sqlite3ExprDelete(db, pKey); +} + +/* +** Called by the parser to compile a DETACH statement. +** +** DETACH pDbname +*/ +void sqlite3Detach(Parse *pParse, Expr *pDbname){ + static const FuncDef detach_func = { + 1, /* nArg */ + SQLITE_UTF8, /* iPrefEnc */ + 0, /* flags */ + 0, /* pUserData */ + 0, /* pNext */ + detachFunc, /* xFunc */ + 0, /* xStep */ + 0, /* xFinalize */ + "sqlite_detach", /* zName */ + 0, /* pHash */ + 0 /* pDestructor */ + }; + codeAttach(pParse, SQLITE_DETACH, &detach_func, pDbname, 0, 0, pDbname); +} + +/* +** Called by the parser to compile an ATTACH statement. +** +** ATTACH p AS pDbname KEY pKey +*/ +void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){ + static const FuncDef attach_func = { + 3, /* nArg */ + SQLITE_UTF8, /* iPrefEnc */ + 0, /* flags */ + 0, /* pUserData */ + 0, /* pNext */ + attachFunc, /* xFunc */ + 0, /* xStep */ + 0, /* xFinalize */ + "sqlite_attach", /* zName */ + 0, /* pHash */ + 0 /* pDestructor */ + }; + codeAttach(pParse, SQLITE_ATTACH, &attach_func, p, p, pDbname, pKey); +} +#endif /* SQLITE_OMIT_ATTACH */ + +/* +** Initialize a DbFixer structure. This routine must be called prior +** to passing the structure to one of the sqliteFixAAAA() routines below. +** +** The return value indicates whether or not fixation is required. TRUE +** means we do need to fix the database references, FALSE means we do not. +*/ +int sqlite3FixInit( + DbFixer *pFix, /* The fixer to be initialized */ + Parse *pParse, /* Error messages will be written here */ + int iDb, /* This is the database that must be used */ + const char *zType, /* "view", "trigger", or "index" */ + const Token *pName /* Name of the view, trigger, or index */ +){ + sqlite3 *db; + + if( NEVER(iDb<0) || iDb==1 ) return 0; + db = pParse->db; + assert( db->nDb>iDb ); + pFix->pParse = pParse; + pFix->zDb = db->aDb[iDb].zName; + pFix->zType = zType; + pFix->pName = pName; + return 1; +} + +/* +** The following set of routines walk through the parse tree and assign +** a specific database to all table references where the database name +** was left unspecified in the original SQL statement. The pFix structure +** must have been initialized by a prior call to sqlite3FixInit(). +** +** These routines are used to make sure that an index, trigger, or +** view in one database does not refer to objects in a different database. +** (Exception: indices, triggers, and views in the TEMP database are +** allowed to refer to anything.) If a reference is explicitly made +** to an object in a different database, an error message is added to +** pParse->zErrMsg and these routines return non-zero. If everything +** checks out, these routines return 0. +*/ +int sqlite3FixSrcList( + DbFixer *pFix, /* Context of the fixation */ + SrcList *pList /* The Source list to check and modify */ +){ + int i; + const char *zDb; + struct SrcList_item *pItem; + + if( NEVER(pList==0) ) return 0; + zDb = pFix->zDb; + for(i=0, pItem=pList->a; inSrc; i++, pItem++){ + if( pItem->zDatabase==0 ){ + pItem->zDatabase = sqlite3DbStrDup(pFix->pParse->db, zDb); + }else if( sqlite3StrICmp(pItem->zDatabase,zDb)!=0 ){ + sqlite3ErrorMsg(pFix->pParse, + "%s %T cannot reference objects in database %s", + pFix->zType, pFix->pName, pItem->zDatabase); + return 1; + } +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) + if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1; + if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1; +#endif + } + return 0; +} +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) +int sqlite3FixSelect( + DbFixer *pFix, /* Context of the fixation */ + Select *pSelect /* The SELECT statement to be fixed to one database */ +){ + while( pSelect ){ + if( sqlite3FixExprList(pFix, pSelect->pEList) ){ + return 1; + } + if( sqlite3FixSrcList(pFix, pSelect->pSrc) ){ + return 1; + } + if( sqlite3FixExpr(pFix, pSelect->pWhere) ){ + return 1; + } + if( sqlite3FixExpr(pFix, pSelect->pHaving) ){ + return 1; + } + pSelect = pSelect->pPrior; + } + return 0; +} +int sqlite3FixExpr( + DbFixer *pFix, /* Context of the fixation */ + Expr *pExpr /* The expression to be fixed to one database */ +){ + while( pExpr ){ + if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ) break; + if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1; + }else{ + if( sqlite3FixExprList(pFix, pExpr->x.pList) ) return 1; + } + if( sqlite3FixExpr(pFix, pExpr->pRight) ){ + return 1; + } + pExpr = pExpr->pLeft; + } + return 0; +} +int sqlite3FixExprList( + DbFixer *pFix, /* Context of the fixation */ + ExprList *pList /* The expression to be fixed to one database */ +){ + int i; + struct ExprList_item *pItem; + if( pList==0 ) return 0; + for(i=0, pItem=pList->a; inExpr; i++, pItem++){ + if( sqlite3FixExpr(pFix, pItem->pExpr) ){ + return 1; + } + } + return 0; +} +#endif + +#ifndef SQLITE_OMIT_TRIGGER +int sqlite3FixTriggerStep( + DbFixer *pFix, /* Context of the fixation */ + TriggerStep *pStep /* The trigger step be fixed to one database */ +){ + while( pStep ){ + if( sqlite3FixSelect(pFix, pStep->pSelect) ){ + return 1; + } + if( sqlite3FixExpr(pFix, pStep->pWhere) ){ + return 1; + } + if( sqlite3FixExprList(pFix, pStep->pExprList) ){ + return 1; + } + pStep = pStep->pNext; + } + return 0; +} +#endif diff --git a/scalos/libraries/sqlite/src/auth.c b/scalos/libraries/sqlite/src/auth.c new file mode 100644 index 000000000..d38bb836a --- /dev/null +++ b/scalos/libraries/sqlite/src/auth.c @@ -0,0 +1,249 @@ +/* +** 2003 January 11 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code used to implement the sqlite3_set_authorizer() +** API. This facility is an optional feature of the library. Embedded +** systems that do not need this facility may omit it by recompiling +** the library with -DSQLITE_OMIT_AUTHORIZATION=1 +*/ +#include "sqliteInt.h" + +/* +** All of the code in this file may be omitted by defining a single +** macro. +*/ +#ifndef SQLITE_OMIT_AUTHORIZATION + +/* +** Set or clear the access authorization function. +** +** The access authorization function is be called during the compilation +** phase to verify that the user has read and/or write access permission on +** various fields of the database. The first argument to the auth function +** is a copy of the 3rd argument to this routine. The second argument +** to the auth function is one of these constants: +** +** SQLITE_CREATE_INDEX +** SQLITE_CREATE_TABLE +** SQLITE_CREATE_TEMP_INDEX +** SQLITE_CREATE_TEMP_TABLE +** SQLITE_CREATE_TEMP_TRIGGER +** SQLITE_CREATE_TEMP_VIEW +** SQLITE_CREATE_TRIGGER +** SQLITE_CREATE_VIEW +** SQLITE_DELETE +** SQLITE_DROP_INDEX +** SQLITE_DROP_TABLE +** SQLITE_DROP_TEMP_INDEX +** SQLITE_DROP_TEMP_TABLE +** SQLITE_DROP_TEMP_TRIGGER +** SQLITE_DROP_TEMP_VIEW +** SQLITE_DROP_TRIGGER +** SQLITE_DROP_VIEW +** SQLITE_INSERT +** SQLITE_PRAGMA +** SQLITE_READ +** SQLITE_SELECT +** SQLITE_TRANSACTION +** SQLITE_UPDATE +** +** The third and fourth arguments to the auth function are the name of +** the table and the column that are being accessed. The auth function +** should return either SQLITE_OK, SQLITE_DENY, or SQLITE_IGNORE. If +** SQLITE_OK is returned, it means that access is allowed. SQLITE_DENY +** means that the SQL statement will never-run - the sqlite3_exec() call +** will return with an error. SQLITE_IGNORE means that the SQL statement +** should run but attempts to read the specified column will return NULL +** and attempts to write the column will be ignored. +** +** Setting the auth function to NULL disables this hook. The default +** setting of the auth function is NULL. +*/ +int sqlite3_set_authorizer( + sqlite3 *db, + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), + void *pArg +){ + sqlite3_mutex_enter(db->mutex); + db->xAuth = xAuth; + db->pAuthArg = pArg; + sqlite3ExpirePreparedStatements(db); + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + +/* +** Write an error message into pParse->zErrMsg that explains that the +** user-supplied authorization function returned an illegal value. +*/ +static void sqliteAuthBadReturnCode(Parse *pParse){ + sqlite3ErrorMsg(pParse, "authorizer malfunction"); + pParse->rc = SQLITE_ERROR; +} + +/* +** Invoke the authorization callback for permission to read column zCol from +** table zTab in database zDb. This function assumes that an authorization +** callback has been registered (i.e. that sqlite3.xAuth is not NULL). +** +** If SQLITE_IGNORE is returned and pExpr is not NULL, then pExpr is changed +** to an SQL NULL expression. Otherwise, if pExpr is NULL, then SQLITE_IGNORE +** is treated as SQLITE_DENY. In this case an error is left in pParse. +*/ +int sqlite3AuthReadCol( + Parse *pParse, /* The parser context */ + const char *zTab, /* Table name */ + const char *zCol, /* Column name */ + int iDb /* Index of containing database. */ +){ + sqlite3 *db = pParse->db; /* Database handle */ + char *zDb = db->aDb[iDb].zName; /* Name of attached database */ + int rc; /* Auth callback return code */ + + rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext); + if( rc==SQLITE_DENY ){ + if( db->nDb>2 || iDb!=0 ){ + sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited",zDb,zTab,zCol); + }else{ + sqlite3ErrorMsg(pParse, "access to %s.%s is prohibited", zTab, zCol); + } + pParse->rc = SQLITE_AUTH; + }else if( rc!=SQLITE_IGNORE && rc!=SQLITE_OK ){ + sqliteAuthBadReturnCode(pParse); + } + return rc; +} + +/* +** The pExpr should be a TK_COLUMN expression. The table referred to +** is in pTabList or else it is the NEW or OLD table of a trigger. +** Check to see if it is OK to read this particular column. +** +** If the auth function returns SQLITE_IGNORE, change the TK_COLUMN +** instruction into a TK_NULL. If the auth function returns SQLITE_DENY, +** then generate an error. +*/ +void sqlite3AuthRead( + Parse *pParse, /* The parser context */ + Expr *pExpr, /* The expression to check authorization on */ + Schema *pSchema, /* The schema of the expression */ + SrcList *pTabList /* All table that pExpr might refer to */ +){ + sqlite3 *db = pParse->db; + Table *pTab = 0; /* The table being read */ + const char *zCol; /* Name of the column of the table */ + int iSrc; /* Index in pTabList->a[] of table being read */ + int iDb; /* The index of the database the expression refers to */ + int iCol; /* Index of column in table */ + + if( db->xAuth==0 ) return; + iDb = sqlite3SchemaToIndex(pParse->db, pSchema); + if( iDb<0 ){ + /* An attempt to read a column out of a subquery or other + ** temporary table. */ + return; + } + + assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER ); + if( pExpr->op==TK_TRIGGER ){ + pTab = pParse->pTriggerTab; + }else{ + assert( pTabList ); + for(iSrc=0; ALWAYS(iSrcnSrc); iSrc++){ + if( pExpr->iTable==pTabList->a[iSrc].iCursor ){ + pTab = pTabList->a[iSrc].pTab; + break; + } + } + } + iCol = pExpr->iColumn; + if( NEVER(pTab==0) ) return; + + if( iCol>=0 ){ + assert( iColnCol ); + zCol = pTab->aCol[iCol].zName; + }else if( pTab->iPKey>=0 ){ + assert( pTab->iPKeynCol ); + zCol = pTab->aCol[pTab->iPKey].zName; + }else{ + zCol = "ROWID"; + } + assert( iDb>=0 && iDbnDb ); + if( SQLITE_IGNORE==sqlite3AuthReadCol(pParse, pTab->zName, zCol, iDb) ){ + pExpr->op = TK_NULL; + } +} + +/* +** Do an authorization check using the code and arguments given. Return +** either SQLITE_OK (zero) or SQLITE_IGNORE or SQLITE_DENY. If SQLITE_DENY +** is returned, then the error count and error message in pParse are +** modified appropriately. +*/ +int sqlite3AuthCheck( + Parse *pParse, + int code, + const char *zArg1, + const char *zArg2, + const char *zArg3 +){ + sqlite3 *db = pParse->db; + int rc; + + /* Don't do any authorization checks if the database is initialising + ** or if the parser is being invoked from within sqlite3_declare_vtab. + */ + if( db->init.busy || IN_DECLARE_VTAB ){ + return SQLITE_OK; + } + + if( db->xAuth==0 ){ + return SQLITE_OK; + } + rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext); + if( rc==SQLITE_DENY ){ + sqlite3ErrorMsg(pParse, "not authorized"); + pParse->rc = SQLITE_AUTH; + }else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){ + rc = SQLITE_DENY; + sqliteAuthBadReturnCode(pParse); + } + return rc; +} + +/* +** Push an authorization context. After this routine is called, the +** zArg3 argument to authorization callbacks will be zContext until +** popped. Or if pParse==0, this routine is a no-op. +*/ +void sqlite3AuthContextPush( + Parse *pParse, + AuthContext *pContext, + const char *zContext +){ + assert( pParse ); + pContext->pParse = pParse; + pContext->zAuthContext = pParse->zAuthContext; + pParse->zAuthContext = zContext; +} + +/* +** Pop an authorization context that was previously pushed +** by sqlite3AuthContextPush +*/ +void sqlite3AuthContextPop(AuthContext *pContext){ + if( pContext->pParse ){ + pContext->pParse->zAuthContext = pContext->zAuthContext; + pContext->pParse = 0; + } +} + +#endif /* SQLITE_OMIT_AUTHORIZATION */ diff --git a/scalos/libraries/sqlite/src/backup.c b/scalos/libraries/sqlite/src/backup.c new file mode 100644 index 000000000..aa3401897 --- /dev/null +++ b/scalos/libraries/sqlite/src/backup.c @@ -0,0 +1,719 @@ +/* +** 2009 January 28 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains the implementation of the sqlite3_backup_XXX() +** API functions and the related features. +*/ +#include "sqliteInt.h" +#include "btreeInt.h" + +/* Macro to find the minimum of two numeric values. +*/ +#ifndef MIN +# define MIN(x,y) ((x)<(y)?(x):(y)) +#endif + +/* +** Structure allocated for each backup operation. +*/ +struct sqlite3_backup { + sqlite3* pDestDb; /* Destination database handle */ + Btree *pDest; /* Destination b-tree file */ + u32 iDestSchema; /* Original schema cookie in destination */ + int bDestLocked; /* True once a write-transaction is open on pDest */ + + Pgno iNext; /* Page number of the next source page to copy */ + sqlite3* pSrcDb; /* Source database handle */ + Btree *pSrc; /* Source b-tree file */ + + int rc; /* Backup process error code */ + + /* These two variables are set by every call to backup_step(). They are + ** read by calls to backup_remaining() and backup_pagecount(). + */ + Pgno nRemaining; /* Number of pages left to copy */ + Pgno nPagecount; /* Total number of pages to copy */ + + int isAttached; /* True once backup has been registered with pager */ + sqlite3_backup *pNext; /* Next backup associated with source pager */ +}; + +/* +** THREAD SAFETY NOTES: +** +** Once it has been created using backup_init(), a single sqlite3_backup +** structure may be accessed via two groups of thread-safe entry points: +** +** * Via the sqlite3_backup_XXX() API function backup_step() and +** backup_finish(). Both these functions obtain the source database +** handle mutex and the mutex associated with the source BtShared +** structure, in that order. +** +** * Via the BackupUpdate() and BackupRestart() functions, which are +** invoked by the pager layer to report various state changes in +** the page cache associated with the source database. The mutex +** associated with the source database BtShared structure will always +** be held when either of these functions are invoked. +** +** The other sqlite3_backup_XXX() API functions, backup_remaining() and +** backup_pagecount() are not thread-safe functions. If they are called +** while some other thread is calling backup_step() or backup_finish(), +** the values returned may be invalid. There is no way for a call to +** BackupUpdate() or BackupRestart() to interfere with backup_remaining() +** or backup_pagecount(). +** +** Depending on the SQLite configuration, the database handles and/or +** the Btree objects may have their own mutexes that require locking. +** Non-sharable Btrees (in-memory databases for example), do not have +** associated mutexes. +*/ + +/* +** Return a pointer corresponding to database zDb (i.e. "main", "temp") +** in connection handle pDb. If such a database cannot be found, return +** a NULL pointer and write an error message to pErrorDb. +** +** If the "temp" database is requested, it may need to be opened by this +** function. If an error occurs while doing so, return 0 and write an +** error message to pErrorDb. +*/ +static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){ + int i = sqlite3FindDbName(pDb, zDb); + + if( i==1 ){ + Parse *pParse; + int rc = 0; + pParse = sqlite3StackAllocZero(pErrorDb, sizeof(*pParse)); + if( pParse==0 ){ + sqlite3Error(pErrorDb, SQLITE_NOMEM, "out of memory"); + rc = SQLITE_NOMEM; + }else{ + pParse->db = pDb; + if( sqlite3OpenTempDatabase(pParse) ){ + sqlite3Error(pErrorDb, pParse->rc, "%s", pParse->zErrMsg); + rc = SQLITE_ERROR; + } + sqlite3DbFree(pErrorDb, pParse->zErrMsg); + sqlite3StackFree(pErrorDb, pParse); + } + if( rc ){ + return 0; + } + } + + if( i<0 ){ + sqlite3Error(pErrorDb, SQLITE_ERROR, "unknown database %s", zDb); + return 0; + } + + return pDb->aDb[i].pBt; +} + +/* +** Attempt to set the page size of the destination to match the page size +** of the source. +*/ +static int setDestPgsz(sqlite3_backup *p){ + int rc; + rc = sqlite3BtreeSetPageSize(p->pDest,sqlite3BtreeGetPageSize(p->pSrc),-1,0); + return rc; +} + +/* +** Create an sqlite3_backup process to copy the contents of zSrcDb from +** connection handle pSrcDb to zDestDb in pDestDb. If successful, return +** a pointer to the new sqlite3_backup object. +** +** If an error occurs, NULL is returned and an error code and error message +** stored in database handle pDestDb. +*/ +sqlite3_backup *sqlite3_backup_init( + sqlite3* pDestDb, /* Database to write to */ + const char *zDestDb, /* Name of database within pDestDb */ + sqlite3* pSrcDb, /* Database connection to read from */ + const char *zSrcDb /* Name of database within pSrcDb */ +){ + sqlite3_backup *p; /* Value to return */ + + /* Lock the source database handle. The destination database + ** handle is not locked in this routine, but it is locked in + ** sqlite3_backup_step(). The user is required to ensure that no + ** other thread accesses the destination handle for the duration + ** of the backup operation. Any attempt to use the destination + ** database connection while a backup is in progress may cause + ** a malfunction or a deadlock. + */ + sqlite3_mutex_enter(pSrcDb->mutex); + sqlite3_mutex_enter(pDestDb->mutex); + + if( pSrcDb==pDestDb ){ + sqlite3Error( + pDestDb, SQLITE_ERROR, "source and destination must be distinct" + ); + p = 0; + }else { + /* Allocate space for a new sqlite3_backup object... + ** EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a + ** call to sqlite3_backup_init() and is destroyed by a call to + ** sqlite3_backup_finish(). */ + p = (sqlite3_backup *)sqlite3_malloc(sizeof(sqlite3_backup)); + if( !p ){ + sqlite3Error(pDestDb, SQLITE_NOMEM, 0); + } + } + + /* If the allocation succeeded, populate the new object. */ + if( p ){ + memset(p, 0, sizeof(sqlite3_backup)); + p->pSrc = findBtree(pDestDb, pSrcDb, zSrcDb); + p->pDest = findBtree(pDestDb, pDestDb, zDestDb); + p->pDestDb = pDestDb; + p->pSrcDb = pSrcDb; + p->iNext = 1; + p->isAttached = 0; + + if( 0==p->pSrc || 0==p->pDest || setDestPgsz(p)==SQLITE_NOMEM ){ + /* One (or both) of the named databases did not exist or an OOM + ** error was hit. The error has already been written into the + ** pDestDb handle. All that is left to do here is free the + ** sqlite3_backup structure. + */ + sqlite3_free(p); + p = 0; + } + } + if( p ){ + p->pSrc->nBackup++; + } + + sqlite3_mutex_leave(pDestDb->mutex); + sqlite3_mutex_leave(pSrcDb->mutex); + return p; +} + +/* +** Argument rc is an SQLite error code. Return true if this error is +** considered fatal if encountered during a backup operation. All errors +** are considered fatal except for SQLITE_BUSY and SQLITE_LOCKED. +*/ +static int isFatalError(int rc){ + return (rc!=SQLITE_OK && rc!=SQLITE_BUSY && ALWAYS(rc!=SQLITE_LOCKED)); +} + +/* +** Parameter zSrcData points to a buffer containing the data for +** page iSrcPg from the source database. Copy this data into the +** destination database. +*/ +static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){ + Pager * const pDestPager = sqlite3BtreePager(p->pDest); + const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc); + int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest); + const int nCopy = MIN(nSrcPgsz, nDestPgsz); + const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz; +#ifdef SQLITE_HAS_CODEC + int nSrcReserve = sqlite3BtreeGetReserve(p->pSrc); + int nDestReserve = sqlite3BtreeGetReserve(p->pDest); +#endif + + int rc = SQLITE_OK; + i64 iOff; + + assert( p->bDestLocked ); + assert( !isFatalError(p->rc) ); + assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ); + assert( zSrcData ); + + /* Catch the case where the destination is an in-memory database and the + ** page sizes of the source and destination differ. + */ + if( nSrcPgsz!=nDestPgsz && sqlite3PagerIsMemdb(pDestPager) ){ + rc = SQLITE_READONLY; + } + +#ifdef SQLITE_HAS_CODEC + /* Backup is not possible if the page size of the destination is changing + ** and a codec is in use. + */ + if( nSrcPgsz!=nDestPgsz && sqlite3PagerGetCodec(pDestPager)!=0 ){ + rc = SQLITE_READONLY; + } + + /* Backup is not possible if the number of bytes of reserve space differ + ** between source and destination. If there is a difference, try to + ** fix the destination to agree with the source. If that is not possible, + ** then the backup cannot proceed. + */ + if( nSrcReserve!=nDestReserve ){ + u32 newPgsz = nSrcPgsz; + rc = sqlite3PagerSetPagesize(pDestPager, &newPgsz, nSrcReserve); + if( rc==SQLITE_OK && newPgsz!=nSrcPgsz ) rc = SQLITE_READONLY; + } +#endif + + /* This loop runs once for each destination page spanned by the source + ** page. For each iteration, variable iOff is set to the byte offset + ** of the destination page. + */ + for(iOff=iEnd-(i64)nSrcPgsz; rc==SQLITE_OK && iOffpDest->pBt) ) continue; + if( SQLITE_OK==(rc = sqlite3PagerGet(pDestPager, iDest, &pDestPg)) + && SQLITE_OK==(rc = sqlite3PagerWrite(pDestPg)) + ){ + const u8 *zIn = &zSrcData[iOff%nSrcPgsz]; + u8 *zDestData = sqlite3PagerGetData(pDestPg); + u8 *zOut = &zDestData[iOff%nDestPgsz]; + + /* Copy the data from the source page into the destination page. + ** Then clear the Btree layer MemPage.isInit flag. Both this module + ** and the pager code use this trick (clearing the first byte + ** of the page 'extra' space to invalidate the Btree layers + ** cached parse of the page). MemPage.isInit is marked + ** "MUST BE FIRST" for this purpose. + */ + memcpy(zOut, zIn, nCopy); + ((u8 *)sqlite3PagerGetExtra(pDestPg))[0] = 0; + } + sqlite3PagerUnref(pDestPg); + } + + return rc; +} + +/* +** If pFile is currently larger than iSize bytes, then truncate it to +** exactly iSize bytes. If pFile is not larger than iSize bytes, then +** this function is a no-op. +** +** Return SQLITE_OK if everything is successful, or an SQLite error +** code if an error occurs. +*/ +static int backupTruncateFile(sqlite3_file *pFile, i64 iSize){ + i64 iCurrent; + int rc = sqlite3OsFileSize(pFile, &iCurrent); + if( rc==SQLITE_OK && iCurrent>iSize ){ + rc = sqlite3OsTruncate(pFile, iSize); + } + return rc; +} + +/* +** Register this backup object with the associated source pager for +** callbacks when pages are changed or the cache invalidated. +*/ +static void attachBackupObject(sqlite3_backup *p){ + sqlite3_backup **pp; + assert( sqlite3BtreeHoldsMutex(p->pSrc) ); + pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc)); + p->pNext = *pp; + *pp = p; + p->isAttached = 1; +} + +/* +** Copy nPage pages from the source b-tree to the destination. +*/ +int sqlite3_backup_step(sqlite3_backup *p, int nPage){ + int rc; + int destMode; /* Destination journal mode */ + int pgszSrc = 0; /* Source page size */ + int pgszDest = 0; /* Destination page size */ + + sqlite3_mutex_enter(p->pSrcDb->mutex); + sqlite3BtreeEnter(p->pSrc); + if( p->pDestDb ){ + sqlite3_mutex_enter(p->pDestDb->mutex); + } + + rc = p->rc; + if( !isFatalError(rc) ){ + Pager * const pSrcPager = sqlite3BtreePager(p->pSrc); /* Source pager */ + Pager * const pDestPager = sqlite3BtreePager(p->pDest); /* Dest pager */ + int ii; /* Iterator variable */ + int nSrcPage = -1; /* Size of source db in pages */ + int bCloseTrans = 0; /* True if src db requires unlocking */ + + /* If the source pager is currently in a write-transaction, return + ** SQLITE_BUSY immediately. + */ + if( p->pDestDb && p->pSrc->pBt->inTransaction==TRANS_WRITE ){ + rc = SQLITE_BUSY; + }else{ + rc = SQLITE_OK; + } + + /* Lock the destination database, if it is not locked already. */ + if( SQLITE_OK==rc && p->bDestLocked==0 + && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2)) + ){ + p->bDestLocked = 1; + sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema); + } + + /* If there is no open read-transaction on the source database, open + ** one now. If a transaction is opened here, then it will be closed + ** before this function exits. + */ + if( rc==SQLITE_OK && 0==sqlite3BtreeIsInReadTrans(p->pSrc) ){ + rc = sqlite3BtreeBeginTrans(p->pSrc, 0); + bCloseTrans = 1; + } + + /* Do not allow backup if the destination database is in WAL mode + ** and the page sizes are different between source and destination */ + pgszSrc = sqlite3BtreeGetPageSize(p->pSrc); + pgszDest = sqlite3BtreeGetPageSize(p->pDest); + destMode = sqlite3PagerGetJournalMode(sqlite3BtreePager(p->pDest)); + if( SQLITE_OK==rc && destMode==PAGER_JOURNALMODE_WAL && pgszSrc!=pgszDest ){ + rc = SQLITE_READONLY; + } + + /* Now that there is a read-lock on the source database, query the + ** source pager for the number of pages in the database. + */ + nSrcPage = (int)sqlite3BtreeLastPage(p->pSrc); + assert( nSrcPage>=0 ); + for(ii=0; (nPage<0 || iiiNext<=(Pgno)nSrcPage && !rc; ii++){ + const Pgno iSrcPg = p->iNext; /* Source page number */ + if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){ + DbPage *pSrcPg; /* Source page object */ + rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg); + if( rc==SQLITE_OK ){ + rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg)); + sqlite3PagerUnref(pSrcPg); + } + } + p->iNext++; + } + if( rc==SQLITE_OK ){ + p->nPagecount = nSrcPage; + p->nRemaining = nSrcPage+1-p->iNext; + if( p->iNext>(Pgno)nSrcPage ){ + rc = SQLITE_DONE; + }else if( !p->isAttached ){ + attachBackupObject(p); + } + } + + /* Update the schema version field in the destination database. This + ** is to make sure that the schema-version really does change in + ** the case where the source and destination databases have the + ** same schema version. + */ + if( rc==SQLITE_DONE ){ + rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1); + if( rc==SQLITE_OK ){ + if( p->pDestDb ){ + sqlite3ResetInternalSchema(p->pDestDb, -1); + } + if( destMode==PAGER_JOURNALMODE_WAL ){ + rc = sqlite3BtreeSetVersion(p->pDest, 2); + } + } + if( rc==SQLITE_OK ){ + int nDestTruncate; + /* Set nDestTruncate to the final number of pages in the destination + ** database. The complication here is that the destination page + ** size may be different to the source page size. + ** + ** If the source page size is smaller than the destination page size, + ** round up. In this case the call to sqlite3OsTruncate() below will + ** fix the size of the file. However it is important to call + ** sqlite3PagerTruncateImage() here so that any pages in the + ** destination file that lie beyond the nDestTruncate page mark are + ** journalled by PagerCommitPhaseOne() before they are destroyed + ** by the file truncation. + */ + assert( pgszSrc==sqlite3BtreeGetPageSize(p->pSrc) ); + assert( pgszDest==sqlite3BtreeGetPageSize(p->pDest) ); + if( pgszSrcpDest->pBt) ){ + nDestTruncate--; + } + }else{ + nDestTruncate = nSrcPage * (pgszSrc/pgszDest); + } + sqlite3PagerTruncateImage(pDestPager, nDestTruncate); + + if( pgszSrc= iSize || ( + nDestTruncate==(int)(PENDING_BYTE_PAGE(p->pDest->pBt)-1) + && iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+pgszDest + )); + + /* This call ensures that all data required to recreate the original + ** database has been stored in the journal for pDestPager and the + ** journal synced to disk. So at this point we may safely modify + ** the database file in any way, knowing that if a power failure + ** occurs, the original database will be reconstructed from the + ** journal file. */ + rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 1); + + /* Write the extra pages and truncate the database file as required */ + iEnd = MIN(PENDING_BYTE + pgszDest, iSize); + for( + iOff=PENDING_BYTE+pgszSrc; + rc==SQLITE_OK && iOffpDest, 0)) + ){ + rc = SQLITE_DONE; + } + } + } + + /* If bCloseTrans is true, then this function opened a read transaction + ** on the source database. Close the read transaction here. There is + ** no need to check the return values of the btree methods here, as + ** "committing" a read-only transaction cannot fail. + */ + if( bCloseTrans ){ + TESTONLY( int rc2 ); + TESTONLY( rc2 = ) sqlite3BtreeCommitPhaseOne(p->pSrc, 0); + TESTONLY( rc2 |= ) sqlite3BtreeCommitPhaseTwo(p->pSrc, 0); + assert( rc2==SQLITE_OK ); + } + + if( rc==SQLITE_IOERR_NOMEM ){ + rc = SQLITE_NOMEM; + } + p->rc = rc; + } + if( p->pDestDb ){ + sqlite3_mutex_leave(p->pDestDb->mutex); + } + sqlite3BtreeLeave(p->pSrc); + sqlite3_mutex_leave(p->pSrcDb->mutex); + return rc; +} + +/* +** Release all resources associated with an sqlite3_backup* handle. +*/ +int sqlite3_backup_finish(sqlite3_backup *p){ + sqlite3_backup **pp; /* Ptr to head of pagers backup list */ + MUTEX_LOGIC( sqlite3_mutex *mutex; ) /* Mutex to protect source database */ + int rc; /* Value to return */ + + /* Enter the mutexes */ + if( p==0 ) return SQLITE_OK; + sqlite3_mutex_enter(p->pSrcDb->mutex); + sqlite3BtreeEnter(p->pSrc); + MUTEX_LOGIC( mutex = p->pSrcDb->mutex; ) + if( p->pDestDb ){ + sqlite3_mutex_enter(p->pDestDb->mutex); + } + + /* Detach this backup from the source pager. */ + if( p->pDestDb ){ + p->pSrc->nBackup--; + } + if( p->isAttached ){ + pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc)); + while( *pp!=p ){ + pp = &(*pp)->pNext; + } + *pp = p->pNext; + } + + /* If a transaction is still open on the Btree, roll it back. */ + sqlite3BtreeRollback(p->pDest); + + /* Set the error code of the destination database handle. */ + rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc; + sqlite3Error(p->pDestDb, rc, 0); + + /* Exit the mutexes and free the backup context structure. */ + if( p->pDestDb ){ + sqlite3_mutex_leave(p->pDestDb->mutex); + } + sqlite3BtreeLeave(p->pSrc); + if( p->pDestDb ){ + /* EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a + ** call to sqlite3_backup_init() and is destroyed by a call to + ** sqlite3_backup_finish(). */ + sqlite3_free(p); + } + sqlite3_mutex_leave(mutex); + return rc; +} + +/* +** Return the number of pages still to be backed up as of the most recent +** call to sqlite3_backup_step(). +*/ +int sqlite3_backup_remaining(sqlite3_backup *p){ + return p->nRemaining; +} + +/* +** Return the total number of pages in the source database as of the most +** recent call to sqlite3_backup_step(). +*/ +int sqlite3_backup_pagecount(sqlite3_backup *p){ + return p->nPagecount; +} + +/* +** This function is called after the contents of page iPage of the +** source database have been modified. If page iPage has already been +** copied into the destination database, then the data written to the +** destination is now invalidated. The destination copy of iPage needs +** to be updated with the new data before the backup operation is +** complete. +** +** It is assumed that the mutex associated with the BtShared object +** corresponding to the source database is held when this function is +** called. +*/ +void sqlite3BackupUpdate(sqlite3_backup *pBackup, Pgno iPage, const u8 *aData){ + sqlite3_backup *p; /* Iterator variable */ + for(p=pBackup; p; p=p->pNext){ + assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) ); + if( !isFatalError(p->rc) && iPageiNext ){ + /* The backup process p has already copied page iPage. But now it + ** has been modified by a transaction on the source pager. Copy + ** the new data into the backup. + */ + int rc; + assert( p->pDestDb ); + sqlite3_mutex_enter(p->pDestDb->mutex); + rc = backupOnePage(p, iPage, aData); + sqlite3_mutex_leave(p->pDestDb->mutex); + assert( rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED ); + if( rc!=SQLITE_OK ){ + p->rc = rc; + } + } + } +} + +/* +** Restart the backup process. This is called when the pager layer +** detects that the database has been modified by an external database +** connection. In this case there is no way of knowing which of the +** pages that have been copied into the destination database are still +** valid and which are not, so the entire process needs to be restarted. +** +** It is assumed that the mutex associated with the BtShared object +** corresponding to the source database is held when this function is +** called. +*/ +void sqlite3BackupRestart(sqlite3_backup *pBackup){ + sqlite3_backup *p; /* Iterator variable */ + for(p=pBackup; p; p=p->pNext){ + assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) ); + p->iNext = 1; + } +} + +#ifndef SQLITE_OMIT_VACUUM +/* +** Copy the complete content of pBtFrom into pBtTo. A transaction +** must be active for both files. +** +** The size of file pTo may be reduced by this operation. If anything +** goes wrong, the transaction on pTo is rolled back. If successful, the +** transaction is committed before returning. +*/ +int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ + int rc; + sqlite3_file *pFd; /* File descriptor for database pTo */ + sqlite3_backup b; + sqlite3BtreeEnter(pTo); + sqlite3BtreeEnter(pFrom); + + assert( sqlite3BtreeIsInTrans(pTo) ); + pFd = sqlite3PagerFile(sqlite3BtreePager(pTo)); + if( pFd->pMethods ){ + i64 nByte = sqlite3BtreeGetPageSize(pFrom)*(i64)sqlite3BtreeLastPage(pFrom); + rc = sqlite3OsFileControl(pFd, SQLITE_FCNTL_OVERWRITE, &nByte); + if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; + if( rc ) goto copy_finished; + } + + /* Set up an sqlite3_backup object. sqlite3_backup.pDestDb must be set + ** to 0. This is used by the implementations of sqlite3_backup_step() + ** and sqlite3_backup_finish() to detect that they are being called + ** from this function, not directly by the user. + */ + memset(&b, 0, sizeof(b)); + b.pSrcDb = pFrom->db; + b.pSrc = pFrom; + b.pDest = pTo; + b.iNext = 1; + + /* 0x7FFFFFFF is the hard limit for the number of pages in a database + ** file. By passing this as the number of pages to copy to + ** sqlite3_backup_step(), we can guarantee that the copy finishes + ** within a single call (unless an error occurs). The assert() statement + ** checks this assumption - (p->rc) should be set to either SQLITE_DONE + ** or an error code. + */ + sqlite3_backup_step(&b, 0x7FFFFFFF); + assert( b.rc!=SQLITE_OK ); + rc = sqlite3_backup_finish(&b); + if( rc==SQLITE_OK ){ + pTo->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED; + }else{ + sqlite3PagerClearCache(sqlite3BtreePager(b.pDest)); + } + + assert( sqlite3BtreeIsInTrans(pTo)==0 ); +copy_finished: + sqlite3BtreeLeave(pFrom); + sqlite3BtreeLeave(pTo); + return rc; +} +#endif /* SQLITE_OMIT_VACUUM */ diff --git a/scalos/libraries/sqlite/src/bitvec.c b/scalos/libraries/sqlite/src/bitvec.c new file mode 100644 index 000000000..47d33ea84 --- /dev/null +++ b/scalos/libraries/sqlite/src/bitvec.c @@ -0,0 +1,408 @@ +/* +** 2008 February 16 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file implements an object that represents a fixed-length +** bitmap. Bits are numbered starting with 1. +** +** A bitmap is used to record which pages of a database file have been +** journalled during a transaction, or which pages have the "dont-write" +** property. Usually only a few pages are meet either condition. +** So the bitmap is usually sparse and has low cardinality. +** But sometimes (for example when during a DROP of a large table) most +** or all of the pages in a database can get journalled. In those cases, +** the bitmap becomes dense with high cardinality. The algorithm needs +** to handle both cases well. +** +** The size of the bitmap is fixed when the object is created. +** +** All bits are clear when the bitmap is created. Individual bits +** may be set or cleared one at a time. +** +** Test operations are about 100 times more common that set operations. +** Clear operations are exceedingly rare. There are usually between +** 5 and 500 set operations per Bitvec object, though the number of sets can +** sometimes grow into tens of thousands or larger. The size of the +** Bitvec object is the number of pages in the database file at the +** start of a transaction, and is thus usually less than a few thousand, +** but can be as large as 2 billion for a really big database. +*/ +#include "sqliteInt.h" + +/* Size of the Bitvec structure in bytes. */ +#define BITVEC_SZ 512 + +/* Round the union size down to the nearest pointer boundary, since that's how +** it will be aligned within the Bitvec struct. */ +#define BITVEC_USIZE (((BITVEC_SZ-(3*sizeof(u32)))/sizeof(Bitvec*))*sizeof(Bitvec*)) + +/* Type of the array "element" for the bitmap representation. +** Should be a power of 2, and ideally, evenly divide into BITVEC_USIZE. +** Setting this to the "natural word" size of your CPU may improve +** performance. */ +#define BITVEC_TELEM u8 +/* Size, in bits, of the bitmap element. */ +#define BITVEC_SZELEM 8 +/* Number of elements in a bitmap array. */ +#define BITVEC_NELEM (BITVEC_USIZE/sizeof(BITVEC_TELEM)) +/* Number of bits in the bitmap array. */ +#define BITVEC_NBIT (BITVEC_NELEM*BITVEC_SZELEM) + +/* Number of u32 values in hash table. */ +#define BITVEC_NINT (BITVEC_USIZE/sizeof(u32)) +/* Maximum number of entries in hash table before +** sub-dividing and re-hashing. */ +#define BITVEC_MXHASH (BITVEC_NINT/2) +/* Hashing function for the aHash representation. +** Empirical testing showed that the *37 multiplier +** (an arbitrary prime)in the hash function provided +** no fewer collisions than the no-op *1. */ +#define BITVEC_HASH(X) (((X)*1)%BITVEC_NINT) + +#define BITVEC_NPTR (BITVEC_USIZE/sizeof(Bitvec *)) + + +/* +** A bitmap is an instance of the following structure. +** +** This bitmap records the existance of zero or more bits +** with values between 1 and iSize, inclusive. +** +** There are three possible representations of the bitmap. +** If iSize<=BITVEC_NBIT, then Bitvec.u.aBitmap[] is a straight +** bitmap. The least significant bit is bit 1. +** +** If iSize>BITVEC_NBIT and iDivisor==0 then Bitvec.u.aHash[] is +** a hash table that will hold up to BITVEC_MXHASH distinct values. +** +** Otherwise, the value i is redirected into one of BITVEC_NPTR +** sub-bitmaps pointed to by Bitvec.u.apSub[]. Each subbitmap +** handles up to iDivisor separate values of i. apSub[0] holds +** values between 1 and iDivisor. apSub[1] holds values between +** iDivisor+1 and 2*iDivisor. apSub[N] holds values between +** N*iDivisor+1 and (N+1)*iDivisor. Each subbitmap is normalized +** to hold deal with values between 1 and iDivisor. +*/ +struct Bitvec { + u32 iSize; /* Maximum bit index. Max iSize is 4,294,967,296. */ + u32 nSet; /* Number of bits that are set - only valid for aHash + ** element. Max is BITVEC_NINT. For BITVEC_SZ of 512, + ** this would be 125. */ + u32 iDivisor; /* Number of bits handled by each apSub[] entry. */ + /* Should >=0 for apSub element. */ + /* Max iDivisor is max(u32) / BITVEC_NPTR + 1. */ + /* For a BITVEC_SZ of 512, this would be 34,359,739. */ + union { + BITVEC_TELEM aBitmap[BITVEC_NELEM]; /* Bitmap representation */ + u32 aHash[BITVEC_NINT]; /* Hash table representation */ + Bitvec *apSub[BITVEC_NPTR]; /* Recursive representation */ + } u; +}; + +/* +** Create a new bitmap object able to handle bits between 0 and iSize, +** inclusive. Return a pointer to the new object. Return NULL if +** malloc fails. +*/ +Bitvec *sqlite3BitvecCreate(u32 iSize){ + Bitvec *p; + assert( sizeof(*p)==BITVEC_SZ ); + p = sqlite3MallocZero( sizeof(*p) ); + if( p ){ + p->iSize = iSize; + } + return p; +} + +/* +** Check to see if the i-th bit is set. Return true or false. +** If p is NULL (if the bitmap has not been created) or if +** i is out of range, then return false. +*/ +int sqlite3BitvecTest(Bitvec *p, u32 i){ + if( p==0 ) return 0; + if( i>p->iSize || i==0 ) return 0; + i--; + while( p->iDivisor ){ + u32 bin = i/p->iDivisor; + i = i%p->iDivisor; + p = p->u.apSub[bin]; + if (!p) { + return 0; + } + } + if( p->iSize<=BITVEC_NBIT ){ + return (p->u.aBitmap[i/BITVEC_SZELEM] & (1<<(i&(BITVEC_SZELEM-1))))!=0; + } else{ + u32 h = BITVEC_HASH(i++); + while( p->u.aHash[h] ){ + if( p->u.aHash[h]==i ) return 1; + h = (h+1) % BITVEC_NINT; + } + return 0; + } +} + +/* +** Set the i-th bit. Return 0 on success and an error code if +** anything goes wrong. +** +** This routine might cause sub-bitmaps to be allocated. Failing +** to get the memory needed to hold the sub-bitmap is the only +** that can go wrong with an insert, assuming p and i are valid. +** +** The calling function must ensure that p is a valid Bitvec object +** and that the value for "i" is within range of the Bitvec object. +** Otherwise the behavior is undefined. +*/ +int sqlite3BitvecSet(Bitvec *p, u32 i){ + u32 h; + if( p==0 ) return SQLITE_OK; + assert( i>0 ); + assert( i<=p->iSize ); + i--; + while((p->iSize > BITVEC_NBIT) && p->iDivisor) { + u32 bin = i/p->iDivisor; + i = i%p->iDivisor; + if( p->u.apSub[bin]==0 ){ + p->u.apSub[bin] = sqlite3BitvecCreate( p->iDivisor ); + if( p->u.apSub[bin]==0 ) return SQLITE_NOMEM; + } + p = p->u.apSub[bin]; + } + if( p->iSize<=BITVEC_NBIT ){ + p->u.aBitmap[i/BITVEC_SZELEM] |= 1 << (i&(BITVEC_SZELEM-1)); + return SQLITE_OK; + } + h = BITVEC_HASH(i++); + /* if there wasn't a hash collision, and this doesn't */ + /* completely fill the hash, then just add it without */ + /* worring about sub-dividing and re-hashing. */ + if( !p->u.aHash[h] ){ + if (p->nSet<(BITVEC_NINT-1)) { + goto bitvec_set_end; + } else { + goto bitvec_set_rehash; + } + } + /* there was a collision, check to see if it's already */ + /* in hash, if not, try to find a spot for it */ + do { + if( p->u.aHash[h]==i ) return SQLITE_OK; + h++; + if( h>=BITVEC_NINT ) h = 0; + } while( p->u.aHash[h] ); + /* we didn't find it in the hash. h points to the first */ + /* available free spot. check to see if this is going to */ + /* make our hash too "full". */ +bitvec_set_rehash: + if( p->nSet>=BITVEC_MXHASH ){ + unsigned int j; + int rc; + u32 *aiValues = sqlite3StackAllocRaw(0, sizeof(p->u.aHash)); + if( aiValues==0 ){ + return SQLITE_NOMEM; + }else{ + memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash)); + memset(p->u.apSub, 0, sizeof(p->u.apSub)); + p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR; + rc = sqlite3BitvecSet(p, i); + for(j=0; jnSet++; + p->u.aHash[h] = i; + return SQLITE_OK; +} + +/* +** Clear the i-th bit. +** +** pBuf must be a pointer to at least BITVEC_SZ bytes of temporary storage +** that BitvecClear can use to rebuilt its hash table. +*/ +void sqlite3BitvecClear(Bitvec *p, u32 i, void *pBuf){ + if( p==0 ) return; + assert( i>0 ); + i--; + while( p->iDivisor ){ + u32 bin = i/p->iDivisor; + i = i%p->iDivisor; + p = p->u.apSub[bin]; + if (!p) { + return; + } + } + if( p->iSize<=BITVEC_NBIT ){ + p->u.aBitmap[i/BITVEC_SZELEM] &= ~(1 << (i&(BITVEC_SZELEM-1))); + }else{ + unsigned int j; + u32 *aiValues = pBuf; + memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash)); + memset(p->u.aHash, 0, sizeof(p->u.aHash)); + p->nSet = 0; + for(j=0; jnSet++; + while( p->u.aHash[h] ){ + h++; + if( h>=BITVEC_NINT ) h = 0; + } + p->u.aHash[h] = aiValues[j]; + } + } + } +} + +/* +** Destroy a bitmap object. Reclaim all memory used. +*/ +void sqlite3BitvecDestroy(Bitvec *p){ + if( p==0 ) return; + if( p->iDivisor ){ + unsigned int i; + for(i=0; iu.apSub[i]); + } + } + sqlite3_free(p); +} + +/* +** Return the value of the iSize parameter specified when Bitvec *p +** was created. +*/ +u32 sqlite3BitvecSize(Bitvec *p){ + return p->iSize; +} + +#ifndef SQLITE_OMIT_BUILTIN_TEST +/* +** Let V[] be an array of unsigned characters sufficient to hold +** up to N bits. Let I be an integer between 0 and N. 0<=I>3] |= (1<<(I&7)) +#define CLEARBIT(V,I) V[I>>3] &= ~(1<<(I&7)) +#define TESTBIT(V,I) (V[I>>3]&(1<<(I&7)))!=0 + +/* +** This routine runs an extensive test of the Bitvec code. +** +** The input is an array of integers that acts as a program +** to test the Bitvec. The integers are opcodes followed +** by 0, 1, or 3 operands, depending on the opcode. Another +** opcode follows immediately after the last operand. +** +** There are 6 opcodes numbered from 0 through 5. 0 is the +** "halt" opcode and causes the test to end. +** +** 0 Halt and return the number of errors +** 1 N S X Set N bits beginning with S and incrementing by X +** 2 N S X Clear N bits beginning with S and incrementing by X +** 3 N Set N randomly chosen bits +** 4 N Clear N randomly chosen bits +** 5 N S X Set N bits from S increment X in array only, not in bitvec +** +** The opcodes 1 through 4 perform set and clear operations are performed +** on both a Bitvec object and on a linear array of bits obtained from malloc. +** Opcode 5 works on the linear array only, not on the Bitvec. +** Opcode 5 is used to deliberately induce a fault in order to +** confirm that error detection works. +** +** At the conclusion of the test the linear array is compared +** against the Bitvec object. If there are any differences, +** an error is returned. If they are the same, zero is returned. +** +** If a memory allocation error occurs, return -1. +*/ +int sqlite3BitvecBuiltinTest(int sz, int *aOp){ + Bitvec *pBitvec = 0; + unsigned char *pV = 0; + int rc = -1; + int i, nx, pc, op; + void *pTmpSpace; + + /* Allocate the Bitvec to be tested and a linear array of + ** bits to act as the reference */ + pBitvec = sqlite3BitvecCreate( sz ); + pV = sqlite3_malloc( (sz+7)/8 + 1 ); + pTmpSpace = sqlite3_malloc(BITVEC_SZ); + if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end; + memset(pV, 0, (sz+7)/8 + 1); + + /* NULL pBitvec tests */ + sqlite3BitvecSet(0, 1); + sqlite3BitvecClear(0, 1, pTmpSpace); + + /* Run the program */ + pc = 0; + while( (op = aOp[pc])!=0 ){ + switch( op ){ + case 1: + case 2: + case 5: { + nx = 4; + i = aOp[pc+2] - 1; + aOp[pc+2] += aOp[pc+3]; + break; + } + case 3: + case 4: + default: { + nx = 2; + sqlite3_randomness(sizeof(i), &i); + break; + } + } + if( (--aOp[pc+1]) > 0 ) nx = 0; + pc += nx; + i = (i & 0x7fffffff)%sz; + if( (op & 1)!=0 ){ + SETBIT(pV, (i+1)); + if( op!=5 ){ + if( sqlite3BitvecSet(pBitvec, i+1) ) goto bitvec_end; + } + }else{ + CLEARBIT(pV, (i+1)); + sqlite3BitvecClear(pBitvec, i+1, pTmpSpace); + } + } + + /* Test to make sure the linear array exactly matches the + ** Bitvec object. Start with the assumption that they do + ** match (rc==0). Change rc to non-zero if a discrepancy + ** is found. + */ + rc = sqlite3BitvecTest(0,0) + sqlite3BitvecTest(pBitvec, sz+1) + + sqlite3BitvecTest(pBitvec, 0) + + (sqlite3BitvecSize(pBitvec) - sz); + for(i=1; i<=sz; i++){ + if( (TESTBIT(pV,i))!=sqlite3BitvecTest(pBitvec,i) ){ + rc = i; + break; + } + } + + /* Free allocated structure */ +bitvec_end: + sqlite3_free(pTmpSpace); + sqlite3_free(pV); + sqlite3BitvecDestroy(pBitvec); + return rc; +} +#endif /* SQLITE_OMIT_BUILTIN_TEST */ diff --git a/scalos/libraries/sqlite/src/btmutex.c b/scalos/libraries/sqlite/src/btmutex.c new file mode 100644 index 000000000..d87d4d5fe --- /dev/null +++ b/scalos/libraries/sqlite/src/btmutex.c @@ -0,0 +1,287 @@ +/* +** 2007 August 27 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains code used to implement mutexes on Btree objects. +** This code really belongs in btree.c. But btree.c is getting too +** big and we want to break it down some. This packaged seemed like +** a good breakout. +*/ +#include "btreeInt.h" +#ifndef SQLITE_OMIT_SHARED_CACHE +#if SQLITE_THREADSAFE + +/* +** Obtain the BtShared mutex associated with B-Tree handle p. Also, +** set BtShared.db to the database handle associated with p and the +** p->locked boolean to true. +*/ +static void lockBtreeMutex(Btree *p){ + assert( p->locked==0 ); + assert( sqlite3_mutex_notheld(p->pBt->mutex) ); + assert( sqlite3_mutex_held(p->db->mutex) ); + + sqlite3_mutex_enter(p->pBt->mutex); + p->pBt->db = p->db; + p->locked = 1; +} + +/* +** Release the BtShared mutex associated with B-Tree handle p and +** clear the p->locked boolean. +*/ +static void unlockBtreeMutex(Btree *p){ + BtShared *pBt = p->pBt; + assert( p->locked==1 ); + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3_mutex_held(p->db->mutex) ); + assert( p->db==pBt->db ); + + sqlite3_mutex_leave(pBt->mutex); + p->locked = 0; +} + +/* +** Enter a mutex on the given BTree object. +** +** If the object is not sharable, then no mutex is ever required +** and this routine is a no-op. The underlying mutex is non-recursive. +** But we keep a reference count in Btree.wantToLock so the behavior +** of this interface is recursive. +** +** To avoid deadlocks, multiple Btrees are locked in the same order +** by all database connections. The p->pNext is a list of other +** Btrees belonging to the same database connection as the p Btree +** which need to be locked after p. If we cannot get a lock on +** p, then first unlock all of the others on p->pNext, then wait +** for the lock to become available on p, then relock all of the +** subsequent Btrees that desire a lock. +*/ +void sqlite3BtreeEnter(Btree *p){ + Btree *pLater; + + /* Some basic sanity checking on the Btree. The list of Btrees + ** connected by pNext and pPrev should be in sorted order by + ** Btree.pBt value. All elements of the list should belong to + ** the same connection. Only shared Btrees are on the list. */ + assert( p->pNext==0 || p->pNext->pBt>p->pBt ); + assert( p->pPrev==0 || p->pPrev->pBtpBt ); + assert( p->pNext==0 || p->pNext->db==p->db ); + assert( p->pPrev==0 || p->pPrev->db==p->db ); + assert( p->sharable || (p->pNext==0 && p->pPrev==0) ); + + /* Check for locking consistency */ + assert( !p->locked || p->wantToLock>0 ); + assert( p->sharable || p->wantToLock==0 ); + + /* We should already hold a lock on the database connection */ + assert( sqlite3_mutex_held(p->db->mutex) ); + + /* Unless the database is sharable and unlocked, then BtShared.db + ** should already be set correctly. */ + assert( (p->locked==0 && p->sharable) || p->pBt->db==p->db ); + + if( !p->sharable ) return; + p->wantToLock++; + if( p->locked ) return; + + /* In most cases, we should be able to acquire the lock we + ** want without having to go throught the ascending lock + ** procedure that follows. Just be sure not to block. + */ + if( sqlite3_mutex_try(p->pBt->mutex)==SQLITE_OK ){ + p->pBt->db = p->db; + p->locked = 1; + return; + } + + /* To avoid deadlock, first release all locks with a larger + ** BtShared address. Then acquire our lock. Then reacquire + ** the other BtShared locks that we used to hold in ascending + ** order. + */ + for(pLater=p->pNext; pLater; pLater=pLater->pNext){ + assert( pLater->sharable ); + assert( pLater->pNext==0 || pLater->pNext->pBt>pLater->pBt ); + assert( !pLater->locked || pLater->wantToLock>0 ); + if( pLater->locked ){ + unlockBtreeMutex(pLater); + } + } + lockBtreeMutex(p); + for(pLater=p->pNext; pLater; pLater=pLater->pNext){ + if( pLater->wantToLock ){ + lockBtreeMutex(pLater); + } + } +} + +/* +** Exit the recursive mutex on a Btree. +*/ +void sqlite3BtreeLeave(Btree *p){ + if( p->sharable ){ + assert( p->wantToLock>0 ); + p->wantToLock--; + if( p->wantToLock==0 ){ + unlockBtreeMutex(p); + } + } +} + +#ifndef NDEBUG +/* +** Return true if the BtShared mutex is held on the btree, or if the +** B-Tree is not marked as sharable. +** +** This routine is used only from within assert() statements. +*/ +int sqlite3BtreeHoldsMutex(Btree *p){ + assert( p->sharable==0 || p->locked==0 || p->wantToLock>0 ); + assert( p->sharable==0 || p->locked==0 || p->db==p->pBt->db ); + assert( p->sharable==0 || p->locked==0 || sqlite3_mutex_held(p->pBt->mutex) ); + assert( p->sharable==0 || p->locked==0 || sqlite3_mutex_held(p->db->mutex) ); + + return (p->sharable==0 || p->locked); +} +#endif + + +#ifndef SQLITE_OMIT_INCRBLOB +/* +** Enter and leave a mutex on a Btree given a cursor owned by that +** Btree. These entry points are used by incremental I/O and can be +** omitted if that module is not used. +*/ +void sqlite3BtreeEnterCursor(BtCursor *pCur){ + sqlite3BtreeEnter(pCur->pBtree); +} +void sqlite3BtreeLeaveCursor(BtCursor *pCur){ + sqlite3BtreeLeave(pCur->pBtree); +} +#endif /* SQLITE_OMIT_INCRBLOB */ + + +/* +** Enter the mutex on every Btree associated with a database +** connection. This is needed (for example) prior to parsing +** a statement since we will be comparing table and column names +** against all schemas and we do not want those schemas being +** reset out from under us. +** +** There is a corresponding leave-all procedures. +** +** Enter the mutexes in accending order by BtShared pointer address +** to avoid the possibility of deadlock when two threads with +** two or more btrees in common both try to lock all their btrees +** at the same instant. +*/ +void sqlite3BtreeEnterAll(sqlite3 *db){ + int i; + Btree *p; + assert( sqlite3_mutex_held(db->mutex) ); + for(i=0; inDb; i++){ + p = db->aDb[i].pBt; + if( p ) sqlite3BtreeEnter(p); + } +} +void sqlite3BtreeLeaveAll(sqlite3 *db){ + int i; + Btree *p; + assert( sqlite3_mutex_held(db->mutex) ); + for(i=0; inDb; i++){ + p = db->aDb[i].pBt; + if( p ) sqlite3BtreeLeave(p); + } +} + +/* +** Return true if a particular Btree requires a lock. Return FALSE if +** no lock is ever required since it is not sharable. +*/ +int sqlite3BtreeSharable(Btree *p){ + return p->sharable; +} + +#ifndef NDEBUG +/* +** Return true if the current thread holds the database connection +** mutex and all required BtShared mutexes. +** +** This routine is used inside assert() statements only. +*/ +int sqlite3BtreeHoldsAllMutexes(sqlite3 *db){ + int i; + if( !sqlite3_mutex_held(db->mutex) ){ + return 0; + } + for(i=0; inDb; i++){ + Btree *p; + p = db->aDb[i].pBt; + if( p && p->sharable && + (p->wantToLock==0 || !sqlite3_mutex_held(p->pBt->mutex)) ){ + return 0; + } + } + return 1; +} +#endif /* NDEBUG */ + +#ifndef NDEBUG +/* +** Return true if the correct mutexes are held for accessing the +** db->aDb[iDb].pSchema structure. The mutexes required for schema +** access are: +** +** (1) The mutex on db +** (2) if iDb!=1, then the mutex on db->aDb[iDb].pBt. +** +** If pSchema is not NULL, then iDb is computed from pSchema and +** db using sqlite3SchemaToIndex(). +*/ +int sqlite3SchemaMutexHeld(sqlite3 *db, int iDb, Schema *pSchema){ + Btree *p; + assert( db!=0 ); + if( pSchema ) iDb = sqlite3SchemaToIndex(db, pSchema); + assert( iDb>=0 && iDbnDb ); + if( !sqlite3_mutex_held(db->mutex) ) return 0; + if( iDb==1 ) return 1; + p = db->aDb[iDb].pBt; + assert( p!=0 ); + return p->sharable==0 || p->locked==1; +} +#endif /* NDEBUG */ + +#else /* SQLITE_THREADSAFE>0 above. SQLITE_THREADSAFE==0 below */ +/* +** The following are special cases for mutex enter routines for use +** in single threaded applications that use shared cache. Except for +** these two routines, all mutex operations are no-ops in that case and +** are null #defines in btree.h. +** +** If shared cache is disabled, then all btree mutex routines, including +** the ones below, are no-ops and are null #defines in btree.h. +*/ + +void sqlite3BtreeEnter(Btree *p){ + p->pBt->db = p->db; +} +void sqlite3BtreeEnterAll(sqlite3 *db){ + int i; + for(i=0; inDb; i++){ + Btree *p = db->aDb[i].pBt; + if( p ){ + p->pBt->db = p->db; + } + } +} +#endif /* if SQLITE_THREADSAFE */ +#endif /* ifndef SQLITE_OMIT_SHARED_CACHE */ diff --git a/scalos/libraries/sqlite/src/btree.c b/scalos/libraries/sqlite/src/btree.c new file mode 100644 index 000000000..253240665 --- /dev/null +++ b/scalos/libraries/sqlite/src/btree.c @@ -0,0 +1,8277 @@ +/* +** 2004 April 6 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file implements a external (disk-based) database using BTrees. +** See the header comment on "btreeInt.h" for additional information. +** Including a description of file format and an overview of operation. +*/ +#include "btreeInt.h" + +/* +** The header string that appears at the beginning of every +** SQLite database. +*/ +static const char zMagicHeader[] = SQLITE_FILE_HEADER; + +/* +** Set this global variable to 1 to enable tracing using the TRACE +** macro. +*/ +#if 0 +int sqlite3BtreeTrace=1; /* True to enable tracing */ +# define TRACE(X) if(sqlite3BtreeTrace){printf X;fflush(stdout);} +#else +# define TRACE(X) +#endif + +/* +** Extract a 2-byte big-endian integer from an array of unsigned bytes. +** But if the value is zero, make it 65536. +** +** This routine is used to extract the "offset to cell content area" value +** from the header of a btree page. If the page size is 65536 and the page +** is empty, the offset should be 65536, but the 2-byte value stores zero. +** This routine makes the necessary adjustment to 65536. +*/ +#define get2byteNotZero(X) (((((int)get2byte(X))-1)&0xffff)+1) + +#ifndef SQLITE_OMIT_SHARED_CACHE +/* +** A list of BtShared objects that are eligible for participation +** in shared cache. This variable has file scope during normal builds, +** but the test harness needs to access it so we make it global for +** test builds. +** +** Access to this variable is protected by SQLITE_MUTEX_STATIC_MASTER. +*/ +#ifdef SQLITE_TEST +BtShared *SQLITE_WSD sqlite3SharedCacheList = 0; +#else +static BtShared *SQLITE_WSD sqlite3SharedCacheList = 0; +#endif +#endif /* SQLITE_OMIT_SHARED_CACHE */ + +#ifndef SQLITE_OMIT_SHARED_CACHE +/* +** Enable or disable the shared pager and schema features. +** +** This routine has no effect on existing database connections. +** The shared cache setting effects only future calls to +** sqlite3_open(), sqlite3_open16(), or sqlite3_open_v2(). +*/ +int sqlite3_enable_shared_cache(int enable){ + sqlite3GlobalConfig.sharedCacheEnabled = enable; + return SQLITE_OK; +} +#endif + + + +#ifdef SQLITE_OMIT_SHARED_CACHE + /* + ** The functions querySharedCacheTableLock(), setSharedCacheTableLock(), + ** and clearAllSharedCacheTableLocks() + ** manipulate entries in the BtShared.pLock linked list used to store + ** shared-cache table level locks. If the library is compiled with the + ** shared-cache feature disabled, then there is only ever one user + ** of each BtShared structure and so this locking is not necessary. + ** So define the lock related functions as no-ops. + */ + #define querySharedCacheTableLock(a,b,c) SQLITE_OK + #define setSharedCacheTableLock(a,b,c) SQLITE_OK + #define clearAllSharedCacheTableLocks(a) + #define downgradeAllSharedCacheTableLocks(a) + #define hasSharedCacheTableLock(a,b,c,d) 1 + #define hasReadConflicts(a, b) 0 +#endif + +#ifndef SQLITE_OMIT_SHARED_CACHE + +#ifdef SQLITE_DEBUG +/* +**** This function is only used as part of an assert() statement. *** +** +** Check to see if pBtree holds the required locks to read or write to the +** table with root page iRoot. Return 1 if it does and 0 if not. +** +** For example, when writing to a table with root-page iRoot via +** Btree connection pBtree: +** +** assert( hasSharedCacheTableLock(pBtree, iRoot, 0, WRITE_LOCK) ); +** +** When writing to an index that resides in a sharable database, the +** caller should have first obtained a lock specifying the root page of +** the corresponding table. This makes things a bit more complicated, +** as this module treats each table as a separate structure. To determine +** the table corresponding to the index being written, this +** function has to search through the database schema. +** +** Instead of a lock on the table/index rooted at page iRoot, the caller may +** hold a write-lock on the schema table (root page 1). This is also +** acceptable. +*/ +static int hasSharedCacheTableLock( + Btree *pBtree, /* Handle that must hold lock */ + Pgno iRoot, /* Root page of b-tree */ + int isIndex, /* True if iRoot is the root of an index b-tree */ + int eLockType /* Required lock type (READ_LOCK or WRITE_LOCK) */ +){ + Schema *pSchema = (Schema *)pBtree->pBt->pSchema; + Pgno iTab = 0; + BtLock *pLock; + + /* If this database is not shareable, or if the client is reading + ** and has the read-uncommitted flag set, then no lock is required. + ** Return true immediately. + */ + if( (pBtree->sharable==0) + || (eLockType==READ_LOCK && (pBtree->db->flags & SQLITE_ReadUncommitted)) + ){ + return 1; + } + + /* If the client is reading or writing an index and the schema is + ** not loaded, then it is too difficult to actually check to see if + ** the correct locks are held. So do not bother - just return true. + ** This case does not come up very often anyhow. + */ + if( isIndex && (!pSchema || (pSchema->flags&DB_SchemaLoaded)==0) ){ + return 1; + } + + /* Figure out the root-page that the lock should be held on. For table + ** b-trees, this is just the root page of the b-tree being read or + ** written. For index b-trees, it is the root page of the associated + ** table. */ + if( isIndex ){ + HashElem *p; + for(p=sqliteHashFirst(&pSchema->idxHash); p; p=sqliteHashNext(p)){ + Index *pIdx = (Index *)sqliteHashData(p); + if( pIdx->tnum==(int)iRoot ){ + iTab = pIdx->pTable->tnum; + } + } + }else{ + iTab = iRoot; + } + + /* Search for the required lock. Either a write-lock on root-page iTab, a + ** write-lock on the schema table, or (if the client is reading) a + ** read-lock on iTab will suffice. Return 1 if any of these are found. */ + for(pLock=pBtree->pBt->pLock; pLock; pLock=pLock->pNext){ + if( pLock->pBtree==pBtree + && (pLock->iTable==iTab || (pLock->eLock==WRITE_LOCK && pLock->iTable==1)) + && pLock->eLock>=eLockType + ){ + return 1; + } + } + + /* Failed to find the required lock. */ + return 0; +} +#endif /* SQLITE_DEBUG */ + +#ifdef SQLITE_DEBUG +/* +**** This function may be used as part of assert() statements only. **** +** +** Return true if it would be illegal for pBtree to write into the +** table or index rooted at iRoot because other shared connections are +** simultaneously reading that same table or index. +** +** It is illegal for pBtree to write if some other Btree object that +** shares the same BtShared object is currently reading or writing +** the iRoot table. Except, if the other Btree object has the +** read-uncommitted flag set, then it is OK for the other object to +** have a read cursor. +** +** For example, before writing to any part of the table or index +** rooted at page iRoot, one should call: +** +** assert( !hasReadConflicts(pBtree, iRoot) ); +*/ +static int hasReadConflicts(Btree *pBtree, Pgno iRoot){ + BtCursor *p; + for(p=pBtree->pBt->pCursor; p; p=p->pNext){ + if( p->pgnoRoot==iRoot + && p->pBtree!=pBtree + && 0==(p->pBtree->db->flags & SQLITE_ReadUncommitted) + ){ + return 1; + } + } + return 0; +} +#endif /* #ifdef SQLITE_DEBUG */ + +/* +** Query to see if Btree handle p may obtain a lock of type eLock +** (READ_LOCK or WRITE_LOCK) on the table with root-page iTab. Return +** SQLITE_OK if the lock may be obtained (by calling +** setSharedCacheTableLock()), or SQLITE_LOCKED if not. +*/ +static int querySharedCacheTableLock(Btree *p, Pgno iTab, u8 eLock){ + BtShared *pBt = p->pBt; + BtLock *pIter; + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( eLock==READ_LOCK || eLock==WRITE_LOCK ); + assert( p->db!=0 ); + assert( !(p->db->flags&SQLITE_ReadUncommitted)||eLock==WRITE_LOCK||iTab==1 ); + + /* If requesting a write-lock, then the Btree must have an open write + ** transaction on this file. And, obviously, for this to be so there + ** must be an open write transaction on the file itself. + */ + assert( eLock==READ_LOCK || (p==pBt->pWriter && p->inTrans==TRANS_WRITE) ); + assert( eLock==READ_LOCK || pBt->inTransaction==TRANS_WRITE ); + + /* This routine is a no-op if the shared-cache is not enabled */ + if( !p->sharable ){ + return SQLITE_OK; + } + + /* If some other connection is holding an exclusive lock, the + ** requested lock may not be obtained. + */ + if( pBt->pWriter!=p && (pBt->btsFlags & BTS_EXCLUSIVE)!=0 ){ + sqlite3ConnectionBlocked(p->db, pBt->pWriter->db); + return SQLITE_LOCKED_SHAREDCACHE; + } + + for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){ + /* The condition (pIter->eLock!=eLock) in the following if(...) + ** statement is a simplification of: + ** + ** (eLock==WRITE_LOCK || pIter->eLock==WRITE_LOCK) + ** + ** since we know that if eLock==WRITE_LOCK, then no other connection + ** may hold a WRITE_LOCK on any table in this file (since there can + ** only be a single writer). + */ + assert( pIter->eLock==READ_LOCK || pIter->eLock==WRITE_LOCK ); + assert( eLock==READ_LOCK || pIter->pBtree==p || pIter->eLock==READ_LOCK); + if( pIter->pBtree!=p && pIter->iTable==iTab && pIter->eLock!=eLock ){ + sqlite3ConnectionBlocked(p->db, pIter->pBtree->db); + if( eLock==WRITE_LOCK ){ + assert( p==pBt->pWriter ); + pBt->btsFlags |= BTS_PENDING; + } + return SQLITE_LOCKED_SHAREDCACHE; + } + } + return SQLITE_OK; +} +#endif /* !SQLITE_OMIT_SHARED_CACHE */ + +#ifndef SQLITE_OMIT_SHARED_CACHE +/* +** Add a lock on the table with root-page iTable to the shared-btree used +** by Btree handle p. Parameter eLock must be either READ_LOCK or +** WRITE_LOCK. +** +** This function assumes the following: +** +** (a) The specified Btree object p is connected to a sharable +** database (one with the BtShared.sharable flag set), and +** +** (b) No other Btree objects hold a lock that conflicts +** with the requested lock (i.e. querySharedCacheTableLock() has +** already been called and returned SQLITE_OK). +** +** SQLITE_OK is returned if the lock is added successfully. SQLITE_NOMEM +** is returned if a malloc attempt fails. +*/ +static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){ + BtShared *pBt = p->pBt; + BtLock *pLock = 0; + BtLock *pIter; + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( eLock==READ_LOCK || eLock==WRITE_LOCK ); + assert( p->db!=0 ); + + /* A connection with the read-uncommitted flag set will never try to + ** obtain a read-lock using this function. The only read-lock obtained + ** by a connection in read-uncommitted mode is on the sqlite_master + ** table, and that lock is obtained in BtreeBeginTrans(). */ + assert( 0==(p->db->flags&SQLITE_ReadUncommitted) || eLock==WRITE_LOCK ); + + /* This function should only be called on a sharable b-tree after it + ** has been determined that no other b-tree holds a conflicting lock. */ + assert( p->sharable ); + assert( SQLITE_OK==querySharedCacheTableLock(p, iTable, eLock) ); + + /* First search the list for an existing lock on this table. */ + for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){ + if( pIter->iTable==iTable && pIter->pBtree==p ){ + pLock = pIter; + break; + } + } + + /* If the above search did not find a BtLock struct associating Btree p + ** with table iTable, allocate one and link it into the list. + */ + if( !pLock ){ + pLock = (BtLock *)sqlite3MallocZero(sizeof(BtLock)); + if( !pLock ){ + return SQLITE_NOMEM; + } + pLock->iTable = iTable; + pLock->pBtree = p; + pLock->pNext = pBt->pLock; + pBt->pLock = pLock; + } + + /* Set the BtLock.eLock variable to the maximum of the current lock + ** and the requested lock. This means if a write-lock was already held + ** and a read-lock requested, we don't incorrectly downgrade the lock. + */ + assert( WRITE_LOCK>READ_LOCK ); + if( eLock>pLock->eLock ){ + pLock->eLock = eLock; + } + + return SQLITE_OK; +} +#endif /* !SQLITE_OMIT_SHARED_CACHE */ + +#ifndef SQLITE_OMIT_SHARED_CACHE +/* +** Release all the table locks (locks obtained via calls to +** the setSharedCacheTableLock() procedure) held by Btree object p. +** +** This function assumes that Btree p has an open read or write +** transaction. If it does not, then the BTS_PENDING flag +** may be incorrectly cleared. +*/ +static void clearAllSharedCacheTableLocks(Btree *p){ + BtShared *pBt = p->pBt; + BtLock **ppIter = &pBt->pLock; + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( p->sharable || 0==*ppIter ); + assert( p->inTrans>0 ); + + while( *ppIter ){ + BtLock *pLock = *ppIter; + assert( (pBt->btsFlags & BTS_EXCLUSIVE)==0 || pBt->pWriter==pLock->pBtree ); + assert( pLock->pBtree->inTrans>=pLock->eLock ); + if( pLock->pBtree==p ){ + *ppIter = pLock->pNext; + assert( pLock->iTable!=1 || pLock==&p->lock ); + if( pLock->iTable!=1 ){ + sqlite3_free(pLock); + } + }else{ + ppIter = &pLock->pNext; + } + } + + assert( (pBt->btsFlags & BTS_PENDING)==0 || pBt->pWriter ); + if( pBt->pWriter==p ){ + pBt->pWriter = 0; + pBt->btsFlags &= ~(BTS_EXCLUSIVE|BTS_PENDING); + }else if( pBt->nTransaction==2 ){ + /* This function is called when Btree p is concluding its + ** transaction. If there currently exists a writer, and p is not + ** that writer, then the number of locks held by connections other + ** than the writer must be about to drop to zero. In this case + ** set the BTS_PENDING flag to 0. + ** + ** If there is not currently a writer, then BTS_PENDING must + ** be zero already. So this next line is harmless in that case. + */ + pBt->btsFlags &= ~BTS_PENDING; + } +} + +/* +** This function changes all write-locks held by Btree p into read-locks. +*/ +static void downgradeAllSharedCacheTableLocks(Btree *p){ + BtShared *pBt = p->pBt; + if( pBt->pWriter==p ){ + BtLock *pLock; + pBt->pWriter = 0; + pBt->btsFlags &= ~(BTS_EXCLUSIVE|BTS_PENDING); + for(pLock=pBt->pLock; pLock; pLock=pLock->pNext){ + assert( pLock->eLock==READ_LOCK || pLock->pBtree==p ); + pLock->eLock = READ_LOCK; + } + } +} + +#endif /* SQLITE_OMIT_SHARED_CACHE */ + +static void releasePage(MemPage *pPage); /* Forward reference */ + +/* +***** This routine is used inside of assert() only **** +** +** Verify that the cursor holds the mutex on its BtShared +*/ +#ifdef SQLITE_DEBUG +static int cursorHoldsMutex(BtCursor *p){ + return sqlite3_mutex_held(p->pBt->mutex); +} +#endif + + +#ifndef SQLITE_OMIT_INCRBLOB +/* +** Invalidate the overflow page-list cache for cursor pCur, if any. +*/ +static void invalidateOverflowCache(BtCursor *pCur){ + assert( cursorHoldsMutex(pCur) ); + sqlite3_free(pCur->aOverflow); + pCur->aOverflow = 0; +} + +/* +** Invalidate the overflow page-list cache for all cursors opened +** on the shared btree structure pBt. +*/ +static void invalidateAllOverflowCache(BtShared *pBt){ + BtCursor *p; + assert( sqlite3_mutex_held(pBt->mutex) ); + for(p=pBt->pCursor; p; p=p->pNext){ + invalidateOverflowCache(p); + } +} + +/* +** This function is called before modifying the contents of a table +** to invalidate any incrblob cursors that are open on the +** row or one of the rows being modified. +** +** If argument isClearTable is true, then the entire contents of the +** table is about to be deleted. In this case invalidate all incrblob +** cursors open on any row within the table with root-page pgnoRoot. +** +** Otherwise, if argument isClearTable is false, then the row with +** rowid iRow is being replaced or deleted. In this case invalidate +** only those incrblob cursors open on that specific row. +*/ +static void invalidateIncrblobCursors( + Btree *pBtree, /* The database file to check */ + i64 iRow, /* The rowid that might be changing */ + int isClearTable /* True if all rows are being deleted */ +){ + BtCursor *p; + BtShared *pBt = pBtree->pBt; + assert( sqlite3BtreeHoldsMutex(pBtree) ); + for(p=pBt->pCursor; p; p=p->pNext){ + if( p->isIncrblobHandle && (isClearTable || p->info.nKey==iRow) ){ + p->eState = CURSOR_INVALID; + } + } +} + +#else + /* Stub functions when INCRBLOB is omitted */ + #define invalidateOverflowCache(x) + #define invalidateAllOverflowCache(x) + #define invalidateIncrblobCursors(x,y,z) +#endif /* SQLITE_OMIT_INCRBLOB */ + +/* +** Set bit pgno of the BtShared.pHasContent bitvec. This is called +** when a page that previously contained data becomes a free-list leaf +** page. +** +** The BtShared.pHasContent bitvec exists to work around an obscure +** bug caused by the interaction of two useful IO optimizations surrounding +** free-list leaf pages: +** +** 1) When all data is deleted from a page and the page becomes +** a free-list leaf page, the page is not written to the database +** (as free-list leaf pages contain no meaningful data). Sometimes +** such a page is not even journalled (as it will not be modified, +** why bother journalling it?). +** +** 2) When a free-list leaf page is reused, its content is not read +** from the database or written to the journal file (why should it +** be, if it is not at all meaningful?). +** +** By themselves, these optimizations work fine and provide a handy +** performance boost to bulk delete or insert operations. However, if +** a page is moved to the free-list and then reused within the same +** transaction, a problem comes up. If the page is not journalled when +** it is moved to the free-list and it is also not journalled when it +** is extracted from the free-list and reused, then the original data +** may be lost. In the event of a rollback, it may not be possible +** to restore the database to its original configuration. +** +** The solution is the BtShared.pHasContent bitvec. Whenever a page is +** moved to become a free-list leaf page, the corresponding bit is +** set in the bitvec. Whenever a leaf page is extracted from the free-list, +** optimization 2 above is omitted if the corresponding bit is already +** set in BtShared.pHasContent. The contents of the bitvec are cleared +** at the end of every transaction. +*/ +static int btreeSetHasContent(BtShared *pBt, Pgno pgno){ + int rc = SQLITE_OK; + if( !pBt->pHasContent ){ + assert( pgno<=pBt->nPage ); + pBt->pHasContent = sqlite3BitvecCreate(pBt->nPage); + if( !pBt->pHasContent ){ + rc = SQLITE_NOMEM; + } + } + if( rc==SQLITE_OK && pgno<=sqlite3BitvecSize(pBt->pHasContent) ){ + rc = sqlite3BitvecSet(pBt->pHasContent, pgno); + } + return rc; +} + +/* +** Query the BtShared.pHasContent vector. +** +** This function is called when a free-list leaf page is removed from the +** free-list for reuse. It returns false if it is safe to retrieve the +** page from the pager layer with the 'no-content' flag set. True otherwise. +*/ +static int btreeGetHasContent(BtShared *pBt, Pgno pgno){ + Bitvec *p = pBt->pHasContent; + return (p && (pgno>sqlite3BitvecSize(p) || sqlite3BitvecTest(p, pgno))); +} + +/* +** Clear (destroy) the BtShared.pHasContent bitvec. This should be +** invoked at the conclusion of each write-transaction. +*/ +static void btreeClearHasContent(BtShared *pBt){ + sqlite3BitvecDestroy(pBt->pHasContent); + pBt->pHasContent = 0; +} + +/* +** Save the current cursor position in the variables BtCursor.nKey +** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK. +** +** The caller must ensure that the cursor is valid (has eState==CURSOR_VALID) +** prior to calling this routine. +*/ +static int saveCursorPosition(BtCursor *pCur){ + int rc; + + assert( CURSOR_VALID==pCur->eState ); + assert( 0==pCur->pKey ); + assert( cursorHoldsMutex(pCur) ); + + rc = sqlite3BtreeKeySize(pCur, &pCur->nKey); + assert( rc==SQLITE_OK ); /* KeySize() cannot fail */ + + /* If this is an intKey table, then the above call to BtreeKeySize() + ** stores the integer key in pCur->nKey. In this case this value is + ** all that is required. Otherwise, if pCur is not open on an intKey + ** table, then malloc space for and store the pCur->nKey bytes of key + ** data. + */ + if( 0==pCur->apPage[0]->intKey ){ + void *pKey = sqlite3Malloc( (int)pCur->nKey ); + if( pKey ){ + rc = sqlite3BtreeKey(pCur, 0, (int)pCur->nKey, pKey); + if( rc==SQLITE_OK ){ + pCur->pKey = pKey; + }else{ + sqlite3_free(pKey); + } + }else{ + rc = SQLITE_NOMEM; + } + } + assert( !pCur->apPage[0]->intKey || !pCur->pKey ); + + if( rc==SQLITE_OK ){ + int i; + for(i=0; i<=pCur->iPage; i++){ + releasePage(pCur->apPage[i]); + pCur->apPage[i] = 0; + } + pCur->iPage = -1; + pCur->eState = CURSOR_REQUIRESEEK; + } + + invalidateOverflowCache(pCur); + return rc; +} + +/* +** Save the positions of all cursors (except pExcept) that are open on +** the table with root-page iRoot. Usually, this is called just before cursor +** pExcept is used to modify the table (BtreeDelete() or BtreeInsert()). +*/ +static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){ + BtCursor *p; + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( pExcept==0 || pExcept->pBt==pBt ); + for(p=pBt->pCursor; p; p=p->pNext){ + if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) && + p->eState==CURSOR_VALID ){ + int rc = saveCursorPosition(p); + if( SQLITE_OK!=rc ){ + return rc; + } + } + } + return SQLITE_OK; +} + +/* +** Clear the current cursor position. +*/ +void sqlite3BtreeClearCursor(BtCursor *pCur){ + assert( cursorHoldsMutex(pCur) ); + sqlite3_free(pCur->pKey); + pCur->pKey = 0; + pCur->eState = CURSOR_INVALID; +} + +/* +** In this version of BtreeMoveto, pKey is a packed index record +** such as is generated by the OP_MakeRecord opcode. Unpack the +** record and then call BtreeMovetoUnpacked() to do the work. +*/ +static int btreeMoveto( + BtCursor *pCur, /* Cursor open on the btree to be searched */ + const void *pKey, /* Packed key if the btree is an index */ + i64 nKey, /* Integer key for tables. Size of pKey for indices */ + int bias, /* Bias search to the high end */ + int *pRes /* Write search results here */ +){ + int rc; /* Status code */ + UnpackedRecord *pIdxKey; /* Unpacked index key */ + char aSpace[150]; /* Temp space for pIdxKey - to avoid a malloc */ + char *pFree = 0; + + if( pKey ){ + assert( nKey==(i64)(int)nKey ); + pIdxKey = sqlite3VdbeAllocUnpackedRecord( + pCur->pKeyInfo, aSpace, sizeof(aSpace), &pFree + ); + if( pIdxKey==0 ) return SQLITE_NOMEM; + sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey); + }else{ + pIdxKey = 0; + } + rc = sqlite3BtreeMovetoUnpacked(pCur, pIdxKey, nKey, bias, pRes); + if( pFree ){ + sqlite3DbFree(pCur->pKeyInfo->db, pFree); + } + return rc; +} + +/* +** Restore the cursor to the position it was in (or as close to as possible) +** when saveCursorPosition() was called. Note that this call deletes the +** saved position info stored by saveCursorPosition(), so there can be +** at most one effective restoreCursorPosition() call after each +** saveCursorPosition(). +*/ +static int btreeRestoreCursorPosition(BtCursor *pCur){ + int rc; + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState>=CURSOR_REQUIRESEEK ); + if( pCur->eState==CURSOR_FAULT ){ + return pCur->skipNext; + } + pCur->eState = CURSOR_INVALID; + rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &pCur->skipNext); + if( rc==SQLITE_OK ){ + sqlite3_free(pCur->pKey); + pCur->pKey = 0; + assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID ); + } + return rc; +} + +#define restoreCursorPosition(p) \ + (p->eState>=CURSOR_REQUIRESEEK ? \ + btreeRestoreCursorPosition(p) : \ + SQLITE_OK) + +/* +** Determine whether or not a cursor has moved from the position it +** was last placed at. Cursors can move when the row they are pointing +** at is deleted out from under them. +** +** This routine returns an error code if something goes wrong. The +** integer *pHasMoved is set to one if the cursor has moved and 0 if not. +*/ +int sqlite3BtreeCursorHasMoved(BtCursor *pCur, int *pHasMoved){ + int rc; + + rc = restoreCursorPosition(pCur); + if( rc ){ + *pHasMoved = 1; + return rc; + } + if( pCur->eState!=CURSOR_VALID || pCur->skipNext!=0 ){ + *pHasMoved = 1; + }else{ + *pHasMoved = 0; + } + return SQLITE_OK; +} + +#ifndef SQLITE_OMIT_AUTOVACUUM +/* +** Given a page number of a regular database page, return the page +** number for the pointer-map page that contains the entry for the +** input page number. +** +** Return 0 (not a valid page) for pgno==1 since there is +** no pointer map associated with page 1. The integrity_check logic +** requires that ptrmapPageno(*,1)!=1. +*/ +static Pgno ptrmapPageno(BtShared *pBt, Pgno pgno){ + int nPagesPerMapPage; + Pgno iPtrMap, ret; + assert( sqlite3_mutex_held(pBt->mutex) ); + if( pgno<2 ) return 0; + nPagesPerMapPage = (pBt->usableSize/5)+1; + iPtrMap = (pgno-2)/nPagesPerMapPage; + ret = (iPtrMap*nPagesPerMapPage) + 2; + if( ret==PENDING_BYTE_PAGE(pBt) ){ + ret++; + } + return ret; +} + +/* +** Write an entry into the pointer map. +** +** This routine updates the pointer map entry for page number 'key' +** so that it maps to type 'eType' and parent page number 'pgno'. +** +** If *pRC is initially non-zero (non-SQLITE_OK) then this routine is +** a no-op. If an error occurs, the appropriate error code is written +** into *pRC. +*/ +static void ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent, int *pRC){ + DbPage *pDbPage; /* The pointer map page */ + u8 *pPtrmap; /* The pointer map data */ + Pgno iPtrmap; /* The pointer map page number */ + int offset; /* Offset in pointer map page */ + int rc; /* Return code from subfunctions */ + + if( *pRC ) return; + + assert( sqlite3_mutex_held(pBt->mutex) ); + /* The master-journal page number must never be used as a pointer map page */ + assert( 0==PTRMAP_ISPAGE(pBt, PENDING_BYTE_PAGE(pBt)) ); + + assert( pBt->autoVacuum ); + if( key==0 ){ + *pRC = SQLITE_CORRUPT_BKPT; + return; + } + iPtrmap = PTRMAP_PAGENO(pBt, key); + rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage); + if( rc!=SQLITE_OK ){ + *pRC = rc; + return; + } + offset = PTRMAP_PTROFFSET(iPtrmap, key); + if( offset<0 ){ + *pRC = SQLITE_CORRUPT_BKPT; + goto ptrmap_exit; + } + assert( offset <= (int)pBt->usableSize-5 ); + pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage); + + if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){ + TRACE(("PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent)); + *pRC= rc = sqlite3PagerWrite(pDbPage); + if( rc==SQLITE_OK ){ + pPtrmap[offset] = eType; + put4byte(&pPtrmap[offset+1], parent); + } + } + +ptrmap_exit: + sqlite3PagerUnref(pDbPage); +} + +/* +** Read an entry from the pointer map. +** +** This routine retrieves the pointer map entry for page 'key', writing +** the type and parent page number to *pEType and *pPgno respectively. +** An error code is returned if something goes wrong, otherwise SQLITE_OK. +*/ +static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){ + DbPage *pDbPage; /* The pointer map page */ + int iPtrmap; /* Pointer map page index */ + u8 *pPtrmap; /* Pointer map page data */ + int offset; /* Offset of entry in pointer map */ + int rc; + + assert( sqlite3_mutex_held(pBt->mutex) ); + + iPtrmap = PTRMAP_PAGENO(pBt, key); + rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage); + if( rc!=0 ){ + return rc; + } + pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage); + + offset = PTRMAP_PTROFFSET(iPtrmap, key); + if( offset<0 ){ + sqlite3PagerUnref(pDbPage); + return SQLITE_CORRUPT_BKPT; + } + assert( offset <= (int)pBt->usableSize-5 ); + assert( pEType!=0 ); + *pEType = pPtrmap[offset]; + if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]); + + sqlite3PagerUnref(pDbPage); + if( *pEType<1 || *pEType>5 ) return SQLITE_CORRUPT_BKPT; + return SQLITE_OK; +} + +#else /* if defined SQLITE_OMIT_AUTOVACUUM */ + #define ptrmapPut(w,x,y,z,rc) + #define ptrmapGet(w,x,y,z) SQLITE_OK + #define ptrmapPutOvflPtr(x, y, rc) +#endif + +/* +** Given a btree page and a cell index (0 means the first cell on +** the page, 1 means the second cell, and so forth) return a pointer +** to the cell content. +** +** This routine works only for pages that do not contain overflow cells. +*/ +#define findCell(P,I) \ + ((P)->aData + ((P)->maskPage & get2byte(&(P)->aCellIdx[2*(I)]))) +#define findCellv2(D,M,O,I) (D+(M&get2byte(D+(O+2*(I))))) + + +/* +** This a more complex version of findCell() that works for +** pages that do contain overflow cells. +*/ +static u8 *findOverflowCell(MemPage *pPage, int iCell){ + int i; + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + for(i=pPage->nOverflow-1; i>=0; i--){ + int k; + struct _OvflCell *pOvfl; + pOvfl = &pPage->aOvfl[i]; + k = pOvfl->idx; + if( k<=iCell ){ + if( k==iCell ){ + return pOvfl->pCell; + } + iCell--; + } + } + return findCell(pPage, iCell); +} + +/* +** Parse a cell content block and fill in the CellInfo structure. There +** are two versions of this function. btreeParseCell() takes a +** cell index as the second argument and btreeParseCellPtr() +** takes a pointer to the body of the cell as its second argument. +** +** Within this file, the parseCell() macro can be called instead of +** btreeParseCellPtr(). Using some compilers, this will be faster. +*/ +static void btreeParseCellPtr( + MemPage *pPage, /* Page containing the cell */ + u8 *pCell, /* Pointer to the cell text. */ + CellInfo *pInfo /* Fill in this structure */ +){ + u16 n; /* Number bytes in cell content header */ + u32 nPayload; /* Number of bytes of cell payload */ + + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + + pInfo->pCell = pCell; + assert( pPage->leaf==0 || pPage->leaf==1 ); + n = pPage->childPtrSize; + assert( n==4-4*pPage->leaf ); + if( pPage->intKey ){ + if( pPage->hasData ){ + n += getVarint32(&pCell[n], nPayload); + }else{ + nPayload = 0; + } + n += getVarint(&pCell[n], (u64*)&pInfo->nKey); + pInfo->nData = nPayload; + }else{ + pInfo->nData = 0; + n += getVarint32(&pCell[n], nPayload); + pInfo->nKey = nPayload; + } + pInfo->nPayload = nPayload; + pInfo->nHeader = n; + testcase( nPayload==pPage->maxLocal ); + testcase( nPayload==pPage->maxLocal+1 ); + if( likely(nPayload<=pPage->maxLocal) ){ + /* This is the (easy) common case where the entire payload fits + ** on the local page. No overflow is required. + */ + if( (pInfo->nSize = (u16)(n+nPayload))<4 ) pInfo->nSize = 4; + pInfo->nLocal = (u16)nPayload; + pInfo->iOverflow = 0; + }else{ + /* If the payload will not fit completely on the local page, we have + ** to decide how much to store locally and how much to spill onto + ** overflow pages. The strategy is to minimize the amount of unused + ** space on overflow pages while keeping the amount of local storage + ** in between minLocal and maxLocal. + ** + ** Warning: changing the way overflow payload is distributed in any + ** way will result in an incompatible file format. + */ + int minLocal; /* Minimum amount of payload held locally */ + int maxLocal; /* Maximum amount of payload held locally */ + int surplus; /* Overflow payload available for local storage */ + + minLocal = pPage->minLocal; + maxLocal = pPage->maxLocal; + surplus = minLocal + (nPayload - minLocal)%(pPage->pBt->usableSize - 4); + testcase( surplus==maxLocal ); + testcase( surplus==maxLocal+1 ); + if( surplus <= maxLocal ){ + pInfo->nLocal = (u16)surplus; + }else{ + pInfo->nLocal = (u16)minLocal; + } + pInfo->iOverflow = (u16)(pInfo->nLocal + n); + pInfo->nSize = pInfo->iOverflow + 4; + } +} +#define parseCell(pPage, iCell, pInfo) \ + btreeParseCellPtr((pPage), findCell((pPage), (iCell)), (pInfo)) +static void btreeParseCell( + MemPage *pPage, /* Page containing the cell */ + int iCell, /* The cell index. First cell is 0 */ + CellInfo *pInfo /* Fill in this structure */ +){ + parseCell(pPage, iCell, pInfo); +} + +/* +** Compute the total number of bytes that a Cell needs in the cell +** data area of the btree-page. The return number includes the cell +** data header and the local payload, but not any overflow page or +** the space used by the cell pointer. +*/ +static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ + u8 *pIter = &pCell[pPage->childPtrSize]; + u32 nSize; + +#ifdef SQLITE_DEBUG + /* The value returned by this function should always be the same as + ** the (CellInfo.nSize) value found by doing a full parse of the + ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of + ** this function verifies that this invariant is not violated. */ + CellInfo debuginfo; + btreeParseCellPtr(pPage, pCell, &debuginfo); +#endif + + if( pPage->intKey ){ + u8 *pEnd; + if( pPage->hasData ){ + pIter += getVarint32(pIter, nSize); + }else{ + nSize = 0; + } + + /* pIter now points at the 64-bit integer key value, a variable length + ** integer. The following block moves pIter to point at the first byte + ** past the end of the key value. */ + pEnd = &pIter[9]; + while( (*pIter++)&0x80 && pItermaxLocal ); + testcase( nSize==pPage->maxLocal+1 ); + if( nSize>pPage->maxLocal ){ + int minLocal = pPage->minLocal; + nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4); + testcase( nSize==pPage->maxLocal ); + testcase( nSize==pPage->maxLocal+1 ); + if( nSize>pPage->maxLocal ){ + nSize = minLocal; + } + nSize += 4; + } + nSize += (u32)(pIter - pCell); + + /* The minimum size of any cell is 4 bytes. */ + if( nSize<4 ){ + nSize = 4; + } + + assert( nSize==debuginfo.nSize ); + return (u16)nSize; +} + +#ifdef SQLITE_DEBUG +/* This variation on cellSizePtr() is used inside of assert() statements +** only. */ +static u16 cellSize(MemPage *pPage, int iCell){ + return cellSizePtr(pPage, findCell(pPage, iCell)); +} +#endif + +#ifndef SQLITE_OMIT_AUTOVACUUM +/* +** If the cell pCell, part of page pPage contains a pointer +** to an overflow page, insert an entry into the pointer-map +** for the overflow page. +*/ +static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){ + CellInfo info; + if( *pRC ) return; + assert( pCell!=0 ); + btreeParseCellPtr(pPage, pCell, &info); + assert( (info.nData+(pPage->intKey?0:info.nKey))==info.nPayload ); + if( info.iOverflow ){ + Pgno ovfl = get4byte(&pCell[info.iOverflow]); + ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC); + } +} +#endif + + +/* +** Defragment the page given. All Cells are moved to the +** end of the page and all free space is collected into one +** big FreeBlk that occurs in between the header and cell +** pointer array and the cell content area. +*/ +static int defragmentPage(MemPage *pPage){ + int i; /* Loop counter */ + int pc; /* Address of a i-th cell */ + int hdr; /* Offset to the page header */ + int size; /* Size of a cell */ + int usableSize; /* Number of usable bytes on a page */ + int cellOffset; /* Offset to the cell pointer array */ + int cbrk; /* Offset to the cell content area */ + int nCell; /* Number of cells on the page */ + unsigned char *data; /* The page data */ + unsigned char *temp; /* Temp area for cell content */ + int iCellFirst; /* First allowable cell index */ + int iCellLast; /* Last possible cell index */ + + + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + assert( pPage->pBt!=0 ); + assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE ); + assert( pPage->nOverflow==0 ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + temp = sqlite3PagerTempSpace(pPage->pBt->pPager); + data = pPage->aData; + hdr = pPage->hdrOffset; + cellOffset = pPage->cellOffset; + nCell = pPage->nCell; + assert( nCell==get2byte(&data[hdr+3]) ); + usableSize = pPage->pBt->usableSize; + cbrk = get2byte(&data[hdr+5]); + memcpy(&temp[cbrk], &data[cbrk], usableSize - cbrk); + cbrk = usableSize; + iCellFirst = cellOffset + 2*nCell; + iCellLast = usableSize - 4; + for(i=0; iiCellLast ){ + return SQLITE_CORRUPT_BKPT; + } +#endif + assert( pc>=iCellFirst && pc<=iCellLast ); + size = cellSizePtr(pPage, &temp[pc]); + cbrk -= size; +#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK) + if( cbrkusableSize ){ + return SQLITE_CORRUPT_BKPT; + } +#endif + assert( cbrk+size<=usableSize && cbrk>=iCellFirst ); + testcase( cbrk+size==usableSize ); + testcase( pc+size==usableSize ); + memcpy(&data[cbrk], &temp[pc], size); + put2byte(pAddr, cbrk); + } + assert( cbrk>=iCellFirst ); + put2byte(&data[hdr+5], cbrk); + data[hdr+1] = 0; + data[hdr+2] = 0; + data[hdr+7] = 0; + memset(&data[iCellFirst], 0, cbrk-iCellFirst); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + if( cbrk-iCellFirst!=pPage->nFree ){ + return SQLITE_CORRUPT_BKPT; + } + return SQLITE_OK; +} + +/* +** Allocate nByte bytes of space from within the B-Tree page passed +** as the first argument. Write into *pIdx the index into pPage->aData[] +** of the first byte of allocated space. Return either SQLITE_OK or +** an error code (usually SQLITE_CORRUPT). +** +** The caller guarantees that there is sufficient space to make the +** allocation. This routine might need to defragment in order to bring +** all the space together, however. This routine will avoid using +** the first two bytes past the cell pointer area since presumably this +** allocation is being made in order to insert a new cell, so we will +** also end up needing a new cell pointer. +*/ +static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ + const int hdr = pPage->hdrOffset; /* Local cache of pPage->hdrOffset */ + u8 * const data = pPage->aData; /* Local cache of pPage->aData */ + int nFrag; /* Number of fragmented bytes on pPage */ + int top; /* First byte of cell content area */ + int gap; /* First byte of gap between cell pointers and cell content */ + int rc; /* Integer return code */ + int usableSize; /* Usable size of the page */ + + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + assert( pPage->pBt ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( nByte>=0 ); /* Minimum cell size is 4 */ + assert( pPage->nFree>=nByte ); + assert( pPage->nOverflow==0 ); + usableSize = pPage->pBt->usableSize; + assert( nByte < usableSize-8 ); + + nFrag = data[hdr+7]; + assert( pPage->cellOffset == hdr + 12 - 4*pPage->leaf ); + gap = pPage->cellOffset + 2*pPage->nCell; + top = get2byteNotZero(&data[hdr+5]); + if( gap>top ) return SQLITE_CORRUPT_BKPT; + testcase( gap+2==top ); + testcase( gap+1==top ); + testcase( gap==top ); + + if( nFrag>=60 ){ + /* Always defragment highly fragmented pages */ + rc = defragmentPage(pPage); + if( rc ) return rc; + top = get2byteNotZero(&data[hdr+5]); + }else if( gap+2<=top ){ + /* Search the freelist looking for a free slot big enough to satisfy + ** the request. The allocation is made from the first free slot in + ** the list that is large enough to accomadate it. + */ + int pc, addr; + for(addr=hdr+1; (pc = get2byte(&data[addr]))>0; addr=pc){ + int size; /* Size of the free slot */ + if( pc>usableSize-4 || pc=nByte ){ + int x = size - nByte; + testcase( x==4 ); + testcase( x==3 ); + if( x<4 ){ + /* Remove the slot from the free-list. Update the number of + ** fragmented bytes within the page. */ + memcpy(&data[addr], &data[pc], 2); + data[hdr+7] = (u8)(nFrag + x); + }else if( size+pc > usableSize ){ + return SQLITE_CORRUPT_BKPT; + }else{ + /* The slot remains on the free-list. Reduce its size to account + ** for the portion used by the new allocation. */ + put2byte(&data[pc+2], x); + } + *pIdx = pc + x; + return SQLITE_OK; + } + } + } + + /* Check to make sure there is enough space in the gap to satisfy + ** the allocation. If not, defragment. + */ + testcase( gap+2+nByte==top ); + if( gap+2+nByte>top ){ + rc = defragmentPage(pPage); + if( rc ) return rc; + top = get2byteNotZero(&data[hdr+5]); + assert( gap+nByte<=top ); + } + + + /* Allocate memory from the gap in between the cell pointer array + ** and the cell content area. The btreeInitPage() call has already + ** validated the freelist. Given that the freelist is valid, there + ** is no way that the allocation can extend off the end of the page. + ** The assert() below verifies the previous sentence. + */ + top -= nByte; + put2byte(&data[hdr+5], top); + assert( top+nByte <= (int)pPage->pBt->usableSize ); + *pIdx = top; + return SQLITE_OK; +} + +/* +** Return a section of the pPage->aData to the freelist. +** The first byte of the new free block is pPage->aDisk[start] +** and the size of the block is "size" bytes. +** +** Most of the effort here is involved in coalesing adjacent +** free blocks into a single big free block. +*/ +static int freeSpace(MemPage *pPage, int start, int size){ + int addr, pbegin, hdr; + int iLast; /* Largest possible freeblock offset */ + unsigned char *data = pPage->aData; + + assert( pPage->pBt!=0 ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + assert( start>=pPage->hdrOffset+6+pPage->childPtrSize ); + assert( (start + size) <= (int)pPage->pBt->usableSize ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( size>=0 ); /* Minimum cell size is 4 */ + + if( pPage->pBt->btsFlags & BTS_SECURE_DELETE ){ + /* Overwrite deleted information with zeros when the secure_delete + ** option is enabled */ + memset(&data[start], 0, size); + } + + /* Add the space back into the linked list of freeblocks. Note that + ** even though the freeblock list was checked by btreeInitPage(), + ** btreeInitPage() did not detect overlapping cells or + ** freeblocks that overlapped cells. Nor does it detect when the + ** cell content area exceeds the value in the page header. If these + ** situations arise, then subsequent insert operations might corrupt + ** the freelist. So we do need to check for corruption while scanning + ** the freelist. + */ + hdr = pPage->hdrOffset; + addr = hdr + 1; + iLast = pPage->pBt->usableSize - 4; + assert( start<=iLast ); + while( (pbegin = get2byte(&data[addr]))0 ){ + if( pbeginiLast ){ + return SQLITE_CORRUPT_BKPT; + } + assert( pbegin>addr || pbegin==0 ); + put2byte(&data[addr], start); + put2byte(&data[start], pbegin); + put2byte(&data[start+2], size); + pPage->nFree = pPage->nFree + (u16)size; + + /* Coalesce adjacent free blocks */ + addr = hdr + 1; + while( (pbegin = get2byte(&data[addr]))>0 ){ + int pnext, psize, x; + assert( pbegin>addr ); + assert( pbegin <= (int)pPage->pBt->usableSize-4 ); + pnext = get2byte(&data[pbegin]); + psize = get2byte(&data[pbegin+2]); + if( pbegin + psize + 3 >= pnext && pnext>0 ){ + int frag = pnext - (pbegin+psize); + if( (frag<0) || (frag>(int)data[hdr+7]) ){ + return SQLITE_CORRUPT_BKPT; + } + data[hdr+7] -= (u8)frag; + x = get2byte(&data[pnext]); + put2byte(&data[pbegin], x); + x = pnext + get2byte(&data[pnext+2]) - pbegin; + put2byte(&data[pbegin+2], x); + }else{ + addr = pbegin; + } + } + + /* If the cell content area begins with a freeblock, remove it. */ + if( data[hdr+1]==data[hdr+5] && data[hdr+2]==data[hdr+6] ){ + int top; + pbegin = get2byte(&data[hdr+1]); + memcpy(&data[hdr+1], &data[pbegin], 2); + top = get2byte(&data[hdr+5]) + get2byte(&data[pbegin+2]); + put2byte(&data[hdr+5], top); + } + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + return SQLITE_OK; +} + +/* +** Decode the flags byte (the first byte of the header) for a page +** and initialize fields of the MemPage structure accordingly. +** +** Only the following combinations are supported. Anything different +** indicates a corrupt database files: +** +** PTF_ZERODATA +** PTF_ZERODATA | PTF_LEAF +** PTF_LEAFDATA | PTF_INTKEY +** PTF_LEAFDATA | PTF_INTKEY | PTF_LEAF +*/ +static int decodeFlags(MemPage *pPage, int flagByte){ + BtShared *pBt; /* A copy of pPage->pBt */ + + assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + pPage->leaf = (u8)(flagByte>>3); assert( PTF_LEAF == 1<<3 ); + flagByte &= ~PTF_LEAF; + pPage->childPtrSize = 4-4*pPage->leaf; + pBt = pPage->pBt; + if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){ + pPage->intKey = 1; + pPage->hasData = pPage->leaf; + pPage->maxLocal = pBt->maxLeaf; + pPage->minLocal = pBt->minLeaf; + }else if( flagByte==PTF_ZERODATA ){ + pPage->intKey = 0; + pPage->hasData = 0; + pPage->maxLocal = pBt->maxLocal; + pPage->minLocal = pBt->minLocal; + }else{ + return SQLITE_CORRUPT_BKPT; + } + pPage->max1bytePayload = pBt->max1bytePayload; + return SQLITE_OK; +} + +/* +** Initialize the auxiliary information for a disk block. +** +** Return SQLITE_OK on success. If we see that the page does +** not contain a well-formed database page, then return +** SQLITE_CORRUPT. Note that a return of SQLITE_OK does not +** guarantee that the page is well-formed. It only shows that +** we failed to detect any corruption. +*/ +static int btreeInitPage(MemPage *pPage){ + + assert( pPage->pBt!=0 ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) ); + assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) ); + assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) ); + + if( !pPage->isInit ){ + u16 pc; /* Address of a freeblock within pPage->aData[] */ + u8 hdr; /* Offset to beginning of page header */ + u8 *data; /* Equal to pPage->aData */ + BtShared *pBt; /* The main btree structure */ + int usableSize; /* Amount of usable space on each page */ + u16 cellOffset; /* Offset from start of page to first cell pointer */ + int nFree; /* Number of unused bytes on the page */ + int top; /* First byte of the cell content area */ + int iCellFirst; /* First allowable cell or freeblock offset */ + int iCellLast; /* Last possible cell or freeblock offset */ + + pBt = pPage->pBt; + + hdr = pPage->hdrOffset; + data = pPage->aData; + if( decodeFlags(pPage, data[hdr]) ) return SQLITE_CORRUPT_BKPT; + assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); + pPage->maskPage = (u16)(pBt->pageSize - 1); + pPage->nOverflow = 0; + usableSize = pBt->usableSize; + pPage->cellOffset = cellOffset = hdr + 12 - 4*pPage->leaf; + pPage->aDataEnd = &data[usableSize]; + pPage->aCellIdx = &data[cellOffset]; + top = get2byteNotZero(&data[hdr+5]); + pPage->nCell = get2byte(&data[hdr+3]); + if( pPage->nCell>MX_CELL(pBt) ){ + /* To many cells for a single page. The page must be corrupt */ + return SQLITE_CORRUPT_BKPT; + } + testcase( pPage->nCell==MX_CELL(pBt) ); + + /* A malformed database page might cause us to read past the end + ** of page when parsing a cell. + ** + ** The following block of code checks early to see if a cell extends + ** past the end of a page boundary and causes SQLITE_CORRUPT to be + ** returned if it does. + */ + iCellFirst = cellOffset + 2*pPage->nCell; + iCellLast = usableSize - 4; +#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK) + { + int i; /* Index into the cell pointer array */ + int sz; /* Size of a cell */ + + if( !pPage->leaf ) iCellLast--; + for(i=0; inCell; i++){ + pc = get2byte(&data[cellOffset+i*2]); + testcase( pc==iCellFirst ); + testcase( pc==iCellLast ); + if( pciCellLast ){ + return SQLITE_CORRUPT_BKPT; + } + sz = cellSizePtr(pPage, &data[pc]); + testcase( pc+sz==usableSize ); + if( pc+sz>usableSize ){ + return SQLITE_CORRUPT_BKPT; + } + } + if( !pPage->leaf ) iCellLast++; + } +#endif + + /* Compute the total free space on the page */ + pc = get2byte(&data[hdr+1]); + nFree = data[hdr+7] + top; + while( pc>0 ){ + u16 next, size; + if( pciCellLast ){ + /* Start of free block is off the page */ + return SQLITE_CORRUPT_BKPT; + } + next = get2byte(&data[pc]); + size = get2byte(&data[pc+2]); + if( (next>0 && next<=pc+size+3) || pc+size>usableSize ){ + /* Free blocks must be in ascending order. And the last byte of + ** the free-block must lie on the database page. */ + return SQLITE_CORRUPT_BKPT; + } + nFree = nFree + size; + pc = next; + } + + /* At this point, nFree contains the sum of the offset to the start + ** of the cell-content area plus the number of free bytes within + ** the cell-content area. If this is greater than the usable-size + ** of the page, then the page must be corrupted. This check also + ** serves to verify that the offset to the start of the cell-content + ** area, according to the page header, lies within the page. + */ + if( nFree>usableSize ){ + return SQLITE_CORRUPT_BKPT; + } + pPage->nFree = (u16)(nFree - iCellFirst); + pPage->isInit = 1; + } + return SQLITE_OK; +} + +/* +** Set up a raw page so that it looks like a database page holding +** no entries. +*/ +static void zeroPage(MemPage *pPage, int flags){ + unsigned char *data = pPage->aData; + BtShared *pBt = pPage->pBt; + u8 hdr = pPage->hdrOffset; + u16 first; + + assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno ); + assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); + assert( sqlite3PagerGetData(pPage->pDbPage) == data ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + assert( sqlite3_mutex_held(pBt->mutex) ); + if( pBt->btsFlags & BTS_SECURE_DELETE ){ + memset(&data[hdr], 0, pBt->usableSize - hdr); + } + data[hdr] = (char)flags; + first = hdr + 8 + 4*((flags&PTF_LEAF)==0 ?1:0); + memset(&data[hdr+1], 0, 4); + data[hdr+7] = 0; + put2byte(&data[hdr+5], pBt->usableSize); + pPage->nFree = (u16)(pBt->usableSize - first); + decodeFlags(pPage, flags); + pPage->hdrOffset = hdr; + pPage->cellOffset = first; + pPage->aDataEnd = &data[pBt->usableSize]; + pPage->aCellIdx = &data[first]; + pPage->nOverflow = 0; + assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); + pPage->maskPage = (u16)(pBt->pageSize - 1); + pPage->nCell = 0; + pPage->isInit = 1; +} + + +/* +** Convert a DbPage obtained from the pager into a MemPage used by +** the btree layer. +*/ +static MemPage *btreePageFromDbPage(DbPage *pDbPage, Pgno pgno, BtShared *pBt){ + MemPage *pPage = (MemPage*)sqlite3PagerGetExtra(pDbPage); + pPage->aData = sqlite3PagerGetData(pDbPage); + pPage->pDbPage = pDbPage; + pPage->pBt = pBt; + pPage->pgno = pgno; + pPage->hdrOffset = pPage->pgno==1 ? 100 : 0; + return pPage; +} + +/* +** Get a page from the pager. Initialize the MemPage.pBt and +** MemPage.aData elements if needed. +** +** If the noContent flag is set, it means that we do not care about +** the content of the page at this time. So do not go to the disk +** to fetch the content. Just fill in the content with zeros for now. +** If in the future we call sqlite3PagerWrite() on this page, that +** means we have started to be concerned about content and the disk +** read should occur at that point. +*/ +static int btreeGetPage( + BtShared *pBt, /* The btree */ + Pgno pgno, /* Number of the page to fetch */ + MemPage **ppPage, /* Return the page in this parameter */ + int noContent /* Do not load page content if true */ +){ + int rc; + DbPage *pDbPage; + + assert( sqlite3_mutex_held(pBt->mutex) ); + rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, noContent); + if( rc ) return rc; + *ppPage = btreePageFromDbPage(pDbPage, pgno, pBt); + return SQLITE_OK; +} + +/* +** Retrieve a page from the pager cache. If the requested page is not +** already in the pager cache return NULL. Initialize the MemPage.pBt and +** MemPage.aData elements if needed. +*/ +static MemPage *btreePageLookup(BtShared *pBt, Pgno pgno){ + DbPage *pDbPage; + assert( sqlite3_mutex_held(pBt->mutex) ); + pDbPage = sqlite3PagerLookup(pBt->pPager, pgno); + if( pDbPage ){ + return btreePageFromDbPage(pDbPage, pgno, pBt); + } + return 0; +} + +/* +** Return the size of the database file in pages. If there is any kind of +** error, return ((unsigned int)-1). +*/ +static Pgno btreePagecount(BtShared *pBt){ + return pBt->nPage; +} +u32 sqlite3BtreeLastPage(Btree *p){ + assert( sqlite3BtreeHoldsMutex(p) ); + assert( ((p->pBt->nPage)&0x8000000)==0 ); + return (int)btreePagecount(p->pBt); +} + +/* +** Get a page from the pager and initialize it. This routine is just a +** convenience wrapper around separate calls to btreeGetPage() and +** btreeInitPage(). +** +** If an error occurs, then the value *ppPage is set to is undefined. It +** may remain unchanged, or it may be set to an invalid value. +*/ +static int getAndInitPage( + BtShared *pBt, /* The database file */ + Pgno pgno, /* Number of the page to get */ + MemPage **ppPage /* Write the page pointer here */ +){ + int rc; + assert( sqlite3_mutex_held(pBt->mutex) ); + + if( pgno>btreePagecount(pBt) ){ + rc = SQLITE_CORRUPT_BKPT; + }else{ + rc = btreeGetPage(pBt, pgno, ppPage, 0); + if( rc==SQLITE_OK ){ + rc = btreeInitPage(*ppPage); + if( rc!=SQLITE_OK ){ + releasePage(*ppPage); + } + } + } + + testcase( pgno==0 ); + assert( pgno!=0 || rc==SQLITE_CORRUPT ); + return rc; +} + +/* +** Release a MemPage. This should be called once for each prior +** call to btreeGetPage. +*/ +static void releasePage(MemPage *pPage){ + if( pPage ){ + assert( pPage->aData ); + assert( pPage->pBt ); + assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); + assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + sqlite3PagerUnref(pPage->pDbPage); + } +} + +/* +** During a rollback, when the pager reloads information into the cache +** so that the cache is restored to its original state at the start of +** the transaction, for each page restored this routine is called. +** +** This routine needs to reset the extra data section at the end of the +** page to agree with the restored data. +*/ +static void pageReinit(DbPage *pData){ + MemPage *pPage; + pPage = (MemPage *)sqlite3PagerGetExtra(pData); + assert( sqlite3PagerPageRefcount(pData)>0 ); + if( pPage->isInit ){ + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + pPage->isInit = 0; + if( sqlite3PagerPageRefcount(pData)>1 ){ + /* pPage might not be a btree page; it might be an overflow page + ** or ptrmap page or a free page. In those cases, the following + ** call to btreeInitPage() will likely return SQLITE_CORRUPT. + ** But no harm is done by this. And it is very important that + ** btreeInitPage() be called on every btree page so we make + ** the call for every page that comes in for re-initing. */ + btreeInitPage(pPage); + } + } +} + +/* +** Invoke the busy handler for a btree. +*/ +static int btreeInvokeBusyHandler(void *pArg){ + BtShared *pBt = (BtShared*)pArg; + assert( pBt->db ); + assert( sqlite3_mutex_held(pBt->db->mutex) ); + return sqlite3InvokeBusyHandler(&pBt->db->busyHandler); +} + +/* +** Open a database file. +** +** zFilename is the name of the database file. If zFilename is NULL +** then an ephemeral database is created. The ephemeral database might +** be exclusively in memory, or it might use a disk-based memory cache. +** Either way, the ephemeral database will be automatically deleted +** when sqlite3BtreeClose() is called. +** +** If zFilename is ":memory:" then an in-memory database is created +** that is automatically destroyed when it is closed. +** +** The "flags" parameter is a bitmask that might contain bits +** BTREE_OMIT_JOURNAL and/or BTREE_NO_READLOCK. The BTREE_NO_READLOCK +** bit is also set if the SQLITE_NoReadlock flags is set in db->flags. +** These flags are passed through into sqlite3PagerOpen() and must +** be the same values as PAGER_OMIT_JOURNAL and PAGER_NO_READLOCK. +** +** If the database is already opened in the same database connection +** and we are in shared cache mode, then the open will fail with an +** SQLITE_CONSTRAINT error. We cannot allow two or more BtShared +** objects in the same database connection since doing so will lead +** to problems with locking. +*/ +int sqlite3BtreeOpen( + sqlite3_vfs *pVfs, /* VFS to use for this b-tree */ + const char *zFilename, /* Name of the file containing the BTree database */ + sqlite3 *db, /* Associated database handle */ + Btree **ppBtree, /* Pointer to new Btree object written here */ + int flags, /* Options */ + int vfsFlags /* Flags passed through to sqlite3_vfs.xOpen() */ +){ + BtShared *pBt = 0; /* Shared part of btree structure */ + Btree *p; /* Handle to return */ + sqlite3_mutex *mutexOpen = 0; /* Prevents a race condition. Ticket #3537 */ + int rc = SQLITE_OK; /* Result code from this function */ + u8 nReserve; /* Byte of unused space on each page */ + unsigned char zDbHeader[100]; /* Database header content */ + + /* True if opening an ephemeral, temporary database */ + const int isTempDb = zFilename==0 || zFilename[0]==0; + + /* Set the variable isMemdb to true for an in-memory database, or + ** false for a file-based database. + */ +#ifdef SQLITE_OMIT_MEMORYDB + const int isMemdb = 0; +#else + const int isMemdb = (zFilename && strcmp(zFilename, ":memory:")==0) + || (isTempDb && sqlite3TempInMemory(db)); +#endif + + assert( db!=0 ); + assert( pVfs!=0 ); + assert( sqlite3_mutex_held(db->mutex) ); + assert( (flags&0xff)==flags ); /* flags fit in 8 bits */ + + /* Only a BTREE_SINGLE database can be BTREE_UNORDERED */ + assert( (flags & BTREE_UNORDERED)==0 || (flags & BTREE_SINGLE)!=0 ); + + /* A BTREE_SINGLE database is always a temporary and/or ephemeral */ + assert( (flags & BTREE_SINGLE)==0 || isTempDb ); + + if( db->flags & SQLITE_NoReadlock ){ + flags |= BTREE_NO_READLOCK; + } + if( isMemdb ){ + flags |= BTREE_MEMORY; + } + if( (vfsFlags & SQLITE_OPEN_MAIN_DB)!=0 && (isMemdb || isTempDb) ){ + vfsFlags = (vfsFlags & ~SQLITE_OPEN_MAIN_DB) | SQLITE_OPEN_TEMP_DB; + } + p = sqlite3MallocZero(sizeof(Btree)); + if( !p ){ + return SQLITE_NOMEM; + } + p->inTrans = TRANS_NONE; + p->db = db; +#ifndef SQLITE_OMIT_SHARED_CACHE + p->lock.pBtree = p; + p->lock.iTable = 1; +#endif + +#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) + /* + ** If this Btree is a candidate for shared cache, try to find an + ** existing BtShared object that we can share with + */ + if( isMemdb==0 && isTempDb==0 ){ + if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){ + int nFullPathname = pVfs->mxPathname+1; + char *zFullPathname = sqlite3Malloc(nFullPathname); + MUTEX_LOGIC( sqlite3_mutex *mutexShared; ) + p->sharable = 1; + if( !zFullPathname ){ + sqlite3_free(p); + return SQLITE_NOMEM; + } + rc = sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname); + if( rc ){ + sqlite3_free(zFullPathname); + sqlite3_free(p); + return rc; + } +#if SQLITE_THREADSAFE + mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN); + sqlite3_mutex_enter(mutexOpen); + mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); + sqlite3_mutex_enter(mutexShared); +#endif + for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){ + assert( pBt->nRef>0 ); + if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager)) + && sqlite3PagerVfs(pBt->pPager)==pVfs ){ + int iDb; + for(iDb=db->nDb-1; iDb>=0; iDb--){ + Btree *pExisting = db->aDb[iDb].pBt; + if( pExisting && pExisting->pBt==pBt ){ + sqlite3_mutex_leave(mutexShared); + sqlite3_mutex_leave(mutexOpen); + sqlite3_free(zFullPathname); + sqlite3_free(p); + return SQLITE_CONSTRAINT; + } + } + p->pBt = pBt; + pBt->nRef++; + break; + } + } + sqlite3_mutex_leave(mutexShared); + sqlite3_free(zFullPathname); + } +#ifdef SQLITE_DEBUG + else{ + /* In debug mode, we mark all persistent databases as sharable + ** even when they are not. This exercises the locking code and + ** gives more opportunity for asserts(sqlite3_mutex_held()) + ** statements to find locking problems. + */ + p->sharable = 1; + } +#endif + } +#endif + if( pBt==0 ){ + /* + ** The following asserts make sure that structures used by the btree are + ** the right size. This is to guard against size changes that result + ** when compiling on a different architecture. + */ + assert( sizeof(i64)==8 || sizeof(i64)==4 ); + assert( sizeof(u64)==8 || sizeof(u64)==4 ); + assert( sizeof(u32)==4 ); + assert( sizeof(u16)==2 ); + assert( sizeof(Pgno)==4 ); + + pBt = sqlite3MallocZero( sizeof(*pBt) ); + if( pBt==0 ){ + rc = SQLITE_NOMEM; + goto btree_open_out; + } + rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename, + EXTRA_SIZE, flags, vfsFlags, pageReinit); + if( rc==SQLITE_OK ){ + rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader); + } + if( rc!=SQLITE_OK ){ + goto btree_open_out; + } + pBt->openFlags = (u8)flags; + pBt->db = db; + sqlite3PagerSetBusyhandler(pBt->pPager, btreeInvokeBusyHandler, pBt); + p->pBt = pBt; + + pBt->pCursor = 0; + pBt->pPage1 = 0; + if( sqlite3PagerIsreadonly(pBt->pPager) ) pBt->btsFlags |= BTS_READ_ONLY; +#ifdef SQLITE_SECURE_DELETE + pBt->btsFlags |= BTS_SECURE_DELETE; +#endif + pBt->pageSize = (zDbHeader[16]<<8) | (zDbHeader[17]<<16); + if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE + || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){ + pBt->pageSize = 0; +#ifndef SQLITE_OMIT_AUTOVACUUM + /* If the magic name ":memory:" will create an in-memory database, then + ** leave the autoVacuum mode at 0 (do not auto-vacuum), even if + ** SQLITE_DEFAULT_AUTOVACUUM is true. On the other hand, if + ** SQLITE_OMIT_MEMORYDB has been defined, then ":memory:" is just a + ** regular file-name. In this case the auto-vacuum applies as per normal. + */ + if( zFilename && !isMemdb ){ + pBt->autoVacuum = (SQLITE_DEFAULT_AUTOVACUUM ? 1 : 0); + pBt->incrVacuum = (SQLITE_DEFAULT_AUTOVACUUM==2 ? 1 : 0); + } +#endif + nReserve = 0; + }else{ + nReserve = zDbHeader[20]; + pBt->btsFlags |= BTS_PAGESIZE_FIXED; +#ifndef SQLITE_OMIT_AUTOVACUUM + pBt->autoVacuum = (get4byte(&zDbHeader[36 + 4*4])?1:0); + pBt->incrVacuum = (get4byte(&zDbHeader[36 + 7*4])?1:0); +#endif + } + rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve); + if( rc ) goto btree_open_out; + pBt->usableSize = pBt->pageSize - nReserve; + assert( (pBt->pageSize & 7)==0 ); /* 8-byte alignment of pageSize */ + +#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) + /* Add the new BtShared object to the linked list sharable BtShareds. + */ + if( p->sharable ){ + MUTEX_LOGIC( sqlite3_mutex *mutexShared; ) + pBt->nRef = 1; + MUTEX_LOGIC( mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);) + if( SQLITE_THREADSAFE && sqlite3GlobalConfig.bCoreMutex ){ + pBt->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST); + if( pBt->mutex==0 ){ + rc = SQLITE_NOMEM; + db->mallocFailed = 0; + goto btree_open_out; + } + } + sqlite3_mutex_enter(mutexShared); + pBt->pNext = GLOBAL(BtShared*,sqlite3SharedCacheList); + GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt; + sqlite3_mutex_leave(mutexShared); + } +#endif + } + +#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) + /* If the new Btree uses a sharable pBtShared, then link the new + ** Btree into the list of all sharable Btrees for the same connection. + ** The list is kept in ascending order by pBt address. + */ + if( p->sharable ){ + int i; + Btree *pSib; + for(i=0; inDb; i++){ + if( (pSib = db->aDb[i].pBt)!=0 && pSib->sharable ){ + while( pSib->pPrev ){ pSib = pSib->pPrev; } + if( p->pBtpBt ){ + p->pNext = pSib; + p->pPrev = 0; + pSib->pPrev = p; + }else{ + while( pSib->pNext && pSib->pNext->pBtpBt ){ + pSib = pSib->pNext; + } + p->pNext = pSib->pNext; + p->pPrev = pSib; + if( p->pNext ){ + p->pNext->pPrev = p; + } + pSib->pNext = p; + } + break; + } + } + } +#endif + *ppBtree = p; + +btree_open_out: + if( rc!=SQLITE_OK ){ + if( pBt && pBt->pPager ){ + sqlite3PagerClose(pBt->pPager); + } + sqlite3_free(pBt); + sqlite3_free(p); + *ppBtree = 0; + }else{ + /* If the B-Tree was successfully opened, set the pager-cache size to the + ** default value. Except, when opening on an existing shared pager-cache, + ** do not change the pager-cache size. + */ + if( sqlite3BtreeSchema(p, 0, 0)==0 ){ + sqlite3PagerSetCachesize(p->pBt->pPager, SQLITE_DEFAULT_CACHE_SIZE); + } + } + if( mutexOpen ){ + assert( sqlite3_mutex_held(mutexOpen) ); + sqlite3_mutex_leave(mutexOpen); + } + return rc; +} + +/* +** Decrement the BtShared.nRef counter. When it reaches zero, +** remove the BtShared structure from the sharing list. Return +** true if the BtShared.nRef counter reaches zero and return +** false if it is still positive. +*/ +static int removeFromSharingList(BtShared *pBt){ +#ifndef SQLITE_OMIT_SHARED_CACHE + MUTEX_LOGIC( sqlite3_mutex *pMaster; ) + BtShared *pList; + int removed = 0; + + assert( sqlite3_mutex_notheld(pBt->mutex) ); + MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) + sqlite3_mutex_enter(pMaster); + pBt->nRef--; + if( pBt->nRef<=0 ){ + if( GLOBAL(BtShared*,sqlite3SharedCacheList)==pBt ){ + GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt->pNext; + }else{ + pList = GLOBAL(BtShared*,sqlite3SharedCacheList); + while( ALWAYS(pList) && pList->pNext!=pBt ){ + pList=pList->pNext; + } + if( ALWAYS(pList) ){ + pList->pNext = pBt->pNext; + } + } + if( SQLITE_THREADSAFE ){ + sqlite3_mutex_free(pBt->mutex); + } + removed = 1; + } + sqlite3_mutex_leave(pMaster); + return removed; +#else + return 1; +#endif +} + +/* +** Make sure pBt->pTmpSpace points to an allocation of +** MX_CELL_SIZE(pBt) bytes. +*/ +static void allocateTempSpace(BtShared *pBt){ + if( !pBt->pTmpSpace ){ + pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize ); + } +} + +/* +** Free the pBt->pTmpSpace allocation +*/ +static void freeTempSpace(BtShared *pBt){ + sqlite3PageFree( pBt->pTmpSpace); + pBt->pTmpSpace = 0; +} + +/* +** Close an open database and invalidate all cursors. +*/ +int sqlite3BtreeClose(Btree *p){ + BtShared *pBt = p->pBt; + BtCursor *pCur; + + /* Close all cursors opened via this handle. */ + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + pCur = pBt->pCursor; + while( pCur ){ + BtCursor *pTmp = pCur; + pCur = pCur->pNext; + if( pTmp->pBtree==p ){ + sqlite3BtreeCloseCursor(pTmp); + } + } + + /* Rollback any active transaction and free the handle structure. + ** The call to sqlite3BtreeRollback() drops any table-locks held by + ** this handle. + */ + sqlite3BtreeRollback(p); + sqlite3BtreeLeave(p); + + /* If there are still other outstanding references to the shared-btree + ** structure, return now. The remainder of this procedure cleans + ** up the shared-btree. + */ + assert( p->wantToLock==0 && p->locked==0 ); + if( !p->sharable || removeFromSharingList(pBt) ){ + /* The pBt is no longer on the sharing list, so we can access + ** it without having to hold the mutex. + ** + ** Clean out and delete the BtShared object. + */ + assert( !pBt->pCursor ); + sqlite3PagerClose(pBt->pPager); + if( pBt->xFreeSchema && pBt->pSchema ){ + pBt->xFreeSchema(pBt->pSchema); + } + sqlite3DbFree(0, pBt->pSchema); + freeTempSpace(pBt); + sqlite3_free(pBt); + } + +#ifndef SQLITE_OMIT_SHARED_CACHE + assert( p->wantToLock==0 ); + assert( p->locked==0 ); + if( p->pPrev ) p->pPrev->pNext = p->pNext; + if( p->pNext ) p->pNext->pPrev = p->pPrev; +#endif + + sqlite3_free(p); + return SQLITE_OK; +} + +/* +** Change the limit on the number of pages allowed in the cache. +** +** The maximum number of cache pages is set to the absolute +** value of mxPage. If mxPage is negative, the pager will +** operate asynchronously - it will not stop to do fsync()s +** to insure data is written to the disk surface before +** continuing. Transactions still work if synchronous is off, +** and the database cannot be corrupted if this program +** crashes. But if the operating system crashes or there is +** an abrupt power failure when synchronous is off, the database +** could be left in an inconsistent and unrecoverable state. +** Synchronous is on by default so database corruption is not +** normally a worry. +*/ +int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){ + BtShared *pBt = p->pBt; + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + sqlite3PagerSetCachesize(pBt->pPager, mxPage); + sqlite3BtreeLeave(p); + return SQLITE_OK; +} + +/* +** Change the way data is synced to disk in order to increase or decrease +** how well the database resists damage due to OS crashes and power +** failures. Level 1 is the same as asynchronous (no syncs() occur and +** there is a high probability of damage) Level 2 is the default. There +** is a very low but non-zero probability of damage. Level 3 reduces the +** probability of damage to near zero but with a write performance reduction. +*/ +#ifndef SQLITE_OMIT_PAGER_PRAGMAS +int sqlite3BtreeSetSafetyLevel( + Btree *p, /* The btree to set the safety level on */ + int level, /* PRAGMA synchronous. 1=OFF, 2=NORMAL, 3=FULL */ + int fullSync, /* PRAGMA fullfsync. */ + int ckptFullSync /* PRAGMA checkpoint_fullfync */ +){ + BtShared *pBt = p->pBt; + assert( sqlite3_mutex_held(p->db->mutex) ); + assert( level>=1 && level<=3 ); + sqlite3BtreeEnter(p); + sqlite3PagerSetSafetyLevel(pBt->pPager, level, fullSync, ckptFullSync); + sqlite3BtreeLeave(p); + return SQLITE_OK; +} +#endif + +/* +** Return TRUE if the given btree is set to safety level 1. In other +** words, return TRUE if no sync() occurs on the disk files. +*/ +int sqlite3BtreeSyncDisabled(Btree *p){ + BtShared *pBt = p->pBt; + int rc; + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + assert( pBt && pBt->pPager ); + rc = sqlite3PagerNosync(pBt->pPager); + sqlite3BtreeLeave(p); + return rc; +} + +/* +** Change the default pages size and the number of reserved bytes per page. +** Or, if the page size has already been fixed, return SQLITE_READONLY +** without changing anything. +** +** The page size must be a power of 2 between 512 and 65536. If the page +** size supplied does not meet this constraint then the page size is not +** changed. +** +** Page sizes are constrained to be a power of two so that the region +** of the database file used for locking (beginning at PENDING_BYTE, +** the first byte past the 1GB boundary, 0x40000000) needs to occur +** at the beginning of a page. +** +** If parameter nReserve is less than zero, then the number of reserved +** bytes per page is left unchanged. +** +** If the iFix!=0 then the BTS_PAGESIZE_FIXED flag is set so that the page size +** and autovacuum mode can no longer be changed. +*/ +int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){ + int rc = SQLITE_OK; + BtShared *pBt = p->pBt; + assert( nReserve>=-1 && nReserve<=255 ); + sqlite3BtreeEnter(p); + if( pBt->btsFlags & BTS_PAGESIZE_FIXED ){ + sqlite3BtreeLeave(p); + return SQLITE_READONLY; + } + if( nReserve<0 ){ + nReserve = pBt->pageSize - pBt->usableSize; + } + assert( nReserve>=0 && nReserve<=255 ); + if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE && + ((pageSize-1)&pageSize)==0 ){ + assert( (pageSize & 7)==0 ); + assert( !pBt->pPage1 && !pBt->pCursor ); + pBt->pageSize = (u32)pageSize; + freeTempSpace(pBt); + } + rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve); + pBt->usableSize = pBt->pageSize - (u16)nReserve; + if( iFix ) pBt->btsFlags |= BTS_PAGESIZE_FIXED; + sqlite3BtreeLeave(p); + return rc; +} + +/* +** Return the currently defined page size +*/ +int sqlite3BtreeGetPageSize(Btree *p){ + return p->pBt->pageSize; +} + +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) +/* +** Return the number of bytes of space at the end of every page that +** are intentually left unused. This is the "reserved" space that is +** sometimes used by extensions. +*/ +int sqlite3BtreeGetReserve(Btree *p){ + int n; + sqlite3BtreeEnter(p); + n = p->pBt->pageSize - p->pBt->usableSize; + sqlite3BtreeLeave(p); + return n; +} + +/* +** Set the maximum page count for a database if mxPage is positive. +** No changes are made if mxPage is 0 or negative. +** Regardless of the value of mxPage, return the maximum page count. +*/ +int sqlite3BtreeMaxPageCount(Btree *p, int mxPage){ + int n; + sqlite3BtreeEnter(p); + n = sqlite3PagerMaxPageCount(p->pBt->pPager, mxPage); + sqlite3BtreeLeave(p); + return n; +} + +/* +** Set the BTS_SECURE_DELETE flag if newFlag is 0 or 1. If newFlag is -1, +** then make no changes. Always return the value of the BTS_SECURE_DELETE +** setting after the change. +*/ +int sqlite3BtreeSecureDelete(Btree *p, int newFlag){ + int b; + if( p==0 ) return 0; + sqlite3BtreeEnter(p); + if( newFlag>=0 ){ + p->pBt->btsFlags &= ~BTS_SECURE_DELETE; + if( newFlag ) p->pBt->btsFlags |= BTS_SECURE_DELETE; + } + b = (p->pBt->btsFlags & BTS_SECURE_DELETE)!=0; + sqlite3BtreeLeave(p); + return b; +} +#endif /* !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) */ + +/* +** Change the 'auto-vacuum' property of the database. If the 'autoVacuum' +** parameter is non-zero, then auto-vacuum mode is enabled. If zero, it +** is disabled. The default value for the auto-vacuum property is +** determined by the SQLITE_DEFAULT_AUTOVACUUM macro. +*/ +int sqlite3BtreeSetAutoVacuum(Btree *p, int autoVacuum){ +#ifdef SQLITE_OMIT_AUTOVACUUM + return SQLITE_READONLY; +#else + BtShared *pBt = p->pBt; + int rc = SQLITE_OK; + u8 av = (u8)autoVacuum; + + sqlite3BtreeEnter(p); + if( (pBt->btsFlags & BTS_PAGESIZE_FIXED)!=0 && (av ?1:0)!=pBt->autoVacuum ){ + rc = SQLITE_READONLY; + }else{ + pBt->autoVacuum = av ?1:0; + pBt->incrVacuum = av==2 ?1:0; + } + sqlite3BtreeLeave(p); + return rc; +#endif +} + +/* +** Return the value of the 'auto-vacuum' property. If auto-vacuum is +** enabled 1 is returned. Otherwise 0. +*/ +int sqlite3BtreeGetAutoVacuum(Btree *p){ +#ifdef SQLITE_OMIT_AUTOVACUUM + return BTREE_AUTOVACUUM_NONE; +#else + int rc; + sqlite3BtreeEnter(p); + rc = ( + (!p->pBt->autoVacuum)?BTREE_AUTOVACUUM_NONE: + (!p->pBt->incrVacuum)?BTREE_AUTOVACUUM_FULL: + BTREE_AUTOVACUUM_INCR + ); + sqlite3BtreeLeave(p); + return rc; +#endif +} + + +/* +** Get a reference to pPage1 of the database file. This will +** also acquire a readlock on that file. +** +** SQLITE_OK is returned on success. If the file is not a +** well-formed database file, then SQLITE_CORRUPT is returned. +** SQLITE_BUSY is returned if the database is locked. SQLITE_NOMEM +** is returned if we run out of memory. +*/ +static int lockBtree(BtShared *pBt){ + int rc; /* Result code from subfunctions */ + MemPage *pPage1; /* Page 1 of the database file */ + int nPage; /* Number of pages in the database */ + int nPageFile = 0; /* Number of pages in the database file */ + int nPageHeader; /* Number of pages in the database according to hdr */ + + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( pBt->pPage1==0 ); + rc = sqlite3PagerSharedLock(pBt->pPager); + if( rc!=SQLITE_OK ) return rc; + rc = btreeGetPage(pBt, 1, &pPage1, 0); + if( rc!=SQLITE_OK ) return rc; + + /* Do some checking to help insure the file we opened really is + ** a valid database file. + */ + nPage = nPageHeader = get4byte(28+(u8*)pPage1->aData); + sqlite3PagerPagecount(pBt->pPager, &nPageFile); + if( nPage==0 || memcmp(24+(u8*)pPage1->aData, 92+(u8*)pPage1->aData,4)!=0 ){ + nPage = nPageFile; + } + if( nPage>0 ){ + u32 pageSize; + u32 usableSize; + u8 *page1 = pPage1->aData; + rc = SQLITE_NOTADB; + if( memcmp(page1, zMagicHeader, 16)!=0 ){ + goto page1_init_failed; + } + +#ifdef SQLITE_OMIT_WAL + if( page1[18]>1 ){ + pBt->btsFlags |= BTS_READ_ONLY; + } + if( page1[19]>1 ){ + goto page1_init_failed; + } +#else + if( page1[18]>2 ){ + pBt->btsFlags |= BTS_READ_ONLY; + } + if( page1[19]>2 ){ + goto page1_init_failed; + } + + /* If the write version is set to 2, this database should be accessed + ** in WAL mode. If the log is not already open, open it now. Then + ** return SQLITE_OK and return without populating BtShared.pPage1. + ** The caller detects this and calls this function again. This is + ** required as the version of page 1 currently in the page1 buffer + ** may not be the latest version - there may be a newer one in the log + ** file. + */ + if( page1[19]==2 && (pBt->btsFlags & BTS_NO_WAL)==0 ){ + int isOpen = 0; + rc = sqlite3PagerOpenWal(pBt->pPager, &isOpen); + if( rc!=SQLITE_OK ){ + goto page1_init_failed; + }else if( isOpen==0 ){ + releasePage(pPage1); + return SQLITE_OK; + } + rc = SQLITE_NOTADB; + } +#endif + + /* The maximum embedded fraction must be exactly 25%. And the minimum + ** embedded fraction must be 12.5% for both leaf-data and non-leaf-data. + ** The original design allowed these amounts to vary, but as of + ** version 3.6.0, we require them to be fixed. + */ + if( memcmp(&page1[21], "\100\040\040",3)!=0 ){ + goto page1_init_failed; + } + pageSize = (page1[16]<<8) | (page1[17]<<16); + if( ((pageSize-1)&pageSize)!=0 + || pageSize>SQLITE_MAX_PAGE_SIZE + || pageSize<=256 + ){ + goto page1_init_failed; + } + assert( (pageSize & 7)==0 ); + usableSize = pageSize - page1[20]; + if( (u32)pageSize!=pBt->pageSize ){ + /* After reading the first page of the database assuming a page size + ** of BtShared.pageSize, we have discovered that the page-size is + ** actually pageSize. Unlock the database, leave pBt->pPage1 at + ** zero and return SQLITE_OK. The caller will call this function + ** again with the correct page-size. + */ + releasePage(pPage1); + pBt->usableSize = usableSize; + pBt->pageSize = pageSize; + freeTempSpace(pBt); + rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, + pageSize-usableSize); + return rc; + } + if( (pBt->db->flags & SQLITE_RecoveryMode)==0 && nPage>nPageFile ){ + rc = SQLITE_CORRUPT_BKPT; + goto page1_init_failed; + } + if( usableSize<480 ){ + goto page1_init_failed; + } + pBt->pageSize = pageSize; + pBt->usableSize = usableSize; +#ifndef SQLITE_OMIT_AUTOVACUUM + pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0); + pBt->incrVacuum = (get4byte(&page1[36 + 7*4])?1:0); +#endif + } + + /* maxLocal is the maximum amount of payload to store locally for + ** a cell. Make sure it is small enough so that at least minFanout + ** cells can will fit on one page. We assume a 10-byte page header. + ** Besides the payload, the cell must store: + ** 2-byte pointer to the cell + ** 4-byte child pointer + ** 9-byte nKey value + ** 4-byte nData value + ** 4-byte overflow page pointer + ** So a cell consists of a 2-byte pointer, a header which is as much as + ** 17 bytes long, 0 to N bytes of payload, and an optional 4 byte overflow + ** page pointer. + */ + pBt->maxLocal = (u16)((pBt->usableSize-12)*64/255 - 23); + pBt->minLocal = (u16)((pBt->usableSize-12)*32/255 - 23); + pBt->maxLeaf = (u16)(pBt->usableSize - 35); + pBt->minLeaf = (u16)((pBt->usableSize-12)*32/255 - 23); + if( pBt->maxLocal>127 ){ + pBt->max1bytePayload = 127; + }else{ + pBt->max1bytePayload = (u8)pBt->maxLocal; + } + assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE(pBt) ); + pBt->pPage1 = pPage1; + pBt->nPage = nPage; + return SQLITE_OK; + +page1_init_failed: + releasePage(pPage1); + pBt->pPage1 = 0; + return rc; +} + +/* +** If there are no outstanding cursors and we are not in the middle +** of a transaction but there is a read lock on the database, then +** this routine unrefs the first page of the database file which +** has the effect of releasing the read lock. +** +** If there is a transaction in progress, this routine is a no-op. +*/ +static void unlockBtreeIfUnused(BtShared *pBt){ + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( pBt->pCursor==0 || pBt->inTransaction>TRANS_NONE ); + if( pBt->inTransaction==TRANS_NONE && pBt->pPage1!=0 ){ + assert( pBt->pPage1->aData ); + assert( sqlite3PagerRefcount(pBt->pPager)==1 ); + assert( pBt->pPage1->aData ); + releasePage(pBt->pPage1); + pBt->pPage1 = 0; + } +} + +/* +** If pBt points to an empty file then convert that empty file +** into a new empty database by initializing the first page of +** the database. +*/ +static int newDatabase(BtShared *pBt){ + MemPage *pP1; + unsigned char *data; + int rc; + + assert( sqlite3_mutex_held(pBt->mutex) ); + if( pBt->nPage>0 ){ + return SQLITE_OK; + } + pP1 = pBt->pPage1; + assert( pP1!=0 ); + data = pP1->aData; + rc = sqlite3PagerWrite(pP1->pDbPage); + if( rc ) return rc; + memcpy(data, zMagicHeader, sizeof(zMagicHeader)); + assert( sizeof(zMagicHeader)==16 ); + data[16] = (u8)((pBt->pageSize>>8)&0xff); + data[17] = (u8)((pBt->pageSize>>16)&0xff); + data[18] = 1; + data[19] = 1; + assert( pBt->usableSize<=pBt->pageSize && pBt->usableSize+255>=pBt->pageSize); + data[20] = (u8)(pBt->pageSize - pBt->usableSize); + data[21] = 64; + data[22] = 32; + data[23] = 32; + memset(&data[24], 0, 100-24); + zeroPage(pP1, PTF_INTKEY|PTF_LEAF|PTF_LEAFDATA ); + pBt->btsFlags |= BTS_PAGESIZE_FIXED; +#ifndef SQLITE_OMIT_AUTOVACUUM + assert( pBt->autoVacuum==1 || pBt->autoVacuum==0 ); + assert( pBt->incrVacuum==1 || pBt->incrVacuum==0 ); + put4byte(&data[36 + 4*4], pBt->autoVacuum); + put4byte(&data[36 + 7*4], pBt->incrVacuum); +#endif + pBt->nPage = 1; + data[31] = 1; + return SQLITE_OK; +} + +/* +** Attempt to start a new transaction. A write-transaction +** is started if the second argument is nonzero, otherwise a read- +** transaction. If the second argument is 2 or more and exclusive +** transaction is started, meaning that no other process is allowed +** to access the database. A preexisting transaction may not be +** upgraded to exclusive by calling this routine a second time - the +** exclusivity flag only works for a new transaction. +** +** A write-transaction must be started before attempting any +** changes to the database. None of the following routines +** will work unless a transaction is started first: +** +** sqlite3BtreeCreateTable() +** sqlite3BtreeCreateIndex() +** sqlite3BtreeClearTable() +** sqlite3BtreeDropTable() +** sqlite3BtreeInsert() +** sqlite3BtreeDelete() +** sqlite3BtreeUpdateMeta() +** +** If an initial attempt to acquire the lock fails because of lock contention +** and the database was previously unlocked, then invoke the busy handler +** if there is one. But if there was previously a read-lock, do not +** invoke the busy handler - just return SQLITE_BUSY. SQLITE_BUSY is +** returned when there is already a read-lock in order to avoid a deadlock. +** +** Suppose there are two processes A and B. A has a read lock and B has +** a reserved lock. B tries to promote to exclusive but is blocked because +** of A's read lock. A tries to promote to reserved but is blocked by B. +** One or the other of the two processes must give way or there can be +** no progress. By returning SQLITE_BUSY and not invoking the busy callback +** when A already has a read lock, we encourage A to give up and let B +** proceed. +*/ +int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ + sqlite3 *pBlock = 0; + BtShared *pBt = p->pBt; + int rc = SQLITE_OK; + + sqlite3BtreeEnter(p); + btreeIntegrity(p); + + /* If the btree is already in a write-transaction, or it + ** is already in a read-transaction and a read-transaction + ** is requested, this is a no-op. + */ + if( p->inTrans==TRANS_WRITE || (p->inTrans==TRANS_READ && !wrflag) ){ + goto trans_begun; + } + + /* Write transactions are not possible on a read-only database */ + if( (pBt->btsFlags & BTS_READ_ONLY)!=0 && wrflag ){ + rc = SQLITE_READONLY; + goto trans_begun; + } + +#ifndef SQLITE_OMIT_SHARED_CACHE + /* If another database handle has already opened a write transaction + ** on this shared-btree structure and a second write transaction is + ** requested, return SQLITE_LOCKED. + */ + if( (wrflag && pBt->inTransaction==TRANS_WRITE) + || (pBt->btsFlags & BTS_PENDING)!=0 + ){ + pBlock = pBt->pWriter->db; + }else if( wrflag>1 ){ + BtLock *pIter; + for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){ + if( pIter->pBtree!=p ){ + pBlock = pIter->pBtree->db; + break; + } + } + } + if( pBlock ){ + sqlite3ConnectionBlocked(p->db, pBlock); + rc = SQLITE_LOCKED_SHAREDCACHE; + goto trans_begun; + } +#endif + + /* Any read-only or read-write transaction implies a read-lock on + ** page 1. So if some other shared-cache client already has a write-lock + ** on page 1, the transaction cannot be opened. */ + rc = querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK); + if( SQLITE_OK!=rc ) goto trans_begun; + + pBt->btsFlags &= ~BTS_INITIALLY_EMPTY; + if( pBt->nPage==0 ) pBt->btsFlags |= BTS_INITIALLY_EMPTY; + do { + /* Call lockBtree() until either pBt->pPage1 is populated or + ** lockBtree() returns something other than SQLITE_OK. lockBtree() + ** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after + ** reading page 1 it discovers that the page-size of the database + ** file is not pBt->pageSize. In this case lockBtree() will update + ** pBt->pageSize to the page-size of the file on disk. + */ + while( pBt->pPage1==0 && SQLITE_OK==(rc = lockBtree(pBt)) ); + + if( rc==SQLITE_OK && wrflag ){ + if( (pBt->btsFlags & BTS_READ_ONLY)!=0 ){ + rc = SQLITE_READONLY; + }else{ + rc = sqlite3PagerBegin(pBt->pPager,wrflag>1,sqlite3TempInMemory(p->db)); + if( rc==SQLITE_OK ){ + rc = newDatabase(pBt); + } + } + } + + if( rc!=SQLITE_OK ){ + unlockBtreeIfUnused(pBt); + } + }while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE && + btreeInvokeBusyHandler(pBt) ); + + if( rc==SQLITE_OK ){ + if( p->inTrans==TRANS_NONE ){ + pBt->nTransaction++; +#ifndef SQLITE_OMIT_SHARED_CACHE + if( p->sharable ){ + assert( p->lock.pBtree==p && p->lock.iTable==1 ); + p->lock.eLock = READ_LOCK; + p->lock.pNext = pBt->pLock; + pBt->pLock = &p->lock; + } +#endif + } + p->inTrans = (wrflag?TRANS_WRITE:TRANS_READ); + if( p->inTrans>pBt->inTransaction ){ + pBt->inTransaction = p->inTrans; + } + if( wrflag ){ + MemPage *pPage1 = pBt->pPage1; +#ifndef SQLITE_OMIT_SHARED_CACHE + assert( !pBt->pWriter ); + pBt->pWriter = p; + pBt->btsFlags &= ~BTS_EXCLUSIVE; + if( wrflag>1 ) pBt->btsFlags |= BTS_EXCLUSIVE; +#endif + + /* If the db-size header field is incorrect (as it may be if an old + ** client has been writing the database file), update it now. Doing + ** this sooner rather than later means the database size can safely + ** re-read the database size from page 1 if a savepoint or transaction + ** rollback occurs within the transaction. + */ + if( pBt->nPage!=get4byte(&pPage1->aData[28]) ){ + rc = sqlite3PagerWrite(pPage1->pDbPage); + if( rc==SQLITE_OK ){ + put4byte(&pPage1->aData[28], pBt->nPage); + } + } + } + } + + +trans_begun: + if( rc==SQLITE_OK && wrflag ){ + /* This call makes sure that the pager has the correct number of + ** open savepoints. If the second parameter is greater than 0 and + ** the sub-journal is not already open, then it will be opened here. + */ + rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint); + } + + btreeIntegrity(p); + sqlite3BtreeLeave(p); + return rc; +} + +#ifndef SQLITE_OMIT_AUTOVACUUM + +/* +** Set the pointer-map entries for all children of page pPage. Also, if +** pPage contains cells that point to overflow pages, set the pointer +** map entries for the overflow pages as well. +*/ +static int setChildPtrmaps(MemPage *pPage){ + int i; /* Counter variable */ + int nCell; /* Number of cells in page pPage */ + int rc; /* Return code */ + BtShared *pBt = pPage->pBt; + u8 isInitOrig = pPage->isInit; + Pgno pgno = pPage->pgno; + + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + rc = btreeInitPage(pPage); + if( rc!=SQLITE_OK ){ + goto set_child_ptrmaps_out; + } + nCell = pPage->nCell; + + for(i=0; ileaf ){ + Pgno childPgno = get4byte(pCell); + ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno, &rc); + } + } + + if( !pPage->leaf ){ + Pgno childPgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); + ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno, &rc); + } + +set_child_ptrmaps_out: + pPage->isInit = isInitOrig; + return rc; +} + +/* +** Somewhere on pPage is a pointer to page iFrom. Modify this pointer so +** that it points to iTo. Parameter eType describes the type of pointer to +** be modified, as follows: +** +** PTRMAP_BTREE: pPage is a btree-page. The pointer points at a child +** page of pPage. +** +** PTRMAP_OVERFLOW1: pPage is a btree-page. The pointer points at an overflow +** page pointed to by one of the cells on pPage. +** +** PTRMAP_OVERFLOW2: pPage is an overflow-page. The pointer points at the next +** overflow page in the list. +*/ +static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){ + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + if( eType==PTRMAP_OVERFLOW2 ){ + /* The pointer is always the first 4 bytes of the page in this case. */ + if( get4byte(pPage->aData)!=iFrom ){ + return SQLITE_CORRUPT_BKPT; + } + put4byte(pPage->aData, iTo); + }else{ + u8 isInitOrig = pPage->isInit; + int i; + int nCell; + + btreeInitPage(pPage); + nCell = pPage->nCell; + + for(i=0; iaData+pPage->maskPage + && iFrom==get4byte(&pCell[info.iOverflow]) + ){ + put4byte(&pCell[info.iOverflow], iTo); + break; + } + }else{ + if( get4byte(pCell)==iFrom ){ + put4byte(pCell, iTo); + break; + } + } + } + + if( i==nCell ){ + if( eType!=PTRMAP_BTREE || + get4byte(&pPage->aData[pPage->hdrOffset+8])!=iFrom ){ + return SQLITE_CORRUPT_BKPT; + } + put4byte(&pPage->aData[pPage->hdrOffset+8], iTo); + } + + pPage->isInit = isInitOrig; + } + return SQLITE_OK; +} + + +/* +** Move the open database page pDbPage to location iFreePage in the +** database. The pDbPage reference remains valid. +** +** The isCommit flag indicates that there is no need to remember that +** the journal needs to be sync()ed before database page pDbPage->pgno +** can be written to. The caller has already promised not to write to that +** page. +*/ +static int relocatePage( + BtShared *pBt, /* Btree */ + MemPage *pDbPage, /* Open page to move */ + u8 eType, /* Pointer map 'type' entry for pDbPage */ + Pgno iPtrPage, /* Pointer map 'page-no' entry for pDbPage */ + Pgno iFreePage, /* The location to move pDbPage to */ + int isCommit /* isCommit flag passed to sqlite3PagerMovepage */ +){ + MemPage *pPtrPage; /* The page that contains a pointer to pDbPage */ + Pgno iDbPage = pDbPage->pgno; + Pager *pPager = pBt->pPager; + int rc; + + assert( eType==PTRMAP_OVERFLOW2 || eType==PTRMAP_OVERFLOW1 || + eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ); + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( pDbPage->pBt==pBt ); + + /* Move page iDbPage from its current location to page number iFreePage */ + TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n", + iDbPage, iFreePage, iPtrPage, eType)); + rc = sqlite3PagerMovepage(pPager, pDbPage->pDbPage, iFreePage, isCommit); + if( rc!=SQLITE_OK ){ + return rc; + } + pDbPage->pgno = iFreePage; + + /* If pDbPage was a btree-page, then it may have child pages and/or cells + ** that point to overflow pages. The pointer map entries for all these + ** pages need to be changed. + ** + ** If pDbPage is an overflow page, then the first 4 bytes may store a + ** pointer to a subsequent overflow page. If this is the case, then + ** the pointer map needs to be updated for the subsequent overflow page. + */ + if( eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ){ + rc = setChildPtrmaps(pDbPage); + if( rc!=SQLITE_OK ){ + return rc; + } + }else{ + Pgno nextOvfl = get4byte(pDbPage->aData); + if( nextOvfl!=0 ){ + ptrmapPut(pBt, nextOvfl, PTRMAP_OVERFLOW2, iFreePage, &rc); + if( rc!=SQLITE_OK ){ + return rc; + } + } + } + + /* Fix the database pointer on page iPtrPage that pointed at iDbPage so + ** that it points at iFreePage. Also fix the pointer map entry for + ** iPtrPage. + */ + if( eType!=PTRMAP_ROOTPAGE ){ + rc = btreeGetPage(pBt, iPtrPage, &pPtrPage, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = sqlite3PagerWrite(pPtrPage->pDbPage); + if( rc!=SQLITE_OK ){ + releasePage(pPtrPage); + return rc; + } + rc = modifyPagePointer(pPtrPage, iDbPage, iFreePage, eType); + releasePage(pPtrPage); + if( rc==SQLITE_OK ){ + ptrmapPut(pBt, iFreePage, eType, iPtrPage, &rc); + } + } + return rc; +} + +/* Forward declaration required by incrVacuumStep(). */ +static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8); + +/* +** Perform a single step of an incremental-vacuum. If successful, +** return SQLITE_OK. If there is no work to do (and therefore no +** point in calling this function again), return SQLITE_DONE. +** +** More specificly, this function attempts to re-organize the +** database so that the last page of the file currently in use +** is no longer in use. +** +** If the nFin parameter is non-zero, this function assumes +** that the caller will keep calling incrVacuumStep() until +** it returns SQLITE_DONE or an error, and that nFin is the +** number of pages the database file will contain after this +** process is complete. If nFin is zero, it is assumed that +** incrVacuumStep() will be called a finite amount of times +** which may or may not empty the freelist. A full autovacuum +** has nFin>0. A "PRAGMA incremental_vacuum" has nFin==0. +*/ +static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){ + Pgno nFreeList; /* Number of pages still on the free-list */ + int rc; + + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( iLastPg>nFin ); + + if( !PTRMAP_ISPAGE(pBt, iLastPg) && iLastPg!=PENDING_BYTE_PAGE(pBt) ){ + u8 eType; + Pgno iPtrPage; + + nFreeList = get4byte(&pBt->pPage1->aData[36]); + if( nFreeList==0 ){ + return SQLITE_DONE; + } + + rc = ptrmapGet(pBt, iLastPg, &eType, &iPtrPage); + if( rc!=SQLITE_OK ){ + return rc; + } + if( eType==PTRMAP_ROOTPAGE ){ + return SQLITE_CORRUPT_BKPT; + } + + if( eType==PTRMAP_FREEPAGE ){ + if( nFin==0 ){ + /* Remove the page from the files free-list. This is not required + ** if nFin is non-zero. In that case, the free-list will be + ** truncated to zero after this function returns, so it doesn't + ** matter if it still contains some garbage entries. + */ + Pgno iFreePg; + MemPage *pFreePg; + rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iLastPg, 1); + if( rc!=SQLITE_OK ){ + return rc; + } + assert( iFreePg==iLastPg ); + releasePage(pFreePg); + } + } else { + Pgno iFreePg; /* Index of free page to move pLastPg to */ + MemPage *pLastPg; + + rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + + /* If nFin is zero, this loop runs exactly once and page pLastPg + ** is swapped with the first free page pulled off the free list. + ** + ** On the other hand, if nFin is greater than zero, then keep + ** looping until a free-page located within the first nFin pages + ** of the file is found. + */ + do { + MemPage *pFreePg; + rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, 0, 0); + if( rc!=SQLITE_OK ){ + releasePage(pLastPg); + return rc; + } + releasePage(pFreePg); + }while( nFin!=0 && iFreePg>nFin ); + assert( iFreePgpDbPage); + if( rc==SQLITE_OK ){ + rc = relocatePage(pBt, pLastPg, eType, iPtrPage, iFreePg, nFin!=0); + } + releasePage(pLastPg); + if( rc!=SQLITE_OK ){ + return rc; + } + } + } + + if( nFin==0 ){ + iLastPg--; + while( iLastPg==PENDING_BYTE_PAGE(pBt)||PTRMAP_ISPAGE(pBt, iLastPg) ){ + if( PTRMAP_ISPAGE(pBt, iLastPg) ){ + MemPage *pPg; + rc = btreeGetPage(pBt, iLastPg, &pPg, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = sqlite3PagerWrite(pPg->pDbPage); + releasePage(pPg); + if( rc!=SQLITE_OK ){ + return rc; + } + } + iLastPg--; + } + sqlite3PagerTruncateImage(pBt->pPager, iLastPg); + pBt->nPage = iLastPg; + } + return SQLITE_OK; +} + +/* +** A write-transaction must be opened before calling this function. +** It performs a single unit of work towards an incremental vacuum. +** +** If the incremental vacuum is finished after this function has run, +** SQLITE_DONE is returned. If it is not finished, but no error occurred, +** SQLITE_OK is returned. Otherwise an SQLite error code. +*/ +int sqlite3BtreeIncrVacuum(Btree *p){ + int rc; + BtShared *pBt = p->pBt; + + sqlite3BtreeEnter(p); + assert( pBt->inTransaction==TRANS_WRITE && p->inTrans==TRANS_WRITE ); + if( !pBt->autoVacuum ){ + rc = SQLITE_DONE; + }else{ + invalidateAllOverflowCache(pBt); + rc = incrVacuumStep(pBt, 0, btreePagecount(pBt)); + if( rc==SQLITE_OK ){ + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + put4byte(&pBt->pPage1->aData[28], pBt->nPage); + } + } + sqlite3BtreeLeave(p); + return rc; +} + +/* +** This routine is called prior to sqlite3PagerCommit when a transaction +** is commited for an auto-vacuum database. +** +** If SQLITE_OK is returned, then *pnTrunc is set to the number of pages +** the database file should be truncated to during the commit process. +** i.e. the database has been reorganized so that only the first *pnTrunc +** pages are in use. +*/ +static int autoVacuumCommit(BtShared *pBt){ + int rc = SQLITE_OK; + Pager *pPager = pBt->pPager; + VVA_ONLY( int nRef = sqlite3PagerRefcount(pPager) ); + + assert( sqlite3_mutex_held(pBt->mutex) ); + invalidateAllOverflowCache(pBt); + assert(pBt->autoVacuum); + if( !pBt->incrVacuum ){ + Pgno nFin; /* Number of pages in database after autovacuuming */ + Pgno nFree; /* Number of pages on the freelist initially */ + Pgno nPtrmap; /* Number of PtrMap pages to be freed */ + Pgno iFree; /* The next page to be freed */ + int nEntry; /* Number of entries on one ptrmap page */ + Pgno nOrig; /* Database size before freeing */ + + nOrig = btreePagecount(pBt); + if( PTRMAP_ISPAGE(pBt, nOrig) || nOrig==PENDING_BYTE_PAGE(pBt) ){ + /* It is not possible to create a database for which the final page + ** is either a pointer-map page or the pending-byte page. If one + ** is encountered, this indicates corruption. + */ + return SQLITE_CORRUPT_BKPT; + } + + nFree = get4byte(&pBt->pPage1->aData[36]); + nEntry = pBt->usableSize/5; + nPtrmap = (nFree-nOrig+PTRMAP_PAGENO(pBt, nOrig)+nEntry)/nEntry; + nFin = nOrig - nFree - nPtrmap; + if( nOrig>PENDING_BYTE_PAGE(pBt) && nFinnOrig ) return SQLITE_CORRUPT_BKPT; + + for(iFree=nOrig; iFree>nFin && rc==SQLITE_OK; iFree--){ + rc = incrVacuumStep(pBt, nFin, iFree); + } + if( (rc==SQLITE_DONE || rc==SQLITE_OK) && nFree>0 ){ + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + put4byte(&pBt->pPage1->aData[32], 0); + put4byte(&pBt->pPage1->aData[36], 0); + put4byte(&pBt->pPage1->aData[28], nFin); + sqlite3PagerTruncateImage(pBt->pPager, nFin); + pBt->nPage = nFin; + } + if( rc!=SQLITE_OK ){ + sqlite3PagerRollback(pPager); + } + } + + assert( nRef==sqlite3PagerRefcount(pPager) ); + return rc; +} + +#else /* ifndef SQLITE_OMIT_AUTOVACUUM */ +# define setChildPtrmaps(x) SQLITE_OK +#endif + +/* +** This routine does the first phase of a two-phase commit. This routine +** causes a rollback journal to be created (if it does not already exist) +** and populated with enough information so that if a power loss occurs +** the database can be restored to its original state by playing back +** the journal. Then the contents of the journal are flushed out to +** the disk. After the journal is safely on oxide, the changes to the +** database are written into the database file and flushed to oxide. +** At the end of this call, the rollback journal still exists on the +** disk and we are still holding all locks, so the transaction has not +** committed. See sqlite3BtreeCommitPhaseTwo() for the second phase of the +** commit process. +** +** This call is a no-op if no write-transaction is currently active on pBt. +** +** Otherwise, sync the database file for the btree pBt. zMaster points to +** the name of a master journal file that should be written into the +** individual journal file, or is NULL, indicating no master journal file +** (single database transaction). +** +** When this is called, the master journal should already have been +** created, populated with this journal pointer and synced to disk. +** +** Once this is routine has returned, the only thing required to commit +** the write-transaction for this database file is to delete the journal. +*/ +int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zMaster){ + int rc = SQLITE_OK; + if( p->inTrans==TRANS_WRITE ){ + BtShared *pBt = p->pBt; + sqlite3BtreeEnter(p); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + rc = autoVacuumCommit(pBt); + if( rc!=SQLITE_OK ){ + sqlite3BtreeLeave(p); + return rc; + } + } +#endif + rc = sqlite3PagerCommitPhaseOne(pBt->pPager, zMaster, 0); + sqlite3BtreeLeave(p); + } + return rc; +} + +/* +** This function is called from both BtreeCommitPhaseTwo() and BtreeRollback() +** at the conclusion of a transaction. +*/ +static void btreeEndTransaction(Btree *p){ + BtShared *pBt = p->pBt; + assert( sqlite3BtreeHoldsMutex(p) ); + + btreeClearHasContent(pBt); + if( p->inTrans>TRANS_NONE && p->db->activeVdbeCnt>1 ){ + /* If there are other active statements that belong to this database + ** handle, downgrade to a read-only transaction. The other statements + ** may still be reading from the database. */ + downgradeAllSharedCacheTableLocks(p); + p->inTrans = TRANS_READ; + }else{ + /* If the handle had any kind of transaction open, decrement the + ** transaction count of the shared btree. If the transaction count + ** reaches 0, set the shared state to TRANS_NONE. The unlockBtreeIfUnused() + ** call below will unlock the pager. */ + if( p->inTrans!=TRANS_NONE ){ + clearAllSharedCacheTableLocks(p); + pBt->nTransaction--; + if( 0==pBt->nTransaction ){ + pBt->inTransaction = TRANS_NONE; + } + } + + /* Set the current transaction state to TRANS_NONE and unlock the + ** pager if this call closed the only read or write transaction. */ + p->inTrans = TRANS_NONE; + unlockBtreeIfUnused(pBt); + } + + btreeIntegrity(p); +} + +/* +** Commit the transaction currently in progress. +** +** This routine implements the second phase of a 2-phase commit. The +** sqlite3BtreeCommitPhaseOne() routine does the first phase and should +** be invoked prior to calling this routine. The sqlite3BtreeCommitPhaseOne() +** routine did all the work of writing information out to disk and flushing the +** contents so that they are written onto the disk platter. All this +** routine has to do is delete or truncate or zero the header in the +** the rollback journal (which causes the transaction to commit) and +** drop locks. +** +** Normally, if an error occurs while the pager layer is attempting to +** finalize the underlying journal file, this function returns an error and +** the upper layer will attempt a rollback. However, if the second argument +** is non-zero then this b-tree transaction is part of a multi-file +** transaction. In this case, the transaction has already been committed +** (by deleting a master journal file) and the caller will ignore this +** functions return code. So, even if an error occurs in the pager layer, +** reset the b-tree objects internal state to indicate that the write +** transaction has been closed. This is quite safe, as the pager will have +** transitioned to the error state. +** +** This will release the write lock on the database file. If there +** are no active cursors, it also releases the read lock. +*/ +int sqlite3BtreeCommitPhaseTwo(Btree *p, int bCleanup){ + + if( p->inTrans==TRANS_NONE ) return SQLITE_OK; + sqlite3BtreeEnter(p); + btreeIntegrity(p); + + /* If the handle has a write-transaction open, commit the shared-btrees + ** transaction and set the shared state to TRANS_READ. + */ + if( p->inTrans==TRANS_WRITE ){ + int rc; + BtShared *pBt = p->pBt; + assert( pBt->inTransaction==TRANS_WRITE ); + assert( pBt->nTransaction>0 ); + rc = sqlite3PagerCommitPhaseTwo(pBt->pPager); + if( rc!=SQLITE_OK && bCleanup==0 ){ + sqlite3BtreeLeave(p); + return rc; + } + pBt->inTransaction = TRANS_READ; + } + + btreeEndTransaction(p); + sqlite3BtreeLeave(p); + return SQLITE_OK; +} + +/* +** Do both phases of a commit. +*/ +int sqlite3BtreeCommit(Btree *p){ + int rc; + sqlite3BtreeEnter(p); + rc = sqlite3BtreeCommitPhaseOne(p, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3BtreeCommitPhaseTwo(p, 0); + } + sqlite3BtreeLeave(p); + return rc; +} + +#ifndef NDEBUG +/* +** Return the number of write-cursors open on this handle. This is for use +** in assert() expressions, so it is only compiled if NDEBUG is not +** defined. +** +** For the purposes of this routine, a write-cursor is any cursor that +** is capable of writing to the databse. That means the cursor was +** originally opened for writing and the cursor has not be disabled +** by having its state changed to CURSOR_FAULT. +*/ +static int countWriteCursors(BtShared *pBt){ + BtCursor *pCur; + int r = 0; + for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ + if( pCur->wrFlag && pCur->eState!=CURSOR_FAULT ) r++; + } + return r; +} +#endif + +/* +** This routine sets the state to CURSOR_FAULT and the error +** code to errCode for every cursor on BtShared that pBtree +** references. +** +** Every cursor is tripped, including cursors that belong +** to other database connections that happen to be sharing +** the cache with pBtree. +** +** This routine gets called when a rollback occurs. +** All cursors using the same cache must be tripped +** to prevent them from trying to use the btree after +** the rollback. The rollback may have deleted tables +** or moved root pages, so it is not sufficient to +** save the state of the cursor. The cursor must be +** invalidated. +*/ +void sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode){ + BtCursor *p; + sqlite3BtreeEnter(pBtree); + for(p=pBtree->pBt->pCursor; p; p=p->pNext){ + int i; + sqlite3BtreeClearCursor(p); + p->eState = CURSOR_FAULT; + p->skipNext = errCode; + for(i=0; i<=p->iPage; i++){ + releasePage(p->apPage[i]); + p->apPage[i] = 0; + } + } + sqlite3BtreeLeave(pBtree); +} + +/* +** Rollback the transaction in progress. All cursors will be +** invalided by this operation. Any attempt to use a cursor +** that was open at the beginning of this operation will result +** in an error. +** +** This will release the write lock on the database file. If there +** are no active cursors, it also releases the read lock. +*/ +int sqlite3BtreeRollback(Btree *p){ + int rc; + BtShared *pBt = p->pBt; + MemPage *pPage1; + + sqlite3BtreeEnter(p); + rc = saveAllCursors(pBt, 0, 0); +#ifndef SQLITE_OMIT_SHARED_CACHE + if( rc!=SQLITE_OK ){ + /* This is a horrible situation. An IO or malloc() error occurred whilst + ** trying to save cursor positions. If this is an automatic rollback (as + ** the result of a constraint, malloc() failure or IO error) then + ** the cache may be internally inconsistent (not contain valid trees) so + ** we cannot simply return the error to the caller. Instead, abort + ** all queries that may be using any of the cursors that failed to save. + */ + sqlite3BtreeTripAllCursors(p, rc); + } +#endif + btreeIntegrity(p); + + if( p->inTrans==TRANS_WRITE ){ + int rc2; + + assert( TRANS_WRITE==pBt->inTransaction ); + rc2 = sqlite3PagerRollback(pBt->pPager); + if( rc2!=SQLITE_OK ){ + rc = rc2; + } + + /* The rollback may have destroyed the pPage1->aData value. So + ** call btreeGetPage() on page 1 again to make + ** sure pPage1->aData is set correctly. */ + if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){ + int nPage = get4byte(28+(u8*)pPage1->aData); + testcase( nPage==0 ); + if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage); + testcase( pBt->nPage!=nPage ); + pBt->nPage = nPage; + releasePage(pPage1); + } + assert( countWriteCursors(pBt)==0 ); + pBt->inTransaction = TRANS_READ; + } + + btreeEndTransaction(p); + sqlite3BtreeLeave(p); + return rc; +} + +/* +** Start a statement subtransaction. The subtransaction can can be rolled +** back independently of the main transaction. You must start a transaction +** before starting a subtransaction. The subtransaction is ended automatically +** if the main transaction commits or rolls back. +** +** Statement subtransactions are used around individual SQL statements +** that are contained within a BEGIN...COMMIT block. If a constraint +** error occurs within the statement, the effect of that one statement +** can be rolled back without having to rollback the entire transaction. +** +** A statement sub-transaction is implemented as an anonymous savepoint. The +** value passed as the second parameter is the total number of savepoints, +** including the new anonymous savepoint, open on the B-Tree. i.e. if there +** are no active savepoints and no other statement-transactions open, +** iStatement is 1. This anonymous savepoint can be released or rolled back +** using the sqlite3BtreeSavepoint() function. +*/ +int sqlite3BtreeBeginStmt(Btree *p, int iStatement){ + int rc; + BtShared *pBt = p->pBt; + sqlite3BtreeEnter(p); + assert( p->inTrans==TRANS_WRITE ); + assert( (pBt->btsFlags & BTS_READ_ONLY)==0 ); + assert( iStatement>0 ); + assert( iStatement>p->db->nSavepoint ); + assert( pBt->inTransaction==TRANS_WRITE ); + /* At the pager level, a statement transaction is a savepoint with + ** an index greater than all savepoints created explicitly using + ** SQL statements. It is illegal to open, release or rollback any + ** such savepoints while the statement transaction savepoint is active. + */ + rc = sqlite3PagerOpenSavepoint(pBt->pPager, iStatement); + sqlite3BtreeLeave(p); + return rc; +} + +/* +** The second argument to this function, op, is always SAVEPOINT_ROLLBACK +** or SAVEPOINT_RELEASE. This function either releases or rolls back the +** savepoint identified by parameter iSavepoint, depending on the value +** of op. +** +** Normally, iSavepoint is greater than or equal to zero. However, if op is +** SAVEPOINT_ROLLBACK, then iSavepoint may also be -1. In this case the +** contents of the entire transaction are rolled back. This is different +** from a normal transaction rollback, as no locks are released and the +** transaction remains open. +*/ +int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){ + int rc = SQLITE_OK; + if( p && p->inTrans==TRANS_WRITE ){ + BtShared *pBt = p->pBt; + assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK ); + assert( iSavepoint>=0 || (iSavepoint==-1 && op==SAVEPOINT_ROLLBACK) ); + sqlite3BtreeEnter(p); + rc = sqlite3PagerSavepoint(pBt->pPager, op, iSavepoint); + if( rc==SQLITE_OK ){ + if( iSavepoint<0 && (pBt->btsFlags & BTS_INITIALLY_EMPTY)!=0 ){ + pBt->nPage = 0; + } + rc = newDatabase(pBt); + pBt->nPage = get4byte(28 + pBt->pPage1->aData); + + /* The database size was written into the offset 28 of the header + ** when the transaction started, so we know that the value at offset + ** 28 is nonzero. */ + assert( pBt->nPage>0 ); + } + sqlite3BtreeLeave(p); + } + return rc; +} + +/* +** Create a new cursor for the BTree whose root is on the page +** iTable. If a read-only cursor is requested, it is assumed that +** the caller already has at least a read-only transaction open +** on the database already. If a write-cursor is requested, then +** the caller is assumed to have an open write transaction. +** +** If wrFlag==0, then the cursor can only be used for reading. +** If wrFlag==1, then the cursor can be used for reading or for +** writing if other conditions for writing are also met. These +** are the conditions that must be met in order for writing to +** be allowed: +** +** 1: The cursor must have been opened with wrFlag==1 +** +** 2: Other database connections that share the same pager cache +** but which are not in the READ_UNCOMMITTED state may not have +** cursors open with wrFlag==0 on the same table. Otherwise +** the changes made by this write cursor would be visible to +** the read cursors in the other database connection. +** +** 3: The database must be writable (not on read-only media) +** +** 4: There must be an active transaction. +** +** No checking is done to make sure that page iTable really is the +** root page of a b-tree. If it is not, then the cursor acquired +** will not work correctly. +** +** It is assumed that the sqlite3BtreeCursorZero() has been called +** on pCur to initialize the memory space prior to invoking this routine. +*/ +static int btreeCursor( + Btree *p, /* The btree */ + int iTable, /* Root page of table to open */ + int wrFlag, /* 1 to write. 0 read-only */ + struct KeyInfo *pKeyInfo, /* First arg to comparison function */ + BtCursor *pCur /* Space for new cursor */ +){ + BtShared *pBt = p->pBt; /* Shared b-tree handle */ + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( wrFlag==0 || wrFlag==1 ); + + /* The following assert statements verify that if this is a sharable + ** b-tree database, the connection is holding the required table locks, + ** and that no other connection has any open cursor that conflicts with + ** this lock. */ + assert( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, wrFlag+1) ); + assert( wrFlag==0 || !hasReadConflicts(p, iTable) ); + + /* Assert that the caller has opened the required transaction. */ + assert( p->inTrans>TRANS_NONE ); + assert( wrFlag==0 || p->inTrans==TRANS_WRITE ); + assert( pBt->pPage1 && pBt->pPage1->aData ); + + if( NEVER(wrFlag && (pBt->btsFlags & BTS_READ_ONLY)!=0) ){ + return SQLITE_READONLY; + } + if( iTable==1 && btreePagecount(pBt)==0 ){ + assert( wrFlag==0 ); + iTable = 0; + } + + /* Now that no other errors can occur, finish filling in the BtCursor + ** variables and link the cursor into the BtShared list. */ + pCur->pgnoRoot = (Pgno)iTable; + pCur->iPage = -1; + pCur->pKeyInfo = pKeyInfo; + pCur->pBtree = p; + pCur->pBt = pBt; + pCur->wrFlag = (u8)wrFlag; + pCur->pNext = pBt->pCursor; + if( pCur->pNext ){ + pCur->pNext->pPrev = pCur; + } + pBt->pCursor = pCur; + pCur->eState = CURSOR_INVALID; + pCur->cachedRowid = 0; + return SQLITE_OK; +} +int sqlite3BtreeCursor( + Btree *p, /* The btree */ + int iTable, /* Root page of table to open */ + int wrFlag, /* 1 to write. 0 read-only */ + struct KeyInfo *pKeyInfo, /* First arg to xCompare() */ + BtCursor *pCur /* Write new cursor here */ +){ + int rc; + sqlite3BtreeEnter(p); + rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur); + sqlite3BtreeLeave(p); + return rc; +} + +/* +** Return the size of a BtCursor object in bytes. +** +** This interfaces is needed so that users of cursors can preallocate +** sufficient storage to hold a cursor. The BtCursor object is opaque +** to users so they cannot do the sizeof() themselves - they must call +** this routine. +*/ +int sqlite3BtreeCursorSize(void){ + return ROUND8(sizeof(BtCursor)); +} + +/* +** Initialize memory that will be converted into a BtCursor object. +** +** The simple approach here would be to memset() the entire object +** to zero. But it turns out that the apPage[] and aiIdx[] arrays +** do not need to be zeroed and they are large, so we can save a lot +** of run-time by skipping the initialization of those elements. +*/ +void sqlite3BtreeCursorZero(BtCursor *p){ + memset(p, 0, offsetof(BtCursor, iPage)); +} + +/* +** Set the cached rowid value of every cursor in the same database file +** as pCur and having the same root page number as pCur. The value is +** set to iRowid. +** +** Only positive rowid values are considered valid for this cache. +** The cache is initialized to zero, indicating an invalid cache. +** A btree will work fine with zero or negative rowids. We just cannot +** cache zero or negative rowids, which means tables that use zero or +** negative rowids might run a little slower. But in practice, zero +** or negative rowids are very uncommon so this should not be a problem. +*/ +void sqlite3BtreeSetCachedRowid(BtCursor *pCur, sqlite3_int64 iRowid){ + BtCursor *p; + for(p=pCur->pBt->pCursor; p; p=p->pNext){ + if( p->pgnoRoot==pCur->pgnoRoot ) p->cachedRowid = iRowid; + } + assert( pCur->cachedRowid==iRowid ); +} + +/* +** Return the cached rowid for the given cursor. A negative or zero +** return value indicates that the rowid cache is invalid and should be +** ignored. If the rowid cache has never before been set, then a +** zero is returned. +*/ +sqlite3_int64 sqlite3BtreeGetCachedRowid(BtCursor *pCur){ + return pCur->cachedRowid; +} + +/* +** Close a cursor. The read lock on the database file is released +** when the last cursor is closed. +*/ +int sqlite3BtreeCloseCursor(BtCursor *pCur){ + Btree *pBtree = pCur->pBtree; + if( pBtree ){ + int i; + BtShared *pBt = pCur->pBt; + sqlite3BtreeEnter(pBtree); + sqlite3BtreeClearCursor(pCur); + if( pCur->pPrev ){ + pCur->pPrev->pNext = pCur->pNext; + }else{ + pBt->pCursor = pCur->pNext; + } + if( pCur->pNext ){ + pCur->pNext->pPrev = pCur->pPrev; + } + for(i=0; i<=pCur->iPage; i++){ + releasePage(pCur->apPage[i]); + } + unlockBtreeIfUnused(pBt); + invalidateOverflowCache(pCur); + /* sqlite3_free(pCur); */ + sqlite3BtreeLeave(pBtree); + } + return SQLITE_OK; +} + +/* +** Make sure the BtCursor* given in the argument has a valid +** BtCursor.info structure. If it is not already valid, call +** btreeParseCell() to fill it in. +** +** BtCursor.info is a cache of the information in the current cell. +** Using this cache reduces the number of calls to btreeParseCell(). +** +** 2007-06-25: There is a bug in some versions of MSVC that cause the +** compiler to crash when getCellInfo() is implemented as a macro. +** But there is a measureable speed advantage to using the macro on gcc +** (when less compiler optimizations like -Os or -O0 are used and the +** compiler is not doing agressive inlining.) So we use a real function +** for MSVC and a macro for everything else. Ticket #2457. +*/ +#ifndef NDEBUG + static void assertCellInfo(BtCursor *pCur){ + CellInfo info; + int iPage = pCur->iPage; + memset(&info, 0, sizeof(info)); + btreeParseCell(pCur->apPage[iPage], pCur->aiIdx[iPage], &info); + assert( memcmp(&info, &pCur->info, sizeof(info))==0 ); + } +#else + #define assertCellInfo(x) +#endif +#ifdef _MSC_VER + /* Use a real function in MSVC to work around bugs in that compiler. */ + static void getCellInfo(BtCursor *pCur){ + if( pCur->info.nSize==0 ){ + int iPage = pCur->iPage; + btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info); + pCur->validNKey = 1; + }else{ + assertCellInfo(pCur); + } + } +#else /* if not _MSC_VER */ + /* Use a macro in all other compilers so that the function is inlined */ +#define getCellInfo(pCur) \ + if( pCur->info.nSize==0 ){ \ + int iPage = pCur->iPage; \ + btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info); \ + pCur->validNKey = 1; \ + }else{ \ + assertCellInfo(pCur); \ + } +#endif /* _MSC_VER */ + +#ifndef NDEBUG /* The next routine used only within assert() statements */ +/* +** Return true if the given BtCursor is valid. A valid cursor is one +** that is currently pointing to a row in a (non-empty) table. +** This is a verification routine is used only within assert() statements. +*/ +int sqlite3BtreeCursorIsValid(BtCursor *pCur){ + return pCur && pCur->eState==CURSOR_VALID; +} +#endif /* NDEBUG */ + +/* +** Set *pSize to the size of the buffer needed to hold the value of +** the key for the current entry. If the cursor is not pointing +** to a valid entry, *pSize is set to 0. +** +** For a table with the INTKEY flag set, this routine returns the key +** itself, not the number of bytes in the key. +** +** The caller must position the cursor prior to invoking this routine. +** +** This routine cannot fail. It always returns SQLITE_OK. +*/ +int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){ + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID ); + if( pCur->eState!=CURSOR_VALID ){ + *pSize = 0; + }else{ + getCellInfo(pCur); + *pSize = pCur->info.nKey; + } + return SQLITE_OK; +} + +/* +** Set *pSize to the number of bytes of data in the entry the +** cursor currently points to. +** +** The caller must guarantee that the cursor is pointing to a non-NULL +** valid entry. In other words, the calling procedure must guarantee +** that the cursor has Cursor.eState==CURSOR_VALID. +** +** Failure is not possible. This function always returns SQLITE_OK. +** It might just as well be a procedure (returning void) but we continue +** to return an integer result code for historical reasons. +*/ +int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){ + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + getCellInfo(pCur); + *pSize = pCur->info.nData; + return SQLITE_OK; +} + +/* +** Given the page number of an overflow page in the database (parameter +** ovfl), this function finds the page number of the next page in the +** linked list of overflow pages. If possible, it uses the auto-vacuum +** pointer-map data instead of reading the content of page ovfl to do so. +** +** If an error occurs an SQLite error code is returned. Otherwise: +** +** The page number of the next overflow page in the linked list is +** written to *pPgnoNext. If page ovfl is the last page in its linked +** list, *pPgnoNext is set to zero. +** +** If ppPage is not NULL, and a reference to the MemPage object corresponding +** to page number pOvfl was obtained, then *ppPage is set to point to that +** reference. It is the responsibility of the caller to call releasePage() +** on *ppPage to free the reference. In no reference was obtained (because +** the pointer-map was used to obtain the value for *pPgnoNext), then +** *ppPage is set to zero. +*/ +static int getOverflowPage( + BtShared *pBt, /* The database file */ + Pgno ovfl, /* Current overflow page number */ + MemPage **ppPage, /* OUT: MemPage handle (may be NULL) */ + Pgno *pPgnoNext /* OUT: Next overflow page number */ +){ + Pgno next = 0; + MemPage *pPage = 0; + int rc = SQLITE_OK; + + assert( sqlite3_mutex_held(pBt->mutex) ); + assert(pPgnoNext); + +#ifndef SQLITE_OMIT_AUTOVACUUM + /* Try to find the next page in the overflow list using the + ** autovacuum pointer-map pages. Guess that the next page in + ** the overflow list is page number (ovfl+1). If that guess turns + ** out to be wrong, fall back to loading the data of page + ** number ovfl to determine the next page number. + */ + if( pBt->autoVacuum ){ + Pgno pgno; + Pgno iGuess = ovfl+1; + u8 eType; + + while( PTRMAP_ISPAGE(pBt, iGuess) || iGuess==PENDING_BYTE_PAGE(pBt) ){ + iGuess++; + } + + if( iGuess<=btreePagecount(pBt) ){ + rc = ptrmapGet(pBt, iGuess, &eType, &pgno); + if( rc==SQLITE_OK && eType==PTRMAP_OVERFLOW2 && pgno==ovfl ){ + next = iGuess; + rc = SQLITE_DONE; + } + } + } +#endif + + assert( next==0 || rc==SQLITE_DONE ); + if( rc==SQLITE_OK ){ + rc = btreeGetPage(pBt, ovfl, &pPage, 0); + assert( rc==SQLITE_OK || pPage==0 ); + if( rc==SQLITE_OK ){ + next = get4byte(pPage->aData); + } + } + + *pPgnoNext = next; + if( ppPage ){ + *ppPage = pPage; + }else{ + releasePage(pPage); + } + return (rc==SQLITE_DONE ? SQLITE_OK : rc); +} + +/* +** Copy data from a buffer to a page, or from a page to a buffer. +** +** pPayload is a pointer to data stored on database page pDbPage. +** If argument eOp is false, then nByte bytes of data are copied +** from pPayload to the buffer pointed at by pBuf. If eOp is true, +** then sqlite3PagerWrite() is called on pDbPage and nByte bytes +** of data are copied from the buffer pBuf to pPayload. +** +** SQLITE_OK is returned on success, otherwise an error code. +*/ +static int copyPayload( + void *pPayload, /* Pointer to page data */ + void *pBuf, /* Pointer to buffer */ + int nByte, /* Number of bytes to copy */ + int eOp, /* 0 -> copy from page, 1 -> copy to page */ + DbPage *pDbPage /* Page containing pPayload */ +){ + if( eOp ){ + /* Copy data from buffer to page (a write operation) */ + int rc = sqlite3PagerWrite(pDbPage); + if( rc!=SQLITE_OK ){ + return rc; + } + memcpy(pPayload, pBuf, nByte); + }else{ + /* Copy data from page to buffer (a read operation) */ + memcpy(pBuf, pPayload, nByte); + } + return SQLITE_OK; +} + +/* +** This function is used to read or overwrite payload information +** for the entry that the pCur cursor is pointing to. If the eOp +** parameter is 0, this is a read operation (data copied into +** buffer pBuf). If it is non-zero, a write (data copied from +** buffer pBuf). +** +** A total of "amt" bytes are read or written beginning at "offset". +** Data is read to or from the buffer pBuf. +** +** The content being read or written might appear on the main page +** or be scattered out on multiple overflow pages. +** +** If the BtCursor.isIncrblobHandle flag is set, and the current +** cursor entry uses one or more overflow pages, this function +** allocates space for and lazily popluates the overflow page-list +** cache array (BtCursor.aOverflow). Subsequent calls use this +** cache to make seeking to the supplied offset more efficient. +** +** Once an overflow page-list cache has been allocated, it may be +** invalidated if some other cursor writes to the same table, or if +** the cursor is moved to a different row. Additionally, in auto-vacuum +** mode, the following events may invalidate an overflow page-list cache. +** +** * An incremental vacuum, +** * A commit in auto_vacuum="full" mode, +** * Creating a table (may require moving an overflow page). +*/ +static int accessPayload( + BtCursor *pCur, /* Cursor pointing to entry to read from */ + u32 offset, /* Begin reading this far into payload */ + u32 amt, /* Read this many bytes */ + unsigned char *pBuf, /* Write the bytes into this buffer */ + int eOp /* zero to read. non-zero to write. */ +){ + unsigned char *aPayload; + int rc = SQLITE_OK; + u32 nKey; + int iIdx = 0; + MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */ + BtShared *pBt = pCur->pBt; /* Btree this cursor belongs to */ + + assert( pPage ); + assert( pCur->eState==CURSOR_VALID ); + assert( pCur->aiIdx[pCur->iPage]nCell ); + assert( cursorHoldsMutex(pCur) ); + + getCellInfo(pCur); + aPayload = pCur->info.pCell + pCur->info.nHeader; + nKey = (pPage->intKey ? 0 : (int)pCur->info.nKey); + + if( NEVER(offset+amt > nKey+pCur->info.nData) + || &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize] + ){ + /* Trying to read or write past the end of the data is an error */ + return SQLITE_CORRUPT_BKPT; + } + + /* Check if data must be read/written to/from the btree page itself. */ + if( offsetinfo.nLocal ){ + int a = amt; + if( a+offset>pCur->info.nLocal ){ + a = pCur->info.nLocal - offset; + } + rc = copyPayload(&aPayload[offset], pBuf, a, eOp, pPage->pDbPage); + offset = 0; + pBuf += a; + amt -= a; + }else{ + offset -= pCur->info.nLocal; + } + + if( rc==SQLITE_OK && amt>0 ){ + const u32 ovflSize = pBt->usableSize - 4; /* Bytes content per ovfl page */ + Pgno nextPage; + + nextPage = get4byte(&aPayload[pCur->info.nLocal]); + +#ifndef SQLITE_OMIT_INCRBLOB + /* If the isIncrblobHandle flag is set and the BtCursor.aOverflow[] + ** has not been allocated, allocate it now. The array is sized at + ** one entry for each overflow page in the overflow chain. The + ** page number of the first overflow page is stored in aOverflow[0], + ** etc. A value of 0 in the aOverflow[] array means "not yet known" + ** (the cache is lazily populated). + */ + if( pCur->isIncrblobHandle && !pCur->aOverflow ){ + int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize; + pCur->aOverflow = (Pgno *)sqlite3MallocZero(sizeof(Pgno)*nOvfl); + /* nOvfl is always positive. If it were zero, fetchPayload would have + ** been used instead of this routine. */ + if( ALWAYS(nOvfl) && !pCur->aOverflow ){ + rc = SQLITE_NOMEM; + } + } + + /* If the overflow page-list cache has been allocated and the + ** entry for the first required overflow page is valid, skip + ** directly to it. + */ + if( pCur->aOverflow && pCur->aOverflow[offset/ovflSize] ){ + iIdx = (offset/ovflSize); + nextPage = pCur->aOverflow[iIdx]; + offset = (offset%ovflSize); + } +#endif + + for( ; rc==SQLITE_OK && amt>0 && nextPage; iIdx++){ + +#ifndef SQLITE_OMIT_INCRBLOB + /* If required, populate the overflow page-list cache. */ + if( pCur->aOverflow ){ + assert(!pCur->aOverflow[iIdx] || pCur->aOverflow[iIdx]==nextPage); + pCur->aOverflow[iIdx] = nextPage; + } +#endif + + if( offset>=ovflSize ){ + /* The only reason to read this page is to obtain the page + ** number for the next page in the overflow chain. The page + ** data is not required. So first try to lookup the overflow + ** page-list cache, if any, then fall back to the getOverflowPage() + ** function. + */ +#ifndef SQLITE_OMIT_INCRBLOB + if( pCur->aOverflow && pCur->aOverflow[iIdx+1] ){ + nextPage = pCur->aOverflow[iIdx+1]; + } else +#endif + rc = getOverflowPage(pBt, nextPage, 0, &nextPage); + offset -= ovflSize; + }else{ + /* Need to read this page properly. It contains some of the + ** range of data that is being read (eOp==0) or written (eOp!=0). + */ +#ifdef SQLITE_DIRECT_OVERFLOW_READ + sqlite3_file *fd; +#endif + int a = amt; + if( a + offset > ovflSize ){ + a = ovflSize - offset; + } + +#ifdef SQLITE_DIRECT_OVERFLOW_READ + /* If all the following are true: + ** + ** 1) this is a read operation, and + ** 2) data is required from the start of this overflow page, and + ** 3) the database is file-backed, and + ** 4) there is no open write-transaction, and + ** 5) the database is not a WAL database, + ** + ** then data can be read directly from the database file into the + ** output buffer, bypassing the page-cache altogether. This speeds + ** up loading large records that span many overflow pages. + */ + if( eOp==0 /* (1) */ + && offset==0 /* (2) */ + && pBt->inTransaction==TRANS_READ /* (4) */ + && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (3) */ + && pBt->pPage1->aData[19]==0x01 /* (5) */ + ){ + u8 aSave[4]; + u8 *aWrite = &pBuf[-4]; + memcpy(aSave, aWrite, 4); + rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1)); + nextPage = get4byte(aWrite); + memcpy(aWrite, aSave, 4); + }else +#endif + + { + DbPage *pDbPage; + rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage); + if( rc==SQLITE_OK ){ + aPayload = sqlite3PagerGetData(pDbPage); + nextPage = get4byte(aPayload); + rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage); + sqlite3PagerUnref(pDbPage); + offset = 0; + } + } + amt -= a; + pBuf += a; + } + } + } + + if( rc==SQLITE_OK && amt>0 ){ + return SQLITE_CORRUPT_BKPT; + } + return rc; +} + +/* +** Read part of the key associated with cursor pCur. Exactly +** "amt" bytes will be transfered into pBuf[]. The transfer +** begins at "offset". +** +** The caller must ensure that pCur is pointing to a valid row +** in the table. +** +** Return SQLITE_OK on success or an error code if anything goes +** wrong. An error is returned if "offset+amt" is larger than +** the available payload. +*/ +int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] ); + assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); + return accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0); +} + +/* +** Read part of the data associated with cursor pCur. Exactly +** "amt" bytes will be transfered into pBuf[]. The transfer +** begins at "offset". +** +** Return SQLITE_OK on success or an error code if anything goes +** wrong. An error is returned if "offset+amt" is larger than +** the available payload. +*/ +int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ + int rc; + +#ifndef SQLITE_OMIT_INCRBLOB + if ( pCur->eState==CURSOR_INVALID ){ + return SQLITE_ABORT; + } +#endif + + assert( cursorHoldsMutex(pCur) ); + rc = restoreCursorPosition(pCur); + if( rc==SQLITE_OK ){ + assert( pCur->eState==CURSOR_VALID ); + assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] ); + assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); + rc = accessPayload(pCur, offset, amt, pBuf, 0); + } + return rc; +} + +/* +** Return a pointer to payload information from the entry that the +** pCur cursor is pointing to. The pointer is to the beginning of +** the key if skipKey==0 and it points to the beginning of data if +** skipKey==1. The number of bytes of available key/data is written +** into *pAmt. If *pAmt==0, then the value returned will not be +** a valid pointer. +** +** This routine is an optimization. It is common for the entire key +** and data to fit on the local page and for there to be no overflow +** pages. When that is so, this routine can be used to access the +** key and data without making a copy. If the key and/or data spills +** onto overflow pages, then accessPayload() must be used to reassemble +** the key/data and copy it into a preallocated buffer. +** +** The pointer returned by this routine looks directly into the cached +** page of the database. The data might change or move the next time +** any btree routine is called. +*/ +static const unsigned char *fetchPayload( + BtCursor *pCur, /* Cursor pointing to entry to read from */ + int *pAmt, /* Write the number of available bytes here */ + int skipKey /* read beginning at data if this is true */ +){ + unsigned char *aPayload; + MemPage *pPage; + u32 nKey; + u32 nLocal; + + assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]); + assert( pCur->eState==CURSOR_VALID ); + assert( cursorHoldsMutex(pCur) ); + pPage = pCur->apPage[pCur->iPage]; + assert( pCur->aiIdx[pCur->iPage]nCell ); + if( NEVER(pCur->info.nSize==0) ){ + btreeParseCell(pCur->apPage[pCur->iPage], pCur->aiIdx[pCur->iPage], + &pCur->info); + } + aPayload = pCur->info.pCell; + aPayload += pCur->info.nHeader; + if( pPage->intKey ){ + nKey = 0; + }else{ + nKey = (int)pCur->info.nKey; + } + if( skipKey ){ + aPayload += nKey; + nLocal = pCur->info.nLocal - nKey; + }else{ + nLocal = pCur->info.nLocal; + assert( nLocal<=nKey ); + } + *pAmt = nLocal; + return aPayload; +} + + +/* +** For the entry that cursor pCur is point to, return as +** many bytes of the key or data as are available on the local +** b-tree page. Write the number of available bytes into *pAmt. +** +** The pointer returned is ephemeral. The key/data may move +** or be destroyed on the next call to any Btree routine, +** including calls from other threads against the same cache. +** Hence, a mutex on the BtShared should be held prior to calling +** this routine. +** +** These routines is used to get quick access to key and data +** in the common case where no overflow pages are used. +*/ +const void *sqlite3BtreeKeyFetch(BtCursor *pCur, int *pAmt){ + const void *p = 0; + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + assert( cursorHoldsMutex(pCur) ); + if( ALWAYS(pCur->eState==CURSOR_VALID) ){ + p = (const void*)fetchPayload(pCur, pAmt, 0); + } + return p; +} +const void *sqlite3BtreeDataFetch(BtCursor *pCur, int *pAmt){ + const void *p = 0; + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + assert( cursorHoldsMutex(pCur) ); + if( ALWAYS(pCur->eState==CURSOR_VALID) ){ + p = (const void*)fetchPayload(pCur, pAmt, 1); + } + return p; +} + + +/* +** Move the cursor down to a new child page. The newPgno argument is the +** page number of the child page to move to. +** +** This function returns SQLITE_CORRUPT if the page-header flags field of +** the new child page does not match the flags field of the parent (i.e. +** if an intkey page appears to be the parent of a non-intkey page, or +** vice-versa). +*/ +static int moveToChild(BtCursor *pCur, u32 newPgno){ + int rc; + int i = pCur->iPage; + MemPage *pNewPage; + BtShared *pBt = pCur->pBt; + + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + assert( pCur->iPageiPage>=(BTCURSOR_MAX_DEPTH-1) ){ + return SQLITE_CORRUPT_BKPT; + } + rc = getAndInitPage(pBt, newPgno, &pNewPage); + if( rc ) return rc; + pCur->apPage[i+1] = pNewPage; + pCur->aiIdx[i+1] = 0; + pCur->iPage++; + + pCur->info.nSize = 0; + pCur->validNKey = 0; + if( pNewPage->nCell<1 || pNewPage->intKey!=pCur->apPage[i]->intKey ){ + return SQLITE_CORRUPT_BKPT; + } + return SQLITE_OK; +} + +#if 0 +/* +** Page pParent is an internal (non-leaf) tree page. This function +** asserts that page number iChild is the left-child if the iIdx'th +** cell in page pParent. Or, if iIdx is equal to the total number of +** cells in pParent, that page number iChild is the right-child of +** the page. +*/ +static void assertParentIndex(MemPage *pParent, int iIdx, Pgno iChild){ + assert( iIdx<=pParent->nCell ); + if( iIdx==pParent->nCell ){ + assert( get4byte(&pParent->aData[pParent->hdrOffset+8])==iChild ); + }else{ + assert( get4byte(findCell(pParent, iIdx))==iChild ); + } +} +#else +# define assertParentIndex(x,y,z) +#endif + +/* +** Move the cursor up to the parent page. +** +** pCur->idx is set to the cell index that contains the pointer +** to the page we are coming from. If we are coming from the +** right-most child page then pCur->idx is set to one more than +** the largest cell index. +*/ +static void moveToParent(BtCursor *pCur){ + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + assert( pCur->iPage>0 ); + assert( pCur->apPage[pCur->iPage] ); + + /* UPDATE: It is actually possible for the condition tested by the assert + ** below to be untrue if the database file is corrupt. This can occur if + ** one cursor has modified page pParent while a reference to it is held + ** by a second cursor. Which can only happen if a single page is linked + ** into more than one b-tree structure in a corrupt database. */ +#if 0 + assertParentIndex( + pCur->apPage[pCur->iPage-1], + pCur->aiIdx[pCur->iPage-1], + pCur->apPage[pCur->iPage]->pgno + ); +#endif + testcase( pCur->aiIdx[pCur->iPage-1] > pCur->apPage[pCur->iPage-1]->nCell ); + + releasePage(pCur->apPage[pCur->iPage]); + pCur->iPage--; + pCur->info.nSize = 0; + pCur->validNKey = 0; +} + +/* +** Move the cursor to point to the root page of its b-tree structure. +** +** If the table has a virtual root page, then the cursor is moved to point +** to the virtual root page instead of the actual root page. A table has a +** virtual root page when the actual root page contains no cells and a +** single child page. This can only happen with the table rooted at page 1. +** +** If the b-tree structure is empty, the cursor state is set to +** CURSOR_INVALID. Otherwise, the cursor is set to point to the first +** cell located on the root (or virtual root) page and the cursor state +** is set to CURSOR_VALID. +** +** If this function returns successfully, it may be assumed that the +** page-header flags indicate that the [virtual] root-page is the expected +** kind of b-tree page (i.e. if when opening the cursor the caller did not +** specify a KeyInfo structure the flags byte is set to 0x05 or 0x0D, +** indicating a table b-tree, or if the caller did specify a KeyInfo +** structure the flags byte is set to 0x02 or 0x0A, indicating an index +** b-tree). +*/ +static int moveToRoot(BtCursor *pCur){ + MemPage *pRoot; + int rc = SQLITE_OK; + Btree *p = pCur->pBtree; + BtShared *pBt = p->pBt; + + assert( cursorHoldsMutex(pCur) ); + assert( CURSOR_INVALID < CURSOR_REQUIRESEEK ); + assert( CURSOR_VALID < CURSOR_REQUIRESEEK ); + assert( CURSOR_FAULT > CURSOR_REQUIRESEEK ); + if( pCur->eState>=CURSOR_REQUIRESEEK ){ + if( pCur->eState==CURSOR_FAULT ){ + assert( pCur->skipNext!=SQLITE_OK ); + return pCur->skipNext; + } + sqlite3BtreeClearCursor(pCur); + } + + if( pCur->iPage>=0 ){ + int i; + for(i=1; i<=pCur->iPage; i++){ + releasePage(pCur->apPage[i]); + } + pCur->iPage = 0; + }else if( pCur->pgnoRoot==0 ){ + pCur->eState = CURSOR_INVALID; + return SQLITE_OK; + }else{ + rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0]); + if( rc!=SQLITE_OK ){ + pCur->eState = CURSOR_INVALID; + return rc; + } + pCur->iPage = 0; + + /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor + ** expected to open it on an index b-tree. Otherwise, if pKeyInfo is + ** NULL, the caller expects a table b-tree. If this is not the case, + ** return an SQLITE_CORRUPT error. */ + assert( pCur->apPage[0]->intKey==1 || pCur->apPage[0]->intKey==0 ); + if( (pCur->pKeyInfo==0)!=pCur->apPage[0]->intKey ){ + return SQLITE_CORRUPT_BKPT; + } + } + + /* Assert that the root page is of the correct type. This must be the + ** case as the call to this function that loaded the root-page (either + ** this call or a previous invocation) would have detected corruption + ** if the assumption were not true, and it is not possible for the flags + ** byte to have been modified while this cursor is holding a reference + ** to the page. */ + pRoot = pCur->apPage[0]; + assert( pRoot->pgno==pCur->pgnoRoot ); + assert( pRoot->isInit && (pCur->pKeyInfo==0)==pRoot->intKey ); + + pCur->aiIdx[0] = 0; + pCur->info.nSize = 0; + pCur->atLast = 0; + pCur->validNKey = 0; + + if( pRoot->nCell==0 && !pRoot->leaf ){ + Pgno subpage; + if( pRoot->pgno!=1 ) return SQLITE_CORRUPT_BKPT; + subpage = get4byte(&pRoot->aData[pRoot->hdrOffset+8]); + pCur->eState = CURSOR_VALID; + rc = moveToChild(pCur, subpage); + }else{ + pCur->eState = ((pRoot->nCell>0)?CURSOR_VALID:CURSOR_INVALID); + } + return rc; +} + +/* +** Move the cursor down to the left-most leaf entry beneath the +** entry to which it is currently pointing. +** +** The left-most leaf is the one with the smallest key - the first +** in ascending order. +*/ +static int moveToLeftmost(BtCursor *pCur){ + Pgno pgno; + int rc = SQLITE_OK; + MemPage *pPage; + + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){ + assert( pCur->aiIdx[pCur->iPage]nCell ); + pgno = get4byte(findCell(pPage, pCur->aiIdx[pCur->iPage])); + rc = moveToChild(pCur, pgno); + } + return rc; +} + +/* +** Move the cursor down to the right-most leaf entry beneath the +** page to which it is currently pointing. Notice the difference +** between moveToLeftmost() and moveToRightmost(). moveToLeftmost() +** finds the left-most entry beneath the *entry* whereas moveToRightmost() +** finds the right-most entry beneath the *page*. +** +** The right-most entry is the one with the largest key - the last +** key in ascending order. +*/ +static int moveToRightmost(BtCursor *pCur){ + Pgno pgno; + int rc = SQLITE_OK; + MemPage *pPage = 0; + + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){ + pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); + pCur->aiIdx[pCur->iPage] = pPage->nCell; + rc = moveToChild(pCur, pgno); + } + if( rc==SQLITE_OK ){ + pCur->aiIdx[pCur->iPage] = pPage->nCell-1; + pCur->info.nSize = 0; + pCur->validNKey = 0; + } + return rc; +} + +/* Move the cursor to the first entry in the table. Return SQLITE_OK +** on success. Set *pRes to 0 if the cursor actually points to something +** or set *pRes to 1 if the table is empty. +*/ +int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){ + int rc; + + assert( cursorHoldsMutex(pCur) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + rc = moveToRoot(pCur); + if( rc==SQLITE_OK ){ + if( pCur->eState==CURSOR_INVALID ){ + assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 ); + *pRes = 1; + }else{ + assert( pCur->apPage[pCur->iPage]->nCell>0 ); + *pRes = 0; + rc = moveToLeftmost(pCur); + } + } + return rc; +} + +/* Move the cursor to the last entry in the table. Return SQLITE_OK +** on success. Set *pRes to 0 if the cursor actually points to something +** or set *pRes to 1 if the table is empty. +*/ +int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ + int rc; + + assert( cursorHoldsMutex(pCur) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + + /* If the cursor already points to the last entry, this is a no-op. */ + if( CURSOR_VALID==pCur->eState && pCur->atLast ){ +#ifdef SQLITE_DEBUG + /* This block serves to assert() that the cursor really does point + ** to the last entry in the b-tree. */ + int ii; + for(ii=0; iiiPage; ii++){ + assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell ); + } + assert( pCur->aiIdx[pCur->iPage]==pCur->apPage[pCur->iPage]->nCell-1 ); + assert( pCur->apPage[pCur->iPage]->leaf ); +#endif + return SQLITE_OK; + } + + rc = moveToRoot(pCur); + if( rc==SQLITE_OK ){ + if( CURSOR_INVALID==pCur->eState ){ + assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 ); + *pRes = 1; + }else{ + assert( pCur->eState==CURSOR_VALID ); + *pRes = 0; + rc = moveToRightmost(pCur); + pCur->atLast = rc==SQLITE_OK ?1:0; + } + } + return rc; +} + +/* Move the cursor so that it points to an entry near the key +** specified by pIdxKey or intKey. Return a success code. +** +** For INTKEY tables, the intKey parameter is used. pIdxKey +** must be NULL. For index tables, pIdxKey is used and intKey +** is ignored. +** +** If an exact match is not found, then the cursor is always +** left pointing at a leaf page which would hold the entry if it +** were present. The cursor might point to an entry that comes +** before or after the key. +** +** An integer is written into *pRes which is the result of +** comparing the key with the entry to which the cursor is +** pointing. The meaning of the integer written into +** *pRes is as follows: +** +** *pRes<0 The cursor is left pointing at an entry that +** is smaller than intKey/pIdxKey or if the table is empty +** and the cursor is therefore left point to nothing. +** +** *pRes==0 The cursor is left pointing at an entry that +** exactly matches intKey/pIdxKey. +** +** *pRes>0 The cursor is left pointing at an entry that +** is larger than intKey/pIdxKey. +** +*/ +int sqlite3BtreeMovetoUnpacked( + BtCursor *pCur, /* The cursor to be moved */ + UnpackedRecord *pIdxKey, /* Unpacked index key */ + i64 intKey, /* The table key */ + int biasRight, /* If true, bias the search to the high end */ + int *pRes /* Write search results here */ +){ + int rc; + + assert( cursorHoldsMutex(pCur) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + assert( pRes ); + assert( (pIdxKey==0)==(pCur->pKeyInfo==0) ); + + /* If the cursor is already positioned at the point we are trying + ** to move to, then just return without doing any work */ + if( pCur->eState==CURSOR_VALID && pCur->validNKey + && pCur->apPage[0]->intKey + ){ + if( pCur->info.nKey==intKey ){ + *pRes = 0; + return SQLITE_OK; + } + if( pCur->atLast && pCur->info.nKeypgnoRoot==0 || pCur->apPage[pCur->iPage] ); + assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->isInit ); + assert( pCur->eState==CURSOR_INVALID || pCur->apPage[pCur->iPage]->nCell>0 ); + if( pCur->eState==CURSOR_INVALID ){ + *pRes = -1; + assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 ); + return SQLITE_OK; + } + assert( pCur->apPage[0]->intKey || pIdxKey ); + for(;;){ + int lwr, upr, idx; + Pgno chldPg; + MemPage *pPage = pCur->apPage[pCur->iPage]; + int c; + + /* pPage->nCell must be greater than zero. If this is the root-page + ** the cursor would have been INVALID above and this for(;;) loop + ** not run. If this is not the root-page, then the moveToChild() routine + ** would have already detected db corruption. Similarly, pPage must + ** be the right kind (index or table) of b-tree page. Otherwise + ** a moveToChild() or moveToRoot() call would have detected corruption. */ + assert( pPage->nCell>0 ); + assert( pPage->intKey==(pIdxKey==0) ); + lwr = 0; + upr = pPage->nCell-1; + if( biasRight ){ + pCur->aiIdx[pCur->iPage] = (u16)(idx = upr); + }else{ + pCur->aiIdx[pCur->iPage] = (u16)(idx = (upr+lwr)/2); + } + for(;;){ + u8 *pCell; /* Pointer to current cell in pPage */ + + assert( idx==pCur->aiIdx[pCur->iPage] ); + pCur->info.nSize = 0; + pCell = findCell(pPage, idx) + pPage->childPtrSize; + if( pPage->intKey ){ + i64 nCellKey; + if( pPage->hasData ){ + u32 dummy; + pCell += getVarint32(pCell, dummy); + } + getVarint(pCell, (u64*)&nCellKey); + if( nCellKey==intKey ){ + c = 0; + }else if( nCellKeyintKey ); + c = +1; + } + pCur->validNKey = 1; + pCur->info.nKey = nCellKey; + }else{ + /* The maximum supported page-size is 65536 bytes. This means that + ** the maximum number of record bytes stored on an index B-Tree + ** page is less than 16384 bytes and may be stored as a 2-byte + ** varint. This information is used to attempt to avoid parsing + ** the entire cell by checking for the cases where the record is + ** stored entirely within the b-tree page by inspecting the first + ** 2 bytes of the cell. + */ + int nCell = pCell[0]; + if( nCell<=pPage->max1bytePayload + /* && (pCell+nCell)aDataEnd */ + ){ + /* This branch runs if the record-size field of the cell is a + ** single byte varint and the record fits entirely on the main + ** b-tree page. */ + testcase( pCell+nCell+1==pPage->aDataEnd ); + c = sqlite3VdbeRecordCompare(nCell, (void*)&pCell[1], pIdxKey); + }else if( !(pCell[1] & 0x80) + && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal + /* && (pCell+nCell+2)<=pPage->aDataEnd */ + ){ + /* The record-size field is a 2 byte varint and the record + ** fits entirely on the main b-tree page. */ + testcase( pCell+nCell+2==pPage->aDataEnd ); + c = sqlite3VdbeRecordCompare(nCell, (void*)&pCell[2], pIdxKey); + }else{ + /* The record flows over onto one or more overflow pages. In + ** this case the whole cell needs to be parsed, a buffer allocated + ** and accessPayload() used to retrieve the record into the + ** buffer before VdbeRecordCompare() can be called. */ + void *pCellKey; + u8 * const pCellBody = pCell - pPage->childPtrSize; + btreeParseCellPtr(pPage, pCellBody, &pCur->info); + nCell = (int)pCur->info.nKey; + pCellKey = sqlite3Malloc( nCell ); + if( pCellKey==0 ){ + rc = SQLITE_NOMEM; + goto moveto_finish; + } + rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0); + if( rc ){ + sqlite3_free(pCellKey); + goto moveto_finish; + } + c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey); + sqlite3_free(pCellKey); + } + } + if( c==0 ){ + if( pPage->intKey && !pPage->leaf ){ + lwr = idx; + break; + }else{ + *pRes = 0; + rc = SQLITE_OK; + goto moveto_finish; + } + } + if( c<0 ){ + lwr = idx+1; + }else{ + upr = idx-1; + } + if( lwr>upr ){ + break; + } + pCur->aiIdx[pCur->iPage] = (u16)(idx = (lwr+upr)/2); + } + assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) ); + assert( pPage->isInit ); + if( pPage->leaf ){ + chldPg = 0; + }else if( lwr>=pPage->nCell ){ + chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]); + }else{ + chldPg = get4byte(findCell(pPage, lwr)); + } + if( chldPg==0 ){ + assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); + *pRes = c; + rc = SQLITE_OK; + goto moveto_finish; + } + pCur->aiIdx[pCur->iPage] = (u16)lwr; + pCur->info.nSize = 0; + pCur->validNKey = 0; + rc = moveToChild(pCur, chldPg); + if( rc ) goto moveto_finish; + } +moveto_finish: + return rc; +} + + +/* +** Return TRUE if the cursor is not pointing at an entry of the table. +** +** TRUE will be returned after a call to sqlite3BtreeNext() moves +** past the last entry in the table or sqlite3BtreePrev() moves past +** the first entry. TRUE is also returned if the table is empty. +*/ +int sqlite3BtreeEof(BtCursor *pCur){ + /* TODO: What if the cursor is in CURSOR_REQUIRESEEK but all table entries + ** have been deleted? This API will need to change to return an error code + ** as well as the boolean result value. + */ + return (CURSOR_VALID!=pCur->eState); +} + +/* +** Advance the cursor to the next entry in the database. If +** successful then set *pRes=0. If the cursor +** was already pointing to the last entry in the database before +** this routine was called, then set *pRes=1. +*/ +int sqlite3BtreeNext(BtCursor *pCur, int *pRes){ + int rc; + int idx; + MemPage *pPage; + + assert( cursorHoldsMutex(pCur) ); + rc = restoreCursorPosition(pCur); + if( rc!=SQLITE_OK ){ + return rc; + } + assert( pRes!=0 ); + if( CURSOR_INVALID==pCur->eState ){ + *pRes = 1; + return SQLITE_OK; + } + if( pCur->skipNext>0 ){ + pCur->skipNext = 0; + *pRes = 0; + return SQLITE_OK; + } + pCur->skipNext = 0; + + pPage = pCur->apPage[pCur->iPage]; + idx = ++pCur->aiIdx[pCur->iPage]; + assert( pPage->isInit ); + + /* If the database file is corrupt, it is possible for the value of idx + ** to be invalid here. This can only occur if a second cursor modifies + ** the page while cursor pCur is holding a reference to it. Which can + ** only happen if the database is corrupt in such a way as to link the + ** page into more than one b-tree structure. */ + testcase( idx>pPage->nCell ); + + pCur->info.nSize = 0; + pCur->validNKey = 0; + if( idx>=pPage->nCell ){ + if( !pPage->leaf ){ + rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8])); + if( rc ) return rc; + rc = moveToLeftmost(pCur); + *pRes = 0; + return rc; + } + do{ + if( pCur->iPage==0 ){ + *pRes = 1; + pCur->eState = CURSOR_INVALID; + return SQLITE_OK; + } + moveToParent(pCur); + pPage = pCur->apPage[pCur->iPage]; + }while( pCur->aiIdx[pCur->iPage]>=pPage->nCell ); + *pRes = 0; + if( pPage->intKey ){ + rc = sqlite3BtreeNext(pCur, pRes); + }else{ + rc = SQLITE_OK; + } + return rc; + } + *pRes = 0; + if( pPage->leaf ){ + return SQLITE_OK; + } + rc = moveToLeftmost(pCur); + return rc; +} + + +/* +** Step the cursor to the back to the previous entry in the database. If +** successful then set *pRes=0. If the cursor +** was already pointing to the first entry in the database before +** this routine was called, then set *pRes=1. +*/ +int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){ + int rc; + MemPage *pPage; + + assert( cursorHoldsMutex(pCur) ); + rc = restoreCursorPosition(pCur); + if( rc!=SQLITE_OK ){ + return rc; + } + pCur->atLast = 0; + if( CURSOR_INVALID==pCur->eState ){ + *pRes = 1; + return SQLITE_OK; + } + if( pCur->skipNext<0 ){ + pCur->skipNext = 0; + *pRes = 0; + return SQLITE_OK; + } + pCur->skipNext = 0; + + pPage = pCur->apPage[pCur->iPage]; + assert( pPage->isInit ); + if( !pPage->leaf ){ + int idx = pCur->aiIdx[pCur->iPage]; + rc = moveToChild(pCur, get4byte(findCell(pPage, idx))); + if( rc ){ + return rc; + } + rc = moveToRightmost(pCur); + }else{ + while( pCur->aiIdx[pCur->iPage]==0 ){ + if( pCur->iPage==0 ){ + pCur->eState = CURSOR_INVALID; + *pRes = 1; + return SQLITE_OK; + } + moveToParent(pCur); + } + pCur->info.nSize = 0; + pCur->validNKey = 0; + + pCur->aiIdx[pCur->iPage]--; + pPage = pCur->apPage[pCur->iPage]; + if( pPage->intKey && !pPage->leaf ){ + rc = sqlite3BtreePrevious(pCur, pRes); + }else{ + rc = SQLITE_OK; + } + } + *pRes = 0; + return rc; +} + +/* +** Allocate a new page from the database file. +** +** The new page is marked as dirty. (In other words, sqlite3PagerWrite() +** has already been called on the new page.) The new page has also +** been referenced and the calling routine is responsible for calling +** sqlite3PagerUnref() on the new page when it is done. +** +** SQLITE_OK is returned on success. Any other return value indicates +** an error. *ppPage and *pPgno are undefined in the event of an error. +** Do not invoke sqlite3PagerUnref() on *ppPage if an error is returned. +** +** If the "nearby" parameter is not 0, then a (feeble) effort is made to +** locate a page close to the page number "nearby". This can be used in an +** attempt to keep related pages close to each other in the database file, +** which in turn can make database access faster. +** +** If the "exact" parameter is not 0, and the page-number nearby exists +** anywhere on the free-list, then it is guarenteed to be returned. This +** is only used by auto-vacuum databases when allocating a new table. +*/ +static int allocateBtreePage( + BtShared *pBt, + MemPage **ppPage, + Pgno *pPgno, + Pgno nearby, + u8 exact +){ + MemPage *pPage1; + int rc; + u32 n; /* Number of pages on the freelist */ + u32 k; /* Number of leaves on the trunk of the freelist */ + MemPage *pTrunk = 0; + MemPage *pPrevTrunk = 0; + Pgno mxPage; /* Total size of the database file */ + + assert( sqlite3_mutex_held(pBt->mutex) ); + pPage1 = pBt->pPage1; + mxPage = btreePagecount(pBt); + n = get4byte(&pPage1->aData[36]); + testcase( n==mxPage-1 ); + if( n>=mxPage ){ + return SQLITE_CORRUPT_BKPT; + } + if( n>0 ){ + /* There are pages on the freelist. Reuse one of those pages. */ + Pgno iTrunk; + u8 searchList = 0; /* If the free-list must be searched for 'nearby' */ + + /* If the 'exact' parameter was true and a query of the pointer-map + ** shows that the page 'nearby' is somewhere on the free-list, then + ** the entire-list will be searched for that page. + */ +#ifndef SQLITE_OMIT_AUTOVACUUM + if( exact && nearby<=mxPage ){ + u8 eType; + assert( nearby>0 ); + assert( pBt->autoVacuum ); + rc = ptrmapGet(pBt, nearby, &eType, 0); + if( rc ) return rc; + if( eType==PTRMAP_FREEPAGE ){ + searchList = 1; + } + *pPgno = nearby; + } +#endif + + /* Decrement the free-list count by 1. Set iTrunk to the index of the + ** first free-list trunk page. iPrevTrunk is initially 1. + */ + rc = sqlite3PagerWrite(pPage1->pDbPage); + if( rc ) return rc; + put4byte(&pPage1->aData[36], n-1); + + /* The code within this loop is run only once if the 'searchList' variable + ** is not true. Otherwise, it runs once for each trunk-page on the + ** free-list until the page 'nearby' is located. + */ + do { + pPrevTrunk = pTrunk; + if( pPrevTrunk ){ + iTrunk = get4byte(&pPrevTrunk->aData[0]); + }else{ + iTrunk = get4byte(&pPage1->aData[32]); + } + testcase( iTrunk==mxPage ); + if( iTrunk>mxPage ){ + rc = SQLITE_CORRUPT_BKPT; + }else{ + rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0); + } + if( rc ){ + pTrunk = 0; + goto end_allocate_page; + } + assert( pTrunk!=0 ); + assert( pTrunk->aData!=0 ); + + k = get4byte(&pTrunk->aData[4]); /* # of leaves on this trunk page */ + if( k==0 && !searchList ){ + /* The trunk has no leaves and the list is not being searched. + ** So extract the trunk page itself and use it as the newly + ** allocated page */ + assert( pPrevTrunk==0 ); + rc = sqlite3PagerWrite(pTrunk->pDbPage); + if( rc ){ + goto end_allocate_page; + } + *pPgno = iTrunk; + memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); + *ppPage = pTrunk; + pTrunk = 0; + TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); + }else if( k>(u32)(pBt->usableSize/4 - 2) ){ + /* Value of k is out of range. Database corruption */ + rc = SQLITE_CORRUPT_BKPT; + goto end_allocate_page; +#ifndef SQLITE_OMIT_AUTOVACUUM + }else if( searchList && nearby==iTrunk ){ + /* The list is being searched and this trunk page is the page + ** to allocate, regardless of whether it has leaves. + */ + assert( *pPgno==iTrunk ); + *ppPage = pTrunk; + searchList = 0; + rc = sqlite3PagerWrite(pTrunk->pDbPage); + if( rc ){ + goto end_allocate_page; + } + if( k==0 ){ + if( !pPrevTrunk ){ + memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); + }else{ + rc = sqlite3PagerWrite(pPrevTrunk->pDbPage); + if( rc!=SQLITE_OK ){ + goto end_allocate_page; + } + memcpy(&pPrevTrunk->aData[0], &pTrunk->aData[0], 4); + } + }else{ + /* The trunk page is required by the caller but it contains + ** pointers to free-list leaves. The first leaf becomes a trunk + ** page in this case. + */ + MemPage *pNewTrunk; + Pgno iNewTrunk = get4byte(&pTrunk->aData[8]); + if( iNewTrunk>mxPage ){ + rc = SQLITE_CORRUPT_BKPT; + goto end_allocate_page; + } + testcase( iNewTrunk==mxPage ); + rc = btreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0); + if( rc!=SQLITE_OK ){ + goto end_allocate_page; + } + rc = sqlite3PagerWrite(pNewTrunk->pDbPage); + if( rc!=SQLITE_OK ){ + releasePage(pNewTrunk); + goto end_allocate_page; + } + memcpy(&pNewTrunk->aData[0], &pTrunk->aData[0], 4); + put4byte(&pNewTrunk->aData[4], k-1); + memcpy(&pNewTrunk->aData[8], &pTrunk->aData[12], (k-1)*4); + releasePage(pNewTrunk); + if( !pPrevTrunk ){ + assert( sqlite3PagerIswriteable(pPage1->pDbPage) ); + put4byte(&pPage1->aData[32], iNewTrunk); + }else{ + rc = sqlite3PagerWrite(pPrevTrunk->pDbPage); + if( rc ){ + goto end_allocate_page; + } + put4byte(&pPrevTrunk->aData[0], iNewTrunk); + } + } + pTrunk = 0; + TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); +#endif + }else if( k>0 ){ + /* Extract a leaf from the trunk */ + u32 closest; + Pgno iPage; + unsigned char *aData = pTrunk->aData; + if( nearby>0 ){ + u32 i; + int dist; + closest = 0; + dist = sqlite3AbsInt32(get4byte(&aData[8]) - nearby); + for(i=1; imxPage ){ + rc = SQLITE_CORRUPT_BKPT; + goto end_allocate_page; + } + testcase( iPage==mxPage ); + if( !searchList || iPage==nearby ){ + int noContent; + *pPgno = iPage; + TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d" + ": %d more free pages\n", + *pPgno, closest+1, k, pTrunk->pgno, n-1)); + rc = sqlite3PagerWrite(pTrunk->pDbPage); + if( rc ) goto end_allocate_page; + if( closestpDbPage); + if( rc!=SQLITE_OK ){ + releasePage(*ppPage); + } + } + searchList = 0; + } + } + releasePage(pPrevTrunk); + pPrevTrunk = 0; + }while( searchList ); + }else{ + /* There are no pages on the freelist, so create a new page at the + ** end of the file */ + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + if( rc ) return rc; + pBt->nPage++; + if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ) pBt->nPage++; + +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt, pBt->nPage) ){ + /* If *pPgno refers to a pointer-map page, allocate two new pages + ** at the end of the file instead of one. The first allocated page + ** becomes a new pointer-map page, the second is used by the caller. + */ + MemPage *pPg = 0; + TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage)); + assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) ); + rc = btreeGetPage(pBt, pBt->nPage, &pPg, 1); + if( rc==SQLITE_OK ){ + rc = sqlite3PagerWrite(pPg->pDbPage); + releasePage(pPg); + } + if( rc ) return rc; + pBt->nPage++; + if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ){ pBt->nPage++; } + } +#endif + put4byte(28 + (u8*)pBt->pPage1->aData, pBt->nPage); + *pPgno = pBt->nPage; + + assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); + rc = btreeGetPage(pBt, *pPgno, ppPage, 1); + if( rc ) return rc; + rc = sqlite3PagerWrite((*ppPage)->pDbPage); + if( rc!=SQLITE_OK ){ + releasePage(*ppPage); + } + TRACE(("ALLOCATE: %d from end of file\n", *pPgno)); + } + + assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); + +end_allocate_page: + releasePage(pTrunk); + releasePage(pPrevTrunk); + if( rc==SQLITE_OK ){ + if( sqlite3PagerPageRefcount((*ppPage)->pDbPage)>1 ){ + releasePage(*ppPage); + return SQLITE_CORRUPT_BKPT; + } + (*ppPage)->isInit = 0; + }else{ + *ppPage = 0; + } + assert( rc!=SQLITE_OK || sqlite3PagerIswriteable((*ppPage)->pDbPage) ); + return rc; +} + +/* +** This function is used to add page iPage to the database file free-list. +** It is assumed that the page is not already a part of the free-list. +** +** The value passed as the second argument to this function is optional. +** If the caller happens to have a pointer to the MemPage object +** corresponding to page iPage handy, it may pass it as the second value. +** Otherwise, it may pass NULL. +** +** If a pointer to a MemPage object is passed as the second argument, +** its reference count is not altered by this function. +*/ +static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){ + MemPage *pTrunk = 0; /* Free-list trunk page */ + Pgno iTrunk = 0; /* Page number of free-list trunk page */ + MemPage *pPage1 = pBt->pPage1; /* Local reference to page 1 */ + MemPage *pPage; /* Page being freed. May be NULL. */ + int rc; /* Return Code */ + int nFree; /* Initial number of pages on free-list */ + + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( iPage>1 ); + assert( !pMemPage || pMemPage->pgno==iPage ); + + if( pMemPage ){ + pPage = pMemPage; + sqlite3PagerRef(pPage->pDbPage); + }else{ + pPage = btreePageLookup(pBt, iPage); + } + + /* Increment the free page count on pPage1 */ + rc = sqlite3PagerWrite(pPage1->pDbPage); + if( rc ) goto freepage_out; + nFree = get4byte(&pPage1->aData[36]); + put4byte(&pPage1->aData[36], nFree+1); + + if( pBt->btsFlags & BTS_SECURE_DELETE ){ + /* If the secure_delete option is enabled, then + ** always fully overwrite deleted information with zeros. + */ + if( (!pPage && ((rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0) ) + || ((rc = sqlite3PagerWrite(pPage->pDbPage))!=0) + ){ + goto freepage_out; + } + memset(pPage->aData, 0, pPage->pBt->pageSize); + } + + /* If the database supports auto-vacuum, write an entry in the pointer-map + ** to indicate that the page is free. + */ + if( ISAUTOVACUUM ){ + ptrmapPut(pBt, iPage, PTRMAP_FREEPAGE, 0, &rc); + if( rc ) goto freepage_out; + } + + /* Now manipulate the actual database free-list structure. There are two + ** possibilities. If the free-list is currently empty, or if the first + ** trunk page in the free-list is full, then this page will become a + ** new free-list trunk page. Otherwise, it will become a leaf of the + ** first trunk page in the current free-list. This block tests if it + ** is possible to add the page as a new free-list leaf. + */ + if( nFree!=0 ){ + u32 nLeaf; /* Initial number of leaf cells on trunk page */ + + iTrunk = get4byte(&pPage1->aData[32]); + rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0); + if( rc!=SQLITE_OK ){ + goto freepage_out; + } + + nLeaf = get4byte(&pTrunk->aData[4]); + assert( pBt->usableSize>32 ); + if( nLeaf > (u32)pBt->usableSize/4 - 2 ){ + rc = SQLITE_CORRUPT_BKPT; + goto freepage_out; + } + if( nLeaf < (u32)pBt->usableSize/4 - 8 ){ + /* In this case there is room on the trunk page to insert the page + ** being freed as a new leaf. + ** + ** Note that the trunk page is not really full until it contains + ** usableSize/4 - 2 entries, not usableSize/4 - 8 entries as we have + ** coded. But due to a coding error in versions of SQLite prior to + ** 3.6.0, databases with freelist trunk pages holding more than + ** usableSize/4 - 8 entries will be reported as corrupt. In order + ** to maintain backwards compatibility with older versions of SQLite, + ** we will continue to restrict the number of entries to usableSize/4 - 8 + ** for now. At some point in the future (once everyone has upgraded + ** to 3.6.0 or later) we should consider fixing the conditional above + ** to read "usableSize/4-2" instead of "usableSize/4-8". + */ + rc = sqlite3PagerWrite(pTrunk->pDbPage); + if( rc==SQLITE_OK ){ + put4byte(&pTrunk->aData[4], nLeaf+1); + put4byte(&pTrunk->aData[8+nLeaf*4], iPage); + if( pPage && (pBt->btsFlags & BTS_SECURE_DELETE)==0 ){ + sqlite3PagerDontWrite(pPage->pDbPage); + } + rc = btreeSetHasContent(pBt, iPage); + } + TRACE(("FREE-PAGE: %d leaf on trunk page %d\n",pPage->pgno,pTrunk->pgno)); + goto freepage_out; + } + } + + /* If control flows to this point, then it was not possible to add the + ** the page being freed as a leaf page of the first trunk in the free-list. + ** Possibly because the free-list is empty, or possibly because the + ** first trunk in the free-list is full. Either way, the page being freed + ** will become the new first trunk page in the free-list. + */ + if( pPage==0 && SQLITE_OK!=(rc = btreeGetPage(pBt, iPage, &pPage, 0)) ){ + goto freepage_out; + } + rc = sqlite3PagerWrite(pPage->pDbPage); + if( rc!=SQLITE_OK ){ + goto freepage_out; + } + put4byte(pPage->aData, iTrunk); + put4byte(&pPage->aData[4], 0); + put4byte(&pPage1->aData[32], iPage); + TRACE(("FREE-PAGE: %d new trunk page replacing %d\n", pPage->pgno, iTrunk)); + +freepage_out: + if( pPage ){ + pPage->isInit = 0; + } + releasePage(pPage); + releasePage(pTrunk); + return rc; +} +static void freePage(MemPage *pPage, int *pRC){ + if( (*pRC)==SQLITE_OK ){ + *pRC = freePage2(pPage->pBt, pPage, pPage->pgno); + } +} + +/* +** Free any overflow pages associated with the given Cell. +*/ +static int clearCell(MemPage *pPage, unsigned char *pCell){ + BtShared *pBt = pPage->pBt; + CellInfo info; + Pgno ovflPgno; + int rc; + int nOvfl; + u32 ovflPageSize; + + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + btreeParseCellPtr(pPage, pCell, &info); + if( info.iOverflow==0 ){ + return SQLITE_OK; /* No overflow pages. Return without doing anything */ + } + if( pCell+info.iOverflow+3 > pPage->aData+pPage->maskPage ){ + return SQLITE_CORRUPT; /* Cell extends past end of page */ + } + ovflPgno = get4byte(&pCell[info.iOverflow]); + assert( pBt->usableSize > 4 ); + ovflPageSize = pBt->usableSize - 4; + nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize; + assert( ovflPgno==0 || nOvfl>0 ); + while( nOvfl-- ){ + Pgno iNext = 0; + MemPage *pOvfl = 0; + if( ovflPgno<2 || ovflPgno>btreePagecount(pBt) ){ + /* 0 is not a legal page number and page 1 cannot be an + ** overflow page. Therefore if ovflPgno<2 or past the end of the + ** file the database must be corrupt. */ + return SQLITE_CORRUPT_BKPT; + } + if( nOvfl ){ + rc = getOverflowPage(pBt, ovflPgno, &pOvfl, &iNext); + if( rc ) return rc; + } + + if( ( pOvfl || ((pOvfl = btreePageLookup(pBt, ovflPgno))!=0) ) + && sqlite3PagerPageRefcount(pOvfl->pDbPage)!=1 + ){ + /* There is no reason any cursor should have an outstanding reference + ** to an overflow page belonging to a cell that is being deleted/updated. + ** So if there exists more than one reference to this page, then it + ** must not really be an overflow page and the database must be corrupt. + ** It is helpful to detect this before calling freePage2(), as + ** freePage2() may zero the page contents if secure-delete mode is + ** enabled. If this 'overflow' page happens to be a page that the + ** caller is iterating through or using in some other way, this + ** can be problematic. + */ + rc = SQLITE_CORRUPT_BKPT; + }else{ + rc = freePage2(pBt, pOvfl, ovflPgno); + } + + if( pOvfl ){ + sqlite3PagerUnref(pOvfl->pDbPage); + } + if( rc ) return rc; + ovflPgno = iNext; + } + return SQLITE_OK; +} + +/* +** Create the byte sequence used to represent a cell on page pPage +** and write that byte sequence into pCell[]. Overflow pages are +** allocated and filled in as necessary. The calling procedure +** is responsible for making sure sufficient space has been allocated +** for pCell[]. +** +** Note that pCell does not necessary need to point to the pPage->aData +** area. pCell might point to some temporary storage. The cell will +** be constructed in this temporary area then copied into pPage->aData +** later. +*/ +static int fillInCell( + MemPage *pPage, /* The page that contains the cell */ + unsigned char *pCell, /* Complete text of the cell */ + const void *pKey, i64 nKey, /* The key */ + const void *pData,int nData, /* The data */ + int nZero, /* Extra zero bytes to append to pData */ + int *pnSize /* Write cell size here */ +){ + int nPayload; + const u8 *pSrc; + int nSrc, n, rc; + int spaceLeft; + MemPage *pOvfl = 0; + MemPage *pToRelease = 0; + unsigned char *pPrior; + unsigned char *pPayload; + BtShared *pBt = pPage->pBt; + Pgno pgnoOvfl = 0; + int nHeader; + CellInfo info; + + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + + /* pPage is not necessarily writeable since pCell might be auxiliary + ** buffer space that is separate from the pPage buffer area */ + assert( pCellaData || pCell>=&pPage->aData[pBt->pageSize] + || sqlite3PagerIswriteable(pPage->pDbPage) ); + + /* Fill in the header. */ + nHeader = 0; + if( !pPage->leaf ){ + nHeader += 4; + } + if( pPage->hasData ){ + nHeader += putVarint(&pCell[nHeader], nData+nZero); + }else{ + nData = nZero = 0; + } + nHeader += putVarint(&pCell[nHeader], *(u64*)&nKey); + btreeParseCellPtr(pPage, pCell, &info); + assert( info.nHeader==nHeader ); + assert( info.nKey==nKey ); + assert( info.nData==(u32)(nData+nZero) ); + + /* Fill in the payload */ + nPayload = nData + nZero; + if( pPage->intKey ){ + pSrc = pData; + nSrc = nData; + nData = 0; + }else{ + if( NEVER(nKey>0x7fffffff || pKey==0) ){ + return SQLITE_CORRUPT_BKPT; + } + nPayload += (int)nKey; + pSrc = pKey; + nSrc = (int)nKey; + } + *pnSize = info.nSize; + spaceLeft = info.nLocal; + pPayload = &pCell[nHeader]; + pPrior = &pCell[info.iOverflow]; + + while( nPayload>0 ){ + if( spaceLeft==0 ){ +#ifndef SQLITE_OMIT_AUTOVACUUM + Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */ + if( pBt->autoVacuum ){ + do{ + pgnoOvfl++; + } while( + PTRMAP_ISPAGE(pBt, pgnoOvfl) || pgnoOvfl==PENDING_BYTE_PAGE(pBt) + ); + } +#endif + rc = allocateBtreePage(pBt, &pOvfl, &pgnoOvfl, pgnoOvfl, 0); +#ifndef SQLITE_OMIT_AUTOVACUUM + /* If the database supports auto-vacuum, and the second or subsequent + ** overflow page is being allocated, add an entry to the pointer-map + ** for that page now. + ** + ** If this is the first overflow page, then write a partial entry + ** to the pointer-map. If we write nothing to this pointer-map slot, + ** then the optimistic overflow chain processing in clearCell() + ** may misinterpret the uninitialised values and delete the + ** wrong pages from the database. + */ + if( pBt->autoVacuum && rc==SQLITE_OK ){ + u8 eType = (pgnoPtrmap?PTRMAP_OVERFLOW2:PTRMAP_OVERFLOW1); + ptrmapPut(pBt, pgnoOvfl, eType, pgnoPtrmap, &rc); + if( rc ){ + releasePage(pOvfl); + } + } +#endif + if( rc ){ + releasePage(pToRelease); + return rc; + } + + /* If pToRelease is not zero than pPrior points into the data area + ** of pToRelease. Make sure pToRelease is still writeable. */ + assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) ); + + /* If pPrior is part of the data area of pPage, then make sure pPage + ** is still writeable */ + assert( pPrioraData || pPrior>=&pPage->aData[pBt->pageSize] + || sqlite3PagerIswriteable(pPage->pDbPage) ); + + put4byte(pPrior, pgnoOvfl); + releasePage(pToRelease); + pToRelease = pOvfl; + pPrior = pOvfl->aData; + put4byte(pPrior, 0); + pPayload = &pOvfl->aData[4]; + spaceLeft = pBt->usableSize - 4; + } + n = nPayload; + if( n>spaceLeft ) n = spaceLeft; + + /* If pToRelease is not zero than pPayload points into the data area + ** of pToRelease. Make sure pToRelease is still writeable. */ + assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) ); + + /* If pPayload is part of the data area of pPage, then make sure pPage + ** is still writeable */ + assert( pPayloadaData || pPayload>=&pPage->aData[pBt->pageSize] + || sqlite3PagerIswriteable(pPage->pDbPage) ); + + if( nSrc>0 ){ + if( n>nSrc ) n = nSrc; + assert( pSrc ); + memcpy(pPayload, pSrc, n); + }else{ + memset(pPayload, 0, n); + } + nPayload -= n; + pPayload += n; + pSrc += n; + nSrc -= n; + spaceLeft -= n; + if( nSrc==0 ){ + nSrc = nData; + pSrc = pData; + } + } + releasePage(pToRelease); + return SQLITE_OK; +} + +/* +** Remove the i-th cell from pPage. This routine effects pPage only. +** The cell content is not freed or deallocated. It is assumed that +** the cell content has been copied someplace else. This routine just +** removes the reference to the cell from pPage. +** +** "sz" must be the number of bytes in the cell. +*/ +static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ + u32 pc; /* Offset to cell content of cell being deleted */ + u8 *data; /* pPage->aData */ + u8 *ptr; /* Used to move bytes around within data[] */ + u8 *endPtr; /* End of loop */ + int rc; /* The return code */ + int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */ + + if( *pRC ) return; + + assert( idx>=0 && idxnCell ); + assert( sz==cellSize(pPage, idx) ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + data = pPage->aData; + ptr = &pPage->aCellIdx[2*idx]; + pc = get2byte(ptr); + hdr = pPage->hdrOffset; + testcase( pc==get2byte(&data[hdr+5]) ); + testcase( pc+sz==pPage->pBt->usableSize ); + if( pc < (u32)get2byte(&data[hdr+5]) || pc+sz > pPage->pBt->usableSize ){ + *pRC = SQLITE_CORRUPT_BKPT; + return; + } + rc = freeSpace(pPage, pc, sz); + if( rc ){ + *pRC = rc; + return; + } + endPtr = &pPage->aCellIdx[2*pPage->nCell - 2]; + assert( (SQLITE_PTR_TO_INT(ptr)&1)==0 ); /* ptr is always 2-byte aligned */ + while( ptrnCell--; + put2byte(&data[hdr+3], pPage->nCell); + pPage->nFree += 2; +} + +/* +** Insert a new cell on pPage at cell index "i". pCell points to the +** content of the cell. +** +** If the cell content will fit on the page, then put it there. If it +** will not fit, then make a copy of the cell content into pTemp if +** pTemp is not null. Regardless of pTemp, allocate a new entry +** in pPage->aOvfl[] and make it point to the cell content (either +** in pTemp or the original pCell) and also record its index. +** Allocating a new entry in pPage->aCell[] implies that +** pPage->nOverflow is incremented. +** +** If nSkip is non-zero, then do not copy the first nSkip bytes of the +** cell. The caller will overwrite them after this function returns. If +** nSkip is non-zero, then pCell may not point to an invalid memory location +** (but pCell+nSkip is always valid). +*/ +static void insertCell( + MemPage *pPage, /* Page into which we are copying */ + int i, /* New cell becomes the i-th cell of the page */ + u8 *pCell, /* Content of the new cell */ + int sz, /* Bytes of content in pCell */ + u8 *pTemp, /* Temp storage space for pCell, if needed */ + Pgno iChild, /* If non-zero, replace first 4 bytes with this value */ + int *pRC /* Read and write return code from here */ +){ + int idx = 0; /* Where to write new cell content in data[] */ + int j; /* Loop counter */ + int end; /* First byte past the last cell pointer in data[] */ + int ins; /* Index in data[] where new cell pointer is inserted */ + int cellOffset; /* Address of first cell pointer in data[] */ + u8 *data; /* The content of the whole page */ + u8 *ptr; /* Used for moving information around in data[] */ + u8 *endPtr; /* End of the loop */ + + int nSkip = (iChild ? 4 : 0); + + if( *pRC ) return; + + assert( i>=0 && i<=pPage->nCell+pPage->nOverflow ); + assert( pPage->nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=10921 ); + assert( pPage->nOverflow<=ArraySize(pPage->aOvfl) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + /* The cell should normally be sized correctly. However, when moving a + ** malformed cell from a leaf page to an interior page, if the cell size + ** wanted to be less than 4 but got rounded up to 4 on the leaf, then size + ** might be less than 8 (leaf-size + pointer) on the interior node. Hence + ** the term after the || in the following assert(). */ + assert( sz==cellSizePtr(pPage, pCell) || (sz==8 && iChild>0) ); + if( pPage->nOverflow || sz+2>pPage->nFree ){ + if( pTemp ){ + memcpy(pTemp+nSkip, pCell+nSkip, sz-nSkip); + pCell = pTemp; + } + if( iChild ){ + put4byte(pCell, iChild); + } + j = pPage->nOverflow++; + assert( j<(int)(sizeof(pPage->aOvfl)/sizeof(pPage->aOvfl[0])) ); + pPage->aOvfl[j].pCell = pCell; + pPage->aOvfl[j].idx = (u16)i; + }else{ + int rc = sqlite3PagerWrite(pPage->pDbPage); + if( rc!=SQLITE_OK ){ + *pRC = rc; + return; + } + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + data = pPage->aData; + cellOffset = pPage->cellOffset; + end = cellOffset + 2*pPage->nCell; + ins = cellOffset + 2*i; + rc = allocateSpace(pPage, sz, &idx); + if( rc ){ *pRC = rc; return; } + /* The allocateSpace() routine guarantees the following two properties + ** if it returns success */ + assert( idx >= end+2 ); + assert( idx+sz <= (int)pPage->pBt->usableSize ); + pPage->nCell++; + pPage->nFree -= (u16)(2 + sz); + memcpy(&data[idx+nSkip], pCell+nSkip, sz-nSkip); + if( iChild ){ + put4byte(&data[idx], iChild); + } + ptr = &data[end]; + endPtr = &data[ins]; + assert( (SQLITE_PTR_TO_INT(ptr)&1)==0 ); /* ptr is always 2-byte aligned */ + while( ptr>endPtr ){ + *(u16*)ptr = *(u16*)&ptr[-2]; + ptr -= 2; + } + put2byte(&data[ins], idx); + put2byte(&data[pPage->hdrOffset+3], pPage->nCell); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pPage->pBt->autoVacuum ){ + /* The cell may contain a pointer to an overflow page. If so, write + ** the entry for the overflow page into the pointer map. + */ + ptrmapPutOvflPtr(pPage, pCell, pRC); + } +#endif + } +} + +/* +** Add a list of cells to a page. The page should be initially empty. +** The cells are guaranteed to fit on the page. +*/ +static void assemblePage( + MemPage *pPage, /* The page to be assemblied */ + int nCell, /* The number of cells to add to this page */ + u8 **apCell, /* Pointers to cell bodies */ + u16 *aSize /* Sizes of the cells */ +){ + int i; /* Loop counter */ + u8 *pCellptr; /* Address of next cell pointer */ + int cellbody; /* Address of next cell body */ + u8 * const data = pPage->aData; /* Pointer to data for pPage */ + const int hdr = pPage->hdrOffset; /* Offset of header on pPage */ + const int nUsable = pPage->pBt->usableSize; /* Usable size of page */ + + assert( pPage->nOverflow==0 ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( nCell>=0 && nCell<=(int)MX_CELL(pPage->pBt) + && (int)MX_CELL(pPage->pBt)<=10921); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + + /* Check that the page has just been zeroed by zeroPage() */ + assert( pPage->nCell==0 ); + assert( get2byteNotZero(&data[hdr+5])==nUsable ); + + pCellptr = &pPage->aCellIdx[nCell*2]; + cellbody = nUsable; + for(i=nCell-1; i>=0; i--){ + u16 sz = aSize[i]; + pCellptr -= 2; + cellbody -= sz; + put2byte(pCellptr, cellbody); + memcpy(&data[cellbody], apCell[i], sz); + } + put2byte(&data[hdr+3], nCell); + put2byte(&data[hdr+5], cellbody); + pPage->nFree -= (nCell*2 + nUsable - cellbody); + pPage->nCell = (u16)nCell; +} + +/* +** The following parameters determine how many adjacent pages get involved +** in a balancing operation. NN is the number of neighbors on either side +** of the page that participate in the balancing operation. NB is the +** total number of pages that participate, including the target page and +** NN neighbors on either side. +** +** The minimum value of NN is 1 (of course). Increasing NN above 1 +** (to 2 or 3) gives a modest improvement in SELECT and DELETE performance +** in exchange for a larger degradation in INSERT and UPDATE performance. +** The value of NN appears to give the best results overall. +*/ +#define NN 1 /* Number of neighbors on either side of pPage */ +#define NB (NN*2+1) /* Total pages involved in the balance */ + + +#ifndef SQLITE_OMIT_QUICKBALANCE +/* +** This version of balance() handles the common special case where +** a new entry is being inserted on the extreme right-end of the +** tree, in other words, when the new entry will become the largest +** entry in the tree. +** +** Instead of trying to balance the 3 right-most leaf pages, just add +** a new page to the right-hand side and put the one new entry in +** that page. This leaves the right side of the tree somewhat +** unbalanced. But odds are that we will be inserting new entries +** at the end soon afterwards so the nearly empty page will quickly +** fill up. On average. +** +** pPage is the leaf page which is the right-most page in the tree. +** pParent is its parent. pPage must have a single overflow entry +** which is also the right-most entry on the page. +** +** The pSpace buffer is used to store a temporary copy of the divider +** cell that will be inserted into pParent. Such a cell consists of a 4 +** byte page number followed by a variable length integer. In other +** words, at most 13 bytes. Hence the pSpace buffer must be at +** least 13 bytes in size. +*/ +static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ + BtShared *const pBt = pPage->pBt; /* B-Tree Database */ + MemPage *pNew; /* Newly allocated page */ + int rc; /* Return Code */ + Pgno pgnoNew; /* Page number of pNew */ + + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); + assert( pPage->nOverflow==1 ); + + /* This error condition is now caught prior to reaching this function */ + if( pPage->nCell<=0 ) return SQLITE_CORRUPT_BKPT; + + /* Allocate a new page. This page will become the right-sibling of + ** pPage. Make the parent page writable, so that the new divider cell + ** may be inserted. If both these operations are successful, proceed. + */ + rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0); + + if( rc==SQLITE_OK ){ + + u8 *pOut = &pSpace[4]; + u8 *pCell = pPage->aOvfl[0].pCell; + u16 szCell = cellSizePtr(pPage, pCell); + u8 *pStop; + + assert( sqlite3PagerIswriteable(pNew->pDbPage) ); + assert( pPage->aData[0]==(PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF) ); + zeroPage(pNew, PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF); + assemblePage(pNew, 1, &pCell, &szCell); + + /* If this is an auto-vacuum database, update the pointer map + ** with entries for the new page, and any pointer from the + ** cell on the page to an overflow page. If either of these + ** operations fails, the return code is set, but the contents + ** of the parent page are still manipulated by thh code below. + ** That is Ok, at this point the parent page is guaranteed to + ** be marked as dirty. Returning an error code will cause a + ** rollback, undoing any changes made to the parent page. + */ + if( ISAUTOVACUUM ){ + ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno, &rc); + if( szCell>pNew->minLocal ){ + ptrmapPutOvflPtr(pNew, pCell, &rc); + } + } + + /* Create a divider cell to insert into pParent. The divider cell + ** consists of a 4-byte page number (the page number of pPage) and + ** a variable length key value (which must be the same value as the + ** largest key on pPage). + ** + ** To find the largest key value on pPage, first find the right-most + ** cell on pPage. The first two fields of this cell are the + ** record-length (a variable length integer at most 32-bits in size) + ** and the key value (a variable length integer, may have any value). + ** The first of the while(...) loops below skips over the record-length + ** field. The second while(...) loop copies the key value from the + ** cell on pPage into the pSpace buffer. + */ + pCell = findCell(pPage, pPage->nCell-1); + pStop = &pCell[9]; + while( (*(pCell++)&0x80) && pCellnCell, pSpace, (int)(pOut-pSpace), + 0, pPage->pgno, &rc); + + /* Set the right-child pointer of pParent to point to the new page. */ + put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew); + + /* Release the reference to the new page. */ + releasePage(pNew); + } + + return rc; +} +#endif /* SQLITE_OMIT_QUICKBALANCE */ + +#if 0 +/* +** This function does not contribute anything to the operation of SQLite. +** it is sometimes activated temporarily while debugging code responsible +** for setting pointer-map entries. +*/ +static int ptrmapCheckPages(MemPage **apPage, int nPage){ + int i, j; + for(i=0; ipBt; + assert( pPage->isInit ); + + for(j=0; jnCell; j++){ + CellInfo info; + u8 *z; + + z = findCell(pPage, j); + btreeParseCellPtr(pPage, z, &info); + if( info.iOverflow ){ + Pgno ovfl = get4byte(&z[info.iOverflow]); + ptrmapGet(pBt, ovfl, &e, &n); + assert( n==pPage->pgno && e==PTRMAP_OVERFLOW1 ); + } + if( !pPage->leaf ){ + Pgno child = get4byte(z); + ptrmapGet(pBt, child, &e, &n); + assert( n==pPage->pgno && e==PTRMAP_BTREE ); + } + } + if( !pPage->leaf ){ + Pgno child = get4byte(&pPage->aData[pPage->hdrOffset+8]); + ptrmapGet(pBt, child, &e, &n); + assert( n==pPage->pgno && e==PTRMAP_BTREE ); + } + } + return 1; +} +#endif + +/* +** This function is used to copy the contents of the b-tree node stored +** on page pFrom to page pTo. If page pFrom was not a leaf page, then +** the pointer-map entries for each child page are updated so that the +** parent page stored in the pointer map is page pTo. If pFrom contained +** any cells with overflow page pointers, then the corresponding pointer +** map entries are also updated so that the parent page is page pTo. +** +** If pFrom is currently carrying any overflow cells (entries in the +** MemPage.aOvfl[] array), they are not copied to pTo. +** +** Before returning, page pTo is reinitialized using btreeInitPage(). +** +** The performance of this function is not critical. It is only used by +** the balance_shallower() and balance_deeper() procedures, neither of +** which are called often under normal circumstances. +*/ +static void copyNodeContent(MemPage *pFrom, MemPage *pTo, int *pRC){ + if( (*pRC)==SQLITE_OK ){ + BtShared * const pBt = pFrom->pBt; + u8 * const aFrom = pFrom->aData; + u8 * const aTo = pTo->aData; + int const iFromHdr = pFrom->hdrOffset; + int const iToHdr = ((pTo->pgno==1) ? 100 : 0); + int rc; + int iData; + + + assert( pFrom->isInit ); + assert( pFrom->nFree>=iToHdr ); + assert( get2byte(&aFrom[iFromHdr+5]) <= (int)pBt->usableSize ); + + /* Copy the b-tree node content from page pFrom to page pTo. */ + iData = get2byte(&aFrom[iFromHdr+5]); + memcpy(&aTo[iData], &aFrom[iData], pBt->usableSize-iData); + memcpy(&aTo[iToHdr], &aFrom[iFromHdr], pFrom->cellOffset + 2*pFrom->nCell); + + /* Reinitialize page pTo so that the contents of the MemPage structure + ** match the new data. The initialization of pTo can actually fail under + ** fairly obscure circumstances, even though it is a copy of initialized + ** page pFrom. + */ + pTo->isInit = 0; + rc = btreeInitPage(pTo); + if( rc!=SQLITE_OK ){ + *pRC = rc; + return; + } + + /* If this is an auto-vacuum database, update the pointer-map entries + ** for any b-tree or overflow pages that pTo now contains the pointers to. + */ + if( ISAUTOVACUUM ){ + *pRC = setChildPtrmaps(pTo); + } + } +} + +/* +** This routine redistributes cells on the iParentIdx'th child of pParent +** (hereafter "the page") and up to 2 siblings so that all pages have about the +** same amount of free space. Usually a single sibling on either side of the +** page are used in the balancing, though both siblings might come from one +** side if the page is the first or last child of its parent. If the page +** has fewer than 2 siblings (something which can only happen if the page +** is a root page or a child of a root page) then all available siblings +** participate in the balancing. +** +** The number of siblings of the page might be increased or decreased by +** one or two in an effort to keep pages nearly full but not over full. +** +** Note that when this routine is called, some of the cells on the page +** might not actually be stored in MemPage.aData[]. This can happen +** if the page is overfull. This routine ensures that all cells allocated +** to the page and its siblings fit into MemPage.aData[] before returning. +** +** In the course of balancing the page and its siblings, cells may be +** inserted into or removed from the parent page (pParent). Doing so +** may cause the parent page to become overfull or underfull. If this +** happens, it is the responsibility of the caller to invoke the correct +** balancing routine to fix this problem (see the balance() routine). +** +** If this routine fails for any reason, it might leave the database +** in a corrupted state. So if this routine fails, the database should +** be rolled back. +** +** The third argument to this function, aOvflSpace, is a pointer to a +** buffer big enough to hold one page. If while inserting cells into the parent +** page (pParent) the parent page becomes overfull, this buffer is +** used to store the parent's overflow cells. Because this function inserts +** a maximum of four divider cells into the parent page, and the maximum +** size of a cell stored within an internal node is always less than 1/4 +** of the page-size, the aOvflSpace[] buffer is guaranteed to be large +** enough for all overflow cells. +** +** If aOvflSpace is set to a null pointer, this function returns +** SQLITE_NOMEM. +*/ +static int balance_nonroot( + MemPage *pParent, /* Parent page of siblings being balanced */ + int iParentIdx, /* Index of "the page" in pParent */ + u8 *aOvflSpace, /* page-size bytes of space for parent ovfl */ + int isRoot /* True if pParent is a root-page */ +){ + BtShared *pBt; /* The whole database */ + int nCell = 0; /* Number of cells in apCell[] */ + int nMaxCells = 0; /* Allocated size of apCell, szCell, aFrom. */ + int nNew = 0; /* Number of pages in apNew[] */ + int nOld; /* Number of pages in apOld[] */ + int i, j, k; /* Loop counters */ + int nxDiv; /* Next divider slot in pParent->aCell[] */ + int rc = SQLITE_OK; /* The return code */ + u16 leafCorrection; /* 4 if pPage is a leaf. 0 if not */ + int leafData; /* True if pPage is a leaf of a LEAFDATA tree */ + int usableSpace; /* Bytes in pPage beyond the header */ + int pageFlags; /* Value of pPage->aData[0] */ + int subtotal; /* Subtotal of bytes in cells on one page */ + int iSpace1 = 0; /* First unused byte of aSpace1[] */ + int iOvflSpace = 0; /* First unused byte of aOvflSpace[] */ + int szScratch; /* Size of scratch memory requested */ + MemPage *apOld[NB]; /* pPage and up to two siblings */ + MemPage *apCopy[NB]; /* Private copies of apOld[] pages */ + MemPage *apNew[NB+2]; /* pPage and up to NB siblings after balancing */ + u8 *pRight; /* Location in parent of right-sibling pointer */ + u8 *apDiv[NB-1]; /* Divider cells in pParent */ + int cntNew[NB+2]; /* Index in aCell[] of cell after i-th page */ + int szNew[NB+2]; /* Combined size of cells place on i-th page */ + u8 **apCell = 0; /* All cells begin balanced */ + u16 *szCell; /* Local size of all cells in apCell[] */ + u8 *aSpace1; /* Space for copies of dividers cells */ + Pgno pgno; /* Temp var to store a page number in */ + + pBt = pParent->pBt; + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); + +#if 0 + TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno)); +#endif + + /* At this point pParent may have at most one overflow cell. And if + ** this overflow cell is present, it must be the cell with + ** index iParentIdx. This scenario comes about when this function + ** is called (indirectly) from sqlite3BtreeDelete(). + */ + assert( pParent->nOverflow==0 || pParent->nOverflow==1 ); + assert( pParent->nOverflow==0 || pParent->aOvfl[0].idx==iParentIdx ); + + if( !aOvflSpace ){ + return SQLITE_NOMEM; + } + + /* Find the sibling pages to balance. Also locate the cells in pParent + ** that divide the siblings. An attempt is made to find NN siblings on + ** either side of pPage. More siblings are taken from one side, however, + ** if there are fewer than NN siblings on the other side. If pParent + ** has NB or fewer children then all children of pParent are taken. + ** + ** This loop also drops the divider cells from the parent page. This + ** way, the remainder of the function does not have to deal with any + ** overflow cells in the parent page, since if any existed they will + ** have already been removed. + */ + i = pParent->nOverflow + pParent->nCell; + if( i<2 ){ + nxDiv = 0; + nOld = i+1; + }else{ + nOld = 3; + if( iParentIdx==0 ){ + nxDiv = 0; + }else if( iParentIdx==i ){ + nxDiv = i-2; + }else{ + nxDiv = iParentIdx-1; + } + i = 2; + } + if( (i+nxDiv-pParent->nOverflow)==pParent->nCell ){ + pRight = &pParent->aData[pParent->hdrOffset+8]; + }else{ + pRight = findCell(pParent, i+nxDiv-pParent->nOverflow); + } + pgno = get4byte(pRight); + while( 1 ){ + rc = getAndInitPage(pBt, pgno, &apOld[i]); + if( rc ){ + memset(apOld, 0, (i+1)*sizeof(MemPage*)); + goto balance_cleanup; + } + nMaxCells += 1+apOld[i]->nCell+apOld[i]->nOverflow; + if( (i--)==0 ) break; + + if( i+nxDiv==pParent->aOvfl[0].idx && pParent->nOverflow ){ + apDiv[i] = pParent->aOvfl[0].pCell; + pgno = get4byte(apDiv[i]); + szNew[i] = cellSizePtr(pParent, apDiv[i]); + pParent->nOverflow = 0; + }else{ + apDiv[i] = findCell(pParent, i+nxDiv-pParent->nOverflow); + pgno = get4byte(apDiv[i]); + szNew[i] = cellSizePtr(pParent, apDiv[i]); + + /* Drop the cell from the parent page. apDiv[i] still points to + ** the cell within the parent, even though it has been dropped. + ** This is safe because dropping a cell only overwrites the first + ** four bytes of it, and this function does not need the first + ** four bytes of the divider cell. So the pointer is safe to use + ** later on. + ** + ** But not if we are in secure-delete mode. In secure-delete mode, + ** the dropCell() routine will overwrite the entire cell with zeroes. + ** In this case, temporarily copy the cell into the aOvflSpace[] + ** buffer. It will be copied out again as soon as the aSpace[] buffer + ** is allocated. */ + if( pBt->btsFlags & BTS_SECURE_DELETE ){ + int iOff; + + iOff = SQLITE_PTR_TO_INT(apDiv[i]) - SQLITE_PTR_TO_INT(pParent->aData); + if( (iOff+szNew[i])>(int)pBt->usableSize ){ + rc = SQLITE_CORRUPT_BKPT; + memset(apOld, 0, (i+1)*sizeof(MemPage*)); + goto balance_cleanup; + }else{ + memcpy(&aOvflSpace[iOff], apDiv[i], szNew[i]); + apDiv[i] = &aOvflSpace[apDiv[i]-pParent->aData]; + } + } + dropCell(pParent, i+nxDiv-pParent->nOverflow, szNew[i], &rc); + } + } + + /* Make nMaxCells a multiple of 4 in order to preserve 8-byte + ** alignment */ + nMaxCells = (nMaxCells + 3)&~3; + + /* + ** Allocate space for memory structures + */ + k = pBt->pageSize + ROUND8(sizeof(MemPage)); + szScratch = + nMaxCells*sizeof(u8*) /* apCell */ + + nMaxCells*sizeof(u16) /* szCell */ + + pBt->pageSize /* aSpace1 */ + + k*nOld; /* Page copies (apCopy) */ + apCell = sqlite3ScratchMalloc( szScratch ); + if( apCell==0 ){ + rc = SQLITE_NOMEM; + goto balance_cleanup; + } + szCell = (u16*)&apCell[nMaxCells]; + aSpace1 = (u8*)&szCell[nMaxCells]; + assert( EIGHT_BYTE_ALIGNMENT(aSpace1) ); + + /* + ** Load pointers to all cells on sibling pages and the divider cells + ** into the local apCell[] array. Make copies of the divider cells + ** into space obtained from aSpace1[] and remove the the divider Cells + ** from pParent. + ** + ** If the siblings are on leaf pages, then the child pointers of the + ** divider cells are stripped from the cells before they are copied + ** into aSpace1[]. In this way, all cells in apCell[] are without + ** child pointers. If siblings are not leaves, then all cell in + ** apCell[] include child pointers. Either way, all cells in apCell[] + ** are alike. + ** + ** leafCorrection: 4 if pPage is a leaf. 0 if pPage is not a leaf. + ** leafData: 1 if pPage holds key+data and pParent holds only keys. + */ + leafCorrection = apOld[0]->leaf*4; + leafData = apOld[0]->hasData; + for(i=0; ipageSize + k*i]; + memcpy(pOld, apOld[i], sizeof(MemPage)); + pOld->aData = (void*)&pOld[1]; + memcpy(pOld->aData, apOld[i]->aData, pBt->pageSize); + + limit = pOld->nCell+pOld->nOverflow; + if( pOld->nOverflow>0 ){ + for(j=0; jaData; + u16 maskPage = pOld->maskPage; + u16 cellOffset = pOld->cellOffset; + for(j=0; jmaxLocal+23 ); + assert( iSpace1 <= (int)pBt->pageSize ); + memcpy(pTemp, apDiv[i], sz); + apCell[nCell] = pTemp+leafCorrection; + assert( leafCorrection==0 || leafCorrection==4 ); + szCell[nCell] = szCell[nCell] - leafCorrection; + if( !pOld->leaf ){ + assert( leafCorrection==0 ); + assert( pOld->hdrOffset==0 ); + /* The right pointer of the child page pOld becomes the left + ** pointer of the divider cell */ + memcpy(apCell[nCell], &pOld->aData[8], 4); + }else{ + assert( leafCorrection==4 ); + if( szCell[nCell]<4 ){ + /* Do not allow any cells smaller than 4 bytes. */ + szCell[nCell] = 4; + } + } + nCell++; + } + } + + /* + ** Figure out the number of pages needed to hold all nCell cells. + ** Store this number in "k". Also compute szNew[] which is the total + ** size of all cells on the i-th page and cntNew[] which is the index + ** in apCell[] of the cell that divides page i from page i+1. + ** cntNew[k] should equal nCell. + ** + ** Values computed by this block: + ** + ** k: The total number of sibling pages + ** szNew[i]: Spaced used on the i-th sibling page. + ** cntNew[i]: Index in apCell[] and szCell[] for the first cell to + ** the right of the i-th sibling page. + ** usableSpace: Number of bytes of space available on each sibling. + ** + */ + usableSpace = pBt->usableSize - 12 + leafCorrection; + for(subtotal=k=i=0; i usableSpace ){ + szNew[k] = subtotal - szCell[i]; + cntNew[k] = i; + if( leafData ){ i--; } + subtotal = 0; + k++; + if( k>NB+1 ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; } + } + } + szNew[k] = subtotal; + cntNew[k] = nCell; + k++; + + /* + ** The packing computed by the previous block is biased toward the siblings + ** on the left side. The left siblings are always nearly full, while the + ** right-most sibling might be nearly empty. This block of code attempts + ** to adjust the packing of siblings to get a better balance. + ** + ** This adjustment is more than an optimization. The packing above might + ** be so out of balance as to be illegal. For example, the right-most + ** sibling might be completely empty. This adjustment is not optional. + */ + for(i=k-1; i>0; i--){ + int szRight = szNew[i]; /* Size of sibling on the right */ + int szLeft = szNew[i-1]; /* Size of sibling on the left */ + int r; /* Index of right-most cell in left sibling */ + int d; /* Index of first cell to the left of right sibling */ + + r = cntNew[i-1] - 1; + d = r + 1 - leafData; + assert( d0) or pPage is + ** a virtual root page. A virtual root page is when the real root + ** page is page 1 and we are the only child of that page. + ** + ** UPDATE: The assert() below is not necessarily true if the database + ** file is corrupt. The corruption will be detected and reported later + ** in this procedure so there is no need to act upon it now. + */ +#if 0 + assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) ); +#endif + + TRACE(("BALANCE: old: %d %d %d ", + apOld[0]->pgno, + nOld>=2 ? apOld[1]->pgno : 0, + nOld>=3 ? apOld[2]->pgno : 0 + )); + + /* + ** Allocate k new pages. Reuse old pages where possible. + */ + if( apOld[0]->pgno<=1 ){ + rc = SQLITE_CORRUPT_BKPT; + goto balance_cleanup; + } + pageFlags = apOld[0]->aData[0]; + for(i=0; ipDbPage); + nNew++; + if( rc ) goto balance_cleanup; + }else{ + assert( i>0 ); + rc = allocateBtreePage(pBt, &pNew, &pgno, pgno, 0); + if( rc ) goto balance_cleanup; + apNew[i] = pNew; + nNew++; + + /* Set the pointer-map entry for the new sibling page. */ + if( ISAUTOVACUUM ){ + ptrmapPut(pBt, pNew->pgno, PTRMAP_BTREE, pParent->pgno, &rc); + if( rc!=SQLITE_OK ){ + goto balance_cleanup; + } + } + } + } + + /* Free any old pages that were not reused as new pages. + */ + while( ipgno; + int minI = i; + for(j=i+1; jpgno<(unsigned)minV ){ + minI = j; + minV = apNew[j]->pgno; + } + } + if( minI>i ){ + MemPage *pT; + pT = apNew[i]; + apNew[i] = apNew[minI]; + apNew[minI] = pT; + } + } + TRACE(("new: %d(%d) %d(%d) %d(%d) %d(%d) %d(%d)\n", + apNew[0]->pgno, szNew[0], + nNew>=2 ? apNew[1]->pgno : 0, nNew>=2 ? szNew[1] : 0, + nNew>=3 ? apNew[2]->pgno : 0, nNew>=3 ? szNew[2] : 0, + nNew>=4 ? apNew[3]->pgno : 0, nNew>=4 ? szNew[3] : 0, + nNew>=5 ? apNew[4]->pgno : 0, nNew>=5 ? szNew[4] : 0)); + + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); + put4byte(pRight, apNew[nNew-1]->pgno); + + /* + ** Evenly distribute the data in apCell[] across the new pages. + ** Insert divider cells into pParent as necessary. + */ + j = 0; + for(i=0; inCell>0 || (nNew==1 && cntNew[0]==0) ); + assert( pNew->nOverflow==0 ); + + j = cntNew[i]; + + /* If the sibling page assembled above was not the right-most sibling, + ** insert a divider cell into the parent page. + */ + assert( ileaf ){ + memcpy(&pNew->aData[8], pCell, 4); + }else if( leafData ){ + /* If the tree is a leaf-data tree, and the siblings are leaves, + ** then there is no divider cell in apCell[]. Instead, the divider + ** cell consists of the integer key for the right-most cell of + ** the sibling-page assembled above only. + */ + CellInfo info; + j--; + btreeParseCellPtr(pNew, apCell[j], &info); + pCell = pTemp; + sz = 4 + putVarint(&pCell[4], info.nKey); + pTemp = 0; + }else{ + pCell -= 4; + /* Obscure case for non-leaf-data trees: If the cell at pCell was + ** previously stored on a leaf node, and its reported size was 4 + ** bytes, then it may actually be smaller than this + ** (see btreeParseCellPtr(), 4 bytes is the minimum size of + ** any cell). But it is important to pass the correct size to + ** insertCell(), so reparse the cell now. + ** + ** Note that this can never happen in an SQLite data file, as all + ** cells are at least 4 bytes. It only happens in b-trees used + ** to evaluate "IN (SELECT ...)" and similar clauses. + */ + if( szCell[j]==4 ){ + assert(leafCorrection==4); + sz = cellSizePtr(pParent, pCell); + } + } + iOvflSpace += sz; + assert( sz<=pBt->maxLocal+23 ); + assert( iOvflSpace <= (int)pBt->pageSize ); + insertCell(pParent, nxDiv, pCell, sz, pTemp, pNew->pgno, &rc); + if( rc!=SQLITE_OK ) goto balance_cleanup; + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); + + j++; + nxDiv++; + } + } + assert( j==nCell ); + assert( nOld>0 ); + assert( nNew>0 ); + if( (pageFlags & PTF_LEAF)==0 ){ + u8 *zChild = &apCopy[nOld-1]->aData[8]; + memcpy(&apNew[nNew-1]->aData[8], zChild, 4); + } + + if( isRoot && pParent->nCell==0 && pParent->hdrOffset<=apNew[0]->nFree ){ + /* The root page of the b-tree now contains no cells. The only sibling + ** page is the right-child of the parent. Copy the contents of the + ** child page into the parent, decreasing the overall height of the + ** b-tree structure by one. This is described as the "balance-shallower" + ** sub-algorithm in some documentation. + ** + ** If this is an auto-vacuum database, the call to copyNodeContent() + ** sets all pointer-map entries corresponding to database image pages + ** for which the pointer is stored within the content being copied. + ** + ** The second assert below verifies that the child page is defragmented + ** (it must be, as it was just reconstructed using assemblePage()). This + ** is important if the parent page happens to be page 1 of the database + ** image. */ + assert( nNew==1 ); + assert( apNew[0]->nFree == + (get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2) + ); + copyNodeContent(apNew[0], pParent, &rc); + freePage(apNew[0], &rc); + }else if( ISAUTOVACUUM ){ + /* Fix the pointer-map entries for all the cells that were shifted around. + ** There are several different types of pointer-map entries that need to + ** be dealt with by this routine. Some of these have been set already, but + ** many have not. The following is a summary: + ** + ** 1) The entries associated with new sibling pages that were not + ** siblings when this function was called. These have already + ** been set. We don't need to worry about old siblings that were + ** moved to the free-list - the freePage() code has taken care + ** of those. + ** + ** 2) The pointer-map entries associated with the first overflow + ** page in any overflow chains used by new divider cells. These + ** have also already been taken care of by the insertCell() code. + ** + ** 3) If the sibling pages are not leaves, then the child pages of + ** cells stored on the sibling pages may need to be updated. + ** + ** 4) If the sibling pages are not internal intkey nodes, then any + ** overflow pages used by these cells may need to be updated + ** (internal intkey nodes never contain pointers to overflow pages). + ** + ** 5) If the sibling pages are not leaves, then the pointer-map + ** entries for the right-child pages of each sibling may need + ** to be updated. + ** + ** Cases 1 and 2 are dealt with above by other code. The next + ** block deals with cases 3 and 4 and the one after that, case 5. Since + ** setting a pointer map entry is a relatively expensive operation, this + ** code only sets pointer map entries for child or overflow pages that have + ** actually moved between pages. */ + MemPage *pNew = apNew[0]; + MemPage *pOld = apCopy[0]; + int nOverflow = pOld->nOverflow; + int iNextOld = pOld->nCell + nOverflow; + int iOverflow = (nOverflow ? pOld->aOvfl[0].idx : -1); + j = 0; /* Current 'old' sibling page */ + k = 0; /* Current 'new' sibling page */ + for(i=0; inCell + pOld->nOverflow; + if( pOld->nOverflow ){ + nOverflow = pOld->nOverflow; + iOverflow = i + !leafData + pOld->aOvfl[0].idx; + } + isDivider = !leafData; + } + + assert(nOverflow>0 || iOverflowaOvfl[0].idx==pOld->aOvfl[1].idx-1); + assert(nOverflow<3 || pOld->aOvfl[1].idx==pOld->aOvfl[2].idx-1); + if( i==iOverflow ){ + isDivider = 1; + if( (--nOverflow)>0 ){ + iOverflow++; + } + } + + if( i==cntNew[k] ){ + /* Cell i is the cell immediately following the last cell on new + ** sibling page k. If the siblings are not leaf pages of an + ** intkey b-tree, then cell i is a divider cell. */ + pNew = apNew[++k]; + if( !leafData ) continue; + } + assert( jpgno!=pNew->pgno ){ + if( !leafCorrection ){ + ptrmapPut(pBt, get4byte(apCell[i]), PTRMAP_BTREE, pNew->pgno, &rc); + } + if( szCell[i]>pNew->minLocal ){ + ptrmapPutOvflPtr(pNew, apCell[i], &rc); + } + } + } + + if( !leafCorrection ){ + for(i=0; iaData[8]); + ptrmapPut(pBt, key, PTRMAP_BTREE, apNew[i]->pgno, &rc); + } + } + +#if 0 + /* The ptrmapCheckPages() contains assert() statements that verify that + ** all pointer map pages are set correctly. This is helpful while + ** debugging. This is usually disabled because a corrupt database may + ** cause an assert() statement to fail. */ + ptrmapCheckPages(apNew, nNew); + ptrmapCheckPages(&pParent, 1); +#endif + } + + assert( pParent->isInit ); + TRACE(("BALANCE: finished: old=%d new=%d cells=%d\n", + nOld, nNew, nCell)); + + /* + ** Cleanup before returning. + */ +balance_cleanup: + sqlite3ScratchFree(apCell); + for(i=0; ipBt; /* The BTree */ + + assert( pRoot->nOverflow>0 ); + assert( sqlite3_mutex_held(pBt->mutex) ); + + /* Make pRoot, the root page of the b-tree, writable. Allocate a new + ** page that will become the new right-child of pPage. Copy the contents + ** of the node stored on pRoot into the new child page. + */ + rc = sqlite3PagerWrite(pRoot->pDbPage); + if( rc==SQLITE_OK ){ + rc = allocateBtreePage(pBt,&pChild,&pgnoChild,pRoot->pgno,0); + copyNodeContent(pRoot, pChild, &rc); + if( ISAUTOVACUUM ){ + ptrmapPut(pBt, pgnoChild, PTRMAP_BTREE, pRoot->pgno, &rc); + } + } + if( rc ){ + *ppChild = 0; + releasePage(pChild); + return rc; + } + assert( sqlite3PagerIswriteable(pChild->pDbPage) ); + assert( sqlite3PagerIswriteable(pRoot->pDbPage) ); + assert( pChild->nCell==pRoot->nCell ); + + TRACE(("BALANCE: copy root %d into %d\n", pRoot->pgno, pChild->pgno)); + + /* Copy the overflow cells from pRoot to pChild */ + memcpy(pChild->aOvfl, pRoot->aOvfl, pRoot->nOverflow*sizeof(pRoot->aOvfl[0])); + pChild->nOverflow = pRoot->nOverflow; + + /* Zero the contents of pRoot. Then install pChild as the right-child. */ + zeroPage(pRoot, pChild->aData[0] & ~PTF_LEAF); + put4byte(&pRoot->aData[pRoot->hdrOffset+8], pgnoChild); + + *ppChild = pChild; + return SQLITE_OK; +} + +/* +** The page that pCur currently points to has just been modified in +** some way. This function figures out if this modification means the +** tree needs to be balanced, and if so calls the appropriate balancing +** routine. Balancing routines are: +** +** balance_quick() +** balance_deeper() +** balance_nonroot() +*/ +static int balance(BtCursor *pCur){ + int rc = SQLITE_OK; + const int nMin = pCur->pBt->usableSize * 2 / 3; + u8 aBalanceQuickSpace[13]; + u8 *pFree = 0; + + TESTONLY( int balance_quick_called = 0 ); + TESTONLY( int balance_deeper_called = 0 ); + + do { + int iPage = pCur->iPage; + MemPage *pPage = pCur->apPage[iPage]; + + if( iPage==0 ){ + if( pPage->nOverflow ){ + /* The root page of the b-tree is overfull. In this case call the + ** balance_deeper() function to create a new child for the root-page + ** and copy the current contents of the root-page to it. The + ** next iteration of the do-loop will balance the child page. + */ + assert( (balance_deeper_called++)==0 ); + rc = balance_deeper(pPage, &pCur->apPage[1]); + if( rc==SQLITE_OK ){ + pCur->iPage = 1; + pCur->aiIdx[0] = 0; + pCur->aiIdx[1] = 0; + assert( pCur->apPage[1]->nOverflow ); + } + }else{ + break; + } + }else if( pPage->nOverflow==0 && pPage->nFree<=nMin ){ + break; + }else{ + MemPage * const pParent = pCur->apPage[iPage-1]; + int const iIdx = pCur->aiIdx[iPage-1]; + + rc = sqlite3PagerWrite(pParent->pDbPage); + if( rc==SQLITE_OK ){ +#ifndef SQLITE_OMIT_QUICKBALANCE + if( pPage->hasData + && pPage->nOverflow==1 + && pPage->aOvfl[0].idx==pPage->nCell + && pParent->pgno!=1 + && pParent->nCell==iIdx + ){ + /* Call balance_quick() to create a new sibling of pPage on which + ** to store the overflow cell. balance_quick() inserts a new cell + ** into pParent, which may cause pParent overflow. If this + ** happens, the next interation of the do-loop will balance pParent + ** use either balance_nonroot() or balance_deeper(). Until this + ** happens, the overflow cell is stored in the aBalanceQuickSpace[] + ** buffer. + ** + ** The purpose of the following assert() is to check that only a + ** single call to balance_quick() is made for each call to this + ** function. If this were not verified, a subtle bug involving reuse + ** of the aBalanceQuickSpace[] might sneak in. + */ + assert( (balance_quick_called++)==0 ); + rc = balance_quick(pParent, pPage, aBalanceQuickSpace); + }else +#endif + { + /* In this case, call balance_nonroot() to redistribute cells + ** between pPage and up to 2 of its sibling pages. This involves + ** modifying the contents of pParent, which may cause pParent to + ** become overfull or underfull. The next iteration of the do-loop + ** will balance the parent page to correct this. + ** + ** If the parent page becomes overfull, the overflow cell or cells + ** are stored in the pSpace buffer allocated immediately below. + ** A subsequent iteration of the do-loop will deal with this by + ** calling balance_nonroot() (balance_deeper() may be called first, + ** but it doesn't deal with overflow cells - just moves them to a + ** different page). Once this subsequent call to balance_nonroot() + ** has completed, it is safe to release the pSpace buffer used by + ** the previous call, as the overflow cell data will have been + ** copied either into the body of a database page or into the new + ** pSpace buffer passed to the latter call to balance_nonroot(). + */ + u8 *pSpace = sqlite3PageMalloc(pCur->pBt->pageSize); + rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1); + if( pFree ){ + /* If pFree is not NULL, it points to the pSpace buffer used + ** by a previous call to balance_nonroot(). Its contents are + ** now stored either on real database pages or within the + ** new pSpace buffer, so it may be safely freed here. */ + sqlite3PageFree(pFree); + } + + /* The pSpace buffer will be freed after the next call to + ** balance_nonroot(), or just before this function returns, whichever + ** comes first. */ + pFree = pSpace; + } + } + + pPage->nOverflow = 0; + + /* The next iteration of the do-loop balances the parent page. */ + releasePage(pPage); + pCur->iPage--; + } + }while( rc==SQLITE_OK ); + + if( pFree ){ + sqlite3PageFree(pFree); + } + return rc; +} + + +/* +** Insert a new record into the BTree. The key is given by (pKey,nKey) +** and the data is given by (pData,nData). The cursor is used only to +** define what table the record should be inserted into. The cursor +** is left pointing at a random location. +** +** For an INTKEY table, only the nKey value of the key is used. pKey is +** ignored. For a ZERODATA table, the pData and nData are both ignored. +** +** If the seekResult parameter is non-zero, then a successful call to +** MovetoUnpacked() to seek cursor pCur to (pKey, nKey) has already +** been performed. seekResult is the search result returned (a negative +** number if pCur points at an entry that is smaller than (pKey, nKey), or +** a positive value if pCur points at an etry that is larger than +** (pKey, nKey)). +** +** If the seekResult parameter is non-zero, then the caller guarantees that +** cursor pCur is pointing at the existing copy of a row that is to be +** overwritten. If the seekResult parameter is 0, then cursor pCur may +** point to any entry or to no entry at all and so this function has to seek +** the cursor before the new key can be inserted. +*/ +int sqlite3BtreeInsert( + BtCursor *pCur, /* Insert data into the table of this cursor */ + const void *pKey, i64 nKey, /* The key of the new record */ + const void *pData, int nData, /* The data of the new record */ + int nZero, /* Number of extra 0 bytes to append to data */ + int appendBias, /* True if this is likely an append */ + int seekResult /* Result of prior MovetoUnpacked() call */ +){ + int rc; + int loc = seekResult; /* -1: before desired location +1: after */ + int szNew = 0; + int idx; + MemPage *pPage; + Btree *p = pCur->pBtree; + BtShared *pBt = p->pBt; + unsigned char *oldCell; + unsigned char *newCell = 0; + + if( pCur->eState==CURSOR_FAULT ){ + assert( pCur->skipNext!=SQLITE_OK ); + return pCur->skipNext; + } + + assert( cursorHoldsMutex(pCur) ); + assert( pCur->wrFlag && pBt->inTransaction==TRANS_WRITE + && (pBt->btsFlags & BTS_READ_ONLY)==0 ); + assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); + + /* Assert that the caller has been consistent. If this cursor was opened + ** expecting an index b-tree, then the caller should be inserting blob + ** keys with no associated data. If the cursor was opened expecting an + ** intkey table, the caller should be inserting integer keys with a + ** blob of associated data. */ + assert( (pKey==0)==(pCur->pKeyInfo==0) ); + + /* If this is an insert into a table b-tree, invalidate any incrblob + ** cursors open on the row being replaced (assuming this is a replace + ** operation - if it is not, the following is a no-op). */ + if( pCur->pKeyInfo==0 ){ + invalidateIncrblobCursors(p, nKey, 0); + } + + /* Save the positions of any other cursors open on this table. + ** + ** In some cases, the call to btreeMoveto() below is a no-op. For + ** example, when inserting data into a table with auto-generated integer + ** keys, the VDBE layer invokes sqlite3BtreeLast() to figure out the + ** integer key to use. It then calls this function to actually insert the + ** data into the intkey B-Tree. In this case btreeMoveto() recognizes + ** that the cursor is already where it needs to be and returns without + ** doing any work. To avoid thwarting these optimizations, it is important + ** not to clear the cursor here. + */ + rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur); + if( rc ) return rc; + if( !loc ){ + rc = btreeMoveto(pCur, pKey, nKey, appendBias, &loc); + if( rc ) return rc; + } + assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) ); + + pPage = pCur->apPage[pCur->iPage]; + assert( pPage->intKey || nKey>=0 ); + assert( pPage->leaf || !pPage->intKey ); + + TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n", + pCur->pgnoRoot, nKey, nData, pPage->pgno, + loc==0 ? "overwrite" : "new entry")); + assert( pPage->isInit ); + allocateTempSpace(pBt); + newCell = pBt->pTmpSpace; + if( newCell==0 ) return SQLITE_NOMEM; + rc = fillInCell(pPage, newCell, pKey, nKey, pData, nData, nZero, &szNew); + if( rc ) goto end_insert; + assert( szNew==cellSizePtr(pPage, newCell) ); + assert( szNew <= MX_CELL_SIZE(pBt) ); + idx = pCur->aiIdx[pCur->iPage]; + if( loc==0 ){ + u16 szOld; + assert( idxnCell ); + rc = sqlite3PagerWrite(pPage->pDbPage); + if( rc ){ + goto end_insert; + } + oldCell = findCell(pPage, idx); + if( !pPage->leaf ){ + memcpy(newCell, oldCell, 4); + } + szOld = cellSizePtr(pPage, oldCell); + rc = clearCell(pPage, oldCell); + dropCell(pPage, idx, szOld, &rc); + if( rc ) goto end_insert; + }else if( loc<0 && pPage->nCell>0 ){ + assert( pPage->leaf ); + idx = ++pCur->aiIdx[pCur->iPage]; + }else{ + assert( pPage->leaf ); + } + insertCell(pPage, idx, newCell, szNew, 0, 0, &rc); + assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 ); + + /* If no error has occured and pPage has an overflow cell, call balance() + ** to redistribute the cells within the tree. Since balance() may move + ** the cursor, zero the BtCursor.info.nSize and BtCursor.validNKey + ** variables. + ** + ** Previous versions of SQLite called moveToRoot() to move the cursor + ** back to the root page as balance() used to invalidate the contents + ** of BtCursor.apPage[] and BtCursor.aiIdx[]. Instead of doing that, + ** set the cursor state to "invalid". This makes common insert operations + ** slightly faster. + ** + ** There is a subtle but important optimization here too. When inserting + ** multiple records into an intkey b-tree using a single cursor (as can + ** happen while processing an "INSERT INTO ... SELECT" statement), it + ** is advantageous to leave the cursor pointing to the last entry in + ** the b-tree if possible. If the cursor is left pointing to the last + ** entry in the table, and the next row inserted has an integer key + ** larger than the largest existing key, it is possible to insert the + ** row without seeking the cursor. This can be a big performance boost. + */ + pCur->info.nSize = 0; + pCur->validNKey = 0; + if( rc==SQLITE_OK && pPage->nOverflow ){ + rc = balance(pCur); + + /* Must make sure nOverflow is reset to zero even if the balance() + ** fails. Internal data structure corruption will result otherwise. + ** Also, set the cursor state to invalid. This stops saveCursorPosition() + ** from trying to save the current position of the cursor. */ + pCur->apPage[pCur->iPage]->nOverflow = 0; + pCur->eState = CURSOR_INVALID; + } + assert( pCur->apPage[pCur->iPage]->nOverflow==0 ); + +end_insert: + return rc; +} + +/* +** Delete the entry that the cursor is pointing to. The cursor +** is left pointing at a arbitrary location. +*/ +int sqlite3BtreeDelete(BtCursor *pCur){ + Btree *p = pCur->pBtree; + BtShared *pBt = p->pBt; + int rc; /* Return code */ + MemPage *pPage; /* Page to delete cell from */ + unsigned char *pCell; /* Pointer to cell to delete */ + int iCellIdx; /* Index of cell to delete */ + int iCellDepth; /* Depth of node containing pCell */ + + assert( cursorHoldsMutex(pCur) ); + assert( pBt->inTransaction==TRANS_WRITE ); + assert( (pBt->btsFlags & BTS_READ_ONLY)==0 ); + assert( pCur->wrFlag ); + assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); + assert( !hasReadConflicts(p, pCur->pgnoRoot) ); + + if( NEVER(pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell) + || NEVER(pCur->eState!=CURSOR_VALID) + ){ + return SQLITE_ERROR; /* Something has gone awry. */ + } + + /* If this is a delete operation to remove a row from a table b-tree, + ** invalidate any incrblob cursors open on the row being deleted. */ + if( pCur->pKeyInfo==0 ){ + invalidateIncrblobCursors(p, pCur->info.nKey, 0); + } + + iCellDepth = pCur->iPage; + iCellIdx = pCur->aiIdx[iCellDepth]; + pPage = pCur->apPage[iCellDepth]; + pCell = findCell(pPage, iCellIdx); + + /* If the page containing the entry to delete is not a leaf page, move + ** the cursor to the largest entry in the tree that is smaller than + ** the entry being deleted. This cell will replace the cell being deleted + ** from the internal node. The 'previous' entry is used for this instead + ** of the 'next' entry, as the previous entry is always a part of the + ** sub-tree headed by the child page of the cell being deleted. This makes + ** balancing the tree following the delete operation easier. */ + if( !pPage->leaf ){ + int notUsed; + rc = sqlite3BtreePrevious(pCur, ¬Used); + if( rc ) return rc; + } + + /* Save the positions of any other cursors open on this table before + ** making any modifications. Make the page containing the entry to be + ** deleted writable. Then free any overflow pages associated with the + ** entry and finally remove the cell itself from within the page. + */ + rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur); + if( rc ) return rc; + rc = sqlite3PagerWrite(pPage->pDbPage); + if( rc ) return rc; + rc = clearCell(pPage, pCell); + dropCell(pPage, iCellIdx, cellSizePtr(pPage, pCell), &rc); + if( rc ) return rc; + + /* If the cell deleted was not located on a leaf page, then the cursor + ** is currently pointing to the largest entry in the sub-tree headed + ** by the child-page of the cell that was just deleted from an internal + ** node. The cell from the leaf node needs to be moved to the internal + ** node to replace the deleted cell. */ + if( !pPage->leaf ){ + MemPage *pLeaf = pCur->apPage[pCur->iPage]; + int nCell; + Pgno n = pCur->apPage[iCellDepth+1]->pgno; + unsigned char *pTmp; + + pCell = findCell(pLeaf, pLeaf->nCell-1); + nCell = cellSizePtr(pLeaf, pCell); + assert( MX_CELL_SIZE(pBt) >= nCell ); + + allocateTempSpace(pBt); + pTmp = pBt->pTmpSpace; + + rc = sqlite3PagerWrite(pLeaf->pDbPage); + insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc); + dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc); + if( rc ) return rc; + } + + /* Balance the tree. If the entry deleted was located on a leaf page, + ** then the cursor still points to that page. In this case the first + ** call to balance() repairs the tree, and the if(...) condition is + ** never true. + ** + ** Otherwise, if the entry deleted was on an internal node page, then + ** pCur is pointing to the leaf page from which a cell was removed to + ** replace the cell deleted from the internal node. This is slightly + ** tricky as the leaf node may be underfull, and the internal node may + ** be either under or overfull. In this case run the balancing algorithm + ** on the leaf node first. If the balance proceeds far enough up the + ** tree that we can be sure that any problem in the internal node has + ** been corrected, so be it. Otherwise, after balancing the leaf node, + ** walk the cursor up the tree to the internal node and balance it as + ** well. */ + rc = balance(pCur); + if( rc==SQLITE_OK && pCur->iPage>iCellDepth ){ + while( pCur->iPage>iCellDepth ){ + releasePage(pCur->apPage[pCur->iPage--]); + } + rc = balance(pCur); + } + + if( rc==SQLITE_OK ){ + moveToRoot(pCur); + } + return rc; +} + +/* +** Create a new BTree table. Write into *piTable the page +** number for the root page of the new table. +** +** The type of type is determined by the flags parameter. Only the +** following values of flags are currently in use. Other values for +** flags might not work: +** +** BTREE_INTKEY|BTREE_LEAFDATA Used for SQL tables with rowid keys +** BTREE_ZERODATA Used for SQL indices +*/ +static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){ + BtShared *pBt = p->pBt; + MemPage *pRoot; + Pgno pgnoRoot; + int rc; + int ptfFlags; /* Page-type flage for the root page of new table */ + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( pBt->inTransaction==TRANS_WRITE ); + assert( (pBt->btsFlags & BTS_READ_ONLY)==0 ); + +#ifdef SQLITE_OMIT_AUTOVACUUM + rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0); + if( rc ){ + return rc; + } +#else + if( pBt->autoVacuum ){ + Pgno pgnoMove; /* Move a page here to make room for the root-page */ + MemPage *pPageMove; /* The page to move to. */ + + /* Creating a new table may probably require moving an existing database + ** to make room for the new tables root page. In case this page turns + ** out to be an overflow page, delete all overflow page-map caches + ** held by open cursors. + */ + invalidateAllOverflowCache(pBt); + + /* Read the value of meta[3] from the database to determine where the + ** root page of the new table should go. meta[3] is the largest root-page + ** created so far, so the new root-page is (meta[3]+1). + */ + sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &pgnoRoot); + pgnoRoot++; + + /* The new root-page may not be allocated on a pointer-map page, or the + ** PENDING_BYTE page. + */ + while( pgnoRoot==PTRMAP_PAGENO(pBt, pgnoRoot) || + pgnoRoot==PENDING_BYTE_PAGE(pBt) ){ + pgnoRoot++; + } + assert( pgnoRoot>=3 ); + + /* Allocate a page. The page that currently resides at pgnoRoot will + ** be moved to the allocated page (unless the allocated page happens + ** to reside at pgnoRoot). + */ + rc = allocateBtreePage(pBt, &pPageMove, &pgnoMove, pgnoRoot, 1); + if( rc!=SQLITE_OK ){ + return rc; + } + + if( pgnoMove!=pgnoRoot ){ + /* pgnoRoot is the page that will be used for the root-page of + ** the new table (assuming an error did not occur). But we were + ** allocated pgnoMove. If required (i.e. if it was not allocated + ** by extending the file), the current page at position pgnoMove + ** is already journaled. + */ + u8 eType = 0; + Pgno iPtrPage = 0; + + releasePage(pPageMove); + + /* Move the page currently at pgnoRoot to pgnoMove. */ + rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage); + if( eType==PTRMAP_ROOTPAGE || eType==PTRMAP_FREEPAGE ){ + rc = SQLITE_CORRUPT_BKPT; + } + if( rc!=SQLITE_OK ){ + releasePage(pRoot); + return rc; + } + assert( eType!=PTRMAP_ROOTPAGE ); + assert( eType!=PTRMAP_FREEPAGE ); + rc = relocatePage(pBt, pRoot, eType, iPtrPage, pgnoMove, 0); + releasePage(pRoot); + + /* Obtain the page at pgnoRoot */ + if( rc!=SQLITE_OK ){ + return rc; + } + rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = sqlite3PagerWrite(pRoot->pDbPage); + if( rc!=SQLITE_OK ){ + releasePage(pRoot); + return rc; + } + }else{ + pRoot = pPageMove; + } + + /* Update the pointer-map and meta-data with the new root-page number. */ + ptrmapPut(pBt, pgnoRoot, PTRMAP_ROOTPAGE, 0, &rc); + if( rc ){ + releasePage(pRoot); + return rc; + } + + /* When the new root page was allocated, page 1 was made writable in + ** order either to increase the database filesize, or to decrement the + ** freelist count. Hence, the sqlite3BtreeUpdateMeta() call cannot fail. + */ + assert( sqlite3PagerIswriteable(pBt->pPage1->pDbPage) ); + rc = sqlite3BtreeUpdateMeta(p, 4, pgnoRoot); + if( NEVER(rc) ){ + releasePage(pRoot); + return rc; + } + + }else{ + rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0); + if( rc ) return rc; + } +#endif + assert( sqlite3PagerIswriteable(pRoot->pDbPage) ); + if( createTabFlags & BTREE_INTKEY ){ + ptfFlags = PTF_INTKEY | PTF_LEAFDATA | PTF_LEAF; + }else{ + ptfFlags = PTF_ZERODATA | PTF_LEAF; + } + zeroPage(pRoot, ptfFlags); + sqlite3PagerUnref(pRoot->pDbPage); + assert( (pBt->openFlags & BTREE_SINGLE)==0 || pgnoRoot==2 ); + *piTable = (int)pgnoRoot; + return SQLITE_OK; +} +int sqlite3BtreeCreateTable(Btree *p, int *piTable, int flags){ + int rc; + sqlite3BtreeEnter(p); + rc = btreeCreateTable(p, piTable, flags); + sqlite3BtreeLeave(p); + return rc; +} + +/* +** Erase the given database page and all its children. Return +** the page to the freelist. +*/ +static int clearDatabasePage( + BtShared *pBt, /* The BTree that contains the table */ + Pgno pgno, /* Page number to clear */ + int freePageFlag, /* Deallocate page if true */ + int *pnChange /* Add number of Cells freed to this counter */ +){ + MemPage *pPage; + int rc; + unsigned char *pCell; + int i; + + assert( sqlite3_mutex_held(pBt->mutex) ); + if( pgno>btreePagecount(pBt) ){ + return SQLITE_CORRUPT_BKPT; + } + + rc = getAndInitPage(pBt, pgno, &pPage); + if( rc ) return rc; + for(i=0; inCell; i++){ + pCell = findCell(pPage, i); + if( !pPage->leaf ){ + rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange); + if( rc ) goto cleardatabasepage_out; + } + rc = clearCell(pPage, pCell); + if( rc ) goto cleardatabasepage_out; + } + if( !pPage->leaf ){ + rc = clearDatabasePage(pBt, get4byte(&pPage->aData[8]), 1, pnChange); + if( rc ) goto cleardatabasepage_out; + }else if( pnChange ){ + assert( pPage->intKey ); + *pnChange += pPage->nCell; + } + if( freePageFlag ){ + freePage(pPage, &rc); + }else if( (rc = sqlite3PagerWrite(pPage->pDbPage))==0 ){ + zeroPage(pPage, pPage->aData[0] | PTF_LEAF); + } + +cleardatabasepage_out: + releasePage(pPage); + return rc; +} + +/* +** Delete all information from a single table in the database. iTable is +** the page number of the root of the table. After this routine returns, +** the root page is empty, but still exists. +** +** This routine will fail with SQLITE_LOCKED if there are any open +** read cursors on the table. Open write cursors are moved to the +** root of the table. +** +** If pnChange is not NULL, then table iTable must be an intkey table. The +** integer value pointed to by pnChange is incremented by the number of +** entries in the table. +*/ +int sqlite3BtreeClearTable(Btree *p, int iTable, int *pnChange){ + int rc; + BtShared *pBt = p->pBt; + sqlite3BtreeEnter(p); + assert( p->inTrans==TRANS_WRITE ); + + /* Invalidate all incrblob cursors open on table iTable (assuming iTable + ** is the root of a table b-tree - if it is not, the following call is + ** a no-op). */ + invalidateIncrblobCursors(p, 0, 1); + + rc = saveAllCursors(pBt, (Pgno)iTable, 0); + if( SQLITE_OK==rc ){ + rc = clearDatabasePage(pBt, (Pgno)iTable, 0, pnChange); + } + sqlite3BtreeLeave(p); + return rc; +} + +/* +** Erase all information in a table and add the root of the table to +** the freelist. Except, the root of the principle table (the one on +** page 1) is never added to the freelist. +** +** This routine will fail with SQLITE_LOCKED if there are any open +** cursors on the table. +** +** If AUTOVACUUM is enabled and the page at iTable is not the last +** root page in the database file, then the last root page +** in the database file is moved into the slot formerly occupied by +** iTable and that last slot formerly occupied by the last root page +** is added to the freelist instead of iTable. In this say, all +** root pages are kept at the beginning of the database file, which +** is necessary for AUTOVACUUM to work right. *piMoved is set to the +** page number that used to be the last root page in the file before +** the move. If no page gets moved, *piMoved is set to 0. +** The last root page is recorded in meta[3] and the value of +** meta[3] is updated by this procedure. +*/ +static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){ + int rc; + MemPage *pPage = 0; + BtShared *pBt = p->pBt; + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( p->inTrans==TRANS_WRITE ); + + /* It is illegal to drop a table if any cursors are open on the + ** database. This is because in auto-vacuum mode the backend may + ** need to move another root-page to fill a gap left by the deleted + ** root page. If an open cursor was using this page a problem would + ** occur. + ** + ** This error is caught long before control reaches this point. + */ + if( NEVER(pBt->pCursor) ){ + sqlite3ConnectionBlocked(p->db, pBt->pCursor->pBtree->db); + return SQLITE_LOCKED_SHAREDCACHE; + } + + rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0); + if( rc ) return rc; + rc = sqlite3BtreeClearTable(p, iTable, 0); + if( rc ){ + releasePage(pPage); + return rc; + } + + *piMoved = 0; + + if( iTable>1 ){ +#ifdef SQLITE_OMIT_AUTOVACUUM + freePage(pPage, &rc); + releasePage(pPage); +#else + if( pBt->autoVacuum ){ + Pgno maxRootPgno; + sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &maxRootPgno); + + if( iTable==maxRootPgno ){ + /* If the table being dropped is the table with the largest root-page + ** number in the database, put the root page on the free list. + */ + freePage(pPage, &rc); + releasePage(pPage); + if( rc!=SQLITE_OK ){ + return rc; + } + }else{ + /* The table being dropped does not have the largest root-page + ** number in the database. So move the page that does into the + ** gap left by the deleted root-page. + */ + MemPage *pMove; + releasePage(pPage); + rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable, 0); + releasePage(pMove); + if( rc!=SQLITE_OK ){ + return rc; + } + pMove = 0; + rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0); + freePage(pMove, &rc); + releasePage(pMove); + if( rc!=SQLITE_OK ){ + return rc; + } + *piMoved = maxRootPgno; + } + + /* Set the new 'max-root-page' value in the database header. This + ** is the old value less one, less one more if that happens to + ** be a root-page number, less one again if that is the + ** PENDING_BYTE_PAGE. + */ + maxRootPgno--; + while( maxRootPgno==PENDING_BYTE_PAGE(pBt) + || PTRMAP_ISPAGE(pBt, maxRootPgno) ){ + maxRootPgno--; + } + assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) ); + + rc = sqlite3BtreeUpdateMeta(p, 4, maxRootPgno); + }else{ + freePage(pPage, &rc); + releasePage(pPage); + } +#endif + }else{ + /* If sqlite3BtreeDropTable was called on page 1. + ** This really never should happen except in a corrupt + ** database. + */ + zeroPage(pPage, PTF_INTKEY|PTF_LEAF ); + releasePage(pPage); + } + return rc; +} +int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){ + int rc; + sqlite3BtreeEnter(p); + rc = btreeDropTable(p, iTable, piMoved); + sqlite3BtreeLeave(p); + return rc; +} + + +/* +** This function may only be called if the b-tree connection already +** has a read or write transaction open on the database. +** +** Read the meta-information out of a database file. Meta[0] +** is the number of free pages currently in the database. Meta[1] +** through meta[15] are available for use by higher layers. Meta[0] +** is read-only, the others are read/write. +** +** The schema layer numbers meta values differently. At the schema +** layer (and the SetCookie and ReadCookie opcodes) the number of +** free pages is not visible. So Cookie[0] is the same as Meta[1]. +*/ +void sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){ + BtShared *pBt = p->pBt; + + sqlite3BtreeEnter(p); + assert( p->inTrans>TRANS_NONE ); + assert( SQLITE_OK==querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK) ); + assert( pBt->pPage1 ); + assert( idx>=0 && idx<=15 ); + + *pMeta = get4byte(&pBt->pPage1->aData[36 + idx*4]); + + /* If auto-vacuum is disabled in this build and this is an auto-vacuum + ** database, mark the database as read-only. */ +#ifdef SQLITE_OMIT_AUTOVACUUM + if( idx==BTREE_LARGEST_ROOT_PAGE && *pMeta>0 ){ + pBt->btsFlags |= BTS_READ_ONLY; + } +#endif + + sqlite3BtreeLeave(p); +} + +/* +** Write meta-information back into the database. Meta[0] is +** read-only and may not be written. +*/ +int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){ + BtShared *pBt = p->pBt; + unsigned char *pP1; + int rc; + assert( idx>=1 && idx<=15 ); + sqlite3BtreeEnter(p); + assert( p->inTrans==TRANS_WRITE ); + assert( pBt->pPage1!=0 ); + pP1 = pBt->pPage1->aData; + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + if( rc==SQLITE_OK ){ + put4byte(&pP1[36 + idx*4], iMeta); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( idx==BTREE_INCR_VACUUM ){ + assert( pBt->autoVacuum || iMeta==0 ); + assert( iMeta==0 || iMeta==1 ); + pBt->incrVacuum = (u8)iMeta; + } +#endif + } + sqlite3BtreeLeave(p); + return rc; +} + +#ifndef SQLITE_OMIT_BTREECOUNT +/* +** The first argument, pCur, is a cursor opened on some b-tree. Count the +** number of entries in the b-tree and write the result to *pnEntry. +** +** SQLITE_OK is returned if the operation is successfully executed. +** Otherwise, if an error is encountered (i.e. an IO error or database +** corruption) an SQLite error code is returned. +*/ +int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){ + i64 nEntry = 0; /* Value to return in *pnEntry */ + int rc; /* Return code */ + + if( pCur->pgnoRoot==0 ){ + *pnEntry = 0; + return SQLITE_OK; + } + rc = moveToRoot(pCur); + + /* Unless an error occurs, the following loop runs one iteration for each + ** page in the B-Tree structure (not including overflow pages). + */ + while( rc==SQLITE_OK ){ + int iIdx; /* Index of child node in parent */ + MemPage *pPage; /* Current page of the b-tree */ + + /* If this is a leaf page or the tree is not an int-key tree, then + ** this page contains countable entries. Increment the entry counter + ** accordingly. + */ + pPage = pCur->apPage[pCur->iPage]; + if( pPage->leaf || !pPage->intKey ){ + nEntry += pPage->nCell; + } + + /* pPage is a leaf node. This loop navigates the cursor so that it + ** points to the first interior cell that it points to the parent of + ** the next page in the tree that has not yet been visited. The + ** pCur->aiIdx[pCur->iPage] value is set to the index of the parent cell + ** of the page, or to the number of cells in the page if the next page + ** to visit is the right-child of its parent. + ** + ** If all pages in the tree have been visited, return SQLITE_OK to the + ** caller. + */ + if( pPage->leaf ){ + do { + if( pCur->iPage==0 ){ + /* All pages of the b-tree have been visited. Return successfully. */ + *pnEntry = nEntry; + return SQLITE_OK; + } + moveToParent(pCur); + }while ( pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell ); + + pCur->aiIdx[pCur->iPage]++; + pPage = pCur->apPage[pCur->iPage]; + } + + /* Descend to the child node of the cell that the cursor currently + ** points at. This is the right-child if (iIdx==pPage->nCell). + */ + iIdx = pCur->aiIdx[pCur->iPage]; + if( iIdx==pPage->nCell ){ + rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8])); + }else{ + rc = moveToChild(pCur, get4byte(findCell(pPage, iIdx))); + } + } + + /* An error has occurred. Return an error code. */ + return rc; +} +#endif + +/* +** Return the pager associated with a BTree. This routine is used for +** testing and debugging only. +*/ +Pager *sqlite3BtreePager(Btree *p){ + return p->pBt->pPager; +} + +#ifndef SQLITE_OMIT_INTEGRITY_CHECK +/* +** Append a message to the error message string. +*/ +static void checkAppendMsg( + IntegrityCk *pCheck, + char *zMsg1, + const char *zFormat, + ... +){ + va_list ap; + if( !pCheck->mxErr ) return; + pCheck->mxErr--; + pCheck->nErr++; + va_start(ap, zFormat); + if( pCheck->errMsg.nChar ){ + sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1); + } + if( zMsg1 ){ + sqlite3StrAccumAppend(&pCheck->errMsg, zMsg1, -1); + } + sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap); + va_end(ap); + if( pCheck->errMsg.mallocFailed ){ + pCheck->mallocFailed = 1; + } +} +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ + +#ifndef SQLITE_OMIT_INTEGRITY_CHECK +/* +** Add 1 to the reference count for page iPage. If this is the second +** reference to the page, add an error message to pCheck->zErrMsg. +** Return 1 if there are 2 ore more references to the page and 0 if +** if this is the first reference to the page. +** +** Also check that the page number is in bounds. +*/ +static int checkRef(IntegrityCk *pCheck, Pgno iPage, char *zContext){ + if( iPage==0 ) return 1; + if( iPage>pCheck->nPage ){ + checkAppendMsg(pCheck, zContext, "invalid page number %d", iPage); + return 1; + } + if( pCheck->anRef[iPage]==1 ){ + checkAppendMsg(pCheck, zContext, "2nd reference to page %d", iPage); + return 1; + } + return (pCheck->anRef[iPage]++)>1; +} + +#ifndef SQLITE_OMIT_AUTOVACUUM +/* +** Check that the entry in the pointer-map for page iChild maps to +** page iParent, pointer type ptrType. If not, append an error message +** to pCheck. +*/ +static void checkPtrmap( + IntegrityCk *pCheck, /* Integrity check context */ + Pgno iChild, /* Child page number */ + u8 eType, /* Expected pointer map type */ + Pgno iParent, /* Expected pointer map parent page number */ + char *zContext /* Context description (used for error msg) */ +){ + int rc; + u8 ePtrmapType; + Pgno iPtrmapParent; + + rc = ptrmapGet(pCheck->pBt, iChild, &ePtrmapType, &iPtrmapParent); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ) pCheck->mallocFailed = 1; + checkAppendMsg(pCheck, zContext, "Failed to read ptrmap key=%d", iChild); + return; + } + + if( ePtrmapType!=eType || iPtrmapParent!=iParent ){ + checkAppendMsg(pCheck, zContext, + "Bad ptr map entry key=%d expected=(%d,%d) got=(%d,%d)", + iChild, eType, iParent, ePtrmapType, iPtrmapParent); + } +} +#endif + +/* +** Check the integrity of the freelist or of an overflow page list. +** Verify that the number of pages on the list is N. +*/ +static void checkList( + IntegrityCk *pCheck, /* Integrity checking context */ + int isFreeList, /* True for a freelist. False for overflow page list */ + int iPage, /* Page number for first page in the list */ + int N, /* Expected number of pages in the list */ + char *zContext /* Context for error messages */ +){ + int i; + int expected = N; + int iFirst = iPage; + while( N-- > 0 && pCheck->mxErr ){ + DbPage *pOvflPage; + unsigned char *pOvflData; + if( iPage<1 ){ + checkAppendMsg(pCheck, zContext, + "%d of %d pages missing from overflow list starting at %d", + N+1, expected, iFirst); + break; + } + if( checkRef(pCheck, iPage, zContext) ) break; + if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage) ){ + checkAppendMsg(pCheck, zContext, "failed to get page %d", iPage); + break; + } + pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage); + if( isFreeList ){ + int n = get4byte(&pOvflData[4]); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pCheck->pBt->autoVacuum ){ + checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0, zContext); + } +#endif + if( n>(int)pCheck->pBt->usableSize/4-2 ){ + checkAppendMsg(pCheck, zContext, + "freelist leaf count too big on page %d", iPage); + N--; + }else{ + for(i=0; ipBt->autoVacuum ){ + checkPtrmap(pCheck, iFreePage, PTRMAP_FREEPAGE, 0, zContext); + } +#endif + checkRef(pCheck, iFreePage, zContext); + } + N -= n; + } + } +#ifndef SQLITE_OMIT_AUTOVACUUM + else{ + /* If this database supports auto-vacuum and iPage is not the last + ** page in this overflow list, check that the pointer-map entry for + ** the following page matches iPage. + */ + if( pCheck->pBt->autoVacuum && N>0 ){ + i = get4byte(pOvflData); + checkPtrmap(pCheck, i, PTRMAP_OVERFLOW2, iPage, zContext); + } + } +#endif + iPage = get4byte(pOvflData); + sqlite3PagerUnref(pOvflPage); + } +} +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ + +#ifndef SQLITE_OMIT_INTEGRITY_CHECK +/* +** Do various sanity checks on a single page of a tree. Return +** the tree depth. Root pages return 0. Parents of root pages +** return 1, and so forth. +** +** These checks are done: +** +** 1. Make sure that cells and freeblocks do not overlap +** but combine to completely cover the page. +** NO 2. Make sure cell keys are in order. +** NO 3. Make sure no key is less than or equal to zLowerBound. +** NO 4. Make sure no key is greater than or equal to zUpperBound. +** 5. Check the integrity of overflow pages. +** 6. Recursively call checkTreePage on all children. +** 7. Verify that the depth of all children is the same. +** 8. Make sure this page is at least 33% full or else it is +** the root of the tree. +*/ +static int checkTreePage( + IntegrityCk *pCheck, /* Context for the sanity check */ + int iPage, /* Page number of the page to check */ + char *zParentContext, /* Parent context */ + i64 *pnParentMinKey, + i64 *pnParentMaxKey +){ + MemPage *pPage; + int i, rc, depth, d2, pgno, cnt; + int hdr, cellStart; + int nCell; + u8 *data; + BtShared *pBt; + int usableSize; + char zContext[100]; + char *hit = 0; + i64 nMinKey = 0; + i64 nMaxKey = 0; + + sqlite3_snprintf(sizeof(zContext), zContext, "Page %d: ", iPage); + + /* Check that the page exists + */ + pBt = pCheck->pBt; + usableSize = pBt->usableSize; + if( iPage==0 ) return 0; + if( checkRef(pCheck, iPage, zParentContext) ) return 0; + if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){ + checkAppendMsg(pCheck, zContext, + "unable to get the page. error code=%d", rc); + return 0; + } + + /* Clear MemPage.isInit to make sure the corruption detection code in + ** btreeInitPage() is executed. */ + pPage->isInit = 0; + if( (rc = btreeInitPage(pPage))!=0 ){ + assert( rc==SQLITE_CORRUPT ); /* The only possible error from InitPage */ + checkAppendMsg(pCheck, zContext, + "btreeInitPage() returns error code %d", rc); + releasePage(pPage); + return 0; + } + + /* Check out all the cells. + */ + depth = 0; + for(i=0; inCell && pCheck->mxErr; i++){ + u8 *pCell; + u32 sz; + CellInfo info; + + /* Check payload overflow pages + */ + sqlite3_snprintf(sizeof(zContext), zContext, + "On tree page %d cell %d: ", iPage, i); + pCell = findCell(pPage,i); + btreeParseCellPtr(pPage, pCell, &info); + sz = info.nData; + if( !pPage->intKey ) sz += (int)info.nKey; + /* For intKey pages, check that the keys are in order. + */ + else if( i==0 ) nMinKey = nMaxKey = info.nKey; + else{ + if( info.nKey <= nMaxKey ){ + checkAppendMsg(pCheck, zContext, + "Rowid %lld out of order (previous was %lld)", info.nKey, nMaxKey); + } + nMaxKey = info.nKey; + } + assert( sz==info.nPayload ); + if( (sz>info.nLocal) + && (&pCell[info.iOverflow]<=&pPage->aData[pBt->usableSize]) + ){ + int nPage = (sz - info.nLocal + usableSize - 5)/(usableSize - 4); + Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + checkPtrmap(pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, iPage, zContext); + } +#endif + checkList(pCheck, 0, pgnoOvfl, nPage, zContext); + } + + /* Check sanity of left child page. + */ + if( !pPage->leaf ){ + pgno = get4byte(pCell); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, zContext); + } +#endif + d2 = checkTreePage(pCheck, pgno, zContext, &nMinKey, i==0 ? NULL : &nMaxKey); + if( i>0 && d2!=depth ){ + checkAppendMsg(pCheck, zContext, "Child page depth differs"); + } + depth = d2; + } + } + + if( !pPage->leaf ){ + pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); + sqlite3_snprintf(sizeof(zContext), zContext, + "On page %d at right child: ", iPage); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, zContext); + } +#endif + checkTreePage(pCheck, pgno, zContext, NULL, !pPage->nCell ? NULL : &nMaxKey); + } + + /* For intKey leaf pages, check that the min/max keys are in order + ** with any left/parent/right pages. + */ + if( pPage->leaf && pPage->intKey ){ + /* if we are a left child page */ + if( pnParentMinKey ){ + /* if we are the left most child page */ + if( !pnParentMaxKey ){ + if( nMaxKey > *pnParentMinKey ){ + checkAppendMsg(pCheck, zContext, + "Rowid %lld out of order (max larger than parent min of %lld)", + nMaxKey, *pnParentMinKey); + } + }else{ + if( nMinKey <= *pnParentMinKey ){ + checkAppendMsg(pCheck, zContext, + "Rowid %lld out of order (min less than parent min of %lld)", + nMinKey, *pnParentMinKey); + } + if( nMaxKey > *pnParentMaxKey ){ + checkAppendMsg(pCheck, zContext, + "Rowid %lld out of order (max larger than parent max of %lld)", + nMaxKey, *pnParentMaxKey); + } + *pnParentMinKey = nMaxKey; + } + /* else if we're a right child page */ + } else if( pnParentMaxKey ){ + if( nMinKey <= *pnParentMaxKey ){ + checkAppendMsg(pCheck, zContext, + "Rowid %lld out of order (min less than parent max of %lld)", + nMinKey, *pnParentMaxKey); + } + } + } + + /* Check for complete coverage of the page + */ + data = pPage->aData; + hdr = pPage->hdrOffset; + hit = sqlite3PageMalloc( pBt->pageSize ); + if( hit==0 ){ + pCheck->mallocFailed = 1; + }else{ + int contentOffset = get2byteNotZero(&data[hdr+5]); + assert( contentOffset<=usableSize ); /* Enforced by btreeInitPage() */ + memset(hit+contentOffset, 0, usableSize-contentOffset); + memset(hit, 1, contentOffset); + nCell = get2byte(&data[hdr+3]); + cellStart = hdr + 12 - 4*pPage->leaf; + for(i=0; i=usableSize ){ + checkAppendMsg(pCheck, 0, + "Corruption detected in cell %d on page %d",i,iPage); + }else{ + for(j=pc+size-1; j>=pc; j--) hit[j]++; + } + } + i = get2byte(&data[hdr+1]); + while( i>0 ){ + int size, j; + assert( i<=usableSize-4 ); /* Enforced by btreeInitPage() */ + size = get2byte(&data[i+2]); + assert( i+size<=usableSize ); /* Enforced by btreeInitPage() */ + for(j=i+size-1; j>=i; j--) hit[j]++; + j = get2byte(&data[i]); + assert( j==0 || j>i+size ); /* Enforced by btreeInitPage() */ + assert( j<=usableSize-4 ); /* Enforced by btreeInitPage() */ + i = j; + } + for(i=cnt=0; i1 ){ + checkAppendMsg(pCheck, 0, + "Multiple uses for byte %d of page %d", i, iPage); + break; + } + } + if( cnt!=data[hdr+7] ){ + checkAppendMsg(pCheck, 0, + "Fragmentation of %d bytes reported as %d on page %d", + cnt, data[hdr+7], iPage); + } + } + sqlite3PageFree(hit); + releasePage(pPage); + return depth+1; +} +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ + +#ifndef SQLITE_OMIT_INTEGRITY_CHECK +/* +** This routine does a complete check of the given BTree file. aRoot[] is +** an array of pages numbers were each page number is the root page of +** a table. nRoot is the number of entries in aRoot. +** +** A read-only or read-write transaction must be opened before calling +** this function. +** +** Write the number of error seen in *pnErr. Except for some memory +** allocation errors, an error message held in memory obtained from +** malloc is returned if *pnErr is non-zero. If *pnErr==0 then NULL is +** returned. If a memory allocation error occurs, NULL is returned. +*/ +char *sqlite3BtreeIntegrityCheck( + Btree *p, /* The btree to be checked */ + int *aRoot, /* An array of root pages numbers for individual trees */ + int nRoot, /* Number of entries in aRoot[] */ + int mxErr, /* Stop reporting errors after this many */ + int *pnErr /* Write number of errors seen to this variable */ +){ + Pgno i; + int nRef; + IntegrityCk sCheck; + BtShared *pBt = p->pBt; + char zErr[100]; + + sqlite3BtreeEnter(p); + assert( p->inTrans>TRANS_NONE && pBt->inTransaction>TRANS_NONE ); + nRef = sqlite3PagerRefcount(pBt->pPager); + sCheck.pBt = pBt; + sCheck.pPager = pBt->pPager; + sCheck.nPage = btreePagecount(sCheck.pBt); + sCheck.mxErr = mxErr; + sCheck.nErr = 0; + sCheck.mallocFailed = 0; + *pnErr = 0; + if( sCheck.nPage==0 ){ + sqlite3BtreeLeave(p); + return 0; + } + sCheck.anRef = sqlite3Malloc( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) ); + if( !sCheck.anRef ){ + *pnErr = 1; + sqlite3BtreeLeave(p); + return 0; + } + for(i=0; i<=sCheck.nPage; i++){ sCheck.anRef[i] = 0; } + i = PENDING_BYTE_PAGE(pBt); + if( i<=sCheck.nPage ){ + sCheck.anRef[i] = 1; + } + sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), 20000); + sCheck.errMsg.useMalloc = 2; + + /* Check the integrity of the freelist + */ + checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]), + get4byte(&pBt->pPage1->aData[36]), "Main freelist: "); + + /* Check all the tables. + */ + for(i=0; (int)iautoVacuum && aRoot[i]>1 ){ + checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0, 0); + } +#endif + checkTreePage(&sCheck, aRoot[i], "List of tree roots: ", NULL, NULL); + } + + /* Make sure every page in the file is referenced + */ + for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){ +#ifdef SQLITE_OMIT_AUTOVACUUM + if( sCheck.anRef[i]==0 ){ + checkAppendMsg(&sCheck, 0, "Page %d is never used", i); + } +#else + /* If the database supports auto-vacuum, make sure no tables contain + ** references to pointer-map pages. + */ + if( sCheck.anRef[i]==0 && + (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){ + checkAppendMsg(&sCheck, 0, "Page %d is never used", i); + } + if( sCheck.anRef[i]!=0 && + (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){ + checkAppendMsg(&sCheck, 0, "Pointer map page %d is referenced", i); + } +#endif + } + + /* Make sure this analysis did not leave any unref() pages. + ** This is an internal consistency check; an integrity check + ** of the integrity check. + */ + if( NEVER(nRef != sqlite3PagerRefcount(pBt->pPager)) ){ + checkAppendMsg(&sCheck, 0, + "Outstanding page count goes from %d to %d during this analysis", + nRef, sqlite3PagerRefcount(pBt->pPager) + ); + } + + /* Clean up and report errors. + */ + sqlite3BtreeLeave(p); + sqlite3_free(sCheck.anRef); + if( sCheck.mallocFailed ){ + sqlite3StrAccumReset(&sCheck.errMsg); + *pnErr = sCheck.nErr+1; + return 0; + } + *pnErr = sCheck.nErr; + if( sCheck.nErr==0 ) sqlite3StrAccumReset(&sCheck.errMsg); + return sqlite3StrAccumFinish(&sCheck.errMsg); +} +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ + +/* +** Return the full pathname of the underlying database file. +** +** The pager filename is invariant as long as the pager is +** open so it is safe to access without the BtShared mutex. +*/ +const char *sqlite3BtreeGetFilename(Btree *p){ + assert( p->pBt->pPager!=0 ); + return sqlite3PagerFilename(p->pBt->pPager); +} + +/* +** Return the pathname of the journal file for this database. The return +** value of this routine is the same regardless of whether the journal file +** has been created or not. +** +** The pager journal filename is invariant as long as the pager is +** open so it is safe to access without the BtShared mutex. +*/ +const char *sqlite3BtreeGetJournalname(Btree *p){ + assert( p->pBt->pPager!=0 ); + return sqlite3PagerJournalname(p->pBt->pPager); +} + +/* +** Return non-zero if a transaction is active. +*/ +int sqlite3BtreeIsInTrans(Btree *p){ + assert( p==0 || sqlite3_mutex_held(p->db->mutex) ); + return (p && (p->inTrans==TRANS_WRITE)); +} + +#ifndef SQLITE_OMIT_WAL +/* +** Run a checkpoint on the Btree passed as the first argument. +** +** Return SQLITE_LOCKED if this or any other connection has an open +** transaction on the shared-cache the argument Btree is connected to. +** +** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART. +*/ +int sqlite3BtreeCheckpoint(Btree *p, int eMode, int *pnLog, int *pnCkpt){ + int rc = SQLITE_OK; + if( p ){ + BtShared *pBt = p->pBt; + sqlite3BtreeEnter(p); + if( pBt->inTransaction!=TRANS_NONE ){ + rc = SQLITE_LOCKED; + }else{ + rc = sqlite3PagerCheckpoint(pBt->pPager, eMode, pnLog, pnCkpt); + } + sqlite3BtreeLeave(p); + } + return rc; +} +#endif + +/* +** Return non-zero if a read (or write) transaction is active. +*/ +int sqlite3BtreeIsInReadTrans(Btree *p){ + assert( p ); + assert( sqlite3_mutex_held(p->db->mutex) ); + return p->inTrans!=TRANS_NONE; +} + +int sqlite3BtreeIsInBackup(Btree *p){ + assert( p ); + assert( sqlite3_mutex_held(p->db->mutex) ); + return p->nBackup!=0; +} + +/* +** This function returns a pointer to a blob of memory associated with +** a single shared-btree. The memory is used by client code for its own +** purposes (for example, to store a high-level schema associated with +** the shared-btree). The btree layer manages reference counting issues. +** +** The first time this is called on a shared-btree, nBytes bytes of memory +** are allocated, zeroed, and returned to the caller. For each subsequent +** call the nBytes parameter is ignored and a pointer to the same blob +** of memory returned. +** +** If the nBytes parameter is 0 and the blob of memory has not yet been +** allocated, a null pointer is returned. If the blob has already been +** allocated, it is returned as normal. +** +** Just before the shared-btree is closed, the function passed as the +** xFree argument when the memory allocation was made is invoked on the +** blob of allocated memory. The xFree function should not call sqlite3_free() +** on the memory, the btree layer does that. +*/ +void *sqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(void *)){ + BtShared *pBt = p->pBt; + sqlite3BtreeEnter(p); + if( !pBt->pSchema && nBytes ){ + pBt->pSchema = sqlite3DbMallocZero(0, nBytes); + pBt->xFreeSchema = xFree; + } + sqlite3BtreeLeave(p); + return pBt->pSchema; +} + +/* +** Return SQLITE_LOCKED_SHAREDCACHE if another user of the same shared +** btree as the argument handle holds an exclusive lock on the +** sqlite_master table. Otherwise SQLITE_OK. +*/ +int sqlite3BtreeSchemaLocked(Btree *p){ + int rc; + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + rc = querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK); + assert( rc==SQLITE_OK || rc==SQLITE_LOCKED_SHAREDCACHE ); + sqlite3BtreeLeave(p); + return rc; +} + + +#ifndef SQLITE_OMIT_SHARED_CACHE +/* +** Obtain a lock on the table whose root page is iTab. The +** lock is a write lock if isWritelock is true or a read lock +** if it is false. +*/ +int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){ + int rc = SQLITE_OK; + assert( p->inTrans!=TRANS_NONE ); + if( p->sharable ){ + u8 lockType = READ_LOCK + isWriteLock; + assert( READ_LOCK+1==WRITE_LOCK ); + assert( isWriteLock==0 || isWriteLock==1 ); + + sqlite3BtreeEnter(p); + rc = querySharedCacheTableLock(p, iTab, lockType); + if( rc==SQLITE_OK ){ + rc = setSharedCacheTableLock(p, iTab, lockType); + } + sqlite3BtreeLeave(p); + } + return rc; +} +#endif + +#ifndef SQLITE_OMIT_INCRBLOB +/* +** Argument pCsr must be a cursor opened for writing on an +** INTKEY table currently pointing at a valid table entry. +** This function modifies the data stored as part of that entry. +** +** Only the data content may only be modified, it is not possible to +** change the length of the data stored. If this function is called with +** parameters that attempt to write past the end of the existing data, +** no modifications are made and SQLITE_CORRUPT is returned. +*/ +int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){ + int rc; + assert( cursorHoldsMutex(pCsr) ); + assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) ); + assert( pCsr->isIncrblobHandle ); + + rc = restoreCursorPosition(pCsr); + if( rc!=SQLITE_OK ){ + return rc; + } + assert( pCsr->eState!=CURSOR_REQUIRESEEK ); + if( pCsr->eState!=CURSOR_VALID ){ + return SQLITE_ABORT; + } + + /* Check some assumptions: + ** (a) the cursor is open for writing, + ** (b) there is a read/write transaction open, + ** (c) the connection holds a write-lock on the table (if required), + ** (d) there are no conflicting read-locks, and + ** (e) the cursor points at a valid row of an intKey table. + */ + if( !pCsr->wrFlag ){ + return SQLITE_READONLY; + } + assert( (pCsr->pBt->btsFlags & BTS_READ_ONLY)==0 + && pCsr->pBt->inTransaction==TRANS_WRITE ); + assert( hasSharedCacheTableLock(pCsr->pBtree, pCsr->pgnoRoot, 0, 2) ); + assert( !hasReadConflicts(pCsr->pBtree, pCsr->pgnoRoot) ); + assert( pCsr->apPage[pCsr->iPage]->intKey ); + + return accessPayload(pCsr, offset, amt, (unsigned char *)z, 1); +} + +/* +** Set a flag on this cursor to cache the locations of pages from the +** overflow list for the current row. This is used by cursors opened +** for incremental blob IO only. +** +** This function sets a flag only. The actual page location cache +** (stored in BtCursor.aOverflow[]) is allocated and used by function +** accessPayload() (the worker function for sqlite3BtreeData() and +** sqlite3BtreePutData()). +*/ +void sqlite3BtreeCacheOverflow(BtCursor *pCur){ + assert( cursorHoldsMutex(pCur) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + invalidateOverflowCache(pCur); + pCur->isIncrblobHandle = 1; +} +#endif + +/* +** Set both the "read version" (single byte at byte offset 18) and +** "write version" (single byte at byte offset 19) fields in the database +** header to iVersion. +*/ +int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){ + BtShared *pBt = pBtree->pBt; + int rc; /* Return code */ + + assert( iVersion==1 || iVersion==2 ); + + /* If setting the version fields to 1, do not automatically open the + ** WAL connection, even if the version fields are currently set to 2. + */ + pBt->btsFlags &= ~BTS_NO_WAL; + if( iVersion==1 ) pBt->btsFlags |= BTS_NO_WAL; + + rc = sqlite3BtreeBeginTrans(pBtree, 0); + if( rc==SQLITE_OK ){ + u8 *aData = pBt->pPage1->aData; + if( aData[18]!=(u8)iVersion || aData[19]!=(u8)iVersion ){ + rc = sqlite3BtreeBeginTrans(pBtree, 2); + if( rc==SQLITE_OK ){ + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + if( rc==SQLITE_OK ){ + aData[18] = (u8)iVersion; + aData[19] = (u8)iVersion; + } + } + } + } + + pBt->btsFlags &= ~BTS_NO_WAL; + return rc; +} diff --git a/scalos/libraries/sqlite/src/btree.h b/scalos/libraries/sqlite/src/btree.h new file mode 100644 index 000000000..9e3a73b3b --- /dev/null +++ b/scalos/libraries/sqlite/src/btree.h @@ -0,0 +1,241 @@ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This header file defines the interface that the sqlite B-Tree file +** subsystem. See comments in the source code for a detailed description +** of what each interface routine does. +*/ +#ifndef _BTREE_H_ +#define _BTREE_H_ + +/* TODO: This definition is just included so other modules compile. It +** needs to be revisited. +*/ +#define SQLITE_N_BTREE_META 10 + +/* +** If defined as non-zero, auto-vacuum is enabled by default. Otherwise +** it must be turned on for each database using "PRAGMA auto_vacuum = 1". +*/ +#ifndef SQLITE_DEFAULT_AUTOVACUUM + #define SQLITE_DEFAULT_AUTOVACUUM 0 +#endif + +#define BTREE_AUTOVACUUM_NONE 0 /* Do not do auto-vacuum */ +#define BTREE_AUTOVACUUM_FULL 1 /* Do full auto-vacuum */ +#define BTREE_AUTOVACUUM_INCR 2 /* Incremental vacuum */ + +/* +** Forward declarations of structure +*/ +typedef struct Btree Btree; +typedef struct BtCursor BtCursor; +typedef struct BtShared BtShared; + + +int sqlite3BtreeOpen( + sqlite3_vfs *pVfs, /* VFS to use with this b-tree */ + const char *zFilename, /* Name of database file to open */ + sqlite3 *db, /* Associated database connection */ + Btree **ppBtree, /* Return open Btree* here */ + int flags, /* Flags */ + int vfsFlags /* Flags passed through to VFS open */ +); + +/* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the +** following values. +** +** NOTE: These values must match the corresponding PAGER_ values in +** pager.h. +*/ +#define BTREE_OMIT_JOURNAL 1 /* Do not create or use a rollback journal */ +#define BTREE_NO_READLOCK 2 /* Omit readlocks on readonly files */ +#define BTREE_MEMORY 4 /* This is an in-memory DB */ +#define BTREE_SINGLE 8 /* The file contains at most 1 b-tree */ +#define BTREE_UNORDERED 16 /* Use of a hash implementation is OK */ + +int sqlite3BtreeClose(Btree*); +int sqlite3BtreeSetCacheSize(Btree*,int); +int sqlite3BtreeSetSafetyLevel(Btree*,int,int,int); +int sqlite3BtreeSyncDisabled(Btree*); +int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix); +int sqlite3BtreeGetPageSize(Btree*); +int sqlite3BtreeMaxPageCount(Btree*,int); +u32 sqlite3BtreeLastPage(Btree*); +int sqlite3BtreeSecureDelete(Btree*,int); +int sqlite3BtreeGetReserve(Btree*); +int sqlite3BtreeSetAutoVacuum(Btree *, int); +int sqlite3BtreeGetAutoVacuum(Btree *); +int sqlite3BtreeBeginTrans(Btree*,int); +int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster); +int sqlite3BtreeCommitPhaseTwo(Btree*, int); +int sqlite3BtreeCommit(Btree*); +int sqlite3BtreeRollback(Btree*); +int sqlite3BtreeBeginStmt(Btree*,int); +int sqlite3BtreeCreateTable(Btree*, int*, int flags); +int sqlite3BtreeIsInTrans(Btree*); +int sqlite3BtreeIsInReadTrans(Btree*); +int sqlite3BtreeIsInBackup(Btree*); +void *sqlite3BtreeSchema(Btree *, int, void(*)(void *)); +int sqlite3BtreeSchemaLocked(Btree *pBtree); +int sqlite3BtreeLockTable(Btree *pBtree, int iTab, u8 isWriteLock); +int sqlite3BtreeSavepoint(Btree *, int, int); + +const char *sqlite3BtreeGetFilename(Btree *); +const char *sqlite3BtreeGetJournalname(Btree *); +int sqlite3BtreeCopyFile(Btree *, Btree *); + +int sqlite3BtreeIncrVacuum(Btree *); + +/* The flags parameter to sqlite3BtreeCreateTable can be the bitwise OR +** of the flags shown below. +** +** Every SQLite table must have either BTREE_INTKEY or BTREE_BLOBKEY set. +** With BTREE_INTKEY, the table key is a 64-bit integer and arbitrary data +** is stored in the leaves. (BTREE_INTKEY is used for SQL tables.) With +** BTREE_BLOBKEY, the key is an arbitrary BLOB and no content is stored +** anywhere - the key is the content. (BTREE_BLOBKEY is used for SQL +** indices.) +*/ +#define BTREE_INTKEY 1 /* Table has only 64-bit signed integer keys */ +#define BTREE_BLOBKEY 2 /* Table has keys only - no data */ + +int sqlite3BtreeDropTable(Btree*, int, int*); +int sqlite3BtreeClearTable(Btree*, int, int*); +void sqlite3BtreeTripAllCursors(Btree*, int); + +void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue); +int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value); + +/* +** The second parameter to sqlite3BtreeGetMeta or sqlite3BtreeUpdateMeta +** should be one of the following values. The integer values are assigned +** to constants so that the offset of the corresponding field in an +** SQLite database header may be found using the following formula: +** +** offset = 36 + (idx * 4) +** +** For example, the free-page-count field is located at byte offset 36 of +** the database file header. The incr-vacuum-flag field is located at +** byte offset 64 (== 36+4*7). +*/ +#define BTREE_FREE_PAGE_COUNT 0 +#define BTREE_SCHEMA_VERSION 1 +#define BTREE_FILE_FORMAT 2 +#define BTREE_DEFAULT_CACHE_SIZE 3 +#define BTREE_LARGEST_ROOT_PAGE 4 +#define BTREE_TEXT_ENCODING 5 +#define BTREE_USER_VERSION 6 +#define BTREE_INCR_VACUUM 7 + +int sqlite3BtreeCursor( + Btree*, /* BTree containing table to open */ + int iTable, /* Index of root page */ + int wrFlag, /* 1 for writing. 0 for read-only */ + struct KeyInfo*, /* First argument to compare function */ + BtCursor *pCursor /* Space to write cursor structure */ +); +int sqlite3BtreeCursorSize(void); +void sqlite3BtreeCursorZero(BtCursor*); + +int sqlite3BtreeCloseCursor(BtCursor*); +int sqlite3BtreeMovetoUnpacked( + BtCursor*, + UnpackedRecord *pUnKey, + i64 intKey, + int bias, + int *pRes +); +int sqlite3BtreeCursorHasMoved(BtCursor*, int*); +int sqlite3BtreeDelete(BtCursor*); +int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey, + const void *pData, int nData, + int nZero, int bias, int seekResult); +int sqlite3BtreeFirst(BtCursor*, int *pRes); +int sqlite3BtreeLast(BtCursor*, int *pRes); +int sqlite3BtreeNext(BtCursor*, int *pRes); +int sqlite3BtreeEof(BtCursor*); +int sqlite3BtreePrevious(BtCursor*, int *pRes); +int sqlite3BtreeKeySize(BtCursor*, i64 *pSize); +int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*); +const void *sqlite3BtreeKeyFetch(BtCursor*, int *pAmt); +const void *sqlite3BtreeDataFetch(BtCursor*, int *pAmt); +int sqlite3BtreeDataSize(BtCursor*, u32 *pSize); +int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*); +void sqlite3BtreeSetCachedRowid(BtCursor*, sqlite3_int64); +sqlite3_int64 sqlite3BtreeGetCachedRowid(BtCursor*); + +char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*); +struct Pager *sqlite3BtreePager(Btree*); + +int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*); +void sqlite3BtreeCacheOverflow(BtCursor *); +void sqlite3BtreeClearCursor(BtCursor *); + +int sqlite3BtreeSetVersion(Btree *pBt, int iVersion); + +#ifndef NDEBUG +int sqlite3BtreeCursorIsValid(BtCursor*); +#endif + +#ifndef SQLITE_OMIT_BTREECOUNT +int sqlite3BtreeCount(BtCursor *, i64 *); +#endif + +#ifdef SQLITE_TEST +int sqlite3BtreeCursorInfo(BtCursor*, int*, int); +void sqlite3BtreeCursorList(Btree*); +#endif + +#ifndef SQLITE_OMIT_WAL + int sqlite3BtreeCheckpoint(Btree*, int, int *, int *); +#endif + +/* +** If we are not using shared cache, then there is no need to +** use mutexes to access the BtShared structures. So make the +** Enter and Leave procedures no-ops. +*/ +#ifndef SQLITE_OMIT_SHARED_CACHE + void sqlite3BtreeEnter(Btree*); + void sqlite3BtreeEnterAll(sqlite3*); +#else +# define sqlite3BtreeEnter(X) +# define sqlite3BtreeEnterAll(X) +#endif + +#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE + int sqlite3BtreeSharable(Btree*); + void sqlite3BtreeLeave(Btree*); + void sqlite3BtreeEnterCursor(BtCursor*); + void sqlite3BtreeLeaveCursor(BtCursor*); + void sqlite3BtreeLeaveAll(sqlite3*); +#ifndef NDEBUG + /* These routines are used inside assert() statements only. */ + int sqlite3BtreeHoldsMutex(Btree*); + int sqlite3BtreeHoldsAllMutexes(sqlite3*); + int sqlite3SchemaMutexHeld(sqlite3*,int,Schema*); +#endif +#else + +# define sqlite3BtreeSharable(X) 0 +# define sqlite3BtreeLeave(X) +# define sqlite3BtreeEnterCursor(X) +# define sqlite3BtreeLeaveCursor(X) +# define sqlite3BtreeLeaveAll(X) + +# define sqlite3BtreeHoldsMutex(X) 1 +# define sqlite3BtreeHoldsAllMutexes(X) 1 +# define sqlite3SchemaMutexHeld(X,Y,Z) 1 +#endif + + +#endif /* _BTREE_H_ */ diff --git a/scalos/libraries/sqlite/src/btreeInt.h b/scalos/libraries/sqlite/src/btreeInt.h new file mode 100644 index 000000000..907c02e60 --- /dev/null +++ b/scalos/libraries/sqlite/src/btreeInt.h @@ -0,0 +1,652 @@ +/* +** 2004 April 6 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file implements a external (disk-based) database using BTrees. +** For a detailed discussion of BTrees, refer to +** +** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3: +** "Sorting And Searching", pages 473-480. Addison-Wesley +** Publishing Company, Reading, Massachusetts. +** +** The basic idea is that each page of the file contains N database +** entries and N+1 pointers to subpages. +** +** ---------------------------------------------------------------- +** | Ptr(0) | Key(0) | Ptr(1) | Key(1) | ... | Key(N-1) | Ptr(N) | +** ---------------------------------------------------------------- +** +** All of the keys on the page that Ptr(0) points to have values less +** than Key(0). All of the keys on page Ptr(1) and its subpages have +** values greater than Key(0) and less than Key(1). All of the keys +** on Ptr(N) and its subpages have values greater than Key(N-1). And +** so forth. +** +** Finding a particular key requires reading O(log(M)) pages from the +** disk where M is the number of entries in the tree. +** +** In this implementation, a single file can hold one or more separate +** BTrees. Each BTree is identified by the index of its root page. The +** key and data for any entry are combined to form the "payload". A +** fixed amount of payload can be carried directly on the database +** page. If the payload is larger than the preset amount then surplus +** bytes are stored on overflow pages. The payload for an entry +** and the preceding pointer are combined to form a "Cell". Each +** page has a small header which contains the Ptr(N) pointer and other +** information such as the size of key and data. +** +** FORMAT DETAILS +** +** The file is divided into pages. The first page is called page 1, +** the second is page 2, and so forth. A page number of zero indicates +** "no such page". The page size can be any power of 2 between 512 and 65536. +** Each page can be either a btree page, a freelist page, an overflow +** page, or a pointer-map page. +** +** The first page is always a btree page. The first 100 bytes of the first +** page contain a special header (the "file header") that describes the file. +** The format of the file header is as follows: +** +** OFFSET SIZE DESCRIPTION +** 0 16 Header string: "SQLite format 3\000" +** 16 2 Page size in bytes. +** 18 1 File format write version +** 19 1 File format read version +** 20 1 Bytes of unused space at the end of each page +** 21 1 Max embedded payload fraction +** 22 1 Min embedded payload fraction +** 23 1 Min leaf payload fraction +** 24 4 File change counter +** 28 4 Reserved for future use +** 32 4 First freelist page +** 36 4 Number of freelist pages in the file +** 40 60 15 4-byte meta values passed to higher layers +** +** 40 4 Schema cookie +** 44 4 File format of schema layer +** 48 4 Size of page cache +** 52 4 Largest root-page (auto/incr_vacuum) +** 56 4 1=UTF-8 2=UTF16le 3=UTF16be +** 60 4 User version +** 64 4 Incremental vacuum mode +** 68 4 unused +** 72 4 unused +** 76 4 unused +** +** All of the integer values are big-endian (most significant byte first). +** +** The file change counter is incremented when the database is changed +** This counter allows other processes to know when the file has changed +** and thus when they need to flush their cache. +** +** The max embedded payload fraction is the amount of the total usable +** space in a page that can be consumed by a single cell for standard +** B-tree (non-LEAFDATA) tables. A value of 255 means 100%. The default +** is to limit the maximum cell size so that at least 4 cells will fit +** on one page. Thus the default max embedded payload fraction is 64. +** +** If the payload for a cell is larger than the max payload, then extra +** payload is spilled to overflow pages. Once an overflow page is allocated, +** as many bytes as possible are moved into the overflow pages without letting +** the cell size drop below the min embedded payload fraction. +** +** The min leaf payload fraction is like the min embedded payload fraction +** except that it applies to leaf nodes in a LEAFDATA tree. The maximum +** payload fraction for a LEAFDATA tree is always 100% (or 255) and it +** not specified in the header. +** +** Each btree pages is divided into three sections: The header, the +** cell pointer array, and the cell content area. Page 1 also has a 100-byte +** file header that occurs before the page header. +** +** |----------------| +** | file header | 100 bytes. Page 1 only. +** |----------------| +** | page header | 8 bytes for leaves. 12 bytes for interior nodes +** |----------------| +** | cell pointer | | 2 bytes per cell. Sorted order. +** | array | | Grows downward +** | | v +** |----------------| +** | unallocated | +** | space | +** |----------------| ^ Grows upwards +** | cell content | | Arbitrary order interspersed with freeblocks. +** | area | | and free space fragments. +** |----------------| +** +** The page headers looks like this: +** +** OFFSET SIZE DESCRIPTION +** 0 1 Flags. 1: intkey, 2: zerodata, 4: leafdata, 8: leaf +** 1 2 byte offset to the first freeblock +** 3 2 number of cells on this page +** 5 2 first byte of the cell content area +** 7 1 number of fragmented free bytes +** 8 4 Right child (the Ptr(N) value). Omitted on leaves. +** +** The flags define the format of this btree page. The leaf flag means that +** this page has no children. The zerodata flag means that this page carries +** only keys and no data. The intkey flag means that the key is a integer +** which is stored in the key size entry of the cell header rather than in +** the payload area. +** +** The cell pointer array begins on the first byte after the page header. +** The cell pointer array contains zero or more 2-byte numbers which are +** offsets from the beginning of the page to the cell content in the cell +** content area. The cell pointers occur in sorted order. The system strives +** to keep free space after the last cell pointer so that new cells can +** be easily added without having to defragment the page. +** +** Cell content is stored at the very end of the page and grows toward the +** beginning of the page. +** +** Unused space within the cell content area is collected into a linked list of +** freeblocks. Each freeblock is at least 4 bytes in size. The byte offset +** to the first freeblock is given in the header. Freeblocks occur in +** increasing order. Because a freeblock must be at least 4 bytes in size, +** any group of 3 or fewer unused bytes in the cell content area cannot +** exist on the freeblock chain. A group of 3 or fewer free bytes is called +** a fragment. The total number of bytes in all fragments is recorded. +** in the page header at offset 7. +** +** SIZE DESCRIPTION +** 2 Byte offset of the next freeblock +** 2 Bytes in this freeblock +** +** Cells are of variable length. Cells are stored in the cell content area at +** the end of the page. Pointers to the cells are in the cell pointer array +** that immediately follows the page header. Cells is not necessarily +** contiguous or in order, but cell pointers are contiguous and in order. +** +** Cell content makes use of variable length integers. A variable +** length integer is 1 to 9 bytes where the lower 7 bits of each +** byte are used. The integer consists of all bytes that have bit 8 set and +** the first byte with bit 8 clear. The most significant byte of the integer +** appears first. A variable-length integer may not be more than 9 bytes long. +** As a special case, all 8 bytes of the 9th byte are used as data. This +** allows a 64-bit integer to be encoded in 9 bytes. +** +** 0x00 becomes 0x00000000 +** 0x7f becomes 0x0000007f +** 0x81 0x00 becomes 0x00000080 +** 0x82 0x00 becomes 0x00000100 +** 0x80 0x7f becomes 0x0000007f +** 0x8a 0x91 0xd1 0xac 0x78 becomes 0x12345678 +** 0x81 0x81 0x81 0x81 0x01 becomes 0x10204081 +** +** Variable length integers are used for rowids and to hold the number of +** bytes of key and data in a btree cell. +** +** The content of a cell looks like this: +** +** SIZE DESCRIPTION +** 4 Page number of the left child. Omitted if leaf flag is set. +** var Number of bytes of data. Omitted if the zerodata flag is set. +** var Number of bytes of key. Or the key itself if intkey flag is set. +** * Payload +** 4 First page of the overflow chain. Omitted if no overflow +** +** Overflow pages form a linked list. Each page except the last is completely +** filled with data (pagesize - 4 bytes). The last page can have as little +** as 1 byte of data. +** +** SIZE DESCRIPTION +** 4 Page number of next overflow page +** * Data +** +** Freelist pages come in two subtypes: trunk pages and leaf pages. The +** file header points to the first in a linked list of trunk page. Each trunk +** page points to multiple leaf pages. The content of a leaf page is +** unspecified. A trunk page looks like this: +** +** SIZE DESCRIPTION +** 4 Page number of next trunk page +** 4 Number of leaf pointers on this page +** * zero or more pages numbers of leaves +*/ +#include "sqliteInt.h" + + +/* The following value is the maximum cell size assuming a maximum page +** size give above. +*/ +#define MX_CELL_SIZE(pBt) ((int)(pBt->pageSize-8)) + +/* The maximum number of cells on a single page of the database. This +** assumes a minimum cell size of 6 bytes (4 bytes for the cell itself +** plus 2 bytes for the index to the cell in the page header). Such +** small cells will be rare, but they are possible. +*/ +#define MX_CELL(pBt) ((pBt->pageSize-8)/6) + +/* Forward declarations */ +typedef struct MemPage MemPage; +typedef struct BtLock BtLock; + +/* +** This is a magic string that appears at the beginning of every +** SQLite database in order to identify the file as a real database. +** +** You can change this value at compile-time by specifying a +** -DSQLITE_FILE_HEADER="..." on the compiler command-line. The +** header must be exactly 16 bytes including the zero-terminator so +** the string itself should be 15 characters long. If you change +** the header, then your custom library will not be able to read +** databases generated by the standard tools and the standard tools +** will not be able to read databases created by your custom library. +*/ +#ifndef SQLITE_FILE_HEADER /* 123456789 123456 */ +# define SQLITE_FILE_HEADER "SQLite format 3" +#endif + +/* +** Page type flags. An ORed combination of these flags appear as the +** first byte of on-disk image of every BTree page. +*/ +#define PTF_INTKEY 0x01 +#define PTF_ZERODATA 0x02 +#define PTF_LEAFDATA 0x04 +#define PTF_LEAF 0x08 + +/* +** As each page of the file is loaded into memory, an instance of the following +** structure is appended and initialized to zero. This structure stores +** information about the page that is decoded from the raw file page. +** +** The pParent field points back to the parent page. This allows us to +** walk up the BTree from any leaf to the root. Care must be taken to +** unref() the parent page pointer when this page is no longer referenced. +** The pageDestructor() routine handles that chore. +** +** Access to all fields of this structure is controlled by the mutex +** stored in MemPage.pBt->mutex. +*/ +struct MemPage { + u8 isInit; /* True if previously initialized. MUST BE FIRST! */ + u8 nOverflow; /* Number of overflow cell bodies in aCell[] */ + u8 intKey; /* True if intkey flag is set */ + u8 leaf; /* True if leaf flag is set */ + u8 hasData; /* True if this page stores data */ + u8 hdrOffset; /* 100 for page 1. 0 otherwise */ + u8 childPtrSize; /* 0 if leaf==1. 4 if leaf==0 */ + u8 max1bytePayload; /* min(maxLocal,127) */ + u16 maxLocal; /* Copy of BtShared.maxLocal or BtShared.maxLeaf */ + u16 minLocal; /* Copy of BtShared.minLocal or BtShared.minLeaf */ + u16 cellOffset; /* Index in aData of first cell pointer */ + u16 nFree; /* Number of free bytes on the page */ + u16 nCell; /* Number of cells on this page, local and ovfl */ + u16 maskPage; /* Mask for page offset */ + struct _OvflCell { /* Cells that will not fit on aData[] */ + u8 *pCell; /* Pointers to the body of the overflow cell */ + u16 idx; /* Insert this cell before idx-th non-overflow cell */ + } aOvfl[5]; + BtShared *pBt; /* Pointer to BtShared that this page is part of */ + u8 *aData; /* Pointer to disk image of the page data */ + u8 *aDataEnd; /* One byte past the end of usable data */ + u8 *aCellIdx; /* The cell index area */ + DbPage *pDbPage; /* Pager page handle */ + Pgno pgno; /* Page number for this page */ +}; + +/* +** The in-memory image of a disk page has the auxiliary information appended +** to the end. EXTRA_SIZE is the number of bytes of space needed to hold +** that extra information. +*/ +#define EXTRA_SIZE sizeof(MemPage) + +/* +** A linked list of the following structures is stored at BtShared.pLock. +** Locks are added (or upgraded from READ_LOCK to WRITE_LOCK) when a cursor +** is opened on the table with root page BtShared.iTable. Locks are removed +** from this list when a transaction is committed or rolled back, or when +** a btree handle is closed. +*/ +struct BtLock { + Btree *pBtree; /* Btree handle holding this lock */ + Pgno iTable; /* Root page of table */ + u8 eLock; /* READ_LOCK or WRITE_LOCK */ + BtLock *pNext; /* Next in BtShared.pLock list */ +}; + +/* Candidate values for BtLock.eLock */ +#define READ_LOCK 1 +#define WRITE_LOCK 2 + +/* A Btree handle +** +** A database connection contains a pointer to an instance of +** this object for every database file that it has open. This structure +** is opaque to the database connection. The database connection cannot +** see the internals of this structure and only deals with pointers to +** this structure. +** +** For some database files, the same underlying database cache might be +** shared between multiple connections. In that case, each connection +** has it own instance of this object. But each instance of this object +** points to the same BtShared object. The database cache and the +** schema associated with the database file are all contained within +** the BtShared object. +** +** All fields in this structure are accessed under sqlite3.mutex. +** The pBt pointer itself may not be changed while there exists cursors +** in the referenced BtShared that point back to this Btree since those +** cursors have to go through this Btree to find their BtShared and +** they often do so without holding sqlite3.mutex. +*/ +struct Btree { + sqlite3 *db; /* The database connection holding this btree */ + BtShared *pBt; /* Sharable content of this btree */ + u8 inTrans; /* TRANS_NONE, TRANS_READ or TRANS_WRITE */ + u8 sharable; /* True if we can share pBt with another db */ + u8 locked; /* True if db currently has pBt locked */ + int wantToLock; /* Number of nested calls to sqlite3BtreeEnter() */ + int nBackup; /* Number of backup operations reading this btree */ + Btree *pNext; /* List of other sharable Btrees from the same db */ + Btree *pPrev; /* Back pointer of the same list */ +#ifndef SQLITE_OMIT_SHARED_CACHE + BtLock lock; /* Object used to lock page 1 */ +#endif +}; + +/* +** Btree.inTrans may take one of the following values. +** +** If the shared-data extension is enabled, there may be multiple users +** of the Btree structure. At most one of these may open a write transaction, +** but any number may have active read transactions. +*/ +#define TRANS_NONE 0 +#define TRANS_READ 1 +#define TRANS_WRITE 2 + +/* +** An instance of this object represents a single database file. +** +** A single database file can be in use at the same time by two +** or more database connections. When two or more connections are +** sharing the same database file, each connection has it own +** private Btree object for the file and each of those Btrees points +** to this one BtShared object. BtShared.nRef is the number of +** connections currently sharing this database file. +** +** Fields in this structure are accessed under the BtShared.mutex +** mutex, except for nRef and pNext which are accessed under the +** global SQLITE_MUTEX_STATIC_MASTER mutex. The pPager field +** may not be modified once it is initially set as long as nRef>0. +** The pSchema field may be set once under BtShared.mutex and +** thereafter is unchanged as long as nRef>0. +** +** isPending: +** +** If a BtShared client fails to obtain a write-lock on a database +** table (because there exists one or more read-locks on the table), +** the shared-cache enters 'pending-lock' state and isPending is +** set to true. +** +** The shared-cache leaves the 'pending lock' state when either of +** the following occur: +** +** 1) The current writer (BtShared.pWriter) concludes its transaction, OR +** 2) The number of locks held by other connections drops to zero. +** +** while in the 'pending-lock' state, no connection may start a new +** transaction. +** +** This feature is included to help prevent writer-starvation. +*/ +struct BtShared { + Pager *pPager; /* The page cache */ + sqlite3 *db; /* Database connection currently using this Btree */ + BtCursor *pCursor; /* A list of all open cursors */ + MemPage *pPage1; /* First page of the database */ + u8 openFlags; /* Flags to sqlite3BtreeOpen() */ +#ifndef SQLITE_OMIT_AUTOVACUUM + u8 autoVacuum; /* True if auto-vacuum is enabled */ + u8 incrVacuum; /* True if incr-vacuum is enabled */ +#endif + u8 inTransaction; /* Transaction state */ + u8 max1bytePayload; /* Maximum first byte of cell for a 1-byte payload */ + u16 btsFlags; /* Boolean parameters. See BTS_* macros below */ + u16 maxLocal; /* Maximum local payload in non-LEAFDATA tables */ + u16 minLocal; /* Minimum local payload in non-LEAFDATA tables */ + u16 maxLeaf; /* Maximum local payload in a LEAFDATA table */ + u16 minLeaf; /* Minimum local payload in a LEAFDATA table */ + u32 pageSize; /* Total number of bytes on a page */ + u32 usableSize; /* Number of usable bytes on each page */ + int nTransaction; /* Number of open transactions (read + write) */ + u32 nPage; /* Number of pages in the database */ + void *pSchema; /* Pointer to space allocated by sqlite3BtreeSchema() */ + void (*xFreeSchema)(void*); /* Destructor for BtShared.pSchema */ + sqlite3_mutex *mutex; /* Non-recursive mutex required to access this object */ + Bitvec *pHasContent; /* Set of pages moved to free-list this transaction */ +#ifndef SQLITE_OMIT_SHARED_CACHE + int nRef; /* Number of references to this structure */ + BtShared *pNext; /* Next on a list of sharable BtShared structs */ + BtLock *pLock; /* List of locks held on this shared-btree struct */ + Btree *pWriter; /* Btree with currently open write transaction */ +#endif + u8 *pTmpSpace; /* BtShared.pageSize bytes of space for tmp use */ +}; + +/* +** Allowed values for BtShared.btsFlags +*/ +#define BTS_READ_ONLY 0x0001 /* Underlying file is readonly */ +#define BTS_PAGESIZE_FIXED 0x0002 /* Page size can no longer be changed */ +#define BTS_SECURE_DELETE 0x0004 /* PRAGMA secure_delete is enabled */ +#define BTS_INITIALLY_EMPTY 0x0008 /* Database was empty at trans start */ +#define BTS_NO_WAL 0x0010 /* Do not open write-ahead-log files */ +#define BTS_EXCLUSIVE 0x0020 /* pWriter has an exclusive lock */ +#define BTS_PENDING 0x0040 /* Waiting for read-locks to clear */ + +/* +** An instance of the following structure is used to hold information +** about a cell. The parseCellPtr() function fills in this structure +** based on information extract from the raw disk page. +*/ +typedef struct CellInfo CellInfo; +struct CellInfo { + i64 nKey; /* The key for INTKEY tables, or number of bytes in key */ + u8 *pCell; /* Pointer to the start of cell content */ + u32 nData; /* Number of bytes of data */ + u32 nPayload; /* Total amount of payload */ + u16 nHeader; /* Size of the cell content header in bytes */ + u16 nLocal; /* Amount of payload held locally */ + u16 iOverflow; /* Offset to overflow page number. Zero if no overflow */ + u16 nSize; /* Size of the cell content on the main b-tree page */ +}; + +/* +** Maximum depth of an SQLite B-Tree structure. Any B-Tree deeper than +** this will be declared corrupt. This value is calculated based on a +** maximum database size of 2^31 pages a minimum fanout of 2 for a +** root-node and 3 for all other internal nodes. +** +** If a tree that appears to be taller than this is encountered, it is +** assumed that the database is corrupt. +*/ +#define BTCURSOR_MAX_DEPTH 20 + +/* +** A cursor is a pointer to a particular entry within a particular +** b-tree within a database file. +** +** The entry is identified by its MemPage and the index in +** MemPage.aCell[] of the entry. +** +** A single database file can be shared by two more database connections, +** but cursors cannot be shared. Each cursor is associated with a +** particular database connection identified BtCursor.pBtree.db. +** +** Fields in this structure are accessed under the BtShared.mutex +** found at self->pBt->mutex. +*/ +struct BtCursor { + Btree *pBtree; /* The Btree to which this cursor belongs */ + BtShared *pBt; /* The BtShared this cursor points to */ + BtCursor *pNext, *pPrev; /* Forms a linked list of all cursors */ + struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */ + Pgno pgnoRoot; /* The root page of this tree */ + sqlite3_int64 cachedRowid; /* Next rowid cache. 0 means not valid */ + CellInfo info; /* A parse of the cell we are pointing at */ + i64 nKey; /* Size of pKey, or last integer key */ + void *pKey; /* Saved key that was cursor's last known position */ + int skipNext; /* Prev() is noop if negative. Next() is noop if positive */ + u8 wrFlag; /* True if writable */ + u8 atLast; /* Cursor pointing to the last entry */ + u8 validNKey; /* True if info.nKey is valid */ + u8 eState; /* One of the CURSOR_XXX constants (see below) */ +#ifndef SQLITE_OMIT_INCRBLOB + Pgno *aOverflow; /* Cache of overflow page locations */ + u8 isIncrblobHandle; /* True if this cursor is an incr. io handle */ +#endif + i16 iPage; /* Index of current page in apPage */ + u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */ + MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */ +}; + +/* +** Potential values for BtCursor.eState. +** +** CURSOR_VALID: +** Cursor points to a valid entry. getPayload() etc. may be called. +** +** CURSOR_INVALID: +** Cursor does not point to a valid entry. This can happen (for example) +** because the table is empty or because BtreeCursorFirst() has not been +** called. +** +** CURSOR_REQUIRESEEK: +** The table that this cursor was opened on still exists, but has been +** modified since the cursor was last used. The cursor position is saved +** in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in +** this state, restoreCursorPosition() can be called to attempt to +** seek the cursor to the saved position. +** +** CURSOR_FAULT: +** A unrecoverable error (an I/O error or a malloc failure) has occurred +** on a different connection that shares the BtShared cache with this +** cursor. The error has left the cache in an inconsistent state. +** Do nothing else with this cursor. Any attempt to use the cursor +** should return the error code stored in BtCursor.skip +*/ +#define CURSOR_INVALID 0 +#define CURSOR_VALID 1 +#define CURSOR_REQUIRESEEK 2 +#define CURSOR_FAULT 3 + +/* +** The database page the PENDING_BYTE occupies. This page is never used. +*/ +# define PENDING_BYTE_PAGE(pBt) PAGER_MJ_PGNO(pBt) + +/* +** These macros define the location of the pointer-map entry for a +** database page. The first argument to each is the number of usable +** bytes on each page of the database (often 1024). The second is the +** page number to look up in the pointer map. +** +** PTRMAP_PAGENO returns the database page number of the pointer-map +** page that stores the required pointer. PTRMAP_PTROFFSET returns +** the offset of the requested map entry. +** +** If the pgno argument passed to PTRMAP_PAGENO is a pointer-map page, +** then pgno is returned. So (pgno==PTRMAP_PAGENO(pgsz, pgno)) can be +** used to test if pgno is a pointer-map page. PTRMAP_ISPAGE implements +** this test. +*/ +#define PTRMAP_PAGENO(pBt, pgno) ptrmapPageno(pBt, pgno) +#define PTRMAP_PTROFFSET(pgptrmap, pgno) (5*(pgno-pgptrmap-1)) +#define PTRMAP_ISPAGE(pBt, pgno) (PTRMAP_PAGENO((pBt),(pgno))==(pgno)) + +/* +** The pointer map is a lookup table that identifies the parent page for +** each child page in the database file. The parent page is the page that +** contains a pointer to the child. Every page in the database contains +** 0 or 1 parent pages. (In this context 'database page' refers +** to any page that is not part of the pointer map itself.) Each pointer map +** entry consists of a single byte 'type' and a 4 byte parent page number. +** The PTRMAP_XXX identifiers below are the valid types. +** +** The purpose of the pointer map is to facility moving pages from one +** position in the file to another as part of autovacuum. When a page +** is moved, the pointer in its parent must be updated to point to the +** new location. The pointer map is used to locate the parent page quickly. +** +** PTRMAP_ROOTPAGE: The database page is a root-page. The page-number is not +** used in this case. +** +** PTRMAP_FREEPAGE: The database page is an unused (free) page. The page-number +** is not used in this case. +** +** PTRMAP_OVERFLOW1: The database page is the first page in a list of +** overflow pages. The page number identifies the page that +** contains the cell with a pointer to this overflow page. +** +** PTRMAP_OVERFLOW2: The database page is the second or later page in a list of +** overflow pages. The page-number identifies the previous +** page in the overflow page list. +** +** PTRMAP_BTREE: The database page is a non-root btree page. The page number +** identifies the parent page in the btree. +*/ +#define PTRMAP_ROOTPAGE 1 +#define PTRMAP_FREEPAGE 2 +#define PTRMAP_OVERFLOW1 3 +#define PTRMAP_OVERFLOW2 4 +#define PTRMAP_BTREE 5 + +/* A bunch of assert() statements to check the transaction state variables +** of handle p (type Btree*) are internally consistent. +*/ +#define btreeIntegrity(p) \ + assert( p->pBt->inTransaction!=TRANS_NONE || p->pBt->nTransaction==0 ); \ + assert( p->pBt->inTransaction>=p->inTrans ); + + +/* +** The ISAUTOVACUUM macro is used within balance_nonroot() to determine +** if the database supports auto-vacuum or not. Because it is used +** within an expression that is an argument to another macro +** (sqliteMallocRaw), it is not possible to use conditional compilation. +** So, this macro is defined instead. +*/ +#ifndef SQLITE_OMIT_AUTOVACUUM +#define ISAUTOVACUUM (pBt->autoVacuum) +#else +#define ISAUTOVACUUM 0 +#endif + + +/* +** This structure is passed around through all the sanity checking routines +** in order to keep track of some global state information. +*/ +typedef struct IntegrityCk IntegrityCk; +struct IntegrityCk { + BtShared *pBt; /* The tree being checked out */ + Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */ + Pgno nPage; /* Number of pages in the database */ + int *anRef; /* Number of times each page is referenced */ + int mxErr; /* Stop accumulating errors when this reaches zero */ + int nErr; /* Number of messages written to zErrMsg so far */ + int mallocFailed; /* A memory allocation error has occurred */ + StrAccum errMsg; /* Accumulate the error message text here */ +}; + +/* +** Routines to read or write a two- and four-byte big-endian integer values. +*/ +#define get2byte(x) ((x)[0]<<8 | (x)[1]) +#define put2byte(p,v) ((p)[0] = (u8)((v)>>8), (p)[1] = (u8)(v)) +#define get4byte sqlite3Get4byte +#define put4byte sqlite3Put4byte diff --git a/scalos/libraries/sqlite/src/build.c b/scalos/libraries/sqlite/src/build.c new file mode 100644 index 000000000..5798e7322 --- /dev/null +++ b/scalos/libraries/sqlite/src/build.c @@ -0,0 +1,3822 @@ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains C code routines that are called by the SQLite parser +** when syntax rules are reduced. The routines in this file handle the +** following kinds of SQL syntax: +** +** CREATE TABLE +** DROP TABLE +** CREATE INDEX +** DROP INDEX +** creating ID lists +** BEGIN TRANSACTION +** COMMIT +** ROLLBACK +*/ +#include "sqliteInt.h" + +/* +** This routine is called when a new SQL statement is beginning to +** be parsed. Initialize the pParse structure as needed. +*/ +void sqlite3BeginParse(Parse *pParse, int explainFlag){ + pParse->explain = (u8)explainFlag; + pParse->nVar = 0; +} + +#ifndef SQLITE_OMIT_SHARED_CACHE +/* +** The TableLock structure is only used by the sqlite3TableLock() and +** codeTableLocks() functions. +*/ +struct TableLock { + int iDb; /* The database containing the table to be locked */ + int iTab; /* The root page of the table to be locked */ + u8 isWriteLock; /* True for write lock. False for a read lock */ + const char *zName; /* Name of the table */ +}; + +/* +** Record the fact that we want to lock a table at run-time. +** +** The table to be locked has root page iTab and is found in database iDb. +** A read or a write lock can be taken depending on isWritelock. +** +** This routine just records the fact that the lock is desired. The +** code to make the lock occur is generated by a later call to +** codeTableLocks() which occurs during sqlite3FinishCoding(). +*/ +void sqlite3TableLock( + Parse *pParse, /* Parsing context */ + int iDb, /* Index of the database containing the table to lock */ + int iTab, /* Root page number of the table to be locked */ + u8 isWriteLock, /* True for a write lock */ + const char *zName /* Name of the table to be locked */ +){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + int i; + int nBytes; + TableLock *p; + assert( iDb>=0 ); + + for(i=0; inTableLock; i++){ + p = &pToplevel->aTableLock[i]; + if( p->iDb==iDb && p->iTab==iTab ){ + p->isWriteLock = (p->isWriteLock || isWriteLock); + return; + } + } + + nBytes = sizeof(TableLock) * (pToplevel->nTableLock+1); + pToplevel->aTableLock = + sqlite3DbReallocOrFree(pToplevel->db, pToplevel->aTableLock, nBytes); + if( pToplevel->aTableLock ){ + p = &pToplevel->aTableLock[pToplevel->nTableLock++]; + p->iDb = iDb; + p->iTab = iTab; + p->isWriteLock = isWriteLock; + p->zName = zName; + }else{ + pToplevel->nTableLock = 0; + pToplevel->db->mallocFailed = 1; + } +} + +/* +** Code an OP_TableLock instruction for each table locked by the +** statement (configured by calls to sqlite3TableLock()). +*/ +static void codeTableLocks(Parse *pParse){ + int i; + Vdbe *pVdbe; + + pVdbe = sqlite3GetVdbe(pParse); + assert( pVdbe!=0 ); /* sqlite3GetVdbe cannot fail: VDBE already allocated */ + + for(i=0; inTableLock; i++){ + TableLock *p = &pParse->aTableLock[i]; + int p1 = p->iDb; + sqlite3VdbeAddOp4(pVdbe, OP_TableLock, p1, p->iTab, p->isWriteLock, + p->zName, P4_STATIC); + } +} +#else + #define codeTableLocks(x) +#endif + +/* +** This routine is called after a single SQL statement has been +** parsed and a VDBE program to execute that statement has been +** prepared. This routine puts the finishing touches on the +** VDBE program and resets the pParse structure for the next +** parse. +** +** Note that if an error occurred, it might be the case that +** no VDBE code was generated. +*/ +void sqlite3FinishCoding(Parse *pParse){ + sqlite3 *db; + Vdbe *v; + + db = pParse->db; + if( db->mallocFailed ) return; + if( pParse->nested ) return; + if( pParse->nErr ) return; + + /* Begin by generating some termination code at the end of the + ** vdbe program + */ + v = sqlite3GetVdbe(pParse); + assert( !pParse->isMultiWrite + || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort)); + if( v ){ + sqlite3VdbeAddOp0(v, OP_Halt); + + /* The cookie mask contains one bit for each database file open. + ** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are + ** set for each database that is used. Generate code to start a + ** transaction on each used database and to verify the schema cookie + ** on each used database. + */ + if( pParse->cookieGoto>0 ){ + yDbMask mask; + int iDb; + sqlite3VdbeJumpHere(v, pParse->cookieGoto-1); + for(iDb=0, mask=1; iDbnDb; mask<<=1, iDb++){ + if( (mask & pParse->cookieMask)==0 ) continue; + sqlite3VdbeUsesBtree(v, iDb); + sqlite3VdbeAddOp2(v,OP_Transaction, iDb, (mask & pParse->writeMask)!=0); + if( db->init.busy==0 ){ + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + sqlite3VdbeAddOp3(v, OP_VerifyCookie, + iDb, pParse->cookieValue[iDb], + db->aDb[iDb].pSchema->iGeneration); + } + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + { + int i; + for(i=0; inVtabLock; i++){ + char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]); + sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB); + } + pParse->nVtabLock = 0; + } +#endif + + /* Once all the cookies have been verified and transactions opened, + ** obtain the required table-locks. This is a no-op unless the + ** shared-cache feature is enabled. + */ + codeTableLocks(pParse); + + /* Initialize any AUTOINCREMENT data structures required. + */ + sqlite3AutoincrementBegin(pParse); + + /* Finally, jump back to the beginning of the executable code. */ + sqlite3VdbeAddOp2(v, OP_Goto, 0, pParse->cookieGoto); + } + } + + + /* Get the VDBE program ready for execution + */ + if( v && ALWAYS(pParse->nErr==0) && !db->mallocFailed ){ +#ifdef SQLITE_DEBUG + FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0; + sqlite3VdbeTrace(v, trace); +#endif + assert( pParse->iCacheLevel==0 ); /* Disables and re-enables match */ + /* A minimum of one cursor is required if autoincrement is used + * See ticket [a696379c1f08866] */ + if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1; + sqlite3VdbeMakeReady(v, pParse); + pParse->rc = SQLITE_DONE; + pParse->colNamesSet = 0; + }else{ + pParse->rc = SQLITE_ERROR; + } + pParse->nTab = 0; + pParse->nMem = 0; + pParse->nSet = 0; + pParse->nVar = 0; + pParse->cookieMask = 0; + pParse->cookieGoto = 0; +} + +/* +** Run the parser and code generator recursively in order to generate +** code for the SQL statement given onto the end of the pParse context +** currently under construction. When the parser is run recursively +** this way, the final OP_Halt is not appended and other initialization +** and finalization steps are omitted because those are handling by the +** outermost parser. +** +** Not everything is nestable. This facility is designed to permit +** INSERT, UPDATE, and DELETE operations against SQLITE_MASTER. Use +** care if you decide to try to use this routine for some other purposes. +*/ +void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){ + va_list ap; + char *zSql; + char *zErrMsg = 0; + sqlite3 *db = pParse->db; +# define SAVE_SZ (sizeof(Parse) - offsetof(Parse,nVar)) + char saveBuf[SAVE_SZ]; + + if( pParse->nErr ) return; + assert( pParse->nested<10 ); /* Nesting should only be of limited depth */ + va_start(ap, zFormat); + zSql = sqlite3VMPrintf(db, zFormat, ap); + va_end(ap); + if( zSql==0 ){ + return; /* A malloc must have failed */ + } + pParse->nested++; + memcpy(saveBuf, &pParse->nVar, SAVE_SZ); + memset(&pParse->nVar, 0, SAVE_SZ); + sqlite3RunParser(pParse, zSql, &zErrMsg); + sqlite3DbFree(db, zErrMsg); + sqlite3DbFree(db, zSql); + memcpy(&pParse->nVar, saveBuf, SAVE_SZ); + pParse->nested--; +} + +/* +** Locate the in-memory structure that describes a particular database +** table given the name of that table and (optionally) the name of the +** database containing the table. Return NULL if not found. +** +** If zDatabase is 0, all databases are searched for the table and the +** first matching table is returned. (No checking for duplicate table +** names is done.) The search order is TEMP first, then MAIN, then any +** auxiliary databases added using the ATTACH command. +** +** See also sqlite3LocateTable(). +*/ +Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){ + Table *p = 0; + int i; + int nName; + assert( zName!=0 ); + nName = sqlite3Strlen30(zName); + /* All mutexes are required for schema access. Make sure we hold them. */ + assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) ); + for(i=OMIT_TEMPDB; inDb; i++){ + int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ + if( zDatabase!=0 && sqlite3StrICmp(zDatabase, db->aDb[j].zName) ) continue; + assert( sqlite3SchemaMutexHeld(db, j, 0) ); + p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName, nName); + if( p ) break; + } + return p; +} + +/* +** Locate the in-memory structure that describes a particular database +** table given the name of that table and (optionally) the name of the +** database containing the table. Return NULL if not found. Also leave an +** error message in pParse->zErrMsg. +** +** The difference between this routine and sqlite3FindTable() is that this +** routine leaves an error message in pParse->zErrMsg where +** sqlite3FindTable() does not. +*/ +Table *sqlite3LocateTable( + Parse *pParse, /* context in which to report errors */ + int isView, /* True if looking for a VIEW rather than a TABLE */ + const char *zName, /* Name of the table we are looking for */ + const char *zDbase /* Name of the database. Might be NULL */ +){ + Table *p; + + /* Read the database schema. If an error occurs, leave an error message + ** and code in pParse and return NULL. */ + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + return 0; + } + + p = sqlite3FindTable(pParse->db, zName, zDbase); + if( p==0 ){ + const char *zMsg = isView ? "no such view" : "no such table"; + if( zDbase ){ + sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName); + }else{ + sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName); + } + pParse->checkSchema = 1; + } + return p; +} + +/* +** Locate the in-memory structure that describes +** a particular index given the name of that index +** and the name of the database that contains the index. +** Return NULL if not found. +** +** If zDatabase is 0, all databases are searched for the +** table and the first matching index is returned. (No checking +** for duplicate index names is done.) The search order is +** TEMP first, then MAIN, then any auxiliary databases added +** using the ATTACH command. +*/ +Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){ + Index *p = 0; + int i; + int nName = sqlite3Strlen30(zName); + /* All mutexes are required for schema access. Make sure we hold them. */ + assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) ); + for(i=OMIT_TEMPDB; inDb; i++){ + int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ + Schema *pSchema = db->aDb[j].pSchema; + assert( pSchema ); + if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue; + assert( sqlite3SchemaMutexHeld(db, j, 0) ); + p = sqlite3HashFind(&pSchema->idxHash, zName, nName); + if( p ) break; + } + return p; +} + +/* +** Reclaim the memory used by an index +*/ +static void freeIndex(sqlite3 *db, Index *p){ +#ifndef SQLITE_OMIT_ANALYZE + sqlite3DeleteIndexSamples(db, p); +#endif + sqlite3DbFree(db, p->zColAff); + sqlite3DbFree(db, p); +} + +/* +** For the index called zIdxName which is found in the database iDb, +** unlike that index from its Table then remove the index from +** the index hash table and free all memory structures associated +** with the index. +*/ +void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){ + Index *pIndex; + int len; + Hash *pHash; + + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + pHash = &db->aDb[iDb].pSchema->idxHash; + len = sqlite3Strlen30(zIdxName); + pIndex = sqlite3HashInsert(pHash, zIdxName, len, 0); + if( ALWAYS(pIndex) ){ + if( pIndex->pTable->pIndex==pIndex ){ + pIndex->pTable->pIndex = pIndex->pNext; + }else{ + Index *p; + /* Justification of ALWAYS(); The index must be on the list of + ** indices. */ + p = pIndex->pTable->pIndex; + while( ALWAYS(p) && p->pNext!=pIndex ){ p = p->pNext; } + if( ALWAYS(p && p->pNext==pIndex) ){ + p->pNext = pIndex->pNext; + } + } + freeIndex(db, pIndex); + } + db->flags |= SQLITE_InternChanges; +} + +/* +** Erase all schema information from the in-memory hash tables of +** a single database. This routine is called to reclaim memory +** before the database closes. It is also called during a rollback +** if there were schema changes during the transaction or if a +** schema-cookie mismatch occurs. +** +** If iDb<0 then reset the internal schema tables for all database +** files. If iDb>=0 then reset the internal schema for only the +** single file indicated. +*/ +void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){ + int i, j; + assert( iDbnDb ); + + if( iDb>=0 ){ + /* Case 1: Reset the single schema identified by iDb */ + Db *pDb = &db->aDb[iDb]; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + assert( pDb->pSchema!=0 ); + sqlite3SchemaClear(pDb->pSchema); + + /* If any database other than TEMP is reset, then also reset TEMP + ** since TEMP might be holding triggers that reference tables in the + ** other database. + */ + if( iDb!=1 ){ + pDb = &db->aDb[1]; + assert( pDb->pSchema!=0 ); + sqlite3SchemaClear(pDb->pSchema); + } + return; + } + /* Case 2 (from here to the end): Reset all schemas for all attached + ** databases. */ + assert( iDb<0 ); + sqlite3BtreeEnterAll(db); + for(i=0; inDb; i++){ + Db *pDb = &db->aDb[i]; + if( pDb->pSchema ){ + sqlite3SchemaClear(pDb->pSchema); + } + } + db->flags &= ~SQLITE_InternChanges; + sqlite3VtabUnlockList(db); + sqlite3BtreeLeaveAll(db); + + /* If one or more of the auxiliary database files has been closed, + ** then remove them from the auxiliary database list. We take the + ** opportunity to do this here since we have just deleted all of the + ** schema hash tables and therefore do not have to make any changes + ** to any of those tables. + */ + for(i=j=2; inDb; i++){ + struct Db *pDb = &db->aDb[i]; + if( pDb->pBt==0 ){ + sqlite3DbFree(db, pDb->zName); + pDb->zName = 0; + continue; + } + if( jaDb[j] = db->aDb[i]; + } + j++; + } + memset(&db->aDb[j], 0, (db->nDb-j)*sizeof(db->aDb[j])); + db->nDb = j; + if( db->nDb<=2 && db->aDb!=db->aDbStatic ){ + memcpy(db->aDbStatic, db->aDb, 2*sizeof(db->aDb[0])); + sqlite3DbFree(db, db->aDb); + db->aDb = db->aDbStatic; + } +} + +/* +** This routine is called when a commit occurs. +*/ +void sqlite3CommitInternalChanges(sqlite3 *db){ + db->flags &= ~SQLITE_InternChanges; +} + +/* +** Delete memory allocated for the column names of a table or view (the +** Table.aCol[] array). +*/ +static void sqliteDeleteColumnNames(sqlite3 *db, Table *pTable){ + int i; + Column *pCol; + assert( pTable!=0 ); + if( (pCol = pTable->aCol)!=0 ){ + for(i=0; inCol; i++, pCol++){ + sqlite3DbFree(db, pCol->zName); + sqlite3ExprDelete(db, pCol->pDflt); + sqlite3DbFree(db, pCol->zDflt); + sqlite3DbFree(db, pCol->zType); + sqlite3DbFree(db, pCol->zColl); + } + sqlite3DbFree(db, pTable->aCol); + } +} + +/* +** Remove the memory data structures associated with the given +** Table. No changes are made to disk by this routine. +** +** This routine just deletes the data structure. It does not unlink +** the table data structure from the hash table. But it does destroy +** memory structures of the indices and foreign keys associated with +** the table. +*/ +void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ + Index *pIndex, *pNext; + + assert( !pTable || pTable->nRef>0 ); + + /* Do not delete the table until the reference count reaches zero. */ + if( !pTable ) return; + if( ((!db || db->pnBytesFreed==0) && (--pTable->nRef)>0) ) return; + + /* Delete all indices associated with this table. */ + for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){ + pNext = pIndex->pNext; + assert( pIndex->pSchema==pTable->pSchema ); + if( !db || db->pnBytesFreed==0 ){ + char *zName = pIndex->zName; + TESTONLY ( Index *pOld = ) sqlite3HashInsert( + &pIndex->pSchema->idxHash, zName, sqlite3Strlen30(zName), 0 + ); + assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); + assert( pOld==pIndex || pOld==0 ); + } + freeIndex(db, pIndex); + } + + /* Delete any foreign keys attached to this table. */ + sqlite3FkDelete(db, pTable); + + /* Delete the Table structure itself. + */ + sqliteDeleteColumnNames(db, pTable); + sqlite3DbFree(db, pTable->zName); + sqlite3DbFree(db, pTable->zColAff); + sqlite3SelectDelete(db, pTable->pSelect); +#ifndef SQLITE_OMIT_CHECK + sqlite3ExprDelete(db, pTable->pCheck); +#endif +#ifndef SQLITE_OMIT_VIRTUALTABLE + sqlite3VtabClear(db, pTable); +#endif + sqlite3DbFree(db, pTable); +} + +/* +** Unlink the given table from the hash tables and the delete the +** table structure with all its indices and foreign keys. +*/ +void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){ + Table *p; + Db *pDb; + + assert( db!=0 ); + assert( iDb>=0 && iDbnDb ); + assert( zTabName ); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + testcase( zTabName[0]==0 ); /* Zero-length table names are allowed */ + pDb = &db->aDb[iDb]; + p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName, + sqlite3Strlen30(zTabName),0); + sqlite3DeleteTable(db, p); + db->flags |= SQLITE_InternChanges; +} + +/* +** Given a token, return a string that consists of the text of that +** token. Space to hold the returned string +** is obtained from sqliteMalloc() and must be freed by the calling +** function. +** +** Any quotation marks (ex: "name", 'name', [name], or `name`) that +** surround the body of the token are removed. +** +** Tokens are often just pointers into the original SQL text and so +** are not \000 terminated and are not persistent. The returned string +** is \000 terminated and is persistent. +*/ +char *sqlite3NameFromToken(sqlite3 *db, Token *pName){ + char *zName; + if( pName ){ + zName = sqlite3DbStrNDup(db, (char*)pName->z, pName->n); + sqlite3Dequote(zName); + }else{ + zName = 0; + } + return zName; +} + +/* +** Open the sqlite_master table stored in database number iDb for +** writing. The table is opened using cursor 0. +*/ +void sqlite3OpenMasterTable(Parse *p, int iDb){ + Vdbe *v = sqlite3GetVdbe(p); + sqlite3TableLock(p, iDb, MASTER_ROOT, 1, SCHEMA_TABLE(iDb)); + sqlite3VdbeAddOp3(v, OP_OpenWrite, 0, MASTER_ROOT, iDb); + sqlite3VdbeChangeP4(v, -1, (char *)5, P4_INT32); /* 5 column table */ + if( p->nTab==0 ){ + p->nTab = 1; + } +} + +/* +** Parameter zName points to a nul-terminated buffer containing the name +** of a database ("main", "temp" or the name of an attached db). This +** function returns the index of the named database in db->aDb[], or +** -1 if the named db cannot be found. +*/ +int sqlite3FindDbName(sqlite3 *db, const char *zName){ + int i = -1; /* Database number */ + if( zName ){ + Db *pDb; + int n = sqlite3Strlen30(zName); + for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){ + if( (!OMIT_TEMPDB || i!=1 ) && n==sqlite3Strlen30(pDb->zName) && + 0==sqlite3StrICmp(pDb->zName, zName) ){ + break; + } + } + } + return i; +} + +/* +** The token *pName contains the name of a database (either "main" or +** "temp" or the name of an attached db). This routine returns the +** index of the named database in db->aDb[], or -1 if the named db +** does not exist. +*/ +int sqlite3FindDb(sqlite3 *db, Token *pName){ + int i; /* Database number */ + char *zName; /* Name we are searching for */ + zName = sqlite3NameFromToken(db, pName); + i = sqlite3FindDbName(db, zName); + sqlite3DbFree(db, zName); + return i; +} + +/* The table or view or trigger name is passed to this routine via tokens +** pName1 and pName2. If the table name was fully qualified, for example: +** +** CREATE TABLE xxx.yyy (...); +** +** Then pName1 is set to "xxx" and pName2 "yyy". On the other hand if +** the table name is not fully qualified, i.e.: +** +** CREATE TABLE yyy(...); +** +** Then pName1 is set to "yyy" and pName2 is "". +** +** This routine sets the *ppUnqual pointer to point at the token (pName1 or +** pName2) that stores the unqualified table name. The index of the +** database "xxx" is returned. +*/ +int sqlite3TwoPartName( + Parse *pParse, /* Parsing and code generating context */ + Token *pName1, /* The "xxx" in the name "xxx.yyy" or "xxx" */ + Token *pName2, /* The "yyy" in the name "xxx.yyy" */ + Token **pUnqual /* Write the unqualified object name here */ +){ + int iDb; /* Database holding the object */ + sqlite3 *db = pParse->db; + + if( ALWAYS(pName2!=0) && pName2->n>0 ){ + if( db->init.busy ) { + sqlite3ErrorMsg(pParse, "corrupt database"); + pParse->nErr++; + return -1; + } + *pUnqual = pName2; + iDb = sqlite3FindDb(db, pName1); + if( iDb<0 ){ + sqlite3ErrorMsg(pParse, "unknown database %T", pName1); + pParse->nErr++; + return -1; + } + }else{ + assert( db->init.iDb==0 || db->init.busy ); + iDb = db->init.iDb; + *pUnqual = pName1; + } + return iDb; +} + +/* +** This routine is used to check if the UTF-8 string zName is a legal +** unqualified name for a new schema object (table, index, view or +** trigger). All names are legal except those that begin with the string +** "sqlite_" (in upper, lower or mixed case). This portion of the namespace +** is reserved for internal use. +*/ +int sqlite3CheckObjectName(Parse *pParse, const char *zName){ + if( !pParse->db->init.busy && pParse->nested==0 + && (pParse->db->flags & SQLITE_WriteSchema)==0 + && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){ + sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName); + return SQLITE_ERROR; + } + return SQLITE_OK; +} + +/* +** Begin constructing a new table representation in memory. This is +** the first of several action routines that get called in response +** to a CREATE TABLE statement. In particular, this routine is called +** after seeing tokens "CREATE" and "TABLE" and the table name. The isTemp +** flag is true if the table should be stored in the auxiliary database +** file instead of in the main database file. This is normally the case +** when the "TEMP" or "TEMPORARY" keyword occurs in between +** CREATE and TABLE. +** +** The new table record is initialized and put in pParse->pNewTable. +** As more of the CREATE TABLE statement is parsed, additional action +** routines will be called to add more information to this record. +** At the end of the CREATE TABLE statement, the sqlite3EndTable() routine +** is called to complete the construction of the new table record. +*/ +void sqlite3StartTable( + Parse *pParse, /* Parser context */ + Token *pName1, /* First part of the name of the table or view */ + Token *pName2, /* Second part of the name of the table or view */ + int isTemp, /* True if this is a TEMP table */ + int isView, /* True if this is a VIEW */ + int isVirtual, /* True if this is a VIRTUAL table */ + int noErr /* Do nothing if table already exists */ +){ + Table *pTable; + char *zName = 0; /* The name of the new table */ + sqlite3 *db = pParse->db; + Vdbe *v; + int iDb; /* Database number to create the table in */ + Token *pName; /* Unqualified name of the table to create */ + + /* The table or view name to create is passed to this routine via tokens + ** pName1 and pName2. If the table name was fully qualified, for example: + ** + ** CREATE TABLE xxx.yyy (...); + ** + ** Then pName1 is set to "xxx" and pName2 "yyy". On the other hand if + ** the table name is not fully qualified, i.e.: + ** + ** CREATE TABLE yyy(...); + ** + ** Then pName1 is set to "yyy" and pName2 is "". + ** + ** The call below sets the pName pointer to point at the token (pName1 or + ** pName2) that stores the unqualified table name. The variable iDb is + ** set to the index of the database that the table or view is to be + ** created in. + */ + iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName); + if( iDb<0 ) return; + if( !OMIT_TEMPDB && isTemp && pName2->n>0 && iDb!=1 ){ + /* If creating a temp table, the name may not be qualified. Unless + ** the database name is "temp" anyway. */ + sqlite3ErrorMsg(pParse, "temporary table name must be unqualified"); + return; + } + if( !OMIT_TEMPDB && isTemp ) iDb = 1; + + pParse->sNameToken = *pName; + zName = sqlite3NameFromToken(db, pName); + if( zName==0 ) return; + if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ + goto begin_table_error; + } + if( db->init.iDb==1 ) isTemp = 1; +#ifndef SQLITE_OMIT_AUTHORIZATION + assert( (isTemp & 1)==isTemp ); + { + int code; + char *zDb = db->aDb[iDb].zName; + if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){ + goto begin_table_error; + } + if( isView ){ + if( !OMIT_TEMPDB && isTemp ){ + code = SQLITE_CREATE_TEMP_VIEW; + }else{ + code = SQLITE_CREATE_VIEW; + } + }else{ + if( !OMIT_TEMPDB && isTemp ){ + code = SQLITE_CREATE_TEMP_TABLE; + }else{ + code = SQLITE_CREATE_TABLE; + } + } + if( !isVirtual && sqlite3AuthCheck(pParse, code, zName, 0, zDb) ){ + goto begin_table_error; + } + } +#endif + + /* Make sure the new table name does not collide with an existing + ** index or table name in the same database. Issue an error message if + ** it does. The exception is if the statement being parsed was passed + ** to an sqlite3_declare_vtab() call. In that case only the column names + ** and types will be used, so there is no need to test for namespace + ** collisions. + */ + if( !IN_DECLARE_VTAB ){ + char *zDb = db->aDb[iDb].zName; + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + goto begin_table_error; + } + pTable = sqlite3FindTable(db, zName, zDb); + if( pTable ){ + if( !noErr ){ + sqlite3ErrorMsg(pParse, "table %T already exists", pName); + }else{ + assert( !db->init.busy ); + sqlite3CodeVerifySchema(pParse, iDb); + } + goto begin_table_error; + } + if( sqlite3FindIndex(db, zName, zDb)!=0 ){ + sqlite3ErrorMsg(pParse, "there is already an index named %s", zName); + goto begin_table_error; + } + } + + pTable = sqlite3DbMallocZero(db, sizeof(Table)); + if( pTable==0 ){ + db->mallocFailed = 1; + pParse->rc = SQLITE_NOMEM; + pParse->nErr++; + goto begin_table_error; + } + pTable->zName = zName; + pTable->iPKey = -1; + pTable->pSchema = db->aDb[iDb].pSchema; + pTable->nRef = 1; + pTable->nRowEst = 1000000; + assert( pParse->pNewTable==0 ); + pParse->pNewTable = pTable; + + /* If this is the magic sqlite_sequence table used by autoincrement, + ** then record a pointer to this table in the main database structure + ** so that INSERT can find the table easily. + */ +#ifndef SQLITE_OMIT_AUTOINCREMENT + if( !pParse->nested && strcmp(zName, "sqlite_sequence")==0 ){ + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + pTable->pSchema->pSeqTab = pTable; + } +#endif + + /* Begin generating the code that will insert the table record into + ** the SQLITE_MASTER table. Note in particular that we must go ahead + ** and allocate the record number for the table entry now. Before any + ** PRIMARY KEY or UNIQUE keywords are parsed. Those keywords will cause + ** indices to be created and the table record must come before the + ** indices. Hence, the record number for the table must be allocated + ** now. + */ + if( !db->init.busy && (v = sqlite3GetVdbe(pParse))!=0 ){ + int j1; + int fileFormat; + int reg1, reg2, reg3; + sqlite3BeginWriteOperation(pParse, 0, iDb); + +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( isVirtual ){ + sqlite3VdbeAddOp0(v, OP_VBegin); + } +#endif + + /* If the file format and encoding in the database have not been set, + ** set them now. + */ + reg1 = pParse->regRowid = ++pParse->nMem; + reg2 = pParse->regRoot = ++pParse->nMem; + reg3 = ++pParse->nMem; + sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, BTREE_FILE_FORMAT); + sqlite3VdbeUsesBtree(v, iDb); + j1 = sqlite3VdbeAddOp1(v, OP_If, reg3); + fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ? + 1 : SQLITE_MAX_FILE_FORMAT; + sqlite3VdbeAddOp2(v, OP_Integer, fileFormat, reg3); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, reg3); + sqlite3VdbeAddOp2(v, OP_Integer, ENC(db), reg3); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_TEXT_ENCODING, reg3); + sqlite3VdbeJumpHere(v, j1); + + /* This just creates a place-holder record in the sqlite_master table. + ** The record created does not contain anything yet. It will be replaced + ** by the real entry in code generated at sqlite3EndTable(). + ** + ** The rowid for the new entry is left in register pParse->regRowid. + ** The root page number of the new table is left in reg pParse->regRoot. + ** The rowid and root page number values are needed by the code that + ** sqlite3EndTable will generate. + */ +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) + if( isView || isVirtual ){ + sqlite3VdbeAddOp2(v, OP_Integer, 0, reg2); + }else +#endif + { + sqlite3VdbeAddOp2(v, OP_CreateTable, iDb, reg2); + } + sqlite3OpenMasterTable(pParse, iDb); + sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1); + sqlite3VdbeAddOp2(v, OP_Null, 0, reg3); + sqlite3VdbeAddOp3(v, OP_Insert, 0, reg3, reg1); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); + sqlite3VdbeAddOp0(v, OP_Close); + } + + /* Normal (non-error) return. */ + return; + + /* If an error occurs, we jump here */ +begin_table_error: + sqlite3DbFree(db, zName); + return; +} + +/* +** This macro is used to compare two strings in a case-insensitive manner. +** It is slightly faster than calling sqlite3StrICmp() directly, but +** produces larger code. +** +** WARNING: This macro is not compatible with the strcmp() family. It +** returns true if the two strings are equal, otherwise false. +*/ +#define STRICMP(x, y) (\ +sqlite3UpperToLower[*(unsigned char *)(x)]== \ +sqlite3UpperToLower[*(unsigned char *)(y)] \ +&& sqlite3StrICmp((x)+1,(y)+1)==0 ) + +/* +** Add a new column to the table currently being constructed. +** +** The parser calls this routine once for each column declaration +** in a CREATE TABLE statement. sqlite3StartTable() gets called +** first to get things going. Then this routine is called for each +** column. +*/ +void sqlite3AddColumn(Parse *pParse, Token *pName){ + Table *p; + int i; + char *z; + Column *pCol; + sqlite3 *db = pParse->db; + if( (p = pParse->pNewTable)==0 ) return; +#if SQLITE_MAX_COLUMN + if( p->nCol+1>db->aLimit[SQLITE_LIMIT_COLUMN] ){ + sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName); + return; + } +#endif + z = sqlite3NameFromToken(db, pName); + if( z==0 ) return; + for(i=0; inCol; i++){ + if( STRICMP(z, p->aCol[i].zName) ){ + sqlite3ErrorMsg(pParse, "duplicate column name: %s", z); + sqlite3DbFree(db, z); + return; + } + } + if( (p->nCol & 0x7)==0 ){ + Column *aNew; + aNew = sqlite3DbRealloc(db,p->aCol,(p->nCol+8)*sizeof(p->aCol[0])); + if( aNew==0 ){ + sqlite3DbFree(db, z); + return; + } + p->aCol = aNew; + } + pCol = &p->aCol[p->nCol]; + memset(pCol, 0, sizeof(p->aCol[0])); + pCol->zName = z; + + /* If there is no type specified, columns have the default affinity + ** 'NONE'. If there is a type specified, then sqlite3AddColumnType() will + ** be called next to set pCol->affinity correctly. + */ + pCol->affinity = SQLITE_AFF_NONE; + p->nCol++; +} + +/* +** This routine is called by the parser while in the middle of +** parsing a CREATE TABLE statement. A "NOT NULL" constraint has +** been seen on a column. This routine sets the notNull flag on +** the column currently under construction. +*/ +void sqlite3AddNotNull(Parse *pParse, int onError){ + Table *p; + p = pParse->pNewTable; + if( p==0 || NEVER(p->nCol<1) ) return; + p->aCol[p->nCol-1].notNull = (u8)onError; +} + +/* +** Scan the column type name zType (length nType) and return the +** associated affinity type. +** +** This routine does a case-independent search of zType for the +** substrings in the following table. If one of the substrings is +** found, the corresponding affinity is returned. If zType contains +** more than one of the substrings, entries toward the top of +** the table take priority. For example, if zType is 'BLOBINT', +** SQLITE_AFF_INTEGER is returned. +** +** Substring | Affinity +** -------------------------------- +** 'INT' | SQLITE_AFF_INTEGER +** 'CHAR' | SQLITE_AFF_TEXT +** 'CLOB' | SQLITE_AFF_TEXT +** 'TEXT' | SQLITE_AFF_TEXT +** 'BLOB' | SQLITE_AFF_NONE +** 'REAL' | SQLITE_AFF_REAL +** 'FLOA' | SQLITE_AFF_REAL +** 'DOUB' | SQLITE_AFF_REAL +** +** If none of the substrings in the above table are found, +** SQLITE_AFF_NUMERIC is returned. +*/ +char sqlite3AffinityType(const char *zIn){ + u32 h = 0; + char aff = SQLITE_AFF_NUMERIC; + + if( zIn ) while( zIn[0] ){ + h = (h<<8) + sqlite3UpperToLower[(*zIn)&0xff]; + zIn++; + if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){ /* CHAR */ + aff = SQLITE_AFF_TEXT; + }else if( h==(('c'<<24)+('l'<<16)+('o'<<8)+'b') ){ /* CLOB */ + aff = SQLITE_AFF_TEXT; + }else if( h==(('t'<<24)+('e'<<16)+('x'<<8)+'t') ){ /* TEXT */ + aff = SQLITE_AFF_TEXT; + }else if( h==(('b'<<24)+('l'<<16)+('o'<<8)+'b') /* BLOB */ + && (aff==SQLITE_AFF_NUMERIC || aff==SQLITE_AFF_REAL) ){ + aff = SQLITE_AFF_NONE; +#ifndef SQLITE_OMIT_FLOATING_POINT + }else if( h==(('r'<<24)+('e'<<16)+('a'<<8)+'l') /* REAL */ + && aff==SQLITE_AFF_NUMERIC ){ + aff = SQLITE_AFF_REAL; + }else if( h==(('f'<<24)+('l'<<16)+('o'<<8)+'a') /* FLOA */ + && aff==SQLITE_AFF_NUMERIC ){ + aff = SQLITE_AFF_REAL; + }else if( h==(('d'<<24)+('o'<<16)+('u'<<8)+'b') /* DOUB */ + && aff==SQLITE_AFF_NUMERIC ){ + aff = SQLITE_AFF_REAL; +#endif + }else if( (h&0x00FFFFFF)==(('i'<<16)+('n'<<8)+'t') ){ /* INT */ + aff = SQLITE_AFF_INTEGER; + break; + } + } + + return aff; +} + +/* +** This routine is called by the parser while in the middle of +** parsing a CREATE TABLE statement. The pFirst token is the first +** token in the sequence of tokens that describe the type of the +** column currently under construction. pLast is the last token +** in the sequence. Use this information to construct a string +** that contains the typename of the column and store that string +** in zType. +*/ +void sqlite3AddColumnType(Parse *pParse, Token *pType){ + Table *p; + Column *pCol; + + p = pParse->pNewTable; + if( p==0 || NEVER(p->nCol<1) ) return; + pCol = &p->aCol[p->nCol-1]; + assert( pCol->zType==0 ); + pCol->zType = sqlite3NameFromToken(pParse->db, pType); + pCol->affinity = sqlite3AffinityType(pCol->zType); +} + +/* +** The expression is the default value for the most recently added column +** of the table currently under construction. +** +** Default value expressions must be constant. Raise an exception if this +** is not the case. +** +** This routine is called by the parser while in the middle of +** parsing a CREATE TABLE statement. +*/ +void sqlite3AddDefaultValue(Parse *pParse, ExprSpan *pSpan){ + Table *p; + Column *pCol; + sqlite3 *db = pParse->db; + p = pParse->pNewTable; + if( p!=0 ){ + pCol = &(p->aCol[p->nCol-1]); + if( !sqlite3ExprIsConstantOrFunction(pSpan->pExpr) ){ + sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant", + pCol->zName); + }else{ + /* A copy of pExpr is used instead of the original, as pExpr contains + ** tokens that point to volatile memory. The 'span' of the expression + ** is required by pragma table_info. + */ + sqlite3ExprDelete(db, pCol->pDflt); + pCol->pDflt = sqlite3ExprDup(db, pSpan->pExpr, EXPRDUP_REDUCE); + sqlite3DbFree(db, pCol->zDflt); + pCol->zDflt = sqlite3DbStrNDup(db, (char*)pSpan->zStart, + (int)(pSpan->zEnd - pSpan->zStart)); + } + } + sqlite3ExprDelete(db, pSpan->pExpr); +} + +/* +** Designate the PRIMARY KEY for the table. pList is a list of names +** of columns that form the primary key. If pList is NULL, then the +** most recently added column of the table is the primary key. +** +** A table can have at most one primary key. If the table already has +** a primary key (and this is the second primary key) then create an +** error. +** +** If the PRIMARY KEY is on a single column whose datatype is INTEGER, +** then we will try to use that column as the rowid. Set the Table.iPKey +** field of the table under construction to be the index of the +** INTEGER PRIMARY KEY column. Table.iPKey is set to -1 if there is +** no INTEGER PRIMARY KEY. +** +** If the key is not an INTEGER PRIMARY KEY, then create a unique +** index for the key. No index is created for INTEGER PRIMARY KEYs. +*/ +void sqlite3AddPrimaryKey( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* List of field names to be indexed */ + int onError, /* What to do with a uniqueness conflict */ + int autoInc, /* True if the AUTOINCREMENT keyword is present */ + int sortOrder /* SQLITE_SO_ASC or SQLITE_SO_DESC */ +){ + Table *pTab = pParse->pNewTable; + char *zType = 0; + int iCol = -1, i; + if( pTab==0 || IN_DECLARE_VTAB ) goto primary_key_exit; + if( pTab->tabFlags & TF_HasPrimaryKey ){ + sqlite3ErrorMsg(pParse, + "table \"%s\" has more than one primary key", pTab->zName); + goto primary_key_exit; + } + pTab->tabFlags |= TF_HasPrimaryKey; + if( pList==0 ){ + iCol = pTab->nCol - 1; + pTab->aCol[iCol].isPrimKey = 1; + }else{ + for(i=0; inExpr; i++){ + for(iCol=0; iColnCol; iCol++){ + if( sqlite3StrICmp(pList->a[i].zName, pTab->aCol[iCol].zName)==0 ){ + break; + } + } + if( iColnCol ){ + pTab->aCol[iCol].isPrimKey = 1; + } + } + if( pList->nExpr>1 ) iCol = -1; + } + if( iCol>=0 && iColnCol ){ + zType = pTab->aCol[iCol].zType; + } + if( zType && sqlite3StrICmp(zType, "INTEGER")==0 + && sortOrder==SQLITE_SO_ASC ){ + pTab->iPKey = iCol; + pTab->keyConf = (u8)onError; + assert( autoInc==0 || autoInc==1 ); + pTab->tabFlags |= autoInc*TF_Autoincrement; + }else if( autoInc ){ +#ifndef SQLITE_OMIT_AUTOINCREMENT + sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an " + "INTEGER PRIMARY KEY"); +#endif + }else{ + Index *p; + p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder, 0); + if( p ){ + p->autoIndex = 2; + } + pList = 0; + } + +primary_key_exit: + sqlite3ExprListDelete(pParse->db, pList); + return; +} + +/* +** Add a new CHECK constraint to the table currently under construction. +*/ +void sqlite3AddCheckConstraint( + Parse *pParse, /* Parsing context */ + Expr *pCheckExpr /* The check expression */ +){ + sqlite3 *db = pParse->db; +#ifndef SQLITE_OMIT_CHECK + Table *pTab = pParse->pNewTable; + if( pTab && !IN_DECLARE_VTAB ){ + pTab->pCheck = sqlite3ExprAnd(db, pTab->pCheck, pCheckExpr); + }else +#endif + { + sqlite3ExprDelete(db, pCheckExpr); + } +} + +/* +** Set the collation function of the most recently parsed table column +** to the CollSeq given. +*/ +void sqlite3AddCollateType(Parse *pParse, Token *pToken){ + Table *p; + int i; + char *zColl; /* Dequoted name of collation sequence */ + sqlite3 *db; + + if( (p = pParse->pNewTable)==0 ) return; + i = p->nCol-1; + db = pParse->db; + zColl = sqlite3NameFromToken(db, pToken); + if( !zColl ) return; + + if( sqlite3LocateCollSeq(pParse, zColl) ){ + Index *pIdx; + p->aCol[i].zColl = zColl; + + /* If the column is declared as " PRIMARY KEY COLLATE ", + ** then an index may have been created on this column before the + ** collation type was added. Correct this if it is the case. + */ + for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){ + assert( pIdx->nColumn==1 ); + if( pIdx->aiColumn[0]==i ){ + pIdx->azColl[0] = p->aCol[i].zColl; + } + } + }else{ + sqlite3DbFree(db, zColl); + } +} + +/* +** This function returns the collation sequence for database native text +** encoding identified by the string zName, length nName. +** +** If the requested collation sequence is not available, or not available +** in the database native encoding, the collation factory is invoked to +** request it. If the collation factory does not supply such a sequence, +** and the sequence is available in another text encoding, then that is +** returned instead. +** +** If no versions of the requested collations sequence are available, or +** another error occurs, NULL is returned and an error message written into +** pParse. +** +** This routine is a wrapper around sqlite3FindCollSeq(). This routine +** invokes the collation factory if the named collation cannot be found +** and generates an error message. +** +** See also: sqlite3FindCollSeq(), sqlite3GetCollSeq() +*/ +CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){ + sqlite3 *db = pParse->db; + u8 enc = ENC(db); + u8 initbusy = db->init.busy; + CollSeq *pColl; + + pColl = sqlite3FindCollSeq(db, enc, zName, initbusy); + if( !initbusy && (!pColl || !pColl->xCmp) ){ + pColl = sqlite3GetCollSeq(db, enc, pColl, zName); + if( !pColl ){ + sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); + } + } + + return pColl; +} + + +/* +** Generate code that will increment the schema cookie. +** +** The schema cookie is used to determine when the schema for the +** database changes. After each schema change, the cookie value +** changes. When a process first reads the schema it records the +** cookie. Thereafter, whenever it goes to access the database, +** it checks the cookie to make sure the schema has not changed +** since it was last read. +** +** This plan is not completely bullet-proof. It is possible for +** the schema to change multiple times and for the cookie to be +** set back to prior value. But schema changes are infrequent +** and the probability of hitting the same cookie value is only +** 1 chance in 2^32. So we're safe enough. +*/ +void sqlite3ChangeCookie(Parse *pParse, int iDb){ + int r1 = sqlite3GetTempReg(pParse); + sqlite3 *db = pParse->db; + Vdbe *v = pParse->pVdbe; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + sqlite3VdbeAddOp2(v, OP_Integer, db->aDb[iDb].pSchema->schema_cookie+1, r1); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_SCHEMA_VERSION, r1); + sqlite3ReleaseTempReg(pParse, r1); +} + +/* +** Measure the number of characters needed to output the given +** identifier. The number returned includes any quotes used +** but does not include the null terminator. +** +** The estimate is conservative. It might be larger that what is +** really needed. +*/ +static int identLength(const char *z){ + int n; + for(n=0; *z; n++, z++){ + if( *z=='"' ){ n++; } + } + return n + 2; +} + +/* +** The first parameter is a pointer to an output buffer. The second +** parameter is a pointer to an integer that contains the offset at +** which to write into the output buffer. This function copies the +** nul-terminated string pointed to by the third parameter, zSignedIdent, +** to the specified offset in the buffer and updates *pIdx to refer +** to the first byte after the last byte written before returning. +** +** If the string zSignedIdent consists entirely of alpha-numeric +** characters, does not begin with a digit and is not an SQL keyword, +** then it is copied to the output buffer exactly as it is. Otherwise, +** it is quoted using double-quotes. +*/ +static void identPut(char *z, int *pIdx, char *zSignedIdent){ + unsigned char *zIdent = (unsigned char*)zSignedIdent; + int i, j, needQuote; + i = *pIdx; + + for(j=0; zIdent[j]; j++){ + if( !sqlite3Isalnum(zIdent[j]) && zIdent[j]!='_' ) break; + } + needQuote = sqlite3Isdigit(zIdent[0]) || sqlite3KeywordCode(zIdent, j)!=TK_ID; + if( !needQuote ){ + needQuote = zIdent[j]; + } + + if( needQuote ) z[i++] = '"'; + for(j=0; zIdent[j]; j++){ + z[i++] = zIdent[j]; + if( zIdent[j]=='"' ) z[i++] = '"'; + } + if( needQuote ) z[i++] = '"'; + z[i] = 0; + *pIdx = i; +} + +/* +** Generate a CREATE TABLE statement appropriate for the given +** table. Memory to hold the text of the statement is obtained +** from sqliteMalloc() and must be freed by the calling function. +*/ +static char *createTableStmt(sqlite3 *db, Table *p){ + int i, k, n; + char *zStmt; + char *zSep, *zSep2, *zEnd; + Column *pCol; + n = 0; + for(pCol = p->aCol, i=0; inCol; i++, pCol++){ + n += identLength(pCol->zName) + 5; + } + n += identLength(p->zName); + if( n<50 ){ + zSep = ""; + zSep2 = ","; + zEnd = ")"; + }else{ + zSep = "\n "; + zSep2 = ",\n "; + zEnd = "\n)"; + } + n += 35 + 6*p->nCol; + zStmt = sqlite3DbMallocRaw(0, n); + if( zStmt==0 ){ + db->mallocFailed = 1; + return 0; + } + sqlite3_snprintf(n, zStmt, "CREATE TABLE "); + k = sqlite3Strlen30(zStmt); + identPut(zStmt, &k, p->zName); + zStmt[k++] = '('; + for(pCol=p->aCol, i=0; inCol; i++, pCol++){ + static const char * const azType[] = { + /* SQLITE_AFF_TEXT */ " TEXT", + /* SQLITE_AFF_NONE */ "", + /* SQLITE_AFF_NUMERIC */ " NUM", + /* SQLITE_AFF_INTEGER */ " INT", + /* SQLITE_AFF_REAL */ " REAL" + }; + int len; + const char *zType; + + sqlite3_snprintf(n-k, &zStmt[k], zSep); + k += sqlite3Strlen30(&zStmt[k]); + zSep = zSep2; + identPut(zStmt, &k, pCol->zName); + assert( pCol->affinity-SQLITE_AFF_TEXT >= 0 ); + assert( pCol->affinity-SQLITE_AFF_TEXT < ArraySize(azType) ); + testcase( pCol->affinity==SQLITE_AFF_TEXT ); + testcase( pCol->affinity==SQLITE_AFF_NONE ); + testcase( pCol->affinity==SQLITE_AFF_NUMERIC ); + testcase( pCol->affinity==SQLITE_AFF_INTEGER ); + testcase( pCol->affinity==SQLITE_AFF_REAL ); + + zType = azType[pCol->affinity - SQLITE_AFF_TEXT]; + len = sqlite3Strlen30(zType); + assert( pCol->affinity==SQLITE_AFF_NONE + || pCol->affinity==sqlite3AffinityType(zType) ); + memcpy(&zStmt[k], zType, len); + k += len; + assert( k<=n ); + } + sqlite3_snprintf(n-k, &zStmt[k], "%s", zEnd); + return zStmt; +} + +/* +** This routine is called to report the final ")" that terminates +** a CREATE TABLE statement. +** +** The table structure that other action routines have been building +** is added to the internal hash tables, assuming no errors have +** occurred. +** +** An entry for the table is made in the master table on disk, unless +** this is a temporary table or db->init.busy==1. When db->init.busy==1 +** it means we are reading the sqlite_master table because we just +** connected to the database or because the sqlite_master table has +** recently changed, so the entry for this table already exists in +** the sqlite_master table. We do not want to create it again. +** +** If the pSelect argument is not NULL, it means that this routine +** was called to create a table generated from a +** "CREATE TABLE ... AS SELECT ..." statement. The column names of +** the new table will match the result set of the SELECT. +*/ +void sqlite3EndTable( + Parse *pParse, /* Parse context */ + Token *pCons, /* The ',' token after the last column defn. */ + Token *pEnd, /* The final ')' token in the CREATE TABLE */ + Select *pSelect /* Select from a "CREATE ... AS SELECT" */ +){ + Table *p; + sqlite3 *db = pParse->db; + int iDb; + + if( (pEnd==0 && pSelect==0) || db->mallocFailed ){ + return; + } + p = pParse->pNewTable; + if( p==0 ) return; + + assert( !db->init.busy || !pSelect ); + + iDb = sqlite3SchemaToIndex(db, p->pSchema); + +#ifndef SQLITE_OMIT_CHECK + /* Resolve names in all CHECK constraint expressions. + */ + if( p->pCheck ){ + SrcList sSrc; /* Fake SrcList for pParse->pNewTable */ + NameContext sNC; /* Name context for pParse->pNewTable */ + + memset(&sNC, 0, sizeof(sNC)); + memset(&sSrc, 0, sizeof(sSrc)); + sSrc.nSrc = 1; + sSrc.a[0].zName = p->zName; + sSrc.a[0].pTab = p; + sSrc.a[0].iCursor = -1; + sNC.pParse = pParse; + sNC.pSrcList = &sSrc; + sNC.isCheck = 1; + if( sqlite3ResolveExprNames(&sNC, p->pCheck) ){ + return; + } + } +#endif /* !defined(SQLITE_OMIT_CHECK) */ + + /* If the db->init.busy is 1 it means we are reading the SQL off the + ** "sqlite_master" or "sqlite_temp_master" table on the disk. + ** So do not write to the disk again. Extract the root page number + ** for the table from the db->init.newTnum field. (The page number + ** should have been put there by the sqliteOpenCb routine.) + */ + if( db->init.busy ){ + p->tnum = db->init.newTnum; + } + + /* If not initializing, then create a record for the new table + ** in the SQLITE_MASTER table of the database. + ** + ** If this is a TEMPORARY table, write the entry into the auxiliary + ** file instead of into the main database file. + */ + if( !db->init.busy ){ + int n; + Vdbe *v; + char *zType; /* "view" or "table" */ + char *zType2; /* "VIEW" or "TABLE" */ + char *zStmt; /* Text of the CREATE TABLE or CREATE VIEW statement */ + + v = sqlite3GetVdbe(pParse); + if( NEVER(v==0) ) return; + + sqlite3VdbeAddOp1(v, OP_Close, 0); + + /* + ** Initialize zType for the new view or table. + */ + if( p->pSelect==0 ){ + /* A regular table */ + zType = "table"; + zType2 = "TABLE"; +#ifndef SQLITE_OMIT_VIEW + }else{ + /* A view */ + zType = "view"; + zType2 = "VIEW"; +#endif + } + + /* If this is a CREATE TABLE xx AS SELECT ..., execute the SELECT + ** statement to populate the new table. The root-page number for the + ** new table is in register pParse->regRoot. + ** + ** Once the SELECT has been coded by sqlite3Select(), it is in a + ** suitable state to query for the column names and types to be used + ** by the new table. + ** + ** A shared-cache write-lock is not required to write to the new table, + ** as a schema-lock must have already been obtained to create it. Since + ** a schema-lock excludes all other database users, the write-lock would + ** be redundant. + */ + if( pSelect ){ + SelectDest dest; + Table *pSelTab; + + assert(pParse->nTab==1); + sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb); + sqlite3VdbeChangeP5(v, 1); + pParse->nTab = 2; + sqlite3SelectDestInit(&dest, SRT_Table, 1); + sqlite3Select(pParse, pSelect, &dest); + sqlite3VdbeAddOp1(v, OP_Close, 1); + if( pParse->nErr==0 ){ + pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect); + if( pSelTab==0 ) return; + assert( p->aCol==0 ); + p->nCol = pSelTab->nCol; + p->aCol = pSelTab->aCol; + pSelTab->nCol = 0; + pSelTab->aCol = 0; + sqlite3DeleteTable(db, pSelTab); + } + } + + /* Compute the complete text of the CREATE statement */ + if( pSelect ){ + zStmt = createTableStmt(db, p); + }else{ + n = (int)(pEnd->z - pParse->sNameToken.z) + 1; + zStmt = sqlite3MPrintf(db, + "CREATE %s %.*s", zType2, n, pParse->sNameToken.z + ); + } + + /* A slot for the record has already been allocated in the + ** SQLITE_MASTER table. We just need to update that slot with all + ** the information we've collected. + */ + sqlite3NestedParse(pParse, + "UPDATE %Q.%s " + "SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q " + "WHERE rowid=#%d", + db->aDb[iDb].zName, SCHEMA_TABLE(iDb), + zType, + p->zName, + p->zName, + pParse->regRoot, + zStmt, + pParse->regRowid + ); + sqlite3DbFree(db, zStmt); + sqlite3ChangeCookie(pParse, iDb); + +#ifndef SQLITE_OMIT_AUTOINCREMENT + /* Check to see if we need to create an sqlite_sequence table for + ** keeping track of autoincrement keys. + */ + if( p->tabFlags & TF_Autoincrement ){ + Db *pDb = &db->aDb[iDb]; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + if( pDb->pSchema->pSeqTab==0 ){ + sqlite3NestedParse(pParse, + "CREATE TABLE %Q.sqlite_sequence(name,seq)", + pDb->zName + ); + } + } +#endif + + /* Reparse everything to update our internal data structures */ + sqlite3VdbeAddParseSchemaOp(v, iDb, + sqlite3MPrintf(db, "tbl_name='%q'", p->zName)); + } + + + /* Add the table to the in-memory representation of the database. + */ + if( db->init.busy ){ + Table *pOld; + Schema *pSchema = p->pSchema; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, + sqlite3Strlen30(p->zName),p); + if( pOld ){ + assert( p==pOld ); /* Malloc must have failed inside HashInsert() */ + db->mallocFailed = 1; + return; + } + pParse->pNewTable = 0; + db->nTable++; + db->flags |= SQLITE_InternChanges; + +#ifndef SQLITE_OMIT_ALTERTABLE + if( !p->pSelect ){ + const char *zName = (const char *)pParse->sNameToken.z; + int nName; + assert( !pSelect && pCons && pEnd ); + if( pCons->z==0 ){ + pCons = pEnd; + } + nName = (int)((const char *)pCons->z - zName); + p->addColOffset = 13 + sqlite3Utf8CharLen(zName, nName); + } +#endif + } +} + +#ifndef SQLITE_OMIT_VIEW +/* +** The parser calls this routine in order to create a new VIEW +*/ +void sqlite3CreateView( + Parse *pParse, /* The parsing context */ + Token *pBegin, /* The CREATE token that begins the statement */ + Token *pName1, /* The token that holds the name of the view */ + Token *pName2, /* The token that holds the name of the view */ + Select *pSelect, /* A SELECT statement that will become the new view */ + int isTemp, /* TRUE for a TEMPORARY view */ + int noErr /* Suppress error messages if VIEW already exists */ +){ + Table *p; + int n; + const char *z; + Token sEnd; + DbFixer sFix; + Token *pName = 0; + int iDb; + sqlite3 *db = pParse->db; + + if( pParse->nVar>0 ){ + sqlite3ErrorMsg(pParse, "parameters are not allowed in views"); + sqlite3SelectDelete(db, pSelect); + return; + } + sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr); + p = pParse->pNewTable; + if( p==0 || pParse->nErr ){ + sqlite3SelectDelete(db, pSelect); + return; + } + sqlite3TwoPartName(pParse, pName1, pName2, &pName); + iDb = sqlite3SchemaToIndex(db, p->pSchema); + if( sqlite3FixInit(&sFix, pParse, iDb, "view", pName) + && sqlite3FixSelect(&sFix, pSelect) + ){ + sqlite3SelectDelete(db, pSelect); + return; + } + + /* Make a copy of the entire SELECT statement that defines the view. + ** This will force all the Expr.token.z values to be dynamically + ** allocated rather than point to the input string - which means that + ** they will persist after the current sqlite3_exec() call returns. + */ + p->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); + sqlite3SelectDelete(db, pSelect); + if( db->mallocFailed ){ + return; + } + if( !db->init.busy ){ + sqlite3ViewGetColumnNames(pParse, p); + } + + /* Locate the end of the CREATE VIEW statement. Make sEnd point to + ** the end. + */ + sEnd = pParse->sLastToken; + if( ALWAYS(sEnd.z[0]!=0) && sEnd.z[0]!=';' ){ + sEnd.z += sEnd.n; + } + sEnd.n = 0; + n = (int)(sEnd.z - pBegin->z); + z = pBegin->z; + while( ALWAYS(n>0) && sqlite3Isspace(z[n-1]) ){ n--; } + sEnd.z = &z[n-1]; + sEnd.n = 1; + + /* Use sqlite3EndTable() to add the view to the SQLITE_MASTER table */ + sqlite3EndTable(pParse, 0, &sEnd, 0); + return; +} +#endif /* SQLITE_OMIT_VIEW */ + +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) +/* +** The Table structure pTable is really a VIEW. Fill in the names of +** the columns of the view in the pTable structure. Return the number +** of errors. If an error is seen leave an error message in pParse->zErrMsg. +*/ +int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ + Table *pSelTab; /* A fake table from which we get the result set */ + Select *pSel; /* Copy of the SELECT that implements the view */ + int nErr = 0; /* Number of errors encountered */ + int n; /* Temporarily holds the number of cursors assigned */ + sqlite3 *db = pParse->db; /* Database connection for malloc errors */ + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*); + + assert( pTable ); + +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( sqlite3VtabCallConnect(pParse, pTable) ){ + return SQLITE_ERROR; + } + if( IsVirtual(pTable) ) return 0; +#endif + +#ifndef SQLITE_OMIT_VIEW + /* A positive nCol means the columns names for this view are + ** already known. + */ + if( pTable->nCol>0 ) return 0; + + /* A negative nCol is a special marker meaning that we are currently + ** trying to compute the column names. If we enter this routine with + ** a negative nCol, it means two or more views form a loop, like this: + ** + ** CREATE VIEW one AS SELECT * FROM two; + ** CREATE VIEW two AS SELECT * FROM one; + ** + ** Actually, the error above is now caught prior to reaching this point. + ** But the following test is still important as it does come up + ** in the following: + ** + ** CREATE TABLE main.ex1(a); + ** CREATE TEMP VIEW ex1 AS SELECT a FROM ex1; + ** SELECT * FROM temp.ex1; + */ + if( pTable->nCol<0 ){ + sqlite3ErrorMsg(pParse, "view %s is circularly defined", pTable->zName); + return 1; + } + assert( pTable->nCol>=0 ); + + /* If we get this far, it means we need to compute the table names. + ** Note that the call to sqlite3ResultSetOfSelect() will expand any + ** "*" elements in the results set of the view and will assign cursors + ** to the elements of the FROM clause. But we do not want these changes + ** to be permanent. So the computation is done on a copy of the SELECT + ** statement that defines the view. + */ + assert( pTable->pSelect ); + pSel = sqlite3SelectDup(db, pTable->pSelect, 0); + if( pSel ){ + u8 enableLookaside = db->lookaside.bEnabled; + n = pParse->nTab; + sqlite3SrcListAssignCursors(pParse, pSel->pSrc); + pTable->nCol = -1; + db->lookaside.bEnabled = 0; +#ifndef SQLITE_OMIT_AUTHORIZATION + xAuth = db->xAuth; + db->xAuth = 0; + pSelTab = sqlite3ResultSetOfSelect(pParse, pSel); + db->xAuth = xAuth; +#else + pSelTab = sqlite3ResultSetOfSelect(pParse, pSel); +#endif + db->lookaside.bEnabled = enableLookaside; + pParse->nTab = n; + if( pSelTab ){ + assert( pTable->aCol==0 ); + pTable->nCol = pSelTab->nCol; + pTable->aCol = pSelTab->aCol; + pSelTab->nCol = 0; + pSelTab->aCol = 0; + sqlite3DeleteTable(db, pSelTab); + assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) ); + pTable->pSchema->flags |= DB_UnresetViews; + }else{ + pTable->nCol = 0; + nErr++; + } + sqlite3SelectDelete(db, pSel); + } else { + nErr++; + } +#endif /* SQLITE_OMIT_VIEW */ + return nErr; +} +#endif /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */ + +#ifndef SQLITE_OMIT_VIEW +/* +** Clear the column names from every VIEW in database idx. +*/ +static void sqliteViewResetAll(sqlite3 *db, int idx){ + HashElem *i; + assert( sqlite3SchemaMutexHeld(db, idx, 0) ); + if( !DbHasProperty(db, idx, DB_UnresetViews) ) return; + for(i=sqliteHashFirst(&db->aDb[idx].pSchema->tblHash); i;i=sqliteHashNext(i)){ + Table *pTab = sqliteHashData(i); + if( pTab->pSelect ){ + sqliteDeleteColumnNames(db, pTab); + pTab->aCol = 0; + pTab->nCol = 0; + } + } + DbClearProperty(db, idx, DB_UnresetViews); +} +#else +# define sqliteViewResetAll(A,B) +#endif /* SQLITE_OMIT_VIEW */ + +/* +** This function is called by the VDBE to adjust the internal schema +** used by SQLite when the btree layer moves a table root page. The +** root-page of a table or index in database iDb has changed from iFrom +** to iTo. +** +** Ticket #1728: The symbol table might still contain information +** on tables and/or indices that are the process of being deleted. +** If you are unlucky, one of those deleted indices or tables might +** have the same rootpage number as the real table or index that is +** being moved. So we cannot stop searching after the first match +** because the first match might be for one of the deleted indices +** or tables and not the table/index that is actually being moved. +** We must continue looping until all tables and indices with +** rootpage==iFrom have been converted to have a rootpage of iTo +** in order to be certain that we got the right one. +*/ +#ifndef SQLITE_OMIT_AUTOVACUUM +void sqlite3RootPageMoved(sqlite3 *db, int iDb, int iFrom, int iTo){ + HashElem *pElem; + Hash *pHash; + Db *pDb; + + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + pDb = &db->aDb[iDb]; + pHash = &pDb->pSchema->tblHash; + for(pElem=sqliteHashFirst(pHash); pElem; pElem=sqliteHashNext(pElem)){ + Table *pTab = sqliteHashData(pElem); + if( pTab->tnum==iFrom ){ + pTab->tnum = iTo; + } + } + pHash = &pDb->pSchema->idxHash; + for(pElem=sqliteHashFirst(pHash); pElem; pElem=sqliteHashNext(pElem)){ + Index *pIdx = sqliteHashData(pElem); + if( pIdx->tnum==iFrom ){ + pIdx->tnum = iTo; + } + } +} +#endif + +/* +** Write code to erase the table with root-page iTable from database iDb. +** Also write code to modify the sqlite_master table and internal schema +** if a root-page of another table is moved by the btree-layer whilst +** erasing iTable (this can happen with an auto-vacuum database). +*/ +static void destroyRootPage(Parse *pParse, int iTable, int iDb){ + Vdbe *v = sqlite3GetVdbe(pParse); + int r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb); + sqlite3MayAbort(pParse); +#ifndef SQLITE_OMIT_AUTOVACUUM + /* OP_Destroy stores an in integer r1. If this integer + ** is non-zero, then it is the root page number of a table moved to + ** location iTable. The following code modifies the sqlite_master table to + ** reflect this. + ** + ** The "#NNN" in the SQL is a special constant that means whatever value + ** is in register NNN. See grammar rules associated with the TK_REGISTER + ** token for additional information. + */ + sqlite3NestedParse(pParse, + "UPDATE %Q.%s SET rootpage=%d WHERE #%d AND rootpage=#%d", + pParse->db->aDb[iDb].zName, SCHEMA_TABLE(iDb), iTable, r1, r1); +#endif + sqlite3ReleaseTempReg(pParse, r1); +} + +/* +** Write VDBE code to erase table pTab and all associated indices on disk. +** Code to update the sqlite_master tables and internal schema definitions +** in case a root-page belonging to another table is moved by the btree layer +** is also added (this can happen with an auto-vacuum database). +*/ +static void destroyTable(Parse *pParse, Table *pTab){ +#ifdef SQLITE_OMIT_AUTOVACUUM + Index *pIdx; + int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + destroyRootPage(pParse, pTab->tnum, iDb); + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + destroyRootPage(pParse, pIdx->tnum, iDb); + } +#else + /* If the database may be auto-vacuum capable (if SQLITE_OMIT_AUTOVACUUM + ** is not defined), then it is important to call OP_Destroy on the + ** table and index root-pages in order, starting with the numerically + ** largest root-page number. This guarantees that none of the root-pages + ** to be destroyed is relocated by an earlier OP_Destroy. i.e. if the + ** following were coded: + ** + ** OP_Destroy 4 0 + ** ... + ** OP_Destroy 5 0 + ** + ** and root page 5 happened to be the largest root-page number in the + ** database, then root page 5 would be moved to page 4 by the + ** "OP_Destroy 4 0" opcode. The subsequent "OP_Destroy 5 0" would hit + ** a free-list page. + */ + int iTab = pTab->tnum; + int iDestroyed = 0; + + while( 1 ){ + Index *pIdx; + int iLargest = 0; + + if( iDestroyed==0 || iTabpIndex; pIdx; pIdx=pIdx->pNext){ + int iIdx = pIdx->tnum; + assert( pIdx->pSchema==pTab->pSchema ); + if( (iDestroyed==0 || (iIdxiLargest ){ + iLargest = iIdx; + } + } + if( iLargest==0 ){ + return; + }else{ + int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + destroyRootPage(pParse, iLargest, iDb); + iDestroyed = iLargest; + } + } +#endif +} + +/* +** Remove entries from the sqlite_statN tables (for N in (1,2,3)) +** after a DROP INDEX or DROP TABLE command. +*/ +static void sqlite3ClearStatTables( + Parse *pParse, /* The parsing context */ + int iDb, /* The database number */ + const char *zType, /* "idx" or "tbl" */ + const char *zName /* Name of index or table */ +){ + int i; + const char *zDbName = pParse->db->aDb[iDb].zName; + for(i=1; i<=3; i++){ + char zTab[24]; + sqlite3_snprintf(sizeof(zTab),zTab,"sqlite_stat%d",i); + if( sqlite3FindTable(pParse->db, zTab, zDbName) ){ + sqlite3NestedParse(pParse, + "DELETE FROM %Q.%s WHERE %s=%Q", + zDbName, zTab, zType, zName + ); + } + } +} + +/* +** Generate code to drop a table. +*/ +void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, int isView){ + Vdbe *v; + sqlite3 *db = pParse->db; + Trigger *pTrigger; + Db *pDb = &db->aDb[iDb]; + + v = sqlite3GetVdbe(pParse); + assert( v!=0 ); + sqlite3BeginWriteOperation(pParse, 1, iDb); + +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + sqlite3VdbeAddOp0(v, OP_VBegin); + } +#endif + + /* Drop all triggers associated with the table being dropped. Code + ** is generated to remove entries from sqlite_master and/or + ** sqlite_temp_master if required. + */ + pTrigger = sqlite3TriggerList(pParse, pTab); + while( pTrigger ){ + assert( pTrigger->pSchema==pTab->pSchema || + pTrigger->pSchema==db->aDb[1].pSchema ); + sqlite3DropTriggerPtr(pParse, pTrigger); + pTrigger = pTrigger->pNext; + } + +#ifndef SQLITE_OMIT_AUTOINCREMENT + /* Remove any entries of the sqlite_sequence table associated with + ** the table being dropped. This is done before the table is dropped + ** at the btree level, in case the sqlite_sequence table needs to + ** move as a result of the drop (can happen in auto-vacuum mode). + */ + if( pTab->tabFlags & TF_Autoincrement ){ + sqlite3NestedParse(pParse, + "DELETE FROM %Q.sqlite_sequence WHERE name=%Q", + pDb->zName, pTab->zName + ); + } +#endif + + /* Drop all SQLITE_MASTER table and index entries that refer to the + ** table. The program name loops through the master table and deletes + ** every row that refers to a table of the same name as the one being + ** dropped. Triggers are handled seperately because a trigger can be + ** created in the temp database that refers to a table in another + ** database. + */ + sqlite3NestedParse(pParse, + "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'", + pDb->zName, SCHEMA_TABLE(iDb), pTab->zName); + if( !isView && !IsVirtual(pTab) ){ + destroyTable(pParse, pTab); + } + + /* Remove the table entry from SQLite's internal schema and modify + ** the schema cookie. + */ + if( IsVirtual(pTab) ){ + sqlite3VdbeAddOp4(v, OP_VDestroy, iDb, 0, 0, pTab->zName, 0); + } + sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0); + sqlite3ChangeCookie(pParse, iDb); + sqliteViewResetAll(db, iDb); +} + +/* +** This routine is called to do the work of a DROP TABLE statement. +** pName is the name of the table to be dropped. +*/ +void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ + Table *pTab; + Vdbe *v; + sqlite3 *db = pParse->db; + int iDb; + + if( db->mallocFailed ){ + goto exit_drop_table; + } + assert( pParse->nErr==0 ); + assert( pName->nSrc==1 ); + if( noErr ) db->suppressErr++; + pTab = sqlite3LocateTable(pParse, isView, + pName->a[0].zName, pName->a[0].zDatabase); + if( noErr ) db->suppressErr--; + + if( pTab==0 ){ + if( noErr ) sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); + goto exit_drop_table; + } + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iDb>=0 && iDbnDb ); + + /* If pTab is a virtual table, call ViewGetColumnNames() to ensure + ** it is initialized. + */ + if( IsVirtual(pTab) && sqlite3ViewGetColumnNames(pParse, pTab) ){ + goto exit_drop_table; + } +#ifndef SQLITE_OMIT_AUTHORIZATION + { + int code; + const char *zTab = SCHEMA_TABLE(iDb); + const char *zDb = db->aDb[iDb].zName; + const char *zArg2 = 0; + if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){ + goto exit_drop_table; + } + if( isView ){ + if( !OMIT_TEMPDB && iDb==1 ){ + code = SQLITE_DROP_TEMP_VIEW; + }else{ + code = SQLITE_DROP_VIEW; + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + }else if( IsVirtual(pTab) ){ + code = SQLITE_DROP_VTABLE; + zArg2 = sqlite3GetVTable(db, pTab)->pMod->zName; +#endif + }else{ + if( !OMIT_TEMPDB && iDb==1 ){ + code = SQLITE_DROP_TEMP_TABLE; + }else{ + code = SQLITE_DROP_TABLE; + } + } + if( sqlite3AuthCheck(pParse, code, pTab->zName, zArg2, zDb) ){ + goto exit_drop_table; + } + if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){ + goto exit_drop_table; + } + } +#endif + if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 + && sqlite3StrNICmp(pTab->zName, "sqlite_stat", 11)!=0 ){ + sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName); + goto exit_drop_table; + } + +#ifndef SQLITE_OMIT_VIEW + /* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used + ** on a table. + */ + if( isView && pTab->pSelect==0 ){ + sqlite3ErrorMsg(pParse, "use DROP TABLE to delete table %s", pTab->zName); + goto exit_drop_table; + } + if( !isView && pTab->pSelect ){ + sqlite3ErrorMsg(pParse, "use DROP VIEW to delete view %s", pTab->zName); + goto exit_drop_table; + } +#endif + + /* Generate code to remove the table from the master table + ** on disk. + */ + v = sqlite3GetVdbe(pParse); + if( v ){ + sqlite3BeginWriteOperation(pParse, 1, iDb); + sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName); + sqlite3FkDropTable(pParse, pName, pTab); + sqlite3CodeDropTable(pParse, pTab, iDb, isView); + } + +exit_drop_table: + sqlite3SrcListDelete(db, pName); +} + +/* +** This routine is called to create a new foreign key on the table +** currently under construction. pFromCol determines which columns +** in the current table point to the foreign key. If pFromCol==0 then +** connect the key to the last column inserted. pTo is the name of +** the table referred to. pToCol is a list of tables in the other +** pTo table that the foreign key points to. flags contains all +** information about the conflict resolution algorithms specified +** in the ON DELETE, ON UPDATE and ON INSERT clauses. +** +** An FKey structure is created and added to the table currently +** under construction in the pParse->pNewTable field. +** +** The foreign key is set for IMMEDIATE processing. A subsequent call +** to sqlite3DeferForeignKey() might change this to DEFERRED. +*/ +void sqlite3CreateForeignKey( + Parse *pParse, /* Parsing context */ + ExprList *pFromCol, /* Columns in this table that point to other table */ + Token *pTo, /* Name of the other table */ + ExprList *pToCol, /* Columns in the other table */ + int flags /* Conflict resolution algorithms. */ +){ + sqlite3 *db = pParse->db; +#ifndef SQLITE_OMIT_FOREIGN_KEY + FKey *pFKey = 0; + FKey *pNextTo; + Table *p = pParse->pNewTable; + int nByte; + int i; + int nCol; + char *z; + + assert( pTo!=0 ); + if( p==0 || IN_DECLARE_VTAB ) goto fk_end; + if( pFromCol==0 ){ + int iCol = p->nCol-1; + if( NEVER(iCol<0) ) goto fk_end; + if( pToCol && pToCol->nExpr!=1 ){ + sqlite3ErrorMsg(pParse, "foreign key on %s" + " should reference only one column of table %T", + p->aCol[iCol].zName, pTo); + goto fk_end; + } + nCol = 1; + }else if( pToCol && pToCol->nExpr!=pFromCol->nExpr ){ + sqlite3ErrorMsg(pParse, + "number of columns in foreign key does not match the number of " + "columns in the referenced table"); + goto fk_end; + }else{ + nCol = pFromCol->nExpr; + } + nByte = sizeof(*pFKey) + (nCol-1)*sizeof(pFKey->aCol[0]) + pTo->n + 1; + if( pToCol ){ + for(i=0; inExpr; i++){ + nByte += sqlite3Strlen30(pToCol->a[i].zName) + 1; + } + } + pFKey = sqlite3DbMallocZero(db, nByte ); + if( pFKey==0 ){ + goto fk_end; + } + pFKey->pFrom = p; + pFKey->pNextFrom = p->pFKey; + z = (char*)&pFKey->aCol[nCol]; + pFKey->zTo = z; + memcpy(z, pTo->z, pTo->n); + z[pTo->n] = 0; + sqlite3Dequote(z); + z += pTo->n+1; + pFKey->nCol = nCol; + if( pFromCol==0 ){ + pFKey->aCol[0].iFrom = p->nCol-1; + }else{ + for(i=0; inCol; j++){ + if( sqlite3StrICmp(p->aCol[j].zName, pFromCol->a[i].zName)==0 ){ + pFKey->aCol[i].iFrom = j; + break; + } + } + if( j>=p->nCol ){ + sqlite3ErrorMsg(pParse, + "unknown column \"%s\" in foreign key definition", + pFromCol->a[i].zName); + goto fk_end; + } + } + } + if( pToCol ){ + for(i=0; ia[i].zName); + pFKey->aCol[i].zCol = z; + memcpy(z, pToCol->a[i].zName, n); + z[n] = 0; + z += n+1; + } + } + pFKey->isDeferred = 0; + pFKey->aAction[0] = (u8)(flags & 0xff); /* ON DELETE action */ + pFKey->aAction[1] = (u8)((flags >> 8 ) & 0xff); /* ON UPDATE action */ + + assert( sqlite3SchemaMutexHeld(db, 0, p->pSchema) ); + pNextTo = (FKey *)sqlite3HashInsert(&p->pSchema->fkeyHash, + pFKey->zTo, sqlite3Strlen30(pFKey->zTo), (void *)pFKey + ); + if( pNextTo==pFKey ){ + db->mallocFailed = 1; + goto fk_end; + } + if( pNextTo ){ + assert( pNextTo->pPrevTo==0 ); + pFKey->pNextTo = pNextTo; + pNextTo->pPrevTo = pFKey; + } + + /* Link the foreign key to the table as the last step. + */ + p->pFKey = pFKey; + pFKey = 0; + +fk_end: + sqlite3DbFree(db, pFKey); +#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ + sqlite3ExprListDelete(db, pFromCol); + sqlite3ExprListDelete(db, pToCol); +} + +/* +** This routine is called when an INITIALLY IMMEDIATE or INITIALLY DEFERRED +** clause is seen as part of a foreign key definition. The isDeferred +** parameter is 1 for INITIALLY DEFERRED and 0 for INITIALLY IMMEDIATE. +** The behavior of the most recently created foreign key is adjusted +** accordingly. +*/ +void sqlite3DeferForeignKey(Parse *pParse, int isDeferred){ +#ifndef SQLITE_OMIT_FOREIGN_KEY + Table *pTab; + FKey *pFKey; + if( (pTab = pParse->pNewTable)==0 || (pFKey = pTab->pFKey)==0 ) return; + assert( isDeferred==0 || isDeferred==1 ); /* EV: R-30323-21917 */ + pFKey->isDeferred = (u8)isDeferred; +#endif +} + +/* +** Generate code that will erase and refill index *pIdx. This is +** used to initialize a newly created index or to recompute the +** content of an index in response to a REINDEX command. +** +** if memRootPage is not negative, it means that the index is newly +** created. The register specified by memRootPage contains the +** root page number of the index. If memRootPage is negative, then +** the index already exists and must be cleared before being refilled and +** the root page number of the index is taken from pIndex->tnum. +*/ +static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ + Table *pTab = pIndex->pTable; /* The table that is indexed */ + int iTab = pParse->nTab++; /* Btree cursor used for pTab */ + int iIdx = pParse->nTab++; /* Btree cursor used for pIndex */ + int iSorter; /* Cursor opened by OpenSorter (if in use) */ + int addr1; /* Address of top of loop */ + int addr2; /* Address to jump to for next iteration */ + int tnum; /* Root page of index */ + Vdbe *v; /* Generate code into this virtual machine */ + KeyInfo *pKey; /* KeyInfo for index */ +#ifdef SQLITE_OMIT_MERGE_SORT + int regIdxKey; /* Registers containing the index key */ +#endif + int regRecord; /* Register holding assemblied index record */ + sqlite3 *db = pParse->db; /* The database connection */ + int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema); + +#ifndef SQLITE_OMIT_AUTHORIZATION + if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0, + db->aDb[iDb].zName ) ){ + return; + } +#endif + + /* Require a write-lock on the table to perform this operation */ + sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName); + + v = sqlite3GetVdbe(pParse); + if( v==0 ) return; + if( memRootPage>=0 ){ + tnum = memRootPage; + }else{ + tnum = pIndex->tnum; + sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb); + } + pKey = sqlite3IndexKeyinfo(pParse, pIndex); + sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb, + (char *)pKey, P4_KEYINFO_HANDOFF); + if( memRootPage>=0 ){ + sqlite3VdbeChangeP5(v, 1); + } + +#ifndef SQLITE_OMIT_MERGE_SORT + /* Open the sorter cursor if we are to use one. */ + iSorter = pParse->nTab++; + sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*)pKey, P4_KEYINFO); +#else + iSorter = iTab; +#endif + + /* Open the table. Loop through all rows of the table, inserting index + ** records into the sorter. */ + sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); + addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); + regRecord = sqlite3GetTempReg(pParse); + +#ifndef SQLITE_OMIT_MERGE_SORT + sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1); + sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord); + sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); + sqlite3VdbeJumpHere(v, addr1); + addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); + if( pIndex->onError!=OE_None ){ + int j2 = sqlite3VdbeCurrentAddr(v) + 3; + sqlite3VdbeAddOp2(v, OP_Goto, 0, j2); + addr2 = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp3(v, OP_SorterCompare, iSorter, j2, regRecord); + sqlite3HaltConstraint( + pParse, OE_Abort, "indexed columns are not unique", P4_STATIC + ); + }else{ + addr2 = sqlite3VdbeCurrentAddr(v); + } + sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord); + sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1); + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); +#else + regIdxKey = sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1); + addr2 = addr1 + 1; + if( pIndex->onError!=OE_None ){ + const int regRowid = regIdxKey + pIndex->nColumn; + const int j2 = sqlite3VdbeCurrentAddr(v) + 2; + void * const pRegKey = SQLITE_INT_TO_PTR(regIdxKey); + + /* The registers accessed by the OP_IsUnique opcode were allocated + ** using sqlite3GetTempRange() inside of the sqlite3GenerateIndexKey() + ** call above. Just before that function was freed they were released + ** (made available to the compiler for reuse) using + ** sqlite3ReleaseTempRange(). So in some ways having the OP_IsUnique + ** opcode use the values stored within seems dangerous. However, since + ** we can be sure that no other temp registers have been allocated + ** since sqlite3ReleaseTempRange() was called, it is safe to do so. + */ + sqlite3VdbeAddOp4(v, OP_IsUnique, iIdx, j2, regRowid, pRegKey, P4_INT32); + sqlite3HaltConstraint( + pParse, OE_Abort, "indexed columns are not unique", P4_STATIC); + } + sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 0); + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); +#endif + sqlite3ReleaseTempReg(pParse, regRecord); + sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); + sqlite3VdbeJumpHere(v, addr1); + + sqlite3VdbeAddOp1(v, OP_Close, iTab); + sqlite3VdbeAddOp1(v, OP_Close, iIdx); + sqlite3VdbeAddOp1(v, OP_Close, iSorter); +} + +/* +** Create a new index for an SQL table. pName1.pName2 is the name of the index +** and pTblList is the name of the table that is to be indexed. Both will +** be NULL for a primary key or an index that is created to satisfy a +** UNIQUE constraint. If pTable and pIndex are NULL, use pParse->pNewTable +** as the table to be indexed. pParse->pNewTable is a table that is +** currently being constructed by a CREATE TABLE statement. +** +** pList is a list of columns to be indexed. pList will be NULL if this +** is a primary key or unique-constraint on the most recent column added +** to the table currently under construction. +** +** If the index is created successfully, return a pointer to the new Index +** structure. This is used by sqlite3AddPrimaryKey() to mark the index +** as the tables primary key (Index.autoIndex==2). +*/ +Index *sqlite3CreateIndex( + Parse *pParse, /* All information about this parse */ + Token *pName1, /* First part of index name. May be NULL */ + Token *pName2, /* Second part of index name. May be NULL */ + SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */ + ExprList *pList, /* A list of columns to be indexed */ + int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ + Token *pStart, /* The CREATE token that begins this statement */ + Token *pEnd, /* The ")" that closes the CREATE INDEX statement */ + int sortOrder, /* Sort order of primary key when pList==NULL */ + int ifNotExist /* Omit error if index already exists */ +){ + Index *pRet = 0; /* Pointer to return */ + Table *pTab = 0; /* Table to be indexed */ + Index *pIndex = 0; /* The index to be created */ + char *zName = 0; /* Name of the index */ + int nName; /* Number of characters in zName */ + int i, j; + Token nullId; /* Fake token for an empty ID list */ + DbFixer sFix; /* For assigning database names to pTable */ + int sortOrderMask; /* 1 to honor DESC in index. 0 to ignore. */ + sqlite3 *db = pParse->db; + Db *pDb; /* The specific table containing the indexed database */ + int iDb; /* Index of the database that is being written */ + Token *pName = 0; /* Unqualified name of the index to create */ + struct ExprList_item *pListItem; /* For looping over pList */ + int nCol; + int nExtra = 0; + char *zExtra; + + assert( pStart==0 || pEnd!=0 ); /* pEnd must be non-NULL if pStart is */ + assert( pParse->nErr==0 ); /* Never called with prior errors */ + if( db->mallocFailed || IN_DECLARE_VTAB ){ + goto exit_create_index; + } + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + goto exit_create_index; + } + + /* + ** Find the table that is to be indexed. Return early if not found. + */ + if( pTblName!=0 ){ + + /* Use the two-part index name to determine the database + ** to search for the table. 'Fix' the table name to this db + ** before looking up the table. + */ + assert( pName1 && pName2 ); + iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName); + if( iDb<0 ) goto exit_create_index; + assert( pName && pName->z ); + +#ifndef SQLITE_OMIT_TEMPDB + /* If the index name was unqualified, check if the the table + ** is a temp table. If so, set the database to 1. Do not do this + ** if initialising a database schema. + */ + if( !db->init.busy ){ + pTab = sqlite3SrcListLookup(pParse, pTblName); + if( pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){ + iDb = 1; + } + } +#endif + + if( sqlite3FixInit(&sFix, pParse, iDb, "index", pName) && + sqlite3FixSrcList(&sFix, pTblName) + ){ + /* Because the parser constructs pTblName from a single identifier, + ** sqlite3FixSrcList can never fail. */ + assert(0); + } + pTab = sqlite3LocateTable(pParse, 0, pTblName->a[0].zName, + pTblName->a[0].zDatabase); + if( !pTab || db->mallocFailed ) goto exit_create_index; + assert( db->aDb[iDb].pSchema==pTab->pSchema ); + }else{ + assert( pName==0 ); + assert( pStart==0 ); + pTab = pParse->pNewTable; + if( !pTab ) goto exit_create_index; + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + } + pDb = &db->aDb[iDb]; + + assert( pTab!=0 ); + assert( pParse->nErr==0 ); + if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 + && memcmp(&pTab->zName[7],"altertab_",9)!=0 ){ + sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName); + goto exit_create_index; + } +#ifndef SQLITE_OMIT_VIEW + if( pTab->pSelect ){ + sqlite3ErrorMsg(pParse, "views may not be indexed"); + goto exit_create_index; + } +#endif +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + sqlite3ErrorMsg(pParse, "virtual tables may not be indexed"); + goto exit_create_index; + } +#endif + + /* + ** Find the name of the index. Make sure there is not already another + ** index or table with the same name. + ** + ** Exception: If we are reading the names of permanent indices from the + ** sqlite_master table (because some other process changed the schema) and + ** one of the index names collides with the name of a temporary table or + ** index, then we will continue to process this index. + ** + ** If pName==0 it means that we are + ** dealing with a primary key or UNIQUE constraint. We have to invent our + ** own name. + */ + if( pName ){ + zName = sqlite3NameFromToken(db, pName); + if( zName==0 ) goto exit_create_index; + assert( pName->z!=0 ); + if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ + goto exit_create_index; + } + if( !db->init.busy ){ + if( sqlite3FindTable(db, zName, 0)!=0 ){ + sqlite3ErrorMsg(pParse, "there is already a table named %s", zName); + goto exit_create_index; + } + } + if( sqlite3FindIndex(db, zName, pDb->zName)!=0 ){ + if( !ifNotExist ){ + sqlite3ErrorMsg(pParse, "index %s already exists", zName); + }else{ + assert( !db->init.busy ); + sqlite3CodeVerifySchema(pParse, iDb); + } + goto exit_create_index; + } + }else{ + int n; + Index *pLoop; + for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){} + zName = sqlite3MPrintf(db, "sqlite_autoindex_%s_%d", pTab->zName, n); + if( zName==0 ){ + goto exit_create_index; + } + } + + /* Check for authorization to create an index. + */ +#ifndef SQLITE_OMIT_AUTHORIZATION + { + const char *zDb = pDb->zName; + if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){ + goto exit_create_index; + } + i = SQLITE_CREATE_INDEX; + if( !OMIT_TEMPDB && iDb==1 ) i = SQLITE_CREATE_TEMP_INDEX; + if( sqlite3AuthCheck(pParse, i, zName, pTab->zName, zDb) ){ + goto exit_create_index; + } + } +#endif + + /* If pList==0, it means this routine was called to make a primary + ** key out of the last column added to the table under construction. + ** So create a fake list to simulate this. + */ + if( pList==0 ){ + nullId.z = pTab->aCol[pTab->nCol-1].zName; + nullId.n = sqlite3Strlen30((char*)nullId.z); + pList = sqlite3ExprListAppend(pParse, 0, 0); + if( pList==0 ) goto exit_create_index; + sqlite3ExprListSetName(pParse, pList, &nullId, 0); + pList->a[0].sortOrder = (u8)sortOrder; + } + + /* Figure out how many bytes of space are required to store explicitly + ** specified collation sequence names. + */ + for(i=0; inExpr; i++){ + Expr *pExpr = pList->a[i].pExpr; + if( pExpr ){ + CollSeq *pColl = pExpr->pColl; + /* Either pColl!=0 or there was an OOM failure. But if an OOM + ** failure we have quit before reaching this point. */ + if( ALWAYS(pColl) ){ + nExtra += (1 + sqlite3Strlen30(pColl->zName)); + } + } + } + + /* + ** Allocate the index structure. + */ + nName = sqlite3Strlen30(zName); + nCol = pList->nExpr; + pIndex = sqlite3DbMallocZero(db, + ROUND8(sizeof(Index)) + /* Index structure */ + ROUND8(sizeof(tRowcnt)*(nCol+1)) + /* Index.aiRowEst */ + sizeof(char *)*nCol + /* Index.azColl */ + sizeof(int)*nCol + /* Index.aiColumn */ + sizeof(u8)*nCol + /* Index.aSortOrder */ + nName + 1 + /* Index.zName */ + nExtra /* Collation sequence names */ + ); + if( db->mallocFailed ){ + goto exit_create_index; + } + zExtra = (char*)pIndex; + pIndex->aiRowEst = (tRowcnt*)&zExtra[ROUND8(sizeof(Index))]; + pIndex->azColl = (char**) + ((char*)pIndex->aiRowEst + ROUND8(sizeof(tRowcnt)*nCol+1)); + assert( EIGHT_BYTE_ALIGNMENT(pIndex->aiRowEst) ); + assert( EIGHT_BYTE_ALIGNMENT(pIndex->azColl) ); + pIndex->aiColumn = (int *)(&pIndex->azColl[nCol]); + pIndex->aSortOrder = (u8 *)(&pIndex->aiColumn[nCol]); + pIndex->zName = (char *)(&pIndex->aSortOrder[nCol]); + zExtra = (char *)(&pIndex->zName[nName+1]); + memcpy(pIndex->zName, zName, nName+1); + pIndex->pTable = pTab; + pIndex->nColumn = pList->nExpr; + pIndex->onError = (u8)onError; + pIndex->autoIndex = (u8)(pName==0); + pIndex->pSchema = db->aDb[iDb].pSchema; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + + /* Check to see if we should honor DESC requests on index columns + */ + if( pDb->pSchema->file_format>=4 ){ + sortOrderMask = -1; /* Honor DESC */ + }else{ + sortOrderMask = 0; /* Ignore DESC */ + } + + /* Scan the names of the columns of the table to be indexed and + ** load the column indices into the Index structure. Report an error + ** if any column is not found. + ** + ** TODO: Add a test to make sure that the same column is not named + ** more than once within the same index. Only the first instance of + ** the column will ever be used by the optimizer. Note that using the + ** same column more than once cannot be an error because that would + ** break backwards compatibility - it needs to be a warning. + */ + for(i=0, pListItem=pList->a; inExpr; i++, pListItem++){ + const char *zColName = pListItem->zName; + Column *pTabCol; + int requestedSortOrder; + char *zColl; /* Collation sequence name */ + + for(j=0, pTabCol=pTab->aCol; jnCol; j++, pTabCol++){ + if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break; + } + if( j>=pTab->nCol ){ + sqlite3ErrorMsg(pParse, "table %s has no column named %s", + pTab->zName, zColName); + pParse->checkSchema = 1; + goto exit_create_index; + } + pIndex->aiColumn[i] = j; + /* Justification of the ALWAYS(pListItem->pExpr->pColl): Because of + ** the way the "idxlist" non-terminal is constructed by the parser, + ** if pListItem->pExpr is not null then either pListItem->pExpr->pColl + ** must exist or else there must have been an OOM error. But if there + ** was an OOM error, we would never reach this point. */ + if( pListItem->pExpr && ALWAYS(pListItem->pExpr->pColl) ){ + int nColl; + zColl = pListItem->pExpr->pColl->zName; + nColl = sqlite3Strlen30(zColl) + 1; + assert( nExtra>=nColl ); + memcpy(zExtra, zColl, nColl); + zColl = zExtra; + zExtra += nColl; + nExtra -= nColl; + }else{ + zColl = pTab->aCol[j].zColl; + if( !zColl ){ + zColl = db->pDfltColl->zName; + } + } + if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){ + goto exit_create_index; + } + pIndex->azColl[i] = zColl; + requestedSortOrder = pListItem->sortOrder & sortOrderMask; + pIndex->aSortOrder[i] = (u8)requestedSortOrder; + } + sqlite3DefaultRowEst(pIndex); + + if( pTab==pParse->pNewTable ){ + /* This routine has been called to create an automatic index as a + ** result of a PRIMARY KEY or UNIQUE clause on a column definition, or + ** a PRIMARY KEY or UNIQUE clause following the column definitions. + ** i.e. one of: + ** + ** CREATE TABLE t(x PRIMARY KEY, y); + ** CREATE TABLE t(x, y, UNIQUE(x, y)); + ** + ** Either way, check to see if the table already has such an index. If + ** so, don't bother creating this one. This only applies to + ** automatically created indices. Users can do as they wish with + ** explicit indices. + ** + ** Two UNIQUE or PRIMARY KEY constraints are considered equivalent + ** (and thus suppressing the second one) even if they have different + ** sort orders. + ** + ** If there are different collating sequences or if the columns of + ** the constraint occur in different orders, then the constraints are + ** considered distinct and both result in separate indices. + */ + Index *pIdx; + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + int k; + assert( pIdx->onError!=OE_None ); + assert( pIdx->autoIndex ); + assert( pIndex->onError!=OE_None ); + + if( pIdx->nColumn!=pIndex->nColumn ) continue; + for(k=0; knColumn; k++){ + const char *z1; + const char *z2; + if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break; + z1 = pIdx->azColl[k]; + z2 = pIndex->azColl[k]; + if( z1!=z2 && sqlite3StrICmp(z1, z2) ) break; + } + if( k==pIdx->nColumn ){ + if( pIdx->onError!=pIndex->onError ){ + /* This constraint creates the same index as a previous + ** constraint specified somewhere in the CREATE TABLE statement. + ** However the ON CONFLICT clauses are different. If both this + ** constraint and the previous equivalent constraint have explicit + ** ON CONFLICT clauses this is an error. Otherwise, use the + ** explicitly specified behaviour for the index. + */ + if( !(pIdx->onError==OE_Default || pIndex->onError==OE_Default) ){ + sqlite3ErrorMsg(pParse, + "conflicting ON CONFLICT clauses specified", 0); + } + if( pIdx->onError==OE_Default ){ + pIdx->onError = pIndex->onError; + } + } + goto exit_create_index; + } + } + } + + /* Link the new Index structure to its table and to the other + ** in-memory database structures. + */ + if( db->init.busy ){ + Index *p; + assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); + p = sqlite3HashInsert(&pIndex->pSchema->idxHash, + pIndex->zName, sqlite3Strlen30(pIndex->zName), + pIndex); + if( p ){ + assert( p==pIndex ); /* Malloc must have failed */ + db->mallocFailed = 1; + goto exit_create_index; + } + db->flags |= SQLITE_InternChanges; + if( pTblName!=0 ){ + pIndex->tnum = db->init.newTnum; + } + } + + /* If the db->init.busy is 0 then create the index on disk. This + ** involves writing the index into the master table and filling in the + ** index with the current table contents. + ** + ** The db->init.busy is 0 when the user first enters a CREATE INDEX + ** command. db->init.busy is 1 when a database is opened and + ** CREATE INDEX statements are read out of the master table. In + ** the latter case the index already exists on disk, which is why + ** we don't want to recreate it. + ** + ** If pTblName==0 it means this index is generated as a primary key + ** or UNIQUE constraint of a CREATE TABLE statement. Since the table + ** has just been created, it contains no data and the index initialization + ** step can be skipped. + */ + else{ /* if( db->init.busy==0 ) */ + Vdbe *v; + char *zStmt; + int iMem = ++pParse->nMem; + + v = sqlite3GetVdbe(pParse); + if( v==0 ) goto exit_create_index; + + + /* Create the rootpage for the index + */ + sqlite3BeginWriteOperation(pParse, 1, iDb); + sqlite3VdbeAddOp2(v, OP_CreateIndex, iDb, iMem); + + /* Gather the complete text of the CREATE INDEX statement into + ** the zStmt variable + */ + if( pStart ){ + assert( pEnd!=0 ); + /* A named index with an explicit CREATE INDEX statement */ + zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s", + onError==OE_None ? "" : " UNIQUE", + (int)(pEnd->z - pName->z) + 1, + pName->z); + }else{ + /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */ + /* zStmt = sqlite3MPrintf(""); */ + zStmt = 0; + } + + /* Add an entry in sqlite_master for this index + */ + sqlite3NestedParse(pParse, + "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);", + db->aDb[iDb].zName, SCHEMA_TABLE(iDb), + pIndex->zName, + pTab->zName, + iMem, + zStmt + ); + sqlite3DbFree(db, zStmt); + + /* Fill the index with data and reparse the schema. Code an OP_Expire + ** to invalidate all pre-compiled statements. + */ + if( pTblName ){ + sqlite3RefillIndex(pParse, pIndex, iMem); + sqlite3ChangeCookie(pParse, iDb); + sqlite3VdbeAddParseSchemaOp(v, iDb, + sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName)); + sqlite3VdbeAddOp1(v, OP_Expire, 0); + } + } + + /* When adding an index to the list of indices for a table, make + ** sure all indices labeled OE_Replace come after all those labeled + ** OE_Ignore. This is necessary for the correct constraint check + ** processing (in sqlite3GenerateConstraintChecks()) as part of + ** UPDATE and INSERT statements. + */ + if( db->init.busy || pTblName==0 ){ + if( onError!=OE_Replace || pTab->pIndex==0 + || pTab->pIndex->onError==OE_Replace){ + pIndex->pNext = pTab->pIndex; + pTab->pIndex = pIndex; + }else{ + Index *pOther = pTab->pIndex; + while( pOther->pNext && pOther->pNext->onError!=OE_Replace ){ + pOther = pOther->pNext; + } + pIndex->pNext = pOther->pNext; + pOther->pNext = pIndex; + } + pRet = pIndex; + pIndex = 0; + } + + /* Clean up before exiting */ +exit_create_index: + if( pIndex ){ + sqlite3DbFree(db, pIndex->zColAff); + sqlite3DbFree(db, pIndex); + } + sqlite3ExprListDelete(db, pList); + sqlite3SrcListDelete(db, pTblName); + sqlite3DbFree(db, zName); + return pRet; +} + +/* +** Fill the Index.aiRowEst[] array with default information - information +** to be used when we have not run the ANALYZE command. +** +** aiRowEst[0] is suppose to contain the number of elements in the index. +** Since we do not know, guess 1 million. aiRowEst[1] is an estimate of the +** number of rows in the table that match any particular value of the +** first column of the index. aiRowEst[2] is an estimate of the number +** of rows that match any particular combiniation of the first 2 columns +** of the index. And so forth. It must always be the case that +* +** aiRowEst[N]<=aiRowEst[N-1] +** aiRowEst[N]>=1 +** +** Apart from that, we have little to go on besides intuition as to +** how aiRowEst[] should be initialized. The numbers generated here +** are based on typical values found in actual indices. +*/ +void sqlite3DefaultRowEst(Index *pIdx){ + tRowcnt *a = pIdx->aiRowEst; + int i; + tRowcnt n; + assert( a!=0 ); + a[0] = pIdx->pTable->nRowEst; + if( a[0]<10 ) a[0] = 10; + n = 10; + for(i=1; i<=pIdx->nColumn; i++){ + a[i] = n; + if( n>5 ) n--; + } + if( pIdx->onError!=OE_None ){ + a[pIdx->nColumn] = 1; + } +} + +/* +** This routine will drop an existing named index. This routine +** implements the DROP INDEX statement. +*/ +void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){ + Index *pIndex; + Vdbe *v; + sqlite3 *db = pParse->db; + int iDb; + + assert( pParse->nErr==0 ); /* Never called with prior errors */ + if( db->mallocFailed ){ + goto exit_drop_index; + } + assert( pName->nSrc==1 ); + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + goto exit_drop_index; + } + pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase); + if( pIndex==0 ){ + if( !ifExists ){ + sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0); + }else{ + sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); + } + pParse->checkSchema = 1; + goto exit_drop_index; + } + if( pIndex->autoIndex ){ + sqlite3ErrorMsg(pParse, "index associated with UNIQUE " + "or PRIMARY KEY constraint cannot be dropped", 0); + goto exit_drop_index; + } + iDb = sqlite3SchemaToIndex(db, pIndex->pSchema); +#ifndef SQLITE_OMIT_AUTHORIZATION + { + int code = SQLITE_DROP_INDEX; + Table *pTab = pIndex->pTable; + const char *zDb = db->aDb[iDb].zName; + const char *zTab = SCHEMA_TABLE(iDb); + if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){ + goto exit_drop_index; + } + if( !OMIT_TEMPDB && iDb ) code = SQLITE_DROP_TEMP_INDEX; + if( sqlite3AuthCheck(pParse, code, pIndex->zName, pTab->zName, zDb) ){ + goto exit_drop_index; + } + } +#endif + + /* Generate code to remove the index and from the master table */ + v = sqlite3GetVdbe(pParse); + if( v ){ + sqlite3BeginWriteOperation(pParse, 1, iDb); + sqlite3NestedParse(pParse, + "DELETE FROM %Q.%s WHERE name=%Q AND type='index'", + db->aDb[iDb].zName, SCHEMA_TABLE(iDb), pIndex->zName + ); + sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName); + sqlite3ChangeCookie(pParse, iDb); + destroyRootPage(pParse, pIndex->tnum, iDb); + sqlite3VdbeAddOp4(v, OP_DropIndex, iDb, 0, 0, pIndex->zName, 0); + } + +exit_drop_index: + sqlite3SrcListDelete(db, pName); +} + +/* +** pArray is a pointer to an array of objects. Each object in the +** array is szEntry bytes in size. This routine allocates a new +** object on the end of the array. +** +** *pnEntry is the number of entries already in use. *pnAlloc is +** the previously allocated size of the array. initSize is the +** suggested initial array size allocation. +** +** The index of the new entry is returned in *pIdx. +** +** This routine returns a pointer to the array of objects. This +** might be the same as the pArray parameter or it might be a different +** pointer if the array was resized. +*/ +void *sqlite3ArrayAllocate( + sqlite3 *db, /* Connection to notify of malloc failures */ + void *pArray, /* Array of objects. Might be reallocated */ + int szEntry, /* Size of each object in the array */ + int initSize, /* Suggested initial allocation, in elements */ + int *pnEntry, /* Number of objects currently in use */ + int *pnAlloc, /* Current size of the allocation, in elements */ + int *pIdx /* Write the index of a new slot here */ +){ + char *z; + if( *pnEntry >= *pnAlloc ){ + void *pNew; + int newSize; + newSize = (*pnAlloc)*2 + initSize; + pNew = sqlite3DbRealloc(db, pArray, newSize*szEntry); + if( pNew==0 ){ + *pIdx = -1; + return pArray; + } + *pnAlloc = sqlite3DbMallocSize(db, pNew)/szEntry; + pArray = pNew; + } + z = (char*)pArray; + memset(&z[*pnEntry * szEntry], 0, szEntry); + *pIdx = *pnEntry; + ++*pnEntry; + return pArray; +} + +/* +** Append a new element to the given IdList. Create a new IdList if +** need be. +** +** A new IdList is returned, or NULL if malloc() fails. +*/ +IdList *sqlite3IdListAppend(sqlite3 *db, IdList *pList, Token *pToken){ + int i; + if( pList==0 ){ + pList = sqlite3DbMallocZero(db, sizeof(IdList) ); + if( pList==0 ) return 0; + pList->nAlloc = 0; + } + pList->a = sqlite3ArrayAllocate( + db, + pList->a, + sizeof(pList->a[0]), + 5, + &pList->nId, + &pList->nAlloc, + &i + ); + if( i<0 ){ + sqlite3IdListDelete(db, pList); + return 0; + } + pList->a[i].zName = sqlite3NameFromToken(db, pToken); + return pList; +} + +/* +** Delete an IdList. +*/ +void sqlite3IdListDelete(sqlite3 *db, IdList *pList){ + int i; + if( pList==0 ) return; + for(i=0; inId; i++){ + sqlite3DbFree(db, pList->a[i].zName); + } + sqlite3DbFree(db, pList->a); + sqlite3DbFree(db, pList); +} + +/* +** Return the index in pList of the identifier named zId. Return -1 +** if not found. +*/ +int sqlite3IdListIndex(IdList *pList, const char *zName){ + int i; + if( pList==0 ) return -1; + for(i=0; inId; i++){ + if( sqlite3StrICmp(pList->a[i].zName, zName)==0 ) return i; + } + return -1; +} + +/* +** Expand the space allocated for the given SrcList object by +** creating nExtra new slots beginning at iStart. iStart is zero based. +** New slots are zeroed. +** +** For example, suppose a SrcList initially contains two entries: A,B. +** To append 3 new entries onto the end, do this: +** +** sqlite3SrcListEnlarge(db, pSrclist, 3, 2); +** +** After the call above it would contain: A, B, nil, nil, nil. +** If the iStart argument had been 1 instead of 2, then the result +** would have been: A, nil, nil, nil, B. To prepend the new slots, +** the iStart value would be 0. The result then would +** be: nil, nil, nil, A, B. +** +** If a memory allocation fails the SrcList is unchanged. The +** db->mallocFailed flag will be set to true. +*/ +SrcList *sqlite3SrcListEnlarge( + sqlite3 *db, /* Database connection to notify of OOM errors */ + SrcList *pSrc, /* The SrcList to be enlarged */ + int nExtra, /* Number of new slots to add to pSrc->a[] */ + int iStart /* Index in pSrc->a[] of first new slot */ +){ + int i; + + /* Sanity checking on calling parameters */ + assert( iStart>=0 ); + assert( nExtra>=1 ); + assert( pSrc!=0 ); + assert( iStart<=pSrc->nSrc ); + + /* Allocate additional space if needed */ + if( pSrc->nSrc+nExtra>pSrc->nAlloc ){ + SrcList *pNew; + int nAlloc = pSrc->nSrc+nExtra; + int nGot; + pNew = sqlite3DbRealloc(db, pSrc, + sizeof(*pSrc) + (nAlloc-1)*sizeof(pSrc->a[0]) ); + if( pNew==0 ){ + assert( db->mallocFailed ); + return pSrc; + } + pSrc = pNew; + nGot = (sqlite3DbMallocSize(db, pNew) - sizeof(*pSrc))/sizeof(pSrc->a[0])+1; + pSrc->nAlloc = (u16)nGot; + } + + /* Move existing slots that come after the newly inserted slots + ** out of the way */ + for(i=pSrc->nSrc-1; i>=iStart; i--){ + pSrc->a[i+nExtra] = pSrc->a[i]; + } + pSrc->nSrc += (i16)nExtra; + + /* Zero the newly allocated slots */ + memset(&pSrc->a[iStart], 0, sizeof(pSrc->a[0])*nExtra); + for(i=iStart; ia[i].iCursor = -1; + } + + /* Return a pointer to the enlarged SrcList */ + return pSrc; +} + + +/* +** Append a new table name to the given SrcList. Create a new SrcList if +** need be. A new entry is created in the SrcList even if pTable is NULL. +** +** A SrcList is returned, or NULL if there is an OOM error. The returned +** SrcList might be the same as the SrcList that was input or it might be +** a new one. If an OOM error does occurs, then the prior value of pList +** that is input to this routine is automatically freed. +** +** If pDatabase is not null, it means that the table has an optional +** database name prefix. Like this: "database.table". The pDatabase +** points to the table name and the pTable points to the database name. +** The SrcList.a[].zName field is filled with the table name which might +** come from pTable (if pDatabase is NULL) or from pDatabase. +** SrcList.a[].zDatabase is filled with the database name from pTable, +** or with NULL if no database is specified. +** +** In other words, if call like this: +** +** sqlite3SrcListAppend(D,A,B,0); +** +** Then B is a table name and the database name is unspecified. If called +** like this: +** +** sqlite3SrcListAppend(D,A,B,C); +** +** Then C is the table name and B is the database name. If C is defined +** then so is B. In other words, we never have a case where: +** +** sqlite3SrcListAppend(D,A,0,C); +** +** Both pTable and pDatabase are assumed to be quoted. They are dequoted +** before being added to the SrcList. +*/ +SrcList *sqlite3SrcListAppend( + sqlite3 *db, /* Connection to notify of malloc failures */ + SrcList *pList, /* Append to this SrcList. NULL creates a new SrcList */ + Token *pTable, /* Table to append */ + Token *pDatabase /* Database of the table */ +){ + struct SrcList_item *pItem; + assert( pDatabase==0 || pTable!=0 ); /* Cannot have C without B */ + if( pList==0 ){ + pList = sqlite3DbMallocZero(db, sizeof(SrcList) ); + if( pList==0 ) return 0; + pList->nAlloc = 1; + } + pList = sqlite3SrcListEnlarge(db, pList, 1, pList->nSrc); + if( db->mallocFailed ){ + sqlite3SrcListDelete(db, pList); + return 0; + } + pItem = &pList->a[pList->nSrc-1]; + if( pDatabase && pDatabase->z==0 ){ + pDatabase = 0; + } + if( pDatabase ){ + Token *pTemp = pDatabase; + pDatabase = pTable; + pTable = pTemp; + } + pItem->zName = sqlite3NameFromToken(db, pTable); + pItem->zDatabase = sqlite3NameFromToken(db, pDatabase); + return pList; +} + +/* +** Assign VdbeCursor index numbers to all tables in a SrcList +*/ +void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ + int i; + struct SrcList_item *pItem; + assert(pList || pParse->db->mallocFailed ); + if( pList ){ + for(i=0, pItem=pList->a; inSrc; i++, pItem++){ + if( pItem->iCursor>=0 ) break; + pItem->iCursor = pParse->nTab++; + if( pItem->pSelect ){ + sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc); + } + } + } +} + +/* +** Delete an entire SrcList including all its substructure. +*/ +void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ + int i; + struct SrcList_item *pItem; + if( pList==0 ) return; + for(pItem=pList->a, i=0; inSrc; i++, pItem++){ + sqlite3DbFree(db, pItem->zDatabase); + sqlite3DbFree(db, pItem->zName); + sqlite3DbFree(db, pItem->zAlias); + sqlite3DbFree(db, pItem->zIndex); + sqlite3DeleteTable(db, pItem->pTab); + sqlite3SelectDelete(db, pItem->pSelect); + sqlite3ExprDelete(db, pItem->pOn); + sqlite3IdListDelete(db, pItem->pUsing); + } + sqlite3DbFree(db, pList); +} + +/* +** This routine is called by the parser to add a new term to the +** end of a growing FROM clause. The "p" parameter is the part of +** the FROM clause that has already been constructed. "p" is NULL +** if this is the first term of the FROM clause. pTable and pDatabase +** are the name of the table and database named in the FROM clause term. +** pDatabase is NULL if the database name qualifier is missing - the +** usual case. If the term has a alias, then pAlias points to the +** alias token. If the term is a subquery, then pSubquery is the +** SELECT statement that the subquery encodes. The pTable and +** pDatabase parameters are NULL for subqueries. The pOn and pUsing +** parameters are the content of the ON and USING clauses. +** +** Return a new SrcList which encodes is the FROM with the new +** term added. +*/ +SrcList *sqlite3SrcListAppendFromTerm( + Parse *pParse, /* Parsing context */ + SrcList *p, /* The left part of the FROM clause already seen */ + Token *pTable, /* Name of the table to add to the FROM clause */ + Token *pDatabase, /* Name of the database containing pTable */ + Token *pAlias, /* The right-hand side of the AS subexpression */ + Select *pSubquery, /* A subquery used in place of a table name */ + Expr *pOn, /* The ON clause of a join */ + IdList *pUsing /* The USING clause of a join */ +){ + struct SrcList_item *pItem; + sqlite3 *db = pParse->db; + if( !p && (pOn || pUsing) ){ + sqlite3ErrorMsg(pParse, "a JOIN clause is required before %s", + (pOn ? "ON" : "USING") + ); + goto append_from_error; + } + p = sqlite3SrcListAppend(db, p, pTable, pDatabase); + if( p==0 || NEVER(p->nSrc==0) ){ + goto append_from_error; + } + pItem = &p->a[p->nSrc-1]; + assert( pAlias!=0 ); + if( pAlias->n ){ + pItem->zAlias = sqlite3NameFromToken(db, pAlias); + } + pItem->pSelect = pSubquery; + pItem->pOn = pOn; + pItem->pUsing = pUsing; + return p; + + append_from_error: + assert( p==0 ); + sqlite3ExprDelete(db, pOn); + sqlite3IdListDelete(db, pUsing); + sqlite3SelectDelete(db, pSubquery); + return 0; +} + +/* +** Add an INDEXED BY or NOT INDEXED clause to the most recently added +** element of the source-list passed as the second argument. +*/ +void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){ + assert( pIndexedBy!=0 ); + if( p && ALWAYS(p->nSrc>0) ){ + struct SrcList_item *pItem = &p->a[p->nSrc-1]; + assert( pItem->notIndexed==0 && pItem->zIndex==0 ); + if( pIndexedBy->n==1 && !pIndexedBy->z ){ + /* A "NOT INDEXED" clause was supplied. See parse.y + ** construct "indexed_opt" for details. */ + pItem->notIndexed = 1; + }else{ + pItem->zIndex = sqlite3NameFromToken(pParse->db, pIndexedBy); + } + } +} + +/* +** When building up a FROM clause in the parser, the join operator +** is initially attached to the left operand. But the code generator +** expects the join operator to be on the right operand. This routine +** Shifts all join operators from left to right for an entire FROM +** clause. +** +** Example: Suppose the join is like this: +** +** A natural cross join B +** +** The operator is "natural cross join". The A and B operands are stored +** in p->a[0] and p->a[1], respectively. The parser initially stores the +** operator with A. This routine shifts that operator over to B. +*/ +void sqlite3SrcListShiftJoinType(SrcList *p){ + if( p ){ + int i; + assert( p->a || p->nSrc==0 ); + for(i=p->nSrc-1; i>0; i--){ + p->a[i].jointype = p->a[i-1].jointype; + } + p->a[0].jointype = 0; + } +} + +/* +** Begin a transaction +*/ +void sqlite3BeginTransaction(Parse *pParse, int type){ + sqlite3 *db; + Vdbe *v; + int i; + + assert( pParse!=0 ); + db = pParse->db; + assert( db!=0 ); +/* if( db->aDb[0].pBt==0 ) return; */ + if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ){ + return; + } + v = sqlite3GetVdbe(pParse); + if( !v ) return; + if( type!=TK_DEFERRED ){ + for(i=0; inDb; i++){ + sqlite3VdbeAddOp2(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1); + sqlite3VdbeUsesBtree(v, i); + } + } + sqlite3VdbeAddOp2(v, OP_AutoCommit, 0, 0); +} + +/* +** Commit a transaction +*/ +void sqlite3CommitTransaction(Parse *pParse){ + Vdbe *v; + + assert( pParse!=0 ); + assert( pParse->db!=0 ); + if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ){ + return; + } + v = sqlite3GetVdbe(pParse); + if( v ){ + sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 0); + } +} + +/* +** Rollback a transaction +*/ +void sqlite3RollbackTransaction(Parse *pParse){ + Vdbe *v; + + assert( pParse!=0 ); + assert( pParse->db!=0 ); + if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ){ + return; + } + v = sqlite3GetVdbe(pParse); + if( v ){ + sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 1); + } +} + +/* +** This function is called by the parser when it parses a command to create, +** release or rollback an SQL savepoint. +*/ +void sqlite3Savepoint(Parse *pParse, int op, Token *pName){ + char *zName = sqlite3NameFromToken(pParse->db, pName); + if( zName ){ + Vdbe *v = sqlite3GetVdbe(pParse); +#ifndef SQLITE_OMIT_AUTHORIZATION + static const char * const az[] = { "BEGIN", "RELEASE", "ROLLBACK" }; + assert( !SAVEPOINT_BEGIN && SAVEPOINT_RELEASE==1 && SAVEPOINT_ROLLBACK==2 ); +#endif + if( !v || sqlite3AuthCheck(pParse, SQLITE_SAVEPOINT, az[op], zName, 0) ){ + sqlite3DbFree(pParse->db, zName); + return; + } + sqlite3VdbeAddOp4(v, OP_Savepoint, op, 0, 0, zName, P4_DYNAMIC); + } +} + +/* +** Make sure the TEMP database is open and available for use. Return +** the number of errors. Leave any error messages in the pParse structure. +*/ +int sqlite3OpenTempDatabase(Parse *pParse){ + sqlite3 *db = pParse->db; + if( db->aDb[1].pBt==0 && !pParse->explain ){ + int rc; + Btree *pBt; + static const int flags = + SQLITE_OPEN_READWRITE | + SQLITE_OPEN_CREATE | + SQLITE_OPEN_EXCLUSIVE | + SQLITE_OPEN_DELETEONCLOSE | + SQLITE_OPEN_TEMP_DB; + + rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pBt, 0, flags); + if( rc!=SQLITE_OK ){ + sqlite3ErrorMsg(pParse, "unable to open a temporary database " + "file for storing temporary tables"); + pParse->rc = rc; + return 1; + } + db->aDb[1].pBt = pBt; + assert( db->aDb[1].pSchema ); + if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1, 0) ){ + db->mallocFailed = 1; + return 1; + } + } + return 0; +} + +/* +** Generate VDBE code that will verify the schema cookie and start +** a read-transaction for all named database files. +** +** It is important that all schema cookies be verified and all +** read transactions be started before anything else happens in +** the VDBE program. But this routine can be called after much other +** code has been generated. So here is what we do: +** +** The first time this routine is called, we code an OP_Goto that +** will jump to a subroutine at the end of the program. Then we +** record every database that needs its schema verified in the +** pParse->cookieMask field. Later, after all other code has been +** generated, the subroutine that does the cookie verifications and +** starts the transactions will be coded and the OP_Goto P2 value +** will be made to point to that subroutine. The generation of the +** cookie verification subroutine code happens in sqlite3FinishCoding(). +** +** If iDb<0 then code the OP_Goto only - don't set flag to verify the +** schema on any databases. This can be used to position the OP_Goto +** early in the code, before we know if any database tables will be used. +*/ +void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + + if( pToplevel->cookieGoto==0 ){ + Vdbe *v = sqlite3GetVdbe(pToplevel); + if( v==0 ) return; /* This only happens if there was a prior error */ + pToplevel->cookieGoto = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0)+1; + } + if( iDb>=0 ){ + sqlite3 *db = pToplevel->db; + yDbMask mask; + + assert( iDbnDb ); + assert( db->aDb[iDb].pBt!=0 || iDb==1 ); + assert( iDbcookieMask & mask)==0 ){ + pToplevel->cookieMask |= mask; + pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie; + if( !OMIT_TEMPDB && iDb==1 ){ + sqlite3OpenTempDatabase(pToplevel); + } + } + } +} + +/* +** If argument zDb is NULL, then call sqlite3CodeVerifySchema() for each +** attached database. Otherwise, invoke it for the database named zDb only. +*/ +void sqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb){ + sqlite3 *db = pParse->db; + int i; + for(i=0; inDb; i++){ + Db *pDb = &db->aDb[i]; + if( pDb->pBt && (!zDb || 0==sqlite3StrICmp(zDb, pDb->zName)) ){ + sqlite3CodeVerifySchema(pParse, i); + } + } +} + +/* +** Generate VDBE code that prepares for doing an operation that +** might change the database. +** +** This routine starts a new transaction if we are not already within +** a transaction. If we are already within a transaction, then a checkpoint +** is set if the setStatement parameter is true. A checkpoint should +** be set for operations that might fail (due to a constraint) part of +** the way through and which will need to undo some writes without having to +** rollback the whole transaction. For operations where all constraints +** can be checked before any changes are made to the database, it is never +** necessary to undo a write and the checkpoint should not be set. +*/ +void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + sqlite3CodeVerifySchema(pParse, iDb); + pToplevel->writeMask |= ((yDbMask)1)<isMultiWrite |= setStatement; +} + +/* +** Indicate that the statement currently under construction might write +** more than one entry (example: deleting one row then inserting another, +** inserting multiple rows in a table, or inserting a row and index entries.) +** If an abort occurs after some of these writes have completed, then it will +** be necessary to undo the completed writes. +*/ +void sqlite3MultiWrite(Parse *pParse){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + pToplevel->isMultiWrite = 1; +} + +/* +** The code generator calls this routine if is discovers that it is +** possible to abort a statement prior to completion. In order to +** perform this abort without corrupting the database, we need to make +** sure that the statement is protected by a statement transaction. +** +** Technically, we only need to set the mayAbort flag if the +** isMultiWrite flag was previously set. There is a time dependency +** such that the abort must occur after the multiwrite. This makes +** some statements involving the REPLACE conflict resolution algorithm +** go a little faster. But taking advantage of this time dependency +** makes it more difficult to prove that the code is correct (in +** particular, it prevents us from writing an effective +** implementation of sqlite3AssertMayAbort()) and so we have chosen +** to take the safe route and skip the optimization. +*/ +void sqlite3MayAbort(Parse *pParse){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + pToplevel->mayAbort = 1; +} + +/* +** Code an OP_Halt that causes the vdbe to return an SQLITE_CONSTRAINT +** error. The onError parameter determines which (if any) of the statement +** and/or current transaction is rolled back. +*/ +void sqlite3HaltConstraint(Parse *pParse, int onError, char *p4, int p4type){ + Vdbe *v = sqlite3GetVdbe(pParse); + if( onError==OE_Abort ){ + sqlite3MayAbort(pParse); + } + sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0, p4, p4type); +} + +/* +** Check to see if pIndex uses the collating sequence pColl. Return +** true if it does and false if it does not. +*/ +#ifndef SQLITE_OMIT_REINDEX +static int collationMatch(const char *zColl, Index *pIndex){ + int i; + assert( zColl!=0 ); + for(i=0; inColumn; i++){ + const char *z = pIndex->azColl[i]; + assert( z!=0 ); + if( 0==sqlite3StrICmp(z, zColl) ){ + return 1; + } + } + return 0; +} +#endif + +/* +** Recompute all indices of pTab that use the collating sequence pColl. +** If pColl==0 then recompute all indices of pTab. +*/ +#ifndef SQLITE_OMIT_REINDEX +static void reindexTable(Parse *pParse, Table *pTab, char const *zColl){ + Index *pIndex; /* An index associated with pTab */ + + for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){ + if( zColl==0 || collationMatch(zColl, pIndex) ){ + int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + sqlite3BeginWriteOperation(pParse, 0, iDb); + sqlite3RefillIndex(pParse, pIndex, -1); + } + } +} +#endif + +/* +** Recompute all indices of all tables in all databases where the +** indices use the collating sequence pColl. If pColl==0 then recompute +** all indices everywhere. +*/ +#ifndef SQLITE_OMIT_REINDEX +static void reindexDatabases(Parse *pParse, char const *zColl){ + Db *pDb; /* A single database */ + int iDb; /* The database index number */ + sqlite3 *db = pParse->db; /* The database connection */ + HashElem *k; /* For looping over tables in pDb */ + Table *pTab; /* A table in the database */ + + assert( sqlite3BtreeHoldsAllMutexes(db) ); /* Needed for schema access */ + for(iDb=0, pDb=db->aDb; iDbnDb; iDb++, pDb++){ + assert( pDb!=0 ); + for(k=sqliteHashFirst(&pDb->pSchema->tblHash); k; k=sqliteHashNext(k)){ + pTab = (Table*)sqliteHashData(k); + reindexTable(pParse, pTab, zColl); + } + } +} +#endif + +/* +** Generate code for the REINDEX command. +** +** REINDEX -- 1 +** REINDEX -- 2 +** REINDEX ?.? -- 3 +** REINDEX ?.? -- 4 +** +** Form 1 causes all indices in all attached databases to be rebuilt. +** Form 2 rebuilds all indices in all databases that use the named +** collating function. Forms 3 and 4 rebuild the named index or all +** indices associated with the named table. +*/ +#ifndef SQLITE_OMIT_REINDEX +void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){ + CollSeq *pColl; /* Collating sequence to be reindexed, or NULL */ + char *z; /* Name of a table or index */ + const char *zDb; /* Name of the database */ + Table *pTab; /* A table in the database */ + Index *pIndex; /* An index associated with pTab */ + int iDb; /* The database index number */ + sqlite3 *db = pParse->db; /* The database connection */ + Token *pObjName; /* Name of the table or index to be reindexed */ + + /* Read the database schema. If an error occurs, leave an error message + ** and code in pParse and return NULL. */ + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + return; + } + + if( pName1==0 ){ + reindexDatabases(pParse, 0); + return; + }else if( NEVER(pName2==0) || pName2->z==0 ){ + char *zColl; + assert( pName1->z ); + zColl = sqlite3NameFromToken(pParse->db, pName1); + if( !zColl ) return; + pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0); + if( pColl ){ + reindexDatabases(pParse, zColl); + sqlite3DbFree(db, zColl); + return; + } + sqlite3DbFree(db, zColl); + } + iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName); + if( iDb<0 ) return; + z = sqlite3NameFromToken(db, pObjName); + if( z==0 ) return; + zDb = db->aDb[iDb].zName; + pTab = sqlite3FindTable(db, z, zDb); + if( pTab ){ + reindexTable(pParse, pTab, 0); + sqlite3DbFree(db, z); + return; + } + pIndex = sqlite3FindIndex(db, z, zDb); + sqlite3DbFree(db, z); + if( pIndex ){ + sqlite3BeginWriteOperation(pParse, 0, iDb); + sqlite3RefillIndex(pParse, pIndex, -1); + return; + } + sqlite3ErrorMsg(pParse, "unable to identify the object to be reindexed"); +} +#endif + +/* +** Return a dynamicly allocated KeyInfo structure that can be used +** with OP_OpenRead or OP_OpenWrite to access database index pIdx. +** +** If successful, a pointer to the new structure is returned. In this case +** the caller is responsible for calling sqlite3DbFree(db, ) on the returned +** pointer. If an error occurs (out of memory or missing collation +** sequence), NULL is returned and the state of pParse updated to reflect +** the error. +*/ +KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){ + int i; + int nCol = pIdx->nColumn; + int nBytes = sizeof(KeyInfo) + (nCol-1)*sizeof(CollSeq*) + nCol; + sqlite3 *db = pParse->db; + KeyInfo *pKey = (KeyInfo *)sqlite3DbMallocZero(db, nBytes); + + if( pKey ){ + pKey->db = pParse->db; + pKey->aSortOrder = (u8 *)&(pKey->aColl[nCol]); + assert( &pKey->aSortOrder[nCol]==&(((u8 *)pKey)[nBytes]) ); + for(i=0; iazColl[i]; + assert( zColl ); + pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl); + pKey->aSortOrder[i] = pIdx->aSortOrder[i]; + } + pKey->nField = (u16)nCol; + } + + if( pParse->nErr ){ + sqlite3DbFree(db, pKey); + pKey = 0; + } + return pKey; +} diff --git a/scalos/libraries/sqlite/src/callback.c b/scalos/libraries/sqlite/src/callback.c new file mode 100644 index 000000000..ce849085c --- /dev/null +++ b/scalos/libraries/sqlite/src/callback.c @@ -0,0 +1,457 @@ +/* +** 2005 May 23 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains functions used to access the internal hash tables +** of user defined functions and collation sequences. +*/ + +#include "sqliteInt.h" + +/* +** Invoke the 'collation needed' callback to request a collation sequence +** in the encoding enc of name zName, length nName. +*/ +static void callCollNeeded(sqlite3 *db, int enc, const char *zName){ + assert( !db->xCollNeeded || !db->xCollNeeded16 ); + if( db->xCollNeeded ){ + char *zExternal = sqlite3DbStrDup(db, zName); + if( !zExternal ) return; + db->xCollNeeded(db->pCollNeededArg, db, enc, zExternal); + sqlite3DbFree(db, zExternal); + } +#ifndef SQLITE_OMIT_UTF16 + if( db->xCollNeeded16 ){ + char const *zExternal; + sqlite3_value *pTmp = sqlite3ValueNew(db); + sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC); + zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE); + if( zExternal ){ + db->xCollNeeded16(db->pCollNeededArg, db, (int)ENC(db), zExternal); + } + sqlite3ValueFree(pTmp); + } +#endif +} + +/* +** This routine is called if the collation factory fails to deliver a +** collation function in the best encoding but there may be other versions +** of this collation function (for other text encodings) available. Use one +** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if +** possible. +*/ +static int synthCollSeq(sqlite3 *db, CollSeq *pColl){ + CollSeq *pColl2; + char *z = pColl->zName; + int i; + static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 }; + for(i=0; i<3; i++){ + pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, 0); + if( pColl2->xCmp!=0 ){ + memcpy(pColl, pColl2, sizeof(CollSeq)); + pColl->xDel = 0; /* Do not copy the destructor */ + return SQLITE_OK; + } + } + return SQLITE_ERROR; +} + +/* +** This function is responsible for invoking the collation factory callback +** or substituting a collation sequence of a different encoding when the +** requested collation sequence is not available in the desired encoding. +** +** If it is not NULL, then pColl must point to the database native encoding +** collation sequence with name zName, length nName. +** +** The return value is either the collation sequence to be used in database +** db for collation type name zName, length nName, or NULL, if no collation +** sequence can be found. +** +** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq() +*/ +CollSeq *sqlite3GetCollSeq( + sqlite3* db, /* The database connection */ + u8 enc, /* The desired encoding for the collating sequence */ + CollSeq *pColl, /* Collating sequence with native encoding, or NULL */ + const char *zName /* Collating sequence name */ +){ + CollSeq *p; + + p = pColl; + if( !p ){ + p = sqlite3FindCollSeq(db, enc, zName, 0); + } + if( !p || !p->xCmp ){ + /* No collation sequence of this type for this encoding is registered. + ** Call the collation factory to see if it can supply us with one. + */ + callCollNeeded(db, enc, zName); + p = sqlite3FindCollSeq(db, enc, zName, 0); + } + if( p && !p->xCmp && synthCollSeq(db, p) ){ + p = 0; + } + assert( !p || p->xCmp ); + return p; +} + +/* +** This routine is called on a collation sequence before it is used to +** check that it is defined. An undefined collation sequence exists when +** a database is loaded that contains references to collation sequences +** that have not been defined by sqlite3_create_collation() etc. +** +** If required, this routine calls the 'collation needed' callback to +** request a definition of the collating sequence. If this doesn't work, +** an equivalent collating sequence that uses a text encoding different +** from the main database is substituted, if one is available. +*/ +int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){ + if( pColl ){ + const char *zName = pColl->zName; + sqlite3 *db = pParse->db; + CollSeq *p = sqlite3GetCollSeq(db, ENC(db), pColl, zName); + if( !p ){ + sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); + pParse->nErr++; + return SQLITE_ERROR; + } + assert( p==pColl ); + } + return SQLITE_OK; +} + + + +/* +** Locate and return an entry from the db.aCollSeq hash table. If the entry +** specified by zName and nName is not found and parameter 'create' is +** true, then create a new entry. Otherwise return NULL. +** +** Each pointer stored in the sqlite3.aCollSeq hash table contains an +** array of three CollSeq structures. The first is the collation sequence +** prefferred for UTF-8, the second UTF-16le, and the third UTF-16be. +** +** Stored immediately after the three collation sequences is a copy of +** the collation sequence name. A pointer to this string is stored in +** each collation sequence structure. +*/ +static CollSeq *findCollSeqEntry( + sqlite3 *db, /* Database connection */ + const char *zName, /* Name of the collating sequence */ + int create /* Create a new entry if true */ +){ + CollSeq *pColl; + int nName = sqlite3Strlen30(zName); + pColl = sqlite3HashFind(&db->aCollSeq, zName, nName); + + if( 0==pColl && create ){ + pColl = sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName + 1 ); + if( pColl ){ + CollSeq *pDel = 0; + pColl[0].zName = (char*)&pColl[3]; + pColl[0].enc = SQLITE_UTF8; + pColl[1].zName = (char*)&pColl[3]; + pColl[1].enc = SQLITE_UTF16LE; + pColl[2].zName = (char*)&pColl[3]; + pColl[2].enc = SQLITE_UTF16BE; + memcpy(pColl[0].zName, zName, nName); + pColl[0].zName[nName] = 0; + pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl); + + /* If a malloc() failure occurred in sqlite3HashInsert(), it will + ** return the pColl pointer to be deleted (because it wasn't added + ** to the hash table). + */ + assert( pDel==0 || pDel==pColl ); + if( pDel!=0 ){ + db->mallocFailed = 1; + sqlite3DbFree(db, pDel); + pColl = 0; + } + } + } + return pColl; +} + +/* +** Parameter zName points to a UTF-8 encoded string nName bytes long. +** Return the CollSeq* pointer for the collation sequence named zName +** for the encoding 'enc' from the database 'db'. +** +** If the entry specified is not found and 'create' is true, then create a +** new entry. Otherwise return NULL. +** +** A separate function sqlite3LocateCollSeq() is a wrapper around +** this routine. sqlite3LocateCollSeq() invokes the collation factory +** if necessary and generates an error message if the collating sequence +** cannot be found. +** +** See also: sqlite3LocateCollSeq(), sqlite3GetCollSeq() +*/ +CollSeq *sqlite3FindCollSeq( + sqlite3 *db, + u8 enc, + const char *zName, + int create +){ + CollSeq *pColl; + if( zName ){ + pColl = findCollSeqEntry(db, zName, create); + }else{ + pColl = db->pDfltColl; + } + assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 ); + assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE ); + if( pColl ) pColl += enc-1; + return pColl; +} + +/* During the search for the best function definition, this procedure +** is called to test how well the function passed as the first argument +** matches the request for a function with nArg arguments in a system +** that uses encoding enc. The value returned indicates how well the +** request is matched. A higher value indicates a better match. +** +** The returned value is always between 0 and 6, as follows: +** +** 0: Not a match, or if nArg<0 and the function is has no implementation. +** 1: A variable arguments function that prefers UTF-8 when a UTF-16 +** encoding is requested, or vice versa. +** 2: A variable arguments function that uses UTF-16BE when UTF-16LE is +** requested, or vice versa. +** 3: A variable arguments function using the same text encoding. +** 4: A function with the exact number of arguments requested that +** prefers UTF-8 when a UTF-16 encoding is requested, or vice versa. +** 5: A function with the exact number of arguments requested that +** prefers UTF-16LE when UTF-16BE is requested, or vice versa. +** 6: An exact match. +** +*/ +static int matchQuality(FuncDef *p, int nArg, u8 enc){ + int match = 0; + if( p->nArg==-1 || p->nArg==nArg + || (nArg==-1 && (p->xFunc!=0 || p->xStep!=0)) + ){ + match = 1; + if( p->nArg==nArg || nArg==-1 ){ + match = 4; + } + if( enc==p->iPrefEnc ){ + match += 2; + } + else if( (enc==SQLITE_UTF16LE && p->iPrefEnc==SQLITE_UTF16BE) || + (enc==SQLITE_UTF16BE && p->iPrefEnc==SQLITE_UTF16LE) ){ + match += 1; + } + } + return match; +} + +/* +** Search a FuncDefHash for a function with the given name. Return +** a pointer to the matching FuncDef if found, or 0 if there is no match. +*/ +static FuncDef *functionSearch( + FuncDefHash *pHash, /* Hash table to search */ + int h, /* Hash of the name */ + const char *zFunc, /* Name of function */ + int nFunc /* Number of bytes in zFunc */ +){ + FuncDef *p; + for(p=pHash->a[h]; p; p=p->pHash){ + if( sqlite3StrNICmp(p->zName, zFunc, nFunc)==0 && p->zName[nFunc]==0 ){ + return p; + } + } + return 0; +} + +/* +** Insert a new FuncDef into a FuncDefHash hash table. +*/ +void sqlite3FuncDefInsert( + FuncDefHash *pHash, /* The hash table into which to insert */ + FuncDef *pDef /* The function definition to insert */ +){ + FuncDef *pOther; + int nName = sqlite3Strlen30(pDef->zName); + u8 c1 = (u8)pDef->zName[0]; + int h = (sqlite3UpperToLower[c1] + nName) % ArraySize(pHash->a); + pOther = functionSearch(pHash, h, pDef->zName, nName); + if( pOther ){ + assert( pOther!=pDef && pOther->pNext!=pDef ); + pDef->pNext = pOther->pNext; + pOther->pNext = pDef; + }else{ + pDef->pNext = 0; + pDef->pHash = pHash->a[h]; + pHash->a[h] = pDef; + } +} + + + +/* +** Locate a user function given a name, a number of arguments and a flag +** indicating whether the function prefers UTF-16 over UTF-8. Return a +** pointer to the FuncDef structure that defines that function, or return +** NULL if the function does not exist. +** +** If the createFlag argument is true, then a new (blank) FuncDef +** structure is created and liked into the "db" structure if a +** no matching function previously existed. When createFlag is true +** and the nArg parameter is -1, then only a function that accepts +** any number of arguments will be returned. +** +** If createFlag is false and nArg is -1, then the first valid +** function found is returned. A function is valid if either xFunc +** or xStep is non-zero. +** +** If createFlag is false, then a function with the required name and +** number of arguments may be returned even if the eTextRep flag does not +** match that requested. +*/ +FuncDef *sqlite3FindFunction( + sqlite3 *db, /* An open database */ + const char *zName, /* Name of the function. Not null-terminated */ + int nName, /* Number of characters in the name */ + int nArg, /* Number of arguments. -1 means any number */ + u8 enc, /* Preferred text encoding */ + int createFlag /* Create new entry if true and does not otherwise exist */ +){ + FuncDef *p; /* Iterator variable */ + FuncDef *pBest = 0; /* Best match found so far */ + int bestScore = 0; /* Score of best match */ + int h; /* Hash value */ + + + assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); + h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % ArraySize(db->aFunc.a); + + /* First search for a match amongst the application-defined functions. + */ + p = functionSearch(&db->aFunc, h, zName, nName); + while( p ){ + int score = matchQuality(p, nArg, enc); + if( score>bestScore ){ + pBest = p; + bestScore = score; + } + p = p->pNext; + } + + /* If no match is found, search the built-in functions. + ** + ** If the SQLITE_PreferBuiltin flag is set, then search the built-in + ** functions even if a prior app-defined function was found. And give + ** priority to built-in functions. + ** + ** Except, if createFlag is true, that means that we are trying to + ** install a new function. Whatever FuncDef structure is returned it will + ** have fields overwritten with new information appropriate for the + ** new function. But the FuncDefs for built-in functions are read-only. + ** So we must not search for built-ins when creating a new function. + */ + if( !createFlag && (pBest==0 || (db->flags & SQLITE_PreferBuiltin)!=0) ){ + FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions); + bestScore = 0; + p = functionSearch(pHash, h, zName, nName); + while( p ){ + int score = matchQuality(p, nArg, enc); + if( score>bestScore ){ + pBest = p; + bestScore = score; + } + p = p->pNext; + } + } + + /* If the createFlag parameter is true and the search did not reveal an + ** exact match for the name, number of arguments and encoding, then add a + ** new entry to the hash table and return it. + */ + if( createFlag && (bestScore<6 || pBest->nArg!=nArg) && + (pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){ + pBest->zName = (char *)&pBest[1]; + pBest->nArg = (u16)nArg; + pBest->iPrefEnc = enc; + memcpy(pBest->zName, zName, nName); + pBest->zName[nName] = 0; + sqlite3FuncDefInsert(&db->aFunc, pBest); + } + + if( pBest && (pBest->xStep || pBest->xFunc || createFlag) ){ + return pBest; + } + return 0; +} + +/* +** Free all resources held by the schema structure. The void* argument points +** at a Schema struct. This function does not call sqlite3DbFree(db, ) on the +** pointer itself, it just cleans up subsidiary resources (i.e. the contents +** of the schema hash tables). +** +** The Schema.cache_size variable is not cleared. +*/ +void sqlite3SchemaClear(void *p){ + Hash temp1; + Hash temp2; + HashElem *pElem; + Schema *pSchema = (Schema *)p; + + temp1 = pSchema->tblHash; + temp2 = pSchema->trigHash; + sqlite3HashInit(&pSchema->trigHash); + sqlite3HashClear(&pSchema->idxHash); + for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){ + sqlite3DeleteTrigger(0, (Trigger*)sqliteHashData(pElem)); + } + sqlite3HashClear(&temp2); + sqlite3HashInit(&pSchema->tblHash); + for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){ + Table *pTab = sqliteHashData(pElem); + sqlite3DeleteTable(0, pTab); + } + sqlite3HashClear(&temp1); + sqlite3HashClear(&pSchema->fkeyHash); + pSchema->pSeqTab = 0; + if( pSchema->flags & DB_SchemaLoaded ){ + pSchema->iGeneration++; + pSchema->flags &= ~DB_SchemaLoaded; + } +} + +/* +** Find and return the schema associated with a BTree. Create +** a new one if necessary. +*/ +Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ + Schema * p; + if( pBt ){ + p = (Schema *)sqlite3BtreeSchema(pBt, sizeof(Schema), sqlite3SchemaClear); + }else{ + p = (Schema *)sqlite3DbMallocZero(0, sizeof(Schema)); + } + if( !p ){ + db->mallocFailed = 1; + }else if ( 0==p->file_format ){ + sqlite3HashInit(&p->tblHash); + sqlite3HashInit(&p->idxHash); + sqlite3HashInit(&p->trigHash); + sqlite3HashInit(&p->fkeyHash); + p->enc = SQLITE_UTF8; + } + return p; +} diff --git a/scalos/libraries/sqlite/src/complete.c b/scalos/libraries/sqlite/src/complete.c new file mode 100644 index 000000000..9e9140085 --- /dev/null +++ b/scalos/libraries/sqlite/src/complete.c @@ -0,0 +1,283 @@ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** An tokenizer for SQL +** +** This file contains C code that implements the sqlite3_complete() API. +** This code used to be part of the tokenizer.c source file. But by +** separating it out, the code will be automatically omitted from +** static links that do not use it. +*/ +#include "sqliteInt.h" +#ifndef SQLITE_OMIT_COMPLETE + +/* +** This is defined in tokenize.c. We just have to import the definition. +*/ +#ifndef SQLITE_AMALGAMATION +#ifdef SQLITE_ASCII +#define IdChar(C) ((sqlite3CtypeMap[(unsigned char)C]&0x46)!=0) +#endif +#ifdef SQLITE_EBCDIC +extern const char sqlite3IsEbcdicIdChar[]; +#define IdChar(C) (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40])) +#endif +#endif /* SQLITE_AMALGAMATION */ + + +/* +** Token types used by the sqlite3_complete() routine. See the header +** comments on that procedure for additional information. +*/ +#define tkSEMI 0 +#define tkWS 1 +#define tkOTHER 2 +#ifndef SQLITE_OMIT_TRIGGER +#define tkEXPLAIN 3 +#define tkCREATE 4 +#define tkTEMP 5 +#define tkTRIGGER 6 +#define tkEND 7 +#endif + +/* +** Return TRUE if the given SQL string ends in a semicolon. +** +** Special handling is require for CREATE TRIGGER statements. +** Whenever the CREATE TRIGGER keywords are seen, the statement +** must end with ";END;". +** +** This implementation uses a state machine with 8 states: +** +** (0) INVALID We have not yet seen a non-whitespace character. +** +** (1) START At the beginning or end of an SQL statement. This routine +** returns 1 if it ends in the START state and 0 if it ends +** in any other state. +** +** (2) NORMAL We are in the middle of statement which ends with a single +** semicolon. +** +** (3) EXPLAIN The keyword EXPLAIN has been seen at the beginning of +** a statement. +** +** (4) CREATE The keyword CREATE has been seen at the beginning of a +** statement, possibly preceeded by EXPLAIN and/or followed by +** TEMP or TEMPORARY +** +** (5) TRIGGER We are in the middle of a trigger definition that must be +** ended by a semicolon, the keyword END, and another semicolon. +** +** (6) SEMI We've seen the first semicolon in the ";END;" that occurs at +** the end of a trigger definition. +** +** (7) END We've seen the ";END" of the ";END;" that occurs at the end +** of a trigger difinition. +** +** Transitions between states above are determined by tokens extracted +** from the input. The following tokens are significant: +** +** (0) tkSEMI A semicolon. +** (1) tkWS Whitespace. +** (2) tkOTHER Any other SQL token. +** (3) tkEXPLAIN The "explain" keyword. +** (4) tkCREATE The "create" keyword. +** (5) tkTEMP The "temp" or "temporary" keyword. +** (6) tkTRIGGER The "trigger" keyword. +** (7) tkEND The "end" keyword. +** +** Whitespace never causes a state transition and is always ignored. +** This means that a SQL string of all whitespace is invalid. +** +** If we compile with SQLITE_OMIT_TRIGGER, all of the computation needed +** to recognize the end of a trigger can be omitted. All we have to do +** is look for a semicolon that is not part of an string or comment. +*/ +int sqlite3_complete(const char *zSql){ + u8 state = 0; /* Current state, using numbers defined in header comment */ + u8 token; /* Value of the next token */ + +#ifndef SQLITE_OMIT_TRIGGER + /* A complex statement machine used to detect the end of a CREATE TRIGGER + ** statement. This is the normal case. + */ + static const u8 trans[8][8] = { + /* Token: */ + /* State: ** SEMI WS OTHER EXPLAIN CREATE TEMP TRIGGER END */ + /* 0 INVALID: */ { 1, 0, 2, 3, 4, 2, 2, 2, }, + /* 1 START: */ { 1, 1, 2, 3, 4, 2, 2, 2, }, + /* 2 NORMAL: */ { 1, 2, 2, 2, 2, 2, 2, 2, }, + /* 3 EXPLAIN: */ { 1, 3, 3, 2, 4, 2, 2, 2, }, + /* 4 CREATE: */ { 1, 4, 2, 2, 2, 4, 5, 2, }, + /* 5 TRIGGER: */ { 6, 5, 5, 5, 5, 5, 5, 5, }, + /* 6 SEMI: */ { 6, 6, 5, 5, 5, 5, 5, 7, }, + /* 7 END: */ { 1, 7, 5, 5, 5, 5, 5, 5, }, + }; +#else + /* If triggers are not supported by this compile then the statement machine + ** used to detect the end of a statement is much simplier + */ + static const u8 trans[3][3] = { + /* Token: */ + /* State: ** SEMI WS OTHER */ + /* 0 INVALID: */ { 1, 0, 2, }, + /* 1 START: */ { 1, 1, 2, }, + /* 2 NORMAL: */ { 1, 2, 2, }, + }; +#endif /* SQLITE_OMIT_TRIGGER */ + + while( *zSql ){ + switch( *zSql ){ + case ';': { /* A semicolon */ + token = tkSEMI; + break; + } + case ' ': + case '\r': + case '\t': + case '\n': + case '\f': { /* White space is ignored */ + token = tkWS; + break; + } + case '/': { /* C-style comments */ + if( zSql[1]!='*' ){ + token = tkOTHER; + break; + } + zSql += 2; + while( zSql[0] && (zSql[0]!='*' || zSql[1]!='/') ){ zSql++; } + if( zSql[0]==0 ) return 0; + zSql++; + token = tkWS; + break; + } + case '-': { /* SQL-style comments from "--" to end of line */ + if( zSql[1]!='-' ){ + token = tkOTHER; + break; + } + while( *zSql && *zSql!='\n' ){ zSql++; } + if( *zSql==0 ) return state==1; + token = tkWS; + break; + } + case '[': { /* Microsoft-style identifiers in [...] */ + zSql++; + while( *zSql && *zSql!=']' ){ zSql++; } + if( *zSql==0 ) return 0; + token = tkOTHER; + break; + } + case '`': /* Grave-accent quoted symbols used by MySQL */ + case '"': /* single- and double-quoted strings */ + case '\'': { + int c = *zSql; + zSql++; + while( *zSql && *zSql!=c ){ zSql++; } + if( *zSql==0 ) return 0; + token = tkOTHER; + break; + } + default: { +#ifdef SQLITE_EBCDIC + unsigned char c; +#endif + if( IdChar((u8)*zSql) ){ + /* Keywords and unquoted identifiers */ + int nId; + for(nId=1; IdChar(zSql[nId]); nId++){} +#ifdef SQLITE_OMIT_TRIGGER + token = tkOTHER; +#else + switch( *zSql ){ + case 'c': case 'C': { + if( nId==6 && sqlite3StrNICmp(zSql, "create", 6)==0 ){ + token = tkCREATE; + }else{ + token = tkOTHER; + } + break; + } + case 't': case 'T': { + if( nId==7 && sqlite3StrNICmp(zSql, "trigger", 7)==0 ){ + token = tkTRIGGER; + }else if( nId==4 && sqlite3StrNICmp(zSql, "temp", 4)==0 ){ + token = tkTEMP; + }else if( nId==9 && sqlite3StrNICmp(zSql, "temporary", 9)==0 ){ + token = tkTEMP; + }else{ + token = tkOTHER; + } + break; + } + case 'e': case 'E': { + if( nId==3 && sqlite3StrNICmp(zSql, "end", 3)==0 ){ + token = tkEND; + }else +#ifndef SQLITE_OMIT_EXPLAIN + if( nId==7 && sqlite3StrNICmp(zSql, "explain", 7)==0 ){ + token = tkEXPLAIN; + }else +#endif + { + token = tkOTHER; + } + break; + } + default: { + token = tkOTHER; + break; + } + } +#endif /* SQLITE_OMIT_TRIGGER */ + zSql += nId-1; + }else{ + /* Operators and special symbols */ + token = tkOTHER; + } + break; + } + } + state = trans[state][token]; + zSql++; + } + return state==1; +} + +#ifndef SQLITE_OMIT_UTF16 +/* +** This routine is the same as the sqlite3_complete() routine described +** above, except that the parameter is required to be UTF-16 encoded, not +** UTF-8. +*/ +int sqlite3_complete16(const void *zSql){ + sqlite3_value *pVal; + char const *zSql8; + int rc = SQLITE_NOMEM; + +#ifndef SQLITE_OMIT_AUTOINIT + rc = sqlite3_initialize(); + if( rc ) return rc; +#endif + pVal = sqlite3ValueNew(0); + sqlite3ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC); + zSql8 = sqlite3ValueText(pVal, SQLITE_UTF8); + if( zSql8 ){ + rc = sqlite3_complete(zSql8); + }else{ + rc = SQLITE_NOMEM; + } + sqlite3ValueFree(pVal); + return sqlite3ApiExit(0, rc); +} +#endif /* SQLITE_OMIT_UTF16 */ +#endif /* SQLITE_OMIT_COMPLETE */ diff --git a/scalos/libraries/sqlite/src/ctime.c b/scalos/libraries/sqlite/src/ctime.c new file mode 100644 index 000000000..1688069cb --- /dev/null +++ b/scalos/libraries/sqlite/src/ctime.c @@ -0,0 +1,399 @@ +/* +** 2010 February 23 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file implements routines used to report what compile-time options +** SQLite was built with. +*/ + +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS + +#include "sqliteInt.h" + +/* +** An array of names of all compile-time options. This array should +** be sorted A-Z. +** +** This array looks large, but in a typical installation actually uses +** only a handful of compile-time options, so most times this array is usually +** rather short and uses little memory space. +*/ +static const char * const azCompileOpt[] = { + +/* These macros are provided to "stringify" the value of the define +** for those options in which the value is meaningful. */ +#define CTIMEOPT_VAL_(opt) #opt +#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt) + +#ifdef SQLITE_32BIT_ROWID + "32BIT_ROWID", +#endif +#ifdef SQLITE_4_BYTE_ALIGNED_MALLOC + "4_BYTE_ALIGNED_MALLOC", +#endif +#ifdef SQLITE_CASE_SENSITIVE_LIKE + "CASE_SENSITIVE_LIKE", +#endif +#ifdef SQLITE_CHECK_PAGES + "CHECK_PAGES", +#endif +#ifdef SQLITE_COVERAGE_TEST + "COVERAGE_TEST", +#endif +#ifdef SQLITE_DEBUG + "DEBUG", +#endif +#ifdef SQLITE_DEFAULT_LOCKING_MODE + "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE), +#endif +#ifdef SQLITE_DISABLE_DIRSYNC + "DISABLE_DIRSYNC", +#endif +#ifdef SQLITE_DISABLE_LFS + "DISABLE_LFS", +#endif +#ifdef SQLITE_ENABLE_ATOMIC_WRITE + "ENABLE_ATOMIC_WRITE", +#endif +#ifdef SQLITE_ENABLE_CEROD + "ENABLE_CEROD", +#endif +#ifdef SQLITE_ENABLE_COLUMN_METADATA + "ENABLE_COLUMN_METADATA", +#endif +#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT + "ENABLE_EXPENSIVE_ASSERT", +#endif +#ifdef SQLITE_ENABLE_FTS1 + "ENABLE_FTS1", +#endif +#ifdef SQLITE_ENABLE_FTS2 + "ENABLE_FTS2", +#endif +#ifdef SQLITE_ENABLE_FTS3 + "ENABLE_FTS3", +#endif +#ifdef SQLITE_ENABLE_FTS3_PARENTHESIS + "ENABLE_FTS3_PARENTHESIS", +#endif +#ifdef SQLITE_ENABLE_FTS4 + "ENABLE_FTS4", +#endif +#ifdef SQLITE_ENABLE_ICU + "ENABLE_ICU", +#endif +#ifdef SQLITE_ENABLE_IOTRACE + "ENABLE_IOTRACE", +#endif +#ifdef SQLITE_ENABLE_LOAD_EXTENSION + "ENABLE_LOAD_EXTENSION", +#endif +#ifdef SQLITE_ENABLE_LOCKING_STYLE + "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE), +#endif +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT + "ENABLE_MEMORY_MANAGEMENT", +#endif +#ifdef SQLITE_ENABLE_MEMSYS3 + "ENABLE_MEMSYS3", +#endif +#ifdef SQLITE_ENABLE_MEMSYS5 + "ENABLE_MEMSYS5", +#endif +#ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK + "ENABLE_OVERSIZE_CELL_CHECK", +#endif +#ifdef SQLITE_ENABLE_RTREE + "ENABLE_RTREE", +#endif +#ifdef SQLITE_ENABLE_STAT3 + "ENABLE_STAT3", +#endif +#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY + "ENABLE_UNLOCK_NOTIFY", +#endif +#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT + "ENABLE_UPDATE_DELETE_LIMIT", +#endif +#ifdef SQLITE_HAS_CODEC + "HAS_CODEC", +#endif +#ifdef SQLITE_HAVE_ISNAN + "HAVE_ISNAN", +#endif +#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX + "HOMEGROWN_RECURSIVE_MUTEX", +#endif +#ifdef SQLITE_IGNORE_AFP_LOCK_ERRORS + "IGNORE_AFP_LOCK_ERRORS", +#endif +#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS + "IGNORE_FLOCK_LOCK_ERRORS", +#endif +#ifdef SQLITE_INT64_TYPE + "INT64_TYPE", +#endif +#ifdef SQLITE_LOCK_TRACE + "LOCK_TRACE", +#endif +#ifdef SQLITE_MAX_SCHEMA_RETRY + "MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY), +#endif +#ifdef SQLITE_MEMDEBUG + "MEMDEBUG", +#endif +#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT + "MIXED_ENDIAN_64BIT_FLOAT", +#endif +#ifdef SQLITE_NO_SYNC + "NO_SYNC", +#endif +#ifdef SQLITE_OMIT_ALTERTABLE + "OMIT_ALTERTABLE", +#endif +#ifdef SQLITE_OMIT_ANALYZE + "OMIT_ANALYZE", +#endif +#ifdef SQLITE_OMIT_ATTACH + "OMIT_ATTACH", +#endif +#ifdef SQLITE_OMIT_AUTHORIZATION + "OMIT_AUTHORIZATION", +#endif +#ifdef SQLITE_OMIT_AUTOINCREMENT + "OMIT_AUTOINCREMENT", +#endif +#ifdef SQLITE_OMIT_AUTOINIT + "OMIT_AUTOINIT", +#endif +#ifdef SQLITE_OMIT_AUTOMATIC_INDEX + "OMIT_AUTOMATIC_INDEX", +#endif +#ifdef SQLITE_OMIT_AUTORESET + "OMIT_AUTORESET", +#endif +#ifdef SQLITE_OMIT_AUTOVACUUM + "OMIT_AUTOVACUUM", +#endif +#ifdef SQLITE_OMIT_BETWEEN_OPTIMIZATION + "OMIT_BETWEEN_OPTIMIZATION", +#endif +#ifdef SQLITE_OMIT_BLOB_LITERAL + "OMIT_BLOB_LITERAL", +#endif +#ifdef SQLITE_OMIT_BTREECOUNT + "OMIT_BTREECOUNT", +#endif +#ifdef SQLITE_OMIT_BUILTIN_TEST + "OMIT_BUILTIN_TEST", +#endif +#ifdef SQLITE_OMIT_CAST + "OMIT_CAST", +#endif +#ifdef SQLITE_OMIT_CHECK + "OMIT_CHECK", +#endif +/* // redundant +** #ifdef SQLITE_OMIT_COMPILEOPTION_DIAGS +** "OMIT_COMPILEOPTION_DIAGS", +** #endif +*/ +#ifdef SQLITE_OMIT_COMPLETE + "OMIT_COMPLETE", +#endif +#ifdef SQLITE_OMIT_COMPOUND_SELECT + "OMIT_COMPOUND_SELECT", +#endif +#ifdef SQLITE_OMIT_DATETIME_FUNCS + "OMIT_DATETIME_FUNCS", +#endif +#ifdef SQLITE_OMIT_DECLTYPE + "OMIT_DECLTYPE", +#endif +#ifdef SQLITE_OMIT_DEPRECATED + "OMIT_DEPRECATED", +#endif +#ifdef SQLITE_OMIT_DISKIO + "OMIT_DISKIO", +#endif +#ifdef SQLITE_OMIT_EXPLAIN + "OMIT_EXPLAIN", +#endif +#ifdef SQLITE_OMIT_FLAG_PRAGMAS + "OMIT_FLAG_PRAGMAS", +#endif +#ifdef SQLITE_OMIT_FLOATING_POINT + "OMIT_FLOATING_POINT", +#endif +#ifdef SQLITE_OMIT_FOREIGN_KEY + "OMIT_FOREIGN_KEY", +#endif +#ifdef SQLITE_OMIT_GET_TABLE + "OMIT_GET_TABLE", +#endif +#ifdef SQLITE_OMIT_INCRBLOB + "OMIT_INCRBLOB", +#endif +#ifdef SQLITE_OMIT_INTEGRITY_CHECK + "OMIT_INTEGRITY_CHECK", +#endif +#ifdef SQLITE_OMIT_LIKE_OPTIMIZATION + "OMIT_LIKE_OPTIMIZATION", +#endif +#ifdef SQLITE_OMIT_LOAD_EXTENSION + "OMIT_LOAD_EXTENSION", +#endif +#ifdef SQLITE_OMIT_LOCALTIME + "OMIT_LOCALTIME", +#endif +#ifdef SQLITE_OMIT_LOOKASIDE + "OMIT_LOOKASIDE", +#endif +#ifdef SQLITE_OMIT_MEMORYDB + "OMIT_MEMORYDB", +#endif +#ifdef SQLITE_OMIT_MERGE_SORT + "OMIT_MERGE_SORT", +#endif +#ifdef SQLITE_OMIT_OR_OPTIMIZATION + "OMIT_OR_OPTIMIZATION", +#endif +#ifdef SQLITE_OMIT_PAGER_PRAGMAS + "OMIT_PAGER_PRAGMAS", +#endif +#ifdef SQLITE_OMIT_PRAGMA + "OMIT_PRAGMA", +#endif +#ifdef SQLITE_OMIT_PROGRESS_CALLBACK + "OMIT_PROGRESS_CALLBACK", +#endif +#ifdef SQLITE_OMIT_QUICKBALANCE + "OMIT_QUICKBALANCE", +#endif +#ifdef SQLITE_OMIT_REINDEX + "OMIT_REINDEX", +#endif +#ifdef SQLITE_OMIT_SCHEMA_PRAGMAS + "OMIT_SCHEMA_PRAGMAS", +#endif +#ifdef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS + "OMIT_SCHEMA_VERSION_PRAGMAS", +#endif +#ifdef SQLITE_OMIT_SHARED_CACHE + "OMIT_SHARED_CACHE", +#endif +#ifdef SQLITE_OMIT_SUBQUERY + "OMIT_SUBQUERY", +#endif +#ifdef SQLITE_OMIT_TCL_VARIABLE + "OMIT_TCL_VARIABLE", +#endif +#ifdef SQLITE_OMIT_TEMPDB + "OMIT_TEMPDB", +#endif +#ifdef SQLITE_OMIT_TRACE + "OMIT_TRACE", +#endif +#ifdef SQLITE_OMIT_TRIGGER + "OMIT_TRIGGER", +#endif +#ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION + "OMIT_TRUNCATE_OPTIMIZATION", +#endif +#ifdef SQLITE_OMIT_UTF16 + "OMIT_UTF16", +#endif +#ifdef SQLITE_OMIT_VACUUM + "OMIT_VACUUM", +#endif +#ifdef SQLITE_OMIT_VIEW + "OMIT_VIEW", +#endif +#ifdef SQLITE_OMIT_VIRTUALTABLE + "OMIT_VIRTUALTABLE", +#endif +#ifdef SQLITE_OMIT_WAL + "OMIT_WAL", +#endif +#ifdef SQLITE_OMIT_WSD + "OMIT_WSD", +#endif +#ifdef SQLITE_OMIT_XFER_OPT + "OMIT_XFER_OPT", +#endif +#ifdef SQLITE_PERFORMANCE_TRACE + "PERFORMANCE_TRACE", +#endif +#ifdef SQLITE_PROXY_DEBUG + "PROXY_DEBUG", +#endif +#ifdef SQLITE_SECURE_DELETE + "SECURE_DELETE", +#endif +#ifdef SQLITE_SMALL_STACK + "SMALL_STACK", +#endif +#ifdef SQLITE_SOUNDEX + "SOUNDEX", +#endif +#ifdef SQLITE_TCL + "TCL", +#endif +#ifdef SQLITE_TEMP_STORE + "TEMP_STORE=" CTIMEOPT_VAL(SQLITE_TEMP_STORE), +#endif +#ifdef SQLITE_TEST + "TEST", +#endif +#ifdef SQLITE_THREADSAFE + "THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE), +#endif +#ifdef SQLITE_USE_ALLOCA + "USE_ALLOCA", +#endif +#ifdef SQLITE_ZERO_MALLOC + "ZERO_MALLOC" +#endif +}; + +/* +** Given the name of a compile-time option, return true if that option +** was used and false if not. +** +** The name can optionally begin with "SQLITE_" but the "SQLITE_" prefix +** is not required for a match. +*/ +int sqlite3_compileoption_used(const char *zOptName){ + int i, n; + if( sqlite3StrNICmp(zOptName, "SQLITE_", 7)==0 ) zOptName += 7; + n = sqlite3Strlen30(zOptName); + + /* Since ArraySize(azCompileOpt) is normally in single digits, a + ** linear search is adequate. No need for a binary search. */ + for(i=0; i=0 && N +#include +#include + +#ifndef SQLITE_OMIT_DATETIME_FUNCS + + +/* +** A structure for holding a single date and time. +*/ +typedef struct DateTime DateTime; +struct DateTime { + sqlite3_int64 iJD; /* The julian day number times 86400000 */ + int Y, M, D; /* Year, month, and day */ + int h, m; /* Hour and minutes */ + int tz; /* Timezone offset in minutes */ + double s; /* Seconds */ + char validYMD; /* True (1) if Y,M,D are valid */ + char validHMS; /* True (1) if h,m,s are valid */ + char validJD; /* True (1) if iJD is valid */ + char validTZ; /* True (1) if tz is valid */ +}; + + +/* +** Convert zDate into one or more integers. Additional arguments +** come in groups of 5 as follows: +** +** N number of digits in the integer +** min minimum allowed value of the integer +** max maximum allowed value of the integer +** nextC first character after the integer +** pVal where to write the integers value. +** +** Conversions continue until one with nextC==0 is encountered. +** The function returns the number of successful conversions. +*/ +static int getDigits(const char *zDate, ...){ + va_list ap; + int val; + int N; + int min; + int max; + int nextC; + int *pVal; + int cnt = 0; + va_start(ap, zDate); + do{ + N = va_arg(ap, int); + min = va_arg(ap, int); + max = va_arg(ap, int); + nextC = va_arg(ap, int); + pVal = va_arg(ap, int*); + val = 0; + while( N-- ){ + if( !sqlite3Isdigit(*zDate) ){ + goto end_getDigits; + } + val = val*10 + *zDate - '0'; + zDate++; + } + if( valmax || (nextC!=0 && nextC!=*zDate) ){ + goto end_getDigits; + } + *pVal = val; + zDate++; + cnt++; + }while( nextC ); +end_getDigits: + va_end(ap); + return cnt; +} + +/* +** Parse a timezone extension on the end of a date-time. +** The extension is of the form: +** +** (+/-)HH:MM +** +** Or the "zulu" notation: +** +** Z +** +** If the parse is successful, write the number of minutes +** of change in p->tz and return 0. If a parser error occurs, +** return non-zero. +** +** A missing specifier is not considered an error. +*/ +static int parseTimezone(const char *zDate, DateTime *p){ + int sgn = 0; + int nHr, nMn; + int c; + while( sqlite3Isspace(*zDate) ){ zDate++; } + p->tz = 0; + c = *zDate; + if( c=='-' ){ + sgn = -1; + }else if( c=='+' ){ + sgn = +1; + }else if( c=='Z' || c=='z' ){ + zDate++; + goto zulu_time; + }else{ + return c!=0; + } + zDate++; + if( getDigits(zDate, 2, 0, 14, ':', &nHr, 2, 0, 59, 0, &nMn)!=2 ){ + return 1; + } + zDate += 5; + p->tz = sgn*(nMn + nHr*60); +zulu_time: + while( sqlite3Isspace(*zDate) ){ zDate++; } + return *zDate!=0; +} + +/* +** Parse times of the form HH:MM or HH:MM:SS or HH:MM:SS.FFFF. +** The HH, MM, and SS must each be exactly 2 digits. The +** fractional seconds FFFF can be one or more digits. +** +** Return 1 if there is a parsing error and 0 on success. +*/ +static int parseHhMmSs(const char *zDate, DateTime *p){ + int h, m, s; + double ms = 0.0; + if( getDigits(zDate, 2, 0, 24, ':', &h, 2, 0, 59, 0, &m)!=2 ){ + return 1; + } + zDate += 5; + if( *zDate==':' ){ + zDate++; + if( getDigits(zDate, 2, 0, 59, 0, &s)!=1 ){ + return 1; + } + zDate += 2; + if( *zDate=='.' && sqlite3Isdigit(zDate[1]) ){ + double rScale = 1.0; + zDate++; + while( sqlite3Isdigit(*zDate) ){ + ms = ms*10.0 + *zDate - '0'; + rScale *= 10.0; + zDate++; + } + ms /= rScale; + } + }else{ + s = 0; + } + p->validJD = 0; + p->validHMS = 1; + p->h = h; + p->m = m; + p->s = s + ms; + if( parseTimezone(zDate, p) ) return 1; + p->validTZ = (p->tz!=0)?1:0; + return 0; +} + +/* +** Convert from YYYY-MM-DD HH:MM:SS to julian day. We always assume +** that the YYYY-MM-DD is according to the Gregorian calendar. +** +** Reference: Meeus page 61 +*/ +static void computeJD(DateTime *p){ + int Y, M, D, A, B, X1, X2; + + if( p->validJD ) return; + if( p->validYMD ){ + Y = p->Y; + M = p->M; + D = p->D; + }else{ + Y = 2000; /* If no YMD specified, assume 2000-Jan-01 */ + M = 1; + D = 1; + } + if( M<=2 ){ + Y--; + M += 12; + } + A = Y/100; + B = 2 - A + (A/4); + X1 = 36525*(Y+4716)/100; + X2 = 306001*(M+1)/10000; + p->iJD = (sqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000); + p->validJD = 1; + if( p->validHMS ){ + p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000); + if( p->validTZ ){ + p->iJD -= p->tz*60000; + p->validYMD = 0; + p->validHMS = 0; + p->validTZ = 0; + } + } +} + +/* +** Parse dates of the form +** +** YYYY-MM-DD HH:MM:SS.FFF +** YYYY-MM-DD HH:MM:SS +** YYYY-MM-DD HH:MM +** YYYY-MM-DD +** +** Write the result into the DateTime structure and return 0 +** on success and 1 if the input string is not a well-formed +** date. +*/ +static int parseYyyyMmDd(const char *zDate, DateTime *p){ + int Y, M, D, neg; + + if( zDate[0]=='-' ){ + zDate++; + neg = 1; + }else{ + neg = 0; + } + if( getDigits(zDate,4,0,9999,'-',&Y,2,1,12,'-',&M,2,1,31,0,&D)!=3 ){ + return 1; + } + zDate += 10; + while( sqlite3Isspace(*zDate) || 'T'==*(u8*)zDate ){ zDate++; } + if( parseHhMmSs(zDate, p)==0 ){ + /* We got the time */ + }else if( *zDate==0 ){ + p->validHMS = 0; + }else{ + return 1; + } + p->validJD = 0; + p->validYMD = 1; + p->Y = neg ? -Y : Y; + p->M = M; + p->D = D; + if( p->validTZ ){ + computeJD(p); + } + return 0; +} + +/* +** Set the time to the current time reported by the VFS. +** +** Return the number of errors. +*/ +static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){ + sqlite3 *db = sqlite3_context_db_handle(context); + if( sqlite3OsCurrentTimeInt64(db->pVfs, &p->iJD)==SQLITE_OK ){ + p->validJD = 1; + return 0; + }else{ + return 1; + } +} + +/* +** Attempt to parse the given string into a Julian Day Number. Return +** the number of errors. +** +** The following are acceptable forms for the input string: +** +** YYYY-MM-DD HH:MM:SS.FFF +/-HH:MM +** DDDD.DD +** now +** +** In the first form, the +/-HH:MM is always optional. The fractional +** seconds extension (the ".FFF") is optional. The seconds portion +** (":SS.FFF") is option. The year and date can be omitted as long +** as there is a time string. The time string can be omitted as long +** as there is a year and date. +*/ +static int parseDateOrTime( + sqlite3_context *context, + const char *zDate, + DateTime *p +){ + double r; + if( parseYyyyMmDd(zDate,p)==0 ){ + return 0; + }else if( parseHhMmSs(zDate, p)==0 ){ + return 0; + }else if( sqlite3StrICmp(zDate,"now")==0){ + return setDateTimeToCurrent(context, p); + }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){ + p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5); + p->validJD = 1; + return 0; + } + return 1; +} + +/* +** Compute the Year, Month, and Day from the julian day number. +*/ +static void computeYMD(DateTime *p){ + int Z, A, B, C, D, E, X1; + if( p->validYMD ) return; + if( !p->validJD ){ + p->Y = 2000; + p->M = 1; + p->D = 1; + }else{ + Z = (int)((p->iJD + 43200000)/86400000); + A = (int)((Z - 1867216.25)/36524.25); + A = Z + 1 + A - (A/4); + B = A + 1524; + C = (int)((B - 122.1)/365.25); + D = (36525*C)/100; + E = (int)((B-D)/30.6001); + X1 = (int)(30.6001*E); + p->D = B - D - X1; + p->M = E<14 ? E-1 : E-13; + p->Y = p->M>2 ? C - 4716 : C - 4715; + } + p->validYMD = 1; +} + +/* +** Compute the Hour, Minute, and Seconds from the julian day number. +*/ +static void computeHMS(DateTime *p){ + int s; + if( p->validHMS ) return; + computeJD(p); + s = (int)((p->iJD + 43200000) % 86400000); + p->s = s/1000.0; + s = (int)p->s; + p->s -= s; + p->h = s/3600; + s -= p->h*3600; + p->m = s/60; + p->s += s - p->m*60; + p->validHMS = 1; +} + +/* +** Compute both YMD and HMS +*/ +static void computeYMD_HMS(DateTime *p){ + computeYMD(p); + computeHMS(p); +} + +/* +** Clear the YMD and HMS and the TZ +*/ +static void clearYMD_HMS_TZ(DateTime *p){ + p->validYMD = 0; + p->validHMS = 0; + p->validTZ = 0; +} + +/* +** On recent Windows platforms, the localtime_s() function is available +** as part of the "Secure CRT". It is essentially equivalent to +** localtime_r() available under most POSIX platforms, except that the +** order of the parameters is reversed. +** +** See http://msdn.microsoft.com/en-us/library/a442x3ye(VS.80).aspx. +** +** If the user has not indicated to use localtime_r() or localtime_s() +** already, check for an MSVC build environment that provides +** localtime_s(). +*/ +#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S) && \ + defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE) +#define HAVE_LOCALTIME_S 1 +#endif + +#ifndef SQLITE_OMIT_LOCALTIME +/* +** The following routine implements the rough equivalent of localtime_r() +** using whatever operating-system specific localtime facility that +** is available. This routine returns 0 on success and +** non-zero on any kind of error. +** +** If the sqlite3GlobalConfig.bLocaltimeFault variable is true then this +** routine will always fail. +*/ +static int osLocaltime(time_t *t, struct tm *pTm){ + int rc; +#if (!defined(HAVE_LOCALTIME_R) || !HAVE_LOCALTIME_R) \ + && (!defined(HAVE_LOCALTIME_S) || !HAVE_LOCALTIME_S) + struct tm *pX; +#if SQLITE_THREADSAFE>0 + sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); +#endif + sqlite3_mutex_enter(mutex); + pX = localtime(t); +#ifndef SQLITE_OMIT_BUILTIN_TEST + if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0; +#endif + if( pX ) *pTm = *pX; + sqlite3_mutex_leave(mutex); + rc = pX==0; +#else +#ifndef SQLITE_OMIT_BUILTIN_TEST + if( sqlite3GlobalConfig.bLocaltimeFault ) return 1; +#endif +#if defined(HAVE_LOCALTIME_R) && HAVE_LOCALTIME_R + rc = localtime_r(t, pTm)==0; +#else + rc = localtime_s(pTm, t); +#endif /* HAVE_LOCALTIME_R */ +#endif /* HAVE_LOCALTIME_R || HAVE_LOCALTIME_S */ + return rc; +} +#endif /* SQLITE_OMIT_LOCALTIME */ + + +#ifndef SQLITE_OMIT_LOCALTIME +/* +** Compute the difference (in milliseconds) between localtime and UTC +** (a.k.a. GMT) for the time value p where p is in UTC. If no error occurs, +** return this value and set *pRc to SQLITE_OK. +** +** Or, if an error does occur, set *pRc to SQLITE_ERROR. The returned value +** is undefined in this case. +*/ +static sqlite3_int64 localtimeOffset( + DateTime *p, /* Date at which to calculate offset */ + sqlite3_context *pCtx, /* Write error here if one occurs */ + int *pRc /* OUT: Error code. SQLITE_OK or ERROR */ +){ + DateTime x, y; + time_t t; + struct tm sLocal; + + /* Initialize the contents of sLocal to avoid a compiler warning. */ + memset(&sLocal, 0, sizeof(sLocal)); + + x = *p; + computeYMD_HMS(&x); + if( x.Y<1971 || x.Y>=2038 ){ + x.Y = 2000; + x.M = 1; + x.D = 1; + x.h = 0; + x.m = 0; + x.s = 0.0; + } else { + int s = (int)(x.s + 0.5); + x.s = s; + } + x.tz = 0; + x.validJD = 0; + computeJD(&x); + t = (time_t)(x.iJD/1000 - 21086676*(i64)10000); + if( osLocaltime(&t, &sLocal) ){ + sqlite3_result_error(pCtx, "local time unavailable", -1); + *pRc = SQLITE_ERROR; + return 0; + } + y.Y = sLocal.tm_year + 1900; + y.M = sLocal.tm_mon + 1; + y.D = sLocal.tm_mday; + y.h = sLocal.tm_hour; + y.m = sLocal.tm_min; + y.s = sLocal.tm_sec; + y.validYMD = 1; + y.validHMS = 1; + y.validJD = 0; + y.validTZ = 0; + computeJD(&y); + *pRc = SQLITE_OK; + return y.iJD - x.iJD; +} +#endif /* SQLITE_OMIT_LOCALTIME */ + +/* +** Process a modifier to a date-time stamp. The modifiers are +** as follows: +** +** NNN days +** NNN hours +** NNN minutes +** NNN.NNNN seconds +** NNN months +** NNN years +** start of month +** start of year +** start of week +** start of day +** weekday N +** unixepoch +** localtime +** utc +** +** Return 0 on success and 1 if there is any kind of error. If the error +** is in a system call (i.e. localtime()), then an error message is written +** to context pCtx. If the error is an unrecognized modifier, no error is +** written to pCtx. +*/ +static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ + int rc = 1; + int n; + double r; + char *z, zBuf[30]; + z = zBuf; + for(n=0; niJD += localtimeOffset(p, pCtx, &rc); + clearYMD_HMS_TZ(p); + } + break; + } +#endif + case 'u': { + /* + ** unixepoch + ** + ** Treat the current value of p->iJD as the number of + ** seconds since 1970. Convert to a real julian day number. + */ + if( strcmp(z, "unixepoch")==0 && p->validJD ){ + p->iJD = (p->iJD + 43200)/86400 + 21086676*(i64)10000000; + clearYMD_HMS_TZ(p); + rc = 0; + } +#ifndef SQLITE_OMIT_LOCALTIME + else if( strcmp(z, "utc")==0 ){ + sqlite3_int64 c1; + computeJD(p); + c1 = localtimeOffset(p, pCtx, &rc); + if( rc==SQLITE_OK ){ + p->iJD -= c1; + clearYMD_HMS_TZ(p); + p->iJD += c1 - localtimeOffset(p, pCtx, &rc); + } + } +#endif + break; + } + case 'w': { + /* + ** weekday N + ** + ** Move the date to the same time on the next occurrence of + ** weekday N where 0==Sunday, 1==Monday, and so forth. If the + ** date is already on the appropriate weekday, this is a no-op. + */ + if( strncmp(z, "weekday ", 8)==0 + && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8) + && (n=(int)r)==r && n>=0 && r<7 ){ + sqlite3_int64 Z; + computeYMD_HMS(p); + p->validTZ = 0; + p->validJD = 0; + computeJD(p); + Z = ((p->iJD + 129600000)/86400000) % 7; + if( Z>n ) Z -= 7; + p->iJD += (n - Z)*86400000; + clearYMD_HMS_TZ(p); + rc = 0; + } + break; + } + case 's': { + /* + ** start of TTTTT + ** + ** Move the date backwards to the beginning of the current day, + ** or month or year. + */ + if( strncmp(z, "start of ", 9)!=0 ) break; + z += 9; + computeYMD(p); + p->validHMS = 1; + p->h = p->m = 0; + p->s = 0.0; + p->validTZ = 0; + p->validJD = 0; + if( strcmp(z,"month")==0 ){ + p->D = 1; + rc = 0; + }else if( strcmp(z,"year")==0 ){ + computeYMD(p); + p->M = 1; + p->D = 1; + rc = 0; + }else if( strcmp(z,"day")==0 ){ + rc = 0; + } + break; + } + case '+': + case '-': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': { + double rRounder; + for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){} + if( !sqlite3AtoF(z, &r, n, SQLITE_UTF8) ){ + rc = 1; + break; + } + if( z[n]==':' ){ + /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the + ** specified number of hours, minutes, seconds, and fractional seconds + ** to the time. The ".FFF" may be omitted. The ":SS.FFF" may be + ** omitted. + */ + const char *z2 = z; + DateTime tx; + sqlite3_int64 day; + if( !sqlite3Isdigit(*z2) ) z2++; + memset(&tx, 0, sizeof(tx)); + if( parseHhMmSs(z2, &tx) ) break; + computeJD(&tx); + tx.iJD -= 43200000; + day = tx.iJD/86400000; + tx.iJD -= day*86400000; + if( z[0]=='-' ) tx.iJD = -tx.iJD; + computeJD(p); + clearYMD_HMS_TZ(p); + p->iJD += tx.iJD; + rc = 0; + break; + } + z += n; + while( sqlite3Isspace(*z) ) z++; + n = sqlite3Strlen30(z); + if( n>10 || n<3 ) break; + if( z[n-1]=='s' ){ z[n-1] = 0; n--; } + computeJD(p); + rc = 0; + rRounder = r<0 ? -0.5 : +0.5; + if( n==3 && strcmp(z,"day")==0 ){ + p->iJD += (sqlite3_int64)(r*86400000.0 + rRounder); + }else if( n==4 && strcmp(z,"hour")==0 ){ + p->iJD += (sqlite3_int64)(r*(86400000.0/24.0) + rRounder); + }else if( n==6 && strcmp(z,"minute")==0 ){ + p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0)) + rRounder); + }else if( n==6 && strcmp(z,"second")==0 ){ + p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0*60.0)) + rRounder); + }else if( n==5 && strcmp(z,"month")==0 ){ + int x, y; + computeYMD_HMS(p); + p->M += (int)r; + x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12; + p->Y += x; + p->M -= x*12; + p->validJD = 0; + computeJD(p); + y = (int)r; + if( y!=r ){ + p->iJD += (sqlite3_int64)((r - y)*30.0*86400000.0 + rRounder); + } + }else if( n==4 && strcmp(z,"year")==0 ){ + int y = (int)r; + computeYMD_HMS(p); + p->Y += y; + p->validJD = 0; + computeJD(p); + if( y!=r ){ + p->iJD += (sqlite3_int64)((r - y)*365.0*86400000.0 + rRounder); + } + }else{ + rc = 1; + } + clearYMD_HMS_TZ(p); + break; + } + default: { + break; + } + } + return rc; +} + +/* +** Process time function arguments. argv[0] is a date-time stamp. +** argv[1] and following are modifiers. Parse them all and write +** the resulting time into the DateTime structure p. Return 0 +** on success and 1 if there are any errors. +** +** If there are zero parameters (if even argv[0] is undefined) +** then assume a default value of "now" for argv[0]. +*/ +static int isDate( + sqlite3_context *context, + int argc, + sqlite3_value **argv, + DateTime *p +){ + int i; + const unsigned char *z; + int eType; + memset(p, 0, sizeof(*p)); + if( argc==0 ){ + return setDateTimeToCurrent(context, p); + } + if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT + || eType==SQLITE_INTEGER ){ + p->iJD = (sqlite3_int64)(sqlite3_value_double(argv[0])*86400000.0 + 0.5); + p->validJD = 1; + }else{ + z = sqlite3_value_text(argv[0]); + if( !z || parseDateOrTime(context, (char*)z, p) ){ + return 1; + } + } + for(i=1; iaLimit[SQLITE_LIMIT_LENGTH]+1 ); + testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH] ); + if( n(u64)db->aLimit[SQLITE_LIMIT_LENGTH] ){ + sqlite3_result_error_toobig(context); + return; + }else{ + z = sqlite3DbMallocRaw(db, (int)n); + if( z==0 ){ + sqlite3_result_error_nomem(context); + return; + } + } + computeJD(&x); + computeYMD_HMS(&x); + for(i=j=0; zFmt[i]; i++){ + if( zFmt[i]!='%' ){ + z[j++] = zFmt[i]; + }else{ + i++; + switch( zFmt[i] ){ + case 'd': sqlite3_snprintf(3, &z[j],"%02d",x.D); j+=2; break; + case 'f': { + double s = x.s; + if( s>59.999 ) s = 59.999; + sqlite3_snprintf(7, &z[j],"%06.3f", s); + j += sqlite3Strlen30(&z[j]); + break; + } + case 'H': sqlite3_snprintf(3, &z[j],"%02d",x.h); j+=2; break; + case 'W': /* Fall thru */ + case 'j': { + int nDay; /* Number of days since 1st day of year */ + DateTime y = x; + y.validJD = 0; + y.M = 1; + y.D = 1; + computeJD(&y); + nDay = (int)((x.iJD-y.iJD+43200000)/86400000); + if( zFmt[i]=='W' ){ + int wd; /* 0=Monday, 1=Tuesday, ... 6=Sunday */ + wd = (int)(((x.iJD+43200000)/86400000)%7); + sqlite3_snprintf(3, &z[j],"%02d",(nDay+7-wd)/7); + j += 2; + }else{ + sqlite3_snprintf(4, &z[j],"%03d",nDay+1); + j += 3; + } + break; + } + case 'J': { + sqlite3_snprintf(20, &z[j],"%.16g",x.iJD/86400000.0); + j+=sqlite3Strlen30(&z[j]); + break; + } + case 'm': sqlite3_snprintf(3, &z[j],"%02d",x.M); j+=2; break; + case 'M': sqlite3_snprintf(3, &z[j],"%02d",x.m); j+=2; break; + case 's': { + sqlite3_snprintf(30,&z[j],"%lld", + (i64)(x.iJD/1000 - 21086676*(i64)10000)); + j += sqlite3Strlen30(&z[j]); + break; + } + case 'S': sqlite3_snprintf(3,&z[j],"%02d",(int)x.s); j+=2; break; + case 'w': { + z[j++] = (char)(((x.iJD+129600000)/86400000) % 7) + '0'; + break; + } + case 'Y': { + sqlite3_snprintf(5,&z[j],"%04d",x.Y); j+=sqlite3Strlen30(&z[j]); + break; + } + default: z[j++] = '%'; break; + } + } + } + z[j] = 0; + sqlite3_result_text(context, z, -1, + z==zBuf ? SQLITE_TRANSIENT : SQLITE_DYNAMIC); +} + +/* +** current_time() +** +** This function returns the same value as time('now'). +*/ +static void ctimeFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **NotUsed2 +){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + timeFunc(context, 0, 0); +} + +/* +** current_date() +** +** This function returns the same value as date('now'). +*/ +static void cdateFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **NotUsed2 +){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + dateFunc(context, 0, 0); +} + +/* +** current_timestamp() +** +** This function returns the same value as datetime('now'). +*/ +static void ctimestampFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **NotUsed2 +){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + datetimeFunc(context, 0, 0); +} +#endif /* !defined(SQLITE_OMIT_DATETIME_FUNCS) */ + +#ifdef SQLITE_OMIT_DATETIME_FUNCS +/* +** If the library is compiled to omit the full-scale date and time +** handling (to get a smaller binary), the following minimal version +** of the functions current_time(), current_date() and current_timestamp() +** are included instead. This is to support column declarations that +** include "DEFAULT CURRENT_TIME" etc. +** +** This function uses the C-library functions time(), gmtime() +** and strftime(). The format string to pass to strftime() is supplied +** as the user-data for the function. +*/ +static void currentTimeFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + time_t t; + char *zFormat = (char *)sqlite3_user_data(context); + sqlite3 *db; + sqlite3_int64 iT; + struct tm *pTm; + struct tm sNow; + char zBuf[20]; + + UNUSED_PARAMETER(argc); + UNUSED_PARAMETER(argv); + + db = sqlite3_context_db_handle(context); + if( sqlite3OsCurrentTimeInt64(db->pVfs, &iT) ) return; + t = iT/1000 - 10000*(sqlite3_int64)21086676; +#ifdef HAVE_GMTIME_R + pTm = gmtime_r(&t, &sNow); +#else + sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); + pTm = gmtime(&t); + if( pTm ) memcpy(&sNow, pTm, sizeof(sNow)); + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); +#endif + if( pTm ){ + strftime(zBuf, 20, zFormat, &sNow); + sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); + } +} +#endif + +/* +** This function registered all of the above C functions as SQL +** functions. This should be the only routine in this file with +** external linkage. +*/ +void sqlite3RegisterDateTimeFunctions(void){ + static SQLITE_WSD FuncDef aDateTimeFuncs[] = { +#ifndef SQLITE_OMIT_DATETIME_FUNCS + FUNCTION(julianday, -1, 0, 0, juliandayFunc ), + FUNCTION(date, -1, 0, 0, dateFunc ), + FUNCTION(time, -1, 0, 0, timeFunc ), + FUNCTION(datetime, -1, 0, 0, datetimeFunc ), + FUNCTION(strftime, -1, 0, 0, strftimeFunc ), + FUNCTION(current_time, 0, 0, 0, ctimeFunc ), + FUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc), + FUNCTION(current_date, 0, 0, 0, cdateFunc ), +#else + STR_FUNCTION(current_time, 0, "%H:%M:%S", 0, currentTimeFunc), + STR_FUNCTION(current_date, 0, "%Y-%m-%d", 0, currentTimeFunc), + STR_FUNCTION(current_timestamp, 0, "%Y-%m-%d %H:%M:%S", 0, currentTimeFunc), +#endif + }; + int i; + FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions); + FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aDateTimeFuncs); + + for(i=0; ia[0].pTab Pointer to the Table object +** pSrc->a[0].pIndex Pointer to the INDEXED BY index, if there is one +** +*/ +Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ + struct SrcList_item *pItem = pSrc->a; + Table *pTab; + assert( pItem && pSrc->nSrc==1 ); + pTab = sqlite3LocateTable(pParse, 0, pItem->zName, pItem->zDatabase); + sqlite3DeleteTable(pParse->db, pItem->pTab); + pItem->pTab = pTab; + if( pTab ){ + pTab->nRef++; + } + if( sqlite3IndexedByLookup(pParse, pItem) ){ + pTab = 0; + } + return pTab; +} + +/* +** Check to make sure the given table is writable. If it is not +** writable, generate an error message and return 1. If it is +** writable return 0; +*/ +int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){ + /* A table is not writable under the following circumstances: + ** + ** 1) It is a virtual table and no implementation of the xUpdate method + ** has been provided, or + ** 2) It is a system table (i.e. sqlite_master), this call is not + ** part of a nested parse and writable_schema pragma has not + ** been specified. + ** + ** In either case leave an error message in pParse and return non-zero. + */ + if( ( IsVirtual(pTab) + && sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 ) + || ( (pTab->tabFlags & TF_Readonly)!=0 + && (pParse->db->flags & SQLITE_WriteSchema)==0 + && pParse->nested==0 ) + ){ + sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName); + return 1; + } + +#ifndef SQLITE_OMIT_VIEW + if( !viewOk && pTab->pSelect ){ + sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName); + return 1; + } +#endif + return 0; +} + + +#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) +/* +** Evaluate a view and store its result in an ephemeral table. The +** pWhere argument is an optional WHERE clause that restricts the +** set of rows in the view that are to be added to the ephemeral table. +*/ +void sqlite3MaterializeView( + Parse *pParse, /* Parsing context */ + Table *pView, /* View definition */ + Expr *pWhere, /* Optional WHERE clause to be added */ + int iCur /* Cursor number for ephemerial table */ +){ + SelectDest dest; + Select *pDup; + sqlite3 *db = pParse->db; + + pDup = sqlite3SelectDup(db, pView->pSelect, 0); + if( pWhere ){ + SrcList *pFrom; + + pWhere = sqlite3ExprDup(db, pWhere, 0); + pFrom = sqlite3SrcListAppend(db, 0, 0, 0); + if( pFrom ){ + assert( pFrom->nSrc==1 ); + pFrom->a[0].zAlias = sqlite3DbStrDup(db, pView->zName); + pFrom->a[0].pSelect = pDup; + assert( pFrom->a[0].pOn==0 ); + assert( pFrom->a[0].pUsing==0 ); + }else{ + sqlite3SelectDelete(db, pDup); + } + pDup = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 0, 0, 0); + } + sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur); + sqlite3Select(pParse, pDup, &dest); + sqlite3SelectDelete(db, pDup); +} +#endif /* !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) */ + +#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) +/* +** Generate an expression tree to implement the WHERE, ORDER BY, +** and LIMIT/OFFSET portion of DELETE and UPDATE statements. +** +** DELETE FROM table_wxyz WHERE a<5 ORDER BY a LIMIT 1; +** \__________________________/ +** pLimitWhere (pInClause) +*/ +Expr *sqlite3LimitWhere( + Parse *pParse, /* The parser context */ + SrcList *pSrc, /* the FROM clause -- which tables to scan */ + Expr *pWhere, /* The WHERE clause. May be null */ + ExprList *pOrderBy, /* The ORDER BY clause. May be null */ + Expr *pLimit, /* The LIMIT clause. May be null */ + Expr *pOffset, /* The OFFSET clause. May be null */ + char *zStmtType /* Either DELETE or UPDATE. For error messages. */ +){ + Expr *pWhereRowid = NULL; /* WHERE rowid .. */ + Expr *pInClause = NULL; /* WHERE rowid IN ( select ) */ + Expr *pSelectRowid = NULL; /* SELECT rowid ... */ + ExprList *pEList = NULL; /* Expression list contaning only pSelectRowid */ + SrcList *pSelectSrc = NULL; /* SELECT rowid FROM x ... (dup of pSrc) */ + Select *pSelect = NULL; /* Complete SELECT tree */ + + /* Check that there isn't an ORDER BY without a LIMIT clause. + */ + if( pOrderBy && (pLimit == 0) ) { + sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType); + goto limit_where_cleanup_2; + } + + /* We only need to generate a select expression if there + ** is a limit/offset term to enforce. + */ + if( pLimit == 0 ) { + /* if pLimit is null, pOffset will always be null as well. */ + assert( pOffset == 0 ); + return pWhere; + } + + /* Generate a select expression tree to enforce the limit/offset + ** term for the DELETE or UPDATE statement. For example: + ** DELETE FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1 + ** becomes: + ** DELETE FROM table_a WHERE rowid IN ( + ** SELECT rowid FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1 + ** ); + */ + + pSelectRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0); + if( pSelectRowid == 0 ) goto limit_where_cleanup_2; + pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid); + if( pEList == 0 ) goto limit_where_cleanup_2; + + /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree + ** and the SELECT subtree. */ + pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0); + if( pSelectSrc == 0 ) { + sqlite3ExprListDelete(pParse->db, pEList); + goto limit_where_cleanup_2; + } + + /* generate the SELECT expression tree. */ + pSelect = sqlite3SelectNew(pParse,pEList,pSelectSrc,pWhere,0,0, + pOrderBy,0,pLimit,pOffset); + if( pSelect == 0 ) return 0; + + /* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */ + pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0); + if( pWhereRowid == 0 ) goto limit_where_cleanup_1; + pInClause = sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0); + if( pInClause == 0 ) goto limit_where_cleanup_1; + + pInClause->x.pSelect = pSelect; + pInClause->flags |= EP_xIsSelect; + sqlite3ExprSetHeight(pParse, pInClause); + return pInClause; + + /* something went wrong. clean up anything allocated. */ +limit_where_cleanup_1: + sqlite3SelectDelete(pParse->db, pSelect); + return 0; + +limit_where_cleanup_2: + sqlite3ExprDelete(pParse->db, pWhere); + sqlite3ExprListDelete(pParse->db, pOrderBy); + sqlite3ExprDelete(pParse->db, pLimit); + sqlite3ExprDelete(pParse->db, pOffset); + return 0; +} +#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */ + +/* +** Generate code for a DELETE FROM statement. +** +** DELETE FROM table_wxyz WHERE a<5 AND b NOT NULL; +** \________/ \________________/ +** pTabList pWhere +*/ +void sqlite3DeleteFrom( + Parse *pParse, /* The parser context */ + SrcList *pTabList, /* The table from which we should delete things */ + Expr *pWhere /* The WHERE clause. May be null */ +){ + Vdbe *v; /* The virtual database engine */ + Table *pTab; /* The table from which records will be deleted */ + const char *zDb; /* Name of database holding pTab */ + int end, addr = 0; /* A couple addresses of generated code */ + int i; /* Loop counter */ + WhereInfo *pWInfo; /* Information about the WHERE clause */ + Index *pIdx; /* For looping over indices of the table */ + int iCur; /* VDBE Cursor number for pTab */ + sqlite3 *db; /* Main database structure */ + AuthContext sContext; /* Authorization context */ + NameContext sNC; /* Name context to resolve expressions in */ + int iDb; /* Database number */ + int memCnt = -1; /* Memory cell used for change counting */ + int rcauth; /* Value returned by authorization callback */ + +#ifndef SQLITE_OMIT_TRIGGER + int isView; /* True if attempting to delete from a view */ + Trigger *pTrigger; /* List of table triggers, if required */ +#endif + + memset(&sContext, 0, sizeof(sContext)); + db = pParse->db; + if( pParse->nErr || db->mallocFailed ){ + goto delete_from_cleanup; + } + assert( pTabList->nSrc==1 ); + + /* Locate the table which we want to delete. This table has to be + ** put in an SrcList structure because some of the subroutines we + ** will be calling are designed to work with multiple tables and expect + ** an SrcList* parameter instead of just a Table* parameter. + */ + pTab = sqlite3SrcListLookup(pParse, pTabList); + if( pTab==0 ) goto delete_from_cleanup; + + /* Figure out if we have any triggers and if the table being + ** deleted from is a view + */ +#ifndef SQLITE_OMIT_TRIGGER + pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); + isView = pTab->pSelect!=0; +#else +# define pTrigger 0 +# define isView 0 +#endif +#ifdef SQLITE_OMIT_VIEW +# undef isView +# define isView 0 +#endif + + /* If pTab is really a view, make sure it has been initialized. + */ + if( sqlite3ViewGetColumnNames(pParse, pTab) ){ + goto delete_from_cleanup; + } + + if( sqlite3IsReadOnly(pParse, pTab, (pTrigger?1:0)) ){ + goto delete_from_cleanup; + } + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iDbnDb ); + zDb = db->aDb[iDb].zName; + rcauth = sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb); + assert( rcauth==SQLITE_OK || rcauth==SQLITE_DENY || rcauth==SQLITE_IGNORE ); + if( rcauth==SQLITE_DENY ){ + goto delete_from_cleanup; + } + assert(!isView || pTrigger); + + /* Assign cursor number to the table and all its indices. + */ + assert( pTabList->nSrc==1 ); + iCur = pTabList->a[0].iCursor = pParse->nTab++; + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + pParse->nTab++; + } + + /* Start the view context + */ + if( isView ){ + sqlite3AuthContextPush(pParse, &sContext, pTab->zName); + } + + /* Begin generating code. + */ + v = sqlite3GetVdbe(pParse); + if( v==0 ){ + goto delete_from_cleanup; + } + if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); + sqlite3BeginWriteOperation(pParse, 1, iDb); + + /* If we are trying to delete from a view, realize that view into + ** a ephemeral table. + */ +#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) + if( isView ){ + sqlite3MaterializeView(pParse, pTab, pWhere, iCur); + } +#endif + + /* Resolve the column names in the WHERE clause. + */ + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + sNC.pSrcList = pTabList; + if( sqlite3ResolveExprNames(&sNC, pWhere) ){ + goto delete_from_cleanup; + } + + /* Initialize the counter of the number of rows deleted, if + ** we are counting rows. + */ + if( db->flags & SQLITE_CountRows ){ + memCnt = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt); + } + +#ifndef SQLITE_OMIT_TRUNCATE_OPTIMIZATION + /* Special case: A DELETE without a WHERE clause deletes everything. + ** It is easier just to erase the whole table. Prior to version 3.6.5, + ** this optimization caused the row change count (the value returned by + ** API function sqlite3_count_changes) to be set incorrectly. */ + if( rcauth==SQLITE_OK && pWhere==0 && !pTrigger && !IsVirtual(pTab) + && 0==sqlite3FkRequired(pParse, pTab, 0, 0) + ){ + assert( !isView ); + sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt, + pTab->zName, P4_STATIC); + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + assert( pIdx->pSchema==pTab->pSchema ); + sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb); + } + }else +#endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */ + /* The usual case: There is a WHERE clause so we have to scan through + ** the table and pick which records to delete. + */ + { + int iRowSet = ++pParse->nMem; /* Register for rowset of rows to delete */ + int iRowid = ++pParse->nMem; /* Used for storing rowid values. */ + int regRowid; /* Actual register containing rowids */ + + /* Collect rowids of every row to be deleted. + */ + sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet); + pWInfo = sqlite3WhereBegin( + pParse, pTabList, pWhere, 0, 0, WHERE_DUPLICATES_OK + ); + if( pWInfo==0 ) goto delete_from_cleanup; + regRowid = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iCur, iRowid); + sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, regRowid); + if( db->flags & SQLITE_CountRows ){ + sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1); + } + sqlite3WhereEnd(pWInfo); + + /* Delete every item whose key was written to the list during the + ** database scan. We have to delete items after the scan is complete + ** because deleting an item can change the scan order. */ + end = sqlite3VdbeMakeLabel(v); + + /* Unless this is a view, open cursors for the table we are + ** deleting from and all its indices. If this is a view, then the + ** only effect this statement has is to fire the INSTEAD OF + ** triggers. */ + if( !isView ){ + sqlite3OpenTableAndIndices(pParse, pTab, iCur, OP_OpenWrite); + } + + addr = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, end, iRowid); + + /* Delete the row */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); + sqlite3VtabMakeWritable(pParse, pTab); + sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iRowid, pVTab, P4_VTAB); + sqlite3VdbeChangeP5(v, OE_Abort); + sqlite3MayAbort(pParse); + }else +#endif + { + int count = (pParse->nested==0); /* True to count changes */ + sqlite3GenerateRowDelete(pParse, pTab, iCur, iRowid, count, pTrigger, OE_Default); + } + + /* End of the delete loop */ + sqlite3VdbeAddOp2(v, OP_Goto, 0, addr); + sqlite3VdbeResolveLabel(v, end); + + /* Close the cursors open on the table and its indexes. */ + if( !isView && !IsVirtual(pTab) ){ + for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ + sqlite3VdbeAddOp2(v, OP_Close, iCur + i, pIdx->tnum); + } + sqlite3VdbeAddOp1(v, OP_Close, iCur); + } + } + + /* Update the sqlite_sequence table by storing the content of the + ** maximum rowid counter values recorded while inserting into + ** autoincrement tables. + */ + if( pParse->nested==0 && pParse->pTriggerTab==0 ){ + sqlite3AutoincrementEnd(pParse); + } + + /* Return the number of rows that were deleted. If this routine is + ** generating code because of a call to sqlite3NestedParse(), do not + ** invoke the callback function. + */ + if( (db->flags&SQLITE_CountRows) && !pParse->nested && !pParse->pTriggerTab ){ + sqlite3VdbeAddOp2(v, OP_ResultRow, memCnt, 1); + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC); + } + +delete_from_cleanup: + sqlite3AuthContextPop(&sContext); + sqlite3SrcListDelete(db, pTabList); + sqlite3ExprDelete(db, pWhere); + return; +} +/* Make sure "isView" and other macros defined above are undefined. Otherwise +** thely may interfere with compilation of other functions in this file +** (or in another file, if this file becomes part of the amalgamation). */ +#ifdef isView + #undef isView +#endif +#ifdef pTrigger + #undef pTrigger +#endif + +/* +** This routine generates VDBE code that causes a single row of a +** single table to be deleted. +** +** The VDBE must be in a particular state when this routine is called. +** These are the requirements: +** +** 1. A read/write cursor pointing to pTab, the table containing the row +** to be deleted, must be opened as cursor number $iCur. +** +** 2. Read/write cursors for all indices of pTab must be open as +** cursor number base+i for the i-th index. +** +** 3. The record number of the row to be deleted must be stored in +** memory cell iRowid. +** +** This routine generates code to remove both the table record and all +** index entries that point to that record. +*/ +void sqlite3GenerateRowDelete( + Parse *pParse, /* Parsing context */ + Table *pTab, /* Table containing the row to be deleted */ + int iCur, /* Cursor number for the table */ + int iRowid, /* Memory cell that contains the rowid to delete */ + int count, /* If non-zero, increment the row change counter */ + Trigger *pTrigger, /* List of triggers to (potentially) fire */ + int onconf /* Default ON CONFLICT policy for triggers */ +){ + Vdbe *v = pParse->pVdbe; /* Vdbe */ + int iOld = 0; /* First register in OLD.* array */ + int iLabel; /* Label resolved to end of generated code */ + + /* Vdbe is guaranteed to have been allocated by this stage. */ + assert( v ); + + /* Seek cursor iCur to the row to delete. If this row no longer exists + ** (this can happen if a trigger program has already deleted it), do + ** not attempt to delete it or fire any DELETE triggers. */ + iLabel = sqlite3VdbeMakeLabel(v); + sqlite3VdbeAddOp3(v, OP_NotExists, iCur, iLabel, iRowid); + + /* If there are any triggers to fire, allocate a range of registers to + ** use for the old.* references in the triggers. */ + if( sqlite3FkRequired(pParse, pTab, 0, 0) || pTrigger ){ + u32 mask; /* Mask of OLD.* columns in use */ + int iCol; /* Iterator used while populating OLD.* */ + + /* TODO: Could use temporary registers here. Also could attempt to + ** avoid copying the contents of the rowid register. */ + mask = sqlite3TriggerColmask( + pParse, pTrigger, 0, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onconf + ); + mask |= sqlite3FkOldmask(pParse, pTab); + iOld = pParse->nMem+1; + pParse->nMem += (1 + pTab->nCol); + + /* Populate the OLD.* pseudo-table register array. These values will be + ** used by any BEFORE and AFTER triggers that exist. */ + sqlite3VdbeAddOp2(v, OP_Copy, iRowid, iOld); + for(iCol=0; iColnCol; iCol++){ + if( mask==0xffffffff || mask&(1<pSelect==0 ){ + sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, 0); + sqlite3VdbeAddOp2(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0)); + if( count ){ + sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT); + } + } + + /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to + ** handle rows (possibly in other tables) that refer via a foreign key + ** to the row just deleted. */ + sqlite3FkActions(pParse, pTab, 0, iOld); + + /* Invoke AFTER DELETE trigger programs. */ + sqlite3CodeRowTrigger(pParse, pTrigger, + TK_DELETE, 0, TRIGGER_AFTER, pTab, iOld, onconf, iLabel + ); + + /* Jump here if the row had already been deleted before any BEFORE + ** trigger programs were invoked. Or if a trigger program throws a + ** RAISE(IGNORE) exception. */ + sqlite3VdbeResolveLabel(v, iLabel); +} + +/* +** This routine generates VDBE code that causes the deletion of all +** index entries associated with a single row of a single table. +** +** The VDBE must be in a particular state when this routine is called. +** These are the requirements: +** +** 1. A read/write cursor pointing to pTab, the table containing the row +** to be deleted, must be opened as cursor number "iCur". +** +** 2. Read/write cursors for all indices of pTab must be open as +** cursor number iCur+i for the i-th index. +** +** 3. The "iCur" cursor must be pointing to the row that is to be +** deleted. +*/ +void sqlite3GenerateRowIndexDelete( + Parse *pParse, /* Parsing and code generating context */ + Table *pTab, /* Table containing the row to be deleted */ + int iCur, /* Cursor number for the table */ + int *aRegIdx /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */ +){ + int i; + Index *pIdx; + int r1; + + for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ + if( aRegIdx!=0 && aRegIdx[i-1]==0 ) continue; + r1 = sqlite3GenerateIndexKey(pParse, pIdx, iCur, 0, 0); + sqlite3VdbeAddOp3(pParse->pVdbe, OP_IdxDelete, iCur+i, r1,pIdx->nColumn+1); + } +} + +/* +** Generate code that will assemble an index key and put it in register +** regOut. The key with be for index pIdx which is an index on pTab. +** iCur is the index of a cursor open on the pTab table and pointing to +** the entry that needs indexing. +** +** Return a register number which is the first in a block of +** registers that holds the elements of the index key. The +** block of registers has already been deallocated by the time +** this routine returns. +*/ +int sqlite3GenerateIndexKey( + Parse *pParse, /* Parsing context */ + Index *pIdx, /* The index for which to generate a key */ + int iCur, /* Cursor number for the pIdx->pTable table */ + int regOut, /* Write the new index key to this register */ + int doMakeRec /* Run the OP_MakeRecord instruction if true */ +){ + Vdbe *v = pParse->pVdbe; + int j; + Table *pTab = pIdx->pTable; + int regBase; + int nCol; + + nCol = pIdx->nColumn; + regBase = sqlite3GetTempRange(pParse, nCol+1); + sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regBase+nCol); + for(j=0; jaiColumn[j]; + if( idx==pTab->iPKey ){ + sqlite3VdbeAddOp2(v, OP_SCopy, regBase+nCol, regBase+j); + }else{ + sqlite3VdbeAddOp3(v, OP_Column, iCur, idx, regBase+j); + sqlite3ColumnDefault(v, pTab, idx, -1); + } + } + if( doMakeRec ){ + const char *zAff; + if( pTab->pSelect || (pParse->db->flags & SQLITE_IdxRealAsInt)!=0 ){ + zAff = 0; + }else{ + zAff = sqlite3IndexAffinityStr(v, pIdx); + } + sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol+1, regOut); + sqlite3VdbeChangeP4(v, -1, zAff, P4_TRANSIENT); + } + sqlite3ReleaseTempRange(pParse, regBase, nCol+1); + return regBase; +} diff --git a/scalos/libraries/sqlite/src/expr.c b/scalos/libraries/sqlite/src/expr.c new file mode 100644 index 000000000..22643ff33 --- /dev/null +++ b/scalos/libraries/sqlite/src/expr.c @@ -0,0 +1,4040 @@ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains routines used for analyzing expressions and +** for generating VDBE code that evaluates expressions in SQLite. +*/ +#include "sqliteInt.h" + +/* +** Return the 'affinity' of the expression pExpr if any. +** +** If pExpr is a column, a reference to a column via an 'AS' alias, +** or a sub-select with a column as the return value, then the +** affinity of that column is returned. Otherwise, 0x00 is returned, +** indicating no affinity for the expression. +** +** i.e. the WHERE clause expresssions in the following statements all +** have an affinity: +** +** CREATE TABLE t1(a); +** SELECT * FROM t1 WHERE a; +** SELECT a AS b FROM t1 WHERE b; +** SELECT * FROM t1 WHERE (select a from t1); +*/ +char sqlite3ExprAffinity(Expr *pExpr){ + int op = pExpr->op; + if( op==TK_SELECT ){ + assert( pExpr->flags&EP_xIsSelect ); + return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr); + } +#ifndef SQLITE_OMIT_CAST + if( op==TK_CAST ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + return sqlite3AffinityType(pExpr->u.zToken); + } +#endif + if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER) + && pExpr->pTab!=0 + ){ + /* op==TK_REGISTER && pExpr->pTab!=0 happens when pExpr was originally + ** a TK_COLUMN but was previously evaluated and cached in a register */ + int j = pExpr->iColumn; + if( j<0 ) return SQLITE_AFF_INTEGER; + assert( pExpr->pTab && jpTab->nCol ); + return pExpr->pTab->aCol[j].affinity; + } + return pExpr->affinity; +} + +/* +** Set the explicit collating sequence for an expression to the +** collating sequence supplied in the second argument. +*/ +Expr *sqlite3ExprSetColl(Expr *pExpr, CollSeq *pColl){ + if( pExpr && pColl ){ + pExpr->pColl = pColl; + pExpr->flags |= EP_ExpCollate; + } + return pExpr; +} + +/* +** Set the collating sequence for expression pExpr to be the collating +** sequence named by pToken. Return a pointer to the revised expression. +** The collating sequence is marked as "explicit" using the EP_ExpCollate +** flag. An explicit collating sequence will override implicit +** collating sequences. +*/ +Expr *sqlite3ExprSetCollByToken(Parse *pParse, Expr *pExpr, Token *pCollName){ + char *zColl = 0; /* Dequoted name of collation sequence */ + CollSeq *pColl; + sqlite3 *db = pParse->db; + zColl = sqlite3NameFromToken(db, pCollName); + pColl = sqlite3LocateCollSeq(pParse, zColl); + sqlite3ExprSetColl(pExpr, pColl); + sqlite3DbFree(db, zColl); + return pExpr; +} + +/* +** Return the default collation sequence for the expression pExpr. If +** there is no default collation type, return 0. +*/ +CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ + CollSeq *pColl = 0; + Expr *p = pExpr; + while( p ){ + int op; + pColl = p->pColl; + if( pColl ) break; + op = p->op; + if( p->pTab!=0 && ( + op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER || op==TK_TRIGGER + )){ + /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally + ** a TK_COLUMN but was previously evaluated and cached in a register */ + const char *zColl; + int j = p->iColumn; + if( j>=0 ){ + sqlite3 *db = pParse->db; + zColl = p->pTab->aCol[j].zColl; + pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0); + pExpr->pColl = pColl; + } + break; + } + if( op!=TK_CAST && op!=TK_UPLUS ){ + break; + } + p = p->pLeft; + } + if( sqlite3CheckCollSeq(pParse, pColl) ){ + pColl = 0; + } + return pColl; +} + +/* +** pExpr is an operand of a comparison operator. aff2 is the +** type affinity of the other operand. This routine returns the +** type affinity that should be used for the comparison operator. +*/ +char sqlite3CompareAffinity(Expr *pExpr, char aff2){ + char aff1 = sqlite3ExprAffinity(pExpr); + if( aff1 && aff2 ){ + /* Both sides of the comparison are columns. If one has numeric + ** affinity, use that. Otherwise use no affinity. + */ + if( sqlite3IsNumericAffinity(aff1) || sqlite3IsNumericAffinity(aff2) ){ + return SQLITE_AFF_NUMERIC; + }else{ + return SQLITE_AFF_NONE; + } + }else if( !aff1 && !aff2 ){ + /* Neither side of the comparison is a column. Compare the + ** results directly. + */ + return SQLITE_AFF_NONE; + }else{ + /* One side is a column, the other is not. Use the columns affinity. */ + assert( aff1==0 || aff2==0 ); + return (aff1 + aff2); + } +} + +/* +** pExpr is a comparison operator. Return the type affinity that should +** be applied to both operands prior to doing the comparison. +*/ +static char comparisonAffinity(Expr *pExpr){ + char aff; + assert( pExpr->op==TK_EQ || pExpr->op==TK_IN || pExpr->op==TK_LT || + pExpr->op==TK_GT || pExpr->op==TK_GE || pExpr->op==TK_LE || + pExpr->op==TK_NE || pExpr->op==TK_IS || pExpr->op==TK_ISNOT ); + assert( pExpr->pLeft ); + aff = sqlite3ExprAffinity(pExpr->pLeft); + if( pExpr->pRight ){ + aff = sqlite3CompareAffinity(pExpr->pRight, aff); + }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + aff = sqlite3CompareAffinity(pExpr->x.pSelect->pEList->a[0].pExpr, aff); + }else if( !aff ){ + aff = SQLITE_AFF_NONE; + } + return aff; +} + +/* +** pExpr is a comparison expression, eg. '=', '<', IN(...) etc. +** idx_affinity is the affinity of an indexed column. Return true +** if the index with affinity idx_affinity may be used to implement +** the comparison in pExpr. +*/ +int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){ + char aff = comparisonAffinity(pExpr); + switch( aff ){ + case SQLITE_AFF_NONE: + return 1; + case SQLITE_AFF_TEXT: + return idx_affinity==SQLITE_AFF_TEXT; + default: + return sqlite3IsNumericAffinity(idx_affinity); + } +} + +/* +** Return the P5 value that should be used for a binary comparison +** opcode (OP_Eq, OP_Ge etc.) used to compare pExpr1 and pExpr2. +*/ +static u8 binaryCompareP5(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){ + u8 aff = (char)sqlite3ExprAffinity(pExpr2); + aff = (u8)sqlite3CompareAffinity(pExpr1, aff) | (u8)jumpIfNull; + return aff; +} + +/* +** Return a pointer to the collation sequence that should be used by +** a binary comparison operator comparing pLeft and pRight. +** +** If the left hand expression has a collating sequence type, then it is +** used. Otherwise the collation sequence for the right hand expression +** is used, or the default (BINARY) if neither expression has a collating +** type. +** +** Argument pRight (but not pLeft) may be a null pointer. In this case, +** it is not considered. +*/ +CollSeq *sqlite3BinaryCompareCollSeq( + Parse *pParse, + Expr *pLeft, + Expr *pRight +){ + CollSeq *pColl; + assert( pLeft ); + if( pLeft->flags & EP_ExpCollate ){ + assert( pLeft->pColl ); + pColl = pLeft->pColl; + }else if( pRight && pRight->flags & EP_ExpCollate ){ + assert( pRight->pColl ); + pColl = pRight->pColl; + }else{ + pColl = sqlite3ExprCollSeq(pParse, pLeft); + if( !pColl ){ + pColl = sqlite3ExprCollSeq(pParse, pRight); + } + } + return pColl; +} + +/* +** Generate code for a comparison operator. +*/ +static int codeCompare( + Parse *pParse, /* The parsing (and code generating) context */ + Expr *pLeft, /* The left operand */ + Expr *pRight, /* The right operand */ + int opcode, /* The comparison opcode */ + int in1, int in2, /* Register holding operands */ + int dest, /* Jump here if true. */ + int jumpIfNull /* If true, jump if either operand is NULL */ +){ + int p5; + int addr; + CollSeq *p4; + + p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight); + p5 = binaryCompareP5(pLeft, pRight, jumpIfNull); + addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1, + (void*)p4, P4_COLLSEQ); + sqlite3VdbeChangeP5(pParse->pVdbe, (u8)p5); + return addr; +} + +#if SQLITE_MAX_EXPR_DEPTH>0 +/* +** Check that argument nHeight is less than or equal to the maximum +** expression depth allowed. If it is not, leave an error message in +** pParse. +*/ +int sqlite3ExprCheckHeight(Parse *pParse, int nHeight){ + int rc = SQLITE_OK; + int mxHeight = pParse->db->aLimit[SQLITE_LIMIT_EXPR_DEPTH]; + if( nHeight>mxHeight ){ + sqlite3ErrorMsg(pParse, + "Expression tree is too large (maximum depth %d)", mxHeight + ); + rc = SQLITE_ERROR; + } + return rc; +} + +/* The following three functions, heightOfExpr(), heightOfExprList() +** and heightOfSelect(), are used to determine the maximum height +** of any expression tree referenced by the structure passed as the +** first argument. +** +** If this maximum height is greater than the current value pointed +** to by pnHeight, the second parameter, then set *pnHeight to that +** value. +*/ +static void heightOfExpr(Expr *p, int *pnHeight){ + if( p ){ + if( p->nHeight>*pnHeight ){ + *pnHeight = p->nHeight; + } + } +} +static void heightOfExprList(ExprList *p, int *pnHeight){ + if( p ){ + int i; + for(i=0; inExpr; i++){ + heightOfExpr(p->a[i].pExpr, pnHeight); + } + } +} +static void heightOfSelect(Select *p, int *pnHeight){ + if( p ){ + heightOfExpr(p->pWhere, pnHeight); + heightOfExpr(p->pHaving, pnHeight); + heightOfExpr(p->pLimit, pnHeight); + heightOfExpr(p->pOffset, pnHeight); + heightOfExprList(p->pEList, pnHeight); + heightOfExprList(p->pGroupBy, pnHeight); + heightOfExprList(p->pOrderBy, pnHeight); + heightOfSelect(p->pPrior, pnHeight); + } +} + +/* +** Set the Expr.nHeight variable in the structure passed as an +** argument. An expression with no children, Expr.pList or +** Expr.pSelect member has a height of 1. Any other expression +** has a height equal to the maximum height of any other +** referenced Expr plus one. +*/ +static void exprSetHeight(Expr *p){ + int nHeight = 0; + heightOfExpr(p->pLeft, &nHeight); + heightOfExpr(p->pRight, &nHeight); + if( ExprHasProperty(p, EP_xIsSelect) ){ + heightOfSelect(p->x.pSelect, &nHeight); + }else{ + heightOfExprList(p->x.pList, &nHeight); + } + p->nHeight = nHeight + 1; +} + +/* +** Set the Expr.nHeight variable using the exprSetHeight() function. If +** the height is greater than the maximum allowed expression depth, +** leave an error in pParse. +*/ +void sqlite3ExprSetHeight(Parse *pParse, Expr *p){ + exprSetHeight(p); + sqlite3ExprCheckHeight(pParse, p->nHeight); +} + +/* +** Return the maximum height of any expression tree referenced +** by the select statement passed as an argument. +*/ +int sqlite3SelectExprHeight(Select *p){ + int nHeight = 0; + heightOfSelect(p, &nHeight); + return nHeight; +} +#else + #define exprSetHeight(y) +#endif /* SQLITE_MAX_EXPR_DEPTH>0 */ + +/* +** This routine is the core allocator for Expr nodes. +** +** Construct a new expression node and return a pointer to it. Memory +** for this node and for the pToken argument is a single allocation +** obtained from sqlite3DbMalloc(). The calling function +** is responsible for making sure the node eventually gets freed. +** +** If dequote is true, then the token (if it exists) is dequoted. +** If dequote is false, no dequoting is performance. The deQuote +** parameter is ignored if pToken is NULL or if the token does not +** appear to be quoted. If the quotes were of the form "..." (double-quotes) +** then the EP_DblQuoted flag is set on the expression node. +** +** Special case: If op==TK_INTEGER and pToken points to a string that +** can be translated into a 32-bit integer, then the token is not +** stored in u.zToken. Instead, the integer values is written +** into u.iValue and the EP_IntValue flag is set. No extra storage +** is allocated to hold the integer text and the dequote flag is ignored. +*/ +Expr *sqlite3ExprAlloc( + sqlite3 *db, /* Handle for sqlite3DbMallocZero() (may be null) */ + int op, /* Expression opcode */ + const Token *pToken, /* Token argument. Might be NULL */ + int dequote /* True to dequote */ +){ + Expr *pNew; + int nExtra = 0; + int iValue = 0; + + if( pToken ){ + if( op!=TK_INTEGER || pToken->z==0 + || sqlite3GetInt32(pToken->z, &iValue)==0 ){ + nExtra = pToken->n+1; + assert( iValue>=0 ); + } + } + pNew = sqlite3DbMallocZero(db, sizeof(Expr)+nExtra); + if( pNew ){ + pNew->op = (u8)op; + pNew->iAgg = -1; + if( pToken ){ + if( nExtra==0 ){ + pNew->flags |= EP_IntValue; + pNew->u.iValue = iValue; + }else{ + int c; + pNew->u.zToken = (char*)&pNew[1]; + assert( pToken->z!=0 || pToken->n==0 ); + if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n); + pNew->u.zToken[pToken->n] = 0; + if( dequote && nExtra>=3 + && ((c = pToken->z[0])=='\'' || c=='"' || c=='[' || c=='`') ){ + sqlite3Dequote(pNew->u.zToken); + if( c=='"' ) pNew->flags |= EP_DblQuoted; + } + } + } +#if SQLITE_MAX_EXPR_DEPTH>0 + pNew->nHeight = 1; +#endif + } + return pNew; +} + +/* +** Allocate a new expression node from a zero-terminated token that has +** already been dequoted. +*/ +Expr *sqlite3Expr( + sqlite3 *db, /* Handle for sqlite3DbMallocZero() (may be null) */ + int op, /* Expression opcode */ + const char *zToken /* Token argument. Might be NULL */ +){ + Token x; + x.z = zToken; + x.n = zToken ? sqlite3Strlen30(zToken) : 0; + return sqlite3ExprAlloc(db, op, &x, 0); +} + +/* +** Attach subtrees pLeft and pRight to the Expr node pRoot. +** +** If pRoot==NULL that means that a memory allocation error has occurred. +** In that case, delete the subtrees pLeft and pRight. +*/ +void sqlite3ExprAttachSubtrees( + sqlite3 *db, + Expr *pRoot, + Expr *pLeft, + Expr *pRight +){ + if( pRoot==0 ){ + assert( db->mallocFailed ); + sqlite3ExprDelete(db, pLeft); + sqlite3ExprDelete(db, pRight); + }else{ + if( pRight ){ + pRoot->pRight = pRight; + if( pRight->flags & EP_ExpCollate ){ + pRoot->flags |= EP_ExpCollate; + pRoot->pColl = pRight->pColl; + } + } + if( pLeft ){ + pRoot->pLeft = pLeft; + if( pLeft->flags & EP_ExpCollate ){ + pRoot->flags |= EP_ExpCollate; + pRoot->pColl = pLeft->pColl; + } + } + exprSetHeight(pRoot); + } +} + +/* +** Allocate a Expr node which joins as many as two subtrees. +** +** One or both of the subtrees can be NULL. Return a pointer to the new +** Expr node. Or, if an OOM error occurs, set pParse->db->mallocFailed, +** free the subtrees and return NULL. +*/ +Expr *sqlite3PExpr( + Parse *pParse, /* Parsing context */ + int op, /* Expression opcode */ + Expr *pLeft, /* Left operand */ + Expr *pRight, /* Right operand */ + const Token *pToken /* Argument token */ +){ + Expr *p = sqlite3ExprAlloc(pParse->db, op, pToken, 1); + sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight); + if( p ) { + sqlite3ExprCheckHeight(pParse, p->nHeight); + } + return p; +} + +/* +** Join two expressions using an AND operator. If either expression is +** NULL, then just return the other expression. +*/ +Expr *sqlite3ExprAnd(sqlite3 *db, Expr *pLeft, Expr *pRight){ + if( pLeft==0 ){ + return pRight; + }else if( pRight==0 ){ + return pLeft; + }else{ + Expr *pNew = sqlite3ExprAlloc(db, TK_AND, 0, 0); + sqlite3ExprAttachSubtrees(db, pNew, pLeft, pRight); + return pNew; + } +} + +/* +** Construct a new expression node for a function with multiple +** arguments. +*/ +Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){ + Expr *pNew; + sqlite3 *db = pParse->db; + assert( pToken ); + pNew = sqlite3ExprAlloc(db, TK_FUNCTION, pToken, 1); + if( pNew==0 ){ + sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */ + return 0; + } + pNew->x.pList = pList; + assert( !ExprHasProperty(pNew, EP_xIsSelect) ); + sqlite3ExprSetHeight(pParse, pNew); + return pNew; +} + +/* +** Assign a variable number to an expression that encodes a wildcard +** in the original SQL statement. +** +** Wildcards consisting of a single "?" are assigned the next sequential +** variable number. +** +** Wildcards of the form "?nnn" are assigned the number "nnn". We make +** sure "nnn" is not too be to avoid a denial of service attack when +** the SQL statement comes from an external source. +** +** Wildcards of the form ":aaa", "@aaa", or "$aaa" are assigned the same number +** as the previous instance of the same wildcard. Or if this is the first +** instance of the wildcard, the next sequenial variable number is +** assigned. +*/ +void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){ + sqlite3 *db = pParse->db; + const char *z; + + if( pExpr==0 ) return; + assert( !ExprHasAnyProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) ); + z = pExpr->u.zToken; + assert( z!=0 ); + assert( z[0]!=0 ); + if( z[1]==0 ){ + /* Wildcard of the form "?". Assign the next variable number */ + assert( z[0]=='?' ); + pExpr->iColumn = (ynVar)(++pParse->nVar); + }else{ + ynVar x = 0; + u32 n = sqlite3Strlen30(z); + if( z[0]=='?' ){ + /* Wildcard of the form "?nnn". Convert "nnn" to an integer and + ** use it as the variable number */ + i64 i; + int bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8); + pExpr->iColumn = x = (ynVar)i; + testcase( i==0 ); + testcase( i==1 ); + testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 ); + testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ); + if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ + sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d", + db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]); + x = 0; + } + if( i>pParse->nVar ){ + pParse->nVar = (int)i; + } + }else{ + /* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable + ** number as the prior appearance of the same name, or if the name + ** has never appeared before, reuse the same variable number + */ + ynVar i; + for(i=0; inzVar; i++){ + if( pParse->azVar[i] && memcmp(pParse->azVar[i],z,n+1)==0 ){ + pExpr->iColumn = x = (ynVar)i+1; + break; + } + } + if( x==0 ) x = pExpr->iColumn = (ynVar)(++pParse->nVar); + } + if( x>0 ){ + if( x>pParse->nzVar ){ + char **a; + a = sqlite3DbRealloc(db, pParse->azVar, x*sizeof(a[0])); + if( a==0 ) return; /* Error reported through db->mallocFailed */ + pParse->azVar = a; + memset(&a[pParse->nzVar], 0, (x-pParse->nzVar)*sizeof(a[0])); + pParse->nzVar = x; + } + if( z[0]!='?' || pParse->azVar[x-1]==0 ){ + sqlite3DbFree(db, pParse->azVar[x-1]); + pParse->azVar[x-1] = sqlite3DbStrNDup(db, z, n); + } + } + } + if( !pParse->nErr && pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ + sqlite3ErrorMsg(pParse, "too many SQL variables"); + } +} + +/* +** Recursively delete an expression tree. +*/ +void sqlite3ExprDelete(sqlite3 *db, Expr *p){ + if( p==0 ) return; + /* Sanity check: Assert that the IntValue is non-negative if it exists */ + assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 ); + if( !ExprHasAnyProperty(p, EP_TokenOnly) ){ + sqlite3ExprDelete(db, p->pLeft); + sqlite3ExprDelete(db, p->pRight); + if( !ExprHasProperty(p, EP_Reduced) && (p->flags2 & EP2_MallocedToken)!=0 ){ + sqlite3DbFree(db, p->u.zToken); + } + if( ExprHasProperty(p, EP_xIsSelect) ){ + sqlite3SelectDelete(db, p->x.pSelect); + }else{ + sqlite3ExprListDelete(db, p->x.pList); + } + } + if( !ExprHasProperty(p, EP_Static) ){ + sqlite3DbFree(db, p); + } +} + +/* +** Return the number of bytes allocated for the expression structure +** passed as the first argument. This is always one of EXPR_FULLSIZE, +** EXPR_REDUCEDSIZE or EXPR_TOKENONLYSIZE. +*/ +static int exprStructSize(Expr *p){ + if( ExprHasProperty(p, EP_TokenOnly) ) return EXPR_TOKENONLYSIZE; + if( ExprHasProperty(p, EP_Reduced) ) return EXPR_REDUCEDSIZE; + return EXPR_FULLSIZE; +} + +/* +** The dupedExpr*Size() routines each return the number of bytes required +** to store a copy of an expression or expression tree. They differ in +** how much of the tree is measured. +** +** dupedExprStructSize() Size of only the Expr structure +** dupedExprNodeSize() Size of Expr + space for token +** dupedExprSize() Expr + token + subtree components +** +*************************************************************************** +** +** The dupedExprStructSize() function returns two values OR-ed together: +** (1) the space required for a copy of the Expr structure only and +** (2) the EP_xxx flags that indicate what the structure size should be. +** The return values is always one of: +** +** EXPR_FULLSIZE +** EXPR_REDUCEDSIZE | EP_Reduced +** EXPR_TOKENONLYSIZE | EP_TokenOnly +** +** The size of the structure can be found by masking the return value +** of this routine with 0xfff. The flags can be found by masking the +** return value with EP_Reduced|EP_TokenOnly. +** +** Note that with flags==EXPRDUP_REDUCE, this routines works on full-size +** (unreduced) Expr objects as they or originally constructed by the parser. +** During expression analysis, extra information is computed and moved into +** later parts of teh Expr object and that extra information might get chopped +** off if the expression is reduced. Note also that it does not work to +** make a EXPRDUP_REDUCE copy of a reduced expression. It is only legal +** to reduce a pristine expression tree from the parser. The implementation +** of dupedExprStructSize() contain multiple assert() statements that attempt +** to enforce this constraint. +*/ +static int dupedExprStructSize(Expr *p, int flags){ + int nSize; + assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */ + if( 0==(flags&EXPRDUP_REDUCE) ){ + nSize = EXPR_FULLSIZE; + }else{ + assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) ); + assert( !ExprHasProperty(p, EP_FromJoin) ); + assert( (p->flags2 & EP2_MallocedToken)==0 ); + assert( (p->flags2 & EP2_Irreducible)==0 ); + if( p->pLeft || p->pRight || p->pColl || p->x.pList ){ + nSize = EXPR_REDUCEDSIZE | EP_Reduced; + }else{ + nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly; + } + } + return nSize; +} + +/* +** This function returns the space in bytes required to store the copy +** of the Expr structure and a copy of the Expr.u.zToken string (if that +** string is defined.) +*/ +static int dupedExprNodeSize(Expr *p, int flags){ + int nByte = dupedExprStructSize(p, flags) & 0xfff; + if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ + nByte += sqlite3Strlen30(p->u.zToken)+1; + } + return ROUND8(nByte); +} + +/* +** Return the number of bytes required to create a duplicate of the +** expression passed as the first argument. The second argument is a +** mask containing EXPRDUP_XXX flags. +** +** The value returned includes space to create a copy of the Expr struct +** itself and the buffer referred to by Expr.u.zToken, if any. +** +** If the EXPRDUP_REDUCE flag is set, then the return value includes +** space to duplicate all Expr nodes in the tree formed by Expr.pLeft +** and Expr.pRight variables (but not for any structures pointed to or +** descended from the Expr.x.pList or Expr.x.pSelect variables). +*/ +static int dupedExprSize(Expr *p, int flags){ + int nByte = 0; + if( p ){ + nByte = dupedExprNodeSize(p, flags); + if( flags&EXPRDUP_REDUCE ){ + nByte += dupedExprSize(p->pLeft, flags) + dupedExprSize(p->pRight, flags); + } + } + return nByte; +} + +/* +** This function is similar to sqlite3ExprDup(), except that if pzBuffer +** is not NULL then *pzBuffer is assumed to point to a buffer large enough +** to store the copy of expression p, the copies of p->u.zToken +** (if applicable), and the copies of the p->pLeft and p->pRight expressions, +** if any. Before returning, *pzBuffer is set to the first byte passed the +** portion of the buffer copied into by this function. +*/ +static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){ + Expr *pNew = 0; /* Value to return */ + if( p ){ + const int isReduced = (flags&EXPRDUP_REDUCE); + u8 *zAlloc; + u32 staticFlag = 0; + + assert( pzBuffer==0 || isReduced ); + + /* Figure out where to write the new Expr structure. */ + if( pzBuffer ){ + zAlloc = *pzBuffer; + staticFlag = EP_Static; + }else{ + zAlloc = sqlite3DbMallocRaw(db, dupedExprSize(p, flags)); + } + pNew = (Expr *)zAlloc; + + if( pNew ){ + /* Set nNewSize to the size allocated for the structure pointed to + ** by pNew. This is either EXPR_FULLSIZE, EXPR_REDUCEDSIZE or + ** EXPR_TOKENONLYSIZE. nToken is set to the number of bytes consumed + ** by the copy of the p->u.zToken string (if any). + */ + const unsigned nStructSize = dupedExprStructSize(p, flags); + const int nNewSize = nStructSize & 0xfff; + int nToken; + if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ + nToken = sqlite3Strlen30(p->u.zToken) + 1; + }else{ + nToken = 0; + } + if( isReduced ){ + assert( ExprHasProperty(p, EP_Reduced)==0 ); + memcpy(zAlloc, p, nNewSize); + }else{ + int nSize = exprStructSize(p); + memcpy(zAlloc, p, nSize); + memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize); + } + + /* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */ + pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static); + pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly); + pNew->flags |= staticFlag; + + /* Copy the p->u.zToken string, if any. */ + if( nToken ){ + char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize]; + memcpy(zToken, p->u.zToken, nToken); + } + + if( 0==((p->flags|pNew->flags) & EP_TokenOnly) ){ + /* Fill in the pNew->x.pSelect or pNew->x.pList member. */ + if( ExprHasProperty(p, EP_xIsSelect) ){ + pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, isReduced); + }else{ + pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, isReduced); + } + } + + /* Fill in pNew->pLeft and pNew->pRight. */ + if( ExprHasAnyProperty(pNew, EP_Reduced|EP_TokenOnly) ){ + zAlloc += dupedExprNodeSize(p, flags); + if( ExprHasProperty(pNew, EP_Reduced) ){ + pNew->pLeft = exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc); + pNew->pRight = exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc); + } + if( pzBuffer ){ + *pzBuffer = zAlloc; + } + }else{ + pNew->flags2 = 0; + if( !ExprHasAnyProperty(p, EP_TokenOnly) ){ + pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0); + pNew->pRight = sqlite3ExprDup(db, p->pRight, 0); + } + } + + } + } + return pNew; +} + +/* +** The following group of routines make deep copies of expressions, +** expression lists, ID lists, and select statements. The copies can +** be deleted (by being passed to their respective ...Delete() routines) +** without effecting the originals. +** +** The expression list, ID, and source lists return by sqlite3ExprListDup(), +** sqlite3IdListDup(), and sqlite3SrcListDup() can not be further expanded +** by subsequent calls to sqlite*ListAppend() routines. +** +** Any tables that the SrcList might point to are not duplicated. +** +** The flags parameter contains a combination of the EXPRDUP_XXX flags. +** If the EXPRDUP_REDUCE flag is set, then the structure returned is a +** truncated version of the usual Expr structure that will be stored as +** part of the in-memory representation of the database schema. +*/ +Expr *sqlite3ExprDup(sqlite3 *db, Expr *p, int flags){ + return exprDup(db, p, flags, 0); +} +ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){ + ExprList *pNew; + struct ExprList_item *pItem, *pOldItem; + int i; + if( p==0 ) return 0; + pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) ); + if( pNew==0 ) return 0; + pNew->iECursor = 0; + pNew->nExpr = pNew->nAlloc = p->nExpr; + pNew->a = pItem = sqlite3DbMallocRaw(db, p->nExpr*sizeof(p->a[0]) ); + if( pItem==0 ){ + sqlite3DbFree(db, pNew); + return 0; + } + pOldItem = p->a; + for(i=0; inExpr; i++, pItem++, pOldItem++){ + Expr *pOldExpr = pOldItem->pExpr; + pItem->pExpr = sqlite3ExprDup(db, pOldExpr, flags); + pItem->zName = sqlite3DbStrDup(db, pOldItem->zName); + pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan); + pItem->sortOrder = pOldItem->sortOrder; + pItem->done = 0; + pItem->iOrderByCol = pOldItem->iOrderByCol; + pItem->iAlias = pOldItem->iAlias; + } + return pNew; +} + +/* +** If cursors, triggers, views and subqueries are all omitted from +** the build, then none of the following routines, except for +** sqlite3SelectDup(), can be called. sqlite3SelectDup() is sometimes +** called with a NULL argument. +*/ +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) \ + || !defined(SQLITE_OMIT_SUBQUERY) +SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){ + SrcList *pNew; + int i; + int nByte; + if( p==0 ) return 0; + nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0); + pNew = sqlite3DbMallocRaw(db, nByte ); + if( pNew==0 ) return 0; + pNew->nSrc = pNew->nAlloc = p->nSrc; + for(i=0; inSrc; i++){ + struct SrcList_item *pNewItem = &pNew->a[i]; + struct SrcList_item *pOldItem = &p->a[i]; + Table *pTab; + pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase); + pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); + pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias); + pNewItem->jointype = pOldItem->jointype; + pNewItem->iCursor = pOldItem->iCursor; + pNewItem->addrFillSub = pOldItem->addrFillSub; + pNewItem->regReturn = pOldItem->regReturn; + pNewItem->isCorrelated = pOldItem->isCorrelated; + pNewItem->zIndex = sqlite3DbStrDup(db, pOldItem->zIndex); + pNewItem->notIndexed = pOldItem->notIndexed; + pNewItem->pIndex = pOldItem->pIndex; + pTab = pNewItem->pTab = pOldItem->pTab; + if( pTab ){ + pTab->nRef++; + } + pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags); + pNewItem->pOn = sqlite3ExprDup(db, pOldItem->pOn, flags); + pNewItem->pUsing = sqlite3IdListDup(db, pOldItem->pUsing); + pNewItem->colUsed = pOldItem->colUsed; + } + return pNew; +} +IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){ + IdList *pNew; + int i; + if( p==0 ) return 0; + pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) ); + if( pNew==0 ) return 0; + pNew->nId = pNew->nAlloc = p->nId; + pNew->a = sqlite3DbMallocRaw(db, p->nId*sizeof(p->a[0]) ); + if( pNew->a==0 ){ + sqlite3DbFree(db, pNew); + return 0; + } + for(i=0; inId; i++){ + struct IdList_item *pNewItem = &pNew->a[i]; + struct IdList_item *pOldItem = &p->a[i]; + pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); + pNewItem->idx = pOldItem->idx; + } + return pNew; +} +Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ + Select *pNew, *pPrior; + if( p==0 ) return 0; + pNew = sqlite3DbMallocRaw(db, sizeof(*p) ); + if( pNew==0 ) return 0; + pNew->pEList = sqlite3ExprListDup(db, p->pEList, flags); + pNew->pSrc = sqlite3SrcListDup(db, p->pSrc, flags); + pNew->pWhere = sqlite3ExprDup(db, p->pWhere, flags); + pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy, flags); + pNew->pHaving = sqlite3ExprDup(db, p->pHaving, flags); + pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, flags); + pNew->op = p->op; + pNew->pPrior = pPrior = sqlite3SelectDup(db, p->pPrior, flags); + if( pPrior ) pPrior->pNext = pNew; + pNew->pNext = 0; + pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags); + pNew->pOffset = sqlite3ExprDup(db, p->pOffset, flags); + pNew->iLimit = 0; + pNew->iOffset = 0; + pNew->selFlags = p->selFlags & ~SF_UsesEphemeral; + pNew->pRightmost = 0; + pNew->addrOpenEphm[0] = -1; + pNew->addrOpenEphm[1] = -1; + pNew->addrOpenEphm[2] = -1; + return pNew; +} +#else +Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ + assert( p==0 ); + return 0; +} +#endif + + +/* +** Add a new element to the end of an expression list. If pList is +** initially NULL, then create a new expression list. +** +** If a memory allocation error occurs, the entire list is freed and +** NULL is returned. If non-NULL is returned, then it is guaranteed +** that the new entry was successfully appended. +*/ +ExprList *sqlite3ExprListAppend( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* List to which to append. Might be NULL */ + Expr *pExpr /* Expression to be appended. Might be NULL */ +){ + sqlite3 *db = pParse->db; + if( pList==0 ){ + pList = sqlite3DbMallocZero(db, sizeof(ExprList) ); + if( pList==0 ){ + goto no_mem; + } + assert( pList->nAlloc==0 ); + } + if( pList->nAlloc<=pList->nExpr ){ + struct ExprList_item *a; + int n = pList->nAlloc*2 + 4; + a = sqlite3DbRealloc(db, pList->a, n*sizeof(pList->a[0])); + if( a==0 ){ + goto no_mem; + } + pList->a = a; + pList->nAlloc = sqlite3DbMallocSize(db, a)/sizeof(a[0]); + } + assert( pList->a!=0 ); + if( 1 ){ + struct ExprList_item *pItem = &pList->a[pList->nExpr++]; + memset(pItem, 0, sizeof(*pItem)); + pItem->pExpr = pExpr; + } + return pList; + +no_mem: + /* Avoid leaking memory if malloc has failed. */ + sqlite3ExprDelete(db, pExpr); + sqlite3ExprListDelete(db, pList); + return 0; +} + +/* +** Set the ExprList.a[].zName element of the most recently added item +** on the expression list. +** +** pList might be NULL following an OOM error. But pName should never be +** NULL. If a memory allocation fails, the pParse->db->mallocFailed flag +** is set. +*/ +void sqlite3ExprListSetName( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* List to which to add the span. */ + Token *pName, /* Name to be added */ + int dequote /* True to cause the name to be dequoted */ +){ + assert( pList!=0 || pParse->db->mallocFailed!=0 ); + if( pList ){ + struct ExprList_item *pItem; + assert( pList->nExpr>0 ); + pItem = &pList->a[pList->nExpr-1]; + assert( pItem->zName==0 ); + pItem->zName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n); + if( dequote && pItem->zName ) sqlite3Dequote(pItem->zName); + } +} + +/* +** Set the ExprList.a[].zSpan element of the most recently added item +** on the expression list. +** +** pList might be NULL following an OOM error. But pSpan should never be +** NULL. If a memory allocation fails, the pParse->db->mallocFailed flag +** is set. +*/ +void sqlite3ExprListSetSpan( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* List to which to add the span. */ + ExprSpan *pSpan /* The span to be added */ +){ + sqlite3 *db = pParse->db; + assert( pList!=0 || db->mallocFailed!=0 ); + if( pList ){ + struct ExprList_item *pItem = &pList->a[pList->nExpr-1]; + assert( pList->nExpr>0 ); + assert( db->mallocFailed || pItem->pExpr==pSpan->pExpr ); + sqlite3DbFree(db, pItem->zSpan); + pItem->zSpan = sqlite3DbStrNDup(db, (char*)pSpan->zStart, + (int)(pSpan->zEnd - pSpan->zStart)); + } +} + +/* +** If the expression list pEList contains more than iLimit elements, +** leave an error message in pParse. +*/ +void sqlite3ExprListCheckLength( + Parse *pParse, + ExprList *pEList, + const char *zObject +){ + int mx = pParse->db->aLimit[SQLITE_LIMIT_COLUMN]; + testcase( pEList && pEList->nExpr==mx ); + testcase( pEList && pEList->nExpr==mx+1 ); + if( pEList && pEList->nExpr>mx ){ + sqlite3ErrorMsg(pParse, "too many columns in %s", zObject); + } +} + +/* +** Delete an entire expression list. +*/ +void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){ + int i; + struct ExprList_item *pItem; + if( pList==0 ) return; + assert( pList->a!=0 || (pList->nExpr==0 && pList->nAlloc==0) ); + assert( pList->nExpr<=pList->nAlloc ); + for(pItem=pList->a, i=0; inExpr; i++, pItem++){ + sqlite3ExprDelete(db, pItem->pExpr); + sqlite3DbFree(db, pItem->zName); + sqlite3DbFree(db, pItem->zSpan); + } + sqlite3DbFree(db, pList->a); + sqlite3DbFree(db, pList); +} + +/* +** These routines are Walker callbacks. Walker.u.pi is a pointer +** to an integer. These routines are checking an expression to see +** if it is a constant. Set *Walker.u.pi to 0 if the expression is +** not constant. +** +** These callback routines are used to implement the following: +** +** sqlite3ExprIsConstant() +** sqlite3ExprIsConstantNotJoin() +** sqlite3ExprIsConstantOrFunction() +** +*/ +static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ + + /* If pWalker->u.i is 3 then any term of the expression that comes from + ** the ON or USING clauses of a join disqualifies the expression + ** from being considered constant. */ + if( pWalker->u.i==3 && ExprHasAnyProperty(pExpr, EP_FromJoin) ){ + pWalker->u.i = 0; + return WRC_Abort; + } + + switch( pExpr->op ){ + /* Consider functions to be constant if all their arguments are constant + ** and pWalker->u.i==2 */ + case TK_FUNCTION: + if( pWalker->u.i==2 ) return 0; + /* Fall through */ + case TK_ID: + case TK_COLUMN: + case TK_AGG_FUNCTION: + case TK_AGG_COLUMN: + testcase( pExpr->op==TK_ID ); + testcase( pExpr->op==TK_COLUMN ); + testcase( pExpr->op==TK_AGG_FUNCTION ); + testcase( pExpr->op==TK_AGG_COLUMN ); + pWalker->u.i = 0; + return WRC_Abort; + default: + testcase( pExpr->op==TK_SELECT ); /* selectNodeIsConstant will disallow */ + testcase( pExpr->op==TK_EXISTS ); /* selectNodeIsConstant will disallow */ + return WRC_Continue; + } +} +static int selectNodeIsConstant(Walker *pWalker, Select *NotUsed){ + UNUSED_PARAMETER(NotUsed); + pWalker->u.i = 0; + return WRC_Abort; +} +static int exprIsConst(Expr *p, int initFlag){ + Walker w; + w.u.i = initFlag; + w.xExprCallback = exprNodeIsConstant; + w.xSelectCallback = selectNodeIsConstant; + sqlite3WalkExpr(&w, p); + return w.u.i; +} + +/* +** Walk an expression tree. Return 1 if the expression is constant +** and 0 if it involves variables or function calls. +** +** For the purposes of this function, a double-quoted string (ex: "abc") +** is considered a variable but a single-quoted string (ex: 'abc') is +** a constant. +*/ +int sqlite3ExprIsConstant(Expr *p){ + return exprIsConst(p, 1); +} + +/* +** Walk an expression tree. Return 1 if the expression is constant +** that does no originate from the ON or USING clauses of a join. +** Return 0 if it involves variables or function calls or terms from +** an ON or USING clause. +*/ +int sqlite3ExprIsConstantNotJoin(Expr *p){ + return exprIsConst(p, 3); +} + +/* +** Walk an expression tree. Return 1 if the expression is constant +** or a function call with constant arguments. Return and 0 if there +** are any variables. +** +** For the purposes of this function, a double-quoted string (ex: "abc") +** is considered a variable but a single-quoted string (ex: 'abc') is +** a constant. +*/ +int sqlite3ExprIsConstantOrFunction(Expr *p){ + return exprIsConst(p, 2); +} + +/* +** If the expression p codes a constant integer that is small enough +** to fit in a 32-bit integer, return 1 and put the value of the integer +** in *pValue. If the expression is not an integer or if it is too big +** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged. +*/ +int sqlite3ExprIsInteger(Expr *p, int *pValue){ + int rc = 0; + + /* If an expression is an integer literal that fits in a signed 32-bit + ** integer, then the EP_IntValue flag will have already been set */ + assert( p->op!=TK_INTEGER || (p->flags & EP_IntValue)!=0 + || sqlite3GetInt32(p->u.zToken, &rc)==0 ); + + if( p->flags & EP_IntValue ){ + *pValue = p->u.iValue; + return 1; + } + switch( p->op ){ + case TK_UPLUS: { + rc = sqlite3ExprIsInteger(p->pLeft, pValue); + break; + } + case TK_UMINUS: { + int v; + if( sqlite3ExprIsInteger(p->pLeft, &v) ){ + *pValue = -v; + rc = 1; + } + break; + } + default: break; + } + return rc; +} + +/* +** Return FALSE if there is no chance that the expression can be NULL. +** +** If the expression might be NULL or if the expression is too complex +** to tell return TRUE. +** +** This routine is used as an optimization, to skip OP_IsNull opcodes +** when we know that a value cannot be NULL. Hence, a false positive +** (returning TRUE when in fact the expression can never be NULL) might +** be a small performance hit but is otherwise harmless. On the other +** hand, a false negative (returning FALSE when the result could be NULL) +** will likely result in an incorrect answer. So when in doubt, return +** TRUE. +*/ +int sqlite3ExprCanBeNull(const Expr *p){ + u8 op; + while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ p = p->pLeft; } + op = p->op; + if( op==TK_REGISTER ) op = p->op2; + switch( op ){ + case TK_INTEGER: + case TK_STRING: + case TK_FLOAT: + case TK_BLOB: + return 0; + default: + return 1; + } +} + +/* +** Generate an OP_IsNull instruction that tests register iReg and jumps +** to location iDest if the value in iReg is NULL. The value in iReg +** was computed by pExpr. If we can look at pExpr at compile-time and +** determine that it can never generate a NULL, then the OP_IsNull operation +** can be omitted. +*/ +void sqlite3ExprCodeIsNullJump( + Vdbe *v, /* The VDBE under construction */ + const Expr *pExpr, /* Only generate OP_IsNull if this expr can be NULL */ + int iReg, /* Test the value in this register for NULL */ + int iDest /* Jump here if the value is null */ +){ + if( sqlite3ExprCanBeNull(pExpr) ){ + sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iDest); + } +} + +/* +** Return TRUE if the given expression is a constant which would be +** unchanged by OP_Affinity with the affinity given in the second +** argument. +** +** This routine is used to determine if the OP_Affinity operation +** can be omitted. When in doubt return FALSE. A false negative +** is harmless. A false positive, however, can result in the wrong +** answer. +*/ +int sqlite3ExprNeedsNoAffinityChange(const Expr *p, char aff){ + u8 op; + if( aff==SQLITE_AFF_NONE ) return 1; + while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ p = p->pLeft; } + op = p->op; + if( op==TK_REGISTER ) op = p->op2; + switch( op ){ + case TK_INTEGER: { + return aff==SQLITE_AFF_INTEGER || aff==SQLITE_AFF_NUMERIC; + } + case TK_FLOAT: { + return aff==SQLITE_AFF_REAL || aff==SQLITE_AFF_NUMERIC; + } + case TK_STRING: { + return aff==SQLITE_AFF_TEXT; + } + case TK_BLOB: { + return 1; + } + case TK_COLUMN: { + assert( p->iTable>=0 ); /* p cannot be part of a CHECK constraint */ + return p->iColumn<0 + && (aff==SQLITE_AFF_INTEGER || aff==SQLITE_AFF_NUMERIC); + } + default: { + return 0; + } + } +} + +/* +** Return TRUE if the given string is a row-id column name. +*/ +int sqlite3IsRowid(const char *z){ + if( sqlite3StrICmp(z, "_ROWID_")==0 ) return 1; + if( sqlite3StrICmp(z, "ROWID")==0 ) return 1; + if( sqlite3StrICmp(z, "OID")==0 ) return 1; + return 0; +} + +/* +** Return true if we are able to the IN operator optimization on a +** query of the form +** +** x IN (SELECT ...) +** +** Where the SELECT... clause is as specified by the parameter to this +** routine. +** +** The Select object passed in has already been preprocessed and no +** errors have been found. +*/ +#ifndef SQLITE_OMIT_SUBQUERY +static int isCandidateForInOpt(Select *p){ + SrcList *pSrc; + ExprList *pEList; + Table *pTab; + if( p==0 ) return 0; /* right-hand side of IN is SELECT */ + if( p->pPrior ) return 0; /* Not a compound SELECT */ + if( p->selFlags & (SF_Distinct|SF_Aggregate) ){ + testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct ); + testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate ); + return 0; /* No DISTINCT keyword and no aggregate functions */ + } + assert( p->pGroupBy==0 ); /* Has no GROUP BY clause */ + if( p->pLimit ) return 0; /* Has no LIMIT clause */ + assert( p->pOffset==0 ); /* No LIMIT means no OFFSET */ + if( p->pWhere ) return 0; /* Has no WHERE clause */ + pSrc = p->pSrc; + assert( pSrc!=0 ); + if( pSrc->nSrc!=1 ) return 0; /* Single term in FROM clause */ + if( pSrc->a[0].pSelect ) return 0; /* FROM is not a subquery or view */ + pTab = pSrc->a[0].pTab; + if( NEVER(pTab==0) ) return 0; + assert( pTab->pSelect==0 ); /* FROM clause is not a view */ + if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */ + pEList = p->pEList; + if( pEList->nExpr!=1 ) return 0; /* One column in the result set */ + if( pEList->a[0].pExpr->op!=TK_COLUMN ) return 0; /* Result is a column */ + return 1; +} +#endif /* SQLITE_OMIT_SUBQUERY */ + +/* +** Code an OP_Once instruction and allocate space for its flag. Return the +** address of the new instruction. +*/ +int sqlite3CodeOnce(Parse *pParse){ + Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ + return sqlite3VdbeAddOp1(v, OP_Once, pParse->nOnce++); +} + +/* +** This function is used by the implementation of the IN (...) operator. +** It's job is to find or create a b-tree structure that may be used +** either to test for membership of the (...) set or to iterate through +** its members, skipping duplicates. +** +** The index of the cursor opened on the b-tree (database table, database index +** or ephermal table) is stored in pX->iTable before this function returns. +** The returned value of this function indicates the b-tree type, as follows: +** +** IN_INDEX_ROWID - The cursor was opened on a database table. +** IN_INDEX_INDEX - The cursor was opened on a database index. +** IN_INDEX_EPH - The cursor was opened on a specially created and +** populated epheremal table. +** +** An existing b-tree may only be used if the SELECT is of the simple +** form: +** +** SELECT FROM +** +** If the prNotFound parameter is 0, then the b-tree will be used to iterate +** through the set members, skipping any duplicates. In this case an +** epheremal table must be used unless the selected is guaranteed +** to be unique - either because it is an INTEGER PRIMARY KEY or it +** has a UNIQUE constraint or UNIQUE index. +** +** If the prNotFound parameter is not 0, then the b-tree will be used +** for fast set membership tests. In this case an epheremal table must +** be used unless is an INTEGER PRIMARY KEY or an index can +** be found with as its left-most column. +** +** When the b-tree is being used for membership tests, the calling function +** needs to know whether or not the structure contains an SQL NULL +** value in order to correctly evaluate expressions like "X IN (Y, Z)". +** If there is any chance that the (...) might contain a NULL value at +** runtime, then a register is allocated and the register number written +** to *prNotFound. If there is no chance that the (...) contains a +** NULL value, then *prNotFound is left unchanged. +** +** If a register is allocated and its location stored in *prNotFound, then +** its initial value is NULL. If the (...) does not remain constant +** for the duration of the query (i.e. the SELECT within the (...) +** is a correlated subquery) then the value of the allocated register is +** reset to NULL each time the subquery is rerun. This allows the +** caller to use vdbe code equivalent to the following: +** +** if( register==NULL ){ +** has_null = +** register = 1 +** } +** +** in order to avoid running the +** test more often than is necessary. +*/ +#ifndef SQLITE_OMIT_SUBQUERY +int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ + Select *p; /* SELECT to the right of IN operator */ + int eType = 0; /* Type of RHS table. IN_INDEX_* */ + int iTab = pParse->nTab++; /* Cursor of the RHS table */ + int mustBeUnique = (prNotFound==0); /* True if RHS must be unique */ + Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ + + assert( pX->op==TK_IN ); + + /* Check to see if an existing table or index can be used to + ** satisfy the query. This is preferable to generating a new + ** ephemeral table. + */ + p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0); + if( ALWAYS(pParse->nErr==0) && isCandidateForInOpt(p) ){ + sqlite3 *db = pParse->db; /* Database connection */ + Table *pTab; /* Table
. */ + Expr *pExpr; /* Expression */ + int iCol; /* Index of column */ + int iDb; /* Database idx for pTab */ + + assert( p ); /* Because of isCandidateForInOpt(p) */ + assert( p->pEList!=0 ); /* Because of isCandidateForInOpt(p) */ + assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */ + assert( p->pSrc!=0 ); /* Because of isCandidateForInOpt(p) */ + pTab = p->pSrc->a[0].pTab; + pExpr = p->pEList->a[0].pExpr; + iCol = pExpr->iColumn; + + /* Code an OP_VerifyCookie and OP_TableLock for
. */ + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + sqlite3CodeVerifySchema(pParse, iDb); + sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); + + /* This function is only called from two places. In both cases the vdbe + ** has already been allocated. So assume sqlite3GetVdbe() is always + ** successful here. + */ + assert(v); + if( iCol<0 ){ + int iAddr; + + iAddr = sqlite3CodeOnce(pParse); + + sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); + eType = IN_INDEX_ROWID; + + sqlite3VdbeJumpHere(v, iAddr); + }else{ + Index *pIdx; /* Iterator variable */ + + /* The collation sequence used by the comparison. If an index is to + ** be used in place of a temp-table, it must be ordered according + ** to this collation sequence. */ + CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pExpr); + + /* Check that the affinity that will be used to perform the + ** comparison is the same as the affinity of the column. If + ** it is not, it is not possible to use any index. + */ + char aff = comparisonAffinity(pX); + int affinity_ok = (pTab->aCol[iCol].affinity==aff||aff==SQLITE_AFF_NONE); + + for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){ + if( (pIdx->aiColumn[0]==iCol) + && sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], 0)==pReq + && (!mustBeUnique || (pIdx->nColumn==1 && pIdx->onError!=OE_None)) + ){ + int iAddr; + char *pKey; + + pKey = (char *)sqlite3IndexKeyinfo(pParse, pIdx); + iAddr = sqlite3CodeOnce(pParse); + + sqlite3VdbeAddOp4(v, OP_OpenRead, iTab, pIdx->tnum, iDb, + pKey,P4_KEYINFO_HANDOFF); + VdbeComment((v, "%s", pIdx->zName)); + eType = IN_INDEX_INDEX; + + sqlite3VdbeJumpHere(v, iAddr); + if( prNotFound && !pTab->aCol[iCol].notNull ){ + *prNotFound = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound); + } + } + } + } + } + + if( eType==0 ){ + /* Could not found an existing table or index to use as the RHS b-tree. + ** We will have to generate an ephemeral table to do the job. + */ + double savedNQueryLoop = pParse->nQueryLoop; + int rMayHaveNull = 0; + eType = IN_INDEX_EPH; + if( prNotFound ){ + *prNotFound = rMayHaveNull = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound); + }else{ + testcase( pParse->nQueryLoop>(double)1 ); + pParse->nQueryLoop = (double)1; + if( pX->pLeft->iColumn<0 && !ExprHasAnyProperty(pX, EP_xIsSelect) ){ + eType = IN_INDEX_ROWID; + } + } + sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID); + pParse->nQueryLoop = savedNQueryLoop; + }else{ + pX->iTable = iTab; + } + return eType; +} +#endif + +/* +** Generate code for scalar subqueries used as a subquery expression, EXISTS, +** or IN operators. Examples: +** +** (SELECT a FROM b) -- subquery +** EXISTS (SELECT a FROM b) -- EXISTS subquery +** x IN (4,5,11) -- IN operator with list on right-hand side +** x IN (SELECT a FROM b) -- IN operator with subquery on the right +** +** The pExpr parameter describes the expression that contains the IN +** operator or subquery. +** +** If parameter isRowid is non-zero, then expression pExpr is guaranteed +** to be of the form " IN (?, ?, ?)", where is a reference +** to some integer key column of a table B-Tree. In this case, use an +** intkey B-Tree to store the set of IN(...) values instead of the usual +** (slower) variable length keys B-Tree. +** +** If rMayHaveNull is non-zero, that means that the operation is an IN +** (not a SELECT or EXISTS) and that the RHS might contains NULLs. +** Furthermore, the IN is in a WHERE clause and that we really want +** to iterate over the RHS of the IN operator in order to quickly locate +** all corresponding LHS elements. All this routine does is initialize +** the register given by rMayHaveNull to NULL. Calling routines will take +** care of changing this register value to non-NULL if the RHS is NULL-free. +** +** If rMayHaveNull is zero, that means that the subquery is being used +** for membership testing only. There is no need to initialize any +** registers to indicate the presense or absence of NULLs on the RHS. +** +** For a SELECT or EXISTS operator, return the register that holds the +** result. For IN operators or if an error occurs, the return value is 0. +*/ +#ifndef SQLITE_OMIT_SUBQUERY +int sqlite3CodeSubselect( + Parse *pParse, /* Parsing context */ + Expr *pExpr, /* The IN, SELECT, or EXISTS operator */ + int rMayHaveNull, /* Register that records whether NULLs exist in RHS */ + int isRowid /* If true, LHS of IN operator is a rowid */ +){ + int testAddr = -1; /* One-time test address */ + int rReg = 0; /* Register storing resulting */ + Vdbe *v = sqlite3GetVdbe(pParse); + if( NEVER(v==0) ) return 0; + sqlite3ExprCachePush(pParse); + + /* This code must be run in its entirety every time it is encountered + ** if any of the following is true: + ** + ** * The right-hand side is a correlated subquery + ** * The right-hand side is an expression list containing variables + ** * We are inside a trigger + ** + ** If all of the above are false, then we can run this code just once + ** save the results, and reuse the same result on subsequent invocations. + */ + if( !ExprHasAnyProperty(pExpr, EP_VarSelect) ){ + testAddr = sqlite3CodeOnce(pParse); + } + +#ifndef SQLITE_OMIT_EXPLAIN + if( pParse->explain==2 ){ + char *zMsg = sqlite3MPrintf( + pParse->db, "EXECUTE %s%s SUBQUERY %d", testAddr>=0?"":"CORRELATED ", + pExpr->op==TK_IN?"LIST":"SCALAR", pParse->iNextSelectId + ); + sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC); + } +#endif + + switch( pExpr->op ){ + case TK_IN: { + char affinity; /* Affinity of the LHS of the IN */ + KeyInfo keyInfo; /* Keyinfo for the generated table */ + int addr; /* Address of OP_OpenEphemeral instruction */ + Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */ + + if( rMayHaveNull ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, rMayHaveNull); + } + + affinity = sqlite3ExprAffinity(pLeft); + + /* Whether this is an 'x IN(SELECT...)' or an 'x IN()' + ** expression it is handled the same way. An ephemeral table is + ** filled with single-field index keys representing the results + ** from the SELECT or the . + ** + ** If the 'x' expression is a column value, or the SELECT... + ** statement returns a column value, then the affinity of that + ** column is used to build the index keys. If both 'x' and the + ** SELECT... statement are columns, then numeric affinity is used + ** if either column has NUMERIC or INTEGER affinity. If neither + ** 'x' nor the SELECT... statement are columns, then numeric affinity + ** is used. + */ + pExpr->iTable = pParse->nTab++; + addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, !isRowid); + if( rMayHaveNull==0 ) sqlite3VdbeChangeP5(v, BTREE_UNORDERED); + memset(&keyInfo, 0, sizeof(keyInfo)); + keyInfo.nField = 1; + + if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + /* Case 1: expr IN (SELECT ...) + ** + ** Generate code to write the results of the select into the temporary + ** table allocated and opened above. + */ + SelectDest dest; + ExprList *pEList; + + assert( !isRowid ); + sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable); + dest.affinity = (u8)affinity; + assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable ); + pExpr->x.pSelect->iLimit = 0; + if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){ + return 0; + } + pEList = pExpr->x.pSelect->pEList; + if( ALWAYS(pEList!=0 && pEList->nExpr>0) ){ + keyInfo.aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, + pEList->a[0].pExpr); + } + }else if( ALWAYS(pExpr->x.pList!=0) ){ + /* Case 2: expr IN (exprlist) + ** + ** For each expression, build an index key from the evaluation and + ** store it in the temporary table. If is a column, then use + ** that columns affinity when building index keys. If is not + ** a column, use numeric affinity. + */ + int i; + ExprList *pList = pExpr->x.pList; + struct ExprList_item *pItem; + int r1, r2, r3; + + if( !affinity ){ + affinity = SQLITE_AFF_NONE; + } + keyInfo.aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft); + + /* Loop through each expression in . */ + r1 = sqlite3GetTempReg(pParse); + r2 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_Null, 0, r2); + for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){ + Expr *pE2 = pItem->pExpr; + int iValToIns; + + /* If the expression is not constant then we will need to + ** disable the test that was generated above that makes sure + ** this code only executes once. Because for a non-constant + ** expression we need to rerun this code each time. + */ + if( testAddr>=0 && !sqlite3ExprIsConstant(pE2) ){ + sqlite3VdbeChangeToNoop(v, testAddr); + testAddr = -1; + } + + /* Evaluate the expression and insert it into the temp table */ + if( isRowid && sqlite3ExprIsInteger(pE2, &iValToIns) ){ + sqlite3VdbeAddOp3(v, OP_InsertInt, pExpr->iTable, r2, iValToIns); + }else{ + r3 = sqlite3ExprCodeTarget(pParse, pE2, r1); + if( isRowid ){ + sqlite3VdbeAddOp2(v, OP_MustBeInt, r3, + sqlite3VdbeCurrentAddr(v)+2); + sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3); + }else{ + sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1); + sqlite3ExprCacheAffinityChange(pParse, r3, 1); + sqlite3VdbeAddOp2(v, OP_IdxInsert, pExpr->iTable, r2); + } + } + } + sqlite3ReleaseTempReg(pParse, r1); + sqlite3ReleaseTempReg(pParse, r2); + } + if( !isRowid ){ + sqlite3VdbeChangeP4(v, addr, (void *)&keyInfo, P4_KEYINFO); + } + break; + } + + case TK_EXISTS: + case TK_SELECT: + default: { + /* If this has to be a scalar SELECT. Generate code to put the + ** value of this select in a memory cell and record the number + ** of the memory cell in iColumn. If this is an EXISTS, write + ** an integer 0 (not exists) or 1 (exists) into a memory cell + ** and record that memory cell in iColumn. + */ + Select *pSel; /* SELECT statement to encode */ + SelectDest dest; /* How to deal with SELECt result */ + + testcase( pExpr->op==TK_EXISTS ); + testcase( pExpr->op==TK_SELECT ); + assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT ); + + assert( ExprHasProperty(pExpr, EP_xIsSelect) ); + pSel = pExpr->x.pSelect; + sqlite3SelectDestInit(&dest, 0, ++pParse->nMem); + if( pExpr->op==TK_SELECT ){ + dest.eDest = SRT_Mem; + sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iParm); + VdbeComment((v, "Init subquery result")); + }else{ + dest.eDest = SRT_Exists; + sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iParm); + VdbeComment((v, "Init EXISTS result")); + } + sqlite3ExprDelete(pParse->db, pSel->pLimit); + pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, + &sqlite3IntTokens[1]); + pSel->iLimit = 0; + if( sqlite3Select(pParse, pSel, &dest) ){ + return 0; + } + rReg = dest.iParm; + ExprSetIrreducible(pExpr); + break; + } + } + + if( testAddr>=0 ){ + sqlite3VdbeJumpHere(v, testAddr); + } + sqlite3ExprCachePop(pParse, 1); + + return rReg; +} +#endif /* SQLITE_OMIT_SUBQUERY */ + +#ifndef SQLITE_OMIT_SUBQUERY +/* +** Generate code for an IN expression. +** +** x IN (SELECT ...) +** x IN (value, value, ...) +** +** The left-hand side (LHS) is a scalar expression. The right-hand side (RHS) +** is an array of zero or more values. The expression is true if the LHS is +** contained within the RHS. The value of the expression is unknown (NULL) +** if the LHS is NULL or if the LHS is not contained within the RHS and the +** RHS contains one or more NULL values. +** +** This routine generates code will jump to destIfFalse if the LHS is not +** contained within the RHS. If due to NULLs we cannot determine if the LHS +** is contained in the RHS then jump to destIfNull. If the LHS is contained +** within the RHS then fall through. +*/ +static void sqlite3ExprCodeIN( + Parse *pParse, /* Parsing and code generating context */ + Expr *pExpr, /* The IN expression */ + int destIfFalse, /* Jump here if LHS is not contained in the RHS */ + int destIfNull /* Jump here if the results are unknown due to NULLs */ +){ + int rRhsHasNull = 0; /* Register that is true if RHS contains NULL values */ + char affinity; /* Comparison affinity to use */ + int eType; /* Type of the RHS */ + int r1; /* Temporary use register */ + Vdbe *v; /* Statement under construction */ + + /* Compute the RHS. After this step, the table with cursor + ** pExpr->iTable will contains the values that make up the RHS. + */ + v = pParse->pVdbe; + assert( v!=0 ); /* OOM detected prior to this routine */ + VdbeNoopComment((v, "begin IN expr")); + eType = sqlite3FindInIndex(pParse, pExpr, &rRhsHasNull); + + /* Figure out the affinity to use to create a key from the results + ** of the expression. affinityStr stores a static string suitable for + ** P4 of OP_MakeRecord. + */ + affinity = comparisonAffinity(pExpr); + + /* Code the LHS, the from " IN (...)". + */ + sqlite3ExprCachePush(pParse); + r1 = sqlite3GetTempReg(pParse); + sqlite3ExprCode(pParse, pExpr->pLeft, r1); + + /* If the LHS is NULL, then the result is either false or NULL depending + ** on whether the RHS is empty or not, respectively. + */ + if( destIfNull==destIfFalse ){ + /* Shortcut for the common case where the false and NULL outcomes are + ** the same. */ + sqlite3VdbeAddOp2(v, OP_IsNull, r1, destIfNull); + }else{ + int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1); + sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse); + sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull); + sqlite3VdbeJumpHere(v, addr1); + } + + if( eType==IN_INDEX_ROWID ){ + /* In this case, the RHS is the ROWID of table b-tree + */ + sqlite3VdbeAddOp2(v, OP_MustBeInt, r1, destIfFalse); + sqlite3VdbeAddOp3(v, OP_NotExists, pExpr->iTable, destIfFalse, r1); + }else{ + /* In this case, the RHS is an index b-tree. + */ + sqlite3VdbeAddOp4(v, OP_Affinity, r1, 1, 0, &affinity, 1); + + /* If the set membership test fails, then the result of the + ** "x IN (...)" expression must be either 0 or NULL. If the set + ** contains no NULL values, then the result is 0. If the set + ** contains one or more NULL values, then the result of the + ** expression is also NULL. + */ + if( rRhsHasNull==0 || destIfFalse==destIfNull ){ + /* This branch runs if it is known at compile time that the RHS + ** cannot contain NULL values. This happens as the result + ** of a "NOT NULL" constraint in the database schema. + ** + ** Also run this branch if NULL is equivalent to FALSE + ** for this particular IN operator. + */ + sqlite3VdbeAddOp4Int(v, OP_NotFound, pExpr->iTable, destIfFalse, r1, 1); + + }else{ + /* In this branch, the RHS of the IN might contain a NULL and + ** the presence of a NULL on the RHS makes a difference in the + ** outcome. + */ + int j1, j2, j3; + + /* First check to see if the LHS is contained in the RHS. If so, + ** then the presence of NULLs in the RHS does not matter, so jump + ** over all of the code that follows. + */ + j1 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, r1, 1); + + /* Here we begin generating code that runs if the LHS is not + ** contained within the RHS. Generate additional code that + ** tests the RHS for NULLs. If the RHS contains a NULL then + ** jump to destIfNull. If there are no NULLs in the RHS then + ** jump to destIfFalse. + */ + j2 = sqlite3VdbeAddOp1(v, OP_NotNull, rRhsHasNull); + j3 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, rRhsHasNull, 1); + sqlite3VdbeAddOp2(v, OP_Integer, -1, rRhsHasNull); + sqlite3VdbeJumpHere(v, j3); + sqlite3VdbeAddOp2(v, OP_AddImm, rRhsHasNull, 1); + sqlite3VdbeJumpHere(v, j2); + + /* Jump to the appropriate target depending on whether or not + ** the RHS contains a NULL + */ + sqlite3VdbeAddOp2(v, OP_If, rRhsHasNull, destIfNull); + sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse); + + /* The OP_Found at the top of this branch jumps here when true, + ** causing the overall IN expression evaluation to fall through. + */ + sqlite3VdbeJumpHere(v, j1); + } + } + sqlite3ReleaseTempReg(pParse, r1); + sqlite3ExprCachePop(pParse, 1); + VdbeComment((v, "end IN expr")); +} +#endif /* SQLITE_OMIT_SUBQUERY */ + +/* +** Duplicate an 8-byte value +*/ +static char *dup8bytes(Vdbe *v, const char *in){ + char *out = sqlite3DbMallocRaw(sqlite3VdbeDb(v), 8); + if( out ){ + memcpy(out, in, 8); + } + return out; +} + +#ifndef SQLITE_OMIT_FLOATING_POINT +/* +** Generate an instruction that will put the floating point +** value described by z[0..n-1] into register iMem. +** +** The z[] string will probably not be zero-terminated. But the +** z[n] character is guaranteed to be something that does not look +** like the continuation of the number. +*/ +static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){ + if( ALWAYS(z!=0) ){ + double value; + char *zV; + sqlite3AtoF(z, &value, sqlite3Strlen30(z), SQLITE_UTF8); + assert( !sqlite3IsNaN(value) ); /* The new AtoF never returns NaN */ + if( negateFlag ) value = -value; + zV = dup8bytes(v, (char*)&value); + sqlite3VdbeAddOp4(v, OP_Real, 0, iMem, 0, zV, P4_REAL); + } +} +#endif + + +/* +** Generate an instruction that will put the integer describe by +** text z[0..n-1] into register iMem. +** +** Expr.u.zToken is always UTF8 and zero-terminated. +*/ +static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){ + Vdbe *v = pParse->pVdbe; + if( pExpr->flags & EP_IntValue ){ + int i = pExpr->u.iValue; + assert( i>=0 ); + if( negFlag ) i = -i; + sqlite3VdbeAddOp2(v, OP_Integer, i, iMem); + }else{ + int c; + i64 value; + const char *z = pExpr->u.zToken; + assert( z!=0 ); + c = sqlite3Atoi64(z, &value, sqlite3Strlen30(z), SQLITE_UTF8); + if( c==0 || (c==2 && negFlag) ){ + char *zV; + if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; } + zV = dup8bytes(v, (char*)&value); + sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64); + }else{ +#ifdef SQLITE_OMIT_FLOATING_POINT + sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z); +#else + codeReal(v, z, negFlag, iMem); +#endif + } + } +} + +/* +** Clear a cache entry. +*/ +static void cacheEntryClear(Parse *pParse, struct yColCache *p){ + if( p->tempReg ){ + if( pParse->nTempRegaTempReg) ){ + pParse->aTempReg[pParse->nTempReg++] = p->iReg; + } + p->tempReg = 0; + } +} + + +/* +** Record in the column cache that a particular column from a +** particular table is stored in a particular register. +*/ +void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){ + int i; + int minLru; + int idxLru; + struct yColCache *p; + + assert( iReg>0 ); /* Register numbers are always positive */ + assert( iCol>=-1 && iCol<32768 ); /* Finite column numbers */ + + /* The SQLITE_ColumnCache flag disables the column cache. This is used + ** for testing only - to verify that SQLite always gets the same answer + ** with and without the column cache. + */ + if( pParse->db->flags & SQLITE_ColumnCache ) return; + + /* First replace any existing entry. + ** + ** Actually, the way the column cache is currently used, we are guaranteed + ** that the object will never already be in cache. Verify this guarantee. + */ +#ifndef NDEBUG + for(i=0, p=pParse->aColCache; iiReg && p->iTable==iTab && p->iColumn==iCol ){ + cacheEntryClear(pParse, p); + p->iLevel = pParse->iCacheLevel; + p->iReg = iReg; + p->lru = pParse->iCacheCnt++; + return; + } +#endif + assert( p->iReg==0 || p->iTable!=iTab || p->iColumn!=iCol ); + } +#endif + + /* Find an empty slot and replace it */ + for(i=0, p=pParse->aColCache; iiReg==0 ){ + p->iLevel = pParse->iCacheLevel; + p->iTable = iTab; + p->iColumn = iCol; + p->iReg = iReg; + p->tempReg = 0; + p->lru = pParse->iCacheCnt++; + return; + } + } + + /* Replace the last recently used */ + minLru = 0x7fffffff; + idxLru = -1; + for(i=0, p=pParse->aColCache; ilrulru; + } + } + if( ALWAYS(idxLru>=0) ){ + p = &pParse->aColCache[idxLru]; + p->iLevel = pParse->iCacheLevel; + p->iTable = iTab; + p->iColumn = iCol; + p->iReg = iReg; + p->tempReg = 0; + p->lru = pParse->iCacheCnt++; + return; + } +} + +/* +** Indicate that registers between iReg..iReg+nReg-1 are being overwritten. +** Purge the range of registers from the column cache. +*/ +void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){ + int i; + int iLast = iReg + nReg - 1; + struct yColCache *p; + for(i=0, p=pParse->aColCache; iiReg; + if( r>=iReg && r<=iLast ){ + cacheEntryClear(pParse, p); + p->iReg = 0; + } + } +} + +/* +** Remember the current column cache context. Any new entries added +** added to the column cache after this call are removed when the +** corresponding pop occurs. +*/ +void sqlite3ExprCachePush(Parse *pParse){ + pParse->iCacheLevel++; +} + +/* +** Remove from the column cache any entries that were added since the +** the previous N Push operations. In other words, restore the cache +** to the state it was in N Pushes ago. +*/ +void sqlite3ExprCachePop(Parse *pParse, int N){ + int i; + struct yColCache *p; + assert( N>0 ); + assert( pParse->iCacheLevel>=N ); + pParse->iCacheLevel -= N; + for(i=0, p=pParse->aColCache; iiReg && p->iLevel>pParse->iCacheLevel ){ + cacheEntryClear(pParse, p); + p->iReg = 0; + } + } +} + +/* +** When a cached column is reused, make sure that its register is +** no longer available as a temp register. ticket #3879: that same +** register might be in the cache in multiple places, so be sure to +** get them all. +*/ +static void sqlite3ExprCachePinRegister(Parse *pParse, int iReg){ + int i; + struct yColCache *p; + for(i=0, p=pParse->aColCache; iiReg==iReg ){ + p->tempReg = 0; + } + } +} + +/* +** Generate code to extract the value of the iCol-th column of a table. +*/ +void sqlite3ExprCodeGetColumnOfTable( + Vdbe *v, /* The VDBE under construction */ + Table *pTab, /* The table containing the value */ + int iTabCur, /* The cursor for this table */ + int iCol, /* Index of the column to extract */ + int regOut /* Extract the valud into this register */ +){ + if( iCol<0 || iCol==pTab->iPKey ){ + sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut); + }else{ + int op = IsVirtual(pTab) ? OP_VColumn : OP_Column; + sqlite3VdbeAddOp3(v, op, iTabCur, iCol, regOut); + } + if( iCol>=0 ){ + sqlite3ColumnDefault(v, pTab, iCol, regOut); + } +} + +/* +** Generate code that will extract the iColumn-th column from +** table pTab and store the column value in a register. An effort +** is made to store the column value in register iReg, but this is +** not guaranteed. The location of the column value is returned. +** +** There must be an open cursor to pTab in iTable when this routine +** is called. If iColumn<0 then code is generated that extracts the rowid. +*/ +int sqlite3ExprCodeGetColumn( + Parse *pParse, /* Parsing and code generating context */ + Table *pTab, /* Description of the table we are reading from */ + int iColumn, /* Index of the table column */ + int iTable, /* The cursor pointing to the table */ + int iReg /* Store results here */ +){ + Vdbe *v = pParse->pVdbe; + int i; + struct yColCache *p; + + for(i=0, p=pParse->aColCache; iiReg>0 && p->iTable==iTable && p->iColumn==iColumn ){ + p->lru = pParse->iCacheCnt++; + sqlite3ExprCachePinRegister(pParse, p->iReg); + return p->iReg; + } + } + assert( v!=0 ); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iTable, iColumn, iReg); + sqlite3ExprCacheStore(pParse, iTable, iColumn, iReg); + return iReg; +} + +/* +** Clear all column cache entries. +*/ +void sqlite3ExprCacheClear(Parse *pParse){ + int i; + struct yColCache *p; + + for(i=0, p=pParse->aColCache; iiReg ){ + cacheEntryClear(pParse, p); + p->iReg = 0; + } + } +} + +/* +** Record the fact that an affinity change has occurred on iCount +** registers starting with iStart. +*/ +void sqlite3ExprCacheAffinityChange(Parse *pParse, int iStart, int iCount){ + sqlite3ExprCacheRemove(pParse, iStart, iCount); +} + +/* +** Generate code to move content from registers iFrom...iFrom+nReg-1 +** over to iTo..iTo+nReg-1. Keep the column cache up-to-date. +*/ +void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){ + int i; + struct yColCache *p; + if( NEVER(iFrom==iTo) ) return; + sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg); + for(i=0, p=pParse->aColCache; iiReg; + if( x>=iFrom && xiReg += iTo-iFrom; + } + } +} + +/* +** Generate code to copy content from registers iFrom...iFrom+nReg-1 +** over to iTo..iTo+nReg-1. +*/ +void sqlite3ExprCodeCopy(Parse *pParse, int iFrom, int iTo, int nReg){ + int i; + if( NEVER(iFrom==iTo) ) return; + for(i=0; ipVdbe, OP_Copy, iFrom+i, iTo+i); + } +} + +#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) +/* +** Return true if any register in the range iFrom..iTo (inclusive) +** is used as part of the column cache. +** +** This routine is used within assert() and testcase() macros only +** and does not appear in a normal build. +*/ +static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){ + int i; + struct yColCache *p; + for(i=0, p=pParse->aColCache; iiReg; + if( r>=iFrom && r<=iTo ) return 1; /*NO_TEST*/ + } + return 0; +} +#endif /* SQLITE_DEBUG || SQLITE_COVERAGE_TEST */ + +/* +** Generate code into the current Vdbe to evaluate the given +** expression. Attempt to store the results in register "target". +** Return the register where results are stored. +** +** With this routine, there is no guarantee that results will +** be stored in target. The result might be stored in some other +** register if it is convenient to do so. The calling function +** must check the return code and move the results to the desired +** register. +*/ +int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ + Vdbe *v = pParse->pVdbe; /* The VM under construction */ + int op; /* The opcode being coded */ + int inReg = target; /* Results stored in register inReg */ + int regFree1 = 0; /* If non-zero free this temporary register */ + int regFree2 = 0; /* If non-zero free this temporary register */ + int r1, r2, r3, r4; /* Various register numbers */ + sqlite3 *db = pParse->db; /* The database connection */ + + assert( target>0 && target<=pParse->nMem ); + if( v==0 ){ + assert( pParse->db->mallocFailed ); + return 0; + } + + if( pExpr==0 ){ + op = TK_NULL; + }else{ + op = pExpr->op; + } + switch( op ){ + case TK_AGG_COLUMN: { + AggInfo *pAggInfo = pExpr->pAggInfo; + struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg]; + if( !pAggInfo->directMode ){ + assert( pCol->iMem>0 ); + inReg = pCol->iMem; + break; + }else if( pAggInfo->useSortingIdx ){ + sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab, + pCol->iSorterColumn, target); + break; + } + /* Otherwise, fall thru into the TK_COLUMN case */ + } + case TK_COLUMN: { + if( pExpr->iTable<0 ){ + /* This only happens when coding check constraints */ + assert( pParse->ckBase>0 ); + inReg = pExpr->iColumn + pParse->ckBase; + }else{ + inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab, + pExpr->iColumn, pExpr->iTable, target); + } + break; + } + case TK_INTEGER: { + codeInteger(pParse, pExpr, 0, target); + break; + } +#ifndef SQLITE_OMIT_FLOATING_POINT + case TK_FLOAT: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + codeReal(v, pExpr->u.zToken, 0, target); + break; + } +#endif + case TK_STRING: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3VdbeAddOp4(v, OP_String8, 0, target, 0, pExpr->u.zToken, 0); + break; + } + case TK_NULL: { + sqlite3VdbeAddOp2(v, OP_Null, 0, target); + break; + } +#ifndef SQLITE_OMIT_BLOB_LITERAL + case TK_BLOB: { + int n; + const char *z; + char *zBlob; + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' ); + assert( pExpr->u.zToken[1]=='\'' ); + z = &pExpr->u.zToken[2]; + n = sqlite3Strlen30(z) - 1; + assert( z[n]=='\'' ); + zBlob = sqlite3HexToBlob(sqlite3VdbeDb(v), z, n); + sqlite3VdbeAddOp4(v, OP_Blob, n/2, target, 0, zBlob, P4_DYNAMIC); + break; + } +#endif + case TK_VARIABLE: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + assert( pExpr->u.zToken!=0 ); + assert( pExpr->u.zToken[0]!=0 ); + sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target); + if( pExpr->u.zToken[1]!=0 ){ + assert( pExpr->u.zToken[0]=='?' + || strcmp(pExpr->u.zToken, pParse->azVar[pExpr->iColumn-1])==0 ); + sqlite3VdbeChangeP4(v, -1, pParse->azVar[pExpr->iColumn-1], P4_STATIC); + } + break; + } + case TK_REGISTER: { + inReg = pExpr->iTable; + break; + } + case TK_AS: { + inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); + break; + } +#ifndef SQLITE_OMIT_CAST + case TK_CAST: { + /* Expressions of the form: CAST(pLeft AS token) */ + int aff, to_op; + inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + aff = sqlite3AffinityType(pExpr->u.zToken); + to_op = aff - SQLITE_AFF_TEXT + OP_ToText; + assert( to_op==OP_ToText || aff!=SQLITE_AFF_TEXT ); + assert( to_op==OP_ToBlob || aff!=SQLITE_AFF_NONE ); + assert( to_op==OP_ToNumeric || aff!=SQLITE_AFF_NUMERIC ); + assert( to_op==OP_ToInt || aff!=SQLITE_AFF_INTEGER ); + assert( to_op==OP_ToReal || aff!=SQLITE_AFF_REAL ); + testcase( to_op==OP_ToText ); + testcase( to_op==OP_ToBlob ); + testcase( to_op==OP_ToNumeric ); + testcase( to_op==OP_ToInt ); + testcase( to_op==OP_ToReal ); + if( inReg!=target ){ + sqlite3VdbeAddOp2(v, OP_SCopy, inReg, target); + inReg = target; + } + sqlite3VdbeAddOp1(v, to_op, inReg); + testcase( usedAsColumnCache(pParse, inReg, inReg) ); + sqlite3ExprCacheAffinityChange(pParse, inReg, 1); + break; + } +#endif /* SQLITE_OMIT_CAST */ + case TK_LT: + case TK_LE: + case TK_GT: + case TK_GE: + case TK_NE: + case TK_EQ: { + assert( TK_LT==OP_Lt ); + assert( TK_LE==OP_Le ); + assert( TK_GT==OP_Gt ); + assert( TK_GE==OP_Ge ); + assert( TK_EQ==OP_Eq ); + assert( TK_NE==OP_Ne ); + testcase( op==TK_LT ); + testcase( op==TK_LE ); + testcase( op==TK_GT ); + testcase( op==TK_GE ); + testcase( op==TK_EQ ); + testcase( op==TK_NE ); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, + r1, r2, inReg, SQLITE_STOREP2); + testcase( regFree1==0 ); + testcase( regFree2==0 ); + break; + } + case TK_IS: + case TK_ISNOT: { + testcase( op==TK_IS ); + testcase( op==TK_ISNOT ); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + op = (op==TK_IS) ? TK_EQ : TK_NE; + codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, + r1, r2, inReg, SQLITE_STOREP2 | SQLITE_NULLEQ); + testcase( regFree1==0 ); + testcase( regFree2==0 ); + break; + } + case TK_AND: + case TK_OR: + case TK_PLUS: + case TK_STAR: + case TK_MINUS: + case TK_REM: + case TK_BITAND: + case TK_BITOR: + case TK_SLASH: + case TK_LSHIFT: + case TK_RSHIFT: + case TK_CONCAT: { + assert( TK_AND==OP_And ); + assert( TK_OR==OP_Or ); + assert( TK_PLUS==OP_Add ); + assert( TK_MINUS==OP_Subtract ); + assert( TK_REM==OP_Remainder ); + assert( TK_BITAND==OP_BitAnd ); + assert( TK_BITOR==OP_BitOr ); + assert( TK_SLASH==OP_Divide ); + assert( TK_LSHIFT==OP_ShiftLeft ); + assert( TK_RSHIFT==OP_ShiftRight ); + assert( TK_CONCAT==OP_Concat ); + testcase( op==TK_AND ); + testcase( op==TK_OR ); + testcase( op==TK_PLUS ); + testcase( op==TK_MINUS ); + testcase( op==TK_REM ); + testcase( op==TK_BITAND ); + testcase( op==TK_BITOR ); + testcase( op==TK_SLASH ); + testcase( op==TK_LSHIFT ); + testcase( op==TK_RSHIFT ); + testcase( op==TK_CONCAT ); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + sqlite3VdbeAddOp3(v, op, r2, r1, target); + testcase( regFree1==0 ); + testcase( regFree2==0 ); + break; + } + case TK_UMINUS: { + Expr *pLeft = pExpr->pLeft; + assert( pLeft ); + if( pLeft->op==TK_INTEGER ){ + codeInteger(pParse, pLeft, 1, target); +#ifndef SQLITE_OMIT_FLOATING_POINT + }else if( pLeft->op==TK_FLOAT ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + codeReal(v, pLeft->u.zToken, 1, target); +#endif + }else{ + regFree1 = r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_Integer, 0, r1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free2); + sqlite3VdbeAddOp3(v, OP_Subtract, r2, r1, target); + testcase( regFree2==0 ); + } + inReg = target; + break; + } + case TK_BITNOT: + case TK_NOT: { + assert( TK_BITNOT==OP_BitNot ); + assert( TK_NOT==OP_Not ); + testcase( op==TK_BITNOT ); + testcase( op==TK_NOT ); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + testcase( regFree1==0 ); + inReg = target; + sqlite3VdbeAddOp2(v, op, r1, inReg); + break; + } + case TK_ISNULL: + case TK_NOTNULL: { + int addr; + assert( TK_ISNULL==OP_IsNull ); + assert( TK_NOTNULL==OP_NotNull ); + testcase( op==TK_ISNULL ); + testcase( op==TK_NOTNULL ); + sqlite3VdbeAddOp2(v, OP_Integer, 1, target); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + testcase( regFree1==0 ); + addr = sqlite3VdbeAddOp1(v, op, r1); + sqlite3VdbeAddOp2(v, OP_AddImm, target, -1); + sqlite3VdbeJumpHere(v, addr); + break; + } + case TK_AGG_FUNCTION: { + AggInfo *pInfo = pExpr->pAggInfo; + if( pInfo==0 ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken); + }else{ + inReg = pInfo->aFunc[pExpr->iAgg].iMem; + } + break; + } + case TK_CONST_FUNC: + case TK_FUNCTION: { + ExprList *pFarg; /* List of function arguments */ + int nFarg; /* Number of function arguments */ + FuncDef *pDef; /* The function definition object */ + int nId; /* Length of the function name in bytes */ + const char *zId; /* The function name */ + int constMask = 0; /* Mask of function arguments that are constant */ + int i; /* Loop counter */ + u8 enc = ENC(db); /* The text encoding used by this database */ + CollSeq *pColl = 0; /* A collating sequence */ + + assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); + testcase( op==TK_CONST_FUNC ); + testcase( op==TK_FUNCTION ); + if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ){ + pFarg = 0; + }else{ + pFarg = pExpr->x.pList; + } + nFarg = pFarg ? pFarg->nExpr : 0; + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + zId = pExpr->u.zToken; + nId = sqlite3Strlen30(zId); + pDef = sqlite3FindFunction(db, zId, nId, nFarg, enc, 0); + if( pDef==0 ){ + sqlite3ErrorMsg(pParse, "unknown function: %.*s()", nId, zId); + break; + } + + /* Attempt a direct implementation of the built-in COALESCE() and + ** IFNULL() functions. This avoids unnecessary evalation of + ** arguments past the first non-NULL argument. + */ + if( pDef->flags & SQLITE_FUNC_COALESCE ){ + int endCoalesce = sqlite3VdbeMakeLabel(v); + assert( nFarg>=2 ); + sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target); + for(i=1; ia[i].pExpr, target); + sqlite3ExprCachePop(pParse, 1); + } + sqlite3VdbeResolveLabel(v, endCoalesce); + break; + } + + + if( pFarg ){ + r1 = sqlite3GetTempRange(pParse, nFarg); + sqlite3ExprCachePush(pParse); /* Ticket 2ea2425d34be */ + sqlite3ExprCodeExprList(pParse, pFarg, r1, 1); + sqlite3ExprCachePop(pParse, 1); /* Ticket 2ea2425d34be */ + }else{ + r1 = 0; + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + /* Possibly overload the function if the first argument is + ** a virtual table column. + ** + ** For infix functions (LIKE, GLOB, REGEXP, and MATCH) use the + ** second argument, not the first, as the argument to test to + ** see if it is a column in a virtual table. This is done because + ** the left operand of infix functions (the operand we want to + ** control overloading) ends up as the second argument to the + ** function. The expression "A glob B" is equivalent to + ** "glob(B,A). We want to use the A in "A glob B" to test + ** for function overloading. But we use the B term in "glob(B,A)". + */ + if( nFarg>=2 && (pExpr->flags & EP_InfixFunc) ){ + pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[1].pExpr); + }else if( nFarg>0 ){ + pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[0].pExpr); + } +#endif + for(i=0; ia[i].pExpr) ){ + constMask |= (1<flags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){ + pColl = sqlite3ExprCollSeq(pParse, pFarg->a[i].pExpr); + } + } + if( pDef->flags & SQLITE_FUNC_NEEDCOLL ){ + if( !pColl ) pColl = db->pDfltColl; + sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ); + } + sqlite3VdbeAddOp4(v, OP_Function, constMask, r1, target, + (char*)pDef, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, (u8)nFarg); + if( nFarg ){ + sqlite3ReleaseTempRange(pParse, r1, nFarg); + } + break; + } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_EXISTS: + case TK_SELECT: { + testcase( op==TK_EXISTS ); + testcase( op==TK_SELECT ); + inReg = sqlite3CodeSubselect(pParse, pExpr, 0, 0); + break; + } + case TK_IN: { + int destIfFalse = sqlite3VdbeMakeLabel(v); + int destIfNull = sqlite3VdbeMakeLabel(v); + sqlite3VdbeAddOp2(v, OP_Null, 0, target); + sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull); + sqlite3VdbeAddOp2(v, OP_Integer, 1, target); + sqlite3VdbeResolveLabel(v, destIfFalse); + sqlite3VdbeAddOp2(v, OP_AddImm, target, 0); + sqlite3VdbeResolveLabel(v, destIfNull); + break; + } +#endif /* SQLITE_OMIT_SUBQUERY */ + + + /* + ** x BETWEEN y AND z + ** + ** This is equivalent to + ** + ** x>=y AND x<=z + ** + ** X is stored in pExpr->pLeft. + ** Y is stored in pExpr->pList->a[0].pExpr. + ** Z is stored in pExpr->pList->a[1].pExpr. + */ + case TK_BETWEEN: { + Expr *pLeft = pExpr->pLeft; + struct ExprList_item *pLItem = pExpr->x.pList->a; + Expr *pRight = pLItem->pExpr; + + r1 = sqlite3ExprCodeTemp(pParse, pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pRight, ®Free2); + testcase( regFree1==0 ); + testcase( regFree2==0 ); + r3 = sqlite3GetTempReg(pParse); + r4 = sqlite3GetTempReg(pParse); + codeCompare(pParse, pLeft, pRight, OP_Ge, + r1, r2, r3, SQLITE_STOREP2); + pLItem++; + pRight = pLItem->pExpr; + sqlite3ReleaseTempReg(pParse, regFree2); + r2 = sqlite3ExprCodeTemp(pParse, pRight, ®Free2); + testcase( regFree2==0 ); + codeCompare(pParse, pLeft, pRight, OP_Le, r1, r2, r4, SQLITE_STOREP2); + sqlite3VdbeAddOp3(v, OP_And, r3, r4, target); + sqlite3ReleaseTempReg(pParse, r3); + sqlite3ReleaseTempReg(pParse, r4); + break; + } + case TK_UPLUS: { + inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); + break; + } + + case TK_TRIGGER: { + /* If the opcode is TK_TRIGGER, then the expression is a reference + ** to a column in the new.* or old.* pseudo-tables available to + ** trigger programs. In this case Expr.iTable is set to 1 for the + ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn + ** is set to the column of the pseudo-table to read, or to -1 to + ** read the rowid field. + ** + ** The expression is implemented using an OP_Param opcode. The p1 + ** parameter is set to 0 for an old.rowid reference, or to (i+1) + ** to reference another column of the old.* pseudo-table, where + ** i is the index of the column. For a new.rowid reference, p1 is + ** set to (n+1), where n is the number of columns in each pseudo-table. + ** For a reference to any other column in the new.* pseudo-table, p1 + ** is set to (n+2+i), where n and i are as defined previously. For + ** example, if the table on which triggers are being fired is + ** declared as: + ** + ** CREATE TABLE t1(a, b); + ** + ** Then p1 is interpreted as follows: + ** + ** p1==0 -> old.rowid p1==3 -> new.rowid + ** p1==1 -> old.a p1==4 -> new.a + ** p1==2 -> old.b p1==5 -> new.b + */ + Table *pTab = pExpr->pTab; + int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn; + + assert( pExpr->iTable==0 || pExpr->iTable==1 ); + assert( pExpr->iColumn>=-1 && pExpr->iColumnnCol ); + assert( pTab->iPKey<0 || pExpr->iColumn!=pTab->iPKey ); + assert( p1>=0 && p1<(pTab->nCol*2+2) ); + + sqlite3VdbeAddOp2(v, OP_Param, p1, target); + VdbeComment((v, "%s.%s -> $%d", + (pExpr->iTable ? "new" : "old"), + (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName), + target + )); + +#ifndef SQLITE_OMIT_FLOATING_POINT + /* If the column has REAL affinity, it may currently be stored as an + ** integer. Use OP_RealAffinity to make sure it is really real. */ + if( pExpr->iColumn>=0 + && pTab->aCol[pExpr->iColumn].affinity==SQLITE_AFF_REAL + ){ + sqlite3VdbeAddOp1(v, OP_RealAffinity, target); + } +#endif + break; + } + + + /* + ** Form A: + ** CASE x WHEN e1 THEN r1 WHEN e2 THEN r2 ... WHEN eN THEN rN ELSE y END + ** + ** Form B: + ** CASE WHEN e1 THEN r1 WHEN e2 THEN r2 ... WHEN eN THEN rN ELSE y END + ** + ** Form A is can be transformed into the equivalent form B as follows: + ** CASE WHEN x=e1 THEN r1 WHEN x=e2 THEN r2 ... + ** WHEN x=eN THEN rN ELSE y END + ** + ** X (if it exists) is in pExpr->pLeft. + ** Y is in pExpr->pRight. The Y is also optional. If there is no + ** ELSE clause and no other term matches, then the result of the + ** exprssion is NULL. + ** Ei is in pExpr->pList->a[i*2] and Ri is pExpr->pList->a[i*2+1]. + ** + ** The result of the expression is the Ri for the first matching Ei, + ** or if there is no matching Ei, the ELSE term Y, or if there is + ** no ELSE term, NULL. + */ + default: assert( op==TK_CASE ); { + int endLabel; /* GOTO label for end of CASE stmt */ + int nextCase; /* GOTO label for next WHEN clause */ + int nExpr; /* 2x number of WHEN terms */ + int i; /* Loop counter */ + ExprList *pEList; /* List of WHEN terms */ + struct ExprList_item *aListelem; /* Array of WHEN terms */ + Expr opCompare; /* The X==Ei expression */ + Expr cacheX; /* Cached expression X */ + Expr *pX; /* The X expression */ + Expr *pTest = 0; /* X==Ei (form A) or just Ei (form B) */ + VVA_ONLY( int iCacheLevel = pParse->iCacheLevel; ) + + assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList ); + assert((pExpr->x.pList->nExpr % 2) == 0); + assert(pExpr->x.pList->nExpr > 0); + pEList = pExpr->x.pList; + aListelem = pEList->a; + nExpr = pEList->nExpr; + endLabel = sqlite3VdbeMakeLabel(v); + if( (pX = pExpr->pLeft)!=0 ){ + cacheX = *pX; + testcase( pX->op==TK_COLUMN ); + testcase( pX->op==TK_REGISTER ); + cacheX.iTable = sqlite3ExprCodeTemp(pParse, pX, ®Free1); + testcase( regFree1==0 ); + cacheX.op = TK_REGISTER; + opCompare.op = TK_EQ; + opCompare.pLeft = &cacheX; + pTest = &opCompare; + /* Ticket b351d95f9cd5ef17e9d9dbae18f5ca8611190001: + ** The value in regFree1 might get SCopy-ed into the file result. + ** So make sure that the regFree1 register is not reused for other + ** purposes and possibly overwritten. */ + regFree1 = 0; + } + for(i=0; iop==TK_COLUMN ); + sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL); + testcase( aListelem[i+1].pExpr->op==TK_COLUMN ); + testcase( aListelem[i+1].pExpr->op==TK_REGISTER ); + sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target); + sqlite3VdbeAddOp2(v, OP_Goto, 0, endLabel); + sqlite3ExprCachePop(pParse, 1); + sqlite3VdbeResolveLabel(v, nextCase); + } + if( pExpr->pRight ){ + sqlite3ExprCachePush(pParse); + sqlite3ExprCode(pParse, pExpr->pRight, target); + sqlite3ExprCachePop(pParse, 1); + }else{ + sqlite3VdbeAddOp2(v, OP_Null, 0, target); + } + assert( db->mallocFailed || pParse->nErr>0 + || pParse->iCacheLevel==iCacheLevel ); + sqlite3VdbeResolveLabel(v, endLabel); + break; + } +#ifndef SQLITE_OMIT_TRIGGER + case TK_RAISE: { + assert( pExpr->affinity==OE_Rollback + || pExpr->affinity==OE_Abort + || pExpr->affinity==OE_Fail + || pExpr->affinity==OE_Ignore + ); + if( !pParse->pTriggerTab ){ + sqlite3ErrorMsg(pParse, + "RAISE() may only be used within a trigger-program"); + return 0; + } + if( pExpr->affinity==OE_Abort ){ + sqlite3MayAbort(pParse); + } + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + if( pExpr->affinity==OE_Ignore ){ + sqlite3VdbeAddOp4( + v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0); + }else{ + sqlite3HaltConstraint(pParse, pExpr->affinity, pExpr->u.zToken, 0); + } + + break; + } +#endif + } + sqlite3ReleaseTempReg(pParse, regFree1); + sqlite3ReleaseTempReg(pParse, regFree2); + return inReg; +} + +/* +** Generate code to evaluate an expression and store the results +** into a register. Return the register number where the results +** are stored. +** +** If the register is a temporary register that can be deallocated, +** then write its number into *pReg. If the result register is not +** a temporary, then set *pReg to zero. +*/ +int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ + int r1 = sqlite3GetTempReg(pParse); + int r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1); + if( r2==r1 ){ + *pReg = r1; + }else{ + sqlite3ReleaseTempReg(pParse, r1); + *pReg = 0; + } + return r2; +} + +/* +** Generate code that will evaluate expression pExpr and store the +** results in register target. The results are guaranteed to appear +** in register target. +*/ +int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ + int inReg; + + assert( target>0 && target<=pParse->nMem ); + if( pExpr && pExpr->op==TK_REGISTER ){ + sqlite3VdbeAddOp2(pParse->pVdbe, OP_Copy, pExpr->iTable, target); + }else{ + inReg = sqlite3ExprCodeTarget(pParse, pExpr, target); + assert( pParse->pVdbe || pParse->db->mallocFailed ); + if( inReg!=target && pParse->pVdbe ){ + sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, inReg, target); + } + } + return target; +} + +/* +** Generate code that evalutes the given expression and puts the result +** in register target. +** +** Also make a copy of the expression results into another "cache" register +** and modify the expression so that the next time it is evaluated, +** the result is a copy of the cache register. +** +** This routine is used for expressions that are used multiple +** times. They are evaluated once and the results of the expression +** are reused. +*/ +int sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){ + Vdbe *v = pParse->pVdbe; + int inReg; + inReg = sqlite3ExprCode(pParse, pExpr, target); + assert( target>0 ); + /* This routine is called for terms to INSERT or UPDATE. And the only + ** other place where expressions can be converted into TK_REGISTER is + ** in WHERE clause processing. So as currently implemented, there is + ** no way for a TK_REGISTER to exist here. But it seems prudent to + ** keep the ALWAYS() in case the conditions above change with future + ** modifications or enhancements. */ + if( ALWAYS(pExpr->op!=TK_REGISTER) ){ + int iMem; + iMem = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Copy, inReg, iMem); + pExpr->iTable = iMem; + pExpr->op2 = pExpr->op; + pExpr->op = TK_REGISTER; + } + return inReg; +} + +#if defined(SQLITE_ENABLE_TREE_EXPLAIN) +/* +** Generate a human-readable explanation of an expression tree. +*/ +void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){ + int op; /* The opcode being coded */ + const char *zBinOp = 0; /* Binary operator */ + const char *zUniOp = 0; /* Unary operator */ + if( pExpr==0 ){ + op = TK_NULL; + }else{ + op = pExpr->op; + } + switch( op ){ + case TK_AGG_COLUMN: { + sqlite3ExplainPrintf(pOut, "AGG{%d:%d}", + pExpr->iTable, pExpr->iColumn); + break; + } + case TK_COLUMN: { + if( pExpr->iTable<0 ){ + /* This only happens when coding check constraints */ + sqlite3ExplainPrintf(pOut, "COLUMN(%d)", pExpr->iColumn); + }else{ + sqlite3ExplainPrintf(pOut, "{%d:%d}", + pExpr->iTable, pExpr->iColumn); + } + break; + } + case TK_INTEGER: { + if( pExpr->flags & EP_IntValue ){ + sqlite3ExplainPrintf(pOut, "%d", pExpr->u.iValue); + }else{ + sqlite3ExplainPrintf(pOut, "%s", pExpr->u.zToken); + } + break; + } +#ifndef SQLITE_OMIT_FLOATING_POINT + case TK_FLOAT: { + sqlite3ExplainPrintf(pOut,"%s", pExpr->u.zToken); + break; + } +#endif + case TK_STRING: { + sqlite3ExplainPrintf(pOut,"%Q", pExpr->u.zToken); + break; + } + case TK_NULL: { + sqlite3ExplainPrintf(pOut,"NULL"); + break; + } +#ifndef SQLITE_OMIT_BLOB_LITERAL + case TK_BLOB: { + sqlite3ExplainPrintf(pOut,"%s", pExpr->u.zToken); + break; + } +#endif + case TK_VARIABLE: { + sqlite3ExplainPrintf(pOut,"VARIABLE(%s,%d)", + pExpr->u.zToken, pExpr->iColumn); + break; + } + case TK_REGISTER: { + sqlite3ExplainPrintf(pOut,"REGISTER(%d)", pExpr->iTable); + break; + } + case TK_AS: { + sqlite3ExplainExpr(pOut, pExpr->pLeft); + break; + } +#ifndef SQLITE_OMIT_CAST + case TK_CAST: { + /* Expressions of the form: CAST(pLeft AS token) */ + const char *zAff = "unk"; + switch( sqlite3AffinityType(pExpr->u.zToken) ){ + case SQLITE_AFF_TEXT: zAff = "TEXT"; break; + case SQLITE_AFF_NONE: zAff = "NONE"; break; + case SQLITE_AFF_NUMERIC: zAff = "NUMERIC"; break; + case SQLITE_AFF_INTEGER: zAff = "INTEGER"; break; + case SQLITE_AFF_REAL: zAff = "REAL"; break; + } + sqlite3ExplainPrintf(pOut, "CAST-%s(", zAff); + sqlite3ExplainExpr(pOut, pExpr->pLeft); + sqlite3ExplainPrintf(pOut, ")"); + break; + } +#endif /* SQLITE_OMIT_CAST */ + case TK_LT: zBinOp = "LT"; break; + case TK_LE: zBinOp = "LE"; break; + case TK_GT: zBinOp = "GT"; break; + case TK_GE: zBinOp = "GE"; break; + case TK_NE: zBinOp = "NE"; break; + case TK_EQ: zBinOp = "EQ"; break; + case TK_IS: zBinOp = "IS"; break; + case TK_ISNOT: zBinOp = "ISNOT"; break; + case TK_AND: zBinOp = "AND"; break; + case TK_OR: zBinOp = "OR"; break; + case TK_PLUS: zBinOp = "ADD"; break; + case TK_STAR: zBinOp = "MUL"; break; + case TK_MINUS: zBinOp = "SUB"; break; + case TK_REM: zBinOp = "REM"; break; + case TK_BITAND: zBinOp = "BITAND"; break; + case TK_BITOR: zBinOp = "BITOR"; break; + case TK_SLASH: zBinOp = "DIV"; break; + case TK_LSHIFT: zBinOp = "LSHIFT"; break; + case TK_RSHIFT: zBinOp = "RSHIFT"; break; + case TK_CONCAT: zBinOp = "CONCAT"; break; + + case TK_UMINUS: zUniOp = "UMINUS"; break; + case TK_UPLUS: zUniOp = "UPLUS"; break; + case TK_BITNOT: zUniOp = "BITNOT"; break; + case TK_NOT: zUniOp = "NOT"; break; + case TK_ISNULL: zUniOp = "ISNULL"; break; + case TK_NOTNULL: zUniOp = "NOTNULL"; break; + + case TK_AGG_FUNCTION: + case TK_CONST_FUNC: + case TK_FUNCTION: { + ExprList *pFarg; /* List of function arguments */ + if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ){ + pFarg = 0; + }else{ + pFarg = pExpr->x.pList; + } + sqlite3ExplainPrintf(pOut, "%sFUNCTION:%s(", + op==TK_AGG_FUNCTION ? "AGG_" : "", + pExpr->u.zToken); + if( pFarg ){ + sqlite3ExplainExprList(pOut, pFarg); + } + sqlite3ExplainPrintf(pOut, ")"); + break; + } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_EXISTS: { + sqlite3ExplainPrintf(pOut, "EXISTS("); + sqlite3ExplainSelect(pOut, pExpr->x.pSelect); + sqlite3ExplainPrintf(pOut,")"); + break; + } + case TK_SELECT: { + sqlite3ExplainPrintf(pOut, "("); + sqlite3ExplainSelect(pOut, pExpr->x.pSelect); + sqlite3ExplainPrintf(pOut, ")"); + break; + } + case TK_IN: { + sqlite3ExplainPrintf(pOut, "IN("); + sqlite3ExplainExpr(pOut, pExpr->pLeft); + sqlite3ExplainPrintf(pOut, ","); + if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + sqlite3ExplainSelect(pOut, pExpr->x.pSelect); + }else{ + sqlite3ExplainExprList(pOut, pExpr->x.pList); + } + sqlite3ExplainPrintf(pOut, ")"); + break; + } +#endif /* SQLITE_OMIT_SUBQUERY */ + + /* + ** x BETWEEN y AND z + ** + ** This is equivalent to + ** + ** x>=y AND x<=z + ** + ** X is stored in pExpr->pLeft. + ** Y is stored in pExpr->pList->a[0].pExpr. + ** Z is stored in pExpr->pList->a[1].pExpr. + */ + case TK_BETWEEN: { + Expr *pX = pExpr->pLeft; + Expr *pY = pExpr->x.pList->a[0].pExpr; + Expr *pZ = pExpr->x.pList->a[1].pExpr; + sqlite3ExplainPrintf(pOut, "BETWEEN("); + sqlite3ExplainExpr(pOut, pX); + sqlite3ExplainPrintf(pOut, ","); + sqlite3ExplainExpr(pOut, pY); + sqlite3ExplainPrintf(pOut, ","); + sqlite3ExplainExpr(pOut, pZ); + sqlite3ExplainPrintf(pOut, ")"); + break; + } + case TK_TRIGGER: { + /* If the opcode is TK_TRIGGER, then the expression is a reference + ** to a column in the new.* or old.* pseudo-tables available to + ** trigger programs. In this case Expr.iTable is set to 1 for the + ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn + ** is set to the column of the pseudo-table to read, or to -1 to + ** read the rowid field. + */ + sqlite3ExplainPrintf(pOut, "%s(%d)", + pExpr->iTable ? "NEW" : "OLD", pExpr->iColumn); + break; + } + case TK_CASE: { + sqlite3ExplainPrintf(pOut, "CASE("); + sqlite3ExplainExpr(pOut, pExpr->pLeft); + sqlite3ExplainPrintf(pOut, ","); + sqlite3ExplainExprList(pOut, pExpr->x.pList); + break; + } +#ifndef SQLITE_OMIT_TRIGGER + case TK_RAISE: { + const char *zType = "unk"; + switch( pExpr->affinity ){ + case OE_Rollback: zType = "rollback"; break; + case OE_Abort: zType = "abort"; break; + case OE_Fail: zType = "fail"; break; + case OE_Ignore: zType = "ignore"; break; + } + sqlite3ExplainPrintf(pOut, "RAISE-%s(%s)", zType, pExpr->u.zToken); + break; + } +#endif + } + if( zBinOp ){ + sqlite3ExplainPrintf(pOut,"%s(", zBinOp); + sqlite3ExplainExpr(pOut, pExpr->pLeft); + sqlite3ExplainPrintf(pOut,","); + sqlite3ExplainExpr(pOut, pExpr->pRight); + sqlite3ExplainPrintf(pOut,")"); + }else if( zUniOp ){ + sqlite3ExplainPrintf(pOut,"%s(", zUniOp); + sqlite3ExplainExpr(pOut, pExpr->pLeft); + sqlite3ExplainPrintf(pOut,")"); + } +} +#endif /* defined(SQLITE_ENABLE_TREE_EXPLAIN) */ + +#if defined(SQLITE_ENABLE_TREE_EXPLAIN) +/* +** Generate a human-readable explanation of an expression list. +*/ +void sqlite3ExplainExprList(Vdbe *pOut, ExprList *pList){ + int i; + if( pList==0 || pList->nExpr==0 ){ + sqlite3ExplainPrintf(pOut, "(empty-list)"); + return; + }else if( pList->nExpr==1 ){ + sqlite3ExplainExpr(pOut, pList->a[0].pExpr); + }else{ + sqlite3ExplainPush(pOut); + for(i=0; inExpr; i++){ + sqlite3ExplainPrintf(pOut, "item[%d] = ", i); + sqlite3ExplainPush(pOut); + sqlite3ExplainExpr(pOut, pList->a[i].pExpr); + sqlite3ExplainPop(pOut); + if( inExpr-1 ){ + sqlite3ExplainNL(pOut); + } + } + sqlite3ExplainPop(pOut); + } +} +#endif /* SQLITE_DEBUG */ + +/* +** Return TRUE if pExpr is an constant expression that is appropriate +** for factoring out of a loop. Appropriate expressions are: +** +** * Any expression that evaluates to two or more opcodes. +** +** * Any OP_Integer, OP_Real, OP_String, OP_Blob, OP_Null, +** or OP_Variable that does not need to be placed in a +** specific register. +** +** There is no point in factoring out single-instruction constant +** expressions that need to be placed in a particular register. +** We could factor them out, but then we would end up adding an +** OP_SCopy instruction to move the value into the correct register +** later. We might as well just use the original instruction and +** avoid the OP_SCopy. +*/ +static int isAppropriateForFactoring(Expr *p){ + if( !sqlite3ExprIsConstantNotJoin(p) ){ + return 0; /* Only constant expressions are appropriate for factoring */ + } + if( (p->flags & EP_FixedDest)==0 ){ + return 1; /* Any constant without a fixed destination is appropriate */ + } + while( p->op==TK_UPLUS ) p = p->pLeft; + switch( p->op ){ +#ifndef SQLITE_OMIT_BLOB_LITERAL + case TK_BLOB: +#endif + case TK_VARIABLE: + case TK_INTEGER: + case TK_FLOAT: + case TK_NULL: + case TK_STRING: { + testcase( p->op==TK_BLOB ); + testcase( p->op==TK_VARIABLE ); + testcase( p->op==TK_INTEGER ); + testcase( p->op==TK_FLOAT ); + testcase( p->op==TK_NULL ); + testcase( p->op==TK_STRING ); + /* Single-instruction constants with a fixed destination are + ** better done in-line. If we factor them, they will just end + ** up generating an OP_SCopy to move the value to the destination + ** register. */ + return 0; + } + case TK_UMINUS: { + if( p->pLeft->op==TK_FLOAT || p->pLeft->op==TK_INTEGER ){ + return 0; + } + break; + } + default: { + break; + } + } + return 1; +} + +/* +** If pExpr is a constant expression that is appropriate for +** factoring out of a loop, then evaluate the expression +** into a register and convert the expression into a TK_REGISTER +** expression. +*/ +static int evalConstExpr(Walker *pWalker, Expr *pExpr){ + Parse *pParse = pWalker->pParse; + switch( pExpr->op ){ + case TK_IN: + case TK_REGISTER: { + return WRC_Prune; + } + case TK_FUNCTION: + case TK_AGG_FUNCTION: + case TK_CONST_FUNC: { + /* The arguments to a function have a fixed destination. + ** Mark them this way to avoid generated unneeded OP_SCopy + ** instructions. + */ + ExprList *pList = pExpr->x.pList; + assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); + if( pList ){ + int i = pList->nExpr; + struct ExprList_item *pItem = pList->a; + for(; i>0; i--, pItem++){ + if( ALWAYS(pItem->pExpr) ) pItem->pExpr->flags |= EP_FixedDest; + } + } + break; + } + } + if( isAppropriateForFactoring(pExpr) ){ + int r1 = ++pParse->nMem; + int r2; + r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1); + if( NEVER(r1!=r2) ) sqlite3ReleaseTempReg(pParse, r1); + pExpr->op2 = pExpr->op; + pExpr->op = TK_REGISTER; + pExpr->iTable = r2; + return WRC_Prune; + } + return WRC_Continue; +} + +/* +** Preevaluate constant subexpressions within pExpr and store the +** results in registers. Modify pExpr so that the constant subexpresions +** are TK_REGISTER opcodes that refer to the precomputed values. +** +** This routine is a no-op if the jump to the cookie-check code has +** already occur. Since the cookie-check jump is generated prior to +** any other serious processing, this check ensures that there is no +** way to accidently bypass the constant initializations. +** +** This routine is also a no-op if the SQLITE_FactorOutConst optimization +** is disabled via the sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS) +** interface. This allows test logic to verify that the same answer is +** obtained for queries regardless of whether or not constants are +** precomputed into registers or if they are inserted in-line. +*/ +void sqlite3ExprCodeConstants(Parse *pParse, Expr *pExpr){ + Walker w; + if( pParse->cookieGoto ) return; + if( (pParse->db->flags & SQLITE_FactorOutConst)!=0 ) return; + w.xExprCallback = evalConstExpr; + w.xSelectCallback = 0; + w.pParse = pParse; + sqlite3WalkExpr(&w, pExpr); +} + + +/* +** Generate code that pushes the value of every element of the given +** expression list into a sequence of registers beginning at target. +** +** Return the number of elements evaluated. +*/ +int sqlite3ExprCodeExprList( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* The expression list to be coded */ + int target, /* Where to write results */ + int doHardCopy /* Make a hard copy of every element */ +){ + struct ExprList_item *pItem; + int i, n; + assert( pList!=0 ); + assert( target>0 ); + assert( pParse->pVdbe!=0 ); /* Never gets this far otherwise */ + n = pList->nExpr; + for(pItem=pList->a, i=0; ipExpr; + int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i); + if( inReg!=target+i ){ + sqlite3VdbeAddOp2(pParse->pVdbe, doHardCopy ? OP_Copy : OP_SCopy, + inReg, target+i); + } + } + return n; +} + +/* +** Generate code for a BETWEEN operator. +** +** x BETWEEN y AND z +** +** The above is equivalent to +** +** x>=y AND x<=z +** +** Code it as such, taking care to do the common subexpression +** elementation of x. +*/ +static void exprCodeBetween( + Parse *pParse, /* Parsing and code generating context */ + Expr *pExpr, /* The BETWEEN expression */ + int dest, /* Jump here if the jump is taken */ + int jumpIfTrue, /* Take the jump if the BETWEEN is true */ + int jumpIfNull /* Take the jump if the BETWEEN is NULL */ +){ + Expr exprAnd; /* The AND operator in x>=y AND x<=z */ + Expr compLeft; /* The x>=y term */ + Expr compRight; /* The x<=z term */ + Expr exprX; /* The x subexpression */ + int regFree1 = 0; /* Temporary use register */ + + assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); + exprX = *pExpr->pLeft; + exprAnd.op = TK_AND; + exprAnd.pLeft = &compLeft; + exprAnd.pRight = &compRight; + compLeft.op = TK_GE; + compLeft.pLeft = &exprX; + compLeft.pRight = pExpr->x.pList->a[0].pExpr; + compRight.op = TK_LE; + compRight.pLeft = &exprX; + compRight.pRight = pExpr->x.pList->a[1].pExpr; + exprX.iTable = sqlite3ExprCodeTemp(pParse, &exprX, ®Free1); + exprX.op = TK_REGISTER; + if( jumpIfTrue ){ + sqlite3ExprIfTrue(pParse, &exprAnd, dest, jumpIfNull); + }else{ + sqlite3ExprIfFalse(pParse, &exprAnd, dest, jumpIfNull); + } + sqlite3ReleaseTempReg(pParse, regFree1); + + /* Ensure adequate test coverage */ + testcase( jumpIfTrue==0 && jumpIfNull==0 && regFree1==0 ); + testcase( jumpIfTrue==0 && jumpIfNull==0 && regFree1!=0 ); + testcase( jumpIfTrue==0 && jumpIfNull!=0 && regFree1==0 ); + testcase( jumpIfTrue==0 && jumpIfNull!=0 && regFree1!=0 ); + testcase( jumpIfTrue!=0 && jumpIfNull==0 && regFree1==0 ); + testcase( jumpIfTrue!=0 && jumpIfNull==0 && regFree1!=0 ); + testcase( jumpIfTrue!=0 && jumpIfNull!=0 && regFree1==0 ); + testcase( jumpIfTrue!=0 && jumpIfNull!=0 && regFree1!=0 ); +} + +/* +** Generate code for a boolean expression such that a jump is made +** to the label "dest" if the expression is true but execution +** continues straight thru if the expression is false. +** +** If the expression evaluates to NULL (neither true nor false), then +** take the jump if the jumpIfNull flag is SQLITE_JUMPIFNULL. +** +** This code depends on the fact that certain token values (ex: TK_EQ) +** are the same as opcode values (ex: OP_Eq) that implement the corresponding +** operation. Special comments in vdbe.c and the mkopcodeh.awk script in +** the make process cause these values to align. Assert()s in the code +** below verify that the numbers are aligned correctly. +*/ +void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ + Vdbe *v = pParse->pVdbe; + int op = 0; + int regFree1 = 0; + int regFree2 = 0; + int r1, r2; + + assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 ); + if( NEVER(v==0) ) return; /* Existance of VDBE checked by caller */ + if( NEVER(pExpr==0) ) return; /* No way this can happen */ + op = pExpr->op; + switch( op ){ + case TK_AND: { + int d2 = sqlite3VdbeMakeLabel(v); + testcase( jumpIfNull==0 ); + sqlite3ExprCachePush(pParse); + sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL); + sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); + sqlite3VdbeResolveLabel(v, d2); + sqlite3ExprCachePop(pParse, 1); + break; + } + case TK_OR: { + testcase( jumpIfNull==0 ); + sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); + sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); + break; + } + case TK_NOT: { + testcase( jumpIfNull==0 ); + sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); + break; + } + case TK_LT: + case TK_LE: + case TK_GT: + case TK_GE: + case TK_NE: + case TK_EQ: { + assert( TK_LT==OP_Lt ); + assert( TK_LE==OP_Le ); + assert( TK_GT==OP_Gt ); + assert( TK_GE==OP_Ge ); + assert( TK_EQ==OP_Eq ); + assert( TK_NE==OP_Ne ); + testcase( op==TK_LT ); + testcase( op==TK_LE ); + testcase( op==TK_GT ); + testcase( op==TK_GE ); + testcase( op==TK_EQ ); + testcase( op==TK_NE ); + testcase( jumpIfNull==0 ); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, + r1, r2, dest, jumpIfNull); + testcase( regFree1==0 ); + testcase( regFree2==0 ); + break; + } + case TK_IS: + case TK_ISNOT: { + testcase( op==TK_IS ); + testcase( op==TK_ISNOT ); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + op = (op==TK_IS) ? TK_EQ : TK_NE; + codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, + r1, r2, dest, SQLITE_NULLEQ); + testcase( regFree1==0 ); + testcase( regFree2==0 ); + break; + } + case TK_ISNULL: + case TK_NOTNULL: { + assert( TK_ISNULL==OP_IsNull ); + assert( TK_NOTNULL==OP_NotNull ); + testcase( op==TK_ISNULL ); + testcase( op==TK_NOTNULL ); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + sqlite3VdbeAddOp2(v, op, r1, dest); + testcase( regFree1==0 ); + break; + } + case TK_BETWEEN: { + testcase( jumpIfNull==0 ); + exprCodeBetween(pParse, pExpr, dest, 1, jumpIfNull); + break; + } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_IN: { + int destIfFalse = sqlite3VdbeMakeLabel(v); + int destIfNull = jumpIfNull ? dest : destIfFalse; + sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull); + sqlite3VdbeAddOp2(v, OP_Goto, 0, dest); + sqlite3VdbeResolveLabel(v, destIfFalse); + break; + } +#endif + default: { + r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1); + sqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0); + testcase( regFree1==0 ); + testcase( jumpIfNull==0 ); + break; + } + } + sqlite3ReleaseTempReg(pParse, regFree1); + sqlite3ReleaseTempReg(pParse, regFree2); +} + +/* +** Generate code for a boolean expression such that a jump is made +** to the label "dest" if the expression is false but execution +** continues straight thru if the expression is true. +** +** If the expression evaluates to NULL (neither true nor false) then +** jump if jumpIfNull is SQLITE_JUMPIFNULL or fall through if jumpIfNull +** is 0. +*/ +void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ + Vdbe *v = pParse->pVdbe; + int op = 0; + int regFree1 = 0; + int regFree2 = 0; + int r1, r2; + + assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 ); + if( NEVER(v==0) ) return; /* Existance of VDBE checked by caller */ + if( pExpr==0 ) return; + + /* The value of pExpr->op and op are related as follows: + ** + ** pExpr->op op + ** --------- ---------- + ** TK_ISNULL OP_NotNull + ** TK_NOTNULL OP_IsNull + ** TK_NE OP_Eq + ** TK_EQ OP_Ne + ** TK_GT OP_Le + ** TK_LE OP_Gt + ** TK_GE OP_Lt + ** TK_LT OP_Ge + ** + ** For other values of pExpr->op, op is undefined and unused. + ** The value of TK_ and OP_ constants are arranged such that we + ** can compute the mapping above using the following expression. + ** Assert()s verify that the computation is correct. + */ + op = ((pExpr->op+(TK_ISNULL&1))^1)-(TK_ISNULL&1); + + /* Verify correct alignment of TK_ and OP_ constants + */ + assert( pExpr->op!=TK_ISNULL || op==OP_NotNull ); + assert( pExpr->op!=TK_NOTNULL || op==OP_IsNull ); + assert( pExpr->op!=TK_NE || op==OP_Eq ); + assert( pExpr->op!=TK_EQ || op==OP_Ne ); + assert( pExpr->op!=TK_LT || op==OP_Ge ); + assert( pExpr->op!=TK_LE || op==OP_Gt ); + assert( pExpr->op!=TK_GT || op==OP_Le ); + assert( pExpr->op!=TK_GE || op==OP_Lt ); + + switch( pExpr->op ){ + case TK_AND: { + testcase( jumpIfNull==0 ); + sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); + sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); + break; + } + case TK_OR: { + int d2 = sqlite3VdbeMakeLabel(v); + testcase( jumpIfNull==0 ); + sqlite3ExprCachePush(pParse); + sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL); + sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); + sqlite3VdbeResolveLabel(v, d2); + sqlite3ExprCachePop(pParse, 1); + break; + } + case TK_NOT: { + testcase( jumpIfNull==0 ); + sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); + break; + } + case TK_LT: + case TK_LE: + case TK_GT: + case TK_GE: + case TK_NE: + case TK_EQ: { + testcase( op==TK_LT ); + testcase( op==TK_LE ); + testcase( op==TK_GT ); + testcase( op==TK_GE ); + testcase( op==TK_EQ ); + testcase( op==TK_NE ); + testcase( jumpIfNull==0 ); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, + r1, r2, dest, jumpIfNull); + testcase( regFree1==0 ); + testcase( regFree2==0 ); + break; + } + case TK_IS: + case TK_ISNOT: { + testcase( pExpr->op==TK_IS ); + testcase( pExpr->op==TK_ISNOT ); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ; + codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, + r1, r2, dest, SQLITE_NULLEQ); + testcase( regFree1==0 ); + testcase( regFree2==0 ); + break; + } + case TK_ISNULL: + case TK_NOTNULL: { + testcase( op==TK_ISNULL ); + testcase( op==TK_NOTNULL ); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + sqlite3VdbeAddOp2(v, op, r1, dest); + testcase( regFree1==0 ); + break; + } + case TK_BETWEEN: { + testcase( jumpIfNull==0 ); + exprCodeBetween(pParse, pExpr, dest, 0, jumpIfNull); + break; + } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_IN: { + if( jumpIfNull ){ + sqlite3ExprCodeIN(pParse, pExpr, dest, dest); + }else{ + int destIfNull = sqlite3VdbeMakeLabel(v); + sqlite3ExprCodeIN(pParse, pExpr, dest, destIfNull); + sqlite3VdbeResolveLabel(v, destIfNull); + } + break; + } +#endif + default: { + r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1); + sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0); + testcase( regFree1==0 ); + testcase( jumpIfNull==0 ); + break; + } + } + sqlite3ReleaseTempReg(pParse, regFree1); + sqlite3ReleaseTempReg(pParse, regFree2); +} + +/* +** Do a deep comparison of two expression trees. Return 0 if the two +** expressions are completely identical. Return 1 if they differ only +** by a COLLATE operator at the top level. Return 2 if there are differences +** other than the top-level COLLATE operator. +** +** Sometimes this routine will return 2 even if the two expressions +** really are equivalent. If we cannot prove that the expressions are +** identical, we return 2 just to be safe. So if this routine +** returns 2, then you do not really know for certain if the two +** expressions are the same. But if you get a 0 or 1 return, then you +** can be sure the expressions are the same. In the places where +** this routine is used, it does not hurt to get an extra 2 - that +** just might result in some slightly slower code. But returning +** an incorrect 0 or 1 could lead to a malfunction. +*/ +int sqlite3ExprCompare(Expr *pA, Expr *pB){ + if( pA==0||pB==0 ){ + return pB==pA ? 0 : 2; + } + assert( !ExprHasAnyProperty(pA, EP_TokenOnly|EP_Reduced) ); + assert( !ExprHasAnyProperty(pB, EP_TokenOnly|EP_Reduced) ); + if( ExprHasProperty(pA, EP_xIsSelect) || ExprHasProperty(pB, EP_xIsSelect) ){ + return 2; + } + if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2; + if( pA->op!=pB->op ) return 2; + if( sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 2; + if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2; + if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2; + if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 2; + if( ExprHasProperty(pA, EP_IntValue) ){ + if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){ + return 2; + } + }else if( pA->op!=TK_COLUMN && pA->u.zToken ){ + if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2; + if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){ + return 2; + } + } + if( (pA->flags & EP_ExpCollate)!=(pB->flags & EP_ExpCollate) ) return 1; + if( (pA->flags & EP_ExpCollate)!=0 && pA->pColl!=pB->pColl ) return 2; + return 0; +} + +/* +** Compare two ExprList objects. Return 0 if they are identical and +** non-zero if they differ in any way. +** +** This routine might return non-zero for equivalent ExprLists. The +** only consequence will be disabled optimizations. But this routine +** must never return 0 if the two ExprList objects are different, or +** a malfunction will result. +** +** Two NULL pointers are considered to be the same. But a NULL pointer +** always differs from a non-NULL pointer. +*/ +int sqlite3ExprListCompare(ExprList *pA, ExprList *pB){ + int i; + if( pA==0 && pB==0 ) return 0; + if( pA==0 || pB==0 ) return 1; + if( pA->nExpr!=pB->nExpr ) return 1; + for(i=0; inExpr; i++){ + Expr *pExprA = pA->a[i].pExpr; + Expr *pExprB = pB->a[i].pExpr; + if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1; + if( sqlite3ExprCompare(pExprA, pExprB) ) return 1; + } + return 0; +} + +/* +** Add a new element to the pAggInfo->aCol[] array. Return the index of +** the new element. Return a negative number if malloc fails. +*/ +static int addAggInfoColumn(sqlite3 *db, AggInfo *pInfo){ + int i; + pInfo->aCol = sqlite3ArrayAllocate( + db, + pInfo->aCol, + sizeof(pInfo->aCol[0]), + 3, + &pInfo->nColumn, + &pInfo->nColumnAlloc, + &i + ); + return i; +} + +/* +** Add a new element to the pAggInfo->aFunc[] array. Return the index of +** the new element. Return a negative number if malloc fails. +*/ +static int addAggInfoFunc(sqlite3 *db, AggInfo *pInfo){ + int i; + pInfo->aFunc = sqlite3ArrayAllocate( + db, + pInfo->aFunc, + sizeof(pInfo->aFunc[0]), + 3, + &pInfo->nFunc, + &pInfo->nFuncAlloc, + &i + ); + return i; +} + +/* +** This is the xExprCallback for a tree walker. It is used to +** implement sqlite3ExprAnalyzeAggregates(). See sqlite3ExprAnalyzeAggregates +** for additional information. +*/ +static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ + int i; + NameContext *pNC = pWalker->u.pNC; + Parse *pParse = pNC->pParse; + SrcList *pSrcList = pNC->pSrcList; + AggInfo *pAggInfo = pNC->pAggInfo; + + switch( pExpr->op ){ + case TK_AGG_COLUMN: + case TK_COLUMN: { + testcase( pExpr->op==TK_AGG_COLUMN ); + testcase( pExpr->op==TK_COLUMN ); + /* Check to see if the column is in one of the tables in the FROM + ** clause of the aggregate query */ + if( ALWAYS(pSrcList!=0) ){ + struct SrcList_item *pItem = pSrcList->a; + for(i=0; inSrc; i++, pItem++){ + struct AggInfo_col *pCol; + assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) ); + if( pExpr->iTable==pItem->iCursor ){ + /* If we reach this point, it means that pExpr refers to a table + ** that is in the FROM clause of the aggregate query. + ** + ** Make an entry for the column in pAggInfo->aCol[] if there + ** is not an entry there already. + */ + int k; + pCol = pAggInfo->aCol; + for(k=0; knColumn; k++, pCol++){ + if( pCol->iTable==pExpr->iTable && + pCol->iColumn==pExpr->iColumn ){ + break; + } + } + if( (k>=pAggInfo->nColumn) + && (k = addAggInfoColumn(pParse->db, pAggInfo))>=0 + ){ + pCol = &pAggInfo->aCol[k]; + pCol->pTab = pExpr->pTab; + pCol->iTable = pExpr->iTable; + pCol->iColumn = pExpr->iColumn; + pCol->iMem = ++pParse->nMem; + pCol->iSorterColumn = -1; + pCol->pExpr = pExpr; + if( pAggInfo->pGroupBy ){ + int j, n; + ExprList *pGB = pAggInfo->pGroupBy; + struct ExprList_item *pTerm = pGB->a; + n = pGB->nExpr; + for(j=0; jpExpr; + if( pE->op==TK_COLUMN && pE->iTable==pExpr->iTable && + pE->iColumn==pExpr->iColumn ){ + pCol->iSorterColumn = j; + break; + } + } + } + if( pCol->iSorterColumn<0 ){ + pCol->iSorterColumn = pAggInfo->nSortingColumn++; + } + } + /* There is now an entry for pExpr in pAggInfo->aCol[] (either + ** because it was there before or because we just created it). + ** Convert the pExpr to be a TK_AGG_COLUMN referring to that + ** pAggInfo->aCol[] entry. + */ + ExprSetIrreducible(pExpr); + pExpr->pAggInfo = pAggInfo; + pExpr->op = TK_AGG_COLUMN; + pExpr->iAgg = (i16)k; + break; + } /* endif pExpr->iTable==pItem->iCursor */ + } /* end loop over pSrcList */ + } + return WRC_Prune; + } + case TK_AGG_FUNCTION: { + /* The pNC->nDepth==0 test causes aggregate functions in subqueries + ** to be ignored */ + if( pNC->nDepth==0 ){ + /* Check to see if pExpr is a duplicate of another aggregate + ** function that is already in the pAggInfo structure + */ + struct AggInfo_func *pItem = pAggInfo->aFunc; + for(i=0; inFunc; i++, pItem++){ + if( sqlite3ExprCompare(pItem->pExpr, pExpr)==0 ){ + break; + } + } + if( i>=pAggInfo->nFunc ){ + /* pExpr is original. Make a new entry in pAggInfo->aFunc[] + */ + u8 enc = ENC(pParse->db); + i = addAggInfoFunc(pParse->db, pAggInfo); + if( i>=0 ){ + assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); + pItem = &pAggInfo->aFunc[i]; + pItem->pExpr = pExpr; + pItem->iMem = ++pParse->nMem; + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + pItem->pFunc = sqlite3FindFunction(pParse->db, + pExpr->u.zToken, sqlite3Strlen30(pExpr->u.zToken), + pExpr->x.pList ? pExpr->x.pList->nExpr : 0, enc, 0); + if( pExpr->flags & EP_Distinct ){ + pItem->iDistinct = pParse->nTab++; + }else{ + pItem->iDistinct = -1; + } + } + } + /* Make pExpr point to the appropriate pAggInfo->aFunc[] entry + */ + assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) ); + ExprSetIrreducible(pExpr); + pExpr->iAgg = (i16)i; + pExpr->pAggInfo = pAggInfo; + return WRC_Prune; + } + } + } + return WRC_Continue; +} +static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){ + NameContext *pNC = pWalker->u.pNC; + if( pNC->nDepth==0 ){ + pNC->nDepth++; + sqlite3WalkSelect(pWalker, pSelect); + pNC->nDepth--; + return WRC_Prune; + }else{ + return WRC_Continue; + } +} + +/* +** Analyze the given expression looking for aggregate functions and +** for variables that need to be added to the pParse->aAgg[] array. +** Make additional entries to the pParse->aAgg[] array as necessary. +** +** This routine should only be called after the expression has been +** analyzed by sqlite3ResolveExprNames(). +*/ +void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){ + Walker w; + w.xExprCallback = analyzeAggregate; + w.xSelectCallback = analyzeAggregatesInSelect; + w.u.pNC = pNC; + assert( pNC->pSrcList!=0 ); + sqlite3WalkExpr(&w, pExpr); +} + +/* +** Call sqlite3ExprAnalyzeAggregates() for every expression in an +** expression list. Return the number of errors. +** +** If an error is found, the analysis is cut short. +*/ +void sqlite3ExprAnalyzeAggList(NameContext *pNC, ExprList *pList){ + struct ExprList_item *pItem; + int i; + if( pList ){ + for(pItem=pList->a, i=0; inExpr; i++, pItem++){ + sqlite3ExprAnalyzeAggregates(pNC, pItem->pExpr); + } + } +} + +/* +** Allocate a single new register for use to hold some intermediate result. +*/ +int sqlite3GetTempReg(Parse *pParse){ + if( pParse->nTempReg==0 ){ + return ++pParse->nMem; + } + return pParse->aTempReg[--pParse->nTempReg]; +} + +/* +** Deallocate a register, making available for reuse for some other +** purpose. +** +** If a register is currently being used by the column cache, then +** the dallocation is deferred until the column cache line that uses +** the register becomes stale. +*/ +void sqlite3ReleaseTempReg(Parse *pParse, int iReg){ + if( iReg && pParse->nTempRegaTempReg) ){ + int i; + struct yColCache *p; + for(i=0, p=pParse->aColCache; iiReg==iReg ){ + p->tempReg = 1; + return; + } + } + pParse->aTempReg[pParse->nTempReg++] = iReg; + } +} + +/* +** Allocate or deallocate a block of nReg consecutive registers +*/ +int sqlite3GetTempRange(Parse *pParse, int nReg){ + int i, n; + i = pParse->iRangeReg; + n = pParse->nRangeReg; + if( nReg<=n ){ + assert( !usedAsColumnCache(pParse, i, i+n-1) ); + pParse->iRangeReg += nReg; + pParse->nRangeReg -= nReg; + }else{ + i = pParse->nMem+1; + pParse->nMem += nReg; + } + return i; +} +void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){ + sqlite3ExprCacheRemove(pParse, iReg, nReg); + if( nReg>pParse->nRangeReg ){ + pParse->nRangeReg = nReg; + pParse->iRangeReg = iReg; + } +} + +/* +** Mark all temporary registers as being unavailable for reuse. +*/ +void sqlite3ClearTempRegCache(Parse *pParse){ + pParse->nTempReg = 0; + pParse->nRangeReg = 0; +} diff --git a/scalos/libraries/sqlite/src/fault.c b/scalos/libraries/sqlite/src/fault.c new file mode 100644 index 000000000..c3028c4f9 --- /dev/null +++ b/scalos/libraries/sqlite/src/fault.c @@ -0,0 +1,87 @@ +/* +** 2008 Jan 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains code to support the concept of "benign" +** malloc failures (when the xMalloc() or xRealloc() method of the +** sqlite3_mem_methods structure fails to allocate a block of memory +** and returns 0). +** +** Most malloc failures are non-benign. After they occur, SQLite +** abandons the current operation and returns an error code (usually +** SQLITE_NOMEM) to the user. However, sometimes a fault is not necessarily +** fatal. For example, if a malloc fails while resizing a hash table, this +** is completely recoverable simply by not carrying out the resize. The +** hash table will continue to function normally. So a malloc failure +** during a hash table resize is a benign fault. +*/ + +#include "sqliteInt.h" + +#ifndef SQLITE_OMIT_BUILTIN_TEST + +/* +** Global variables. +*/ +typedef struct BenignMallocHooks BenignMallocHooks; +static SQLITE_WSD struct BenignMallocHooks { + void (*xBenignBegin)(void); + void (*xBenignEnd)(void); +} sqlite3Hooks = { 0, 0 }; + +/* The "wsdHooks" macro will resolve to the appropriate BenignMallocHooks +** structure. If writable static data is unsupported on the target, +** we have to locate the state vector at run-time. In the more common +** case where writable static data is supported, wsdHooks can refer directly +** to the "sqlite3Hooks" state vector declared above. +*/ +#ifdef SQLITE_OMIT_WSD +# define wsdHooksInit \ + BenignMallocHooks *x = &GLOBAL(BenignMallocHooks,sqlite3Hooks) +# define wsdHooks x[0] +#else +# define wsdHooksInit +# define wsdHooks sqlite3Hooks +#endif + + +/* +** Register hooks to call when sqlite3BeginBenignMalloc() and +** sqlite3EndBenignMalloc() are called, respectively. +*/ +void sqlite3BenignMallocHooks( + void (*xBenignBegin)(void), + void (*xBenignEnd)(void) +){ + wsdHooksInit; + wsdHooks.xBenignBegin = xBenignBegin; + wsdHooks.xBenignEnd = xBenignEnd; +} + +/* +** This (sqlite3EndBenignMalloc()) is called by SQLite code to indicate that +** subsequent malloc failures are benign. A call to sqlite3EndBenignMalloc() +** indicates that subsequent malloc failures are non-benign. +*/ +void sqlite3BeginBenignMalloc(void){ + wsdHooksInit; + if( wsdHooks.xBenignBegin ){ + wsdHooks.xBenignBegin(); + } +} +void sqlite3EndBenignMalloc(void){ + wsdHooksInit; + if( wsdHooks.xBenignEnd ){ + wsdHooks.xBenignEnd(); + } +} + +#endif /* #ifndef SQLITE_OMIT_BUILTIN_TEST */ diff --git a/scalos/libraries/sqlite/src/fkey.c b/scalos/libraries/sqlite/src/fkey.c new file mode 100644 index 000000000..82e4cdc47 --- /dev/null +++ b/scalos/libraries/sqlite/src/fkey.c @@ -0,0 +1,1219 @@ +/* +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code used by the compiler to add foreign key +** support to compiled SQL statements. +*/ +#include "sqliteInt.h" + +#ifndef SQLITE_OMIT_FOREIGN_KEY +#ifndef SQLITE_OMIT_TRIGGER + +/* +** Deferred and Immediate FKs +** -------------------------- +** +** Foreign keys in SQLite come in two flavours: deferred and immediate. +** If an immediate foreign key constraint is violated, SQLITE_CONSTRAINT +** is returned and the current statement transaction rolled back. If a +** deferred foreign key constraint is violated, no action is taken +** immediately. However if the application attempts to commit the +** transaction before fixing the constraint violation, the attempt fails. +** +** Deferred constraints are implemented using a simple counter associated +** with the database handle. The counter is set to zero each time a +** database transaction is opened. Each time a statement is executed +** that causes a foreign key violation, the counter is incremented. Each +** time a statement is executed that removes an existing violation from +** the database, the counter is decremented. When the transaction is +** committed, the commit fails if the current value of the counter is +** greater than zero. This scheme has two big drawbacks: +** +** * When a commit fails due to a deferred foreign key constraint, +** there is no way to tell which foreign constraint is not satisfied, +** or which row it is not satisfied for. +** +** * If the database contains foreign key violations when the +** transaction is opened, this may cause the mechanism to malfunction. +** +** Despite these problems, this approach is adopted as it seems simpler +** than the alternatives. +** +** INSERT operations: +** +** I.1) For each FK for which the table is the child table, search +** the parent table for a match. If none is found increment the +** constraint counter. +** +** I.2) For each FK for which the table is the parent table, +** search the child table for rows that correspond to the new +** row in the parent table. Decrement the counter for each row +** found (as the constraint is now satisfied). +** +** DELETE operations: +** +** D.1) For each FK for which the table is the child table, +** search the parent table for a row that corresponds to the +** deleted row in the child table. If such a row is not found, +** decrement the counter. +** +** D.2) For each FK for which the table is the parent table, search +** the child table for rows that correspond to the deleted row +** in the parent table. For each found increment the counter. +** +** UPDATE operations: +** +** An UPDATE command requires that all 4 steps above are taken, but only +** for FK constraints for which the affected columns are actually +** modified (values must be compared at runtime). +** +** Note that I.1 and D.1 are very similar operations, as are I.2 and D.2. +** This simplifies the implementation a bit. +** +** For the purposes of immediate FK constraints, the OR REPLACE conflict +** resolution is considered to delete rows before the new row is inserted. +** If a delete caused by OR REPLACE violates an FK constraint, an exception +** is thrown, even if the FK constraint would be satisfied after the new +** row is inserted. +** +** Immediate constraints are usually handled similarly. The only difference +** is that the counter used is stored as part of each individual statement +** object (struct Vdbe). If, after the statement has run, its immediate +** constraint counter is greater than zero, it returns SQLITE_CONSTRAINT +** and the statement transaction is rolled back. An exception is an INSERT +** statement that inserts a single row only (no triggers). In this case, +** instead of using a counter, an exception is thrown immediately if the +** INSERT violates a foreign key constraint. This is necessary as such +** an INSERT does not open a statement transaction. +** +** TODO: How should dropping a table be handled? How should renaming a +** table be handled? +** +** +** Query API Notes +** --------------- +** +** Before coding an UPDATE or DELETE row operation, the code-generator +** for those two operations needs to know whether or not the operation +** requires any FK processing and, if so, which columns of the original +** row are required by the FK processing VDBE code (i.e. if FKs were +** implemented using triggers, which of the old.* columns would be +** accessed). No information is required by the code-generator before +** coding an INSERT operation. The functions used by the UPDATE/DELETE +** generation code to query for this information are: +** +** sqlite3FkRequired() - Test to see if FK processing is required. +** sqlite3FkOldmask() - Query for the set of required old.* columns. +** +** +** Externally accessible module functions +** -------------------------------------- +** +** sqlite3FkCheck() - Check for foreign key violations. +** sqlite3FkActions() - Code triggers for ON UPDATE/ON DELETE actions. +** sqlite3FkDelete() - Delete an FKey structure. +*/ + +/* +** VDBE Calling Convention +** ----------------------- +** +** Example: +** +** For the following INSERT statement: +** +** CREATE TABLE t1(a, b INTEGER PRIMARY KEY, c); +** INSERT INTO t1 VALUES(1, 2, 3.1); +** +** Register (x): 2 (type integer) +** Register (x+1): 1 (type integer) +** Register (x+2): NULL (type NULL) +** Register (x+3): 3.1 (type real) +*/ + +/* +** A foreign key constraint requires that the key columns in the parent +** table are collectively subject to a UNIQUE or PRIMARY KEY constraint. +** Given that pParent is the parent table for foreign key constraint pFKey, +** search the schema a unique index on the parent key columns. +** +** If successful, zero is returned. If the parent key is an INTEGER PRIMARY +** KEY column, then output variable *ppIdx is set to NULL. Otherwise, *ppIdx +** is set to point to the unique index. +** +** If the parent key consists of a single column (the foreign key constraint +** is not a composite foreign key), output variable *paiCol is set to NULL. +** Otherwise, it is set to point to an allocated array of size N, where +** N is the number of columns in the parent key. The first element of the +** array is the index of the child table column that is mapped by the FK +** constraint to the parent table column stored in the left-most column +** of index *ppIdx. The second element of the array is the index of the +** child table column that corresponds to the second left-most column of +** *ppIdx, and so on. +** +** If the required index cannot be found, either because: +** +** 1) The named parent key columns do not exist, or +** +** 2) The named parent key columns do exist, but are not subject to a +** UNIQUE or PRIMARY KEY constraint, or +** +** 3) No parent key columns were provided explicitly as part of the +** foreign key definition, and the parent table does not have a +** PRIMARY KEY, or +** +** 4) No parent key columns were provided explicitly as part of the +** foreign key definition, and the PRIMARY KEY of the parent table +** consists of a a different number of columns to the child key in +** the child table. +** +** then non-zero is returned, and a "foreign key mismatch" error loaded +** into pParse. If an OOM error occurs, non-zero is returned and the +** pParse->db->mallocFailed flag is set. +*/ +static int locateFkeyIndex( + Parse *pParse, /* Parse context to store any error in */ + Table *pParent, /* Parent table of FK constraint pFKey */ + FKey *pFKey, /* Foreign key to find index for */ + Index **ppIdx, /* OUT: Unique index on parent table */ + int **paiCol /* OUT: Map of index columns in pFKey */ +){ + Index *pIdx = 0; /* Value to return via *ppIdx */ + int *aiCol = 0; /* Value to return via *paiCol */ + int nCol = pFKey->nCol; /* Number of columns in parent key */ + char *zKey = pFKey->aCol[0].zCol; /* Name of left-most parent key column */ + + /* The caller is responsible for zeroing output parameters. */ + assert( ppIdx && *ppIdx==0 ); + assert( !paiCol || *paiCol==0 ); + assert( pParse ); + + /* If this is a non-composite (single column) foreign key, check if it + ** maps to the INTEGER PRIMARY KEY of table pParent. If so, leave *ppIdx + ** and *paiCol set to zero and return early. + ** + ** Otherwise, for a composite foreign key (more than one column), allocate + ** space for the aiCol array (returned via output parameter *paiCol). + ** Non-composite foreign keys do not require the aiCol array. + */ + if( nCol==1 ){ + /* The FK maps to the IPK if any of the following are true: + ** + ** 1) There is an INTEGER PRIMARY KEY column and the FK is implicitly + ** mapped to the primary key of table pParent, or + ** 2) The FK is explicitly mapped to a column declared as INTEGER + ** PRIMARY KEY. + */ + if( pParent->iPKey>=0 ){ + if( !zKey ) return 0; + if( !sqlite3StrICmp(pParent->aCol[pParent->iPKey].zName, zKey) ) return 0; + } + }else if( paiCol ){ + assert( nCol>1 ); + aiCol = (int *)sqlite3DbMallocRaw(pParse->db, nCol*sizeof(int)); + if( !aiCol ) return 1; + *paiCol = aiCol; + } + + for(pIdx=pParent->pIndex; pIdx; pIdx=pIdx->pNext){ + if( pIdx->nColumn==nCol && pIdx->onError!=OE_None ){ + /* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number + ** of columns. If each indexed column corresponds to a foreign key + ** column of pFKey, then this index is a winner. */ + + if( zKey==0 ){ + /* If zKey is NULL, then this foreign key is implicitly mapped to + ** the PRIMARY KEY of table pParent. The PRIMARY KEY index may be + ** identified by the test (Index.autoIndex==2). */ + if( pIdx->autoIndex==2 ){ + if( aiCol ){ + int i; + for(i=0; iaCol[i].iFrom; + } + break; + } + }else{ + /* If zKey is non-NULL, then this foreign key was declared to + ** map to an explicit list of columns in table pParent. Check if this + ** index matches those columns. Also, check that the index uses + ** the default collation sequences for each column. */ + int i, j; + for(i=0; iaiColumn[i]; /* Index of column in parent tbl */ + char *zDfltColl; /* Def. collation for column */ + char *zIdxCol; /* Name of indexed column */ + + /* If the index uses a collation sequence that is different from + ** the default collation sequence for the column, this index is + ** unusable. Bail out early in this case. */ + zDfltColl = pParent->aCol[iCol].zColl; + if( !zDfltColl ){ + zDfltColl = "BINARY"; + } + if( sqlite3StrICmp(pIdx->azColl[i], zDfltColl) ) break; + + zIdxCol = pParent->aCol[iCol].zName; + for(j=0; jaCol[j].zCol, zIdxCol)==0 ){ + if( aiCol ) aiCol[i] = pFKey->aCol[j].iFrom; + break; + } + } + if( j==nCol ) break; + } + if( i==nCol ) break; /* pIdx is usable */ + } + } + } + + if( !pIdx ){ + if( !pParse->disableTriggers ){ + sqlite3ErrorMsg(pParse, "foreign key mismatch"); + } + sqlite3DbFree(pParse->db, aiCol); + return 1; + } + + *ppIdx = pIdx; + return 0; +} + +/* +** This function is called when a row is inserted into or deleted from the +** child table of foreign key constraint pFKey. If an SQL UPDATE is executed +** on the child table of pFKey, this function is invoked twice for each row +** affected - once to "delete" the old row, and then again to "insert" the +** new row. +** +** Each time it is called, this function generates VDBE code to locate the +** row in the parent table that corresponds to the row being inserted into +** or deleted from the child table. If the parent row can be found, no +** special action is taken. Otherwise, if the parent row can *not* be +** found in the parent table: +** +** Operation | FK type | Action taken +** -------------------------------------------------------------------------- +** INSERT immediate Increment the "immediate constraint counter". +** +** DELETE immediate Decrement the "immediate constraint counter". +** +** INSERT deferred Increment the "deferred constraint counter". +** +** DELETE deferred Decrement the "deferred constraint counter". +** +** These operations are identified in the comment at the top of this file +** (fkey.c) as "I.1" and "D.1". +*/ +static void fkLookupParent( + Parse *pParse, /* Parse context */ + int iDb, /* Index of database housing pTab */ + Table *pTab, /* Parent table of FK pFKey */ + Index *pIdx, /* Unique index on parent key columns in pTab */ + FKey *pFKey, /* Foreign key constraint */ + int *aiCol, /* Map from parent key columns to child table columns */ + int regData, /* Address of array containing child table row */ + int nIncr, /* Increment constraint counter by this */ + int isIgnore /* If true, pretend pTab contains all NULL values */ +){ + int i; /* Iterator variable */ + Vdbe *v = sqlite3GetVdbe(pParse); /* Vdbe to add code to */ + int iCur = pParse->nTab - 1; /* Cursor number to use */ + int iOk = sqlite3VdbeMakeLabel(v); /* jump here if parent key found */ + + /* If nIncr is less than zero, then check at runtime if there are any + ** outstanding constraints to resolve. If there are not, there is no need + ** to check if deleting this row resolves any outstanding violations. + ** + ** Check if any of the key columns in the child table row are NULL. If + ** any are, then the constraint is considered satisfied. No need to + ** search for a matching row in the parent table. */ + if( nIncr<0 ){ + sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, iOk); + } + for(i=0; inCol; i++){ + int iReg = aiCol[i] + regData + 1; + sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iOk); + } + + if( isIgnore==0 ){ + if( pIdx==0 ){ + /* If pIdx is NULL, then the parent key is the INTEGER PRIMARY KEY + ** column of the parent table (table pTab). */ + int iMustBeInt; /* Address of MustBeInt instruction */ + int regTemp = sqlite3GetTempReg(pParse); + + /* Invoke MustBeInt to coerce the child key value to an integer (i.e. + ** apply the affinity of the parent key). If this fails, then there + ** is no matching parent key. Before using MustBeInt, make a copy of + ** the value. Otherwise, the value inserted into the child key column + ** will have INTEGER affinity applied to it, which may not be correct. */ + sqlite3VdbeAddOp2(v, OP_SCopy, aiCol[0]+1+regData, regTemp); + iMustBeInt = sqlite3VdbeAddOp2(v, OP_MustBeInt, regTemp, 0); + + /* If the parent table is the same as the child table, and we are about + ** to increment the constraint-counter (i.e. this is an INSERT operation), + ** then check if the row being inserted matches itself. If so, do not + ** increment the constraint-counter. */ + if( pTab==pFKey->pFrom && nIncr==1 ){ + sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp); + } + + sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead); + sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp); + sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk); + sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2); + sqlite3VdbeJumpHere(v, iMustBeInt); + sqlite3ReleaseTempReg(pParse, regTemp); + }else{ + int nCol = pFKey->nCol; + int regTemp = sqlite3GetTempRange(pParse, nCol); + int regRec = sqlite3GetTempReg(pParse); + KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx); + + sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb); + sqlite3VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF); + for(i=0; ipFrom && nIncr==1 ){ + int iJump = sqlite3VdbeCurrentAddr(v) + nCol + 1; + for(i=0; iaiColumn[i]+1+regData; + assert( aiCol[i]!=pTab->iPKey ); + if( pIdx->aiColumn[i]==pTab->iPKey ){ + /* The parent key is a composite key that includes the IPK column */ + iParent = regData; + } + sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent); + sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL); + } + sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk); + } + + sqlite3VdbeAddOp3(v, OP_MakeRecord, regTemp, nCol, regRec); + sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v,pIdx), P4_TRANSIENT); + sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0); + + sqlite3ReleaseTempReg(pParse, regRec); + sqlite3ReleaseTempRange(pParse, regTemp, nCol); + } + } + + if( !pFKey->isDeferred && !pParse->pToplevel && !pParse->isMultiWrite ){ + /* Special case: If this is an INSERT statement that will insert exactly + ** one row into the table, raise a constraint immediately instead of + ** incrementing a counter. This is necessary as the VM code is being + ** generated for will not open a statement transaction. */ + assert( nIncr==1 ); + sqlite3HaltConstraint( + pParse, OE_Abort, "foreign key constraint failed", P4_STATIC + ); + }else{ + if( nIncr>0 && pFKey->isDeferred==0 ){ + sqlite3ParseToplevel(pParse)->mayAbort = 1; + } + sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr); + } + + sqlite3VdbeResolveLabel(v, iOk); + sqlite3VdbeAddOp1(v, OP_Close, iCur); +} + +/* +** This function is called to generate code executed when a row is deleted +** from the parent table of foreign key constraint pFKey and, if pFKey is +** deferred, when a row is inserted into the same table. When generating +** code for an SQL UPDATE operation, this function may be called twice - +** once to "delete" the old row and once to "insert" the new row. +** +** The code generated by this function scans through the rows in the child +** table that correspond to the parent table row being deleted or inserted. +** For each child row found, one of the following actions is taken: +** +** Operation | FK type | Action taken +** -------------------------------------------------------------------------- +** DELETE immediate Increment the "immediate constraint counter". +** Or, if the ON (UPDATE|DELETE) action is RESTRICT, +** throw a "foreign key constraint failed" exception. +** +** INSERT immediate Decrement the "immediate constraint counter". +** +** DELETE deferred Increment the "deferred constraint counter". +** Or, if the ON (UPDATE|DELETE) action is RESTRICT, +** throw a "foreign key constraint failed" exception. +** +** INSERT deferred Decrement the "deferred constraint counter". +** +** These operations are identified in the comment at the top of this file +** (fkey.c) as "I.2" and "D.2". +*/ +static void fkScanChildren( + Parse *pParse, /* Parse context */ + SrcList *pSrc, /* SrcList containing the table to scan */ + Table *pTab, + Index *pIdx, /* Foreign key index */ + FKey *pFKey, /* Foreign key relationship */ + int *aiCol, /* Map from pIdx cols to child table cols */ + int regData, /* Referenced table data starts here */ + int nIncr /* Amount to increment deferred counter by */ +){ + sqlite3 *db = pParse->db; /* Database handle */ + int i; /* Iterator variable */ + Expr *pWhere = 0; /* WHERE clause to scan with */ + NameContext sNameContext; /* Context used to resolve WHERE clause */ + WhereInfo *pWInfo; /* Context used by sqlite3WhereXXX() */ + int iFkIfZero = 0; /* Address of OP_FkIfZero */ + Vdbe *v = sqlite3GetVdbe(pParse); + + assert( !pIdx || pIdx->pTable==pTab ); + + if( nIncr<0 ){ + iFkIfZero = sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, 0); + } + + /* Create an Expr object representing an SQL expression like: + ** + ** = AND = ... + ** + ** The collation sequence used for the comparison should be that of + ** the parent key columns. The affinity of the parent key column should + ** be applied to each child key value before the comparison takes place. + */ + for(i=0; inCol; i++){ + Expr *pLeft; /* Value from parent table row */ + Expr *pRight; /* Column ref to child table */ + Expr *pEq; /* Expression (pLeft = pRight) */ + int iCol; /* Index of column in child table */ + const char *zCol; /* Name of column in child table */ + + pLeft = sqlite3Expr(db, TK_REGISTER, 0); + if( pLeft ){ + /* Set the collation sequence and affinity of the LHS of each TK_EQ + ** expression to the parent key column defaults. */ + if( pIdx ){ + Column *pCol; + iCol = pIdx->aiColumn[i]; + pCol = &pTab->aCol[iCol]; + if( pTab->iPKey==iCol ) iCol = -1; + pLeft->iTable = regData+iCol+1; + pLeft->affinity = pCol->affinity; + pLeft->pColl = sqlite3LocateCollSeq(pParse, pCol->zColl); + }else{ + pLeft->iTable = regData; + pLeft->affinity = SQLITE_AFF_INTEGER; + } + } + iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom; + assert( iCol>=0 ); + zCol = pFKey->pFrom->aCol[iCol].zName; + pRight = sqlite3Expr(db, TK_ID, zCol); + pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight, 0); + pWhere = sqlite3ExprAnd(db, pWhere, pEq); + } + + /* If the child table is the same as the parent table, and this scan + ** is taking place as part of a DELETE operation (operation D.2), omit the + ** row being deleted from the scan by adding ($rowid != rowid) to the WHERE + ** clause, where $rowid is the rowid of the row being deleted. */ + if( pTab==pFKey->pFrom && nIncr>0 ){ + Expr *pEq; /* Expression (pLeft = pRight) */ + Expr *pLeft; /* Value from parent table row */ + Expr *pRight; /* Column ref to child table */ + pLeft = sqlite3Expr(db, TK_REGISTER, 0); + pRight = sqlite3Expr(db, TK_COLUMN, 0); + if( pLeft && pRight ){ + pLeft->iTable = regData; + pLeft->affinity = SQLITE_AFF_INTEGER; + pRight->iTable = pSrc->a[0].iCursor; + pRight->iColumn = -1; + } + pEq = sqlite3PExpr(pParse, TK_NE, pLeft, pRight, 0); + pWhere = sqlite3ExprAnd(db, pWhere, pEq); + } + + /* Resolve the references in the WHERE clause. */ + memset(&sNameContext, 0, sizeof(NameContext)); + sNameContext.pSrcList = pSrc; + sNameContext.pParse = pParse; + sqlite3ResolveExprNames(&sNameContext, pWhere); + + /* Create VDBE to loop through the entries in pSrc that match the WHERE + ** clause. If the constraint is not deferred, throw an exception for + ** each row found. Otherwise, for deferred constraints, increment the + ** deferred constraint counter by nIncr for each row selected. */ + pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0); + if( nIncr>0 && pFKey->isDeferred==0 ){ + sqlite3ParseToplevel(pParse)->mayAbort = 1; + } + sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr); + if( pWInfo ){ + sqlite3WhereEnd(pWInfo); + } + + /* Clean up the WHERE clause constructed above. */ + sqlite3ExprDelete(db, pWhere); + if( iFkIfZero ){ + sqlite3VdbeJumpHere(v, iFkIfZero); + } +} + +/* +** This function returns a pointer to the head of a linked list of FK +** constraints for which table pTab is the parent table. For example, +** given the following schema: +** +** CREATE TABLE t1(a PRIMARY KEY); +** CREATE TABLE t2(b REFERENCES t1(a); +** +** Calling this function with table "t1" as an argument returns a pointer +** to the FKey structure representing the foreign key constraint on table +** "t2". Calling this function with "t2" as the argument would return a +** NULL pointer (as there are no FK constraints for which t2 is the parent +** table). +*/ +FKey *sqlite3FkReferences(Table *pTab){ + int nName = sqlite3Strlen30(pTab->zName); + return (FKey *)sqlite3HashFind(&pTab->pSchema->fkeyHash, pTab->zName, nName); +} + +/* +** The second argument is a Trigger structure allocated by the +** fkActionTrigger() routine. This function deletes the Trigger structure +** and all of its sub-components. +** +** The Trigger structure or any of its sub-components may be allocated from +** the lookaside buffer belonging to database handle dbMem. +*/ +static void fkTriggerDelete(sqlite3 *dbMem, Trigger *p){ + if( p ){ + TriggerStep *pStep = p->step_list; + sqlite3ExprDelete(dbMem, pStep->pWhere); + sqlite3ExprListDelete(dbMem, pStep->pExprList); + sqlite3SelectDelete(dbMem, pStep->pSelect); + sqlite3ExprDelete(dbMem, p->pWhen); + sqlite3DbFree(dbMem, p); + } +} + +/* +** This function is called to generate code that runs when table pTab is +** being dropped from the database. The SrcList passed as the second argument +** to this function contains a single entry guaranteed to resolve to +** table pTab. +** +** Normally, no code is required. However, if either +** +** (a) The table is the parent table of a FK constraint, or +** (b) The table is the child table of a deferred FK constraint and it is +** determined at runtime that there are outstanding deferred FK +** constraint violations in the database, +** +** then the equivalent of "DELETE FROM " is executed before dropping +** the table from the database. Triggers are disabled while running this +** DELETE, but foreign key actions are not. +*/ +void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){ + sqlite3 *db = pParse->db; + if( (db->flags&SQLITE_ForeignKeys) && !IsVirtual(pTab) && !pTab->pSelect ){ + int iSkip = 0; + Vdbe *v = sqlite3GetVdbe(pParse); + + assert( v ); /* VDBE has already been allocated */ + if( sqlite3FkReferences(pTab)==0 ){ + /* Search for a deferred foreign key constraint for which this table + ** is the child table. If one cannot be found, return without + ** generating any VDBE code. If one can be found, then jump over + ** the entire DELETE if there are no outstanding deferred constraints + ** when this statement is run. */ + FKey *p; + for(p=pTab->pFKey; p; p=p->pNextFrom){ + if( p->isDeferred ) break; + } + if( !p ) return; + iSkip = sqlite3VdbeMakeLabel(v); + sqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip); + } + + pParse->disableTriggers = 1; + sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0); + pParse->disableTriggers = 0; + + /* If the DELETE has generated immediate foreign key constraint + ** violations, halt the VDBE and return an error at this point, before + ** any modifications to the schema are made. This is because statement + ** transactions are not able to rollback schema changes. */ + sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2); + sqlite3HaltConstraint( + pParse, OE_Abort, "foreign key constraint failed", P4_STATIC + ); + + if( iSkip ){ + sqlite3VdbeResolveLabel(v, iSkip); + } + } +} + +/* +** This function is called when inserting, deleting or updating a row of +** table pTab to generate VDBE code to perform foreign key constraint +** processing for the operation. +** +** For a DELETE operation, parameter regOld is passed the index of the +** first register in an array of (pTab->nCol+1) registers containing the +** rowid of the row being deleted, followed by each of the column values +** of the row being deleted, from left to right. Parameter regNew is passed +** zero in this case. +** +** For an INSERT operation, regOld is passed zero and regNew is passed the +** first register of an array of (pTab->nCol+1) registers containing the new +** row data. +** +** For an UPDATE operation, this function is called twice. Once before +** the original record is deleted from the table using the calling convention +** described for DELETE. Then again after the original record is deleted +** but before the new record is inserted using the INSERT convention. +*/ +void sqlite3FkCheck( + Parse *pParse, /* Parse context */ + Table *pTab, /* Row is being deleted from this table */ + int regOld, /* Previous row data is stored here */ + int regNew /* New row data is stored here */ +){ + sqlite3 *db = pParse->db; /* Database handle */ + FKey *pFKey; /* Used to iterate through FKs */ + int iDb; /* Index of database containing pTab */ + const char *zDb; /* Name of database containing pTab */ + int isIgnoreErrors = pParse->disableTriggers; + + /* Exactly one of regOld and regNew should be non-zero. */ + assert( (regOld==0)!=(regNew==0) ); + + /* If foreign-keys are disabled, this function is a no-op. */ + if( (db->flags&SQLITE_ForeignKeys)==0 ) return; + + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + zDb = db->aDb[iDb].zName; + + /* Loop through all the foreign key constraints for which pTab is the + ** child table (the table that the foreign key definition is part of). */ + for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){ + Table *pTo; /* Parent table of foreign key pFKey */ + Index *pIdx = 0; /* Index on key columns in pTo */ + int *aiFree = 0; + int *aiCol; + int iCol; + int i; + int isIgnore = 0; + + /* Find the parent table of this foreign key. Also find a unique index + ** on the parent key columns in the parent table. If either of these + ** schema items cannot be located, set an error in pParse and return + ** early. */ + if( pParse->disableTriggers ){ + pTo = sqlite3FindTable(db, pFKey->zTo, zDb); + }else{ + pTo = sqlite3LocateTable(pParse, 0, pFKey->zTo, zDb); + } + if( !pTo || locateFkeyIndex(pParse, pTo, pFKey, &pIdx, &aiFree) ){ + assert( isIgnoreErrors==0 || (regOld!=0 && regNew==0) ); + if( !isIgnoreErrors || db->mallocFailed ) return; + if( pTo==0 ){ + /* If isIgnoreErrors is true, then a table is being dropped. In this + ** case SQLite runs a "DELETE FROM xxx" on the table being dropped + ** before actually dropping it in order to check FK constraints. + ** If the parent table of an FK constraint on the current table is + ** missing, behave as if it is empty. i.e. decrement the relevant + ** FK counter for each row of the current table with non-NULL keys. + */ + Vdbe *v = sqlite3GetVdbe(pParse); + int iJump = sqlite3VdbeCurrentAddr(v) + pFKey->nCol + 1; + for(i=0; inCol; i++){ + int iReg = pFKey->aCol[i].iFrom + regOld + 1; + sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iJump); + } + sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, -1); + } + continue; + } + assert( pFKey->nCol==1 || (aiFree && pIdx) ); + + if( aiFree ){ + aiCol = aiFree; + }else{ + iCol = pFKey->aCol[0].iFrom; + aiCol = &iCol; + } + for(i=0; inCol; i++){ + if( aiCol[i]==pTab->iPKey ){ + aiCol[i] = -1; + } +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Request permission to read the parent key columns. If the + ** authorization callback returns SQLITE_IGNORE, behave as if any + ** values read from the parent table are NULL. */ + if( db->xAuth ){ + int rcauth; + char *zCol = pTo->aCol[pIdx ? pIdx->aiColumn[i] : pTo->iPKey].zName; + rcauth = sqlite3AuthReadCol(pParse, pTo->zName, zCol, iDb); + isIgnore = (rcauth==SQLITE_IGNORE); + } +#endif + } + + /* Take a shared-cache advisory read-lock on the parent table. Allocate + ** a cursor to use to search the unique index on the parent key columns + ** in the parent table. */ + sqlite3TableLock(pParse, iDb, pTo->tnum, 0, pTo->zName); + pParse->nTab++; + + if( regOld!=0 ){ + /* A row is being removed from the child table. Search for the parent. + ** If the parent does not exist, removing the child row resolves an + ** outstanding foreign key constraint violation. */ + fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regOld, -1,isIgnore); + } + if( regNew!=0 ){ + /* A row is being added to the child table. If a parent row cannot + ** be found, adding the child row has violated the FK constraint. */ + fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regNew, +1,isIgnore); + } + + sqlite3DbFree(db, aiFree); + } + + /* Loop through all the foreign key constraints that refer to this table */ + for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){ + Index *pIdx = 0; /* Foreign key index for pFKey */ + SrcList *pSrc; + int *aiCol = 0; + + if( !pFKey->isDeferred && !pParse->pToplevel && !pParse->isMultiWrite ){ + assert( regOld==0 && regNew!=0 ); + /* Inserting a single row into a parent table cannot cause an immediate + ** foreign key violation. So do nothing in this case. */ + continue; + } + + if( locateFkeyIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ){ + if( !isIgnoreErrors || db->mallocFailed ) return; + continue; + } + assert( aiCol || pFKey->nCol==1 ); + + /* Create a SrcList structure containing a single table (the table + ** the foreign key that refers to this table is attached to). This + ** is required for the sqlite3WhereXXX() interface. */ + pSrc = sqlite3SrcListAppend(db, 0, 0, 0); + if( pSrc ){ + struct SrcList_item *pItem = pSrc->a; + pItem->pTab = pFKey->pFrom; + pItem->zName = pFKey->pFrom->zName; + pItem->pTab->nRef++; + pItem->iCursor = pParse->nTab++; + + if( regNew!=0 ){ + fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regNew, -1); + } + if( regOld!=0 ){ + /* If there is a RESTRICT action configured for the current operation + ** on the parent table of this FK, then throw an exception + ** immediately if the FK constraint is violated, even if this is a + ** deferred trigger. That's what RESTRICT means. To defer checking + ** the constraint, the FK should specify NO ACTION (represented + ** using OE_None). NO ACTION is the default. */ + fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regOld, 1); + } + pItem->zName = 0; + sqlite3SrcListDelete(db, pSrc); + } + sqlite3DbFree(db, aiCol); + } +} + +#define COLUMN_MASK(x) (((x)>31) ? 0xffffffff : ((u32)1<<(x))) + +/* +** This function is called before generating code to update or delete a +** row contained in table pTab. +*/ +u32 sqlite3FkOldmask( + Parse *pParse, /* Parse context */ + Table *pTab /* Table being modified */ +){ + u32 mask = 0; + if( pParse->db->flags&SQLITE_ForeignKeys ){ + FKey *p; + int i; + for(p=pTab->pFKey; p; p=p->pNextFrom){ + for(i=0; inCol; i++) mask |= COLUMN_MASK(p->aCol[i].iFrom); + } + for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ + Index *pIdx = 0; + locateFkeyIndex(pParse, pTab, p, &pIdx, 0); + if( pIdx ){ + for(i=0; inColumn; i++) mask |= COLUMN_MASK(pIdx->aiColumn[i]); + } + } + } + return mask; +} + +/* +** This function is called before generating code to update or delete a +** row contained in table pTab. If the operation is a DELETE, then +** parameter aChange is passed a NULL value. For an UPDATE, aChange points +** to an array of size N, where N is the number of columns in table pTab. +** If the i'th column is not modified by the UPDATE, then the corresponding +** entry in the aChange[] array is set to -1. If the column is modified, +** the value is 0 or greater. Parameter chngRowid is set to true if the +** UPDATE statement modifies the rowid fields of the table. +** +** If any foreign key processing will be required, this function returns +** true. If there is no foreign key related processing, this function +** returns false. +*/ +int sqlite3FkRequired( + Parse *pParse, /* Parse context */ + Table *pTab, /* Table being modified */ + int *aChange, /* Non-NULL for UPDATE operations */ + int chngRowid /* True for UPDATE that affects rowid */ +){ + if( pParse->db->flags&SQLITE_ForeignKeys ){ + if( !aChange ){ + /* A DELETE operation. Foreign key processing is required if the + ** table in question is either the child or parent table for any + ** foreign key constraint. */ + return (sqlite3FkReferences(pTab) || pTab->pFKey); + }else{ + /* This is an UPDATE. Foreign key processing is only required if the + ** operation modifies one or more child or parent key columns. */ + int i; + FKey *p; + + /* Check if any child key columns are being modified. */ + for(p=pTab->pFKey; p; p=p->pNextFrom){ + for(i=0; inCol; i++){ + int iChildKey = p->aCol[i].iFrom; + if( aChange[iChildKey]>=0 ) return 1; + if( iChildKey==pTab->iPKey && chngRowid ) return 1; + } + } + + /* Check if any parent key columns are being modified. */ + for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ + for(i=0; inCol; i++){ + char *zKey = p->aCol[i].zCol; + int iKey; + for(iKey=0; iKeynCol; iKey++){ + Column *pCol = &pTab->aCol[iKey]; + if( (zKey ? !sqlite3StrICmp(pCol->zName, zKey) : pCol->isPrimKey) ){ + if( aChange[iKey]>=0 ) return 1; + if( iKey==pTab->iPKey && chngRowid ) return 1; + } + } + } + } + } + } + return 0; +} + +/* +** This function is called when an UPDATE or DELETE operation is being +** compiled on table pTab, which is the parent table of foreign-key pFKey. +** If the current operation is an UPDATE, then the pChanges parameter is +** passed a pointer to the list of columns being modified. If it is a +** DELETE, pChanges is passed a NULL pointer. +** +** It returns a pointer to a Trigger structure containing a trigger +** equivalent to the ON UPDATE or ON DELETE action specified by pFKey. +** If the action is "NO ACTION" or "RESTRICT", then a NULL pointer is +** returned (these actions require no special handling by the triggers +** sub-system, code for them is created by fkScanChildren()). +** +** For example, if pFKey is the foreign key and pTab is table "p" in +** the following schema: +** +** CREATE TABLE p(pk PRIMARY KEY); +** CREATE TABLE c(ck REFERENCES p ON DELETE CASCADE); +** +** then the returned trigger structure is equivalent to: +** +** CREATE TRIGGER ... DELETE ON p BEGIN +** DELETE FROM c WHERE ck = old.pk; +** END; +** +** The returned pointer is cached as part of the foreign key object. It +** is eventually freed along with the rest of the foreign key object by +** sqlite3FkDelete(). +*/ +static Trigger *fkActionTrigger( + Parse *pParse, /* Parse context */ + Table *pTab, /* Table being updated or deleted from */ + FKey *pFKey, /* Foreign key to get action for */ + ExprList *pChanges /* Change-list for UPDATE, NULL for DELETE */ +){ + sqlite3 *db = pParse->db; /* Database handle */ + int action; /* One of OE_None, OE_Cascade etc. */ + Trigger *pTrigger; /* Trigger definition to return */ + int iAction = (pChanges!=0); /* 1 for UPDATE, 0 for DELETE */ + + action = pFKey->aAction[iAction]; + pTrigger = pFKey->apTrigger[iAction]; + + if( action!=OE_None && !pTrigger ){ + u8 enableLookaside; /* Copy of db->lookaside.bEnabled */ + char const *zFrom; /* Name of child table */ + int nFrom; /* Length in bytes of zFrom */ + Index *pIdx = 0; /* Parent key index for this FK */ + int *aiCol = 0; /* child table cols -> parent key cols */ + TriggerStep *pStep = 0; /* First (only) step of trigger program */ + Expr *pWhere = 0; /* WHERE clause of trigger step */ + ExprList *pList = 0; /* Changes list if ON UPDATE CASCADE */ + Select *pSelect = 0; /* If RESTRICT, "SELECT RAISE(...)" */ + int i; /* Iterator variable */ + Expr *pWhen = 0; /* WHEN clause for the trigger */ + + if( locateFkeyIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ) return 0; + assert( aiCol || pFKey->nCol==1 ); + + for(i=0; inCol; i++){ + Token tOld = { "old", 3 }; /* Literal "old" token */ + Token tNew = { "new", 3 }; /* Literal "new" token */ + Token tFromCol; /* Name of column in child table */ + Token tToCol; /* Name of column in parent table */ + int iFromCol; /* Idx of column in child table */ + Expr *pEq; /* tFromCol = OLD.tToCol */ + + iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom; + assert( iFromCol>=0 ); + tToCol.z = pIdx ? pTab->aCol[pIdx->aiColumn[i]].zName : "oid"; + tFromCol.z = pFKey->pFrom->aCol[iFromCol].zName; + + tToCol.n = sqlite3Strlen30(tToCol.z); + tFromCol.n = sqlite3Strlen30(tFromCol.z); + + /* Create the expression "OLD.zToCol = zFromCol". It is important + ** that the "OLD.zToCol" term is on the LHS of the = operator, so + ** that the affinity and collation sequence associated with the + ** parent table are used for the comparison. */ + pEq = sqlite3PExpr(pParse, TK_EQ, + sqlite3PExpr(pParse, TK_DOT, + sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld), + sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol) + , 0), + sqlite3PExpr(pParse, TK_ID, 0, 0, &tFromCol) + , 0); + pWhere = sqlite3ExprAnd(db, pWhere, pEq); + + /* For ON UPDATE, construct the next term of the WHEN clause. + ** The final WHEN clause will be like this: + ** + ** WHEN NOT(old.col1 IS new.col1 AND ... AND old.colN IS new.colN) + */ + if( pChanges ){ + pEq = sqlite3PExpr(pParse, TK_IS, + sqlite3PExpr(pParse, TK_DOT, + sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld), + sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol), + 0), + sqlite3PExpr(pParse, TK_DOT, + sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew), + sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol), + 0), + 0); + pWhen = sqlite3ExprAnd(db, pWhen, pEq); + } + + if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){ + Expr *pNew; + if( action==OE_Cascade ){ + pNew = sqlite3PExpr(pParse, TK_DOT, + sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew), + sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol) + , 0); + }else if( action==OE_SetDflt ){ + Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt; + if( pDflt ){ + pNew = sqlite3ExprDup(db, pDflt, 0); + }else{ + pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0); + } + }else{ + pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0); + } + pList = sqlite3ExprListAppend(pParse, pList, pNew); + sqlite3ExprListSetName(pParse, pList, &tFromCol, 0); + } + } + sqlite3DbFree(db, aiCol); + + zFrom = pFKey->pFrom->zName; + nFrom = sqlite3Strlen30(zFrom); + + if( action==OE_Restrict ){ + Token tFrom; + Expr *pRaise; + + tFrom.z = zFrom; + tFrom.n = nFrom; + pRaise = sqlite3Expr(db, TK_RAISE, "foreign key constraint failed"); + if( pRaise ){ + pRaise->affinity = OE_Abort; + } + pSelect = sqlite3SelectNew(pParse, + sqlite3ExprListAppend(pParse, 0, pRaise), + sqlite3SrcListAppend(db, 0, &tFrom, 0), + pWhere, + 0, 0, 0, 0, 0, 0 + ); + pWhere = 0; + } + + /* Disable lookaside memory allocation */ + enableLookaside = db->lookaside.bEnabled; + db->lookaside.bEnabled = 0; + + pTrigger = (Trigger *)sqlite3DbMallocZero(db, + sizeof(Trigger) + /* struct Trigger */ + sizeof(TriggerStep) + /* Single step in trigger program */ + nFrom + 1 /* Space for pStep->target.z */ + ); + if( pTrigger ){ + pStep = pTrigger->step_list = (TriggerStep *)&pTrigger[1]; + pStep->target.z = (char *)&pStep[1]; + pStep->target.n = nFrom; + memcpy((char *)pStep->target.z, zFrom, nFrom); + + pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); + pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE); + pStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); + if( pWhen ){ + pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0, 0); + pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); + } + } + + /* Re-enable the lookaside buffer, if it was disabled earlier. */ + db->lookaside.bEnabled = enableLookaside; + + sqlite3ExprDelete(db, pWhere); + sqlite3ExprDelete(db, pWhen); + sqlite3ExprListDelete(db, pList); + sqlite3SelectDelete(db, pSelect); + if( db->mallocFailed==1 ){ + fkTriggerDelete(db, pTrigger); + return 0; + } + assert( pStep!=0 ); + + switch( action ){ + case OE_Restrict: + pStep->op = TK_SELECT; + break; + case OE_Cascade: + if( !pChanges ){ + pStep->op = TK_DELETE; + break; + } + default: + pStep->op = TK_UPDATE; + } + pStep->pTrig = pTrigger; + pTrigger->pSchema = pTab->pSchema; + pTrigger->pTabSchema = pTab->pSchema; + pFKey->apTrigger[iAction] = pTrigger; + pTrigger->op = (pChanges ? TK_UPDATE : TK_DELETE); + } + + return pTrigger; +} + +/* +** This function is called when deleting or updating a row to implement +** any required CASCADE, SET NULL or SET DEFAULT actions. +*/ +void sqlite3FkActions( + Parse *pParse, /* Parse context */ + Table *pTab, /* Table being updated or deleted from */ + ExprList *pChanges, /* Change-list for UPDATE, NULL for DELETE */ + int regOld /* Address of array containing old row */ +){ + /* If foreign-key support is enabled, iterate through all FKs that + ** refer to table pTab. If there is an action associated with the FK + ** for this operation (either update or delete), invoke the associated + ** trigger sub-program. */ + if( pParse->db->flags&SQLITE_ForeignKeys ){ + FKey *pFKey; /* Iterator variable */ + for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){ + Trigger *pAction = fkActionTrigger(pParse, pTab, pFKey, pChanges); + if( pAction ){ + sqlite3CodeRowTriggerDirect(pParse, pAction, pTab, regOld, OE_Abort, 0); + } + } + } +} + +#endif /* ifndef SQLITE_OMIT_TRIGGER */ + +/* +** Free all memory associated with foreign key definitions attached to +** table pTab. Remove the deleted foreign keys from the Schema.fkeyHash +** hash table. +*/ +void sqlite3FkDelete(sqlite3 *db, Table *pTab){ + FKey *pFKey; /* Iterator variable */ + FKey *pNext; /* Copy of pFKey->pNextFrom */ + + assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) ); + for(pFKey=pTab->pFKey; pFKey; pFKey=pNext){ + + /* Remove the FK from the fkeyHash hash table. */ + if( !db || db->pnBytesFreed==0 ){ + if( pFKey->pPrevTo ){ + pFKey->pPrevTo->pNextTo = pFKey->pNextTo; + }else{ + void *p = (void *)pFKey->pNextTo; + const char *z = (p ? pFKey->pNextTo->zTo : pFKey->zTo); + sqlite3HashInsert(&pTab->pSchema->fkeyHash, z, sqlite3Strlen30(z), p); + } + if( pFKey->pNextTo ){ + pFKey->pNextTo->pPrevTo = pFKey->pPrevTo; + } + } + + /* EV: R-30323-21917 Each foreign key constraint in SQLite is + ** classified as either immediate or deferred. + */ + assert( pFKey->isDeferred==0 || pFKey->isDeferred==1 ); + + /* Delete any triggers created to implement actions for this FK. */ +#ifndef SQLITE_OMIT_TRIGGER + fkTriggerDelete(db, pFKey->apTrigger[0]); + fkTriggerDelete(db, pFKey->apTrigger[1]); +#endif + + pNext = pFKey->pNextFrom; + sqlite3DbFree(db, pFKey); + } +} +#endif /* ifndef SQLITE_OMIT_FOREIGN_KEY */ diff --git a/scalos/libraries/sqlite/src/func.c b/scalos/libraries/sqlite/src/func.c new file mode 100644 index 000000000..3a1879ca6 --- /dev/null +++ b/scalos/libraries/sqlite/src/func.c @@ -0,0 +1,1605 @@ +/* +** 2002 February 23 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains the C functions that implement various SQL +** functions of SQLite. +** +** There is only one exported symbol in this file - the function +** sqliteRegisterBuildinFunctions() found at the bottom of the file. +** All other code has file scope. +*/ +#include "sqliteInt.h" +#include +#include +#include "vdbeInt.h" + +/* +** Return the collating function associated with a function. +*/ +static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){ + return context->pColl; +} + +/* +** Implementation of the non-aggregate min() and max() functions +*/ +static void minmaxFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int i; + int mask; /* 0 for min() or 0xffffffff for max() */ + int iBest; + CollSeq *pColl; + + assert( argc>1 ); + mask = sqlite3_user_data(context)==0 ? 0 : -1; + pColl = sqlite3GetFuncCollSeq(context); + assert( pColl ); + assert( mask==-1 || mask==0 ); + iBest = 0; + if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; + for(i=1; i=0 ){ + testcase( mask==0 ); + iBest = i; + } + } + sqlite3_result_value(context, argv[iBest]); +} + +/* +** Return the type of the argument. +*/ +static void typeofFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + const char *z = 0; + UNUSED_PARAMETER(NotUsed); + switch( sqlite3_value_type(argv[0]) ){ + case SQLITE_INTEGER: z = "integer"; break; + case SQLITE_TEXT: z = "text"; break; + case SQLITE_FLOAT: z = "real"; break; + case SQLITE_BLOB: z = "blob"; break; + default: z = "null"; break; + } + sqlite3_result_text(context, z, -1, SQLITE_STATIC); +} + + +/* +** Implementation of the length() function +*/ +static void lengthFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int len; + + assert( argc==1 ); + UNUSED_PARAMETER(argc); + switch( sqlite3_value_type(argv[0]) ){ + case SQLITE_BLOB: + case SQLITE_INTEGER: + case SQLITE_FLOAT: { + sqlite3_result_int(context, sqlite3_value_bytes(argv[0])); + break; + } + case SQLITE_TEXT: { + const unsigned char *z = sqlite3_value_text(argv[0]); + if( z==0 ) return; + len = 0; + while( *z ){ + len++; + SQLITE_SKIP_UTF8(z); + } + sqlite3_result_int(context, len); + break; + } + default: { + sqlite3_result_null(context); + break; + } + } +} + +/* +** Implementation of the abs() function. +** +** IMP: R-23979-26855 The abs(X) function returns the absolute value of +** the numeric argument X. +*/ +static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ + assert( argc==1 ); + UNUSED_PARAMETER(argc); + switch( sqlite3_value_type(argv[0]) ){ + case SQLITE_INTEGER: { + i64 iVal = sqlite3_value_int64(argv[0]); + if( iVal<0 ){ + if( (iVal<<1)==0 ){ + /* IMP: R-35460-15084 If X is the integer -9223372036854775807 then + ** abs(X) throws an integer overflow error since there is no + ** equivalent positive 64-bit two complement value. */ + sqlite3_result_error(context, "integer overflow", -1); + return; + } + iVal = -iVal; + } + sqlite3_result_int64(context, iVal); + break; + } + case SQLITE_NULL: { + /* IMP: R-37434-19929 Abs(X) returns NULL if X is NULL. */ + sqlite3_result_null(context); + break; + } + default: { + /* Because sqlite3_value_double() returns 0.0 if the argument is not + ** something that can be converted into a number, we have: + ** IMP: R-57326-31541 Abs(X) return 0.0 if X is a string or blob that + ** cannot be converted to a numeric value. + */ + double rVal = sqlite3_value_double(argv[0]); + if( rVal<0 ) rVal = -rVal; + sqlite3_result_double(context, rVal); + break; + } + } +} + +/* +** Implementation of the substr() function. +** +** substr(x,p1,p2) returns p2 characters of x[] beginning with p1. +** p1 is 1-indexed. So substr(x,1,1) returns the first character +** of x. If x is text, then we actually count UTF-8 characters. +** If x is a blob, then we count bytes. +** +** If p1 is negative, then we begin abs(p1) from the end of x[]. +** +** If p2 is negative, return the p2 characters preceeding p1. +*/ +static void substrFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const unsigned char *z; + const unsigned char *z2; + int len; + int p0type; + i64 p1, p2; + int negP2 = 0; + + assert( argc==3 || argc==2 ); + if( sqlite3_value_type(argv[1])==SQLITE_NULL + || (argc==3 && sqlite3_value_type(argv[2])==SQLITE_NULL) + ){ + return; + } + p0type = sqlite3_value_type(argv[0]); + p1 = sqlite3_value_int(argv[1]); + if( p0type==SQLITE_BLOB ){ + len = sqlite3_value_bytes(argv[0]); + z = sqlite3_value_blob(argv[0]); + if( z==0 ) return; + assert( len==sqlite3_value_bytes(argv[0]) ); + }else{ + z = sqlite3_value_text(argv[0]); + if( z==0 ) return; + len = 0; + if( p1<0 ){ + for(z2=z; *z2; len++){ + SQLITE_SKIP_UTF8(z2); + } + } + } + if( argc==3 ){ + p2 = sqlite3_value_int(argv[2]); + if( p2<0 ){ + p2 = -p2; + negP2 = 1; + } + }else{ + p2 = sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH]; + } + if( p1<0 ){ + p1 += len; + if( p1<0 ){ + p2 += p1; + if( p2<0 ) p2 = 0; + p1 = 0; + } + }else if( p1>0 ){ + p1--; + }else if( p2>0 ){ + p2--; + } + if( negP2 ){ + p1 -= p2; + if( p1<0 ){ + p2 += p1; + p1 = 0; + } + } + assert( p1>=0 && p2>=0 ); + if( p0type!=SQLITE_BLOB ){ + while( *z && p1 ){ + SQLITE_SKIP_UTF8(z); + p1--; + } + for(z2=z; *z2 && p2; p2--){ + SQLITE_SKIP_UTF8(z2); + } + sqlite3_result_text(context, (char*)z, (int)(z2-z), SQLITE_TRANSIENT); + }else{ + if( p1+p2>len ){ + p2 = len-p1; + if( p2<0 ) p2 = 0; + } + sqlite3_result_blob(context, (char*)&z[p1], (int)p2, SQLITE_TRANSIENT); + } +} + +/* +** Implementation of the round() function +*/ +#ifndef SQLITE_OMIT_FLOATING_POINT +static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ + int n = 0; + double r; + char *zBuf; + assert( argc==1 || argc==2 ); + if( argc==2 ){ + if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return; + n = sqlite3_value_int(argv[1]); + if( n>30 ) n = 30; + if( n<0 ) n = 0; + } + if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; + r = sqlite3_value_double(argv[0]); + /* If Y==0 and X will fit in a 64-bit int, + ** handle the rounding directly, + ** otherwise use printf. + */ + if( n==0 && r>=0 && r0 ); + testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH] ); + testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH]+1 ); + if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + sqlite3_result_error_toobig(context); + z = 0; + }else{ + z = sqlite3Malloc((int)nByte); + if( !z ){ + sqlite3_result_error_nomem(context); + } + } + return z; +} + +/* +** Implementation of the upper() and lower() SQL functions. +*/ +static void upperFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ + char *z1; + const char *z2; + int i, n; + UNUSED_PARAMETER(argc); + z2 = (char*)sqlite3_value_text(argv[0]); + n = sqlite3_value_bytes(argv[0]); + /* Verify that the call to _bytes() does not invalidate the _text() pointer */ + assert( z2==(char*)sqlite3_value_text(argv[0]) ); + if( z2 ){ + z1 = contextMalloc(context, ((i64)n)+1); + if( z1 ){ + for(i=0; imatchOne; + u8 matchAll = pInfo->matchAll; + u8 matchSet = pInfo->matchSet; + u8 noCase = pInfo->noCase; + int prevEscape = 0; /* True if the previous character was 'escape' */ + + while( (c = sqlite3Utf8Read(zPattern,&zPattern))!=0 ){ + if( !prevEscape && c==matchAll ){ + while( (c=sqlite3Utf8Read(zPattern,&zPattern)) == matchAll + || c == matchOne ){ + if( c==matchOne && sqlite3Utf8Read(zString, &zString)==0 ){ + return 0; + } + } + if( c==0 ){ + return 1; + }else if( c==esc ){ + c = sqlite3Utf8Read(zPattern, &zPattern); + if( c==0 ){ + return 0; + } + }else if( c==matchSet ){ + assert( esc==0 ); /* This is GLOB, not LIKE */ + assert( matchSet<0x80 ); /* '[' is a single-byte character */ + while( *zString && patternCompare(&zPattern[-1],zString,pInfo,esc)==0 ){ + SQLITE_SKIP_UTF8(zString); + } + return *zString!=0; + } + while( (c2 = sqlite3Utf8Read(zString,&zString))!=0 ){ + if( noCase ){ + GlogUpperToLower(c2); + GlogUpperToLower(c); + while( c2 != 0 && c2 != c ){ + c2 = sqlite3Utf8Read(zString, &zString); + GlogUpperToLower(c2); + } + }else{ + while( c2 != 0 && c2 != c ){ + c2 = sqlite3Utf8Read(zString, &zString); + } + } + if( c2==0 ) return 0; + if( patternCompare(zPattern,zString,pInfo,esc) ) return 1; + } + return 0; + }else if( !prevEscape && c==matchOne ){ + if( sqlite3Utf8Read(zString, &zString)==0 ){ + return 0; + } + }else if( c==matchSet ){ + u32 prior_c = 0; + assert( esc==0 ); /* This only occurs for GLOB, not LIKE */ + seen = 0; + invert = 0; + c = sqlite3Utf8Read(zString, &zString); + if( c==0 ) return 0; + c2 = sqlite3Utf8Read(zPattern, &zPattern); + if( c2=='^' ){ + invert = 1; + c2 = sqlite3Utf8Read(zPattern, &zPattern); + } + if( c2==']' ){ + if( c==']' ) seen = 1; + c2 = sqlite3Utf8Read(zPattern, &zPattern); + } + while( c2 && c2!=']' ){ + if( c2=='-' && zPattern[0]!=']' && zPattern[0]!=0 && prior_c>0 ){ + c2 = sqlite3Utf8Read(zPattern, &zPattern); + if( c>=prior_c && c<=c2 ) seen = 1; + prior_c = 0; + }else{ + if( c==c2 ){ + seen = 1; + } + prior_c = c2; + } + c2 = sqlite3Utf8Read(zPattern, &zPattern); + } + if( c2==0 || (seen ^ invert)==0 ){ + return 0; + } + }else if( esc==c && !prevEscape ){ + prevEscape = 1; + }else{ + c2 = sqlite3Utf8Read(zString, &zString); + if( noCase ){ + GlogUpperToLower(c); + GlogUpperToLower(c2); + } + if( c!=c2 ){ + return 0; + } + prevEscape = 0; + } + } + return *zString==0; +} + +/* +** Count the number of times that the LIKE operator (or GLOB which is +** just a variation of LIKE) gets called. This is used for testing +** only. +*/ +#ifdef SQLITE_TEST +int sqlite3_like_count = 0; +#endif + + +/* +** Implementation of the like() SQL function. This function implements +** the build-in LIKE operator. The first argument to the function is the +** pattern and the second argument is the string. So, the SQL statements: +** +** A LIKE B +** +** is implemented as like(B,A). +** +** This same function (with a different compareInfo structure) computes +** the GLOB operator. +*/ +static void likeFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const unsigned char *zA, *zB; + u32 escape = 0; + int nPat; + sqlite3 *db = sqlite3_context_db_handle(context); + + zB = sqlite3_value_text(argv[0]); + zA = sqlite3_value_text(argv[1]); + + /* Limit the length of the LIKE or GLOB pattern to avoid problems + ** of deep recursion and N*N behavior in patternCompare(). + */ + nPat = sqlite3_value_bytes(argv[0]); + testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] ); + testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]+1 ); + if( nPat > db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] ){ + sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1); + return; + } + assert( zB==sqlite3_value_text(argv[0]) ); /* Encoding did not change */ + + if( argc==3 ){ + /* The escape character string must consist of a single UTF-8 character. + ** Otherwise, return an error. + */ + const unsigned char *zEsc = sqlite3_value_text(argv[2]); + if( zEsc==0 ) return; + if( sqlite3Utf8CharLen((char*)zEsc, -1)!=1 ){ + sqlite3_result_error(context, + "ESCAPE expression must be a single character", -1); + return; + } + escape = sqlite3Utf8Read(zEsc, &zEsc); + } + if( zA && zB ){ + struct compareInfo *pInfo = sqlite3_user_data(context); +#ifdef SQLITE_TEST + sqlite3_like_count++; +#endif + + sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape)); + } +} + +/* +** Implementation of the NULLIF(x,y) function. The result is the first +** argument if the arguments are different. The result is NULL if the +** arguments are equal to each other. +*/ +static void nullifFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + CollSeq *pColl = sqlite3GetFuncCollSeq(context); + UNUSED_PARAMETER(NotUsed); + if( sqlite3MemCompare(argv[0], argv[1], pColl)!=0 ){ + sqlite3_result_value(context, argv[0]); + } +} + +/* +** Implementation of the sqlite_version() function. The result is the version +** of the SQLite library that is running. +*/ +static void versionFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **NotUsed2 +){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + /* IMP: R-48699-48617 This function is an SQL wrapper around the + ** sqlite3_libversion() C-interface. */ + sqlite3_result_text(context, sqlite3_libversion(), -1, SQLITE_STATIC); +} + +/* +** Implementation of the sqlite_source_id() function. The result is a string +** that identifies the particular version of the source code used to build +** SQLite. +*/ +static void sourceidFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **NotUsed2 +){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + /* IMP: R-24470-31136 This function is an SQL wrapper around the + ** sqlite3_sourceid() C interface. */ + sqlite3_result_text(context, sqlite3_sourceid(), -1, SQLITE_STATIC); +} + +/* +** Implementation of the sqlite_log() function. This is a wrapper around +** sqlite3_log(). The return value is NULL. The function exists purely for +** its side-effects. +*/ +static void errlogFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + UNUSED_PARAMETER(argc); + UNUSED_PARAMETER(context); + sqlite3_log(sqlite3_value_int(argv[0]), "%s", sqlite3_value_text(argv[1])); +} + +/* +** Implementation of the sqlite_compileoption_used() function. +** The result is an integer that identifies if the compiler option +** was used to build SQLite. +*/ +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS +static void compileoptionusedFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const char *zOptName; + assert( argc==1 ); + UNUSED_PARAMETER(argc); + /* IMP: R-39564-36305 The sqlite_compileoption_used() SQL + ** function is a wrapper around the sqlite3_compileoption_used() C/C++ + ** function. + */ + if( (zOptName = (const char*)sqlite3_value_text(argv[0]))!=0 ){ + sqlite3_result_int(context, sqlite3_compileoption_used(zOptName)); + } +} +#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ + +/* +** Implementation of the sqlite_compileoption_get() function. +** The result is a string that identifies the compiler options +** used to build SQLite. +*/ +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS +static void compileoptiongetFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int n; + assert( argc==1 ); + UNUSED_PARAMETER(argc); + /* IMP: R-04922-24076 The sqlite_compileoption_get() SQL function + ** is a wrapper around the sqlite3_compileoption_get() C/C++ function. + */ + n = sqlite3_value_int(argv[0]); + sqlite3_result_text(context, sqlite3_compileoption_get(n), -1, SQLITE_STATIC); +} +#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ + +/* Array for converting from half-bytes (nybbles) into ASCII hex +** digits. */ +static const char hexdigits[] = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' +}; + +/* +** EXPERIMENTAL - This is not an official function. The interface may +** change. This function may disappear. Do not write code that depends +** on this function. +** +** Implementation of the QUOTE() function. This function takes a single +** argument. If the argument is numeric, the return value is the same as +** the argument. If the argument is NULL, the return value is the string +** "NULL". Otherwise, the argument is enclosed in single quotes with +** single-quote escapes. +*/ +static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ + assert( argc==1 ); + UNUSED_PARAMETER(argc); + switch( sqlite3_value_type(argv[0]) ){ + case SQLITE_INTEGER: + case SQLITE_FLOAT: { + sqlite3_result_value(context, argv[0]); + break; + } + case SQLITE_BLOB: { + char *zText = 0; + char const *zBlob = sqlite3_value_blob(argv[0]); + int nBlob = sqlite3_value_bytes(argv[0]); + assert( zBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */ + zText = (char *)contextMalloc(context, (2*(i64)nBlob)+4); + if( zText ){ + int i; + for(i=0; i>4)&0x0F]; + zText[(i*2)+3] = hexdigits[(zBlob[i])&0x0F]; + } + zText[(nBlob*2)+2] = '\''; + zText[(nBlob*2)+3] = '\0'; + zText[0] = 'X'; + zText[1] = '\''; + sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT); + sqlite3_free(zText); + } + break; + } + case SQLITE_TEXT: { + int i,j; + u64 n; + const unsigned char *zArg = sqlite3_value_text(argv[0]); + char *z; + + if( zArg==0 ) return; + for(i=0, n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; } + z = contextMalloc(context, ((i64)i)+((i64)n)+3); + if( z ){ + z[0] = '\''; + for(i=0, j=1; zArg[i]; i++){ + z[j++] = zArg[i]; + if( zArg[i]=='\'' ){ + z[j++] = '\''; + } + } + z[j++] = '\''; + z[j] = 0; + sqlite3_result_text(context, z, j, sqlite3_free); + } + break; + } + default: { + assert( sqlite3_value_type(argv[0])==SQLITE_NULL ); + sqlite3_result_text(context, "NULL", 4, SQLITE_STATIC); + break; + } + } +} + +/* +** The hex() function. Interpret the argument as a blob. Return +** a hexadecimal rendering as text. +*/ +static void hexFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int i, n; + const unsigned char *pBlob; + char *zHex, *z; + assert( argc==1 ); + UNUSED_PARAMETER(argc); + pBlob = sqlite3_value_blob(argv[0]); + n = sqlite3_value_bytes(argv[0]); + assert( pBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */ + z = zHex = contextMalloc(context, ((i64)n)*2 + 1); + if( zHex ){ + for(i=0; i>4)&0xf]; + *(z++) = hexdigits[c&0xf]; + } + *z = 0; + sqlite3_result_text(context, zHex, n*2, sqlite3_free); + } +} + +/* +** The zeroblob(N) function returns a zero-filled blob of size N bytes. +*/ +static void zeroblobFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + i64 n; + sqlite3 *db = sqlite3_context_db_handle(context); + assert( argc==1 ); + UNUSED_PARAMETER(argc); + n = sqlite3_value_int64(argv[0]); + testcase( n==db->aLimit[SQLITE_LIMIT_LENGTH] ); + testcase( n==db->aLimit[SQLITE_LIMIT_LENGTH]+1 ); + if( n>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + sqlite3_result_error_toobig(context); + }else{ + sqlite3_result_zeroblob(context, (int)n); /* IMP: R-00293-64994 */ + } +} + +/* +** The replace() function. Three arguments are all strings: call +** them A, B, and C. The result is also a string which is derived +** from A by replacing every occurance of B with C. The match +** must be exact. Collating sequences are not used. +*/ +static void replaceFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const unsigned char *zStr; /* The input string A */ + const unsigned char *zPattern; /* The pattern string B */ + const unsigned char *zRep; /* The replacement string C */ + unsigned char *zOut; /* The output */ + int nStr; /* Size of zStr */ + int nPattern; /* Size of zPattern */ + int nRep; /* Size of zRep */ + i64 nOut; /* Maximum size of zOut */ + int loopLimit; /* Last zStr[] that might match zPattern[] */ + int i, j; /* Loop counters */ + + assert( argc==3 ); + UNUSED_PARAMETER(argc); + zStr = sqlite3_value_text(argv[0]); + if( zStr==0 ) return; + nStr = sqlite3_value_bytes(argv[0]); + assert( zStr==sqlite3_value_text(argv[0]) ); /* No encoding change */ + zPattern = sqlite3_value_text(argv[1]); + if( zPattern==0 ){ + assert( sqlite3_value_type(argv[1])==SQLITE_NULL + || sqlite3_context_db_handle(context)->mallocFailed ); + return; + } + if( zPattern[0]==0 ){ + assert( sqlite3_value_type(argv[1])!=SQLITE_NULL ); + sqlite3_result_value(context, argv[0]); + return; + } + nPattern = sqlite3_value_bytes(argv[1]); + assert( zPattern==sqlite3_value_text(argv[1]) ); /* No encoding change */ + zRep = sqlite3_value_text(argv[2]); + if( zRep==0 ) return; + nRep = sqlite3_value_bytes(argv[2]); + assert( zRep==sqlite3_value_text(argv[2]) ); + nOut = nStr + 1; + assert( nOutaLimit[SQLITE_LIMIT_LENGTH] ); + testcase( nOut-2==db->aLimit[SQLITE_LIMIT_LENGTH] ); + if( nOut-1>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + sqlite3_result_error_toobig(context); + sqlite3_free(zOut); + return; + } + zOld = zOut; + zOut = sqlite3_realloc(zOut, (int)nOut); + if( zOut==0 ){ + sqlite3_result_error_nomem(context); + sqlite3_free(zOld); + return; + } + memcpy(&zOut[j], zRep, nRep); + j += nRep; + i += nPattern-1; + } + } + assert( j+nStr-i+1==nOut ); + memcpy(&zOut[j], &zStr[i], nStr-i); + j += nStr - i; + assert( j<=nOut ); + zOut[j] = 0; + sqlite3_result_text(context, (char*)zOut, j, sqlite3_free); +} + +/* +** Implementation of the TRIM(), LTRIM(), and RTRIM() functions. +** The userdata is 0x1 for left trim, 0x2 for right trim, 0x3 for both. +*/ +static void trimFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const unsigned char *zIn; /* Input string */ + const unsigned char *zCharSet; /* Set of characters to trim */ + int nIn; /* Number of bytes in input */ + int flags; /* 1: trimleft 2: trimright 3: trim */ + int i; /* Loop counter */ + unsigned char *aLen = 0; /* Length of each character in zCharSet */ + unsigned char **azChar = 0; /* Individual characters in zCharSet */ + int nChar; /* Number of characters in zCharSet */ + + if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ + return; + } + zIn = sqlite3_value_text(argv[0]); + if( zIn==0 ) return; + nIn = sqlite3_value_bytes(argv[0]); + assert( zIn==sqlite3_value_text(argv[0]) ); + if( argc==1 ){ + static const unsigned char lenOne[] = { 1 }; + static unsigned char * const azOne[] = { (u8*)" " }; + nChar = 1; + aLen = (u8*)lenOne; + azChar = (unsigned char **)azOne; + zCharSet = 0; + }else if( (zCharSet = sqlite3_value_text(argv[1]))==0 ){ + return; + }else{ + const unsigned char *z; + for(z=zCharSet, nChar=0; *z; nChar++){ + SQLITE_SKIP_UTF8(z); + } + if( nChar>0 ){ + azChar = contextMalloc(context, ((i64)nChar)*(sizeof(char*)+1)); + if( azChar==0 ){ + return; + } + aLen = (unsigned char*)&azChar[nChar]; + for(z=zCharSet, nChar=0; *z; nChar++){ + azChar[nChar] = (unsigned char *)z; + SQLITE_SKIP_UTF8(z); + aLen[nChar] = (u8)(z - azChar[nChar]); + } + } + } + if( nChar>0 ){ + flags = SQLITE_PTR_TO_INT(sqlite3_user_data(context)); + if( flags & 1 ){ + while( nIn>0 ){ + int len = 0; + for(i=0; i=nChar ) break; + zIn += len; + nIn -= len; + } + } + if( flags & 2 ){ + while( nIn>0 ){ + int len = 0; + for(i=0; i=nChar ) break; + nIn -= len; + } + } + if( zCharSet ){ + sqlite3_free(azChar); + } + } + sqlite3_result_text(context, (char*)zIn, nIn, SQLITE_TRANSIENT); +} + + +/* IMP: R-25361-16150 This function is omitted from SQLite by default. It +** is only available if the SQLITE_SOUNDEX compile-time option is used +** when SQLite is built. +*/ +#ifdef SQLITE_SOUNDEX +/* +** Compute the soundex encoding of a word. +** +** IMP: R-59782-00072 The soundex(X) function returns a string that is the +** soundex encoding of the string X. +*/ +static void soundexFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + char zResult[8]; + const u8 *zIn; + int i, j; + static const unsigned char iCode[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0, + 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0, + 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0, + }; + assert( argc==1 ); + zIn = (u8*)sqlite3_value_text(argv[0]); + if( zIn==0 ) zIn = (u8*)""; + for(i=0; zIn[i] && !sqlite3Isalpha(zIn[i]); i++){} + if( zIn[i] ){ + u8 prevcode = iCode[zIn[i]&0x7f]; + zResult[0] = sqlite3Toupper(zIn[i]); + for(j=1; j<4 && zIn[i]; i++){ + int code = iCode[zIn[i]&0x7f]; + if( code>0 ){ + if( code!=prevcode ){ + prevcode = code; + zResult[j++] = code + '0'; + } + }else{ + prevcode = 0; + } + } + while( j<4 ){ + zResult[j++] = '0'; + } + zResult[j] = 0; + sqlite3_result_text(context, zResult, 4, SQLITE_TRANSIENT); + }else{ + /* IMP: R-64894-50321 The string "?000" is returned if the argument + ** is NULL or contains no ASCII alphabetic characters. */ + sqlite3_result_text(context, "?000", 4, SQLITE_STATIC); + } +} +#endif /* SQLITE_SOUNDEX */ + +#ifndef SQLITE_OMIT_LOAD_EXTENSION +/* +** A function that loads a shared-library extension then returns NULL. +*/ +static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){ + const char *zFile = (const char *)sqlite3_value_text(argv[0]); + const char *zProc; + sqlite3 *db = sqlite3_context_db_handle(context); + char *zErrMsg = 0; + + if( argc==2 ){ + zProc = (const char *)sqlite3_value_text(argv[1]); + }else{ + zProc = 0; + } + if( zFile && sqlite3_load_extension(db, zFile, zProc, &zErrMsg) ){ + sqlite3_result_error(context, zErrMsg, -1); + sqlite3_free(zErrMsg); + } +} +#endif + + +/* +** An instance of the following structure holds the context of a +** sum() or avg() aggregate computation. +*/ +typedef struct SumCtx SumCtx; +struct SumCtx { + double rSum; /* Floating point sum */ + i64 iSum; /* Integer sum */ + i64 cnt; /* Number of elements summed */ + u8 overflow; /* True if integer overflow seen */ + u8 approx; /* True if non-integer value was input to the sum */ +}; + +/* +** Routines used to compute the sum, average, and total. +** +** The SUM() function follows the (broken) SQL standard which means +** that it returns NULL if it sums over no inputs. TOTAL returns +** 0.0 in that case. In addition, TOTAL always returns a float where +** SUM might return an integer if it never encounters a floating point +** value. TOTAL never fails, but SUM might through an exception if +** it overflows an integer. +*/ +static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){ + SumCtx *p; + int type; + assert( argc==1 ); + UNUSED_PARAMETER(argc); + p = sqlite3_aggregate_context(context, sizeof(*p)); + type = sqlite3_value_numeric_type(argv[0]); + if( p && type!=SQLITE_NULL ){ + p->cnt++; + if( type==SQLITE_INTEGER ){ + i64 v = sqlite3_value_int64(argv[0]); + p->rSum += v; + if( (p->approx|p->overflow)==0 && sqlite3AddInt64(&p->iSum, v) ){ + p->overflow = 1; + } + }else{ + p->rSum += sqlite3_value_double(argv[0]); + p->approx = 1; + } + } +} +static void sumFinalize(sqlite3_context *context){ + SumCtx *p; + p = sqlite3_aggregate_context(context, 0); + if( p && p->cnt>0 ){ + if( p->overflow ){ + sqlite3_result_error(context,"integer overflow",-1); + }else if( p->approx ){ + sqlite3_result_double(context, p->rSum); + }else{ + sqlite3_result_int64(context, p->iSum); + } + } +} +static void avgFinalize(sqlite3_context *context){ + SumCtx *p; + p = sqlite3_aggregate_context(context, 0); + if( p && p->cnt>0 ){ + sqlite3_result_double(context, p->rSum/(double)p->cnt); + } +} +static void totalFinalize(sqlite3_context *context){ + SumCtx *p; + p = sqlite3_aggregate_context(context, 0); + /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ + sqlite3_result_double(context, p ? p->rSum : (double)0); +} + +/* +** The following structure keeps track of state information for the +** count() aggregate function. +*/ +typedef struct CountCtx CountCtx; +struct CountCtx { + i64 n; +}; + +/* +** Routines to implement the count() aggregate function. +*/ +static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){ + CountCtx *p; + p = sqlite3_aggregate_context(context, sizeof(*p)); + if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && p ){ + p->n++; + } + +#ifndef SQLITE_OMIT_DEPRECATED + /* The sqlite3_aggregate_count() function is deprecated. But just to make + ** sure it still operates correctly, verify that its count agrees with our + ** internal count when using count(*) and when the total count can be + ** expressed as a 32-bit integer. */ + assert( argc==1 || p==0 || p->n>0x7fffffff + || p->n==sqlite3_aggregate_count(context) ); +#endif +} +static void countFinalize(sqlite3_context *context){ + CountCtx *p; + p = sqlite3_aggregate_context(context, 0); + sqlite3_result_int64(context, p ? p->n : 0); +} + +/* +** Routines to implement min() and max() aggregate functions. +*/ +static void minmaxStep( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + Mem *pArg = (Mem *)argv[0]; + Mem *pBest; + UNUSED_PARAMETER(NotUsed); + + if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; + pBest = (Mem *)sqlite3_aggregate_context(context, sizeof(*pBest)); + if( !pBest ) return; + + if( pBest->flags ){ + int max; + int cmp; + CollSeq *pColl = sqlite3GetFuncCollSeq(context); + /* This step function is used for both the min() and max() aggregates, + ** the only difference between the two being that the sense of the + ** comparison is inverted. For the max() aggregate, the + ** sqlite3_user_data() function returns (void *)-1. For min() it + ** returns (void *)db, where db is the sqlite3* database pointer. + ** Therefore the next statement sets variable 'max' to 1 for the max() + ** aggregate, or 0 for min(). + */ + max = sqlite3_user_data(context)!=0; + cmp = sqlite3MemCompare(pBest, pArg, pColl); + if( (max && cmp<0) || (!max && cmp>0) ){ + sqlite3VdbeMemCopy(pBest, pArg); + } + }else{ + sqlite3VdbeMemCopy(pBest, pArg); + } +} +static void minMaxFinalize(sqlite3_context *context){ + sqlite3_value *pRes; + pRes = (sqlite3_value *)sqlite3_aggregate_context(context, 0); + if( pRes ){ + if( ALWAYS(pRes->flags) ){ + sqlite3_result_value(context, pRes); + } + sqlite3VdbeMemRelease(pRes); + } +} + +/* +** group_concat(EXPR, ?SEPARATOR?) +*/ +static void groupConcatStep( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const char *zVal; + StrAccum *pAccum; + const char *zSep; + int nVal, nSep; + assert( argc==1 || argc==2 ); + if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; + pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum)); + + if( pAccum ){ + sqlite3 *db = sqlite3_context_db_handle(context); + int firstTerm = pAccum->useMalloc==0; + pAccum->useMalloc = 2; + pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH]; + if( !firstTerm ){ + if( argc==2 ){ + zSep = (char*)sqlite3_value_text(argv[1]); + nSep = sqlite3_value_bytes(argv[1]); + }else{ + zSep = ","; + nSep = 1; + } + sqlite3StrAccumAppend(pAccum, zSep, nSep); + } + zVal = (char*)sqlite3_value_text(argv[0]); + nVal = sqlite3_value_bytes(argv[0]); + sqlite3StrAccumAppend(pAccum, zVal, nVal); + } +} +static void groupConcatFinalize(sqlite3_context *context){ + StrAccum *pAccum; + pAccum = sqlite3_aggregate_context(context, 0); + if( pAccum ){ + if( pAccum->tooBig ){ + sqlite3_result_error_toobig(context); + }else if( pAccum->mallocFailed ){ + sqlite3_result_error_nomem(context); + }else{ + sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1, + sqlite3_free); + } + } +} + +/* +** This routine does per-connection function registration. Most +** of the built-in functions above are part of the global function set. +** This routine only deals with those that are not global. +*/ +void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ + int rc = sqlite3_overload_function(db, "MATCH", 2); + assert( rc==SQLITE_NOMEM || rc==SQLITE_OK ); + if( rc==SQLITE_NOMEM ){ + db->mallocFailed = 1; + } +} + +/* +** Set the LIKEOPT flag on the 2-argument function with the given name. +*/ +static void setLikeOptFlag(sqlite3 *db, const char *zName, u8 flagVal){ + FuncDef *pDef; + pDef = sqlite3FindFunction(db, zName, sqlite3Strlen30(zName), + 2, SQLITE_UTF8, 0); + if( ALWAYS(pDef) ){ + pDef->flags = flagVal; + } +} + +/* +** Register the built-in LIKE and GLOB functions. The caseSensitive +** parameter determines whether or not the LIKE operator is case +** sensitive. GLOB is always case sensitive. +*/ +void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){ + struct compareInfo *pInfo; + if( caseSensitive ){ + pInfo = (struct compareInfo*)&likeInfoAlt; + }else{ + pInfo = (struct compareInfo*)&likeInfoNorm; + } + sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0); + sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0); + sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8, + (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0); + setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE); + setLikeOptFlag(db, "like", + caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE); +} + +/* +** pExpr points to an expression which implements a function. If +** it is appropriate to apply the LIKE optimization to that function +** then set aWc[0] through aWc[2] to the wildcard characters and +** return TRUE. If the function is not a LIKE-style function then +** return FALSE. +*/ +int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){ + FuncDef *pDef; + if( pExpr->op!=TK_FUNCTION + || !pExpr->x.pList + || pExpr->x.pList->nExpr!=2 + ){ + return 0; + } + assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); + pDef = sqlite3FindFunction(db, pExpr->u.zToken, + sqlite3Strlen30(pExpr->u.zToken), + 2, SQLITE_UTF8, 0); + if( NEVER(pDef==0) || (pDef->flags & SQLITE_FUNC_LIKE)==0 ){ + return 0; + } + + /* The memcpy() statement assumes that the wildcard characters are + ** the first three statements in the compareInfo structure. The + ** asserts() that follow verify that assumption + */ + memcpy(aWc, pDef->pUserData, 3); + assert( (char*)&likeInfoAlt == (char*)&likeInfoAlt.matchAll ); + assert( &((char*)&likeInfoAlt)[1] == (char*)&likeInfoAlt.matchOne ); + assert( &((char*)&likeInfoAlt)[2] == (char*)&likeInfoAlt.matchSet ); + *pIsNocase = (pDef->flags & SQLITE_FUNC_CASE)==0; + return 1; +} + +/* +** All all of the FuncDef structures in the aBuiltinFunc[] array above +** to the global function hash table. This occurs at start-time (as +** a consequence of calling sqlite3_initialize()). +** +** After this routine runs +*/ +void sqlite3RegisterGlobalFunctions(void){ + /* + ** The following array holds FuncDef structures for all of the functions + ** defined in this file. + ** + ** The array cannot be constant since changes are made to the + ** FuncDef.pHash elements at start-time. The elements of this array + ** are read-only after initialization is complete. + */ + static SQLITE_WSD FuncDef aBuiltinFunc[] = { + FUNCTION(ltrim, 1, 1, 0, trimFunc ), + FUNCTION(ltrim, 2, 1, 0, trimFunc ), + FUNCTION(rtrim, 1, 2, 0, trimFunc ), + FUNCTION(rtrim, 2, 2, 0, trimFunc ), + FUNCTION(trim, 1, 3, 0, trimFunc ), + FUNCTION(trim, 2, 3, 0, trimFunc ), + FUNCTION(min, -1, 0, 1, minmaxFunc ), + FUNCTION(min, 0, 0, 1, 0 ), + AGGREGATE(min, 1, 0, 1, minmaxStep, minMaxFinalize ), + FUNCTION(max, -1, 1, 1, minmaxFunc ), + FUNCTION(max, 0, 1, 1, 0 ), + AGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize ), + FUNCTION(typeof, 1, 0, 0, typeofFunc ), + FUNCTION(length, 1, 0, 0, lengthFunc ), + FUNCTION(substr, 2, 0, 0, substrFunc ), + FUNCTION(substr, 3, 0, 0, substrFunc ), + FUNCTION(abs, 1, 0, 0, absFunc ), +#ifndef SQLITE_OMIT_FLOATING_POINT + FUNCTION(round, 1, 0, 0, roundFunc ), + FUNCTION(round, 2, 0, 0, roundFunc ), +#endif + FUNCTION(upper, 1, 0, 0, upperFunc ), + FUNCTION(lower, 1, 0, 0, lowerFunc ), + FUNCTION(coalesce, 1, 0, 0, 0 ), + FUNCTION(coalesce, 0, 0, 0, 0 ), +/* FUNCTION(coalesce, -1, 0, 0, ifnullFunc ), */ + {-1,SQLITE_UTF8,SQLITE_FUNC_COALESCE,0,0,ifnullFunc,0,0,"coalesce",0,0}, + FUNCTION(hex, 1, 0, 0, hexFunc ), +/* FUNCTION(ifnull, 2, 0, 0, ifnullFunc ), */ + {2,SQLITE_UTF8,SQLITE_FUNC_COALESCE,0,0,ifnullFunc,0,0,"ifnull",0,0}, + FUNCTION(random, 0, 0, 0, randomFunc ), + FUNCTION(randomblob, 1, 0, 0, randomBlob ), + FUNCTION(nullif, 2, 0, 1, nullifFunc ), + FUNCTION(sqlite_version, 0, 0, 0, versionFunc ), + FUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ), + FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ), +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS + FUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ), + FUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ), +#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ + FUNCTION(quote, 1, 0, 0, quoteFunc ), + FUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid), + FUNCTION(changes, 0, 0, 0, changes ), + FUNCTION(total_changes, 0, 0, 0, total_changes ), + FUNCTION(replace, 3, 0, 0, replaceFunc ), + FUNCTION(zeroblob, 1, 0, 0, zeroblobFunc ), + #ifdef SQLITE_SOUNDEX + FUNCTION(soundex, 1, 0, 0, soundexFunc ), + #endif + #ifndef SQLITE_OMIT_LOAD_EXTENSION + FUNCTION(load_extension, 1, 0, 0, loadExt ), + FUNCTION(load_extension, 2, 0, 0, loadExt ), + #endif + AGGREGATE(sum, 1, 0, 0, sumStep, sumFinalize ), + AGGREGATE(total, 1, 0, 0, sumStep, totalFinalize ), + AGGREGATE(avg, 1, 0, 0, sumStep, avgFinalize ), + /* AGGREGATE(count, 0, 0, 0, countStep, countFinalize ), */ + {0,SQLITE_UTF8,SQLITE_FUNC_COUNT,0,0,0,countStep,countFinalize,"count",0,0}, + AGGREGATE(count, 1, 0, 0, countStep, countFinalize ), + AGGREGATE(group_concat, 1, 0, 0, groupConcatStep, groupConcatFinalize), + AGGREGATE(group_concat, 2, 0, 0, groupConcatStep, groupConcatFinalize), + + LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), + #ifdef SQLITE_CASE_SENSITIVE_LIKE + LIKEFUNC(like, 2, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), + LIKEFUNC(like, 3, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), + #else + LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE), + LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE), + #endif + }; + + int i; + FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions); + FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aBuiltinFunc); + + for(i=0; i? */ + + 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x02, /* 40..47 @ABCDEFG */ + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 48..4f HIJKLMNO */ + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 50..57 PQRSTUVW */ + 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x40, /* 58..5f XYZ[\]^_ */ + 0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x22, /* 60..67 `abcdefg */ + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 68..6f hijklmno */ + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 70..77 pqrstuvw */ + 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, /* 78..7f xyz{|}~. */ + + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 80..87 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 88..8f ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 90..97 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 98..9f ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* a0..a7 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* a8..af ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* b0..b7 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* b8..bf ........ */ + + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* c0..c7 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* c8..cf ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* d0..d7 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* d8..df ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* e0..e7 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* e8..ef ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* f0..f7 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 /* f8..ff ........ */ +}; +#endif + +#ifndef SQLITE_USE_URI +# define SQLITE_USE_URI 0 +#endif + +/* +** The following singleton contains the global configuration for +** the SQLite library. +*/ +SQLITE_WSD struct Sqlite3Config sqlite3Config = { + SQLITE_DEFAULT_MEMSTATUS, /* bMemstat */ + 1, /* bCoreMutex */ + SQLITE_THREADSAFE==1, /* bFullMutex */ + SQLITE_USE_URI, /* bOpenUri */ + 0x7ffffffe, /* mxStrlen */ + 128, /* szLookaside */ + 500, /* nLookaside */ + {0,0,0,0,0,0,0,0}, /* m */ + {0,0,0,0,0,0,0,0,0}, /* mutex */ + {0,0,0,0,0,0,0,0,0,0,0,0,0},/* pcache2 */ + (void*)0, /* pHeap */ + 0, /* nHeap */ + 0, 0, /* mnHeap, mxHeap */ + (void*)0, /* pScratch */ + 0, /* szScratch */ + 0, /* nScratch */ + (void*)0, /* pPage */ + 0, /* szPage */ + 0, /* nPage */ + 0, /* mxParserStack */ + 0, /* sharedCacheEnabled */ + /* All the rest should always be initialized to zero */ + 0, /* isInit */ + 0, /* inProgress */ + 0, /* isMutexInit */ + 0, /* isMallocInit */ + 0, /* isPCacheInit */ + 0, /* pInitMutex */ + 0, /* nRefInitMutex */ + 0, /* xLog */ + 0, /* pLogArg */ + 0, /* bLocaltimeFault */ +}; + + +/* +** Hash table for global functions - functions common to all +** database connections. After initialization, this table is +** read-only. +*/ +SQLITE_WSD FuncDefHash sqlite3GlobalFunctions; + +/* +** Constant tokens for values 0 and 1. +*/ +const Token sqlite3IntTokens[] = { + { "0", 1 }, + { "1", 1 } +}; + + +/* +** The value of the "pending" byte must be 0x40000000 (1 byte past the +** 1-gibabyte boundary) in a compatible database. SQLite never uses +** the database page that contains the pending byte. It never attempts +** to read or write that page. The pending byte page is set assign +** for use by the VFS layers as space for managing file locks. +** +** During testing, it is often desirable to move the pending byte to +** a different position in the file. This allows code that has to +** deal with the pending byte to run on files that are much smaller +** than 1 GiB. The sqlite3_test_control() interface can be used to +** move the pending byte. +** +** IMPORTANT: Changing the pending byte to any value other than +** 0x40000000 results in an incompatible database file format! +** Changing the pending byte during operating results in undefined +** and dileterious behavior. +*/ +#ifndef SQLITE_OMIT_WSD +int sqlite3PendingByte = 0x40000000; +#endif + +#include "opcodes.h" +/* +** Properties of opcodes. The OPFLG_INITIALIZER macro is +** created by mkopcodeh.awk during compilation. Data is obtained +** from the comments following the "case OP_xxxx:" statements in +** the vdbe.c file. +*/ +const unsigned char sqlite3OpcodeProperty[] = OPFLG_INITIALIZER; diff --git a/scalos/libraries/sqlite/src/hash.c b/scalos/libraries/sqlite/src/hash.c new file mode 100644 index 000000000..d4daf92a6 --- /dev/null +++ b/scalos/libraries/sqlite/src/hash.c @@ -0,0 +1,277 @@ +/* +** 2001 September 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This is the implementation of generic hash-tables +** used in SQLite. +*/ +#include "sqliteInt.h" +#include + +/* Turn bulk memory into a hash table object by initializing the +** fields of the Hash structure. +** +** "pNew" is a pointer to the hash table that is to be initialized. +*/ +void sqlite3HashInit(Hash *pNew){ + assert( pNew!=0 ); + pNew->first = 0; + pNew->count = 0; + pNew->htsize = 0; + pNew->ht = 0; +} + +/* Remove all entries from a hash table. Reclaim all memory. +** Call this routine to delete a hash table or to reset a hash table +** to the empty state. +*/ +void sqlite3HashClear(Hash *pH){ + HashElem *elem; /* For looping over all elements of the table */ + + assert( pH!=0 ); + elem = pH->first; + pH->first = 0; + sqlite3_free(pH->ht); + pH->ht = 0; + pH->htsize = 0; + while( elem ){ + HashElem *next_elem = elem->next; + sqlite3_free(elem); + elem = next_elem; + } + pH->count = 0; +} + +/* +** The hashing function. +*/ +static unsigned int strHash(const char *z, int nKey){ + int h = 0; + assert( nKey>=0 ); + while( nKey > 0 ){ + h = (h<<3) ^ h ^ sqlite3UpperToLower[(unsigned char)*z++]; + nKey--; + } + return h; +} + + +/* Link pNew element into the hash table pH. If pEntry!=0 then also +** insert pNew into the pEntry hash bucket. +*/ +static void insertElement( + Hash *pH, /* The complete hash table */ + struct _ht *pEntry, /* The entry into which pNew is inserted */ + HashElem *pNew /* The element to be inserted */ +){ + HashElem *pHead; /* First element already in pEntry */ + if( pEntry ){ + pHead = pEntry->count ? pEntry->chain : 0; + pEntry->count++; + pEntry->chain = pNew; + }else{ + pHead = 0; + } + if( pHead ){ + pNew->next = pHead; + pNew->prev = pHead->prev; + if( pHead->prev ){ pHead->prev->next = pNew; } + else { pH->first = pNew; } + pHead->prev = pNew; + }else{ + pNew->next = pH->first; + if( pH->first ){ pH->first->prev = pNew; } + pNew->prev = 0; + pH->first = pNew; + } +} + + +/* Resize the hash table so that it cantains "new_size" buckets. +** +** The hash table might fail to resize if sqlite3_malloc() fails or +** if the new size is the same as the prior size. +** Return TRUE if the resize occurs and false if not. +*/ +static int rehash(Hash *pH, unsigned int new_size){ + struct _ht *new_ht; /* The new hash table */ + HashElem *elem, *next_elem; /* For looping over existing elements */ + +#if SQLITE_MALLOC_SOFT_LIMIT>0 + if( new_size*sizeof(struct _ht)>SQLITE_MALLOC_SOFT_LIMIT ){ + new_size = SQLITE_MALLOC_SOFT_LIMIT/sizeof(struct _ht); + } + if( new_size==pH->htsize ) return 0; +#endif + + /* The inability to allocates space for a larger hash table is + ** a performance hit but it is not a fatal error. So mark the + ** allocation as a benign. + */ + sqlite3BeginBenignMalloc(); + new_ht = (struct _ht *)sqlite3Malloc( new_size*sizeof(struct _ht) ); + sqlite3EndBenignMalloc(); + + if( new_ht==0 ) return 0; + sqlite3_free(pH->ht); + pH->ht = new_ht; + pH->htsize = new_size = sqlite3MallocSize(new_ht)/sizeof(struct _ht); + memset(new_ht, 0, new_size*sizeof(struct _ht)); + for(elem=pH->first, pH->first=0; elem; elem = next_elem){ + unsigned int h = strHash(elem->pKey, elem->nKey) % new_size; + next_elem = elem->next; + insertElement(pH, &new_ht[h], elem); + } + return 1; +} + +/* This function (for internal use only) locates an element in an +** hash table that matches the given key. The hash for this key has +** already been computed and is passed as the 4th parameter. +*/ +static HashElem *findElementGivenHash( + const Hash *pH, /* The pH to be searched */ + const char *pKey, /* The key we are searching for */ + int nKey, /* Bytes in key (not counting zero terminator) */ + unsigned int h /* The hash for this key. */ +){ + HashElem *elem; /* Used to loop thru the element list */ + int count; /* Number of elements left to test */ + + if( pH->ht ){ + struct _ht *pEntry = &pH->ht[h]; + elem = pEntry->chain; + count = pEntry->count; + }else{ + elem = pH->first; + count = pH->count; + } + while( count-- && ALWAYS(elem) ){ + if( elem->nKey==nKey && sqlite3StrNICmp(elem->pKey,pKey,nKey)==0 ){ + return elem; + } + elem = elem->next; + } + return 0; +} + +/* Remove a single entry from the hash table given a pointer to that +** element and a hash on the element's key. +*/ +static void removeElementGivenHash( + Hash *pH, /* The pH containing "elem" */ + HashElem* elem, /* The element to be removed from the pH */ + unsigned int h /* Hash value for the element */ +){ + struct _ht *pEntry; + if( elem->prev ){ + elem->prev->next = elem->next; + }else{ + pH->first = elem->next; + } + if( elem->next ){ + elem->next->prev = elem->prev; + } + if( pH->ht ){ + pEntry = &pH->ht[h]; + if( pEntry->chain==elem ){ + pEntry->chain = elem->next; + } + pEntry->count--; + assert( pEntry->count>=0 ); + } + sqlite3_free( elem ); + pH->count--; + if( pH->count<=0 ){ + assert( pH->first==0 ); + assert( pH->count==0 ); + sqlite3HashClear(pH); + } +} + +/* Attempt to locate an element of the hash table pH with a key +** that matches pKey,nKey. Return the data for this element if it is +** found, or NULL if there is no match. +*/ +void *sqlite3HashFind(const Hash *pH, const char *pKey, int nKey){ + HashElem *elem; /* The element that matches key */ + unsigned int h; /* A hash on key */ + + assert( pH!=0 ); + assert( pKey!=0 ); + assert( nKey>=0 ); + if( pH->ht ){ + h = strHash(pKey, nKey) % pH->htsize; + }else{ + h = 0; + } + elem = findElementGivenHash(pH, pKey, nKey, h); + return elem ? elem->data : 0; +} + +/* Insert an element into the hash table pH. The key is pKey,nKey +** and the data is "data". +** +** If no element exists with a matching key, then a new +** element is created and NULL is returned. +** +** If another element already exists with the same key, then the +** new data replaces the old data and the old data is returned. +** The key is not copied in this instance. If a malloc fails, then +** the new data is returned and the hash table is unchanged. +** +** If the "data" parameter to this function is NULL, then the +** element corresponding to "key" is removed from the hash table. +*/ +void *sqlite3HashInsert(Hash *pH, const char *pKey, int nKey, void *data){ + unsigned int h; /* the hash of the key modulo hash table size */ + HashElem *elem; /* Used to loop thru the element list */ + HashElem *new_elem; /* New element added to the pH */ + + assert( pH!=0 ); + assert( pKey!=0 ); + assert( nKey>=0 ); + if( pH->htsize ){ + h = strHash(pKey, nKey) % pH->htsize; + }else{ + h = 0; + } + elem = findElementGivenHash(pH,pKey,nKey,h); + if( elem ){ + void *old_data = elem->data; + if( data==0 ){ + removeElementGivenHash(pH,elem,h); + }else{ + elem->data = data; + elem->pKey = pKey; + assert(nKey==elem->nKey); + } + return old_data; + } + if( data==0 ) return 0; + new_elem = (HashElem*)sqlite3Malloc( sizeof(HashElem) ); + if( new_elem==0 ) return data; + new_elem->pKey = pKey; + new_elem->nKey = nKey; + new_elem->data = data; + pH->count++; + if( pH->count>=10 && pH->count > 2*pH->htsize ){ + if( rehash(pH, pH->count*2) ){ + assert( pH->htsize>0 ); + h = strHash(pKey, nKey) % pH->htsize; + } + } + if( pH->ht ){ + insertElement(pH, &pH->ht[h], new_elem); + }else{ + insertElement(pH, 0, new_elem); + } + return 0; +} diff --git a/scalos/libraries/sqlite/src/hash.h b/scalos/libraries/sqlite/src/hash.h new file mode 100644 index 000000000..990a2d6e2 --- /dev/null +++ b/scalos/libraries/sqlite/src/hash.h @@ -0,0 +1,96 @@ +/* +** 2001 September 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This is the header file for the generic hash-table implemenation +** used in SQLite. +*/ +#ifndef _SQLITE_HASH_H_ +#define _SQLITE_HASH_H_ + +/* Forward declarations of structures. */ +typedef struct Hash Hash; +typedef struct HashElem HashElem; + +/* A complete hash table is an instance of the following structure. +** The internals of this structure are intended to be opaque -- client +** code should not attempt to access or modify the fields of this structure +** directly. Change this structure only by using the routines below. +** However, some of the "procedures" and "functions" for modifying and +** accessing this structure are really macros, so we can't really make +** this structure opaque. +** +** All elements of the hash table are on a single doubly-linked list. +** Hash.first points to the head of this list. +** +** There are Hash.htsize buckets. Each bucket points to a spot in +** the global doubly-linked list. The contents of the bucket are the +** element pointed to plus the next _ht.count-1 elements in the list. +** +** Hash.htsize and Hash.ht may be zero. In that case lookup is done +** by a linear search of the global list. For small tables, the +** Hash.ht table is never allocated because if there are few elements +** in the table, it is faster to do a linear search than to manage +** the hash table. +*/ +struct Hash { + unsigned int htsize; /* Number of buckets in the hash table */ + unsigned int count; /* Number of entries in this table */ + HashElem *first; /* The first element of the array */ + struct _ht { /* the hash table */ + int count; /* Number of entries with this hash */ + HashElem *chain; /* Pointer to first entry with this hash */ + } *ht; +}; + +/* Each element in the hash table is an instance of the following +** structure. All elements are stored on a single doubly-linked list. +** +** Again, this structure is intended to be opaque, but it can't really +** be opaque because it is used by macros. +*/ +struct HashElem { + HashElem *next, *prev; /* Next and previous elements in the table */ + void *data; /* Data associated with this element */ + const char *pKey; int nKey; /* Key associated with this element */ +}; + +/* +** Access routines. To delete, insert a NULL pointer. +*/ +void sqlite3HashInit(Hash*); +void *sqlite3HashInsert(Hash*, const char *pKey, int nKey, void *pData); +void *sqlite3HashFind(const Hash*, const char *pKey, int nKey); +void sqlite3HashClear(Hash*); + +/* +** Macros for looping over all elements of a hash table. The idiom is +** like this: +** +** Hash h; +** HashElem *p; +** ... +** for(p=sqliteHashFirst(&h); p; p=sqliteHashNext(p)){ +** SomeStructure *pData = sqliteHashData(p); +** // do something with pData +** } +*/ +#define sqliteHashFirst(H) ((H)->first) +#define sqliteHashNext(E) ((E)->next) +#define sqliteHashData(E) ((E)->data) +/* #define sqliteHashKey(E) ((E)->pKey) // NOT USED */ +/* #define sqliteHashKeysize(E) ((E)->nKey) // NOT USED */ + +/* +** Number of entries in a hash table +*/ +/* #define sqliteHashCount(H) ((H)->count) // NOT USED */ + +#endif /* _SQLITE_HASH_H_ */ diff --git a/scalos/libraries/sqlite/src/hwtime.h b/scalos/libraries/sqlite/src/hwtime.h new file mode 100644 index 000000000..b8bc5a295 --- /dev/null +++ b/scalos/libraries/sqlite/src/hwtime.h @@ -0,0 +1,85 @@ +/* +** 2008 May 27 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains inline asm code for retrieving "high-performance" +** counters for x86 class CPUs. +*/ +#ifndef _HWTIME_H_ +#define _HWTIME_H_ + +/* +** The following routine only works on pentium-class (or newer) processors. +** It uses the RDTSC opcode to read the cycle count value out of the +** processor and returns that value. This can be used for high-res +** profiling. +*/ +#if (defined(__GNUC__) || defined(_MSC_VER)) && \ + (defined(i386) || defined(__i386__) || defined(_M_IX86)) + + #if defined(__GNUC__) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned int lo, hi; + __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); + return (sqlite_uint64)hi << 32 | lo; + } + + #elif defined(_MSC_VER) + + __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ + __asm { + rdtsc + ret ; return value at EDX:EAX + } + } + + #endif + +#elif (defined(__GNUC__) && defined(__x86_64__)) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned long val; + __asm__ __volatile__ ("rdtsc" : "=A" (val)); + return val; + } + +#elif (defined(__GNUC__) && defined(__ppc__)) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned long long retval; + unsigned long junk; + __asm__ __volatile__ ("\n\ + 1: mftbu %1\n\ + mftb %L0\n\ + mftbu %0\n\ + cmpw %0,%1\n\ + bne 1b" + : "=r" (retval), "=r" (junk)); + return retval; + } + +#else + + #error Need implementation of sqlite3Hwtime() for your platform. + + /* + ** To compile without implementing sqlite3Hwtime() for your platform, + ** you can remove the above #error and use the following + ** stub function. You will lose timing support for many + ** of the debugging and testing utilities, but it should at + ** least compile and run. + */ + sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } + +#endif + +#endif /* !defined(_HWTIME_H_) */ diff --git a/scalos/libraries/sqlite/src/insert.c b/scalos/libraries/sqlite/src/insert.c new file mode 100644 index 000000000..6b31e24f2 --- /dev/null +++ b/scalos/libraries/sqlite/src/insert.c @@ -0,0 +1,1842 @@ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains C code routines that are called by the parser +** to handle INSERT statements in SQLite. +*/ +#include "sqliteInt.h" + +/* +** Generate code that will open a table for reading. +*/ +void sqlite3OpenTable( + Parse *p, /* Generate code into this VDBE */ + int iCur, /* The cursor number of the table */ + int iDb, /* The database index in sqlite3.aDb[] */ + Table *pTab, /* The table to be opened */ + int opcode /* OP_OpenRead or OP_OpenWrite */ +){ + Vdbe *v; + if( IsVirtual(pTab) ) return; + v = sqlite3GetVdbe(p); + assert( opcode==OP_OpenWrite || opcode==OP_OpenRead ); + sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite)?1:0, pTab->zName); + sqlite3VdbeAddOp3(v, opcode, iCur, pTab->tnum, iDb); + sqlite3VdbeChangeP4(v, -1, SQLITE_INT_TO_PTR(pTab->nCol), P4_INT32); + VdbeComment((v, "%s", pTab->zName)); +} + +/* +** Return a pointer to the column affinity string associated with index +** pIdx. A column affinity string has one character for each column in +** the table, according to the affinity of the column: +** +** Character Column affinity +** ------------------------------ +** 'a' TEXT +** 'b' NONE +** 'c' NUMERIC +** 'd' INTEGER +** 'e' REAL +** +** An extra 'd' is appended to the end of the string to cover the +** rowid that appears as the last column in every index. +** +** Memory for the buffer containing the column index affinity string +** is managed along with the rest of the Index structure. It will be +** released when sqlite3DeleteIndex() is called. +*/ +const char *sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){ + if( !pIdx->zColAff ){ + /* The first time a column affinity string for a particular index is + ** required, it is allocated and populated here. It is then stored as + ** a member of the Index structure for subsequent use. + ** + ** The column affinity string will eventually be deleted by + ** sqliteDeleteIndex() when the Index structure itself is cleaned + ** up. + */ + int n; + Table *pTab = pIdx->pTable; + sqlite3 *db = sqlite3VdbeDb(v); + pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+2); + if( !pIdx->zColAff ){ + db->mallocFailed = 1; + return 0; + } + for(n=0; nnColumn; n++){ + pIdx->zColAff[n] = pTab->aCol[pIdx->aiColumn[n]].affinity; + } + pIdx->zColAff[n++] = SQLITE_AFF_INTEGER; + pIdx->zColAff[n] = 0; + } + + return pIdx->zColAff; +} + +/* +** Set P4 of the most recently inserted opcode to a column affinity +** string for table pTab. A column affinity string has one character +** for each column indexed by the index, according to the affinity of the +** column: +** +** Character Column affinity +** ------------------------------ +** 'a' TEXT +** 'b' NONE +** 'c' NUMERIC +** 'd' INTEGER +** 'e' REAL +*/ +void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){ + /* The first time a column affinity string for a particular table + ** is required, it is allocated and populated here. It is then + ** stored as a member of the Table structure for subsequent use. + ** + ** The column affinity string will eventually be deleted by + ** sqlite3DeleteTable() when the Table structure itself is cleaned up. + */ + if( !pTab->zColAff ){ + char *zColAff; + int i; + sqlite3 *db = sqlite3VdbeDb(v); + + zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1); + if( !zColAff ){ + db->mallocFailed = 1; + return; + } + + for(i=0; inCol; i++){ + zColAff[i] = pTab->aCol[i].affinity; + } + zColAff[pTab->nCol] = '\0'; + + pTab->zColAff = zColAff; + } + + sqlite3VdbeChangeP4(v, -1, pTab->zColAff, P4_TRANSIENT); +} + +/* +** Return non-zero if the table pTab in database iDb or any of its indices +** have been opened at any point in the VDBE program beginning at location +** iStartAddr throught the end of the program. This is used to see if +** a statement of the form "INSERT INTO SELECT ..." can +** run without using temporary table for the results of the SELECT. +*/ +static int readsTable(Parse *p, int iStartAddr, int iDb, Table *pTab){ + Vdbe *v = sqlite3GetVdbe(p); + int i; + int iEnd = sqlite3VdbeCurrentAddr(v); +#ifndef SQLITE_OMIT_VIRTUALTABLE + VTable *pVTab = IsVirtual(pTab) ? sqlite3GetVTable(p->db, pTab) : 0; +#endif + + for(i=iStartAddr; iopcode==OP_OpenRead && pOp->p3==iDb ){ + Index *pIndex; + int tnum = pOp->p2; + if( tnum==pTab->tnum ){ + return 1; + } + for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){ + if( tnum==pIndex->tnum ){ + return 1; + } + } + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( pOp->opcode==OP_VOpen && pOp->p4.pVtab==pVTab ){ + assert( pOp->p4.pVtab!=0 ); + assert( pOp->p4type==P4_VTAB ); + return 1; + } +#endif + } + return 0; +} + +#ifndef SQLITE_OMIT_AUTOINCREMENT +/* +** Locate or create an AutoincInfo structure associated with table pTab +** which is in database iDb. Return the register number for the register +** that holds the maximum rowid. +** +** There is at most one AutoincInfo structure per table even if the +** same table is autoincremented multiple times due to inserts within +** triggers. A new AutoincInfo structure is created if this is the +** first use of table pTab. On 2nd and subsequent uses, the original +** AutoincInfo structure is used. +** +** Three memory locations are allocated: +** +** (1) Register to hold the name of the pTab table. +** (2) Register to hold the maximum ROWID of pTab. +** (3) Register to hold the rowid in sqlite_sequence of pTab +** +** The 2nd register is the one that is returned. That is all the +** insert routine needs to know about. +*/ +static int autoIncBegin( + Parse *pParse, /* Parsing context */ + int iDb, /* Index of the database holding pTab */ + Table *pTab /* The table we are writing to */ +){ + int memId = 0; /* Register holding maximum rowid */ + if( pTab->tabFlags & TF_Autoincrement ){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + AutoincInfo *pInfo; + + pInfo = pToplevel->pAinc; + while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; } + if( pInfo==0 ){ + pInfo = sqlite3DbMallocRaw(pParse->db, sizeof(*pInfo)); + if( pInfo==0 ) return 0; + pInfo->pNext = pToplevel->pAinc; + pToplevel->pAinc = pInfo; + pInfo->pTab = pTab; + pInfo->iDb = iDb; + pToplevel->nMem++; /* Register to hold name of table */ + pInfo->regCtr = ++pToplevel->nMem; /* Max rowid register */ + pToplevel->nMem++; /* Rowid in sqlite_sequence */ + } + memId = pInfo->regCtr; + } + return memId; +} + +/* +** This routine generates code that will initialize all of the +** register used by the autoincrement tracker. +*/ +void sqlite3AutoincrementBegin(Parse *pParse){ + AutoincInfo *p; /* Information about an AUTOINCREMENT */ + sqlite3 *db = pParse->db; /* The database connection */ + Db *pDb; /* Database only autoinc table */ + int memId; /* Register holding max rowid */ + int addr; /* A VDBE address */ + Vdbe *v = pParse->pVdbe; /* VDBE under construction */ + + /* This routine is never called during trigger-generation. It is + ** only called from the top-level */ + assert( pParse->pTriggerTab==0 ); + assert( pParse==sqlite3ParseToplevel(pParse) ); + + assert( v ); /* We failed long ago if this is not so */ + for(p = pParse->pAinc; p; p = p->pNext){ + pDb = &db->aDb[p->iDb]; + memId = p->regCtr; + assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); + sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead); + sqlite3VdbeAddOp3(v, OP_Null, 0, memId, memId+1); + addr = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp4(v, OP_String8, 0, memId-1, 0, p->pTab->zName, 0); + sqlite3VdbeAddOp2(v, OP_Rewind, 0, addr+9); + sqlite3VdbeAddOp3(v, OP_Column, 0, 0, memId); + sqlite3VdbeAddOp3(v, OP_Ne, memId-1, addr+7, memId); + sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL); + sqlite3VdbeAddOp2(v, OP_Rowid, 0, memId+1); + sqlite3VdbeAddOp3(v, OP_Column, 0, 1, memId); + sqlite3VdbeAddOp2(v, OP_Goto, 0, addr+9); + sqlite3VdbeAddOp2(v, OP_Next, 0, addr+2); + sqlite3VdbeAddOp2(v, OP_Integer, 0, memId); + sqlite3VdbeAddOp0(v, OP_Close); + } +} + +/* +** Update the maximum rowid for an autoincrement calculation. +** +** This routine should be called when the top of the stack holds a +** new rowid that is about to be inserted. If that new rowid is +** larger than the maximum rowid in the memId memory cell, then the +** memory cell is updated. The stack is unchanged. +*/ +static void autoIncStep(Parse *pParse, int memId, int regRowid){ + if( memId>0 ){ + sqlite3VdbeAddOp2(pParse->pVdbe, OP_MemMax, memId, regRowid); + } +} + +/* +** This routine generates the code needed to write autoincrement +** maximum rowid values back into the sqlite_sequence register. +** Every statement that might do an INSERT into an autoincrement +** table (either directly or through triggers) needs to call this +** routine just before the "exit" code. +*/ +void sqlite3AutoincrementEnd(Parse *pParse){ + AutoincInfo *p; + Vdbe *v = pParse->pVdbe; + sqlite3 *db = pParse->db; + + assert( v ); + for(p = pParse->pAinc; p; p = p->pNext){ + Db *pDb = &db->aDb[p->iDb]; + int j1, j2, j3, j4, j5; + int iRec; + int memId = p->regCtr; + + iRec = sqlite3GetTempReg(pParse); + assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); + sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite); + j1 = sqlite3VdbeAddOp1(v, OP_NotNull, memId+1); + j2 = sqlite3VdbeAddOp0(v, OP_Rewind); + j3 = sqlite3VdbeAddOp3(v, OP_Column, 0, 0, iRec); + j4 = sqlite3VdbeAddOp3(v, OP_Eq, memId-1, 0, iRec); + sqlite3VdbeAddOp2(v, OP_Next, 0, j3); + sqlite3VdbeJumpHere(v, j2); + sqlite3VdbeAddOp2(v, OP_NewRowid, 0, memId+1); + j5 = sqlite3VdbeAddOp0(v, OP_Goto); + sqlite3VdbeJumpHere(v, j4); + sqlite3VdbeAddOp2(v, OP_Rowid, 0, memId+1); + sqlite3VdbeJumpHere(v, j1); + sqlite3VdbeJumpHere(v, j5); + sqlite3VdbeAddOp3(v, OP_MakeRecord, memId-1, 2, iRec); + sqlite3VdbeAddOp3(v, OP_Insert, 0, iRec, memId+1); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); + sqlite3VdbeAddOp0(v, OP_Close); + sqlite3ReleaseTempReg(pParse, iRec); + } +} +#else +/* +** If SQLITE_OMIT_AUTOINCREMENT is defined, then the three routines +** above are all no-ops +*/ +# define autoIncBegin(A,B,C) (0) +# define autoIncStep(A,B,C) +#endif /* SQLITE_OMIT_AUTOINCREMENT */ + + +/* Forward declaration */ +static int xferOptimization( + Parse *pParse, /* Parser context */ + Table *pDest, /* The table we are inserting into */ + Select *pSelect, /* A SELECT statement to use as the data source */ + int onError, /* How to handle constraint errors */ + int iDbDest /* The database of pDest */ +); + +/* +** This routine is call to handle SQL of the following forms: +** +** insert into TABLE (IDLIST) values(EXPRLIST) +** insert into TABLE (IDLIST) select +** +** The IDLIST following the table name is always optional. If omitted, +** then a list of all columns for the table is substituted. The IDLIST +** appears in the pColumn parameter. pColumn is NULL if IDLIST is omitted. +** +** The pList parameter holds EXPRLIST in the first form of the INSERT +** statement above, and pSelect is NULL. For the second form, pList is +** NULL and pSelect is a pointer to the select statement used to generate +** data for the insert. +** +** The code generated follows one of four templates. For a simple +** select with data coming from a VALUES clause, the code executes +** once straight down through. Pseudo-code follows (we call this +** the "1st template"): +** +** open write cursor to
and its indices +** puts VALUES clause expressions onto the stack +** write the resulting record into
+** cleanup +** +** The three remaining templates assume the statement is of the form +** +** INSERT INTO
SELECT ... +** +** If the SELECT clause is of the restricted form "SELECT * FROM " - +** in other words if the SELECT pulls all columns from a single table +** and there is no WHERE or LIMIT or GROUP BY or ORDER BY clauses, and +** if and are distinct tables but have identical +** schemas, including all the same indices, then a special optimization +** is invoked that copies raw records from over to . +** See the xferOptimization() function for the implementation of this +** template. This is the 2nd template. +** +** open a write cursor to
+** open read cursor on +** transfer all records in over to
+** close cursors +** foreach index on
+** open a write cursor on the
index +** open a read cursor on the corresponding index +** transfer all records from the read to the write cursors +** close cursors +** end foreach +** +** The 3rd template is for when the second template does not apply +** and the SELECT clause does not read from
at any time. +** The generated code follows this template: +** +** EOF <- 0 +** X <- A +** goto B +** A: setup for the SELECT +** loop over the rows in the SELECT +** load values into registers R..R+n +** yield X +** end loop +** cleanup after the SELECT +** EOF <- 1 +** yield X +** goto A +** B: open write cursor to
and its indices +** C: yield X +** if EOF goto D +** insert the select result into
from R..R+n +** goto C +** D: cleanup +** +** The 4th template is used if the insert statement takes its +** values from a SELECT but the data is being inserted into a table +** that is also read as part of the SELECT. In the third form, +** we have to use a intermediate table to store the results of +** the select. The template is like this: +** +** EOF <- 0 +** X <- A +** goto B +** A: setup for the SELECT +** loop over the tables in the SELECT +** load value into register R..R+n +** yield X +** end loop +** cleanup after the SELECT +** EOF <- 1 +** yield X +** halt-error +** B: open temp table +** L: yield X +** if EOF goto M +** insert row from R..R+n into temp table +** goto L +** M: open write cursor to
and its indices +** rewind temp table +** C: loop over rows of intermediate table +** transfer values form intermediate table into
+** end loop +** D: cleanup +*/ +void sqlite3Insert( + Parse *pParse, /* Parser context */ + SrcList *pTabList, /* Name of table into which we are inserting */ + ExprList *pList, /* List of values to be inserted */ + Select *pSelect, /* A SELECT statement to use as the data source */ + IdList *pColumn, /* Column names corresponding to IDLIST. */ + int onError /* How to handle constraint errors */ +){ + sqlite3 *db; /* The main database structure */ + Table *pTab; /* The table to insert into. aka TABLE */ + char *zTab; /* Name of the table into which we are inserting */ + const char *zDb; /* Name of the database holding this table */ + int i, j, idx; /* Loop counters */ + Vdbe *v; /* Generate code into this virtual machine */ + Index *pIdx; /* For looping over indices of the table */ + int nColumn; /* Number of columns in the data */ + int nHidden = 0; /* Number of hidden columns if TABLE is virtual */ + int baseCur = 0; /* VDBE Cursor number for pTab */ + int keyColumn = -1; /* Column that is the INTEGER PRIMARY KEY */ + int endOfLoop; /* Label for the end of the insertion loop */ + int useTempTable = 0; /* Store SELECT results in intermediate table */ + int srcTab = 0; /* Data comes from this temporary cursor if >=0 */ + int addrInsTop = 0; /* Jump to label "D" */ + int addrCont = 0; /* Top of insert loop. Label "C" in templates 3 and 4 */ + int addrSelect = 0; /* Address of coroutine that implements the SELECT */ + SelectDest dest; /* Destination for SELECT on rhs of INSERT */ + int iDb; /* Index of database holding TABLE */ + Db *pDb; /* The database containing table being inserted into */ + int appendFlag = 0; /* True if the insert is likely to be an append */ + + /* Register allocations */ + int regFromSelect = 0;/* Base register for data coming from SELECT */ + int regAutoinc = 0; /* Register holding the AUTOINCREMENT counter */ + int regRowCount = 0; /* Memory cell used for the row counter */ + int regIns; /* Block of regs holding rowid+data being inserted */ + int regRowid; /* registers holding insert rowid */ + int regData; /* register holding first column to insert */ + int regEof = 0; /* Register recording end of SELECT data */ + int *aRegIdx = 0; /* One register allocated to each index */ + +#ifndef SQLITE_OMIT_TRIGGER + int isView; /* True if attempting to insert into a view */ + Trigger *pTrigger; /* List of triggers on pTab, if required */ + int tmask; /* Mask of trigger times */ +#endif + + db = pParse->db; + memset(&dest, 0, sizeof(dest)); + if( pParse->nErr || db->mallocFailed ){ + goto insert_cleanup; + } + + /* Locate the table into which we will be inserting new information. + */ + assert( pTabList->nSrc==1 ); + zTab = pTabList->a[0].zName; + if( NEVER(zTab==0) ) goto insert_cleanup; + pTab = sqlite3SrcListLookup(pParse, pTabList); + if( pTab==0 ){ + goto insert_cleanup; + } + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iDbnDb ); + pDb = &db->aDb[iDb]; + zDb = pDb->zName; + if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){ + goto insert_cleanup; + } + + /* Figure out if we have any triggers and if the table being + ** inserted into is a view + */ +#ifndef SQLITE_OMIT_TRIGGER + pTrigger = sqlite3TriggersExist(pParse, pTab, TK_INSERT, 0, &tmask); + isView = pTab->pSelect!=0; +#else +# define pTrigger 0 +# define tmask 0 +# define isView 0 +#endif +#ifdef SQLITE_OMIT_VIEW +# undef isView +# define isView 0 +#endif + assert( (pTrigger && tmask) || (pTrigger==0 && tmask==0) ); + + /* If pTab is really a view, make sure it has been initialized. + ** ViewGetColumnNames() is a no-op if pTab is not a view (or virtual + ** module table). + */ + if( sqlite3ViewGetColumnNames(pParse, pTab) ){ + goto insert_cleanup; + } + + /* Ensure that: + * (a) the table is not read-only, + * (b) that if it is a view then ON INSERT triggers exist + */ + if( sqlite3IsReadOnly(pParse, pTab, tmask) ){ + goto insert_cleanup; + } + + /* Allocate a VDBE + */ + v = sqlite3GetVdbe(pParse); + if( v==0 ) goto insert_cleanup; + if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); + sqlite3BeginWriteOperation(pParse, pSelect || pTrigger, iDb); + +#ifndef SQLITE_OMIT_XFER_OPT + /* If the statement is of the form + ** + ** INSERT INTO SELECT * FROM ; + ** + ** Then special optimizations can be applied that make the transfer + ** very fast and which reduce fragmentation of indices. + ** + ** This is the 2nd template. + */ + if( pColumn==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){ + assert( !pTrigger ); + assert( pList==0 ); + goto insert_end; + } +#endif /* SQLITE_OMIT_XFER_OPT */ + + /* If this is an AUTOINCREMENT table, look up the sequence number in the + ** sqlite_sequence table and store it in memory cell regAutoinc. + */ + regAutoinc = autoIncBegin(pParse, iDb, pTab); + + /* Figure out how many columns of data are supplied. If the data + ** is coming from a SELECT statement, then generate a co-routine that + ** produces a single row of the SELECT on each invocation. The + ** co-routine is the common header to the 3rd and 4th templates. + */ + if( pSelect ){ + /* Data is coming from a SELECT. Generate code to implement that SELECT + ** as a co-routine. The code is common to both the 3rd and 4th + ** templates: + ** + ** EOF <- 0 + ** X <- A + ** goto B + ** A: setup for the SELECT + ** loop over the tables in the SELECT + ** load value into register R..R+n + ** yield X + ** end loop + ** cleanup after the SELECT + ** EOF <- 1 + ** yield X + ** halt-error + ** + ** On each invocation of the co-routine, it puts a single row of the + ** SELECT result into registers dest.iMem...dest.iMem+dest.nMem-1. + ** (These output registers are allocated by sqlite3Select().) When + ** the SELECT completes, it sets the EOF flag stored in regEof. + */ + int rc, j1; + + regEof = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 0, regEof); /* EOF <- 0 */ + VdbeComment((v, "SELECT eof flag")); + sqlite3SelectDestInit(&dest, SRT_Coroutine, ++pParse->nMem); + addrSelect = sqlite3VdbeCurrentAddr(v)+2; + sqlite3VdbeAddOp2(v, OP_Integer, addrSelect-1, dest.iParm); + j1 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); + VdbeComment((v, "Jump over SELECT coroutine")); + + /* Resolve the expressions in the SELECT statement and execute it. */ + rc = sqlite3Select(pParse, pSelect, &dest); + assert( pParse->nErr==0 || rc ); + if( rc || NEVER(pParse->nErr) || db->mallocFailed ){ + goto insert_cleanup; + } + sqlite3VdbeAddOp2(v, OP_Integer, 1, regEof); /* EOF <- 1 */ + sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm); /* yield X */ + sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_INTERNAL, OE_Abort); + VdbeComment((v, "End of SELECT coroutine")); + sqlite3VdbeJumpHere(v, j1); /* label B: */ + + regFromSelect = dest.iMem; + assert( pSelect->pEList ); + nColumn = pSelect->pEList->nExpr; + assert( dest.nMem==nColumn ); + + /* Set useTempTable to TRUE if the result of the SELECT statement + ** should be written into a temporary table (template 4). Set to + ** FALSE if each* row of the SELECT can be written directly into + ** the destination table (template 3). + ** + ** A temp table must be used if the table being updated is also one + ** of the tables being read by the SELECT statement. Also use a + ** temp table in the case of row triggers. + */ + if( pTrigger || readsTable(pParse, addrSelect, iDb, pTab) ){ + useTempTable = 1; + } + + if( useTempTable ){ + /* Invoke the coroutine to extract information from the SELECT + ** and add it to a transient table srcTab. The code generated + ** here is from the 4th template: + ** + ** B: open temp table + ** L: yield X + ** if EOF goto M + ** insert row from R..R+n into temp table + ** goto L + ** M: ... + */ + int regRec; /* Register to hold packed record */ + int regTempRowid; /* Register to hold temp table ROWID */ + int addrTop; /* Label "L" */ + int addrIf; /* Address of jump to M */ + + srcTab = pParse->nTab++; + regRec = sqlite3GetTempReg(pParse); + regTempRowid = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn); + addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm); + addrIf = sqlite3VdbeAddOp1(v, OP_If, regEof); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec); + sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid); + sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid); + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop); + sqlite3VdbeJumpHere(v, addrIf); + sqlite3ReleaseTempReg(pParse, regRec); + sqlite3ReleaseTempReg(pParse, regTempRowid); + } + }else{ + /* This is the case if the data for the INSERT is coming from a VALUES + ** clause + */ + NameContext sNC; + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + srcTab = -1; + assert( useTempTable==0 ); + nColumn = pList ? pList->nExpr : 0; + for(i=0; ia[i].pExpr) ){ + goto insert_cleanup; + } + } + } + + /* Make sure the number of columns in the source data matches the number + ** of columns to be inserted into the table. + */ + if( IsVirtual(pTab) ){ + for(i=0; inCol; i++){ + nHidden += (IsHiddenColumn(&pTab->aCol[i]) ? 1 : 0); + } + } + if( pColumn==0 && nColumn && nColumn!=(pTab->nCol-nHidden) ){ + sqlite3ErrorMsg(pParse, + "table %S has %d columns but %d values were supplied", + pTabList, 0, pTab->nCol-nHidden, nColumn); + goto insert_cleanup; + } + if( pColumn!=0 && nColumn!=pColumn->nId ){ + sqlite3ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId); + goto insert_cleanup; + } + + /* If the INSERT statement included an IDLIST term, then make sure + ** all elements of the IDLIST really are columns of the table and + ** remember the column indices. + ** + ** If the table has an INTEGER PRIMARY KEY column and that column + ** is named in the IDLIST, then record in the keyColumn variable + ** the index into IDLIST of the primary key column. keyColumn is + ** the index of the primary key as it appears in IDLIST, not as + ** is appears in the original table. (The index of the primary + ** key in the original table is pTab->iPKey.) + */ + if( pColumn ){ + for(i=0; inId; i++){ + pColumn->a[i].idx = -1; + } + for(i=0; inId; i++){ + for(j=0; jnCol; j++){ + if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){ + pColumn->a[i].idx = j; + if( j==pTab->iPKey ){ + keyColumn = i; + } + break; + } + } + if( j>=pTab->nCol ){ + if( sqlite3IsRowid(pColumn->a[i].zName) ){ + keyColumn = i; + }else{ + sqlite3ErrorMsg(pParse, "table %S has no column named %s", + pTabList, 0, pColumn->a[i].zName); + pParse->checkSchema = 1; + goto insert_cleanup; + } + } + } + } + + /* If there is no IDLIST term but the table has an integer primary + ** key, the set the keyColumn variable to the primary key column index + ** in the original table definition. + */ + if( pColumn==0 && nColumn>0 ){ + keyColumn = pTab->iPKey; + } + + /* Initialize the count of rows to be inserted + */ + if( db->flags & SQLITE_CountRows ){ + regRowCount = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount); + } + + /* If this is not a view, open the table and and all indices */ + if( !isView ){ + int nIdx; + + baseCur = pParse->nTab; + nIdx = sqlite3OpenTableAndIndices(pParse, pTab, baseCur, OP_OpenWrite); + aRegIdx = sqlite3DbMallocRaw(db, sizeof(int)*(nIdx+1)); + if( aRegIdx==0 ){ + goto insert_cleanup; + } + for(i=0; inMem; + } + } + + /* This is the top of the main insertion loop */ + if( useTempTable ){ + /* This block codes the top of loop only. The complete loop is the + ** following pseudocode (template 4): + ** + ** rewind temp table + ** C: loop over rows of intermediate table + ** transfer values form intermediate table into
+ ** end loop + ** D: ... + */ + addrInsTop = sqlite3VdbeAddOp1(v, OP_Rewind, srcTab); + addrCont = sqlite3VdbeCurrentAddr(v); + }else if( pSelect ){ + /* This block codes the top of loop only. The complete loop is the + ** following pseudocode (template 3): + ** + ** C: yield X + ** if EOF goto D + ** insert the select result into
from R..R+n + ** goto C + ** D: ... + */ + addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm); + addrInsTop = sqlite3VdbeAddOp1(v, OP_If, regEof); + } + + /* Allocate registers for holding the rowid of the new row, + ** the content of the new row, and the assemblied row record. + */ + regRowid = regIns = pParse->nMem+1; + pParse->nMem += pTab->nCol + 1; + if( IsVirtual(pTab) ){ + regRowid++; + pParse->nMem++; + } + regData = regRowid+1; + + /* Run the BEFORE and INSTEAD OF triggers, if there are any + */ + endOfLoop = sqlite3VdbeMakeLabel(v); + if( tmask & TRIGGER_BEFORE ){ + int regCols = sqlite3GetTempRange(pParse, pTab->nCol+1); + + /* build the NEW.* reference row. Note that if there is an INTEGER + ** PRIMARY KEY into which a NULL is being inserted, that NULL will be + ** translated into a unique ID for the row. But on a BEFORE trigger, + ** we do not know what the unique ID will be (because the insert has + ** not happened yet) so we substitute a rowid of -1 + */ + if( keyColumn<0 ){ + sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols); + }else{ + int j1; + if( useTempTable ){ + sqlite3VdbeAddOp3(v, OP_Column, srcTab, keyColumn, regCols); + }else{ + assert( pSelect==0 ); /* Otherwise useTempTable is true */ + sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, regCols); + } + j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols); + sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols); + sqlite3VdbeJumpHere(v, j1); + sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols); + } + + /* Cannot have triggers on a virtual table. If it were possible, + ** this block would have to account for hidden column. + */ + assert( !IsVirtual(pTab) ); + + /* Create the new column data + */ + for(i=0; inCol; i++){ + if( pColumn==0 ){ + j = i; + }else{ + for(j=0; jnId; j++){ + if( pColumn->a[j].idx==i ) break; + } + } + if( (!useTempTable && !pList) || (pColumn && j>=pColumn->nId) ){ + sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regCols+i+1); + }else if( useTempTable ){ + sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, regCols+i+1); + }else{ + assert( pSelect==0 ); /* Otherwise useTempTable is true */ + sqlite3ExprCodeAndCache(pParse, pList->a[j].pExpr, regCols+i+1); + } + } + + /* If this is an INSERT on a view with an INSTEAD OF INSERT trigger, + ** do not attempt any conversions before assembling the record. + ** If this is a real table, attempt conversions as required by the + ** table column affinities. + */ + if( !isView ){ + sqlite3VdbeAddOp2(v, OP_Affinity, regCols+1, pTab->nCol); + sqlite3TableAffinityStr(v, pTab); + } + + /* Fire BEFORE or INSTEAD OF triggers */ + sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_BEFORE, + pTab, regCols-pTab->nCol-1, onError, endOfLoop); + + sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol+1); + } + + /* Push the record number for the new entry onto the stack. The + ** record number is a randomly generate integer created by NewRowid + ** except when the table has an INTEGER PRIMARY KEY column, in which + ** case the record number is the same as that column. + */ + if( !isView ){ + if( IsVirtual(pTab) ){ + /* The row that the VUpdate opcode will delete: none */ + sqlite3VdbeAddOp2(v, OP_Null, 0, regIns); + } + if( keyColumn>=0 ){ + if( useTempTable ){ + sqlite3VdbeAddOp3(v, OP_Column, srcTab, keyColumn, regRowid); + }else if( pSelect ){ + sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+keyColumn, regRowid); + }else{ + VdbeOp *pOp; + sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, regRowid); + pOp = sqlite3VdbeGetOp(v, -1); + if( ALWAYS(pOp) && pOp->opcode==OP_Null && !IsVirtual(pTab) ){ + appendFlag = 1; + pOp->opcode = OP_NewRowid; + pOp->p1 = baseCur; + pOp->p2 = regRowid; + pOp->p3 = regAutoinc; + } + } + /* If the PRIMARY KEY expression is NULL, then use OP_NewRowid + ** to generate a unique primary key value. + */ + if( !appendFlag ){ + int j1; + if( !IsVirtual(pTab) ){ + j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid); + sqlite3VdbeAddOp3(v, OP_NewRowid, baseCur, regRowid, regAutoinc); + sqlite3VdbeJumpHere(v, j1); + }else{ + j1 = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, j1+2); + } + sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid); + } + }else if( IsVirtual(pTab) ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, regRowid); + }else{ + sqlite3VdbeAddOp3(v, OP_NewRowid, baseCur, regRowid, regAutoinc); + appendFlag = 1; + } + autoIncStep(pParse, regAutoinc, regRowid); + + /* Push onto the stack, data for all columns of the new entry, beginning + ** with the first column. + */ + nHidden = 0; + for(i=0; inCol; i++){ + int iRegStore = regRowid+1+i; + if( i==pTab->iPKey ){ + /* The value of the INTEGER PRIMARY KEY column is always a NULL. + ** Whenever this column is read, the record number will be substituted + ** in its place. So will fill this column with a NULL to avoid + ** taking up data space with information that will never be used. */ + sqlite3VdbeAddOp2(v, OP_Null, 0, iRegStore); + continue; + } + if( pColumn==0 ){ + if( IsHiddenColumn(&pTab->aCol[i]) ){ + assert( IsVirtual(pTab) ); + j = -1; + nHidden++; + }else{ + j = i - nHidden; + } + }else{ + for(j=0; jnId; j++){ + if( pColumn->a[j].idx==i ) break; + } + } + if( j<0 || nColumn==0 || (pColumn && j>=pColumn->nId) ){ + sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, iRegStore); + }else if( useTempTable ){ + sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, iRegStore); + }else if( pSelect ){ + sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+j, iRegStore); + }else{ + sqlite3ExprCode(pParse, pList->a[j].pExpr, iRegStore); + } + } + + /* Generate code to check constraints and generate index keys and + ** do the insertion. + */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); + sqlite3VtabMakeWritable(pParse, pTab); + sqlite3VdbeAddOp4(v, OP_VUpdate, 1, pTab->nCol+2, regIns, pVTab, P4_VTAB); + sqlite3VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError); + sqlite3MayAbort(pParse); + }else +#endif + { + int isReplace; /* Set to true if constraints may cause a replace */ + sqlite3GenerateConstraintChecks(pParse, pTab, baseCur, regIns, aRegIdx, + keyColumn>=0, 0, onError, endOfLoop, &isReplace + ); + sqlite3FkCheck(pParse, pTab, 0, regIns); + sqlite3CompleteInsertion( + pParse, pTab, baseCur, regIns, aRegIdx, 0, appendFlag, isReplace==0 + ); + } + } + + /* Update the count of rows that are inserted + */ + if( (db->flags & SQLITE_CountRows)!=0 ){ + sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1); + } + + if( pTrigger ){ + /* Code AFTER triggers */ + sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_AFTER, + pTab, regData-2-pTab->nCol, onError, endOfLoop); + } + + /* The bottom of the main insertion loop, if the data source + ** is a SELECT statement. + */ + sqlite3VdbeResolveLabel(v, endOfLoop); + if( useTempTable ){ + sqlite3VdbeAddOp2(v, OP_Next, srcTab, addrCont); + sqlite3VdbeJumpHere(v, addrInsTop); + sqlite3VdbeAddOp1(v, OP_Close, srcTab); + }else if( pSelect ){ + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrCont); + sqlite3VdbeJumpHere(v, addrInsTop); + } + + if( !IsVirtual(pTab) && !isView ){ + /* Close all tables opened */ + sqlite3VdbeAddOp1(v, OP_Close, baseCur); + for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){ + sqlite3VdbeAddOp1(v, OP_Close, idx+baseCur); + } + } + +insert_end: + /* Update the sqlite_sequence table by storing the content of the + ** maximum rowid counter values recorded while inserting into + ** autoincrement tables. + */ + if( pParse->nested==0 && pParse->pTriggerTab==0 ){ + sqlite3AutoincrementEnd(pParse); + } + + /* + ** Return the number of rows inserted. If this routine is + ** generating code because of a call to sqlite3NestedParse(), do not + ** invoke the callback function. + */ + if( (db->flags&SQLITE_CountRows) && !pParse->nested && !pParse->pTriggerTab ){ + sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1); + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC); + } + +insert_cleanup: + sqlite3SrcListDelete(db, pTabList); + sqlite3ExprListDelete(db, pList); + sqlite3SelectDelete(db, pSelect); + sqlite3IdListDelete(db, pColumn); + sqlite3DbFree(db, aRegIdx); +} + +/* Make sure "isView" and other macros defined above are undefined. Otherwise +** thely may interfere with compilation of other functions in this file +** (or in another file, if this file becomes part of the amalgamation). */ +#ifdef isView + #undef isView +#endif +#ifdef pTrigger + #undef pTrigger +#endif +#ifdef tmask + #undef tmask +#endif + + +/* +** Generate code to do constraint checks prior to an INSERT or an UPDATE. +** +** The input is a range of consecutive registers as follows: +** +** 1. The rowid of the row after the update. +** +** 2. The data in the first column of the entry after the update. +** +** i. Data from middle columns... +** +** N. The data in the last column of the entry after the update. +** +** The regRowid parameter is the index of the register containing (1). +** +** If isUpdate is true and rowidChng is non-zero, then rowidChng contains +** the address of a register containing the rowid before the update takes +** place. isUpdate is true for UPDATEs and false for INSERTs. If isUpdate +** is false, indicating an INSERT statement, then a non-zero rowidChng +** indicates that the rowid was explicitly specified as part of the +** INSERT statement. If rowidChng is false, it means that the rowid is +** computed automatically in an insert or that the rowid value is not +** modified by an update. +** +** The code generated by this routine store new index entries into +** registers identified by aRegIdx[]. No index entry is created for +** indices where aRegIdx[i]==0. The order of indices in aRegIdx[] is +** the same as the order of indices on the linked list of indices +** attached to the table. +** +** This routine also generates code to check constraints. NOT NULL, +** CHECK, and UNIQUE constraints are all checked. If a constraint fails, +** then the appropriate action is performed. There are five possible +** actions: ROLLBACK, ABORT, FAIL, REPLACE, and IGNORE. +** +** Constraint type Action What Happens +** --------------- ---------- ---------------------------------------- +** any ROLLBACK The current transaction is rolled back and +** sqlite3_exec() returns immediately with a +** return code of SQLITE_CONSTRAINT. +** +** any ABORT Back out changes from the current command +** only (do not do a complete rollback) then +** cause sqlite3_exec() to return immediately +** with SQLITE_CONSTRAINT. +** +** any FAIL Sqlite3_exec() returns immediately with a +** return code of SQLITE_CONSTRAINT. The +** transaction is not rolled back and any +** prior changes are retained. +** +** any IGNORE The record number and data is popped from +** the stack and there is an immediate jump +** to label ignoreDest. +** +** NOT NULL REPLACE The NULL value is replace by the default +** value for that column. If the default value +** is NULL, the action is the same as ABORT. +** +** UNIQUE REPLACE The other row that conflicts with the row +** being inserted is removed. +** +** CHECK REPLACE Illegal. The results in an exception. +** +** Which action to take is determined by the overrideError parameter. +** Or if overrideError==OE_Default, then the pParse->onError parameter +** is used. Or if pParse->onError==OE_Default then the onError value +** for the constraint is used. +** +** The calling routine must open a read/write cursor for pTab with +** cursor number "baseCur". All indices of pTab must also have open +** read/write cursors with cursor number baseCur+i for the i-th cursor. +** Except, if there is no possibility of a REPLACE action then +** cursors do not need to be open for indices where aRegIdx[i]==0. +*/ +void sqlite3GenerateConstraintChecks( + Parse *pParse, /* The parser context */ + Table *pTab, /* the table into which we are inserting */ + int baseCur, /* Index of a read/write cursor pointing at pTab */ + int regRowid, /* Index of the range of input registers */ + int *aRegIdx, /* Register used by each index. 0 for unused indices */ + int rowidChng, /* True if the rowid might collide with existing entry */ + int isUpdate, /* True for UPDATE, False for INSERT */ + int overrideError, /* Override onError to this if not OE_Default */ + int ignoreDest, /* Jump to this label on an OE_Ignore resolution */ + int *pbMayReplace /* OUT: Set to true if constraint may cause a replace */ +){ + int i; /* loop counter */ + Vdbe *v; /* VDBE under constrution */ + int nCol; /* Number of columns */ + int onError; /* Conflict resolution strategy */ + int j1; /* Addresss of jump instruction */ + int j2 = 0, j3; /* Addresses of jump instructions */ + int regData; /* Register containing first data column */ + int iCur; /* Table cursor number */ + Index *pIdx; /* Pointer to one of the indices */ + int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */ + int regOldRowid = (rowidChng && isUpdate) ? rowidChng : regRowid; + + v = sqlite3GetVdbe(pParse); + assert( v!=0 ); + assert( pTab->pSelect==0 ); /* This table is not a VIEW */ + nCol = pTab->nCol; + regData = regRowid + 1; + + /* Test all NOT NULL constraints. + */ + for(i=0; iiPKey ){ + continue; + } + onError = pTab->aCol[i].notNull; + if( onError==OE_None ) continue; + if( overrideError!=OE_Default ){ + onError = overrideError; + }else if( onError==OE_Default ){ + onError = OE_Abort; + } + if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){ + onError = OE_Abort; + } + assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail + || onError==OE_Ignore || onError==OE_Replace ); + switch( onError ){ + case OE_Abort: + sqlite3MayAbort(pParse); + case OE_Rollback: + case OE_Fail: { + char *zMsg; + sqlite3VdbeAddOp3(v, OP_HaltIfNull, + SQLITE_CONSTRAINT, onError, regData+i); + zMsg = sqlite3MPrintf(pParse->db, "%s.%s may not be NULL", + pTab->zName, pTab->aCol[i].zName); + sqlite3VdbeChangeP4(v, -1, zMsg, P4_DYNAMIC); + break; + } + case OE_Ignore: { + sqlite3VdbeAddOp2(v, OP_IsNull, regData+i, ignoreDest); + break; + } + default: { + assert( onError==OE_Replace ); + j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regData+i); + sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regData+i); + sqlite3VdbeJumpHere(v, j1); + break; + } + } + } + + /* Test all CHECK constraints + */ +#ifndef SQLITE_OMIT_CHECK + if( pTab->pCheck && (pParse->db->flags & SQLITE_IgnoreChecks)==0 ){ + int allOk = sqlite3VdbeMakeLabel(v); + pParse->ckBase = regData; + sqlite3ExprIfTrue(pParse, pTab->pCheck, allOk, SQLITE_JUMPIFNULL); + onError = overrideError!=OE_Default ? overrideError : OE_Abort; + if( onError==OE_Ignore ){ + sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest); + }else{ + if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */ + sqlite3HaltConstraint(pParse, onError, 0, 0); + } + sqlite3VdbeResolveLabel(v, allOk); + } +#endif /* !defined(SQLITE_OMIT_CHECK) */ + + /* If we have an INTEGER PRIMARY KEY, make sure the primary key + ** of the new record does not previously exist. Except, if this + ** is an UPDATE and the primary key is not changing, that is OK. + */ + if( rowidChng ){ + onError = pTab->keyConf; + if( overrideError!=OE_Default ){ + onError = overrideError; + }else if( onError==OE_Default ){ + onError = OE_Abort; + } + + if( isUpdate ){ + j2 = sqlite3VdbeAddOp3(v, OP_Eq, regRowid, 0, rowidChng); + } + j3 = sqlite3VdbeAddOp3(v, OP_NotExists, baseCur, 0, regRowid); + switch( onError ){ + default: { + onError = OE_Abort; + /* Fall thru into the next case */ + } + case OE_Rollback: + case OE_Abort: + case OE_Fail: { + sqlite3HaltConstraint( + pParse, onError, "PRIMARY KEY must be unique", P4_STATIC); + break; + } + case OE_Replace: { + /* If there are DELETE triggers on this table and the + ** recursive-triggers flag is set, call GenerateRowDelete() to + ** remove the conflicting row from the the table. This will fire + ** the triggers and remove both the table and index b-tree entries. + ** + ** Otherwise, if there are no triggers or the recursive-triggers + ** flag is not set, but the table has one or more indexes, call + ** GenerateRowIndexDelete(). This removes the index b-tree entries + ** only. The table b-tree entry will be replaced by the new entry + ** when it is inserted. + ** + ** If either GenerateRowDelete() or GenerateRowIndexDelete() is called, + ** also invoke MultiWrite() to indicate that this VDBE may require + ** statement rollback (if the statement is aborted after the delete + ** takes place). Earlier versions called sqlite3MultiWrite() regardless, + ** but being more selective here allows statements like: + ** + ** REPLACE INTO t(rowid) VALUES($newrowid) + ** + ** to run without a statement journal if there are no indexes on the + ** table. + */ + Trigger *pTrigger = 0; + if( pParse->db->flags&SQLITE_RecTriggers ){ + pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); + } + if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){ + sqlite3MultiWrite(pParse); + sqlite3GenerateRowDelete( + pParse, pTab, baseCur, regRowid, 0, pTrigger, OE_Replace + ); + }else if( pTab->pIndex ){ + sqlite3MultiWrite(pParse); + sqlite3GenerateRowIndexDelete(pParse, pTab, baseCur, 0); + } + seenReplace = 1; + break; + } + case OE_Ignore: { + assert( seenReplace==0 ); + sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest); + break; + } + } + sqlite3VdbeJumpHere(v, j3); + if( isUpdate ){ + sqlite3VdbeJumpHere(v, j2); + } + } + + /* Test all UNIQUE constraints by creating entries for each UNIQUE + ** index and making sure that duplicate entries do not already exist. + ** Add the new records to the indices as we go. + */ + for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){ + int regIdx; + int regR; + + if( aRegIdx[iCur]==0 ) continue; /* Skip unused indices */ + + /* Create a key for accessing the index entry */ + regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1); + for(i=0; inColumn; i++){ + int idx = pIdx->aiColumn[i]; + if( idx==pTab->iPKey ){ + sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i); + }else{ + sqlite3VdbeAddOp2(v, OP_SCopy, regData+idx, regIdx+i); + } + } + sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn+1, aRegIdx[iCur]); + sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), P4_TRANSIENT); + sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn+1); + + /* Find out what action to take in case there is an indexing conflict */ + onError = pIdx->onError; + if( onError==OE_None ){ + sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1); + continue; /* pIdx is not a UNIQUE index */ + } + if( overrideError!=OE_Default ){ + onError = overrideError; + }else if( onError==OE_Default ){ + onError = OE_Abort; + } + if( seenReplace ){ + if( onError==OE_Ignore ) onError = OE_Replace; + else if( onError==OE_Fail ) onError = OE_Abort; + } + + /* Check to see if the new index entry will be unique */ + regR = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_SCopy, regOldRowid, regR); + j3 = sqlite3VdbeAddOp4(v, OP_IsUnique, baseCur+iCur+1, 0, + regR, SQLITE_INT_TO_PTR(regIdx), + P4_INT32); + sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1); + + /* Generate code that executes if the new index entry is not unique */ + assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail + || onError==OE_Ignore || onError==OE_Replace ); + switch( onError ){ + case OE_Rollback: + case OE_Abort: + case OE_Fail: { + int j; + StrAccum errMsg; + const char *zSep; + char *zErr; + + sqlite3StrAccumInit(&errMsg, 0, 0, 200); + errMsg.db = pParse->db; + zSep = pIdx->nColumn>1 ? "columns " : "column "; + for(j=0; jnColumn; j++){ + char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName; + sqlite3StrAccumAppend(&errMsg, zSep, -1); + zSep = ", "; + sqlite3StrAccumAppend(&errMsg, zCol, -1); + } + sqlite3StrAccumAppend(&errMsg, + pIdx->nColumn>1 ? " are not unique" : " is not unique", -1); + zErr = sqlite3StrAccumFinish(&errMsg); + sqlite3HaltConstraint(pParse, onError, zErr, 0); + sqlite3DbFree(errMsg.db, zErr); + break; + } + case OE_Ignore: { + assert( seenReplace==0 ); + sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest); + break; + } + default: { + Trigger *pTrigger = 0; + assert( onError==OE_Replace ); + sqlite3MultiWrite(pParse); + if( pParse->db->flags&SQLITE_RecTriggers ){ + pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); + } + sqlite3GenerateRowDelete( + pParse, pTab, baseCur, regR, 0, pTrigger, OE_Replace + ); + seenReplace = 1; + break; + } + } + sqlite3VdbeJumpHere(v, j3); + sqlite3ReleaseTempReg(pParse, regR); + } + + if( pbMayReplace ){ + *pbMayReplace = seenReplace; + } +} + +/* +** This routine generates code to finish the INSERT or UPDATE operation +** that was started by a prior call to sqlite3GenerateConstraintChecks. +** A consecutive range of registers starting at regRowid contains the +** rowid and the content to be inserted. +** +** The arguments to this routine should be the same as the first six +** arguments to sqlite3GenerateConstraintChecks. +*/ +void sqlite3CompleteInsertion( + Parse *pParse, /* The parser context */ + Table *pTab, /* the table into which we are inserting */ + int baseCur, /* Index of a read/write cursor pointing at pTab */ + int regRowid, /* Range of content */ + int *aRegIdx, /* Register used by each index. 0 for unused indices */ + int isUpdate, /* True for UPDATE, False for INSERT */ + int appendBias, /* True if this is likely to be an append */ + int useSeekResult /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */ +){ + int i; + Vdbe *v; + int nIdx; + Index *pIdx; + u8 pik_flags; + int regData; + int regRec; + + v = sqlite3GetVdbe(pParse); + assert( v!=0 ); + assert( pTab->pSelect==0 ); /* This table is not a VIEW */ + for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){} + for(i=nIdx-1; i>=0; i--){ + if( aRegIdx[i]==0 ) continue; + sqlite3VdbeAddOp2(v, OP_IdxInsert, baseCur+i+1, aRegIdx[i]); + if( useSeekResult ){ + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + } + } + regData = regRowid + 1; + regRec = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec); + sqlite3TableAffinityStr(v, pTab); + sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol); + if( pParse->nested ){ + pik_flags = 0; + }else{ + pik_flags = OPFLAG_NCHANGE; + pik_flags |= (isUpdate?OPFLAG_ISUPDATE:OPFLAG_LASTROWID); + } + if( appendBias ){ + pik_flags |= OPFLAG_APPEND; + } + if( useSeekResult ){ + pik_flags |= OPFLAG_USESEEKRESULT; + } + sqlite3VdbeAddOp3(v, OP_Insert, baseCur, regRec, regRowid); + if( !pParse->nested ){ + sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT); + } + sqlite3VdbeChangeP5(v, pik_flags); +} + +/* +** Generate code that will open cursors for a table and for all +** indices of that table. The "baseCur" parameter is the cursor number used +** for the table. Indices are opened on subsequent cursors. +** +** Return the number of indices on the table. +*/ +int sqlite3OpenTableAndIndices( + Parse *pParse, /* Parsing context */ + Table *pTab, /* Table to be opened */ + int baseCur, /* Cursor number assigned to the table */ + int op /* OP_OpenRead or OP_OpenWrite */ +){ + int i; + int iDb; + Index *pIdx; + Vdbe *v; + + if( IsVirtual(pTab) ) return 0; + iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + v = sqlite3GetVdbe(pParse); + assert( v!=0 ); + sqlite3OpenTable(pParse, baseCur, iDb, pTab, op); + for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ + KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx); + assert( pIdx->pSchema==pTab->pSchema ); + sqlite3VdbeAddOp4(v, op, i+baseCur, pIdx->tnum, iDb, + (char*)pKey, P4_KEYINFO_HANDOFF); + VdbeComment((v, "%s", pIdx->zName)); + } + if( pParse->nTabnTab = baseCur+i; + } + return i-1; +} + + +#ifdef SQLITE_TEST +/* +** The following global variable is incremented whenever the +** transfer optimization is used. This is used for testing +** purposes only - to make sure the transfer optimization really +** is happening when it is suppose to. +*/ +int sqlite3_xferopt_count; +#endif /* SQLITE_TEST */ + + +#ifndef SQLITE_OMIT_XFER_OPT +/* +** Check to collation names to see if they are compatible. +*/ +static int xferCompatibleCollation(const char *z1, const char *z2){ + if( z1==0 ){ + return z2==0; + } + if( z2==0 ){ + return 0; + } + return sqlite3StrICmp(z1, z2)==0; +} + + +/* +** Check to see if index pSrc is compatible as a source of data +** for index pDest in an insert transfer optimization. The rules +** for a compatible index: +** +** * The index is over the same set of columns +** * The same DESC and ASC markings occurs on all columns +** * The same onError processing (OE_Abort, OE_Ignore, etc) +** * The same collating sequence on each column +*/ +static int xferCompatibleIndex(Index *pDest, Index *pSrc){ + int i; + assert( pDest && pSrc ); + assert( pDest->pTable!=pSrc->pTable ); + if( pDest->nColumn!=pSrc->nColumn ){ + return 0; /* Different number of columns */ + } + if( pDest->onError!=pSrc->onError ){ + return 0; /* Different conflict resolution strategies */ + } + for(i=0; inColumn; i++){ + if( pSrc->aiColumn[i]!=pDest->aiColumn[i] ){ + return 0; /* Different columns indexed */ + } + if( pSrc->aSortOrder[i]!=pDest->aSortOrder[i] ){ + return 0; /* Different sort orders */ + } + if( !xferCompatibleCollation(pSrc->azColl[i],pDest->azColl[i]) ){ + return 0; /* Different collating sequences */ + } + } + + /* If no test above fails then the indices must be compatible */ + return 1; +} + +/* +** Attempt the transfer optimization on INSERTs of the form +** +** INSERT INTO tab1 SELECT * FROM tab2; +** +** The xfer optimization transfers raw records from tab2 over to tab1. +** Columns are not decoded and reassemblied, which greatly improves +** performance. Raw index records are transferred in the same way. +** +** The xfer optimization is only attempted if tab1 and tab2 are compatible. +** There are lots of rules for determining compatibility - see comments +** embedded in the code for details. +** +** This routine returns TRUE if the optimization is guaranteed to be used. +** Sometimes the xfer optimization will only work if the destination table +** is empty - a factor that can only be determined at run-time. In that +** case, this routine generates code for the xfer optimization but also +** does a test to see if the destination table is empty and jumps over the +** xfer optimization code if the test fails. In that case, this routine +** returns FALSE so that the caller will know to go ahead and generate +** an unoptimized transfer. This routine also returns FALSE if there +** is no chance that the xfer optimization can be applied. +** +** This optimization is particularly useful at making VACUUM run faster. +*/ +static int xferOptimization( + Parse *pParse, /* Parser context */ + Table *pDest, /* The table we are inserting into */ + Select *pSelect, /* A SELECT statement to use as the data source */ + int onError, /* How to handle constraint errors */ + int iDbDest /* The database of pDest */ +){ + ExprList *pEList; /* The result set of the SELECT */ + Table *pSrc; /* The table in the FROM clause of SELECT */ + Index *pSrcIdx, *pDestIdx; /* Source and destination indices */ + struct SrcList_item *pItem; /* An element of pSelect->pSrc */ + int i; /* Loop counter */ + int iDbSrc; /* The database of pSrc */ + int iSrc, iDest; /* Cursors from source and destination */ + int addr1, addr2; /* Loop addresses */ + int emptyDestTest; /* Address of test for empty pDest */ + int emptySrcTest; /* Address of test for empty pSrc */ + Vdbe *v; /* The VDBE we are building */ + KeyInfo *pKey; /* Key information for an index */ + int regAutoinc; /* Memory register used by AUTOINC */ + int destHasUniqueIdx = 0; /* True if pDest has a UNIQUE index */ + int regData, regRowid; /* Registers holding data and rowid */ + + if( pSelect==0 ){ + return 0; /* Must be of the form INSERT INTO ... SELECT ... */ + } + if( sqlite3TriggerList(pParse, pDest) ){ + return 0; /* tab1 must not have triggers */ + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( pDest->tabFlags & TF_Virtual ){ + return 0; /* tab1 must not be a virtual table */ + } +#endif + if( onError==OE_Default ){ + if( pDest->iPKey>=0 ) onError = pDest->keyConf; + if( onError==OE_Default ) onError = OE_Abort; + } + assert(pSelect->pSrc); /* allocated even if there is no FROM clause */ + if( pSelect->pSrc->nSrc!=1 ){ + return 0; /* FROM clause must have exactly one term */ + } + if( pSelect->pSrc->a[0].pSelect ){ + return 0; /* FROM clause cannot contain a subquery */ + } + if( pSelect->pWhere ){ + return 0; /* SELECT may not have a WHERE clause */ + } + if( pSelect->pOrderBy ){ + return 0; /* SELECT may not have an ORDER BY clause */ + } + /* Do not need to test for a HAVING clause. If HAVING is present but + ** there is no ORDER BY, we will get an error. */ + if( pSelect->pGroupBy ){ + return 0; /* SELECT may not have a GROUP BY clause */ + } + if( pSelect->pLimit ){ + return 0; /* SELECT may not have a LIMIT clause */ + } + assert( pSelect->pOffset==0 ); /* Must be so if pLimit==0 */ + if( pSelect->pPrior ){ + return 0; /* SELECT may not be a compound query */ + } + if( pSelect->selFlags & SF_Distinct ){ + return 0; /* SELECT may not be DISTINCT */ + } + pEList = pSelect->pEList; + assert( pEList!=0 ); + if( pEList->nExpr!=1 ){ + return 0; /* The result set must have exactly one column */ + } + assert( pEList->a[0].pExpr ); + if( pEList->a[0].pExpr->op!=TK_ALL ){ + return 0; /* The result set must be the special operator "*" */ + } + + /* At this point we have established that the statement is of the + ** correct syntactic form to participate in this optimization. Now + ** we have to check the semantics. + */ + pItem = pSelect->pSrc->a; + pSrc = sqlite3LocateTable(pParse, 0, pItem->zName, pItem->zDatabase); + if( pSrc==0 ){ + return 0; /* FROM clause does not contain a real table */ + } + if( pSrc==pDest ){ + return 0; /* tab1 and tab2 may not be the same table */ + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( pSrc->tabFlags & TF_Virtual ){ + return 0; /* tab2 must not be a virtual table */ + } +#endif + if( pSrc->pSelect ){ + return 0; /* tab2 may not be a view */ + } + if( pDest->nCol!=pSrc->nCol ){ + return 0; /* Number of columns must be the same in tab1 and tab2 */ + } + if( pDest->iPKey!=pSrc->iPKey ){ + return 0; /* Both tables must have the same INTEGER PRIMARY KEY */ + } + for(i=0; inCol; i++){ + if( pDest->aCol[i].affinity!=pSrc->aCol[i].affinity ){ + return 0; /* Affinity must be the same on all columns */ + } + if( !xferCompatibleCollation(pDest->aCol[i].zColl, pSrc->aCol[i].zColl) ){ + return 0; /* Collating sequence must be the same on all columns */ + } + if( pDest->aCol[i].notNull && !pSrc->aCol[i].notNull ){ + return 0; /* tab2 must be NOT NULL if tab1 is */ + } + } + for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){ + if( pDestIdx->onError!=OE_None ){ + destHasUniqueIdx = 1; + } + for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){ + if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break; + } + if( pSrcIdx==0 ){ + return 0; /* pDestIdx has no corresponding index in pSrc */ + } + } +#ifndef SQLITE_OMIT_CHECK + if( pDest->pCheck && sqlite3ExprCompare(pSrc->pCheck, pDest->pCheck) ){ + return 0; /* Tables have different CHECK constraints. Ticket #2252 */ + } +#endif +#ifndef SQLITE_OMIT_FOREIGN_KEY + /* Disallow the transfer optimization if the destination table constains + ** any foreign key constraints. This is more restrictive than necessary. + ** But the main beneficiary of the transfer optimization is the VACUUM + ** command, and the VACUUM command disables foreign key constraints. So + ** the extra complication to make this rule less restrictive is probably + ** not worth the effort. Ticket [6284df89debdfa61db8073e062908af0c9b6118e] + */ + if( (pParse->db->flags & SQLITE_ForeignKeys)!=0 && pDest->pFKey!=0 ){ + return 0; + } +#endif + if( (pParse->db->flags & SQLITE_CountRows)!=0 ){ + return 0; /* xfer opt does not play well with PRAGMA count_changes */ + } + + /* If we get this far, it means that the xfer optimization is at + ** least a possibility, though it might only work if the destination + ** table (tab1) is initially empty. + */ +#ifdef SQLITE_TEST + sqlite3_xferopt_count++; +#endif + iDbSrc = sqlite3SchemaToIndex(pParse->db, pSrc->pSchema); + v = sqlite3GetVdbe(pParse); + sqlite3CodeVerifySchema(pParse, iDbSrc); + iSrc = pParse->nTab++; + iDest = pParse->nTab++; + regAutoinc = autoIncBegin(pParse, iDbDest, pDest); + sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite); + if( (pDest->iPKey<0 && pDest->pIndex!=0) /* (1) */ + || destHasUniqueIdx /* (2) */ + || (onError!=OE_Abort && onError!=OE_Rollback) /* (3) */ + ){ + /* In some circumstances, we are able to run the xfer optimization + ** only if the destination table is initially empty. This code makes + ** that determination. Conditions under which the destination must + ** be empty: + ** + ** (1) There is no INTEGER PRIMARY KEY but there are indices. + ** (If the destination is not initially empty, the rowid fields + ** of index entries might need to change.) + ** + ** (2) The destination has a unique index. (The xfer optimization + ** is unable to test uniqueness.) + ** + ** (3) onError is something other than OE_Abort and OE_Rollback. + */ + addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0); + emptyDestTest = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); + sqlite3VdbeJumpHere(v, addr1); + }else{ + emptyDestTest = 0; + } + sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead); + emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); + regData = sqlite3GetTempReg(pParse); + regRowid = sqlite3GetTempReg(pParse); + if( pDest->iPKey>=0 ){ + addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid); + addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid); + sqlite3HaltConstraint( + pParse, onError, "PRIMARY KEY must be unique", P4_STATIC); + sqlite3VdbeJumpHere(v, addr2); + autoIncStep(pParse, regAutoinc, regRowid); + }else if( pDest->pIndex==0 ){ + addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, regRowid); + }else{ + addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid); + assert( (pDest->tabFlags & TF_Autoincrement)==0 ); + } + sqlite3VdbeAddOp2(v, OP_RowData, iSrc, regData); + sqlite3VdbeAddOp3(v, OP_Insert, iDest, regData, regRowid); + sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND); + sqlite3VdbeChangeP4(v, -1, pDest->zName, 0); + sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1); + for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){ + for(pSrcIdx=pSrc->pIndex; ALWAYS(pSrcIdx); pSrcIdx=pSrcIdx->pNext){ + if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break; + } + assert( pSrcIdx ); + sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0); + sqlite3VdbeAddOp2(v, OP_Close, iDest, 0); + pKey = sqlite3IndexKeyinfo(pParse, pSrcIdx); + sqlite3VdbeAddOp4(v, OP_OpenRead, iSrc, pSrcIdx->tnum, iDbSrc, + (char*)pKey, P4_KEYINFO_HANDOFF); + VdbeComment((v, "%s", pSrcIdx->zName)); + pKey = sqlite3IndexKeyinfo(pParse, pDestIdx); + sqlite3VdbeAddOp4(v, OP_OpenWrite, iDest, pDestIdx->tnum, iDbDest, + (char*)pKey, P4_KEYINFO_HANDOFF); + VdbeComment((v, "%s", pDestIdx->zName)); + addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); + sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, regData); + sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1); + sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); + sqlite3VdbeJumpHere(v, addr1); + } + sqlite3VdbeJumpHere(v, emptySrcTest); + sqlite3ReleaseTempReg(pParse, regRowid); + sqlite3ReleaseTempReg(pParse, regData); + sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0); + sqlite3VdbeAddOp2(v, OP_Close, iDest, 0); + if( emptyDestTest ){ + sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, 0); + sqlite3VdbeJumpHere(v, emptyDestTest); + sqlite3VdbeAddOp2(v, OP_Close, iDest, 0); + return 0; + }else{ + return 1; + } +} +#endif /* SQLITE_OMIT_XFER_OPT */ diff --git a/scalos/libraries/sqlite/src/journal.c b/scalos/libraries/sqlite/src/journal.c new file mode 100644 index 000000000..2f9e22208 --- /dev/null +++ b/scalos/libraries/sqlite/src/journal.c @@ -0,0 +1,238 @@ +/* +** 2007 August 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file implements a special kind of sqlite3_file object used +** by SQLite to create journal files if the atomic-write optimization +** is enabled. +** +** The distinctive characteristic of this sqlite3_file is that the +** actual on disk file is created lazily. When the file is created, +** the caller specifies a buffer size for an in-memory buffer to +** be used to service read() and write() requests. The actual file +** on disk is not created or populated until either: +** +** 1) The in-memory representation grows too large for the allocated +** buffer, or +** 2) The sqlite3JournalCreate() function is called. +*/ +#ifdef SQLITE_ENABLE_ATOMIC_WRITE +#include "sqliteInt.h" + + +/* +** A JournalFile object is a subclass of sqlite3_file used by +** as an open file handle for journal files. +*/ +struct JournalFile { + sqlite3_io_methods *pMethod; /* I/O methods on journal files */ + int nBuf; /* Size of zBuf[] in bytes */ + char *zBuf; /* Space to buffer journal writes */ + int iSize; /* Amount of zBuf[] currently used */ + int flags; /* xOpen flags */ + sqlite3_vfs *pVfs; /* The "real" underlying VFS */ + sqlite3_file *pReal; /* The "real" underlying file descriptor */ + const char *zJournal; /* Name of the journal file */ +}; +typedef struct JournalFile JournalFile; + +/* +** If it does not already exists, create and populate the on-disk file +** for JournalFile p. +*/ +static int createFile(JournalFile *p){ + int rc = SQLITE_OK; + if( !p->pReal ){ + sqlite3_file *pReal = (sqlite3_file *)&p[1]; + rc = sqlite3OsOpen(p->pVfs, p->zJournal, pReal, p->flags, 0); + if( rc==SQLITE_OK ){ + p->pReal = pReal; + if( p->iSize>0 ){ + assert(p->iSize<=p->nBuf); + rc = sqlite3OsWrite(p->pReal, p->zBuf, p->iSize, 0); + } + } + } + return rc; +} + +/* +** Close the file. +*/ +static int jrnlClose(sqlite3_file *pJfd){ + JournalFile *p = (JournalFile *)pJfd; + if( p->pReal ){ + sqlite3OsClose(p->pReal); + } + sqlite3_free(p->zBuf); + return SQLITE_OK; +} + +/* +** Read data from the file. +*/ +static int jrnlRead( + sqlite3_file *pJfd, /* The journal file from which to read */ + void *zBuf, /* Put the results here */ + int iAmt, /* Number of bytes to read */ + sqlite_int64 iOfst /* Begin reading at this offset */ +){ + int rc = SQLITE_OK; + JournalFile *p = (JournalFile *)pJfd; + if( p->pReal ){ + rc = sqlite3OsRead(p->pReal, zBuf, iAmt, iOfst); + }else if( (iAmt+iOfst)>p->iSize ){ + rc = SQLITE_IOERR_SHORT_READ; + }else{ + memcpy(zBuf, &p->zBuf[iOfst], iAmt); + } + return rc; +} + +/* +** Write data to the file. +*/ +static int jrnlWrite( + sqlite3_file *pJfd, /* The journal file into which to write */ + const void *zBuf, /* Take data to be written from here */ + int iAmt, /* Number of bytes to write */ + sqlite_int64 iOfst /* Begin writing at this offset into the file */ +){ + int rc = SQLITE_OK; + JournalFile *p = (JournalFile *)pJfd; + if( !p->pReal && (iOfst+iAmt)>p->nBuf ){ + rc = createFile(p); + } + if( rc==SQLITE_OK ){ + if( p->pReal ){ + rc = sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst); + }else{ + memcpy(&p->zBuf[iOfst], zBuf, iAmt); + if( p->iSize<(iOfst+iAmt) ){ + p->iSize = (iOfst+iAmt); + } + } + } + return rc; +} + +/* +** Truncate the file. +*/ +static int jrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){ + int rc = SQLITE_OK; + JournalFile *p = (JournalFile *)pJfd; + if( p->pReal ){ + rc = sqlite3OsTruncate(p->pReal, size); + }else if( sizeiSize ){ + p->iSize = size; + } + return rc; +} + +/* +** Sync the file. +*/ +static int jrnlSync(sqlite3_file *pJfd, int flags){ + int rc; + JournalFile *p = (JournalFile *)pJfd; + if( p->pReal ){ + rc = sqlite3OsSync(p->pReal, flags); + }else{ + rc = SQLITE_OK; + } + return rc; +} + +/* +** Query the size of the file in bytes. +*/ +static int jrnlFileSize(sqlite3_file *pJfd, sqlite_int64 *pSize){ + int rc = SQLITE_OK; + JournalFile *p = (JournalFile *)pJfd; + if( p->pReal ){ + rc = sqlite3OsFileSize(p->pReal, pSize); + }else{ + *pSize = (sqlite_int64) p->iSize; + } + return rc; +} + +/* +** Table of methods for JournalFile sqlite3_file object. +*/ +static struct sqlite3_io_methods JournalFileMethods = { + 1, /* iVersion */ + jrnlClose, /* xClose */ + jrnlRead, /* xRead */ + jrnlWrite, /* xWrite */ + jrnlTruncate, /* xTruncate */ + jrnlSync, /* xSync */ + jrnlFileSize, /* xFileSize */ + 0, /* xLock */ + 0, /* xUnlock */ + 0, /* xCheckReservedLock */ + 0, /* xFileControl */ + 0, /* xSectorSize */ + 0, /* xDeviceCharacteristics */ + 0, /* xShmMap */ + 0, /* xShmLock */ + 0, /* xShmBarrier */ + 0 /* xShmUnmap */ +}; + +/* +** Open a journal file. +*/ +int sqlite3JournalOpen( + sqlite3_vfs *pVfs, /* The VFS to use for actual file I/O */ + const char *zName, /* Name of the journal file */ + sqlite3_file *pJfd, /* Preallocated, blank file handle */ + int flags, /* Opening flags */ + int nBuf /* Bytes buffered before opening the file */ +){ + JournalFile *p = (JournalFile *)pJfd; + memset(p, 0, sqlite3JournalSize(pVfs)); + if( nBuf>0 ){ + p->zBuf = sqlite3MallocZero(nBuf); + if( !p->zBuf ){ + return SQLITE_NOMEM; + } + }else{ + return sqlite3OsOpen(pVfs, zName, pJfd, flags, 0); + } + p->pMethod = &JournalFileMethods; + p->nBuf = nBuf; + p->flags = flags; + p->zJournal = zName; + p->pVfs = pVfs; + return SQLITE_OK; +} + +/* +** If the argument p points to a JournalFile structure, and the underlying +** file has not yet been created, create it now. +*/ +int sqlite3JournalCreate(sqlite3_file *p){ + if( p->pMethods!=&JournalFileMethods ){ + return SQLITE_OK; + } + return createFile((JournalFile *)p); +} + +/* +** Return the number of bytes required to store a JournalFile that uses vfs +** pVfs to create the underlying on-disk files. +*/ +int sqlite3JournalSize(sqlite3_vfs *pVfs){ + return (pVfs->szOsFile+sizeof(JournalFile)); +} +#endif diff --git a/scalos/libraries/sqlite/src/legacy.c b/scalos/libraries/sqlite/src/legacy.c new file mode 100644 index 000000000..ebab2de37 --- /dev/null +++ b/scalos/libraries/sqlite/src/legacy.c @@ -0,0 +1,145 @@ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** Main file for the SQLite library. The routines in this file +** implement the programmer interface to the library. Routines in +** other files are for internal use by SQLite and should not be +** accessed by users of the library. +*/ + +#include "sqliteInt.h" + +/* +** Execute SQL code. Return one of the SQLITE_ success/failure +** codes. Also write an error message into memory obtained from +** malloc() and make *pzErrMsg point to that message. +** +** If the SQL is a query, then for each row in the query result +** the xCallback() function is called. pArg becomes the first +** argument to xCallback(). If xCallback=NULL then no callback +** is invoked, even for queries. +*/ +int sqlite3_exec( + sqlite3 *db, /* The database on which the SQL executes */ + const char *zSql, /* The SQL to be executed */ + sqlite3_callback xCallback, /* Invoke this callback routine */ + void *pArg, /* First argument to xCallback() */ + char **pzErrMsg /* Write error messages here */ +){ + int rc = SQLITE_OK; /* Return code */ + const char *zLeftover; /* Tail of unprocessed SQL */ + sqlite3_stmt *pStmt = 0; /* The current SQL statement */ + char **azCols = 0; /* Names of result columns */ + int nRetry = 0; /* Number of retry attempts */ + int callbackIsInit; /* True if callback data is initialized */ + + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; + if( zSql==0 ) zSql = ""; + + sqlite3_mutex_enter(db->mutex); + sqlite3Error(db, SQLITE_OK, 0); + while( (rc==SQLITE_OK || (rc==SQLITE_SCHEMA && (++nRetry)<2)) && zSql[0] ){ + int nCol; + char **azVals = 0; + + pStmt = 0; + rc = sqlite3_prepare(db, zSql, -1, &pStmt, &zLeftover); + assert( rc==SQLITE_OK || pStmt==0 ); + if( rc!=SQLITE_OK ){ + continue; + } + if( !pStmt ){ + /* this happens for a comment or white-space */ + zSql = zLeftover; + continue; + } + + callbackIsInit = 0; + nCol = sqlite3_column_count(pStmt); + + while( 1 ){ + int i; + rc = sqlite3_step(pStmt); + + /* Invoke the callback function if required */ + if( xCallback && (SQLITE_ROW==rc || + (SQLITE_DONE==rc && !callbackIsInit + && db->flags&SQLITE_NullCallback)) ){ + if( !callbackIsInit ){ + azCols = sqlite3DbMallocZero(db, 2*nCol*sizeof(const char*) + 1); + if( azCols==0 ){ + goto exec_out; + } + for(i=0; imallocFailed = 1; + goto exec_out; + } + } + } + if( xCallback(pArg, nCol, azVals, azCols) ){ + rc = SQLITE_ABORT; + sqlite3VdbeFinalize((Vdbe *)pStmt); + pStmt = 0; + sqlite3Error(db, SQLITE_ABORT, 0); + goto exec_out; + } + } + + if( rc!=SQLITE_ROW ){ + rc = sqlite3VdbeFinalize((Vdbe *)pStmt); + pStmt = 0; + if( rc!=SQLITE_SCHEMA ){ + nRetry = 0; + zSql = zLeftover; + while( sqlite3Isspace(zSql[0]) ) zSql++; + } + break; + } + } + + sqlite3DbFree(db, azCols); + azCols = 0; + } + +exec_out: + if( pStmt ) sqlite3VdbeFinalize((Vdbe *)pStmt); + sqlite3DbFree(db, azCols); + + rc = sqlite3ApiExit(db, rc); + if( rc!=SQLITE_OK && ALWAYS(rc==sqlite3_errcode(db)) && pzErrMsg ){ + int nErrMsg = 1 + sqlite3Strlen30(sqlite3_errmsg(db)); + *pzErrMsg = sqlite3Malloc(nErrMsg); + if( *pzErrMsg ){ + memcpy(*pzErrMsg, sqlite3_errmsg(db), nErrMsg); + }else{ + rc = SQLITE_NOMEM; + sqlite3Error(db, SQLITE_NOMEM, 0); + } + }else if( pzErrMsg ){ + *pzErrMsg = 0; + } + + assert( (rc&db->errMask)==rc ); + sqlite3_mutex_leave(db->mutex); + return rc; +} diff --git a/scalos/libraries/sqlite/src/lempar.c b/scalos/libraries/sqlite/src/lempar.c new file mode 100644 index 000000000..cb6025e87 --- /dev/null +++ b/scalos/libraries/sqlite/src/lempar.c @@ -0,0 +1,863 @@ +/* Driver template for the LEMON parser generator. +** The author disclaims copyright to this source code. +** +** This version of "lempar.c" is modified, slightly, for use by SQLite. +** The only modifications are the addition of a couple of NEVER() +** macros to disable tests that are needed in the case of a general +** LALR(1) grammar but which are always false in the +** specific grammar used by SQLite. +*/ +/* First off, code is included that follows the "include" declaration +** in the input grammar file. */ +#include +%% +/* Next is all token values, in a form suitable for use by makeheaders. +** This section will be null unless lemon is run with the -m switch. +*/ +/* +** These constants (all generated automatically by the parser generator) +** specify the various kinds of tokens (terminals) that the parser +** understands. +** +** Each symbol here is a terminal symbol in the grammar. +*/ +%% +/* Make sure the INTERFACE macro is defined. +*/ +#ifndef INTERFACE +# define INTERFACE 1 +#endif +/* The next thing included is series of defines which control +** various aspects of the generated parser. +** YYCODETYPE is the data type used for storing terminal +** and nonterminal numbers. "unsigned char" is +** used if there are fewer than 250 terminals +** and nonterminals. "int" is used otherwise. +** YYNOCODE is a number of type YYCODETYPE which corresponds +** to no legal terminal or nonterminal number. This +** number is used to fill in empty slots of the hash +** table. +** YYFALLBACK If defined, this indicates that one or more tokens +** have fall-back values which should be used if the +** original value of the token will not parse. +** YYACTIONTYPE is the data type used for storing terminal +** and nonterminal numbers. "unsigned char" is +** used if there are fewer than 250 rules and +** states combined. "int" is used otherwise. +** ParseTOKENTYPE is the data type used for minor tokens given +** directly to the parser from the tokenizer. +** YYMINORTYPE is the data type used for all minor tokens. +** This is typically a union of many types, one of +** which is ParseTOKENTYPE. The entry in the union +** for base tokens is called "yy0". +** YYSTACKDEPTH is the maximum depth of the parser's stack. If +** zero the stack is dynamically sized using realloc() +** ParseARG_SDECL A static variable declaration for the %extra_argument +** ParseARG_PDECL A parameter declaration for the %extra_argument +** ParseARG_STORE Code to store %extra_argument into yypParser +** ParseARG_FETCH Code to extract %extra_argument from yypParser +** YYNSTATE the combined number of states. +** YYNRULE the number of rules in the grammar +** YYERRORSYMBOL is the code number of the error symbol. If not +** defined, then do no error processing. +*/ +%% +#define YY_NO_ACTION (YYNSTATE+YYNRULE+2) +#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) +#define YY_ERROR_ACTION (YYNSTATE+YYNRULE) + +/* The yyzerominor constant is used to initialize instances of +** YYMINORTYPE objects to zero. */ +static const YYMINORTYPE yyzerominor = { 0 }; + +/* Define the yytestcase() macro to be a no-op if is not already defined +** otherwise. +** +** Applications can choose to define yytestcase() in the %include section +** to a macro that can assist in verifying code coverage. For production +** code the yytestcase() macro should be turned off. But it is useful +** for testing. +*/ +#ifndef yytestcase +# define yytestcase(X) +#endif + + +/* Next are the tables used to determine what action to take based on the +** current state and lookahead token. These tables are used to implement +** functions that take a state number and lookahead value and return an +** action integer. +** +** Suppose the action integer is N. Then the action is determined as +** follows +** +** 0 <= N < YYNSTATE Shift N. That is, push the lookahead +** token onto the stack and goto state N. +** +** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE. +** +** N == YYNSTATE+YYNRULE A syntax error has occurred. +** +** N == YYNSTATE+YYNRULE+1 The parser accepts its input. +** +** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused +** slots in the yy_action[] table. +** +** The action table is constructed as a single large table named yy_action[]. +** Given state S and lookahead X, the action is computed as +** +** yy_action[ yy_shift_ofst[S] + X ] +** +** If the index value yy_shift_ofst[S]+X is out of range or if the value +** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S] +** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table +** and that yy_default[S] should be used instead. +** +** The formula above is for computing the action when the lookahead is +** a terminal symbol. If the lookahead is a non-terminal (as occurs after +** a reduce action) then the yy_reduce_ofst[] array is used in place of +** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of +** YY_SHIFT_USE_DFLT. +** +** The following are the tables generated in this section: +** +** yy_action[] A single table containing all actions. +** yy_lookahead[] A table containing the lookahead for each entry in +** yy_action. Used to detect hash collisions. +** yy_shift_ofst[] For each state, the offset into yy_action for +** shifting terminals. +** yy_reduce_ofst[] For each state, the offset into yy_action for +** shifting non-terminals after a reduce. +** yy_default[] Default action for each state. +*/ +%% + +/* The next table maps tokens into fallback tokens. If a construct +** like the following: +** +** %fallback ID X Y Z. +** +** appears in the grammar, then ID becomes a fallback token for X, Y, +** and Z. Whenever one of the tokens X, Y, or Z is input to the parser +** but it does not parse, the type of the token is changed to ID and +** the parse is retried before an error is thrown. +*/ +#ifdef YYFALLBACK +static const YYCODETYPE yyFallback[] = { +%% +}; +#endif /* YYFALLBACK */ + +/* The following structure represents a single element of the +** parser's stack. Information stored includes: +** +** + The state number for the parser at this level of the stack. +** +** + The value of the token stored at this level of the stack. +** (In other words, the "major" token.) +** +** + The semantic value stored at this level of the stack. This is +** the information used by the action routines in the grammar. +** It is sometimes called the "minor" token. +*/ +struct yyStackEntry { + YYACTIONTYPE stateno; /* The state-number */ + YYCODETYPE major; /* The major token value. This is the code + ** number for the token at this stack level */ + YYMINORTYPE minor; /* The user-supplied minor token value. This + ** is the value of the token */ +}; +typedef struct yyStackEntry yyStackEntry; + +/* The state of the parser is completely contained in an instance of +** the following structure */ +struct yyParser { + int yyidx; /* Index of top element in stack */ +#ifdef YYTRACKMAXSTACKDEPTH + int yyidxMax; /* Maximum value of yyidx */ +#endif + int yyerrcnt; /* Shifts left before out of the error */ + ParseARG_SDECL /* A place to hold %extra_argument */ +#if YYSTACKDEPTH<=0 + int yystksz; /* Current side of the stack */ + yyStackEntry *yystack; /* The parser's stack */ +#else + yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */ +#endif +}; +typedef struct yyParser yyParser; + +#ifndef NDEBUG +#include +static FILE *yyTraceFILE = 0; +static char *yyTracePrompt = 0; +#endif /* NDEBUG */ + +#ifndef NDEBUG +/* +** Turn parser tracing on by giving a stream to which to write the trace +** and a prompt to preface each trace message. Tracing is turned off +** by making either argument NULL +** +** Inputs: +**
    +**
  • A FILE* to which trace output should be written. +** If NULL, then tracing is turned off. +**
  • A prefix string written at the beginning of every +** line of trace output. If NULL, then tracing is +** turned off. +**
+** +** Outputs: +** None. +*/ +void ParseTrace(FILE *TraceFILE, char *zTracePrompt){ + yyTraceFILE = TraceFILE; + yyTracePrompt = zTracePrompt; + if( yyTraceFILE==0 ) yyTracePrompt = 0; + else if( yyTracePrompt==0 ) yyTraceFILE = 0; +} +#endif /* NDEBUG */ + +#ifndef NDEBUG +/* For tracing shifts, the names of all terminals and nonterminals +** are required. The following table supplies these names */ +static const char *const yyTokenName[] = { +%% +}; +#endif /* NDEBUG */ + +#ifndef NDEBUG +/* For tracing reduce actions, the names of all rules are required. +*/ +static const char *const yyRuleName[] = { +%% +}; +#endif /* NDEBUG */ + + +#if YYSTACKDEPTH<=0 +/* +** Try to increase the size of the parser stack. +*/ +static void yyGrowStack(yyParser *p){ + int newSize; + yyStackEntry *pNew; + + newSize = p->yystksz*2 + 100; + pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); + if( pNew ){ + p->yystack = pNew; + p->yystksz = newSize; +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sStack grows to %d entries!\n", + yyTracePrompt, p->yystksz); + } +#endif + } +} +#endif + +/* +** This function allocates a new parser. +** The only argument is a pointer to a function which works like +** malloc. +** +** Inputs: +** A pointer to the function used to allocate memory. +** +** Outputs: +** A pointer to a parser. This pointer is used in subsequent calls +** to Parse and ParseFree. +*/ +void *ParseAlloc(void *(*mallocProc)(size_t)){ + yyParser *pParser; + pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) ); + if( pParser ){ + pParser->yyidx = -1; +#ifdef YYTRACKMAXSTACKDEPTH + pParser->yyidxMax = 0; +#endif +#if YYSTACKDEPTH<=0 + pParser->yystack = NULL; + pParser->yystksz = 0; + yyGrowStack(pParser); +#endif + } + return pParser; +} + +/* The following function deletes the value associated with a +** symbol. The symbol can be either a terminal or nonterminal. +** "yymajor" is the symbol code, and "yypminor" is a pointer to +** the value. +*/ +static void yy_destructor( + yyParser *yypParser, /* The parser */ + YYCODETYPE yymajor, /* Type code for object to destroy */ + YYMINORTYPE *yypminor /* The object to be destroyed */ +){ + ParseARG_FETCH; + switch( yymajor ){ + /* Here is inserted the actions which take place when a + ** terminal or non-terminal is destroyed. This can happen + ** when the symbol is popped from the stack during a + ** reduce or during error processing or when a parser is + ** being destroyed before it is finished parsing. + ** + ** Note: during a reduce, the only symbols destroyed are those + ** which appear on the RHS of the rule, but which are not used + ** inside the C code. + */ +%% + default: break; /* If no destructor action specified: do nothing */ + } +} + +/* +** Pop the parser's stack once. +** +** If there is a destructor routine associated with the token which +** is popped from the stack, then call it. +** +** Return the major token number for the symbol popped. +*/ +static int yy_pop_parser_stack(yyParser *pParser){ + YYCODETYPE yymajor; + yyStackEntry *yytos = &pParser->yystack[pParser->yyidx]; + + /* There is no mechanism by which the parser stack can be popped below + ** empty in SQLite. */ + if( NEVER(pParser->yyidx<0) ) return 0; +#ifndef NDEBUG + if( yyTraceFILE && pParser->yyidx>=0 ){ + fprintf(yyTraceFILE,"%sPopping %s\n", + yyTracePrompt, + yyTokenName[yytos->major]); + } +#endif + yymajor = yytos->major; + yy_destructor(pParser, yymajor, &yytos->minor); + pParser->yyidx--; + return yymajor; +} + +/* +** Deallocate and destroy a parser. Destructors are all called for +** all stack elements before shutting the parser down. +** +** Inputs: +**
    +**
  • A pointer to the parser. This should be a pointer +** obtained from ParseAlloc. +**
  • A pointer to a function used to reclaim memory obtained +** from malloc. +**
+*/ +void ParseFree( + void *p, /* The parser to be deleted */ + void (*freeProc)(void*) /* Function used to reclaim memory */ +){ + yyParser *pParser = (yyParser*)p; + /* In SQLite, we never try to destroy a parser that was not successfully + ** created in the first place. */ + if( NEVER(pParser==0) ) return; + while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser); +#if YYSTACKDEPTH<=0 + free(pParser->yystack); +#endif + (*freeProc)((void*)pParser); +} + +/* +** Return the peak depth of the stack for a parser. +*/ +#ifdef YYTRACKMAXSTACKDEPTH +int ParseStackPeak(void *p){ + yyParser *pParser = (yyParser*)p; + return pParser->yyidxMax; +} +#endif + +/* +** Find the appropriate action for a parser given the terminal +** look-ahead token iLookAhead. +** +** If the look-ahead token is YYNOCODE, then check to see if the action is +** independent of the look-ahead. If it is, return the action, otherwise +** return YY_NO_ACTION. +*/ +static int yy_find_shift_action( + yyParser *pParser, /* The parser */ + YYCODETYPE iLookAhead /* The look-ahead token */ +){ + int i; + int stateno = pParser->yystack[pParser->yyidx].stateno; + + if( stateno>YY_SHIFT_COUNT + || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){ + return yy_default[stateno]; + } + assert( iLookAhead!=YYNOCODE ); + i += iLookAhead; + if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){ + if( iLookAhead>0 ){ +#ifdef YYFALLBACK + YYCODETYPE iFallback; /* Fallback token */ + if( iLookAhead %s\n", + yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); + } +#endif + return yy_find_shift_action(pParser, iFallback); + } +#endif +#ifdef YYWILDCARD + { + int j = i - iLookAhead + YYWILDCARD; + if( +#if YY_SHIFT_MIN+YYWILDCARD<0 + j>=0 && +#endif +#if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT + j %s\n", + yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]); + } +#endif /* NDEBUG */ + return yy_action[j]; + } + } +#endif /* YYWILDCARD */ + } + return yy_default[stateno]; + }else{ + return yy_action[i]; + } +} + +/* +** Find the appropriate action for a parser given the non-terminal +** look-ahead token iLookAhead. +** +** If the look-ahead token is YYNOCODE, then check to see if the action is +** independent of the look-ahead. If it is, return the action, otherwise +** return YY_NO_ACTION. +*/ +static int yy_find_reduce_action( + int stateno, /* Current state number */ + YYCODETYPE iLookAhead /* The look-ahead token */ +){ + int i; +#ifdef YYERRORSYMBOL + if( stateno>YY_REDUCE_COUNT ){ + return yy_default[stateno]; + } +#else + assert( stateno<=YY_REDUCE_COUNT ); +#endif + i = yy_reduce_ofst[stateno]; + assert( i!=YY_REDUCE_USE_DFLT ); + assert( iLookAhead!=YYNOCODE ); + i += iLookAhead; +#ifdef YYERRORSYMBOL + if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){ + return yy_default[stateno]; + } +#else + assert( i>=0 && iyyidx--; +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt); + } +#endif + while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); + /* Here code is inserted which will execute if the parser + ** stack every overflows */ +%% + ParseARG_STORE; /* Suppress warning about unused %extra_argument var */ +} + +/* +** Perform a shift action. +*/ +static void yy_shift( + yyParser *yypParser, /* The parser to be shifted */ + int yyNewState, /* The new state to shift in */ + int yyMajor, /* The major token to shift in */ + YYMINORTYPE *yypMinor /* Pointer to the minor token to shift in */ +){ + yyStackEntry *yytos; + yypParser->yyidx++; +#ifdef YYTRACKMAXSTACKDEPTH + if( yypParser->yyidx>yypParser->yyidxMax ){ + yypParser->yyidxMax = yypParser->yyidx; + } +#endif +#if YYSTACKDEPTH>0 + if( yypParser->yyidx>=YYSTACKDEPTH ){ + yyStackOverflow(yypParser, yypMinor); + return; + } +#else + if( yypParser->yyidx>=yypParser->yystksz ){ + yyGrowStack(yypParser); + if( yypParser->yyidx>=yypParser->yystksz ){ + yyStackOverflow(yypParser, yypMinor); + return; + } + } +#endif + yytos = &yypParser->yystack[yypParser->yyidx]; + yytos->stateno = (YYACTIONTYPE)yyNewState; + yytos->major = (YYCODETYPE)yyMajor; + yytos->minor = *yypMinor; +#ifndef NDEBUG + if( yyTraceFILE && yypParser->yyidx>0 ){ + int i; + fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState); + fprintf(yyTraceFILE,"%sStack:",yyTracePrompt); + for(i=1; i<=yypParser->yyidx; i++) + fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]); + fprintf(yyTraceFILE,"\n"); + } +#endif +} + +/* The following table contains information about every rule that +** is used during the reduce. +*/ +static const struct { + YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ + unsigned char nrhs; /* Number of right-hand side symbols in the rule */ +} yyRuleInfo[] = { +%% +}; + +static void yy_accept(yyParser*); /* Forward Declaration */ + +/* +** Perform a reduce action and the shift that must immediately +** follow the reduce. +*/ +static void yy_reduce( + yyParser *yypParser, /* The parser */ + int yyruleno /* Number of the rule by which to reduce */ +){ + int yygoto; /* The next state */ + int yyact; /* The next action */ + YYMINORTYPE yygotominor; /* The LHS of the rule reduced */ + yyStackEntry *yymsp; /* The top of the parser's stack */ + int yysize; /* Amount to pop the stack */ + ParseARG_FETCH; + yymsp = &yypParser->yystack[yypParser->yyidx]; +#ifndef NDEBUG + if( yyTraceFILE && yyruleno>=0 + && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ + fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt, + yyRuleName[yyruleno]); + } +#endif /* NDEBUG */ + + /* Silence complaints from purify about yygotominor being uninitialized + ** in some cases when it is copied into the stack after the following + ** switch. yygotominor is uninitialized when a rule reduces that does + ** not set the value of its left-hand side nonterminal. Leaving the + ** value of the nonterminal uninitialized is utterly harmless as long + ** as the value is never used. So really the only thing this code + ** accomplishes is to quieten purify. + ** + ** 2007-01-16: The wireshark project (www.wireshark.org) reports that + ** without this code, their parser segfaults. I'm not sure what there + ** parser is doing to make this happen. This is the second bug report + ** from wireshark this week. Clearly they are stressing Lemon in ways + ** that it has not been previously stressed... (SQLite ticket #2172) + */ + /*memset(&yygotominor, 0, sizeof(yygotominor));*/ + yygotominor = yyzerominor; + + + switch( yyruleno ){ + /* Beginning here are the reduction cases. A typical example + ** follows: + ** case 0: + ** #line + ** { ... } // User supplied code + ** #line + ** break; + */ +%% + }; + yygoto = yyRuleInfo[yyruleno].lhs; + yysize = yyRuleInfo[yyruleno].nrhs; + yypParser->yyidx -= yysize; + yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto); + if( yyact < YYNSTATE ){ +#ifdef NDEBUG + /* If we are not debugging and the reduce action popped at least + ** one element off the stack, then we can push the new element back + ** onto the stack here, and skip the stack overflow test in yy_shift(). + ** That gives a significant speed improvement. */ + if( yysize ){ + yypParser->yyidx++; + yymsp -= yysize-1; + yymsp->stateno = (YYACTIONTYPE)yyact; + yymsp->major = (YYCODETYPE)yygoto; + yymsp->minor = yygotominor; + }else +#endif + { + yy_shift(yypParser,yyact,yygoto,&yygotominor); + } + }else{ + assert( yyact == YYNSTATE + YYNRULE + 1 ); + yy_accept(yypParser); + } +} + +/* +** The following code executes when the parse fails +*/ +#ifndef YYNOERRORRECOVERY +static void yy_parse_failed( + yyParser *yypParser /* The parser */ +){ + ParseARG_FETCH; +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); + } +#endif + while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); + /* Here code is inserted which will be executed whenever the + ** parser fails */ +%% + ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ +} +#endif /* YYNOERRORRECOVERY */ + +/* +** The following code executes when a syntax error first occurs. +*/ +static void yy_syntax_error( + yyParser *yypParser, /* The parser */ + int yymajor, /* The major type of the error token */ + YYMINORTYPE yyminor /* The minor type of the error token */ +){ + ParseARG_FETCH; +#define TOKEN (yyminor.yy0) +%% + ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ +} + +/* +** The following is executed when the parser accepts +*/ +static void yy_accept( + yyParser *yypParser /* The parser */ +){ + ParseARG_FETCH; +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); + } +#endif + while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); + /* Here code is inserted which will be executed whenever the + ** parser accepts */ +%% + ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ +} + +/* The main parser program. +** The first argument is a pointer to a structure obtained from +** "ParseAlloc" which describes the current state of the parser. +** The second argument is the major token number. The third is +** the minor token. The fourth optional argument is whatever the +** user wants (and specified in the grammar) and is available for +** use by the action routines. +** +** Inputs: +**
    +**
  • A pointer to the parser (an opaque structure.) +**
  • The major token number. +**
  • The minor token number. +**
  • An option argument of a grammar-specified type. +**
+** +** Outputs: +** None. +*/ +void Parse( + void *yyp, /* The parser */ + int yymajor, /* The major token code number */ + ParseTOKENTYPE yyminor /* The value for the token */ + ParseARG_PDECL /* Optional %extra_argument parameter */ +){ + YYMINORTYPE yyminorunion; + int yyact; /* The parser action. */ +#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) + int yyendofinput; /* True if we are at the end of input */ +#endif +#ifdef YYERRORSYMBOL + int yyerrorhit = 0; /* True if yymajor has invoked an error */ +#endif + yyParser *yypParser; /* The parser */ + + /* (re)initialize the parser, if necessary */ + yypParser = (yyParser*)yyp; + if( yypParser->yyidx<0 ){ +#if YYSTACKDEPTH<=0 + if( yypParser->yystksz <=0 ){ + /*memset(&yyminorunion, 0, sizeof(yyminorunion));*/ + yyminorunion = yyzerominor; + yyStackOverflow(yypParser, &yyminorunion); + return; + } +#endif + yypParser->yyidx = 0; + yypParser->yyerrcnt = -1; + yypParser->yystack[0].stateno = 0; + yypParser->yystack[0].major = 0; + } + yyminorunion.yy0 = yyminor; +#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) + yyendofinput = (yymajor==0); +#endif + ParseARG_STORE; + +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]); + } +#endif + + do{ + yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor); + if( yyactyyerrcnt--; + yymajor = YYNOCODE; + }else if( yyact < YYNSTATE + YYNRULE ){ + yy_reduce(yypParser,yyact-YYNSTATE); + }else{ + assert( yyact == YY_ERROR_ACTION ); +#ifdef YYERRORSYMBOL + int yymx; +#endif +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt); + } +#endif +#ifdef YYERRORSYMBOL + /* A syntax error has occurred. + ** The response to an error depends upon whether or not the + ** grammar defines an error token "ERROR". + ** + ** This is what we do if the grammar does define ERROR: + ** + ** * Call the %syntax_error function. + ** + ** * Begin popping the stack until we enter a state where + ** it is legal to shift the error symbol, then shift + ** the error symbol. + ** + ** * Set the error count to three. + ** + ** * Begin accepting and shifting new tokens. No new error + ** processing will occur until three tokens have been + ** shifted successfully. + ** + */ + if( yypParser->yyerrcnt<0 ){ + yy_syntax_error(yypParser,yymajor,yyminorunion); + } + yymx = yypParser->yystack[yypParser->yyidx].major; + if( yymx==YYERRORSYMBOL || yyerrorhit ){ +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sDiscard input token %s\n", + yyTracePrompt,yyTokenName[yymajor]); + } +#endif + yy_destructor(yypParser, (YYCODETYPE)yymajor,&yyminorunion); + yymajor = YYNOCODE; + }else{ + while( + yypParser->yyidx >= 0 && + yymx != YYERRORSYMBOL && + (yyact = yy_find_reduce_action( + yypParser->yystack[yypParser->yyidx].stateno, + YYERRORSYMBOL)) >= YYNSTATE + ){ + yy_pop_parser_stack(yypParser); + } + if( yypParser->yyidx < 0 || yymajor==0 ){ + yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); + yy_parse_failed(yypParser); + yymajor = YYNOCODE; + }else if( yymx!=YYERRORSYMBOL ){ + YYMINORTYPE u2; + u2.YYERRSYMDT = 0; + yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2); + } + } + yypParser->yyerrcnt = 3; + yyerrorhit = 1; +#elif defined(YYNOERRORRECOVERY) + /* If the YYNOERRORRECOVERY macro is defined, then do not attempt to + ** do any kind of error recovery. Instead, simply invoke the syntax + ** error routine and continue going as if nothing had happened. + ** + ** Applications can set this macro (for example inside %include) if + ** they intend to abandon the parse upon the first syntax error seen. + */ + yy_syntax_error(yypParser,yymajor,yyminorunion); + yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); + yymajor = YYNOCODE; + +#else /* YYERRORSYMBOL is not defined */ + /* This is what we do if the grammar does not define ERROR: + ** + ** * Report an error message, and throw away the input token. + ** + ** * If the input token is $, then fail the parse. + ** + ** As before, subsequent error messages are suppressed until + ** three input tokens have been successfully shifted. + */ + if( yypParser->yyerrcnt<=0 ){ + yy_syntax_error(yypParser,yymajor,yyminorunion); + } + yypParser->yyerrcnt = 3; + yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); + if( yyendofinput ){ + yy_parse_failed(yypParser); + } + yymajor = YYNOCODE; +#endif + } + }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 ); + return; +} diff --git a/scalos/libraries/sqlite/src/loadext.c b/scalos/libraries/sqlite/src/loadext.c new file mode 100644 index 000000000..3fcf5008c --- /dev/null +++ b/scalos/libraries/sqlite/src/loadext.c @@ -0,0 +1,658 @@ +/* +** 2006 June 7 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code used to dynamically load extensions into +** the SQLite library. +*/ + +#ifndef SQLITE_CORE + #define SQLITE_CORE 1 /* Disable the API redefinition in sqlite3ext.h */ +#endif +#include "sqlite3ext.h" +#include "sqliteInt.h" +#include + +#ifndef SQLITE_OMIT_LOAD_EXTENSION + +/* +** Some API routines are omitted when various features are +** excluded from a build of SQLite. Substitute a NULL pointer +** for any missing APIs. +*/ +#ifndef SQLITE_ENABLE_COLUMN_METADATA +# define sqlite3_column_database_name 0 +# define sqlite3_column_database_name16 0 +# define sqlite3_column_table_name 0 +# define sqlite3_column_table_name16 0 +# define sqlite3_column_origin_name 0 +# define sqlite3_column_origin_name16 0 +# define sqlite3_table_column_metadata 0 +#endif + +#ifdef SQLITE_OMIT_AUTHORIZATION +# define sqlite3_set_authorizer 0 +#endif + +#ifdef SQLITE_OMIT_UTF16 +# define sqlite3_bind_text16 0 +# define sqlite3_collation_needed16 0 +# define sqlite3_column_decltype16 0 +# define sqlite3_column_name16 0 +# define sqlite3_column_text16 0 +# define sqlite3_complete16 0 +# define sqlite3_create_collation16 0 +# define sqlite3_create_function16 0 +# define sqlite3_errmsg16 0 +# define sqlite3_open16 0 +# define sqlite3_prepare16 0 +# define sqlite3_prepare16_v2 0 +# define sqlite3_result_error16 0 +# define sqlite3_result_text16 0 +# define sqlite3_result_text16be 0 +# define sqlite3_result_text16le 0 +# define sqlite3_value_text16 0 +# define sqlite3_value_text16be 0 +# define sqlite3_value_text16le 0 +# define sqlite3_column_database_name16 0 +# define sqlite3_column_table_name16 0 +# define sqlite3_column_origin_name16 0 +#endif + +#ifdef SQLITE_OMIT_COMPLETE +# define sqlite3_complete 0 +# define sqlite3_complete16 0 +#endif + +#ifdef SQLITE_OMIT_DECLTYPE +# define sqlite3_column_decltype16 0 +# define sqlite3_column_decltype 0 +#endif + +#ifdef SQLITE_OMIT_PROGRESS_CALLBACK +# define sqlite3_progress_handler 0 +#endif + +#ifdef SQLITE_OMIT_VIRTUALTABLE +# define sqlite3_create_module 0 +# define sqlite3_create_module_v2 0 +# define sqlite3_declare_vtab 0 +# define sqlite3_vtab_config 0 +# define sqlite3_vtab_on_conflict 0 +#endif + +#ifdef SQLITE_OMIT_SHARED_CACHE +# define sqlite3_enable_shared_cache 0 +#endif + +#ifdef SQLITE_OMIT_TRACE +# define sqlite3_profile 0 +# define sqlite3_trace 0 +#endif + +#ifdef SQLITE_OMIT_GET_TABLE +# define sqlite3_free_table 0 +# define sqlite3_get_table 0 +#endif + +#ifdef SQLITE_OMIT_INCRBLOB +#define sqlite3_bind_zeroblob 0 +#define sqlite3_blob_bytes 0 +#define sqlite3_blob_close 0 +#define sqlite3_blob_open 0 +#define sqlite3_blob_read 0 +#define sqlite3_blob_write 0 +#define sqlite3_blob_reopen 0 +#endif + +/* +** The following structure contains pointers to all SQLite API routines. +** A pointer to this structure is passed into extensions when they are +** loaded so that the extension can make calls back into the SQLite +** library. +** +** When adding new APIs, add them to the bottom of this structure +** in order to preserve backwards compatibility. +** +** Extensions that use newer APIs should first call the +** sqlite3_libversion_number() to make sure that the API they +** intend to use is supported by the library. Extensions should +** also check to make sure that the pointer to the function is +** not NULL before calling it. +*/ +static const sqlite3_api_routines sqlite3Apis = { + sqlite3_aggregate_context, +#ifndef SQLITE_OMIT_DEPRECATED + sqlite3_aggregate_count, +#else + 0, +#endif + sqlite3_bind_blob, + sqlite3_bind_double, + sqlite3_bind_int, + sqlite3_bind_int64, + sqlite3_bind_null, + sqlite3_bind_parameter_count, + sqlite3_bind_parameter_index, + sqlite3_bind_parameter_name, + sqlite3_bind_text, + sqlite3_bind_text16, + sqlite3_bind_value, + sqlite3_busy_handler, + sqlite3_busy_timeout, + sqlite3_changes, + sqlite3_close, + sqlite3_collation_needed, + sqlite3_collation_needed16, + sqlite3_column_blob, + sqlite3_column_bytes, + sqlite3_column_bytes16, + sqlite3_column_count, + sqlite3_column_database_name, + sqlite3_column_database_name16, + sqlite3_column_decltype, + sqlite3_column_decltype16, + sqlite3_column_double, + sqlite3_column_int, + sqlite3_column_int64, + sqlite3_column_name, + sqlite3_column_name16, + sqlite3_column_origin_name, + sqlite3_column_origin_name16, + sqlite3_column_table_name, + sqlite3_column_table_name16, + sqlite3_column_text, + sqlite3_column_text16, + sqlite3_column_type, + sqlite3_column_value, + sqlite3_commit_hook, + sqlite3_complete, + sqlite3_complete16, + sqlite3_create_collation, + sqlite3_create_collation16, + sqlite3_create_function, + sqlite3_create_function16, + sqlite3_create_module, + sqlite3_data_count, + sqlite3_db_handle, + sqlite3_declare_vtab, + sqlite3_enable_shared_cache, + sqlite3_errcode, + sqlite3_errmsg, + sqlite3_errmsg16, + sqlite3_exec, +#ifndef SQLITE_OMIT_DEPRECATED + sqlite3_expired, +#else + 0, +#endif + sqlite3_finalize, + sqlite3_free, + sqlite3_free_table, + sqlite3_get_autocommit, + sqlite3_get_auxdata, + sqlite3_get_table, + 0, /* Was sqlite3_global_recover(), but that function is deprecated */ + sqlite3_interrupt, + sqlite3_last_insert_rowid, + sqlite3_libversion, + sqlite3_libversion_number, + sqlite3_malloc, + sqlite3_mprintf, + sqlite3_open, + sqlite3_open16, + sqlite3_prepare, + sqlite3_prepare16, + sqlite3_profile, + sqlite3_progress_handler, + sqlite3_realloc, + sqlite3_reset, + sqlite3_result_blob, + sqlite3_result_double, + sqlite3_result_error, + sqlite3_result_error16, + sqlite3_result_int, + sqlite3_result_int64, + sqlite3_result_null, + sqlite3_result_text, + sqlite3_result_text16, + sqlite3_result_text16be, + sqlite3_result_text16le, + sqlite3_result_value, + sqlite3_rollback_hook, + sqlite3_set_authorizer, + sqlite3_set_auxdata, + sqlite3_snprintf, + sqlite3_step, + sqlite3_table_column_metadata, +#ifndef SQLITE_OMIT_DEPRECATED + sqlite3_thread_cleanup, +#else + 0, +#endif + sqlite3_total_changes, + sqlite3_trace, +#ifndef SQLITE_OMIT_DEPRECATED + sqlite3_transfer_bindings, +#else + 0, +#endif + sqlite3_update_hook, + sqlite3_user_data, + sqlite3_value_blob, + sqlite3_value_bytes, + sqlite3_value_bytes16, + sqlite3_value_double, + sqlite3_value_int, + sqlite3_value_int64, + sqlite3_value_numeric_type, + sqlite3_value_text, + sqlite3_value_text16, + sqlite3_value_text16be, + sqlite3_value_text16le, + sqlite3_value_type, + sqlite3_vmprintf, + /* + ** The original API set ends here. All extensions can call any + ** of the APIs above provided that the pointer is not NULL. But + ** before calling APIs that follow, extension should check the + ** sqlite3_libversion_number() to make sure they are dealing with + ** a library that is new enough to support that API. + ************************************************************************* + */ + sqlite3_overload_function, + + /* + ** Added after 3.3.13 + */ + sqlite3_prepare_v2, + sqlite3_prepare16_v2, + sqlite3_clear_bindings, + + /* + ** Added for 3.4.1 + */ + sqlite3_create_module_v2, + + /* + ** Added for 3.5.0 + */ + sqlite3_bind_zeroblob, + sqlite3_blob_bytes, + sqlite3_blob_close, + sqlite3_blob_open, + sqlite3_blob_read, + sqlite3_blob_write, + sqlite3_create_collation_v2, + sqlite3_file_control, + sqlite3_memory_highwater, + sqlite3_memory_used, +#ifdef SQLITE_MUTEX_OMIT + 0, + 0, + 0, + 0, + 0, +#else + sqlite3_mutex_alloc, + sqlite3_mutex_enter, + sqlite3_mutex_free, + sqlite3_mutex_leave, + sqlite3_mutex_try, +#endif + sqlite3_open_v2, + sqlite3_release_memory, + sqlite3_result_error_nomem, + sqlite3_result_error_toobig, + sqlite3_sleep, + sqlite3_soft_heap_limit, + sqlite3_vfs_find, + sqlite3_vfs_register, + sqlite3_vfs_unregister, + + /* + ** Added for 3.5.8 + */ + sqlite3_threadsafe, + sqlite3_result_zeroblob, + sqlite3_result_error_code, + sqlite3_test_control, + sqlite3_randomness, + sqlite3_context_db_handle, + + /* + ** Added for 3.6.0 + */ + sqlite3_extended_result_codes, + sqlite3_limit, + sqlite3_next_stmt, + sqlite3_sql, + sqlite3_status, + + /* + ** Added for 3.7.4 + */ + sqlite3_backup_finish, + sqlite3_backup_init, + sqlite3_backup_pagecount, + sqlite3_backup_remaining, + sqlite3_backup_step, +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS + sqlite3_compileoption_get, + sqlite3_compileoption_used, +#else + 0, + 0, +#endif + sqlite3_create_function_v2, + sqlite3_db_config, + sqlite3_db_mutex, + sqlite3_db_status, + sqlite3_extended_errcode, + sqlite3_log, + sqlite3_soft_heap_limit64, + sqlite3_sourceid, + sqlite3_stmt_status, + sqlite3_strnicmp, +#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY + sqlite3_unlock_notify, +#else + 0, +#endif +#ifndef SQLITE_OMIT_WAL + sqlite3_wal_autocheckpoint, + sqlite3_wal_checkpoint, + sqlite3_wal_hook, +#else + 0, + 0, + 0, +#endif + sqlite3_blob_reopen, + sqlite3_vtab_config, + sqlite3_vtab_on_conflict, +}; + +/* +** Attempt to load an SQLite extension library contained in the file +** zFile. The entry point is zProc. zProc may be 0 in which case a +** default entry point name (sqlite3_extension_init) is used. Use +** of the default name is recommended. +** +** Return SQLITE_OK on success and SQLITE_ERROR if something goes wrong. +** +** If an error occurs and pzErrMsg is not 0, then fill *pzErrMsg with +** error message text. The calling function should free this memory +** by calling sqlite3DbFree(db, ). +*/ +static int sqlite3LoadExtension( + sqlite3 *db, /* Load the extension into this database connection */ + const char *zFile, /* Name of the shared library containing extension */ + const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */ + char **pzErrMsg /* Put error message here if not 0 */ +){ + sqlite3_vfs *pVfs = db->pVfs; + void *handle; + int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*); + char *zErrmsg = 0; + void **aHandle; + int nMsg = 300 + sqlite3Strlen30(zFile); + + if( pzErrMsg ) *pzErrMsg = 0; + + /* Ticket #1863. To avoid a creating security problems for older + ** applications that relink against newer versions of SQLite, the + ** ability to run load_extension is turned off by default. One + ** must call sqlite3_enable_load_extension() to turn on extension + ** loading. Otherwise you get the following error. + */ + if( (db->flags & SQLITE_LoadExtension)==0 ){ + if( pzErrMsg ){ + *pzErrMsg = sqlite3_mprintf("not authorized"); + } + return SQLITE_ERROR; + } + + if( zProc==0 ){ + zProc = "sqlite3_extension_init"; + } + + handle = sqlite3OsDlOpen(pVfs, zFile); + if( handle==0 ){ + if( pzErrMsg ){ + *pzErrMsg = zErrmsg = sqlite3_malloc(nMsg); + if( zErrmsg ){ + sqlite3_snprintf(nMsg, zErrmsg, + "unable to open shared library [%s]", zFile); + sqlite3OsDlError(pVfs, nMsg-1, zErrmsg); + } + } + return SQLITE_ERROR; + } + xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*)) + sqlite3OsDlSym(pVfs, handle, zProc); + if( xInit==0 ){ + if( pzErrMsg ){ + nMsg += sqlite3Strlen30(zProc); + *pzErrMsg = zErrmsg = sqlite3_malloc(nMsg); + if( zErrmsg ){ + sqlite3_snprintf(nMsg, zErrmsg, + "no entry point [%s] in shared library [%s]", zProc,zFile); + sqlite3OsDlError(pVfs, nMsg-1, zErrmsg); + } + sqlite3OsDlClose(pVfs, handle); + } + return SQLITE_ERROR; + }else if( xInit(db, &zErrmsg, &sqlite3Apis) ){ + if( pzErrMsg ){ + *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg); + } + sqlite3_free(zErrmsg); + sqlite3OsDlClose(pVfs, handle); + return SQLITE_ERROR; + } + + /* Append the new shared library handle to the db->aExtension array. */ + aHandle = sqlite3DbMallocZero(db, sizeof(handle)*(db->nExtension+1)); + if( aHandle==0 ){ + return SQLITE_NOMEM; + } + if( db->nExtension>0 ){ + memcpy(aHandle, db->aExtension, sizeof(handle)*db->nExtension); + } + sqlite3DbFree(db, db->aExtension); + db->aExtension = aHandle; + + db->aExtension[db->nExtension++] = handle; + return SQLITE_OK; +} +int sqlite3_load_extension( + sqlite3 *db, /* Load the extension into this database connection */ + const char *zFile, /* Name of the shared library containing extension */ + const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */ + char **pzErrMsg /* Put error message here if not 0 */ +){ + int rc; + sqlite3_mutex_enter(db->mutex); + rc = sqlite3LoadExtension(db, zFile, zProc, pzErrMsg); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** Call this routine when the database connection is closing in order +** to clean up loaded extensions +*/ +void sqlite3CloseExtensions(sqlite3 *db){ + int i; + assert( sqlite3_mutex_held(db->mutex) ); + for(i=0; inExtension; i++){ + sqlite3OsDlClose(db->pVfs, db->aExtension[i]); + } + sqlite3DbFree(db, db->aExtension); +} + +/* +** Enable or disable extension loading. Extension loading is disabled by +** default so as not to open security holes in older applications. +*/ +int sqlite3_enable_load_extension(sqlite3 *db, int onoff){ + sqlite3_mutex_enter(db->mutex); + if( onoff ){ + db->flags |= SQLITE_LoadExtension; + }else{ + db->flags &= ~SQLITE_LoadExtension; + } + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + +#endif /* SQLITE_OMIT_LOAD_EXTENSION */ + +/* +** The auto-extension code added regardless of whether or not extension +** loading is supported. We need a dummy sqlite3Apis pointer for that +** code if regular extension loading is not available. This is that +** dummy pointer. +*/ +#ifdef SQLITE_OMIT_LOAD_EXTENSION +static const sqlite3_api_routines sqlite3Apis = { 0 }; +#endif + + +/* +** The following object holds the list of automatically loaded +** extensions. +** +** This list is shared across threads. The SQLITE_MUTEX_STATIC_MASTER +** mutex must be held while accessing this list. +*/ +typedef struct sqlite3AutoExtList sqlite3AutoExtList; +static SQLITE_WSD struct sqlite3AutoExtList { + int nExt; /* Number of entries in aExt[] */ + void (**aExt)(void); /* Pointers to the extension init functions */ +} sqlite3Autoext = { 0, 0 }; + +/* The "wsdAutoext" macro will resolve to the autoextension +** state vector. If writable static data is unsupported on the target, +** we have to locate the state vector at run-time. In the more common +** case where writable static data is supported, wsdStat can refer directly +** to the "sqlite3Autoext" state vector declared above. +*/ +#ifdef SQLITE_OMIT_WSD +# define wsdAutoextInit \ + sqlite3AutoExtList *x = &GLOBAL(sqlite3AutoExtList,sqlite3Autoext) +# define wsdAutoext x[0] +#else +# define wsdAutoextInit +# define wsdAutoext sqlite3Autoext +#endif + + +/* +** Register a statically linked extension that is automatically +** loaded by every new database connection. +*/ +int sqlite3_auto_extension(void (*xInit)(void)){ + int rc = SQLITE_OK; +#ifndef SQLITE_OMIT_AUTOINIT + rc = sqlite3_initialize(); + if( rc ){ + return rc; + }else +#endif + { + int i; +#if SQLITE_THREADSAFE + sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); +#endif + wsdAutoextInit; + sqlite3_mutex_enter(mutex); + for(i=0; i=wsdAutoext.nExt ){ + xInit = 0; + go = 0; + }else{ + xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*)) + wsdAutoext.aExt[i]; + } + sqlite3_mutex_leave(mutex); + zErrmsg = 0; + if( xInit && (rc = xInit(db, &zErrmsg, &sqlite3Apis))!=0 ){ + sqlite3Error(db, rc, + "automatic extension loading failed: %s", zErrmsg); + go = 0; + } + sqlite3_free(zErrmsg); + } +} diff --git a/scalos/libraries/sqlite/src/main.c b/scalos/libraries/sqlite/src/main.c new file mode 100644 index 000000000..fcbfcdeb5 --- /dev/null +++ b/scalos/libraries/sqlite/src/main.c @@ -0,0 +1,3070 @@ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** Main file for the SQLite library. The routines in this file +** implement the programmer interface to the library. Routines in +** other files are for internal use by SQLite and should not be +** accessed by users of the library. +*/ +#include "sqliteInt.h" + +#ifdef SQLITE_ENABLE_FTS3 +# include "fts3.h" +#endif +#ifdef SQLITE_ENABLE_RTREE +# include "rtree.h" +#endif +#ifdef SQLITE_ENABLE_ICU +# include "sqliteicu.h" +#endif + +#ifndef SQLITE_AMALGAMATION +/* IMPLEMENTATION-OF: R-46656-45156 The sqlite3_version[] string constant +** contains the text of SQLITE_VERSION macro. +*/ +const char sqlite3_version[] = SQLITE_VERSION; +#endif + +/* IMPLEMENTATION-OF: R-53536-42575 The sqlite3_libversion() function returns +** a pointer to the to the sqlite3_version[] string constant. +*/ +const char *sqlite3_libversion(void){ return sqlite3_version; } + +/* IMPLEMENTATION-OF: R-63124-39300 The sqlite3_sourceid() function returns a +** pointer to a string constant whose value is the same as the +** SQLITE_SOURCE_ID C preprocessor macro. +*/ +const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } + +/* IMPLEMENTATION-OF: R-35210-63508 The sqlite3_libversion_number() function +** returns an integer equal to SQLITE_VERSION_NUMBER. +*/ +int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; } + +/* IMPLEMENTATION-OF: R-20790-14025 The sqlite3_threadsafe() function returns +** zero if and only if SQLite was compiled with mutexing code omitted due to +** the SQLITE_THREADSAFE compile-time option being set to 0. +*/ +int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; } + +#if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE) +/* +** If the following function pointer is not NULL and if +** SQLITE_ENABLE_IOTRACE is enabled, then messages describing +** I/O active are written using this function. These messages +** are intended for debugging activity only. +*/ +void (*sqlite3IoTrace)(const char*, ...) = 0; +#endif + +/* +** If the following global variable points to a string which is the +** name of a directory, then that directory will be used to store +** temporary files. +** +** See also the "PRAGMA temp_store_directory" SQL command. +*/ +char *sqlite3_temp_directory = 0; + +/* +** Initialize SQLite. +** +** This routine must be called to initialize the memory allocation, +** VFS, and mutex subsystems prior to doing any serious work with +** SQLite. But as long as you do not compile with SQLITE_OMIT_AUTOINIT +** this routine will be called automatically by key routines such as +** sqlite3_open(). +** +** This routine is a no-op except on its very first call for the process, +** or for the first call after a call to sqlite3_shutdown. +** +** The first thread to call this routine runs the initialization to +** completion. If subsequent threads call this routine before the first +** thread has finished the initialization process, then the subsequent +** threads must block until the first thread finishes with the initialization. +** +** The first thread might call this routine recursively. Recursive +** calls to this routine should not block, of course. Otherwise the +** initialization process would never complete. +** +** Let X be the first thread to enter this routine. Let Y be some other +** thread. Then while the initial invocation of this routine by X is +** incomplete, it is required that: +** +** * Calls to this routine from Y must block until the outer-most +** call by X completes. +** +** * Recursive calls to this routine from thread X return immediately +** without blocking. +*/ +int sqlite3_initialize(void){ + MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */ + int rc; /* Result code */ + +#ifdef SQLITE_OMIT_WSD + rc = sqlite3_wsd_init(4096, 24); + if( rc!=SQLITE_OK ){ + return rc; + } +#endif + + /* If SQLite is already completely initialized, then this call + ** to sqlite3_initialize() should be a no-op. But the initialization + ** must be complete. So isInit must not be set until the very end + ** of this routine. + */ + if( sqlite3GlobalConfig.isInit ) return SQLITE_OK; + + /* Make sure the mutex subsystem is initialized. If unable to + ** initialize the mutex subsystem, return early with the error. + ** If the system is so sick that we are unable to allocate a mutex, + ** there is not much SQLite is going to be able to do. + ** + ** The mutex subsystem must take care of serializing its own + ** initialization. + */ + rc = sqlite3MutexInit(); + if( rc ) return rc; + + /* Initialize the malloc() system and the recursive pInitMutex mutex. + ** This operation is protected by the STATIC_MASTER mutex. Note that + ** MutexAlloc() is called for a static mutex prior to initializing the + ** malloc subsystem - this implies that the allocation of a static + ** mutex must not require support from the malloc subsystem. + */ + MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) + sqlite3_mutex_enter(pMaster); + sqlite3GlobalConfig.isMutexInit = 1; + if( !sqlite3GlobalConfig.isMallocInit ){ + rc = sqlite3MallocInit(); + } + if( rc==SQLITE_OK ){ + sqlite3GlobalConfig.isMallocInit = 1; + if( !sqlite3GlobalConfig.pInitMutex ){ + sqlite3GlobalConfig.pInitMutex = + sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); + if( sqlite3GlobalConfig.bCoreMutex && !sqlite3GlobalConfig.pInitMutex ){ + rc = SQLITE_NOMEM; + } + } + } + if( rc==SQLITE_OK ){ + sqlite3GlobalConfig.nRefInitMutex++; + } + sqlite3_mutex_leave(pMaster); + + /* If rc is not SQLITE_OK at this point, then either the malloc + ** subsystem could not be initialized or the system failed to allocate + ** the pInitMutex mutex. Return an error in either case. */ + if( rc!=SQLITE_OK ){ + return rc; + } + + /* Do the rest of the initialization under the recursive mutex so + ** that we will be able to handle recursive calls into + ** sqlite3_initialize(). The recursive calls normally come through + ** sqlite3_os_init() when it invokes sqlite3_vfs_register(), but other + ** recursive calls might also be possible. + ** + ** IMPLEMENTATION-OF: R-00140-37445 SQLite automatically serializes calls + ** to the xInit method, so the xInit method need not be threadsafe. + ** + ** The following mutex is what serializes access to the appdef pcache xInit + ** methods. The sqlite3_pcache_methods.xInit() all is embedded in the + ** call to sqlite3PcacheInitialize(). + */ + sqlite3_mutex_enter(sqlite3GlobalConfig.pInitMutex); + if( sqlite3GlobalConfig.isInit==0 && sqlite3GlobalConfig.inProgress==0 ){ + FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions); + sqlite3GlobalConfig.inProgress = 1; + memset(pHash, 0, sizeof(sqlite3GlobalFunctions)); + sqlite3RegisterGlobalFunctions(); + if( sqlite3GlobalConfig.isPCacheInit==0 ){ + rc = sqlite3PcacheInitialize(); + } + if( rc==SQLITE_OK ){ + sqlite3GlobalConfig.isPCacheInit = 1; + rc = sqlite3OsInit(); + } + if( rc==SQLITE_OK ){ + sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage, + sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage); + sqlite3GlobalConfig.isInit = 1; + } + sqlite3GlobalConfig.inProgress = 0; + } + sqlite3_mutex_leave(sqlite3GlobalConfig.pInitMutex); + + /* Go back under the static mutex and clean up the recursive + ** mutex to prevent a resource leak. + */ + sqlite3_mutex_enter(pMaster); + sqlite3GlobalConfig.nRefInitMutex--; + if( sqlite3GlobalConfig.nRefInitMutex<=0 ){ + assert( sqlite3GlobalConfig.nRefInitMutex==0 ); + sqlite3_mutex_free(sqlite3GlobalConfig.pInitMutex); + sqlite3GlobalConfig.pInitMutex = 0; + } + sqlite3_mutex_leave(pMaster); + + /* The following is just a sanity check to make sure SQLite has + ** been compiled correctly. It is important to run this code, but + ** we don't want to run it too often and soak up CPU cycles for no + ** reason. So we run it once during initialization. + */ +#ifndef NDEBUG +#ifndef SQLITE_OMIT_FLOATING_POINT + /* This section of code's only "output" is via assert() statements. */ + if ( rc==SQLITE_OK ){ + u64 x = (((u64)1)<<63)-1; + double y; + assert(sizeof(x)==8); + assert(sizeof(x)==sizeof(y)); + memcpy(&y, &x, 8); + assert( sqlite3IsNaN(y) ); + } +#endif +#endif + + /* Do extra initialization steps requested by the SQLITE_EXTRA_INIT + ** compile-time option. + */ +#ifdef SQLITE_EXTRA_INIT + if( rc==SQLITE_OK && sqlite3GlobalConfig.isInit ){ + int SQLITE_EXTRA_INIT(const char*); + rc = SQLITE_EXTRA_INIT(0); + } +#endif + + return rc; +} + +/* +** Undo the effects of sqlite3_initialize(). Must not be called while +** there are outstanding database connections or memory allocations or +** while any part of SQLite is otherwise in use in any thread. This +** routine is not threadsafe. But it is safe to invoke this routine +** on when SQLite is already shut down. If SQLite is already shut down +** when this routine is invoked, then this routine is a harmless no-op. +*/ +int sqlite3_shutdown(void){ + if( sqlite3GlobalConfig.isInit ){ +#ifdef SQLITE_EXTRA_SHUTDOWN + void SQLITE_EXTRA_SHUTDOWN(void); + SQLITE_EXTRA_SHUTDOWN(); +#endif + sqlite3_os_end(); + sqlite3_reset_auto_extension(); + sqlite3GlobalConfig.isInit = 0; + } + if( sqlite3GlobalConfig.isPCacheInit ){ + sqlite3PcacheShutdown(); + sqlite3GlobalConfig.isPCacheInit = 0; + } + if( sqlite3GlobalConfig.isMallocInit ){ + sqlite3MallocEnd(); + sqlite3GlobalConfig.isMallocInit = 0; + } + if( sqlite3GlobalConfig.isMutexInit ){ + sqlite3MutexEnd(); + sqlite3GlobalConfig.isMutexInit = 0; + } + + return SQLITE_OK; +} + +/* +** This API allows applications to modify the global configuration of +** the SQLite library at run-time. +** +** This routine should only be called when there are no outstanding +** database connections or memory allocations. This routine is not +** threadsafe. Failure to heed these warnings can lead to unpredictable +** behavior. +*/ +#ifdef AMIGA +int sqlite3_config(int op, ...){ + va_list ap; + int rc; + + va_start(ap, op); + rc = sqlite3_configv(op, ap); + va_end(ap); + return rc; +} + +int sqlite3_configv(int op, va_list ap){ + int rc = SQLITE_OK; + + /* sqlite3_config() shall return SQLITE_MISUSE if it is invoked while + ** the SQLite library is in use. */ + if( sqlite3GlobalConfig.isInit ) return SQLITE_MISUSE_BKPT; + +#else /* AMIGA */ +int sqlite3_config(int op, ...){ + va_list ap; + int rc = SQLITE_OK; + + /* sqlite3_config() shall return SQLITE_MISUSE if it is invoked while + ** the SQLite library is in use. */ + if( sqlite3GlobalConfig.isInit ) return SQLITE_MISUSE_BKPT; + + va_start(ap, op); +#endif /* AMIGA */ + switch( op ){ + + /* Mutex configuration options are only available in a threadsafe + ** compile. + */ +#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 + case SQLITE_CONFIG_SINGLETHREAD: { + /* Disable all mutexing */ + sqlite3GlobalConfig.bCoreMutex = 0; + sqlite3GlobalConfig.bFullMutex = 0; + break; + } + case SQLITE_CONFIG_MULTITHREAD: { + /* Disable mutexing of database connections */ + /* Enable mutexing of core data structures */ + sqlite3GlobalConfig.bCoreMutex = 1; + sqlite3GlobalConfig.bFullMutex = 0; + break; + } + case SQLITE_CONFIG_SERIALIZED: { + /* Enable all mutexing */ + sqlite3GlobalConfig.bCoreMutex = 1; + sqlite3GlobalConfig.bFullMutex = 1; + break; + } + case SQLITE_CONFIG_MUTEX: { + /* Specify an alternative mutex implementation */ + sqlite3GlobalConfig.mutex = *va_arg(ap, sqlite3_mutex_methods*); + break; + } + case SQLITE_CONFIG_GETMUTEX: { + /* Retrieve the current mutex implementation */ + *va_arg(ap, sqlite3_mutex_methods*) = sqlite3GlobalConfig.mutex; + break; + } +#endif + + + case SQLITE_CONFIG_MALLOC: { + /* Specify an alternative malloc implementation */ + sqlite3GlobalConfig.m = *va_arg(ap, sqlite3_mem_methods*); + break; + } + case SQLITE_CONFIG_GETMALLOC: { + /* Retrieve the current malloc() implementation */ + if( sqlite3GlobalConfig.m.xMalloc==0 ) sqlite3MemSetDefault(); + *va_arg(ap, sqlite3_mem_methods*) = sqlite3GlobalConfig.m; + break; + } + case SQLITE_CONFIG_MEMSTATUS: { + /* Enable or disable the malloc status collection */ + sqlite3GlobalConfig.bMemstat = va_arg(ap, int); + break; + } + case SQLITE_CONFIG_SCRATCH: { + /* Designate a buffer for scratch memory space */ + sqlite3GlobalConfig.pScratch = va_arg(ap, void*); + sqlite3GlobalConfig.szScratch = va_arg(ap, int); + sqlite3GlobalConfig.nScratch = va_arg(ap, int); + break; + } + case SQLITE_CONFIG_PAGECACHE: { + /* Designate a buffer for page cache memory space */ + sqlite3GlobalConfig.pPage = va_arg(ap, void*); + sqlite3GlobalConfig.szPage = va_arg(ap, int); + sqlite3GlobalConfig.nPage = va_arg(ap, int); + break; + } + + case SQLITE_CONFIG_PCACHE: { + /* no-op */ + break; + } + case SQLITE_CONFIG_GETPCACHE: { + /* now an error */ + rc = SQLITE_ERROR; + break; + } + + case SQLITE_CONFIG_PCACHE2: { + /* Specify an alternative page cache implementation */ + sqlite3GlobalConfig.pcache2 = *va_arg(ap, sqlite3_pcache_methods2*); + break; + } + case SQLITE_CONFIG_GETPCACHE2: { + if( sqlite3GlobalConfig.pcache2.xInit==0 ){ + sqlite3PCacheSetDefault(); + } + *va_arg(ap, sqlite3_pcache_methods2*) = sqlite3GlobalConfig.pcache2; + break; + } + +#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) + case SQLITE_CONFIG_HEAP: { + /* Designate a buffer for heap memory space */ + sqlite3GlobalConfig.pHeap = va_arg(ap, void*); + sqlite3GlobalConfig.nHeap = va_arg(ap, int); + sqlite3GlobalConfig.mnReq = va_arg(ap, int); + + if( sqlite3GlobalConfig.mnReq<1 ){ + sqlite3GlobalConfig.mnReq = 1; + }else if( sqlite3GlobalConfig.mnReq>(1<<12) ){ + /* cap min request size at 2^12 */ + sqlite3GlobalConfig.mnReq = (1<<12); + } + + if( sqlite3GlobalConfig.pHeap==0 ){ + /* If the heap pointer is NULL, then restore the malloc implementation + ** back to NULL pointers too. This will cause the malloc to go + ** back to its default implementation when sqlite3_initialize() is + ** run. + */ + memset(&sqlite3GlobalConfig.m, 0, sizeof(sqlite3GlobalConfig.m)); + }else{ + /* The heap pointer is not NULL, then install one of the + ** mem5.c/mem3.c methods. If neither ENABLE_MEMSYS3 nor + ** ENABLE_MEMSYS5 is defined, return an error. + */ +#ifdef SQLITE_ENABLE_MEMSYS3 + sqlite3GlobalConfig.m = *sqlite3MemGetMemsys3(); +#endif +#ifdef SQLITE_ENABLE_MEMSYS5 + sqlite3GlobalConfig.m = *sqlite3MemGetMemsys5(); +#endif + } + break; + } +#endif + + case SQLITE_CONFIG_LOOKASIDE: { + sqlite3GlobalConfig.szLookaside = va_arg(ap, int); + sqlite3GlobalConfig.nLookaside = va_arg(ap, int); + break; + } + + /* Record a pointer to the logger funcction and its first argument. + ** The default is NULL. Logging is disabled if the function pointer is + ** NULL. + */ + case SQLITE_CONFIG_LOG: { + /* MSVC is picky about pulling func ptrs from va lists. + ** http://support.microsoft.com/kb/47961 + ** sqlite3GlobalConfig.xLog = va_arg(ap, void(*)(void*,int,const char*)); + */ + typedef void(*LOGFUNC_t)(void*,int,const char*); + sqlite3GlobalConfig.xLog = va_arg(ap, LOGFUNC_t); + sqlite3GlobalConfig.pLogArg = va_arg(ap, void*); + break; + } + + case SQLITE_CONFIG_URI: { + sqlite3GlobalConfig.bOpenUri = va_arg(ap, int); + break; + } + + default: { + rc = SQLITE_ERROR; + break; + } + } +#ifndef AMIGA + va_end(ap); +#endif /* AMIGA */ + return rc; +} + +/* +** Set up the lookaside buffers for a database connection. +** Return SQLITE_OK on success. +** If lookaside is already active, return SQLITE_BUSY. +** +** The sz parameter is the number of bytes in each lookaside slot. +** The cnt parameter is the number of slots. If pStart is NULL the +** space for the lookaside memory is obtained from sqlite3_malloc(). +** If pStart is not NULL then it is sz*cnt bytes of memory to use for +** the lookaside memory. +*/ +static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ + void *pStart; + if( db->lookaside.nOut ){ + return SQLITE_BUSY; + } + /* Free any existing lookaside buffer for this handle before + ** allocating a new one so we don't have to have space for + ** both at the same time. + */ + if( db->lookaside.bMalloced ){ + sqlite3_free(db->lookaside.pStart); + } + /* The size of a lookaside slot after ROUNDDOWN8 needs to be larger + ** than a pointer to be useful. + */ + sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */ + if( sz<=(int)sizeof(LookasideSlot*) ) sz = 0; + if( cnt<0 ) cnt = 0; + if( sz==0 || cnt==0 ){ + sz = 0; + pStart = 0; + }else if( pBuf==0 ){ + sqlite3BeginBenignMalloc(); + pStart = sqlite3Malloc( sz*cnt ); /* IMP: R-61949-35727 */ + sqlite3EndBenignMalloc(); + if( pStart ) cnt = sqlite3MallocSize(pStart)/sz; + }else{ + pStart = pBuf; + } + db->lookaside.pStart = pStart; + db->lookaside.pFree = 0; + db->lookaside.sz = (u16)sz; + if( pStart ){ + int i; + LookasideSlot *p; + assert( sz > (int)sizeof(LookasideSlot*) ); + p = (LookasideSlot*)pStart; + for(i=cnt-1; i>=0; i--){ + p->pNext = db->lookaside.pFree; + db->lookaside.pFree = p; + p = (LookasideSlot*)&((u8*)p)[sz]; + } + db->lookaside.pEnd = p; + db->lookaside.bEnabled = 1; + db->lookaside.bMalloced = pBuf==0 ?1:0; + }else{ + db->lookaside.pEnd = 0; + db->lookaside.bEnabled = 0; + db->lookaside.bMalloced = 0; + } + return SQLITE_OK; +} + +/* +** Return the mutex associated with a database connection. +*/ +sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){ + return db->mutex; +} + +/* +** Free up as much memory as we can from the given database +** connection. +*/ +int sqlite3_db_release_memory(sqlite3 *db){ + int i; + sqlite3_mutex_enter(db->mutex); + sqlite3BtreeEnterAll(db); + for(i=0; inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + Pager *pPager = sqlite3BtreePager(pBt); + sqlite3PagerShrink(pPager); + } + } + sqlite3BtreeLeaveAll(db); + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + +/* +** Configuration settings for an individual database connection +*/ +#ifdef AMIGA +int sqlite3_db_config(sqlite3 *db, int op, ...) +{ + va_list ap; + int rc; + + va_start(ap, op); + rc = sqlite3_db_configv(db, op, ap); + va_end(ap); + + return rc; +} + +int sqlite3_db_configv(sqlite3 *db, int op, va_list ap){ + int rc; +#else /* AMIGA */ +int sqlite3_db_config(sqlite3 *db, int op, ...){ + va_list ap; + int rc; + va_start(ap, op); +#endif /* AMIGA */ + switch( op ){ + case SQLITE_DBCONFIG_LOOKASIDE: { + void *pBuf = va_arg(ap, void*); /* IMP: R-26835-10964 */ + int sz = va_arg(ap, int); /* IMP: R-47871-25994 */ + int cnt = va_arg(ap, int); /* IMP: R-04460-53386 */ + rc = setupLookaside(db, pBuf, sz, cnt); + break; + } + default: { + static const struct { + int op; /* The opcode */ + u32 mask; /* Mask of the bit in sqlite3.flags to set/clear */ + } aFlagOp[] = { + { SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys }, + { SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger }, + }; + unsigned int i; + rc = SQLITE_ERROR; /* IMP: R-42790-23372 */ + for(i=0; iflags; + if( onoff>0 ){ + db->flags |= aFlagOp[i].mask; + }else if( onoff==0 ){ + db->flags &= ~aFlagOp[i].mask; + } + if( oldFlags!=db->flags ){ + sqlite3ExpirePreparedStatements(db); + } + if( pRes ){ + *pRes = (db->flags & aFlagOp[i].mask)!=0; + } + rc = SQLITE_OK; + break; + } + } + break; + } + } +#ifndef AMIGA + va_end(ap); +#endif /* AMIGA */ + return rc; +} + + +/* +** Return true if the buffer z[0..n-1] contains all spaces. +*/ +static int allSpaces(const char *z, int n){ + while( n>0 && z[n-1]==' ' ){ n--; } + return n==0; +} + +/* +** This is the default collating function named "BINARY" which is always +** available. +** +** If the padFlag argument is not NULL then space padding at the end +** of strings is ignored. This implements the RTRIM collation. +*/ +static int binCollFunc( + void *padFlag, + int nKey1, const void *pKey1, + int nKey2, const void *pKey2 +){ + int rc, n; + n = nKey1lastRowid; +} + +/* +** Return the number of changes in the most recent call to sqlite3_exec(). +*/ +int sqlite3_changes(sqlite3 *db){ + return db->nChange; +} + +/* +** Return the number of changes since the database handle was opened. +*/ +int sqlite3_total_changes(sqlite3 *db){ + return db->nTotalChange; +} + +/* +** Close all open savepoints. This function only manipulates fields of the +** database handle object, it does not close any savepoints that may be open +** at the b-tree/pager level. +*/ +void sqlite3CloseSavepoints(sqlite3 *db){ + while( db->pSavepoint ){ + Savepoint *pTmp = db->pSavepoint; + db->pSavepoint = pTmp->pNext; + sqlite3DbFree(db, pTmp); + } + db->nSavepoint = 0; + db->nStatement = 0; + db->isTransactionSavepoint = 0; +} + +/* +** Invoke the destructor function associated with FuncDef p, if any. Except, +** if this is not the last copy of the function, do not invoke it. Multiple +** copies of a single function are created when create_function() is called +** with SQLITE_ANY as the encoding. +*/ +static void functionDestroy(sqlite3 *db, FuncDef *p){ + FuncDestructor *pDestructor = p->pDestructor; + if( pDestructor ){ + pDestructor->nRef--; + if( pDestructor->nRef==0 ){ + pDestructor->xDestroy(pDestructor->pUserData); + sqlite3DbFree(db, pDestructor); + } + } +} + +/* +** Close an existing SQLite database +*/ +int sqlite3_close(sqlite3 *db){ + HashElem *i; /* Hash table iterator */ + int j; + + if( !db ){ + return SQLITE_OK; + } + if( !sqlite3SafetyCheckSickOrOk(db) ){ + return SQLITE_MISUSE_BKPT; + } + sqlite3_mutex_enter(db->mutex); + + /* Force xDestroy calls on all virtual tables */ + sqlite3ResetInternalSchema(db, -1); + + /* If a transaction is open, the ResetInternalSchema() call above + ** will not have called the xDisconnect() method on any virtual + ** tables in the db->aVTrans[] array. The following sqlite3VtabRollback() + ** call will do so. We need to do this before the check for active + ** SQL statements below, as the v-table implementation may be storing + ** some prepared statements internally. + */ + sqlite3VtabRollback(db); + + /* If there are any outstanding VMs, return SQLITE_BUSY. */ + if( db->pVdbe ){ + sqlite3Error(db, SQLITE_BUSY, + "unable to close due to unfinalised statements"); + sqlite3_mutex_leave(db->mutex); + return SQLITE_BUSY; + } + assert( sqlite3SafetyCheckSickOrOk(db) ); + + for(j=0; jnDb; j++){ + Btree *pBt = db->aDb[j].pBt; + if( pBt && sqlite3BtreeIsInBackup(pBt) ){ + sqlite3Error(db, SQLITE_BUSY, + "unable to close due to unfinished backup operation"); + sqlite3_mutex_leave(db->mutex); + return SQLITE_BUSY; + } + } + + /* Free any outstanding Savepoint structures. */ + sqlite3CloseSavepoints(db); + + for(j=0; jnDb; j++){ + struct Db *pDb = &db->aDb[j]; + if( pDb->pBt ){ + sqlite3BtreeClose(pDb->pBt); + pDb->pBt = 0; + if( j!=1 ){ + pDb->pSchema = 0; + } + } + } + sqlite3ResetInternalSchema(db, -1); + + /* Tell the code in notify.c that the connection no longer holds any + ** locks and does not require any further unlock-notify callbacks. + */ + sqlite3ConnectionClosed(db); + + assert( db->nDb<=2 ); + assert( db->aDb==db->aDbStatic ); + for(j=0; jaFunc.a); j++){ + FuncDef *pNext, *pHash, *p; + for(p=db->aFunc.a[j]; p; p=pHash){ + pHash = p->pHash; + while( p ){ + functionDestroy(db, p); + pNext = p->pNext; + sqlite3DbFree(db, p); + p = pNext; + } + } + } + for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){ + CollSeq *pColl = (CollSeq *)sqliteHashData(i); + /* Invoke any destructors registered for collation sequence user data. */ + for(j=0; j<3; j++){ + if( pColl[j].xDel ){ + pColl[j].xDel(pColl[j].pUser); + } + } + sqlite3DbFree(db, pColl); + } + sqlite3HashClear(&db->aCollSeq); +#ifndef SQLITE_OMIT_VIRTUALTABLE + for(i=sqliteHashFirst(&db->aModule); i; i=sqliteHashNext(i)){ + Module *pMod = (Module *)sqliteHashData(i); + if( pMod->xDestroy ){ + pMod->xDestroy(pMod->pAux); + } + sqlite3DbFree(db, pMod); + } + sqlite3HashClear(&db->aModule); +#endif + + sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */ + if( db->pErr ){ + sqlite3ValueFree(db->pErr); + } + sqlite3CloseExtensions(db); + + db->magic = SQLITE_MAGIC_ERROR; + + /* The temp-database schema is allocated differently from the other schema + ** objects (using sqliteMalloc() directly, instead of sqlite3BtreeSchema()). + ** So it needs to be freed here. Todo: Why not roll the temp schema into + ** the same sqliteMalloc() as the one that allocates the database + ** structure? + */ + sqlite3DbFree(db, db->aDb[1].pSchema); + sqlite3_mutex_leave(db->mutex); + db->magic = SQLITE_MAGIC_CLOSED; + sqlite3_mutex_free(db->mutex); + assert( db->lookaside.nOut==0 ); /* Fails on a lookaside memory leak */ + if( db->lookaside.bMalloced ){ + sqlite3_free(db->lookaside.pStart); + } + sqlite3_free(db); + return SQLITE_OK; +} + +/* +** Rollback all database files. +*/ +void sqlite3RollbackAll(sqlite3 *db){ + int i; + int inTrans = 0; + assert( sqlite3_mutex_held(db->mutex) ); + sqlite3BeginBenignMalloc(); + for(i=0; inDb; i++){ + if( db->aDb[i].pBt ){ + if( sqlite3BtreeIsInTrans(db->aDb[i].pBt) ){ + inTrans = 1; + } + sqlite3BtreeRollback(db->aDb[i].pBt); + db->aDb[i].inTrans = 0; + } + } + sqlite3VtabRollback(db); + sqlite3EndBenignMalloc(); + + if( db->flags&SQLITE_InternChanges ){ + sqlite3ExpirePreparedStatements(db); + sqlite3ResetInternalSchema(db, -1); + } + + /* Any deferred constraint violations have now been resolved. */ + db->nDeferredCons = 0; + + /* If one has been configured, invoke the rollback-hook callback */ + if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){ + db->xRollbackCallback(db->pRollbackArg); + } +} + +/* +** Return a static string that describes the kind of error specified in the +** argument. +*/ +const char *sqlite3ErrStr(int rc){ + static const char* const aMsg[] = { + /* SQLITE_OK */ "not an error", + /* SQLITE_ERROR */ "SQL logic error or missing database", + /* SQLITE_INTERNAL */ 0, + /* SQLITE_PERM */ "access permission denied", + /* SQLITE_ABORT */ "callback requested query abort", + /* SQLITE_BUSY */ "database is locked", + /* SQLITE_LOCKED */ "database table is locked", + /* SQLITE_NOMEM */ "out of memory", + /* SQLITE_READONLY */ "attempt to write a readonly database", + /* SQLITE_INTERRUPT */ "interrupted", + /* SQLITE_IOERR */ "disk I/O error", + /* SQLITE_CORRUPT */ "database disk image is malformed", + /* SQLITE_NOTFOUND */ "unknown operation", + /* SQLITE_FULL */ "database or disk is full", + /* SQLITE_CANTOPEN */ "unable to open database file", + /* SQLITE_PROTOCOL */ "locking protocol", + /* SQLITE_EMPTY */ "table contains no data", + /* SQLITE_SCHEMA */ "database schema has changed", + /* SQLITE_TOOBIG */ "string or blob too big", + /* SQLITE_CONSTRAINT */ "constraint failed", + /* SQLITE_MISMATCH */ "datatype mismatch", + /* SQLITE_MISUSE */ "library routine called out of sequence", + /* SQLITE_NOLFS */ "large file support is disabled", + /* SQLITE_AUTH */ "authorization denied", + /* SQLITE_FORMAT */ "auxiliary database format error", + /* SQLITE_RANGE */ "bind or column index out of range", + /* SQLITE_NOTADB */ "file is encrypted or is not a database", + }; + rc &= 0xff; + if( ALWAYS(rc>=0) && rc<(int)(sizeof(aMsg)/sizeof(aMsg[0])) && aMsg[rc]!=0 ){ + return aMsg[rc]; + }else{ + return "unknown error"; + } +} + +/* +** This routine implements a busy callback that sleeps and tries +** again until a timeout value is reached. The timeout value is +** an integer number of milliseconds passed in as the first +** argument. +*/ +static int sqliteDefaultBusyCallback( + void *ptr, /* Database connection */ + int count /* Number of times table has been busy */ +){ +#if SQLITE_OS_WIN || (defined(HAVE_USLEEP) && HAVE_USLEEP) + static const u8 delays[] = + { 1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 100 }; + static const u8 totals[] = + { 0, 1, 3, 8, 18, 33, 53, 78, 103, 128, 178, 228 }; +# define NDELAY ArraySize(delays) + sqlite3 *db = (sqlite3 *)ptr; + int timeout = db->busyTimeout; + int delay, prior; + + assert( count>=0 ); + if( count < NDELAY ){ + delay = delays[count]; + prior = totals[count]; + }else{ + delay = delays[NDELAY-1]; + prior = totals[NDELAY-1] + delay*(count-(NDELAY-1)); + } + if( prior + delay > timeout ){ + delay = timeout - prior; + if( delay<=0 ) return 0; + } + sqlite3OsSleep(db->pVfs, delay*1000); + return 1; +#else + sqlite3 *db = (sqlite3 *)ptr; + int timeout = ((sqlite3 *)ptr)->busyTimeout; + if( (count+1)*1000 > timeout ){ + return 0; + } + sqlite3OsSleep(db->pVfs, 1000000); + return 1; +#endif +} + +/* +** Invoke the given busy handler. +** +** This routine is called when an operation failed with a lock. +** If this routine returns non-zero, the lock is retried. If it +** returns 0, the operation aborts with an SQLITE_BUSY error. +*/ +int sqlite3InvokeBusyHandler(BusyHandler *p){ + int rc; + if( NEVER(p==0) || p->xFunc==0 || p->nBusy<0 ) return 0; + rc = p->xFunc(p->pArg, p->nBusy); + if( rc==0 ){ + p->nBusy = -1; + }else{ + p->nBusy++; + } + return rc; +} + +/* +** This routine sets the busy callback for an Sqlite database to the +** given callback function with the given argument. +*/ +int sqlite3_busy_handler( + sqlite3 *db, + int (*xBusy)(void*,int), + void *pArg +){ + sqlite3_mutex_enter(db->mutex); + db->busyHandler.xFunc = xBusy; + db->busyHandler.pArg = pArg; + db->busyHandler.nBusy = 0; + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK +/* +** This routine sets the progress callback for an Sqlite database to the +** given callback function with the given argument. The progress callback will +** be invoked every nOps opcodes. +*/ +void sqlite3_progress_handler( + sqlite3 *db, + int nOps, + int (*xProgress)(void*), + void *pArg +){ + sqlite3_mutex_enter(db->mutex); + if( nOps>0 ){ + db->xProgress = xProgress; + db->nProgressOps = nOps; + db->pProgressArg = pArg; + }else{ + db->xProgress = 0; + db->nProgressOps = 0; + db->pProgressArg = 0; + } + sqlite3_mutex_leave(db->mutex); +} +#endif + + +/* +** This routine installs a default busy handler that waits for the +** specified number of milliseconds before returning 0. +*/ +int sqlite3_busy_timeout(sqlite3 *db, int ms){ + if( ms>0 ){ + db->busyTimeout = ms; + sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db); + }else{ + sqlite3_busy_handler(db, 0, 0); + } + return SQLITE_OK; +} + +/* +** Cause any pending operation to stop at its earliest opportunity. +*/ +void sqlite3_interrupt(sqlite3 *db){ + db->u1.isInterrupted = 1; +} + + +/* +** This function is exactly the same as sqlite3_create_function(), except +** that it is designed to be called by internal code. The difference is +** that if a malloc() fails in sqlite3_create_function(), an error code +** is returned and the mallocFailed flag cleared. +*/ +int sqlite3CreateFunc( + sqlite3 *db, + const char *zFunctionName, + int nArg, + int enc, + void *pUserData, + void (*xFunc)(sqlite3_context*,int,sqlite3_value **), + void (*xStep)(sqlite3_context*,int,sqlite3_value **), + void (*xFinal)(sqlite3_context*), + FuncDestructor *pDestructor +){ + FuncDef *p; + int nName; + + assert( sqlite3_mutex_held(db->mutex) ); + if( zFunctionName==0 || + (xFunc && (xFinal || xStep)) || + (!xFunc && (xFinal && !xStep)) || + (!xFunc && (!xFinal && xStep)) || + (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) || + (255<(nName = sqlite3Strlen30( zFunctionName))) ){ + return SQLITE_MISUSE_BKPT; + } + +#ifndef SQLITE_OMIT_UTF16 + /* If SQLITE_UTF16 is specified as the encoding type, transform this + ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the + ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally. + ** + ** If SQLITE_ANY is specified, add three versions of the function + ** to the hash table. + */ + if( enc==SQLITE_UTF16 ){ + enc = SQLITE_UTF16NATIVE; + }else if( enc==SQLITE_ANY ){ + int rc; + rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8, + pUserData, xFunc, xStep, xFinal, pDestructor); + if( rc==SQLITE_OK ){ + rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE, + pUserData, xFunc, xStep, xFinal, pDestructor); + } + if( rc!=SQLITE_OK ){ + return rc; + } + enc = SQLITE_UTF16BE; + } +#else + enc = SQLITE_UTF8; +#endif + + /* Check if an existing function is being overridden or deleted. If so, + ** and there are active VMs, then return SQLITE_BUSY. If a function + ** is being overridden/deleted but there are no active VMs, allow the + ** operation to continue but invalidate all precompiled statements. + */ + p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 0); + if( p && p->iPrefEnc==enc && p->nArg==nArg ){ + if( db->activeVdbeCnt ){ + sqlite3Error(db, SQLITE_BUSY, + "unable to delete/modify user-function due to active statements"); + assert( !db->mallocFailed ); + return SQLITE_BUSY; + }else{ + sqlite3ExpirePreparedStatements(db); + } + } + + p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 1); + assert(p || db->mallocFailed); + if( !p ){ + return SQLITE_NOMEM; + } + + /* If an older version of the function with a configured destructor is + ** being replaced invoke the destructor function here. */ + functionDestroy(db, p); + + if( pDestructor ){ + pDestructor->nRef++; + } + p->pDestructor = pDestructor; + p->flags = 0; + p->xFunc = xFunc; + p->xStep = xStep; + p->xFinalize = xFinal; + p->pUserData = pUserData; + p->nArg = (u16)nArg; + return SQLITE_OK; +} + +/* +** Create new user functions. +*/ +int sqlite3_create_function( + sqlite3 *db, + const char *zFunc, + int nArg, + int enc, + void *p, + void (*xFunc)(sqlite3_context*,int,sqlite3_value **), + void (*xStep)(sqlite3_context*,int,sqlite3_value **), + void (*xFinal)(sqlite3_context*) +){ + return sqlite3_create_function_v2(db, zFunc, nArg, enc, p, xFunc, xStep, + xFinal, 0); +} + +int sqlite3_create_function_v2( + sqlite3 *db, + const char *zFunc, + int nArg, + int enc, + void *p, + void (*xFunc)(sqlite3_context*,int,sqlite3_value **), + void (*xStep)(sqlite3_context*,int,sqlite3_value **), + void (*xFinal)(sqlite3_context*), + void (*xDestroy)(void *) +){ + int rc = SQLITE_ERROR; + FuncDestructor *pArg = 0; + sqlite3_mutex_enter(db->mutex); + if( xDestroy ){ + pArg = (FuncDestructor *)sqlite3DbMallocZero(db, sizeof(FuncDestructor)); + if( !pArg ){ + xDestroy(p); + goto out; + } + pArg->xDestroy = xDestroy; + pArg->pUserData = p; + } + rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, xFunc, xStep, xFinal, pArg); + if( pArg && pArg->nRef==0 ){ + assert( rc!=SQLITE_OK ); + xDestroy(p); + sqlite3DbFree(db, pArg); + } + + out: + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +#ifndef SQLITE_OMIT_UTF16 +int sqlite3_create_function16( + sqlite3 *db, + const void *zFunctionName, + int nArg, + int eTextRep, + void *p, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +){ + int rc; + char *zFunc8; + sqlite3_mutex_enter(db->mutex); + assert( !db->mallocFailed ); + zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1, SQLITE_UTF16NATIVE); + rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xFunc, xStep, xFinal,0); + sqlite3DbFree(db, zFunc8); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} +#endif + + +/* +** Declare that a function has been overloaded by a virtual table. +** +** If the function already exists as a regular global function, then +** this routine is a no-op. If the function does not exist, then create +** a new one that always throws a run-time error. +** +** When virtual tables intend to provide an overloaded function, they +** should call this routine to make sure the global function exists. +** A global function must exist in order for name resolution to work +** properly. +*/ +int sqlite3_overload_function( + sqlite3 *db, + const char *zName, + int nArg +){ + int nName = sqlite3Strlen30(zName); + int rc = SQLITE_OK; + sqlite3_mutex_enter(db->mutex); + if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){ + rc = sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8, + 0, sqlite3InvalidFunction, 0, 0, 0); + } + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +#ifndef SQLITE_OMIT_TRACE +/* +** Register a trace function. The pArg from the previously registered trace +** is returned. +** +** A NULL trace function means that no tracing is executes. A non-NULL +** trace is a pointer to a function that is invoked at the start of each +** SQL statement. +*/ +void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){ + void *pOld; + sqlite3_mutex_enter(db->mutex); + pOld = db->pTraceArg; + db->xTrace = xTrace; + db->pTraceArg = pArg; + sqlite3_mutex_leave(db->mutex); + return pOld; +} +/* +** Register a profile function. The pArg from the previously registered +** profile function is returned. +** +** A NULL profile function means that no profiling is executes. A non-NULL +** profile is a pointer to a function that is invoked at the conclusion of +** each SQL statement that is run. +*/ +void *sqlite3_profile( + sqlite3 *db, + void (*xProfile)(void*,const char*,sqlite_uint64), + void *pArg +){ + void *pOld; + sqlite3_mutex_enter(db->mutex); + pOld = db->pProfileArg; + db->xProfile = xProfile; + db->pProfileArg = pArg; + sqlite3_mutex_leave(db->mutex); + return pOld; +} +#endif /* SQLITE_OMIT_TRACE */ + +/*** EXPERIMENTAL *** +** +** Register a function to be invoked when a transaction comments. +** If the invoked function returns non-zero, then the commit becomes a +** rollback. +*/ +void *sqlite3_commit_hook( + sqlite3 *db, /* Attach the hook to this database */ + int (*xCallback)(void*), /* Function to invoke on each commit */ + void *pArg /* Argument to the function */ +){ + void *pOld; + sqlite3_mutex_enter(db->mutex); + pOld = db->pCommitArg; + db->xCommitCallback = xCallback; + db->pCommitArg = pArg; + sqlite3_mutex_leave(db->mutex); + return pOld; +} + +/* +** Register a callback to be invoked each time a row is updated, +** inserted or deleted using this database connection. +*/ +void *sqlite3_update_hook( + sqlite3 *db, /* Attach the hook to this database */ + void (*xCallback)(void*,int,char const *,char const *,sqlite_int64), + void *pArg /* Argument to the function */ +){ + void *pRet; + sqlite3_mutex_enter(db->mutex); + pRet = db->pUpdateArg; + db->xUpdateCallback = xCallback; + db->pUpdateArg = pArg; + sqlite3_mutex_leave(db->mutex); + return pRet; +} + +/* +** Register a callback to be invoked each time a transaction is rolled +** back by this database connection. +*/ +void *sqlite3_rollback_hook( + sqlite3 *db, /* Attach the hook to this database */ + void (*xCallback)(void*), /* Callback function */ + void *pArg /* Argument to the function */ +){ + void *pRet; + sqlite3_mutex_enter(db->mutex); + pRet = db->pRollbackArg; + db->xRollbackCallback = xCallback; + db->pRollbackArg = pArg; + sqlite3_mutex_leave(db->mutex); + return pRet; +} + +#ifndef SQLITE_OMIT_WAL +/* +** The sqlite3_wal_hook() callback registered by sqlite3_wal_autocheckpoint(). +** Invoke sqlite3_wal_checkpoint if the number of frames in the log file +** is greater than sqlite3.pWalArg cast to an integer (the value configured by +** wal_autocheckpoint()). +*/ +int sqlite3WalDefaultHook( + void *pClientData, /* Argument */ + sqlite3 *db, /* Connection */ + const char *zDb, /* Database */ + int nFrame /* Size of WAL */ +){ + if( nFrame>=SQLITE_PTR_TO_INT(pClientData) ){ + sqlite3BeginBenignMalloc(); + sqlite3_wal_checkpoint(db, zDb); + sqlite3EndBenignMalloc(); + } + return SQLITE_OK; +} +#endif /* SQLITE_OMIT_WAL */ + +/* +** Configure an sqlite3_wal_hook() callback to automatically checkpoint +** a database after committing a transaction if there are nFrame or +** more frames in the log file. Passing zero or a negative value as the +** nFrame parameter disables automatic checkpoints entirely. +** +** The callback registered by this function replaces any existing callback +** registered using sqlite3_wal_hook(). Likewise, registering a callback +** using sqlite3_wal_hook() disables the automatic checkpoint mechanism +** configured by this function. +*/ +int sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){ +#ifdef SQLITE_OMIT_WAL + UNUSED_PARAMETER(db); + UNUSED_PARAMETER(nFrame); +#else + if( nFrame>0 ){ + sqlite3_wal_hook(db, sqlite3WalDefaultHook, SQLITE_INT_TO_PTR(nFrame)); + }else{ + sqlite3_wal_hook(db, 0, 0); + } +#endif + return SQLITE_OK; +} + +/* +** Register a callback to be invoked each time a transaction is written +** into the write-ahead-log by this database connection. +*/ +void *sqlite3_wal_hook( + sqlite3 *db, /* Attach the hook to this db handle */ + int(*xCallback)(void *, sqlite3*, const char*, int), + void *pArg /* First argument passed to xCallback() */ +){ +#ifndef SQLITE_OMIT_WAL + void *pRet; + sqlite3_mutex_enter(db->mutex); + pRet = db->pWalArg; + db->xWalCallback = xCallback; + db->pWalArg = pArg; + sqlite3_mutex_leave(db->mutex); + return pRet; +#else + return 0; +#endif +} + +/* +** Checkpoint database zDb. +*/ +int sqlite3_wal_checkpoint_v2( + sqlite3 *db, /* Database handle */ + const char *zDb, /* Name of attached database (or NULL) */ + int eMode, /* SQLITE_CHECKPOINT_* value */ + int *pnLog, /* OUT: Size of WAL log in frames */ + int *pnCkpt /* OUT: Total number of frames checkpointed */ +){ +#ifdef SQLITE_OMIT_WAL + return SQLITE_OK; +#else + int rc; /* Return code */ + int iDb = SQLITE_MAX_ATTACHED; /* sqlite3.aDb[] index of db to checkpoint */ + + /* Initialize the output variables to -1 in case an error occurs. */ + if( pnLog ) *pnLog = -1; + if( pnCkpt ) *pnCkpt = -1; + + assert( SQLITE_CHECKPOINT_FULL>SQLITE_CHECKPOINT_PASSIVE ); + assert( SQLITE_CHECKPOINT_FULLSQLITE_CHECKPOINT_RESTART ){ + return SQLITE_MISUSE; + } + + sqlite3_mutex_enter(db->mutex); + if( zDb && zDb[0] ){ + iDb = sqlite3FindDbName(db, zDb); + } + if( iDb<0 ){ + rc = SQLITE_ERROR; + sqlite3Error(db, SQLITE_ERROR, "unknown database: %s", zDb); + }else{ + rc = sqlite3Checkpoint(db, iDb, eMode, pnLog, pnCkpt); + sqlite3Error(db, rc, 0); + } + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +#endif +} + + +/* +** Checkpoint database zDb. If zDb is NULL, or if the buffer zDb points +** to contains a zero-length string, all attached databases are +** checkpointed. +*/ +int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){ + return sqlite3_wal_checkpoint_v2(db, zDb, SQLITE_CHECKPOINT_PASSIVE, 0, 0); +} + +#ifndef SQLITE_OMIT_WAL +/* +** Run a checkpoint on database iDb. This is a no-op if database iDb is +** not currently open in WAL mode. +** +** If a transaction is open on the database being checkpointed, this +** function returns SQLITE_LOCKED and a checkpoint is not attempted. If +** an error occurs while running the checkpoint, an SQLite error code is +** returned (i.e. SQLITE_IOERR). Otherwise, SQLITE_OK. +** +** The mutex on database handle db should be held by the caller. The mutex +** associated with the specific b-tree being checkpointed is taken by +** this function while the checkpoint is running. +** +** If iDb is passed SQLITE_MAX_ATTACHED, then all attached databases are +** checkpointed. If an error is encountered it is returned immediately - +** no attempt is made to checkpoint any remaining databases. +** +** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART. +*/ +int sqlite3Checkpoint(sqlite3 *db, int iDb, int eMode, int *pnLog, int *pnCkpt){ + int rc = SQLITE_OK; /* Return code */ + int i; /* Used to iterate through attached dbs */ + int bBusy = 0; /* True if SQLITE_BUSY has been encountered */ + + assert( sqlite3_mutex_held(db->mutex) ); + assert( !pnLog || *pnLog==-1 ); + assert( !pnCkpt || *pnCkpt==-1 ); + + for(i=0; inDb && rc==SQLITE_OK; i++){ + if( i==iDb || iDb==SQLITE_MAX_ATTACHED ){ + rc = sqlite3BtreeCheckpoint(db->aDb[i].pBt, eMode, pnLog, pnCkpt); + pnLog = 0; + pnCkpt = 0; + if( rc==SQLITE_BUSY ){ + bBusy = 1; + rc = SQLITE_OK; + } + } + } + + return (rc==SQLITE_OK && bBusy) ? SQLITE_BUSY : rc; +} +#endif /* SQLITE_OMIT_WAL */ + +/* +** This function returns true if main-memory should be used instead of +** a temporary file for transient pager files and statement journals. +** The value returned depends on the value of db->temp_store (runtime +** parameter) and the compile time value of SQLITE_TEMP_STORE. The +** following table describes the relationship between these two values +** and this functions return value. +** +** SQLITE_TEMP_STORE db->temp_store Location of temporary database +** ----------------- -------------- ------------------------------ +** 0 any file (return 0) +** 1 1 file (return 0) +** 1 2 memory (return 1) +** 1 0 file (return 0) +** 2 1 file (return 0) +** 2 2 memory (return 1) +** 2 0 memory (return 1) +** 3 any memory (return 1) +*/ +int sqlite3TempInMemory(const sqlite3 *db){ +#if SQLITE_TEMP_STORE==1 + return ( db->temp_store==2 ); +#endif +#if SQLITE_TEMP_STORE==2 + return ( db->temp_store!=1 ); +#endif +#if SQLITE_TEMP_STORE==3 + return 1; +#endif +#if SQLITE_TEMP_STORE<1 || SQLITE_TEMP_STORE>3 + return 0; +#endif +} + +/* +** Return UTF-8 encoded English language explanation of the most recent +** error. +*/ +const char *sqlite3_errmsg(sqlite3 *db){ + const char *z; + if( !db ){ + return sqlite3ErrStr(SQLITE_NOMEM); + } + if( !sqlite3SafetyCheckSickOrOk(db) ){ + return sqlite3ErrStr(SQLITE_MISUSE_BKPT); + } + sqlite3_mutex_enter(db->mutex); + if( db->mallocFailed ){ + z = sqlite3ErrStr(SQLITE_NOMEM); + }else{ + z = (char*)sqlite3_value_text(db->pErr); + assert( !db->mallocFailed ); + if( z==0 ){ + z = sqlite3ErrStr(db->errCode); + } + } + sqlite3_mutex_leave(db->mutex); + return z; +} + +#ifndef SQLITE_OMIT_UTF16 +/* +** Return UTF-16 encoded English language explanation of the most recent +** error. +*/ +const void *sqlite3_errmsg16(sqlite3 *db){ + static const u16 outOfMem[] = { + 'o', 'u', 't', ' ', 'o', 'f', ' ', 'm', 'e', 'm', 'o', 'r', 'y', 0 + }; + static const u16 misuse[] = { + 'l', 'i', 'b', 'r', 'a', 'r', 'y', ' ', + 'r', 'o', 'u', 't', 'i', 'n', 'e', ' ', + 'c', 'a', 'l', 'l', 'e', 'd', ' ', + 'o', 'u', 't', ' ', + 'o', 'f', ' ', + 's', 'e', 'q', 'u', 'e', 'n', 'c', 'e', 0 + }; + + const void *z; + if( !db ){ + return (void *)outOfMem; + } + if( !sqlite3SafetyCheckSickOrOk(db) ){ + return (void *)misuse; + } + sqlite3_mutex_enter(db->mutex); + if( db->mallocFailed ){ + z = (void *)outOfMem; + }else{ + z = sqlite3_value_text16(db->pErr); + if( z==0 ){ + sqlite3ValueSetStr(db->pErr, -1, sqlite3ErrStr(db->errCode), + SQLITE_UTF8, SQLITE_STATIC); + z = sqlite3_value_text16(db->pErr); + } + /* A malloc() may have failed within the call to sqlite3_value_text16() + ** above. If this is the case, then the db->mallocFailed flag needs to + ** be cleared before returning. Do this directly, instead of via + ** sqlite3ApiExit(), to avoid setting the database handle error message. + */ + db->mallocFailed = 0; + } + sqlite3_mutex_leave(db->mutex); + return z; +} +#endif /* SQLITE_OMIT_UTF16 */ + +/* +** Return the most recent error code generated by an SQLite routine. If NULL is +** passed to this function, we assume a malloc() failed during sqlite3_open(). +*/ +int sqlite3_errcode(sqlite3 *db){ + if( db && !sqlite3SafetyCheckSickOrOk(db) ){ + return SQLITE_MISUSE_BKPT; + } + if( !db || db->mallocFailed ){ + return SQLITE_NOMEM; + } + return db->errCode & db->errMask; +} +int sqlite3_extended_errcode(sqlite3 *db){ + if( db && !sqlite3SafetyCheckSickOrOk(db) ){ + return SQLITE_MISUSE_BKPT; + } + if( !db || db->mallocFailed ){ + return SQLITE_NOMEM; + } + return db->errCode; +} + +/* +** Create a new collating function for database "db". The name is zName +** and the encoding is enc. +*/ +static int createCollation( + sqlite3* db, + const char *zName, + u8 enc, + void* pCtx, + int(*xCompare)(void*,int,const void*,int,const void*), + void(*xDel)(void*) +){ + CollSeq *pColl; + int enc2; + int nName = sqlite3Strlen30(zName); + + assert( sqlite3_mutex_held(db->mutex) ); + + /* If SQLITE_UTF16 is specified as the encoding type, transform this + ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the + ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally. + */ + enc2 = enc; + testcase( enc2==SQLITE_UTF16 ); + testcase( enc2==SQLITE_UTF16_ALIGNED ); + if( enc2==SQLITE_UTF16 || enc2==SQLITE_UTF16_ALIGNED ){ + enc2 = SQLITE_UTF16NATIVE; + } + if( enc2SQLITE_UTF16BE ){ + return SQLITE_MISUSE_BKPT; + } + + /* Check if this call is removing or replacing an existing collation + ** sequence. If so, and there are active VMs, return busy. If there + ** are no active VMs, invalidate any pre-compiled statements. + */ + pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 0); + if( pColl && pColl->xCmp ){ + if( db->activeVdbeCnt ){ + sqlite3Error(db, SQLITE_BUSY, + "unable to delete/modify collation sequence due to active statements"); + return SQLITE_BUSY; + } + sqlite3ExpirePreparedStatements(db); + + /* If collation sequence pColl was created directly by a call to + ** sqlite3_create_collation, and not generated by synthCollSeq(), + ** then any copies made by synthCollSeq() need to be invalidated. + ** Also, collation destructor - CollSeq.xDel() - function may need + ** to be called. + */ + if( (pColl->enc & ~SQLITE_UTF16_ALIGNED)==enc2 ){ + CollSeq *aColl = sqlite3HashFind(&db->aCollSeq, zName, nName); + int j; + for(j=0; j<3; j++){ + CollSeq *p = &aColl[j]; + if( p->enc==pColl->enc ){ + if( p->xDel ){ + p->xDel(p->pUser); + } + p->xCmp = 0; + } + } + } + } + + pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 1); + if( pColl==0 ) return SQLITE_NOMEM; + pColl->xCmp = xCompare; + pColl->pUser = pCtx; + pColl->xDel = xDel; + pColl->enc = (u8)(enc2 | (enc & SQLITE_UTF16_ALIGNED)); + sqlite3Error(db, SQLITE_OK, 0); + return SQLITE_OK; +} + + +/* +** This array defines hard upper bounds on limit values. The +** initializer must be kept in sync with the SQLITE_LIMIT_* +** #defines in sqlite3.h. +*/ +static const int aHardLimit[] = { + SQLITE_MAX_LENGTH, + SQLITE_MAX_SQL_LENGTH, + SQLITE_MAX_COLUMN, + SQLITE_MAX_EXPR_DEPTH, + SQLITE_MAX_COMPOUND_SELECT, + SQLITE_MAX_VDBE_OP, + SQLITE_MAX_FUNCTION_ARG, + SQLITE_MAX_ATTACHED, + SQLITE_MAX_LIKE_PATTERN_LENGTH, + SQLITE_MAX_VARIABLE_NUMBER, + SQLITE_MAX_TRIGGER_DEPTH, +}; + +/* +** Make sure the hard limits are set to reasonable values +*/ +#if SQLITE_MAX_LENGTH<100 +# error SQLITE_MAX_LENGTH must be at least 100 +#endif +#if SQLITE_MAX_SQL_LENGTH<100 +# error SQLITE_MAX_SQL_LENGTH must be at least 100 +#endif +#if SQLITE_MAX_SQL_LENGTH>SQLITE_MAX_LENGTH +# error SQLITE_MAX_SQL_LENGTH must not be greater than SQLITE_MAX_LENGTH +#endif +#if SQLITE_MAX_COMPOUND_SELECT<2 +# error SQLITE_MAX_COMPOUND_SELECT must be at least 2 +#endif +#if SQLITE_MAX_VDBE_OP<40 +# error SQLITE_MAX_VDBE_OP must be at least 40 +#endif +#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>1000 +# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 1000 +#endif +#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>62 +# error SQLITE_MAX_ATTACHED must be between 0 and 62 +#endif +#if SQLITE_MAX_LIKE_PATTERN_LENGTH<1 +# error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1 +#endif +#if SQLITE_MAX_COLUMN>32767 +# error SQLITE_MAX_COLUMN must not exceed 32767 +#endif +#if SQLITE_MAX_TRIGGER_DEPTH<1 +# error SQLITE_MAX_TRIGGER_DEPTH must be at least 1 +#endif + + +/* +** Change the value of a limit. Report the old value. +** If an invalid limit index is supplied, report -1. +** Make no changes but still report the old value if the +** new limit is negative. +** +** A new lower limit does not shrink existing constructs. +** It merely prevents new constructs that exceed the limit +** from forming. +*/ +int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ + int oldLimit; + + + /* EVIDENCE-OF: R-30189-54097 For each limit category SQLITE_LIMIT_NAME + ** there is a hard upper bound set at compile-time by a C preprocessor + ** macro called SQLITE_MAX_NAME. (The "_LIMIT_" in the name is changed to + ** "_MAX_".) + */ + assert( aHardLimit[SQLITE_LIMIT_LENGTH]==SQLITE_MAX_LENGTH ); + assert( aHardLimit[SQLITE_LIMIT_SQL_LENGTH]==SQLITE_MAX_SQL_LENGTH ); + assert( aHardLimit[SQLITE_LIMIT_COLUMN]==SQLITE_MAX_COLUMN ); + assert( aHardLimit[SQLITE_LIMIT_EXPR_DEPTH]==SQLITE_MAX_EXPR_DEPTH ); + assert( aHardLimit[SQLITE_LIMIT_COMPOUND_SELECT]==SQLITE_MAX_COMPOUND_SELECT); + assert( aHardLimit[SQLITE_LIMIT_VDBE_OP]==SQLITE_MAX_VDBE_OP ); + assert( aHardLimit[SQLITE_LIMIT_FUNCTION_ARG]==SQLITE_MAX_FUNCTION_ARG ); + assert( aHardLimit[SQLITE_LIMIT_ATTACHED]==SQLITE_MAX_ATTACHED ); + assert( aHardLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]== + SQLITE_MAX_LIKE_PATTERN_LENGTH ); + assert( aHardLimit[SQLITE_LIMIT_VARIABLE_NUMBER]==SQLITE_MAX_VARIABLE_NUMBER); + assert( aHardLimit[SQLITE_LIMIT_TRIGGER_DEPTH]==SQLITE_MAX_TRIGGER_DEPTH ); + assert( SQLITE_LIMIT_TRIGGER_DEPTH==(SQLITE_N_LIMIT-1) ); + + + if( limitId<0 || limitId>=SQLITE_N_LIMIT ){ + return -1; + } + oldLimit = db->aLimit[limitId]; + if( newLimit>=0 ){ /* IMP: R-52476-28732 */ + if( newLimit>aHardLimit[limitId] ){ + newLimit = aHardLimit[limitId]; /* IMP: R-51463-25634 */ + } + db->aLimit[limitId] = newLimit; + } + return oldLimit; /* IMP: R-53341-35419 */ +} + +/* +** This function is used to parse both URIs and non-URI filenames passed by the +** user to API functions sqlite3_open() or sqlite3_open_v2(), and for database +** URIs specified as part of ATTACH statements. +** +** The first argument to this function is the name of the VFS to use (or +** a NULL to signify the default VFS) if the URI does not contain a "vfs=xxx" +** query parameter. The second argument contains the URI (or non-URI filename) +** itself. When this function is called the *pFlags variable should contain +** the default flags to open the database handle with. The value stored in +** *pFlags may be updated before returning if the URI filename contains +** "cache=xxx" or "mode=xxx" query parameters. +** +** If successful, SQLITE_OK is returned. In this case *ppVfs is set to point to +** the VFS that should be used to open the database file. *pzFile is set to +** point to a buffer containing the name of the file to open. It is the +** responsibility of the caller to eventually call sqlite3_free() to release +** this buffer. +** +** If an error occurs, then an SQLite error code is returned and *pzErrMsg +** may be set to point to a buffer containing an English language error +** message. It is the responsibility of the caller to eventually release +** this buffer by calling sqlite3_free(). +*/ +int sqlite3ParseUri( + const char *zDefaultVfs, /* VFS to use if no "vfs=xxx" query option */ + const char *zUri, /* Nul-terminated URI to parse */ + unsigned int *pFlags, /* IN/OUT: SQLITE_OPEN_XXX flags */ + sqlite3_vfs **ppVfs, /* OUT: VFS to use */ + char **pzFile, /* OUT: Filename component of URI */ + char **pzErrMsg /* OUT: Error message (if rc!=SQLITE_OK) */ +){ + int rc = SQLITE_OK; + unsigned int flags = *pFlags; + const char *zVfs = zDefaultVfs; + char *zFile; + char c; + int nUri = sqlite3Strlen30(zUri); + + assert( *pzErrMsg==0 ); + + if( ((flags & SQLITE_OPEN_URI) || sqlite3GlobalConfig.bOpenUri) + && nUri>=5 && memcmp(zUri, "file:", 5)==0 + ){ + char *zOpt; + int eState; /* Parser state when parsing URI */ + int iIn; /* Input character index */ + int iOut = 0; /* Output character index */ + int nByte = nUri+2; /* Bytes of space to allocate */ + + /* Make sure the SQLITE_OPEN_URI flag is set to indicate to the VFS xOpen + ** method that there may be extra parameters following the file-name. */ + flags |= SQLITE_OPEN_URI; + + for(iIn=0; iIn=0 && octet<256 ); + if( octet==0 ){ + /* This branch is taken when "%00" appears within the URI. In this + ** case we ignore all text in the remainder of the path, name or + ** value currently being parsed. So ignore the current character + ** and skip to the next "?", "=" or "&", as appropriate. */ + while( (c = zUri[iIn])!=0 && c!='#' + && (eState!=0 || c!='?') + && (eState!=1 || (c!='=' && c!='&')) + && (eState!=2 || c!='&') + ){ + iIn++; + } + continue; + } + c = octet; + }else if( eState==1 && (c=='&' || c=='=') ){ + if( zFile[iOut-1]==0 ){ + /* An empty option name. Ignore this option altogether. */ + while( zUri[iIn] && zUri[iIn]!='#' && zUri[iIn-1]!='&' ) iIn++; + continue; + } + if( c=='&' ){ + zFile[iOut++] = '\0'; + }else{ + eState = 2; + } + c = 0; + }else if( (eState==0 && c=='?') || (eState==2 && c=='&') ){ + c = 0; + eState = 1; + } + zFile[iOut++] = c; + } + if( eState==1 ) zFile[iOut++] = '\0'; + zFile[iOut++] = '\0'; + zFile[iOut++] = '\0'; + + /* Check if there were any options specified that should be interpreted + ** here. Options that are interpreted here include "vfs" and those that + ** correspond to flags that may be passed to the sqlite3_open_v2() + ** method. */ + zOpt = &zFile[sqlite3Strlen30(zFile)+1]; + while( zOpt[0] ){ + int nOpt = sqlite3Strlen30(zOpt); + char *zVal = &zOpt[nOpt+1]; + int nVal = sqlite3Strlen30(zVal); + + if( nOpt==3 && memcmp("vfs", zOpt, 3)==0 ){ + zVfs = zVal; + }else{ + struct OpenMode { + const char *z; + int mode; + } *aMode = 0; + char *zModeType = 0; + int mask = 0; + int limit = 0; + + if( nOpt==5 && memcmp("cache", zOpt, 5)==0 ){ + static struct OpenMode aCacheMode[] = { + { "shared", SQLITE_OPEN_SHAREDCACHE }, + { "private", SQLITE_OPEN_PRIVATECACHE }, + { 0, 0 } + }; + + mask = SQLITE_OPEN_SHAREDCACHE|SQLITE_OPEN_PRIVATECACHE; + aMode = aCacheMode; + limit = mask; + zModeType = "cache"; + } + if( nOpt==4 && memcmp("mode", zOpt, 4)==0 ){ + static struct OpenMode aOpenMode[] = { + { "ro", SQLITE_OPEN_READONLY }, + { "rw", SQLITE_OPEN_READWRITE }, + { "rwc", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE }, + { 0, 0 } + }; + + mask = SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE; + aMode = aOpenMode; + limit = mask & flags; + zModeType = "access"; + } + + if( aMode ){ + int i; + int mode = 0; + for(i=0; aMode[i].z; i++){ + const char *z = aMode[i].z; + if( nVal==sqlite3Strlen30(z) && 0==memcmp(zVal, z, nVal) ){ + mode = aMode[i].mode; + break; + } + } + if( mode==0 ){ + *pzErrMsg = sqlite3_mprintf("no such %s mode: %s", zModeType, zVal); + rc = SQLITE_ERROR; + goto parse_uri_out; + } + if( mode>limit ){ + *pzErrMsg = sqlite3_mprintf("%s mode not allowed: %s", + zModeType, zVal); + rc = SQLITE_PERM; + goto parse_uri_out; + } + flags = (flags & ~mask) | mode; + } + } + + zOpt = &zVal[nVal+1]; + } + + }else{ + zFile = sqlite3_malloc(nUri+2); + if( !zFile ) return SQLITE_NOMEM; + memcpy(zFile, zUri, nUri); + zFile[nUri] = '\0'; + zFile[nUri+1] = '\0'; + } + + *ppVfs = sqlite3_vfs_find(zVfs); + if( *ppVfs==0 ){ + *pzErrMsg = sqlite3_mprintf("no such vfs: %s", zVfs); + rc = SQLITE_ERROR; + } + parse_uri_out: + if( rc!=SQLITE_OK ){ + sqlite3_free(zFile); + zFile = 0; + } + *pFlags = flags; + *pzFile = zFile; + return rc; +} + + +/* +** This routine does the work of opening a database on behalf of +** sqlite3_open() and sqlite3_open16(). The database filename "zFilename" +** is UTF-8 encoded. +*/ +static int openDatabase( + const char *zFilename, /* Database filename UTF-8 encoded */ + sqlite3 **ppDb, /* OUT: Returned database handle */ + unsigned int flags, /* Operational flags */ + const char *zVfs /* Name of the VFS to use */ +){ + sqlite3 *db; /* Store allocated handle here */ + int rc; /* Return code */ + int isThreadsafe; /* True for threadsafe connections */ + char *zOpen = 0; /* Filename argument to pass to BtreeOpen() */ + char *zErrMsg = 0; /* Error message from sqlite3ParseUri() */ + + *ppDb = 0; +#ifndef SQLITE_OMIT_AUTOINIT + rc = sqlite3_initialize(); + if( rc ) return rc; +#endif + + /* Only allow sensible combinations of bits in the flags argument. + ** Throw an error if any non-sense combination is used. If we + ** do not block illegal combinations here, it could trigger + ** assert() statements in deeper layers. Sensible combinations + ** are: + ** + ** 1: SQLITE_OPEN_READONLY + ** 2: SQLITE_OPEN_READWRITE + ** 6: SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE + */ + assert( SQLITE_OPEN_READONLY == 0x01 ); + assert( SQLITE_OPEN_READWRITE == 0x02 ); + assert( SQLITE_OPEN_CREATE == 0x04 ); + testcase( (1<<(flags&7))==0x02 ); /* READONLY */ + testcase( (1<<(flags&7))==0x04 ); /* READWRITE */ + testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */ + if( ((1<<(flags&7)) & 0x46)==0 ) return SQLITE_MISUSE_BKPT; + + if( sqlite3GlobalConfig.bCoreMutex==0 ){ + isThreadsafe = 0; + }else if( flags & SQLITE_OPEN_NOMUTEX ){ + isThreadsafe = 0; + }else if( flags & SQLITE_OPEN_FULLMUTEX ){ + isThreadsafe = 1; + }else{ + isThreadsafe = sqlite3GlobalConfig.bFullMutex; + } + if( flags & SQLITE_OPEN_PRIVATECACHE ){ + flags &= ~SQLITE_OPEN_SHAREDCACHE; + }else if( sqlite3GlobalConfig.sharedCacheEnabled ){ + flags |= SQLITE_OPEN_SHAREDCACHE; + } + + /* Remove harmful bits from the flags parameter + ** + ** The SQLITE_OPEN_NOMUTEX and SQLITE_OPEN_FULLMUTEX flags were + ** dealt with in the previous code block. Besides these, the only + ** valid input flags for sqlite3_open_v2() are SQLITE_OPEN_READONLY, + ** SQLITE_OPEN_READWRITE, SQLITE_OPEN_CREATE, SQLITE_OPEN_SHAREDCACHE, + ** SQLITE_OPEN_PRIVATECACHE, and some reserved bits. Silently mask + ** off all other flags. + */ + flags &= ~( SQLITE_OPEN_DELETEONCLOSE | + SQLITE_OPEN_EXCLUSIVE | + SQLITE_OPEN_MAIN_DB | + SQLITE_OPEN_TEMP_DB | + SQLITE_OPEN_TRANSIENT_DB | + SQLITE_OPEN_MAIN_JOURNAL | + SQLITE_OPEN_TEMP_JOURNAL | + SQLITE_OPEN_SUBJOURNAL | + SQLITE_OPEN_MASTER_JOURNAL | + SQLITE_OPEN_NOMUTEX | + SQLITE_OPEN_FULLMUTEX | + SQLITE_OPEN_WAL + ); + + /* Allocate the sqlite data structure */ + db = sqlite3MallocZero( sizeof(sqlite3) ); + if( db==0 ) goto opendb_out; + if( isThreadsafe ){ + db->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); + if( db->mutex==0 ){ + sqlite3_free(db); + db = 0; + goto opendb_out; + } + } + sqlite3_mutex_enter(db->mutex); + db->errMask = 0xff; + db->nDb = 2; + db->magic = SQLITE_MAGIC_BUSY; + db->aDb = db->aDbStatic; + + assert( sizeof(db->aLimit)==sizeof(aHardLimit) ); + memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit)); + db->autoCommit = 1; + db->nextAutovac = -1; + db->nextPagesize = 0; + db->flags |= SQLITE_ShortColNames | SQLITE_AutoIndex | SQLITE_EnableTrigger +#if SQLITE_DEFAULT_FILE_FORMAT<4 + | SQLITE_LegacyFileFmt +#endif +#ifdef SQLITE_ENABLE_LOAD_EXTENSION + | SQLITE_LoadExtension +#endif +#if SQLITE_DEFAULT_RECURSIVE_TRIGGERS + | SQLITE_RecTriggers +#endif +#if defined(SQLITE_DEFAULT_FOREIGN_KEYS) && SQLITE_DEFAULT_FOREIGN_KEYS + | SQLITE_ForeignKeys +#endif + ; + sqlite3HashInit(&db->aCollSeq); +#ifndef SQLITE_OMIT_VIRTUALTABLE + sqlite3HashInit(&db->aModule); +#endif + + /* Add the default collation sequence BINARY. BINARY works for both UTF-8 + ** and UTF-16, so add a version for each to avoid any unnecessary + ** conversions. The only error that can occur here is a malloc() failure. + */ + createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc, 0); + createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc, 0); + createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc, 0); + createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0); + if( db->mallocFailed ){ + goto opendb_out; + } + db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 0); + assert( db->pDfltColl!=0 ); + + /* Also add a UTF-8 case-insensitive collation sequence. */ + createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0); + + /* Parse the filename/URI argument. */ + db->openFlags = flags; + rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; + sqlite3Error(db, rc, zErrMsg ? "%s" : 0, zErrMsg); + sqlite3_free(zErrMsg); + goto opendb_out; + } + + /* Open the backend database driver */ + rc = sqlite3BtreeOpen(db->pVfs, zOpen, db, &db->aDb[0].pBt, 0, + flags | SQLITE_OPEN_MAIN_DB); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_IOERR_NOMEM ){ + rc = SQLITE_NOMEM; + } + sqlite3Error(db, rc, 0); + goto opendb_out; + } + db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt); + db->aDb[1].pSchema = sqlite3SchemaGet(db, 0); + + + /* The default safety_level for the main database is 'full'; for the temp + ** database it is 'NONE'. This matches the pager layer defaults. + */ + db->aDb[0].zName = "main"; + db->aDb[0].safety_level = 3; + db->aDb[1].zName = "temp"; + db->aDb[1].safety_level = 1; + + db->magic = SQLITE_MAGIC_OPEN; + if( db->mallocFailed ){ + goto opendb_out; + } + + /* Register all built-in functions, but do not attempt to read the + ** database schema yet. This is delayed until the first time the database + ** is accessed. + */ + sqlite3Error(db, SQLITE_OK, 0); + sqlite3RegisterBuiltinFunctions(db); + + /* Load automatic extensions - extensions that have been registered + ** using the sqlite3_automatic_extension() API. + */ + rc = sqlite3_errcode(db); + if( rc==SQLITE_OK ){ + sqlite3AutoLoadExtensions(db); + rc = sqlite3_errcode(db); + if( rc!=SQLITE_OK ){ + goto opendb_out; + } + } + +#ifdef SQLITE_ENABLE_FTS1 + if( !db->mallocFailed ){ + extern int sqlite3Fts1Init(sqlite3*); + rc = sqlite3Fts1Init(db); + } +#endif + +#ifdef SQLITE_ENABLE_FTS2 + if( !db->mallocFailed && rc==SQLITE_OK ){ + extern int sqlite3Fts2Init(sqlite3*); + rc = sqlite3Fts2Init(db); + } +#endif + +#ifdef SQLITE_ENABLE_FTS3 + if( !db->mallocFailed && rc==SQLITE_OK ){ + rc = sqlite3Fts3Init(db); + } +#endif + +#ifdef SQLITE_ENABLE_ICU + if( !db->mallocFailed && rc==SQLITE_OK ){ + rc = sqlite3IcuInit(db); + } +#endif + +#ifdef SQLITE_ENABLE_RTREE + if( !db->mallocFailed && rc==SQLITE_OK){ + rc = sqlite3RtreeInit(db); + } +#endif + + sqlite3Error(db, rc, 0); + + /* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking + ** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking + ** mode. Doing nothing at all also makes NORMAL the default. + */ +#ifdef SQLITE_DEFAULT_LOCKING_MODE + db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE; + sqlite3PagerLockingMode(sqlite3BtreePager(db->aDb[0].pBt), + SQLITE_DEFAULT_LOCKING_MODE); +#endif + + /* Enable the lookaside-malloc subsystem */ + setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside, + sqlite3GlobalConfig.nLookaside); + + sqlite3_wal_autocheckpoint(db, SQLITE_DEFAULT_WAL_AUTOCHECKPOINT); + +opendb_out: + sqlite3_free(zOpen); + if( db ){ + assert( db->mutex!=0 || isThreadsafe==0 || sqlite3GlobalConfig.bFullMutex==0 ); + sqlite3_mutex_leave(db->mutex); + } + rc = sqlite3_errcode(db); + assert( db!=0 || rc==SQLITE_NOMEM ); + if( rc==SQLITE_NOMEM ){ + sqlite3_close(db); + db = 0; + }else if( rc!=SQLITE_OK ){ + db->magic = SQLITE_MAGIC_SICK; + } + *ppDb = db; + return sqlite3ApiExit(0, rc); +} + +/* +** Open a new database handle. +*/ +int sqlite3_open( + const char *zFilename, + sqlite3 **ppDb +){ + return openDatabase(zFilename, ppDb, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0); +} +int sqlite3_open_v2( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs /* Name of VFS module to use */ +){ + return openDatabase(filename, ppDb, (unsigned int)flags, zVfs); +} + +#ifndef SQLITE_OMIT_UTF16 +/* +** Open a new database handle. +*/ +int sqlite3_open16( + const void *zFilename, + sqlite3 **ppDb +){ + char const *zFilename8; /* zFilename encoded in UTF-8 instead of UTF-16 */ + sqlite3_value *pVal; + int rc; + + assert( zFilename ); + assert( ppDb ); + *ppDb = 0; +#ifndef SQLITE_OMIT_AUTOINIT + rc = sqlite3_initialize(); + if( rc ) return rc; +#endif + pVal = sqlite3ValueNew(0); + sqlite3ValueSetStr(pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC); + zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8); + if( zFilename8 ){ + rc = openDatabase(zFilename8, ppDb, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0); + assert( *ppDb || rc==SQLITE_NOMEM ); + if( rc==SQLITE_OK && !DbHasProperty(*ppDb, 0, DB_SchemaLoaded) ){ + ENC(*ppDb) = SQLITE_UTF16NATIVE; + } + }else{ + rc = SQLITE_NOMEM; + } + sqlite3ValueFree(pVal); + + return sqlite3ApiExit(0, rc); +} +#endif /* SQLITE_OMIT_UTF16 */ + +/* +** Register a new collation sequence with the database handle db. +*/ +int sqlite3_create_collation( + sqlite3* db, + const char *zName, + int enc, + void* pCtx, + int(*xCompare)(void*,int,const void*,int,const void*) +){ + int rc; + sqlite3_mutex_enter(db->mutex); + assert( !db->mallocFailed ); + rc = createCollation(db, zName, (u8)enc, pCtx, xCompare, 0); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** Register a new collation sequence with the database handle db. +*/ +int sqlite3_create_collation_v2( + sqlite3* db, + const char *zName, + int enc, + void* pCtx, + int(*xCompare)(void*,int,const void*,int,const void*), + void(*xDel)(void*) +){ + int rc; + sqlite3_mutex_enter(db->mutex); + assert( !db->mallocFailed ); + rc = createCollation(db, zName, (u8)enc, pCtx, xCompare, xDel); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +#ifndef SQLITE_OMIT_UTF16 +/* +** Register a new collation sequence with the database handle db. +*/ +int sqlite3_create_collation16( + sqlite3* db, + const void *zName, + int enc, + void* pCtx, + int(*xCompare)(void*,int,const void*,int,const void*) +){ + int rc = SQLITE_OK; + char *zName8; + sqlite3_mutex_enter(db->mutex); + assert( !db->mallocFailed ); + zName8 = sqlite3Utf16to8(db, zName, -1, SQLITE_UTF16NATIVE); + if( zName8 ){ + rc = createCollation(db, zName8, (u8)enc, pCtx, xCompare, 0); + sqlite3DbFree(db, zName8); + } + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} +#endif /* SQLITE_OMIT_UTF16 */ + +/* +** Register a collation sequence factory callback with the database handle +** db. Replace any previously installed collation sequence factory. +*/ +int sqlite3_collation_needed( + sqlite3 *db, + void *pCollNeededArg, + void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*) +){ + sqlite3_mutex_enter(db->mutex); + db->xCollNeeded = xCollNeeded; + db->xCollNeeded16 = 0; + db->pCollNeededArg = pCollNeededArg; + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + +#ifndef SQLITE_OMIT_UTF16 +/* +** Register a collation sequence factory callback with the database handle +** db. Replace any previously installed collation sequence factory. +*/ +int sqlite3_collation_needed16( + sqlite3 *db, + void *pCollNeededArg, + void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*) +){ + sqlite3_mutex_enter(db->mutex); + db->xCollNeeded = 0; + db->xCollNeeded16 = xCollNeeded16; + db->pCollNeededArg = pCollNeededArg; + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} +#endif /* SQLITE_OMIT_UTF16 */ + +#ifndef SQLITE_OMIT_DEPRECATED +/* +** This function is now an anachronism. It used to be used to recover from a +** malloc() failure, but SQLite now does this automatically. +*/ +int sqlite3_global_recover(void){ + return SQLITE_OK; +} +#endif + +/* +** Test to see whether or not the database connection is in autocommit +** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on +** by default. Autocommit is disabled by a BEGIN statement and reenabled +** by the next COMMIT or ROLLBACK. +** +******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ****** +*/ +int sqlite3_get_autocommit(sqlite3 *db){ + return db->autoCommit; +} + +/* +** The following routines are subtitutes for constants SQLITE_CORRUPT, +** SQLITE_MISUSE, SQLITE_CANTOPEN, SQLITE_IOERR and possibly other error +** constants. They server two purposes: +** +** 1. Serve as a convenient place to set a breakpoint in a debugger +** to detect when version error conditions occurs. +** +** 2. Invoke sqlite3_log() to provide the source code location where +** a low-level error is first detected. +*/ +int sqlite3CorruptError(int lineno){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_CORRUPT, + "database corruption at line %d of [%.10s]", + lineno, 20+sqlite3_sourceid()); + return SQLITE_CORRUPT; +} +int sqlite3MisuseError(int lineno){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_MISUSE, + "misuse at line %d of [%.10s]", + lineno, 20+sqlite3_sourceid()); + return SQLITE_MISUSE; +} +int sqlite3CantopenError(int lineno){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_CANTOPEN, + "cannot open file at line %d of [%.10s]", + lineno, 20+sqlite3_sourceid()); + return SQLITE_CANTOPEN; +} + + +#ifndef SQLITE_OMIT_DEPRECATED +/* +** This is a convenience routine that makes sure that all thread-specific +** data for this thread has been deallocated. +** +** SQLite no longer uses thread-specific data so this routine is now a +** no-op. It is retained for historical compatibility. +*/ +void sqlite3_thread_cleanup(void){ +} +#endif + +/* +** Return meta information about a specific column of a database table. +** See comment in sqlite3.h (sqlite.h.in) for details. +*/ +#ifdef SQLITE_ENABLE_COLUMN_METADATA +int sqlite3_table_column_metadata( + sqlite3 *db, /* Connection handle */ + const char *zDbName, /* Database name or NULL */ + const char *zTableName, /* Table name */ + const char *zColumnName, /* Column name */ + char const **pzDataType, /* OUTPUT: Declared data type */ + char const **pzCollSeq, /* OUTPUT: Collation sequence name */ + int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ + int *pPrimaryKey, /* OUTPUT: True if column part of PK */ + int *pAutoinc /* OUTPUT: True if column is auto-increment */ +){ + int rc; + char *zErrMsg = 0; + Table *pTab = 0; + Column *pCol = 0; + int iCol; + + char const *zDataType = 0; + char const *zCollSeq = 0; + int notnull = 0; + int primarykey = 0; + int autoinc = 0; + + /* Ensure the database schema has been loaded */ + sqlite3_mutex_enter(db->mutex); + sqlite3BtreeEnterAll(db); + rc = sqlite3Init(db, &zErrMsg); + if( SQLITE_OK!=rc ){ + goto error_out; + } + + /* Locate the table in question */ + pTab = sqlite3FindTable(db, zTableName, zDbName); + if( !pTab || pTab->pSelect ){ + pTab = 0; + goto error_out; + } + + /* Find the column for which info is requested */ + if( sqlite3IsRowid(zColumnName) ){ + iCol = pTab->iPKey; + if( iCol>=0 ){ + pCol = &pTab->aCol[iCol]; + } + }else{ + for(iCol=0; iColnCol; iCol++){ + pCol = &pTab->aCol[iCol]; + if( 0==sqlite3StrICmp(pCol->zName, zColumnName) ){ + break; + } + } + if( iCol==pTab->nCol ){ + pTab = 0; + goto error_out; + } + } + + /* The following block stores the meta information that will be returned + ** to the caller in local variables zDataType, zCollSeq, notnull, primarykey + ** and autoinc. At this point there are two possibilities: + ** + ** 1. The specified column name was rowid", "oid" or "_rowid_" + ** and there is no explicitly declared IPK column. + ** + ** 2. The table is not a view and the column name identified an + ** explicitly declared column. Copy meta information from *pCol. + */ + if( pCol ){ + zDataType = pCol->zType; + zCollSeq = pCol->zColl; + notnull = pCol->notNull!=0; + primarykey = pCol->isPrimKey!=0; + autoinc = pTab->iPKey==iCol && (pTab->tabFlags & TF_Autoincrement)!=0; + }else{ + zDataType = "INTEGER"; + primarykey = 1; + } + if( !zCollSeq ){ + zCollSeq = "BINARY"; + } + +error_out: + sqlite3BtreeLeaveAll(db); + + /* Whether the function call succeeded or failed, set the output parameters + ** to whatever their local counterparts contain. If an error did occur, + ** this has the effect of zeroing all output parameters. + */ + if( pzDataType ) *pzDataType = zDataType; + if( pzCollSeq ) *pzCollSeq = zCollSeq; + if( pNotNull ) *pNotNull = notnull; + if( pPrimaryKey ) *pPrimaryKey = primarykey; + if( pAutoinc ) *pAutoinc = autoinc; + + if( SQLITE_OK==rc && !pTab ){ + sqlite3DbFree(db, zErrMsg); + zErrMsg = sqlite3MPrintf(db, "no such table column: %s.%s", zTableName, + zColumnName); + rc = SQLITE_ERROR; + } + sqlite3Error(db, rc, (zErrMsg?"%s":0), zErrMsg); + sqlite3DbFree(db, zErrMsg); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} +#endif + +/* +** Sleep for a little while. Return the amount of time slept. +*/ +int sqlite3_sleep(int ms){ + sqlite3_vfs *pVfs; + int rc; + pVfs = sqlite3_vfs_find(0); + if( pVfs==0 ) return 0; + + /* This function works in milliseconds, but the underlying OsSleep() + ** API uses microseconds. Hence the 1000's. + */ + rc = (sqlite3OsSleep(pVfs, 1000*ms)/1000); + return rc; +} + +/* +** Enable or disable the extended result codes. +*/ +int sqlite3_extended_result_codes(sqlite3 *db, int onoff){ + sqlite3_mutex_enter(db->mutex); + db->errMask = onoff ? 0xffffffff : 0xff; + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + +/* +** Invoke the xFileControl method on a particular database. +*/ +int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){ + int rc = SQLITE_ERROR; + int iDb; + sqlite3_mutex_enter(db->mutex); + if( zDbName==0 ){ + iDb = 0; + }else{ + for(iDb=0; iDbnDb; iDb++){ + if( strcmp(db->aDb[iDb].zName, zDbName)==0 ) break; + } + } + if( iDbnDb ){ + Btree *pBtree = db->aDb[iDb].pBt; + if( pBtree ){ + Pager *pPager; + sqlite3_file *fd; + sqlite3BtreeEnter(pBtree); + pPager = sqlite3BtreePager(pBtree); + assert( pPager!=0 ); + fd = sqlite3PagerFile(pPager); + assert( fd!=0 ); + if( op==SQLITE_FCNTL_FILE_POINTER ){ + *(sqlite3_file**)pArg = fd; + rc = SQLITE_OK; + }else if( fd->pMethods ){ + rc = sqlite3OsFileControl(fd, op, pArg); + }else{ + rc = SQLITE_NOTFOUND; + } + sqlite3BtreeLeave(pBtree); + } + } + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** Interface to the testing logic. +*/ +int sqlite3_test_control(int op, ...){ + int rc = 0; +#ifndef SQLITE_OMIT_BUILTIN_TEST + va_list ap; + va_start(ap, op); + switch( op ){ + + /* + ** Save the current state of the PRNG. + */ + case SQLITE_TESTCTRL_PRNG_SAVE: { + sqlite3PrngSaveState(); + break; + } + + /* + ** Restore the state of the PRNG to the last state saved using + ** PRNG_SAVE. If PRNG_SAVE has never before been called, then + ** this verb acts like PRNG_RESET. + */ + case SQLITE_TESTCTRL_PRNG_RESTORE: { + sqlite3PrngRestoreState(); + break; + } + + /* + ** Reset the PRNG back to its uninitialized state. The next call + ** to sqlite3_randomness() will reseed the PRNG using a single call + ** to the xRandomness method of the default VFS. + */ + case SQLITE_TESTCTRL_PRNG_RESET: { + sqlite3PrngResetState(); + break; + } + + /* + ** sqlite3_test_control(BITVEC_TEST, size, program) + ** + ** Run a test against a Bitvec object of size. The program argument + ** is an array of integers that defines the test. Return -1 on a + ** memory allocation error, 0 on success, or non-zero for an error. + ** See the sqlite3BitvecBuiltinTest() for additional information. + */ + case SQLITE_TESTCTRL_BITVEC_TEST: { + int sz = va_arg(ap, int); + int *aProg = va_arg(ap, int*); + rc = sqlite3BitvecBuiltinTest(sz, aProg); + break; + } + + /* + ** sqlite3_test_control(BENIGN_MALLOC_HOOKS, xBegin, xEnd) + ** + ** Register hooks to call to indicate which malloc() failures + ** are benign. + */ + case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: { + typedef void (*void_function)(void); + void_function xBenignBegin; + void_function xBenignEnd; + xBenignBegin = va_arg(ap, void_function); + xBenignEnd = va_arg(ap, void_function); + sqlite3BenignMallocHooks(xBenignBegin, xBenignEnd); + break; + } + + /* + ** sqlite3_test_control(SQLITE_TESTCTRL_PENDING_BYTE, unsigned int X) + ** + ** Set the PENDING byte to the value in the argument, if X>0. + ** Make no changes if X==0. Return the value of the pending byte + ** as it existing before this routine was called. + ** + ** IMPORTANT: Changing the PENDING byte from 0x40000000 results in + ** an incompatible database file format. Changing the PENDING byte + ** while any database connection is open results in undefined and + ** dileterious behavior. + */ + case SQLITE_TESTCTRL_PENDING_BYTE: { + rc = PENDING_BYTE; +#ifndef SQLITE_OMIT_WSD + { + unsigned int newVal = va_arg(ap, unsigned int); + if( newVal ) sqlite3PendingByte = newVal; + } +#endif + break; + } + + /* + ** sqlite3_test_control(SQLITE_TESTCTRL_ASSERT, int X) + ** + ** This action provides a run-time test to see whether or not + ** assert() was enabled at compile-time. If X is true and assert() + ** is enabled, then the return value is true. If X is true and + ** assert() is disabled, then the return value is zero. If X is + ** false and assert() is enabled, then the assertion fires and the + ** process aborts. If X is false and assert() is disabled, then the + ** return value is zero. + */ + case SQLITE_TESTCTRL_ASSERT: { + volatile int x = 0; + assert( (x = va_arg(ap,int))!=0 ); + rc = x; + break; + } + + + /* + ** sqlite3_test_control(SQLITE_TESTCTRL_ALWAYS, int X) + ** + ** This action provides a run-time test to see how the ALWAYS and + ** NEVER macros were defined at compile-time. + ** + ** The return value is ALWAYS(X). + ** + ** The recommended test is X==2. If the return value is 2, that means + ** ALWAYS() and NEVER() are both no-op pass-through macros, which is the + ** default setting. If the return value is 1, then ALWAYS() is either + ** hard-coded to true or else it asserts if its argument is false. + ** The first behavior (hard-coded to true) is the case if + ** SQLITE_TESTCTRL_ASSERT shows that assert() is disabled and the second + ** behavior (assert if the argument to ALWAYS() is false) is the case if + ** SQLITE_TESTCTRL_ASSERT shows that assert() is enabled. + ** + ** The run-time test procedure might look something like this: + ** + ** if( sqlite3_test_control(SQLITE_TESTCTRL_ALWAYS, 2)==2 ){ + ** // ALWAYS() and NEVER() are no-op pass-through macros + ** }else if( sqlite3_test_control(SQLITE_TESTCTRL_ASSERT, 1) ){ + ** // ALWAYS(x) asserts that x is true. NEVER(x) asserts x is false. + ** }else{ + ** // ALWAYS(x) is a constant 1. NEVER(x) is a constant 0. + ** } + */ + case SQLITE_TESTCTRL_ALWAYS: { + int x = va_arg(ap,int); + rc = ALWAYS(x); + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_RESERVE, sqlite3 *db, int N) + ** + ** Set the nReserve size to N for the main database on the database + ** connection db. + */ + case SQLITE_TESTCTRL_RESERVE: { + sqlite3 *db = va_arg(ap, sqlite3*); + int x = va_arg(ap,int); + sqlite3_mutex_enter(db->mutex); + sqlite3BtreeSetPageSize(db->aDb[0].pBt, 0, x, 0); + sqlite3_mutex_leave(db->mutex); + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, sqlite3 *db, int N) + ** + ** Enable or disable various optimizations for testing purposes. The + ** argument N is a bitmask of optimizations to be disabled. For normal + ** operation N should be 0. The idea is that a test program (like the + ** SQL Logic Test or SLT test module) can run the same SQL multiple times + ** with various optimizations disabled to verify that the same answer + ** is obtained in every case. + */ + case SQLITE_TESTCTRL_OPTIMIZATIONS: { + sqlite3 *db = va_arg(ap, sqlite3*); + int x = va_arg(ap,int); + db->flags = (x & SQLITE_OptMask) | (db->flags & ~SQLITE_OptMask); + break; + } + +#ifdef SQLITE_N_KEYWORD + /* sqlite3_test_control(SQLITE_TESTCTRL_ISKEYWORD, const char *zWord) + ** + ** If zWord is a keyword recognized by the parser, then return the + ** number of keywords. Or if zWord is not a keyword, return 0. + ** + ** This test feature is only available in the amalgamation since + ** the SQLITE_N_KEYWORD macro is not defined in this file if SQLite + ** is built using separate source files. + */ + case SQLITE_TESTCTRL_ISKEYWORD: { + const char *zWord = va_arg(ap, const char*); + int n = sqlite3Strlen30(zWord); + rc = (sqlite3KeywordCode((u8*)zWord, n)!=TK_ID) ? SQLITE_N_KEYWORD : 0; + break; + } +#endif + + /* sqlite3_test_control(SQLITE_TESTCTRL_SCRATCHMALLOC, sz, &pNew, pFree); + ** + ** Pass pFree into sqlite3ScratchFree(). + ** If sz>0 then allocate a scratch buffer into pNew. + */ + case SQLITE_TESTCTRL_SCRATCHMALLOC: { + void *pFree, **ppNew; + int sz; + sz = va_arg(ap, int); + ppNew = va_arg(ap, void**); + pFree = va_arg(ap, void*); + if( sz ) *ppNew = sqlite3ScratchMalloc(sz); + sqlite3ScratchFree(pFree); + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff); + ** + ** If parameter onoff is non-zero, configure the wrappers so that all + ** subsequent calls to localtime() and variants fail. If onoff is zero, + ** undo this setting. + */ + case SQLITE_TESTCTRL_LOCALTIME_FAULT: { + sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int); + break; + } + +#if defined(SQLITE_ENABLE_TREE_EXPLAIN) + /* sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, + ** sqlite3_stmt*,const char**); + ** + ** If compiled with SQLITE_ENABLE_TREE_EXPLAIN, each sqlite3_stmt holds + ** a string that describes the optimized parse tree. This test-control + ** returns a pointer to that string. + */ + case SQLITE_TESTCTRL_EXPLAIN_STMT: { + sqlite3_stmt *pStmt = va_arg(ap, sqlite3_stmt*); + const char **pzRet = va_arg(ap, const char**); + *pzRet = sqlite3VdbeExplanation((Vdbe*)pStmt); + break; + } +#endif + + } + va_end(ap); +#endif /* SQLITE_OMIT_BUILTIN_TEST */ + return rc; +} + +/* +** This is a utility routine, useful to VFS implementations, that checks +** to see if a database file was a URI that contained a specific query +** parameter, and if so obtains the value of the query parameter. +** +** The zFilename argument is the filename pointer passed into the xOpen() +** method of a VFS implementation. The zParam argument is the name of the +** query parameter we seek. This routine returns the value of the zParam +** parameter if it exists. If the parameter does not exist, this routine +** returns a NULL pointer. +*/ +const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){ + if( zFilename==0 ) return 0; + zFilename += sqlite3Strlen30(zFilename) + 1; + while( zFilename[0] ){ + int x = strcmp(zFilename, zParam); + zFilename += sqlite3Strlen30(zFilename) + 1; + if( x==0 ) return zFilename; + zFilename += sqlite3Strlen30(zFilename) + 1; + } + return 0; +} + +/* +** Return a boolean value for a query parameter. +*/ +int sqlite3_uri_boolean(const char *zFilename, const char *zParam, int bDflt){ + const char *z = sqlite3_uri_parameter(zFilename, zParam); + return z ? sqlite3GetBoolean(z) : (bDflt!=0); +} + +/* +** Return a 64-bit integer value for a query parameter. +*/ +sqlite3_int64 sqlite3_uri_int64( + const char *zFilename, /* Filename as passed to xOpen */ + const char *zParam, /* URI parameter sought */ + sqlite3_int64 bDflt /* return if parameter is missing */ +){ + const char *z = sqlite3_uri_parameter(zFilename, zParam); + sqlite3_int64 v; + if( z && sqlite3Atoi64(z, &v, sqlite3Strlen30(z), SQLITE_UTF8)==SQLITE_OK ){ + bDflt = v; + } + return bDflt; +} + +/* +** Return the filename of the database associated with a database +** connection. +*/ +const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){ + int i; + for(i=0; inDb; i++){ + if( db->aDb[i].pBt && sqlite3StrICmp(zDbName, db->aDb[i].zName)==0 ){ + return sqlite3BtreeGetFilename(db->aDb[i].pBt); + } + } + return 0; +} diff --git a/scalos/libraries/sqlite/src/malloc.c b/scalos/libraries/sqlite/src/malloc.c new file mode 100644 index 000000000..29c6b0dcd --- /dev/null +++ b/scalos/libraries/sqlite/src/malloc.c @@ -0,0 +1,778 @@ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** Memory allocation functions used throughout sqlite. +*/ +#include "sqliteInt.h" +#include + +/* +** Attempt to release up to n bytes of non-essential memory currently +** held by SQLite. An example of non-essential memory is memory used to +** cache database pages that are not currently in use. +*/ +int sqlite3_release_memory(int n){ +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT + return sqlite3PcacheReleaseMemory(n); +#else + /* IMPLEMENTATION-OF: R-34391-24921 The sqlite3_release_memory() routine + ** is a no-op returning zero if SQLite is not compiled with + ** SQLITE_ENABLE_MEMORY_MANAGEMENT. */ + UNUSED_PARAMETER(n); + return 0; +#endif +} + +/* +** An instance of the following object records the location of +** each unused scratch buffer. +*/ +typedef struct ScratchFreeslot { + struct ScratchFreeslot *pNext; /* Next unused scratch buffer */ +} ScratchFreeslot; + +/* +** State information local to the memory allocation subsystem. +*/ +static SQLITE_WSD struct Mem0Global { + sqlite3_mutex *mutex; /* Mutex to serialize access */ + + /* + ** The alarm callback and its arguments. The mem0.mutex lock will + ** be held while the callback is running. Recursive calls into + ** the memory subsystem are allowed, but no new callbacks will be + ** issued. + */ + sqlite3_int64 alarmThreshold; + void (*alarmCallback)(void*, sqlite3_int64,int); + void *alarmArg; + + /* + ** Pointers to the end of sqlite3GlobalConfig.pScratch memory + ** (so that a range test can be used to determine if an allocation + ** being freed came from pScratch) and a pointer to the list of + ** unused scratch allocations. + */ + void *pScratchEnd; + ScratchFreeslot *pScratchFree; + u32 nScratchFree; + + /* + ** True if heap is nearly "full" where "full" is defined by the + ** sqlite3_soft_heap_limit() setting. + */ + int nearlyFull; +} mem0 = { 0, 0, 0, 0, 0, 0, 0, 0 }; + +#define mem0 GLOBAL(struct Mem0Global, mem0) + +/* +** This routine runs when the memory allocator sees that the +** total memory allocation is about to exceed the soft heap +** limit. +*/ +static void softHeapLimitEnforcer( + void *NotUsed, + sqlite3_int64 NotUsed2, + int allocSize +){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + sqlite3_release_memory(allocSize); +} + +/* +** Change the alarm callback +*/ +static int sqlite3MemoryAlarm( + void(*xCallback)(void *pArg, sqlite3_int64 used,int N), + void *pArg, + sqlite3_int64 iThreshold +){ + int nUsed; + sqlite3_mutex_enter(mem0.mutex); + mem0.alarmCallback = xCallback; + mem0.alarmArg = pArg; + mem0.alarmThreshold = iThreshold; + nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); + mem0.nearlyFull = (iThreshold>0 && iThreshold<=nUsed); + sqlite3_mutex_leave(mem0.mutex); + return SQLITE_OK; +} + +#ifndef SQLITE_OMIT_DEPRECATED +/* +** Deprecated external interface. Internal/core SQLite code +** should call sqlite3MemoryAlarm. +*/ +int sqlite3_memory_alarm( + void(*xCallback)(void *pArg, sqlite3_int64 used,int N), + void *pArg, + sqlite3_int64 iThreshold +){ + return sqlite3MemoryAlarm(xCallback, pArg, iThreshold); +} +#endif + +/* +** Set the soft heap-size limit for the library. Passing a zero or +** negative value indicates no limit. +*/ +sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){ + sqlite3_int64 priorLimit; + sqlite3_int64 excess; +#ifndef SQLITE_OMIT_AUTOINIT + int rc = sqlite3_initialize(); + if( rc ) return -1; +#endif + sqlite3_mutex_enter(mem0.mutex); + priorLimit = mem0.alarmThreshold; + sqlite3_mutex_leave(mem0.mutex); + if( n<0 ) return priorLimit; + if( n>0 ){ + sqlite3MemoryAlarm(softHeapLimitEnforcer, 0, n); + }else{ + sqlite3MemoryAlarm(0, 0, 0); + } + excess = sqlite3_memory_used() - n; + if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff)); + return priorLimit; +} +void sqlite3_soft_heap_limit(int n){ + if( n<0 ) n = 0; + sqlite3_soft_heap_limit64(n); +} + +/* +** Initialize the memory allocation subsystem. +*/ +int sqlite3MallocInit(void){ + if( sqlite3GlobalConfig.m.xMalloc==0 ){ + sqlite3MemSetDefault(); + } + memset(&mem0, 0, sizeof(mem0)); + if( sqlite3GlobalConfig.bCoreMutex ){ + mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); + } + if( sqlite3GlobalConfig.pScratch && sqlite3GlobalConfig.szScratch>=100 + && sqlite3GlobalConfig.nScratch>0 ){ + int i, n, sz; + ScratchFreeslot *pSlot; + sz = ROUNDDOWN8(sqlite3GlobalConfig.szScratch); + sqlite3GlobalConfig.szScratch = sz; + pSlot = (ScratchFreeslot*)sqlite3GlobalConfig.pScratch; + n = sqlite3GlobalConfig.nScratch; + mem0.pScratchFree = pSlot; + mem0.nScratchFree = n; + for(i=0; ipNext = (ScratchFreeslot*)(sz+(char*)pSlot); + pSlot = pSlot->pNext; + } + pSlot->pNext = 0; + mem0.pScratchEnd = (void*)&pSlot[1]; + }else{ + mem0.pScratchEnd = 0; + sqlite3GlobalConfig.pScratch = 0; + sqlite3GlobalConfig.szScratch = 0; + sqlite3GlobalConfig.nScratch = 0; + } + if( sqlite3GlobalConfig.pPage==0 || sqlite3GlobalConfig.szPage<512 + || sqlite3GlobalConfig.nPage<1 ){ + sqlite3GlobalConfig.pPage = 0; + sqlite3GlobalConfig.szPage = 0; + sqlite3GlobalConfig.nPage = 0; + } + return sqlite3GlobalConfig.m.xInit(sqlite3GlobalConfig.m.pAppData); +} + +/* +** Return true if the heap is currently under memory pressure - in other +** words if the amount of heap used is close to the limit set by +** sqlite3_soft_heap_limit(). +*/ +int sqlite3HeapNearlyFull(void){ + return mem0.nearlyFull; +} + +/* +** Deinitialize the memory allocation subsystem. +*/ +void sqlite3MallocEnd(void){ + if( sqlite3GlobalConfig.m.xShutdown ){ + sqlite3GlobalConfig.m.xShutdown(sqlite3GlobalConfig.m.pAppData); + } + memset(&mem0, 0, sizeof(mem0)); +} + +/* +** Return the amount of memory currently checked out. +*/ +sqlite3_int64 sqlite3_memory_used(void){ + int n, mx; + sqlite3_int64 res; + sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, 0); + res = (sqlite3_int64)n; /* Work around bug in Borland C. Ticket #3216 */ + return res; +} + +/* +** Return the maximum amount of memory that has ever been +** checked out since either the beginning of this process +** or since the most recent reset. +*/ +sqlite3_int64 sqlite3_memory_highwater(int resetFlag){ + int n, mx; + sqlite3_int64 res; + sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, resetFlag); + res = (sqlite3_int64)mx; /* Work around bug in Borland C. Ticket #3216 */ + return res; +} + +/* +** Trigger the alarm +*/ +static void sqlite3MallocAlarm(int nByte){ + void (*xCallback)(void*,sqlite3_int64,int); + sqlite3_int64 nowUsed; + void *pArg; + if( mem0.alarmCallback==0 ) return; + xCallback = mem0.alarmCallback; + nowUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); + pArg = mem0.alarmArg; + mem0.alarmCallback = 0; + sqlite3_mutex_leave(mem0.mutex); + xCallback(pArg, nowUsed, nByte); + sqlite3_mutex_enter(mem0.mutex); + mem0.alarmCallback = xCallback; + mem0.alarmArg = pArg; +} + +/* +** Do a memory allocation with statistics and alarms. Assume the +** lock is already held. +*/ +static int mallocWithAlarm(int n, void **pp){ + int nFull; + void *p; + assert( sqlite3_mutex_held(mem0.mutex) ); + nFull = sqlite3GlobalConfig.m.xRoundup(n); + sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, n); + if( mem0.alarmCallback!=0 ){ + int nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); + if( nUsed >= mem0.alarmThreshold - nFull ){ + mem0.nearlyFull = 1; + sqlite3MallocAlarm(nFull); + }else{ + mem0.nearlyFull = 0; + } + } + p = sqlite3GlobalConfig.m.xMalloc(nFull); +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT + if( p==0 && mem0.alarmCallback ){ + sqlite3MallocAlarm(nFull); + p = sqlite3GlobalConfig.m.xMalloc(nFull); + } +#endif + if( p ){ + nFull = sqlite3MallocSize(p); + sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nFull); + sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, 1); + } + *pp = p; + return nFull; +} + +/* +** Allocate memory. This routine is like sqlite3_malloc() except that it +** assumes the memory subsystem has already been initialized. +*/ +void *sqlite3Malloc(int n){ + void *p; + if( n<=0 /* IMP: R-65312-04917 */ + || n>=0x7fffff00 + ){ + /* A memory allocation of a number of bytes which is near the maximum + ** signed integer value might cause an integer overflow inside of the + ** xMalloc(). Hence we limit the maximum size to 0x7fffff00, giving + ** 255 bytes of overhead. SQLite itself will never use anything near + ** this amount. The only way to reach the limit is with sqlite3_malloc() */ + p = 0; + }else if( sqlite3GlobalConfig.bMemstat ){ + sqlite3_mutex_enter(mem0.mutex); + mallocWithAlarm(n, &p); + sqlite3_mutex_leave(mem0.mutex); + }else{ + p = sqlite3GlobalConfig.m.xMalloc(n); + } + assert( EIGHT_BYTE_ALIGNMENT(p) ); /* IMP: R-04675-44850 */ + return p; +} + +/* +** This version of the memory allocation is for use by the application. +** First make sure the memory subsystem is initialized, then do the +** allocation. +*/ +void *sqlite3_malloc(int n){ +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return sqlite3Malloc(n); +} + +/* +** Each thread may only have a single outstanding allocation from +** xScratchMalloc(). We verify this constraint in the single-threaded +** case by setting scratchAllocOut to 1 when an allocation +** is outstanding clearing it when the allocation is freed. +*/ +#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) +static int scratchAllocOut = 0; +#endif + + +/* +** Allocate memory that is to be used and released right away. +** This routine is similar to alloca() in that it is not intended +** for situations where the memory might be held long-term. This +** routine is intended to get memory to old large transient data +** structures that would not normally fit on the stack of an +** embedded processor. +*/ +void *sqlite3ScratchMalloc(int n){ + void *p; + assert( n>0 ); + + sqlite3_mutex_enter(mem0.mutex); + if( mem0.nScratchFree && sqlite3GlobalConfig.szScratch>=n ){ + p = mem0.pScratchFree; + mem0.pScratchFree = mem0.pScratchFree->pNext; + mem0.nScratchFree--; + sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, 1); + sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n); + sqlite3_mutex_leave(mem0.mutex); + }else{ + if( sqlite3GlobalConfig.bMemstat ){ + sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n); + n = mallocWithAlarm(n, &p); + if( p ) sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, n); + sqlite3_mutex_leave(mem0.mutex); + }else{ + sqlite3_mutex_leave(mem0.mutex); + p = sqlite3GlobalConfig.m.xMalloc(n); + } + sqlite3MemdebugSetType(p, MEMTYPE_SCRATCH); + } + assert( sqlite3_mutex_notheld(mem0.mutex) ); + + +#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) + /* Verify that no more than two scratch allocations per thread + ** are outstanding at one time. (This is only checked in the + ** single-threaded case since checking in the multi-threaded case + ** would be much more complicated.) */ + assert( scratchAllocOut<=1 ); + if( p ) scratchAllocOut++; +#endif + + return p; +} +void sqlite3ScratchFree(void *p){ + if( p ){ + +#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) + /* Verify that no more than two scratch allocation per thread + ** is outstanding at one time. (This is only checked in the + ** single-threaded case since checking in the multi-threaded case + ** would be much more complicated.) */ + assert( scratchAllocOut>=1 && scratchAllocOut<=2 ); + scratchAllocOut--; +#endif + + if( p>=sqlite3GlobalConfig.pScratch && ppNext = mem0.pScratchFree; + mem0.pScratchFree = pSlot; + mem0.nScratchFree++; + assert( mem0.nScratchFree <= (u32)sqlite3GlobalConfig.nScratch ); + sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, -1); + sqlite3_mutex_leave(mem0.mutex); + }else{ + /* Release memory back to the heap */ + assert( sqlite3MemdebugHasType(p, MEMTYPE_SCRATCH) ); + assert( sqlite3MemdebugNoType(p, ~MEMTYPE_SCRATCH) ); + sqlite3MemdebugSetType(p, MEMTYPE_HEAP); + if( sqlite3GlobalConfig.bMemstat ){ + int iSize = sqlite3MallocSize(p); + sqlite3_mutex_enter(mem0.mutex); + sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, -iSize); + sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -iSize); + sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1); + sqlite3GlobalConfig.m.xFree(p); + sqlite3_mutex_leave(mem0.mutex); + }else{ + sqlite3GlobalConfig.m.xFree(p); + } + } + } +} + +/* +** TRUE if p is a lookaside memory allocation from db +*/ +#ifndef SQLITE_OMIT_LOOKASIDE +static int isLookaside(sqlite3 *db, void *p){ + return p && p>=db->lookaside.pStart && plookaside.pEnd; +} +#else +#define isLookaside(A,B) 0 +#endif + +/* +** Return the size of a memory allocation previously obtained from +** sqlite3Malloc() or sqlite3_malloc(). +*/ +int sqlite3MallocSize(void *p){ + assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); + assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) ); + return sqlite3GlobalConfig.m.xSize(p); +} +int sqlite3DbMallocSize(sqlite3 *db, void *p){ + assert( db==0 || sqlite3_mutex_held(db->mutex) ); + if( db && isLookaside(db, p) ){ + return db->lookaside.sz; + }else{ + assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) ); + assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) ); + assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); + return sqlite3GlobalConfig.m.xSize(p); + } +} + +/* +** Free memory previously obtained from sqlite3Malloc(). +*/ +void sqlite3_free(void *p){ + if( p==0 ) return; /* IMP: R-49053-54554 */ + assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) ); + assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); + if( sqlite3GlobalConfig.bMemstat ){ + sqlite3_mutex_enter(mem0.mutex); + sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize(p)); + sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1); + sqlite3GlobalConfig.m.xFree(p); + sqlite3_mutex_leave(mem0.mutex); + }else{ + sqlite3GlobalConfig.m.xFree(p); + } +} + +/* +** Free memory that might be associated with a particular database +** connection. +*/ +void sqlite3DbFree(sqlite3 *db, void *p){ + assert( db==0 || sqlite3_mutex_held(db->mutex) ); + if( db ){ + if( db->pnBytesFreed ){ + *db->pnBytesFreed += sqlite3DbMallocSize(db, p); + return; + } + if( isLookaside(db, p) ){ + LookasideSlot *pBuf = (LookasideSlot*)p; + pBuf->pNext = db->lookaside.pFree; + db->lookaside.pFree = pBuf; + db->lookaside.nOut--; + return; + } + } + assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) ); + assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) ); + assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); + sqlite3MemdebugSetType(p, MEMTYPE_HEAP); + sqlite3_free(p); +} + +/* +** Change the size of an existing memory allocation +*/ +void *sqlite3Realloc(void *pOld, int nBytes){ + int nOld, nNew, nDiff; + void *pNew; + if( pOld==0 ){ + return sqlite3Malloc(nBytes); /* IMP: R-28354-25769 */ + } + if( nBytes<=0 ){ + sqlite3_free(pOld); /* IMP: R-31593-10574 */ + return 0; + } + if( nBytes>=0x7fffff00 ){ + /* The 0x7ffff00 limit term is explained in comments on sqlite3Malloc() */ + return 0; + } + nOld = sqlite3MallocSize(pOld); + /* IMPLEMENTATION-OF: R-46199-30249 SQLite guarantees that the second + ** argument to xRealloc is always a value returned by a prior call to + ** xRoundup. */ + nNew = sqlite3GlobalConfig.m.xRoundup(nBytes); + if( nOld==nNew ){ + pNew = pOld; + }else if( sqlite3GlobalConfig.bMemstat ){ + sqlite3_mutex_enter(mem0.mutex); + sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, nBytes); + nDiff = nNew - nOld; + if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >= + mem0.alarmThreshold-nDiff ){ + sqlite3MallocAlarm(nDiff); + } + assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) ); + assert( sqlite3MemdebugNoType(pOld, ~MEMTYPE_HEAP) ); + pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); + if( pNew==0 && mem0.alarmCallback ){ + sqlite3MallocAlarm(nBytes); + pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); + } + if( pNew ){ + nNew = sqlite3MallocSize(pNew); + sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nNew-nOld); + } + sqlite3_mutex_leave(mem0.mutex); + }else{ + pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); + } + assert( EIGHT_BYTE_ALIGNMENT(pNew) ); /* IMP: R-04675-44850 */ + return pNew; +} + +/* +** The public interface to sqlite3Realloc. Make sure that the memory +** subsystem is initialized prior to invoking sqliteRealloc. +*/ +void *sqlite3_realloc(void *pOld, int n){ +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return sqlite3Realloc(pOld, n); +} + + +/* +** Allocate and zero memory. +*/ +void *sqlite3MallocZero(int n){ + void *p = sqlite3Malloc(n); + if( p ){ + memset(p, 0, n); + } + return p; +} + +/* +** Allocate and zero memory. If the allocation fails, make +** the mallocFailed flag in the connection pointer. +*/ +void *sqlite3DbMallocZero(sqlite3 *db, int n){ + void *p = sqlite3DbMallocRaw(db, n); + if( p ){ + memset(p, 0, n); + } + return p; +} + +/* +** Allocate and zero memory. If the allocation fails, make +** the mallocFailed flag in the connection pointer. +** +** If db!=0 and db->mallocFailed is true (indicating a prior malloc +** failure on the same database connection) then always return 0. +** Hence for a particular database connection, once malloc starts +** failing, it fails consistently until mallocFailed is reset. +** This is an important assumption. There are many places in the +** code that do things like this: +** +** int *a = (int*)sqlite3DbMallocRaw(db, 100); +** int *b = (int*)sqlite3DbMallocRaw(db, 200); +** if( b ) a[10] = 9; +** +** In other words, if a subsequent malloc (ex: "b") worked, it is assumed +** that all prior mallocs (ex: "a") worked too. +*/ +void *sqlite3DbMallocRaw(sqlite3 *db, int n){ + void *p; + assert( db==0 || sqlite3_mutex_held(db->mutex) ); + assert( db==0 || db->pnBytesFreed==0 ); +#ifndef SQLITE_OMIT_LOOKASIDE + if( db ){ + LookasideSlot *pBuf; + if( db->mallocFailed ){ + return 0; + } + if( db->lookaside.bEnabled ){ + if( n>db->lookaside.sz ){ + db->lookaside.anStat[1]++; + }else if( (pBuf = db->lookaside.pFree)==0 ){ + db->lookaside.anStat[2]++; + }else{ + db->lookaside.pFree = pBuf->pNext; + db->lookaside.nOut++; + db->lookaside.anStat[0]++; + if( db->lookaside.nOut>db->lookaside.mxOut ){ + db->lookaside.mxOut = db->lookaside.nOut; + } + return (void*)pBuf; + } + } + } +#else + if( db && db->mallocFailed ){ + return 0; + } +#endif + p = sqlite3Malloc(n); + if( !p && db ){ + db->mallocFailed = 1; + } + sqlite3MemdebugSetType(p, MEMTYPE_DB | + ((db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP)); + return p; +} + +/* +** Resize the block of memory pointed to by p to n bytes. If the +** resize fails, set the mallocFailed flag in the connection object. +*/ +void *sqlite3DbRealloc(sqlite3 *db, void *p, int n){ + void *pNew = 0; + assert( db!=0 ); + assert( sqlite3_mutex_held(db->mutex) ); + if( db->mallocFailed==0 ){ + if( p==0 ){ + return sqlite3DbMallocRaw(db, n); + } + if( isLookaside(db, p) ){ + if( n<=db->lookaside.sz ){ + return p; + } + pNew = sqlite3DbMallocRaw(db, n); + if( pNew ){ + memcpy(pNew, p, db->lookaside.sz); + sqlite3DbFree(db, p); + } + }else{ + assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) ); + assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) ); + sqlite3MemdebugSetType(p, MEMTYPE_HEAP); + pNew = sqlite3_realloc(p, n); + if( !pNew ){ + sqlite3MemdebugSetType(p, MEMTYPE_DB|MEMTYPE_HEAP); + db->mallocFailed = 1; + } + sqlite3MemdebugSetType(pNew, MEMTYPE_DB | + (db->lookaside.bEnabled ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP)); + } + } + return pNew; +} + +/* +** Attempt to reallocate p. If the reallocation fails, then free p +** and set the mallocFailed flag in the database connection. +*/ +void *sqlite3DbReallocOrFree(sqlite3 *db, void *p, int n){ + void *pNew; + pNew = sqlite3DbRealloc(db, p, n); + if( !pNew ){ + sqlite3DbFree(db, p); + } + return pNew; +} + +/* +** Make a copy of a string in memory obtained from sqliteMalloc(). These +** functions call sqlite3MallocRaw() directly instead of sqliteMalloc(). This +** is because when memory debugging is turned on, these two functions are +** called via macros that record the current file and line number in the +** ThreadData structure. +*/ +char *sqlite3DbStrDup(sqlite3 *db, const char *z){ + char *zNew; + size_t n; + if( z==0 ){ + return 0; + } + n = sqlite3Strlen30(z) + 1; + assert( (n&0x7fffffff)==n ); + zNew = sqlite3DbMallocRaw(db, (int)n); + if( zNew ){ + memcpy(zNew, z, n); + } + return zNew; +} +char *sqlite3DbStrNDup(sqlite3 *db, const char *z, int n){ + char *zNew; + if( z==0 ){ + return 0; + } + assert( (n&0x7fffffff)==n ); + zNew = sqlite3DbMallocRaw(db, n+1); + if( zNew ){ + memcpy(zNew, z, n); + zNew[n] = 0; + } + return zNew; +} + +/* +** Create a string from the zFromat argument and the va_list that follows. +** Store the string in memory obtained from sqliteMalloc() and make *pz +** point to that string. +*/ +void sqlite3SetString(char **pz, sqlite3 *db, const char *zFormat, ...){ + va_list ap; + char *z; + + va_start(ap, zFormat); + z = sqlite3VMPrintf(db, zFormat, ap); + va_end(ap); + sqlite3DbFree(db, *pz); + *pz = z; +} + + +/* +** This function must be called before exiting any API function (i.e. +** returning control to the user) that has called sqlite3_malloc or +** sqlite3_realloc. +** +** The returned value is normally a copy of the second argument to this +** function. However, if a malloc() failure has occurred since the previous +** invocation SQLITE_NOMEM is returned instead. +** +** If the first argument, db, is not NULL and a malloc() error has occurred, +** then the connection error-code (the value returned by sqlite3_errcode()) +** is set to SQLITE_NOMEM. +*/ +int sqlite3ApiExit(sqlite3* db, int rc){ + /* If the db handle is not NULL, then we must hold the connection handle + ** mutex here. Otherwise the read (and possible write) of db->mallocFailed + ** is unsafe, as is the call to sqlite3Error(). + */ + assert( !db || sqlite3_mutex_held(db->mutex) ); + if( db && (db->mallocFailed || rc==SQLITE_IOERR_NOMEM) ){ + sqlite3Error(db, SQLITE_NOMEM, 0); + db->mallocFailed = 0; + rc = SQLITE_NOMEM; + } + return rc & (db ? db->errMask : 0xff); +} diff --git a/scalos/libraries/sqlite/src/mem0.c b/scalos/libraries/sqlite/src/mem0.c new file mode 100644 index 000000000..0d0b6667d --- /dev/null +++ b/scalos/libraries/sqlite/src/mem0.c @@ -0,0 +1,59 @@ +/* +** 2008 October 28 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains a no-op memory allocation drivers for use when +** SQLITE_ZERO_MALLOC is defined. The allocation drivers implemented +** here always fail. SQLite will not operate with these drivers. These +** are merely placeholders. Real drivers must be substituted using +** sqlite3_config() before SQLite will operate. +*/ +#include "sqliteInt.h" + +/* +** This version of the memory allocator is the default. It is +** used when no other memory allocator is specified using compile-time +** macros. +*/ +#ifdef SQLITE_ZERO_MALLOC + +/* +** No-op versions of all memory allocation routines +*/ +static void *sqlite3MemMalloc(int nByte){ return 0; } +static void sqlite3MemFree(void *pPrior){ return; } +static void *sqlite3MemRealloc(void *pPrior, int nByte){ return 0; } +static int sqlite3MemSize(void *pPrior){ return 0; } +static int sqlite3MemRoundup(int n){ return n; } +static int sqlite3MemInit(void *NotUsed){ return SQLITE_OK; } +static void sqlite3MemShutdown(void *NotUsed){ return; } + +/* +** This routine is the only routine in this file with external linkage. +** +** Populate the low-level memory allocation function pointers in +** sqlite3GlobalConfig.m with pointers to the routines in this file. +*/ +void sqlite3MemSetDefault(void){ + static const sqlite3_mem_methods defaultMethods = { + sqlite3MemMalloc, + sqlite3MemFree, + sqlite3MemRealloc, + sqlite3MemSize, + sqlite3MemRoundup, + sqlite3MemInit, + sqlite3MemShutdown, + 0 + }; + sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods); +} + +#endif /* SQLITE_ZERO_MALLOC */ diff --git a/scalos/libraries/sqlite/src/mem1.c b/scalos/libraries/sqlite/src/mem1.c new file mode 100644 index 000000000..bf84ce090 --- /dev/null +++ b/scalos/libraries/sqlite/src/mem1.c @@ -0,0 +1,247 @@ +/* +** 2007 August 14 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains low-level memory allocation drivers for when +** SQLite will use the standard C-library malloc/realloc/free interface +** to obtain the memory it needs. +** +** This file contains implementations of the low-level memory allocation +** routines specified in the sqlite3_mem_methods object. +*/ +#include "sqliteInt.h" + +/* +** This version of the memory allocator is the default. It is +** used when no other memory allocator is specified using compile-time +** macros. +*/ +#ifdef SQLITE_SYSTEM_MALLOC + +/* +** Windows systems have malloc_usable_size() but it is called _msize() +*/ +#if !defined(HAVE_MALLOC_USABLE_SIZE) && SQLITE_OS_WIN +# define HAVE_MALLOC_USABLE_SIZE 1 +# define malloc_usable_size _msize +#endif + +#if defined(__APPLE__) + +/* +** Use the zone allocator available on apple products +*/ +#include +#include +#include +static malloc_zone_t* _sqliteZone_; +#define SQLITE_MALLOC(x) malloc_zone_malloc(_sqliteZone_, (x)) +#define SQLITE_FREE(x) malloc_zone_free(_sqliteZone_, (x)); +#define SQLITE_REALLOC(x,y) malloc_zone_realloc(_sqliteZone_, (x), (y)) +#define SQLITE_MALLOCSIZE(x) \ + (_sqliteZone_ ? _sqliteZone_->size(_sqliteZone_,x) : malloc_size(x)) + +#else /* if not __APPLE__ */ + +/* +** Use standard C library malloc and free on non-Apple systems. +*/ +#define SQLITE_MALLOC(x) malloc(x) +#define SQLITE_FREE(x) free(x) +#define SQLITE_REALLOC(x,y) realloc((x),(y)) + +#ifdef HAVE_MALLOC_USABLE_SIZE +#include +#define SQLITE_MALLOCSIZE(x) malloc_usable_size(x) +#else +#undef SQLITE_MALLOCSIZE +#endif + +#endif /* __APPLE__ or not __APPLE__ */ + +/* +** Like malloc(), but remember the size of the allocation +** so that we can find it later using sqlite3MemSize(). +** +** For this low-level routine, we are guaranteed that nByte>0 because +** cases of nByte<=0 will be intercepted and dealt with by higher level +** routines. +*/ +static void *sqlite3MemMalloc(int nByte){ +#ifdef SQLITE_MALLOCSIZE + void *p = SQLITE_MALLOC( nByte ); + if( p==0 ){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte); + } + return p; +#else + sqlite3_int64 *p; + assert( nByte>0 ); + nByte = ROUND8(nByte); + p = SQLITE_MALLOC( nByte+8 ); + if( p ){ + p[0] = nByte; + p++; + }else{ + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte); + } + return (void *)p; +#endif +} + +/* +** Like free() but works for allocations obtained from sqlite3MemMalloc() +** or sqlite3MemRealloc(). +** +** For this low-level routine, we already know that pPrior!=0 since +** cases where pPrior==0 will have been intecepted and dealt with +** by higher-level routines. +*/ +static void sqlite3MemFree(void *pPrior){ +#ifdef SQLITE_MALLOCSIZE + SQLITE_FREE(pPrior); +#else + sqlite3_int64 *p = (sqlite3_int64*)pPrior; + assert( pPrior!=0 ); + p--; + SQLITE_FREE(p); +#endif +} + +/* +** Report the allocated size of a prior return from xMalloc() +** or xRealloc(). +*/ +static int sqlite3MemSize(void *pPrior){ +#ifdef SQLITE_MALLOCSIZE + return pPrior ? (int)SQLITE_MALLOCSIZE(pPrior) : 0; +#else + sqlite3_int64 *p; + if( pPrior==0 ) return 0; + p = (sqlite3_int64*)pPrior; + p--; + return (int)p[0]; +#endif +} + +/* +** Like realloc(). Resize an allocation previously obtained from +** sqlite3MemMalloc(). +** +** For this low-level interface, we know that pPrior!=0. Cases where +** pPrior==0 while have been intercepted by higher-level routine and +** redirected to xMalloc. Similarly, we know that nByte>0 becauses +** cases where nByte<=0 will have been intercepted by higher-level +** routines and redirected to xFree. +*/ +static void *sqlite3MemRealloc(void *pPrior, int nByte){ +#ifdef SQLITE_MALLOCSIZE + void *p = SQLITE_REALLOC(pPrior, nByte); + if( p==0 ){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_NOMEM, + "failed memory resize %u to %u bytes", + SQLITE_MALLOCSIZE(pPrior), nByte); + } + return p; +#else + sqlite3_int64 *p = (sqlite3_int64*)pPrior; + assert( pPrior!=0 && nByte>0 ); + assert( nByte==ROUND8(nByte) ); /* EV: R-46199-30249 */ + p--; + p = SQLITE_REALLOC(p, nByte+8 ); + if( p ){ + p[0] = nByte; + p++; + }else{ + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_NOMEM, + "failed memory resize %u to %u bytes", + sqlite3MemSize(pPrior), nByte); + } + return (void*)p; +#endif +} + +/* +** Round up a request size to the next valid allocation size. +*/ +static int sqlite3MemRoundup(int n){ + return ROUND8(n); +} + +/* +** Initialize this module. +*/ +static int sqlite3MemInit(void *NotUsed){ +#if defined(__APPLE__) + int cpuCount; + size_t len; + if( _sqliteZone_ ){ + return SQLITE_OK; + } + len = sizeof(cpuCount); + /* One usually wants to use hw.acctivecpu for MT decisions, but not here */ + sysctlbyname("hw.ncpu", &cpuCount, &len, NULL, 0); + if( cpuCount>1 ){ + /* defer MT decisions to system malloc */ + _sqliteZone_ = malloc_default_zone(); + }else{ + /* only 1 core, use our own zone to contention over global locks, + ** e.g. we have our own dedicated locks */ + bool success; + malloc_zone_t* newzone = malloc_create_zone(4096, 0); + malloc_set_zone_name(newzone, "Sqlite_Heap"); + do{ + success = OSAtomicCompareAndSwapPtrBarrier(NULL, newzone, + (void * volatile *)&_sqliteZone_); + }while(!_sqliteZone_); + if( !success ){ + /* somebody registered a zone first */ + malloc_destroy_zone(newzone); + } + } +#endif + UNUSED_PARAMETER(NotUsed); + return SQLITE_OK; +} + +/* +** Deinitialize this module. +*/ +static void sqlite3MemShutdown(void *NotUsed){ + UNUSED_PARAMETER(NotUsed); + return; +} + +/* +** This routine is the only routine in this file with external linkage. +** +** Populate the low-level memory allocation function pointers in +** sqlite3GlobalConfig.m with pointers to the routines in this file. +*/ +void sqlite3MemSetDefault(void){ + static const sqlite3_mem_methods defaultMethods = { + sqlite3MemMalloc, + sqlite3MemFree, + sqlite3MemRealloc, + sqlite3MemSize, + sqlite3MemRoundup, + sqlite3MemInit, + sqlite3MemShutdown, + 0 + }; + sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods); +} + +#endif /* SQLITE_SYSTEM_MALLOC */ diff --git a/scalos/libraries/sqlite/src/mem2.c b/scalos/libraries/sqlite/src/mem2.c new file mode 100644 index 000000000..26448ea8a --- /dev/null +++ b/scalos/libraries/sqlite/src/mem2.c @@ -0,0 +1,528 @@ +/* +** 2007 August 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains low-level memory allocation drivers for when +** SQLite will use the standard C-library malloc/realloc/free interface +** to obtain the memory it needs while adding lots of additional debugging +** information to each allocation in order to help detect and fix memory +** leaks and memory usage errors. +** +** This file contains implementations of the low-level memory allocation +** routines specified in the sqlite3_mem_methods object. +*/ +#include "sqliteInt.h" + +/* +** This version of the memory allocator is used only if the +** SQLITE_MEMDEBUG macro is defined +*/ +#ifdef SQLITE_MEMDEBUG + +/* +** The backtrace functionality is only available with GLIBC +*/ +#ifdef __GLIBC__ + extern int backtrace(void**,int); + extern void backtrace_symbols_fd(void*const*,int,int); +#else +# define backtrace(A,B) 1 +# define backtrace_symbols_fd(A,B,C) +#endif +#include + +/* +** Each memory allocation looks like this: +** +** ------------------------------------------------------------------------ +** | Title | backtrace pointers | MemBlockHdr | allocation | EndGuard | +** ------------------------------------------------------------------------ +** +** The application code sees only a pointer to the allocation. We have +** to back up from the allocation pointer to find the MemBlockHdr. The +** MemBlockHdr tells us the size of the allocation and the number of +** backtrace pointers. There is also a guard word at the end of the +** MemBlockHdr. +*/ +struct MemBlockHdr { + i64 iSize; /* Size of this allocation */ + struct MemBlockHdr *pNext, *pPrev; /* Linked list of all unfreed memory */ + char nBacktrace; /* Number of backtraces on this alloc */ + char nBacktraceSlots; /* Available backtrace slots */ + u8 nTitle; /* Bytes of title; includes '\0' */ + u8 eType; /* Allocation type code */ + int iForeGuard; /* Guard word for sanity */ +}; + +/* +** Guard words +*/ +#define FOREGUARD 0x80F5E153 +#define REARGUARD 0xE4676B53 + +/* +** Number of malloc size increments to track. +*/ +#define NCSIZE 1000 + +/* +** All of the static variables used by this module are collected +** into a single structure named "mem". This is to keep the +** static variables organized and to reduce namespace pollution +** when this module is combined with other in the amalgamation. +*/ +static struct { + + /* + ** Mutex to control access to the memory allocation subsystem. + */ + sqlite3_mutex *mutex; + + /* + ** Head and tail of a linked list of all outstanding allocations + */ + struct MemBlockHdr *pFirst; + struct MemBlockHdr *pLast; + + /* + ** The number of levels of backtrace to save in new allocations. + */ + int nBacktrace; + void (*xBacktrace)(int, int, void **); + + /* + ** Title text to insert in front of each block + */ + int nTitle; /* Bytes of zTitle to save. Includes '\0' and padding */ + char zTitle[100]; /* The title text */ + + /* + ** sqlite3MallocDisallow() increments the following counter. + ** sqlite3MallocAllow() decrements it. + */ + int disallow; /* Do not allow memory allocation */ + + /* + ** Gather statistics on the sizes of memory allocations. + ** nAlloc[i] is the number of allocation attempts of i*8 + ** bytes. i==NCSIZE is the number of allocation attempts for + ** sizes more than NCSIZE*8 bytes. + */ + int nAlloc[NCSIZE]; /* Total number of allocations */ + int nCurrent[NCSIZE]; /* Current number of allocations */ + int mxCurrent[NCSIZE]; /* Highwater mark for nCurrent */ + +} mem; + + +/* +** Adjust memory usage statistics +*/ +static void adjustStats(int iSize, int increment){ + int i = ROUND8(iSize)/8; + if( i>NCSIZE-1 ){ + i = NCSIZE - 1; + } + if( increment>0 ){ + mem.nAlloc[i]++; + mem.nCurrent[i]++; + if( mem.nCurrent[i]>mem.mxCurrent[i] ){ + mem.mxCurrent[i] = mem.nCurrent[i]; + } + }else{ + mem.nCurrent[i]--; + assert( mem.nCurrent[i]>=0 ); + } +} + +/* +** Given an allocation, find the MemBlockHdr for that allocation. +** +** This routine checks the guards at either end of the allocation and +** if they are incorrect it asserts. +*/ +static struct MemBlockHdr *sqlite3MemsysGetHeader(void *pAllocation){ + struct MemBlockHdr *p; + int *pInt; + u8 *pU8; + int nReserve; + + p = (struct MemBlockHdr*)pAllocation; + p--; + assert( p->iForeGuard==(int)FOREGUARD ); + nReserve = ROUND8(p->iSize); + pInt = (int*)pAllocation; + pU8 = (u8*)pAllocation; + assert( pInt[nReserve/sizeof(int)]==(int)REARGUARD ); + /* This checks any of the "extra" bytes allocated due + ** to rounding up to an 8 byte boundary to ensure + ** they haven't been overwritten. + */ + while( nReserve-- > p->iSize ) assert( pU8[nReserve]==0x65 ); + return p; +} + +/* +** Return the number of bytes currently allocated at address p. +*/ +static int sqlite3MemSize(void *p){ + struct MemBlockHdr *pHdr; + if( !p ){ + return 0; + } + pHdr = sqlite3MemsysGetHeader(p); + return pHdr->iSize; +} + +/* +** Initialize the memory allocation subsystem. +*/ +static int sqlite3MemInit(void *NotUsed){ + UNUSED_PARAMETER(NotUsed); + assert( (sizeof(struct MemBlockHdr)&7) == 0 ); + if( !sqlite3GlobalConfig.bMemstat ){ + /* If memory status is enabled, then the malloc.c wrapper will already + ** hold the STATIC_MEM mutex when the routines here are invoked. */ + mem.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); + } + return SQLITE_OK; +} + +/* +** Deinitialize the memory allocation subsystem. +*/ +static void sqlite3MemShutdown(void *NotUsed){ + UNUSED_PARAMETER(NotUsed); + mem.mutex = 0; +} + +/* +** Round up a request size to the next valid allocation size. +*/ +static int sqlite3MemRoundup(int n){ + return ROUND8(n); +} + +/* +** Fill a buffer with pseudo-random bytes. This is used to preset +** the content of a new memory allocation to unpredictable values and +** to clear the content of a freed allocation to unpredictable values. +*/ +static void randomFill(char *pBuf, int nByte){ + unsigned int x, y, r; + x = SQLITE_PTR_TO_INT(pBuf); + y = nByte | 1; + while( nByte >= 4 ){ + x = (x>>1) ^ (-(x&1) & 0xd0000001); + y = y*1103515245 + 12345; + r = x ^ y; + *(int*)pBuf = r; + pBuf += 4; + nByte -= 4; + } + while( nByte-- > 0 ){ + x = (x>>1) ^ (-(x&1) & 0xd0000001); + y = y*1103515245 + 12345; + r = x ^ y; + *(pBuf++) = r & 0xff; + } +} + +/* +** Allocate nByte bytes of memory. +*/ +static void *sqlite3MemMalloc(int nByte){ + struct MemBlockHdr *pHdr; + void **pBt; + char *z; + int *pInt; + void *p = 0; + int totalSize; + int nReserve; + sqlite3_mutex_enter(mem.mutex); + assert( mem.disallow==0 ); + nReserve = ROUND8(nByte); + totalSize = nReserve + sizeof(*pHdr) + sizeof(int) + + mem.nBacktrace*sizeof(void*) + mem.nTitle; + p = malloc(totalSize); + if( p ){ + z = p; + pBt = (void**)&z[mem.nTitle]; + pHdr = (struct MemBlockHdr*)&pBt[mem.nBacktrace]; + pHdr->pNext = 0; + pHdr->pPrev = mem.pLast; + if( mem.pLast ){ + mem.pLast->pNext = pHdr; + }else{ + mem.pFirst = pHdr; + } + mem.pLast = pHdr; + pHdr->iForeGuard = FOREGUARD; + pHdr->eType = MEMTYPE_HEAP; + pHdr->nBacktraceSlots = mem.nBacktrace; + pHdr->nTitle = mem.nTitle; + if( mem.nBacktrace ){ + void *aAddr[40]; + pHdr->nBacktrace = backtrace(aAddr, mem.nBacktrace+1)-1; + memcpy(pBt, &aAddr[1], pHdr->nBacktrace*sizeof(void*)); + assert(pBt[0]); + if( mem.xBacktrace ){ + mem.xBacktrace(nByte, pHdr->nBacktrace-1, &aAddr[1]); + } + }else{ + pHdr->nBacktrace = 0; + } + if( mem.nTitle ){ + memcpy(z, mem.zTitle, mem.nTitle); + } + pHdr->iSize = nByte; + adjustStats(nByte, +1); + pInt = (int*)&pHdr[1]; + pInt[nReserve/sizeof(int)] = REARGUARD; + randomFill((char*)pInt, nByte); + memset(((char*)pInt)+nByte, 0x65, nReserve-nByte); + p = (void*)pInt; + } + sqlite3_mutex_leave(mem.mutex); + return p; +} + +/* +** Free memory. +*/ +static void sqlite3MemFree(void *pPrior){ + struct MemBlockHdr *pHdr; + void **pBt; + char *z; + assert( sqlite3GlobalConfig.bMemstat || sqlite3GlobalConfig.bCoreMutex==0 + || mem.mutex!=0 ); + pHdr = sqlite3MemsysGetHeader(pPrior); + pBt = (void**)pHdr; + pBt -= pHdr->nBacktraceSlots; + sqlite3_mutex_enter(mem.mutex); + if( pHdr->pPrev ){ + assert( pHdr->pPrev->pNext==pHdr ); + pHdr->pPrev->pNext = pHdr->pNext; + }else{ + assert( mem.pFirst==pHdr ); + mem.pFirst = pHdr->pNext; + } + if( pHdr->pNext ){ + assert( pHdr->pNext->pPrev==pHdr ); + pHdr->pNext->pPrev = pHdr->pPrev; + }else{ + assert( mem.pLast==pHdr ); + mem.pLast = pHdr->pPrev; + } + z = (char*)pBt; + z -= pHdr->nTitle; + adjustStats(pHdr->iSize, -1); + randomFill(z, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) + + pHdr->iSize + sizeof(int) + pHdr->nTitle); + free(z); + sqlite3_mutex_leave(mem.mutex); +} + +/* +** Change the size of an existing memory allocation. +** +** For this debugging implementation, we *always* make a copy of the +** allocation into a new place in memory. In this way, if the +** higher level code is using pointer to the old allocation, it is +** much more likely to break and we are much more liking to find +** the error. +*/ +static void *sqlite3MemRealloc(void *pPrior, int nByte){ + struct MemBlockHdr *pOldHdr; + void *pNew; + assert( mem.disallow==0 ); + assert( (nByte & 7)==0 ); /* EV: R-46199-30249 */ + pOldHdr = sqlite3MemsysGetHeader(pPrior); + pNew = sqlite3MemMalloc(nByte); + if( pNew ){ + memcpy(pNew, pPrior, nByteiSize ? nByte : pOldHdr->iSize); + if( nByte>pOldHdr->iSize ){ + randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - pOldHdr->iSize); + } + sqlite3MemFree(pPrior); + } + return pNew; +} + +/* +** Populate the low-level memory allocation function pointers in +** sqlite3GlobalConfig.m with pointers to the routines in this file. +*/ +void sqlite3MemSetDefault(void){ + static const sqlite3_mem_methods defaultMethods = { + sqlite3MemMalloc, + sqlite3MemFree, + sqlite3MemRealloc, + sqlite3MemSize, + sqlite3MemRoundup, + sqlite3MemInit, + sqlite3MemShutdown, + 0 + }; + sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods); +} + +/* +** Set the "type" of an allocation. +*/ +void sqlite3MemdebugSetType(void *p, u8 eType){ + if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){ + struct MemBlockHdr *pHdr; + pHdr = sqlite3MemsysGetHeader(p); + assert( pHdr->iForeGuard==FOREGUARD ); + pHdr->eType = eType; + } +} + +/* +** Return TRUE if the mask of type in eType matches the type of the +** allocation p. Also return true if p==NULL. +** +** This routine is designed for use within an assert() statement, to +** verify the type of an allocation. For example: +** +** assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) ); +*/ +int sqlite3MemdebugHasType(void *p, u8 eType){ + int rc = 1; + if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){ + struct MemBlockHdr *pHdr; + pHdr = sqlite3MemsysGetHeader(p); + assert( pHdr->iForeGuard==FOREGUARD ); /* Allocation is valid */ + if( (pHdr->eType&eType)==0 ){ + rc = 0; + } + } + return rc; +} + +/* +** Return TRUE if the mask of type in eType matches no bits of the type of the +** allocation p. Also return true if p==NULL. +** +** This routine is designed for use within an assert() statement, to +** verify the type of an allocation. For example: +** +** assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) ); +*/ +int sqlite3MemdebugNoType(void *p, u8 eType){ + int rc = 1; + if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){ + struct MemBlockHdr *pHdr; + pHdr = sqlite3MemsysGetHeader(p); + assert( pHdr->iForeGuard==FOREGUARD ); /* Allocation is valid */ + if( (pHdr->eType&eType)!=0 ){ + rc = 0; + } + } + return rc; +} + +/* +** Set the number of backtrace levels kept for each allocation. +** A value of zero turns off backtracing. The number is always rounded +** up to a multiple of 2. +*/ +void sqlite3MemdebugBacktrace(int depth){ + if( depth<0 ){ depth = 0; } + if( depth>20 ){ depth = 20; } + depth = (depth+1)&0xfe; + mem.nBacktrace = depth; +} + +void sqlite3MemdebugBacktraceCallback(void (*xBacktrace)(int, int, void **)){ + mem.xBacktrace = xBacktrace; +} + +/* +** Set the title string for subsequent allocations. +*/ +void sqlite3MemdebugSettitle(const char *zTitle){ + unsigned int n = sqlite3Strlen30(zTitle) + 1; + sqlite3_mutex_enter(mem.mutex); + if( n>=sizeof(mem.zTitle) ) n = sizeof(mem.zTitle)-1; + memcpy(mem.zTitle, zTitle, n); + mem.zTitle[n] = 0; + mem.nTitle = ROUND8(n); + sqlite3_mutex_leave(mem.mutex); +} + +void sqlite3MemdebugSync(){ + struct MemBlockHdr *pHdr; + for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){ + void **pBt = (void**)pHdr; + pBt -= pHdr->nBacktraceSlots; + mem.xBacktrace(pHdr->iSize, pHdr->nBacktrace-1, &pBt[1]); + } +} + +/* +** Open the file indicated and write a log of all unfreed memory +** allocations into that log. +*/ +void sqlite3MemdebugDump(const char *zFilename){ + FILE *out; + struct MemBlockHdr *pHdr; + void **pBt; + int i; + out = fopen(zFilename, "w"); + if( out==0 ){ + fprintf(stderr, "** Unable to output memory debug output log: %s **\n", + zFilename); + return; + } + for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){ + char *z = (char*)pHdr; + z -= pHdr->nBacktraceSlots*sizeof(void*) + pHdr->nTitle; + fprintf(out, "**** %lld bytes at %p from %s ****\n", + pHdr->iSize, &pHdr[1], pHdr->nTitle ? z : "???"); + if( pHdr->nBacktrace ){ + fflush(out); + pBt = (void**)pHdr; + pBt -= pHdr->nBacktraceSlots; + backtrace_symbols_fd(pBt, pHdr->nBacktrace, fileno(out)); + fprintf(out, "\n"); + } + } + fprintf(out, "COUNTS:\n"); + for(i=0; i=1 ); + size = mem3.aPool[i-1].u.hdr.size4x/4; + assert( size==mem3.aPool[i+size-1].u.hdr.prevSize ); + assert( size>=2 ); + if( size <= MX_SMALL ){ + memsys3UnlinkFromList(i, &mem3.aiSmall[size-2]); + }else{ + hash = size % N_HASH; + memsys3UnlinkFromList(i, &mem3.aiHash[hash]); + } +} + +/* +** Link the chunk at mem3.aPool[i] so that is on the list rooted +** at *pRoot. +*/ +static void memsys3LinkIntoList(u32 i, u32 *pRoot){ + assert( sqlite3_mutex_held(mem3.mutex) ); + mem3.aPool[i].u.list.next = *pRoot; + mem3.aPool[i].u.list.prev = 0; + if( *pRoot ){ + mem3.aPool[*pRoot].u.list.prev = i; + } + *pRoot = i; +} + +/* +** Link the chunk at index i into either the appropriate +** small chunk list, or into the large chunk hash table. +*/ +static void memsys3Link(u32 i){ + u32 size, hash; + assert( sqlite3_mutex_held(mem3.mutex) ); + assert( i>=1 ); + assert( (mem3.aPool[i-1].u.hdr.size4x & 1)==0 ); + size = mem3.aPool[i-1].u.hdr.size4x/4; + assert( size==mem3.aPool[i+size-1].u.hdr.prevSize ); + assert( size>=2 ); + if( size <= MX_SMALL ){ + memsys3LinkIntoList(i, &mem3.aiSmall[size-2]); + }else{ + hash = size % N_HASH; + memsys3LinkIntoList(i, &mem3.aiHash[hash]); + } +} + +/* +** If the STATIC_MEM mutex is not already held, obtain it now. The mutex +** will already be held (obtained by code in malloc.c) if +** sqlite3GlobalConfig.bMemStat is true. +*/ +static void memsys3Enter(void){ + if( sqlite3GlobalConfig.bMemstat==0 && mem3.mutex==0 ){ + mem3.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); + } + sqlite3_mutex_enter(mem3.mutex); +} +static void memsys3Leave(void){ + sqlite3_mutex_leave(mem3.mutex); +} + +/* +** Called when we are unable to satisfy an allocation of nBytes. +*/ +static void memsys3OutOfMemory(int nByte){ + if( !mem3.alarmBusy ){ + mem3.alarmBusy = 1; + assert( sqlite3_mutex_held(mem3.mutex) ); + sqlite3_mutex_leave(mem3.mutex); + sqlite3_release_memory(nByte); + sqlite3_mutex_enter(mem3.mutex); + mem3.alarmBusy = 0; + } +} + + +/* +** Chunk i is a free chunk that has been unlinked. Adjust its +** size parameters for check-out and return a pointer to the +** user portion of the chunk. +*/ +static void *memsys3Checkout(u32 i, u32 nBlock){ + u32 x; + assert( sqlite3_mutex_held(mem3.mutex) ); + assert( i>=1 ); + assert( mem3.aPool[i-1].u.hdr.size4x/4==nBlock ); + assert( mem3.aPool[i+nBlock-1].u.hdr.prevSize==nBlock ); + x = mem3.aPool[i-1].u.hdr.size4x; + mem3.aPool[i-1].u.hdr.size4x = nBlock*4 | 1 | (x&2); + mem3.aPool[i+nBlock-1].u.hdr.prevSize = nBlock; + mem3.aPool[i+nBlock-1].u.hdr.size4x |= 2; + return &mem3.aPool[i]; +} + +/* +** Carve a piece off of the end of the mem3.iMaster free chunk. +** Return a pointer to the new allocation. Or, if the master chunk +** is not large enough, return 0. +*/ +static void *memsys3FromMaster(u32 nBlock){ + assert( sqlite3_mutex_held(mem3.mutex) ); + assert( mem3.szMaster>=nBlock ); + if( nBlock>=mem3.szMaster-1 ){ + /* Use the entire master */ + void *p = memsys3Checkout(mem3.iMaster, mem3.szMaster); + mem3.iMaster = 0; + mem3.szMaster = 0; + mem3.mnMaster = 0; + return p; + }else{ + /* Split the master block. Return the tail. */ + u32 newi, x; + newi = mem3.iMaster + mem3.szMaster - nBlock; + assert( newi > mem3.iMaster+1 ); + mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = nBlock; + mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x |= 2; + mem3.aPool[newi-1].u.hdr.size4x = nBlock*4 + 1; + mem3.szMaster -= nBlock; + mem3.aPool[newi-1].u.hdr.prevSize = mem3.szMaster; + x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2; + mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x; + if( mem3.szMaster < mem3.mnMaster ){ + mem3.mnMaster = mem3.szMaster; + } + return (void*)&mem3.aPool[newi]; + } +} + +/* +** *pRoot is the head of a list of free chunks of the same size +** or same size hash. In other words, *pRoot is an entry in either +** mem3.aiSmall[] or mem3.aiHash[]. +** +** This routine examines all entries on the given list and tries +** to coalesce each entries with adjacent free chunks. +** +** If it sees a chunk that is larger than mem3.iMaster, it replaces +** the current mem3.iMaster with the new larger chunk. In order for +** this mem3.iMaster replacement to work, the master chunk must be +** linked into the hash tables. That is not the normal state of +** affairs, of course. The calling routine must link the master +** chunk before invoking this routine, then must unlink the (possibly +** changed) master chunk once this routine has finished. +*/ +static void memsys3Merge(u32 *pRoot){ + u32 iNext, prev, size, i, x; + + assert( sqlite3_mutex_held(mem3.mutex) ); + for(i=*pRoot; i>0; i=iNext){ + iNext = mem3.aPool[i].u.list.next; + size = mem3.aPool[i-1].u.hdr.size4x; + assert( (size&1)==0 ); + if( (size&2)==0 ){ + memsys3UnlinkFromList(i, pRoot); + assert( i > mem3.aPool[i-1].u.hdr.prevSize ); + prev = i - mem3.aPool[i-1].u.hdr.prevSize; + if( prev==iNext ){ + iNext = mem3.aPool[prev].u.list.next; + } + memsys3Unlink(prev); + size = i + size/4 - prev; + x = mem3.aPool[prev-1].u.hdr.size4x & 2; + mem3.aPool[prev-1].u.hdr.size4x = size*4 | x; + mem3.aPool[prev+size-1].u.hdr.prevSize = size; + memsys3Link(prev); + i = prev; + }else{ + size /= 4; + } + if( size>mem3.szMaster ){ + mem3.iMaster = i; + mem3.szMaster = size; + } + } +} + +/* +** Return a block of memory of at least nBytes in size. +** Return NULL if unable. +** +** This function assumes that the necessary mutexes, if any, are +** already held by the caller. Hence "Unsafe". +*/ +static void *memsys3MallocUnsafe(int nByte){ + u32 i; + u32 nBlock; + u32 toFree; + + assert( sqlite3_mutex_held(mem3.mutex) ); + assert( sizeof(Mem3Block)==8 ); + if( nByte<=12 ){ + nBlock = 2; + }else{ + nBlock = (nByte + 11)/8; + } + assert( nBlock>=2 ); + + /* STEP 1: + ** Look for an entry of the correct size in either the small + ** chunk table or in the large chunk hash table. This is + ** successful most of the time (about 9 times out of 10). + */ + if( nBlock <= MX_SMALL ){ + i = mem3.aiSmall[nBlock-2]; + if( i>0 ){ + memsys3UnlinkFromList(i, &mem3.aiSmall[nBlock-2]); + return memsys3Checkout(i, nBlock); + } + }else{ + int hash = nBlock % N_HASH; + for(i=mem3.aiHash[hash]; i>0; i=mem3.aPool[i].u.list.next){ + if( mem3.aPool[i-1].u.hdr.size4x/4==nBlock ){ + memsys3UnlinkFromList(i, &mem3.aiHash[hash]); + return memsys3Checkout(i, nBlock); + } + } + } + + /* STEP 2: + ** Try to satisfy the allocation by carving a piece off of the end + ** of the master chunk. This step usually works if step 1 fails. + */ + if( mem3.szMaster>=nBlock ){ + return memsys3FromMaster(nBlock); + } + + + /* STEP 3: + ** Loop through the entire memory pool. Coalesce adjacent free + ** chunks. Recompute the master chunk as the largest free chunk. + ** Then try again to satisfy the allocation by carving a piece off + ** of the end of the master chunk. This step happens very + ** rarely (we hope!) + */ + for(toFree=nBlock*16; toFree<(mem3.nPool*16); toFree *= 2){ + memsys3OutOfMemory(toFree); + if( mem3.iMaster ){ + memsys3Link(mem3.iMaster); + mem3.iMaster = 0; + mem3.szMaster = 0; + } + for(i=0; i=nBlock ){ + return memsys3FromMaster(nBlock); + } + } + } + + /* If none of the above worked, then we fail. */ + return 0; +} + +/* +** Free an outstanding memory allocation. +** +** This function assumes that the necessary mutexes, if any, are +** already held by the caller. Hence "Unsafe". +*/ +static void memsys3FreeUnsafe(void *pOld){ + Mem3Block *p = (Mem3Block*)pOld; + int i; + u32 size, x; + assert( sqlite3_mutex_held(mem3.mutex) ); + assert( p>mem3.aPool && p<&mem3.aPool[mem3.nPool] ); + i = p - mem3.aPool; + assert( (mem3.aPool[i-1].u.hdr.size4x&1)==1 ); + size = mem3.aPool[i-1].u.hdr.size4x/4; + assert( i+size<=mem3.nPool+1 ); + mem3.aPool[i-1].u.hdr.size4x &= ~1; + mem3.aPool[i+size-1].u.hdr.prevSize = size; + mem3.aPool[i+size-1].u.hdr.size4x &= ~2; + memsys3Link(i); + + /* Try to expand the master using the newly freed chunk */ + if( mem3.iMaster ){ + while( (mem3.aPool[mem3.iMaster-1].u.hdr.size4x&2)==0 ){ + size = mem3.aPool[mem3.iMaster-1].u.hdr.prevSize; + mem3.iMaster -= size; + mem3.szMaster += size; + memsys3Unlink(mem3.iMaster); + x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2; + mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x; + mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = mem3.szMaster; + } + x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2; + while( (mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x&1)==0 ){ + memsys3Unlink(mem3.iMaster+mem3.szMaster); + mem3.szMaster += mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x/4; + mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x; + mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = mem3.szMaster; + } + } +} + +/* +** Return the size of an outstanding allocation, in bytes. The +** size returned omits the 8-byte header overhead. This only +** works for chunks that are currently checked out. +*/ +static int memsys3Size(void *p){ + Mem3Block *pBlock; + if( p==0 ) return 0; + pBlock = (Mem3Block*)p; + assert( (pBlock[-1].u.hdr.size4x&1)!=0 ); + return (pBlock[-1].u.hdr.size4x&~3)*2 - 4; +} + +/* +** Round up a request size to the next valid allocation size. +*/ +static int memsys3Roundup(int n){ + if( n<=12 ){ + return 12; + }else{ + return ((n+11)&~7) - 4; + } +} + +/* +** Allocate nBytes of memory. +*/ +static void *memsys3Malloc(int nBytes){ + sqlite3_int64 *p; + assert( nBytes>0 ); /* malloc.c filters out 0 byte requests */ + memsys3Enter(); + p = memsys3MallocUnsafe(nBytes); + memsys3Leave(); + return (void*)p; +} + +/* +** Free memory. +*/ +static void memsys3Free(void *pPrior){ + assert( pPrior ); + memsys3Enter(); + memsys3FreeUnsafe(pPrior); + memsys3Leave(); +} + +/* +** Change the size of an existing memory allocation +*/ +static void *memsys3Realloc(void *pPrior, int nBytes){ + int nOld; + void *p; + if( pPrior==0 ){ + return sqlite3_malloc(nBytes); + } + if( nBytes<=0 ){ + sqlite3_free(pPrior); + return 0; + } + nOld = memsys3Size(pPrior); + if( nBytes<=nOld && nBytes>=nOld-128 ){ + return pPrior; + } + memsys3Enter(); + p = memsys3MallocUnsafe(nBytes); + if( p ){ + if( nOld>1)!=(size&1) ){ + fprintf(out, "%p tail checkout bit is incorrect\n", &mem3.aPool[i]); + assert( 0 ); + break; + } + if( size&1 ){ + fprintf(out, "%p %6d bytes checked out\n", &mem3.aPool[i], (size/4)*8-8); + }else{ + fprintf(out, "%p %6d bytes free%s\n", &mem3.aPool[i], (size/4)*8-8, + i==mem3.iMaster ? " **master**" : ""); + } + } + for(i=0; i0; j=mem3.aPool[j].u.list.next){ + fprintf(out, " %p(%d)", &mem3.aPool[j], + (mem3.aPool[j-1].u.hdr.size4x/4)*8-8); + } + fprintf(out, "\n"); + } + for(i=0; i0; j=mem3.aPool[j].u.list.next){ + fprintf(out, " %p(%d)", &mem3.aPool[j], + (mem3.aPool[j-1].u.hdr.size4x/4)*8-8); + } + fprintf(out, "\n"); + } + fprintf(out, "master=%d\n", mem3.iMaster); + fprintf(out, "nowUsed=%d\n", mem3.nPool*8 - mem3.szMaster*8); + fprintf(out, "mxUsed=%d\n", mem3.nPool*8 - mem3.mnMaster*8); + sqlite3_mutex_leave(mem3.mutex); + if( out==stdout ){ + fflush(stdout); + }else{ + fclose(out); + } +#else + UNUSED_PARAMETER(zFilename); +#endif +} + +/* +** This routine is the only routine in this file with external +** linkage. +** +** Populate the low-level memory allocation function pointers in +** sqlite3GlobalConfig.m with pointers to the routines in this file. The +** arguments specify the block of memory to manage. +** +** This routine is only called by sqlite3_config(), and therefore +** is not required to be threadsafe (it is not). +*/ +const sqlite3_mem_methods *sqlite3MemGetMemsys3(void){ + static const sqlite3_mem_methods mempoolMethods = { + memsys3Malloc, + memsys3Free, + memsys3Realloc, + memsys3Size, + memsys3Roundup, + memsys3Init, + memsys3Shutdown, + 0 + }; + return &mempoolMethods; +} + +#endif /* SQLITE_ENABLE_MEMSYS3 */ diff --git a/scalos/libraries/sqlite/src/mem5.c b/scalos/libraries/sqlite/src/mem5.c new file mode 100644 index 000000000..783cef617 --- /dev/null +++ b/scalos/libraries/sqlite/src/mem5.c @@ -0,0 +1,581 @@ +/* +** 2007 October 14 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains the C functions that implement a memory +** allocation subsystem for use by SQLite. +** +** This version of the memory allocation subsystem omits all +** use of malloc(). The application gives SQLite a block of memory +** before calling sqlite3_initialize() from which allocations +** are made and returned by the xMalloc() and xRealloc() +** implementations. Once sqlite3_initialize() has been called, +** the amount of memory available to SQLite is fixed and cannot +** be changed. +** +** This version of the memory allocation subsystem is included +** in the build only if SQLITE_ENABLE_MEMSYS5 is defined. +** +** This memory allocator uses the following algorithm: +** +** 1. All memory allocations sizes are rounded up to a power of 2. +** +** 2. If two adjacent free blocks are the halves of a larger block, +** then the two blocks are coalesed into the single larger block. +** +** 3. New memory is allocated from the first available free block. +** +** This algorithm is described in: J. M. Robson. "Bounds for Some Functions +** Concerning Dynamic Storage Allocation". Journal of the Association for +** Computing Machinery, Volume 21, Number 8, July 1974, pages 491-499. +** +** Let n be the size of the largest allocation divided by the minimum +** allocation size (after rounding all sizes up to a power of 2.) Let M +** be the maximum amount of memory ever outstanding at one time. Let +** N be the total amount of memory available for allocation. Robson +** proved that this memory allocator will never breakdown due to +** fragmentation as long as the following constraint holds: +** +** N >= M*(1 + log2(n)/2) - n + 1 +** +** The sqlite3_status() logic tracks the maximum values of n and M so +** that an application can, at any time, verify this constraint. +*/ +#include "sqliteInt.h" + +/* +** This version of the memory allocator is used only when +** SQLITE_ENABLE_MEMSYS5 is defined. +*/ +#ifdef SQLITE_ENABLE_MEMSYS5 + +/* +** A minimum allocation is an instance of the following structure. +** Larger allocations are an array of these structures where the +** size of the array is a power of 2. +** +** The size of this object must be a power of two. That fact is +** verified in memsys5Init(). +*/ +typedef struct Mem5Link Mem5Link; +struct Mem5Link { + int next; /* Index of next free chunk */ + int prev; /* Index of previous free chunk */ +}; + +/* +** Maximum size of any allocation is ((1<=0 && i=0 && iLogsize<=LOGMAX ); + assert( (mem5.aCtrl[i] & CTRL_LOGSIZE)==iLogsize ); + + next = MEM5LINK(i)->next; + prev = MEM5LINK(i)->prev; + if( prev<0 ){ + mem5.aiFreelist[iLogsize] = next; + }else{ + MEM5LINK(prev)->next = next; + } + if( next>=0 ){ + MEM5LINK(next)->prev = prev; + } +} + +/* +** Link the chunk at mem5.aPool[i] so that is on the iLogsize +** free list. +*/ +static void memsys5Link(int i, int iLogsize){ + int x; + assert( sqlite3_mutex_held(mem5.mutex) ); + assert( i>=0 && i=0 && iLogsize<=LOGMAX ); + assert( (mem5.aCtrl[i] & CTRL_LOGSIZE)==iLogsize ); + + x = MEM5LINK(i)->next = mem5.aiFreelist[iLogsize]; + MEM5LINK(i)->prev = -1; + if( x>=0 ){ + assert( xprev = i; + } + mem5.aiFreelist[iLogsize] = i; +} + +/* +** If the STATIC_MEM mutex is not already held, obtain it now. The mutex +** will already be held (obtained by code in malloc.c) if +** sqlite3GlobalConfig.bMemStat is true. +*/ +static void memsys5Enter(void){ + sqlite3_mutex_enter(mem5.mutex); +} +static void memsys5Leave(void){ + sqlite3_mutex_leave(mem5.mutex); +} + +/* +** Return the size of an outstanding allocation, in bytes. The +** size returned omits the 8-byte header overhead. This only +** works for chunks that are currently checked out. +*/ +static int memsys5Size(void *p){ + int iSize = 0; + if( p ){ + int i = ((u8 *)p-mem5.zPool)/mem5.szAtom; + assert( i>=0 && i=0 && iLogsize<=LOGMAX ); + i = iFirst = mem5.aiFreelist[iLogsize]; + assert( iFirst>=0 ); + while( i>0 ){ + if( inext; + } + memsys5Unlink(iFirst, iLogsize); + return iFirst; +} + +/* +** Return a block of memory of at least nBytes in size. +** Return NULL if unable. Return NULL if nBytes==0. +** +** The caller guarantees that nByte positive. +** +** The caller has obtained a mutex prior to invoking this +** routine so there is never any chance that two or more +** threads can be in this routine at the same time. +*/ +static void *memsys5MallocUnsafe(int nByte){ + int i; /* Index of a mem5.aPool[] slot */ + int iBin; /* Index into mem5.aiFreelist[] */ + int iFullSz; /* Size of allocation rounded up to power of 2 */ + int iLogsize; /* Log2 of iFullSz/POW2_MIN */ + + /* nByte must be a positive */ + assert( nByte>0 ); + + /* Keep track of the maximum allocation request. Even unfulfilled + ** requests are counted */ + if( (u32)nByte>mem5.maxRequest ){ + mem5.maxRequest = nByte; + } + + /* Abort if the requested allocation size is larger than the largest + ** power of two that we can represent using 32-bit signed integers. + */ + if( nByte > 0x40000000 ){ + return 0; + } + + /* Round nByte up to the next valid power of two */ + for(iFullSz=mem5.szAtom, iLogsize=0; iFullSzLOGMAX ){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes", nByte); + return 0; + } + i = memsys5UnlinkFirst(iBin); + while( iBin>iLogsize ){ + int newSize; + + iBin--; + newSize = 1 << iBin; + mem5.aCtrl[i+newSize] = CTRL_FREE | iBin; + memsys5Link(i+newSize, iBin); + } + mem5.aCtrl[i] = iLogsize; + + /* Update allocator performance statistics. */ + mem5.nAlloc++; + mem5.totalAlloc += iFullSz; + mem5.totalExcess += iFullSz - nByte; + mem5.currentCount++; + mem5.currentOut += iFullSz; + if( mem5.maxCount=0 && iBlock0 ); + assert( mem5.currentOut>=(size*mem5.szAtom) ); + mem5.currentCount--; + mem5.currentOut -= size*mem5.szAtom; + assert( mem5.currentOut>0 || mem5.currentCount==0 ); + assert( mem5.currentCount>0 || mem5.currentOut==0 ); + + mem5.aCtrl[iBlock] = CTRL_FREE | iLogsize; + while( ALWAYS(iLogsize>iLogsize) & 1 ){ + iBuddy = iBlock - size; + }else{ + iBuddy = iBlock + size; + } + assert( iBuddy>=0 ); + if( (iBuddy+(1<mem5.nBlock ) break; + if( mem5.aCtrl[iBuddy]!=(CTRL_FREE | iLogsize) ) break; + memsys5Unlink(iBuddy, iLogsize); + iLogsize++; + if( iBuddy0 ){ + memsys5Enter(); + p = memsys5MallocUnsafe(nBytes); + memsys5Leave(); + } + return (void*)p; +} + +/* +** Free memory. +** +** The outer layer memory allocator prevents this routine from +** being called with pPrior==0. +*/ +static void memsys5Free(void *pPrior){ + assert( pPrior!=0 ); + memsys5Enter(); + memsys5FreeUnsafe(pPrior); + memsys5Leave(); +} + +/* +** Change the size of an existing memory allocation. +** +** The outer layer memory allocator prevents this routine from +** being called with pPrior==0. +** +** nBytes is always a value obtained from a prior call to +** memsys5Round(). Hence nBytes is always a non-negative power +** of two. If nBytes==0 that means that an oversize allocation +** (an allocation larger than 0x40000000) was requested and this +** routine should return 0 without freeing pPrior. +*/ +static void *memsys5Realloc(void *pPrior, int nBytes){ + int nOld; + void *p; + assert( pPrior!=0 ); + assert( (nBytes&(nBytes-1))==0 ); /* EV: R-46199-30249 */ + assert( nBytes>=0 ); + if( nBytes==0 ){ + return 0; + } + nOld = memsys5Size(pPrior); + if( nBytes<=nOld ){ + return pPrior; + } + memsys5Enter(); + p = memsys5MallocUnsafe(nBytes); + if( p ){ + memcpy(p, pPrior, nOld); + memsys5FreeUnsafe(pPrior); + } + memsys5Leave(); + return p; +} + +/* +** Round up a request size to the next valid allocation size. If +** the allocation is too large to be handled by this allocation system, +** return 0. +** +** All allocations must be a power of two and must be expressed by a +** 32-bit signed integer. Hence the largest allocation is 0x40000000 +** or 1073741824 bytes. +*/ +static int memsys5Roundup(int n){ + int iFullSz; + if( n > 0x40000000 ) return 0; + for(iFullSz=mem5.szAtom; iFullSz 0 +** memsys5Log(2) -> 1 +** memsys5Log(4) -> 2 +** memsys5Log(5) -> 3 +** memsys5Log(8) -> 3 +** memsys5Log(9) -> 4 +*/ +static int memsys5Log(int iValue){ + int iLog; + for(iLog=0; (iLog<(int)((sizeof(int)*8)-1)) && (1<mem5.szAtom ){ + mem5.szAtom = mem5.szAtom << 1; + } + + mem5.nBlock = (nByte / (mem5.szAtom+sizeof(u8))); + mem5.zPool = zByte; + mem5.aCtrl = (u8 *)&mem5.zPool[mem5.nBlock*mem5.szAtom]; + + for(ii=0; ii<=LOGMAX; ii++){ + mem5.aiFreelist[ii] = -1; + } + + iOffset = 0; + for(ii=LOGMAX; ii>=0; ii--){ + int nAlloc = (1<mem5.nBlock); + } + + /* If a mutex is required for normal operation, allocate one */ + if( sqlite3GlobalConfig.bMemstat==0 ){ + mem5.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); + } + + return SQLITE_OK; +} + +/* +** Deinitialize this module. +*/ +static void memsys5Shutdown(void *NotUsed){ + UNUSED_PARAMETER(NotUsed); + mem5.mutex = 0; + return; +} + +#ifdef SQLITE_TEST +/* +** Open the file indicated and write a log of all unfreed memory +** allocations into that log. +*/ +void sqlite3Memsys5Dump(const char *zFilename){ + FILE *out; + int i, j, n; + int nMinLog; + + if( zFilename==0 || zFilename[0]==0 ){ + out = stdout; + }else{ + out = fopen(zFilename, "w"); + if( out==0 ){ + fprintf(stderr, "** Unable to output memory debug output log: %s **\n", + zFilename); + return; + } + } + memsys5Enter(); + nMinLog = memsys5Log(mem5.szAtom); + for(i=0; i<=LOGMAX && i+nMinLog<32; i++){ + for(n=0, j=mem5.aiFreelist[i]; j>=0; j = MEM5LINK(j)->next, n++){} + fprintf(out, "freelist items of size %d: %d\n", mem5.szAtom << i, n); + } + fprintf(out, "mem5.nAlloc = %llu\n", mem5.nAlloc); + fprintf(out, "mem5.totalAlloc = %llu\n", mem5.totalAlloc); + fprintf(out, "mem5.totalExcess = %llu\n", mem5.totalExcess); + fprintf(out, "mem5.currentOut = %u\n", mem5.currentOut); + fprintf(out, "mem5.currentCount = %u\n", mem5.currentCount); + fprintf(out, "mem5.maxOut = %u\n", mem5.maxOut); + fprintf(out, "mem5.maxCount = %u\n", mem5.maxCount); + fprintf(out, "mem5.maxRequest = %u\n", mem5.maxRequest); + memsys5Leave(); + if( out==stdout ){ + fflush(stdout); + }else{ + fclose(out); + } +} +#endif + +/* +** This routine is the only routine in this file with external +** linkage. It returns a pointer to a static sqlite3_mem_methods +** struct populated with the memsys5 methods. +*/ +const sqlite3_mem_methods *sqlite3MemGetMemsys5(void){ + static const sqlite3_mem_methods memsys5Methods = { + memsys5Malloc, + memsys5Free, + memsys5Realloc, + memsys5Size, + memsys5Roundup, + memsys5Init, + memsys5Shutdown, + 0 + }; + return &memsys5Methods; +} + +#endif /* SQLITE_ENABLE_MEMSYS5 */ diff --git a/scalos/libraries/sqlite/src/memjournal.c b/scalos/libraries/sqlite/src/memjournal.c new file mode 100644 index 000000000..3e66e215b --- /dev/null +++ b/scalos/libraries/sqlite/src/memjournal.c @@ -0,0 +1,259 @@ +/* +** 2008 October 7 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains code use to implement an in-memory rollback journal. +** The in-memory rollback journal is used to journal transactions for +** ":memory:" databases and when the journal_mode=MEMORY pragma is used. +*/ +#include "sqliteInt.h" + +/* Forward references to internal structures */ +typedef struct MemJournal MemJournal; +typedef struct FilePoint FilePoint; +typedef struct FileChunk FileChunk; + +/* Space to hold the rollback journal is allocated in increments of +** this many bytes. +** +** The size chosen is a little less than a power of two. That way, +** the FileChunk object will have a size that almost exactly fills +** a power-of-two allocation. This mimimizes wasted space in power-of-two +** memory allocators. +*/ +#define JOURNAL_CHUNKSIZE ((int)(1024-sizeof(FileChunk*))) + +/* Macro to find the minimum of two numeric values. +*/ +#ifndef MIN +# define MIN(x,y) ((x)<(y)?(x):(y)) +#endif + +/* +** The rollback journal is composed of a linked list of these structures. +*/ +struct FileChunk { + FileChunk *pNext; /* Next chunk in the journal */ + u8 zChunk[JOURNAL_CHUNKSIZE]; /* Content of this chunk */ +}; + +/* +** An instance of this object serves as a cursor into the rollback journal. +** The cursor can be either for reading or writing. +*/ +struct FilePoint { + sqlite3_int64 iOffset; /* Offset from the beginning of the file */ + FileChunk *pChunk; /* Specific chunk into which cursor points */ +}; + +/* +** This subclass is a subclass of sqlite3_file. Each open memory-journal +** is an instance of this class. +*/ +struct MemJournal { + sqlite3_io_methods *pMethod; /* Parent class. MUST BE FIRST */ + FileChunk *pFirst; /* Head of in-memory chunk-list */ + FilePoint endpoint; /* Pointer to the end of the file */ + FilePoint readpoint; /* Pointer to the end of the last xRead() */ +}; + +/* +** Read data from the in-memory journal file. This is the implementation +** of the sqlite3_vfs.xRead method. +*/ +static int memjrnlRead( + sqlite3_file *pJfd, /* The journal file from which to read */ + void *zBuf, /* Put the results here */ + int iAmt, /* Number of bytes to read */ + sqlite_int64 iOfst /* Begin reading at this offset */ +){ + MemJournal *p = (MemJournal *)pJfd; + u8 *zOut = zBuf; + int nRead = iAmt; + int iChunkOffset; + FileChunk *pChunk; + + /* SQLite never tries to read past the end of a rollback journal file */ + assert( iOfst+iAmt<=p->endpoint.iOffset ); + + if( p->readpoint.iOffset!=iOfst || iOfst==0 ){ + sqlite3_int64 iOff = 0; + for(pChunk=p->pFirst; + ALWAYS(pChunk) && (iOff+JOURNAL_CHUNKSIZE)<=iOfst; + pChunk=pChunk->pNext + ){ + iOff += JOURNAL_CHUNKSIZE; + } + }else{ + pChunk = p->readpoint.pChunk; + } + + iChunkOffset = (int)(iOfst%JOURNAL_CHUNKSIZE); + do { + int iSpace = JOURNAL_CHUNKSIZE - iChunkOffset; + int nCopy = MIN(nRead, (JOURNAL_CHUNKSIZE - iChunkOffset)); + memcpy(zOut, &pChunk->zChunk[iChunkOffset], nCopy); + zOut += nCopy; + nRead -= iSpace; + iChunkOffset = 0; + } while( nRead>=0 && (pChunk=pChunk->pNext)!=0 && nRead>0 ); + p->readpoint.iOffset = iOfst+iAmt; + p->readpoint.pChunk = pChunk; + + return SQLITE_OK; +} + +/* +** Write data to the file. +*/ +static int memjrnlWrite( + sqlite3_file *pJfd, /* The journal file into which to write */ + const void *zBuf, /* Take data to be written from here */ + int iAmt, /* Number of bytes to write */ + sqlite_int64 iOfst /* Begin writing at this offset into the file */ +){ + MemJournal *p = (MemJournal *)pJfd; + int nWrite = iAmt; + u8 *zWrite = (u8 *)zBuf; + + /* An in-memory journal file should only ever be appended to. Random + ** access writes are not required by sqlite. + */ + assert( iOfst==p->endpoint.iOffset ); + UNUSED_PARAMETER(iOfst); + + while( nWrite>0 ){ + FileChunk *pChunk = p->endpoint.pChunk; + int iChunkOffset = (int)(p->endpoint.iOffset%JOURNAL_CHUNKSIZE); + int iSpace = MIN(nWrite, JOURNAL_CHUNKSIZE - iChunkOffset); + + if( iChunkOffset==0 ){ + /* New chunk is required to extend the file. */ + FileChunk *pNew = sqlite3_malloc(sizeof(FileChunk)); + if( !pNew ){ + return SQLITE_IOERR_NOMEM; + } + pNew->pNext = 0; + if( pChunk ){ + assert( p->pFirst ); + pChunk->pNext = pNew; + }else{ + assert( !p->pFirst ); + p->pFirst = pNew; + } + p->endpoint.pChunk = pNew; + } + + memcpy(&p->endpoint.pChunk->zChunk[iChunkOffset], zWrite, iSpace); + zWrite += iSpace; + nWrite -= iSpace; + p->endpoint.iOffset += iSpace; + } + + return SQLITE_OK; +} + +/* +** Truncate the file. +*/ +static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){ + MemJournal *p = (MemJournal *)pJfd; + FileChunk *pChunk; + assert(size==0); + UNUSED_PARAMETER(size); + pChunk = p->pFirst; + while( pChunk ){ + FileChunk *pTmp = pChunk; + pChunk = pChunk->pNext; + sqlite3_free(pTmp); + } + sqlite3MemJournalOpen(pJfd); + return SQLITE_OK; +} + +/* +** Close the file. +*/ +static int memjrnlClose(sqlite3_file *pJfd){ + memjrnlTruncate(pJfd, 0); + return SQLITE_OK; +} + + +/* +** Sync the file. +** +** Syncing an in-memory journal is a no-op. And, in fact, this routine +** is never called in a working implementation. This implementation +** exists purely as a contingency, in case some malfunction in some other +** part of SQLite causes Sync to be called by mistake. +*/ +static int memjrnlSync(sqlite3_file *NotUsed, int NotUsed2){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + return SQLITE_OK; +} + +/* +** Query the size of the file in bytes. +*/ +static int memjrnlFileSize(sqlite3_file *pJfd, sqlite_int64 *pSize){ + MemJournal *p = (MemJournal *)pJfd; + *pSize = (sqlite_int64) p->endpoint.iOffset; + return SQLITE_OK; +} + +/* +** Table of methods for MemJournal sqlite3_file object. +*/ +static const struct sqlite3_io_methods MemJournalMethods = { + 1, /* iVersion */ + memjrnlClose, /* xClose */ + memjrnlRead, /* xRead */ + memjrnlWrite, /* xWrite */ + memjrnlTruncate, /* xTruncate */ + memjrnlSync, /* xSync */ + memjrnlFileSize, /* xFileSize */ + 0, /* xLock */ + 0, /* xUnlock */ + 0, /* xCheckReservedLock */ + 0, /* xFileControl */ + 0, /* xSectorSize */ + 0, /* xDeviceCharacteristics */ + 0, /* xShmMap */ + 0, /* xShmLock */ + 0, /* xShmBarrier */ + 0 /* xShmUnlock */ +}; + +/* +** Open a journal file. +*/ +void sqlite3MemJournalOpen(sqlite3_file *pJfd){ + MemJournal *p = (MemJournal *)pJfd; + assert( EIGHT_BYTE_ALIGNMENT(p) ); + memset(p, 0, sqlite3MemJournalSize()); + p->pMethod = (sqlite3_io_methods*)&MemJournalMethods; +} + +/* +** Return true if the file-handle passed as an argument is +** an in-memory journal +*/ +int sqlite3IsMemJournal(sqlite3_file *pJfd){ + return pJfd->pMethods==&MemJournalMethods; +} + +/* +** Return the number of bytes required to store a MemJournal file descriptor. +*/ +int sqlite3MemJournalSize(void){ + return sizeof(MemJournal); +} diff --git a/scalos/libraries/sqlite/src/mutex.c b/scalos/libraries/sqlite/src/mutex.c new file mode 100644 index 000000000..b567e7c27 --- /dev/null +++ b/scalos/libraries/sqlite/src/mutex.c @@ -0,0 +1,153 @@ +/* +** 2007 August 14 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains the C functions that implement mutexes. +** +** This file contains code that is common across all mutex implementations. +*/ +#include "sqliteInt.h" + +#if defined(SQLITE_DEBUG) && !defined(SQLITE_MUTEX_OMIT) +/* +** For debugging purposes, record when the mutex subsystem is initialized +** and uninitialized so that we can assert() if there is an attempt to +** allocate a mutex while the system is uninitialized. +*/ +static SQLITE_WSD int mutexIsInit = 0; +#endif /* SQLITE_DEBUG */ + + +#ifndef SQLITE_MUTEX_OMIT +/* +** Initialize the mutex system. +*/ +int sqlite3MutexInit(void){ + int rc = SQLITE_OK; + if( !sqlite3GlobalConfig.mutex.xMutexAlloc ){ + /* If the xMutexAlloc method has not been set, then the user did not + ** install a mutex implementation via sqlite3_config() prior to + ** sqlite3_initialize() being called. This block copies pointers to + ** the default implementation into the sqlite3GlobalConfig structure. + */ + sqlite3_mutex_methods const *pFrom; + sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex; + + if( sqlite3GlobalConfig.bCoreMutex ){ + pFrom = sqlite3DefaultMutex(); + }else{ + pFrom = sqlite3NoopMutex(); + } + memcpy(pTo, pFrom, offsetof(sqlite3_mutex_methods, xMutexAlloc)); + memcpy(&pTo->xMutexFree, &pFrom->xMutexFree, + sizeof(*pTo) - offsetof(sqlite3_mutex_methods, xMutexFree)); + pTo->xMutexAlloc = pFrom->xMutexAlloc; + } + rc = sqlite3GlobalConfig.mutex.xMutexInit(); + +#ifdef SQLITE_DEBUG + GLOBAL(int, mutexIsInit) = 1; +#endif + + return rc; +} + +/* +** Shutdown the mutex system. This call frees resources allocated by +** sqlite3MutexInit(). +*/ +int sqlite3MutexEnd(void){ + int rc = SQLITE_OK; + if( sqlite3GlobalConfig.mutex.xMutexEnd ){ + rc = sqlite3GlobalConfig.mutex.xMutexEnd(); + } + +#ifdef SQLITE_DEBUG + GLOBAL(int, mutexIsInit) = 0; +#endif + + return rc; +} + +/* +** Retrieve a pointer to a static mutex or allocate a new dynamic one. +*/ +sqlite3_mutex *sqlite3_mutex_alloc(int id){ +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return sqlite3GlobalConfig.mutex.xMutexAlloc(id); +} + +sqlite3_mutex *sqlite3MutexAlloc(int id){ + if( !sqlite3GlobalConfig.bCoreMutex ){ + return 0; + } + assert( GLOBAL(int, mutexIsInit) ); + return sqlite3GlobalConfig.mutex.xMutexAlloc(id); +} + +/* +** Free a dynamic mutex. +*/ +void sqlite3_mutex_free(sqlite3_mutex *p){ + if( p ){ + sqlite3GlobalConfig.mutex.xMutexFree(p); + } +} + +/* +** Obtain the mutex p. If some other thread already has the mutex, block +** until it can be obtained. +*/ +void sqlite3_mutex_enter(sqlite3_mutex *p){ + if( p ){ + sqlite3GlobalConfig.mutex.xMutexEnter(p); + } +} + +/* +** Obtain the mutex p. If successful, return SQLITE_OK. Otherwise, if another +** thread holds the mutex and it cannot be obtained, return SQLITE_BUSY. +*/ +int sqlite3_mutex_try(sqlite3_mutex *p){ + int rc = SQLITE_OK; + if( p ){ + return sqlite3GlobalConfig.mutex.xMutexTry(p); + } + return rc; +} + +/* +** The sqlite3_mutex_leave() routine exits a mutex that was previously +** entered by the same thread. The behavior is undefined if the mutex +** is not currently entered. If a NULL pointer is passed as an argument +** this function is a no-op. +*/ +void sqlite3_mutex_leave(sqlite3_mutex *p){ + if( p ){ + sqlite3GlobalConfig.mutex.xMutexLeave(p); + } +} + +#ifndef NDEBUG +/* +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are +** intended for use inside assert() statements. +*/ +int sqlite3_mutex_held(sqlite3_mutex *p){ + return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p); +} +int sqlite3_mutex_notheld(sqlite3_mutex *p){ + return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p); +} +#endif + +#endif /* !defined(SQLITE_MUTEX_OMIT) */ diff --git a/scalos/libraries/sqlite/src/mutex.h b/scalos/libraries/sqlite/src/mutex.h new file mode 100644 index 000000000..b0e552c7c --- /dev/null +++ b/scalos/libraries/sqlite/src/mutex.h @@ -0,0 +1,74 @@ +/* +** 2007 August 28 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains the common header for all mutex implementations. +** The sqliteInt.h header #includes this file so that it is available +** to all source files. We break it out in an effort to keep the code +** better organized. +** +** NOTE: source files should *not* #include this header file directly. +** Source files should #include the sqliteInt.h file and let that file +** include this one indirectly. +*/ + + +/* +** Figure out what version of the code to use. The choices are +** +** SQLITE_MUTEX_OMIT No mutex logic. Not even stubs. The +** mutexes implemention cannot be overridden +** at start-time. +** +** SQLITE_MUTEX_NOOP For single-threaded applications. No +** mutual exclusion is provided. But this +** implementation can be overridden at +** start-time. +** +** SQLITE_MUTEX_PTHREADS For multi-threaded applications on Unix. +** +** SQLITE_MUTEX_W32 For multi-threaded applications on Win32. +** +** SQLITE_MUTEX_OS2 For multi-threaded applications on OS/2. +*/ +#if !SQLITE_THREADSAFE +# define SQLITE_MUTEX_OMIT +#endif +#if SQLITE_THREADSAFE && !defined(SQLITE_MUTEX_NOOP) +# if SQLITE_OS_UNIX +# define SQLITE_MUTEX_PTHREADS +# elif SQLITE_OS_WIN +# define SQLITE_MUTEX_W32 +# elif SQLITE_OS_OS2 +# define SQLITE_MUTEX_OS2 +# else +# define SQLITE_MUTEX_NOOP +# endif +#endif + +#ifdef SQLITE_MUTEX_OMIT +/* +** If this is a no-op implementation, implement everything as macros. +*/ +#define sqlite3_mutex_alloc(X) ((sqlite3_mutex*)8) +#define sqlite3_mutex_free(X) +#define sqlite3_mutex_enter(X) +#define sqlite3_mutex_try(X) SQLITE_OK +#define sqlite3_mutex_leave(X) +#define sqlite3_mutex_held(X) ((void)(X),1) +#define sqlite3_mutex_notheld(X) ((void)(X),1) +#define sqlite3MutexAlloc(X) ((sqlite3_mutex*)8) +#define sqlite3MutexInit() SQLITE_OK +#define sqlite3MutexEnd() +#define MUTEX_LOGIC(X) +#else +#define MUTEX_LOGIC(X) X +#endif /* defined(SQLITE_MUTEX_OMIT) */ diff --git a/scalos/libraries/sqlite/src/mutex_noop.c b/scalos/libraries/sqlite/src/mutex_noop.c new file mode 100644 index 000000000..456e82a25 --- /dev/null +++ b/scalos/libraries/sqlite/src/mutex_noop.c @@ -0,0 +1,206 @@ +/* +** 2008 October 07 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains the C functions that implement mutexes. +** +** This implementation in this file does not provide any mutual +** exclusion and is thus suitable for use only in applications +** that use SQLite in a single thread. The routines defined +** here are place-holders. Applications can substitute working +** mutex routines at start-time using the +** +** sqlite3_config(SQLITE_CONFIG_MUTEX,...) +** +** interface. +** +** If compiled with SQLITE_DEBUG, then additional logic is inserted +** that does error checking on mutexes to make sure they are being +** called correctly. +*/ +#include "sqliteInt.h" + +#ifndef SQLITE_MUTEX_OMIT + +#ifndef SQLITE_DEBUG +/* +** Stub routines for all mutex methods. +** +** This routines provide no mutual exclusion or error checking. +*/ +static int noopMutexInit(void){ return SQLITE_OK; } +static int noopMutexEnd(void){ return SQLITE_OK; } +static sqlite3_mutex *noopMutexAlloc(int id){ + UNUSED_PARAMETER(id); + return (sqlite3_mutex*)8; +} +static void noopMutexFree(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } +static void noopMutexEnter(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } +static int noopMutexTry(sqlite3_mutex *p){ + UNUSED_PARAMETER(p); + return SQLITE_OK; +} +static void noopMutexLeave(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } + +sqlite3_mutex_methods const *sqlite3NoopMutex(void){ + static const sqlite3_mutex_methods sMutex = { + noopMutexInit, + noopMutexEnd, + noopMutexAlloc, + noopMutexFree, + noopMutexEnter, + noopMutexTry, + noopMutexLeave, + + 0, + 0, + }; + + return &sMutex; +} +#endif /* !SQLITE_DEBUG */ + +#ifdef SQLITE_DEBUG +/* +** In this implementation, error checking is provided for testing +** and debugging purposes. The mutexes still do not provide any +** mutual exclusion. +*/ + +/* +** The mutex object +*/ +typedef struct sqlite3_debug_mutex { + int id; /* The mutex type */ + int cnt; /* Number of entries without a matching leave */ +} sqlite3_debug_mutex; + +/* +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are +** intended for use inside assert() statements. +*/ +static int debugMutexHeld(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; + return p==0 || p->cnt>0; +} +static int debugMutexNotheld(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; + return p==0 || p->cnt==0; +} + +/* +** Initialize and deinitialize the mutex subsystem. +*/ +static int debugMutexInit(void){ return SQLITE_OK; } +static int debugMutexEnd(void){ return SQLITE_OK; } + +/* +** The sqlite3_mutex_alloc() routine allocates a new +** mutex and returns a pointer to it. If it returns NULL +** that means that a mutex could not be allocated. +*/ +static sqlite3_mutex *debugMutexAlloc(int id){ + static sqlite3_debug_mutex aStatic[6]; + sqlite3_debug_mutex *pNew = 0; + switch( id ){ + case SQLITE_MUTEX_FAST: + case SQLITE_MUTEX_RECURSIVE: { + pNew = sqlite3Malloc(sizeof(*pNew)); + if( pNew ){ + pNew->id = id; + pNew->cnt = 0; + } + break; + } + default: { + assert( id-2 >= 0 ); + assert( id-2 < (int)(sizeof(aStatic)/sizeof(aStatic[0])) ); + pNew = &aStatic[id-2]; + pNew->id = id; + break; + } + } + return (sqlite3_mutex*)pNew; +} + +/* +** This routine deallocates a previously allocated mutex. +*/ +static void debugMutexFree(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; + assert( p->cnt==0 ); + assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); + sqlite3_free(p); +} + +/* +** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt +** to enter a mutex. If another thread is already within the mutex, +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK +** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can +** be entered multiple times by the same thread. In such cases the, +** mutex must be exited an equal number of times before another thread +** can enter. If the same thread tries to enter any other kind of mutex +** more than once, the behavior is undefined. +*/ +static void debugMutexEnter(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; + assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); + p->cnt++; +} +static int debugMutexTry(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; + assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); + p->cnt++; + return SQLITE_OK; +} + +/* +** The sqlite3_mutex_leave() routine exits a mutex that was +** previously entered by the same thread. The behavior +** is undefined if the mutex is not currently entered or +** is not currently allocated. SQLite will never do either. +*/ +static void debugMutexLeave(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; + assert( debugMutexHeld(pX) ); + p->cnt--; + assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); +} + +sqlite3_mutex_methods const *sqlite3NoopMutex(void){ + static const sqlite3_mutex_methods sMutex = { + debugMutexInit, + debugMutexEnd, + debugMutexAlloc, + debugMutexFree, + debugMutexEnter, + debugMutexTry, + debugMutexLeave, + + debugMutexHeld, + debugMutexNotheld + }; + + return &sMutex; +} +#endif /* SQLITE_DEBUG */ + +/* +** If compiled with SQLITE_MUTEX_NOOP, then the no-op mutex implementation +** is used regardless of the run-time threadsafety setting. +*/ +#ifdef SQLITE_MUTEX_NOOP +sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ + return sqlite3NoopMutex(); +} +#endif /* defined(SQLITE_MUTEX_NOOP) */ +#endif /* !defined(SQLITE_MUTEX_OMIT) */ diff --git a/scalos/libraries/sqlite/src/mutex_os2.c b/scalos/libraries/sqlite/src/mutex_os2.c new file mode 100644 index 000000000..ce650d994 --- /dev/null +++ b/scalos/libraries/sqlite/src/mutex_os2.c @@ -0,0 +1,274 @@ +/* +** 2007 August 28 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains the C functions that implement mutexes for OS/2 +*/ +#include "sqliteInt.h" + +/* +** The code in this file is only used if SQLITE_MUTEX_OS2 is defined. +** See the mutex.h file for details. +*/ +#ifdef SQLITE_MUTEX_OS2 + +/********************** OS/2 Mutex Implementation ********************** +** +** This implementation of mutexes is built using the OS/2 API. +*/ + +/* +** The mutex object +** Each recursive mutex is an instance of the following structure. +*/ +struct sqlite3_mutex { + HMTX mutex; /* Mutex controlling the lock */ + int id; /* Mutex type */ +#ifdef SQLITE_DEBUG + int trace; /* True to trace changes */ +#endif +}; + +#ifdef SQLITE_DEBUG +#define SQLITE3_MUTEX_INITIALIZER { 0, 0, 0 } +#else +#define SQLITE3_MUTEX_INITIALIZER { 0, 0 } +#endif + +/* +** Initialize and deinitialize the mutex subsystem. +*/ +static int os2MutexInit(void){ return SQLITE_OK; } +static int os2MutexEnd(void){ return SQLITE_OK; } + +/* +** The sqlite3_mutex_alloc() routine allocates a new +** mutex and returns a pointer to it. If it returns NULL +** that means that a mutex could not be allocated. +** SQLite will unwind its stack and return an error. The argument +** to sqlite3_mutex_alloc() is one of these integer constants: +** +**
    +**
  • SQLITE_MUTEX_FAST +**
  • SQLITE_MUTEX_RECURSIVE +**
  • SQLITE_MUTEX_STATIC_MASTER +**
  • SQLITE_MUTEX_STATIC_MEM +**
  • SQLITE_MUTEX_STATIC_MEM2 +**
  • SQLITE_MUTEX_STATIC_PRNG +**
  • SQLITE_MUTEX_STATIC_LRU +**
  • SQLITE_MUTEX_STATIC_LRU2 +**
+** +** The first two constants cause sqlite3_mutex_alloc() to create +** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE +** is used but not necessarily so when SQLITE_MUTEX_FAST is used. +** The mutex implementation does not need to make a distinction +** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does +** not want to. But SQLite will only request a recursive mutex in +** cases where it really needs one. If a faster non-recursive mutex +** implementation is available on the host platform, the mutex subsystem +** might return such a mutex in response to SQLITE_MUTEX_FAST. +** +** The other allowed parameters to sqlite3_mutex_alloc() each return +** a pointer to a static preexisting mutex. Six static mutexes are +** used by the current version of SQLite. Future versions of SQLite +** may add additional static mutexes. Static mutexes are for internal +** use by SQLite only. Applications that use SQLite mutexes should +** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or +** SQLITE_MUTEX_RECURSIVE. +** +** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST +** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() +** returns a different mutex on every call. But for the static +** mutex types, the same mutex is returned on every call that has +** the same type number. +*/ +static sqlite3_mutex *os2MutexAlloc(int iType){ + sqlite3_mutex *p = NULL; + switch( iType ){ + case SQLITE_MUTEX_FAST: + case SQLITE_MUTEX_RECURSIVE: { + p = sqlite3MallocZero( sizeof(*p) ); + if( p ){ + p->id = iType; + if( DosCreateMutexSem( 0, &p->mutex, 0, FALSE ) != NO_ERROR ){ + sqlite3_free( p ); + p = NULL; + } + } + break; + } + default: { + static volatile int isInit = 0; + static sqlite3_mutex staticMutexes[6] = { + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + }; + if ( !isInit ){ + APIRET rc; + PTIB ptib; + PPIB ppib; + HMTX mutex; + char name[32]; + DosGetInfoBlocks( &ptib, &ppib ); + sqlite3_snprintf( sizeof(name), name, "\\SEM32\\SQLITE%04x", + ppib->pib_ulpid ); + while( !isInit ){ + mutex = 0; + rc = DosCreateMutexSem( name, &mutex, 0, FALSE); + if( rc == NO_ERROR ){ + unsigned int i; + if( !isInit ){ + for( i = 0; i < sizeof(staticMutexes)/sizeof(staticMutexes[0]); i++ ){ + DosCreateMutexSem( 0, &staticMutexes[i].mutex, 0, FALSE ); + } + isInit = 1; + } + DosCloseMutexSem( mutex ); + }else if( rc == ERROR_DUPLICATE_NAME ){ + DosSleep( 1 ); + }else{ + return p; + } + } + } + assert( iType-2 >= 0 ); + assert( iType-2 < sizeof(staticMutexes)/sizeof(staticMutexes[0]) ); + p = &staticMutexes[iType-2]; + p->id = iType; + break; + } + } + return p; +} + + +/* +** This routine deallocates a previously allocated mutex. +** SQLite is careful to deallocate every mutex that it allocates. +*/ +static void os2MutexFree(sqlite3_mutex *p){ +#ifdef SQLITE_DEBUG + TID tid; + PID pid; + ULONG ulCount; + DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); + assert( ulCount==0 ); + assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); +#endif + DosCloseMutexSem( p->mutex ); + sqlite3_free( p ); +} + +#ifdef SQLITE_DEBUG +/* +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are +** intended for use inside assert() statements. +*/ +static int os2MutexHeld(sqlite3_mutex *p){ + TID tid; + PID pid; + ULONG ulCount; + PTIB ptib; + DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); + if( ulCount==0 || ( ulCount>1 && p->id!=SQLITE_MUTEX_RECURSIVE ) ) + return 0; + DosGetInfoBlocks(&ptib, NULL); + return tid==ptib->tib_ptib2->tib2_ultid; +} +static int os2MutexNotheld(sqlite3_mutex *p){ + TID tid; + PID pid; + ULONG ulCount; + PTIB ptib; + DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); + if( ulCount==0 ) + return 1; + DosGetInfoBlocks(&ptib, NULL); + return tid!=ptib->tib_ptib2->tib2_ultid; +} +static void os2MutexTrace(sqlite3_mutex *p, char *pAction){ + TID tid; + PID pid; + ULONG ulCount; + DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); + printf("%s mutex %p (%d) with nRef=%ld\n", pAction, (void*)p, p->trace, ulCount); +} +#endif + +/* +** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt +** to enter a mutex. If another thread is already within the mutex, +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK +** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can +** be entered multiple times by the same thread. In such cases the, +** mutex must be exited an equal number of times before another thread +** can enter. If the same thread tries to enter any other kind of mutex +** more than once, the behavior is undefined. +*/ +static void os2MutexEnter(sqlite3_mutex *p){ + assert( p->id==SQLITE_MUTEX_RECURSIVE || os2MutexNotheld(p) ); + DosRequestMutexSem(p->mutex, SEM_INDEFINITE_WAIT); +#ifdef SQLITE_DEBUG + if( p->trace ) os2MutexTrace(p, "enter"); +#endif +} +static int os2MutexTry(sqlite3_mutex *p){ + int rc = SQLITE_BUSY; + assert( p->id==SQLITE_MUTEX_RECURSIVE || os2MutexNotheld(p) ); + if( DosRequestMutexSem(p->mutex, SEM_IMMEDIATE_RETURN) == NO_ERROR ) { + rc = SQLITE_OK; +#ifdef SQLITE_DEBUG + if( p->trace ) os2MutexTrace(p, "try"); +#endif + } + return rc; +} + +/* +** The sqlite3_mutex_leave() routine exits a mutex that was +** previously entered by the same thread. The behavior +** is undefined if the mutex is not currently entered or +** is not currently allocated. SQLite will never do either. +*/ +static void os2MutexLeave(sqlite3_mutex *p){ + assert( os2MutexHeld(p) ); + DosReleaseMutexSem(p->mutex); +#ifdef SQLITE_DEBUG + if( p->trace ) os2MutexTrace(p, "leave"); +#endif +} + +sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ + static const sqlite3_mutex_methods sMutex = { + os2MutexInit, + os2MutexEnd, + os2MutexAlloc, + os2MutexFree, + os2MutexEnter, + os2MutexTry, + os2MutexLeave, +#ifdef SQLITE_DEBUG + os2MutexHeld, + os2MutexNotheld +#else + 0, + 0 +#endif + }; + + return &sMutex; +} +#endif /* SQLITE_MUTEX_OS2 */ diff --git a/scalos/libraries/sqlite/src/mutex_other.c b/scalos/libraries/sqlite/src/mutex_other.c new file mode 100644 index 000000000..f2f7417b9 --- /dev/null +++ b/scalos/libraries/sqlite/src/mutex_other.c @@ -0,0 +1,324 @@ +/* +** 2007 August 28 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains the C functions that implement mutexes for OS/2 +** +** $Id$ +*/ + +/* +** The code in this file is only used if SQLITE_MUTEX_OTHER is defined. +** See the mutex.h file for details. +*/ +#ifdef SQLITE_OS_OTHER +#ifndef SQLITE_MUTEX_OMIT + + +#include +#include + +#undef GLOBAL + +#include "os_other.h" +#include "sqliteInt.h" + +//#define SQLITE_DEBUG + +#include "sqlite3_base.h" +#include "LibSQLite3.h" + +#if defined(SQLITE_DEBUG) +#undef d2 +#define d2(x) x +#endif /* SQLITE_DEBUG */ + + +/********************** Amiga Mutex Implementation ********************** +** +** This implementation of mutexes is built using the AMigaOS API. +*/ + + +static int otherMutexInit(void); +static int otherMutexEnd(void); +static sqlite3_mutex *otherMutexAlloc(int iType); +static void otherMutexFree(sqlite3_mutex *p); +static void otherMutexEnter(sqlite3_mutex *p); +static int otherMutexTry(sqlite3_mutex *p); +static void otherMutexLeave(sqlite3_mutex *p); +#ifdef SQLITE_DEBUG +static int otherMutexHeld(sqlite3_mutex *p); +static int otherMutexNotheld(sqlite3_mutex *p); +#endif /* SQLITE_DEBUG */ + + +/* +** The mutex object +** Each recursive mutex is an instance of the following structure. +*/ +struct sqlite3_mutex +{ + struct SignalSemaphore sema; // Semaphore controlling the lock + int id; /* Mutex type */ + int nRef; /* Number of references */ + struct Task *owner; // Thread holding this mutex +}; + +/* +** Initialize and deinitialize the mutex subsystem. +*/ +static int otherMutexInit(void) +{ + return SQLITE_OK; +} + + +static int otherMutexEnd(void) +{ + return SQLITE_OK; +} + + +/* +** The sqlite3_mutex_alloc() routine allocates a new +** mutex and returns a pointer to it. If it returns NULL +** that means that a mutex could not be allocated. +** SQLite will unwind its stack and return an error. The argument +** to sqlite3_mutex_alloc() is one of these integer constants: +** +**
    +**
  • SQLITE_MUTEX_FAST 0 +**
  • SQLITE_MUTEX_RECURSIVE 1 +**
  • SQLITE_MUTEX_STATIC_MASTER 2 +**
  • SQLITE_MUTEX_STATIC_MEM 3 +**
  • SQLITE_MUTEX_STATIC_PRNG 4 +**
  • SQLITE_MUTEX_STATIC_LRU +**
+** +** The first two constants cause sqlite3_mutex_alloc() to create +** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE +** is used but not necessarily so when SQLITE_MUTEX_FAST is used. +** The mutex implementation does not need to make a distinction +** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does +** not want to. But SQLite will only request a recursive mutex in +** cases where it really needs one. If a faster non-recursive mutex +** implementation is available on the host platform, the mutex subsystem +** might return such a mutex in response to SQLITE_MUTEX_FAST. +** +** The other allowed parameters to sqlite3_mutex_alloc() each return +** a pointer to a static preexisting mutex. Three static mutexes are +** used by the current version of SQLite. Future versions of SQLite +** may add additional static mutexes. Static mutexes are for internal +** use by SQLite only. Applications that use SQLite mutexes should +** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or +** SQLITE_MUTEX_RECURSIVE. +** +** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST +** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() +** returns a different mutex on every call. But for the static +** mutex types, the same mutex is returned on every call that has +** the same type number. +*/ +static sqlite3_mutex *otherMutexAlloc(int iType) +{ + sqlite3_mutex *p; + + d1(KPrintF(__FILE__ "/%s/%ld: iType=%ld\n", __FUNC__, __LINE__, iType)); + + switch( iType ) + { + case SQLITE_MUTEX_FAST: + case SQLITE_MUTEX_RECURSIVE: + p = sqlite3MallocZero( sizeof(*p) ); + d1(KPrintF(__FILE__ "/%s/%ld: p=%08lx\n", __FUNC__, __LINE__, p)); + if( p ) + { + p->id = iType; + InitSemaphore(&p->sema); + } + break; + + default: + { + static sqlite3_mutex staticMutexes[6]; + static int isInit = 0; + + while( !isInit ) + { + static long lock = 0; + + Forbid(); + lock++; + if( lock == 1 ) + { + int i; + + Permit(); + + for(i = 0; i < sizeof(staticMutexes)/sizeof(staticMutexes[0]); i++) + { + InitSemaphore(&staticMutexes[i].sema); + } + isInit = 1; + } + else + { + Permit(); + Delay(1); + } + } + assert( iType-2 >= 0 ); + assert( iType-2 < sizeof(staticMutexes)/sizeof(staticMutexes[0]) ); + p = &staticMutexes[iType-2]; + p->id = iType; + d1(KPrintF(__FILE__ "/%s/%ld: p=%08lx\n", __FUNC__, __LINE__, p)); + break; + } + } + + d1(KPrintF(__FILE__ "/%s/%ld: p=%08lx\n", __FUNC__, __LINE__, p)); + + return p; +} + + +/* +** This routine deallocates a previously allocated mutex. +** SQLite is careful to deallocate every mutex that it allocates. +*/ +static void otherMutexFree(sqlite3_mutex *p) +{ + assert( p ); + assert( p->nRef==0 ); + assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); + + d1(KPrintF(__FILE__ "/%s/%ld: p=%08lx id=%ld\n", __FUNC__, __LINE__, p, p->id)); + sqlite3_free(p); + d1(KPrintF(__FILE__ "/%s/%ld: p=%08lx\n", __FUNC__, __LINE__, p)); +} + +/* +** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt +** to enter a mutex. If another thread is already within the mutex, +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK +** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can +** be entered multiple times by the same thread. In such cases the, +** mutex must be exited an equal number of times before another thread +** can enter. If the same thread tries to enter any other kind of mutex +** more than once, the behavior is undefined. +*/ +static void otherMutexEnter(sqlite3_mutex *p) +{ + assert( p ); + d1(KPrintF(__FILE__ "/%s/%ld: p=%08lx\n", __FUNC__, __LINE__, p)); + assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) ); + + ObtainSemaphore(&p->sema); + + p->owner = FindTask(NULL); + p->nRef++; + d1(KPrintF(__FILE__ "/%s/%ld: p=%08lx\n", __FUNC__, __LINE__, p)); +} + + +static int otherMutexTry(sqlite3_mutex *p) +{ + int rc; + + assert( p ); + assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) ); + + d1(KPrintF(__FILE__ "/%s/%ld: p=%08lx\n", __FUNC__, __LINE__, p)); + if (AttemptSemaphore(&p->sema)) + { + p->owner = FindTask(NULL); + p->nRef++; + rc = SQLITE_OK; + } + else + { + rc = SQLITE_BUSY; + } + + d1(KPrintF(__FILE__ "/%s/%ld: rc=%ld\n", __FUNC__, __LINE__, rc)); + + return rc; +} + +/* +** The sqlite3_mutex_leave() routine exits a mutex that was +** previously entered by the same thread. The behavior +** is undefined if the mutex is not currently entered or +** is not currently allocated. SQLite will never do either. +*/ +static void otherMutexLeave(sqlite3_mutex *p) +{ + struct Task *tid; + + d1(KPrintF(__FILE__ "/%s/%ld: p=%08lx\n", __FUNC__, __LINE__, p)); + assert( p ); + assert( p->nRef > 0 ); + tid = FindTask(NULL); + assert( p->owner==tid ); + p->nRef--; + assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); + ReleaseSemaphore(&p->sema); + d1(KPrintF(__FILE__ "/%s/%ld: p=%08lx\n", __FUNC__, __LINE__, p)); +} + +#ifdef SQLITE_DEBUG +/* +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are +** intended for use inside assert() statements. +*/ +static int otherMutexHeld(sqlite3_mutex *p) +{ + struct Task *tid; + + tid = FindTask(NULL); + return p==NULL || (p->nRef!=0 && p->owner==tid); +} + +static int otherMutexNotheld(sqlite3_mutex *p) +{ + struct Task *tid; + + tid = FindTask(NULL); + + return p==NULL || p->nRef==0 || p->owner!=tid; +} +#endif /* SQLITE_DEBUG */ + +sqlite3_mutex_methods *sqlite3OtherMutex(void) +{ + static sqlite3_mutex_methods sMutex = + { + otherMutexInit, + otherMutexEnd, + otherMutexAlloc, + otherMutexFree, + otherMutexEnter, + otherMutexTry, + otherMutexLeave, +#ifdef SQLITE_DEBUG + otherMutexHeld, + otherMutexNotheld +#endif /* SQLITE_DEBUG */ + }; + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + return &sMutex; +} + +#endif /* SQLITE_MUTEX_OMIT */ +#endif /* SQLITE_OS_OTHER */ diff --git a/scalos/libraries/sqlite/src/mutex_unix.c b/scalos/libraries/sqlite/src/mutex_unix.c new file mode 100644 index 000000000..eca729583 --- /dev/null +++ b/scalos/libraries/sqlite/src/mutex_unix.c @@ -0,0 +1,351 @@ +/* +** 2007 August 28 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains the C functions that implement mutexes for pthreads +*/ +#include "sqliteInt.h" + +/* +** The code in this file is only used if we are compiling threadsafe +** under unix with pthreads. +** +** Note that this implementation requires a version of pthreads that +** supports recursive mutexes. +*/ +#ifdef SQLITE_MUTEX_PTHREADS + +#include + +/* +** The sqlite3_mutex.id, sqlite3_mutex.nRef, and sqlite3_mutex.owner fields +** are necessary under two condidtions: (1) Debug builds and (2) using +** home-grown mutexes. Encapsulate these conditions into a single #define. +*/ +#if defined(SQLITE_DEBUG) || defined(SQLITE_HOMEGROWN_RECURSIVE_MUTEX) +# define SQLITE_MUTEX_NREF 1 +#else +# define SQLITE_MUTEX_NREF 0 +#endif + +/* +** Each recursive mutex is an instance of the following structure. +*/ +struct sqlite3_mutex { + pthread_mutex_t mutex; /* Mutex controlling the lock */ +#if SQLITE_MUTEX_NREF + int id; /* Mutex type */ + volatile int nRef; /* Number of entrances */ + volatile pthread_t owner; /* Thread that is within this mutex */ + int trace; /* True to trace changes */ +#endif +}; +#if SQLITE_MUTEX_NREF +#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0, 0, (pthread_t)0, 0 } +#else +#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER } +#endif + +/* +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are +** intended for use only inside assert() statements. On some platforms, +** there might be race conditions that can cause these routines to +** deliver incorrect results. In particular, if pthread_equal() is +** not an atomic operation, then these routines might delivery +** incorrect results. On most platforms, pthread_equal() is a +** comparison of two integers and is therefore atomic. But we are +** told that HPUX is not such a platform. If so, then these routines +** will not always work correctly on HPUX. +** +** On those platforms where pthread_equal() is not atomic, SQLite +** should be compiled without -DSQLITE_DEBUG and with -DNDEBUG to +** make sure no assert() statements are evaluated and hence these +** routines are never called. +*/ +#if !defined(NDEBUG) || defined(SQLITE_DEBUG) +static int pthreadMutexHeld(sqlite3_mutex *p){ + return (p->nRef!=0 && pthread_equal(p->owner, pthread_self())); +} +static int pthreadMutexNotheld(sqlite3_mutex *p){ + return p->nRef==0 || pthread_equal(p->owner, pthread_self())==0; +} +#endif + +/* +** Initialize and deinitialize the mutex subsystem. +*/ +static int pthreadMutexInit(void){ return SQLITE_OK; } +static int pthreadMutexEnd(void){ return SQLITE_OK; } + +/* +** The sqlite3_mutex_alloc() routine allocates a new +** mutex and returns a pointer to it. If it returns NULL +** that means that a mutex could not be allocated. SQLite +** will unwind its stack and return an error. The argument +** to sqlite3_mutex_alloc() is one of these integer constants: +** +**
    +**
  • SQLITE_MUTEX_FAST +**
  • SQLITE_MUTEX_RECURSIVE +**
  • SQLITE_MUTEX_STATIC_MASTER +**
  • SQLITE_MUTEX_STATIC_MEM +**
  • SQLITE_MUTEX_STATIC_MEM2 +**
  • SQLITE_MUTEX_STATIC_PRNG +**
  • SQLITE_MUTEX_STATIC_LRU +**
  • SQLITE_MUTEX_STATIC_PMEM +**
+** +** The first two constants cause sqlite3_mutex_alloc() to create +** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE +** is used but not necessarily so when SQLITE_MUTEX_FAST is used. +** The mutex implementation does not need to make a distinction +** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does +** not want to. But SQLite will only request a recursive mutex in +** cases where it really needs one. If a faster non-recursive mutex +** implementation is available on the host platform, the mutex subsystem +** might return such a mutex in response to SQLITE_MUTEX_FAST. +** +** The other allowed parameters to sqlite3_mutex_alloc() each return +** a pointer to a static preexisting mutex. Six static mutexes are +** used by the current version of SQLite. Future versions of SQLite +** may add additional static mutexes. Static mutexes are for internal +** use by SQLite only. Applications that use SQLite mutexes should +** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or +** SQLITE_MUTEX_RECURSIVE. +** +** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST +** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() +** returns a different mutex on every call. But for the static +** mutex types, the same mutex is returned on every call that has +** the same type number. +*/ +static sqlite3_mutex *pthreadMutexAlloc(int iType){ + static sqlite3_mutex staticMutexes[] = { + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER + }; + sqlite3_mutex *p; + switch( iType ){ + case SQLITE_MUTEX_RECURSIVE: { + p = sqlite3MallocZero( sizeof(*p) ); + if( p ){ +#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX + /* If recursive mutexes are not available, we will have to + ** build our own. See below. */ + pthread_mutex_init(&p->mutex, 0); +#else + /* Use a recursive mutex if it is available */ + pthread_mutexattr_t recursiveAttr; + pthread_mutexattr_init(&recursiveAttr); + pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&p->mutex, &recursiveAttr); + pthread_mutexattr_destroy(&recursiveAttr); +#endif +#if SQLITE_MUTEX_NREF + p->id = iType; +#endif + } + break; + } + case SQLITE_MUTEX_FAST: { + p = sqlite3MallocZero( sizeof(*p) ); + if( p ){ +#if SQLITE_MUTEX_NREF + p->id = iType; +#endif + pthread_mutex_init(&p->mutex, 0); + } + break; + } + default: { + assert( iType-2 >= 0 ); + assert( iType-2 < ArraySize(staticMutexes) ); + p = &staticMutexes[iType-2]; +#if SQLITE_MUTEX_NREF + p->id = iType; +#endif + break; + } + } + return p; +} + + +/* +** This routine deallocates a previously +** allocated mutex. SQLite is careful to deallocate every +** mutex that it allocates. +*/ +static void pthreadMutexFree(sqlite3_mutex *p){ + assert( p->nRef==0 ); + assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); + pthread_mutex_destroy(&p->mutex); + sqlite3_free(p); +} + +/* +** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt +** to enter a mutex. If another thread is already within the mutex, +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK +** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can +** be entered multiple times by the same thread. In such cases the, +** mutex must be exited an equal number of times before another thread +** can enter. If the same thread tries to enter any other kind of mutex +** more than once, the behavior is undefined. +*/ +static void pthreadMutexEnter(sqlite3_mutex *p){ + assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) ); + +#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX + /* If recursive mutexes are not available, then we have to grow + ** our own. This implementation assumes that pthread_equal() + ** is atomic - that it cannot be deceived into thinking self + ** and p->owner are equal if p->owner changes between two values + ** that are not equal to self while the comparison is taking place. + ** This implementation also assumes a coherent cache - that + ** separate processes cannot read different values from the same + ** address at the same time. If either of these two conditions + ** are not met, then the mutexes will fail and problems will result. + */ + { + pthread_t self = pthread_self(); + if( p->nRef>0 && pthread_equal(p->owner, self) ){ + p->nRef++; + }else{ + pthread_mutex_lock(&p->mutex); + assert( p->nRef==0 ); + p->owner = self; + p->nRef = 1; + } + } +#else + /* Use the built-in recursive mutexes if they are available. + */ + pthread_mutex_lock(&p->mutex); +#if SQLITE_MUTEX_NREF + assert( p->nRef>0 || p->owner==0 ); + p->owner = pthread_self(); + p->nRef++; +#endif +#endif + +#ifdef SQLITE_DEBUG + if( p->trace ){ + printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); + } +#endif +} +static int pthreadMutexTry(sqlite3_mutex *p){ + int rc; + assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) ); + +#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX + /* If recursive mutexes are not available, then we have to grow + ** our own. This implementation assumes that pthread_equal() + ** is atomic - that it cannot be deceived into thinking self + ** and p->owner are equal if p->owner changes between two values + ** that are not equal to self while the comparison is taking place. + ** This implementation also assumes a coherent cache - that + ** separate processes cannot read different values from the same + ** address at the same time. If either of these two conditions + ** are not met, then the mutexes will fail and problems will result. + */ + { + pthread_t self = pthread_self(); + if( p->nRef>0 && pthread_equal(p->owner, self) ){ + p->nRef++; + rc = SQLITE_OK; + }else if( pthread_mutex_trylock(&p->mutex)==0 ){ + assert( p->nRef==0 ); + p->owner = self; + p->nRef = 1; + rc = SQLITE_OK; + }else{ + rc = SQLITE_BUSY; + } + } +#else + /* Use the built-in recursive mutexes if they are available. + */ + if( pthread_mutex_trylock(&p->mutex)==0 ){ +#if SQLITE_MUTEX_NREF + p->owner = pthread_self(); + p->nRef++; +#endif + rc = SQLITE_OK; + }else{ + rc = SQLITE_BUSY; + } +#endif + +#ifdef SQLITE_DEBUG + if( rc==SQLITE_OK && p->trace ){ + printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); + } +#endif + return rc; +} + +/* +** The sqlite3_mutex_leave() routine exits a mutex that was +** previously entered by the same thread. The behavior +** is undefined if the mutex is not currently entered or +** is not currently allocated. SQLite will never do either. +*/ +static void pthreadMutexLeave(sqlite3_mutex *p){ + assert( pthreadMutexHeld(p) ); +#if SQLITE_MUTEX_NREF + p->nRef--; + if( p->nRef==0 ) p->owner = 0; +#endif + assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); + +#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX + if( p->nRef==0 ){ + pthread_mutex_unlock(&p->mutex); + } +#else + pthread_mutex_unlock(&p->mutex); +#endif + +#ifdef SQLITE_DEBUG + if( p->trace ){ + printf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); + } +#endif +} + +sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ + static const sqlite3_mutex_methods sMutex = { + pthreadMutexInit, + pthreadMutexEnd, + pthreadMutexAlloc, + pthreadMutexFree, + pthreadMutexEnter, + pthreadMutexTry, + pthreadMutexLeave, +#ifdef SQLITE_DEBUG + pthreadMutexHeld, + pthreadMutexNotheld +#else + 0, + 0 +#endif + }; + + return &sMutex; +} + +#endif /* SQLITE_MUTEX_PTHREADS */ diff --git a/scalos/libraries/sqlite/src/mutex_w32.c b/scalos/libraries/sqlite/src/mutex_w32.c new file mode 100644 index 000000000..bfd9dacf6 --- /dev/null +++ b/scalos/libraries/sqlite/src/mutex_w32.c @@ -0,0 +1,332 @@ +/* +** 2007 August 14 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains the C functions that implement mutexes for win32 +*/ +#include "sqliteInt.h" + +/* +** The code in this file is only used if we are compiling multithreaded +** on a win32 system. +*/ +#ifdef SQLITE_MUTEX_W32 + +/* +** Each recursive mutex is an instance of the following structure. +*/ +struct sqlite3_mutex { + CRITICAL_SECTION mutex; /* Mutex controlling the lock */ + int id; /* Mutex type */ +#ifdef SQLITE_DEBUG + volatile int nRef; /* Number of enterances */ + volatile DWORD owner; /* Thread holding this mutex */ + int trace; /* True to trace changes */ +#endif +}; +#define SQLITE_W32_MUTEX_INITIALIZER { 0 } +#ifdef SQLITE_DEBUG +#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, 0L, (DWORD)0, 0 } +#else +#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0 } +#endif + +/* +** Return true (non-zero) if we are running under WinNT, Win2K, WinXP, +** or WinCE. Return false (zero) for Win95, Win98, or WinME. +** +** Here is an interesting observation: Win95, Win98, and WinME lack +** the LockFileEx() API. But we can still statically link against that +** API as long as we don't call it win running Win95/98/ME. A call to +** this routine is used to determine if the host is Win95/98/ME or +** WinNT/2K/XP so that we will know whether or not we can safely call +** the LockFileEx() API. +** +** mutexIsNT() is only used for the TryEnterCriticalSection() API call, +** which is only available if your application was compiled with +** _WIN32_WINNT defined to a value >= 0x0400. Currently, the only +** call to TryEnterCriticalSection() is #ifdef'ed out, so #ifdef +** this out as well. +*/ +#if 0 +#if SQLITE_OS_WINCE +# define mutexIsNT() (1) +#else + static int mutexIsNT(void){ + static int osType = 0; + if( osType==0 ){ + OSVERSIONINFO sInfo; + sInfo.dwOSVersionInfoSize = sizeof(sInfo); + GetVersionEx(&sInfo); + osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1; + } + return osType==2; + } +#endif /* SQLITE_OS_WINCE */ +#endif + +#ifdef SQLITE_DEBUG +/* +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are +** intended for use only inside assert() statements. +*/ +static int winMutexHeld(sqlite3_mutex *p){ + return p->nRef!=0 && p->owner==GetCurrentThreadId(); +} +static int winMutexNotheld2(sqlite3_mutex *p, DWORD tid){ + return p->nRef==0 || p->owner!=tid; +} +static int winMutexNotheld(sqlite3_mutex *p){ + DWORD tid = GetCurrentThreadId(); + return winMutexNotheld2(p, tid); +} +#endif + + +/* +** Initialize and deinitialize the mutex subsystem. +*/ +static sqlite3_mutex winMutex_staticMutexes[6] = { + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER +}; +static int winMutex_isInit = 0; +/* As winMutexInit() and winMutexEnd() are called as part +** of the sqlite3_initialize and sqlite3_shutdown() +** processing, the "interlocked" magic is probably not +** strictly necessary. +*/ +static long winMutex_lock = 0; + +static int winMutexInit(void){ + /* The first to increment to 1 does actual initialization */ + if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){ + int i; + for(i=0; i +**
  • SQLITE_MUTEX_FAST +**
  • SQLITE_MUTEX_RECURSIVE +**
  • SQLITE_MUTEX_STATIC_MASTER +**
  • SQLITE_MUTEX_STATIC_MEM +**
  • SQLITE_MUTEX_STATIC_MEM2 +**
  • SQLITE_MUTEX_STATIC_PRNG +**
  • SQLITE_MUTEX_STATIC_LRU +**
  • SQLITE_MUTEX_STATIC_PMEM +** +** +** The first two constants cause sqlite3_mutex_alloc() to create +** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE +** is used but not necessarily so when SQLITE_MUTEX_FAST is used. +** The mutex implementation does not need to make a distinction +** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does +** not want to. But SQLite will only request a recursive mutex in +** cases where it really needs one. If a faster non-recursive mutex +** implementation is available on the host platform, the mutex subsystem +** might return such a mutex in response to SQLITE_MUTEX_FAST. +** +** The other allowed parameters to sqlite3_mutex_alloc() each return +** a pointer to a static preexisting mutex. Six static mutexes are +** used by the current version of SQLite. Future versions of SQLite +** may add additional static mutexes. Static mutexes are for internal +** use by SQLite only. Applications that use SQLite mutexes should +** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or +** SQLITE_MUTEX_RECURSIVE. +** +** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST +** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() +** returns a different mutex on every call. But for the static +** mutex types, the same mutex is returned on every call that has +** the same type number. +*/ +static sqlite3_mutex *winMutexAlloc(int iType){ + sqlite3_mutex *p; + + switch( iType ){ + case SQLITE_MUTEX_FAST: + case SQLITE_MUTEX_RECURSIVE: { + p = sqlite3MallocZero( sizeof(*p) ); + if( p ){ +#ifdef SQLITE_DEBUG + p->id = iType; +#endif + InitializeCriticalSection(&p->mutex); + } + break; + } + default: { + assert( winMutex_isInit==1 ); + assert( iType-2 >= 0 ); + assert( iType-2 < ArraySize(winMutex_staticMutexes) ); + p = &winMutex_staticMutexes[iType-2]; +#ifdef SQLITE_DEBUG + p->id = iType; +#endif + break; + } + } + return p; +} + + +/* +** This routine deallocates a previously +** allocated mutex. SQLite is careful to deallocate every +** mutex that it allocates. +*/ +static void winMutexFree(sqlite3_mutex *p){ + assert( p ); + assert( p->nRef==0 && p->owner==0 ); + assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); + DeleteCriticalSection(&p->mutex); + sqlite3_free(p); +} + +/* +** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt +** to enter a mutex. If another thread is already within the mutex, +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK +** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can +** be entered multiple times by the same thread. In such cases the, +** mutex must be exited an equal number of times before another thread +** can enter. If the same thread tries to enter any other kind of mutex +** more than once, the behavior is undefined. +*/ +static void winMutexEnter(sqlite3_mutex *p){ +#ifdef SQLITE_DEBUG + DWORD tid = GetCurrentThreadId(); + assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); +#endif + EnterCriticalSection(&p->mutex); +#ifdef SQLITE_DEBUG + assert( p->nRef>0 || p->owner==0 ); + p->owner = tid; + p->nRef++; + if( p->trace ){ + printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); + } +#endif +} +static int winMutexTry(sqlite3_mutex *p){ +#ifndef NDEBUG + DWORD tid = GetCurrentThreadId(); +#endif + int rc = SQLITE_BUSY; + assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); + /* + ** The sqlite3_mutex_try() routine is very rarely used, and when it + ** is used it is merely an optimization. So it is OK for it to always + ** fail. + ** + ** The TryEnterCriticalSection() interface is only available on WinNT. + ** And some windows compilers complain if you try to use it without + ** first doing some #defines that prevent SQLite from building on Win98. + ** For that reason, we will omit this optimization for now. See + ** ticket #2685. + */ +#if 0 + if( mutexIsNT() && TryEnterCriticalSection(&p->mutex) ){ + p->owner = tid; + p->nRef++; + rc = SQLITE_OK; + } +#else + UNUSED_PARAMETER(p); +#endif +#ifdef SQLITE_DEBUG + if( rc==SQLITE_OK && p->trace ){ + printf("try mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); + } +#endif + return rc; +} + +/* +** The sqlite3_mutex_leave() routine exits a mutex that was +** previously entered by the same thread. The behavior +** is undefined if the mutex is not currently entered or +** is not currently allocated. SQLite will never do either. +*/ +static void winMutexLeave(sqlite3_mutex *p){ +#ifndef NDEBUG + DWORD tid = GetCurrentThreadId(); + assert( p->nRef>0 ); + assert( p->owner==tid ); + p->nRef--; + if( p->nRef==0 ) p->owner = 0; + assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); +#endif + LeaveCriticalSection(&p->mutex); +#ifdef SQLITE_DEBUG + if( p->trace ){ + printf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); + } +#endif +} + +sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ + static const sqlite3_mutex_methods sMutex = { + winMutexInit, + winMutexEnd, + winMutexAlloc, + winMutexFree, + winMutexEnter, + winMutexTry, + winMutexLeave, +#ifdef SQLITE_DEBUG + winMutexHeld, + winMutexNotheld +#else + 0, + 0 +#endif + }; + + return &sMutex; +} +#endif /* SQLITE_MUTEX_W32 */ diff --git a/scalos/libraries/sqlite/src/notify.c b/scalos/libraries/sqlite/src/notify.c new file mode 100644 index 000000000..fcab5bfaf --- /dev/null +++ b/scalos/libraries/sqlite/src/notify.c @@ -0,0 +1,332 @@ +/* +** 2009 March 3 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains the implementation of the sqlite3_unlock_notify() +** API method and its associated functionality. +*/ +#include "sqliteInt.h" +#include "btreeInt.h" + +/* Omit this entire file if SQLITE_ENABLE_UNLOCK_NOTIFY is not defined. */ +#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY + +/* +** Public interfaces: +** +** sqlite3ConnectionBlocked() +** sqlite3ConnectionUnlocked() +** sqlite3ConnectionClosed() +** sqlite3_unlock_notify() +*/ + +#define assertMutexHeld() \ + assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) ) + +/* +** Head of a linked list of all sqlite3 objects created by this process +** for which either sqlite3.pBlockingConnection or sqlite3.pUnlockConnection +** is not NULL. This variable may only accessed while the STATIC_MASTER +** mutex is held. +*/ +static sqlite3 *SQLITE_WSD sqlite3BlockedList = 0; + +#ifndef NDEBUG +/* +** This function is a complex assert() that verifies the following +** properties of the blocked connections list: +** +** 1) Each entry in the list has a non-NULL value for either +** pUnlockConnection or pBlockingConnection, or both. +** +** 2) All entries in the list that share a common value for +** xUnlockNotify are grouped together. +** +** 3) If the argument db is not NULL, then none of the entries in the +** blocked connections list have pUnlockConnection or pBlockingConnection +** set to db. This is used when closing connection db. +*/ +static void checkListProperties(sqlite3 *db){ + sqlite3 *p; + for(p=sqlite3BlockedList; p; p=p->pNextBlocked){ + int seen = 0; + sqlite3 *p2; + + /* Verify property (1) */ + assert( p->pUnlockConnection || p->pBlockingConnection ); + + /* Verify property (2) */ + for(p2=sqlite3BlockedList; p2!=p; p2=p2->pNextBlocked){ + if( p2->xUnlockNotify==p->xUnlockNotify ) seen = 1; + assert( p2->xUnlockNotify==p->xUnlockNotify || !seen ); + assert( db==0 || p->pUnlockConnection!=db ); + assert( db==0 || p->pBlockingConnection!=db ); + } + } +} +#else +# define checkListProperties(x) +#endif + +/* +** Remove connection db from the blocked connections list. If connection +** db is not currently a part of the list, this function is a no-op. +*/ +static void removeFromBlockedList(sqlite3 *db){ + sqlite3 **pp; + assertMutexHeld(); + for(pp=&sqlite3BlockedList; *pp; pp = &(*pp)->pNextBlocked){ + if( *pp==db ){ + *pp = (*pp)->pNextBlocked; + break; + } + } +} + +/* +** Add connection db to the blocked connections list. It is assumed +** that it is not already a part of the list. +*/ +static void addToBlockedList(sqlite3 *db){ + sqlite3 **pp; + assertMutexHeld(); + for( + pp=&sqlite3BlockedList; + *pp && (*pp)->xUnlockNotify!=db->xUnlockNotify; + pp=&(*pp)->pNextBlocked + ); + db->pNextBlocked = *pp; + *pp = db; +} + +/* +** Obtain the STATIC_MASTER mutex. +*/ +static void enterMutex(void){ + sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); + checkListProperties(0); +} + +/* +** Release the STATIC_MASTER mutex. +*/ +static void leaveMutex(void){ + assertMutexHeld(); + checkListProperties(0); + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); +} + +/* +** Register an unlock-notify callback. +** +** This is called after connection "db" has attempted some operation +** but has received an SQLITE_LOCKED error because another connection +** (call it pOther) in the same process was busy using the same shared +** cache. pOther is found by looking at db->pBlockingConnection. +** +** If there is no blocking connection, the callback is invoked immediately, +** before this routine returns. +** +** If pOther is already blocked on db, then report SQLITE_LOCKED, to indicate +** a deadlock. +** +** Otherwise, make arrangements to invoke xNotify when pOther drops +** its locks. +** +** Each call to this routine overrides any prior callbacks registered +** on the same "db". If xNotify==0 then any prior callbacks are immediately +** cancelled. +*/ +int sqlite3_unlock_notify( + sqlite3 *db, + void (*xNotify)(void **, int), + void *pArg +){ + int rc = SQLITE_OK; + + sqlite3_mutex_enter(db->mutex); + enterMutex(); + + if( xNotify==0 ){ + removeFromBlockedList(db); + db->pBlockingConnection = 0; + db->pUnlockConnection = 0; + db->xUnlockNotify = 0; + db->pUnlockArg = 0; + }else if( 0==db->pBlockingConnection ){ + /* The blocking transaction has been concluded. Or there never was a + ** blocking transaction. In either case, invoke the notify callback + ** immediately. + */ + xNotify(&pArg, 1); + }else{ + sqlite3 *p; + + for(p=db->pBlockingConnection; p && p!=db; p=p->pUnlockConnection){} + if( p ){ + rc = SQLITE_LOCKED; /* Deadlock detected. */ + }else{ + db->pUnlockConnection = db->pBlockingConnection; + db->xUnlockNotify = xNotify; + db->pUnlockArg = pArg; + removeFromBlockedList(db); + addToBlockedList(db); + } + } + + leaveMutex(); + assert( !db->mallocFailed ); + sqlite3Error(db, rc, (rc?"database is deadlocked":0)); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** This function is called while stepping or preparing a statement +** associated with connection db. The operation will return SQLITE_LOCKED +** to the user because it requires a lock that will not be available +** until connection pBlocker concludes its current transaction. +*/ +void sqlite3ConnectionBlocked(sqlite3 *db, sqlite3 *pBlocker){ + enterMutex(); + if( db->pBlockingConnection==0 && db->pUnlockConnection==0 ){ + addToBlockedList(db); + } + db->pBlockingConnection = pBlocker; + leaveMutex(); +} + +/* +** This function is called when +** the transaction opened by database db has just finished. Locks held +** by database connection db have been released. +** +** This function loops through each entry in the blocked connections +** list and does the following: +** +** 1) If the sqlite3.pBlockingConnection member of a list entry is +** set to db, then set pBlockingConnection=0. +** +** 2) If the sqlite3.pUnlockConnection member of a list entry is +** set to db, then invoke the configured unlock-notify callback and +** set pUnlockConnection=0. +** +** 3) If the two steps above mean that pBlockingConnection==0 and +** pUnlockConnection==0, remove the entry from the blocked connections +** list. +*/ +void sqlite3ConnectionUnlocked(sqlite3 *db){ + void (*xUnlockNotify)(void **, int) = 0; /* Unlock-notify cb to invoke */ + int nArg = 0; /* Number of entries in aArg[] */ + sqlite3 **pp; /* Iterator variable */ + void **aArg; /* Arguments to the unlock callback */ + void **aDyn = 0; /* Dynamically allocated space for aArg[] */ + void *aStatic[16]; /* Starter space for aArg[]. No malloc required */ + + aArg = aStatic; + enterMutex(); /* Enter STATIC_MASTER mutex */ + + /* This loop runs once for each entry in the blocked-connections list. */ + for(pp=&sqlite3BlockedList; *pp; /* no-op */ ){ + sqlite3 *p = *pp; + + /* Step 1. */ + if( p->pBlockingConnection==db ){ + p->pBlockingConnection = 0; + } + + /* Step 2. */ + if( p->pUnlockConnection==db ){ + assert( p->xUnlockNotify ); + if( p->xUnlockNotify!=xUnlockNotify && nArg!=0 ){ + xUnlockNotify(aArg, nArg); + nArg = 0; + } + + sqlite3BeginBenignMalloc(); + assert( aArg==aDyn || (aDyn==0 && aArg==aStatic) ); + assert( nArg<=(int)ArraySize(aStatic) || aArg==aDyn ); + if( (!aDyn && nArg==(int)ArraySize(aStatic)) + || (aDyn && nArg==(int)(sqlite3MallocSize(aDyn)/sizeof(void*))) + ){ + /* The aArg[] array needs to grow. */ + void **pNew = (void **)sqlite3Malloc(nArg*sizeof(void *)*2); + if( pNew ){ + memcpy(pNew, aArg, nArg*sizeof(void *)); + sqlite3_free(aDyn); + aDyn = aArg = pNew; + }else{ + /* This occurs when the array of context pointers that need to + ** be passed to the unlock-notify callback is larger than the + ** aStatic[] array allocated on the stack and the attempt to + ** allocate a larger array from the heap has failed. + ** + ** This is a difficult situation to handle. Returning an error + ** code to the caller is insufficient, as even if an error code + ** is returned the transaction on connection db will still be + ** closed and the unlock-notify callbacks on blocked connections + ** will go unissued. This might cause the application to wait + ** indefinitely for an unlock-notify callback that will never + ** arrive. + ** + ** Instead, invoke the unlock-notify callback with the context + ** array already accumulated. We can then clear the array and + ** begin accumulating any further context pointers without + ** requiring any dynamic allocation. This is sub-optimal because + ** it means that instead of one callback with a large array of + ** context pointers the application will receive two or more + ** callbacks with smaller arrays of context pointers, which will + ** reduce the applications ability to prioritize multiple + ** connections. But it is the best that can be done under the + ** circumstances. + */ + xUnlockNotify(aArg, nArg); + nArg = 0; + } + } + sqlite3EndBenignMalloc(); + + aArg[nArg++] = p->pUnlockArg; + xUnlockNotify = p->xUnlockNotify; + p->pUnlockConnection = 0; + p->xUnlockNotify = 0; + p->pUnlockArg = 0; + } + + /* Step 3. */ + if( p->pBlockingConnection==0 && p->pUnlockConnection==0 ){ + /* Remove connection p from the blocked connections list. */ + *pp = p->pNextBlocked; + p->pNextBlocked = 0; + }else{ + pp = &p->pNextBlocked; + } + } + + if( nArg!=0 ){ + xUnlockNotify(aArg, nArg); + } + sqlite3_free(aDyn); + leaveMutex(); /* Leave STATIC_MASTER mutex */ +} + +/* +** This is called when the database connection passed as an argument is +** being closed. The connection is removed from the blocked list. +*/ +void sqlite3ConnectionClosed(sqlite3 *db){ + sqlite3ConnectionUnlocked(db); + enterMutex(); + removeFromBlockedList(db); + checkListProperties(db); + leaveMutex(); +} +#endif diff --git a/scalos/libraries/sqlite/src/os.c b/scalos/libraries/sqlite/src/os.c new file mode 100644 index 000000000..b5e918a72 --- /dev/null +++ b/scalos/libraries/sqlite/src/os.c @@ -0,0 +1,356 @@ +/* +** 2005 November 29 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains OS interface code that is common to all +** architectures. +*/ +#define _SQLITE_OS_C_ 1 +#include "sqliteInt.h" +#undef _SQLITE_OS_C_ + +/* +** The default SQLite sqlite3_vfs implementations do not allocate +** memory (actually, os_unix.c allocates a small amount of memory +** from within OsOpen()), but some third-party implementations may. +** So we test the effects of a malloc() failing and the sqlite3OsXXX() +** function returning SQLITE_IOERR_NOMEM using the DO_OS_MALLOC_TEST macro. +** +** The following functions are instrumented for malloc() failure +** testing: +** +** sqlite3OsRead() +** sqlite3OsWrite() +** sqlite3OsSync() +** sqlite3OsFileSize() +** sqlite3OsLock() +** sqlite3OsCheckReservedLock() +** sqlite3OsFileControl() +** sqlite3OsShmMap() +** sqlite3OsOpen() +** sqlite3OsDelete() +** sqlite3OsAccess() +** sqlite3OsFullPathname() +** +*/ +#if defined(SQLITE_TEST) +int sqlite3_memdebug_vfs_oom_test = 1; + #define DO_OS_MALLOC_TEST(x) \ + if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3IsMemJournal(x))) { \ + void *pTstAlloc = sqlite3Malloc(10); \ + if (!pTstAlloc) return SQLITE_IOERR_NOMEM; \ + sqlite3_free(pTstAlloc); \ + } +#else + #define DO_OS_MALLOC_TEST(x) +#endif + +/* +** The following routines are convenience wrappers around methods +** of the sqlite3_file object. This is mostly just syntactic sugar. All +** of this would be completely automatic if SQLite were coded using +** C++ instead of plain old C. +*/ +int sqlite3OsClose(sqlite3_file *pId){ + int rc = SQLITE_OK; + if( pId->pMethods ){ + rc = pId->pMethods->xClose(pId); + pId->pMethods = 0; + } + return rc; +} +int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){ + DO_OS_MALLOC_TEST(id); + return id->pMethods->xRead(id, pBuf, amt, offset); +} +int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){ + DO_OS_MALLOC_TEST(id); + return id->pMethods->xWrite(id, pBuf, amt, offset); +} +int sqlite3OsTruncate(sqlite3_file *id, i64 size){ + return id->pMethods->xTruncate(id, size); +} +int sqlite3OsSync(sqlite3_file *id, int flags){ + DO_OS_MALLOC_TEST(id); + return id->pMethods->xSync(id, flags); +} +int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){ + DO_OS_MALLOC_TEST(id); + return id->pMethods->xFileSize(id, pSize); +} +int sqlite3OsLock(sqlite3_file *id, int lockType){ + DO_OS_MALLOC_TEST(id); + return id->pMethods->xLock(id, lockType); +} +int sqlite3OsUnlock(sqlite3_file *id, int lockType){ + return id->pMethods->xUnlock(id, lockType); +} +int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){ + DO_OS_MALLOC_TEST(id); + return id->pMethods->xCheckReservedLock(id, pResOut); +} + +/* +** Use sqlite3OsFileControl() when we are doing something that might fail +** and we need to know about the failures. Use sqlite3OsFileControlHint() +** when simply tossing information over the wall to the VFS and we do not +** really care if the VFS receives and understands the information since it +** is only a hint and can be safely ignored. The sqlite3OsFileControlHint() +** routine has no return value since the return value would be meaningless. +*/ +int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ + DO_OS_MALLOC_TEST(id); + return id->pMethods->xFileControl(id, op, pArg); +} +void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){ + (void)id->pMethods->xFileControl(id, op, pArg); +} + +int sqlite3OsSectorSize(sqlite3_file *id){ + int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize; + return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE); +} +int sqlite3OsDeviceCharacteristics(sqlite3_file *id){ + return id->pMethods->xDeviceCharacteristics(id); +} +int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){ + return id->pMethods->xShmLock(id, offset, n, flags); +} +void sqlite3OsShmBarrier(sqlite3_file *id){ + id->pMethods->xShmBarrier(id); +} +int sqlite3OsShmUnmap(sqlite3_file *id, int deleteFlag){ + return id->pMethods->xShmUnmap(id, deleteFlag); +} +int sqlite3OsShmMap( + sqlite3_file *id, /* Database file handle */ + int iPage, + int pgsz, + int bExtend, /* True to extend file if necessary */ + void volatile **pp /* OUT: Pointer to mapping */ +){ + DO_OS_MALLOC_TEST(id); + return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp); +} + +/* +** The next group of routines are convenience wrappers around the +** VFS methods. +*/ +int sqlite3OsOpen( + sqlite3_vfs *pVfs, + const char *zPath, + sqlite3_file *pFile, + int flags, + int *pFlagsOut +){ + int rc; + DO_OS_MALLOC_TEST(0); + /* 0x87f7f is a mask of SQLITE_OPEN_ flags that are valid to be passed + ** down into the VFS layer. Some SQLITE_OPEN_ flags (for example, + ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before + ** reaching the VFS. */ + rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x87f7f, pFlagsOut); + assert( rc==SQLITE_OK || pFile->pMethods==0 ); + return rc; +} +int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ + DO_OS_MALLOC_TEST(0); + assert( dirSync==0 || dirSync==1 ); + return pVfs->xDelete(pVfs, zPath, dirSync); +} +int sqlite3OsAccess( + sqlite3_vfs *pVfs, + const char *zPath, + int flags, + int *pResOut +){ + DO_OS_MALLOC_TEST(0); + return pVfs->xAccess(pVfs, zPath, flags, pResOut); +} +int sqlite3OsFullPathname( + sqlite3_vfs *pVfs, + const char *zPath, + int nPathOut, + char *zPathOut +){ + DO_OS_MALLOC_TEST(0); + zPathOut[0] = 0; + return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut); +} +#ifndef SQLITE_OMIT_LOAD_EXTENSION +void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){ + return pVfs->xDlOpen(pVfs, zPath); +} +void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ + pVfs->xDlError(pVfs, nByte, zBufOut); +} +void (*sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHdle, const char *zSym))(void){ + return pVfs->xDlSym(pVfs, pHdle, zSym); +} +void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){ + pVfs->xDlClose(pVfs, pHandle); +} +#endif /* SQLITE_OMIT_LOAD_EXTENSION */ +int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ + return pVfs->xRandomness(pVfs, nByte, zBufOut); +} +int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){ + return pVfs->xSleep(pVfs, nMicro); +} +int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){ + int rc; + /* IMPLEMENTATION-OF: R-49045-42493 SQLite will use the xCurrentTimeInt64() + ** method to get the current date and time if that method is available + ** (if iVersion is 2 or greater and the function pointer is not NULL) and + ** will fall back to xCurrentTime() if xCurrentTimeInt64() is + ** unavailable. + */ + if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){ + rc = pVfs->xCurrentTimeInt64(pVfs, pTimeOut); + }else{ + double r; + rc = pVfs->xCurrentTime(pVfs, &r); + *pTimeOut = (sqlite3_int64)(r*86400000.0); + } + return rc; +} + +int sqlite3OsOpenMalloc( + sqlite3_vfs *pVfs, + const char *zFile, + sqlite3_file **ppFile, + int flags, + int *pOutFlags +){ + int rc = SQLITE_NOMEM; + sqlite3_file *pFile; + pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile); + if( pFile ){ + rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags); + if( rc!=SQLITE_OK ){ + sqlite3_free(pFile); + }else{ + *ppFile = pFile; + } + } + return rc; +} +int sqlite3OsCloseFree(sqlite3_file *pFile){ + int rc = SQLITE_OK; + assert( pFile ); + rc = sqlite3OsClose(pFile); + sqlite3_free(pFile); + return rc; +} + +/* +** This function is a wrapper around the OS specific implementation of +** sqlite3_os_init(). The purpose of the wrapper is to provide the +** ability to simulate a malloc failure, so that the handling of an +** error in sqlite3_os_init() by the upper layers can be tested. +*/ +int sqlite3OsInit(void){ + void *p = sqlite3_malloc(10); + if( p==0 ) return SQLITE_NOMEM; + sqlite3_free(p); + return sqlite3_os_init(); +} + +/* +** The list of all registered VFS implementations. +*/ +static sqlite3_vfs * SQLITE_WSD vfsList = 0; +#define vfsList GLOBAL(sqlite3_vfs *, vfsList) + +/* +** Locate a VFS by name. If no name is given, simply return the +** first VFS on the list. +*/ +sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){ + sqlite3_vfs *pVfs = 0; +#if SQLITE_THREADSAFE + sqlite3_mutex *mutex; +#endif +#ifndef SQLITE_OMIT_AUTOINIT + int rc = sqlite3_initialize(); + if( rc ) return 0; +#endif +#if SQLITE_THREADSAFE + mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); +#endif + sqlite3_mutex_enter(mutex); + for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){ + if( zVfs==0 ) break; + if( strcmp(zVfs, pVfs->zName)==0 ) break; + } + sqlite3_mutex_leave(mutex); + return pVfs; +} + +/* +** Unlink a VFS from the linked list +*/ +static void vfsUnlink(sqlite3_vfs *pVfs){ + assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) ); + if( pVfs==0 ){ + /* No-op */ + }else if( vfsList==pVfs ){ + vfsList = pVfs->pNext; + }else if( vfsList ){ + sqlite3_vfs *p = vfsList; + while( p->pNext && p->pNext!=pVfs ){ + p = p->pNext; + } + if( p->pNext==pVfs ){ + p->pNext = pVfs->pNext; + } + } +} + +/* +** Register a VFS with the system. It is harmless to register the same +** VFS multiple times. The new VFS becomes the default if makeDflt is +** true. +*/ +int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){ + MUTEX_LOGIC(sqlite3_mutex *mutex;) +#ifndef SQLITE_OMIT_AUTOINIT + int rc = sqlite3_initialize(); + if( rc ) return rc; +#endif + MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) + sqlite3_mutex_enter(mutex); + vfsUnlink(pVfs); + if( makeDflt || vfsList==0 ){ + pVfs->pNext = vfsList; + vfsList = pVfs; + }else{ + pVfs->pNext = vfsList->pNext; + vfsList->pNext = pVfs; + } + assert(vfsList); + sqlite3_mutex_leave(mutex); + return SQLITE_OK; +} + +/* +** Unregister a VFS so that it is no longer accessible. +*/ +int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){ +#if SQLITE_THREADSAFE + sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); +#endif + sqlite3_mutex_enter(mutex); + vfsUnlink(pVfs); + sqlite3_mutex_leave(mutex); + return SQLITE_OK; +} diff --git a/scalos/libraries/sqlite/src/os.h b/scalos/libraries/sqlite/src/os.h new file mode 100644 index 000000000..08cd178e7 --- /dev/null +++ b/scalos/libraries/sqlite/src/os.h @@ -0,0 +1,289 @@ +/* +** 2001 September 16 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This header file (together with is companion C source-code file +** "os.c") attempt to abstract the underlying operating system so that +** the SQLite library will work on both POSIX and windows systems. +** +** This header file is #include-ed by sqliteInt.h and thus ends up +** being included by every source file. +*/ +#ifndef _SQLITE_OS_H_ +#define _SQLITE_OS_H_ + +/* +** Figure out if we are dealing with Unix, Windows, or some other +** operating system. After the following block of preprocess macros, +** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, SQLITE_OS_OS2, and SQLITE_OS_OTHER +** will defined to either 1 or 0. One of the four will be 1. The other +** three will be 0. +*/ +#if defined(SQLITE_OS_OTHER) +# if SQLITE_OS_OTHER==1 +# undef SQLITE_OS_UNIX +# define SQLITE_OS_UNIX 0 +# undef SQLITE_OS_WIN +# define SQLITE_OS_WIN 0 +# undef SQLITE_OS_OS2 +# define SQLITE_OS_OS2 0 +# else +# undef SQLITE_OS_OTHER +# endif +#endif +#if !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_OTHER) +# define SQLITE_OS_OTHER 0 +# ifndef SQLITE_OS_WIN +# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__) +# define SQLITE_OS_WIN 1 +# define SQLITE_OS_UNIX 0 +# define SQLITE_OS_OS2 0 +# elif defined(__EMX__) || defined(_OS2) || defined(OS2) || defined(_OS2_) || defined(__OS2__) +# define SQLITE_OS_WIN 0 +# define SQLITE_OS_UNIX 0 +# define SQLITE_OS_OS2 1 +# else +# define SQLITE_OS_WIN 0 +# define SQLITE_OS_UNIX 1 +# define SQLITE_OS_OS2 0 +# endif +# else +# define SQLITE_OS_UNIX 0 +# define SQLITE_OS_OS2 0 +# endif +#else +# ifndef SQLITE_OS_WIN +# define SQLITE_OS_WIN 0 +# endif +#endif + +/* +** Define the maximum size of a temporary filename +*/ +#if SQLITE_OS_WIN +# include +# define SQLITE_TEMPNAME_SIZE (MAX_PATH+50) +#elif SQLITE_OS_OS2 +# if (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 3) && defined(OS2_HIGH_MEMORY) +# include /* has to be included before os2.h for linking to work */ +# endif +# define INCL_DOSDATETIME +# define INCL_DOSFILEMGR +# define INCL_DOSERRORS +# define INCL_DOSMISC +# define INCL_DOSPROCESS +# define INCL_DOSMODULEMGR +# define INCL_DOSSEMAPHORES +# include +# include +# define SQLITE_TEMPNAME_SIZE (CCHMAXPATHCOMP) +#else +# define SQLITE_TEMPNAME_SIZE 200 +#endif + +/* +** Determine if we are dealing with Windows NT. +*/ +#if defined(_WIN32_WINNT) +# define SQLITE_OS_WINNT 1 +#else +# define SQLITE_OS_WINNT 0 +#endif + +/* +** Determine if we are dealing with WindowsCE - which has a much +** reduced API. +*/ +#if defined(_WIN32_WCE) +# define SQLITE_OS_WINCE 1 +#else +# define SQLITE_OS_WINCE 0 +#endif + +/* If the SET_FULLSYNC macro is not defined above, then make it +** a no-op +*/ +#ifndef SET_FULLSYNC +# define SET_FULLSYNC(x,y) +#endif + +/* +** The default size of a disk sector +*/ +#ifndef SQLITE_DEFAULT_SECTOR_SIZE +# define SQLITE_DEFAULT_SECTOR_SIZE 4096 +#endif + +/* +** Temporary files are named starting with this prefix followed by 16 random +** alphanumeric characters, and no file extension. They are stored in the +** OS's standard temporary file directory, and are deleted prior to exit. +** If sqlite is being embedded in another program, you may wish to change the +** prefix to reflect your program's name, so that if your program exits +** prematurely, old temporary files can be easily identified. This can be done +** using -DSQLITE_TEMP_FILE_PREFIX=myprefix_ on the compiler command line. +** +** 2006-10-31: The default prefix used to be "sqlite_". But then +** Mcafee started using SQLite in their anti-virus product and it +** started putting files with the "sqlite" name in the c:/temp folder. +** This annoyed many windows users. Those users would then do a +** Google search for "sqlite", find the telephone numbers of the +** developers and call to wake them up at night and complain. +** For this reason, the default name prefix is changed to be "sqlite" +** spelled backwards. So the temp files are still identified, but +** anybody smart enough to figure out the code is also likely smart +** enough to know that calling the developer will not help get rid +** of the file. +*/ +#ifndef SQLITE_TEMP_FILE_PREFIX +# define SQLITE_TEMP_FILE_PREFIX "etilqs_" +#endif + +/* +** The following values may be passed as the second argument to +** sqlite3OsLock(). The various locks exhibit the following semantics: +** +** SHARED: Any number of processes may hold a SHARED lock simultaneously. +** RESERVED: A single process may hold a RESERVED lock on a file at +** any time. Other processes may hold and obtain new SHARED locks. +** PENDING: A single process may hold a PENDING lock on a file at +** any one time. Existing SHARED locks may persist, but no new +** SHARED locks may be obtained by other processes. +** EXCLUSIVE: An EXCLUSIVE lock precludes all other locks. +** +** PENDING_LOCK may not be passed directly to sqlite3OsLock(). Instead, a +** process that requests an EXCLUSIVE lock may actually obtain a PENDING +** lock. This can be upgraded to an EXCLUSIVE lock by a subsequent call to +** sqlite3OsLock(). +*/ +#define NO_LOCK 0 +#define SHARED_LOCK 1 +#define RESERVED_LOCK 2 +#define PENDING_LOCK 3 +#define EXCLUSIVE_LOCK 4 + +/* +** File Locking Notes: (Mostly about windows but also some info for Unix) +** +** We cannot use LockFileEx() or UnlockFileEx() on Win95/98/ME because +** those functions are not available. So we use only LockFile() and +** UnlockFile(). +** +** LockFile() prevents not just writing but also reading by other processes. +** A SHARED_LOCK is obtained by locking a single randomly-chosen +** byte out of a specific range of bytes. The lock byte is obtained at +** random so two separate readers can probably access the file at the +** same time, unless they are unlucky and choose the same lock byte. +** An EXCLUSIVE_LOCK is obtained by locking all bytes in the range. +** There can only be one writer. A RESERVED_LOCK is obtained by locking +** a single byte of the file that is designated as the reserved lock byte. +** A PENDING_LOCK is obtained by locking a designated byte different from +** the RESERVED_LOCK byte. +** +** On WinNT/2K/XP systems, LockFileEx() and UnlockFileEx() are available, +** which means we can use reader/writer locks. When reader/writer locks +** are used, the lock is placed on the same range of bytes that is used +** for probabilistic locking in Win95/98/ME. Hence, the locking scheme +** will support two or more Win95 readers or two or more WinNT readers. +** But a single Win95 reader will lock out all WinNT readers and a single +** WinNT reader will lock out all other Win95 readers. +** +** The following #defines specify the range of bytes used for locking. +** SHARED_SIZE is the number of bytes available in the pool from which +** a random byte is selected for a shared lock. The pool of bytes for +** shared locks begins at SHARED_FIRST. +** +** The same locking strategy and +** byte ranges are used for Unix. This leaves open the possiblity of having +** clients on win95, winNT, and unix all talking to the same shared file +** and all locking correctly. To do so would require that samba (or whatever +** tool is being used for file sharing) implements locks correctly between +** windows and unix. I'm guessing that isn't likely to happen, but by +** using the same locking range we are at least open to the possibility. +** +** Locking in windows is manditory. For this reason, we cannot store +** actual data in the bytes used for locking. The pager never allocates +** the pages involved in locking therefore. SHARED_SIZE is selected so +** that all locks will fit on a single page even at the minimum page size. +** PENDING_BYTE defines the beginning of the locks. By default PENDING_BYTE +** is set high so that we don't have to allocate an unused page except +** for very large databases. But one should test the page skipping logic +** by setting PENDING_BYTE low and running the entire regression suite. +** +** Changing the value of PENDING_BYTE results in a subtly incompatible +** file format. Depending on how it is changed, you might not notice +** the incompatibility right away, even running a full regression test. +** The default location of PENDING_BYTE is the first byte past the +** 1GB boundary. +** +*/ +#ifdef SQLITE_OMIT_WSD +# define PENDING_BYTE (0x40000000) +#else +# define PENDING_BYTE sqlite3PendingByte +#endif +#define RESERVED_BYTE (PENDING_BYTE+1) +#define SHARED_FIRST (PENDING_BYTE+2) +#define SHARED_SIZE 510 + +/* +** Wrapper around OS specific sqlite3_os_init() function. +*/ +int sqlite3OsInit(void); + +/* +** Functions for accessing sqlite3_file methods +*/ +int sqlite3OsClose(sqlite3_file*); +int sqlite3OsRead(sqlite3_file*, void*, int amt, i64 offset); +int sqlite3OsWrite(sqlite3_file*, const void*, int amt, i64 offset); +int sqlite3OsTruncate(sqlite3_file*, i64 size); +int sqlite3OsSync(sqlite3_file*, int); +int sqlite3OsFileSize(sqlite3_file*, i64 *pSize); +int sqlite3OsLock(sqlite3_file*, int); +int sqlite3OsUnlock(sqlite3_file*, int); +int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut); +int sqlite3OsFileControl(sqlite3_file*,int,void*); +void sqlite3OsFileControlHint(sqlite3_file*,int,void*); +#define SQLITE_FCNTL_DB_UNCHANGED 0xca093fa0 +int sqlite3OsSectorSize(sqlite3_file *id); +int sqlite3OsDeviceCharacteristics(sqlite3_file *id); +int sqlite3OsShmMap(sqlite3_file *,int,int,int,void volatile **); +int sqlite3OsShmLock(sqlite3_file *id, int, int, int); +void sqlite3OsShmBarrier(sqlite3_file *id); +int sqlite3OsShmUnmap(sqlite3_file *id, int); + + +/* +** Functions for accessing sqlite3_vfs methods +*/ +int sqlite3OsOpen(sqlite3_vfs *, const char *, sqlite3_file*, int, int *); +int sqlite3OsDelete(sqlite3_vfs *, const char *, int); +int sqlite3OsAccess(sqlite3_vfs *, const char *, int, int *pResOut); +int sqlite3OsFullPathname(sqlite3_vfs *, const char *, int, char *); +#ifndef SQLITE_OMIT_LOAD_EXTENSION +void *sqlite3OsDlOpen(sqlite3_vfs *, const char *); +void sqlite3OsDlError(sqlite3_vfs *, int, char *); +void (*sqlite3OsDlSym(sqlite3_vfs *, void *, const char *))(void); +void sqlite3OsDlClose(sqlite3_vfs *, void *); +#endif /* SQLITE_OMIT_LOAD_EXTENSION */ +int sqlite3OsRandomness(sqlite3_vfs *, int, char *); +int sqlite3OsSleep(sqlite3_vfs *, int); +int sqlite3OsCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64*); + +/* +** Convenience functions for opening and closing files using +** sqlite3_malloc() to obtain space for the file-handle structure. +*/ +int sqlite3OsOpenMalloc(sqlite3_vfs *, const char *, sqlite3_file **, int,int*); +int sqlite3OsCloseFree(sqlite3_file *); + +#endif /* _SQLITE_OS_H_ */ diff --git a/scalos/libraries/sqlite/src/os_common.h b/scalos/libraries/sqlite/src/os_common.h new file mode 100644 index 000000000..f6c3e7ff8 --- /dev/null +++ b/scalos/libraries/sqlite/src/os_common.h @@ -0,0 +1,115 @@ +/* +** 2004 May 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains macros and a little bit of code that is common to +** all of the platform-specific files (os_*.c) and is #included into those +** files. +** +** This file should be #included by the os_*.c files only. It is not a +** general purpose header file. +*/ +#ifndef _OS_COMMON_H_ +#define _OS_COMMON_H_ + +/* +** At least two bugs have slipped in because we changed the MEMORY_DEBUG +** macro to SQLITE_DEBUG and some older makefiles have not yet made the +** switch. The following code should catch this problem at compile-time. +*/ +#ifdef MEMORY_DEBUG +# error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." +#endif + +#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) +# ifndef SQLITE_DEBUG_OS_TRACE +# define SQLITE_DEBUG_OS_TRACE 0 +# endif + int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; +# define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X +#else +# define OSTRACE(X) +#endif + +/* +** Macros for performance tracing. Normally turned off. Only works +** on i486 hardware. +*/ +#ifdef SQLITE_PERFORMANCE_TRACE + +/* +** hwtime.h contains inline assembler code for implementing +** high-performance timing routines. +*/ +#include "hwtime.h" + +static sqlite_uint64 g_start; +static sqlite_uint64 g_elapsed; +#define TIMER_START g_start=sqlite3Hwtime() +#define TIMER_END g_elapsed=sqlite3Hwtime()-g_start +#define TIMER_ELAPSED g_elapsed +#else +#define TIMER_START +#define TIMER_END +#define TIMER_ELAPSED ((sqlite_uint64)0) +#endif + +/* +** If we compile with the SQLITE_TEST macro set, then the following block +** of code will give us the ability to simulate a disk I/O error. This +** is used for testing the I/O recovery logic. +*/ +#ifdef SQLITE_TEST +int sqlite3_io_error_hit = 0; /* Total number of I/O Errors */ +int sqlite3_io_error_hardhit = 0; /* Number of non-benign errors */ +int sqlite3_io_error_pending = 0; /* Count down to first I/O error */ +int sqlite3_io_error_persist = 0; /* True if I/O errors persist */ +int sqlite3_io_error_benign = 0; /* True if errors are benign */ +int sqlite3_diskfull_pending = 0; +int sqlite3_diskfull = 0; +#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X) +#define SimulateIOError(CODE) \ + if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \ + || sqlite3_io_error_pending-- == 1 ) \ + { local_ioerr(); CODE; } +static void local_ioerr(){ + IOTRACE(("IOERR\n")); + sqlite3_io_error_hit++; + if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++; +} +#define SimulateDiskfullError(CODE) \ + if( sqlite3_diskfull_pending ){ \ + if( sqlite3_diskfull_pending == 1 ){ \ + local_ioerr(); \ + sqlite3_diskfull = 1; \ + sqlite3_io_error_hit = 1; \ + CODE; \ + }else{ \ + sqlite3_diskfull_pending--; \ + } \ + } +#else +#define SimulateIOErrorBenign(X) +#define SimulateIOError(A) +#define SimulateDiskfullError(A) +#endif + +/* +** When testing, keep a count of the number of open files. +*/ +#ifdef SQLITE_TEST +int sqlite3_open_file_count = 0; +#define OpenCounter(X) sqlite3_open_file_count+=(X) +#else +#define OpenCounter(X) +#endif + +#endif /* !defined(_OS_COMMON_H_) */ diff --git a/scalos/libraries/sqlite/src/os_os2.c b/scalos/libraries/sqlite/src/os_os2.c new file mode 100644 index 000000000..487ac3c3c --- /dev/null +++ b/scalos/libraries/sqlite/src/os_os2.c @@ -0,0 +1,1924 @@ +/* +** 2006 Feb 14 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains code that is specific to OS/2. +*/ + +#include "sqliteInt.h" + +#if SQLITE_OS_OS2 + +/* +** A Note About Memory Allocation: +** +** This driver uses malloc()/free() directly rather than going through +** the SQLite-wrappers sqlite3_malloc()/sqlite3_free(). Those wrappers +** are designed for use on embedded systems where memory is scarce and +** malloc failures happen frequently. OS/2 does not typically run on +** embedded systems, and when it does the developers normally have bigger +** problems to worry about than running out of memory. So there is not +** a compelling need to use the wrappers. +** +** But there is a good reason to not use the wrappers. If we use the +** wrappers then we will get simulated malloc() failures within this +** driver. And that causes all kinds of problems for our tests. We +** could enhance SQLite to deal with simulated malloc failures within +** the OS driver, but the code to deal with those failure would not +** be exercised on Linux (which does not need to malloc() in the driver) +** and so we would have difficulty writing coverage tests for that +** code. Better to leave the code out, we think. +** +** The point of this discussion is as follows: When creating a new +** OS layer for an embedded system, if you use this file as an example, +** avoid the use of malloc()/free(). Those routines work ok on OS/2 +** desktops but not so well in embedded systems. +*/ + +/* +** Macros used to determine whether or not to use threads. +*/ +#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE +# define SQLITE_OS2_THREADS 1 +#endif + +/* +** Include code that is common to all os_*.c files +*/ +#include "os_common.h" + +/* Forward references */ +typedef struct os2File os2File; /* The file structure */ +typedef struct os2ShmNode os2ShmNode; /* A shared descritive memory node */ +typedef struct os2ShmLink os2ShmLink; /* A connection to shared-memory */ + +/* +** The os2File structure is subclass of sqlite3_file specific for the OS/2 +** protability layer. +*/ +struct os2File { + const sqlite3_io_methods *pMethod; /* Always the first entry */ + HFILE h; /* Handle for accessing the file */ + int flags; /* Flags provided to os2Open() */ + int locktype; /* Type of lock currently held on this file */ + int szChunk; /* Chunk size configured by FCNTL_CHUNK_SIZE */ + char *zFullPathCp; /* Full path name of this file */ + os2ShmLink *pShmLink; /* Instance of shared memory on this file */ +}; + +#define LOCK_TIMEOUT 10L /* the default locking timeout */ + +/* +** Missing from some versions of the OS/2 toolkit - +** used to allocate from high memory if possible +*/ +#ifndef OBJ_ANY +# define OBJ_ANY 0x00000400 +#endif + +/***************************************************************************** +** The next group of routines implement the I/O methods specified +** by the sqlite3_io_methods object. +******************************************************************************/ + +/* +** Close a file. +*/ +static int os2Close( sqlite3_file *id ){ + APIRET rc; + os2File *pFile = (os2File*)id; + + assert( id!=0 ); + OSTRACE(( "CLOSE %d (%s)\n", pFile->h, pFile->zFullPathCp )); + + rc = DosClose( pFile->h ); + + if( pFile->flags & SQLITE_OPEN_DELETEONCLOSE ) + DosForceDelete( (PSZ)pFile->zFullPathCp ); + + free( pFile->zFullPathCp ); + pFile->zFullPathCp = NULL; + pFile->locktype = NO_LOCK; + pFile->h = (HFILE)-1; + pFile->flags = 0; + + OpenCounter( -1 ); + return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR; +} + +/* +** Read data from a file into a buffer. Return SQLITE_OK if all +** bytes were read successfully and SQLITE_IOERR if anything goes +** wrong. +*/ +static int os2Read( + sqlite3_file *id, /* File to read from */ + void *pBuf, /* Write content into this buffer */ + int amt, /* Number of bytes to read */ + sqlite3_int64 offset /* Begin reading at this offset */ +){ + ULONG fileLocation = 0L; + ULONG got; + os2File *pFile = (os2File*)id; + assert( id!=0 ); + SimulateIOError( return SQLITE_IOERR_READ ); + OSTRACE(( "READ %d lock=%d\n", pFile->h, pFile->locktype )); + if( DosSetFilePtr(pFile->h, offset, FILE_BEGIN, &fileLocation) != NO_ERROR ){ + return SQLITE_IOERR; + } + if( DosRead( pFile->h, pBuf, amt, &got ) != NO_ERROR ){ + return SQLITE_IOERR_READ; + } + if( got == (ULONG)amt ) + return SQLITE_OK; + else { + /* Unread portions of the input buffer must be zero-filled */ + memset(&((char*)pBuf)[got], 0, amt-got); + return SQLITE_IOERR_SHORT_READ; + } +} + +/* +** Write data from a buffer into a file. Return SQLITE_OK on success +** or some other error code on failure. +*/ +static int os2Write( + sqlite3_file *id, /* File to write into */ + const void *pBuf, /* The bytes to be written */ + int amt, /* Number of bytes to write */ + sqlite3_int64 offset /* Offset into the file to begin writing at */ +){ + ULONG fileLocation = 0L; + APIRET rc = NO_ERROR; + ULONG wrote; + os2File *pFile = (os2File*)id; + assert( id!=0 ); + SimulateIOError( return SQLITE_IOERR_WRITE ); + SimulateDiskfullError( return SQLITE_FULL ); + OSTRACE(( "WRITE %d lock=%d\n", pFile->h, pFile->locktype )); + if( DosSetFilePtr(pFile->h, offset, FILE_BEGIN, &fileLocation) != NO_ERROR ){ + return SQLITE_IOERR; + } + assert( amt>0 ); + while( amt > 0 && + ( rc = DosWrite( pFile->h, (PVOID)pBuf, amt, &wrote ) ) == NO_ERROR && + wrote > 0 + ){ + amt -= wrote; + pBuf = &((char*)pBuf)[wrote]; + } + + return ( rc != NO_ERROR || amt > (int)wrote ) ? SQLITE_FULL : SQLITE_OK; +} + +/* +** Truncate an open file to a specified size +*/ +static int os2Truncate( sqlite3_file *id, i64 nByte ){ + APIRET rc; + os2File *pFile = (os2File*)id; + assert( id!=0 ); + OSTRACE(( "TRUNCATE %d %lld\n", pFile->h, nByte )); + SimulateIOError( return SQLITE_IOERR_TRUNCATE ); + + /* If the user has configured a chunk-size for this file, truncate the + ** file so that it consists of an integer number of chunks (i.e. the + ** actual file size after the operation may be larger than the requested + ** size). + */ + if( pFile->szChunk ){ + nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; + } + + rc = DosSetFileSize( pFile->h, nByte ); + return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR_TRUNCATE; +} + +#ifdef SQLITE_TEST +/* +** Count the number of fullsyncs and normal syncs. This is used to test +** that syncs and fullsyncs are occuring at the right times. +*/ +int sqlite3_sync_count = 0; +int sqlite3_fullsync_count = 0; +#endif + +/* +** Make sure all writes to a particular file are committed to disk. +*/ +static int os2Sync( sqlite3_file *id, int flags ){ + os2File *pFile = (os2File*)id; + OSTRACE(( "SYNC %d lock=%d\n", pFile->h, pFile->locktype )); +#ifdef SQLITE_TEST + if( flags & SQLITE_SYNC_FULL){ + sqlite3_fullsync_count++; + } + sqlite3_sync_count++; +#endif + /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a + ** no-op + */ +#ifdef SQLITE_NO_SYNC + UNUSED_PARAMETER(pFile); + return SQLITE_OK; +#else + return DosResetBuffer( pFile->h ) == NO_ERROR ? SQLITE_OK : SQLITE_IOERR; +#endif +} + +/* +** Determine the current size of a file in bytes +*/ +static int os2FileSize( sqlite3_file *id, sqlite3_int64 *pSize ){ + APIRET rc = NO_ERROR; + FILESTATUS3 fsts3FileInfo; + memset(&fsts3FileInfo, 0, sizeof(fsts3FileInfo)); + assert( id!=0 ); + SimulateIOError( return SQLITE_IOERR_FSTAT ); + rc = DosQueryFileInfo( ((os2File*)id)->h, FIL_STANDARD, &fsts3FileInfo, sizeof(FILESTATUS3) ); + if( rc == NO_ERROR ){ + *pSize = fsts3FileInfo.cbFile; + return SQLITE_OK; + }else{ + return SQLITE_IOERR_FSTAT; + } +} + +/* +** Acquire a reader lock. +*/ +static int getReadLock( os2File *pFile ){ + FILELOCK LockArea, + UnlockArea; + APIRET res; + memset(&LockArea, 0, sizeof(LockArea)); + memset(&UnlockArea, 0, sizeof(UnlockArea)); + LockArea.lOffset = SHARED_FIRST; + LockArea.lRange = SHARED_SIZE; + UnlockArea.lOffset = 0L; + UnlockArea.lRange = 0L; + res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 1L ); + OSTRACE(( "GETREADLOCK %d res=%d\n", pFile->h, res )); + return res; +} + +/* +** Undo a readlock +*/ +static int unlockReadLock( os2File *id ){ + FILELOCK LockArea, + UnlockArea; + APIRET res; + memset(&LockArea, 0, sizeof(LockArea)); + memset(&UnlockArea, 0, sizeof(UnlockArea)); + LockArea.lOffset = 0L; + LockArea.lRange = 0L; + UnlockArea.lOffset = SHARED_FIRST; + UnlockArea.lRange = SHARED_SIZE; + res = DosSetFileLocks( id->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 1L ); + OSTRACE(( "UNLOCK-READLOCK file handle=%d res=%d?\n", id->h, res )); + return res; +} + +/* +** Lock the file with the lock specified by parameter locktype - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** SHARED -> (PENDING) -> EXCLUSIVE +** RESERVED -> (PENDING) -> EXCLUSIVE +** PENDING -> EXCLUSIVE +** +** This routine will only increase a lock. The os2Unlock() routine +** erases all locks at once and returns us immediately to locking level 0. +** It is not possible to lower the locking level one step at a time. You +** must go straight to locking level 0. +*/ +static int os2Lock( sqlite3_file *id, int locktype ){ + int rc = SQLITE_OK; /* Return code from subroutines */ + APIRET res = NO_ERROR; /* Result of an OS/2 lock call */ + int newLocktype; /* Set pFile->locktype to this value before exiting */ + int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */ + FILELOCK LockArea, + UnlockArea; + os2File *pFile = (os2File*)id; + memset(&LockArea, 0, sizeof(LockArea)); + memset(&UnlockArea, 0, sizeof(UnlockArea)); + assert( pFile!=0 ); + OSTRACE(( "LOCK %d %d was %d\n", pFile->h, locktype, pFile->locktype )); + + /* If there is already a lock of this type or more restrictive on the + ** os2File, do nothing. Don't use the end_lock: exit path, as + ** sqlite3_mutex_enter() hasn't been called yet. + */ + if( pFile->locktype>=locktype ){ + OSTRACE(( "LOCK %d %d ok (already held)\n", pFile->h, locktype )); + return SQLITE_OK; + } + + /* Make sure the locking sequence is correct + */ + assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK ); + assert( locktype!=PENDING_LOCK ); + assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK ); + + /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or + ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of + ** the PENDING_LOCK byte is temporary. + */ + newLocktype = pFile->locktype; + if( pFile->locktype==NO_LOCK + || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK) + ){ + LockArea.lOffset = PENDING_BYTE; + LockArea.lRange = 1L; + UnlockArea.lOffset = 0L; + UnlockArea.lRange = 0L; + + /* wait longer than LOCK_TIMEOUT here not to have to try multiple times */ + res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 100L, 0L ); + if( res == NO_ERROR ){ + gotPendingLock = 1; + OSTRACE(( "LOCK %d pending lock boolean set. res=%d\n", pFile->h, res )); + } + } + + /* Acquire a shared lock + */ + if( locktype==SHARED_LOCK && res == NO_ERROR ){ + assert( pFile->locktype==NO_LOCK ); + res = getReadLock(pFile); + if( res == NO_ERROR ){ + newLocktype = SHARED_LOCK; + } + OSTRACE(( "LOCK %d acquire shared lock. res=%d\n", pFile->h, res )); + } + + /* Acquire a RESERVED lock + */ + if( locktype==RESERVED_LOCK && res == NO_ERROR ){ + assert( pFile->locktype==SHARED_LOCK ); + LockArea.lOffset = RESERVED_BYTE; + LockArea.lRange = 1L; + UnlockArea.lOffset = 0L; + UnlockArea.lRange = 0L; + res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); + if( res == NO_ERROR ){ + newLocktype = RESERVED_LOCK; + } + OSTRACE(( "LOCK %d acquire reserved lock. res=%d\n", pFile->h, res )); + } + + /* Acquire a PENDING lock + */ + if( locktype==EXCLUSIVE_LOCK && res == NO_ERROR ){ + newLocktype = PENDING_LOCK; + gotPendingLock = 0; + OSTRACE(( "LOCK %d acquire pending lock. pending lock boolean unset.\n", + pFile->h )); + } + + /* Acquire an EXCLUSIVE lock + */ + if( locktype==EXCLUSIVE_LOCK && res == NO_ERROR ){ + assert( pFile->locktype>=SHARED_LOCK ); + res = unlockReadLock(pFile); + OSTRACE(( "unreadlock = %d\n", res )); + LockArea.lOffset = SHARED_FIRST; + LockArea.lRange = SHARED_SIZE; + UnlockArea.lOffset = 0L; + UnlockArea.lRange = 0L; + res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); + if( res == NO_ERROR ){ + newLocktype = EXCLUSIVE_LOCK; + }else{ + OSTRACE(( "OS/2 error-code = %d\n", res )); + getReadLock(pFile); + } + OSTRACE(( "LOCK %d acquire exclusive lock. res=%d\n", pFile->h, res )); + } + + /* If we are holding a PENDING lock that ought to be released, then + ** release it now. + */ + if( gotPendingLock && locktype==SHARED_LOCK ){ + int r; + LockArea.lOffset = 0L; + LockArea.lRange = 0L; + UnlockArea.lOffset = PENDING_BYTE; + UnlockArea.lRange = 1L; + r = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); + OSTRACE(( "LOCK %d unlocking pending/is shared. r=%d\n", pFile->h, r )); + } + + /* Update the state of the lock has held in the file descriptor then + ** return the appropriate result code. + */ + if( res == NO_ERROR ){ + rc = SQLITE_OK; + }else{ + OSTRACE(( "LOCK FAILED %d trying for %d but got %d\n", pFile->h, + locktype, newLocktype )); + rc = SQLITE_BUSY; + } + pFile->locktype = newLocktype; + OSTRACE(( "LOCK %d now %d\n", pFile->h, pFile->locktype )); + return rc; +} + +/* +** This routine checks if there is a RESERVED lock held on the specified +** file by this or any other process. If such a lock is held, return +** non-zero, otherwise zero. +*/ +static int os2CheckReservedLock( sqlite3_file *id, int *pOut ){ + int r = 0; + os2File *pFile = (os2File*)id; + assert( pFile!=0 ); + if( pFile->locktype>=RESERVED_LOCK ){ + r = 1; + OSTRACE(( "TEST WR-LOCK %d %d (local)\n", pFile->h, r )); + }else{ + FILELOCK LockArea, + UnlockArea; + APIRET rc = NO_ERROR; + memset(&LockArea, 0, sizeof(LockArea)); + memset(&UnlockArea, 0, sizeof(UnlockArea)); + LockArea.lOffset = RESERVED_BYTE; + LockArea.lRange = 1L; + UnlockArea.lOffset = 0L; + UnlockArea.lRange = 0L; + rc = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); + OSTRACE(( "TEST WR-LOCK %d lock reserved byte rc=%d\n", pFile->h, rc )); + if( rc == NO_ERROR ){ + APIRET rcu = NO_ERROR; /* return code for unlocking */ + LockArea.lOffset = 0L; + LockArea.lRange = 0L; + UnlockArea.lOffset = RESERVED_BYTE; + UnlockArea.lRange = 1L; + rcu = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); + OSTRACE(( "TEST WR-LOCK %d unlock reserved byte r=%d\n", pFile->h, rcu )); + } + r = !(rc == NO_ERROR); + OSTRACE(( "TEST WR-LOCK %d %d (remote)\n", pFile->h, r )); + } + *pOut = r; + return SQLITE_OK; +} + +/* +** Lower the locking level on file descriptor id to locktype. locktype +** must be either NO_LOCK or SHARED_LOCK. +** +** If the locking level of the file descriptor is already at or below +** the requested locking level, this routine is a no-op. +** +** It is not possible for this routine to fail if the second argument +** is NO_LOCK. If the second argument is SHARED_LOCK then this routine +** might return SQLITE_IOERR; +*/ +static int os2Unlock( sqlite3_file *id, int locktype ){ + int type; + os2File *pFile = (os2File*)id; + APIRET rc = SQLITE_OK; + APIRET res = NO_ERROR; + FILELOCK LockArea, + UnlockArea; + memset(&LockArea, 0, sizeof(LockArea)); + memset(&UnlockArea, 0, sizeof(UnlockArea)); + assert( pFile!=0 ); + assert( locktype<=SHARED_LOCK ); + OSTRACE(( "UNLOCK %d to %d was %d\n", pFile->h, locktype, pFile->locktype )); + type = pFile->locktype; + if( type>=EXCLUSIVE_LOCK ){ + LockArea.lOffset = 0L; + LockArea.lRange = 0L; + UnlockArea.lOffset = SHARED_FIRST; + UnlockArea.lRange = SHARED_SIZE; + res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); + OSTRACE(( "UNLOCK %d exclusive lock res=%d\n", pFile->h, res )); + if( locktype==SHARED_LOCK && getReadLock(pFile) != NO_ERROR ){ + /* This should never happen. We should always be able to + ** reacquire the read lock */ + OSTRACE(( "UNLOCK %d to %d getReadLock() failed\n", pFile->h, locktype )); + rc = SQLITE_IOERR_UNLOCK; + } + } + if( type>=RESERVED_LOCK ){ + LockArea.lOffset = 0L; + LockArea.lRange = 0L; + UnlockArea.lOffset = RESERVED_BYTE; + UnlockArea.lRange = 1L; + res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); + OSTRACE(( "UNLOCK %d reserved res=%d\n", pFile->h, res )); + } + if( locktype==NO_LOCK && type>=SHARED_LOCK ){ + res = unlockReadLock(pFile); + OSTRACE(( "UNLOCK %d is %d want %d res=%d\n", + pFile->h, type, locktype, res )); + } + if( type>=PENDING_LOCK ){ + LockArea.lOffset = 0L; + LockArea.lRange = 0L; + UnlockArea.lOffset = PENDING_BYTE; + UnlockArea.lRange = 1L; + res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L ); + OSTRACE(( "UNLOCK %d pending res=%d\n", pFile->h, res )); + } + pFile->locktype = locktype; + OSTRACE(( "UNLOCK %d now %d\n", pFile->h, pFile->locktype )); + return rc; +} + +/* +** Control and query of the open file handle. +*/ +static int os2FileControl(sqlite3_file *id, int op, void *pArg){ + switch( op ){ + case SQLITE_FCNTL_LOCKSTATE: { + *(int*)pArg = ((os2File*)id)->locktype; + OSTRACE(( "FCNTL_LOCKSTATE %d lock=%d\n", + ((os2File*)id)->h, ((os2File*)id)->locktype )); + return SQLITE_OK; + } + case SQLITE_FCNTL_CHUNK_SIZE: { + ((os2File*)id)->szChunk = *(int*)pArg; + return SQLITE_OK; + } + case SQLITE_FCNTL_SIZE_HINT: { + sqlite3_int64 sz = *(sqlite3_int64*)pArg; + SimulateIOErrorBenign(1); + os2Truncate(id, sz); + SimulateIOErrorBenign(0); + return SQLITE_OK; + } + case SQLITE_FCNTL_SYNC_OMITTED: { + return SQLITE_OK; + } + } + return SQLITE_NOTFOUND; +} + +/* +** Return the sector size in bytes of the underlying block device for +** the specified file. This is almost always 512 bytes, but may be +** larger for some devices. +** +** SQLite code assumes this function cannot fail. It also assumes that +** if two files are created in the same file-system directory (i.e. +** a database and its journal file) that the sector size will be the +** same for both. +*/ +static int os2SectorSize(sqlite3_file *id){ + UNUSED_PARAMETER(id); + return SQLITE_DEFAULT_SECTOR_SIZE; +} + +/* +** Return a vector of device characteristics. +*/ +static int os2DeviceCharacteristics(sqlite3_file *id){ + UNUSED_PARAMETER(id); + return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN; +} + + +/* +** Character set conversion objects used by conversion routines. +*/ +static UconvObject ucUtf8 = NULL; /* convert between UTF-8 and UCS-2 */ +static UconvObject uclCp = NULL; /* convert between local codepage and UCS-2 */ + +/* +** Helper function to initialize the conversion objects from and to UTF-8. +*/ +static void initUconvObjects( void ){ + if( UniCreateUconvObject( UTF_8, &ucUtf8 ) != ULS_SUCCESS ) + ucUtf8 = NULL; + if ( UniCreateUconvObject( (UniChar *)L"@path=yes", &uclCp ) != ULS_SUCCESS ) + uclCp = NULL; +} + +/* +** Helper function to free the conversion objects from and to UTF-8. +*/ +static void freeUconvObjects( void ){ + if ( ucUtf8 ) + UniFreeUconvObject( ucUtf8 ); + if ( uclCp ) + UniFreeUconvObject( uclCp ); + ucUtf8 = NULL; + uclCp = NULL; +} + +/* +** Helper function to convert UTF-8 filenames to local OS/2 codepage. +** The two-step process: first convert the incoming UTF-8 string +** into UCS-2 and then from UCS-2 to the current codepage. +** The returned char pointer has to be freed. +*/ +static char *convertUtf8PathToCp( const char *in ){ + UniChar tempPath[CCHMAXPATH]; + char *out = (char *)calloc( CCHMAXPATH, 1 ); + + if( !out ) + return NULL; + + if( !ucUtf8 || !uclCp ) + initUconvObjects(); + + /* determine string for the conversion of UTF-8 which is CP1208 */ + if( UniStrToUcs( ucUtf8, tempPath, (char *)in, CCHMAXPATH ) != ULS_SUCCESS ) + return out; /* if conversion fails, return the empty string */ + + /* conversion for current codepage which can be used for paths */ + UniStrFromUcs( uclCp, out, tempPath, CCHMAXPATH ); + + return out; +} + +/* +** Helper function to convert filenames from local codepage to UTF-8. +** The two-step process: first convert the incoming codepage-specific +** string into UCS-2 and then from UCS-2 to the codepage of UTF-8. +** The returned char pointer has to be freed. +** +** This function is non-static to be able to use this in shell.c and +** similar applications that take command line arguments. +*/ +char *convertCpPathToUtf8( const char *in ){ + UniChar tempPath[CCHMAXPATH]; + char *out = (char *)calloc( CCHMAXPATH, 1 ); + + if( !out ) + return NULL; + + if( !ucUtf8 || !uclCp ) + initUconvObjects(); + + /* conversion for current codepage which can be used for paths */ + if( UniStrToUcs( uclCp, tempPath, (char *)in, CCHMAXPATH ) != ULS_SUCCESS ) + return out; /* if conversion fails, return the empty string */ + + /* determine string for the conversion of UTF-8 which is CP1208 */ + UniStrFromUcs( ucUtf8, out, tempPath, CCHMAXPATH ); + + return out; +} + + +#ifndef SQLITE_OMIT_WAL + +/* +** Use main database file for interprocess locking. If un-defined +** a separate file is created for this purpose. The file will be +** used only to set file locks. There will be no data written to it. +*/ +#define SQLITE_OS2_NO_WAL_LOCK_FILE + +#if 0 +static void _ERR_TRACE( const char *fmt, ... ) { + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + fflush(stderr); +} +#define ERR_TRACE(rc, msg) \ + if( (rc) != SQLITE_OK ) _ERR_TRACE msg; +#else +#define ERR_TRACE(rc, msg) +#endif + +/* +** Helper functions to obtain and relinquish the global mutex. The +** global mutex is used to protect os2ShmNodeList. +** +** Function os2ShmMutexHeld() is used to assert() that the global mutex +** is held when required. This function is only used as part of assert() +** statements. e.g. +** +** os2ShmEnterMutex() +** assert( os2ShmMutexHeld() ); +** os2ShmLeaveMutex() +*/ +static void os2ShmEnterMutex(void){ + sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); +} +static void os2ShmLeaveMutex(void){ + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); +} +#ifdef SQLITE_DEBUG +static int os2ShmMutexHeld(void) { + return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); +} +int GetCurrentProcessId(void) { + PPIB pib; + DosGetInfoBlocks(NULL, &pib); + return (int)pib->pib_ulpid; +} +#endif + +/* +** Object used to represent a the shared memory area for a single log file. +** When multiple threads all reference the same log-summary, each thread has +** its own os2File object, but they all point to a single instance of this +** object. In other words, each log-summary is opened only once per process. +** +** os2ShmMutexHeld() must be true when creating or destroying +** this object or while reading or writing the following fields: +** +** nRef +** pNext +** +** The following fields are read-only after the object is created: +** +** szRegion +** hLockFile +** shmBaseName +** +** Either os2ShmNode.mutex must be held or os2ShmNode.nRef==0 and +** os2ShmMutexHeld() is true when reading or writing any other field +** in this structure. +** +*/ +struct os2ShmNode { + sqlite3_mutex *mutex; /* Mutex to access this object */ + os2ShmNode *pNext; /* Next in list of all os2ShmNode objects */ + + int szRegion; /* Size of shared-memory regions */ + + int nRegion; /* Size of array apRegion */ + void **apRegion; /* Array of pointers to shared-memory regions */ + + int nRef; /* Number of os2ShmLink objects pointing to this */ + os2ShmLink *pFirst; /* First os2ShmLink object pointing to this */ + + HFILE hLockFile; /* File used for inter-process memory locking */ + char shmBaseName[1]; /* Name of the memory object !!! must last !!! */ +}; + + +/* +** Structure used internally by this VFS to record the state of an +** open shared memory connection. +** +** The following fields are initialized when this object is created and +** are read-only thereafter: +** +** os2Shm.pShmNode +** os2Shm.id +** +** All other fields are read/write. The os2Shm.pShmNode->mutex must be held +** while accessing any read/write fields. +*/ +struct os2ShmLink { + os2ShmNode *pShmNode; /* The underlying os2ShmNode object */ + os2ShmLink *pNext; /* Next os2Shm with the same os2ShmNode */ + u32 sharedMask; /* Mask of shared locks held */ + u32 exclMask; /* Mask of exclusive locks held */ +#ifdef SQLITE_DEBUG + u8 id; /* Id of this connection with its os2ShmNode */ +#endif +}; + + +/* +** A global list of all os2ShmNode objects. +** +** The os2ShmMutexHeld() must be true while reading or writing this list. +*/ +static os2ShmNode *os2ShmNodeList = NULL; + +/* +** Constants used for locking +*/ +#ifdef SQLITE_OS2_NO_WAL_LOCK_FILE +#define OS2_SHM_BASE (PENDING_BYTE + 0x10000) /* first lock byte */ +#else +#define OS2_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */ +#endif + +#define OS2_SHM_DMS (OS2_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */ + +/* +** Apply advisory locks for all n bytes beginning at ofst. +*/ +#define _SHM_UNLCK 1 /* no lock */ +#define _SHM_RDLCK 2 /* shared lock, no wait */ +#define _SHM_WRLCK 3 /* exlusive lock, no wait */ +#define _SHM_WRLCK_WAIT 4 /* exclusive lock, wait */ +static int os2ShmSystemLock( + os2ShmNode *pNode, /* Apply locks to this open shared-memory segment */ + int lockType, /* _SHM_UNLCK, _SHM_RDLCK, _SHM_WRLCK or _SHM_WRLCK_WAIT */ + int ofst, /* Offset to first byte to be locked/unlocked */ + int nByte /* Number of bytes to lock or unlock */ +){ + APIRET rc; + FILELOCK area; + ULONG mode, timeout; + + /* Access to the os2ShmNode object is serialized by the caller */ + assert( sqlite3_mutex_held(pNode->mutex) || pNode->nRef==0 ); + + mode = 1; /* shared lock */ + timeout = 0; /* no wait */ + area.lOffset = ofst; + area.lRange = nByte; + + switch( lockType ) { + case _SHM_WRLCK_WAIT: + timeout = (ULONG)-1; /* wait forever */ + case _SHM_WRLCK: + mode = 0; /* exclusive lock */ + case _SHM_RDLCK: + rc = DosSetFileLocks(pNode->hLockFile, + NULL, &area, timeout, mode); + break; + /* case _SHM_UNLCK: */ + default: + rc = DosSetFileLocks(pNode->hLockFile, + &area, NULL, 0, 0); + break; + } + + OSTRACE(("SHM-LOCK %d %s %s 0x%08lx\n", + pNode->hLockFile, + rc==SQLITE_OK ? "ok" : "failed", + lockType==_SHM_UNLCK ? "Unlock" : "Lock", + rc)); + + ERR_TRACE(rc, ("os2ShmSystemLock: %d %s\n", rc, pNode->shmBaseName)) + + return ( rc == 0 ) ? SQLITE_OK : SQLITE_BUSY; +} + +/* +** Find an os2ShmNode in global list or allocate a new one, if not found. +** +** This is not a VFS shared-memory method; it is a utility function called +** by VFS shared-memory methods. +*/ +static int os2OpenSharedMemory( os2File *fd, int szRegion ) { + os2ShmLink *pLink; + os2ShmNode *pNode; + int cbShmName, rc = SQLITE_OK; + char shmName[CCHMAXPATH + 30]; +#ifndef SQLITE_OS2_NO_WAL_LOCK_FILE + ULONG action; +#endif + + /* We need some additional space at the end to append the region number */ + cbShmName = sprintf(shmName, "\\SHAREMEM\\%s", fd->zFullPathCp ); + if( cbShmName >= CCHMAXPATH-8 ) + return SQLITE_IOERR_SHMOPEN; + + /* Replace colon in file name to form a valid shared memory name */ + shmName[10+1] = '!'; + + /* Allocate link object (we free it later in case of failure) */ + pLink = sqlite3_malloc( sizeof(*pLink) ); + if( !pLink ) + return SQLITE_NOMEM; + + /* Access node list */ + os2ShmEnterMutex(); + + /* Find node by it's shared memory base name */ + for( pNode = os2ShmNodeList; + pNode && stricmp(shmName, pNode->shmBaseName) != 0; + pNode = pNode->pNext ) ; + + /* Not found: allocate a new node */ + if( !pNode ) { + pNode = sqlite3_malloc( sizeof(*pNode) + cbShmName ); + if( pNode ) { + memset(pNode, 0, sizeof(*pNode) ); + pNode->szRegion = szRegion; + pNode->hLockFile = (HFILE)-1; + strcpy(pNode->shmBaseName, shmName); + +#ifdef SQLITE_OS2_NO_WAL_LOCK_FILE + if( DosDupHandle(fd->h, &pNode->hLockFile) != 0 ) { +#else + sprintf(shmName, "%s-lck", fd->zFullPathCp); + if( DosOpen((PSZ)shmName, &pNode->hLockFile, &action, 0, FILE_NORMAL, + OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW, + OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE | + OPEN_FLAGS_NOINHERIT | OPEN_FLAGS_FAIL_ON_ERROR, + NULL) != 0 ) { +#endif + sqlite3_free(pNode); + rc = SQLITE_IOERR; + } else { + pNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( !pNode->mutex ) { + sqlite3_free(pNode); + rc = SQLITE_NOMEM; + } + } + } else { + rc = SQLITE_NOMEM; + } + + if( rc == SQLITE_OK ) { + pNode->pNext = os2ShmNodeList; + os2ShmNodeList = pNode; + } else { + pNode = NULL; + } + } else if( pNode->szRegion != szRegion ) { + rc = SQLITE_IOERR_SHMSIZE; + pNode = NULL; + } + + if( pNode ) { + sqlite3_mutex_enter(pNode->mutex); + + memset(pLink, 0, sizeof(*pLink)); + + pLink->pShmNode = pNode; + pLink->pNext = pNode->pFirst; + pNode->pFirst = pLink; + pNode->nRef++; + + fd->pShmLink = pLink; + + sqlite3_mutex_leave(pNode->mutex); + + } else { + /* Error occured. Free our link object. */ + sqlite3_free(pLink); + } + + os2ShmLeaveMutex(); + + ERR_TRACE(rc, ("os2OpenSharedMemory: %d %s\n", rc, fd->zFullPathCp)) + + return rc; +} + +/* +** Purge the os2ShmNodeList list of all entries with nRef==0. +** +** This is not a VFS shared-memory method; it is a utility function called +** by VFS shared-memory methods. +*/ +static void os2PurgeShmNodes( int deleteFlag ) { + os2ShmNode *pNode; + os2ShmNode **ppNode; + + os2ShmEnterMutex(); + + ppNode = &os2ShmNodeList; + + while( *ppNode ) { + pNode = *ppNode; + + if( pNode->nRef == 0 ) { + *ppNode = pNode->pNext; + + if( pNode->apRegion ) { + /* Prevent other processes from resizing the shared memory */ + os2ShmSystemLock(pNode, _SHM_WRLCK_WAIT, OS2_SHM_DMS, 1); + + while( pNode->nRegion-- ) { +#ifdef SQLITE_DEBUG + int rc = +#endif + DosFreeMem(pNode->apRegion[pNode->nRegion]); + + OSTRACE(("SHM-PURGE pid-%d unmap region=%d %s\n", + (int)GetCurrentProcessId(), pNode->nRegion, + rc == 0 ? "ok" : "failed")); + } + + /* Allow other processes to resize the shared memory */ + os2ShmSystemLock(pNode, _SHM_UNLCK, OS2_SHM_DMS, 1); + + sqlite3_free(pNode->apRegion); + } + + DosClose(pNode->hLockFile); + +#ifndef SQLITE_OS2_NO_WAL_LOCK_FILE + if( deleteFlag ) { + char fileName[CCHMAXPATH]; + /* Skip "\\SHAREMEM\\" */ + sprintf(fileName, "%s-lck", pNode->shmBaseName + 10); + /* restore colon */ + fileName[1] = ':'; + + DosForceDelete(fileName); + } +#endif + + sqlite3_mutex_free(pNode->mutex); + + sqlite3_free(pNode); + + } else { + ppNode = &pNode->pNext; + } + } + + os2ShmLeaveMutex(); +} + +/* +** This function is called to obtain a pointer to region iRegion of the +** shared-memory associated with the database file id. Shared-memory regions +** are numbered starting from zero. Each shared-memory region is szRegion +** bytes in size. +** +** If an error occurs, an error code is returned and *pp is set to NULL. +** +** Otherwise, if the bExtend parameter is 0 and the requested shared-memory +** region has not been allocated (by any client, including one running in a +** separate process), then *pp is set to NULL and SQLITE_OK returned. If +** bExtend is non-zero and the requested shared-memory region has not yet +** been allocated, it is allocated by this function. +** +** If the shared-memory region has already been allocated or is allocated by +** this call as described above, then it is mapped into this processes +** address space (if it is not already), *pp is set to point to the mapped +** memory and SQLITE_OK returned. +*/ +static int os2ShmMap( + sqlite3_file *id, /* Handle open on database file */ + int iRegion, /* Region to retrieve */ + int szRegion, /* Size of regions */ + int bExtend, /* True to extend block if necessary */ + void volatile **pp /* OUT: Mapped memory */ +){ + PVOID pvTemp; + void **apRegion; + os2ShmNode *pNode; + int n, rc = SQLITE_OK; + char shmName[CCHMAXPATH]; + os2File *pFile = (os2File*)id; + + *pp = NULL; + + if( !pFile->pShmLink ) + rc = os2OpenSharedMemory( pFile, szRegion ); + + if( rc == SQLITE_OK ) { + pNode = pFile->pShmLink->pShmNode ; + + sqlite3_mutex_enter(pNode->mutex); + + assert( szRegion==pNode->szRegion ); + + /* Unmapped region ? */ + if( iRegion >= pNode->nRegion ) { + /* Prevent other processes from resizing the shared memory */ + os2ShmSystemLock(pNode, _SHM_WRLCK_WAIT, OS2_SHM_DMS, 1); + + apRegion = sqlite3_realloc( + pNode->apRegion, (iRegion + 1) * sizeof(apRegion[0])); + + if( apRegion ) { + pNode->apRegion = apRegion; + + while( pNode->nRegion <= iRegion ) { + sprintf(shmName, "%s-%u", + pNode->shmBaseName, pNode->nRegion); + + if( DosGetNamedSharedMem(&pvTemp, (PSZ)shmName, + PAG_READ | PAG_WRITE) != NO_ERROR ) { + if( !bExtend ) + break; + + if( DosAllocSharedMem(&pvTemp, (PSZ)shmName, szRegion, + PAG_READ | PAG_WRITE | PAG_COMMIT | OBJ_ANY) != NO_ERROR && + DosAllocSharedMem(&pvTemp, (PSZ)shmName, szRegion, + PAG_READ | PAG_WRITE | PAG_COMMIT) != NO_ERROR ) { + rc = SQLITE_NOMEM; + break; + } + } + + apRegion[pNode->nRegion++] = pvTemp; + } + + /* zero out remaining entries */ + for( n = pNode->nRegion; n <= iRegion; n++ ) + pNode->apRegion[n] = NULL; + + /* Return this region (maybe zero) */ + *pp = pNode->apRegion[iRegion]; + } else { + rc = SQLITE_NOMEM; + } + + /* Allow other processes to resize the shared memory */ + os2ShmSystemLock(pNode, _SHM_UNLCK, OS2_SHM_DMS, 1); + + } else { + /* Region has been mapped previously */ + *pp = pNode->apRegion[iRegion]; + } + + sqlite3_mutex_leave(pNode->mutex); + } + + ERR_TRACE(rc, ("os2ShmMap: %s iRgn = %d, szRgn = %d, bExt = %d : %d\n", + pFile->zFullPathCp, iRegion, szRegion, bExtend, rc)) + + return rc; +} + +/* +** Close a connection to shared-memory. Delete the underlying +** storage if deleteFlag is true. +** +** If there is no shared memory associated with the connection then this +** routine is a harmless no-op. +*/ +static int os2ShmUnmap( + sqlite3_file *id, /* The underlying database file */ + int deleteFlag /* Delete shared-memory if true */ +){ + os2File *pFile = (os2File*)id; + os2ShmLink *pLink = pFile->pShmLink; + + if( pLink ) { + int nRef = -1; + os2ShmLink **ppLink; + os2ShmNode *pNode = pLink->pShmNode; + + sqlite3_mutex_enter(pNode->mutex); + + for( ppLink = &pNode->pFirst; + *ppLink && *ppLink != pLink; + ppLink = &(*ppLink)->pNext ) ; + + assert(*ppLink); + + if( *ppLink ) { + *ppLink = pLink->pNext; + nRef = --pNode->nRef; + } else { + ERR_TRACE(1, ("os2ShmUnmap: link not found ! %s\n", + pNode->shmBaseName)) + } + + pFile->pShmLink = NULL; + sqlite3_free(pLink); + + sqlite3_mutex_leave(pNode->mutex); + + if( nRef == 0 ) + os2PurgeShmNodes( deleteFlag ); + } + + return SQLITE_OK; +} + +/* +** Change the lock state for a shared-memory segment. +** +** Note that the relationship between SHAREd and EXCLUSIVE locks is a little +** different here than in posix. In xShmLock(), one can go from unlocked +** to shared and back or from unlocked to exclusive and back. But one may +** not go from shared to exclusive or from exclusive to shared. +*/ +static int os2ShmLock( + sqlite3_file *id, /* Database file holding the shared memory */ + int ofst, /* First lock to acquire or release */ + int n, /* Number of locks to acquire or release */ + int flags /* What to do with the lock */ +){ + u32 mask; /* Mask of locks to take or release */ + int rc = SQLITE_OK; /* Result code */ + os2File *pFile = (os2File*)id; + os2ShmLink *p = pFile->pShmLink; /* The shared memory being locked */ + os2ShmLink *pX; /* For looping over all siblings */ + os2ShmNode *pShmNode = p->pShmNode; /* Our node */ + + assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK ); + assert( n>=1 ); + assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED) + || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE) + || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED) + || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) ); + assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); + + mask = (u32)((1U<<(ofst+n)) - (1U<1 || mask==(1<mutex); + + if( flags & SQLITE_SHM_UNLOCK ){ + u32 allMask = 0; /* Mask of locks held by siblings */ + + /* See if any siblings hold this same lock */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( pX==p ) continue; + assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 ); + allMask |= pX->sharedMask; + } + + /* Unlock the system-level locks */ + if( (mask & allMask)==0 ){ + rc = os2ShmSystemLock(pShmNode, _SHM_UNLCK, ofst+OS2_SHM_BASE, n); + }else{ + rc = SQLITE_OK; + } + + /* Undo the local locks */ + if( rc==SQLITE_OK ){ + p->exclMask &= ~mask; + p->sharedMask &= ~mask; + } + }else if( flags & SQLITE_SHM_SHARED ){ + u32 allShared = 0; /* Union of locks held by connections other than "p" */ + + /* Find out which shared locks are already held by sibling connections. + ** If any sibling already holds an exclusive lock, go ahead and return + ** SQLITE_BUSY. + */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( (pX->exclMask & mask)!=0 ){ + rc = SQLITE_BUSY; + break; + } + allShared |= pX->sharedMask; + } + + /* Get shared locks at the system level, if necessary */ + if( rc==SQLITE_OK ){ + if( (allShared & mask)==0 ){ + rc = os2ShmSystemLock(pShmNode, _SHM_RDLCK, ofst+OS2_SHM_BASE, n); + }else{ + rc = SQLITE_OK; + } + } + + /* Get the local shared locks */ + if( rc==SQLITE_OK ){ + p->sharedMask |= mask; + } + }else{ + /* Make sure no sibling connections hold locks that will block this + ** lock. If any do, return SQLITE_BUSY right away. + */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){ + rc = SQLITE_BUSY; + break; + } + } + + /* Get the exclusive locks at the system level. Then if successful + ** also mark the local connection as being locked. + */ + if( rc==SQLITE_OK ){ + rc = os2ShmSystemLock(pShmNode, _SHM_WRLCK, ofst+OS2_SHM_BASE, n); + if( rc==SQLITE_OK ){ + assert( (p->sharedMask & mask)==0 ); + p->exclMask |= mask; + } + } + } + + sqlite3_mutex_leave(pShmNode->mutex); + + OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x %s\n", + p->id, (int)GetCurrentProcessId(), p->sharedMask, p->exclMask, + rc ? "failed" : "ok")); + + ERR_TRACE(rc, ("os2ShmLock: ofst = %d, n = %d, flags = 0x%x -> %d \n", + ofst, n, flags, rc)) + + return rc; +} + +/* +** Implement a memory barrier or memory fence on shared memory. +** +** All loads and stores begun before the barrier must complete before +** any load or store begun after the barrier. +*/ +static void os2ShmBarrier( + sqlite3_file *id /* Database file holding the shared memory */ +){ + UNUSED_PARAMETER(id); + os2ShmEnterMutex(); + os2ShmLeaveMutex(); +} + +#else +# define os2ShmMap 0 +# define os2ShmLock 0 +# define os2ShmBarrier 0 +# define os2ShmUnmap 0 +#endif /* #ifndef SQLITE_OMIT_WAL */ + + +/* +** This vector defines all the methods that can operate on an +** sqlite3_file for os2. +*/ +static const sqlite3_io_methods os2IoMethod = { + 2, /* iVersion */ + os2Close, /* xClose */ + os2Read, /* xRead */ + os2Write, /* xWrite */ + os2Truncate, /* xTruncate */ + os2Sync, /* xSync */ + os2FileSize, /* xFileSize */ + os2Lock, /* xLock */ + os2Unlock, /* xUnlock */ + os2CheckReservedLock, /* xCheckReservedLock */ + os2FileControl, /* xFileControl */ + os2SectorSize, /* xSectorSize */ + os2DeviceCharacteristics, /* xDeviceCharacteristics */ + os2ShmMap, /* xShmMap */ + os2ShmLock, /* xShmLock */ + os2ShmBarrier, /* xShmBarrier */ + os2ShmUnmap /* xShmUnmap */ +}; + + +/*************************************************************************** +** Here ends the I/O methods that form the sqlite3_io_methods object. +** +** The next block of code implements the VFS methods. +****************************************************************************/ + +/* +** Create a temporary file name in zBuf. zBuf must be big enough to +** hold at pVfs->mxPathname characters. +*/ +static int getTempname(int nBuf, char *zBuf ){ + static const char zChars[] = + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789"; + int i, j; + PSZ zTempPathCp; + char zTempPath[CCHMAXPATH]; + ULONG ulDriveNum, ulDriveMap; + + /* It's odd to simulate an io-error here, but really this is just + ** using the io-error infrastructure to test that SQLite handles this + ** function failing. + */ + SimulateIOError( return SQLITE_IOERR ); + + if( sqlite3_temp_directory ) { + sqlite3_snprintf(CCHMAXPATH-30, zTempPath, "%s", sqlite3_temp_directory); + } else if( DosScanEnv( (PSZ)"TEMP", &zTempPathCp ) == NO_ERROR || + DosScanEnv( (PSZ)"TMP", &zTempPathCp ) == NO_ERROR || + DosScanEnv( (PSZ)"TMPDIR", &zTempPathCp ) == NO_ERROR ) { + char *zTempPathUTF = convertCpPathToUtf8( (char *)zTempPathCp ); + sqlite3_snprintf(CCHMAXPATH-30, zTempPath, "%s", zTempPathUTF); + free( zTempPathUTF ); + } else if( DosQueryCurrentDisk( &ulDriveNum, &ulDriveMap ) == NO_ERROR ) { + zTempPath[0] = (char)('A' + ulDriveNum - 1); + zTempPath[1] = ':'; + zTempPath[2] = '\0'; + } else { + zTempPath[0] = '\0'; + } + + /* Strip off a trailing slashes or backslashes, otherwise we would get * + * multiple (back)slashes which causes DosOpen() to fail. * + * Trailing spaces are not allowed, either. */ + j = sqlite3Strlen30(zTempPath); + while( j > 0 && ( zTempPath[j-1] == '\\' || zTempPath[j-1] == '/' || + zTempPath[j-1] == ' ' ) ){ + j--; + } + zTempPath[j] = '\0'; + + /* We use 20 bytes to randomize the name */ + sqlite3_snprintf(nBuf-22, zBuf, + "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath); + j = sqlite3Strlen30(zBuf); + sqlite3_randomness( 20, &zBuf[j] ); + for( i = 0; i < 20; i++, j++ ){ + zBuf[j] = zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; + } + zBuf[j] = 0; + + OSTRACE(( "TEMP FILENAME: %s\n", zBuf )); + return SQLITE_OK; +} + + +/* +** Turn a relative pathname into a full pathname. Write the full +** pathname into zFull[]. zFull[] will be at least pVfs->mxPathname +** bytes in size. +*/ +static int os2FullPathname( + sqlite3_vfs *pVfs, /* Pointer to vfs object */ + const char *zRelative, /* Possibly relative input path */ + int nFull, /* Size of output buffer in bytes */ + char *zFull /* Output buffer */ +){ + char *zRelativeCp = convertUtf8PathToCp( zRelative ); + char zFullCp[CCHMAXPATH] = "\0"; + char *zFullUTF; + APIRET rc = DosQueryPathInfo( (PSZ)zRelativeCp, FIL_QUERYFULLNAME, + zFullCp, CCHMAXPATH ); + free( zRelativeCp ); + zFullUTF = convertCpPathToUtf8( zFullCp ); + sqlite3_snprintf( nFull, zFull, zFullUTF ); + free( zFullUTF ); + return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR; +} + + +/* +** Open a file. +*/ +static int os2Open( + sqlite3_vfs *pVfs, /* Not used */ + const char *zName, /* Name of the file (UTF-8) */ + sqlite3_file *id, /* Write the SQLite file handle here */ + int flags, /* Open mode flags */ + int *pOutFlags /* Status return flags */ +){ + HFILE h; + ULONG ulOpenFlags = 0; + ULONG ulOpenMode = 0; + ULONG ulAction = 0; + ULONG rc; + os2File *pFile = (os2File*)id; + const char *zUtf8Name = zName; + char *zNameCp; + char zTmpname[CCHMAXPATH]; + + int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); + int isCreate = (flags & SQLITE_OPEN_CREATE); + int isReadWrite = (flags & SQLITE_OPEN_READWRITE); +#ifndef NDEBUG + int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE); + int isReadonly = (flags & SQLITE_OPEN_READONLY); + int eType = (flags & 0xFFFFFF00); + int isOpenJournal = (isCreate && ( + eType==SQLITE_OPEN_MASTER_JOURNAL + || eType==SQLITE_OPEN_MAIN_JOURNAL + || eType==SQLITE_OPEN_WAL + )); +#endif + + UNUSED_PARAMETER(pVfs); + assert( id!=0 ); + + /* Check the following statements are true: + ** + ** (a) Exactly one of the READWRITE and READONLY flags must be set, and + ** (b) if CREATE is set, then READWRITE must also be set, and + ** (c) if EXCLUSIVE is set, then CREATE must also be set. + ** (d) if DELETEONCLOSE is set, then CREATE must also be set. + */ + assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly)); + assert(isCreate==0 || isReadWrite); + assert(isExclusive==0 || isCreate); + assert(isDelete==0 || isCreate); + + /* The main DB, main journal, WAL file and master journal are never + ** automatically deleted. Nor are they ever temporary files. */ + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL ); + + /* Assert that the upper layer has set one of the "file-type" flags. */ + assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB + || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL + || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL + || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL + ); + + memset( pFile, 0, sizeof(*pFile) ); + pFile->h = (HFILE)-1; + + /* If the second argument to this function is NULL, generate a + ** temporary file name to use + */ + if( !zUtf8Name ){ + assert(isDelete && !isOpenJournal); + rc = getTempname(CCHMAXPATH, zTmpname); + if( rc!=SQLITE_OK ){ + return rc; + } + zUtf8Name = zTmpname; + } + + if( isReadWrite ){ + ulOpenMode |= OPEN_ACCESS_READWRITE; + }else{ + ulOpenMode |= OPEN_ACCESS_READONLY; + } + + /* Open in random access mode for possibly better speed. Allow full + ** sharing because file locks will provide exclusive access when needed. + ** The handle should not be inherited by child processes and we don't + ** want popups from the critical error handler. + */ + ulOpenMode |= OPEN_FLAGS_RANDOM | OPEN_SHARE_DENYNONE | + OPEN_FLAGS_NOINHERIT | OPEN_FLAGS_FAIL_ON_ERROR; + + /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is + ** created. SQLite doesn't use it to indicate "exclusive access" + ** as it is usually understood. + */ + if( isExclusive ){ + /* Creates a new file, only if it does not already exist. */ + /* If the file exists, it fails. */ + ulOpenFlags |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_FAIL_IF_EXISTS; + }else if( isCreate ){ + /* Open existing file, or create if it doesn't exist */ + ulOpenFlags |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS; + }else{ + /* Opens a file, only if it exists. */ + ulOpenFlags |= OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS; + } + + zNameCp = convertUtf8PathToCp( zUtf8Name ); + rc = DosOpen( (PSZ)zNameCp, + &h, + &ulAction, + 0L, + FILE_NORMAL, + ulOpenFlags, + ulOpenMode, + (PEAOP2)NULL ); + free( zNameCp ); + + if( rc != NO_ERROR ){ + OSTRACE(( "OPEN Invalid handle rc=%d: zName=%s, ulAction=%#lx, ulFlags=%#lx, ulMode=%#lx\n", + rc, zUtf8Name, ulAction, ulOpenFlags, ulOpenMode )); + + if( isReadWrite ){ + return os2Open( pVfs, zName, id, + ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), + pOutFlags ); + }else{ + return SQLITE_CANTOPEN; + } + } + + if( pOutFlags ){ + *pOutFlags = isReadWrite ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY; + } + + os2FullPathname( pVfs, zUtf8Name, sizeof( zTmpname ), zTmpname ); + pFile->zFullPathCp = convertUtf8PathToCp( zTmpname ); + pFile->pMethod = &os2IoMethod; + pFile->flags = flags; + pFile->h = h; + + OpenCounter(+1); + OSTRACE(( "OPEN %d pOutFlags=%d\n", pFile->h, pOutFlags )); + return SQLITE_OK; +} + +/* +** Delete the named file. +*/ +static int os2Delete( + sqlite3_vfs *pVfs, /* Not used on os2 */ + const char *zFilename, /* Name of file to delete */ + int syncDir /* Not used on os2 */ +){ + APIRET rc; + char *zFilenameCp; + SimulateIOError( return SQLITE_IOERR_DELETE ); + zFilenameCp = convertUtf8PathToCp( zFilename ); + rc = DosDelete( (PSZ)zFilenameCp ); + free( zFilenameCp ); + OSTRACE(( "DELETE \"%s\"\n", zFilename )); + return (rc == NO_ERROR || + rc == ERROR_FILE_NOT_FOUND || + rc == ERROR_PATH_NOT_FOUND ) ? SQLITE_OK : SQLITE_IOERR_DELETE; +} + +/* +** Check the existance and status of a file. +*/ +static int os2Access( + sqlite3_vfs *pVfs, /* Not used on os2 */ + const char *zFilename, /* Name of file to check */ + int flags, /* Type of test to make on this file */ + int *pOut /* Write results here */ +){ + APIRET rc; + FILESTATUS3 fsts3ConfigInfo; + char *zFilenameCp; + + UNUSED_PARAMETER(pVfs); + SimulateIOError( return SQLITE_IOERR_ACCESS; ); + + zFilenameCp = convertUtf8PathToCp( zFilename ); + rc = DosQueryPathInfo( (PSZ)zFilenameCp, FIL_STANDARD, + &fsts3ConfigInfo, sizeof(FILESTATUS3) ); + free( zFilenameCp ); + OSTRACE(( "ACCESS fsts3ConfigInfo.attrFile=%d flags=%d rc=%d\n", + fsts3ConfigInfo.attrFile, flags, rc )); + + switch( flags ){ + case SQLITE_ACCESS_EXISTS: + /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file + ** as if it does not exist. + */ + if( fsts3ConfigInfo.cbFile == 0 ) + rc = ERROR_FILE_NOT_FOUND; + break; + case SQLITE_ACCESS_READ: + break; + case SQLITE_ACCESS_READWRITE: + if( fsts3ConfigInfo.attrFile & FILE_READONLY ) + rc = ERROR_ACCESS_DENIED; + break; + default: + rc = ERROR_FILE_NOT_FOUND; + assert( !"Invalid flags argument" ); + } + + *pOut = (rc == NO_ERROR); + OSTRACE(( "ACCESS %s flags %d: rc=%d\n", zFilename, flags, *pOut )); + + return SQLITE_OK; +} + + +#ifndef SQLITE_OMIT_LOAD_EXTENSION +/* +** Interfaces for opening a shared library, finding entry points +** within the shared library, and closing the shared library. +*/ +/* +** Interfaces for opening a shared library, finding entry points +** within the shared library, and closing the shared library. +*/ +static void *os2DlOpen(sqlite3_vfs *pVfs, const char *zFilename){ + HMODULE hmod; + APIRET rc; + char *zFilenameCp = convertUtf8PathToCp(zFilename); + rc = DosLoadModule(NULL, 0, (PSZ)zFilenameCp, &hmod); + free(zFilenameCp); + return rc != NO_ERROR ? 0 : (void*)hmod; +} +/* +** A no-op since the error code is returned on the DosLoadModule call. +** os2Dlopen returns zero if DosLoadModule is not successful. +*/ +static void os2DlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ +/* no-op */ +} +static void (*os2DlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){ + PFN pfn; + APIRET rc; + rc = DosQueryProcAddr((HMODULE)pHandle, 0L, (PSZ)zSymbol, &pfn); + if( rc != NO_ERROR ){ + /* if the symbol itself was not found, search again for the same + * symbol with an extra underscore, that might be needed depending + * on the calling convention */ + char _zSymbol[256] = "_"; + strncat(_zSymbol, zSymbol, 254); + rc = DosQueryProcAddr((HMODULE)pHandle, 0L, (PSZ)_zSymbol, &pfn); + } + return rc != NO_ERROR ? 0 : (void(*)(void))pfn; +} +static void os2DlClose(sqlite3_vfs *pVfs, void *pHandle){ + DosFreeModule((HMODULE)pHandle); +} +#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */ + #define os2DlOpen 0 + #define os2DlError 0 + #define os2DlSym 0 + #define os2DlClose 0 +#endif + + +/* +** Write up to nBuf bytes of randomness into zBuf. +*/ +static int os2Randomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf ){ + int n = 0; +#if defined(SQLITE_TEST) + n = nBuf; + memset(zBuf, 0, nBuf); +#else + int i; + PPIB ppib; + PTIB ptib; + DATETIME dt; + static unsigned c = 0; + /* Ordered by variation probability */ + static ULONG svIdx[6] = { QSV_MS_COUNT, QSV_TIME_LOW, + QSV_MAXPRMEM, QSV_MAXSHMEM, + QSV_TOTAVAILMEM, QSV_TOTRESMEM }; + + /* 8 bytes; timezone and weekday don't increase the randomness much */ + if( (int)sizeof(dt)-3 <= nBuf - n ){ + c += 0x0100; + DosGetDateTime(&dt); + dt.year = (USHORT)((dt.year - 1900) | c); + memcpy(&zBuf[n], &dt, sizeof(dt)-3); + n += sizeof(dt)-3; + } + + /* 4 bytes; PIDs and TIDs are 16 bit internally, so combine them */ + if( (int)sizeof(ULONG) <= nBuf - n ){ + DosGetInfoBlocks(&ptib, &ppib); + *(PULONG)&zBuf[n] = MAKELONG(ppib->pib_ulpid, + ptib->tib_ptib2->tib2_ultid); + n += sizeof(ULONG); + } + + /* Up to 6 * 4 bytes; variables depend on the system state */ + for( i = 0; i < 6 && (int)sizeof(ULONG) <= nBuf - n; i++ ){ + DosQuerySysInfo(svIdx[i], svIdx[i], + (PULONG)&zBuf[n], sizeof(ULONG)); + n += sizeof(ULONG); + } +#endif + + return n; +} + +/* +** Sleep for a little while. Return the amount of time slept. +** The argument is the number of microseconds we want to sleep. +** The return value is the number of microseconds of sleep actually +** requested from the underlying operating system, a number which +** might be greater than or equal to the argument, but not less +** than the argument. +*/ +static int os2Sleep( sqlite3_vfs *pVfs, int microsec ){ + DosSleep( (microsec/1000) ); + return microsec; +} + +/* +** The following variable, if set to a non-zero value, becomes the result +** returned from sqlite3OsCurrentTime(). This is used for testing. +*/ +#ifdef SQLITE_TEST +int sqlite3_current_time = 0; +#endif + +/* +** Find the current time (in Universal Coordinated Time). Write into *piNow +** the current time and date as a Julian Day number times 86_400_000. In +** other words, write into *piNow the number of milliseconds since the Julian +** epoch of noon in Greenwich on November 24, 4714 B.C according to the +** proleptic Gregorian calendar. +** +** On success, return 0. Return 1 if the time and date cannot be found. +*/ +static int os2CurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){ +#ifdef SQLITE_TEST + static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000; +#endif + int year, month, datepart, timepart; + + DATETIME dt; + DosGetDateTime( &dt ); + + year = dt.year; + month = dt.month; + + /* Calculations from http://www.astro.keele.ac.uk/~rno/Astronomy/hjd.html + ** http://www.astro.keele.ac.uk/~rno/Astronomy/hjd-0.1.c + ** Calculate the Julian days + */ + datepart = (int)dt.day - 32076 + + 1461*(year + 4800 + (month - 14)/12)/4 + + 367*(month - 2 - (month - 14)/12*12)/12 - + 3*((year + 4900 + (month - 14)/12)/100)/4; + + /* Time in milliseconds, hours to noon added */ + timepart = 12*3600*1000 + dt.hundredths*10 + dt.seconds*1000 + + ((int)dt.minutes + dt.timezone)*60*1000 + dt.hours*3600*1000; + + *piNow = (sqlite3_int64)datepart*86400*1000 + timepart; + +#ifdef SQLITE_TEST + if( sqlite3_current_time ){ + *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch; + } +#endif + + UNUSED_PARAMETER(pVfs); + return 0; +} + +/* +** Find the current time (in Universal Coordinated Time). Write the +** current time and date as a Julian Day number into *prNow and +** return 0. Return 1 if the time and date cannot be found. +*/ +static int os2CurrentTime( sqlite3_vfs *pVfs, double *prNow ){ + int rc; + sqlite3_int64 i; + rc = os2CurrentTimeInt64(pVfs, &i); + if( !rc ){ + *prNow = i/86400000.0; + } + return rc; +} + +/* +** The idea is that this function works like a combination of +** GetLastError() and FormatMessage() on windows (or errno and +** strerror_r() on unix). After an error is returned by an OS +** function, SQLite calls this function with zBuf pointing to +** a buffer of nBuf bytes. The OS layer should populate the +** buffer with a nul-terminated UTF-8 encoded error message +** describing the last IO error to have occurred within the calling +** thread. +** +** If the error message is too large for the supplied buffer, +** it should be truncated. The return value of xGetLastError +** is zero if the error message fits in the buffer, or non-zero +** otherwise (if the message was truncated). If non-zero is returned, +** then it is not necessary to include the nul-terminator character +** in the output buffer. +** +** Not supplying an error message will have no adverse effect +** on SQLite. It is fine to have an implementation that never +** returns an error message: +** +** int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ +** assert(zBuf[0]=='\0'); +** return 0; +** } +** +** However if an error message is supplied, it will be incorporated +** by sqlite into the error message available to the user using +** sqlite3_errmsg(), possibly making IO errors easier to debug. +*/ +static int os2GetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ + assert(zBuf[0]=='\0'); + return 0; +} + +/* +** Initialize and deinitialize the operating system interface. +*/ +int sqlite3_os_init(void){ + static sqlite3_vfs os2Vfs = { + 3, /* iVersion */ + sizeof(os2File), /* szOsFile */ + CCHMAXPATH, /* mxPathname */ + 0, /* pNext */ + "os2", /* zName */ + 0, /* pAppData */ + + os2Open, /* xOpen */ + os2Delete, /* xDelete */ + os2Access, /* xAccess */ + os2FullPathname, /* xFullPathname */ + os2DlOpen, /* xDlOpen */ + os2DlError, /* xDlError */ + os2DlSym, /* xDlSym */ + os2DlClose, /* xDlClose */ + os2Randomness, /* xRandomness */ + os2Sleep, /* xSleep */ + os2CurrentTime, /* xCurrentTime */ + os2GetLastError, /* xGetLastError */ + os2CurrentTimeInt64, /* xCurrentTimeInt64 */ + 0, /* xSetSystemCall */ + 0, /* xGetSystemCall */ + 0 /* xNextSystemCall */ + }; + sqlite3_vfs_register(&os2Vfs, 1); + initUconvObjects(); +/* sqlite3OSTrace = 1; */ + return SQLITE_OK; +} +int sqlite3_os_end(void){ + freeUconvObjects(); + return SQLITE_OK; +} + +#endif /* SQLITE_OS_OS2 */ diff --git a/scalos/libraries/sqlite/src/os_other.c b/scalos/libraries/sqlite/src/os_other.c new file mode 100644 index 000000000..1f2f645d1 --- /dev/null +++ b/scalos/libraries/sqlite/src/os_other.c @@ -0,0 +1,2367 @@ +/* +** $Date$ +** $Revision$ +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains code that is specific to windows. +*/ + +#if SQLITE_OS_OTHER /* This file is used for AmigaDOS only */ + +#include +#include + +#include +#include +#include +#include +#ifdef __amigaos4__ +#define Flush(f) FFlush(f) +#endif /* __amigaos4__ */ +#include + +#undef GLOBAL + +#include "os_other.h" +#include "sqliteInt.h" +#include "os.h" + +//#define SQLITE_DEBUG + +#include "sqlite3_base.h" +#include "LibSQLite3.h" + +#if defined(SQLITE_DEBUG) +#undef d2 +#define d2(x) x +#endif /* SQLITE_DEBUG */ + +//#undef d2 +//#define d2(x) x + +//--------------------------------------------------------------------- + +/* +** Include code that is common to all os_*.c files +*/ +#include "os_common.h" + +//--------------------------------------------------------------------- + +struct LockKey + { + LONG lk_LockCount; + struct SignalSemaphore lk_Sema; + }; + +struct LockInfo + { + struct Node li_Node; + + LONG li_UseCount; + ULONG li_Hash; + + struct LockKey li_Shared; + struct LockKey li_Pending; + struct LockKey li_Reserved; + }; + +//--------------------------------------------------------------------- + +/* +** The otherFile structure is a subclass of sqlite3_file specific to the win32 +** portability layer. +** This is the definition for AmigaOS +*/ +#ifndef SQLITE_OMIT_WAL +typedef struct otherInodeInfo otherInodeInfo; +typedef struct otherShmNode otherShmNode; +typedef struct otherShm otherShm; +#endif // SQLITE_OMIT_WAL + +typedef struct otherFile otherFile; +struct otherFile +{ + sqlite3_io_methods const *pMethod; /* Must be first */ + BPTR h; /* Handle for accessing the file */ + unsigned char locktype; /* Type of lock currently held on this file */ + BOOL DeleteOnClose; + BOOL ReadOnly; + + LONG lastErrno; + + ULONG FileNameHash; + +#ifndef SQLITE_OMIT_WAL + otherShmNode *pShmNode; + otherShm *pShm; /* Shared memory segment information */ +#endif // SQLITE_OMIT_WAL + +#ifndef NDEBUG + /* The next group of variables are used to track whether or not the + ** transaction counter in bytes 24-27 of database files are updated + ** whenever any part of the database changes. An assertion fault will + ** occur if a file is updated without also updating the transaction + ** counter. This test is made to avoid new problems similar to the + ** one described by ticket #3584. + */ + unsigned char transCntrChng; /* True if the transaction counter changed */ + unsigned char dbUpdate; /* True if any part of database file changed */ + unsigned char inNormalWrite; /* True if in a normal write operation */ +#endif +#ifdef SQLITE_TEST + /* In test mode, increase the size of this structure a bit so that + ** it is larger than the struct CrashFile defined in test6.c. + */ + char aPadding[32]; +#endif +}; +//--------------------------------------------------------------------- + +/* +** Do not include any of the File I/O interface procedures if the +** SQLITE_OMIT_DISKIO macro is defined (indicating that there database +** will be in-memory only) +*/ +#ifndef SQLITE_OMIT_DISKIO + +/* +** Macros used to determine whether or not to use threads. +*/ +#if defined(THREADSAFE) && THREADSAFE +# define SQLITE_OTHER_THREADS 1 +#endif +#define SHM_LOCK_MASK(ofst,n) (1<<((ofst)-OTHER_SHM_BASE+(n)) ) - (1<<((ofst)-OTHER_SHM_BASE) ); + +//--------------------------------------------------------------------- + +extern sqlite3_mutex_methods *sqlite3OtherMutex(void); + +//--------------------------------------------------------------------- + +static void otherEnterMutex(void); +static void otherLeaveMutex(void); +static int otherCheckWriteable(const char *zFilename); +static int otherDelete(sqlite3_vfs *pVfs, const char *zFilename, int syncDir); +static int otherAccess(sqlite3_vfs *pVfs, const char *zFilename, int flags, int *pResOut); +static int otherOpen(sqlite3_vfs *pVfs, const char *zName, sqlite3_file *id, int flags, int *pOutFlags); +static int otherTempFileName(sqlite3_vfs *pVfs, int nBuf, char *zBuf); +static int otherClose(sqlite3_file *pId); +static int otherRead(sqlite3_file *id, void *pBuf, int amt, sqlite3_int64 offset); +static int otherWrite(sqlite3_file *id, const void *pBuf, int amt, sqlite3_int64 offset); +static int otherSeek(sqlite3_file *id, sqlite3_int64 offset); +static int otherSync(sqlite3_file *id, int dataOnly); +static int otherTruncate(sqlite3_file *id, sqlite3_int64 nByte); +static int otherFileSize(sqlite3_file *id, sqlite3_int64 *pSize); +static int otherDeviceCharacteristics(sqlite3_file *id); + +#ifndef SQLITE_OMIT_WAL +static int otherShmSystemLock(otherShmNode *pShmNode, int lockType, int ofst, int n); +static void otherShmPurge(otherFile *pFd); +static int otherOpenSharedMemory(otherFile *pDbFd); +static int otherShmMap(sqlite3_file *fd, int iRegion, int szRegion, int bExtend, void volatile **pp); +static int otherShmLock(sqlite3_file *fd, int ofst, int n, int flags); +static void otherShmBarrier(sqlite3_file *fd); +static int otherShmUnmap(sqlite3_file *fd, int deleteFlag); +#endif // SQLITE_OMIT_WAL + +#if defined(SQLITE_DEBUG) +static const char *locktypeName(int locktype); +#endif /* SQLITE_DEBUG */ +static int otherLock(sqlite3_file *id, int locktype); +static int otherCheckReservedLock(sqlite3_file *id, int *pResOut); +static int otherUnlock(sqlite3_file *id, int locktype); + +static int otherFullPathname(sqlite3_vfs *pVfs, const char *zRelative, int nFull, char *zFull); +static void *otherDlOpen(sqlite3_vfs *pVfs, const char *zFilename); +static void otherDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut); +static void otherDlClose(sqlite3_vfs *pVfs, void *pHandle); +static int otherRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf); +static int otherSleep(sqlite3_vfs *pVfs, int microsec); +static int otherCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow); +static int otherCurrentTime(sqlite3_vfs *pVfs, double *prNow); + +static __inline__ ULONG hashadd(ULONG h, UBYTE c); +static ULONG hash_nocase(CONST_STRPTR s); +static BOOL NewLockInfo(otherFile *id, const char *zFilename); +static void DisposeLockInfo(otherFile *id); +static struct LockInfo *FindLockInfo(ULONG Hash); +static struct LockInfo *FindLockInfoProtected(ULONG Hash); +static int otherFileControl(sqlite3_file *id, int op, void *pArg); +static int otherSectorSize(sqlite3_file *id); +static int allocateOtherFile(otherFile *pNew, const char *zFilename); +static void InitOtherKey(struct LockKey *lk); +static LONG AttemptLockOtherKey(struct LockKey *lk); +static LONG AttemptLockOtherKeyShared(struct LockKey *lk); +static void UnlockOtherKey(struct LockKey *lk); +static int otherGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf); + +//--------------------------------------------------------------------- + +static struct List LockInfoList; +static struct SignalSemaphore LockInfoListSema; +static BOOL LockInfoInit = FALSE; + +//--------------------------------------------------------------------- + +/* +** Helper functions to obtain and relinquish the global mutex. +*/ +static void otherEnterMutex(void) +{ + sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); +} + +static void otherLeaveMutex(void) +{ + sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); +} + +//--------------------------------------------------------------------- + +static int otherCheckWriteable(const char *zFilename) +{ + int isWriteable = 0; + BPTR fLock; + struct FileInfoBlock *fib = NULL; + struct InfoData *id = NULL; + + d1(KPrintF(__FILE__ "/%s/%ld: zFilename=<%s>\n", __FUNC__, __LINE__, zFilename)); + + do { + fLock = Lock(zFilename, ACCESS_READ); + d1(KPrintF(__FILE__ "/%s/%ld: fLock=%08lx\n", __FUNC__, __LINE__, fLock)); + if (0 == fLock) + break; + + id = sqlite3_malloc(sizeof(struct InfoData)); + d1(KPrintF(__FILE__ "/%s/%ld: id=%08lx\n", __FUNC__, __LINE__, id)); + if (NULL == id) + break; + + fib = AllocDosObject(DOS_FIB, NULL); + d1(KPrintF(__FILE__ "/%s/%ld: fib=%08lx\n", __FUNC__, __LINE__, fib)); + if (NULL == fib) + break; + + if (!Examine(fLock, fib)) + break; + + d1(KPrintF(__FILE__ "/%s/%ld: Examine() succeeded, fib_Protection=%08lx\n", __FUNC__, __LINE__, fib->fib_Protection)); + + if (fib->fib_Protection & FIBF_OTR_WRITE) + break; // read-only! + + // Object seems writebale, but might be on read-only disk + if (!Info(fLock, id)) + break; + + d1(KPrintF(__FILE__ "/%s/%ld: Info() succeeded, id_DiskState=%ld\n", __FUNC__, __LINE__, id->id_DiskState)); + + if (ID_VALIDATED != id->id_DiskState) + break; // not validated or read-only + + isWriteable = 1; + } while (0); + + if (fib) + FreeDosObject(DOS_FIB, fib); + if (id) + sqlite3_free(id); + if (fLock) + UnLock(fLock); + + d1(KPrintF(__FILE__ "/%s/%ld: isWriteable=%ld\n", __FUNC__, __LINE__, isWriteable)); + + return isWriteable; +} + +//--------------------------------------------------------------------- + +/* +** Delete the named file +*/ +static int otherDelete(sqlite3_vfs *pVfs, const char *zFilename, int syncDir) +{ + (void) syncDir; + + d1(KPrintF(__FILE__ "/%s/%ld: zFilename=<%s> syncDir=%ld\n", __FUNC__, __LINE__, zFilename, syncDir)); + DeleteFile(zFilename); + return SQLITE_OK; +} + +/* +** Test the existance of or access permissions of file zPath. The +** test performed depends on the value of flags: +** +** SQLITE_ACCESS_EXISTS: Return 1 if the file exists +** SQLITE_ACCESS_READWRITE: Return 1 if the file is read and writable. +** SQLITE_ACCESS_READONLY: Return 1 if the file is readable. +** +** Otherwise return 0. +*/ +static int otherAccess(sqlite3_vfs *pVfs, const char *zFilename, int flags, int *pResOut) +{ + BPTR fLock = NULL; + int exists = 0; + + d1(KPrintF(__FILE__ "/%s/%ld: zFilename=<%s> flags=%08lx\n", __FUNC__, __LINE__, zFilename, flags)); + + switch( flags ) + { + case SQLITE_ACCESS_READ: + case SQLITE_ACCESS_EXISTS: + fLock = Lock(zFilename, ACCESS_READ); + break; + case SQLITE_ACCESS_READWRITE: + exists = otherCheckWriteable(zFilename); + break; + default: + assert(!"Invalid flags argument"); + break; + } + + if (fLock) + { + exists = 1; + UnLock(fLock); + } + else + { + d1(KPrintF(__FILE__ "/%s/%ld: Lock(9 failed, IoErr=%ld\n", __FUNC__, __LINE__, IoErr())); + } + + d1(KPrintF(__FILE__ "/%s/%ld: exists=%ld\n", __FUNC__, __LINE__, exists)); + + *pResOut = exists; + + return SQLITE_OK; +} + +/* +** Open the file zPath. +** +** Previously, the SQLite OS layer used three functions in place of this +** one: +** +** sqlite3OsOpenReadWrite(); +** sqlite3OsOpenReadOnly(); +** sqlite3OsOpenExclusive(); +** +** These calls correspond to the following combinations of flags: +** +** ReadWrite() -> (READWRITE | CREATE) +** ReadOnly() -> (READONLY) +** OpenExclusive() -> (READWRITE | CREATE | EXCLUSIVE) +** +** The old OpenExclusive() accepted a boolean argument - "delFlag". If +** true, the file was configured to be automatically deleted when the +** file handle closed. To achieve the same effect using this new +** interface, add the DELETEONCLOSE flag to those specified above for +** OpenExclusive(). +*/ +static int otherOpen(sqlite3_vfs *pVfs, const char *zPath, sqlite3_file *id, int flags, int *pOutFlags) +{ + otherFile *pFile = (otherFile*) id; + int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); + int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE); + int isCreate = (flags & SQLITE_OPEN_CREATE); + int isReadonly = (flags & SQLITE_OPEN_READONLY); + int isReadWrite = (flags & SQLITE_OPEN_READWRITE); + char zTmpname[SQLITE_TEMPNAME_SIZE]; + const char *zName = zPath; + + d1(KPrintF(__FILE__ "/%s/%ld: zPath=<%s> flags=%08lx\n", __FUNC__, __LINE__, zPath, flags)); + + /* If argument zPath is a NULL pointer, this function is required to open + ** a temporary file. Use this buffer to store the file name in. + */ + + /* Check the following statements are true: + ** + ** (a) Exactly one of the READWRITE and READONLY flags must be set, and + ** (b) if CREATE is set, then READWRITE must also be set, and + ** (c) if EXCLUSIVE is set, then CREATE must also be set. + ** (d) if DELETEONCLOSE is set, then CREATE must also be set. + */ + assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly)); + assert(isCreate==0 || isReadWrite); + assert(isExclusive==0 || isCreate); + assert(isDelete==0 || isCreate); + + + /* The main DB, main journal, and master journal are never automatically + ** deleted + */ + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL ); + + /* Assert that the upper layer has set one of the "file-type" flags. */ + assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB + || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL + || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL + || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL + ); + + (void) isExclusive; + (void) isCreate; + + memset(pFile, 0, sizeof(otherFile)); + + if ( !zName ) + { + /* If zName is NULL, the upper layer is requesting a temp file. */ + int rc; + + assert(isDelete && !isOpenDirectory); + rc = otherTempFileName(pVfs, sizeof(zTmpname), zTmpname); + if ( rc != SQLITE_OK ) + { + return rc; + } + zName = zTmpname; + } + + if (isReadonly) + pFile->h = Open(zName, MODE_OLDFILE); + if (isReadWrite) + pFile->h = Open(zName, MODE_READWRITE); + + d1(KPrintF(__FILE__ "/%s/%ld: h=%08lx\n", __FUNC__, __LINE__, pFile->h)); + + pFile->ReadOnly = isReadonly; + pFile->DeleteOnClose = isDelete; + + if (0 == pFile->h) + { + if (isReadWrite) + { + return otherOpen(NULL, zName, id, + ((flags|SQLITE_OPEN_READONLY)&~SQLITE_OPEN_READWRITE), + pOutFlags); + } + else + { + return SQLITE_CANTOPEN; + } + } + + if ( pOutFlags ) + { + if ( flags & SQLITE_OPEN_READWRITE ) + { + *pOutFlags = SQLITE_OPEN_READWRITE; + } + else + { + *pOutFlags = SQLITE_OPEN_READONLY; + } + d1(KPrintF(__FILE__ "/%s/%ld: *pOutFlags=%08lx\n", __FUNC__, __LINE__, *pOutFlags)); + } + + d1(KPrintF(__FILE__ "/%s/%ld: id=%08lx h=%08lx\n", __FUNC__, __LINE__, id, pFile->h)); + + return allocateOtherFile(pFile, zName); +} + +/* +** Create a temporary file name in zBuf. +*/ +static int otherTempFileName(sqlite3_vfs *pVfs, int nBuf, char *zBuf) +{ + static const char zChars[] = + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789"; + int i, j; + char zTempPath[SQLITE_TEMPNAME_SIZE]; + int exists = 0; + + if (sqlite3_temp_directory ) + { + strncpy(zTempPath, sqlite3_temp_directory, SQLITE_TEMPNAME_SIZE-30); + zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0; + + for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='/'; i--) + { + } + zTempPath[i] = 0; + } + else + { + memset(zTempPath, 0, sizeof(zTempPath)); + } + + do { + sqlite3_snprintf(nBuf, zBuf, "%s%s", STR(TEMP_FILE_PREFIX), zTempPath); + + j = strlen(zBuf); + sqlite3_randomness(15, &zBuf[j]); + for(i=0; i<15; i++, j++) + { + zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; + } + zBuf[j] = 0; + sqlite3OsAccess(pVfs, zBuf, SQLITE_ACCESS_EXISTS, &exists); + } while (exists); + + d1(KPrintF(__FILE__ "/%s/%ld: zBuf=<%s>\n", __FUNC__, __LINE__, zBuf)); + return SQLITE_OK; +} + +/* +** Close a file. +*/ +static int otherClose(sqlite3_file *pId) +{ + STRPTR Buffer = NULL; + otherFile *pFile = NULL; + + do { + d1(KPrintF(__FILE__ "/%s/%ld: pId=%08lx\n", __FUNC__, __LINE__, pId)); + + if (NULL == pId) + break; + + pFile = (otherFile *) pId; + if (NULL == pFile) + break; + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + + if (NULL == pFile->h) + break; + + do { + // try to delete files that have been opened with "delFlag" set + const LONG MaxLen = 1024; + + if (!pFile->DeleteOnClose) + break; + + Buffer = sqlite3_malloc(MaxLen); + if (NULL == Buffer) + break;; + + if (!NameFromFH(pFile->h, Buffer, MaxLen)) + break; + + // close file before trying to delete it! + if ( !Close(pFile->h) ) + pFile->lastErrno = IoErr(); + + pFile->h = 0; + + DeleteFile(Buffer); + } while (0); + + if (pFile->h) + { + if ( !Close(pFile->h) ) + pFile->lastErrno = IoErr(); + pFile->h = 0; + } + + OpenCounter(-1); + } while (0); + + if (Buffer) + { + d1(KPrintF(__FILE__ "/%s/%ld: Buffer=%08lx\n", __FUNC__, __LINE__, Buffer)); + sqlite3_free(Buffer); + } + if (pFile) + DisposeLockInfo(pFile); + + return SQLITE_OK; +} + +/* +** Read data from a file into a buffer. Return SQLITE_OK if all +** bytes were read successfully and SQLITE_IOERR if anything goes +** wrong. +*/ +static int otherRead(sqlite3_file *id, void *pBuf, int amt, sqlite3_int64 offset) +{ + otherFile *pFile = (otherFile *) id; + LONG got; + int rc; + + d1(KPrintF(__FILE__ "/%s/%ld: amt=%ld\n", __FUNC__, __LINE__, amt)); + SimulateIOError(SQLITE_IOERR); + + rc = otherSeek(id, offset); + if (SQLITE_OK != rc) + { + d1(KPrintF(__FILE__ "/%s/%ld: Read seek error=%ld\n", __FUNC__, __LINE__, rc)); + return rc; + } + + got = FRead(pFile->h, pBuf, 1, amt); + d1(KPrintF(__FILE__ "/%s/%ld: got=%ld\n", __FUNC__, __LINE__, got)); + if (got == amt ) + return SQLITE_OK; + else if (got < 0) + { + pFile->lastErrno = IoErr(); + return SQLITE_IOERR; + } + else + { + d1(KPrintF(__FILE__ "/%s/%ld: SQLITE_IOERR_SHORT_READ\n", __FUNC__, __LINE__)); + pFile->lastErrno = IoErr(); + memset(&((char*)pBuf)[got], 0, amt-got); + return SQLITE_IOERR_SHORT_READ; + } +} + +/* +** Write data from a buffer into a file. Return SQLITE_OK on success +** or some other error code on failure. +*/ +static int otherWrite(sqlite3_file *id, const void *pBuf, int amt, sqlite3_int64 offset) +{ + otherFile *pFile = (otherFile *) id; + LONG wrote; + int rc; + + d1(KPrintF(__FILE__ "/%s/%ld: amt=%ld\n", __FUNC__, __LINE__, amt)); + SimulateIOError(( wrote=(-1), amt=1 )); + SimulateDiskfullError(( wrote=0, amt=1 )); + assert( amt>0 ); + +#ifndef NDEBUG + /* If we are doing a normal write to a database file (as opposed to + ** doing a hot-journal rollback or a write to some file other than a + ** normal database file) then record the fact that the database + ** has changed. If the transaction counter is modified, record that + ** fact too. + */ + if ( pFile->inNormalWrite ) + { + pFile->dbUpdate = 1; /* The database has been modified */ + if ( offset<=24 && offset+amt>=27 ) + { + char oldCntr[4]; + SimulateIOErrorBenign(1); + seekAndRead(pFile, 24, oldCntr, 4); + SimulateIOErrorBenign(0); + if ( memcmp(oldCntr, &((char*)pBuf)[24-offset], 4)!=0 ) + { + pFile->transCntrChng = 1; /* The transaction counter has changed */ + } + } + } +#endif + + rc = otherSeek(id, offset); + if (SQLITE_OK != rc) + { + d1(KPrintF(__FILE__ "/%s/%ld: Write seek error=%ld\n", __FUNC__, __LINE__, rc)); + return rc; + } + + wrote = FWrite(pFile->h, (APTR) pBuf, 1, amt); + d1(KPrintF(__FILE__ "/%s/%ld: wrote=%ld\n", __FUNC__, __LINE__, wrote)); + if (wrote < 0) + { + pFile->lastErrno = IoErr(); + d1(KPrintF(__FILE__ "/%s/%ld: SQLITE_IOERR_WRITE\n", __FUNC__, __LINE__)); + return SQLITE_IOERR_WRITE; + } + else if (wrote != amt) + { + pFile->lastErrno = IoErr(); + d1(KPrintF(__FILE__ "/%s/%ld: SQLITE_FULL\n", __FUNC__, __LINE__)); + return SQLITE_FULL; + } + + return SQLITE_OK; +} + +/* +** Move the read/write pointer in a file. +*/ +static int otherSeek(sqlite3_file *id, sqlite3_int64 offset) +{ + otherFile *pFile = (otherFile *) id; +// LONG upperBits = offset>>32; + LONG lowerBits = offset & 0xffffffff; + LONG rc; + LONG Pos, OldPos; + + d1(KPrintF(__FILE__ "/%s/%ld: offset=%ld\n", __FUNC__, __LINE__, lowerBits)); +#ifdef SQLITE_TEST + if (offset ) + SimulateDiskfullError +#endif + rc = Seek(pFile->h, lowerBits, OFFSET_BEGINNING); + if (rc >= 0) + return SQLITE_OK; + + pFile->lastErrno = IoErr(); + + OldPos = Seek(pFile->h, 0, OFFSET_END); + Pos = Seek(pFile->h, 0, OFFSET_END); + d1(KPrintF(__FILE__ "/%s/%ld: Pos=%ld\n", __FUNC__, __LINE__, Pos)); + if (Pos < lowerBits) + { + rc = SetFileSize(pFile->h, lowerBits, OFFSET_BEGINNING); + if (rc < 0 ) + { + pFile->lastErrno = IoErr(); + d1(KPrintF(__FILE__ "/%s/%ld: rc=%ld IoErr()=%ld\n", __FUNC__, __LINE__, rc, IoErr())); + return SQLITE_FULL; + } + + rc = Seek(pFile->h, lowerBits, OFFSET_BEGINNING); + if (rc < 0 ) + { + pFile->lastErrno = IoErr(); + d1(KPrintF(__FILE__ "/%s/%ld: rc=%ld IoErr()=%ld\n", __FUNC__, __LINE__, rc, IoErr())); + return SQLITE_FULL; + } + return SQLITE_OK; + } + return SQLITE_FULL; +} + +/* +** Make sure all writes to a particular file are committed to disk. +*/ +static int otherSync(sqlite3_file *id, int dataOnly) +{ + otherFile *pFile = (otherFile *) id; + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + if (Flush(pFile->h) ) + return SQLITE_OK; + else + { + pFile->lastErrno = IoErr(); + return SQLITE_IOERR; + } +} + +/* +** Sync the directory zDirname. This is a no-op on operating systems other +** than UNIX. +*/ +int sqlite3OtherSyncDirectory(const char *zDirname) +{ + SimulateIOError(SQLITE_IOERR); + return SQLITE_OK; +} + +/* +** Truncate an open file to a specified size +*/ +static int otherTruncate(sqlite3_file *id, sqlite3_int64 nByte) +{ + otherFile *pFile = (otherFile *) id; +// LONG upperBits = nByte>>32; + LONG lowerBits = nByte & 0xffffffff; + + d1(KPrintF(__FILE__ "/%s/%ld: nByte=%ld\n", __FUNC__, __LINE__, lowerBits)); + SimulateIOError(SQLITE_IOERR); + if (SetFileSize(pFile->h, lowerBits, OFFSET_BEGINNING) < 0) + { + pFile->lastErrno = IoErr(); + } + return SQLITE_OK; +} + +/* +** Determine the current size of a file in bytes +*/ +static int otherFileSize(sqlite3_file *id, sqlite3_int64 *pSize) +{ + otherFile *pFile = (otherFile *) id; + LONG OldPos; + + SimulateIOError(SQLITE_IOERR); + + OldPos = Seek(pFile->h, 0, OFFSET_END); + *pSize = Seek(pFile->h, OldPos, OFFSET_BEGINNING); + + return SQLITE_OK; +} + + +#ifdef SQLITE_DEBUG +/* +** Helper function for printing out trace information from debugging +** binaries. This returns the string represetation of the supplied +** integer lock-type. +*/ +static const char *locktypeName(int locktype) +{ + switch( locktype ) + { + case NO_LOCK: + return "NONE"; + case SHARED_LOCK: + return "SHARED"; + case RESERVED_LOCK: + return "RESERVED"; + case PENDING_LOCK: + return "PENDING"; + case EXCLUSIVE_LOCK: + return "EXCLUSIVE"; + default: + return "ERROR"; + } +} +#endif + + +/* +** Lock the file with the lock specified by parameter locktype - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** SHARED -> (PENDING) -> EXCLUSIVE +** RESERVED -> (PENDING) -> EXCLUSIVE +** PENDING -> EXCLUSIVE +** +** This routine will only increase a lock. The sqlite3OsUnlock() routine +** erases all locks at once and returns us immediately to locking level 0. +** It is not possible to lower the locking level one step at a time. You +** must go straight to locking level 0. +*/ +static int otherLock(sqlite3_file *id, int locktype) +{ + /* The following describes the implementation of the various locks and + ** lock transitions in terms of the POSIX advisory shared and exclusive + ** lock primitives (called read-locks and write-locks below, to avoid + ** confusion with SQLite lock names). The algorithms are complicated + ** slightly in order to be compatible with windows systems simultaneously + ** accessing the same database file, in case that is ever required. + ** + ** To obtain a SHARED lock, a shared lock is obtained on the PendingSema + ** If this is successful, a shared lock on SharedSema is obtained + ** and the lock on the PendingSema released. + ** + ** A process may only obtain a RESERVED lock after it has a SHARED lock. + ** A RESERVED lock is implemented by grabbing an exclusive lock on the + ** ReservedSema. + ** + ** A process may only obtain a PENDING lock after it has obtained a + ** SHARED lock. A PENDING lock is implemented by obtaining an exclusive + ** lock on the PendingSema. This ensures that no new SHARED locks can be + ** obtained, but existing SHARED locks are allowed to persist. A process + ** does not have to obtain a RESERVED lock on the way to a PENDING lock. + ** This property is used by the algorithm for rolling back a journal file + ** after a crash. + ** + ** An EXCLUSIVE lock, obtained after a PENDING lock is held, is + ** implemented by obtaining an exclusive lock on the SharedSema. + ** Since all other locks require a shared lock on one of the SharedSema, + ** this ensures that no other locks are held on the database. + ** + */ + int rc = SQLITE_OK; /* Return code from subroutines */ + BOOL res = TRUE; /* Result of a DOS lock call */ + otherFile *pFile = (otherFile *) id; + struct LockInfo *pLock; + + assert( NULL != pFile ); + + /* If there is already a lock of this type or more restrictive on the + ** sqlite3_file, do nothing. Don't use the end_lock: exit path, as + ** otherEnterMutex() hasn't been called yet. + */ + if (pFile->locktype >= locktype ) + { + return SQLITE_OK; + } + + /* Make sure the locking sequence is correct + */ + assert( NO_LOCK != pFile->locktype || SHARED_LOCK == locktype ); + assert( locktype != PENDING_LOCK ); + assert( locktype != RESERVED_LOCK || SHARED_LOCK == pFile->locktype ); + + pLock = FindLockInfoProtected(pFile->FileNameHash); + d1(KPrintF(__FILE__ "/%s/%ld: pLock=%08lx\n", __FUNC__, __LINE__, pLock)); + if (NULL == pLock) + return SQLITE_IOERR; + + /* This mutex is needed because pFile->pLock is shared across threads + */ + otherEnterMutex(); + + /* A PENDING lock is needed before acquiring a SHARED lock and before + ** acquiring an EXCLUSIVE lock. For the SHARED lock, the PENDING will + ** be released. + */ + if (SHARED_LOCK == locktype + || (EXCLUSIVE_LOCK == locktype && pFile->locktype < PENDING_LOCK)) + { + res = AttemptLockOtherKey(&pLock->li_Pending); + d1(KPrintF(__FILE__ "/%s/%ld: Attempt PendingSema pLock=%08lx res=%ld\n", __FUNC__, __LINE__, pLock, res)); + if ( !res ) + { + rc = SQLITE_BUSY; + goto end_lock; + } + } + + /* If control gets to this point, then actually go ahead and make + ** operating system calls for the specified lock. + */ + if (SHARED_LOCK == locktype) + { + assert( pLock->cnt==0 ); + assert( pLock->locktype==0 ); + + /* Now get the shared lock on SharedSema */ + res = AttemptLockOtherKeyShared(&pLock->li_Shared); + d1(KPrintF(__FILE__ "/%s/%ld: Attempt shared SharedSema pLock=%08lx res=%ld\n", __FUNC__, __LINE__, pLock, res)); + + /* Drop the temporary PENDING lock */ + d1(KPrintF(__FILE__ "/%s/%ld: Release PendingSema pLock=%08lx Count=%ld\n", __FUNC__, __LINE__, pLock, pLock->li_Pending)); + UnlockOtherKey(&pLock->li_Pending); + if (!res ) + { + rc = SQLITE_BUSY; + } + else + { + pFile->locktype = SHARED_LOCK; + } + } + else + { + /* The request was for a RESERVED or EXCLUSIVE lock. It is + ** assumed that there is a SHARED or greater lock on the file + ** already. + */ + assert( NO_LOCK != pFile->locktype ); + + switch( locktype ) + { + case RESERVED_LOCK: + res = AttemptLockOtherKey(&pLock->li_Reserved); + d1(KPrintF(__FILE__ "/%s/%ld: Attempt ReservedSema pLock=%08lx res=%ld\n", __FUNC__, __LINE__, pLock, res)); + break; + case EXCLUSIVE_LOCK: + // Release the current shared lock on SharedSema + // and try to get an exclusive lock + UnlockOtherKey(&pLock->li_Shared); + res = AttemptLockOtherKey(&pLock->li_Shared); + d1(KPrintF(__FILE__ "/%s/%ld: Attempt SharedSema pLock=%08lx res=%ld\n", __FUNC__, __LINE__, pLock, res)); + break; + default: + assert(0); + } + + if (!res ) + { + rc = SQLITE_BUSY; + } + } + +#ifndef NDEBUG + /* Set up the transaction-counter change checking flags when + ** transitioning from a SHARED to a RESERVED lock. The change + ** from SHARED to RESERVED marks the beginning of a normal + ** write operation (not a hot journal rollback). + */ + if ( SQLITE_OK == rc + && pFile->locktype <= SHARED_LOCK + && locktype == RESERVED_LOCK) + { + pFile->transCntrChng = 0; + pFile->dbUpdate = 0; + pFile->inNormalWrite = 1; + } +#endif + + if (SQLITE_OK == rc) + { + pFile->locktype = locktype; + } + else if (EXCLUSIVE_LOCK == locktype) + { + pFile->locktype = PENDING_LOCK; + } + +end_lock: + otherLeaveMutex(); + + return rc; +} + +/* +** This routine checks if there is a RESERVED lock held on the specified +** file by this or any other process. If such a lock is held, return +** non-zero. If the file is unlocked or holds only SHARED locks, then +** return zero. +*/ +static int otherCheckReservedLock(sqlite3_file *id, int *pResOut) +{ + int rc = 0; + otherFile *pFile = (otherFile *) id; + struct LockInfo *pLock; + + assert( NULL != pFile ); + pLock = FindLockInfoProtected(pFile->FileNameHash); + d1(KPrintF(__FILE__ "/%s/%ld: pLock=%08lx\n", __FUNC__, __LINE__, pLock)); + if (NULL == pLock) + return SQLITE_IOERR_CHECKRESERVEDLOCK; + + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + if (pFile->locktype >= RESERVED_LOCK ) + { + rc = 1; + } + else + { + rc = AttemptLockOtherKey(&pLock->li_Reserved); + d1(KPrintF(__FILE__ "/%s/%ld: Attempt ReservedSema pLock=%08lx rc=%ld\n", __FUNC__, __LINE__, pLock, rc)); + if (rc ) + { + d1(KPrintF(__FILE__ "/%s/%ld: Release ReservedSema pLock=%08lx Count=%ld\n", __FUNC__, __LINE__, pLock, pLock->li_Reserved)); + UnlockOtherKey(&pLock->li_Reserved); + } + + rc = !rc; + } + + *pResOut = rc; + + return SQLITE_OK; +} + +/* +** Lower the locking level on file descriptor id to locktype. locktype +** must be either NO_LOCK or SHARED_LOCK. +** +** If the locking level of the file descriptor is already at or below +** the requested locking level, this routine is a no-op. +** +** It is not possible for this routine to fail if the second argument +** is NO_LOCK. If the second argument is SHARED_LOCK then this routine +** might return SQLITE_IOERR; +*/ +static int otherUnlock(sqlite3_file *id, int locktype) +{ + int rc = SQLITE_OK; + struct LockInfo *pLock; + otherFile *pFile = (otherFile *) id; + + assert( NULL != pFile ); + assert( locktype <= SHARED_LOCK ); + + if (pFile->locktype <= locktype ) + { + return SQLITE_OK; + } + + pLock = FindLockInfoProtected(pFile->FileNameHash); + d1(KPrintF(__FILE__ "/%s/%ld: pLock=%08lx\n", __FUNC__, __LINE__, pLock)); + if (NULL == pLock) + return SQLITE_IOERR; + + otherEnterMutex(); + +#ifndef NDEBUG + /* When reducing a lock such that other processes can start + ** reading the database file again, make sure that the + ** transaction counter was updated if any part of the database + ** file changed. If the transaction counter is not updated, + ** other connections to the same file might not realize that + ** the file has changed and hence might not know to flush their + ** cache. The use of a stale cache can lead to database corruption. + */ + assert( pFile->inNormalWrite==0 + || pFile->dbUpdate==0 + || pFile->transCntrChng==1 ); + pFile->inNormalWrite = 0; +#endif + + if (pFile->locktype > SHARED_LOCK ) + { + if (SHARED_LOCK == locktype ) + { + d1(KPrintF(__FILE__ "/%s/%ld: Release SharedSema pLock=%08lx Count=%ld\n", __FUNC__, __LINE__, pLock, pLock->li_Shared)); + // Change exclusive lock on SharedSema to a shared one + UnlockOtherKey(&pLock->li_Shared); + + d1(KPrintF(__FILE__ "/%s/%ld: Obtain SharedSema pLock=%08lx Count=%ld\n", __FUNC__, __LINE__, pLock, pLock->li_Shared)); + if (!AttemptLockOtherKeyShared(&pLock->li_Shared)) + rc = SQLITE_IOERR; /* This should never happen */ + } + d1(KPrintF(__FILE__ "/%s/%ld: Release PendingSema pLock=%08lx Count=%ld\n", __FUNC__, __LINE__, pLock, pLock->li_Pending)); + UnlockOtherKey(&pLock->li_Pending); + d1(KPrintF(__FILE__ "/%s/%ld: Release ReservedSema pLock=%08lx Count=%ld\n", __FUNC__, __LINE__, pLock, pLock->li_Reserved)); + UnlockOtherKey(&pLock->li_Reserved); + } + if (locktype == NO_LOCK ) + { + // Unlock shared lock on SharedSema + d1(KPrintF(__FILE__ "/%s/%ld: Release SharedSema pLock=%08lx Count=%ld\n", __FUNC__, __LINE__, pLock, pLock->li_Shared)); + UnlockOtherKey(&pLock->li_Shared); + } + + otherLeaveMutex(); + pFile->locktype = locktype; + + d1(KPrintF(__FILE__ "/%s/%ld: rc=%ld locktype=%s\n", __FUNC__, __LINE__, rc, locktypeName(pFile->locktype))); + + return rc; +} + +/* +** Turn a relative pathname into a full pathname. The relative path +** is stored as a nul-terminated string in the buffer pointed to by +** zPath. +** +** zOut points to a buffer of at least sqlite3_vfs.mxPathname bytes +** (in this case, MAX_PATHNAME bytes). The full-path is written to +** this buffer before returning. +*/ +static int otherFullPathname(sqlite3_vfs *pVfs, const char *zRelative, int nFull, char *zFull) +{ + BPTR pLock = 0; + BOOL Success = FALSE; + int Result = SQLITE_OK; + + d1(KPrintF(__FILE__ "/%s/%ld: START zRelative=<%s>\n", __FUNC__, __LINE__, zRelative)); + + do { + if (NULL == zFull) + { + Result = SQLITE_NOMEM; + break; + } + + pLock = Lock(zRelative, ACCESS_READ); + if (0 == pLock) + { + sqlite3_snprintf(nFull, zFull, "%s", zRelative); + //Result = SQLITE_CANTOPEN; + break; + } + + if (!NameFromLock(pLock, zFull, nFull)) + { + Result = SQLITE_NOMEM; + break; + } + + Success = TRUE; + } while (0); + + if (pLock) + UnLock(pLock); + if (!Success && zFull) + { + strcpy(zFull, zRelative); + } + + d1(KPrintF(__FILE__ "/%s/%ld: END Result=%ld\n", __FUNC__, __LINE__, Result)); + + return Result; +} + +#endif /* SQLITE_OMIT_DISKIO */ + + +#ifndef SQLITE_OMIT_LOAD_EXTENSION +/* +** Interfaces for opening a shared library, finding entry points +** within the shared library, and closing the shared library. +*/ +static void *otherDlOpen(sqlite3_vfs *pVfs, const char *zFilename) +{ + return 0; +} + + +static void (*otherDlSym(sqlite3_vfs *NotUsed, void *p, const char*zSym))(void) +{ + return 0; +} + +static void otherDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut) +{ +} + +static void otherDlClose(sqlite3_vfs *pVfs, void *pHandle) +{ +} +#endif /* SQLITE_OMIT_LOAD_EXTENSION */ + +/* +** Get information to seed the random number generator. The seed +** is written into the buffer zBuf[256]. The calling function must +** supply a sufficiently large buffer. +*/ +static int otherRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf) +{ + /* We have to initialize zBuf to prevent valgrind from reporting + ** errors. The reports issued by valgrind are incorrect - we would + ** prefer that the randomness be increased by making use of the + ** uninitialized space in zBuf - but valgrind errors tend to worry + ** some users. Rather than argue, it seems easier just to initialize + ** the whole array and silence valgrind, even if that means less randomness + ** in the random seed. + ** + ** When testing, initializing zBuf[] to zero is all we do. That means + ** that we always use the same random number sequence.* This makes the + ** tests repeatable. + */ + T_TIMEVAL tv; + + d1(KPrintF(__FILE__ "/%s/%ld: TimerBase=%08lx\n", __FUNC__, __LINE__, TimerBase)); + memset(zBuf, 0, 256); + GetSysTime(&tv); + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + sqlite3_snprintf(nBuf, zBuf, "%08lx-%08lx", tv.tv_secs, tv.tv_micro); + d1(KPrintF(__FILE__ "/%s/%ld: zBuf=<%s>\n", __FUNC__, __LINE__, zBuf)); + return SQLITE_OK; +} + +/* +** Sleep for a little while. Return the amount of time slept. +*/ +static int otherSleep(sqlite3_vfs *pVfs, int microsec) +{ + (void) pVfs; + + Delay((microsec + 999) / (20 * 1000)); // 50ms per tick + return ((microsec+999)/1000)*1000; +} + +/* +** The following variable, if set to a non-zero value, becomes the result +** returned from sqlite3OsCurrentTime(). This is used for testing. +*/ +#ifdef SQLITE_TEST +int sqlite3_current_time = 0; +#endif + +/* +** Find the current time (in Universal Coordinated Time). Write into *piNow +** the current time and date as a Julian Day number times 86_400_000. In +** other words, write into *piNow the number of milliseconds since the Julian +** epoch of noon in Greenwich on November 24, 4714 B.C according to the +** proleptic Gregorian calendar. +** +** On success, return 0. Return 1 if the time and date cannot be found. +*/ +static int otherCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow) +{ + static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000; + + double now; + T_TIMEVAL tv; + + GetSysTime(&tv); + + now = ((double) tv.tv_secs) * 4294967296.0; + *piNow = (now + tv.tv_micro)/864000000000.0 + 2305813.5 + unixEpoch; + +#ifdef SQLITE_TEST + if (sqlite3_current_time ) + { + *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch; + } +#endif + + UNUSED_PARAMETER(NotUsed); + return 0; +} + +/* +** Find the current time (in Universal Coordinated Time). Write the +** current time and date as a Julian Day number into *prNow and +** return 0. Return 1 if the time and date cannot be found. +*/ +static int otherCurrentTime(sqlite3_vfs *pVfs, double *prNow) +{ + double now; + T_TIMEVAL tv; + + GetSysTime(&tv); + + now = ((double) tv.tv_secs) * 4294967296.0; + *prNow = (now + tv.tv_micro)/864000000000.0 + 2305813.5; +#ifdef SQLITE_TEST + if (sqlite3_current_time ) + { + *prNow = sqlite3_current_time/86400.0 + 2440587.5; + } +#endif + return 0; +} + + +static __inline__ ULONG hashadd(ULONG h, UBYTE c) +{ + h += (h << 5); /* multiply by 33 */ + return (h ^ c); +} + + +// String hashing function (taken from Bernstein's cdb). +static ULONG hash_nocase(CONST_STRPTR s) +{ + ULONG h = 5381; + UBYTE c; + + assert(s); + + while (c = *s++) + { + h = hashadd(h, toupper(c)); + } + + return (h); +} + + +static BOOL NewLockInfo(otherFile *id, const char *zFilename) +{ + struct LockInfo *pLock; + + d1(KPrintF(__FILE__ "/%s/%ld: START id=%08lx zFilename=<%s>\n", __FUNC__, __LINE__, id, zFilename)); + + Forbid(); + if (!LockInfoInit) + { + NewList(&LockInfoList); + InitSemaphore(&LockInfoListSema); + LockInfoInit = TRUE; + } + Permit(); + + id->FileNameHash = hash_nocase(zFilename); + d1(KPrintF(__FILE__ "/%s/%ld: FileNameHash=%08lx\n", __FUNC__, __LINE__, id->FileNameHash)); + + ObtainSemaphore(&LockInfoListSema); + + pLock = FindLockInfo(id->FileNameHash); + d1(KPrintF(__FILE__ "/%s/%ld: pLock=%08lx\n", __FUNC__, __LINE__, pLock)); + + if (pLock) + { + pLock->li_UseCount++; + } + else + { + pLock = sqlite3_malloc(sizeof(struct LockInfo)); + if (NULL == pLock) + { + ReleaseSemaphore(&LockInfoListSema); + return FALSE; + } + + pLock->li_Hash = id->FileNameHash; + pLock->li_UseCount = 1; + + InitOtherKey(&pLock->li_Shared); + InitOtherKey(&pLock->li_Pending); + InitOtherKey(&pLock->li_Reserved); + + AddTail(&LockInfoList, &pLock->li_Node); + } + + ReleaseSemaphore(&LockInfoListSema); + + d1(KPrintF(__FILE__ "/%s/%ld: END pLock=%08lx\n", __FUNC__, __LINE__, pLock)); + + return TRUE; +} + + +static void DisposeLockInfo(otherFile *id) +{ + struct LockInfo *pLock; + + d1(KPrintF(__FILE__ "/%s/%ld: START\n", __FUNC__, __LINE__)); + + ObtainSemaphore(&LockInfoListSema); + + pLock = FindLockInfo(id->FileNameHash); + d1(KPrintF(__FILE__ "/%s/%ld: pLock=%08lx\n", __FUNC__, __LINE__, pLock)); + if (pLock) + { + d1(KPrintF(__FILE__ "/%s/%ld: li_UseCount=%ld\n", __FUNC__, __LINE__, pLock->li_UseCount)); + + if (0 == --pLock->li_UseCount) + { + Remove(&pLock->li_Node); + d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__)); + sqlite3_free(pLock); + } + } + + ReleaseSemaphore(&LockInfoListSema); + + d1(KPrintF(__FILE__ "/%s/%ld: END\n", __FUNC__, __LINE__)); +} + + +static struct LockInfo *FindLockInfo(ULONG Hash) +{ + struct LockInfo *pLock; + + for (pLock = (struct LockInfo *) LockInfoList.lh_Head; + pLock != (struct LockInfo *) &LockInfoList.lh_Tail; + pLock = (struct LockInfo *) pLock->li_Node.ln_Succ) + { + if (pLock->li_Hash == Hash) + return pLock; + } + + return NULL; +} + + +static struct LockInfo *FindLockInfoProtected(ULONG Hash) +{ + struct LockInfo *pLock; + + ObtainSemaphoreShared(&LockInfoListSema); + pLock = FindLockInfo(Hash); + ReleaseSemaphore(&LockInfoListSema); + + return pLock; +} + + +/* +** Control and query of the open file handle. +*/ +static int otherFileControl(sqlite3_file *id, int op, void *pArg) +{ + otherFile *pFile = (otherFile *) id; + + switch( op ) + { + case SQLITE_FCNTL_LOCKSTATE: + { + *(int*) pArg = pFile->locktype; + return SQLITE_OK; + } + case SQLITE_LAST_ERRNO: + { + *(int*)pArg = pFile->lastErrno; + return SQLITE_OK; + } +#ifndef NDEBUG + /* The pager calls this method to signal that it has done + ** a rollback and that the database is therefore unchanged and + ** it hence it is OK for the transaction change counter to be + ** unchanged. + */ + case SQLITE_FCNTL_DB_UNCHANGED: + { + pFile->dbUpdate = 0; + return SQLITE_OK; + } +#endif + default: + break; + } + return SQLITE_ERROR; +} + +/* +** Return the sector size in bytes of the underlying block device for +** the specified file. This is almost always 512 bytes, but may be +** larger for some devices. +** +** SQLite code assumes this function cannot fail. It also assumes that +** if two files are created in the same file-system directory (i.e. +** a database and it's journal file) that the sector size will be the +** same for both. +*/ +static int otherSectorSize(sqlite3_file *id) +{ + return SQLITE_DEFAULT_SECTOR_SIZE; +} + +/* +** Return a vector of device characteristics. +*/ +static int otherDeviceCharacteristics(sqlite3_file *id) +{ + return 0; +} + +#ifndef SQLITE_OMIT_WAL + + +/* +** Object used to represent an shared memory buffer. +** +** When multiple threads all reference the same wal-index, each thread +** has its own otherShm object, but they all point to a single instance +** of this otherShmNode object. In other words, each wal-index is opened +** only once per process. +** +** Each otherShmNode object is connected to a single unixInodeInfo object. +** We could coalesce this object into unixInodeInfo, but that would mean +** every open file that does not use shared memory (in other words, most +** open files) would have to carry around this extra information. So +** the unixInodeInfo object contains a pointer to this otherShmNode object +** and the otherShmNode object is created only when needed. +** +** unixMutexHeld() must be true when creating or destroying +** this object or while reading or writing the following fields: +** +** nRef +** +** The following fields are read-only after the object is created: +** +** fid +** zFilename +** +** Either otherShmNode.mutex must be held or otherShmNode.nRef==0 and +** unixMutexHeld() is true when reading or writing any other field +** in this structure. +*/ + +struct otherShmNode + { + struct SignalSemaphore shn_Sema; + otherInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */ + size_t shn_szRegion; /* Size of shared-memory regions */ + int shn_nRegion; /* Size of array apRegion */ + char **apRegion; /* Array of mapped shared-memory regions */ + int shn_nRef; /* Number of otherShm objects pointing to this */ + otherShm *pFirst; /* All otherShm objects pointing to this */ + u32 exclMask; /* Mask of exclusive locks held */ + u32 sharedMask; /* Mask of shared locks held */ + u8 nextShmId; /* Next available otherShm.id value */ + }; + +/* +** An instance of the following structure is allocated for each open +** inode. Or, on LinuxThreads, there is one of these structures for +** each inode opened by each thread. +** +** A single inode can have multiple file descriptors, so each unixFile +** structure contains a pointer to an instance of this object and this +** object keeps a count of the number of unixFile pointing to it. +*/ +struct otherInodeInfo + { + otherShmNode *pShmNode; /* Shared memory associated with this inode */ + }; + +/* +** Structure used internally by this VFS to record the state of an +** open shared memory connection. +** +** The following fields are initialized when this object is created and +** are read-only thereafter: +** +** otherShm.pFile +** otherShm.id +** +** All other fields are read/write. The otherShm.pFile->mutex must be held +** while accessing any read/write fields. +*/ +struct otherShm + { + otherShmNode *osh_pShmNode; /* The underlying otherShmNode object */ + otherShm *osh_pNext; /* Next otherShm with the same otherShmNode */ + u8 osh_hasMutex; /* True if holding the otherShmNode mutex */ + u32 osh_sharedMask; /* Mask of shared locks held */ + u32 osh_exclMask; /* Mask of exclusive locks held */ +#ifdef SQLITE_DEBUG + u8 osh_id; /* Id of this connection within its otherShmNode */ +#endif + }; + +/* +** Constants used for locking +*/ +#define OTHER_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */ +#define OTHER_SHM_DMS (OTHER_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */ + +/* +** Apply posix advisory locks for all bytes from ofst through ofst+n-1. +** +** Locks block if the mask is exactly UNIX_SHM_C and are non-blocking +** otherwise. +*/ +static int otherShmSystemLock( + otherShmNode *pShmNode, /* Apply locks to this open shared-memory segment */ + int lockType, /* SQLITE_SHM_UNLOCK, SQLITE_SHM_SHARED, or SQLITE_SHM_EXCLUSIVE */ + int ofst, /* First byte of the locking range */ + int n /* Number of bytes to lock */ +) +{ +// struct flock f; /* The posix advisory locking structure */ + int rc = SQLITE_OK; /* Result code form fcntl() */ + + d2(KPrintF(__FILE__ "/%s/%ld: START pShmNode=%08lx\n", __FUNC__, __LINE__, pShmNode)); + d2(KPrintF(__FILE__ "/%s/%ld: lockType=%ld\n", __FUNC__, __LINE__, lockType)); + d2(KPrintF(__FILE__ "/%s/%ld: ofst=%ld n=%ld\n", __FUNC__, __LINE__, ofst, n)); + + /* Access to the otherShmNode object is serialized by the caller */ + assert( sqlite3_mutex_held(pShmNode->mutex) || pShmNode->shn_nRef==0 ); + + /* Shared locks never span more than one byte */ + assert( n==1 || lockType!=SQLITE_SHM_SHARED ); + + /* Locks are within range */ + assert( n>=1 && nh, F_SETLK, &f); + rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY; +#else //XXX + + /* Update the global lock state and do debug tracing */ +//#ifdef SQLITE_DEBUG +#if 1 + { + u32 mask; + mask = SHM_LOCK_MASK(ofst, n); + d2(KPrintF(__FILE__ "/%s/%ld: SHM-LOCK: mask=%08lx\n", __FUNC__, __LINE__, mask)); + + d2(KPrintF(__FILE__ "/%s/%ld: before: sharedMask=%08lx exclMask=%08lx\n", __FUNC__, __LINE__, pShmNode->sharedMask, pShmNode->exclMask)); + + if ( lockType==SQLITE_SHM_UNLOCK ) + { + if ( (pShmNode->exclMask & mask) || (pShmNode->sharedMask & mask) ) + { + d2(KPrintF(__FILE__ "/%s/%ld: unlock %ld ok\n", __FUNC__, __LINE__, ofst)); + pShmNode->exclMask &= ~mask; + pShmNode->sharedMask &= ~mask; + } + else + { + d2(KPrintF(__FILE__ "/%s/%ld: unlock %ld failed\n", __FUNC__, __LINE__, ofst)); + } + } + else if ( lockType==SQLITE_SHM_SHARED ) + { + if (pShmNode->sharedMask & mask) + { + d2(KPrintF(__FILE__ "/%s/%ld: shared lock %ld failed\n", __FUNC__, __LINE__, ofst)); + rc = SQLITE_BUSY; + } + else + { + d2(KPrintF(__FILE__ "/%s/%ld: shared lock %ld ok\n", __FUNC__, __LINE__, ofst)); + pShmNode->exclMask &= ~mask; + pShmNode->sharedMask |= mask; + } + } + else + { + assert( lockType==SQLITE_SHM_EXCLUSIVE ); + if (pShmNode->exclMask & mask) + { + d2(KPrintF(__FILE__ "/%s/%ld: exclusive lock %ld failed\n", __FUNC__, __LINE__, ofst)); + rc = SQLITE_BUSY; + } + else + { + d2(KPrintF(__FILE__ "/%s/%ld: exclusive lock %ld ok\n", __FUNC__, __LINE__, ofst)); + pShmNode->exclMask |= mask; + pShmNode->sharedMask &= ~mask; + } + } + d2(KPrintF(__FILE__ "/%s/%ld: afterwards: sharedMask=%08lx exclMask=%08lx\n", __FUNC__, __LINE__, pShmNode->sharedMask, pShmNode->exclMask)); + } +#endif + rc = 0; +#endif //XXX + d2(KPrintF(__FILE__ "/%s/%ld: ENC rc=%ld\n", __FUNC__, __LINE__, rc)); + return rc; +} + + +/* +** Purge the unixShmNodeList list of all entries with otherShmNode.nRef==0. +** +** This is not a VFS shared-memory method; it is a utility function called +** by VFS shared-memory methods. +*/ +static void otherShmPurge(otherFile *pFd) +{ + otherShmNode *p = pFd->pShmNode; + + d2(KPrintF(__FILE__ "/%s/%ld: START pFd=%08lx\n", __FUNC__, __LINE__, pFd)); + assert( unixMutexHeld() ); + + if ( p && p->shn_nRef==0 ) + { + int i; + for(i=0; ishn_nRegion; i++) + { + FreeVec(p->apRegion[i]); + } + sqlite3_free(p->apRegion); + pFd->pShmNode = NULL; + sqlite3_free(p); + } + d2(KPrintF(__FILE__ "/%s/%ld: END\n", __FUNC__, __LINE__)); +} + +/* +** Open a shared-memory area associated with open database file pDbFd. +** This particular implementation uses mmapped files. +** +** The file used to implement shared-memory is in the same directory +** as the open database file and has the same name as the open database +** file with the "-shm" suffix added. For example, if the database file +** is "/home/user1/config.db" then the file that is created and mmapped +** for shared memory will be called "/home/user1/config.db-shm". +** +** Another approach to is to use files in /dev/shm or /dev/tmp or an +** some other tmpfs mount. But if a file in a different directory +** from the database file is used, then differing access permissions +** or a chroot() might cause two different processes on the same +** database to end up using different files for shared memory - +** meaning that their memory would not really be shared - resulting +** in database corruption. Nevertheless, this tmpfs file usage +** can be enabled at compile-time using -DSQLITE_SHM_DIRECTORY="/dev/shm" +** or the equivalent. The use of the SQLITE_SHM_DIRECTORY compile-time +** option results in an incompatible build of SQLite; builds of SQLite +** that with differing SQLITE_SHM_DIRECTORY settings attempt to use the +** same database file at the same time, database corruption will likely +** result. The SQLITE_SHM_DIRECTORY compile-time option is considered +** "unsupported" and may go away in a future SQLite release. +** +** When opening a new shared-memory file, if no other instances of that +** file are currently open, in this process or in other processes, then +** the file must be truncated to zero length or have its header cleared. +*/ +static int otherOpenSharedMemory(otherFile *pDbFd) +{ + struct otherShm *p = 0; /* The connection to be opened */ + struct otherShmNode *pShmNode; /* The underlying mmapped file */ + int rc; /* Result code */ + + d2(KPrintF(__FILE__ "/%s/%ld: START pDbFd=%08lx\n", __FUNC__, __LINE__, pDbFd)); + + /* Allocate space for the new otherShm object. */ + p = sqlite3_malloc( sizeof(*p) ); + if ( p==0 ) + return SQLITE_NOMEM; + memset(p, 0, sizeof(*p)); + assert( pDbFd->pShm==0 ); + + /* Check to see if a otherShmNode object already exists. Reuse an existing + ** one if present. Create a new one if necessary. + */ + otherEnterMutex(); + + pShmNode = pDbFd->pShmNode; + if ( pShmNode==0 ) + { + pShmNode = sqlite3_malloc( sizeof(*pShmNode) ); + if ( NULL == pShmNode ) + { + rc = SQLITE_NOMEM; + goto shm_open_err; + } + memset(pShmNode, 0, sizeof(*pShmNode)); + InitSemaphore(&pShmNode->shn_Sema); + + pDbFd->pShmNode = pShmNode; + InitSemaphore(&pShmNode->shn_Sema); + + /* Check to see if another process is holding the dead-man switch. + ** If not, truncate the file to zero length. + */ + rc = SQLITE_OK; + if ( otherShmSystemLock(pShmNode, SQLITE_SHM_EXCLUSIVE, OTHER_SHM_DMS, 1)==SQLITE_OK ) + { + } + if ( rc==SQLITE_OK ) + { + rc = otherShmSystemLock(pShmNode, SQLITE_SHM_SHARED, OTHER_SHM_DMS, 1); + } + if ( rc ) goto + shm_open_err; + } + + /* Make the new connection a child of the otherShmNode */ + p->osh_pShmNode = pShmNode; +#ifdef SQLITE_DEBUG + p->osh_id = pShmNode->nextShmId++; +#endif + pShmNode->shn_nRef++; + pDbFd->pShm = p; + + otherLeaveMutex(); + + /* The reference count on pShmNode has already been incremented under + ** the cover of the otherEnterMutex() mutex and the pointer from the + ** new (struct otherShm) object to the pShmNode has been set. All that is + ** left to do is to link the new object into the linked list starting + ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex + ** mutex. + */ + ObtainSemaphore(&pShmNode->shn_Sema); + p->osh_pNext = pShmNode->pFirst; + pShmNode->pFirst = p; + ReleaseSemaphore(&pShmNode->shn_Sema); + return SQLITE_OK; + + /* Jump here on any error */ +shm_open_err: + otherShmPurge(pDbFd); /* This call frees pShmNode if required */ + sqlite3_free(p); + otherLeaveMutex(); + + d2(KPrintF(__FILE__ "/%s/%ld: END rc=%ld\n", __FUNC__, __LINE__, rc)); + return rc; +} + +/* +** This function is called to obtain a pointer to region iRegion of the +** shared-memory associated with the database file fd. Shared-memory regions +** are numbered starting from zero. Each shared-memory region is szRegion +** bytes in size. +** +** If an error occurs, an error code is returned and *pp is set to NULL. +** +** Otherwise, if the bExtend parameter is 0 and the requested shared-memory +** region has not been allocated (by any client, including one running in a +** separate process), then *pp is set to NULL and SQLITE_OK returned. If +** bExtend is non-zero and the requested shared-memory region has not yet +** been allocated, it is allocated by this function. +** +** If the shared-memory region has already been allocated or is allocated by +** this call as described above, then it is mapped into this processes +** address space (if it is not already), *pp is set to point to the mapped +** memory and SQLITE_OK returned. +*/ +static int otherShmMap( + sqlite3_file *fd, /* Handle open on database file */ + int iRegion, /* Region to retrieve */ + int szRegion, /* Size of regions */ + int bExtend, /* True to extend file if necessary */ + void volatile **pp /* OUT: Mapped memory */ +) +{ + otherFile *pDbFd = (otherFile*)fd; + otherShm *p; + otherShmNode *pShmNode; + int rc = SQLITE_OK; + + d2(KPrintF(__FILE__ "/%s/%ld: START fd=%08lx\n", __FUNC__, __LINE__, fd)); + d2(KPrintF(__FILE__ "/%s/%ld: iRegion=%ld szRegion=%ld bExtend=%ld\n", __FUNC__, __LINE__, iRegion, szRegion, bExtend)); + + /* If the shared-memory file has not yet been opened, open it now. */ + if ( pDbFd->pShm==0 ) + { + rc = otherOpenSharedMemory(pDbFd); + if ( rc!=SQLITE_OK ) + return rc; + } + + p = pDbFd->pShm; + pShmNode = p->osh_pShmNode; + ObtainSemaphore(&pShmNode->shn_Sema); + + assert( szRegion==pShmNode->shn_szRegion || pShmNode->shn_nRegion==0 ); + + if ( pShmNode->shn_nRegion <= iRegion ) + { + char **apNew; /* New apRegion[] array */ +// int nByte = (iRegion+1)*szRegion; /* Minimum required file size */ +// struct stat sStat; /* Used by fstat() */ + + pShmNode->shn_szRegion = szRegion; +#if XXX + /* The requested region is not mapped into this processes address space. + ** Check to see if it has been allocated (i.e. if the wal-index file is + ** large enough to contain the requested region). + */ + if ( fstat(pShmNode->h, &sStat) ) + { + rc = SQLITE_IOERR_SHMSIZE; + goto shmpage_out; + } + + if ( sStat.st_sizeh, nByte) ) + { + rc = SQLITE_IOERR_SHMSIZE; + goto shmpage_out; + } + } +#endif //XXX + + /* Map the requested memory region into this processes address space. */ + apNew = (char **)sqlite3_realloc(pShmNode->apRegion, (iRegion+1)*sizeof(char *)); + if ( !apNew ) + { + rc = SQLITE_IOERR_NOMEM; + goto shmpage_out; + } + pShmNode->apRegion = apNew; + while (pShmNode->shn_nRegion<=iRegion) + { + void *pMem = AllocVec(szRegion, MEMF_PUBLIC); + if (NULL == pMem) + { + rc = SQLITE_IOERR; + goto shmpage_out; + } + pShmNode->apRegion[pShmNode->shn_nRegion] = pMem; + pShmNode->shn_nRegion++; + } + } + +shmpage_out: + d2(KPrintF(__FILE__ "/%s/%ld: shn_nRegion=%ld iRegion=%ld\n", __FUNC__, __LINE__, pShmNode->shn_nRegion, iRegion)); + if ( pShmNode->shn_nRegion>iRegion ) + { + *pp = pShmNode->apRegion[iRegion]; + } + else + { + *pp = 0; + } + ReleaseSemaphore(&pShmNode->shn_Sema); + d2(KPrintF(__FILE__ "/%s/%ld: END *pp=%08lx rc=%ld\n", __FUNC__, __LINE__, *pp, rc)); + return rc; +} + +/* +** Change the lock state for a shared-memory segment. +** +** Note that the relationship between SHAREd and EXCLUSIVE locks is a little +** different here than in posix. In xShmLock(), one can go from unlocked +** to shared and back or from unlocked to exclusive and back. But one may +** not go from shared to exclusive or from exclusive to shared. +*/ +static int otherShmLock( + sqlite3_file *fd, /* Database file holding the shared memory */ + int ofst, /* First lock to acquire or release */ + int n, /* Number of locks to acquire or release */ + int flags /* What to do with the lock */ +) +{ + otherFile *pDbFd = (otherFile*)fd; /* Connection holding shared memory */ + otherShm *p = pDbFd->pShm; /* The shared memory being locked */ + otherShm *pX; /* For looping over all siblings */ + otherShmNode *pShmNode = p->osh_pShmNode; /* The underlying file iNode */ + int rc = SQLITE_OK; /* Result code */ + u32 mask; /* Mask of locks to take or release */ + + d2(KPrintF(__FILE__ "/%s/%ld: START fd=%08lx\n", __FUNC__, __LINE__, fd)); + d2(KPrintF(__FILE__ "/%s/%ld: ofst=%ld n=%ld flags=%ld\n", __FUNC__, __LINE__, ofst, n, flags)); + + assert( pShmNode==pDbFd->pShmNode ); + assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK ); + assert( n>=1 ); + assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED) + || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE) + || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED) + || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) ); + assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); + + mask = SHM_LOCK_MASK(ofst, n); + assert( n>1 || mask==(1<shn_Sema); + + if ( flags & SQLITE_SHM_UNLOCK ) + { + u32 allMask = 0; /* Mask of locks held by siblings */ + + /* See if any siblings hold this same lock */ + for(pX=pShmNode->pFirst; pX; pX=pX->osh_pNext) + { + if ( pX==p ) + continue; + assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 ); + allMask |= pX->osh_sharedMask; + } + + /* Unlock the system-level locks */ + if ( (mask & allMask)==0 ) + { + rc = otherShmSystemLock(pShmNode, SQLITE_SHM_UNLOCK, ofst+OTHER_SHM_BASE, n); + } + else + { + rc = SQLITE_OK; + } + + /* Undo the local locks */ + if ( rc==SQLITE_OK ) + { + p->osh_exclMask &= ~mask; + p->osh_sharedMask &= ~mask; + } + } + else if ( flags & SQLITE_SHM_SHARED ) + { + u32 allShared = 0; /* Union of locks held by connections other than "p" */ + + /* Find out which shared locks are already held by sibling connections. + ** If any sibling already holds an exclusive lock, go ahead and return + ** SQLITE_BUSY. + */ + for(pX=pShmNode->pFirst; pX; pX=pX->osh_pNext) + { + if ( (pX->osh_exclMask & mask)!=0 ) + { + rc = SQLITE_BUSY; + break; + } + allShared |= pX->osh_sharedMask; + } + + /* Get shared locks at the system level, if necessary */ + if ( rc==SQLITE_OK ) + { + if ( (allShared & mask)==0 ) + { + rc = otherShmSystemLock(pShmNode, SQLITE_SHM_SHARED, ofst+OTHER_SHM_BASE, n); + } + else + { + rc = SQLITE_OK; + } + } + + /* Get the local shared locks */ + if ( rc==SQLITE_OK ) + { + p->osh_sharedMask |= mask; + } + } + else + { + /* Make sure no sibling connections hold locks that will block this + ** lock. If any do, return SQLITE_BUSY right away. + */ + for(pX=pShmNode->pFirst; pX; pX=pX->osh_pNext) + { + if ( (pX->osh_exclMask & mask)!=0 || (pX->osh_sharedMask & mask)!=0 ) + { + rc = SQLITE_BUSY; + break; + } + } + + /* Get the exclusive locks at the system level. Then if successful + ** also mark the local connection as being locked. + */ + if ( rc==SQLITE_OK ) + { + rc = otherShmSystemLock(pShmNode, SQLITE_SHM_EXCLUSIVE, ofst+OTHER_SHM_BASE, n); + if ( rc==SQLITE_OK ) + { + assert( (p->sharedMask & mask)==0 ); + p->osh_exclMask |= mask; + } + } + } + + ReleaseSemaphore(&pShmNode->shn_Sema); + OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n", + p->osh_id, getpid(), p->osh_sharedMask, p->osh_exclMask)); + d2(KPrintF(__FILE__ "/%s/%ld: END rc=%ld\n", __FUNC__, __LINE__, rc)); + return rc; +} + +/* +** Implement a memory barrier or memory fence on shared memory. +** +** All loads and stores begun before the barrier must complete before +** any load or store begun after the barrier. +*/ +static void otherShmBarrier( + sqlite3_file *fd /* Database file holding the shared memory */ +) +{ + UNUSED_PARAMETER(fd); + otherEnterMutex(); + otherLeaveMutex(); +} + +/* +** Close a connection to shared-memory. Delete the underlying +** storage if deleteFlag is true. +** +** If there is no shared memory associated with the connection then this +** routine is a harmless no-op. +*/ +static int otherShmUnmap( + sqlite3_file *fd, /* The underlying database file */ + int deleteFlag /* Delete shared-memory if true */ +) +{ + otherShm *p; /* The connection to be closed */ + otherShmNode *pShmNode; /* The underlying shared-memory file */ + otherShm **pp; /* For looping over sibling connections */ + otherFile *pDbFd; /* The underlying database file */ + + d2(KPrintF(__FILE__ "/%s/%ld: START fd=%08lx deleteFlag=%ld\n", __FUNC__, __LINE__, fd, deleteFlag)); + + pDbFd = (otherFile*)fd; + p = pDbFd->pShm; + if ( p==0 ) + return SQLITE_OK; + pShmNode = p->osh_pShmNode; + + assert( pShmNode==pDbFd->pShmNode ); + + /* Remove connection p from the set of connections associated + ** with pShmNode */ + ObtainSemaphore(&pShmNode->shn_Sema); + for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->osh_pNext) + { + } + *pp = p->osh_pNext; + + /* Free the connection p */ + sqlite3_free(p); + pDbFd->pShm = 0; + ReleaseSemaphore(&pShmNode->shn_Sema); + + /* If pShmNode->shn_nRef has reached 0, then close the underlying + ** shared-memory file, too */ + otherEnterMutex(); + assert( pShmNode->shn_nRef>0 ); + pShmNode->shn_nRef--; + if ( pShmNode->shn_nRef==0 ) + { + otherShmPurge(pDbFd); + } + otherLeaveMutex(); + d2(KPrintF(__FILE__ "/%s/%ld: END rc=%ld\n", __FUNC__, __LINE__, SQLITE_OK)); + + return SQLITE_OK; +} + + +#else /* #ifndef SQLITE_OMIT_WAL */ +# define otherShmMap 0 +# define otherShmLock 0 +# define otherShmBarrier 0 +# define otherShmUnmap 0 +#endif /* #ifndef SQLITE_OMIT_WAL */ + +/* +** This vector defines all the methods that can operate on an sqlite3_file +** for win32. +*/ +static const sqlite3_io_methods sqlite3OtherIoMethod = +{ + 2, // iVersion + otherClose, + otherRead, + otherWrite, + otherTruncate, + otherSync, + otherFileSize, + otherLock, + otherUnlock, + otherCheckReservedLock, + otherFileControl, + otherSectorSize, + otherDeviceCharacteristics, + /* Methods above are valid for version 1 */ + otherShmMap, + otherShmLock, + otherShmBarrier, + otherShmUnmap, + /* Methods above are valid for version 2 */ + /* Additional methods may be added in future releases */ +}; + +/* +** Allocate memory for an otherFile. Initialize the new otherFile +** to the value given in pInit and return a pointer to the new +** sqlite3_file. If we run out of memory, close the file and return NULL. +*/ +static int allocateOtherFile(otherFile *pNew, const char *zFilename) +{ + if (!NewLockInfo(pNew, zFilename)) + { + d1(KPrintF(__FILE__ "/%s/%ld: NewLockInfo failed\n", __FUNC__, __LINE__)); + return SQLITE_NOMEM; + } + pNew->pMethod = &sqlite3OtherIoMethod; + OpenCounter(+1); + return SQLITE_OK; +} + + +static void InitOtherKey(struct LockKey *lk) +{ + lk->lk_LockCount = 0; + InitSemaphore(&lk->lk_Sema); +} + + +static LONG AttemptLockOtherKey(struct LockKey *lk) +{ + LONG Result; + + Result = AttemptSemaphore(&lk->lk_Sema); + if (Result) + lk->lk_LockCount++; + else + { + ULONG delay; + + sqlite3_randomness(sizeof(delay), &delay); + Delay(delay % 10); // Semaphore is locked by another process - give way to allow other process to procede + } + + return Result; +} + + +static LONG AttemptLockOtherKeyShared(struct LockKey *lk) +{ + LONG Result; + + Result = AttemptSemaphoreShared(&lk->lk_Sema); + if (Result) + lk->lk_LockCount++; + else + { + ULONG delay; + + sqlite3_randomness(sizeof(delay), &delay); + Delay(delay % 10); // Semaphore is locked by another process - give way to allow other process to procede + } + + return Result; +} + + +static void UnlockOtherKey(struct LockKey *lk) +{ + if (lk->lk_LockCount) + { + lk->lk_LockCount--; + ReleaseSemaphore(&lk->lk_Sema); + } +} + + +static int otherGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf) +{ + return 0; +} + +/* +** Initialize the operating system interface. +*/ +int sqlite3_os_init(void) +{ + int rc; + static sqlite3_vfs otherVfs = + { + 2, /* iVersion */ + sizeof(otherFile), /* szOsFile */ + 512, /* mxPathname */ + 0, /* pNext */ + "amiga", /* zName */ + 0, /* pAppData */ + + otherOpen, /* xOpen */ + otherDelete, /* xDelete */ + otherAccess, /* xAccess */ + otherFullPathname, /* xFullPathname */ + otherDlOpen, /* xDlOpen */ + otherDlError, /* xDlError */ + otherDlSym, /* xDlSym */ + otherDlClose, /* xDlClose */ + otherRandomness, /* xRandomness */ + otherSleep, /* xSleep */ + otherCurrentTime, /* xCurrentTime */ + otherGetLastError, /* xGetLastError */ + /* + ** The methods above are in version 1 of the sqlite_vfs object + ** definition. Those that follow are added in version 2 or later + */ + otherCurrentTimeInt64, /* xCurrentTimeInt64 */ + /* + ** The methods above are in versions 1 and 2 of the sqlite_vfs object. + ** New fields may be appended in figure versions. The iVersion + ** value will increment whenever this happens. + */ + }; + + rc = sqlite3_config(SQLITE_CONFIG_MUTEX, sqlite3OtherMutex()); + d1(KPrintF(__FILE__ "/%s/%ld: SQLITE_CONFIG_MUTEX rc=%ld\n", __FUNC__, __LINE__, rc)); + if (SQLITE_OK != rc) + return rc; + + rc = sqlite3_vfs_register(&otherVfs, 1); + if (SQLITE_OK != rc) + return rc; + + rc = sqlite3_config(SQLITE_CONFIG_SERIALIZED); + d1(KPrintF(__FILE__ "/%s/%ld: SQLITE_CONFIG_SERIALIZED rc=%ld\n", __FUNC__, __LINE__, rc)); + if (SQLITE_OK != rc) + return rc; + + rc = sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 100, 500); + d1(KPrintF(__FILE__ "/%s/%ld: SQLITE_CONFIG_LOOKASIDE rc=%ld\n", __FUNC__, __LINE__, rc)); + if (SQLITE_OK != rc) + return rc; + + return SQLITE_OK; +} + +/* +** Shutdown the operating system interface. This is a no-op for unix. +*/ +int sqlite3_os_end(void) +{ + return SQLITE_OK; +} + +#endif /* SQLITE_OS_OTHER */ diff --git a/scalos/libraries/sqlite/src/os_other.h b/scalos/libraries/sqlite/src/os_other.h new file mode 100644 index 000000000..8534a0655 --- /dev/null +++ b/scalos/libraries/sqlite/src/os_other.h @@ -0,0 +1,42 @@ +/* +** 2004 May 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This header file defines OS-specific features for Amiga-type OS +** AmigaOS3.x AmigaOS4 MorphOS +*/ +#ifndef _SQLITE_OS_OTHER_H_ +#define _SQLITE_OS_OTHER_H_ + +#include +#include +#include + +#define DOS_SHARED_LOCK SHARED_LOCK +#define DOS_EXCLUSIVE_LOCK EXCLUSIVE_LOCK + +#undef SHARED_LOCK +#undef EXCLUSIVE_LOCK + + +#if SQLITE_OS_OTHER + +#define sqlite3DebugPrintf KPrintF +#endif + + +/* +** Maximum number of characters in a temporary file name +*/ +#define SQLITE_TEMPNAME_SIZE 200 + + +#endif /* _SQLITE_OS_OTHER_H_ */ diff --git a/scalos/libraries/sqlite/src/os_unix.c b/scalos/libraries/sqlite/src/os_unix.c new file mode 100644 index 000000000..13faac3a5 --- /dev/null +++ b/scalos/libraries/sqlite/src/os_unix.c @@ -0,0 +1,6833 @@ +/* +** 2004 May 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains the VFS implementation for unix-like operating systems +** include Linux, MacOSX, *BSD, QNX, VxWorks, AIX, HPUX, and others. +** +** There are actually several different VFS implementations in this file. +** The differences are in the way that file locking is done. The default +** implementation uses Posix Advisory Locks. Alternative implementations +** use flock(), dot-files, various proprietary locking schemas, or simply +** skip locking all together. +** +** This source file is organized into divisions where the logic for various +** subfunctions is contained within the appropriate division. PLEASE +** KEEP THE STRUCTURE OF THIS FILE INTACT. New code should be placed +** in the correct division and should be clearly labeled. +** +** The layout of divisions is as follows: +** +** * General-purpose declarations and utility functions. +** * Unique file ID logic used by VxWorks. +** * Various locking primitive implementations (all except proxy locking): +** + for Posix Advisory Locks +** + for no-op locks +** + for dot-file locks +** + for flock() locking +** + for named semaphore locks (VxWorks only) +** + for AFP filesystem locks (MacOSX only) +** * sqlite3_file methods not associated with locking. +** * Definitions of sqlite3_io_methods objects for all locking +** methods plus "finder" functions for each locking method. +** * sqlite3_vfs method implementations. +** * Locking primitives for the proxy uber-locking-method. (MacOSX only) +** * Definitions of sqlite3_vfs objects for all locking methods +** plus implementations of sqlite3_os_init() and sqlite3_os_end(). +*/ +#include "sqliteInt.h" +#if SQLITE_OS_UNIX /* This file is used on unix only */ + +/* +** There are various methods for file locking used for concurrency +** control: +** +** 1. POSIX locking (the default), +** 2. No locking, +** 3. Dot-file locking, +** 4. flock() locking, +** 5. AFP locking (OSX only), +** 6. Named POSIX semaphores (VXWorks only), +** 7. proxy locking. (OSX only) +** +** Styles 4, 5, and 7 are only available of SQLITE_ENABLE_LOCKING_STYLE +** is defined to 1. The SQLITE_ENABLE_LOCKING_STYLE also enables automatic +** selection of the appropriate locking style based on the filesystem +** where the database is located. +*/ +#if !defined(SQLITE_ENABLE_LOCKING_STYLE) +# if defined(__APPLE__) +# define SQLITE_ENABLE_LOCKING_STYLE 1 +# else +# define SQLITE_ENABLE_LOCKING_STYLE 0 +# endif +#endif + +/* +** Define the OS_VXWORKS pre-processor macro to 1 if building on +** vxworks, or 0 otherwise. +*/ +#ifndef OS_VXWORKS +# if defined(__RTP__) || defined(_WRS_KERNEL) +# define OS_VXWORKS 1 +# else +# define OS_VXWORKS 0 +# endif +#endif + +/* +** These #defines should enable >2GB file support on Posix if the +** underlying operating system supports it. If the OS lacks +** large file support, these should be no-ops. +** +** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch +** on the compiler command line. This is necessary if you are compiling +** on a recent machine (ex: RedHat 7.2) but you want your code to work +** on an older machine (ex: RedHat 6.0). If you compile on RedHat 7.2 +** without this option, LFS is enable. But LFS does not exist in the kernel +** in RedHat 6.0, so the code won't work. Hence, for maximum binary +** portability you should omit LFS. +** +** The previous paragraph was written in 2005. (This paragraph is written +** on 2008-11-28.) These days, all Linux kernels support large files, so +** you should probably leave LFS enabled. But some embedded platforms might +** lack LFS in which case the SQLITE_DISABLE_LFS macro might still be useful. +*/ +#ifndef SQLITE_DISABLE_LFS +# define _LARGE_FILE 1 +# ifndef _FILE_OFFSET_BITS +# define _FILE_OFFSET_BITS 64 +# endif +# define _LARGEFILE_SOURCE 1 +#endif + +/* +** standard include files. +*/ +#include +#include +#include +#include +#include +#include +#include +#ifndef SQLITE_OMIT_WAL +#include +#endif + + +#if SQLITE_ENABLE_LOCKING_STYLE +# include +# if OS_VXWORKS +# include +# include +# else +# include +# include +# endif +#endif /* SQLITE_ENABLE_LOCKING_STYLE */ + +#if defined(__APPLE__) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS) +# include +#endif + +#ifdef HAVE_UTIME +# include +#endif + +/* +** Allowed values of unixFile.fsFlags +*/ +#define SQLITE_FSFLAGS_IS_MSDOS 0x1 + +/* +** If we are to be thread-safe, include the pthreads header and define +** the SQLITE_UNIX_THREADS macro. +*/ +#if SQLITE_THREADSAFE +# include +# define SQLITE_UNIX_THREADS 1 +#endif + +/* +** Default permissions when creating a new file +*/ +#ifndef SQLITE_DEFAULT_FILE_PERMISSIONS +# define SQLITE_DEFAULT_FILE_PERMISSIONS 0644 +#endif + +/* + ** Default permissions when creating auto proxy dir + */ +#ifndef SQLITE_DEFAULT_PROXYDIR_PERMISSIONS +# define SQLITE_DEFAULT_PROXYDIR_PERMISSIONS 0755 +#endif + +/* +** Maximum supported path-length. +*/ +#define MAX_PATHNAME 512 + +/* +** Only set the lastErrno if the error code is a real error and not +** a normal expected return code of SQLITE_BUSY or SQLITE_OK +*/ +#define IS_LOCK_ERROR(x) ((x != SQLITE_OK) && (x != SQLITE_BUSY)) + +/* Forward references */ +typedef struct unixShm unixShm; /* Connection shared memory */ +typedef struct unixShmNode unixShmNode; /* Shared memory instance */ +typedef struct unixInodeInfo unixInodeInfo; /* An i-node */ +typedef struct UnixUnusedFd UnixUnusedFd; /* An unused file descriptor */ + +/* +** Sometimes, after a file handle is closed by SQLite, the file descriptor +** cannot be closed immediately. In these cases, instances of the following +** structure are used to store the file descriptor while waiting for an +** opportunity to either close or reuse it. +*/ +struct UnixUnusedFd { + int fd; /* File descriptor to close */ + int flags; /* Flags this file descriptor was opened with */ + UnixUnusedFd *pNext; /* Next unused file descriptor on same file */ +}; + +/* +** The unixFile structure is subclass of sqlite3_file specific to the unix +** VFS implementations. +*/ +typedef struct unixFile unixFile; +struct unixFile { + sqlite3_io_methods const *pMethod; /* Always the first entry */ + sqlite3_vfs *pVfs; /* The VFS that created this unixFile */ + unixInodeInfo *pInode; /* Info about locks on this inode */ + int h; /* The file descriptor */ + unsigned char eFileLock; /* The type of lock held on this fd */ + unsigned char ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */ + int lastErrno; /* The unix errno from last I/O error */ + void *lockingContext; /* Locking style specific state */ + UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ + const char *zPath; /* Name of the file */ + unixShm *pShm; /* Shared memory segment information */ + int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ +#if SQLITE_ENABLE_LOCKING_STYLE + int openFlags; /* The flags specified at open() */ +#endif +#if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__) + unsigned fsFlags; /* cached details from statfs() */ +#endif +#if OS_VXWORKS + struct vxworksFileId *pId; /* Unique file ID */ +#endif +#ifndef NDEBUG + /* The next group of variables are used to track whether or not the + ** transaction counter in bytes 24-27 of database files are updated + ** whenever any part of the database changes. An assertion fault will + ** occur if a file is updated without also updating the transaction + ** counter. This test is made to avoid new problems similar to the + ** one described by ticket #3584. + */ + unsigned char transCntrChng; /* True if the transaction counter changed */ + unsigned char dbUpdate; /* True if any part of database file changed */ + unsigned char inNormalWrite; /* True if in a normal write operation */ +#endif +#ifdef SQLITE_TEST + /* In test mode, increase the size of this structure a bit so that + ** it is larger than the struct CrashFile defined in test6.c. + */ + char aPadding[32]; +#endif +}; + +/* +** Allowed values for the unixFile.ctrlFlags bitmask: +*/ +#define UNIXFILE_EXCL 0x01 /* Connections from one process only */ +#define UNIXFILE_RDONLY 0x02 /* Connection is read only */ +#define UNIXFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ +#ifndef SQLITE_DISABLE_DIRSYNC +# define UNIXFILE_DIRSYNC 0x08 /* Directory sync needed */ +#else +# define UNIXFILE_DIRSYNC 0x00 +#endif +#define UNIXFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */ +#define UNIXFILE_DELETE 0x20 /* Delete on close */ +#define UNIXFILE_URI 0x40 /* Filename might have query parameters */ +#define UNIXFILE_NOLOCK 0x80 /* Do no file locking */ + +/* +** Include code that is common to all os_*.c files +*/ +#include "os_common.h" + +/* +** Define various macros that are missing from some systems. +*/ +#ifndef O_LARGEFILE +# define O_LARGEFILE 0 +#endif +#ifdef SQLITE_DISABLE_LFS +# undef O_LARGEFILE +# define O_LARGEFILE 0 +#endif +#ifndef O_NOFOLLOW +# define O_NOFOLLOW 0 +#endif +#ifndef O_BINARY +# define O_BINARY 0 +#endif + +/* +** The threadid macro resolves to the thread-id or to 0. Used for +** testing and debugging only. +*/ +#if SQLITE_THREADSAFE +#define threadid pthread_self() +#else +#define threadid 0 +#endif + +/* +** Different Unix systems declare open() in different ways. Same use +** open(const char*,int,mode_t). Others use open(const char*,int,...). +** The difference is important when using a pointer to the function. +** +** The safest way to deal with the problem is to always use this wrapper +** which always has the same well-defined interface. +*/ +static int posixOpen(const char *zFile, int flags, int mode){ + return open(zFile, flags, mode); +} + +/* Forward reference */ +static int openDirectory(const char*, int*); + +/* +** Many system calls are accessed through pointer-to-functions so that +** they may be overridden at runtime to facilitate fault injection during +** testing and sandboxing. The following array holds the names and pointers +** to all overrideable system calls. +*/ +static struct unix_syscall { + const char *zName; /* Name of the sytem call */ + sqlite3_syscall_ptr pCurrent; /* Current value of the system call */ + sqlite3_syscall_ptr pDefault; /* Default value */ +} aSyscall[] = { + { "open", (sqlite3_syscall_ptr)posixOpen, 0 }, +#define osOpen ((int(*)(const char*,int,int))aSyscall[0].pCurrent) + + { "close", (sqlite3_syscall_ptr)close, 0 }, +#define osClose ((int(*)(int))aSyscall[1].pCurrent) + + { "access", (sqlite3_syscall_ptr)access, 0 }, +#define osAccess ((int(*)(const char*,int))aSyscall[2].pCurrent) + + { "getcwd", (sqlite3_syscall_ptr)getcwd, 0 }, +#define osGetcwd ((char*(*)(char*,size_t))aSyscall[3].pCurrent) + + { "stat", (sqlite3_syscall_ptr)stat, 0 }, +#define osStat ((int(*)(const char*,struct stat*))aSyscall[4].pCurrent) + +/* +** The DJGPP compiler environment looks mostly like Unix, but it +** lacks the fcntl() system call. So redefine fcntl() to be something +** that always succeeds. This means that locking does not occur under +** DJGPP. But it is DOS - what did you expect? +*/ +#ifdef __DJGPP__ + { "fstat", 0, 0 }, +#define osFstat(a,b,c) 0 +#else + { "fstat", (sqlite3_syscall_ptr)fstat, 0 }, +#define osFstat ((int(*)(int,struct stat*))aSyscall[5].pCurrent) +#endif + + { "ftruncate", (sqlite3_syscall_ptr)ftruncate, 0 }, +#define osFtruncate ((int(*)(int,off_t))aSyscall[6].pCurrent) + + { "fcntl", (sqlite3_syscall_ptr)fcntl, 0 }, +#define osFcntl ((int(*)(int,int,...))aSyscall[7].pCurrent) + + { "read", (sqlite3_syscall_ptr)read, 0 }, +#define osRead ((ssize_t(*)(int,void*,size_t))aSyscall[8].pCurrent) + +#if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE + { "pread", (sqlite3_syscall_ptr)pread, 0 }, +#else + { "pread", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osPread ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[9].pCurrent) + +#if defined(USE_PREAD64) + { "pread64", (sqlite3_syscall_ptr)pread64, 0 }, +#else + { "pread64", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osPread64 ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[10].pCurrent) + + { "write", (sqlite3_syscall_ptr)write, 0 }, +#define osWrite ((ssize_t(*)(int,const void*,size_t))aSyscall[11].pCurrent) + +#if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE + { "pwrite", (sqlite3_syscall_ptr)pwrite, 0 }, +#else + { "pwrite", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osPwrite ((ssize_t(*)(int,const void*,size_t,off_t))\ + aSyscall[12].pCurrent) + +#if defined(USE_PREAD64) + { "pwrite64", (sqlite3_syscall_ptr)pwrite64, 0 }, +#else + { "pwrite64", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off_t))\ + aSyscall[13].pCurrent) + +#if SQLITE_ENABLE_LOCKING_STYLE + { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 }, +#else + { "fchmod", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent) + +#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE + { "fallocate", (sqlite3_syscall_ptr)posix_fallocate, 0 }, +#else + { "fallocate", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osFallocate ((int(*)(int,off_t,off_t))aSyscall[15].pCurrent) + + { "unlink", (sqlite3_syscall_ptr)unlink, 0 }, +#define osUnlink ((int(*)(const char*))aSyscall[16].pCurrent) + + { "openDirectory", (sqlite3_syscall_ptr)openDirectory, 0 }, +#define osOpenDirectory ((int(*)(const char*,int*))aSyscall[17].pCurrent) + + { "mkdir", (sqlite3_syscall_ptr)mkdir, 0 }, +#define osMkdir ((int(*)(const char*,mode_t))aSyscall[18].pCurrent) + + { "rmdir", (sqlite3_syscall_ptr)rmdir, 0 }, +#define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent) + +}; /* End of the overrideable system calls */ + +/* +** This is the xSetSystemCall() method of sqlite3_vfs for all of the +** "unix" VFSes. Return SQLITE_OK opon successfully updating the +** system call pointer, or SQLITE_NOTFOUND if there is no configurable +** system call named zName. +*/ +static int unixSetSystemCall( + sqlite3_vfs *pNotUsed, /* The VFS pointer. Not used */ + const char *zName, /* Name of system call to override */ + sqlite3_syscall_ptr pNewFunc /* Pointer to new system call value */ +){ + unsigned int i; + int rc = SQLITE_NOTFOUND; + + UNUSED_PARAMETER(pNotUsed); + if( zName==0 ){ + /* If no zName is given, restore all system calls to their default + ** settings and return NULL + */ + rc = SQLITE_OK; + for(i=0; il_type==F_RDLCK ){ + zType = "RDLCK"; + }else if( p->l_type==F_WRLCK ){ + zType = "WRLCK"; + }else if( p->l_type==F_UNLCK ){ + zType = "UNLCK"; + }else{ + assert( 0 ); + } + assert( p->l_whence==SEEK_SET ); + s = osFcntl(fd, op, p); + savedErrno = errno; + sqlite3DebugPrintf("fcntl %d %d %s %s %d %d %d %d\n", + threadid, fd, zOpName, zType, (int)p->l_start, (int)p->l_len, + (int)p->l_pid, s); + if( s==(-1) && op==F_SETLK && (p->l_type==F_RDLCK || p->l_type==F_WRLCK) ){ + struct flock l2; + l2 = *p; + osFcntl(fd, F_GETLK, &l2); + if( l2.l_type==F_RDLCK ){ + zType = "RDLCK"; + }else if( l2.l_type==F_WRLCK ){ + zType = "WRLCK"; + }else if( l2.l_type==F_UNLCK ){ + zType = "UNLCK"; + }else{ + assert( 0 ); + } + sqlite3DebugPrintf("fcntl-failure-reason: %s %d %d %d\n", + zType, (int)l2.l_start, (int)l2.l_len, (int)l2.l_pid); + } + errno = savedErrno; + return s; +} +#undef osFcntl +#define osFcntl lockTrace +#endif /* SQLITE_LOCK_TRACE */ + +/* +** Retry ftruncate() calls that fail due to EINTR +*/ +static int robust_ftruncate(int h, sqlite3_int64 sz){ + int rc; + do{ rc = osFtruncate(h,sz); }while( rc<0 && errno==EINTR ); + return rc; +} + +/* +** This routine translates a standard POSIX errno code into something +** useful to the clients of the sqlite3 functions. Specifically, it is +** intended to translate a variety of "try again" errors into SQLITE_BUSY +** and a variety of "please close the file descriptor NOW" errors into +** SQLITE_IOERR +** +** Errors during initialization of locks, or file system support for locks, +** should handle ENOLCK, ENOTSUP, EOPNOTSUPP separately. +*/ +static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) { + switch (posixError) { +#if 0 + /* At one point this code was not commented out. In theory, this branch + ** should never be hit, as this function should only be called after + ** a locking-related function (i.e. fcntl()) has returned non-zero with + ** the value of errno as the first argument. Since a system call has failed, + ** errno should be non-zero. + ** + ** Despite this, if errno really is zero, we still don't want to return + ** SQLITE_OK. The system call failed, and *some* SQLite error should be + ** propagated back to the caller. Commenting this branch out means errno==0 + ** will be handled by the "default:" case below. + */ + case 0: + return SQLITE_OK; +#endif + + case EAGAIN: + case ETIMEDOUT: + case EBUSY: + case EINTR: + case ENOLCK: + /* random NFS retry error, unless during file system support + * introspection, in which it actually means what it says */ + return SQLITE_BUSY; + + case EACCES: + /* EACCES is like EAGAIN during locking operations, but not any other time*/ + if( (sqliteIOErr == SQLITE_IOERR_LOCK) || + (sqliteIOErr == SQLITE_IOERR_UNLOCK) || + (sqliteIOErr == SQLITE_IOERR_RDLOCK) || + (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ){ + return SQLITE_BUSY; + } + /* else fall through */ + case EPERM: + return SQLITE_PERM; + + /* EDEADLK is only possible if a call to fcntl(F_SETLKW) is made. And + ** this module never makes such a call. And the code in SQLite itself + ** asserts that SQLITE_IOERR_BLOCKED is never returned. For these reasons + ** this case is also commented out. If the system does set errno to EDEADLK, + ** the default SQLITE_IOERR_XXX code will be returned. */ +#if 0 + case EDEADLK: + return SQLITE_IOERR_BLOCKED; +#endif + +#if EOPNOTSUPP!=ENOTSUP + case EOPNOTSUPP: + /* something went terribly awry, unless during file system support + * introspection, in which it actually means what it says */ +#endif +#ifdef ENOTSUP + case ENOTSUP: + /* invalid fd, unless during file system support introspection, in which + * it actually means what it says */ +#endif + case EIO: + case EBADF: + case EINVAL: + case ENOTCONN: + case ENODEV: + case ENXIO: + case ENOENT: +#ifdef ESTALE /* ESTALE is not defined on Interix systems */ + case ESTALE: +#endif + case ENOSYS: + /* these should force the client to close the file and reconnect */ + + default: + return sqliteIOErr; + } +} + + + +/****************************************************************************** +****************** Begin Unique File ID Utility Used By VxWorks *************** +** +** On most versions of unix, we can get a unique ID for a file by concatenating +** the device number and the inode number. But this does not work on VxWorks. +** On VxWorks, a unique file id must be based on the canonical filename. +** +** A pointer to an instance of the following structure can be used as a +** unique file ID in VxWorks. Each instance of this structure contains +** a copy of the canonical filename. There is also a reference count. +** The structure is reclaimed when the number of pointers to it drops to +** zero. +** +** There are never very many files open at one time and lookups are not +** a performance-critical path, so it is sufficient to put these +** structures on a linked list. +*/ +struct vxworksFileId { + struct vxworksFileId *pNext; /* Next in a list of them all */ + int nRef; /* Number of references to this one */ + int nName; /* Length of the zCanonicalName[] string */ + char *zCanonicalName; /* Canonical filename */ +}; + +#if OS_VXWORKS +/* +** All unique filenames are held on a linked list headed by this +** variable: +*/ +static struct vxworksFileId *vxworksFileList = 0; + +/* +** Simplify a filename into its canonical form +** by making the following changes: +** +** * removing any trailing and duplicate / +** * convert /./ into just / +** * convert /A/../ where A is any simple name into just / +** +** Changes are made in-place. Return the new name length. +** +** The original filename is in z[0..n-1]. Return the number of +** characters in the simplified name. +*/ +static int vxworksSimplifyName(char *z, int n){ + int i, j; + while( n>1 && z[n-1]=='/' ){ n--; } + for(i=j=0; i0 && z[j-1]!='/' ){ j--; } + if( j>0 ){ j--; } + i += 2; + continue; + } + } + z[j++] = z[i]; + } + z[j] = 0; + return j; +} + +/* +** Find a unique file ID for the given absolute pathname. Return +** a pointer to the vxworksFileId object. This pointer is the unique +** file ID. +** +** The nRef field of the vxworksFileId object is incremented before +** the object is returned. A new vxworksFileId object is created +** and added to the global list if necessary. +** +** If a memory allocation error occurs, return NULL. +*/ +static struct vxworksFileId *vxworksFindFileId(const char *zAbsoluteName){ + struct vxworksFileId *pNew; /* search key and new file ID */ + struct vxworksFileId *pCandidate; /* For looping over existing file IDs */ + int n; /* Length of zAbsoluteName string */ + + assert( zAbsoluteName[0]=='/' ); + n = (int)strlen(zAbsoluteName); + pNew = sqlite3_malloc( sizeof(*pNew) + (n+1) ); + if( pNew==0 ) return 0; + pNew->zCanonicalName = (char*)&pNew[1]; + memcpy(pNew->zCanonicalName, zAbsoluteName, n+1); + n = vxworksSimplifyName(pNew->zCanonicalName, n); + + /* Search for an existing entry that matching the canonical name. + ** If found, increment the reference count and return a pointer to + ** the existing file ID. + */ + unixEnterMutex(); + for(pCandidate=vxworksFileList; pCandidate; pCandidate=pCandidate->pNext){ + if( pCandidate->nName==n + && memcmp(pCandidate->zCanonicalName, pNew->zCanonicalName, n)==0 + ){ + sqlite3_free(pNew); + pCandidate->nRef++; + unixLeaveMutex(); + return pCandidate; + } + } + + /* No match was found. We will make a new file ID */ + pNew->nRef = 1; + pNew->nName = n; + pNew->pNext = vxworksFileList; + vxworksFileList = pNew; + unixLeaveMutex(); + return pNew; +} + +/* +** Decrement the reference count on a vxworksFileId object. Free +** the object when the reference count reaches zero. +*/ +static void vxworksReleaseFileId(struct vxworksFileId *pId){ + unixEnterMutex(); + assert( pId->nRef>0 ); + pId->nRef--; + if( pId->nRef==0 ){ + struct vxworksFileId **pp; + for(pp=&vxworksFileList; *pp && *pp!=pId; pp = &((*pp)->pNext)){} + assert( *pp==pId ); + *pp = pId->pNext; + sqlite3_free(pId); + } + unixLeaveMutex(); +} +#endif /* OS_VXWORKS */ +/*************** End of Unique File ID Utility Used By VxWorks **************** +******************************************************************************/ + + +/****************************************************************************** +*************************** Posix Advisory Locking **************************** +** +** POSIX advisory locks are broken by design. ANSI STD 1003.1 (1996) +** section 6.5.2.2 lines 483 through 490 specify that when a process +** sets or clears a lock, that operation overrides any prior locks set +** by the same process. It does not explicitly say so, but this implies +** that it overrides locks set by the same process using a different +** file descriptor. Consider this test case: +** +** int fd1 = open("./file1", O_RDWR|O_CREAT, 0644); +** int fd2 = open("./file2", O_RDWR|O_CREAT, 0644); +** +** Suppose ./file1 and ./file2 are really the same file (because +** one is a hard or symbolic link to the other) then if you set +** an exclusive lock on fd1, then try to get an exclusive lock +** on fd2, it works. I would have expected the second lock to +** fail since there was already a lock on the file due to fd1. +** But not so. Since both locks came from the same process, the +** second overrides the first, even though they were on different +** file descriptors opened on different file names. +** +** This means that we cannot use POSIX locks to synchronize file access +** among competing threads of the same process. POSIX locks will work fine +** to synchronize access for threads in separate processes, but not +** threads within the same process. +** +** To work around the problem, SQLite has to manage file locks internally +** on its own. Whenever a new database is opened, we have to find the +** specific inode of the database file (the inode is determined by the +** st_dev and st_ino fields of the stat structure that fstat() fills in) +** and check for locks already existing on that inode. When locks are +** created or removed, we have to look at our own internal record of the +** locks to see if another thread has previously set a lock on that same +** inode. +** +** (Aside: The use of inode numbers as unique IDs does not work on VxWorks. +** For VxWorks, we have to use the alternative unique ID system based on +** canonical filename and implemented in the previous division.) +** +** The sqlite3_file structure for POSIX is no longer just an integer file +** descriptor. It is now a structure that holds the integer file +** descriptor and a pointer to a structure that describes the internal +** locks on the corresponding inode. There is one locking structure +** per inode, so if the same inode is opened twice, both unixFile structures +** point to the same locking structure. The locking structure keeps +** a reference count (so we will know when to delete it) and a "cnt" +** field that tells us its internal lock status. cnt==0 means the +** file is unlocked. cnt==-1 means the file has an exclusive lock. +** cnt>0 means there are cnt shared locks on the file. +** +** Any attempt to lock or unlock a file first checks the locking +** structure. The fcntl() system call is only invoked to set a +** POSIX lock if the internal lock structure transitions between +** a locked and an unlocked state. +** +** But wait: there are yet more problems with POSIX advisory locks. +** +** If you close a file descriptor that points to a file that has locks, +** all locks on that file that are owned by the current process are +** released. To work around this problem, each unixInodeInfo object +** maintains a count of the number of pending locks on tha inode. +** When an attempt is made to close an unixFile, if there are +** other unixFile open on the same inode that are holding locks, the call +** to close() the file descriptor is deferred until all of the locks clear. +** The unixInodeInfo structure keeps a list of file descriptors that need to +** be closed and that list is walked (and cleared) when the last lock +** clears. +** +** Yet another problem: LinuxThreads do not play well with posix locks. +** +** Many older versions of linux use the LinuxThreads library which is +** not posix compliant. Under LinuxThreads, a lock created by thread +** A cannot be modified or overridden by a different thread B. +** Only thread A can modify the lock. Locking behavior is correct +** if the appliation uses the newer Native Posix Thread Library (NPTL) +** on linux - with NPTL a lock created by thread A can override locks +** in thread B. But there is no way to know at compile-time which +** threading library is being used. So there is no way to know at +** compile-time whether or not thread A can override locks on thread B. +** One has to do a run-time check to discover the behavior of the +** current process. +** +** SQLite used to support LinuxThreads. But support for LinuxThreads +** was dropped beginning with version 3.7.0. SQLite will still work with +** LinuxThreads provided that (1) there is no more than one connection +** per database file in the same process and (2) database connections +** do not move across threads. +*/ + +/* +** An instance of the following structure serves as the key used +** to locate a particular unixInodeInfo object. +*/ +struct unixFileId { + dev_t dev; /* Device number */ +#if OS_VXWORKS + struct vxworksFileId *pId; /* Unique file ID for vxworks. */ +#else + ino_t ino; /* Inode number */ +#endif +}; + +/* +** An instance of the following structure is allocated for each open +** inode. Or, on LinuxThreads, there is one of these structures for +** each inode opened by each thread. +** +** A single inode can have multiple file descriptors, so each unixFile +** structure contains a pointer to an instance of this object and this +** object keeps a count of the number of unixFile pointing to it. +*/ +struct unixInodeInfo { + struct unixFileId fileId; /* The lookup key */ + int nShared; /* Number of SHARED locks held */ + unsigned char eFileLock; /* One of SHARED_LOCK, RESERVED_LOCK etc. */ + unsigned char bProcessLock; /* An exclusive process lock is held */ + int nRef; /* Number of pointers to this structure */ + unixShmNode *pShmNode; /* Shared memory associated with this inode */ + int nLock; /* Number of outstanding file locks */ + UnixUnusedFd *pUnused; /* Unused file descriptors to close */ + unixInodeInfo *pNext; /* List of all unixInodeInfo objects */ + unixInodeInfo *pPrev; /* .... doubly linked */ +#if SQLITE_ENABLE_LOCKING_STYLE + unsigned long long sharedByte; /* for AFP simulated shared lock */ +#endif +#if OS_VXWORKS + sem_t *pSem; /* Named POSIX semaphore */ + char aSemName[MAX_PATHNAME+2]; /* Name of that semaphore */ +#endif +}; + +/* +** A lists of all unixInodeInfo objects. +*/ +static unixInodeInfo *inodeList = 0; + +/* +** +** This function - unixLogError_x(), is only ever called via the macro +** unixLogError(). +** +** It is invoked after an error occurs in an OS function and errno has been +** set. It logs a message using sqlite3_log() containing the current value of +** errno and, if possible, the human-readable equivalent from strerror() or +** strerror_r(). +** +** The first argument passed to the macro should be the error code that +** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN). +** The two subsequent arguments should be the name of the OS function that +** failed (e.g. "unlink", "open") and the the associated file-system path, +** if any. +*/ +#define unixLogError(a,b,c) unixLogErrorAtLine(a,b,c,__LINE__) +static int unixLogErrorAtLine( + int errcode, /* SQLite error code */ + const char *zFunc, /* Name of OS function that failed */ + const char *zPath, /* File path associated with error */ + int iLine /* Source line number where error occurred */ +){ + char *zErr; /* Message from strerror() or equivalent */ + int iErrno = errno; /* Saved syscall error number */ + + /* If this is not a threadsafe build (SQLITE_THREADSAFE==0), then use + ** the strerror() function to obtain the human-readable error message + ** equivalent to errno. Otherwise, use strerror_r(). + */ +#if SQLITE_THREADSAFE && defined(HAVE_STRERROR_R) + char aErr[80]; + memset(aErr, 0, sizeof(aErr)); + zErr = aErr; + + /* If STRERROR_R_CHAR_P (set by autoconf scripts) or __USE_GNU is defined, + ** assume that the system provides the the GNU version of strerror_r() that + ** returns a pointer to a buffer containing the error message. That pointer + ** may point to aErr[], or it may point to some static storage somewhere. + ** Otherwise, assume that the system provides the POSIX version of + ** strerror_r(), which always writes an error message into aErr[]. + ** + ** If the code incorrectly assumes that it is the POSIX version that is + ** available, the error message will often be an empty string. Not a + ** huge problem. Incorrectly concluding that the GNU version is available + ** could lead to a segfault though. + */ +#if defined(STRERROR_R_CHAR_P) || defined(__USE_GNU) + zErr = +# endif + strerror_r(iErrno, aErr, sizeof(aErr)-1); + +#elif SQLITE_THREADSAFE + /* This is a threadsafe build, but strerror_r() is not available. */ + zErr = ""; +#else + /* Non-threadsafe build, use strerror(). */ + zErr = strerror(iErrno); +#endif + + assert( errcode!=SQLITE_OK ); + if( zPath==0 ) zPath = ""; + sqlite3_log(errcode, + "os_unix.c:%d: (%d) %s(%s) - %s", + iLine, iErrno, zFunc, zPath, zErr + ); + + return errcode; +} + +/* +** Close a file descriptor. +** +** We assume that close() almost always works, since it is only in a +** very sick application or on a very sick platform that it might fail. +** If it does fail, simply leak the file descriptor, but do log the +** error. +** +** Note that it is not safe to retry close() after EINTR since the +** file descriptor might have already been reused by another thread. +** So we don't even try to recover from an EINTR. Just log the error +** and move on. +*/ +static void robust_close(unixFile *pFile, int h, int lineno){ + if( osClose(h) ){ + unixLogErrorAtLine(SQLITE_IOERR_CLOSE, "close", + pFile ? pFile->zPath : 0, lineno); + } +} + +/* +** Close all file descriptors accumuated in the unixInodeInfo->pUnused list. +*/ +static void closePendingFds(unixFile *pFile){ + unixInodeInfo *pInode = pFile->pInode; + UnixUnusedFd *p; + UnixUnusedFd *pNext; + for(p=pInode->pUnused; p; p=pNext){ + pNext = p->pNext; + robust_close(pFile, p->fd, __LINE__); + sqlite3_free(p); + } + pInode->pUnused = 0; +} + +/* +** Release a unixInodeInfo structure previously allocated by findInodeInfo(). +** +** The mutex entered using the unixEnterMutex() function must be held +** when this function is called. +*/ +static void releaseInodeInfo(unixFile *pFile){ + unixInodeInfo *pInode = pFile->pInode; + assert( unixMutexHeld() ); + if( ALWAYS(pInode) ){ + pInode->nRef--; + if( pInode->nRef==0 ){ + assert( pInode->pShmNode==0 ); + closePendingFds(pFile); + if( pInode->pPrev ){ + assert( pInode->pPrev->pNext==pInode ); + pInode->pPrev->pNext = pInode->pNext; + }else{ + assert( inodeList==pInode ); + inodeList = pInode->pNext; + } + if( pInode->pNext ){ + assert( pInode->pNext->pPrev==pInode ); + pInode->pNext->pPrev = pInode->pPrev; + } + sqlite3_free(pInode); + } + } +} + +/* +** Given a file descriptor, locate the unixInodeInfo object that +** describes that file descriptor. Create a new one if necessary. The +** return value might be uninitialized if an error occurs. +** +** The mutex entered using the unixEnterMutex() function must be held +** when this function is called. +** +** Return an appropriate error code. +*/ +static int findInodeInfo( + unixFile *pFile, /* Unix file with file desc used in the key */ + unixInodeInfo **ppInode /* Return the unixInodeInfo object here */ +){ + int rc; /* System call return code */ + int fd; /* The file descriptor for pFile */ + struct unixFileId fileId; /* Lookup key for the unixInodeInfo */ + struct stat statbuf; /* Low-level file information */ + unixInodeInfo *pInode = 0; /* Candidate unixInodeInfo object */ + + assert( unixMutexHeld() ); + + /* Get low-level information about the file that we can used to + ** create a unique name for the file. + */ + fd = pFile->h; + rc = osFstat(fd, &statbuf); + if( rc!=0 ){ + pFile->lastErrno = errno; +#ifdef EOVERFLOW + if( pFile->lastErrno==EOVERFLOW ) return SQLITE_NOLFS; +#endif + return SQLITE_IOERR; + } + +#ifdef __APPLE__ + /* On OS X on an msdos filesystem, the inode number is reported + ** incorrectly for zero-size files. See ticket #3260. To work + ** around this problem (we consider it a bug in OS X, not SQLite) + ** we always increase the file size to 1 by writing a single byte + ** prior to accessing the inode number. The one byte written is + ** an ASCII 'S' character which also happens to be the first byte + ** in the header of every SQLite database. In this way, if there + ** is a race condition such that another thread has already populated + ** the first page of the database, no damage is done. + */ + if( statbuf.st_size==0 && (pFile->fsFlags & SQLITE_FSFLAGS_IS_MSDOS)!=0 ){ + do{ rc = osWrite(fd, "S", 1); }while( rc<0 && errno==EINTR ); + if( rc!=1 ){ + pFile->lastErrno = errno; + return SQLITE_IOERR; + } + rc = osFstat(fd, &statbuf); + if( rc!=0 ){ + pFile->lastErrno = errno; + return SQLITE_IOERR; + } + } +#endif + + memset(&fileId, 0, sizeof(fileId)); + fileId.dev = statbuf.st_dev; +#if OS_VXWORKS + fileId.pId = pFile->pId; +#else + fileId.ino = statbuf.st_ino; +#endif + pInode = inodeList; + while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){ + pInode = pInode->pNext; + } + if( pInode==0 ){ + pInode = sqlite3_malloc( sizeof(*pInode) ); + if( pInode==0 ){ + return SQLITE_NOMEM; + } + memset(pInode, 0, sizeof(*pInode)); + memcpy(&pInode->fileId, &fileId, sizeof(fileId)); + pInode->nRef = 1; + pInode->pNext = inodeList; + pInode->pPrev = 0; + if( inodeList ) inodeList->pPrev = pInode; + inodeList = pInode; + }else{ + pInode->nRef++; + } + *ppInode = pInode; + return SQLITE_OK; +} + + +/* +** This routine checks if there is a RESERVED lock held on the specified +** file by this or any other process. If such a lock is held, set *pResOut +** to a non-zero value otherwise *pResOut is set to zero. The return value +** is set to SQLITE_OK unless an I/O error occurs during lock checking. +*/ +static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){ + int rc = SQLITE_OK; + int reserved = 0; + unixFile *pFile = (unixFile*)id; + + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); + + assert( pFile ); + unixEnterMutex(); /* Because pFile->pInode is shared across threads */ + + /* Check if a thread in this process holds such a lock */ + if( pFile->pInode->eFileLock>SHARED_LOCK ){ + reserved = 1; + } + + /* Otherwise see if some other process holds it. + */ +#ifndef __DJGPP__ + if( !reserved && !pFile->pInode->bProcessLock ){ + struct flock lock; + lock.l_whence = SEEK_SET; + lock.l_start = RESERVED_BYTE; + lock.l_len = 1; + lock.l_type = F_WRLCK; + if( osFcntl(pFile->h, F_GETLK, &lock) ){ + rc = SQLITE_IOERR_CHECKRESERVEDLOCK; + pFile->lastErrno = errno; + } else if( lock.l_type!=F_UNLCK ){ + reserved = 1; + } + } +#endif + + unixLeaveMutex(); + OSTRACE(("TEST WR-LOCK %d %d %d (unix)\n", pFile->h, rc, reserved)); + + *pResOut = reserved; + return rc; +} + +/* +** Attempt to set a system-lock on the file pFile. The lock is +** described by pLock. +** +** If the pFile was opened read/write from unix-excl, then the only lock +** ever obtained is an exclusive lock, and it is obtained exactly once +** the first time any lock is attempted. All subsequent system locking +** operations become no-ops. Locking operations still happen internally, +** in order to coordinate access between separate database connections +** within this process, but all of that is handled in memory and the +** operating system does not participate. +** +** This function is a pass-through to fcntl(F_SETLK) if pFile is using +** any VFS other than "unix-excl" or if pFile is opened on "unix-excl" +** and is read-only. +** +** Zero is returned if the call completes successfully, or -1 if a call +** to fcntl() fails. In this case, errno is set appropriately (by fcntl()). +*/ +static int unixFileLock(unixFile *pFile, struct flock *pLock){ + int rc; + unixInodeInfo *pInode = pFile->pInode; + assert( unixMutexHeld() ); + assert( pInode!=0 ); + if( ((pFile->ctrlFlags & UNIXFILE_EXCL)!=0 || pInode->bProcessLock) + && ((pFile->ctrlFlags & UNIXFILE_RDONLY)==0) + ){ + if( pInode->bProcessLock==0 ){ + struct flock lock; + assert( pInode->nLock==0 ); + lock.l_whence = SEEK_SET; + lock.l_start = SHARED_FIRST; + lock.l_len = SHARED_SIZE; + lock.l_type = F_WRLCK; + rc = osFcntl(pFile->h, F_SETLK, &lock); + if( rc<0 ) return rc; + pInode->bProcessLock = 1; + pInode->nLock++; + }else{ + rc = 0; + } + }else{ + rc = osFcntl(pFile->h, F_SETLK, pLock); + } + return rc; +} + +/* +** Lock the file with the lock specified by parameter eFileLock - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** SHARED -> (PENDING) -> EXCLUSIVE +** RESERVED -> (PENDING) -> EXCLUSIVE +** PENDING -> EXCLUSIVE +** +** This routine will only increase a lock. Use the sqlite3OsUnlock() +** routine to lower a locking level. +*/ +static int unixLock(sqlite3_file *id, int eFileLock){ + /* The following describes the implementation of the various locks and + ** lock transitions in terms of the POSIX advisory shared and exclusive + ** lock primitives (called read-locks and write-locks below, to avoid + ** confusion with SQLite lock names). The algorithms are complicated + ** slightly in order to be compatible with windows systems simultaneously + ** accessing the same database file, in case that is ever required. + ** + ** Symbols defined in os.h indentify the 'pending byte' and the 'reserved + ** byte', each single bytes at well known offsets, and the 'shared byte + ** range', a range of 510 bytes at a well known offset. + ** + ** To obtain a SHARED lock, a read-lock is obtained on the 'pending + ** byte'. If this is successful, a random byte from the 'shared byte + ** range' is read-locked and the lock on the 'pending byte' released. + ** + ** A process may only obtain a RESERVED lock after it has a SHARED lock. + ** A RESERVED lock is implemented by grabbing a write-lock on the + ** 'reserved byte'. + ** + ** A process may only obtain a PENDING lock after it has obtained a + ** SHARED lock. A PENDING lock is implemented by obtaining a write-lock + ** on the 'pending byte'. This ensures that no new SHARED locks can be + ** obtained, but existing SHARED locks are allowed to persist. A process + ** does not have to obtain a RESERVED lock on the way to a PENDING lock. + ** This property is used by the algorithm for rolling back a journal file + ** after a crash. + ** + ** An EXCLUSIVE lock, obtained after a PENDING lock is held, is + ** implemented by obtaining a write-lock on the entire 'shared byte + ** range'. Since all other locks require a read-lock on one of the bytes + ** within this range, this ensures that no other locks are held on the + ** database. + ** + ** The reason a single byte cannot be used instead of the 'shared byte + ** range' is that some versions of windows do not support read-locks. By + ** locking a random byte from a range, concurrent SHARED locks may exist + ** even if the locking primitive used is always a write-lock. + */ + int rc = SQLITE_OK; + unixFile *pFile = (unixFile*)id; + unixInodeInfo *pInode; + struct flock lock; + int tErrno = 0; + + assert( pFile ); + OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (unix)\n", pFile->h, + azFileLock(eFileLock), azFileLock(pFile->eFileLock), + azFileLock(pFile->pInode->eFileLock), pFile->pInode->nShared , getpid())); + + /* If there is already a lock of this type or more restrictive on the + ** unixFile, do nothing. Don't use the end_lock: exit path, as + ** unixEnterMutex() hasn't been called yet. + */ + if( pFile->eFileLock>=eFileLock ){ + OSTRACE(("LOCK %d %s ok (already held) (unix)\n", pFile->h, + azFileLock(eFileLock))); + return SQLITE_OK; + } + + /* Make sure the locking sequence is correct. + ** (1) We never move from unlocked to anything higher than shared lock. + ** (2) SQLite never explicitly requests a pendig lock. + ** (3) A shared lock is always held when a reserve lock is requested. + */ + assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK ); + assert( eFileLock!=PENDING_LOCK ); + assert( eFileLock!=RESERVED_LOCK || pFile->eFileLock==SHARED_LOCK ); + + /* This mutex is needed because pFile->pInode is shared across threads + */ + unixEnterMutex(); + pInode = pFile->pInode; + + /* If some thread using this PID has a lock via a different unixFile* + ** handle that precludes the requested lock, return BUSY. + */ + if( (pFile->eFileLock!=pInode->eFileLock && + (pInode->eFileLock>=PENDING_LOCK || eFileLock>SHARED_LOCK)) + ){ + rc = SQLITE_BUSY; + goto end_lock; + } + + /* If a SHARED lock is requested, and some thread using this PID already + ** has a SHARED or RESERVED lock, then increment reference counts and + ** return SQLITE_OK. + */ + if( eFileLock==SHARED_LOCK && + (pInode->eFileLock==SHARED_LOCK || pInode->eFileLock==RESERVED_LOCK) ){ + assert( eFileLock==SHARED_LOCK ); + assert( pFile->eFileLock==0 ); + assert( pInode->nShared>0 ); + pFile->eFileLock = SHARED_LOCK; + pInode->nShared++; + pInode->nLock++; + goto end_lock; + } + + + /* A PENDING lock is needed before acquiring a SHARED lock and before + ** acquiring an EXCLUSIVE lock. For the SHARED lock, the PENDING will + ** be released. + */ + lock.l_len = 1L; + lock.l_whence = SEEK_SET; + if( eFileLock==SHARED_LOCK + || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLocklastErrno = tErrno; + } + goto end_lock; + } + } + + + /* If control gets to this point, then actually go ahead and make + ** operating system calls for the specified lock. + */ + if( eFileLock==SHARED_LOCK ){ + assert( pInode->nShared==0 ); + assert( pInode->eFileLock==0 ); + assert( rc==SQLITE_OK ); + + /* Now get the read-lock */ + lock.l_start = SHARED_FIRST; + lock.l_len = SHARED_SIZE; + if( unixFileLock(pFile, &lock) ){ + tErrno = errno; + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); + } + + /* Drop the temporary PENDING lock */ + lock.l_start = PENDING_BYTE; + lock.l_len = 1L; + lock.l_type = F_UNLCK; + if( unixFileLock(pFile, &lock) && rc==SQLITE_OK ){ + /* This could happen with a network mount */ + tErrno = errno; + rc = SQLITE_IOERR_UNLOCK; + } + + if( rc ){ + if( rc!=SQLITE_BUSY ){ + pFile->lastErrno = tErrno; + } + goto end_lock; + }else{ + pFile->eFileLock = SHARED_LOCK; + pInode->nLock++; + pInode->nShared = 1; + } + }else if( eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1 ){ + /* We are trying for an exclusive lock but another thread in this + ** same process is still holding a shared lock. */ + rc = SQLITE_BUSY; + }else{ + /* The request was for a RESERVED or EXCLUSIVE lock. It is + ** assumed that there is a SHARED or greater lock on the file + ** already. + */ + assert( 0!=pFile->eFileLock ); + lock.l_type = F_WRLCK; + + assert( eFileLock==RESERVED_LOCK || eFileLock==EXCLUSIVE_LOCK ); + if( eFileLock==RESERVED_LOCK ){ + lock.l_start = RESERVED_BYTE; + lock.l_len = 1L; + }else{ + lock.l_start = SHARED_FIRST; + lock.l_len = SHARED_SIZE; + } + + if( unixFileLock(pFile, &lock) ){ + tErrno = errno; + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); + if( rc!=SQLITE_BUSY ){ + pFile->lastErrno = tErrno; + } + } + } + + +#ifndef NDEBUG + /* Set up the transaction-counter change checking flags when + ** transitioning from a SHARED to a RESERVED lock. The change + ** from SHARED to RESERVED marks the beginning of a normal + ** write operation (not a hot journal rollback). + */ + if( rc==SQLITE_OK + && pFile->eFileLock<=SHARED_LOCK + && eFileLock==RESERVED_LOCK + ){ + pFile->transCntrChng = 0; + pFile->dbUpdate = 0; + pFile->inNormalWrite = 1; + } +#endif + + + if( rc==SQLITE_OK ){ + pFile->eFileLock = eFileLock; + pInode->eFileLock = eFileLock; + }else if( eFileLock==EXCLUSIVE_LOCK ){ + pFile->eFileLock = PENDING_LOCK; + pInode->eFileLock = PENDING_LOCK; + } + +end_lock: + unixLeaveMutex(); + OSTRACE(("LOCK %d %s %s (unix)\n", pFile->h, azFileLock(eFileLock), + rc==SQLITE_OK ? "ok" : "failed")); + return rc; +} + +/* +** Add the file descriptor used by file handle pFile to the corresponding +** pUnused list. +*/ +static void setPendingFd(unixFile *pFile){ + unixInodeInfo *pInode = pFile->pInode; + UnixUnusedFd *p = pFile->pUnused; + p->pNext = pInode->pUnused; + pInode->pUnused = p; + pFile->h = -1; + pFile->pUnused = 0; +} + +/* +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock +** must be either NO_LOCK or SHARED_LOCK. +** +** If the locking level of the file descriptor is already at or below +** the requested locking level, this routine is a no-op. +** +** If handleNFSUnlock is true, then on downgrading an EXCLUSIVE_LOCK to SHARED +** the byte range is divided into 2 parts and the first part is unlocked then +** set to a read lock, then the other part is simply unlocked. This works +** around a bug in BSD NFS lockd (also seen on MacOSX 10.3+) that fails to +** remove the write lock on a region when a read lock is set. +*/ +static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ + unixFile *pFile = (unixFile*)id; + unixInodeInfo *pInode; + struct flock lock; + int rc = SQLITE_OK; + + assert( pFile ); + OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (unix)\n", pFile->h, eFileLock, + pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared, + getpid())); + + assert( eFileLock<=SHARED_LOCK ); + if( pFile->eFileLock<=eFileLock ){ + return SQLITE_OK; + } + unixEnterMutex(); + pInode = pFile->pInode; + assert( pInode->nShared!=0 ); + if( pFile->eFileLock>SHARED_LOCK ){ + assert( pInode->eFileLock==pFile->eFileLock ); + +#ifndef NDEBUG + /* When reducing a lock such that other processes can start + ** reading the database file again, make sure that the + ** transaction counter was updated if any part of the database + ** file changed. If the transaction counter is not updated, + ** other connections to the same file might not realize that + ** the file has changed and hence might not know to flush their + ** cache. The use of a stale cache can lead to database corruption. + */ + pFile->inNormalWrite = 0; +#endif + + /* downgrading to a shared lock on NFS involves clearing the write lock + ** before establishing the readlock - to avoid a race condition we downgrade + ** the lock in 2 blocks, so that part of the range will be covered by a + ** write lock until the rest is covered by a read lock: + ** 1: [WWWWW] + ** 2: [....W] + ** 3: [RRRRW] + ** 4: [RRRR.] + */ + if( eFileLock==SHARED_LOCK ){ + +#if !defined(__APPLE__) || !SQLITE_ENABLE_LOCKING_STYLE + (void)handleNFSUnlock; + assert( handleNFSUnlock==0 ); +#endif +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE + if( handleNFSUnlock ){ + int tErrno; /* Error code from system call errors */ + off_t divSize = SHARED_SIZE - 1; + + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + lock.l_start = SHARED_FIRST; + lock.l_len = divSize; + if( unixFileLock(pFile, &lock)==(-1) ){ + tErrno = errno; + rc = SQLITE_IOERR_UNLOCK; + if( IS_LOCK_ERROR(rc) ){ + pFile->lastErrno = tErrno; + } + goto end_unlock; + } + lock.l_type = F_RDLCK; + lock.l_whence = SEEK_SET; + lock.l_start = SHARED_FIRST; + lock.l_len = divSize; + if( unixFileLock(pFile, &lock)==(-1) ){ + tErrno = errno; + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK); + if( IS_LOCK_ERROR(rc) ){ + pFile->lastErrno = tErrno; + } + goto end_unlock; + } + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + lock.l_start = SHARED_FIRST+divSize; + lock.l_len = SHARED_SIZE-divSize; + if( unixFileLock(pFile, &lock)==(-1) ){ + tErrno = errno; + rc = SQLITE_IOERR_UNLOCK; + if( IS_LOCK_ERROR(rc) ){ + pFile->lastErrno = tErrno; + } + goto end_unlock; + } + }else +#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ + { + lock.l_type = F_RDLCK; + lock.l_whence = SEEK_SET; + lock.l_start = SHARED_FIRST; + lock.l_len = SHARED_SIZE; + if( unixFileLock(pFile, &lock) ){ + /* In theory, the call to unixFileLock() cannot fail because another + ** process is holding an incompatible lock. If it does, this + ** indicates that the other process is not following the locking + ** protocol. If this happens, return SQLITE_IOERR_RDLOCK. Returning + ** SQLITE_BUSY would confuse the upper layer (in practice it causes + ** an assert to fail). */ + rc = SQLITE_IOERR_RDLOCK; + pFile->lastErrno = errno; + goto end_unlock; + } + } + } + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + lock.l_start = PENDING_BYTE; + lock.l_len = 2L; assert( PENDING_BYTE+1==RESERVED_BYTE ); + if( unixFileLock(pFile, &lock)==0 ){ + pInode->eFileLock = SHARED_LOCK; + }else{ + rc = SQLITE_IOERR_UNLOCK; + pFile->lastErrno = errno; + goto end_unlock; + } + } + if( eFileLock==NO_LOCK ){ + /* Decrement the shared lock counter. Release the lock using an + ** OS call only when all threads in this same process have released + ** the lock. + */ + pInode->nShared--; + if( pInode->nShared==0 ){ + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + lock.l_start = lock.l_len = 0L; + if( unixFileLock(pFile, &lock)==0 ){ + pInode->eFileLock = NO_LOCK; + }else{ + rc = SQLITE_IOERR_UNLOCK; + pFile->lastErrno = errno; + pInode->eFileLock = NO_LOCK; + pFile->eFileLock = NO_LOCK; + } + } + + /* Decrement the count of locks against this same file. When the + ** count reaches zero, close any other file descriptors whose close + ** was deferred because of outstanding locks. + */ + pInode->nLock--; + assert( pInode->nLock>=0 ); + if( pInode->nLock==0 ){ + closePendingFds(pFile); + } + } + +end_unlock: + unixLeaveMutex(); + if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock; + return rc; +} + +/* +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock +** must be either NO_LOCK or SHARED_LOCK. +** +** If the locking level of the file descriptor is already at or below +** the requested locking level, this routine is a no-op. +*/ +static int unixUnlock(sqlite3_file *id, int eFileLock){ + return posixUnlock(id, eFileLock, 0); +} + +/* +** This function performs the parts of the "close file" operation +** common to all locking schemes. It closes the directory and file +** handles, if they are valid, and sets all fields of the unixFile +** structure to 0. +** +** It is *not* necessary to hold the mutex when this routine is called, +** even on VxWorks. A mutex will be acquired on VxWorks by the +** vxworksReleaseFileId() routine. +*/ +static int closeUnixFile(sqlite3_file *id){ + unixFile *pFile = (unixFile*)id; + if( pFile->h>=0 ){ + robust_close(pFile, pFile->h, __LINE__); + pFile->h = -1; + } +#if OS_VXWORKS + if( pFile->pId ){ + if( pFile->ctrlFlags & UNIXFILE_DELETE ){ + osUnlink(pFile->pId->zCanonicalName); + } + vxworksReleaseFileId(pFile->pId); + pFile->pId = 0; + } +#endif + OSTRACE(("CLOSE %-3d\n", pFile->h)); + OpenCounter(-1); + sqlite3_free(pFile->pUnused); + memset(pFile, 0, sizeof(unixFile)); + return SQLITE_OK; +} + +/* +** Close a file. +*/ +static int unixClose(sqlite3_file *id){ + int rc = SQLITE_OK; + unixFile *pFile = (unixFile *)id; + unixUnlock(id, NO_LOCK); + unixEnterMutex(); + + /* unixFile.pInode is always valid here. Otherwise, a different close + ** routine (e.g. nolockClose()) would be called instead. + */ + assert( pFile->pInode->nLock>0 || pFile->pInode->bProcessLock==0 ); + if( ALWAYS(pFile->pInode) && pFile->pInode->nLock ){ + /* If there are outstanding locks, do not actually close the file just + ** yet because that would clear those locks. Instead, add the file + ** descriptor to pInode->pUnused list. It will be automatically closed + ** when the last lock is cleared. + */ + setPendingFd(pFile); + } + releaseInodeInfo(pFile); + rc = closeUnixFile(id); + unixLeaveMutex(); + return rc; +} + +/************** End of the posix advisory lock implementation ***************** +******************************************************************************/ + +/****************************************************************************** +****************************** No-op Locking ********************************** +** +** Of the various locking implementations available, this is by far the +** simplest: locking is ignored. No attempt is made to lock the database +** file for reading or writing. +** +** This locking mode is appropriate for use on read-only databases +** (ex: databases that are burned into CD-ROM, for example.) It can +** also be used if the application employs some external mechanism to +** prevent simultaneous access of the same database by two or more +** database connections. But there is a serious risk of database +** corruption if this locking mode is used in situations where multiple +** database connections are accessing the same database file at the same +** time and one or more of those connections are writing. +*/ + +static int nolockCheckReservedLock(sqlite3_file *NotUsed, int *pResOut){ + UNUSED_PARAMETER(NotUsed); + *pResOut = 0; + return SQLITE_OK; +} +static int nolockLock(sqlite3_file *NotUsed, int NotUsed2){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + return SQLITE_OK; +} +static int nolockUnlock(sqlite3_file *NotUsed, int NotUsed2){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + return SQLITE_OK; +} + +/* +** Close the file. +*/ +static int nolockClose(sqlite3_file *id) { + return closeUnixFile(id); +} + +/******************* End of the no-op lock implementation ********************* +******************************************************************************/ + +/****************************************************************************** +************************* Begin dot-file Locking ****************************** +** +** The dotfile locking implementation uses the existance of separate lock +** files (really a directory) to control access to the database. This works +** on just about every filesystem imaginable. But there are serious downsides: +** +** (1) There is zero concurrency. A single reader blocks all other +** connections from reading or writing the database. +** +** (2) An application crash or power loss can leave stale lock files +** sitting around that need to be cleared manually. +** +** Nevertheless, a dotlock is an appropriate locking mode for use if no +** other locking strategy is available. +** +** Dotfile locking works by creating a subdirectory in the same directory as +** the database and with the same name but with a ".lock" extension added. +** The existance of a lock directory implies an EXCLUSIVE lock. All other +** lock types (SHARED, RESERVED, PENDING) are mapped into EXCLUSIVE. +*/ + +/* +** The file suffix added to the data base filename in order to create the +** lock directory. +*/ +#define DOTLOCK_SUFFIX ".lock" + +/* +** This routine checks if there is a RESERVED lock held on the specified +** file by this or any other process. If such a lock is held, set *pResOut +** to a non-zero value otherwise *pResOut is set to zero. The return value +** is set to SQLITE_OK unless an I/O error occurs during lock checking. +** +** In dotfile locking, either a lock exists or it does not. So in this +** variation of CheckReservedLock(), *pResOut is set to true if any lock +** is held on the file and false if the file is unlocked. +*/ +static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) { + int rc = SQLITE_OK; + int reserved = 0; + unixFile *pFile = (unixFile*)id; + + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); + + assert( pFile ); + + /* Check if a thread in this process holds such a lock */ + if( pFile->eFileLock>SHARED_LOCK ){ + /* Either this connection or some other connection in the same process + ** holds a lock on the file. No need to check further. */ + reserved = 1; + }else{ + /* The lock is held if and only if the lockfile exists */ + const char *zLockFile = (const char*)pFile->lockingContext; + reserved = osAccess(zLockFile, 0)==0; + } + OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved)); + *pResOut = reserved; + return rc; +} + +/* +** Lock the file with the lock specified by parameter eFileLock - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** SHARED -> (PENDING) -> EXCLUSIVE +** RESERVED -> (PENDING) -> EXCLUSIVE +** PENDING -> EXCLUSIVE +** +** This routine will only increase a lock. Use the sqlite3OsUnlock() +** routine to lower a locking level. +** +** With dotfile locking, we really only support state (4): EXCLUSIVE. +** But we track the other locking levels internally. +*/ +static int dotlockLock(sqlite3_file *id, int eFileLock) { + unixFile *pFile = (unixFile*)id; + char *zLockFile = (char *)pFile->lockingContext; + int rc = SQLITE_OK; + + + /* If we have any lock, then the lock file already exists. All we have + ** to do is adjust our internal record of the lock level. + */ + if( pFile->eFileLock > NO_LOCK ){ + pFile->eFileLock = eFileLock; + /* Always update the timestamp on the old file */ +#ifdef HAVE_UTIME + utime(zLockFile, NULL); +#else + utimes(zLockFile, NULL); +#endif + return SQLITE_OK; + } + + /* grab an exclusive lock */ + rc = osMkdir(zLockFile, 0777); + if( rc<0 ){ + /* failed to open/create the lock directory */ + int tErrno = errno; + if( EEXIST == tErrno ){ + rc = SQLITE_BUSY; + } else { + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); + if( IS_LOCK_ERROR(rc) ){ + pFile->lastErrno = tErrno; + } + } + return rc; + } + + /* got it, set the type and return ok */ + pFile->eFileLock = eFileLock; + return rc; +} + +/* +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock +** must be either NO_LOCK or SHARED_LOCK. +** +** If the locking level of the file descriptor is already at or below +** the requested locking level, this routine is a no-op. +** +** When the locking level reaches NO_LOCK, delete the lock file. +*/ +static int dotlockUnlock(sqlite3_file *id, int eFileLock) { + unixFile *pFile = (unixFile*)id; + char *zLockFile = (char *)pFile->lockingContext; + int rc; + + assert( pFile ); + OSTRACE(("UNLOCK %d %d was %d pid=%d (dotlock)\n", pFile->h, eFileLock, + pFile->eFileLock, getpid())); + assert( eFileLock<=SHARED_LOCK ); + + /* no-op if possible */ + if( pFile->eFileLock==eFileLock ){ + return SQLITE_OK; + } + + /* To downgrade to shared, simply update our internal notion of the + ** lock state. No need to mess with the file on disk. + */ + if( eFileLock==SHARED_LOCK ){ + pFile->eFileLock = SHARED_LOCK; + return SQLITE_OK; + } + + /* To fully unlock the database, delete the lock file */ + assert( eFileLock==NO_LOCK ); + rc = osRmdir(zLockFile); + if( rc<0 && errno==ENOTDIR ) rc = osUnlink(zLockFile); + if( rc<0 ){ + int tErrno = errno; + rc = 0; + if( ENOENT != tErrno ){ + rc = SQLITE_IOERR_UNLOCK; + } + if( IS_LOCK_ERROR(rc) ){ + pFile->lastErrno = tErrno; + } + return rc; + } + pFile->eFileLock = NO_LOCK; + return SQLITE_OK; +} + +/* +** Close a file. Make sure the lock has been released before closing. +*/ +static int dotlockClose(sqlite3_file *id) { + int rc; + if( id ){ + unixFile *pFile = (unixFile*)id; + dotlockUnlock(id, NO_LOCK); + sqlite3_free(pFile->lockingContext); + } + rc = closeUnixFile(id); + return rc; +} +/****************** End of the dot-file lock implementation ******************* +******************************************************************************/ + +/****************************************************************************** +************************** Begin flock Locking ******************************** +** +** Use the flock() system call to do file locking. +** +** flock() locking is like dot-file locking in that the various +** fine-grain locking levels supported by SQLite are collapsed into +** a single exclusive lock. In other words, SHARED, RESERVED, and +** PENDING locks are the same thing as an EXCLUSIVE lock. SQLite +** still works when you do this, but concurrency is reduced since +** only a single process can be reading the database at a time. +** +** Omit this section if SQLITE_ENABLE_LOCKING_STYLE is turned off or if +** compiling for VXWORKS. +*/ +#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS + +/* +** Retry flock() calls that fail with EINTR +*/ +#ifdef EINTR +static int robust_flock(int fd, int op){ + int rc; + do{ rc = flock(fd,op); }while( rc<0 && errno==EINTR ); + return rc; +} +#else +# define robust_flock(a,b) flock(a,b) +#endif + + +/* +** This routine checks if there is a RESERVED lock held on the specified +** file by this or any other process. If such a lock is held, set *pResOut +** to a non-zero value otherwise *pResOut is set to zero. The return value +** is set to SQLITE_OK unless an I/O error occurs during lock checking. +*/ +static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){ + int rc = SQLITE_OK; + int reserved = 0; + unixFile *pFile = (unixFile*)id; + + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); + + assert( pFile ); + + /* Check if a thread in this process holds such a lock */ + if( pFile->eFileLock>SHARED_LOCK ){ + reserved = 1; + } + + /* Otherwise see if some other process holds it. */ + if( !reserved ){ + /* attempt to get the lock */ + int lrc = robust_flock(pFile->h, LOCK_EX | LOCK_NB); + if( !lrc ){ + /* got the lock, unlock it */ + lrc = robust_flock(pFile->h, LOCK_UN); + if ( lrc ) { + int tErrno = errno; + /* unlock failed with an error */ + lrc = SQLITE_IOERR_UNLOCK; + if( IS_LOCK_ERROR(lrc) ){ + pFile->lastErrno = tErrno; + rc = lrc; + } + } + } else { + int tErrno = errno; + reserved = 1; + /* someone else might have it reserved */ + lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); + if( IS_LOCK_ERROR(lrc) ){ + pFile->lastErrno = tErrno; + rc = lrc; + } + } + } + OSTRACE(("TEST WR-LOCK %d %d %d (flock)\n", pFile->h, rc, reserved)); + +#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS + if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){ + rc = SQLITE_OK; + reserved=1; + } +#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ + *pResOut = reserved; + return rc; +} + +/* +** Lock the file with the lock specified by parameter eFileLock - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** SHARED -> (PENDING) -> EXCLUSIVE +** RESERVED -> (PENDING) -> EXCLUSIVE +** PENDING -> EXCLUSIVE +** +** flock() only really support EXCLUSIVE locks. We track intermediate +** lock states in the sqlite3_file structure, but all locks SHARED or +** above are really EXCLUSIVE locks and exclude all other processes from +** access the file. +** +** This routine will only increase a lock. Use the sqlite3OsUnlock() +** routine to lower a locking level. +*/ +static int flockLock(sqlite3_file *id, int eFileLock) { + int rc = SQLITE_OK; + unixFile *pFile = (unixFile*)id; + + assert( pFile ); + + /* if we already have a lock, it is exclusive. + ** Just adjust level and punt on outta here. */ + if (pFile->eFileLock > NO_LOCK) { + pFile->eFileLock = eFileLock; + return SQLITE_OK; + } + + /* grab an exclusive lock */ + + if (robust_flock(pFile->h, LOCK_EX | LOCK_NB)) { + int tErrno = errno; + /* didn't get, must be busy */ + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); + if( IS_LOCK_ERROR(rc) ){ + pFile->lastErrno = tErrno; + } + } else { + /* got it, set the type and return ok */ + pFile->eFileLock = eFileLock; + } + OSTRACE(("LOCK %d %s %s (flock)\n", pFile->h, azFileLock(eFileLock), + rc==SQLITE_OK ? "ok" : "failed")); +#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS + if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){ + rc = SQLITE_BUSY; + } +#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ + return rc; +} + + +/* +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock +** must be either NO_LOCK or SHARED_LOCK. +** +** If the locking level of the file descriptor is already at or below +** the requested locking level, this routine is a no-op. +*/ +static int flockUnlock(sqlite3_file *id, int eFileLock) { + unixFile *pFile = (unixFile*)id; + + assert( pFile ); + OSTRACE(("UNLOCK %d %d was %d pid=%d (flock)\n", pFile->h, eFileLock, + pFile->eFileLock, getpid())); + assert( eFileLock<=SHARED_LOCK ); + + /* no-op if possible */ + if( pFile->eFileLock==eFileLock ){ + return SQLITE_OK; + } + + /* shared can just be set because we always have an exclusive */ + if (eFileLock==SHARED_LOCK) { + pFile->eFileLock = eFileLock; + return SQLITE_OK; + } + + /* no, really, unlock. */ + if( robust_flock(pFile->h, LOCK_UN) ){ +#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS + return SQLITE_OK; +#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ + return SQLITE_IOERR_UNLOCK; + }else{ + pFile->eFileLock = NO_LOCK; + return SQLITE_OK; + } +} + +/* +** Close a file. +*/ +static int flockClose(sqlite3_file *id) { + if( id ){ + flockUnlock(id, NO_LOCK); + } + return closeUnixFile(id); +} + +#endif /* SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORK */ + +/******************* End of the flock lock implementation ********************* +******************************************************************************/ + +/****************************************************************************** +************************ Begin Named Semaphore Locking ************************ +** +** Named semaphore locking is only supported on VxWorks. +** +** Semaphore locking is like dot-lock and flock in that it really only +** supports EXCLUSIVE locking. Only a single process can read or write +** the database file at a time. This reduces potential concurrency, but +** makes the lock implementation much easier. +*/ +#if OS_VXWORKS + +/* +** This routine checks if there is a RESERVED lock held on the specified +** file by this or any other process. If such a lock is held, set *pResOut +** to a non-zero value otherwise *pResOut is set to zero. The return value +** is set to SQLITE_OK unless an I/O error occurs during lock checking. +*/ +static int semCheckReservedLock(sqlite3_file *id, int *pResOut) { + int rc = SQLITE_OK; + int reserved = 0; + unixFile *pFile = (unixFile*)id; + + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); + + assert( pFile ); + + /* Check if a thread in this process holds such a lock */ + if( pFile->eFileLock>SHARED_LOCK ){ + reserved = 1; + } + + /* Otherwise see if some other process holds it. */ + if( !reserved ){ + sem_t *pSem = pFile->pInode->pSem; + struct stat statBuf; + + if( sem_trywait(pSem)==-1 ){ + int tErrno = errno; + if( EAGAIN != tErrno ){ + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK); + pFile->lastErrno = tErrno; + } else { + /* someone else has the lock when we are in NO_LOCK */ + reserved = (pFile->eFileLock < SHARED_LOCK); + } + }else{ + /* we could have it if we want it */ + sem_post(pSem); + } + } + OSTRACE(("TEST WR-LOCK %d %d %d (sem)\n", pFile->h, rc, reserved)); + + *pResOut = reserved; + return rc; +} + +/* +** Lock the file with the lock specified by parameter eFileLock - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** SHARED -> (PENDING) -> EXCLUSIVE +** RESERVED -> (PENDING) -> EXCLUSIVE +** PENDING -> EXCLUSIVE +** +** Semaphore locks only really support EXCLUSIVE locks. We track intermediate +** lock states in the sqlite3_file structure, but all locks SHARED or +** above are really EXCLUSIVE locks and exclude all other processes from +** access the file. +** +** This routine will only increase a lock. Use the sqlite3OsUnlock() +** routine to lower a locking level. +*/ +static int semLock(sqlite3_file *id, int eFileLock) { + unixFile *pFile = (unixFile*)id; + int fd; + sem_t *pSem = pFile->pInode->pSem; + int rc = SQLITE_OK; + + /* if we already have a lock, it is exclusive. + ** Just adjust level and punt on outta here. */ + if (pFile->eFileLock > NO_LOCK) { + pFile->eFileLock = eFileLock; + rc = SQLITE_OK; + goto sem_end_lock; + } + + /* lock semaphore now but bail out when already locked. */ + if( sem_trywait(pSem)==-1 ){ + rc = SQLITE_BUSY; + goto sem_end_lock; + } + + /* got it, set the type and return ok */ + pFile->eFileLock = eFileLock; + + sem_end_lock: + return rc; +} + +/* +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock +** must be either NO_LOCK or SHARED_LOCK. +** +** If the locking level of the file descriptor is already at or below +** the requested locking level, this routine is a no-op. +*/ +static int semUnlock(sqlite3_file *id, int eFileLock) { + unixFile *pFile = (unixFile*)id; + sem_t *pSem = pFile->pInode->pSem; + + assert( pFile ); + assert( pSem ); + OSTRACE(("UNLOCK %d %d was %d pid=%d (sem)\n", pFile->h, eFileLock, + pFile->eFileLock, getpid())); + assert( eFileLock<=SHARED_LOCK ); + + /* no-op if possible */ + if( pFile->eFileLock==eFileLock ){ + return SQLITE_OK; + } + + /* shared can just be set because we always have an exclusive */ + if (eFileLock==SHARED_LOCK) { + pFile->eFileLock = eFileLock; + return SQLITE_OK; + } + + /* no, really unlock. */ + if ( sem_post(pSem)==-1 ) { + int rc, tErrno = errno; + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); + if( IS_LOCK_ERROR(rc) ){ + pFile->lastErrno = tErrno; + } + return rc; + } + pFile->eFileLock = NO_LOCK; + return SQLITE_OK; +} + +/* + ** Close a file. + */ +static int semClose(sqlite3_file *id) { + if( id ){ + unixFile *pFile = (unixFile*)id; + semUnlock(id, NO_LOCK); + assert( pFile ); + unixEnterMutex(); + releaseInodeInfo(pFile); + unixLeaveMutex(); + closeUnixFile(id); + } + return SQLITE_OK; +} + +#endif /* OS_VXWORKS */ +/* +** Named semaphore locking is only available on VxWorks. +** +*************** End of the named semaphore lock implementation **************** +******************************************************************************/ + + +/****************************************************************************** +*************************** Begin AFP Locking ********************************* +** +** AFP is the Apple Filing Protocol. AFP is a network filesystem found +** on Apple Macintosh computers - both OS9 and OSX. +** +** Third-party implementations of AFP are available. But this code here +** only works on OSX. +*/ + +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE +/* +** The afpLockingContext structure contains all afp lock specific state +*/ +typedef struct afpLockingContext afpLockingContext; +struct afpLockingContext { + int reserved; + const char *dbPath; /* Name of the open file */ +}; + +struct ByteRangeLockPB2 +{ + unsigned long long offset; /* offset to first byte to lock */ + unsigned long long length; /* nbr of bytes to lock */ + unsigned long long retRangeStart; /* nbr of 1st byte locked if successful */ + unsigned char unLockFlag; /* 1 = unlock, 0 = lock */ + unsigned char startEndFlag; /* 1=rel to end of fork, 0=rel to start */ + int fd; /* file desc to assoc this lock with */ +}; + +#define afpfsByteRangeLock2FSCTL _IOWR('z', 23, struct ByteRangeLockPB2) + +/* +** This is a utility for setting or clearing a bit-range lock on an +** AFP filesystem. +** +** Return SQLITE_OK on success, SQLITE_BUSY on failure. +*/ +static int afpSetLock( + const char *path, /* Name of the file to be locked or unlocked */ + unixFile *pFile, /* Open file descriptor on path */ + unsigned long long offset, /* First byte to be locked */ + unsigned long long length, /* Number of bytes to lock */ + int setLockFlag /* True to set lock. False to clear lock */ +){ + struct ByteRangeLockPB2 pb; + int err; + + pb.unLockFlag = setLockFlag ? 0 : 1; + pb.startEndFlag = 0; + pb.offset = offset; + pb.length = length; + pb.fd = pFile->h; + + OSTRACE(("AFPSETLOCK [%s] for %d%s in range %llx:%llx\n", + (setLockFlag?"ON":"OFF"), pFile->h, (pb.fd==-1?"[testval-1]":""), + offset, length)); + err = fsctl(path, afpfsByteRangeLock2FSCTL, &pb, 0); + if ( err==-1 ) { + int rc; + int tErrno = errno; + OSTRACE(("AFPSETLOCK failed to fsctl() '%s' %d %s\n", + path, tErrno, strerror(tErrno))); +#ifdef SQLITE_IGNORE_AFP_LOCK_ERRORS + rc = SQLITE_BUSY; +#else + rc = sqliteErrorFromPosixError(tErrno, + setLockFlag ? SQLITE_IOERR_LOCK : SQLITE_IOERR_UNLOCK); +#endif /* SQLITE_IGNORE_AFP_LOCK_ERRORS */ + if( IS_LOCK_ERROR(rc) ){ + pFile->lastErrno = tErrno; + } + return rc; + } else { + return SQLITE_OK; + } +} + +/* +** This routine checks if there is a RESERVED lock held on the specified +** file by this or any other process. If such a lock is held, set *pResOut +** to a non-zero value otherwise *pResOut is set to zero. The return value +** is set to SQLITE_OK unless an I/O error occurs during lock checking. +*/ +static int afpCheckReservedLock(sqlite3_file *id, int *pResOut){ + int rc = SQLITE_OK; + int reserved = 0; + unixFile *pFile = (unixFile*)id; + afpLockingContext *context; + + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); + + assert( pFile ); + context = (afpLockingContext *) pFile->lockingContext; + if( context->reserved ){ + *pResOut = 1; + return SQLITE_OK; + } + unixEnterMutex(); /* Because pFile->pInode is shared across threads */ + + /* Check if a thread in this process holds such a lock */ + if( pFile->pInode->eFileLock>SHARED_LOCK ){ + reserved = 1; + } + + /* Otherwise see if some other process holds it. + */ + if( !reserved ){ + /* lock the RESERVED byte */ + int lrc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1,1); + if( SQLITE_OK==lrc ){ + /* if we succeeded in taking the reserved lock, unlock it to restore + ** the original state */ + lrc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1, 0); + } else { + /* if we failed to get the lock then someone else must have it */ + reserved = 1; + } + if( IS_LOCK_ERROR(lrc) ){ + rc=lrc; + } + } + + unixLeaveMutex(); + OSTRACE(("TEST WR-LOCK %d %d %d (afp)\n", pFile->h, rc, reserved)); + + *pResOut = reserved; + return rc; +} + +/* +** Lock the file with the lock specified by parameter eFileLock - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** SHARED -> (PENDING) -> EXCLUSIVE +** RESERVED -> (PENDING) -> EXCLUSIVE +** PENDING -> EXCLUSIVE +** +** This routine will only increase a lock. Use the sqlite3OsUnlock() +** routine to lower a locking level. +*/ +static int afpLock(sqlite3_file *id, int eFileLock){ + int rc = SQLITE_OK; + unixFile *pFile = (unixFile*)id; + unixInodeInfo *pInode = pFile->pInode; + afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; + + assert( pFile ); + OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (afp)\n", pFile->h, + azFileLock(eFileLock), azFileLock(pFile->eFileLock), + azFileLock(pInode->eFileLock), pInode->nShared , getpid())); + + /* If there is already a lock of this type or more restrictive on the + ** unixFile, do nothing. Don't use the afp_end_lock: exit path, as + ** unixEnterMutex() hasn't been called yet. + */ + if( pFile->eFileLock>=eFileLock ){ + OSTRACE(("LOCK %d %s ok (already held) (afp)\n", pFile->h, + azFileLock(eFileLock))); + return SQLITE_OK; + } + + /* Make sure the locking sequence is correct + ** (1) We never move from unlocked to anything higher than shared lock. + ** (2) SQLite never explicitly requests a pendig lock. + ** (3) A shared lock is always held when a reserve lock is requested. + */ + assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK ); + assert( eFileLock!=PENDING_LOCK ); + assert( eFileLock!=RESERVED_LOCK || pFile->eFileLock==SHARED_LOCK ); + + /* This mutex is needed because pFile->pInode is shared across threads + */ + unixEnterMutex(); + pInode = pFile->pInode; + + /* If some thread using this PID has a lock via a different unixFile* + ** handle that precludes the requested lock, return BUSY. + */ + if( (pFile->eFileLock!=pInode->eFileLock && + (pInode->eFileLock>=PENDING_LOCK || eFileLock>SHARED_LOCK)) + ){ + rc = SQLITE_BUSY; + goto afp_end_lock; + } + + /* If a SHARED lock is requested, and some thread using this PID already + ** has a SHARED or RESERVED lock, then increment reference counts and + ** return SQLITE_OK. + */ + if( eFileLock==SHARED_LOCK && + (pInode->eFileLock==SHARED_LOCK || pInode->eFileLock==RESERVED_LOCK) ){ + assert( eFileLock==SHARED_LOCK ); + assert( pFile->eFileLock==0 ); + assert( pInode->nShared>0 ); + pFile->eFileLock = SHARED_LOCK; + pInode->nShared++; + pInode->nLock++; + goto afp_end_lock; + } + + /* A PENDING lock is needed before acquiring a SHARED lock and before + ** acquiring an EXCLUSIVE lock. For the SHARED lock, the PENDING will + ** be released. + */ + if( eFileLock==SHARED_LOCK + || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLockdbPath, pFile, PENDING_BYTE, 1, 1); + if (failed) { + rc = failed; + goto afp_end_lock; + } + } + + /* If control gets to this point, then actually go ahead and make + ** operating system calls for the specified lock. + */ + if( eFileLock==SHARED_LOCK ){ + int lrc1, lrc2, lrc1Errno = 0; + long lk, mask; + + assert( pInode->nShared==0 ); + assert( pInode->eFileLock==0 ); + + mask = (sizeof(long)==8) ? LARGEST_INT64 : 0x7fffffff; + /* Now get the read-lock SHARED_LOCK */ + /* note that the quality of the randomness doesn't matter that much */ + lk = random(); + pInode->sharedByte = (lk & mask)%(SHARED_SIZE - 1); + lrc1 = afpSetLock(context->dbPath, pFile, + SHARED_FIRST+pInode->sharedByte, 1, 1); + if( IS_LOCK_ERROR(lrc1) ){ + lrc1Errno = pFile->lastErrno; + } + /* Drop the temporary PENDING lock */ + lrc2 = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0); + + if( IS_LOCK_ERROR(lrc1) ) { + pFile->lastErrno = lrc1Errno; + rc = lrc1; + goto afp_end_lock; + } else if( IS_LOCK_ERROR(lrc2) ){ + rc = lrc2; + goto afp_end_lock; + } else if( lrc1 != SQLITE_OK ) { + rc = lrc1; + } else { + pFile->eFileLock = SHARED_LOCK; + pInode->nLock++; + pInode->nShared = 1; + } + }else if( eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1 ){ + /* We are trying for an exclusive lock but another thread in this + ** same process is still holding a shared lock. */ + rc = SQLITE_BUSY; + }else{ + /* The request was for a RESERVED or EXCLUSIVE lock. It is + ** assumed that there is a SHARED or greater lock on the file + ** already. + */ + int failed = 0; + assert( 0!=pFile->eFileLock ); + if (eFileLock >= RESERVED_LOCK && pFile->eFileLock < RESERVED_LOCK) { + /* Acquire a RESERVED lock */ + failed = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1,1); + if( !failed ){ + context->reserved = 1; + } + } + if (!failed && eFileLock == EXCLUSIVE_LOCK) { + /* Acquire an EXCLUSIVE lock */ + + /* Remove the shared lock before trying the range. we'll need to + ** reestablish the shared lock if we can't get the afpUnlock + */ + if( !(failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST + + pInode->sharedByte, 1, 0)) ){ + int failed2 = SQLITE_OK; + /* now attemmpt to get the exclusive lock range */ + failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST, + SHARED_SIZE, 1); + if( failed && (failed2 = afpSetLock(context->dbPath, pFile, + SHARED_FIRST + pInode->sharedByte, 1, 1)) ){ + /* Can't reestablish the shared lock. Sqlite can't deal, this is + ** a critical I/O error + */ + rc = ((failed & SQLITE_IOERR) == SQLITE_IOERR) ? failed2 : + SQLITE_IOERR_LOCK; + goto afp_end_lock; + } + }else{ + rc = failed; + } + } + if( failed ){ + rc = failed; + } + } + + if( rc==SQLITE_OK ){ + pFile->eFileLock = eFileLock; + pInode->eFileLock = eFileLock; + }else if( eFileLock==EXCLUSIVE_LOCK ){ + pFile->eFileLock = PENDING_LOCK; + pInode->eFileLock = PENDING_LOCK; + } + +afp_end_lock: + unixLeaveMutex(); + OSTRACE(("LOCK %d %s %s (afp)\n", pFile->h, azFileLock(eFileLock), + rc==SQLITE_OK ? "ok" : "failed")); + return rc; +} + +/* +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock +** must be either NO_LOCK or SHARED_LOCK. +** +** If the locking level of the file descriptor is already at or below +** the requested locking level, this routine is a no-op. +*/ +static int afpUnlock(sqlite3_file *id, int eFileLock) { + int rc = SQLITE_OK; + unixFile *pFile = (unixFile*)id; + unixInodeInfo *pInode; + afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; + int skipShared = 0; +#ifdef SQLITE_TEST + int h = pFile->h; +#endif + + assert( pFile ); + OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (afp)\n", pFile->h, eFileLock, + pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared, + getpid())); + + assert( eFileLock<=SHARED_LOCK ); + if( pFile->eFileLock<=eFileLock ){ + return SQLITE_OK; + } + unixEnterMutex(); + pInode = pFile->pInode; + assert( pInode->nShared!=0 ); + if( pFile->eFileLock>SHARED_LOCK ){ + assert( pInode->eFileLock==pFile->eFileLock ); + SimulateIOErrorBenign(1); + SimulateIOError( h=(-1) ) + SimulateIOErrorBenign(0); + +#ifndef NDEBUG + /* When reducing a lock such that other processes can start + ** reading the database file again, make sure that the + ** transaction counter was updated if any part of the database + ** file changed. If the transaction counter is not updated, + ** other connections to the same file might not realize that + ** the file has changed and hence might not know to flush their + ** cache. The use of a stale cache can lead to database corruption. + */ + assert( pFile->inNormalWrite==0 + || pFile->dbUpdate==0 + || pFile->transCntrChng==1 ); + pFile->inNormalWrite = 0; +#endif + + if( pFile->eFileLock==EXCLUSIVE_LOCK ){ + rc = afpSetLock(context->dbPath, pFile, SHARED_FIRST, SHARED_SIZE, 0); + if( rc==SQLITE_OK && (eFileLock==SHARED_LOCK || pInode->nShared>1) ){ + /* only re-establish the shared lock if necessary */ + int sharedLockByte = SHARED_FIRST+pInode->sharedByte; + rc = afpSetLock(context->dbPath, pFile, sharedLockByte, 1, 1); + } else { + skipShared = 1; + } + } + if( rc==SQLITE_OK && pFile->eFileLock>=PENDING_LOCK ){ + rc = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0); + } + if( rc==SQLITE_OK && pFile->eFileLock>=RESERVED_LOCK && context->reserved ){ + rc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1, 0); + if( !rc ){ + context->reserved = 0; + } + } + if( rc==SQLITE_OK && (eFileLock==SHARED_LOCK || pInode->nShared>1)){ + pInode->eFileLock = SHARED_LOCK; + } + } + if( rc==SQLITE_OK && eFileLock==NO_LOCK ){ + + /* Decrement the shared lock counter. Release the lock using an + ** OS call only when all threads in this same process have released + ** the lock. + */ + unsigned long long sharedLockByte = SHARED_FIRST+pInode->sharedByte; + pInode->nShared--; + if( pInode->nShared==0 ){ + SimulateIOErrorBenign(1); + SimulateIOError( h=(-1) ) + SimulateIOErrorBenign(0); + if( !skipShared ){ + rc = afpSetLock(context->dbPath, pFile, sharedLockByte, 1, 0); + } + if( !rc ){ + pInode->eFileLock = NO_LOCK; + pFile->eFileLock = NO_LOCK; + } + } + if( rc==SQLITE_OK ){ + pInode->nLock--; + assert( pInode->nLock>=0 ); + if( pInode->nLock==0 ){ + closePendingFds(pFile); + } + } + } + + unixLeaveMutex(); + if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock; + return rc; +} + +/* +** Close a file & cleanup AFP specific locking context +*/ +static int afpClose(sqlite3_file *id) { + int rc = SQLITE_OK; + if( id ){ + unixFile *pFile = (unixFile*)id; + afpUnlock(id, NO_LOCK); + unixEnterMutex(); + if( pFile->pInode && pFile->pInode->nLock ){ + /* If there are outstanding locks, do not actually close the file just + ** yet because that would clear those locks. Instead, add the file + ** descriptor to pInode->aPending. It will be automatically closed when + ** the last lock is cleared. + */ + setPendingFd(pFile); + } + releaseInodeInfo(pFile); + sqlite3_free(pFile->lockingContext); + rc = closeUnixFile(id); + unixLeaveMutex(); + } + return rc; +} + +#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ +/* +** The code above is the AFP lock implementation. The code is specific +** to MacOSX and does not work on other unix platforms. No alternative +** is available. If you don't compile for a mac, then the "unix-afp" +** VFS is not available. +** +********************* End of the AFP lock implementation ********************** +******************************************************************************/ + +/****************************************************************************** +*************************** Begin NFS Locking ********************************/ + +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE +/* + ** Lower the locking level on file descriptor pFile to eFileLock. eFileLock + ** must be either NO_LOCK or SHARED_LOCK. + ** + ** If the locking level of the file descriptor is already at or below + ** the requested locking level, this routine is a no-op. + */ +static int nfsUnlock(sqlite3_file *id, int eFileLock){ + return posixUnlock(id, eFileLock, 1); +} + +#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ +/* +** The code above is the NFS lock implementation. The code is specific +** to MacOSX and does not work on other unix platforms. No alternative +** is available. +** +********************* End of the NFS lock implementation ********************** +******************************************************************************/ + +/****************************************************************************** +**************** Non-locking sqlite3_file methods ***************************** +** +** The next division contains implementations for all methods of the +** sqlite3_file object other than the locking methods. The locking +** methods were defined in divisions above (one locking method per +** division). Those methods that are common to all locking modes +** are gather together into this division. +*/ + +/* +** Seek to the offset passed as the second argument, then read cnt +** bytes into pBuf. Return the number of bytes actually read. +** +** NB: If you define USE_PREAD or USE_PREAD64, then it might also +** be necessary to define _XOPEN_SOURCE to be 500. This varies from +** one system to another. Since SQLite does not define USE_PREAD +** any any form by default, we will not attempt to define _XOPEN_SOURCE. +** See tickets #2741 and #2681. +** +** To avoid stomping the errno value on a failed read the lastErrno value +** is set before returning. +*/ +static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){ + int got; + int prior = 0; +#if (!defined(USE_PREAD) && !defined(USE_PREAD64)) + i64 newOffset; +#endif + TIMER_START; + do{ +#if defined(USE_PREAD) + got = osPread(id->h, pBuf, cnt, offset); + SimulateIOError( got = -1 ); +#elif defined(USE_PREAD64) + got = osPread64(id->h, pBuf, cnt, offset); + SimulateIOError( got = -1 ); +#else + newOffset = lseek(id->h, offset, SEEK_SET); + SimulateIOError( newOffset-- ); + if( newOffset!=offset ){ + if( newOffset == -1 ){ + ((unixFile*)id)->lastErrno = errno; + }else{ + ((unixFile*)id)->lastErrno = 0; + } + return -1; + } + got = osRead(id->h, pBuf, cnt); +#endif + if( got==cnt ) break; + if( got<0 ){ + if( errno==EINTR ){ got = 1; continue; } + prior = 0; + ((unixFile*)id)->lastErrno = errno; + break; + }else if( got>0 ){ + cnt -= got; + offset += got; + prior += got; + pBuf = (void*)(got + (char*)pBuf); + } + }while( got>0 ); + TIMER_END; + OSTRACE(("READ %-3d %5d %7lld %llu\n", + id->h, got+prior, offset-prior, TIMER_ELAPSED)); + return got+prior; +} + +/* +** Read data from a file into a buffer. Return SQLITE_OK if all +** bytes were read successfully and SQLITE_IOERR if anything goes +** wrong. +*/ +static int unixRead( + sqlite3_file *id, + void *pBuf, + int amt, + sqlite3_int64 offset +){ + unixFile *pFile = (unixFile *)id; + int got; + assert( id ); + + /* If this is a database file (not a journal, master-journal or temp + ** file), the bytes in the locking range should never be read or written. */ +#if 0 + assert( pFile->pUnused==0 + || offset>=PENDING_BYTE+512 + || offset+amt<=PENDING_BYTE + ); +#endif + + got = seekAndRead(pFile, offset, pBuf, amt); + if( got==amt ){ + return SQLITE_OK; + }else if( got<0 ){ + /* lastErrno set by seekAndRead */ + return SQLITE_IOERR_READ; + }else{ + pFile->lastErrno = 0; /* not a system error */ + /* Unread parts of the buffer must be zero-filled */ + memset(&((char*)pBuf)[got], 0, amt-got); + return SQLITE_IOERR_SHORT_READ; + } +} + +/* +** Seek to the offset in id->offset then read cnt bytes into pBuf. +** Return the number of bytes actually read. Update the offset. +** +** To avoid stomping the errno value on a failed write the lastErrno value +** is set before returning. +*/ +static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){ + int got; +#if (!defined(USE_PREAD) && !defined(USE_PREAD64)) + i64 newOffset; +#endif + TIMER_START; +#if defined(USE_PREAD) + do{ got = osPwrite(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR ); +#elif defined(USE_PREAD64) + do{ got = osPwrite64(id->h, pBuf, cnt, offset);}while( got<0 && errno==EINTR); +#else + do{ + newOffset = lseek(id->h, offset, SEEK_SET); + SimulateIOError( newOffset-- ); + if( newOffset!=offset ){ + if( newOffset == -1 ){ + ((unixFile*)id)->lastErrno = errno; + }else{ + ((unixFile*)id)->lastErrno = 0; + } + return -1; + } + got = osWrite(id->h, pBuf, cnt); + }while( got<0 && errno==EINTR ); +#endif + TIMER_END; + if( got<0 ){ + ((unixFile*)id)->lastErrno = errno; + } + + OSTRACE(("WRITE %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED)); + return got; +} + + +/* +** Write data from a buffer into a file. Return SQLITE_OK on success +** or some other error code on failure. +*/ +static int unixWrite( + sqlite3_file *id, + const void *pBuf, + int amt, + sqlite3_int64 offset +){ + unixFile *pFile = (unixFile*)id; + int wrote = 0; + assert( id ); + assert( amt>0 ); + + /* If this is a database file (not a journal, master-journal or temp + ** file), the bytes in the locking range should never be read or written. */ +#if 0 + assert( pFile->pUnused==0 + || offset>=PENDING_BYTE+512 + || offset+amt<=PENDING_BYTE + ); +#endif + +#ifndef NDEBUG + /* If we are doing a normal write to a database file (as opposed to + ** doing a hot-journal rollback or a write to some file other than a + ** normal database file) then record the fact that the database + ** has changed. If the transaction counter is modified, record that + ** fact too. + */ + if( pFile->inNormalWrite ){ + pFile->dbUpdate = 1; /* The database has been modified */ + if( offset<=24 && offset+amt>=27 ){ + int rc; + char oldCntr[4]; + SimulateIOErrorBenign(1); + rc = seekAndRead(pFile, 24, oldCntr, 4); + SimulateIOErrorBenign(0); + if( rc!=4 || memcmp(oldCntr, &((char*)pBuf)[24-offset], 4)!=0 ){ + pFile->transCntrChng = 1; /* The transaction counter has changed */ + } + } + } +#endif + + while( amt>0 && (wrote = seekAndWrite(pFile, offset, pBuf, amt))>0 ){ + amt -= wrote; + offset += wrote; + pBuf = &((char*)pBuf)[wrote]; + } + SimulateIOError(( wrote=(-1), amt=1 )); + SimulateDiskfullError(( wrote=0, amt=1 )); + + if( amt>0 ){ + if( wrote<0 && pFile->lastErrno!=ENOSPC ){ + /* lastErrno set by seekAndWrite */ + return SQLITE_IOERR_WRITE; + }else{ + pFile->lastErrno = 0; /* not a system error */ + return SQLITE_FULL; + } + } + + return SQLITE_OK; +} + +#ifdef SQLITE_TEST +/* +** Count the number of fullsyncs and normal syncs. This is used to test +** that syncs and fullsyncs are occurring at the right times. +*/ +int sqlite3_sync_count = 0; +int sqlite3_fullsync_count = 0; +#endif + +/* +** We do not trust systems to provide a working fdatasync(). Some do. +** Others do no. To be safe, we will stick with the (slightly slower) +** fsync(). If you know that your system does support fdatasync() correctly, +** then simply compile with -Dfdatasync=fdatasync +*/ +#if !defined(fdatasync) +# define fdatasync fsync +#endif + +/* +** Define HAVE_FULLFSYNC to 0 or 1 depending on whether or not +** the F_FULLFSYNC macro is defined. F_FULLFSYNC is currently +** only available on Mac OS X. But that could change. +*/ +#ifdef F_FULLFSYNC +# define HAVE_FULLFSYNC 1 +#else +# define HAVE_FULLFSYNC 0 +#endif + + +/* +** The fsync() system call does not work as advertised on many +** unix systems. The following procedure is an attempt to make +** it work better. +** +** The SQLITE_NO_SYNC macro disables all fsync()s. This is useful +** for testing when we want to run through the test suite quickly. +** You are strongly advised *not* to deploy with SQLITE_NO_SYNC +** enabled, however, since with SQLITE_NO_SYNC enabled, an OS crash +** or power failure will likely corrupt the database file. +** +** SQLite sets the dataOnly flag if the size of the file is unchanged. +** The idea behind dataOnly is that it should only write the file content +** to disk, not the inode. We only set dataOnly if the file size is +** unchanged since the file size is part of the inode. However, +** Ted Ts'o tells us that fdatasync() will also write the inode if the +** file size has changed. The only real difference between fdatasync() +** and fsync(), Ted tells us, is that fdatasync() will not flush the +** inode if the mtime or owner or other inode attributes have changed. +** We only care about the file size, not the other file attributes, so +** as far as SQLite is concerned, an fdatasync() is always adequate. +** So, we always use fdatasync() if it is available, regardless of +** the value of the dataOnly flag. +*/ +static int full_fsync(int fd, int fullSync, int dataOnly){ + int rc; + + /* The following "ifdef/elif/else/" block has the same structure as + ** the one below. It is replicated here solely to avoid cluttering + ** up the real code with the UNUSED_PARAMETER() macros. + */ +#ifdef SQLITE_NO_SYNC + UNUSED_PARAMETER(fd); + UNUSED_PARAMETER(fullSync); + UNUSED_PARAMETER(dataOnly); +#elif HAVE_FULLFSYNC + UNUSED_PARAMETER(dataOnly); +#else + UNUSED_PARAMETER(fullSync); + UNUSED_PARAMETER(dataOnly); +#endif + + /* Record the number of times that we do a normal fsync() and + ** FULLSYNC. This is used during testing to verify that this procedure + ** gets called with the correct arguments. + */ +#ifdef SQLITE_TEST + if( fullSync ) sqlite3_fullsync_count++; + sqlite3_sync_count++; +#endif + + /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a + ** no-op + */ +#ifdef SQLITE_NO_SYNC + rc = SQLITE_OK; +#elif HAVE_FULLFSYNC + if( fullSync ){ + rc = osFcntl(fd, F_FULLFSYNC, 0); + }else{ + rc = 1; + } + /* If the FULLFSYNC failed, fall back to attempting an fsync(). + ** It shouldn't be possible for fullfsync to fail on the local + ** file system (on OSX), so failure indicates that FULLFSYNC + ** isn't supported for this file system. So, attempt an fsync + ** and (for now) ignore the overhead of a superfluous fcntl call. + ** It'd be better to detect fullfsync support once and avoid + ** the fcntl call every time sync is called. + */ + if( rc ) rc = fsync(fd); + +#elif defined(__APPLE__) + /* fdatasync() on HFS+ doesn't yet flush the file size if it changed correctly + ** so currently we default to the macro that redefines fdatasync to fsync + */ + rc = fsync(fd); +#else + rc = fdatasync(fd); +#if OS_VXWORKS + if( rc==-1 && errno==ENOTSUP ){ + rc = fsync(fd); + } +#endif /* OS_VXWORKS */ +#endif /* ifdef SQLITE_NO_SYNC elif HAVE_FULLFSYNC */ + + if( OS_VXWORKS && rc!= -1 ){ + rc = 0; + } + return rc; +} + +/* +** Open a file descriptor to the directory containing file zFilename. +** If successful, *pFd is set to the opened file descriptor and +** SQLITE_OK is returned. If an error occurs, either SQLITE_NOMEM +** or SQLITE_CANTOPEN is returned and *pFd is set to an undefined +** value. +** +** The directory file descriptor is used for only one thing - to +** fsync() a directory to make sure file creation and deletion events +** are flushed to disk. Such fsyncs are not needed on newer +** journaling filesystems, but are required on older filesystems. +** +** This routine can be overridden using the xSetSysCall interface. +** The ability to override this routine was added in support of the +** chromium sandbox. Opening a directory is a security risk (we are +** told) so making it overrideable allows the chromium sandbox to +** replace this routine with a harmless no-op. To make this routine +** a no-op, replace it with a stub that returns SQLITE_OK but leaves +** *pFd set to a negative number. +** +** If SQLITE_OK is returned, the caller is responsible for closing +** the file descriptor *pFd using close(). +*/ +static int openDirectory(const char *zFilename, int *pFd){ + int ii; + int fd = -1; + char zDirname[MAX_PATHNAME+1]; + + sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename); + for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--); + if( ii>0 ){ + zDirname[ii] = '\0'; + fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0); + if( fd>=0 ){ +#ifdef FD_CLOEXEC + osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC); +#endif + OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname)); + } + } + *pFd = fd; + return (fd>=0?SQLITE_OK:unixLogError(SQLITE_CANTOPEN_BKPT, "open", zDirname)); +} + +/* +** Make sure all writes to a particular file are committed to disk. +** +** If dataOnly==0 then both the file itself and its metadata (file +** size, access time, etc) are synced. If dataOnly!=0 then only the +** file data is synced. +** +** Under Unix, also make sure that the directory entry for the file +** has been created by fsync-ing the directory that contains the file. +** If we do not do this and we encounter a power failure, the directory +** entry for the journal might not exist after we reboot. The next +** SQLite to access the file will not know that the journal exists (because +** the directory entry for the journal was never created) and the transaction +** will not roll back - possibly leading to database corruption. +*/ +static int unixSync(sqlite3_file *id, int flags){ + int rc; + unixFile *pFile = (unixFile*)id; + + int isDataOnly = (flags&SQLITE_SYNC_DATAONLY); + int isFullsync = (flags&0x0F)==SQLITE_SYNC_FULL; + + /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */ + assert((flags&0x0F)==SQLITE_SYNC_NORMAL + || (flags&0x0F)==SQLITE_SYNC_FULL + ); + + /* Unix cannot, but some systems may return SQLITE_FULL from here. This + ** line is to test that doing so does not cause any problems. + */ + SimulateDiskfullError( return SQLITE_FULL ); + + assert( pFile ); + OSTRACE(("SYNC %-3d\n", pFile->h)); + rc = full_fsync(pFile->h, isFullsync, isDataOnly); + SimulateIOError( rc=1 ); + if( rc ){ + pFile->lastErrno = errno; + return unixLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath); + } + + /* Also fsync the directory containing the file if the DIRSYNC flag + ** is set. This is a one-time occurrance. Many systems (examples: AIX) + ** are unable to fsync a directory, so ignore errors on the fsync. + */ + if( pFile->ctrlFlags & UNIXFILE_DIRSYNC ){ + int dirfd; + OSTRACE(("DIRSYNC %s (have_fullfsync=%d fullsync=%d)\n", pFile->zPath, + HAVE_FULLFSYNC, isFullsync)); + rc = osOpenDirectory(pFile->zPath, &dirfd); + if( rc==SQLITE_OK && dirfd>=0 ){ + full_fsync(dirfd, 0, 0); + robust_close(pFile, dirfd, __LINE__); + }else if( rc==SQLITE_CANTOPEN ){ + rc = SQLITE_OK; + } + pFile->ctrlFlags &= ~UNIXFILE_DIRSYNC; + } + return rc; +} + +/* +** Truncate an open file to a specified size +*/ +static int unixTruncate(sqlite3_file *id, i64 nByte){ + unixFile *pFile = (unixFile *)id; + int rc; + assert( pFile ); + SimulateIOError( return SQLITE_IOERR_TRUNCATE ); + + /* If the user has configured a chunk-size for this file, truncate the + ** file so that it consists of an integer number of chunks (i.e. the + ** actual file size after the operation may be larger than the requested + ** size). + */ + if( pFile->szChunk ){ + nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; + } + + rc = robust_ftruncate(pFile->h, (off_t)nByte); + if( rc ){ + pFile->lastErrno = errno; + return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); + }else{ +#ifndef NDEBUG + /* If we are doing a normal write to a database file (as opposed to + ** doing a hot-journal rollback or a write to some file other than a + ** normal database file) and we truncate the file to zero length, + ** that effectively updates the change counter. This might happen + ** when restoring a database using the backup API from a zero-length + ** source. + */ + if( pFile->inNormalWrite && nByte==0 ){ + pFile->transCntrChng = 1; + } +#endif + + return SQLITE_OK; + } +} + +/* +** Determine the current size of a file in bytes +*/ +static int unixFileSize(sqlite3_file *id, i64 *pSize){ + int rc; + struct stat buf; + assert( id ); + rc = osFstat(((unixFile*)id)->h, &buf); + SimulateIOError( rc=1 ); + if( rc!=0 ){ + ((unixFile*)id)->lastErrno = errno; + return SQLITE_IOERR_FSTAT; + } + *pSize = buf.st_size; + + /* When opening a zero-size database, the findInodeInfo() procedure + ** writes a single byte into that file in order to work around a bug + ** in the OS-X msdos filesystem. In order to avoid problems with upper + ** layers, we need to report this file size as zero even though it is + ** really 1. Ticket #3260. + */ + if( *pSize==1 ) *pSize = 0; + + + return SQLITE_OK; +} + +#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) +/* +** Handler for proxy-locking file-control verbs. Defined below in the +** proxying locking division. +*/ +static int proxyFileControl(sqlite3_file*,int,void*); +#endif + +/* +** This function is called to handle the SQLITE_FCNTL_SIZE_HINT +** file-control operation. Enlarge the database to nBytes in size +** (rounded up to the next chunk-size). If the database is already +** nBytes or larger, this routine is a no-op. +*/ +static int fcntlSizeHint(unixFile *pFile, i64 nByte){ + if( pFile->szChunk>0 ){ + i64 nSize; /* Required file size */ + struct stat buf; /* Used to hold return values of fstat() */ + + if( osFstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT; + + nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk; + if( nSize>(i64)buf.st_size ){ + +#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE + /* The code below is handling the return value of osFallocate() + ** correctly. posix_fallocate() is defined to "returns zero on success, + ** or an error number on failure". See the manpage for details. */ + int err; + do{ + err = osFallocate(pFile->h, buf.st_size, nSize-buf.st_size); + }while( err==EINTR ); + if( err ) return SQLITE_IOERR_WRITE; +#else + /* If the OS does not have posix_fallocate(), fake it. First use + ** ftruncate() to set the file size, then write a single byte to + ** the last byte in each block within the extended region. This + ** is the same technique used by glibc to implement posix_fallocate() + ** on systems that do not have a real fallocate() system call. + */ + int nBlk = buf.st_blksize; /* File-system block size */ + i64 iWrite; /* Next offset to write to */ + + if( robust_ftruncate(pFile->h, nSize) ){ + pFile->lastErrno = errno; + return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); + } + iWrite = ((buf.st_size + 2*nBlk - 1)/nBlk)*nBlk-1; + while( iWritectrlFlags is set. +** +** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags. +*/ +static void unixModeBit(unixFile *pFile, unsigned char mask, int *pArg){ + if( *pArg<0 ){ + *pArg = (pFile->ctrlFlags & mask)!=0; + }else if( (*pArg)==0 ){ + pFile->ctrlFlags &= ~mask; + }else{ + pFile->ctrlFlags |= mask; + } +} + +/* +** Information and control of an open file handle. +*/ +static int unixFileControl(sqlite3_file *id, int op, void *pArg){ + unixFile *pFile = (unixFile*)id; + switch( op ){ + case SQLITE_FCNTL_LOCKSTATE: { + *(int*)pArg = pFile->eFileLock; + return SQLITE_OK; + } + case SQLITE_LAST_ERRNO: { + *(int*)pArg = pFile->lastErrno; + return SQLITE_OK; + } + case SQLITE_FCNTL_CHUNK_SIZE: { + pFile->szChunk = *(int *)pArg; + return SQLITE_OK; + } + case SQLITE_FCNTL_SIZE_HINT: { + int rc; + SimulateIOErrorBenign(1); + rc = fcntlSizeHint(pFile, *(i64 *)pArg); + SimulateIOErrorBenign(0); + return rc; + } + case SQLITE_FCNTL_PERSIST_WAL: { + unixModeBit(pFile, UNIXFILE_PERSIST_WAL, (int*)pArg); + return SQLITE_OK; + } + case SQLITE_FCNTL_POWERSAFE_OVERWRITE: { + unixModeBit(pFile, UNIXFILE_PSOW, (int*)pArg); + return SQLITE_OK; + } + case SQLITE_FCNTL_VFSNAME: { + *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName); + return SQLITE_OK; + } +#ifndef NDEBUG + /* The pager calls this method to signal that it has done + ** a rollback and that the database is therefore unchanged and + ** it hence it is OK for the transaction change counter to be + ** unchanged. + */ + case SQLITE_FCNTL_DB_UNCHANGED: { + ((unixFile*)id)->dbUpdate = 0; + return SQLITE_OK; + } +#endif +#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) + case SQLITE_SET_LOCKPROXYFILE: + case SQLITE_GET_LOCKPROXYFILE: { + return proxyFileControl(id,op,pArg); + } +#endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */ + } + return SQLITE_NOTFOUND; +} + +/* +** Return the sector size in bytes of the underlying block device for +** the specified file. This is almost always 512 bytes, but may be +** larger for some devices. +** +** SQLite code assumes this function cannot fail. It also assumes that +** if two files are created in the same file-system directory (i.e. +** a database and its journal file) that the sector size will be the +** same for both. +*/ +static int unixSectorSize(sqlite3_file *pFile){ + (void)pFile; + return SQLITE_DEFAULT_SECTOR_SIZE; +} + +/* +** Return the device characteristics for the file. +** +** This VFS is set up to return SQLITE_IOCAP_POWERSAFE_OVERWRITE by default. +** However, that choice is contraversial since technically the underlying +** file system does not always provide powersafe overwrites. (In other +** words, after a power-loss event, parts of the file that were never +** written might end up being altered.) However, non-PSOW behavior is very, +** very rare. And asserting PSOW makes a large reduction in the amount +** of required I/O for journaling, since a lot of padding is eliminated. +** Hence, while POWERSAFE_OVERWRITE is on by default, there is a file-control +** available to turn it off and URI query parameter available to turn it off. +*/ +static int unixDeviceCharacteristics(sqlite3_file *id){ + unixFile *p = (unixFile*)id; + if( p->ctrlFlags & UNIXFILE_PSOW ){ + return SQLITE_IOCAP_POWERSAFE_OVERWRITE; + }else{ + return 0; + } +} + +#ifndef SQLITE_OMIT_WAL + + +/* +** Object used to represent an shared memory buffer. +** +** When multiple threads all reference the same wal-index, each thread +** has its own unixShm object, but they all point to a single instance +** of this unixShmNode object. In other words, each wal-index is opened +** only once per process. +** +** Each unixShmNode object is connected to a single unixInodeInfo object. +** We could coalesce this object into unixInodeInfo, but that would mean +** every open file that does not use shared memory (in other words, most +** open files) would have to carry around this extra information. So +** the unixInodeInfo object contains a pointer to this unixShmNode object +** and the unixShmNode object is created only when needed. +** +** unixMutexHeld() must be true when creating or destroying +** this object or while reading or writing the following fields: +** +** nRef +** +** The following fields are read-only after the object is created: +** +** fid +** zFilename +** +** Either unixShmNode.mutex must be held or unixShmNode.nRef==0 and +** unixMutexHeld() is true when reading or writing any other field +** in this structure. +*/ +struct unixShmNode { + unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */ + sqlite3_mutex *mutex; /* Mutex to access this object */ + char *zFilename; /* Name of the mmapped file */ + int h; /* Open file descriptor */ + int szRegion; /* Size of shared-memory regions */ + u16 nRegion; /* Size of array apRegion */ + u8 isReadonly; /* True if read-only */ + char **apRegion; /* Array of mapped shared-memory regions */ + int nRef; /* Number of unixShm objects pointing to this */ + unixShm *pFirst; /* All unixShm objects pointing to this */ +#ifdef SQLITE_DEBUG + u8 exclMask; /* Mask of exclusive locks held */ + u8 sharedMask; /* Mask of shared locks held */ + u8 nextShmId; /* Next available unixShm.id value */ +#endif +}; + +/* +** Structure used internally by this VFS to record the state of an +** open shared memory connection. +** +** The following fields are initialized when this object is created and +** are read-only thereafter: +** +** unixShm.pFile +** unixShm.id +** +** All other fields are read/write. The unixShm.pFile->mutex must be held +** while accessing any read/write fields. +*/ +struct unixShm { + unixShmNode *pShmNode; /* The underlying unixShmNode object */ + unixShm *pNext; /* Next unixShm with the same unixShmNode */ + u8 hasMutex; /* True if holding the unixShmNode mutex */ + u8 id; /* Id of this connection within its unixShmNode */ + u16 sharedMask; /* Mask of shared locks held */ + u16 exclMask; /* Mask of exclusive locks held */ +}; + +/* +** Constants used for locking +*/ +#define UNIX_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */ +#define UNIX_SHM_DMS (UNIX_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */ + +/* +** Apply posix advisory locks for all bytes from ofst through ofst+n-1. +** +** Locks block if the mask is exactly UNIX_SHM_C and are non-blocking +** otherwise. +*/ +static int unixShmSystemLock( + unixShmNode *pShmNode, /* Apply locks to this open shared-memory segment */ + int lockType, /* F_UNLCK, F_RDLCK, or F_WRLCK */ + int ofst, /* First byte of the locking range */ + int n /* Number of bytes to lock */ +){ + struct flock f; /* The posix advisory locking structure */ + int rc = SQLITE_OK; /* Result code form fcntl() */ + + /* Access to the unixShmNode object is serialized by the caller */ + assert( sqlite3_mutex_held(pShmNode->mutex) || pShmNode->nRef==0 ); + + /* Shared locks never span more than one byte */ + assert( n==1 || lockType!=F_RDLCK ); + + /* Locks are within range */ + assert( n>=1 && nh>=0 ){ + /* Initialize the locking parameters */ + memset(&f, 0, sizeof(f)); + f.l_type = lockType; + f.l_whence = SEEK_SET; + f.l_start = ofst; + f.l_len = n; + + rc = osFcntl(pShmNode->h, F_SETLK, &f); + rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY; + } + + /* Update the global lock state and do debug tracing */ +#ifdef SQLITE_DEBUG + { u16 mask; + OSTRACE(("SHM-LOCK ")); + mask = (1<<(ofst+n)) - (1<exclMask &= ~mask; + pShmNode->sharedMask &= ~mask; + }else if( lockType==F_RDLCK ){ + OSTRACE(("read-lock %d ok", ofst)); + pShmNode->exclMask &= ~mask; + pShmNode->sharedMask |= mask; + }else{ + assert( lockType==F_WRLCK ); + OSTRACE(("write-lock %d ok", ofst)); + pShmNode->exclMask |= mask; + pShmNode->sharedMask &= ~mask; + } + }else{ + if( lockType==F_UNLCK ){ + OSTRACE(("unlock %d failed", ofst)); + }else if( lockType==F_RDLCK ){ + OSTRACE(("read-lock failed")); + }else{ + assert( lockType==F_WRLCK ); + OSTRACE(("write-lock %d failed", ofst)); + } + } + OSTRACE((" - afterwards %03x,%03x\n", + pShmNode->sharedMask, pShmNode->exclMask)); + } +#endif + + return rc; +} + + +/* +** Purge the unixShmNodeList list of all entries with unixShmNode.nRef==0. +** +** This is not a VFS shared-memory method; it is a utility function called +** by VFS shared-memory methods. +*/ +static void unixShmPurge(unixFile *pFd){ + unixShmNode *p = pFd->pInode->pShmNode; + assert( unixMutexHeld() ); + if( p && p->nRef==0 ){ + int i; + assert( p->pInode==pFd->pInode ); + sqlite3_mutex_free(p->mutex); + for(i=0; inRegion; i++){ + if( p->h>=0 ){ + munmap(p->apRegion[i], p->szRegion); + }else{ + sqlite3_free(p->apRegion[i]); + } + } + sqlite3_free(p->apRegion); + if( p->h>=0 ){ + robust_close(pFd, p->h, __LINE__); + p->h = -1; + } + p->pInode->pShmNode = 0; + sqlite3_free(p); + } +} + +/* +** Open a shared-memory area associated with open database file pDbFd. +** This particular implementation uses mmapped files. +** +** The file used to implement shared-memory is in the same directory +** as the open database file and has the same name as the open database +** file with the "-shm" suffix added. For example, if the database file +** is "/home/user1/config.db" then the file that is created and mmapped +** for shared memory will be called "/home/user1/config.db-shm". +** +** Another approach to is to use files in /dev/shm or /dev/tmp or an +** some other tmpfs mount. But if a file in a different directory +** from the database file is used, then differing access permissions +** or a chroot() might cause two different processes on the same +** database to end up using different files for shared memory - +** meaning that their memory would not really be shared - resulting +** in database corruption. Nevertheless, this tmpfs file usage +** can be enabled at compile-time using -DSQLITE_SHM_DIRECTORY="/dev/shm" +** or the equivalent. The use of the SQLITE_SHM_DIRECTORY compile-time +** option results in an incompatible build of SQLite; builds of SQLite +** that with differing SQLITE_SHM_DIRECTORY settings attempt to use the +** same database file at the same time, database corruption will likely +** result. The SQLITE_SHM_DIRECTORY compile-time option is considered +** "unsupported" and may go away in a future SQLite release. +** +** When opening a new shared-memory file, if no other instances of that +** file are currently open, in this process or in other processes, then +** the file must be truncated to zero length or have its header cleared. +** +** If the original database file (pDbFd) is using the "unix-excl" VFS +** that means that an exclusive lock is held on the database file and +** that no other processes are able to read or write the database. In +** that case, we do not really need shared memory. No shared memory +** file is created. The shared memory will be simulated with heap memory. +*/ +static int unixOpenSharedMemory(unixFile *pDbFd){ + struct unixShm *p = 0; /* The connection to be opened */ + struct unixShmNode *pShmNode; /* The underlying mmapped file */ + int rc; /* Result code */ + unixInodeInfo *pInode; /* The inode of fd */ + char *zShmFilename; /* Name of the file used for SHM */ + int nShmFilename; /* Size of the SHM filename in bytes */ + + /* Allocate space for the new unixShm object. */ + p = sqlite3_malloc( sizeof(*p) ); + if( p==0 ) return SQLITE_NOMEM; + memset(p, 0, sizeof(*p)); + assert( pDbFd->pShm==0 ); + + /* Check to see if a unixShmNode object already exists. Reuse an existing + ** one if present. Create a new one if necessary. + */ + unixEnterMutex(); + pInode = pDbFd->pInode; + pShmNode = pInode->pShmNode; + if( pShmNode==0 ){ + struct stat sStat; /* fstat() info for database file */ + + /* Call fstat() to figure out the permissions on the database file. If + ** a new *-shm file is created, an attempt will be made to create it + ** with the same permissions. The actual permissions the file is created + ** with are subject to the current umask setting. + */ + if( osFstat(pDbFd->h, &sStat) && pInode->bProcessLock==0 ){ + rc = SQLITE_IOERR_FSTAT; + goto shm_open_err; + } + +#ifdef SQLITE_SHM_DIRECTORY + nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 31; +#else + nShmFilename = 6 + (int)strlen(pDbFd->zPath); +#endif + pShmNode = sqlite3_malloc( sizeof(*pShmNode) + nShmFilename ); + if( pShmNode==0 ){ + rc = SQLITE_NOMEM; + goto shm_open_err; + } + memset(pShmNode, 0, sizeof(*pShmNode)+nShmFilename); + zShmFilename = pShmNode->zFilename = (char*)&pShmNode[1]; +#ifdef SQLITE_SHM_DIRECTORY + sqlite3_snprintf(nShmFilename, zShmFilename, + SQLITE_SHM_DIRECTORY "/sqlite-shm-%x-%x", + (u32)sStat.st_ino, (u32)sStat.st_dev); +#else + sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", pDbFd->zPath); + sqlite3FileSuffix3(pDbFd->zPath, zShmFilename); +#endif + pShmNode->h = -1; + pDbFd->pInode->pShmNode = pShmNode; + pShmNode->pInode = pDbFd->pInode; + pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( pShmNode->mutex==0 ){ + rc = SQLITE_NOMEM; + goto shm_open_err; + } + + if( pInode->bProcessLock==0 ){ + int openFlags = O_RDWR | O_CREAT; + if( sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ + openFlags = O_RDONLY; + pShmNode->isReadonly = 1; + } + pShmNode->h = robust_open(zShmFilename, openFlags, (sStat.st_mode&0777)); + if( pShmNode->h<0 ){ + if( pShmNode->h<0 ){ + rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); + goto shm_open_err; + } + } + + /* Check to see if another process is holding the dead-man switch. + ** If not, truncate the file to zero length. + */ + rc = SQLITE_OK; + if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){ + if( robust_ftruncate(pShmNode->h, 0) ){ + rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename); + } + } + if( rc==SQLITE_OK ){ + rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1); + } + if( rc ) goto shm_open_err; + } + } + + /* Make the new connection a child of the unixShmNode */ + p->pShmNode = pShmNode; +#ifdef SQLITE_DEBUG + p->id = pShmNode->nextShmId++; +#endif + pShmNode->nRef++; + pDbFd->pShm = p; + unixLeaveMutex(); + + /* The reference count on pShmNode has already been incremented under + ** the cover of the unixEnterMutex() mutex and the pointer from the + ** new (struct unixShm) object to the pShmNode has been set. All that is + ** left to do is to link the new object into the linked list starting + ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex + ** mutex. + */ + sqlite3_mutex_enter(pShmNode->mutex); + p->pNext = pShmNode->pFirst; + pShmNode->pFirst = p; + sqlite3_mutex_leave(pShmNode->mutex); + return SQLITE_OK; + + /* Jump here on any error */ +shm_open_err: + unixShmPurge(pDbFd); /* This call frees pShmNode if required */ + sqlite3_free(p); + unixLeaveMutex(); + return rc; +} + +/* +** This function is called to obtain a pointer to region iRegion of the +** shared-memory associated with the database file fd. Shared-memory regions +** are numbered starting from zero. Each shared-memory region is szRegion +** bytes in size. +** +** If an error occurs, an error code is returned and *pp is set to NULL. +** +** Otherwise, if the bExtend parameter is 0 and the requested shared-memory +** region has not been allocated (by any client, including one running in a +** separate process), then *pp is set to NULL and SQLITE_OK returned. If +** bExtend is non-zero and the requested shared-memory region has not yet +** been allocated, it is allocated by this function. +** +** If the shared-memory region has already been allocated or is allocated by +** this call as described above, then it is mapped into this processes +** address space (if it is not already), *pp is set to point to the mapped +** memory and SQLITE_OK returned. +*/ +static int unixShmMap( + sqlite3_file *fd, /* Handle open on database file */ + int iRegion, /* Region to retrieve */ + int szRegion, /* Size of regions */ + int bExtend, /* True to extend file if necessary */ + void volatile **pp /* OUT: Mapped memory */ +){ + unixFile *pDbFd = (unixFile*)fd; + unixShm *p; + unixShmNode *pShmNode; + int rc = SQLITE_OK; + + /* If the shared-memory file has not yet been opened, open it now. */ + if( pDbFd->pShm==0 ){ + rc = unixOpenSharedMemory(pDbFd); + if( rc!=SQLITE_OK ) return rc; + } + + p = pDbFd->pShm; + pShmNode = p->pShmNode; + sqlite3_mutex_enter(pShmNode->mutex); + assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); + assert( pShmNode->pInode==pDbFd->pInode ); + assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 ); + assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 ); + + if( pShmNode->nRegion<=iRegion ){ + char **apNew; /* New apRegion[] array */ + int nByte = (iRegion+1)*szRegion; /* Minimum required file size */ + struct stat sStat; /* Used by fstat() */ + + pShmNode->szRegion = szRegion; + + if( pShmNode->h>=0 ){ + /* The requested region is not mapped into this processes address space. + ** Check to see if it has been allocated (i.e. if the wal-index file is + ** large enough to contain the requested region). + */ + if( osFstat(pShmNode->h, &sStat) ){ + rc = SQLITE_IOERR_SHMSIZE; + goto shmpage_out; + } + + if( sStat.st_sizeh, nByte) ){ + rc = unixLogError(SQLITE_IOERR_SHMSIZE, "ftruncate", + pShmNode->zFilename); + goto shmpage_out; + } + } + } + + /* Map the requested memory region into this processes address space. */ + apNew = (char **)sqlite3_realloc( + pShmNode->apRegion, (iRegion+1)*sizeof(char *) + ); + if( !apNew ){ + rc = SQLITE_IOERR_NOMEM; + goto shmpage_out; + } + pShmNode->apRegion = apNew; + while(pShmNode->nRegion<=iRegion){ + void *pMem; + if( pShmNode->h>=0 ){ + pMem = mmap(0, szRegion, + pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, + MAP_SHARED, pShmNode->h, pShmNode->nRegion*szRegion + ); + if( pMem==MAP_FAILED ){ + rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename); + goto shmpage_out; + } + }else{ + pMem = sqlite3_malloc(szRegion); + if( pMem==0 ){ + rc = SQLITE_NOMEM; + goto shmpage_out; + } + memset(pMem, 0, szRegion); + } + pShmNode->apRegion[pShmNode->nRegion] = pMem; + pShmNode->nRegion++; + } + } + +shmpage_out: + if( pShmNode->nRegion>iRegion ){ + *pp = pShmNode->apRegion[iRegion]; + }else{ + *pp = 0; + } + if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY; + sqlite3_mutex_leave(pShmNode->mutex); + return rc; +} + +/* +** Change the lock state for a shared-memory segment. +** +** Note that the relationship between SHAREd and EXCLUSIVE locks is a little +** different here than in posix. In xShmLock(), one can go from unlocked +** to shared and back or from unlocked to exclusive and back. But one may +** not go from shared to exclusive or from exclusive to shared. +*/ +static int unixShmLock( + sqlite3_file *fd, /* Database file holding the shared memory */ + int ofst, /* First lock to acquire or release */ + int n, /* Number of locks to acquire or release */ + int flags /* What to do with the lock */ +){ + unixFile *pDbFd = (unixFile*)fd; /* Connection holding shared memory */ + unixShm *p = pDbFd->pShm; /* The shared memory being locked */ + unixShm *pX; /* For looping over all siblings */ + unixShmNode *pShmNode = p->pShmNode; /* The underlying file iNode */ + int rc = SQLITE_OK; /* Result code */ + u16 mask; /* Mask of locks to take or release */ + + assert( pShmNode==pDbFd->pInode->pShmNode ); + assert( pShmNode->pInode==pDbFd->pInode ); + assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK ); + assert( n>=1 ); + assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED) + || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE) + || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED) + || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) ); + assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); + assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 ); + assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 ); + + mask = (1<<(ofst+n)) - (1<1 || mask==(1<mutex); + if( flags & SQLITE_SHM_UNLOCK ){ + u16 allMask = 0; /* Mask of locks held by siblings */ + + /* See if any siblings hold this same lock */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( pX==p ) continue; + assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 ); + allMask |= pX->sharedMask; + } + + /* Unlock the system-level locks */ + if( (mask & allMask)==0 ){ + rc = unixShmSystemLock(pShmNode, F_UNLCK, ofst+UNIX_SHM_BASE, n); + }else{ + rc = SQLITE_OK; + } + + /* Undo the local locks */ + if( rc==SQLITE_OK ){ + p->exclMask &= ~mask; + p->sharedMask &= ~mask; + } + }else if( flags & SQLITE_SHM_SHARED ){ + u16 allShared = 0; /* Union of locks held by connections other than "p" */ + + /* Find out which shared locks are already held by sibling connections. + ** If any sibling already holds an exclusive lock, go ahead and return + ** SQLITE_BUSY. + */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( (pX->exclMask & mask)!=0 ){ + rc = SQLITE_BUSY; + break; + } + allShared |= pX->sharedMask; + } + + /* Get shared locks at the system level, if necessary */ + if( rc==SQLITE_OK ){ + if( (allShared & mask)==0 ){ + rc = unixShmSystemLock(pShmNode, F_RDLCK, ofst+UNIX_SHM_BASE, n); + }else{ + rc = SQLITE_OK; + } + } + + /* Get the local shared locks */ + if( rc==SQLITE_OK ){ + p->sharedMask |= mask; + } + }else{ + /* Make sure no sibling connections hold locks that will block this + ** lock. If any do, return SQLITE_BUSY right away. + */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){ + rc = SQLITE_BUSY; + break; + } + } + + /* Get the exclusive locks at the system level. Then if successful + ** also mark the local connection as being locked. + */ + if( rc==SQLITE_OK ){ + rc = unixShmSystemLock(pShmNode, F_WRLCK, ofst+UNIX_SHM_BASE, n); + if( rc==SQLITE_OK ){ + assert( (p->sharedMask & mask)==0 ); + p->exclMask |= mask; + } + } + } + sqlite3_mutex_leave(pShmNode->mutex); + OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n", + p->id, getpid(), p->sharedMask, p->exclMask)); + return rc; +} + +/* +** Implement a memory barrier or memory fence on shared memory. +** +** All loads and stores begun before the barrier must complete before +** any load or store begun after the barrier. +*/ +static void unixShmBarrier( + sqlite3_file *fd /* Database file holding the shared memory */ +){ + UNUSED_PARAMETER(fd); + unixEnterMutex(); + unixLeaveMutex(); +} + +/* +** Close a connection to shared-memory. Delete the underlying +** storage if deleteFlag is true. +** +** If there is no shared memory associated with the connection then this +** routine is a harmless no-op. +*/ +static int unixShmUnmap( + sqlite3_file *fd, /* The underlying database file */ + int deleteFlag /* Delete shared-memory if true */ +){ + unixShm *p; /* The connection to be closed */ + unixShmNode *pShmNode; /* The underlying shared-memory file */ + unixShm **pp; /* For looping over sibling connections */ + unixFile *pDbFd; /* The underlying database file */ + + pDbFd = (unixFile*)fd; + p = pDbFd->pShm; + if( p==0 ) return SQLITE_OK; + pShmNode = p->pShmNode; + + assert( pShmNode==pDbFd->pInode->pShmNode ); + assert( pShmNode->pInode==pDbFd->pInode ); + + /* Remove connection p from the set of connections associated + ** with pShmNode */ + sqlite3_mutex_enter(pShmNode->mutex); + for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){} + *pp = p->pNext; + + /* Free the connection p */ + sqlite3_free(p); + pDbFd->pShm = 0; + sqlite3_mutex_leave(pShmNode->mutex); + + /* If pShmNode->nRef has reached 0, then close the underlying + ** shared-memory file, too */ + unixEnterMutex(); + assert( pShmNode->nRef>0 ); + pShmNode->nRef--; + if( pShmNode->nRef==0 ){ + if( deleteFlag && pShmNode->h>=0 ) osUnlink(pShmNode->zFilename); + unixShmPurge(pDbFd); + } + unixLeaveMutex(); + + return SQLITE_OK; +} + + +#else +# define unixShmMap 0 +# define unixShmLock 0 +# define unixShmBarrier 0 +# define unixShmUnmap 0 +#endif /* #ifndef SQLITE_OMIT_WAL */ + +/* +** Here ends the implementation of all sqlite3_file methods. +** +********************** End sqlite3_file Methods ******************************* +******************************************************************************/ + +/* +** This division contains definitions of sqlite3_io_methods objects that +** implement various file locking strategies. It also contains definitions +** of "finder" functions. A finder-function is used to locate the appropriate +** sqlite3_io_methods object for a particular database file. The pAppData +** field of the sqlite3_vfs VFS objects are initialized to be pointers to +** the correct finder-function for that VFS. +** +** Most finder functions return a pointer to a fixed sqlite3_io_methods +** object. The only interesting finder-function is autolockIoFinder, which +** looks at the filesystem type and tries to guess the best locking +** strategy from that. +** +** For finder-funtion F, two objects are created: +** +** (1) The real finder-function named "FImpt()". +** +** (2) A constant pointer to this function named just "F". +** +** +** A pointer to the F pointer is used as the pAppData value for VFS +** objects. We have to do this instead of letting pAppData point +** directly at the finder-function since C90 rules prevent a void* +** from be cast into a function pointer. +** +** +** Each instance of this macro generates two objects: +** +** * A constant sqlite3_io_methods object call METHOD that has locking +** methods CLOSE, LOCK, UNLOCK, CKRESLOCK. +** +** * An I/O method finder function called FINDER that returns a pointer +** to the METHOD object in the previous bullet. +*/ +#define IOMETHODS(FINDER, METHOD, VERSION, CLOSE, LOCK, UNLOCK, CKLOCK) \ +static const sqlite3_io_methods METHOD = { \ + VERSION, /* iVersion */ \ + CLOSE, /* xClose */ \ + unixRead, /* xRead */ \ + unixWrite, /* xWrite */ \ + unixTruncate, /* xTruncate */ \ + unixSync, /* xSync */ \ + unixFileSize, /* xFileSize */ \ + LOCK, /* xLock */ \ + UNLOCK, /* xUnlock */ \ + CKLOCK, /* xCheckReservedLock */ \ + unixFileControl, /* xFileControl */ \ + unixSectorSize, /* xSectorSize */ \ + unixDeviceCharacteristics, /* xDeviceCapabilities */ \ + unixShmMap, /* xShmMap */ \ + unixShmLock, /* xShmLock */ \ + unixShmBarrier, /* xShmBarrier */ \ + unixShmUnmap /* xShmUnmap */ \ +}; \ +static const sqlite3_io_methods *FINDER##Impl(const char *z, unixFile *p){ \ + UNUSED_PARAMETER(z); UNUSED_PARAMETER(p); \ + return &METHOD; \ +} \ +static const sqlite3_io_methods *(*const FINDER)(const char*,unixFile *p) \ + = FINDER##Impl; + +/* +** Here are all of the sqlite3_io_methods objects for each of the +** locking strategies. Functions that return pointers to these methods +** are also created. +*/ +IOMETHODS( + posixIoFinder, /* Finder function name */ + posixIoMethods, /* sqlite3_io_methods object name */ + 2, /* shared memory is enabled */ + unixClose, /* xClose method */ + unixLock, /* xLock method */ + unixUnlock, /* xUnlock method */ + unixCheckReservedLock /* xCheckReservedLock method */ +) +IOMETHODS( + nolockIoFinder, /* Finder function name */ + nolockIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ + nolockClose, /* xClose method */ + nolockLock, /* xLock method */ + nolockUnlock, /* xUnlock method */ + nolockCheckReservedLock /* xCheckReservedLock method */ +) +IOMETHODS( + dotlockIoFinder, /* Finder function name */ + dotlockIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ + dotlockClose, /* xClose method */ + dotlockLock, /* xLock method */ + dotlockUnlock, /* xUnlock method */ + dotlockCheckReservedLock /* xCheckReservedLock method */ +) + +#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS +IOMETHODS( + flockIoFinder, /* Finder function name */ + flockIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ + flockClose, /* xClose method */ + flockLock, /* xLock method */ + flockUnlock, /* xUnlock method */ + flockCheckReservedLock /* xCheckReservedLock method */ +) +#endif + +#if OS_VXWORKS +IOMETHODS( + semIoFinder, /* Finder function name */ + semIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ + semClose, /* xClose method */ + semLock, /* xLock method */ + semUnlock, /* xUnlock method */ + semCheckReservedLock /* xCheckReservedLock method */ +) +#endif + +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE +IOMETHODS( + afpIoFinder, /* Finder function name */ + afpIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ + afpClose, /* xClose method */ + afpLock, /* xLock method */ + afpUnlock, /* xUnlock method */ + afpCheckReservedLock /* xCheckReservedLock method */ +) +#endif + +/* +** The proxy locking method is a "super-method" in the sense that it +** opens secondary file descriptors for the conch and lock files and +** it uses proxy, dot-file, AFP, and flock() locking methods on those +** secondary files. For this reason, the division that implements +** proxy locking is located much further down in the file. But we need +** to go ahead and define the sqlite3_io_methods and finder function +** for proxy locking here. So we forward declare the I/O methods. +*/ +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE +static int proxyClose(sqlite3_file*); +static int proxyLock(sqlite3_file*, int); +static int proxyUnlock(sqlite3_file*, int); +static int proxyCheckReservedLock(sqlite3_file*, int*); +IOMETHODS( + proxyIoFinder, /* Finder function name */ + proxyIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ + proxyClose, /* xClose method */ + proxyLock, /* xLock method */ + proxyUnlock, /* xUnlock method */ + proxyCheckReservedLock /* xCheckReservedLock method */ +) +#endif + +/* nfs lockd on OSX 10.3+ doesn't clear write locks when a read lock is set */ +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE +IOMETHODS( + nfsIoFinder, /* Finder function name */ + nfsIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ + unixClose, /* xClose method */ + unixLock, /* xLock method */ + nfsUnlock, /* xUnlock method */ + unixCheckReservedLock /* xCheckReservedLock method */ +) +#endif + +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE +/* +** This "finder" function attempts to determine the best locking strategy +** for the database file "filePath". It then returns the sqlite3_io_methods +** object that implements that strategy. +** +** This is for MacOSX only. +*/ +static const sqlite3_io_methods *autolockIoFinderImpl( + const char *filePath, /* name of the database file */ + unixFile *pNew /* open file object for the database file */ +){ + static const struct Mapping { + const char *zFilesystem; /* Filesystem type name */ + const sqlite3_io_methods *pMethods; /* Appropriate locking method */ + } aMap[] = { + { "hfs", &posixIoMethods }, + { "ufs", &posixIoMethods }, + { "afpfs", &afpIoMethods }, + { "smbfs", &afpIoMethods }, + { "webdav", &nolockIoMethods }, + { 0, 0 } + }; + int i; + struct statfs fsInfo; + struct flock lockInfo; + + if( !filePath ){ + /* If filePath==NULL that means we are dealing with a transient file + ** that does not need to be locked. */ + return &nolockIoMethods; + } + if( statfs(filePath, &fsInfo) != -1 ){ + if( fsInfo.f_flags & MNT_RDONLY ){ + return &nolockIoMethods; + } + for(i=0; aMap[i].zFilesystem; i++){ + if( strcmp(fsInfo.f_fstypename, aMap[i].zFilesystem)==0 ){ + return aMap[i].pMethods; + } + } + } + + /* Default case. Handles, amongst others, "nfs". + ** Test byte-range lock using fcntl(). If the call succeeds, + ** assume that the file-system supports POSIX style locks. + */ + lockInfo.l_len = 1; + lockInfo.l_start = 0; + lockInfo.l_whence = SEEK_SET; + lockInfo.l_type = F_RDLCK; + if( osFcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) { + if( strcmp(fsInfo.f_fstypename, "nfs")==0 ){ + return &nfsIoMethods; + } else { + return &posixIoMethods; + } + }else{ + return &dotlockIoMethods; + } +} +static const sqlite3_io_methods + *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl; + +#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ + +#if OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE +/* +** This "finder" function attempts to determine the best locking strategy +** for the database file "filePath". It then returns the sqlite3_io_methods +** object that implements that strategy. +** +** This is for VXWorks only. +*/ +static const sqlite3_io_methods *autolockIoFinderImpl( + const char *filePath, /* name of the database file */ + unixFile *pNew /* the open file object */ +){ + struct flock lockInfo; + + if( !filePath ){ + /* If filePath==NULL that means we are dealing with a transient file + ** that does not need to be locked. */ + return &nolockIoMethods; + } + + /* Test if fcntl() is supported and use POSIX style locks. + ** Otherwise fall back to the named semaphore method. + */ + lockInfo.l_len = 1; + lockInfo.l_start = 0; + lockInfo.l_whence = SEEK_SET; + lockInfo.l_type = F_RDLCK; + if( osFcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) { + return &posixIoMethods; + }else{ + return &semIoMethods; + } +} +static const sqlite3_io_methods + *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl; + +#endif /* OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE */ + +/* +** An abstract type for a pointer to a IO method finder function: +*/ +typedef const sqlite3_io_methods *(*finder_type)(const char*,unixFile*); + + +/**************************************************************************** +**************************** sqlite3_vfs methods **************************** +** +** This division contains the implementation of methods on the +** sqlite3_vfs object. +*/ + +/* +** Initialize the contents of the unixFile structure pointed to by pId. +*/ +static int fillInUnixFile( + sqlite3_vfs *pVfs, /* Pointer to vfs object */ + int h, /* Open file descriptor of file being opened */ + sqlite3_file *pId, /* Write to the unixFile structure here */ + const char *zFilename, /* Name of the file being opened */ + int ctrlFlags /* Zero or more UNIXFILE_* values */ +){ + const sqlite3_io_methods *pLockingStyle; + unixFile *pNew = (unixFile *)pId; + int rc = SQLITE_OK; + + assert( pNew->pInode==NULL ); + + /* Usually the path zFilename should not be a relative pathname. The + ** exception is when opening the proxy "conch" file in builds that + ** include the special Apple locking styles. + */ +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE + assert( zFilename==0 || zFilename[0]=='/' + || pVfs->pAppData==(void*)&autolockIoFinder ); +#else + assert( zFilename==0 || zFilename[0]=='/' ); +#endif + + /* No locking occurs in temporary files */ + assert( zFilename!=0 || (ctrlFlags & UNIXFILE_NOLOCK)!=0 ); + + OSTRACE(("OPEN %-3d %s\n", h, zFilename)); + pNew->h = h; + pNew->pVfs = pVfs; + pNew->zPath = zFilename; + pNew->ctrlFlags = (u8)ctrlFlags; + if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0), + "psow", SQLITE_POWERSAFE_OVERWRITE) ){ + pNew->ctrlFlags |= UNIXFILE_PSOW; + } + if( memcmp(pVfs->zName,"unix-excl",10)==0 ){ + pNew->ctrlFlags |= UNIXFILE_EXCL; + } + +#if OS_VXWORKS + pNew->pId = vxworksFindFileId(zFilename); + if( pNew->pId==0 ){ + ctrlFlags |= UNIXFILE_NOLOCK; + rc = SQLITE_NOMEM; + } +#endif + + if( ctrlFlags & UNIXFILE_NOLOCK ){ + pLockingStyle = &nolockIoMethods; + }else{ + pLockingStyle = (**(finder_type*)pVfs->pAppData)(zFilename, pNew); +#if SQLITE_ENABLE_LOCKING_STYLE + /* Cache zFilename in the locking context (AFP and dotlock override) for + ** proxyLock activation is possible (remote proxy is based on db name) + ** zFilename remains valid until file is closed, to support */ + pNew->lockingContext = (void*)zFilename; +#endif + } + + if( pLockingStyle == &posixIoMethods +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE + || pLockingStyle == &nfsIoMethods +#endif + ){ + unixEnterMutex(); + rc = findInodeInfo(pNew, &pNew->pInode); + if( rc!=SQLITE_OK ){ + /* If an error occured in findInodeInfo(), close the file descriptor + ** immediately, before releasing the mutex. findInodeInfo() may fail + ** in two scenarios: + ** + ** (a) A call to fstat() failed. + ** (b) A malloc failed. + ** + ** Scenario (b) may only occur if the process is holding no other + ** file descriptors open on the same file. If there were other file + ** descriptors on this file, then no malloc would be required by + ** findInodeInfo(). If this is the case, it is quite safe to close + ** handle h - as it is guaranteed that no posix locks will be released + ** by doing so. + ** + ** If scenario (a) caused the error then things are not so safe. The + ** implicit assumption here is that if fstat() fails, things are in + ** such bad shape that dropping a lock or two doesn't matter much. + */ + robust_close(pNew, h, __LINE__); + h = -1; + } + unixLeaveMutex(); + } + +#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) + else if( pLockingStyle == &afpIoMethods ){ + /* AFP locking uses the file path so it needs to be included in + ** the afpLockingContext. + */ + afpLockingContext *pCtx; + pNew->lockingContext = pCtx = sqlite3_malloc( sizeof(*pCtx) ); + if( pCtx==0 ){ + rc = SQLITE_NOMEM; + }else{ + /* NB: zFilename exists and remains valid until the file is closed + ** according to requirement F11141. So we do not need to make a + ** copy of the filename. */ + pCtx->dbPath = zFilename; + pCtx->reserved = 0; + srandomdev(); + unixEnterMutex(); + rc = findInodeInfo(pNew, &pNew->pInode); + if( rc!=SQLITE_OK ){ + sqlite3_free(pNew->lockingContext); + robust_close(pNew, h, __LINE__); + h = -1; + } + unixLeaveMutex(); + } + } +#endif + + else if( pLockingStyle == &dotlockIoMethods ){ + /* Dotfile locking uses the file path so it needs to be included in + ** the dotlockLockingContext + */ + char *zLockFile; + int nFilename; + assert( zFilename!=0 ); + nFilename = (int)strlen(zFilename) + 6; + zLockFile = (char *)sqlite3_malloc(nFilename); + if( zLockFile==0 ){ + rc = SQLITE_NOMEM; + }else{ + sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename); + } + pNew->lockingContext = zLockFile; + } + +#if OS_VXWORKS + else if( pLockingStyle == &semIoMethods ){ + /* Named semaphore locking uses the file path so it needs to be + ** included in the semLockingContext + */ + unixEnterMutex(); + rc = findInodeInfo(pNew, &pNew->pInode); + if( (rc==SQLITE_OK) && (pNew->pInode->pSem==NULL) ){ + char *zSemName = pNew->pInode->aSemName; + int n; + sqlite3_snprintf(MAX_PATHNAME, zSemName, "/%s.sem", + pNew->pId->zCanonicalName); + for( n=1; zSemName[n]; n++ ) + if( zSemName[n]=='/' ) zSemName[n] = '_'; + pNew->pInode->pSem = sem_open(zSemName, O_CREAT, 0666, 1); + if( pNew->pInode->pSem == SEM_FAILED ){ + rc = SQLITE_NOMEM; + pNew->pInode->aSemName[0] = '\0'; + } + } + unixLeaveMutex(); + } +#endif + + pNew->lastErrno = 0; +#if OS_VXWORKS + if( rc!=SQLITE_OK ){ + if( h>=0 ) robust_close(pNew, h, __LINE__); + h = -1; + osUnlink(zFilename); + isDelete = 0; + } + if( isDelete ) pNew->ctrlFlags |= UNIXFILE_DELETE; +#endif + if( rc!=SQLITE_OK ){ + if( h>=0 ) robust_close(pNew, h, __LINE__); + }else{ + pNew->pMethod = pLockingStyle; + OpenCounter(+1); + } + return rc; +} + +/* +** Return the name of a directory in which to put temporary files. +** If no suitable temporary file directory can be found, return NULL. +*/ +static const char *unixTempFileDir(void){ + static const char *azDirs[] = { + 0, + 0, + "/var/tmp", + "/usr/tmp", + "/tmp", + 0 /* List terminator */ + }; + unsigned int i; + struct stat buf; + const char *zDir = 0; + + azDirs[0] = sqlite3_temp_directory; + if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR"); + for(i=0; imxPathname bytes. +*/ +static int unixGetTempname(int nBuf, char *zBuf){ + static const unsigned char zChars[] = + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789"; + unsigned int i, j; + const char *zDir; + + /* It's odd to simulate an io-error here, but really this is just + ** using the io-error infrastructure to test that SQLite handles this + ** function failing. + */ + SimulateIOError( return SQLITE_IOERR ); + + zDir = unixTempFileDir(); + if( zDir==0 ) zDir = "."; + + /* Check that the output buffer is large enough for the temporary file + ** name. If it is not, return SQLITE_ERROR. + */ + if( (strlen(zDir) + strlen(SQLITE_TEMP_FILE_PREFIX) + 18) >= (size_t)nBuf ){ + return SQLITE_ERROR; + } + + do{ + sqlite3_snprintf(nBuf-18, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX, zDir); + j = (int)strlen(zBuf); + sqlite3_randomness(15, &zBuf[j]); + for(i=0; i<15; i++, j++){ + zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; + } + zBuf[j] = 0; + zBuf[j+1] = 0; + }while( osAccess(zBuf,0)==0 ); + return SQLITE_OK; +} + +#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) +/* +** Routine to transform a unixFile into a proxy-locking unixFile. +** Implementation in the proxy-lock division, but used by unixOpen() +** if SQLITE_PREFER_PROXY_LOCKING is defined. +*/ +static int proxyTransformUnixFile(unixFile*, const char*); +#endif + +/* +** Search for an unused file descriptor that was opened on the database +** file (not a journal or master-journal file) identified by pathname +** zPath with SQLITE_OPEN_XXX flags matching those passed as the second +** argument to this function. +** +** Such a file descriptor may exist if a database connection was closed +** but the associated file descriptor could not be closed because some +** other file descriptor open on the same file is holding a file-lock. +** Refer to comments in the unixClose() function and the lengthy comment +** describing "Posix Advisory Locking" at the start of this file for +** further details. Also, ticket #4018. +** +** If a suitable file descriptor is found, then it is returned. If no +** such file descriptor is located, -1 is returned. +*/ +static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ + UnixUnusedFd *pUnused = 0; + + /* Do not search for an unused file descriptor on vxworks. Not because + ** vxworks would not benefit from the change (it might, we're not sure), + ** but because no way to test it is currently available. It is better + ** not to risk breaking vxworks support for the sake of such an obscure + ** feature. */ +#if !OS_VXWORKS + struct stat sStat; /* Results of stat() call */ + + /* A stat() call may fail for various reasons. If this happens, it is + ** almost certain that an open() call on the same path will also fail. + ** For this reason, if an error occurs in the stat() call here, it is + ** ignored and -1 is returned. The caller will try to open a new file + ** descriptor on the same path, fail, and return an error to SQLite. + ** + ** Even if a subsequent open() call does succeed, the consequences of + ** not searching for a resusable file descriptor are not dire. */ + if( 0==osStat(zPath, &sStat) ){ + unixInodeInfo *pInode; + + unixEnterMutex(); + pInode = inodeList; + while( pInode && (pInode->fileId.dev!=sStat.st_dev + || pInode->fileId.ino!=sStat.st_ino) ){ + pInode = pInode->pNext; + } + if( pInode ){ + UnixUnusedFd **pp; + for(pp=&pInode->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext)); + pUnused = *pp; + if( pUnused ){ + *pp = pUnused->pNext; + } + } + unixLeaveMutex(); + } +#endif /* if !OS_VXWORKS */ + return pUnused; +} + +/* +** This function is called by unixOpen() to determine the unix permissions +** to create new files with. If no error occurs, then SQLITE_OK is returned +** and a value suitable for passing as the third argument to open(2) is +** written to *pMode. If an IO error occurs, an SQLite error code is +** returned and the value of *pMode is not modified. +** +** If the file being opened is a temporary file, it is always created with +** the octal permissions 0600 (read/writable by owner only). If the file +** is a database or master journal file, it is created with the permissions +** mask SQLITE_DEFAULT_FILE_PERMISSIONS. +** +** Finally, if the file being opened is a WAL or regular journal file, then +** this function queries the file-system for the permissions on the +** corresponding database file and sets *pMode to this value. Whenever +** possible, WAL and journal files are created using the same permissions +** as the associated database file. +** +** If the SQLITE_ENABLE_8_3_NAMES option is enabled, then the +** original filename is unavailable. But 8_3_NAMES is only used for +** FAT filesystems and permissions do not matter there, so just use +** the default permissions. +*/ +static int findCreateFileMode( + const char *zPath, /* Path of file (possibly) being created */ + int flags, /* Flags passed as 4th argument to xOpen() */ + mode_t *pMode /* OUT: Permissions to open file with */ +){ + int rc = SQLITE_OK; /* Return Code */ + *pMode = SQLITE_DEFAULT_FILE_PERMISSIONS; + if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){ + char zDb[MAX_PATHNAME+1]; /* Database file path */ + int nDb; /* Number of valid bytes in zDb */ + struct stat sStat; /* Output of stat() on database file */ + + /* zPath is a path to a WAL or journal file. The following block derives + ** the path to the associated database file from zPath. This block handles + ** the following naming conventions: + ** + ** "-journal" + ** "-wal" + ** "-journalNN" + ** "-walNN" + ** + ** where NN is a decimal number. The NN naming schemes are + ** used by the test_multiplex.c module. + */ + nDb = sqlite3Strlen30(zPath) - 1; +#ifdef SQLITE_ENABLE_8_3_NAMES + while( nDb>0 && sqlite3Isalnum(zPath[nDb]) ) nDb--; + if( nDb==0 || zPath[nDb]!='-' ) return SQLITE_OK; +#else + while( zPath[nDb]!='-' ){ + assert( nDb>0 ); + assert( zPath[nDb]!='\n' ); + nDb--; + } +#endif + memcpy(zDb, zPath, nDb); + zDb[nDb] = '\0'; + + if( 0==osStat(zDb, &sStat) ){ + *pMode = sStat.st_mode & 0777; + }else{ + rc = SQLITE_IOERR_FSTAT; + } + }else if( flags & SQLITE_OPEN_DELETEONCLOSE ){ + *pMode = 0600; + } + return rc; +} + +/* +** Open the file zPath. +** +** Previously, the SQLite OS layer used three functions in place of this +** one: +** +** sqlite3OsOpenReadWrite(); +** sqlite3OsOpenReadOnly(); +** sqlite3OsOpenExclusive(); +** +** These calls correspond to the following combinations of flags: +** +** ReadWrite() -> (READWRITE | CREATE) +** ReadOnly() -> (READONLY) +** OpenExclusive() -> (READWRITE | CREATE | EXCLUSIVE) +** +** The old OpenExclusive() accepted a boolean argument - "delFlag". If +** true, the file was configured to be automatically deleted when the +** file handle closed. To achieve the same effect using this new +** interface, add the DELETEONCLOSE flag to those specified above for +** OpenExclusive(). +*/ +static int unixOpen( + sqlite3_vfs *pVfs, /* The VFS for which this is the xOpen method */ + const char *zPath, /* Pathname of file to be opened */ + sqlite3_file *pFile, /* The file descriptor to be filled in */ + int flags, /* Input flags to control the opening */ + int *pOutFlags /* Output flags returned to SQLite core */ +){ + unixFile *p = (unixFile *)pFile; + int fd = -1; /* File descriptor returned by open() */ + int openFlags = 0; /* Flags to pass to open() */ + int eType = flags&0xFFFFFF00; /* Type of file to open */ + int noLock; /* True to omit locking primitives */ + int rc = SQLITE_OK; /* Function Return Code */ + int ctrlFlags = 0; /* UNIXFILE_* flags */ + + int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); + int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE); + int isCreate = (flags & SQLITE_OPEN_CREATE); + int isReadonly = (flags & SQLITE_OPEN_READONLY); + int isReadWrite = (flags & SQLITE_OPEN_READWRITE); +#if SQLITE_ENABLE_LOCKING_STYLE + int isAutoProxy = (flags & SQLITE_OPEN_AUTOPROXY); +#endif +#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE + struct statfs fsInfo; +#endif + + /* If creating a master or main-file journal, this function will open + ** a file-descriptor on the directory too. The first time unixSync() + ** is called the directory file descriptor will be fsync()ed and close()d. + */ + int syncDir = (isCreate && ( + eType==SQLITE_OPEN_MASTER_JOURNAL + || eType==SQLITE_OPEN_MAIN_JOURNAL + || eType==SQLITE_OPEN_WAL + )); + + /* If argument zPath is a NULL pointer, this function is required to open + ** a temporary file. Use this buffer to store the file name in. + */ + char zTmpname[MAX_PATHNAME+2]; + const char *zName = zPath; + + /* Check the following statements are true: + ** + ** (a) Exactly one of the READWRITE and READONLY flags must be set, and + ** (b) if CREATE is set, then READWRITE must also be set, and + ** (c) if EXCLUSIVE is set, then CREATE must also be set. + ** (d) if DELETEONCLOSE is set, then CREATE must also be set. + */ + assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly)); + assert(isCreate==0 || isReadWrite); + assert(isExclusive==0 || isCreate); + assert(isDelete==0 || isCreate); + + /* The main DB, main journal, WAL file and master journal are never + ** automatically deleted. Nor are they ever temporary files. */ + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL ); + + /* Assert that the upper layer has set one of the "file-type" flags. */ + assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB + || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL + || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL + || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL + ); + + memset(p, 0, sizeof(unixFile)); + + if( eType==SQLITE_OPEN_MAIN_DB ){ + UnixUnusedFd *pUnused; + pUnused = findReusableFd(zName, flags); + if( pUnused ){ + fd = pUnused->fd; + }else{ + pUnused = sqlite3_malloc(sizeof(*pUnused)); + if( !pUnused ){ + return SQLITE_NOMEM; + } + } + p->pUnused = pUnused; + + /* Database filenames are double-zero terminated if they are not + ** URIs with parameters. Hence, they can always be passed into + ** sqlite3_uri_parameter(). */ + assert( (flags & SQLITE_OPEN_URI) || zName[strlen(zName)+1]==0 ); + + }else if( !zName ){ + /* If zName is NULL, the upper layer is requesting a temp file. */ + assert(isDelete && !syncDir); + rc = unixGetTempname(MAX_PATHNAME+2, zTmpname); + if( rc!=SQLITE_OK ){ + return rc; + } + zName = zTmpname; + + /* Generated temporary filenames are always double-zero terminated + ** for use by sqlite3_uri_parameter(). */ + assert( zName[strlen(zName)+1]==0 ); + } + + /* Determine the value of the flags parameter passed to POSIX function + ** open(). These must be calculated even if open() is not called, as + ** they may be stored as part of the file handle and used by the + ** 'conch file' locking functions later on. */ + if( isReadonly ) openFlags |= O_RDONLY; + if( isReadWrite ) openFlags |= O_RDWR; + if( isCreate ) openFlags |= O_CREAT; + if( isExclusive ) openFlags |= (O_EXCL|O_NOFOLLOW); + openFlags |= (O_LARGEFILE|O_BINARY); + + if( fd<0 ){ + mode_t openMode; /* Permissions to create file with */ + rc = findCreateFileMode(zName, flags, &openMode); + if( rc!=SQLITE_OK ){ + assert( !p->pUnused ); + assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL ); + return rc; + } + fd = robust_open(zName, openFlags, openMode); + OSTRACE(("OPENX %-3d %s 0%o\n", fd, zName, openFlags)); + if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){ + /* Failed to open the file for read/write access. Try read-only. */ + flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); + openFlags &= ~(O_RDWR|O_CREAT); + flags |= SQLITE_OPEN_READONLY; + openFlags |= O_RDONLY; + isReadonly = 1; + fd = robust_open(zName, openFlags, openMode); + } + if( fd<0 ){ + rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName); + goto open_finished; + } + } + assert( fd>=0 ); + if( pOutFlags ){ + *pOutFlags = flags; + } + + if( p->pUnused ){ + p->pUnused->fd = fd; + p->pUnused->flags = flags; + } + + if( isDelete ){ +#if OS_VXWORKS + zPath = zName; +#else + osUnlink(zName); +#endif + } +#if SQLITE_ENABLE_LOCKING_STYLE + else{ + p->openFlags = openFlags; + } +#endif + +#ifdef FD_CLOEXEC + osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC); +#endif + + noLock = eType!=SQLITE_OPEN_MAIN_DB; + + +#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE + if( fstatfs(fd, &fsInfo) == -1 ){ + ((unixFile*)pFile)->lastErrno = errno; + robust_close(p, fd, __LINE__); + return SQLITE_IOERR_ACCESS; + } + if (0 == strncmp("msdos", fsInfo.f_fstypename, 5)) { + ((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS; + } +#endif + + /* Set up appropriate ctrlFlags */ + if( isDelete ) ctrlFlags |= UNIXFILE_DELETE; + if( isReadonly ) ctrlFlags |= UNIXFILE_RDONLY; + if( noLock ) ctrlFlags |= UNIXFILE_NOLOCK; + if( syncDir ) ctrlFlags |= UNIXFILE_DIRSYNC; + if( flags & SQLITE_OPEN_URI ) ctrlFlags |= UNIXFILE_URI; + +#if SQLITE_ENABLE_LOCKING_STYLE +#if SQLITE_PREFER_PROXY_LOCKING + isAutoProxy = 1; +#endif + if( isAutoProxy && (zPath!=NULL) && (!noLock) && pVfs->xOpen ){ + char *envforce = getenv("SQLITE_FORCE_PROXY_LOCKING"); + int useProxy = 0; + + /* SQLITE_FORCE_PROXY_LOCKING==1 means force always use proxy, 0 means + ** never use proxy, NULL means use proxy for non-local files only. */ + if( envforce!=NULL ){ + useProxy = atoi(envforce)>0; + }else{ + if( statfs(zPath, &fsInfo) == -1 ){ + /* In theory, the close(fd) call is sub-optimal. If the file opened + ** with fd is a database file, and there are other connections open + ** on that file that are currently holding advisory locks on it, + ** then the call to close() will cancel those locks. In practice, + ** we're assuming that statfs() doesn't fail very often. At least + ** not while other file descriptors opened by the same process on + ** the same file are working. */ + p->lastErrno = errno; + robust_close(p, fd, __LINE__); + rc = SQLITE_IOERR_ACCESS; + goto open_finished; + } + useProxy = !(fsInfo.f_flags&MNT_LOCAL); + } + if( useProxy ){ + rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags); + if( rc==SQLITE_OK ){ + rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:"); + if( rc!=SQLITE_OK ){ + /* Use unixClose to clean up the resources added in fillInUnixFile + ** and clear all the structure's references. Specifically, + ** pFile->pMethods will be NULL so sqlite3OsClose will be a no-op + */ + unixClose(pFile); + return rc; + } + } + goto open_finished; + } + } +#endif + + rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags); + +open_finished: + if( rc!=SQLITE_OK ){ + sqlite3_free(p->pUnused); + } + return rc; +} + + +/* +** Delete the file at zPath. If the dirSync argument is true, fsync() +** the directory after deleting the file. +*/ +static int unixDelete( + sqlite3_vfs *NotUsed, /* VFS containing this as the xDelete method */ + const char *zPath, /* Name of file to be deleted */ + int dirSync /* If true, fsync() directory after deleting file */ +){ + int rc = SQLITE_OK; + UNUSED_PARAMETER(NotUsed); + SimulateIOError(return SQLITE_IOERR_DELETE); + if( osUnlink(zPath)==(-1) && errno!=ENOENT ){ + return unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath); + } +#ifndef SQLITE_DISABLE_DIRSYNC + if( (dirSync & 1)!=0 ){ + int fd; + rc = osOpenDirectory(zPath, &fd); + if( rc==SQLITE_OK ){ +#if OS_VXWORKS + if( fsync(fd)==-1 ) +#else + if( fsync(fd) ) +#endif + { + rc = unixLogError(SQLITE_IOERR_DIR_FSYNC, "fsync", zPath); + } + robust_close(0, fd, __LINE__); + }else if( rc==SQLITE_CANTOPEN ){ + rc = SQLITE_OK; + } + } +#endif + return rc; +} + +/* +** Test the existance of or access permissions of file zPath. The +** test performed depends on the value of flags: +** +** SQLITE_ACCESS_EXISTS: Return 1 if the file exists +** SQLITE_ACCESS_READWRITE: Return 1 if the file is read and writable. +** SQLITE_ACCESS_READONLY: Return 1 if the file is readable. +** +** Otherwise return 0. +*/ +static int unixAccess( + sqlite3_vfs *NotUsed, /* The VFS containing this xAccess method */ + const char *zPath, /* Path of the file to examine */ + int flags, /* What do we want to learn about the zPath file? */ + int *pResOut /* Write result boolean here */ +){ + int amode = 0; + UNUSED_PARAMETER(NotUsed); + SimulateIOError( return SQLITE_IOERR_ACCESS; ); + switch( flags ){ + case SQLITE_ACCESS_EXISTS: + amode = F_OK; + break; + case SQLITE_ACCESS_READWRITE: + amode = W_OK|R_OK; + break; + case SQLITE_ACCESS_READ: + amode = R_OK; + break; + + default: + assert(!"Invalid flags argument"); + } + *pResOut = (osAccess(zPath, amode)==0); + if( flags==SQLITE_ACCESS_EXISTS && *pResOut ){ + struct stat buf; + if( 0==osStat(zPath, &buf) && buf.st_size==0 ){ + *pResOut = 0; + } + } + return SQLITE_OK; +} + + +/* +** Turn a relative pathname into a full pathname. The relative path +** is stored as a nul-terminated string in the buffer pointed to by +** zPath. +** +** zOut points to a buffer of at least sqlite3_vfs.mxPathname bytes +** (in this case, MAX_PATHNAME bytes). The full-path is written to +** this buffer before returning. +*/ +static int unixFullPathname( + sqlite3_vfs *pVfs, /* Pointer to vfs object */ + const char *zPath, /* Possibly relative input path */ + int nOut, /* Size of output buffer in bytes */ + char *zOut /* Output buffer */ +){ + + /* It's odd to simulate an io-error here, but really this is just + ** using the io-error infrastructure to test that SQLite handles this + ** function failing. This function could fail if, for example, the + ** current working directory has been unlinked. + */ + SimulateIOError( return SQLITE_ERROR ); + + assert( pVfs->mxPathname==MAX_PATHNAME ); + UNUSED_PARAMETER(pVfs); + + zOut[nOut-1] = '\0'; + if( zPath[0]=='/' ){ + sqlite3_snprintf(nOut, zOut, "%s", zPath); + }else{ + int nCwd; + if( osGetcwd(zOut, nOut-1)==0 ){ + return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath); + } + nCwd = (int)strlen(zOut); + sqlite3_snprintf(nOut-nCwd, &zOut[nCwd], "/%s", zPath); + } + return SQLITE_OK; +} + + +#ifndef SQLITE_OMIT_LOAD_EXTENSION +/* +** Interfaces for opening a shared library, finding entry points +** within the shared library, and closing the shared library. +*/ +#include +static void *unixDlOpen(sqlite3_vfs *NotUsed, const char *zFilename){ + UNUSED_PARAMETER(NotUsed); + return dlopen(zFilename, RTLD_NOW | RTLD_GLOBAL); +} + +/* +** SQLite calls this function immediately after a call to unixDlSym() or +** unixDlOpen() fails (returns a null pointer). If a more detailed error +** message is available, it is written to zBufOut. If no error message +** is available, zBufOut is left unmodified and SQLite uses a default +** error message. +*/ +static void unixDlError(sqlite3_vfs *NotUsed, int nBuf, char *zBufOut){ + const char *zErr; + UNUSED_PARAMETER(NotUsed); + unixEnterMutex(); + zErr = dlerror(); + if( zErr ){ + sqlite3_snprintf(nBuf, zBufOut, "%s", zErr); + } + unixLeaveMutex(); +} +static void (*unixDlSym(sqlite3_vfs *NotUsed, void *p, const char*zSym))(void){ + /* + ** GCC with -pedantic-errors says that C90 does not allow a void* to be + ** cast into a pointer to a function. And yet the library dlsym() routine + ** returns a void* which is really a pointer to a function. So how do we + ** use dlsym() with -pedantic-errors? + ** + ** Variable x below is defined to be a pointer to a function taking + ** parameters void* and const char* and returning a pointer to a function. + ** We initialize x by assigning it a pointer to the dlsym() function. + ** (That assignment requires a cast.) Then we call the function that + ** x points to. + ** + ** This work-around is unlikely to work correctly on any system where + ** you really cannot cast a function pointer into void*. But then, on the + ** other hand, dlsym() will not work on such a system either, so we have + ** not really lost anything. + */ + void (*(*x)(void*,const char*))(void); + UNUSED_PARAMETER(NotUsed); + x = (void(*(*)(void*,const char*))(void))dlsym; + return (*x)(p, zSym); +} +static void unixDlClose(sqlite3_vfs *NotUsed, void *pHandle){ + UNUSED_PARAMETER(NotUsed); + dlclose(pHandle); +} +#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */ + #define unixDlOpen 0 + #define unixDlError 0 + #define unixDlSym 0 + #define unixDlClose 0 +#endif + +/* +** Write nBuf bytes of random data to the supplied buffer zBuf. +*/ +static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){ + UNUSED_PARAMETER(NotUsed); + assert((size_t)nBuf>=(sizeof(time_t)+sizeof(int))); + + /* We have to initialize zBuf to prevent valgrind from reporting + ** errors. The reports issued by valgrind are incorrect - we would + ** prefer that the randomness be increased by making use of the + ** uninitialized space in zBuf - but valgrind errors tend to worry + ** some users. Rather than argue, it seems easier just to initialize + ** the whole array and silence valgrind, even if that means less randomness + ** in the random seed. + ** + ** When testing, initializing zBuf[] to zero is all we do. That means + ** that we always use the same random number sequence. This makes the + ** tests repeatable. + */ + memset(zBuf, 0, nBuf); +#if !defined(SQLITE_TEST) + { + int pid, fd; + fd = robust_open("/dev/urandom", O_RDONLY, 0); + if( fd<0 ){ + time_t t; + time(&t); + memcpy(zBuf, &t, sizeof(t)); + pid = getpid(); + memcpy(&zBuf[sizeof(t)], &pid, sizeof(pid)); + assert( sizeof(t)+sizeof(pid)<=(size_t)nBuf ); + nBuf = sizeof(t) + sizeof(pid); + }else{ + do{ nBuf = osRead(fd, zBuf, nBuf); }while( nBuf<0 && errno==EINTR ); + robust_close(0, fd, __LINE__); + } + } +#endif + return nBuf; +} + + +/* +** Sleep for a little while. Return the amount of time slept. +** The argument is the number of microseconds we want to sleep. +** The return value is the number of microseconds of sleep actually +** requested from the underlying operating system, a number which +** might be greater than or equal to the argument, but not less +** than the argument. +*/ +static int unixSleep(sqlite3_vfs *NotUsed, int microseconds){ +#if OS_VXWORKS + struct timespec sp; + + sp.tv_sec = microseconds / 1000000; + sp.tv_nsec = (microseconds % 1000000) * 1000; + nanosleep(&sp, NULL); + UNUSED_PARAMETER(NotUsed); + return microseconds; +#elif defined(HAVE_USLEEP) && HAVE_USLEEP + usleep(microseconds); + UNUSED_PARAMETER(NotUsed); + return microseconds; +#else + int seconds = (microseconds+999999)/1000000; + sleep(seconds); + UNUSED_PARAMETER(NotUsed); + return seconds*1000000; +#endif +} + +/* +** The following variable, if set to a non-zero value, is interpreted as +** the number of seconds since 1970 and is used to set the result of +** sqlite3OsCurrentTime() during testing. +*/ +#ifdef SQLITE_TEST +int sqlite3_current_time = 0; /* Fake system time in seconds since 1970. */ +#endif + +/* +** Find the current time (in Universal Coordinated Time). Write into *piNow +** the current time and date as a Julian Day number times 86_400_000. In +** other words, write into *piNow the number of milliseconds since the Julian +** epoch of noon in Greenwich on November 24, 4714 B.C according to the +** proleptic Gregorian calendar. +** +** On success, return SQLITE_OK. Return SQLITE_ERROR if the time and date +** cannot be found. +*/ +static int unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){ + static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000; + int rc = SQLITE_OK; +#if defined(NO_GETTOD) + time_t t; + time(&t); + *piNow = ((sqlite3_int64)t)*1000 + unixEpoch; +#elif OS_VXWORKS + struct timespec sNow; + clock_gettime(CLOCK_REALTIME, &sNow); + *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_nsec/1000000; +#else + struct timeval sNow; + if( gettimeofday(&sNow, 0)==0 ){ + *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000; + }else{ + rc = SQLITE_ERROR; + } +#endif + +#ifdef SQLITE_TEST + if( sqlite3_current_time ){ + *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch; + } +#endif + UNUSED_PARAMETER(NotUsed); + return rc; +} + +/* +** Find the current time (in Universal Coordinated Time). Write the +** current time and date as a Julian Day number into *prNow and +** return 0. Return 1 if the time and date cannot be found. +*/ +static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){ + sqlite3_int64 i = 0; + int rc; + UNUSED_PARAMETER(NotUsed); + rc = unixCurrentTimeInt64(0, &i); + *prNow = i/86400000.0; + return rc; +} + +/* +** We added the xGetLastError() method with the intention of providing +** better low-level error messages when operating-system problems come up +** during SQLite operation. But so far, none of that has been implemented +** in the core. So this routine is never called. For now, it is merely +** a place-holder. +*/ +static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){ + UNUSED_PARAMETER(NotUsed); + UNUSED_PARAMETER(NotUsed2); + UNUSED_PARAMETER(NotUsed3); + return 0; +} + + +/* +************************ End of sqlite3_vfs methods *************************** +******************************************************************************/ + +/****************************************************************************** +************************** Begin Proxy Locking ******************************** +** +** Proxy locking is a "uber-locking-method" in this sense: It uses the +** other locking methods on secondary lock files. Proxy locking is a +** meta-layer over top of the primitive locking implemented above. For +** this reason, the division that implements of proxy locking is deferred +** until late in the file (here) after all of the other I/O methods have +** been defined - so that the primitive locking methods are available +** as services to help with the implementation of proxy locking. +** +**** +** +** The default locking schemes in SQLite use byte-range locks on the +** database file to coordinate safe, concurrent access by multiple readers +** and writers [http://sqlite.org/lockingv3.html]. The five file locking +** states (UNLOCKED, PENDING, SHARED, RESERVED, EXCLUSIVE) are implemented +** as POSIX read & write locks over fixed set of locations (via fsctl), +** on AFP and SMB only exclusive byte-range locks are available via fsctl +** with _IOWR('z', 23, struct ByteRangeLockPB2) to track the same 5 states. +** To simulate a F_RDLCK on the shared range, on AFP a randomly selected +** address in the shared range is taken for a SHARED lock, the entire +** shared range is taken for an EXCLUSIVE lock): +** +** PENDING_BYTE 0x40000000 +** RESERVED_BYTE 0x40000001 +** SHARED_RANGE 0x40000002 -> 0x40000200 +** +** This works well on the local file system, but shows a nearly 100x +** slowdown in read performance on AFP because the AFP client disables +** the read cache when byte-range locks are present. Enabling the read +** cache exposes a cache coherency problem that is present on all OS X +** supported network file systems. NFS and AFP both observe the +** close-to-open semantics for ensuring cache coherency +** [http://nfs.sourceforge.net/#faq_a8], which does not effectively +** address the requirements for concurrent database access by multiple +** readers and writers +** [http://www.nabble.com/SQLite-on-NFS-cache-coherency-td15655701.html]. +** +** To address the performance and cache coherency issues, proxy file locking +** changes the way database access is controlled by limiting access to a +** single host at a time and moving file locks off of the database file +** and onto a proxy file on the local file system. +** +** +** Using proxy locks +** ----------------- +** +** C APIs +** +** sqlite3_file_control(db, dbname, SQLITE_SET_LOCKPROXYFILE, +** | ":auto:"); +** sqlite3_file_control(db, dbname, SQLITE_GET_LOCKPROXYFILE, &); +** +** +** SQL pragmas +** +** PRAGMA [database.]lock_proxy_file= | :auto: +** PRAGMA [database.]lock_proxy_file +** +** Specifying ":auto:" means that if there is a conch file with a matching +** host ID in it, the proxy path in the conch file will be used, otherwise +** a proxy path based on the user's temp dir +** (via confstr(_CS_DARWIN_USER_TEMP_DIR,...)) will be used and the +** actual proxy file name is generated from the name and path of the +** database file. For example: +** +** For database path "/Users/me/foo.db" +** The lock path will be "/sqliteplocks/_Users_me_foo.db:auto:") +** +** Once a lock proxy is configured for a database connection, it can not +** be removed, however it may be switched to a different proxy path via +** the above APIs (assuming the conch file is not being held by another +** connection or process). +** +** +** How proxy locking works +** ----------------------- +** +** Proxy file locking relies primarily on two new supporting files: +** +** * conch file to limit access to the database file to a single host +** at a time +** +** * proxy file to act as a proxy for the advisory locks normally +** taken on the database +** +** The conch file - to use a proxy file, sqlite must first "hold the conch" +** by taking an sqlite-style shared lock on the conch file, reading the +** contents and comparing the host's unique host ID (see below) and lock +** proxy path against the values stored in the conch. The conch file is +** stored in the same directory as the database file and the file name +** is patterned after the database file name as ".-conch". +** If the conch file does not exist, or it's contents do not match the +** host ID and/or proxy path, then the lock is escalated to an exclusive +** lock and the conch file contents is updated with the host ID and proxy +** path and the lock is downgraded to a shared lock again. If the conch +** is held by another process (with a shared lock), the exclusive lock +** will fail and SQLITE_BUSY is returned. +** +** The proxy file - a single-byte file used for all advisory file locks +** normally taken on the database file. This allows for safe sharing +** of the database file for multiple readers and writers on the same +** host (the conch ensures that they all use the same local lock file). +** +** Requesting the lock proxy does not immediately take the conch, it is +** only taken when the first request to lock database file is made. +** This matches the semantics of the traditional locking behavior, where +** opening a connection to a database file does not take a lock on it. +** The shared lock and an open file descriptor are maintained until +** the connection to the database is closed. +** +** The proxy file and the lock file are never deleted so they only need +** to be created the first time they are used. +** +** Configuration options +** --------------------- +** +** SQLITE_PREFER_PROXY_LOCKING +** +** Database files accessed on non-local file systems are +** automatically configured for proxy locking, lock files are +** named automatically using the same logic as +** PRAGMA lock_proxy_file=":auto:" +** +** SQLITE_PROXY_DEBUG +** +** Enables the logging of error messages during host id file +** retrieval and creation +** +** LOCKPROXYDIR +** +** Overrides the default directory used for lock proxy files that +** are named automatically via the ":auto:" setting +** +** SQLITE_DEFAULT_PROXYDIR_PERMISSIONS +** +** Permissions to use when creating a directory for storing the +** lock proxy files, only used when LOCKPROXYDIR is not set. +** +** +** As mentioned above, when compiled with SQLITE_PREFER_PROXY_LOCKING, +** setting the environment variable SQLITE_FORCE_PROXY_LOCKING to 1 will +** force proxy locking to be used for every database file opened, and 0 +** will force automatic proxy locking to be disabled for all database +** files (explicity calling the SQLITE_SET_LOCKPROXYFILE pragma or +** sqlite_file_control API is not affected by SQLITE_FORCE_PROXY_LOCKING). +*/ + +/* +** Proxy locking is only available on MacOSX +*/ +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE + +/* +** The proxyLockingContext has the path and file structures for the remote +** and local proxy files in it +*/ +typedef struct proxyLockingContext proxyLockingContext; +struct proxyLockingContext { + unixFile *conchFile; /* Open conch file */ + char *conchFilePath; /* Name of the conch file */ + unixFile *lockProxy; /* Open proxy lock file */ + char *lockProxyPath; /* Name of the proxy lock file */ + char *dbPath; /* Name of the open file */ + int conchHeld; /* 1 if the conch is held, -1 if lockless */ + void *oldLockingContext; /* Original lockingcontext to restore on close */ + sqlite3_io_methods const *pOldMethod; /* Original I/O methods for close */ +}; + +/* +** The proxy lock file path for the database at dbPath is written into lPath, +** which must point to valid, writable memory large enough for a maxLen length +** file path. +*/ +static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){ + int len; + int dbLen; + int i; + +#ifdef LOCKPROXYDIR + len = strlcpy(lPath, LOCKPROXYDIR, maxLen); +#else +# ifdef _CS_DARWIN_USER_TEMP_DIR + { + if( !confstr(_CS_DARWIN_USER_TEMP_DIR, lPath, maxLen) ){ + OSTRACE(("GETLOCKPATH failed %s errno=%d pid=%d\n", + lPath, errno, getpid())); + return SQLITE_IOERR_LOCK; + } + len = strlcat(lPath, "sqliteplocks", maxLen); + } +# else + len = strlcpy(lPath, "/tmp/", maxLen); +# endif +#endif + + if( lPath[len-1]!='/' ){ + len = strlcat(lPath, "/", maxLen); + } + + /* transform the db path to a unique cache name */ + dbLen = (int)strlen(dbPath); + for( i=0; i 0) ){ + /* only mkdir if leaf dir != "." or "/" or ".." */ + if( i-start>2 || (i-start==1 && buf[start] != '.' && buf[start] != '/') + || (i-start==2 && buf[start] != '.' && buf[start+1] != '.') ){ + buf[i]='\0'; + if( osMkdir(buf, SQLITE_DEFAULT_PROXYDIR_PERMISSIONS) ){ + int err=errno; + if( err!=EEXIST ) { + OSTRACE(("CREATELOCKPATH FAILED creating %s, " + "'%s' proxy lock path=%s pid=%d\n", + buf, strerror(err), lockPath, getpid())); + return err; + } + } + } + start=i+1; + } + buf[i] = lockPath[i]; + } + OSTRACE(("CREATELOCKPATH proxy lock path=%s pid=%d\n", lockPath, getpid())); + return 0; +} + +/* +** Create a new VFS file descriptor (stored in memory obtained from +** sqlite3_malloc) and open the file named "path" in the file descriptor. +** +** The caller is responsible not only for closing the file descriptor +** but also for freeing the memory associated with the file descriptor. +*/ +static int proxyCreateUnixFile( + const char *path, /* path for the new unixFile */ + unixFile **ppFile, /* unixFile created and returned by ref */ + int islockfile /* if non zero missing dirs will be created */ +) { + int fd = -1; + unixFile *pNew; + int rc = SQLITE_OK; + int openFlags = O_RDWR | O_CREAT; + sqlite3_vfs dummyVfs; + int terrno = 0; + UnixUnusedFd *pUnused = NULL; + + /* 1. first try to open/create the file + ** 2. if that fails, and this is a lock file (not-conch), try creating + ** the parent directories and then try again. + ** 3. if that fails, try to open the file read-only + ** otherwise return BUSY (if lock file) or CANTOPEN for the conch file + */ + pUnused = findReusableFd(path, openFlags); + if( pUnused ){ + fd = pUnused->fd; + }else{ + pUnused = sqlite3_malloc(sizeof(*pUnused)); + if( !pUnused ){ + return SQLITE_NOMEM; + } + } + if( fd<0 ){ + fd = robust_open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); + terrno = errno; + if( fd<0 && errno==ENOENT && islockfile ){ + if( proxyCreateLockPath(path) == SQLITE_OK ){ + fd = robust_open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); + } + } + } + if( fd<0 ){ + openFlags = O_RDONLY; + fd = robust_open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); + terrno = errno; + } + if( fd<0 ){ + if( islockfile ){ + return SQLITE_BUSY; + } + switch (terrno) { + case EACCES: + return SQLITE_PERM; + case EIO: + return SQLITE_IOERR_LOCK; /* even though it is the conch */ + default: + return SQLITE_CANTOPEN_BKPT; + } + } + + pNew = (unixFile *)sqlite3_malloc(sizeof(*pNew)); + if( pNew==NULL ){ + rc = SQLITE_NOMEM; + goto end_create_proxy; + } + memset(pNew, 0, sizeof(unixFile)); + pNew->openFlags = openFlags; + memset(&dummyVfs, 0, sizeof(dummyVfs)); + dummyVfs.pAppData = (void*)&autolockIoFinder; + dummyVfs.zName = "dummy"; + pUnused->fd = fd; + pUnused->flags = openFlags; + pNew->pUnused = pUnused; + + rc = fillInUnixFile(&dummyVfs, fd, (sqlite3_file*)pNew, path, 0); + if( rc==SQLITE_OK ){ + *ppFile = pNew; + return SQLITE_OK; + } +end_create_proxy: + robust_close(pNew, fd, __LINE__); + sqlite3_free(pNew); + sqlite3_free(pUnused); + return rc; +} + +#ifdef SQLITE_TEST +/* simulate multiple hosts by creating unique hostid file paths */ +int sqlite3_hostid_num = 0; +#endif + +#define PROXY_HOSTIDLEN 16 /* conch file host id length */ + +/* Not always defined in the headers as it ought to be */ +extern int gethostuuid(uuid_t id, const struct timespec *wait); + +/* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN +** bytes of writable memory. +*/ +static int proxyGetHostID(unsigned char *pHostID, int *pError){ + assert(PROXY_HOSTIDLEN == sizeof(uuid_t)); + memset(pHostID, 0, PROXY_HOSTIDLEN); +#if defined(__MAX_OS_X_VERSION_MIN_REQUIRED)\ + && __MAC_OS_X_VERSION_MIN_REQUIRED<1050 + { + static const struct timespec timeout = {1, 0}; /* 1 sec timeout */ + if( gethostuuid(pHostID, &timeout) ){ + int err = errno; + if( pError ){ + *pError = err; + } + return SQLITE_IOERR; + } + } +#else + UNUSED_PARAMETER(pError); +#endif +#ifdef SQLITE_TEST + /* simulate multiple hosts by creating unique hostid file paths */ + if( sqlite3_hostid_num != 0){ + pHostID[0] = (char)(pHostID[0] + (char)(sqlite3_hostid_num & 0xFF)); + } +#endif + + return SQLITE_OK; +} + +/* The conch file contains the header, host id and lock file path + */ +#define PROXY_CONCHVERSION 2 /* 1-byte header, 16-byte host id, path */ +#define PROXY_HEADERLEN 1 /* conch file header length */ +#define PROXY_PATHINDEX (PROXY_HEADERLEN+PROXY_HOSTIDLEN) +#define PROXY_MAXCONCHLEN (PROXY_HEADERLEN+PROXY_HOSTIDLEN+MAXPATHLEN) + +/* +** Takes an open conch file, copies the contents to a new path and then moves +** it back. The newly created file's file descriptor is assigned to the +** conch file structure and finally the original conch file descriptor is +** closed. Returns zero if successful. +*/ +static int proxyBreakConchLock(unixFile *pFile, uuid_t myHostID){ + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + unixFile *conchFile = pCtx->conchFile; + char tPath[MAXPATHLEN]; + char buf[PROXY_MAXCONCHLEN]; + char *cPath = pCtx->conchFilePath; + size_t readLen = 0; + size_t pathLen = 0; + char errmsg[64] = ""; + int fd = -1; + int rc = -1; + UNUSED_PARAMETER(myHostID); + + /* create a new path by replace the trailing '-conch' with '-break' */ + pathLen = strlcpy(tPath, cPath, MAXPATHLEN); + if( pathLen>MAXPATHLEN || pathLen<6 || + (strlcpy(&tPath[pathLen-5], "break", 6) != 5) ){ + sqlite3_snprintf(sizeof(errmsg),errmsg,"path error (len %d)",(int)pathLen); + goto end_breaklock; + } + /* read the conch content */ + readLen = osPread(conchFile->h, buf, PROXY_MAXCONCHLEN, 0); + if( readLenh, __LINE__); + conchFile->h = fd; + conchFile->openFlags = O_RDWR | O_CREAT; + +end_breaklock: + if( rc ){ + if( fd>=0 ){ + osUnlink(tPath); + robust_close(pFile, fd, __LINE__); + } + fprintf(stderr, "failed to break stale lock on %s, %s\n", cPath, errmsg); + } + return rc; +} + +/* Take the requested lock on the conch file and break a stale lock if the +** host id matches. +*/ +static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){ + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + unixFile *conchFile = pCtx->conchFile; + int rc = SQLITE_OK; + int nTries = 0; + struct timespec conchModTime; + + memset(&conchModTime, 0, sizeof(conchModTime)); + do { + rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType); + nTries ++; + if( rc==SQLITE_BUSY ){ + /* If the lock failed (busy): + * 1st try: get the mod time of the conch, wait 0.5s and try again. + * 2nd try: fail if the mod time changed or host id is different, wait + * 10 sec and try again + * 3rd try: break the lock unless the mod time has changed. + */ + struct stat buf; + if( osFstat(conchFile->h, &buf) ){ + pFile->lastErrno = errno; + return SQLITE_IOERR_LOCK; + } + + if( nTries==1 ){ + conchModTime = buf.st_mtimespec; + usleep(500000); /* wait 0.5 sec and try the lock again*/ + continue; + } + + assert( nTries>1 ); + if( conchModTime.tv_sec != buf.st_mtimespec.tv_sec || + conchModTime.tv_nsec != buf.st_mtimespec.tv_nsec ){ + return SQLITE_BUSY; + } + + if( nTries==2 ){ + char tBuf[PROXY_MAXCONCHLEN]; + int len = osPread(conchFile->h, tBuf, PROXY_MAXCONCHLEN, 0); + if( len<0 ){ + pFile->lastErrno = errno; + return SQLITE_IOERR_LOCK; + } + if( len>PROXY_PATHINDEX && tBuf[0]==(char)PROXY_CONCHVERSION){ + /* don't break the lock if the host id doesn't match */ + if( 0!=memcmp(&tBuf[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN) ){ + return SQLITE_BUSY; + } + }else{ + /* don't break the lock on short read or a version mismatch */ + return SQLITE_BUSY; + } + usleep(10000000); /* wait 10 sec and try the lock again */ + continue; + } + + assert( nTries==3 ); + if( 0==proxyBreakConchLock(pFile, myHostID) ){ + rc = SQLITE_OK; + if( lockType==EXCLUSIVE_LOCK ){ + rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, SHARED_LOCK); + } + if( !rc ){ + rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType); + } + } + } + } while( rc==SQLITE_BUSY && nTries<3 ); + + return rc; +} + +/* Takes the conch by taking a shared lock and read the contents conch, if +** lockPath is non-NULL, the host ID and lock file path must match. A NULL +** lockPath means that the lockPath in the conch file will be used if the +** host IDs match, or a new lock path will be generated automatically +** and written to the conch file. +*/ +static int proxyTakeConch(unixFile *pFile){ + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + + if( pCtx->conchHeld!=0 ){ + return SQLITE_OK; + }else{ + unixFile *conchFile = pCtx->conchFile; + uuid_t myHostID; + int pError = 0; + char readBuf[PROXY_MAXCONCHLEN]; + char lockPath[MAXPATHLEN]; + char *tempLockPath = NULL; + int rc = SQLITE_OK; + int createConch = 0; + int hostIdMatch = 0; + int readLen = 0; + int tryOldLockPath = 0; + int forceNewLockPath = 0; + + OSTRACE(("TAKECONCH %d for %s pid=%d\n", conchFile->h, + (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), getpid())); + + rc = proxyGetHostID(myHostID, &pError); + if( (rc&0xff)==SQLITE_IOERR ){ + pFile->lastErrno = pError; + goto end_takeconch; + } + rc = proxyConchLock(pFile, myHostID, SHARED_LOCK); + if( rc!=SQLITE_OK ){ + goto end_takeconch; + } + /* read the existing conch file */ + readLen = seekAndRead((unixFile*)conchFile, 0, readBuf, PROXY_MAXCONCHLEN); + if( readLen<0 ){ + /* I/O error: lastErrno set by seekAndRead */ + pFile->lastErrno = conchFile->lastErrno; + rc = SQLITE_IOERR_READ; + goto end_takeconch; + }else if( readLen<=(PROXY_HEADERLEN+PROXY_HOSTIDLEN) || + readBuf[0]!=(char)PROXY_CONCHVERSION ){ + /* a short read or version format mismatch means we need to create a new + ** conch file. + */ + createConch = 1; + } + /* if the host id matches and the lock path already exists in the conch + ** we'll try to use the path there, if we can't open that path, we'll + ** retry with a new auto-generated path + */ + do { /* in case we need to try again for an :auto: named lock file */ + + if( !createConch && !forceNewLockPath ){ + hostIdMatch = !memcmp(&readBuf[PROXY_HEADERLEN], myHostID, + PROXY_HOSTIDLEN); + /* if the conch has data compare the contents */ + if( !pCtx->lockProxyPath ){ + /* for auto-named local lock file, just check the host ID and we'll + ** use the local lock file path that's already in there + */ + if( hostIdMatch ){ + size_t pathLen = (readLen - PROXY_PATHINDEX); + + if( pathLen>=MAXPATHLEN ){ + pathLen=MAXPATHLEN-1; + } + memcpy(lockPath, &readBuf[PROXY_PATHINDEX], pathLen); + lockPath[pathLen] = 0; + tempLockPath = lockPath; + tryOldLockPath = 1; + /* create a copy of the lock path if the conch is taken */ + goto end_takeconch; + } + }else if( hostIdMatch + && !strncmp(pCtx->lockProxyPath, &readBuf[PROXY_PATHINDEX], + readLen-PROXY_PATHINDEX) + ){ + /* conch host and lock path match */ + goto end_takeconch; + } + } + + /* if the conch isn't writable and doesn't match, we can't take it */ + if( (conchFile->openFlags&O_RDWR) == 0 ){ + rc = SQLITE_BUSY; + goto end_takeconch; + } + + /* either the conch didn't match or we need to create a new one */ + if( !pCtx->lockProxyPath ){ + proxyGetLockPath(pCtx->dbPath, lockPath, MAXPATHLEN); + tempLockPath = lockPath; + /* create a copy of the lock path _only_ if the conch is taken */ + } + + /* update conch with host and path (this will fail if other process + ** has a shared lock already), if the host id matches, use the big + ** stick. + */ + futimes(conchFile->h, NULL); + if( hostIdMatch && !createConch ){ + if( conchFile->pInode && conchFile->pInode->nShared>1 ){ + /* We are trying for an exclusive lock but another thread in this + ** same process is still holding a shared lock. */ + rc = SQLITE_BUSY; + } else { + rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK); + } + }else{ + rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, EXCLUSIVE_LOCK); + } + if( rc==SQLITE_OK ){ + char writeBuffer[PROXY_MAXCONCHLEN]; + int writeSize = 0; + + writeBuffer[0] = (char)PROXY_CONCHVERSION; + memcpy(&writeBuffer[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN); + if( pCtx->lockProxyPath!=NULL ){ + strlcpy(&writeBuffer[PROXY_PATHINDEX], pCtx->lockProxyPath, MAXPATHLEN); + }else{ + strlcpy(&writeBuffer[PROXY_PATHINDEX], tempLockPath, MAXPATHLEN); + } + writeSize = PROXY_PATHINDEX + strlen(&writeBuffer[PROXY_PATHINDEX]); + robust_ftruncate(conchFile->h, writeSize); + rc = unixWrite((sqlite3_file *)conchFile, writeBuffer, writeSize, 0); + fsync(conchFile->h); + /* If we created a new conch file (not just updated the contents of a + ** valid conch file), try to match the permissions of the database + */ + if( rc==SQLITE_OK && createConch ){ + struct stat buf; + int err = osFstat(pFile->h, &buf); + if( err==0 ){ + mode_t cmode = buf.st_mode&(S_IRUSR|S_IWUSR | S_IRGRP|S_IWGRP | + S_IROTH|S_IWOTH); + /* try to match the database file R/W permissions, ignore failure */ +#ifndef SQLITE_PROXY_DEBUG + osFchmod(conchFile->h, cmode); +#else + do{ + rc = osFchmod(conchFile->h, cmode); + }while( rc==(-1) && errno==EINTR ); + if( rc!=0 ){ + int code = errno; + fprintf(stderr, "fchmod %o FAILED with %d %s\n", + cmode, code, strerror(code)); + } else { + fprintf(stderr, "fchmod %o SUCCEDED\n",cmode); + } + }else{ + int code = errno; + fprintf(stderr, "STAT FAILED[%d] with %d %s\n", + err, code, strerror(code)); +#endif + } + } + } + conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, SHARED_LOCK); + + end_takeconch: + OSTRACE(("TRANSPROXY: CLOSE %d\n", pFile->h)); + if( rc==SQLITE_OK && pFile->openFlags ){ + int fd; + if( pFile->h>=0 ){ + robust_close(pFile, pFile->h, __LINE__); + } + pFile->h = -1; + fd = robust_open(pCtx->dbPath, pFile->openFlags, + SQLITE_DEFAULT_FILE_PERMISSIONS); + OSTRACE(("TRANSPROXY: OPEN %d\n", fd)); + if( fd>=0 ){ + pFile->h = fd; + }else{ + rc=SQLITE_CANTOPEN_BKPT; /* SQLITE_BUSY? proxyTakeConch called + during locking */ + } + } + if( rc==SQLITE_OK && !pCtx->lockProxy ){ + char *path = tempLockPath ? tempLockPath : pCtx->lockProxyPath; + rc = proxyCreateUnixFile(path, &pCtx->lockProxy, 1); + if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM && tryOldLockPath ){ + /* we couldn't create the proxy lock file with the old lock file path + ** so try again via auto-naming + */ + forceNewLockPath = 1; + tryOldLockPath = 0; + continue; /* go back to the do {} while start point, try again */ + } + } + if( rc==SQLITE_OK ){ + /* Need to make a copy of path if we extracted the value + ** from the conch file or the path was allocated on the stack + */ + if( tempLockPath ){ + pCtx->lockProxyPath = sqlite3DbStrDup(0, tempLockPath); + if( !pCtx->lockProxyPath ){ + rc = SQLITE_NOMEM; + } + } + } + if( rc==SQLITE_OK ){ + pCtx->conchHeld = 1; + + if( pCtx->lockProxy->pMethod == &afpIoMethods ){ + afpLockingContext *afpCtx; + afpCtx = (afpLockingContext *)pCtx->lockProxy->lockingContext; + afpCtx->dbPath = pCtx->lockProxyPath; + } + } else { + conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK); + } + OSTRACE(("TAKECONCH %d %s\n", conchFile->h, + rc==SQLITE_OK?"ok":"failed")); + return rc; + } while (1); /* in case we need to retry the :auto: lock file - + ** we should never get here except via the 'continue' call. */ + } +} + +/* +** If pFile holds a lock on a conch file, then release that lock. +*/ +static int proxyReleaseConch(unixFile *pFile){ + int rc = SQLITE_OK; /* Subroutine return code */ + proxyLockingContext *pCtx; /* The locking context for the proxy lock */ + unixFile *conchFile; /* Name of the conch file */ + + pCtx = (proxyLockingContext *)pFile->lockingContext; + conchFile = pCtx->conchFile; + OSTRACE(("RELEASECONCH %d for %s pid=%d\n", conchFile->h, + (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), + getpid())); + if( pCtx->conchHeld>0 ){ + rc = conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK); + } + pCtx->conchHeld = 0; + OSTRACE(("RELEASECONCH %d %s\n", conchFile->h, + (rc==SQLITE_OK ? "ok" : "failed"))); + return rc; +} + +/* +** Given the name of a database file, compute the name of its conch file. +** Store the conch filename in memory obtained from sqlite3_malloc(). +** Make *pConchPath point to the new name. Return SQLITE_OK on success +** or SQLITE_NOMEM if unable to obtain memory. +** +** The caller is responsible for ensuring that the allocated memory +** space is eventually freed. +** +** *pConchPath is set to NULL if a memory allocation error occurs. +*/ +static int proxyCreateConchPathname(char *dbPath, char **pConchPath){ + int i; /* Loop counter */ + int len = (int)strlen(dbPath); /* Length of database filename - dbPath */ + char *conchPath; /* buffer in which to construct conch name */ + + /* Allocate space for the conch filename and initialize the name to + ** the name of the original database file. */ + *pConchPath = conchPath = (char *)sqlite3_malloc(len + 8); + if( conchPath==0 ){ + return SQLITE_NOMEM; + } + memcpy(conchPath, dbPath, len+1); + + /* now insert a "." before the last / character */ + for( i=(len-1); i>=0; i-- ){ + if( conchPath[i]=='/' ){ + i++; + break; + } + } + conchPath[i]='.'; + while ( ilockingContext; + char *oldPath = pCtx->lockProxyPath; + int rc = SQLITE_OK; + + if( pFile->eFileLock!=NO_LOCK ){ + return SQLITE_BUSY; + } + + /* nothing to do if the path is NULL, :auto: or matches the existing path */ + if( !path || path[0]=='\0' || !strcmp(path, ":auto:") || + (oldPath && !strncmp(oldPath, path, MAXPATHLEN)) ){ + return SQLITE_OK; + }else{ + unixFile *lockProxy = pCtx->lockProxy; + pCtx->lockProxy=NULL; + pCtx->conchHeld = 0; + if( lockProxy!=NULL ){ + rc=lockProxy->pMethod->xClose((sqlite3_file *)lockProxy); + if( rc ) return rc; + sqlite3_free(lockProxy); + } + sqlite3_free(oldPath); + pCtx->lockProxyPath = sqlite3DbStrDup(0, path); + } + + return rc; +} + +/* +** pFile is a file that has been opened by a prior xOpen call. dbPath +** is a string buffer at least MAXPATHLEN+1 characters in size. +** +** This routine find the filename associated with pFile and writes it +** int dbPath. +*/ +static int proxyGetDbPathForUnixFile(unixFile *pFile, char *dbPath){ +#if defined(__APPLE__) + if( pFile->pMethod == &afpIoMethods ){ + /* afp style keeps a reference to the db path in the filePath field + ** of the struct */ + assert( (int)strlen((char*)pFile->lockingContext)<=MAXPATHLEN ); + strlcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath, MAXPATHLEN); + } else +#endif + if( pFile->pMethod == &dotlockIoMethods ){ + /* dot lock style uses the locking context to store the dot lock + ** file path */ + int len = strlen((char *)pFile->lockingContext) - strlen(DOTLOCK_SUFFIX); + memcpy(dbPath, (char *)pFile->lockingContext, len + 1); + }else{ + /* all other styles use the locking context to store the db file path */ + assert( strlen((char*)pFile->lockingContext)<=MAXPATHLEN ); + strlcpy(dbPath, (char *)pFile->lockingContext, MAXPATHLEN); + } + return SQLITE_OK; +} + +/* +** Takes an already filled in unix file and alters it so all file locking +** will be performed on the local proxy lock file. The following fields +** are preserved in the locking context so that they can be restored and +** the unix structure properly cleaned up at close time: +** ->lockingContext +** ->pMethod +*/ +static int proxyTransformUnixFile(unixFile *pFile, const char *path) { + proxyLockingContext *pCtx; + char dbPath[MAXPATHLEN+1]; /* Name of the database file */ + char *lockPath=NULL; + int rc = SQLITE_OK; + + if( pFile->eFileLock!=NO_LOCK ){ + return SQLITE_BUSY; + } + proxyGetDbPathForUnixFile(pFile, dbPath); + if( !path || path[0]=='\0' || !strcmp(path, ":auto:") ){ + lockPath=NULL; + }else{ + lockPath=(char *)path; + } + + OSTRACE(("TRANSPROXY %d for %s pid=%d\n", pFile->h, + (lockPath ? lockPath : ":auto:"), getpid())); + + pCtx = sqlite3_malloc( sizeof(*pCtx) ); + if( pCtx==0 ){ + return SQLITE_NOMEM; + } + memset(pCtx, 0, sizeof(*pCtx)); + + rc = proxyCreateConchPathname(dbPath, &pCtx->conchFilePath); + if( rc==SQLITE_OK ){ + rc = proxyCreateUnixFile(pCtx->conchFilePath, &pCtx->conchFile, 0); + if( rc==SQLITE_CANTOPEN && ((pFile->openFlags&O_RDWR) == 0) ){ + /* if (a) the open flags are not O_RDWR, (b) the conch isn't there, and + ** (c) the file system is read-only, then enable no-locking access. + ** Ugh, since O_RDONLY==0x0000 we test for !O_RDWR since unixOpen asserts + ** that openFlags will have only one of O_RDONLY or O_RDWR. + */ + struct statfs fsInfo; + struct stat conchInfo; + int goLockless = 0; + + if( osStat(pCtx->conchFilePath, &conchInfo) == -1 ) { + int err = errno; + if( (err==ENOENT) && (statfs(dbPath, &fsInfo) != -1) ){ + goLockless = (fsInfo.f_flags&MNT_RDONLY) == MNT_RDONLY; + } + } + if( goLockless ){ + pCtx->conchHeld = -1; /* read only FS/ lockless */ + rc = SQLITE_OK; + } + } + } + if( rc==SQLITE_OK && lockPath ){ + pCtx->lockProxyPath = sqlite3DbStrDup(0, lockPath); + } + + if( rc==SQLITE_OK ){ + pCtx->dbPath = sqlite3DbStrDup(0, dbPath); + if( pCtx->dbPath==NULL ){ + rc = SQLITE_NOMEM; + } + } + if( rc==SQLITE_OK ){ + /* all memory is allocated, proxys are created and assigned, + ** switch the locking context and pMethod then return. + */ + pCtx->oldLockingContext = pFile->lockingContext; + pFile->lockingContext = pCtx; + pCtx->pOldMethod = pFile->pMethod; + pFile->pMethod = &proxyIoMethods; + }else{ + if( pCtx->conchFile ){ + pCtx->conchFile->pMethod->xClose((sqlite3_file *)pCtx->conchFile); + sqlite3_free(pCtx->conchFile); + } + sqlite3DbFree(0, pCtx->lockProxyPath); + sqlite3_free(pCtx->conchFilePath); + sqlite3_free(pCtx); + } + OSTRACE(("TRANSPROXY %d %s\n", pFile->h, + (rc==SQLITE_OK ? "ok" : "failed"))); + return rc; +} + + +/* +** This routine handles sqlite3_file_control() calls that are specific +** to proxy locking. +*/ +static int proxyFileControl(sqlite3_file *id, int op, void *pArg){ + switch( op ){ + case SQLITE_GET_LOCKPROXYFILE: { + unixFile *pFile = (unixFile*)id; + if( pFile->pMethod == &proxyIoMethods ){ + proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext; + proxyTakeConch(pFile); + if( pCtx->lockProxyPath ){ + *(const char **)pArg = pCtx->lockProxyPath; + }else{ + *(const char **)pArg = ":auto: (not held)"; + } + } else { + *(const char **)pArg = NULL; + } + return SQLITE_OK; + } + case SQLITE_SET_LOCKPROXYFILE: { + unixFile *pFile = (unixFile*)id; + int rc = SQLITE_OK; + int isProxyStyle = (pFile->pMethod == &proxyIoMethods); + if( pArg==NULL || (const char *)pArg==0 ){ + if( isProxyStyle ){ + /* turn off proxy locking - not supported */ + rc = SQLITE_ERROR /*SQLITE_PROTOCOL? SQLITE_MISUSE?*/; + }else{ + /* turn off proxy locking - already off - NOOP */ + rc = SQLITE_OK; + } + }else{ + const char *proxyPath = (const char *)pArg; + if( isProxyStyle ){ + proxyLockingContext *pCtx = + (proxyLockingContext*)pFile->lockingContext; + if( !strcmp(pArg, ":auto:") + || (pCtx->lockProxyPath && + !strncmp(pCtx->lockProxyPath, proxyPath, MAXPATHLEN)) + ){ + rc = SQLITE_OK; + }else{ + rc = switchLockProxyPath(pFile, proxyPath); + } + }else{ + /* turn on proxy file locking */ + rc = proxyTransformUnixFile(pFile, proxyPath); + } + } + return rc; + } + default: { + assert( 0 ); /* The call assures that only valid opcodes are sent */ + } + } + /*NOTREACHED*/ + return SQLITE_ERROR; +} + +/* +** Within this division (the proxying locking implementation) the procedures +** above this point are all utilities. The lock-related methods of the +** proxy-locking sqlite3_io_method object follow. +*/ + + +/* +** This routine checks if there is a RESERVED lock held on the specified +** file by this or any other process. If such a lock is held, set *pResOut +** to a non-zero value otherwise *pResOut is set to zero. The return value +** is set to SQLITE_OK unless an I/O error occurs during lock checking. +*/ +static int proxyCheckReservedLock(sqlite3_file *id, int *pResOut) { + unixFile *pFile = (unixFile*)id; + int rc = proxyTakeConch(pFile); + if( rc==SQLITE_OK ){ + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + if( pCtx->conchHeld>0 ){ + unixFile *proxy = pCtx->lockProxy; + return proxy->pMethod->xCheckReservedLock((sqlite3_file*)proxy, pResOut); + }else{ /* conchHeld < 0 is lockless */ + pResOut=0; + } + } + return rc; +} + +/* +** Lock the file with the lock specified by parameter eFileLock - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** SHARED -> (PENDING) -> EXCLUSIVE +** RESERVED -> (PENDING) -> EXCLUSIVE +** PENDING -> EXCLUSIVE +** +** This routine will only increase a lock. Use the sqlite3OsUnlock() +** routine to lower a locking level. +*/ +static int proxyLock(sqlite3_file *id, int eFileLock) { + unixFile *pFile = (unixFile*)id; + int rc = proxyTakeConch(pFile); + if( rc==SQLITE_OK ){ + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + if( pCtx->conchHeld>0 ){ + unixFile *proxy = pCtx->lockProxy; + rc = proxy->pMethod->xLock((sqlite3_file*)proxy, eFileLock); + pFile->eFileLock = proxy->eFileLock; + }else{ + /* conchHeld < 0 is lockless */ + } + } + return rc; +} + + +/* +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock +** must be either NO_LOCK or SHARED_LOCK. +** +** If the locking level of the file descriptor is already at or below +** the requested locking level, this routine is a no-op. +*/ +static int proxyUnlock(sqlite3_file *id, int eFileLock) { + unixFile *pFile = (unixFile*)id; + int rc = proxyTakeConch(pFile); + if( rc==SQLITE_OK ){ + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + if( pCtx->conchHeld>0 ){ + unixFile *proxy = pCtx->lockProxy; + rc = proxy->pMethod->xUnlock((sqlite3_file*)proxy, eFileLock); + pFile->eFileLock = proxy->eFileLock; + }else{ + /* conchHeld < 0 is lockless */ + } + } + return rc; +} + +/* +** Close a file that uses proxy locks. +*/ +static int proxyClose(sqlite3_file *id) { + if( id ){ + unixFile *pFile = (unixFile*)id; + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + unixFile *lockProxy = pCtx->lockProxy; + unixFile *conchFile = pCtx->conchFile; + int rc = SQLITE_OK; + + if( lockProxy ){ + rc = lockProxy->pMethod->xUnlock((sqlite3_file*)lockProxy, NO_LOCK); + if( rc ) return rc; + rc = lockProxy->pMethod->xClose((sqlite3_file*)lockProxy); + if( rc ) return rc; + sqlite3_free(lockProxy); + pCtx->lockProxy = 0; + } + if( conchFile ){ + if( pCtx->conchHeld ){ + rc = proxyReleaseConch(pFile); + if( rc ) return rc; + } + rc = conchFile->pMethod->xClose((sqlite3_file*)conchFile); + if( rc ) return rc; + sqlite3_free(conchFile); + } + sqlite3DbFree(0, pCtx->lockProxyPath); + sqlite3_free(pCtx->conchFilePath); + sqlite3DbFree(0, pCtx->dbPath); + /* restore the original locking context and pMethod then close it */ + pFile->lockingContext = pCtx->oldLockingContext; + pFile->pMethod = pCtx->pOldMethod; + sqlite3_free(pCtx); + return pFile->pMethod->xClose(id); + } + return SQLITE_OK; +} + + + +#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ +/* +** The proxy locking style is intended for use with AFP filesystems. +** And since AFP is only supported on MacOSX, the proxy locking is also +** restricted to MacOSX. +** +** +******************* End of the proxy lock implementation ********************** +******************************************************************************/ + +/* +** Initialize the operating system interface. +** +** This routine registers all VFS implementations for unix-like operating +** systems. This routine, and the sqlite3_os_end() routine that follows, +** should be the only routines in this file that are visible from other +** files. +** +** This routine is called once during SQLite initialization and by a +** single thread. The memory allocation and mutex subsystems have not +** necessarily been initialized when this routine is called, and so they +** should not be used. +*/ +int sqlite3_os_init(void){ + /* + ** The following macro defines an initializer for an sqlite3_vfs object. + ** The name of the VFS is NAME. The pAppData is a pointer to a pointer + ** to the "finder" function. (pAppData is a pointer to a pointer because + ** silly C90 rules prohibit a void* from being cast to a function pointer + ** and so we have to go through the intermediate pointer to avoid problems + ** when compiling with -pedantic-errors on GCC.) + ** + ** The FINDER parameter to this macro is the name of the pointer to the + ** finder-function. The finder-function returns a pointer to the + ** sqlite_io_methods object that implements the desired locking + ** behaviors. See the division above that contains the IOMETHODS + ** macro for addition information on finder-functions. + ** + ** Most finders simply return a pointer to a fixed sqlite3_io_methods + ** object. But the "autolockIoFinder" available on MacOSX does a little + ** more than that; it looks at the filesystem type that hosts the + ** database file and tries to choose an locking method appropriate for + ** that filesystem time. + */ + #define UNIXVFS(VFSNAME, FINDER) { \ + 3, /* iVersion */ \ + sizeof(unixFile), /* szOsFile */ \ + MAX_PATHNAME, /* mxPathname */ \ + 0, /* pNext */ \ + VFSNAME, /* zName */ \ + (void*)&FINDER, /* pAppData */ \ + unixOpen, /* xOpen */ \ + unixDelete, /* xDelete */ \ + unixAccess, /* xAccess */ \ + unixFullPathname, /* xFullPathname */ \ + unixDlOpen, /* xDlOpen */ \ + unixDlError, /* xDlError */ \ + unixDlSym, /* xDlSym */ \ + unixDlClose, /* xDlClose */ \ + unixRandomness, /* xRandomness */ \ + unixSleep, /* xSleep */ \ + unixCurrentTime, /* xCurrentTime */ \ + unixGetLastError, /* xGetLastError */ \ + unixCurrentTimeInt64, /* xCurrentTimeInt64 */ \ + unixSetSystemCall, /* xSetSystemCall */ \ + unixGetSystemCall, /* xGetSystemCall */ \ + unixNextSystemCall, /* xNextSystemCall */ \ + } + + /* + ** All default VFSes for unix are contained in the following array. + ** + ** Note that the sqlite3_vfs.pNext field of the VFS object is modified + ** by the SQLite core when the VFS is registered. So the following + ** array cannot be const. + */ + static sqlite3_vfs aVfs[] = { +#if SQLITE_ENABLE_LOCKING_STYLE && (OS_VXWORKS || defined(__APPLE__)) + UNIXVFS("unix", autolockIoFinder ), +#else + UNIXVFS("unix", posixIoFinder ), +#endif + UNIXVFS("unix-none", nolockIoFinder ), + UNIXVFS("unix-dotfile", dotlockIoFinder ), + UNIXVFS("unix-excl", posixIoFinder ), +#if OS_VXWORKS + UNIXVFS("unix-namedsem", semIoFinder ), +#endif +#if SQLITE_ENABLE_LOCKING_STYLE + UNIXVFS("unix-posix", posixIoFinder ), +#if !OS_VXWORKS + UNIXVFS("unix-flock", flockIoFinder ), +#endif +#endif +#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) + UNIXVFS("unix-afp", afpIoFinder ), + UNIXVFS("unix-nfs", nfsIoFinder ), + UNIXVFS("unix-proxy", proxyIoFinder ), +#endif + }; + unsigned int i; /* Loop counter */ + + /* Double-check that the aSyscall[] array has been constructed + ** correctly. See ticket [bb3a86e890c8e96ab] */ + assert( ArraySize(aSyscall)==20 ); + + /* Register all VFSes defined in the aVfs[] array */ + for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ + sqlite3_vfs_register(&aVfs[i], i==0); + } + return SQLITE_OK; +} + +/* +** Shutdown the operating system interface. +** +** Some operating systems might need to do some cleanup in this routine, +** to release dynamically allocated objects. But not on unix. +** This routine is a no-op for unix. +*/ +int sqlite3_os_end(void){ + return SQLITE_OK; +} + +#endif /* SQLITE_OS_UNIX */ diff --git a/scalos/libraries/sqlite/src/os_win.c b/scalos/libraries/sqlite/src/os_win.c new file mode 100644 index 000000000..8b86c7ed5 --- /dev/null +++ b/scalos/libraries/sqlite/src/os_win.c @@ -0,0 +1,3697 @@ +/* +** 2004 May 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains code that is specific to Windows. +*/ +#include "sqliteInt.h" +#if SQLITE_OS_WIN /* This file is used for Windows only */ + +#ifdef __CYGWIN__ +# include +#endif + +/* +** Include code that is common to all os_*.c files +*/ +#include "os_common.h" + +/* +** Some Microsoft compilers lack this definition. +*/ +#ifndef INVALID_FILE_ATTRIBUTES +# define INVALID_FILE_ATTRIBUTES ((DWORD)-1) +#endif + +/* Forward references */ +typedef struct winShm winShm; /* A connection to shared-memory */ +typedef struct winShmNode winShmNode; /* A region of shared-memory */ + +/* +** WinCE lacks native support for file locking so we have to fake it +** with some code of our own. +*/ +#if SQLITE_OS_WINCE +typedef struct winceLock { + int nReaders; /* Number of reader locks obtained */ + BOOL bPending; /* Indicates a pending lock has been obtained */ + BOOL bReserved; /* Indicates a reserved lock has been obtained */ + BOOL bExclusive; /* Indicates an exclusive lock has been obtained */ +} winceLock; +#endif + +/* +** The winFile structure is a subclass of sqlite3_file* specific to the win32 +** portability layer. +*/ +typedef struct winFile winFile; +struct winFile { + const sqlite3_io_methods *pMethod; /*** Must be first ***/ + sqlite3_vfs *pVfs; /* The VFS used to open this file */ + HANDLE h; /* Handle for accessing the file */ + u8 locktype; /* Type of lock currently held on this file */ + short sharedLockByte; /* Randomly chosen byte used as a shared lock */ + u8 ctrlFlags; /* Flags. See WINFILE_* below */ + DWORD lastErrno; /* The Windows errno from the last I/O error */ + winShm *pShm; /* Instance of shared memory on this file */ + const char *zPath; /* Full pathname of this file */ + int szChunk; /* Chunk size configured by FCNTL_CHUNK_SIZE */ +#if SQLITE_OS_WINCE + LPWSTR zDeleteOnClose; /* Name of file to delete when closing */ + HANDLE hMutex; /* Mutex used to control access to shared lock */ + HANDLE hShared; /* Shared memory segment used for locking */ + winceLock local; /* Locks obtained by this instance of winFile */ + winceLock *shared; /* Global shared lock memory for the file */ +#endif +}; + +/* +** Allowed values for winFile.ctrlFlags +*/ +#define WINFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ +#define WINFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */ + +/* + * If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the + * various Win32 API heap functions instead of our own. + */ +#ifdef SQLITE_WIN32_MALLOC +/* + * The initial size of the Win32-specific heap. This value may be zero. + */ +#ifndef SQLITE_WIN32_HEAP_INIT_SIZE +# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_DEFAULT_CACHE_SIZE) * \ + (SQLITE_DEFAULT_PAGE_SIZE) + 4194304) +#endif + +/* + * The maximum size of the Win32-specific heap. This value may be zero. + */ +#ifndef SQLITE_WIN32_HEAP_MAX_SIZE +# define SQLITE_WIN32_HEAP_MAX_SIZE (0) +#endif + +/* + * The extra flags to use in calls to the Win32 heap APIs. This value may be + * zero for the default behavior. + */ +#ifndef SQLITE_WIN32_HEAP_FLAGS +# define SQLITE_WIN32_HEAP_FLAGS (0) +#endif + +/* +** The winMemData structure stores information required by the Win32-specific +** sqlite3_mem_methods implementation. +*/ +typedef struct winMemData winMemData; +struct winMemData { +#ifndef NDEBUG + u32 magic; /* Magic number to detect structure corruption. */ +#endif + HANDLE hHeap; /* The handle to our heap. */ + BOOL bOwned; /* Do we own the heap (i.e. destroy it on shutdown)? */ +}; + +#ifndef NDEBUG +#define WINMEM_MAGIC 0x42b2830b +#endif + +static struct winMemData win_mem_data = { +#ifndef NDEBUG + WINMEM_MAGIC, +#endif + NULL, FALSE +}; + +#ifndef NDEBUG +#define winMemAssertMagic() assert( win_mem_data.magic==WINMEM_MAGIC ) +#else +#define winMemAssertMagic() +#endif + +#define winMemGetHeap() win_mem_data.hHeap + +static void *winMemMalloc(int nBytes); +static void winMemFree(void *pPrior); +static void *winMemRealloc(void *pPrior, int nBytes); +static int winMemSize(void *p); +static int winMemRoundup(int n); +static int winMemInit(void *pAppData); +static void winMemShutdown(void *pAppData); + +const sqlite3_mem_methods *sqlite3MemGetWin32(void); +#endif /* SQLITE_WIN32_MALLOC */ + +/* +** The following variable is (normally) set once and never changes +** thereafter. It records whether the operating system is Win9x +** or WinNT. +** +** 0: Operating system unknown. +** 1: Operating system is Win9x. +** 2: Operating system is WinNT. +** +** In order to facilitate testing on a WinNT system, the test fixture +** can manually set this value to 1 to emulate Win98 behavior. +*/ +#ifdef SQLITE_TEST +int sqlite3_os_type = 0; +#else +static int sqlite3_os_type = 0; +#endif + +/* +** Many system calls are accessed through pointer-to-functions so that +** they may be overridden at runtime to facilitate fault injection during +** testing and sandboxing. The following array holds the names and pointers +** to all overrideable system calls. +*/ +#if !SQLITE_OS_WINCE +# define SQLITE_WIN32_HAS_ANSI +#endif + +#if SQLITE_OS_WINCE || SQLITE_OS_WINNT +# define SQLITE_WIN32_HAS_WIDE +#endif + +#ifndef SYSCALL +# define SYSCALL sqlite3_syscall_ptr +#endif + +#if SQLITE_OS_WINCE +/* +** These macros are necessary because Windows CE does not natively support the +** Win32 APIs LockFile, UnlockFile, and LockFileEx. + */ + +# define LockFile(a,b,c,d,e) winceLockFile(&a, b, c, d, e) +# define UnlockFile(a,b,c,d,e) winceUnlockFile(&a, b, c, d, e) +# define LockFileEx(a,b,c,d,e,f) winceLockFileEx(&a, b, c, d, e, f) + +/* +** These are the special syscall hacks for Windows CE. The locking related +** defines here refer to the macros defined just above. + */ + +# define osAreFileApisANSI() 1 +# define osLockFile LockFile +# define osUnlockFile UnlockFile +# define osLockFileEx LockFileEx +#endif + +static struct win_syscall { + const char *zName; /* Name of the sytem call */ + sqlite3_syscall_ptr pCurrent; /* Current value of the system call */ + sqlite3_syscall_ptr pDefault; /* Default value */ +} aSyscall[] = { +#if !SQLITE_OS_WINCE + { "AreFileApisANSI", (SYSCALL)AreFileApisANSI, 0 }, + +#define osAreFileApisANSI ((BOOL(WINAPI*)(VOID))aSyscall[0].pCurrent) +#else + { "AreFileApisANSI", (SYSCALL)0, 0 }, +#endif + +#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE) + { "CharLowerW", (SYSCALL)CharLowerW, 0 }, +#else + { "CharLowerW", (SYSCALL)0, 0 }, +#endif + +#define osCharLowerW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[1].pCurrent) + +#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE) + { "CharUpperW", (SYSCALL)CharUpperW, 0 }, +#else + { "CharUpperW", (SYSCALL)0, 0 }, +#endif + +#define osCharUpperW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[2].pCurrent) + + { "CloseHandle", (SYSCALL)CloseHandle, 0 }, + +#define osCloseHandle ((BOOL(WINAPI*)(HANDLE))aSyscall[3].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "CreateFileA", (SYSCALL)CreateFileA, 0 }, +#else + { "CreateFileA", (SYSCALL)0, 0 }, +#endif + +#define osCreateFileA ((HANDLE(WINAPI*)(LPCSTR,DWORD,DWORD, \ + LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[4].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "CreateFileW", (SYSCALL)CreateFileW, 0 }, +#else + { "CreateFileW", (SYSCALL)0, 0 }, +#endif + +#define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \ + LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent) + + { "CreateFileMapping", (SYSCALL)CreateFileMapping, 0 }, + +#define osCreateFileMapping ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \ + DWORD,DWORD,DWORD,LPCTSTR))aSyscall[6].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "CreateFileMappingW", (SYSCALL)CreateFileMappingW, 0 }, +#else + { "CreateFileMappingW", (SYSCALL)0, 0 }, +#endif + +#define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \ + DWORD,DWORD,DWORD,LPCWSTR))aSyscall[7].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "CreateMutexW", (SYSCALL)CreateMutexW, 0 }, +#else + { "CreateMutexW", (SYSCALL)0, 0 }, +#endif + +#define osCreateMutexW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,BOOL, \ + LPCWSTR))aSyscall[8].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "DeleteFileA", (SYSCALL)DeleteFileA, 0 }, +#else + { "DeleteFileA", (SYSCALL)0, 0 }, +#endif + +#define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[9].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "DeleteFileW", (SYSCALL)DeleteFileW, 0 }, +#else + { "DeleteFileW", (SYSCALL)0, 0 }, +#endif + +#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[10].pCurrent) + +#if SQLITE_OS_WINCE + { "FileTimeToLocalFileTime", (SYSCALL)FileTimeToLocalFileTime, 0 }, +#else + { "FileTimeToLocalFileTime", (SYSCALL)0, 0 }, +#endif + +#define osFileTimeToLocalFileTime ((BOOL(WINAPI*)(CONST FILETIME*, \ + LPFILETIME))aSyscall[11].pCurrent) + +#if SQLITE_OS_WINCE + { "FileTimeToSystemTime", (SYSCALL)FileTimeToSystemTime, 0 }, +#else + { "FileTimeToSystemTime", (SYSCALL)0, 0 }, +#endif + +#define osFileTimeToSystemTime ((BOOL(WINAPI*)(CONST FILETIME*, \ + LPSYSTEMTIME))aSyscall[12].pCurrent) + + { "FlushFileBuffers", (SYSCALL)FlushFileBuffers, 0 }, + +#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[13].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "FormatMessageA", (SYSCALL)FormatMessageA, 0 }, +#else + { "FormatMessageA", (SYSCALL)0, 0 }, +#endif + +#define osFormatMessageA ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPSTR, \ + DWORD,va_list*))aSyscall[14].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "FormatMessageW", (SYSCALL)FormatMessageW, 0 }, +#else + { "FormatMessageW", (SYSCALL)0, 0 }, +#endif + +#define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \ + DWORD,va_list*))aSyscall[15].pCurrent) + + { "FreeLibrary", (SYSCALL)FreeLibrary, 0 }, + +#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[16].pCurrent) + + { "GetCurrentProcessId", (SYSCALL)GetCurrentProcessId, 0 }, + +#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[17].pCurrent) + +#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI) + { "GetDiskFreeSpaceA", (SYSCALL)GetDiskFreeSpaceA, 0 }, +#else + { "GetDiskFreeSpaceA", (SYSCALL)0, 0 }, +#endif + +#define osGetDiskFreeSpaceA ((BOOL(WINAPI*)(LPCSTR,LPDWORD,LPDWORD,LPDWORD, \ + LPDWORD))aSyscall[18].pCurrent) + +#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE) + { "GetDiskFreeSpaceW", (SYSCALL)GetDiskFreeSpaceW, 0 }, +#else + { "GetDiskFreeSpaceW", (SYSCALL)0, 0 }, +#endif + +#define osGetDiskFreeSpaceW ((BOOL(WINAPI*)(LPCWSTR,LPDWORD,LPDWORD,LPDWORD, \ + LPDWORD))aSyscall[19].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "GetFileAttributesA", (SYSCALL)GetFileAttributesA, 0 }, +#else + { "GetFileAttributesA", (SYSCALL)0, 0 }, +#endif + +#define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[20].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "GetFileAttributesW", (SYSCALL)GetFileAttributesW, 0 }, +#else + { "GetFileAttributesW", (SYSCALL)0, 0 }, +#endif + +#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[21].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "GetFileAttributesExW", (SYSCALL)GetFileAttributesExW, 0 }, +#else + { "GetFileAttributesExW", (SYSCALL)0, 0 }, +#endif + +#define osGetFileAttributesExW ((BOOL(WINAPI*)(LPCWSTR,GET_FILEEX_INFO_LEVELS, \ + LPVOID))aSyscall[22].pCurrent) + + { "GetFileSize", (SYSCALL)GetFileSize, 0 }, + +#define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[23].pCurrent) + +#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI) + { "GetFullPathNameA", (SYSCALL)GetFullPathNameA, 0 }, +#else + { "GetFullPathNameA", (SYSCALL)0, 0 }, +#endif + +#define osGetFullPathNameA ((DWORD(WINAPI*)(LPCSTR,DWORD,LPSTR, \ + LPSTR*))aSyscall[24].pCurrent) + +#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE) + { "GetFullPathNameW", (SYSCALL)GetFullPathNameW, 0 }, +#else + { "GetFullPathNameW", (SYSCALL)0, 0 }, +#endif + +#define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \ + LPWSTR*))aSyscall[25].pCurrent) + + { "GetLastError", (SYSCALL)GetLastError, 0 }, + +#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent) + +#if SQLITE_OS_WINCE + /* The GetProcAddressA() routine is only available on Windows CE. */ + { "GetProcAddressA", (SYSCALL)GetProcAddressA, 0 }, +#else + /* All other Windows platforms expect GetProcAddress() to take + ** an ANSI string regardless of the _UNICODE setting */ + { "GetProcAddressA", (SYSCALL)GetProcAddress, 0 }, +#endif + +#define osGetProcAddressA ((FARPROC(WINAPI*)(HMODULE, \ + LPCSTR))aSyscall[27].pCurrent) + + { "GetSystemInfo", (SYSCALL)GetSystemInfo, 0 }, + +#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[28].pCurrent) + + { "GetSystemTime", (SYSCALL)GetSystemTime, 0 }, + +#define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[29].pCurrent) + +#if !SQLITE_OS_WINCE + { "GetSystemTimeAsFileTime", (SYSCALL)GetSystemTimeAsFileTime, 0 }, +#else + { "GetSystemTimeAsFileTime", (SYSCALL)0, 0 }, +#endif + +#define osGetSystemTimeAsFileTime ((VOID(WINAPI*)( \ + LPFILETIME))aSyscall[30].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "GetTempPathA", (SYSCALL)GetTempPathA, 0 }, +#else + { "GetTempPathA", (SYSCALL)0, 0 }, +#endif + +#define osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[31].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "GetTempPathW", (SYSCALL)GetTempPathW, 0 }, +#else + { "GetTempPathW", (SYSCALL)0, 0 }, +#endif + +#define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[32].pCurrent) + + { "GetTickCount", (SYSCALL)GetTickCount, 0 }, + +#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "GetVersionExA", (SYSCALL)GetVersionExA, 0 }, +#else + { "GetVersionExA", (SYSCALL)0, 0 }, +#endif + +#define osGetVersionExA ((BOOL(WINAPI*)( \ + LPOSVERSIONINFOA))aSyscall[34].pCurrent) + + { "HeapAlloc", (SYSCALL)HeapAlloc, 0 }, + +#define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \ + SIZE_T))aSyscall[35].pCurrent) + + { "HeapCreate", (SYSCALL)HeapCreate, 0 }, + +#define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \ + SIZE_T))aSyscall[36].pCurrent) + + { "HeapDestroy", (SYSCALL)HeapDestroy, 0 }, + +#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[37].pCurrent) + + { "HeapFree", (SYSCALL)HeapFree, 0 }, + +#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[38].pCurrent) + + { "HeapReAlloc", (SYSCALL)HeapReAlloc, 0 }, + +#define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \ + SIZE_T))aSyscall[39].pCurrent) + + { "HeapSize", (SYSCALL)HeapSize, 0 }, + +#define osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \ + LPCVOID))aSyscall[40].pCurrent) + + { "HeapValidate", (SYSCALL)HeapValidate, 0 }, + +#define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \ + LPCVOID))aSyscall[41].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "LoadLibraryA", (SYSCALL)LoadLibraryA, 0 }, +#else + { "LoadLibraryA", (SYSCALL)0, 0 }, +#endif + +#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[42].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "LoadLibraryW", (SYSCALL)LoadLibraryW, 0 }, +#else + { "LoadLibraryW", (SYSCALL)0, 0 }, +#endif + +#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[43].pCurrent) + + { "LocalFree", (SYSCALL)LocalFree, 0 }, + +#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[44].pCurrent) + +#if !SQLITE_OS_WINCE + { "LockFile", (SYSCALL)LockFile, 0 }, + +#define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ + DWORD))aSyscall[45].pCurrent) +#else + { "LockFile", (SYSCALL)0, 0 }, +#endif + +#if !SQLITE_OS_WINCE + { "LockFileEx", (SYSCALL)LockFileEx, 0 }, + +#define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \ + LPOVERLAPPED))aSyscall[46].pCurrent) +#else + { "LockFileEx", (SYSCALL)0, 0 }, +#endif + + { "MapViewOfFile", (SYSCALL)MapViewOfFile, 0 }, + +#define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ + SIZE_T))aSyscall[47].pCurrent) + + { "MultiByteToWideChar", (SYSCALL)MultiByteToWideChar, 0 }, + +#define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \ + int))aSyscall[48].pCurrent) + + { "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 }, + +#define osQueryPerformanceCounter ((BOOL(WINAPI*)( \ + LARGE_INTEGER*))aSyscall[49].pCurrent) + + { "ReadFile", (SYSCALL)ReadFile, 0 }, + +#define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \ + LPOVERLAPPED))aSyscall[50].pCurrent) + + { "SetEndOfFile", (SYSCALL)SetEndOfFile, 0 }, + +#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[51].pCurrent) + + { "SetFilePointer", (SYSCALL)SetFilePointer, 0 }, + +#define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \ + DWORD))aSyscall[52].pCurrent) + + { "Sleep", (SYSCALL)Sleep, 0 }, + +#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[53].pCurrent) + + { "SystemTimeToFileTime", (SYSCALL)SystemTimeToFileTime, 0 }, + +#define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \ + LPFILETIME))aSyscall[54].pCurrent) + +#if !SQLITE_OS_WINCE + { "UnlockFile", (SYSCALL)UnlockFile, 0 }, + +#define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ + DWORD))aSyscall[55].pCurrent) +#else + { "UnlockFile", (SYSCALL)0, 0 }, +#endif + +#if !SQLITE_OS_WINCE + { "UnlockFileEx", (SYSCALL)UnlockFileEx, 0 }, + +#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ + LPOVERLAPPED))aSyscall[56].pCurrent) +#else + { "UnlockFileEx", (SYSCALL)0, 0 }, +#endif + + { "UnmapViewOfFile", (SYSCALL)UnmapViewOfFile, 0 }, + +#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[57].pCurrent) + + { "WideCharToMultiByte", (SYSCALL)WideCharToMultiByte, 0 }, + +#define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \ + LPCSTR,LPBOOL))aSyscall[58].pCurrent) + + { "WriteFile", (SYSCALL)WriteFile, 0 }, + +#define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \ + LPOVERLAPPED))aSyscall[59].pCurrent) + +}; /* End of the overrideable system calls */ + +/* +** This is the xSetSystemCall() method of sqlite3_vfs for all of the +** "win32" VFSes. Return SQLITE_OK opon successfully updating the +** system call pointer, or SQLITE_NOTFOUND if there is no configurable +** system call named zName. +*/ +static int winSetSystemCall( + sqlite3_vfs *pNotUsed, /* The VFS pointer. Not used */ + const char *zName, /* Name of system call to override */ + sqlite3_syscall_ptr pNewFunc /* Pointer to new system call value */ +){ + unsigned int i; + int rc = SQLITE_NOTFOUND; + + UNUSED_PARAMETER(pNotUsed); + if( zName==0 ){ + /* If no zName is given, restore all system calls to their default + ** settings and return NULL + */ + rc = SQLITE_OK; + for(i=0; i=0 ); + p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes); + if( !p ){ + sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%d), heap=%p", + nBytes, osGetLastError(), (void*)hHeap); + } + return p; +} + +/* +** Free memory. +*/ +static void winMemFree(void *pPrior){ + HANDLE hHeap; + + winMemAssertMagic(); + hHeap = winMemGetHeap(); + assert( hHeap!=0 ); + assert( hHeap!=INVALID_HANDLE_VALUE ); +#ifdef SQLITE_WIN32_MALLOC_VALIDATE + assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ); +#endif + if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */ + if( !osHeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){ + sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%d), heap=%p", + pPrior, osGetLastError(), (void*)hHeap); + } +} + +/* +** Change the size of an existing memory allocation +*/ +static void *winMemRealloc(void *pPrior, int nBytes){ + HANDLE hHeap; + void *p; + + winMemAssertMagic(); + hHeap = winMemGetHeap(); + assert( hHeap!=0 ); + assert( hHeap!=INVALID_HANDLE_VALUE ); +#ifdef SQLITE_WIN32_MALLOC_VALIDATE + assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ); +#endif + assert( nBytes>=0 ); + if( !pPrior ){ + p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes); + }else{ + p = osHeapReAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior, (SIZE_T)nBytes); + } + if( !p ){ + sqlite3_log(SQLITE_NOMEM, "failed to %s %u bytes (%d), heap=%p", + pPrior ? "HeapReAlloc" : "HeapAlloc", nBytes, osGetLastError(), + (void*)hHeap); + } + return p; +} + +/* +** Return the size of an outstanding allocation, in bytes. +*/ +static int winMemSize(void *p){ + HANDLE hHeap; + SIZE_T n; + + winMemAssertMagic(); + hHeap = winMemGetHeap(); + assert( hHeap!=0 ); + assert( hHeap!=INVALID_HANDLE_VALUE ); +#ifdef SQLITE_WIN32_MALLOC_VALIDATE + assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); +#endif + if( !p ) return 0; + n = osHeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p); + if( n==(SIZE_T)-1 ){ + sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%d), heap=%p", + p, osGetLastError(), (void*)hHeap); + return 0; + } + return (int)n; +} + +/* +** Round up a request size to the next valid allocation size. +*/ +static int winMemRoundup(int n){ + return n; +} + +/* +** Initialize this module. +*/ +static int winMemInit(void *pAppData){ + winMemData *pWinMemData = (winMemData *)pAppData; + + if( !pWinMemData ) return SQLITE_ERROR; + assert( pWinMemData->magic==WINMEM_MAGIC ); + if( !pWinMemData->hHeap ){ + pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS, + SQLITE_WIN32_HEAP_INIT_SIZE, + SQLITE_WIN32_HEAP_MAX_SIZE); + if( !pWinMemData->hHeap ){ + sqlite3_log(SQLITE_NOMEM, + "failed to HeapCreate (%d), flags=%u, initSize=%u, maxSize=%u", + osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, + SQLITE_WIN32_HEAP_INIT_SIZE, SQLITE_WIN32_HEAP_MAX_SIZE); + return SQLITE_NOMEM; + } + pWinMemData->bOwned = TRUE; + } + assert( pWinMemData->hHeap!=0 ); + assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE ); +#ifdef SQLITE_WIN32_MALLOC_VALIDATE + assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); +#endif + return SQLITE_OK; +} + +/* +** Deinitialize this module. +*/ +static void winMemShutdown(void *pAppData){ + winMemData *pWinMemData = (winMemData *)pAppData; + + if( !pWinMemData ) return; + if( pWinMemData->hHeap ){ + assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE ); +#ifdef SQLITE_WIN32_MALLOC_VALIDATE + assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); +#endif + if( pWinMemData->bOwned ){ + if( !osHeapDestroy(pWinMemData->hHeap) ){ + sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%d), heap=%p", + osGetLastError(), (void*)pWinMemData->hHeap); + } + pWinMemData->bOwned = FALSE; + } + pWinMemData->hHeap = NULL; + } +} + +/* +** Populate the low-level memory allocation function pointers in +** sqlite3GlobalConfig.m with pointers to the routines in this file. The +** arguments specify the block of memory to manage. +** +** This routine is only called by sqlite3_config(), and therefore +** is not required to be threadsafe (it is not). +*/ +const sqlite3_mem_methods *sqlite3MemGetWin32(void){ + static const sqlite3_mem_methods winMemMethods = { + winMemMalloc, + winMemFree, + winMemRealloc, + winMemSize, + winMemRoundup, + winMemInit, + winMemShutdown, + &win_mem_data + }; + return &winMemMethods; +} + +void sqlite3MemSetDefault(void){ + sqlite3_config(SQLITE_CONFIG_MALLOC, sqlite3MemGetWin32()); +} +#endif /* SQLITE_WIN32_MALLOC */ + +/* +** Convert a UTF-8 string to Microsoft Unicode (UTF-16?). +** +** Space to hold the returned string is obtained from malloc. +*/ +static LPWSTR utf8ToUnicode(const char *zFilename){ + int nChar; + LPWSTR zWideFilename; + + nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); + if( nChar==0 ){ + return 0; + } + zWideFilename = sqlite3_malloc( nChar*sizeof(zWideFilename[0]) ); + if( zWideFilename==0 ){ + return 0; + } + nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, + nChar); + if( nChar==0 ){ + sqlite3_free(zWideFilename); + zWideFilename = 0; + } + return zWideFilename; +} + +/* +** Convert Microsoft Unicode to UTF-8. Space to hold the returned string is +** obtained from sqlite3_malloc(). +*/ +static char *unicodeToUtf8(LPCWSTR zWideFilename){ + int nByte; + char *zFilename; + + nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0); + if( nByte == 0 ){ + return 0; + } + zFilename = sqlite3_malloc( nByte ); + if( zFilename==0 ){ + return 0; + } + nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte, + 0, 0); + if( nByte == 0 ){ + sqlite3_free(zFilename); + zFilename = 0; + } + return zFilename; +} + +/* +** Convert an ANSI string to Microsoft Unicode, based on the +** current codepage settings for file apis. +** +** Space to hold the returned string is obtained +** from sqlite3_malloc. +*/ +static LPWSTR mbcsToUnicode(const char *zFilename){ + int nByte; + LPWSTR zMbcsFilename; + int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP; + + nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, NULL, + 0)*sizeof(WCHAR); + if( nByte==0 ){ + return 0; + } + zMbcsFilename = sqlite3_malloc( nByte*sizeof(zMbcsFilename[0]) ); + if( zMbcsFilename==0 ){ + return 0; + } + nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, + nByte); + if( nByte==0 ){ + sqlite3_free(zMbcsFilename); + zMbcsFilename = 0; + } + return zMbcsFilename; +} + +/* +** Convert Microsoft Unicode to multi-byte character string, based on the +** user's ANSI codepage. +** +** Space to hold the returned string is obtained from +** sqlite3_malloc(). +*/ +static char *unicodeToMbcs(LPCWSTR zWideFilename){ + int nByte; + char *zFilename; + int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP; + + nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0); + if( nByte == 0 ){ + return 0; + } + zFilename = sqlite3_malloc( nByte ); + if( zFilename==0 ){ + return 0; + } + nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, + nByte, 0, 0); + if( nByte == 0 ){ + sqlite3_free(zFilename); + zFilename = 0; + } + return zFilename; +} + +/* +** Convert multibyte character string to UTF-8. Space to hold the +** returned string is obtained from sqlite3_malloc(). +*/ +char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){ + char *zFilenameUtf8; + LPWSTR zTmpWide; + + zTmpWide = mbcsToUnicode(zFilename); + if( zTmpWide==0 ){ + return 0; + } + zFilenameUtf8 = unicodeToUtf8(zTmpWide); + sqlite3_free(zTmpWide); + return zFilenameUtf8; +} + +/* +** Convert UTF-8 to multibyte character string. Space to hold the +** returned string is obtained from sqlite3_malloc(). +*/ +char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){ + char *zFilenameMbcs; + LPWSTR zTmpWide; + + zTmpWide = utf8ToUnicode(zFilename); + if( zTmpWide==0 ){ + return 0; + } + zFilenameMbcs = unicodeToMbcs(zTmpWide); + sqlite3_free(zTmpWide); + return zFilenameMbcs; +} + + +/* +** The return value of getLastErrorMsg +** is zero if the error message fits in the buffer, or non-zero +** otherwise (if the message was truncated). +*/ +static int getLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ + /* FormatMessage returns 0 on failure. Otherwise it + ** returns the number of TCHARs written to the output + ** buffer, excluding the terminating null char. + */ + DWORD dwLen = 0; + char *zOut = 0; + + if( isNT() ){ + LPWSTR zTempWide = NULL; + dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + lastErrno, + 0, + (LPWSTR) &zTempWide, + 0, + 0); + if( dwLen > 0 ){ + /* allocate a buffer and convert to UTF8 */ + sqlite3BeginBenignMalloc(); + zOut = unicodeToUtf8(zTempWide); + sqlite3EndBenignMalloc(); + /* free the system buffer allocated by FormatMessage */ + osLocalFree(zTempWide); + } +/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. +** Since the ANSI version of these Windows API do not exist for WINCE, +** it's important to not reference them for WINCE builds. +*/ +#if SQLITE_OS_WINCE==0 + }else{ + char *zTemp = NULL; + dwLen = osFormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + lastErrno, + 0, + (LPSTR) &zTemp, + 0, + 0); + if( dwLen > 0 ){ + /* allocate a buffer and convert to UTF8 */ + sqlite3BeginBenignMalloc(); + zOut = sqlite3_win32_mbcs_to_utf8(zTemp); + sqlite3EndBenignMalloc(); + /* free the system buffer allocated by FormatMessage */ + osLocalFree(zTemp); + } +#endif + } + if( 0 == dwLen ){ + sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", lastErrno, lastErrno); + }else{ + /* copy a maximum of nBuf chars to output buffer */ + sqlite3_snprintf(nBuf, zBuf, "%s", zOut); + /* free the UTF8 buffer */ + sqlite3_free(zOut); + } + return 0; +} + +/* +** +** This function - winLogErrorAtLine() - is only ever called via the macro +** winLogError(). +** +** This routine is invoked after an error occurs in an OS function. +** It logs a message using sqlite3_log() containing the current value of +** error code and, if possible, the human-readable equivalent from +** FormatMessage. +** +** The first argument passed to the macro should be the error code that +** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN). +** The two subsequent arguments should be the name of the OS function that +** failed and the the associated file-system path, if any. +*/ +#define winLogError(a,b,c,d) winLogErrorAtLine(a,b,c,d,__LINE__) +static int winLogErrorAtLine( + int errcode, /* SQLite error code */ + DWORD lastErrno, /* Win32 last error */ + const char *zFunc, /* Name of OS function that failed */ + const char *zPath, /* File path associated with error */ + int iLine /* Source line number where error occurred */ +){ + char zMsg[500]; /* Human readable error text */ + int i; /* Loop counter */ + + zMsg[0] = 0; + getLastErrorMsg(lastErrno, sizeof(zMsg), zMsg); + assert( errcode!=SQLITE_OK ); + if( zPath==0 ) zPath = ""; + for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){} + zMsg[i] = 0; + sqlite3_log(errcode, + "os_win.c:%d: (%d) %s(%s) - %s", + iLine, lastErrno, zFunc, zPath, zMsg + ); + + return errcode; +} + +/* +** The number of times that a ReadFile(), WriteFile(), and DeleteFile() +** will be retried following a locking error - probably caused by +** antivirus software. Also the initial delay before the first retry. +** The delay increases linearly with each retry. +*/ +#ifndef SQLITE_WIN32_IOERR_RETRY +# define SQLITE_WIN32_IOERR_RETRY 10 +#endif +#ifndef SQLITE_WIN32_IOERR_RETRY_DELAY +# define SQLITE_WIN32_IOERR_RETRY_DELAY 25 +#endif +static int win32IoerrRetry = SQLITE_WIN32_IOERR_RETRY; +static int win32IoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY; + +/* +** If a ReadFile() or WriteFile() error occurs, invoke this routine +** to see if it should be retried. Return TRUE to retry. Return FALSE +** to give up with an error. +*/ +static int retryIoerr(int *pnRetry, DWORD *pError){ + DWORD e = osGetLastError(); + if( *pnRetry>=win32IoerrRetry ){ + if( pError ){ + *pError = e; + } + return 0; + } + if( e==ERROR_ACCESS_DENIED || + e==ERROR_LOCK_VIOLATION || + e==ERROR_SHARING_VIOLATION ){ + osSleep(win32IoerrRetryDelay*(1+*pnRetry)); + ++*pnRetry; + return 1; + } + if( pError ){ + *pError = e; + } + return 0; +} + +/* +** Log a I/O error retry episode. +*/ +static void logIoerr(int nRetry){ + if( nRetry ){ + sqlite3_log(SQLITE_IOERR, + "delayed %dms for lock/sharing conflict", + win32IoerrRetryDelay*nRetry*(nRetry+1)/2 + ); + } +} + +#if SQLITE_OS_WINCE +/************************************************************************* +** This section contains code for WinCE only. +*/ +/* +** Windows CE does not have a localtime() function. So create a +** substitute. +*/ +#include +struct tm *__cdecl localtime(const time_t *t) +{ + static struct tm y; + FILETIME uTm, lTm; + SYSTEMTIME pTm; + sqlite3_int64 t64; + t64 = *t; + t64 = (t64 + 11644473600)*10000000; + uTm.dwLowDateTime = (DWORD)(t64 & 0xFFFFFFFF); + uTm.dwHighDateTime= (DWORD)(t64 >> 32); + osFileTimeToLocalFileTime(&uTm,&lTm); + osFileTimeToSystemTime(&lTm,&pTm); + y.tm_year = pTm.wYear - 1900; + y.tm_mon = pTm.wMonth - 1; + y.tm_wday = pTm.wDayOfWeek; + y.tm_mday = pTm.wDay; + y.tm_hour = pTm.wHour; + y.tm_min = pTm.wMinute; + y.tm_sec = pTm.wSecond; + return &y; +} + +#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)] + +/* +** Acquire a lock on the handle h +*/ +static void winceMutexAcquire(HANDLE h){ + DWORD dwErr; + do { + dwErr = WaitForSingleObject(h, INFINITE); + } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED); +} +/* +** Release a lock acquired by winceMutexAcquire() +*/ +#define winceMutexRelease(h) ReleaseMutex(h) + +/* +** Create the mutex and shared memory used for locking in the file +** descriptor pFile +*/ +static BOOL winceCreateLock(const char *zFilename, winFile *pFile){ + LPWSTR zTok; + LPWSTR zName; + BOOL bInit = TRUE; + + zName = utf8ToUnicode(zFilename); + if( zName==0 ){ + /* out of memory */ + return FALSE; + } + + /* Initialize the local lockdata */ + memset(&pFile->local, 0, sizeof(pFile->local)); + + /* Replace the backslashes from the filename and lowercase it + ** to derive a mutex name. */ + zTok = osCharLowerW(zName); + for (;*zTok;zTok++){ + if (*zTok == '\\') *zTok = '_'; + } + + /* Create/open the named mutex */ + pFile->hMutex = osCreateMutexW(NULL, FALSE, zName); + if (!pFile->hMutex){ + pFile->lastErrno = osGetLastError(); + winLogError(SQLITE_ERROR, pFile->lastErrno, "winceCreateLock1", zFilename); + sqlite3_free(zName); + return FALSE; + } + + /* Acquire the mutex before continuing */ + winceMutexAcquire(pFile->hMutex); + + /* Since the names of named mutexes, semaphores, file mappings etc are + ** case-sensitive, take advantage of that by uppercasing the mutex name + ** and using that as the shared filemapping name. + */ + osCharUpperW(zName); + pFile->hShared = osCreateFileMappingW(INVALID_HANDLE_VALUE, NULL, + PAGE_READWRITE, 0, sizeof(winceLock), + zName); + + /* Set a flag that indicates we're the first to create the memory so it + ** must be zero-initialized */ + if (osGetLastError() == ERROR_ALREADY_EXISTS){ + bInit = FALSE; + } + + sqlite3_free(zName); + + /* If we succeeded in making the shared memory handle, map it. */ + if (pFile->hShared){ + pFile->shared = (winceLock*)osMapViewOfFile(pFile->hShared, + FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock)); + /* If mapping failed, close the shared memory handle and erase it */ + if (!pFile->shared){ + pFile->lastErrno = osGetLastError(); + winLogError(SQLITE_ERROR, pFile->lastErrno, + "winceCreateLock2", zFilename); + osCloseHandle(pFile->hShared); + pFile->hShared = NULL; + } + } + + /* If shared memory could not be created, then close the mutex and fail */ + if (pFile->hShared == NULL){ + winceMutexRelease(pFile->hMutex); + osCloseHandle(pFile->hMutex); + pFile->hMutex = NULL; + return FALSE; + } + + /* Initialize the shared memory if we're supposed to */ + if (bInit) { + memset(pFile->shared, 0, sizeof(winceLock)); + } + + winceMutexRelease(pFile->hMutex); + return TRUE; +} + +/* +** Destroy the part of winFile that deals with wince locks +*/ +static void winceDestroyLock(winFile *pFile){ + if (pFile->hMutex){ + /* Acquire the mutex */ + winceMutexAcquire(pFile->hMutex); + + /* The following blocks should probably assert in debug mode, but they + are to cleanup in case any locks remained open */ + if (pFile->local.nReaders){ + pFile->shared->nReaders --; + } + if (pFile->local.bReserved){ + pFile->shared->bReserved = FALSE; + } + if (pFile->local.bPending){ + pFile->shared->bPending = FALSE; + } + if (pFile->local.bExclusive){ + pFile->shared->bExclusive = FALSE; + } + + /* De-reference and close our copy of the shared memory handle */ + osUnmapViewOfFile(pFile->shared); + osCloseHandle(pFile->hShared); + + /* Done with the mutex */ + winceMutexRelease(pFile->hMutex); + osCloseHandle(pFile->hMutex); + pFile->hMutex = NULL; + } +} + +/* +** An implementation of the LockFile() API of Windows for CE +*/ +static BOOL winceLockFile( + HANDLE *phFile, + DWORD dwFileOffsetLow, + DWORD dwFileOffsetHigh, + DWORD nNumberOfBytesToLockLow, + DWORD nNumberOfBytesToLockHigh +){ + winFile *pFile = HANDLE_TO_WINFILE(phFile); + BOOL bReturn = FALSE; + + UNUSED_PARAMETER(dwFileOffsetHigh); + UNUSED_PARAMETER(nNumberOfBytesToLockHigh); + + if (!pFile->hMutex) return TRUE; + winceMutexAcquire(pFile->hMutex); + + /* Wanting an exclusive lock? */ + if (dwFileOffsetLow == (DWORD)SHARED_FIRST + && nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){ + if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){ + pFile->shared->bExclusive = TRUE; + pFile->local.bExclusive = TRUE; + bReturn = TRUE; + } + } + + /* Want a read-only lock? */ + else if (dwFileOffsetLow == (DWORD)SHARED_FIRST && + nNumberOfBytesToLockLow == 1){ + if (pFile->shared->bExclusive == 0){ + pFile->local.nReaders ++; + if (pFile->local.nReaders == 1){ + pFile->shared->nReaders ++; + } + bReturn = TRUE; + } + } + + /* Want a pending lock? */ + else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToLockLow == 1){ + /* If no pending lock has been acquired, then acquire it */ + if (pFile->shared->bPending == 0) { + pFile->shared->bPending = TRUE; + pFile->local.bPending = TRUE; + bReturn = TRUE; + } + } + + /* Want a reserved lock? */ + else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToLockLow == 1){ + if (pFile->shared->bReserved == 0) { + pFile->shared->bReserved = TRUE; + pFile->local.bReserved = TRUE; + bReturn = TRUE; + } + } + + winceMutexRelease(pFile->hMutex); + return bReturn; +} + +/* +** An implementation of the UnlockFile API of Windows for CE +*/ +static BOOL winceUnlockFile( + HANDLE *phFile, + DWORD dwFileOffsetLow, + DWORD dwFileOffsetHigh, + DWORD nNumberOfBytesToUnlockLow, + DWORD nNumberOfBytesToUnlockHigh +){ + winFile *pFile = HANDLE_TO_WINFILE(phFile); + BOOL bReturn = FALSE; + + UNUSED_PARAMETER(dwFileOffsetHigh); + UNUSED_PARAMETER(nNumberOfBytesToUnlockHigh); + + if (!pFile->hMutex) return TRUE; + winceMutexAcquire(pFile->hMutex); + + /* Releasing a reader lock or an exclusive lock */ + if (dwFileOffsetLow == (DWORD)SHARED_FIRST){ + /* Did we have an exclusive lock? */ + if (pFile->local.bExclusive){ + assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE); + pFile->local.bExclusive = FALSE; + pFile->shared->bExclusive = FALSE; + bReturn = TRUE; + } + + /* Did we just have a reader lock? */ + else if (pFile->local.nReaders){ + assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE || nNumberOfBytesToUnlockLow == 1); + pFile->local.nReaders --; + if (pFile->local.nReaders == 0) + { + pFile->shared->nReaders --; + } + bReturn = TRUE; + } + } + + /* Releasing a pending lock */ + else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){ + if (pFile->local.bPending){ + pFile->local.bPending = FALSE; + pFile->shared->bPending = FALSE; + bReturn = TRUE; + } + } + /* Releasing a reserved lock */ + else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){ + if (pFile->local.bReserved) { + pFile->local.bReserved = FALSE; + pFile->shared->bReserved = FALSE; + bReturn = TRUE; + } + } + + winceMutexRelease(pFile->hMutex); + return bReturn; +} + +/* +** An implementation of the LockFileEx() API of Windows for CE +*/ +static BOOL winceLockFileEx( + HANDLE *phFile, + DWORD dwFlags, + DWORD dwReserved, + DWORD nNumberOfBytesToLockLow, + DWORD nNumberOfBytesToLockHigh, + LPOVERLAPPED lpOverlapped +){ + UNUSED_PARAMETER(dwReserved); + UNUSED_PARAMETER(nNumberOfBytesToLockHigh); + + /* If the caller wants a shared read lock, forward this call + ** to winceLockFile */ + if (lpOverlapped->Offset == (DWORD)SHARED_FIRST && + dwFlags == 1 && + nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){ + return winceLockFile(phFile, SHARED_FIRST, 0, 1, 0); + } + return FALSE; +} +/* +** End of the special code for wince +*****************************************************************************/ +#endif /* SQLITE_OS_WINCE */ + +/***************************************************************************** +** The next group of routines implement the I/O methods specified +** by the sqlite3_io_methods object. +******************************************************************************/ + +/* +** Some Microsoft compilers lack this definition. +*/ +#ifndef INVALID_SET_FILE_POINTER +# define INVALID_SET_FILE_POINTER ((DWORD)-1) +#endif + +/* +** Move the current position of the file handle passed as the first +** argument to offset iOffset within the file. If successful, return 0. +** Otherwise, set pFile->lastErrno and return non-zero. +*/ +static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){ + LONG upperBits; /* Most sig. 32 bits of new offset */ + LONG lowerBits; /* Least sig. 32 bits of new offset */ + DWORD dwRet; /* Value returned by SetFilePointer() */ + DWORD lastErrno; /* Value returned by GetLastError() */ + + upperBits = (LONG)((iOffset>>32) & 0x7fffffff); + lowerBits = (LONG)(iOffset & 0xffffffff); + + /* API oddity: If successful, SetFilePointer() returns a dword + ** containing the lower 32-bits of the new file-offset. Or, if it fails, + ** it returns INVALID_SET_FILE_POINTER. However according to MSDN, + ** INVALID_SET_FILE_POINTER may also be a valid new offset. So to determine + ** whether an error has actually occured, it is also necessary to call + ** GetLastError(). + */ + dwRet = osSetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); + + if( (dwRet==INVALID_SET_FILE_POINTER + && ((lastErrno = osGetLastError())!=NO_ERROR)) ){ + pFile->lastErrno = lastErrno; + winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, + "seekWinFile", pFile->zPath); + return 1; + } + + return 0; +} + +/* +** Close a file. +** +** It is reported that an attempt to close a handle might sometimes +** fail. This is a very unreasonable result, but Windows is notorious +** for being unreasonable so I do not doubt that it might happen. If +** the close fails, we pause for 100 milliseconds and try again. As +** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before +** giving up and returning an error. +*/ +#define MX_CLOSE_ATTEMPT 3 +static int winClose(sqlite3_file *id){ + int rc, cnt = 0; + winFile *pFile = (winFile*)id; + + assert( id!=0 ); + assert( pFile->pShm==0 ); + OSTRACE(("CLOSE %d\n", pFile->h)); + do{ + rc = osCloseHandle(pFile->h); + /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */ + }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (osSleep(100), 1) ); +#if SQLITE_OS_WINCE +#define WINCE_DELETION_ATTEMPTS 3 + winceDestroyLock(pFile); + if( pFile->zDeleteOnClose ){ + int cnt = 0; + while( + osDeleteFileW(pFile->zDeleteOnClose)==0 + && osGetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff + && cnt++ < WINCE_DELETION_ATTEMPTS + ){ + osSleep(100); /* Wait a little before trying again */ + } + sqlite3_free(pFile->zDeleteOnClose); + } +#endif + OSTRACE(("CLOSE %d %s\n", pFile->h, rc ? "ok" : "failed")); + OpenCounter(-1); + return rc ? SQLITE_OK + : winLogError(SQLITE_IOERR_CLOSE, osGetLastError(), + "winClose", pFile->zPath); +} + +/* +** Read data from a file into a buffer. Return SQLITE_OK if all +** bytes were read successfully and SQLITE_IOERR if anything goes +** wrong. +*/ +static int winRead( + sqlite3_file *id, /* File to read from */ + void *pBuf, /* Write content into this buffer */ + int amt, /* Number of bytes to read */ + sqlite3_int64 offset /* Begin reading at this offset */ +){ + winFile *pFile = (winFile*)id; /* file handle */ + DWORD nRead; /* Number of bytes actually read from file */ + int nRetry = 0; /* Number of retrys */ + + assert( id!=0 ); + SimulateIOError(return SQLITE_IOERR_READ); + OSTRACE(("READ %d lock=%d\n", pFile->h, pFile->locktype)); + + if( seekWinFile(pFile, offset) ){ + return SQLITE_FULL; + } + while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){ + DWORD lastErrno; + if( retryIoerr(&nRetry, &lastErrno) ) continue; + pFile->lastErrno = lastErrno; + return winLogError(SQLITE_IOERR_READ, pFile->lastErrno, + "winRead", pFile->zPath); + } + logIoerr(nRetry); + if( nRead<(DWORD)amt ){ + /* Unread parts of the buffer must be zero-filled */ + memset(&((char*)pBuf)[nRead], 0, amt-nRead); + return SQLITE_IOERR_SHORT_READ; + } + + return SQLITE_OK; +} + +/* +** Write data from a buffer into a file. Return SQLITE_OK on success +** or some other error code on failure. +*/ +static int winWrite( + sqlite3_file *id, /* File to write into */ + const void *pBuf, /* The bytes to be written */ + int amt, /* Number of bytes to write */ + sqlite3_int64 offset /* Offset into the file to begin writing at */ +){ + int rc; /* True if error has occured, else false */ + winFile *pFile = (winFile*)id; /* File handle */ + int nRetry = 0; /* Number of retries */ + + assert( amt>0 ); + assert( pFile ); + SimulateIOError(return SQLITE_IOERR_WRITE); + SimulateDiskfullError(return SQLITE_FULL); + + OSTRACE(("WRITE %d lock=%d\n", pFile->h, pFile->locktype)); + + rc = seekWinFile(pFile, offset); + if( rc==0 ){ + u8 *aRem = (u8 *)pBuf; /* Data yet to be written */ + int nRem = amt; /* Number of bytes yet to be written */ + DWORD nWrite; /* Bytes written by each WriteFile() call */ + DWORD lastErrno = NO_ERROR; /* Value returned by GetLastError() */ + + while( nRem>0 ){ + if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){ + if( retryIoerr(&nRetry, &lastErrno) ) continue; + break; + } + if( nWrite<=0 ) break; + aRem += nWrite; + nRem -= nWrite; + } + if( nRem>0 ){ + pFile->lastErrno = lastErrno; + rc = 1; + } + } + + if( rc ){ + if( ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ) + || ( pFile->lastErrno==ERROR_DISK_FULL )){ + return SQLITE_FULL; + } + return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno, + "winWrite", pFile->zPath); + }else{ + logIoerr(nRetry); + } + return SQLITE_OK; +} + +/* +** Truncate an open file to a specified size +*/ +static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ + winFile *pFile = (winFile*)id; /* File handle object */ + int rc = SQLITE_OK; /* Return code for this function */ + + assert( pFile ); + + OSTRACE(("TRUNCATE %d %lld\n", pFile->h, nByte)); + SimulateIOError(return SQLITE_IOERR_TRUNCATE); + + /* If the user has configured a chunk-size for this file, truncate the + ** file so that it consists of an integer number of chunks (i.e. the + ** actual file size after the operation may be larger than the requested + ** size). + */ + if( pFile->szChunk>0 ){ + nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; + } + + /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */ + if( seekWinFile(pFile, nByte) ){ + rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, + "winTruncate1", pFile->zPath); + }else if( 0==osSetEndOfFile(pFile->h) ){ + pFile->lastErrno = osGetLastError(); + rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, + "winTruncate2", pFile->zPath); + } + + OSTRACE(("TRUNCATE %d %lld %s\n", pFile->h, nByte, rc ? "failed" : "ok")); + return rc; +} + +#ifdef SQLITE_TEST +/* +** Count the number of fullsyncs and normal syncs. This is used to test +** that syncs and fullsyncs are occuring at the right times. +*/ +int sqlite3_sync_count = 0; +int sqlite3_fullsync_count = 0; +#endif + +/* +** Make sure all writes to a particular file are committed to disk. +*/ +static int winSync(sqlite3_file *id, int flags){ +#ifndef SQLITE_NO_SYNC + /* + ** Used only when SQLITE_NO_SYNC is not defined. + */ + BOOL rc; +#endif +#if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || \ + (defined(SQLITE_TEST) && defined(SQLITE_DEBUG)) + /* + ** Used when SQLITE_NO_SYNC is not defined and by the assert() and/or + ** OSTRACE() macros. + */ + winFile *pFile = (winFile*)id; +#else + UNUSED_PARAMETER(id); +#endif + + assert( pFile ); + /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */ + assert((flags&0x0F)==SQLITE_SYNC_NORMAL + || (flags&0x0F)==SQLITE_SYNC_FULL + ); + + OSTRACE(("SYNC %d lock=%d\n", pFile->h, pFile->locktype)); + + /* Unix cannot, but some systems may return SQLITE_FULL from here. This + ** line is to test that doing so does not cause any problems. + */ + SimulateDiskfullError( return SQLITE_FULL ); + +#ifndef SQLITE_TEST + UNUSED_PARAMETER(flags); +#else + if( (flags&0x0F)==SQLITE_SYNC_FULL ){ + sqlite3_fullsync_count++; + } + sqlite3_sync_count++; +#endif + + /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a + ** no-op + */ +#ifdef SQLITE_NO_SYNC + return SQLITE_OK; +#else + rc = osFlushFileBuffers(pFile->h); + SimulateIOError( rc=FALSE ); + if( rc ){ + return SQLITE_OK; + }else{ + pFile->lastErrno = osGetLastError(); + return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno, + "winSync", pFile->zPath); + } +#endif +} + +/* +** Determine the current size of a file in bytes +*/ +static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ + DWORD upperBits; + DWORD lowerBits; + winFile *pFile = (winFile*)id; + DWORD lastErrno; + + assert( id!=0 ); + SimulateIOError(return SQLITE_IOERR_FSTAT); + lowerBits = osGetFileSize(pFile->h, &upperBits); + if( (lowerBits == INVALID_FILE_SIZE) + && ((lastErrno = osGetLastError())!=NO_ERROR) ) + { + pFile->lastErrno = lastErrno; + return winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, + "winFileSize", pFile->zPath); + } + *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits; + return SQLITE_OK; +} + +/* +** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems. +*/ +#ifndef LOCKFILE_FAIL_IMMEDIATELY +# define LOCKFILE_FAIL_IMMEDIATELY 1 +#endif + +/* +** Acquire a reader lock. +** Different API routines are called depending on whether or not this +** is Win9x or WinNT. +*/ +static int getReadLock(winFile *pFile){ + int res; + if( isNT() ){ + OVERLAPPED ovlp; + ovlp.Offset = SHARED_FIRST; + ovlp.OffsetHigh = 0; + ovlp.hEvent = 0; + res = osLockFileEx(pFile->h, LOCKFILE_FAIL_IMMEDIATELY, + 0, SHARED_SIZE, 0, &ovlp); +/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. +*/ +#if SQLITE_OS_WINCE==0 + }else{ + int lk; + sqlite3_randomness(sizeof(lk), &lk); + pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1)); + res = osLockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); +#endif + } + if( res == 0 ){ + pFile->lastErrno = osGetLastError(); + /* No need to log a failure to lock */ + } + return res; +} + +/* +** Undo a readlock +*/ +static int unlockReadLock(winFile *pFile){ + int res; + DWORD lastErrno; + if( isNT() ){ + res = osUnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); +/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. +*/ +#if SQLITE_OS_WINCE==0 + }else{ + res = osUnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0); +#endif + } + if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){ + pFile->lastErrno = lastErrno; + winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno, + "unlockReadLock", pFile->zPath); + } + return res; +} + +/* +** Lock the file with the lock specified by parameter locktype - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** SHARED -> (PENDING) -> EXCLUSIVE +** RESERVED -> (PENDING) -> EXCLUSIVE +** PENDING -> EXCLUSIVE +** +** This routine will only increase a lock. The winUnlock() routine +** erases all locks at once and returns us immediately to locking level 0. +** It is not possible to lower the locking level one step at a time. You +** must go straight to locking level 0. +*/ +static int winLock(sqlite3_file *id, int locktype){ + int rc = SQLITE_OK; /* Return code from subroutines */ + int res = 1; /* Result of a Windows lock call */ + int newLocktype; /* Set pFile->locktype to this value before exiting */ + int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */ + winFile *pFile = (winFile*)id; + DWORD lastErrno = NO_ERROR; + + assert( id!=0 ); + OSTRACE(("LOCK %d %d was %d(%d)\n", + pFile->h, locktype, pFile->locktype, pFile->sharedLockByte)); + + /* If there is already a lock of this type or more restrictive on the + ** OsFile, do nothing. Don't use the end_lock: exit path, as + ** sqlite3OsEnterMutex() hasn't been called yet. + */ + if( pFile->locktype>=locktype ){ + return SQLITE_OK; + } + + /* Make sure the locking sequence is correct + */ + assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK ); + assert( locktype!=PENDING_LOCK ); + assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK ); + + /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or + ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of + ** the PENDING_LOCK byte is temporary. + */ + newLocktype = pFile->locktype; + if( (pFile->locktype==NO_LOCK) + || ( (locktype==EXCLUSIVE_LOCK) + && (pFile->locktype==RESERVED_LOCK)) + ){ + int cnt = 3; + while( cnt-->0 && (res = osLockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){ + /* Try 3 times to get the pending lock. This is needed to work + ** around problems caused by indexing and/or anti-virus software on + ** Windows systems. + ** If you are using this code as a model for alternative VFSes, do not + ** copy this retry logic. It is a hack intended for Windows only. + */ + OSTRACE(("could not get a PENDING lock. cnt=%d\n", cnt)); + if( cnt ) osSleep(1); + } + gotPendingLock = res; + if( !res ){ + lastErrno = osGetLastError(); + } + } + + /* Acquire a shared lock + */ + if( locktype==SHARED_LOCK && res ){ + assert( pFile->locktype==NO_LOCK ); + res = getReadLock(pFile); + if( res ){ + newLocktype = SHARED_LOCK; + }else{ + lastErrno = osGetLastError(); + } + } + + /* Acquire a RESERVED lock + */ + if( locktype==RESERVED_LOCK && res ){ + assert( pFile->locktype==SHARED_LOCK ); + res = osLockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); + if( res ){ + newLocktype = RESERVED_LOCK; + }else{ + lastErrno = osGetLastError(); + } + } + + /* Acquire a PENDING lock + */ + if( locktype==EXCLUSIVE_LOCK && res ){ + newLocktype = PENDING_LOCK; + gotPendingLock = 0; + } + + /* Acquire an EXCLUSIVE lock + */ + if( locktype==EXCLUSIVE_LOCK && res ){ + assert( pFile->locktype>=SHARED_LOCK ); + res = unlockReadLock(pFile); + OSTRACE(("unreadlock = %d\n", res)); + res = osLockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); + if( res ){ + newLocktype = EXCLUSIVE_LOCK; + }else{ + lastErrno = osGetLastError(); + OSTRACE(("error-code = %d\n", lastErrno)); + getReadLock(pFile); + } + } + + /* If we are holding a PENDING lock that ought to be released, then + ** release it now. + */ + if( gotPendingLock && locktype==SHARED_LOCK ){ + osUnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0); + } + + /* Update the state of the lock has held in the file descriptor then + ** return the appropriate result code. + */ + if( res ){ + rc = SQLITE_OK; + }else{ + OSTRACE(("LOCK FAILED %d trying for %d but got %d\n", pFile->h, + locktype, newLocktype)); + pFile->lastErrno = lastErrno; + rc = SQLITE_BUSY; + } + pFile->locktype = (u8)newLocktype; + return rc; +} + +/* +** This routine checks if there is a RESERVED lock held on the specified +** file by this or any other process. If such a lock is held, return +** non-zero, otherwise zero. +*/ +static int winCheckReservedLock(sqlite3_file *id, int *pResOut){ + int rc; + winFile *pFile = (winFile*)id; + + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); + + assert( id!=0 ); + if( pFile->locktype>=RESERVED_LOCK ){ + rc = 1; + OSTRACE(("TEST WR-LOCK %d %d (local)\n", pFile->h, rc)); + }else{ + rc = osLockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); + if( rc ){ + osUnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); + } + rc = !rc; + OSTRACE(("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc)); + } + *pResOut = rc; + return SQLITE_OK; +} + +/* +** Lower the locking level on file descriptor id to locktype. locktype +** must be either NO_LOCK or SHARED_LOCK. +** +** If the locking level of the file descriptor is already at or below +** the requested locking level, this routine is a no-op. +** +** It is not possible for this routine to fail if the second argument +** is NO_LOCK. If the second argument is SHARED_LOCK then this routine +** might return SQLITE_IOERR; +*/ +static int winUnlock(sqlite3_file *id, int locktype){ + int type; + winFile *pFile = (winFile*)id; + int rc = SQLITE_OK; + assert( pFile!=0 ); + assert( locktype<=SHARED_LOCK ); + OSTRACE(("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype, + pFile->locktype, pFile->sharedLockByte)); + type = pFile->locktype; + if( type>=EXCLUSIVE_LOCK ){ + osUnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); + if( locktype==SHARED_LOCK && !getReadLock(pFile) ){ + /* This should never happen. We should always be able to + ** reacquire the read lock */ + rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(), + "winUnlock", pFile->zPath); + } + } + if( type>=RESERVED_LOCK ){ + osUnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); + } + if( locktype==NO_LOCK && type>=SHARED_LOCK ){ + unlockReadLock(pFile); + } + if( type>=PENDING_LOCK ){ + osUnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0); + } + pFile->locktype = (u8)locktype; + return rc; +} + +/* +** If *pArg is inititially negative then this is a query. Set *pArg to +** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set. +** +** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags. +*/ +static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){ + if( *pArg<0 ){ + *pArg = (pFile->ctrlFlags & mask)!=0; + }else if( (*pArg)==0 ){ + pFile->ctrlFlags &= ~mask; + }else{ + pFile->ctrlFlags |= mask; + } +} + +/* +** Control and query of the open file handle. +*/ +static int winFileControl(sqlite3_file *id, int op, void *pArg){ + winFile *pFile = (winFile*)id; + switch( op ){ + case SQLITE_FCNTL_LOCKSTATE: { + *(int*)pArg = pFile->locktype; + return SQLITE_OK; + } + case SQLITE_LAST_ERRNO: { + *(int*)pArg = (int)pFile->lastErrno; + return SQLITE_OK; + } + case SQLITE_FCNTL_CHUNK_SIZE: { + pFile->szChunk = *(int *)pArg; + return SQLITE_OK; + } + case SQLITE_FCNTL_SIZE_HINT: { + if( pFile->szChunk>0 ){ + sqlite3_int64 oldSz; + int rc = winFileSize(id, &oldSz); + if( rc==SQLITE_OK ){ + sqlite3_int64 newSz = *(sqlite3_int64*)pArg; + if( newSz>oldSz ){ + SimulateIOErrorBenign(1); + rc = winTruncate(id, newSz); + SimulateIOErrorBenign(0); + } + } + return rc; + } + return SQLITE_OK; + } + case SQLITE_FCNTL_PERSIST_WAL: { + winModeBit(pFile, WINFILE_PERSIST_WAL, (int*)pArg); + return SQLITE_OK; + } + case SQLITE_FCNTL_POWERSAFE_OVERWRITE: { + winModeBit(pFile, WINFILE_PSOW, (int*)pArg); + return SQLITE_OK; + } + case SQLITE_FCNTL_VFSNAME: { + *(char**)pArg = sqlite3_mprintf("win32"); + return SQLITE_OK; + } + case SQLITE_FCNTL_WIN32_AV_RETRY: { + int *a = (int*)pArg; + if( a[0]>0 ){ + win32IoerrRetry = a[0]; + }else{ + a[0] = win32IoerrRetry; + } + if( a[1]>0 ){ + win32IoerrRetryDelay = a[1]; + }else{ + a[1] = win32IoerrRetryDelay; + } + return SQLITE_OK; + } + } + return SQLITE_NOTFOUND; +} + +/* +** Return the sector size in bytes of the underlying block device for +** the specified file. This is almost always 512 bytes, but may be +** larger for some devices. +** +** SQLite code assumes this function cannot fail. It also assumes that +** if two files are created in the same file-system directory (i.e. +** a database and its journal file) that the sector size will be the +** same for both. +*/ +static int winSectorSize(sqlite3_file *id){ + (void)id; + return SQLITE_DEFAULT_SECTOR_SIZE; +} + +/* +** Return a vector of device characteristics. +*/ +static int winDeviceCharacteristics(sqlite3_file *id){ + winFile *p = (winFile*)id; + return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | + ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0); +} + +#ifndef SQLITE_OMIT_WAL + +/* +** Windows will only let you create file view mappings +** on allocation size granularity boundaries. +** During sqlite3_os_init() we do a GetSystemInfo() +** to get the granularity size. +*/ +SYSTEM_INFO winSysInfo; + +/* +** Helper functions to obtain and relinquish the global mutex. The +** global mutex is used to protect the winLockInfo objects used by +** this file, all of which may be shared by multiple threads. +** +** Function winShmMutexHeld() is used to assert() that the global mutex +** is held when required. This function is only used as part of assert() +** statements. e.g. +** +** winShmEnterMutex() +** assert( winShmMutexHeld() ); +** winShmLeaveMutex() +*/ +static void winShmEnterMutex(void){ + sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); +} +static void winShmLeaveMutex(void){ + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); +} +#ifdef SQLITE_DEBUG +static int winShmMutexHeld(void) { + return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); +} +#endif + +/* +** Object used to represent a single file opened and mmapped to provide +** shared memory. When multiple threads all reference the same +** log-summary, each thread has its own winFile object, but they all +** point to a single instance of this object. In other words, each +** log-summary is opened only once per process. +** +** winShmMutexHeld() must be true when creating or destroying +** this object or while reading or writing the following fields: +** +** nRef +** pNext +** +** The following fields are read-only after the object is created: +** +** fid +** zFilename +** +** Either winShmNode.mutex must be held or winShmNode.nRef==0 and +** winShmMutexHeld() is true when reading or writing any other field +** in this structure. +** +*/ +struct winShmNode { + sqlite3_mutex *mutex; /* Mutex to access this object */ + char *zFilename; /* Name of the file */ + winFile hFile; /* File handle from winOpen */ + + int szRegion; /* Size of shared-memory regions */ + int nRegion; /* Size of array apRegion */ + struct ShmRegion { + HANDLE hMap; /* File handle from CreateFileMapping */ + void *pMap; + } *aRegion; + DWORD lastErrno; /* The Windows errno from the last I/O error */ + + int nRef; /* Number of winShm objects pointing to this */ + winShm *pFirst; /* All winShm objects pointing to this */ + winShmNode *pNext; /* Next in list of all winShmNode objects */ +#ifdef SQLITE_DEBUG + u8 nextShmId; /* Next available winShm.id value */ +#endif +}; + +/* +** A global array of all winShmNode objects. +** +** The winShmMutexHeld() must be true while reading or writing this list. +*/ +static winShmNode *winShmNodeList = 0; + +/* +** Structure used internally by this VFS to record the state of an +** open shared memory connection. +** +** The following fields are initialized when this object is created and +** are read-only thereafter: +** +** winShm.pShmNode +** winShm.id +** +** All other fields are read/write. The winShm.pShmNode->mutex must be held +** while accessing any read/write fields. +*/ +struct winShm { + winShmNode *pShmNode; /* The underlying winShmNode object */ + winShm *pNext; /* Next winShm with the same winShmNode */ + u8 hasMutex; /* True if holding the winShmNode mutex */ + u16 sharedMask; /* Mask of shared locks held */ + u16 exclMask; /* Mask of exclusive locks held */ +#ifdef SQLITE_DEBUG + u8 id; /* Id of this connection with its winShmNode */ +#endif +}; + +/* +** Constants used for locking +*/ +#define WIN_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */ +#define WIN_SHM_DMS (WIN_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */ + +/* +** Apply advisory locks for all n bytes beginning at ofst. +*/ +#define _SHM_UNLCK 1 +#define _SHM_RDLCK 2 +#define _SHM_WRLCK 3 +static int winShmSystemLock( + winShmNode *pFile, /* Apply locks to this open shared-memory segment */ + int lockType, /* _SHM_UNLCK, _SHM_RDLCK, or _SHM_WRLCK */ + int ofst, /* Offset to first byte to be locked/unlocked */ + int nByte /* Number of bytes to lock or unlock */ +){ + OVERLAPPED ovlp; + DWORD dwFlags; + int rc = 0; /* Result code form Lock/UnlockFileEx() */ + + /* Access to the winShmNode object is serialized by the caller */ + assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 ); + + /* Initialize the locking parameters */ + dwFlags = LOCKFILE_FAIL_IMMEDIATELY; + if( lockType == _SHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK; + + memset(&ovlp, 0, sizeof(OVERLAPPED)); + ovlp.Offset = ofst; + + /* Release/Acquire the system-level lock */ + if( lockType==_SHM_UNLCK ){ + rc = osUnlockFileEx(pFile->hFile.h, 0, nByte, 0, &ovlp); + }else{ + rc = osLockFileEx(pFile->hFile.h, dwFlags, 0, nByte, 0, &ovlp); + } + + if( rc!= 0 ){ + rc = SQLITE_OK; + }else{ + pFile->lastErrno = osGetLastError(); + rc = SQLITE_BUSY; + } + + OSTRACE(("SHM-LOCK %d %s %s 0x%08lx\n", + pFile->hFile.h, + rc==SQLITE_OK ? "ok" : "failed", + lockType==_SHM_UNLCK ? "UnlockFileEx" : "LockFileEx", + pFile->lastErrno)); + + return rc; +} + +/* Forward references to VFS methods */ +static int winOpen(sqlite3_vfs*,const char*,sqlite3_file*,int,int*); +static int winDelete(sqlite3_vfs *,const char*,int); + +/* +** Purge the winShmNodeList list of all entries with winShmNode.nRef==0. +** +** This is not a VFS shared-memory method; it is a utility function called +** by VFS shared-memory methods. +*/ +static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){ + winShmNode **pp; + winShmNode *p; + BOOL bRc; + assert( winShmMutexHeld() ); + pp = &winShmNodeList; + while( (p = *pp)!=0 ){ + if( p->nRef==0 ){ + int i; + if( p->mutex ) sqlite3_mutex_free(p->mutex); + for(i=0; inRegion; i++){ + bRc = osUnmapViewOfFile(p->aRegion[i].pMap); + OSTRACE(("SHM-PURGE pid-%d unmap region=%d %s\n", + (int)osGetCurrentProcessId(), i, + bRc ? "ok" : "failed")); + bRc = osCloseHandle(p->aRegion[i].hMap); + OSTRACE(("SHM-PURGE pid-%d close region=%d %s\n", + (int)osGetCurrentProcessId(), i, + bRc ? "ok" : "failed")); + } + if( p->hFile.h != INVALID_HANDLE_VALUE ){ + SimulateIOErrorBenign(1); + winClose((sqlite3_file *)&p->hFile); + SimulateIOErrorBenign(0); + } + if( deleteFlag ){ + SimulateIOErrorBenign(1); + sqlite3BeginBenignMalloc(); + winDelete(pVfs, p->zFilename, 0); + sqlite3EndBenignMalloc(); + SimulateIOErrorBenign(0); + } + *pp = p->pNext; + sqlite3_free(p->aRegion); + sqlite3_free(p); + }else{ + pp = &p->pNext; + } + } +} + +/* +** Open the shared-memory area associated with database file pDbFd. +** +** When opening a new shared-memory file, if no other instances of that +** file are currently open, in this process or in other processes, then +** the file must be truncated to zero length or have its header cleared. +*/ +static int winOpenSharedMemory(winFile *pDbFd){ + struct winShm *p; /* The connection to be opened */ + struct winShmNode *pShmNode = 0; /* The underlying mmapped file */ + int rc; /* Result code */ + struct winShmNode *pNew; /* Newly allocated winShmNode */ + int nName; /* Size of zName in bytes */ + + assert( pDbFd->pShm==0 ); /* Not previously opened */ + + /* Allocate space for the new sqlite3_shm object. Also speculatively + ** allocate space for a new winShmNode and filename. + */ + p = sqlite3_malloc( sizeof(*p) ); + if( p==0 ) return SQLITE_IOERR_NOMEM; + memset(p, 0, sizeof(*p)); + nName = sqlite3Strlen30(pDbFd->zPath); + pNew = sqlite3_malloc( sizeof(*pShmNode) + nName + 17 ); + if( pNew==0 ){ + sqlite3_free(p); + return SQLITE_IOERR_NOMEM; + } + memset(pNew, 0, sizeof(*pNew) + nName + 17); + pNew->zFilename = (char*)&pNew[1]; + sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath); + sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename); + + /* Look to see if there is an existing winShmNode that can be used. + ** If no matching winShmNode currently exists, create a new one. + */ + winShmEnterMutex(); + for(pShmNode = winShmNodeList; pShmNode; pShmNode=pShmNode->pNext){ + /* TBD need to come up with better match here. Perhaps + ** use FILE_ID_BOTH_DIR_INFO Structure. + */ + if( sqlite3StrICmp(pShmNode->zFilename, pNew->zFilename)==0 ) break; + } + if( pShmNode ){ + sqlite3_free(pNew); + }else{ + pShmNode = pNew; + pNew = 0; + ((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE; + pShmNode->pNext = winShmNodeList; + winShmNodeList = pShmNode; + + pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( pShmNode->mutex==0 ){ + rc = SQLITE_IOERR_NOMEM; + goto shm_open_err; + } + + rc = winOpen(pDbFd->pVfs, + pShmNode->zFilename, /* Name of the file (UTF-8) */ + (sqlite3_file*)&pShmNode->hFile, /* File handle here */ + SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, /* Mode flags */ + 0); + if( SQLITE_OK!=rc ){ + goto shm_open_err; + } + + /* Check to see if another process is holding the dead-man switch. + ** If not, truncate the file to zero length. + */ + if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){ + rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0); + if( rc!=SQLITE_OK ){ + rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(), + "winOpenShm", pDbFd->zPath); + } + } + if( rc==SQLITE_OK ){ + winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1); + rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1); + } + if( rc ) goto shm_open_err; + } + + /* Make the new connection a child of the winShmNode */ + p->pShmNode = pShmNode; +#ifdef SQLITE_DEBUG + p->id = pShmNode->nextShmId++; +#endif + pShmNode->nRef++; + pDbFd->pShm = p; + winShmLeaveMutex(); + + /* The reference count on pShmNode has already been incremented under + ** the cover of the winShmEnterMutex() mutex and the pointer from the + ** new (struct winShm) object to the pShmNode has been set. All that is + ** left to do is to link the new object into the linked list starting + ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex + ** mutex. + */ + sqlite3_mutex_enter(pShmNode->mutex); + p->pNext = pShmNode->pFirst; + pShmNode->pFirst = p; + sqlite3_mutex_leave(pShmNode->mutex); + return SQLITE_OK; + + /* Jump here on any error */ +shm_open_err: + winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1); + winShmPurge(pDbFd->pVfs, 0); /* This call frees pShmNode if required */ + sqlite3_free(p); + sqlite3_free(pNew); + winShmLeaveMutex(); + return rc; +} + +/* +** Close a connection to shared-memory. Delete the underlying +** storage if deleteFlag is true. +*/ +static int winShmUnmap( + sqlite3_file *fd, /* Database holding shared memory */ + int deleteFlag /* Delete after closing if true */ +){ + winFile *pDbFd; /* Database holding shared-memory */ + winShm *p; /* The connection to be closed */ + winShmNode *pShmNode; /* The underlying shared-memory file */ + winShm **pp; /* For looping over sibling connections */ + + pDbFd = (winFile*)fd; + p = pDbFd->pShm; + if( p==0 ) return SQLITE_OK; + pShmNode = p->pShmNode; + + /* Remove connection p from the set of connections associated + ** with pShmNode */ + sqlite3_mutex_enter(pShmNode->mutex); + for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){} + *pp = p->pNext; + + /* Free the connection p */ + sqlite3_free(p); + pDbFd->pShm = 0; + sqlite3_mutex_leave(pShmNode->mutex); + + /* If pShmNode->nRef has reached 0, then close the underlying + ** shared-memory file, too */ + winShmEnterMutex(); + assert( pShmNode->nRef>0 ); + pShmNode->nRef--; + if( pShmNode->nRef==0 ){ + winShmPurge(pDbFd->pVfs, deleteFlag); + } + winShmLeaveMutex(); + + return SQLITE_OK; +} + +/* +** Change the lock state for a shared-memory segment. +*/ +static int winShmLock( + sqlite3_file *fd, /* Database file holding the shared memory */ + int ofst, /* First lock to acquire or release */ + int n, /* Number of locks to acquire or release */ + int flags /* What to do with the lock */ +){ + winFile *pDbFd = (winFile*)fd; /* Connection holding shared memory */ + winShm *p = pDbFd->pShm; /* The shared memory being locked */ + winShm *pX; /* For looping over all siblings */ + winShmNode *pShmNode = p->pShmNode; + int rc = SQLITE_OK; /* Result code */ + u16 mask; /* Mask of locks to take or release */ + + assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK ); + assert( n>=1 ); + assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED) + || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE) + || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED) + || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) ); + assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); + + mask = (u16)((1U<<(ofst+n)) - (1U<1 || mask==(1<mutex); + if( flags & SQLITE_SHM_UNLOCK ){ + u16 allMask = 0; /* Mask of locks held by siblings */ + + /* See if any siblings hold this same lock */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( pX==p ) continue; + assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 ); + allMask |= pX->sharedMask; + } + + /* Unlock the system-level locks */ + if( (mask & allMask)==0 ){ + rc = winShmSystemLock(pShmNode, _SHM_UNLCK, ofst+WIN_SHM_BASE, n); + }else{ + rc = SQLITE_OK; + } + + /* Undo the local locks */ + if( rc==SQLITE_OK ){ + p->exclMask &= ~mask; + p->sharedMask &= ~mask; + } + }else if( flags & SQLITE_SHM_SHARED ){ + u16 allShared = 0; /* Union of locks held by connections other than "p" */ + + /* Find out which shared locks are already held by sibling connections. + ** If any sibling already holds an exclusive lock, go ahead and return + ** SQLITE_BUSY. + */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( (pX->exclMask & mask)!=0 ){ + rc = SQLITE_BUSY; + break; + } + allShared |= pX->sharedMask; + } + + /* Get shared locks at the system level, if necessary */ + if( rc==SQLITE_OK ){ + if( (allShared & mask)==0 ){ + rc = winShmSystemLock(pShmNode, _SHM_RDLCK, ofst+WIN_SHM_BASE, n); + }else{ + rc = SQLITE_OK; + } + } + + /* Get the local shared locks */ + if( rc==SQLITE_OK ){ + p->sharedMask |= mask; + } + }else{ + /* Make sure no sibling connections hold locks that will block this + ** lock. If any do, return SQLITE_BUSY right away. + */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){ + rc = SQLITE_BUSY; + break; + } + } + + /* Get the exclusive locks at the system level. Then if successful + ** also mark the local connection as being locked. + */ + if( rc==SQLITE_OK ){ + rc = winShmSystemLock(pShmNode, _SHM_WRLCK, ofst+WIN_SHM_BASE, n); + if( rc==SQLITE_OK ){ + assert( (p->sharedMask & mask)==0 ); + p->exclMask |= mask; + } + } + } + sqlite3_mutex_leave(pShmNode->mutex); + OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x %s\n", + p->id, (int)osGetCurrentProcessId(), p->sharedMask, p->exclMask, + rc ? "failed" : "ok")); + return rc; +} + +/* +** Implement a memory barrier or memory fence on shared memory. +** +** All loads and stores begun before the barrier must complete before +** any load or store begun after the barrier. +*/ +static void winShmBarrier( + sqlite3_file *fd /* Database holding the shared memory */ +){ + UNUSED_PARAMETER(fd); + /* MemoryBarrier(); // does not work -- do not know why not */ + winShmEnterMutex(); + winShmLeaveMutex(); +} + +/* +** This function is called to obtain a pointer to region iRegion of the +** shared-memory associated with the database file fd. Shared-memory regions +** are numbered starting from zero. Each shared-memory region is szRegion +** bytes in size. +** +** If an error occurs, an error code is returned and *pp is set to NULL. +** +** Otherwise, if the isWrite parameter is 0 and the requested shared-memory +** region has not been allocated (by any client, including one running in a +** separate process), then *pp is set to NULL and SQLITE_OK returned. If +** isWrite is non-zero and the requested shared-memory region has not yet +** been allocated, it is allocated by this function. +** +** If the shared-memory region has already been allocated or is allocated by +** this call as described above, then it is mapped into this processes +** address space (if it is not already), *pp is set to point to the mapped +** memory and SQLITE_OK returned. +*/ +static int winShmMap( + sqlite3_file *fd, /* Handle open on database file */ + int iRegion, /* Region to retrieve */ + int szRegion, /* Size of regions */ + int isWrite, /* True to extend file if necessary */ + void volatile **pp /* OUT: Mapped memory */ +){ + winFile *pDbFd = (winFile*)fd; + winShm *p = pDbFd->pShm; + winShmNode *pShmNode; + int rc = SQLITE_OK; + + if( !p ){ + rc = winOpenSharedMemory(pDbFd); + if( rc!=SQLITE_OK ) return rc; + p = pDbFd->pShm; + } + pShmNode = p->pShmNode; + + sqlite3_mutex_enter(pShmNode->mutex); + assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); + + if( pShmNode->nRegion<=iRegion ){ + struct ShmRegion *apNew; /* New aRegion[] array */ + int nByte = (iRegion+1)*szRegion; /* Minimum required file size */ + sqlite3_int64 sz; /* Current size of wal-index file */ + + pShmNode->szRegion = szRegion; + + /* The requested region is not mapped into this processes address space. + ** Check to see if it has been allocated (i.e. if the wal-index file is + ** large enough to contain the requested region). + */ + rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz); + if( rc!=SQLITE_OK ){ + rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), + "winShmMap1", pDbFd->zPath); + goto shmpage_out; + } + + if( szhFile, nByte); + if( rc!=SQLITE_OK ){ + rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), + "winShmMap2", pDbFd->zPath); + goto shmpage_out; + } + } + + /* Map the requested memory region into this processes address space. */ + apNew = (struct ShmRegion *)sqlite3_realloc( + pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0]) + ); + if( !apNew ){ + rc = SQLITE_IOERR_NOMEM; + goto shmpage_out; + } + pShmNode->aRegion = apNew; + + while( pShmNode->nRegion<=iRegion ){ + HANDLE hMap; /* file-mapping handle */ + void *pMap = 0; /* Mapped memory region */ + + hMap = osCreateFileMapping(pShmNode->hFile.h, + NULL, PAGE_READWRITE, 0, nByte, NULL + ); + OSTRACE(("SHM-MAP pid-%d create region=%d nbyte=%d %s\n", + (int)osGetCurrentProcessId(), pShmNode->nRegion, nByte, + hMap ? "ok" : "failed")); + if( hMap ){ + int iOffset = pShmNode->nRegion*szRegion; + int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; + pMap = osMapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ, + 0, iOffset - iOffsetShift, szRegion + iOffsetShift + ); + OSTRACE(("SHM-MAP pid-%d map region=%d offset=%d size=%d %s\n", + (int)osGetCurrentProcessId(), pShmNode->nRegion, iOffset, + szRegion, pMap ? "ok" : "failed")); + } + if( !pMap ){ + pShmNode->lastErrno = osGetLastError(); + rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno, + "winShmMap3", pDbFd->zPath); + if( hMap ) osCloseHandle(hMap); + goto shmpage_out; + } + + pShmNode->aRegion[pShmNode->nRegion].pMap = pMap; + pShmNode->aRegion[pShmNode->nRegion].hMap = hMap; + pShmNode->nRegion++; + } + } + +shmpage_out: + if( pShmNode->nRegion>iRegion ){ + int iOffset = iRegion*szRegion; + int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; + char *p = (char *)pShmNode->aRegion[iRegion].pMap; + *pp = (void *)&p[iOffsetShift]; + }else{ + *pp = 0; + } + sqlite3_mutex_leave(pShmNode->mutex); + return rc; +} + +#else +# define winShmMap 0 +# define winShmLock 0 +# define winShmBarrier 0 +# define winShmUnmap 0 +#endif /* #ifndef SQLITE_OMIT_WAL */ + +/* +** Here ends the implementation of all sqlite3_file methods. +** +********************** End sqlite3_file Methods ******************************* +******************************************************************************/ + +/* +** This vector defines all the methods that can operate on an +** sqlite3_file for win32. +*/ +static const sqlite3_io_methods winIoMethod = { + 2, /* iVersion */ + winClose, /* xClose */ + winRead, /* xRead */ + winWrite, /* xWrite */ + winTruncate, /* xTruncate */ + winSync, /* xSync */ + winFileSize, /* xFileSize */ + winLock, /* xLock */ + winUnlock, /* xUnlock */ + winCheckReservedLock, /* xCheckReservedLock */ + winFileControl, /* xFileControl */ + winSectorSize, /* xSectorSize */ + winDeviceCharacteristics, /* xDeviceCharacteristics */ + winShmMap, /* xShmMap */ + winShmLock, /* xShmLock */ + winShmBarrier, /* xShmBarrier */ + winShmUnmap /* xShmUnmap */ +}; + +/**************************************************************************** +**************************** sqlite3_vfs methods **************************** +** +** This division contains the implementation of methods on the +** sqlite3_vfs object. +*/ + +/* +** Convert a UTF-8 filename into whatever form the underlying +** operating system wants filenames in. Space to hold the result +** is obtained from malloc and must be freed by the calling +** function. +*/ +static void *convertUtf8Filename(const char *zFilename){ + void *zConverted = 0; + if( isNT() ){ + zConverted = utf8ToUnicode(zFilename); +/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. +*/ +#if SQLITE_OS_WINCE==0 + }else{ + zConverted = sqlite3_win32_utf8_to_mbcs(zFilename); +#endif + } + /* caller will handle out of memory */ + return zConverted; +} + +/* +** Create a temporary file name in zBuf. zBuf must be big enough to +** hold at pVfs->mxPathname characters. +*/ +static int getTempname(int nBuf, char *zBuf){ + static char zChars[] = + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789"; + size_t i, j; + char zTempPath[MAX_PATH+2]; + + /* It's odd to simulate an io-error here, but really this is just + ** using the io-error infrastructure to test that SQLite handles this + ** function failing. + */ + SimulateIOError( return SQLITE_IOERR ); + + if( sqlite3_temp_directory ){ + sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory); + }else if( isNT() ){ + char *zMulti; + WCHAR zWidePath[MAX_PATH]; + osGetTempPathW(MAX_PATH-30, zWidePath); + zMulti = unicodeToUtf8(zWidePath); + if( zMulti ){ + sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti); + sqlite3_free(zMulti); + }else{ + return SQLITE_IOERR_NOMEM; + } +/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. +** Since the ANSI version of these Windows API do not exist for WINCE, +** it's important to not reference them for WINCE builds. +*/ +#if SQLITE_OS_WINCE==0 + }else{ + char *zUtf8; + char zMbcsPath[MAX_PATH]; + osGetTempPathA(MAX_PATH-30, zMbcsPath); + zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath); + if( zUtf8 ){ + sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8); + sqlite3_free(zUtf8); + }else{ + return SQLITE_IOERR_NOMEM; + } +#endif + } + + /* Check that the output buffer is large enough for the temporary file + ** name. If it is not, return SQLITE_ERROR. + */ + if( (sqlite3Strlen30(zTempPath) + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){ + return SQLITE_ERROR; + } + + for(i=sqlite3Strlen30(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){} + zTempPath[i] = 0; + + sqlite3_snprintf(nBuf-18, zBuf, + "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath); + j = sqlite3Strlen30(zBuf); + sqlite3_randomness(15, &zBuf[j]); + for(i=0; i<15; i++, j++){ + zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; + } + zBuf[j] = 0; + zBuf[j+1] = 0; + + OSTRACE(("TEMP FILENAME: %s\n", zBuf)); + return SQLITE_OK; +} + +/* +** Open a file. +*/ +static int winOpen( + sqlite3_vfs *pVfs, /* Not used */ + const char *zName, /* Name of the file (UTF-8) */ + sqlite3_file *id, /* Write the SQLite file handle here */ + int flags, /* Open mode flags */ + int *pOutFlags /* Status return flags */ +){ + HANDLE h; + DWORD lastErrno; + DWORD dwDesiredAccess; + DWORD dwShareMode; + DWORD dwCreationDisposition; + DWORD dwFlagsAndAttributes = 0; +#if SQLITE_OS_WINCE + int isTemp = 0; +#endif + winFile *pFile = (winFile*)id; + void *zConverted; /* Filename in OS encoding */ + const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */ + int cnt = 0; + + /* If argument zPath is a NULL pointer, this function is required to open + ** a temporary file. Use this buffer to store the file name in. + */ + char zTmpname[MAX_PATH+2]; /* Buffer used to create temp filename */ + + int rc = SQLITE_OK; /* Function Return Code */ +#if !defined(NDEBUG) || SQLITE_OS_WINCE + int eType = flags&0xFFFFFF00; /* Type of file to open */ +#endif + + int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); + int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE); + int isCreate = (flags & SQLITE_OPEN_CREATE); +#ifndef NDEBUG + int isReadonly = (flags & SQLITE_OPEN_READONLY); +#endif + int isReadWrite = (flags & SQLITE_OPEN_READWRITE); + +#ifndef NDEBUG + int isOpenJournal = (isCreate && ( + eType==SQLITE_OPEN_MASTER_JOURNAL + || eType==SQLITE_OPEN_MAIN_JOURNAL + || eType==SQLITE_OPEN_WAL + )); +#endif + + /* Check the following statements are true: + ** + ** (a) Exactly one of the READWRITE and READONLY flags must be set, and + ** (b) if CREATE is set, then READWRITE must also be set, and + ** (c) if EXCLUSIVE is set, then CREATE must also be set. + ** (d) if DELETEONCLOSE is set, then CREATE must also be set. + */ + assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly)); + assert(isCreate==0 || isReadWrite); + assert(isExclusive==0 || isCreate); + assert(isDelete==0 || isCreate); + + /* The main DB, main journal, WAL file and master journal are never + ** automatically deleted. Nor are they ever temporary files. */ + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL ); + + /* Assert that the upper layer has set one of the "file-type" flags. */ + assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB + || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL + || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL + || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL + ); + + assert( id!=0 ); + UNUSED_PARAMETER(pVfs); + + pFile->h = INVALID_HANDLE_VALUE; + + /* If the second argument to this function is NULL, generate a + ** temporary file name to use + */ + if( !zUtf8Name ){ + assert(isDelete && !isOpenJournal); + rc = getTempname(MAX_PATH+2, zTmpname); + if( rc!=SQLITE_OK ){ + return rc; + } + zUtf8Name = zTmpname; + } + + /* Database filenames are double-zero terminated if they are not + ** URIs with parameters. Hence, they can always be passed into + ** sqlite3_uri_parameter(). + */ + assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) || + zUtf8Name[strlen(zUtf8Name)+1]==0 ); + + /* Convert the filename to the system encoding. */ + zConverted = convertUtf8Filename(zUtf8Name); + if( zConverted==0 ){ + return SQLITE_IOERR_NOMEM; + } + + if( isReadWrite ){ + dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; + }else{ + dwDesiredAccess = GENERIC_READ; + } + + /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is + ** created. SQLite doesn't use it to indicate "exclusive access" + ** as it is usually understood. + */ + if( isExclusive ){ + /* Creates a new file, only if it does not already exist. */ + /* If the file exists, it fails. */ + dwCreationDisposition = CREATE_NEW; + }else if( isCreate ){ + /* Open existing file, or create if it doesn't exist */ + dwCreationDisposition = OPEN_ALWAYS; + }else{ + /* Opens a file, only if it exists. */ + dwCreationDisposition = OPEN_EXISTING; + } + + dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; + + if( isDelete ){ +#if SQLITE_OS_WINCE + dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN; + isTemp = 1; +#else + dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY + | FILE_ATTRIBUTE_HIDDEN + | FILE_FLAG_DELETE_ON_CLOSE; +#endif + }else{ + dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; + } + /* Reports from the internet are that performance is always + ** better if FILE_FLAG_RANDOM_ACCESS is used. Ticket #2699. */ +#if SQLITE_OS_WINCE + dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; +#endif + + if( isNT() ){ + while( (h = osCreateFileW((LPCWSTR)zConverted, + dwDesiredAccess, + dwShareMode, NULL, + dwCreationDisposition, + dwFlagsAndAttributes, + NULL))==INVALID_HANDLE_VALUE && + retryIoerr(&cnt, &lastErrno) ){} +/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. +** Since the ANSI version of these Windows API do not exist for WINCE, +** it's important to not reference them for WINCE builds. +*/ +#if SQLITE_OS_WINCE==0 + }else{ + while( (h = osCreateFileA((LPCSTR)zConverted, + dwDesiredAccess, + dwShareMode, NULL, + dwCreationDisposition, + dwFlagsAndAttributes, + NULL))==INVALID_HANDLE_VALUE && + retryIoerr(&cnt, &lastErrno) ){} +#endif + } + + logIoerr(cnt); + + OSTRACE(("OPEN %d %s 0x%lx %s\n", + h, zName, dwDesiredAccess, + h==INVALID_HANDLE_VALUE ? "failed" : "ok")); + + if( h==INVALID_HANDLE_VALUE ){ + pFile->lastErrno = lastErrno; + winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name); + sqlite3_free(zConverted); + if( isReadWrite && !isExclusive ){ + return winOpen(pVfs, zName, id, + ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), pOutFlags); + }else{ + return SQLITE_CANTOPEN_BKPT; + } + } + + if( pOutFlags ){ + if( isReadWrite ){ + *pOutFlags = SQLITE_OPEN_READWRITE; + }else{ + *pOutFlags = SQLITE_OPEN_READONLY; + } + } + + memset(pFile, 0, sizeof(*pFile)); + pFile->pMethod = &winIoMethod; + pFile->h = h; + pFile->lastErrno = NO_ERROR; + pFile->pVfs = pVfs; + pFile->pShm = 0; + pFile->zPath = zName; + if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){ + pFile->ctrlFlags |= WINFILE_PSOW; + } + +#if SQLITE_OS_WINCE + if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB + && !winceCreateLock(zName, pFile) + ){ + osCloseHandle(h); + sqlite3_free(zConverted); + return SQLITE_CANTOPEN_BKPT; + } + if( isTemp ){ + pFile->zDeleteOnClose = zConverted; + }else +#endif + { + sqlite3_free(zConverted); + } + + OpenCounter(+1); + return rc; +} + +/* +** Delete the named file. +** +** Note that Windows does not allow a file to be deleted if some other +** process has it open. Sometimes a virus scanner or indexing program +** will open a journal file shortly after it is created in order to do +** whatever it does. While this other process is holding the +** file open, we will be unable to delete it. To work around this +** problem, we delay 100 milliseconds and try to delete again. Up +** to MX_DELETION_ATTEMPTs deletion attempts are run before giving +** up and returning an error. +*/ +static int winDelete( + sqlite3_vfs *pVfs, /* Not used on win32 */ + const char *zFilename, /* Name of file to delete */ + int syncDir /* Not used on win32 */ +){ + int cnt = 0; + int rc; + DWORD lastErrno; + void *zConverted; + UNUSED_PARAMETER(pVfs); + UNUSED_PARAMETER(syncDir); + + SimulateIOError(return SQLITE_IOERR_DELETE); + zConverted = convertUtf8Filename(zFilename); + if( zConverted==0 ){ + return SQLITE_IOERR_NOMEM; + } + if( isNT() ){ + rc = 1; + while( osGetFileAttributesW(zConverted)!=INVALID_FILE_ATTRIBUTES && + (rc = osDeleteFileW(zConverted))==0 && retryIoerr(&cnt, &lastErrno) ){} + rc = rc ? SQLITE_OK : SQLITE_ERROR; +/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. +** Since the ANSI version of these Windows API do not exist for WINCE, +** it's important to not reference them for WINCE builds. +*/ +#if SQLITE_OS_WINCE==0 + }else{ + rc = 1; + while( osGetFileAttributesA(zConverted)!=INVALID_FILE_ATTRIBUTES && + (rc = osDeleteFileA(zConverted))==0 && retryIoerr(&cnt, &lastErrno) ){} + rc = rc ? SQLITE_OK : SQLITE_ERROR; +#endif + } + if( rc ){ + rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, + "winDelete", zFilename); + }else{ + logIoerr(cnt); + } + sqlite3_free(zConverted); + OSTRACE(("DELETE \"%s\" %s\n", zFilename, (rc ? "failed" : "ok" ))); + return rc; +} + +/* +** Check the existance and status of a file. +*/ +static int winAccess( + sqlite3_vfs *pVfs, /* Not used on win32 */ + const char *zFilename, /* Name of file to check */ + int flags, /* Type of test to make on this file */ + int *pResOut /* OUT: Result */ +){ + DWORD attr; + int rc = 0; + DWORD lastErrno; + void *zConverted; + UNUSED_PARAMETER(pVfs); + + SimulateIOError( return SQLITE_IOERR_ACCESS; ); + zConverted = convertUtf8Filename(zFilename); + if( zConverted==0 ){ + return SQLITE_IOERR_NOMEM; + } + if( isNT() ){ + int cnt = 0; + WIN32_FILE_ATTRIBUTE_DATA sAttrData; + memset(&sAttrData, 0, sizeof(sAttrData)); + while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, + GetFileExInfoStandard, + &sAttrData)) && retryIoerr(&cnt, &lastErrno) ){} + if( rc ){ + /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file + ** as if it does not exist. + */ + if( flags==SQLITE_ACCESS_EXISTS + && sAttrData.nFileSizeHigh==0 + && sAttrData.nFileSizeLow==0 ){ + attr = INVALID_FILE_ATTRIBUTES; + }else{ + attr = sAttrData.dwFileAttributes; + } + }else{ + logIoerr(cnt); + if( lastErrno!=ERROR_FILE_NOT_FOUND ){ + winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename); + sqlite3_free(zConverted); + return SQLITE_IOERR_ACCESS; + }else{ + attr = INVALID_FILE_ATTRIBUTES; + } + } +/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. +** Since the ANSI version of these Windows API do not exist for WINCE, +** it's important to not reference them for WINCE builds. +*/ +#if SQLITE_OS_WINCE==0 + }else{ + attr = osGetFileAttributesA((char*)zConverted); +#endif + } + sqlite3_free(zConverted); + switch( flags ){ + case SQLITE_ACCESS_READ: + case SQLITE_ACCESS_EXISTS: + rc = attr!=INVALID_FILE_ATTRIBUTES; + break; + case SQLITE_ACCESS_READWRITE: + rc = attr!=INVALID_FILE_ATTRIBUTES && + (attr & FILE_ATTRIBUTE_READONLY)==0; + break; + default: + assert(!"Invalid flags argument"); + } + *pResOut = rc; + return SQLITE_OK; +} + + +/* +** Turn a relative pathname into a full pathname. Write the full +** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname +** bytes in size. +*/ +static int winFullPathname( + sqlite3_vfs *pVfs, /* Pointer to vfs object */ + const char *zRelative, /* Possibly relative input path */ + int nFull, /* Size of output buffer in bytes */ + char *zFull /* Output buffer */ +){ + +#if defined(__CYGWIN__) + SimulateIOError( return SQLITE_ERROR ); + UNUSED_PARAMETER(nFull); + cygwin_conv_to_full_win32_path(zRelative, zFull); + return SQLITE_OK; +#endif + +#if SQLITE_OS_WINCE + SimulateIOError( return SQLITE_ERROR ); + UNUSED_PARAMETER(nFull); + /* WinCE has no concept of a relative pathname, or so I am told. */ + sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative); + return SQLITE_OK; +#endif + +#if !SQLITE_OS_WINCE && !defined(__CYGWIN__) + int nByte; + void *zConverted; + char *zOut; + + /* If this path name begins with "/X:", where "X" is any alphabetic + ** character, discard the initial "/" from the pathname. + */ + if( zRelative[0]=='/' && sqlite3Isalpha(zRelative[1]) && zRelative[2]==':' ){ + zRelative++; + } + + /* It's odd to simulate an io-error here, but really this is just + ** using the io-error infrastructure to test that SQLite handles this + ** function failing. This function could fail if, for example, the + ** current working directory has been unlinked. + */ + SimulateIOError( return SQLITE_ERROR ); + UNUSED_PARAMETER(nFull); + zConverted = convertUtf8Filename(zRelative); + if( zConverted==0 ){ + return SQLITE_IOERR_NOMEM; + } + if( isNT() ){ + LPWSTR zTemp; + nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0) + 3; + zTemp = sqlite3_malloc( nByte*sizeof(zTemp[0]) ); + if( zTemp==0 ){ + sqlite3_free(zConverted); + return SQLITE_IOERR_NOMEM; + } + osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0); + sqlite3_free(zConverted); + zOut = unicodeToUtf8(zTemp); + sqlite3_free(zTemp); +/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. +** Since the ANSI version of these Windows API do not exist for WINCE, +** it's important to not reference them for WINCE builds. +*/ +#if SQLITE_OS_WINCE==0 + }else{ + char *zTemp; + nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0) + 3; + zTemp = sqlite3_malloc( nByte*sizeof(zTemp[0]) ); + if( zTemp==0 ){ + sqlite3_free(zConverted); + return SQLITE_IOERR_NOMEM; + } + osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0); + sqlite3_free(zConverted); + zOut = sqlite3_win32_mbcs_to_utf8(zTemp); + sqlite3_free(zTemp); +#endif + } + if( zOut ){ + sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zOut); + sqlite3_free(zOut); + return SQLITE_OK; + }else{ + return SQLITE_IOERR_NOMEM; + } +#endif +} + +#ifndef SQLITE_OMIT_LOAD_EXTENSION +/* +** Interfaces for opening a shared library, finding entry points +** within the shared library, and closing the shared library. +*/ +/* +** Interfaces for opening a shared library, finding entry points +** within the shared library, and closing the shared library. +*/ +static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ + HANDLE h; + void *zConverted = convertUtf8Filename(zFilename); + UNUSED_PARAMETER(pVfs); + if( zConverted==0 ){ + return 0; + } + if( isNT() ){ + h = osLoadLibraryW((LPCWSTR)zConverted); +/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. +** Since the ANSI version of these Windows API do not exist for WINCE, +** it's important to not reference them for WINCE builds. +*/ +#if SQLITE_OS_WINCE==0 + }else{ + h = osLoadLibraryA((char*)zConverted); +#endif + } + sqlite3_free(zConverted); + return (void*)h; +} +static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ + UNUSED_PARAMETER(pVfs); + getLastErrorMsg(osGetLastError(), nBuf, zBufOut); +} +static void (*winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){ + UNUSED_PARAMETER(pVfs); + return (void(*)(void))osGetProcAddressA((HANDLE)pHandle, zSymbol); +} +static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){ + UNUSED_PARAMETER(pVfs); + osFreeLibrary((HANDLE)pHandle); +} +#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */ + #define winDlOpen 0 + #define winDlError 0 + #define winDlSym 0 + #define winDlClose 0 +#endif + + +/* +** Write up to nBuf bytes of randomness into zBuf. +*/ +static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ + int n = 0; + UNUSED_PARAMETER(pVfs); +#if defined(SQLITE_TEST) + n = nBuf; + memset(zBuf, 0, nBuf); +#else + if( sizeof(SYSTEMTIME)<=nBuf-n ){ + SYSTEMTIME x; + osGetSystemTime(&x); + memcpy(&zBuf[n], &x, sizeof(x)); + n += sizeof(x); + } + if( sizeof(DWORD)<=nBuf-n ){ + DWORD pid = osGetCurrentProcessId(); + memcpy(&zBuf[n], &pid, sizeof(pid)); + n += sizeof(pid); + } + if( sizeof(DWORD)<=nBuf-n ){ + DWORD cnt = osGetTickCount(); + memcpy(&zBuf[n], &cnt, sizeof(cnt)); + n += sizeof(cnt); + } + if( sizeof(LARGE_INTEGER)<=nBuf-n ){ + LARGE_INTEGER i; + osQueryPerformanceCounter(&i); + memcpy(&zBuf[n], &i, sizeof(i)); + n += sizeof(i); + } +#endif + return n; +} + + +/* +** Sleep for a little while. Return the amount of time slept. +*/ +static int winSleep(sqlite3_vfs *pVfs, int microsec){ + osSleep((microsec+999)/1000); + UNUSED_PARAMETER(pVfs); + return ((microsec+999)/1000)*1000; +} + +/* +** The following variable, if set to a non-zero value, is interpreted as +** the number of seconds since 1970 and is used to set the result of +** sqlite3OsCurrentTime() during testing. +*/ +#ifdef SQLITE_TEST +int sqlite3_current_time = 0; /* Fake system time in seconds since 1970. */ +#endif + +/* +** Find the current time (in Universal Coordinated Time). Write into *piNow +** the current time and date as a Julian Day number times 86_400_000. In +** other words, write into *piNow the number of milliseconds since the Julian +** epoch of noon in Greenwich on November 24, 4714 B.C according to the +** proleptic Gregorian calendar. +** +** On success, return SQLITE_OK. Return SQLITE_ERROR if the time and date +** cannot be found. +*/ +static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){ + /* FILETIME structure is a 64-bit value representing the number of + 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). + */ + FILETIME ft; + static const sqlite3_int64 winFiletimeEpoch = 23058135*(sqlite3_int64)8640000; +#ifdef SQLITE_TEST + static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000; +#endif + /* 2^32 - to avoid use of LL and warnings in gcc */ + static const sqlite3_int64 max32BitValue = + (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 + (sqlite3_int64)294967296; + +#if SQLITE_OS_WINCE + SYSTEMTIME time; + osGetSystemTime(&time); + /* if SystemTimeToFileTime() fails, it returns zero. */ + if (!osSystemTimeToFileTime(&time,&ft)){ + return SQLITE_ERROR; + } +#else + osGetSystemTimeAsFileTime( &ft ); +#endif + + *piNow = winFiletimeEpoch + + ((((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) + + (sqlite3_int64)ft.dwLowDateTime)/(sqlite3_int64)10000; + +#ifdef SQLITE_TEST + if( sqlite3_current_time ){ + *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch; + } +#endif + UNUSED_PARAMETER(pVfs); + return SQLITE_OK; +} + +/* +** Find the current time (in Universal Coordinated Time). Write the +** current time and date as a Julian Day number into *prNow and +** return 0. Return 1 if the time and date cannot be found. +*/ +static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){ + int rc; + sqlite3_int64 i; + rc = winCurrentTimeInt64(pVfs, &i); + if( !rc ){ + *prNow = i/86400000.0; + } + return rc; +} + +/* +** The idea is that this function works like a combination of +** GetLastError() and FormatMessage() on Windows (or errno and +** strerror_r() on Unix). After an error is returned by an OS +** function, SQLite calls this function with zBuf pointing to +** a buffer of nBuf bytes. The OS layer should populate the +** buffer with a nul-terminated UTF-8 encoded error message +** describing the last IO error to have occurred within the calling +** thread. +** +** If the error message is too large for the supplied buffer, +** it should be truncated. The return value of xGetLastError +** is zero if the error message fits in the buffer, or non-zero +** otherwise (if the message was truncated). If non-zero is returned, +** then it is not necessary to include the nul-terminator character +** in the output buffer. +** +** Not supplying an error message will have no adverse effect +** on SQLite. It is fine to have an implementation that never +** returns an error message: +** +** int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ +** assert(zBuf[0]=='\0'); +** return 0; +** } +** +** However if an error message is supplied, it will be incorporated +** by sqlite into the error message available to the user using +** sqlite3_errmsg(), possibly making IO errors easier to debug. +*/ +static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ + UNUSED_PARAMETER(pVfs); + return getLastErrorMsg(osGetLastError(), nBuf, zBuf); +} + +/* +** Initialize and deinitialize the operating system interface. +*/ +int sqlite3_os_init(void){ + static sqlite3_vfs winVfs = { + 3, /* iVersion */ + sizeof(winFile), /* szOsFile */ + MAX_PATH, /* mxPathname */ + 0, /* pNext */ + "win32", /* zName */ + 0, /* pAppData */ + winOpen, /* xOpen */ + winDelete, /* xDelete */ + winAccess, /* xAccess */ + winFullPathname, /* xFullPathname */ + winDlOpen, /* xDlOpen */ + winDlError, /* xDlError */ + winDlSym, /* xDlSym */ + winDlClose, /* xDlClose */ + winRandomness, /* xRandomness */ + winSleep, /* xSleep */ + winCurrentTime, /* xCurrentTime */ + winGetLastError, /* xGetLastError */ + winCurrentTimeInt64, /* xCurrentTimeInt64 */ + winSetSystemCall, /* xSetSystemCall */ + winGetSystemCall, /* xGetSystemCall */ + winNextSystemCall, /* xNextSystemCall */ + }; + + /* Double-check that the aSyscall[] array has been constructed + ** correctly. See ticket [bb3a86e890c8e96ab] */ + assert( ArraySize(aSyscall)==60 ); + +#ifndef SQLITE_OMIT_WAL + /* get memory map allocation granularity */ + memset(&winSysInfo, 0, sizeof(SYSTEM_INFO)); + osGetSystemInfo(&winSysInfo); + assert(winSysInfo.dwAllocationGranularity > 0); +#endif + + sqlite3_vfs_register(&winVfs, 1); + return SQLITE_OK; +} + +int sqlite3_os_end(void){ + return SQLITE_OK; +} + +#endif /* SQLITE_OS_WIN */ diff --git a/scalos/libraries/sqlite/src/pager.c b/scalos/libraries/sqlite/src/pager.c new file mode 100644 index 000000000..6f3b65166 --- /dev/null +++ b/scalos/libraries/sqlite/src/pager.c @@ -0,0 +1,6897 @@ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This is the implementation of the page cache subsystem or "pager". +** +** The pager is used to access a database disk file. It implements +** atomic commit and rollback through the use of a journal file that +** is separate from the database file. The pager also implements file +** locking to prevent two processes from writing the same database +** file simultaneously, or one process from reading the database while +** another is writing. +*/ +#ifndef SQLITE_OMIT_DISKIO +#include "sqliteInt.h" +#include "wal.h" + + +/******************* NOTES ON THE DESIGN OF THE PAGER ************************ +** +** This comment block describes invariants that hold when using a rollback +** journal. These invariants do not apply for journal_mode=WAL, +** journal_mode=MEMORY, or journal_mode=OFF. +** +** Within this comment block, a page is deemed to have been synced +** automatically as soon as it is written when PRAGMA synchronous=OFF. +** Otherwise, the page is not synced until the xSync method of the VFS +** is called successfully on the file containing the page. +** +** Definition: A page of the database file is said to be "overwriteable" if +** one or more of the following are true about the page: +** +** (a) The original content of the page as it was at the beginning of +** the transaction has been written into the rollback journal and +** synced. +** +** (b) The page was a freelist leaf page at the start of the transaction. +** +** (c) The page number is greater than the largest page that existed in +** the database file at the start of the transaction. +** +** (1) A page of the database file is never overwritten unless one of the +** following are true: +** +** (a) The page and all other pages on the same sector are overwriteable. +** +** (b) The atomic page write optimization is enabled, and the entire +** transaction other than the update of the transaction sequence +** number consists of a single page change. +** +** (2) The content of a page written into the rollback journal exactly matches +** both the content in the database when the rollback journal was written +** and the content in the database at the beginning of the current +** transaction. +** +** (3) Writes to the database file are an integer multiple of the page size +** in length and are aligned on a page boundary. +** +** (4) Reads from the database file are either aligned on a page boundary and +** an integer multiple of the page size in length or are taken from the +** first 100 bytes of the database file. +** +** (5) All writes to the database file are synced prior to the rollback journal +** being deleted, truncated, or zeroed. +** +** (6) If a master journal file is used, then all writes to the database file +** are synced prior to the master journal being deleted. +** +** Definition: Two databases (or the same database at two points it time) +** are said to be "logically equivalent" if they give the same answer to +** all queries. Note in particular the the content of freelist leaf +** pages can be changed arbitarily without effecting the logical equivalence +** of the database. +** +** (7) At any time, if any subset, including the empty set and the total set, +** of the unsynced changes to a rollback journal are removed and the +** journal is rolled back, the resulting database file will be logical +** equivalent to the database file at the beginning of the transaction. +** +** (8) When a transaction is rolled back, the xTruncate method of the VFS +** is called to restore the database file to the same size it was at +** the beginning of the transaction. (In some VFSes, the xTruncate +** method is a no-op, but that does not change the fact the SQLite will +** invoke it.) +** +** (9) Whenever the database file is modified, at least one bit in the range +** of bytes from 24 through 39 inclusive will be changed prior to releasing +** the EXCLUSIVE lock, thus signaling other connections on the same +** database to flush their caches. +** +** (10) The pattern of bits in bytes 24 through 39 shall not repeat in less +** than one billion transactions. +** +** (11) A database file is well-formed at the beginning and at the conclusion +** of every transaction. +** +** (12) An EXCLUSIVE lock is held on the database file when writing to +** the database file. +** +** (13) A SHARED lock is held on the database file while reading any +** content out of the database file. +** +******************************************************************************/ + +/* +** Macros for troubleshooting. Normally turned off +*/ +#if 0 +int sqlite3PagerTrace=1; /* True to enable tracing */ +#define sqlite3DebugPrintf printf +#define PAGERTRACE(X) if( sqlite3PagerTrace ){ sqlite3DebugPrintf X; } +#else +#define PAGERTRACE(X) +#endif + +/* +** The following two macros are used within the PAGERTRACE() macros above +** to print out file-descriptors. +** +** PAGERID() takes a pointer to a Pager struct as its argument. The +** associated file-descriptor is returned. FILEHANDLEID() takes an sqlite3_file +** struct as its argument. +*/ +#define PAGERID(p) ((int)(p->fd)) +#define FILEHANDLEID(fd) ((int)fd) + +/* +** The Pager.eState variable stores the current 'state' of a pager. A +** pager may be in any one of the seven states shown in the following +** state diagram. +** +** OPEN <------+------+ +** | | | +** V | | +** +---------> READER-------+ | +** | | | +** | V | +** |<-------WRITER_LOCKED------> ERROR +** | | ^ +** | V | +** |<------WRITER_CACHEMOD-------->| +** | | | +** | V | +** |<-------WRITER_DBMOD---------->| +** | | | +** | V | +** +<------WRITER_FINISHED-------->+ +** +** +** List of state transitions and the C [function] that performs each: +** +** OPEN -> READER [sqlite3PagerSharedLock] +** READER -> OPEN [pager_unlock] +** +** READER -> WRITER_LOCKED [sqlite3PagerBegin] +** WRITER_LOCKED -> WRITER_CACHEMOD [pager_open_journal] +** WRITER_CACHEMOD -> WRITER_DBMOD [syncJournal] +** WRITER_DBMOD -> WRITER_FINISHED [sqlite3PagerCommitPhaseOne] +** WRITER_*** -> READER [pager_end_transaction] +** +** WRITER_*** -> ERROR [pager_error] +** ERROR -> OPEN [pager_unlock] +** +** +** OPEN: +** +** The pager starts up in this state. Nothing is guaranteed in this +** state - the file may or may not be locked and the database size is +** unknown. The database may not be read or written. +** +** * No read or write transaction is active. +** * Any lock, or no lock at all, may be held on the database file. +** * The dbSize, dbOrigSize and dbFileSize variables may not be trusted. +** +** READER: +** +** In this state all the requirements for reading the database in +** rollback (non-WAL) mode are met. Unless the pager is (or recently +** was) in exclusive-locking mode, a user-level read transaction is +** open. The database size is known in this state. +** +** A connection running with locking_mode=normal enters this state when +** it opens a read-transaction on the database and returns to state +** OPEN after the read-transaction is completed. However a connection +** running in locking_mode=exclusive (including temp databases) remains in +** this state even after the read-transaction is closed. The only way +** a locking_mode=exclusive connection can transition from READER to OPEN +** is via the ERROR state (see below). +** +** * A read transaction may be active (but a write-transaction cannot). +** * A SHARED or greater lock is held on the database file. +** * The dbSize variable may be trusted (even if a user-level read +** transaction is not active). The dbOrigSize and dbFileSize variables +** may not be trusted at this point. +** * If the database is a WAL database, then the WAL connection is open. +** * Even if a read-transaction is not open, it is guaranteed that +** there is no hot-journal in the file-system. +** +** WRITER_LOCKED: +** +** The pager moves to this state from READER when a write-transaction +** is first opened on the database. In WRITER_LOCKED state, all locks +** required to start a write-transaction are held, but no actual +** modifications to the cache or database have taken place. +** +** In rollback mode, a RESERVED or (if the transaction was opened with +** BEGIN EXCLUSIVE) EXCLUSIVE lock is obtained on the database file when +** moving to this state, but the journal file is not written to or opened +** to in this state. If the transaction is committed or rolled back while +** in WRITER_LOCKED state, all that is required is to unlock the database +** file. +** +** IN WAL mode, WalBeginWriteTransaction() is called to lock the log file. +** If the connection is running with locking_mode=exclusive, an attempt +** is made to obtain an EXCLUSIVE lock on the database file. +** +** * A write transaction is active. +** * If the connection is open in rollback-mode, a RESERVED or greater +** lock is held on the database file. +** * If the connection is open in WAL-mode, a WAL write transaction +** is open (i.e. sqlite3WalBeginWriteTransaction() has been successfully +** called). +** * The dbSize, dbOrigSize and dbFileSize variables are all valid. +** * The contents of the pager cache have not been modified. +** * The journal file may or may not be open. +** * Nothing (not even the first header) has been written to the journal. +** +** WRITER_CACHEMOD: +** +** A pager moves from WRITER_LOCKED state to this state when a page is +** first modified by the upper layer. In rollback mode the journal file +** is opened (if it is not already open) and a header written to the +** start of it. The database file on disk has not been modified. +** +** * A write transaction is active. +** * A RESERVED or greater lock is held on the database file. +** * The journal file is open and the first header has been written +** to it, but the header has not been synced to disk. +** * The contents of the page cache have been modified. +** +** WRITER_DBMOD: +** +** The pager transitions from WRITER_CACHEMOD into WRITER_DBMOD state +** when it modifies the contents of the database file. WAL connections +** never enter this state (since they do not modify the database file, +** just the log file). +** +** * A write transaction is active. +** * An EXCLUSIVE or greater lock is held on the database file. +** * The journal file is open and the first header has been written +** and synced to disk. +** * The contents of the page cache have been modified (and possibly +** written to disk). +** +** WRITER_FINISHED: +** +** It is not possible for a WAL connection to enter this state. +** +** A rollback-mode pager changes to WRITER_FINISHED state from WRITER_DBMOD +** state after the entire transaction has been successfully written into the +** database file. In this state the transaction may be committed simply +** by finalizing the journal file. Once in WRITER_FINISHED state, it is +** not possible to modify the database further. At this point, the upper +** layer must either commit or rollback the transaction. +** +** * A write transaction is active. +** * An EXCLUSIVE or greater lock is held on the database file. +** * All writing and syncing of journal and database data has finished. +** If no error occured, all that remains is to finalize the journal to +** commit the transaction. If an error did occur, the caller will need +** to rollback the transaction. +** +** ERROR: +** +** The ERROR state is entered when an IO or disk-full error (including +** SQLITE_IOERR_NOMEM) occurs at a point in the code that makes it +** difficult to be sure that the in-memory pager state (cache contents, +** db size etc.) are consistent with the contents of the file-system. +** +** Temporary pager files may enter the ERROR state, but in-memory pagers +** cannot. +** +** For example, if an IO error occurs while performing a rollback, +** the contents of the page-cache may be left in an inconsistent state. +** At this point it would be dangerous to change back to READER state +** (as usually happens after a rollback). Any subsequent readers might +** report database corruption (due to the inconsistent cache), and if +** they upgrade to writers, they may inadvertently corrupt the database +** file. To avoid this hazard, the pager switches into the ERROR state +** instead of READER following such an error. +** +** Once it has entered the ERROR state, any attempt to use the pager +** to read or write data returns an error. Eventually, once all +** outstanding transactions have been abandoned, the pager is able to +** transition back to OPEN state, discarding the contents of the +** page-cache and any other in-memory state at the same time. Everything +** is reloaded from disk (and, if necessary, hot-journal rollback peformed) +** when a read-transaction is next opened on the pager (transitioning +** the pager into READER state). At that point the system has recovered +** from the error. +** +** Specifically, the pager jumps into the ERROR state if: +** +** 1. An error occurs while attempting a rollback. This happens in +** function sqlite3PagerRollback(). +** +** 2. An error occurs while attempting to finalize a journal file +** following a commit in function sqlite3PagerCommitPhaseTwo(). +** +** 3. An error occurs while attempting to write to the journal or +** database file in function pagerStress() in order to free up +** memory. +** +** In other cases, the error is returned to the b-tree layer. The b-tree +** layer then attempts a rollback operation. If the error condition +** persists, the pager enters the ERROR state via condition (1) above. +** +** Condition (3) is necessary because it can be triggered by a read-only +** statement executed within a transaction. In this case, if the error +** code were simply returned to the user, the b-tree layer would not +** automatically attempt a rollback, as it assumes that an error in a +** read-only statement cannot leave the pager in an internally inconsistent +** state. +** +** * The Pager.errCode variable is set to something other than SQLITE_OK. +** * There are one or more outstanding references to pages (after the +** last reference is dropped the pager should move back to OPEN state). +** * The pager is not an in-memory pager. +** +** +** Notes: +** +** * A pager is never in WRITER_DBMOD or WRITER_FINISHED state if the +** connection is open in WAL mode. A WAL connection is always in one +** of the first four states. +** +** * Normally, a connection open in exclusive mode is never in PAGER_OPEN +** state. There are two exceptions: immediately after exclusive-mode has +** been turned on (and before any read or write transactions are +** executed), and when the pager is leaving the "error state". +** +** * See also: assert_pager_state(). +*/ +#define PAGER_OPEN 0 +#define PAGER_READER 1 +#define PAGER_WRITER_LOCKED 2 +#define PAGER_WRITER_CACHEMOD 3 +#define PAGER_WRITER_DBMOD 4 +#define PAGER_WRITER_FINISHED 5 +#define PAGER_ERROR 6 + +/* +** The Pager.eLock variable is almost always set to one of the +** following locking-states, according to the lock currently held on +** the database file: NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK. +** This variable is kept up to date as locks are taken and released by +** the pagerLockDb() and pagerUnlockDb() wrappers. +** +** If the VFS xLock() or xUnlock() returns an error other than SQLITE_BUSY +** (i.e. one of the SQLITE_IOERR subtypes), it is not clear whether or not +** the operation was successful. In these circumstances pagerLockDb() and +** pagerUnlockDb() take a conservative approach - eLock is always updated +** when unlocking the file, and only updated when locking the file if the +** VFS call is successful. This way, the Pager.eLock variable may be set +** to a less exclusive (lower) value than the lock that is actually held +** at the system level, but it is never set to a more exclusive value. +** +** This is usually safe. If an xUnlock fails or appears to fail, there may +** be a few redundant xLock() calls or a lock may be held for longer than +** required, but nothing really goes wrong. +** +** The exception is when the database file is unlocked as the pager moves +** from ERROR to OPEN state. At this point there may be a hot-journal file +** in the file-system that needs to be rolled back (as part of a OPEN->SHARED +** transition, by the same pager or any other). If the call to xUnlock() +** fails at this point and the pager is left holding an EXCLUSIVE lock, this +** can confuse the call to xCheckReservedLock() call made later as part +** of hot-journal detection. +** +** xCheckReservedLock() is defined as returning true "if there is a RESERVED +** lock held by this process or any others". So xCheckReservedLock may +** return true because the caller itself is holding an EXCLUSIVE lock (but +** doesn't know it because of a previous error in xUnlock). If this happens +** a hot-journal may be mistaken for a journal being created by an active +** transaction in another process, causing SQLite to read from the database +** without rolling it back. +** +** To work around this, if a call to xUnlock() fails when unlocking the +** database in the ERROR state, Pager.eLock is set to UNKNOWN_LOCK. It +** is only changed back to a real locking state after a successful call +** to xLock(EXCLUSIVE). Also, the code to do the OPEN->SHARED state transition +** omits the check for a hot-journal if Pager.eLock is set to UNKNOWN_LOCK +** lock. Instead, it assumes a hot-journal exists and obtains an EXCLUSIVE +** lock on the database file before attempting to roll it back. See function +** PagerSharedLock() for more detail. +** +** Pager.eLock may only be set to UNKNOWN_LOCK when the pager is in +** PAGER_OPEN state. +*/ +#define UNKNOWN_LOCK (EXCLUSIVE_LOCK+1) + +/* +** A macro used for invoking the codec if there is one +*/ +#ifdef SQLITE_HAS_CODEC +# define CODEC1(P,D,N,X,E) \ + if( P->xCodec && P->xCodec(P->pCodec,D,N,X)==0 ){ E; } +# define CODEC2(P,D,N,X,E,O) \ + if( P->xCodec==0 ){ O=(char*)D; }else \ + if( (O=(char*)(P->xCodec(P->pCodec,D,N,X)))==0 ){ E; } +#else +# define CODEC1(P,D,N,X,E) /* NO-OP */ +# define CODEC2(P,D,N,X,E,O) O=(char*)D +#endif + +/* +** The maximum allowed sector size. 64KiB. If the xSectorsize() method +** returns a value larger than this, then MAX_SECTOR_SIZE is used instead. +** This could conceivably cause corruption following a power failure on +** such a system. This is currently an undocumented limit. +*/ +#define MAX_SECTOR_SIZE 0x10000 + +/* +** An instance of the following structure is allocated for each active +** savepoint and statement transaction in the system. All such structures +** are stored in the Pager.aSavepoint[] array, which is allocated and +** resized using sqlite3Realloc(). +** +** When a savepoint is created, the PagerSavepoint.iHdrOffset field is +** set to 0. If a journal-header is written into the main journal while +** the savepoint is active, then iHdrOffset is set to the byte offset +** immediately following the last journal record written into the main +** journal before the journal-header. This is required during savepoint +** rollback (see pagerPlaybackSavepoint()). +*/ +typedef struct PagerSavepoint PagerSavepoint; +struct PagerSavepoint { + i64 iOffset; /* Starting offset in main journal */ + i64 iHdrOffset; /* See above */ + Bitvec *pInSavepoint; /* Set of pages in this savepoint */ + Pgno nOrig; /* Original number of pages in file */ + Pgno iSubRec; /* Index of first record in sub-journal */ +#ifndef SQLITE_OMIT_WAL + u32 aWalData[WAL_SAVEPOINT_NDATA]; /* WAL savepoint context */ +#endif +}; + +/* +** A open page cache is an instance of struct Pager. A description of +** some of the more important member variables follows: +** +** eState +** +** The current 'state' of the pager object. See the comment and state +** diagram above for a description of the pager state. +** +** eLock +** +** For a real on-disk database, the current lock held on the database file - +** NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK. +** +** For a temporary or in-memory database (neither of which require any +** locks), this variable is always set to EXCLUSIVE_LOCK. Since such +** databases always have Pager.exclusiveMode==1, this tricks the pager +** logic into thinking that it already has all the locks it will ever +** need (and no reason to release them). +** +** In some (obscure) circumstances, this variable may also be set to +** UNKNOWN_LOCK. See the comment above the #define of UNKNOWN_LOCK for +** details. +** +** changeCountDone +** +** This boolean variable is used to make sure that the change-counter +** (the 4-byte header field at byte offset 24 of the database file) is +** not updated more often than necessary. +** +** It is set to true when the change-counter field is updated, which +** can only happen if an exclusive lock is held on the database file. +** It is cleared (set to false) whenever an exclusive lock is +** relinquished on the database file. Each time a transaction is committed, +** The changeCountDone flag is inspected. If it is true, the work of +** updating the change-counter is omitted for the current transaction. +** +** This mechanism means that when running in exclusive mode, a connection +** need only update the change-counter once, for the first transaction +** committed. +** +** setMaster +** +** When PagerCommitPhaseOne() is called to commit a transaction, it may +** (or may not) specify a master-journal name to be written into the +** journal file before it is synced to disk. +** +** Whether or not a journal file contains a master-journal pointer affects +** the way in which the journal file is finalized after the transaction is +** committed or rolled back when running in "journal_mode=PERSIST" mode. +** If a journal file does not contain a master-journal pointer, it is +** finalized by overwriting the first journal header with zeroes. If +** it does contain a master-journal pointer the journal file is finalized +** by truncating it to zero bytes, just as if the connection were +** running in "journal_mode=truncate" mode. +** +** Journal files that contain master journal pointers cannot be finalized +** simply by overwriting the first journal-header with zeroes, as the +** master journal pointer could interfere with hot-journal rollback of any +** subsequently interrupted transaction that reuses the journal file. +** +** The flag is cleared as soon as the journal file is finalized (either +** by PagerCommitPhaseTwo or PagerRollback). If an IO error prevents the +** journal file from being successfully finalized, the setMaster flag +** is cleared anyway (and the pager will move to ERROR state). +** +** doNotSpill, doNotSyncSpill +** +** These two boolean variables control the behaviour of cache-spills +** (calls made by the pcache module to the pagerStress() routine to +** write cached data to the file-system in order to free up memory). +** +** When doNotSpill is non-zero, writing to the database from pagerStress() +** is disabled altogether. This is done in a very obscure case that +** comes up during savepoint rollback that requires the pcache module +** to allocate a new page to prevent the journal file from being written +** while it is being traversed by code in pager_playback(). +** +** If doNotSyncSpill is non-zero, writing to the database from pagerStress() +** is permitted, but syncing the journal file is not. This flag is set +** by sqlite3PagerWrite() when the file-system sector-size is larger than +** the database page-size in order to prevent a journal sync from happening +** in between the journalling of two pages on the same sector. +** +** subjInMemory +** +** This is a boolean variable. If true, then any required sub-journal +** is opened as an in-memory journal file. If false, then in-memory +** sub-journals are only used for in-memory pager files. +** +** This variable is updated by the upper layer each time a new +** write-transaction is opened. +** +** dbSize, dbOrigSize, dbFileSize +** +** Variable dbSize is set to the number of pages in the database file. +** It is valid in PAGER_READER and higher states (all states except for +** OPEN and ERROR). +** +** dbSize is set based on the size of the database file, which may be +** larger than the size of the database (the value stored at offset +** 28 of the database header by the btree). If the size of the file +** is not an integer multiple of the page-size, the value stored in +** dbSize is rounded down (i.e. a 5KB file with 2K page-size has dbSize==2). +** Except, any file that is greater than 0 bytes in size is considered +** to have at least one page. (i.e. a 1KB file with 2K page-size leads +** to dbSize==1). +** +** During a write-transaction, if pages with page-numbers greater than +** dbSize are modified in the cache, dbSize is updated accordingly. +** Similarly, if the database is truncated using PagerTruncateImage(), +** dbSize is updated. +** +** Variables dbOrigSize and dbFileSize are valid in states +** PAGER_WRITER_LOCKED and higher. dbOrigSize is a copy of the dbSize +** variable at the start of the transaction. It is used during rollback, +** and to determine whether or not pages need to be journalled before +** being modified. +** +** Throughout a write-transaction, dbFileSize contains the size of +** the file on disk in pages. It is set to a copy of dbSize when the +** write-transaction is first opened, and updated when VFS calls are made +** to write or truncate the database file on disk. +** +** The only reason the dbFileSize variable is required is to suppress +** unnecessary calls to xTruncate() after committing a transaction. If, +** when a transaction is committed, the dbFileSize variable indicates +** that the database file is larger than the database image (Pager.dbSize), +** pager_truncate() is called. The pager_truncate() call uses xFilesize() +** to measure the database file on disk, and then truncates it if required. +** dbFileSize is not used when rolling back a transaction. In this case +** pager_truncate() is called unconditionally (which means there may be +** a call to xFilesize() that is not strictly required). In either case, +** pager_truncate() may cause the file to become smaller or larger. +** +** dbHintSize +** +** The dbHintSize variable is used to limit the number of calls made to +** the VFS xFileControl(FCNTL_SIZE_HINT) method. +** +** dbHintSize is set to a copy of the dbSize variable when a +** write-transaction is opened (at the same time as dbFileSize and +** dbOrigSize). If the xFileControl(FCNTL_SIZE_HINT) method is called, +** dbHintSize is increased to the number of pages that correspond to the +** size-hint passed to the method call. See pager_write_pagelist() for +** details. +** +** errCode +** +** The Pager.errCode variable is only ever used in PAGER_ERROR state. It +** is set to zero in all other states. In PAGER_ERROR state, Pager.errCode +** is always set to SQLITE_FULL, SQLITE_IOERR or one of the SQLITE_IOERR_XXX +** sub-codes. +*/ +struct Pager { + sqlite3_vfs *pVfs; /* OS functions to use for IO */ + u8 exclusiveMode; /* Boolean. True if locking_mode==EXCLUSIVE */ + u8 journalMode; /* One of the PAGER_JOURNALMODE_* values */ + u8 useJournal; /* Use a rollback journal on this file */ + u8 noReadlock; /* Do not bother to obtain readlocks */ + u8 noSync; /* Do not sync the journal if true */ + u8 fullSync; /* Do extra syncs of the journal for robustness */ + u8 ckptSyncFlags; /* SYNC_NORMAL or SYNC_FULL for checkpoint */ + u8 walSyncFlags; /* SYNC_NORMAL or SYNC_FULL for wal writes */ + u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ + u8 tempFile; /* zFilename is a temporary file */ + u8 readOnly; /* True for a read-only database */ + u8 memDb; /* True to inhibit all file I/O */ + + /************************************************************************** + ** The following block contains those class members that change during + ** routine opertion. Class members not in this block are either fixed + ** when the pager is first created or else only change when there is a + ** significant mode change (such as changing the page_size, locking_mode, + ** or the journal_mode). From another view, these class members describe + ** the "state" of the pager, while other class members describe the + ** "configuration" of the pager. + */ + u8 eState; /* Pager state (OPEN, READER, WRITER_LOCKED..) */ + u8 eLock; /* Current lock held on database file */ + u8 changeCountDone; /* Set after incrementing the change-counter */ + u8 setMaster; /* True if a m-j name has been written to jrnl */ + u8 doNotSpill; /* Do not spill the cache when non-zero */ + u8 doNotSyncSpill; /* Do not do a spill that requires jrnl sync */ + u8 subjInMemory; /* True to use in-memory sub-journals */ + Pgno dbSize; /* Number of pages in the database */ + Pgno dbOrigSize; /* dbSize before the current transaction */ + Pgno dbFileSize; /* Number of pages in the database file */ + Pgno dbHintSize; /* Value passed to FCNTL_SIZE_HINT call */ + int errCode; /* One of several kinds of errors */ + int nRec; /* Pages journalled since last j-header written */ + u32 cksumInit; /* Quasi-random value added to every checksum */ + u32 nSubRec; /* Number of records written to sub-journal */ + Bitvec *pInJournal; /* One bit for each page in the database file */ + sqlite3_file *fd; /* File descriptor for database */ + sqlite3_file *jfd; /* File descriptor for main journal */ + sqlite3_file *sjfd; /* File descriptor for sub-journal */ + i64 journalOff; /* Current write offset in the journal file */ + i64 journalHdr; /* Byte offset to previous journal header */ + sqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */ + PagerSavepoint *aSavepoint; /* Array of active savepoints */ + int nSavepoint; /* Number of elements in aSavepoint[] */ + char dbFileVers[16]; /* Changes whenever database file changes */ + /* + ** End of the routinely-changing class members + ***************************************************************************/ + + u16 nExtra; /* Add this many bytes to each in-memory page */ + i16 nReserve; /* Number of unused bytes at end of each page */ + u32 vfsFlags; /* Flags for sqlite3_vfs.xOpen() */ + u32 sectorSize; /* Assumed sector size during rollback */ + int pageSize; /* Number of bytes in a page */ + Pgno mxPgno; /* Maximum allowed size of the database */ + i64 journalSizeLimit; /* Size limit for persistent journal files */ + char *zFilename; /* Name of the database file */ + char *zJournal; /* Name of the journal file */ + int (*xBusyHandler)(void*); /* Function to call when busy */ + void *pBusyHandlerArg; /* Context argument for xBusyHandler */ + int nHit, nMiss; /* Total cache hits and misses */ +#ifdef SQLITE_TEST + int nRead, nWrite; /* Database pages read/written */ +#endif + void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */ +#ifdef SQLITE_HAS_CODEC + void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */ + void (*xCodecSizeChng)(void*,int,int); /* Notify of page size changes */ + void (*xCodecFree)(void*); /* Destructor for the codec */ + void *pCodec; /* First argument to xCodec... methods */ +#endif + char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ + PCache *pPCache; /* Pointer to page cache object */ +#ifndef SQLITE_OMIT_WAL + Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */ + char *zWal; /* File name for write-ahead log */ +#endif +}; + +/* +** The following global variables hold counters used for +** testing purposes only. These variables do not exist in +** a non-testing build. These variables are not thread-safe. +*/ +#ifdef SQLITE_TEST +int sqlite3_pager_readdb_count = 0; /* Number of full pages read from DB */ +int sqlite3_pager_writedb_count = 0; /* Number of full pages written to DB */ +int sqlite3_pager_writej_count = 0; /* Number of pages written to journal */ +# define PAGER_INCR(v) v++ +#else +# define PAGER_INCR(v) +#endif + + + +/* +** Journal files begin with the following magic string. The data +** was obtained from /dev/random. It is used only as a sanity check. +** +** Since version 2.8.0, the journal format contains additional sanity +** checking information. If the power fails while the journal is being +** written, semi-random garbage data might appear in the journal +** file after power is restored. If an attempt is then made +** to roll the journal back, the database could be corrupted. The additional +** sanity checking data is an attempt to discover the garbage in the +** journal and ignore it. +** +** The sanity checking information for the new journal format consists +** of a 32-bit checksum on each page of data. The checksum covers both +** the page number and the pPager->pageSize bytes of data for the page. +** This cksum is initialized to a 32-bit random value that appears in the +** journal file right after the header. The random initializer is important, +** because garbage data that appears at the end of a journal is likely +** data that was once in other files that have now been deleted. If the +** garbage data came from an obsolete journal file, the checksums might +** be correct. But by initializing the checksum to random value which +** is different for every journal, we minimize that risk. +*/ +static const unsigned char aJournalMagic[] = { + 0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, 0xd7, +}; + +/* +** The size of the of each page record in the journal is given by +** the following macro. +*/ +#define JOURNAL_PG_SZ(pPager) ((pPager->pageSize) + 8) + +/* +** The journal header size for this pager. This is usually the same +** size as a single disk sector. See also setSectorSize(). +*/ +#define JOURNAL_HDR_SZ(pPager) (pPager->sectorSize) + +/* +** The macro MEMDB is true if we are dealing with an in-memory database. +** We do this as a macro so that if the SQLITE_OMIT_MEMORYDB macro is set, +** the value of MEMDB will be a constant and the compiler will optimize +** out code that would never execute. +*/ +#ifdef SQLITE_OMIT_MEMORYDB +# define MEMDB 0 +#else +# define MEMDB pPager->memDb +#endif + +/* +** The maximum legal page number is (2^31 - 1). +*/ +#define PAGER_MAX_PGNO 2147483647 + +/* +** The argument to this macro is a file descriptor (type sqlite3_file*). +** Return 0 if it is not open, or non-zero (but not 1) if it is. +** +** This is so that expressions can be written as: +** +** if( isOpen(pPager->jfd) ){ ... +** +** instead of +** +** if( pPager->jfd->pMethods ){ ... +*/ +#define isOpen(pFd) ((pFd)->pMethods) + +/* +** Return true if this pager uses a write-ahead log instead of the usual +** rollback journal. Otherwise false. +*/ +#ifndef SQLITE_OMIT_WAL +static int pagerUseWal(Pager *pPager){ + return (pPager->pWal!=0); +} +#else +# define pagerUseWal(x) 0 +# define pagerRollbackWal(x) 0 +# define pagerWalFrames(v,w,x,y) 0 +# define pagerOpenWalIfPresent(z) SQLITE_OK +# define pagerBeginReadTransaction(z) SQLITE_OK +#endif + +#ifndef NDEBUG +/* +** Usage: +** +** assert( assert_pager_state(pPager) ); +** +** This function runs many asserts to try to find inconsistencies in +** the internal state of the Pager object. +*/ +static int assert_pager_state(Pager *p){ + Pager *pPager = p; + + /* State must be valid. */ + assert( p->eState==PAGER_OPEN + || p->eState==PAGER_READER + || p->eState==PAGER_WRITER_LOCKED + || p->eState==PAGER_WRITER_CACHEMOD + || p->eState==PAGER_WRITER_DBMOD + || p->eState==PAGER_WRITER_FINISHED + || p->eState==PAGER_ERROR + ); + + /* Regardless of the current state, a temp-file connection always behaves + ** as if it has an exclusive lock on the database file. It never updates + ** the change-counter field, so the changeCountDone flag is always set. + */ + assert( p->tempFile==0 || p->eLock==EXCLUSIVE_LOCK ); + assert( p->tempFile==0 || pPager->changeCountDone ); + + /* If the useJournal flag is clear, the journal-mode must be "OFF". + ** And if the journal-mode is "OFF", the journal file must not be open. + */ + assert( p->journalMode==PAGER_JOURNALMODE_OFF || p->useJournal ); + assert( p->journalMode!=PAGER_JOURNALMODE_OFF || !isOpen(p->jfd) ); + + /* Check that MEMDB implies noSync. And an in-memory journal. Since + ** this means an in-memory pager performs no IO at all, it cannot encounter + ** either SQLITE_IOERR or SQLITE_FULL during rollback or while finalizing + ** a journal file. (although the in-memory journal implementation may + ** return SQLITE_IOERR_NOMEM while the journal file is being written). It + ** is therefore not possible for an in-memory pager to enter the ERROR + ** state. + */ + if( MEMDB ){ + assert( p->noSync ); + assert( p->journalMode==PAGER_JOURNALMODE_OFF + || p->journalMode==PAGER_JOURNALMODE_MEMORY + ); + assert( p->eState!=PAGER_ERROR && p->eState!=PAGER_OPEN ); + assert( pagerUseWal(p)==0 ); + } + + /* If changeCountDone is set, a RESERVED lock or greater must be held + ** on the file. + */ + assert( pPager->changeCountDone==0 || pPager->eLock>=RESERVED_LOCK ); + assert( p->eLock!=PENDING_LOCK ); + + switch( p->eState ){ + case PAGER_OPEN: + assert( !MEMDB ); + assert( pPager->errCode==SQLITE_OK ); + assert( sqlite3PcacheRefCount(pPager->pPCache)==0 || pPager->tempFile ); + break; + + case PAGER_READER: + assert( pPager->errCode==SQLITE_OK ); + assert( p->eLock!=UNKNOWN_LOCK ); + assert( p->eLock>=SHARED_LOCK || p->noReadlock ); + break; + + case PAGER_WRITER_LOCKED: + assert( p->eLock!=UNKNOWN_LOCK ); + assert( pPager->errCode==SQLITE_OK ); + if( !pagerUseWal(pPager) ){ + assert( p->eLock>=RESERVED_LOCK ); + } + assert( pPager->dbSize==pPager->dbOrigSize ); + assert( pPager->dbOrigSize==pPager->dbFileSize ); + assert( pPager->dbOrigSize==pPager->dbHintSize ); + assert( pPager->setMaster==0 ); + break; + + case PAGER_WRITER_CACHEMOD: + assert( p->eLock!=UNKNOWN_LOCK ); + assert( pPager->errCode==SQLITE_OK ); + if( !pagerUseWal(pPager) ){ + /* It is possible that if journal_mode=wal here that neither the + ** journal file nor the WAL file are open. This happens during + ** a rollback transaction that switches from journal_mode=off + ** to journal_mode=wal. + */ + assert( p->eLock>=RESERVED_LOCK ); + assert( isOpen(p->jfd) + || p->journalMode==PAGER_JOURNALMODE_OFF + || p->journalMode==PAGER_JOURNALMODE_WAL + ); + } + assert( pPager->dbOrigSize==pPager->dbFileSize ); + assert( pPager->dbOrigSize==pPager->dbHintSize ); + break; + + case PAGER_WRITER_DBMOD: + assert( p->eLock==EXCLUSIVE_LOCK ); + assert( pPager->errCode==SQLITE_OK ); + assert( !pagerUseWal(pPager) ); + assert( p->eLock>=EXCLUSIVE_LOCK ); + assert( isOpen(p->jfd) + || p->journalMode==PAGER_JOURNALMODE_OFF + || p->journalMode==PAGER_JOURNALMODE_WAL + ); + assert( pPager->dbOrigSize<=pPager->dbHintSize ); + break; + + case PAGER_WRITER_FINISHED: + assert( p->eLock==EXCLUSIVE_LOCK ); + assert( pPager->errCode==SQLITE_OK ); + assert( !pagerUseWal(pPager) ); + assert( isOpen(p->jfd) + || p->journalMode==PAGER_JOURNALMODE_OFF + || p->journalMode==PAGER_JOURNALMODE_WAL + ); + break; + + case PAGER_ERROR: + /* There must be at least one outstanding reference to the pager if + ** in ERROR state. Otherwise the pager should have already dropped + ** back to OPEN state. + */ + assert( pPager->errCode!=SQLITE_OK ); + assert( sqlite3PcacheRefCount(pPager->pPCache)>0 ); + break; + } + + return 1; +} +#endif /* ifndef NDEBUG */ + +#ifdef SQLITE_DEBUG +/* +** Return a pointer to a human readable string in a static buffer +** containing the state of the Pager object passed as an argument. This +** is intended to be used within debuggers. For example, as an alternative +** to "print *pPager" in gdb: +** +** (gdb) printf "%s", print_pager_state(pPager) +*/ +static char *print_pager_state(Pager *p){ + static char zRet[1024]; + + sqlite3_snprintf(1024, zRet, + "Filename: %s\n" + "State: %s errCode=%d\n" + "Lock: %s\n" + "Locking mode: locking_mode=%s\n" + "Journal mode: journal_mode=%s\n" + "Backing store: tempFile=%d memDb=%d useJournal=%d\n" + "Journal: journalOff=%lld journalHdr=%lld\n" + "Size: dbsize=%d dbOrigSize=%d dbFileSize=%d\n" + , p->zFilename + , p->eState==PAGER_OPEN ? "OPEN" : + p->eState==PAGER_READER ? "READER" : + p->eState==PAGER_WRITER_LOCKED ? "WRITER_LOCKED" : + p->eState==PAGER_WRITER_CACHEMOD ? "WRITER_CACHEMOD" : + p->eState==PAGER_WRITER_DBMOD ? "WRITER_DBMOD" : + p->eState==PAGER_WRITER_FINISHED ? "WRITER_FINISHED" : + p->eState==PAGER_ERROR ? "ERROR" : "?error?" + , (int)p->errCode + , p->eLock==NO_LOCK ? "NO_LOCK" : + p->eLock==RESERVED_LOCK ? "RESERVED" : + p->eLock==EXCLUSIVE_LOCK ? "EXCLUSIVE" : + p->eLock==SHARED_LOCK ? "SHARED" : + p->eLock==UNKNOWN_LOCK ? "UNKNOWN" : "?error?" + , p->exclusiveMode ? "exclusive" : "normal" + , p->journalMode==PAGER_JOURNALMODE_MEMORY ? "memory" : + p->journalMode==PAGER_JOURNALMODE_OFF ? "off" : + p->journalMode==PAGER_JOURNALMODE_DELETE ? "delete" : + p->journalMode==PAGER_JOURNALMODE_PERSIST ? "persist" : + p->journalMode==PAGER_JOURNALMODE_TRUNCATE ? "truncate" : + p->journalMode==PAGER_JOURNALMODE_WAL ? "wal" : "?error?" + , (int)p->tempFile, (int)p->memDb, (int)p->useJournal + , p->journalOff, p->journalHdr + , (int)p->dbSize, (int)p->dbOrigSize, (int)p->dbFileSize + ); + + return zRet; +} +#endif + +/* +** Return true if it is necessary to write page *pPg into the sub-journal. +** A page needs to be written into the sub-journal if there exists one +** or more open savepoints for which: +** +** * The page-number is less than or equal to PagerSavepoint.nOrig, and +** * The bit corresponding to the page-number is not set in +** PagerSavepoint.pInSavepoint. +*/ +static int subjRequiresPage(PgHdr *pPg){ + Pgno pgno = pPg->pgno; + Pager *pPager = pPg->pPager; + int i; + for(i=0; inSavepoint; i++){ + PagerSavepoint *p = &pPager->aSavepoint[i]; + if( p->nOrig>=pgno && 0==sqlite3BitvecTest(p->pInSavepoint, pgno) ){ + return 1; + } + } + return 0; +} + +/* +** Return true if the page is already in the journal file. +*/ +static int pageInJournal(PgHdr *pPg){ + return sqlite3BitvecTest(pPg->pPager->pInJournal, pPg->pgno); +} + +/* +** Read a 32-bit integer from the given file descriptor. Store the integer +** that is read in *pRes. Return SQLITE_OK if everything worked, or an +** error code is something goes wrong. +** +** All values are stored on disk as big-endian. +*/ +static int read32bits(sqlite3_file *fd, i64 offset, u32 *pRes){ + unsigned char ac[4]; + int rc = sqlite3OsRead(fd, ac, sizeof(ac), offset); + if( rc==SQLITE_OK ){ + *pRes = sqlite3Get4byte(ac); + } + return rc; +} + +/* +** Write a 32-bit integer into a string buffer in big-endian byte order. +*/ +#define put32bits(A,B) sqlite3Put4byte((u8*)A,B) + + +/* +** Write a 32-bit integer into the given file descriptor. Return SQLITE_OK +** on success or an error code is something goes wrong. +*/ +static int write32bits(sqlite3_file *fd, i64 offset, u32 val){ + char ac[4]; + put32bits(ac, val); + return sqlite3OsWrite(fd, ac, 4, offset); +} + +/* +** Unlock the database file to level eLock, which must be either NO_LOCK +** or SHARED_LOCK. Regardless of whether or not the call to xUnlock() +** succeeds, set the Pager.eLock variable to match the (attempted) new lock. +** +** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is +** called, do not modify it. See the comment above the #define of +** UNKNOWN_LOCK for an explanation of this. +*/ +static int pagerUnlockDb(Pager *pPager, int eLock){ + int rc = SQLITE_OK; + + assert( !pPager->exclusiveMode || pPager->eLock==eLock ); + assert( eLock==NO_LOCK || eLock==SHARED_LOCK ); + assert( eLock!=NO_LOCK || pagerUseWal(pPager)==0 ); + if( isOpen(pPager->fd) ){ + assert( pPager->eLock>=eLock ); + rc = sqlite3OsUnlock(pPager->fd, eLock); + if( pPager->eLock!=UNKNOWN_LOCK ){ + pPager->eLock = (u8)eLock; + } + IOTRACE(("UNLOCK %p %d\n", pPager, eLock)) + } + return rc; +} + +/* +** Lock the database file to level eLock, which must be either SHARED_LOCK, +** RESERVED_LOCK or EXCLUSIVE_LOCK. If the caller is successful, set the +** Pager.eLock variable to the new locking state. +** +** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is +** called, do not modify it unless the new locking state is EXCLUSIVE_LOCK. +** See the comment above the #define of UNKNOWN_LOCK for an explanation +** of this. +*/ +static int pagerLockDb(Pager *pPager, int eLock){ + int rc = SQLITE_OK; + + assert( eLock==SHARED_LOCK || eLock==RESERVED_LOCK || eLock==EXCLUSIVE_LOCK ); + if( pPager->eLockeLock==UNKNOWN_LOCK ){ + rc = sqlite3OsLock(pPager->fd, eLock); + if( rc==SQLITE_OK && (pPager->eLock!=UNKNOWN_LOCK||eLock==EXCLUSIVE_LOCK) ){ + pPager->eLock = (u8)eLock; + IOTRACE(("LOCK %p %d\n", pPager, eLock)) + } + } + return rc; +} + +/* +** This function determines whether or not the atomic-write optimization +** can be used with this pager. The optimization can be used if: +** +** (a) the value returned by OsDeviceCharacteristics() indicates that +** a database page may be written atomically, and +** (b) the value returned by OsSectorSize() is less than or equal +** to the page size. +** +** The optimization is also always enabled for temporary files. It is +** an error to call this function if pPager is opened on an in-memory +** database. +** +** If the optimization cannot be used, 0 is returned. If it can be used, +** then the value returned is the size of the journal file when it +** contains rollback data for exactly one page. +*/ +#ifdef SQLITE_ENABLE_ATOMIC_WRITE +static int jrnlBufferSize(Pager *pPager){ + assert( !MEMDB ); + if( !pPager->tempFile ){ + int dc; /* Device characteristics */ + int nSector; /* Sector size */ + int szPage; /* Page size */ + + assert( isOpen(pPager->fd) ); + dc = sqlite3OsDeviceCharacteristics(pPager->fd); + nSector = pPager->sectorSize; + szPage = pPager->pageSize; + + assert(SQLITE_IOCAP_ATOMIC512==(512>>8)); + assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8)); + if( 0==(dc&(SQLITE_IOCAP_ATOMIC|(szPage>>8)) || nSector>szPage) ){ + return 0; + } + } + + return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager); +} +#endif + +/* +** If SQLITE_CHECK_PAGES is defined then we do some sanity checking +** on the cache using a hash function. This is used for testing +** and debugging only. +*/ +#ifdef SQLITE_CHECK_PAGES +/* +** Return a 32-bit hash of the page data for pPage. +*/ +static u32 pager_datahash(int nByte, unsigned char *pData){ + u32 hash = 0; + int i; + for(i=0; ipPager->pageSize, (unsigned char *)pPage->pData); +} +static void pager_set_pagehash(PgHdr *pPage){ + pPage->pageHash = pager_pagehash(pPage); +} + +/* +** The CHECK_PAGE macro takes a PgHdr* as an argument. If SQLITE_CHECK_PAGES +** is defined, and NDEBUG is not defined, an assert() statement checks +** that the page is either dirty or still matches the calculated page-hash. +*/ +#define CHECK_PAGE(x) checkPage(x) +static void checkPage(PgHdr *pPg){ + Pager *pPager = pPg->pPager; + assert( pPager->eState!=PAGER_ERROR ); + assert( (pPg->flags&PGHDR_DIRTY) || pPg->pageHash==pager_pagehash(pPg) ); +} + +#else +#define pager_datahash(X,Y) 0 +#define pager_pagehash(X) 0 +#define pager_set_pagehash(X) +#define CHECK_PAGE(x) +#endif /* SQLITE_CHECK_PAGES */ + +/* +** When this is called the journal file for pager pPager must be open. +** This function attempts to read a master journal file name from the +** end of the file and, if successful, copies it into memory supplied +** by the caller. See comments above writeMasterJournal() for the format +** used to store a master journal file name at the end of a journal file. +** +** zMaster must point to a buffer of at least nMaster bytes allocated by +** the caller. This should be sqlite3_vfs.mxPathname+1 (to ensure there is +** enough space to write the master journal name). If the master journal +** name in the journal is longer than nMaster bytes (including a +** nul-terminator), then this is handled as if no master journal name +** were present in the journal. +** +** If a master journal file name is present at the end of the journal +** file, then it is copied into the buffer pointed to by zMaster. A +** nul-terminator byte is appended to the buffer following the master +** journal file name. +** +** If it is determined that no master journal file name is present +** zMaster[0] is set to 0 and SQLITE_OK returned. +** +** If an error occurs while reading from the journal file, an SQLite +** error code is returned. +*/ +static int readMasterJournal(sqlite3_file *pJrnl, char *zMaster, u32 nMaster){ + int rc; /* Return code */ + u32 len; /* Length in bytes of master journal name */ + i64 szJ; /* Total size in bytes of journal file pJrnl */ + u32 cksum; /* MJ checksum value read from journal */ + u32 u; /* Unsigned loop counter */ + unsigned char aMagic[8]; /* A buffer to hold the magic header */ + zMaster[0] = '\0'; + + if( SQLITE_OK!=(rc = sqlite3OsFileSize(pJrnl, &szJ)) + || szJ<16 + || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len)) + || len>=nMaster + || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum)) + || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8)) + || memcmp(aMagic, aJournalMagic, 8) + || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, zMaster, len, szJ-16-len)) + ){ + return rc; + } + + /* See if the checksum matches the master journal name */ + for(u=0; ujournalOff, assuming a sector +** size of pPager->sectorSize bytes. +** +** i.e for a sector size of 512: +** +** Pager.journalOff Return value +** --------------------------------------- +** 0 0 +** 512 512 +** 100 512 +** 2000 2048 +** +*/ +static i64 journalHdrOffset(Pager *pPager){ + i64 offset = 0; + i64 c = pPager->journalOff; + if( c ){ + offset = ((c-1)/JOURNAL_HDR_SZ(pPager) + 1) * JOURNAL_HDR_SZ(pPager); + } + assert( offset%JOURNAL_HDR_SZ(pPager)==0 ); + assert( offset>=c ); + assert( (offset-c)jfd) ); + if( pPager->journalOff ){ + const i64 iLimit = pPager->journalSizeLimit; /* Local cache of jsl */ + + IOTRACE(("JZEROHDR %p\n", pPager)) + if( doTruncate || iLimit==0 ){ + rc = sqlite3OsTruncate(pPager->jfd, 0); + }else{ + static const char zeroHdr[28] = {0}; + rc = sqlite3OsWrite(pPager->jfd, zeroHdr, sizeof(zeroHdr), 0); + } + if( rc==SQLITE_OK && !pPager->noSync ){ + rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_DATAONLY|pPager->syncFlags); + } + + /* At this point the transaction is committed but the write lock + ** is still held on the file. If there is a size limit configured for + ** the persistent journal and the journal file currently consumes more + ** space than that limit allows for, truncate it now. There is no need + ** to sync the file following this operation. + */ + if( rc==SQLITE_OK && iLimit>0 ){ + i64 sz; + rc = sqlite3OsFileSize(pPager->jfd, &sz); + if( rc==SQLITE_OK && sz>iLimit ){ + rc = sqlite3OsTruncate(pPager->jfd, iLimit); + } + } + } + return rc; +} + +/* +** The journal file must be open when this routine is called. A journal +** header (JOURNAL_HDR_SZ bytes) is written into the journal file at the +** current location. +** +** The format for the journal header is as follows: +** - 8 bytes: Magic identifying journal format. +** - 4 bytes: Number of records in journal, or -1 no-sync mode is on. +** - 4 bytes: Random number used for page hash. +** - 4 bytes: Initial database page count. +** - 4 bytes: Sector size used by the process that wrote this journal. +** - 4 bytes: Database page size. +** +** Followed by (JOURNAL_HDR_SZ - 28) bytes of unused space. +*/ +static int writeJournalHdr(Pager *pPager){ + int rc = SQLITE_OK; /* Return code */ + char *zHeader = pPager->pTmpSpace; /* Temporary space used to build header */ + u32 nHeader = (u32)pPager->pageSize;/* Size of buffer pointed to by zHeader */ + u32 nWrite; /* Bytes of header sector written */ + int ii; /* Loop counter */ + + assert( isOpen(pPager->jfd) ); /* Journal file must be open. */ + + if( nHeader>JOURNAL_HDR_SZ(pPager) ){ + nHeader = JOURNAL_HDR_SZ(pPager); + } + + /* If there are active savepoints and any of them were created + ** since the most recent journal header was written, update the + ** PagerSavepoint.iHdrOffset fields now. + */ + for(ii=0; iinSavepoint; ii++){ + if( pPager->aSavepoint[ii].iHdrOffset==0 ){ + pPager->aSavepoint[ii].iHdrOffset = pPager->journalOff; + } + } + + pPager->journalHdr = pPager->journalOff = journalHdrOffset(pPager); + + /* + ** Write the nRec Field - the number of page records that follow this + ** journal header. Normally, zero is written to this value at this time. + ** After the records are added to the journal (and the journal synced, + ** if in full-sync mode), the zero is overwritten with the true number + ** of records (see syncJournal()). + ** + ** A faster alternative is to write 0xFFFFFFFF to the nRec field. When + ** reading the journal this value tells SQLite to assume that the + ** rest of the journal file contains valid page records. This assumption + ** is dangerous, as if a failure occurred whilst writing to the journal + ** file it may contain some garbage data. There are two scenarios + ** where this risk can be ignored: + ** + ** * When the pager is in no-sync mode. Corruption can follow a + ** power failure in this case anyway. + ** + ** * When the SQLITE_IOCAP_SAFE_APPEND flag is set. This guarantees + ** that garbage data is never appended to the journal file. + */ + assert( isOpen(pPager->fd) || pPager->noSync ); + if( pPager->noSync || (pPager->journalMode==PAGER_JOURNALMODE_MEMORY) + || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND) + ){ + memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic)); + put32bits(&zHeader[sizeof(aJournalMagic)], 0xffffffff); + }else{ + memset(zHeader, 0, sizeof(aJournalMagic)+4); + } + + /* The random check-hash initialiser */ + sqlite3_randomness(sizeof(pPager->cksumInit), &pPager->cksumInit); + put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit); + /* The initial database size */ + put32bits(&zHeader[sizeof(aJournalMagic)+8], pPager->dbOrigSize); + /* The assumed sector size for this process */ + put32bits(&zHeader[sizeof(aJournalMagic)+12], pPager->sectorSize); + + /* The page size */ + put32bits(&zHeader[sizeof(aJournalMagic)+16], pPager->pageSize); + + /* Initializing the tail of the buffer is not necessary. Everything + ** works find if the following memset() is omitted. But initializing + ** the memory prevents valgrind from complaining, so we are willing to + ** take the performance hit. + */ + memset(&zHeader[sizeof(aJournalMagic)+20], 0, + nHeader-(sizeof(aJournalMagic)+20)); + + /* In theory, it is only necessary to write the 28 bytes that the + ** journal header consumes to the journal file here. Then increment the + ** Pager.journalOff variable by JOURNAL_HDR_SZ so that the next + ** record is written to the following sector (leaving a gap in the file + ** that will be implicitly filled in by the OS). + ** + ** However it has been discovered that on some systems this pattern can + ** be significantly slower than contiguously writing data to the file, + ** even if that means explicitly writing data to the block of + ** (JOURNAL_HDR_SZ - 28) bytes that will not be used. So that is what + ** is done. + ** + ** The loop is required here in case the sector-size is larger than the + ** database page size. Since the zHeader buffer is only Pager.pageSize + ** bytes in size, more than one call to sqlite3OsWrite() may be required + ** to populate the entire journal header sector. + */ + for(nWrite=0; rc==SQLITE_OK&&nWritejournalHdr, nHeader)) + rc = sqlite3OsWrite(pPager->jfd, zHeader, nHeader, pPager->journalOff); + assert( pPager->journalHdr <= pPager->journalOff ); + pPager->journalOff += nHeader; + } + + return rc; +} + +/* +** The journal file must be open when this is called. A journal header file +** (JOURNAL_HDR_SZ bytes) is read from the current location in the journal +** file. The current location in the journal file is given by +** pPager->journalOff. See comments above function writeJournalHdr() for +** a description of the journal header format. +** +** If the header is read successfully, *pNRec is set to the number of +** page records following this header and *pDbSize is set to the size of the +** database before the transaction began, in pages. Also, pPager->cksumInit +** is set to the value read from the journal header. SQLITE_OK is returned +** in this case. +** +** If the journal header file appears to be corrupted, SQLITE_DONE is +** returned and *pNRec and *PDbSize are undefined. If JOURNAL_HDR_SZ bytes +** cannot be read from the journal file an error code is returned. +*/ +static int readJournalHdr( + Pager *pPager, /* Pager object */ + int isHot, + i64 journalSize, /* Size of the open journal file in bytes */ + u32 *pNRec, /* OUT: Value read from the nRec field */ + u32 *pDbSize /* OUT: Value of original database size field */ +){ + int rc; /* Return code */ + unsigned char aMagic[8]; /* A buffer to hold the magic header */ + i64 iHdrOff; /* Offset of journal header being read */ + + assert( isOpen(pPager->jfd) ); /* Journal file must be open. */ + + /* Advance Pager.journalOff to the start of the next sector. If the + ** journal file is too small for there to be a header stored at this + ** point, return SQLITE_DONE. + */ + pPager->journalOff = journalHdrOffset(pPager); + if( pPager->journalOff+JOURNAL_HDR_SZ(pPager) > journalSize ){ + return SQLITE_DONE; + } + iHdrOff = pPager->journalOff; + + /* Read in the first 8 bytes of the journal header. If they do not match + ** the magic string found at the start of each journal header, return + ** SQLITE_DONE. If an IO error occurs, return an error code. Otherwise, + ** proceed. + */ + if( isHot || iHdrOff!=pPager->journalHdr ){ + rc = sqlite3OsRead(pPager->jfd, aMagic, sizeof(aMagic), iHdrOff); + if( rc ){ + return rc; + } + if( memcmp(aMagic, aJournalMagic, sizeof(aMagic))!=0 ){ + return SQLITE_DONE; + } + } + + /* Read the first three 32-bit fields of the journal header: The nRec + ** field, the checksum-initializer and the database size at the start + ** of the transaction. Return an error code if anything goes wrong. + */ + if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+8, pNRec)) + || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+12, &pPager->cksumInit)) + || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+16, pDbSize)) + ){ + return rc; + } + + if( pPager->journalOff==0 ){ + u32 iPageSize; /* Page-size field of journal header */ + u32 iSectorSize; /* Sector-size field of journal header */ + + /* Read the page-size and sector-size journal header fields. */ + if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+20, &iSectorSize)) + || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+24, &iPageSize)) + ){ + return rc; + } + + /* Versions of SQLite prior to 3.5.8 set the page-size field of the + ** journal header to zero. In this case, assume that the Pager.pageSize + ** variable is already set to the correct page size. + */ + if( iPageSize==0 ){ + iPageSize = pPager->pageSize; + } + + /* Check that the values read from the page-size and sector-size fields + ** are within range. To be 'in range', both values need to be a power + ** of two greater than or equal to 512 or 32, and not greater than their + ** respective compile time maximum limits. + */ + if( iPageSize<512 || iSectorSize<32 + || iPageSize>SQLITE_MAX_PAGE_SIZE || iSectorSize>MAX_SECTOR_SIZE + || ((iPageSize-1)&iPageSize)!=0 || ((iSectorSize-1)&iSectorSize)!=0 + ){ + /* If the either the page-size or sector-size in the journal-header is + ** invalid, then the process that wrote the journal-header must have + ** crashed before the header was synced. In this case stop reading + ** the journal file here. + */ + return SQLITE_DONE; + } + + /* Update the page-size to match the value read from the journal. + ** Use a testcase() macro to make sure that malloc failure within + ** PagerSetPagesize() is tested. + */ + rc = sqlite3PagerSetPagesize(pPager, &iPageSize, -1); + testcase( rc!=SQLITE_OK ); + + /* Update the assumed sector-size to match the value used by + ** the process that created this journal. If this journal was + ** created by a process other than this one, then this routine + ** is being called from within pager_playback(). The local value + ** of Pager.sectorSize is restored at the end of that routine. + */ + pPager->sectorSize = iSectorSize; + } + + pPager->journalOff += JOURNAL_HDR_SZ(pPager); + return rc; +} + + +/* +** Write the supplied master journal name into the journal file for pager +** pPager at the current location. The master journal name must be the last +** thing written to a journal file. If the pager is in full-sync mode, the +** journal file descriptor is advanced to the next sector boundary before +** anything is written. The format is: +** +** + 4 bytes: PAGER_MJ_PGNO. +** + N bytes: Master journal filename in utf-8. +** + 4 bytes: N (length of master journal name in bytes, no nul-terminator). +** + 4 bytes: Master journal name checksum. +** + 8 bytes: aJournalMagic[]. +** +** The master journal page checksum is the sum of the bytes in the master +** journal name, where each byte is interpreted as a signed 8-bit integer. +** +** If zMaster is a NULL pointer (occurs for a single database transaction), +** this call is a no-op. +*/ +static int writeMasterJournal(Pager *pPager, const char *zMaster){ + int rc; /* Return code */ + int nMaster; /* Length of string zMaster */ + i64 iHdrOff; /* Offset of header in journal file */ + i64 jrnlSize; /* Size of journal file on disk */ + u32 cksum = 0; /* Checksum of string zMaster */ + + assert( pPager->setMaster==0 ); + assert( !pagerUseWal(pPager) ); + + if( !zMaster + || pPager->journalMode==PAGER_JOURNALMODE_MEMORY + || pPager->journalMode==PAGER_JOURNALMODE_OFF + ){ + return SQLITE_OK; + } + pPager->setMaster = 1; + assert( isOpen(pPager->jfd) ); + assert( pPager->journalHdr <= pPager->journalOff ); + + /* Calculate the length in bytes and the checksum of zMaster */ + for(nMaster=0; zMaster[nMaster]; nMaster++){ + cksum += zMaster[nMaster]; + } + + /* If in full-sync mode, advance to the next disk sector before writing + ** the master journal name. This is in case the previous page written to + ** the journal has already been synced. + */ + if( pPager->fullSync ){ + pPager->journalOff = journalHdrOffset(pPager); + } + iHdrOff = pPager->journalOff; + + /* Write the master journal data to the end of the journal file. If + ** an error occurs, return the error code to the caller. + */ + if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_MJ_PGNO(pPager)))) + || (0 != (rc = sqlite3OsWrite(pPager->jfd, zMaster, nMaster, iHdrOff+4))) + || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster, nMaster))) + || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster+4, cksum))) + || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8, iHdrOff+4+nMaster+8))) + ){ + return rc; + } + pPager->journalOff += (nMaster+20); + + /* If the pager is in peristent-journal mode, then the physical + ** journal-file may extend past the end of the master-journal name + ** and 8 bytes of magic data just written to the file. This is + ** dangerous because the code to rollback a hot-journal file + ** will not be able to find the master-journal name to determine + ** whether or not the journal is hot. + ** + ** Easiest thing to do in this scenario is to truncate the journal + ** file to the required size. + */ + if( SQLITE_OK==(rc = sqlite3OsFileSize(pPager->jfd, &jrnlSize)) + && jrnlSize>pPager->journalOff + ){ + rc = sqlite3OsTruncate(pPager->jfd, pPager->journalOff); + } + return rc; +} + +/* +** Find a page in the hash table given its page number. Return +** a pointer to the page or NULL if the requested page is not +** already in memory. +*/ +static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){ + PgHdr *p; /* Return value */ + + /* It is not possible for a call to PcacheFetch() with createFlag==0 to + ** fail, since no attempt to allocate dynamic memory will be made. + */ + (void)sqlite3PcacheFetch(pPager->pPCache, pgno, 0, &p); + return p; +} + +/* +** Discard the entire contents of the in-memory page-cache. +*/ +static void pager_reset(Pager *pPager){ + sqlite3BackupRestart(pPager->pBackup); + sqlite3PcacheClear(pPager->pPCache); +} + +/* +** Free all structures in the Pager.aSavepoint[] array and set both +** Pager.aSavepoint and Pager.nSavepoint to zero. Close the sub-journal +** if it is open and the pager is not in exclusive mode. +*/ +static void releaseAllSavepoints(Pager *pPager){ + int ii; /* Iterator for looping through Pager.aSavepoint */ + for(ii=0; iinSavepoint; ii++){ + sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint); + } + if( !pPager->exclusiveMode || sqlite3IsMemJournal(pPager->sjfd) ){ + sqlite3OsClose(pPager->sjfd); + } + sqlite3_free(pPager->aSavepoint); + pPager->aSavepoint = 0; + pPager->nSavepoint = 0; + pPager->nSubRec = 0; +} + +/* +** Set the bit number pgno in the PagerSavepoint.pInSavepoint +** bitvecs of all open savepoints. Return SQLITE_OK if successful +** or SQLITE_NOMEM if a malloc failure occurs. +*/ +static int addToSavepointBitvecs(Pager *pPager, Pgno pgno){ + int ii; /* Loop counter */ + int rc = SQLITE_OK; /* Result code */ + + for(ii=0; iinSavepoint; ii++){ + PagerSavepoint *p = &pPager->aSavepoint[ii]; + if( pgno<=p->nOrig ){ + rc |= sqlite3BitvecSet(p->pInSavepoint, pgno); + testcase( rc==SQLITE_NOMEM ); + assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); + } + } + return rc; +} + +/* +** This function is a no-op if the pager is in exclusive mode and not +** in the ERROR state. Otherwise, it switches the pager to PAGER_OPEN +** state. +** +** If the pager is not in exclusive-access mode, the database file is +** completely unlocked. If the file is unlocked and the file-system does +** not exhibit the UNDELETABLE_WHEN_OPEN property, the journal file is +** closed (if it is open). +** +** If the pager is in ERROR state when this function is called, the +** contents of the pager cache are discarded before switching back to +** the OPEN state. Regardless of whether the pager is in exclusive-mode +** or not, any journal file left in the file-system will be treated +** as a hot-journal and rolled back the next time a read-transaction +** is opened (by this or by any other connection). +*/ +static void pager_unlock(Pager *pPager){ + + assert( pPager->eState==PAGER_READER + || pPager->eState==PAGER_OPEN + || pPager->eState==PAGER_ERROR + ); + + sqlite3BitvecDestroy(pPager->pInJournal); + pPager->pInJournal = 0; + releaseAllSavepoints(pPager); + + if( pagerUseWal(pPager) ){ + assert( !isOpen(pPager->jfd) ); + sqlite3WalEndReadTransaction(pPager->pWal); + pPager->eState = PAGER_OPEN; + }else if( !pPager->exclusiveMode ){ + int rc; /* Error code returned by pagerUnlockDb() */ + int iDc = isOpen(pPager->fd)?sqlite3OsDeviceCharacteristics(pPager->fd):0; + + /* If the operating system support deletion of open files, then + ** close the journal file when dropping the database lock. Otherwise + ** another connection with journal_mode=delete might delete the file + ** out from under us. + */ + assert( (PAGER_JOURNALMODE_MEMORY & 5)!=1 ); + assert( (PAGER_JOURNALMODE_OFF & 5)!=1 ); + assert( (PAGER_JOURNALMODE_WAL & 5)!=1 ); + assert( (PAGER_JOURNALMODE_DELETE & 5)!=1 ); + assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 ); + assert( (PAGER_JOURNALMODE_PERSIST & 5)==1 ); + if( 0==(iDc & SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN) + || 1!=(pPager->journalMode & 5) + ){ + sqlite3OsClose(pPager->jfd); + } + + /* If the pager is in the ERROR state and the call to unlock the database + ** file fails, set the current lock to UNKNOWN_LOCK. See the comment + ** above the #define for UNKNOWN_LOCK for an explanation of why this + ** is necessary. + */ + rc = pagerUnlockDb(pPager, NO_LOCK); + if( rc!=SQLITE_OK && pPager->eState==PAGER_ERROR ){ + pPager->eLock = UNKNOWN_LOCK; + } + + /* The pager state may be changed from PAGER_ERROR to PAGER_OPEN here + ** without clearing the error code. This is intentional - the error + ** code is cleared and the cache reset in the block below. + */ + assert( pPager->errCode || pPager->eState!=PAGER_ERROR ); + pPager->changeCountDone = 0; + pPager->eState = PAGER_OPEN; + } + + /* If Pager.errCode is set, the contents of the pager cache cannot be + ** trusted. Now that there are no outstanding references to the pager, + ** it can safely move back to PAGER_OPEN state. This happens in both + ** normal and exclusive-locking mode. + */ + if( pPager->errCode ){ + assert( !MEMDB ); + pager_reset(pPager); + pPager->changeCountDone = pPager->tempFile; + pPager->eState = PAGER_OPEN; + pPager->errCode = SQLITE_OK; + } + + pPager->journalOff = 0; + pPager->journalHdr = 0; + pPager->setMaster = 0; +} + +/* +** This function is called whenever an IOERR or FULL error that requires +** the pager to transition into the ERROR state may ahve occurred. +** The first argument is a pointer to the pager structure, the second +** the error-code about to be returned by a pager API function. The +** value returned is a copy of the second argument to this function. +** +** If the second argument is SQLITE_FULL, SQLITE_IOERR or one of the +** IOERR sub-codes, the pager enters the ERROR state and the error code +** is stored in Pager.errCode. While the pager remains in the ERROR state, +** all major API calls on the Pager will immediately return Pager.errCode. +** +** The ERROR state indicates that the contents of the pager-cache +** cannot be trusted. This state can be cleared by completely discarding +** the contents of the pager-cache. If a transaction was active when +** the persistent error occurred, then the rollback journal may need +** to be replayed to restore the contents of the database file (as if +** it were a hot-journal). +*/ +static int pager_error(Pager *pPager, int rc){ + int rc2 = rc & 0xff; + assert( rc==SQLITE_OK || !MEMDB ); + assert( + pPager->errCode==SQLITE_FULL || + pPager->errCode==SQLITE_OK || + (pPager->errCode & 0xff)==SQLITE_IOERR + ); + if( rc2==SQLITE_FULL || rc2==SQLITE_IOERR ){ + pPager->errCode = rc; + pPager->eState = PAGER_ERROR; + } + return rc; +} + +/* +** This routine ends a transaction. A transaction is usually ended by +** either a COMMIT or a ROLLBACK operation. This routine may be called +** after rollback of a hot-journal, or if an error occurs while opening +** the journal file or writing the very first journal-header of a +** database transaction. +** +** This routine is never called in PAGER_ERROR state. If it is called +** in PAGER_NONE or PAGER_SHARED state and the lock held is less +** exclusive than a RESERVED lock, it is a no-op. +** +** Otherwise, any active savepoints are released. +** +** If the journal file is open, then it is "finalized". Once a journal +** file has been finalized it is not possible to use it to roll back a +** transaction. Nor will it be considered to be a hot-journal by this +** or any other database connection. Exactly how a journal is finalized +** depends on whether or not the pager is running in exclusive mode and +** the current journal-mode (Pager.journalMode value), as follows: +** +** journalMode==MEMORY +** Journal file descriptor is simply closed. This destroys an +** in-memory journal. +** +** journalMode==TRUNCATE +** Journal file is truncated to zero bytes in size. +** +** journalMode==PERSIST +** The first 28 bytes of the journal file are zeroed. This invalidates +** the first journal header in the file, and hence the entire journal +** file. An invalid journal file cannot be rolled back. +** +** journalMode==DELETE +** The journal file is closed and deleted using sqlite3OsDelete(). +** +** If the pager is running in exclusive mode, this method of finalizing +** the journal file is never used. Instead, if the journalMode is +** DELETE and the pager is in exclusive mode, the method described under +** journalMode==PERSIST is used instead. +** +** After the journal is finalized, the pager moves to PAGER_READER state. +** If running in non-exclusive rollback mode, the lock on the file is +** downgraded to a SHARED_LOCK. +** +** SQLITE_OK is returned if no error occurs. If an error occurs during +** any of the IO operations to finalize the journal file or unlock the +** database then the IO error code is returned to the user. If the +** operation to finalize the journal file fails, then the code still +** tries to unlock the database file if not in exclusive mode. If the +** unlock operation fails as well, then the first error code related +** to the first error encountered (the journal finalization one) is +** returned. +*/ +static int pager_end_transaction(Pager *pPager, int hasMaster){ + int rc = SQLITE_OK; /* Error code from journal finalization operation */ + int rc2 = SQLITE_OK; /* Error code from db file unlock operation */ + + /* Do nothing if the pager does not have an open write transaction + ** or at least a RESERVED lock. This function may be called when there + ** is no write-transaction active but a RESERVED or greater lock is + ** held under two circumstances: + ** + ** 1. After a successful hot-journal rollback, it is called with + ** eState==PAGER_NONE and eLock==EXCLUSIVE_LOCK. + ** + ** 2. If a connection with locking_mode=exclusive holding an EXCLUSIVE + ** lock switches back to locking_mode=normal and then executes a + ** read-transaction, this function is called with eState==PAGER_READER + ** and eLock==EXCLUSIVE_LOCK when the read-transaction is closed. + */ + assert( assert_pager_state(pPager) ); + assert( pPager->eState!=PAGER_ERROR ); + if( pPager->eStateeLockjfd) || pPager->pInJournal==0 ); + if( isOpen(pPager->jfd) ){ + assert( !pagerUseWal(pPager) ); + + /* Finalize the journal file. */ + if( sqlite3IsMemJournal(pPager->jfd) ){ + assert( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ); + sqlite3OsClose(pPager->jfd); + }else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){ + if( pPager->journalOff==0 ){ + rc = SQLITE_OK; + }else{ + rc = sqlite3OsTruncate(pPager->jfd, 0); + } + pPager->journalOff = 0; + }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST + || (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL) + ){ + rc = zeroJournalHdr(pPager, hasMaster); + pPager->journalOff = 0; + }else{ + /* This branch may be executed with Pager.journalMode==MEMORY if + ** a hot-journal was just rolled back. In this case the journal + ** file should be closed and deleted. If this connection writes to + ** the database file, it will do so using an in-memory journal. + */ + assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE + || pPager->journalMode==PAGER_JOURNALMODE_MEMORY + || pPager->journalMode==PAGER_JOURNALMODE_WAL + ); + sqlite3OsClose(pPager->jfd); + if( !pPager->tempFile ){ + rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); + } + } + } + +#ifdef SQLITE_CHECK_PAGES + sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash); + if( pPager->dbSize==0 && sqlite3PcacheRefCount(pPager->pPCache)>0 ){ + PgHdr *p = pager_lookup(pPager, 1); + if( p ){ + p->pageHash = 0; + sqlite3PagerUnref(p); + } + } +#endif + + sqlite3BitvecDestroy(pPager->pInJournal); + pPager->pInJournal = 0; + pPager->nRec = 0; + sqlite3PcacheCleanAll(pPager->pPCache); + sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize); + + if( pagerUseWal(pPager) ){ + /* Drop the WAL write-lock, if any. Also, if the connection was in + ** locking_mode=exclusive mode but is no longer, drop the EXCLUSIVE + ** lock held on the database file. + */ + rc2 = sqlite3WalEndWriteTransaction(pPager->pWal); + assert( rc2==SQLITE_OK ); + } + if( !pPager->exclusiveMode + && (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0)) + ){ + rc2 = pagerUnlockDb(pPager, SHARED_LOCK); + pPager->changeCountDone = 0; + } + pPager->eState = PAGER_READER; + pPager->setMaster = 0; + + return (rc==SQLITE_OK?rc2:rc); +} + +/* +** Execute a rollback if a transaction is active and unlock the +** database file. +** +** If the pager has already entered the ERROR state, do not attempt +** the rollback at this time. Instead, pager_unlock() is called. The +** call to pager_unlock() will discard all in-memory pages, unlock +** the database file and move the pager back to OPEN state. If this +** means that there is a hot-journal left in the file-system, the next +** connection to obtain a shared lock on the pager (which may be this one) +** will roll it back. +** +** If the pager has not already entered the ERROR state, but an IO or +** malloc error occurs during a rollback, then this will itself cause +** the pager to enter the ERROR state. Which will be cleared by the +** call to pager_unlock(), as described above. +*/ +static void pagerUnlockAndRollback(Pager *pPager){ + if( pPager->eState!=PAGER_ERROR && pPager->eState!=PAGER_OPEN ){ + assert( assert_pager_state(pPager) ); + if( pPager->eState>=PAGER_WRITER_LOCKED ){ + sqlite3BeginBenignMalloc(); + sqlite3PagerRollback(pPager); + sqlite3EndBenignMalloc(); + }else if( !pPager->exclusiveMode ){ + assert( pPager->eState==PAGER_READER ); + pager_end_transaction(pPager, 0); + } + } + pager_unlock(pPager); +} + +/* +** Parameter aData must point to a buffer of pPager->pageSize bytes +** of data. Compute and return a checksum based ont the contents of the +** page of data and the current value of pPager->cksumInit. +** +** This is not a real checksum. It is really just the sum of the +** random initial value (pPager->cksumInit) and every 200th byte +** of the page data, starting with byte offset (pPager->pageSize%200). +** Each byte is interpreted as an 8-bit unsigned integer. +** +** Changing the formula used to compute this checksum results in an +** incompatible journal file format. +** +** If journal corruption occurs due to a power failure, the most likely +** scenario is that one end or the other of the record will be changed. +** It is much less likely that the two ends of the journal record will be +** correct and the middle be corrupt. Thus, this "checksum" scheme, +** though fast and simple, catches the mostly likely kind of corruption. +*/ +static u32 pager_cksum(Pager *pPager, const u8 *aData){ + u32 cksum = pPager->cksumInit; /* Checksum value to return */ + int i = pPager->pageSize-200; /* Loop counter */ + while( i>0 ){ + cksum += aData[i]; + i -= 200; + } + return cksum; +} + +/* +** Report the current page size and number of reserved bytes back +** to the codec. +*/ +#ifdef SQLITE_HAS_CODEC +static void pagerReportSize(Pager *pPager){ + if( pPager->xCodecSizeChng ){ + pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize, + (int)pPager->nReserve); + } +} +#else +# define pagerReportSize(X) /* No-op if we do not support a codec */ +#endif + +/* +** Read a single page from either the journal file (if isMainJrnl==1) or +** from the sub-journal (if isMainJrnl==0) and playback that page. +** The page begins at offset *pOffset into the file. The *pOffset +** value is increased to the start of the next page in the journal. +** +** The main rollback journal uses checksums - the statement journal does +** not. +** +** If the page number of the page record read from the (sub-)journal file +** is greater than the current value of Pager.dbSize, then playback is +** skipped and SQLITE_OK is returned. +** +** If pDone is not NULL, then it is a record of pages that have already +** been played back. If the page at *pOffset has already been played back +** (if the corresponding pDone bit is set) then skip the playback. +** Make sure the pDone bit corresponding to the *pOffset page is set +** prior to returning. +** +** If the page record is successfully read from the (sub-)journal file +** and played back, then SQLITE_OK is returned. If an IO error occurs +** while reading the record from the (sub-)journal file or while writing +** to the database file, then the IO error code is returned. If data +** is successfully read from the (sub-)journal file but appears to be +** corrupted, SQLITE_DONE is returned. Data is considered corrupted in +** two circumstances: +** +** * If the record page-number is illegal (0 or PAGER_MJ_PGNO), or +** * If the record is being rolled back from the main journal file +** and the checksum field does not match the record content. +** +** Neither of these two scenarios are possible during a savepoint rollback. +** +** If this is a savepoint rollback, then memory may have to be dynamically +** allocated by this function. If this is the case and an allocation fails, +** SQLITE_NOMEM is returned. +*/ +static int pager_playback_one_page( + Pager *pPager, /* The pager being played back */ + i64 *pOffset, /* Offset of record to playback */ + Bitvec *pDone, /* Bitvec of pages already played back */ + int isMainJrnl, /* 1 -> main journal. 0 -> sub-journal. */ + int isSavepnt /* True for a savepoint rollback */ +){ + int rc; + PgHdr *pPg; /* An existing page in the cache */ + Pgno pgno; /* The page number of a page in journal */ + u32 cksum; /* Checksum used for sanity checking */ + char *aData; /* Temporary storage for the page */ + sqlite3_file *jfd; /* The file descriptor for the journal file */ + int isSynced; /* True if journal page is synced */ + + assert( (isMainJrnl&~1)==0 ); /* isMainJrnl is 0 or 1 */ + assert( (isSavepnt&~1)==0 ); /* isSavepnt is 0 or 1 */ + assert( isMainJrnl || pDone ); /* pDone always used on sub-journals */ + assert( isSavepnt || pDone==0 ); /* pDone never used on non-savepoint */ + + aData = pPager->pTmpSpace; + assert( aData ); /* Temp storage must have already been allocated */ + assert( pagerUseWal(pPager)==0 || (!isMainJrnl && isSavepnt) ); + + /* Either the state is greater than PAGER_WRITER_CACHEMOD (a transaction + ** or savepoint rollback done at the request of the caller) or this is + ** a hot-journal rollback. If it is a hot-journal rollback, the pager + ** is in state OPEN and holds an EXCLUSIVE lock. Hot-journal rollback + ** only reads from the main journal, not the sub-journal. + */ + assert( pPager->eState>=PAGER_WRITER_CACHEMOD + || (pPager->eState==PAGER_OPEN && pPager->eLock==EXCLUSIVE_LOCK) + ); + assert( pPager->eState>=PAGER_WRITER_CACHEMOD || isMainJrnl ); + + /* Read the page number and page data from the journal or sub-journal + ** file. Return an error code to the caller if an IO error occurs. + */ + jfd = isMainJrnl ? pPager->jfd : pPager->sjfd; + rc = read32bits(jfd, *pOffset, &pgno); + if( rc!=SQLITE_OK ) return rc; + rc = sqlite3OsRead(jfd, (u8*)aData, pPager->pageSize, (*pOffset)+4); + if( rc!=SQLITE_OK ) return rc; + *pOffset += pPager->pageSize + 4 + isMainJrnl*4; + + /* Sanity checking on the page. This is more important that I originally + ** thought. If a power failure occurs while the journal is being written, + ** it could cause invalid data to be written into the journal. We need to + ** detect this invalid data (with high probability) and ignore it. + */ + if( pgno==0 || pgno==PAGER_MJ_PGNO(pPager) ){ + assert( !isSavepnt ); + return SQLITE_DONE; + } + if( pgno>(Pgno)pPager->dbSize || sqlite3BitvecTest(pDone, pgno) ){ + return SQLITE_OK; + } + if( isMainJrnl ){ + rc = read32bits(jfd, (*pOffset)-4, &cksum); + if( rc ) return rc; + if( !isSavepnt && pager_cksum(pPager, (u8*)aData)!=cksum ){ + return SQLITE_DONE; + } + } + + /* If this page has already been played by before during the current + ** rollback, then don't bother to play it back again. + */ + if( pDone && (rc = sqlite3BitvecSet(pDone, pgno))!=SQLITE_OK ){ + return rc; + } + + /* When playing back page 1, restore the nReserve setting + */ + if( pgno==1 && pPager->nReserve!=((u8*)aData)[20] ){ + pPager->nReserve = ((u8*)aData)[20]; + pagerReportSize(pPager); + } + + /* If the pager is in CACHEMOD state, then there must be a copy of this + ** page in the pager cache. In this case just update the pager cache, + ** not the database file. The page is left marked dirty in this case. + ** + ** An exception to the above rule: If the database is in no-sync mode + ** and a page is moved during an incremental vacuum then the page may + ** not be in the pager cache. Later: if a malloc() or IO error occurs + ** during a Movepage() call, then the page may not be in the cache + ** either. So the condition described in the above paragraph is not + ** assert()able. + ** + ** If in WRITER_DBMOD, WRITER_FINISHED or OPEN state, then we update the + ** pager cache if it exists and the main file. The page is then marked + ** not dirty. Since this code is only executed in PAGER_OPEN state for + ** a hot-journal rollback, it is guaranteed that the page-cache is empty + ** if the pager is in OPEN state. + ** + ** Ticket #1171: The statement journal might contain page content that is + ** different from the page content at the start of the transaction. + ** This occurs when a page is changed prior to the start of a statement + ** then changed again within the statement. When rolling back such a + ** statement we must not write to the original database unless we know + ** for certain that original page contents are synced into the main rollback + ** journal. Otherwise, a power loss might leave modified data in the + ** database file without an entry in the rollback journal that can + ** restore the database to its original form. Two conditions must be + ** met before writing to the database files. (1) the database must be + ** locked. (2) we know that the original page content is fully synced + ** in the main journal either because the page is not in cache or else + ** the page is marked as needSync==0. + ** + ** 2008-04-14: When attempting to vacuum a corrupt database file, it + ** is possible to fail a statement on a database that does not yet exist. + ** Do not attempt to write if database file has never been opened. + */ + if( pagerUseWal(pPager) ){ + pPg = 0; + }else{ + pPg = pager_lookup(pPager, pgno); + } + assert( pPg || !MEMDB ); + assert( pPager->eState!=PAGER_OPEN || pPg==0 ); + PAGERTRACE(("PLAYBACK %d page %d hash(%08x) %s\n", + PAGERID(pPager), pgno, pager_datahash(pPager->pageSize, (u8*)aData), + (isMainJrnl?"main-journal":"sub-journal") + )); + if( isMainJrnl ){ + isSynced = pPager->noSync || (*pOffset <= pPager->journalHdr); + }else{ + isSynced = (pPg==0 || 0==(pPg->flags & PGHDR_NEED_SYNC)); + } + if( isOpen(pPager->fd) + && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) + && isSynced + ){ + i64 ofst = (pgno-1)*(i64)pPager->pageSize; + testcase( !isSavepnt && pPg!=0 && (pPg->flags&PGHDR_NEED_SYNC)!=0 ); + assert( !pagerUseWal(pPager) ); + rc = sqlite3OsWrite(pPager->fd, (u8*)aData, pPager->pageSize, ofst); + if( pgno>pPager->dbFileSize ){ + pPager->dbFileSize = pgno; + } + if( pPager->pBackup ){ + CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM); + sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData); + CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM, aData); + } + }else if( !isMainJrnl && pPg==0 ){ + /* If this is a rollback of a savepoint and data was not written to + ** the database and the page is not in-memory, there is a potential + ** problem. When the page is next fetched by the b-tree layer, it + ** will be read from the database file, which may or may not be + ** current. + ** + ** There are a couple of different ways this can happen. All are quite + ** obscure. When running in synchronous mode, this can only happen + ** if the page is on the free-list at the start of the transaction, then + ** populated, then moved using sqlite3PagerMovepage(). + ** + ** The solution is to add an in-memory page to the cache containing + ** the data just read from the sub-journal. Mark the page as dirty + ** and if the pager requires a journal-sync, then mark the page as + ** requiring a journal-sync before it is written. + */ + assert( isSavepnt ); + assert( pPager->doNotSpill==0 ); + pPager->doNotSpill++; + rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1); + assert( pPager->doNotSpill==1 ); + pPager->doNotSpill--; + if( rc!=SQLITE_OK ) return rc; + pPg->flags &= ~PGHDR_NEED_READ; + sqlite3PcacheMakeDirty(pPg); + } + if( pPg ){ + /* No page should ever be explicitly rolled back that is in use, except + ** for page 1 which is held in use in order to keep the lock on the + ** database active. However such a page may be rolled back as a result + ** of an internal error resulting in an automatic call to + ** sqlite3PagerRollback(). + */ + void *pData; + pData = pPg->pData; + memcpy(pData, (u8*)aData, pPager->pageSize); + pPager->xReiniter(pPg); + if( isMainJrnl && (!isSavepnt || *pOffset<=pPager->journalHdr) ){ + /* If the contents of this page were just restored from the main + ** journal file, then its content must be as they were when the + ** transaction was first opened. In this case we can mark the page + ** as clean, since there will be no need to write it out to the + ** database. + ** + ** There is one exception to this rule. If the page is being rolled + ** back as part of a savepoint (or statement) rollback from an + ** unsynced portion of the main journal file, then it is not safe + ** to mark the page as clean. This is because marking the page as + ** clean will clear the PGHDR_NEED_SYNC flag. Since the page is + ** already in the journal file (recorded in Pager.pInJournal) and + ** the PGHDR_NEED_SYNC flag is cleared, if the page is written to + ** again within this transaction, it will be marked as dirty but + ** the PGHDR_NEED_SYNC flag will not be set. It could then potentially + ** be written out into the database file before its journal file + ** segment is synced. If a crash occurs during or following this, + ** database corruption may ensue. + */ + assert( !pagerUseWal(pPager) ); + sqlite3PcacheMakeClean(pPg); + } + pager_set_pagehash(pPg); + + /* If this was page 1, then restore the value of Pager.dbFileVers. + ** Do this before any decoding. */ + if( pgno==1 ){ + memcpy(&pPager->dbFileVers, &((u8*)pData)[24],sizeof(pPager->dbFileVers)); + } + + /* Decode the page just read from disk */ + CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM); + sqlite3PcacheRelease(pPg); + } + return rc; +} + +/* +** Parameter zMaster is the name of a master journal file. A single journal +** file that referred to the master journal file has just been rolled back. +** This routine checks if it is possible to delete the master journal file, +** and does so if it is. +** +** Argument zMaster may point to Pager.pTmpSpace. So that buffer is not +** available for use within this function. +** +** When a master journal file is created, it is populated with the names +** of all of its child journals, one after another, formatted as utf-8 +** encoded text. The end of each child journal file is marked with a +** nul-terminator byte (0x00). i.e. the entire contents of a master journal +** file for a transaction involving two databases might be: +** +** "/home/bill/a.db-journal\x00/home/bill/b.db-journal\x00" +** +** A master journal file may only be deleted once all of its child +** journals have been rolled back. +** +** This function reads the contents of the master-journal file into +** memory and loops through each of the child journal names. For +** each child journal, it checks if: +** +** * if the child journal exists, and if so +** * if the child journal contains a reference to master journal +** file zMaster +** +** If a child journal can be found that matches both of the criteria +** above, this function returns without doing anything. Otherwise, if +** no such child journal can be found, file zMaster is deleted from +** the file-system using sqlite3OsDelete(). +** +** If an IO error within this function, an error code is returned. This +** function allocates memory by calling sqlite3Malloc(). If an allocation +** fails, SQLITE_NOMEM is returned. Otherwise, if no IO or malloc errors +** occur, SQLITE_OK is returned. +** +** TODO: This function allocates a single block of memory to load +** the entire contents of the master journal file. This could be +** a couple of kilobytes or so - potentially larger than the page +** size. +*/ +static int pager_delmaster(Pager *pPager, const char *zMaster){ + sqlite3_vfs *pVfs = pPager->pVfs; + int rc; /* Return code */ + sqlite3_file *pMaster; /* Malloc'd master-journal file descriptor */ + sqlite3_file *pJournal; /* Malloc'd child-journal file descriptor */ + char *zMasterJournal = 0; /* Contents of master journal file */ + i64 nMasterJournal; /* Size of master journal file */ + char *zJournal; /* Pointer to one journal within MJ file */ + char *zMasterPtr; /* Space to hold MJ filename from a journal file */ + int nMasterPtr; /* Amount of space allocated to zMasterPtr[] */ + + /* Allocate space for both the pJournal and pMaster file descriptors. + ** If successful, open the master journal file for reading. + */ + pMaster = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile * 2); + pJournal = (sqlite3_file *)(((u8 *)pMaster) + pVfs->szOsFile); + if( !pMaster ){ + rc = SQLITE_NOMEM; + }else{ + const int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL); + rc = sqlite3OsOpen(pVfs, zMaster, pMaster, flags, 0); + } + if( rc!=SQLITE_OK ) goto delmaster_out; + + /* Load the entire master journal file into space obtained from + ** sqlite3_malloc() and pointed to by zMasterJournal. Also obtain + ** sufficient space (in zMasterPtr) to hold the names of master + ** journal files extracted from regular rollback-journals. + */ + rc = sqlite3OsFileSize(pMaster, &nMasterJournal); + if( rc!=SQLITE_OK ) goto delmaster_out; + nMasterPtr = pVfs->mxPathname+1; + zMasterJournal = sqlite3Malloc((int)nMasterJournal + nMasterPtr + 1); + if( !zMasterJournal ){ + rc = SQLITE_NOMEM; + goto delmaster_out; + } + zMasterPtr = &zMasterJournal[nMasterJournal+1]; + rc = sqlite3OsRead(pMaster, zMasterJournal, (int)nMasterJournal, 0); + if( rc!=SQLITE_OK ) goto delmaster_out; + zMasterJournal[nMasterJournal] = 0; + + zJournal = zMasterJournal; + while( (zJournal-zMasterJournal)pageSize bytes). +** If the file on disk is currently larger than nPage pages, then use the VFS +** xTruncate() method to truncate it. +** +** Or, it might might be the case that the file on disk is smaller than +** nPage pages. Some operating system implementations can get confused if +** you try to truncate a file to some size that is larger than it +** currently is, so detect this case and write a single zero byte to +** the end of the new file instead. +** +** If successful, return SQLITE_OK. If an IO error occurs while modifying +** the database file, return the error code to the caller. +*/ +static int pager_truncate(Pager *pPager, Pgno nPage){ + int rc = SQLITE_OK; + assert( pPager->eState!=PAGER_ERROR ); + assert( pPager->eState!=PAGER_READER ); + + if( isOpen(pPager->fd) + && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) + ){ + i64 currentSize, newSize; + int szPage = pPager->pageSize; + assert( pPager->eLock==EXCLUSIVE_LOCK ); + /* TODO: Is it safe to use Pager.dbFileSize here? */ + rc = sqlite3OsFileSize(pPager->fd, ¤tSize); + newSize = szPage*(i64)nPage; + if( rc==SQLITE_OK && currentSize!=newSize ){ + if( currentSize>newSize ){ + rc = sqlite3OsTruncate(pPager->fd, newSize); + }else if( (currentSize+szPage)<=newSize ){ + char *pTmp = pPager->pTmpSpace; + memset(pTmp, 0, szPage); + testcase( (newSize-szPage) == currentSize ); + testcase( (newSize-szPage) > currentSize ); + rc = sqlite3OsWrite(pPager->fd, pTmp, szPage, newSize-szPage); + } + if( rc==SQLITE_OK ){ + pPager->dbFileSize = nPage; + } + } + } + return rc; +} + +/* +** Set the value of the Pager.sectorSize variable for the given +** pager based on the value returned by the xSectorSize method +** of the open database file. The sector size will be used used +** to determine the size and alignment of journal header and +** master journal pointers within created journal files. +** +** For temporary files the effective sector size is always 512 bytes. +** +** Otherwise, for non-temporary files, the effective sector size is +** the value returned by the xSectorSize() method rounded up to 32 if +** it is less than 32, or rounded down to MAX_SECTOR_SIZE if it +** is greater than MAX_SECTOR_SIZE. +** +** If the file has the SQLITE_IOCAP_POWERSAFE_OVERWRITE property, then set +** the effective sector size to its minimum value (512). The purpose of +** pPager->sectorSize is to define the "blast radius" of bytes that +** might change if a crash occurs while writing to a single byte in +** that range. But with POWERSAFE_OVERWRITE, the blast radius is zero +** (that is what POWERSAFE_OVERWRITE means), so we minimize the sector +** size. For backwards compatibility of the rollback journal file format, +** we cannot reduce the effective sector size below 512. +*/ +static void setSectorSize(Pager *pPager){ + assert( isOpen(pPager->fd) || pPager->tempFile ); + + if( pPager->tempFile + || (sqlite3OsDeviceCharacteristics(pPager->fd) & + SQLITE_IOCAP_POWERSAFE_OVERWRITE)!=0 + ){ + /* Sector size doesn't matter for temporary files. Also, the file + ** may not have been opened yet, in which case the OsSectorSize() + ** call will segfault. */ + pPager->sectorSize = 512; + }else{ + pPager->sectorSize = sqlite3OsSectorSize(pPager->fd); + if( pPager->sectorSize<32 ){ + pPager->sectorSize = 512; + } + if( pPager->sectorSize>MAX_SECTOR_SIZE ){ + assert( MAX_SECTOR_SIZE>=512 ); + pPager->sectorSize = MAX_SECTOR_SIZE; + } + } +} + +/* +** Playback the journal and thus restore the database file to +** the state it was in before we started making changes. +** +** The journal file format is as follows: +** +** (1) 8 byte prefix. A copy of aJournalMagic[]. +** (2) 4 byte big-endian integer which is the number of valid page records +** in the journal. If this value is 0xffffffff, then compute the +** number of page records from the journal size. +** (3) 4 byte big-endian integer which is the initial value for the +** sanity checksum. +** (4) 4 byte integer which is the number of pages to truncate the +** database to during a rollback. +** (5) 4 byte big-endian integer which is the sector size. The header +** is this many bytes in size. +** (6) 4 byte big-endian integer which is the page size. +** (7) zero padding out to the next sector size. +** (8) Zero or more pages instances, each as follows: +** + 4 byte page number. +** + pPager->pageSize bytes of data. +** + 4 byte checksum +** +** When we speak of the journal header, we mean the first 7 items above. +** Each entry in the journal is an instance of the 8th item. +** +** Call the value from the second bullet "nRec". nRec is the number of +** valid page entries in the journal. In most cases, you can compute the +** value of nRec from the size of the journal file. But if a power +** failure occurred while the journal was being written, it could be the +** case that the size of the journal file had already been increased but +** the extra entries had not yet made it safely to disk. In such a case, +** the value of nRec computed from the file size would be too large. For +** that reason, we always use the nRec value in the header. +** +** If the nRec value is 0xffffffff it means that nRec should be computed +** from the file size. This value is used when the user selects the +** no-sync option for the journal. A power failure could lead to corruption +** in this case. But for things like temporary table (which will be +** deleted when the power is restored) we don't care. +** +** If the file opened as the journal file is not a well-formed +** journal file then all pages up to the first corrupted page are rolled +** back (or no pages if the journal header is corrupted). The journal file +** is then deleted and SQLITE_OK returned, just as if no corruption had +** been encountered. +** +** If an I/O or malloc() error occurs, the journal-file is not deleted +** and an error code is returned. +** +** The isHot parameter indicates that we are trying to rollback a journal +** that might be a hot journal. Or, it could be that the journal is +** preserved because of JOURNALMODE_PERSIST or JOURNALMODE_TRUNCATE. +** If the journal really is hot, reset the pager cache prior rolling +** back any content. If the journal is merely persistent, no reset is +** needed. +*/ +static int pager_playback(Pager *pPager, int isHot){ + sqlite3_vfs *pVfs = pPager->pVfs; + i64 szJ; /* Size of the journal file in bytes */ + u32 nRec; /* Number of Records in the journal */ + u32 u; /* Unsigned loop counter */ + Pgno mxPg = 0; /* Size of the original file in pages */ + int rc; /* Result code of a subroutine */ + int res = 1; /* Value returned by sqlite3OsAccess() */ + char *zMaster = 0; /* Name of master journal file if any */ + int needPagerReset; /* True to reset page prior to first page rollback */ + + /* Figure out how many records are in the journal. Abort early if + ** the journal is empty. + */ + assert( isOpen(pPager->jfd) ); + rc = sqlite3OsFileSize(pPager->jfd, &szJ); + if( rc!=SQLITE_OK ){ + goto end_playback; + } + + /* Read the master journal name from the journal, if it is present. + ** If a master journal file name is specified, but the file is not + ** present on disk, then the journal is not hot and does not need to be + ** played back. + ** + ** TODO: Technically the following is an error because it assumes that + ** buffer Pager.pTmpSpace is (mxPathname+1) bytes or larger. i.e. that + ** (pPager->pageSize >= pPager->pVfs->mxPathname+1). Using os_unix.c, + ** mxPathname is 512, which is the same as the minimum allowable value + ** for pageSize. + */ + zMaster = pPager->pTmpSpace; + rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1); + if( rc==SQLITE_OK && zMaster[0] ){ + rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res); + } + zMaster = 0; + if( rc!=SQLITE_OK || !res ){ + goto end_playback; + } + pPager->journalOff = 0; + needPagerReset = isHot; + + /* This loop terminates either when a readJournalHdr() or + ** pager_playback_one_page() call returns SQLITE_DONE or an IO error + ** occurs. + */ + while( 1 ){ + /* Read the next journal header from the journal file. If there are + ** not enough bytes left in the journal file for a complete header, or + ** it is corrupted, then a process must have failed while writing it. + ** This indicates nothing more needs to be rolled back. + */ + rc = readJournalHdr(pPager, isHot, szJ, &nRec, &mxPg); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_DONE ){ + rc = SQLITE_OK; + } + goto end_playback; + } + + /* If nRec is 0xffffffff, then this journal was created by a process + ** working in no-sync mode. This means that the rest of the journal + ** file consists of pages, there are no more journal headers. Compute + ** the value of nRec based on this assumption. + */ + if( nRec==0xffffffff ){ + assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ); + nRec = (int)((szJ - JOURNAL_HDR_SZ(pPager))/JOURNAL_PG_SZ(pPager)); + } + + /* If nRec is 0 and this rollback is of a transaction created by this + ** process and if this is the final header in the journal, then it means + ** that this part of the journal was being filled but has not yet been + ** synced to disk. Compute the number of pages based on the remaining + ** size of the file. + ** + ** The third term of the test was added to fix ticket #2565. + ** When rolling back a hot journal, nRec==0 always means that the next + ** chunk of the journal contains zero pages to be rolled back. But + ** when doing a ROLLBACK and the nRec==0 chunk is the last chunk in + ** the journal, it means that the journal might contain additional + ** pages that need to be rolled back and that the number of pages + ** should be computed based on the journal file size. + */ + if( nRec==0 && !isHot && + pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff ){ + nRec = (int)((szJ - pPager->journalOff) / JOURNAL_PG_SZ(pPager)); + } + + /* If this is the first header read from the journal, truncate the + ** database file back to its original size. + */ + if( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){ + rc = pager_truncate(pPager, mxPg); + if( rc!=SQLITE_OK ){ + goto end_playback; + } + pPager->dbSize = mxPg; + } + + /* Copy original pages out of the journal and back into the + ** database file and/or page cache. + */ + for(u=0; ujournalOff,0,1,0); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_DONE ){ + pPager->journalOff = szJ; + break; + }else if( rc==SQLITE_IOERR_SHORT_READ ){ + /* If the journal has been truncated, simply stop reading and + ** processing the journal. This might happen if the journal was + ** not completely written and synced prior to a crash. In that + ** case, the database should have never been written in the + ** first place so it is OK to simply abandon the rollback. */ + rc = SQLITE_OK; + goto end_playback; + }else{ + /* If we are unable to rollback, quit and return the error + ** code. This will cause the pager to enter the error state + ** so that no further harm will be done. Perhaps the next + ** process to come along will be able to rollback the database. + */ + goto end_playback; + } + } + } + } + /*NOTREACHED*/ + assert( 0 ); + +end_playback: + /* Following a rollback, the database file should be back in its original + ** state prior to the start of the transaction, so invoke the + ** SQLITE_FCNTL_DB_UNCHANGED file-control method to disable the + ** assertion that the transaction counter was modified. + */ +#ifdef SQLITE_DEBUG + if( pPager->fd->pMethods ){ + sqlite3OsFileControlHint(pPager->fd,SQLITE_FCNTL_DB_UNCHANGED,0); + } +#endif + + /* If this playback is happening automatically as a result of an IO or + ** malloc error that occurred after the change-counter was updated but + ** before the transaction was committed, then the change-counter + ** modification may just have been reverted. If this happens in exclusive + ** mode, then subsequent transactions performed by the connection will not + ** update the change-counter at all. This may lead to cache inconsistency + ** problems for other processes at some point in the future. So, just + ** in case this has happened, clear the changeCountDone flag now. + */ + pPager->changeCountDone = pPager->tempFile; + + if( rc==SQLITE_OK ){ + zMaster = pPager->pTmpSpace; + rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1); + testcase( rc!=SQLITE_OK ); + } + if( rc==SQLITE_OK + && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) + ){ + rc = sqlite3PagerSync(pPager); + } + if( rc==SQLITE_OK ){ + rc = pager_end_transaction(pPager, zMaster[0]!='\0'); + testcase( rc!=SQLITE_OK ); + } + if( rc==SQLITE_OK && zMaster[0] && res ){ + /* If there was a master journal and this routine will return success, + ** see if it is possible to delete the master journal. + */ + rc = pager_delmaster(pPager, zMaster); + testcase( rc!=SQLITE_OK ); + } + + /* The Pager.sectorSize variable may have been updated while rolling + ** back a journal created by a process with a different sector size + ** value. Reset it to the correct value for this process. + */ + setSectorSize(pPager); + return rc; +} + + +/* +** Read the content for page pPg out of the database file and into +** pPg->pData. A shared lock or greater must be held on the database +** file before this function is called. +** +** If page 1 is read, then the value of Pager.dbFileVers[] is set to +** the value read from the database file. +** +** If an IO error occurs, then the IO error is returned to the caller. +** Otherwise, SQLITE_OK is returned. +*/ +static int readDbPage(PgHdr *pPg){ + Pager *pPager = pPg->pPager; /* Pager object associated with page pPg */ + Pgno pgno = pPg->pgno; /* Page number to read */ + int rc = SQLITE_OK; /* Return code */ + int isInWal = 0; /* True if page is in log file */ + int pgsz = pPager->pageSize; /* Number of bytes to read */ + + assert( pPager->eState>=PAGER_READER && !MEMDB ); + assert( isOpen(pPager->fd) ); + + if( NEVER(!isOpen(pPager->fd)) ){ + assert( pPager->tempFile ); + memset(pPg->pData, 0, pPager->pageSize); + return SQLITE_OK; + } + + if( pagerUseWal(pPager) ){ + /* Try to pull the page from the write-ahead log. */ + rc = sqlite3WalRead(pPager->pWal, pgno, &isInWal, pgsz, pPg->pData); + } + if( rc==SQLITE_OK && !isInWal ){ + i64 iOffset = (pgno-1)*(i64)pPager->pageSize; + rc = sqlite3OsRead(pPager->fd, pPg->pData, pgsz, iOffset); + if( rc==SQLITE_IOERR_SHORT_READ ){ + rc = SQLITE_OK; + } + } + + if( pgno==1 ){ + if( rc ){ + /* If the read is unsuccessful, set the dbFileVers[] to something + ** that will never be a valid file version. dbFileVers[] is a copy + ** of bytes 24..39 of the database. Bytes 28..31 should always be + ** zero or the size of the database in page. Bytes 32..35 and 35..39 + ** should be page numbers which are never 0xffffffff. So filling + ** pPager->dbFileVers[] with all 0xff bytes should suffice. + ** + ** For an encrypted database, the situation is more complex: bytes + ** 24..39 of the database are white noise. But the probability of + ** white noising equaling 16 bytes of 0xff is vanishingly small so + ** we should still be ok. + */ + memset(pPager->dbFileVers, 0xff, sizeof(pPager->dbFileVers)); + }else{ + u8 *dbFileVers = &((u8*)pPg->pData)[24]; + memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers)); + } + } + CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM); + + PAGER_INCR(sqlite3_pager_readdb_count); + PAGER_INCR(pPager->nRead); + IOTRACE(("PGIN %p %d\n", pPager, pgno)); + PAGERTRACE(("FETCH %d page %d hash(%08x)\n", + PAGERID(pPager), pgno, pager_pagehash(pPg))); + + return rc; +} + +/* +** Update the value of the change-counter at offsets 24 and 92 in +** the header and the sqlite version number at offset 96. +** +** This is an unconditional update. See also the pager_incr_changecounter() +** routine which only updates the change-counter if the update is actually +** needed, as determined by the pPager->changeCountDone state variable. +*/ +static void pager_write_changecounter(PgHdr *pPg){ + u32 change_counter; + + /* Increment the value just read and write it back to byte 24. */ + change_counter = sqlite3Get4byte((u8*)pPg->pPager->dbFileVers)+1; + put32bits(((char*)pPg->pData)+24, change_counter); + + /* Also store the SQLite version number in bytes 96..99 and in + ** bytes 92..95 store the change counter for which the version number + ** is valid. */ + put32bits(((char*)pPg->pData)+92, change_counter); + put32bits(((char*)pPg->pData)+96, SQLITE_VERSION_NUMBER); +} + +#ifndef SQLITE_OMIT_WAL +/* +** This function is invoked once for each page that has already been +** written into the log file when a WAL transaction is rolled back. +** Parameter iPg is the page number of said page. The pCtx argument +** is actually a pointer to the Pager structure. +** +** If page iPg is present in the cache, and has no outstanding references, +** it is discarded. Otherwise, if there are one or more outstanding +** references, the page content is reloaded from the database. If the +** attempt to reload content from the database is required and fails, +** return an SQLite error code. Otherwise, SQLITE_OK. +*/ +static int pagerUndoCallback(void *pCtx, Pgno iPg){ + int rc = SQLITE_OK; + Pager *pPager = (Pager *)pCtx; + PgHdr *pPg; + + pPg = sqlite3PagerLookup(pPager, iPg); + if( pPg ){ + if( sqlite3PcachePageRefcount(pPg)==1 ){ + sqlite3PcacheDrop(pPg); + }else{ + rc = readDbPage(pPg); + if( rc==SQLITE_OK ){ + pPager->xReiniter(pPg); + } + sqlite3PagerUnref(pPg); + } + } + + /* Normally, if a transaction is rolled back, any backup processes are + ** updated as data is copied out of the rollback journal and into the + ** database. This is not generally possible with a WAL database, as + ** rollback involves simply truncating the log file. Therefore, if one + ** or more frames have already been written to the log (and therefore + ** also copied into the backup databases) as part of this transaction, + ** the backups must be restarted. + */ + sqlite3BackupRestart(pPager->pBackup); + + return rc; +} + +/* +** This function is called to rollback a transaction on a WAL database. +*/ +static int pagerRollbackWal(Pager *pPager){ + int rc; /* Return Code */ + PgHdr *pList; /* List of dirty pages to revert */ + + /* For all pages in the cache that are currently dirty or have already + ** been written (but not committed) to the log file, do one of the + ** following: + ** + ** + Discard the cached page (if refcount==0), or + ** + Reload page content from the database (if refcount>0). + */ + pPager->dbSize = pPager->dbOrigSize; + rc = sqlite3WalUndo(pPager->pWal, pagerUndoCallback, (void *)pPager); + pList = sqlite3PcacheDirtyList(pPager->pPCache); + while( pList && rc==SQLITE_OK ){ + PgHdr *pNext = pList->pDirty; + rc = pagerUndoCallback((void *)pPager, pList->pgno); + pList = pNext; + } + + return rc; +} + +/* +** This function is a wrapper around sqlite3WalFrames(). As well as logging +** the contents of the list of pages headed by pList (connected by pDirty), +** this function notifies any active backup processes that the pages have +** changed. +** +** The list of pages passed into this routine is always sorted by page number. +** Hence, if page 1 appears anywhere on the list, it will be the first page. +*/ +static int pagerWalFrames( + Pager *pPager, /* Pager object */ + PgHdr *pList, /* List of frames to log */ + Pgno nTruncate, /* Database size after this commit */ + int isCommit /* True if this is a commit */ +){ + int rc; /* Return code */ +#if defined(SQLITE_DEBUG) || defined(SQLITE_CHECK_PAGES) + PgHdr *p; /* For looping over pages */ +#endif + + assert( pPager->pWal ); + assert( pList ); +#ifdef SQLITE_DEBUG + /* Verify that the page list is in accending order */ + for(p=pList; p && p->pDirty; p=p->pDirty){ + assert( p->pgno < p->pDirty->pgno ); + } +#endif + + if( isCommit ){ + /* If a WAL transaction is being committed, there is no point in writing + ** any pages with page numbers greater than nTruncate into the WAL file. + ** They will never be read by any client. So remove them from the pDirty + ** list here. */ + PgHdr *p; + PgHdr **ppNext = &pList; + for(p=pList; (*ppNext = p); p=p->pDirty){ + if( p->pgno<=nTruncate ) ppNext = &p->pDirty; + } + assert( pList ); + } + + if( pList->pgno==1 ) pager_write_changecounter(pList); + rc = sqlite3WalFrames(pPager->pWal, + pPager->pageSize, pList, nTruncate, isCommit, pPager->walSyncFlags + ); + if( rc==SQLITE_OK && pPager->pBackup ){ + PgHdr *p; + for(p=pList; p; p=p->pDirty){ + sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData); + } + } + +#ifdef SQLITE_CHECK_PAGES + pList = sqlite3PcacheDirtyList(pPager->pPCache); + for(p=pList; p; p=p->pDirty){ + pager_set_pagehash(p); + } +#endif + + return rc; +} + +/* +** Begin a read transaction on the WAL. +** +** This routine used to be called "pagerOpenSnapshot()" because it essentially +** makes a snapshot of the database at the current point in time and preserves +** that snapshot for use by the reader in spite of concurrently changes by +** other writers or checkpointers. +*/ +static int pagerBeginReadTransaction(Pager *pPager){ + int rc; /* Return code */ + int changed = 0; /* True if cache must be reset */ + + assert( pagerUseWal(pPager) ); + assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER ); + + /* sqlite3WalEndReadTransaction() was not called for the previous + ** transaction in locking_mode=EXCLUSIVE. So call it now. If we + ** are in locking_mode=NORMAL and EndRead() was previously called, + ** the duplicate call is harmless. + */ + sqlite3WalEndReadTransaction(pPager->pWal); + + rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed); + if( rc!=SQLITE_OK || changed ){ + pager_reset(pPager); + } + + return rc; +} +#endif + +/* +** This function is called as part of the transition from PAGER_OPEN +** to PAGER_READER state to determine the size of the database file +** in pages (assuming the page size currently stored in Pager.pageSize). +** +** If no error occurs, SQLITE_OK is returned and the size of the database +** in pages is stored in *pnPage. Otherwise, an error code (perhaps +** SQLITE_IOERR_FSTAT) is returned and *pnPage is left unmodified. +*/ +static int pagerPagecount(Pager *pPager, Pgno *pnPage){ + Pgno nPage; /* Value to return via *pnPage */ + + /* Query the WAL sub-system for the database size. The WalDbsize() + ** function returns zero if the WAL is not open (i.e. Pager.pWal==0), or + ** if the database size is not available. The database size is not + ** available from the WAL sub-system if the log file is empty or + ** contains no valid committed transactions. + */ + assert( pPager->eState==PAGER_OPEN ); + assert( pPager->eLock>=SHARED_LOCK || pPager->noReadlock ); + nPage = sqlite3WalDbsize(pPager->pWal); + + /* If the database size was not available from the WAL sub-system, + ** determine it based on the size of the database file. If the size + ** of the database file is not an integer multiple of the page-size, + ** round down to the nearest page. Except, any file larger than 0 + ** bytes in size is considered to contain at least one page. + */ + if( nPage==0 ){ + i64 n = 0; /* Size of db file in bytes */ + assert( isOpen(pPager->fd) || pPager->tempFile ); + if( isOpen(pPager->fd) ){ + int rc = sqlite3OsFileSize(pPager->fd, &n); + if( rc!=SQLITE_OK ){ + return rc; + } + } + nPage = (Pgno)((n+pPager->pageSize-1) / pPager->pageSize); + } + + /* If the current number of pages in the file is greater than the + ** configured maximum pager number, increase the allowed limit so + ** that the file can be read. + */ + if( nPage>pPager->mxPgno ){ + pPager->mxPgno = (Pgno)nPage; + } + + *pnPage = nPage; + return SQLITE_OK; +} + +#ifndef SQLITE_OMIT_WAL +/* +** Check if the *-wal file that corresponds to the database opened by pPager +** exists if the database is not empy, or verify that the *-wal file does +** not exist (by deleting it) if the database file is empty. +** +** If the database is not empty and the *-wal file exists, open the pager +** in WAL mode. If the database is empty or if no *-wal file exists and +** if no error occurs, make sure Pager.journalMode is not set to +** PAGER_JOURNALMODE_WAL. +** +** Return SQLITE_OK or an error code. +** +** The caller must hold a SHARED lock on the database file to call this +** function. Because an EXCLUSIVE lock on the db file is required to delete +** a WAL on a none-empty database, this ensures there is no race condition +** between the xAccess() below and an xDelete() being executed by some +** other connection. +*/ +static int pagerOpenWalIfPresent(Pager *pPager){ + int rc = SQLITE_OK; + assert( pPager->eState==PAGER_OPEN ); + assert( pPager->eLock>=SHARED_LOCK || pPager->noReadlock ); + + if( !pPager->tempFile ){ + int isWal; /* True if WAL file exists */ + Pgno nPage; /* Size of the database file */ + + rc = pagerPagecount(pPager, &nPage); + if( rc ) return rc; + if( nPage==0 ){ + rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0); + isWal = 0; + }else{ + rc = sqlite3OsAccess( + pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &isWal + ); + } + if( rc==SQLITE_OK ){ + if( isWal ){ + testcase( sqlite3PcachePagecount(pPager->pPCache)==0 ); + rc = sqlite3PagerOpenWal(pPager, 0); + }else if( pPager->journalMode==PAGER_JOURNALMODE_WAL ){ + pPager->journalMode = PAGER_JOURNALMODE_DELETE; + } + } + } + return rc; +} +#endif + +/* +** Playback savepoint pSavepoint. Or, if pSavepoint==NULL, then playback +** the entire master journal file. The case pSavepoint==NULL occurs when +** a ROLLBACK TO command is invoked on a SAVEPOINT that is a transaction +** savepoint. +** +** When pSavepoint is not NULL (meaning a non-transaction savepoint is +** being rolled back), then the rollback consists of up to three stages, +** performed in the order specified: +** +** * Pages are played back from the main journal starting at byte +** offset PagerSavepoint.iOffset and continuing to +** PagerSavepoint.iHdrOffset, or to the end of the main journal +** file if PagerSavepoint.iHdrOffset is zero. +** +** * If PagerSavepoint.iHdrOffset is not zero, then pages are played +** back starting from the journal header immediately following +** PagerSavepoint.iHdrOffset to the end of the main journal file. +** +** * Pages are then played back from the sub-journal file, starting +** with the PagerSavepoint.iSubRec and continuing to the end of +** the journal file. +** +** Throughout the rollback process, each time a page is rolled back, the +** corresponding bit is set in a bitvec structure (variable pDone in the +** implementation below). This is used to ensure that a page is only +** rolled back the first time it is encountered in either journal. +** +** If pSavepoint is NULL, then pages are only played back from the main +** journal file. There is no need for a bitvec in this case. +** +** In either case, before playback commences the Pager.dbSize variable +** is reset to the value that it held at the start of the savepoint +** (or transaction). No page with a page-number greater than this value +** is played back. If one is encountered it is simply skipped. +*/ +static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){ + i64 szJ; /* Effective size of the main journal */ + i64 iHdrOff; /* End of first segment of main-journal records */ + int rc = SQLITE_OK; /* Return code */ + Bitvec *pDone = 0; /* Bitvec to ensure pages played back only once */ + + assert( pPager->eState!=PAGER_ERROR ); + assert( pPager->eState>=PAGER_WRITER_LOCKED ); + + /* Allocate a bitvec to use to store the set of pages rolled back */ + if( pSavepoint ){ + pDone = sqlite3BitvecCreate(pSavepoint->nOrig); + if( !pDone ){ + return SQLITE_NOMEM; + } + } + + /* Set the database size back to the value it was before the savepoint + ** being reverted was opened. + */ + pPager->dbSize = pSavepoint ? pSavepoint->nOrig : pPager->dbOrigSize; + pPager->changeCountDone = pPager->tempFile; + + if( !pSavepoint && pagerUseWal(pPager) ){ + return pagerRollbackWal(pPager); + } + + /* Use pPager->journalOff as the effective size of the main rollback + ** journal. The actual file might be larger than this in + ** PAGER_JOURNALMODE_TRUNCATE or PAGER_JOURNALMODE_PERSIST. But anything + ** past pPager->journalOff is off-limits to us. + */ + szJ = pPager->journalOff; + assert( pagerUseWal(pPager)==0 || szJ==0 ); + + /* Begin by rolling back records from the main journal starting at + ** PagerSavepoint.iOffset and continuing to the next journal header. + ** There might be records in the main journal that have a page number + ** greater than the current database size (pPager->dbSize) but those + ** will be skipped automatically. Pages are added to pDone as they + ** are played back. + */ + if( pSavepoint && !pagerUseWal(pPager) ){ + iHdrOff = pSavepoint->iHdrOffset ? pSavepoint->iHdrOffset : szJ; + pPager->journalOff = pSavepoint->iOffset; + while( rc==SQLITE_OK && pPager->journalOffjournalOff, pDone, 1, 1); + } + assert( rc!=SQLITE_DONE ); + }else{ + pPager->journalOff = 0; + } + + /* Continue rolling back records out of the main journal starting at + ** the first journal header seen and continuing until the effective end + ** of the main journal file. Continue to skip out-of-range pages and + ** continue adding pages rolled back to pDone. + */ + while( rc==SQLITE_OK && pPager->journalOffjournalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff" + ** test is related to ticket #2565. See the discussion in the + ** pager_playback() function for additional information. + */ + if( nJRec==0 + && pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff + ){ + nJRec = (u32)((szJ - pPager->journalOff)/JOURNAL_PG_SZ(pPager)); + } + for(ii=0; rc==SQLITE_OK && iijournalOffjournalOff, pDone, 1, 1); + } + assert( rc!=SQLITE_DONE ); + } + assert( rc!=SQLITE_OK || pPager->journalOff>=szJ ); + + /* Finally, rollback pages from the sub-journal. Page that were + ** previously rolled back out of the main journal (and are hence in pDone) + ** will be skipped. Out-of-range pages are also skipped. + */ + if( pSavepoint ){ + u32 ii; /* Loop counter */ + i64 offset = (i64)pSavepoint->iSubRec*(4+pPager->pageSize); + + if( pagerUseWal(pPager) ){ + rc = sqlite3WalSavepointUndo(pPager->pWal, pSavepoint->aWalData); + } + for(ii=pSavepoint->iSubRec; rc==SQLITE_OK && iinSubRec; ii++){ + assert( offset==(i64)ii*(4+pPager->pageSize) ); + rc = pager_playback_one_page(pPager, &offset, pDone, 0, 1); + } + assert( rc!=SQLITE_DONE ); + } + + sqlite3BitvecDestroy(pDone); + if( rc==SQLITE_OK ){ + pPager->journalOff = szJ; + } + + return rc; +} + +/* +** Change the maximum number of in-memory pages that are allowed. +*/ +void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){ + sqlite3PcacheSetCachesize(pPager->pPCache, mxPage); +} + +/* +** Free as much memory as possible from the pager. +*/ +void sqlite3PagerShrink(Pager *pPager){ + sqlite3PcacheShrink(pPager->pPCache); +} + +/* +** Adjust the robustness of the database to damage due to OS crashes +** or power failures by changing the number of syncs()s when writing +** the rollback journal. There are three levels: +** +** OFF sqlite3OsSync() is never called. This is the default +** for temporary and transient files. +** +** NORMAL The journal is synced once before writes begin on the +** database. This is normally adequate protection, but +** it is theoretically possible, though very unlikely, +** that an inopertune power failure could leave the journal +** in a state which would cause damage to the database +** when it is rolled back. +** +** FULL The journal is synced twice before writes begin on the +** database (with some additional information - the nRec field +** of the journal header - being written in between the two +** syncs). If we assume that writing a +** single disk sector is atomic, then this mode provides +** assurance that the journal will not be corrupted to the +** point of causing damage to the database during rollback. +** +** The above is for a rollback-journal mode. For WAL mode, OFF continues +** to mean that no syncs ever occur. NORMAL means that the WAL is synced +** prior to the start of checkpoint and that the database file is synced +** at the conclusion of the checkpoint if the entire content of the WAL +** was written back into the database. But no sync operations occur for +** an ordinary commit in NORMAL mode with WAL. FULL means that the WAL +** file is synced following each commit operation, in addition to the +** syncs associated with NORMAL. +** +** Do not confuse synchronous=FULL with SQLITE_SYNC_FULL. The +** SQLITE_SYNC_FULL macro means to use the MacOSX-style full-fsync +** using fcntl(F_FULLFSYNC). SQLITE_SYNC_NORMAL means to do an +** ordinary fsync() call. There is no difference between SQLITE_SYNC_FULL +** and SQLITE_SYNC_NORMAL on platforms other than MacOSX. But the +** synchronous=FULL versus synchronous=NORMAL setting determines when +** the xSync primitive is called and is relevant to all platforms. +** +** Numeric values associated with these states are OFF==1, NORMAL=2, +** and FULL=3. +*/ +#ifndef SQLITE_OMIT_PAGER_PRAGMAS +void sqlite3PagerSetSafetyLevel( + Pager *pPager, /* The pager to set safety level for */ + int level, /* PRAGMA synchronous. 1=OFF, 2=NORMAL, 3=FULL */ + int bFullFsync, /* PRAGMA fullfsync */ + int bCkptFullFsync /* PRAGMA checkpoint_fullfsync */ +){ + assert( level>=1 && level<=3 ); + pPager->noSync = (level==1 || pPager->tempFile) ?1:0; + pPager->fullSync = (level==3 && !pPager->tempFile) ?1:0; + if( pPager->noSync ){ + pPager->syncFlags = 0; + pPager->ckptSyncFlags = 0; + }else if( bFullFsync ){ + pPager->syncFlags = SQLITE_SYNC_FULL; + pPager->ckptSyncFlags = SQLITE_SYNC_FULL; + }else if( bCkptFullFsync ){ + pPager->syncFlags = SQLITE_SYNC_NORMAL; + pPager->ckptSyncFlags = SQLITE_SYNC_FULL; + }else{ + pPager->syncFlags = SQLITE_SYNC_NORMAL; + pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL; + } + pPager->walSyncFlags = pPager->syncFlags; + if( pPager->fullSync ){ + pPager->walSyncFlags |= WAL_SYNC_TRANSACTIONS; + } +} +#endif + +/* +** The following global variable is incremented whenever the library +** attempts to open a temporary file. This information is used for +** testing and analysis only. +*/ +#ifdef SQLITE_TEST +int sqlite3_opentemp_count = 0; +#endif + +/* +** Open a temporary file. +** +** Write the file descriptor into *pFile. Return SQLITE_OK on success +** or some other error code if we fail. The OS will automatically +** delete the temporary file when it is closed. +** +** The flags passed to the VFS layer xOpen() call are those specified +** by parameter vfsFlags ORed with the following: +** +** SQLITE_OPEN_READWRITE +** SQLITE_OPEN_CREATE +** SQLITE_OPEN_EXCLUSIVE +** SQLITE_OPEN_DELETEONCLOSE +*/ +static int pagerOpentemp( + Pager *pPager, /* The pager object */ + sqlite3_file *pFile, /* Write the file descriptor here */ + int vfsFlags /* Flags passed through to the VFS */ +){ + int rc; /* Return code */ + +#ifdef SQLITE_TEST + sqlite3_opentemp_count++; /* Used for testing and analysis only */ +#endif + + vfsFlags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | + SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE; + rc = sqlite3OsOpen(pPager->pVfs, 0, pFile, vfsFlags, 0); + assert( rc!=SQLITE_OK || isOpen(pFile) ); + return rc; +} + +/* +** Set the busy handler function. +** +** The pager invokes the busy-handler if sqlite3OsLock() returns +** SQLITE_BUSY when trying to upgrade from no-lock to a SHARED lock, +** or when trying to upgrade from a RESERVED lock to an EXCLUSIVE +** lock. It does *not* invoke the busy handler when upgrading from +** SHARED to RESERVED, or when upgrading from SHARED to EXCLUSIVE +** (which occurs during hot-journal rollback). Summary: +** +** Transition | Invokes xBusyHandler +** -------------------------------------------------------- +** NO_LOCK -> SHARED_LOCK | Yes +** SHARED_LOCK -> RESERVED_LOCK | No +** SHARED_LOCK -> EXCLUSIVE_LOCK | No +** RESERVED_LOCK -> EXCLUSIVE_LOCK | Yes +** +** If the busy-handler callback returns non-zero, the lock is +** retried. If it returns zero, then the SQLITE_BUSY error is +** returned to the caller of the pager API function. +*/ +void sqlite3PagerSetBusyhandler( + Pager *pPager, /* Pager object */ + int (*xBusyHandler)(void *), /* Pointer to busy-handler function */ + void *pBusyHandlerArg /* Argument to pass to xBusyHandler */ +){ + pPager->xBusyHandler = xBusyHandler; + pPager->pBusyHandlerArg = pBusyHandlerArg; +} + +/* +** Change the page size used by the Pager object. The new page size +** is passed in *pPageSize. +** +** If the pager is in the error state when this function is called, it +** is a no-op. The value returned is the error state error code (i.e. +** one of SQLITE_IOERR, an SQLITE_IOERR_xxx sub-code or SQLITE_FULL). +** +** Otherwise, if all of the following are true: +** +** * the new page size (value of *pPageSize) is valid (a power +** of two between 512 and SQLITE_MAX_PAGE_SIZE, inclusive), and +** +** * there are no outstanding page references, and +** +** * the database is either not an in-memory database or it is +** an in-memory database that currently consists of zero pages. +** +** then the pager object page size is set to *pPageSize. +** +** If the page size is changed, then this function uses sqlite3PagerMalloc() +** to obtain a new Pager.pTmpSpace buffer. If this allocation attempt +** fails, SQLITE_NOMEM is returned and the page size remains unchanged. +** In all other cases, SQLITE_OK is returned. +** +** If the page size is not changed, either because one of the enumerated +** conditions above is not true, the pager was in error state when this +** function was called, or because the memory allocation attempt failed, +** then *pPageSize is set to the old, retained page size before returning. +*/ +int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nReserve){ + int rc = SQLITE_OK; + + /* It is not possible to do a full assert_pager_state() here, as this + ** function may be called from within PagerOpen(), before the state + ** of the Pager object is internally consistent. + ** + ** At one point this function returned an error if the pager was in + ** PAGER_ERROR state. But since PAGER_ERROR state guarantees that + ** there is at least one outstanding page reference, this function + ** is a no-op for that case anyhow. + */ + + u32 pageSize = *pPageSize; + assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) ); + if( (pPager->memDb==0 || pPager->dbSize==0) + && sqlite3PcacheRefCount(pPager->pPCache)==0 + && pageSize && pageSize!=(u32)pPager->pageSize + ){ + char *pNew = NULL; /* New temp space */ + i64 nByte = 0; + + if( pPager->eState>PAGER_OPEN && isOpen(pPager->fd) ){ + rc = sqlite3OsFileSize(pPager->fd, &nByte); + } + if( rc==SQLITE_OK ){ + pNew = (char *)sqlite3PageMalloc(pageSize); + if( !pNew ) rc = SQLITE_NOMEM; + } + + if( rc==SQLITE_OK ){ + pager_reset(pPager); + pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize); + pPager->pageSize = pageSize; + sqlite3PageFree(pPager->pTmpSpace); + pPager->pTmpSpace = pNew; + sqlite3PcacheSetPageSize(pPager->pPCache, pageSize); + } + } + + *pPageSize = pPager->pageSize; + if( rc==SQLITE_OK ){ + if( nReserve<0 ) nReserve = pPager->nReserve; + assert( nReserve>=0 && nReserve<1000 ); + pPager->nReserve = (i16)nReserve; + pagerReportSize(pPager); + } + return rc; +} + +/* +** Return a pointer to the "temporary page" buffer held internally +** by the pager. This is a buffer that is big enough to hold the +** entire content of a database page. This buffer is used internally +** during rollback and will be overwritten whenever a rollback +** occurs. But other modules are free to use it too, as long as +** no rollbacks are happening. +*/ +void *sqlite3PagerTempSpace(Pager *pPager){ + return pPager->pTmpSpace; +} + +/* +** Attempt to set the maximum database page count if mxPage is positive. +** Make no changes if mxPage is zero or negative. And never reduce the +** maximum page count below the current size of the database. +** +** Regardless of mxPage, return the current maximum page count. +*/ +int sqlite3PagerMaxPageCount(Pager *pPager, int mxPage){ + if( mxPage>0 ){ + pPager->mxPgno = mxPage; + } + assert( pPager->eState!=PAGER_OPEN ); /* Called only by OP_MaxPgcnt */ + assert( pPager->mxPgno>=pPager->dbSize ); /* OP_MaxPgcnt enforces this */ + return pPager->mxPgno; +} + +/* +** The following set of routines are used to disable the simulated +** I/O error mechanism. These routines are used to avoid simulated +** errors in places where we do not care about errors. +** +** Unless -DSQLITE_TEST=1 is used, these routines are all no-ops +** and generate no code. +*/ +#ifdef SQLITE_TEST +extern int sqlite3_io_error_pending; +extern int sqlite3_io_error_hit; +static int saved_cnt; +void disable_simulated_io_errors(void){ + saved_cnt = sqlite3_io_error_pending; + sqlite3_io_error_pending = -1; +} +void enable_simulated_io_errors(void){ + sqlite3_io_error_pending = saved_cnt; +} +#else +# define disable_simulated_io_errors() +# define enable_simulated_io_errors() +#endif + +/* +** Read the first N bytes from the beginning of the file into memory +** that pDest points to. +** +** If the pager was opened on a transient file (zFilename==""), or +** opened on a file less than N bytes in size, the output buffer is +** zeroed and SQLITE_OK returned. The rationale for this is that this +** function is used to read database headers, and a new transient or +** zero sized database has a header than consists entirely of zeroes. +** +** If any IO error apart from SQLITE_IOERR_SHORT_READ is encountered, +** the error code is returned to the caller and the contents of the +** output buffer undefined. +*/ +int sqlite3PagerReadFileheader(Pager *pPager, int N, unsigned char *pDest){ + int rc = SQLITE_OK; + memset(pDest, 0, N); + assert( isOpen(pPager->fd) || pPager->tempFile ); + + /* This routine is only called by btree immediately after creating + ** the Pager object. There has not been an opportunity to transition + ** to WAL mode yet. + */ + assert( !pagerUseWal(pPager) ); + + if( isOpen(pPager->fd) ){ + IOTRACE(("DBHDR %p 0 %d\n", pPager, N)) + rc = sqlite3OsRead(pPager->fd, pDest, N, 0); + if( rc==SQLITE_IOERR_SHORT_READ ){ + rc = SQLITE_OK; + } + } + return rc; +} + +/* +** This function may only be called when a read-transaction is open on +** the pager. It returns the total number of pages in the database. +** +** However, if the file is between 1 and bytes in size, then +** this is considered a 1 page file. +*/ +void sqlite3PagerPagecount(Pager *pPager, int *pnPage){ + assert( pPager->eState>=PAGER_READER ); + assert( pPager->eState!=PAGER_WRITER_FINISHED ); + *pnPage = (int)pPager->dbSize; +} + + +/* +** Try to obtain a lock of type locktype on the database file. If +** a similar or greater lock is already held, this function is a no-op +** (returning SQLITE_OK immediately). +** +** Otherwise, attempt to obtain the lock using sqlite3OsLock(). Invoke +** the busy callback if the lock is currently not available. Repeat +** until the busy callback returns false or until the attempt to +** obtain the lock succeeds. +** +** Return SQLITE_OK on success and an error code if we cannot obtain +** the lock. If the lock is obtained successfully, set the Pager.state +** variable to locktype before returning. +*/ +static int pager_wait_on_lock(Pager *pPager, int locktype){ + int rc; /* Return code */ + + /* Check that this is either a no-op (because the requested lock is + ** already held, or one of the transistions that the busy-handler + ** may be invoked during, according to the comment above + ** sqlite3PagerSetBusyhandler(). + */ + assert( (pPager->eLock>=locktype) + || (pPager->eLock==NO_LOCK && locktype==SHARED_LOCK) + || (pPager->eLock==RESERVED_LOCK && locktype==EXCLUSIVE_LOCK) + ); + + do { + rc = pagerLockDb(pPager, locktype); + }while( rc==SQLITE_BUSY && pPager->xBusyHandler(pPager->pBusyHandlerArg) ); + return rc; +} + +/* +** Function assertTruncateConstraint(pPager) checks that one of the +** following is true for all dirty pages currently in the page-cache: +** +** a) The page number is less than or equal to the size of the +** current database image, in pages, OR +** +** b) if the page content were written at this time, it would not +** be necessary to write the current content out to the sub-journal +** (as determined by function subjRequiresPage()). +** +** If the condition asserted by this function were not true, and the +** dirty page were to be discarded from the cache via the pagerStress() +** routine, pagerStress() would not write the current page content to +** the database file. If a savepoint transaction were rolled back after +** this happened, the correct behaviour would be to restore the current +** content of the page. However, since this content is not present in either +** the database file or the portion of the rollback journal and +** sub-journal rolled back the content could not be restored and the +** database image would become corrupt. It is therefore fortunate that +** this circumstance cannot arise. +*/ +#if defined(SQLITE_DEBUG) +static void assertTruncateConstraintCb(PgHdr *pPg){ + assert( pPg->flags&PGHDR_DIRTY ); + assert( !subjRequiresPage(pPg) || pPg->pgno<=pPg->pPager->dbSize ); +} +static void assertTruncateConstraint(Pager *pPager){ + sqlite3PcacheIterateDirty(pPager->pPCache, assertTruncateConstraintCb); +} +#else +# define assertTruncateConstraint(pPager) +#endif + +/* +** Truncate the in-memory database file image to nPage pages. This +** function does not actually modify the database file on disk. It +** just sets the internal state of the pager object so that the +** truncation will be done when the current transaction is committed. +*/ +void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){ + assert( pPager->dbSize>=nPage ); + assert( pPager->eState>=PAGER_WRITER_CACHEMOD ); + pPager->dbSize = nPage; + assertTruncateConstraint(pPager); +} + + +/* +** This function is called before attempting a hot-journal rollback. It +** syncs the journal file to disk, then sets pPager->journalHdr to the +** size of the journal file so that the pager_playback() routine knows +** that the entire journal file has been synced. +** +** Syncing a hot-journal to disk before attempting to roll it back ensures +** that if a power-failure occurs during the rollback, the process that +** attempts rollback following system recovery sees the same journal +** content as this process. +** +** If everything goes as planned, SQLITE_OK is returned. Otherwise, +** an SQLite error code. +*/ +static int pagerSyncHotJournal(Pager *pPager){ + int rc = SQLITE_OK; + if( !pPager->noSync ){ + rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_NORMAL); + } + if( rc==SQLITE_OK ){ + rc = sqlite3OsFileSize(pPager->jfd, &pPager->journalHdr); + } + return rc; +} + +/* +** Shutdown the page cache. Free all memory and close all files. +** +** If a transaction was in progress when this routine is called, that +** transaction is rolled back. All outstanding pages are invalidated +** and their memory is freed. Any attempt to use a page associated +** with this page cache after this function returns will likely +** result in a coredump. +** +** This function always succeeds. If a transaction is active an attempt +** is made to roll it back. If an error occurs during the rollback +** a hot journal may be left in the filesystem but no error is returned +** to the caller. +*/ +int sqlite3PagerClose(Pager *pPager){ + u8 *pTmp = (u8 *)pPager->pTmpSpace; + + assert( assert_pager_state(pPager) ); + disable_simulated_io_errors(); + sqlite3BeginBenignMalloc(); + /* pPager->errCode = 0; */ + pPager->exclusiveMode = 0; +#ifndef SQLITE_OMIT_WAL + sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags, pPager->pageSize, pTmp); + pPager->pWal = 0; +#endif + pager_reset(pPager); + if( MEMDB ){ + pager_unlock(pPager); + }else{ + /* If it is open, sync the journal file before calling UnlockAndRollback. + ** If this is not done, then an unsynced portion of the open journal + ** file may be played back into the database. If a power failure occurs + ** while this is happening, the database could become corrupt. + ** + ** If an error occurs while trying to sync the journal, shift the pager + ** into the ERROR state. This causes UnlockAndRollback to unlock the + ** database and close the journal file without attempting to roll it + ** back or finalize it. The next database user will have to do hot-journal + ** rollback before accessing the database file. + */ + if( isOpen(pPager->jfd) ){ + pager_error(pPager, pagerSyncHotJournal(pPager)); + } + pagerUnlockAndRollback(pPager); + } + sqlite3EndBenignMalloc(); + enable_simulated_io_errors(); + PAGERTRACE(("CLOSE %d\n", PAGERID(pPager))); + IOTRACE(("CLOSE %p\n", pPager)) + sqlite3OsClose(pPager->jfd); + sqlite3OsClose(pPager->fd); + sqlite3PageFree(pTmp); + sqlite3PcacheClose(pPager->pPCache); + +#ifdef SQLITE_HAS_CODEC + if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec); +#endif + + assert( !pPager->aSavepoint && !pPager->pInJournal ); + assert( !isOpen(pPager->jfd) && !isOpen(pPager->sjfd) ); + + sqlite3_free(pPager); + return SQLITE_OK; +} + +#if !defined(NDEBUG) || defined(SQLITE_TEST) +/* +** Return the page number for page pPg. +*/ +Pgno sqlite3PagerPagenumber(DbPage *pPg){ + return pPg->pgno; +} +#endif + +/* +** Increment the reference count for page pPg. +*/ +void sqlite3PagerRef(DbPage *pPg){ + sqlite3PcacheRef(pPg); +} + +/* +** Sync the journal. In other words, make sure all the pages that have +** been written to the journal have actually reached the surface of the +** disk and can be restored in the event of a hot-journal rollback. +** +** If the Pager.noSync flag is set, then this function is a no-op. +** Otherwise, the actions required depend on the journal-mode and the +** device characteristics of the the file-system, as follows: +** +** * If the journal file is an in-memory journal file, no action need +** be taken. +** +** * Otherwise, if the device does not support the SAFE_APPEND property, +** then the nRec field of the most recently written journal header +** is updated to contain the number of journal records that have +** been written following it. If the pager is operating in full-sync +** mode, then the journal file is synced before this field is updated. +** +** * If the device does not support the SEQUENTIAL property, then +** journal file is synced. +** +** Or, in pseudo-code: +** +** if( NOT ){ +** if( NOT SAFE_APPEND ){ +** if( ) xSync(); +** +** } +** if( NOT SEQUENTIAL ) xSync(); +** } +** +** If successful, this routine clears the PGHDR_NEED_SYNC flag of every +** page currently held in memory before returning SQLITE_OK. If an IO +** error is encountered, then the IO error code is returned to the caller. +*/ +static int syncJournal(Pager *pPager, int newHdr){ + int rc; /* Return code */ + + assert( pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + ); + assert( assert_pager_state(pPager) ); + assert( !pagerUseWal(pPager) ); + + rc = sqlite3PagerExclusiveLock(pPager); + if( rc!=SQLITE_OK ) return rc; + + if( !pPager->noSync ){ + assert( !pPager->tempFile ); + if( isOpen(pPager->jfd) && pPager->journalMode!=PAGER_JOURNALMODE_MEMORY ){ + const int iDc = sqlite3OsDeviceCharacteristics(pPager->fd); + assert( isOpen(pPager->jfd) ); + + if( 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){ + /* This block deals with an obscure problem. If the last connection + ** that wrote to this database was operating in persistent-journal + ** mode, then the journal file may at this point actually be larger + ** than Pager.journalOff bytes. If the next thing in the journal + ** file happens to be a journal-header (written as part of the + ** previous connection's transaction), and a crash or power-failure + ** occurs after nRec is updated but before this connection writes + ** anything else to the journal file (or commits/rolls back its + ** transaction), then SQLite may become confused when doing the + ** hot-journal rollback following recovery. It may roll back all + ** of this connections data, then proceed to rolling back the old, + ** out-of-date data that follows it. Database corruption. + ** + ** To work around this, if the journal file does appear to contain + ** a valid header following Pager.journalOff, then write a 0x00 + ** byte to the start of it to prevent it from being recognized. + ** + ** Variable iNextHdrOffset is set to the offset at which this + ** problematic header will occur, if it exists. aMagic is used + ** as a temporary buffer to inspect the first couple of bytes of + ** the potential journal header. + */ + i64 iNextHdrOffset; + u8 aMagic[8]; + u8 zHeader[sizeof(aJournalMagic)+4]; + + memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic)); + put32bits(&zHeader[sizeof(aJournalMagic)], pPager->nRec); + + iNextHdrOffset = journalHdrOffset(pPager); + rc = sqlite3OsRead(pPager->jfd, aMagic, 8, iNextHdrOffset); + if( rc==SQLITE_OK && 0==memcmp(aMagic, aJournalMagic, 8) ){ + static const u8 zerobyte = 0; + rc = sqlite3OsWrite(pPager->jfd, &zerobyte, 1, iNextHdrOffset); + } + if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){ + return rc; + } + + /* Write the nRec value into the journal file header. If in + ** full-synchronous mode, sync the journal first. This ensures that + ** all data has really hit the disk before nRec is updated to mark + ** it as a candidate for rollback. + ** + ** This is not required if the persistent media supports the + ** SAFE_APPEND property. Because in this case it is not possible + ** for garbage data to be appended to the file, the nRec field + ** is populated with 0xFFFFFFFF when the journal header is written + ** and never needs to be updated. + */ + if( pPager->fullSync && 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){ + PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager))); + IOTRACE(("JSYNC %p\n", pPager)) + rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags); + if( rc!=SQLITE_OK ) return rc; + } + IOTRACE(("JHDR %p %lld\n", pPager, pPager->journalHdr)); + rc = sqlite3OsWrite( + pPager->jfd, zHeader, sizeof(zHeader), pPager->journalHdr + ); + if( rc!=SQLITE_OK ) return rc; + } + if( 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){ + PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager))); + IOTRACE(("JSYNC %p\n", pPager)) + rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags| + (pPager->syncFlags==SQLITE_SYNC_FULL?SQLITE_SYNC_DATAONLY:0) + ); + if( rc!=SQLITE_OK ) return rc; + } + + pPager->journalHdr = pPager->journalOff; + if( newHdr && 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){ + pPager->nRec = 0; + rc = writeJournalHdr(pPager); + if( rc!=SQLITE_OK ) return rc; + } + }else{ + pPager->journalHdr = pPager->journalOff; + } + } + + /* Unless the pager is in noSync mode, the journal file was just + ** successfully synced. Either way, clear the PGHDR_NEED_SYNC flag on + ** all pages. + */ + sqlite3PcacheClearSyncFlags(pPager->pPCache); + pPager->eState = PAGER_WRITER_DBMOD; + assert( assert_pager_state(pPager) ); + return SQLITE_OK; +} + +/* +** The argument is the first in a linked list of dirty pages connected +** by the PgHdr.pDirty pointer. This function writes each one of the +** in-memory pages in the list to the database file. The argument may +** be NULL, representing an empty list. In this case this function is +** a no-op. +** +** The pager must hold at least a RESERVED lock when this function +** is called. Before writing anything to the database file, this lock +** is upgraded to an EXCLUSIVE lock. If the lock cannot be obtained, +** SQLITE_BUSY is returned and no data is written to the database file. +** +** If the pager is a temp-file pager and the actual file-system file +** is not yet open, it is created and opened before any data is +** written out. +** +** Once the lock has been upgraded and, if necessary, the file opened, +** the pages are written out to the database file in list order. Writing +** a page is skipped if it meets either of the following criteria: +** +** * The page number is greater than Pager.dbSize, or +** * The PGHDR_DONT_WRITE flag is set on the page. +** +** If writing out a page causes the database file to grow, Pager.dbFileSize +** is updated accordingly. If page 1 is written out, then the value cached +** in Pager.dbFileVers[] is updated to match the new value stored in +** the database file. +** +** If everything is successful, SQLITE_OK is returned. If an IO error +** occurs, an IO error code is returned. Or, if the EXCLUSIVE lock cannot +** be obtained, SQLITE_BUSY is returned. +*/ +static int pager_write_pagelist(Pager *pPager, PgHdr *pList){ + int rc = SQLITE_OK; /* Return code */ + + /* This function is only called for rollback pagers in WRITER_DBMOD state. */ + assert( !pagerUseWal(pPager) ); + assert( pPager->eState==PAGER_WRITER_DBMOD ); + assert( pPager->eLock==EXCLUSIVE_LOCK ); + + /* If the file is a temp-file has not yet been opened, open it now. It + ** is not possible for rc to be other than SQLITE_OK if this branch + ** is taken, as pager_wait_on_lock() is a no-op for temp-files. + */ + if( !isOpen(pPager->fd) ){ + assert( pPager->tempFile && rc==SQLITE_OK ); + rc = pagerOpentemp(pPager, pPager->fd, pPager->vfsFlags); + } + + /* Before the first write, give the VFS a hint of what the final + ** file size will be. + */ + assert( rc!=SQLITE_OK || isOpen(pPager->fd) ); + if( rc==SQLITE_OK && pPager->dbSize>pPager->dbHintSize ){ + sqlite3_int64 szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize; + sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile); + pPager->dbHintSize = pPager->dbSize; + } + + while( rc==SQLITE_OK && pList ){ + Pgno pgno = pList->pgno; + + /* If there are dirty pages in the page cache with page numbers greater + ** than Pager.dbSize, this means sqlite3PagerTruncateImage() was called to + ** make the file smaller (presumably by auto-vacuum code). Do not write + ** any such pages to the file. + ** + ** Also, do not write out any page that has the PGHDR_DONT_WRITE flag + ** set (set by sqlite3PagerDontWrite()). + */ + if( pgno<=pPager->dbSize && 0==(pList->flags&PGHDR_DONT_WRITE) ){ + i64 offset = (pgno-1)*(i64)pPager->pageSize; /* Offset to write */ + char *pData; /* Data to write */ + + assert( (pList->flags&PGHDR_NEED_SYNC)==0 ); + if( pList->pgno==1 ) pager_write_changecounter(pList); + + /* Encode the database */ + CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM, pData); + + /* Write out the page data. */ + rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset); + + /* If page 1 was just written, update Pager.dbFileVers to match + ** the value now stored in the database file. If writing this + ** page caused the database file to grow, update dbFileSize. + */ + if( pgno==1 ){ + memcpy(&pPager->dbFileVers, &pData[24], sizeof(pPager->dbFileVers)); + } + if( pgno>pPager->dbFileSize ){ + pPager->dbFileSize = pgno; + } + + /* Update any backup objects copying the contents of this pager. */ + sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)pList->pData); + + PAGERTRACE(("STORE %d page %d hash(%08x)\n", + PAGERID(pPager), pgno, pager_pagehash(pList))); + IOTRACE(("PGOUT %p %d\n", pPager, pgno)); + PAGER_INCR(sqlite3_pager_writedb_count); + PAGER_INCR(pPager->nWrite); + }else{ + PAGERTRACE(("NOSTORE %d page %d\n", PAGERID(pPager), pgno)); + } + pager_set_pagehash(pList); + pList = pList->pDirty; + } + + return rc; +} + +/* +** Ensure that the sub-journal file is open. If it is already open, this +** function is a no-op. +** +** SQLITE_OK is returned if everything goes according to plan. An +** SQLITE_IOERR_XXX error code is returned if a call to sqlite3OsOpen() +** fails. +*/ +static int openSubJournal(Pager *pPager){ + int rc = SQLITE_OK; + if( !isOpen(pPager->sjfd) ){ + if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY || pPager->subjInMemory ){ + sqlite3MemJournalOpen(pPager->sjfd); + }else{ + rc = pagerOpentemp(pPager, pPager->sjfd, SQLITE_OPEN_SUBJOURNAL); + } + } + return rc; +} + +/* +** Append a record of the current state of page pPg to the sub-journal. +** It is the callers responsibility to use subjRequiresPage() to check +** that it is really required before calling this function. +** +** If successful, set the bit corresponding to pPg->pgno in the bitvecs +** for all open savepoints before returning. +** +** This function returns SQLITE_OK if everything is successful, an IO +** error code if the attempt to write to the sub-journal fails, or +** SQLITE_NOMEM if a malloc fails while setting a bit in a savepoint +** bitvec. +*/ +static int subjournalPage(PgHdr *pPg){ + int rc = SQLITE_OK; + Pager *pPager = pPg->pPager; + if( pPager->journalMode!=PAGER_JOURNALMODE_OFF ){ + + /* Open the sub-journal, if it has not already been opened */ + assert( pPager->useJournal ); + assert( isOpen(pPager->jfd) || pagerUseWal(pPager) ); + assert( isOpen(pPager->sjfd) || pPager->nSubRec==0 ); + assert( pagerUseWal(pPager) + || pageInJournal(pPg) + || pPg->pgno>pPager->dbOrigSize + ); + rc = openSubJournal(pPager); + + /* If the sub-journal was opened successfully (or was already open), + ** write the journal record into the file. */ + if( rc==SQLITE_OK ){ + void *pData = pPg->pData; + i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize); + char *pData2; + + CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2); + PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno)); + rc = write32bits(pPager->sjfd, offset, pPg->pgno); + if( rc==SQLITE_OK ){ + rc = sqlite3OsWrite(pPager->sjfd, pData2, pPager->pageSize, offset+4); + } + } + } + if( rc==SQLITE_OK ){ + pPager->nSubRec++; + assert( pPager->nSavepoint>0 ); + rc = addToSavepointBitvecs(pPager, pPg->pgno); + } + return rc; +} + +/* +** This function is called by the pcache layer when it has reached some +** soft memory limit. The first argument is a pointer to a Pager object +** (cast as a void*). The pager is always 'purgeable' (not an in-memory +** database). The second argument is a reference to a page that is +** currently dirty but has no outstanding references. The page +** is always associated with the Pager object passed as the first +** argument. +** +** The job of this function is to make pPg clean by writing its contents +** out to the database file, if possible. This may involve syncing the +** journal file. +** +** If successful, sqlite3PcacheMakeClean() is called on the page and +** SQLITE_OK returned. If an IO error occurs while trying to make the +** page clean, the IO error code is returned. If the page cannot be +** made clean for some other reason, but no error occurs, then SQLITE_OK +** is returned by sqlite3PcacheMakeClean() is not called. +*/ +static int pagerStress(void *p, PgHdr *pPg){ + Pager *pPager = (Pager *)p; + int rc = SQLITE_OK; + + assert( pPg->pPager==pPager ); + assert( pPg->flags&PGHDR_DIRTY ); + + /* The doNotSyncSpill flag is set during times when doing a sync of + ** journal (and adding a new header) is not allowed. This occurs + ** during calls to sqlite3PagerWrite() while trying to journal multiple + ** pages belonging to the same sector. + ** + ** The doNotSpill flag inhibits all cache spilling regardless of whether + ** or not a sync is required. This is set during a rollback. + ** + ** Spilling is also prohibited when in an error state since that could + ** lead to database corruption. In the current implementaton it + ** is impossible for sqlite3PcacheFetch() to be called with createFlag==1 + ** while in the error state, hence it is impossible for this routine to + ** be called in the error state. Nevertheless, we include a NEVER() + ** test for the error state as a safeguard against future changes. + */ + if( NEVER(pPager->errCode) ) return SQLITE_OK; + if( pPager->doNotSpill ) return SQLITE_OK; + if( pPager->doNotSyncSpill && (pPg->flags & PGHDR_NEED_SYNC)!=0 ){ + return SQLITE_OK; + } + + pPg->pDirty = 0; + if( pagerUseWal(pPager) ){ + /* Write a single frame for this page to the log. */ + if( subjRequiresPage(pPg) ){ + rc = subjournalPage(pPg); + } + if( rc==SQLITE_OK ){ + rc = pagerWalFrames(pPager, pPg, 0, 0); + } + }else{ + + /* Sync the journal file if required. */ + if( pPg->flags&PGHDR_NEED_SYNC + || pPager->eState==PAGER_WRITER_CACHEMOD + ){ + rc = syncJournal(pPager, 1); + } + + /* If the page number of this page is larger than the current size of + ** the database image, it may need to be written to the sub-journal. + ** This is because the call to pager_write_pagelist() below will not + ** actually write data to the file in this case. + ** + ** Consider the following sequence of events: + ** + ** BEGIN; + ** + ** + ** SAVEPOINT sp; + ** + ** pagerStress(page X) + ** ROLLBACK TO sp; + ** + ** If (X>Y), then when pagerStress is called page X will not be written + ** out to the database file, but will be dropped from the cache. Then, + ** following the "ROLLBACK TO sp" statement, reading page X will read + ** data from the database file. This will be the copy of page X as it + ** was when the transaction started, not as it was when "SAVEPOINT sp" + ** was executed. + ** + ** The solution is to write the current data for page X into the + ** sub-journal file now (if it is not already there), so that it will + ** be restored to its current value when the "ROLLBACK TO sp" is + ** executed. + */ + if( NEVER( + rc==SQLITE_OK && pPg->pgno>pPager->dbSize && subjRequiresPage(pPg) + ) ){ + rc = subjournalPage(pPg); + } + + /* Write the contents of the page out to the database file. */ + if( rc==SQLITE_OK ){ + assert( (pPg->flags&PGHDR_NEED_SYNC)==0 ); + rc = pager_write_pagelist(pPager, pPg); + } + } + + /* Mark the page as clean. */ + if( rc==SQLITE_OK ){ + PAGERTRACE(("STRESS %d page %d\n", PAGERID(pPager), pPg->pgno)); + sqlite3PcacheMakeClean(pPg); + } + + return pager_error(pPager, rc); +} + + +/* +** Allocate and initialize a new Pager object and put a pointer to it +** in *ppPager. The pager should eventually be freed by passing it +** to sqlite3PagerClose(). +** +** The zFilename argument is the path to the database file to open. +** If zFilename is NULL then a randomly-named temporary file is created +** and used as the file to be cached. Temporary files are be deleted +** automatically when they are closed. If zFilename is ":memory:" then +** all information is held in cache. It is never written to disk. +** This can be used to implement an in-memory database. +** +** The nExtra parameter specifies the number of bytes of space allocated +** along with each page reference. This space is available to the user +** via the sqlite3PagerGetExtra() API. +** +** The flags argument is used to specify properties that affect the +** operation of the pager. It should be passed some bitwise combination +** of the PAGER_OMIT_JOURNAL and PAGER_NO_READLOCK flags. +** +** The vfsFlags parameter is a bitmask to pass to the flags parameter +** of the xOpen() method of the supplied VFS when opening files. +** +** If the pager object is allocated and the specified file opened +** successfully, SQLITE_OK is returned and *ppPager set to point to +** the new pager object. If an error occurs, *ppPager is set to NULL +** and error code returned. This function may return SQLITE_NOMEM +** (sqlite3Malloc() is used to allocate memory), SQLITE_CANTOPEN or +** various SQLITE_IO_XXX errors. +*/ +int sqlite3PagerOpen( + sqlite3_vfs *pVfs, /* The virtual file system to use */ + Pager **ppPager, /* OUT: Return the Pager structure here */ + const char *zFilename, /* Name of the database file to open */ + int nExtra, /* Extra bytes append to each in-memory page */ + int flags, /* flags controlling this file */ + int vfsFlags, /* flags passed through to sqlite3_vfs.xOpen() */ + void (*xReinit)(DbPage*) /* Function to reinitialize pages */ +){ + u8 *pPtr; + Pager *pPager = 0; /* Pager object to allocate and return */ + int rc = SQLITE_OK; /* Return code */ + int tempFile = 0; /* True for temp files (incl. in-memory files) */ + int memDb = 0; /* True if this is an in-memory file */ + int readOnly = 0; /* True if this is a read-only file */ + int journalFileSize; /* Bytes to allocate for each journal fd */ + char *zPathname = 0; /* Full path to database file */ + int nPathname = 0; /* Number of bytes in zPathname */ + int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */ + int noReadlock = (flags & PAGER_NO_READLOCK)!=0; /* True to omit read-lock */ + int pcacheSize = sqlite3PcacheSize(); /* Bytes to allocate for PCache */ + u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE; /* Default page size */ + const char *zUri = 0; /* URI args to copy */ + int nUri = 0; /* Number of bytes of URI args at *zUri */ + + /* Figure out how much space is required for each journal file-handle + ** (there are two of them, the main journal and the sub-journal). This + ** is the maximum space required for an in-memory journal file handle + ** and a regular journal file-handle. Note that a "regular journal-handle" + ** may be a wrapper capable of caching the first portion of the journal + ** file in memory to implement the atomic-write optimization (see + ** source file journal.c). + */ + if( sqlite3JournalSize(pVfs)>sqlite3MemJournalSize() ){ + journalFileSize = ROUND8(sqlite3JournalSize(pVfs)); + }else{ + journalFileSize = ROUND8(sqlite3MemJournalSize()); + } + + /* Set the output variable to NULL in case an error occurs. */ + *ppPager = 0; + +#ifndef SQLITE_OMIT_MEMORYDB + if( flags & PAGER_MEMORY ){ + memDb = 1; + zFilename = 0; + } +#endif + + /* Compute and store the full pathname in an allocated buffer pointed + ** to by zPathname, length nPathname. Or, if this is a temporary file, + ** leave both nPathname and zPathname set to 0. + */ + if( zFilename && zFilename[0] ){ + const char *z; + nPathname = pVfs->mxPathname+1; + zPathname = sqlite3Malloc(nPathname*2); + if( zPathname==0 ){ + return SQLITE_NOMEM; + } + zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */ + rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname); + nPathname = sqlite3Strlen30(zPathname); + z = zUri = &zFilename[sqlite3Strlen30(zFilename)+1]; + while( *z ){ + z += sqlite3Strlen30(z)+1; + z += sqlite3Strlen30(z)+1; + } + nUri = (int)(&z[1] - zUri); + assert( nUri>=0 ); + if( rc==SQLITE_OK && nPathname+8>pVfs->mxPathname ){ + /* This branch is taken when the journal path required by + ** the database being opened will be more than pVfs->mxPathname + ** bytes in length. This means the database cannot be opened, + ** as it will not be possible to open the journal file or even + ** check for a hot-journal before reading. + */ + rc = SQLITE_CANTOPEN_BKPT; + } + if( rc!=SQLITE_OK ){ + sqlite3_free(zPathname); + return rc; + } + } + + /* Allocate memory for the Pager structure, PCache object, the + ** three file descriptors, the database file name and the journal + ** file name. The layout in memory is as follows: + ** + ** Pager object (sizeof(Pager) bytes) + ** PCache object (sqlite3PcacheSize() bytes) + ** Database file handle (pVfs->szOsFile bytes) + ** Sub-journal file handle (journalFileSize bytes) + ** Main journal file handle (journalFileSize bytes) + ** Database file name (nPathname+1 bytes) + ** Journal file name (nPathname+8+1 bytes) + */ + pPtr = (u8 *)sqlite3MallocZero( + ROUND8(sizeof(*pPager)) + /* Pager structure */ + ROUND8(pcacheSize) + /* PCache object */ + ROUND8(pVfs->szOsFile) + /* The main db file */ + journalFileSize * 2 + /* The two journal files */ + nPathname + 1 + nUri + /* zFilename */ + nPathname + 8 + 2 /* zJournal */ +#ifndef SQLITE_OMIT_WAL + + nPathname + 4 + 2 /* zWal */ +#endif + ); + assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) ); + if( !pPtr ){ + sqlite3_free(zPathname); + return SQLITE_NOMEM; + } + pPager = (Pager*)(pPtr); + pPager->pPCache = (PCache*)(pPtr += ROUND8(sizeof(*pPager))); + pPager->fd = (sqlite3_file*)(pPtr += ROUND8(pcacheSize)); + pPager->sjfd = (sqlite3_file*)(pPtr += ROUND8(pVfs->szOsFile)); + pPager->jfd = (sqlite3_file*)(pPtr += journalFileSize); + pPager->zFilename = (char*)(pPtr += journalFileSize); + assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) ); + + /* Fill in the Pager.zFilename and Pager.zJournal buffers, if required. */ + if( zPathname ){ + assert( nPathname>0 ); + pPager->zJournal = (char*)(pPtr += nPathname + 1 + nUri); + memcpy(pPager->zFilename, zPathname, nPathname); + memcpy(&pPager->zFilename[nPathname+1], zUri, nUri); + memcpy(pPager->zJournal, zPathname, nPathname); + memcpy(&pPager->zJournal[nPathname], "-journal\000", 8+1); + sqlite3FileSuffix3(pPager->zFilename, pPager->zJournal); +#ifndef SQLITE_OMIT_WAL + pPager->zWal = &pPager->zJournal[nPathname+8+1]; + memcpy(pPager->zWal, zPathname, nPathname); + memcpy(&pPager->zWal[nPathname], "-wal\000", 4+1); + sqlite3FileSuffix3(pPager->zFilename, pPager->zWal); +#endif + sqlite3_free(zPathname); + } + pPager->pVfs = pVfs; + pPager->vfsFlags = vfsFlags; + + /* Open the pager file. + */ + if( zFilename && zFilename[0] ){ + int fout = 0; /* VFS flags returned by xOpen() */ + rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout); + assert( !memDb ); + readOnly = (fout&SQLITE_OPEN_READONLY); + + /* If the file was successfully opened for read/write access, + ** choose a default page size in case we have to create the + ** database file. The default page size is the maximum of: + ** + ** + SQLITE_DEFAULT_PAGE_SIZE, + ** + The value returned by sqlite3OsSectorSize() + ** + The largest page size that can be written atomically. + */ + if( rc==SQLITE_OK && !readOnly ){ + setSectorSize(pPager); + assert(SQLITE_DEFAULT_PAGE_SIZE<=SQLITE_MAX_DEFAULT_PAGE_SIZE); + if( szPageDfltsectorSize ){ + if( pPager->sectorSize>SQLITE_MAX_DEFAULT_PAGE_SIZE ){ + szPageDflt = SQLITE_MAX_DEFAULT_PAGE_SIZE; + }else{ + szPageDflt = (u32)pPager->sectorSize; + } + } +#ifdef SQLITE_ENABLE_ATOMIC_WRITE + { + int iDc = sqlite3OsDeviceCharacteristics(pPager->fd); + int ii; + assert(SQLITE_IOCAP_ATOMIC512==(512>>8)); + assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8)); + assert(SQLITE_MAX_DEFAULT_PAGE_SIZE<=65536); + for(ii=szPageDflt; ii<=SQLITE_MAX_DEFAULT_PAGE_SIZE; ii=ii*2){ + if( iDc&(SQLITE_IOCAP_ATOMIC|(ii>>8)) ){ + szPageDflt = ii; + } + } + } +#endif + } + }else{ + /* If a temporary file is requested, it is not opened immediately. + ** In this case we accept the default page size and delay actually + ** opening the file until the first call to OsWrite(). + ** + ** This branch is also run for an in-memory database. An in-memory + ** database is the same as a temp-file that is never written out to + ** disk and uses an in-memory rollback journal. + */ + tempFile = 1; + pPager->eState = PAGER_READER; + pPager->eLock = EXCLUSIVE_LOCK; + readOnly = (vfsFlags&SQLITE_OPEN_READONLY); + } + + /* The following call to PagerSetPagesize() serves to set the value of + ** Pager.pageSize and to allocate the Pager.pTmpSpace buffer. + */ + if( rc==SQLITE_OK ){ + assert( pPager->memDb==0 ); + rc = sqlite3PagerSetPagesize(pPager, &szPageDflt, -1); + testcase( rc!=SQLITE_OK ); + } + + /* If an error occurred in either of the blocks above, free the + ** Pager structure and close the file. + */ + if( rc!=SQLITE_OK ){ + assert( !pPager->pTmpSpace ); + sqlite3OsClose(pPager->fd); + sqlite3_free(pPager); + return rc; + } + + /* Initialize the PCache object. */ + assert( nExtra<1000 ); + nExtra = ROUND8(nExtra); + sqlite3PcacheOpen(szPageDflt, nExtra, !memDb, + !memDb?pagerStress:0, (void *)pPager, pPager->pPCache); + + PAGERTRACE(("OPEN %d %s\n", FILEHANDLEID(pPager->fd), pPager->zFilename)); + IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename)) + + pPager->useJournal = (u8)useJournal; + pPager->noReadlock = (noReadlock && readOnly) ?1:0; + /* pPager->stmtOpen = 0; */ + /* pPager->stmtInUse = 0; */ + /* pPager->nRef = 0; */ + /* pPager->stmtSize = 0; */ + /* pPager->stmtJSize = 0; */ + /* pPager->nPage = 0; */ + pPager->mxPgno = SQLITE_MAX_PAGE_COUNT; + /* pPager->state = PAGER_UNLOCK; */ +#if 0 + assert( pPager->state == (tempFile ? PAGER_EXCLUSIVE : PAGER_UNLOCK) ); +#endif + /* pPager->errMask = 0; */ + pPager->tempFile = (u8)tempFile; + assert( tempFile==PAGER_LOCKINGMODE_NORMAL + || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE ); + assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 ); + pPager->exclusiveMode = (u8)tempFile; + pPager->changeCountDone = pPager->tempFile; + pPager->memDb = (u8)memDb; + pPager->readOnly = (u8)readOnly; + assert( useJournal || pPager->tempFile ); + pPager->noSync = pPager->tempFile; + if( pPager->noSync ){ + assert( pPager->fullSync==0 ); + assert( pPager->syncFlags==0 ); + assert( pPager->walSyncFlags==0 ); + assert( pPager->ckptSyncFlags==0 ); + }else{ + pPager->fullSync = 1; + pPager->syncFlags = SQLITE_SYNC_NORMAL; + pPager->walSyncFlags = SQLITE_SYNC_NORMAL | WAL_SYNC_TRANSACTIONS; + pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL; + } + /* pPager->pFirst = 0; */ + /* pPager->pFirstSynced = 0; */ + /* pPager->pLast = 0; */ + pPager->nExtra = (u16)nExtra; + pPager->journalSizeLimit = SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT; + assert( isOpen(pPager->fd) || tempFile ); + setSectorSize(pPager); + if( !useJournal ){ + pPager->journalMode = PAGER_JOURNALMODE_OFF; + }else if( memDb ){ + pPager->journalMode = PAGER_JOURNALMODE_MEMORY; + } + /* pPager->xBusyHandler = 0; */ + /* pPager->pBusyHandlerArg = 0; */ + pPager->xReiniter = xReinit; + /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */ + + *ppPager = pPager; + return SQLITE_OK; +} + + + +/* +** This function is called after transitioning from PAGER_UNLOCK to +** PAGER_SHARED state. It tests if there is a hot journal present in +** the file-system for the given pager. A hot journal is one that +** needs to be played back. According to this function, a hot-journal +** file exists if the following criteria are met: +** +** * The journal file exists in the file system, and +** * No process holds a RESERVED or greater lock on the database file, and +** * The database file itself is greater than 0 bytes in size, and +** * The first byte of the journal file exists and is not 0x00. +** +** If the current size of the database file is 0 but a journal file +** exists, that is probably an old journal left over from a prior +** database with the same name. In this case the journal file is +** just deleted using OsDelete, *pExists is set to 0 and SQLITE_OK +** is returned. +** +** This routine does not check if there is a master journal filename +** at the end of the file. If there is, and that master journal file +** does not exist, then the journal file is not really hot. In this +** case this routine will return a false-positive. The pager_playback() +** routine will discover that the journal file is not really hot and +** will not roll it back. +** +** If a hot-journal file is found to exist, *pExists is set to 1 and +** SQLITE_OK returned. If no hot-journal file is present, *pExists is +** set to 0 and SQLITE_OK returned. If an IO error occurs while trying +** to determine whether or not a hot-journal file exists, the IO error +** code is returned and the value of *pExists is undefined. +*/ +static int hasHotJournal(Pager *pPager, int *pExists){ + sqlite3_vfs * const pVfs = pPager->pVfs; + int rc = SQLITE_OK; /* Return code */ + int exists = 1; /* True if a journal file is present */ + int jrnlOpen = !!isOpen(pPager->jfd); + + assert( pPager->useJournal ); + assert( isOpen(pPager->fd) ); + assert( pPager->eState==PAGER_OPEN ); + + assert( jrnlOpen==0 || ( sqlite3OsDeviceCharacteristics(pPager->jfd) & + SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN + )); + + *pExists = 0; + if( !jrnlOpen ){ + rc = sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &exists); + } + if( rc==SQLITE_OK && exists ){ + int locked = 0; /* True if some process holds a RESERVED lock */ + + /* Race condition here: Another process might have been holding the + ** the RESERVED lock and have a journal open at the sqlite3OsAccess() + ** call above, but then delete the journal and drop the lock before + ** we get to the following sqlite3OsCheckReservedLock() call. If that + ** is the case, this routine might think there is a hot journal when + ** in fact there is none. This results in a false-positive which will + ** be dealt with by the playback routine. Ticket #3883. + */ + rc = sqlite3OsCheckReservedLock(pPager->fd, &locked); + if( rc==SQLITE_OK && !locked ){ + Pgno nPage; /* Number of pages in database file */ + + /* Check the size of the database file. If it consists of 0 pages, + ** then delete the journal file. See the header comment above for + ** the reasoning here. Delete the obsolete journal file under + ** a RESERVED lock to avoid race conditions and to avoid violating + ** [H33020]. + */ + rc = pagerPagecount(pPager, &nPage); + if( rc==SQLITE_OK ){ + if( nPage==0 ){ + sqlite3BeginBenignMalloc(); + if( pagerLockDb(pPager, RESERVED_LOCK)==SQLITE_OK ){ + sqlite3OsDelete(pVfs, pPager->zJournal, 0); + if( !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK); + } + sqlite3EndBenignMalloc(); + }else{ + /* The journal file exists and no other connection has a reserved + ** or greater lock on the database file. Now check that there is + ** at least one non-zero bytes at the start of the journal file. + ** If there is, then we consider this journal to be hot. If not, + ** it can be ignored. + */ + if( !jrnlOpen ){ + int f = SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL; + rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &f); + } + if( rc==SQLITE_OK ){ + u8 first = 0; + rc = sqlite3OsRead(pPager->jfd, (void *)&first, 1, 0); + if( rc==SQLITE_IOERR_SHORT_READ ){ + rc = SQLITE_OK; + } + if( !jrnlOpen ){ + sqlite3OsClose(pPager->jfd); + } + *pExists = (first!=0); + }else if( rc==SQLITE_CANTOPEN ){ + /* If we cannot open the rollback journal file in order to see if + ** its has a zero header, that might be due to an I/O error, or + ** it might be due to the race condition described above and in + ** ticket #3883. Either way, assume that the journal is hot. + ** This might be a false positive. But if it is, then the + ** automatic journal playback and recovery mechanism will deal + ** with it under an EXCLUSIVE lock where we do not need to + ** worry so much with race conditions. + */ + *pExists = 1; + rc = SQLITE_OK; + } + } + } + } + } + + return rc; +} + +/* +** This function is called to obtain a shared lock on the database file. +** It is illegal to call sqlite3PagerAcquire() until after this function +** has been successfully called. If a shared-lock is already held when +** this function is called, it is a no-op. +** +** The following operations are also performed by this function. +** +** 1) If the pager is currently in PAGER_OPEN state (no lock held +** on the database file), then an attempt is made to obtain a +** SHARED lock on the database file. Immediately after obtaining +** the SHARED lock, the file-system is checked for a hot-journal, +** which is played back if present. Following any hot-journal +** rollback, the contents of the cache are validated by checking +** the 'change-counter' field of the database file header and +** discarded if they are found to be invalid. +** +** 2) If the pager is running in exclusive-mode, and there are currently +** no outstanding references to any pages, and is in the error state, +** then an attempt is made to clear the error state by discarding +** the contents of the page cache and rolling back any open journal +** file. +** +** If everything is successful, SQLITE_OK is returned. If an IO error +** occurs while locking the database, checking for a hot-journal file or +** rolling back a journal file, the IO error code is returned. +*/ +int sqlite3PagerSharedLock(Pager *pPager){ + int rc = SQLITE_OK; /* Return code */ + + /* This routine is only called from b-tree and only when there are no + ** outstanding pages. This implies that the pager state should either + ** be OPEN or READER. READER is only possible if the pager is or was in + ** exclusive access mode. + */ + assert( sqlite3PcacheRefCount(pPager->pPCache)==0 ); + assert( assert_pager_state(pPager) ); + assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER ); + if( NEVER(MEMDB && pPager->errCode) ){ return pPager->errCode; } + + if( !pagerUseWal(pPager) && pPager->eState==PAGER_OPEN ){ + int bHotJournal = 1; /* True if there exists a hot journal-file */ + + assert( !MEMDB ); + assert( pPager->noReadlock==0 || pPager->readOnly ); + + if( pPager->noReadlock==0 ){ + rc = pager_wait_on_lock(pPager, SHARED_LOCK); + if( rc!=SQLITE_OK ){ + assert( pPager->eLock==NO_LOCK || pPager->eLock==UNKNOWN_LOCK ); + goto failed; + } + } + + /* If a journal file exists, and there is no RESERVED lock on the + ** database file, then it either needs to be played back or deleted. + */ + if( pPager->eLock<=SHARED_LOCK ){ + rc = hasHotJournal(pPager, &bHotJournal); + } + if( rc!=SQLITE_OK ){ + goto failed; + } + if( bHotJournal ){ + /* Get an EXCLUSIVE lock on the database file. At this point it is + ** important that a RESERVED lock is not obtained on the way to the + ** EXCLUSIVE lock. If it were, another process might open the + ** database file, detect the RESERVED lock, and conclude that the + ** database is safe to read while this process is still rolling the + ** hot-journal back. + ** + ** Because the intermediate RESERVED lock is not requested, any + ** other process attempting to access the database file will get to + ** this point in the code and fail to obtain its own EXCLUSIVE lock + ** on the database file. + ** + ** Unless the pager is in locking_mode=exclusive mode, the lock is + ** downgraded to SHARED_LOCK before this function returns. + */ + rc = pagerLockDb(pPager, EXCLUSIVE_LOCK); + if( rc!=SQLITE_OK ){ + goto failed; + } + + /* If it is not already open and the file exists on disk, open the + ** journal for read/write access. Write access is required because + ** in exclusive-access mode the file descriptor will be kept open + ** and possibly used for a transaction later on. Also, write-access + ** is usually required to finalize the journal in journal_mode=persist + ** mode (and also for journal_mode=truncate on some systems). + ** + ** If the journal does not exist, it usually means that some + ** other connection managed to get in and roll it back before + ** this connection obtained the exclusive lock above. Or, it + ** may mean that the pager was in the error-state when this + ** function was called and the journal file does not exist. + */ + if( !isOpen(pPager->jfd) ){ + sqlite3_vfs * const pVfs = pPager->pVfs; + int bExists; /* True if journal file exists */ + rc = sqlite3OsAccess( + pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &bExists); + if( rc==SQLITE_OK && bExists ){ + int fout = 0; + int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL; + assert( !pPager->tempFile ); + rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout); + assert( rc!=SQLITE_OK || isOpen(pPager->jfd) ); + if( rc==SQLITE_OK && fout&SQLITE_OPEN_READONLY ){ + rc = SQLITE_CANTOPEN_BKPT; + sqlite3OsClose(pPager->jfd); + } + } + } + + /* Playback and delete the journal. Drop the database write + ** lock and reacquire the read lock. Purge the cache before + ** playing back the hot-journal so that we don't end up with + ** an inconsistent cache. Sync the hot journal before playing + ** it back since the process that crashed and left the hot journal + ** probably did not sync it and we are required to always sync + ** the journal before playing it back. + */ + if( isOpen(pPager->jfd) ){ + assert( rc==SQLITE_OK ); + rc = pagerSyncHotJournal(pPager); + if( rc==SQLITE_OK ){ + rc = pager_playback(pPager, 1); + pPager->eState = PAGER_OPEN; + } + }else if( !pPager->exclusiveMode ){ + pagerUnlockDb(pPager, SHARED_LOCK); + } + + if( rc!=SQLITE_OK ){ + /* This branch is taken if an error occurs while trying to open + ** or roll back a hot-journal while holding an EXCLUSIVE lock. The + ** pager_unlock() routine will be called before returning to unlock + ** the file. If the unlock attempt fails, then Pager.eLock must be + ** set to UNKNOWN_LOCK (see the comment above the #define for + ** UNKNOWN_LOCK above for an explanation). + ** + ** In order to get pager_unlock() to do this, set Pager.eState to + ** PAGER_ERROR now. This is not actually counted as a transition + ** to ERROR state in the state diagram at the top of this file, + ** since we know that the same call to pager_unlock() will very + ** shortly transition the pager object to the OPEN state. Calling + ** assert_pager_state() would fail now, as it should not be possible + ** to be in ERROR state when there are zero outstanding page + ** references. + */ + pager_error(pPager, rc); + goto failed; + } + + assert( pPager->eState==PAGER_OPEN ); + assert( (pPager->eLock==SHARED_LOCK) + || (pPager->exclusiveMode && pPager->eLock>SHARED_LOCK) + ); + } + + if( !pPager->tempFile + && (pPager->pBackup || sqlite3PcachePagecount(pPager->pPCache)>0) + ){ + /* The shared-lock has just been acquired on the database file + ** and there are already pages in the cache (from a previous + ** read or write transaction). Check to see if the database + ** has been modified. If the database has changed, flush the + ** cache. + ** + ** Database changes is detected by looking at 15 bytes beginning + ** at offset 24 into the file. The first 4 of these 16 bytes are + ** a 32-bit counter that is incremented with each change. The + ** other bytes change randomly with each file change when + ** a codec is in use. + ** + ** There is a vanishingly small chance that a change will not be + ** detected. The chance of an undetected change is so small that + ** it can be neglected. + */ + Pgno nPage = 0; + char dbFileVers[sizeof(pPager->dbFileVers)]; + + rc = pagerPagecount(pPager, &nPage); + if( rc ) goto failed; + + if( nPage>0 ){ + IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers))); + rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24); + if( rc!=SQLITE_OK ){ + goto failed; + } + }else{ + memset(dbFileVers, 0, sizeof(dbFileVers)); + } + + if( memcmp(pPager->dbFileVers, dbFileVers, sizeof(dbFileVers))!=0 ){ + pager_reset(pPager); + } + } + + /* If there is a WAL file in the file-system, open this database in WAL + ** mode. Otherwise, the following function call is a no-op. + */ + rc = pagerOpenWalIfPresent(pPager); +#ifndef SQLITE_OMIT_WAL + assert( pPager->pWal==0 || rc==SQLITE_OK ); +#endif + } + + if( pagerUseWal(pPager) ){ + assert( rc==SQLITE_OK ); + rc = pagerBeginReadTransaction(pPager); + } + + if( pPager->eState==PAGER_OPEN && rc==SQLITE_OK ){ + rc = pagerPagecount(pPager, &pPager->dbSize); + } + + failed: + if( rc!=SQLITE_OK ){ + assert( !MEMDB ); + pager_unlock(pPager); + assert( pPager->eState==PAGER_OPEN ); + }else{ + pPager->eState = PAGER_READER; + } + return rc; +} + +/* +** If the reference count has reached zero, rollback any active +** transaction and unlock the pager. +** +** Except, in locking_mode=EXCLUSIVE when there is nothing to in +** the rollback journal, the unlock is not performed and there is +** nothing to rollback, so this routine is a no-op. +*/ +static void pagerUnlockIfUnused(Pager *pPager){ + if( (sqlite3PcacheRefCount(pPager->pPCache)==0) ){ + pagerUnlockAndRollback(pPager); + } +} + +/* +** Acquire a reference to page number pgno in pager pPager (a page +** reference has type DbPage*). If the requested reference is +** successfully obtained, it is copied to *ppPage and SQLITE_OK returned. +** +** If the requested page is already in the cache, it is returned. +** Otherwise, a new page object is allocated and populated with data +** read from the database file. In some cases, the pcache module may +** choose not to allocate a new page object and may reuse an existing +** object with no outstanding references. +** +** The extra data appended to a page is always initialized to zeros the +** first time a page is loaded into memory. If the page requested is +** already in the cache when this function is called, then the extra +** data is left as it was when the page object was last used. +** +** If the database image is smaller than the requested page or if a +** non-zero value is passed as the noContent parameter and the +** requested page is not already stored in the cache, then no +** actual disk read occurs. In this case the memory image of the +** page is initialized to all zeros. +** +** If noContent is true, it means that we do not care about the contents +** of the page. This occurs in two seperate scenarios: +** +** a) When reading a free-list leaf page from the database, and +** +** b) When a savepoint is being rolled back and we need to load +** a new page into the cache to be filled with the data read +** from the savepoint journal. +** +** If noContent is true, then the data returned is zeroed instead of +** being read from the database. Additionally, the bits corresponding +** to pgno in Pager.pInJournal (bitvec of pages already written to the +** journal file) and the PagerSavepoint.pInSavepoint bitvecs of any open +** savepoints are set. This means if the page is made writable at any +** point in the future, using a call to sqlite3PagerWrite(), its contents +** will not be journaled. This saves IO. +** +** The acquisition might fail for several reasons. In all cases, +** an appropriate error code is returned and *ppPage is set to NULL. +** +** See also sqlite3PagerLookup(). Both this routine and Lookup() attempt +** to find a page in the in-memory cache first. If the page is not already +** in memory, this routine goes to disk to read it in whereas Lookup() +** just returns 0. This routine acquires a read-lock the first time it +** has to go to disk, and could also playback an old journal if necessary. +** Since Lookup() never goes to disk, it never has to deal with locks +** or journal files. +*/ +int sqlite3PagerAcquire( + Pager *pPager, /* The pager open on the database file */ + Pgno pgno, /* Page number to fetch */ + DbPage **ppPage, /* Write a pointer to the page here */ + int noContent /* Do not bother reading content from disk if true */ +){ + int rc; + PgHdr *pPg; + + assert( pPager->eState>=PAGER_READER ); + assert( assert_pager_state(pPager) ); + + if( pgno==0 ){ + return SQLITE_CORRUPT_BKPT; + } + + /* If the pager is in the error state, return an error immediately. + ** Otherwise, request the page from the PCache layer. */ + if( pPager->errCode!=SQLITE_OK ){ + rc = pPager->errCode; + }else{ + rc = sqlite3PcacheFetch(pPager->pPCache, pgno, 1, ppPage); + } + + if( rc!=SQLITE_OK ){ + /* Either the call to sqlite3PcacheFetch() returned an error or the + ** pager was already in the error-state when this function was called. + ** Set pPg to 0 and jump to the exception handler. */ + pPg = 0; + goto pager_acquire_err; + } + assert( (*ppPage)->pgno==pgno ); + assert( (*ppPage)->pPager==pPager || (*ppPage)->pPager==0 ); + + if( (*ppPage)->pPager && !noContent ){ + /* In this case the pcache already contains an initialized copy of + ** the page. Return without further ado. */ + assert( pgno<=PAGER_MAX_PGNO && pgno!=PAGER_MJ_PGNO(pPager) ); + pPager->nHit++; + return SQLITE_OK; + + }else{ + /* The pager cache has created a new page. Its content needs to + ** be initialized. */ + + pPg = *ppPage; + pPg->pPager = pPager; + + /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page + ** number greater than this, or the unused locking-page, is requested. */ + if( pgno>PAGER_MAX_PGNO || pgno==PAGER_MJ_PGNO(pPager) ){ + rc = SQLITE_CORRUPT_BKPT; + goto pager_acquire_err; + } + + if( MEMDB || pPager->dbSizefd) ){ + if( pgno>pPager->mxPgno ){ + rc = SQLITE_FULL; + goto pager_acquire_err; + } + if( noContent ){ + /* Failure to set the bits in the InJournal bit-vectors is benign. + ** It merely means that we might do some extra work to journal a + ** page that does not need to be journaled. Nevertheless, be sure + ** to test the case where a malloc error occurs while trying to set + ** a bit in a bit vector. + */ + sqlite3BeginBenignMalloc(); + if( pgno<=pPager->dbOrigSize ){ + TESTONLY( rc = ) sqlite3BitvecSet(pPager->pInJournal, pgno); + testcase( rc==SQLITE_NOMEM ); + } + TESTONLY( rc = ) addToSavepointBitvecs(pPager, pgno); + testcase( rc==SQLITE_NOMEM ); + sqlite3EndBenignMalloc(); + } + memset(pPg->pData, 0, pPager->pageSize); + IOTRACE(("ZERO %p %d\n", pPager, pgno)); + }else{ + assert( pPg->pPager==pPager ); + pPager->nMiss++; + rc = readDbPage(pPg); + if( rc!=SQLITE_OK ){ + goto pager_acquire_err; + } + } + pager_set_pagehash(pPg); + } + + return SQLITE_OK; + +pager_acquire_err: + assert( rc!=SQLITE_OK ); + if( pPg ){ + sqlite3PcacheDrop(pPg); + } + pagerUnlockIfUnused(pPager); + + *ppPage = 0; + return rc; +} + +/* +** Acquire a page if it is already in the in-memory cache. Do +** not read the page from disk. Return a pointer to the page, +** or 0 if the page is not in cache. +** +** See also sqlite3PagerGet(). The difference between this routine +** and sqlite3PagerGet() is that _get() will go to the disk and read +** in the page if the page is not already in cache. This routine +** returns NULL if the page is not in cache or if a disk I/O error +** has ever happened. +*/ +DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){ + PgHdr *pPg = 0; + assert( pPager!=0 ); + assert( pgno!=0 ); + assert( pPager->pPCache!=0 ); + assert( pPager->eState>=PAGER_READER && pPager->eState!=PAGER_ERROR ); + sqlite3PcacheFetch(pPager->pPCache, pgno, 0, &pPg); + return pPg; +} + +/* +** Release a page reference. +** +** If the number of references to the page drop to zero, then the +** page is added to the LRU list. When all references to all pages +** are released, a rollback occurs and the lock on the database is +** removed. +*/ +void sqlite3PagerUnref(DbPage *pPg){ + if( pPg ){ + Pager *pPager = pPg->pPager; + sqlite3PcacheRelease(pPg); + pagerUnlockIfUnused(pPager); + } +} + +/* +** This function is called at the start of every write transaction. +** There must already be a RESERVED or EXCLUSIVE lock on the database +** file when this routine is called. +** +** Open the journal file for pager pPager and write a journal header +** to the start of it. If there are active savepoints, open the sub-journal +** as well. This function is only used when the journal file is being +** opened to write a rollback log for a transaction. It is not used +** when opening a hot journal file to roll it back. +** +** If the journal file is already open (as it may be in exclusive mode), +** then this function just writes a journal header to the start of the +** already open file. +** +** Whether or not the journal file is opened by this function, the +** Pager.pInJournal bitvec structure is allocated. +** +** Return SQLITE_OK if everything is successful. Otherwise, return +** SQLITE_NOMEM if the attempt to allocate Pager.pInJournal fails, or +** an IO error code if opening or writing the journal file fails. +*/ +static int pager_open_journal(Pager *pPager){ + int rc = SQLITE_OK; /* Return code */ + sqlite3_vfs * const pVfs = pPager->pVfs; /* Local cache of vfs pointer */ + + assert( pPager->eState==PAGER_WRITER_LOCKED ); + assert( assert_pager_state(pPager) ); + assert( pPager->pInJournal==0 ); + + /* If already in the error state, this function is a no-op. But on + ** the other hand, this routine is never called if we are already in + ** an error state. */ + if( NEVER(pPager->errCode) ) return pPager->errCode; + + if( !pagerUseWal(pPager) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){ + pPager->pInJournal = sqlite3BitvecCreate(pPager->dbSize); + if( pPager->pInJournal==0 ){ + return SQLITE_NOMEM; + } + + /* Open the journal file if it is not already open. */ + if( !isOpen(pPager->jfd) ){ + if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){ + sqlite3MemJournalOpen(pPager->jfd); + }else{ + const int flags = /* VFS flags to open journal file */ + SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE| + (pPager->tempFile ? + (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL): + (SQLITE_OPEN_MAIN_JOURNAL) + ); + #ifdef SQLITE_ENABLE_ATOMIC_WRITE + rc = sqlite3JournalOpen( + pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager) + ); + #else + rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0); + #endif + } + assert( rc!=SQLITE_OK || isOpen(pPager->jfd) ); + } + + + /* Write the first journal header to the journal file and open + ** the sub-journal if necessary. + */ + if( rc==SQLITE_OK ){ + /* TODO: Check if all of these are really required. */ + pPager->nRec = 0; + pPager->journalOff = 0; + pPager->setMaster = 0; + pPager->journalHdr = 0; + rc = writeJournalHdr(pPager); + } + } + + if( rc!=SQLITE_OK ){ + sqlite3BitvecDestroy(pPager->pInJournal); + pPager->pInJournal = 0; + }else{ + assert( pPager->eState==PAGER_WRITER_LOCKED ); + pPager->eState = PAGER_WRITER_CACHEMOD; + } + + return rc; +} + +/* +** Begin a write-transaction on the specified pager object. If a +** write-transaction has already been opened, this function is a no-op. +** +** If the exFlag argument is false, then acquire at least a RESERVED +** lock on the database file. If exFlag is true, then acquire at least +** an EXCLUSIVE lock. If such a lock is already held, no locking +** functions need be called. +** +** If the subjInMemory argument is non-zero, then any sub-journal opened +** within this transaction will be opened as an in-memory file. This +** has no effect if the sub-journal is already opened (as it may be when +** running in exclusive mode) or if the transaction does not require a +** sub-journal. If the subjInMemory argument is zero, then any required +** sub-journal is implemented in-memory if pPager is an in-memory database, +** or using a temporary file otherwise. +*/ +int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory){ + int rc = SQLITE_OK; + + if( pPager->errCode ) return pPager->errCode; + assert( pPager->eState>=PAGER_READER && pPager->eStatesubjInMemory = (u8)subjInMemory; + + if( ALWAYS(pPager->eState==PAGER_READER) ){ + assert( pPager->pInJournal==0 ); + + if( pagerUseWal(pPager) ){ + /* If the pager is configured to use locking_mode=exclusive, and an + ** exclusive lock on the database is not already held, obtain it now. + */ + if( pPager->exclusiveMode && sqlite3WalExclusiveMode(pPager->pWal, -1) ){ + rc = pagerLockDb(pPager, EXCLUSIVE_LOCK); + if( rc!=SQLITE_OK ){ + return rc; + } + sqlite3WalExclusiveMode(pPager->pWal, 1); + } + + /* Grab the write lock on the log file. If successful, upgrade to + ** PAGER_RESERVED state. Otherwise, return an error code to the caller. + ** The busy-handler is not invoked if another connection already + ** holds the write-lock. If possible, the upper layer will call it. + */ + rc = sqlite3WalBeginWriteTransaction(pPager->pWal); + }else{ + /* Obtain a RESERVED lock on the database file. If the exFlag parameter + ** is true, then immediately upgrade this to an EXCLUSIVE lock. The + ** busy-handler callback can be used when upgrading to the EXCLUSIVE + ** lock, but not when obtaining the RESERVED lock. + */ + rc = pagerLockDb(pPager, RESERVED_LOCK); + if( rc==SQLITE_OK && exFlag ){ + rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); + } + } + + if( rc==SQLITE_OK ){ + /* Change to WRITER_LOCKED state. + ** + ** WAL mode sets Pager.eState to PAGER_WRITER_LOCKED or CACHEMOD + ** when it has an open transaction, but never to DBMOD or FINISHED. + ** This is because in those states the code to roll back savepoint + ** transactions may copy data from the sub-journal into the database + ** file as well as into the page cache. Which would be incorrect in + ** WAL mode. + */ + pPager->eState = PAGER_WRITER_LOCKED; + pPager->dbHintSize = pPager->dbSize; + pPager->dbFileSize = pPager->dbSize; + pPager->dbOrigSize = pPager->dbSize; + pPager->journalOff = 0; + } + + assert( rc==SQLITE_OK || pPager->eState==PAGER_READER ); + assert( rc!=SQLITE_OK || pPager->eState==PAGER_WRITER_LOCKED ); + assert( assert_pager_state(pPager) ); + } + + PAGERTRACE(("TRANSACTION %d\n", PAGERID(pPager))); + return rc; +} + +/* +** Mark a single data page as writeable. The page is written into the +** main journal or sub-journal as required. If the page is written into +** one of the journals, the corresponding bit is set in the +** Pager.pInJournal bitvec and the PagerSavepoint.pInSavepoint bitvecs +** of any open savepoints as appropriate. +*/ +static int pager_write(PgHdr *pPg){ + void *pData = pPg->pData; + Pager *pPager = pPg->pPager; + int rc = SQLITE_OK; + + /* This routine is not called unless a write-transaction has already + ** been started. The journal file may or may not be open at this point. + ** It is never called in the ERROR state. + */ + assert( pPager->eState==PAGER_WRITER_LOCKED + || pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + ); + assert( assert_pager_state(pPager) ); + + /* If an error has been previously detected, report the same error + ** again. This should not happen, but the check provides robustness. */ + if( NEVER(pPager->errCode) ) return pPager->errCode; + + /* Higher-level routines never call this function if database is not + ** writable. But check anyway, just for robustness. */ + if( NEVER(pPager->readOnly) ) return SQLITE_PERM; + + CHECK_PAGE(pPg); + + /* The journal file needs to be opened. Higher level routines have already + ** obtained the necessary locks to begin the write-transaction, but the + ** rollback journal might not yet be open. Open it now if this is the case. + ** + ** This is done before calling sqlite3PcacheMakeDirty() on the page. + ** Otherwise, if it were done after calling sqlite3PcacheMakeDirty(), then + ** an error might occur and the pager would end up in WRITER_LOCKED state + ** with pages marked as dirty in the cache. + */ + if( pPager->eState==PAGER_WRITER_LOCKED ){ + rc = pager_open_journal(pPager); + if( rc!=SQLITE_OK ) return rc; + } + assert( pPager->eState>=PAGER_WRITER_CACHEMOD ); + assert( assert_pager_state(pPager) ); + + /* Mark the page as dirty. If the page has already been written + ** to the journal then we can return right away. + */ + sqlite3PcacheMakeDirty(pPg); + if( pageInJournal(pPg) && !subjRequiresPage(pPg) ){ + assert( !pagerUseWal(pPager) ); + }else{ + + /* The transaction journal now exists and we have a RESERVED or an + ** EXCLUSIVE lock on the main database file. Write the current page to + ** the transaction journal if it is not there already. + */ + if( !pageInJournal(pPg) && !pagerUseWal(pPager) ){ + assert( pagerUseWal(pPager)==0 ); + if( pPg->pgno<=pPager->dbOrigSize && isOpen(pPager->jfd) ){ + u32 cksum; + char *pData2; + i64 iOff = pPager->journalOff; + + /* We should never write to the journal file the page that + ** contains the database locks. The following assert verifies + ** that we do not. */ + assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) ); + + assert( pPager->journalHdr<=pPager->journalOff ); + CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2); + cksum = pager_cksum(pPager, (u8*)pData2); + + /* Even if an IO or diskfull error occurs while journalling the + ** page in the block above, set the need-sync flag for the page. + ** Otherwise, when the transaction is rolled back, the logic in + ** playback_one_page() will think that the page needs to be restored + ** in the database file. And if an IO error occurs while doing so, + ** then corruption may follow. + */ + pPg->flags |= PGHDR_NEED_SYNC; + + rc = write32bits(pPager->jfd, iOff, pPg->pgno); + if( rc!=SQLITE_OK ) return rc; + rc = sqlite3OsWrite(pPager->jfd, pData2, pPager->pageSize, iOff+4); + if( rc!=SQLITE_OK ) return rc; + rc = write32bits(pPager->jfd, iOff+pPager->pageSize+4, cksum); + if( rc!=SQLITE_OK ) return rc; + + IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno, + pPager->journalOff, pPager->pageSize)); + PAGER_INCR(sqlite3_pager_writej_count); + PAGERTRACE(("JOURNAL %d page %d needSync=%d hash(%08x)\n", + PAGERID(pPager), pPg->pgno, + ((pPg->flags&PGHDR_NEED_SYNC)?1:0), pager_pagehash(pPg))); + + pPager->journalOff += 8 + pPager->pageSize; + pPager->nRec++; + assert( pPager->pInJournal!=0 ); + rc = sqlite3BitvecSet(pPager->pInJournal, pPg->pgno); + testcase( rc==SQLITE_NOMEM ); + assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); + rc |= addToSavepointBitvecs(pPager, pPg->pgno); + if( rc!=SQLITE_OK ){ + assert( rc==SQLITE_NOMEM ); + return rc; + } + }else{ + if( pPager->eState!=PAGER_WRITER_DBMOD ){ + pPg->flags |= PGHDR_NEED_SYNC; + } + PAGERTRACE(("APPEND %d page %d needSync=%d\n", + PAGERID(pPager), pPg->pgno, + ((pPg->flags&PGHDR_NEED_SYNC)?1:0))); + } + } + + /* If the statement journal is open and the page is not in it, + ** then write the current page to the statement journal. Note that + ** the statement journal format differs from the standard journal format + ** in that it omits the checksums and the header. + */ + if( subjRequiresPage(pPg) ){ + rc = subjournalPage(pPg); + } + } + + /* Update the database size and return. + */ + if( pPager->dbSizepgno ){ + pPager->dbSize = pPg->pgno; + } + return rc; +} + +/* +** Mark a data page as writeable. This routine must be called before +** making changes to a page. The caller must check the return value +** of this function and be careful not to change any page data unless +** this routine returns SQLITE_OK. +** +** The difference between this function and pager_write() is that this +** function also deals with the special case where 2 or more pages +** fit on a single disk sector. In this case all co-resident pages +** must have been written to the journal file before returning. +** +** If an error occurs, SQLITE_NOMEM or an IO error code is returned +** as appropriate. Otherwise, SQLITE_OK. +*/ +int sqlite3PagerWrite(DbPage *pDbPage){ + int rc = SQLITE_OK; + + PgHdr *pPg = pDbPage; + Pager *pPager = pPg->pPager; + Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize); + + assert( pPager->eState>=PAGER_WRITER_LOCKED ); + assert( pPager->eState!=PAGER_ERROR ); + assert( assert_pager_state(pPager) ); + + if( nPagePerSector>1 ){ + Pgno nPageCount; /* Total number of pages in database file */ + Pgno pg1; /* First page of the sector pPg is located on. */ + int nPage = 0; /* Number of pages starting at pg1 to journal */ + int ii; /* Loop counter */ + int needSync = 0; /* True if any page has PGHDR_NEED_SYNC */ + + /* Set the doNotSyncSpill flag to 1. This is because we cannot allow + ** a journal header to be written between the pages journaled by + ** this function. + */ + assert( !MEMDB ); + assert( pPager->doNotSyncSpill==0 ); + pPager->doNotSyncSpill++; + + /* This trick assumes that both the page-size and sector-size are + ** an integer power of 2. It sets variable pg1 to the identifier + ** of the first page of the sector pPg is located on. + */ + pg1 = ((pPg->pgno-1) & ~(nPagePerSector-1)) + 1; + + nPageCount = pPager->dbSize; + if( pPg->pgno>nPageCount ){ + nPage = (pPg->pgno - pg1)+1; + }else if( (pg1+nPagePerSector-1)>nPageCount ){ + nPage = nPageCount+1-pg1; + }else{ + nPage = nPagePerSector; + } + assert(nPage>0); + assert(pg1<=pPg->pgno); + assert((pg1+nPage)>pPg->pgno); + + for(ii=0; iipgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){ + if( pg!=PAGER_MJ_PGNO(pPager) ){ + rc = sqlite3PagerGet(pPager, pg, &pPage); + if( rc==SQLITE_OK ){ + rc = pager_write(pPage); + if( pPage->flags&PGHDR_NEED_SYNC ){ + needSync = 1; + } + sqlite3PagerUnref(pPage); + } + } + }else if( (pPage = pager_lookup(pPager, pg))!=0 ){ + if( pPage->flags&PGHDR_NEED_SYNC ){ + needSync = 1; + } + sqlite3PagerUnref(pPage); + } + } + + /* If the PGHDR_NEED_SYNC flag is set for any of the nPage pages + ** starting at pg1, then it needs to be set for all of them. Because + ** writing to any of these nPage pages may damage the others, the + ** journal file must contain sync()ed copies of all of them + ** before any of them can be written out to the database file. + */ + if( rc==SQLITE_OK && needSync ){ + assert( !MEMDB ); + for(ii=0; iiflags |= PGHDR_NEED_SYNC; + sqlite3PagerUnref(pPage); + } + } + } + + assert( pPager->doNotSyncSpill==1 ); + pPager->doNotSyncSpill--; + }else{ + rc = pager_write(pDbPage); + } + return rc; +} + +/* +** Return TRUE if the page given in the argument was previously passed +** to sqlite3PagerWrite(). In other words, return TRUE if it is ok +** to change the content of the page. +*/ +#ifndef NDEBUG +int sqlite3PagerIswriteable(DbPage *pPg){ + return pPg->flags&PGHDR_DIRTY; +} +#endif + +/* +** A call to this routine tells the pager that it is not necessary to +** write the information on page pPg back to the disk, even though +** that page might be marked as dirty. This happens, for example, when +** the page has been added as a leaf of the freelist and so its +** content no longer matters. +** +** The overlying software layer calls this routine when all of the data +** on the given page is unused. The pager marks the page as clean so +** that it does not get written to disk. +** +** Tests show that this optimization can quadruple the speed of large +** DELETE operations. +*/ +void sqlite3PagerDontWrite(PgHdr *pPg){ + Pager *pPager = pPg->pPager; + if( (pPg->flags&PGHDR_DIRTY) && pPager->nSavepoint==0 ){ + PAGERTRACE(("DONT_WRITE page %d of %d\n", pPg->pgno, PAGERID(pPager))); + IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno)) + pPg->flags |= PGHDR_DONT_WRITE; + pager_set_pagehash(pPg); + } +} + +/* +** This routine is called to increment the value of the database file +** change-counter, stored as a 4-byte big-endian integer starting at +** byte offset 24 of the pager file. The secondary change counter at +** 92 is also updated, as is the SQLite version number at offset 96. +** +** But this only happens if the pPager->changeCountDone flag is false. +** To avoid excess churning of page 1, the update only happens once. +** See also the pager_write_changecounter() routine that does an +** unconditional update of the change counters. +** +** If the isDirectMode flag is zero, then this is done by calling +** sqlite3PagerWrite() on page 1, then modifying the contents of the +** page data. In this case the file will be updated when the current +** transaction is committed. +** +** The isDirectMode flag may only be non-zero if the library was compiled +** with the SQLITE_ENABLE_ATOMIC_WRITE macro defined. In this case, +** if isDirect is non-zero, then the database file is updated directly +** by writing an updated version of page 1 using a call to the +** sqlite3OsWrite() function. +*/ +static int pager_incr_changecounter(Pager *pPager, int isDirectMode){ + int rc = SQLITE_OK; + + assert( pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + ); + assert( assert_pager_state(pPager) ); + + /* Declare and initialize constant integer 'isDirect'. If the + ** atomic-write optimization is enabled in this build, then isDirect + ** is initialized to the value passed as the isDirectMode parameter + ** to this function. Otherwise, it is always set to zero. + ** + ** The idea is that if the atomic-write optimization is not + ** enabled at compile time, the compiler can omit the tests of + ** 'isDirect' below, as well as the block enclosed in the + ** "if( isDirect )" condition. + */ +#ifndef SQLITE_ENABLE_ATOMIC_WRITE +# define DIRECT_MODE 0 + assert( isDirectMode==0 ); + UNUSED_PARAMETER(isDirectMode); +#else +# define DIRECT_MODE isDirectMode +#endif + + if( !pPager->changeCountDone && pPager->dbSize>0 ){ + PgHdr *pPgHdr; /* Reference to page 1 */ + + assert( !pPager->tempFile && isOpen(pPager->fd) ); + + /* Open page 1 of the file for writing. */ + rc = sqlite3PagerGet(pPager, 1, &pPgHdr); + assert( pPgHdr==0 || rc==SQLITE_OK ); + + /* If page one was fetched successfully, and this function is not + ** operating in direct-mode, make page 1 writable. When not in + ** direct mode, page 1 is always held in cache and hence the PagerGet() + ** above is always successful - hence the ALWAYS on rc==SQLITE_OK. + */ + if( !DIRECT_MODE && ALWAYS(rc==SQLITE_OK) ){ + rc = sqlite3PagerWrite(pPgHdr); + } + + if( rc==SQLITE_OK ){ + /* Actually do the update of the change counter */ + pager_write_changecounter(pPgHdr); + + /* If running in direct mode, write the contents of page 1 to the file. */ + if( DIRECT_MODE ){ + const void *zBuf; + assert( pPager->dbFileSize>0 ); + CODEC2(pPager, pPgHdr->pData, 1, 6, rc=SQLITE_NOMEM, zBuf); + if( rc==SQLITE_OK ){ + rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0); + } + if( rc==SQLITE_OK ){ + pPager->changeCountDone = 1; + } + }else{ + pPager->changeCountDone = 1; + } + } + + /* Release the page reference. */ + sqlite3PagerUnref(pPgHdr); + } + return rc; +} + +/* +** Sync the database file to disk. This is a no-op for in-memory databases +** or pages with the Pager.noSync flag set. +** +** If successful, or if called on a pager for which it is a no-op, this +** function returns SQLITE_OK. Otherwise, an IO error code is returned. +*/ +int sqlite3PagerSync(Pager *pPager){ + int rc = SQLITE_OK; + if( !pPager->noSync ){ + assert( !MEMDB ); + rc = sqlite3OsSync(pPager->fd, pPager->syncFlags); + }else if( isOpen(pPager->fd) ){ + assert( !MEMDB ); + rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC_OMITTED, 0); + if( rc==SQLITE_NOTFOUND ){ + rc = SQLITE_OK; + } + } + return rc; +} + +/* +** This function may only be called while a write-transaction is active in +** rollback. If the connection is in WAL mode, this call is a no-op. +** Otherwise, if the connection does not already have an EXCLUSIVE lock on +** the database file, an attempt is made to obtain one. +** +** If the EXCLUSIVE lock is already held or the attempt to obtain it is +** successful, or the connection is in WAL mode, SQLITE_OK is returned. +** Otherwise, either SQLITE_BUSY or an SQLITE_IOERR_XXX error code is +** returned. +*/ +int sqlite3PagerExclusiveLock(Pager *pPager){ + int rc = SQLITE_OK; + assert( pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + || pPager->eState==PAGER_WRITER_LOCKED + ); + assert( assert_pager_state(pPager) ); + if( 0==pagerUseWal(pPager) ){ + rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); + } + return rc; +} + +/* +** Sync the database file for the pager pPager. zMaster points to the name +** of a master journal file that should be written into the individual +** journal file. zMaster may be NULL, which is interpreted as no master +** journal (a single database transaction). +** +** This routine ensures that: +** +** * The database file change-counter is updated, +** * the journal is synced (unless the atomic-write optimization is used), +** * all dirty pages are written to the database file, +** * the database file is truncated (if required), and +** * the database file synced. +** +** The only thing that remains to commit the transaction is to finalize +** (delete, truncate or zero the first part of) the journal file (or +** delete the master journal file if specified). +** +** Note that if zMaster==NULL, this does not overwrite a previous value +** passed to an sqlite3PagerCommitPhaseOne() call. +** +** If the final parameter - noSync - is true, then the database file itself +** is not synced. The caller must call sqlite3PagerSync() directly to +** sync the database file before calling CommitPhaseTwo() to delete the +** journal file in this case. +*/ +int sqlite3PagerCommitPhaseOne( + Pager *pPager, /* Pager object */ + const char *zMaster, /* If not NULL, the master journal name */ + int noSync /* True to omit the xSync on the db file */ +){ + int rc = SQLITE_OK; /* Return code */ + + assert( pPager->eState==PAGER_WRITER_LOCKED + || pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + || pPager->eState==PAGER_ERROR + ); + assert( assert_pager_state(pPager) ); + + /* If a prior error occurred, report that error again. */ + if( NEVER(pPager->errCode) ) return pPager->errCode; + + PAGERTRACE(("DATABASE SYNC: File=%s zMaster=%s nSize=%d\n", + pPager->zFilename, zMaster, pPager->dbSize)); + + /* If no database changes have been made, return early. */ + if( pPager->eStatepBackup); + }else{ + if( pagerUseWal(pPager) ){ + PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache); + PgHdr *pPageOne = 0; + if( pList==0 ){ + /* Must have at least one page for the WAL commit flag. + ** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */ + rc = sqlite3PagerGet(pPager, 1, &pPageOne); + pList = pPageOne; + pList->pDirty = 0; + } + assert( rc==SQLITE_OK ); + if( ALWAYS(pList) ){ + rc = pagerWalFrames(pPager, pList, pPager->dbSize, 1); + } + sqlite3PagerUnref(pPageOne); + if( rc==SQLITE_OK ){ + sqlite3PcacheCleanAll(pPager->pPCache); + } + }else{ + /* The following block updates the change-counter. Exactly how it + ** does this depends on whether or not the atomic-update optimization + ** was enabled at compile time, and if this transaction meets the + ** runtime criteria to use the operation: + ** + ** * The file-system supports the atomic-write property for + ** blocks of size page-size, and + ** * This commit is not part of a multi-file transaction, and + ** * Exactly one page has been modified and store in the journal file. + ** + ** If the optimization was not enabled at compile time, then the + ** pager_incr_changecounter() function is called to update the change + ** counter in 'indirect-mode'. If the optimization is compiled in but + ** is not applicable to this transaction, call sqlite3JournalCreate() + ** to make sure the journal file has actually been created, then call + ** pager_incr_changecounter() to update the change-counter in indirect + ** mode. + ** + ** Otherwise, if the optimization is both enabled and applicable, + ** then call pager_incr_changecounter() to update the change-counter + ** in 'direct' mode. In this case the journal file will never be + ** created for this transaction. + */ + #ifdef SQLITE_ENABLE_ATOMIC_WRITE + PgHdr *pPg; + assert( isOpen(pPager->jfd) + || pPager->journalMode==PAGER_JOURNALMODE_OFF + || pPager->journalMode==PAGER_JOURNALMODE_WAL + ); + if( !zMaster && isOpen(pPager->jfd) + && pPager->journalOff==jrnlBufferSize(pPager) + && pPager->dbSize>=pPager->dbOrigSize + && (0==(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty) + ){ + /* Update the db file change counter via the direct-write method. The + ** following call will modify the in-memory representation of page 1 + ** to include the updated change counter and then write page 1 + ** directly to the database file. Because of the atomic-write + ** property of the host file-system, this is safe. + */ + rc = pager_incr_changecounter(pPager, 1); + }else{ + rc = sqlite3JournalCreate(pPager->jfd); + if( rc==SQLITE_OK ){ + rc = pager_incr_changecounter(pPager, 0); + } + } + #else + rc = pager_incr_changecounter(pPager, 0); + #endif + if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + + /* If this transaction has made the database smaller, then all pages + ** being discarded by the truncation must be written to the journal + ** file. This can only happen in auto-vacuum mode. + ** + ** Before reading the pages with page numbers larger than the + ** current value of Pager.dbSize, set dbSize back to the value + ** that it took at the start of the transaction. Otherwise, the + ** calls to sqlite3PagerGet() return zeroed pages instead of + ** reading data from the database file. + */ + #ifndef SQLITE_OMIT_AUTOVACUUM + if( pPager->dbSizedbOrigSize + && pPager->journalMode!=PAGER_JOURNALMODE_OFF + ){ + Pgno i; /* Iterator variable */ + const Pgno iSkip = PAGER_MJ_PGNO(pPager); /* Pending lock page */ + const Pgno dbSize = pPager->dbSize; /* Database image size */ + pPager->dbSize = pPager->dbOrigSize; + for( i=dbSize+1; i<=pPager->dbOrigSize; i++ ){ + if( !sqlite3BitvecTest(pPager->pInJournal, i) && i!=iSkip ){ + PgHdr *pPage; /* Page to journal */ + rc = sqlite3PagerGet(pPager, i, &pPage); + if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + rc = sqlite3PagerWrite(pPage); + sqlite3PagerUnref(pPage); + if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + } + } + pPager->dbSize = dbSize; + } + #endif + + /* Write the master journal name into the journal file. If a master + ** journal file name has already been written to the journal file, + ** or if zMaster is NULL (no master journal), then this call is a no-op. + */ + rc = writeMasterJournal(pPager, zMaster); + if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + + /* Sync the journal file and write all dirty pages to the database. + ** If the atomic-update optimization is being used, this sync will not + ** create the journal file or perform any real IO. + ** + ** Because the change-counter page was just modified, unless the + ** atomic-update optimization is used it is almost certain that the + ** journal requires a sync here. However, in locking_mode=exclusive + ** on a system under memory pressure it is just possible that this is + ** not the case. In this case it is likely enough that the redundant + ** xSync() call will be changed to a no-op by the OS anyhow. + */ + rc = syncJournal(pPager, 0); + if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + + rc = pager_write_pagelist(pPager,sqlite3PcacheDirtyList(pPager->pPCache)); + if( rc!=SQLITE_OK ){ + assert( rc!=SQLITE_IOERR_BLOCKED ); + goto commit_phase_one_exit; + } + sqlite3PcacheCleanAll(pPager->pPCache); + + /* If the file on disk is not the same size as the database image, + ** then use pager_truncate to grow or shrink the file here. + */ + if( pPager->dbSize!=pPager->dbFileSize ){ + Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_MJ_PGNO(pPager)); + assert( pPager->eState==PAGER_WRITER_DBMOD ); + rc = pager_truncate(pPager, nNew); + if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + } + + /* Finally, sync the database file. */ + if( !noSync ){ + rc = sqlite3PagerSync(pPager); + } + IOTRACE(("DBSYNC %p\n", pPager)) + } + } + +commit_phase_one_exit: + if( rc==SQLITE_OK && !pagerUseWal(pPager) ){ + pPager->eState = PAGER_WRITER_FINISHED; + } + return rc; +} + + +/* +** When this function is called, the database file has been completely +** updated to reflect the changes made by the current transaction and +** synced to disk. The journal file still exists in the file-system +** though, and if a failure occurs at this point it will eventually +** be used as a hot-journal and the current transaction rolled back. +** +** This function finalizes the journal file, either by deleting, +** truncating or partially zeroing it, so that it cannot be used +** for hot-journal rollback. Once this is done the transaction is +** irrevocably committed. +** +** If an error occurs, an IO error code is returned and the pager +** moves into the error state. Otherwise, SQLITE_OK is returned. +*/ +int sqlite3PagerCommitPhaseTwo(Pager *pPager){ + int rc = SQLITE_OK; /* Return code */ + + /* This routine should not be called if a prior error has occurred. + ** But if (due to a coding error elsewhere in the system) it does get + ** called, just return the same error code without doing anything. */ + if( NEVER(pPager->errCode) ) return pPager->errCode; + + assert( pPager->eState==PAGER_WRITER_LOCKED + || pPager->eState==PAGER_WRITER_FINISHED + || (pagerUseWal(pPager) && pPager->eState==PAGER_WRITER_CACHEMOD) + ); + assert( assert_pager_state(pPager) ); + + /* An optimization. If the database was not actually modified during + ** this transaction, the pager is running in exclusive-mode and is + ** using persistent journals, then this function is a no-op. + ** + ** The start of the journal file currently contains a single journal + ** header with the nRec field set to 0. If such a journal is used as + ** a hot-journal during hot-journal rollback, 0 changes will be made + ** to the database file. So there is no need to zero the journal + ** header. Since the pager is in exclusive mode, there is no need + ** to drop any locks either. + */ + if( pPager->eState==PAGER_WRITER_LOCKED + && pPager->exclusiveMode + && pPager->journalMode==PAGER_JOURNALMODE_PERSIST + ){ + assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) || !pPager->journalOff ); + pPager->eState = PAGER_READER; + return SQLITE_OK; + } + + PAGERTRACE(("COMMIT %d\n", PAGERID(pPager))); + rc = pager_end_transaction(pPager, pPager->setMaster); + return pager_error(pPager, rc); +} + +/* +** If a write transaction is open, then all changes made within the +** transaction are reverted and the current write-transaction is closed. +** The pager falls back to PAGER_READER state if successful, or PAGER_ERROR +** state if an error occurs. +** +** If the pager is already in PAGER_ERROR state when this function is called, +** it returns Pager.errCode immediately. No work is performed in this case. +** +** Otherwise, in rollback mode, this function performs two functions: +** +** 1) It rolls back the journal file, restoring all database file and +** in-memory cache pages to the state they were in when the transaction +** was opened, and +** +** 2) It finalizes the journal file, so that it is not used for hot +** rollback at any point in the future. +** +** Finalization of the journal file (task 2) is only performed if the +** rollback is successful. +** +** In WAL mode, all cache-entries containing data modified within the +** current transaction are either expelled from the cache or reverted to +** their pre-transaction state by re-reading data from the database or +** WAL files. The WAL transaction is then closed. +*/ +int sqlite3PagerRollback(Pager *pPager){ + int rc = SQLITE_OK; /* Return code */ + PAGERTRACE(("ROLLBACK %d\n", PAGERID(pPager))); + + /* PagerRollback() is a no-op if called in READER or OPEN state. If + ** the pager is already in the ERROR state, the rollback is not + ** attempted here. Instead, the error code is returned to the caller. + */ + assert( assert_pager_state(pPager) ); + if( pPager->eState==PAGER_ERROR ) return pPager->errCode; + if( pPager->eState<=PAGER_READER ) return SQLITE_OK; + + if( pagerUseWal(pPager) ){ + int rc2; + rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_ROLLBACK, -1); + rc2 = pager_end_transaction(pPager, pPager->setMaster); + if( rc==SQLITE_OK ) rc = rc2; + }else if( !isOpen(pPager->jfd) || pPager->eState==PAGER_WRITER_LOCKED ){ + int eState = pPager->eState; + rc = pager_end_transaction(pPager, 0); + if( !MEMDB && eState>PAGER_WRITER_LOCKED ){ + /* This can happen using journal_mode=off. Move the pager to the error + ** state to indicate that the contents of the cache may not be trusted. + ** Any active readers will get SQLITE_ABORT. + */ + pPager->errCode = SQLITE_ABORT; + pPager->eState = PAGER_ERROR; + return rc; + } + }else{ + rc = pager_playback(pPager, 0); + } + + assert( pPager->eState==PAGER_READER || rc!=SQLITE_OK ); + assert( rc==SQLITE_OK || rc==SQLITE_FULL + || rc==SQLITE_NOMEM || (rc&0xFF)==SQLITE_IOERR ); + + /* If an error occurs during a ROLLBACK, we can no longer trust the pager + ** cache. So call pager_error() on the way out to make any error persistent. + */ + return pager_error(pPager, rc); +} + +/* +** Return TRUE if the database file is opened read-only. Return FALSE +** if the database is (in theory) writable. +*/ +u8 sqlite3PagerIsreadonly(Pager *pPager){ + return pPager->readOnly; +} + +/* +** Return the number of references to the pager. +*/ +int sqlite3PagerRefcount(Pager *pPager){ + return sqlite3PcacheRefCount(pPager->pPCache); +} + +/* +** Return the approximate number of bytes of memory currently +** used by the pager and its associated cache. +*/ +int sqlite3PagerMemUsed(Pager *pPager){ + int perPageSize = pPager->pageSize + pPager->nExtra + sizeof(PgHdr) + + 5*sizeof(void*); + return perPageSize*sqlite3PcachePagecount(pPager->pPCache) + + sqlite3MallocSize(pPager) + + pPager->pageSize; +} + +/* +** Return the number of references to the specified page. +*/ +int sqlite3PagerPageRefcount(DbPage *pPage){ + return sqlite3PcachePageRefcount(pPage); +} + +#ifdef SQLITE_TEST +/* +** This routine is used for testing and analysis only. +*/ +int *sqlite3PagerStats(Pager *pPager){ + static int a[11]; + a[0] = sqlite3PcacheRefCount(pPager->pPCache); + a[1] = sqlite3PcachePagecount(pPager->pPCache); + a[2] = sqlite3PcacheGetCachesize(pPager->pPCache); + a[3] = pPager->eState==PAGER_OPEN ? -1 : (int) pPager->dbSize; + a[4] = pPager->eState; + a[5] = pPager->errCode; + a[6] = pPager->nHit; + a[7] = pPager->nMiss; + a[8] = 0; /* Used to be pPager->nOvfl */ + a[9] = pPager->nRead; + a[10] = pPager->nWrite; + return a; +} +#endif + +/* +** Parameter eStat must be either SQLITE_DBSTATUS_CACHE_HIT or +** SQLITE_DBSTATUS_CACHE_MISS. Before returning, *pnVal is incremented by the +** current cache hit or miss count, according to the value of eStat. If the +** reset parameter is non-zero, the cache hit or miss count is zeroed before +** returning. +*/ +void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, int *pnVal){ + int *piStat; + + assert( eStat==SQLITE_DBSTATUS_CACHE_HIT + || eStat==SQLITE_DBSTATUS_CACHE_MISS + ); + if( eStat==SQLITE_DBSTATUS_CACHE_HIT ){ + piStat = &pPager->nHit; + }else{ + piStat = &pPager->nMiss; + } + + *pnVal += *piStat; + if( reset ){ + *piStat = 0; + } +} + +/* +** Return true if this is an in-memory pager. +*/ +int sqlite3PagerIsMemdb(Pager *pPager){ + return MEMDB; +} + +/* +** Check that there are at least nSavepoint savepoints open. If there are +** currently less than nSavepoints open, then open one or more savepoints +** to make up the difference. If the number of savepoints is already +** equal to nSavepoint, then this function is a no-op. +** +** If a memory allocation fails, SQLITE_NOMEM is returned. If an error +** occurs while opening the sub-journal file, then an IO error code is +** returned. Otherwise, SQLITE_OK. +*/ +int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){ + int rc = SQLITE_OK; /* Return code */ + int nCurrent = pPager->nSavepoint; /* Current number of savepoints */ + + assert( pPager->eState>=PAGER_WRITER_LOCKED ); + assert( assert_pager_state(pPager) ); + + if( nSavepoint>nCurrent && pPager->useJournal ){ + int ii; /* Iterator variable */ + PagerSavepoint *aNew; /* New Pager.aSavepoint array */ + + /* Grow the Pager.aSavepoint array using realloc(). Return SQLITE_NOMEM + ** if the allocation fails. Otherwise, zero the new portion in case a + ** malloc failure occurs while populating it in the for(...) loop below. + */ + aNew = (PagerSavepoint *)sqlite3Realloc( + pPager->aSavepoint, sizeof(PagerSavepoint)*nSavepoint + ); + if( !aNew ){ + return SQLITE_NOMEM; + } + memset(&aNew[nCurrent], 0, (nSavepoint-nCurrent) * sizeof(PagerSavepoint)); + pPager->aSavepoint = aNew; + + /* Populate the PagerSavepoint structures just allocated. */ + for(ii=nCurrent; iidbSize; + if( isOpen(pPager->jfd) && pPager->journalOff>0 ){ + aNew[ii].iOffset = pPager->journalOff; + }else{ + aNew[ii].iOffset = JOURNAL_HDR_SZ(pPager); + } + aNew[ii].iSubRec = pPager->nSubRec; + aNew[ii].pInSavepoint = sqlite3BitvecCreate(pPager->dbSize); + if( !aNew[ii].pInSavepoint ){ + return SQLITE_NOMEM; + } + if( pagerUseWal(pPager) ){ + sqlite3WalSavepoint(pPager->pWal, aNew[ii].aWalData); + } + pPager->nSavepoint = ii+1; + } + assert( pPager->nSavepoint==nSavepoint ); + assertTruncateConstraint(pPager); + } + + return rc; +} + +/* +** This function is called to rollback or release (commit) a savepoint. +** The savepoint to release or rollback need not be the most recently +** created savepoint. +** +** Parameter op is always either SAVEPOINT_ROLLBACK or SAVEPOINT_RELEASE. +** If it is SAVEPOINT_RELEASE, then release and destroy the savepoint with +** index iSavepoint. If it is SAVEPOINT_ROLLBACK, then rollback all changes +** that have occurred since the specified savepoint was created. +** +** The savepoint to rollback or release is identified by parameter +** iSavepoint. A value of 0 means to operate on the outermost savepoint +** (the first created). A value of (Pager.nSavepoint-1) means operate +** on the most recently created savepoint. If iSavepoint is greater than +** (Pager.nSavepoint-1), then this function is a no-op. +** +** If a negative value is passed to this function, then the current +** transaction is rolled back. This is different to calling +** sqlite3PagerRollback() because this function does not terminate +** the transaction or unlock the database, it just restores the +** contents of the database to its original state. +** +** In any case, all savepoints with an index greater than iSavepoint +** are destroyed. If this is a release operation (op==SAVEPOINT_RELEASE), +** then savepoint iSavepoint is also destroyed. +** +** This function may return SQLITE_NOMEM if a memory allocation fails, +** or an IO error code if an IO error occurs while rolling back a +** savepoint. If no errors occur, SQLITE_OK is returned. +*/ +int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){ + int rc = pPager->errCode; /* Return code */ + + assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK ); + assert( iSavepoint>=0 || op==SAVEPOINT_ROLLBACK ); + + if( rc==SQLITE_OK && iSavepointnSavepoint ){ + int ii; /* Iterator variable */ + int nNew; /* Number of remaining savepoints after this op. */ + + /* Figure out how many savepoints will still be active after this + ** operation. Store this value in nNew. Then free resources associated + ** with any savepoints that are destroyed by this operation. + */ + nNew = iSavepoint + (( op==SAVEPOINT_RELEASE ) ? 0 : 1); + for(ii=nNew; iinSavepoint; ii++){ + sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint); + } + pPager->nSavepoint = nNew; + + /* If this is a release of the outermost savepoint, truncate + ** the sub-journal to zero bytes in size. */ + if( op==SAVEPOINT_RELEASE ){ + if( nNew==0 && isOpen(pPager->sjfd) ){ + /* Only truncate if it is an in-memory sub-journal. */ + if( sqlite3IsMemJournal(pPager->sjfd) ){ + rc = sqlite3OsTruncate(pPager->sjfd, 0); + assert( rc==SQLITE_OK ); + } + pPager->nSubRec = 0; + } + } + /* Else this is a rollback operation, playback the specified savepoint. + ** If this is a temp-file, it is possible that the journal file has + ** not yet been opened. In this case there have been no changes to + ** the database file, so the playback operation can be skipped. + */ + else if( pagerUseWal(pPager) || isOpen(pPager->jfd) ){ + PagerSavepoint *pSavepoint = (nNew==0)?0:&pPager->aSavepoint[nNew-1]; + rc = pagerPlaybackSavepoint(pPager, pSavepoint); + assert(rc!=SQLITE_DONE); + } + } + + return rc; +} + +/* +** Return the full pathname of the database file. +*/ +const char *sqlite3PagerFilename(Pager *pPager){ + return pPager->zFilename; +} + +/* +** Return the VFS structure for the pager. +*/ +const sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){ + return pPager->pVfs; +} + +/* +** Return the file handle for the database file associated +** with the pager. This might return NULL if the file has +** not yet been opened. +*/ +sqlite3_file *sqlite3PagerFile(Pager *pPager){ + return pPager->fd; +} + +/* +** Return the full pathname of the journal file. +*/ +const char *sqlite3PagerJournalname(Pager *pPager){ + return pPager->zJournal; +} + +/* +** Return true if fsync() calls are disabled for this pager. Return FALSE +** if fsync()s are executed normally. +*/ +int sqlite3PagerNosync(Pager *pPager){ + return pPager->noSync; +} + +#ifdef SQLITE_HAS_CODEC +/* +** Set or retrieve the codec for this pager +*/ +void sqlite3PagerSetCodec( + Pager *pPager, + void *(*xCodec)(void*,void*,Pgno,int), + void (*xCodecSizeChng)(void*,int,int), + void (*xCodecFree)(void*), + void *pCodec +){ + if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec); + pPager->xCodec = pPager->memDb ? 0 : xCodec; + pPager->xCodecSizeChng = xCodecSizeChng; + pPager->xCodecFree = xCodecFree; + pPager->pCodec = pCodec; + pagerReportSize(pPager); +} +void *sqlite3PagerGetCodec(Pager *pPager){ + return pPager->pCodec; +} +#endif + +#ifndef SQLITE_OMIT_AUTOVACUUM +/* +** Move the page pPg to location pgno in the file. +** +** There must be no references to the page previously located at +** pgno (which we call pPgOld) though that page is allowed to be +** in cache. If the page previously located at pgno is not already +** in the rollback journal, it is not put there by by this routine. +** +** References to the page pPg remain valid. Updating any +** meta-data associated with pPg (i.e. data stored in the nExtra bytes +** allocated along with the page) is the responsibility of the caller. +** +** A transaction must be active when this routine is called. It used to be +** required that a statement transaction was not active, but this restriction +** has been removed (CREATE INDEX needs to move a page when a statement +** transaction is active). +** +** If the fourth argument, isCommit, is non-zero, then this page is being +** moved as part of a database reorganization just before the transaction +** is being committed. In this case, it is guaranteed that the database page +** pPg refers to will not be written to again within this transaction. +** +** This function may return SQLITE_NOMEM or an IO error code if an error +** occurs. Otherwise, it returns SQLITE_OK. +*/ +int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){ + PgHdr *pPgOld; /* The page being overwritten. */ + Pgno needSyncPgno = 0; /* Old value of pPg->pgno, if sync is required */ + int rc; /* Return code */ + Pgno origPgno; /* The original page number */ + + assert( pPg->nRef>0 ); + assert( pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + ); + assert( assert_pager_state(pPager) ); + + /* In order to be able to rollback, an in-memory database must journal + ** the page we are moving from. + */ + if( MEMDB ){ + rc = sqlite3PagerWrite(pPg); + if( rc ) return rc; + } + + /* If the page being moved is dirty and has not been saved by the latest + ** savepoint, then save the current contents of the page into the + ** sub-journal now. This is required to handle the following scenario: + ** + ** BEGIN; + ** + ** SAVEPOINT one; + ** + ** ROLLBACK TO one; + ** + ** If page X were not written to the sub-journal here, it would not + ** be possible to restore its contents when the "ROLLBACK TO one" + ** statement were is processed. + ** + ** subjournalPage() may need to allocate space to store pPg->pgno into + ** one or more savepoint bitvecs. This is the reason this function + ** may return SQLITE_NOMEM. + */ + if( pPg->flags&PGHDR_DIRTY + && subjRequiresPage(pPg) + && SQLITE_OK!=(rc = subjournalPage(pPg)) + ){ + return rc; + } + + PAGERTRACE(("MOVE %d page %d (needSync=%d) moves to %d\n", + PAGERID(pPager), pPg->pgno, (pPg->flags&PGHDR_NEED_SYNC)?1:0, pgno)); + IOTRACE(("MOVE %p %d %d\n", pPager, pPg->pgno, pgno)) + + /* If the journal needs to be sync()ed before page pPg->pgno can + ** be written to, store pPg->pgno in local variable needSyncPgno. + ** + ** If the isCommit flag is set, there is no need to remember that + ** the journal needs to be sync()ed before database page pPg->pgno + ** can be written to. The caller has already promised not to write to it. + */ + if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){ + needSyncPgno = pPg->pgno; + assert( pageInJournal(pPg) || pPg->pgno>pPager->dbOrigSize ); + assert( pPg->flags&PGHDR_DIRTY ); + } + + /* If the cache contains a page with page-number pgno, remove it + ** from its hash chain. Also, if the PGHDR_NEED_SYNC flag was set for + ** page pgno before the 'move' operation, it needs to be retained + ** for the page moved there. + */ + pPg->flags &= ~PGHDR_NEED_SYNC; + pPgOld = pager_lookup(pPager, pgno); + assert( !pPgOld || pPgOld->nRef==1 ); + if( pPgOld ){ + pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC); + if( MEMDB ){ + /* Do not discard pages from an in-memory database since we might + ** need to rollback later. Just move the page out of the way. */ + sqlite3PcacheMove(pPgOld, pPager->dbSize+1); + }else{ + sqlite3PcacheDrop(pPgOld); + } + } + + origPgno = pPg->pgno; + sqlite3PcacheMove(pPg, pgno); + sqlite3PcacheMakeDirty(pPg); + + /* For an in-memory database, make sure the original page continues + ** to exist, in case the transaction needs to roll back. Use pPgOld + ** as the original page since it has already been allocated. + */ + if( MEMDB ){ + assert( pPgOld ); + sqlite3PcacheMove(pPgOld, origPgno); + sqlite3PagerUnref(pPgOld); + } + + if( needSyncPgno ){ + /* If needSyncPgno is non-zero, then the journal file needs to be + ** sync()ed before any data is written to database file page needSyncPgno. + ** Currently, no such page exists in the page-cache and the + ** "is journaled" bitvec flag has been set. This needs to be remedied by + ** loading the page into the pager-cache and setting the PGHDR_NEED_SYNC + ** flag. + ** + ** If the attempt to load the page into the page-cache fails, (due + ** to a malloc() or IO failure), clear the bit in the pInJournal[] + ** array. Otherwise, if the page is loaded and written again in + ** this transaction, it may be written to the database file before + ** it is synced into the journal file. This way, it may end up in + ** the journal file twice, but that is not a problem. + */ + PgHdr *pPgHdr; + rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr); + if( rc!=SQLITE_OK ){ + if( needSyncPgno<=pPager->dbOrigSize ){ + assert( pPager->pTmpSpace!=0 ); + sqlite3BitvecClear(pPager->pInJournal, needSyncPgno, pPager->pTmpSpace); + } + return rc; + } + pPgHdr->flags |= PGHDR_NEED_SYNC; + sqlite3PcacheMakeDirty(pPgHdr); + sqlite3PagerUnref(pPgHdr); + } + + return SQLITE_OK; +} +#endif + +/* +** Return a pointer to the data for the specified page. +*/ +void *sqlite3PagerGetData(DbPage *pPg){ + assert( pPg->nRef>0 || pPg->pPager->memDb ); + return pPg->pData; +} + +/* +** Return a pointer to the Pager.nExtra bytes of "extra" space +** allocated along with the specified page. +*/ +void *sqlite3PagerGetExtra(DbPage *pPg){ + return pPg->pExtra; +} + +/* +** Get/set the locking-mode for this pager. Parameter eMode must be one +** of PAGER_LOCKINGMODE_QUERY, PAGER_LOCKINGMODE_NORMAL or +** PAGER_LOCKINGMODE_EXCLUSIVE. If the parameter is not _QUERY, then +** the locking-mode is set to the value specified. +** +** The returned value is either PAGER_LOCKINGMODE_NORMAL or +** PAGER_LOCKINGMODE_EXCLUSIVE, indicating the current (possibly updated) +** locking-mode. +*/ +int sqlite3PagerLockingMode(Pager *pPager, int eMode){ + assert( eMode==PAGER_LOCKINGMODE_QUERY + || eMode==PAGER_LOCKINGMODE_NORMAL + || eMode==PAGER_LOCKINGMODE_EXCLUSIVE ); + assert( PAGER_LOCKINGMODE_QUERY<0 ); + assert( PAGER_LOCKINGMODE_NORMAL>=0 && PAGER_LOCKINGMODE_EXCLUSIVE>=0 ); + assert( pPager->exclusiveMode || 0==sqlite3WalHeapMemory(pPager->pWal) ); + if( eMode>=0 && !pPager->tempFile && !sqlite3WalHeapMemory(pPager->pWal) ){ + pPager->exclusiveMode = (u8)eMode; + } + return (int)pPager->exclusiveMode; +} + +/* +** Set the journal-mode for this pager. Parameter eMode must be one of: +** +** PAGER_JOURNALMODE_DELETE +** PAGER_JOURNALMODE_TRUNCATE +** PAGER_JOURNALMODE_PERSIST +** PAGER_JOURNALMODE_OFF +** PAGER_JOURNALMODE_MEMORY +** PAGER_JOURNALMODE_WAL +** +** The journalmode is set to the value specified if the change is allowed. +** The change may be disallowed for the following reasons: +** +** * An in-memory database can only have its journal_mode set to _OFF +** or _MEMORY. +** +** * Temporary databases cannot have _WAL journalmode. +** +** The returned indicate the current (possibly updated) journal-mode. +*/ +int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){ + u8 eOld = pPager->journalMode; /* Prior journalmode */ + +#ifdef SQLITE_DEBUG + /* The print_pager_state() routine is intended to be used by the debugger + ** only. We invoke it once here to suppress a compiler warning. */ + print_pager_state(pPager); +#endif + + + /* The eMode parameter is always valid */ + assert( eMode==PAGER_JOURNALMODE_DELETE + || eMode==PAGER_JOURNALMODE_TRUNCATE + || eMode==PAGER_JOURNALMODE_PERSIST + || eMode==PAGER_JOURNALMODE_OFF + || eMode==PAGER_JOURNALMODE_WAL + || eMode==PAGER_JOURNALMODE_MEMORY ); + + /* This routine is only called from the OP_JournalMode opcode, and + ** the logic there will never allow a temporary file to be changed + ** to WAL mode. + */ + assert( pPager->tempFile==0 || eMode!=PAGER_JOURNALMODE_WAL ); + + /* Do allow the journalmode of an in-memory database to be set to + ** anything other than MEMORY or OFF + */ + if( MEMDB ){ + assert( eOld==PAGER_JOURNALMODE_MEMORY || eOld==PAGER_JOURNALMODE_OFF ); + if( eMode!=PAGER_JOURNALMODE_MEMORY && eMode!=PAGER_JOURNALMODE_OFF ){ + eMode = eOld; + } + } + + if( eMode!=eOld ){ + + /* Change the journal mode. */ + assert( pPager->eState!=PAGER_ERROR ); + pPager->journalMode = (u8)eMode; + + /* When transistioning from TRUNCATE or PERSIST to any other journal + ** mode except WAL, unless the pager is in locking_mode=exclusive mode, + ** delete the journal file. + */ + assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 ); + assert( (PAGER_JOURNALMODE_PERSIST & 5)==1 ); + assert( (PAGER_JOURNALMODE_DELETE & 5)==0 ); + assert( (PAGER_JOURNALMODE_MEMORY & 5)==4 ); + assert( (PAGER_JOURNALMODE_OFF & 5)==0 ); + assert( (PAGER_JOURNALMODE_WAL & 5)==5 ); + + assert( isOpen(pPager->fd) || pPager->exclusiveMode ); + if( !pPager->exclusiveMode && (eOld & 5)==1 && (eMode & 1)==0 ){ + + /* In this case we would like to delete the journal file. If it is + ** not possible, then that is not a problem. Deleting the journal file + ** here is an optimization only. + ** + ** Before deleting the journal file, obtain a RESERVED lock on the + ** database file. This ensures that the journal file is not deleted + ** while it is in use by some other client. + */ + sqlite3OsClose(pPager->jfd); + if( pPager->eLock>=RESERVED_LOCK ){ + sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); + }else{ + int rc = SQLITE_OK; + int state = pPager->eState; + assert( state==PAGER_OPEN || state==PAGER_READER ); + if( state==PAGER_OPEN ){ + rc = sqlite3PagerSharedLock(pPager); + } + if( pPager->eState==PAGER_READER ){ + assert( rc==SQLITE_OK ); + rc = pagerLockDb(pPager, RESERVED_LOCK); + } + if( rc==SQLITE_OK ){ + sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); + } + if( rc==SQLITE_OK && state==PAGER_READER ){ + pagerUnlockDb(pPager, SHARED_LOCK); + }else if( state==PAGER_OPEN ){ + pager_unlock(pPager); + } + assert( state==pPager->eState ); + } + } + } + + /* Return the new journal mode */ + return (int)pPager->journalMode; +} + +/* +** Return the current journal mode. +*/ +int sqlite3PagerGetJournalMode(Pager *pPager){ + return (int)pPager->journalMode; +} + +/* +** Return TRUE if the pager is in a state where it is OK to change the +** journalmode. Journalmode changes can only happen when the database +** is unmodified. +*/ +int sqlite3PagerOkToChangeJournalMode(Pager *pPager){ + assert( assert_pager_state(pPager) ); + if( pPager->eState>=PAGER_WRITER_CACHEMOD ) return 0; + if( NEVER(isOpen(pPager->jfd) && pPager->journalOff>0) ) return 0; + return 1; +} + +/* +** Get/set the size-limit used for persistent journal files. +** +** Setting the size limit to -1 means no limit is enforced. +** An attempt to set a limit smaller than -1 is a no-op. +*/ +i64 sqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){ + if( iLimit>=-1 ){ + pPager->journalSizeLimit = iLimit; + sqlite3WalLimit(pPager->pWal, iLimit); + } + return pPager->journalSizeLimit; +} + +/* +** Return a pointer to the pPager->pBackup variable. The backup module +** in backup.c maintains the content of this variable. This module +** uses it opaquely as an argument to sqlite3BackupRestart() and +** sqlite3BackupUpdate() only. +*/ +sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){ + return &pPager->pBackup; +} + +#ifndef SQLITE_OMIT_VACUUM +/* +** Unless this is an in-memory or temporary database, clear the pager cache. +*/ +void sqlite3PagerClearCache(Pager *pPager){ + if( !MEMDB && pPager->tempFile==0 ) pager_reset(pPager); +} +#endif + +#ifndef SQLITE_OMIT_WAL +/* +** This function is called when the user invokes "PRAGMA wal_checkpoint", +** "PRAGMA wal_blocking_checkpoint" or calls the sqlite3_wal_checkpoint() +** or wal_blocking_checkpoint() API functions. +** +** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART. +*/ +int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){ + int rc = SQLITE_OK; + if( pPager->pWal ){ + rc = sqlite3WalCheckpoint(pPager->pWal, eMode, + pPager->xBusyHandler, pPager->pBusyHandlerArg, + pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace, + pnLog, pnCkpt + ); + } + return rc; +} + +int sqlite3PagerWalCallback(Pager *pPager){ + return sqlite3WalCallback(pPager->pWal); +} + +/* +** Return true if the underlying VFS for the given pager supports the +** primitives necessary for write-ahead logging. +*/ +int sqlite3PagerWalSupported(Pager *pPager){ + const sqlite3_io_methods *pMethods = pPager->fd->pMethods; + return pPager->exclusiveMode || (pMethods->iVersion>=2 && pMethods->xShmMap); +} + +/* +** Attempt to take an exclusive lock on the database file. If a PENDING lock +** is obtained instead, immediately release it. +*/ +static int pagerExclusiveLock(Pager *pPager){ + int rc; /* Return code */ + + assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK ); + rc = pagerLockDb(pPager, EXCLUSIVE_LOCK); + if( rc!=SQLITE_OK ){ + /* If the attempt to grab the exclusive lock failed, release the + ** pending lock that may have been obtained instead. */ + pagerUnlockDb(pPager, SHARED_LOCK); + } + + return rc; +} + +/* +** Call sqlite3WalOpen() to open the WAL handle. If the pager is in +** exclusive-locking mode when this function is called, take an EXCLUSIVE +** lock on the database file and use heap-memory to store the wal-index +** in. Otherwise, use the normal shared-memory. +*/ +static int pagerOpenWal(Pager *pPager){ + int rc = SQLITE_OK; + + assert( pPager->pWal==0 && pPager->tempFile==0 ); + assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK || pPager->noReadlock); + + /* If the pager is already in exclusive-mode, the WAL module will use + ** heap-memory for the wal-index instead of the VFS shared-memory + ** implementation. Take the exclusive lock now, before opening the WAL + ** file, to make sure this is safe. + */ + if( pPager->exclusiveMode ){ + rc = pagerExclusiveLock(pPager); + } + + /* Open the connection to the log file. If this operation fails, + ** (e.g. due to malloc() failure), return an error code. + */ + if( rc==SQLITE_OK ){ + rc = sqlite3WalOpen(pPager->pVfs, + pPager->fd, pPager->zWal, pPager->exclusiveMode, + pPager->journalSizeLimit, &pPager->pWal + ); + } + + return rc; +} + + +/* +** The caller must be holding a SHARED lock on the database file to call +** this function. +** +** If the pager passed as the first argument is open on a real database +** file (not a temp file or an in-memory database), and the WAL file +** is not already open, make an attempt to open it now. If successful, +** return SQLITE_OK. If an error occurs or the VFS used by the pager does +** not support the xShmXXX() methods, return an error code. *pbOpen is +** not modified in either case. +** +** If the pager is open on a temp-file (or in-memory database), or if +** the WAL file is already open, set *pbOpen to 1 and return SQLITE_OK +** without doing anything. +*/ +int sqlite3PagerOpenWal( + Pager *pPager, /* Pager object */ + int *pbOpen /* OUT: Set to true if call is a no-op */ +){ + int rc = SQLITE_OK; /* Return code */ + + assert( assert_pager_state(pPager) ); + assert( pPager->eState==PAGER_OPEN || pbOpen ); + assert( pPager->eState==PAGER_READER || !pbOpen ); + assert( pbOpen==0 || *pbOpen==0 ); + assert( pbOpen!=0 || (!pPager->tempFile && !pPager->pWal) ); + + if( !pPager->tempFile && !pPager->pWal ){ + if( !sqlite3PagerWalSupported(pPager) ) return SQLITE_CANTOPEN; + + /* Close any rollback journal previously open */ + sqlite3OsClose(pPager->jfd); + + rc = pagerOpenWal(pPager); + if( rc==SQLITE_OK ){ + pPager->journalMode = PAGER_JOURNALMODE_WAL; + pPager->eState = PAGER_OPEN; + } + }else{ + *pbOpen = 1; + } + + return rc; +} + +/* +** This function is called to close the connection to the log file prior +** to switching from WAL to rollback mode. +** +** Before closing the log file, this function attempts to take an +** EXCLUSIVE lock on the database file. If this cannot be obtained, an +** error (SQLITE_BUSY) is returned and the log connection is not closed. +** If successful, the EXCLUSIVE lock is not released before returning. +*/ +int sqlite3PagerCloseWal(Pager *pPager){ + int rc = SQLITE_OK; + + assert( pPager->journalMode==PAGER_JOURNALMODE_WAL ); + + /* If the log file is not already open, but does exist in the file-system, + ** it may need to be checkpointed before the connection can switch to + ** rollback mode. Open it now so this can happen. + */ + if( !pPager->pWal ){ + int logexists = 0; + rc = pagerLockDb(pPager, SHARED_LOCK); + if( rc==SQLITE_OK ){ + rc = sqlite3OsAccess( + pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &logexists + ); + } + if( rc==SQLITE_OK && logexists ){ + rc = pagerOpenWal(pPager); + } + } + + /* Checkpoint and close the log. Because an EXCLUSIVE lock is held on + ** the database file, the log and log-summary files will be deleted. + */ + if( rc==SQLITE_OK && pPager->pWal ){ + rc = pagerExclusiveLock(pPager); + if( rc==SQLITE_OK ){ + rc = sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags, + pPager->pageSize, (u8*)pPager->pTmpSpace); + pPager->pWal = 0; + } + } + return rc; +} + +#ifdef SQLITE_HAS_CODEC +/* +** This function is called by the wal module when writing page content +** into the log file. +** +** This function returns a pointer to a buffer containing the encrypted +** page content. If a malloc fails, this function may return NULL. +*/ +void *sqlite3PagerCodec(PgHdr *pPg){ + void *aData = 0; + CODEC2(pPg->pPager, pPg->pData, pPg->pgno, 6, return 0, aData); + return aData; +} +#endif /* SQLITE_HAS_CODEC */ + +#endif /* !SQLITE_OMIT_WAL */ + +#endif /* SQLITE_OMIT_DISKIO */ diff --git a/scalos/libraries/sqlite/src/pager.h b/scalos/libraries/sqlite/src/pager.h new file mode 100644 index 000000000..f68b19f6e --- /dev/null +++ b/scalos/libraries/sqlite/src/pager.h @@ -0,0 +1,184 @@ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This header file defines the interface that the sqlite page cache +** subsystem. The page cache subsystem reads and writes a file a page +** at a time and provides a journal for rollback. +*/ + +#ifndef _PAGER_H_ +#define _PAGER_H_ + +/* +** Default maximum size for persistent journal files. A negative +** value means no limit. This value may be overridden using the +** sqlite3PagerJournalSizeLimit() API. See also "PRAGMA journal_size_limit". +*/ +#ifndef SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT + #define SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT -1 +#endif + +/* +** The type used to represent a page number. The first page in a file +** is called page 1. 0 is used to represent "not a page". +*/ +typedef u32 Pgno; + +/* +** Each open file is managed by a separate instance of the "Pager" structure. +*/ +typedef struct Pager Pager; + +/* +** Handle type for pages. +*/ +typedef struct PgHdr DbPage; + +/* +** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is +** reserved for working around a windows/posix incompatibility). It is +** used in the journal to signify that the remainder of the journal file +** is devoted to storing a master journal name - there are no more pages to +** roll back. See comments for function writeMasterJournal() in pager.c +** for details. +*/ +#define PAGER_MJ_PGNO(x) ((Pgno)((PENDING_BYTE/((x)->pageSize))+1)) + +/* +** Allowed values for the flags parameter to sqlite3PagerOpen(). +** +** NOTE: These values must match the corresponding BTREE_ values in btree.h. +*/ +#define PAGER_OMIT_JOURNAL 0x0001 /* Do not use a rollback journal */ +#define PAGER_NO_READLOCK 0x0002 /* Omit readlocks on readonly files */ +#define PAGER_MEMORY 0x0004 /* In-memory database */ + +/* +** Valid values for the second argument to sqlite3PagerLockingMode(). +*/ +#define PAGER_LOCKINGMODE_QUERY -1 +#define PAGER_LOCKINGMODE_NORMAL 0 +#define PAGER_LOCKINGMODE_EXCLUSIVE 1 + +/* +** Numeric constants that encode the journalmode. +*/ +#define PAGER_JOURNALMODE_QUERY (-1) /* Query the value of journalmode */ +#define PAGER_JOURNALMODE_DELETE 0 /* Commit by deleting journal file */ +#define PAGER_JOURNALMODE_PERSIST 1 /* Commit by zeroing journal header */ +#define PAGER_JOURNALMODE_OFF 2 /* Journal omitted. */ +#define PAGER_JOURNALMODE_TRUNCATE 3 /* Commit by truncating journal */ +#define PAGER_JOURNALMODE_MEMORY 4 /* In-memory journal file */ +#define PAGER_JOURNALMODE_WAL 5 /* Use write-ahead logging */ + +/* +** The remainder of this file contains the declarations of the functions +** that make up the Pager sub-system API. See source code comments for +** a detailed description of each routine. +*/ + +/* Open and close a Pager connection. */ +int sqlite3PagerOpen( + sqlite3_vfs*, + Pager **ppPager, + const char*, + int, + int, + int, + void(*)(DbPage*) +); +int sqlite3PagerClose(Pager *pPager); +int sqlite3PagerReadFileheader(Pager*, int, unsigned char*); + +/* Functions used to configure a Pager object. */ +void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *); +int sqlite3PagerSetPagesize(Pager*, u32*, int); +int sqlite3PagerMaxPageCount(Pager*, int); +void sqlite3PagerSetCachesize(Pager*, int); +void sqlite3PagerShrink(Pager*); +void sqlite3PagerSetSafetyLevel(Pager*,int,int,int); +int sqlite3PagerLockingMode(Pager *, int); +int sqlite3PagerSetJournalMode(Pager *, int); +int sqlite3PagerGetJournalMode(Pager*); +int sqlite3PagerOkToChangeJournalMode(Pager*); +i64 sqlite3PagerJournalSizeLimit(Pager *, i64); +sqlite3_backup **sqlite3PagerBackupPtr(Pager*); + +/* Functions used to obtain and release page references. */ +int sqlite3PagerAcquire(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag); +#define sqlite3PagerGet(A,B,C) sqlite3PagerAcquire(A,B,C,0) +DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno); +void sqlite3PagerRef(DbPage*); +void sqlite3PagerUnref(DbPage*); + +/* Operations on page references. */ +int sqlite3PagerWrite(DbPage*); +void sqlite3PagerDontWrite(DbPage*); +int sqlite3PagerMovepage(Pager*,DbPage*,Pgno,int); +int sqlite3PagerPageRefcount(DbPage*); +void *sqlite3PagerGetData(DbPage *); +void *sqlite3PagerGetExtra(DbPage *); + +/* Functions used to manage pager transactions and savepoints. */ +void sqlite3PagerPagecount(Pager*, int*); +int sqlite3PagerBegin(Pager*, int exFlag, int); +int sqlite3PagerCommitPhaseOne(Pager*,const char *zMaster, int); +int sqlite3PagerExclusiveLock(Pager*); +int sqlite3PagerSync(Pager *pPager); +int sqlite3PagerCommitPhaseTwo(Pager*); +int sqlite3PagerRollback(Pager*); +int sqlite3PagerOpenSavepoint(Pager *pPager, int n); +int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint); +int sqlite3PagerSharedLock(Pager *pPager); + +int sqlite3PagerCheckpoint(Pager *pPager, int, int*, int*); +int sqlite3PagerWalSupported(Pager *pPager); +int sqlite3PagerWalCallback(Pager *pPager); +int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen); +int sqlite3PagerCloseWal(Pager *pPager); + +/* Functions used to query pager state and configuration. */ +u8 sqlite3PagerIsreadonly(Pager*); +int sqlite3PagerRefcount(Pager*); +int sqlite3PagerMemUsed(Pager*); +const char *sqlite3PagerFilename(Pager*); +const sqlite3_vfs *sqlite3PagerVfs(Pager*); +sqlite3_file *sqlite3PagerFile(Pager*); +const char *sqlite3PagerJournalname(Pager*); +int sqlite3PagerNosync(Pager*); +void *sqlite3PagerTempSpace(Pager*); +int sqlite3PagerIsMemdb(Pager*); +void sqlite3PagerCacheStat(Pager *, int, int, int *); +void sqlite3PagerClearCache(Pager *); + +/* Functions used to truncate the database file. */ +void sqlite3PagerTruncateImage(Pager*,Pgno); + +#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL) +void *sqlite3PagerCodec(DbPage *); +#endif + +/* Functions to support testing and debugging. */ +#if !defined(NDEBUG) || defined(SQLITE_TEST) + Pgno sqlite3PagerPagenumber(DbPage*); + int sqlite3PagerIswriteable(DbPage*); +#endif +#ifdef SQLITE_TEST + int *sqlite3PagerStats(Pager*); + void sqlite3PagerRefdump(Pager*); + void disable_simulated_io_errors(void); + void enable_simulated_io_errors(void); +#else +# define disable_simulated_io_errors() +# define enable_simulated_io_errors() +#endif + +#endif /* _PAGER_H_ */ diff --git a/scalos/libraries/sqlite/src/pcache.c b/scalos/libraries/sqlite/src/pcache.c new file mode 100644 index 000000000..482a188be --- /dev/null +++ b/scalos/libraries/sqlite/src/pcache.c @@ -0,0 +1,619 @@ +/* +** 2008 August 05 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file implements that page cache. +*/ +#include "sqliteInt.h" + +/* +** A complete page cache is an instance of this structure. +*/ +struct PCache { + PgHdr *pDirty, *pDirtyTail; /* List of dirty pages in LRU order */ + PgHdr *pSynced; /* Last synced page in dirty page list */ + int nRef; /* Number of referenced pages */ + int szCache; /* Configured cache size */ + int szPage; /* Size of every page in this cache */ + int szExtra; /* Size of extra space for each page */ + int bPurgeable; /* True if pages are on backing store */ + int (*xStress)(void*,PgHdr*); /* Call to try make a page clean */ + void *pStress; /* Argument to xStress */ + sqlite3_pcache *pCache; /* Pluggable cache module */ + PgHdr *pPage1; /* Reference to page 1 */ +}; + +/* +** Some of the assert() macros in this code are too expensive to run +** even during normal debugging. Use them only rarely on long-running +** tests. Enable the expensive asserts using the +** -DSQLITE_ENABLE_EXPENSIVE_ASSERT=1 compile-time option. +*/ +#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT +# define expensive_assert(X) assert(X) +#else +# define expensive_assert(X) +#endif + +/********************************** Linked List Management ********************/ + +#if !defined(NDEBUG) && defined(SQLITE_ENABLE_EXPENSIVE_ASSERT) +/* +** Check that the pCache->pSynced variable is set correctly. If it +** is not, either fail an assert or return zero. Otherwise, return +** non-zero. This is only used in debugging builds, as follows: +** +** expensive_assert( pcacheCheckSynced(pCache) ); +*/ +static int pcacheCheckSynced(PCache *pCache){ + PgHdr *p; + for(p=pCache->pDirtyTail; p!=pCache->pSynced; p=p->pDirtyPrev){ + assert( p->nRef || (p->flags&PGHDR_NEED_SYNC) ); + } + return (p==0 || p->nRef || (p->flags&PGHDR_NEED_SYNC)==0); +} +#endif /* !NDEBUG && SQLITE_ENABLE_EXPENSIVE_ASSERT */ + +/* +** Remove page pPage from the list of dirty pages. +*/ +static void pcacheRemoveFromDirtyList(PgHdr *pPage){ + PCache *p = pPage->pCache; + + assert( pPage->pDirtyNext || pPage==p->pDirtyTail ); + assert( pPage->pDirtyPrev || pPage==p->pDirty ); + + /* Update the PCache1.pSynced variable if necessary. */ + if( p->pSynced==pPage ){ + PgHdr *pSynced = pPage->pDirtyPrev; + while( pSynced && (pSynced->flags&PGHDR_NEED_SYNC) ){ + pSynced = pSynced->pDirtyPrev; + } + p->pSynced = pSynced; + } + + if( pPage->pDirtyNext ){ + pPage->pDirtyNext->pDirtyPrev = pPage->pDirtyPrev; + }else{ + assert( pPage==p->pDirtyTail ); + p->pDirtyTail = pPage->pDirtyPrev; + } + if( pPage->pDirtyPrev ){ + pPage->pDirtyPrev->pDirtyNext = pPage->pDirtyNext; + }else{ + assert( pPage==p->pDirty ); + p->pDirty = pPage->pDirtyNext; + } + pPage->pDirtyNext = 0; + pPage->pDirtyPrev = 0; + + expensive_assert( pcacheCheckSynced(p) ); +} + +/* +** Add page pPage to the head of the dirty list (PCache1.pDirty is set to +** pPage). +*/ +static void pcacheAddToDirtyList(PgHdr *pPage){ + PCache *p = pPage->pCache; + + assert( pPage->pDirtyNext==0 && pPage->pDirtyPrev==0 && p->pDirty!=pPage ); + + pPage->pDirtyNext = p->pDirty; + if( pPage->pDirtyNext ){ + assert( pPage->pDirtyNext->pDirtyPrev==0 ); + pPage->pDirtyNext->pDirtyPrev = pPage; + } + p->pDirty = pPage; + if( !p->pDirtyTail ){ + p->pDirtyTail = pPage; + } + if( !p->pSynced && 0==(pPage->flags&PGHDR_NEED_SYNC) ){ + p->pSynced = pPage; + } + expensive_assert( pcacheCheckSynced(p) ); +} + +/* +** Wrapper around the pluggable caches xUnpin method. If the cache is +** being used for an in-memory database, this function is a no-op. +*/ +static void pcacheUnpin(PgHdr *p){ + PCache *pCache = p->pCache; + if( pCache->bPurgeable ){ + if( p->pgno==1 ){ + pCache->pPage1 = 0; + } + sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, p->pPage, 0); + } +} + +/*************************************************** General Interfaces ****** +** +** Initialize and shutdown the page cache subsystem. Neither of these +** functions are threadsafe. +*/ +int sqlite3PcacheInitialize(void){ + if( sqlite3GlobalConfig.pcache2.xInit==0 ){ + /* IMPLEMENTATION-OF: R-26801-64137 If the xInit() method is NULL, then the + ** built-in default page cache is used instead of the application defined + ** page cache. */ + sqlite3PCacheSetDefault(); + } + return sqlite3GlobalConfig.pcache2.xInit(sqlite3GlobalConfig.pcache2.pArg); +} +void sqlite3PcacheShutdown(void){ + if( sqlite3GlobalConfig.pcache2.xShutdown ){ + /* IMPLEMENTATION-OF: R-26000-56589 The xShutdown() method may be NULL. */ + sqlite3GlobalConfig.pcache2.xShutdown(sqlite3GlobalConfig.pcache2.pArg); + } +} + +/* +** Return the size in bytes of a PCache object. +*/ +int sqlite3PcacheSize(void){ return sizeof(PCache); } + +/* +** Create a new PCache object. Storage space to hold the object +** has already been allocated and is passed in as the p pointer. +** The caller discovers how much space needs to be allocated by +** calling sqlite3PcacheSize(). +*/ +void sqlite3PcacheOpen( + int szPage, /* Size of every page */ + int szExtra, /* Extra space associated with each page */ + int bPurgeable, /* True if pages are on backing store */ + int (*xStress)(void*,PgHdr*),/* Call to try to make pages clean */ + void *pStress, /* Argument to xStress */ + PCache *p /* Preallocated space for the PCache */ +){ + memset(p, 0, sizeof(PCache)); + p->szPage = szPage; + p->szExtra = szExtra; + p->bPurgeable = bPurgeable; + p->xStress = xStress; + p->pStress = pStress; + p->szCache = 100; +} + +/* +** Change the page size for PCache object. The caller must ensure that there +** are no outstanding page references when this function is called. +*/ +void sqlite3PcacheSetPageSize(PCache *pCache, int szPage){ + assert( pCache->nRef==0 && pCache->pDirty==0 ); + if( pCache->pCache ){ + sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); + pCache->pCache = 0; + pCache->pPage1 = 0; + } + pCache->szPage = szPage; +} + +/* +** Compute the number of pages of cache requested. +*/ +static int numberOfCachePages(PCache *p){ + if( p->szCache>=0 ){ + return p->szCache; + }else{ + return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra)); + } +} + +/* +** Try to obtain a page from the cache. +*/ +int sqlite3PcacheFetch( + PCache *pCache, /* Obtain the page from this cache */ + Pgno pgno, /* Page number to obtain */ + int createFlag, /* If true, create page if it does not exist already */ + PgHdr **ppPage /* Write the page here */ +){ + sqlite3_pcache_page *pPage = 0; + PgHdr *pPgHdr = 0; + int eCreate; + + assert( pCache!=0 ); + assert( createFlag==1 || createFlag==0 ); + assert( pgno>0 ); + + /* If the pluggable cache (sqlite3_pcache*) has not been allocated, + ** allocate it now. + */ + if( !pCache->pCache && createFlag ){ + sqlite3_pcache *p; + p = sqlite3GlobalConfig.pcache2.xCreate( + pCache->szPage, pCache->szExtra + sizeof(PgHdr), pCache->bPurgeable + ); + if( !p ){ + return SQLITE_NOMEM; + } + sqlite3GlobalConfig.pcache2.xCachesize(p, numberOfCachePages(pCache)); + pCache->pCache = p; + } + + eCreate = createFlag * (1 + (!pCache->bPurgeable || !pCache->pDirty)); + if( pCache->pCache ){ + pPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate); + } + + if( !pPage && eCreate==1 ){ + PgHdr *pPg; + + /* Find a dirty page to write-out and recycle. First try to find a + ** page that does not require a journal-sync (one with PGHDR_NEED_SYNC + ** cleared), but if that is not possible settle for any other + ** unreferenced dirty page. + */ + expensive_assert( pcacheCheckSynced(pCache) ); + for(pPg=pCache->pSynced; + pPg && (pPg->nRef || (pPg->flags&PGHDR_NEED_SYNC)); + pPg=pPg->pDirtyPrev + ); + pCache->pSynced = pPg; + if( !pPg ){ + for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pDirtyPrev); + } + if( pPg ){ + int rc; +#ifdef SQLITE_LOG_CACHE_SPILL + sqlite3_log(SQLITE_FULL, + "spill page %d making room for %d - cache used: %d/%d", + pPg->pgno, pgno, + sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache), + numberOfCachePages(pCache)); +#endif + rc = pCache->xStress(pCache->pStress, pPg); + if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){ + return rc; + } + } + + pPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2); + } + + if( pPage ){ + pPgHdr = (PgHdr *)pPage->pExtra; + + if( !pPgHdr->pPage ){ + memset(pPgHdr, 0, sizeof(PgHdr)); + pPgHdr->pPage = pPage; + pPgHdr->pData = pPage->pBuf; + pPgHdr->pExtra = (void *)&pPgHdr[1]; + memset(pPgHdr->pExtra, 0, pCache->szExtra); + pPgHdr->pCache = pCache; + pPgHdr->pgno = pgno; + } + assert( pPgHdr->pCache==pCache ); + assert( pPgHdr->pgno==pgno ); + assert( pPgHdr->pData==pPage->pBuf ); + assert( pPgHdr->pExtra==(void *)&pPgHdr[1] ); + + if( 0==pPgHdr->nRef ){ + pCache->nRef++; + } + pPgHdr->nRef++; + if( pgno==1 ){ + pCache->pPage1 = pPgHdr; + } + } + *ppPage = pPgHdr; + return (pPgHdr==0 && eCreate) ? SQLITE_NOMEM : SQLITE_OK; +} + +/* +** Decrement the reference count on a page. If the page is clean and the +** reference count drops to 0, then it is made elible for recycling. +*/ +void sqlite3PcacheRelease(PgHdr *p){ + assert( p->nRef>0 ); + p->nRef--; + if( p->nRef==0 ){ + PCache *pCache = p->pCache; + pCache->nRef--; + if( (p->flags&PGHDR_DIRTY)==0 ){ + pcacheUnpin(p); + }else{ + /* Move the page to the head of the dirty list. */ + pcacheRemoveFromDirtyList(p); + pcacheAddToDirtyList(p); + } + } +} + +/* +** Increase the reference count of a supplied page by 1. +*/ +void sqlite3PcacheRef(PgHdr *p){ + assert(p->nRef>0); + p->nRef++; +} + +/* +** Drop a page from the cache. There must be exactly one reference to the +** page. This function deletes that reference, so after it returns the +** page pointed to by p is invalid. +*/ +void sqlite3PcacheDrop(PgHdr *p){ + PCache *pCache; + assert( p->nRef==1 ); + if( p->flags&PGHDR_DIRTY ){ + pcacheRemoveFromDirtyList(p); + } + pCache = p->pCache; + pCache->nRef--; + if( p->pgno==1 ){ + pCache->pPage1 = 0; + } + sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, p->pPage, 1); +} + +/* +** Make sure the page is marked as dirty. If it isn't dirty already, +** make it so. +*/ +void sqlite3PcacheMakeDirty(PgHdr *p){ + p->flags &= ~PGHDR_DONT_WRITE; + assert( p->nRef>0 ); + if( 0==(p->flags & PGHDR_DIRTY) ){ + p->flags |= PGHDR_DIRTY; + pcacheAddToDirtyList( p); + } +} + +/* +** Make sure the page is marked as clean. If it isn't clean already, +** make it so. +*/ +void sqlite3PcacheMakeClean(PgHdr *p){ + if( (p->flags & PGHDR_DIRTY) ){ + pcacheRemoveFromDirtyList(p); + p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC); + if( p->nRef==0 ){ + pcacheUnpin(p); + } + } +} + +/* +** Make every page in the cache clean. +*/ +void sqlite3PcacheCleanAll(PCache *pCache){ + PgHdr *p; + while( (p = pCache->pDirty)!=0 ){ + sqlite3PcacheMakeClean(p); + } +} + +/* +** Clear the PGHDR_NEED_SYNC flag from all dirty pages. +*/ +void sqlite3PcacheClearSyncFlags(PCache *pCache){ + PgHdr *p; + for(p=pCache->pDirty; p; p=p->pDirtyNext){ + p->flags &= ~PGHDR_NEED_SYNC; + } + pCache->pSynced = pCache->pDirtyTail; +} + +/* +** Change the page number of page p to newPgno. +*/ +void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){ + PCache *pCache = p->pCache; + assert( p->nRef>0 ); + assert( newPgno>0 ); + sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno); + p->pgno = newPgno; + if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){ + pcacheRemoveFromDirtyList(p); + pcacheAddToDirtyList(p); + } +} + +/* +** Drop every cache entry whose page number is greater than "pgno". The +** caller must ensure that there are no outstanding references to any pages +** other than page 1 with a page number greater than pgno. +** +** If there is a reference to page 1 and the pgno parameter passed to this +** function is 0, then the data area associated with page 1 is zeroed, but +** the page object is not dropped. +*/ +void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){ + if( pCache->pCache ){ + PgHdr *p; + PgHdr *pNext; + for(p=pCache->pDirty; p; p=pNext){ + pNext = p->pDirtyNext; + /* This routine never gets call with a positive pgno except right + ** after sqlite3PcacheCleanAll(). So if there are dirty pages, + ** it must be that pgno==0. + */ + assert( p->pgno>0 ); + if( ALWAYS(p->pgno>pgno) ){ + assert( p->flags&PGHDR_DIRTY ); + sqlite3PcacheMakeClean(p); + } + } + if( pgno==0 && pCache->pPage1 ){ + memset(pCache->pPage1->pData, 0, pCache->szPage); + pgno = 1; + } + sqlite3GlobalConfig.pcache2.xTruncate(pCache->pCache, pgno+1); + } +} + +/* +** Close a cache. +*/ +void sqlite3PcacheClose(PCache *pCache){ + if( pCache->pCache ){ + sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); + } +} + +/* +** Discard the contents of the cache. +*/ +void sqlite3PcacheClear(PCache *pCache){ + sqlite3PcacheTruncate(pCache, 0); +} + +/* +** Merge two lists of pages connected by pDirty and in pgno order. +** Do not both fixing the pDirtyPrev pointers. +*/ +static PgHdr *pcacheMergeDirtyList(PgHdr *pA, PgHdr *pB){ + PgHdr result, *pTail; + pTail = &result; + while( pA && pB ){ + if( pA->pgnopgno ){ + pTail->pDirty = pA; + pTail = pA; + pA = pA->pDirty; + }else{ + pTail->pDirty = pB; + pTail = pB; + pB = pB->pDirty; + } + } + if( pA ){ + pTail->pDirty = pA; + }else if( pB ){ + pTail->pDirty = pB; + }else{ + pTail->pDirty = 0; + } + return result.pDirty; +} + +/* +** Sort the list of pages in accending order by pgno. Pages are +** connected by pDirty pointers. The pDirtyPrev pointers are +** corrupted by this sort. +** +** Since there cannot be more than 2^31 distinct pages in a database, +** there cannot be more than 31 buckets required by the merge sorter. +** One extra bucket is added to catch overflow in case something +** ever changes to make the previous sentence incorrect. +*/ +#define N_SORT_BUCKET 32 +static PgHdr *pcacheSortDirtyList(PgHdr *pIn){ + PgHdr *a[N_SORT_BUCKET], *p; + int i; + memset(a, 0, sizeof(a)); + while( pIn ){ + p = pIn; + pIn = p->pDirty; + p->pDirty = 0; + for(i=0; ALWAYS(ipDirty; p; p=p->pDirtyNext){ + p->pDirty = p->pDirtyNext; + } + return pcacheSortDirtyList(pCache->pDirty); +} + +/* +** Return the total number of referenced pages held by the cache. +*/ +int sqlite3PcacheRefCount(PCache *pCache){ + return pCache->nRef; +} + +/* +** Return the number of references to the page supplied as an argument. +*/ +int sqlite3PcachePageRefcount(PgHdr *p){ + return p->nRef; +} + +/* +** Return the total number of pages in the cache. +*/ +int sqlite3PcachePagecount(PCache *pCache){ + int nPage = 0; + if( pCache->pCache ){ + nPage = sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache); + } + return nPage; +} + +#ifdef SQLITE_TEST +/* +** Get the suggested cache-size value. +*/ +int sqlite3PcacheGetCachesize(PCache *pCache){ + return numberOfCachePages(pCache); +} +#endif + +/* +** Set the suggested cache-size value. +*/ +void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){ + pCache->szCache = mxPage; + if( pCache->pCache ){ + sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache, + numberOfCachePages(pCache)); + } +} + +/* +** Free up as much memory as possible from the page cache. +*/ +void sqlite3PcacheShrink(PCache *pCache){ + if( pCache->pCache ){ + sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache); + } +} + +#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG) +/* +** For all dirty pages currently in the cache, invoke the specified +** callback. This is only used if the SQLITE_CHECK_PAGES macro is +** defined. +*/ +void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)){ + PgHdr *pDirty; + for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext){ + xIter(pDirty); + } +} +#endif diff --git a/scalos/libraries/sqlite/src/pcache.h b/scalos/libraries/sqlite/src/pcache.h new file mode 100644 index 000000000..82543dbc3 --- /dev/null +++ b/scalos/libraries/sqlite/src/pcache.h @@ -0,0 +1,159 @@ +/* +** 2008 August 05 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This header file defines the interface that the sqlite page cache +** subsystem. +*/ + +#ifndef _PCACHE_H_ + +typedef struct PgHdr PgHdr; +typedef struct PCache PCache; + +/* +** Every page in the cache is controlled by an instance of the following +** structure. +*/ +struct PgHdr { + sqlite3_pcache_page *pPage; /* Pcache object page handle */ + void *pData; /* Page data */ + void *pExtra; /* Extra content */ + PgHdr *pDirty; /* Transient list of dirty pages */ + Pgno pgno; /* Page number for this page */ + Pager *pPager; /* The pager this page is part of */ +#ifdef SQLITE_CHECK_PAGES + u32 pageHash; /* Hash of page content */ +#endif + u16 flags; /* PGHDR flags defined below */ + + /********************************************************************** + ** Elements above are public. All that follows is private to pcache.c + ** and should not be accessed by other modules. + */ + i16 nRef; /* Number of users of this page */ + PCache *pCache; /* Cache that owns this page */ + + PgHdr *pDirtyNext; /* Next element in list of dirty pages */ + PgHdr *pDirtyPrev; /* Previous element in list of dirty pages */ +}; + +/* Bit values for PgHdr.flags */ +#define PGHDR_DIRTY 0x002 /* Page has changed */ +#define PGHDR_NEED_SYNC 0x004 /* Fsync the rollback journal before + ** writing this page to the database */ +#define PGHDR_NEED_READ 0x008 /* Content is unread */ +#define PGHDR_REUSE_UNLIKELY 0x010 /* A hint that reuse is unlikely */ +#define PGHDR_DONT_WRITE 0x020 /* Do not write content to disk */ + +/* Initialize and shutdown the page cache subsystem */ +int sqlite3PcacheInitialize(void); +void sqlite3PcacheShutdown(void); + +/* Page cache buffer management: +** These routines implement SQLITE_CONFIG_PAGECACHE. +*/ +void sqlite3PCacheBufferSetup(void *, int sz, int n); + +/* Create a new pager cache. +** Under memory stress, invoke xStress to try to make pages clean. +** Only clean and unpinned pages can be reclaimed. +*/ +void sqlite3PcacheOpen( + int szPage, /* Size of every page */ + int szExtra, /* Extra space associated with each page */ + int bPurgeable, /* True if pages are on backing store */ + int (*xStress)(void*, PgHdr*), /* Call to try to make pages clean */ + void *pStress, /* Argument to xStress */ + PCache *pToInit /* Preallocated space for the PCache */ +); + +/* Modify the page-size after the cache has been created. */ +void sqlite3PcacheSetPageSize(PCache *, int); + +/* Return the size in bytes of a PCache object. Used to preallocate +** storage space. +*/ +int sqlite3PcacheSize(void); + +/* One release per successful fetch. Page is pinned until released. +** Reference counted. +*/ +int sqlite3PcacheFetch(PCache*, Pgno, int createFlag, PgHdr**); +void sqlite3PcacheRelease(PgHdr*); + +void sqlite3PcacheDrop(PgHdr*); /* Remove page from cache */ +void sqlite3PcacheMakeDirty(PgHdr*); /* Make sure page is marked dirty */ +void sqlite3PcacheMakeClean(PgHdr*); /* Mark a single page as clean */ +void sqlite3PcacheCleanAll(PCache*); /* Mark all dirty list pages as clean */ + +/* Change a page number. Used by incr-vacuum. */ +void sqlite3PcacheMove(PgHdr*, Pgno); + +/* Remove all pages with pgno>x. Reset the cache if x==0 */ +void sqlite3PcacheTruncate(PCache*, Pgno x); + +/* Get a list of all dirty pages in the cache, sorted by page number */ +PgHdr *sqlite3PcacheDirtyList(PCache*); + +/* Reset and close the cache object */ +void sqlite3PcacheClose(PCache*); + +/* Clear flags from pages of the page cache */ +void sqlite3PcacheClearSyncFlags(PCache *); + +/* Discard the contents of the cache */ +void sqlite3PcacheClear(PCache*); + +/* Return the total number of outstanding page references */ +int sqlite3PcacheRefCount(PCache*); + +/* Increment the reference count of an existing page */ +void sqlite3PcacheRef(PgHdr*); + +int sqlite3PcachePageRefcount(PgHdr*); + +/* Return the total number of pages stored in the cache */ +int sqlite3PcachePagecount(PCache*); + +#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG) +/* Iterate through all dirty pages currently stored in the cache. This +** interface is only available if SQLITE_CHECK_PAGES is defined when the +** library is built. +*/ +void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)); +#endif + +/* Set and get the suggested cache-size for the specified pager-cache. +** +** If no global maximum is configured, then the system attempts to limit +** the total number of pages cached by purgeable pager-caches to the sum +** of the suggested cache-sizes. +*/ +void sqlite3PcacheSetCachesize(PCache *, int); +#ifdef SQLITE_TEST +int sqlite3PcacheGetCachesize(PCache *); +#endif + +/* Free up as much memory as possible from the page cache */ +void sqlite3PcacheShrink(PCache*); + +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT +/* Try to return memory used by the pcache module to the main memory heap */ +int sqlite3PcacheReleaseMemory(int); +#endif + +#ifdef SQLITE_TEST +void sqlite3PcacheStats(int*,int*,int*,int*); +#endif + +void sqlite3PCacheSetDefault(void); + +#endif /* _PCACHE_H_ */ diff --git a/scalos/libraries/sqlite/src/pcache1.c b/scalos/libraries/sqlite/src/pcache1.c new file mode 100644 index 000000000..f76d7c8e8 --- /dev/null +++ b/scalos/libraries/sqlite/src/pcache1.c @@ -0,0 +1,1019 @@ +/* +** 2008 November 05 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file implements the default page cache implementation (the +** sqlite3_pcache interface). It also contains part of the implementation +** of the SQLITE_CONFIG_PAGECACHE and sqlite3_release_memory() features. +** If the default page cache implementation is overriden, then neither of +** these two features are available. +*/ + +#include "sqliteInt.h" + +typedef struct PCache1 PCache1; +typedef struct PgHdr1 PgHdr1; +typedef struct PgFreeslot PgFreeslot; +typedef struct PGroup PGroup; + +/* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set +** of one or more PCaches that are able to recycle each others unpinned +** pages when they are under memory pressure. A PGroup is an instance of +** the following object. +** +** This page cache implementation works in one of two modes: +** +** (1) Every PCache is the sole member of its own PGroup. There is +** one PGroup per PCache. +** +** (2) There is a single global PGroup that all PCaches are a member +** of. +** +** Mode 1 uses more memory (since PCache instances are not able to rob +** unused pages from other PCaches) but it also operates without a mutex, +** and is therefore often faster. Mode 2 requires a mutex in order to be +** threadsafe, but recycles pages more efficiently. +** +** For mode (1), PGroup.mutex is NULL. For mode (2) there is only a single +** PGroup which is the pcache1.grp global variable and its mutex is +** SQLITE_MUTEX_STATIC_LRU. +*/ +struct PGroup { + sqlite3_mutex *mutex; /* MUTEX_STATIC_LRU or NULL */ + unsigned int nMaxPage; /* Sum of nMax for purgeable caches */ + unsigned int nMinPage; /* Sum of nMin for purgeable caches */ + unsigned int mxPinned; /* nMaxpage + 10 - nMinPage */ + unsigned int nCurrentPage; /* Number of purgeable pages allocated */ + PgHdr1 *pLruHead, *pLruTail; /* LRU list of unpinned pages */ +}; + +/* Each page cache is an instance of the following object. Every +** open database file (including each in-memory database and each +** temporary or transient database) has a single page cache which +** is an instance of this object. +** +** Pointers to structures of this type are cast and returned as +** opaque sqlite3_pcache* handles. +*/ +struct PCache1 { + /* Cache configuration parameters. Page size (szPage) and the purgeable + ** flag (bPurgeable) are set when the cache is created. nMax may be + ** modified at any time by a call to the pcache1Cachesize() method. + ** The PGroup mutex must be held when accessing nMax. + */ + PGroup *pGroup; /* PGroup this cache belongs to */ + int szPage; /* Size of allocated pages in bytes */ + int szExtra; /* Size of extra space in bytes */ + int bPurgeable; /* True if cache is purgeable */ + unsigned int nMin; /* Minimum number of pages reserved */ + unsigned int nMax; /* Configured "cache_size" value */ + unsigned int n90pct; /* nMax*9/10 */ + + /* Hash table of all pages. The following variables may only be accessed + ** when the accessor is holding the PGroup mutex. + */ + unsigned int nRecyclable; /* Number of pages in the LRU list */ + unsigned int nPage; /* Total number of pages in apHash */ + unsigned int nHash; /* Number of slots in apHash[] */ + PgHdr1 **apHash; /* Hash table for fast lookup by key */ + + unsigned int iMaxKey; /* Largest key seen since xTruncate() */ +}; + +/* +** Each cache entry is represented by an instance of the following +** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of +** PgHdr1.pCache->szPage bytes is allocated directly before this structure +** in memory. +*/ +struct PgHdr1 { + sqlite3_pcache_page page; + unsigned int iKey; /* Key value (page number) */ + PgHdr1 *pNext; /* Next in hash table chain */ + PCache1 *pCache; /* Cache that currently owns this page */ + PgHdr1 *pLruNext; /* Next in LRU list of unpinned pages */ + PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */ +}; + +/* +** Free slots in the allocator used to divide up the buffer provided using +** the SQLITE_CONFIG_PAGECACHE mechanism. +*/ +struct PgFreeslot { + PgFreeslot *pNext; /* Next free slot */ +}; + +/* +** Global data used by this cache. +*/ +static SQLITE_WSD struct PCacheGlobal { + PGroup grp; /* The global PGroup for mode (2) */ + + /* Variables related to SQLITE_CONFIG_PAGECACHE settings. The + ** szSlot, nSlot, pStart, pEnd, nReserve, and isInit values are all + ** fixed at sqlite3_initialize() time and do not require mutex protection. + ** The nFreeSlot and pFree values do require mutex protection. + */ + int isInit; /* True if initialized */ + int szSlot; /* Size of each free slot */ + int nSlot; /* The number of pcache slots */ + int nReserve; /* Try to keep nFreeSlot above this */ + void *pStart, *pEnd; /* Bounds of pagecache malloc range */ + /* Above requires no mutex. Use mutex below for variable that follow. */ + sqlite3_mutex *mutex; /* Mutex for accessing the following: */ + int nFreeSlot; /* Number of unused pcache slots */ + PgFreeslot *pFree; /* Free page blocks */ + /* The following value requires a mutex to change. We skip the mutex on + ** reading because (1) most platforms read a 32-bit integer atomically and + ** (2) even if an incorrect value is read, no great harm is done since this + ** is really just an optimization. */ + int bUnderPressure; /* True if low on PAGECACHE memory */ +} pcache1_g; + +/* +** All code in this file should access the global structure above via the +** alias "pcache1". This ensures that the WSD emulation is used when +** compiling for systems that do not support real WSD. +*/ +#define pcache1 (GLOBAL(struct PCacheGlobal, pcache1_g)) + +/* +** Macros to enter and leave the PCache LRU mutex. +*/ +#define pcache1EnterMutex(X) sqlite3_mutex_enter((X)->mutex) +#define pcache1LeaveMutex(X) sqlite3_mutex_leave((X)->mutex) + +/******************************************************************************/ +/******** Page Allocation/SQLITE_CONFIG_PCACHE Related Functions **************/ + +/* +** This function is called during initialization if a static buffer is +** supplied to use for the page-cache by passing the SQLITE_CONFIG_PAGECACHE +** verb to sqlite3_config(). Parameter pBuf points to an allocation large +** enough to contain 'n' buffers of 'sz' bytes each. +** +** This routine is called from sqlite3_initialize() and so it is guaranteed +** to be serialized already. There is no need for further mutexing. +*/ +void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){ + if( pcache1.isInit ){ + PgFreeslot *p; + sz = ROUNDDOWN8(sz); + pcache1.szSlot = sz; + pcache1.nSlot = pcache1.nFreeSlot = n; + pcache1.nReserve = n>90 ? 10 : (n/10 + 1); + pcache1.pStart = pBuf; + pcache1.pFree = 0; + pcache1.bUnderPressure = 0; + while( n-- ){ + p = (PgFreeslot*)pBuf; + p->pNext = pcache1.pFree; + pcache1.pFree = p; + pBuf = (void*)&((char*)pBuf)[sz]; + } + pcache1.pEnd = pBuf; + } +} + +/* +** Malloc function used within this file to allocate space from the buffer +** configured using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no +** such buffer exists or there is no space left in it, this function falls +** back to sqlite3Malloc(). +** +** Multiple threads can run this routine at the same time. Global variables +** in pcache1 need to be protected via mutex. +*/ +static void *pcache1Alloc(int nByte){ + void *p = 0; + assert( sqlite3_mutex_notheld(pcache1.grp.mutex) ); + sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte); + if( nByte<=pcache1.szSlot ){ + sqlite3_mutex_enter(pcache1.mutex); + p = (PgHdr1 *)pcache1.pFree; + if( p ){ + pcache1.pFree = pcache1.pFree->pNext; + pcache1.nFreeSlot--; + pcache1.bUnderPressure = pcache1.nFreeSlot=0 ); + sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, 1); + } + sqlite3_mutex_leave(pcache1.mutex); + } + if( p==0 ){ + /* Memory is not available in the SQLITE_CONFIG_PAGECACHE pool. Get + ** it from sqlite3Malloc instead. + */ + p = sqlite3Malloc(nByte); + if( p ){ + int sz = sqlite3MallocSize(p); + sqlite3_mutex_enter(pcache1.mutex); + sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz); + sqlite3_mutex_leave(pcache1.mutex); + } + sqlite3MemdebugSetType(p, MEMTYPE_PCACHE); + } + return p; +} + +/* +** Free an allocated buffer obtained from pcache1Alloc(). +*/ +static int pcache1Free(void *p){ + int nFreed = 0; + if( p==0 ) return 0; + if( p>=pcache1.pStart && ppNext = pcache1.pFree; + pcache1.pFree = pSlot; + pcache1.nFreeSlot++; + pcache1.bUnderPressure = pcache1.nFreeSlot=pcache1.pStart && ppGroup->mutex) ); + pcache1LeaveMutex(pCache->pGroup); +#ifdef SQLITE_PCACHE_SEPARATE_HEADER + pPg = pcache1Alloc(pCache->szPage); + p = sqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra); + if( !pPg || !p ){ + pcache1Free(pPg); + sqlite3_free(p); + pPg = 0; + } +#else + pPg = pcache1Alloc(sizeof(PgHdr1) + pCache->szPage + pCache->szExtra); + p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage]; +#endif + pcache1EnterMutex(pCache->pGroup); + + if( pPg ){ + p->page.pBuf = pPg; + p->page.pExtra = &p[1]; + if( pCache->bPurgeable ){ + pCache->pGroup->nCurrentPage++; + } + return p; + } + return 0; +} + +/* +** Free a page object allocated by pcache1AllocPage(). +** +** The pointer is allowed to be NULL, which is prudent. But it turns out +** that the current implementation happens to never call this routine +** with a NULL pointer, so we mark the NULL test with ALWAYS(). +*/ +static void pcache1FreePage(PgHdr1 *p){ + if( ALWAYS(p) ){ + PCache1 *pCache = p->pCache; + assert( sqlite3_mutex_held(p->pCache->pGroup->mutex) ); + pcache1Free(p->page.pBuf); +#ifdef SQLITE_PCACHE_SEPARATE_HEADER + sqlite3_free(p); +#endif + if( pCache->bPurgeable ){ + pCache->pGroup->nCurrentPage--; + } + } +} + +/* +** Malloc function used by SQLite to obtain space from the buffer configured +** using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no such buffer +** exists, this function falls back to sqlite3Malloc(). +*/ +void *sqlite3PageMalloc(int sz){ + return pcache1Alloc(sz); +} + +/* +** Free an allocated buffer obtained from sqlite3PageMalloc(). +*/ +void sqlite3PageFree(void *p){ + pcache1Free(p); +} + + +/* +** Return true if it desirable to avoid allocating a new page cache +** entry. +** +** If memory was allocated specifically to the page cache using +** SQLITE_CONFIG_PAGECACHE but that memory has all been used, then +** it is desirable to avoid allocating a new page cache entry because +** presumably SQLITE_CONFIG_PAGECACHE was suppose to be sufficient +** for all page cache needs and we should not need to spill the +** allocation onto the heap. +** +** Or, the heap is used for all page cache memory but the heap is +** under memory pressure, then again it is desirable to avoid +** allocating a new page cache entry in order to avoid stressing +** the heap even further. +*/ +static int pcache1UnderMemoryPressure(PCache1 *pCache){ + if( pcache1.nSlot && (pCache->szPage+pCache->szExtra)<=pcache1.szSlot ){ + return pcache1.bUnderPressure; + }else{ + return sqlite3HeapNearlyFull(); + } +} + +/******************************************************************************/ +/******** General Implementation Functions ************************************/ + +/* +** This function is used to resize the hash table used by the cache passed +** as the first argument. +** +** The PCache mutex must be held when this function is called. +*/ +static int pcache1ResizeHash(PCache1 *p){ + PgHdr1 **apNew; + unsigned int nNew; + unsigned int i; + + assert( sqlite3_mutex_held(p->pGroup->mutex) ); + + nNew = p->nHash*2; + if( nNew<256 ){ + nNew = 256; + } + + pcache1LeaveMutex(p->pGroup); + if( p->nHash ){ sqlite3BeginBenignMalloc(); } + apNew = (PgHdr1 **)sqlite3_malloc(sizeof(PgHdr1 *)*nNew); + if( p->nHash ){ sqlite3EndBenignMalloc(); } + pcache1EnterMutex(p->pGroup); + if( apNew ){ + memset(apNew, 0, sizeof(PgHdr1 *)*nNew); + for(i=0; inHash; i++){ + PgHdr1 *pPage; + PgHdr1 *pNext = p->apHash[i]; + while( (pPage = pNext)!=0 ){ + unsigned int h = pPage->iKey % nNew; + pNext = pPage->pNext; + pPage->pNext = apNew[h]; + apNew[h] = pPage; + } + } + sqlite3_free(p->apHash); + p->apHash = apNew; + p->nHash = nNew; + } + + return (p->apHash ? SQLITE_OK : SQLITE_NOMEM); +} + +/* +** This function is used internally to remove the page pPage from the +** PGroup LRU list, if is part of it. If pPage is not part of the PGroup +** LRU list, then this function is a no-op. +** +** The PGroup mutex must be held when this function is called. +** +** If pPage is NULL then this routine is a no-op. +*/ +static void pcache1PinPage(PgHdr1 *pPage){ + PCache1 *pCache; + PGroup *pGroup; + + if( pPage==0 ) return; + pCache = pPage->pCache; + pGroup = pCache->pGroup; + assert( sqlite3_mutex_held(pGroup->mutex) ); + if( pPage->pLruNext || pPage==pGroup->pLruTail ){ + if( pPage->pLruPrev ){ + pPage->pLruPrev->pLruNext = pPage->pLruNext; + } + if( pPage->pLruNext ){ + pPage->pLruNext->pLruPrev = pPage->pLruPrev; + } + if( pGroup->pLruHead==pPage ){ + pGroup->pLruHead = pPage->pLruNext; + } + if( pGroup->pLruTail==pPage ){ + pGroup->pLruTail = pPage->pLruPrev; + } + pPage->pLruNext = 0; + pPage->pLruPrev = 0; + pPage->pCache->nRecyclable--; + } +} + + +/* +** Remove the page supplied as an argument from the hash table +** (PCache1.apHash structure) that it is currently stored in. +** +** The PGroup mutex must be held when this function is called. +*/ +static void pcache1RemoveFromHash(PgHdr1 *pPage){ + unsigned int h; + PCache1 *pCache = pPage->pCache; + PgHdr1 **pp; + + assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); + h = pPage->iKey % pCache->nHash; + for(pp=&pCache->apHash[h]; (*pp)!=pPage; pp=&(*pp)->pNext); + *pp = (*pp)->pNext; + + pCache->nPage--; +} + +/* +** If there are currently more than nMaxPage pages allocated, try +** to recycle pages to reduce the number allocated to nMaxPage. +*/ +static void pcache1EnforceMaxPage(PGroup *pGroup){ + assert( sqlite3_mutex_held(pGroup->mutex) ); + while( pGroup->nCurrentPage>pGroup->nMaxPage && pGroup->pLruTail ){ + PgHdr1 *p = pGroup->pLruTail; + assert( p->pCache->pGroup==pGroup ); + pcache1PinPage(p); + pcache1RemoveFromHash(p); + pcache1FreePage(p); + } +} + +/* +** Discard all pages from cache pCache with a page number (key value) +** greater than or equal to iLimit. Any pinned pages that meet this +** criteria are unpinned before they are discarded. +** +** The PCache mutex must be held when this function is called. +*/ +static void pcache1TruncateUnsafe( + PCache1 *pCache, /* The cache to truncate */ + unsigned int iLimit /* Drop pages with this pgno or larger */ +){ + TESTONLY( unsigned int nPage = 0; ) /* To assert pCache->nPage is correct */ + unsigned int h; + assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); + for(h=0; hnHash; h++){ + PgHdr1 **pp = &pCache->apHash[h]; + PgHdr1 *pPage; + while( (pPage = *pp)!=0 ){ + if( pPage->iKey>=iLimit ){ + pCache->nPage--; + *pp = pPage->pNext; + pcache1PinPage(pPage); + pcache1FreePage(pPage); + }else{ + pp = &pPage->pNext; + TESTONLY( nPage++; ) + } + } + } + assert( pCache->nPage==nPage ); +} + +/******************************************************************************/ +/******** sqlite3_pcache Methods **********************************************/ + +/* +** Implementation of the sqlite3_pcache.xInit method. +*/ +static int pcache1Init(void *NotUsed){ + UNUSED_PARAMETER(NotUsed); + assert( pcache1.isInit==0 ); + memset(&pcache1, 0, sizeof(pcache1)); + if( sqlite3GlobalConfig.bCoreMutex ){ + pcache1.grp.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU); + pcache1.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_PMEM); + } + pcache1.grp.mxPinned = 10; + pcache1.isInit = 1; + return SQLITE_OK; +} + +/* +** Implementation of the sqlite3_pcache.xShutdown method. +** Note that the static mutex allocated in xInit does +** not need to be freed. +*/ +static void pcache1Shutdown(void *NotUsed){ + UNUSED_PARAMETER(NotUsed); + assert( pcache1.isInit!=0 ); + memset(&pcache1, 0, sizeof(pcache1)); +} + +/* +** Implementation of the sqlite3_pcache.xCreate method. +** +** Allocate a new cache. +*/ +static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){ + PCache1 *pCache; /* The newly created page cache */ + PGroup *pGroup; /* The group the new page cache will belong to */ + int sz; /* Bytes of memory required to allocate the new cache */ + + /* + ** The seperateCache variable is true if each PCache has its own private + ** PGroup. In other words, separateCache is true for mode (1) where no + ** mutexing is required. + ** + ** * Always use a unified cache (mode-2) if ENABLE_MEMORY_MANAGEMENT + ** + ** * Always use a unified cache in single-threaded applications + ** + ** * Otherwise (if multi-threaded and ENABLE_MEMORY_MANAGEMENT is off) + ** use separate caches (mode-1) + */ +#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) || SQLITE_THREADSAFE==0 + const int separateCache = 0; +#else + int separateCache = sqlite3GlobalConfig.bCoreMutex>0; +#endif + + assert( (szPage & (szPage-1))==0 && szPage>=512 && szPage<=65536 ); + assert( szExtra < 300 ); + + sz = sizeof(PCache1) + sizeof(PGroup)*separateCache; + pCache = (PCache1 *)sqlite3_malloc(sz); + if( pCache ){ + memset(pCache, 0, sz); + if( separateCache ){ + pGroup = (PGroup*)&pCache[1]; + pGroup->mxPinned = 10; + }else{ + pGroup = &pcache1.grp; + } + pCache->pGroup = pGroup; + pCache->szPage = szPage; + pCache->szExtra = szExtra; + pCache->bPurgeable = (bPurgeable ? 1 : 0); + if( bPurgeable ){ + pCache->nMin = 10; + pcache1EnterMutex(pGroup); + pGroup->nMinPage += pCache->nMin; + pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; + pcache1LeaveMutex(pGroup); + } + } + return (sqlite3_pcache *)pCache; +} + +/* +** Implementation of the sqlite3_pcache.xCachesize method. +** +** Configure the cache_size limit for a cache. +*/ +static void pcache1Cachesize(sqlite3_pcache *p, int nMax){ + PCache1 *pCache = (PCache1 *)p; + if( pCache->bPurgeable ){ + PGroup *pGroup = pCache->pGroup; + pcache1EnterMutex(pGroup); + pGroup->nMaxPage += (nMax - pCache->nMax); + pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; + pCache->nMax = nMax; + pCache->n90pct = pCache->nMax*9/10; + pcache1EnforceMaxPage(pGroup); + pcache1LeaveMutex(pGroup); + } +} + +/* +** Implementation of the sqlite3_pcache.xShrink method. +** +** Free up as much memory as possible. +*/ +static void pcache1Shrink(sqlite3_pcache *p){ + PCache1 *pCache = (PCache1*)p; + if( pCache->bPurgeable ){ + PGroup *pGroup = pCache->pGroup; + int savedMaxPage; + pcache1EnterMutex(pGroup); + savedMaxPage = pGroup->nMaxPage; + pGroup->nMaxPage = 0; + pcache1EnforceMaxPage(pGroup); + pGroup->nMaxPage = savedMaxPage; + pcache1LeaveMutex(pGroup); + } +} + +/* +** Implementation of the sqlite3_pcache.xPagecount method. +*/ +static int pcache1Pagecount(sqlite3_pcache *p){ + int n; + PCache1 *pCache = (PCache1*)p; + pcache1EnterMutex(pCache->pGroup); + n = pCache->nPage; + pcache1LeaveMutex(pCache->pGroup); + return n; +} + +/* +** Implementation of the sqlite3_pcache.xFetch method. +** +** Fetch a page by key value. +** +** Whether or not a new page may be allocated by this function depends on +** the value of the createFlag argument. 0 means do not allocate a new +** page. 1 means allocate a new page if space is easily available. 2 +** means to try really hard to allocate a new page. +** +** For a non-purgeable cache (a cache used as the storage for an in-memory +** database) there is really no difference between createFlag 1 and 2. So +** the calling function (pcache.c) will never have a createFlag of 1 on +** a non-purgeable cache. +** +** There are three different approaches to obtaining space for a page, +** depending on the value of parameter createFlag (which may be 0, 1 or 2). +** +** 1. Regardless of the value of createFlag, the cache is searched for a +** copy of the requested page. If one is found, it is returned. +** +** 2. If createFlag==0 and the page is not already in the cache, NULL is +** returned. +** +** 3. If createFlag is 1, and the page is not already in the cache, then +** return NULL (do not allocate a new page) if any of the following +** conditions are true: +** +** (a) the number of pages pinned by the cache is greater than +** PCache1.nMax, or +** +** (b) the number of pages pinned by the cache is greater than +** the sum of nMax for all purgeable caches, less the sum of +** nMin for all other purgeable caches, or +** +** 4. If none of the first three conditions apply and the cache is marked +** as purgeable, and if one of the following is true: +** +** (a) The number of pages allocated for the cache is already +** PCache1.nMax, or +** +** (b) The number of pages allocated for all purgeable caches is +** already equal to or greater than the sum of nMax for all +** purgeable caches, +** +** (c) The system is under memory pressure and wants to avoid +** unnecessary pages cache entry allocations +** +** then attempt to recycle a page from the LRU list. If it is the right +** size, return the recycled buffer. Otherwise, free the buffer and +** proceed to step 5. +** +** 5. Otherwise, allocate and return a new page buffer. +*/ +static sqlite3_pcache_page *pcache1Fetch( + sqlite3_pcache *p, + unsigned int iKey, + int createFlag +){ + unsigned int nPinned; + PCache1 *pCache = (PCache1 *)p; + PGroup *pGroup; + PgHdr1 *pPage = 0; + + assert( pCache->bPurgeable || createFlag!=1 ); + assert( pCache->bPurgeable || pCache->nMin==0 ); + assert( pCache->bPurgeable==0 || pCache->nMin==10 ); + assert( pCache->nMin==0 || pCache->bPurgeable ); + pcache1EnterMutex(pGroup = pCache->pGroup); + + /* Step 1: Search the hash table for an existing entry. */ + if( pCache->nHash>0 ){ + unsigned int h = iKey % pCache->nHash; + for(pPage=pCache->apHash[h]; pPage&&pPage->iKey!=iKey; pPage=pPage->pNext); + } + + /* Step 2: Abort if no existing page is found and createFlag is 0 */ + if( pPage || createFlag==0 ){ + pcache1PinPage(pPage); + goto fetch_out; + } + + /* The pGroup local variable will normally be initialized by the + ** pcache1EnterMutex() macro above. But if SQLITE_MUTEX_OMIT is defined, + ** then pcache1EnterMutex() is a no-op, so we have to initialize the + ** local variable here. Delaying the initialization of pGroup is an + ** optimization: The common case is to exit the module before reaching + ** this point. + */ +#ifdef SQLITE_MUTEX_OMIT + pGroup = pCache->pGroup; +#endif + + /* Step 3: Abort if createFlag is 1 but the cache is nearly full */ + assert( pCache->nPage >= pCache->nRecyclable ); + nPinned = pCache->nPage - pCache->nRecyclable; + assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage ); + assert( pCache->n90pct == pCache->nMax*9/10 ); + if( createFlag==1 && ( + nPinned>=pGroup->mxPinned + || nPinned>=pCache->n90pct + || pcache1UnderMemoryPressure(pCache) + )){ + goto fetch_out; + } + + if( pCache->nPage>=pCache->nHash && pcache1ResizeHash(pCache) ){ + goto fetch_out; + } + + /* Step 4. Try to recycle a page. */ + if( pCache->bPurgeable && pGroup->pLruTail && ( + (pCache->nPage+1>=pCache->nMax) + || pGroup->nCurrentPage>=pGroup->nMaxPage + || pcache1UnderMemoryPressure(pCache) + )){ + PCache1 *pOther; + pPage = pGroup->pLruTail; + pcache1RemoveFromHash(pPage); + pcache1PinPage(pPage); + pOther = pPage->pCache; + + /* We want to verify that szPage and szExtra are the same for pOther + ** and pCache. Assert that we can verify this by comparing sums. */ + assert( (pCache->szPage & (pCache->szPage-1))==0 && pCache->szPage>=512 ); + assert( pCache->szExtra<512 ); + assert( (pOther->szPage & (pOther->szPage-1))==0 && pOther->szPage>=512 ); + assert( pOther->szExtra<512 ); + + if( pOther->szPage+pOther->szExtra != pCache->szPage+pCache->szExtra ){ + pcache1FreePage(pPage); + pPage = 0; + }else{ + pGroup->nCurrentPage -= (pOther->bPurgeable - pCache->bPurgeable); + } + } + + /* Step 5. If a usable page buffer has still not been found, + ** attempt to allocate a new one. + */ + if( !pPage ){ + if( createFlag==1 ) sqlite3BeginBenignMalloc(); + pPage = pcache1AllocPage(pCache); + if( createFlag==1 ) sqlite3EndBenignMalloc(); + } + + if( pPage ){ + unsigned int h = iKey % pCache->nHash; + pCache->nPage++; + pPage->iKey = iKey; + pPage->pNext = pCache->apHash[h]; + pPage->pCache = pCache; + pPage->pLruPrev = 0; + pPage->pLruNext = 0; + *(void **)pPage->page.pExtra = 0; + pCache->apHash[h] = pPage; + } + +fetch_out: + if( pPage && iKey>pCache->iMaxKey ){ + pCache->iMaxKey = iKey; + } + pcache1LeaveMutex(pGroup); + return &pPage->page; +} + + +/* +** Implementation of the sqlite3_pcache.xUnpin method. +** +** Mark a page as unpinned (eligible for asynchronous recycling). +*/ +static void pcache1Unpin( + sqlite3_pcache *p, + sqlite3_pcache_page *pPg, + int reuseUnlikely +){ + PCache1 *pCache = (PCache1 *)p; + PgHdr1 *pPage = (PgHdr1 *)pPg; + PGroup *pGroup = pCache->pGroup; + + assert( pPage->pCache==pCache ); + pcache1EnterMutex(pGroup); + + /* It is an error to call this function if the page is already + ** part of the PGroup LRU list. + */ + assert( pPage->pLruPrev==0 && pPage->pLruNext==0 ); + assert( pGroup->pLruHead!=pPage && pGroup->pLruTail!=pPage ); + + if( reuseUnlikely || pGroup->nCurrentPage>pGroup->nMaxPage ){ + pcache1RemoveFromHash(pPage); + pcache1FreePage(pPage); + }else{ + /* Add the page to the PGroup LRU list. */ + if( pGroup->pLruHead ){ + pGroup->pLruHead->pLruPrev = pPage; + pPage->pLruNext = pGroup->pLruHead; + pGroup->pLruHead = pPage; + }else{ + pGroup->pLruTail = pPage; + pGroup->pLruHead = pPage; + } + pCache->nRecyclable++; + } + + pcache1LeaveMutex(pCache->pGroup); +} + +/* +** Implementation of the sqlite3_pcache.xRekey method. +*/ +static void pcache1Rekey( + sqlite3_pcache *p, + sqlite3_pcache_page *pPg, + unsigned int iOld, + unsigned int iNew +){ + PCache1 *pCache = (PCache1 *)p; + PgHdr1 *pPage = (PgHdr1 *)pPg; + PgHdr1 **pp; + unsigned int h; + assert( pPage->iKey==iOld ); + assert( pPage->pCache==pCache ); + + pcache1EnterMutex(pCache->pGroup); + + h = iOld%pCache->nHash; + pp = &pCache->apHash[h]; + while( (*pp)!=pPage ){ + pp = &(*pp)->pNext; + } + *pp = pPage->pNext; + + h = iNew%pCache->nHash; + pPage->iKey = iNew; + pPage->pNext = pCache->apHash[h]; + pCache->apHash[h] = pPage; + if( iNew>pCache->iMaxKey ){ + pCache->iMaxKey = iNew; + } + + pcache1LeaveMutex(pCache->pGroup); +} + +/* +** Implementation of the sqlite3_pcache.xTruncate method. +** +** Discard all unpinned pages in the cache with a page number equal to +** or greater than parameter iLimit. Any pinned pages with a page number +** equal to or greater than iLimit are implicitly unpinned. +*/ +static void pcache1Truncate(sqlite3_pcache *p, unsigned int iLimit){ + PCache1 *pCache = (PCache1 *)p; + pcache1EnterMutex(pCache->pGroup); + if( iLimit<=pCache->iMaxKey ){ + pcache1TruncateUnsafe(pCache, iLimit); + pCache->iMaxKey = iLimit-1; + } + pcache1LeaveMutex(pCache->pGroup); +} + +/* +** Implementation of the sqlite3_pcache.xDestroy method. +** +** Destroy a cache allocated using pcache1Create(). +*/ +static void pcache1Destroy(sqlite3_pcache *p){ + PCache1 *pCache = (PCache1 *)p; + PGroup *pGroup = pCache->pGroup; + assert( pCache->bPurgeable || (pCache->nMax==0 && pCache->nMin==0) ); + pcache1EnterMutex(pGroup); + pcache1TruncateUnsafe(pCache, 0); + assert( pGroup->nMaxPage >= pCache->nMax ); + pGroup->nMaxPage -= pCache->nMax; + assert( pGroup->nMinPage >= pCache->nMin ); + pGroup->nMinPage -= pCache->nMin; + pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; + pcache1EnforceMaxPage(pGroup); + pcache1LeaveMutex(pGroup); + sqlite3_free(pCache->apHash); + sqlite3_free(pCache); +} + +/* +** This function is called during initialization (sqlite3_initialize()) to +** install the default pluggable cache module, assuming the user has not +** already provided an alternative. +*/ +void sqlite3PCacheSetDefault(void){ + static const sqlite3_pcache_methods2 defaultMethods = { + 1, /* iVersion */ + 0, /* pArg */ + pcache1Init, /* xInit */ + pcache1Shutdown, /* xShutdown */ + pcache1Create, /* xCreate */ + pcache1Cachesize, /* xCachesize */ + pcache1Pagecount, /* xPagecount */ + pcache1Fetch, /* xFetch */ + pcache1Unpin, /* xUnpin */ + pcache1Rekey, /* xRekey */ + pcache1Truncate, /* xTruncate */ + pcache1Destroy, /* xDestroy */ + pcache1Shrink /* xShrink */ + }; + sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultMethods); +} + +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT +/* +** This function is called to free superfluous dynamically allocated memory +** held by the pager system. Memory in use by any SQLite pager allocated +** by the current thread may be sqlite3_free()ed. +** +** nReq is the number of bytes of memory required. Once this much has +** been released, the function returns. The return value is the total number +** of bytes of memory released. +*/ +int sqlite3PcacheReleaseMemory(int nReq){ + int nFree = 0; + assert( sqlite3_mutex_notheld(pcache1.grp.mutex) ); + assert( sqlite3_mutex_notheld(pcache1.mutex) ); + if( pcache1.pStart==0 ){ + PgHdr1 *p; + pcache1EnterMutex(&pcache1.grp); + while( (nReq<0 || nFreepage.pBuf); +#ifdef SQLITE_PCACHE_SEPARATE_HEADER + nFree += sqlite3MemSize(p); +#endif + pcache1PinPage(p); + pcache1RemoveFromHash(p); + pcache1FreePage(p); + } + pcache1LeaveMutex(&pcache1.grp); + } + return nFree; +} +#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */ + +#ifdef SQLITE_TEST +/* +** This function is used by test procedures to inspect the internal state +** of the global cache. +*/ +void sqlite3PcacheStats( + int *pnCurrent, /* OUT: Total number of pages cached */ + int *pnMax, /* OUT: Global maximum cache size */ + int *pnMin, /* OUT: Sum of PCache1.nMin for purgeable caches */ + int *pnRecyclable /* OUT: Total number of pages available for recycling */ +){ + PgHdr1 *p; + int nRecyclable = 0; + for(p=pcache1.grp.pLruHead; p; p=p->pLruNext){ + nRecyclable++; + } + *pnCurrent = pcache1.grp.nCurrentPage; + *pnMax = (int)pcache1.grp.nMaxPage; + *pnMin = (int)pcache1.grp.nMinPage; + *pnRecyclable = nRecyclable; +} +#endif diff --git a/scalos/libraries/sqlite/src/pragma.c b/scalos/libraries/sqlite/src/pragma.c new file mode 100644 index 000000000..581bcaf0e --- /dev/null +++ b/scalos/libraries/sqlite/src/pragma.c @@ -0,0 +1,1542 @@ +/* +** 2003 April 6 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code used to implement the PRAGMA command. +*/ +#include "sqliteInt.h" + +/* +** Interpret the given string as a safety level. Return 0 for OFF, +** 1 for ON or NORMAL and 2 for FULL. Return 1 for an empty or +** unrecognized string argument. +** +** Note that the values returned are one less that the values that +** should be passed into sqlite3BtreeSetSafetyLevel(). The is done +** to support legacy SQL code. The safety level used to be boolean +** and older scripts may have used numbers 0 for OFF and 1 for ON. +*/ +static u8 getSafetyLevel(const char *z){ + /* 123456789 123456789 */ + static const char zText[] = "onoffalseyestruefull"; + static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16}; + static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 4}; + static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 2}; + int i, n; + if( sqlite3Isdigit(*z) ){ + return (u8)sqlite3Atoi(z); + } + n = sqlite3Strlen30(z); + for(i=0; i=0&&i<=2)?i:0); +} +#endif /* ifndef SQLITE_OMIT_AUTOVACUUM */ + +#ifndef SQLITE_OMIT_PAGER_PRAGMAS +/* +** Interpret the given string as a temp db location. Return 1 for file +** backed temporary databases, 2 for the Red-Black tree in memory database +** and 0 to use the compile-time default. +*/ +static int getTempStore(const char *z){ + if( z[0]>='0' && z[0]<='2' ){ + return z[0] - '0'; + }else if( sqlite3StrICmp(z, "file")==0 ){ + return 1; + }else if( sqlite3StrICmp(z, "memory")==0 ){ + return 2; + }else{ + return 0; + } +} +#endif /* SQLITE_PAGER_PRAGMAS */ + +#ifndef SQLITE_OMIT_PAGER_PRAGMAS +/* +** Invalidate temp storage, either when the temp storage is changed +** from default, or when 'file' and the temp_store_directory has changed +*/ +static int invalidateTempStorage(Parse *pParse){ + sqlite3 *db = pParse->db; + if( db->aDb[1].pBt!=0 ){ + if( !db->autoCommit || sqlite3BtreeIsInReadTrans(db->aDb[1].pBt) ){ + sqlite3ErrorMsg(pParse, "temporary storage cannot be changed " + "from within a transaction"); + return SQLITE_ERROR; + } + sqlite3BtreeClose(db->aDb[1].pBt); + db->aDb[1].pBt = 0; + sqlite3ResetInternalSchema(db, -1); + } + return SQLITE_OK; +} +#endif /* SQLITE_PAGER_PRAGMAS */ + +#ifndef SQLITE_OMIT_PAGER_PRAGMAS +/* +** If the TEMP database is open, close it and mark the database schema +** as needing reloading. This must be done when using the SQLITE_TEMP_STORE +** or DEFAULT_TEMP_STORE pragmas. +*/ +static int changeTempStorage(Parse *pParse, const char *zStorageType){ + int ts = getTempStore(zStorageType); + sqlite3 *db = pParse->db; + if( db->temp_store==ts ) return SQLITE_OK; + if( invalidateTempStorage( pParse ) != SQLITE_OK ){ + return SQLITE_ERROR; + } + db->temp_store = (u8)ts; + return SQLITE_OK; +} +#endif /* SQLITE_PAGER_PRAGMAS */ + +/* +** Generate code to return a single integer value. +*/ +static void returnSingleInt(Parse *pParse, const char *zLabel, i64 value){ + Vdbe *v = sqlite3GetVdbe(pParse); + int mem = ++pParse->nMem; + i64 *pI64 = sqlite3DbMallocRaw(pParse->db, sizeof(value)); + if( pI64 ){ + memcpy(pI64, &value, sizeof(value)); + } + sqlite3VdbeAddOp4(v, OP_Int64, 0, mem, 0, (char*)pI64, P4_INT64); + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC); + sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1); +} + +#ifndef SQLITE_OMIT_FLAG_PRAGMAS +/* +** Check to see if zRight and zLeft refer to a pragma that queries +** or changes one of the flags in db->flags. Return 1 if so and 0 if not. +** Also, implement the pragma. +*/ +static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){ + static const struct sPragmaType { + const char *zName; /* Name of the pragma */ + int mask; /* Mask for the db->flags value */ + } aPragma[] = { + { "full_column_names", SQLITE_FullColNames }, + { "short_column_names", SQLITE_ShortColNames }, + { "count_changes", SQLITE_CountRows }, + { "empty_result_callbacks", SQLITE_NullCallback }, + { "legacy_file_format", SQLITE_LegacyFileFmt }, + { "fullfsync", SQLITE_FullFSync }, + { "checkpoint_fullfsync", SQLITE_CkptFullFSync }, + { "reverse_unordered_selects", SQLITE_ReverseOrder }, +#ifndef SQLITE_OMIT_AUTOMATIC_INDEX + { "automatic_index", SQLITE_AutoIndex }, +#endif +#ifdef SQLITE_DEBUG + { "sql_trace", SQLITE_SqlTrace }, + { "vdbe_listing", SQLITE_VdbeListing }, + { "vdbe_trace", SQLITE_VdbeTrace }, +#endif +#ifndef SQLITE_OMIT_CHECK + { "ignore_check_constraints", SQLITE_IgnoreChecks }, +#endif + /* The following is VERY experimental */ + { "writable_schema", SQLITE_WriteSchema|SQLITE_RecoveryMode }, + { "omit_readlock", SQLITE_NoReadlock }, + + /* TODO: Maybe it shouldn't be possible to change the ReadUncommitted + ** flag if there are any active statements. */ + { "read_uncommitted", SQLITE_ReadUncommitted }, + { "recursive_triggers", SQLITE_RecTriggers }, + + /* This flag may only be set if both foreign-key and trigger support + ** are present in the build. */ +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) + { "foreign_keys", SQLITE_ForeignKeys }, +#endif + }; + int i; + const struct sPragmaType *p; + for(i=0, p=aPragma; izName)==0 ){ + sqlite3 *db = pParse->db; + Vdbe *v; + v = sqlite3GetVdbe(pParse); + assert( v!=0 ); /* Already allocated by sqlite3Pragma() */ + if( ALWAYS(v) ){ + if( zRight==0 ){ + returnSingleInt(pParse, p->zName, (db->flags & p->mask)!=0 ); + }else{ + int mask = p->mask; /* Mask of bits to set or clear. */ + if( db->autoCommit==0 ){ + /* Foreign key support may not be enabled or disabled while not + ** in auto-commit mode. */ + mask &= ~(SQLITE_ForeignKeys); + } + + if( sqlite3GetBoolean(zRight) ){ + db->flags |= mask; + }else{ + db->flags &= ~mask; + } + + /* Many of the flag-pragmas modify the code generated by the SQL + ** compiler (eg. count_changes). So add an opcode to expire all + ** compiled SQL statements after modifying a pragma value. + */ + sqlite3VdbeAddOp2(v, OP_Expire, 0, 0); + } + } + + return 1; + } + } + return 0; +} +#endif /* SQLITE_OMIT_FLAG_PRAGMAS */ + +/* +** Return a human-readable name for a constraint resolution action. +*/ +#ifndef SQLITE_OMIT_FOREIGN_KEY +static const char *actionName(u8 action){ + const char *zName; + switch( action ){ + case OE_SetNull: zName = "SET NULL"; break; + case OE_SetDflt: zName = "SET DEFAULT"; break; + case OE_Cascade: zName = "CASCADE"; break; + case OE_Restrict: zName = "RESTRICT"; break; + default: zName = "NO ACTION"; + assert( action==OE_None ); break; + } + return zName; +} +#endif + + +/* +** Parameter eMode must be one of the PAGER_JOURNALMODE_XXX constants +** defined in pager.h. This function returns the associated lowercase +** journal-mode name. +*/ +const char *sqlite3JournalModename(int eMode){ + static char * const azModeName[] = { + "delete", "persist", "off", "truncate", "memory" +#ifndef SQLITE_OMIT_WAL + , "wal" +#endif + }; + assert( PAGER_JOURNALMODE_DELETE==0 ); + assert( PAGER_JOURNALMODE_PERSIST==1 ); + assert( PAGER_JOURNALMODE_OFF==2 ); + assert( PAGER_JOURNALMODE_TRUNCATE==3 ); + assert( PAGER_JOURNALMODE_MEMORY==4 ); + assert( PAGER_JOURNALMODE_WAL==5 ); + assert( eMode>=0 && eMode<=ArraySize(azModeName) ); + + if( eMode==ArraySize(azModeName) ) return 0; + return azModeName[eMode]; +} + +/* +** Process a pragma statement. +** +** Pragmas are of this form: +** +** PRAGMA [database.]id [= value] +** +** The identifier might also be a string. The value is a string, and +** identifier, or a number. If minusFlag is true, then the value is +** a number that was preceded by a minus sign. +** +** If the left side is "database.id" then pId1 is the database name +** and pId2 is the id. If the left side is just "id" then pId1 is the +** id and pId2 is any empty string. +*/ +void sqlite3Pragma( + Parse *pParse, + Token *pId1, /* First part of [database.]id field */ + Token *pId2, /* Second part of [database.]id field, or NULL */ + Token *pValue, /* Token for , or NULL */ + int minusFlag /* True if a '-' sign preceded */ +){ + char *zLeft = 0; /* Nul-terminated UTF-8 string */ + char *zRight = 0; /* Nul-terminated UTF-8 string , or NULL */ + const char *zDb = 0; /* The database name */ + Token *pId; /* Pointer to token */ + int iDb; /* Database index for */ + sqlite3 *db = pParse->db; + Db *pDb; + Vdbe *v = pParse->pVdbe = sqlite3VdbeCreate(db); + if( v==0 ) return; + sqlite3VdbeRunOnlyOnce(v); + pParse->nMem = 2; + + /* Interpret the [database.] part of the pragma statement. iDb is the + ** index of the database this pragma is being applied to in db.aDb[]. */ + iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId); + if( iDb<0 ) return; + pDb = &db->aDb[iDb]; + + /* If the temp database has been explicitly named as part of the + ** pragma, make sure it is open. + */ + if( iDb==1 && sqlite3OpenTempDatabase(pParse) ){ + return; + } + + zLeft = sqlite3NameFromToken(db, pId); + if( !zLeft ) return; + if( minusFlag ){ + zRight = sqlite3MPrintf(db, "-%T", pValue); + }else{ + zRight = sqlite3NameFromToken(db, pValue); + } + + assert( pId2 ); + zDb = pId2->n>0 ? pDb->zName : 0; + if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){ + goto pragma_out; + } + +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) + /* + ** PRAGMA [database.]default_cache_size + ** PRAGMA [database.]default_cache_size=N + ** + ** The first form reports the current persistent setting for the + ** page cache size. The value returned is the maximum number of + ** pages in the page cache. The second form sets both the current + ** page cache size value and the persistent page cache size value + ** stored in the database file. + ** + ** Older versions of SQLite would set the default cache size to a + ** negative number to indicate synchronous=OFF. These days, synchronous + ** is always on by default regardless of the sign of the default cache + ** size. But continue to take the absolute value of the default cache + ** size of historical compatibility. + */ + if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){ + static const VdbeOpList getCacheSize[] = { + { OP_Transaction, 0, 0, 0}, /* 0 */ + { OP_ReadCookie, 0, 1, BTREE_DEFAULT_CACHE_SIZE}, /* 1 */ + { OP_IfPos, 1, 7, 0}, + { OP_Integer, 0, 2, 0}, + { OP_Subtract, 1, 2, 1}, + { OP_IfPos, 1, 7, 0}, + { OP_Integer, 0, 1, 0}, /* 6 */ + { OP_ResultRow, 1, 1, 0}, + }; + int addr; + if( sqlite3ReadSchema(pParse) ) goto pragma_out; + sqlite3VdbeUsesBtree(v, iDb); + if( !zRight ){ + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", SQLITE_STATIC); + pParse->nMem += 2; + addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize); + sqlite3VdbeChangeP1(v, addr, iDb); + sqlite3VdbeChangeP1(v, addr+1, iDb); + sqlite3VdbeChangeP1(v, addr+6, SQLITE_DEFAULT_CACHE_SIZE); + }else{ + int size = sqlite3AbsInt32(sqlite3Atoi(zRight)); + sqlite3BeginWriteOperation(pParse, 0, iDb); + sqlite3VdbeAddOp2(v, OP_Integer, size, 1); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_DEFAULT_CACHE_SIZE, 1); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + pDb->pSchema->cache_size = size; + sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); + } + }else +#endif /* !SQLITE_OMIT_PAGER_PRAGMAS && !SQLITE_OMIT_DEPRECATED */ + +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + /* + ** PRAGMA [database.]page_size + ** PRAGMA [database.]page_size=N + ** + ** The first form reports the current setting for the + ** database page size in bytes. The second form sets the + ** database page size value. The value can only be set if + ** the database has not yet been created. + */ + if( sqlite3StrICmp(zLeft,"page_size")==0 ){ + Btree *pBt = pDb->pBt; + assert( pBt!=0 ); + if( !zRight ){ + int size = ALWAYS(pBt) ? sqlite3BtreeGetPageSize(pBt) : 0; + returnSingleInt(pParse, "page_size", size); + }else{ + /* Malloc may fail when setting the page-size, as there is an internal + ** buffer that the pager module resizes using sqlite3_realloc(). + */ + db->nextPagesize = sqlite3Atoi(zRight); + if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,-1,0) ){ + db->mallocFailed = 1; + } + } + }else + + /* + ** PRAGMA [database.]secure_delete + ** PRAGMA [database.]secure_delete=ON/OFF + ** + ** The first form reports the current setting for the + ** secure_delete flag. The second form changes the secure_delete + ** flag setting and reports thenew value. + */ + if( sqlite3StrICmp(zLeft,"secure_delete")==0 ){ + Btree *pBt = pDb->pBt; + int b = -1; + assert( pBt!=0 ); + if( zRight ){ + b = sqlite3GetBoolean(zRight); + } + if( pId2->n==0 && b>=0 ){ + int ii; + for(ii=0; iinDb; ii++){ + sqlite3BtreeSecureDelete(db->aDb[ii].pBt, b); + } + } + b = sqlite3BtreeSecureDelete(pBt, b); + returnSingleInt(pParse, "secure_delete", b); + }else + + /* + ** PRAGMA [database.]max_page_count + ** PRAGMA [database.]max_page_count=N + ** + ** The first form reports the current setting for the + ** maximum number of pages in the database file. The + ** second form attempts to change this setting. Both + ** forms return the current setting. + ** + ** The absolute value of N is used. This is undocumented and might + ** change. The only purpose is to provide an easy way to test + ** the sqlite3AbsInt32() function. + ** + ** PRAGMA [database.]page_count + ** + ** Return the number of pages in the specified database. + */ + if( sqlite3StrICmp(zLeft,"page_count")==0 + || sqlite3StrICmp(zLeft,"max_page_count")==0 + ){ + int iReg; + if( sqlite3ReadSchema(pParse) ) goto pragma_out; + sqlite3CodeVerifySchema(pParse, iDb); + iReg = ++pParse->nMem; + if( sqlite3Tolower(zLeft[0])=='p' ){ + sqlite3VdbeAddOp2(v, OP_Pagecount, iDb, iReg); + }else{ + sqlite3VdbeAddOp3(v, OP_MaxPgcnt, iDb, iReg, + sqlite3AbsInt32(sqlite3Atoi(zRight))); + } + sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1); + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT); + }else + + /* + ** PRAGMA [database.]locking_mode + ** PRAGMA [database.]locking_mode = (normal|exclusive) + */ + if( sqlite3StrICmp(zLeft,"locking_mode")==0 ){ + const char *zRet = "normal"; + int eMode = getLockingMode(zRight); + + if( pId2->n==0 && eMode==PAGER_LOCKINGMODE_QUERY ){ + /* Simple "PRAGMA locking_mode;" statement. This is a query for + ** the current default locking mode (which may be different to + ** the locking-mode of the main database). + */ + eMode = db->dfltLockMode; + }else{ + Pager *pPager; + if( pId2->n==0 ){ + /* This indicates that no database name was specified as part + ** of the PRAGMA command. In this case the locking-mode must be + ** set on all attached databases, as well as the main db file. + ** + ** Also, the sqlite3.dfltLockMode variable is set so that + ** any subsequently attached databases also use the specified + ** locking mode. + */ + int ii; + assert(pDb==&db->aDb[0]); + for(ii=2; iinDb; ii++){ + pPager = sqlite3BtreePager(db->aDb[ii].pBt); + sqlite3PagerLockingMode(pPager, eMode); + } + db->dfltLockMode = (u8)eMode; + } + pPager = sqlite3BtreePager(pDb->pBt); + eMode = sqlite3PagerLockingMode(pPager, eMode); + } + + assert(eMode==PAGER_LOCKINGMODE_NORMAL||eMode==PAGER_LOCKINGMODE_EXCLUSIVE); + if( eMode==PAGER_LOCKINGMODE_EXCLUSIVE ){ + zRet = "exclusive"; + } + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "locking_mode", SQLITE_STATIC); + sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, zRet, 0); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); + }else + + /* + ** PRAGMA [database.]journal_mode + ** PRAGMA [database.]journal_mode = + ** (delete|persist|off|truncate|memory|wal|off) + */ + if( sqlite3StrICmp(zLeft,"journal_mode")==0 ){ + int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */ + int ii; /* Loop counter */ + + /* Force the schema to be loaded on all databases. This causes all + ** database files to be opened and the journal_modes set. This is + ** necessary because subsequent processing must know if the databases + ** are in WAL mode. */ + if( sqlite3ReadSchema(pParse) ){ + goto pragma_out; + } + + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "journal_mode", SQLITE_STATIC); + + if( zRight==0 ){ + /* If there is no "=MODE" part of the pragma, do a query for the + ** current mode */ + eMode = PAGER_JOURNALMODE_QUERY; + }else{ + const char *zMode; + int n = sqlite3Strlen30(zRight); + for(eMode=0; (zMode = sqlite3JournalModename(eMode))!=0; eMode++){ + if( sqlite3StrNICmp(zRight, zMode, n)==0 ) break; + } + if( !zMode ){ + /* If the "=MODE" part does not match any known journal mode, + ** then do a query */ + eMode = PAGER_JOURNALMODE_QUERY; + } + } + if( eMode==PAGER_JOURNALMODE_QUERY && pId2->n==0 ){ + /* Convert "PRAGMA journal_mode" into "PRAGMA main.journal_mode" */ + iDb = 0; + pId2->n = 1; + } + for(ii=db->nDb-1; ii>=0; ii--){ + if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ + sqlite3VdbeUsesBtree(v, ii); + sqlite3VdbeAddOp3(v, OP_JournalMode, ii, 1, eMode); + } + } + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); + }else + + /* + ** PRAGMA [database.]journal_size_limit + ** PRAGMA [database.]journal_size_limit=N + ** + ** Get or set the size limit on rollback journal files. + */ + if( sqlite3StrICmp(zLeft,"journal_size_limit")==0 ){ + Pager *pPager = sqlite3BtreePager(pDb->pBt); + i64 iLimit = -2; + if( zRight ){ + sqlite3Atoi64(zRight, &iLimit, 1000000, SQLITE_UTF8); + if( iLimit<-1 ) iLimit = -1; + } + iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit); + returnSingleInt(pParse, "journal_size_limit", iLimit); + }else + +#endif /* SQLITE_OMIT_PAGER_PRAGMAS */ + + /* + ** PRAGMA [database.]auto_vacuum + ** PRAGMA [database.]auto_vacuum=N + ** + ** Get or set the value of the database 'auto-vacuum' parameter. + ** The value is one of: 0 NONE 1 FULL 2 INCREMENTAL + */ +#ifndef SQLITE_OMIT_AUTOVACUUM + if( sqlite3StrICmp(zLeft,"auto_vacuum")==0 ){ + Btree *pBt = pDb->pBt; + assert( pBt!=0 ); + if( sqlite3ReadSchema(pParse) ){ + goto pragma_out; + } + if( !zRight ){ + int auto_vacuum; + if( ALWAYS(pBt) ){ + auto_vacuum = sqlite3BtreeGetAutoVacuum(pBt); + }else{ + auto_vacuum = SQLITE_DEFAULT_AUTOVACUUM; + } + returnSingleInt(pParse, "auto_vacuum", auto_vacuum); + }else{ + int eAuto = getAutoVacuum(zRight); + assert( eAuto>=0 && eAuto<=2 ); + db->nextAutovac = (u8)eAuto; + if( ALWAYS(eAuto>=0) ){ + /* Call SetAutoVacuum() to set initialize the internal auto and + ** incr-vacuum flags. This is required in case this connection + ** creates the database file. It is important that it is created + ** as an auto-vacuum capable db. + */ + int rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto); + if( rc==SQLITE_OK && (eAuto==1 || eAuto==2) ){ + /* When setting the auto_vacuum mode to either "full" or + ** "incremental", write the value of meta[6] in the database + ** file. Before writing to meta[6], check that meta[3] indicates + ** that this really is an auto-vacuum capable database. + */ + static const VdbeOpList setMeta6[] = { + { OP_Transaction, 0, 1, 0}, /* 0 */ + { OP_ReadCookie, 0, 1, BTREE_LARGEST_ROOT_PAGE}, + { OP_If, 1, 0, 0}, /* 2 */ + { OP_Halt, SQLITE_OK, OE_Abort, 0}, /* 3 */ + { OP_Integer, 0, 1, 0}, /* 4 */ + { OP_SetCookie, 0, BTREE_INCR_VACUUM, 1}, /* 5 */ + }; + int iAddr; + iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6); + sqlite3VdbeChangeP1(v, iAddr, iDb); + sqlite3VdbeChangeP1(v, iAddr+1, iDb); + sqlite3VdbeChangeP2(v, iAddr+2, iAddr+4); + sqlite3VdbeChangeP1(v, iAddr+4, eAuto-1); + sqlite3VdbeChangeP1(v, iAddr+5, iDb); + sqlite3VdbeUsesBtree(v, iDb); + } + } + } + }else +#endif + + /* + ** PRAGMA [database.]incremental_vacuum(N) + ** + ** Do N steps of incremental vacuuming on a database. + */ +#ifndef SQLITE_OMIT_AUTOVACUUM + if( sqlite3StrICmp(zLeft,"incremental_vacuum")==0 ){ + int iLimit, addr; + if( sqlite3ReadSchema(pParse) ){ + goto pragma_out; + } + if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){ + iLimit = 0x7fffffff; + } + sqlite3BeginWriteOperation(pParse, 0, iDb); + sqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1); + addr = sqlite3VdbeAddOp1(v, OP_IncrVacuum, iDb); + sqlite3VdbeAddOp1(v, OP_ResultRow, 1); + sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); + sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr); + sqlite3VdbeJumpHere(v, addr); + }else +#endif + +#ifndef SQLITE_OMIT_PAGER_PRAGMAS + /* + ** PRAGMA [database.]cache_size + ** PRAGMA [database.]cache_size=N + ** + ** The first form reports the current local setting for the + ** page cache size. The second form sets the local + ** page cache size value. If N is positive then that is the + ** number of pages in the cache. If N is negative, then the + ** number of pages is adjusted so that the cache uses -N kibibytes + ** of memory. + */ + if( sqlite3StrICmp(zLeft,"cache_size")==0 ){ + if( sqlite3ReadSchema(pParse) ) goto pragma_out; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + if( !zRight ){ + returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size); + }else{ + int size = sqlite3Atoi(zRight); + pDb->pSchema->cache_size = size; + sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); + } + }else + + /* + ** PRAGMA temp_store + ** PRAGMA temp_store = "default"|"memory"|"file" + ** + ** Return or set the local value of the temp_store flag. Changing + ** the local value does not make changes to the disk file and the default + ** value will be restored the next time the database is opened. + ** + ** Note that it is possible for the library compile-time options to + ** override this setting + */ + if( sqlite3StrICmp(zLeft, "temp_store")==0 ){ + if( !zRight ){ + returnSingleInt(pParse, "temp_store", db->temp_store); + }else{ + changeTempStorage(pParse, zRight); + } + }else + + /* + ** PRAGMA temp_store_directory + ** PRAGMA temp_store_directory = ""|"directory_name" + ** + ** Return or set the local value of the temp_store_directory flag. Changing + ** the value sets a specific directory to be used for temporary files. + ** Setting to a null string reverts to the default temporary directory search. + ** If temporary directory is changed, then invalidateTempStorage. + ** + */ + if( sqlite3StrICmp(zLeft, "temp_store_directory")==0 ){ + if( !zRight ){ + if( sqlite3_temp_directory ){ + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, + "temp_store_directory", SQLITE_STATIC); + sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, sqlite3_temp_directory, 0); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); + } + }else{ +#ifndef SQLITE_OMIT_WSD + if( zRight[0] ){ + int rc; + int res; + rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res); + if( rc!=SQLITE_OK || res==0 ){ + sqlite3ErrorMsg(pParse, "not a writable directory"); + goto pragma_out; + } + } + if( SQLITE_TEMP_STORE==0 + || (SQLITE_TEMP_STORE==1 && db->temp_store<=1) + || (SQLITE_TEMP_STORE==2 && db->temp_store==1) + ){ + invalidateTempStorage(pParse); + } + sqlite3_free(sqlite3_temp_directory); + if( zRight[0] ){ + sqlite3_temp_directory = sqlite3_mprintf("%s", zRight); + }else{ + sqlite3_temp_directory = 0; + } +#endif /* SQLITE_OMIT_WSD */ + } + }else + +#if !defined(SQLITE_ENABLE_LOCKING_STYLE) +# if defined(__APPLE__) +# define SQLITE_ENABLE_LOCKING_STYLE 1 +# else +# define SQLITE_ENABLE_LOCKING_STYLE 0 +# endif +#endif +#if SQLITE_ENABLE_LOCKING_STYLE + /* + ** PRAGMA [database.]lock_proxy_file + ** PRAGMA [database.]lock_proxy_file = ":auto:"|"lock_file_path" + ** + ** Return or set the value of the lock_proxy_file flag. Changing + ** the value sets a specific file to be used for database access locks. + ** + */ + if( sqlite3StrICmp(zLeft, "lock_proxy_file")==0 ){ + if( !zRight ){ + Pager *pPager = sqlite3BtreePager(pDb->pBt); + char *proxy_file_path = NULL; + sqlite3_file *pFile = sqlite3PagerFile(pPager); + sqlite3OsFileControlHint(pFile, SQLITE_GET_LOCKPROXYFILE, + &proxy_file_path); + + if( proxy_file_path ){ + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, + "lock_proxy_file", SQLITE_STATIC); + sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, proxy_file_path, 0); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); + } + }else{ + Pager *pPager = sqlite3BtreePager(pDb->pBt); + sqlite3_file *pFile = sqlite3PagerFile(pPager); + int res; + if( zRight[0] ){ + res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE, + zRight); + } else { + res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE, + NULL); + } + if( res!=SQLITE_OK ){ + sqlite3ErrorMsg(pParse, "failed to set lock proxy file"); + goto pragma_out; + } + } + }else +#endif /* SQLITE_ENABLE_LOCKING_STYLE */ + + /* + ** PRAGMA [database.]synchronous + ** PRAGMA [database.]synchronous=OFF|ON|NORMAL|FULL + ** + ** Return or set the local value of the synchronous flag. Changing + ** the local value does not make changes to the disk file and the + ** default value will be restored the next time the database is + ** opened. + */ + if( sqlite3StrICmp(zLeft,"synchronous")==0 ){ + if( sqlite3ReadSchema(pParse) ) goto pragma_out; + if( !zRight ){ + returnSingleInt(pParse, "synchronous", pDb->safety_level-1); + }else{ + if( !db->autoCommit ){ + sqlite3ErrorMsg(pParse, + "Safety level may not be changed inside a transaction"); + }else{ + pDb->safety_level = getSafetyLevel(zRight)+1; + } + } + }else +#endif /* SQLITE_OMIT_PAGER_PRAGMAS */ + +#ifndef SQLITE_OMIT_FLAG_PRAGMAS + if( flagPragma(pParse, zLeft, zRight) ){ + /* The flagPragma() subroutine also generates any necessary code + ** there is nothing more to do here */ + }else +#endif /* SQLITE_OMIT_FLAG_PRAGMAS */ + +#ifndef SQLITE_OMIT_SCHEMA_PRAGMAS + /* + ** PRAGMA table_info(
  • ) + ** + ** Return a single row for each column of the named table. The columns of + ** the returned data set are: + ** + ** cid: Column id (numbered from left to right, starting at 0) + ** name: Column name + ** type: Column declaration type. + ** notnull: True if 'NOT NULL' is part of column declaration + ** dflt_value: The default value for the column, if any. + */ + if( sqlite3StrICmp(zLeft, "table_info")==0 && zRight ){ + Table *pTab; + if( sqlite3ReadSchema(pParse) ) goto pragma_out; + pTab = sqlite3FindTable(db, zRight, zDb); + if( pTab ){ + int i; + int nHidden = 0; + Column *pCol; + sqlite3VdbeSetNumCols(v, 6); + pParse->nMem = 6; + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cid", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "type", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "notnull", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "dflt_value", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "pk", SQLITE_STATIC); + sqlite3ViewGetColumnNames(pParse, pTab); + for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){ + if( IsHiddenColumn(pCol) ){ + nHidden++; + continue; + } + sqlite3VdbeAddOp2(v, OP_Integer, i-nHidden, 1); + sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pCol->zName, 0); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, + pCol->zType ? pCol->zType : "", 0); + sqlite3VdbeAddOp2(v, OP_Integer, (pCol->notNull ? 1 : 0), 4); + if( pCol->zDflt ){ + sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, (char*)pCol->zDflt, 0); + }else{ + sqlite3VdbeAddOp2(v, OP_Null, 0, 5); + } + sqlite3VdbeAddOp2(v, OP_Integer, pCol->isPrimKey, 6); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6); + } + } + }else + + if( sqlite3StrICmp(zLeft, "index_info")==0 && zRight ){ + Index *pIdx; + Table *pTab; + if( sqlite3ReadSchema(pParse) ) goto pragma_out; + pIdx = sqlite3FindIndex(db, zRight, zDb); + if( pIdx ){ + int i; + pTab = pIdx->pTable; + sqlite3VdbeSetNumCols(v, 3); + pParse->nMem = 3; + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seqno", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "cid", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "name", SQLITE_STATIC); + for(i=0; inColumn; i++){ + int cnum = pIdx->aiColumn[i]; + sqlite3VdbeAddOp2(v, OP_Integer, i, 1); + sqlite3VdbeAddOp2(v, OP_Integer, cnum, 2); + assert( pTab->nCol>cnum ); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pTab->aCol[cnum].zName, 0); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); + } + } + }else + + if( sqlite3StrICmp(zLeft, "index_list")==0 && zRight ){ + Index *pIdx; + Table *pTab; + if( sqlite3ReadSchema(pParse) ) goto pragma_out; + pTab = sqlite3FindTable(db, zRight, zDb); + if( pTab ){ + v = sqlite3GetVdbe(pParse); + pIdx = pTab->pIndex; + if( pIdx ){ + int i = 0; + sqlite3VdbeSetNumCols(v, 3); + pParse->nMem = 3; + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE_STATIC); + while(pIdx){ + sqlite3VdbeAddOp2(v, OP_Integer, i, 1); + sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0); + sqlite3VdbeAddOp2(v, OP_Integer, pIdx->onError!=OE_None, 3); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); + ++i; + pIdx = pIdx->pNext; + } + } + } + }else + + if( sqlite3StrICmp(zLeft, "database_list")==0 ){ + int i; + if( sqlite3ReadSchema(pParse) ) goto pragma_out; + sqlite3VdbeSetNumCols(v, 3); + pParse->nMem = 3; + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "file", SQLITE_STATIC); + for(i=0; inDb; i++){ + if( db->aDb[i].pBt==0 ) continue; + assert( db->aDb[i].zName!=0 ); + sqlite3VdbeAddOp2(v, OP_Integer, i, 1); + sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, db->aDb[i].zName, 0); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, + sqlite3BtreeGetFilename(db->aDb[i].pBt), 0); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); + } + }else + + if( sqlite3StrICmp(zLeft, "collation_list")==0 ){ + int i = 0; + HashElem *p; + sqlite3VdbeSetNumCols(v, 2); + pParse->nMem = 2; + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC); + for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){ + CollSeq *pColl = (CollSeq *)sqliteHashData(p); + sqlite3VdbeAddOp2(v, OP_Integer, i++, 1); + sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pColl->zName, 0); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2); + } + }else +#endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */ + +#ifndef SQLITE_OMIT_FOREIGN_KEY + if( sqlite3StrICmp(zLeft, "foreign_key_list")==0 && zRight ){ + FKey *pFK; + Table *pTab; + if( sqlite3ReadSchema(pParse) ) goto pragma_out; + pTab = sqlite3FindTable(db, zRight, zDb); + if( pTab ){ + v = sqlite3GetVdbe(pParse); + pFK = pTab->pFKey; + if( pFK ){ + int i = 0; + sqlite3VdbeSetNumCols(v, 8); + pParse->nMem = 8; + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "id", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "seq", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "table", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "from", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "to", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "on_update", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 6, COLNAME_NAME, "on_delete", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 7, COLNAME_NAME, "match", SQLITE_STATIC); + while(pFK){ + int j; + for(j=0; jnCol; j++){ + char *zCol = pFK->aCol[j].zCol; + char *zOnDelete = (char *)actionName(pFK->aAction[0]); + char *zOnUpdate = (char *)actionName(pFK->aAction[1]); + sqlite3VdbeAddOp2(v, OP_Integer, i, 1); + sqlite3VdbeAddOp2(v, OP_Integer, j, 2); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pFK->zTo, 0); + sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, + pTab->aCol[pFK->aCol[j].iFrom].zName, 0); + sqlite3VdbeAddOp4(v, zCol ? OP_String8 : OP_Null, 0, 5, 0, zCol, 0); + sqlite3VdbeAddOp4(v, OP_String8, 0, 6, 0, zOnUpdate, 0); + sqlite3VdbeAddOp4(v, OP_String8, 0, 7, 0, zOnDelete, 0); + sqlite3VdbeAddOp4(v, OP_String8, 0, 8, 0, "NONE", 0); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 8); + } + ++i; + pFK = pFK->pNextFrom; + } + } + } + }else +#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ + +#ifndef NDEBUG + if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){ + if( zRight ){ + if( sqlite3GetBoolean(zRight) ){ + sqlite3ParserTrace(stderr, "parser: "); + }else{ + sqlite3ParserTrace(0, 0); + } + } + }else +#endif + + /* Reinstall the LIKE and GLOB functions. The variant of LIKE + ** used will be case sensitive or not depending on the RHS. + */ + if( sqlite3StrICmp(zLeft, "case_sensitive_like")==0 ){ + if( zRight ){ + sqlite3RegisterLikeFunctions(db, sqlite3GetBoolean(zRight)); + } + }else + +#ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX +# define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100 +#endif + +#ifndef SQLITE_OMIT_INTEGRITY_CHECK + /* Pragma "quick_check" is an experimental reduced version of + ** integrity_check designed to detect most database corruption + ** without most of the overhead of a full integrity-check. + */ + if( sqlite3StrICmp(zLeft, "integrity_check")==0 + || sqlite3StrICmp(zLeft, "quick_check")==0 + ){ + int i, j, addr, mxErr; + + /* Code that appears at the end of the integrity check. If no error + ** messages have been generated, output OK. Otherwise output the + ** error message + */ + static const VdbeOpList endCode[] = { + { OP_AddImm, 1, 0, 0}, /* 0 */ + { OP_IfNeg, 1, 0, 0}, /* 1 */ + { OP_String8, 0, 3, 0}, /* 2 */ + { OP_ResultRow, 3, 1, 0}, + }; + + int isQuick = (sqlite3Tolower(zLeft[0])=='q'); + + /* Initialize the VDBE program */ + if( sqlite3ReadSchema(pParse) ) goto pragma_out; + pParse->nMem = 6; + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "integrity_check", SQLITE_STATIC); + + /* Set the maximum error count */ + mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; + if( zRight ){ + sqlite3GetInt32(zRight, &mxErr); + if( mxErr<=0 ){ + mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; + } + } + sqlite3VdbeAddOp2(v, OP_Integer, mxErr, 1); /* reg[1] holds errors left */ + + /* Do an integrity check on each database file */ + for(i=0; inDb; i++){ + HashElem *x; + Hash *pTbls; + int cnt = 0; + + if( OMIT_TEMPDB && i==1 ) continue; + + sqlite3CodeVerifySchema(pParse, i); + addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */ + sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); + sqlite3VdbeJumpHere(v, addr); + + /* Do an integrity check of the B-Tree + ** + ** Begin by filling registers 2, 3, ... with the root pages numbers + ** for all tables and indices in the database. + */ + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + pTbls = &db->aDb[i].pSchema->tblHash; + for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ + Table *pTab = sqliteHashData(x); + Index *pIdx; + sqlite3VdbeAddOp2(v, OP_Integer, pTab->tnum, 2+cnt); + cnt++; + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + sqlite3VdbeAddOp2(v, OP_Integer, pIdx->tnum, 2+cnt); + cnt++; + } + } + + /* Make sure sufficient number of registers have been allocated */ + if( pParse->nMem < cnt+4 ){ + pParse->nMem = cnt+4; + } + + /* Do the b-tree integrity checks */ + sqlite3VdbeAddOp3(v, OP_IntegrityCk, 2, cnt, 1); + sqlite3VdbeChangeP5(v, (u8)i); + addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, + sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName), + P4_DYNAMIC); + sqlite3VdbeAddOp3(v, OP_Move, 2, 4, 1); + sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2); + sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1); + sqlite3VdbeJumpHere(v, addr); + + /* Make sure all the indices are constructed correctly. + */ + for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){ + Table *pTab = sqliteHashData(x); + Index *pIdx; + int loopTop; + + if( pTab->pIndex==0 ) continue; + addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */ + sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); + sqlite3VdbeJumpHere(v, addr); + sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead); + sqlite3VdbeAddOp2(v, OP_Integer, 0, 2); /* reg(2) will count entries */ + loopTop = sqlite3VdbeAddOp2(v, OP_Rewind, 1, 0); + sqlite3VdbeAddOp2(v, OP_AddImm, 2, 1); /* increment entry count */ + for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ + int jmp2; + int r1; + static const VdbeOpList idxErr[] = { + { OP_AddImm, 1, -1, 0}, + { OP_String8, 0, 3, 0}, /* 1 */ + { OP_Rowid, 1, 4, 0}, + { OP_String8, 0, 5, 0}, /* 3 */ + { OP_String8, 0, 6, 0}, /* 4 */ + { OP_Concat, 4, 3, 3}, + { OP_Concat, 5, 3, 3}, + { OP_Concat, 6, 3, 3}, + { OP_ResultRow, 3, 1, 0}, + { OP_IfPos, 1, 0, 0}, /* 9 */ + { OP_Halt, 0, 0, 0}, + }; + r1 = sqlite3GenerateIndexKey(pParse, pIdx, 1, 3, 0); + jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, j+2, 0, r1, pIdx->nColumn+1); + addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr); + sqlite3VdbeChangeP4(v, addr+1, "rowid ", P4_STATIC); + sqlite3VdbeChangeP4(v, addr+3, " missing from index ", P4_STATIC); + sqlite3VdbeChangeP4(v, addr+4, pIdx->zName, P4_TRANSIENT); + sqlite3VdbeJumpHere(v, addr+9); + sqlite3VdbeJumpHere(v, jmp2); + } + sqlite3VdbeAddOp2(v, OP_Next, 1, loopTop+1); + sqlite3VdbeJumpHere(v, loopTop); + for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ + static const VdbeOpList cntIdx[] = { + { OP_Integer, 0, 3, 0}, + { OP_Rewind, 0, 0, 0}, /* 1 */ + { OP_AddImm, 3, 1, 0}, + { OP_Next, 0, 0, 0}, /* 3 */ + { OP_Eq, 2, 0, 3}, /* 4 */ + { OP_AddImm, 1, -1, 0}, + { OP_String8, 0, 2, 0}, /* 6 */ + { OP_String8, 0, 3, 0}, /* 7 */ + { OP_Concat, 3, 2, 2}, + { OP_ResultRow, 2, 1, 0}, + }; + addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); + sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); + sqlite3VdbeJumpHere(v, addr); + addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx); + sqlite3VdbeChangeP1(v, addr+1, j+2); + sqlite3VdbeChangeP2(v, addr+1, addr+4); + sqlite3VdbeChangeP1(v, addr+3, j+2); + sqlite3VdbeChangeP2(v, addr+3, addr+2); + sqlite3VdbeJumpHere(v, addr+4); + sqlite3VdbeChangeP4(v, addr+6, + "wrong # of entries in index ", P4_STATIC); + sqlite3VdbeChangeP4(v, addr+7, pIdx->zName, P4_TRANSIENT); + } + } + } + addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode); + sqlite3VdbeChangeP2(v, addr, -mxErr); + sqlite3VdbeJumpHere(v, addr+1); + sqlite3VdbeChangeP4(v, addr+2, "ok", P4_STATIC); + }else +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ + +#ifndef SQLITE_OMIT_UTF16 + /* + ** PRAGMA encoding + ** PRAGMA encoding = "utf-8"|"utf-16"|"utf-16le"|"utf-16be" + ** + ** In its first form, this pragma returns the encoding of the main + ** database. If the database is not initialized, it is initialized now. + ** + ** The second form of this pragma is a no-op if the main database file + ** has not already been initialized. In this case it sets the default + ** encoding that will be used for the main database file if a new file + ** is created. If an existing main database file is opened, then the + ** default text encoding for the existing database is used. + ** + ** In all cases new databases created using the ATTACH command are + ** created to use the same default text encoding as the main database. If + ** the main database has not been initialized and/or created when ATTACH + ** is executed, this is done before the ATTACH operation. + ** + ** In the second form this pragma sets the text encoding to be used in + ** new database files created using this database handle. It is only + ** useful if invoked immediately after the main database i + */ + if( sqlite3StrICmp(zLeft, "encoding")==0 ){ + static const struct EncName { + char *zName; + u8 enc; + } encnames[] = { + { "UTF8", SQLITE_UTF8 }, + { "UTF-8", SQLITE_UTF8 }, /* Must be element [1] */ + { "UTF-16le", SQLITE_UTF16LE }, /* Must be element [2] */ + { "UTF-16be", SQLITE_UTF16BE }, /* Must be element [3] */ + { "UTF16le", SQLITE_UTF16LE }, + { "UTF16be", SQLITE_UTF16BE }, + { "UTF-16", 0 }, /* SQLITE_UTF16NATIVE */ + { "UTF16", 0 }, /* SQLITE_UTF16NATIVE */ + { 0, 0 } + }; + const struct EncName *pEnc; + if( !zRight ){ /* "PRAGMA encoding" */ + if( sqlite3ReadSchema(pParse) ) goto pragma_out; + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "encoding", SQLITE_STATIC); + sqlite3VdbeAddOp2(v, OP_String8, 0, 1); + assert( encnames[SQLITE_UTF8].enc==SQLITE_UTF8 ); + assert( encnames[SQLITE_UTF16LE].enc==SQLITE_UTF16LE ); + assert( encnames[SQLITE_UTF16BE].enc==SQLITE_UTF16BE ); + sqlite3VdbeChangeP4(v, -1, encnames[ENC(pParse->db)].zName, P4_STATIC); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); + }else{ /* "PRAGMA encoding = XXX" */ + /* Only change the value of sqlite.enc if the database handle is not + ** initialized. If the main database exists, the new sqlite.enc value + ** will be overwritten when the schema is next loaded. If it does not + ** already exists, it will be created to use the new encoding value. + */ + if( + !(DbHasProperty(db, 0, DB_SchemaLoaded)) || + DbHasProperty(db, 0, DB_Empty) + ){ + for(pEnc=&encnames[0]; pEnc->zName; pEnc++){ + if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){ + ENC(pParse->db) = pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE; + break; + } + } + if( !pEnc->zName ){ + sqlite3ErrorMsg(pParse, "unsupported encoding: %s", zRight); + } + } + } + }else +#endif /* SQLITE_OMIT_UTF16 */ + +#ifndef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS + /* + ** PRAGMA [database.]schema_version + ** PRAGMA [database.]schema_version = + ** + ** PRAGMA [database.]user_version + ** PRAGMA [database.]user_version = + ** + ** The pragma's schema_version and user_version are used to set or get + ** the value of the schema-version and user-version, respectively. Both + ** the schema-version and the user-version are 32-bit signed integers + ** stored in the database header. + ** + ** The schema-cookie is usually only manipulated internally by SQLite. It + ** is incremented by SQLite whenever the database schema is modified (by + ** creating or dropping a table or index). The schema version is used by + ** SQLite each time a query is executed to ensure that the internal cache + ** of the schema used when compiling the SQL query matches the schema of + ** the database against which the compiled query is actually executed. + ** Subverting this mechanism by using "PRAGMA schema_version" to modify + ** the schema-version is potentially dangerous and may lead to program + ** crashes or database corruption. Use with caution! + ** + ** The user-version is not used internally by SQLite. It may be used by + ** applications for any purpose. + */ + if( sqlite3StrICmp(zLeft, "schema_version")==0 + || sqlite3StrICmp(zLeft, "user_version")==0 + || sqlite3StrICmp(zLeft, "freelist_count")==0 + ){ + int iCookie; /* Cookie index. 1 for schema-cookie, 6 for user-cookie. */ + sqlite3VdbeUsesBtree(v, iDb); + switch( zLeft[0] ){ + case 'f': case 'F': + iCookie = BTREE_FREE_PAGE_COUNT; + break; + case 's': case 'S': + iCookie = BTREE_SCHEMA_VERSION; + break; + default: + iCookie = BTREE_USER_VERSION; + break; + } + + if( zRight && iCookie!=BTREE_FREE_PAGE_COUNT ){ + /* Write the specified cookie value */ + static const VdbeOpList setCookie[] = { + { OP_Transaction, 0, 1, 0}, /* 0 */ + { OP_Integer, 0, 1, 0}, /* 1 */ + { OP_SetCookie, 0, 0, 1}, /* 2 */ + }; + int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie); + sqlite3VdbeChangeP1(v, addr, iDb); + sqlite3VdbeChangeP1(v, addr+1, sqlite3Atoi(zRight)); + sqlite3VdbeChangeP1(v, addr+2, iDb); + sqlite3VdbeChangeP2(v, addr+2, iCookie); + }else{ + /* Read the specified cookie value */ + static const VdbeOpList readCookie[] = { + { OP_Transaction, 0, 0, 0}, /* 0 */ + { OP_ReadCookie, 0, 1, 0}, /* 1 */ + { OP_ResultRow, 1, 1, 0} + }; + int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie); + sqlite3VdbeChangeP1(v, addr, iDb); + sqlite3VdbeChangeP1(v, addr+1, iDb); + sqlite3VdbeChangeP3(v, addr+1, iCookie); + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT); + } + }else +#endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */ + +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS + /* + ** PRAGMA compile_options + ** + ** Return the names of all compile-time options used in this build, + ** one option per row. + */ + if( sqlite3StrICmp(zLeft, "compile_options")==0 ){ + int i = 0; + const char *zOpt; + sqlite3VdbeSetNumCols(v, 1); + pParse->nMem = 1; + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "compile_option", SQLITE_STATIC); + while( (zOpt = sqlite3_compileoption_get(i++))!=0 ){ + sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, zOpt, 0); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); + } + }else +#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ + +#ifndef SQLITE_OMIT_WAL + /* + ** PRAGMA [database.]wal_checkpoint = passive|full|restart + ** + ** Checkpoint the database. + */ + if( sqlite3StrICmp(zLeft, "wal_checkpoint")==0 ){ + int iBt = (pId2->z?iDb:SQLITE_MAX_ATTACHED); + int eMode = SQLITE_CHECKPOINT_PASSIVE; + if( zRight ){ + if( sqlite3StrICmp(zRight, "full")==0 ){ + eMode = SQLITE_CHECKPOINT_FULL; + }else if( sqlite3StrICmp(zRight, "restart")==0 ){ + eMode = SQLITE_CHECKPOINT_RESTART; + } + } + if( sqlite3ReadSchema(pParse) ) goto pragma_out; + sqlite3VdbeSetNumCols(v, 3); + pParse->nMem = 3; + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "busy", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "log", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "checkpointed", SQLITE_STATIC); + + sqlite3VdbeAddOp3(v, OP_Checkpoint, iBt, eMode, 1); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); + }else + + /* + ** PRAGMA wal_autocheckpoint + ** PRAGMA wal_autocheckpoint = N + ** + ** Configure a database connection to automatically checkpoint a database + ** after accumulating N frames in the log. Or query for the current value + ** of N. + */ + if( sqlite3StrICmp(zLeft, "wal_autocheckpoint")==0 ){ + if( zRight ){ + sqlite3_wal_autocheckpoint(db, sqlite3Atoi(zRight)); + } + returnSingleInt(pParse, "wal_autocheckpoint", + db->xWalCallback==sqlite3WalDefaultHook ? + SQLITE_PTR_TO_INT(db->pWalArg) : 0); + }else +#endif + + /* + ** PRAGMA shrink_memory + ** + ** This pragma attempts to free as much memory as possible from the + ** current database connection. + */ + if( sqlite3StrICmp(zLeft, "shrink_memory")==0 ){ + sqlite3_db_release_memory(db); + }else + +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) + /* + ** Report the current state of file logs for all databases + */ + if( sqlite3StrICmp(zLeft, "lock_status")==0 ){ + static const char *const azLockName[] = { + "unlocked", "shared", "reserved", "pending", "exclusive" + }; + int i; + sqlite3VdbeSetNumCols(v, 2); + pParse->nMem = 2; + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "database", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "status", SQLITE_STATIC); + for(i=0; inDb; i++){ + Btree *pBt; + Pager *pPager; + const char *zState = "unknown"; + int j; + if( db->aDb[i].zName==0 ) continue; + sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, db->aDb[i].zName, P4_STATIC); + pBt = db->aDb[i].pBt; + if( pBt==0 || (pPager = sqlite3BtreePager(pBt))==0 ){ + zState = "closed"; + }else if( sqlite3_file_control(db, i ? db->aDb[i].zName : 0, + SQLITE_FCNTL_LOCKSTATE, &j)==SQLITE_OK ){ + zState = azLockName[j]; + } + sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, zState, P4_STATIC); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2); + } + + }else +#endif + +#ifdef SQLITE_HAS_CODEC + if( sqlite3StrICmp(zLeft, "key")==0 && zRight ){ + sqlite3_key(db, zRight, sqlite3Strlen30(zRight)); + }else + if( sqlite3StrICmp(zLeft, "rekey")==0 && zRight ){ + sqlite3_rekey(db, zRight, sqlite3Strlen30(zRight)); + }else + if( zRight && (sqlite3StrICmp(zLeft, "hexkey")==0 || + sqlite3StrICmp(zLeft, "hexrekey")==0) ){ + int i, h1, h2; + char zKey[40]; + for(i=0; (h1 = zRight[i])!=0 && (h2 = zRight[i+1])!=0; i+=2){ + h1 += 9*(1&(h1>>6)); + h2 += 9*(1&(h2>>6)); + zKey[i/2] = (h2 & 0x0f) | ((h1 & 0xf)<<4); + } + if( (zLeft[3] & 0xf)==0xb ){ + sqlite3_key(db, zKey, i/2); + }else{ + sqlite3_rekey(db, zKey, i/2); + } + }else +#endif +#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD) + if( sqlite3StrICmp(zLeft, "activate_extensions")==0 ){ +#ifdef SQLITE_HAS_CODEC + if( sqlite3StrNICmp(zRight, "see-", 4)==0 ){ + sqlite3_activate_see(&zRight[4]); + } +#endif +#ifdef SQLITE_ENABLE_CEROD + if( sqlite3StrNICmp(zRight, "cerod-", 6)==0 ){ + sqlite3_activate_cerod(&zRight[6]); + } +#endif + }else +#endif + + + {/* Empty ELSE clause */} + + /* + ** Reset the safety level, in case the fullfsync flag or synchronous + ** setting changed. + */ +#ifndef SQLITE_OMIT_PAGER_PRAGMAS + if( db->autoCommit ){ + sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level, + (db->flags&SQLITE_FullFSync)!=0, + (db->flags&SQLITE_CkptFullFSync)!=0); + } +#endif +pragma_out: + sqlite3DbFree(db, zLeft); + sqlite3DbFree(db, zRight); +} + +#endif /* SQLITE_OMIT_PRAGMA */ diff --git a/scalos/libraries/sqlite/src/prepare.c b/scalos/libraries/sqlite/src/prepare.c new file mode 100644 index 000000000..faeefa894 --- /dev/null +++ b/scalos/libraries/sqlite/src/prepare.c @@ -0,0 +1,862 @@ +/* +** 2005 May 25 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains the implementation of the sqlite3_prepare() +** interface, and routines that contribute to loading the database schema +** from disk. +*/ +#include "sqliteInt.h" + +/* +** Fill the InitData structure with an error message that indicates +** that the database is corrupt. +*/ +static void corruptSchema( + InitData *pData, /* Initialization context */ + const char *zObj, /* Object being parsed at the point of error */ + const char *zExtra /* Error information */ +){ + sqlite3 *db = pData->db; + if( !db->mallocFailed && (db->flags & SQLITE_RecoveryMode)==0 ){ + if( zObj==0 ) zObj = "?"; + sqlite3SetString(pData->pzErrMsg, db, + "malformed database schema (%s)", zObj); + if( zExtra ){ + *pData->pzErrMsg = sqlite3MAppendf(db, *pData->pzErrMsg, + "%s - %s", *pData->pzErrMsg, zExtra); + } + } + pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT_BKPT; +} + +/* +** This is the callback routine for the code that initializes the +** database. See sqlite3Init() below for additional information. +** This routine is also called from the OP_ParseSchema opcode of the VDBE. +** +** Each callback contains the following information: +** +** argv[0] = name of thing being created +** argv[1] = root page number for table or index. 0 for trigger or view. +** argv[2] = SQL text for the CREATE statement. +** +*/ +int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ + InitData *pData = (InitData*)pInit; + sqlite3 *db = pData->db; + int iDb = pData->iDb; + + assert( argc==3 ); + UNUSED_PARAMETER2(NotUsed, argc); + assert( sqlite3_mutex_held(db->mutex) ); + DbClearProperty(db, iDb, DB_Empty); + if( db->mallocFailed ){ + corruptSchema(pData, argv[0], 0); + return 1; + } + + assert( iDb>=0 && iDbnDb ); + if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */ + if( argv[1]==0 ){ + corruptSchema(pData, argv[0], 0); + }else if( argv[2] && argv[2][0] ){ + /* Call the parser to process a CREATE TABLE, INDEX or VIEW. + ** But because db->init.busy is set to 1, no VDBE code is generated + ** or executed. All the parser does is build the internal data + ** structures that describe the table, index, or view. + */ + int rc; + sqlite3_stmt *pStmt; + TESTONLY(int rcp); /* Return code from sqlite3_prepare() */ + + assert( db->init.busy ); + db->init.iDb = iDb; + db->init.newTnum = sqlite3Atoi(argv[1]); + db->init.orphanTrigger = 0; + TESTONLY(rcp = ) sqlite3_prepare(db, argv[2], -1, &pStmt, 0); + rc = db->errCode; + assert( (rc&0xFF)==(rcp&0xFF) ); + db->init.iDb = 0; + if( SQLITE_OK!=rc ){ + if( db->init.orphanTrigger ){ + assert( iDb==1 ); + }else{ + pData->rc = rc; + if( rc==SQLITE_NOMEM ){ + db->mallocFailed = 1; + }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){ + corruptSchema(pData, argv[0], sqlite3_errmsg(db)); + } + } + } + sqlite3_finalize(pStmt); + }else if( argv[0]==0 ){ + corruptSchema(pData, 0, 0); + }else{ + /* If the SQL column is blank it means this is an index that + ** was created to be the PRIMARY KEY or to fulfill a UNIQUE + ** constraint for a CREATE TABLE. The index should have already + ** been created when we processed the CREATE TABLE. All we have + ** to do here is record the root page number for that index. + */ + Index *pIndex; + pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zName); + if( pIndex==0 ){ + /* This can occur if there exists an index on a TEMP table which + ** has the same name as another index on a permanent index. Since + ** the permanent table is hidden by the TEMP table, we can also + ** safely ignore the index on the permanent table. + */ + /* Do Nothing */; + }else if( sqlite3GetInt32(argv[1], &pIndex->tnum)==0 ){ + corruptSchema(pData, argv[0], "invalid rootpage"); + } + } + return 0; +} + +/* +** Attempt to read the database schema and initialize internal +** data structures for a single database file. The index of the +** database file is given by iDb. iDb==0 is used for the main +** database. iDb==1 should never be used. iDb>=2 is used for +** auxiliary databases. Return one of the SQLITE_ error codes to +** indicate success or failure. +*/ +static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ + int rc; + int i; + int size; + Table *pTab; + Db *pDb; + char const *azArg[4]; + int meta[5]; + InitData initData; + char const *zMasterSchema; + char const *zMasterName; + int openedTransaction = 0; + + /* + ** The master database table has a structure like this + */ + static const char master_schema[] = + "CREATE TABLE sqlite_master(\n" + " type text,\n" + " name text,\n" + " tbl_name text,\n" + " rootpage integer,\n" + " sql text\n" + ")" + ; +#ifndef SQLITE_OMIT_TEMPDB + static const char temp_master_schema[] = + "CREATE TEMP TABLE sqlite_temp_master(\n" + " type text,\n" + " name text,\n" + " tbl_name text,\n" + " rootpage integer,\n" + " sql text\n" + ")" + ; +#else + #define temp_master_schema 0 +#endif + + assert( iDb>=0 && iDbnDb ); + assert( db->aDb[iDb].pSchema ); + assert( sqlite3_mutex_held(db->mutex) ); + assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); + + /* zMasterSchema and zInitScript are set to point at the master schema + ** and initialisation script appropriate for the database being + ** initialised. zMasterName is the name of the master table. + */ + if( !OMIT_TEMPDB && iDb==1 ){ + zMasterSchema = temp_master_schema; + }else{ + zMasterSchema = master_schema; + } + zMasterName = SCHEMA_TABLE(iDb); + + /* Construct the schema tables. */ + azArg[0] = zMasterName; + azArg[1] = "1"; + azArg[2] = zMasterSchema; + azArg[3] = 0; + initData.db = db; + initData.iDb = iDb; + initData.rc = SQLITE_OK; + initData.pzErrMsg = pzErrMsg; + sqlite3InitCallback(&initData, 3, (char **)azArg, 0); + if( initData.rc ){ + rc = initData.rc; + goto error_out; + } + pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName); + if( ALWAYS(pTab) ){ + pTab->tabFlags |= TF_Readonly; + } + + /* Create a cursor to hold the database open + */ + pDb = &db->aDb[iDb]; + if( pDb->pBt==0 ){ + if( !OMIT_TEMPDB && ALWAYS(iDb==1) ){ + DbSetProperty(db, 1, DB_SchemaLoaded); + } + return SQLITE_OK; + } + + /* If there is not already a read-only (or read-write) transaction opened + ** on the b-tree database, open one now. If a transaction is opened, it + ** will be closed before this function returns. */ + sqlite3BtreeEnter(pDb->pBt); + if( !sqlite3BtreeIsInReadTrans(pDb->pBt) ){ + rc = sqlite3BtreeBeginTrans(pDb->pBt, 0); + if( rc!=SQLITE_OK ){ + sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc)); + goto initone_error_out; + } + openedTransaction = 1; + } + + /* Get the database meta information. + ** + ** Meta values are as follows: + ** meta[0] Schema cookie. Changes with each schema change. + ** meta[1] File format of schema layer. + ** meta[2] Size of the page cache. + ** meta[3] Largest rootpage (auto/incr_vacuum mode) + ** meta[4] Db text encoding. 1:UTF-8 2:UTF-16LE 3:UTF-16BE + ** meta[5] User version + ** meta[6] Incremental vacuum mode + ** meta[7] unused + ** meta[8] unused + ** meta[9] unused + ** + ** Note: The #defined SQLITE_UTF* symbols in sqliteInt.h correspond to + ** the possible values of meta[4]. + */ + for(i=0; ipBt, i+1, (u32 *)&meta[i]); + } + pDb->pSchema->schema_cookie = meta[BTREE_SCHEMA_VERSION-1]; + + /* If opening a non-empty database, check the text encoding. For the + ** main database, set sqlite3.enc to the encoding of the main database. + ** For an attached db, it is an error if the encoding is not the same + ** as sqlite3.enc. + */ + if( meta[BTREE_TEXT_ENCODING-1] ){ /* text encoding */ + if( iDb==0 ){ + u8 encoding; + /* If opening the main database, set ENC(db). */ + encoding = (u8)meta[BTREE_TEXT_ENCODING-1] & 3; + if( encoding==0 ) encoding = SQLITE_UTF8; + ENC(db) = encoding; + db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 0); + }else{ + /* If opening an attached database, the encoding much match ENC(db) */ + if( meta[BTREE_TEXT_ENCODING-1]!=ENC(db) ){ + sqlite3SetString(pzErrMsg, db, "attached databases must use the same" + " text encoding as main database"); + rc = SQLITE_ERROR; + goto initone_error_out; + } + } + }else{ + DbSetProperty(db, iDb, DB_Empty); + } + pDb->pSchema->enc = ENC(db); + + if( pDb->pSchema->cache_size==0 ){ +#ifndef SQLITE_OMIT_DEPRECATED + size = sqlite3AbsInt32(meta[BTREE_DEFAULT_CACHE_SIZE-1]); + if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; } + pDb->pSchema->cache_size = size; +#else + pDb->pSchema->cache_size = SQLITE_DEFAULT_CACHE_SIZE; +#endif + sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); + } + + /* + ** file_format==1 Version 3.0.0. + ** file_format==2 Version 3.1.3. // ALTER TABLE ADD COLUMN + ** file_format==3 Version 3.1.4. // ditto but with non-NULL defaults + ** file_format==4 Version 3.3.0. // DESC indices. Boolean constants + */ + pDb->pSchema->file_format = (u8)meta[BTREE_FILE_FORMAT-1]; + if( pDb->pSchema->file_format==0 ){ + pDb->pSchema->file_format = 1; + } + if( pDb->pSchema->file_format>SQLITE_MAX_FILE_FORMAT ){ + sqlite3SetString(pzErrMsg, db, "unsupported file format"); + rc = SQLITE_ERROR; + goto initone_error_out; + } + + /* Ticket #2804: When we open a database in the newer file format, + ** clear the legacy_file_format pragma flag so that a VACUUM will + ** not downgrade the database and thus invalidate any descending + ** indices that the user might have created. + */ + if( iDb==0 && meta[BTREE_FILE_FORMAT-1]>=4 ){ + db->flags &= ~SQLITE_LegacyFileFmt; + } + + /* Read the schema information out of the schema tables + */ + assert( db->init.busy ); + { + char *zSql; + zSql = sqlite3MPrintf(db, + "SELECT name, rootpage, sql FROM '%q'.%s ORDER BY rowid", + db->aDb[iDb].zName, zMasterName); +#ifndef SQLITE_OMIT_AUTHORIZATION + { + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*); + xAuth = db->xAuth; + db->xAuth = 0; +#endif + rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; + } +#endif + if( rc==SQLITE_OK ) rc = initData.rc; + sqlite3DbFree(db, zSql); +#ifndef SQLITE_OMIT_ANALYZE + if( rc==SQLITE_OK ){ + sqlite3AnalysisLoad(db, iDb); + } +#endif + } + if( db->mallocFailed ){ + rc = SQLITE_NOMEM; + sqlite3ResetInternalSchema(db, -1); + } + if( rc==SQLITE_OK || (db->flags&SQLITE_RecoveryMode)){ + /* Black magic: If the SQLITE_RecoveryMode flag is set, then consider + ** the schema loaded, even if errors occurred. In this situation the + ** current sqlite3_prepare() operation will fail, but the following one + ** will attempt to compile the supplied statement against whatever subset + ** of the schema was loaded before the error occurred. The primary + ** purpose of this is to allow access to the sqlite_master table + ** even when its contents have been corrupted. + */ + DbSetProperty(db, iDb, DB_SchemaLoaded); + rc = SQLITE_OK; + } + + /* Jump here for an error that occurs after successfully allocating + ** curMain and calling sqlite3BtreeEnter(). For an error that occurs + ** before that point, jump to error_out. + */ +initone_error_out: + if( openedTransaction ){ + sqlite3BtreeCommit(pDb->pBt); + } + sqlite3BtreeLeave(pDb->pBt); + +error_out: + if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ + db->mallocFailed = 1; + } + return rc; +} + +/* +** Initialize all database files - the main database file, the file +** used to store temporary tables, and any additional database files +** created using ATTACH statements. Return a success code. If an +** error occurs, write an error message into *pzErrMsg. +** +** After a database is initialized, the DB_SchemaLoaded bit is set +** bit is set in the flags field of the Db structure. If the database +** file was of zero-length, then the DB_Empty flag is also set. +*/ +int sqlite3Init(sqlite3 *db, char **pzErrMsg){ + int i, rc; + int commit_internal = !(db->flags&SQLITE_InternChanges); + + assert( sqlite3_mutex_held(db->mutex) ); + rc = SQLITE_OK; + db->init.busy = 1; + for(i=0; rc==SQLITE_OK && inDb; i++){ + if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue; + rc = sqlite3InitOne(db, i, pzErrMsg); + if( rc ){ + sqlite3ResetInternalSchema(db, i); + } + } + + /* Once all the other databases have been initialised, load the schema + ** for the TEMP database. This is loaded last, as the TEMP database + ** schema may contain references to objects in other databases. + */ +#ifndef SQLITE_OMIT_TEMPDB + if( rc==SQLITE_OK && ALWAYS(db->nDb>1) + && !DbHasProperty(db, 1, DB_SchemaLoaded) ){ + rc = sqlite3InitOne(db, 1, pzErrMsg); + if( rc ){ + sqlite3ResetInternalSchema(db, 1); + } + } +#endif + + db->init.busy = 0; + if( rc==SQLITE_OK && commit_internal ){ + sqlite3CommitInternalChanges(db); + } + + return rc; +} + +/* +** This routine is a no-op if the database schema is already initialised. +** Otherwise, the schema is loaded. An error code is returned. +*/ +int sqlite3ReadSchema(Parse *pParse){ + int rc = SQLITE_OK; + sqlite3 *db = pParse->db; + assert( sqlite3_mutex_held(db->mutex) ); + if( !db->init.busy ){ + rc = sqlite3Init(db, &pParse->zErrMsg); + } + if( rc!=SQLITE_OK ){ + pParse->rc = rc; + pParse->nErr++; + } + return rc; +} + + +/* +** Check schema cookies in all databases. If any cookie is out +** of date set pParse->rc to SQLITE_SCHEMA. If all schema cookies +** make no changes to pParse->rc. +*/ +static void schemaIsValid(Parse *pParse){ + sqlite3 *db = pParse->db; + int iDb; + int rc; + int cookie; + + assert( pParse->checkSchema ); + assert( sqlite3_mutex_held(db->mutex) ); + for(iDb=0; iDbnDb; iDb++){ + int openedTransaction = 0; /* True if a transaction is opened */ + Btree *pBt = db->aDb[iDb].pBt; /* Btree database to read cookie from */ + if( pBt==0 ) continue; + + /* If there is not already a read-only (or read-write) transaction opened + ** on the b-tree database, open one now. If a transaction is opened, it + ** will be closed immediately after reading the meta-value. */ + if( !sqlite3BtreeIsInReadTrans(pBt) ){ + rc = sqlite3BtreeBeginTrans(pBt, 0); + if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ + db->mallocFailed = 1; + } + if( rc!=SQLITE_OK ) return; + openedTransaction = 1; + } + + /* Read the schema cookie from the database. If it does not match the + ** value stored as part of the in-memory schema representation, + ** set Parse.rc to SQLITE_SCHEMA. */ + sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + if( cookie!=db->aDb[iDb].pSchema->schema_cookie ){ + sqlite3ResetInternalSchema(db, iDb); + pParse->rc = SQLITE_SCHEMA; + } + + /* Close the transaction, if one was opened. */ + if( openedTransaction ){ + sqlite3BtreeCommit(pBt); + } + } +} + +/* +** Convert a schema pointer into the iDb index that indicates +** which database file in db->aDb[] the schema refers to. +** +** If the same database is attached more than once, the first +** attached database is returned. +*/ +int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){ + int i = -1000000; + + /* If pSchema is NULL, then return -1000000. This happens when code in + ** expr.c is trying to resolve a reference to a transient table (i.e. one + ** created by a sub-select). In this case the return value of this + ** function should never be used. + ** + ** We return -1000000 instead of the more usual -1 simply because using + ** -1000000 as the incorrect index into db->aDb[] is much + ** more likely to cause a segfault than -1 (of course there are assert() + ** statements too, but it never hurts to play the odds). + */ + assert( sqlite3_mutex_held(db->mutex) ); + if( pSchema ){ + for(i=0; ALWAYS(inDb); i++){ + if( db->aDb[i].pSchema==pSchema ){ + break; + } + } + assert( i>=0 && inDb ); + } + return i; +} + +/* +** Compile the UTF-8 encoded SQL statement zSql into a statement handle. +*/ +static int sqlite3Prepare( + sqlite3 *db, /* Database handle. */ + const char *zSql, /* UTF-8 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + int saveSqlFlag, /* True to copy SQL text into the sqlite3_stmt */ + Vdbe *pReprepare, /* VM being reprepared */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const char **pzTail /* OUT: End of parsed string */ +){ + Parse *pParse; /* Parsing context */ + char *zErrMsg = 0; /* Error message */ + int rc = SQLITE_OK; /* Result code */ + int i; /* Loop counter */ + + /* Allocate the parsing context */ + pParse = sqlite3StackAllocZero(db, sizeof(*pParse)); + if( pParse==0 ){ + rc = SQLITE_NOMEM; + goto end_prepare; + } + pParse->pReprepare = pReprepare; + assert( ppStmt && *ppStmt==0 ); + assert( !db->mallocFailed ); + assert( sqlite3_mutex_held(db->mutex) ); + + /* Check to verify that it is possible to get a read lock on all + ** database schemas. The inability to get a read lock indicates that + ** some other database connection is holding a write-lock, which in + ** turn means that the other connection has made uncommitted changes + ** to the schema. + ** + ** Were we to proceed and prepare the statement against the uncommitted + ** schema changes and if those schema changes are subsequently rolled + ** back and different changes are made in their place, then when this + ** prepared statement goes to run the schema cookie would fail to detect + ** the schema change. Disaster would follow. + ** + ** This thread is currently holding mutexes on all Btrees (because + ** of the sqlite3BtreeEnterAll() in sqlite3LockAndPrepare()) so it + ** is not possible for another thread to start a new schema change + ** while this routine is running. Hence, we do not need to hold + ** locks on the schema, we just need to make sure nobody else is + ** holding them. + ** + ** Note that setting READ_UNCOMMITTED overrides most lock detection, + ** but it does *not* override schema lock detection, so this all still + ** works even if READ_UNCOMMITTED is set. + */ + for(i=0; inDb; i++) { + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + assert( sqlite3BtreeHoldsMutex(pBt) ); + rc = sqlite3BtreeSchemaLocked(pBt); + if( rc ){ + const char *zDb = db->aDb[i].zName; + sqlite3Error(db, rc, "database schema is locked: %s", zDb); + testcase( db->flags & SQLITE_ReadUncommitted ); + goto end_prepare; + } + } + } + + sqlite3VtabUnlockList(db); + + pParse->db = db; + pParse->nQueryLoop = (double)1; + if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){ + char *zSqlCopy; + int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; + testcase( nBytes==mxLen ); + testcase( nBytes==mxLen+1 ); + if( nBytes>mxLen ){ + sqlite3Error(db, SQLITE_TOOBIG, "statement too long"); + rc = sqlite3ApiExit(db, SQLITE_TOOBIG); + goto end_prepare; + } + zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes); + if( zSqlCopy ){ + sqlite3RunParser(pParse, zSqlCopy, &zErrMsg); + sqlite3DbFree(db, zSqlCopy); + pParse->zTail = &zSql[pParse->zTail-zSqlCopy]; + }else{ + pParse->zTail = &zSql[nBytes]; + } + }else{ + sqlite3RunParser(pParse, zSql, &zErrMsg); + } + assert( 1==(int)pParse->nQueryLoop ); + + if( db->mallocFailed ){ + pParse->rc = SQLITE_NOMEM; + } + if( pParse->rc==SQLITE_DONE ) pParse->rc = SQLITE_OK; + if( pParse->checkSchema ){ + schemaIsValid(pParse); + } + if( db->mallocFailed ){ + pParse->rc = SQLITE_NOMEM; + } + if( pzTail ){ + *pzTail = pParse->zTail; + } + rc = pParse->rc; + +#ifndef SQLITE_OMIT_EXPLAIN + if( rc==SQLITE_OK && pParse->pVdbe && pParse->explain ){ + static const char * const azColName[] = { + "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment", + "selectid", "order", "from", "detail" + }; + int iFirst, mx; + if( pParse->explain==2 ){ + sqlite3VdbeSetNumCols(pParse->pVdbe, 4); + iFirst = 8; + mx = 12; + }else{ + sqlite3VdbeSetNumCols(pParse->pVdbe, 8); + iFirst = 0; + mx = 8; + } + for(i=iFirst; ipVdbe, i-iFirst, COLNAME_NAME, + azColName[i], SQLITE_STATIC); + } + } +#endif + + assert( db->init.busy==0 || saveSqlFlag==0 ); + if( db->init.busy==0 ){ + Vdbe *pVdbe = pParse->pVdbe; + sqlite3VdbeSetSql(pVdbe, zSql, (int)(pParse->zTail-zSql), saveSqlFlag); + } + if( pParse->pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){ + sqlite3VdbeFinalize(pParse->pVdbe); + assert(!(*ppStmt)); + }else{ + *ppStmt = (sqlite3_stmt*)pParse->pVdbe; + } + + if( zErrMsg ){ + sqlite3Error(db, rc, "%s", zErrMsg); + sqlite3DbFree(db, zErrMsg); + }else{ + sqlite3Error(db, rc, 0); + } + + /* Delete any TriggerPrg structures allocated while parsing this statement. */ + while( pParse->pTriggerPrg ){ + TriggerPrg *pT = pParse->pTriggerPrg; + pParse->pTriggerPrg = pT->pNext; + sqlite3DbFree(db, pT); + } + +end_prepare: + + sqlite3StackFree(db, pParse); + rc = sqlite3ApiExit(db, rc); + assert( (rc&db->errMask)==rc ); + return rc; +} +static int sqlite3LockAndPrepare( + sqlite3 *db, /* Database handle. */ + const char *zSql, /* UTF-8 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + int saveSqlFlag, /* True to copy SQL text into the sqlite3_stmt */ + Vdbe *pOld, /* VM being reprepared */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const char **pzTail /* OUT: End of parsed string */ +){ + int rc; + assert( ppStmt!=0 ); + *ppStmt = 0; + if( !sqlite3SafetyCheckOk(db) ){ + return SQLITE_MISUSE_BKPT; + } + sqlite3_mutex_enter(db->mutex); + sqlite3BtreeEnterAll(db); + rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail); + if( rc==SQLITE_SCHEMA ){ + sqlite3_finalize(*ppStmt); + rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail); + } + sqlite3BtreeLeaveAll(db); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** Rerun the compilation of a statement after a schema change. +** +** If the statement is successfully recompiled, return SQLITE_OK. Otherwise, +** if the statement cannot be recompiled because another connection has +** locked the sqlite3_master table, return SQLITE_LOCKED. If any other error +** occurs, return SQLITE_SCHEMA. +*/ +int sqlite3Reprepare(Vdbe *p){ + int rc; + sqlite3_stmt *pNew; + const char *zSql; + sqlite3 *db; + + assert( sqlite3_mutex_held(sqlite3VdbeDb(p)->mutex) ); + zSql = sqlite3_sql((sqlite3_stmt *)p); + assert( zSql!=0 ); /* Reprepare only called for prepare_v2() statements */ + db = sqlite3VdbeDb(p); + assert( sqlite3_mutex_held(db->mutex) ); + rc = sqlite3LockAndPrepare(db, zSql, -1, 0, p, &pNew, 0); + if( rc ){ + if( rc==SQLITE_NOMEM ){ + db->mallocFailed = 1; + } + assert( pNew==0 ); + return rc; + }else{ + assert( pNew!=0 ); + } + sqlite3VdbeSwap((Vdbe*)pNew, p); + sqlite3TransferBindings(pNew, (sqlite3_stmt*)p); + sqlite3VdbeResetStepResult((Vdbe*)pNew); + sqlite3VdbeFinalize((Vdbe*)pNew); + return SQLITE_OK; +} + + +/* +** Two versions of the official API. Legacy and new use. In the legacy +** version, the original SQL text is not saved in the prepared statement +** and so if a schema change occurs, SQLITE_SCHEMA is returned by +** sqlite3_step(). In the new version, the original SQL text is retained +** and the statement is automatically recompiled if an schema change +** occurs. +*/ +int sqlite3_prepare( + sqlite3 *db, /* Database handle. */ + const char *zSql, /* UTF-8 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const char **pzTail /* OUT: End of parsed string */ +){ + int rc; + rc = sqlite3LockAndPrepare(db,zSql,nBytes,0,0,ppStmt,pzTail); + assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ + return rc; +} +int sqlite3_prepare_v2( + sqlite3 *db, /* Database handle. */ + const char *zSql, /* UTF-8 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const char **pzTail /* OUT: End of parsed string */ +){ + int rc; + rc = sqlite3LockAndPrepare(db,zSql,nBytes,1,0,ppStmt,pzTail); + assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ + return rc; +} + + +#ifndef SQLITE_OMIT_UTF16 +/* +** Compile the UTF-16 encoded SQL statement zSql into a statement handle. +*/ +static int sqlite3Prepare16( + sqlite3 *db, /* Database handle. */ + const void *zSql, /* UTF-16 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + int saveSqlFlag, /* True to save SQL text into the sqlite3_stmt */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const void **pzTail /* OUT: End of parsed string */ +){ + /* This function currently works by first transforming the UTF-16 + ** encoded string to UTF-8, then invoking sqlite3_prepare(). The + ** tricky bit is figuring out the pointer to return in *pzTail. + */ + char *zSql8; + const char *zTail8 = 0; + int rc = SQLITE_OK; + + assert( ppStmt ); + *ppStmt = 0; + if( !sqlite3SafetyCheckOk(db) ){ + return SQLITE_MISUSE_BKPT; + } + sqlite3_mutex_enter(db->mutex); + zSql8 = sqlite3Utf16to8(db, zSql, nBytes, SQLITE_UTF16NATIVE); + if( zSql8 ){ + rc = sqlite3LockAndPrepare(db, zSql8, -1, saveSqlFlag, 0, ppStmt, &zTail8); + } + + if( zTail8 && pzTail ){ + /* If sqlite3_prepare returns a tail pointer, we calculate the + ** equivalent pointer into the UTF-16 string by counting the unicode + ** characters between zSql8 and zTail8, and then returning a pointer + ** the same number of characters into the UTF-16 string. + */ + int chars_parsed = sqlite3Utf8CharLen(zSql8, (int)(zTail8-zSql8)); + *pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, chars_parsed); + } + sqlite3DbFree(db, zSql8); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** Two versions of the official API. Legacy and new use. In the legacy +** version, the original SQL text is not saved in the prepared statement +** and so if a schema change occurs, SQLITE_SCHEMA is returned by +** sqlite3_step(). In the new version, the original SQL text is retained +** and the statement is automatically recompiled if an schema change +** occurs. +*/ +int sqlite3_prepare16( + sqlite3 *db, /* Database handle. */ + const void *zSql, /* UTF-16 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const void **pzTail /* OUT: End of parsed string */ +){ + int rc; + rc = sqlite3Prepare16(db,zSql,nBytes,0,ppStmt,pzTail); + assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ + return rc; +} +int sqlite3_prepare16_v2( + sqlite3 *db, /* Database handle. */ + const void *zSql, /* UTF-16 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const void **pzTail /* OUT: End of parsed string */ +){ + int rc; + rc = sqlite3Prepare16(db,zSql,nBytes,1,ppStmt,pzTail); + assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ + return rc; +} + +#endif /* SQLITE_OMIT_UTF16 */ diff --git a/scalos/libraries/sqlite/src/printf.c b/scalos/libraries/sqlite/src/printf.c new file mode 100644 index 000000000..58cfd2bd4 --- /dev/null +++ b/scalos/libraries/sqlite/src/printf.c @@ -0,0 +1,970 @@ +/* +** The "printf" code that follows dates from the 1980's. It is in +** the public domain. The original comments are included here for +** completeness. They are very out-of-date but might be useful as +** an historical reference. Most of the "enhancements" have been backed +** out so that the functionality is now the same as standard printf(). +** +************************************************************************** +** +** This file contains code for a set of "printf"-like routines. These +** routines format strings much like the printf() from the standard C +** library, though the implementation here has enhancements to support +** SQLlite. +*/ +#include "sqliteInt.h" + +/* +** Conversion types fall into various categories as defined by the +** following enumeration. +*/ +#define etRADIX 1 /* Integer types. %d, %x, %o, and so forth */ +#define etFLOAT 2 /* Floating point. %f */ +#define etEXP 3 /* Exponentional notation. %e and %E */ +#define etGENERIC 4 /* Floating or exponential, depending on exponent. %g */ +#define etSIZE 5 /* Return number of characters processed so far. %n */ +#define etSTRING 6 /* Strings. %s */ +#define etDYNSTRING 7 /* Dynamically allocated strings. %z */ +#define etPERCENT 8 /* Percent symbol. %% */ +#define etCHARX 9 /* Characters. %c */ +/* The rest are extensions, not normally found in printf() */ +#define etSQLESCAPE 10 /* Strings with '\'' doubled. %q */ +#define etSQLESCAPE2 11 /* Strings with '\'' doubled and enclosed in '', + NULL pointers replaced by SQL NULL. %Q */ +#define etTOKEN 12 /* a pointer to a Token structure */ +#define etSRCLIST 13 /* a pointer to a SrcList */ +#define etPOINTER 14 /* The %p conversion */ +#define etSQLESCAPE3 15 /* %w -> Strings with '\"' doubled */ +#define etORDINAL 16 /* %r -> 1st, 2nd, 3rd, 4th, etc. English only */ + +#define etINVALID 0 /* Any unrecognized conversion type */ + + +/* +** An "etByte" is an 8-bit unsigned value. +*/ +typedef unsigned char etByte; + +/* +** Each builtin conversion character (ex: the 'd' in "%d") is described +** by an instance of the following structure +*/ +typedef struct et_info { /* Information about each format field */ + char fmttype; /* The format field code letter */ + etByte base; /* The base for radix conversion */ + etByte flags; /* One or more of FLAG_ constants below */ + etByte type; /* Conversion paradigm */ + etByte charset; /* Offset into aDigits[] of the digits string */ + etByte prefix; /* Offset into aPrefix[] of the prefix string */ +} et_info; + +/* +** Allowed values for et_info.flags +*/ +#define FLAG_SIGNED 1 /* True if the value to convert is signed */ +#define FLAG_INTERN 2 /* True if for internal use only */ +#define FLAG_STRING 4 /* Allow infinity precision */ + + +/* +** The following table is searched linearly, so it is good to put the +** most frequently used conversion types first. +*/ +static const char aDigits[] = "0123456789ABCDEF0123456789abcdef"; +static const char aPrefix[] = "-x0\000X0"; +static const et_info fmtinfo[] = { + { 'd', 10, 1, etRADIX, 0, 0 }, + { 's', 0, 4, etSTRING, 0, 0 }, + { 'g', 0, 1, etGENERIC, 30, 0 }, + { 'z', 0, 4, etDYNSTRING, 0, 0 }, + { 'q', 0, 4, etSQLESCAPE, 0, 0 }, + { 'Q', 0, 4, etSQLESCAPE2, 0, 0 }, + { 'w', 0, 4, etSQLESCAPE3, 0, 0 }, + { 'c', 0, 0, etCHARX, 0, 0 }, + { 'o', 8, 0, etRADIX, 0, 2 }, + { 'u', 10, 0, etRADIX, 0, 0 }, + { 'x', 16, 0, etRADIX, 16, 1 }, + { 'X', 16, 0, etRADIX, 0, 4 }, +#ifndef SQLITE_OMIT_FLOATING_POINT + { 'f', 0, 1, etFLOAT, 0, 0 }, + { 'e', 0, 1, etEXP, 30, 0 }, + { 'E', 0, 1, etEXP, 14, 0 }, + { 'G', 0, 1, etGENERIC, 14, 0 }, +#endif + { 'i', 10, 1, etRADIX, 0, 0 }, + { 'n', 0, 0, etSIZE, 0, 0 }, + { '%', 0, 0, etPERCENT, 0, 0 }, + { 'p', 16, 0, etPOINTER, 0, 1 }, + +/* All the rest have the FLAG_INTERN bit set and are thus for internal +** use only */ + { 'T', 0, 2, etTOKEN, 0, 0 }, + { 'S', 0, 2, etSRCLIST, 0, 0 }, + { 'r', 10, 3, etORDINAL, 0, 0 }, +}; + +/* +** If SQLITE_OMIT_FLOATING_POINT is defined, then none of the floating point +** conversions will work. +*/ +#ifndef SQLITE_OMIT_FLOATING_POINT +/* +** "*val" is a double such that 0.1 <= *val < 10.0 +** Return the ascii code for the leading digit of *val, then +** multiply "*val" by 10.0 to renormalize. +** +** Example: +** input: *val = 3.14159 +** output: *val = 1.4159 function return = '3' +** +** The counter *cnt is incremented each time. After counter exceeds +** 16 (the number of significant digits in a 64-bit float) '0' is +** always returned. +*/ +static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){ + int digit; + LONGDOUBLE_TYPE d; + if( (*cnt)++ >= 16 ) return '0'; + digit = (int)*val; + d = digit; + digit += '0'; + *val = (*val - d)*10.0; + return (char)digit; +} +#endif /* SQLITE_OMIT_FLOATING_POINT */ + +/* +** Append N space characters to the given string buffer. +*/ +void sqlite3AppendSpace(StrAccum *pAccum, int N){ + static const char zSpaces[] = " "; + while( N>=(int)sizeof(zSpaces)-1 ){ + sqlite3StrAccumAppend(pAccum, zSpaces, sizeof(zSpaces)-1); + N -= sizeof(zSpaces)-1; + } + if( N>0 ){ + sqlite3StrAccumAppend(pAccum, zSpaces, N); + } +} + +/* +** On machines with a small stack size, you can redefine the +** SQLITE_PRINT_BUF_SIZE to be something smaller, if desired. +*/ +#ifndef SQLITE_PRINT_BUF_SIZE +# define SQLITE_PRINT_BUF_SIZE 70 +#endif +#define etBUFSIZE SQLITE_PRINT_BUF_SIZE /* Size of the output buffer */ + +/* +** Render a string given by "fmt" into the StrAccum object. +*/ +void sqlite3VXPrintf( + StrAccum *pAccum, /* Accumulate results here */ + int useExtended, /* Allow extended %-conversions */ + const char *fmt, /* Format string */ + va_list ap /* arguments */ +){ + int c; /* Next character in the format string */ + char *bufpt; /* Pointer to the conversion buffer */ + int precision; /* Precision of the current field */ + int length; /* Length of the field */ + int idx; /* A general purpose loop counter */ + int width; /* Width of the current field */ + etByte flag_leftjustify; /* True if "-" flag is present */ + etByte flag_plussign; /* True if "+" flag is present */ + etByte flag_blanksign; /* True if " " flag is present */ + etByte flag_alternateform; /* True if "#" flag is present */ + etByte flag_altform2; /* True if "!" flag is present */ + etByte flag_zeropad; /* True if field width constant starts with zero */ + etByte flag_long; /* True if "l" flag is present */ + etByte flag_longlong; /* True if the "ll" flag is present */ + etByte done; /* Loop termination flag */ + etByte xtype = 0; /* Conversion paradigm */ + char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */ + sqlite_uint64 longvalue; /* Value for integer types */ + LONGDOUBLE_TYPE realvalue; /* Value for real types */ + const et_info *infop; /* Pointer to the appropriate info structure */ + char *zOut; /* Rendering buffer */ + int nOut; /* Size of the rendering buffer */ + char *zExtra; /* Malloced memory used by some conversion */ +#ifndef SQLITE_OMIT_FLOATING_POINT + int exp, e2; /* exponent of real numbers */ + int nsd; /* Number of significant digits returned */ + double rounder; /* Used for rounding floating point values */ + etByte flag_dp; /* True if decimal point should be shown */ + etByte flag_rtz; /* True if trailing zeros should be removed */ +#endif + char buf[etBUFSIZE]; /* Conversion buffer */ + + bufpt = 0; + for(; (c=(*fmt))!=0; ++fmt){ + if( c!='%' ){ + int amt; + bufpt = (char *)fmt; + amt = 1; + while( (c=(*++fmt))!='%' && c!=0 ) amt++; + sqlite3StrAccumAppend(pAccum, bufpt, amt); + if( c==0 ) break; + } + if( (c=(*++fmt))==0 ){ + sqlite3StrAccumAppend(pAccum, "%", 1); + break; + } + /* Find out what flags are present */ + flag_leftjustify = flag_plussign = flag_blanksign = + flag_alternateform = flag_altform2 = flag_zeropad = 0; + done = 0; + do{ + switch( c ){ + case '-': flag_leftjustify = 1; break; + case '+': flag_plussign = 1; break; + case ' ': flag_blanksign = 1; break; + case '#': flag_alternateform = 1; break; + case '!': flag_altform2 = 1; break; + case '0': flag_zeropad = 1; break; + default: done = 1; break; + } + }while( !done && (c=(*++fmt))!=0 ); + /* Get the field width */ + width = 0; + if( c=='*' ){ + width = va_arg(ap,int); + if( width<0 ){ + flag_leftjustify = 1; + width = -width; + } + c = *++fmt; + }else{ + while( c>='0' && c<='9' ){ + width = width*10 + c - '0'; + c = *++fmt; + } + } + /* Get the precision */ + if( c=='.' ){ + precision = 0; + c = *++fmt; + if( c=='*' ){ + precision = va_arg(ap,int); + if( precision<0 ) precision = -precision; + c = *++fmt; + }else{ + while( c>='0' && c<='9' ){ + precision = precision*10 + c - '0'; + c = *++fmt; + } + } + }else{ + precision = -1; + } + /* Get the conversion type modifier */ + if( c=='l' ){ + flag_long = 1; + c = *++fmt; + if( c=='l' ){ + flag_longlong = 1; + c = *++fmt; + }else{ + flag_longlong = 0; + } + }else{ + flag_long = flag_longlong = 0; + } + /* Fetch the info entry for the field */ + infop = &fmtinfo[0]; + xtype = etINVALID; + for(idx=0; idxflags & FLAG_INTERN)==0 ){ + xtype = infop->type; + }else{ + return; + } + break; + } + } + zExtra = 0; + + /* + ** At this point, variables are initialized as follows: + ** + ** flag_alternateform TRUE if a '#' is present. + ** flag_altform2 TRUE if a '!' is present. + ** flag_plussign TRUE if a '+' is present. + ** flag_leftjustify TRUE if a '-' is present or if the + ** field width was negative. + ** flag_zeropad TRUE if the width began with 0. + ** flag_long TRUE if the letter 'l' (ell) prefixed + ** the conversion character. + ** flag_longlong TRUE if the letter 'll' (ell ell) prefixed + ** the conversion character. + ** flag_blanksign TRUE if a ' ' is present. + ** width The specified field width. This is + ** always non-negative. Zero is the default. + ** precision The specified precision. The default + ** is -1. + ** xtype The class of the conversion. + ** infop Pointer to the appropriate info struct. + */ + switch( xtype ){ + case etPOINTER: + flag_longlong = sizeof(char*)==sizeof(i64); + flag_long = sizeof(char*)==sizeof(long int); + /* Fall through into the next case */ + case etORDINAL: + case etRADIX: + if( infop->flags & FLAG_SIGNED ){ + i64 v; + if( flag_longlong ){ + v = va_arg(ap,i64); + }else if( flag_long ){ + v = va_arg(ap,long int); + }else{ + v = va_arg(ap,int); + } + if( v<0 ){ + if( v==SMALLEST_INT64 ){ + longvalue = ((u64)1)<<63; + }else{ + longvalue = -v; + } + prefix = '-'; + }else{ + longvalue = v; + if( flag_plussign ) prefix = '+'; + else if( flag_blanksign ) prefix = ' '; + else prefix = 0; + } + }else{ + if( flag_longlong ){ + longvalue = va_arg(ap,u64); + }else if( flag_long ){ + longvalue = va_arg(ap,unsigned long int); + }else{ + longvalue = va_arg(ap,unsigned int); + } + prefix = 0; + } + if( longvalue==0 ) flag_alternateform = 0; + if( flag_zeropad && precisionmallocFailed = 1; + return; + } + } + bufpt = &zOut[nOut-1]; + if( xtype==etORDINAL ){ + static const char zOrd[] = "thstndrd"; + int x = (int)(longvalue % 10); + if( x>=4 || (longvalue/10)%10==1 ){ + x = 0; + } + *(--bufpt) = zOrd[x*2+1]; + *(--bufpt) = zOrd[x*2]; + } + { + register const char *cset; /* Use registers for speed */ + register int base; + cset = &aDigits[infop->charset]; + base = infop->base; + do{ /* Convert to ascii */ + *(--bufpt) = cset[longvalue%base]; + longvalue = longvalue/base; + }while( longvalue>0 ); + } + length = (int)(&zOut[nOut-1]-bufpt); + for(idx=precision-length; idx>0; idx--){ + *(--bufpt) = '0'; /* Zero pad */ + } + if( prefix ) *(--bufpt) = prefix; /* Add sign */ + if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */ + const char *pre; + char x; + pre = &aPrefix[infop->prefix]; + for(; (x=(*pre))!=0; pre++) *(--bufpt) = x; + } + length = (int)(&zOut[nOut-1]-bufpt); + break; + case etFLOAT: + case etEXP: + case etGENERIC: + realvalue = va_arg(ap,double); +#ifdef SQLITE_OMIT_FLOATING_POINT + length = 0; +#else + if( precision<0 ) precision = 6; /* Set default precision */ + if( realvalue<0.0 ){ + realvalue = -realvalue; + prefix = '-'; + }else{ + if( flag_plussign ) prefix = '+'; + else if( flag_blanksign ) prefix = ' '; + else prefix = 0; + } + if( xtype==etGENERIC && precision>0 ) precision--; +#if 0 + /* Rounding works like BSD when the constant 0.4999 is used. Wierd! */ + for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1); +#else + /* It makes more sense to use 0.5 */ + for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1){} +#endif + if( xtype==etFLOAT ) realvalue += rounder; + /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */ + exp = 0; + if( sqlite3IsNaN((double)realvalue) ){ + bufpt = "NaN"; + length = 3; + break; + } + if( realvalue>0.0 ){ + while( realvalue>=1e32 && exp<=350 ){ realvalue *= 1e-32; exp+=32; } + while( realvalue>=1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; } + while( realvalue>=10.0 && exp<=350 ){ realvalue *= 0.1; exp++; } + while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; } + while( realvalue<1.0 ){ realvalue *= 10.0; exp--; } + if( exp>350 ){ + if( prefix=='-' ){ + bufpt = "-Inf"; + }else if( prefix=='+' ){ + bufpt = "+Inf"; + }else{ + bufpt = "Inf"; + } + length = sqlite3Strlen30(bufpt); + break; + } + } + bufpt = buf; + /* + ** If the field type is etGENERIC, then convert to either etEXP + ** or etFLOAT, as appropriate. + */ + if( xtype!=etFLOAT ){ + realvalue += rounder; + if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; } + } + if( xtype==etGENERIC ){ + flag_rtz = !flag_alternateform; + if( exp<-4 || exp>precision ){ + xtype = etEXP; + }else{ + precision = precision - exp; + xtype = etFLOAT; + } + }else{ + flag_rtz = 0; + } + if( xtype==etEXP ){ + e2 = 0; + }else{ + e2 = exp; + } + if( e2+precision+width > etBUFSIZE - 15 ){ + bufpt = zExtra = sqlite3Malloc( e2+precision+width+15 ); + if( bufpt==0 ){ + pAccum->mallocFailed = 1; + return; + } + } + zOut = bufpt; + nsd = 0; + flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2; + /* The sign in front of the number */ + if( prefix ){ + *(bufpt++) = prefix; + } + /* Digits prior to the decimal point */ + if( e2<0 ){ + *(bufpt++) = '0'; + }else{ + for(; e2>=0; e2--){ + *(bufpt++) = et_getdigit(&realvalue,&nsd); + } + } + /* The decimal point */ + if( flag_dp ){ + *(bufpt++) = '.'; + } + /* "0" digits after the decimal point but before the first + ** significant digit of the number */ + for(e2++; e2<0; precision--, e2++){ + assert( precision>0 ); + *(bufpt++) = '0'; + } + /* Significant digits after the decimal point */ + while( (precision--)>0 ){ + *(bufpt++) = et_getdigit(&realvalue,&nsd); + } + /* Remove trailing zeros and the "." if no digits follow the "." */ + if( flag_rtz && flag_dp ){ + while( bufpt[-1]=='0' ) *(--bufpt) = 0; + assert( bufpt>zOut ); + if( bufpt[-1]=='.' ){ + if( flag_altform2 ){ + *(bufpt++) = '0'; + }else{ + *(--bufpt) = 0; + } + } + } + /* Add the "eNNN" suffix */ + if( xtype==etEXP ){ + *(bufpt++) = aDigits[infop->charset]; + if( exp<0 ){ + *(bufpt++) = '-'; exp = -exp; + }else{ + *(bufpt++) = '+'; + } + if( exp>=100 ){ + *(bufpt++) = (char)((exp/100)+'0'); /* 100's digit */ + exp %= 100; + } + *(bufpt++) = (char)(exp/10+'0'); /* 10's digit */ + *(bufpt++) = (char)(exp%10+'0'); /* 1's digit */ + } + *bufpt = 0; + + /* The converted number is in buf[] and zero terminated. Output it. + ** Note that the number is in the usual order, not reversed as with + ** integer conversions. */ + length = (int)(bufpt-zOut); + bufpt = zOut; + + /* Special case: Add leading zeros if the flag_zeropad flag is + ** set and we are not left justified */ + if( flag_zeropad && !flag_leftjustify && length < width){ + int i; + int nPad = width - length; + for(i=width; i>=nPad; i--){ + bufpt[i] = bufpt[i-nPad]; + } + i = prefix!=0; + while( nPad-- ) bufpt[i++] = '0'; + length = width; + } +#endif /* !defined(SQLITE_OMIT_FLOATING_POINT) */ + break; + case etSIZE: + *(va_arg(ap,int*)) = pAccum->nChar; + length = width = 0; + break; + case etPERCENT: + buf[0] = '%'; + bufpt = buf; + length = 1; + break; + case etCHARX: + c = va_arg(ap,int); + buf[0] = (char)c; + if( precision>=0 ){ + for(idx=1; idx=0 ){ + for(length=0; lengthetBUFSIZE ){ + bufpt = zExtra = sqlite3Malloc( n ); + if( bufpt==0 ){ + pAccum->mallocFailed = 1; + return; + } + }else{ + bufpt = buf; + } + j = 0; + if( needQuote ) bufpt[j++] = q; + k = i; + for(i=0; i=0 && precisionz, pToken->n); + } + length = width = 0; + break; + } + case etSRCLIST: { + SrcList *pSrc = va_arg(ap, SrcList*); + int k = va_arg(ap, int); + struct SrcList_item *pItem = &pSrc->a[k]; + assert( k>=0 && knSrc ); + if( pItem->zDatabase ){ + sqlite3StrAccumAppend(pAccum, pItem->zDatabase, -1); + sqlite3StrAccumAppend(pAccum, ".", 1); + } + sqlite3StrAccumAppend(pAccum, pItem->zName, -1); + length = width = 0; + break; + } + default: { + assert( xtype==etINVALID ); + return; + } + }/* End switch over the format type */ + /* + ** The text of the conversion is pointed to by "bufpt" and is + ** "length" characters long. The field width is "width". Do + ** the output. + */ + if( !flag_leftjustify ){ + register int nspace; + nspace = width-length; + if( nspace>0 ){ + sqlite3AppendSpace(pAccum, nspace); + } + } + if( length>0 ){ + sqlite3StrAccumAppend(pAccum, bufpt, length); + } + if( flag_leftjustify ){ + register int nspace; + nspace = width-length; + if( nspace>0 ){ + sqlite3AppendSpace(pAccum, nspace); + } + } + sqlite3_free(zExtra); + }/* End for loop over the format string */ +} /* End of function */ + +/* +** Append N bytes of text from z to the StrAccum object. +*/ +void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){ + assert( z!=0 || N==0 ); + if( p->tooBig | p->mallocFailed ){ + testcase(p->tooBig); + testcase(p->mallocFailed); + return; + } + assert( p->zText!=0 || p->nChar==0 ); + if( N<0 ){ + N = sqlite3Strlen30(z); + } + if( N==0 || NEVER(z==0) ){ + return; + } + if( p->nChar+N >= p->nAlloc ){ + char *zNew; + if( !p->useMalloc ){ + p->tooBig = 1; + N = p->nAlloc - p->nChar - 1; + if( N<=0 ){ + return; + } + }else{ + char *zOld = (p->zText==p->zBase ? 0 : p->zText); + i64 szNew = p->nChar; + szNew += N + 1; + if( szNew > p->mxAlloc ){ + sqlite3StrAccumReset(p); + p->tooBig = 1; + return; + }else{ + p->nAlloc = (int)szNew; + } + if( p->useMalloc==1 ){ + zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc); + }else{ + zNew = sqlite3_realloc(zOld, p->nAlloc); + } + if( zNew ){ + if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar); + p->zText = zNew; + }else{ + p->mallocFailed = 1; + sqlite3StrAccumReset(p); + return; + } + } + } + assert( p->zText ); + memcpy(&p->zText[p->nChar], z, N); + p->nChar += N; +} + +/* +** Finish off a string by making sure it is zero-terminated. +** Return a pointer to the resulting string. Return a NULL +** pointer if any kind of error was encountered. +*/ +char *sqlite3StrAccumFinish(StrAccum *p){ + if( p->zText ){ + p->zText[p->nChar] = 0; + if( p->useMalloc && p->zText==p->zBase ){ + if( p->useMalloc==1 ){ + p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 ); + }else{ + p->zText = sqlite3_malloc(p->nChar+1); + } + if( p->zText ){ + memcpy(p->zText, p->zBase, p->nChar+1); + }else{ + p->mallocFailed = 1; + } + } + } + return p->zText; +} + +/* +** Reset an StrAccum string. Reclaim all malloced memory. +*/ +void sqlite3StrAccumReset(StrAccum *p){ + if( p->zText!=p->zBase ){ + if( p->useMalloc==1 ){ + sqlite3DbFree(p->db, p->zText); + }else{ + sqlite3_free(p->zText); + } + } + p->zText = 0; +} + +/* +** Initialize a string accumulator +*/ +void sqlite3StrAccumInit(StrAccum *p, char *zBase, int n, int mx){ + p->zText = p->zBase = zBase; + p->db = 0; + p->nChar = 0; + p->nAlloc = n; + p->mxAlloc = mx; + p->useMalloc = 1; + p->tooBig = 0; + p->mallocFailed = 0; +} + +/* +** Print into memory obtained from sqliteMalloc(). Use the internal +** %-conversion extensions. +*/ +char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){ + char *z; + char zBase[SQLITE_PRINT_BUF_SIZE]; + StrAccum acc; + assert( db!=0 ); + sqlite3StrAccumInit(&acc, zBase, sizeof(zBase), + db->aLimit[SQLITE_LIMIT_LENGTH]); + acc.db = db; + sqlite3VXPrintf(&acc, 1, zFormat, ap); + z = sqlite3StrAccumFinish(&acc); + if( acc.mallocFailed ){ + db->mallocFailed = 1; + } + return z; +} + +/* +** Print into memory obtained from sqliteMalloc(). Use the internal +** %-conversion extensions. +*/ +char *sqlite3MPrintf(sqlite3 *db, const char *zFormat, ...){ + va_list ap; + char *z; + va_start(ap, zFormat); + z = sqlite3VMPrintf(db, zFormat, ap); + va_end(ap); + return z; +} + +/* +** Like sqlite3MPrintf(), but call sqlite3DbFree() on zStr after formatting +** the string and before returnning. This routine is intended to be used +** to modify an existing string. For example: +** +** x = sqlite3MPrintf(db, x, "prefix %s suffix", x); +** +*/ +char *sqlite3MAppendf(sqlite3 *db, char *zStr, const char *zFormat, ...){ + va_list ap; + char *z; + va_start(ap, zFormat); + z = sqlite3VMPrintf(db, zFormat, ap); + va_end(ap); + sqlite3DbFree(db, zStr); + return z; +} + +/* +** Print into memory obtained from sqlite3_malloc(). Omit the internal +** %-conversion extensions. +*/ +char *sqlite3_vmprintf(const char *zFormat, va_list ap){ + char *z; + char zBase[SQLITE_PRINT_BUF_SIZE]; + StrAccum acc; +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + sqlite3StrAccumInit(&acc, zBase, sizeof(zBase), SQLITE_MAX_LENGTH); + acc.useMalloc = 2; + sqlite3VXPrintf(&acc, 0, zFormat, ap); + z = sqlite3StrAccumFinish(&acc); + return z; +} + +/* +** Print into memory obtained from sqlite3_malloc()(). Omit the internal +** %-conversion extensions. +*/ +char *sqlite3_mprintf(const char *zFormat, ...){ + va_list ap; + char *z; +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + va_start(ap, zFormat); + z = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + return z; +} + +/* +** sqlite3_snprintf() works like snprintf() except that it ignores the +** current locale settings. This is important for SQLite because we +** are not able to use a "," as the decimal point in place of "." as +** specified by some locales. +** +** Oops: The first two arguments of sqlite3_snprintf() are backwards +** from the snprintf() standard. Unfortunately, it is too late to change +** this without breaking compatibility, so we just have to live with the +** mistake. +** +** sqlite3_vsnprintf() is the varargs version. +*/ +char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){ + StrAccum acc; + if( n<=0 ) return zBuf; + sqlite3StrAccumInit(&acc, zBuf, n, 0); + acc.useMalloc = 0; + sqlite3VXPrintf(&acc, 0, zFormat, ap); + return sqlite3StrAccumFinish(&acc); +} +char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){ + char *z; + va_list ap; + va_start(ap,zFormat); + z = sqlite3_vsnprintf(n, zBuf, zFormat, ap); + va_end(ap); + return z; +} + +/* +** This is the routine that actually formats the sqlite3_log() message. +** We house it in a separate routine from sqlite3_log() to avoid using +** stack space on small-stack systems when logging is disabled. +** +** sqlite3_log() must render into a static buffer. It cannot dynamically +** allocate memory because it might be called while the memory allocator +** mutex is held. +*/ +static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){ + StrAccum acc; /* String accumulator */ + char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */ + + sqlite3StrAccumInit(&acc, zMsg, sizeof(zMsg), 0); + acc.useMalloc = 0; + sqlite3VXPrintf(&acc, 0, zFormat, ap); + sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode, + sqlite3StrAccumFinish(&acc)); +} + +/* +** Format and write a message to the log if logging is enabled. +*/ +void sqlite3_log(int iErrCode, const char *zFormat, ...){ + va_list ap; /* Vararg list */ + if( sqlite3GlobalConfig.xLog ){ + va_start(ap, zFormat); + renderLogMsg(iErrCode, zFormat, ap); + va_end(ap); + } +} + +#if defined(SQLITE_DEBUG) +/* +** A version of printf() that understands %lld. Used for debugging. +** The printf() built into some versions of windows does not understand %lld +** and segfaults if you give it a long long int. +*/ +void sqlite3DebugPrintf(const char *zFormat, ...){ + va_list ap; + StrAccum acc; + char zBuf[500]; + sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0); + acc.useMalloc = 0; + va_start(ap,zFormat); + sqlite3VXPrintf(&acc, 0, zFormat, ap); + va_end(ap); + sqlite3StrAccumFinish(&acc); + fprintf(stdout,"%s", zBuf); + fflush(stdout); +} +#endif + +#ifndef SQLITE_OMIT_TRACE +/* +** variable-argument wrapper around sqlite3VXPrintf(). +*/ +void sqlite3XPrintf(StrAccum *p, const char *zFormat, ...){ + va_list ap; + va_start(ap,zFormat); + sqlite3VXPrintf(p, 1, zFormat, ap); + va_end(ap); +} +#endif diff --git a/scalos/libraries/sqlite/src/random.c b/scalos/libraries/sqlite/src/random.c new file mode 100644 index 000000000..234ebdf65 --- /dev/null +++ b/scalos/libraries/sqlite/src/random.c @@ -0,0 +1,145 @@ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code to implement a pseudo-random number +** generator (PRNG) for SQLite. +** +** Random numbers are used by some of the database backends in order +** to generate random integer keys for tables or random filenames. +*/ +#include "sqliteInt.h" + + +/* All threads share a single random number generator. +** This structure is the current state of the generator. +*/ +static SQLITE_WSD struct sqlite3PrngType { + unsigned char isInit; /* True if initialized */ + unsigned char i, j; /* State variables */ + unsigned char s[256]; /* State variables */ +} sqlite3Prng; + +/* +** Get a single 8-bit random value from the RC4 PRNG. The Mutex +** must be held while executing this routine. +** +** Why not just use a library random generator like lrand48() for this? +** Because the OP_NewRowid opcode in the VDBE depends on having a very +** good source of random numbers. The lrand48() library function may +** well be good enough. But maybe not. Or maybe lrand48() has some +** subtle problems on some systems that could cause problems. It is hard +** to know. To minimize the risk of problems due to bad lrand48() +** implementations, SQLite uses this random number generator based +** on RC4, which we know works very well. +** +** (Later): Actually, OP_NewRowid does not depend on a good source of +** randomness any more. But we will leave this code in all the same. +*/ +static u8 randomByte(void){ + unsigned char t; + + + /* The "wsdPrng" macro will resolve to the pseudo-random number generator + ** state vector. If writable static data is unsupported on the target, + ** we have to locate the state vector at run-time. In the more common + ** case where writable static data is supported, wsdPrng can refer directly + ** to the "sqlite3Prng" state vector declared above. + */ +#ifdef SQLITE_OMIT_WSD + struct sqlite3PrngType *p = &GLOBAL(struct sqlite3PrngType, sqlite3Prng); +# define wsdPrng p[0] +#else +# define wsdPrng sqlite3Prng +#endif + + + /* Initialize the state of the random number generator once, + ** the first time this routine is called. The seed value does + ** not need to contain a lot of randomness since we are not + ** trying to do secure encryption or anything like that... + ** + ** Nothing in this file or anywhere else in SQLite does any kind of + ** encryption. The RC4 algorithm is being used as a PRNG (pseudo-random + ** number generator) not as an encryption device. + */ + if( !wsdPrng.isInit ){ + int i; + char k[256]; + wsdPrng.j = 0; + wsdPrng.i = 0; + sqlite3OsRandomness(sqlite3_vfs_find(0), 256, k); + for(i=0; i<256; i++){ + wsdPrng.s[i] = (u8)i; + } + for(i=0; i<256; i++){ + wsdPrng.j += wsdPrng.s[i] + k[i]; + t = wsdPrng.s[wsdPrng.j]; + wsdPrng.s[wsdPrng.j] = wsdPrng.s[i]; + wsdPrng.s[i] = t; + } + wsdPrng.isInit = 1; + } + + /* Generate and return single random byte + */ + wsdPrng.i++; + t = wsdPrng.s[wsdPrng.i]; + wsdPrng.j += t; + wsdPrng.s[wsdPrng.i] = wsdPrng.s[wsdPrng.j]; + wsdPrng.s[wsdPrng.j] = t; + t += wsdPrng.s[wsdPrng.i]; + return wsdPrng.s[t]; +} + +/* +** Return N random bytes. +*/ +void sqlite3_randomness(int N, void *pBuf){ + unsigned char *zBuf = pBuf; +#if SQLITE_THREADSAFE + sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG); +#endif + sqlite3_mutex_enter(mutex); + while( N-- ){ + *(zBuf++) = randomByte(); + } + sqlite3_mutex_leave(mutex); +} + +#ifndef SQLITE_OMIT_BUILTIN_TEST +/* +** For testing purposes, we sometimes want to preserve the state of +** PRNG and restore the PRNG to its saved state at a later time, or +** to reset the PRNG to its initial state. These routines accomplish +** those tasks. +** +** The sqlite3_test_control() interface calls these routines to +** control the PRNG. +*/ +static SQLITE_WSD struct sqlite3PrngType sqlite3SavedPrng; +void sqlite3PrngSaveState(void){ + memcpy( + &GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng), + &GLOBAL(struct sqlite3PrngType, sqlite3Prng), + sizeof(sqlite3Prng) + ); +} +void sqlite3PrngRestoreState(void){ + memcpy( + &GLOBAL(struct sqlite3PrngType, sqlite3Prng), + &GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng), + sizeof(sqlite3Prng) + ); +} +void sqlite3PrngResetState(void){ + GLOBAL(struct sqlite3PrngType, sqlite3Prng).isInit = 0; +} +#endif /* SQLITE_OMIT_BUILTIN_TEST */ diff --git a/scalos/libraries/sqlite/src/resolve.c b/scalos/libraries/sqlite/src/resolve.c new file mode 100644 index 000000000..3da48136f --- /dev/null +++ b/scalos/libraries/sqlite/src/resolve.c @@ -0,0 +1,1223 @@ +/* +** 2008 August 18 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains routines used for walking the parser tree and +** resolve all identifiers by associating them with a particular +** table and column. +*/ +#include "sqliteInt.h" +#include +#include + +/* +** Turn the pExpr expression into an alias for the iCol-th column of the +** result set in pEList. +** +** If the result set column is a simple column reference, then this routine +** makes an exact copy. But for any other kind of expression, this +** routine make a copy of the result set column as the argument to the +** TK_AS operator. The TK_AS operator causes the expression to be +** evaluated just once and then reused for each alias. +** +** The reason for suppressing the TK_AS term when the expression is a simple +** column reference is so that the column reference will be recognized as +** usable by indices within the WHERE clause processing logic. +** +** Hack: The TK_AS operator is inhibited if zType[0]=='G'. This means +** that in a GROUP BY clause, the expression is evaluated twice. Hence: +** +** SELECT random()%5 AS x, count(*) FROM tab GROUP BY x +** +** Is equivalent to: +** +** SELECT random()%5 AS x, count(*) FROM tab GROUP BY random()%5 +** +** The result of random()%5 in the GROUP BY clause is probably different +** from the result in the result-set. We might fix this someday. Or +** then again, we might not... +*/ +static void resolveAlias( + Parse *pParse, /* Parsing context */ + ExprList *pEList, /* A result set */ + int iCol, /* A column in the result set. 0..pEList->nExpr-1 */ + Expr *pExpr, /* Transform this into an alias to the result set */ + const char *zType /* "GROUP" or "ORDER" or "" */ +){ + Expr *pOrig; /* The iCol-th column of the result set */ + Expr *pDup; /* Copy of pOrig */ + sqlite3 *db; /* The database connection */ + + assert( iCol>=0 && iColnExpr ); + pOrig = pEList->a[iCol].pExpr; + assert( pOrig!=0 ); + assert( pOrig->flags & EP_Resolved ); + db = pParse->db; + if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){ + pDup = sqlite3ExprDup(db, pOrig, 0); + pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0); + if( pDup==0 ) return; + if( pEList->a[iCol].iAlias==0 ){ + pEList->a[iCol].iAlias = (u16)(++pParse->nAlias); + } + pDup->iTable = pEList->a[iCol].iAlias; + }else if( ExprHasProperty(pOrig, EP_IntValue) || pOrig->u.zToken==0 ){ + pDup = sqlite3ExprDup(db, pOrig, 0); + if( pDup==0 ) return; + }else{ + char *zToken = pOrig->u.zToken; + assert( zToken!=0 ); + pOrig->u.zToken = 0; + pDup = sqlite3ExprDup(db, pOrig, 0); + pOrig->u.zToken = zToken; + if( pDup==0 ) return; + assert( (pDup->flags & (EP_Reduced|EP_TokenOnly))==0 ); + pDup->flags2 |= EP2_MallocedToken; + pDup->u.zToken = sqlite3DbStrDup(db, zToken); + } + if( pExpr->flags & EP_ExpCollate ){ + pDup->pColl = pExpr->pColl; + pDup->flags |= EP_ExpCollate; + } + + /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This + ** prevents ExprDelete() from deleting the Expr structure itself, + ** allowing it to be repopulated by the memcpy() on the following line. + */ + ExprSetProperty(pExpr, EP_Static); + sqlite3ExprDelete(db, pExpr); + memcpy(pExpr, pDup, sizeof(*pExpr)); + sqlite3DbFree(db, pDup); +} + + +/* +** Return TRUE if the name zCol occurs anywhere in the USING clause. +** +** Return FALSE if the USING clause is NULL or if it does not contain +** zCol. +*/ +static int nameInUsingClause(IdList *pUsing, const char *zCol){ + if( pUsing ){ + int k; + for(k=0; knId; k++){ + if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ) return 1; + } + } + return 0; +} + + +/* +** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up +** that name in the set of source tables in pSrcList and make the pExpr +** expression node refer back to that source column. The following changes +** are made to pExpr: +** +** pExpr->iDb Set the index in db->aDb[] of the database X +** (even if X is implied). +** pExpr->iTable Set to the cursor number for the table obtained +** from pSrcList. +** pExpr->pTab Points to the Table structure of X.Y (even if +** X and/or Y are implied.) +** pExpr->iColumn Set to the column number within the table. +** pExpr->op Set to TK_COLUMN. +** pExpr->pLeft Any expression this points to is deleted +** pExpr->pRight Any expression this points to is deleted. +** +** The zDb variable is the name of the database (the "X"). This value may be +** NULL meaning that name is of the form Y.Z or Z. Any available database +** can be used. The zTable variable is the name of the table (the "Y"). This +** value can be NULL if zDb is also NULL. If zTable is NULL it +** means that the form of the name is Z and that columns from any table +** can be used. +** +** If the name cannot be resolved unambiguously, leave an error message +** in pParse and return WRC_Abort. Return WRC_Prune on success. +*/ +static int lookupName( + Parse *pParse, /* The parsing context */ + const char *zDb, /* Name of the database containing table, or NULL */ + const char *zTab, /* Name of table containing column, or NULL */ + const char *zCol, /* Name of the column. */ + NameContext *pNC, /* The name context used to resolve the name */ + Expr *pExpr /* Make this EXPR node point to the selected column */ +){ + int i, j; /* Loop counters */ + int cnt = 0; /* Number of matching column names */ + int cntTab = 0; /* Number of matching table names */ + sqlite3 *db = pParse->db; /* The database connection */ + struct SrcList_item *pItem; /* Use for looping over pSrcList items */ + struct SrcList_item *pMatch = 0; /* The matching pSrcList item */ + NameContext *pTopNC = pNC; /* First namecontext in the list */ + Schema *pSchema = 0; /* Schema of the expression */ + int isTrigger = 0; + + assert( pNC ); /* the name context cannot be NULL. */ + assert( zCol ); /* The Z in X.Y.Z cannot be NULL */ + assert( ~ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) ); + + /* Initialize the node to no-match */ + pExpr->iTable = -1; + pExpr->pTab = 0; + ExprSetIrreducible(pExpr); + + /* Start at the inner-most context and move outward until a match is found */ + while( pNC && cnt==0 ){ + ExprList *pEList; + SrcList *pSrcList = pNC->pSrcList; + + if( pSrcList ){ + for(i=0, pItem=pSrcList->a; inSrc; i++, pItem++){ + Table *pTab; + int iDb; + Column *pCol; + + pTab = pItem->pTab; + assert( pTab!=0 && pTab->zName!=0 ); + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( pTab->nCol>0 ); + if( zTab ){ + if( pItem->zAlias ){ + char *zTabName = pItem->zAlias; + if( sqlite3StrICmp(zTabName, zTab)!=0 ) continue; + }else{ + char *zTabName = pTab->zName; + if( NEVER(zTabName==0) || sqlite3StrICmp(zTabName, zTab)!=0 ){ + continue; + } + if( zDb!=0 && sqlite3StrICmp(db->aDb[iDb].zName, zDb)!=0 ){ + continue; + } + } + } + if( 0==(cntTab++) ){ + pExpr->iTable = pItem->iCursor; + pExpr->pTab = pTab; + pSchema = pTab->pSchema; + pMatch = pItem; + } + for(j=0, pCol=pTab->aCol; jnCol; j++, pCol++){ + if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ + /* If there has been exactly one prior match and this match + ** is for the right-hand table of a NATURAL JOIN or is in a + ** USING clause, then skip this match. + */ + if( cnt==1 ){ + if( pItem->jointype & JT_NATURAL ) continue; + if( nameInUsingClause(pItem->pUsing, zCol) ) continue; + } + cnt++; + pExpr->iTable = pItem->iCursor; + pExpr->pTab = pTab; + pMatch = pItem; + pSchema = pTab->pSchema; + /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ + pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j; + break; + } + } + } + } + +#ifndef SQLITE_OMIT_TRIGGER + /* If we have not already resolved the name, then maybe + ** it is a new.* or old.* trigger argument reference + */ + if( zDb==0 && zTab!=0 && cnt==0 && pParse->pTriggerTab!=0 ){ + int op = pParse->eTriggerOp; + Table *pTab = 0; + assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT ); + if( op!=TK_DELETE && sqlite3StrICmp("new",zTab) == 0 ){ + pExpr->iTable = 1; + pTab = pParse->pTriggerTab; + }else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){ + pExpr->iTable = 0; + pTab = pParse->pTriggerTab; + } + + if( pTab ){ + int iCol; + pSchema = pTab->pSchema; + cntTab++; + for(iCol=0; iColnCol; iCol++){ + Column *pCol = &pTab->aCol[iCol]; + if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ + if( iCol==pTab->iPKey ){ + iCol = -1; + } + break; + } + } + if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) ){ + iCol = -1; /* IMP: R-44911-55124 */ + } + if( iColnCol ){ + cnt++; + if( iCol<0 ){ + pExpr->affinity = SQLITE_AFF_INTEGER; + }else if( pExpr->iTable==0 ){ + testcase( iCol==31 ); + testcase( iCol==32 ); + pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<iColumn = (i16)iCol; + pExpr->pTab = pTab; + isTrigger = 1; + } + } + } +#endif /* !defined(SQLITE_OMIT_TRIGGER) */ + + /* + ** Perhaps the name is a reference to the ROWID + */ + if( cnt==0 && cntTab==1 && sqlite3IsRowid(zCol) ){ + cnt = 1; + pExpr->iColumn = -1; /* IMP: R-44911-55124 */ + pExpr->affinity = SQLITE_AFF_INTEGER; + } + + /* + ** If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z + ** might refer to an result-set alias. This happens, for example, when + ** we are resolving names in the WHERE clause of the following command: + ** + ** SELECT a+b AS x FROM table WHERE x<10; + ** + ** In cases like this, replace pExpr with a copy of the expression that + ** forms the result set entry ("a+b" in the example) and return immediately. + ** Note that the expression in the result set should have already been + ** resolved by the time the WHERE clause is resolved. + */ + if( cnt==0 && (pEList = pNC->pEList)!=0 && zTab==0 ){ + for(j=0; jnExpr; j++){ + char *zAs = pEList->a[j].zName; + if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){ + Expr *pOrig; + assert( pExpr->pLeft==0 && pExpr->pRight==0 ); + assert( pExpr->x.pList==0 ); + assert( pExpr->x.pSelect==0 ); + pOrig = pEList->a[j].pExpr; + if( !pNC->allowAgg && ExprHasProperty(pOrig, EP_Agg) ){ + sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs); + return WRC_Abort; + } + resolveAlias(pParse, pEList, j, pExpr, ""); + cnt = 1; + pMatch = 0; + assert( zTab==0 && zDb==0 ); + goto lookupname_end; + } + } + } + + /* Advance to the next name context. The loop will exit when either + ** we have a match (cnt>0) or when we run out of name contexts. + */ + if( cnt==0 ){ + pNC = pNC->pNext; + } + } + + /* + ** If X and Y are NULL (in other words if only the column name Z is + ** supplied) and the value of Z is enclosed in double-quotes, then + ** Z is a string literal if it doesn't match any column names. In that + ** case, we need to return right away and not make any changes to + ** pExpr. + ** + ** Because no reference was made to outer contexts, the pNC->nRef + ** fields are not changed in any context. + */ + if( cnt==0 && zTab==0 && ExprHasProperty(pExpr,EP_DblQuoted) ){ + pExpr->op = TK_STRING; + pExpr->pTab = 0; + return WRC_Prune; + } + + /* + ** cnt==0 means there was not match. cnt>1 means there were two or + ** more matches. Either way, we have an error. + */ + if( cnt!=1 ){ + const char *zErr; + zErr = cnt==0 ? "no such column" : "ambiguous column name"; + if( zDb ){ + sqlite3ErrorMsg(pParse, "%s: %s.%s.%s", zErr, zDb, zTab, zCol); + }else if( zTab ){ + sqlite3ErrorMsg(pParse, "%s: %s.%s", zErr, zTab, zCol); + }else{ + sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol); + } + pParse->checkSchema = 1; + pTopNC->nErr++; + } + + /* If a column from a table in pSrcList is referenced, then record + ** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes + ** bit 0 to be set. Column 1 sets bit 1. And so forth. If the + ** column number is greater than the number of bits in the bitmask + ** then set the high-order bit of the bitmask. + */ + if( pExpr->iColumn>=0 && pMatch!=0 ){ + int n = pExpr->iColumn; + testcase( n==BMS-1 ); + if( n>=BMS ){ + n = BMS-1; + } + assert( pMatch->iCursor==pExpr->iTable ); + pMatch->colUsed |= ((Bitmask)1)<pLeft); + pExpr->pLeft = 0; + sqlite3ExprDelete(db, pExpr->pRight); + pExpr->pRight = 0; + pExpr->op = (isTrigger ? TK_TRIGGER : TK_COLUMN); +lookupname_end: + if( cnt==1 ){ + assert( pNC!=0 ); + sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList); + /* Increment the nRef value on all name contexts from TopNC up to + ** the point where the name matched. */ + for(;;){ + assert( pTopNC!=0 ); + pTopNC->nRef++; + if( pTopNC==pNC ) break; + pTopNC = pTopNC->pNext; + } + return WRC_Prune; + } else { + return WRC_Abort; + } +} + +/* +** Allocate and return a pointer to an expression to load the column iCol +** from datasource iSrc in SrcList pSrc. +*/ +Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){ + Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0); + if( p ){ + struct SrcList_item *pItem = &pSrc->a[iSrc]; + p->pTab = pItem->pTab; + p->iTable = pItem->iCursor; + if( p->pTab->iPKey==iCol ){ + p->iColumn = -1; + }else{ + p->iColumn = (ynVar)iCol; + testcase( iCol==BMS ); + testcase( iCol==BMS-1 ); + pItem->colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol); + } + ExprSetProperty(p, EP_Resolved); + } + return p; +} + +/* +** This routine is callback for sqlite3WalkExpr(). +** +** Resolve symbolic names into TK_COLUMN operators for the current +** node in the expression tree. Return 0 to continue the search down +** the tree or 2 to abort the tree walk. +** +** This routine also does error checking and name resolution for +** function names. The operator for aggregate functions is changed +** to TK_AGG_FUNCTION. +*/ +static int resolveExprStep(Walker *pWalker, Expr *pExpr){ + NameContext *pNC; + Parse *pParse; + + pNC = pWalker->u.pNC; + assert( pNC!=0 ); + pParse = pNC->pParse; + assert( pParse==pWalker->pParse ); + + if( ExprHasAnyProperty(pExpr, EP_Resolved) ) return WRC_Prune; + ExprSetProperty(pExpr, EP_Resolved); +#ifndef NDEBUG + if( pNC->pSrcList && pNC->pSrcList->nAlloc>0 ){ + SrcList *pSrcList = pNC->pSrcList; + int i; + for(i=0; ipSrcList->nSrc; i++){ + assert( pSrcList->a[i].iCursor>=0 && pSrcList->a[i].iCursornTab); + } + } +#endif + switch( pExpr->op ){ + +#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) + /* The special operator TK_ROW means use the rowid for the first + ** column in the FROM clause. This is used by the LIMIT and ORDER BY + ** clause processing on UPDATE and DELETE statements. + */ + case TK_ROW: { + SrcList *pSrcList = pNC->pSrcList; + struct SrcList_item *pItem; + assert( pSrcList && pSrcList->nSrc==1 ); + pItem = pSrcList->a; + pExpr->op = TK_COLUMN; + pExpr->pTab = pItem->pTab; + pExpr->iTable = pItem->iCursor; + pExpr->iColumn = -1; + pExpr->affinity = SQLITE_AFF_INTEGER; + break; + } +#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */ + + /* A lone identifier is the name of a column. + */ + case TK_ID: { + return lookupName(pParse, 0, 0, pExpr->u.zToken, pNC, pExpr); + } + + /* A table name and column name: ID.ID + ** Or a database, table and column: ID.ID.ID + */ + case TK_DOT: { + const char *zColumn; + const char *zTable; + const char *zDb; + Expr *pRight; + + /* if( pSrcList==0 ) break; */ + pRight = pExpr->pRight; + if( pRight->op==TK_ID ){ + zDb = 0; + zTable = pExpr->pLeft->u.zToken; + zColumn = pRight->u.zToken; + }else{ + assert( pRight->op==TK_DOT ); + zDb = pExpr->pLeft->u.zToken; + zTable = pRight->pLeft->u.zToken; + zColumn = pRight->pRight->u.zToken; + } + return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr); + } + + /* Resolve function names + */ + case TK_CONST_FUNC: + case TK_FUNCTION: { + ExprList *pList = pExpr->x.pList; /* The argument list */ + int n = pList ? pList->nExpr : 0; /* Number of arguments */ + int no_such_func = 0; /* True if no such function exists */ + int wrong_num_args = 0; /* True if wrong number of arguments */ + int is_agg = 0; /* True if is an aggregate function */ + int auth; /* Authorization to use the function */ + int nId; /* Number of characters in function name */ + const char *zId; /* The function name. */ + FuncDef *pDef; /* Information about the function */ + u8 enc = ENC(pParse->db); /* The database encoding */ + + testcase( pExpr->op==TK_CONST_FUNC ); + assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); + zId = pExpr->u.zToken; + nId = sqlite3Strlen30(zId); + pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0); + if( pDef==0 ){ + pDef = sqlite3FindFunction(pParse->db, zId, nId, -1, enc, 0); + if( pDef==0 ){ + no_such_func = 1; + }else{ + wrong_num_args = 1; + } + }else{ + is_agg = pDef->xFunc==0; + } +#ifndef SQLITE_OMIT_AUTHORIZATION + if( pDef ){ + auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0); + if( auth!=SQLITE_OK ){ + if( auth==SQLITE_DENY ){ + sqlite3ErrorMsg(pParse, "not authorized to use function: %s", + pDef->zName); + pNC->nErr++; + } + pExpr->op = TK_NULL; + return WRC_Prune; + } + } +#endif + if( is_agg && !pNC->allowAgg ){ + sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId); + pNC->nErr++; + is_agg = 0; + }else if( no_such_func ){ + sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId); + pNC->nErr++; + }else if( wrong_num_args ){ + sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()", + nId, zId); + pNC->nErr++; + } + if( is_agg ){ + pExpr->op = TK_AGG_FUNCTION; + pNC->hasAgg = 1; + } + if( is_agg ) pNC->allowAgg = 0; + sqlite3WalkExprList(pWalker, pList); + if( is_agg ) pNC->allowAgg = 1; + /* FIX ME: Compute pExpr->affinity based on the expected return + ** type of the function + */ + return WRC_Prune; + } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_SELECT: + case TK_EXISTS: testcase( pExpr->op==TK_EXISTS ); +#endif + case TK_IN: { + testcase( pExpr->op==TK_IN ); + if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + int nRef = pNC->nRef; +#ifndef SQLITE_OMIT_CHECK + if( pNC->isCheck ){ + sqlite3ErrorMsg(pParse,"subqueries prohibited in CHECK constraints"); + } +#endif + sqlite3WalkSelect(pWalker, pExpr->x.pSelect); + assert( pNC->nRef>=nRef ); + if( nRef!=pNC->nRef ){ + ExprSetProperty(pExpr, EP_VarSelect); + } + } + break; + } +#ifndef SQLITE_OMIT_CHECK + case TK_VARIABLE: { + if( pNC->isCheck ){ + sqlite3ErrorMsg(pParse,"parameters prohibited in CHECK constraints"); + } + break; + } +#endif + } + return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue; +} + +/* +** pEList is a list of expressions which are really the result set of the +** a SELECT statement. pE is a term in an ORDER BY or GROUP BY clause. +** This routine checks to see if pE is a simple identifier which corresponds +** to the AS-name of one of the terms of the expression list. If it is, +** this routine return an integer between 1 and N where N is the number of +** elements in pEList, corresponding to the matching entry. If there is +** no match, or if pE is not a simple identifier, then this routine +** return 0. +** +** pEList has been resolved. pE has not. +*/ +static int resolveAsName( + Parse *pParse, /* Parsing context for error messages */ + ExprList *pEList, /* List of expressions to scan */ + Expr *pE /* Expression we are trying to match */ +){ + int i; /* Loop counter */ + + UNUSED_PARAMETER(pParse); + + if( pE->op==TK_ID ){ + char *zCol = pE->u.zToken; + for(i=0; inExpr; i++){ + char *zAs = pEList->a[i].zName; + if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){ + return i+1; + } + } + } + return 0; +} + +/* +** pE is a pointer to an expression which is a single term in the +** ORDER BY of a compound SELECT. The expression has not been +** name resolved. +** +** At the point this routine is called, we already know that the +** ORDER BY term is not an integer index into the result set. That +** case is handled by the calling routine. +** +** Attempt to match pE against result set columns in the left-most +** SELECT statement. Return the index i of the matching column, +** as an indication to the caller that it should sort by the i-th column. +** The left-most column is 1. In other words, the value returned is the +** same integer value that would be used in the SQL statement to indicate +** the column. +** +** If there is no match, return 0. Return -1 if an error occurs. +*/ +static int resolveOrderByTermToExprList( + Parse *pParse, /* Parsing context for error messages */ + Select *pSelect, /* The SELECT statement with the ORDER BY clause */ + Expr *pE /* The specific ORDER BY term */ +){ + int i; /* Loop counter */ + ExprList *pEList; /* The columns of the result set */ + NameContext nc; /* Name context for resolving pE */ + sqlite3 *db; /* Database connection */ + int rc; /* Return code from subprocedures */ + u8 savedSuppErr; /* Saved value of db->suppressErr */ + + assert( sqlite3ExprIsInteger(pE, &i)==0 ); + pEList = pSelect->pEList; + + /* Resolve all names in the ORDER BY term expression + */ + memset(&nc, 0, sizeof(nc)); + nc.pParse = pParse; + nc.pSrcList = pSelect->pSrc; + nc.pEList = pEList; + nc.allowAgg = 1; + nc.nErr = 0; + db = pParse->db; + savedSuppErr = db->suppressErr; + db->suppressErr = 1; + rc = sqlite3ResolveExprNames(&nc, pE); + db->suppressErr = savedSuppErr; + if( rc ) return 0; + + /* Try to match the ORDER BY expression against an expression + ** in the result set. Return an 1-based index of the matching + ** result-set entry. + */ + for(i=0; inExpr; i++){ + if( sqlite3ExprCompare(pEList->a[i].pExpr, pE)<2 ){ + return i+1; + } + } + + /* If no match, return 0. */ + return 0; +} + +/* +** Generate an ORDER BY or GROUP BY term out-of-range error. +*/ +static void resolveOutOfRangeError( + Parse *pParse, /* The error context into which to write the error */ + const char *zType, /* "ORDER" or "GROUP" */ + int i, /* The index (1-based) of the term out of range */ + int mx /* Largest permissible value of i */ +){ + sqlite3ErrorMsg(pParse, + "%r %s BY term out of range - should be " + "between 1 and %d", i, zType, mx); +} + +/* +** Analyze the ORDER BY clause in a compound SELECT statement. Modify +** each term of the ORDER BY clause is a constant integer between 1 +** and N where N is the number of columns in the compound SELECT. +** +** ORDER BY terms that are already an integer between 1 and N are +** unmodified. ORDER BY terms that are integers outside the range of +** 1 through N generate an error. ORDER BY terms that are expressions +** are matched against result set expressions of compound SELECT +** beginning with the left-most SELECT and working toward the right. +** At the first match, the ORDER BY expression is transformed into +** the integer column number. +** +** Return the number of errors seen. +*/ +static int resolveCompoundOrderBy( + Parse *pParse, /* Parsing context. Leave error messages here */ + Select *pSelect /* The SELECT statement containing the ORDER BY */ +){ + int i; + ExprList *pOrderBy; + ExprList *pEList; + sqlite3 *db; + int moreToDo = 1; + + pOrderBy = pSelect->pOrderBy; + if( pOrderBy==0 ) return 0; + db = pParse->db; +#if SQLITE_MAX_COLUMN + if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ + sqlite3ErrorMsg(pParse, "too many terms in ORDER BY clause"); + return 1; + } +#endif + for(i=0; inExpr; i++){ + pOrderBy->a[i].done = 0; + } + pSelect->pNext = 0; + while( pSelect->pPrior ){ + pSelect->pPrior->pNext = pSelect; + pSelect = pSelect->pPrior; + } + while( pSelect && moreToDo ){ + struct ExprList_item *pItem; + moreToDo = 0; + pEList = pSelect->pEList; + assert( pEList!=0 ); + for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ + int iCol = -1; + Expr *pE, *pDup; + if( pItem->done ) continue; + pE = pItem->pExpr; + if( sqlite3ExprIsInteger(pE, &iCol) ){ + if( iCol<=0 || iCol>pEList->nExpr ){ + resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr); + return 1; + } + }else{ + iCol = resolveAsName(pParse, pEList, pE); + if( iCol==0 ){ + pDup = sqlite3ExprDup(db, pE, 0); + if( !db->mallocFailed ){ + assert(pDup); + iCol = resolveOrderByTermToExprList(pParse, pSelect, pDup); + } + sqlite3ExprDelete(db, pDup); + } + } + if( iCol>0 ){ + CollSeq *pColl = pE->pColl; + int flags = pE->flags & EP_ExpCollate; + sqlite3ExprDelete(db, pE); + pItem->pExpr = pE = sqlite3Expr(db, TK_INTEGER, 0); + if( pE==0 ) return 1; + pE->pColl = pColl; + pE->flags |= EP_IntValue | flags; + pE->u.iValue = iCol; + pItem->iOrderByCol = (u16)iCol; + pItem->done = 1; + }else{ + moreToDo = 1; + } + } + pSelect = pSelect->pNext; + } + for(i=0; inExpr; i++){ + if( pOrderBy->a[i].done==0 ){ + sqlite3ErrorMsg(pParse, "%r ORDER BY term does not match any " + "column in the result set", i+1); + return 1; + } + } + return 0; +} + +/* +** Check every term in the ORDER BY or GROUP BY clause pOrderBy of +** the SELECT statement pSelect. If any term is reference to a +** result set expression (as determined by the ExprList.a.iCol field) +** then convert that term into a copy of the corresponding result set +** column. +** +** If any errors are detected, add an error message to pParse and +** return non-zero. Return zero if no errors are seen. +*/ +int sqlite3ResolveOrderGroupBy( + Parse *pParse, /* Parsing context. Leave error messages here */ + Select *pSelect, /* The SELECT statement containing the clause */ + ExprList *pOrderBy, /* The ORDER BY or GROUP BY clause to be processed */ + const char *zType /* "ORDER" or "GROUP" */ +){ + int i; + sqlite3 *db = pParse->db; + ExprList *pEList; + struct ExprList_item *pItem; + + if( pOrderBy==0 || pParse->db->mallocFailed ) return 0; +#if SQLITE_MAX_COLUMN + if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ + sqlite3ErrorMsg(pParse, "too many terms in %s BY clause", zType); + return 1; + } +#endif + pEList = pSelect->pEList; + assert( pEList!=0 ); /* sqlite3SelectNew() guarantees this */ + for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ + if( pItem->iOrderByCol ){ + if( pItem->iOrderByCol>pEList->nExpr ){ + resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr); + return 1; + } + resolveAlias(pParse, pEList, pItem->iOrderByCol-1, pItem->pExpr, zType); + } + } + return 0; +} + +/* +** pOrderBy is an ORDER BY or GROUP BY clause in SELECT statement pSelect. +** The Name context of the SELECT statement is pNC. zType is either +** "ORDER" or "GROUP" depending on which type of clause pOrderBy is. +** +** This routine resolves each term of the clause into an expression. +** If the order-by term is an integer I between 1 and N (where N is the +** number of columns in the result set of the SELECT) then the expression +** in the resolution is a copy of the I-th result-set expression. If +** the order-by term is an identify that corresponds to the AS-name of +** a result-set expression, then the term resolves to a copy of the +** result-set expression. Otherwise, the expression is resolved in +** the usual way - using sqlite3ResolveExprNames(). +** +** This routine returns the number of errors. If errors occur, then +** an appropriate error message might be left in pParse. (OOM errors +** excepted.) +*/ +static int resolveOrderGroupBy( + NameContext *pNC, /* The name context of the SELECT statement */ + Select *pSelect, /* The SELECT statement holding pOrderBy */ + ExprList *pOrderBy, /* An ORDER BY or GROUP BY clause to resolve */ + const char *zType /* Either "ORDER" or "GROUP", as appropriate */ +){ + int i; /* Loop counter */ + int iCol; /* Column number */ + struct ExprList_item *pItem; /* A term of the ORDER BY clause */ + Parse *pParse; /* Parsing context */ + int nResult; /* Number of terms in the result set */ + + if( pOrderBy==0 ) return 0; + nResult = pSelect->pEList->nExpr; + pParse = pNC->pParse; + for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ + Expr *pE = pItem->pExpr; + iCol = resolveAsName(pParse, pSelect->pEList, pE); + if( iCol>0 ){ + /* If an AS-name match is found, mark this ORDER BY column as being + ** a copy of the iCol-th result-set column. The subsequent call to + ** sqlite3ResolveOrderGroupBy() will convert the expression to a + ** copy of the iCol-th result-set expression. */ + pItem->iOrderByCol = (u16)iCol; + continue; + } + if( sqlite3ExprIsInteger(pE, &iCol) ){ + /* The ORDER BY term is an integer constant. Again, set the column + ** number so that sqlite3ResolveOrderGroupBy() will convert the + ** order-by term to a copy of the result-set expression */ + if( iCol<1 ){ + resolveOutOfRangeError(pParse, zType, i+1, nResult); + return 1; + } + pItem->iOrderByCol = (u16)iCol; + continue; + } + + /* Otherwise, treat the ORDER BY term as an ordinary expression */ + pItem->iOrderByCol = 0; + if( sqlite3ResolveExprNames(pNC, pE) ){ + return 1; + } + } + return sqlite3ResolveOrderGroupBy(pParse, pSelect, pOrderBy, zType); +} + +/* +** Resolve names in the SELECT statement p and all of its descendents. +*/ +static int resolveSelectStep(Walker *pWalker, Select *p){ + NameContext *pOuterNC; /* Context that contains this SELECT */ + NameContext sNC; /* Name context of this SELECT */ + int isCompound; /* True if p is a compound select */ + int nCompound; /* Number of compound terms processed so far */ + Parse *pParse; /* Parsing context */ + ExprList *pEList; /* Result set expression list */ + int i; /* Loop counter */ + ExprList *pGroupBy; /* The GROUP BY clause */ + Select *pLeftmost; /* Left-most of SELECT of a compound */ + sqlite3 *db; /* Database connection */ + + + assert( p!=0 ); + if( p->selFlags & SF_Resolved ){ + return WRC_Prune; + } + pOuterNC = pWalker->u.pNC; + pParse = pWalker->pParse; + db = pParse->db; + + /* Normally sqlite3SelectExpand() will be called first and will have + ** already expanded this SELECT. However, if this is a subquery within + ** an expression, sqlite3ResolveExprNames() will be called without a + ** prior call to sqlite3SelectExpand(). When that happens, let + ** sqlite3SelectPrep() do all of the processing for this SELECT. + ** sqlite3SelectPrep() will invoke both sqlite3SelectExpand() and + ** this routine in the correct order. + */ + if( (p->selFlags & SF_Expanded)==0 ){ + sqlite3SelectPrep(pParse, p, pOuterNC); + return (pParse->nErr || db->mallocFailed) ? WRC_Abort : WRC_Prune; + } + + isCompound = p->pPrior!=0; + nCompound = 0; + pLeftmost = p; + while( p ){ + assert( (p->selFlags & SF_Expanded)!=0 ); + assert( (p->selFlags & SF_Resolved)==0 ); + p->selFlags |= SF_Resolved; + + /* Resolve the expressions in the LIMIT and OFFSET clauses. These + ** are not allowed to refer to any names, so pass an empty NameContext. + */ + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + if( sqlite3ResolveExprNames(&sNC, p->pLimit) || + sqlite3ResolveExprNames(&sNC, p->pOffset) ){ + return WRC_Abort; + } + + /* Set up the local name-context to pass to sqlite3ResolveExprNames() to + ** resolve the result-set expression list. + */ + sNC.allowAgg = 1; + sNC.pSrcList = p->pSrc; + sNC.pNext = pOuterNC; + + /* Resolve names in the result set. */ + pEList = p->pEList; + assert( pEList!=0 ); + for(i=0; inExpr; i++){ + Expr *pX = pEList->a[i].pExpr; + if( sqlite3ResolveExprNames(&sNC, pX) ){ + return WRC_Abort; + } + } + + /* Recursively resolve names in all subqueries + */ + for(i=0; ipSrc->nSrc; i++){ + struct SrcList_item *pItem = &p->pSrc->a[i]; + if( pItem->pSelect ){ + NameContext *pNC; /* Used to iterate name contexts */ + int nRef = 0; /* Refcount for pOuterNC and outer contexts */ + const char *zSavedContext = pParse->zAuthContext; + + /* Count the total number of references to pOuterNC and all of its + ** parent contexts. After resolving references to expressions in + ** pItem->pSelect, check if this value has changed. If so, then + ** SELECT statement pItem->pSelect must be correlated. Set the + ** pItem->isCorrelated flag if this is the case. */ + for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef += pNC->nRef; + + if( pItem->zName ) pParse->zAuthContext = pItem->zName; + sqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC); + pParse->zAuthContext = zSavedContext; + if( pParse->nErr || db->mallocFailed ) return WRC_Abort; + + for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef -= pNC->nRef; + assert( pItem->isCorrelated==0 && nRef<=0 ); + pItem->isCorrelated = (nRef!=0); + } + } + + /* If there are no aggregate functions in the result-set, and no GROUP BY + ** expression, do not allow aggregates in any of the other expressions. + */ + assert( (p->selFlags & SF_Aggregate)==0 ); + pGroupBy = p->pGroupBy; + if( pGroupBy || sNC.hasAgg ){ + p->selFlags |= SF_Aggregate; + }else{ + sNC.allowAgg = 0; + } + + /* If a HAVING clause is present, then there must be a GROUP BY clause. + */ + if( p->pHaving && !pGroupBy ){ + sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING"); + return WRC_Abort; + } + + /* Add the expression list to the name-context before parsing the + ** other expressions in the SELECT statement. This is so that + ** expressions in the WHERE clause (etc.) can refer to expressions by + ** aliases in the result set. + ** + ** Minor point: If this is the case, then the expression will be + ** re-evaluated for each reference to it. + */ + sNC.pEList = p->pEList; + if( sqlite3ResolveExprNames(&sNC, p->pWhere) || + sqlite3ResolveExprNames(&sNC, p->pHaving) + ){ + return WRC_Abort; + } + + /* The ORDER BY and GROUP BY clauses may not refer to terms in + ** outer queries + */ + sNC.pNext = 0; + sNC.allowAgg = 1; + + /* Process the ORDER BY clause for singleton SELECT statements. + ** The ORDER BY clause for compounds SELECT statements is handled + ** below, after all of the result-sets for all of the elements of + ** the compound have been resolved. + */ + if( !isCompound && resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER") ){ + return WRC_Abort; + } + if( db->mallocFailed ){ + return WRC_Abort; + } + + /* Resolve the GROUP BY clause. At the same time, make sure + ** the GROUP BY clause does not contain aggregate functions. + */ + if( pGroupBy ){ + struct ExprList_item *pItem; + + if( resolveOrderGroupBy(&sNC, p, pGroupBy, "GROUP") || db->mallocFailed ){ + return WRC_Abort; + } + for(i=0, pItem=pGroupBy->a; inExpr; i++, pItem++){ + if( ExprHasProperty(pItem->pExpr, EP_Agg) ){ + sqlite3ErrorMsg(pParse, "aggregate functions are not allowed in " + "the GROUP BY clause"); + return WRC_Abort; + } + } + } + + /* Advance to the next term of the compound + */ + p = p->pPrior; + nCompound++; + } + + /* Resolve the ORDER BY on a compound SELECT after all terms of + ** the compound have been resolved. + */ + if( isCompound && resolveCompoundOrderBy(pParse, pLeftmost) ){ + return WRC_Abort; + } + + return WRC_Prune; +} + +/* +** This routine walks an expression tree and resolves references to +** table columns and result-set columns. At the same time, do error +** checking on function usage and set a flag if any aggregate functions +** are seen. +** +** To resolve table columns references we look for nodes (or subtrees) of the +** form X.Y.Z or Y.Z or just Z where +** +** X: The name of a database. Ex: "main" or "temp" or +** the symbolic name assigned to an ATTACH-ed database. +** +** Y: The name of a table in a FROM clause. Or in a trigger +** one of the special names "old" or "new". +** +** Z: The name of a column in table Y. +** +** The node at the root of the subtree is modified as follows: +** +** Expr.op Changed to TK_COLUMN +** Expr.pTab Points to the Table object for X.Y +** Expr.iColumn The column index in X.Y. -1 for the rowid. +** Expr.iTable The VDBE cursor number for X.Y +** +** +** To resolve result-set references, look for expression nodes of the +** form Z (with no X and Y prefix) where the Z matches the right-hand +** size of an AS clause in the result-set of a SELECT. The Z expression +** is replaced by a copy of the left-hand side of the result-set expression. +** Table-name and function resolution occurs on the substituted expression +** tree. For example, in: +** +** SELECT a+b AS x, c+d AS y FROM t1 ORDER BY x; +** +** The "x" term of the order by is replaced by "a+b" to render: +** +** SELECT a+b AS x, c+d AS y FROM t1 ORDER BY a+b; +** +** Function calls are checked to make sure that the function is +** defined and that the correct number of arguments are specified. +** If the function is an aggregate function, then the pNC->hasAgg is +** set and the opcode is changed from TK_FUNCTION to TK_AGG_FUNCTION. +** If an expression contains aggregate functions then the EP_Agg +** property on the expression is set. +** +** An error message is left in pParse if anything is amiss. The number +** if errors is returned. +*/ +int sqlite3ResolveExprNames( + NameContext *pNC, /* Namespace to resolve expressions in. */ + Expr *pExpr /* The expression to be analyzed. */ +){ + int savedHasAgg; + Walker w; + + if( pExpr==0 ) return 0; +#if SQLITE_MAX_EXPR_DEPTH>0 + { + Parse *pParse = pNC->pParse; + if( sqlite3ExprCheckHeight(pParse, pExpr->nHeight+pNC->pParse->nHeight) ){ + return 1; + } + pParse->nHeight += pExpr->nHeight; + } +#endif + savedHasAgg = pNC->hasAgg; + pNC->hasAgg = 0; + w.xExprCallback = resolveExprStep; + w.xSelectCallback = resolveSelectStep; + w.pParse = pNC->pParse; + w.u.pNC = pNC; + sqlite3WalkExpr(&w, pExpr); +#if SQLITE_MAX_EXPR_DEPTH>0 + pNC->pParse->nHeight -= pExpr->nHeight; +#endif + if( pNC->nErr>0 || w.pParse->nErr>0 ){ + ExprSetProperty(pExpr, EP_Error); + } + if( pNC->hasAgg ){ + ExprSetProperty(pExpr, EP_Agg); + }else if( savedHasAgg ){ + pNC->hasAgg = 1; + } + return ExprHasProperty(pExpr, EP_Error); +} + + +/* +** Resolve all names in all expressions of a SELECT and in all +** decendents of the SELECT, including compounds off of p->pPrior, +** subqueries in expressions, and subqueries used as FROM clause +** terms. +** +** See sqlite3ResolveExprNames() for a description of the kinds of +** transformations that occur. +** +** All SELECT statements should have been expanded using +** sqlite3SelectExpand() prior to invoking this routine. +*/ +void sqlite3ResolveSelectNames( + Parse *pParse, /* The parser context */ + Select *p, /* The SELECT statement being coded. */ + NameContext *pOuterNC /* Name context for parent SELECT statement */ +){ + Walker w; + + assert( p!=0 ); + w.xExprCallback = resolveExprStep; + w.xSelectCallback = resolveSelectStep; + w.pParse = pParse; + w.u.pNC = pOuterNC; + sqlite3WalkSelect(&w, p); +} diff --git a/scalos/libraries/sqlite/src/rowset.c b/scalos/libraries/sqlite/src/rowset.c new file mode 100644 index 000000000..d84bb93ab --- /dev/null +++ b/scalos/libraries/sqlite/src/rowset.c @@ -0,0 +1,422 @@ +/* +** 2008 December 3 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This module implements an object we call a "RowSet". +** +** The RowSet object is a collection of rowids. Rowids +** are inserted into the RowSet in an arbitrary order. Inserts +** can be intermixed with tests to see if a given rowid has been +** previously inserted into the RowSet. +** +** After all inserts are finished, it is possible to extract the +** elements of the RowSet in sorted order. Once this extraction +** process has started, no new elements may be inserted. +** +** Hence, the primitive operations for a RowSet are: +** +** CREATE +** INSERT +** TEST +** SMALLEST +** DESTROY +** +** The CREATE and DESTROY primitives are the constructor and destructor, +** obviously. The INSERT primitive adds a new element to the RowSet. +** TEST checks to see if an element is already in the RowSet. SMALLEST +** extracts the least value from the RowSet. +** +** The INSERT primitive might allocate additional memory. Memory is +** allocated in chunks so most INSERTs do no allocation. There is an +** upper bound on the size of allocated memory. No memory is freed +** until DESTROY. +** +** The TEST primitive includes a "batch" number. The TEST primitive +** will only see elements that were inserted before the last change +** in the batch number. In other words, if an INSERT occurs between +** two TESTs where the TESTs have the same batch nubmer, then the +** value added by the INSERT will not be visible to the second TEST. +** The initial batch number is zero, so if the very first TEST contains +** a non-zero batch number, it will see all prior INSERTs. +** +** No INSERTs may occurs after a SMALLEST. An assertion will fail if +** that is attempted. +** +** The cost of an INSERT is roughly constant. (Sometime new memory +** has to be allocated on an INSERT.) The cost of a TEST with a new +** batch number is O(NlogN) where N is the number of elements in the RowSet. +** The cost of a TEST using the same batch number is O(logN). The cost +** of the first SMALLEST is O(NlogN). Second and subsequent SMALLEST +** primitives are constant time. The cost of DESTROY is O(N). +** +** There is an added cost of O(N) when switching between TEST and +** SMALLEST primitives. +*/ +#include "sqliteInt.h" + + +/* +** Target size for allocation chunks. +*/ +#define ROWSET_ALLOCATION_SIZE 1024 + +/* +** The number of rowset entries per allocation chunk. +*/ +#define ROWSET_ENTRY_PER_CHUNK \ + ((ROWSET_ALLOCATION_SIZE-8)/sizeof(struct RowSetEntry)) + +/* +** Each entry in a RowSet is an instance of the following object. +*/ +struct RowSetEntry { + i64 v; /* ROWID value for this entry */ + struct RowSetEntry *pRight; /* Right subtree (larger entries) or list */ + struct RowSetEntry *pLeft; /* Left subtree (smaller entries) */ +}; + +/* +** RowSetEntry objects are allocated in large chunks (instances of the +** following structure) to reduce memory allocation overhead. The +** chunks are kept on a linked list so that they can be deallocated +** when the RowSet is destroyed. +*/ +struct RowSetChunk { + struct RowSetChunk *pNextChunk; /* Next chunk on list of them all */ + struct RowSetEntry aEntry[ROWSET_ENTRY_PER_CHUNK]; /* Allocated entries */ +}; + +/* +** A RowSet in an instance of the following structure. +** +** A typedef of this structure if found in sqliteInt.h. +*/ +struct RowSet { + struct RowSetChunk *pChunk; /* List of all chunk allocations */ + sqlite3 *db; /* The database connection */ + struct RowSetEntry *pEntry; /* List of entries using pRight */ + struct RowSetEntry *pLast; /* Last entry on the pEntry list */ + struct RowSetEntry *pFresh; /* Source of new entry objects */ + struct RowSetEntry *pTree; /* Binary tree of entries */ + u16 nFresh; /* Number of objects on pFresh */ + u8 isSorted; /* True if pEntry is sorted */ + u8 iBatch; /* Current insert batch */ +}; + +/* +** Turn bulk memory into a RowSet object. N bytes of memory +** are available at pSpace. The db pointer is used as a memory context +** for any subsequent allocations that need to occur. +** Return a pointer to the new RowSet object. +** +** It must be the case that N is sufficient to make a Rowset. If not +** an assertion fault occurs. +** +** If N is larger than the minimum, use the surplus as an initial +** allocation of entries available to be filled. +*/ +RowSet *sqlite3RowSetInit(sqlite3 *db, void *pSpace, unsigned int N){ + RowSet *p; + assert( N >= ROUND8(sizeof(*p)) ); + p = pSpace; + p->pChunk = 0; + p->db = db; + p->pEntry = 0; + p->pLast = 0; + p->pTree = 0; + p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p); + p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry)); + p->isSorted = 1; + p->iBatch = 0; + return p; +} + +/* +** Deallocate all chunks from a RowSet. This frees all memory that +** the RowSet has allocated over its lifetime. This routine is +** the destructor for the RowSet. +*/ +void sqlite3RowSetClear(RowSet *p){ + struct RowSetChunk *pChunk, *pNextChunk; + for(pChunk=p->pChunk; pChunk; pChunk = pNextChunk){ + pNextChunk = pChunk->pNextChunk; + sqlite3DbFree(p->db, pChunk); + } + p->pChunk = 0; + p->nFresh = 0; + p->pEntry = 0; + p->pLast = 0; + p->pTree = 0; + p->isSorted = 1; +} + +/* +** Insert a new value into a RowSet. +** +** The mallocFailed flag of the database connection is set if a +** memory allocation fails. +*/ +void sqlite3RowSetInsert(RowSet *p, i64 rowid){ + struct RowSetEntry *pEntry; /* The new entry */ + struct RowSetEntry *pLast; /* The last prior entry */ + assert( p!=0 ); + if( p->nFresh==0 ){ + struct RowSetChunk *pNew; + pNew = sqlite3DbMallocRaw(p->db, sizeof(*pNew)); + if( pNew==0 ){ + return; + } + pNew->pNextChunk = p->pChunk; + p->pChunk = pNew; + p->pFresh = pNew->aEntry; + p->nFresh = ROWSET_ENTRY_PER_CHUNK; + } + pEntry = p->pFresh++; + p->nFresh--; + pEntry->v = rowid; + pEntry->pRight = 0; + pLast = p->pLast; + if( pLast ){ + if( p->isSorted && rowid<=pLast->v ){ + p->isSorted = 0; + } + pLast->pRight = pEntry; + }else{ + assert( p->pEntry==0 ); /* Fires if INSERT after SMALLEST */ + p->pEntry = pEntry; + } + p->pLast = pEntry; +} + +/* +** Merge two lists of RowSetEntry objects. Remove duplicates. +** +** The input lists are connected via pRight pointers and are +** assumed to each already be in sorted order. +*/ +static struct RowSetEntry *rowSetMerge( + struct RowSetEntry *pA, /* First sorted list to be merged */ + struct RowSetEntry *pB /* Second sorted list to be merged */ +){ + struct RowSetEntry head; + struct RowSetEntry *pTail; + + pTail = &head; + while( pA && pB ){ + assert( pA->pRight==0 || pA->v<=pA->pRight->v ); + assert( pB->pRight==0 || pB->v<=pB->pRight->v ); + if( pA->vv ){ + pTail->pRight = pA; + pA = pA->pRight; + pTail = pTail->pRight; + }else if( pB->vv ){ + pTail->pRight = pB; + pB = pB->pRight; + pTail = pTail->pRight; + }else{ + pA = pA->pRight; + } + } + if( pA ){ + assert( pA->pRight==0 || pA->v<=pA->pRight->v ); + pTail->pRight = pA; + }else{ + assert( pB==0 || pB->pRight==0 || pB->v<=pB->pRight->v ); + pTail->pRight = pB; + } + return head.pRight; +} + +/* +** Sort all elements on the pEntry list of the RowSet into ascending order. +*/ +static void rowSetSort(RowSet *p){ + unsigned int i; + struct RowSetEntry *pEntry; + struct RowSetEntry *aBucket[40]; + + assert( p->isSorted==0 ); + memset(aBucket, 0, sizeof(aBucket)); + while( p->pEntry ){ + pEntry = p->pEntry; + p->pEntry = pEntry->pRight; + pEntry->pRight = 0; + for(i=0; aBucket[i]; i++){ + pEntry = rowSetMerge(aBucket[i], pEntry); + aBucket[i] = 0; + } + aBucket[i] = pEntry; + } + pEntry = 0; + for(i=0; ipEntry = pEntry; + p->pLast = 0; + p->isSorted = 1; +} + + +/* +** The input, pIn, is a binary tree (or subtree) of RowSetEntry objects. +** Convert this tree into a linked list connected by the pRight pointers +** and return pointers to the first and last elements of the new list. +*/ +static void rowSetTreeToList( + struct RowSetEntry *pIn, /* Root of the input tree */ + struct RowSetEntry **ppFirst, /* Write head of the output list here */ + struct RowSetEntry **ppLast /* Write tail of the output list here */ +){ + assert( pIn!=0 ); + if( pIn->pLeft ){ + struct RowSetEntry *p; + rowSetTreeToList(pIn->pLeft, ppFirst, &p); + p->pRight = pIn; + }else{ + *ppFirst = pIn; + } + if( pIn->pRight ){ + rowSetTreeToList(pIn->pRight, &pIn->pRight, ppLast); + }else{ + *ppLast = pIn; + } + assert( (*ppLast)->pRight==0 ); +} + + +/* +** Convert a sorted list of elements (connected by pRight) into a binary +** tree with depth of iDepth. A depth of 1 means the tree contains a single +** node taken from the head of *ppList. A depth of 2 means a tree with +** three nodes. And so forth. +** +** Use as many entries from the input list as required and update the +** *ppList to point to the unused elements of the list. If the input +** list contains too few elements, then construct an incomplete tree +** and leave *ppList set to NULL. +** +** Return a pointer to the root of the constructed binary tree. +*/ +static struct RowSetEntry *rowSetNDeepTree( + struct RowSetEntry **ppList, + int iDepth +){ + struct RowSetEntry *p; /* Root of the new tree */ + struct RowSetEntry *pLeft; /* Left subtree */ + if( *ppList==0 ){ + return 0; + } + if( iDepth==1 ){ + p = *ppList; + *ppList = p->pRight; + p->pLeft = p->pRight = 0; + return p; + } + pLeft = rowSetNDeepTree(ppList, iDepth-1); + p = *ppList; + if( p==0 ){ + return pLeft; + } + p->pLeft = pLeft; + *ppList = p->pRight; + p->pRight = rowSetNDeepTree(ppList, iDepth-1); + return p; +} + +/* +** Convert a sorted list of elements into a binary tree. Make the tree +** as deep as it needs to be in order to contain the entire list. +*/ +static struct RowSetEntry *rowSetListToTree(struct RowSetEntry *pList){ + int iDepth; /* Depth of the tree so far */ + struct RowSetEntry *p; /* Current tree root */ + struct RowSetEntry *pLeft; /* Left subtree */ + + assert( pList!=0 ); + p = pList; + pList = p->pRight; + p->pLeft = p->pRight = 0; + for(iDepth=1; pList; iDepth++){ + pLeft = p; + p = pList; + pList = p->pRight; + p->pLeft = pLeft; + p->pRight = rowSetNDeepTree(&pList, iDepth); + } + return p; +} + +/* +** Convert the list in p->pEntry into a sorted list if it is not +** sorted already. If there is a binary tree on p->pTree, then +** convert it into a list too and merge it into the p->pEntry list. +*/ +static void rowSetToList(RowSet *p){ + if( !p->isSorted ){ + rowSetSort(p); + } + if( p->pTree ){ + struct RowSetEntry *pHead, *pTail; + rowSetTreeToList(p->pTree, &pHead, &pTail); + p->pTree = 0; + p->pEntry = rowSetMerge(p->pEntry, pHead); + } +} + +/* +** Extract the smallest element from the RowSet. +** Write the element into *pRowid. Return 1 on success. Return +** 0 if the RowSet is already empty. +** +** After this routine has been called, the sqlite3RowSetInsert() +** routine may not be called again. +*/ +int sqlite3RowSetNext(RowSet *p, i64 *pRowid){ + rowSetToList(p); + if( p->pEntry ){ + *pRowid = p->pEntry->v; + p->pEntry = p->pEntry->pRight; + if( p->pEntry==0 ){ + sqlite3RowSetClear(p); + } + return 1; + }else{ + return 0; + } +} + +/* +** Check to see if element iRowid was inserted into the the rowset as +** part of any insert batch prior to iBatch. Return 1 or 0. +*/ +int sqlite3RowSetTest(RowSet *pRowSet, u8 iBatch, sqlite3_int64 iRowid){ + struct RowSetEntry *p; + if( iBatch!=pRowSet->iBatch ){ + if( pRowSet->pEntry ){ + rowSetToList(pRowSet); + pRowSet->pTree = rowSetListToTree(pRowSet->pEntry); + pRowSet->pEntry = 0; + pRowSet->pLast = 0; + } + pRowSet->iBatch = iBatch; + } + p = pRowSet->pTree; + while( p ){ + if( p->vpRight; + }else if( p->v>iRowid ){ + p = p->pLeft; + }else{ + return 1; + } + } + return 0; +} diff --git a/scalos/libraries/sqlite/src/select.c b/scalos/libraries/sqlite/src/select.c new file mode 100644 index 000000000..188050e8d --- /dev/null +++ b/scalos/libraries/sqlite/src/select.c @@ -0,0 +1,4598 @@ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains C code routines that are called by the parser +** to handle SELECT statements in SQLite. +*/ +#include "sqliteInt.h" + + +/* +** Delete all the content of a Select structure but do not deallocate +** the select structure itself. +*/ +static void clearSelect(sqlite3 *db, Select *p){ + sqlite3ExprListDelete(db, p->pEList); + sqlite3SrcListDelete(db, p->pSrc); + sqlite3ExprDelete(db, p->pWhere); + sqlite3ExprListDelete(db, p->pGroupBy); + sqlite3ExprDelete(db, p->pHaving); + sqlite3ExprListDelete(db, p->pOrderBy); + sqlite3SelectDelete(db, p->pPrior); + sqlite3ExprDelete(db, p->pLimit); + sqlite3ExprDelete(db, p->pOffset); +} + +/* +** Initialize a SelectDest structure. +*/ +void sqlite3SelectDestInit(SelectDest *pDest, int eDest, int iParm){ + pDest->eDest = (u8)eDest; + pDest->iParm = iParm; + pDest->affinity = 0; + pDest->iMem = 0; + pDest->nMem = 0; +} + + +/* +** Allocate a new Select structure and return a pointer to that +** structure. +*/ +Select *sqlite3SelectNew( + Parse *pParse, /* Parsing context */ + ExprList *pEList, /* which columns to include in the result */ + SrcList *pSrc, /* the FROM clause -- which tables to scan */ + Expr *pWhere, /* the WHERE clause */ + ExprList *pGroupBy, /* the GROUP BY clause */ + Expr *pHaving, /* the HAVING clause */ + ExprList *pOrderBy, /* the ORDER BY clause */ + int isDistinct, /* true if the DISTINCT keyword is present */ + Expr *pLimit, /* LIMIT value. NULL means not used */ + Expr *pOffset /* OFFSET value. NULL means no offset */ +){ + Select *pNew; + Select standin; + sqlite3 *db = pParse->db; + pNew = sqlite3DbMallocZero(db, sizeof(*pNew) ); + assert( db->mallocFailed || !pOffset || pLimit ); /* OFFSET implies LIMIT */ + if( pNew==0 ){ + assert( db->mallocFailed ); + pNew = &standin; + memset(pNew, 0, sizeof(*pNew)); + } + if( pEList==0 ){ + pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ALL,0)); + } + pNew->pEList = pEList; + pNew->pSrc = pSrc; + pNew->pWhere = pWhere; + pNew->pGroupBy = pGroupBy; + pNew->pHaving = pHaving; + pNew->pOrderBy = pOrderBy; + pNew->selFlags = isDistinct ? SF_Distinct : 0; + pNew->op = TK_SELECT; + pNew->pLimit = pLimit; + pNew->pOffset = pOffset; + assert( pOffset==0 || pLimit!=0 ); + pNew->addrOpenEphm[0] = -1; + pNew->addrOpenEphm[1] = -1; + pNew->addrOpenEphm[2] = -1; + if( db->mallocFailed ) { + clearSelect(db, pNew); + if( pNew!=&standin ) sqlite3DbFree(db, pNew); + pNew = 0; + }else{ + assert( pNew->pSrc!=0 || pParse->nErr>0 ); + } + assert( pNew!=&standin ); + return pNew; +} + +/* +** Delete the given Select structure and all of its substructures. +*/ +void sqlite3SelectDelete(sqlite3 *db, Select *p){ + if( p ){ + clearSelect(db, p); + sqlite3DbFree(db, p); + } +} + +/* +** Given 1 to 3 identifiers preceeding the JOIN keyword, determine the +** type of join. Return an integer constant that expresses that type +** in terms of the following bit values: +** +** JT_INNER +** JT_CROSS +** JT_OUTER +** JT_NATURAL +** JT_LEFT +** JT_RIGHT +** +** A full outer join is the combination of JT_LEFT and JT_RIGHT. +** +** If an illegal or unsupported join type is seen, then still return +** a join type, but put an error in the pParse structure. +*/ +int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){ + int jointype = 0; + Token *apAll[3]; + Token *p; + /* 0123456789 123456789 123456789 123 */ + static const char zKeyText[] = "naturaleftouterightfullinnercross"; + static const struct { + u8 i; /* Beginning of keyword text in zKeyText[] */ + u8 nChar; /* Length of the keyword in characters */ + u8 code; /* Join type mask */ + } aKeyword[] = { + /* natural */ { 0, 7, JT_NATURAL }, + /* left */ { 6, 4, JT_LEFT|JT_OUTER }, + /* outer */ { 10, 5, JT_OUTER }, + /* right */ { 14, 5, JT_RIGHT|JT_OUTER }, + /* full */ { 19, 4, JT_LEFT|JT_RIGHT|JT_OUTER }, + /* inner */ { 23, 5, JT_INNER }, + /* cross */ { 28, 5, JT_INNER|JT_CROSS }, + }; + int i, j; + apAll[0] = pA; + apAll[1] = pB; + apAll[2] = pC; + for(i=0; i<3 && apAll[i]; i++){ + p = apAll[i]; + for(j=0; jn==aKeyword[j].nChar + && sqlite3StrNICmp((char*)p->z, &zKeyText[aKeyword[j].i], p->n)==0 ){ + jointype |= aKeyword[j].code; + break; + } + } + testcase( j==0 || j==1 || j==2 || j==3 || j==4 || j==5 || j==6 ); + if( j>=ArraySize(aKeyword) ){ + jointype |= JT_ERROR; + break; + } + } + if( + (jointype & (JT_INNER|JT_OUTER))==(JT_INNER|JT_OUTER) || + (jointype & JT_ERROR)!=0 + ){ + const char *zSp = " "; + assert( pB!=0 ); + if( pC==0 ){ zSp++; } + sqlite3ErrorMsg(pParse, "unknown or unsupported join type: " + "%T %T%s%T", pA, pB, zSp, pC); + jointype = JT_INNER; + }else if( (jointype & JT_OUTER)!=0 + && (jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ){ + sqlite3ErrorMsg(pParse, + "RIGHT and FULL OUTER JOINs are not currently supported"); + jointype = JT_INNER; + } + return jointype; +} + +/* +** Return the index of a column in a table. Return -1 if the column +** is not contained in the table. +*/ +static int columnIndex(Table *pTab, const char *zCol){ + int i; + for(i=0; inCol; i++){ + if( sqlite3StrICmp(pTab->aCol[i].zName, zCol)==0 ) return i; + } + return -1; +} + +/* +** Search the first N tables in pSrc, from left to right, looking for a +** table that has a column named zCol. +** +** When found, set *piTab and *piCol to the table index and column index +** of the matching column and return TRUE. +** +** If not found, return FALSE. +*/ +static int tableAndColumnIndex( + SrcList *pSrc, /* Array of tables to search */ + int N, /* Number of tables in pSrc->a[] to search */ + const char *zCol, /* Name of the column we are looking for */ + int *piTab, /* Write index of pSrc->a[] here */ + int *piCol /* Write index of pSrc->a[*piTab].pTab->aCol[] here */ +){ + int i; /* For looping over tables in pSrc */ + int iCol; /* Index of column matching zCol */ + + assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */ + for(i=0; ia[i].pTab, zCol); + if( iCol>=0 ){ + if( piTab ){ + *piTab = i; + *piCol = iCol; + } + return 1; + } + } + return 0; +} + +/* +** This function is used to add terms implied by JOIN syntax to the +** WHERE clause expression of a SELECT statement. The new term, which +** is ANDed with the existing WHERE clause, is of the form: +** +** (tab1.col1 = tab2.col2) +** +** where tab1 is the iSrc'th table in SrcList pSrc and tab2 is the +** (iSrc+1)'th. Column col1 is column iColLeft of tab1, and col2 is +** column iColRight of tab2. +*/ +static void addWhereTerm( + Parse *pParse, /* Parsing context */ + SrcList *pSrc, /* List of tables in FROM clause */ + int iLeft, /* Index of first table to join in pSrc */ + int iColLeft, /* Index of column in first table */ + int iRight, /* Index of second table in pSrc */ + int iColRight, /* Index of column in second table */ + int isOuterJoin, /* True if this is an OUTER join */ + Expr **ppWhere /* IN/OUT: The WHERE clause to add to */ +){ + sqlite3 *db = pParse->db; + Expr *pE1; + Expr *pE2; + Expr *pEq; + + assert( iLeftnSrc>iRight ); + assert( pSrc->a[iLeft].pTab ); + assert( pSrc->a[iRight].pTab ); + + pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iColLeft); + pE2 = sqlite3CreateColumnExpr(db, pSrc, iRight, iColRight); + + pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2, 0); + if( pEq && isOuterJoin ){ + ExprSetProperty(pEq, EP_FromJoin); + assert( !ExprHasAnyProperty(pEq, EP_TokenOnly|EP_Reduced) ); + ExprSetIrreducible(pEq); + pEq->iRightJoinTable = (i16)pE2->iTable; + } + *ppWhere = sqlite3ExprAnd(db, *ppWhere, pEq); +} + +/* +** Set the EP_FromJoin property on all terms of the given expression. +** And set the Expr.iRightJoinTable to iTable for every term in the +** expression. +** +** The EP_FromJoin property is used on terms of an expression to tell +** the LEFT OUTER JOIN processing logic that this term is part of the +** join restriction specified in the ON or USING clause and not a part +** of the more general WHERE clause. These terms are moved over to the +** WHERE clause during join processing but we need to remember that they +** originated in the ON or USING clause. +** +** The Expr.iRightJoinTable tells the WHERE clause processing that the +** expression depends on table iRightJoinTable even if that table is not +** explicitly mentioned in the expression. That information is needed +** for cases like this: +** +** SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.b AND t1.x=5 +** +** The where clause needs to defer the handling of the t1.x=5 +** term until after the t2 loop of the join. In that way, a +** NULL t2 row will be inserted whenever t1.x!=5. If we do not +** defer the handling of t1.x=5, it will be processed immediately +** after the t1 loop and rows with t1.x!=5 will never appear in +** the output, which is incorrect. +*/ +static void setJoinExpr(Expr *p, int iTable){ + while( p ){ + ExprSetProperty(p, EP_FromJoin); + assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) ); + ExprSetIrreducible(p); + p->iRightJoinTable = (i16)iTable; + setJoinExpr(p->pLeft, iTable); + p = p->pRight; + } +} + +/* +** This routine processes the join information for a SELECT statement. +** ON and USING clauses are converted into extra terms of the WHERE clause. +** NATURAL joins also create extra WHERE clause terms. +** +** The terms of a FROM clause are contained in the Select.pSrc structure. +** The left most table is the first entry in Select.pSrc. The right-most +** table is the last entry. The join operator is held in the entry to +** the left. Thus entry 0 contains the join operator for the join between +** entries 0 and 1. Any ON or USING clauses associated with the join are +** also attached to the left entry. +** +** This routine returns the number of errors encountered. +*/ +static int sqliteProcessJoin(Parse *pParse, Select *p){ + SrcList *pSrc; /* All tables in the FROM clause */ + int i, j; /* Loop counters */ + struct SrcList_item *pLeft; /* Left table being joined */ + struct SrcList_item *pRight; /* Right table being joined */ + + pSrc = p->pSrc; + pLeft = &pSrc->a[0]; + pRight = &pLeft[1]; + for(i=0; inSrc-1; i++, pRight++, pLeft++){ + Table *pLeftTab = pLeft->pTab; + Table *pRightTab = pRight->pTab; + int isOuter; + + if( NEVER(pLeftTab==0 || pRightTab==0) ) continue; + isOuter = (pRight->jointype & JT_OUTER)!=0; + + /* When the NATURAL keyword is present, add WHERE clause terms for + ** every column that the two tables have in common. + */ + if( pRight->jointype & JT_NATURAL ){ + if( pRight->pOn || pRight->pUsing ){ + sqlite3ErrorMsg(pParse, "a NATURAL join may not have " + "an ON or USING clause", 0); + return 1; + } + for(j=0; jnCol; j++){ + char *zName; /* Name of column in the right table */ + int iLeft; /* Matching left table */ + int iLeftCol; /* Matching column in the left table */ + + zName = pRightTab->aCol[j].zName; + if( tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol) ){ + addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, j, + isOuter, &p->pWhere); + } + } + } + + /* Disallow both ON and USING clauses in the same join + */ + if( pRight->pOn && pRight->pUsing ){ + sqlite3ErrorMsg(pParse, "cannot have both ON and USING " + "clauses in the same join"); + return 1; + } + + /* Add the ON clause to the end of the WHERE clause, connected by + ** an AND operator. + */ + if( pRight->pOn ){ + if( isOuter ) setJoinExpr(pRight->pOn, pRight->iCursor); + p->pWhere = sqlite3ExprAnd(pParse->db, p->pWhere, pRight->pOn); + pRight->pOn = 0; + } + + /* Create extra terms on the WHERE clause for each column named + ** in the USING clause. Example: If the two tables to be joined are + ** A and B and the USING clause names X, Y, and Z, then add this + ** to the WHERE clause: A.X=B.X AND A.Y=B.Y AND A.Z=B.Z + ** Report an error if any column mentioned in the USING clause is + ** not contained in both tables to be joined. + */ + if( pRight->pUsing ){ + IdList *pList = pRight->pUsing; + for(j=0; jnId; j++){ + char *zName; /* Name of the term in the USING clause */ + int iLeft; /* Table on the left with matching column name */ + int iLeftCol; /* Column number of matching column on the left */ + int iRightCol; /* Column number of matching column on the right */ + + zName = pList->a[j].zName; + iRightCol = columnIndex(pRightTab, zName); + if( iRightCol<0 + || !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol) + ){ + sqlite3ErrorMsg(pParse, "cannot join using column %s - column " + "not present in both tables", zName); + return 1; + } + addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, iRightCol, + isOuter, &p->pWhere); + } + } + } + return 0; +} + +/* +** Insert code into "v" that will push the record on the top of the +** stack into the sorter. +*/ +static void pushOntoSorter( + Parse *pParse, /* Parser context */ + ExprList *pOrderBy, /* The ORDER BY clause */ + Select *pSelect, /* The whole SELECT statement */ + int regData /* Register holding data to be sorted */ +){ + Vdbe *v = pParse->pVdbe; + int nExpr = pOrderBy->nExpr; + int regBase = sqlite3GetTempRange(pParse, nExpr+2); + int regRecord = sqlite3GetTempReg(pParse); + int op; + sqlite3ExprCacheClear(pParse); + sqlite3ExprCodeExprList(pParse, pOrderBy, regBase, 0); + sqlite3VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, regBase+nExpr); + sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+1, 1); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nExpr + 2, regRecord); + if( pSelect->selFlags & SF_UseSorter ){ + op = OP_SorterInsert; + }else{ + op = OP_IdxInsert; + } + sqlite3VdbeAddOp2(v, op, pOrderBy->iECursor, regRecord); + sqlite3ReleaseTempReg(pParse, regRecord); + sqlite3ReleaseTempRange(pParse, regBase, nExpr+2); + if( pSelect->iLimit ){ + int addr1, addr2; + int iLimit; + if( pSelect->iOffset ){ + iLimit = pSelect->iOffset+1; + }else{ + iLimit = pSelect->iLimit; + } + addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, iLimit); + sqlite3VdbeAddOp2(v, OP_AddImm, iLimit, -1); + addr2 = sqlite3VdbeAddOp0(v, OP_Goto); + sqlite3VdbeJumpHere(v, addr1); + sqlite3VdbeAddOp1(v, OP_Last, pOrderBy->iECursor); + sqlite3VdbeAddOp1(v, OP_Delete, pOrderBy->iECursor); + sqlite3VdbeJumpHere(v, addr2); + } +} + +/* +** Add code to implement the OFFSET +*/ +static void codeOffset( + Vdbe *v, /* Generate code into this VM */ + Select *p, /* The SELECT statement being coded */ + int iContinue /* Jump here to skip the current record */ +){ + if( p->iOffset && iContinue!=0 ){ + int addr; + sqlite3VdbeAddOp2(v, OP_AddImm, p->iOffset, -1); + addr = sqlite3VdbeAddOp1(v, OP_IfNeg, p->iOffset); + sqlite3VdbeAddOp2(v, OP_Goto, 0, iContinue); + VdbeComment((v, "skip OFFSET records")); + sqlite3VdbeJumpHere(v, addr); + } +} + +/* +** Add code that will check to make sure the N registers starting at iMem +** form a distinct entry. iTab is a sorting index that holds previously +** seen combinations of the N values. A new entry is made in iTab +** if the current N values are new. +** +** A jump to addrRepeat is made and the N+1 values are popped from the +** stack if the top N elements are not distinct. +*/ +static void codeDistinct( + Parse *pParse, /* Parsing and code generating context */ + int iTab, /* A sorting index used to test for distinctness */ + int addrRepeat, /* Jump to here if not distinct */ + int N, /* Number of elements */ + int iMem /* First element */ +){ + Vdbe *v; + int r1; + + v = pParse->pVdbe; + r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, iMem, N); + sqlite3VdbeAddOp3(v, OP_MakeRecord, iMem, N, r1); + sqlite3VdbeAddOp2(v, OP_IdxInsert, iTab, r1); + sqlite3ReleaseTempReg(pParse, r1); +} + +#ifndef SQLITE_OMIT_SUBQUERY +/* +** Generate an error message when a SELECT is used within a subexpression +** (example: "a IN (SELECT * FROM table)") but it has more than 1 result +** column. We do this in a subroutine because the error used to occur +** in multiple places. (The error only occurs in one place now, but we +** retain the subroutine to minimize code disruption.) +*/ +static int checkForMultiColumnSelectError( + Parse *pParse, /* Parse context. */ + SelectDest *pDest, /* Destination of SELECT results */ + int nExpr /* Number of result columns returned by SELECT */ +){ + int eDest = pDest->eDest; + if( nExpr>1 && (eDest==SRT_Mem || eDest==SRT_Set) ){ + sqlite3ErrorMsg(pParse, "only a single result allowed for " + "a SELECT that is part of an expression"); + return 1; + }else{ + return 0; + } +} +#endif + +/* +** This routine generates the code for the inside of the inner loop +** of a SELECT. +** +** If srcTab and nColumn are both zero, then the pEList expressions +** are evaluated in order to get the data for this row. If nColumn>0 +** then data is pulled from srcTab and pEList is used only to get the +** datatypes for each column. +*/ +static void selectInnerLoop( + Parse *pParse, /* The parser context */ + Select *p, /* The complete select statement being coded */ + ExprList *pEList, /* List of values being extracted */ + int srcTab, /* Pull data from this table */ + int nColumn, /* Number of columns in the source table */ + ExprList *pOrderBy, /* If not NULL, sort results using this key */ + int distinct, /* If >=0, make sure results are distinct */ + SelectDest *pDest, /* How to dispose of the results */ + int iContinue, /* Jump here to continue with next row */ + int iBreak /* Jump here to break out of the inner loop */ +){ + Vdbe *v = pParse->pVdbe; + int i; + int hasDistinct; /* True if the DISTINCT keyword is present */ + int regResult; /* Start of memory holding result set */ + int eDest = pDest->eDest; /* How to dispose of results */ + int iParm = pDest->iParm; /* First argument to disposal method */ + int nResultCol; /* Number of result columns */ + + assert( v ); + if( NEVER(v==0) ) return; + assert( pEList!=0 ); + hasDistinct = distinct>=0; + if( pOrderBy==0 && !hasDistinct ){ + codeOffset(v, p, iContinue); + } + + /* Pull the requested columns. + */ + if( nColumn>0 ){ + nResultCol = nColumn; + }else{ + nResultCol = pEList->nExpr; + } + if( pDest->iMem==0 ){ + pDest->iMem = pParse->nMem+1; + pDest->nMem = nResultCol; + pParse->nMem += nResultCol; + }else{ + assert( pDest->nMem==nResultCol ); + } + regResult = pDest->iMem; + if( nColumn>0 ){ + for(i=0; inExpr==nColumn ); + codeDistinct(pParse, distinct, iContinue, nColumn, regResult); + if( pOrderBy==0 ){ + codeOffset(v, p, iContinue); + } + } + + switch( eDest ){ + /* In this mode, write each query result to the key of the temporary + ** table iParm. + */ +#ifndef SQLITE_OMIT_COMPOUND_SELECT + case SRT_Union: { + int r1; + r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1); + sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1); + sqlite3ReleaseTempReg(pParse, r1); + break; + } + + /* Construct a record from the query result, but instead of + ** saving that record, use it as a key to delete elements from + ** the temporary table iParm. + */ + case SRT_Except: { + sqlite3VdbeAddOp3(v, OP_IdxDelete, iParm, regResult, nColumn); + break; + } +#endif + + /* Store the result as data using a unique key. + */ + case SRT_Table: + case SRT_EphemTab: { + int r1 = sqlite3GetTempReg(pParse); + testcase( eDest==SRT_Table ); + testcase( eDest==SRT_EphemTab ); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1); + if( pOrderBy ){ + pushOntoSorter(pParse, pOrderBy, p, r1); + }else{ + int r2 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2); + sqlite3VdbeAddOp3(v, OP_Insert, iParm, r1, r2); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); + sqlite3ReleaseTempReg(pParse, r2); + } + sqlite3ReleaseTempReg(pParse, r1); + break; + } + +#ifndef SQLITE_OMIT_SUBQUERY + /* If we are creating a set for an "expr IN (SELECT ...)" construct, + ** then there should be a single item on the stack. Write this + ** item into the set table with bogus data. + */ + case SRT_Set: { + assert( nColumn==1 ); + p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affinity); + if( pOrderBy ){ + /* At first glance you would think we could optimize out the + ** ORDER BY in this case since the order of entries in the set + ** does not matter. But there might be a LIMIT clause, in which + ** case the order does matter */ + pushOntoSorter(pParse, pOrderBy, p, regResult); + }else{ + int r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, 1, r1, &p->affinity, 1); + sqlite3ExprCacheAffinityChange(pParse, regResult, 1); + sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1); + sqlite3ReleaseTempReg(pParse, r1); + } + break; + } + + /* If any row exist in the result set, record that fact and abort. + */ + case SRT_Exists: { + sqlite3VdbeAddOp2(v, OP_Integer, 1, iParm); + /* The LIMIT clause will terminate the loop for us */ + break; + } + + /* If this is a scalar select that is part of an expression, then + ** store the results in the appropriate memory cell and break out + ** of the scan loop. + */ + case SRT_Mem: { + assert( nColumn==1 ); + if( pOrderBy ){ + pushOntoSorter(pParse, pOrderBy, p, regResult); + }else{ + sqlite3ExprCodeMove(pParse, regResult, iParm, 1); + /* The LIMIT clause will jump out of the loop for us */ + } + break; + } +#endif /* #ifndef SQLITE_OMIT_SUBQUERY */ + + /* Send the data to the callback function or to a subroutine. In the + ** case of a subroutine, the subroutine itself is responsible for + ** popping the data from the stack. + */ + case SRT_Coroutine: + case SRT_Output: { + testcase( eDest==SRT_Coroutine ); + testcase( eDest==SRT_Output ); + if( pOrderBy ){ + int r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1); + pushOntoSorter(pParse, pOrderBy, p, r1); + sqlite3ReleaseTempReg(pParse, r1); + }else if( eDest==SRT_Coroutine ){ + sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm); + }else{ + sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nColumn); + sqlite3ExprCacheAffinityChange(pParse, regResult, nColumn); + } + break; + } + +#if !defined(SQLITE_OMIT_TRIGGER) + /* Discard the results. This is used for SELECT statements inside + ** the body of a TRIGGER. The purpose of such selects is to call + ** user-defined functions that have side effects. We do not care + ** about the actual results of the select. + */ + default: { + assert( eDest==SRT_Discard ); + break; + } +#endif + } + + /* Jump to the end of the loop if the LIMIT is reached. Except, if + ** there is a sorter, in which case the sorter has already limited + ** the output for us. + */ + if( pOrderBy==0 && p->iLimit ){ + sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1); + } +} + +/* +** Given an expression list, generate a KeyInfo structure that records +** the collating sequence for each expression in that expression list. +** +** If the ExprList is an ORDER BY or GROUP BY clause then the resulting +** KeyInfo structure is appropriate for initializing a virtual index to +** implement that clause. If the ExprList is the result set of a SELECT +** then the KeyInfo structure is appropriate for initializing a virtual +** index to implement a DISTINCT test. +** +** Space to hold the KeyInfo structure is obtain from malloc. The calling +** function is responsible for seeing that this structure is eventually +** freed. Add the KeyInfo structure to the P4 field of an opcode using +** P4_KEYINFO_HANDOFF is the usual way of dealing with this. +*/ +static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){ + sqlite3 *db = pParse->db; + int nExpr; + KeyInfo *pInfo; + struct ExprList_item *pItem; + int i; + + nExpr = pList->nExpr; + pInfo = sqlite3DbMallocZero(db, sizeof(*pInfo) + nExpr*(sizeof(CollSeq*)+1) ); + if( pInfo ){ + pInfo->aSortOrder = (u8*)&pInfo->aColl[nExpr]; + pInfo->nField = (u16)nExpr; + pInfo->enc = ENC(db); + pInfo->db = db; + for(i=0, pItem=pList->a; ipExpr); + if( !pColl ){ + pColl = db->pDfltColl; + } + pInfo->aColl[i] = pColl; + pInfo->aSortOrder[i] = pItem->sortOrder; + } + } + return pInfo; +} + +#ifndef SQLITE_OMIT_COMPOUND_SELECT +/* +** Name of the connection operator, used for error messages. +*/ +static const char *selectOpName(int id){ + char *z; + switch( id ){ + case TK_ALL: z = "UNION ALL"; break; + case TK_INTERSECT: z = "INTERSECT"; break; + case TK_EXCEPT: z = "EXCEPT"; break; + default: z = "UNION"; break; + } + return z; +} +#endif /* SQLITE_OMIT_COMPOUND_SELECT */ + +#ifndef SQLITE_OMIT_EXPLAIN +/* +** Unless an "EXPLAIN QUERY PLAN" command is being processed, this function +** is a no-op. Otherwise, it adds a single row of output to the EQP result, +** where the caption is of the form: +** +** "USE TEMP B-TREE FOR xxx" +** +** where xxx is one of "DISTINCT", "ORDER BY" or "GROUP BY". Exactly which +** is determined by the zUsage argument. +*/ +static void explainTempTable(Parse *pParse, const char *zUsage){ + if( pParse->explain==2 ){ + Vdbe *v = pParse->pVdbe; + char *zMsg = sqlite3MPrintf(pParse->db, "USE TEMP B-TREE FOR %s", zUsage); + sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC); + } +} + +/* +** Assign expression b to lvalue a. A second, no-op, version of this macro +** is provided when SQLITE_OMIT_EXPLAIN is defined. This allows the code +** in sqlite3Select() to assign values to structure member variables that +** only exist if SQLITE_OMIT_EXPLAIN is not defined without polluting the +** code with #ifndef directives. +*/ +# define explainSetInteger(a, b) a = b + +#else +/* No-op versions of the explainXXX() functions and macros. */ +# define explainTempTable(y,z) +# define explainSetInteger(y,z) +#endif + +#if !defined(SQLITE_OMIT_EXPLAIN) && !defined(SQLITE_OMIT_COMPOUND_SELECT) +/* +** Unless an "EXPLAIN QUERY PLAN" command is being processed, this function +** is a no-op. Otherwise, it adds a single row of output to the EQP result, +** where the caption is of one of the two forms: +** +** "COMPOSITE SUBQUERIES iSub1 and iSub2 (op)" +** "COMPOSITE SUBQUERIES iSub1 and iSub2 USING TEMP B-TREE (op)" +** +** where iSub1 and iSub2 are the integers passed as the corresponding +** function parameters, and op is the text representation of the parameter +** of the same name. The parameter "op" must be one of TK_UNION, TK_EXCEPT, +** TK_INTERSECT or TK_ALL. The first form is used if argument bUseTmp is +** false, or the second form if it is true. +*/ +static void explainComposite( + Parse *pParse, /* Parse context */ + int op, /* One of TK_UNION, TK_EXCEPT etc. */ + int iSub1, /* Subquery id 1 */ + int iSub2, /* Subquery id 2 */ + int bUseTmp /* True if a temp table was used */ +){ + assert( op==TK_UNION || op==TK_EXCEPT || op==TK_INTERSECT || op==TK_ALL ); + if( pParse->explain==2 ){ + Vdbe *v = pParse->pVdbe; + char *zMsg = sqlite3MPrintf( + pParse->db, "COMPOUND SUBQUERIES %d AND %d %s(%s)", iSub1, iSub2, + bUseTmp?"USING TEMP B-TREE ":"", selectOpName(op) + ); + sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC); + } +} +#else +/* No-op versions of the explainXXX() functions and macros. */ +# define explainComposite(v,w,x,y,z) +#endif + +/* +** If the inner loop was generated using a non-null pOrderBy argument, +** then the results were placed in a sorter. After the loop is terminated +** we need to run the sorter and output the results. The following +** routine generates the code needed to do that. +*/ +static void generateSortTail( + Parse *pParse, /* Parsing context */ + Select *p, /* The SELECT statement */ + Vdbe *v, /* Generate code into this VDBE */ + int nColumn, /* Number of columns of data */ + SelectDest *pDest /* Write the sorted results here */ +){ + int addrBreak = sqlite3VdbeMakeLabel(v); /* Jump here to exit loop */ + int addrContinue = sqlite3VdbeMakeLabel(v); /* Jump here for next cycle */ + int addr; + int iTab; + int pseudoTab = 0; + ExprList *pOrderBy = p->pOrderBy; + + int eDest = pDest->eDest; + int iParm = pDest->iParm; + + int regRow; + int regRowid; + + iTab = pOrderBy->iECursor; + regRow = sqlite3GetTempReg(pParse); + if( eDest==SRT_Output || eDest==SRT_Coroutine ){ + pseudoTab = pParse->nTab++; + sqlite3VdbeAddOp3(v, OP_OpenPseudo, pseudoTab, regRow, nColumn); + regRowid = 0; + }else{ + regRowid = sqlite3GetTempReg(pParse); + } + if( p->selFlags & SF_UseSorter ){ + int regSortOut = ++pParse->nMem; + int ptab2 = pParse->nTab++; + sqlite3VdbeAddOp3(v, OP_OpenPseudo, ptab2, regSortOut, pOrderBy->nExpr+2); + addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak); + codeOffset(v, p, addrContinue); + sqlite3VdbeAddOp2(v, OP_SorterData, iTab, regSortOut); + sqlite3VdbeAddOp3(v, OP_Column, ptab2, pOrderBy->nExpr+1, regRow); + sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE); + }else{ + addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); + codeOffset(v, p, addrContinue); + sqlite3VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr+1, regRow); + } + switch( eDest ){ + case SRT_Table: + case SRT_EphemTab: { + testcase( eDest==SRT_Table ); + testcase( eDest==SRT_EphemTab ); + sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid); + sqlite3VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); + break; + } +#ifndef SQLITE_OMIT_SUBQUERY + case SRT_Set: { + assert( nColumn==1 ); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRowid, &p->affinity, 1); + sqlite3ExprCacheAffinityChange(pParse, regRow, 1); + sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, regRowid); + break; + } + case SRT_Mem: { + assert( nColumn==1 ); + sqlite3ExprCodeMove(pParse, regRow, iParm, 1); + /* The LIMIT clause will terminate the loop for us */ + break; + } +#endif + default: { + int i; + assert( eDest==SRT_Output || eDest==SRT_Coroutine ); + testcase( eDest==SRT_Output ); + testcase( eDest==SRT_Coroutine ); + for(i=0; iiMem+i ); + sqlite3VdbeAddOp3(v, OP_Column, pseudoTab, i, pDest->iMem+i); + if( i==0 ){ + sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE); + } + } + if( eDest==SRT_Output ){ + sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iMem, nColumn); + sqlite3ExprCacheAffinityChange(pParse, pDest->iMem, nColumn); + }else{ + sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm); + } + break; + } + } + sqlite3ReleaseTempReg(pParse, regRow); + sqlite3ReleaseTempReg(pParse, regRowid); + + /* The bottom of the loop + */ + sqlite3VdbeResolveLabel(v, addrContinue); + if( p->selFlags & SF_UseSorter ){ + sqlite3VdbeAddOp2(v, OP_SorterNext, iTab, addr); + }else{ + sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); + } + sqlite3VdbeResolveLabel(v, addrBreak); + if( eDest==SRT_Output || eDest==SRT_Coroutine ){ + sqlite3VdbeAddOp2(v, OP_Close, pseudoTab, 0); + } +} + +/* +** Return a pointer to a string containing the 'declaration type' of the +** expression pExpr. The string may be treated as static by the caller. +** +** The declaration type is the exact datatype definition extracted from the +** original CREATE TABLE statement if the expression is a column. The +** declaration type for a ROWID field is INTEGER. Exactly when an expression +** is considered a column can be complex in the presence of subqueries. The +** result-set expression in all of the following SELECT statements is +** considered a column by this function. +** +** SELECT col FROM tbl; +** SELECT (SELECT col FROM tbl; +** SELECT (SELECT col FROM tbl); +** SELECT abc FROM (SELECT col AS abc FROM tbl); +** +** The declaration type for any expression other than a column is NULL. +*/ +static const char *columnType( + NameContext *pNC, + Expr *pExpr, + const char **pzOriginDb, + const char **pzOriginTab, + const char **pzOriginCol +){ + char const *zType = 0; + char const *zOriginDb = 0; + char const *zOriginTab = 0; + char const *zOriginCol = 0; + int j; + if( NEVER(pExpr==0) || pNC->pSrcList==0 ) return 0; + + switch( pExpr->op ){ + case TK_AGG_COLUMN: + case TK_COLUMN: { + /* The expression is a column. Locate the table the column is being + ** extracted from in NameContext.pSrcList. This table may be real + ** database table or a subquery. + */ + Table *pTab = 0; /* Table structure column is extracted from */ + Select *pS = 0; /* Select the column is extracted from */ + int iCol = pExpr->iColumn; /* Index of column in pTab */ + testcase( pExpr->op==TK_AGG_COLUMN ); + testcase( pExpr->op==TK_COLUMN ); + while( pNC && !pTab ){ + SrcList *pTabList = pNC->pSrcList; + for(j=0;jnSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++); + if( jnSrc ){ + pTab = pTabList->a[j].pTab; + pS = pTabList->a[j].pSelect; + }else{ + pNC = pNC->pNext; + } + } + + if( pTab==0 ){ + /* At one time, code such as "SELECT new.x" within a trigger would + ** cause this condition to run. Since then, we have restructured how + ** trigger code is generated and so this condition is no longer + ** possible. However, it can still be true for statements like + ** the following: + ** + ** CREATE TABLE t1(col INTEGER); + ** SELECT (SELECT t1.col) FROM FROM t1; + ** + ** when columnType() is called on the expression "t1.col" in the + ** sub-select. In this case, set the column type to NULL, even + ** though it should really be "INTEGER". + ** + ** This is not a problem, as the column type of "t1.col" is never + ** used. When columnType() is called on the expression + ** "(SELECT t1.col)", the correct type is returned (see the TK_SELECT + ** branch below. */ + break; + } + + assert( pTab && pExpr->pTab==pTab ); + if( pS ){ + /* The "table" is actually a sub-select or a view in the FROM clause + ** of the SELECT statement. Return the declaration type and origin + ** data for the result-set column of the sub-select. + */ + if( iCol>=0 && ALWAYS(iColpEList->nExpr) ){ + /* If iCol is less than zero, then the expression requests the + ** rowid of the sub-select or view. This expression is legal (see + ** test case misc2.2.2) - it always evaluates to NULL. + */ + NameContext sNC; + Expr *p = pS->pEList->a[iCol].pExpr; + sNC.pSrcList = pS->pSrc; + sNC.pNext = pNC; + sNC.pParse = pNC->pParse; + zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol); + } + }else if( ALWAYS(pTab->pSchema) ){ + /* A real table */ + assert( !pS ); + if( iCol<0 ) iCol = pTab->iPKey; + assert( iCol==-1 || (iCol>=0 && iColnCol) ); + if( iCol<0 ){ + zType = "INTEGER"; + zOriginCol = "rowid"; + }else{ + zType = pTab->aCol[iCol].zType; + zOriginCol = pTab->aCol[iCol].zName; + } + zOriginTab = pTab->zName; + if( pNC->pParse ){ + int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema); + zOriginDb = pNC->pParse->db->aDb[iDb].zName; + } + } + break; + } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_SELECT: { + /* The expression is a sub-select. Return the declaration type and + ** origin info for the single column in the result set of the SELECT + ** statement. + */ + NameContext sNC; + Select *pS = pExpr->x.pSelect; + Expr *p = pS->pEList->a[0].pExpr; + assert( ExprHasProperty(pExpr, EP_xIsSelect) ); + sNC.pSrcList = pS->pSrc; + sNC.pNext = pNC; + sNC.pParse = pNC->pParse; + zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol); + break; + } +#endif + } + + if( pzOriginDb ){ + assert( pzOriginTab && pzOriginCol ); + *pzOriginDb = zOriginDb; + *pzOriginTab = zOriginTab; + *pzOriginCol = zOriginCol; + } + return zType; +} + +/* +** Generate code that will tell the VDBE the declaration types of columns +** in the result set. +*/ +static void generateColumnTypes( + Parse *pParse, /* Parser context */ + SrcList *pTabList, /* List of tables */ + ExprList *pEList /* Expressions defining the result set */ +){ +#ifndef SQLITE_OMIT_DECLTYPE + Vdbe *v = pParse->pVdbe; + int i; + NameContext sNC; + sNC.pSrcList = pTabList; + sNC.pParse = pParse; + for(i=0; inExpr; i++){ + Expr *p = pEList->a[i].pExpr; + const char *zType; +#ifdef SQLITE_ENABLE_COLUMN_METADATA + const char *zOrigDb = 0; + const char *zOrigTab = 0; + const char *zOrigCol = 0; + zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol); + + /* The vdbe must make its own copy of the column-type and other + ** column specific strings, in case the schema is reset before this + ** virtual machine is deleted. + */ + sqlite3VdbeSetColName(v, i, COLNAME_DATABASE, zOrigDb, SQLITE_TRANSIENT); + sqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, SQLITE_TRANSIENT); + sqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, SQLITE_TRANSIENT); +#else + zType = columnType(&sNC, p, 0, 0, 0); +#endif + sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT); + } +#endif /* SQLITE_OMIT_DECLTYPE */ +} + +/* +** Generate code that will tell the VDBE the names of columns +** in the result set. This information is used to provide the +** azCol[] values in the callback. +*/ +static void generateColumnNames( + Parse *pParse, /* Parser context */ + SrcList *pTabList, /* List of tables */ + ExprList *pEList /* Expressions defining the result set */ +){ + Vdbe *v = pParse->pVdbe; + int i, j; + sqlite3 *db = pParse->db; + int fullNames, shortNames; + +#ifndef SQLITE_OMIT_EXPLAIN + /* If this is an EXPLAIN, skip this step */ + if( pParse->explain ){ + return; + } +#endif + + if( pParse->colNamesSet || NEVER(v==0) || db->mallocFailed ) return; + pParse->colNamesSet = 1; + fullNames = (db->flags & SQLITE_FullColNames)!=0; + shortNames = (db->flags & SQLITE_ShortColNames)!=0; + sqlite3VdbeSetNumCols(v, pEList->nExpr); + for(i=0; inExpr; i++){ + Expr *p; + p = pEList->a[i].pExpr; + if( NEVER(p==0) ) continue; + if( pEList->a[i].zName ){ + char *zName = pEList->a[i].zName; + sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT); + }else if( (p->op==TK_COLUMN || p->op==TK_AGG_COLUMN) && pTabList ){ + Table *pTab; + char *zCol; + int iCol = p->iColumn; + for(j=0; ALWAYS(jnSrc); j++){ + if( pTabList->a[j].iCursor==p->iTable ) break; + } + assert( jnSrc ); + pTab = pTabList->a[j].pTab; + if( iCol<0 ) iCol = pTab->iPKey; + assert( iCol==-1 || (iCol>=0 && iColnCol) ); + if( iCol<0 ){ + zCol = "rowid"; + }else{ + zCol = pTab->aCol[iCol].zName; + } + if( !shortNames && !fullNames ){ + sqlite3VdbeSetColName(v, i, COLNAME_NAME, + sqlite3DbStrDup(db, pEList->a[i].zSpan), SQLITE_DYNAMIC); + }else if( fullNames ){ + char *zName = 0; + zName = sqlite3MPrintf(db, "%s.%s", pTab->zName, zCol); + sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_DYNAMIC); + }else{ + sqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, SQLITE_TRANSIENT); + } + }else{ + sqlite3VdbeSetColName(v, i, COLNAME_NAME, + sqlite3DbStrDup(db, pEList->a[i].zSpan), SQLITE_DYNAMIC); + } + } + generateColumnTypes(pParse, pTabList, pEList); +} + +/* +** Given a an expression list (which is really the list of expressions +** that form the result set of a SELECT statement) compute appropriate +** column names for a table that would hold the expression list. +** +** All column names will be unique. +** +** Only the column names are computed. Column.zType, Column.zColl, +** and other fields of Column are zeroed. +** +** Return SQLITE_OK on success. If a memory allocation error occurs, +** store NULL in *paCol and 0 in *pnCol and return SQLITE_NOMEM. +*/ +static int selectColumnsFromExprList( + Parse *pParse, /* Parsing context */ + ExprList *pEList, /* Expr list from which to derive column names */ + int *pnCol, /* Write the number of columns here */ + Column **paCol /* Write the new column list here */ +){ + sqlite3 *db = pParse->db; /* Database connection */ + int i, j; /* Loop counters */ + int cnt; /* Index added to make the name unique */ + Column *aCol, *pCol; /* For looping over result columns */ + int nCol; /* Number of columns in the result set */ + Expr *p; /* Expression for a single result column */ + char *zName; /* Column name */ + int nName; /* Size of name in zName[] */ + + *pnCol = nCol = pEList->nExpr; + aCol = *paCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol); + if( aCol==0 ) return SQLITE_NOMEM; + for(i=0, pCol=aCol; ia[i].pExpr; + assert( p->pRight==0 || ExprHasProperty(p->pRight, EP_IntValue) + || p->pRight->u.zToken==0 || p->pRight->u.zToken[0]!=0 ); + if( (zName = pEList->a[i].zName)!=0 ){ + /* If the column contains an "AS " phrase, use as the name */ + zName = sqlite3DbStrDup(db, zName); + }else{ + Expr *pColExpr = p; /* The expression that is the result column name */ + Table *pTab; /* Table associated with this expression */ + while( pColExpr->op==TK_DOT ){ + pColExpr = pColExpr->pRight; + assert( pColExpr!=0 ); + } + if( pColExpr->op==TK_COLUMN && ALWAYS(pColExpr->pTab!=0) ){ + /* For columns use the column name name */ + int iCol = pColExpr->iColumn; + pTab = pColExpr->pTab; + if( iCol<0 ) iCol = pTab->iPKey; + zName = sqlite3MPrintf(db, "%s", + iCol>=0 ? pTab->aCol[iCol].zName : "rowid"); + }else if( pColExpr->op==TK_ID ){ + assert( !ExprHasProperty(pColExpr, EP_IntValue) ); + zName = sqlite3MPrintf(db, "%s", pColExpr->u.zToken); + }else{ + /* Use the original text of the column expression as its name */ + zName = sqlite3MPrintf(db, "%s", pEList->a[i].zSpan); + } + } + if( db->mallocFailed ){ + sqlite3DbFree(db, zName); + break; + } + + /* Make sure the column name is unique. If the name is not unique, + ** append a integer to the name so that it becomes unique. + */ + nName = sqlite3Strlen30(zName); + for(j=cnt=0; jzName = zName; + } + if( db->mallocFailed ){ + for(j=0; jdb; + NameContext sNC; + Column *pCol; + CollSeq *pColl; + int i; + Expr *p; + struct ExprList_item *a; + + assert( pSelect!=0 ); + assert( (pSelect->selFlags & SF_Resolved)!=0 ); + assert( nCol==pSelect->pEList->nExpr || db->mallocFailed ); + if( db->mallocFailed ) return; + memset(&sNC, 0, sizeof(sNC)); + sNC.pSrcList = pSelect->pSrc; + a = pSelect->pEList->a; + for(i=0, pCol=aCol; izType = sqlite3DbStrDup(db, columnType(&sNC, p, 0, 0, 0)); + pCol->affinity = sqlite3ExprAffinity(p); + if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_NONE; + pColl = sqlite3ExprCollSeq(pParse, p); + if( pColl ){ + pCol->zColl = sqlite3DbStrDup(db, pColl->zName); + } + } +} + +/* +** Given a SELECT statement, generate a Table structure that describes +** the result set of that SELECT. +*/ +Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){ + Table *pTab; + sqlite3 *db = pParse->db; + int savedFlags; + + savedFlags = db->flags; + db->flags &= ~SQLITE_FullColNames; + db->flags |= SQLITE_ShortColNames; + sqlite3SelectPrep(pParse, pSelect, 0); + if( pParse->nErr ) return 0; + while( pSelect->pPrior ) pSelect = pSelect->pPrior; + db->flags = savedFlags; + pTab = sqlite3DbMallocZero(db, sizeof(Table) ); + if( pTab==0 ){ + return 0; + } + /* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside + ** is disabled */ + assert( db->lookaside.bEnabled==0 ); + pTab->nRef = 1; + pTab->zName = 0; + pTab->nRowEst = 1000000; + selectColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol); + selectAddColumnTypeAndCollation(pParse, pTab->nCol, pTab->aCol, pSelect); + pTab->iPKey = -1; + if( db->mallocFailed ){ + sqlite3DeleteTable(db, pTab); + return 0; + } + return pTab; +} + +/* +** Get a VDBE for the given parser context. Create a new one if necessary. +** If an error occurs, return NULL and leave a message in pParse. +*/ +Vdbe *sqlite3GetVdbe(Parse *pParse){ + Vdbe *v = pParse->pVdbe; + if( v==0 ){ + v = pParse->pVdbe = sqlite3VdbeCreate(pParse->db); +#ifndef SQLITE_OMIT_TRACE + if( v ){ + sqlite3VdbeAddOp0(v, OP_Trace); + } +#endif + } + return v; +} + + +/* +** Compute the iLimit and iOffset fields of the SELECT based on the +** pLimit and pOffset expressions. pLimit and pOffset hold the expressions +** that appear in the original SQL statement after the LIMIT and OFFSET +** keywords. Or NULL if those keywords are omitted. iLimit and iOffset +** are the integer memory register numbers for counters used to compute +** the limit and offset. If there is no limit and/or offset, then +** iLimit and iOffset are negative. +** +** This routine changes the values of iLimit and iOffset only if +** a limit or offset is defined by pLimit and pOffset. iLimit and +** iOffset should have been preset to appropriate default values +** (usually but not always -1) prior to calling this routine. +** Only if pLimit!=0 or pOffset!=0 do the limit registers get +** redefined. The UNION ALL operator uses this property to force +** the reuse of the same limit and offset registers across multiple +** SELECT statements. +*/ +static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ + Vdbe *v = 0; + int iLimit = 0; + int iOffset; + int addr1, n; + if( p->iLimit ) return; + + /* + ** "LIMIT -1" always shows all rows. There is some + ** contraversy about what the correct behavior should be. + ** The current implementation interprets "LIMIT 0" to mean + ** no rows. + */ + sqlite3ExprCacheClear(pParse); + assert( p->pOffset==0 || p->pLimit!=0 ); + if( p->pLimit ){ + p->iLimit = iLimit = ++pParse->nMem; + v = sqlite3GetVdbe(pParse); + if( NEVER(v==0) ) return; /* VDBE should have already been allocated */ + if( sqlite3ExprIsInteger(p->pLimit, &n) ){ + sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit); + VdbeComment((v, "LIMIT counter")); + if( n==0 ){ + sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak); + }else{ + if( p->nSelectRow > (double)n ) p->nSelectRow = (double)n; + } + }else{ + sqlite3ExprCode(pParse, p->pLimit, iLimit); + sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); + VdbeComment((v, "LIMIT counter")); + sqlite3VdbeAddOp2(v, OP_IfZero, iLimit, iBreak); + } + if( p->pOffset ){ + p->iOffset = iOffset = ++pParse->nMem; + pParse->nMem++; /* Allocate an extra register for limit+offset */ + sqlite3ExprCode(pParse, p->pOffset, iOffset); + sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); + VdbeComment((v, "OFFSET counter")); + addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iOffset); + sqlite3VdbeAddOp2(v, OP_Integer, 0, iOffset); + sqlite3VdbeJumpHere(v, addr1); + sqlite3VdbeAddOp3(v, OP_Add, iLimit, iOffset, iOffset+1); + VdbeComment((v, "LIMIT+OFFSET")); + addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iLimit); + sqlite3VdbeAddOp2(v, OP_Integer, -1, iOffset+1); + sqlite3VdbeJumpHere(v, addr1); + } + } +} + +#ifndef SQLITE_OMIT_COMPOUND_SELECT +/* +** Return the appropriate collating sequence for the iCol-th column of +** the result set for the compound-select statement "p". Return NULL if +** the column has no default collating sequence. +** +** The collating sequence for the compound select is taken from the +** left-most term of the select that has a collating sequence. +*/ +static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){ + CollSeq *pRet; + if( p->pPrior ){ + pRet = multiSelectCollSeq(pParse, p->pPrior, iCol); + }else{ + pRet = 0; + } + assert( iCol>=0 ); + if( pRet==0 && iColpEList->nExpr ){ + pRet = sqlite3ExprCollSeq(pParse, p->pEList->a[iCol].pExpr); + } + return pRet; +} +#endif /* SQLITE_OMIT_COMPOUND_SELECT */ + +/* Forward reference */ +static int multiSelectOrderBy( + Parse *pParse, /* Parsing context */ + Select *p, /* The right-most of SELECTs to be coded */ + SelectDest *pDest /* What to do with query results */ +); + + +#ifndef SQLITE_OMIT_COMPOUND_SELECT +/* +** This routine is called to process a compound query form from +** two or more separate queries using UNION, UNION ALL, EXCEPT, or +** INTERSECT +** +** "p" points to the right-most of the two queries. the query on the +** left is p->pPrior. The left query could also be a compound query +** in which case this routine will be called recursively. +** +** The results of the total query are to be written into a destination +** of type eDest with parameter iParm. +** +** Example 1: Consider a three-way compound SQL statement. +** +** SELECT a FROM t1 UNION SELECT b FROM t2 UNION SELECT c FROM t3 +** +** This statement is parsed up as follows: +** +** SELECT c FROM t3 +** | +** `-----> SELECT b FROM t2 +** | +** `------> SELECT a FROM t1 +** +** The arrows in the diagram above represent the Select.pPrior pointer. +** So if this routine is called with p equal to the t3 query, then +** pPrior will be the t2 query. p->op will be TK_UNION in this case. +** +** Notice that because of the way SQLite parses compound SELECTs, the +** individual selects always group from left to right. +*/ +static int multiSelect( + Parse *pParse, /* Parsing context */ + Select *p, /* The right-most of SELECTs to be coded */ + SelectDest *pDest /* What to do with query results */ +){ + int rc = SQLITE_OK; /* Success code from a subroutine */ + Select *pPrior; /* Another SELECT immediately to our left */ + Vdbe *v; /* Generate code to this VDBE */ + SelectDest dest; /* Alternative data destination */ + Select *pDelete = 0; /* Chain of simple selects to delete */ + sqlite3 *db; /* Database connection */ +#ifndef SQLITE_OMIT_EXPLAIN + int iSub1; /* EQP id of left-hand query */ + int iSub2; /* EQP id of right-hand query */ +#endif + + /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs. Only + ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT. + */ + assert( p && p->pPrior ); /* Calling function guarantees this much */ + db = pParse->db; + pPrior = p->pPrior; + assert( pPrior->pRightmost!=pPrior ); + assert( pPrior->pRightmost==p->pRightmost ); + dest = *pDest; + if( pPrior->pOrderBy ){ + sqlite3ErrorMsg(pParse,"ORDER BY clause should come after %s not before", + selectOpName(p->op)); + rc = 1; + goto multi_select_end; + } + if( pPrior->pLimit ){ + sqlite3ErrorMsg(pParse,"LIMIT clause should come after %s not before", + selectOpName(p->op)); + rc = 1; + goto multi_select_end; + } + + v = sqlite3GetVdbe(pParse); + assert( v!=0 ); /* The VDBE already created by calling function */ + + /* Create the destination temporary table if necessary + */ + if( dest.eDest==SRT_EphemTab ){ + assert( p->pEList ); + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iParm, p->pEList->nExpr); + sqlite3VdbeChangeP5(v, BTREE_UNORDERED); + dest.eDest = SRT_Table; + } + + /* Make sure all SELECTs in the statement have the same number of elements + ** in their result sets. + */ + assert( p->pEList && pPrior->pEList ); + if( p->pEList->nExpr!=pPrior->pEList->nExpr ){ + sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s" + " do not have the same number of result columns", selectOpName(p->op)); + rc = 1; + goto multi_select_end; + } + + /* Compound SELECTs that have an ORDER BY clause are handled separately. + */ + if( p->pOrderBy ){ + return multiSelectOrderBy(pParse, p, pDest); + } + + /* Generate code for the left and right SELECT statements. + */ + switch( p->op ){ + case TK_ALL: { + int addr = 0; + int nLimit; + assert( !pPrior->pLimit ); + pPrior->pLimit = p->pLimit; + pPrior->pOffset = p->pOffset; + explainSetInteger(iSub1, pParse->iNextSelectId); + rc = sqlite3Select(pParse, pPrior, &dest); + p->pLimit = 0; + p->pOffset = 0; + if( rc ){ + goto multi_select_end; + } + p->pPrior = 0; + p->iLimit = pPrior->iLimit; + p->iOffset = pPrior->iOffset; + if( p->iLimit ){ + addr = sqlite3VdbeAddOp1(v, OP_IfZero, p->iLimit); + VdbeComment((v, "Jump ahead if LIMIT reached")); + } + explainSetInteger(iSub2, pParse->iNextSelectId); + rc = sqlite3Select(pParse, p, &dest); + testcase( rc!=SQLITE_OK ); + pDelete = p->pPrior; + p->pPrior = pPrior; + p->nSelectRow += pPrior->nSelectRow; + if( pPrior->pLimit + && sqlite3ExprIsInteger(pPrior->pLimit, &nLimit) + && p->nSelectRow > (double)nLimit + ){ + p->nSelectRow = (double)nLimit; + } + if( addr ){ + sqlite3VdbeJumpHere(v, addr); + } + break; + } + case TK_EXCEPT: + case TK_UNION: { + int unionTab; /* Cursor number of the temporary table holding result */ + u8 op = 0; /* One of the SRT_ operations to apply to self */ + int priorOp; /* The SRT_ operation to apply to prior selects */ + Expr *pLimit, *pOffset; /* Saved values of p->nLimit and p->nOffset */ + int addr; + SelectDest uniondest; + + testcase( p->op==TK_EXCEPT ); + testcase( p->op==TK_UNION ); + priorOp = SRT_Union; + if( dest.eDest==priorOp && ALWAYS(!p->pLimit &&!p->pOffset) ){ + /* We can reuse a temporary table generated by a SELECT to our + ** right. + */ + assert( p->pRightmost!=p ); /* Can only happen for leftward elements + ** of a 3-way or more compound */ + assert( p->pLimit==0 ); /* Not allowed on leftward elements */ + assert( p->pOffset==0 ); /* Not allowed on leftward elements */ + unionTab = dest.iParm; + }else{ + /* We will need to create our own temporary table to hold the + ** intermediate results. + */ + unionTab = pParse->nTab++; + assert( p->pOrderBy==0 ); + addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0); + assert( p->addrOpenEphm[0] == -1 ); + p->addrOpenEphm[0] = addr; + p->pRightmost->selFlags |= SF_UsesEphemeral; + assert( p->pEList ); + } + + /* Code the SELECT statements to our left + */ + assert( !pPrior->pOrderBy ); + sqlite3SelectDestInit(&uniondest, priorOp, unionTab); + explainSetInteger(iSub1, pParse->iNextSelectId); + rc = sqlite3Select(pParse, pPrior, &uniondest); + if( rc ){ + goto multi_select_end; + } + + /* Code the current SELECT statement + */ + if( p->op==TK_EXCEPT ){ + op = SRT_Except; + }else{ + assert( p->op==TK_UNION ); + op = SRT_Union; + } + p->pPrior = 0; + pLimit = p->pLimit; + p->pLimit = 0; + pOffset = p->pOffset; + p->pOffset = 0; + uniondest.eDest = op; + explainSetInteger(iSub2, pParse->iNextSelectId); + rc = sqlite3Select(pParse, p, &uniondest); + testcase( rc!=SQLITE_OK ); + /* Query flattening in sqlite3Select() might refill p->pOrderBy. + ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */ + sqlite3ExprListDelete(db, p->pOrderBy); + pDelete = p->pPrior; + p->pPrior = pPrior; + p->pOrderBy = 0; + if( p->op==TK_UNION ) p->nSelectRow += pPrior->nSelectRow; + sqlite3ExprDelete(db, p->pLimit); + p->pLimit = pLimit; + p->pOffset = pOffset; + p->iLimit = 0; + p->iOffset = 0; + + /* Convert the data in the temporary table into whatever form + ** it is that we currently need. + */ + assert( unionTab==dest.iParm || dest.eDest!=priorOp ); + if( dest.eDest!=priorOp ){ + int iCont, iBreak, iStart; + assert( p->pEList ); + if( dest.eDest==SRT_Output ){ + Select *pFirst = p; + while( pFirst->pPrior ) pFirst = pFirst->pPrior; + generateColumnNames(pParse, 0, pFirst->pEList); + } + iBreak = sqlite3VdbeMakeLabel(v); + iCont = sqlite3VdbeMakeLabel(v); + computeLimitRegisters(pParse, p, iBreak); + sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); + iStart = sqlite3VdbeCurrentAddr(v); + selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr, + 0, -1, &dest, iCont, iBreak); + sqlite3VdbeResolveLabel(v, iCont); + sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); + sqlite3VdbeResolveLabel(v, iBreak); + sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0); + } + break; + } + default: assert( p->op==TK_INTERSECT ); { + int tab1, tab2; + int iCont, iBreak, iStart; + Expr *pLimit, *pOffset; + int addr; + SelectDest intersectdest; + int r1; + + /* INTERSECT is different from the others since it requires + ** two temporary tables. Hence it has its own case. Begin + ** by allocating the tables we will need. + */ + tab1 = pParse->nTab++; + tab2 = pParse->nTab++; + assert( p->pOrderBy==0 ); + + addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0); + assert( p->addrOpenEphm[0] == -1 ); + p->addrOpenEphm[0] = addr; + p->pRightmost->selFlags |= SF_UsesEphemeral; + assert( p->pEList ); + + /* Code the SELECTs to our left into temporary table "tab1". + */ + sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1); + explainSetInteger(iSub1, pParse->iNextSelectId); + rc = sqlite3Select(pParse, pPrior, &intersectdest); + if( rc ){ + goto multi_select_end; + } + + /* Code the current SELECT into temporary table "tab2" + */ + addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0); + assert( p->addrOpenEphm[1] == -1 ); + p->addrOpenEphm[1] = addr; + p->pPrior = 0; + pLimit = p->pLimit; + p->pLimit = 0; + pOffset = p->pOffset; + p->pOffset = 0; + intersectdest.iParm = tab2; + explainSetInteger(iSub2, pParse->iNextSelectId); + rc = sqlite3Select(pParse, p, &intersectdest); + testcase( rc!=SQLITE_OK ); + pDelete = p->pPrior; + p->pPrior = pPrior; + if( p->nSelectRow>pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow; + sqlite3ExprDelete(db, p->pLimit); + p->pLimit = pLimit; + p->pOffset = pOffset; + + /* Generate code to take the intersection of the two temporary + ** tables. + */ + assert( p->pEList ); + if( dest.eDest==SRT_Output ){ + Select *pFirst = p; + while( pFirst->pPrior ) pFirst = pFirst->pPrior; + generateColumnNames(pParse, 0, pFirst->pEList); + } + iBreak = sqlite3VdbeMakeLabel(v); + iCont = sqlite3VdbeMakeLabel(v); + computeLimitRegisters(pParse, p, iBreak); + sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); + r1 = sqlite3GetTempReg(pParse); + iStart = sqlite3VdbeAddOp2(v, OP_RowKey, tab1, r1); + sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); + sqlite3ReleaseTempReg(pParse, r1); + selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr, + 0, -1, &dest, iCont, iBreak); + sqlite3VdbeResolveLabel(v, iCont); + sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); + sqlite3VdbeResolveLabel(v, iBreak); + sqlite3VdbeAddOp2(v, OP_Close, tab2, 0); + sqlite3VdbeAddOp2(v, OP_Close, tab1, 0); + break; + } + } + + explainComposite(pParse, p->op, iSub1, iSub2, p->op!=TK_ALL); + + /* Compute collating sequences used by + ** temporary tables needed to implement the compound select. + ** Attach the KeyInfo structure to all temporary tables. + ** + ** This section is run by the right-most SELECT statement only. + ** SELECT statements to the left always skip this part. The right-most + ** SELECT might also skip this part if it has no ORDER BY clause and + ** no temp tables are required. + */ + if( p->selFlags & SF_UsesEphemeral ){ + int i; /* Loop counter */ + KeyInfo *pKeyInfo; /* Collating sequence for the result set */ + Select *pLoop; /* For looping through SELECT statements */ + CollSeq **apColl; /* For looping through pKeyInfo->aColl[] */ + int nCol; /* Number of columns in result set */ + + assert( p->pRightmost==p ); + nCol = p->pEList->nExpr; + pKeyInfo = sqlite3DbMallocZero(db, + sizeof(*pKeyInfo)+nCol*(sizeof(CollSeq*) + 1)); + if( !pKeyInfo ){ + rc = SQLITE_NOMEM; + goto multi_select_end; + } + + pKeyInfo->enc = ENC(db); + pKeyInfo->nField = (u16)nCol; + + for(i=0, apColl=pKeyInfo->aColl; ipDfltColl; + } + } + + for(pLoop=p; pLoop; pLoop=pLoop->pPrior){ + for(i=0; i<2; i++){ + int addr = pLoop->addrOpenEphm[i]; + if( addr<0 ){ + /* If [0] is unused then [1] is also unused. So we can + ** always safely abort as soon as the first unused slot is found */ + assert( pLoop->addrOpenEphm[1]<0 ); + break; + } + sqlite3VdbeChangeP2(v, addr, nCol); + sqlite3VdbeChangeP4(v, addr, (char*)pKeyInfo, P4_KEYINFO); + pLoop->addrOpenEphm[i] = -1; + } + } + sqlite3DbFree(db, pKeyInfo); + } + +multi_select_end: + pDest->iMem = dest.iMem; + pDest->nMem = dest.nMem; + sqlite3SelectDelete(db, pDelete); + return rc; +} +#endif /* SQLITE_OMIT_COMPOUND_SELECT */ + +/* +** Code an output subroutine for a coroutine implementation of a +** SELECT statment. +** +** The data to be output is contained in pIn->iMem. There are +** pIn->nMem columns to be output. pDest is where the output should +** be sent. +** +** regReturn is the number of the register holding the subroutine +** return address. +** +** If regPrev>0 then it is the first register in a vector that +** records the previous output. mem[regPrev] is a flag that is false +** if there has been no previous output. If regPrev>0 then code is +** generated to suppress duplicates. pKeyInfo is used for comparing +** keys. +** +** If the LIMIT found in p->iLimit is reached, jump immediately to +** iBreak. +*/ +static int generateOutputSubroutine( + Parse *pParse, /* Parsing context */ + Select *p, /* The SELECT statement */ + SelectDest *pIn, /* Coroutine supplying data */ + SelectDest *pDest, /* Where to send the data */ + int regReturn, /* The return address register */ + int regPrev, /* Previous result register. No uniqueness if 0 */ + KeyInfo *pKeyInfo, /* For comparing with previous entry */ + int p4type, /* The p4 type for pKeyInfo */ + int iBreak /* Jump here if we hit the LIMIT */ +){ + Vdbe *v = pParse->pVdbe; + int iContinue; + int addr; + + addr = sqlite3VdbeCurrentAddr(v); + iContinue = sqlite3VdbeMakeLabel(v); + + /* Suppress duplicates for UNION, EXCEPT, and INTERSECT + */ + if( regPrev ){ + int j1, j2; + j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); + j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iMem, regPrev+1, pIn->nMem, + (char*)pKeyInfo, p4type); + sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2); + sqlite3VdbeJumpHere(v, j1); + sqlite3ExprCodeCopy(pParse, pIn->iMem, regPrev+1, pIn->nMem); + sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev); + } + if( pParse->db->mallocFailed ) return 0; + + /* Suppress the the first OFFSET entries if there is an OFFSET clause + */ + codeOffset(v, p, iContinue); + + switch( pDest->eDest ){ + /* Store the result as data using a unique key. + */ + case SRT_Table: + case SRT_EphemTab: { + int r1 = sqlite3GetTempReg(pParse); + int r2 = sqlite3GetTempReg(pParse); + testcase( pDest->eDest==SRT_Table ); + testcase( pDest->eDest==SRT_EphemTab ); + sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iMem, pIn->nMem, r1); + sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iParm, r2); + sqlite3VdbeAddOp3(v, OP_Insert, pDest->iParm, r1, r2); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); + sqlite3ReleaseTempReg(pParse, r2); + sqlite3ReleaseTempReg(pParse, r1); + break; + } + +#ifndef SQLITE_OMIT_SUBQUERY + /* If we are creating a set for an "expr IN (SELECT ...)" construct, + ** then there should be a single item on the stack. Write this + ** item into the set table with bogus data. + */ + case SRT_Set: { + int r1; + assert( pIn->nMem==1 ); + p->affinity = + sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affinity); + r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iMem, 1, r1, &p->affinity, 1); + sqlite3ExprCacheAffinityChange(pParse, pIn->iMem, 1); + sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iParm, r1); + sqlite3ReleaseTempReg(pParse, r1); + break; + } + +#if 0 /* Never occurs on an ORDER BY query */ + /* If any row exist in the result set, record that fact and abort. + */ + case SRT_Exists: { + sqlite3VdbeAddOp2(v, OP_Integer, 1, pDest->iParm); + /* The LIMIT clause will terminate the loop for us */ + break; + } +#endif + + /* If this is a scalar select that is part of an expression, then + ** store the results in the appropriate memory cell and break out + ** of the scan loop. + */ + case SRT_Mem: { + assert( pIn->nMem==1 ); + sqlite3ExprCodeMove(pParse, pIn->iMem, pDest->iParm, 1); + /* The LIMIT clause will jump out of the loop for us */ + break; + } +#endif /* #ifndef SQLITE_OMIT_SUBQUERY */ + + /* The results are stored in a sequence of registers + ** starting at pDest->iMem. Then the co-routine yields. + */ + case SRT_Coroutine: { + if( pDest->iMem==0 ){ + pDest->iMem = sqlite3GetTempRange(pParse, pIn->nMem); + pDest->nMem = pIn->nMem; + } + sqlite3ExprCodeMove(pParse, pIn->iMem, pDest->iMem, pDest->nMem); + sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm); + break; + } + + /* If none of the above, then the result destination must be + ** SRT_Output. This routine is never called with any other + ** destination other than the ones handled above or SRT_Output. + ** + ** For SRT_Output, results are stored in a sequence of registers. + ** Then the OP_ResultRow opcode is used to cause sqlite3_step() to + ** return the next row of result. + */ + default: { + assert( pDest->eDest==SRT_Output ); + sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iMem, pIn->nMem); + sqlite3ExprCacheAffinityChange(pParse, pIn->iMem, pIn->nMem); + break; + } + } + + /* Jump to the end of the loop if the LIMIT is reached. + */ + if( p->iLimit ){ + sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1); + } + + /* Generate the subroutine return + */ + sqlite3VdbeResolveLabel(v, iContinue); + sqlite3VdbeAddOp1(v, OP_Return, regReturn); + + return addr; +} + +/* +** Alternative compound select code generator for cases when there +** is an ORDER BY clause. +** +** We assume a query of the following form: +** +** ORDER BY +** +** is one of UNION ALL, UNION, EXCEPT, or INTERSECT. The idea +** is to code both and with the ORDER BY clause as +** co-routines. Then run the co-routines in parallel and merge the results +** into the output. In addition to the two coroutines (called selectA and +** selectB) there are 7 subroutines: +** +** outA: Move the output of the selectA coroutine into the output +** of the compound query. +** +** outB: Move the output of the selectB coroutine into the output +** of the compound query. (Only generated for UNION and +** UNION ALL. EXCEPT and INSERTSECT never output a row that +** appears only in B.) +** +** AltB: Called when there is data from both coroutines and AB. +** +** EofA: Called when data is exhausted from selectA. +** +** EofB: Called when data is exhausted from selectB. +** +** The implementation of the latter five subroutines depend on which +** is used: +** +** +** UNION ALL UNION EXCEPT INTERSECT +** ------------- ----------------- -------------- ----------------- +** AltB: outA, nextA outA, nextA outA, nextA nextA +** +** AeqB: outA, nextA nextA nextA outA, nextA +** +** AgtB: outB, nextB outB, nextB nextB nextB +** +** EofA: outB, nextB outB, nextB halt halt +** +** EofB: outA, nextA outA, nextA outA, nextA halt +** +** In the AltB, AeqB, and AgtB subroutines, an EOF on A following nextA +** causes an immediate jump to EofA and an EOF on B following nextB causes +** an immediate jump to EofB. Within EofA and EofB, and EOF on entry or +** following nextX causes a jump to the end of the select processing. +** +** Duplicate removal in the UNION, EXCEPT, and INTERSECT cases is handled +** within the output subroutine. The regPrev register set holds the previously +** output value. A comparison is made against this value and the output +** is skipped if the next results would be the same as the previous. +** +** The implementation plan is to implement the two coroutines and seven +** subroutines first, then put the control logic at the bottom. Like this: +** +** goto Init +** coA: coroutine for left query (A) +** coB: coroutine for right query (B) +** outA: output one row of A +** outB: output one row of B (UNION and UNION ALL only) +** EofA: ... +** EofB: ... +** AltB: ... +** AeqB: ... +** AgtB: ... +** Init: initialize coroutine registers +** yield coA +** if eof(A) goto EofA +** yield coB +** if eof(B) goto EofB +** Cmpr: Compare A, B +** Jump AltB, AeqB, AgtB +** End: ... +** +** We call AltB, AeqB, AgtB, EofA, and EofB "subroutines" but they are not +** actually called using Gosub and they do not Return. EofA and EofB loop +** until all data is exhausted then jump to the "end" labe. AltB, AeqB, +** and AgtB jump to either L2 or to one of EofA or EofB. +*/ +#ifndef SQLITE_OMIT_COMPOUND_SELECT +static int multiSelectOrderBy( + Parse *pParse, /* Parsing context */ + Select *p, /* The right-most of SELECTs to be coded */ + SelectDest *pDest /* What to do with query results */ +){ + int i, j; /* Loop counters */ + Select *pPrior; /* Another SELECT immediately to our left */ + Vdbe *v; /* Generate code to this VDBE */ + SelectDest destA; /* Destination for coroutine A */ + SelectDest destB; /* Destination for coroutine B */ + int regAddrA; /* Address register for select-A coroutine */ + int regEofA; /* Flag to indicate when select-A is complete */ + int regAddrB; /* Address register for select-B coroutine */ + int regEofB; /* Flag to indicate when select-B is complete */ + int addrSelectA; /* Address of the select-A coroutine */ + int addrSelectB; /* Address of the select-B coroutine */ + int regOutA; /* Address register for the output-A subroutine */ + int regOutB; /* Address register for the output-B subroutine */ + int addrOutA; /* Address of the output-A subroutine */ + int addrOutB = 0; /* Address of the output-B subroutine */ + int addrEofA; /* Address of the select-A-exhausted subroutine */ + int addrEofB; /* Address of the select-B-exhausted subroutine */ + int addrAltB; /* Address of the AB subroutine */ + int regLimitA; /* Limit register for select-A */ + int regLimitB; /* Limit register for select-A */ + int regPrev; /* A range of registers to hold previous output */ + int savedLimit; /* Saved value of p->iLimit */ + int savedOffset; /* Saved value of p->iOffset */ + int labelCmpr; /* Label for the start of the merge algorithm */ + int labelEnd; /* Label for the end of the overall SELECT stmt */ + int j1; /* Jump instructions that get retargetted */ + int op; /* One of TK_ALL, TK_UNION, TK_EXCEPT, TK_INTERSECT */ + KeyInfo *pKeyDup = 0; /* Comparison information for duplicate removal */ + KeyInfo *pKeyMerge; /* Comparison information for merging rows */ + sqlite3 *db; /* Database connection */ + ExprList *pOrderBy; /* The ORDER BY clause */ + int nOrderBy; /* Number of terms in the ORDER BY clause */ + int *aPermute; /* Mapping from ORDER BY terms to result set columns */ +#ifndef SQLITE_OMIT_EXPLAIN + int iSub1; /* EQP id of left-hand query */ + int iSub2; /* EQP id of right-hand query */ +#endif + + assert( p->pOrderBy!=0 ); + assert( pKeyDup==0 ); /* "Managed" code needs this. Ticket #3382. */ + db = pParse->db; + v = pParse->pVdbe; + assert( v!=0 ); /* Already thrown the error if VDBE alloc failed */ + labelEnd = sqlite3VdbeMakeLabel(v); + labelCmpr = sqlite3VdbeMakeLabel(v); + + + /* Patch up the ORDER BY clause + */ + op = p->op; + pPrior = p->pPrior; + assert( pPrior->pOrderBy==0 ); + pOrderBy = p->pOrderBy; + assert( pOrderBy ); + nOrderBy = pOrderBy->nExpr; + + /* For operators other than UNION ALL we have to make sure that + ** the ORDER BY clause covers every term of the result set. Add + ** terms to the ORDER BY clause as necessary. + */ + if( op!=TK_ALL ){ + for(i=1; db->mallocFailed==0 && i<=p->pEList->nExpr; i++){ + struct ExprList_item *pItem; + for(j=0, pItem=pOrderBy->a; jiOrderByCol>0 ); + if( pItem->iOrderByCol==i ) break; + } + if( j==nOrderBy ){ + Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0); + if( pNew==0 ) return SQLITE_NOMEM; + pNew->flags |= EP_IntValue; + pNew->u.iValue = i; + pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew); + pOrderBy->a[nOrderBy++].iOrderByCol = (u16)i; + } + } + } + + /* Compute the comparison permutation and keyinfo that is used with + ** the permutation used to determine if the next + ** row of results comes from selectA or selectB. Also add explicit + ** collations to the ORDER BY clause terms so that when the subqueries + ** to the right and the left are evaluated, they use the correct + ** collation. + */ + aPermute = sqlite3DbMallocRaw(db, sizeof(int)*nOrderBy); + if( aPermute ){ + struct ExprList_item *pItem; + for(i=0, pItem=pOrderBy->a; iiOrderByCol>0 && pItem->iOrderByCol<=p->pEList->nExpr ); + aPermute[i] = pItem->iOrderByCol - 1; + } + pKeyMerge = + sqlite3DbMallocRaw(db, sizeof(*pKeyMerge)+nOrderBy*(sizeof(CollSeq*)+1)); + if( pKeyMerge ){ + pKeyMerge->aSortOrder = (u8*)&pKeyMerge->aColl[nOrderBy]; + pKeyMerge->nField = (u16)nOrderBy; + pKeyMerge->enc = ENC(db); + for(i=0; ia[i].pExpr; + if( pTerm->flags & EP_ExpCollate ){ + pColl = pTerm->pColl; + }else{ + pColl = multiSelectCollSeq(pParse, p, aPermute[i]); + pTerm->flags |= EP_ExpCollate; + pTerm->pColl = pColl; + } + pKeyMerge->aColl[i] = pColl; + pKeyMerge->aSortOrder[i] = pOrderBy->a[i].sortOrder; + } + } + }else{ + pKeyMerge = 0; + } + + /* Reattach the ORDER BY clause to the query. + */ + p->pOrderBy = pOrderBy; + pPrior->pOrderBy = sqlite3ExprListDup(pParse->db, pOrderBy, 0); + + /* Allocate a range of temporary registers and the KeyInfo needed + ** for the logic that removes duplicate result rows when the + ** operator is UNION, EXCEPT, or INTERSECT (but not UNION ALL). + */ + if( op==TK_ALL ){ + regPrev = 0; + }else{ + int nExpr = p->pEList->nExpr; + assert( nOrderBy>=nExpr || db->mallocFailed ); + regPrev = sqlite3GetTempRange(pParse, nExpr+1); + sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev); + pKeyDup = sqlite3DbMallocZero(db, + sizeof(*pKeyDup) + nExpr*(sizeof(CollSeq*)+1) ); + if( pKeyDup ){ + pKeyDup->aSortOrder = (u8*)&pKeyDup->aColl[nExpr]; + pKeyDup->nField = (u16)nExpr; + pKeyDup->enc = ENC(db); + for(i=0; iaColl[i] = multiSelectCollSeq(pParse, p, i); + pKeyDup->aSortOrder[i] = 0; + } + } + } + + /* Separate the left and the right query from one another + */ + p->pPrior = 0; + sqlite3ResolveOrderGroupBy(pParse, p, p->pOrderBy, "ORDER"); + if( pPrior->pPrior==0 ){ + sqlite3ResolveOrderGroupBy(pParse, pPrior, pPrior->pOrderBy, "ORDER"); + } + + /* Compute the limit registers */ + computeLimitRegisters(pParse, p, labelEnd); + if( p->iLimit && op==TK_ALL ){ + regLimitA = ++pParse->nMem; + regLimitB = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Copy, p->iOffset ? p->iOffset+1 : p->iLimit, + regLimitA); + sqlite3VdbeAddOp2(v, OP_Copy, regLimitA, regLimitB); + }else{ + regLimitA = regLimitB = 0; + } + sqlite3ExprDelete(db, p->pLimit); + p->pLimit = 0; + sqlite3ExprDelete(db, p->pOffset); + p->pOffset = 0; + + regAddrA = ++pParse->nMem; + regEofA = ++pParse->nMem; + regAddrB = ++pParse->nMem; + regEofB = ++pParse->nMem; + regOutA = ++pParse->nMem; + regOutB = ++pParse->nMem; + sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA); + sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB); + + /* Jump past the various subroutines and coroutines to the main + ** merge loop + */ + j1 = sqlite3VdbeAddOp0(v, OP_Goto); + addrSelectA = sqlite3VdbeCurrentAddr(v); + + + /* Generate a coroutine to evaluate the SELECT statement to the + ** left of the compound operator - the "A" select. + */ + VdbeNoopComment((v, "Begin coroutine for left SELECT")); + pPrior->iLimit = regLimitA; + explainSetInteger(iSub1, pParse->iNextSelectId); + sqlite3Select(pParse, pPrior, &destA); + sqlite3VdbeAddOp2(v, OP_Integer, 1, regEofA); + sqlite3VdbeAddOp1(v, OP_Yield, regAddrA); + VdbeNoopComment((v, "End coroutine for left SELECT")); + + /* Generate a coroutine to evaluate the SELECT statement on + ** the right - the "B" select + */ + addrSelectB = sqlite3VdbeCurrentAddr(v); + VdbeNoopComment((v, "Begin coroutine for right SELECT")); + savedLimit = p->iLimit; + savedOffset = p->iOffset; + p->iLimit = regLimitB; + p->iOffset = 0; + explainSetInteger(iSub2, pParse->iNextSelectId); + sqlite3Select(pParse, p, &destB); + p->iLimit = savedLimit; + p->iOffset = savedOffset; + sqlite3VdbeAddOp2(v, OP_Integer, 1, regEofB); + sqlite3VdbeAddOp1(v, OP_Yield, regAddrB); + VdbeNoopComment((v, "End coroutine for right SELECT")); + + /* Generate a subroutine that outputs the current row of the A + ** select as the next output row of the compound select. + */ + VdbeNoopComment((v, "Output routine for A")); + addrOutA = generateOutputSubroutine(pParse, + p, &destA, pDest, regOutA, + regPrev, pKeyDup, P4_KEYINFO_HANDOFF, labelEnd); + + /* Generate a subroutine that outputs the current row of the B + ** select as the next output row of the compound select. + */ + if( op==TK_ALL || op==TK_UNION ){ + VdbeNoopComment((v, "Output routine for B")); + addrOutB = generateOutputSubroutine(pParse, + p, &destB, pDest, regOutB, + regPrev, pKeyDup, P4_KEYINFO_STATIC, labelEnd); + } + + /* Generate a subroutine to run when the results from select A + ** are exhausted and only data in select B remains. + */ + VdbeNoopComment((v, "eof-A subroutine")); + if( op==TK_EXCEPT || op==TK_INTERSECT ){ + addrEofA = sqlite3VdbeAddOp2(v, OP_Goto, 0, labelEnd); + }else{ + addrEofA = sqlite3VdbeAddOp2(v, OP_If, regEofB, labelEnd); + sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB); + sqlite3VdbeAddOp1(v, OP_Yield, regAddrB); + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofA); + p->nSelectRow += pPrior->nSelectRow; + } + + /* Generate a subroutine to run when the results from select B + ** are exhausted and only data in select A remains. + */ + if( op==TK_INTERSECT ){ + addrEofB = addrEofA; + if( p->nSelectRow > pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow; + }else{ + VdbeNoopComment((v, "eof-B subroutine")); + addrEofB = sqlite3VdbeAddOp2(v, OP_If, regEofA, labelEnd); + sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA); + sqlite3VdbeAddOp1(v, OP_Yield, regAddrA); + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofB); + } + + /* Generate code to handle the case of AB + */ + VdbeNoopComment((v, "A-gt-B subroutine")); + addrAgtB = sqlite3VdbeCurrentAddr(v); + if( op==TK_ALL || op==TK_UNION ){ + sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB); + } + sqlite3VdbeAddOp1(v, OP_Yield, regAddrB); + sqlite3VdbeAddOp2(v, OP_If, regEofB, addrEofB); + sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr); + + /* This code runs once to initialize everything. + */ + sqlite3VdbeJumpHere(v, j1); + sqlite3VdbeAddOp2(v, OP_Integer, 0, regEofA); + sqlite3VdbeAddOp2(v, OP_Integer, 0, regEofB); + sqlite3VdbeAddOp2(v, OP_Gosub, regAddrA, addrSelectA); + sqlite3VdbeAddOp2(v, OP_Gosub, regAddrB, addrSelectB); + sqlite3VdbeAddOp2(v, OP_If, regEofA, addrEofA); + sqlite3VdbeAddOp2(v, OP_If, regEofB, addrEofB); + + /* Implement the main merge loop + */ + sqlite3VdbeResolveLabel(v, labelCmpr); + sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY); + sqlite3VdbeAddOp4(v, OP_Compare, destA.iMem, destB.iMem, nOrderBy, + (char*)pKeyMerge, P4_KEYINFO_HANDOFF); + sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB); + + /* Release temporary registers + */ + if( regPrev ){ + sqlite3ReleaseTempRange(pParse, regPrev, nOrderBy+1); + } + + /* Jump to the this point in order to terminate the query. + */ + sqlite3VdbeResolveLabel(v, labelEnd); + + /* Set the number of output columns + */ + if( pDest->eDest==SRT_Output ){ + Select *pFirst = pPrior; + while( pFirst->pPrior ) pFirst = pFirst->pPrior; + generateColumnNames(pParse, 0, pFirst->pEList); + } + + /* Reassembly the compound query so that it will be freed correctly + ** by the calling function */ + if( p->pPrior ){ + sqlite3SelectDelete(db, p->pPrior); + } + p->pPrior = pPrior; + + /*** TBD: Insert subroutine calls to close cursors on incomplete + **** subqueries ****/ + explainComposite(pParse, p->op, iSub1, iSub2, 0); + return SQLITE_OK; +} +#endif + +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) +/* Forward Declarations */ +static void substExprList(sqlite3*, ExprList*, int, ExprList*); +static void substSelect(sqlite3*, Select *, int, ExprList *); + +/* +** Scan through the expression pExpr. Replace every reference to +** a column in table number iTable with a copy of the iColumn-th +** entry in pEList. (But leave references to the ROWID column +** unchanged.) +** +** This routine is part of the flattening procedure. A subquery +** whose result set is defined by pEList appears as entry in the +** FROM clause of a SELECT such that the VDBE cursor assigned to that +** FORM clause entry is iTable. This routine make the necessary +** changes to pExpr so that it refers directly to the source table +** of the subquery rather the result set of the subquery. +*/ +static Expr *substExpr( + sqlite3 *db, /* Report malloc errors to this connection */ + Expr *pExpr, /* Expr in which substitution occurs */ + int iTable, /* Table to be substituted */ + ExprList *pEList /* Substitute expressions */ +){ + if( pExpr==0 ) return 0; + if( pExpr->op==TK_COLUMN && pExpr->iTable==iTable ){ + if( pExpr->iColumn<0 ){ + pExpr->op = TK_NULL; + }else{ + Expr *pNew; + assert( pEList!=0 && pExpr->iColumnnExpr ); + assert( pExpr->pLeft==0 && pExpr->pRight==0 ); + pNew = sqlite3ExprDup(db, pEList->a[pExpr->iColumn].pExpr, 0); + if( pNew && pExpr->pColl ){ + pNew->pColl = pExpr->pColl; + } + sqlite3ExprDelete(db, pExpr); + pExpr = pNew; + } + }else{ + pExpr->pLeft = substExpr(db, pExpr->pLeft, iTable, pEList); + pExpr->pRight = substExpr(db, pExpr->pRight, iTable, pEList); + if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + substSelect(db, pExpr->x.pSelect, iTable, pEList); + }else{ + substExprList(db, pExpr->x.pList, iTable, pEList); + } + } + return pExpr; +} +static void substExprList( + sqlite3 *db, /* Report malloc errors here */ + ExprList *pList, /* List to scan and in which to make substitutes */ + int iTable, /* Table to be substituted */ + ExprList *pEList /* Substitute values */ +){ + int i; + if( pList==0 ) return; + for(i=0; inExpr; i++){ + pList->a[i].pExpr = substExpr(db, pList->a[i].pExpr, iTable, pEList); + } +} +static void substSelect( + sqlite3 *db, /* Report malloc errors here */ + Select *p, /* SELECT statement in which to make substitutions */ + int iTable, /* Table to be replaced */ + ExprList *pEList /* Substitute values */ +){ + SrcList *pSrc; + struct SrcList_item *pItem; + int i; + if( !p ) return; + substExprList(db, p->pEList, iTable, pEList); + substExprList(db, p->pGroupBy, iTable, pEList); + substExprList(db, p->pOrderBy, iTable, pEList); + p->pHaving = substExpr(db, p->pHaving, iTable, pEList); + p->pWhere = substExpr(db, p->pWhere, iTable, pEList); + substSelect(db, p->pPrior, iTable, pEList); + pSrc = p->pSrc; + assert( pSrc ); /* Even for (SELECT 1) we have: pSrc!=0 but pSrc->nSrc==0 */ + if( ALWAYS(pSrc) ){ + for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ + substSelect(db, pItem->pSelect, iTable, pEList); + } + } +} +#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ + +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) +/* +** This routine attempts to flatten subqueries as a performance optimization. +** This routine returns 1 if it makes changes and 0 if no flattening occurs. +** +** To understand the concept of flattening, consider the following +** query: +** +** SELECT a FROM (SELECT x+y AS a FROM t1 WHERE z<100) WHERE a>5 +** +** The default way of implementing this query is to execute the +** subquery first and store the results in a temporary table, then +** run the outer query on that temporary table. This requires two +** passes over the data. Furthermore, because the temporary table +** has no indices, the WHERE clause on the outer query cannot be +** optimized. +** +** This routine attempts to rewrite queries such as the above into +** a single flat select, like this: +** +** SELECT x+y AS a FROM t1 WHERE z<100 AND a>5 +** +** The code generated for this simpification gives the same result +** but only has to scan the data once. And because indices might +** exist on the table t1, a complete scan of the data might be +** avoided. +** +** Flattening is only attempted if all of the following are true: +** +** (1) The subquery and the outer query do not both use aggregates. +** +** (2) The subquery is not an aggregate or the outer query is not a join. +** +** (3) The subquery is not the right operand of a left outer join +** (Originally ticket #306. Strengthened by ticket #3300) +** +** (4) The subquery is not DISTINCT. +** +** (**) At one point restrictions (4) and (5) defined a subset of DISTINCT +** sub-queries that were excluded from this optimization. Restriction +** (4) has since been expanded to exclude all DISTINCT subqueries. +** +** (6) The subquery does not use aggregates or the outer query is not +** DISTINCT. +** +** (7) The subquery has a FROM clause. TODO: For subqueries without +** A FROM clause, consider adding a FROM close with the special +** table sqlite_once that consists of a single row containing a +** single NULL. +** +** (8) The subquery does not use LIMIT or the outer query is not a join. +** +** (9) The subquery does not use LIMIT or the outer query does not use +** aggregates. +** +** (10) The subquery does not use aggregates or the outer query does not +** use LIMIT. +** +** (11) The subquery and the outer query do not both have ORDER BY clauses. +** +** (**) Not implemented. Subsumed into restriction (3). Was previously +** a separate restriction deriving from ticket #350. +** +** (13) The subquery and outer query do not both use LIMIT. +** +** (14) The subquery does not use OFFSET. +** +** (15) The outer query is not part of a compound select or the +** subquery does not have a LIMIT clause. +** (See ticket #2339 and ticket [02a8e81d44]). +** +** (16) The outer query is not an aggregate or the subquery does +** not contain ORDER BY. (Ticket #2942) This used to not matter +** until we introduced the group_concat() function. +** +** (17) The sub-query is not a compound select, or it is a UNION ALL +** compound clause made up entirely of non-aggregate queries, and +** the parent query: +** +** * is not itself part of a compound select, +** * is not an aggregate or DISTINCT query, and +** * is not a join +** +** The parent and sub-query may contain WHERE clauses. Subject to +** rules (11), (13) and (14), they may also contain ORDER BY, +** LIMIT and OFFSET clauses. The subquery cannot use any compound +** operator other than UNION ALL because all the other compound +** operators have an implied DISTINCT which is disallowed by +** restriction (4). +** +** (18) If the sub-query is a compound select, then all terms of the +** ORDER by clause of the parent must be simple references to +** columns of the sub-query. +** +** (19) The subquery does not use LIMIT or the outer query does not +** have a WHERE clause. +** +** (20) If the sub-query is a compound select, then it must not use +** an ORDER BY clause. Ticket #3773. We could relax this constraint +** somewhat by saying that the terms of the ORDER BY clause must +** appear as unmodified result columns in the outer query. But we +** have other optimizations in mind to deal with that case. +** +** (21) The subquery does not use LIMIT or the outer query is not +** DISTINCT. (See ticket [752e1646fc]). +** +** In this routine, the "p" parameter is a pointer to the outer query. +** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query +** uses aggregates and subqueryIsAgg is true if the subquery uses aggregates. +** +** If flattening is not attempted, this routine is a no-op and returns 0. +** If flattening is attempted this routine returns 1. +** +** All of the expression analysis must occur on both the outer query and +** the subquery before this routine runs. +*/ +static int flattenSubquery( + Parse *pParse, /* Parsing context */ + Select *p, /* The parent or outer SELECT statement */ + int iFrom, /* Index in p->pSrc->a[] of the inner subquery */ + int isAgg, /* True if outer SELECT uses aggregate functions */ + int subqueryIsAgg /* True if the subquery uses aggregate functions */ +){ + const char *zSavedAuthContext = pParse->zAuthContext; + Select *pParent; + Select *pSub; /* The inner query or "subquery" */ + Select *pSub1; /* Pointer to the rightmost select in sub-query */ + SrcList *pSrc; /* The FROM clause of the outer query */ + SrcList *pSubSrc; /* The FROM clause of the subquery */ + ExprList *pList; /* The result set of the outer query */ + int iParent; /* VDBE cursor number of the pSub result set temp table */ + int i; /* Loop counter */ + Expr *pWhere; /* The WHERE clause */ + struct SrcList_item *pSubitem; /* The subquery */ + sqlite3 *db = pParse->db; + + /* Check to see if flattening is permitted. Return 0 if not. + */ + assert( p!=0 ); + assert( p->pPrior==0 ); /* Unable to flatten compound queries */ + if( db->flags & SQLITE_QueryFlattener ) return 0; + pSrc = p->pSrc; + assert( pSrc && iFrom>=0 && iFromnSrc ); + pSubitem = &pSrc->a[iFrom]; + iParent = pSubitem->iCursor; + pSub = pSubitem->pSelect; + assert( pSub!=0 ); + if( isAgg && subqueryIsAgg ) return 0; /* Restriction (1) */ + if( subqueryIsAgg && pSrc->nSrc>1 ) return 0; /* Restriction (2) */ + pSubSrc = pSub->pSrc; + assert( pSubSrc ); + /* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants, + ** not arbitrary expresssions, we allowed some combining of LIMIT and OFFSET + ** because they could be computed at compile-time. But when LIMIT and OFFSET + ** became arbitrary expressions, we were forced to add restrictions (13) + ** and (14). */ + if( pSub->pLimit && p->pLimit ) return 0; /* Restriction (13) */ + if( pSub->pOffset ) return 0; /* Restriction (14) */ + if( p->pRightmost && pSub->pLimit ){ + return 0; /* Restriction (15) */ + } + if( pSubSrc->nSrc==0 ) return 0; /* Restriction (7) */ + if( pSub->selFlags & SF_Distinct ) return 0; /* Restriction (5) */ + if( pSub->pLimit && (pSrc->nSrc>1 || isAgg) ){ + return 0; /* Restrictions (8)(9) */ + } + if( (p->selFlags & SF_Distinct)!=0 && subqueryIsAgg ){ + return 0; /* Restriction (6) */ + } + if( p->pOrderBy && pSub->pOrderBy ){ + return 0; /* Restriction (11) */ + } + if( isAgg && pSub->pOrderBy ) return 0; /* Restriction (16) */ + if( pSub->pLimit && p->pWhere ) return 0; /* Restriction (19) */ + if( pSub->pLimit && (p->selFlags & SF_Distinct)!=0 ){ + return 0; /* Restriction (21) */ + } + + /* OBSOLETE COMMENT 1: + ** Restriction 3: If the subquery is a join, make sure the subquery is + ** not used as the right operand of an outer join. Examples of why this + ** is not allowed: + ** + ** t1 LEFT OUTER JOIN (t2 JOIN t3) + ** + ** If we flatten the above, we would get + ** + ** (t1 LEFT OUTER JOIN t2) JOIN t3 + ** + ** which is not at all the same thing. + ** + ** OBSOLETE COMMENT 2: + ** Restriction 12: If the subquery is the right operand of a left outer + ** join, make sure the subquery has no WHERE clause. + ** An examples of why this is not allowed: + ** + ** t1 LEFT OUTER JOIN (SELECT * FROM t2 WHERE t2.x>0) + ** + ** If we flatten the above, we would get + ** + ** (t1 LEFT OUTER JOIN t2) WHERE t2.x>0 + ** + ** But the t2.x>0 test will always fail on a NULL row of t2, which + ** effectively converts the OUTER JOIN into an INNER JOIN. + ** + ** THIS OVERRIDES OBSOLETE COMMENTS 1 AND 2 ABOVE: + ** Ticket #3300 shows that flattening the right term of a LEFT JOIN + ** is fraught with danger. Best to avoid the whole thing. If the + ** subquery is the right term of a LEFT JOIN, then do not flatten. + */ + if( (pSubitem->jointype & JT_OUTER)!=0 ){ + return 0; + } + + /* Restriction 17: If the sub-query is a compound SELECT, then it must + ** use only the UNION ALL operator. And none of the simple select queries + ** that make up the compound SELECT are allowed to be aggregate or distinct + ** queries. + */ + if( pSub->pPrior ){ + if( pSub->pOrderBy ){ + return 0; /* Restriction 20 */ + } + if( isAgg || (p->selFlags & SF_Distinct)!=0 || pSrc->nSrc!=1 ){ + return 0; + } + for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){ + testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct ); + testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate ); + assert( pSub->pSrc!=0 ); + if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0 + || (pSub1->pPrior && pSub1->op!=TK_ALL) + || pSub1->pSrc->nSrc<1 + ){ + return 0; + } + testcase( pSub1->pSrc->nSrc>1 ); + } + + /* Restriction 18. */ + if( p->pOrderBy ){ + int ii; + for(ii=0; iipOrderBy->nExpr; ii++){ + if( p->pOrderBy->a[ii].iOrderByCol==0 ) return 0; + } + } + } + + /***** If we reach this point, flattening is permitted. *****/ + + /* Authorize the subquery */ + pParse->zAuthContext = pSubitem->zName; + sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0); + pParse->zAuthContext = zSavedAuthContext; + + /* If the sub-query is a compound SELECT statement, then (by restrictions + ** 17 and 18 above) it must be a UNION ALL and the parent query must + ** be of the form: + ** + ** SELECT FROM () + ** + ** followed by any ORDER BY, LIMIT and/or OFFSET clauses. This block + ** creates N-1 copies of the parent query without any ORDER BY, LIMIT or + ** OFFSET clauses and joins them to the left-hand-side of the original + ** using UNION ALL operators. In this case N is the number of simple + ** select statements in the compound sub-query. + ** + ** Example: + ** + ** SELECT a+1 FROM ( + ** SELECT x FROM tab + ** UNION ALL + ** SELECT y FROM tab + ** UNION ALL + ** SELECT abs(z*2) FROM tab2 + ** ) WHERE a!=5 ORDER BY 1 + ** + ** Transformed into: + ** + ** SELECT x+1 FROM tab WHERE x+1!=5 + ** UNION ALL + ** SELECT y+1 FROM tab WHERE y+1!=5 + ** UNION ALL + ** SELECT abs(z*2)+1 FROM tab2 WHERE abs(z*2)+1!=5 + ** ORDER BY 1 + ** + ** We call this the "compound-subquery flattening". + */ + for(pSub=pSub->pPrior; pSub; pSub=pSub->pPrior){ + Select *pNew; + ExprList *pOrderBy = p->pOrderBy; + Expr *pLimit = p->pLimit; + Select *pPrior = p->pPrior; + p->pOrderBy = 0; + p->pSrc = 0; + p->pPrior = 0; + p->pLimit = 0; + pNew = sqlite3SelectDup(db, p, 0); + p->pLimit = pLimit; + p->pOrderBy = pOrderBy; + p->pSrc = pSrc; + p->op = TK_ALL; + p->pRightmost = 0; + if( pNew==0 ){ + pNew = pPrior; + }else{ + pNew->pPrior = pPrior; + pNew->pRightmost = 0; + } + p->pPrior = pNew; + if( db->mallocFailed ) return 1; + } + + /* Begin flattening the iFrom-th entry of the FROM clause + ** in the outer query. + */ + pSub = pSub1 = pSubitem->pSelect; + + /* Delete the transient table structure associated with the + ** subquery + */ + sqlite3DbFree(db, pSubitem->zDatabase); + sqlite3DbFree(db, pSubitem->zName); + sqlite3DbFree(db, pSubitem->zAlias); + pSubitem->zDatabase = 0; + pSubitem->zName = 0; + pSubitem->zAlias = 0; + pSubitem->pSelect = 0; + + /* Defer deleting the Table object associated with the + ** subquery until code generation is + ** complete, since there may still exist Expr.pTab entries that + ** refer to the subquery even after flattening. Ticket #3346. + ** + ** pSubitem->pTab is always non-NULL by test restrictions and tests above. + */ + if( ALWAYS(pSubitem->pTab!=0) ){ + Table *pTabToDel = pSubitem->pTab; + if( pTabToDel->nRef==1 ){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + pTabToDel->pNextZombie = pToplevel->pZombieTab; + pToplevel->pZombieTab = pTabToDel; + }else{ + pTabToDel->nRef--; + } + pSubitem->pTab = 0; + } + + /* The following loop runs once for each term in a compound-subquery + ** flattening (as described above). If we are doing a different kind + ** of flattening - a flattening other than a compound-subquery flattening - + ** then this loop only runs once. + ** + ** This loop moves all of the FROM elements of the subquery into the + ** the FROM clause of the outer query. Before doing this, remember + ** the cursor number for the original outer query FROM element in + ** iParent. The iParent cursor will never be used. Subsequent code + ** will scan expressions looking for iParent references and replace + ** those references with expressions that resolve to the subquery FROM + ** elements we are now copying in. + */ + for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){ + int nSubSrc; + u8 jointype = 0; + pSubSrc = pSub->pSrc; /* FROM clause of subquery */ + nSubSrc = pSubSrc->nSrc; /* Number of terms in subquery FROM clause */ + pSrc = pParent->pSrc; /* FROM clause of the outer query */ + + if( pSrc ){ + assert( pParent==p ); /* First time through the loop */ + jointype = pSubitem->jointype; + }else{ + assert( pParent!=p ); /* 2nd and subsequent times through the loop */ + pSrc = pParent->pSrc = sqlite3SrcListAppend(db, 0, 0, 0); + if( pSrc==0 ){ + assert( db->mallocFailed ); + break; + } + } + + /* The subquery uses a single slot of the FROM clause of the outer + ** query. If the subquery has more than one element in its FROM clause, + ** then expand the outer query to make space for it to hold all elements + ** of the subquery. + ** + ** Example: + ** + ** SELECT * FROM tabA, (SELECT * FROM sub1, sub2), tabB; + ** + ** The outer query has 3 slots in its FROM clause. One slot of the + ** outer query (the middle slot) is used by the subquery. The next + ** block of code will expand the out query to 4 slots. The middle + ** slot is expanded to two slots in order to make space for the + ** two elements in the FROM clause of the subquery. + */ + if( nSubSrc>1 ){ + pParent->pSrc = pSrc = sqlite3SrcListEnlarge(db, pSrc, nSubSrc-1,iFrom+1); + if( db->mallocFailed ){ + break; + } + } + + /* Transfer the FROM clause terms from the subquery into the + ** outer query. + */ + for(i=0; ia[i+iFrom].pUsing); + pSrc->a[i+iFrom] = pSubSrc->a[i]; + memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i])); + } + pSrc->a[iFrom].jointype = jointype; + + /* Now begin substituting subquery result set expressions for + ** references to the iParent in the outer query. + ** + ** Example: + ** + ** SELECT a+5, b*10 FROM (SELECT x*3 AS a, y+10 AS b FROM t1) WHERE a>b; + ** \ \_____________ subquery __________/ / + ** \_____________________ outer query ______________________________/ + ** + ** We look at every expression in the outer query and every place we see + ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10". + */ + pList = pParent->pEList; + for(i=0; inExpr; i++){ + if( pList->a[i].zName==0 ){ + const char *zSpan = pList->a[i].zSpan; + if( ALWAYS(zSpan) ){ + pList->a[i].zName = sqlite3DbStrDup(db, zSpan); + } + } + } + substExprList(db, pParent->pEList, iParent, pSub->pEList); + if( isAgg ){ + substExprList(db, pParent->pGroupBy, iParent, pSub->pEList); + pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList); + } + if( pSub->pOrderBy ){ + assert( pParent->pOrderBy==0 ); + pParent->pOrderBy = pSub->pOrderBy; + pSub->pOrderBy = 0; + }else if( pParent->pOrderBy ){ + substExprList(db, pParent->pOrderBy, iParent, pSub->pEList); + } + if( pSub->pWhere ){ + pWhere = sqlite3ExprDup(db, pSub->pWhere, 0); + }else{ + pWhere = 0; + } + if( subqueryIsAgg ){ + assert( pParent->pHaving==0 ); + pParent->pHaving = pParent->pWhere; + pParent->pWhere = pWhere; + pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList); + pParent->pHaving = sqlite3ExprAnd(db, pParent->pHaving, + sqlite3ExprDup(db, pSub->pHaving, 0)); + assert( pParent->pGroupBy==0 ); + pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy, 0); + }else{ + pParent->pWhere = substExpr(db, pParent->pWhere, iParent, pSub->pEList); + pParent->pWhere = sqlite3ExprAnd(db, pParent->pWhere, pWhere); + } + + /* The flattened query is distinct if either the inner or the + ** outer query is distinct. + */ + pParent->selFlags |= pSub->selFlags & SF_Distinct; + + /* + ** SELECT ... FROM (SELECT ... LIMIT a OFFSET b) LIMIT x OFFSET y; + ** + ** One is tempted to try to add a and b to combine the limits. But this + ** does not work if either limit is negative. + */ + if( pSub->pLimit ){ + pParent->pLimit = pSub->pLimit; + pSub->pLimit = 0; + } + } + + /* Finially, delete what is left of the subquery and return + ** success. + */ + sqlite3SelectDelete(db, pSub1); + + return 1; +} +#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ + +/* +** Analyze the SELECT statement passed as an argument to see if it +** is a min() or max() query. Return WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX if +** it is, or 0 otherwise. At present, a query is considered to be +** a min()/max() query if: +** +** 1. There is a single object in the FROM clause. +** +** 2. There is a single expression in the result set, and it is +** either min(x) or max(x), where x is a column reference. +*/ +static u8 minMaxQuery(Select *p){ + Expr *pExpr; + ExprList *pEList = p->pEList; + + if( pEList->nExpr!=1 ) return WHERE_ORDERBY_NORMAL; + pExpr = pEList->a[0].pExpr; + if( pExpr->op!=TK_AGG_FUNCTION ) return 0; + if( NEVER(ExprHasProperty(pExpr, EP_xIsSelect)) ) return 0; + pEList = pExpr->x.pList; + if( pEList==0 || pEList->nExpr!=1 ) return 0; + if( pEList->a[0].pExpr->op!=TK_AGG_COLUMN ) return WHERE_ORDERBY_NORMAL; + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + if( sqlite3StrICmp(pExpr->u.zToken,"min")==0 ){ + return WHERE_ORDERBY_MIN; + }else if( sqlite3StrICmp(pExpr->u.zToken,"max")==0 ){ + return WHERE_ORDERBY_MAX; + } + return WHERE_ORDERBY_NORMAL; +} + +/* +** The select statement passed as the first argument is an aggregate query. +** The second argment is the associated aggregate-info object. This +** function tests if the SELECT is of the form: +** +** SELECT count(*) FROM +** +** where table is a database table, not a sub-select or view. If the query +** does match this pattern, then a pointer to the Table object representing +** is returned. Otherwise, 0 is returned. +*/ +static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){ + Table *pTab; + Expr *pExpr; + + assert( !p->pGroupBy ); + + if( p->pWhere || p->pEList->nExpr!=1 + || p->pSrc->nSrc!=1 || p->pSrc->a[0].pSelect + ){ + return 0; + } + pTab = p->pSrc->a[0].pTab; + pExpr = p->pEList->a[0].pExpr; + assert( pTab && !pTab->pSelect && pExpr ); + + if( IsVirtual(pTab) ) return 0; + if( pExpr->op!=TK_AGG_FUNCTION ) return 0; + if( (pAggInfo->aFunc[0].pFunc->flags&SQLITE_FUNC_COUNT)==0 ) return 0; + if( pExpr->flags&EP_Distinct ) return 0; + + return pTab; +} + +/* +** If the source-list item passed as an argument was augmented with an +** INDEXED BY clause, then try to locate the specified index. If there +** was such a clause and the named index cannot be found, return +** SQLITE_ERROR and leave an error in pParse. Otherwise, populate +** pFrom->pIndex and return SQLITE_OK. +*/ +int sqlite3IndexedByLookup(Parse *pParse, struct SrcList_item *pFrom){ + if( pFrom->pTab && pFrom->zIndex ){ + Table *pTab = pFrom->pTab; + char *zIndex = pFrom->zIndex; + Index *pIdx; + for(pIdx=pTab->pIndex; + pIdx && sqlite3StrICmp(pIdx->zName, zIndex); + pIdx=pIdx->pNext + ); + if( !pIdx ){ + sqlite3ErrorMsg(pParse, "no such index: %s", zIndex, 0); + pParse->checkSchema = 1; + return SQLITE_ERROR; + } + pFrom->pIndex = pIdx; + } + return SQLITE_OK; +} + +/* +** This routine is a Walker callback for "expanding" a SELECT statement. +** "Expanding" means to do the following: +** +** (1) Make sure VDBE cursor numbers have been assigned to every +** element of the FROM clause. +** +** (2) Fill in the pTabList->a[].pTab fields in the SrcList that +** defines FROM clause. When views appear in the FROM clause, +** fill pTabList->a[].pSelect with a copy of the SELECT statement +** that implements the view. A copy is made of the view's SELECT +** statement so that we can freely modify or delete that statement +** without worrying about messing up the presistent representation +** of the view. +** +** (3) Add terms to the WHERE clause to accomodate the NATURAL keyword +** on joins and the ON and USING clause of joins. +** +** (4) Scan the list of columns in the result set (pEList) looking +** for instances of the "*" operator or the TABLE.* operator. +** If found, expand each "*" to be every column in every table +** and TABLE.* to be every column in TABLE. +** +*/ +static int selectExpander(Walker *pWalker, Select *p){ + Parse *pParse = pWalker->pParse; + int i, j, k; + SrcList *pTabList; + ExprList *pEList; + struct SrcList_item *pFrom; + sqlite3 *db = pParse->db; + + if( db->mallocFailed ){ + return WRC_Abort; + } + if( NEVER(p->pSrc==0) || (p->selFlags & SF_Expanded)!=0 ){ + return WRC_Prune; + } + p->selFlags |= SF_Expanded; + pTabList = p->pSrc; + pEList = p->pEList; + + /* Make sure cursor numbers have been assigned to all entries in + ** the FROM clause of the SELECT statement. + */ + sqlite3SrcListAssignCursors(pParse, pTabList); + + /* Look up every table named in the FROM clause of the select. If + ** an entry of the FROM clause is a subquery instead of a table or view, + ** then create a transient table structure to describe the subquery. + */ + for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ + Table *pTab; + if( pFrom->pTab!=0 ){ + /* This statement has already been prepared. There is no need + ** to go further. */ + assert( i==0 ); + return WRC_Prune; + } + if( pFrom->zName==0 ){ +#ifndef SQLITE_OMIT_SUBQUERY + Select *pSel = pFrom->pSelect; + /* A sub-query in the FROM clause of a SELECT */ + assert( pSel!=0 ); + assert( pFrom->pTab==0 ); + sqlite3WalkSelect(pWalker, pSel); + pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); + if( pTab==0 ) return WRC_Abort; + pTab->nRef = 1; + pTab->zName = sqlite3MPrintf(db, "sqlite_subquery_%p_", (void*)pTab); + while( pSel->pPrior ){ pSel = pSel->pPrior; } + selectColumnsFromExprList(pParse, pSel->pEList, &pTab->nCol, &pTab->aCol); + pTab->iPKey = -1; + pTab->nRowEst = 1000000; + pTab->tabFlags |= TF_Ephemeral; +#endif + }else{ + /* An ordinary table or view name in the FROM clause */ + assert( pFrom->pTab==0 ); + pFrom->pTab = pTab = + sqlite3LocateTable(pParse,0,pFrom->zName,pFrom->zDatabase); + if( pTab==0 ) return WRC_Abort; + pTab->nRef++; +#if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE) + if( pTab->pSelect || IsVirtual(pTab) ){ + /* We reach here if the named table is a really a view */ + if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort; + assert( pFrom->pSelect==0 ); + pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0); + sqlite3WalkSelect(pWalker, pFrom->pSelect); + } +#endif + } + + /* Locate the index named by the INDEXED BY clause, if any. */ + if( sqlite3IndexedByLookup(pParse, pFrom) ){ + return WRC_Abort; + } + } + + /* Process NATURAL keywords, and ON and USING clauses of joins. + */ + if( db->mallocFailed || sqliteProcessJoin(pParse, p) ){ + return WRC_Abort; + } + + /* For every "*" that occurs in the column list, insert the names of + ** all columns in all tables. And for every TABLE.* insert the names + ** of all columns in TABLE. The parser inserted a special expression + ** with the TK_ALL operator for each "*" that it found in the column list. + ** The following code just has to locate the TK_ALL expressions and expand + ** each one to the list of all columns in all tables. + ** + ** The first loop just checks to see if there are any "*" operators + ** that need expanding. + */ + for(k=0; knExpr; k++){ + Expr *pE = pEList->a[k].pExpr; + if( pE->op==TK_ALL ) break; + assert( pE->op!=TK_DOT || pE->pRight!=0 ); + assert( pE->op!=TK_DOT || (pE->pLeft!=0 && pE->pLeft->op==TK_ID) ); + if( pE->op==TK_DOT && pE->pRight->op==TK_ALL ) break; + } + if( knExpr ){ + /* + ** If we get here it means the result set contains one or more "*" + ** operators that need to be expanded. Loop through each expression + ** in the result set and expand them one by one. + */ + struct ExprList_item *a = pEList->a; + ExprList *pNew = 0; + int flags = pParse->db->flags; + int longNames = (flags & SQLITE_FullColNames)!=0 + && (flags & SQLITE_ShortColNames)==0; + + for(k=0; knExpr; k++){ + Expr *pE = a[k].pExpr; + assert( pE->op!=TK_DOT || pE->pRight!=0 ); + if( pE->op!=TK_ALL && (pE->op!=TK_DOT || pE->pRight->op!=TK_ALL) ){ + /* This particular expression does not need to be expanded. + */ + pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr); + if( pNew ){ + pNew->a[pNew->nExpr-1].zName = a[k].zName; + pNew->a[pNew->nExpr-1].zSpan = a[k].zSpan; + a[k].zName = 0; + a[k].zSpan = 0; + } + a[k].pExpr = 0; + }else{ + /* This expression is a "*" or a "TABLE.*" and needs to be + ** expanded. */ + int tableSeen = 0; /* Set to 1 when TABLE matches */ + char *zTName; /* text of name of TABLE */ + if( pE->op==TK_DOT ){ + assert( pE->pLeft!=0 ); + assert( !ExprHasProperty(pE->pLeft, EP_IntValue) ); + zTName = pE->pLeft->u.zToken; + }else{ + zTName = 0; + } + for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ + Table *pTab = pFrom->pTab; + char *zTabName = pFrom->zAlias; + if( zTabName==0 ){ + zTabName = pTab->zName; + } + if( db->mallocFailed ) break; + if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){ + continue; + } + tableSeen = 1; + for(j=0; jnCol; j++){ + Expr *pExpr, *pRight; + char *zName = pTab->aCol[j].zName; + char *zColname; /* The computed column name */ + char *zToFree; /* Malloced string that needs to be freed */ + Token sColname; /* Computed column name as a token */ + + /* If a column is marked as 'hidden' (currently only possible + ** for virtual tables), do not include it in the expanded + ** result-set list. + */ + if( IsHiddenColumn(&pTab->aCol[j]) ){ + assert(IsVirtual(pTab)); + continue; + } + + if( i>0 && zTName==0 ){ + if( (pFrom->jointype & JT_NATURAL)!=0 + && tableAndColumnIndex(pTabList, i, zName, 0, 0) + ){ + /* In a NATURAL join, omit the join columns from the + ** table to the right of the join */ + continue; + } + if( sqlite3IdListIndex(pFrom->pUsing, zName)>=0 ){ + /* In a join with a USING clause, omit columns in the + ** using clause from the table on the right. */ + continue; + } + } + pRight = sqlite3Expr(db, TK_ID, zName); + zColname = zName; + zToFree = 0; + if( longNames || pTabList->nSrc>1 ){ + Expr *pLeft; + pLeft = sqlite3Expr(db, TK_ID, zTabName); + pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0); + if( longNames ){ + zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName); + zToFree = zColname; + } + }else{ + pExpr = pRight; + } + pNew = sqlite3ExprListAppend(pParse, pNew, pExpr); + sColname.z = zColname; + sColname.n = sqlite3Strlen30(zColname); + sqlite3ExprListSetName(pParse, pNew, &sColname, 0); + sqlite3DbFree(db, zToFree); + } + } + if( !tableSeen ){ + if( zTName ){ + sqlite3ErrorMsg(pParse, "no such table: %s", zTName); + }else{ + sqlite3ErrorMsg(pParse, "no tables specified"); + } + } + } + } + sqlite3ExprListDelete(db, pEList); + p->pEList = pNew; + } +#if SQLITE_MAX_COLUMN + if( p->pEList && p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ + sqlite3ErrorMsg(pParse, "too many columns in result set"); + } +#endif + return WRC_Continue; +} + +/* +** No-op routine for the parse-tree walker. +** +** When this routine is the Walker.xExprCallback then expression trees +** are walked without any actions being taken at each node. Presumably, +** when this routine is used for Walker.xExprCallback then +** Walker.xSelectCallback is set to do something useful for every +** subquery in the parser tree. +*/ +static int exprWalkNoop(Walker *NotUsed, Expr *NotUsed2){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + return WRC_Continue; +} + +/* +** This routine "expands" a SELECT statement and all of its subqueries. +** For additional information on what it means to "expand" a SELECT +** statement, see the comment on the selectExpand worker callback above. +** +** Expanding a SELECT statement is the first step in processing a +** SELECT statement. The SELECT statement must be expanded before +** name resolution is performed. +** +** If anything goes wrong, an error message is written into pParse. +** The calling function can detect the problem by looking at pParse->nErr +** and/or pParse->db->mallocFailed. +*/ +static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){ + Walker w; + w.xSelectCallback = selectExpander; + w.xExprCallback = exprWalkNoop; + w.pParse = pParse; + sqlite3WalkSelect(&w, pSelect); +} + + +#ifndef SQLITE_OMIT_SUBQUERY +/* +** This is a Walker.xSelectCallback callback for the sqlite3SelectTypeInfo() +** interface. +** +** For each FROM-clause subquery, add Column.zType and Column.zColl +** information to the Table structure that represents the result set +** of that subquery. +** +** The Table structure that represents the result set was constructed +** by selectExpander() but the type and collation information was omitted +** at that point because identifiers had not yet been resolved. This +** routine is called after identifier resolution. +*/ +static int selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ + Parse *pParse; + int i; + SrcList *pTabList; + struct SrcList_item *pFrom; + + assert( p->selFlags & SF_Resolved ); + if( (p->selFlags & SF_HasTypeInfo)==0 ){ + p->selFlags |= SF_HasTypeInfo; + pParse = pWalker->pParse; + pTabList = p->pSrc; + for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ + Table *pTab = pFrom->pTab; + if( ALWAYS(pTab!=0) && (pTab->tabFlags & TF_Ephemeral)!=0 ){ + /* A sub-query in the FROM clause of a SELECT */ + Select *pSel = pFrom->pSelect; + assert( pSel ); + while( pSel->pPrior ) pSel = pSel->pPrior; + selectAddColumnTypeAndCollation(pParse, pTab->nCol, pTab->aCol, pSel); + } + } + } + return WRC_Continue; +} +#endif + + +/* +** This routine adds datatype and collating sequence information to +** the Table structures of all FROM-clause subqueries in a +** SELECT statement. +** +** Use this routine after name resolution. +*/ +static void sqlite3SelectAddTypeInfo(Parse *pParse, Select *pSelect){ +#ifndef SQLITE_OMIT_SUBQUERY + Walker w; + w.xSelectCallback = selectAddSubqueryTypeInfo; + w.xExprCallback = exprWalkNoop; + w.pParse = pParse; + sqlite3WalkSelect(&w, pSelect); +#endif +} + + +/* +** This routine sets of a SELECT statement for processing. The +** following is accomplished: +** +** * VDBE Cursor numbers are assigned to all FROM-clause terms. +** * Ephemeral Table objects are created for all FROM-clause subqueries. +** * ON and USING clauses are shifted into WHERE statements +** * Wildcards "*" and "TABLE.*" in result sets are expanded. +** * Identifiers in expression are matched to tables. +** +** This routine acts recursively on all subqueries within the SELECT. +*/ +void sqlite3SelectPrep( + Parse *pParse, /* The parser context */ + Select *p, /* The SELECT statement being coded. */ + NameContext *pOuterNC /* Name context for container */ +){ + sqlite3 *db; + if( NEVER(p==0) ) return; + db = pParse->db; + if( p->selFlags & SF_HasTypeInfo ) return; + sqlite3SelectExpand(pParse, p); + if( pParse->nErr || db->mallocFailed ) return; + sqlite3ResolveSelectNames(pParse, p, pOuterNC); + if( pParse->nErr || db->mallocFailed ) return; + sqlite3SelectAddTypeInfo(pParse, p); +} + +/* +** Reset the aggregate accumulator. +** +** The aggregate accumulator is a set of memory cells that hold +** intermediate results while calculating an aggregate. This +** routine simply stores NULLs in all of those memory cells. +*/ +static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ + Vdbe *v = pParse->pVdbe; + int i; + struct AggInfo_func *pFunc; + if( pAggInfo->nFunc+pAggInfo->nColumn==0 ){ + return; + } + for(i=0; inColumn; i++){ + sqlite3VdbeAddOp2(v, OP_Null, 0, pAggInfo->aCol[i].iMem); + } + for(pFunc=pAggInfo->aFunc, i=0; inFunc; i++, pFunc++){ + sqlite3VdbeAddOp2(v, OP_Null, 0, pFunc->iMem); + if( pFunc->iDistinct>=0 ){ + Expr *pE = pFunc->pExpr; + assert( !ExprHasProperty(pE, EP_xIsSelect) ); + if( pE->x.pList==0 || pE->x.pList->nExpr!=1 ){ + sqlite3ErrorMsg(pParse, "DISTINCT aggregates must have exactly one " + "argument"); + pFunc->iDistinct = -1; + }else{ + KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList); + sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0, + (char*)pKeyInfo, P4_KEYINFO_HANDOFF); + } + } + } +} + +/* +** Invoke the OP_AggFinalize opcode for every aggregate function +** in the AggInfo structure. +*/ +static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ + Vdbe *v = pParse->pVdbe; + int i; + struct AggInfo_func *pF; + for(i=0, pF=pAggInfo->aFunc; inFunc; i++, pF++){ + ExprList *pList = pF->pExpr->x.pList; + assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) ); + sqlite3VdbeAddOp4(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0, 0, + (void*)pF->pFunc, P4_FUNCDEF); + } +} + +/* +** Update the accumulator memory cells for an aggregate based on +** the current cursor position. +*/ +static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){ + Vdbe *v = pParse->pVdbe; + int i; + struct AggInfo_func *pF; + struct AggInfo_col *pC; + + pAggInfo->directMode = 1; + sqlite3ExprCacheClear(pParse); + for(i=0, pF=pAggInfo->aFunc; inFunc; i++, pF++){ + int nArg; + int addrNext = 0; + int regAgg; + ExprList *pList = pF->pExpr->x.pList; + assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) ); + if( pList ){ + nArg = pList->nExpr; + regAgg = sqlite3GetTempRange(pParse, nArg); + sqlite3ExprCodeExprList(pParse, pList, regAgg, 1); + }else{ + nArg = 0; + regAgg = 0; + } + if( pF->iDistinct>=0 ){ + addrNext = sqlite3VdbeMakeLabel(v); + assert( nArg==1 ); + codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg); + } + if( pF->pFunc->flags & SQLITE_FUNC_NEEDCOLL ){ + CollSeq *pColl = 0; + struct ExprList_item *pItem; + int j; + assert( pList!=0 ); /* pList!=0 if pF->pFunc has NEEDCOLL */ + for(j=0, pItem=pList->a; !pColl && jpExpr); + } + if( !pColl ){ + pColl = pParse->db->pDfltColl; + } + sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ); + } + sqlite3VdbeAddOp4(v, OP_AggStep, 0, regAgg, pF->iMem, + (void*)pF->pFunc, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, (u8)nArg); + sqlite3ExprCacheAffinityChange(pParse, regAgg, nArg); + sqlite3ReleaseTempRange(pParse, regAgg, nArg); + if( addrNext ){ + sqlite3VdbeResolveLabel(v, addrNext); + sqlite3ExprCacheClear(pParse); + } + } + + /* Before populating the accumulator registers, clear the column cache. + ** Otherwise, if any of the required column values are already present + ** in registers, sqlite3ExprCode() may use OP_SCopy to copy the value + ** to pC->iMem. But by the time the value is used, the original register + ** may have been used, invalidating the underlying buffer holding the + ** text or blob value. See ticket [883034dcb5]. + ** + ** Another solution would be to change the OP_SCopy used to copy cached + ** values to an OP_Copy. + */ + sqlite3ExprCacheClear(pParse); + for(i=0, pC=pAggInfo->aCol; inAccumulator; i++, pC++){ + sqlite3ExprCode(pParse, pC->pExpr, pC->iMem); + } + pAggInfo->directMode = 0; + sqlite3ExprCacheClear(pParse); +} + +/* +** Add a single OP_Explain instruction to the VDBE to explain a simple +** count(*) query ("SELECT count(*) FROM pTab"). +*/ +#ifndef SQLITE_OMIT_EXPLAIN +static void explainSimpleCount( + Parse *pParse, /* Parse context */ + Table *pTab, /* Table being queried */ + Index *pIdx /* Index used to optimize scan, or NULL */ +){ + if( pParse->explain==2 ){ + char *zEqp = sqlite3MPrintf(pParse->db, "SCAN TABLE %s %s%s(~%d rows)", + pTab->zName, + pIdx ? "USING COVERING INDEX " : "", + pIdx ? pIdx->zName : "", + pTab->nRowEst + ); + sqlite3VdbeAddOp4( + pParse->pVdbe, OP_Explain, pParse->iSelectId, 0, 0, zEqp, P4_DYNAMIC + ); + } +} +#else +# define explainSimpleCount(a,b,c) +#endif + +/* +** Generate code for the SELECT statement given in the p argument. +** +** The results are distributed in various ways depending on the +** contents of the SelectDest structure pointed to by argument pDest +** as follows: +** +** pDest->eDest Result +** ------------ ------------------------------------------- +** SRT_Output Generate a row of output (using the OP_ResultRow +** opcode) for each row in the result set. +** +** SRT_Mem Only valid if the result is a single column. +** Store the first column of the first result row +** in register pDest->iParm then abandon the rest +** of the query. This destination implies "LIMIT 1". +** +** SRT_Set The result must be a single column. Store each +** row of result as the key in table pDest->iParm. +** Apply the affinity pDest->affinity before storing +** results. Used to implement "IN (SELECT ...)". +** +** SRT_Union Store results as a key in a temporary table pDest->iParm. +** +** SRT_Except Remove results from the temporary table pDest->iParm. +** +** SRT_Table Store results in temporary table pDest->iParm. +** This is like SRT_EphemTab except that the table +** is assumed to already be open. +** +** SRT_EphemTab Create an temporary table pDest->iParm and store +** the result there. The cursor is left open after +** returning. This is like SRT_Table except that +** this destination uses OP_OpenEphemeral to create +** the table first. +** +** SRT_Coroutine Generate a co-routine that returns a new row of +** results each time it is invoked. The entry point +** of the co-routine is stored in register pDest->iParm. +** +** SRT_Exists Store a 1 in memory cell pDest->iParm if the result +** set is not empty. +** +** SRT_Discard Throw the results away. This is used by SELECT +** statements within triggers whose only purpose is +** the side-effects of functions. +** +** This routine returns the number of errors. If any errors are +** encountered, then an appropriate error message is left in +** pParse->zErrMsg. +** +** This routine does NOT free the Select structure passed in. The +** calling function needs to do that. +*/ +int sqlite3Select( + Parse *pParse, /* The parser context */ + Select *p, /* The SELECT statement being coded. */ + SelectDest *pDest /* What to do with the query results */ +){ + int i, j; /* Loop counters */ + WhereInfo *pWInfo; /* Return from sqlite3WhereBegin() */ + Vdbe *v; /* The virtual machine under construction */ + int isAgg; /* True for select lists like "count(*)" */ + ExprList *pEList; /* List of columns to extract. */ + SrcList *pTabList; /* List of tables to select from */ + Expr *pWhere; /* The WHERE clause. May be NULL */ + ExprList *pOrderBy; /* The ORDER BY clause. May be NULL */ + ExprList *pGroupBy; /* The GROUP BY clause. May be NULL */ + Expr *pHaving; /* The HAVING clause. May be NULL */ + int isDistinct; /* True if the DISTINCT keyword is present */ + int distinct; /* Table to use for the distinct set */ + int rc = 1; /* Value to return from this function */ + int addrSortIndex; /* Address of an OP_OpenEphemeral instruction */ + int addrDistinctIndex; /* Address of an OP_OpenEphemeral instruction */ + AggInfo sAggInfo; /* Information used by aggregate queries */ + int iEnd; /* Address of the end of the query */ + sqlite3 *db; /* The database connection */ + +#ifndef SQLITE_OMIT_EXPLAIN + int iRestoreSelectId = pParse->iSelectId; + pParse->iSelectId = pParse->iNextSelectId++; +#endif + + db = pParse->db; + if( p==0 || db->mallocFailed || pParse->nErr ){ + return 1; + } + if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; + memset(&sAggInfo, 0, sizeof(sAggInfo)); + + if( IgnorableOrderby(pDest) ){ + assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union || + pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard); + /* If ORDER BY makes no difference in the output then neither does + ** DISTINCT so it can be removed too. */ + sqlite3ExprListDelete(db, p->pOrderBy); + p->pOrderBy = 0; + p->selFlags &= ~SF_Distinct; + } + sqlite3SelectPrep(pParse, p, 0); + pOrderBy = p->pOrderBy; + pTabList = p->pSrc; + pEList = p->pEList; + if( pParse->nErr || db->mallocFailed ){ + goto select_end; + } + isAgg = (p->selFlags & SF_Aggregate)!=0; + assert( pEList!=0 ); + + /* Begin generating code. + */ + v = sqlite3GetVdbe(pParse); + if( v==0 ) goto select_end; + + /* If writing to memory or generating a set + ** only a single column may be output. + */ +#ifndef SQLITE_OMIT_SUBQUERY + if( checkForMultiColumnSelectError(pParse, pDest, pEList->nExpr) ){ + goto select_end; + } +#endif + + /* Generate code for all sub-queries in the FROM clause + */ +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) + for(i=0; !p->pPrior && inSrc; i++){ + struct SrcList_item *pItem = &pTabList->a[i]; + SelectDest dest; + Select *pSub = pItem->pSelect; + int isAggSub; + + if( pSub==0 ) continue; + if( pItem->addrFillSub ){ + sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub); + continue; + } + + /* Increment Parse.nHeight by the height of the largest expression + ** tree refered to by this, the parent select. The child select + ** may contain expression trees of at most + ** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit + ** more conservative than necessary, but much easier than enforcing + ** an exact limit. + */ + pParse->nHeight += sqlite3SelectExprHeight(p); + + isAggSub = (pSub->selFlags & SF_Aggregate)!=0; + if( flattenSubquery(pParse, p, i, isAgg, isAggSub) ){ + /* This subquery can be absorbed into its parent. */ + if( isAggSub ){ + isAgg = 1; + p->selFlags |= SF_Aggregate; + } + i = -1; + }else{ + /* Generate a subroutine that will fill an ephemeral table with + ** the content of this subquery. pItem->addrFillSub will point + ** to the address of the generated subroutine. pItem->regReturn + ** is a register allocated to hold the subroutine return address + */ + int topAddr; + int onceAddr = 0; + int retAddr; + assert( pItem->addrFillSub==0 ); + pItem->regReturn = ++pParse->nMem; + topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn); + pItem->addrFillSub = topAddr+1; + VdbeNoopComment((v, "materialize %s", pItem->pTab->zName)); + if( pItem->isCorrelated==0 ){ + /* If the subquery is no correlated and if we are not inside of + ** a trigger, then we only need to compute the value of the subquery + ** once. */ + onceAddr = sqlite3CodeOnce(pParse); + } + sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); + explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); + sqlite3Select(pParse, pSub, &dest); + pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow; + if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr); + retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn); + VdbeComment((v, "end %s", pItem->pTab->zName)); + sqlite3VdbeChangeP1(v, topAddr, retAddr); + sqlite3ClearTempRegCache(pParse); + } + if( /*pParse->nErr ||*/ db->mallocFailed ){ + goto select_end; + } + pParse->nHeight -= sqlite3SelectExprHeight(p); + pTabList = p->pSrc; + if( !IgnorableOrderby(pDest) ){ + pOrderBy = p->pOrderBy; + } + } + pEList = p->pEList; +#endif + pWhere = p->pWhere; + pGroupBy = p->pGroupBy; + pHaving = p->pHaving; + isDistinct = (p->selFlags & SF_Distinct)!=0; + +#ifndef SQLITE_OMIT_COMPOUND_SELECT + /* If there is are a sequence of queries, do the earlier ones first. + */ + if( p->pPrior ){ + if( p->pRightmost==0 ){ + Select *pLoop, *pRight = 0; + int cnt = 0; + int mxSelect; + for(pLoop=p; pLoop; pLoop=pLoop->pPrior, cnt++){ + pLoop->pRightmost = p; + pLoop->pNext = pRight; + pRight = pLoop; + } + mxSelect = db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT]; + if( mxSelect && cnt>mxSelect ){ + sqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); + goto select_end; + } + } + rc = multiSelect(pParse, p, pDest); + explainSetInteger(pParse->iSelectId, iRestoreSelectId); + return rc; + } +#endif + + /* If there is both a GROUP BY and an ORDER BY clause and they are + ** identical, then disable the ORDER BY clause since the GROUP BY + ** will cause elements to come out in the correct order. This is + ** an optimization - the correct answer should result regardless. + ** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER + ** to disable this optimization for testing purposes. + */ + if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy)==0 + && (db->flags & SQLITE_GroupByOrder)==0 ){ + pOrderBy = 0; + } + + /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and + ** if the select-list is the same as the ORDER BY list, then this query + ** can be rewritten as a GROUP BY. In other words, this: + ** + ** SELECT DISTINCT xyz FROM ... ORDER BY xyz + ** + ** is transformed to: + ** + ** SELECT xyz FROM ... GROUP BY xyz + ** + ** The second form is preferred as a single index (or temp-table) may be + ** used for both the ORDER BY and DISTINCT processing. As originally + ** written the query must use a temp-table for at least one of the ORDER + ** BY and DISTINCT, and an index or separate temp-table for the other. + */ + if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct + && sqlite3ExprListCompare(pOrderBy, p->pEList)==0 + ){ + p->selFlags &= ~SF_Distinct; + p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0); + pGroupBy = p->pGroupBy; + pOrderBy = 0; + } + + /* If there is an ORDER BY clause, then this sorting + ** index might end up being unused if the data can be + ** extracted in pre-sorted order. If that is the case, then the + ** OP_OpenEphemeral instruction will be changed to an OP_Noop once + ** we figure out that the sorting index is not needed. The addrSortIndex + ** variable is used to facilitate that change. + */ + if( pOrderBy ){ + KeyInfo *pKeyInfo; + pKeyInfo = keyInfoFromExprList(pParse, pOrderBy); + pOrderBy->iECursor = pParse->nTab++; + p->addrOpenEphm[2] = addrSortIndex = + sqlite3VdbeAddOp4(v, OP_OpenEphemeral, + pOrderBy->iECursor, pOrderBy->nExpr+2, 0, + (char*)pKeyInfo, P4_KEYINFO_HANDOFF); + }else{ + addrSortIndex = -1; + } + + /* If the output is destined for a temporary table, open that table. + */ + if( pDest->eDest==SRT_EphemTab ){ + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iParm, pEList->nExpr); + } + + /* Set the limiter. + */ + iEnd = sqlite3VdbeMakeLabel(v); + p->nSelectRow = (double)LARGEST_INT64; + computeLimitRegisters(pParse, p, iEnd); + if( p->iLimit==0 && addrSortIndex>=0 ){ + sqlite3VdbeGetOp(v, addrSortIndex)->opcode = OP_SorterOpen; + p->selFlags |= SF_UseSorter; + } + + /* Open a virtual index to use for the distinct set. + */ + if( p->selFlags & SF_Distinct ){ + KeyInfo *pKeyInfo; + distinct = pParse->nTab++; + pKeyInfo = keyInfoFromExprList(pParse, p->pEList); + addrDistinctIndex = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, distinct, 0, 0, + (char*)pKeyInfo, P4_KEYINFO_HANDOFF); + sqlite3VdbeChangeP5(v, BTREE_UNORDERED); + }else{ + distinct = addrDistinctIndex = -1; + } + + /* Aggregate and non-aggregate queries are handled differently */ + if( !isAgg && pGroupBy==0 ){ + ExprList *pDist = (isDistinct ? p->pEList : 0); + + /* Begin the database scan. */ + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pOrderBy, pDist, 0); + if( pWInfo==0 ) goto select_end; + if( pWInfo->nRowOut < p->nSelectRow ) p->nSelectRow = pWInfo->nRowOut; + + /* If sorting index that was created by a prior OP_OpenEphemeral + ** instruction ended up not being needed, then change the OP_OpenEphemeral + ** into an OP_Noop. + */ + if( addrSortIndex>=0 && pOrderBy==0 ){ + sqlite3VdbeChangeToNoop(v, addrSortIndex); + p->addrOpenEphm[2] = -1; + } + + if( pWInfo->eDistinct ){ + VdbeOp *pOp; /* No longer required OpenEphemeral instr. */ + + assert( addrDistinctIndex>=0 ); + pOp = sqlite3VdbeGetOp(v, addrDistinctIndex); + + assert( isDistinct ); + assert( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED + || pWInfo->eDistinct==WHERE_DISTINCT_UNIQUE + ); + distinct = -1; + if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED ){ + int iJump; + int iExpr; + int iFlag = ++pParse->nMem; + int iBase = pParse->nMem+1; + int iBase2 = iBase + pEList->nExpr; + pParse->nMem += (pEList->nExpr*2); + + /* Change the OP_OpenEphemeral coded earlier to an OP_Integer. The + ** OP_Integer initializes the "first row" flag. */ + pOp->opcode = OP_Integer; + pOp->p1 = 1; + pOp->p2 = iFlag; + + sqlite3ExprCodeExprList(pParse, pEList, iBase, 1); + iJump = sqlite3VdbeCurrentAddr(v) + 1 + pEList->nExpr + 1 + 1; + sqlite3VdbeAddOp2(v, OP_If, iFlag, iJump-1); + for(iExpr=0; iExprnExpr; iExpr++){ + CollSeq *pColl = sqlite3ExprCollSeq(pParse, pEList->a[iExpr].pExpr); + sqlite3VdbeAddOp3(v, OP_Ne, iBase+iExpr, iJump, iBase2+iExpr); + sqlite3VdbeChangeP4(v, -1, (const char *)pColl, P4_COLLSEQ); + sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); + } + sqlite3VdbeAddOp2(v, OP_Goto, 0, pWInfo->iContinue); + + sqlite3VdbeAddOp2(v, OP_Integer, 0, iFlag); + assert( sqlite3VdbeCurrentAddr(v)==iJump ); + sqlite3VdbeAddOp3(v, OP_Move, iBase, iBase2, pEList->nExpr); + }else{ + pOp->opcode = OP_Noop; + } + } + + /* Use the standard inner loop. */ + selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinct, pDest, + pWInfo->iContinue, pWInfo->iBreak); + + /* End the database scan loop. + */ + sqlite3WhereEnd(pWInfo); + }else{ + /* This is the processing for aggregate queries */ + NameContext sNC; /* Name context for processing aggregate information */ + int iAMem; /* First Mem address for storing current GROUP BY */ + int iBMem; /* First Mem address for previous GROUP BY */ + int iUseFlag; /* Mem address holding flag indicating that at least + ** one row of the input to the aggregator has been + ** processed */ + int iAbortFlag; /* Mem address which causes query abort if positive */ + int groupBySort; /* Rows come from source in GROUP BY order */ + int addrEnd; /* End of processing for this SELECT */ + int sortPTab = 0; /* Pseudotable used to decode sorting results */ + int sortOut = 0; /* Output register from the sorter */ + + /* Remove any and all aliases between the result set and the + ** GROUP BY clause. + */ + if( pGroupBy ){ + int k; /* Loop counter */ + struct ExprList_item *pItem; /* For looping over expression in a list */ + + for(k=p->pEList->nExpr, pItem=p->pEList->a; k>0; k--, pItem++){ + pItem->iAlias = 0; + } + for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){ + pItem->iAlias = 0; + } + if( p->nSelectRow>(double)100 ) p->nSelectRow = (double)100; + }else{ + p->nSelectRow = (double)1; + } + + + /* Create a label to jump to when we want to abort the query */ + addrEnd = sqlite3VdbeMakeLabel(v); + + /* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in + ** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the + ** SELECT statement. + */ + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + sNC.pSrcList = pTabList; + sNC.pAggInfo = &sAggInfo; + sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr+1 : 0; + sAggInfo.pGroupBy = pGroupBy; + sqlite3ExprAnalyzeAggList(&sNC, pEList); + sqlite3ExprAnalyzeAggList(&sNC, pOrderBy); + if( pHaving ){ + sqlite3ExprAnalyzeAggregates(&sNC, pHaving); + } + sAggInfo.nAccumulator = sAggInfo.nColumn; + for(i=0; ix.pList); + } + if( db->mallocFailed ) goto select_end; + + /* Processing for aggregates with GROUP BY is very different and + ** much more complex than aggregates without a GROUP BY. + */ + if( pGroupBy ){ + KeyInfo *pKeyInfo; /* Keying information for the group by clause */ + int j1; /* A-vs-B comparision jump */ + int addrOutputRow; /* Start of subroutine that outputs a result row */ + int regOutputRow; /* Return address register for output subroutine */ + int addrSetAbort; /* Set the abort flag and return */ + int addrTopOfLoop; /* Top of the input loop */ + int addrSortingIdx; /* The OP_OpenEphemeral for the sorting index */ + int addrReset; /* Subroutine for resetting the accumulator */ + int regReset; /* Return address register for reset subroutine */ + + /* If there is a GROUP BY clause we might need a sorting index to + ** implement it. Allocate that sorting index now. If it turns out + ** that we do not need it after all, the OP_SorterOpen instruction + ** will be converted into a Noop. + */ + sAggInfo.sortingIdx = pParse->nTab++; + pKeyInfo = keyInfoFromExprList(pParse, pGroupBy); + addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen, + sAggInfo.sortingIdx, sAggInfo.nSortingColumn, + 0, (char*)pKeyInfo, P4_KEYINFO_HANDOFF); + + /* Initialize memory locations used by GROUP BY aggregate processing + */ + iUseFlag = ++pParse->nMem; + iAbortFlag = ++pParse->nMem; + regOutputRow = ++pParse->nMem; + addrOutputRow = sqlite3VdbeMakeLabel(v); + regReset = ++pParse->nMem; + addrReset = sqlite3VdbeMakeLabel(v); + iAMem = pParse->nMem + 1; + pParse->nMem += pGroupBy->nExpr; + iBMem = pParse->nMem + 1; + pParse->nMem += pGroupBy->nExpr; + sqlite3VdbeAddOp2(v, OP_Integer, 0, iAbortFlag); + VdbeComment((v, "clear abort flag")); + sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag); + VdbeComment((v, "indicate accumulator empty")); + sqlite3VdbeAddOp3(v, OP_Null, 0, iAMem, iAMem+pGroupBy->nExpr-1); + + /* Begin a loop that will extract all source rows in GROUP BY order. + ** This might involve two separate loops with an OP_Sort in between, or + ** it might be a single loop that uses an index to extract information + ** in the right order to begin with. + */ + sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pGroupBy, 0, 0); + if( pWInfo==0 ) goto select_end; + if( pGroupBy==0 ){ + /* The optimizer is able to deliver rows in group by order so + ** we do not have to sort. The OP_OpenEphemeral table will be + ** cancelled later because we still need to use the pKeyInfo + */ + pGroupBy = p->pGroupBy; + groupBySort = 0; + }else{ + /* Rows are coming out in undetermined order. We have to push + ** each row into a sorting index, terminate the first loop, + ** then loop over the sorting index in order to get the output + ** in sorted order + */ + int regBase; + int regRecord; + int nCol; + int nGroupBy; + + explainTempTable(pParse, + isDistinct && !(p->selFlags&SF_Distinct)?"DISTINCT":"GROUP BY"); + + groupBySort = 1; + nGroupBy = pGroupBy->nExpr; + nCol = nGroupBy + 1; + j = nGroupBy+1; + for(i=0; i=j ){ + nCol++; + j++; + } + } + regBase = sqlite3GetTempRange(pParse, nCol); + sqlite3ExprCacheClear(pParse); + sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0); + sqlite3VdbeAddOp2(v, OP_Sequence, sAggInfo.sortingIdx,regBase+nGroupBy); + j = nGroupBy+1; + for(i=0; iiSorterColumn>=j ){ + int r1 = j + regBase; + int r2; + + r2 = sqlite3ExprCodeGetColumn(pParse, + pCol->pTab, pCol->iColumn, pCol->iTable, r1); + if( r1!=r2 ){ + sqlite3VdbeAddOp2(v, OP_SCopy, r2, r1); + } + j++; + } + } + regRecord = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord); + sqlite3VdbeAddOp2(v, OP_SorterInsert, sAggInfo.sortingIdx, regRecord); + sqlite3ReleaseTempReg(pParse, regRecord); + sqlite3ReleaseTempRange(pParse, regBase, nCol); + sqlite3WhereEnd(pWInfo); + sAggInfo.sortingIdxPTab = sortPTab = pParse->nTab++; + sortOut = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol); + sqlite3VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd); + VdbeComment((v, "GROUP BY sort")); + sAggInfo.useSortingIdx = 1; + sqlite3ExprCacheClear(pParse); + } + + /* Evaluate the current GROUP BY terms and store in b0, b1, b2... + ** (b0 is memory location iBMem+0, b1 is iBMem+1, and so forth) + ** Then compare the current GROUP BY terms against the GROUP BY terms + ** from the previous row currently stored in a0, a1, a2... + */ + addrTopOfLoop = sqlite3VdbeCurrentAddr(v); + sqlite3ExprCacheClear(pParse); + if( groupBySort ){ + sqlite3VdbeAddOp2(v, OP_SorterData, sAggInfo.sortingIdx, sortOut); + } + for(j=0; jnExpr; j++){ + if( groupBySort ){ + sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j); + if( j==0 ) sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE); + }else{ + sAggInfo.directMode = 1; + sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j); + } + } + sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr, + (char*)pKeyInfo, P4_KEYINFO); + j1 = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp3(v, OP_Jump, j1+1, 0, j1+1); + + /* Generate code that runs whenever the GROUP BY changes. + ** Changes in the GROUP BY are detected by the previous code + ** block. If there were no changes, this block is skipped. + ** + ** This code copies current group by terms in b0,b1,b2,... + ** over to a0,a1,a2. It then calls the output subroutine + ** and resets the aggregate accumulator registers in preparation + ** for the next GROUP BY batch. + */ + sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr); + sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); + VdbeComment((v, "output one row")); + sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd); + VdbeComment((v, "check abort flag")); + sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); + VdbeComment((v, "reset accumulator")); + + /* Update the aggregate accumulators based on the content of + ** the current row + */ + sqlite3VdbeJumpHere(v, j1); + updateAccumulator(pParse, &sAggInfo); + sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag); + VdbeComment((v, "indicate data in accumulator")); + + /* End of the loop + */ + if( groupBySort ){ + sqlite3VdbeAddOp2(v, OP_SorterNext, sAggInfo.sortingIdx, addrTopOfLoop); + }else{ + sqlite3WhereEnd(pWInfo); + sqlite3VdbeChangeToNoop(v, addrSortingIdx); + } + + /* Output the final row of result + */ + sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); + VdbeComment((v, "output final row")); + + /* Jump over the subroutines + */ + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEnd); + + /* Generate a subroutine that outputs a single row of the result + ** set. This subroutine first looks at the iUseFlag. If iUseFlag + ** is less than or equal to zero, the subroutine is a no-op. If + ** the processing calls for the query to abort, this subroutine + ** increments the iAbortFlag memory location before returning in + ** order to signal the caller to abort. + */ + addrSetAbort = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_Integer, 1, iAbortFlag); + VdbeComment((v, "set abort flag")); + sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); + sqlite3VdbeResolveLabel(v, addrOutputRow); + addrOutputRow = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2); + VdbeComment((v, "Groupby result generator entry point")); + sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); + finalizeAggFunctions(pParse, &sAggInfo); + sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL); + selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy, + distinct, pDest, + addrOutputRow+1, addrSetAbort); + sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); + VdbeComment((v, "end groupby result generator")); + + /* Generate a subroutine that will reset the group-by accumulator + */ + sqlite3VdbeResolveLabel(v, addrReset); + resetAccumulator(pParse, &sAggInfo); + sqlite3VdbeAddOp1(v, OP_Return, regReset); + + } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */ + else { + ExprList *pDel = 0; +#ifndef SQLITE_OMIT_BTREECOUNT + Table *pTab; + if( (pTab = isSimpleCount(p, &sAggInfo))!=0 ){ + /* If isSimpleCount() returns a pointer to a Table structure, then + ** the SQL statement is of the form: + ** + ** SELECT count(*) FROM + ** + ** where the Table structure returned represents table . + ** + ** This statement is so common that it is optimized specially. The + ** OP_Count instruction is executed either on the intkey table that + ** contains the data for table or on one of its indexes. It + ** is better to execute the op on an index, as indexes are almost + ** always spread across less pages than their corresponding tables. + */ + const int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + const int iCsr = pParse->nTab++; /* Cursor to scan b-tree */ + Index *pIdx; /* Iterator variable */ + KeyInfo *pKeyInfo = 0; /* Keyinfo for scanned index */ + Index *pBest = 0; /* Best index found so far */ + int iRoot = pTab->tnum; /* Root page of scanned b-tree */ + + sqlite3CodeVerifySchema(pParse, iDb); + sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); + + /* Search for the index that has the least amount of columns. If + ** there is such an index, and it has less columns than the table + ** does, then we can assume that it consumes less space on disk and + ** will therefore be cheaper to scan to determine the query result. + ** In this case set iRoot to the root page number of the index b-tree + ** and pKeyInfo to the KeyInfo structure required to navigate the + ** index. + ** + ** (2011-04-15) Do not do a full scan of an unordered index. + ** + ** In practice the KeyInfo structure will not be used. It is only + ** passed to keep OP_OpenRead happy. + */ + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + if( pIdx->bUnordered==0 && (!pBest || pIdx->nColumnnColumn) ){ + pBest = pIdx; + } + } + if( pBest && pBest->nColumnnCol ){ + iRoot = pBest->tnum; + pKeyInfo = sqlite3IndexKeyinfo(pParse, pBest); + } + + /* Open a read-only cursor, execute the OP_Count, close the cursor. */ + sqlite3VdbeAddOp3(v, OP_OpenRead, iCsr, iRoot, iDb); + if( pKeyInfo ){ + sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO_HANDOFF); + } + sqlite3VdbeAddOp2(v, OP_Count, iCsr, sAggInfo.aFunc[0].iMem); + sqlite3VdbeAddOp1(v, OP_Close, iCsr); + explainSimpleCount(pParse, pTab, pBest); + }else +#endif /* SQLITE_OMIT_BTREECOUNT */ + { + /* Check if the query is of one of the following forms: + ** + ** SELECT min(x) FROM ... + ** SELECT max(x) FROM ... + ** + ** If it is, then ask the code in where.c to attempt to sort results + ** as if there was an "ORDER ON x" or "ORDER ON x DESC" clause. + ** If where.c is able to produce results sorted in this order, then + ** add vdbe code to break out of the processing loop after the + ** first iteration (since the first iteration of the loop is + ** guaranteed to operate on the row with the minimum or maximum + ** value of x, the only row required). + ** + ** A special flag must be passed to sqlite3WhereBegin() to slightly + ** modify behaviour as follows: + ** + ** + If the query is a "SELECT min(x)", then the loop coded by + ** where.c should not iterate over any values with a NULL value + ** for x. + ** + ** + The optimizer code in where.c (the thing that decides which + ** index or indices to use) should place a different priority on + ** satisfying the 'ORDER BY' clause than it does in other cases. + ** Refer to code and comments in where.c for details. + */ + ExprList *pMinMax = 0; + u8 flag = minMaxQuery(p); + if( flag ){ + assert( !ExprHasProperty(p->pEList->a[0].pExpr, EP_xIsSelect) ); + pMinMax = sqlite3ExprListDup(db, p->pEList->a[0].pExpr->x.pList,0); + pDel = pMinMax; + if( pMinMax && !db->mallocFailed ){ + pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0; + pMinMax->a[0].pExpr->op = TK_COLUMN; + } + } + + /* This case runs if the aggregate has no GROUP BY clause. The + ** processing is much simpler since there is only a single row + ** of output. + */ + resetAccumulator(pParse, &sAggInfo); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pMinMax, 0, flag); + if( pWInfo==0 ){ + sqlite3ExprListDelete(db, pDel); + goto select_end; + } + updateAccumulator(pParse, &sAggInfo); + if( !pMinMax && flag ){ + sqlite3VdbeAddOp2(v, OP_Goto, 0, pWInfo->iBreak); + VdbeComment((v, "%s() by index", + (flag==WHERE_ORDERBY_MIN?"min":"max"))); + } + sqlite3WhereEnd(pWInfo); + finalizeAggFunctions(pParse, &sAggInfo); + } + + pOrderBy = 0; + sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL); + selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, -1, + pDest, addrEnd, addrEnd); + sqlite3ExprListDelete(db, pDel); + } + sqlite3VdbeResolveLabel(v, addrEnd); + + } /* endif aggregate query */ + + if( distinct>=0 ){ + explainTempTable(pParse, "DISTINCT"); + } + + /* If there is an ORDER BY clause, then we need to sort the results + ** and send them to the callback one by one. + */ + if( pOrderBy ){ + explainTempTable(pParse, "ORDER BY"); + generateSortTail(pParse, p, v, pEList->nExpr, pDest); + } + + /* Jump here to skip this query + */ + sqlite3VdbeResolveLabel(v, iEnd); + + /* The SELECT was successfully coded. Set the return code to 0 + ** to indicate no errors. + */ + rc = 0; + + /* Control jumps to here if an error is encountered above, or upon + ** successful coding of the SELECT. + */ +select_end: + explainSetInteger(pParse->iSelectId, iRestoreSelectId); + + /* Identify column names if results of the SELECT are to be output. + */ + if( rc==SQLITE_OK && pDest->eDest==SRT_Output ){ + generateColumnNames(pParse, pTabList, pEList); + } + + sqlite3DbFree(db, sAggInfo.aCol); + sqlite3DbFree(db, sAggInfo.aFunc); + return rc; +} + +#if defined(SQLITE_ENABLE_TREE_EXPLAIN) +/* +** Generate a human-readable description of a the Select object. +*/ +static void explainOneSelect(Vdbe *pVdbe, Select *p){ + sqlite3ExplainPrintf(pVdbe, "SELECT "); + if( p->selFlags & (SF_Distinct|SF_Aggregate) ){ + if( p->selFlags & SF_Distinct ){ + sqlite3ExplainPrintf(pVdbe, "DISTINCT "); + } + if( p->selFlags & SF_Aggregate ){ + sqlite3ExplainPrintf(pVdbe, "agg_flag "); + } + sqlite3ExplainNL(pVdbe); + sqlite3ExplainPrintf(pVdbe, " "); + } + sqlite3ExplainExprList(pVdbe, p->pEList); + sqlite3ExplainNL(pVdbe); + if( p->pSrc && p->pSrc->nSrc ){ + int i; + sqlite3ExplainPrintf(pVdbe, "FROM "); + sqlite3ExplainPush(pVdbe); + for(i=0; ipSrc->nSrc; i++){ + struct SrcList_item *pItem = &p->pSrc->a[i]; + sqlite3ExplainPrintf(pVdbe, "{%d,*} = ", pItem->iCursor); + if( pItem->pSelect ){ + sqlite3ExplainSelect(pVdbe, pItem->pSelect); + if( pItem->pTab ){ + sqlite3ExplainPrintf(pVdbe, " (tabname=%s)", pItem->pTab->zName); + } + }else if( pItem->zName ){ + sqlite3ExplainPrintf(pVdbe, "%s", pItem->zName); + } + if( pItem->zAlias ){ + sqlite3ExplainPrintf(pVdbe, " (AS %s)", pItem->zAlias); + } + if( pItem->jointype & JT_LEFT ){ + sqlite3ExplainPrintf(pVdbe, " LEFT-JOIN"); + } + sqlite3ExplainNL(pVdbe); + } + sqlite3ExplainPop(pVdbe); + } + if( p->pWhere ){ + sqlite3ExplainPrintf(pVdbe, "WHERE "); + sqlite3ExplainExpr(pVdbe, p->pWhere); + sqlite3ExplainNL(pVdbe); + } + if( p->pGroupBy ){ + sqlite3ExplainPrintf(pVdbe, "GROUPBY "); + sqlite3ExplainExprList(pVdbe, p->pGroupBy); + sqlite3ExplainNL(pVdbe); + } + if( p->pHaving ){ + sqlite3ExplainPrintf(pVdbe, "HAVING "); + sqlite3ExplainExpr(pVdbe, p->pHaving); + sqlite3ExplainNL(pVdbe); + } + if( p->pOrderBy ){ + sqlite3ExplainPrintf(pVdbe, "ORDERBY "); + sqlite3ExplainExprList(pVdbe, p->pOrderBy); + sqlite3ExplainNL(pVdbe); + } + if( p->pLimit ){ + sqlite3ExplainPrintf(pVdbe, "LIMIT "); + sqlite3ExplainExpr(pVdbe, p->pLimit); + sqlite3ExplainNL(pVdbe); + } + if( p->pOffset ){ + sqlite3ExplainPrintf(pVdbe, "OFFSET "); + sqlite3ExplainExpr(pVdbe, p->pOffset); + sqlite3ExplainNL(pVdbe); + } +} +void sqlite3ExplainSelect(Vdbe *pVdbe, Select *p){ + if( p==0 ){ + sqlite3ExplainPrintf(pVdbe, "(null-select)"); + return; + } + while( p->pPrior ) p = p->pPrior; + sqlite3ExplainPush(pVdbe); + while( p ){ + explainOneSelect(pVdbe, p); + p = p->pNext; + if( p==0 ) break; + sqlite3ExplainNL(pVdbe); + sqlite3ExplainPrintf(pVdbe, "%s\n", selectOpName(p->op)); + } + sqlite3ExplainPrintf(pVdbe, "END"); + sqlite3ExplainPop(pVdbe); +} + +/* End of the structure debug printing code +*****************************************************************************/ +#endif /* defined(SQLITE_TEST) || defined(SQLITE_DEBUG) */ diff --git a/scalos/libraries/sqlite/src/sqlite3ext.h b/scalos/libraries/sqlite/src/sqlite3ext.h new file mode 100644 index 000000000..5abcde2c8 --- /dev/null +++ b/scalos/libraries/sqlite/src/sqlite3ext.h @@ -0,0 +1,447 @@ +/* +** 2006 June 7 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This header file defines the SQLite interface for use by +** shared libraries that want to be imported as extensions into +** an SQLite instance. Shared libraries that intend to be loaded +** as extensions by SQLite should #include this file instead of +** sqlite3.h. +*/ +#ifndef _SQLITE3EXT_H_ +#define _SQLITE3EXT_H_ +#include "sqlite3.h" + +typedef struct sqlite3_api_routines sqlite3_api_routines; + +/* +** The following structure holds pointers to all of the SQLite API +** routines. +** +** WARNING: In order to maintain backwards compatibility, add new +** interfaces to the end of this structure only. If you insert new +** interfaces in the middle of this structure, then older different +** versions of SQLite will not be able to load each others' shared +** libraries! +*/ +struct sqlite3_api_routines { + void * (*aggregate_context)(sqlite3_context*,int nBytes); + int (*aggregate_count)(sqlite3_context*); + int (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*)); + int (*bind_double)(sqlite3_stmt*,int,double); + int (*bind_int)(sqlite3_stmt*,int,int); + int (*bind_int64)(sqlite3_stmt*,int,sqlite_int64); + int (*bind_null)(sqlite3_stmt*,int); + int (*bind_parameter_count)(sqlite3_stmt*); + int (*bind_parameter_index)(sqlite3_stmt*,const char*zName); + const char * (*bind_parameter_name)(sqlite3_stmt*,int); + int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*)); + int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*)); + int (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*); + int (*busy_handler)(sqlite3*,int(*)(void*,int),void*); + int (*busy_timeout)(sqlite3*,int ms); + int (*changes)(sqlite3*); + int (*close)(sqlite3*); + int (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*, + int eTextRep,const char*)); + int (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*, + int eTextRep,const void*)); + const void * (*column_blob)(sqlite3_stmt*,int iCol); + int (*column_bytes)(sqlite3_stmt*,int iCol); + int (*column_bytes16)(sqlite3_stmt*,int iCol); + int (*column_count)(sqlite3_stmt*pStmt); + const char * (*column_database_name)(sqlite3_stmt*,int); + const void * (*column_database_name16)(sqlite3_stmt*,int); + const char * (*column_decltype)(sqlite3_stmt*,int i); + const void * (*column_decltype16)(sqlite3_stmt*,int); + double (*column_double)(sqlite3_stmt*,int iCol); + int (*column_int)(sqlite3_stmt*,int iCol); + sqlite_int64 (*column_int64)(sqlite3_stmt*,int iCol); + const char * (*column_name)(sqlite3_stmt*,int); + const void * (*column_name16)(sqlite3_stmt*,int); + const char * (*column_origin_name)(sqlite3_stmt*,int); + const void * (*column_origin_name16)(sqlite3_stmt*,int); + const char * (*column_table_name)(sqlite3_stmt*,int); + const void * (*column_table_name16)(sqlite3_stmt*,int); + const unsigned char * (*column_text)(sqlite3_stmt*,int iCol); + const void * (*column_text16)(sqlite3_stmt*,int iCol); + int (*column_type)(sqlite3_stmt*,int iCol); + sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol); + void * (*commit_hook)(sqlite3*,int(*)(void*),void*); + int (*complete)(const char*sql); + int (*complete16)(const void*sql); + int (*create_collation)(sqlite3*,const char*,int,void*, + int(*)(void*,int,const void*,int,const void*)); + int (*create_collation16)(sqlite3*,const void*,int,void*, + int(*)(void*,int,const void*,int,const void*)); + int (*create_function)(sqlite3*,const char*,int,int,void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*)); + int (*create_function16)(sqlite3*,const void*,int,int,void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*)); + int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*); + int (*data_count)(sqlite3_stmt*pStmt); + sqlite3 * (*db_handle)(sqlite3_stmt*); + int (*declare_vtab)(sqlite3*,const char*); + int (*enable_shared_cache)(int); + int (*errcode)(sqlite3*db); + const char * (*errmsg)(sqlite3*); + const void * (*errmsg16)(sqlite3*); + int (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**); + int (*expired)(sqlite3_stmt*); + int (*finalize)(sqlite3_stmt*pStmt); + void (*free)(void*); + void (*free_table)(char**result); + int (*get_autocommit)(sqlite3*); + void * (*get_auxdata)(sqlite3_context*,int); + int (*get_table)(sqlite3*,const char*,char***,int*,int*,char**); + int (*global_recover)(void); + void (*interruptx)(sqlite3*); + sqlite_int64 (*last_insert_rowid)(sqlite3*); + const char * (*libversion)(void); + int (*libversion_number)(void); + void *(*malloc)(int); + char * (*mprintf)(const char*,...); + int (*open)(const char*,sqlite3**); + int (*open16)(const void*,sqlite3**); + int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); + int (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**); + void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*); + void (*progress_handler)(sqlite3*,int,int(*)(void*),void*); + void *(*realloc)(void*,int); + int (*reset)(sqlite3_stmt*pStmt); + void (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_double)(sqlite3_context*,double); + void (*result_error)(sqlite3_context*,const char*,int); + void (*result_error16)(sqlite3_context*,const void*,int); + void (*result_int)(sqlite3_context*,int); + void (*result_int64)(sqlite3_context*,sqlite_int64); + void (*result_null)(sqlite3_context*); + void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*)); + void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_value)(sqlite3_context*,sqlite3_value*); + void * (*rollback_hook)(sqlite3*,void(*)(void*),void*); + int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*, + const char*,const char*),void*); + void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*)); + char * (*snprintf)(int,char*,const char*,...); + int (*step)(sqlite3_stmt*); + int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*, + char const**,char const**,int*,int*,int*); + void (*thread_cleanup)(void); + int (*total_changes)(sqlite3*); + void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*); + int (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*); + void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*, + sqlite_int64),void*); + void * (*user_data)(sqlite3_context*); + const void * (*value_blob)(sqlite3_value*); + int (*value_bytes)(sqlite3_value*); + int (*value_bytes16)(sqlite3_value*); + double (*value_double)(sqlite3_value*); + int (*value_int)(sqlite3_value*); + sqlite_int64 (*value_int64)(sqlite3_value*); + int (*value_numeric_type)(sqlite3_value*); + const unsigned char * (*value_text)(sqlite3_value*); + const void * (*value_text16)(sqlite3_value*); + const void * (*value_text16be)(sqlite3_value*); + const void * (*value_text16le)(sqlite3_value*); + int (*value_type)(sqlite3_value*); + char *(*vmprintf)(const char*,va_list); + /* Added ??? */ + int (*overload_function)(sqlite3*, const char *zFuncName, int nArg); + /* Added by 3.3.13 */ + int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); + int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**); + int (*clear_bindings)(sqlite3_stmt*); + /* Added by 3.4.1 */ + int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*, + void (*xDestroy)(void *)); + /* Added by 3.5.0 */ + int (*bind_zeroblob)(sqlite3_stmt*,int,int); + int (*blob_bytes)(sqlite3_blob*); + int (*blob_close)(sqlite3_blob*); + int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64, + int,sqlite3_blob**); + int (*blob_read)(sqlite3_blob*,void*,int,int); + int (*blob_write)(sqlite3_blob*,const void*,int,int); + int (*create_collation_v2)(sqlite3*,const char*,int,void*, + int(*)(void*,int,const void*,int,const void*), + void(*)(void*)); + int (*file_control)(sqlite3*,const char*,int,void*); + sqlite3_int64 (*memory_highwater)(int); + sqlite3_int64 (*memory_used)(void); + sqlite3_mutex *(*mutex_alloc)(int); + void (*mutex_enter)(sqlite3_mutex*); + void (*mutex_free)(sqlite3_mutex*); + void (*mutex_leave)(sqlite3_mutex*); + int (*mutex_try)(sqlite3_mutex*); + int (*open_v2)(const char*,sqlite3**,int,const char*); + int (*release_memory)(int); + void (*result_error_nomem)(sqlite3_context*); + void (*result_error_toobig)(sqlite3_context*); + int (*sleep)(int); + void (*soft_heap_limit)(int); + sqlite3_vfs *(*vfs_find)(const char*); + int (*vfs_register)(sqlite3_vfs*,int); + int (*vfs_unregister)(sqlite3_vfs*); + int (*xthreadsafe)(void); + void (*result_zeroblob)(sqlite3_context*,int); + void (*result_error_code)(sqlite3_context*,int); + int (*test_control)(int, ...); + void (*randomness)(int,void*); + sqlite3 *(*context_db_handle)(sqlite3_context*); + int (*extended_result_codes)(sqlite3*,int); + int (*limit)(sqlite3*,int,int); + sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*); + const char *(*sql)(sqlite3_stmt*); + int (*status)(int,int*,int*,int); + int (*backup_finish)(sqlite3_backup*); + sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*); + int (*backup_pagecount)(sqlite3_backup*); + int (*backup_remaining)(sqlite3_backup*); + int (*backup_step)(sqlite3_backup*,int); + const char *(*compileoption_get)(int); + int (*compileoption_used)(const char*); + int (*create_function_v2)(sqlite3*,const char*,int,int,void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void(*xDestroy)(void*)); + int (*db_config)(sqlite3*,int,...); + sqlite3_mutex *(*db_mutex)(sqlite3*); + int (*db_status)(sqlite3*,int,int*,int*,int); + int (*extended_errcode)(sqlite3*); + void (*log)(int,const char*,...); + sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64); + const char *(*sourceid)(void); + int (*stmt_status)(sqlite3_stmt*,int,int); + int (*strnicmp)(const char*,const char*,int); + int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*); + int (*wal_autocheckpoint)(sqlite3*,int); + int (*wal_checkpoint)(sqlite3*,const char*); + void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*); + int (*blob_reopen)(sqlite3_blob*,sqlite3_int64); + int (*vtab_config)(sqlite3*,int op,...); + int (*vtab_on_conflict)(sqlite3*); +}; + +/* +** The following macros redefine the API routines so that they are +** redirected throught the global sqlite3_api structure. +** +** This header file is also used by the loadext.c source file +** (part of the main SQLite library - not an extension) so that +** it can get access to the sqlite3_api_routines structure +** definition. But the main library does not want to redefine +** the API. So the redefinition macros are only valid if the +** SQLITE_CORE macros is undefined. +*/ +#ifndef SQLITE_CORE +#define sqlite3_aggregate_context sqlite3_api->aggregate_context +#ifndef SQLITE_OMIT_DEPRECATED +#define sqlite3_aggregate_count sqlite3_api->aggregate_count +#endif +#define sqlite3_bind_blob sqlite3_api->bind_blob +#define sqlite3_bind_double sqlite3_api->bind_double +#define sqlite3_bind_int sqlite3_api->bind_int +#define sqlite3_bind_int64 sqlite3_api->bind_int64 +#define sqlite3_bind_null sqlite3_api->bind_null +#define sqlite3_bind_parameter_count sqlite3_api->bind_parameter_count +#define sqlite3_bind_parameter_index sqlite3_api->bind_parameter_index +#define sqlite3_bind_parameter_name sqlite3_api->bind_parameter_name +#define sqlite3_bind_text sqlite3_api->bind_text +#define sqlite3_bind_text16 sqlite3_api->bind_text16 +#define sqlite3_bind_value sqlite3_api->bind_value +#define sqlite3_busy_handler sqlite3_api->busy_handler +#define sqlite3_busy_timeout sqlite3_api->busy_timeout +#define sqlite3_changes sqlite3_api->changes +#define sqlite3_close sqlite3_api->close +#define sqlite3_collation_needed sqlite3_api->collation_needed +#define sqlite3_collation_needed16 sqlite3_api->collation_needed16 +#define sqlite3_column_blob sqlite3_api->column_blob +#define sqlite3_column_bytes sqlite3_api->column_bytes +#define sqlite3_column_bytes16 sqlite3_api->column_bytes16 +#define sqlite3_column_count sqlite3_api->column_count +#define sqlite3_column_database_name sqlite3_api->column_database_name +#define sqlite3_column_database_name16 sqlite3_api->column_database_name16 +#define sqlite3_column_decltype sqlite3_api->column_decltype +#define sqlite3_column_decltype16 sqlite3_api->column_decltype16 +#define sqlite3_column_double sqlite3_api->column_double +#define sqlite3_column_int sqlite3_api->column_int +#define sqlite3_column_int64 sqlite3_api->column_int64 +#define sqlite3_column_name sqlite3_api->column_name +#define sqlite3_column_name16 sqlite3_api->column_name16 +#define sqlite3_column_origin_name sqlite3_api->column_origin_name +#define sqlite3_column_origin_name16 sqlite3_api->column_origin_name16 +#define sqlite3_column_table_name sqlite3_api->column_table_name +#define sqlite3_column_table_name16 sqlite3_api->column_table_name16 +#define sqlite3_column_text sqlite3_api->column_text +#define sqlite3_column_text16 sqlite3_api->column_text16 +#define sqlite3_column_type sqlite3_api->column_type +#define sqlite3_column_value sqlite3_api->column_value +#define sqlite3_commit_hook sqlite3_api->commit_hook +#define sqlite3_complete sqlite3_api->complete +#define sqlite3_complete16 sqlite3_api->complete16 +#define sqlite3_create_collation sqlite3_api->create_collation +#define sqlite3_create_collation16 sqlite3_api->create_collation16 +#define sqlite3_create_function sqlite3_api->create_function +#define sqlite3_create_function16 sqlite3_api->create_function16 +#define sqlite3_create_module sqlite3_api->create_module +#define sqlite3_create_module_v2 sqlite3_api->create_module_v2 +#define sqlite3_data_count sqlite3_api->data_count +#define sqlite3_db_handle sqlite3_api->db_handle +#define sqlite3_declare_vtab sqlite3_api->declare_vtab +#define sqlite3_enable_shared_cache sqlite3_api->enable_shared_cache +#define sqlite3_errcode sqlite3_api->errcode +#define sqlite3_errmsg sqlite3_api->errmsg +#define sqlite3_errmsg16 sqlite3_api->errmsg16 +#define sqlite3_exec sqlite3_api->exec +#ifndef SQLITE_OMIT_DEPRECATED +#define sqlite3_expired sqlite3_api->expired +#endif +#define sqlite3_finalize sqlite3_api->finalize +#define sqlite3_free sqlite3_api->free +#define sqlite3_free_table sqlite3_api->free_table +#define sqlite3_get_autocommit sqlite3_api->get_autocommit +#define sqlite3_get_auxdata sqlite3_api->get_auxdata +#define sqlite3_get_table sqlite3_api->get_table +#ifndef SQLITE_OMIT_DEPRECATED +#define sqlite3_global_recover sqlite3_api->global_recover +#endif +#define sqlite3_interrupt sqlite3_api->interruptx +#define sqlite3_last_insert_rowid sqlite3_api->last_insert_rowid +#define sqlite3_libversion sqlite3_api->libversion +#define sqlite3_libversion_number sqlite3_api->libversion_number +#define sqlite3_malloc sqlite3_api->malloc +#define sqlite3_mprintf sqlite3_api->mprintf +#define sqlite3_open sqlite3_api->open +#define sqlite3_open16 sqlite3_api->open16 +#define sqlite3_prepare sqlite3_api->prepare +#define sqlite3_prepare16 sqlite3_api->prepare16 +#define sqlite3_prepare_v2 sqlite3_api->prepare_v2 +#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2 +#define sqlite3_profile sqlite3_api->profile +#define sqlite3_progress_handler sqlite3_api->progress_handler +#define sqlite3_realloc sqlite3_api->realloc +#define sqlite3_reset sqlite3_api->reset +#define sqlite3_result_blob sqlite3_api->result_blob +#define sqlite3_result_double sqlite3_api->result_double +#define sqlite3_result_error sqlite3_api->result_error +#define sqlite3_result_error16 sqlite3_api->result_error16 +#define sqlite3_result_int sqlite3_api->result_int +#define sqlite3_result_int64 sqlite3_api->result_int64 +#define sqlite3_result_null sqlite3_api->result_null +#define sqlite3_result_text sqlite3_api->result_text +#define sqlite3_result_text16 sqlite3_api->result_text16 +#define sqlite3_result_text16be sqlite3_api->result_text16be +#define sqlite3_result_text16le sqlite3_api->result_text16le +#define sqlite3_result_value sqlite3_api->result_value +#define sqlite3_rollback_hook sqlite3_api->rollback_hook +#define sqlite3_set_authorizer sqlite3_api->set_authorizer +#define sqlite3_set_auxdata sqlite3_api->set_auxdata +#define sqlite3_snprintf sqlite3_api->snprintf +#define sqlite3_step sqlite3_api->step +#define sqlite3_table_column_metadata sqlite3_api->table_column_metadata +#define sqlite3_thread_cleanup sqlite3_api->thread_cleanup +#define sqlite3_total_changes sqlite3_api->total_changes +#define sqlite3_trace sqlite3_api->trace +#ifndef SQLITE_OMIT_DEPRECATED +#define sqlite3_transfer_bindings sqlite3_api->transfer_bindings +#endif +#define sqlite3_update_hook sqlite3_api->update_hook +#define sqlite3_user_data sqlite3_api->user_data +#define sqlite3_value_blob sqlite3_api->value_blob +#define sqlite3_value_bytes sqlite3_api->value_bytes +#define sqlite3_value_bytes16 sqlite3_api->value_bytes16 +#define sqlite3_value_double sqlite3_api->value_double +#define sqlite3_value_int sqlite3_api->value_int +#define sqlite3_value_int64 sqlite3_api->value_int64 +#define sqlite3_value_numeric_type sqlite3_api->value_numeric_type +#define sqlite3_value_text sqlite3_api->value_text +#define sqlite3_value_text16 sqlite3_api->value_text16 +#define sqlite3_value_text16be sqlite3_api->value_text16be +#define sqlite3_value_text16le sqlite3_api->value_text16le +#define sqlite3_value_type sqlite3_api->value_type +#define sqlite3_vmprintf sqlite3_api->vmprintf +#define sqlite3_overload_function sqlite3_api->overload_function +#define sqlite3_prepare_v2 sqlite3_api->prepare_v2 +#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2 +#define sqlite3_clear_bindings sqlite3_api->clear_bindings +#define sqlite3_bind_zeroblob sqlite3_api->bind_zeroblob +#define sqlite3_blob_bytes sqlite3_api->blob_bytes +#define sqlite3_blob_close sqlite3_api->blob_close +#define sqlite3_blob_open sqlite3_api->blob_open +#define sqlite3_blob_read sqlite3_api->blob_read +#define sqlite3_blob_write sqlite3_api->blob_write +#define sqlite3_create_collation_v2 sqlite3_api->create_collation_v2 +#define sqlite3_file_control sqlite3_api->file_control +#define sqlite3_memory_highwater sqlite3_api->memory_highwater +#define sqlite3_memory_used sqlite3_api->memory_used +#define sqlite3_mutex_alloc sqlite3_api->mutex_alloc +#define sqlite3_mutex_enter sqlite3_api->mutex_enter +#define sqlite3_mutex_free sqlite3_api->mutex_free +#define sqlite3_mutex_leave sqlite3_api->mutex_leave +#define sqlite3_mutex_try sqlite3_api->mutex_try +#define sqlite3_open_v2 sqlite3_api->open_v2 +#define sqlite3_release_memory sqlite3_api->release_memory +#define sqlite3_result_error_nomem sqlite3_api->result_error_nomem +#define sqlite3_result_error_toobig sqlite3_api->result_error_toobig +#define sqlite3_sleep sqlite3_api->sleep +#define sqlite3_soft_heap_limit sqlite3_api->soft_heap_limit +#define sqlite3_vfs_find sqlite3_api->vfs_find +#define sqlite3_vfs_register sqlite3_api->vfs_register +#define sqlite3_vfs_unregister sqlite3_api->vfs_unregister +#define sqlite3_threadsafe sqlite3_api->xthreadsafe +#define sqlite3_result_zeroblob sqlite3_api->result_zeroblob +#define sqlite3_result_error_code sqlite3_api->result_error_code +#define sqlite3_test_control sqlite3_api->test_control +#define sqlite3_randomness sqlite3_api->randomness +#define sqlite3_context_db_handle sqlite3_api->context_db_handle +#define sqlite3_extended_result_codes sqlite3_api->extended_result_codes +#define sqlite3_limit sqlite3_api->limit +#define sqlite3_next_stmt sqlite3_api->next_stmt +#define sqlite3_sql sqlite3_api->sql +#define sqlite3_status sqlite3_api->status +#define sqlite3_backup_finish sqlite3_api->backup_finish +#define sqlite3_backup_init sqlite3_api->backup_init +#define sqlite3_backup_pagecount sqlite3_api->backup_pagecount +#define sqlite3_backup_remaining sqlite3_api->backup_remaining +#define sqlite3_backup_step sqlite3_api->backup_step +#define sqlite3_compileoption_get sqlite3_api->compileoption_get +#define sqlite3_compileoption_used sqlite3_api->compileoption_used +#define sqlite3_create_function_v2 sqlite3_api->create_function_v2 +#define sqlite3_db_config sqlite3_api->db_config +#define sqlite3_db_mutex sqlite3_api->db_mutex +#define sqlite3_db_status sqlite3_api->db_status +#define sqlite3_extended_errcode sqlite3_api->extended_errcode +#define sqlite3_log sqlite3_api->log +#define sqlite3_soft_heap_limit64 sqlite3_api->soft_heap_limit64 +#define sqlite3_sourceid sqlite3_api->sourceid +#define sqlite3_stmt_status sqlite3_api->stmt_status +#define sqlite3_strnicmp sqlite3_api->strnicmp +#define sqlite3_unlock_notify sqlite3_api->unlock_notify +#define sqlite3_wal_autocheckpoint sqlite3_api->wal_autocheckpoint +#define sqlite3_wal_checkpoint sqlite3_api->wal_checkpoint +#define sqlite3_wal_hook sqlite3_api->wal_hook +#define sqlite3_blob_reopen sqlite3_api->blob_reopen +#define sqlite3_vtab_config sqlite3_api->vtab_config +#define sqlite3_vtab_on_conflict sqlite3_api->vtab_on_conflict +#endif /* SQLITE_CORE */ + +#define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api = 0; +#define SQLITE_EXTENSION_INIT2(v) sqlite3_api = v; + +#endif /* _SQLITE3EXT_H_ */ diff --git a/scalos/libraries/sqlite/src/sqliteInt.h b/scalos/libraries/sqlite/src/sqliteInt.h new file mode 100644 index 000000000..6e48b1c4f --- /dev/null +++ b/scalos/libraries/sqlite/src/sqliteInt.h @@ -0,0 +1,3294 @@ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** Internal interface definitions for SQLite. +** +*/ +#ifndef _SQLITEINT_H_ +#define _SQLITEINT_H_ + +/* +** These #defines should enable >2GB file support on POSIX if the +** underlying operating system supports it. If the OS lacks +** large file support, or if the OS is windows, these should be no-ops. +** +** Ticket #2739: The _LARGEFILE_SOURCE macro must appear before any +** system #includes. Hence, this block of code must be the very first +** code in all source files. +** +** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch +** on the compiler command line. This is necessary if you are compiling +** on a recent machine (ex: Red Hat 7.2) but you want your code to work +** on an older machine (ex: Red Hat 6.0). If you compile on Red Hat 7.2 +** without this option, LFS is enable. But LFS does not exist in the kernel +** in Red Hat 6.0, so the code won't work. Hence, for maximum binary +** portability you should omit LFS. +** +** Similar is true for Mac OS X. LFS is only supported on Mac OS X 9 and later. +*/ +#ifndef SQLITE_DISABLE_LFS +# define _LARGE_FILE 1 +# ifndef _FILE_OFFSET_BITS +# define _FILE_OFFSET_BITS 64 +# endif +# define _LARGEFILE_SOURCE 1 +#endif + +/* +** Include the configuration header output by 'configure' if we're using the +** autoconf-based build +*/ +#ifdef _HAVE_SQLITE_CONFIG_H +#include "config.h" +#endif + +#include "sqliteLimit.h" + +/* Disable nuisance warnings on Borland compilers */ +#if defined(__BORLANDC__) +#pragma warn -rch /* unreachable code */ +#pragma warn -ccc /* Condition is always true or false */ +#pragma warn -aus /* Assigned value is never used */ +#pragma warn -csu /* Comparing signed and unsigned */ +#pragma warn -spa /* Suspicious pointer arithmetic */ +#endif + +/* Needed for various definitions... */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + +/* +** Include standard header files as necessary +*/ +#ifdef HAVE_STDINT_H +#include +#endif +#ifdef HAVE_INTTYPES_H +#include +#endif + +/* +** The following macros are used to cast pointers to integers and +** integers to pointers. The way you do this varies from one compiler +** to the next, so we have developed the following set of #if statements +** to generate appropriate macros for a wide range of compilers. +** +** The correct "ANSI" way to do this is to use the intptr_t type. +** Unfortunately, that typedef is not available on all compilers, or +** if it is available, it requires an #include of specific headers +** that vary from one machine to the next. +** +** Ticket #3860: The llvm-gcc-4.2 compiler from Apple chokes on +** the ((void*)&((char*)0)[X]) construct. But MSVC chokes on ((void*)(X)). +** So we have to define the macros in different ways depending on the +** compiler. +*/ +#if defined(__PTRDIFF_TYPE__) /* This case should work for GCC */ +# define SQLITE_INT_TO_PTR(X) ((void*)(__PTRDIFF_TYPE__)(X)) +# define SQLITE_PTR_TO_INT(X) ((int)(__PTRDIFF_TYPE__)(X)) +#elif !defined(__GNUC__) /* Works for compilers other than LLVM */ +# define SQLITE_INT_TO_PTR(X) ((void*)&((char*)0)[X]) +# define SQLITE_PTR_TO_INT(X) ((int)(((char*)X)-(char*)0)) +#elif defined(HAVE_STDINT_H) /* Use this case if we have ANSI headers */ +# define SQLITE_INT_TO_PTR(X) ((void*)(intptr_t)(X)) +# define SQLITE_PTR_TO_INT(X) ((int)(intptr_t)(X)) +#else /* Generates a warning - but it always works */ +# define SQLITE_INT_TO_PTR(X) ((void*)(X)) +# define SQLITE_PTR_TO_INT(X) ((int)(X)) +#endif + +/* +** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2. +** 0 means mutexes are permanently disable and the library is never +** threadsafe. 1 means the library is serialized which is the highest +** level of threadsafety. 2 means the libary is multithreaded - multiple +** threads can use SQLite as long as no two threads try to use the same +** database connection at the same time. +** +** Older versions of SQLite used an optional THREADSAFE macro. +** We support that for legacy. +*/ +#if !defined(SQLITE_THREADSAFE) +#if defined(THREADSAFE) +# define SQLITE_THREADSAFE THREADSAFE +#else +# define SQLITE_THREADSAFE 1 /* IMP: R-07272-22309 */ +#endif +#endif + +/* +** Powersafe overwrite is on by default. But can be turned off using +** the -DSQLITE_POWERSAFE_OVERWRITE=0 command-line option. +*/ +#ifndef SQLITE_POWERSAFE_OVERWRITE +# define SQLITE_POWERSAFE_OVERWRITE 1 +#endif + +/* +** The SQLITE_DEFAULT_MEMSTATUS macro must be defined as either 0 or 1. +** It determines whether or not the features related to +** SQLITE_CONFIG_MEMSTATUS are available by default or not. This value can +** be overridden at runtime using the sqlite3_config() API. +*/ +#if !defined(SQLITE_DEFAULT_MEMSTATUS) +# define SQLITE_DEFAULT_MEMSTATUS 1 +#endif + +/* +** Exactly one of the following macros must be defined in order to +** specify which memory allocation subsystem to use. +** +** SQLITE_SYSTEM_MALLOC // Use normal system malloc() +** SQLITE_WIN32_MALLOC // Use Win32 native heap API +** SQLITE_MEMDEBUG // Debugging version of system malloc() +** +** On Windows, if the SQLITE_WIN32_MALLOC_VALIDATE macro is defined and the +** assert() macro is enabled, each call into the Win32 native heap subsystem +** will cause HeapValidate to be called. If heap validation should fail, an +** assertion will be triggered. +** +** (Historical note: There used to be several other options, but we've +** pared it down to just these three.) +** +** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as +** the default. +*/ +#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_WIN32_MALLOC)+defined(SQLITE_MEMDEBUG)>1 +# error "At most one of the following compile-time configuration options\ + is allows: SQLITE_SYSTEM_MALLOC, SQLITE_WIN32_MALLOC, SQLITE_MEMDEBUG" +#endif +#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_WIN32_MALLOC)+defined(SQLITE_MEMDEBUG)==0 +# define SQLITE_SYSTEM_MALLOC 1 +#endif + +/* +** If SQLITE_MALLOC_SOFT_LIMIT is not zero, then try to keep the +** sizes of memory allocations below this value where possible. +*/ +#if !defined(SQLITE_MALLOC_SOFT_LIMIT) +# define SQLITE_MALLOC_SOFT_LIMIT 1024 +#endif + +/* +** We need to define _XOPEN_SOURCE as follows in order to enable +** recursive mutexes on most Unix systems. But Mac OS X is different. +** The _XOPEN_SOURCE define causes problems for Mac OS X we are told, +** so it is omitted there. See ticket #2673. +** +** Later we learn that _XOPEN_SOURCE is poorly or incorrectly +** implemented on some systems. So we avoid defining it at all +** if it is already defined or if it is unneeded because we are +** not doing a threadsafe build. Ticket #2681. +** +** See also ticket #2741. +*/ +#if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) && !defined(__APPLE__) && SQLITE_THREADSAFE +# define _XOPEN_SOURCE 500 /* Needed to enable pthread recursive mutexes */ +#endif + +/* +** The TCL headers are only needed when compiling the TCL bindings. +*/ +#if defined(SQLITE_TCL) || defined(TCLSH) +# include +#endif + +/* +** Many people are failing to set -DNDEBUG=1 when compiling SQLite. +** Setting NDEBUG makes the code smaller and run faster. So the following +** lines are added to automatically set NDEBUG unless the -DSQLITE_DEBUG=1 +** option is set. Thus NDEBUG becomes an opt-in rather than an opt-out +** feature. +*/ +#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) +# define NDEBUG 1 +#endif + +/* +** The testcase() macro is used to aid in coverage testing. When +** doing coverage testing, the condition inside the argument to +** testcase() must be evaluated both true and false in order to +** get full branch coverage. The testcase() macro is inserted +** to help ensure adequate test coverage in places where simple +** condition/decision coverage is inadequate. For example, testcase() +** can be used to make sure boundary values are tested. For +** bitmask tests, testcase() can be used to make sure each bit +** is significant and used at least once. On switch statements +** where multiple cases go to the same block of code, testcase() +** can insure that all cases are evaluated. +** +*/ +#ifdef SQLITE_COVERAGE_TEST + void sqlite3Coverage(int); +# define testcase(X) if( X ){ sqlite3Coverage(__LINE__); } +#else +# define testcase(X) +#endif + +/* +** The TESTONLY macro is used to enclose variable declarations or +** other bits of code that are needed to support the arguments +** within testcase() and assert() macros. +*/ +#if !defined(NDEBUG) || defined(SQLITE_COVERAGE_TEST) +# define TESTONLY(X) X +#else +# define TESTONLY(X) +#endif + +/* +** Sometimes we need a small amount of code such as a variable initialization +** to setup for a later assert() statement. We do not want this code to +** appear when assert() is disabled. The following macro is therefore +** used to contain that setup code. The "VVA" acronym stands for +** "Verification, Validation, and Accreditation". In other words, the +** code within VVA_ONLY() will only run during verification processes. +*/ +#ifndef NDEBUG +# define VVA_ONLY(X) X +#else +# define VVA_ONLY(X) +#endif + +/* +** The ALWAYS and NEVER macros surround boolean expressions which +** are intended to always be true or false, respectively. Such +** expressions could be omitted from the code completely. But they +** are included in a few cases in order to enhance the resilience +** of SQLite to unexpected behavior - to make the code "self-healing" +** or "ductile" rather than being "brittle" and crashing at the first +** hint of unplanned behavior. +** +** In other words, ALWAYS and NEVER are added for defensive code. +** +** When doing coverage testing ALWAYS and NEVER are hard-coded to +** be true and false so that the unreachable code then specify will +** not be counted as untested code. +*/ +#if defined(SQLITE_COVERAGE_TEST) +# define ALWAYS(X) (1) +# define NEVER(X) (0) +#elif !defined(NDEBUG) +# define ALWAYS(X) ((X)?1:(assert(0),0)) +# define NEVER(X) ((X)?(assert(0),1):0) +#else +# define ALWAYS(X) (X) +# define NEVER(X) (X) +#endif + +/* +** Return true (non-zero) if the input is a integer that is too large +** to fit in 32-bits. This macro is used inside of various testcase() +** macros to verify that we have tested SQLite for large-file support. +*/ +#define IS_BIG_INT(X) (((X)&~(i64)0xffffffff)!=0) + +/* +** The macro unlikely() is a hint that surrounds a boolean +** expression that is usually false. Macro likely() surrounds +** a boolean expression that is usually true. GCC is able to +** use these hints to generate better code, sometimes. +*/ +#if defined(__GNUC__) && 0 +# define likely(X) __builtin_expect((X),1) +# define unlikely(X) __builtin_expect((X),0) +#else +# define likely(X) !!(X) +# define unlikely(X) !!(X) +#endif + +#include "sqlite3.h" +#include "hash.h" +#include "parse.h" +#include +#include +#include +#include +#include + +/* +** If compiling for a processor that lacks floating point support, +** substitute integer for floating-point +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# define double sqlite_int64 +# define float sqlite_int64 +# define LONGDOUBLE_TYPE sqlite_int64 +# ifndef SQLITE_BIG_DBL +# define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50) +# endif +# define SQLITE_OMIT_DATETIME_FUNCS 1 +# define SQLITE_OMIT_TRACE 1 +# undef SQLITE_MIXED_ENDIAN_64BIT_FLOAT +# undef SQLITE_HAVE_ISNAN +#endif +#ifndef SQLITE_BIG_DBL +# define SQLITE_BIG_DBL (1e99) +#endif + +/* +** OMIT_TEMPDB is set to 1 if SQLITE_OMIT_TEMPDB is defined, or 0 +** afterward. Having this macro allows us to cause the C compiler +** to omit code used by TEMP tables without messy #ifndef statements. +*/ +#ifdef SQLITE_OMIT_TEMPDB +#define OMIT_TEMPDB 1 +#else +#define OMIT_TEMPDB 0 +#endif + +/* +** The "file format" number is an integer that is incremented whenever +** the VDBE-level file format changes. The following macros define the +** the default file format for new databases and the maximum file format +** that the library can read. +*/ +#define SQLITE_MAX_FILE_FORMAT 4 +#ifndef SQLITE_DEFAULT_FILE_FORMAT +# define SQLITE_DEFAULT_FILE_FORMAT 4 +#endif + +/* +** Determine whether triggers are recursive by default. This can be +** changed at run-time using a pragma. +*/ +#ifndef SQLITE_DEFAULT_RECURSIVE_TRIGGERS +# define SQLITE_DEFAULT_RECURSIVE_TRIGGERS 0 +#endif + +/* +** Provide a default value for SQLITE_TEMP_STORE in case it is not specified +** on the command-line +*/ +#ifndef SQLITE_TEMP_STORE +# define SQLITE_TEMP_STORE 1 +#endif + +/* +** GCC does not define the offsetof() macro so we'll have to do it +** ourselves. +*/ +#ifndef offsetof +#define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD)) +#endif + +/* +** Check to see if this machine uses EBCDIC. (Yes, believe it or +** not, there are still machines out there that use EBCDIC.) +*/ +#if 'A' == '\301' +# define SQLITE_EBCDIC 1 +#else +# define SQLITE_ASCII 1 +#endif + +/* +** Integers of known sizes. These typedefs might change for architectures +** where the sizes very. Preprocessor macros are available so that the +** types can be conveniently redefined at compile-type. Like this: +** +** cc '-DUINTPTR_TYPE=long long int' ... +*/ +#ifndef UINT32_TYPE +# ifdef HAVE_UINT32_T +# define UINT32_TYPE uint32_t +# else +# define UINT32_TYPE unsigned int +# endif +#endif +#ifndef UINT16_TYPE +# ifdef HAVE_UINT16_T +# define UINT16_TYPE uint16_t +# else +# define UINT16_TYPE unsigned short int +# endif +#endif +#ifndef INT16_TYPE +# ifdef HAVE_INT16_T +# define INT16_TYPE int16_t +# else +# define INT16_TYPE short int +# endif +#endif +#ifndef UINT8_TYPE +# ifdef HAVE_UINT8_T +# define UINT8_TYPE uint8_t +# else +# define UINT8_TYPE unsigned char +# endif +#endif +#ifndef INT8_TYPE +# ifdef HAVE_INT8_T +# define INT8_TYPE int8_t +# else +# define INT8_TYPE signed char +# endif +#endif +#ifndef LONGDOUBLE_TYPE +# define LONGDOUBLE_TYPE long double +#endif +typedef sqlite_int64 i64; /* 8-byte signed integer */ +typedef sqlite_uint64 u64; /* 8-byte unsigned integer */ +typedef UINT32_TYPE u32; /* 4-byte unsigned integer */ +typedef UINT16_TYPE u16; /* 2-byte unsigned integer */ +typedef INT16_TYPE i16; /* 2-byte signed integer */ +typedef UINT8_TYPE u8; /* 1-byte unsigned integer */ +typedef INT8_TYPE i8; /* 1-byte signed integer */ + +/* +** SQLITE_MAX_U32 is a u64 constant that is the maximum u64 value +** that can be stored in a u32 without loss of data. The value +** is 0x00000000ffffffff. But because of quirks of some compilers, we +** have to specify the value in the less intuitive manner shown: +*/ +#define SQLITE_MAX_U32 ((((u64)1)<<32)-1) + +/* +** The datatype used to store estimates of the number of rows in a +** table or index. This is an unsigned integer type. For 99.9% of +** the world, a 32-bit integer is sufficient. But a 64-bit integer +** can be used at compile-time if desired. +*/ +#ifdef SQLITE_64BIT_STATS + typedef u64 tRowcnt; /* 64-bit only if requested at compile-time */ +#else + typedef u32 tRowcnt; /* 32-bit is the default */ +#endif + +/* +** Macros to determine whether the machine is big or little endian, +** evaluated at runtime. +*/ +#ifdef SQLITE_AMALGAMATION +const int sqlite3one = 1; +#else +extern const int sqlite3one; +#endif +#if defined(i386) || defined(__i386__) || defined(_M_IX86)\ + || defined(__x86_64) || defined(__x86_64__) +# define SQLITE_BIGENDIAN 0 +# define SQLITE_LITTLEENDIAN 1 +# define SQLITE_UTF16NATIVE SQLITE_UTF16LE +#else +# define SQLITE_BIGENDIAN (*(char *)(&sqlite3one)==0) +# define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1) +# define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE) +#endif + +/* +** Constants for the largest and smallest possible 64-bit signed integers. +** These macros are designed to work correctly on both 32-bit and 64-bit +** compilers. +*/ +#define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32)) +#define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) + +/* +** Round up a number to the next larger multiple of 8. This is used +** to force 8-byte alignment on 64-bit architectures. +*/ +#define ROUND8(x) (((x)+7)&~7) + +/* +** Round down to the nearest multiple of 8 +*/ +#define ROUNDDOWN8(x) ((x)&~7) + +/* +** Assert that the pointer X is aligned to an 8-byte boundary. This +** macro is used only within assert() to verify that the code gets +** all alignment restrictions correct. +** +** Except, if SQLITE_4_BYTE_ALIGNED_MALLOC is defined, then the +** underlying malloc() implemention might return us 4-byte aligned +** pointers. In that case, only verify 4-byte alignment. +*/ +#ifdef SQLITE_4_BYTE_ALIGNED_MALLOC +# define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&3)==0) +#else +# define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&7)==0) +#endif + + +/* +** An instance of the following structure is used to store the busy-handler +** callback for a given sqlite handle. +** +** The sqlite.busyHandler member of the sqlite struct contains the busy +** callback for the database handle. Each pager opened via the sqlite +** handle is passed a pointer to sqlite.busyHandler. The busy-handler +** callback is currently invoked only from within pager.c. +*/ +typedef struct BusyHandler BusyHandler; +struct BusyHandler { + int (*xFunc)(void *,int); /* The busy callback */ + void *pArg; /* First arg to busy callback */ + int nBusy; /* Incremented with each busy call */ +}; + +/* +** Name of the master database table. The master database table +** is a special table that holds the names and attributes of all +** user tables and indices. +*/ +#define MASTER_NAME "sqlite_master" +#define TEMP_MASTER_NAME "sqlite_temp_master" + +/* +** The root-page of the master database table. +*/ +#define MASTER_ROOT 1 + +/* +** The name of the schema table. +*/ +#define SCHEMA_TABLE(x) ((!OMIT_TEMPDB)&&(x==1)?TEMP_MASTER_NAME:MASTER_NAME) + +/* +** A convenience macro that returns the number of elements in +** an array. +*/ +#define ArraySize(X) ((int)(sizeof(X)/sizeof(X[0]))) + +/* +** The following value as a destructor means to use sqlite3DbFree(). +** This is an internal extension to SQLITE_STATIC and SQLITE_TRANSIENT. +*/ +#define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3DbFree) + +/* +** When SQLITE_OMIT_WSD is defined, it means that the target platform does +** not support Writable Static Data (WSD) such as global and static variables. +** All variables must either be on the stack or dynamically allocated from +** the heap. When WSD is unsupported, the variable declarations scattered +** throughout the SQLite code must become constants instead. The SQLITE_WSD +** macro is used for this purpose. And instead of referencing the variable +** directly, we use its constant as a key to lookup the run-time allocated +** buffer that holds real variable. The constant is also the initializer +** for the run-time allocated buffer. +** +** In the usual case where WSD is supported, the SQLITE_WSD and GLOBAL +** macros become no-ops and have zero performance impact. +*/ +#ifdef SQLITE_OMIT_WSD + #define SQLITE_WSD const + #define GLOBAL(t,v) (*(t*)sqlite3_wsd_find((void*)&(v), sizeof(v))) + #define sqlite3GlobalConfig GLOBAL(struct Sqlite3Config, sqlite3Config) + int sqlite3_wsd_init(int N, int J); + void *sqlite3_wsd_find(void *K, int L); +#else + #define SQLITE_WSD + #define GLOBAL(t,v) v + #define sqlite3GlobalConfig sqlite3Config +#endif + +/* +** The following macros are used to suppress compiler warnings and to +** make it clear to human readers when a function parameter is deliberately +** left unused within the body of a function. This usually happens when +** a function is called via a function pointer. For example the +** implementation of an SQL aggregate step callback may not use the +** parameter indicating the number of arguments passed to the aggregate, +** if it knows that this is enforced elsewhere. +** +** When a function parameter is not used at all within the body of a function, +** it is generally named "NotUsed" or "NotUsed2" to make things even clearer. +** However, these macros may also be used to suppress warnings related to +** parameters that may or may not be used depending on compilation options. +** For example those parameters only used in assert() statements. In these +** cases the parameters are named as per the usual conventions. +*/ +#define UNUSED_PARAMETER(x) (void)(x) +#define UNUSED_PARAMETER2(x,y) UNUSED_PARAMETER(x),UNUSED_PARAMETER(y) + +/* +** Forward references to structures +*/ +typedef struct AggInfo AggInfo; +typedef struct AuthContext AuthContext; +typedef struct AutoincInfo AutoincInfo; +typedef struct Bitvec Bitvec; +typedef struct CollSeq CollSeq; +typedef struct Column Column; +typedef struct Db Db; +typedef struct Schema Schema; +typedef struct Expr Expr; +typedef struct ExprList ExprList; +typedef struct ExprSpan ExprSpan; +typedef struct FKey FKey; +typedef struct FuncDestructor FuncDestructor; +typedef struct FuncDef FuncDef; +typedef struct FuncDefHash FuncDefHash; +typedef struct IdList IdList; +typedef struct Index Index; +typedef struct IndexSample IndexSample; +typedef struct KeyClass KeyClass; +typedef struct KeyInfo KeyInfo; +typedef struct Lookaside Lookaside; +typedef struct LookasideSlot LookasideSlot; +typedef struct Module Module; +typedef struct NameContext NameContext; +typedef struct Parse Parse; +typedef struct RowSet RowSet; +typedef struct Savepoint Savepoint; +typedef struct Select Select; +typedef struct SrcList SrcList; +typedef struct StrAccum StrAccum; +typedef struct Table Table; +typedef struct TableLock TableLock; +typedef struct Token Token; +typedef struct Trigger Trigger; +typedef struct TriggerPrg TriggerPrg; +typedef struct TriggerStep TriggerStep; +typedef struct UnpackedRecord UnpackedRecord; +typedef struct VTable VTable; +typedef struct VtabCtx VtabCtx; +typedef struct Walker Walker; +typedef struct WherePlan WherePlan; +typedef struct WhereInfo WhereInfo; +typedef struct WhereLevel WhereLevel; + +/* +** Defer sourcing vdbe.h and btree.h until after the "u8" and +** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque +** pointer types (i.e. FuncDef) defined above. +*/ +#include "btree.h" +#include "vdbe.h" +#include "pager.h" +#include "pcache.h" + +#include "os.h" +#include "mutex.h" + + +/* +** Each database file to be accessed by the system is an instance +** of the following structure. There are normally two of these structures +** in the sqlite.aDb[] array. aDb[0] is the main database file and +** aDb[1] is the database file used to hold temporary tables. Additional +** databases may be attached. +*/ +struct Db { + char *zName; /* Name of this database */ + Btree *pBt; /* The B*Tree structure for this database file */ + u8 inTrans; /* 0: not writable. 1: Transaction. 2: Checkpoint */ + u8 safety_level; /* How aggressive at syncing data to disk */ + Schema *pSchema; /* Pointer to database schema (possibly shared) */ +}; + +/* +** An instance of the following structure stores a database schema. +** +** Most Schema objects are associated with a Btree. The exception is +** the Schema for the TEMP databaes (sqlite3.aDb[1]) which is free-standing. +** In shared cache mode, a single Schema object can be shared by multiple +** Btrees that refer to the same underlying BtShared object. +** +** Schema objects are automatically deallocated when the last Btree that +** references them is destroyed. The TEMP Schema is manually freed by +** sqlite3_close(). +* +** A thread must be holding a mutex on the corresponding Btree in order +** to access Schema content. This implies that the thread must also be +** holding a mutex on the sqlite3 connection pointer that owns the Btree. +** For a TEMP Schema, only the connection mutex is required. +*/ +struct Schema { + int schema_cookie; /* Database schema version number for this file */ + int iGeneration; /* Generation counter. Incremented with each change */ + Hash tblHash; /* All tables indexed by name */ + Hash idxHash; /* All (named) indices indexed by name */ + Hash trigHash; /* All triggers indexed by name */ + Hash fkeyHash; /* All foreign keys by referenced table name */ + Table *pSeqTab; /* The sqlite_sequence table used by AUTOINCREMENT */ + u8 file_format; /* Schema format version for this file */ + u8 enc; /* Text encoding used by this database */ + u16 flags; /* Flags associated with this schema */ + int cache_size; /* Number of pages to use in the cache */ +}; + +/* +** These macros can be used to test, set, or clear bits in the +** Db.pSchema->flags field. +*/ +#define DbHasProperty(D,I,P) (((D)->aDb[I].pSchema->flags&(P))==(P)) +#define DbHasAnyProperty(D,I,P) (((D)->aDb[I].pSchema->flags&(P))!=0) +#define DbSetProperty(D,I,P) (D)->aDb[I].pSchema->flags|=(P) +#define DbClearProperty(D,I,P) (D)->aDb[I].pSchema->flags&=~(P) + +/* +** Allowed values for the DB.pSchema->flags field. +** +** The DB_SchemaLoaded flag is set after the database schema has been +** read into internal hash tables. +** +** DB_UnresetViews means that one or more views have column names that +** have been filled out. If the schema changes, these column names might +** changes and so the view will need to be reset. +*/ +#define DB_SchemaLoaded 0x0001 /* The schema has been loaded */ +#define DB_UnresetViews 0x0002 /* Some views have defined column names */ +#define DB_Empty 0x0004 /* The file is empty (length 0 bytes) */ + +/* +** The number of different kinds of things that can be limited +** using the sqlite3_limit() interface. +*/ +#define SQLITE_N_LIMIT (SQLITE_LIMIT_TRIGGER_DEPTH+1) + +/* +** Lookaside malloc is a set of fixed-size buffers that can be used +** to satisfy small transient memory allocation requests for objects +** associated with a particular database connection. The use of +** lookaside malloc provides a significant performance enhancement +** (approx 10%) by avoiding numerous malloc/free requests while parsing +** SQL statements. +** +** The Lookaside structure holds configuration information about the +** lookaside malloc subsystem. Each available memory allocation in +** the lookaside subsystem is stored on a linked list of LookasideSlot +** objects. +** +** Lookaside allocations are only allowed for objects that are associated +** with a particular database connection. Hence, schema information cannot +** be stored in lookaside because in shared cache mode the schema information +** is shared by multiple database connections. Therefore, while parsing +** schema information, the Lookaside.bEnabled flag is cleared so that +** lookaside allocations are not used to construct the schema objects. +*/ +struct Lookaside { + u16 sz; /* Size of each buffer in bytes */ + u8 bEnabled; /* False to disable new lookaside allocations */ + u8 bMalloced; /* True if pStart obtained from sqlite3_malloc() */ + int nOut; /* Number of buffers currently checked out */ + int mxOut; /* Highwater mark for nOut */ + int anStat[3]; /* 0: hits. 1: size misses. 2: full misses */ + LookasideSlot *pFree; /* List of available buffers */ + void *pStart; /* First byte of available memory space */ + void *pEnd; /* First byte past end of available space */ +}; +struct LookasideSlot { + LookasideSlot *pNext; /* Next buffer in the list of free buffers */ +}; + +/* +** A hash table for function definitions. +** +** Hash each FuncDef structure into one of the FuncDefHash.a[] slots. +** Collisions are on the FuncDef.pHash chain. +*/ +struct FuncDefHash { + FuncDef *a[23]; /* Hash table for functions */ +}; + +/* +** Each database connection is an instance of the following structure. +** +** The sqlite.lastRowid records the last insert rowid generated by an +** insert statement. Inserts on views do not affect its value. Each +** trigger has its own context, so that lastRowid can be updated inside +** triggers as usual. The previous value will be restored once the trigger +** exits. Upon entering a before or instead of trigger, lastRowid is no +** longer (since after version 2.8.12) reset to -1. +** +** The sqlite.nChange does not count changes within triggers and keeps no +** context. It is reset at start of sqlite3_exec. +** The sqlite.lsChange represents the number of changes made by the last +** insert, update, or delete statement. It remains constant throughout the +** length of a statement and is then updated by OP_SetCounts. It keeps a +** context stack just like lastRowid so that the count of changes +** within a trigger is not seen outside the trigger. Changes to views do not +** affect the value of lsChange. +** The sqlite.csChange keeps track of the number of current changes (since +** the last statement) and is used to update sqlite_lsChange. +** +** The member variables sqlite.errCode, sqlite.zErrMsg and sqlite.zErrMsg16 +** store the most recent error code and, if applicable, string. The +** internal function sqlite3Error() is used to set these variables +** consistently. +*/ +struct sqlite3 { + sqlite3_vfs *pVfs; /* OS Interface */ + int nDb; /* Number of backends currently in use */ + Db *aDb; /* All backends */ + int flags; /* Miscellaneous flags. See below */ + unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */ + int errCode; /* Most recent error code (SQLITE_*) */ + int errMask; /* & result codes with this before returning */ + u8 autoCommit; /* The auto-commit flag. */ + u8 temp_store; /* 1: file 2: memory 0: default */ + u8 mallocFailed; /* True if we have seen a malloc failure */ + u8 dfltLockMode; /* Default locking-mode for attached dbs */ + signed char nextAutovac; /* Autovac setting after VACUUM if >=0 */ + u8 suppressErr; /* Do not issue error messages if true */ + u8 vtabOnConflict; /* Value to return for s3_vtab_on_conflict() */ + int nextPagesize; /* Pagesize after VACUUM if >0 */ + int nTable; /* Number of tables in the database */ + CollSeq *pDfltColl; /* The default collating sequence (BINARY) */ + i64 lastRowid; /* ROWID of most recent insert (see above) */ + u32 magic; /* Magic number for detect library misuse */ + int nChange; /* Value returned by sqlite3_changes() */ + int nTotalChange; /* Value returned by sqlite3_total_changes() */ + sqlite3_mutex *mutex; /* Connection mutex */ + int aLimit[SQLITE_N_LIMIT]; /* Limits */ + struct sqlite3InitInfo { /* Information used during initialization */ + int iDb; /* When back is being initialized */ + int newTnum; /* Rootpage of table being initialized */ + u8 busy; /* TRUE if currently initializing */ + u8 orphanTrigger; /* Last statement is orphaned TEMP trigger */ + } init; + int nExtension; /* Number of loaded extensions */ + void **aExtension; /* Array of shared library handles */ + struct Vdbe *pVdbe; /* List of active virtual machines */ + int activeVdbeCnt; /* Number of VDBEs currently executing */ + int writeVdbeCnt; /* Number of active VDBEs that are writing */ + int vdbeExecCnt; /* Number of nested calls to VdbeExec() */ + void (*xTrace)(void*,const char*); /* Trace function */ + void *pTraceArg; /* Argument to the trace function */ + void (*xProfile)(void*,const char*,u64); /* Profiling function */ + void *pProfileArg; /* Argument to profile function */ + void *pCommitArg; /* Argument to xCommitCallback() */ + int (*xCommitCallback)(void*); /* Invoked at every commit. */ + void *pRollbackArg; /* Argument to xRollbackCallback() */ + void (*xRollbackCallback)(void*); /* Invoked at every commit. */ + void *pUpdateArg; + void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64); +#ifndef SQLITE_OMIT_WAL + int (*xWalCallback)(void *, sqlite3 *, const char *, int); + void *pWalArg; +#endif + void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*); + void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*); + void *pCollNeededArg; + sqlite3_value *pErr; /* Most recent error message */ + char *zErrMsg; /* Most recent error message (UTF-8 encoded) */ + char *zErrMsg16; /* Most recent error message (UTF-16 encoded) */ + union { + volatile int isInterrupted; /* True if sqlite3_interrupt has been called */ + double notUsed1; /* Spacer */ + } u1; + Lookaside lookaside; /* Lookaside malloc configuration */ +#ifndef SQLITE_OMIT_AUTHORIZATION + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*); + /* Access authorization function */ + void *pAuthArg; /* 1st argument to the access auth function */ +#endif +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + int (*xProgress)(void *); /* The progress callback */ + void *pProgressArg; /* Argument to the progress callback */ + int nProgressOps; /* Number of opcodes for progress callback */ +#endif +#ifndef SQLITE_OMIT_VIRTUALTABLE + Hash aModule; /* populated by sqlite3_create_module() */ + VtabCtx *pVtabCtx; /* Context for active vtab connect/create */ + VTable **aVTrans; /* Virtual tables with open transactions */ + int nVTrans; /* Allocated size of aVTrans */ + VTable *pDisconnect; /* Disconnect these in next sqlite3_prepare() */ +#endif + FuncDefHash aFunc; /* Hash table of connection functions */ + Hash aCollSeq; /* All collating sequences */ + BusyHandler busyHandler; /* Busy callback */ + int busyTimeout; /* Busy handler timeout, in msec */ + Db aDbStatic[2]; /* Static space for the 2 default backends */ + Savepoint *pSavepoint; /* List of active savepoints */ + int nSavepoint; /* Number of non-transaction savepoints */ + int nStatement; /* Number of nested statement-transactions */ + u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */ + i64 nDeferredCons; /* Net deferred constraints this transaction. */ + int *pnBytesFreed; /* If not NULL, increment this in DbFree() */ + +#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY + /* The following variables are all protected by the STATIC_MASTER + ** mutex, not by sqlite3.mutex. They are used by code in notify.c. + ** + ** When X.pUnlockConnection==Y, that means that X is waiting for Y to + ** unlock so that it can proceed. + ** + ** When X.pBlockingConnection==Y, that means that something that X tried + ** tried to do recently failed with an SQLITE_LOCKED error due to locks + ** held by Y. + */ + sqlite3 *pBlockingConnection; /* Connection that caused SQLITE_LOCKED */ + sqlite3 *pUnlockConnection; /* Connection to watch for unlock */ + void *pUnlockArg; /* Argument to xUnlockNotify */ + void (*xUnlockNotify)(void **, int); /* Unlock notify callback */ + sqlite3 *pNextBlocked; /* Next in list of all blocked connections */ +#endif +}; + +/* +** A macro to discover the encoding of a database. +*/ +#define ENC(db) ((db)->aDb[0].pSchema->enc) + +/* +** Possible values for the sqlite3.flags. +*/ +#define SQLITE_VdbeTrace 0x00000100 /* True to trace VDBE execution */ +#define SQLITE_InternChanges 0x00000200 /* Uncommitted Hash table changes */ +#define SQLITE_FullColNames 0x00000400 /* Show full column names on SELECT */ +#define SQLITE_ShortColNames 0x00000800 /* Show short columns names */ +#define SQLITE_CountRows 0x00001000 /* Count rows changed by INSERT, */ + /* DELETE, or UPDATE and return */ + /* the count using a callback. */ +#define SQLITE_NullCallback 0x00002000 /* Invoke the callback once if the */ + /* result set is empty */ +#define SQLITE_SqlTrace 0x00004000 /* Debug print SQL as it executes */ +#define SQLITE_VdbeListing 0x00008000 /* Debug listings of VDBE programs */ +#define SQLITE_WriteSchema 0x00010000 /* OK to update SQLITE_MASTER */ +#define SQLITE_NoReadlock 0x00020000 /* Readlocks are omitted when + ** accessing read-only databases */ +#define SQLITE_IgnoreChecks 0x00040000 /* Do not enforce check constraints */ +#define SQLITE_ReadUncommitted 0x0080000 /* For shared-cache mode */ +#define SQLITE_LegacyFileFmt 0x00100000 /* Create new databases in format 1 */ +#define SQLITE_FullFSync 0x00200000 /* Use full fsync on the backend */ +#define SQLITE_CkptFullFSync 0x00400000 /* Use full fsync for checkpoint */ +#define SQLITE_RecoveryMode 0x00800000 /* Ignore schema errors */ +#define SQLITE_ReverseOrder 0x01000000 /* Reverse unordered SELECTs */ +#define SQLITE_RecTriggers 0x02000000 /* Enable recursive triggers */ +#define SQLITE_ForeignKeys 0x04000000 /* Enforce foreign key constraints */ +#define SQLITE_AutoIndex 0x08000000 /* Enable automatic indexes */ +#define SQLITE_PreferBuiltin 0x10000000 /* Preference to built-in funcs */ +#define SQLITE_LoadExtension 0x20000000 /* Enable load_extension */ +#define SQLITE_EnableTrigger 0x40000000 /* True to enable triggers */ + +/* +** Bits of the sqlite3.flags field that are used by the +** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface. +** These must be the low-order bits of the flags field. +*/ +#define SQLITE_QueryFlattener 0x01 /* Disable query flattening */ +#define SQLITE_ColumnCache 0x02 /* Disable the column cache */ +#define SQLITE_IndexSort 0x04 /* Disable indexes for sorting */ +#define SQLITE_IndexSearch 0x08 /* Disable indexes for searching */ +#define SQLITE_IndexCover 0x10 /* Disable index covering table */ +#define SQLITE_GroupByOrder 0x20 /* Disable GROUPBY cover of ORDERBY */ +#define SQLITE_FactorOutConst 0x40 /* Disable factoring out constants */ +#define SQLITE_IdxRealAsInt 0x80 /* Store REAL as INT in indices */ +#define SQLITE_DistinctOpt 0x80 /* DISTINCT using indexes */ +#define SQLITE_OptMask 0xff /* Mask of all disablable opts */ + +/* +** Possible values for the sqlite.magic field. +** The numbers are obtained at random and have no special meaning, other +** than being distinct from one another. +*/ +#define SQLITE_MAGIC_OPEN 0xa029a697 /* Database is open */ +#define SQLITE_MAGIC_CLOSED 0x9f3c2d33 /* Database is closed */ +#define SQLITE_MAGIC_SICK 0x4b771290 /* Error and awaiting close */ +#define SQLITE_MAGIC_BUSY 0xf03b7906 /* Database currently in use */ +#define SQLITE_MAGIC_ERROR 0xb5357930 /* An SQLITE_MISUSE error occurred */ + +/* +** Each SQL function is defined by an instance of the following +** structure. A pointer to this structure is stored in the sqlite.aFunc +** hash table. When multiple functions have the same name, the hash table +** points to a linked list of these structures. +*/ +struct FuncDef { + i16 nArg; /* Number of arguments. -1 means unlimited */ + u8 iPrefEnc; /* Preferred text encoding (SQLITE_UTF8, 16LE, 16BE) */ + u8 flags; /* Some combination of SQLITE_FUNC_* */ + void *pUserData; /* User data parameter */ + FuncDef *pNext; /* Next function with same name */ + void (*xFunc)(sqlite3_context*,int,sqlite3_value**); /* Regular function */ + void (*xStep)(sqlite3_context*,int,sqlite3_value**); /* Aggregate step */ + void (*xFinalize)(sqlite3_context*); /* Aggregate finalizer */ + char *zName; /* SQL name of the function. */ + FuncDef *pHash; /* Next with a different name but the same hash */ + FuncDestructor *pDestructor; /* Reference counted destructor function */ +}; + +/* +** This structure encapsulates a user-function destructor callback (as +** configured using create_function_v2()) and a reference counter. When +** create_function_v2() is called to create a function with a destructor, +** a single object of this type is allocated. FuncDestructor.nRef is set to +** the number of FuncDef objects created (either 1 or 3, depending on whether +** or not the specified encoding is SQLITE_ANY). The FuncDef.pDestructor +** member of each of the new FuncDef objects is set to point to the allocated +** FuncDestructor. +** +** Thereafter, when one of the FuncDef objects is deleted, the reference +** count on this object is decremented. When it reaches 0, the destructor +** is invoked and the FuncDestructor structure freed. +*/ +struct FuncDestructor { + int nRef; + void (*xDestroy)(void *); + void *pUserData; +}; + +/* +** Possible values for FuncDef.flags +*/ +#define SQLITE_FUNC_LIKE 0x01 /* Candidate for the LIKE optimization */ +#define SQLITE_FUNC_CASE 0x02 /* Case-sensitive LIKE-type function */ +#define SQLITE_FUNC_EPHEM 0x04 /* Ephemeral. Delete with VDBE */ +#define SQLITE_FUNC_NEEDCOLL 0x08 /* sqlite3GetFuncCollSeq() might be called */ +#define SQLITE_FUNC_PRIVATE 0x10 /* Allowed for internal use only */ +#define SQLITE_FUNC_COUNT 0x20 /* Built-in count(*) aggregate */ +#define SQLITE_FUNC_COALESCE 0x40 /* Built-in coalesce() or ifnull() function */ + +/* +** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are +** used to create the initializers for the FuncDef structures. +** +** FUNCTION(zName, nArg, iArg, bNC, xFunc) +** Used to create a scalar function definition of a function zName +** implemented by C function xFunc that accepts nArg arguments. The +** value passed as iArg is cast to a (void*) and made available +** as the user-data (sqlite3_user_data()) for the function. If +** argument bNC is true, then the SQLITE_FUNC_NEEDCOLL flag is set. +** +** AGGREGATE(zName, nArg, iArg, bNC, xStep, xFinal) +** Used to create an aggregate function definition implemented by +** the C functions xStep and xFinal. The first four parameters +** are interpreted in the same way as the first 4 parameters to +** FUNCTION(). +** +** LIKEFUNC(zName, nArg, pArg, flags) +** Used to create a scalar function definition of a function zName +** that accepts nArg arguments and is implemented by a call to C +** function likeFunc. Argument pArg is cast to a (void *) and made +** available as the function user-data (sqlite3_user_data()). The +** FuncDef.flags variable is set to the value passed as the flags +** parameter. +*/ +#define FUNCTION(zName, nArg, iArg, bNC, xFunc) \ + {nArg, SQLITE_UTF8, bNC*SQLITE_FUNC_NEEDCOLL, \ + SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0} +#define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \ + {nArg, SQLITE_UTF8, bNC*SQLITE_FUNC_NEEDCOLL, \ + pArg, 0, xFunc, 0, 0, #zName, 0, 0} +#define LIKEFUNC(zName, nArg, arg, flags) \ + {nArg, SQLITE_UTF8, flags, (void *)arg, 0, likeFunc, 0, 0, #zName, 0, 0} +#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \ + {nArg, SQLITE_UTF8, nc*SQLITE_FUNC_NEEDCOLL, \ + SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0,0} + +/* +** All current savepoints are stored in a linked list starting at +** sqlite3.pSavepoint. The first element in the list is the most recently +** opened savepoint. Savepoints are added to the list by the vdbe +** OP_Savepoint instruction. +*/ +struct Savepoint { + char *zName; /* Savepoint name (nul-terminated) */ + i64 nDeferredCons; /* Number of deferred fk violations */ + Savepoint *pNext; /* Parent savepoint (if any) */ +}; + +/* +** The following are used as the second parameter to sqlite3Savepoint(), +** and as the P1 argument to the OP_Savepoint instruction. +*/ +#define SAVEPOINT_BEGIN 0 +#define SAVEPOINT_RELEASE 1 +#define SAVEPOINT_ROLLBACK 2 + + +/* +** Each SQLite module (virtual table definition) is defined by an +** instance of the following structure, stored in the sqlite3.aModule +** hash table. +*/ +struct Module { + const sqlite3_module *pModule; /* Callback pointers */ + const char *zName; /* Name passed to create_module() */ + void *pAux; /* pAux passed to create_module() */ + void (*xDestroy)(void *); /* Module destructor function */ +}; + +/* +** information about each column of an SQL table is held in an instance +** of this structure. +*/ +struct Column { + char *zName; /* Name of this column */ + Expr *pDflt; /* Default value of this column */ + char *zDflt; /* Original text of the default value */ + char *zType; /* Data type for this column */ + char *zColl; /* Collating sequence. If NULL, use the default */ + u8 notNull; /* True if there is a NOT NULL constraint */ + u8 isPrimKey; /* True if this column is part of the PRIMARY KEY */ + char affinity; /* One of the SQLITE_AFF_... values */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + u8 isHidden; /* True if this column is 'hidden' */ +#endif +}; + +/* +** A "Collating Sequence" is defined by an instance of the following +** structure. Conceptually, a collating sequence consists of a name and +** a comparison routine that defines the order of that sequence. +** +** There may two separate implementations of the collation function, one +** that processes text in UTF-8 encoding (CollSeq.xCmp) and another that +** processes text encoded in UTF-16 (CollSeq.xCmp16), using the machine +** native byte order. When a collation sequence is invoked, SQLite selects +** the version that will require the least expensive encoding +** translations, if any. +** +** The CollSeq.pUser member variable is an extra parameter that passed in +** as the first argument to the UTF-8 comparison function, xCmp. +** CollSeq.pUser16 is the equivalent for the UTF-16 comparison function, +** xCmp16. +** +** If both CollSeq.xCmp and CollSeq.xCmp16 are NULL, it means that the +** collating sequence is undefined. Indices built on an undefined +** collating sequence may not be read or written. +*/ +struct CollSeq { + char *zName; /* Name of the collating sequence, UTF-8 encoded */ + u8 enc; /* Text encoding handled by xCmp() */ + void *pUser; /* First argument to xCmp() */ + int (*xCmp)(void*,int, const void*, int, const void*); + void (*xDel)(void*); /* Destructor for pUser */ +}; + +/* +** A sort order can be either ASC or DESC. +*/ +#define SQLITE_SO_ASC 0 /* Sort in ascending order */ +#define SQLITE_SO_DESC 1 /* Sort in ascending order */ + +/* +** Column affinity types. +** +** These used to have mnemonic name like 'i' for SQLITE_AFF_INTEGER and +** 't' for SQLITE_AFF_TEXT. But we can save a little space and improve +** the speed a little by numbering the values consecutively. +** +** But rather than start with 0 or 1, we begin with 'a'. That way, +** when multiple affinity types are concatenated into a string and +** used as the P4 operand, they will be more readable. +** +** Note also that the numeric types are grouped together so that testing +** for a numeric type is a single comparison. +*/ +#define SQLITE_AFF_TEXT 'a' +#define SQLITE_AFF_NONE 'b' +#define SQLITE_AFF_NUMERIC 'c' +#define SQLITE_AFF_INTEGER 'd' +#define SQLITE_AFF_REAL 'e' + +#define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC) + +/* +** The SQLITE_AFF_MASK values masks off the significant bits of an +** affinity value. +*/ +#define SQLITE_AFF_MASK 0x67 + +/* +** Additional bit values that can be ORed with an affinity without +** changing the affinity. +*/ +#define SQLITE_JUMPIFNULL 0x08 /* jumps if either operand is NULL */ +#define SQLITE_STOREP2 0x10 /* Store result in reg[P2] rather than jump */ +#define SQLITE_NULLEQ 0x80 /* NULL=NULL */ + +/* +** An object of this type is created for each virtual table present in +** the database schema. +** +** If the database schema is shared, then there is one instance of this +** structure for each database connection (sqlite3*) that uses the shared +** schema. This is because each database connection requires its own unique +** instance of the sqlite3_vtab* handle used to access the virtual table +** implementation. sqlite3_vtab* handles can not be shared between +** database connections, even when the rest of the in-memory database +** schema is shared, as the implementation often stores the database +** connection handle passed to it via the xConnect() or xCreate() method +** during initialization internally. This database connection handle may +** then be used by the virtual table implementation to access real tables +** within the database. So that they appear as part of the callers +** transaction, these accesses need to be made via the same database +** connection as that used to execute SQL operations on the virtual table. +** +** All VTable objects that correspond to a single table in a shared +** database schema are initially stored in a linked-list pointed to by +** the Table.pVTable member variable of the corresponding Table object. +** When an sqlite3_prepare() operation is required to access the virtual +** table, it searches the list for the VTable that corresponds to the +** database connection doing the preparing so as to use the correct +** sqlite3_vtab* handle in the compiled query. +** +** When an in-memory Table object is deleted (for example when the +** schema is being reloaded for some reason), the VTable objects are not +** deleted and the sqlite3_vtab* handles are not xDisconnect()ed +** immediately. Instead, they are moved from the Table.pVTable list to +** another linked list headed by the sqlite3.pDisconnect member of the +** corresponding sqlite3 structure. They are then deleted/xDisconnected +** next time a statement is prepared using said sqlite3*. This is done +** to avoid deadlock issues involving multiple sqlite3.mutex mutexes. +** Refer to comments above function sqlite3VtabUnlockList() for an +** explanation as to why it is safe to add an entry to an sqlite3.pDisconnect +** list without holding the corresponding sqlite3.mutex mutex. +** +** The memory for objects of this type is always allocated by +** sqlite3DbMalloc(), using the connection handle stored in VTable.db as +** the first argument. +*/ +struct VTable { + sqlite3 *db; /* Database connection associated with this table */ + Module *pMod; /* Pointer to module implementation */ + sqlite3_vtab *pVtab; /* Pointer to vtab instance */ + int nRef; /* Number of pointers to this structure */ + u8 bConstraint; /* True if constraints are supported */ + int iSavepoint; /* Depth of the SAVEPOINT stack */ + VTable *pNext; /* Next in linked list (see above) */ +}; + +/* +** Each SQL table is represented in memory by an instance of the +** following structure. +** +** Table.zName is the name of the table. The case of the original +** CREATE TABLE statement is stored, but case is not significant for +** comparisons. +** +** Table.nCol is the number of columns in this table. Table.aCol is a +** pointer to an array of Column structures, one for each column. +** +** If the table has an INTEGER PRIMARY KEY, then Table.iPKey is the index of +** the column that is that key. Otherwise Table.iPKey is negative. Note +** that the datatype of the PRIMARY KEY must be INTEGER for this field to +** be set. An INTEGER PRIMARY KEY is used as the rowid for each row of +** the table. If a table has no INTEGER PRIMARY KEY, then a random rowid +** is generated for each row of the table. TF_HasPrimaryKey is set if +** the table has any PRIMARY KEY, INTEGER or otherwise. +** +** Table.tnum is the page number for the root BTree page of the table in the +** database file. If Table.iDb is the index of the database table backend +** in sqlite.aDb[]. 0 is for the main database and 1 is for the file that +** holds temporary tables and indices. If TF_Ephemeral is set +** then the table is stored in a file that is automatically deleted +** when the VDBE cursor to the table is closed. In this case Table.tnum +** refers VDBE cursor number that holds the table open, not to the root +** page number. Transient tables are used to hold the results of a +** sub-query that appears instead of a real table name in the FROM clause +** of a SELECT statement. +*/ +struct Table { + char *zName; /* Name of the table or view */ + int iPKey; /* If not negative, use aCol[iPKey] as the primary key */ + int nCol; /* Number of columns in this table */ + Column *aCol; /* Information about each column */ + Index *pIndex; /* List of SQL indexes on this table. */ + int tnum; /* Root BTree node for this table (see note above) */ + tRowcnt nRowEst; /* Estimated rows in table - from sqlite_stat1 table */ + Select *pSelect; /* NULL for tables. Points to definition if a view. */ + u16 nRef; /* Number of pointers to this Table */ + u8 tabFlags; /* Mask of TF_* values */ + u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */ + FKey *pFKey; /* Linked list of all foreign keys in this table */ + char *zColAff; /* String defining the affinity of each column */ +#ifndef SQLITE_OMIT_CHECK + Expr *pCheck; /* The AND of all CHECK constraints */ +#endif +#ifndef SQLITE_OMIT_ALTERTABLE + int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */ +#endif +#ifndef SQLITE_OMIT_VIRTUALTABLE + VTable *pVTable; /* List of VTable objects. */ + int nModuleArg; /* Number of arguments to the module */ + char **azModuleArg; /* Text of all module args. [0] is module name */ +#endif + Trigger *pTrigger; /* List of triggers stored in pSchema */ + Schema *pSchema; /* Schema that contains this table */ + Table *pNextZombie; /* Next on the Parse.pZombieTab list */ +}; + +/* +** Allowed values for Tabe.tabFlags. +*/ +#define TF_Readonly 0x01 /* Read-only system table */ +#define TF_Ephemeral 0x02 /* An ephemeral table */ +#define TF_HasPrimaryKey 0x04 /* Table has a primary key */ +#define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */ +#define TF_Virtual 0x10 /* Is a virtual table */ +#define TF_NeedMetadata 0x20 /* aCol[].zType and aCol[].pColl missing */ + + + +/* +** Test to see whether or not a table is a virtual table. This is +** done as a macro so that it will be optimized out when virtual +** table support is omitted from the build. +*/ +#ifndef SQLITE_OMIT_VIRTUALTABLE +# define IsVirtual(X) (((X)->tabFlags & TF_Virtual)!=0) +# define IsHiddenColumn(X) ((X)->isHidden) +#else +# define IsVirtual(X) 0 +# define IsHiddenColumn(X) 0 +#endif + +/* +** Each foreign key constraint is an instance of the following structure. +** +** A foreign key is associated with two tables. The "from" table is +** the table that contains the REFERENCES clause that creates the foreign +** key. The "to" table is the table that is named in the REFERENCES clause. +** Consider this example: +** +** CREATE TABLE ex1( +** a INTEGER PRIMARY KEY, +** b INTEGER CONSTRAINT fk1 REFERENCES ex2(x) +** ); +** +** For foreign key "fk1", the from-table is "ex1" and the to-table is "ex2". +** +** Each REFERENCES clause generates an instance of the following structure +** which is attached to the from-table. The to-table need not exist when +** the from-table is created. The existence of the to-table is not checked. +*/ +struct FKey { + Table *pFrom; /* Table containing the REFERENCES clause (aka: Child) */ + FKey *pNextFrom; /* Next foreign key in pFrom */ + char *zTo; /* Name of table that the key points to (aka: Parent) */ + FKey *pNextTo; /* Next foreign key on table named zTo */ + FKey *pPrevTo; /* Previous foreign key on table named zTo */ + int nCol; /* Number of columns in this key */ + /* EV: R-30323-21917 */ + u8 isDeferred; /* True if constraint checking is deferred till COMMIT */ + u8 aAction[2]; /* ON DELETE and ON UPDATE actions, respectively */ + Trigger *apTrigger[2]; /* Triggers for aAction[] actions */ + struct sColMap { /* Mapping of columns in pFrom to columns in zTo */ + int iFrom; /* Index of column in pFrom */ + char *zCol; /* Name of column in zTo. If 0 use PRIMARY KEY */ + } aCol[1]; /* One entry for each of nCol column s */ +}; + +/* +** SQLite supports many different ways to resolve a constraint +** error. ROLLBACK processing means that a constraint violation +** causes the operation in process to fail and for the current transaction +** to be rolled back. ABORT processing means the operation in process +** fails and any prior changes from that one operation are backed out, +** but the transaction is not rolled back. FAIL processing means that +** the operation in progress stops and returns an error code. But prior +** changes due to the same operation are not backed out and no rollback +** occurs. IGNORE means that the particular row that caused the constraint +** error is not inserted or updated. Processing continues and no error +** is returned. REPLACE means that preexisting database rows that caused +** a UNIQUE constraint violation are removed so that the new insert or +** update can proceed. Processing continues and no error is reported. +** +** RESTRICT, SETNULL, and CASCADE actions apply only to foreign keys. +** RESTRICT is the same as ABORT for IMMEDIATE foreign keys and the +** same as ROLLBACK for DEFERRED keys. SETNULL means that the foreign +** key is set to NULL. CASCADE means that a DELETE or UPDATE of the +** referenced table row is propagated into the row that holds the +** foreign key. +** +** The following symbolic values are used to record which type +** of action to take. +*/ +#define OE_None 0 /* There is no constraint to check */ +#define OE_Rollback 1 /* Fail the operation and rollback the transaction */ +#define OE_Abort 2 /* Back out changes but do no rollback transaction */ +#define OE_Fail 3 /* Stop the operation but leave all prior changes */ +#define OE_Ignore 4 /* Ignore the error. Do not do the INSERT or UPDATE */ +#define OE_Replace 5 /* Delete existing record, then do INSERT or UPDATE */ + +#define OE_Restrict 6 /* OE_Abort for IMMEDIATE, OE_Rollback for DEFERRED */ +#define OE_SetNull 7 /* Set the foreign key value to NULL */ +#define OE_SetDflt 8 /* Set the foreign key value to its default */ +#define OE_Cascade 9 /* Cascade the changes */ + +#define OE_Default 99 /* Do whatever the default action is */ + + +/* +** An instance of the following structure is passed as the first +** argument to sqlite3VdbeKeyCompare and is used to control the +** comparison of the two index keys. +*/ +struct KeyInfo { + sqlite3 *db; /* The database connection */ + u8 enc; /* Text encoding - one of the SQLITE_UTF* values */ + u16 nField; /* Number of entries in aColl[] */ + u8 *aSortOrder; /* Sort order for each column. May be NULL */ + CollSeq *aColl[1]; /* Collating sequence for each term of the key */ +}; + +/* +** An instance of the following structure holds information about a +** single index record that has already been parsed out into individual +** values. +** +** A record is an object that contains one or more fields of data. +** Records are used to store the content of a table row and to store +** the key of an index. A blob encoding of a record is created by +** the OP_MakeRecord opcode of the VDBE and is disassembled by the +** OP_Column opcode. +** +** This structure holds a record that has already been disassembled +** into its constituent fields. +*/ +struct UnpackedRecord { + KeyInfo *pKeyInfo; /* Collation and sort-order information */ + u16 nField; /* Number of entries in apMem[] */ + u8 flags; /* Boolean settings. UNPACKED_... below */ + i64 rowid; /* Used by UNPACKED_PREFIX_SEARCH */ + Mem *aMem; /* Values */ +}; + +/* +** Allowed values of UnpackedRecord.flags +*/ +#define UNPACKED_INCRKEY 0x01 /* Make this key an epsilon larger */ +#define UNPACKED_PREFIX_MATCH 0x02 /* A prefix match is considered OK */ +#define UNPACKED_PREFIX_SEARCH 0x04 /* Ignore final (rowid) field */ + +/* +** Each SQL index is represented in memory by an +** instance of the following structure. +** +** The columns of the table that are to be indexed are described +** by the aiColumn[] field of this structure. For example, suppose +** we have the following table and index: +** +** CREATE TABLE Ex1(c1 int, c2 int, c3 text); +** CREATE INDEX Ex2 ON Ex1(c3,c1); +** +** In the Table structure describing Ex1, nCol==3 because there are +** three columns in the table. In the Index structure describing +** Ex2, nColumn==2 since 2 of the 3 columns of Ex1 are indexed. +** The value of aiColumn is {2, 0}. aiColumn[0]==2 because the +** first column to be indexed (c3) has an index of 2 in Ex1.aCol[]. +** The second column to be indexed (c1) has an index of 0 in +** Ex1.aCol[], hence Ex2.aiColumn[1]==0. +** +** The Index.onError field determines whether or not the indexed columns +** must be unique and what to do if they are not. When Index.onError=OE_None, +** it means this is not a unique index. Otherwise it is a unique index +** and the value of Index.onError indicate the which conflict resolution +** algorithm to employ whenever an attempt is made to insert a non-unique +** element. +*/ +struct Index { + char *zName; /* Name of this index */ + int nColumn; /* Number of columns in the table used by this index */ + int *aiColumn; /* Which columns are used by this index. 1st is 0 */ + tRowcnt *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */ + Table *pTable; /* The SQL table being indexed */ + int tnum; /* Page containing root of this index in database file */ + u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ + u8 autoIndex; /* True if is automatically created (ex: by UNIQUE) */ + u8 bUnordered; /* Use this index for == or IN queries only */ + char *zColAff; /* String defining the affinity of each column */ + Index *pNext; /* The next index associated with the same table */ + Schema *pSchema; /* Schema containing this index */ + u8 *aSortOrder; /* Array of size Index.nColumn. True==DESC, False==ASC */ + char **azColl; /* Array of collation sequence names for index */ +#ifdef SQLITE_ENABLE_STAT3 + int nSample; /* Number of elements in aSample[] */ + tRowcnt avgEq; /* Average nEq value for key values not in aSample */ + IndexSample *aSample; /* Samples of the left-most key */ +#endif +}; + +/* +** Each sample stored in the sqlite_stat3 table is represented in memory +** using a structure of this type. See documentation at the top of the +** analyze.c source file for additional information. +*/ +struct IndexSample { + union { + char *z; /* Value if eType is SQLITE_TEXT or SQLITE_BLOB */ + double r; /* Value if eType is SQLITE_FLOAT */ + i64 i; /* Value if eType is SQLITE_INTEGER */ + } u; + u8 eType; /* SQLITE_NULL, SQLITE_INTEGER ... etc. */ + int nByte; /* Size in byte of text or blob. */ + tRowcnt nEq; /* Est. number of rows where the key equals this sample */ + tRowcnt nLt; /* Est. number of rows where key is less than this sample */ + tRowcnt nDLt; /* Est. number of distinct keys less than this sample */ +}; + +/* +** Each token coming out of the lexer is an instance of +** this structure. Tokens are also used as part of an expression. +** +** Note if Token.z==0 then Token.dyn and Token.n are undefined and +** may contain random values. Do not make any assumptions about Token.dyn +** and Token.n when Token.z==0. +*/ +struct Token { + const char *z; /* Text of the token. Not NULL-terminated! */ + unsigned int n; /* Number of characters in this token */ +}; + +/* +** An instance of this structure contains information needed to generate +** code for a SELECT that contains aggregate functions. +** +** If Expr.op==TK_AGG_COLUMN or TK_AGG_FUNCTION then Expr.pAggInfo is a +** pointer to this structure. The Expr.iColumn field is the index in +** AggInfo.aCol[] or AggInfo.aFunc[] of information needed to generate +** code for that node. +** +** AggInfo.pGroupBy and AggInfo.aFunc.pExpr point to fields within the +** original Select structure that describes the SELECT statement. These +** fields do not need to be freed when deallocating the AggInfo structure. +*/ +struct AggInfo { + u8 directMode; /* Direct rendering mode means take data directly + ** from source tables rather than from accumulators */ + u8 useSortingIdx; /* In direct mode, reference the sorting index rather + ** than the source table */ + int sortingIdx; /* Cursor number of the sorting index */ + int sortingIdxPTab; /* Cursor number of pseudo-table */ + ExprList *pGroupBy; /* The group by clause */ + int nSortingColumn; /* Number of columns in the sorting index */ + struct AggInfo_col { /* For each column used in source tables */ + Table *pTab; /* Source table */ + int iTable; /* Cursor number of the source table */ + int iColumn; /* Column number within the source table */ + int iSorterColumn; /* Column number in the sorting index */ + int iMem; /* Memory location that acts as accumulator */ + Expr *pExpr; /* The original expression */ + } *aCol; + int nColumn; /* Number of used entries in aCol[] */ + int nColumnAlloc; /* Number of slots allocated for aCol[] */ + int nAccumulator; /* Number of columns that show through to the output. + ** Additional columns are used only as parameters to + ** aggregate functions */ + struct AggInfo_func { /* For each aggregate function */ + Expr *pExpr; /* Expression encoding the function */ + FuncDef *pFunc; /* The aggregate function implementation */ + int iMem; /* Memory location that acts as accumulator */ + int iDistinct; /* Ephemeral table used to enforce DISTINCT */ + } *aFunc; + int nFunc; /* Number of entries in aFunc[] */ + int nFuncAlloc; /* Number of slots allocated for aFunc[] */ +}; + +/* +** The datatype ynVar is a signed integer, either 16-bit or 32-bit. +** Usually it is 16-bits. But if SQLITE_MAX_VARIABLE_NUMBER is greater +** than 32767 we have to make it 32-bit. 16-bit is preferred because +** it uses less memory in the Expr object, which is a big memory user +** in systems with lots of prepared statements. And few applications +** need more than about 10 or 20 variables. But some extreme users want +** to have prepared statements with over 32767 variables, and for them +** the option is available (at compile-time). +*/ +#if SQLITE_MAX_VARIABLE_NUMBER<=32767 +typedef i16 ynVar; +#else +typedef int ynVar; +#endif + +/* +** Each node of an expression in the parse tree is an instance +** of this structure. +** +** Expr.op is the opcode. The integer parser token codes are reused +** as opcodes here. For example, the parser defines TK_GE to be an integer +** code representing the ">=" operator. This same integer code is reused +** to represent the greater-than-or-equal-to operator in the expression +** tree. +** +** If the expression is an SQL literal (TK_INTEGER, TK_FLOAT, TK_BLOB, +** or TK_STRING), then Expr.token contains the text of the SQL literal. If +** the expression is a variable (TK_VARIABLE), then Expr.token contains the +** variable name. Finally, if the expression is an SQL function (TK_FUNCTION), +** then Expr.token contains the name of the function. +** +** Expr.pRight and Expr.pLeft are the left and right subexpressions of a +** binary operator. Either or both may be NULL. +** +** Expr.x.pList is a list of arguments if the expression is an SQL function, +** a CASE expression or an IN expression of the form " IN (, ...)". +** Expr.x.pSelect is used if the expression is a sub-select or an expression of +** the form " IN (SELECT ...)". If the EP_xIsSelect bit is set in the +** Expr.flags mask, then Expr.x.pSelect is valid. Otherwise, Expr.x.pList is +** valid. +** +** An expression of the form ID or ID.ID refers to a column in a table. +** For such expressions, Expr.op is set to TK_COLUMN and Expr.iTable is +** the integer cursor number of a VDBE cursor pointing to that table and +** Expr.iColumn is the column number for the specific column. If the +** expression is used as a result in an aggregate SELECT, then the +** value is also stored in the Expr.iAgg column in the aggregate so that +** it can be accessed after all aggregates are computed. +** +** If the expression is an unbound variable marker (a question mark +** character '?' in the original SQL) then the Expr.iTable holds the index +** number for that variable. +** +** If the expression is a subquery then Expr.iColumn holds an integer +** register number containing the result of the subquery. If the +** subquery gives a constant result, then iTable is -1. If the subquery +** gives a different answer at different times during statement processing +** then iTable is the address of a subroutine that computes the subquery. +** +** If the Expr is of type OP_Column, and the table it is selecting from +** is a disk table or the "old.*" pseudo-table, then pTab points to the +** corresponding table definition. +** +** ALLOCATION NOTES: +** +** Expr objects can use a lot of memory space in database schema. To +** help reduce memory requirements, sometimes an Expr object will be +** truncated. And to reduce the number of memory allocations, sometimes +** two or more Expr objects will be stored in a single memory allocation, +** together with Expr.zToken strings. +** +** If the EP_Reduced and EP_TokenOnly flags are set when +** an Expr object is truncated. When EP_Reduced is set, then all +** the child Expr objects in the Expr.pLeft and Expr.pRight subtrees +** are contained within the same memory allocation. Note, however, that +** the subtrees in Expr.x.pList or Expr.x.pSelect are always separately +** allocated, regardless of whether or not EP_Reduced is set. +*/ +struct Expr { + u8 op; /* Operation performed by this node */ + char affinity; /* The affinity of the column or 0 if not a column */ + u16 flags; /* Various flags. EP_* See below */ + union { + char *zToken; /* Token value. Zero terminated and dequoted */ + int iValue; /* Non-negative integer value if EP_IntValue */ + } u; + + /* If the EP_TokenOnly flag is set in the Expr.flags mask, then no + ** space is allocated for the fields below this point. An attempt to + ** access them will result in a segfault or malfunction. + *********************************************************************/ + + Expr *pLeft; /* Left subnode */ + Expr *pRight; /* Right subnode */ + union { + ExprList *pList; /* Function arguments or in " IN ( IN (

    YVE2DnMpFPEC?n?;)m`2 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 literal 0 HcwPel00001 diff --git a/scalos/Installer/GFX/VGA.png b/scalos/Installer/GFX/VGA.png new file mode 100755 index 0000000000000000000000000000000000000000..283424bee3b99e621d755cf531df4520adb27480 GIT binary patch literal 47261 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

    -4GXVJE;opnoZI0AIMBjBh3+X^ih6siDO(sb*d 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 literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Window/ControlBar/Background b/scalos/Default_Theme/Window/ControlBar/Background new file mode 100755 index 0000000000000000000000000000000000000000..990bb5b79bf40c4e3df3c48bfd0f7762605f0e04 GIT binary patch literal 2030 zcwU{-doo z*1hWFq*0f!U89|$rN$Ymk+i!?Q501gMQTx(Q0lVGnce+o|JdE{^XK!N=RBYDzT1P_ zV?dw93}gZb0sz`6ussZXfu5GOj<%+rjcxrOCT&3Yh++#Lm=3&4?7%Y|IgWO1qPac z5BNyP3Lp$1qye=31nk?nQv>=n;I}{sBuWE~(cC$DXP`kJARr_XfkJ9%pin#A)SW&+ z8E6<*FR z_xFBG|A0VNXxJY=4?lK1B0A=)GiT4mo=-@;m~`oKGB4xmwal#Vu4m^L6c!cVEV)&B zr@W%FN?Kj>=O2HnZ+P&qvFXv{_9wCqx#H=wp5DHf{R4xqhQ{A2C*Dm?O{?B7EG{jp zS5`l+t?#-ZfQ0^;|L8K2MkaemK3xhBLox4HL`LNXySeH%I>#m z!OolygsAuz+Iy^B#y?xwrTr@V?_lZwm+W7#f4hc&E)v>#Jfs1jf%iq%OM%>`J;s5CtJV0OuQ5=&AL=FU#W`ej@GSbIl6e{MZ$m|kxB;N+%L}ox1cm2n zS=cwIL>Em$KpQbF!p$|g(_Iutk@?HnEOg-0eQvaf=+qv12l<&3rWVd&iR-~j&z!*- z_7x^C`()FJm94PHN#c}XDE;SbH$(Ct_N6_)Y1Xu9r*FRv_RyubpwyP;x8<-f*x0rf zY2i;JcS4VpwYH4@a=j(pWfk4=e4%d>F9vK8*0i75mzF+OeArsWZ46OP=B-@ zbjp%LJ3SxxLr0ydvjHYGu)Fy*!VgL7PLf*i&W?n|A2NHC&5UC5QuUD5LzEC#Mn{^n zkAmJtUGHry*v$W3H)%rc(ogJt5jdT&Tvkp}HsL|Wq>q-WCy#AXsS$cZDxPYf2si;M zI+o)Pi!NeXXz|4HfU3J^sq?cvd^-el0;}vV#jmJX-l6J^8v0Y^q9n?^h22wr;ERuO zm`eA>v?9{jdbg!k8z`kS-s9e}fF$SYMLa-*Z{VEzXj@>Umgw^)jDq%!&;(nBfPXMq zNmRcTxn@BDKs|GG&{-7}a~ho5=tkff`3VE*$(weAS?@6T-bSvBB=5{qS!?e&T4|Jrj4|M!dxh1UYZl(^6dK+f{);3-G$XbGe=uVJ)q zCF*h*ZB^p<=by|PUBc9w| zS62%aeW)AgDVspDIn0urn+;o1uH+Q3Po{q(MTHxx=`}y>RjJ?Ceo2I!S0WU?afAg-vib^;}qiQ0rFxn_FfBf9lEn@-2q6 zmB}Zzo01k-nyNRWB{Y`r0Gh9BI1-l5-ZZRqb=fqkwWO5k`yT*``?DWXa{RZbS~6zR}DnX#DoMrqZ^>N<>Url@d(t zTg=wFExqsLrUUZmwXbhTrRQ^ruEx+glh!rGR}-O0<4eQcy%jNMIw(2IBSl291_ECo zGH6x#e{E6tdP3MEoPsmxI>S9T&DZmSFmRK-K&|B?77#1Z}=^nC<62Eq$c155a8;55YRCAj4k<;tzdvPIM{Q{l(l}S{GJ@cawC8^?MR z4pU(2|-x@agL2y^)ywceaV%pmK0m_r529`-;3LqE3EIy*%Pr@Ih(3yVIr}( I588h94{ZZ=egFUf literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Window/ControlBar/BrowseDisabled b/scalos/Default_Theme/Window/ControlBar/BrowseDisabled new file mode 100644 index 0000000000000000000000000000000000000000..4c73c56862e5202f104832d51bb07ce7c0978cb2 GIT binary patch literal 860 zcwQBfT}+c#9L5h{eWTO8PQB>O!vA8+VzR`GU2h1~uVtOfVqz9Ah!Zu=B_wl%N6}P` zN#io6EFlaVRun(xg6#xrN9ZPqtaJ<(r)Y#gD}@#mXy3kVPe0$Y<2iZGdCo6S{x|2@ zvFCFuV`Y1He^O)pwA#9zF{ajh)6jJMkmcy{17Ci9sGhMJ>n@Aro0(Z|xlE<(467&KuXSx3#rBot*q@WW?w5_4oJZvYD$_uFTHNEG;g1?%wU`>G|)`Bc4vX zU9N@s`Di3k$mP<>Q5bUv)X1zk9vD0iXM}%jLT5_1qIeSS%KK*6gu- z!C2`wqbNwM3Nj7~7-wxT`lL44AUd3spQ|LJy9%PB5`qO$Sdq6wB|RkbVd=>YQD29` z$ExHCg}eNczbCmD;++N*)=KZFq~Q>ke3Rr3nLj4;A0T7iPv^sZlnb{a6P-a$e}Syf zk=XqE;cTqoUNxiu}EC3qD&OAPb9Ekyuu}>kPw_2L>`A@ z0!LOd_&F9wcEdVSVo5R;b(kc7vzU>JBO~XS#B0u>2mzDiHp$OOu80&VJOx$GZ{l&N zTtlLC4Yg!JVxbWglG}&lXo{Y|$?~&Qk;+hUq#5f)Gj@(?7=ISW;JP(*e@Q2MK*RlD z9`>*Xe;|+5<{&*g@-7WlY{7-j6#h(HK%n+5%yEVO?kJE=tnH-N7SrhewTvG)K=nat4QBh3Ei<3$$AxqYbuP8jfzx9V%CX##EF8r4mq>@ Y>lPb{_hnc9kUjZI_G7Q?$rFM90g2o5bpQYW literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Window/ControlBar/BrowseNormal b/scalos/Default_Theme/Window/ControlBar/BrowseNormal new file mode 100644 index 0000000000000000000000000000000000000000..4c54d9ecd1bcbdacf551eab0acf87db557718638 GIT binary patch literal 858 zcwQ}%e@t6d6vtl+w!?{a{z?^HPmCnSkSH;kF-v5yF-EkjVTr_;xXj7;0}X5w`I=3t zvJDM&MM#KYYYH;l!otcNqzEKsI4lz=V;dukAjJl{Zm|A%z-!BU?|PSbZoVh?d~(jo zxw&VzrN}G@DMf|v=b88Bn)3xgNY6V`UUjr&Z~2ig4ty>MdFDO4IDJ+y^21H16}}a6 zG@3{8&RlZ=N2xnvg0Rz^`vJcX_Vn~f>uZaPiwph*o6V-m^4*!4=H}*y%gddeolQ+m z4u>NajdpZ&Tpt6q0r6A$$^0ZIhmZDy{p&jm+#*XE-l^g`Bp`7>ej7DINaiN z_V@Mq=jX3_Jm=clTrO9atE;8OIpXzRIDg)5w|94UyWQ@4!C+%Ub1rL{tR(+Xw3lj2`FNgdq}`BV;M%{r7rNJ$axPkLJp5Ms%KB%WPR8zwHZ%;=;szFkm zM}p>za>uYbT3n;s*BbcZ&x8;CI(meZ$^T=QwsV|itx;CU@+|guDs)>fzKowD|BG|%mK75Wn->2 z8LMeaMUHv!%FQUy9&q3&l$ypNH?sc1Eh6?}vlyQ!9Um75@Q3&n)$TFU@w2Gqe|wxz43tEDZaw58?!`}&+b$vMA^lP5Xn zknEV0DC(LN^&D3ztv(>|C%C7D5|oq4o#Dze zGX9^%71AmJW$$0-II*3R+rP zCMPHB>+ApVdS~z4S#i7le*fS1@2>@ex5mc}2E)C@MTf)D)zu{uiK?rsH)F9#B$7&{ z%F4=mdU|?$dsltFKp?Pi_paGwG8&CGn{9q>?$^OVyWKuLHMP97v=NPtj*d1oG+Y@T ze&F%AoX&xP0li+Y9o6>r{XAwI6Era~@#plkR;#V8t#!=L|8B7?FD(n{8Do{Q11C5x zb3gB6#9w2?L@KZm2A0FXCsas^owW77iPDGU;E#8MCxIo35xc0OcwA1&A``aTyRr42 z9UHP?c)#00!SDqNC*t56FMv-~VI{8{HpzK%p8J?QwJC%>7O=w|Fz1SKao--&?>tU+ z&67y>X%H$6qVpLg#@e$ebV5o$9WKX;vK4EmA~+*Ch>uDobkcH`OwQ|wv9Dl{s!=#K zh@;;(Qm02x&xhJD@VOc{l?Hs^Q6oD$k2(V5^tvaF$5|ML)EuONduZZz(JMh0sn`bI z4khs{dx+r>kBPzzy0yJZo1p}3!8G;;-Pp^#7|-PB(b&KAM=TASu*b5!3QPO}u057Z z%1bfI(}b`i9z)0NEy%x)LjA?J#B|Lx#e2|dZHB0Q3k|c4D1AvyuU%Hr?sFkXw_EUt zc@xPWn~-jNfjUbT=v2{JocD*Z%j(0GtQokE`00mt+DP}859;ea%!Z!ANFWbU-&Jxf z7ST6X+u%BS3C Lf+74$T7~}rP8ZpL literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Window/ControlBar/ButtonAboutDisabled b/scalos/Default_Theme/Window/ControlBar/ButtonAboutDisabled new file mode 100755 index 0000000000000000000000000000000000000000..f199d5117196b9ae305ec0a49765e7c8daf54a83 GIT binary patch literal 864 zcwQZnZA@Er6vi(t&}8b0$;>c*=!yH}OLWc;630?nn9R6ZvqZB*mxPTuF6J9YFZ&sI+o$=0wQ9&AyBrs0@byJd+*;n&&e-2&vQ<4 zzC3T4_nA0OUGw%{qv>6PX*b7lTa3r+>W+P3IDG7QUDao`A0Gbv$j6+~w5RIvjw@AK zsbUpp=kx^yk9DQNRIONr6>A(Y=e>a(QyWI;53zN5Qb$r)xrN2M>=-;u?(bm>8mwPXFbzQpP^R2C} z4*xtHi;WNb7+%li5_5m{^j!U8c2-YZWi(eE;5bzUyUU1$d6Hk}!ORTun!1;Ad1g>Zpqcp;|7psyX2m~^3~NJ{odS#Y(l;dsNV~KQA>9P+v=_D0K5R_f zCtKN*q!~#;oteVdBQZEe{((3>PWI9-NfQ-e)y9z3y0H0;G#dSlRDYhRPAZ>Im!`hbW|aiX0nmgskr%bYdqW);>hwr6%rK3g%xxbp0B- zPt+osuSNQ#o+5>MnwJkM|31Mlm`A*R2`M>CkBYvc)X6YbSv3}OlUNq3kv*5D%=43! zahS1k-;d1uUgRzcU>}8vJz*hsTG6jqAbp_Z;jEI4ZAwm#D!ioVy$ozc@%Hoh58Y7N AhyVZp literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Window/ControlBar/ButtonAboutNormal b/scalos/Default_Theme/Window/ControlBar/ButtonAboutNormal new file mode 100755 index 0000000000000000000000000000000000000000..4521975e8cb4b988b0a585a531c2ed31bc03f699 GIT binary patch literal 862 zcwQBfUrbYX6vuzX7BqWc*`LIOhkFuC_F}S4mSD0FTKt2{DCiz$d|1eQm|0{a4$QtA zw71Z1bt-|`01E?(u&Ij+%#H-Zs&p_Y%n2H@b ze)rbAV`psByKhxh*sE>!J&dszDvmcc)_-g}Tz|Z=y8e@o-mha7_IGa&(?5UGavYE`$qpM|QnwHJ>ej8tY_%QNU#NXfl!-WgUwY9*dO9OuY$nZ#b zX6BD;*S;GX0`A1`-;dt8J2o~pIQYxsM~^x?vp)wWV$s-ufBMG4g73_kw$s0PJU4|9 zB_+lZ6*apLF_vf5eKP4^86gEP9 zxzOM>;68(Ilfd^xDPDD+xN7j+LGTl=K(~~GyBcWHSw!5q37T^e&s2yPkzrS;MI54> zcpEv<2`+wxDr%8pW#kooq=-}45Z#9N1r%``o40;I@aEr zGIf`l5>p0WLsNJT-oyiZ`Pwn^R9>ZxNIx9yPmnqi!sgN-SgM(rKS$1yPPhsm!?G|B zuSlc7Y9+HIQ>NAfCjEl~$p=-Qh339Y%<(BPZ9ABw8(MP_%vXotoeq&{C#Qm)AA*gK z!!@3dd_4`P_jRgrtdc`}9(nu-+;AemEhu&#CMN$)(M$=7vk`Ff3I=r(jx}4zB&(#e z2hi1F{A4LYwRsj3triLjgq{Iaaa)F*S^pOgoV5qZa&Gm_xyR! z9^)qlj#HZUeyla@*BCzJIBtXXl-XQSt~p+D%6zcw%d*eRWuJ3e!$v+3`O!OyD-jiI)mnb?7ISiz~bU!e}8{V^U%u5%DHonlPCWyFJJoY=FP^& zMvuqS($aF{`gLDtr^Dg+dur;!`I-5-xhqXg6BFZOqoa3*hV=T!b#;CB?%p+-mTk6B zeSLjN$%Aw{T~jmAd+W|ZBvMe2+HZ{B9~tQq#qm%mJURK-@UYYAy!Okrndxb#L;SV1 zH8>cw+r!=tZ!{Xc-1tXdZ*N;$o6G5Px4AuTcSn1>*X!-}`|WnS%jNp9?!MJBlb_FI zX^r|~j#Ct}Vu3Pm3&hSdFcQF?5|H^ofTYf)#EAyVykCm7~cXXX3{+1s~nq;=s1x)7Sg#o@w_^ULvg&cLq%_OjFBoji@c%;z7>+_+LXlM=M}V7WTb4i zfgh>H(Kl;wh3~;Yo`sUe00oSd2-cP%ui_B0g(lqg&yplGlR}(D&XGF&=Lbi#8CB|Fqm zSWbhb4nuRyORrl7Y4p`97&rGIPq_`)ycgZN5_-7XMrZhEamjKP@k$Mx>dW}4@G9L9 zU!*hYEPQWy4&!U55f+OO(e0xiUq0PaE75Pw!IJbcCcM>nq~R&$Q<1bQh-vF~Jd$c5 z`HGMz4pO51U6NkNLFyJmOwVK0)QZeb`R_-s}WTooVXPVN}7*p=VOSOvFP6IBc-Gk1*ywOLuC}x^G<>Po>u-;ae&=>S+}SQHEEJ;A zudiL}?&|v1yEQd6 zQ&UqtJw1FRtkr7&yno;8^{%X})YjHot=97La$9|Ul;_u0S7)ZDH#atx78jjP=lIyz z(BNQeYpc)ayEif6@p!)P>}+pux7+PaO-*fWZF94;9UUF(Yir9(%QlV6VuxR((7+XlWpN0-@Bp0R6h6IkhIZ>^RCQnom#oK;to{R^ z6z9T{9;OR>>*)Mr1u!M{AwhK+)%V_pVFqMS)RPV)uvX+k*Lwg-TaP0>;-W~Yhf^X$9FCj@G$F8@6s_*P4(-9fMsT#1U z48m+Y%s1VdIL77Wc_$XZ0bth5~REMOdjg zgGf+LT&SOR+#+HZvk-h%4*vQ$A}J;kxjf=un#JzZB?upsoH&#LVO8QsBu^$K4+0V^ JmV9Y4;a?mP#{>WX literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Window/ControlBar/ButtonBackNormal b/scalos/Default_Theme/Window/ControlBar/ButtonBackNormal new file mode 100755 index 0000000000000000000000000000000000000000..a30af5efa509c84e5929abf1bb980bcef91c50fb GIT binary patch literal 862 zcwQZne@t6-6vZDDe}RROt?P6#y)0QkL$aXDwxA9ubsce~Mi%2BvBS-6f?9Od9dNNv z-ny~L?-`p>11yz)Mk2UiU|AEe#dVuxLtV3M7^oDGnUc~Lq_nT^>(g^{a_{||f6qSS zn+A?kyj6BUYbY--bVI_~X!! z%jJ4*PeuQgD{1MQefRFY^Sy8C;ls^+zrSkf+G+PTH#g@U>#%eTt^KoFQfbLPX#3$o zP!h##>)@Y$|HAxyBpi0!n%#EQ7hjJZIQoUSF6s|A>BgtGS2gW7R*H#4V0N~Yks z>JD*SYO!Rtl2l+NR$v9|kj<=+4l~3;jHKN&B48Y0yFih)kXU*LEJ_mQ0eIQ`GSGP9&-#NMjz@bPB|?yp(7vp!K|6sQ1RuIGBO> z?ptuB9;eejf%vcH!T+`uuUM>bw?@@7BD+$npGLHdJ%Rmq;Q;$KEP Bx)J~Y literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Window/ControlBar/ButtonBackSelected b/scalos/Default_Theme/Window/ControlBar/ButtonBackSelected new file mode 100755 index 0000000000000000000000000000000000000000..8e979cd26653f7b05300560d529f9c703d5e5ce8 GIT binary patch literal 864 zcwQBfaZr;57{E#&Mo>+I_6+0e2K|ep?eJAvbFyxI^4<3$9x-Cy4CZ-1>Un``x|o^ZxtWr#hr$ zn3((n@5+_$Wh)g7!${;+8qKkz@=r=D^3F_t98^9@cDeVCnh9kZ@&6Y z`O3;l$&sT)JyS_WN2caNU*FFuyYq}jqv}vWdwcuq=WW+II|l~`ySuxq>VMpJq*>EE zAbK`2;qa-7D!uN)NSF&HXicpKLr$S4wQova|E*%o{bJ$i#f629>hm+x)9j5KE|=?i zSJxf8J;Unm@9#JD_SUfXu3Win8yow5eB5F&&;9$@6Ijcy&<^wu@bUZo9UUFfXjHD+ z`w_zkv!Y@xMPA^kiy~s@VYJ{ognMMPmh2)fjYa613~K@w;Vu^3Yw7fG#7?VM{aD>6 z#v?8rTthmZI6tKO7n^9QG!1@98vZ`kh}FwK!8g@Nwv-&YyAX$&WEQt3L-3{M!d5>@ zXU_=e*UIfM?Z|+>H;A#kGPK1?sCB)Fmh}QWe9MQE=?`F77GbI69BtmUK#C3L@Nq&A z9|)EZy!R5Mr#zG>EvGZP3o&1^74Zd0c;2c*Ah(4Wt%F*hD~8!rjh0)RVK?u@H&z2} z_ur>C4p*b+vpq;^SVUi411!1}5?cKf9LdCQ=1fSLEeOO+;^kr&MZYSgO~qkIDl74} zZVNUx>EL!JQjzNcwJiRHV51Xn#w}wGaVTQ;P{Q<0I@rWw+npL@wpW9ZeGhM}olq;F zFPsx_d_9hxGeSH~9mkjJS|~qb19?{(;QYk^DPnO#*9K0ZCS6+$&CiQ58efC!5aAz1 z8GOfQsrfq*{qaLQyvLtlbp1212yK|;Sh8%DkYh-UKg&I^oKA-0(n)YZ8M${fQNX0d z<1!Vzx?Ko#st}5}D6pTU@cVu|eMN@lEIXnHWC$6f#GSZETx~HTGcp8O7eWPEMD)BP Rb3C=YAH%#SQodug_zwvCurB}r literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Window/ControlBar/ButtonForwardDisabled b/scalos/Default_Theme/Window/ControlBar/ButtonForwardDisabled new file mode 100644 index 0000000000000000000000000000000000000000..342d9a94ad0dadf8213c89c30cb327e261605df6 GIT binary patch literal 866 zcwQY+eN0<*6n)*GbaaTg50;7cCQkiB6I9eJQPZ^`%xT4sf1E@aTTRq3r?ATD=6Ki+ z%R*zJgw)h@g$;0+VcC|s4}%oyq#8iu0)LcXyFj5#LMd%%>0aN@r|0G-_nv!mb8d3V zE8o&_+~#**c}=T(U88%MSk z9T`~&hYbcpXJ=<}eSKwl`SPVpzuvkvG&D3YFmU7g_5S|;wOH(2cXw4)RUi;BnM_8b zF};y$ZEe--^*qlvH#ghu_O`aR-~9fi$kN}lvqCz(xUg`vwl)!uFWB|I^Kz9*?KX?Y6hK+ibRuj*jv1@$me7i^UQO1_uWRdwO~-77P0y z+RCzn9Jgto7-A$o#gjP7z+61U_ZY+y9{0Q|60WF;nbpWFsUaxb5Jyyqo1!Gt=M#&l zkU8Li&{PTW2^Ho{NfM3}5(^bdyaPf@g>)weKIa?>Cm$r{-;7M1McS{1sN4oqAWUgb zA*EdTV5}MGqJ!AD{WiXuzC($?4q7{%2iEr`5-(LFmeAnTw@b9es3t?{W3ZVBirv$w zzpatxE2R93r}&5&^|3A}!wH<0?UD4(QFiPQ30c#y=AFZ**(oS?d=L4>!<6Z|K*IJ$ ztX|Y&Yoif)Ka@iD^NSR3vC_t?*T5BDL2mJ0q)IM8+4wB2^*uw1Ym-p2gp{MmEwDiT zFzD+;@6g_`2VcnMaiHcho_pZ|a7Dk9Ez(U}l_!vY&oAW>aB}I#0z1WGZ&Ln!44<)ATk?og L@<I_l7$lSf` zOc#kRW`Gf>L#0N+u+Gtd1!bX)#El~w7hMP3A)(%JFUY~Y_j`NkufET|+w**$=Z|O4 zo}Bywk>m7xc3QH;JhS*R$8m{Shf7OsALQ6d%8E*?dA5@Gi{9h1#2wkoJ#M`gnhZKl z;s>gsByC>D#w@AFmFw=6t(Fz)px zIC|FX`8c7XBQ!hv`|xm|d#3p4nWe>W&P|^ZQF5)vQmnO+rKKsqfBn{?IazLMY8t$C z3sqk{cc^jQHzUD7;6{Icdt3X(3m1Holhb$Zq7IO)MxEj6jf5*(0WhqM>J7$j|c4HdB|dbn2RTN zf=Be4#v28&Gy&e_`Rjtl)Bnel@zb#>Vgnn9T}wmsbS|Qolfj-}i{ra}6v;~>CBult z)O;w-k0J7vfU4K0Xg(o{!lg#Y>vm#kTEM(dfUB{E_BJ1(VEhUgY{mHK85I@#v|W|2 zN#YruoLPyoNDv1NRvcez#YqQGrLp(vu+I%<_zsaz3ZN^gMd+cYDVP}`-6OjZUw07k zPdth^^C%upc$IWrnY3a!6Vbu9U`Q>1vU(h=*eM#{@+ZaI+>Cj36BgKJY~)U%!uCu~=4rxakx<}09c&DGF z`Z1gr^_Y0~O-vjzV{oH`lyBmz81WMjRBg9d`?P zD1M%TES(mbRLC5U$bmt~2Y9f0fx=-sMau;&N_MCzn(OyN6;xvTv_I+8e#Eb_3hnl) G9sdG~KDu)N literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Window/ControlBar/ButtonForwardSelected b/scalos/Default_Theme/Window/ControlBar/ButtonForwardSelected new file mode 100755 index 0000000000000000000000000000000000000000..46b2f4d0cfd75cfffc7f86a9fedd5381d06d9472 GIT binary patch literal 866 zcwQA!eN3Bm5dIaq6-Uy91-H5_?noV5G97V7F>|DAnRF!U-Z_>`5Hk!#6C;vr%s$3w zL3GPLSVQ>AbX_|U(}<2$90LK{Qda1SE3!t4z~p;ubylISl(xLS-sSS#bI<*8xjZ@C z5e;LB1-S=RnnOy>tBkP?s#E3VW$)*dozT5?LYr6eUP*CziI%A}2lfkUDw7E*#M%T_ z!4x9V|2$i%Q41sSzD35eHOj+6Z*OU7aXOvjV`Dy_Z)4r9L60X82;7}pd>a=yjthlC zI-M@_nlHc2U)SlocK5-DH%5N$=`owly3_T|&CRiB%;K7unw+e@)O@qOeSU842dlNS zvr}5tlk)mm=|@(h(dZZpJa@1($36FywxOc>%Z2;*v$C>wpEUYMMmBsuVz=4;xOdND zvHaN9*6(r+d531Er(0WFZ@b-1O-=Ip+reP4);>D%Fm%y5Wq0&8m@MZTu6A{Gb$563 zJg?&R=QEbDkAGHAtH1KZtMphk@Zi$~+@(jX)I`x6JjKlltR!tktk{NSj}4I_o*vg` z&`NR!LU|d8j&8+Ltpa~1XVRZV1`0`zVPW$zJl2LWU)6|N@lNvFowUFz zz|IF3u)OvY6sD|0TKr?`OG=}XM+_IGvq+v1WBqzFBrY2b+hsI;=NxvZ-^EWa)}dci z0A?@=`%jXQmm=4zLxEI@%WNKQzJ>p+>ED?V?00)zdZ@Vrx-w<5-cH5Zxqr W;&(mq&j>zwna65}z$HTU=Jp8?so-+>*^-#_3F!5ix;nceb{# zv@&9bsn9Sa%<`cT9g_x>)XDlmRj4wBEp7|24HN}YguVqwDQ}-=@4U~SbFP!~=j3|F zy4%8-_M_sRCd)3PA5 zm?16g|JiJ`6sah^AkLWCVk}Yn@R`$Rnwpw^?C7}j+nwIt-p0mrKb*f*Q&ZE^(=+wp z!P37^BYk~bQSMGm)YsRKj*Q&Cb?e5BXm@w-{M=ms_3Lq2uB)s4=dZuJySkFg36ICy z*48;QGZPGiXCFOMlF8|*sl|nbndygPV`E;gSDv5u`FzoVf!3Cm_V)H)1_z(a&U)%R zmo8rP`~AMoo{8~sx7+>aAHNUY9G;wXz$FnCJ8Y(Lr z#j}{Kg?kv&6mY8`-YJpTB_NJV;2Q+^VF}5AfrLdO{%bSDVFS2n9Lg~X@ev=1oj&3x ztPmwW@ajA$rFpoQswQD_6IY5L3jE+Mm9tz#p7Cbl!4DyH?cf0|6x~L+QpYG^_K*^K z4_tQvN!=-<^OVq9DVAZy z(!pHBRyAYgfEz3O^C-DyocJk$)C+r|YzSfHJJpL;)ste?lRXjyS6!)7*;5Js0rI2A AK>z>% literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Window/ControlBar/ButtonInfoNormal b/scalos/Default_Theme/Window/ControlBar/ButtonInfoNormal new file mode 100755 index 0000000000000000000000000000000000000000..7665bba98bbbaf01142c40eb2aa705abef268218 GIT binary patch literal 862 zcwQBfZAe>p6vl6^FBQs=uENUvkV6N9!JykL-AeCGOw!f~iy0e?jg?YanJvu5wYENk z=H5)Hanlj2;EFh%ShQW&sVQQ`n5bE2ibab;H|pA?)#|dUF~%(~-rT$Y&fy%M=Xbsx zo};!8tQ?p1QR#bTYnjPjP@vA*O3lAT9M@JhP*5>EtWNB&S_Vd=(dreJELqkK) zmX;F#{xdl-(ca#!D$0{^xUH>ic4p?hr&qbb4iZ`Shuot#~}L@>f@9XDk{GPE8H;_y2t3 zMqh95z3J)h?(VhK)hky#w}*#EMn=M+@b3>E$nveuj{BiUj~Aalb-UfIEv>ga9!=AV zirCW3w!@!r9AB)i%A|F(c|(R4(4fA^<}B0gA=>`3i+>nT%SOun zeq@^cP^R=yPwJr=jI@|lLW-penTcU2(6Zj9K;}bI)J9~4Q7B>-RBs`Ybw+YI zJ|#_ZF+Ya1_ySVi-Pjb3D?;qf6w<|>_q*ssYfpo=_AQd#rO(hY9}_t3Zw$foG-&lQ)E=2slSb-Zre9@QSYTN=DdRsaV#sX( literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Window/ControlBar/ButtonInfoSelected b/scalos/Default_Theme/Window/ControlBar/ButtonInfoSelected new file mode 100755 index 0000000000000000000000000000000000000000..b838073a42587aca6f43319dd9e4aa59e3e60a92 GIT binary patch literal 864 zcwQBfYfM`O6vuCY4If$jFbqabIEgj;K%z#XVA3~CMq;hmj7XwkiQ*Rw$V2ki6)s(~ z(I$%~CNuE^7E%y5>TtBs5^ir_L$<=&uoYp0*$rWrS`4JHQ0U`&{hyqi-+6pH|91_i z^$b(^aou}5{rg(|NrqvL>%Q*nY;CD)`J(kq)0a)3bvAv@FgpFI8fjO;ydZ_7qXkSa zqn643@2j=?T4_|INij^dUi*Q>{wI5TLqkjL?Xk<3Z(O{X92gk5cI~&xiHY&?ao+2- zSlm~By)rd5^~><^%*;$M7<|035s5?|J$(4!!D=Fr_;+jT{=Iv578d?oT$~Gs`}_Md znarjj7z~@nbB~hAs`32vqJZ6 z1kG9(wdK30h3`R!`W<|zs)L*hqcrdwnR_}Ys|rBiMVwN3VD)s|q?Tpl*B7=5r6Sr(@w}3!^4H%c26$nA*I^5_+xS1{V!ljhA@9V42$&;M(%k%9# zI>SeL#-981gCecII8VQyF{aX1$W7j*pG~ za{hdEb@lHZ9UJRwzh1h;bKHYa=;nf~YA9Bg$#Q1pd?%l%i#7cX20jE>IC z%tTjKdV6}Nr=~m}&u?vQKA+F)^;)e~zt3+nncQx--|r6wgRAj)cy_kEy}hfmb7^t0 zuC7k_Us^-KCyYrnLc~t|xIjXN9m3xN_)O6@JGR^&5`NAm?sGL#V|H-mBCpRzJkv)) zm&i+2L~Z~#?F0X&33Hil5`M}R`Cmvq6Z310A}_=p`&kkO)x^mskaC#8&7B3$jQC;k zdrJ8B5HA~raL0@-c{4We8_}@wA;pbvQ0k-;ykrm7%x@#2co#{tpH7te>Bp62G}2zk za%xZ+$U!vKM(f%rNkU%(SCmN8y@UGJ?QnWWh|_css|kZQr{jdi4_T2Cvh`iW(uZhu z{|I7d(h)wUg(9sGibN?TRmW-dffZSbBaozN@Q>p?#4>!euxp8SAD)A}#*bJFgX$3B zJDrrCl!Qq7$}N0Wx(|+G4JwwDs5PD=hf6^_R9Ps$7)Io_6!JP1WZn(RP&>{I(}Ktgjl|i$qW&WuJj&XQRWjk8!hj{+Z4!bzNcf@?3FIQ| zup?ZQi^%(S;*@HNXN!ODHz4xb1QNYg@Vr2YemiXzd$7e!NTl1rA22~MiapVZz9sg+ MEV4ragg@>07kAUZegFUf literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Window/ControlBar/ButtonPropertiesNormal b/scalos/Default_Theme/Window/ControlBar/ButtonPropertiesNormal new file mode 100755 index 0000000000000000000000000000000000000000..041df819c87ae59fe0896462faea4e5885c52fbb GIT binary patch literal 868 zcwRk{Z%mtY5XYZV)&@*;xEUBadoLEIQ8PC)6EkB+%Z7_BB@km8C0(;2VN5!@E_@e9 z|46rKYNU@%%J0(tPUlUrS447oArwU;h2}?b;S|$I%_r)6?I6T62AHaNxVo z_3qDFjJvu9e)LXF1s4`(CokL!c}#(T!|i!>%VVSdwzn?^e$Db10s)`zT%BS6{M_8+ zZ(pBg=E^oK+xQ&=yEE9upM65S#Ynpj}h?ty_aB~QJN(sJh27KCw<;DcD zN|VSFBKLvcYyiD0B+UAK#-X$SA1-{1xzPwe`4X_`I5-ZiO`7?7a zWQtmm`9%Tym8~R5?-E}&gXI(BNJ_UO*}MsPRzKwitt3cHIN74dM-C61+*!!Z?4(?w zmQK6>#JbustaB0M6^9{p&XBX@D>_au;=}44$j8@!T!sgQS-QVEPLcNu5EEorpSzEu zf)rBiaeDILG(EFef`s!O6k6M{n70e1wHryk@;Bvc(uf_}hIn5Hvo*75dTu)v-91Le zy|3Vl&MHKUo#>2rV#~|>$uQPP-^3d5g6dgViVLtUxDPV@2C{u}oE*uM$lkQVu3kWv zUW4_alWb49X=rI24)-~{9=?Se+Vx=SQF6+MY4wjL1h?uC+GK>|T08jm0uq!hB>2@B zse1`QGU9xF5$?$o6tXqYEvppitBZKR9Y8vF0L!IHism{f3mqc!k03}okZ2O`6Pcv+ zoPu)ECy-V!@G?=$6j<>XDEF~~*eQlp+YE#f1(??WVUPF=*Tp|+uz_V5*wdmihJOLu CWW06& literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Window/ControlBar/ButtonPropertiesSelected b/scalos/Default_Theme/Window/ControlBar/ButtonPropertiesSelected new file mode 100755 index 0000000000000000000000000000000000000000..fc68f990d0eec3a956c352dcf3c86b8c9ad27024 GIT binary patch literal 870 zcwQBfe^8SJ7{^~2f|W{|7m=4dIXw@r6Y1jcL>rqFQhON}dWQWVg4uPDqc!fnU9Jsi z;nhw=OUalMf6>W6cW@xex#3ph(tsV1T;RZ__XZTBIdkx?y}dopeeQXl?>&EhURAxp zGK}QiJf(uom$R=h43n&=(&;n@3bdL^wO03``jbL+g}PLyE@K!4yDLZhSj{{mwpj78 zjFFMW#QcBnl(V^F6qg-jn4PS=K-`^`m74MK@iS+dJ3BgBTU&44yy^G*OLuQw%jWm? zUURuzEL$);JNqycsw$QJZ2RKPkG0ymLmfwUTPzln>C1XuM$wVOjkj-iUp{ucyX(sI zbcE;c4W9Qo8-5)f)wH#Fz24&|PGoLa=DDEXV{02682H9w`Dr0CIx_6)bLMWBp10XJ zj(ex1WMp`FY;4SN{raW$cH@mcyWL*?xiLqtpY-`!T3Wt3T;JW*rFHjR?dh2h1eDfh zcYnVi2ntnB5yQl03rzwEX$Fc01PHf8VhxC{5Lq)xk%|=J0}cpg86qS@xLusCL|S-O zphxFqh{^+4%uYj4gugLK^R*tDqXa}^_u}Dc4qP^e2Z=m!CzELGpqM|Mg;@ybUoPOE zd_4^)Q_22hEyBB!;K}g9xUK=w9Ritmq|@JdXEF8CV=(9ai=*aCurBVWuhSLup89#* zea(yUly>NpbLh-kPsvZE(o|+CT(3WeRhs*VUz!7{@nu@~{V;h$+u;9f2`+yS#NFjV zto)6q!p@Bp_W4ksREE_vbvRYSVZ{hXGeHSCU*I6w#K5#n0@ErPLKmxPOHmeW*xQ4+ zZ?|L1g=DPnzYjyzr{uF;q>1i7Admk6j=~rSS3W{oy@}lU`)Fw61m1tE1e^OBp`oo% z6}u^}b{h@t3&R*Xhg9bfX7;Sao%BB`Bk>gZ9eSKTP=w9#WhlRDhGoBr{#x>g{OV@d zf02TVVe$Lh$*`5l>F5*FG*#}w#L~0)@$qW7UzB37LQ3~euAwR3kHPOe7^#t9^jaO} zly$UNlS%Wg1k5!gKrrS)u&eN3Mn(LgVhV3^V16P6k?LYZ?j(Y5veH7zBt;K85Mc}m cH(9aRl6vqD)M(Nl<7PmEifU}S+*~~^Vzf5IP5XVa_5EGpUlXWXb#3>e$ht=#B zY_cw(WilWkyeT7~Zd10AHKALnMy;t(QDJd_wVDcJjM|nLTQ2wRZqLb+obx-+$LGWR zU24W6_vGx%Q0JwqcQD2hGOCUrKYC<$MP^y0=F`KaTE;Te*_qO3JyS{}DO$!1EG;79 zzk7SSI!i)PssLl#)#(M&K78i%X}w`wy&52vTKTCGl}Gnq_$I6OZ$H}mxA{d@NogTcwkN!RFTcV}m7 zYpdhtO~21KG&I!H)6?D6^=(trBe&b>bbf#7((KI4Kl6W^&E|%NhQ7YOKPD!`|CN!S zS;&}7B{Xs*o)Jmt;2^%tK`0O*=s1Mb63?-bsBwc&DFNRo@sSevvwb8sB#{^y5B`Yc zaUX<3CGcd6B;J-wJO%u_N5L<-AiSLf`_5Go8>RdviJzzjZ+Al26AQ!UH4+mND6Du3 zV%8>v?>iA1%R=4WB@!cEr{#B2u=d^uSWI@pZ_U9AW`TrbiFC3h4)rlDP!u>&S*n5V zXDbQeP73z!L(G-FEgO%bELhhSqC};U6rUY{GSLgq7muO%BpUkq z0G*7nQuIn0xUxFb)l@*=xDIhe9y)QQoa8eHp8PsXZ3e{RTKx28drb)9}I1$#C}x>?Rv*&*L$y`vL8<3hHLl z)bp_yO|n9WvaPuNY7JbrA{sW^XsSYvDW=CWmWFGpH2C^|rRA+01sCG6n7e`}&p6EO zs>YfopF#^hS}9I}u)~dDw+rF#Tv%mYw7MmURu@YUe#MPYwA6{$k|4avk&r6cFZJM# L<_5^>wyv%&b;6pf zSFR*hbth$)IUJ76w-0`PW9)^JuRQnf@9pr6j*PsT{^q7{-G{$ytgo*(etmuU>C&~~ z8CjBofj~;#ZQJdsXW`H*ogTsBl)_T-xqFF)*s%N5(A~Sq_TQyQWXrbg5B>hs@7#+E z3oR`zcU-Q(+?>`ie$j4kXlTee(`U9i3J0biPfuH$tq=ZM>S%BG&4+q=dVU)o=Kocm zL08Jy3az}JlYGrYd=m$^D4FGuD@=G+DN?kGlk|=VzP=UF`f|u^tqA&r|NZAVaJxZq z0dksvDc{SAyGVMXxW$C%}WvQ>>mjT*;}XVJ>dtyIJM@N_3oTVlZR*9|!9&!%In znS>KsL_Z3_*sa6q*#T7bUZ7K}j8v7h59iNMC*zVL3(Z*68lad@J2C&lWS=rD}jV3Nf7E%!1gh)UCQhMCzs1LoB~;KJBua#UDJ4B8>~528Pz z6u!(~;gUY22~`?-rF@L5Z174q;bm=@jWf_A*+BF00_Glz2n3cf86LuXsz?F+NRmpx ya;>t*{XeJie!et2u}5xUp#o0m=iFr$Mk; zjmj8IVO()LB6g7naaV&lLPL)pT0fsp6z+x_xbO6viU=5 zj*}eDJ)ltM$<=Ri9Jfhvs=U1TWPZupx({^Pa$O<>PE zTvYMpiDGEm?ru6*_pbSm*bUDmZ%ga#?H#&$)nG7KESB_!+sbU-Y&LiN*kLpp2L=Xa zA3mJ+dc$k$NqhK~mX?<~#(3?g(!-@``L$b`N9O0|CMG6^ZMM$N&R@E^`uh6ry4|ut zk7sJCySw|r%#8HBU3GoF^2$_udwbP|{%dyolrI?Y`<+f_Pj`<9tJOLakQL`j;9h6kA72$1A|%#}U+4VAj-#^-ezps*1_ml!!1tj`=YwTp22?97v$RLL=FC zbRpEZ3wBEcwI6*5!L*U4g?Re5bQz1=S5W=_el-8)1e5dhjXRD^o=OCCzhgEK!jYjo z2w!|oj@DXI_k0h-@IA!O6e96-H15AFr#zdBN+tQ|NM3_gwi`}KGDfB~WML}0b0Zfe zm$IRerJyawh&>cX-ZLDzQ&-@9egWQN&tSv#L}VoRDf5hkxWoly)|X-b*Am3Vl)xyd zqvmu8o$ISX#O+6hCK~Q{9wEo^A~gs}G*`40R=ydnG6}ZVG~sW>5o$VFNRE*reEgOU zv6@VHYCT1#jWV6Vf O3_?)s$ZI0adi)3Dle`B2 literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Window/ControlBar/CycleBackground b/scalos/Default_Theme/Window/ControlBar/CycleBackground new file mode 100644 index 0000000000000000000000000000000000000000..258d83c40624da41a508db5098cff6b6ffa9a54b GIT binary patch literal 197 zcwXxa@N?(olHy`uVBq!ia0vp^JRr=$1SD^YpWXnZSkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-#$_jGX#skoJ7S^SKLS&>1&!H36% zp@AXk=a-klj;;)hN0hX+y#oXt7&g}Y`7v>UQUin1DPIOgmnpLum^w7f8Ce7Z^O!gk p7TsYHaB$hlsnF0-B<#?@$ezSW(6Vp6>`gY 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 literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Window/ControlBar/HistoryPopupBackground b/scalos/Default_Theme/Window/ControlBar/HistoryPopupBackground new file mode 100755 index 0000000000000000000000000000000000000000..20f441827eab41d87efbfd14ad443608d61947e8 GIT binary patch literal 816 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 literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Window/ControlBar/ViewByCycleFrame b/scalos/Default_Theme/Window/ControlBar/ViewByCycleFrame new file mode 100755 index 0000000000000000000000000000000000000000..4caa7e901233e94dd8d946d9af15afa47046e09b GIT binary patch literal 2080 zcwW6#`#;l*8~@PGFv-y2pv;z%2*=o#jI4zXtwgnb9hWePI49LcIQte($)!T83NujkX|ag*PdrYuy`qMeubK+i=KqZ)AJ&$caNk; z8sWftKGu3wZ()EC>|;J&(RVVRgkwy+$fp`r=>oS8`Tf{3;Z?O|x0(0 zR!>^eXpQU%7JGT~x4gg3z3Dw2)UX^9#9?k2+7()9YqotrJ@)=6+XLhK@k<97 z07KAg&)5ZAn{^Rro@MKrn+>6)F|0-%I4?!1kmPYF?1q9fh&!gu4o0K0FC!|IYPq$w zRUdrqxdw9cMK27%V3-OUSNwdEeYX2$V<08cx#L^1;?TuH>Q%)M{%2}*^h^RxKCYVH zK3Zt%31wWT$HvY*I9fY2K0dyoQK=nRuu6S~beJ1%4Bd2h;*#*whl4qM@BV;SqY_Ew z;_Bx)@7{GJZXw#KgTNGIuYssFH|VbEER>LtnhW= z?>Vu+WKX$L+OAIS?7t0LbrmTEwr+s|8;v~qV`a~oo$Yot! zUPaeI2B{i+IIFyP#U#DXV*q^%RPltz8`orb=UJ#0r9-uw2t-q7IF*WE1(jD9aM*0N zEjs?KvL&Put&w8!*@gcO8C=KQldMq@E>iS9+d$kb49J~pQKX6^s2P)&lnAk_AtMvY z0s{l(9-GTe(F44`M{P`D9BT9Nvu7(D5d}EyUHl1hg8DS1v6jLXF?XYo=qjC&;5yGg zN_%W~fHYQB?kQre#Ty;|z^yI??s~98T&kFc9XK2*J{>nOZqspMCwv!n09lBK5a6NNMPEVUKj+-L6{;S)G zg-gV`6NFW6NACjfO%LA8z-zi zR$n!63t_rp$54h)YpUAS+sqg`e=<$o5bal}7n&R=v_28lQDmV;6F8!%?%tE?6og8V zJ|>j^-_m75tF}o@7!{Liv}t}kv8);Pwa6wyXsrrYa#efpNK`@Sin9fKq!EEwDM=_N zhUL365xUb>ss<2Bns4)an0nIx#k%&SLaK?$aL}>As=P7cnA(jZtWuyL95E(qx+~Vd z5G&OQ&v>a!OtgQc++P@zA72@MX*Go3LQE0ToyiC>>L_FXL-Re7bmR-roOwz;fnCDJn za*+$-tCmon9Bm)MrB@Em-JZm}SagGh?|)6-Ig<1pB$G)XlD+8zK3-l&ZXj_8yZV!P z5T6qAw!L?MDk4&ZT5D@-@`Q12Qr(c$8HGZ%G|aKYa(&y-z10&f_UeNRfRxQdmD%S* z{;dtStOg+`6$)qo(YeI`#-pnDK;Ga zc77UM|G;s*+PBCaAM|Yw+2o$Y{doZ!D_tu^k%P8s0W=zI*;D;(Xsu(3c&ilgvfl`i zYGJx`S{S`=eYV}WQ|kiV7zZ`zvD7{XEUDI(H@8ik0iq-2I(&*oO%fj|#wZ4vEN3%7smC7}T(IC9Oq1L+ zDs(Eonb^VD_QIe0+}jCZovF(W^a4atZd^WYbOJrTkZ4G8Nn+;1}9Z^4jn3Y5dS7ZSnU z2tmH3-xcRvv_dtz(78eKO+I`(!{fZM@0KoV z7T010t|ecnQFP#?|GG1B0FfMak=STR$PDH1i^7%g7|nf%rYzp8z}JfE-FYPeH>Uz0 ptLbywe|a=^6>_4}7D-kd+&A2PT=i$YgPQpP!jYr+23*+He*l122!Q|q literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Window/SortAscending b/scalos/Default_Theme/Window/SortAscending new file mode 100755 index 0000000000000000000000000000000000000000..afc0587b699002efb9066ec8eb82653770f6e705 GIT binary patch literal 3216 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 literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Window/StatusBar.info b/scalos/Default_Theme/Window/StatusBar.info new file mode 100755 index 0000000000000000000000000000000000000000..d82ed8b856bafc74caa8ca748317f471843a28ed GIT binary patch literal 1695 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∑EeED^WW4)yaigw8X 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 literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Window/StatusBar/PadLock b/scalos/Default_Theme/Window/StatusBar/PadLock new file mode 100755 index 0000000000000000000000000000000000000000..1712c94561297dc35d75ed47e58fe9833c0dfc63 GIT binary patch literal 1508 zcwXI<%}T>S5Xb)wDIz^=1L9e8QK$!xo=Wq9vEW*%1{6;|MXqzqL-+*o5%MAm<`v?; z!8++~#6oEgAw4)ln4S3zJF^p*>%~$6!>{>mC_{M@131DVMr`3aAmHM7Fmn*e;GRR5 zTI;&5tEwu?vM7o?&$BE`(=?7_-}gPw!@4BPAZ)H;9Y%pnR%d7IKF;r+xvq;D&Y`u! zCTZh6b0L&AzD=`MKd-_!Ehzo{Jn5kzODa0`L6!D@?G_N=P-To?ps?VfBa57T*SN!@ibjUr+C2?Yl2st hutvZ3jUF(@H%;(K2OxT*2z{z#ziF2ZTVt!o<+Pz@Q_>=)lC_?CTf+6f*e#|Npyp z@9y5cd*;lU-Me?MTD5BC%$Xe>9p&ZaX=!Ppp`k7=F2=^jN=izCf`UK|?m>=DAfp)A z8Q7g2eci!qCIOZZPrpc@y(|n43>pkH2mJp((30l=07A5*!E74R478{D|No~Q4e|#l zCdj1uK}PX2(2V{MO)a#d8K4wRX=2h5xiq2lPbp0(|58j-2Aup|fMp>=0gTVy0D%$- k5U3ykfebKM1Az(_5Lh4pfj<}^Pyq&^`e5e3%!Szl0I&TUp8x;= literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Window/StatusBar/ShowAll b/scalos/Default_Theme/Window/StatusBar/ShowAll new file mode 100755 index 0000000000000000000000000000000000000000..059bea62fb8330f13ea63a103ca1eca7e94c8494 GIT binary patch literal 1500 zcwWVnu}T9$6h*JgMpT4}BGyAH3kyFXy9vgClPn>PU8?Q(53Ez9kA)v%W$%KGAF!YB zdW-AZ8ABRDn|0o0IP>Phn+pSTJ6|}U_c6WCUGDD204~tSi4tjoN8tMMV3=U!vOfZl6~hyRmQfvuXS4HE1{I3ukYp00000 literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Window/StatusBar/ThumbnailsAlways b/scalos/Default_Theme/Window/StatusBar/ThumbnailsAlways new file mode 100755 index 0000000000000000000000000000000000000000..98140096dd295fa3cc34f6703093585f7353843c GIT binary patch literal 1516 zcwW7fF;Buk6vzJ{DudxlVj`OzJCMN0coZU%P$0xX69y+ffr*KO>B#74H|Nf7deYhVg|0P{H}1jLv7*3EnfDL4&)w(OslffU-2Tr!aGoELmSoz@^P{%sD+}l8 z9;+7I# zm9a_Wb;)(ZuT`;fR+ng zL0%!Cg@uJ8{!|t+Wr~ICof!oc1aZj@40GpvcW2J*9cI1Jbb-uWZPRfbccTJe7BiTZ z5$PnlK%tN*CQx=uTOut7K_CM&d%dCW`$K7g&%=N{9Gx8U8_)ypfzb#a13|S}a`aM| zLZ)1Dt0qonv0bb0$i8V5k!RcRTZ@Ym>8^~VRE(Th=E6iX{Dg$4&RDg^nF|BkrHYd(u z{<;o`OvLJ2{iAZdx4vI&>uV&6l{5e0{rE3;8Wnj9(c=b)R*KHs1--`&r?hI7}&{1UD%R*vhE7cQQUQ@45@yWTrrAqryv literal 0 HcwPel00001 diff --git a/scalos/Default_Theme/Window/StatusBar/ThumbnailsGenerate b/scalos/Default_Theme/Window/StatusBar/ThumbnailsGenerate new file mode 100755 index 0000000000000000000000000000000000000000..268d01d67d415b84a81ccb13921b0196a32b0ce1 GIT binary patch literal 1508 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 QkM~70Ve!6{jCf}N0G#_HYybcN literal 0 HcwPel00001 diff --git a/scalos/DevPack b/scalos/DevPack new file mode 100755 index 000000000..6f07042a2 --- /dev/null +++ b/scalos/DevPack @@ -0,0 +1,106 @@ +/* DevPack */ +/* $Date: 2009-03-12 21:27:42 +0100 (Do, 12. Mär 2009) $ */ +/* $Revision: 94 $ */ +/* $Id: DevPack 94 2009-03-12 20:27:42Z jlachmann $ */ + +LHAName = 'RAM:ScalosDev' + +address command + +/* +x = statef(LHAName) +if length(x) > 0 then do + say "Deleting old directory tree..." + "delete " || LHAName || " all QUIET" + end + +x = statef(LHAName || ".lha") +if length(x) > 0 then do + say "Deleting old archive..." + "delete " || LHAName || ".lha quiet" + end +*/ + +"makedir RAM:ScalosDev" +"makedir RAM:ScalosDev/asm/lvo all" +"makedir RAM:ScalosDev/asm/Scalos" +"makedir RAM:ScalosDev/AutoDoc" +"makedir RAM:ScalosDev/C" +"makedir RAM:ScalosDev/C/Include" +"makedir RAM:ScalosDev/C/Include/clib" +"makedir RAM:ScalosDev/C/Include/datatypes" +"makedir RAM:ScalosDev/C/Include/inline" +"makedir RAM:ScalosDev/C/Include/libraries" +"makedir RAM:ScalosDev/C/Include/pragmas" +"makedir RAM:ScalosDev/C/Include/proto" +"makedir RAM:ScalosDev/C/Include/ppc-aos4" +"makedir RAM:ScalosDev/C/Include/ppc-aos4/inline" +"makedir RAM:ScalosDev/C/Include/ppc-aos4/inline4" +"makedir RAM:ScalosDev/C/Include/ppc-aos4/interfaces" +"makedir RAM:ScalosDev/C/Include/ppc-aos4/proto" +"makedir RAM:ScalosDev/C/Include/ppc-mos" +"makedir RAM:ScalosDev/C/Include/ppc-mos/inline" +"makedir RAM:ScalosDev/C/Include/Scalos" +"makedir RAM:ScalosDev/E/modules/Scalos all" +"makedir RAM:ScalosDev/FD" +"makedir RAM:ScalosDev/SFD" +"makedir RAM:ScalosDev/interfaces" +"makedir RAM:ScalosDev/gcc-lib" + + +say "Copying AutoDocs..." + +'copy main/docs/AutoDocs/#?.doc "RAM:ScalosDev/AutoDoc" clone quiet' + +say "Copying asm files..." + +'copy main/std_includes/asm/lvo/#? "RAM:ScalosDev/asm/lvo" clone quiet' +'copy main/std_includes/asm/Scalos/#? "RAM:ScalosDev/asm/Scalos" clone quiet' + +say "Copying C headers..." + +'copy include/defs.h "RAM:ScalosDev/C/Include/" clone quiet' +'copy include/clib/#? "RAM:ScalosDev/C/Include/clib" clone quiet' +'copy include/datatypes/#? "RAM:ScalosDev/C/Include/datatypes" clone quiet' +'copy include/inline/#? "RAM:ScalosDev/C/Include/inline" clone quiet' +'copy include/inline4/#? "RAM:ScalosDev/C/Include/inline4" clone quiet' +'copy include/interfaces/#? "RAM:ScalosDev/C/Include/interfaces" clone quiet' +'copy include/libraries/#? "RAM:ScalosDev/C/Include/libraries" clone quiet' +'copy include/pragmas/#? "RAM:ScalosDev/C/Include/pragmas" clone quiet' +'copy include/proto/#? "RAM:ScalosDev/C/Include/proto" clone quiet' + +'delete "RAM:ScalosDev/C/Include/proto/guigfx.h" quiet' +'delete "RAM:ScalosDev/C/Include/inline/guigfx.h" quiet' + +'copy ppc-mos-include/inline/#?.h "RAM:ScalosDev/C/Include/ppc-mos/inline/" clone quiet' + +'copy include/Scalos/#? "RAM:ScalosDev/C/Include/Scalos" clone quiet' + +say "Copying E modules..." + +'copy main/std_includes/E/modules/#? "RAM:ScalosDev/E/modules" clone quiet' +/* 'copy main/std_includes/E/modules/Scalos/#? "RAM:ScalosDev/E/modules/Scalos" clone quiet' */ +'copy main/std_includes/E/#? "RAM:ScalosDev/E/" clone quiet' + +say "Copying FD files..." + +'copy main/std_includes/fd/#?.fd "RAM:ScalosDev/FD" clone quiet' + +say "Copying SFD files..." + +'copy main/std_includes/sfd/#?.sfd "RAM:ScalosDev/SFD" clone quiet' + +say "Copying OS4 interface files..." + +'copy main/std_includes/interfaces/#?.xml "RAM:ScalosDev/interfaces" clone quiet' + +say "Copying GCC libraries..." + +'copy gcc-lib/libscalosmenuplugin.a "RAM:ScalosDev/gcc-lib" clone quiet' +'copy gcc-lib/libscalosplugin.a "RAM:ScalosDev/gcc-lib" clone quiet' + +say "Creating archive..." + +'lha -r -e -x a ' || LHAName || ' RAM:ScalosDev ' + +lha t LHAName diff --git a/scalos/ExcludeList b/scalos/ExcludeList new file mode 100644 index 000000000..3f1a4f26c --- /dev/null +++ b/scalos/ExcludeList @@ -0,0 +1,12 @@ +*.lha +*.LHA +*.lzx +*.LZX +*.tar +*.tgz +*.gz +*.o +*.lst +*.debug +main/obsolete/* +Website/* diff --git a/scalos/Extras/CreateDefaultIcon b/scalos/Extras/CreateDefaultIcon new file mode 100755 index 0000000000000000000000000000000000000000..3057255f353b6f379f2b998b0e19dc339a935f1e GIT binary patch literal 2176 zcwTK)UrbY182@gmr8W%~hNNuGJh|x@?V1)BqK^1*fibT)c){WpT#R0@^uj2#*5Y(w ztPrD+&4js`Ez4qfFnh5fY){Vcz>;M_Gz&x@a53To1m{R3ju=KN-S6BMaf`S8&iU^5 z?|lExcZu@;rtD+N?E?NcvCBkxe{x)2>|1xsZrcA3XZuc*c^}8dJPc^NMrRa3%5cAP# zOVXf8v?T6@2ZB19sZx?UnTkMr_?){s4God(-Q=d?E+;6nuyf~Pik7OEXqxq_qtD!$ z$uGf|dB6iu@39oE<}}QlUy~B-F~T`iLF(xG@7&+oHDNS{w`a4kIT5zRLK@K{PbYmV zSe2`Yg{Y5pQfg*$W>Rb?$L$-pZ!lAwib_5E1)AI>p?=O}Qj%e7 ztT;eA2~|vj%p@~4CGYeX{zL?90J(cwI8Kb?*hOY4{E-n84o+oO9e58|HKqD5Is#vl zx%~@|B-jJwmYA2^y3-e-2_}i2=SkL>F8 zyxtgTW)>i`J3{F<$P=M^w94yyI7RchjM;bwjjWpe5t?T{!K|B^qz=Q*Q7)U4D^gN4 zt=oAOpgqeq{0b_&q}#;^J>-(`$gd#xI^+I|KEbMU+7CHiuLy4u+c~X>Q=ofGw?cQ4 z>tUY&ua)hnpZly&?FmIs`Xe2!@s{`*LT8PmPZ_#twT(>YE~kZJc`<*NKOj_kqr#qV zZo(^f?PGF@v)P|=Ubn<-8VS2KWVGa)*BhL4$n|4@l<-_t1bx}jwgrEKi$t;qiJ z1|FmOxyXb2$g$d^o(SakQFDqCnp5!!4tRAwY=d-y9aM+?28ZEI84f=v?Il5Quzddx zu6MYhn$M7S|Df(*XMly&Vcd6ftk^EasJTJy$w@>YVcn46boB&>%V}zq7b|wvuF=`e z8hIt7dc`e7U!(U4_p>~cVFKcG+NGk|retWXX1CLMY07s1IdOVq8pI@^#HU|Q-WfPm zj_eNaTcRt7^NL|bMXdJwI7{vEdRbGV<#;D+IMo&pN1`7yua~H#=}*dAwNg8nqV73*@`hV_wS zyROE?F(F*86@c#rW(i(Uw(A9kJUBYj$rxSjAr@GU`{qkV_l zTZ~CI8BFqwEhOWDT+OExCWb4UH^DB#E9A}vuZA3jFY&4n7S0)dH3x^v_Os8M2emzr zHQzgwJB}H Xo}<$k;ClcDCAa_F=Mg|6C;#MMeiU#Z literal 0 HcwPel00001 diff --git a/scalos/Extras/CreateTrash b/scalos/Extras/CreateTrash new file mode 100755 index 0000000000000000000000000000000000000000..1174d748514669a5cbc8f9ec76d96d994b6d9e7d GIT binary patch literal 11579 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 H`uYC@<`<;D literal 0 HcwPel00001 diff --git a/scalos/Extras/CreateTrash.68k b/scalos/Extras/CreateTrash.68k new file mode 100644 index 0000000000000000000000000000000000000000..da489202079665de2efe1c2d2a44fa574a0fec9e GIT binary patch literal 20424 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 Qgetcz%`8f>$f`a63vZl2(EtDd literal 0 HcwPel00001 diff --git a/scalos/Extras/CreateTrash.info b/scalos/Extras/CreateTrash.info new file mode 100644 index 0000000000000000000000000000000000000000..2faa51503b3453150447a275bd1b75f7473a0c17 GIT binary patch literal 1911 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 F{U7Im^|k;2 literal 0 HcwPel00001 diff --git a/scalos/Extras/DoCommand b/scalos/Extras/DoCommand new file mode 100755 index 0000000000000000000000000000000000000000..d3e9df7faf3c4e57a69a348e9f00626a64c70933 GIT binary patch literal 4144 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 literal 0 HcwPel00001 diff --git a/scalos/Extras/NewIconUtil b/scalos/Extras/NewIconUtil new file mode 100755 index 0000000000000000000000000000000000000000..fc2785f69be47ae131a26ddd742f2e18f67e7942 GIT binary patch literal 2348 zcwTK*Z)j6j6hC==#wsUr5prFj)&6QAi; zhjghF*D{45vdIuBW2j*0y5R>m`oRr9)FD!*A3Bh=$VxXSQ=G^qwcYQ&yw*-kIrq=+ z{O-BuoO|wlC93$F%0JQUD~K$gqkj{!2C@Rs9~_I!^v-!BUTXfA(*ivtzQacao!BPy zHLBqIVe8oZtUped{R$2Ex-4$Co=TcDJ-}pEORrB4s8+VJc!4&0R-PzW`}k^qm_|oR z)RSsu0qU_93{0jG&nB{vMH!yo7%gZdR01n4YDdSh!b4IQdC9%M8pvtbId!5$BjI~= zlJzOWPra%Tl;O*H$X7szScyi>6(ZNymuNgk*oQWdGCX&k``hruGMvNg=>%-{r>(h^ zN_5x1k519G=mo?=)XVl!>BiWNF;6EsZ(hB5l?ggk*7%$0%6Q-If*>OUG8H2;vivND z*rXst3u#-<9U_e^8<`BwF(zy)-0E|EON7x8mT)=6G}C(inc z^1V=iM-uugIZ{OyBGH?n%j?LWp&=UO=ewgs=go}Sc?ONFiopz>$61YOB9oOO*6-w8 zlUErn(Me6>r-0R``HEl^>=8}!WT?cM@F)n@xW>4@o&a6bICj?59R_b4u^m+_IfAuC z%?9ikUx&UQx;<=dZ1Uq?r8|{97|iV5qbK!46zQRLh>?7>YKtRwA!kv#O(YO3(IxcWwz$%LW|pML468yks~hf<(=);UlAlFoRE8Us zalQUrBuj4CuT2t7)XDMtB(ZmyEnS8AX#KemyrG|yU$(>z{u!1fC!)TDSnl{_wgpT# zY-Fefyc0>9{|HRGn#a8nHJ>L$ZcWNtnB3n<*4OIEic_lA9H>B1pZk$xVPNaYrum{@ zbFL2V5fcYe=Gt;|mpLYbi~T)YOb>2{?AR5a&xYaB1`OK*gX78pUadU0Pow2|WQMBh5F76Fgd``9 zJ6Gv!#G*acUqbspx1+u5T%{?xXT*}ORUOdRVPs7lkFL@j1|J$tj8ghHAS`iQUCmLg z(y${LcC6e^`giE93GAbOf!dtFi!hcb@JgL7=$1&B-*!~l6t56u_mKx)A^s_NHRyD` zz$+Il95wuEOAPv&*{5v->KkBk|AL9Z964RcibHQK_HjRWt2*mnR$HoO=@r$6)-K6a zHxh$rf5EziI7Xu`O-KxaIl!)#cYk3tF3nnBqtbkeN0YYlw*s#LJoZQEHX_)Lx**hU zUC3d?TZOwjr8yG?obl9jVc|vx+853xGGh^gRF|Q{s*UZ3wpjNbv!@@i<*`XtP-!lr z90=J$qtO?$f=i&zty!+yANGq>Ch#j&FB9uQ{6_3zM=>LK| zDdYS*CRReMWt$ZbA$KugOW%yHjt}>~pY2+lFa0$&#~K5zn_ClMWm`))(WtbBwgr^d z%}V@#5H)1GGpVju^DLX|=wjR)cTcP?Td^*fOA)OcGJWB(3MQT@>x|gBznd#RaNE4(E!ecZ4U#NJ1MrhyOqVMg>r!n5e!S+N)G8NXfgJqIzUt<8 literal 0 HcwPel00001 diff --git a/scalos/Extras/OpenLocation_CA b/scalos/Extras/OpenLocation_CA new file mode 100755 index 0000000000000000000000000000000000000000..87bc54a2dea56f8030693e8dc2e69c3cecb6fd9f GIT binary patch literal 8724 zcwV(xe@t7)9sl}A;FVa!r8Gqwr4P$x&^R{D(l*JW$w1mUC^0njM>=%_L%@(2?1D+s zs@j|^sj{w8)1|ATDbl7YQlpMktjeZN>L0X?rZkHtwnh=F(1JFm($!T_hBk}YynVj+ z?ma&nsM;+9o$u~@ci-Rlz3<&4a{PnzKO32U$`eG6kGb|8Cg(jNKdIY^d{v(9Jj+Yr zH?(c7sXk|-GCb;|$)o5$`_792x}N3L;YV_p06Ez3kT!AZ{qP%0AJzq1e?en?HBFz; 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 literal 0 HcwPel00001 diff --git a/scalos/Extras/OpenLocation_CA.info b/scalos/Extras/OpenLocation_CA.info new file mode 100755 index 0000000000000000000000000000000000000000..509905c9410c9df9324e1d8688c3c7ba7fb577e5 GIT binary patch literal 1348 zcwTLkUrbw79LLYS{Rfq#x1E1tmbSDvK5Us;*8yYclCG|Qzy%>@kO`U*JG#mO?L*DR zpGY^Q!}>s9%xFup#!Z3Sht@%0y%=g@B$F3dHCrMNAZRO~8MtJtz&*!v`-h?N+Vr)|qU$^bRN!5QLCO0p+z)YFil>D(IuDK)H|`QQdNG zBrSEDdExYH)?a{0tB1Oao^y^Ba14ut4W4#7z)%`!u>OZ z?zby74iHL2GoTFWo>u07nQ_bLswyXc4PiAi@85^_lTj0W>0ARKy^zIZ8+v^NrVb` zHgTZ3d3vmfEbDBZXer`n4BI?${&F7wknNz@hQi{rvq5G$814KP#k*OL&$U`s6kz;K zPZc!&wI`sjyUp(&*P8dS<+{^+1@jc^IyO=Ka1V4Fd>zZ=R5C-{gB=T^ z8&dVg0r|k1Z$xm0@z-%_@Qa3vhq3ra24b|Ku!QD?*Y;WwAV_O#S}#; z<5}ebQh$LcN<|@x+}4qtN{1+g@eVMqAXNjR-mhqEgRMfS)5H3GFQ~psH%c4jvmaq|*(!8?ED`)lc$Fi*#=qCGp=HgCK0T1ZOQ~odC zbFpY}TR5&!<4;Q&F8RN*elWi$$rXknrg3qY8Q==@p751|%qNavtn7)vL{D*%=rGf} zFB88-a!xuo@&h|M_;aD6j#L<#(%$go{yYu68+%5ElWDZSq=x2V&xp&gwXyx*^VgC4 zn}=;}&HqtFy`ML67q-#hdg)bvl&>H^`Xkwu{2ujfBd-+pWyMiG7pPO>6VolX9^t2z zb#>ne^CCxSPr~@C^Sp>paaUNcrlgdd4kzXx!PtEX7Wh>Z(ZjtkAmL)aqrSfd;~KpB z0RIT$ho)iVl~_hHHl5oMST2CcC*(*hLyW;Vjd%G0pH^TYJJ0?D DR(N8i literal 0 HcwPel00001 diff --git a/scalos/Extras/OpenLocation_CA.readme b/scalos/Extras/OpenLocation_CA.readme new file mode 100644 index 000000000..06cf715b9 --- /dev/null +++ b/scalos/Extras/OpenLocation_CA.readme @@ -0,0 +1,8 @@ +OpenLocation_CA v0.3 by Eric Sauvageau +-------------------------------------- +This program will popup a GUI, asking you to enter the path of the drawer +you want to open. If a drawer is specified as a WB argument, it will +put this one in its string gadget by default (so you can put it in a +menu, and define it as a "WB+Arg" command type in Scalos_Menu). + +Uses ClassAct for its GUI. diff --git a/scalos/Extras/OpenLocation_CA.readme.info b/scalos/Extras/OpenLocation_CA.readme.info new file mode 100755 index 0000000000000000000000000000000000000000..4d1efe7097763e9c4395735e397f70d5a3f15940 GIT binary patch literal 1696 zcwTLj4{Q==7{agXqLl=2 z%dKI_YGyVw-PUdyX@X&$G1h9D)MzRubFo`ib&QtG+SM#;G-`q4;Mn)wwQ80<7yiBX zd*1hX$$e7_fB`6C8f*qq;lcn$$ag5f{|S=e5s4Q_lid}Rsx}9{pCfUe+-U#qX=8|T>GY20ki z8_KfajK0IuVQoAIEYpP9Y&JQkz(|l#St~u&cUkg7hxsW76&MAUacE^x=@-4nS8J_z z{=NvcH*+H9sr5iiNa;K)(T%{QzPx68hr?nM2xavNiFIMvSzNak?pEdD-P?WjyVxhZ z-irPP=kA63Id{2brBtUwJNf;2_eUrgXEcrj-*@8{W`A(ZR4Edid$$njGb0pQ zC?1dBn8EDqv4c9J(ef)?Qm(r0_xs}JG=g-M2=XHcM?Q~no?3z^zu#c0{TWRi;9}1BSDEOm6ZDZfh#gJ=ewd|MK3h5mtMYNISi`L;`C4! z)KsOCxIbQ~sYK~?j*9SL7QD0WI;xs7y$?&vVI_mGuL?CP6t1QsJfwEZRLNxOI%Z^h z@03#X>2K2@RFzEr%-?u~>vXy5v^0ECO^Q${YFyB?be|4A#*`bAP?uqzJA^rW>I=1@ zsMrwxhQm)Xp~cNylrQpAl9juR{8c_Id8NC7-^Z`vZ9FKU&g}I5v0r>@aS}X-o?2WD zR&x^Uzskt}WC1p*!8o8?H-%{nK&zX4Nz%{at|};JQc9G~M3wm+GKafkC$;;+$cFOgH^3 z3pH>JxNgG+Y>Q9q8i{(l4)xqxB#h=3(1gK1NZwme1R% z1t=CxB{1f}ffpSM6xY`-ggn;0#cz1C@)4*7dgGS-1a!Nvl3qR7j>R4~uGdan&|nP2N=~ r)Q0C3&q_`5(UR1~`uj7>;K>T}Q}A2?KFaSC&X|o~Qv%NzJX-$(j-ru) literal 0 HcwPel00001 diff --git a/scalos/Extras/OpenLocation_MUI b/scalos/Extras/OpenLocation_MUI new file mode 100755 index 0000000000000000000000000000000000000000..6b164817dca109f45405146a8b4e0b5494988648 GIT binary patch literal 3520 zcwUWGZ){uD6~A`u_s6wRR7w|B7Cata7MO9`u1HN4H0LEHjxkOlp{qos*iGCQ7svJ- zr){i`zDN`67}5ws8;TI>2e$E{L?94qCAzs0LS^(rROLg(tTjS~mJ+E|mrYUR+WVdR zZW3#x-JbOGIrrRi&$;K1@4bvQ{FB+AgROnezcbeGEz$6`6V<>m=K9^|v6C*;9~B*U6S3Ylf_lQ`Th5kV#}yYiBIv%{wsDAF)iv0?i?=QSSII z#I)Z$9A+*(ob&YFWV;{!(X$t7l}Ex%(R!fohs}Mt<~5rYb5|fVbpg@?dsmbyqB+dv zS52Q5@{S-=O`{4ZW7~#3m@OM;X*R(eiwWj@ki0t%t?r4PviHO-Tr{5x6qPr1$UPJO zJxZpTYqYde`eQSdBds2Pukq*BHqvcvw~XK3(IyyE7WCf01Z4o0js+wBL9(tFl_18k z2zj4F#E;djp1ap-p+~+Qr1#1x(o>u6qSr69U(|f5a zoJ+x2^h&4GYt`_Xn>CtSFfZ7>Qk{+eh1>OUtIL#89#h49Fi@0>oWE)+T2bClbGqoU z>OngTa(^A)RmX3y<6DU5mdfT$nl3?(*vq%HwLMhOaT*|7>K++|v0iYIwL- z35+l$_WS6SF3jebO*>YY*16&?C!Dcytw}`Yp=e#V^-_G1cf171fC8wb(XrzAD$y8Z zrqZ#}fNpWPG?_e}c&R14+A&Us{%|nfHPB@2(?C(mX+ChXUJHf_qfsrScWXZ3)z4|w z+{)=48e2y5H>L~w_);(V2lPwvOa1|4O7BMgzVch1BiD(pVQ0U)0UBJtX0gQUe?Pb(|mfVFC=29 znvME-{JU>cvXRq4U zx#DWy$-eHLuL#+4onC{GEp3p8TY@eNx@7CBjkYeAT^4lFrfQ?mK|a)yWxV&K@PoJ= z=lTYFqn7c-AMKdcEkd^mc;7O@2JD0_W1$H8yk$(DvFV3D1x;GU&1dZShdu-SgJt}6 zLD*>$c6^L~YLjJr{)J^+&oF-1l6{J)f11wUyXg4ryq^y}w$Q7-N= zui3Swd1t!k*E@E6e?9q6HrjQi{-8Qh4X8HMlj7T(DJ1h+S3YqRq>$CJxnyP!+m|Se zu)*FJ*(A!L3K$xRp%Fe2%?>3Bschz%=X;oc|K8{JXnjM8barg; zzb3W)+E3boJGGXb+aG@_dGPTaZEd?BWgF|Vo}p}p#S)`Q)|Vqw{T z-#7p7r_2B!0#x&J_txEHd|&2yb)8pmwkZz)+X1T8kAc~Zd_+@Yh2ZFTigo9+<2lZC zP7I}!oa;{>vnTgubBVDuXZs5IRL10NM=qC6*$Ls}pQSRx*`u8OAN$|EN*4 zLt6cd<~X`_ZtWG4*NU~~NF#2@*IN|Q`@u=Bx6JkC*Y)_xK5u#?daKeuY@W1}Pjl^g zu6=o3J5a3N!mGv=p0N6u)Vino8Rxvw! z9Df6D09fP1+3nm6Yy;4TPP%Wq0IYW&266z-Ip@m&?xcpD!0WhH@c(zCXWjdNVW0rO zpBsC1zXrSsoB}=qJ^?NOxR>0xhukjE-&UqQWWIqr9;7f)tISjy; zoCe@W#{OmGOMVN04;emW*q5U6c@U%L T-#BBCw@t9KDQ>q&!|ne7KRxj@ literal 0 HcwPel00001 diff --git a/scalos/Extras/OpenLocation_MUI.info b/scalos/Extras/OpenLocation_MUI.info new file mode 100755 index 0000000000000000000000000000000000000000..509905c9410c9df9324e1d8688c3c7ba7fb577e5 GIT binary patch literal 1348 zcwTLkUrbw79LLYS{Rfq#x1E1tmbSDvK5Us;*8yYclCG|Qzy%>@kO`U*JG#mO?L*DR zpGY^Q!}>s9%xFup#!Z3Sht@%0y%=g@B$F3dHCrMNAZRO~8MtJtz&*!v`-h?N+Vr)|qU$^bRN!5QLCO0p+z)YFil>D(IuDK)H|`QQdNG zBrSEDdExYH)?a{0tB1Oao^y^Ba14ut4W4#7z)%`!u>OZ z?zby74iHL2GoTFWo>u07nQ_bLswyXc4PiAi@85^_lTj0W>0ARKy^zIZ8+v^NrVb` zHgTZ3d3vmfEbDBZXer`n4BI?${&F7wknNz@hQi{rvq5G$814KP#k*OL&$U`s6kz;K zPZc!&wI`sjyUp(&*P8dS<+{^+1@jc^IyO=Ka1V4Fd>zZ=R5C-{gB=T^ z8&dVg0r|k1Z$xm0@z-%_@Qa3vhq3ra24b|Ku!QD?*Y;WwAV_O#S}#; z<5}ebQh$LcN<|@x+}4qtN{1+g@eVMqAXNjR-mhqEgRMfS)5H3GFQ~psH%c4jvmaq|*(!8?ED`)lc$Fi*#=qCGp=HgCK0T1ZOQ~odC zbFpY}TR5&!<4;Q&F8RN*elWi$$rXknrg3qY8Q==@p751|%qNavtn7)vL{D*%=rGf} zFB88-a!xuo@&h|M_;aD6j#L<#(%$go{yYu68+%5ElWDZSq=x2V&xp&gwXyx*^VgC4 zn}=;}&HqtFy`ML67q-#hdg)bvl&>H^`Xkwu{2ujfBd-+pWyMiG7pPO>6VolX9^t2z zb#>ne^CCxSPr~@C^Sp>paaUNcrlgdd4kzXx!PtEX7Wh>Z(ZjtkAmL)aqrSfd;~KpB z0RIT$ho)iVl~_hHHl5oMST2CcC*(*hLyW;Vjd%G0pH^TYJJ0?D DR(N8i literal 0 HcwPel00001 diff --git a/scalos/Extras/OpenShell b/scalos/Extras/OpenShell new file mode 100755 index 000000000..0b4a93761 --- /dev/null +++ b/scalos/Extras/OpenShell @@ -0,0 +1,8 @@ +;// $Date: $ +;// $Revision: $ +; $VER: OpenShell 1.1 (08.09.06) (c) The Scalos Team + +.key DIR + +cd